From 836a2fb8872217d2a04a209b89f2ac2ff86a4b99 Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Fri, 28 Sep 2018 17:37:58 +0200 Subject: [PATCH 0001/1650] [macOS] Fix position of sheets when using unifiedTitleAndToolBarOnMac MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Modal sheets are supposed to appear below the toolbar if a toolbar exists, or below the title bar if a toolbar doesn't exist. In the unified title and toolbar mode, sheets should to appear directly below the toolbar, if the toolbar is positioned at the top of the window. Code-wise we achieve that by calling setUnifiedTitleAndToolBarOnMac on a QMainWindow, which results in adjusting the top content border of the NSWindow via [NSWindow setContentBorderThickness:forEdge], which Cocoa uses to position a modal sheet (the sheet top edge is aligned with the top edge of the content view + the Y border thickness value). The issue is that because NSWindow.titlebarAppearsTransparent is set to YES, for sheet presentation purposes, Cocoa considers the content view to begin at the position of the top left corner of the frame (where the title bar is), and thus sheets appear somewhere in the middle of the unified toolbar. To fix that we need to account for the title bar height in the border thickness value. Compute the title bar height from the window frame height - window content view height, and add it to the top border thickness value. Amends 8ac9addd946637401e4685c6e91d1a3cd5b2d768 Change-Id: Icf85c513035cc3710b438e60eb14dc04c5bbaced Fixes: QTBUG-65451 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoawindow.mm | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 9b10c8b053..00c3f7c22c 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1714,6 +1714,14 @@ void QCocoaWindow::applyContentBorderThickness(NSWindow *window) [window setStyleMask:[window styleMask] | NSTexturedBackgroundWindowMask]; window.titlebarAppearsTransparent = YES; + // Setting titlebarAppearsTransparent to YES means that the border thickness has to account + // for the title bar height as well, otherwise sheets will not be presented at the correct + // position, which should be (title bar height + top content border size). + const NSRect frameRect = window.frame; + const NSRect contentRect = [window contentRectForFrameRect:frameRect]; + const CGFloat titlebarHeight = frameRect.size.height - contentRect.size.height; + effectiveTopContentBorderThickness += titlebarHeight; + [window setContentBorderThickness:effectiveTopContentBorderThickness forEdge:NSMaxYEdge]; [window setAutorecalculatesContentBorderThickness:NO forEdge:NSMaxYEdge]; From ba0ff45109a0eb051a42d6d8392d1f1b7a1e9345 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 3 Oct 2018 11:41:40 +0200 Subject: [PATCH 0002/1650] Update the DNS public suffix list from publicsuffix.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It has had some changes and should be kept up to date. Fixes: QTBUG-70386 Task-number: QTBUG-70852 Change-Id: I868a558811c34cf5a800c3087a0ca96e7fb49b1a Reviewed-by: Mårten Nordheim Reviewed-by: Allan Sandfeld Jensen --- src/corelib/io/qurltlds_p.h | 27090 +++++++++++++++++----------------- 1 file changed, 13747 insertions(+), 13343 deletions(-) diff --git a/src/corelib/io/qurltlds_p.h b/src/corelib/io/qurltlds_p.h index 4d21b608fc..5453644225 100644 --- a/src/corelib/io/qurltlds_p.h +++ b/src/corelib/io/qurltlds_p.h @@ -61,13700 +61,14104 @@ QT_BEGIN_NAMESPACE // for instructions see the program at // util/corelib/qurl-generateTLDs -static const quint16 tldCount = 8419; +static const quint16 tldCount = 8621; static const quint32 tldIndices[] = { 0, 0, -14, -14, -14, -14, -43, -43, -43, -61, -73, -73, -73, -73, -115, -122, -141, -150, -165, +26, +26, +26, +26, +40, +40, +54, +54, +54, +59, +65, +75, +75, +109, +117, +132, +149, +149, +149, +159, +166, 193, -210, -210, -228, -228, -248, -248, -261, -277, -277, -277, +193, +235, +235, +235, +241, +276, +282, 287, -287, -296, -330, -345, -345, -345, -345, -345, -381, -381, -381, -381, -381, -395, -405, -418, -418, -438, -448, -448, -448, -472, -472, -472, -477, +309, +339, +349, +349, +390, +402, +420, +452, +468, 489, -496, -496, -514, -542, -554, -554, -578, -578, -578, -597, -597, -597, -627, -627, -627, +489, +503, +508, +531, +551, +551, +574, +605, +605, +605, +615, +615, +615, +633, 655, -655, -663, -676, -691, -691, -691, -697, -704, -711, -738, -754, -788, -825, -830, -837, -849, -849, -856, -909, -927, -952, -952, -959, -1005, +661, +661, +684, +702, +714, +736, +765, +765, +776, +794, +826, +847, +866, +866, +882, +895, +901, +960, +994, +994, +1012, +1012, +1012, 1032, -1052, -1059, -1059, -1066, -1142, -1149, -1174, -1174, -1174, -1181, -1191, -1214, -1245, -1252, -1273, -1317, -1338, -1338, -1338, -1368, -1375, -1401, -1408, -1408, -1408, -1415, -1445, -1468, -1468, -1468, -1468, -1468, -1486, -1506, -1512, -1519, -1539, -1546, -1569, -1577, -1577, -1584, -1584, -1591, -1609, -1647, -1668, -1675, -1703, -1710, -1710, -1717, +1048, +1048, +1068, +1090, +1090, +1090, +1101, +1114, +1114, +1133, +1133, +1140, +1140, +1147, +1147, +1156, +1163, +1163, +1163, +1173, +1185, +1185, +1201, +1201, +1208, +1225, +1230, +1285, +1316, +1374, +1394, +1417, +1417, +1417, +1424, +1438, +1476, +1532, +1549, +1556, +1563, +1570, +1590, +1590, +1597, +1604, +1617, +1617, +1629, +1629, +1641, +1648, +1662, +1662, +1680, +1706, +1722, 1729, -1729, -1742, -1762, -1762, -1762, -1813, -1841, -1841, -1841, -1841, +1745, +1745, +1757, +1779, +1779, +1786, +1835, 1848, -1872, -1890, -1925, -1949, -1965, -1976, -1987, -2002, -2002, -2002, -2002, -2029, -2044, -2092, -2118, -2123, -2123, -2149, -2161, -2167, +1848, +1875, +1895, +1895, +1923, +1943, +1943, +1950, +2004, +2023, +2023, +2030, +2051, +2068, +2083, +2100, +2107, +2142, +2155, +2155, +2155, +2162, 2174, -2181, -2217, -2230, -2255, -2255, -2262, -2262, -2269, -2298, -2319, -2319, -2338, -2338, -2338, -2379, -2379, -2386, -2386, -2393, +2174, +2174, +2196, +2196, +2218, +2254, +2281, +2287, +2303, +2313, +2313, +2313, +2333, +2354, +2367, +2367, +2367, 2420, -2435, -2451, -2477, -2477, -2512, +2442, +2460, +2483, +2494, +2513, +2521, +2521, 2538, -2544, -2598, -2598, -2598, -2598, -2598, -2598, -2604, -2604, -2644, -2657, -2686, -2717, -2717, -2724, -2740, -2747, -2759, -2777, -2787, -2796, -2796, -2796, -2803, -2803, -2820, -2827, -2827, -2834, -2850, -2850, -2864, -2903, -2910, -2917, -2924, -2931, -2938, -2977, -2977, -2999, -2999, -3006, -3026, -3026, -3056, -3077, -3084, -3102, -3118, +2545, +2555, +2583, +2610, +2610, +2617, +2631, +2638, +2649, +2661, +2661, +2668, +2699, +2705, +2705, +2705, +2712, +2721, +2737, +2749, +2768, +2775, +2792, +2815, +2825, +2841, +2841, +2868, +2868, +2905, +2905, +2934, +2957, +2957, +2975, +3005, +3012, +3037, +3046, +3046, +3053, +3053, +3066, +3073, +3083, +3083, +3105, 3123, -3156, -3163, -3212, +3123, +3181, 3226, -3243, -3274, -3281, -3295, -3313, -3318, -3318, -3331, -3345, -3386, -3404, -3437, -3451, -3458, -3492, -3523, -3533, -3540, -3585, -3645, -3652, -3659, -3699, -3725, +3245, +3245, +3301, +3323, +3332, +3360, +3370, +3370, +3370, +3380, +3380, +3387, +3387, +3394, +3394, +3394, +3402, +3409, +3416, +3431, +3448, +3519, +3543, +3569, +3607, +3607, +3613, +3625, +3625, +3682, +3689, +3696, 3734, -3759, -3807, -3842, -3870, -3896, -3910, -3924, -3924, -3924, -3959, -3959, -3972, -3988, -3988, -3993, -4060, -4092, -4099, -4099, -4106, -4119, -4119, -4147, -4147, -4147, -4171, -4178, -4178, -4178, -4178, -4197, -4204, -4243, -4243, -4250, -4257, -4264, -4271, -4271, -4278, -4290, -4302, -4302, -4302, -4302, -4302, -4329, +3750, +3750, +3760, +3760, +3769, +3786, +3786, +3786, +3793, +3809, +3816, +3822, +3829, +3829, +3836, +3852, +3852, +3867, +3874, +3892, +3892, +3902, +3935, +3960, +3980, +4005, +4019, +4032, +4059, +4089, +4089, +4122, +4122, +4151, +4151, +4151, +4151, +4158, +4158, +4158, +4158, +4158, +4158, +4158, +4173, +4191, +4200, +4200, +4224, +4232, +4265, +4281, +4288, +4309, 4348, -4380, -4394, -4394, -4401, -4408, -4425, -4459, -4506, -4513, -4513, -4520, -4520, -4527, -4540, -4573, -4592, -4599, -4647, -4654, -4675, -4686, -4693, -4737, -4806, -4806, -4822, -4859, -4865, -4872, -4894, -4901, -4923, -4975, -4989, -5036, -5036, -5050, -5067, -5073, -5073, -5080, -5130, -5147, -5154, -5161, -5168, +4370, +4377, +4396, +4396, +4403, +4403, +4419, +4439, +4446, +4462, +4469, +4469, +4469, +4476, +4483, +4511, +4518, +4538, +4563, +4580, +4580, +4587, +4608, +4608, +4624, +4640, +4664, +4664, +4664, +4680, +4690, +4699, +4707, +4707, +4707, +4717, +4717, +4741, +4741, +4741, +4741, +4766, +4778, +4778, +4794, +4801, +4834, +4854, +4867, +4874, +4874, +4888, +4888, +4888, +4936, +4942, +4963, +5001, +5008, +5008, +5008, +5008, +5008, +5017, +5024, +5062, +5069, +5074, +5095, +5139, +5146, +5156, 5175, 5182, -5182, -5196, -5210, -5224, -5239, -5259, -5300, -5345, -5359, -5359, -5397, -5436, -5474, -5513, +5193, +5200, +5212, +5225, +5238, +5261, +5268, +5298, +5298, +5305, +5305, +5315, +5315, +5329, +5329, +5349, +5363, +5363, +5399, +5399, +5418, +5445, +5466, +5490, +5505, +5505, +5505, 5530, -5537, -5537, -5544, -5551, -5563, -5577, -5590, -5595, -5601, -5623, -5643, -5680, -5706, -5730, -5737, -5754, -5761, -5785, -5797, -5804, -5816, -5816, +5530, +5546, +5546, +5582, +5610, +5610, +5634, +5676, +5676, +5722, +5735, +5774, +5774, 5828, -5855, -5869, -5892, -5892, -5914, -5935, -5935, -5942, -5963, -5981, -5981, -5988, -6002, -6019, +5828, +5828, +5828, +5851, +5881, +5894, +5894, +5901, +5901, +5906, +5906, +5937, +5937, +5950, +5950, +5950, +5956, +5956, +5956, +5998, +5998, 6030, -6047, -6047, -6054, -6099, -6099, -6121, -6167, -6183, -6190, -6219, +6055, +6074, +6090, +6090, +6103, +6103, +6155, +6177, +6207, +6207, +6214, +6214, 6226, -6240, -6247, -6254, -6299, -6327, -6407, -6434, -6441, -6471, -6485, -6505, -6513, -6513, -6513, -6546, -6558, -6558, -6558, -6565, -6575, -6585, -6592, -6611, -6619, -6619, -6626, -6645, -6645, -6665, +6244, +6266, +6303, +6303, +6330, +6330, +6344, +6360, +6387, +6410, +6410, +6410, +6410, +6438, +6451, +6451, +6451, +6465, +6477, +6477, +6477, +6484, +6500, +6500, +6519, +6519, +6530, +6548, +6567, +6567, +6567, +6586, +6604, +6652, +6652, 6672, -6689, -6689, -6689, -6723, -6730, -6737, -6756, -6799, +6683, +6716, +6716, +6727, +6727, +6727, +6727, +6727, +6747, +6747, +6781, +6781, +6791, +6821, +6821, 6827, -6834, -6841, -6841, +6827, +6843, 6869, -6876, -6876, -6883, -6890, -6955, -6962, -6962, -6982, -7010, -7027, -7034, -7034, -7059, -7099, +6877, +6877, +6877, +6877, +6896, +6896, +6903, +6919, +6919, +6919, +6935, +6935, +6935, +6935, +6935, +6935, +6935, +6966, +6983, +6983, +6999, +6999, +6999, +7013, +7022, +7022, +7022, +7022, +7022, +7022, +7070, +7085, +7105, +7105, 7122, -7122, -7122, -7127, -7134, -7134, -7134, -7161, -7161, -7194, -7194, -7194, -7194, -7234, -7234, -7234, -7234, -7234, -7241, -7253, -7260, -7288, -7308, -7315, -7329, -7338, -7363, -7387, -7397, -7397, -7397, -7414, -7432, -7458, -7465, -7465, -7484, -7495, -7495, -7512, -7537, -7554, -7554, -7561, -7575, -7589, -7594, -7613, -7627, -7650, -7667, -7684, -7691, -7716, -7716, -7728, -7757, -7769, -7799, -7806, -7806, -7823, -7830, -7837, -7837, -7844, -7865, -7865, -7865, -7881, -7888, -7894, -7934, -7966, -7966, -7966, -8007, +7139, +7148, +7162, +7162, +7172, +7172, +7210, +7210, +7230, +7242, +7242, +7249, +7259, +7259, +7279, +7279, +7294, +7311, +7317, +7353, +7369, +7375, +7395, +7395, +7431, +7496, +7496, +7505, +7505, +7505, +7505, +7511, +7539, +7551, +7564, +7583, +7595, +7595, +7595, +7628, +7628, +7628, +7665, +7674, +7686, +7711, +7737, +7755, +7755, +7794, +7805, +7811, +7811, +7831, +7831, +7850, +7850, +7858, +7874, +7879, +7903, +7923, +7958, +7958, +7972, +7987, +7987, +7998, +8008, +8008, 8042, 8042, -8061, -8091, -8105, -8105, -8105, -8105, -8105, -8105, -8105, -8136, -8156, -8156, -8162, -8168, -8168, -8188, -8195, -8195, -8195, -8195, -8195, -8244, -8244, -8257, -8257, -8257, -8277, -8322, -8329, -8356, -8356, -8367, -8367, -8381, -8423, -8429, -8459, -8478, -8497, -8505, -8512, -8512, -8512, -8517, -8524, -8524, -8524, -8524, -8524, -8524, -8524, -8531, -8536, -8551, -8574, -8574, -8581, +8059, +8059, +8076, +8096, +8096, +8096, +8114, +8114, +8132, +8132, +8148, +8163, +8175, +8194, +8194, +8205, +8214, +8218, +8246, +8246, +8246, +8286, +8286, +8286, +8286, +8286, +8305, +8312, +8312, +8312, +8312, +8335, +8357, +8357, +8366, +8382, +8390, +8394, +8394, +8407, +8414, +8446, +8453, +8466, +8466, +8500, +8500, +8522, +8542, +8554, +8577, 8588, -8602, -8635, -8645, -8674, -8688, -8688, -8699, -8723, -8723, -8723, -8736, -8736, -8745, -8786, -8786, -8786, -8805, -8833, -8849, -8863, -8863, -8876, -8876, -8876, -8876, -8876, -8876, -8876, -8901, -8901, -8929, -8940, -8947, -8957, -8969, -8969, -8969, -9023, -9030, -9041, -9041, -9041, -9068, -9102, -9138, -9138, -9155, -9180, -9180, -9180, -9180, -9180, -9208, -9208, -9232, -9232, -9248, -9274, -9281, -9281, -9311, -9318, -9353, -9353, -9353, -9366, -9372, -9372, -9407, -9414, -9426, -9443, -9468, -9468, -9468, -9468, -9484, -9484, -9501, -9529, -9568, -9568, -9606, -9620, -9652, -9675, -9714, -9724, -9736, -9756, -9770, -9806, -9815, -9820, -9831, -9831, -9831, -9846, -9846, -9846, -9846, -9846, -9846, -9846, -9846, -9846, -9861, -9861, -9861, -9861, -9868, -9878, -9900, -9915, -9915, -9925, -9925, -9925, -9946, -9946, -9964, -9977, -9995, -9995, -9995, -9995, -9995, -9995, -9995, -9995, -10020, -10028, -10041, -10041, -10059, -10059, -10064, -10076, -10076, -10076, -10081, -10106, -10130, -10148, -10148, -10155, -10155, -10184, -10184, -10223, -10239, -10239, -10247, -10247, -10254, -10285, -10285, -10297, -10309, -10332, -10332, +8608, +8614, +8621, +8652, +8675, +8675, +8687, +8687, +8712, +8712, +8734, +8744, +8798, +8808, +8827, +8827, +8827, +8840, +8855, +8855, +8880, +8880, +8897, +8897, +8897, +8930, +8968, +8968, +8968, +8968, +8992, +9055, +9073, +9085, +9094, +9116, +9116, +9145, +9164, +9175, +9187, +9214, +9214, +9226, +9242, +9272, +9291, +9305, +9324, +9324, +9324, +9324, +9331, +9368, +9374, +9393, +9415, +9415, +9415, +9428, +9428, +9434, +9451, +9451, +9451, +9486, +9486, +9486, +9486, +9503, +9503, +9503, +9509, +9509, +9541, +9548, +9548, +9548, +9597, +9597, +9604, +9619, +9646, +9657, +9664, +9701, +9730, +9737, +9743, +9755, +9774, +9795, +9802, +9816, +9816, +9824, +9847, +9865, +9865, +9890, +9904, +9911, +9931, +9955, +9969, +10008, +10015, +10032, +10032, +10039, +10046, +10065, +10065, +10113, +10120, +10128, +10135, +10142, +10142, +10167, +10178, +10198, +10232, +10251, +10307, +10325, +10325, +10325, 10332, 10338, -10338, -10338, -10338, -10349, +10360, +10372, 10379, -10379, -10379, -10379, -10379, -10386, -10386, -10386, -10386, -10386, -10386, -10386, -10386, -10391, -10391, -10409, -10409, -10429, -10429, -10429, -10429, -10467, -10467, -10467, -10483, -10506, -10549, -10549, -10556, -10577, -10577, -10588, -10616, -10616, -10654, -10654, -10654, -10666, -10677, -10677, -10692, -10692, -10726, +10412, +10443, +10443, +10460, +10468, +10490, +10490, +10500, +10519, +10534, +10541, +10574, +10598, +10633, +10653, +10673, +10694, +10694, +10694, +10706, +10706, +10715, +10725, +10725, +10736, 10743, -10755, -10817, -10841, -10850, -10866, -10877, -10887, -10914, -10950, -10950, -11015, -11051, -11069, -11069, -11078, -11122, -11165, -11165, -11177, -11177, -11177, -11177, -11215, -11221, -11253, -11253, -11253, -11253, -11253, -11267, -11284, -11309, -11316, -11328, -11336, -11373, -11408, -11427, -11427, -11443, -11443, -11450, -11450, -11472, -11472, -11487, -11494, -11494, -11504, -11504, -11520, -11539, -11539, -11579, -11598, -11608, -11608, +10750, +10782, +10798, +10814, +10833, +10833, +10848, +10858, +10858, +10858, +10863, +10875, +10900, +10907, +10930, +10961, +10989, +11020, +11068, +11075, +11082, +11114, +11131, +11156, +11176, +11184, +11212, +11218, +11235, +11235, +11247, +11247, +11254, +11265, +11269, +11304, +11311, +11340, +11340, +11354, +11384, +11384, +11409, +11409, +11422, +11439, +11449, +11449, +11462, +11469, +11469, +11477, +11488, +11488, +11502, +11522, +11589, 11628, -11645, -11680, -11680, -11680, -11709, -11715, -11715, -11715, -11749, -11766, -11766, -11766, -11766, -11781, -11791, -11805, +11657, +11670, +11670, +11699, +11706, +11723, +11723, +11763, +11763, +11763, +11790, 11825, -11833, -11863, -11863, -11863, -11863, -11876, -11883, +11844, +11875, +11875, 11891, -11903, -11914, -11966, -11966, -11966, -11966, -11980, -11980, -11980, -11987, -12000, -12000, -12017, -12049, -12049, -12049, -12059, -12059, -12059, -12080, -12106, -12123, -12123, -12123, -12137, -12137, -12174, -12180, -12215, -12215, -12251, -12261, -12268, -12268, -12293, -12314, -12314, -12356, -12369, -12390, -12390, -12404, -12404, -12445, -12465, -12505, -12528, -12548, -12554, -12560, -12581, -12597, -12597, -12604, -12636, -12642, -12649, -12649, -12677, -12677, -12705, -12705, -12718, -12718, -12735, -12735, -12793, -12793, -12793, -12798, -12825, -12837, -12837, -12846, -12855, -12865, -12865, -12873, -12882, -12888, -12894, -12894, -12901, -12933, -12960, -12960, +11891, +11898, +11898, +11898, +11898, +11898, +11911, +11911, +11932, +11939, +11939, +11946, +11946, +11957, +11957, +11964, +11988, +11995, +12047, +12110, +12117, +12124, +12131, +12131, +12147, +12173, +12192, +12228, +12235, +12252, +12252, +12284, +12284, +12299, +12299, +12312, +12336, +12343, +12367, +12374, +12400, +12417, +12417, +12437, +12437, +12444, +12479, +12513, +12527, +12541, +12541, +12564, +12607, +12614, +12625, +12632, +12670, +12698, +12739, +12753, +12760, +12791, +12791, +12791, +12791, +12818, +12818, +12818, +12839, +12851, +12851, +12851, +12861, +12877, +12899, +12899, +12906, +12906, +12918, +12925, +12925, +12925, +12925, +12945, +12949, +12968, +12968, +12980, 12996, 12996, -12996, -12996, -12996, -13019, -13019, -13063, -13063, -13063, -13063, -13078, -13110, -13124, -13124, -13124, -13131, -13167, -13178, -13178, -13198, -13198, -13198, -13198, -13198, -13214, -13214, -13214, -13214, -13247, -13247, +13003, +13030, +13037, +13044, +13080, +13084, +13137, +13156, +13175, +13197, +13213, +13220, +13227, +13227, +13245, +13245, +13245, 13262, -13267, -13302, -13302, -13332, -13345, -13355, -13368, -13368, -13380, -13380, -13380, -13412, -13412, -13418, +13277, +13304, +13311, +13311, +13319, +13319, +13319, +13324, +13324, +13324, +13324, +13335, +13342, +13342, +13347, +13378, +13390, +13408, +13413, +13413, +13413, +13420, 13433, -13462, -13462, +13440, +13447, +13466, +13511, 13525, -13579, -13610, -13610, -13631, -13631, -13647, -13657, -13657, -13657, -13664, -13672, -13677, -13732, -13755, -13778, -13784, -13790, -13870, -13891, -13900, -13919, -13933, -13933, -13981, -13993, -14005, -14005, -14012, -14012, -14019, -14060, -14067, -14067, -14067, -14067, -14067, -14087, -14100, -14100, -14111, -14111, -14123, -14123, -14123, -14153, -14153, -14162, -14162, -14181, -14181, -14181, -14187, -14187, -14193, +13537, +13555, +13600, +13600, +13618, +13629, +13636, +13636, +13679, +13686, +13725, +13757, +13757, +13800, +13826, +13836, +13847, +13867, +13867, +13882, +13911, +13925, +13925, +13942, +13954, +13991, +14001, +14016, +14057, +14073, +14095, +14095, +14104, +14118, +14124, +14124, +14130, +14156, +14156, +14179, +14201, +14201, +14205, +14205, 14209, -14227, -14227, -14227, -14242, -14242, +14216, +14224, +14231, +14249, 14253, -14265, -14265, -14273, -14280, -14280, -14288, -14322, -14327, -14327, -14327, -14333, -14340, -14362, -14362, -14391, -14415, -14415, -14423, -14423, -14423, -14431, -14442, -14442, -14461, -14489, -14489, -14499, -14520, -14520, -14536, -14536, -14551, -14572, -14572, -14572, -14572, -14572, -14592, -14638, -14638, -14677, -14683, -14683, -14702, -14702, -14708, -14724, -14738, -14738, +14291, +14338, +14366, +14370, +14375, +14407, +14427, +14427, +14434, +14447, +14463, +14473, +14473, +14484, +14484, +14501, +14501, +14501, +14510, +14529, +14543, +14543, +14555, +14559, +14585, +14585, +14601, +14614, +14618, +14622, +14642, +14711, +14711, +14730, +14730, +14730, +14730, 14743, -14754, -14767, -14767, -14793, -14809, -14827, -14832, -14832, -14832, -14846, -14863, -14902, -14902, -14902, -14910, -14946, -14946, -14957, +14764, +14764, +14782, +14817, +14829, +14829, +14829, +14835, +14839, +14839, +14839, +14839, +14851, +14859, +14859, +14888, +14888, +14888, +14888, +14927, +14939, +14951, +14951, 14971, -15001, -15011, -15011, -15030, -15042, -15070, -15070, -15099, -15118, -15137, -15150, -15150, -15177, -15210, -15210, -15210, -15234, -15259, -15278, -15286, -15286, -15335, -15361, -15361, -15361, -15375, -15401, -15401, -15443, -15443, -15466, -15466, -15530, -15545, -15565, -15618, -15629, -15629, -15645, -15649, -15671, -15671, -15681, -15681, -15692, -15700, -15700, -15700, -15700, -15712, -15761, -15769, -15769, -15769, -15769, -15779, -15785, -15793, -15793, -15793, -15811, -15826, -15826, -15826, -15854, -15854, -15866, -15878, -15900, -15900, -15900, -15900, -15900, -15900, -15909, -15926, -15926, -15950, -15956, -15956, -15962, -15971, -16000, -16023, -16023, -16043, -16064, -16071, -16075, -16093, -16099, -16099, -16115, -16121, -16121, -16121, -16121, -16121, -16137, -16162, -16175, -16175, -16238, -16238, -16238, -16277, -16277, -16282, -16289, -16305, -16328, -16328, -16328, -16332, -16332, -16332, -16361, -16361, -16384, -16384, -16391, -16391, -16391, -16391, -16428, -16464, -16491, -16491, -16498, -16522, -16585, -16602, -16608, -16643, -16653, -16670, -16670, -16670, -16679, -16679, -16695, -16695, -16695, -16719, -16738, -16761, -16761, -16761, -16793, -16801, -16821, -16840, -16878, -16919, -16941, -16941, -16966, -16966, -16966, -16966, -16983, -17003, -17015, -17025, -17037, -17045, -17045, -17072, -17072, -17072, -17072, -17088, -17088, -17095, -17095, -17114, -17145, -17164, -17209, -17258, -17258, -17278, -17278, -17314, -17314, -17329, -17329, -17338, -17354, -17354, -17372, -17393, -17393, -17410, -17419, -17426, -17439, -17456, -17456, -17488, -17529, -17529, -17529, -17546, -17596, -17604, -17604, -17616, -17638, -17638, -17638, -17638, -17663, -17671, -17702, -17749, -17756, -17756, -17756, -17756, -17756, -17756, -17778, -17784, -17784, -17784, -17799, -17814, -17814, -17814, -17824, -17824, -17835, -17835, -17851, -17871, -17896, -17913, -17919, -17919, -17919, -17937, -17937, -17951, -17951, -17951, -17980, -17980, -18017, -18017, -18052, -18052, -18052, -18052, -18079, -18083, -18083, -18092, -18092, -18114, -18124, -18132, -18132, -18132, -18159, -18175, -18175, -18186, +15007, +15007, +15018, +15034, +15034, +15045, +15045, +15067, +15106, +15106, +15141, +15147, +15163, +15195, +15195, +15209, +15209, +15216, +15216, +15224, +15224, +15224, +15243, +15243, +15243, +15253, +15285, +15285, +15306, +15324, +15382, +15403, +15403, +15407, +15407, +15435, +15435, +15468, +15472, +15499, +15516, +15516, +15528, +15533, +15533, +15538, +15538, +15550, +15568, +15579, +15603, +15603, +15611, +15621, +15621, +15621, +15621, +15631, +15647, +15655, +15655, +15655, +15655, +15655, +15707, +15707, +15713, +15713, +15733, +15774, +15774, +15784, +15784, +15784, +15784, +15784, +15795, +15795, +15800, +15800, +15800, +15825, +15825, +15825, +15857, +15884, +15884, +15884, +15884, +15884, +15903, +15922, +15937, +15937, +15997, +16004, +16019, +16065, +16065, +16065, +16086, +16100, +16112, +16112, +16129, +16138, +16138, +16138, +16153, +16169, +16186, +16186, +16228, +16228, +16228, +16259, +16270, +16306, +16316, +16322, +16322, +16383, +16393, +16393, +16423, +16423, +16423, +16433, +16448, +16448, +16472, +16472, +16477, +16487, +16528, +16537, +16547, +16552, +16574, +16579, +16596, +16603, +16651, +16686, +16686, +16686, +16703, +16703, +16753, +16753, +16753, +16767, +16767, +16784, +16825, +16832, +16843, +16843, +16851, +16862, +16879, +16898, +16898, +16917, +16917, +16924, +16932, +16970, +17008, +17016, +17034, +17034, +17034, +17034, +17063, +17098, +17127, +17142, +17142, +17160, +17160, +17160, +17160, +17186, +17213, +17240, +17254, +17259, +17259, +17259, +17294, +17350, +17376, +17414, +17443, +17459, +17459, +17477, +17482, +17495, +17508, +17508, +17515, +17521, +17544, +17544, +17544, +17544, +17550, +17573, +17580, +17587, +17631, +17673, +17673, +17691, +17733, +17743, +17762, +17762, +17771, +17771, +17771, +17780, +17807, +17807, +17840, +17847, +17847, +17855, +17867, +17883, +17900, +17900, +17924, +17964, +17964, +17970, +17970, +17998, +18006, +18006, +18006, +18006, +18006, +18035, +18084, +18110, +18110, +18127, +18135, +18167, +18167, +18203, +18203, +18208, +18208, 18238, -18269, -18269, -18284, -18284, -18299, -18299, -18317, -18317, -18343, -18343, -18343, -18343, -18361, -18361, -18367, -18374, -18380, -18380, -18394, -18406, -18439, -18439, -18455, -18455, -18472, +18238, +18255, +18267, +18267, +18298, +18314, +18344, +18344, +18352, +18352, +18352, +18352, +18392, +18398, +18437, +18437, +18449, +18463, 18497, -18513, -18517, -18537, -18537, -18543, -18543, -18559, -18559, -18559, -18559, -18603, -18622, -18629, -18634, -18648, -18653, -18678, -18678, -18699, -18715, -18727, -18731, -18731, -18775, -18775, -18804, -18825, -18843, -18847, -18865, -18874, -18902, -18902, -18912, -18912, -18912, -18912, -18912, -18944, -18944, -18993, -19008, -19008, -19020, +18497, +18546, +18553, +18566, +18616, +18647, +18647, +18663, +18663, +18663, +18696, +18730, +18749, +18749, +18759, +18771, +18771, +18785, +18785, +18785, +18785, +18803, +18803, +18803, +18803, +18803, +18826, +18832, +18832, +18861, +18861, +18870, +18887, +18897, +18897, +18903, +18926, +18933, +18933, +18941, +18957, +18983, +19025, +19034, +19034, 19055, -19075, -19075, -19098, -19098, -19098, -19120, -19120, -19120, -19120, -19120, -19139, -19144, -19153, -19182, -19182, -19188, -19196, -19196, -19276, -19276, -19276, -19287, -19287, -19287, -19314, -19314, -19335, -19335, -19335, -19349, -19378, -19378, -19378, -19397, -19397, -19422, -19453, -19453, -19453, -19467, -19467, -19467, -19525, -19564, -19573, -19573, -19592, -19592, -19613, -19640, -19644, -19644, -19660, -19660, -19660, -19660, -19666, -19673, -19689, -19715, -19715, -19725, -19736, +19122, +19122, +19152, +19152, +19163, +19163, +19198, +19198, +19198, +19198, +19198, +19210, +19218, +19238, +19238, +19266, +19274, +19303, +19317, +19317, +19329, +19329, +19329, +19329, +19355, +19355, +19410, +19410, +19410, +19433, +19450, +19450, +19450, +19463, +19463, +19490, +19524, +19531, +19558, +19597, +19609, +19609, +19633, +19642, +19642, +19642, +19642, +19658, +19671, +19703, +19710, +19710, +19727, +19741, +19741, 19748, -19782, -19793, -19793, -19793, -19793, -19797, -19807, -19807, -19812, -19832, -19832, -19875, -19875, -19875, -19875, -19903, -19916, -19953, -19953, -19953, -19966, -20006, -20014, -20026, -20026, -20042, -20042, -20053, -20089, -20112, -20112, -20182, +19748, +19748, +19755, +19791, +19808, +19827, +19835, +19859, +19869, +19869, +19869, +19886, +19900, +19919, +19931, +19940, +19960, +19974, +19983, +20002, +20002, +20002, +20002, +20011, +20011, +20011, +20018, +20031, +20049, +20049, +20049, +20065, +20084, +20139, +20152, +20159, +20177, 20191, -20231, -20246, -20266, -20284, -20289, -20289, -20289, -20289, -20289, -20289, -20305, -20333, -20336, -20339, -20362, -20365, -20385, -20404, -20420, -20427, -20427, -20435, -20438, -20443, -20451, -20451, -20482, -20521, -20524, -20550, -20592, -20595, -20617, -20623, -20626, -20632, -20632, -20679, -20682, -20682, -20695, -20695, -20717, -20733, -20752, -20758, -20770, -20784, -20803, -20835, -20854, -20861, -20861, -20871, -20874, -20890, -20909, -20930, -20930, -20933, -20977, -20977, -20983, -20986, -21014, -21033, +20202, +20202, +20229, +20248, +20248, +20254, +20254, +20265, +20265, +20275, +20275, +20295, +20322, +20322, +20347, +20377, +20377, +20377, +20401, +20412, +20412, +20419, +20419, +20419, +20432, +20455, +20462, +20514, +20514, +20514, +20582, +20588, +20603, +20603, +20603, +20615, +20657, +20674, +20691, +20705, +20711, +20711, +20711, +20727, +20727, +20727, +20747, +20769, +20775, +20775, +20790, +20790, +20807, +20826, +20834, +20843, +20856, +20859, +20862, +20873, +20903, +20926, +20926, +20929, +20948, +20982, +21012, +21012, +21018, +21024, 21046, -21052, -21061, -21077, -21080, -21113, -21132, -21146, -21146, -21146, -21158, -21162, -21165, -21186, -21189, -21189, -21195, -21205, -21209, -21209, -21247, -21247, -21268, -21279, -21287, -21308, -21361, -21388, -21413, -21419, -21419, -21419, -21426, -21426, -21442, -21442, -21472, -21489, -21504, -21529, -21542, -21548, -21560, -21573, -21586, -21606, -21632, -21639, +21062, +21087, +21117, +21151, +21157, +21160, +21166, +21182, +21193, +21204, +21207, +21223, +21223, +21283, +21304, +21310, +21316, +21316, +21358, +21364, +21371, +21377, +21386, +21386, +21389, +21427, +21490, +21493, +21493, +21517, +21539, +21545, +21545, +21551, +21554, +21592, +21608, +21611, +21617, +21636, +21636, 21646, -21655, -21676, -21701, -21704, -21707, -21718, -21721, -21724, -21743, -21786, -21806, -21810, -21820, -21837, -21844, -21847, -21858, -21880, -21880, -21894, -21897, -21897, -21897, -21909, -21912, -21912, -21936, -21965, -22005, -22005, -22005, -22015, -22015, -22015, -22018, -22045, -22048, -22069, -22075, -22078, -22099, -22122, -22125, -22148, -22171, -22198, -22208, -22219, -22219, -22219, -22225, -22225, -22235, -22271, -22281, -22281, -22281, -22281, -22281, -22321, -22340, -22343, -22347, -22358, -22358, -22389, -22407, -22432, -22435, -22462, -22484, -22487, -22493, -22510, -22523, -22523, -22544, -22544, -22557, -22563, -22573, -22576, -22576, -22595, -22595, -22634, -22634, -22637, -22663, +21650, +21662, +21688, +21700, +21736, +21739, +21766, +21787, +21805, +21814, +21831, +21852, +21871, +21884, +21901, +21901, +21924, +21932, +21932, +21964, +21964, +21967, +21970, +21973, +21973, +21973, +22007, +22026, +22039, +22056, +22063, +22076, +22115, +22152, +22152, +22155, +22179, +22179, +22182, +22185, +22201, +22204, +22237, +22240, +22257, +22257, +22285, +22288, +22306, +22306, +22309, +22322, +22325, +22328, +22331, +22334, +22334, +22359, +22366, +22386, +22399, +22414, +22437, +22440, +22450, +22459, +22475, +22485, +22488, +22495, +22507, +22513, +22513, +22513, +22513, +22518, +22518, +22530, +22533, +22536, +22539, +22556, +22587, +22590, +22605, +22620, +22641, +22644, +22644, +22644, 22674, -22702, -22720, -22749, -22768, -22806, -22809, -22809, -22846, -22849, -22862, -22865, -22868, -22902, -22908, -22911, -22926, -22946, -22952, -22958, -22971, -22974, -22986, -22989, -22989, -22999, -23018, -23043, -23057, -23057, -23057, +22674, +22685, +22716, +22732, +22748, +22748, +22764, +22767, +22783, +22799, +22799, +22799, +22813, +22825, +22838, +22851, +22854, +22854, +22854, +22899, +22918, +22921, +22921, +22924, +22927, +22975, +22978, +22988, +22988, +22994, +22997, +23004, +23010, +23013, +23016, +23016, +23024, +23024, +23035, 23070, -23084, -23093, -23121, -23139, -23149, -23149, -23149, -23152, -23168, -23168, -23209, -23229, -23246, -23246, -23287, -23287, -23297, -23297, -23317, -23337, -23351, -23385, -23392, -23397, -23432, -23444, -23447, +23073, +23087, +23104, +23119, +23150, +23153, +23156, +23173, +23198, +23225, +23241, +23256, +23256, +23259, +23284, +23324, +23340, +23374, +23380, +23383, +23389, +23415, +23421, +23429, 23450, -23450, -23461, -23484, -23487, -23503, -23523, -23523, -23523, -23549, -23549, -23557, -23557, -23572, -23586, -23605, -23613, -23625, -23642, -23642, -23642, -23653, -23666, -23674, -23697, -23702, -23733, -23757, -23782, -23794, -23794, -23794, -23813, -23822, -23831, -23855, -23871, -23877, -23880, -23899, -23899, -23905, -23908, -23911, +23453, +23453, +23456, +23456, +23456, +23468, +23485, +23498, +23517, +23529, +23536, +23539, +23553, +23565, +23571, +23571, +23589, +23611, +23611, +23631, +23647, +23670, +23670, +23673, +23700, +23700, +23706, +23709, +23712, +23712, +23715, +23732, +23743, +23746, +23761, +23774, +23777, +23783, +23783, +23800, +23803, +23806, +23827, +23827, +23837, +23844, +23882, +23891, +23907, 23914, -23917, -23937, -23967, -23991, -23994, -23994, -24013, -24016, -24019, -24063, -24066, -24072, -24075, -24115, -24140, -24153, -24156, -24167, -24170, -24190, -24202, -24202, -24205, -24215, -24215, -24228, -24238, -24265, -24271, -24285, -24302, -24305, -24329, -24339, -24402, -24402, -24402, -24402, -24431, -24438, -24444, -24444, -24452, -24465, -24484, -24484, -24501, -24504, -24543, -24543, -24543, -24546, -24574, -24574, -24608, -24608, -24608, +23938, +23948, +23948, +23948, +23948, +23948, +23948, +23963, +23963, +23980, +23989, +24003, +24012, +24030, +24036, +24065, +24081, +24102, +24102, +24134, +24134, +24137, +24158, +24185, +24255, +24278, +24287, +24320, +24333, +24350, +24357, +24399, +24425, +24464, +24467, +24470, +24470, +24470, +24488, +24491, +24497, +24500, +24506, +24529, +24535, +24563, +24576, +24579, +24582, +24591, +24594, 24614, -24625, -24628, -24628, -24628, -24628, -24628, -24640, -24640, -24648, -24648, -24648, -24701, -24701, -24713, -24749, -24749, -24749, -24764, -24764, -24788, -24798, -24834, -24834, -24834, -24855, -24898, -24907, -24907, -24907, -24955, -24965, -24971, -24993, +24614, +24617, +24620, +24620, +24623, +24629, +24647, +24669, +24669, +24669, +24711, +24734, +24753, +24758, +24781, +24781, +24805, +24828, +24871, +24895, +24895, +24911, +24911, +24942, +24952, +24984, 25004, -25004, -25015, -25053, -25064, -25064, -25064, -25074, -25084, -25100, -25100, -25112, -25131, -25178, -25181, -25181, -25188, -25194, -25194, -25200, -25204, -25231, -25249, -25252, -25287, -25324, -25348, -25372, -25408, -25408, -25426, -25448, -25464, -25467, -25486, -25519, -25519, -25537, -25548, +25016, +25029, +25036, +25039, +25039, +25039, +25061, +25061, +25067, +25094, +25118, +25121, +25121, +25121, +25126, +25126, +25145, +25145, +25145, +25145, +25145, +25176, +25196, +25218, +25259, +25259, +25259, +25259, +25259, +25269, +25306, +25306, +25306, +25313, +25313, +25336, +25346, +25356, +25366, +25366, +25386, +25386, +25397, +25397, +25411, +25439, +25439, +25439, +25439, +25511, +25515, +25515, +25521, +25521, +25521, +25521, +25536, +25539, +25549, +25549, 25573, -25573, -25587, -25587, -25615, -25615, -25636, -25651, -25651, -25651, -25668, -25668, -25674, -25674, -25680, -25680, -25701, -25707, -25713, -25713, -25730, -25730, -25730, -25779, -25791, -25815, -25815, -25840, -25859, -25859, -25859, -25885, -25903, -25903, -25926, -25935, -25952, -25952, -25965, -25977, +25608, +25608, +25608, +25608, +25643, +25646, +25646, +25646, +25656, +25656, +25656, +25672, +25672, +25692, +25709, +25729, +25729, +25746, +25766, +25766, +25766, +25793, +25793, +25806, +25806, +25817, +25847, +25847, +25873, +25873, +25884, +25892, +25892, +25892, +25892, +25902, +25909, +25917, +25917, +25949, +25949, +25949, +25953, +25953, +25959, +25959, +25974, +25974, +25974, +25985, +25992, 26003, -26015, -26029, -26029, -26043, -26059, -26059, -26059, -26059, -26086, -26121, -26133, -26133, -26153, -26162, -26162, -26195, -26195, +26003, +26003, +26003, +26003, +26003, +26003, +26019, +26025, +26033, +26041, +26053, +26053, +26067, +26076, +26092, +26105, +26105, +26105, +26105, +26138, +26163, +26163, +26169, +26182, +26200, +26200, +26205, +26215, 26219, -26219, -26251, -26251, -26272, +26231, +26231, +26231, +26256, 26277, -26287, -26287, -26325, -26338, -26338, -26396, -26396, -26412, -26442, -26462, -26527, -26551, -26557, -26564, -26564, -26581, -26581, -26603, -26603, -26603, -26621, -26621, -26648, -26657, -26664, -26664, -26694, -26694, -26694, -26694, -26700, -26700, -26721, -26721, -26734, +26277, +26295, +26295, +26299, +26329, +26336, +26342, +26342, +26366, +26413, +26413, +26413, +26434, +26455, +26455, +26472, +26472, +26483, +26497, +26497, +26497, +26508, +26508, +26512, +26532, +26532, +26532, +26536, +26536, +26545, +26545, +26565, +26565, +26565, +26576, +26586, +26595, +26595, +26608, +26612, +26612, +26639, +26639, +26639, +26639, +26655, +26655, +26676, +26676, +26692, +26707, +26707, +26707, +26707, +26722, +26722, +26730, +26739, +26739, +26739, +26739, +26759, +26759, +26759, +26769, +26769, +26769, +26781, +26796, 26815, -26832, -26843, -26860, -26860, -26875, -26881, -26894, -26916, -26916, -26916, -26916, -26923, -26923, -26945, -26961, -26978, -27000, -27020, -27020, -27039, -27081, -27111, -27131, -27141, -27141, +26815, +26815, +26826, +26839, +26839, +26869, +26873, +26914, +26921, +26933, +26950, +26975, +26980, +27007, +27007, +27007, +27042, +27042, +27042, +27046, +27046, +27062, +27070, +27086, +27086, +27086, +27098, +27098, +27105, +27105, +27133, +27133, +27138, 27147, -27158, -27176, -27194, -27194, -27194, -27206, -27206, -27243, -27263, -27278, -27278, -27278, -27282, -27322, -27322, -27322, -27338, -27338, -27338, -27353, -27353, -27374, -27374, -27396, -27414, -27420, -27435, -27435, -27444, -27485, -27485, -27485, -27489, -27506, -27516, -27522, -27532, -27532, -27532, -27566, -27572, -27582, -27605, -27622, +27147, +27154, +27154, +27154, +27154, +27170, +27170, +27192, +27269, +27269, +27269, +27312, +27312, +27319, +27332, +27345, +27393, +27410, +27410, +27432, +27452, +27452, +27452, +27452, +27452, +27479, +27479, +27507, +27507, +27513, +27513, +27530, +27535, +27535, +27535, +27535, +27535, +27548, +27563, +27579, +27601, +27601, +27611, +27611, +27624, +27624, +27624, +27629, 27648, -27664, -27686, -27686, -27686, -27692, -27692, -27711, -27711, -27725, -27732, -27744, -27769, -27783, -27802, -27833, -27839, -27839, -27845, -27867, -27884, -27924, -27943, -27958, -27958, -27993, -27999, -28016, -28016, -28045, -28045, +27648, +27648, +27656, +27656, +27666, +27683, +27683, +27683, +27704, +27723, +27729, +27729, +27762, +27798, +27798, +27864, +27864, +27877, +27907, +27946, +27972, +27972, +27972, +27983, +27983, +27983, +27991, +27998, +28014, +28040, +28040, 28064, 28064, -28064, -28091, -28091, -28091, -28122, -28122, -28144, -28150, -28167, -28175, -28201, -28201, -28201, -28215, -28219, -28233, -28233, +28080, +28092, +28101, +28101, +28123, +28141, +28161, +28168, +28185, +28196, +28209, 28238, -28264, -28280, -28295, -28295, -28301, -28301, -28307, -28307, -28307, -28318, -28345, -28371, -28371, -28371, -28384, -28403, -28403, -28408, -28412, -28416, -28428, -28442, -28469, -28469, -28495, -28495, -28500, -28511, -28529, -28551, -28551, +28259, +28259, +28286, +28304, +28304, +28331, +28348, +28348, +28366, +28379, +28389, +28398, +28398, +28398, +28423, +28449, +28472, +28514, +28523, +28523, +28542, +28542, 28551, 28551, 28565, -28565, -28565, +28579, +28579, +28589, 28597, -28602, -28602, -28602, -28618, -28618, -28647, -28653, -28653, -28653, -28653, -28663, -28663, -28663, -28677, -28692, -28706, -28734, -28744, -28806, -28806, -28806, -28817, -28838, -28849, -28872, -28872, -28872, -28878, -28878, -28914, -28914, -28935, -28946, +28601, +28633, +28633, +28651, +28679, +28696, +28759, +28759, +28759, +28759, +28759, +28778, +28793, +28836, +28842, +28852, +28859, +28859, +28885, +28885, +28915, +28915, +28915, +28919, +28923, +28971, +28971, 28978, -28978, -28978, -28984, -28984, -28984, -28990, -29021, -29043, -29049, -29049, -29049, -29062, -29097, -29097, -29104, -29112, -29138, -29138, -29138, -29148, -29192, -29192, -29198, -29198, -29198, -29198, -29204, -29210, -29220, -29247, -29257, -29278, -29296, -29328, -29335, -29335, -29353, -29353, -29353, -29360, -29382, -29412, -29429, -29454, -29460, -29460, -29460, -29460, -29498, -29522, -29522, -29537, -29537, -29537, -29537, -29537, -29546, -29546, -29546, -29553, -29570, -29587, -29587, -29587, -29608, -29635, -29682, -29682, -29698, -29721, -29735, -29735, -29752, -29752, -29752, -29752, -29781, -29802, -29802, -29809, -29809, -29816, -29822, -29822, -29840, -29840, -29855, -29866, -29866, -29882, -29882, -29888, -29888, -29888, +28982, +28987, +28991, +28991, +29008, +29031, +29041, +29081, +29081, +29081, +29081, +29088, +29088, +29088, +29100, +29110, +29124, +29147, +29147, +29147, +29153, +29153, +29153, +29175, +29185, +29190, +29214, +29231, +29231, +29231, +29231, +29237, +29265, +29302, +29333, +29333, +29374, +29421, +29446, +29446, +29456, +29456, +29473, +29489, +29497, +29497, +29530, +29538, +29571, +29602, +29623, +29631, +29631, +29642, +29655, +29702, +29702, +29702, +29702, +29720, +29720, +29731, +29753, +29753, +29753, +29765, +29793, +29800, +29849, +29884, +29884, +29884, 29894, -29910, -29946, -29953, -29963, -29963, -29963, -29975, -29990, -30010, -30065, -30083, -30106, -30106, -30106, -30106, -30106, -30106, -30137, -30150, -30150, -30180, -30180, -30201, -30220, -30239, -30239, -30245, -30265, -30280, -30280, -30289, -30320, -30329, -30329, -30346, -30359, -30359, -30359, -30377, -30377, -30390, -30396, -30411, -30462, -30472, -30472, -30500, -30500, -30513, -30513, -30513, -30513, -30520, -30531, -30538, -30549, -30573, +29919, +29940, +29973, +30037, +30037, +30054, +30054, +30054, +30054, +30054, +30066, +30090, +30103, +30144, +30144, +30144, +30165, +30189, +30189, +30189, +30189, +30189, +30208, +30222, +30231, +30241, +30241, +30259, +30269, +30276, +30298, +30298, +30298, +30304, +30304, +30314, +30314, +30314, +30314, +30314, +30314, +30321, +30321, +30321, +30321, +30327, +30327, +30334, +30340, +30340, +30362, +30378, +30385, +30385, +30385, +30385, +30406, +30412, +30424, +30464, +30483, +30483, +30492, +30498, +30522, +30529, +30554, +30554, +30554, +30554, +30572, +30572, 30584, 30584, -30584, -30600, -30600, -30600, -30623, -30623, -30637, -30651, -30670, -30687, -30687, -30687, -30687, -30701, -30701, -30740, -30740, -30740, -30768, -30799, -30809, -30809, -30809, -30809, -30826, -30859, -30859, -30873, -30873, -30877, -30932, -30932, -30932, -30942, -30968, -30987, -30993, -30993, -30993, -31025, -31025, -31025, -31025, -31042, -31051, -31095, -31095, -31110, -31115, -31115, -31115, -31132, -31145, -31145, -31145, -31156, -31194, -31227, -31266, -31266, -31285, -31285, -31322, -31336, -31365, -31384, -31401, -31438, -31446, -31453, -31453, -31465, -31477, -31509, +30606, +30626, +30665, +30678, +30678, +30697, +30725, +30765, +30771, +30771, +30771, +30791, +30791, +30824, +30840, +30844, +30872, +30896, +30896, +30922, +30946, +30946, +30970, +30998, +30998, +31028, +31047, +31070, +31070, +31070, +31076, +31113, +31134, +31140, +31151, +31158, +31165, +31185, +31185, +31185, +31203, +31218, +31233, +31233, +31233, +31256, +31263, +31263, +31287, +31287, +31287, +31297, +31309, +31317, +31327, +31343, +31353, +31353, +31389, +31389, +31389, +31406, +31406, +31406, +31423, +31439, +31439, +31459, +31469, +31476, +31493, +31499, +31515, +31515, 31534, 31534, -31543, -31570, -31590, +31566, +31585, 31608, -31627, -31634, -31653, -31658, +31608, +31626, +31641, +31648, +31648, 31665, -31679, -31701, -31720, -31727, -31727, -31740, -31745, -31759, -31759, -31773, -31788, -31788, -31794, -31807, -31807, -31815, -31821, -31863, -31870, -31870, -31906, -31906, -31913, -31913, -31913, -31928, -31950, -31987, -32023, -32063, -32124, -32124, -32138, -32161, -32168, -32168, -32168, -32212, -32212, -32243, -32250, -32268, -32283, +31665, +31665, +31665, +31681, +31705, +31746, +31768, +31841, +31851, +31927, +31927, +31934, +31962, +31986, +31992, +32008, +32021, +32021, +32021, +32021, +32027, +32027, +32053, +32053, +32057, +32088, +32088, +32098, +32098, +32098, +32129, +32172, +32193, +32208, +32208, +32228, +32228, +32248, +32254, +32274, +32274, 32287, -32307, -32307, -32307, -32307, -32324, -32324, -32366, -32366, -32384, -32384, -32405, -32424, -32447, -32447, -32488, -32505, -32505, -32544, -32563, -32563, -32582, -32589, -32609, -32609, -32640, -32651, -32651, +32309, +32319, +32350, +32355, +32391, +32397, +32397, +32412, +32412, +32419, +32461, +32468, +32468, +32468, +32485, +32485, +32510, +32553, +32565, +32578, +32586, +32591, +32591, +32595, +32608, +32608, +32636, +32636, +32636, 32658, -32699, -32699, -32708, +32676, +32680, +32680, +32695, +32695, +32695, +32695, +32695, 32726, -32763, -32783, -32815, -32815, -32815, -32822, -32822, -32822, -32828, -32828, -32828, -32852, -32872, -32872, -32882, -32907, -32929, +32726, +32768, +32779, +32804, +32821, +32835, +32835, +32835, +32851, +32866, +32881, +32881, +32886, +32886, +32886, +32893, +32893, +32912, +32924, +32935, +32935, +32955, 32975, -33013, -33043, -33060, -33067, -33067, -33077, -33084, -33084, -33090, -33090, -33104, -33117, -33117, -33117, -33133, -33143, -33152, -33162, -33167, +32993, +33012, +33020, +33038, +33046, +33069, +33069, +33118, +33131, +33131, +33157, +33157, +33172, 33177, -33184, -33192, -33192, -33202, -33242, -33242, -33242, -33242, -33249, -33249, -33255, -33260, -33260, -33295, -33314, -33314, -33314, -33314, -33314, -33321, -33325, -33325, -33359, -33359, -33359, -33369, -33389, -33396, -33410, -33414, -33439, -33460, -33473, -33491, -33567, -33581, -33581, -33598, -33598, -33652, -33669, -33669, -33694, -33694, -33694, -33694, -33715, -33715, -33715, -33729, -33759, -33759, -33789, -33793, -33823, -33848, -33855, -33855, -33929, -33936, -33954, -33954, -33954, -33954, +33182, +33197, +33204, +33238, +33254, +33281, +33294, +33309, +33320, +33360, +33360, +33364, +33379, +33379, +33397, +33415, +33415, +33415, +33415, +33415, +33415, +33441, +33465, +33508, +33508, +33508, +33525, +33531, +33558, +33572, +33572, +33579, +33579, +33607, +33636, +33642, +33642, +33663, +33663, +33663, +33663, +33670, +33670, +33670, +33670, +33677, +33677, +33677, +33688, +33688, +33688, +33709, +33723, +33741, +33741, +33741, +33741, +33741, +33741, +33752, +33752, +33752, +33771, +33771, +33771, +33790, +33804, +33824, +33864, +33875, +33886, +33903, +33903, +33916, +33928, +33948, 33961, -33965, -33985, -33985, -33992, -33992, -34006, -34033, -34049, -34076, -34091, -34116, -34146, -34146, -34166, -34166, -34182, -34187, -34187, -34187, -34187, -34204, -34218, -34240, -34280, -34287, -34306, -34306, -34351, -34358, +34011, +34048, +34065, +34097, +34112, +34112, +34112, +34112, +34130, +34148, +34148, +34148, +34178, +34191, +34223, +34228, +34228, +34260, +34260, +34260, +34260, +34282, +34305, +34315, +34315, +34336, +34356, +34373, +34373, 34379, -34379, -34379, -34397, -34404, -34465, -34475, -34480, -34490, -34513, -34542, -34542, -34580, -34600, -34600, -34605, -34605, -34615, -34615, -34632, -34632, -34671, -34697, -34697, -34697, -34718, -34718, -34718, -34718, -34718, -34718, -34725, -34739, -34739, -34739, -34755, -34755, -34784, -34784, -34784, -34791, -34807, -34814, -34830, -34848, -34848, -34848, -34885, -34895, -34895, -34913, -34913, -34941, -34951, -34951, -34958, -34958, -34978, -34995, -35001, -35008, -35020, -35020, -35026, -35033, -35065, -35094, -35141, -35141, -35148, -35173, -35203, -35203, -35223, -35230, -35258, -35292, -35312, -35350, -35368, -35405, -35421, -35427, -35427, -35427, -35427, -35434, -35434, -35446, -35446, +34401, +34419, +34419, +34419, +34419, +34432, +34432, +34438, +34460, +34489, +34508, +34515, +34515, +34515, +34515, +34537, +34546, +34546, +34546, +34546, +34546, +34562, +34573, +34573, +34583, +34621, +34634, +34644, +34664, +34664, +34695, +34719, +34719, +34762, +34762, +34762, +34805, +34811, +34832, +34836, +34836, +34836, +34836, +34865, +34891, +34911, +34916, +34916, +34916, +34916, +34933, +34963, +34979, +34979, +35021, +35035, +35035, +35044, +35055, +35092, +35120, +35120, +35120, +35120, +35120, +35139, +35179, +35208, +35218, +35233, +35249, +35249, +35298, +35309, +35325, +35344, +35344, +35358, +35358, +35395, +35410, +35410, +35419, +35419, +35419, +35419, +35419, 35451, -35466, -35495, -35495, -35528, -35533, -35533, -35548, -35569, -35585, -35585, -35592, -35643, +35470, +35470, +35494, +35523, +35523, +35573, +35573, +35597, +35609, +35644, 35662, +35662, +35676, 35680, -35691, -35691, -35691, -35702, -35711, -35718, -35718, -35738, -35779, -35787, -35787, +35680, +35680, +35680, +35685, +35694, +35694, +35694, +35729, +35747, +35747, +35754, +35761, +35761, +35771, +35793, +35802, 35837, -35863, -35887, -35898, -35910, -35910, -35922, -35941, -35964, -35964, -35964, -35990, -36000, -36017, -36025, -36025, -36033, -36063, -36063, -36063, -36076, +35889, +35889, +35889, +35889, +35899, +35915, +35947, +35947, +35947, +35957, +35957, +35980, +35986, +35986, +35986, +36002, +36050, +36050, +36074, +36084, 36092, -36102, -36102, +36092, +36117, +36117, 36133, -36133, -36133, -36139, -36139, -36139, -36139, -36182, -36205, -36235, -36256, -36268, -36300, -36300, -36300, -36300, -36300, -36308, -36327, -36331, -36368, -36368, -36368, -36380, -36380, -36425, -36444, -36444, -36444, -36456, -36507, -36541, -36554, -36614, -36614, -36614, -36626, -36626, -36626, -36650, -36650, +36156, +36171, +36184, +36227, +36247, +36288, +36288, +36317, +36325, +36342, +36342, +36342, +36349, +36349, +36369, +36378, +36397, +36410, +36410, +36449, +36473, +36473, +36488, +36488, +36500, +36527, +36538, +36538, +36578, +36610, +36632, +36651, +36651, +36651, +36651, 36664, -36668, -36685, -36694, -36694, -36694, -36715, -36715, -36730, -36750, -36766, -36766, -36766, -36792, +36664, +36682, +36682, +36682, +36713, +36732, +36732, +36732, +36732, +36732, +36745, +36745, +36751, +36751, +36770, +36770, +36770, +36776, 36807, -36807, -36807, -36819, -36819, -36842, +36827, +36827, +36844, +36844, +36853, +36863, +36873, +36873, 36880, -36898, -36905, -36918, -36918, -36931, -36931, -36937, -36937, -36969, -36974, -36974, -37012, -37019, -37061, -37061, -37061, -37078, -37116, -37116, -37116, -37125, -37125, -37135, -37135, -37164, -37186, -37198, -37222, -37226, -37234, -37234, -37250, -37250, -37250, -37275, -37289, -37289, -37289, -37327, -37357, -37357, -37364, +36880, +36880, +36884, +36897, +36928, +36928, +36950, +36968, +36973, +36973, +36989, +37055, +37055, +37073, +37085, +37094, +37106, +37157, +37163, +37193, +37232, +37241, +37265, +37265, +37272, +37281, +37324, +37359, 37391, -37391, -37391, -37409, -37409, -37417, -37443, -37474, -37474, -37530, -37540, -37550, -37571, -37571, -37571, -37600, -37621, -37621, -37621, -37642, -37642, -37648, -37669, -37669, +37415, +37429, +37429, +37457, +37457, +37463, +37463, +37469, +37469, +37498, +37498, +37498, +37498, +37498, +37498, +37498, +37498, +37498, +37515, +37526, +37541, +37559, +37597, +37617, +37627, +37634, +37668, +37668, +37668, +37668, +37699, +37706, +37706, +37706, +37706, +37715, 37724, -37724, -37737, -37737, -37737, -37765, -37765, -37765, -37777, -37801, -37813, -37813, -37813, -37826, -37826, -37846, -37883, -37914, -37932, -37932, -37944, -37952, +37733, +37751, +37767, +37767, +37783, +37783, +37793, +37793, +37793, +37806, +37806, +37828, +37841, +37841, +37841, +37841, +37866, +37879, +37879, +37896, +37903, +37910, +37910, +37926, 37971, -37978, -37978, -38002, -38002, -38002, -38031, -38047, -38073, -38073, -38088, -38099, -38099, -38099, -38123, -38123, -38123, -38135, -38159, -38159, -38166, -38166, -38166, -38166, -38209, -38216, -38235, -38252, -38259, -38269, -38269, -38282, -38301, -38313, -38358, -38358, -38358, -38369, -38369, -38385, -38414, -38421, -38451, -38458, -38473, -38491, -38498, -38527, -38534, -38559, -38564, -38571, -38595, -38622, -38628, -38649, -38656, -38671, -38678, -38682, -38706, -38718, -38718, -38738, -38796, -38796, -38796, -38796, -38815, -38822, +37971, +37981, +38033, +38082, +38113, +38122, +38122, +38122, +38122, +38144, +38144, +38144, +38169, +38210, +38244, +38284, +38328, +38339, +38339, +38377, +38402, +38412, +38429, +38429, +38452, +38474, +38481, +38488, +38488, +38488, +38488, +38511, +38525, +38568, +38568, +38575, +38592, +38613, +38629, +38629, +38654, +38684, +38684, +38703, +38710, +38710, +38735, +38748, +38755, +38762, +38776, +38776, +38776, +38776, +38776, +38812, +38819, 38834, -38853, -38853, -38885, -38897, -38940, -38971, -38978, -38998, -39042, -39054, -39054, -39085, -39092, -39109, -39146, -39165, -39177, -39177, -39196, -39212, -39247, -39247, -39267, -39279, -39295, -39319, -39319, -39330, -39330, -39342, -39354, -39354, -39364, -39364, -39401, -39420, -39441, +38847, +38854, +38861, +38868, +38868, +38888, +38888, +38908, +38908, +38915, +38926, +38942, +38949, +38956, +38956, +38956, +38963, +38980, +38980, +39003, +39009, +39039, +39052, +39059, +39077, +39084, +39084, +39091, +39091, +39108, +39115, +39115, +39150, +39150, +39179, +39184, +39184, +39240, +39240, +39277, +39284, +39284, +39284, +39309, +39351, +39358, +39363, +39395, +39408, +39421, +39421, +39427, +39427, +39440, 39453, -39475, -39485, -39485, -39517, -39553, -39553, -39553, -39558, -39593, -39600, -39621, -39648, -39682, -39697, -39704, -39716, -39743, -39750, -39757, -39757, -39774, -39781, -39788, -39818, -39854, -39861, -39861, -39868, +39461, +39461, +39473, +39473, +39473, +39490, +39497, +39510, +39510, +39516, +39516, +39523, +39523, +39535, +39544, +39551, +39561, +39561, +39568, +39568, +39585, +39585, +39592, +39592, +39599, +39622, +39622, +39637, +39677, +39715, +39736, +39765, +39765, +39775, +39793, +39793, +39814, +39850, +39864, +39889, 39893, -39900, -39907, -39913, -39913, -39913, -39920, -39932, +39917, +39927, +39934, +39934, +39952, 39959, -39971, -39971, -39998, +39977, +39984, +39991, +40009, +40009, 40013, 40013, -40042, -40042, -40054, -40061, -40061, -40065, -40083, -40118, -40118, -40127, +40032, +40032, +40032, +40032, +40032, +40032, +40047, +40062, +40078, +40078, +40095, +40131, 40137, -40171, -40198, +40151, +40186, +40201, +40208, 40227, -40242, -40269, -40276, -40276, -40283, -40290, -40315, -40321, -40344, -40344, -40355, -40375, -40375, -40375, -40386, -40408, -40431, -40453, -40469, -40505, -40515, -40524, -40555, -40594, +40236, +40236, +40243, +40250, +40250, +40359, +40366, +40373, +40380, +40404, +40404, +40415, +40422, +40434, +40458, +40465, +40472, +40472, +40472, +40472, +40497, +40502, +40509, +40527, +40527, +40540, +40547, +40562, +40569, +40584, +40591, +40591, +40598, +40605, +40605, 40612, -40625, -40642, -40662, -40662, -40692, -40705, -40712, -40727, -40740, -40747, +40619, +40630, +40660, +40667, +40674, +40690, +40714, +40721, +40748, +40763, 40770, -40803, -40807, -40807, -40807, -40832, -40843, -40850, -40857, -40940, -40958, -40958, -40958, -40958, -40989, -40989, -41005, -41014, -41034, -41041, -41063, -41070, -41070, -41102, -41102, -41109, -41116, -41122, -41146, -41180, -41180, -41203, -41203, -41210, -41217, -41217, -41234, -41248, -41265, -41279, -41302, -41327, -41337, -41347, -41347, -41355, -41364, -41370, -41388, -41388, -41399, -41399, -41412, -41412, -41424, -41424, -41424, -41424, -41428, -41441, -41441, -41441, -41453, -41460, +40784, +40795, +40827, +40827, +40841, +40841, +40870, +40870, +40889, +40889, +40889, +40936, +40942, +40952, +40982, +40991, +41001, +41017, +41033, +41040, +41060, +41073, +41104, +41114, +41114, +41149, +41149, +41149, +41149, +41149, +41156, +41221, +41244, +41266, +41292, +41292, +41309, +41309, +41318, +41325, +41361, +41389, +41415, +41415, +41442, +41457, +41471, 41478, -41484, -41484, -41534, -41571, -41571, -41578, -41590, -41607, -41614, -41621, -41621, -41636, -41642, -41642, -41660, -41667, -41712, -41732, -41732, -41751, -41758, -41758, -41774, -41774, -41783, -41792, +41478, +41478, +41487, +41487, +41502, +41518, +41553, +41553, +41575, +41575, +41575, +41596, +41596, +41596, +41596, +41603, +41603, +41603, +41603, +41617, +41625, +41638, +41671, +41704, +41721, +41752, +41788, +41810, +41828, +41842, 41849, -41856, -41856, -41856, -41869, -41869, -41869, -41869, -41879, -41879, -41885, -41891, -41891, -41903, -41913, -41934, -41951, -41985, -41985, -42013, -42035, -42069, -42114, +41849, +41859, +41874, +41881, +41881, +41881, +41881, +41881, +41906, +41919, +41935, +41942, +41942, +41959, +41959, +41966, +41973, +41980, +41980, +41987, +42017, +42024, +42031, +42031, +42038, +42045, +42055, +42092, +42125, 42144, 42151, +42162, 42181, -42221, +42192, +42215, +42215, 42241, -42241, -42248, -42248, -42283, +42255, +42255, +42255, +42255, +42255, +42279, 42290, -42340, -42340, -42340, -42352, -42352, -42352, -42403, -42403, -42435, -42435, -42446, -42453, -42460, -42477, -42477, -42496, -42496, -42512, -42526, -42538, -42563, -42563, -42570, -42570, -42570, -42619, -42636, -42657, -42657, -42657, -42657, -42657, -42657, -42657, -42657, -42657, -42665, -42672, -42697, -42715, -42734, -42734, -42734, -42751, -42782, -42782, -42805, -42826, -42856, -42856, -42869, -42869, -42879, -42895, -42895, -42909, -42922, -42940, -42940, -42940, -42944, -42944, -42954, -42954, -42984, -43000, -43018, -43018, -43038, -43049, +42297, +42315, +42315, +42315, +42356, +42356, +42356, +42382, +42382, +42389, +42398, +42398, +42398, +42408, +42426, +42426, +42437, +42443, +42448, +42448, +42448, +42470, +42470, +42478, +42520, +42546, +42556, +42571, +42588, +42594, +42645, +42656, +42656, +42656, +42656, +42673, +42680, +42680, +42680, +42688, +42688, +42719, +42758, +42758, +42758, +42768, +42794, +42794, +42794, +42806, +42822, +42846, +42865, +42865, +42874, +42874, +42887, +42887, +42894, +42920, +42932, +42932, +42966, +42987, +42987, +42987, +43015, +43030, +43041, +43041, 43049, 43069, -43069, -43069, -43069, -43117, -43134, -43203, -43203, -43203, -43218, -43218, -43238, +43082, +43082, +43082, +43082, +43108, +43125, +43147, +43155, +43174, +43180, +43193, +43193, +43193, +43193, +43193, +43193, +43220, +43232, +43232, +43232, +43246, +43262, 43270, -43289, -43302, -43302, -43354, -43354, -43360, -43360, -43360, -43360, -43360, -43360, -43386, -43393, -43407, -43427, -43434, -43434, -43452, -43458, -43458, -43469, -43484, -43491, -43491, -43491, -43508, -43553, -43560, -43569, -43569, -43569, -43586, -43586, -43623, -43639, -43639, -43639, -43661, -43661, -43682, -43682, -43700, -43700, -43700, -43700, -43700, -43706, -43721, -43721, -43736, -43742, -43748, -43748, -43748, -43759, -43759, -43769, -43769, -43778, +43278, +43278, +43278, +43278, +43301, +43301, +43320, +43320, +43366, +43370, +43388, +43388, +43388, +43433, +43447, +43462, +43462, +43462, +43462, +43462, +43495, +43495, +43521, +43528, +43528, +43552, +43612, +43612, +43632, +43648, +43659, +43666, +43693, +43710, +43723, +43728, +43757, +43768, +43780, +43797, +43797, +43797, 43809, -43824, -43828, -43828, -43828, -43834, -43877, -43884, -43884, -43895, -43895, -43909, -43954, -43954, -43954, -43961, -43961, -43961, -43961, -43961, -43985, -44003, -44003, -44009, -44021, -44053, -44053, -44081, -44081, -44081, -44081, -44102, -44137, -44158, -44167, -44167, -44179, -44179, -44179, -44185, -44204, -44204, -44204, -44223, -44246, -44246, -44260, -44271, -44289, -44289, -44289, -44289, -44306, -44329, -44344, -44365, -44388, -44388, -44414, -44414, -44414, +43816, +43821, +43849, +43871, +43890, +43923, +43923, +43932, +43940, +43940, +43958, +43979, +43979, +43979, +43979, +44002, +44002, +44002, +44002, +44058, +44077, +44099, +44129, +44140, +44146, +44146, +44146, +44165, +44178, +44178, +44202, +44202, +44220, +44238, +44255, +44255, +44263, +44280, +44298, +44302, +44302, +44330, +44351, +44351, +44363, +44363, +44363, +44378, +44385, +44406, +44406, 44434, -44457, -44457, -44468, -44468, -44481, -44496, -44505, -44505, -44518, -44518, -44531, -44531, -44562, -44570, -44582, -44582, -44603, -44629, -44629, -44629, -44649, -44649, -44649, -44649, -44649, -44649, -44662, -44662, -44677, -44677, -44705, -44719, -44733, -44733, -44750, -44754, -44754, -44754, -44789, -44811, +44444, +44472, +44472, +44472, +44488, +44492, +44523, +44561, +44592, +44611, +44611, +44632, +44644, +44644, +44651, +44651, +44651, +44651, +44651, +44684, +44684, +44690, +44706, +44725, +44731, +44731, +44731, +44731, +44746, +44746, +44757, +44757, +44757, +44757, +44787, +44787, +44787, +44787, +44787, +44799, +44812, +44812, 44827, -44840, -44840, -44875, -44875, -44875, -44885, -44894, -44915, -44923, -44929, -44929, -44929, -44945, -44945, -44945, -44964, -44964, -45001, -45010, -45020, -45020, -45020, -45020, -45020, -45030, -45052, -45068, -45068, -45101, -45143, -45147, -45166, -45210, -45247, -45267, -45267, -45267, -45276, -45319, -45323, -45323, -45323, -45323, -45323, -45323, -45323, -45323, -45323, -45334, -45334, -45352, -45371, -45371, -45383, -45392, -45410, -45410, -45424, -45434, -45447, -45454, -45454, -45454, -45472, -45472, -45472, -45483, -45483, -45494, -45503, -45503, -45519, -45541, -45541, -45541, -45566, -45578, -45578, -45578, -45635, -45664, -45684, -45722, -45722, -45733, -45733, -45733, -45742, -45742, +44847, +44856, +44856, +44856, +44856, +44884, +44899, +44911, +44911, +44911, +44928, +44958, +44958, +44981, +44981, +44990, +45012, +45037, +45037, +45046, +45046, +45073, +45073, +45085, +45096, +45096, +45100, +45113, +45123, +45158, +45173, +45206, +45214, +45230, +45230, +45258, +45268, +45295, +45307, +45307, +45307, +45307, +45307, +45307, +45338, +45338, +45355, +45372, +45372, +45393, +45393, +45393, +45403, +45403, +45403, +45414, +45455, +45455, +45455, +45455, +45455, +45463, +45463, +45478, +45497, +45514, +45514, +45524, +45540, +45540, +45540, +45558, +45558, +45558, +45558, +45574, +45574, +45574, +45590, +45654, +45674, +45686, +45686, +45686, +45705, +45705, +45711, +45721, +45732, +45732, +45732, +45732, +45732, +45738, +45748, +45748, 45769, -45794, -45803, -45811, -45824, -45831, -45854, -45866, -45872, -45872, -45872, -45891, +45789, +45789, +45800, +45837, +45856, +45868, +45876, +45885, +45902, 45908, -45908, -45922, -45922, -45922, -45938, -45945, -45945, -45945, -45967, -45973, -45997, -46019, -46025, -46038, -46038, -46057, -46057, -46074, -46074, -46083, -46083, -46088, -46115, -46145, -46151, -46157, -46170, -46178, -46178, -46190, -46211, -46211, -46224, -46235, -46235, -46235, -46235, -46235, -46242, -46263, -46263, -46263, -46263, -46275, -46296, -46296, -46310, -46310, -46310, -46325, -46325, -46325, -46325, -46325, -46332, -46332, -46364, -46364, -46364, -46364, -46364, -46381, -46381, -46381, -46418, -46418, -46418, -46453, -46478, -46521, -46527, -46527, -46527, -46527, -46527, -46527, -46563, -46613, -46613, -46613, -46643, -46682, -46682, -46682, -46682, -46682, -46719, -46719, -46740, -46740, +45918, +45918, +45918, +45948, +45976, +45976, +45976, +45976, +45981, +46009, +46016, +46027, +46027, +46027, +46034, +46050, +46090, +46108, +46108, +46112, +46119, +46126, +46149, +46149, +46149, +46149, +46169, +46193, +46193, +46193, +46204, +46213, +46222, +46222, +46238, +46245, +46257, +46257, +46301, +46301, +46322, +46322, +46322, +46327, +46345, +46359, +46374, +46384, +46417, +46417, +46428, +46458, +46458, +46458, +46493, +46493, +46500, +46505, +46555, +46567, +46567, +46580, +46580, +46580, +46595, +46595, +46595, +46595, +46628, +46628, +46652, +46652, +46669, +46669, +46698, +46718, +46718, +46718, +46738, 46753, -46774, -46793, -46797, -46811, -46811, -46821, -46856, -46866, -46879, -46890, -46890, -46897, -46897, -46897, -46897, -46897, -46904, -46904, -46921, -46921, -46921, -46921, -46948, -46948, -46948, -46970, -46970, -46970, -46986, -46986, -47006, -47006, -47020, -47020, -47036, -47046, -47061, -47061, -47070, -47070, -47085, -47085, -47106, -47144, -47161, -47171, -47181, -47181, -47218, -47218, -47218, -47238, -47238, -47248, -47253, -47257, -47262, -47284, -47297, -47297, -47297, -47317, -47334, -47334, -47334, -47369, -47375, -47397, +46761, +46776, +46776, +46776, +46794, +46794, +46802, +46816, +46846, +46863, +46899, +46899, +46899, +46907, +46907, +46917, +46930, +46957, +46957, +46961, +46961, +46969, +46975, +46975, +46975, +46991, +46999, +46999, +47012, +47018, +47018, +47048, +47058, +47076, +47145, +47145, +47162, +47183, +47228, +47244, +47267, +47267, +47295, +47295, +47295, +47316, +47316, +47316, +47353, +47361, +47385, +47385, +47415, +47419, +47430, +47450, 47465, -47465, -47480, -47489, -47502, -47520, -47520, -47526, -47570, -47583, -47583, -47591, -47612, -47668, -47715, -47715, -47715, -47715, -47715, -47715, -47725, -47742, -47742, -47742, -47742, -47742, -47742, -47742, -47773, -47773, -47798, -47821, -47878, -47878, -47878, -47878, -47878, -47885, -47892, -47892, -47910, -47955, -47973, -48000, -48010, -48035, -48047, -48067, -48079, -48079, -48088, -48114, -48128, -48150, -48175, -48193, +47470, +47470, +47470, +47470, +47479, +47501, +47521, +47529, +47536, +47554, +47572, +47572, +47597, +47606, +47614, +47614, +47614, +47623, +47623, +47660, +47660, +47669, +47681, +47694, +47694, +47694, +47698, +47702, +47720, +47720, +47730, +47749, +47767, +47790, +47808, +47824, +47824, +47824, +47830, +47830, +47836, +47869, +47869, +47875, +47898, +47898, +47958, +47962, +47978, +47978, +47985, +48019, +48023, +48023, +48023, +48023, +48043, +48043, +48058, +48058, +48058, +48058, +48065, +48070, +48101, +48101, +48116, +48127, +48127, +48139, +48139, +48163, +48163, +48177, +48177, 48204, -48216, -48234, -48234, -48251, -48270, -48310, -48319, -48319, -48319, -48337, -48337, -48344, -48344, -48344, -48350, -48350, -48382, -48382, -48382, -48382, -48402, -48409, -48409, -48422, -48437, -48453, -48453, -48453, -48471, -48471, -48471, -48471, -48477, -48477, -48505, -48512, -48512, -48539, -48539, -48580, -48602, -48602, -48615, -48630, -48630, -48649, -48649, -48649, -48672, -48690, -48690, -48697, -48753, -48753, -48804, -48804, -48804, -48804, -48804, -48804, -48810, -48826, -48837, -48837, -48837, -48845, -48866, +48218, +48246, +48262, +48262, +48262, +48283, +48283, +48306, +48306, +48312, +48312, +48317, +48331, +48347, +48354, +48364, +48364, +48364, +48394, +48447, +48452, +48452, +48476, +48476, +48476, +48542, +48572, +48582, +48622, +48658, +48669, +48669, +48669, +48686, +48686, +48686, +48693, +48693, +48699, +48724, +48741, +48741, +48752, +48764, +48784, +48784, +48794, +48799, +48799, +48799, +48799, +48820, +48830, 48866, +48884, 48894, -48894, -48904, -48909, -48909, -48921, -48921, -48921, -48931, -48949, -48963, -48963, -49002, -49019, -49038, -49038, -49038, -49047, +48913, +48913, +48913, +48913, +48925, +48966, +48975, +48975, +48975, +48980, +48987, +49020, +49028, 49054, -49063, -49083, -49102, -49119, -49133, -49133, -49174, -49235, -49235, -49235, -49235, -49235, -49235, -49268, -49268, +49060, +49060, +49086, +49110, +49110, +49121, +49121, +49121, +49134, +49134, +49134, +49141, +49171, +49185, +49197, +49228, +49254, +49254, 49286, -49305, -49320, -49320, -49320, -49320, -49320, -49320, -49320, -49326, -49366, -49386, -49394, -49427, +49302, +49315, +49315, +49353, +49362, +49374, +49385, +49412, +49419, 49447, 49447, -49447, -49468, -49468, -49468, -49494, -49494, -49494, -49504, -49504, -49504, -49504, -49524, -49532, -49558, -49558, -49558, -49572, -49582, -49582, -49597, -49617, -49625, -49638, -49638, -49638, -49645, -49645, -49651, -49651, -49651, -49651, -49651, -49651, -49651, -49651, -49673, -49673, -49673, -49736, -49736, +49489, +49514, +49526, +49526, +49559, +49559, +49603, +49615, +49655, +49667, +49667, +49682, +49699, 49743, -49748, -49748, -49748, -49791, -49819, -49837, -49837, -49855, -49867, -49905, -49927, -49927, -49959, -49972, +49743, +49755, +49755, +49755, +49768, +49778, +49799, +49816, +49816, +49816, +49822, +49822, +49835, +49854, +49872, +49872, +49872, +49882, +49882, +49945, +49969, 49978, 49993, 49993, -49993, -50001, -50001, -50001, -50034, +50028, 50044, -50050, -50050, -50069, -50069, +50054, 50076, -50076, -50105, +50083, +50108, +50108, 50120, 50120, -50127, -50150, -50156, -50178, -50193, -50193, -50209, -50219, -50245, -50266, -50306, -50306, -50306, -50318, -50360, -50406, -50414, -50426, -50426, -50450, -50458, -50465, -50465, +50143, +50143, +50202, +50202, +50214, +50265, +50279, +50279, +50291, +50291, +50316, +50366, +50366, +50387, +50387, +50387, +50387, +50387, +50405, +50405, +50425, +50425, +50432, +50432, +50432, +50439, +50439, +50463, +50470, +50470, +50470, +50470, +50474, +50486, 50495, 50495, -50508, -50508, -50513, -50513, -50513, -50531, -50541, -50556, -50556, -50556, -50556, -50556, -50581, -50631, -50631, -50640, -50656, -50662, -50662, -50673, -50694, -50694, -50694, -50694, -50694, -50718, -50718, -50742, -50763, -50817, -50827, -50827, -50842, -50861, -50861, -50867, -50867, -50899, -50899, -50899, -50899, -50899, -50923, -50923, -50923, -50972, -50984, -51009, -51009, -51009, -51030, -51030, -51030, -51030, -51030, -51051, -51051, -51051, -51051, -51060, -51060, -51069, -51090, -51140, -51140, -51160, -51174, -51188, -51209, -51216, -51222, -51222, -51222, -51229, -51245, -51263, -51263, -51263, +50518, +50518, +50518, +50533, +50558, +50579, +50579, +50601, +50611, +50645, +50674, +50674, +50692, +50729, +50748, +50784, +50784, +50801, +50814, +50831, +50831, +50831, +50831, +50844, +50856, +50860, +50872, +50909, +50921, +50921, +50964, +50964, +50986, +51006, +51006, +51006, +51021, +51021, +51029, +51035, +51047, +51058, +51058, +51062, +51089, +51089, +51120, +51120, +51120, +51126, +51126, +51139, +51139, +51153, +51153, +51153, +51153, +51165, +51186, +51186, +51208, +51247, +51247, +51247, +51261, 51273, 51273, -51273, -51288, -51316, -51316, -51334, -51334, -51334, -51334, -51351, -51351, -51351, -51351, -51351, -51351, -51351, -51351, -51366, -51366, -51376, -51399, -51399, -51427, -51476, -51483, -51483, -51483, -51499, -51499, -51499, +51298, +51298, +51298, +51321, +51321, +51321, +51338, +51343, +51371, +51395, +51417, +51417, +51417, +51426, +51426, +51426, +51445, +51455, +51469, +51469, +51488, +51492, +51492, +51511, 51529, -51542, -51576, -51576, -51576, -51576, -51588, -51605, -51630, -51654, -51654, -51675, -51675, -51704, -51704, -51704, -51710, -51710, -51710, -51729, -51729, -51729, +51529, +51549, +51549, +51564, +51583, +51611, +51622, +51644, +51644, +51644, +51656, +51674, +51674, +51700, +51733, 51741, -51753, -51774, -51787, -51802, -51812, -51816, -51816, -51832, -51846, -51846, -51846, -51846, -51853, -51853, -51853, -51881, -51881, -51889, -51889, -51889, -51909, -51913, -51913, -51913, -51932, -51965, -51965, -51981, -51989, -52030, -52050, -52078, -52082, -52092, -52092, -52097, -52122, -52122, -52122, -52140, -52161, -52161, -52174, -52198, -52198, -52198, -52198, -52241, -52249, -52249, -52259, -52259, -52265, -52280, -52280, -52280, -52280, -52280, -52308, -52308, -52320, -52320, -52320, -52336, -52336, -52350, -52358, -52358, -52358, -52384, -52394, -52394, -52394, -52424, -52431, -52431, -52440, -52447, -52452, -52452, -52460, -52460, -52488, -52510, -52530, -52548, -52556, -52576, -52576, -52593, -52664, -52664, -52672, -52676, -52682, -52682, -52692, -52714, -52714, -52742, -52742, -52746, -52762, -52762, -52803, -52810, -52810, -52810, -52810, -52810, -52828, -52835, -52845, -52859, -52869, -52880, -52880, -52880, -52906, -52906, -52922, -52929, -52929, -52957, -52967, -52967, -52967, -52967, -52967, -52996, -53025, -53029, -53036, -53065, -53065, -53065, -53065, -53088, -53102, -53102, -53102, -53110, -53118, -53144, -53144, -53184, -53212, -53212, -53237, -53247, -53247, -53276, -53276, -53288, -53298, -53298, -53298, -53306, -53306, -53306, -53321, -53321, -53341, -53360, -53360, -53360, -53360, -53360, -53408, -53428, -53441, -53474, -53474, -53481, -53516, -53558, -53603, -53603, -53603, -53603, -53611, -53618, -53638, -53638, -53638, -53657, -53683, -53698, -53714, -53714, -53718, -53718, -53732, -53744, -53744, -53752, -53758, -53793, -53793, -53816, -53816, -53825, -53855, -53855, -53884, -53884, -53890, -53890, -53935, -53935, -53935, -53939, -53939, -53939, -53949, -53961, -53961, -53967, -53967, -53967, -53967, -53984, -53992, -54002, -54002, -54013, -54029, -54048, -54048, -54061, -54107, -54107, +51768, +51822, +51829, +51850, +51850, +51857, +51857, +51867, +51874, +51874, +51874, +51874, +51888, +51910, +51938, +51945, +51958, +51976, +51990, +51990, +52007, +52033, +52043, +52055, +52055, +52095, +52111, +52123, +52128, +52128, +52147, +52153, +52175, +52199, +52223, +52223, +52223, +52223, +52223, +52223, +52262, +52283, +52324, +52346, +52346, +52380, +52380, +52395, +52395, +52407, +52407, +52419, +52426, +52439, +52483, +52495, +52495, +52514, +52514, +52523, +52523, +52535, +52559, +52559, +52563, +52563, +52582, +52594, +52644, +52661, +52661, +52720, +52732, +52740, +52740, +52740, +52740, +52759, +52782, +52809, +52809, +52821, +52833, +52853, +52853, +52853, +52887, +52899, +52903, +52930, +52930, +52942, +52942, +52972, +53012, +53012, +53054, +53066, +53066, +53066, +53092, +53106, +53124, +53124, +53131, +53171, +53176, +53176, +53176, +53176, +53186, +53186, +53210, +53230, +53230, +53230, +53240, +53277, +53291, +53291, +53291, +53302, +53320, +53320, +53347, +53347, +53364, +53378, +53382, +53399, +53424, +53437, +53437, +53437, +53470, +53470, +53470, +53477, +53477, +53484, +53484, +53484, +53499, +53499, +53499, +53504, +53510, +53528, +53528, +53528, +53537, +53537, +53537, +53542, +53547, +53570, +53576, +53601, +53601, +53606, +53606, +53625, +53625, +53643, +53650, +53686, +53686, +53693, +53724, +53743, +53759, +53764, +53764, +53774, +53774, +53794, +53800, +53835, +53851, +53851, +53871, +53892, +53917, +53917, +53925, +53925, +53925, +53973, +53973, +53977, +53998, +54018, +54036, +54054, +54062, +54123, +54123, +54123, 54142, -54142, -54153, -54153, -54170, -54180, -54233, -54233, -54246, -54246, -54246, -54246, -54246, -54250, -54250, -54260, -54260, -54277, -54284, -54302, -54325, -54352, -54352, -54366, -54394, -54394, -54400, -54421, -54421, -54421, -54426, -54426, -54426, -54434, -54434, -54434, -54452, -54452, -54460, -54484, -54484, -54484, -54489, -54511, -54535, -54547, -54562, -54562, -54584, -54612, -54620, -54637, -54637, -54637, -54645, -54655, -54661, -54680, -54680, -54690, -54710, -54714, -54714, -54714, -54750, -54762, -54762, -54762, -54781, -54803, -54813, -54813, -54813, -54818, -54818, -54831, -54849, -54865, -54893, -54893, -54893, -54893, -54893, -54907, -54907, -54907, -54907, -54907, -54911, -54911, -54911, -54931, -54931, -54931, -54945, -54945, -54956, -54956, -54956, -54956, +54194, +54194, +54208, +54232, +54242, +54259, +54259, +54268, +54275, +54282, +54305, +54312, +54335, +54348, +54355, +54369, +54369, +54369, +54382, +54382, +54382, +54410, +54436, +54456, +54456, +54456, +54463, +54463, +54472, +54497, +54537, +54569, +54591, +54591, +54591, +54591, +54617, +54617, +54664, +54664, +54664, +54664, +54693, +54700, +54700, +54736, +54746, +54771, +54782, +54804, +54850, +54868, +54901, +54901, +54921, +54921, +54921, 54960, -54994, -54994, +54987, +54993, 55000, -55018, -55034, -55040, -55050, +55000, +55028, +55037, 55066, -55066, -55066, -55066, -55084, -55084, -55103, -55110, -55110, -55110, -55110, -55129, -55129, -55135, -55154, -55154, -55179, -55179, -55192, -55208, -55218, +55118, +55133, +55133, +55133, +55138, +55138, +55138, +55138, +55138, +55159, +55191, +55191, +55191, 55226, -55226, -55240, -55261, -55281, -55292, -55313, +55232, +55232, +55242, +55257, +55257, +55270, +55270, +55270, +55298, +55317, +55317, +55317, +55317, +55317, +55317, 55331, -55351, -55388, -55388, -55434, -55456, -55476, -55476, -55476, -55494, -55494, -55510, -55510, -55526, -55526, -55538, +55350, +55350, +55350, +55363, +55387, +55387, +55411, +55411, +55422, +55435, +55481, +55490, +55502, +55502, +55502, +55520, +55532, 55554, -55554, -55564, -55564, -55573, -55573, -55623, -55653, -55678, -55697, +55563, +55570, +55585, +55585, +55603, +55610, +55610, +55662, +55662, +55684, +55700, 55707, 55707, -55707, -55725, -55725, -55741, -55741, -55756, -55810, +55749, +55765, +55784, +55784, +55784, +55791, +55791, +55791, +55816, 55823, -55823, -55823, -55848, -55848, -55865, -55865, -55874, -55899, -55899, -55905, -55919, -55932, -55960, -55993, -56010, +55852, +55852, +55906, +55941, +55971, +55971, +55978, +55978, +55978, +55987, +56011, +56018, +56024, +56024, +56024, +56055, 56071, -56083, -56083, -56100, -56115, -56115, -56115, -56133, -56140, -56140, -56159, -56174, -56189, -56189, -56237, -56237, -56252, -56268, -56268, -56268, -56285, -56294, -56328, -56328, -56334, -56334, -56334, -56351, -56371, -56381, -56409, -56441, -56441, -56477, -56477, -56477, -56477, -56481, -56481, -56491, -56491, -56491, -56491, -56491, +56071, +56078, +56078, +56085, +56092, +56122, +56141, +56141, +56141, +56141, +56146, +56146, +56155, +56178, +56209, +56238, +56257, +56257, +56257, +56262, +56275, +56275, +56275, +56275, +56290, +56307, +56323, +56341, +56341, +56347, +56366, +56375, +56375, +56375, +56375, +56413, +56445, +56450, +56450, +56450, +56454, +56460, +56467, +56490, +56510, 56517, -56517, -56517, -56517, -56556, -56572, -56572, -56621, -56634, -56634, -56669, -56679, -56679, -56688, -56705, -56711, -56733, -56733, -56740, -56744, -56744, -56752, -56752, -56752, -56764, -56792, -56806, -56810, -56810, -56830, -56850, -56850, -56858, -56881, -56881, -56906, -56906, -56906, -56906, -56944, -56957, -56961, -56988, -56988, -56988, -57012, -57018, -57043, -57052, -57066, -57077, -57114, -57114, -57134, -57134, -57134, -57173, -57182, -57182, -57205, -57205, -57205, -57225, -57245, -57245, -57259, -57259, -57259, -57292, -57351, -57355, -57365, -57370, -57393, -57419, -57435, -57444, -57444, -57449, -57449, -57468, -57468, -57474, -57491, -57517, -57538, -57556, -57556, -57560, +56527, +56534, +56534, +56534, +56565, +56577, +56577, +56584, +56608, +56608, +56615, +56615, +56640, +56658, +56658, +56658, +56677, +56677, +56701, +56701, +56722, +56750, +56757, +56757, +56802, +56802, +56802, +56821, +56839, +56863, +56863, +56874, +56874, +56905, +56941, +56976, +57006, +57006, +57025, +57032, +57037, +57037, +57061, +57061, +57067, +57067, +57074, +57093, +57131, +57138, +57138, +57158, +57158, +57158, +57169, +57169, +57177, +57191, +57191, +57191, +57191, +57226, +57248, +57261, +57278, +57306, +57306, +57329, +57329, +57349, +57349, +57356, +57356, +57409, +57416, +57422, +57422, +57446, +57463, +57463, +57463, +57487, +57507, +57507, +57507, +57528, +57528, +57528, +57535, +57542, +57542, 57578, 57578, 57592, -57601, -57601, -57601, -57601, -57619, -57629, -57647, -57647, -57647, -57681, -57681, -57687, -57693, -57726, -57726, -57733, -57775, -57775, -57775, -57787, -57805, -57819, -57848, -57848, -57848, -57867, -57886, -57913, -57942, -57949, -57977, +57592, +57598, +57598, +57645, +57651, +57665, +57665, +57684, +57684, +57692, +57692, +57692, +57709, +57724, +57724, +57766, +57766, +57773, +57773, +57780, +57780, +57797, +57842, +57842, +57842, +57842, +57852, +57852, +57852, +57869, +57882, +57899, +57899, +57936, +57943, +57943, +57973, +57989, +58001, +58001, +58001, +58001, 58024, -58067, -58075, +58024, +58024, +58024, +58051, +58051, +58051, 58082, -58082, -58099, -58121, -58134, -58141, -58141, +58091, +58091, +58091, +58097, +58097, +58097, +58130, +58130, +58130, +58130, +58130, +58150, +58150, 58166, -58174, -58193, -58200, -58207, -58221, -58231, -58236, -58236, -58244, -58251, -58258, -58258, -58297, -58346, -58353, -58376, -58376, -58391, -58413, -58424, -58439, -58446, -58470, -58480, -58487, -58494, -58494, +58166, +58171, +58171, +58203, +58209, +58216, +58229, +58235, +58242, +58249, +58260, +58267, +58322, +58332, +58372, +58372, +58384, +58384, +58384, +58405, +58430, +58449, +58476, +58492, +58492, +58499, 58506, -58521, -58528, -58542, -58549, -58549, -58549, -58562, -58569, -58584, -58596, -58596, -58639, -58639, -58639, -58646, -58652, -58652, -58652, -58662, -58678, -58678, -58678, +58520, +58554, +58560, +58579, +58595, +58627, +58651, +58651, +58651, +58658, +58679, 58686, -58724, -58747, -58752, -58776, -58799, -58817, -58817, -58817, -58825, -58840, -58840, -58887, -58893, -58893, -58906, -58926, -58944, -58944, -58993, -58993, -59003, -59039, -59058, -59075, -59115, -59132, -59146, -59153, -59200, -59210, -59214, +58686, +58686, +58714, +58714, +58728, +58735, +58753, +58753, +58770, +58777, +58842, +58842, +58859, +58879, +58886, +58886, +58940, +58940, +58964, +58964, +58982, +58988, +59002, +59032, +59056, +59067, +59083, +59112, +59112, +59121, +59152, +59152, +59180, +59185, +59192, +59192, +59192, +59219, 59229, -59233, -59245, -59245, -59284, -59300, -59317, -59324, -59344, -59364, -59364, -59364, -59387, -59423, -59435, -59435, -59435, -59435, -59435, -59442, -59442, -59470, -59491, -59505, -59512, -59535, -59542, -59542, -59572, -59600, -59623, -59636, -59643, -59681, -59703, -59736, -59753, -59758, -59773, -59773, -59773, -59795, -59822, -59849, -59862, -59877, -59877, -59901, -59943, -59943, -59965, -59965, -59965, -59994, -60005, -60027, -60027, -60077, -60098, -60114, -60121, -60146, -60163, -60170, -60194, -60205, -60205, -60231, -60236, -60236, -60236, -60250, -60277, -60293, -60315, -60338, -60401, -60401, -60401, +59229, +59229, +59229, +59229, +59239, +59239, +59250, +59265, +59288, +59306, +59306, +59318, +59329, +59329, +59350, +59368, +59377, +59394, +59417, +59444, +59465, +59465, +59472, +59472, +59472, +59479, +59479, +59479, +59497, +59514, +59514, +59514, +59528, +59528, +59554, +59554, +59592, +59597, +59628, +59669, +59676, +59683, +59690, +59690, +59719, +59757, +59757, +59764, +59782, +59793, +59819, +59823, +59835, +59850, +59879, +59886, +59893, +59903, +59903, +59918, +59918, +59935, +59963, +59963, +60006, +60030, +60034, +60041, +60041, +60060, +60060, +60074, +60074, +60103, +60103, +60110, +60124, +60138, +60138, +60138, +60152, +60162, +60171, +60186, +60186, +60192, +60240, +60260, +60298, +60298, +60298, +60340, +60354, +60361, +60390, +60390, 60408, -60425, -60425, -60432, -60451, -60458, -60465, -60498, -60505, -60527, -60534, -60541, -60558, +60446, +60452, +60452, +60475, +60482, +60489, +60509, +60509, +60509, +60524, +60531, +60531, +60557, +60564, +60581, 60586, -60606, -60606, -60606, -60639, -60672, -60701, -60738, -60755, -60769, -60796, -60803, -60882, -60889, -60896, -60919, -60926, -60939, -60943, -61009, -61064, -61064, -61064, -61075, -61097, -61117, -61117, -61117, -61124, -61124, -61124, -61192, -61202, -61209, -61213, -61213, -61220, -61258, -61298, -61298, -61298, -61320, +60629, +60629, +60629, +60629, +60629, +60636, +60663, +60675, +60675, +60682, +60704, +60704, +60724, +60776, +60809, +60832, +60849, +60870, +60877, +60907, +60956, +60956, +60989, +61003, +61024, +61048, +61062, +61069, +61101, +61101, +61101, +61101, +61125, +61138, +61155, +61162, +61162, +61184, +61184, +61184, +61184, +61184, +61184, +61216, +61242, +61296, +61296, +61296, +61303, +61303, +61303, 61334, -61361, -61380, -61407, -61429, -61467, -61481, -61488, -61520, -61527, +61360, +61360, +61397, +61416, +61423, +61448, +61476, +61483, +61483, +61532, +61539, +61560, 61578, -61592, -61606, -61606, -61606, -61614, -61619, -61626, -61633, -61690, -61697, -61713, -61726, -61726, -61760, -61771, -61810, -61828, -61854, -61875, -61875, -61875, -61892, -61914, -61931, -61941, -61964, -61964, -61997, -62004, -62019, -62026, -62033, -62047, -62087, -62094, -62110, -62136, -62162, -62199, -62214, -62227, -62254, -62270, -62276, -62304, -62321, -62321, -62326, -62346, -62372, -62372, -62385, -62385, -62405, -62412, -62426, -62446, -62460, -62467, -62500, -62517, -62517, -62551, -62564, -62571, -62578, -62591, -62591, -62605, -62632, -62655, -62655, -62679, -62700, -62700, -62721, -62729, +61578, +61578, +61617, +61624, +61631, +61681, +61706, +61721, +61721, +61729, +61729, +61764, +61776, +61776, +61776, +61808, +61831, +61831, +61837, +61846, +61846, +61864, +61883, +61890, +61910, +61910, +61910, +61917, +61917, +61954, +61954, +61954, +61961, +61968, +61978, +62000, +62007, +62014, +62028, +62042, +62077, +62102, +62109, +62109, +62116, +62116, +62123, +62156, +62163, +62197, +62197, +62197, +62218, +62218, +62232, +62250, +62257, +62286, +62286, +62293, +62300, +62320, +62382, +62430, +62437, +62484, +62484, +62498, +62540, +62552, +62559, +62559, +62559, +62573, +62583, +62592, +62592, +62596, +62628, +62649, +62674, +62674, +62694, +62699, +62699, +62734, 62745, -62766, -62766, -62780, -62792, -62809, -62809, -62831, -62841, -62855, -62855, -62886, -62900, -62900, -62920, -62929, -62929, -62942, -62970, -63013, -63031, -63031, -63058, -63065, -63072, -63090, -63113, -63113, -63113, -63118, -63118, -63122, -63122, -63138, -63138, -63172, -63200, -63223, -63232, -63271, -63271, -63271, -63276, -63276, -63283, -63302, -63309, -63340, -63340, -63340, +62752, +62759, +62773, +62773, +62804, +62821, +62821, +62825, +62836, +62874, +62884, +62911, +62923, +62923, +62935, +62941, +62963, +62987, +63002, +63002, +63027, +63027, +63027, +63027, +63027, +63045, +63045, +63057, +63064, +63064, +63108, +63121, +63136, +63136, +63136, +63136, +63136, +63136, +63143, +63143, +63178, +63178, +63178, +63215, +63238, +63264, +63279, +63315, +63337, +63337, 63360, -63383, -63383, -63403, -63433, +63360, +63364, +63378, +63378, +63426, 63440, -63447, -63447, -63482, -63482, -63482, -63488, -63495, -63510, +63460, +63460, +63460, +63460, +63464, +63468, +63491, 63517, -63524, -63541, -63569, -63569, -63597, -63647, -63664, -63675, -63688, -63695, -63725, -63744, -63766, -63773, -63773, -63789, -63809, -63809, -63826, -63833, -63838, -63838, -63845, +63517, +63535, +63548, +63548, +63601, +63624, +63643, +63660, +63660, +63702, +63714, +63714, +63714, +63723, +63742, +63742, +63742, +63761, +63779, +63790, +63805, +63805, +63805, 63852, -63881, -63894, -63908, -63935, -63952, -63966, -63973, -63995, -63995, -63995, -64009, -64028, -64051, -64078, -64117, -64117, -64117, -64132, -64170, -64170, -64170, -64180, -64235, -64235, -64276, -64304, -64323, -64323, +63858, +63880, +63910, +63927, +63938, +63938, +63985, +63985, +64010, +64010, +64010, +64017, +64017, +64049, +64049, +64065, +64083, +64083, +64102, +64102, +64102, +64110, +64110, +64122, +64122, +64156, +64186, +64186, +64193, +64232, +64249, +64269, +64287, +64287, 64330, -64348, -64348, -64348, -64355, +64361, 64379, -64379, -64379, -64392, -64392, -64398, -64413, -64420, -64420, -64433, -64440, -64460, -64467, -64505, -64526, -64563, -64575, -64588, -64593, -64610, -64621, -64621, -64621, -64621, -64639, -64667, -64667, -64667, -64667, -64667, -64673, -64686, -64715, -64723, -64723, -64723, -64723, -64762, -64762, -64762, -64771, -64771, -64788, -64788, -64805, -64812, -64819, -64826, -64849, -64849, +64407, +64412, +64412, +64431, +64453, +64461, +64498, +64512, +64512, +64512, +64553, +64558, +64558, +64614, +64657, +64657, +64657, +64694, +64694, +64694, +64710, +64710, +64717, +64735, +64735, +64745, +64755, +64763, +64782, +64782, +64782, +64782, +64782, +64796, +64796, +64796, +64822, +64822, +64839, +64839, +64855, +64866, 64874, -64888, -64888, -64892, -64892, -64899, -64899, -64899, +64889, 64906, -64906, -64920, -64970, -64980, -65026, -65053, -65053, -65053, +64934, +64963, +64963, +64963, +64963, +64969, +64982, +64982, +64982, +64996, +64996, +64996, +65008, +65033, +65045, +65045, +65045, 65060, -65116, -65123, -65134, -65140, -65168, -65175, -65209, -65231, -65238, -65245, -65257, -65264, -65264, -65270, -65277, -65277, -65299, -65340, -65371, -65371, -65371, -65371, -65371, -65371, -65371, -65371, -65394, -65394, -65401, -65401, -65414, -65445, -65459, +65075, +65075, +65075, +65075, +65100, +65121, +65121, +65126, +65126, +65126, +65150, +65159, +65159, +65184, +65184, +65206, +65206, +65222, +65228, +65247, +65256, +65263, +65275, +65275, +65294, +65308, +65308, +65359, +65359, +65359, +65381, +65381, +65397, +65415, +65465, +65476, 65482, -65491, -65491, -65491, -65498, -65533, -65533, -65562, -65595, -65612, -65628, -65635, -65635, -65635, -65642, -65652, -65666, -65666, -65678, -65678, -65691, -65711, -65711, -65726, -65746, -65753, -65753, -65753, -65765, -65765, -65776, -65800, -65818, -65818, -65830, -65837, -65837, -65855, -65855, -65872, -65903, -65934, -65934, -65946, -65946, -65964, -65969, -65977, -65987, -66007, -66013, -66013, -66027, -66027, -66043, -66060, -66067, -66067, -66067, -66072, -66089, -66108, -66132, -66146, -66165, -66165, -66182, -66210, -66223, -66223, -66223, -66233, -66240, -66258, +65490, +65490, +65496, +65532, +65559, +65603, +65607, +65607, +65633, +65643, +65715, +65721, +65782, +65782, +65782, +65810, +65825, +65825, +65831, +65831, +65831, +65831, +65845, +65850, +65863, +65873, +65882, +65882, +65886, +65904, +65923, +65923, +65939, +65983, +65995, +65995, +66004, +66035, +66061, +66092, +66112, +66112, +66121, +66150, +66162, +66166, +66166, +66175, +66175, +66200, +66230, +66249, 66275, -66285, -66304, -66304, -66304, -66304, -66304, -66304, -66304, -66304, -66304, -66310, -66327, -66327, -66327, -66355, -66355, -66373, -66407, +66292, +66313, +66317, +66317, +66337, +66344, +66344, +66351, +66364, +66364, +66381, +66391, +66391, +66391, +66400, +66400, +66411, +66411, 66416, -66433, -66433, -66445, -66458, -66458, -66458, -66470, -66476, -66476, -66486, -66495, -66495, -66526, -66526, -66551, -66582, -66589, -66589, -66589, -66616, -66632, -66632, -66647, -66667, -66667, -66673, -66673, -66673, -66700, -66700, -66731, -66746, -66746, -66762, -66762, -66762, -66784, -66794, -66794, -66805, -66811, -66818, -66818, -66852, -66888, -66888, -66888, -66910, -66920, -66920, -66920, -66920, -66920, -66931, -66938, -66954, -66971, -66996, -66996, -67014, -67014, -67014, -67028, -67057, -67057, -67057, -67057, -67063, -67096, -67111, -67133, -67143, -67153, -67153, -67175, -67175, -67175, -67190, -67209, -67209, -67214, -67248, -67267, -67287, -67294, -67316, -67316, -67316, -67316, -67316, -67316, -67316, -67316, -67349, -67373, -67416, -67443, -67443, -67447, -67461, -67461, -67470, -67496, -67505, -67505, -67505, -67523, -67557, -67557, -67581, -67581, -67598, -67622, -67667, -67686, -67686, -67704, -67704, -67723, -67729, -67729, -67743, -67743, -67743, -67751, -67751, -67751, -67769, -67800, -67842, -67842, -67842, -67842, -67842, -67842, -67868, -67868, -67892, -67917, -67936, -67956, -67956, -67963, +66416, +66436, +66448, +66455, +66469, +66478, +66478, +66478, +66482, +66482, +66482, +66482, +66492, +66492, +66501, +66511, +66518, +66531, +66541, +66541, +66561, +66561, +66561, +66576, +66576, +66576, +66576, +66576, +66576, +66602, +66602, +66614, +66619, +66619, +66619, +66680, +66685, +66685, +66685, +66707, +66716, +66716, +66716, +66716, +66716, +66729, +66748, +66748, +66804, +66814, +66814, +66814, +66822, +66832, +66876, +66876, +66895, +66895, +66905, +66914, +66933, +66942, +66967, +66987, +66987, +66998, +67016, +67024, +67034, +67034, +67043, +67043, +67043, +67062, +67103, +67103, +67112, +67145, +67145, +67160, +67168, +67168, +67168, +67176, +67205, +67242, +67242, +67242, +67256, +67276, +67276, +67276, +67276, +67297, +67345, +67345, +67345, +67345, +67345, +67358, +67362, +67382, +67382, +67382, +67388, +67422, +67422, +67454, +67454, +67472, +67488, +67506, +67506, +67506, +67506, +67525, +67525, +67544, +67560, +67578, +67578, +67578, +67583, +67600, +67614, +67641, +67659, +67675, +67706, +67744, +67761, +67801, +67801, +67837, +67837, +67844, +67844, +67844, +67844, +67844, +67854, +67873, +67907, +67907, +67922, +67922, +67929, +67947, +67947, +67977, 67984, -68027, -68054, -68066, -68066, -68084, -68084, -68084, -68092, -68102, -68140, -68140, -68192, -68208, -68215, -68248, -68298, -68298, -68298, -68321, -68349, -68376, -68376, -68394, -68394, -68433, -68465, -68465, -68472, -68492, -68505, -68505, -68505, -68505, -68505, -68564, -68578, -68607, -68637, -68647, -68647, -68673, -68681, -68686, -68699, -68712, -68742, -68754, -68754, -68760, -68765, -68792, -68792, -68792, -68812, -68818, -68887, -68904, -68916, -68925, -68933, -68959, -68984, -69000, -69016, +67994, +67994, +67994, +68022, +68038, +68038, +68046, +68087, +68098, +68104, +68104, +68120, +68120, +68120, +68126, +68126, +68138, +68143, +68169, +68169, +68199, +68241, +68256, +68279, +68279, +68279, +68320, +68330, +68330, +68335, +68335, +68356, +68390, +68390, +68407, +68434, +68434, +68452, +68475, +68484, +68514, +68524, +68524, +68524, +68524, +68524, +68532, +68532, +68532, +68556, +68572, +68587, +68587, +68594, +68594, +68604, +68604, +68621, +68693, +68703, +68737, +68759, +68784, +68784, +68808, +68808, +68808, +68822, +68822, +68881, +68881, +68881, +68919, +68919, +68919, +68934, +68934, +68934, +68951, +68969, +68991, 69022, -69070, -69115, -69115, -69115, -69120, -69140, -69140, -69140, -69157, -69173, -69210, -69243, -69243, -69290, -69290, -69290, -69290, -69296, -69296, -69296, -69296, -69308, -69308, -69319, -69319, +69022, +69022, +69022, +69043, +69052, +69052, +69123, +69141, +69141, +69155, +69177, +69194, +69194, +69194, +69212, +69223, +69223, +69241, +69257, +69271, +69300, +69300, +69300, +69300, 69332, -69332, -69332, -69332, -69341, -69341, -69363, -69384, -69394, -69394, -69421, -69421, -69421, -69453, -69474, -69510, -69527, -69558, -69567, -69567, -69590, -69590, -69597, -69597, -69597, -69660, -69675, -69706, -69706, -69720, -69720, -69720, -69760, -69771, -69771, -69771, -69777, -69777, -69777, -69802, -69802, -69802, -69813, -69813, -69813, -69884, -69890, -69890, -69910, -69910, -69910, -69910, -69910, -69948, -69965, +69367, +69377, +69377, +69381, +69427, +69427, +69427, +69459, +69476, +69524, +69543, +69573, +69573, +69585, +69585, +69585, +69607, +69683, +69698, +69698, +69698, +69698, +69756, +69778, +69792, +69818, +69828, +69853, +69853, +69876, +69893, +69916, +69916, +69916, +69916, +69931, +69944, +69952, +69952, 69982, -69992, -70010, -70035, -70047, -70047, -70047, -70080, -70104, -70140, -70174, -70174, -70174, -70174, -70174, -70196, -70223, -70247, -70254, -70265, -70265, -70265, -70275, -70275, -70282, +69982, +69987, +70026, +70042, +70042, +70059, +70078, +70078, +70135, +70143, +70143, +70158, +70167, +70167, +70167, +70188, +70224, +70260, +70260, +70260, +70287, 70298, 70298, -70305, -70305, -70319, -70327, -70347, -70347, -70347, -70374, -70374, -70374, -70374, -70391, -70391, -70391, -70391, -70391, -70391, -70425, -70432, -70432, -70432, +70314, +70323, +70351, +70382, +70382, +70393, +70402, +70440, +70440, +70440, +70440, +70440, 70448, 70448, 70448, -70459, -70481, -70515, -70528, -70560, -70560, -70560, -70574, -70574, -70591, -70591, -70612, -70612, -70646, -70650, -70661, -70666, -70666, -70670, -70674, -70688, -70732, -70748, -70748, -70771, -70776, -70776, -70788, -70802, -70806, -70830, -70861, -70870, -70904, -70914, -70922, -70961, -70987, -71006, -71006, -71025, -71048, -71075, -71115, -71143, -71176, -71210, -71210, -71269, -71278, -71278, -71306, -71306, -71326, -71326, -71343, -71360, -71360, -71369, -71374, -71392, -71414, -71414, -71414, -71419, -71429, -71434, -71452, -71474, -71474, -71493, -71493, -71493, -71539, -71539, -71539, -71561, -71569, -71569, -71593, -71593, -71603, -71610, -71625, -71625, -71631, -71631, +70472, +70472, +70472, +70472, +70503, +70503, +70503, +70503, +70551, +70551, +70564, +70564, +70564, +70564, +70564, +70609, +70609, +70620, +70620, +70627, +70634, +70651, +70651, +70657, +70663, +70663, +70681, +70687, +70694, +70694, +70701, +70714, +70724, +70724, +70724, +70755, +70755, +70755, +70755, +70755, +70755, +70755, +70755, +70786, +70786, +70808, +70808, +70826, +70826, +70826, +70852, +70852, +70852, +70852, +70852, +70852, +70852, +70852, +70860, +70908, +70918, +70926, +70943, +70943, +71014, +71014, +71014, +71023, +71031, +71049, +71049, +71073, +71073, +71094, +71094, +71103, +71103, +71132, +71149, +71149, +71167, +71177, +71195, +71204, +71204, +71224, +71248, +71248, +71252, +71273, +71279, +71279, +71279, +71313, +71319, +71319, +71319, +71319, +71336, +71336, +71336, +71336, +71336, +71357, +71367, +71367, +71391, +71457, +71457, +71465, +71465, +71469, +71469, +71487, +71521, +71521, +71559, +71559, +71559, +71559, +71559, +71591, +71618, +71618, +71624, 71650, -71682, -71682, -71692, -71710, -71710, +71650, +71650, +71680, +71680, +71680, +71680, +71708, 71720, -71743, -71743, -71743, -71789, -71789, -71821, -71839, -71859, -71864, -71875, -71875, -71881, -71881, -71881, -71893, -71913, -71913, -71930, -71938, -71948, -71948, -71953, -71967, -72000, -72000, +71729, +71752, +71752, +71752, +71752, +71757, +71757, +71793, +71805, +71805, +71805, +71805, +71805, +71805, +71805, +71810, +71810, +71820, +71840, +71888, +71911, +71911, +71921, +71932, +71968, +71992, +71992, +72002, +72002, +72002, 72013, -72024, -72024, -72024, -72024, -72036, -72053, -72053, -72053, -72068, -72068, -72068, -72090, -72101, -72109, -72109, -72109, -72109, -72109, -72109, -72109, -72133, -72148, -72148, -72165, -72165, -72165, -72165, -72165, -72182, -72182, -72182, -72189, -72211, -72211, -72219, -72219, -72219, -72219, -72266, -72280, -72311, -72311, -72311, -72311, -72321, -72336, -72343, -72349, -72349, -72363, -72363, -72373, -72373, -72385, -72385, -72401, -72429, -72449, -72468, -72506, -72510, -72510, -72510, -72524, -72534, -72534, -72534, -72590, -72611, -72648, -72659, -72659, -72671, -72683, -72700, -72700, -72700, -72727, -72727, -72727, -72727, -72727, -72774, -72774, -72807, -72807, -72818, -72853, +72013, +72035, +72046, +72074, +72099, +72099, +72135, +72135, +72135, +72145, +72202, +72202, +72202, +72227, +72234, +72242, +72247, +72255, +72255, +72255, +72277, +72277, +72277, +72284, +72284, +72329, +72345, +72382, +72382, +72382, +72393, +72407, +72407, +72428, +72436, +72436, +72467, +72495, +72495, +72504, +72504, +72504, +72526, +72553, +72579, +72585, +72601, +72640, +72650, +72656, +72661, +72661, +72669, +72688, +72688, +72688, +72730, +72743, +72743, +72764, +72779, +72803, +72813, +72813, +72813, +72825, +72825, +72857, 72866, -72874, -72874, -72885, 72895, -72905, -72920, -72943, -72943, -72943, -72943, -72950, -72950, -72950, -72971, -73000, -73039, -73061, -73061, -73115, -73119, -73125, -73162, -73176, -73176, -73192, -73204, -73204, -73204, -73219, -73231, -73231, -73249, -73266, -73277, -73277, -73294, -73304, -73339, -73355, -73355, -73355, -73360, -73360, -73360, -73360, -73360, -73360, -73390, -73390, -73390, -73405, -73441, -73441, -73447, -73462, -73476, -73476, -73476, -73509, -73509, -73519, -73519, -73519, -73539, -73539, -73555, -73555, -73555, -73555, -73562, -73562, -73615, -73638, -73655, -73655, -73718, -73718, -73718, -73724, -73746, -73759, -73784, -73784, -73784, -73789, -73789, -73789, -73789, -73794, +72895, +72934, +72969, +72969, +72969, +72969, +73020, +73020, +73033, +73046, +73057, +73057, +73057, +73069, +73078, +73082, +73082, +73109, +73129, +73174, +73180, +73180, +73180, +73186, +73186, +73196, +73196, +73196, +73212, +73230, +73230, +73254, +73260, +73260, +73274, +73281, +73311, +73311, +73311, +73337, +73368, +73381, +73402, +73435, +73456, +73456, +73456, +73456, +73472, +73472, +73488, +73488, +73488, +73488, +73488, +73488, +73503, +73522, +73522, +73522, +73530, +73530, +73559, +73616, +73637, +73662, +73685, +73700, +73700, +73711, +73745, +73755, +73790, 73815, -73829, -73829, -73859, -73859, -73863, -73863, -73879, -73894, -73894, -73894, -73894, -73894, -73894, -73900, -73908, -73908, -73908, -73915, -73934, -73945, -73965, -73965, -73965, -73965, -73965, -73978, -73996, -73996, -74010, -74029, -74029, -74029, -74029, -74036, -74036, -74036, -74036, -74058, -74058, -74077, -74090, -74131, +73815, +73815, +73815, +73821, +73844, +73867, +73883, +73907, +73907, +73942, +73974, +73974, +73974, +74007, +74026, +74043, +74043, +74057, +74063, +74079, +74079, +74102, +74102, +74102, +74125, +74136, +74136, +74136, +74136, +74158, 74164, 74164, -74193, -74207, -74207, -74207, -74220, -74220, -74240, -74240, -74240, -74240, -74240, -74255, -74270, -74288, -74288, -74305, -74305, -74305, -74305, -74305, -74318, +74164, +74172, +74188, +74188, +74210, +74246, +74256, +74256, +74256, +74264, +74300, +74312, +74320, 74328, -74352, -74352, -74352, -74365, -74374, -74395, -74395, -74395, -74395, -74404, -74417, -74431, -74431, -74431, -74450, -74456, -74456, -74456, -74473, -74492, -74492, +74360, +74360, +74383, +74389, +74401, +74413, +74430, +74430, +74430, +74460, +74486, +74486, +74486, +74486, +74486, 74510, -74529, -74542, -74542, -74558, -74558, -74577, -74585, -74590, -74590, -74590, -74590, -74605, -74621, -74640, -74640, -74640, -74640, -74671, -74671, -74690, -74699, -74705, -74721, -74766, -74766, -74790, -74801, -74801, -74801, -74801, -74801, -74801, -74810, -74838, -74838, -74838, -74838, -74870, -74890, -74896, -74900, -74900, -74900, -74916, -74942, -74953, -74953, -74959, -74959, -74970, -74995, -74995, +74531, +74531, +74561, +74601, +74620, +74631, +74631, +74674, +74674, +74684, +74684, +74695, +74710, +74710, +74719, +74748, +74773, +74781, +74789, +74789, +74809, +74809, +74809, +74825, +74845, +74845, +74857, +74891, +74891, +74891, +74891, +74891, +74925, +74925, +74925, +74943, +74988, 75011, -75026, -75039, -75039, -75039, -75073, -75080, -75091, -75091, -75100, -75118, -75118, -75155, -75170, -75187, -75207, -75207, -75207, -75207, -75219, -75241, -75241, -75241, -75241, -75241, -75247, -75297, -75297, -75302, -75302, -75310, -75321, -75346, -75354, -75354, -75382, -75382, -75382, -75431, -75455, -75464, -75464, -75480, -75487, -75503, -75524, -75524, -75524, -75524, +75011, +75011, +75011, +75011, +75021, +75021, +75037, +75037, +75064, +75097, +75102, +75102, +75140, +75140, +75158, +75158, +75172, +75172, +75193, +75193, +75212, +75227, +75245, +75256, +75272, +75283, +75293, +75308, +75315, +75315, +75341, +75356, +75367, +75397, +75397, +75453, +75471, +75471, +75471, +75485, 75534, -75544, -75570, -75591, -75627, -75627, -75627, -75627, -75627, -75642, -75665, -75674, -75690, -75690, -75715, -75720, -75730, -75730, -75730, -75730, -75746, -75758, -75771, -75780, -75813, -75813, +75534, +75534, +75545, +75551, +75551, +75551, +75564, +75576, +75609, +75621, +75638, +75671, +75681, +75696, +75702, +75702, +75714, +75714, +75721, +75736, +75736, +75743, +75761, +75770, +75778, +75778, +75778, +75778, +75778, +75805, +75805, 75823, -75833, -75837, -75853, -75863, -75863, -75868, -75868, -75884, -75884, -75934, -75934, -75934, -75971, -75971, -75993, -76008, -76008, -76008, -76029, -76045, -76060, -76085, -76103, -76109, -76135, -76135, -76135, -76155, -76155, -76155, -76196, -76202, -76218, -76228, -76228, +75834, +75840, +75857, +75893, +75893, +75893, +75893, +75893, +75904, +75945, +75945, +75958, +75958, +75958, +75977, +76016, +76031, +76037, +76037, +76051, +76051, +76079, +76084, +76084, +76102, +76120, +76120, +76120, +76120, +76134, +76166, +76175, +76205, +76216, +76216, +76227, 76244, -76244, -76251, -76269, -76274, -76299, -76309, -76309, -76309, -76309, -76309, -76309, -76309, -76348, -76348, -76348, -76370, -76370, -76377, -76384, -76415, -76451, -76480, -76480, -76480, +76275, +76284, +76318, +76337, +76343, +76389, +76389, +76389, +76389, +76402, +76416, +76416, +76434, +76434, +76444, +76497, +76497, 76509, -76556, -76575, -76605, -76605, -76615, -76615, -76615, -76621, -76621, -76645, -76645, -76645, -76692, -76709, -76709, -76719, -76743, -76743, -76743, -76743, -76766, -76773, -76773, -76773, -76784, -76791, -76791, -76791, -76818, -76818, -76818, -76824, -76824, -76824, -76824, -76834, -76850, -76877, -76877, -76889, -76889, -76889, -76889, -76889, -76903, -76909, -76909, -76909, -76909, -76936, -76936, -76936, -76949, -76949, -76949, -76955, -76955, -76976, -76991, -77016, -77016, -77016, -77016, -77016, -77026, -77026, -77026, -77042, +76519, +76566, +76604, +76611, +76611, +76611, +76640, +76654, +76654, +76654, +76654, +76671, +76671, +76676, +76676, +76697, +76697, +76697, +76697, +76707, +76751, +76751, +76751, +76774, +76778, +76807, +76807, +76807, +76830, +76830, +76848, +76864, +76897, +76913, +76932, +76932, +76944, +76970, +76986, +76986, +77002, +77017, +77022, +77039, +77049, +77049, +77049, 77067, -77098, -77098, -77098, -77098, -77107, -77107, -77107, -77107, -77123, -77123, -77123, +77067, +77067, +77081, +77081, +77081, +77089, +77089, +77105, +77121, +77121, 77156, -77168, -77187, -77204, -77213, -77225, -77247, -77247, -77247, -77258, -77302, -77302, -77302, -77302, -77312, -77318, -77318, -77335, -77362, -77379, -77389, -77402, -77413, -77444, -77444, -77444, -77461, -77491, -77491, +77156, +77156, +77156, +77156, +77165, +77173, +77173, +77173, +77173, +77191, +77211, +77211, +77211, +77218, +77242, +77290, +77308, +77308, +77325, +77343, +77343, +77376, +77376, +77376, +77376, +77386, +77386, +77386, +77386, +77393, +77399, +77419, +77428, +77450, +77450, +77492, +77492, +77492, +77492, 77529, -77538, -77543, -77543, -77563, -77576, -77582, -77604, -77604, -77633, +77529, +77529, +77540, +77540, +77540, +77557, +77570, +77570, +77570, +77570, +77570, +77570, +77587, +77597, +77620, 77640, -77675, -77675, -77675, -77675, -77691, -77691, -77695, -77695, -77707, -77707, -77707, -77722, -77722, -77722, -77742, -77742, -77742, -77742, -77742, -77742, -77742, -77742, -77742, -77742, -77742, -77742, -77752, -77752, -77757, -77769, -77808, -77822, -77822, -77832, -77845, -77845, -77845, -77862, -77862, -77868, -77868, -77868, -77868, -77888, -77904, -77972, -77972, -77988, -78004, -78030, -78064, -78069, -78069, -78069, -78087, -78098, -78116, +77640, +77640, +77661, +77680, +77680, +77680, +77680, +77680, +77680, +77712, +77732, +77739, +77739, +77739, +77748, +77765, +77824, +77824, +77834, +77850, +77860, +77860, +77872, +77872, +77889, +77889, +77889, +77902, +77920, +77934, +77962, +77982, +77982, +77982, +77982, +78000, +78000, +78000, +78009, +78025, +78036, +78036, +78043, +78043, +78062, +78072, +78123, 78153, -78153, -78164, -78164, -78173, -78191, -78219, -78243, -78253, -78253, -78273, -78281, -78289, -78305, -78349, -78356, -78369, +78167, +78189, +78211, +78211, +78211, +78222, +78222, +78222, +78230, +78230, +78236, +78236, +78236, +78236, +78254, +78254, +78254, +78254, +78254, +78272, +78296, +78313, +78332, +78368, 78384, -78402, -78402, -78422, -78422, -78422, -78439, -78456, -78456, -78492, -78502, -78502, -78512, -78522, -78554, -78587, -78598, -78614, -78614, -78614, -78619, -78619, -78626, -78626, -78663, -78670, -78670, -78681, -78681, -78681, -78681, -78689, -78689, -78708, -78724, -78724, -78724, -78724, -78724, -78774, -78774, -78786, -78786, -78815, -78834, -78846, -78846, -78846, -78846, -78846, -78870, -78905, +78394, +78404, +78411, +78423, +78444, +78451, +78464, +78485, +78501, +78501, +78514, +78514, +78514, +78514, +78523, +78532, +78544, +78544, +78544, +78544, +78544, +78544, +78555, +78575, +78612, +78612, +78641, +78672, +78678, +78678, +78705, +78705, +78720, +78737, +78737, +78753, +78753, +78757, +78778, +78778, +78778, +78819, +78837, +78837, +78837, +78843, +78843, +78853, +78869, +78869, +78908, +78908, +78908, +78908, +78908, 78913, -78931, -78931, -78949, -78968, -78974, -78974, -78981, -78981, -78981, -78981, -78981, -78985, -79014, -79024, -79024, -79030, -79030, -79049, -79053, -79073, -79077, -79085, -79085, -79085, -79085, -79098, -79098, -79122, -79122, -79122, -79122, -79122, -79144, -79144, -79151, -79151, -79151, -79158, -79158, -79174, -79205, -79205, -79215, -79215, -79215, -79215, -79228, -79246, -79246, -79246, -79267, -79312, -79312, -79336, -79354, -79384, -79384, -79391, -79391, -79412, +78958, +78958, +78958, +78969, +78990, +79019, +79019, +79025, +79025, +79025, +79059, +79079, +79079, +79079, +79086, +79086, +79102, +79102, +79102, +79109, +79109, +79109, +79109, +79109, +79109, +79109, +79109, +79109, +79123, +79136, +79155, +79180, +79180, +79187, +79187, +79187, +79187, +79217, +79217, +79249, +79249, +79266, +79266, +79278, +79288, +79288, +79302, +79311, +79311, +79341, +79357, +79357, +79364, +79382, +79395, +79395, +79395, +79395, +79408, 79427, -79427, -79427, -79447, -79447, -79453, -79485, -79513, -79513, -79527, -79527, -79533, -79533, -79555, -79565, -79580, -79595, -79603, -79603, -79603, -79628, -79641, -79641, -79682, -79691, -79751, -79751, -79751, -79759, -79803, -79803, -79803, -79803, -79865, -79865, -79922, -79937, -79948, -79993, -79993, -79993, -80005, -80012, -80035, -80035, -80035, -80048, -80063, -80080, -80100, -80100, -80107, -80114, -80114, -80114, -80140, -80140, -80167, -80167, +79444, +79444, +79464, +79484, +79484, +79491, +79514, +79526, +79526, +79539, +79571, +79571, +79591, +79626, +79626, +79626, +79656, +79656, +79671, +79671, +79671, +79685, +79685, +79697, +79705, +79722, +79748, +79773, +79773, +79802, +79802, +79802, +79808, +79808, +79818, +79818, +79841, +79841, +79841, +79850, +79850, +79850, +79850, +79850, +79859, +79859, +79876, +79876, +79906, +79927, +79952, +79963, +79974, +79980, +79996, +79996, +79996, +79996, +80014, +80014, +80014, +80014, +80014, +80014, +80014, +80044, +80067, +80074, +80090, +80090, +80090, +80090, +80090, +80090, +80123, +80132, +80137, +80152, +80152, 80177, -80187, 80194, -80194, -80194, -80194, -80206, -80224, -80224, -80233, -80233, -80240, -80253, -80270, -80308, -80330, -80367, -80383, -80391, -80391, -80413, -80413, -80413, -80427, -80427, -80427, -80462, -80462, -80462, -80469, -80489, -80503, -80526, -80550, -80550, -80564, -80564, -80564, -80564, -80571, -80583, -80583, -80583, -80583, -80583, -80612, -80612, -80612, -80624, -80624, -80642, +80211, +80211, +80231, +80248, +80269, +80276, +80276, +80283, +80293, +80310, +80310, +80315, +80332, +80352, +80352, +80404, +80415, +80432, +80464, +80492, +80524, +80534, +80541, +80581, +80581, +80588, +80588, +80601, +80618, +80618, +80634, 80652, -80652, -80664, -80686, -80699, -80699, -80736, -80736, -80748, -80748, -80786, -80786, -80802, -80802, -80802, -80802, -80815, -80846, -80846, -80846, -80864, -80904, -80914, -80935, -80962, -80962, -80962, -80962, -80975, -80984, -81035, -81035, -81035, -81035, -81060, -81081, -81120, -81135, -81152, -81165, -81171, -81171, -81171, -81171, -81180, -81204, -81221, -81221, -81221, -81276, -81276, -81292, -81292, -81335, +80675, +80675, +80682, +80682, +80682, +80682, +80682, +80682, +80704, +80733, +80733, +80749, +80796, +80796, +80812, +80812, +80819, +80819, +80829, +80862, +80885, +80909, +80917, +80917, +80937, +80951, +80951, +80974, +80992, +81014, +81032, +81032, +81032, +81032, +81061, +81069, +81106, +81106, +81111, +81111, +81167, +81201, +81219, +81219, +81219, +81266, +81266, +81280, +81280, +81280, +81287, +81308, +81314, +81336, 81354, -81364, -81372, -81372, -81372, -81382, +81360, +81360, +81360, 81389, -81400, -81439, -81451, -81477, -81477, -81509, -81530, -81530, -81537, -81537, -81537, -81548, -81548, -81563, -81598, -81612, -81619, -81624, -81641, -81666, -81666, -81689, -81689, -81702, -81702, -81707, -81726, -81754, -81770, -81797, -81797, -81837, -81837, -81857, -81862, -81894, -81908, -81908, -81908, -81908, -81908, -81908, -81922, -81956, -81956, -81977, -82016, -82016, -82037, -82065, -82065, -82103, -82103, -82103, -82103, -82103, -82103, -82120, -82120, -82133, -82133, -82150, -82175, -82175, +81410, +81410, +81410, +81410, +81418, +81437, +81460, +81460, +81485, +81497, +81513, +81525, +81525, +81532, +81543, +81543, +81558, +81592, +81592, +81613, +81613, +81630, +81637, +81680, +81727, +81727, +81727, +81727, +81732, +81732, +81732, +81732, +81739, +81739, +81751, +81758, +81758, +81778, +81778, +81785, +81785, +81808, +81830, +81830, +81838, +81855, +81868, +81885, +81885, +81892, +81892, +81905, +81905, +81921, +81934, +81959, +81959, +81966, +82004, +82004, +82004, +82021, +82021, +82048, +82048, +82048, +82070, +82093, +82114, +82114, +82114, +82136, +82160, 82182, -82202, -82217, -82233, -82233, -82233, -82247, -82247, -82273, -82273, -82279, -82285, -82310, -82310, -82310, -82342, -82342, -82359, -82381, -82400, -82400, -82410, -82441, -82441, -82441, -82448, -82467, -82476, -82476, -82476, -82476, -82507, -82528, -82550, -82554, -82559, -82619, -82660, -82660, -82691, -82734, -82769, -82811, -82811, -82811, -82836, -82857, -82863, -82863, -82880, -82880, -82880, -82892, -82906, -82906, -82919, -82943, -82964, -82995, -82995, -82995, -83048, -83059, -83059, -83070, -83079, -83099, -83113, -83113, -83148, -83148, -83164, -83196, -83201, -83215, -83215, -83229, -83229, -83229, -83229, -83244, -83244, -83244, -83257, +82182, +82191, +82198, +82198, +82211, +82245, +82280, +82287, +82287, +82287, +82287, +82308, +82308, +82308, +82315, +82336, +82336, +82336, +82336, +82365, +82375, +82375, +82375, +82375, +82382, +82382, +82417, +82433, +82440, +82474, +82488, +82531, +82531, +82552, +82563, +82581, +82597, +82597, +82613, +82634, +82648, +82654, +82661, +82661, +82661, +82668, +82675, +82690, +82696, +82703, +82717, +82724, +82752, +82752, +82772, +82788, +82795, +82802, +82814, +82837, +82858, +82865, +82888, +82895, +82929, +82948, +82960, +82967, +82981, +82981, +82996, +83015, +83031, +83038, +83045, +83081, +83100, +83149, +83182, +83182, +83206, +83213, +83236, +83236, +83243, +83243, +83249, 83261, -83261, -83303, -83324, -83334, -83343, -83380, -83396, -83396, -83419, -83419, -83419, -83419, -83419, -83419, -83419, -83427, -83427, -83433, -83433, -83449, -83449, -83449, -83470, -83480, -83501, -83501, -83514, -83514, -83524, -83545, -83545, -83561, -83561, -83577, -83577, -83577, -83577, -83594, -83594, -83609, -83635, -83635, -83648, -83648, -83696, -83714, -83714, -83744, -83744, -83770, -83770, -83776, -83816, -83823, -83842, -83864, -83864, -83864, -83875, -83879, -83879, -83879, -83883, -83883, -83883, -83883, -83883, -83896, -83916, -83916, -83935, -83935, -83935, -83951, -83951, -83951, -83951, -83951, -83951, -83971, -83989, -84017, -84054, -84079, -84079, -84079, -84089, -84095, -84121, -84129, -84139, -84157, -84192, -84211, -84265, +83268, +83268, +83292, +83306, +83328, +83328, +83354, +83361, +83395, +83401, +83415, +83425, +83448, +83454, +83481, +83510, +83558, +83565, +83591, +83607, +83617, +83645, +83658, +83665, +83682, +83682, +83682, +83699, +83733, +83743, +83797, +83813, +83829, +83843, +83855, +83859, +83873, +83873, +83873, +83889, +83904, +83945, +83974, +84021, +84021, +84081, +84092, +84106, +84123, +84140, +84212, +84212, +84212, +84212, +84241, +84248, +84255, +84255, +84262, 84282, -84296, -84313, -84325, -84345, -84345, -84357, -84379, -84379, -84400, -84434, -84452, -84457, -84468, -84497, -84497, -84511, -84511, -84533, -84533, -84539, -84539, +84308, +84308, +84308, +84317, +84317, +84331, +84360, +84384, +84401, +84408, +84455, +84488, +84488, +84530, +84551, 84577, -84592, -84604, -84628, -84628, -84628, -84628, -84638, -84638, -84653, -84676, +84577, +84586, +84593, +84612, +84619, +84619, +84666, 84682, -84731, -84752, +84697, +84714, 84766, 84766, -84774, -84815, -84854, -84873, -84889, -84908, -84908, -84924, -84971, -84971, -84971, -84971, -84971, -84971, -84971, -84971, -84971, -84999, -85024, -85024, -85024, -85059, -85068, -85074, -85081, -85103, -85126, -85126, -85126, -85148, -85169, -85179, -85179, -85179, -85190, -85202, -85216, -85229, -85229, +84766, +84766, +84778, +84792, +84799, +84799, +84799, +84805, +84817, +84842, +84842, +84842, +84849, +84864, +84876, +84930, +84936, +84936, +84948, +84960, +84960, +84960, +84983, +84996, +85003, +85011, +85046, +85066, +85111, +85127, +85149, +85165, +85210, 85229, 85229, 85229, 85235, -85242, -85287, -85294, -85294, -85294, -85294, -85300, -85300, -85300, -85300, -85315, -85333, -85356, -85356, -85394, -85394, -85434, -85434, -85444, -85444, -85444, -85451, -85451, -85457, -85464, -85464, -85464, -85471, -85471, -85484, -85484, -85491, -85510, -85510, -85510, -85510, -85522, -85522, -85553, -85595, -85603, -85614, -85633, -85633, -85662, -85662, -85670, -85700, -85720, -85742, -85754, -85754, -85754, -85776, -85788, -85850, -85856, -85856, -85887, -85912, -85953, -85964, -85964, -85995, -85995, -85995, -85995, -86004, -86016, -86016, -86033, -86066, -86066, -86073, -86083, -86083, -86090, -86096, -86109, -86121, -86121, -86132, -86132, -86145, -86145, -86145, -86145, -86178, -86191, -86216, -86230, -86257, -86270, -86281, -86299, -86312, -86323, -86323, -86363, -86383, -86383, -86383, -86422, -86427, -86427, -86427, -86445, -86445, -86451, -86477, -86494, -86520, -86520, -86527, -86534, -86547, -86558, -86576, -86601, -86601, -86607, +85235, +85253, +85266, +85285, +85299, +85329, +85343, +85361, +85379, +85413, +85413, +85446, +85453, +85482, +85492, +85514, +85521, +85521, +85521, +85561, +85568, +85585, +85599, +85654, +85671, +85685, +85699, +85699, +85699, +85699, +85699, +85709, +85734, +85734, +85748, +85748, +85771, +85787, +85787, +85820, +85830, +85830, +85837, +85837, +85837, +85860, +85921, +85944, +85944, +85962, +85968, +85982, +86007, +86014, +86019, +86034, +86054, +86061, +86074, +86112, +86119, +86125, +86144, +86163, +86163, +86170, +86202, +86253, +86310, +86310, +86337, +86344, +86361, +86376, +86410, +86428, +86428, +86444, +86456, +86456, +86456, +86474, +86492, +86500, +86500, +86528, +86528, +86541, +86541, +86562, +86582, +86602, 86615, 86615, -86638, -86656, -86664, -86664, -86695, -86695, -86701, -86701, -86736, -86741, -86741, -86741, -86761, -86799, -86812, -86832, +86615, +86645, +86645, +86666, +86692, +86720, +86727, +86734, +86757, +86781, +86801, +86801, +86801, +86823, 86853, -86891, -86929, -86929, -86955, -86996, -86996, -86996, +86853, +86870, +86889, +86895, +86895, +86895, +86920, +86927, +86939, +86957, +86981, +86988, 87009, -87009, -87016, -87029, -87029, -87029, -87029, -87073, -87084, -87135, -87157, -87165, -87182, -87191, -87208, -87208, -87225, -87235, -87235, -87257, -87265, -87281, -87286, -87286, -87299, -87299, -87319, -87319, -87333, -87344, -87371, +87044, +87044, +87075, +87108, +87129, +87146, +87158, +87176, +87183, +87213, +87266, +87284, +87284, +87291, +87307, +87307, +87312, +87339, +87339, +87346, +87353, 87385, -87385, -87417, -87417, -87443, -87450, -87460, -87460, -87477, -87495, -87520, -87520, -87520, -87544, -87544, -87544, -87557, -87583, -87583, -87583, -87583, -87600, -87635, -87635, -87670, -87670, -87670, -87670, -87670, -87683, -87690, -87690, -87733, +87419, +87419, +87441, +87448, +87470, +87503, +87503, +87509, +87509, +87537, +87561, +87580, +87580, +87625, +87632, +87644, +87656, +87656, +87656, +87656, +87656, +87696, +87713, +87713, +87713, +87713, +87713, +87713, +87738, +87746, 87753, -87768, -87805, -87805, -87827, +87753, +87785, +87800, +87811, +87823, +87833, +87833, +87844, +87844, 87859, -87873, -87873, -87901, -87912, -87912, -87934, -87943, -87952, -87979, -87995, -87995, -88008, -88008, -88008, -88017, -88027, +87878, +87878, +87889, +87920, +87925, +87945, +87945, +87945, +87964, +87974, +87974, +87974, +87980, +87996, +87996, +87996, +87996, +88015, +88015, 88037, 88037, -88037, -88066, -88098, -88098, -88105, -88133, -88133, -88144, -88187, -88207, -88207, -88242, -88242, -88254, -88254, -88284, -88324, -88344, -88344, -88356, -88356, -88356, -88356, -88356, -88362, -88382, -88401, -88431, -88431, -88437, -88447, -88467, -88499, -88499, -88499, -88514, -88526, -88526, -88526, -88526, -88526, -88565, -88565, -88589, -88594, -88594, -88594, -88610, -88638, -88651, -88681, -88710, -88717, -88717, -88717, -88750, -88750, -88757, -88810, -88810, -88825, -88849, -88883, -88903, -88903, -88935, -88941, -88941, -88961, -88980, -89018, -89018, -89039, -89039, -89045, -89061, -89071, -89071, -89071, -89071, -89085, -89085, +88042, +88054, +88063, +88070, +88084, +88084, +88116, +88125, +88125, +88125, +88125, +88164, +88164, +88179, +88179, +88193, +88193, +88237, +88237, +88237, +88237, +88237, +88237, +88261, +88270, +88282, +88293, +88293, +88310, +88323, +88345, +88365, +88385, +88385, +88385, +88385, +88385, +88403, +88403, +88418, +88418, +88418, +88453, +88473, +88483, +88498, +88508, +88508, +88529, +88539, +88550, +88550, +88550, +88558, +88581, +88596, +88596, +88596, +88596, +88596, +88596, +88596, +88617, +88641, +88650, +88678, +88678, +88678, +88700, +88700, +88714, +88756, +88762, +88773, +88828, +88855, +88861, +88861, +88892, +88952, +88962, +88962, +88962, +88968, +88993, +88993, +89003, +89033, +89033, +89078, +89086, +89091, 89102, -89132, -89141, -89165, -89199, -89214, -89243, -89243, -89249, -89249, -89249, -89255, -89273, -89273, +89102, +89127, +89138, +89138, +89155, +89166, +89188, +89188, +89205, +89211, +89211, +89211, +89221, +89221, +89268, 89290, -89290, -89308, -89308, -89308, -89325, -89330, -89355, -89355, -89373, -89390, -89408, -89408, -89408, -89443, -89443, -89443, -89457, -89457, -89457, -89457, -89457, -89471, -89477, -89477, -89477, -89477, -89495, -89495, -89509, -89534, -89534, -89558, -89558, -89567, -89594, -89630, -89630, +89303, +89316, +89324, +89383, +89393, +89404, +89421, +89437, +89466, +89466, +89502, +89502, +89515, +89545, +89580, +89586, +89586, +89586, +89591, +89591, +89620, +89633, 89649, -89649, -89649, -89667, -89678, -89678, -89678, -89692, -89720, -89740, -89755, -89766, -89785, -89796, -89796, -89814, -89814, -89821, -89848, -89848, -89869, +89654, +89694, +89694, +89706, +89706, +89706, +89721, +89721, +89727, +89727, +89727, +89756, +89756, +89756, +89763, +89782, +89782, +89804, +89804, +89826, +89826, +89831, +89840, +89847, +89858, 89885, 89885, -89900, -89900, -89900, -89900, -89908, +89885, +89920, 89942, -89956, -89964, -89964, -89964, -89983, -90010, -90010, -90040, -90040, -90046, -90066, -90074, -90074, -90084, -90084, -90096, -90096, -90141, -90149, -90156, -90156, -90156, -90166, -90176, +89949, +89949, +89949, +89959, +89971, +89978, +89984, +89984, +89999, +90035, +90053, +90064, +90075, +90083, +90083, +90083, +90101, +90101, +90116, +90116, +90150, +90157, +90157, +90157, +90168, +90205, +90205, +90212, +90212, 90242, -90260, -90276, -90276, -90276, -90276, -90290, -90305, -90305, -90305, -90325, -90333, -90333, -90346, -90346, -90378, -90378, -90386, -90397, -90438, -90438, -90438, -90461, -90477, -90520, -90528, -90535, -90568, -90589, -90589, -90608, -90608, +90274, +90280, +90292, +90302, +90302, +90302, +90309, +90309, +90321, +90327, +90343, +90399, +90426, +90435, +90435, +90453, +90459, +90459, +90476, +90476, +90482, +90502, +90502, +90502, +90522, +90522, +90536, +90563, +90563, +90583, +90583, +90583, +90604, +90604, +90610, +90610, +90610, +90610, 90629, +90629, +90654, 90663, -90673, -90673, -90673, -90681, -90681, -90715, -90724, -90735, -90735, -90735, -90755, -90782, -90787, -90787, -90805, -90805, +90669, +90690, +90699, +90699, +90699, +90729, +90752, +90752, +90758, +90758, +90774, +90780, 90825, -90855, -90867, -90907, -90926, -90937, -90958, -90958, -90983, -90983, -91033, -91048, -91065, -91082, -91082, -91082, -91086, -91114, -91133, -91166, -91166, +90845, +90857, +90857, +90857, +90857, +90873, +90905, +90905, +90905, +90920, +90920, +90920, +90963, +90969, +90987, +90987, +90987, +91004, +91023, +91029, +91029, +91061, +91061, +91061, +91067, +91073, +91093, +91093, +91093, +91101, +91126, +91126, +91126, +91126, +91131, +91178, 91185, -91185, -91226, -91226, -91238, -91238, -91238, -91245, -91258, -91270, -91270, +91195, +91216, +91241, +91268, +91268, +91268, +91278, 91288, -91295, -91295, -91295, -91303, -91311, -91342, -91357, -91376, -91383, -91383, -91383, -91383, -91383, -91390, -91397, -91397, -91397, -91397, -91438, -91455, -91463, -91504, -91504, -91511, -91538, -91557, -91575, -91583, -91590, -91611, -91622, -91622, -91647, +91297, +91297, +91297, +91314, +91320, +91320, +91320, +91328, +91328, +91345, +91365, +91365, +91365, +91365, +91386, +91422, +91449, +91458, +91495, +91533, +91551, +91579, +91579, +91579, +91624, +91631, +91631, +91631, +91639, 91657, -91664, -91677, -91677, -91704, -91704, -91712, -91712, -91730, -91739, -91758, -91758, -91770, -91810, -91810, -91810, -91810, -91810, -91831, -91841, -91841, -91841, -91864, -91864, -91864, -91864, -91864, -91864, -91903, -91925, -91945, -91945, -91970, -91970, -91970, -91970, -91970, -92003, -92003, +91688, +91709, +91709, +91709, +91709, +91709, +91709, +91709, +91715, +91743, +91777, +91777, +91800, +91817, +91817, +91848, +91848, +91858, +91858, +91867, +91884, +91884, +91900, +91900, +91900, +91913, +91919, +91926, +91934, +91947, +91947, +91947, +91965, +91965, +91965, +91972, +91982, +92009, 92036, -92056, -92056, -92076, -92076, -92110, -92110, -92133, -92143, -92155, -92155, -92155, -92155, -92175, -92175, -92201, -92201, -92201, -92201, -92231, -92231, -92249, -92263, -92263, -92295, -92321, -92335, -92356, -92375, -92375, -92384, -92384, -92384, -92394, -92394, -92423, -92423, -92439, -92451, -92463, -92463, -92504, -92504, -92504, -92504, -92516, -92532, -92532, -92532, -92553, -92566, -92572, -92572, -92572, -92581, -92597, -92597, -92618, -92647, -92654, -92654, -92654, -92661, -92661, -92672, -92672, -92708, -92713, -92730, -92730, -92730, -92730, -92730, -92765, -92765, -92785, -92785, -92793, -92793, -92793, -92830, -92830, -92857, -92857, -92876, -92885, -92885, -92885, -92885, -92885, -92903, -92903, -92936, -92936, -92936, -92946, -92975, -92999, -93037, -93049, -93049, -93056, -93073, -93098, -93098, -93138, -93182, -93189, -93189, -93241, -93290, -93331, -93364, -93364, -93364, -93402, -93415, -93426, -93434, -93458, -93475, -93475, -93484, -93484, -93501, -93501, -93501, -93512, -93524, -93531, -93554, -93567, -93581, -93594, +92057, +92068, +92068, +92093, +92107, +92114, +92120, +92206, +92218, +92218, +92218, +92218, +92233, +92233, +92290, +92303, +92303, +92315, +92315, +92315, +92326, +92339, +92360, +92360, +92372, +92372, +92387, +92387, +92387, +92407, +92431, +92453, +92453, +92453, +92471, +92494, +92494, +92515, +92539, +92557, +92557, +92562, +92573, +92573, +92595, +92601, +92633, +92633, +92633, +92675, +92706, +92706, +92723, +92729, +92729, +92745, +92745, +92760, +92760, +92806, +92831, +92844, +92844, +92850, +92850, +92856, +92856, +92881, +92913, +92930, +92941, +92956, +92967, +92967, +92977, +93000, +93006, +93025, +93051, +93066, +93079, +93091, +93091, +93097, +93103, +93103, +93133, +93133, +93133, +93139, +93139, +93139, +93158, +93164, +93191, +93191, +93191, +93206, +93220, +93235, +93251, +93251, +93251, +93257, +93265, +93265, +93271, +93323, +93341, +93358, +93373, +93390, +93390, +93390, +93398, +93398, +93398, +93407, +93413, +93422, +93428, +93428, +93452, +93477, +93500, +93508, +93529, +93535, +93535, +93561, +93561, +93561, 93594, +93601, 93617, 93617, -93627, -93636, -93643, -93643, -93643, -93643, -93687, -93687, -93687, -93687, -93687, -93687, -93687, -93687, -93687, -93687, -93695, -93695, -93736, -93747, -93754, -93770, -93789, -93801, -93811, -93811, -93821, -93835, -93835, -93885, -93903, -93916, -93916, -93916, -93926, -93935, -93935, -93951, -93958, -93969, -93969, -93969, -93981, -93993, -94006, -94060, -94060, -94074, -94090, -94090, -94129, +93625, +93642, +93659, +93669, +93669, +93675, +93675, +93691, +93691, +93703, +93718, +93718, +93725, +93725, +93725, +93725, +93733, +93733, +93733, +93733, +93749, +93772, +93799, +93814, +93814, +93839, +93861, +93861, +93861, +93861, +93861, +93883, +93883, +93883, +93897, +93910, +93917, +93917, +93940, +93940, +93956, +93956, +93968, +93985, +94005, +94005, +94005, +94011, +94035, +94035, +94066, +94089, +94089, +94089, +94108, +94132, 94157, -94171, -94171, -94207, -94220, -94220, -94249, -94260, -94304, -94304, -94304, -94304, -94315, -94323, -94345, -94362, -94362, -94362, -94373, -94373, +94175, +94175, +94183, +94212, +94218, +94228, +94234, +94257, +94270, +94270, +94270, +94270, +94292, +94308, +94314, +94314, +94331, +94331, +94355, 94380, -94380, -94399, -94410, -94410, -94410, -94415, -94415, -94449, -94449, -94449, -94449, -94449, -94468, -94474, -94483, -94483, -94534, -94534, -94534, -94541, -94562, -94562, -94569, -94581, -94605, -94605, -94605, -94605, -94612, -94612, -94652, -94658, -94673, -94702, -94748, -94800, -94832, -94832, -94867, -94867, -94874, -94874, -94881, -94903, -94903, -94927, +94424, +94445, +94445, +94445, +94445, +94467, +94473, +94488, +94497, +94515, +94524, +94531, +94571, +94571, +94587, +94610, +94620, +94620, +94627, +94633, +94643, +94643, +94643, +94661, +94661, +94661, +94661, +94668, +94668, +94668, +94668, +94696, +94696, +94696, +94696, +94711, +94734, +94756, +94756, +94794, +94807, +94820, +94837, +94857, +94857, +94868, +94878, +94884, +94884, +94884, +94915, 94935, -94957, -94957, -94974, -95012, -95025, -95025, -95060, -95065, -95074, -95092, -95092, -95125, -95125, -95137, -95137, +94935, +94994, +95020, +95020, +95028, +95028, +95028, +95028, +95042, +95052, +95062, +95076, +95099, +95120, +95126, +95156, 95165, -95214, -95231, -95231, -95231, -95231, -95248, -95248, -95248, -95248, -95261, -95261, -95300, -95315, +95218, +95218, +95230, +95230, +95230, +95230, +95242, +95284, +95303, +95316, +95329, +95329, +95329, 95361, -95373, -95392, -95429, -95443, -95443, -95443, -95454, -95473, -95509, -95509, -95552, -95552, -95552, -95577, -95600, -95600, -95637, -95644, -95672, -95672, -95672, -95689, -95689, -95757, -95797, -95797, -95797, -95797, -95815, -95815, -95832, -95847, -95847, -95857, -95870, -95870, -95889, -95889, -95919, -95934, -95944, -95944, -95944, -95981, -95994, -96005, -96005, -96022, -96042, -96042, -96047, -96047, -96047, +95398, +95411, +95411, +95427, +95427, +95462, +95481, +95496, +95496, +95508, +95540, +95540, +95558, +95558, +95585, +95585, +95597, +95607, +95643, +95674, +95688, +95688, +95688, +95718, +95718, +95731, +95750, +95750, +95750, +95768, +95768, +95776, +95776, +95776, +95776, +95776, +95776, +95776, +95804, +95804, +95822, +95829, +95836, +95836, +95836, +95836, +95849, +95849, +95861, +95861, +95861, +95886, +95886, +95886, +95893, +95893, +95911, +95911, +95918, +95918, +95951, +95951, +95951, +95961, +95998, +95998, +95998, +95998, +96013, +96013, +96013, +96013, +96027, 96057, 96065, 96065, -96078, -96078, -96078, -96078, -96111, -96111, -96118, -96143, -96163, -96163, -96182, -96188, -96194, -96194, -96214, -96214, -96221, -96231, -96231, -96231, -96240, -96252, -96252, +96076, +96076, +96076, +96076, +96108, +96120, +96120, +96120, +96129, +96156, +96156, +96177, +96189, +96201, +96211, +96211, +96211, +96211, +96232, +96232, +96244, 96263, -96263, -96263, -96276, -96302, -96302, -96309, -96309, -96323, +96280, +96280, +96301, +96301, +96301, +96321, +96321, +96321, +96333, 96351, -96351, -96351, -96378, -96385, -96398, -96421, -96430, -96430, -96430, -96430, -96430, -96446, -96446, -96446, -96456, -96478, -96478, -96489, -96501, -96512, -96522, -96537, -96558, -96558, -96598, -96615, -96624, -96624, -96640, -96661, -96677, -96686, -96686, -96686, -96701, -96701, -96701, -96701, -96701, -96723, -96733, -96733, -96733, -96754, -96761, -96761, -96782, -96812, -96827, -96833, -96838, -96838, -96859, -96859, -96880, -96880, -96896, -96896, -96923, -96923, -96923, -96923, -96932, -96932, -96956, -96982, -97012, -97038, -97038, -97059, -97059, -97101, -97107, -97123, -97123, -97123, -97123, -97157, -97185, -97215, -97241, -97253, -97253, -97253, -97284, -97295, -97305, -97305, -97305, -97312, -97322, -97341, -97341, -97341, -97341, -97350, -97350, -97391, -97391, -97391, -97421, -97446, -97457, -97457, -97457, -97475, -97481, -97489, -97499, -97508, -97508, -97542, -97558, -97558, -97581, -97581, -97596, -97637, -97637, -97637, -97637, -97637, -97684, +96363, +96363, +96381, +96387, +96394, +96394, +96399, +96399, +96428, +96441, +96441, +96441, +96454, +96463, +96471, +96471, +96481, +96521, +96521, +96534, +96534, +96544, +96566, +96566, +96566, +96566, +96596, +96596, +96596, +96596, +96611, +96611, +96611, +96611, +96629, +96629, +96642, +96642, +96662, +96662, +96676, +96689, +96689, +96699, +96714, +96725, +96725, +96741, +96769, +96769, +96775, +96775, +96783, +96783, +96783, +96801, +96817, +96834, +96834, +96834, +96834, +96844, +96860, +96889, +96929, +96929, +96945, +96945, +96975, +96985, +97002, +97047, +97062, +97062, +97069, +97069, +97082, +97082, +97093, +97126, +97150, +97150, +97150, +97150, +97150, +97175, +97175, +97175, +97175, +97175, +97175, +97196, +97196, +97196, +97196, +97213, +97232, +97249, +97249, +97276, +97289, +97296, +97307, +97307, +97314, +97338, +97338, +97338, +97358, +97375, +97387, +97408, +97408, +97408, +97408, +97425, +97461, +97483, +97502, +97502, +97509, +97509, +97509, +97518, +97540, +97553, +97553, +97553, +97570, +97576, +97576, +97576, +97610, +97610, +97618, +97624, +97630, +97640, +97674, +97699, +97699, +97709, +97709, +97709, +97709, 97720, -97720, -97738, -97738, -97738, -97744, -97744, -97744, -97750, -97750, -97803, -97803, -97827, -97852, -97878, -97885, +97740, +97740, +97740, +97759, +97759, +97759, +97769, +97776, +97829, +97829, +97829, +97863, +97863, +97887, +97904, +97914, +97914, 97927, -97933, -97933, +97937, 97947, -97957, -98014, -98014, -98049, -98049, -98066, -98066, -98089, -98089, +97947, +97947, +97959, +97959, +97959, +97977, +98002, +98016, +98044, +98044, +98062, +98062, +98072, +98072, +98072, +98072, +98086, 98105, -98123, -98130, -98140, -98158, -98196, -98196, -98196, -98237, -98237, -98265, -98292, -98292, -98292, -98299, -98317, -98317, -98317, -98334, -98355, -98365, -98422, -98422, -98464, -98470, -98470, +98124, +98132, +98132, +98148, +98173, +98185, +98206, +98240, +98240, +98259, +98294, +98320, +98346, +98346, +98346, +98379, +98387, +98415, +98442, +98469, 98477, -98499, -98517, -98538, -98550, -98568, -98568, -98585, -98591, -98615}; +98490, +98528, +98528, +98528, +98553, +98562, +98593, +98608, +98622, +98630, +98630, +98637, +98647, +98703, +98733, +98733, +98733, +98749, +98749, +98754, +98759, +98783, +98783, +98808, +98827, +98827, +98827, +98853, +98888, +98888, +98906, +98906, +98926, +98954, +98963, +98963, +98963, +98973, +98991, +98997, +98997, +98997, +98997, +99014, +99014, +99014, +99014, +99022, +99036, +99036, +99080, +99096, +99101, +99101, +99115, +99125, +99135, +99135, +99135, +99163, +99163, +99163, +99203, +99203, +99222, +99222, +99253, +99253, +99285, +99308, +99308, +99308, +99308, +99333, +99360, +99394, +99394, +99408, +99408, +99414, +99420, +99420, +99420, +99469, +99476, +99476, +99476, +99498, +99498, +99498, +99528, +99528, +99528, +99546, +99552, +99558, +99576, +99576, +99576, +99600, +99611, +99611, +99621, +99636, +99636, +99636, +99636, +99636, +99636, +99636, +99687, +99687, +99721, +99728, +99747, +99753, +99753, +99753, +99796, +99801, +99817, +99826, +99858, +99858, +99873, +99873, +99873, +99912, +99912, +99912, +99912, +99939, +99939, +99939, +99939, +99953, +99963, +100010, +100045, +100056, +100056, +100078, +100078, +100078, +100093, +100098, +100098, +100098, +100106, +100113, +100126, +100126, +100126, +100126, +100126, +100126, +100131, +100156, +100156, +100166, +100166, +100166, +100186, +100186, +100186, +100186, +100219, +100236, +100236, +100236, +100236, +100287, +100305, +100313, +100313, +100328, +100328, +100328, +100328, +100352, +100352, +100352, +100352, +100363, +100399, +100399, +100399, +100417, +100433, +100446, +100446, +100464, +100464, +100464, +100521, +100530, +100539, +100565, +100583, +100591, +100601, +100612, +100612, +100612, +100612, +100612, +100618, +100644, +100644, +100652, +100685, +100695, +100695, +100706, +100712, +100749, +100766, +100811, +100834, +100834, +100860, +100869, +100869, +100869, +100889, +100907, +100907, +100913, +100932, +100932, +100932, +100932, +100932, +100932, +100950, +100950, +100963, +100963, +101015, +101026, +101048, +101048, +101084, +101090, +101103, +101119, +101119, +101119, +101137, +101160, +101171, +101180, +101186, +101194, +101194, +101212, +101237, +101260, +101260, +101260}; static const char *tldData[] = { -"sosa.chiba.jp\0" -"!city.sendai.jp\0pixolino.com\0" -"minano.saitama.jp\0" -"ralingen.no\0" -"s3.dualstack.ap-southeast-1.amazonaws.com\0" -"emp.br\0" -"okinawa.okinawa.jp\0" -"kochi.jp\0" -"florida.museum\0" -"katsuragi.nara.jp\0mielec.pl\0" -"vet.br\0solund.no\0" -"dyndns-server.com\0" -"macapa.br\0lib.oh.us\0" -"is-a-cpa.com\0" -"hikone.shiga.jp\0" -"k12.as.us\0" -"yombo.me\0" -"\xe0\xae\x9a\xe0\xae\xbf\xe0\xae\x99\xe0\xaf\x8d\xe0\xae\x95\xe0\xae\xaa\xe0\xaf\x8d\xe0\xae\xaa\xe0\xaf\x82\xe0\xae\xb0\xe0\xaf\x8d\0" -"carrier.museum\0" -"iwanai.hokkaido.jp\0skedsmokorset.no\0" +"ac.lk\0lu.eu.org\0me.eu.org\0" "hazu.aichi.jp\0" -"royken.no\0" -"paris.eu.org\0" -"okuizumo.shimane.jp\0" -"sk.eu.org\0" -"madrid.museum\0cd.eu.org\0" -"v.bg\0" -"vapor.cloud\0" -"sjc.br\0" -"takaoka.toyama.jp\0" -"tv.na\0eidsberg.no\0k12.id.us\0" -"balashov.su\0" -"misato.miyagi.jp\0\xe9\xa4\x90\xe5\x8e\x85\0" -"kokubunji.tokyo.jp\0" -"s3.eu-central-1.amazonaws.com\0" -"tsu.mie.jp\0cambridge.museum\0" -"booking\0" -"kviteseid.no\0" -"suita.osaka.jp\0" -"oz.au\0" -"za.org\0" -"com.ac\0" -"caxias.br\0nisshin.aichi.jp\0" -"dev.static.land\0" -"com.af\0*.advisor.ws\0is-a-guru.com\0" -"com.ag\0kusu.oita.jp\0honjo.saitama.jp\0" -"plus\0" -"com.ai\0" -"bridgestone\0" -"com.al\0" -"act.edu.au\0shimonita.gunma.jp\0kaminoyama.yamagata.jp\0" -"servehalflife.com\0" -"bialystok.pl\0selfip.info\0" -"com.ba\0" -"com.ar\0com.bb\0harima.hyogo.jp\0ebiz.tw\0chintai\0" -"toba.mie.jp\0ciscofreak.com\0" -"x.se\0redirectme.net\0" -"com.au\0" -"com.aw\0" -"com.bh\0sydney.museum\0virtuel.museum\0gs.nt.no\0amli.no\0\xd9\x85\xd8\xb5\xd8\xb1\0\xd8\xb9\xd9\x85\xd8\xa7\xd9\x86\0alt.za\0" -"com.bi\0" -"com.az\0ppg.br\0loginto.me\0" -"com.bm\0" -"dst.mi.us\0" -"com.bo\0dyndns-work.com\0" -"davvesiida.no\0starostwo.gov.pl\0" -"us.com\0" -"com.br\0bilbao.museum\0" -"com.bs\0troms\xc3\xb8.no\0wales\0ru.eu.org\0se.eu.org\0" -"com.bt\0austin.museum\0" -"agriculture.museum\0loab\xc3\xa1t.no\0" -"tjmaxx\0" -"com.by\0com.ci\0sardinia.it\0" -"com.bz\0" -"com.cm\0" -"com.cn\0bo.telemark.no\0lviv.ua\0" -"com.co\0kanzaki.saga.jp\0" -"tamano.okayama.jp\0" -"com.cu\0vegas\0com.de\0" -"kr.ua\0" -"com.cw\0" -"\xd2\x9b\xd0\xb0\xd0\xb7\0fiat\0lasalle\0" -"com.cy\0" -"andriabarlettatrani.it\0" -"genting\0" -"com.dm\0" -"com.do\0" -"hinohara.tokyo.jp\0" -"tomobe.ibaraki.jp\0tv.sd\0exchange\0vote\0" -"yn.cn\0sakai.fukui.jp\0" -"com.ec\0" -"bl.it\0matsubushi.saitama.jp\0" -"com.ee\0" -"com.eg\0" -"enterprises\0" -"com.dz\0pl.ua\0" -"rahkkeravju.no\0voto\0" -"joso.ibaraki.jp\0matsuda.kanagawa.jp\0cc.gu.us\0works\0" -"sciencecenters.museum\0world\0" -"com.es\0" -"com.et\0*.ex.ortsinfo.at\0" -"shika.ishikawa.jp\0" -"gorlice.pl\0shacknet.nu\0dagestan.ru\0" -"matsuno.ehime.jp\0nowruz\0" -"meguro.tokyo.jp\0" -"podhale.pl\0" -"mantova.it\0" -"stor-elvdal.no\0" -"pueblo.bo\0tv.tr\0logoip.com\0" -"operaunite.com\0" -"miasa.nagano.jp\0holt\xc3\xa5len.no\0is-a-bruinsfan.org\0" -"com.fr\0shiiba.miyazaki.jp\0" -"fido\0" -"com.ge\0nanbu.yamanashi.jp\0" -"dagestan.su\0" -"tv.tz\0" -"com.gh\0" -"com.gi\0" -"brumunddal.no\0githubusercontent.com\0" -"a\xc3\xa9roport.ci\0" -"com.gl\0tadotsu.kagawa.jp\0" -"com.gn\0" -"com.gp\0" -"stateofdelaware.museum\0lease\0" -"com.gr\0misugi.mie.jp\0" -"com.gt\0lans.museum\0" -"watch-and-clock.museum\0kaufen\0selfip.com\0" -"com.gy\0" -"com.hk\0" -"katowice.pl\0point2this.com\0" -"ogata.akita.jp\0" -"com.hn\0trana.no\0" -"hagebostad.no\0krager\xc3\xb8.no\0" -"s3-website.us-east-2.amazonaws.com\0" -"com.hr\0ne.jp\0hida.gifu.jp\0" -"ro.im\0" -"com.ht\0dell-ogliastra.it\0tokorozawa.saitama.jp\0bayern\0" -"ro.it\0" -"exchange.aero\0ddr.museum\0\xd8\xa7\xd9\x84\xd8\xac\xd8\xb2\xd8\xa7\xd8\xa6\xd8\xb1\0" -"com.im\0tt.im\0" -"chosei.chiba.jp\0serveirc.com\0" -"com.io\0soeda.fukuoka.jp\0cya.gg\0" -"com.iq\0" -"bato.tochigi.jp\0" -"com.is\0" -"ud.it\0ne.kr\0" -"lancashire.museum\0" -"jogasz.hu\0" +"ac.ma\0auto.pl\0" +"meme\0" +"ac.me\0" +"kuokgroup\0" +"trentinsu\xcc\x88""d-tirol.it\0holtalen.no\0" +"alibaba\0" +"\xd9\x85\xd9\x88\xd8\xa8\xd8\xa7\xd9\x8a\xd9\x84\xd9\x8a\0" +"k12.ct.us\0hu.com\0" +"lib.ar.us\0" +"bbs.tr\0" +"arao.kumamoto.jp\0no-ip.biz\0" +"js.cn\0s3-fips-us-gov-west-1.amazonaws.com\0" +"ac.mu\0" +"bato.tochigi.jp\0agriculture.museum\0" +"ac.mw\0" +"h.se\0" +"ac.ni\0home.dyndns.org\0" +"umi.fukuoka.jp\0ac.mz\0varoy.no\0" +"lv.eu.org\0" +"slg.br\0bando.ibaraki.jp\0community.museum\0" +"s\xc3\xb8rfold.no\0" +"nysa.pl\0travelers\0" +"krokstadelva.no\0is-a-lawyer.com\0" +"baseball.museum\0" +"southcarolina.museum\0" +"menu\0verisign\0" +"kddi\0" +"fc.it\0docs\0nfshost.com\0" +"outsystemscloud.com\0" +"larsson.museum\0med.pro\0" +"forli\xcc\x80""cesena.it\0arts.nf\0ac.nz\0" +"\xe3\x82\xb9\xe3\x83\x88\xe3\x82\xa2\0" +"tsuruta.aomori.jp\0" +"sp.it\0ac.pa\0fhapp.xyz\0" +"study\0" +"misato.akita.jp\0rocher\0" +"us-1.evennode.com\0" +"ralingen.no\0" +"nesna.no\0ddnsfree.com\0" +"urakawa.hokkaido.jp\0tychy.pl\0" +"webhop.org\0" +"artgallery.museum\0" +"saigawa.fukuoka.jp\0state.museum\0" +"contagem.br\0snasa.no\0" +"museum\0doomdns.org\0" +"tone.ibaraki.jp\0" +"bashkiria.ru\0" +"ac.pr\0" +"uchiko.ehime.jp\0sue.fukuoka.jp\0toyosato.shiga.jp\0es.leg.br\0" +"asahi.nagano.jp\0es.kr\0from-wa.com\0" +"ooshika.nagano.jp\0" +"kasukabe.saitama.jp\0" +"sumita.iwate.jp\0" +"nannestad.no\0\xe5\x81\xa5\xe5\xba\xb7\0" +"teshikaga.hokkaido.jp\0" +"slattum.no\0" +"bashkiria.su\0" +"trentinos-tirol.it\0" +"laz.it\0" +"edu.ac\0" +"memorial\0" +"edu.af\0" +"k12.id.us\0" +"from-la.net\0" +"edu.al\0feedback\0" +"vik.no\0" +"ketrzyn.pl\0ac.rs\0" +"doha\0" +"edu.ba\0okaya.nagano.jp\0ac.ru\0ac.se\0cloudcontrolled.com\0" +"edu.ar\0edu.bb\0kunisaki.oita.jp\0" +"ac.rw\0s3.dualstack.eu-central-1.amazonaws.com\0from-al.com\0" +"kouzushima.tokyo.jp\0" +"edu.au\0is-a-knight.org\0" +"edu.bh\0" +"edu.bi\0inc.hk\0" +"edu.az\0yamashina.kyoto.jp\0time.museum\0" +"ishikawa.fukushima.jp\0naruto.tokushima.jp\0myravendb.com\0" +"stage.nodeart.io\0" +"edu.bm\0" +"edu.bn\0" +"edu.bo\0" +"lplfinancial\0ltd.ua\0" +"edu.br\0" +"edu.bs\0" +"edu.bt\0ac.th\0" +"ac.sz\0ac.tj\0" +"taki.mie.jp\0" +"edu.ci\0" +"edu.bz\0ltd.uk\0" +"github.io\0""32-b.it\0" +"hidaka.hokkaido.jp\0school\0" +"edu.cn\0acct.pro\0" +"edu.co\0" +"windmill.museum\0" +"nittedal.no\0" +"r\xc3\xb8st.no\0ac.ug\0unicom\0" +"edu.cu\0" +"latina.it\0oristano.it\0shakotan.hokkaido.jp\0ac.tz\0" +"edu.cw\0ac.uk\0" +"anan.nagano.jp\0notteroy.no\0" +"miyawaka.fukuoka.jp\0" +"accident-investigation.aero\0" +"edu.dm\0gifu.gifu.jp\0" +"edu.do\0" +"kokubunji.tokyo.jp\0kawanishi.yamagata.jp\0thruhere.net\0" +"zentsuji.kagawa.jp\0" +"edu.ec\0" +"\xc3\xa5seral.no\0mincom.tn\0" +"edu.ee\0marine.ru\0" +"equipment.aero\0" +"edu.eg\0kr.eu.org\0" +"arq.br\0" +"tabuse.yamaguchi.jp\0hamburg.museum\0" +"edu.dz\0ac.vn\0" +"emr.it\0" +"from-mi.com\0" +"christiansburg.museum\0" +"edu.es\0kami.miyagi.jp\0" +"edu.et\0fitness\0*.kunden.ortsinfo.at\0" +"tokoname.aichi.jp\0daegu.kr\0" +"ck.ua\0" +"mobara.chiba.jp\0" +"hsbc\0icbc\0" +"\xe5\xa5\x88\xe8\x89\xaf.jp\0k12.mt.us\0" +"ven.it\0virgin\0yachts\0" +"bjerkreim.no\0" +"idv.hk\0namikata.ehime.jp\0tamatsukuri.ibaraki.jp\0luxe\0" +"macerata.it\0microsoft\0" +"minano.saitama.jp\0" +"f.bg\0oseto.nagasaki.jp\0" +"protection\0" +"edu.ge\0from-ak.com\0" +"aaa.pro\0" +"edu.gh\0novara.it\0" +"edu.gi\0" +"maceio.br\0" +"av.it\0turystyka.pl\0download\0" +"edu.gl\0ringsaker.no\0africa\0" +"edu.gn\0" +"movimiento.bo\0" +"edu.gp\0" +"camdvr.org\0" +"edu.gr\0skin\0" +"edu.gt\0" +"edu.gu\0usdecorativearts.museum\0" +"pc.it\0" +"edu.gy\0" +"flora.no\0" +"edu.hk\0perso.sn\0" +"moskenes.no\0" +"sk\xc3\xa5nland.no\0ac.za\0" +"edu.hn\0" +"annefrank.museum\0" +"higashikurume.tokyo.jp\0" +"powiat.pl\0" +"sandnessjoen.no\0" +"edu.ht\0yamagata.ibaraki.jp\0" +"inzai.chiba.jp\0koto.shiga.jp\0godaddy\0" +"niihama.ehime.jp\0flesberg.no\0" +"ac.zm\0community\0viajes\0" +"perso.tn\0observer\0" +"cesenaforli.it\0cloudfront.net\0" +"secure\0" +"edu.in\0zamami.okinawa.jp\0" +"volda.no\0" +"edu.iq\0" +"edu.is\0ac.zw\0" +"edu.it\0" +"fitjar.no\0" +"sukagawa.fukushima.jp\0" +"versailles.museum\0" +"satsumasendai.kagoshima.jp\0educational.museum\0myphotos.cc\0" +"shingu.fukuoka.jp\0shibata.miyagi.jp\0hemne.no\0" +"oyamazaki.kyoto.jp\0" +"nationalheritage.museum\0north-kazakhstan.su\0dscloud.biz\0" +"edu.jo\0diskstation.me\0" +"feira.br\0" +"\xe0\xb2\xad\xe0\xb2\xbe\xe0\xb2\xb0\xe0\xb2\xa4\0vladikavkaz.ru\0" +"tranby.no\0" +"lib.ca.us\0" +"edu.kg\0" +"edu.ki\0" +"windows\0" +"edu.km\0" +"edu.kn\0" +"diskstation.eu\0" +"edu.kp\0lib.pr.us\0" +"kyonan.chiba.jp\0munakata.fukuoka.jp\0edu.la\0andasuolo.no\0vladikavkaz.su\0" +"edu.lb\0schaeffler\0tushu\0" +"takatsuki.shiga.jp\0edu.lc\0" +"slz.br\0koya.wakayama.jp\0meeres.museum\0" +"aetna\0" +"edu.kw\0game\0" +"hanamaki.iwate.jp\0kuroiso.tochigi.jp\0edu.ky\0dscloud.mobi\0" +"edu.kz\0" +"edu.lk\0" +"in-addr.arpa\0soja.okayama.jp\0hamar.no\0" +"mito.ibaraki.jp\0" +"ic.gov.pl\0" +"cc.ga.us\0" +"edu.lr\0bindal.no\0" +"edu.me\0" +"edu.lv\0naroy.no\0" +"edu.mg\0" +"ts.it\0" +"edu.ly\0" +"edu.mk\0" +"edu.ml\0cc.tn.us\0" +"edu.mn\0cruises\0" +"edu.mo\0" +"hasuda.saitama.jp\0" +"um.gov.pl\0" +"edu.ms\0sande.m\xc3\xb8re-og-romsdal.no\0" +"kitagawa.kochi.jp\0edu.mt\0" +"spy.museum\0stryn.no\0" +"kamijima.ehime.jp\0edu.mv\0" +"edu.mw\0edu.ng\0" +"edu.mx\0house\0" +"saga.saga.jp\0edu.my\0edu.ni\0" +"edu.mz\0boldlygoingnowhere.org\0" +"yoshioka.gunma.jp\0lajolla.museum\0" +"pc.pl\0pagespeedmobilizer.com\0" +"edu.nr\0" +"minoh.osaka.jp\0" +"masuda.shimane.jp\0" +"commbank\0" +"oiso.kanagawa.jp\0edu.om\0" +"banamex\0" +"sobetsu.hokkaido.jp\0trust.museum\0" +"nesoddtangen.no\0" +"edu.pa\0" +"chesapeakebay.museum\0" +"trentino-su\xcc\x88""d-tirol.it\0pacific.museum\0" +"dyn.home-webserver.de\0" +"edu.pe\0" +"edu.pf\0duckdns.org\0" +"edu.ph\0" +"\xe6\xa0\x83\xe6\x9c\xa8.jp\0mk.ua\0" +"edu.pk\0myiphost.com\0" +"edu.pl\0" +"jdf.br\0\xd8\xb9\xd8\xb1\xd8\xa7\xd9\x82\0" +"edu.pn\0" +"edu.qa\0" +"edu.pr\0" +"kunneppu.hokkaido.jp\0edu.ps\0" +"edu.pt\0" +"yabuki.fukushima.jp\0" +"kr\xc3\xb8""dsherad.no\0mel\xc3\xb8y.no\0" +"plurinacional.bo\0" +"edu.py\0" +"shikokuchuo.ehime.jp\0" +"kiyose.tokyo.jp\0" +"miho.ibaraki.jp\0" +"bolzano.it\0versicherung\0" +"shisui.chiba.jp\0" +"us.gov.pl\0" +"cc.la.us\0" +"aure.no\0" +"\xe9\xb3\xa5\xe5\x8f\x96.jp\0" +"kawanishi.nara.jp\0av.tr\0" +"government.aero\0jampa.br\0" +"sortland.no\0" +"mymailer.com.tw\0" +"edu.sa\0" +"aerobatic.aero\0edu.sb\0defense.tn\0" +"in.na\0edu.rs\0edu.sc\0" +"sn.cn\0edu.sd\0" +"edu.ru\0" +"edu.rw\0edu.sg\0" +"okuizumo.shimane.jp\0sykkylven.no\0weatherchannel\0" +"in.ni\0" +"edu.sl\0idv.tw\0review\0" +"higashitsuno.kochi.jp\0channelsdvr.net\0" +"edu.sn\0" +"selje.no\0" +"edu.st\0" +"kawanishi.hyogo.jp\0\xe0\xae\x87\xe0\xae\xb2\xe0\xae\x99\xe0\xaf\x8d\xe0\xae\x95\xe0\xaf\x88\0" +"edu.sv\0" +"free\0" +"b\xc3\xa5""d\xc3\xa5""ddj\xc3\xa5.no\0azure\0" +"kembuchi.hokkaido.jp\0edu.sy\0dev.static.land\0" +"edu.tj\0" +"k12.az.us\0" +"sells-for-less.com\0" +"edu.tm\0" +"cloud66.ws\0" +"edu.to\0" +"surnadal.no\0" +"edu.ua\0dn.ua\0" +"hi.cn\0edu.tr\0" +"fukushima.fukushima.jp\0" +"edu.tt\0" +"kunstsammlung.museum\0bargains\0" +"edu.tw\0" +"lib.ma.us\0" +"yabu.hyogo.jp\0" +"nagatoro.saitama.jp\0" +"y.bg\0marriott\0" +"associates\0builders\0diskstation.org\0" +"okegawa.saitama.jp\0" +"kikonai.hokkaido.jp\0edu.vc\0" +"fujikawa.shizuoka.jp\0" +"usculture.museum\0edu.ve\0" +"ci.it\0bomlo.no\0" +"omura.nagasaki.jp\0edu.uy\0" +"hashima.gifu.jp\0" +"casadelamoneda.museum\0hasura-app.io\0" +"bulsan-su\xcc\x88""dtirol.it\0edu.vn\0" +"friulivenezia-giulia.it\0" +"pv.it\0childrensgarden.museum\0stj\xc3\xb8rdal.no\0" +"shintoku.hokkaido.jp\0gs.va.no\0forgot.his.name\0" +"familyds.com\0" +"es.gov.br\0garden.museum\0edu.vu\0weather\0" +"kudamatsu.yamaguchi.jp\0is-a-democrat.com\0crafting.xyz\0" +"wa.gov.au\0taku.saga.jp\0" +"mitane.akita.jp\0taka.hyogo.jp\0" +"paris.museum\0" +"\xd5\xb0\xd5\xa1\xd5\xb5\0" +"f.se\0" +"komoro.nagano.jp\0edu.ws\0george\0" +"pmn.it\0in.rs\0" +"aa.no\0" +"kamisu.ibaraki.jp\0arai.shizuoka.jp\0iki.fi\0" +"tokai.ibaraki.jp\0shiwa.iwate.jp\0" +"telekommunikation.museum\0" +"rokunohe.aomori.jp\0" +"bounty-full.com\0" +"cyber.museum\0" +"chichibu.saitama.jp\0vantaa.museum\0jgora.pl\0hdfcbank\0" +"is-a-conservative.com\0" +"\xe9\xa6\x99\xe5\xb7\x9d.jp\0v\xc3\xa5gs\xc3\xb8y.no\0flights\0" +"emp.br\0" +"in.th\0movie\0" +"mediocampidano.it\0" +"frontdoor\0gbiz\0zappos\0" +"fie.ee\0military.museum\0ovre-eiker.no\0" +"shimosuwa.nagano.jp\0kep.tr\0" +"edu.za\0\xe5\xae\xb6\xe9\x9b\xbb\0" +"tajiri.osaka.jp\0" +"abashiri.hokkaido.jp\0in.ua\0" +"ikaruga.nara.jp\0\xc3\xa5s.no\0" +"ribeirao.br\0aya.miyazaki.jp\0" +"tokushima.jp\0" +"assisi.museum\0" +"edu.zm\0bofa\0" +"sch.ae\0" +"corvette.museum\0" +"mikasa.hokkaido.jp\0" +"in.us\0work\0" +"iwata.shizuoka.jp\0" +"amami.kagoshima.jp\0" +"miyoshi.saitama.jp\0" +"eu-4.evennode.com\0" +"flekkefjord.no\0kvalsund.no\0*.spectrum.myjino.ru\0" +"ohtawara.tochigi.jp\0" +"poltava.ua\0" +"ikusaka.nagano.jp\0ikeda.osaka.jp\0" +"\xd8\xa7\xd9\x84\xd9\x8a\xd9\x85\xd9\x86\0" +"cc.va.us\0net.eu.org\0" +"film.hu\0moscow.museum\0from-nh.com\0" +"ris\xc3\xb8r.no\0" +"nagahama.shiga.jp\0kv.ua\0trade\0" +"e4.cz\0" +"*.statics.cloud\0" +"mitsue.nara.jp\0properties\0" +"osen.no\0" +"yoichi.hokkaido.jp\0" +"fam.pk\0" +"finearts.museum\0" +"berkeley.museum\0" +"furudono.fukushima.jp\0gs.ol.no\0" +"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xd9\x8a\xd9\x87\0" +"monzabrianza.it\0" +"dontexist.com\0" +"penza.su\0" +"takasu.hokkaido.jp\0gyeongbuk.kr\0cc.wy.us\0spb.ru\0" +"motosu.gifu.jp\0" +"imakane.hokkaido.jp\0" +"servesarcasm.com\0" +"yashiro.hyogo.jp\0" "naklo.pl\0" -"sakura\0" -"!city.sapporo.jp\0" -"mol.it\0" -"com.jo\0" -"settlers.museum\0" -"org.ac\0rogers\0" -"kurate.fukuoka.jp\0psp.gov.pl\0lib.la.us\0" +"kicks-ass.net\0" +"equipment\0" +"moroyama.saitama.jp\0eu-3.evennode.com\0" +"avoues.fr\0lib.wa.us\0" +"poa.br\0zara\0" +"spb.su\0" +"tozsde.hu\0" +"homesecuritymac.com\0" +"bitballoon.com\0" +"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xd9\x8a\xd8\xa9\0" +"tools\0" +"aizumisato.fukushima.jp\0dvrcam.info\0" +"nikaho.akita.jp\0" +"mi.it\0" +"is-a-linux-user.org\0" +"semboku.akita.jp\0iwanai.hokkaido.jp\0" +"himeshima.oita.jp\0house.museum\0vf.no\0unj\xc3\xa1rga.no\0cc.md.us\0gallup\0" +"attorney\0" +"gd.cn\0" +"audible\0richardli\0gdynia.pl\0" +"k\xc3\xa5""fjord.no\0" +"depot.museum\0" +"ashoro.hokkaido.jp\0" +"homeftp.org\0" +"friulivegiulia.it\0sakae.chiba.jp\0" +"s3.dualstack.us-east-2.amazonaws.com\0" +"d.bg\0aaa\0" +"limanowa.pl\0" +"kimitsu.chiba.jp\0digital\0" +"cust.testing.thingdust.io\0" +"chuo.yamanashi.jp\0" +"vic.edu.au\0dellogliastra.it\0war.museum\0" +"mitsubishi\0" +"at.it\0" +"hashikami.aomori.jp\0" +"geometre-expert.fr\0" +"ferrari\0" +"sch.id\0graphics\0" +"bond\0" +"nagareyama.chiba.jp\0abb\0" +"b\xc3\xb8.nordland.no\0abc\0" +"pa.it\0kanuma.tochigi.jp\0webhop.net\0" +"webhosting.be\0" +"tomi.nagano.jp\0" +"g\xc3\xa1ls\xc3\xa1.no\0" +"lib.ak.us\0" +"vibovalentia.it\0eu-2.evennode.com\0" +"sch.ir\0fujixerox\0" +"kamioka.akita.jp\0" +"saskatchewan.museum\0" +"kamikawa.hyogo.jp\0" +"asahi.yamagata.jp\0" +"harstad.no\0book\0" +"aisho.shiga.jp\0" +"dali.museum\0" +"sch.jo\0from-ks.com\0" +"lebesby.no\0" +"sampa.br\0" +"aco\0" +"cagliari.it\0olbia-tempio.it\0" +"obihiro.hokkaido.jp\0r\xc3\xb8ros.no\0kozow.com\0" +"kyotanabe.kyoto.jp\0" +"int.ar\0" +"ri.it\0imabari.ehime.jp\0" +"nakaniikawa.toyama.jp\0" +"vanguard\0" +"int.az\0""4lima.de\0" +"rost.no\0" +"ads\0" +"homeunix.net\0" +"int.bo\0" +"sch.lk\0snoasa.no\0aeg\0memset.net\0" +"bharti\0" +"batsfjord.no\0" +"katsuura.chiba.jp\0kashiba.nara.jp\0" +"niiza.saitama.jp\0y.se\0" +"hagebostad.no\0za.bz\0" +"flight.aero\0" +"int.ci\0dyndns-work.com\0" +"revista.bo\0" +"solund.no\0daplie.me\0" +"ubank\0" +"\xe7\xbd\x91\xe5\x9d\x80\0" +"sch.ly\0marburg.museum\0odesa.ua\0" +"int.co\0meguro.tokyo.jp\0" +"hi.us\0video\0" +"online.museum\0dvrdns.org\0" +"afl\0eu-1.evennode.com\0" +"nt.edu.au\0" +"wios.gov.pl\0beats\0ftpaccess.cc\0global.prod.fastly.net\0" +"\xe6\x96\xb0\xe6\xbd\x9f.jp\0" +"rindal.no\0""4lima.at\0" +"nl.ca\0sch.ng\0" +"blogspot.co.at\0" +"niigata.jp\0sydney.museum\0" +"pesaro-urbino.it\0" +"shizuoka.shizuoka.jp\0nerdpol.ovh\0" +"\xe5\x8d\x83\xe8\x91\x89.jp\0hemsedal.no\0sandvikcoromant\0" +"barreau.bj\0ohi.fukui.jp\0" +"viking.museum\0\xd8\xa7\xd9\x84\xd9\x85\xd8\xba\xd8\xb1\xd8\xa8\0from-wy.com\0synology-diskstation.de\0" +"shinjo.okayama.jp\0" +"from-co.net\0" +"4lima.ch\0" +"pharmacy.museum\0actor\0" +"muenster.museum\0embaixada.st\0" +"association.museum\0" +"dyndns.org\0" +"jessheim.no\0" +"\xd0\xbe\xd0\xb4.\xd1\x81\xd1\x80\xd0\xb1\0ieee\0\xe6\xb7\xa1\xe9\xa9\xac\xe9\x94\xa1\0" +"gyeonggi.kr\0" +"consultant.aero\0" +"s3-eu-central-1.amazonaws.com\0" +"bulsan-sudtirol.it\0" +"museet.museum\0" +"ecn.br\0brindisi.it\0" +"studio\0" +"ami.ibaraki.jp\0h\xc3\xa1mm\xc3\xa1rfeasta.no\0aig\0" +"cisco\0" +"ebetsu.hokkaido.jp\0" +"denmark.museum\0kr.com\0" +"sch.qa\0promo\0" +"mi.th\0" +"tomiya.miyagi.jp\0" +"vao.it\0kawasaki.miyagi.jp\0cc.vt.us\0" +"hekinan.aichi.jp\0" +"bd.se\0" +"nagaokakyo.kyoto.jp\0bill.museum\0" +"kinder\0" +"org.ac\0lib.ut.us\0accountant\0allstate\0from-ne.com\0" "org.ae\0" -"org.af\0" -"org.ag\0" -"com.kg\0" +"org.af\0asso.fr\0" +"org.ag\0kakinoki.shimane.jp\0" +"wiw.gov.pl\0" "org.ai\0" -"dellogliastra.it\0fussa.tokyo.jp\0com.ki\0" -"skydiving.aero\0org.al\0" -"com.km\0" -"kamisato.saitama.jp\0" -"org.ba\0com.kp\0hammarfeasta.no\0" -"org.ar\0org.bb\0com.la\0" -"com.lb\0" -"com.lc\0mypep.link\0" -"org.au\0rovno.ua\0" -"*.bd\0" -"mg.gov.br\0koto.tokyo.jp\0sanok.pl\0" -"org.bh\0" -"org.bi\0yokoshibahikari.chiba.jp\0southwest.museum\0" -"org.az\0com.ky\0" -"com.kz\0afjord.no\0" -"com.lk\0americanantiques.museum\0" -"org.bm\0" -"wolterskluwer\0" -"org.bo\0wroclaw.pl\0" -"*.bn\0" -"org.br\0bj.cn\0" -"org.bs\0com.lr\0" -"org.bt\0tarumizu.kagoshima.jp\0productions\0" -"ozora.hokkaido.jp\0" -"shirako.chiba.jp\0heritage.museum\0" -"org.bw\0com.lv\0" -"com.mg\0" -"org.ci\0norddal.no\0iveco\0sp.leg.br\0" -"org.bz\0com.ly\0karmoy.no\0alsace\0" -"\xe9\xab\x98\xe7\x9f\xa5.jp\0" -"com.mk\0" -"t.bg\0*.ck\0hyogo.jp\0com.ml\0mosj\xc3\xb8""en.no\0\xe6\x96\xb0\xe9\x97\xbb\0" -"org.cn\0trentino-s-tirol.it\0catanzaro.it\0sobetsu.hokkaido.jp\0" -"org.co\0" -"com.mo\0" -"nakama.fukuoka.jp\0nakagusuku.okinawa.jp\0" -"mad.museum\0com.na\0staples\0" -"zagan.pl\0" -"com.ms\0cincinnati.museum\0" -"org.cu\0hashimoto.wakayama.jp\0com.mt\0flesberg.no\0" -"gd.cn\0nishihara.kumamoto.jp\0com.mu\0" -"org.cw\0com.mv\0com.nf\0no.com\0" -"uda.nara.jp\0com.mw\0com.ng\0" -"org.cy\0com.mx\0" -"com.my\0com.ni\0" -"org.dm\0ssl.origin.cdn77-secure.org\0" -"org.do\0phone\0" -"nogi.tochigi.jp\0" -"film\0" -"org.ec\0kujukuri.chiba.jp\0georgia.museum\0com.nr\0cloudcontrolled.com\0" -"ap-south-1.elasticbeanstalk.com\0" -"org.ee\0" -"org.eg\0" -"salem.museum\0" -"org.dz\0ne.pw\0webspace.rocks\0" -"utazas.hu\0mein-vigor.de\0" -"com.om\0" -"jessheim.no\0com.pa\0" +"loyalist.museum\0gloppen.no\0fresenius\0" +"guam.gu\0miyoshi.hiroshima.jp\0" +"org.al\0" +"mi.us\0" +"aarborte.no\0" +"shimonita.gunma.jp\0" +"sch.sa\0\xe8\x87\xba\xe7\x81\xa3\0\xe7\x82\xb9\xe7\x9c\x8b\0" +"org.ba\0" +"org.ar\0org.bb\0" +"asso.gp\0" +"org.au\0sannan.hyogo.jp\0" +"miyama.fukuoka.jp\0" +"org.bh\0kosai.shizuoka.jp\0" +"org.bi\0etc.br\0" +"org.az\0" +"nakatsugawa.gifu.jp\0" +"futsu.nagasaki.jp\0paris\0" +"org.bm\0int.is\0" +"org.bn\0s3-ap-southeast-2.amazonaws.com\0" +"org.bo\0" +"minokamo.gifu.jp\0" +"org.br\0" +"org.bs\0" +"org.bt\0for-the.biz\0" +"karasuyama.tochigi.jp\0plants.museum\0static.land\0" +"org.bw\0" +"asso.ht\0" +"org.ci\0" +"org.bz\0" +"union.aero\0*.platform.sh\0" +"erotica.hu\0" +"org.cn\0ino.kochi.jp\0" +"org.co\0randaberg.no\0vindafjord.no\0" +"hiraizumi.iwate.jp\0" +"railway.museum\0swidnica.pl\0\xe0\xb8\xad\xe0\xb8\x87\xe0\xb8\x84\xe0\xb9\x8c\xe0\xb8\x81\xe0\xb8\xa3.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" +"friuli-vgiulia.it\0" +"org.cu\0" +"pa.us\0" +"org.cw\0blogspot.co.id\0" +"accountants\0" +"org.cy\0" +"kamimine.saga.jp\0naumburg.museum\0" +"int.la\0stor-elvdal.no\0property\0" +"org.dm\0statebank\0" +"asso.bj\0" +"org.do\0blogspot.co.il\0" +"d\xc3\xb8nna.no\0" +"misato.wakayama.jp\0" +"org.ec\0saga.jp\0" +"isa.us\0" +"org.ee\0int.lk\0rade.no\0bukhara.su\0" +"\xe6\xbb\x8b\xe8\xb3\x80.jp\0herokuapp.com\0" +"org.eg\0experts-comptables.fr\0lease\0" +"takarazuka.hyogo.jp\0" +"niyodogawa.kochi.jp\0" +"org.dz\0yasu.shiga.jp\0" +"asso.ci\0anz\0" +"w.bg\0aol\0" +"amsterdam\0" +"unjarga.no\0" "org.es\0" -"*.er\0org.et\0minoh.osaka.jp\0levanger.no\0" -"com.pe\0" -"com.pf\0" -"yachts\0" -"com.ph\0" -"grp.lk\0" -"*.fj\0com.pk\0" -"*.fk\0com.pl\0" -"anthropology.museum\0com.qa\0" -"com.pr\0from-in.com\0" -"nuoro.it\0montreal.museum\0com.ps\0" -"org.ge\0com.pt\0" +"org.et\0" +"s3.ap-northeast-2.amazonaws.com\0" +"gojome.akita.jp\0" +"nerima.tokyo.jp\0" +"\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4\xe0\xa4\xae\xe0\xa5\x8d\0" +"val-d-aosta.it\0" +"jp.eu.org\0" +"sncf\0" +"ri.us\0dodge\0" +"mima.tokushima.jp\0int.mv\0" +"int.mw\0" +"pt.it\0southwest.museum\0" +"int.ni\0s\xc3\xb8r-fron.no\0app\0kindle\0" +"nishihara.okinawa.jp\0yandex\0" +"org.ge\0pisa.it\0doesntexist.com\0" +"watari.miyagi.jp\0yono.saitama.jp\0kosei.shiga.jp\0" "org.gg\0" "org.gh\0" -"org.gi\0myvnc.com\0" -"com.py\0s3-eu-west-1.amazonaws.com\0" -"koganei.tokyo.jp\0missile.museum\0apps.fbsbx.com\0" -"org.gl\0" -"org.gn\0" -"org.gp\0" -"is-slick.com\0" -"org.gr\0salzburg.museum\0sytes.net\0" -"okayama.okayama.jp\0" +"org.gi\0zhitomir.ua\0karaganda.su\0" +"satte.saitama.jp\0" +"mitaka.tokyo.jp\0frogn.no\0" +"org.gl\0h\xc3\xb8yanger.no\0" +"systems\0" +"asso.dz\0org.gn\0sarpsborg.no\0" +"swiss\0" +"org.gp\0\xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0\0" +"org.gr\0d.se\0" "org.gt\0" -"yotsukaido.chiba.jp\0higashimatsushima.miyagi.jp\0" -"com.re\0" -"*.gu\0kamo.niigata.jp\0" -"askvoll.no\0" -"org.gy\0" -"takayama.gunma.jp\0yoita.niigata.jp\0gs.va.no\0" -"org.hk\0ragusa.it\0imakane.hokkaido.jp\0chikusei.ibaraki.jp\0myphotos.cc\0" -"imizu.toyama.jp\0" -"org.hn\0tadaoka.osaka.jp\0s\xc3\xb8rreisa.no\0" -"money\0" -"com.ro\0" -"soundandvision.museum\0" -"com.sa\0" -"fukui.fukui.jp\0com.sb\0" -"org.ht\0kuriyama.hokkaido.jp\0maibara.shiga.jp\0com.sc\0" -"org.hu\0com.sd\0" -"soma.fukushima.jp\0tomi.nagano.jp\0com.se\0com.ru\0" -"com.rw\0com.sg\0" -"com.sh\0accenture\0" -"ne.ug\0" -"org.il\0" -"org.im\0inazawa.aichi.jp\0soni.nara.jp\0com.sl\0ne.tz\0" -"org.in\0hisamitsu\0" -"com.sn\0" -"com.so\0" -"org.iq\0" -"org.ir\0" -"org.is\0" -"org.je\0com.st\0" -"intl.tn\0ne.us\0" -"nom.ad\0com.sv\0" -"arte.bo\0nom.ae\0" -"embetsu.hokkaido.jp\0" -"nom.ag\0higashitsuno.kochi.jp\0com.sy\0fire\0" -"oizumi.gunma.jp\0nakagawa.tokushima.jp\0com.tj\0" -"cam.it\0nom.ai\0" -"motoyama.kochi.jp\0com.tm\0tel.tr\0jetzt\0" -"*.jm\0org.jo\0com.tn\0servebbs.net\0nom.al\0" -"com.to\0us-west-1.elasticbeanstalk.com\0" -"kawachinagano.osaka.jp\0vestre-toten.no\0" -"com.ua\0twmail.cc\0" -"com.tr\0" -"com.tt\0" -"nyc.mn\0" -"*.ke\0org.kg\0" -"com.tw\0com.ug\0" -"org.ki\0photo\0" -"*.kh\0" -"boats\0" -"trentinoalto-adige.it\0" -"org.km\0leka.no\0fish\0" -"asaminami.hiroshima.jp\0org.kn\0eid.no\0" -"sakae.chiba.jp\0wsa.gov.pl\0" -"itako.ibaraki.jp\0org.kp\0" -"org.la\0" -"\xe5\xae\xae\xe5\xb4\x8e.jp\0org.lb\0" -"org.lc\0" -"monzaebrianza.it\0com.vc\0" -"hemsedal.no\0" -"com.ve\0" -"from-co.net\0" -"*.kw\0org.ky\0" -"ms.it\0org.kz\0com.uy\0com.vi\0" -"org.lk\0com.uz\0" -"nsw.au\0diet\0ptplus.fit\0" -"pistoia.it\0wi.us\0town\0" -"pvt.ge\0com.vn\0nom.cl\0" -"org.ma\0" -"nom.co\0org.lr\0travel\0" -"org.ls\0forsand.no\0" -"org.me\0" -"org.lv\0com.vu\0" -"org.mg\0ch.eu.org\0" -"vicenza.it\0" -"milano.it\0org.ly\0" -"org.mk\0" -"savona.it\0org.ml\0nuernberg.museum\0muos\xc3\xa1t.no\0" -"rm.it\0org.mn\0cc.va.us\0" -"valleaosta.it\0*.mm\0org.mo\0varoy.no\0immobilien\0" -"research.museum\0" -"org.na\0" -"r\xc3\xb8mskog.no\0futuremailing.at\0" -"org.ms\0" -"org.mt\0com.ws\0" -"org.mu\0" -"org.mv\0" -"org.mw\0org.ng\0eu-west-2.elasticbeanstalk.com\0" -"tr.it\0ms.kr\0org.mx\0cc.wv.us\0" -"vald-aosta.it\0sakura.chiba.jp\0fukumitsu.toyama.jp\0american.museum\0org.my\0org.ni\0" -"fujimino.saitama.jp\0org.mz\0" -"kep.tr\0" -"manno.kagawa.jp\0tamaki.mie.jp\0" -"balestrand.no\0" -"matsumoto.nagano.jp\0" -"eng.pro\0" -"teramo.it\0*.np\0org.nr\0skoczow.pl\0" -"toys\0uk.net\0" -"nom.es\0" -"lib.ks.us\0" -"miyagi.jp\0" -"red.sv\0" -"notteroy.no\0org.nz\0" -"lanxess\0" -"org.om\0" -"yomitan.okinawa.jp\0" -"fuel.aero\0termez.su\0" -"org.pa\0" -"homegoods\0moscow\0" -"nom.fr\0sekikawa.niigata.jp\0org.pe\0" -"org.pf\0" -"nom.gd\0" -"glas.museum\0org.ph\0" -"cultural.museum\0\xd7\x99\xd7\xa8\xd7\x95\xd7\xa9\xd7\x9c\xd7\x99\xd7\x9d.museum\0*.pg\0" -"directory\0virtueeldomein.nl\0" -"org.pk\0" -"org.pl\0" -"castle.museum\0org.pn\0com.zm\0" -"nom.gl\0" -"org.qa\0" -"org.pr\0" -"kyowa.akita.jp\0shirahama.wakayama.jp\0org.ps\0abudhabi\0from-de.com\0" -"org.pt\0" -"cymru\0vaporcloud.io\0" -"miyazaki.miyazaki.jp\0nom.gt\0" -"sakai.ibaraki.jp\0" -"org.py\0" -"misato.saitama.jp\0mattel\0" -"kuchinotsu.nagasaki.jp\0jerusalem.museum\0" -"contemporaryart.museum\0" -"r.bg\0" -"nom.hn\0" -"kitagata.saga.jp\0gaular.no\0" -"iwamizawa.hokkaido.jp\0gotdns.com\0" -"otake.hiroshima.jp\0kawaguchi.saitama.jp\0" -"org.ro\0" -"room\0nom.im\0" -"org.sa\0" -"trentinoaltoadige.it\0org.sb\0" -"tr.no\0org.rs\0org.sc\0" -"org.sd\0" -"org.se\0org.ru\0" -"boutique\0" -"yashio.saitama.jp\0org.sg\0" -"karikatur.museum\0org.sh\0" -"k12.nj.us\0" -"tromso.no\0org.sl\0" -"keisen.fukuoka.jp\0" -"tsuyama.okayama.jp\0org.sn\0" -"org.so\0" -"urausu.hokkaido.jp\0" -"boxfuse.io\0" -"org.st\0police.uk\0" -"uri.arpa\0muroto.kochi.jp\0" -"trento.it\0org.sv\0" -"fot.br\0" -"sld.do\0org.sy\0" -"org.sz\0org.tj\0" -"t.se\0" -"educational.museum\0" -"fie.ee\0org.tm\0" -"kouhoku.saga.jp\0org.tn\0" -"org.to\0\xe0\xa4\xa8\xe0\xa5\x87\xe0\xa4\x9f\0" -"nom.km\0\xe5\x95\x86\xe6\xa5\xad.tw\0" -"org.ua\0" -"abira.hokkaido.jp\0org.tr\0" -"org.tt\0wang\0" -"belluno.it\0habikino.osaka.jp\0" -"homeftp.org\0" -"org.tw\0org.ug\0az.us\0at.eu.org\0" -"orange\0" -"date.hokkaido.jp\0" -"org.uk\0" -"nom.li\0" -"idv.hk\0" -"kakamigahara.gifu.jp\0" -"haga.tochigi.jp\0" -"org.vc\0" -"we.bs\0" -"akaiwa.okayama.jp\0rockart.museum\0org.ve\0" -"botany.museum\0a.prod.fastly.net\0" -"\xe7\xbe\xa4\xe9\xa6\xac.jp\0kamimine.saga.jp\0org.uy\0org.vi\0" -"nom.mg\0imageandsound.museum\0org.uz\0" -"kuroishi.aomori.jp\0" -"denmark.museum\0mus.mi.us\0cyou\0" -"org.vn\0nom.mk\0" -"fuchu.toyama.jp\0org.vu\0statoil\0" -"nom.nc\0\xe0\xa6\xad\xe0\xa6\xbe\xe0\xa7\xb0\xe0\xa6\xa4\0" -"nc.tr\0" -"xz.cn\0" -"mortgage\0nalchik.ru\0" -"nom.ni\0" -"tozawa.yamagata.jp\0yuza.yamagata.jp\0press.museum\0" -"org.ws\0volvo\0" -"contemporary.museum\0" -"sakata.yamagata.jp\0lindesnes.no\0blogsite.xyz\0" -"nom.nu\0" -"sakyo.kyoto.jp\0ms.us\0nc.us\0" -"nalchik.su\0" -"\xd8\xa7\xd9\x8a\xd8\xb1\xd8\xa7\xd9\x86.ir\0" -"s3.dualstack.ap-northeast-1.amazonaws.com\0" -"fr.it\0" -"hiranai.aomori.jp\0bjark\xc3\xb8y.no\0" -"furano.hokkaido.jp\0" -"agr.br\0juif.museum\0" -"sula.no\0" -"nom.pa\0" -"*.ye\0" -"nom.pe\0" -"nom.pl\0" -"dish\0" -"org.za\0myds.me\0" -"bibai.hokkaido.jp\0pohl\0" -"nom.qa\0" -"k12.ec\0" -"aioi.hyogo.jp\0" -"indianapolis.museum\0steinkjer.no\0" -"lib.al.us\0" -"tanabe.kyoto.jp\0ostroleka.pl\0" -"\xed\x95\x9c\xea\xb5\xad\0nom.pw\0" -"vinnica.ua\0" -"na.it\0froland.no\0org.zm\0" -"shiftedit.io\0" -"forde.no\0" -"niteroi.br\0sakado.saitama.jp\0from-al.com\0" -"takatsuki.osaka.jp\0" -"moseushi.hokkaido.jp\0org.zw\0" -"czest.pl\0nom.re\0" -"pmn.it\0\xe9\xa6\x99\xe6\xb8\xaf\0" -"force.museum\0" -"anan.tokushima.jp\0nom.ro\0" -"iruma.saitama.jp\0kvitsoy.no\0" -"medecin.km\0" -"nom.rs\0" -"rovigo.it\0" -"from-ga.com\0" -"tp.it\0presse.km\0amber.museum\0comcast\0workisboring.com\0" -"nom.si\0" -"dyndns.biz\0" -"\xc3\xb8rland.no\0lancia\0property\0" -"history.museum\0nord-odal.no\0shell\0" -"biz.bb\0gemological.museum\0\xc3\xa5snes.no\0" -"\xe7\xb6\xb2\xe7\xbb\x9c.hk\0biz.at\0" -"\xe4\xba\xac\xe9\x83\xbd.jp\0shiso.hyogo.jp\0" -"biz.az\0kitayama.wakayama.jp\0" -"freesite.host\0df.leg.br\0" -"nago.okinawa.jp\0" -"naroy.no\0cruise\0firestone\0" -"nom.tm\0" -"kyowa.hokkaido.jp\0york.museum\0" -"africa\0" -"ome.tokyo.jp\0tananger.no\0lib.mn.us\0" -"ostrowiec.pl\0" -"delta\0" -"tochio.niigata.jp\0presse.ml\0nom.ug\0" -"\xe5\xbe\xae\xe5\x8d\x9a\0" -"netlify.com\0" -"chiyoda.tokyo.jp\0" -"k12.il\0kamogawa.chiba.jp\0" -"susaki.kochi.jp\0" -"vix.br\0k12.ct.us\0" -"panama.museum\0game-host.org\0" -"kitakata.miyazaki.jp\0\xc3\xa5""fjord.no\0nom.vc\0" -"ono.hyogo.jp\0himi.toyama.jp\0lib.sd.us\0" -"eti.br\0biz.cy\0" -"oregon.museum\0newholland\0nom.vg\0" -"sld.pa\0zgora.pl\0biz.dk\0" -"airline.aero\0fujiidera.osaka.jp\0nom.uy\0" -"marche.it\0" -"rawa-maz.pl\0" -"anamizu.ishikawa.jp\0" -"gs.bu.no\0bike\0" -"nt.edu.au\0kadoma.osaka.jp\0is.gov.pl\0" -"bryne.no\0" -"p.bg\0" -"s\xc3\xa1l\xc3\xa1t.no\0" -"culture.museum\0" -"vestv\xc3\xa5g\xc3\xb8y.no\0" -"biz.et\0" -"\xc3\xa1lt\xc3\xa1.no\0" -"\xe0\xae\x87\xe0\xae\xa8\xe0\xaf\x8d\xe0\xae\xa4\xe0\xae\xbf\xe0\xae\xaf\xe0\xae\xbe\0" -"betainabox.com\0" -"to.leg.br\0" -"kakegawa.shizuoka.jp\0" -"author.aero\0homes\0" -"mytuleap.com\0" -"shimoichi.nara.jp\0" -"katsuura.chiba.jp\0kosher\0" -"fitness\0" -"mo.cn\0idv.tw\0" -"mizusawa.iwate.jp\0" -"r.se\0" -"tingvoll.no\0" -"bing\0" -"hatsukaichi.hiroshima.jp\0" -"shitara.aichi.jp\0nom.za\0" -"sugito.saitama.jp\0" -"\xd0\xba\xd0\xbe\xd0\xbc\0" -"nakano.tokyo.jp\0rakkestad.no\0" -"shizuoka.jp\0photography\0myfusion.cloud\0" -"gotpantheon.com\0" -"aaa.pro\0" -"quebec\0" -"shikatsu.aichi.jp\0baths.museum\0" -"grimstad.no\0" -"biz.id\0porn\0" -"aizubange.fukushima.jp\0" -"mopar\0" -"aremark.no\0" -"judygarland.museum\0r\xc3\xa5holt.no\0" -"ven.it\0" -"post\0" -"choyo.kumamoto.jp\0" -"av.it\0lifeinsurance\0" -"mobi.gp\0s3-ca-central-1.amazonaws.com\0" -"kuki.saitama.jp\0" -"global.prod.fastly.net\0" -"media.aero\0kayabe.hokkaido.jp\0\xd8\xa7\xd9\x84\xd8\xa7\xd8\xb1\xd8\xaf\xd9\x86\0" -"biz.ki\0" -"kobierzyce.pl\0intuit\0" -"shimane.jp\0" -"tsubame.niigata.jp\0baseball\0" -"adachi.tokyo.jp\0donostia.museum\0guide\0" -"ashgabad.su\0" -"lezajsk.pl\0" -"vipsinaapp.com\0" -"au.eu.org\0be.eu.org\0*.triton.zone\0" -"iijima.nagano.jp\0" -"farm.museum\0" -"media.hu\0toki.gifu.jp\0s3-website-ap-southeast-2.amazonaws.com\0" -"suisse.museum\0aejrie.no\0" -"cc.ky.us\0" -"uki.kumamoto.jp\0" -"iveland.no\0" -"osasco.br\0" -"\xc3\xa5mli.no\0sund.no\0marine.ru\0" -"friuli-veneziagiulia.it\0b\xc3\xa1jddar.no\0" -"assedic.fr\0guovdageaidnu.no\0s3.dualstack.eu-west-3.amazonaws.com\0" -"kisarazu.chiba.jp\0is-a-democrat.com\0" -"maebashi.gunma.jp\0" -"turin.it\0" -"chiryu.aichi.jp\0kuji.iwate.jp\0""1password.com\0" -"emergency.aero\0higashimatsuyama.saitama.jp\0" -"salvador.br\0" -"friulivgiulia.it\0szczytno.pl\0brussels\0" -"mo.it\0" -"horonobe.hokkaido.jp\0bukhara.su\0" -"biz.mv\0london\0" -"biz.mw\0ddnss.org\0" -"museumcenter.museum\0safe\0" -"biz.ni\0" -"ot.it\0pd.it\0" -"contact\0" -"columbia.museum\0softbank\0blogdns.org\0" -"omachi.saga.jp\0earth\0dnsupdater.de\0" -"association.museum\0" -"\xe5\x98\x89\xe9\x87\x8c\xe5\xa4\xa7\xe9\x85\x92\xe5\xba\x97\0" -"biz.nr\0" -"ri.it\0k12.tr\0uconnect\0" -"ina.saitama.jp\0" -"vgs.no\0" -"lib.ga.us\0" -"chino.nagano.jp\0" -"atsuma.hokkaido.jp\0" -"tn.it\0kannami.shizuoka.jp\0online.museum\0" -"trentino-aadige.it\0" -"fjaler.no\0" -"kasukabe.saitama.jp\0" -"fukudomi.saga.jp\0" -"asuke.aichi.jp\0is-a-republican.com\0" -"nakagawa.nagano.jp\0bg.eu.org\0" -"vs.it\0" -"takamatsu.kagawa.jp\0biz.pk\0k12.vi\0" -"\xc3\xb8rsta.no\0biz.pl\0" -"sabae.fukui.jp\0" -"meldal.no\0" -"biz.pr\0\xd5\xb0\xd5\xa1\xd5\xb5\0" -"school.na\0horten.no\0" -"website\0" -"\xe7\xa6\x8f\xe4\xba\x95.jp\0bandai.fukushima.jp\0" -"definima.net\0" -"fhs.no\0" -"coupons\0" -"cechire.com\0" -"gjemnes.no\0" -"kamagaya.chiba.jp\0gokase.miyazaki.jp\0ritto.shiga.jp\0" -"far.br\0sec.ps\0" -"jaguar\0" -"thruhere.net\0" -"iiyama.nagano.jp\0" -"consultant.aero\0chonan.chiba.jp\0" -"school.nz\0" -"kadogawa.miyazaki.jp\0" -"nishinoomote.kagoshima.jp\0" -"ibara.okayama.jp\0" -"landes.museum\0" -"n.bg\0dreamhosters.com\0hobby-site.org\0" -"e4.cz\0" -"s3-website-eu-west-1.amazonaws.com\0" -"koryo.nara.jp\0minamiizu.shizuoka.jp\0" -"k12.il.us\0" -"safety\0" -"yakumo.shimane.jp\0comsec\0" -"shirosato.ibaraki.jp\0" -"londrina.br\0nakagawa.hokkaido.jp\0media.pl\0" -"servebbs.org\0" -"inf.br\0palace.museum\0" -"babia-gora.pl\0" -"beiarn.no\0\xc3\xa1k\xc5\x8boluokta.no\0nord-aurdal.no\0" -"pb.ao\0pharmacy\0sale\0" -"takaharu.miyazaki.jp\0timekeeping.museum\0" -"medecin.fr\0biz.tj\0loan\0" -"ishikawa.okinawa.jp\0" -"honda\0" -"or.at\0" -"gushikami.okinawa.jp\0" -"izu.shizuoka.jp\0" -"biz.ua\0" -"or.bi\0kamiichi.toyama.jp\0biz.tr\0" -"jx.cn\0" -"biz.tt\0" -"inf.cu\0trapani.it\0goldpoint\0" -"abu.yamaguchi.jp\0vologda.su\0" -"meiwa.mie.jp\0" -"av.tr\0camdvr.org\0" -"barlettatraniandria.it\0mobara.chiba.jp\0haboro.hokkaido.jp\0" -"p.se\0" -"or.ci\0mishima.fukushima.jp\0" -"homeftp.net\0" -"gs.nl.no\0" -"helsinki\0" -"hr.eu.org\0" -"latrobe\0" -"football\0" -"or.cr\0" -"wa.au\0" -"biz.vn\0" -"isleofman.museum\0\xd9\x85\xd9\x88\xd8\xa8\xd8\xa7\xd9\x8a\xd9\x84\xd9\x8a\0" -"niyodogawa.kochi.jp\0datsun\0" -"s3-website.ap-south-1.amazonaws.com\0" -"onagawa.miyagi.jp\0flir\0" -"fuso.aichi.jp\0tsuruoka.yamagata.jp\0gs.sf.no\0" -"jewelry.museum\0" -"aurskog-holand.no\0isteingeek.de\0" -"mydissent.net\0" -"lawyer\0" -"higashi.okinawa.jp\0transport.museum\0" -"nrw.museum\0" -"shimizu.hokkaido.jp\0" -"s\xc3\xb8ndre-land.no\0" -"barsy.online\0firewall-gateway.de\0" -"at.it\0flora.no\0" -"sapo\0" -"daiwa.hiroshima.jp\0kashima.saga.jp\0" -"brescia.it\0schule\0is-leet.com\0" -"mus.br\0seven\0" -"presse.ci\0" -"council.aero\0" -"augustow.pl\0" -"cooperativa.bo\0eu.meteorapp.com\0" -"mo.us\0" -"melhus.no\0loft\0" -"yamatotakada.nara.jp\0fashion\0" -"pesaro-urbino.it\0namikata.ehime.jp\0santafe.museum\0serveftp.net\0" -"california.museum\0nuremberg.museum\0writesthisblog.com\0" -"kagoshima.jp\0taiji.wakayama.jp\0" -"hachirogata.akita.jp\0" -"sandnessjoen.no\0" -"\xe5\xb1\xb1\xe5\x8f\xa3.jp\0" -"biz.zm\0" -"gouv.fr\0" -"sarl\0" -"accident-investigation.aero\0can.museum\0divtasvuodna.no\0" -"prd.fr\0is-a-doctor.com\0" -"shinanomachi.nagano.jp\0" -"ri.us\0" -"nowtv\0" -"verona.it\0nasu.tochigi.jp\0\xd1\x83\xd0\xbf\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0s3.dualstack.eu-central-1.amazonaws.com\0" -"mj\xc3\xb8ndalen.no\0credit\0" -"slask.pl\0" -"bnr.la\0appspot.com\0" -"meteorapp.com\0" -"hirono.iwate.jp\0nanbu.tottori.jp\0simple-url.com\0" -"redumbrella\0" -"or.id\0tn.us\0" -"mod.gi\0" -"villas\0" -"\xe6\x95\x99\xe8\x82\xb2.hk\0taketomi.okinawa.jp\0webhop.biz\0" -"off.ai\0" -"lebesby.no\0lesja.no\0" -"trainer.aero\0" -"harstad.no\0" -"or.it\0hs.kr\0" -"presse.fr\0gouv.ht\0vercelli.it\0" -"infiniti\0" -"saigawa.fukuoka.jp\0" -"rg.it\0" -"or.jp\0" -"mymailer.com.tw\0" -"sasayama.hyogo.jp\0" -"bo.nordland.no\0" -"boehringer\0" -"skiptvet.no\0" -"berg.no\0" -"\xe6\x94\xbf\xe5\xba\x9c\0" -"gouv.bj\0" -"sayama.saitama.jp\0cadaques.museum\0" -"save\0" -"or.kr\0" -"inf.mk\0" -"kaminokawa.tochigi.jp\0" -"kamikawa.hokkaido.jp\0academy\0" -"ovre-eiker.no\0lib.ky.us\0" -"domains\0" -"gouv.ci\0" -"pilot.aero\0" -"koori.fukushima.jp\0" -"kadena.okinawa.jp\0tysnes.no\0" -"luster.no\0" -"prd.km\0kautokeino.no\0" -"dyndns-pics.com\0" -"*.futurecms.at\0" -"estate.museum\0select\0" -"mobi.tt\0from-fl.com\0" -"nyuzen.toyama.jp\0komvux.se\0dyndns-at-work.com\0" -"historical.museum\0watchandclock.museum\0" -"or.na\0" -"perugia.it\0mobi.tz\0" -"or.mu\0" -"sowa.ibaraki.jp\0" -"ikoma.nara.jp\0" -"saxo\0" -"apartments\0" -"kraanghke.no\0" -"hiraizumi.iwate.jp\0prd.mg\0" -"yosemite.museum\0" -"mima.tokushima.jp\0" -"l.bg\0" -"moonscale.net\0" -"nakano.nagano.jp\0" -"kiho.mie.jp\0tsuru.yamanashi.jp\0stat.no\0" -"forsale\0" -"crew.aero\0tsurugi.ishikawa.jp\0bd.se\0" -"kherson.ua\0" -"krodsherad.no\0" -"ind.br\0vestby.no\0bible\0online\0" -"venice.it\0" -"tenei.fukushima.jp\0" -"wakayama.jp\0" -"ama.aichi.jp\0""3utilities.com\0" -"\xe0\xb8\xad\xe0\xb8\x87\xe0\xb8\x84\xe0\xb9\x8c\xe0\xb8\x81\xe0\xb8\xa3.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" -"career\0dvrcam.info\0" -"omitama.ibaraki.jp\0" -"s\xc3\xb8r-odal.no\0" -"kui.hiroshima.jp\0k12.md.us\0" -"clinton.museum\0ask\xc3\xb8y.no\0pila.pl\0" -"avocat.fr\0basilicata.it\0" -"scienceandhistory.museum\0" -"kotoura.tottori.jp\0" -"taxi.br\0" -"kolobrzeg.pl\0s3-fips-us-gov-west-1.amazonaws.com\0" -"onomichi.hiroshima.jp\0aaa\0" -"\xd0\xbc\xd0\xba\xd0\xb4\0zappos\0" -"mihara.hiroshima.jp\0or.pw\0" -"jobs\0aisho.shiga.jp\0kawanishi.yamagata.jp\0" -"kuzumaki.iwate.jp\0n.se\0" -"lombardia.it\0asahi.mie.jp\0s3.dualstack.ap-south-1.amazonaws.com\0" -"detroit.museum\0" -"iitate.fukushima.jp\0" -"pasadena.museum\0s3.dualstack.us-east-1.amazonaws.com\0" -"leirvik.no\0" -"aoste.it\0\xe5\x85\xab\xe5\x8d\xa6\0" -"abb\0" -"misaki.okayama.jp\0abc\0" -"cuiaba.br\0" -"wif.gov.pl\0" -"mobi.na\0" -"orkanger.no\0" -"uwajima.ehime.jp\0higashimurayama.tokyo.jp\0rocher\0" -"mobi.ng\0" -"morena.br\0" -"tj.cn\0" -"ferrari\0" -"rzeszow.pl\0inf.ua\0" -"castres.museum\0" -"matsuzaki.shizuoka.jp\0kh.ua\0" -"sinaapp.com\0" -"blackfriday\0" -"cc.ca.us\0aco\0barsy.bg\0" -"askim.no\0" -"m\xc3\xa5s\xc3\xb8y.no\0or.th\0" -"marylhurst.museum\0edeka\0" -"ar.it\0" -"sling\0" -"halsa.no\0" -"ind.gt\0kawanabe.kagoshima.jp\0" -"minamidaito.okinawa.jp\0" -"munakata.fukuoka.jp\0" -"kitadaito.okinawa.jp\0" -"gos.pk\0" -"ads\0" -"pittsburgh.museum\0" -"or.ug\0" -"laspezia.it\0aeg\0" -"or.tz\0" -"\xd0\xbc\xd0\xbe\xd0\xbd\0barsy.de\0" -"naustdal.no\0fastlylb.net\0" -"myddns.rocks\0" -"windmill.museum\0or.us\0us-west-2.elasticbeanstalk.com\0ba.leg.br\0" -"yamagata.ibaraki.jp\0is-a-candidate.org\0" -"love\0" -"ind.in\0" -"ogawa.nagano.jp\0" -"yokkaichi.mie.jp\0skype\0" -"afl\0" -"svn-repos.de\0diskstation.org\0" -"stjohn.museum\0cc.nj.us\0" -"\xe5\x95\x86\xe5\x9f\x8e\0" -"isshiki.aichi.jp\0hatogaya.saitama.jp\0" -"airtraffic.aero\0akkeshi.hokkaido.jp\0" -"sakae.nagano.jp\0gniezno.pl\0" -"www.ro\0" -"nature.museum\0il.eu.org\0" -"mizumaki.fukuoka.jp\0kitahiroshima.hokkaido.jp\0courses\0barsy.eu\0" -"nakagyo.kyoto.jp\0" -"wa.us\0" -"miyota.nagano.jp\0akishima.tokyo.jp\0" -"\xe5\xa4\xa7\xe5\x88\x86.jp\0" -"is-a-painter.com\0" -"cc.sd.us\0" -"koga.ibaraki.jp\0" -"hareid.no\0omasvuotna.no\0" -"\xe0\xae\x87\xe0\xae\xb2\xe0\xae\x99\xe0\xaf\x8d\xe0\xae\x95\xe0\xaf\x88\0" -"pa.gov.br\0cyber.museum\0" -"re.it\0rexroth\0home-webserver.de\0" -"lancome\0" -"stpetersburg.museum\0" -"delmenhorst.museum\0" -"\xe9\xa6\x99\xe5\xb7\x9d.jp\0vacations\0is-a-musician.com\0" -"yakage.okayama.jp\0fbxos.fr\0servehttp.com\0" -"\xe7\x8f\xa0\xe5\xae\x9d\0cloudfront.net\0" -"aig\0bentley\0pimienta.org\0" -"belem.br\0aure.no\0" -"hu.eu.org\0ie.eu.org\0" -"stjordal.no\0" -"rj.leg.br\0" -"eidsvoll.no\0" -"tinn.no\0" -"s3.us-east-2.amazonaws.com\0" -"kameyama.mie.jp\0" -"vuelos\0" -"warszawa.pl\0\xe8\xb4\xad\xe7\x89\xa9\0" -"freight.aero\0tainai.niigata.jp\0" -"pb.gov.br\0galsa.no\0" -"kawakami.nagano.jp\0nichinan.tottori.jp\0re.kr\0" -"recreation.aero\0yasu.shiga.jp\0aogashima.tokyo.jp\0" -"minobu.yamanashi.jp\0" -"lib.mt.us\0lib.nd.us\0sweetpepper.org\0" -"geology.museum\0" -"barsy.in\0" -"production.aero\0" -"us-4.evennode.com\0" -"rankoshi.hokkaido.jp\0" -"its.me\0lib.pa.us\0" -"haram.no\0" -"abr.it\0" -"ando.nara.jp\0" -"eisenbahn.museum\0" -"frei.no\0v\xc3\xa5gan.no\0is-a-geek.com\0" -"arai.shizuoka.jp\0tranoy.no\0condos\0\xe5\x85\xac\xe5\x8f\xb8\0" -"\xd0\xb1\xd0\xb3\0engineering\0" -"etc.br\0gobo.wakayama.jp\0n\xc3\xa5\xc3\xa5mesjevuemie.no\0dance\0" -"gouv.rw\0" -"karasjok.no\0" -"skjak.no\0consulado.st\0" -"gouv.sn\0is-a-patsfan.org\0" -"winners\0" -"j.bg\0\xe5\xae\xae\xe5\x9f\x8e.jp\0mito.ibaraki.jp\0" -"trentino-sudtirol.it\0wildlife.museum\0warmia.pl\0" -"nagoya\0" -"bel.tr\0zaporizhzhe.ua\0" -"fj.cn\0" -"handa.aichi.jp\0" -"england.museum\0" -"am.leg.br\0" -"ibestad.no\0" -"workshop.museum\0" -"shimoda.shizuoka.jp\0" -"adult.ht\0hannan.osaka.jp\0" -"hiraya.nagano.jp\0" -"osaka\0" -"sunndal.no\0eu.org\0" -"isla.pr\0legal\0" -"massa-carrara.it\0from-nh.com\0" -"amami.kagoshima.jp\0juedisches.museum\0" -"on.ca\0tosa.kochi.jp\0game-server.cc\0" -"frontier\0us-3.evennode.com\0" -"anz\0" -"l.se\0aol\0" -"odessa.ua\0blogdns.net\0" -"naples.it\0" -"holiday\0" -"vic.gov.au\0shingu.hyogo.jp\0" -"sannan.hyogo.jp\0" -"ostroda.pl\0" -"safety.aero\0\xe7\xbd\x91\xe7\xb5\xa1.hk\0walbrzych.pl\0pagefrontapp.com\0" -"vlaanderen.museum\0\xc3\xa5s.no\0ar.us\0" -"kosei.shiga.jp\0" -"lajolla.museum\0" -"capebreton.museum\0" -"fukushima.hokkaido.jp\0app\0" -"tohma.hokkaido.jp\0" -"sx.cn\0" -"ind.tn\0" -"tmall\0" -"tono.iwate.jp\0" -"from-ar.com\0" -"fl.us\0l-o-g-i-n.de\0taifun-dns.de\0" -"\xe0\xb4\xad\xe0\xb4\xbe\xe0\xb4\xb0\xe0\xb4\xa4\xe0\xb4\x82\0" -"hakuba.nagano.jp\0" -"akabira.hokkaido.jp\0\xd0\xb5\xd1\x8e\0" -"bar\0from-ia.com\0" +"org.gu\0bar\0" "bbc\0" -"gotemba.shizuoka.jp\0" -"ia.us\0" -"mk.ua\0dynv6.net\0" -"ap.it\0ashibetsu.hokkaido.jp\0m\xc3\xa1latvuopmi.no\0" -"kazimierz-dolny.pl\0" -"\xe3\x82\xb3\xe3\x83\xa0\0" -"prod\0" -"meeres.museum\0" -"prof\0" -"empresa.bo\0tuxfamily.org\0" -"riik.ee\0art\0bbt\0weir\0" -"sumida.tokyo.jp\0" -"calabria.it\0" -"bcg\0" -"search\0is-an-engineer.com\0us-2.evennode.com\0" -"miyazaki.jp\0is-into-cars.com\0" -"gr.eu.org\0ufcfan.org\0" -"tsuno.miyazaki.jp\0" -"bcn\0" -"is-a-designer.com\0" -"cc.in.us\0" -"eniwa.hokkaido.jp\0ap.leg.br\0" -"pulawy.pl\0" -"saito.miyazaki.jp\0county.museum\0" -"kawamata.fukushima.jp\0arida.wakayama.jp\0cc.ks.us\0" -"googlecode.com\0" -"r.cdn77.net\0" -"choshi.chiba.jp\0gouv.km\0os\xc3\xb8yro.no\0" -"magazine.aero\0beats\0" -"genkai.saga.jp\0watches\0" -"youth.museum\0cc.nh.us\0" -"tochigi.tochigi.jp\0" -"scor\0" -"luroy.no\0" -"minamitane.kagoshima.jp\0scot\0" -"mi.it\0" -"saga.jp\0" -"chikuhoku.nagano.jp\0eu-central-1.elasticbeanstalk.com\0aktyubinsk.su\0ybo.science\0" -"ecn.br\0bet\0" -"furudono.fukushima.jp\0blog\0" -"yonezawa.yamagata.jp\0" -"is-a-geek.org\0" -"gouv.ml\0firewall-gateway.net\0" -"bifuka.hokkaido.jp\0" -"rc.it\0yurihonjo.akita.jp\0" -"bod\xc3\xb8.no\0dyn.home-webserver.de\0" -"ueno.gunma.jp\0" -"mutsu.aomori.jp\0us-1.evennode.com\0synology-diskstation.de\0" -"tobishima.aichi.jp\0is-a-bookkeeper.com\0" -"memorial\0" -"tomari.hokkaido.jp\0" -"fukui.jp\0mill.museum\0" -"fortmissoula.museum\0toyota\0" -"axa\0" -"swidnica.pl\0aws\0" -"apple\0" -"leg.br\0" -"sells-for-u.com\0" -"virginia.museum\0f\xc3\xb8rde.no\0" -"pi.gov.br\0" -"\xd8\xa7\xdb\x8c\xd8\xb1\xd8\xa7\xd9\x86\0" -"doomdns.com\0" -"profesional.bo\0wajima.ishikawa.jp\0" -"kwp.gov.pl\0" -"bid\0" -"\xe5\xa4\xa9\xe4\xb8\xbb\xe6\x95\x99\0" -"maif\0" -"aca.pro\0from-nv.com\0" -"ichinomiya.aichi.jp\0tamayu.shimane.jp\0tube\0" -"rr.leg.br\0ilovecollege.info\0" -"cuneo.it\0bio\0" -"wakkanai.hokkaido.jp\0missoula.museum\0" -"inabe.mie.jp\0" -"andriatranibarletta.it\0futurehosting.at\0" -"flowers\0" -"from-ut.com\0" -"school.za\0build\0" -"biz\0latino\0" -"narashino.chiba.jp\0omigawa.chiba.jp\0" -"\xe0\xb9\x80\xe0\xb8\x99\xe0\xb9\x87\xe0\xb8\x95.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" -"brandywinevalley.museum\0discovery.museum\0finnoy.no\0dyndns-at-home.com\0" -"guardian\0" -"\xe5\xaf\x8c\xe5\xb1\xb1.jp\0sakawa.kochi.jp\0freebox-os.fr\0" -"marburg.museum\0" -"*.magentosite.cloud\0" -"miyama.fukuoka.jp\0" -"h.bg\0" -"katano.osaka.jp\0" -"fineart.museum\0serveftp.org\0" -"ac\0" -"ad\0" -"ae\0rs.leg.br\0sc.leg.br\0" -"af\0" -"ag\0uruma.okinawa.jp\0" -"recife.br\0catering\0" -"ai\0uji.kyoto.jp\0" -"\xe5\x8f\xb0\xe6\xb9\xbe\0" -"al\0blue\0" -"am\0" +"tempio-olbia.it\0tobishima.aichi.jp\0" +"elk.pl\0" +"org.gy\0trentinoalto-adige.it\0" +"aju.br\0org.hk\0" +"tanabe.wakayama.jp\0apartments\0" +"org.hn\0suginami.tokyo.jp\0" +"pimienta.org\0" +"fortworth.museum\0" +"\xe7\x9f\xb3\xe5\xb7\x9d.jp\0" +"org.ht\0nl.no\0" +"org.hu\0" +"art\0bbt\0" +"barsy.info\0" +"bcg\0education\0" +"itoigawa.niigata.jp\0" +"org.il\0hakusan.ishikawa.jp\0yamato.kanagawa.jp\0ina.nagano.jp\0sch.zm\0" +"org.im\0ap-south-1.elasticbeanstalk.com\0" +"org.in\0int.pt\0turen.tn\0chase\0" +"l\xc3\xa4ns.museum\0" +"org.iq\0valle\xcc\x81""edaoste.it\0bcn\0" +"org.ir\0" +"org.is\0byen.site\0" +"org.je\0environmentalconservation.museum\0" +"watchandclock.museum\0intel\0" +"minamidaito.okinawa.jp\0bonn.museum\0" +"doshi.yamanashi.jp\0" +"daito.osaka.jp\0katano.osaka.jp\0" +"taiwa.miyagi.jp\0" +"org.jo\0" +"a\xc3\xa9roport.ci\0" +"miyake.nara.jp\0il.us\0" +"org.kg\0" +"org.ki\0" +"q-a.eu.org\0" +"org.km\0" +"org.kn\0nuernberg.museum\0" +"int.ru\0" +"yamanashi.jp\0org.kp\0\xe0\xb8\x97\xe0\xb8\xab\xe0\xb8\xb2\xe0\xb8\xa3.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0pictures\0" +"ueno.gunma.jp\0chiyoda.tokyo.jp\0org.la\0int.rw\0wi.us\0lamborghini\0" +"org.lb\0" +"org.lc\0" +"eu.com\0" +"sakura.chiba.jp\0" +"org.kw\0bet\0virtualuser.de\0" +"saroma.hokkaido.jp\0" +"org.ky\0cincinnati.museum\0ybo.review\0" +"org.kz\0" +"org.lk\0gdansk.pl\0" +"design.museum\0vlaanderen.museum\0" +"society.museum\0" +"org.ma\0smart\0" +"org.lr\0australia.museum\0" +"org.ls\0" +"int.tj\0is-very-nice.org\0" +"org.me\0" +"marumori.miyagi.jp\0org.lv\0" +"org.mg\0dnsup.net\0" +"org.ly\0ddnsgeek.com\0" +"org.mk\0" +"org.ml\0\xd8\xa7\xd9\x8a\xd8\xb1\xd8\xa7\xd9\x86\0parts\0\xd8\xa8\xd8\xa7\xd8\xb2\xd8\xa7\xd8\xb1\0" +"\xe5\x92\x8c\xe6\xad\x8c\xe5\xb1\xb1.jp\0omotego.fukushima.jp\0" +"org.mn\0int.tt\0" +"org.mo\0center\0" +"freiburg.museum\0org.na\0" +"journalist.aero\0chuo.tokyo.jp\0estate\0party\0" +"org.ms\0" +"org.mt\0axa\0" +"org.mu\0" +"calabria.it\0org.mv\0aws\0googleapis.com\0" +"miners.museum\0org.mw\0org.ng\0" +"niimi.okayama.jp\0toyama.toyama.jp\0org.mx\0" +"org.my\0org.ni\0" +"org.mz\0" +"val-daosta.it\0oumu.hokkaido.jp\0" +"naganohara.gunma.jp\0int.ve\0" +"l\xc3\xb8renskog.no\0org.nr\0" +"ens.tn\0\xd0\xb1\xd0\xb3\0" +"\xe6\x9d\xb1\xe4\xba\xac.jp\0" +"principe.st\0bid\0" +"shiso.hyogo.jp\0int.vn\0" +"org.nz\0" +"olayangroup\0" +"org.om\0" +"org.pa\0\xd8\xa7\xd9\x85\xd8\xa7\xd8\xb1\xd8\xa7\xd8\xaa\0" +"bio\0" +"musashino.tokyo.jp\0" +"org.pe\0cafe\0" +"org.pf\0mytis.ru\0" +"org.ph\0" +"village.museum\0from-pr.com\0" +"\xe6\x9c\xba\xe6\x9e\x84\0" +"org.pk\0" +"name.hr\0org.pl\0browsersafetymark.io\0" +"biz\0" +"ogose.saitama.jp\0org.pn\0kicks-ass.org\0blogspot.co.uk\0" +"okagaki.fukuoka.jp\0" +"nayoro.hokkaido.jp\0" +"openair.museum\0org.qa\0" +"org.pr\0istanbul\0" +"org.ps\0" +"org.pt\0" +"bibai.hokkaido.jp\0" +"org.py\0k12.nh.us\0" +"tsuno.kochi.jp\0" +"tokamachi.niigata.jp\0wales\0" +"cng.br\0" +"name.et\0" +"b.bg\0" +"karpacz.pl\0" +"otsuka\0" +"mini\0" +"ar.it\0hikawa.shimane.jp\0\xe5\x95\x86\xe5\x9f\x8e\0" +"homeftp.net\0" +"video.hu\0gs.fm.no\0" +"b.br\0" +"org.ro\0" +"rennes\xc3\xb8y.no\0" +"org.sa\0" +"org.sb\0" +"org.rs\0org.sc\0mint\0" +"sayama.osaka.jp\0nirasaki.yamanashi.jp\0org.sd\0" +"org.se\0org.ru\0" +"gjerstad.no\0" +"kommune.no\0org.sg\0" +"takashima.shiga.jp\0fhs.no\0org.sh\0from-mn.com\0" +"bsb.br\0\xc3\xb8rskog.no\0" +"jfk.museum\0" +"org.sl\0" +"iwatsuki.saitama.jp\0nanto.toyama.jp\0org.sn\0" +"org.so\0" +"kurashiki.okayama.jp\0\xc3\xa5""fjord.no\0\xd2\x9b\xd0\xb0\xd0\xb7\0" +"civilaviation.aero\0clock.museum\0" +"name.cy\0traniandriabarletta.it\0pruszkow.pl\0" +"org.st\0fastvps-server.com\0" +"lib.mn.us\0" +"org.sv\0bms\0" +"mashiki.kumamoto.jp\0" +"asso.re\0org.sy\0" +"sogndal.no\0org.sz\0org.tj\0bmw\0" +"balestrand.no\0" +"org.tm\0insurance\0" +"org.tn\0\xd0\xb5\xd1\x8e\0" +"otofuke.hokkaido.jp\0org.to\0bnl\0citic\0" +"\xc3\xa5rdal.no\0" +"name.eg\0org.ua\0" +"cz.it\0toyohashi.aichi.jp\0skaun.no\0org.tr\0" +"mihama.aichi.jp\0" +"jewelry.museum\0org.tt\0" +"cc.de.us\0" +"org.tw\0org.ug\0" +"lupin\0" +"shoes\0" +"org.uk\0here-for-more.info\0" +"rg.it\0matta-varjjat.no\0" +"\xe5\x95\x86\xe6\xa5\xad.tw\0wedeploy.sh\0" +"bom\0" +"boo\0" +"org.vc\0" +"name.az\0" +"org.ve\0" +"tateyama.chiba.jp\0" +"bot\0" +"chungnam.kr\0blogspot.co.ke\0nhlfan.net\0" +"kanie.aichi.jp\0miura.kanagawa.jp\0org.uy\0org.vi\0" +"ishinomaki.miyagi.jp\0org.uz\0" +"box\0" +"call\0" +"national.museum\0stavern.no\0w.se\0" +"org.vn\0lima-city.de\0" +"aip.ee\0" +"kani.gifu.jp\0" +"wake.okayama.jp\0" +"\xe5\xbe\xb3\xe5\xb3\xb6.jp\0" +"org.vu\0cab\0" +"soeda.fukuoka.jp\0" +"terni.it\0" +"fr.it\0homeunix.org\0" +"\xd0\xbe\xd0\xb1\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0" +"from-sd.com\0" +"cal\0" +"cam\0camp\0blackbaudcdn.net\0" +"hidaka.kochi.jp\0" +"ut.us\0org.ws\0" +"cba\0" +"car\0" +"to.it\0servebeer.com\0" +"cat\0fukusaki.hyogo.jp\0takanezawa.tochigi.jp\0asso.nc\0*.ex.ortsinfo.at\0" +"klabu.no\0k12.ga.us\0" +"lima-city.at\0" +"higashiyama.kyoto.jp\0" +"shikatsu.aichi.jp\0" +"gorizia.it\0cbn\0*.hosting.myjino.ru\0" +"gjerdrum.no\0" +"ikano\0" +"cbs\0" +"wakayama.jp\0" +"mobi.gp\0" +"hasvik.no\0sosnowiec.pl\0apple\0" +"kaita.hiroshima.jp\0org.za\0lima-city.ch\0" +"eidsvoll.no\0" +"siracusa.it\0" +"miharu.fukushima.jp\0" +"palmsprings.museum\0teaches-yoga.com\0" +"ibestad.no\0" +"kagami.kochi.jp\0" +"avocat.pro\0" +"org.zm\0blogspot.co.nz\0" +"foundation.museum\0style\0dattorelay.com\0" +"air-surveillance.aero\0for-more.biz\0" +"toray\0" +"zaporizhzhia.ua\0" +"sande.more-og-romsdal.no\0\xe7\xbd\x91\xe7\xab\x99\0" +"lib.gu.us\0ceb\0" +"org.zw\0" +"jeju.kr\0" +"haebaru.okinawa.jp\0" +"police.uk\0" +"nomi.ishikawa.jp\0is-a-green.com\0" +"divttasvuotna.no\0ceo\0" +"tree.museum\0zt.ua\0" +"yugawara.kanagawa.jp\0v\xc3\xa5gan.no\0cfa\0engineering\0""001www.com\0" +"choshi.chiba.jp\0care\0" +"cfd\0" +"usa.oita.jp\0lowicz.pl\0gifts\0" +"uscountryestate.museum\0is.eu.org\0" +"buy\0" +"kr.it\0missoula.museum\0sohu\0" +"iide.yamagata.jp\0" +"from-sc.com\0" +"casa\0" +"cars\0" +"per.la\0case\0" +"soma.fukushima.jp\0" +"romskog.no\0" +"izumisano.osaka.jp\0cash\0" +"booking\0" +"k12.la.us\0" +"\xe4\xbd\x90\xe8\xb3\x80.jp\0" +"ibigawa.gifu.jp\0" +"asso.km\0" +"muni.il\0karatsu.saga.jp\0science-fiction.museum\0xbox\0" +"ar.us\0" +"valle\xcc\x81""e-d-aoste.it\0" +"kozagawa.wakayama.jp\0it.eu.org\0myvnc.com\0" +"cog.mi.us\0" +"folldal.no\0" "\xd1\x80\xd1\x84\0" -"ao\0rsvp\0" -"aq\0ba\0is-lost.org\0myeffect.net\0" -"ar\0bb\0noboribetsu.hokkaido.jp\0romsa.no\0" -"as\0" -"at\0izumizaki.fukushima.jp\0" -"au\0qld.edu.au\0be\0shell.museum\0scrysec.com\0" -"bf\0" -"aw\0bg\0kihoku.ehime.jp\0" +"honjo.saitama.jp\0asso.mc\0" +"cultural.museum\0per.nf\0cc.ne.us\0" +"tvedestrand.no\0wedeploy.me\0" +"he.cn\0spydeberg.no\0" +"kommunalforbund.se\0" +"rifu.miyagi.jp\0" +"inuyama.aichi.jp\0nishio.aichi.jp\0akagi.shimane.jp\0k12.ny.us\0" +"mormon\0" +"gs.svalbard.no\0" +"jevnaker.no\0lib.me.us\0office\0myshopblocks.com\0" +"shibecha.hokkaido.jp\0" +"tj\xc3\xb8me.no\0bzh\0" +"u.bg\0\xe9\xa3\x9f\xe5\x93\x81\0" +"takatori.nara.jp\0" +"czest.pl\0" +"modelling.aero\0" +"hammarfeasta.no\0" +"ce.it\0gausdal.no\0" +"\xd7\x99\xd7\xa8\xd7\x95\xd7\xa9\xd7\x9c\xd7\x99\xd7\x9d.museum\0square7.net\0edu.krd\0" +"shinjo.nara.jp\0is-very-bad.org\0" +"potenza.it\0" +"jelenia-gora.pl\0localhost.daplie.me\0" +"9guacu.br\0" +"audio\0" +"naples.it\0pr.it\0furano.hokkaido.jp\0kamikawa.hokkaido.jp\0song\0" +"ask\xc3\xb8y.no\0" +"orange\0telecity\0serveblog.net\0" +"orland.no\0" +"ikata.ehime.jp\0" +"name.vn\0mozilla-iot.org\0" +"fund\0" +"in.eu.org\0" +"matsushima.miyagi.jp\0c66.me\0dattoweb.com\0" +"realm.cz\0" +"\xe5\xba\x83\xe5\xb3\xb6.jp\0" +"b.se\0" +"myactivedirectory.com\0" +"sony\0" +"ookuwa.nagano.jp\0" +"berlin\0" +"xj.cn\0barletta-trani-andria.it\0is-a-painter.com\0" +"annaka.gunma.jp\0tsukui.kanagawa.jp\0" +"towada.aomori.jp\0" +"deporte.bo\0fukuyama.hiroshima.jp\0gent\0does-it.net\0" +"bieszczady.pl\0" +"b\xc3\xa1hccavuotna.no\0" +"kikuchi.kumamoto.jp\0surrey.museum\0piaget\0" +"tos.it\0" +"barsy.club\0" +"name.tj\0" +"republican\0" +"aquarelle\0dunlop\0" +"nakagawa.nagano.jp\0" +"environment.museum\0" +"per.sg\0" +"name.tr\0" +"verm\xc3\xb6gensberatung\0customer.enonic.io\0" +"samukawa.kanagawa.jp\0name.tt\0ericsson\0" +"compare\0" +"katagami.akita.jp\0" +"elburg.museum\0blogspot.co.za\0" +"mashiko.tochigi.jp\0imizu.toyama.jp\0" +"seika.kyoto.jp\0gildesk\xc3\xa5l.no\0" +"station.museum\0" +"elvendrell.museum\0" +"kitashiobara.fukushima.jp\0" +"nic.in\0iglesiascarbonia.it\0" +"sunagawa.hokkaido.jp\0bu.no\0" +"com\0\xe9\x9d\x92\xe6\xa3\xae.jp\0" +"ollo\0" +"kashiwa.chiba.jp\0otobe.hokkaido.jp\0" +"shibuya.tokyo.jp\0halsa.no\0\xd0\xbc\xd0\xbe\xd1\x81\xd0\xba\xd0\xb2\xd0\xb0\0*.cns.joyent.com\0" +"catering.aero\0dyn-ip24.de\0" +"s3.dualstack.ap-south-1.amazonaws.com\0" +"\xe7\xbd\x91\xe7\xb5\xa1.hk\0okoppe.hokkaido.jp\0" +"chosei.chiba.jp\0" +"agdenes.no\0\xe5\x85\xab\xe5\x8d\xa6\0" +"vana\0" +"riobranco.br\0" +"cam.it\0canon\0" +"airtel\0" +"vb.it\0" +"higashinaruse.akita.jp\0" +"pizza\0" +"fjell.no\0dad\0myjino.ru\0" +"career\0" +"\xe5\x8f\xb0\xe6\xb9\xbe\0" +"kitaakita.akita.jp\0kr.ua\0*.quipelements.com\0" +"nanmoku.gunma.jp\0musashimurayama.tokyo.jp\0" +"joetsu.niigata.jp\0" +"s3.dualstack.ap-southeast-1.amazonaws.com\0" +"k12.va.us\0" +"macapa.br\0ehime.jp\0" +"yokohama\0" +"radoy.no\0" +"kiyama.saga.jp\0j\xc3\xb8lster.no\0" +"estate.museum\0serveminecraft.net\0" +"reg.dk\0" +"name.qa\0" +"name.pr\0day\0" +"yoshino.nara.jp\0" +"fedorapeople.org\0" +"gunma.jp\0vestv\xc3\xa5g\xc3\xb8y.no\0" +"lombardy.it\0gamo.shiga.jp\0my-gateway.de\0" +"mango\0" +"reisen\0is-an-accountant.com\0" +"crs\0csc\0" +"name.na\0fedorainfracloud.org\0" +"nagara.chiba.jp\0utashinai.hokkaido.jp\0creditcard\0" +"joyo.kyoto.jp\0katowice.pl\0" +"s3.amazonaws.com\0" +"name.mv\0" +"mihama.fukui.jp\0name.ng\0support\0" +"!city.kitakyushu.jp\0name.my\0company\0" +"8.bg\0" +"vix.br\0computerhistory.museum\0" +"fujimi.nagano.jp\0" +"contractors\0" +"nakai.kanagawa.jp\0\xd9\x85\xd9\x84\xd9\x8a\xd8\xb3\xd9\x8a\xd8\xa7\0" +"miyako.iwate.jp\0" +"okawa.fukuoka.jp\0gujo.gifu.jp\0" +"kids.us\0" +"campidano-medio.it\0mishima.fukushima.jp\0" +"nj.us\0" +"karuizawa.nagano.jp\0dds\0groks-the.info\0" +"lu.it\0me.it\0" +"dyndns-ip.com\0" +"campinagrande.br\0education.museum\0" +"trentin-su\xcc\x88""dtirol.it\0sekigahara.gifu.jp\0moss.no\0" +"makeup\0" +"bible.museum\0" +"parachuting.aero\0chikugo.fukuoka.jp\0chernivtsi.ua\0" +"us-west-2.elasticbeanstalk.com\0" +"ballooning.aero\0" +"galsa.no\0gok.pk\0cbre\0wedeploy.io\0" +"bjark\xc3\xb8y.no\0\xe3\x82\xbb\xe3\x83\xbc\xe3\x83\xab\0from-tx.com\0" +"sumoto.kumamoto.jp\0" +"me.ke\0dev\0" +"grosseto.it\0" +"sevastopol.ua\0" +"yakage.okayama.jp\0" +"abiko.chiba.jp\0name.mk\0" +"ap.it\0" +"tm.cy\0center.museum\0belau.pw\0" +"cc.ak.us\0" +"gobo.wakayama.jp\0" +"ma.gov.br\0" +"pr.us\0" +"oshima.tokyo.jp\0no.com\0" +"\xe5\x9c\xa8\xe7\xba\xbf\0" +"taxi.br\0" +"columbus.museum\0" +"hamura.tokyo.jp\0utsira.no\0" +"minami.fukuoka.jp\0swinoujscie.pl\0cc.oh.us\0" +"bjugn.no\0" +"is-a-libertarian.com\0" +"name.jo\0s3-website-eu-west-1.amazonaws.com\0dattolocal.net\0sopot.pl\0" +"noboribetsu.hokkaido.jp\0we.bs\0" +"enebakk.no\0" +"soka.saitama.jp\0mobi.tt\0dhl\0\xeb\x8b\xb7\xec\xbb\xb4\0" +"krager\xc3\xb8.no\0" +"mobi.tz\0" +"minamiboso.chiba.jp\0" +"taa.it\0omihachiman.shiga.jp\0" +"flowers\0" +"\xe5\xae\xae\xe5\xb4\x8e.jp\0nakijin.okinawa.jp\0" +"kamo.kyoto.jp\0" +"londrina.br\0" +"tm.fr\0\xe9\xb9\xbf\xe5\x85\x90\xe5\xb3\xb6.jp\0\xe5\xa8\xb1\xe4\xb9\x90\0" +"kosuge.yamanashi.jp\0eng.pro\0naturbruksgymn.se\0cc.dc.us\0" +"oceanographique.museum\0" +"myhome-server.de\0" +"re.it\0nic.tj\0" +"toki.gifu.jp\0hapmir.no\0diy\0" +"akabira.hokkaido.jp\0\xe5\x85\xac\xe5\x8f\xb8\0\xe6\x97\xb6\xe5\xb0\x9a\0" +"uk.com\0" +"\xe3\x81\xbf\xe3\x82\x93\xe3\x81\xaa\0is-a-blogger.com\0" +"yamagata.gifu.jp\0tosa.kochi.jp\0fusa.no\0" +"psse.gov.pl\0" +"valleaosta.it\0ma.leg.br\0" +"stord.no\0" +"settlers.museum\0" +"gaivuotna.no\0" +"u.se\0s3-eu-west-2.amazonaws.com\0" +"nhs.uk\0" +"cesenaforli\xcc\x80.it\0" +"wolterskluwer\0" +"events\0" +"church\0" +"tm.hu\0ushiku.ibaraki.jp\0glas.museum\0" +"kafjord.no\0gu.us\0" +"aejrie.no\0computer\0" +"iselect\0" +"como.it\0re.kr\0komvux.se\0" +"utazas.hu\0" +"kurobe.toyama.jp\0" +"engineer.aero\0" +"duck\0travelchannel\0" +"from-ia.com\0" +"*.s5y.io\0" +"franziskaner.museum\0" +"omasvuotna.no\0" +"baseball\0" +"tawaramoto.nara.jp\0" +"lecce.it\0" +"pub.sa\0" +"mobi.na\0spot\0" +"midtre-gauldal.no\0" +"toyono.osaka.jp\0" +"k12.tn.us\0catering\0" +"asakawa.fukushima.jp\0pharmaciens.km\0nyc.museum\0mobi.ng\0" +"freeboxos.fr\0" +"realty\0" +"yakumo.shimane.jp\0" +"oshu.iwate.jp\0" +"usa.museum\0" +"trolley.museum\0skanland.no\0" +"shinshiro.aichi.jp\0" +"tm.km\0" +"vistaprint\0" +"tysnes.no\0" +"pp.az\0pors\xc3\xa1\xc5\x8bgu.no\0" +"even\xc3\xa1\xc5\xa1\xc5\xa1i.no\0dnp\0tickets\0" +"datsun\0home-webserver.de\0" +"valer.ostfold.no\0blogsite.xyz\0" +"murmansk.su\0brasilia.me\0" +"dog\0schule\0" +"vic.au\0" +"space.museum\0" +"takata.fukuoka.jp\0zero\0" +"sel.no\0" +"shimokitayama.nara.jp\0tm.mc\0brandywinevalley.museum\0" +"nuremberg.museum\0homegoods\0kiwi\0ap-northeast-2.elasticbeanstalk.com\0" +"tm.mg\0" +"bergamo.it\0dot\0" +"from-tn.com\0" +"yatomi.aichi.jp\0narita.chiba.jp\0drobak.no\0" +"transport.museum\0" +"carrara-massa.it\0" +"me.tz\0wanggou\0" +"me.uk\0" +"gs.jan-mayen.no\0" +"ichinomiya.chiba.jp\0" +"uenohara.yamanashi.jp\0" +"me.us\0" +"ushuaia.museum\0" +"bizen.okayama.jp\0" +"koori.fukushima.jp\0" +"ac\0aarp\0" +"ad\0tm.no\0" +"ae\0orskog.no\0" +"af\0" +"ag\0" +"perugia.it\0" +"ai\0lewismiller.museum\0monster\0" +"izumizaki.fukushima.jp\0" +"al\0" +"am\0karasjok.no\0eat\0" +"tas.edu.au\0ferrero\0dyn-o-saur.com\0" +"ao\0kiyokawa.kanagawa.jp\0cheap\0" +"aq\0ba\0" +"ar\0bb\0" +"as\0dupont\0from-wi.com\0" +"at\0leirfjord.no\0" +"au\0be\0sh.cn\0kunst.museum\0" +"bf\0shiojiri.nagano.jp\0mobi.ke\0" +"asn.au\0aw\0bg\0wakkanai.hokkaido.jp\0" "ax\0bh\0" "bi\0" "az\0bj\0" -"nishimera.miyazaki.jp\0space.museum\0oppegard.no\0" -"bm\0" -"bo\0dyr\xc3\xb8y.no\0" -"ca\0luxury\0v-info.info\0" -"br\0hita.oita.jp\0" -"bs\0cc\0hoylandet.no\0" +"forli-cesena.it\0" +"air.museum\0" +"bm\0jewelry\0" +"bn\0" +"bo\0lorenskog.no\0" +"ca\0kuroishi.aomori.jp\0hirono.fukushima.jp\0tm.pl\0credit\0ggee\0" +"br\0yawara.ibaraki.jp\0" +"bs\0cc\0" "bt\0cd\0" -"avellino.it\0" -"bv\0cf\0bolt.hu\0" -"bw\0cg\0porsgrunn.no\0" -"ch\0tamamura.gunma.jp\0boomla.net\0" -"by\0ci\0yamanashi.jp\0" -"bz\0bms\0" -"cl\0dep.no\0" -"cm\0" -"cn\0aosta.it\0bmw\0" -"journalist.aero\0co\0" -"shakotan.hokkaido.jp\0" -"cr\0" -"childrensgarden.museum\0philately.museum\0bnl\0" +"bv\0cf\0artsandcrafts.museum\0kosher\0neustar\0" +"bw\0cg\0" +"ch\0eco\0" +"by\0ci\0" +"bz\0total\0" +"cl\0" +"media.aero\0cm\0cc.ms.us\0cc.nc.us\0hyatt\0" +"trading.aero\0cn\0isen.kagoshima.jp\0wegrow.pl\0northwesternmutual\0" +"co\0" +"mino.gifu.jp\0nflfan.org\0" +"cr\0assabu.hokkaido.jp\0" +"gs.cn\0" "cu\0de\0" "cv\0" -"fst.br\0cw\0hasuda.saitama.jp\0" -"cx\0miyako.iwate.jp\0" -"cy\0tec.mi.us\0" +"cw\0s3-website-us-west-1.amazonaws.com\0" +"cx\0servebbs.net\0" +"cy\0" "cz\0dj\0" -"dk\0gifts\0" -"de.us\0k12.ut.us\0" -"dm\0" -"yanagawa.fukuoka.jp\0vestvagoy.no\0" -"do\0national.museum\0" -"iamallama.com\0" -"ec\0ehime.jp\0" -"bom\0" -"ee\0" -"boo\0is-very-good.org\0" -"eg\0" -"mi.th\0" -"pvh.br\0dz\0" -"bot\0" -"artgallery.museum\0illustration.museum\0" -"uryu.hokkaido.jp\0box\0" -"toscana.it\0" -"hosting\0" -"wazuka.kyoto.jp\0host\0" -"pe.gov.br\0es\0s3-website.ap-northeast-2.amazonaws.com\0" -"et\0bergbau.museum\0parti.se\0" -"eu\0is-a-photographer.com\0" -"an.it\0" -"fi\0cab\0" -"osaki.miyagi.jp\0" -"research.aero\0fm\0lillesand.no\0" -"*.sendai.jp\0jprs\0" -"fo\0nordkapp.no\0" -"cs.it\0shinagawa.tokyo.jp\0" -"ga\0\xe6\x9d\xb1\xe4\xba\xac.jp\0" -"fr\0gb\0" -"bar.pro\0cal\0" -"gd\0mi.us\0cam\0" -"ge\0rn.leg.br\0" -"gf\0fujimi.nagano.jp\0" -"gg\0uslivinghistory.museum\0" -"gh\0cba\0" -"gi\0car\0" -"cc.il.us\0" -"cat\0kamioka.akita.jp\0" -"gl\0milan.it\0zachpomor.pl\0" +"dk\0portland.museum\0" +"fst.br\0dm\0" +"edu\0" +"s.bg\0do\0dtv\0" +"hurum.no\0paroch.k12.ma.us\0" +"casacam.net\0" +"chihayaakasaka.osaka.jp\0cechire.com\0" +"ec\0" +"cargo.aero\0tm.ro\0mypsx.net\0" +"ee\0historical.museum\0" +"uonuma.niigata.jp\0" +"eg\0bs.it\0" +"misawa.aomori.jp\0" +"\xe6\x95\x8e\xe8\x82\xb2.hk\0gs.oslo.no\0" +"dz\0nagano.jp\0tm.se\0" +"scrapping.cc\0" +"nankoku.kochi.jp\0" +"higashiyoshino.nara.jp\0" +"kiev.ua\0" +"miyazaki.jp\0kushiro.hokkaido.jp\0" +"es\0" +"et\0" +"eu\0" +"higashiizumo.shimane.jp\0lib.az.us\0" +"fi\0is-uberleet.com\0" +"intuit\0volvo\0" +"dvr\0*.advisor.ws\0" +"nagoya\0" +"fm\0\xc3\xa5snes.no\0" +"andriatranibarletta.it\0nes.akershus.no\0" +"fo\0botany.museum\0alesund.no\0grane.no\0" +"ga\0" +"fr\0gb\0california.museum\0" +"gd\0" +"ge\0" +"gf\0mx.na\0\xe9\xa4\x90\xe5\x8e\x85\0" +"gg\0" +"gh\0sanagochi.tokushima.jp\0active\0" +"gi\0" +"zama.kanagawa.jp\0" +"gl\0namegawa.saitama.jp\0duns\0" "gm\0" -"gn\0" -"art.museum\0" +"gn\0florida.museum\0" "gp\0" -"gq\0" -"gr\0dyndns-home.com\0" -"gs\0takanezawa.tochigi.jp\0nanyo.yamagata.jp\0" -"gt\0krym.ua\0cc.la.us\0" -"cbn\0" -"hopto.org\0" -"gw\0myasustor.com\0" -"\xe5\xae\xb6\xe9\x9b\xbb\0" -"gy\0" -"cbs\0sydney\0" -"hk\0shiojiri.nagano.jp\0" -"hm\0creditcard\0" -"hn\0" -"brasilia.me\0" +"gq\0pt.eu.org\0" +"gr\0" +"gs\0" +"gt\0" +"gu\0" +"gw\0\xe4\xb8\xaa\xe4\xba\xba.hk\0winb.gov.pl\0" +"fed.us\0" +"gy\0iwama.ibaraki.jp\0" +"tr\xc3\xb8gstad.no\0" +"riopreto.br\0hk\0" +"student.aero\0lancaster\0" +"hm\0" +"hn\0madrid\0" +"cc.sc.us\0" +"futtsu.chiba.jp\0" +"sicily.it\0" "hr\0" -"ht\0id\0versailles.museum\0" -"hu\0ie\0drangedal.no\0ro.leg.br\0" -"seiyo.ehime.jp\0chiyoda.gunma.jp\0toshiba\0" -"bloomberg\0" +"\xe5\x98\x89\xe9\x87\x8c\0" +"ht\0id\0cc.na\0" +"hu\0ie\0" +"talk\0" +"economia.bo\0" "il\0" -"im\0lib.as.us\0*.platform.sh\0" +"im\0" "in\0" -"io\0automotive.museum\0" -"koeln\0" +"io\0togo.aichi.jp\0" +"noda.chiba.jp\0augustow.pl\0dvag\0" "iq\0" -"ir\0ikeda.hokkaido.jp\0" -"is\0\xe6\xa0\x83\xe6\x9c\xa8.jp\0vard\xc3\xb8.no\0" -"it\0" -"je\0stj\xc3\xb8rdalshalsen.no\0" -"north.museum\0fitjar.no\0" -"kusatsu.gunma.jp\0no-ip.org\0" -"1kapp.com\0" -"ceb\0cn.com\0" -"ra.it\0" -"mypets.ws\0" -"arq.br\0jo\0malopolska.pl\0podzone.net\0" -"jp\0racing\0" -"abeno.osaka.jp\0does-it.net\0servep2p.com\0" -"sv.it\0skien.no\0ceo\0" -"kg\0" -"cfa\0" -"ki\0alibaba\0" -"sakura.tochigi.jp\0cfd\0redstone\0" -"shikama.miyagi.jp\0" -"km\0engerdal.no\0pa.gov.pl\0" +"ir\0cody.museum\0" +"is\0flakstad.no\0" +"it\0misato.shimane.jp\0" +"je\0" +"aver\xc3\xb8y.no\0prochowice.pl\0able\0" +"lucania.it\0" +"fortmissoula.museum\0gleeze.com\0" +"khmelnytskyi.ua\0" +"hichiso.gifu.jp\0" +"jo\0glass.museum\0" +"jp\0" +"chino.nagano.jp\0" +"internet-dns.de\0" +"ke\0opoczno.pl\0" +"griw.gov.pl\0" +"kg\0k12.il.us\0" +"rakkestad.no\0" +"ki\0" +"kikugawa.shizuoka.jp\0nasushiobara.tochigi.jp\0" +"km\0misconfused.org\0" "kn\0" -"saitama.jp\0forgot.her.name\0" -"kp\0gs.svalbard.no\0buy\0" +"kp\0" "la\0" -"kr\0lb\0" -"miyama.mie.jp\0lc\0" -"servebbs.com\0" -"rennesoy.no\0selje.no\0" -"agrigento.it\0" -"ky\0li\0" -"kz\0\xd0\xbe\xd1\x80\xd0\xb3\0" -"lk\0" -"numata.hokkaido.jp\0" -"yasaka.nagano.jp\0hm.no\0lib.nh.us\0azure\0" -"ma\0" -"ina.ibaraki.jp\0lr\0kitchen\0" -"ls\0mc\0seat\0" -"aridagawa.wakayama.jp\0lt\0md\0" -"lu\0me\0bloxcms.com\0" -"lv\0ushistory.museum\0services\0" -"kokonoe.oita.jp\0mg\0" -"mh\0arts.museum\0lahppi.no\0marnardal.no\0" -"ly\0" -"miyako.fukuoka.jp\0mk\0memorial.museum\0" -"ml\0" -"kmpsp.gov.pl\0" -"mn\0" -"mo\0" -"val-daosta.it\0ookuwa.nagano.jp\0mp\0" -"mq\0na\0" -"mr\0" -"ms\0nc\0graphics\0" -"mt\0lenvik.no\0blanco\0" -"mu\0ne\0" -"mv\0nf\0" -"mw\0ng\0madrid\0" -"mx\0" -"my\0ni\0today\0" -"mz\0" -"nl\0bbs.tr\0" -"cq.cn\0ol.no\0bir.ru\0" -"f.bg\0nobeoka.miyazaki.jp\0" -"no\0sko.gov.pl\0" -"\xe9\x9d\x92\xe6\xa3\xae.jp\0nr\0" -"moscow.museum\0" -"software\0" -"funahashi.toyama.jp\0nu\0food\0" -"unusualperson.com\0" -"lib.vt.us\0" -"nz\0" -"*.statics.cloud\0" -"trani-andria-barletta.it\0om\0\xe0\xac\xad\xe0\xac\xbe\xe0\xac\xb0\xe0\xac\xa4\0" -"surgeonshall.museum\0" -"bzh\0xs4all.space\0" -"hk.cn\0pa\0s3-ap-southeast-2.amazonaws.com\0" -"pr.gov.br\0" -"urbino-pesaro.it\0pe\0" -"pf\0publishproxy.com\0" -"bialowieza.pl\0" -"ph\0s3-us-gov-west-1.amazonaws.com\0" +"shimodate.ibaraki.jp\0nagasaki.nagasaki.jp\0kr\0lb\0" +"lc\0" +"tromso.no\0" +"tm.za\0" +"kw\0" "\xe5\x85\xac\xe7\x9b\x8a\0" -"seek\0" -"toyo.kochi.jp\0tonsberg.no\0pk\0fh.se\0" -"sveio.no\0pl\0" -"pm\0" +"ky\0li\0" +"kz\0" +"lk\0" +"realtor\0" +"storj.farm\0" +"!city.yokohama.jp\0is-a-student.com\0" +"ma\0" +"lr\0elverum.no\0" +"ls\0mc\0norddal.no\0" +"lt\0md\0gs.of.no\0" +"minamifurano.hokkaido.jp\0lu\0me\0" +"lv\0" +"mg\0" +"asn.lv\0mh\0hughes\0" +"tokorozawa.saitama.jp\0ly\0" +"ainan.ehime.jp\0mydrobo.com\0" +"airport.aero\0mk\0" +"ml\0mordovia.su\0" +"mn\0" +"kobayashi.miyazaki.jp\0mo\0" +"trainer.aero\0mp\0click\0technology\0\xe9\x9b\x86\xe5\x9b\xa2\0" +"milano.it\0mq\0na\0" +"workinggroup.aero\0mr\0togliatti.su\0" +"ms\0nc\0" +"mt\0" +"mu\0ne\0" +"togitsu.nagasaki.jp\0mv\0nf\0" +"mw\0ng\0" +"6.bg\0mx\0" +"my\0ni\0rana.no\0\xe5\xb9\xbf\xe4\xb8\x9c\0" +"mz\0" +"nl\0" +"no\0helsinki\0" +"uwajima.ehime.jp\0" +"dnsalias.net\0" +"tahara.aichi.jp\0nr\0" +"pp.se\0pp.ru\0" +"\xe5\x8f\xb0\xe7\x81\xa3\0" +"nu\0" +"realestate.pl\0" +"medicina.bo\0" +"nh.us\0" +"awaji.hyogo.jp\0nz\0" +"mc.it\0kiyosu.aichi.jp\0" +"om\0is-a-teacher.com\0" +"sumida.tokyo.jp\0" +"sakai.osaka.jp\0avianca\0" +"pa\0" +"tsubata.ishikawa.jp\0""4u.com\0" +"cc.ua\0" +"pe\0" +"pf\0" +"ph\0" +"myoko.niigata.jp\0" +"brescia.it\0" +"pk\0" +"pl\0mordovia.ru\0" +"\xe7\xbd\x91\xe7\xbb\x9c.cn\0pm\0" "pn\0" -"press.aero\0" -"qa\0k12.ny.us\0my-wan.de\0" +"pp.ua\0" +"ouchi.saga.jp\0qa\0" "pr\0" -"gratangen.no\0ps\0" -"suzu.ishikawa.jp\0pt\0" -"matsumoto.kagoshima.jp\0pw\0" -"py\0h.se\0" -"valledaosta.it\0" -"chuo.osaka.jp\0" -"iwafune.tochigi.jp\0" -"capital\0" -"konyvelo.hu\0" -"nikko.tochigi.jp\0" -"kharkiv.ua\0" -"hiroshima.jp\0" -"re\0ford\0" -"cymru.museum\0bievat.no\0" -"docs\0" -"ginan.gifu.jp\0kozow.com\0iki.fi\0" -"uozu.toyama.jp\0saarland\0" -"ohira.tochigi.jp\0hitachi\0" -"myfritz.net\0" -"geometre-expert.fr\0" -"ro\0dc.us\0" -"tolga.no\0" -"dovre.no\0m\xc3\xa5lselv.no\0sa\0" -"sb\0is-saved.org\0" -"rs\0sc\0" -"sd\0" -"gifu.gifu.jp\0ru\0se\0" -"rw\0sg\0" -"sh\0" -"si\0" -"sj\0" -"sk\0" -"sl\0azure-mobile.net\0" -"sm\0*.compute.amazonaws.com.cn\0" -"holmestrand.no\0sn\0trust\0" +"ps\0" +"takasago.hyogo.jp\0pt\0" +"\xe8\xaf\xba\xe5\x9f\xba\xe4\xba\x9a\0" +"pw\0fan\0" +"hachinohe.aomori.jp\0tsugaru.aomori.jp\0" +"an.it\0py\0" +"muenchen.museum\0" +"teo.br\0" +"tsurugashima.saitama.jp\0" +"\xe9\x9d\x99\xe5\xb2\xa1.jp\0" +"bristol.museum\0" +"miki.hyogo.jp\0re\0" +"security\0" +"lebtimnetz.de\0" +"cc.nv.us\0" +"flt.cloud.muni.cz\0" +"yahoo\0" +"floripa.br\0lezajsk.pl\0luxury\0" +"adachi.tokyo.jp\0" +"niikappu.hokkaido.jp\0" +"nara.nara.jp\0hattfjelldal.no\0ro\0" +"sa\0" +"mg.gov.br\0sb\0netflix\0" +"takamori.kumamoto.jp\0rs\0sc\0" +"la-spezia.it\0nishiokoppe.hokkaido.jp\0barcelona.museum\0\xc3\xb8ygarden.no\0sd\0" +"togura.nagano.jp\0ru\0se\0" +"donna.no\0" +"shiraoi.hokkaido.jp\0rw\0sg\0abbott\0" +"sn\xc3\xa5sa.no\0sh\0" +"si\0cleverapps.io\0" +"sj\0esq\0" +"usgarden.museum\0sk\0servecounterstrike.com\0" +"tank.museum\0v\xc3\xa6r\xc3\xb8y.no\0sl\0" +"tomigusuku.okinawa.jp\0sm\0azerbaijan.su\0" +"sn\0" "so\0" -"alaska.museum\0ruhr\0" -"sr\0" +"british.museum\0sr\0" "tc\0" -"st\0td\0from-wy.com\0cust.testing.thingdust.io\0" +"st\0td\0" "su\0" "sv\0tf\0" -"tg\0" -"wakasa.fukui.jp\0fosnes.no\0sx\0th\0godaddy\0" -"al.it\0numata.gunma.jp\0sy\0" -"tmp.br\0sz\0tj\0" +"architecture.museum\0tg\0" +"sx\0th\0" +"pup.gov.pl\0sy\0*.transurl.be\0" +"sz\0tj\0vuelos\0" "tk\0" -"tl\0gallery\0" -"tm\0" -"hamatama.saga.jp\0tn\0" -"smola.no\0to\0" +"tl\0" +"rc.it\0tm\0" +"tn\0" +"westfalen.museum\0to\0" "ua\0" -"tr\0anquan\0" -"com\0tt\0store\0" -"se.leg.br\0" -"hamada.shimane.jp\0tv\0mango\0" -"tw\0ug\0" -"exeter.museum\0" -"matta-varjjat.no\0" -"tz\0" -"nichinan.miyazaki.jp\0uk\0" -"statefarm\0" -"odate.akita.jp\0pramerica\0s3-website.ca-central-1.amazonaws.com\0" -"genoa.it\0asahi.ibaraki.jp\0va\0" -"sic.it\0" -"us\0vc\0" -"ve\0doha\0" -"mino.gifu.jp\0" -"mihama.chiba.jp\0vg\0" -"ski.museum\0uy\0vi\0" -"uz\0" -"bharti\0dad\0estate\0mysecuritycamera.net\0" -"vn\0" -"carrara-massa.it\0uber.space\0" -"nishio.aichi.jp\0cc.mt.us\0cc.nd.us\0" -"irish\0" -"assn.lk\0vu\0" -"wf\0" -"lu.it\0me.it\0" -"publ.pt\0" -"yamada.fukuoka.jp\0morioka.iwate.jp\0day\0is-a-geek.net\0" -"flight.aero\0" -"obama.nagasaki.jp\0malatvuopmi.no\0ws\0" -"saku.nagano.jp\0" -"museumvereniging.museum\0" -"\xe7\x9f\xb3\xe5\xb7\x9d.jp\0" -"kyoto.jp\0crs\0csc\0yandex\0dnsdojo.com\0" -"kunneppu.hokkaido.jp\0" -"nanporo.hokkaido.jp\0\xe0\xb8\x97\xe0\xb8\xab\xe0\xb8\xb2\xe0\xb8\xa3.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" -"rygge.no\0" -"takasaki.gunma.jp\0paderborn.museum\0dynalias.net\0" -"fr.eu.org\0" -"al.no\0" -"museet.museum\0gran.no\0" -"liguria.it\0" -"tysv\xc3\xa6r.no\0" -"*.platformsh.site\0wellbeingzone.co.uk\0" -"revista.bo\0" -"aomori.jp\0" -"lib.id.us\0" -"my-firewall.org\0" -"svalbard.no\0" -"kitaakita.akita.jp\0" -"vi.it\0sasebo.nagasaki.jp\0imari.saga.jp\0aero.tt\0" -"yt\0" -"fvg.it\0" -"co.ae\0" -"co.ag\0" -"dds\0" -"civilization.museum\0fet.no\0" -"kanuma.tochigi.jp\0" -"zm\0" -"ikata.ehime.jp\0takarazuka.hyogo.jp\0" -"alessandria.it\0bellevue.museum\0lupin\0" -"oga.akita.jp\0gloppen.no\0" -"co.ao\0tagami.niigata.jp\0" -"higashisumiyoshi.osaka.jp\0lib.nj.us\0" -"co.bb\0wuoz.gov.pl\0" -"oxford.museum\0aero.mv\0" -"co.at\0voagat.no\0" -"zw\0" -"ugim.gov.pl\0co.krd\0" -"soka.saitama.jp\0americana.museum\0" -"co.bi\0protonet.io\0" -"ferrara.it\0" -"vennesla.no\0dev\0yokohama\0" -"kizu.kyoto.jp\0" -"tonami.toyama.jp\0l\xc3\xa6rdal.no\0" -"co.ca\0resindevice.io\0" -"better-than.tv\0" -"yaese.okinawa.jp\0" -"co.bw\0" -"co.ci\0" -"fukagawa.hokkaido.jp\0" -"co.cl\0" -"co.cm\0" -"d.bg\0porsangu.no\0" -"co.cr\0kosai.shizuoka.jp\0minami-alps.yamanashi.jp\0" -"getmyip.com\0" -"bahn.museum\0from-or.com\0" -"bsb.br\0kamigori.hyogo.jp\0" -"caa.aero\0\xe5\xb2\xa1\xe5\xb1\xb1.jp\0" -"indianmarket.museum\0co.cz\0" -"film.museum\0co.dk\0" -"higashinaruse.akita.jp\0" -"konin.pl\0" -"takayama.gifu.jp\0" -"dhl\0plumbing\0" -"hi.cn\0st.no\0" -"hikari.yamaguchi.jp\0watch\0" -"sorreisa.no\0" -"se.net\0ru.net\0" -"!city.kobe.jp\0" -"kerryproperties\0" -"qld.gov.au\0ozu.kumamoto.jp\0" -"fujikawa.shizuoka.jp\0konskowola.pl\0" -"mydrobo.com\0" -"zao.miyagi.jp\0audio\0" -"*.sch.uk\0" -"ogasawara.tokyo.jp\0servegame.com\0" -"association.aero\0ar.com\0" -"\xe6\xb2\x96\xe7\xb8\x84.jp\0obanazawa.yamagata.jp\0" -"yamanouchi.nagano.jp\0" -"f.se\0" -"po.gov.pl\0" -"honjo.akita.jp\0military.museum\0\xe5\x8f\xb0\xe7\x81\xa3\0" -"gs.mr.no\0diy\0" -"nx.cn\0abashiri.hokkaido.jp\0zama.kanagawa.jp\0canada.museum\0" -"airguard.museum\0" -"siracusa.it\0tendo.yamagata.jp\0" -"ac.gov.br\0\xe5\xb3\xb6\xe6\xa0\xb9.jp\0" -"tecnologia.bo\0rokunohe.aomori.jp\0volkenkunde.museum\0wodzislaw.pl\0" -"campidanomedio.it\0al.us\0" -"co.gg\0" -"makeup\0" -"cranbrook.museum\0" -"co.gl\0ikaruga.nara.jp\0" -"okayama.jp\0spb.ru\0" -"s3-eu-west-3.amazonaws.com\0" -"gs.rl.no\0" -"\xe5\x9c\xa8\xe7\xba\xbf\0" -"tokigawa.saitama.jp\0sn\xc3\xa5sa.no\0" -"co.gy\0" -"ketrzyn.pl\0fbx-os.fr\0" -"ide.kyoto.jp\0" -"ascolipiceno.it\0wassamu.hokkaido.jp\0okutama.tokyo.jp\0farmstead.museum\0associates\0" -"sirdal.no\0spb.su\0" -"goiania.br\0" -"ham-radio-op.net\0" -"gateway.museum\0" -"co.id\0" -"co.hu\0sar.it\0" -"takagi.nagano.jp\0bofa\0" -"airbus\0" -"co.il\0is-a-lawyer.com\0" -"co.im\0\xe8\x8c\xa8\xe5\x9f\x8e.jp\0" -"co.in\0h\xc3\xa1pmir.no\0" -"mulhouse.museum\0me.tz\0" -"os.hedmark.no\0me.uk\0" -"trading.aero\0co.ir\0" -"kudamatsu.yamaguchi.jp\0gok.pk\0podlasie.pl\0" -"co.it\0vibo-valentia.it\0\xe5\xa8\xb1\xe4\xb9\x90\0" -"co.je\0g\xc3\xa1ivuotna.no\0" -"ce.leg.br\0" -"me.us\0" -"ulm.museum\0" -"koebenhavn.museum\0" -"gs.oslo.no\0studio\0" -"piacenza.it\0" -"co.jp\0mitoyo.kagawa.jp\0nabari.mie.jp\0" -"casino.hu\0\xe9\xa3\x9e\xe5\x88\xa9\xe6\xb5\xa6\0" -"brussel.museum\0" -"dnp\0" -"yonago.tottori.jp\0johana.toyama.jp\0sexy\0" -"kaho.fukuoka.jp\0" -"dog\0webhop.org\0" -"shintoku.hokkaido.jp\0" -"tomigusuku.okinawa.jp\0" -"setagaya.tokyo.jp\0" -"co.kr\0" -"agrar.hu\0co.lc\0" -"somna.no\0" -"cloudcontrolapp.com\0fedorainfracloud.org\0" -"dot\0" -"eiheiji.fukui.jp\0" -"habmer.no\0" -"mc.it\0" -"\xe4\xb8\xaa\xe4\xba\xba.hk\0" -"taishi.osaka.jp\0akrehamn.no\0vi.us\0" -"co.ma\0" -"no-ip.net\0" -"co.ls\0beauxarts.museum\0" -"nagano.nagano.jp\0" -"takahagi.ibaraki.jp\0co.me\0" -"kisosaki.mie.jp\0" -"koga.fukuoka.jp\0co.mg\0" -"horse\0" -"northwesternmutual\0" -"kita.osaka.jp\0" -"hermes\0" -"podzone.org\0" -"gangwon.kr\0co.na\0sandvik\0" -"kira.aichi.jp\0" -"kaisei.kanagawa.jp\0" -"from-mi.com\0is-a-therapist.com\0" -"co.mu\0" -"co.mw\0" -"pors\xc3\xa1\xc5\x8bgu.no\0auspost\0" -"co.ni\0eat\0qc.com\0" -"sr.it\0nahari.kochi.jp\0moma.museum\0co.mz\0" -"kotohira.kagawa.jp\0" -"monza.it\0co.nl\0" -"historichouses.museum\0blogsite.org\0" -"co.no\0" -"nagawa.nagano.jp\0" -"rebun.hokkaido.jp\0lyngdal.no\0" -"marketing\0tunk.org\0" -"horology.museum\0r\xc3\xb8yken.no\0" -"geisei.kochi.jp\0balat.no\0co.nz\0" -"koshimizu.hokkaido.jp\0" -"co.om\0" -"noheji.aomori.jp\0" -"ferrero\0" -"riobranco.br\0\xe0\xb6\xbd\xe0\xb6\x82\xe0\xb6\x9a\xe0\xb7\x8f\0" -"swiebodzin.pl\0" -"eco\0" -"hjelmeland.no\0" -"ltda\0" -"rieti.it\0secure\0stockholm\0" -"minami.kyoto.jp\0" -"synology-ds.de\0" -"co.pl\0" -"co.pn\0" -"laquila.it\0" -"freebox-os.com\0nerdpol.ovh\0" -"building.museum\0s\xc3\xb8gne.no\0" -"saga.saga.jp\0" -"ah.cn\0tos.it\0co.pw\0" -"bond\0" -"edu\0" -"dtv\0" -"from-ca.com\0" -"kita.kyoto.jp\0" -"salud.bo\0inami.wakayama.jp\0" -"scienceandindustry.museum\0" -"b.bg\0" -"bygland.no\0" -"miura.kanagawa.jp\0" -"\xe5\x85\xac\xe5\x8f\xb8.cn\0oirm.gov.pl\0" -"pyatigorsk.ru\0" -"okawa.fukuoka.jp\0railway.museum\0" -"b.br\0" -"steigen.no\0book\0" -"\xe5\x85\xac\xe5\x8f\xb8.hk\0mikasa.hokkaido.jp\0" -"co.rs\0" -"co.rw\0dvr\0" -"snillfjord.no\0" -"bearalvahki.no\0" -"med.br\0durban\0" -"iwakuni.yamaguchi.jp\0ens.tn\0" -"us.eu.org\0" -"tas.au\0jl.cn\0kumejima.okinawa.jp\0davvenj\xc3\xa1rga.no\0togliatti.su\0" -"wolomin.pl\0" -"sciencecenter.museum\0" -"co.st\0game\0" -"livorno.it\0ishikawa.jp\0" -"co.th\0" -"higashiizumo.shimane.jp\0co.sz\0co.tj\0" -"kawatana.nagasaki.jp\0" -"d.se\0co.tm\0" -"of.by\0\xe0\xb8\xa8\xe0\xb8\xb6\xe0\xb8\x81\xe0\xb8\xa9\xe0\xb8\xb2.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" -"co.ua\0" -"co.tt\0" -"sorocaba.br\0tsuwano.shimane.jp\0" -"karasuyama.tochigi.jp\0" -"co.ug\0" -"co.tz\0sanofi\0" -"oceanographic.museum\0co.uk\0organic\0" -"med.ec\0" -"country\0" -"med.ee\0showa.fukushima.jp\0" -"alfaromeo\0" -"trentino-altoadige.it\0ohira.miyagi.jp\0co.us\0" -"co.ve\0" -"co.vi\0" -"co.uz\0" -"mw.gov.pl\0" -"wiih.gov.pl\0withgoogle.com\0" -"k12.wy.us\0" -"kamikitayama.nara.jp\0" -"suginami.tokyo.jp\0" -"sakaki.nagano.jp\0diskstation.me\0" -"idf.il\0" -"monticello.museum\0" -"\xd1\x80\xd1\x83\xd1\x81\0" -"hamura.tokyo.jp\0hi.us\0" -"naka.hiroshima.jp\0langevag.no\0" -"is-a-teacher.com\0" -"mo-i-rana.no\0stargard.pl\0" -"xj.cn\0" -"jor.br\0kaizuka.osaka.jp\0homelinux.com\0" -"tydal.no\0diskstation.eu\0" -"veterinaire.km\0" -"cc.ga.us\0" -"adm.br\0" -"kusatsu.shiga.jp\0" -"inuyama.aichi.jp\0" -"fuefuki.yamanashi.jp\0" -"dnsalias.com\0nh-serv.co.uk\0" -"ms.gov.br\0freiburg.museum\0couchpotatofries.org\0" -"yame.fukuoka.jp\0" -"al.gov.br\0labor.museum\0" -"oh.us\0exposed\0" -"okazaki.aichi.jp\0" -"aomori.aomori.jp\0berlevag.no\0" -"mysecuritycamera.org\0" -"med.ht\0" -"\xe5\x98\x89\xe9\x87\x8c\0" -"co.za\0" -"otobe.hokkaido.jp\0" -"nesna.no\0movie\0" -"troitsk.su\0" -"knowsitall.info\0" -"lilly\0" -"co.zm\0" -"tajiri.osaka.jp\0" -"sande.m\xc3\xb8re-og-romsdal.no\0hsbc\0icbc\0" -"hol.no\0" -"mt.gov.br\0" -"from-me.org\0" -"bindal.no\0wien\0" -"namegata.ibaraki.jp\0" -"veterinaire.fr\0co.zw\0ca-central-1.elasticbeanstalk.com\0" -"eu-4.evennode.com\0" -"yamanashi.yamanashi.jp\0" -"yasugi.shimane.jp\0bremanger.no\0" -"blogspot.com\0" -"vads\xc3\xb8.no\0is-a-celticsfan.org\0" -"futtsu.chiba.jp\0free\0" -"namie.fukushima.jp\0" -"yamato.kumamoto.jp\0" -"ah.no\0" -"kunigami.okinawa.jp\0" -"froya.no\0nexus\0" -"mytis.ru\0" -"sp.it\0urbinopesaro.it\0cc.vt.us\0" -"clan.rip\0" -"matsudo.chiba.jp\0" -"isa-geek.org\0" -"toyonaka.osaka.jp\0" -"serveftp.com\0" -"ve.it\0" -"scientist.aero\0" -"kijo.miyazaki.jp\0kakinoki.shimane.jp\0dallas.museum\0" -"\xc3\xa5rdal.no\0" -"neustar\0homesecuritymac.com\0" -"h\xc3\xb8yanger.no\0" -"hiphop\0" -"med.ly\0fan\0" -"bhz.br\0" -"eurovision\0" -"go.leg.br\0barsy.support\0" -"onyourside\0" -"misaki.osaka.jp\0" -"hitachinaka.ibaraki.jp\0" -"oshu.iwate.jp\0" -"servegame.org\0" -"nishitosa.kochi.jp\0" -"utah.museum\0kddi\0" -"joyo.kyoto.jp\0" -"benevento.it\0hotmail\0eu-3.evennode.com\0" -"kazuno.akita.jp\0no-ip.co.uk\0" -"karuizawa.nagano.jp\0legnica.pl\0" -"analytics\0" -"westfalen.museum\0" -"ravenna.it\0shimokawa.hokkaido.jp\0" -"of.no\0finance\0" -"esq\0" -"yachimata.chiba.jp\0fujikawaguchiko.yamanashi.jp\0med.om\0" -"bamble.no\0" -"bihoro.hokkaido.jp\0med.pa\0" -"katsuyama.fukui.jp\0" -"poker\0" -"satsumasendai.kagoshima.jp\0wiki\0" -"mil.ac\0shangrila\0" -"busan.kr\0" -"mil.ae\0services.aero\0!city.nagoya.jp\0med.pl\0" -"res.aero\0he.cn\0" -"gbiz\0" -"akagi.shimane.jp\0" -"mil.al\0nt.au\0" -"aurland.no\0" -"agro.bo\0tromsa.no\0solutions\0es.eu.org\0" -"mil.ba\0hakone.kanagawa.jp\0nis.za\0" -"mil.ar\0kuju.oita.jp\0hidaka.wakayama.jp\0" -"civilaviation.aero\0" -"kamakura.kanagawa.jp\0recipes\0schwarz\0" -"k12.ok.us\0eus\0" -"nt.ca\0higashiyoshino.nara.jp\0" -"cim.br\0eun.eg\0meet\0" -"mil.az\0\xe6\x84\x9b\xe7\x9f\xa5.jp\0" -"edogawa.tokyo.jp\0is-with-theband.com\0" -"panerai\0" -"garden\0" -"mil.bo\0b.se\0" -"mazowsze.pl\0" -"tanagura.fukushima.jp\0k12.pr.us\0" -"mil.br\0kyotango.kyoto.jp\0" -"budapest\0" -"poa.br\0ota.tokyo.jp\0\xd1\x81\xd1\x80\xd0\xb1\0" -"lakas.hu\0agdenes.no\0" -"eu-2.evennode.com\0" -"sekigahara.gifu.jp\0" -"mil.by\0" -"egersund.no\0med.sa\0" -"wine\0" -"mil.cl\0" -"cng.br\0med.sd\0" -"mil.cn\0davvenjarga.no\0" -"mil.co\0pruszkow.pl\0" -"laz.it\0" -"dynalias.org\0" -"shaw\0" -"assisi.museum\0" -"j\xc3\xb8rpeland.no\0" -"kochi.kochi.jp\0" -"sn.cn\0" -"gliding.aero\0" -"theater\0" -"epost\0" -"mo\xc3\xa5reke.no\0siellak.no\0homesecuritypc.com\0" -"mil.do\0" -"minamiashigara.kanagawa.jp\0gs.tm.no\0" -"mil.ec\0" -"olbiatempio.it\0" -"mil.eg\0cookingchannel\0" -"shimosuwa.nagano.jp\0omiya.saitama.jp\0" -"otari.nagano.jp\0audnedaln.no\0hughes\0" -"s3-website-ap-northeast-1.amazonaws.com\0" -"def.br\0nayoro.hokkaido.jp\0schweiz.museum\0mykolaiv.ua\0bauhaus\0" -"on-the-web.tv\0" -"guernsey.museum\0gb.net\0" -"sex.hu\0" -"takazaki.miyazaki.jp\0makinohara.shizuoka.jp\0" -"yamanobe.yamagata.jp\0drobak.no\0" -"coffee\0" -"nagai.yamagata.jp\0" -"zoology.museum\0" -"fit\0" -"forum.hu\0nationwide\0" -"pomorze.pl\0ma.us\0" -"kiyosato.hokkaido.jp\0beeldengeluid.museum\0" -"iwaizumi.iwate.jp\0" -"rendalen.no\0cc.id.us\0" -"trd.br\0\xc3\xa5lesund.no\0" -"mil.ge\0iz.hr\0snaase.no\0" -"nv.us\0eu-1.evennode.com\0fantasyleague.cc\0" -"mil.gh\0novara.it\0" -"genova.it\0app.os.stg.fedoraproject.org\0" -"izumisano.osaka.jp\0" -"mihama.wakayama.jp\0" -"udi.br\0" -"architecture.museum\0" -"ono.fukui.jp\0kitagawa.kochi.jp\0" -"bajddar.no\0" -"mil.gt\0" -"ishinomaki.miyagi.jp\0toyota.yamaguchi.jp\0" -"cc.mn.us\0" -"dyndns-office.com\0" -"s3.dualstack.eu-west-1.amazonaws.com\0" -"sa.edu.au\0cog.mi.us\0" -"kunisaki.oita.jp\0textile.museum\0" -"mil.hn\0" -"lo.it\0" -"mil.id\0soo.kagoshima.jp\0" -"carboniaiglesias.it\0" -"rindal.no\0" -"musashimurayama.tokyo.jp\0" -"noto.ishikawa.jp\0cafe\0" -"niki.hokkaido.jp\0\xc3\xa5krehamn.no\0\xd8\xb3\xd9\x88\xd8\xaf\xd8\xa7\xd9\x86\0meme\0" -"hokuryu.hokkaido.jp\0skodje.no\0cologne\0" -"tamakawa.fukushima.jp\0beep.pl\0" -"fly\0""1password.eu\0" -"mil.in\0" -"lib.ct.us\0" -"mil.iq\0" -"drive\0" -"noda.iwate.jp\0" -"isa-geek.com\0" -"\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\x82\xe0\xa6\xb2\xe0\xa6\xbe\0" -"sigdal.no\0" -"hobol.no\0" -"allfinanz\0" -"shia\0" -"aquila.it\0" -"mil.jo\0" -"mine.nu\0" -"lierne.no\0" -"nakatsugawa.gifu.jp\0est-a-la-maison.com\0" -"mil.kg\0" -"vc.it\0" -"menu\0" -"horokanai.hokkaido.jp\0khakassia.su\0" -"ribeirao.br\0mil.km\0" -"mil.kr\0" -"foo\0" -"niikappu.hokkaido.jp\0money.museum\0" -"larvik.no\0" -"niigata.jp\0agric.za\0" -"mil.kz\0" -"ina.nagano.jp\0" -"fox\0" -"higashiagatsuma.gunma.jp\0" -"k12.ak.us\0consulting\0" -"*.sapporo.jp\0" -"azurewebsites.net\0" -"hokkaido.jp\0arboretum.museum\0from-md.com\0chirurgiens-dentistes-en-france.fr\0" -"ostrowwlkp.pl\0" -"niimi.okayama.jp\0" -"nagahama.shiga.jp\0mil.lv\0nativeamerican.museum\0sex.pl\0" -"torino.it\0mil.mg\0" -"firm.ht\0oarai.ibaraki.jp\0" -"9.bg\0berkeley.museum\0" -"gal\0fi.eu.org\0" -"\xe5\xb2\xa9\xe6\x89\x8b.jp\0shunan.yamaguchi.jp\0" -"firm.in\0ishikawa.fukushima.jp\0" -"gap\0" -"\xe0\xa4\xb8\xe0\xa4\x82\xe0\xa4\x97\xe0\xa4\xa0\xe0\xa4\xa8\0homelinux.net\0" -"mil.mv\0nt.no\0from-ri.com\0" -"mil.ng\0" -"asakawa.fukushima.jp\0mil.my\0mil.ni\0""1password.ca\0*.compute-1.amazonaws.com\0" -"mil.mz\0" -"fukusaki.hyogo.jp\0" -"mil.no\0" -"frl\0" -"kouzushima.tokyo.jp\0" -"dental\0" -"go.dyndns.org\0" -"kawakita.ishikawa.jp\0us.na\0" -"baseball.museum\0" -"gs.fm.no\0expert\0webhop.net\0" -"ambulance.aero\0" -"gs.cn\0mil.nz\0cloudns.pro\0" -"enebakk.no\0\xe3\x83\x95\xe3\x82\xa1\xe3\x83\x83\xe3\x82\xb7\xe3\x83\xa7\xe3\x83\xb3\0" -"fauske.no\0\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" -"nagara.chiba.jp\0" -"call\0" -"firm.co\0cityeats\0" -"res.in\0mil.pe\0" -"v\xc3\xa1rgg\xc3\xa1t.no\0security\0" -"ontario.museum\0telekommunikation.museum\0" -"mil.ph\0" -"mitou.yamaguchi.jp\0" -"stalbans.museum\0\xe0\xb8\xa3\xe0\xb8\xb1\xe0\xb8\x90\xe0\xb8\x9a\xe0\xb8\xb2\xe0\xb8\xa5.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" -"mil.pl\0" -"fujishiro.ibaraki.jp\0" -"firm.dk\0gitlab.io\0" -"mil.qa\0" -"samegawa.fukushima.jp\0gdn\0s3-website.eu-west-3.amazonaws.com\0" -"fujixerox\0" -"camp\0" -"gea\0linde\0" -"obu.aichi.jp\0ck.ua\0ftr\0" -"hichiso.gifu.jp\0t3l3p0rt.net\0" -"chigasaki.kanagawa.jp\0salat.no\0mil.py\0" -"kumano.hiroshima.jp\0" -"shop\0" -"k12.sc.us\0" -"hanyu.saitama.jp\0" -"fun\0dyndns-ip.com\0dvrdns.org\0byen.site\0" -"sauherad.no\0sorum.no\0show\0" -"nt.ro\0servequake.com\0" -"psi.br\0" -"kvinnherad.no\0" -"yokote.akita.jp\0" -"ecologia.bo\0newmexico.museum\0" -"mil.ru\0" -"digital\0network\0" -"mil.rw\0" -"mil.sh\0cc.as.us\0" -"sites.static.land\0" -"saitama.saitama.jp\0gu.us\0blogspot.vn\0" -"mc.eu.org\0" -"portlligat.museum\0" -"lig.it\0nakayama.yamagata.jp\0" -"mel\xc3\xb8y.no\0" -"mil.st\0" -"salangen.no\0whoswho\0" -"teaches-yoga.com\0" -"od.ua\0" -"mil.sy\0" -"mil.tj\0luxe\0" -"ci.it\0" -"mil.tm\0" -"ad.jp\0tottori.tottori.jp\0piaget\0" -"utsunomiya.tochigi.jp\0mil.to\0" -"kawanishi.hyogo.jp\0bruxelles.museum\0sorfold.no\0" -"mil.tr\0" -"rotorcraft.aero\0lubin.pl\0" -"iwama.ibaraki.jp\0porsanger.no\0" -"en.it\0living.museum\0" -"mil.tw\0" -"cherkasy.ua\0internet-dns.de\0" -"hamaroy.no\0care\0static-access.net\0" -"yoro.gifu.jp\0mil.tz\0" -"shimonoseki.yamaguchi.jp\0depot.museum\0" -"shibata.miyagi.jp\0" -"coloradoplateau.museum\0fyi\0lt.eu.org\0" -"shisui.chiba.jp\0" -"sucks\0" -"mil.vc\0" -"mil.ve\0casa\0" -"cars\0" -"giessen.museum\0" -"port.fr\0store.nf\0mil.uy\0case\0" -"hioki.kagoshima.jp\0suzuka.mie.jp\0" -"cash\0" -"trustee.museum\0" -"funagata.yamagata.jp\0" -"lea\xc5\x8bgaviika.no\0" -"qsl.br\0" -"finearts.museum\0muenster.museum\0blogspot.re\0js.org\0" -"hemnes.no\0cc.pa.us\0" -"tanohata.iwate.jp\0" -"nesseby.no\0" -"agrinet.tn\0" -"hotel.tz\0" -"aramco\0" -"agro.pl\0blogspot.ro\0" -"in-addr.arpa\0wakasa.tottori.jp\0\xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0\0" -"moss.no\0" -"ninomiya.kanagawa.jp\0is-a-liberal.com\0blogspot.rs\0" -"folkebibl.no\0\xd8\xa7\xd8\xa8\xd9\x88\xd8\xb8\xd8\xa8\xd9\x8a\0" -"blogspot.ru\0blogspot.se\0" -"lind\xc3\xa5s.no\0" -"blogspot.sg\0" -"blogspot.si\0" -"shingu.wakayama.jp\0" -"gle\0\xe5\xb9\xbf\xe4\xb8\x9c\0blogspot.sk\0" -"movimiento.bo\0blogspot.sn\0" -"aseral.no\0" -"niihama.ehime.jp\0" -"theatre\0" -"odda.no\0" -"halloffame.museum\0blogspot.td\0" -"stavanger.no\0" -"karatsu.saga.jp\0" -"lib.il.us\0" -"uchinada.ishikawa.jp\0myftp.org\0" -"va.it\0" -"yamato.fukushima.jp\0science.museum\0express\0" -"hidaka.kochi.jp\0mil.za\0" -"tomisato.chiba.jp\0olayangroup\0" -"arao.kumamoto.jp\0gmo\0" -"zhytomyr.ua\0" -"lacaixa\0blogspot.tw\0blogspot.ug\0" -"firm.ve\0" -"hirado.nagasaki.jp\0" -"gmx\0" -"notaires.km\0steiermark.museum\0mil.zm\0" -"blogspot.mr\0" -"union.aero\0ab.ca\0ryugasaki.ibaraki.jp\0warman\0" -"kommunalforbund.se\0" -"blogspot.mx\0" -"mil.zw\0s3-ap-northeast-1.amazonaws.com\0blogspot.my\0" -"nakatombetsu.hokkaido.jp\0radoy.no\0" -"kv\xc3\xa6""fjord.no\0" -"izumi.kagoshima.jp\0tome.miyagi.jp\0theworkpc.com\0blogspot.nl\0" -"blogspot.no\0" -"7.bg\0toyohashi.aichi.jp\0" -"\xc3\xa1laheadju.no\0" -"goo\0" -"gop\0homelink.one\0" -"jpmorgan\0" -"australia.museum\0got\0" -"gov\0cieszyn.pl\0" -"riodejaneiro.museum\0" -"zaporizhzhia.ua\0" -"ena.gifu.jp\0hammerfest.no\0" -"wada.nagano.jp\0" -"blogspot.pe\0" -"tokushima.tokushima.jp\0" -"transporte.bo\0austevoll.no\0int.eu.org\0" -"hidaka.saitama.jp\0" -"nissan\0" -"house\0swatch\0" -"udono.mie.jp\0" -"ha.cn\0" -"hirokawa.fukuoka.jp\0blogspot.qa\0" -"ieee\0" -"iyo.ehime.jp\0alaheadju.no\0blogspot.pt\0" -"nissay\0" -"kishiwada.osaka.jp\0laakesvuemie.no\0\xd1\x83\xd0\xba\xd1\x80\0" -"va.no\0silk\0vista\0" -"store.ve\0dyndns-blog.com\0lima-city.de\0" -"hotel.lk\0" -"k12.mo.us\0" -"kamoenai.hokkaido.jp\0realtor\0" -"teshikaga.hokkaido.jp\0" -"blogspot.is\0" -"cloudns.org\0blogspot.it\0" -"hbo\0" -"firm.ro\0" -"daisen.akita.jp\0" -"kuromatsunai.hokkaido.jp\0" -"zlg.br\0\xeb\x8b\xb7\xec\xbb\xb4\0" -"*.kawasaki.jp\0lewismiller.museum\0sina\0" -"mugi.tokushima.jp\0blogspot.jp\0" -"\xe5\x95\x86\xe5\xba\x97\0" -"kamisu.ibaraki.jp\0ulsan.kr\0" -"ogawara.miyagi.jp\0" -"enna.it\0" -"\xe3\x82\xaf\xe3\x83\xa9\xe3\x82\xa6\xe3\x83\x89\0lima-city.at\0" -"aquarium.museum\0trolley.museum\0" -"creation.museum\0public.museum\0ushuaia.museum\0swiftcover\0" -"gotdns.ch\0" -"gamvik.no\0" -"surgery\0isa-geek.net\0" -"inagawa.hyogo.jp\0blogspot.kr\0" -"nishihara.okinawa.jp\0" -"honbetsu.hokkaido.jp\0" -"omega\0" -"lukow.pl\0blogspot.li\0" -"ninohe.iwate.jp\0hachijo.tokyo.jp\0naturalhistory.museum\0" -"lima-city.ch\0" -"group.aero\0onojo.fukuoka.jp\0" -"ipifony.net\0" -"blogspot.lt\0blogspot.md\0" -"blogspot.lu\0" -"ozu.ehime.jp\0" -"togakushi.nagano.jp\0" -"aerobatic.aero\0enonic.io\0blogspot.mk\0" -"suzaka.nagano.jp\0health.museum\0" -"firm.nf\0lyngen.no\0" -"from-tn.com\0" -"citadel\0" -"her\xc3\xb8y.nordland.no\0" -"circle\0" -"voss.no\0store.ro\0\xe6\x9c\xba\xe6\x9e\x84\0" -"hotel.hu\0hirono.fukushima.jp\0" -"channelsdvr.net\0" -"blogspot.fi\0nsupdate.info\0" -"kami.miyagi.jp\0" -"grajewo.pl\0" -"valley.museum\0mk.eu.org\0" -"blogspot.fr\0" -"yamanakako.yamanashi.jp\0" -"gsm.pl\0" -"database.museum\0embaixada.st\0store.st\0aarp\0" -"edu.ac\0" -"mashiko.tochigi.jp\0" -"is-very-nice.org\0" -"edu.af\0" -"wegrow.pl\0" -"godo.gifu.jp\0" -"agematsu.nagano.jp\0" -"blogspot.gr\0" -"edu.al\0shoes\0s3-ap-southeast-1.amazonaws.com\0" -"nextdirect\0" -"edu.ba\0vefsn.no\0" -"edu.ar\0edu.bb\0chofu.tokyo.jp\0" -"hof.no\0" -"\xe0\xa8\xad\xe0\xa8\xbe\xe0\xa8\xb0\xe0\xa8\xa4\0cbre\0blogspot.hk\0" -"edu.au\0" -"skaun.no\0va.us\0" -"hirara.okinawa.jp\0" -"edu.bh\0" -"edu.bi\0kaneyama.fukushima.jp\0" -"edu.az\0" -"samnanger.no\0blogspot.hr\0" -"site\0" -"edu.bm\0" -"blogspot.hu\0blogspot.ie\0" -"groundhandling.aero\0edu.bo\0" -"wv.us\0" -"farmequipment.museum\0" -"edu.br\0" -"edu.bs\0youtube\0" -"edu.bt\0" -"hiv\0" -"caserta.it\0pu.it\0futbol\0" -"blogspot.in\0" -"edu.ci\0my-router.de\0" -"edu.bz\0fujisato.akita.jp\0granvin.no\0blogspot.ba\0mypsx.net\0" -"edu.cn\0blogspot.be\0" -"edu.co\0" -"blogspot.bg\0" -"tsukuba.ibaraki.jp\0" -"mishima.shizuoka.jp\0blogspot.bj\0" -"sardegna.it\0" -"amusement.aero\0edu.cu\0kozagawa.wakayama.jp\0" -"\xe6\x94\xbf\xe5\xba\x9c.hk\0izumozaki.niigata.jp\0" -"edu.cw\0" -"lu.eu.org\0me.eu.org\0" -"nishiaizu.fukushima.jp\0namerikawa.toyama.jp\0" -"blogspot.ca\0" -"erimo.hokkaido.jp\0dscloud.mobi\0" -"edu.dm\0" -"togura.nagano.jp\0" -"edu.do\0trieste.it\0abbott\0blogspot.cf\0" -"marugame.kagawa.jp\0" -"blogspot.ch\0" -"edu.ec\0como.it\0hkt\0" -"ditchyourip.com\0" -"edu.ee\0wake.okayama.jp\0blogspot.cl\0" -"edu.eg\0randaberg.no\0" -"wios.gov.pl\0" -"ha.no\0lib.md.us\0" -"edu.dz\0ogano.saitama.jp\0" -"gorizia.it\0" -"blogspot.de\0" -"blogspot.cv\0" -"powiat.pl\0" -"edu.es\0heroy.nordland.no\0blogspot.cz\0" -"edu.et\0blogspot.dk\0" -"biratori.hokkaido.jp\0" -"moskenes.no\0" -"tsukigata.hokkaido.jp\0" -"lv.eu.org\0" -"val-d-aosta.it\0jewishart.museum\0" -"fujioka.gunma.jp\0schoenbrunn.museum\0" -"5.bg\0" -"sassari.it\0cloud.fedoraproject.org\0" -"us.org\0" -"trentinosud-tirol.it\0" -"her\xc3\xb8y.m\xc3\xb8re-og-romsdal.no\0" -"yonaguni.okinawa.jp\0homelinux.org\0" -"aoki.nagano.jp\0" -"edu.ge\0" -"it.ao\0fedex\0" -"kariwa.niigata.jp\0sauda.no\0" -"edu.gh\0" -"edu.gi\0" -"nomi.ishikawa.jp\0" -"edu.gl\0" -"\xe5\xa4\xa7\xe6\x8b\xbf\0" -"edu.gn\0higashiyamato.tokyo.jp\0" -"mihara.kochi.jp\0washingtondc.museum\0" -"edu.gp\0" -"edu.gr\0" -"kumatori.osaka.jp\0\xe9\x80\x9a\xe8\xb2\xa9\0" -"edu.gt\0" -"imb.br\0" -"go.ci\0" -"edu.gy\0" -"my-vigor.de\0" -"airport.aero\0edu.hk\0rnu.tn\0" -"troandin.no\0" -"edu.hn\0murakami.niigata.jp\0" -"*.nom.br\0go.cr\0" -"equipment.aero\0durham.museum\0" -"coop.ht\0hot\0" -"edu.ht\0" -"how\0" -"endofinternet.net\0" -"b\xc3\xb8.nordland.no\0here-for-more.info\0" -"stcgroup\0" -"k12.ne.us\0" -"shimotsuke.tochigi.jp\0pinb.gov.pl\0" -"scrapper-site.net\0ddnss.de\0" -"edu.in\0sciencehistory.museum\0" -"motosu.gifu.jp\0" -"s3-us-west-1.amazonaws.com\0" -"edu.iq\0" -"edu.is\0" -"edu.it\0" -"aguni.okinawa.jp\0philips\0" -"qc.ca\0" -"sherbrooke.museum\0able\0" -"bnpparibas\0" -"shimizu.shizuoka.jp\0" -"ivanovo.su\0" -"palmas.br\0blogspot.ae\0" -"edu.jo\0histoire.museum\0" -"coastaldefence.museum\0" -"coop.br\0rnrt.tn\0" -"inawashiro.fukushima.jp\0kids.museum\0" -"\xe5\xb2\x90\xe9\x98\x9c.jp\0" -"hopto.me\0" -"\xe6\x84\x9b\xe5\xaa\x9b.jp\0r\xc3\xb8st.no\0blogspot.al\0" -"mallorca.museum\0farsund.no\0blogspot.am\0" -"edu.kg\0and.museum\0" -"basel.museum\0" -"edu.ki\0k12.tn.us\0" -"tsubata.ishikawa.jp\0" -"gojome.akita.jp\0ris\xc3\xb8r.no\0ibm\0" -"sh.cn\0edu.km\0" -"edu.kn\0" -"aga.niigata.jp\0" -"edu.kp\0study\0" -"edu.la\0" -"edu.lb\0liaison\0wedding\0" -"edu.lc\0aviation.museum\0k12.wa.us\0" -"ice\0" -"\xd9\x81\xd9\x84\xd8\xb3\xd8\xb7\xd9\x8a\xd9\x86\0rhcloud.com\0" -"pup.gov.pl\0" -"edu.ky\0" -"edu.kz\0" -"anpachi.gifu.jp\0kitakami.iwate.jp\0edu.lk\0grandrapids.museum\0b\xc3\xa5""d\xc3\xa5""ddj\xc3\xa5.no\0edu.krd\0" -"takata.fukuoka.jp\0" -"sandiego.museum\0\xd9\x83\xd8\xa7\xd8\xab\xd9\x88\xd9\x84\xd9\x8a\xd9\x83\0" -"edu.lr\0bargains\0" -"cc.ct.us\0" -"city.hu\0icu\0de.cool\0" -"edu.me\0" -"taketa.oita.jp\0edu.lv\0" -"edu.mg\0" -"chirurgiens-dentistes.fr\0edu.ly\0" -"edu.mk\0" -"edu.ml\0" -"ce.it\0" -"ukiha.fukuoka.jp\0edu.mn\0" -"osakikamijima.hiroshima.jp\0edu.mo\0" -"maintenance.aero\0go.id\0" -"edu.ms\0" -"edu.mt\0" -"ltd.co.im\0edu.mv\0" -"edu.mw\0edu.ng\0" -"edu.mx\0kr.eu.org\0" -"edu.my\0edu.ni\0" -"edu.mz\0l\xc3\xb8ten.no\0kyoto\0" -"minamiyamashiro.kyoto.jp\0" -"padova.it\0" -"andebu.no\0" -"i234.me\0" -"store.bb\0" -"go.it\0" -"bolivia.bo\0edu.nr\0" -"*.0emm.com\0" -"flynnhub.com\0" -"oji.nara.jp\0" -"ifm\0" -"go.jp\0edu.om\0" -"creditunion\0" -"edu.pa\0" -"is-very-sweet.org\0" -"zippo\0" -"li.it\0yoichi.hokkaido.jp\0warabi.saitama.jp\0edu.pe\0" -"nagasaki.jp\0settlement.museum\0edu.pf\0" -"edu.ph\0" -"blogdns.com\0" -"flynnhosting.net\0" -"edu.pk\0" -"edu.pl\0" -"edu.pn\0compare\0" -"go.kr\0" -"n\xc3\xa6r\xc3\xb8y.no\0edu.qa\0" -"edu.pr\0" -"chikugo.fukuoka.jp\0and\xc3\xb8y.no\0zarow.pl\0edu.ps\0" -"\xe9\xb9\xbf\xe5\x85\x90\xe5\xb3\xb6.jp\0edu.pt\0" -"nishiazai.shiga.jp\0" -"webcam\0" -"edu.py\0store.dk\0" -"bardu.no\0" -"\xd8\xb9\xd8\xb1\xd8\xa7\xd9\x82\0" -"ichikawa.hyogo.jp\0marker.no\0fund\0*.compute.amazonaws.com\0" -"ntr.br\0" -"la-spezia.it\0" -"landrover\0" -"smart\0" -"bu.no\0" -"from-mn.com\0" -"microsoft\0" -"yukuhashi.fukuoka.jp\0" -"notaires.fr\0gent\0" -"toyooka.hyogo.jp\0traeumtgerade.de\0" -"birthplace.museum\0es.leg.br\0" -"judaica.museum\0edu.sa\0" -"indiana.museum\0edu.sb\0lamborghini\0" -"tanabe.wakayama.jp\0edu.rs\0edu.sc\0casacam.net\0" -"barcelona.museum\0edu.sd\0amfam\0" -"edu.ru\0" -"oirase.aomori.jp\0email\0\xe6\x97\xb6\xe5\xb0\x9a\0" -"loten.no\0sn\xc3\xa5""ase.no\0edu.rw\0edu.sg\0canon\0" -"wajiki.tokushima.jp\0" -"global\0" -"nonoichi.ishikawa.jp\0edu.sl\0ath.cx\0" -"eng.br\0" -"fortal.br\0ambulance.museum\0edu.sn\0forgot.his.name\0" -"psse.gov.pl\0" -"takehara.hiroshima.jp\0kamitonda.wakayama.jp\0edu.st\0" -"edu.sv\0app.os.fedoraproject.org\0" -"arendal.no\0" -"edu.sy\0" -"edu.tj\0" -"toyoake.aichi.jp\0" -"edu.tm\0from-va.com\0" -"jampa.br\0edu.to\0" -"beppu.oita.jp\0" -"3.bg\0edu.ua\0" -"tonaki.okinawa.jp\0edu.tr\0" -"edu.tt\0" -"shibukawa.gunma.jp\0asahi.yamagata.jp\0edu.tw\0duck\0" -"wanouchi.gifu.jp\0" -"kunitomi.miyazaki.jp\0" -"company\0" -"edu.vc\0" -"showa.yamanashi.jp\0go.pw\0" -"edu.ve\0syno-ds.de\0" -"beskidy.pl\0careers\0" -"raholt.no\0edu.uy\0" -"mail.pl\0przeworsk.pl\0k12.ia.us\0" -"s\xc3\xb8r-fron.no\0mazury.pl\0" -"bjerkreim.no\0politie\0" -"rns.tn\0edu.vn\0*.alces.network\0" -"jorpeland.no\0" -"sm\xc3\xb8la.no\0" -"columbus.museum\0" -"edu.vu\0george\0" -"gs.hl.no\0ing\0" -"fujisawa.iwate.jp\0" -"ink\0" -"\xe5\xbe\xb3\xe5\xb3\xb6.jp\0" -"elblag.pl\0k12.ms.us\0k12.nc.us\0" -"nl.ca\0hadsel.no\0" -"kasamatsu.gifu.jp\0" -"asakuchi.okayama.jp\0" -"int\0edu.ws\0" -"fuchu.tokyo.jp\0skin\0" -"isesaki.gunma.jp\0higashiyodogawa.osaka.jp\0lamer\0" -"vestre-slidre.no\0" -"aisai.aichi.jp\0shiranuka.hokkaido.jp\0nose.osaka.jp\0space-to-rent.com\0" -"bas.it\0hamburg\0" -"kagamino.okayama.jp\0" -"iizuna.nagano.jp\0leangaviika.no\0" -"doshi.yamanashi.jp\0" -"leirfjord.no\0" -"go.th\0s3-website-us-west-1.amazonaws.com\0no-ip.info\0" -"go.tj\0" -"kumamoto.jp\0indian.museum\0" -"\xe4\xbd\x9b\xe5\xb1\xb1\0" -"gamo.shiga.jp\0" -"psc.br\0wales.museum\0" -"edu.za\0" -"hakui.ishikawa.jp\0" -"go.ug\0" -"dnshome.de\0" -"go.tz\0ericsson\0" -"cri.br\0" -"nankoku.kochi.jp\0" -"taki.mie.jp\0kitagawa.miyazaki.jp\0trogstad.no\0" -"edu.zm\0" -"tgory.pl\0" -"asaka.saitama.jp\0" -"wiw.gov.pl\0\xe6\x96\xb0\xe5\x8a\xa0\xe5\x9d\xa1\0is-a-hunter.com\0" -"nikaho.akita.jp\0" -"higashine.yamagata.jp\0" -"hayashima.okayama.jp\0" -"copenhagen.museum\0" -"bs.it\0" -"messina.it\0jcb\0" -"arkhangelsk.su\0" -"ky.us\0" -"chase\0" -"ciencia.bo\0" -"myftp.biz\0" -"giske.no\0" -"costume.museum\0cable-modem.org\0" -"suwa.nagano.jp\0" -"jcp\0" -"epson\0" -"b\xc3\xa1hccavuotna.no\0coop.tt\0ist\0mangyshlak.su\0" -"repair\0" -"viterbo.it\0" -"family.museum\0" -"hamatonbetsu.hokkaido.jp\0cruises\0synology.me\0" -"juegos\0" -"perso.ht\0birdart.museum\0" -"trafficplex.cloud\0" -"lipsy\0" -"coop.mv\0itv\0" -"kodaira.tokyo.jp\0coop.mw\0taipei\0" -"cc.ok.us\0ae.org\0for-the.biz\0" -"oi.kanagawa.jp\0cisco\0" -"sande.more-og-romsdal.no\0\xe0\xb8\x84\xe0\xb8\xad\xe0\xb8\xa1\0" -"ishikari.hokkaido.jp\0" -"padua.it\0" -"cody.museum\0" -"lg.jp\0" -"sango.nara.jp\0adac\0" -"atsugi.kanagawa.jp\0" -"fujinomiya.shizuoka.jp\0" -"n\xc3\xb8tter\xc3\xb8y.no\0" -"nsw.edu.au\0" -"verbania.it\0cc.na\0" -"noshiro.akita.jp\0" -"matsuyama.ehime.jp\0iwc\0" -"oto.fukuoka.jp\0" -"yanaizu.fukushima.jp\0" -"kashiwazaki.niigata.jp\0" -"kakuda.miyagi.jp\0klepp.no\0" -"fukuroi.shizuoka.jp\0" -"oum.gov.pl\0definima.io\0" -"tottori.jp\0" -"arna.no\0duns\0" -"quicksytes.com\0" -"computer\0" -"temp-dns.com\0" -"ballangen.no\0" -"dyndns-web.com\0is-an-actor.com\0" -"coop.py\0" -"progressive\0" -"shintomi.miyazaki.jp\0" -"ogi.saga.jp\0namdalseid.no\0" -"chichibu.saitama.jp\0" -"bydgoszcz.pl\0" -"mansion.museum\0" -"ichinomiya.chiba.jp\0wanggou\0" -"1337.pictures\0" -"otsu.shiga.jp\0" -"filatelia.museum\0" -"jio\0" -"kunstsammlung.museum\0spjelkavik.no\0" -"shiriuchi.hokkaido.jp\0" -"cargo.aero\0dvag\0" -"1.bg\0jeju.kr\0" -"higashiizu.shizuoka.jp\0playstation\0" -"\xe4\xb8\x89\xe9\x87\x8d.jp\0" -"telecity\0" -"beta.bounty-full.com\0" -"coop.km\0" -"nl.no\0" -"kasuga.hyogo.jp\0" -"is-a-nascarfan.com\0" -"rauma.no\0homeoffice.gov.uk\0no-ip.biz\0" -"brand.se\0" -"lib.ut.us\0" -"oppdal.no\0" -"joinville.br\0ilawa.pl\0" -"starachowice.pl\0" -"iwata.shizuoka.jp\0chtr.k12.ma.us\0" -"sci.eg\0bungotakada.oita.jp\0sf.no\0clothing\0" -"jlc\0" -"ginowan.okinawa.jp\0" -"living\0s3.dualstack.eu-west-2.amazonaws.com\0" -"brussels.museum\0nord-fron.no\0komatsu\0" -"preservation.museum\0" -"kepno.pl\0" -"macerata.it\0nishiawakura.okayama.jp\0design\0" -"jll\0" -"restaurant\0" -"woodside\0\xd0\xb4\xd0\xb5\xd1\x82\xd0\xb8\0" -"kashiwara.osaka.jp\0" -"badaddja.no\0" -"clinique\0" -"tsuiki.fukuoka.jp\0" -"hangout\0cc.ua\0" -"arezzo.it\0" -"sampa.br\0jmp\0" -"cri.nz\0" -"fin.ec\0gausdal.no\0" -"\xd8\xb3\xd9\x88\xd8\xb1\xd9\x8a\xd8\xa7\0" -"\xd8\xb3\xd9\x88\xd8\xb1\xd9\x8a\xd8\xa9\0" -"jnj\0mini\0" -"delaware.museum\0" -"culturalcenter.museum\0" -"higashishirakawa.gifu.jp\0" -"filegear.me\0" -"sd.cn\0vao.it\0privatizehealthinsurance.net\0myfirewall.org\0" -"mint\0devices.resinstaging.io\0" -"schlesisches.museum\0" -"chuo.chiba.jp\0nishiokoppe.hokkaido.jp\0" -"adygeya.su\0" -"asker.no\0" -"olawa.pl\0office-on-the.net\0" -"fyresdal.no\0lapy.pl\0ggee\0" -"cc.ak.us\0" -"tana.no\0" -"paris.museum\0" -"hu.com\0" -"aurskog-h\xc3\xb8land.no\0jot\0" -"from-wv.com\0" -"lg.ua\0" -"lincoln.museum\0joy\0" -"minokamo.gifu.jp\0" -"travelchannel\0" -"toyota.aichi.jp\0" -"shouji\0" -"fujikawa.yamanashi.jp\0" -"ca.it\0" -"shichikashuku.miyagi.jp\0" -"tomakomai.hokkaido.jp\0" -"baidu\0" -"turystyka.pl\0" -"m\xc3\xa1tta-v\xc3\xa1rjjat.no\0" -"nieruchomosci.pl\0" -"diamonds\0" -"yoga\0" -"mifune.kumamoto.jp\0pioneer\0" -"kawakami.nara.jp\0\xe3\x82\xb0\xe3\x83\xbc\xe3\x82\xb0\xe3\x83\xab\0" -"tunes\0" -"rv.ua\0" -"cloudns.info\0" -"law.pro\0" -"from-hi.com\0" -"adygeya.ru\0webhop.me\0" -"journal.aero\0" -"gliwice.pl\0" -"gru.br\0" -"bonn.museum\0cc.md.us\0" -"motorcycles\0" -"minamata.kumamoto.jp\0" -"vindafjord.no\0" -"le.it\0cc.ny.us\0" -"not.br\0" -"aparecida.br\0kitaaiki.nagano.jp\0" -"buzen.fukuoka.jp\0" -"yamashina.kyoto.jp\0endofinternet.org\0" -"s3-website.eu-west-2.amazonaws.com\0" -"sp.gov.br\0bananarepublic\0" -"po.it\0nagasaki.nagasaki.jp\0asahi.toyama.jp\0" -"ca.na\0" -"lucerne.museum\0cloud.metacentrum.cz\0" -"itami.hyogo.jp\0taishi.hyogo.jp\0yoshimi.saitama.jp\0" -"artsandcrafts.museum\0bomlo.no\0" -"yoshida.shizuoka.jp\0chungbuk.kr\0\xeb\x8b\xb7\xeb\x84\xb7\0" -"traniandriabarletta.it\0pfizer\0nov.ru\0" -"omotego.fukushima.jp\0" -"cloudns.club\0" -"miyoshi.hiroshima.jp\0" -"evje-og-hornnes.no\0" -"kfh\0" -"ullensvang.no\0" -"sandoy.no\0" -"iida.nagano.jp\0kumagaya.saitama.jp\0" -"miasta.pl\0" -"\xe9\x9b\xbb\xe8\xa8\x8a\xe7\x9b\x88\xe7\xa7\x91\0" -"dyndns.org\0" -"nov.su\0" -"\xe7\x82\xb9\xe7\x9c\x8b\0" -"community.museum\0" -"ed.ao\0perso.sn\0from-az.net\0" -"air-surveillance.aero\0" -"fidelity\0\xe4\xb8\xad\xe4\xbf\xa1\0" -"localhistory.museum\0" -"catering.aero\0" -"yoshino.nara.jp\0" -"so.gov.pl\0" -"valleeaoste.it\0" -"perso.tn\0" -"hara.nagano.jp\0" -"mysecuritycamera.com\0" -"toho.fukuoka.jp\0kia\0is-into-anime.com\0" -"hekinan.aichi.jp\0" -"honeywell\0" -"maceio.br\0" -"ed.ci\0us-east-2.elasticbeanstalk.com\0" -"futaba.fukushima.jp\0" -"siljan.no\0" -"y.bg\0" -"kim\0" -"cern\0" -"ed.cr\0otsuki.kochi.jp\0" -"trust.museum\0" -"trentino-a-adige.it\0" -"shiki.saitama.jp\0" -"amsterdam\0cust.disrec.thingdust.io\0" -"lotte\0" -"gmina.pl\0cloudapp.net\0" -"emilia-romagna.it\0urakawa.hokkaido.jp\0s3-eu-central-1.amazonaws.com\0" -"mitake.gifu.jp\0" -"reliance\0" -"songdalen.no\0" -"moriyama.shiga.jp\0" -"citic\0" -"hisayama.fukuoka.jp\0hanamaki.iwate.jp\0lotto\0" -"field.museum\0" -"szex.hu\0" -"issmarterthanyou.com\0" -"kawahara.tottori.jp\0oystre-slidre.no\0travelersinsurance\0" -"friuli-vegiulia.it\0sanjo.niigata.jp\0cuisinella\0" -"alvdal.no\0" -"urawa.saitama.jp\0" -"yamaga.kumamoto.jp\0dyn-ip24.de\0" -"sannohe.aomori.jp\0vision\0" -"sakaiminato.tottori.jp\0" -"unnan.shimane.jp\0s3.dualstack.ca-central-1.amazonaws.com\0" -"pro.az\0" -"teo.br\0" -"zushi.kanagawa.jp\0" -"batsfjord.no\0ca.us\0k12.tx.us\0is-a-techie.com\0" -"ebina.kanagawa.jp\0" -"passenger-association.aero\0" -"\xe5\x8d\x83\xe8\x91\x89.jp\0" -"pro.br\0sellsyourhome.org\0" -"unj\xc3\xa1rga.no\0" -"grosseto.it\0juniper\0" -"barclaycard\0" -"navoi.su\0" -"ibaraki.osaka.jp\0lundbeck\0" -"vantaa.museum\0" -"nedre-eiker.no\0fin.tn\0" -"fed.us\0boots\0sandcats.io\0" -"tw.cn\0lavangen.no\0" -"mup.gov.pl\0" -"nowaruda.pl\0" -"otaru.hokkaido.jp\0" -"is-an-artist.com\0" -"hitachi.ibaraki.jp\0" -"tachiarai.fukuoka.jp\0matsubara.osaka.jp\0" -"gs.vf.no\0" -"savannahga.museum\0" -"pro.cy\0" -"za.bz\0" -"s3-ap-northeast-2.amazonaws.com\0" -"bo.it\0oyodo.nara.jp\0" -"pro.ec\0" -"essex.museum\0" -"bristol.museum\0" -"fr\xc3\xa6na.no\0gallo\0" -"kanonji.kagawa.jp\0" -"glade\0" -"kumano.mie.jp\0nj.us\0support\0" -"tur.ar\0" -"whaling.museum\0tokyo\0yahoo\0" -"kembuchi.hokkaido.jp\0localhost.daplie.me\0" -"alpha-myqnapcloud.com\0" -"jus.br\0ed.jp\0" -"kpn\0mitsubishi\0" -"bern.museum\0\xe8\xb0\xb7\xe6\xad\x8c\0" -"yamatokoriyama.nara.jp\0" -"luxembourg.museum\0" -"tur.br\0" -"emiliaromagna.it\0ashoro.hokkaido.jp\0otofuke.hokkaido.jp\0" -"sd.us\0s3-website-sa-east-1.amazonaws.com\0jp.eu.org\0" -"lc.it\0" -"kiyosu.aichi.jp\0" -"karm\xc3\xb8y.no\0" -"krd\0lat\0" -"etajima.hiroshima.jp\0" -"nasushiobara.tochigi.jp\0law\0" -"sr.gov.pl\0" -"buzz\0" -"bill.museum\0" -"\xe3\x82\xb9\xe3\x83\x88\xe3\x82\xa2\0" -"friuliv-giulia.it\0" -"church\0realty\0" -"kanegasaki.iwate.jp\0kimino.wakayama.jp\0" -"iheya.okinawa.jp\0" -"chikuho.fukuoka.jp\0" -"rivne.ua\0" -"pro.ht\0" -"*.s5y.io\0" -"amakusa.kumamoto.jp\0" -"saroma.hokkaido.jp\0" -"mesaverde.museum\0" -"kv\xc3\xa6nangen.no\0" -"assabu.hokkaido.jp\0heguri.nara.jp\0reg.dk\0" -"higashikagura.hokkaido.jp\0moroyama.saitama.jp\0bronnoysund.no\0" -"tempioolbia.it\0sel.no\0cloud.goog\0" -"shiroishi.saga.jp\0" -"freetls.fastly.net\0" -"kawaue.gifu.jp\0" -"in.na\0" -"yusuhara.kochi.jp\0notogawa.shiga.jp\0lds\0" -"mashiki.kumamoto.jp\0" -"info.ht\0" -"info.hu\0*.kobe.jp\0oharu.aichi.jp\0" -"kushima.miyazaki.jp\0" -"cesenaforli.it\0in.ni\0" -"tokashiki.okinawa.jp\0kiwi\0" -"lib.ny.us\0" -"kanoya.kagoshima.jp\0" -"info.et\0" -"inatsuki.fukuoka.jp\0mx.na\0" -"toei.aichi.jp\0" -"lib.pr.us\0" -"readmyblog.org\0" -"l\xc3\xa4ns.museum\0fla.no\0" -"auction\0" -"alstahaug.no\0" -"nic.in\0" -"ed.pw\0" -"bugatti\0xen.prgmr.com\0" -"w.bg\0experts-comptables.fr\0musashino.tokyo.jp\0is-a-caterer.com\0" -"family\0" -"aero\0" -"colonialwilliamsburg.museum\0buyshouses.net\0" -"pro.na\0klodzko.pl\0\xe0\xa4\x95\xe0\xa5\x89\xe0\xa4\xae\0" -"minakami.gunma.jp\0" -"ug.gov.pl\0info.cx\0" -"engine.aero\0" -"takanabe.miyazaki.jp\0pro.mv\0panasonic\0" -"praxi\0myqnapcloud.com\0" -"sncf\0s3-sa-east-1.amazonaws.com\0" -"kunst.museum\0" -"games\0" -"vossevangen.no\0" -"info.ec\0" -"hitachiomiya.ibaraki.jp\0turek.pl\0" -"k12.nm.us\0" -"nf.ca\0" -"stjordalshalsen.no\0" -"fnd.br\0" -"\xe5\x9f\xbc\xe7\x8e\x89.jp\0is-a-anarchist.com\0" -"miyake.nara.jp\0" -"pro.om\0" -"info.bb\0sue.fukuoka.jp\0" -"in.rs\0" -"info.at\0servepics.com\0" -"info.au\0ltd.cy\0" -"naha.okinawa.jp\0" -"dgca.aero\0" -"botanicgarden.museum\0y.se\0" -"info.az\0ddnsgeek.com\0" -"itayanagi.aomori.jp\0mashike.hokkaido.jp\0" -"upow.gov.pl\0" -"info.bo\0""2000.hu\0barrell-of-knowledge.info\0" -"honjyo.akita.jp\0fuji.shizuoka.jp\0\xe0\xb2\xad\xe0\xb2\xbe\xe0\xb2\xb0\xe0\xb2\xa4\0" -"xfinity\0" -"merseine.nu\0" -"nakanojo.gunma.jp\0bingo\0" -"shiksha\0" -"pro.pr\0" -"in.th\0amica\0opencraft.hosting\0" -"naval.museum\0" -"work\0" -"info.co\0k12.wi.us\0" -"orkdal.no\0" -"osaka.jp\0in.ua\0" -"eidfjord.no\0\xc3\xb8ygarden.no\0" -"nirasaki.yamanashi.jp\0divttasvuotna.no\0malbork.pl\0" -"games.hu\0" -"pharmacy.museum\0" -"ks.ua\0" -"torsken.no\0" -"est-mon-blogueur.com\0" -"masuda.shimane.jp\0in.us\0" -"ltd.gi\0starnberg.museum\0" -"frogn.no\0navuotna.no\0" -"tamba.hyogo.jp\0unjarga.no\0international\0hasura-app.io\0" -"\xe6\x95\x8e\xe8\x82\xb2.hk\0" -"kawagoe.mie.jp\0" -"schokoladen.museum\0" -"ks.us\0" -"conference.aero\0is-a-knight.org\0" -"from-ms.com\0from-nc.com\0" -"aibetsu.hokkaido.jp\0nh.us\0adult\0on-web.fr\0ltd.hk\0" -"winb.gov.pl\0" -"amagasaki.hyogo.jp\0sb.ua\0" -"bahccavuotna.no\0ollo\0" -"df.gov.br\0erotika.hu\0" -"marriott\0" -"shopping\0" -"pro.tt\0chernivtsi.ua\0" -"est-le-patron.com\0is-a-student.com\0net-freaks.com\0" -"oshima.tokyo.jp\0lol\0" -"cards\0monster\0" -"realestate.pl\0" -"mombetsu.hokkaido.jp\0" -"xperia\0" -"glass\0" -"nat.tn\0" -"sor-varanger.no\0" -"kamijima.ehime.jp\0" -"mosvik.no\0" -"sokndal.no\0lpl\0" -"s3-external-1.amazonaws.com\0" -"trentinoaadige.it\0" -"\xe5\xa4\xa7\xe9\x98\xaa.jp\0pro.vn\0" -"\xc3\xb8vre-eiker.no\0" -"zapto.org\0" -"rio.br\0nic.tj\0gift\0man\0" -"kiyama.saga.jp\0cc.ut.us\0map\0" -"homebuilt.aero\0ooshika.nagano.jp\0dr.na\0cheap\0mba\0" -"energy\0" -"mihama.aichi.jp\0" -"\xe5\x80\x8b\xe4\xba\xba.hk\0ltd.lk\0bounceme.net\0" -"familyds.com\0" -"midori.chiba.jp\0vikna.no\0cc.wy.us\0" -"kiwa.mie.jp\0" -"to.gov.br\0nhs.uk\0" -"balsan.it\0isumi.chiba.jp\0" -"modelling.aero\0loppa.no\0" -"kppsp.gov.pl\0fishing\0" -"unzen.nagasaki.jp\0ybo.review\0" -"swiss\0" -"nagaoka.niigata.jp\0" -"time.museum\0" -"static.land\0" -"takahata.yamagata.jp\0" -"tr\xc3\xb8gstad.no\0" -"western.museum\0" -"lib.ok.us\0" -"ltd\0" -"americanexpress\0" -"engineer.aero\0" -"bmd.br\0" -"nishiarita.saga.jp\0commbank\0" -"vaga.no\0" -"musica.ar\0k12.co.us\0" -"med\0" -"kaita.hiroshima.jp\0" -"matsushige.tokushima.jp\0democrat\0" -"b\xc3\xb8.telemark.no\0" -"desa.id\0" -"project.museum\0sciencesnaturelles.museum\0" -"itoigawa.niigata.jp\0" -"chihayaakasaka.osaka.jp\0men\0" -"meo\0" -"musica.bo\0" -"u.bg\0" -"annaka.gunma.jp\0radom.pl\0" -"\xe7\xb6\xb2\xe8\xb7\xaf.tw\0info.ve\0" -"hurdal.no\0basketball\0" -"karaganda.su\0" -"hitra.no\0is-a-green.com\0" -"slg.br\0kamikawa.saitama.jp\0minato.tokyo.jp\0" -"info.vn\0" -"oksnes.no\0" -"green\0" -"otoyo.kochi.jp\0" -"jab.br\0kharkov.ua\0is.eu.org\0" -"notodden.no\0" -"mihama.fukui.jp\0" -"cinema.museum\0" -"sumy.ua\0" -"\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4\0scrapping.cc\0" -"k12.or.us\0" -"sumoto.hyogo.jp\0servebeer.com\0" -"bostik\0" -"no-ip.ca\0" -"srv.br\0" -"w.se\0" -"info.tn\0" -"sanfrancisco.museum\0med.pro\0" -"dr.tr\0dyndns-mail.com\0" -"info.tr\0from-tx.com\0" -"taku.saga.jp\0chat\0" -"info.tt\0" -"hakusan.ishikawa.jp\0" -"yaita.tochigi.jp\0" -"aizumisato.fukushima.jp\0namsos.no\0s3.eu-west-3.amazonaws.com\0it.eu.org\0" -"info.tz\0" -"mil\0" -"style\0" -"travel.pl\0" -"student.aero\0lighting\0" -"gosen.niigata.jp\0suwalki.pl\0" -"mit\0" -"iki.nagasaki.jp\0" -"awaji.hyogo.jp\0clock.museum\0vegarshei.no\0" -"ggf.br\0" -"exhibition.museum\0" -"ltd.ua\0" -"baidar.no\0" -"info.ro\0dubai\0" -"deatnu.no\0" -"g\xc3\xa1ls\xc3\xa1.no\0" -"nanae.hokkaido.jp\0info.sd\0" -"\xe6\xbb\x8b\xe8\xb3\x80.jp\0il.us\0" -"ltd.uk\0" -"symantec\0verm\xc3\xb6gensberatung\0" -"latina.it\0" -"takatori.nara.jp\0dnsdojo.org\0" -"charter.aero\0averoy.no\0la.us\0" -"mlb\0" -"pub.sa\0" -"\xe0\xb8\x98\xe0\xb8\xb8\xe0\xb8\xa3\xe0\xb8\x81\xe0\xb8\xb4\xe0\xb8\x88.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" -"vibovalentia.it\0hzc.io\0" -"toon.ehime.jp\0" -"info.pk\0" -"info.pl\0" -"chocolate.museum\0everbank\0" -"ip6.arpa\0sondrio.it\0zara\0on-aptible.com\0" -"ge.it\0maniwa.okayama.jp\0mma\0" -"yamaguchi.jp\0info.pr\0mls\0" -"matera.it\0" -"fukuyama.hiroshima.jp\0target\0" -"noticias.bo\0" -"in.eu.org\0" -"bodo.no\0" -"even\xc3\xa1\xc5\xa1\xc5\xa1i.no\0" -"koka.shiga.jp\0place\0" -"info.na\0dscloud.me\0" -"info.mv\0info.nf\0lebork.pl\0travel.tt\0from-ny.net\0" -"kibichuo.okayama.jp\0" -"eigersund.no\0" -"showa.gunma.jp\0info.ni\0lib.ak.us\0" -"boston\0" -"rec.br\0lillehammer.no\0grocery\0sohu\0" -"aeroclub.aero\0shirakawa.gifu.jp\0rollag.no\0" -"mt.it\0tako.chiba.jp\0nakasatsunai.hokkaido.jp\0" -"info.nr\0" -"taa.it\0" -"hinode.tokyo.jp\0moe\0" -"okegawa.saitama.jp\0" -"asn.au\0pi.it\0chrysler\0moi\0" -"rec.co\0bokn.no\0" -"fundacio.museum\0" -"mom\0" -"b\xc3\xa5tsfjord.no\0" -"contractors\0" -"info.la\0" -"rn.it\0" -"higashikawa.hokkaido.jp\0midsund.no\0" -"kumenan.okayama.jp\0mov\0" -"bjugn.no\0" -"yoshioka.gunma.jp\0webhop.info\0" -"newhampshire.museum\0goodyear\0" -"ts.it\0" -"kashihara.nara.jp\0weatherchannel\0spacekit.io\0" -"nab\0" -"gov.nc.tr\0" -"tank.museum\0" -"oy.lc\0" -"tksat.bo\0shop.ht\0" -"shop.hu\0" -"education\0" -"jolster.no\0" -"nba\0wedeploy.sh\0" -"ichikai.tochigi.jp\0" -"gorge.museum\0" -"nosegawa.nara.jp\0kurobe.toyama.jp\0from-ma.com\0" -"ikeda.fukui.jp\0hanawa.fukushima.jp\0" -"kafjord.no\0" -"oiso.kanagawa.jp\0" -"k12.ar.us\0" -"naturalhistorymuseum.museum\0tatamotors\0accesscam.org\0" -"gyeongbuk.kr\0" -"msd\0" -"k12.de.us\0" -"oyama.tochigi.jp\0" -"soccer\0" -"info.ki\0lib.sc.us\0" -"yatsushiro.kumamoto.jp\0" -"ogimi.okinawa.jp\0tr\xc3\xa6na.no\0" -"\xd0\xbe\xd0\xb1\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0" -"midori.gunma.jp\0song\0gr.com\0" -"gc.ca\0" -"higashi.fukushima.jp\0" -"s.bg\0" -"channel\0" -"kurume.fukuoka.jp\0" -"tiffany\0" -"tynset.no\0lib.wy.us\0mtn\0" -"sony\0" -"humanities.museum\0mtr\0" -"!city.kitakyushu.jp\0nec\0" -"bplaced.com\0" -"is-a-nurse.com\0" -"osoyro.no\0dyndns.info\0" -"mimata.miyazaki.jp\0tychy.pl\0" -"grue.no\0" -"urayasu.chiba.jp\0" -"lincoln\0" -"k12.ma.us\0" -"nb.ca\0" -"takamori.nagano.jp\0" -"halden.no\0" -"encyclopedic.museum\0" -"net\0" -"educator.aero\0torahime.shiga.jp\0new\0" -"honefoss.no\0" -"marumori.miyagi.jp\0" -"takahama.aichi.jp\0nfl\0" -"meland.no\0" -"u.se\0" -"tara.saga.jp\0" -"kawara.fukuoka.jp\0" -"dp.ua\0scjohnson\0" -"hanno.saitama.jp\0tcm.museum\0" -"software.aero\0" -"ngo\0" -"tateshina.nagano.jp\0" -"*.transurl.be\0" -"uzs.gov.pl\0" -"nhk\0" -"federation.aero\0xihuan\0karacol.su\0" -"black\0" -"ayase.kanagawa.jp\0" -"asahi.nagano.jp\0" +"tr\0" +"tt\0" "yk.ca\0" -"\xe7\xbd\x91\xe7\xbb\x9c.cn\0" -"\xe0\xb0\xad\xe0\xb0\xbe\xe0\xb0\xb0\xe0\xb0\xa4\xe0\xb1\x8d\0" -"takasago.hyogo.jp\0" -"takasu.hokkaido.jp\0" -"\xe4\xb8\x96\xe7\x95\x8c\0" -"mitsuke.niigata.jp\0" -"bi.it\0" -"dali.museum\0rec.nf\0" -"pri.ee\0hachioji.tokyo.jp\0" -"fukushima.jp\0" -"toda.saitama.jp\0" -"yodobashi\0" -"clubmed\0" -"asn.lv\0reisen\0" -"kurashiki.okayama.jp\0" -"minami.tokushima.jp\0" -"saltdal.no\0" -"raisa.no\0mt.us\0nd.us\0" -"shioya.tochigi.jp\0" -"yoshinogari.saga.jp\0" -"shinshiro.aichi.jp\0futsu.nagasaki.jp\0" -"fredrikstad.no\0chernihiv.ua\0dnipropetrovsk.ua\0" -"cal.it\0abiko.chiba.jp\0" -"vardo.no\0*.awdev.ca\0" -"oketo.hokkaido.jp\0" -"is-very-bad.org\0" -"yatomi.aichi.jp\0" -"wedeploy.me\0" -"ann-arbor.mi.us\0" -"crimea.ua\0" -"roros.no\0" -"higashihiroshima.hiroshima.jp\0bosch\0*.transurl.eu\0" -"wa.edu.au\0iglesiascarbonia.it\0" -"monza-e-della-brianza.it\0" -"\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4\xe0\xa4\xae\xe0\xa5\x8d\0" -"suldal.no\0" -"yaizu.shizuoka.jp\0" -"mitane.akita.jp\0" -"aerodrome.aero\0" -"minami.fukuoka.jp\0ohda.shimane.jp\0williamsburg.museum\0" -"storfjord.no\0" -"zuerich\0myhome-server.de\0" -"isa.kagoshima.jp\0" -"mckinsey\0" -"andria-barletta-trani.it\0" -"pg.it\0" +"tv\0is-a-nurse.com\0" +"tw\0ug\0taxi\0boxfuse.io\0" +"\xe7\xbd\x91\xe7\xbb\x9c.hk\0arboretum.museum\0tz\0williamhill\0" +"oishida.yamagata.jp\0uk\0" +"profesional.bo\0eus\0" +"s.se\0" +"cooking\0cookingchannel\0" +"arita.saga.jp\0lahppi.no\0" +"riodejaneiro.museum\0va\0" +"hiraya.nagano.jp\0cinema.museum\0nyny.museum\0" +"kyotango.kyoto.jp\0us\0vc\0" +"pordenone.it\0ve\0" +"ontario.museum\0vg\0hepforge.org\0" +"zapto.xyz\0" +"fribourg.museum\0uy\0vi\0mg.leg.br\0" +"beauxarts.museum\0uz\0" +"no-ip.co.uk\0" +"frosinone.it\0" +"plc.ly\0" +"vn\0" +"trentino-suedtirol.it\0" +"nf.ca\0" +"nature.museum\0\xe9\x9b\xbb\xe8\xa8\x8a\xe7\x9b\x88\xe7\xa7\x91\0" +"sciencecenter.museum\0vu\0" +"wf\0" +"qpon\0" +"is-a-anarchist.com\0" +"us-east-1.elasticbeanstalk.com\0" +"tingvoll.no\0careers\0" +"*.nom.br\0essex.museum\0" +"kibichuo.okayama.jp\0birthplace.museum\0ws\0" +"rovigo.it\0" +"kagoshima.kagoshima.jp\0*.transurl.eu\0" +"its.me\0" +"oharu.aichi.jp\0brother\0" +"reklam.hu\0" +"rollag.no\0" +"afjord.no\0" +"yawatahama.ehime.jp\0" +"vpnplus.to\0" "hino.tokyo.jp\0" -"leasing.aero\0" -"\xe7\xbd\x91\xe7\xbb\x9c.hk\0kawanishi.nara.jp\0" -"toyosato.shiga.jp\0convent.museum\0" -"izumo.shimane.jp\0" -"government.aero\0tatebayashi.gunma.jp\0tado.mie.jp\0gets-it.net\0" -"holtalen.no\0" -"kashiwa.chiba.jp\0" -"kanna.gunma.jp\0" -"saintlouis.museum\0" -"rec.ro\0" -"chikujo.fukuoka.jp\0" -"anan.nagano.jp\0" -"tomika.gifu.jp\0" -"shonai.fukuoka.jp\0losangeles.museum\0gjerstad.no\0" -"groks-the.info\0" -"kariya.aichi.jp\0" -"otaki.saitama.jp\0" -"firmdale\0" -"naie.hokkaido.jp\0kameoka.kyoto.jp\0" -"vv.it\0" -"omuta.fukuoka.jp\0" +"kamiichi.toyama.jp\0cc.ia.us\0" +"leasing.aero\0yamato.fukushima.jp\0fuchu.toyama.jp\0media.museum\0logoip.de\0" +"fit\0" +"vs.it\0" +"valledaosta.it\0" +"yt\0" +"lib.hi.us\0" +"fuji.shizuoka.jp\0co.com\0" +"mutsuzawa.chiba.jp\0gotpantheon.com\0" +"showa.gunma.jp\0shimizu.shizuoka.jp\0" +"zm\0" +"teramo.it\0" +"arezzo.it\0zp.ua\0" +"aizumi.tokushima.jp\0" +"br\xc3\xb8nn\xc3\xb8ysund.no\0" +"nakagyo.kyoto.jp\0zw\0" +"r\xc3\xa1hkker\xc3\xa1vju.no\0" "odawara.kanagawa.jp\0" -"grozny.su\0" -"minamiaiki.nagano.jp\0c66.me\0" -"opole.pl\0abbvie\0barclays\0monash\0" -"shimofusa.chiba.jp\0geelvinck.museum\0" -"now\0" -"lib.mo.us\0" -"b\xc3\xb8mlo.no\0backplaneapp.io\0" -"carbonia-iglesias.it\0chikuma.nagano.jp\0" -"yamada.iwate.jp\0" -"miyoshi.tokushima.jp\0home.dyndns.org\0nfshost.com\0" -"for-our.info\0" -"design.aero\0ibaraki.jp\0skierv\xc3\xa1.no\0" -"k12.dc.us\0" -"gs.aa.no\0" -"karumai.iwate.jp\0" +"insurance.aero\0from-ut.com\0" +"cloudapp.net\0" +"l\xc3\xa6rdal.no\0" +"aland.fi\0hachirogata.akita.jp\0" +"yazu.tottori.jp\0wielun.pl\0" +"bajddar.no\0" +"website\0" +"casino.hu\0" +"vda.it\0" +"lanxess\0" +"federation.aero\0koga.fukuoka.jp\0" +"fly\0" +"legal\0" +"ikawa.akita.jp\0" +"etnedal.no\0" +"gb.net\0" +"uzs.gov.pl\0" +"doesntexist.org\0" +"ok.us\0" +"starhub\0" +"frogans\0" +"linz.museum\0" +"mydissent.net\0" +"busan.kr\0" +"nakano.tokyo.jp\0" +"u2.xnbay.com\0" +"stj\xc3\xb8rdalshalsen.no\0cv.ua\0plc.uk\0" +"ha.cn\0hidaka.wakayama.jp\0" +"dy.fi\0" +"h\xc3\xb8nefoss.no\0" +"endofinternet.net\0" +"adac\0" +"lib.mi.us\0" +"foo\0" +"nagasaki.jp\0" +"q.bg\0kannami.shizuoka.jp\0" +"chungbuk.kr\0dyroy.no\0" +"*.platformsh.site\0" +"fox\0" +"ohira.miyagi.jp\0onthewifi.com\0" +"\xe9\xa6\x99\xe6\xb8\xaf\0" +"ca.it\0" +"museumvereniging.museum\0" +"democracia.bo\0*.sendai.jp\0tachiarai.fukuoka.jp\0" +"beta.bounty-full.com\0" +"bauhaus\0apps.lair.io\0" +"meldal.no\0\xe8\x81\x94\xe9\x80\x9a\0" +"pn.it\0raid\0" +"*.transurl.nl\0" +"square7.de\0" +"gal\0" +"isehara.kanagawa.jp\0" +"gap\0" +"tydal.no\0" +"yugawa.fukushima.jp\0" +"uber.space\0" +"sirdal.no\0" +"shopping\0" +"ddnsking.com\0" +"frl\0" +"\xe7\xb5\x84\xe7\xbb\x87.hk\0stuff-4-sale.org\0" +"otsuki.kochi.jp\0" +"couchpotatofries.org\0" +"*.vps.myjino.ru\0" +"asago.hyogo.jp\0" +"damnserver.com\0" +"zone.id\0" +"symantec\0" +"higashiomi.shiga.jp\0" +"lib.ct.us\0" +"ca.na\0if.ua\0" +"kin.okinawa.jp\0" +"cloudfunctions.net\0" +"square7.ch\0" +"gulen.no\0gdn\0" +"lib.ri.us\0is-a-republican.com\0" +"gea\0" +"otaki.chiba.jp\0hole.no\0ftr\0dynathome.net\0" +"\xe7\xbd\x91\xe7\xbb\x9c\0" +"skiptvet.no\0" +"nakano.nagano.jp\0" +"warmia.pl\0bananarepublic\0" +"gift\0" +"ouda.nara.jp\0jur.pro\0tours\0" +"shiroishi.miyagi.jp\0ritto.shiga.jp\0" +"fun\0" +"cards\0goldpoint\0" +"port.fr\0" +"joso.ibaraki.jp\0" +"nesodden.no\0" +"rec.br\0" +"otaki.nagano.jp\0bahn.museum\0" +"cern\0" +"engineer\0" +"lom.it\0" +"sowa.ibaraki.jp\0" +"rec.co\0umaji.kochi.jp\0" +"varese.it\0sosa.chiba.jp\0minnesota.museum\0posts-and-telecommunications.museum\0" +"modalen.no\0s3-ap-southeast-1.amazonaws.com\0" +"rnu.tn\0" +"asahi.mie.jp\0" +"dynalias.com\0" +"kamo.niigata.jp\0betainabox.com\0is-certified.com\0" +"hanno.saitama.jp\0" +"aridagawa.wakayama.jp\0" +"kamikawa.saitama.jp\0" +"trentinosuedtirol.it\0vegas\0" +"katashina.gunma.jp\0gs.nt.no\0" +"sf.no\0" +"miyada.nagano.jp\0" +"open\0" +"servebbs.org\0" +"otoyo.kochi.jp\0" +"cologne\0toshiba\0" +"hiratsuka.kanagawa.jp\0" +"lib.id.us\0" +"fyi\0hospital\0" +"4.bg\0" +"chikujo.fukuoka.jp\0" +"origins\0" +"lib.wi.us\0" +"is-very-good.org\0" +"biratori.hokkaido.jp\0" +"aukra.no\0lindas.no\0" +"ha.no\0" +"yamatokoriyama.nara.jp\0ddnss.org\0" +"suzu.ishikawa.jp\0yamagata.nagano.jp\0" +"tokai.aichi.jp\0saikai.nagasaki.jp\0americana.museum\0bearalvahki.no\0" +"plaza.museum\0" +"nemuro.hokkaido.jp\0klodzko.pl\0" +"itakura.gunma.jp\0nishihara.kumamoto.jp\0" +"maniwa.okayama.jp\0de.cool\0" +"salerno.it\0" +"android\0" +"lom.no\0" +"misaki.osaka.jp\0" +"nishinoomote.kagoshima.jp\0" +"hammerfest.no\0k12.nj.us\0" +"nago.okinawa.jp\0" +"sandcats.io\0" +"kutno.pl\0" +"stange.no\0vladimir.su\0" +"shika.ishikawa.jp\0" +"gle\0dyndns-free.com\0" +"k12.ec\0" +"s\xc3\xb8r-varanger.no\0" +"pointto.us\0" +"id.au\0\xd0\xba\xd0\xbe\xd0\xbc\0" +"kawaminami.miyazaki.jp\0ca.us\0" +"kawaue.gifu.jp\0deals\0" +"al.it\0tosashimizu.kochi.jp\0" +"kumatori.osaka.jp\0" +"iizuka.fukuoka.jp\0services\0" +"discovery.museum\0" +"ato.br\0twmail.net\0" +"wa.au\0hol.no\0" +"e164.arpa\0" +"ddnss.de\0" +"yokoshibahikari.chiba.jp\0" +"uruma.okinawa.jp\0gs.st.no\0" +"express.aero\0k12.as.us\0" +"sasaguri.fukuoka.jp\0kushimoto.wakayama.jp\0" +"rauma.no\0" +"suwa.nagano.jp\0gmo\0" +"wlocl.pl\0" +"cahcesuolo.no\0" +"masfjorden.no\0" +"k12.or.us\0" +"latrobe\0" +"gmx\0" +"lib.mt.us\0lib.nd.us\0from-nm.com\0" +"tsuno.miyazaki.jp\0" +"kawanehon.shizuoka.jp\0rv.ua\0" +"artcenter.museum\0" +"yamakita.kanagawa.jp\0ternopil.ua\0homeunix.com\0fantasyleague.cc\0" +"tur.ar\0vladimir.ru\0" +"hara.nagano.jp\0" +"psi.br\0miyama.mie.jp\0katsuragi.wakayama.jp\0" +"ct.it\0" +"buzz\0star\0" +"the.br\0" +"abu.yamaguchi.jp\0cc.co.us\0" +"s3.ca-central-1.amazonaws.com\0" +"goo\0" +"gop\0" +"ra.it\0matsumoto.kagoshima.jp\0shibata.niigata.jp\0" +"tur.br\0" +"got\0" +"mobi\0" +"gov\0" +"isleofman.museum\0" +"yamanashi.yamanashi.jp\0" +"osasco.br\0" +"aomori.aomori.jp\0sor-varanger.no\0\xe6\xb8\xb8\xe6\x88\x8f\0" +"k12.il\0" +"enterprises\0" +"is.gov.pl\0" +"\xc3\xa1laheadju.no\0" +"tranibarlettaandria.it\0" +"al.no\0" +"rec.nf\0americanfamily\0" +"slupsk.pl\0" +"moda\0" +"luzern.museum\0fairwinds\0" +"is-a-liberal.com\0" +"crown\0" +"museum.tt\0is-into-games.com\0" +"bio.br\0nakagawa.hokkaido.jp\0ilawa.pl\0" +"gliding.aero\0portlligat.museum\0" +"nishikatsura.yamanashi.jp\0seaport.museum\0" +"kasuya.fukuoka.jp\0hirado.nagasaki.jp\0barsy.net\0" +"higashiyodogawa.osaka.jp\0" +"lebork.pl\0" +"official.academy\0" +"mer\xc3\xa5ker.no\0hbo\0" +"aca.pro\0" +"aircraft.aero\0chattanooga.museum\0" +"nara.jp\0" +"\xe6\x94\xbf\xe5\xba\x9c.hk\0alaheadju.no\0\xe0\xa4\xa8\xe0\xa5\x87\xe0\xa4\x9f\0" +"issmarterthanyou.com\0al.eu.org\0" +"*.nagoya.jp\0capetown\0" +"rentals\0" +"budejju.no\0" +"construction\0" +"lib.sd.us\0dnsalias.org\0from-mt.com\0from-nd.com\0" +"tomisato.chiba.jp\0" +"liguria.it\0" +"tomakomai.hokkaido.jp\0" +"cloudns.biz\0" +"id.ir\0shinichi.hiroshima.jp\0" +"hiphop\0" +"showa.yamanashi.jp\0royrvik.no\0url.tw\0pcloud.host\0" +"iris.arpa\0ferrara.it\0oxford.museum\0" +"larvik.no\0" +"konan.shiga.jp\0school.na\0" +"yamanobe.yamagata.jp\0" +"lucca.it\0handson.museum\0dedyn.io\0" +"trentinsued-tirol.it\0kawaguchi.saitama.jp\0wv.us\0ann-arbor.mi.us\0" +"yuu.yamaguchi.jp\0" +"sor-odal.no\0" +"eu.int\0astronomy.museum\0" +"obu.aichi.jp\0" +"muroto.kochi.jp\0newspaper.museum\0amli.no\0" +"oum.gov.pl\0gotdns.ch\0" +"koryo.nara.jp\0lyngen.no\0" +"judygarland.museum\0" +"rec.ro\0aramco\0" +"olawa.pl\0" +"school.nz\0" +"oguni.yamagata.jp\0" +"rimini.it\0" +"now.sh\0" +"torsken.no\0mmafan.biz\0" +"ma.us\0" +"pgfog.com\0" +"gratis\0" +"id.lv\0" +"\xeb\x8b\xb7\xeb\x84\xb7\0" +"id.ly\0" +"k12.ks.us\0merseine.nu\0" +"wazuka.kyoto.jp\0" +"tattoo\0" +"trentino-sudtirol.it\0" +"sd.cn\0" +"tonsberg.no\0" +"tsunan.niigata.jp\0pl.eu.org\0protonet.io\0" +"midatlantic.museum\0" +"business\0" +"al.us\0" +"from-ms.com\0from-nc.com\0" +"iwi.nz\0" +"satosho.okayama.jp\0tires\0" +"tanohata.iwate.jp\0" +"is-leet.com\0" +"monmouth.museum\0ny.us\0" +"est-a-la-masion.com\0" +"indian.museum\0settlement.museum\0""2ix.at\0" +"mt.it\0rec.ve\0" +"nagaoka.niigata.jp\0" +"komforb.se\0linkitools.space\0" +"shishikui.tokushima.jp\0cc.mo.us\0farmers\0" +"go.ci\0" +"toyota.yamaguchi.jp\0" +"higashimatsushima.miyagi.jp\0page\0" +"aogaki.hyogo.jp\0" +"hiv\0" +"salvadordali.museum\0lapy.pl\0" +"go.cr\0k12.ok.us\0gallery\0" +"higashikagura.hokkaido.jp\0" +"cnt.br\0itako.ibaraki.jp\0" +"vestby.no\0\xe5\xa4\xa7\xe6\x8b\xbf\0""2ix.ch\0" +"piemonte.it\0washtenaw.mi.us\0" +"o.bg\0r\xc3\xb8mskog.no\0vestvagoy.no\0" +"marugame.kagawa.jp\0" +"kuchinotsu.nagasaki.jp\0" +"ct.us\0" +"pol.dz\0museum.mv\0dev-myqnapcloud.com\0" +"museum.mw\0pomorze.pl\0" +"bo.it\0" +"dr\xc3\xb8""bak.no\0" +"2ix.de\0" +"\xe7\xbd\x91\xe5\xba\x97\0" +"lugansk.ua\0cc.az.us\0" +"museum.no\0bestbuy\0" +"culture.museum\0" +"quicksytes.com\0" +"shingu.wakayama.jp\0hkt\0" +"k12.tr\0" +"kisofukushima.nagano.jp\0" +"ancona.it\0" +"rennesoy.no\0" +"2038.io\0" +"museum.om\0" +"onna.okinawa.jp\0" +"hvaler.no\0" +"seihi.nagasaki.jp\0linkyard-cloud.ch\0" +"publishproxy.com\0" +"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xdb\x8c\xd8\xa9\0" +"servehumour.com\0" +"fosnes.no\0\xe4\xb8\xad\xe6\x96\x87\xe7\xbd\x91\0" +"and\xc3\xb8y.no\0" +"k12.vi\0" +"traeumtgerade.de\0" +"fl.us\0" +"koga.ibaraki.jp\0" +"moriyoshi.akita.jp\0" +"toyota.aichi.jp\0bahccavuotna.no\0" +"uchinomi.kagawa.jp\0" +"\xd9\xbe\xd8\xa7\xda\xa9\xd8\xb3\xd8\xaa\xd8\xa7\xd9\x86\0spiegel\0" +"moriya.ibaraki.jp\0" +"tempioolbia.it\0" +"villas\0" +"soo.kagoshima.jp\0" +"naka.ibaraki.jp\0" +"pol.ht\0murata.miyagi.jp\0" +"cherkasy.ua\0\xe0\xb8\xa3\xe0\xb8\xb1\xe0\xb8\x90\xe0\xb8\x9a\xe0\xb8\xb2\xe0\xb8\xa5.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" +"kusatsu.gunma.jp\0team\0" +"tenei.fukushima.jp\0misugi.mie.jp\0s3-website-ap-southeast-1.amazonaws.com\0" +"barsy.pro\0" +"tsukigata.hokkaido.jp\0misato.miyagi.jp\0s3.dualstack.eu-west-3.amazonaws.com\0" +"prd.fr\0" +"ru.com\0is-not-certified.com\0" +"matsushige.tokushima.jp\0" +"go.id\0" +"wakasa.fukui.jp\0" +"vinnytsia.ua\0" +"og.ao\0" +"beppu.oita.jp\0town.museum\0" +"hot\0" +"eu-west-3.elasticbeanstalk.com\0" +"id.us\0how\0" +"go.it\0minamiyamashiro.kyoto.jp\0" +"lodi.it\0shizuoka.jp\0cadaques.museum\0\xec\x82\xbc\xec\x84\xb1\0" +"namerikawa.toyama.jp\0" +"sa.edu.au\0tech\0" +"bandai.fukushima.jp\0" +"isahaya.nagasaki.jp\0" +"wa.us\0" +"hanawa.fukushima.jp\0" +"homelink.one\0" +"airtraffic.aero\0go.jp\0" +"barsy.pub\0" +"louvre.museum\0oystre-slidre.no\0" +"aero\0" +"sorocaba.br\0lakas.hu\0sydney\0i234.me\0" +"go.ke\0" +"oto.fukuoka.jp\0" +"hu.net\0" +"s3.dualstack.ap-northeast-1.amazonaws.com\0" +"sic.it\0" +"iheya.okinawa.jp\0" +"hamatonbetsu.hokkaido.jp\0" +"news.hu\0nakanoto.ishikawa.jp\0rns.tn\0za.com\0" +"go.kr\0tirol\0" +"uji.kyoto.jp\0" +"organic\0" +"moto\0" +"ibm\0" +"tara.saga.jp\0" +"yurihonjo.akita.jp\0frana.no\0" +"kerrylogistics\0locker\0" +"chikuma.nagano.jp\0" +"ice\0" +"collegefan.org\0" +"trentinsudtirol.it\0navuotna.no\0" +"dnipropetrovsk.ua\0lilly\0endofinternet.org\0" +"tran\xc3\xb8y.no\0" +"forlicesena.it\0bievat.no\0" +"kijo.miyazaki.jp\0" +"prd.km\0nowruz\0" +"film.museum\0icu\0" +"kawagoe.mie.jp\0" +"birdart.museum\0" +"2.bg\0" +"pvt.ge\0" +"qld.au\0bridgestone\0" +"ecologia.bo\0" +"moareke.no\0" +"fujimino.saitama.jp\0" +"hikari.yamaguchi.jp\0" +"tohma.hokkaido.jp\0" +"numata.hokkaido.jp\0" +"city.hu\0" +"fujisato.akita.jp\0" +"govt.nz\0" +"vinnica.ua\0mt.us\0nd.us\0" +"arte.bo\0kaisei.kanagawa.jp\0higashine.yamagata.jp\0" +"lo.it\0prd.mg\0" +"*.compute-1.amazonaws.com\0" +"kanna.gunma.jp\0" +"chat\0" +"pars\0" +"kongsvinger.no\0" +"physio\0" +"urayasu.chiba.jp\0echizen.fukui.jp\0" +"fj.cn\0\xe6\x84\x9b\xe5\xaa\x9b.jp\0" +"science\0dyndns-at-home.com\0" +"kviteseid.no\0" +"\xd8\xa7\xd8\xaa\xd8\xb5\xd8\xa7\xd9\x84\xd8\xa7\xd8\xaa\0" +"varggat.no\0" +"raisa.no\0temasek\0ae.org\0in-the-band.net\0" +"ifm\0" +"amot.no\0imamat\0" +"oji.nara.jp\0pl.ua\0" +"naka.hiroshima.jp\0" +"kawakami.nara.jp\0esurance\0" +"m\xc4\x81ori.nz\0imdb\0clan.rip\0" +"gonohe.aomori.jp\0kariwa.niigata.jp\0jpn.com\0" +"matsuno.ehime.jp\0" +"go.pw\0" +"s3-us-west-1.amazonaws.com\0" +"snillfjord.no\0" +"\xd0\xbc\xd0\xba\xd0\xb4\0" +"alaska.museum\0isteingeek.de\0" +"transporte.bo\0boleslawiec.pl\0" +"og.it\0" +"iwate.jp\0ybo.science\0" +"n4t.co\0" +"\xe5\x95\x86\xe5\xba\x97\0" +"skedsmo.no\0" +"kitagawa.miyazaki.jp\0" +"yoka.hyogo.jp\0" +"tohnosho.chiba.jp\0" +"eidskog.no\0" +"kahoku.ishikawa.jp\0" +"cr.it\0otago.museum\0" +"homelinux.com\0" +"gs.hm.no\0capitalone\0" +"hirogawa.wakayama.jp\0is-a-therapist.com\0" +"\xd8\xb3\xd9\x88\xd8\xaf\xd8\xa7\xd9\x86\0" +"ravenna.it\0" +"biei.hokkaido.jp\0" +"sd.us\0moscow\0" +"curitiba.br\0" +"arteducation.museum\0" +"go.th\0pol.tr\0" +"esan.hokkaido.jp\0hannan.osaka.jp\0gotsu.shimane.jp\0" +"toyone.aichi.jp\0ostre-toten.no\0go.tj\0" +"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xdb\x8c\xdb\x83\0" +"kanmaki.nara.jp\0undersea.museum\0" +"academy.museum\0" +"sayama.saitama.jp\0" +"fermo.it\0maori.nz\0" +"iglesias-carbonia.it\0bryne.no\0" +"ogliastra.it\0" +"ando.nara.jp\0yao.osaka.jp\0go.ug\0" +"o.se\0" +"go.tz\0is-a-financialadvisor.com\0" +"kawamata.fukushima.jp\0" +"honjyo.akita.jp\0dealer\0" +"orkdal.no\0" +"lindesnes.no\0wedding\0" +"trentinosudtirol.it\0" +"namsos.no\0\xd0\xbc\xd0\xbe\xd0\xbd\0" +"nokia\0" +"onomichi.hiroshima.jp\0" +"tagawa.fukuoka.jp\0" +"blogspot.com\0" +"nb.ca\0" +"is-a-photographer.com\0" +"qsl.br\0tarumizu.kagoshima.jp\0" +"volkenkunde.museum\0" +"fin.ec\0" +"tuscany.it\0vicenza.it\0" +"akita.jp\0" +"brussels.museum\0" +"jab.br\0inc\0" +"k12.tx.us\0" +"s3-website.eu-central-1.amazonaws.com\0" +"ing\0barsy.me\0" +"no.eu.org\0" +"uchihara.ibaraki.jp\0" +"fuso.aichi.jp\0v\xc3\xa1rgg\xc3\xa1t.no\0ink\0" +"chuo.chiba.jp\0barsy.org\0" +"oamishirasato.chiba.jp\0hokuryu.hokkaido.jp\0" +"oz.au\0ogawa.saitama.jp\0oshino.yamanashi.jp\0" +"bosch\0" +"kamiizumi.saitama.jp\0" +"int\0" +"histoire.museum\0yolasite.com\0" +"\xe7\xa6\x8f\xe5\xb3\xb6.jp\0lea\xc5\x8bgaviika.no\0" +"schlesisches.museum\0" +"surf\0" +"smile\0pgafan.net\0" +"toda.saitama.jp\0babia-gora.pl\0" +"stuff-4-sale.us\0" +"k12.ia.us\0apps.fbsbx.com\0flynnhosting.net\0" +"sund.no\0phone\0" +"skjak.no\0" +"\xc3\xb8rland.no\0" +"blanco\0whoswho\0alpha.bounty-full.com\0" +"lombardia.it\0whaling.museum\0" +"tomari.hokkaido.jp\0" +"naturalhistorymuseum.museum\0from-fl.com\0" +"brasil.museum\0sibenik.museum\0" +"lib.tn.us\0" +"castres.museum\0" +"consulting.aero\0" +"countryestate.museum\0olecko.pl\0immo\0appchizi.com\0" +"twmail.org\0" +"ohda.shimane.jp\0" +"shimoji.okinawa.jp\0" +"mus.br\0expert\0" +"tatsuno.nagano.jp\0kawazu.shizuoka.jp\0" +"santafe.museum\0" +"lighting\0" +"valleedaoste.it\0kazuno.akita.jp\0" +"is-a-bulls-fan.com\0" +"nishiawakura.okayama.jp\0" +"livinghistory.museum\0bar.pro\0" +"shirakawa.gifu.jp\0sanuki.kagawa.jp\0carrier.museum\0" +"k12.ky.us\0\xe6\x94\xbf\xe5\xba\x9c.\xe9\xa6\x99\xe6\xb8\xaf\0" +"now-dns.net\0" +"cn-northwest-1.eb.amazonaws.com.cn\0" +"tsuiki.fukuoka.jp\0" +"fylkesbibl.no\0" +"jcb\0" +"teva\0" +"tksat.bo\0" +"saijo.ehime.jp\0kawajima.saitama.jp\0" +"oguni.kumamoto.jp\0" +"grp.lk\0" +"hk.org\0" +"bingo\0jcp\0" +"narusawa.yamanashi.jp\0" +"balat.no\0" +"ujitawara.kyoto.jp\0\xc3\xb8stre-toten.no\0" +"urbino-pesaro.it\0hamada.shimane.jp\0mo-i-rana.no\0ist\0" +"nz.eu.org\0" +"is-an-actor.com\0" +"asker.no\0extraspace\0from-ri.com\0" +"gaular.no\0" +"aizubange.fukushima.jp\0" +"cr.ua\0" +"ashiya.hyogo.jp\0" +"athleta\0s3.dualstack.ca-central-1.amazonaws.com\0" +"akkeshi.hokkaido.jp\0itv\0" +"solutions\0" +"rome.it\0" +"sagae.yamagata.jp\0atm.pl\0" +"tanabe.kyoto.jp\0" +"m.bg\0azurewebsites.net\0" +"georgia.museum\0" +"salem.museum\0" +"shiranuka.hokkaido.jp\0yoshikawa.saitama.jp\0" +"kumagaya.saitama.jp\0" +"\xe7\xbe\xa4\xe9\xa6\xac.jp\0s3-us-gov-west-1.amazonaws.com\0" +"rankoshi.hokkaido.jp\0hosting\0" +"hotmail\0" +"stockholm.museum\0" +"flickr\0" +"is-with-theband.com\0" +"catholic\0" +"snaase.no\0barsy.uk\0" +"london\0photo\0" +"minowa.nagano.jp\0skole.museum\0trana.no\0" +"kiryu.gunma.jp\0orsta.no\0" +"science.museum\0" +"rendalen.no\0" +"nozawaonsen.nagano.jp\0pccw\0" +"lyngdal.no\0" +"pa.gov.br\0frosta.no\0vaga.no\0wskr.gov.pl\0" +"shirosato.ibaraki.jp\0os\xc3\xb8yro.no\0" +"rikubetsu.hokkaido.jp\0" +"mihama.wakayama.jp\0" +"porsgrunn.no\0" +"unzen.nagasaki.jp\0" +"*.yokohama.jp\0etne.no\0zgora.pl\0" +"archaeology.museum\0" +"agrigento.it\0" +"watch\0" +"hasami.nagasaki.jp\0" "mr.no\0" -"shirataka.yamagata.jp\0" -"rec.ve\0" -"nra\0" -"shriram\0" -"rzgw.gov.pl\0" -"lib.tn.us\0is-a-rockstar.com\0" -"q.bg\0sport.hu\0" -"obi\0" -"chikuzen.fukuoka.jp\0" -"kunimi.fukushima.jp\0" -"info.zm\0" -"overhalla.no\0grozny.ru\0" -"yusui.kagoshima.jp\0rl.no\0" -"hitachiota.ibaraki.jp\0naumburg.museum\0" -"kvinesdal.no\0" -"nrw\0" -"jewish.museum\0\xd0\xbc\xd0\xbe\xd1\x81\xd0\xba\xd0\xb2\xd0\xb0\0" -"minamiuonuma.niigata.jp\0" -"tools\0" -"itabashi.tokyo.jp\0viking\0" -"grong.no\0" -"brasil.museum\0" -"republican\0" -"misawa.aomori.jp\0arteducation.museum\0" -"mp.br\0anthro.museum\0" -"namegawa.saitama.jp\0east-kazakhstan.su\0" -"grainger\0" -"music.museum\0museum.tt\0" -"pe.ca\0*.transurl.nl\0" -"oshino.yamanashi.jp\0" -"l\xc3\xb8renskog.no\0" -"ba.gov.br\0shiroi.chiba.jp\0fhv.se\0" -"shishikui.tokushima.jp\0s.se\0s3.cn-north-1.amazonaws.com.cn\0" -"ntt\0" -"k12.ri.us\0" -"vana\0" -"sakahogi.gifu.jp\0dn.ua\0" -"kitanakagusuku.okinawa.jp\0" -"sciences.museum\0" -"asnes.no\0" -"spot\0" -"tsukui.kanagawa.jp\0" -"ikano\0" -"review\0ma.leg.br\0" -"rifu.miyagi.jp\0vpnplus.to\0" -"osakasayama.osaka.jp\0" -"\xc3\xb8ystre-slidre.no\0" -"off\0" -"hikawa.shimane.jp\0" -"\xd0\xbe\xd1\x80\xd0\xb3.\xd1\x81\xd1\x80\xd0\xb1\0" -"is-by.us\0" -"manchester.museum\0" -"\xe7\x86\x8a\xe6\x9c\xac.jp\0" -"tonosho.kagawa.jp\0" -"ureshino.mie.jp\0motobu.okinawa.jp\0" -"km.ua\0" -"click\0" -"gov.ac\0sande.vestfold.no\0shop.ro\0" -"gov.ae\0" -"gov.af\0from-mt.com\0from-nd.com\0bryansk.su\0" -"dnsdojo.net\0" -"kamaishi.iwate.jp\0" -"miki.hyogo.jp\0" -"gov.al\0floripa.br\0properties\0" -"bg.it\0neues.museum\0" -"nakijin.okinawa.jp\0" -"gov.ba\0aizumi.tokushima.jp\0" -"gov.ar\0gov.bb\0oe.yamagata.jp\0" -"gov.as\0" -"blog.bo\0asti.it\0wedeploy.io\0" -"gov.au\0zentsuji.kagawa.jp\0is-a-libertarian.com\0" -"gov.bf\0posts-and-telecommunications.museum\0" -"blog.br\0" -"gov.bh\0" -"gov.az\0kaluga.su\0" -"rj.gov.br\0from-wi.com\0" -"shima.mie.jp\0" -"gov.bm\0" -"fukuchiyama.kyoto.jp\0nyc\0" -"shop.pl\0" -"yamamoto.miyagi.jp\0" +"kashiwara.osaka.jp\0rhcloud.com\0" +"\xe7\xb6\xb2\xe7\xb5\xa1.\xe9\xa6\x99\xe6\xb8\xaf\0koeln\0" +"orkanger.no\0read\0" +"infiniti\0" +"pb.gov.br\0" +"horten.no\0" +"us.org\0" +"jio\0" +"dlugoleka.pl\0" +"osaki.miyagi.jp\0synology-ds.de\0" +"industries\0gotdns.org\0" +"pittsburgh.museum\0" +"info\0" +"kuki.saitama.jp\0" +"trentinosued-tirol.it\0yokaichiba.chiba.jp\0nagano.nagano.jp\0taobao\0" +"aeroport.fr\0linde\0" +"dsmynas.org\0" +"showtime\0" +"farm.museum\0" +"zj.cn\0osakikamijima.hiroshima.jp\0shari.hokkaido.jp\0" +"solar\0" +"ishigaki.okinawa.jp\0pa.leg.br\0" +"mad.museum\0name\0degree\0myqnapcloud.com\0" +"\xd0\xb4\xd0\xb5\xd1\x82\xd0\xb8\0" +"avellino.it\0c.cdn77.org\0" +"coupon\0" +"saarland\0" +"ranzan.saitama.jp\0biev\xc3\xa1t.no\0freebox-os.fr\0" +"itami.hyogo.jp\0hokuto.yamanashi.jp\0" +"saka.hiroshima.jp\0palace.museum\0" +"khmelnitskiy.ua\0capital\0" +"kuji.iwate.jp\0" +"koshimizu.hokkaido.jp\0green\0" +"nu.ca\0" +"ah.cn\0" +"ofunato.iwate.jp\0jlc\0qa2.com\0" +"jll\0familyds.net\0" +"donetsk.ua\0" +"\xd8\xa7\xd9\x84\xd8\xac\xd8\xb2\xd8\xa7\xd8\xa6\xd8\xb1\0" +"\xe7\xb6\xb2\xe7\xb5\xa1.cn\0samsung\0" +"k12.vi.us\0verm\xc3\xb6gensberater\0pb.leg.br\0" +"otsuki.yamanashi.jp\0" +"biella.it\0" +"fin.tn\0" +"hirakata.osaka.jp\0database.museum\0" +"airguard.museum\0loseyourip.com\0" +"jor.br\0" +"ip6.arpa\0" +"genoa.it\0" +"luroy.no\0" +"usarts.museum\0jmp\0" +"g\xc3\xa1\xc5\x8bgaviika.no\0" +"domains\0""16-b.it\0" +"b\xc3\xa6rum.no\0" +"servebbs.com\0" +"kamagaya.chiba.jp\0jnj\0" +"my-router.de\0" +"yaizu.shizuoka.jp\0walter\0" +"hyllestad.no\0" +"kai.yamanashi.jp\0" +"beauty\0" +"msk.ru\0" +"0.bg\0vpndns.net\0" +"tomioka.gunma.jp\0botanical.museum\0gjemnes.no\0" +"\xe9\xa3\x9e\xe5\x88\xa9\xe6\xb5\xa6\0" +"aisai.aichi.jp\0ayagawa.kagawa.jp\0mosjoen.no\0schmidt\0" +"noshiro.akita.jp\0kunimi.fukushima.jp\0witd.gov.pl\0" +"chieti.it\0fujisawa.kanagawa.jp\0" +"cityeats\0" +"naturalhistory.museum\0" +"kobierzyce.pl\0jot\0msk.su\0" +"yoshimi.saitama.jp\0giize.com\0forumz.info\0" +"montreal.museum\0sherbrooke.museum\0" +"kawahara.tottori.jp\0intelligence.museum\0" +"rishirifuji.hokkaido.jp\0bern.museum\0statoil\0" +"gov.ac\0joy\0" +"gov.ae\0porsangu.no\0gmbh\0homelinux.net\0" +"gov.af\0ilovecollege.info\0" +"school.za\0" +"iruma.saitama.jp\0" +"hembygdsforbund.museum\0" +"yufu.oita.jp\0zarow.pl\0" +"gov.al\0" +"rio.br\0" +"gov.ba\0guernsey.museum\0" +"gov.ar\0gov.bb\0" +"aerodrome.aero\0gov.as\0beeldengeluid.museum\0" +"gov.au\0" +"gov.bf\0\xe7\xb6\xb2\xe7\xb5\xa1.hk\0" +"matsumae.hokkaido.jp\0" +"gov.bh\0\xd1\x81\xd0\xb0\xd0\xb9\xd1\x82\0" +"gov.az\0azurecontainer.io\0" +"takaoka.toyama.jp\0calvinklein\0" +"gov.bm\0pinb.gov.pl\0" +"gov.bn\0" +"reit\0wellbeingzone.co.uk\0" +"\xe7\xa5\x9e\xe5\xa5\x88\xe5\xb7\x9d.jp\0" "gov.br\0" "gov.bs\0" "gov.bt\0gov.cd\0" -"pt.eu.org\0" -"xbox\0" -"frogans\0" -"gov.by\0" +"gov.by\0children.museum\0gorge.museum\0" "gov.bz\0" -"gov.cl\0terni.it\0computerhistory.museum\0" -"gov.cm\0oamishirasato.chiba.jp\0tawaramoto.nara.jp\0" +"scientist.aero\0" +"gov.cl\0nu.it\0" +"gov.cm\0" "gov.cn\0" -"gov.co\0presidio.museum\0" -"dyn.cosidns.de\0" -"hiratsuka.kanagawa.jp\0" -"karlsoy.no\0" -"yaotsu.gifu.jp\0" +"gov.co\0" +"cloudcontrolapp.com\0" +"legnica.pl\0barsy.bg\0" "gov.cu\0" -"nationalheritage.museum\0" -"flor\xc3\xb8.no\0" +"karacol.su\0" +"aviation.museum\0" "gov.cx\0" "gov.cy\0" -"uppo.gov.pl\0" -"konan.shiga.jp\0" -"gov.dm\0" -"fylkesbibl.no\0" -"gov.do\0" -"br\xc3\xb8nn\xc3\xb8y.no\0" +"ski.no\0" +"gov.dm\0lib.nh.us\0" +"gov.do\0oizumi.gunma.jp\0" +"sb.ua\0" +"kawagoe.saitama.jp\0seljord.no\0" +"wloclawek.pl\0" "gov.ec\0" -"asago.hyogo.jp\0" -"gov.ee\0citi\0" -"gov.eg\0brindisi.it\0\xd0\xbf\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0bplaced.net\0" +"yokoze.saitama.jp\0" +"gov.ee\0" +"gov.eg\0" +"black\0armenia.su\0" "gov.dz\0" -"pe.it\0" -"\xe7\xb5\x84\xe7\xbb\x87.hk\0" -"nes.buskerud.no\0" -"kvam.no\0" -"sumita.iwate.jp\0heimatunduhren.museum\0" -"gov.et\0khmelnytskyi.ua\0" -"city\0" -"prato.it\0sondre-land.no\0" -"chizu.tottori.jp\0trade\0" -"oguni.yamagata.jp\0" -"windows\0" -"shiwa.iwate.jp\0" -"am.gov.br\0catania.it\0nishinomiya.hyogo.jp\0aigo\0" -"to.it\0" -"ftpaccess.cc\0" -"akita.jp\0square7.de\0" -"is-an-actress.com\0" -"gov.ge\0\xe7\xbd\x91\xe5\x9d\x80\0us-gov-west-1.elasticbeanstalk.com\0" -"museum.mv\0" -"gov.gh\0kuroiso.tochigi.jp\0museum.mw\0" -"gov.gi\0vt.it\0pe.kr\0" -"newspaper.museum\0" -"saves-the-whales.com\0customer.enonic.io\0" -"myshopblocks.com\0" -"mining.museum\0" +"kyowa.hokkaido.jp\0kurotaki.nara.jp\0" +"kadogawa.miyazaki.jp\0network\0" +"navy\0" +"yokkaichi.mie.jp\0kounosu.saitama.jp\0mup.gov.pl\0barsy.de\0" +"kihoku.ehime.jp\0takahata.yamagata.jp\0" +"gov.et\0" +"andria-trani-barletta.it\0" +"botanicalgarden.museum\0askim.no\0k12.co.us\0" +"leg.br\0" +"kpmg\0" +"automotive.museum\0hb.cldmail.ru\0" +"catanzaro.it\0" +"audnedaln.no\0" +"jx.cn\0" +"shima.mie.jp\0" +"kfh\0ddns.net\0" +"staples\0" +"gov.ge\0m.se\0" +"gov.gh\0umbria.it\0" +"gov.gi\0" +"blogsite.org\0" +"ah.no\0" "gov.gn\0" -"tokuyama.yamaguchi.jp\0loseyourip.com\0ybo.trade\0" -"museum.no\0" -"one\0" -"gov.gr\0etne.no\0" -"ong\0" -"ternopil.ua\0" -"obira.hokkaido.jp\0kanazawa.ishikawa.jp\0" -"yawata.kyoto.jp\0" -"state.museum\0onl\0" +"bas.it\0rent\0" +"barsy.eu\0" +"gov.gr\0" +"pi.gov.br\0" +"gov.gu\0" +"oyama.tochigi.jp\0" "gov.gy\0" -"is-a-landscaper.com\0" -"gov.hk\0texas.museum\0" -"berlev\xc3\xa5g.no\0museum.om\0" -"kinokawa.wakayama.jp\0likescandy.com\0" -"k\xc3\xa5""fjord.no\0" -"gov.ie\0" -"healthcare\0wellbeingzone.eu\0" -"auto.pl\0neat-url.com\0" -"louvre.museum\0" -"gub.uy\0" -"club.aero\0ooo\0\xd1\x81\xd0\xb0\xd0\xb9\xd1\x82\0" -"gov.il\0" -"gov.in\0oceanographique.museum\0" -"championship.aero\0iris.arpa\0" -"tranibarlettaandria.it\0" -"id.au\0gov.iq\0" -"gov.ir\0" -"gov.is\0kitagata.gifu.jp\0android\0intel\0" -"gov.it\0taito.tokyo.jp\0" -"towada.aomori.jp\0imdb\0square7.ch\0" -"h\xc3\xa5.no\0logoip.de\0" -"o.bg\0" -"british.museum\0" -"karpacz.pl\0avocat.pro\0" -"takayama.nagano.jp\0walmart\0" -"crotone.it\0nesoddtangen.no\0" -"gaivuotna.no\0" -"gov.jo\0oldnavy\0" -"varese.it\0usarts.museum\0" -"takamori.kumamoto.jp\0wakayama.wakayama.jp\0" -"koriyama.fukushima.jp\0" -"gov.kg\0slattum.no\0folldal.no\0" -"r\xc3\xb8""d\xc3\xb8y.no\0" -"gov.ki\0kerrylogistics\0" -"\xd8\xa7\xdb\x8c\xd8\xb1\xd8\xa7\xd9\x86.ir\0bunkyo.tokyo.jp\0is-a-linux-user.org\0" -"minamimaki.nagano.jp\0" -"iwate.jp\0gov.km\0" +"gov.hk\0" +"eng.br\0mp.br\0krakow.pl\0" +"te.it\0merckmsd\0" +"yamada.fukuoka.jp\0iwamizawa.hokkaido.jp\0" +"miyazu.kyoto.jp\0bungoono.oita.jp\0citi\0" +"kouyama.kagoshima.jp\0" +"evje-og-hornnes.no\0mt.eu.org\0" +"aseral.no\0" +"gov.ie\0utwente.io\0" +"ryugasaki.ibaraki.jp\0" +"togane.chiba.jp\0hirata.fukushima.jp\0" +"sayo.hyogo.jp\0" +"iki.nagasaki.jp\0pharmacy\0" +"kia\0" +"gov.il\0ambulance.museum\0" +"\xe7\xbb\x84\xe7\xbb\x87.hk\0" +"gov.in\0" +"wales.museum\0city\0" +"gov.iq\0" +"gov.ir\0ise.mie.jp\0" +"gov.is\0" +"gov.it\0" +"otaru.hokkaido.jp\0" +"kim\0" +"sklep.pl\0szkola.pl\0" +"gov.jo\0gifu.jp\0" +"farmers.museum\0" +"kadoma.osaka.jp\0" +"semine.miyagi.jp\0" +"akiruno.tokyo.jp\0eating-organic.net\0" +"glade\0" +"anjo.aichi.jp\0" +"piacenza.it\0gov.kg\0cable-modem.org\0" +"kiso.nagano.jp\0" +"gov.ki\0" +"pi.leg.br\0barsy.in\0" +"barsy.io\0" +"gov.km\0" "gov.kn\0" -"saskatchewan.museum\0talk\0" -"gov.kp\0k12.me.us\0" +"yaita.tochigi.jp\0tokushima.tokushima.jp\0gov.kp\0jan-mayen.no\0ap-northeast-1.elasticbeanstalk.com\0mytuleap.com\0" "gov.la\0" -"gov.lb\0k\xc3\xa1r\xc3\xa1\xc5\xa1johka.no\0" -"gov.lc\0org\0" -"nakaniikawa.toyama.jp\0pay\0" -"mobi\0" -"gov.ky\0hk.com\0" -"gov.kz\0outsystemscloud.com\0" -"shiga.jp\0gov.lk\0" -"boleslawiec.pl\0\xe6\xb8\xb8\xe6\x88\x8f\0" -"rikuzentakata.iwate.jp\0" -"ap.gov.br\0shibuya.tokyo.jp\0chuo.yamanashi.jp\0v\xc3\xa5ler.hedmark.no\0" +"gov.lb\0" +"gov.lc\0" +"\xe5\xb2\xa9\xe6\x89\x8b.jp\0landes.museum\0" +"tourism.tn\0" +"gov.kw\0" +"v-info.info\0" +"maizuru.kyoto.jp\0gov.ky\0" +"gov.kz\0" +"gov.lk\0" +"barrel-of-knowledge.info\0" +"rest\0" "gov.ma\0" -"gov.lr\0\xe7\xb5\x84\xe7\xb9\x94.tw\0" -"gov.lt\0" -"gov.me\0physio\0qpon\0" -"gov.lv\0" +"gov.lr\0finn\xc3\xb8y.no\0" +"gov.lt\0baidu\0" +"gov.me\0" +"gov.lv\0tana.no\0" "gov.mg\0" -"bozen.it\0napoli.it\0lebtimnetz.de\0" +"judaica.museum\0" "gov.ly\0" -"shimokitayama.nara.jp\0" "gov.mk\0" "gov.ml\0" -"daigo.ibaraki.jp\0" -"olbia-tempio.it\0gov.mn\0moda\0" -"gov.mo\0steam.museum\0" -"ohtawara.tochigi.jp\0gov.mr\0press\0" -"sera.hiroshima.jp\0gov.ms\0nome.pt\0" -"hirakata.osaka.jp\0stavern.no\0" -"iwaki.fukushima.jp\0gov.mu\0\xd9\x87\xd9\x85\xd8\xb1\xd8\xa7\xd9\x87\0" -"gov.mv\0verdal.no\0" -"gov.mw\0gov.ng\0" -"net.ac\0ap.gov.pl\0k12.va.us\0" +"gov.mn\0" +"gov.mo\0" +"ski.museum\0" +"politica.bo\0tagami.niigata.jp\0" +"gov.mr\0" +"gov.ms\0" +"ascolipiceno.it\0" +"ujiie.tochigi.jp\0gov.mu\0" +"gov.mv\0" +"force.museum\0gov.mw\0gov.ng\0" +"ogata.akita.jp\0" "gov.my\0" -"net.ae\0tokamachi.niigata.jp\0medizinhistorisches.museum\0gov.mz\0czeladz.pl\0if.ua\0" -"net.af\0" -"net.ag\0" -"seranishi.hiroshima.jp\0" -"net.ai\0" -"hyllestad.no\0" -"ott\0" -"net.al\0monzabrianza.it\0tsubetsu.hokkaido.jp\0g\xc3\xa1\xc5\x8bgaviika.no\0tushu\0" -"gov.nr\0ga.us\0s3.dualstack.ap-southeast-2.amazonaws.com\0" -"piw.gov.pl\0" -"net.ba\0ueda.nagano.jp\0" -"net.ar\0net.bb\0tm.cy\0" -"net.au\0" -"net.bh\0takinoue.hokkaido.jp\0children.museum\0gov.om\0s3.amazonaws.com\0" -"sa.gov.au\0" -"net.az\0" -"pet\0" -"net.bm\0" -"fujieda.shizuoka.jp\0plantation.museum\0" -"net.bo\0\xe9\x95\xb7\xe9\x87\x8e.jp\0mikawa.yamagata.jp\0ovh\0" -"net.br\0inzai.chiba.jp\0" -"net.bs\0gov.ph\0" -"net.bt\0rybnik.pl\0\xe3\x81\xbf\xe3\x82\x93\xe3\x81\xaa\0" -"komagane.nagano.jp\0" -"friuli-ve-giulia.it\0gov.pk\0" -"cz.it\0masoy.no\0gov.pl\0" -"minamifurano.hokkaido.jp\0otsuka\0ubank\0" -"net.ci\0gov.pn\0" -"net.bz\0" -"valle-d-aosta.it\0sibenik.museum\0" +"gov.mz\0\xd0\xbe\xd1\x80\xd0\xb3\0" +"sassari.it\0" +"off.ai\0pueblo.bo\0dnsiskinky.com\0" +"\xd1\x83\xd0\xbf\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0" +"hellas.museum\0virtual.museum\0" +"york.museum\0gov.nr\0" +"s3-ap-northeast-1.amazonaws.com\0redirectme.net\0" +"amfam\0" +"toyama.jp\0" +"baidar.no\0roan.no\0doomdns.com\0" +"broadway\0" +"aomori.jp\0" +"carraramassa.it\0" +"building.museum\0" +"gov.om\0" +"kumejima.okinawa.jp\0" +"dolls.museum\0" +"yamagata.yamagata.jp\0evenes.no\0" +"k12.al.us\0" +"pe.gov.br\0minami-alps.yamanashi.jp\0" +"gov.ph\0" +"shimada.shizuoka.jp\0nachikatsuura.wakayama.jp\0interactive.museum\0" +"kamifurano.hokkaido.jp\0" +"gov.pk\0coupons\0report\0" +"gov.pl\0k12.mo.us\0exchange\0" +"tysvar.no\0gov.pn\0" +"frontier\0" "gov.qa\0" -"net.cm\0kitashiobara.fukushima.jp\0gov.pr\0dyn-vpn.de\0" -"net.cn\0gov.ps\0" -"net.co\0gov.pt\0" -"avianca\0" -"open\0" +"misaki.okayama.jp\0gov.pr\0mlbfan.org\0" +"shop.ht\0kvinesdal.no\0gov.ps\0" +"k.bg\0shop.hu\0gov.pt\0fh.se\0" +"tsukuba.ibaraki.jp\0lier.no\0" +"brussel.museum\0" +"\xe5\xa4\xa7\xe5\x88\x86.jp\0kpn\0" "gov.py\0" -"net.cu\0" -"friuli-venezia-giulia.it\0shinjo.yamagata.jp\0\xe5\xa4\xa7\xe4\xbc\x97\xe6\xb1\xbd\xe8\xbd\xa6\0" -"net.cw\0" -"masaki.ehime.jp\0" -"net.cy\0id.ir\0" -"tm.fr\0minamioguni.kumamoto.jp\0phd\0" -"tran\xc3\xb8y.no\0" -"net.dm\0komono.mie.jp\0television.museum\0" -"motorcycle.museum\0" -"net.do\0fuettertdasnetz.de\0" -"matsushima.miyagi.jp\0" -"net.ec\0ybo.party\0" -"faith\0is-a-soxfan.org\0" -"cc.nm.us\0spiegel\0" -"rr.gov.br\0" -"net.eg\0soja.okayama.jp\0" -"tateyama.toyama.jp\0rsc.cdn77.org\0" -"net.dz\0" -"pid\0draydns.de\0" -"gov.sa\0" -"gov.sb\0" -"gov.rs\0gov.sc\0" -"mn.it\0tokyo.jp\0gulen.no\0gov.sd\0cc.pr.us\0" -"gov.ru\0" -"stufftoread.com\0" -"skjervoy.no\0gov.rw\0gov.sg\0" -"ouda.nara.jp\0gov.sh\0vt.us\0" -"net.et\0neyagawa.osaka.jp\0principe.st\0" -"pin\0debian.net\0" -"blogsyte.com\0" -"obihiro.hokkaido.jp\0gov.sl\0" -"komaki.aichi.jp\0" -"pc.it\0" -"suifu.ibaraki.jp\0biev\xc3\xa1t.no\0" -"niiza.saitama.jp\0" -"immo\0" -"tm.hu\0tama.tokyo.jp\0" -"gov.st\0hyatt\0feste-ip.net\0" -"pordenone.it\0" -"wloclawek.pl\0gov.sx\0" -"gov.sy\0" -"net.ge\0gov.tj\0" -"rs.gov.br\0sc.gov.br\0" -"net.gg\0gov.tl\0" -"gov.tm\0" -"harvestcelebration.museum\0gov.tn\0" -"s\xc3\xb8mna.no\0gov.to\0" -"net.gl\0oshima.yamaguchi.jp\0gov.ua\0" -"id.lv\0gov.tr\0" -"net.gn\0" -"gov.tt\0" -"net.gp\0id.ly\0" -"net.gr\0gov.tw\0" -"s3-eu-west-2.amazonaws.com\0" -"net.gt\0kanmaki.nara.jp\0" -"gov.uk\0servesarcasm.com\0" -"forlicesena.it\0vr.it\0" -"lel.br\0net.gy\0alipay\0" -"film.hu\0" -"net.hk\0chiba.jp\0" -"yamakita.kanagawa.jp\0" -"net.hn\0gov.vc\0" -"from-oh.com\0" -"gov.ve\0barcelona\0" -"utashinai.hokkaido.jp\0" -"loabat.no\0" -"net.ht\0net.id\0" -"tm.km\0lib.ms.us\0lib.nc.us\0raid\0" -"quebec.museum\0" -"hole.no\0gov.vn\0gmbh\0" -"daegu.kr\0" -"net.il\0final\0" -"bc.ca\0net.im\0ami.ibaraki.jp\0" -"net.in\0tsuruta.aomori.jp\0zoological.museum\0" -"fhsk.se\0fhapp.xyz\0" -"boavista.br\0net.iq\0guitars\0" -"net.ir\0" -"net.is\0" -"kamikawa.hyogo.jp\0" -"net.je\0nantan.kyoto.jp\0" -"taxi\0" -"pnc\0" -"tm.mc\0giize.com\0" -"fetsund.no\0ing.pa\0gov.ws\0broadway\0" -"net.jo\0air.museum\0melbourne\0" -"yamada.toyama.jp\0tm.mg\0" "lutsk.ua\0" -"fm.br\0tjome.no\0nikolaev.ua\0from-dc.com\0" -"m.bg\0" -"net.kg\0" -"hadano.kanagawa.jp\0" -"net.ki\0" -"yoka.hyogo.jp\0idrett.no\0insure\0" -"katsushika.tokyo.jp\0" -"net.kn\0bounty-full.com\0" -"shiroishi.miyagi.jp\0" -"tamatsukuri.ibaraki.jp\0net.la\0" -"net.lb\0" -"net.lc\0" -"moka.tochigi.jp\0dynamisches-dns.de\0" -"tm.no\0" -"net.ky\0" -"net.kz\0ivgu.no\0" -"net.lk\0" -"gov.za\0" -"sandnessj\xc3\xb8""en.no\0" -"s3.ap-south-1.amazonaws.com\0" -"aosta-valley.it\0\xd0\xbe\xd0\xb4.\xd1\x81\xd1\x80\xd0\xb1\0" -"shinyoshitomi.fukuoka.jp\0net.ma\0pc.pl\0williamhill\0" -"\xe7\xa6\x8f\xe5\xb2\xa1.jp\0net.lr\0" -"isernia.it\0" -"frosinone.it\0" -"net.me\0" -"rn.gov.br\0net.lv\0kwpsp.gov.pl\0" -"shiogama.miyagi.jp\0" -"s\xc3\xb8r-aurdal.no\0gov.zm\0" -"net.ly\0" -"net.mk\0kutno.pl\0" -"net.ml\0dnsalias.net\0" -"valer.ostfold.no\0" -"net.mo\0" -"o.se\0" -"gov.zw\0" -"net.ms\0" -"net.mt\0manx.museum\0lur\xc3\xb8y.no\0" -"net.mu\0tm.pl\0" -"net.mv\0net.nf\0" -"net.mw\0net.ng\0sells-it.net\0" -"net.mx\0mg.leg.br\0" -"net.my\0net.ni\0" -"net.mz\0" -"trentinosued-tirol.it\0" -"cnt.br\0alstom\0" -"photography.museum\0" -"bungoono.oita.jp\0smile\0" -"mochizuki.nagano.jp\0norton\0" -"net.nr\0s3.ap-northeast-2.amazonaws.com\0" -"geekgalaxy.com\0" -"ro.gov.br\0jan-mayen.no\0pro\0telefonica\0" -"institute\0" -"yokaichiba.chiba.jp\0miyashiro.saitama.jp\0net.nz\0chanel\0" -"annefrank.museum\0franziskaner.museum\0pru\0" -"info\0yono.saitama.jp\0net.om\0" -"arakawa.saitama.jp\0" -"caseih\0" -"net.pa\0management\0" -"claims\0" -"stuttgart.museum\0net.pe\0" -"net.ph\0tm.ro\0" -"id.us\0" -"gifu.jp\0net.pk\0" -"net.pl\0" -"net.pn\0tm.se\0" -"\xd8\xb9\xd8\xb1\xd8\xa8\0" +"*.uberspace.de\0" +"barsycenter.com\0" +"mukawa.hokkaido.jp\0stalbans.museum\0" +"okinoshima.shimane.jp\0" +"kawakita.ishikawa.jp\0" +"udi.br\0" +"gwiddle.co.uk\0" +"krd\0lat\0" +"barsy.online\0" +"hasama.oita.jp\0koebenhavn.museum\0" +"higashiosaka.osaka.jp\0gov.sa\0law\0" +"gov.sb\0my.eu.org\0" +"sanjo.niigata.jp\0gov.rs\0gov.sc\0" +"susaki.kochi.jp\0porsanger.no\0gov.sd\0" +"aga.niigata.jp\0gov.ru\0" +"obira.hokkaido.jp\0" +"gov.rw\0gov.sg\0" +"gov.sh\0" +"pe.leg.br\0" +"aichi.jp\0te.ua\0" +"gov.sl\0" +"okinawa.okinawa.jp\0coach\0" +"tjeldsund.no\0" +"shoo.okayama.jp\0" +"gov.st\0" +"valle\xcc\x81""eaoste.it\0" +"gov.sx\0" +"gov.sy\0" +"gov.tj\0" +"gov.tl\0" +"laspezia.it\0kragero.no\0gov.tm\0" +"gov.tn\0" +"gov.to\0" +"gov.ua\0" +"gov.tr\0" +"k12.fl.us\0" +"davvenj\xc3\xa1rga.no\0konskowola.pl\0gov.tt\0" +"fukushima.hokkaido.jp\0boomla.net\0" +"her\xc3\xb8y.nordland.no\0" +"gov.tw\0" +"mywire.org\0" +"is-a-candidate.org\0" +"boehringer\0" +"uto.kumamoto.jp\0gov.uk\0" +"ena.gifu.jp\0pa.gov.pl\0lds\0" +"kv\xc3\xa6nangen.no\0" +"kvafjord.no\0gov.vc\0visa\0" +"loginto.me\0" +"gov.ve\0" +"zoological.museum\0" +"trentin-sud-tirol.it\0sandoy.no\0panasonic\0" +"salat.no\0futuremailing.at\0" +"gov.vn\0" +"bardu.no\0" +"scjohnson\0" +"inabe.mie.jp\0aigo\0" +"ibaraki.jp\0" +"ns.ca\0" +"land\0" +"mandal.no\0now-dns.org\0" +"bokn.no\0" +"\xe7\xa7\xbb\xe5\x8a\xa8\0s3-website-sa-east-1.amazonaws.com\0" +"fukumitsu.toyama.jp\0stada\0" +"recht.pro\0" +"asahi.chiba.jp\0" +"vibo-valentia.it\0" +"kh.ua\0" +"nasu.tochigi.jp\0leka.no\0sorfold.no\0gov.ws\0yombo.me\0" +"tourism.pl\0" +"h\xc3\xa1""bmer.no\0onion\0" +"abbvie\0" +"yamaxun\0" +"tra.kp\0gs.aa.no\0net-freaks.com\0" +"kujukuri.chiba.jp\0fukagawa.hokkaido.jp\0" +"nl.eu.org\0" +"takaharu.miyazaki.jp\0viva\0" +"mydatto.com\0" +"is.it\0lifestyle\0" +"yamanakako.yamanashi.jp\0" +"itano.tokushima.jp\0" +"cc.in.us\0" +"zgorzelec.pl\0" +"br.com\0" +"far.br\0lib.ee\0notodden.no\0" +"gov.za\0vivo\0" +"act.au\0pr.gov.br\0nanbu.tottori.jp\0" +"moseushi.hokkaido.jp\0" +"padua.it\0susono.shizuoka.jp\0" +"ciscofreak.com\0" +"karm\xc3\xb8y.no\0" +"vang.no\0" "haibara.shizuoka.jp\0" -"net.qa\0" -"azumino.nagano.jp\0sarpsborg.no\0net.pr\0" -"hizen.saga.jp\0net.ps\0" -"net.pt\0s3.ca-central-1.amazonaws.com\0" -"oristano.it\0" -"stathelle.no\0" -"moto\0" -"ruovat.no\0za.com\0" -"net.py\0pub\0" -"technology.museum\0" -"otoineppu.hokkaido.jp\0mn.us\0" -"rocks\0" -"fm.it\0isa.us\0" -"nango.fukushima.jp\0lifestyle\0" -"lund.no\0" -"oyamazaki.kyoto.jp\0kawajima.saitama.jp\0" -"vadso.no\0" -"gotsu.shimane.jp\0" -"\xe7\xb5\x84\xe7\xb9\x94.hk\0net.sa\0" -"net.sb\0" -"net.sc\0" -"net.sd\0" -"antiques.museum\0net.ru\0" -"finn\xc3\xb8y.no\0net.rw\0net.sg\0" -"net.sh\0\xec\x82\xbc\xec\x84\xb1\0" -"pwc\0" -"net.sl\0" -"net.so\0" -"kawai.nara.jp\0" -"minamiminowa.nagano.jp\0muika.niigata.jp\0lanbib.se\0" -"al.eu.org\0" -"yoshida.saitama.jp\0net.st\0farmers\0from-vt.com\0" -"pisa.it\0yamato.kanagawa.jp\0" -"net.th\0" -"minamisanriku.miyagi.jp\0net.sy\0is-a-personaltrainer.com\0" -"net.tj\0" -"technology\0" -"pa.it\0" -"trentinosuedtirol.it\0net.tm\0" -"net.tn\0" -"avoues.fr\0ogose.saitama.jp\0net.to\0" -"chikushino.fukuoka.jp\0" -"net.ua\0" -"net.tr\0" -"witd.gov.pl\0" -"net.tt\0" -"kg.kr\0" -"net.tw\0" -"railroad.museum\0toray\0" -"yura.wakayama.jp\0page\0hosting-cluster.nl\0" -"hjartdal.no\0net.uk\0cloudns.biz\0" -"computer.museum\0net.vc\0" -"net.ve\0" -"stj\xc3\xb8rdal.no\0" -"ringerike.no\0akdn\0scholarships\0" -"net.uy\0net.vi\0" -"miho.ibaraki.jp\0net.uz\0" -"orsta.no\0" -"net.vn\0" -"taranto.it\0fm.no\0sortland.no\0lixil\0" -, - -"kazo.saitama.jp\0applinzi.com\0" -"aeroport.fr\0schmidt\0\xd0\xbe\xd0\xbd\xd0\xbb\xd0\xb0\xd0\xb9\xd0\xbd\0" -"v\xc3\xa5g\xc3\xa5.no\0\xe5\x95\x86\xe6\xa0\x87\0" -"oita.jp\0markets\0" -"net.vu\0" -"broker\0" -"lib.ne.us\0" -"univ.sn\0tm.za\0" -"from-la.net\0" -"ora.gunma.jp\0" -"k12.az.us\0\xe3\x82\xbb\xe3\x83\xbc\xe3\x83\xab\0" -"\xd8\xa7\xd8\xaa\xd8\xb5\xd8\xa7\xd9\x84\xd8\xa7\xd8\xaa\0" -"ichiba.tokushima.jp\0" -"net.ws\0" -"contagem.br\0" -"vlaanderen\0" -"donetsk.ua\0\xd9\x85\xd9\x84\xd9\x8a\xd8\xb3\xd9\x8a\xd8\xa7\0" -"ichihara.chiba.jp\0" -"dsmynas.org\0" -"\xe8\x87\xba\xe7\x81\xa3\0" -"trentinostirol.it\0" -"hanggliding.aero\0" -"ekloges.cy\0insurance\0daplie.me\0" -"ryokami.saitama.jp\0\xd0\xb0\xd0\xba.\xd1\x81\xd1\x80\xd0\xb1\0" -"usa.oita.jp\0" -"ashiya.fukuoka.jp\0" -"k.bg\0" -"storage\0" -"mandal.no\0" -"inashiki.ibaraki.jp\0" -"weber\0" -"arita.saga.jp\0" -"krokstadelva.no\0" -"lib.wa.us\0net.za\0" -"walter\0" -"zero\0" -"maizuru.kyoto.jp\0" -"kumakogen.ehime.jp\0" -"tsurugashima.saitama.jp\0" -"torino.museum\0" -"environment.museum\0" -"usculture.museum\0" -"shichinohe.aomori.jp\0net.zm\0" -"ohi.fukui.jp\0" -"k12.mi.us\0" -"iwi.nz\0" -"serveexchange.com\0" -"a.ssl.fastly.net\0" -"dd-dns.de\0" -"se.gov.br\0\xda\x80\xd8\xa7\xd8\xb1\xd8\xaa\0" -"rodeo\0" -"botanical.museum\0" -"kawaminami.miyazaki.jp\0m.se\0" -"tsumagoi.gunma.jp\0" -"barrel-of-knowledge.info\0nodum.co\0" -"feedback\0" -"kasahara.gifu.jp\0" -"calvinklein\0" -"gives\0voting\0" -"roma.museum\0" -"as.us\0" -"nagano.jp\0" -"capetown\0" -"agents.aero\0furukawa.miyagi.jp\0" -"h\xc3\xb8nefoss.no\0from-nm.com\0" -"kiyokawa.kanagawa.jp\0muosat.no\0" -"natura\0" -"higashiura.aichi.jp\0gallup\0" -"lcube-server.de\0" -"alwaysdata.net\0" -"cci.fr\0versicherung\0" -"gripe\0" -"kahoku.yamagata.jp\0jobs.tt\0" -"jamison.museum\0dunlop\0nodum.io\0" -"insurance.aero\0" -"jelenia-gora.pl\0" -"sukagawa.fukushima.jp\0" -"\xe9\x95\xb7\xe5\xb4\x8e.jp\0" -"rennebu.no\0" -"rugby\0" -"pol.dz\0" -"aq.it\0ba.it\0kitakata.fukushima.jp\0" -"\xe9\x9d\x99\xe5\xb2\xa1.jp\0nachikatsuura.wakayama.jp\0" -"iselect\0kicks-ass.net\0" -"strand.no\0" -"svelvik.no\0" -"inc.hk\0" -"kunohe.iwate.jp\0" -"show.aero\0adv.br\0" -"oslo.no\0map.fastlylb.net\0" -"unazuki.toyama.jp\0" -"leitungsen.de\0" -"takahashi.okayama.jp\0origins\0" -"pa.us\0" -"asso.fr\0nerima.tokyo.jp\0volyn.ua\0" -"station.museum\0" -"kawanehon.shizuoka.jp\0" -"lima.zone\0" -"sa.gov.pl\0" -"asahikawa.hokkaido.jp\0" -"googleapis.com\0" -"ancona.it\0fermo.it\0" -"pars\0" -"hongo.hiroshima.jp\0sakai.osaka.jp\0" -"asso.gp\0dr\xc3\xb8""bak.no\0" -"red\0ownprovider.com\0" -"tec.ve\0" -"decorativearts.museum\0" -"akune.kagoshima.jp\0ren\0jambyl.su\0" -"kagami.kochi.jp\0dentist\0" -"oki.fukuoka.jp\0oyabe.toyama.jp\0accountants\0" -"tobetsu.hokkaido.jp\0clinic\0" -"qvc\0" -"eco.br\0pol.ht\0" -"gunma.jp\0" -"asso.ht\0naamesjevuemie.no\0" -"cc.sc.us\0" -"toride.ibaraki.jp\0" -"artdeco.museum\0wielun.pl\0training\0" -"makurazaki.kagoshima.jp\0" -"aip.ee\0kl\xc3\xa6""bu.no\0" -"club.tw\0khmelnitskiy.ua\0" -"kakogawa.hyogo.jp\0ebino.miyazaki.jp\0cc.tx.us\0" -"systems\0cupcake.is\0" -"art.br\0nhlfan.net\0" -"palmsprings.museum\0" -"forex\0" -"airforce\0star\0" -"asso.bj\0" -"university.museum\0" -"shizuoka.shizuoka.jp\0lib.ia.us\0" -"chita.aichi.jp\0ryuoh.shiga.jp\0coal.museum\0" -"is-a-financialadvisor.com\0" -"usdecorativearts.museum\0" -"valle.no\0groks-this.info\0" -"asso.ci\0sogndal.no\0" -"chiropractic.museum\0" -"\xe7\xbd\x91\xe7\xab\x99\0" -"shibecha.hokkaido.jp\0" -"maryland.museum\0natuurwetenschappen.museum\0" -"art.do\0yonabaru.okinawa.jp\0" -"vanylven.no\0" -"kure.hiroshima.jp\0" -"jpn.com\0" -"pl.eu.org\0" -"taiwa.miyagi.jp\0other.nf\0apps.lair.io\0" -"siena.it\0gyokuto.kumamoto.jp\0americanart.museum\0ril\0" -"art.dz\0lecco.it\0" -"\xe4\xb8\xad\xe5\x9b\xbd\0" -"shikaoi.hokkaido.jp\0rio\0realm.cz\0" -"wiki.bo\0otama.fukushima.jp\0yamagata.nagano.jp\0rip\0" -"wiki.br\0holdings\0solar\0" -"tsukumi.oita.jp\0inder\xc3\xb8y.no\0" -"campidano-medio.it\0hyundai\0" -"okinawa.jp\0est.pr\0" -"itano.tokushima.jp\0north-kazakhstan.su\0" -"tohnosho.chiba.jp\0serveblog.net\0" -"\xe4\xb8\xad\xe5\x9c\x8b\0" -"asso.dz\0kalmykia.su\0" -"lorenskog.no\0" -"kamitsue.oita.jp\0s3.dualstack.ap-northeast-2.amazonaws.com\0" -"i.bg\0supplies\0" -"nakamichi.yamanashi.jp\0dodge\0" -"matsue.shimane.jp\0from-ok.com\0" -"\xe7\xb6\xb2\xe7\xb5\xa1.cn\0" -"sukumo.kochi.jp\0k12.gu.us\0" -"drud.io\0" -"kpmg\0" -"rennes\xc3\xb8y.no\0" -"r\xc3\xa6lingen.no\0" -"molise.it\0kikonai.hokkaido.jp\0" -"lombardy.it\0" -"fi.cr\0" -"club\0" -"erotica.hu\0uchiko.ehime.jp\0" -"hatoyama.saitama.jp\0" -"hn.cn\0" -"botanicalgarden.museum\0ap-southeast-2.elasticbeanstalk.com\0gdynia.pl\0" -"astronomy.museum\0" -"mordovia.su\0" -"vagan.no\0" -"tuva.su\0" -"komatsushima.tokushima.jp\0" -"square.museum\0sandnes.no\0" -"miyazu.kyoto.jp\0" -"dyndns-free.com\0" -"js.cn\0" -"ce.gov.br\0ibigawa.gifu.jp\0uenohara.yamanashi.jp\0" -"funabashi.chiba.jp\0okoppe.hokkaido.jp\0olayan\0" -"name\0" -"art.ht\0andasuolo.no\0" -"plurinacional.bo\0" -"inami.toyama.jp\0" -"owani.aomori.jp\0matsuura.nagasaki.jp\0" -"takikawa.hokkaido.jp\0kalmykia.ru\0" -"nishikawa.yamagata.jp\0salvadordali.museum\0k.se\0" -"cv.ua\0" -"from-il.com\0" -"grondar.za\0" -"balsfjord.no\0" -"klabu.no\0" -"openair.museum\0adv.mz\0" -"portal.museum\0events\0" -"gen.mi.us\0" -"gotdns.org\0lima-city.rocks\0" -"naka.ibaraki.jp\0yahaba.iwate.jp\0" -"bergamo.it\0aquarelle\0" -"farmers.museum\0maserati\0mordovia.ru\0" -"tsuruga.fukui.jp\0" -"utazu.kagawa.jp\0kin.okinawa.jp\0" -"verisign\0" -"tokai.aichi.jp\0osen.no\0" -"joburg\0" -"\xe7\xb6\xb2\xe7\xb5\xa1.hk\0friulive-giulia.it\0lucania.it\0narvik.no\0vinnytsia.ua\0" -"gallery.museum\0" -"historisches.museum\0extraspace\0" -"mihama.mie.jp\0" -"nishiwaki.hyogo.jp\0gangaviika.no\0tienda\0" -"schaeffler\0" -"ao.it\0" -"toga.toyama.jp\0s\xc3\xb8rum.no\0" -"gleeze.com\0" -"kamiamakusa.kumamoto.jp\0gop.pk\0isa-hockeynut.com\0cust.dev.thingdust.io\0" -"ct.it\0" -"hashikami.aomori.jp\0" -"hyuga.miyazaki.jp\0wallonie.museum\0sap\0" -"dielddanuorri.no\0" -"skj\xc3\xa5k.no\0pol.tr\0" -"fi.it\0sas\0" -"is-into-games.com\0" -"\xe1\x83\x92\xe1\x83\x94\0dyndns-remote.com\0" -"broker.aero\0" -"nagareyama.chiba.jp\0askoy.no\0sbi\0" -"monza-brianza.it\0msk.ru\0" -"kashima.ibaraki.jp\0koza.wakayama.jp\0" -"bushey.museum\0ally\0cancerresearch\0" -"oseto.nagasaki.jp\0sca\0" -"nes.akershus.no\0giving\0scb\0" -"taka.hyogo.jp\0vn.ua\0sbs\0" -"maison\0" -"potenza.it\0" -"s\xc3\xa1lat.no\0" -"msk.su\0" -"stalowa-wola.pl\0" -"agency\0" -"saiki.oita.jp\0" -"science\0" -"kainan.tokushima.jp\0" -"mukawa.hokkaido.jp\0roan.no\0" -"komoro.nagano.jp\0" -"achi.nagano.jp\0moriguchi.osaka.jp\0" +"gov.zm\0lotte\0" +"kiho.mie.jp\0valley.museum\0" +"cambridge.museum\0" +"mol.it\0vagan.no\0glass\0" +"info.gu\0" +"takayama.nagano.jp\0" +"ox.rs\0" +"gov.zw\0lotto\0" +"zlg.br\0bungotakada.oita.jp\0" +"dabur\0kyoto\0" +"hawaii.museum\0" +"ninohe.iwate.jp\0" +"info.ht\0" +"info.hu\0" +"makinohara.shizuoka.jp\0" +"dazaifu.fukuoka.jp\0" +"bellevue.museum\0nativeamerican.museum\0theater\0" +"llc\0" +"k12.md.us\0courses\0" +"tas.gov.au\0shiki.saitama.jp\0eu.meteorapp.com\0" +"educator.aero\0" +"info.et\0sakura\0" +"egersund.no\0homelinux.org\0js.org\0" +"is-a-techie.com\0pr.leg.br\0" +"mobile\0" +"field.museum\0hamaroy.no\0" +"production.aero\0takamatsu.kagawa.jp\0wallonie.museum\0philips\0" +"ostroda.pl\0tgory.pl\0" +"\xd0\xb8\xd0\xba\xd0\xbe\xd0\xbc.museum\0" +"basketball\0" +"emb.kw\0" +"idf.il\0securitytactics.com\0" +"manaus.br\0hof.no\0" +"austrheim.no\0" +"kred\0" +"noheji.aomori.jp\0my-vigor.de\0" +"firenze.it\0" +"dnsdojo.com\0" +"giehtavuoatna.no\0" +"inder\xc3\xb8y.no\0" +"mobily\0" +"tiaa\0" +"azumino.nagano.jp\0nesset.no\0" +"ng.eu.org\0dsmynas.net\0" +"hn.cn\0\xe0\xac\xad\xe0\xac\xbe\xe0\xac\xb0\xe0\xac\xa4\0" +"\xe7\xa6\x8f\xe4\xba\x95.jp\0kashiwazaki.niigata.jp\0" +"no-ip.ca\0" +"info.cx\0" +"hakata.fukuoka.jp\0" +"m\xc3\xa5s\xc3\xb8y.no\0lib.nj.us\0" +"trentinosu\xcc\x88""d-tirol.it\0" +"info.ec\0higashimurayama.tokyo.jp\0stateofdelaware.museum\0" +"yachiyo.ibaraki.jp\0" +"tamakawa.fukushima.jp\0" +"parma.it\0firewall-gateway.com\0" +"psc.br\0lol\0" +"cn.it\0" +"cloud\0servemp3.com\0" +"\xe7\xbb\x84\xe7\xbb\x87\xe6\x9c\xba\xe6\x9e\x84\0" +"nsn.us\0azure-mobile.net\0" +"aurskog-holand.no\0" +"eniwa.hokkaido.jp\0" +"info.bb\0parti.se\0" +"info.at\0" +"info.au\0gs.vf.no\0" +"bari.it\0k12.de.us\0" +"lpl\0" +"palermo.it\0farmstead.museum\0" +"info.az\0familyds.org\0" +"engerdal.no\0" +"info.bo\0inf.br\0" +"\xd8\xb9\xd8\xb1\xd8\xa8\0" +"nakadomari.aomori.jp\0" +"minamiechizen.fukui.jp\0k.se\0" +"lib.or.us\0" +"north.museum\0rahkkeravju.no\0" +"mallorca.museum\0" +"man\0" +"chonan.chiba.jp\0bo.nordland.no\0" +"hayashima.okayama.jp\0map\0paris.eu.org\0" +"lavagis.no\0\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\x82\xe0\xa6\xb2\xe0\xa6\xbe\0mba\0" +"bifuka.hokkaido.jp\0" +"info.co\0meiwa.mie.jp\0" +"b\xc3\xa1id\xc3\xa1r.no\0" +"inf.cu\0" +"ozu.ehime.jp\0storage\0from-oh.com\0" +"tx.us\0" +"lima-city.rocks\0" +"nagasu.kumamoto.jp\0" +"ss.it\0" +"okawa.kochi.jp\0" +"trapani.it\0" +"izumi.kagoshima.jp\0svelvik.no\0" +"rightathome\0" +"storfjord.no\0" +"tajimi.gifu.jp\0" +"otari.nagano.jp\0ltd\0" +"lubin.pl\0" +"yahaba.iwate.jp\0uzhgorod.ua\0" +"davvenjarga.no\0" +"engine.aero\0" +"is-a-caterer.com\0" +"huissier-justice.fr\0fjaler.no\0" +"kasumigaura.ibaraki.jp\0" +"cc.hi.us\0" +"reggiocalabria.it\0med\0" +"shimonoseki.yamaguchi.jp\0" +"rygge.no\0" +"press.cy\0static-access.net\0" +"from-md.com\0" +"mantova.it\0" +"men\0" +"l\xc3\xb8""dingen.no\0" +"lib.ga.us\0" +"valle\xcc\x81""e-aoste.it\0childrens.museum\0" +"uozu.toyama.jp\0" +"matsumoto.nagano.jp\0oita.oita.jp\0" +"shop.ro\0" +"dyndns-home.com\0" +"balsan-suedtirol.it\0hyundai\0" +"k12.vt.us\0" +"natuurwetenschappen.museum\0" +"kvits\xc3\xb8y.no\0" +"sekikawa.niigata.jp\0piw.gov.pl\0" +"stockholm\0tkmaxx\0" +"santacruz.museum\0" +"realestate\0dd-dns.de\0" +"\xe7\xb6\xb2\xe7\xbb\x9c.hk\0" +"sdn.gov.pl\0" +"nowaruda.pl\0nat.tn\0cartier\0mangyshlak.su\0" +"shop.pl\0" +"emergency.aero\0" +"shonai.yamagata.jp\0" +"sakai.ibaraki.jp\0" +"shangrila\0" +"development.run\0" +"office-on-the.net\0" +"tenkawa.nara.jp\0" +"sweetpepper.org\0" +"yomitan.okinawa.jp\0bus.museum\0philadelphiaarea.museum\0po.gov.pl\0" +"\xe5\xb1\xb1\xe5\x8f\xa3.jp\0bamble.no\0" +"from-ca.com\0" +"friuli-vegiulia.it\0" +"tv.bb\0" +"aquila.it\0" +"art.br\0mil\0" +"mn.it\0" +"ponpes.id\0" +"mit\0fastpanel.direct\0" +"cc.mi.us\0vlaanderen\0" +"tv.bo\0gold\0" +"is-a-hard-worker.com\0pantheonsite.io\0" +"zao.miyagi.jp\0golf\0" +"tv.br\0cn.ua\0" +"leclerc\0" +"\xd8\xb4\xd8\xa8\xd9\x83\xd8\xa9\0" +"johana.toyama.jp\0" +"lipsy\0" +"k12.ne.us\0" +"roma.it\0jaworzno.pl\0lib.la.us\0" +"kusu.oita.jp\0fuchu.tokyo.jp\0" +"i.bg\0" +"\xd8\xb3\xd9\x88\xd8\xb1\xd9\x8a\xd8\xa7\0clinique\0beep.pl\0" +"art.do\0" +"\xd8\xb3\xd9\x88\xd8\xb1\xd9\x8a\xd8\xa9\0" +"inf.mk\0" +"pesarourbino.it\0" +"bi.it\0kitayama.wakayama.jp\0baths.museum\0" +"saotome.st\0\xe4\xbd\x9b\xe5\xb1\xb1\0" +"mlb\0" +"jus.br\0" +"art.dz\0" +"trentino-sued-tirol.it\0" +"coal.museum\0myds.me\0" +"happou.akita.jp\0info.ve\0" +"tysv\xc3\xa6r.no\0" +"cc.pa.us\0" +"greta.fr\0" +"stargard.pl\0mma\0" +"aid.pl\0" +"info.vn\0mls\0" +"friuli-veneziagiulia.it\0shunan.yamaguchi.jp\0" +"elasticbeanstalk.com\0" +"goog\0" +"lib.ny.us\0pioneer\0" +"chuo.osaka.jp\0" +"ariake.saga.jp\0" +"xnbay.com\0" +"trentino-stirol.it\0usuki.oita.jp\0" +"istmein.de\0" +"shiraoka.saitama.jp\0olkusz.pl\0" +"s3-website.us-east-2.amazonaws.com\0" +"rep.kp\0" +"tips\0" +"ora.gunma.jp\0timekeeping.museum\0isa-hockeynut.com\0" +"uvic.museum\0" +"nord-odal.no\0" +"ayabe.kyoto.jp\0" +"rn.it\0gokase.miyazaki.jp\0info.tn\0" +"folkebibl.no\0moe\0own.pm\0" +"info.tr\0cc.ri.us\0" +"caltanissetta.it\0info.tt\0moi\0" +"shikabe.hokkaido.jp\0" +"mom\0dyndns.ddnss.de\0" +"art.ht\0intl.tn\0" +"info.tz\0" +"trustee.museum\0" +"wakasa.tottori.jp\0" +"theatre\0" +"mov\0statefarm\0" +"higashihiroshima.hiroshima.jp\0" +"agano.niigata.jp\0" +"hiranai.aomori.jp\0opencraft.hosting\0" +"shiksha\0" +"\xc3\xa1lt\xc3\xa1.no\0" +"kolobrzeg.pl\0" +"cci.fr\0fujieda.shizuoka.jp\0" +"nab\0" +"info.ro\0" +"tv.im\0" +"presidio.museum\0" +"info.sd\0" +"berlev\xc3\xa5g.no\0" +"tv.it\0" +"britishcolumbia.museum\0\xd1\x80\xd1\x83\xd1\x81\0" +"ybo.party\0" +"passagens\0trading\0" +"date.fukushima.jp\0futaba.fukushima.jp\0tokashiki.okinawa.jp\0iveco\0nba\0" +"alstom\0barcelona\0" +"kamikitayama.nara.jp\0" +"groundhandling.aero\0fujiyoshida.yamanashi.jp\0" +"hikone.shiga.jp\0" +"ushistory.museum\0rugby\0" +"ssl.origin.cdn77-secure.org\0" +"modern.museum\0energy\0" +"mihama.chiba.jp\0tsuruoka.yamagata.jp\0" +"info.pk\0" +"info.pl\0forgot.her.name\0" +"suli.hu\0sologne.museum\0inf.ua\0" +"msd\0" +"niteroi.br\0" +"shimoda.shizuoka.jp\0" +"abo.pa\0info.pr\0" +"akdn\0" +"gs.nl.no\0" +"izunokuni.shizuoka.jp\0" +"olsztyn.pl\0cc.il.us\0" +"conf.au\0" +"bmd.br\0" +"iwade.wakayama.jp\0" +"misasa.tottori.jp\0" +"county.museum\0logoip.com\0" +"agric.za\0" +"info.na\0" +"cc.wi.us\0" +"belluno.it\0info.mv\0info.nf\0lib.il.us\0" +"radom.pl\0" +"info.ni\0mtn\0" +"journal.aero\0" +"mtr\0" +"nec\0" +"nanyo.yamagata.jp\0" +"lib.va.us\0" +"arendal.no\0info.nr\0" +"hachioji.tokyo.jp\0" +"machida.tokyo.jp\0tv.na\0" +"kurogi.fukuoka.jp\0" +"\xc4\x8d\xc3\xa1hcesuolo.no\0" +"nadex\0" +"mn.us\0" +"trentino-su\xcc\x88""dtirol.it\0glogow.pl\0" +"li.it\0" +"net\0u2-local.xnbay.com\0" +"ac.gov.br\0puglia.it\0gushikami.okinawa.jp\0info.la\0iveland.no\0" +"new\0" +"is-a-soxfan.org\0" +"odo.br\0" +"kitahiroshima.hokkaido.jp\0finance\0" +"nfl\0" +"preservation.museum\0" +"meiwa.gunma.jp\0" "art.pl\0" -"figueres.museum\0" -"jeonbuk.kr\0" -"olecko.pl\0from-pr.com\0" -"watari.miyagi.jp\0stuff-4-sale.org\0" -"dnsalias.org\0" -"kiryu.gunma.jp\0frankfurt.museum\0" +"i.ng\0" +"cn-north-1.eb.amazonaws.com.cn\0" +"detroit.museum\0" +"karelia.su\0" +"nordkapp.no\0" +"ichinomiya.aichi.jp\0ngo\0" +"namsskogan.no\0" +"massacarrara.it\0suwalki.pl\0" +"living.museum\0" +"tozawa.yamagata.jp\0press.se\0" +"microlight.aero\0" +"nsw.edu.au\0verona.it\0" +"nhk\0from-in.com\0eu.org\0" +"ad.jp\0" +"club\0" "ullensaker.no\0" -"t\xc3\xb8nsberg.no\0run\0" +"kisosaki.mie.jp\0" +"\xe8\xb4\xad\xe7\x89\xa9\0" +"mw.gov.pl\0" +"hl.cn\0cesena-forli\xcc\x80.it\0jetzt\0" +"ishikari.hokkaido.jp\0java\0\xd9\x85\xd9\x88\xd9\x82\xd8\xb9\0serveexchange.com\0" +"i.ph\0" +"info.ke\0asmatart.museum\0" +"seirou.niigata.jp\0scienceandindustry.museum\0wiih.gov.pl\0ac.leg.br\0" +"udine.it\0info.ki\0stadt.museum\0" +"\xe5\x9f\xbc\xe7\x8e\x89.jp\0" +"s3-website-ap-southeast-2.amazonaws.com\0" +"minamiuonuma.niigata.jp\0blogspot.vn\0" +"barsy.shop\0" +"kitagata.gifu.jp\0" +"art.sn\0" +"cl.it\0" +"higashiagatsuma.gunma.jp\0" +"isernia.it\0tv.sd\0" +"abruzzo.it\0" +"roma.museum\0" +"mihara.hiroshima.jp\0" +"ntdll.top\0" +"zone\0" +"bolzano-altoadige.it\0" +"k12.dc.us\0" +"ms.gov.br\0chofu.tokyo.jp\0b\xc3\xa1l\xc3\xa1t.no\0" +"seki.gifu.jp\0rich\0" +"lib.as.us\0" +"ichikai.tochigi.jp\0" +"asso.eu.org\0" +"ind.br\0nichinan.miyazaki.jp\0balsfjord.no\0" +"reliance\0" +"i.se\0" +"cri.br\0" +"naturhistorisches.museum\0grue.no\0" +"zuerich\0" +"hakui.ishikawa.jp\0tcp4.me\0" +"tv.tr\0" +"siena.it\0kodaira.tokyo.jp\0" +"joinville.br\0caserta.it\0" +"kharkiv.ua\0" +"mie.jp\0tv.tz\0" +"co.krd\0" +"s\xc3\xb8r-aurdal.no\0service.gov.uk\0" +"austin.museum\0" +"blogspot.re\0" +"mt.gov.br\0etajima.hiroshima.jp\0" +"hachijo.tokyo.jp\0konin.pl\0" +"london.museum\0cloudycluster.net\0" +"chuo.fukuoka.jp\0" +"ta.it\0\xd1\x81\xd1\x80\xd0\xb1\0" +"shobara.hiroshima.jp\0sandnessj\xc3\xb8""en.no\0" +"press.ma\0" +"blogspot.ro\0" +"goiania.br\0" +"sport.hu\0notogawa.shiga.jp\0" +"bel.tr\0" +"haga.tochigi.jp\0blogspot.rs\0" +"!city.kawasaki.jp\0blogspot.ru\0blogspot.se\0" +"kmpsp.gov.pl\0from-wv.com\0" +"blogspot.sg\0" +"blogspot.si\0mysecuritycamera.net\0" +"hanamigawa.chiba.jp\0blogspot.sk\0freeddns.us\0" +"hjartdal.no\0" +"miyako.fukuoka.jp\0zhytomyr.ua\0ms.leg.br\0" +"blogspot.sn\0" +"ueda.nagano.jp\0" +"iwakura.aichi.jp\0" +"nishiarita.saga.jp\0stat.no\0tr.eu.org\0ras.ru\0" +"blogspot.td\0" +"shiftedit.io\0" +"hurdal.no\0" +"matsuura.nagasaki.jp\0" +"kasahara.gifu.jp\0" +"amica\0" +"myeffect.net\0" +"kazimierz-dolny.pl\0" +"hidaka.saitama.jp\0" +"vi.it\0now\0" +"takahashi.okayama.jp\0fujikawa.yamanashi.jp\0is-a-bookkeeper.com\0" +"blogspot.tw\0blogspot.ug\0" +"cc.ut.us\0" +"game-server.cc\0" +"sumoto.hyogo.jp\0tsuyama.okayama.jp\0" +"midori.chiba.jp\0" +"mt.leg.br\0" +"trentinosu\xcc\x88""dtirol.it\0" +"uk.net\0" +"ind.gt\0heroy.nordland.no\0" +"blogspot.mr\0" +"hjelmeland.no\0tokke.no\0" +"yoro.gifu.jp\0artanddesign.museum\0muncie.museum\0abkhazia.su\0" +"blogspot.mx\0" +"castle.museum\0monticello.museum\0soccer\0blogspot.my\0" +"iamallama.com\0" +"blogspot.nl\0" +"lunner.no\0nra\0university\0" +"pistoia.it\0mombetsu.hokkaido.jp\0ky.us\0blogspot.no\0" +"hadsel.no\0swiftcover\0" +"berlin.museum\0obi\0" +"ashikaga.tochigi.jp\0" +"ind.in\0" +"pictet\0" +"yuasa.wakayama.jp\0earth\0" +"\xe1\x83\x92\xe1\x83\x94\0" +"nrw\0" +"blogspot.pe\0" +"\xda\x80\xd8\xa7\xd8\xb1\xd8\xaa\0" +"fauske.no\0serveftp.net\0" +"likescandy.com\0" +"international\0syno-ds.de\0" +"lillehammer.no\0nikon\0" +"health-carereform.com\0" +"show.aero\0" +"matsuzaki.shizuoka.jp\0blogspot.qa\0" +"kawai.iwate.jp\0otsu.shiga.jp\0" +"hl.no\0blogspot.pt\0" +"s3.dualstack.eu-west-1.amazonaws.com\0" +"shinagawa.tokyo.jp\0" +"s3-website.ap-south-1.amazonaws.com\0" +"maibara.shiga.jp\0" +"control.aero\0" +"ascoli-piceno.it\0" +"*.sapporo.jp\0" +"design.aero\0" +"ntt\0" +"upow.gov.pl\0" +"ichihara.chiba.jp\0ind.kw\0blogspot.is\0" +"blogspot.it\0" +"shimizu.hokkaido.jp\0uslivinghistory.museum\0" +"bedzin.pl\0webhop.info\0" +"k12.ms.us\0k12.nc.us\0" +"lib.ks.us\0news\0" +"politie\0" +"codes\0" +"blogspot.jp\0" +"g.bg\0gripe\0" +"off\0" +"philately.museum\0dnsfor.me\0" +"ochi.kochi.jp\0democrat\0winners\0" +"bg.it\0" +"broke-it.net\0" +"cc.ar.us\0next\0" +"bale.museum\0" +"\xc3\xb8yer.no\0blogspot.kr\0" +"ot.it\0pd.it\0gitlab.io\0" +"godo.gifu.jp\0iwanuma.miyagi.jp\0hangout\0" +"toon.ehime.jp\0" +"blogspot.li\0" +"shinshinotsu.hokkaido.jp\0" +"sakaiminato.tottori.jp\0" +"omachi.nagano.jp\0" +"hair\0" +"al.gov.br\0toyokawa.aichi.jp\0" +"blogspot.lt\0blogspot.md\0" +"lib.ok.us\0blogspot.lu\0" +"turin.it\0" +"cri.nz\0blogspot.mk\0" +"ragusa.it\0" +"alto-adige.it\0" +"info.zm\0restaurant\0" +"nyc\0" +"niigata.niigata.jp\0" +"gallo\0filegear.me\0" +"qld.edu.au\0hobol.no\0" +"knx-server.net\0" +"yamaga.kumamoto.jp\0" +"epilepsy.museum\0blogspot.fi\0" +"kherson.ua\0" +"nishimera.miyazaki.jp\0" +"blackfriday\0" +"usantiques.museum\0" +"umb.it\0aogashima.tokyo.jp\0" +"media.hu\0rawa-maz.pl\0blogspot.fr\0" +"geek.nz\0" +"nom.ad\0trentin-sudtirol.it\0" +"uhren.museum\0bykle.no\0nom.ae\0customer.speedpartner.de\0" +"nom.af\0" +"nom.ag\0kita.tokyo.jp\0" +"nom.ai\0" +"k12.sc.us\0" +"nom.al\0" +"aeroclub.aero\0" +"biz.bb\0history.museum\0" +"takino.hyogo.jp\0blogspot.gr\0" +"biz.at\0" +"altoadige.it\0" +"author.aero\0rocks\0" +"freesite.host\0" +"ab.ca\0malbork.pl\0" +"biz.az\0grandrapids.museum\0" +"al.leg.br\0" +"blogspot.hk\0" +"s3-website-ap-northeast-1.amazonaws.com\0" +"shingu.hyogo.jp\0" +"tt.im\0space\0" +"ally\0" +"webcam\0blogspot.hr\0" +"vi.us\0" +"kaminokawa.tochigi.jp\0" +"blogspot.hu\0blogspot.ie\0" +"ud.it\0homeoffice.gov.uk\0" +"yonago.tottori.jp\0mayfirst.info\0nom.cl\0" +"yukuhashi.fukuoka.jp\0" +"kitahata.saga.jp\0vennesla.no\0blogspot.in\0" +"nom.co\0\xe6\xbe\xb3\xe9\x96\x80\0tiffany\0" +"shimokawa.hokkaido.jp\0blogspot.ba\0" +"homebuilt.aero\0" +"blogspot.be\0" +"blogspot.bg\0" +"biz.cy\0" +"bydgoszcz.pl\0" +"unazuki.toyama.jp\0ind.tn\0biz.dk\0blogspot.bj\0" +"ashgabad.su\0" +"sakata.yamagata.jp\0" +"plumbing\0" +"blogspot.ca\0" +"kushima.miyazaki.jp\0one\0" +"ong\0" +"tmp.br\0blogspot.cf\0" +"zakopane.pl\0" +"rl.no\0s3-ap-northeast-2.amazonaws.com\0blogspot.ch\0" +"soni.nara.jp\0onl\0" +"amsterdam.museum\0archaeological.museum\0edeka\0jdevcloud.com\0" +"blogspot.cl\0" +"conf.lv\0" +"hongo.hiroshima.jp\0" +"maryland.museum\0juegos\0" +"nom.es\0biz.et\0for-some.biz\0" +"blogspot.de\0" +"blogspot.cv\0" +"*.bd\0tele.amune.org\0" +"oi.kanagawa.jp\0\xe4\xb8\xad\xe4\xbf\xa1\0blogspot.cz\0" +"blogspot.dk\0" +"ooo\0" +"campinas.br\0miniserver.com\0" +"lodingen.no\0" +"valleeaoste.it\0mitake.gifu.jp\0" +"nom.fr\0mizunami.gifu.jp\0kristiansund.no\0" +"gs.bu.no\0broker\0freetls.fastly.net\0nom.gd\0" +"lego\0nom.ge\0" +"bihoro.hokkaido.jp\0gub.uy\0" +"tobe.ehime.jp\0" +"bozen-sudtirol.it\0" +"nom.gl\0" +"trentino-s-tirol.it\0minami.tokushima.jp\0" +"*.ck\0" +"uk.eu.org\0" +"yaese.okinawa.jp\0nom.gt\0" +"iitate.fukushima.jp\0" +"directory\0" +"lg.jp\0kimobetsu.hokkaido.jp\0media.pl\0" +"cdn77-ssl.net\0" +"tatamotors\0" +"bryansk.su\0nom.hn\0" +"s3.eu-west-3.amazonaws.com\0" +"monza-brianza.it\0" +"biz.id\0shouji\0" +"org\0" +"urawa.saitama.jp\0" +"minamiaiki.nagano.jp\0pay\0" +"e12.ve\0games\0" +"ppg.br\0higashisumiyoshi.osaka.jp\0" +"nom.im\0" +"\xed\x95\x9c\xea\xb5\xad\0" +"fussa.tokyo.jp\0" +"*.er\0" +"no.it\0" +"\xe6\xbe\xb3\xe9\x97\xa8\0barsy.site\0" +"cc.nj.us\0" +"*.fj\0" +"*.fk\0" +"flatanger.no\0f\xc3\xb8rde.no\0" +"gz.cn\0" +"labour.museum\0skierva.no\0" +"haus\0" +"blogspot.ae\0nom.ke\0" +"\xc3\xb8ystre-slidre.no\0" +"biz.ki\0" +"nishiazai.shiga.jp\0cranbrook.museum\0" +"pro.az\0" +"z.bg\0celtic.museum\0blogspot.al\0" +"nom.km\0blogspot.am\0" +"virginia.museum\0" +"amex\0" +"ott\0rodeo\0" +"airline.aero\0pro.br\0" +"bz.it\0" +"fukudomi.saga.jp\0tendo.yamagata.jp\0" +"komaki.aichi.jp\0" +"indiana.museum\0itau\0" +"b\xc3\xa5tsfjord.no\0nom.li\0" +"rockart.museum\0ybo.trade\0" +"citadel\0" +"m\xc3\xa1tta-v\xc3\xa1rjjat.no\0privatizehealthinsurance.net\0" +"pet\0" +"juif.museum\0football\0" +"viterbo.it\0cc.pr.us\0" +"choyo.kumamoto.jp\0" +"krodsherad.no\0ovh\0" +"szex.hu\0" +"morioka.iwate.jp\0nom.mg\0s3.dualstack.us-east-1.amazonaws.com\0" +"pro.cy\0gets-it.net\0" +"tynset.no\0s3-website-us-east-1.amazonaws.com\0nom.mk\0" +"gsm.pl\0nym.by\0" +"frankfurt.museum\0nym.bz\0" +"g.se\0pics\0" +"group.aero\0epost\0" +"stcgroup\0" +"nom.nc\0" +"pro.ec\0" +"biz.mv\0\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa5\x8b\xe0\xa4\xa4\0" +"biz.mw\0" +"goshiki.hyogo.jp\0poker\0" +"biz.ni\0lamer\0" +"nom.ni\0" +"sebastopol.ua\0" +"yamaguchi.jp\0" +"friuliveneziagiulia.it\0*.jm\0" +"norfolk.museum\0biz.nr\0phd\0" +"historisches.museum\0" +"nom.nu\0" +"redstone\0" +"so.it\0kumenan.okayama.jp\0" +"takamori.nagano.jp\0funagata.yamagata.jp\0" +"natural.bo\0campobasso.it\0\xd1\x83\xd0\xba\xd1\x80\0" +"ojiya.niigata.jp\0*.kh\0" +"hirosaki.aomori.jp\0waw.pl\0" +"nagato.yamaguchi.jp\0nom.pa\0americanexpress\0pid\0" +"kr\xc3\xa5""anghke.no\0nom.pe\0agakhan\0" +"giving\0" +"tsuchiura.ibaraki.jp\0ina.saitama.jp\0" +"club.aero\0" +"historisch.museum\0biz.pk\0" +"biz.pl\0pin\0" +"pb.ao\0smola.no\0nom.pl\0" +"matsuyama.ehime.jp\0ikeda.fukui.jp\0mydatto.net\0" +"ikeda.hokkaido.jp\0" +"university.museum\0user.party.eus\0" +"or.at\0biz.pr\0nom.qa\0" +"omitama.ibaraki.jp\0kanegasaki.iwate.jp\0" +"higashichichibu.saitama.jp\0" +"or.bi\0" +"nom.pw\0" +"kartuzy.pl\0dynamic-dns.info\0" +"cc.gu.us\0" +"lincoln.museum\0veg\xc3\xa5rshei.no\0" +"sasebo.nagasaki.jp\0mysecuritycamera.org\0bloxcms.com\0" +"achi.nagano.jp\0" +"*.mm\0" +"pro.ht\0sos.pl\0nom.re\0" +"or.ci\0shimane.shimane.jp\0nym.gr\0" +"nishiaizu.fukushima.jp\0tashkent.su\0" +"lg.ua\0" +"institute\0" +"64-b.it\0nym.gy\0" +"or.cr\0nom.ro\0" +"verbania.it\0cloudaccess.net\0" +"*.np\0travel\0nom.rs\0" +"nym.ie\0nom.si\0" +"wajima.ishikawa.jp\0" +"mayfirst.org\0" +"research.aero\0spdns.org\0" +"nuoro.it\0pavia.it\0cymru\0" +"toscana.it\0" +"skjerv\xc3\xb8y.no\0" +"yoshida.shizuoka.jp\0osaka\0\xd8\xa7\xd8\xa8\xd9\x88\xd8\xb8\xd8\xa8\xd9\x8a\0nom.st\0" +"skien.no\0" +"indigena.bo\0" +"erotika.hu\0biz.tj\0" +"*.pg\0nom.tj\0" +"from.hr\0ikoma.nara.jp\0" +"ulsan.kr\0" +"nom.tm\0" +"sabae.fukui.jp\0" +"sci.eg\0pnc\0biz.ua\0" +"biz.tr\0" +"ozu.kumamoto.jp\0fujikawaguchiko.yamanashi.jp\0biz.tt\0" +"chikushino.fukuoka.jp\0" +"railroad.museum\0" +"nom.ug\0" +"nishinoshima.shimane.jp\0setagaya.tokyo.jp\0" +"geisei.kochi.jp\0" +"katsuyama.fukui.jp\0" +"pug.it\0" +"historicalsociety.museum\0" +"natura\0" +"tanagura.fukushima.jp\0nom.vc\0" +"surgeonshall.museum\0bjarkoy.no\0nym.la\0virtual-user.de\0" +"kameyama.mie.jp\0ryokami.saitama.jp\0" +"grocery\0youtube\0nym.lc\0nom.vg\0" +"nom.uy\0" +"cc.me.us\0" +"biz.vn\0dynns.com\0nym.li\0" +"nym.kz\0" +"tatar\0" +"kasaoka.okayama.jp\0pro.na\0fage\0" +"dyndns-wiki.com\0" +"gop.pk\0" +"pro.mv\0" +"nym.lt\0" +"kaho.fukuoka.jp\0nym.lu\0nym.me\0" +"wa.edu.au\0ipiranga\0" +"e.bg\0" +"monza.it\0" +"or.id\0dielddanuorri.no\0" +"rel.ht\0iijima.nagano.jp\0nym.mn\0" +"minamitane.kagoshima.jp\0ping\0" +"\xd8\xa8\xda\xbe\xd8\xa7\xd8\xb1\xd8\xaa\0lasalle\0" +"pink\0" +"samnanger.no\0" +"oldnavy\0nym.mx\0" +"inazawa.aichi.jp\0" +"bozen.it\0pro.om\0" +"losangeles.museum\0" +"or.it\0" +"nango.fukushima.jp\0" +"gs.tm.no\0" +"americanantiques.museum\0wzmiuw.gov.pl\0" +"certification.aero\0aki.kochi.jp\0" +"fail\0" +"pro\0" +"or.jp\0" +"nym.nz\0" +"k12.pa.us\0\xe0\xb6\xbd\xe0\xb6\x82\xe0\xb6\x9a\xe0\xb7\x8f\0" +"*.landing.myjino.ru\0" +"nom.za\0" +"or.ke\0pru\0" +"pro.pr\0" +"cool\0is-a-doctor.com\0half.host\0" +"satx.museum\0" +"nym.pe\0" +"coop\0ostrowiec.pl\0fedex\0" +"biz.zm\0" +"naval.museum\0balashov.su\0" +"or.kr\0stjordal.no\0" +"is-a-socialist.com\0" +"chippubetsu.hokkaido.jp\0" +"minamimaki.nagano.jp\0" +"historichouses.museum\0vista\0" +"nym.pt\0" +"kokonoe.oita.jp\0ringerike.no\0backplaneapp.io\0" +"medio-campidano.it\0" +"nogata.fukuoka.jp\0" +"embetsu.hokkaido.jp\0pub\0" +"dyndns1.de\0" +"\xe0\xaa\xad\xe0\xaa\xbe\xe0\xaa\xb0\xe0\xaa\xa4\0a.prod.fastly.net\0" +"agematsu.nagano.jp\0iizuna.nagano.jp\0" +"takayama.gunma.jp\0paderborn.museum\0" +"ichiba.tokushima.jp\0myftp.org\0" +"toyako.hokkaido.jp\0" +"doctor\0" +"z.se\0" +"homedns.org\0synology.me\0" +"or.na\0" +"tec.ve\0" +"ulm.museum\0goip.de\0" +"or.mu\0localhistory.museum\0playstation\0" +"nym.ro\0" +"hirokawa.fukuoka.jp\0" +"ge.it\0*.ye\0" +"bentley\0" +"fhv.se\0\xe6\x94\xbf\xe5\x8a\xa1\0" +"higashimatsuyama.saitama.jp\0nym.sk\0" +"urasoe.okinawa.jp\0pwc\0" +"ddnslive.com\0" +"iiyama.nagano.jp\0" +"tr.it\0shimotsuma.ibaraki.jp\0" +"kozaki.chiba.jp\0pro.tt\0" +"trentinsud-tirol.it\0" +"nym.su\0" +"harima.hyogo.jp\0serveftp.org\0cloud.fedoraproject.org\0" +"nym.sx\0" +"nm.cn\0" +"ogaki.gifu.jp\0\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" +"\xc3\xa5lg\xc3\xa5rd.no\0fans\0" +"ddr.museum\0is-slick.com\0" +"froland.no\0sochi.su\0" +"fukuchiyama.kyoto.jp\0" +"rel.pl\0" +"nym.tw\0" +"trentino-a-adige.it\0moka.tochigi.jp\0" +"eco.br\0pro.vn\0" +"im.it\0" +"owariasahi.aichi.jp\0jeep\0jp.net\0operaunite.com\0" +"or.pw\0" +"suisse.museum\0" +"r\xc3\xb8""d\xc3\xb8y.no\0markets\0" +"blog.bo\0" +"blog.br\0lundbeck\0" +"servequake.com\0" +"yusui.kagoshima.jp\0k12.in.us\0\xd8\xa7\xd9\x84\xd8\xa7\xd8\xb1\xd8\xaf\xd9\x86\0" +"gen.in\0" +"chanel\0" +"dreamhosters.com\0" +"mizuho.tokyo.jp\0os.hordaland.no\0freeddns.org\0" +"k12.wy.us\0" +"jondal.no\0alipay\0" +"ine.kyoto.jp\0" +"hamatama.saga.jp\0" +"kamiamakusa.kumamoto.jp\0rackmaze.com\0" +"gr.com\0" +"tonami.toyama.jp\0kraanghke.no\0" +"laakesvuemie.no\0" +"hokkaido.jp\0" +"le.it\0farm\0lgbt\0vision\0" +"kanazawa.ishikawa.jp\0tr.no\0" +"est-le-patron.com\0for-our.info\0" +"targi.pl\0" +"or.th\0" +"yawata.kyoto.jp\0nagawa.nagano.jp\0" +"wajiki.tokushima.jp\0" +"conference.aero\0" +"fast\0" +"shonai.fukuoka.jp\0theworkpc.com\0" +"or.ug\0" +"com.ac\0" +"aparecida.br\0" +"or.tz\0" +"com.af\0" +"com.ag\0" +"jeonbuk.kr\0" +"com.ai\0" +"heguri.nara.jp\0tochigi.tochigi.jp\0imageandsound.museum\0" +"balsan.it\0" +"com.al\0yamagata.jp\0andebu.no\0czeladz.pl\0" +"or.us\0ninja\0" +"com.ba\0nabari.mie.jp\0" +"com.ar\0com.bb\0leirvik.no\0" +"schoenbrunn.museum\0" +"yamazoe.nara.jp\0stranda.no\0" +"com.au\0cc.nh.us\0" +"com.aw\0" +"com.bh\0" +"com.bi\0suzuki\0" +"com.az\0minamiashigara.kanagawa.jp\0" +"gx.cn\0" +"kumakogen.ehime.jp\0" +"com.bm\0kochi.jp\0" +"com.bn\0cust.disrec.thingdust.io\0" +"com.bo\0shingo.aomori.jp\0" +"com.br\0" +"com.bs\0bauern.museum\0" +"com.bt\0" +"x.bg\0isla.pr\0map.fastly.net\0" +"com.by\0com.ci\0" +"com.bz\0" +"gj\xc3\xb8vik.no\0gen.nz\0" +"com.cm\0ee.eu.org\0" +"com.cn\0" +"com.co\0ch.it\0saku.nagano.jp\0s3.dualstack.sa-east-1.amazonaws.com\0" +"association.aero\0" +"philadelphia.museum\0" +"safety\0" +"com.cu\0chigasaki.kanagawa.jp\0com.de\0virtueeldomein.nl\0" +"com.cw\0sakahogi.gifu.jp\0" +"com.cy\0selfip.net\0" +"pu.it\0" +"keymachine.de\0" +"hatogaya.saitama.jp\0jambyl.su\0" +"com.dm\0massa-carrara.it\0" +"agrinet.tn\0" +"com.do\0dovre.no\0" +"isumi.chiba.jp\0lifeinsurance\0" +"lesja.no\0" +"com.ec\0kamishihoro.hokkaido.jp\0" +"com.ee\0hakodate.hokkaido.jp\0" +"nico\0" +"com.eg\0" +"com.dz\0e.se\0dattolocal.com\0" +"hisamitsu\0" +"\xe7\xb5\x84\xe7\xb9\x94.tw\0" +"messina.it\0" +"com.es\0lancome\0" +"com.et\0vestre-toten.no\0" +"yuzawa.niigata.jp\0" +"warszawa.pl\0" +"shimane.jp\0" "murayama.yamagata.jp\0" -"politica.bo\0sarufutsu.hokkaido.jp\0" -"ses\0" -"georgia.su\0" -"pccw\0" +"championship.aero\0" +"meloy.no\0" +"kusatsu.shiga.jp\0" +"hemnes.no\0nord-fron.no\0" +"pvt.k12.ma.us\0isa-geek.org\0" +"botanicgarden.museum\0" +"com.fr\0" +"com.ge\0" +"com.gh\0kaszuby.pl\0" +"com.gi\0lib.co.us\0" +"sld.do\0com.gl\0" +"com.gn\0naoshima.kagawa.jp\0" +"com.gp\0tsuruga.fukui.jp\0likes-pie.com\0" +"hdfc\0" +"med.br\0com.gr\0furniture.museum\0" +"oyodo.nara.jp\0takaishi.osaka.jp\0woodside\0" +"com.gt\0" +"com.gu\0" +"\xe4\xb8\x96\xe7\x95\x8c\0" +"nakama.fukuoka.jp\0gangwon.kr\0" +"com.gy\0aremark.no\0knightpoint.systems\0" +"com.hk\0" +"kashihara.nara.jp\0" +"rennebu.no\0" +"bc.ca\0com.hn\0hiji.oita.jp\0" +"red\0" +"uppo.gov.pl\0" +"nishi.osaka.jp\0" +"com.hr\0himeji.hyogo.jp\0adult\0" +"gen.tr\0" +"com.ht\0" +"oksnes.no\0" +"kyowa.akita.jp\0" +"wodzislaw.pl\0ren\0" +"nrw.museum\0stuttgart.museum\0" +"ve.it\0fuefuki.yamanashi.jp\0scotland.museum\0" +"com.im\0goto.nagasaki.jp\0" +"qvc\0" +"com.io\0" +"com.iq\0honefoss.no\0" +"med.ec\0com.is\0" +"fnd.br\0med.ee\0arkhangelsk.su\0" +"ass.km\0" +"ardal.no\0vote\0" +"is-a-guru.com\0" +"vaporcloud.io\0" +"lib.tx.us\0" +"movistar\0" +"com.jo\0country\0" +"gives\0" +"kamogawa.chiba.jp\0yokawa.hyogo.jp\0slask.pl\0voto\0" +"tokigawa.saitama.jp\0" +"yatsuka.shimane.jp\0erni\0tuxfamily.org\0" +"sakaki.nagano.jp\0com.kg\0is-a-musician.com\0" +"freeboxos.com\0" +"com.ki\0" +"sciencehistory.museum\0\xe3\x82\xb3\xe3\x83\xa0\0" +"naamesjevuemie.no\0" +"mitou.yamaguchi.jp\0com.km\0sorreisa.no\0" +"miami\0" +"masaki.ehime.jp\0com.kp\0" +"com.la\0" +"com.lb\0" +"com.lc\0consulado.st\0" +"seiyo.ehime.jp\0" +"com.kw\0" +"com.ky\0ivano-frankivsk.ua\0" +"com.kz\0" +"com.lk\0beiarn.no\0" +"nike\0" +"\xe7\x86\x8a\xe6\x9c\xac.jp\0fukui.fukui.jp\0shinjuku.tokyo.jp\0" +"com.lr\0" +"discover\0router.management\0" +"pokrovsk.su\0" +"com.lv\0" +"com.mg\0inderoy.no\0ril\0" +"com.ly\0kv\xc3\xa6""fjord.no\0" +"trader.aero\0kawanabe.kagoshima.jp\0saiki.oita.jp\0rio\0" +"com.mk\0coastaldefence.museum\0rip\0" +"kosaka.akita.jp\0com.ml\0" +"jewishart.museum\0" +"goodhands\0bplaced.de\0" +"com.mo\0" +"gc.ca\0tainai.niigata.jp\0nm.us\0" +"kanonji.kagawa.jp\0com.na\0nore-og-uvdal.no\0est.pr\0" +"ito.shizuoka.jp\0com.ms\0verdal.no\0" +"med.ht\0com.mt\0" +"com.mu\0family.museum\0" +"com.mv\0com.nf\0cyon.link\0" +"com.mw\0com.ng\0" +"com.mx\0" +"kitakami.iwate.jp\0com.my\0com.ni\0" +"iwate.iwate.jp\0maserati\0" +"is-saved.org\0" +"ogimi.okinawa.jp\0" +"gon.pk\0" +"com.nr\0\xd8\xa7\xd9\x84\xd8\xb9\xd9\x84\xd9\x8a\xd8\xa7\xd9\x86\0" +"karate.museum\0dyndns-remote.com\0" +"c.bg\0iwakuni.yamaguchi.jp\0" +"hamamatsu.shizuoka.jp\0dinosaur.museum\0freedesktop.org\0" +"com.om\0" +"campidanomedio.it\0tosu.saga.jp\0" +"kashima.ibaraki.jp\0com.pa\0" +"fukaya.saitama.jp\0numazu.shizuoka.jp\0" +"kainan.wakayama.jp\0" +"com.pe\0" +"inami.wakayama.jp\0com.pf\0" +"inagawa.hyogo.jp\0draydns.de\0" +"com.ph\0" +"reggioemilia.it\0yuki.ibaraki.jp\0starostwo.gov.pl\0" +"com.pk\0" +"com.pl\0\xe7\xb5\x84\xe7\xb9\x94.\xe9\xa6\x99\xe6\xb8\xaf\0" +"sakado.saitama.jp\0" +"exeter.museum\0s\xc3\xb8ndre-land.no\0cc.ok.us\0" +"com.qa\0" +"com.pr\0" +"culturalcenter.museum\0sandefjord.no\0com.ps\0agency\0" +"halloffame.museum\0com.pt\0" +"leangaviika.no\0" +"x443.pw\0" +"nyuzen.toyama.jp\0com.py\0barsy.menu\0" +"piedmont.it\0" +"decorativearts.museum\0lib.mo.us\0" +"gniezno.pl\0dyndns.info\0" +"sm.ua\0" +"risor.no\0" +"sasayama.hyogo.jp\0" +"saitama.saitama.jp\0" +"com.re\0" +"kanoya.kagoshima.jp\0" +"med.ly\0" +"hitachiota.ibaraki.jp\0atlanta.museum\0" +"sld.pa\0" +"com.ro\0" +"yodobashi\0" +"com.sa\0land-4-sale.us\0" +"com.sb\0" +"com.sc\0" +"com.sd\0direct\0" +"com.se\0com.ru\0" +"s3-website-us-west-2.amazonaws.com\0" +"h\xc3\xa1pmir.no\0com.rw\0com.sg\0" +"com.sh\0" +"\xe5\x95\x86\xe6\xa0\x87\0" +"com.sl\0" +"nishinomiya.hyogo.jp\0kustanai.ru\0" +"com.sn\0" +"passenger-association.aero\0com.so\0" +"tsushima.nagasaki.jp\0" +"com.st\0uy.com\0" +"x.se\0isa-geek.com\0" +"com.sv\0" +"\xe8\x8c\xa8\xe5\x9f\x8e.jp\0otama.fukushima.jp\0" +"com.sy\0" +"com.tj\0" +"crimea.ua\0ybo.faith\0" +"jinsekikogen.hiroshima.jp\0nishikawa.yamagata.jp\0sor-aurdal.no\0" +"\xc3\xa5mli.no\0t\xc3\xb8nsberg.no\0med.om\0com.tm\0kustanai.su\0" +"com.tn\0" +"hatoyama.saitama.jp\0museumcenter.museum\0com.to\0" +"med.pa\0com.ua\0" +"charter.aero\0pvh.br\0com.tr\0simple-url.com\0" +"salvador.br\0" +"com.tt\0" +"com.tw\0com.ug\0" +"marche.it\0" +"goodyear\0" +"sap\0" +"dyndns-office.com\0hzc.io\0med.pl\0" +"kvitsoy.no\0cn.eu.org\0" +"saobernardo.br\0tp.it\0sas\0" +"carboniaiglesias.it\0" +"rmit\0" +"boavista.br\0kawaba.gunma.jp\0com.vc\0" +"photos\0sbi\0" +"com.ve\0" +"vgs.no\0" +"bialowieza.pl\0" +"hakuba.nagano.jp\0com.uy\0com.vi\0" +"l\xc3\xb8ten.no\0com.uz\0" +"sca\0" +"mod.gi\0scb\0" +"aizuwakamatsu.fukushima.jp\0com.vn\0sbs\0" +"\xe5\x85\xb5\xe5\xba\xab.jp\0" +"tinn.no\0dynamisches-dns.de\0" +"from-vt.com\0" +"from-az.net\0" +"delta\0" +"lucerne.museum\0com.vu\0" +"minamisanriku.miyagi.jp\0" +"oki.fukuoka.jp\0" +"hita.oita.jp\0fyresdal.no\0" +"saito.miyazaki.jp\0" +"ingatlan.hu\0" +"med.sa\0" +"com.ws\0s3.dualstack.eu-west-2.amazonaws.com\0" +"qc.ca\0med.sd\0" +"olbiatempio.it\0" +"\xe6\x9b\xb8\xe7\xb1\x8d\0" +"chirurgiens-dentistes-en-france.fr\0" +"firestone\0*.compute.amazonaws.com.cn\0" +"pilot.aero\0m\xc3\xa5lselv.no\0" +"barrell-of-knowledge.info\0" +"guge\0play\0c.la\0" +"\xe7\xb5\x84\xe7\xb9\x94.hk\0iwaki.fukushima.jp\0law.za\0" +"is-an-entertainer.com\0" +"mamurogawa.yamagata.jp\0" +"run\0" +"se.net\0ru.net\0" +"scienceandhistory.museum\0investments\0ravendb.me\0" +"anthro.museum\0" +"izu.shizuoka.jp\0ses\0" "sew\0" "sex\0" -"sandefjord.no\0" -"katori.chiba.jp\0\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xd9\x8a\xd9\x87\0cistron.nl\0" -"doesntexist.com\0" -"toshima.tokyo.jp\0forum\0" -"gold\0" -"golf\0de.com\0" -"herokuapp.com\0" -"sfr\0" -"hattfjelldal.no\0netbank\0" -"newyork.museum\0i.ng\0africa.com\0" -"rwe\0team\0" -"meiwa.gunma.jp\0eating-organic.net\0" -"\xe6\x96\xb0\xe6\xbd\x9f.jp\0" -"asso.re\0" -"higashiomi.shiga.jp\0fam.pk\0*.stolos.io\0" -"navy\0is-into-cartoons.com\0" -"kitami.hokkaido.jp\0" -"hasami.nagasaki.jp\0" -"umaji.kochi.jp\0drud.us\0" -"meraker.no\0firebaseapp.com\0" -"am.br\0higashiosaka.osaka.jp\0from-ct.com\0" -"l\xc3\xa1hppi.no\0snoasa.no\0art.sn\0" -"flog.br\0kanan.osaka.jp\0lib.or.us\0" -"chippubetsu.hokkaido.jp\0malvik.no\0" -"tagawa.fukuoka.jp\0pippu.hokkaido.jp\0nanjo.okinawa.jp\0total\0" -"lomza.pl\0" -"hofu.yamaguchi.jp\0k12.ca.us\0" -"knightpoint.systems\0" -"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xd9\x8a\xd8\xa9\0" -"esp.br\0homesense\0" -"modum.no\0" -"tech\0" -"hagi.yamaguchi.jp\0" -"varggat.no\0foundation\0" -"i.ph\0" -"lib.tx.us\0" -"g.bg\0" -"kasama.ibaraki.jp\0" -"kimobetsu.hokkaido.jp\0" -"fukuchi.fukuoka.jp\0" -"kamo.kyoto.jp\0kiso.nagano.jp\0evenes.no\0nsn.us\0" -"goog\0stackspace.space\0" -"vlog.br\0" -"bale.museum\0certmgr.org\0" -"beardu.no\0" -"pictet\0" -"h\xc3\xa6gebostad.no\0" -"hl.cn\0" -"satosho.okayama.jp\0" -"historyofscience.museum\0fl\xc3\xa5.no\0" -"frontdoor\0" -"iizuka.fukuoka.jp\0" -"richardli\0" -"nadex\0b.ssl.fastly.net\0" -"tosashimizu.kochi.jp\0toyama.toyama.jp\0asso.nc\0" -"happou.akita.jp\0ikeda.nagano.jp\0" -"veg\xc3\xa5rshei.no\0ski\0" -"lodingen.no\0vega.no\0" -"amex\0" -"nyc.museum\0" -"paris\0" -"narviika.no\0" -"fudai.iwate.jp\0i.se\0" -"yuu.yamaguchi.jp\0" -"kids.us\0" -"kuokgroup\0" -"land\0" -"chieti.it\0sky\0" -"yamatsuri.fukushima.jp\0lardal.no\0" -"hepforge.org\0" -"bielawa.pl\0" -"zakopane.pl\0" -"ogori.fukuoka.jp\0" -"konan.aichi.jp\0" -"ct.us\0k12.vi.us\0prime\0" -"treviso.it\0" -"amot.no\0" -"akiruno.tokyo.jp\0abo.pa\0" -"ostre-toten.no\0" -"childrens.museum\0" -"valer.hedmark.no\0" -"emerck\0" -"akita.akita.jp\0uy.com\0" -"audible\0" -"jinsekikogen.hiroshima.jp\0social\0kicks-ass.org\0" -"hawaii.museum\0" -"cn-north-1.eb.amazonaws.com.cn\0" -"no.eu.org\0" -"izumi.osaka.jp\0" -"gon.pk\0" -"cr.it\0" -"viking.museum\0" -"frosta.no\0" -"dsmynas.net\0" -"sennan.osaka.jp\0" -"miners.museum\0cdn77-ssl.net\0" -"fg.it\0gildesk\xc3\xa5l.no\0" -"shimamoto.osaka.jp\0" -"yawara.ibaraki.jp\0ichinoseki.iwate.jp\0" -"soy\0" -"bieszczady.pl\0" -"orland.no\0" -"onjuku.chiba.jp\0yazu.tottori.jp\0asso.km\0olkusz.pl\0crown\0" -"fjell.no\0skanland.no\0" -"go.gov.br\0friuliveneziagiulia.it\0tab\0" -"jfk.museum\0" -"trader.aero\0" -"eaton.mi.us\0" -"education.museum\0" -"fukaya.saitama.jp\0cc.ne.us\0" -"yokoze.saitama.jp\0hirogawa.wakayama.jp\0jewelry\0" -"sanuki.kagawa.jp\0\xc4\x8d\xc3\xa1hcesuolo.no\0" -"h\xc3\xa1""bmer.no\0" -"morimachi.shizuoka.jp\0spydeberg.no\0" -"\xe9\xa6\x99\xe6\xa0\xbc\xe9\x87\x8c\xe6\x8b\x89\0" -"asso.mc\0" -"tax\0viajes\0" -"lib.ar.us\0" -"slupsk.pl\0" -"okawa.kochi.jp\0" -"fuchu.hiroshima.jp\0srl\0" -"dupont\0" -"lib.co.us\0\xd8\xa8\xd8\xa7\xd8\xb2\xd8\xa7\xd8\xb1\0" -"selbu.no\0srt\0cloudaccess.net\0" -"yugawa.fukushima.jp\0lexus\0yolasite.com\0" -"nozawaonsen.nagano.jp\0" -"iglesias-carbonia.it\0mutsuzawa.chiba.jp\0odesa.ua\0kred\0" -"tci\0" -"ricoh\0" -"s3.dualstack.us-east-2.amazonaws.com\0" -"school.museum\0" -"kyonan.chiba.jp\0" -"investments\0" -"te.it\0cc.wi.us\0" -"news.hu\0stc\0" -"h\xc3\xa1mm\xc3\xa1rfeasta.no\0" -"omachi.nagano.jp\0" -"lavagis.no\0" -"minowa.nagano.jp\0" -"lerdal.no\0" -"tdk\0eu-west-3.elasticbeanstalk.com\0" -"shoo.okayama.jp\0" -"read\0" -"kurogi.fukuoka.jp\0tashkent.su\0" -"kongsvinger.no\0" -"bio.br\0shimane.shimane.jp\0nz.eu.org\0" -"hl.no\0" -"\xc3\xb8rskog.no\0tel\0" -"tarnobrzeg.pl\0" -"santacruz.museum\0ski.no\0dynu.net\0" -"e164.arpa\0" -"yawatahama.ehime.jp\0" -"kawaba.gunma.jp\0" -"camera\0" -"britishcolumbia.museum\0ringsaker.no\0stage.nodeart.io\0" -"biei.hokkaido.jp\0parts\0" -"yachiyo.chiba.jp\0" -"tomiya.miyagi.jp\0theater.museum\0royrvik.no\0securitytactics.com\0" -"party\0" -"\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa5\x8b\xe0\xa4\xa4\0tires\0" -"chernigov.ua\0" -"tokai.ibaraki.jp\0rost.no\0" -"e.bg\0" -"surf\0" -"salerno.it\0\xe9\xb3\xa5\xe5\x8f\x96.jp\0" -"circus.museum\0" -"v\xc3\xa6r\xc3\xb8y.no\0deals\0ddnsking.com\0" -"thd\0" -"hoteles\0tickets\0" -"bitballoon.com\0" -"gz.cn\0" -"rome.it\0" -"sos.pl\0" -"ebetsu.hokkaido.jp\0" -"palermo.it\0" -"gyeongnam.kr\0uk.com\0" -"vevelstad.no\0" -"reggiocalabria.it\0" -"conf.au\0md.ci\0" -"dazaifu.fukuoka.jp\0" -"active\0" -"machida.tokyo.jp\0g.se\0" -"omaha.museum\0nokia\0" -"rackmaze.com\0" -"nagi.okayama.jp\0oygarden.no\0cr.ua\0kr.com\0" -"iwakura.aichi.jp\0kozaki.chiba.jp\0" -"date.fukushima.jp\0defense.tn\0" -"tarui.gifu.jp\0" -"miami\0oracle\0" -"bjarkoy.no\0samsclub\0" -"kanra.gunma.jp\0" -"tjx\0nflfan.org\0" -"teva\0\xe7\xbb\x84\xe7\xbb\x87\xe6\x9c\xba\xe6\x9e\x84\0" -"furniture.museum\0" -"otago.museum\0" -"utsira.no\0" -"ethnology.museum\0gol.no\0" -"remotewd.com\0" -"istanbul\0" -"town.museum\0gs.tr.no\0" -"cc.az.us\0" -"control.aero\0" -"freeboxos.com\0" -"misato.wakayama.jp\0" -"lv.ua\0" -"echizen.fukui.jp\0" -"kawasaki.miyagi.jp\0" -"motegi.tochigi.jp\0" -"kamikoani.akita.jp\0" -"lplfinancial\0" -"pantheonsite.io\0" -"\xd8\xb4\xd8\xa8\xd9\x83\xd8\xa9\0dynvpn.de\0" -"weather\0" -"reit\0" -"americanfamily\0" -"*.kitakyushu.jp\0" -"kainan.wakayama.jp\0" -"aircraft.aero\0fe.it\0skierva.no\0" -"freemasonry.museum\0" -"hdfcbank\0" -"ok.us\0" -"usgarden.museum\0" -"yabuki.fukushima.jp\0te.ua\0is-a-socialist.com\0" -"modena.it\0ouchi.saga.jp\0" -"barreau.bj\0" -"discover\0" -"dyroy.no\0sk\xc3\xa5nland.no\0uz.ua\0" -"yabu.hyogo.jp\0cc.ms.us\0cc.nc.us\0" -"sasaguri.fukuoka.jp\0" -"autos\0" -"top\0" -"loyalist.museum\0" -"sosnowiec.pl\0for-some.biz\0" -"mywire.org\0" -"lt.it\0" -"b\xc3\xa1l\xc3\xa1t.no\0" -"ujiie.tochigi.jp\0banamex\0" -"toyone.aichi.jp\0" -"zt.ua\0ddns.net\0" -"hockey\0tirol\0" -"gonohe.aomori.jp\0fortworth.museum\0" -"per.la\0" -"eidskog.no\0" -"4lima.de\0" -"himeshima.oita.jp\0" -"s3.dualstack.sa-east-1.amazonaws.com\0" -"mitsue.nara.jp\0" -"itakura.gunma.jp\0" -"shiraoka.saitama.jp\0" -"kustanai.ru\0" -"kirkenes.no\0community\0" -"ss.it\0" -"kawai.iwate.jp\0s3-website-us-east-1.amazonaws.com\0" -"java\0" -"ismaili\0" -"golffan.us\0" -"cesena-forli.it\0donna.no\0" -"college\0" -"pescara.it\0rent\0kustanai.su\0" -"tahara.aichi.jp\0akashi.hyogo.jp\0semine.miyagi.jp\0" -"hachinohe.aomori.jp\0ubs\0" -"4lima.at\0" -"trv\0from-mo.com\0" -"per.nf\0" -"valle-daosta.it\0" -"shijonawate.osaka.jp\0" -"cyon.site\0" -"lib.nm.us\0" -"\xc3\xb8stre-toten.no\0lancaster\0" -"*.kunden.ortsinfo.at\0" -"yasuda.kochi.jp\0togitsu.nagasaki.jp\0" -"ariake.saga.jp\0" -"boldlygoingnowhere.org\0" -"4lima.ch\0" -"\xd0\xb8\xd0\xba\xd0\xbe\xd0\xbc.museum\0" -"tsukiyono.gunma.jp\0archi\0" -"hair\0" -"financial\0" -"civilwar.museum\0" -"from-sc.com\0" -"media.museum\0" -"aichi.jp\0" -"seirou.niigata.jp\0ama.shimane.jp\0" -"cyon.link\0" -"k12.fl.us\0" -"tui\0" -"misconfused.org\0" -"\xe7\xbb\x84\xe7\xbb\x87.hk\0" -"c.bg\0" -"blogspot.com.cy\0" -"shimotsuma.ibaraki.jp\0kofu.yamanashi.jp\0pa.leg.br\0" -"toyokawa.aichi.jp\0kawazu.shizuoka.jp\0" -"lib.wi.us\0dray-dns.de\0" -"seaport.museum\0" -"cahcesuolo.no\0hu.net\0" -"blogspot.com.ee\0" -"k12.in.us\0cool\0" -"tokke.no\0blogspot.com.eg\0" -"shingu.fukuoka.jp\0" -"og.ao\0" -"gx.cn\0coop\0afamilycompany\0" -"slz.br\0wlocl.pl\0tvs\0" -"k12.la.us\0*.compute.estate\0dontexist.net\0" -"mb.ca\0" -"blogspot.com.ar\0" -"trysil.no\0" -"blogspot.com.au\0" -"ngo.lk\0" -"naturbruksgymn.se\0" -"rest\0" -"k12.oh.us\0user.party.eus\0" -"pb.leg.br\0" -"gj\xc3\xb8vik.no\0e.se\0per.sg\0blogspot.com.br\0" -"casadelamoneda.museum\0" -"2ix.at\0" -"lefrak\0" -"kiwi.nz\0mutual\0blogspot.com.by\0" -"rikubetsu.hokkaido.jp\0casino\0gda.pl\0" -"center.museum\0virtual.museum\0" -"\xc3\xa5l.no\0ak.us\0in-the-band.net\0" -"kushimoto.wakayama.jp\0ardal.no\0blogspot.com.co\0" -"midatlantic.museum\0" -"sicily.it\0dev-myqnapcloud.com\0" -"mt.eu.org\0" -"tours\0" -"gose.nara.jp\0incheon.kr\0" -"ashiya.hyogo.jp\0rochester.museum\0\xe6\x94\xbf\xe5\x8a\xa1\0""2ix.ch\0" -"bando.ibaraki.jp\0" -"bergen.no\0" -"nara.nara.jp\0malselv.no\0" -"haugesund.no\0hob\xc3\xb8l.no\0" -"dealer\0" -"olsztyn.pl\0" -"2ix.de\0" -"s3-us-east-2.amazonaws.com\0" -"lt.ua\0" -"reklam.hu\0" -"blogspot.com.es\0" -"nagato.yamaguchi.jp\0ngo.ph\0" -"abkhazia.su\0" -"mymediapc.net\0" -"cn.it\0" -"md.us\0is-an-accountant.com\0" -"git-repos.de\0" -"fc.it\0" -"airtel\0likes-pie.com\0" -"ikawa.akita.jp\0" -"chattanooga.museum\0ny.us\0" -"gjovik.no\0" -"helsinki.museum\0" -"fujiyoshida.yamanashi.jp\0" -"spreadbetting\0cloudaccess.host\0" -"fedje.no\0" -"ito.shizuoka.jp\0" -"*.nagoya.jp\0samukawa.kanagawa.jp\0" -"economia.bo\0" -"v\xc3\xa5ler.\xc3\xb8stfold.no\0" -"yorii.saitama.jp\0" -"acct.pro\0" -"mb.it\0es.kr\0" -"tabayama.yamanashi.jp\0" -"inderoy.no\0" -"tsuga.tochigi.jp\0uno\0servecounterstrike.com\0" -"kagawa.jp\0" -"og.it\0" -"caltanissetta.it\0" -"tondabayashi.osaka.jp\0c.la\0" -"ube.yamaguchi.jp\0" -"lib.dc.us\0" -"tosu.saga.jp\0" -"kaszuby.pl\0" -"tokushima.jp\0sola.no\0stada\0uol\0" -"tatsuno.hyogo.jp\0" -"tagajo.miyagi.jp\0oppeg\xc3\xa5rd.no\0" -"ono.fukushima.jp\0scotland.museum\0fage\0" -"jgora.pl\0" -"mtpc\0" -"nagatoro.saitama.jp\0" -"cloudns.asia\0" -"ta.it\0" -"izunokuni.shizuoka.jp\0" -"hamamatsu.shizuoka.jp\0vik.no\0" -"photos\0" -"firenze.it\0interactive.museum\0haus\0" -"kiyose.tokyo.jp\0" -"ups\0" -"kanagawa.jp\0" -"tajimi.gifu.jp\0" -"huissier-justice.fr\0" -"foggia.it\0" -"fail\0" -"dscloud.biz\0" -"geek.nz\0sa-east-1.elasticbeanstalk.com\0" -"seto.aichi.jp\0" -"lowicz.pl\0" -"aki.kochi.jp\0" -"fedorapeople.org\0" -"gv.ao\0" -"isahaya.nagasaki.jp\0" -"gv.at\0my.eu.org\0" -"ota.gunma.jp\0cooking\0us-east-1.elasticbeanstalk.com\0blogspot.com.mt\0" -"bearalv\xc3\xa1hki.no\0" -"blogspot.com.ng\0" -"leclerc\0xenapponazure.com\0" -"shimamaki.hokkaido.jp\0sor-fron.no\0" -"a.bg\0" -"cheltenham.museum\0" -"war.museum\0" -"ichinohe.iwate.jp\0" -"budejju.no\0dlugoleka.pl\0homeunix.net\0" -"fuossko.no\0" -"aland.fi\0" -"iwanuma.miyagi.jp\0" -"center\0is-a-hard-worker.com\0" -"chuo.fukuoka.jp\0conf.lv\0" -"mielno.pl\0" -"shimada.shizuoka.jp\0" -"cartier\0" -"limited\0" -"ngo.za\0ventures\0" -"roma.it\0ap-southeast-1.elasticbeanstalk.com\0" -"url.tw\0" -"\xe3\x83\x9d\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\x88\0" -"asahi.chiba.jp\0" -"yuzawa.niigata.jp\0" -"hanamigawa.chiba.jp\0" -"kommune.no\0vf.no\0" -"giehtavuoatna.no\0" -"web.bo\0ladbrokes\0sells-for-less.com\0" -"pi.leg.br\0" -"k12.nv.us\0" -"nu.ca\0vet\0" -"boston.museum\0vestnes.no\0plo.ps\0" -"miyawaka.fukuoka.jp\0sykkylven.no\0" -"armenia.su\0" -"blogspot.com.tr\0" -"c.se\0" -"\xe4\xbf\xa1\xe6\x81\xaf\0" -"koshigaya.saitama.jp\0cn.ua\0christmas\0" -"web.co\0" -"kragero.no\0" -"test.tj\0" -"unicom\0c.cdn77.org\0" -"dyndns-wiki.com\0" -"nagaokakyo.kyoto.jp\0uonuma.niigata.jp\0nissedal.no\0" -"web.do\0fans\0" -"shobara.hiroshima.jp\0pisz.pl\0" -"okuma.fukushima.jp\0" -"from-ks.com\0" -"uw.gov.pl\0tkmaxx\0sa.com\0" -"gamagori.aichi.jp\0rodoy.no\0flights\0" -"samsung\0" -"oguni.kumamoto.jp\0" -"eastafrica.museum\0" -"\xe0\xaa\xad\xe0\xaa\xbe\xe0\xaa\xb0\xe0\xaa\xa4\0cloud\0" -"coach\0" -"\xe7\xbd\x91\xe7\xbb\x9c\0" -"vig\0" -"ako.hyogo.jp\0aso.kumamoto.jp\0" -"nl.eu.org\0" -"ag.it\0" -"entertainment.aero\0" -"vin\0" -"hapmir.no\0dynns.com\0" -"vip\0" -"test.ru\0" -"cl.it\0eu.com\0" -"movistar\0tele.amune.org\0" -"\xd0\xba\xd0\xb0\xd1\x82\xd0\xbe\xd0\xbb\xd0\xb8\xd0\xba\0br.com\0" -"\xd0\xb1\xd0\xb5\xd0\xbb\0" -"dating\0" -"kashiba.nara.jp\0" -"archaeological.museum\0bykle.no\0" -"rad\xc3\xb8y.no\0" -"agakhan\0farm\0" -"joetsu.niigata.jp\0" -"skole.museum\0yamaxun\0" -"microlight.aero\0kani.gifu.jp\0blogspot.com.uy\0" -"us-east-1.amazonaws.com\0" -"urasoe.okinawa.jp\0" -"assassination.museum\0cc.mo.us\0" -"web.id\0" -"minamiawaji.hyogo.jp\0" -"medical.museum\0" -"muni.il\0pokrovsk.su\0" -"vodka\0" -"pesarourbino.it\0fribourg.museum\0" -"stranda.no\0is-certified.com\0" -"\xc3\xa5mot.no\0fast\0" -"zp.ua\0" -"communications.museum\0" -"tj\xc3\xb8me.no\0" -"nu.it\0cc.ri.us\0" -"society.museum\0" -"goip.de\0" -"knx-server.net\0lib.de.us\0" -"tjeldsund.no\0" -"ichikawamisato.yamanashi.jp\0nordreisa.no\0" -"urn.arpa\0" -"pz.it\0okaya.nagano.jp\0\xc3\xa5seral.no\0lier.no\0cc.tn.us\0pe.leg.br\0" -"noip.us\0" -"bestbuy\0ap-northeast-2.elasticbeanstalk.com\0" -"yuasa.wakayama.jp\0rissa.no\0s3-website-us-west-2.amazonaws.com\0" -"so.it\0ikeda.osaka.jp\0koya.wakayama.jp\0cipriani\0\xe4\xb8\xad\xe6\x96\x87\xe7\xbd\x91\0" -"ic.gov.pl\0itau\0" -"moareke.no\0" -"ato.br\0takashima.shiga.jp\0ivano-frankivsk.ua\0" -"\xc3\xa5lg\xc3\xa5rd.no\0" -"elk.pl\0" -"*.elb.amazonaws.com.cn\0" -"chambagri.fr\0" -"norfolk.museum\0" -"kasugai.aichi.jp\0" -"\xe8\xaf\xba\xe5\x9f\xba\xe4\xba\x9a\0ng.eu.org\0" -"\xe4\xbc\x81\xe4\xb8\x9a\0" -"web.lk\0" -"pvt.k12.ma.us\0rightathome\0" -"otaki.chiba.jp\0asso.eu.org\0" -"\xe7\xbb\x84\xe7\xb9\x94.hk\0" -"lib.ma.us\0" -"imamat\0" -"tree.museum\0" -"hikimi.shimane.jp\0" -"lecce.it\0" -"market\0" -"rackmaze.net\0" -"iide.yamagata.jp\0" -"toyako.hokkaido.jp\0aikawa.kanagawa.jp\0" -"christiansburg.museum\0" -"sado.niigata.jp\0jondal.no\0prudential\0" -"tenkawa.nara.jp\0" -"singles\0" -"ainan.ehime.jp\0web.nf\0" -"web.ni\0author\0" -"imabari.ehime.jp\0\xe8\x81\x94\xe9\x80\x9a\0storj.farm\0" -"e12.ve\0" -"civilisation.museum\0" -"karate.museum\0" -"sagamihara.kanagawa.jp\0" -"kamishihoro.hokkaido.jp\0" -"karasjohka.no\0" -"stream\0" -"from-ky.com\0" -"trentino-sud-tirol.it\0\xe7\xbd\x91\xe5\xba\x97\0" -"ingatlan.hu\0" -"cartoonart.museum\0" -"recht.pro\0" -"doomdns.org\0" -"alpha.bounty-full.com\0" -"freeboxos.fr\0" -"chitose.hokkaido.jp\0web.pk\0szkola.pl\0" -"homedns.org\0" -"morotsuka.miyazaki.jp\0kristiansund.no\0" -"usui.fukuoka.jp\0" -"suedtirol.it\0" -"ns.ca\0axis.museum\0pubol.museum\0" -"ln.cn\0szczecin.pl\0" -"misato.akita.jp\0snasa.no\0vladikavkaz.ru\0" -"lindas.no\0" -"chesapeakebay.museum\0" -"logistics.aero\0jdf.br\0a.se\0" -"industria.bo\0" -"radio.br\0" -"fukuoka.jp\0ushiku.ibaraki.jp\0zamami.okinawa.jp\0wed\0" -"natal.br\0observer\0in.net\0" -"nishikata.tochigi.jp\0" -"izena.okinawa.jp\0custom.metacentrum.cz\0" -"vladikavkaz.su\0" -"ogawa.ibaraki.jp\0" -"mjondalen.no\0" -"qh.cn\0" -"partners\0" -"yakumo.hokkaido.jp\0lego\0" -"kaga.ishikawa.jp\0" -"express.aero\0aizuwakamatsu.fukushima.jp\0atlanta.museum\0" -"tiaa\0net.eu.org\0" -"miyoshi.aichi.jp\0yuki.ibaraki.jp\0equipment\0" -"hidaka.hokkaido.jp\0" -"algard.no\0" -"mex.com\0" -"github.io\0" -"\xe5\xb7\xa5\xe8\xa1\x8c\0" -"obninsk.su\0" -"historicalsociety.museum\0parliament.nz\0" -"linz.museum\0" -"communication.museum\0erni\0" -"takko.aomori.jp\0doesntexist.org\0" -"omihachiman.shiga.jp\0" -"web.tj\0" -"sdn.gov.pl\0" -"for-better.biz\0" -"trani-barletta-andria.it\0pr.leg.br\0" -"wzmiuw.gov.pl\0" -"web.tr\0" -"news\0" -"is-very-evil.org\0" -"andria-trani-barletta.it\0" -"bz.it\0natori.miyagi.jp\0" -"\xd8\xa7\xd8\xb1\xd8\xa7\xd9\x85\xd9\x83\xd9\x88\0" -"baby\0" -"bmoattachments.org\0" -"haebaru.okinawa.jp\0esurance\0" -"obuse.nagano.jp\0" -"chuo.tokyo.jp\0familyds.net\0" -"es.gov.br\0plc.co.im\0naganohara.gunma.jp\0" -"tas.gov.au\0ulvik.no\0" -"next\0" -"yashiro.hyogo.jp\0web.ve\0noip.me\0" -"muko.kyoto.jp\0" -"elburg.museum\0" -"takino.hyogo.jp\0omi.nagano.jp\0win\0" -"shizukuishi.iwate.jp\0" -"friulivenezia-giulia.it\0land-4-sale.us\0" -"aknoluokta.no\0kinder\0" -"muenchen.museum\0potager.org\0" -"taira.toyama.jp\0paroch.k12.ma.us\0visa\0" -"jefferson.museum\0" -"uhren.museum\0" -"cc.or.us\0trading\0" -"toyoura.hokkaido.jp\0data\0" -"museum\0" -"alto-adige.it\0ut.us\0" -"lib.az.us\0date\0" -"\xe4\xbd\x90\xe8\xb3\x80.jp\0space\0" -"dontexist.org\0" -"polkowice.pl\0\xd8\xa7\xd9\x85\xd8\xa7\xd8\xb1\xd8\xa7\xd8\xaa\0" -"nikon\0" -"wy.us\0" -"air-traffic-control.aero\0" -"michigan.museum\0b\xc3\xa1hcavuotna.no\0" -"shingo.aomori.jp\0" -"global.ssl.fastly.net\0" -"yachiyo.ibaraki.jp\0" -"b\xc3\xa6rum.no\0" -"shimodate.ibaraki.jp\0um.gov.pl\0" -"voyage\0" -"parma.it\0pgfog.com\0" -"cc.wa.us\0" -"ac.ae\0yasuoka.nagano.jp\0web.za\0" -"furubira.hokkaido.jp\0" -"trentino-suedtirol.it\0" -"wme\0" -"viva\0" -"umi.fukuoka.jp\0ofunato.iwate.jp\0hayakawa.yamanashi.jp\0dabur\0" -"patria.bo\0vb.it\0toyono.osaka.jp\0pictures\0" -"s\xc3\xb8rfold.no\0sklep.pl\0kalisz.pl\0" -"nishiizu.shizuoka.jp\0mmafan.biz\0pgafan.net\0" -"togo.aichi.jp\0is-not-certified.com\0" -"kudoyama.wakayama.jp\0livinghistory.museum\0" -"shinkamigoto.nagasaki.jp\0" -"ac.at\0hobby-site.com\0" -"ac.be\0" -"blockbuster\0vivo\0" -"from-sd.com\0" -"sayo.hyogo.jp\0" -"glass.museum\0" -"philadelphiaarea.museum\0" -"yoshikawa.saitama.jp\0" -"hakodate.hokkaido.jp\0k12.al.us\0" -"dinosaur.museum\0russia.museum\0pagespeedmobilizer.com\0" -"tourism.tn\0" -"\xd8\xa7\xd9\x84\xd9\x8a\xd9\x85\xd9\x86\0" -"business\0" -"kosuge.yamanashi.jp\0" -"ac.ci\0tula.su\0" -"oishida.yamagata.jp\0handson.museum\0" -"sano.tochigi.jp\0" -"ac.cn\0onga.fukuoka.jp\0lib.ri.us\0" -"8.bg\0" -"sevastopol.ua\0" -"ac.cr\0athleta\0" -"aostavalley.it\0" -"ac.cy\0kindle\0" -"wow\0" -"niigata.niigata.jp\0us.gov.pl\0homeunix.org\0" -"taishin.fukushima.jp\0" -"k12.ga.us\0" -"barum.no\0" -"hdfc\0endoftheinternet.org\0karelia.su\0" -"tone.ibaraki.jp\0" -"trentino-alto-adige.it\0" -"alta.no\0" -"hb.cn\0" -"dyndns.ddnss.de\0" -"hemne.no\0nittedal.no\0" -"k12.ks.us\0" -"kouyama.kagoshima.jp\0" -"skjerv\xc3\xb8y.no\0" -"dyndns.tv\0" -"kvalsund.no\0builders\0" -"jeonnam.kr\0jeep\0" -"withyoutube.com\0" -"miyada.nagano.jp\0" -"pharmaciens.km\0" -"usuki.oita.jp\0iraq.museum\0" -"krasnodar.su\0" -"narusawa.yamanashi.jp\0celtic.museum\0tysfjord.no\0" -"seihi.nagasaki.jp\0" -"accident-prevention.aero\0band\0" -"hornindal.no\0is-found.org\0" -"ac.gn\0" -"misasa.tottori.jp\0foodnetwork\0tr.eu.org\0" -"doctor\0" -"sk.ca\0bank\0qa2.com\0" -"comunica\xc3\xa7\xc3\xb5""es.museum\0" -"modalen.no\0" -"wtc\0" -"wtf\0" -"plaza.museum\0" -"ogaki.gifu.jp\0quest\0" -"cricket\0protection\0" -"ac.id\0dyndns.ws\0" -"cc.ar.us\0selfip.net\0" -"ginoza.okinawa.jp\0" -"ac.il\0bronnoy.no\0\xc3\xb8ksnes.no\0" -"ac.im\0komatsu.ishikawa.jp\0mosjoen.no\0" -"ac.in\0sodegaura.chiba.jp\0" -"nombre.bo\0" -"ac.ir\0" -"sumoto.kumamoto.jp\0hotels\0" -"nysa.pl\0" -"wa.gov.au\0" -"tsugaru.aomori.jp\0" -"gob.ar\0abc.br\0b\xc3\xa1id\xc3\xa1r.no\0hamar.no\0" -"muncie.museum\0arab\0" -"matsukawa.nagano.jp\0tarama.okinawa.jp\0topology.museum\0" -"toya.hokkaido.jp\0" -"design.museum\0" -"zj.cn\0saotome.st\0" -"oster\xc3\xb8y.no\0" -"ch.it\0cc.fl.us\0tips\0" -"ac.jp\0radio\0" -"health-carereform.com\0" -"shibetsu.hokkaido.jp\0" -"gob.bo\0vaksdal.no\0washtenaw.mi.us\0" -"friulivegiulia.it\0" -"rich\0" -"tas.edu.au\0" -"plants.museum\0cc.ia.us\0group\0" -"keymachine.de\0" -"aid.pl\0map.fastly.net\0" -"sm.ua\0" -"\xd8\xa7\xd9\x84\xd8\xb9\xd9\x84\xd9\x8a\xd8\xa7\xd9\x86\0is-a-cubicle-slave.com\0" -"gob.cl\0fujitsu\0" -"gr.it\0ac.kr\0" -"feira.br\0coldwar.museum\0" -"ac.leg.br\0" -"kanie.aichi.jp\0" -"toyama.jp\0stadt.museum\0" -"ac.lk\0" -"navigation.aero\0!city.kawasaki.jp\0newport.museum\0" -"garden.museum\0\xe7\xa7\xbb\xe5\x8a\xa8\0" -"arts.co\0gr.jp\0" -"ddns.me\0" -"miyakonojo.miyazaki.jp\0ac.ma\0aarborte.no\0" -"kagamiishi.fukushima.jp\0iwate.iwate.jp\0" -"higashi.fukuoka.jp\0" -"gob.do\0stord.no\0" -"ine.kyoto.jp\0ac.me\0" -"valled-aosta.it\0" -"gob.ec\0s3-ap-south-1.amazonaws.com\0from-wa.com\0" -"sanda.hyogo.jp\0stryn.no\0xin\0" -"heroy.more-og-romsdal.no\0" -"ac.mu\0pomorskie.pl\0weibo\0dnsfor.me\0" -"\xd8\xaa\xd9\x88\xd9\x86\xd8\xb3\0" -"ac.mw\0" -"gob.es\0" -"mansions.museum\0ac.ni\0" -"pv.it\0ac.mz\0lugansk.ua\0" -"is-a-conservative.com\0" -"atm.pl\0dynathome.net\0" -"hasvik.no\0" -"tourism.pl\0" -"campinas.br\0" -"sweden.museum\0" -"appchizi.com\0" -"ac.nz\0" -"gen.in\0" -"kikuchi.kumamoto.jp\0industries\0is-a-chef.org\0" -"gratis\0" -"ac.pa\0" -"omi.niigata.jp\0" -"shari.hokkaido.jp\0" -"higashikurume.tokyo.jp\0" -"gob.gt\0monmouth.museum\0sologne.museum\0" -"honai.ehime.jp\0koge.tottori.jp\0allstate\0" -"lib.me.us\0" -"vic.au\0" -"ac.pr\0" -"gob.hn\0" -"dni.us\0" -"langev\xc3\xa5g.no\0" -"report\0" -"katashina.gunma.jp\0" -"nesodden.no\0" -"tsunan.niigata.jp\0servemp3.com\0" -"6.bg\0sicilia.it\0d\xc3\xb8nna.no\0konsulat.gov.pl\0" -"prof.pr\0" -"bplaced.de\0" -"saikai.nagasaki.jp\0" -"sagae.yamagata.jp\0poltava.ua\0" -"wroc.pl\0" -"florence.it\0ranzan.saitama.jp\0" -"shiraoi.hokkaido.jp\0" -"sakuragawa.ibaraki.jp\0" -"is-gone.com\0" -"monzaedellabrianza.it\0" -"wskr.gov.pl\0" -"hembygdsforbund.museum\0at-band-camp.net\0is-an-entertainer.com\0" -"ac.rs\0" -"lucca.it\0ac.ru\0ac.se\0lib.va.us\0" -"naturhistorisches.museum\0" -"atami.shizuoka.jp\0bedzin.pl\0ac.rw\0degree\0" -"spy.museum\0" -"chungnam.kr\0mragowo.pl\0abogado\0" -"molde.no\0" -"griw.gov.pl\0" -"r\xc3\xa1hkker\xc3\xa1vju.no\0" -"yamagata.gifu.jp\0onna.okinawa.jp\0" -"mormon\0" -"k12.ky.us\0" -"tra.kp\0" -"ac.th\0" -"trondheim.no\0" -"ac.sz\0ac.tj\0" -"q-a.eu.org\0" -"yao.osaka.jp\0" -"reggio-calabria.it\0is-a-chef.com\0" -"ddnsfree.com\0" -"*.yokohama.jp\0\xd8\xa8\xda\xbe\xd8\xa7\xd8\xb1\xd8\xaa\0" -"namsskogan.no\0" -"togane.chiba.jp\0alesund.no\0" -"gen.nz\0ac.ug\0" -"drammen.no\0" -"embroidery.museum\0" -"ac.tz\0\xe6\x9b\xb8\xe7\xb1\x8d\0" -"ac.uk\0lgbt\0" -"nakadomari.aomori.jp\0ohkura.yamagata.jp\0" -"muroran.hokkaido.jp\0" -"rimini.it\0yokawa.hyogo.jp\0flatanger.no\0" -"guge\0" -"vic.edu.au\0g12.br\0" -"video\0" -"venezia.it\0damnserver.com\0" -"is-a-blogger.com\0" -"webhosting.be\0from-nj.com\0" -"rep.kp\0" -"gob.mx\0" -"gob.ni\0ac.vn\0" -"romskog.no\0" -"itoman.okinawa.jp\0" -"silk.museum\0media\0ryukyu\0" -"pizza\0" -"arts.ve\0" -"trentino-sued-tirol.it\0" -"kyotamba.kyoto.jp\0" -"name.hr\0" -"kamifurano.hokkaido.jp\0""12hp.de\0" -"loans\0" -"kimitsu.chiba.jp\0dclk\0bashkiria.ru\0" -"army\0" -"law.za\0freeddns.org\0" -"umbria.it\0naruto.tokushima.jp\0kyiv.ua\0" -"koeln.museum\0" -"trentinosudtirol.it\0" -"parliament.cy\0gob.pa\0" -"southcarolina.museum\0cc.de.us\0rentals\0" -"mediocampidano.it\0*.elb.amazonaws.com\0" -"name.et\0usa.museum\0gob.pe\0" -"bus.museum\0crafts.museum\0egyptian.museum\0" -"bashkiria.su\0" -"gob.pk\0" -"oita.oita.jp\0" -"nagasu.kumamoto.jp\0sener\0cloudfunctions.net\0" -"works.aero\0" -"arpa\0sanagochi.tokushima.jp\0belau.pw\0chernovtsy.ua\0" -"nakatane.kagoshima.jp\0" -"12hp.at\0" -"bizen.okayama.jp\0" -"seoul.kr\0" -"br\xc3\xb8nn\xc3\xb8ysund.no\0" -"arakawa.tokyo.jp\0" -"uk.eu.org\0" -"carraramassa.it\0ac.za\0" -"florist\0" -"undersea.museum\0" -"pics\0" -"seki.gifu.jp\0" -"kutchan.hokkaido.jp\0" -"sebastopol.ua\0" -"capitalone\0" -"lazio.it\0hakata.fukuoka.jp\0" -"ac.zm\0""12hp.ch\0" -"name.cy\0cpa.pro\0gen.tr\0cc.mi.us\0" -"kosaka.akita.jp\0zp.gov.pl\0" -"aju.br\0" -"verran.no\0" -"otsuchi.iwate.jp\0" -"tsushima.aichi.jp\0" -"numazu.shizuoka.jp\0ac.zw\0" -"vallee-aoste.it\0rana.no\0" -"name.eg\0help\0" -"!city.yokohama.jp\0arts.ro\0" -"newjersey.museum\0" -"no.it\0yorkshire.museum\0vladimir.su\0" -"medio-campidano.it\0nebraska.museum\0" -"zgorzelec.pl\0" -"gob.sv\0" -"pt.it\0kurotaki.nara.jp\0est-a-la-masion.com\0" -"valdaosta.it\0\xe6\xbe\xb3\xe9\x96\x80\0" -"shinjo.nara.jp\0" -"name.az\0miharu.fukushima.jp\0hospital\0" -"sayama.osaka.jp\0aa.no\0" -"toyotomi.hokkaido.jp\0sk\xc3\xa1nit.no\0" -"ikeda.gifu.jp\0" -"trentino.it\0kyuragi.saga.jp\0" -"si.it\0asda\0" -"maritimo.museum\0bv.nl\0" -"greta.fr\0" -"xxx\0arte\0" -"s3.eu-west-2.amazonaws.com\0" -"mibu.tochigi.jp\0" -"codespot.com\0" -"meloy.no\0" -"\xe7\xa7\x8b\xe7\x94\xb0.jp\0" -"ms.leg.br\0" -"planetarium.museum\0al.leg.br\0" -"abruzzo.it\0kaneyama.yamagata.jp\0" -"gob.ve\0" -"\xe5\x92\x8c\xe6\xad\x8c\xe5\xb1\xb1.jp\0read-books.org\0" -"xyz\0nym.by\0" -"higashichichibu.saitama.jp\0catholic\0nym.bz\0" -"minamiboso.chiba.jp\0" -"barletta-trani-andria.it\0r\xc3\xa1isa.no\0" -"vladimir.ru\0" -"ise.mie.jp\0arts.nf\0realestate\0" -"higashikagawa.kagawa.jp\0kristiansand.no\0" -"pavia.it\0bbva\0salon\0" -"hoyanger.no\0" -"codes\0" -"tabuse.yamaguchi.jp\0" -"esashi.hokkaido.jp\0" -"joboji.iwate.jp\0h\xc3\xb8ylandet.no\0" -"tatar\0" -"mt.leg.br\0" -"4.bg\0bahcavuotna.no\0" -"aogaki.hyogo.jp\0settsu.osaka.jp\0" -"nishi.osaka.jp\0" -"from-pa.com\0" -"ibaraki.ibaraki.jp\0kitamoto.saitama.jp\0" -"campobasso.it\0furniture\0" -"here\0" -"nanto.toyama.jp\0" -"komae.tokyo.jp\0familyds.org\0" -"dynalias.com\0" -"kushiro.hokkaido.jp\0poznan.pl\0" -"kitaura.miyazaki.jp\0\xd8\xa8\xd9\x8a\xd8\xaa\xd9\x83\0" -"lib.ee\0" -"hirosaki.aomori.jp\0modern.museum\0" -"waw.pl\0" -"isehara.kanagawa.jp\0goto.nagasaki.jp\0barsyonline.com\0" -"health.nz\0guru\0" -"rishirifuji.hokkaido.jp\0" -"bolzano.it\0sor-aurdal.no\0volda.no\0" -"kami.kochi.jp\0promo\0" -"asia\0foundation.museum\0ustka.pl\0" -"ws.na\0" -"bologna.it\0gs.hm.no\0" -"imperia.it\0fusa.no\0" -"merckmsd\0reviews\0firewall-gateway.com\0" -"press.cy\0j\xc3\xb8lster.no\0" -"globo\0" -"uto.kumamoto.jp\0" -"k12.mn.us\0" -"\xe6\xbe\xb3\xe9\x97\xa8\0nym.gr\0" -"minamiise.mie.jp\0" -"delivery\0elasticbeanstalk.com\0" -"r\xc3\xa5""de.no\0" -"ballooning.aero\0priv.hu\0" -"nationalfirearms.museum\0k12.pa.us\0" -"tselinograd.su\0" -"koto.shiga.jp\0kr\xc3\xb8""dsherad.no\0" -"nm.cn\0" -"dy.fi\0" -"ayagawa.kagawa.jp\0" -"dynamic-dns.info\0" -"gs.ol.no\0ping\0you\0" -"goshiki.hyogo.jp\0" -"pink\0" -"kamisunagawa.hokkaido.jp\0" -"nogata.fukuoka.jp\0" -"artcenter.museum\0" -"omura.nagasaki.jp\0" -"kai.yamanashi.jp\0usantiques.museum\0" -"luzern.museum\0" -"kuwana.mie.jp\0" -"rehab\0" -"kasuga.fukuoka.jp\0" -"pilots.museum\0" -"ino.kochi.jp\0square7.net\0" -"herad.no\0blogspot.co.at\0" -"bradesco\0" -"friuli-vgiulia.it\0spdns.eu\0" -"act.au\0iwatsuki.saitama.jp\0cc.dc.us\0" -"kinko.kagoshima.jp\0" -"tatsuno.nagano.jp\0" -"sand\xc3\xb8y.no\0" -"masfjorden.no\0" -"bt.it\0myactivedirectory.com\0" -"\xe5\x8c\x97\xe6\xb5\xb7\xe9\x81\x93.jp\0nym.la\0" -"baghdad.museum\0" -"seljord.no\0" -"archaeology.museum\0" -"natural.bo\0" -"isen.kagoshima.jp\0" -"nym.li\0" -"santabarbara.museum\0nym.kz\0" -"kamiizumi.saitama.jp\0" -"minato.osaka.jp\0" -"puglia.it\0nico\0" -"nara.jp\0" -"alabama.museum\0gjerdrum.no\0nym.lt\0" -"nym.lu\0nym.me\0" -"priv.at\0" -"birkenes.no\0""4u.com\0" -"ishigaki.okinawa.jp\0virgin\0" -"fujisawa.kanagawa.jp\0ngrok.io\0" -"is.it\0" -"intelligence.museum\0" -"name.vn\0" -"health.vn\0" -"uzhgorod.ua\0" -"yokosuka.kanagawa.jp\0murata.miyagi.jp\0taobao\0" -"from.hr\0" -"nym.mx\0" -"travelers\0" -"\xe7\xae\x87\xe4\xba\xba.hk\0" -"tokoname.aichi.jp\0graz.museum\0stockholm.museum\0nordre-land.no\0yun\0" -"shinjo.okayama.jp\0" -"ninja\0statebank\0" -"kr\xc3\xa5""anghke.no\0" -"kasai.hyogo.jp\0" -"nakagawa.fukuoka.jp\0" -"temasek\0" -"gucci\0nym.nz\0" -"pr.it\0nakamura.kochi.jp\0name.tj\0" -"!www.ck\0" -"dyndns1.de\0" -"\xce\xb5\xce\xbb\0ap-northeast-1.elasticbeanstalk.com\0" -"science-fiction.museum\0" -"suli.hu\0name.tr\0" -"mer\xc3\xa5ker.no\0r\xc3\xb8ros.no\0is-a-chef.net\0nym.pe\0" -"name.tt\0" -"mie.jp\0" -"environmentalconservation.museum\0" -"kikugawa.shizuoka.jp\0" -"miyoshi.saitama.jp\0" -"sogne.no\0dsmynas.com\0" -"anjo.aichi.jp\0mincom.tn\0ee.eu.org\0" -"edunet.tn\0" -"bari.it\0" -"murmansk.su\0collegefan.org\0nym.pt\0" -"spdns.de\0" -"leksvik.no\0" -"nesset.no\0stokke.no\0" -"workinggroup.aero\0\xc3\xb8yer.no\0" -"deal\0" -"deporte.bo\0tattoo\0" -"skanit.no\0lib.mi.us\0" -"sakegawa.yamagata.jp\0grane.no\0" -"medicina.bo\0" -"labour.museum\0edu.eu.org\0blogspot.co.id\0" -"izumiotsu.osaka.jp\0" -"tuscany.it\0" -"l\xc3\xb8""dingen.no\0starhub\0" -"shinshinotsu.hokkaido.jp\0" -"nishikatsura.yamanashi.jp\0paleo.museum\0selfip.org\0" -"blogspot.co.il\0" -"francaise.museum\0" -"nore-og-uvdal.no\0" -"zip\0" -"video.hu\0*.quipelements.com\0" -"naoshima.kagawa.jp\0" -"obama.fukui.jp\0hiroo.hokkaido.jp\0" -"2.bg\0surrey.museum\0" -"valle-aosta.it\0baltimore.museum\0deloitte\0" -"jaworzno.pl\0" -"nym.sk\0" -"kongsberg.no\0" -"frog.museum\0" -"*.cryptonomic.net\0" -"\xd9\x82\xd8\xb7\xd8\xb1\0" -"name.qa\0" -"name.pr\0" -"int.ar\0academia.bo\0nike\0nym.su\0" -"service.gov.uk\0" -"toyotsu.fukuoka.jp\0" -"nym.sx\0" -"int.az\0" -"mat.br\0" -"int.bo\0rel.ht\0svizzera.museum\0cloudns.eu\0" -"udine.it\0name.na\0" -"vang.no\0" -"kahoku.ishikawa.jp\0katsuragi.wakayama.jp\0" -"nym.tw\0" -"kasaoka.okayama.jp\0name.mv\0" -"name.ng\0opoczno.pl\0" -"taiki.hokkaido.jp\0" -"name.my\0" -"int.ci\0" -"yamagata.yamagata.jp\0" -"twmail.net\0" -"ichikawa.chiba.jp\0office\0" -"k12.mt.us\0" -"int.co\0" -"austrheim.no\0" -"pp.az\0hellas.museum\0cbg.ru\0" -"oyer.no\0" -"komforb.se\0\xe6\x85\x88\xe5\x96\x84\0" -"barefoot\0" -"tachikawa.tokyo.jp\0" -"surnadal.no\0" -"shinichi.hiroshima.jp\0moriya.ibaraki.jp\0" -"nakanoto.ishikawa.jp\0" -"tysvar.no\0" -"naturalsciences.museum\0" -"kasumigaura.ibaraki.jp\0corvette.museum\0" -"academy.museum\0google\0" -"philadelphia.museum\0" -"sakurai.nara.jp\0aukra.no\0" -"broadcast.museum\0gs.jan-mayen.no\0" -"marshalls\0cust.prod.thingdust.io\0" -"hokuto.yamanashi.jp\0" -"gs.st.no\0cloudns.in\0" -"nishi.fukuoka.jp\0name.mk\0showtime\0" -"cc.al.us\0hb.cldmail.ru\0" -"gdansk.pl\0" -"uvic.museum\0" -"macys\0jdevcloud.com\0" -"berlin.museum\0evenassi.no\0" -"mitaka.tokyo.jp\0ru.com\0se.com\0" -"takahama.fukui.jp\0" -"dontexist.com\0" -"shikokuchuo.ehime.jp\0cloudns.cc\0" -"name.jo\0tateyama.chiba.jp\0" -"kota.aichi.jp\0" -"br.it\0cb.it\0floro.no\0" -"coupon\0from-ne.com\0" -"press.se\0" -"vagsoy.no\0" -"watarai.mie.jp\0worse-than.tv\0" -"massacarrara.it\0" -"sor-odal.no\0" -"limanowa.pl\0" -"owariasahi.aichi.jp\0phoenix.museum\0nm.us\0" -"zhitomir.ua\0" -"narita.chiba.jp\0" -"matsumae.hokkaido.jp\0" -"\xe7\xa5\x9e\xe5\xa5\x88\xe5\xb7\x9d.jp\0" -"pr.us\0" -"engineer\0" -"lidl\0pointto.us\0" -"indigena.bo\0cc.me.us\0" -"tenri.nara.jp\0burghof.museum\0" -"jp.net\0" -"int.is\0" -"skedsmo.no\0" -"ogliastra.it\0himeji.hyogo.jp\0rel.pl\0" -"dell\0" -"minnesota.museum\0" -"otsuki.yamanashi.jp\0flekkefjord.no\0" -"uchihara.ibaraki.jp\0" -"mycd.eu\0" -"asmatart.museum\0life\0webredirect.org\0" -"misato.shimane.jp\0sopot.pl\0" -"game.tw\0\xd8\xa7\xd9\x8a\xd8\xb1\xd8\xa7\xd9\x86\0" -"risor.no\0" -"yahiko.niigata.jp\0" -"odo.br\0int.la\0is-a-bulls-fan.com\0" -"lunner.no\0" -"lodi.it\0nishigo.fukushima.jp\0" -"cc.vi.us\0blogspot.co.uk\0" -"nemuro.hokkaido.jp\0shimoji.okinawa.jp\0" -"piedmont.it\0" -"tennis\0" -"int.lk\0lib.gu.us\0" -"jur.pro\0*.cns.joyent.com\0" -"nanao.ishikawa.jp\0kunstunddesign.museum\0" -"sch.ae\0xerox\0eu-west-1.elasticbeanstalk.com\0" -"now.sh\0" -"paragliding.aero\0okagaki.fukuoka.jp\0yamazoe.nara.jp\0" -"susono.shizuoka.jp\0iwade.wakayama.jp\0r\xc3\xb8yrvik.no\0" -"shimogo.fukushima.jp\0yufu.oita.jp\0soc.lk\0" -"kagoshima.kagoshima.jp\0lib.in.us\0" -"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xdb\x8c\xd8\xa9\0duckdns.org\0penza.su\0" -"construction\0" -"etnedal.no\0" -"priv.pl\0" -"pug.it\0amsterdam.museum\0" -"\xe5\xb1\xb1\xe6\xa2\xa8.jp\0locker\0" -"press.ma\0" -"wakuya.miyagi.jp\0" -"mlbfan.org\0" -"gyeonggi.kr\0" -"int.mv\0" -"mizuho.tokyo.jp\0int.mw\0" -"for-more.biz\0" -"plc.ly\0int.ni\0" -"\xe0\xa6\xad\xe0\xa6\xbe\xe0\xa6\xb0\xe0\xa6\xa4\0" -"fukushima.fukushima.jp\0" -"krakow.pl\0" -"dedyn.io\0" -"school\0" -"0.bg\0taiki.mie.jp\0goodhands\0stuff-4-sale.us\0" -"priv.no\0" -"chrome\0zone\0kurgan.su\0serveminecraft.net\0" -"university\0" -"\xe9\xa3\x9f\xe5\x93\x81\0" -"sandvikcoromant\0" -"kyotanabe.kyoto.jp\0" -"berlin\0like\0" -"\xe5\xb1\xb1\xe5\xbd\xa2.jp\0" -"z.bg\0audi\0" -"azerbaijan.su\0" -"s3-website-ap-southeast-1.amazonaws.com\0cn.eu.org\0" -"verm\xc3\xb6gensberater\0" -"leikanger.no\0" -"\xe5\x85\xb5\xe5\xba\xab.jp\0" -"andoy.no\0" -"epilepsy.museum\0" -"int.pt\0" -"desi\0locus\0" -"satx.museum\0" -"iron.museum\0" -"n\xc3\xa1vuotna.no\0" -"nanmoku.gunma.jp\0nakai.kanagawa.jp\0kunitachi.tokyo.jp\0" -"bauern.museum\0" -"tempio-olbia.it\0" -"dolls.museum\0osteroy.no\0blogspot.co.ke\0" -"uscountryestate.museum\0beer\0" -"tobe.ehime.jp\0" -"priv.me\0browsersafetymark.io\0za.net\0" -"hiji.oita.jp\0" -"campania.it\0seiro.niigata.jp\0" -"homeip.net\0" -"democracia.bo\0tsushima.nagasaki.jp\0ipiranga\0" -"cloudns.us\0" -"brother\0" -"parachuting.aero\0limo\0" -"oumu.hokkaido.jp\0" -"gjesdal.no\0" -"int.ru\0" -"int.rw\0wmflabs.org\0" -"vistaprint\0" -"link\0" -"koshu.yamanashi.jp\0tvedestrand.no\0" -"friuli-v-giulia.it\0" -"sc.cn\0" -"lenug.su\0" -"the.br\0aya.miyazaki.jp\0hino.tottori.jp\0chimkent.su\0" -"\xe6\x89\x8b\xe6\x9c\xba\0" -"kita.tokyo.jp\0int.tj\0" -"mobile\0" -"pp.se\0pp.ru\0" -"sch.id\0semboku.akita.jp\0" -"\xd7\xa7\xd7\x95\xd7\x9d\0" -"corporation.museum\0int.tt\0onthewifi.com\0" -"kv.ua\0" -"swinoujscie.pl\0" -"trentinos-tirol.it\0fresenius\0" -"kounosu.saitama.jp\0elvendrell.museum\0exnet.su\0" -"shikabe.hokkaido.jp\0fuoisku.no\0cc.co.us\0from-id.com\0" -"kumamoto.kumamoto.jp\0kartuzy.pl\0" -"repbody.aero\0sch.ir\0tsuno.kochi.jp\0" -"qld.au\0" -"mobily\0" -"os.hordaland.no\0aetna\0" -"kitahata.saga.jp\0direct\0" -"kiev.ua\0" -"int.ve\0blogspot.co.nz\0" -"tomioka.gunma.jp\0" -"kawagoe.saitama.jp\0*.sensiosite.cloud\0" -"sch.jo\0pp.ua\0" -"katagami.akita.jp\0plc.uk\0cy.eu.org\0" -"hgtv\0" -"cc.hi.us\0" -"tochigi.jp\0int.vn\0" -"kumiyama.kyoto.jp\0badajoz.museum\0" -"umig.gov.pl\0" -"chijiwa.nagasaki.jp\0caravan\0" -"correios-e-telecomunica\xc3\xa7\xc3\xb5""es.museum\0flakstad.no\0" -"lom.it\0spdns.org\0" -"agano.niigata.jp\0" -"broke-it.net\0" -"mar.it\0satte.saitama.jp\0village.museum\0" -"is-a-llama.com\0" -"certification.aero\0ayabe.kyoto.jp\0poivron.org\0" -"hokksund.no\0" -"ujitawara.kyoto.jp\0" -"my.id\0nishinoshima.shimane.jp\0sch.lk\0" -"niepce.museum\0" -"vaapste.no\0" -"hokuto.hokkaido.jp\0" -"ojiya.niigata.jp\0cc.oh.us\0cz.eu.org\0" -"esan.hokkaido.jp\0daejeon.kr\0pacific.museum\0" -"\xd8\xa7\xd9\x84\xd9\x85\xd8\xba\xd8\xb1\xd8\xa8\0kerryhotels\0" -"minamiechizen.fukui.jp\0" -"sch.ly\0artanddesign.museum\0orskog.no\0" -"\xe6\x89\x8b\xe8\xa1\xa8\0" -"ogawa.saitama.jp\0gwangju.kr\0" -"myoko.niigata.jp\0" -"yugawara.kanagawa.jp\0glogow.pl\0lib.ca.us\0s3-us-west-2.amazonaws.com\0" -"piemonte.it\0trentinoa-adige.it\0cleaning\0" -"pn.it\0yamagata.jp\0" -"sch.ng\0tranby.no\0" -"chicago.museum\0" -"hvaler.no\0" -"nannestad.no\0" -"uchinomi.kagawa.jp\0" -"shinjuku.tokyo.jp\0reise\0sharp\0" -"inagi.tokyo.jp\0" -"dk.eu.org\0" -"saka.hiroshima.jp\0oregontrail.museum\0" -"dyn.ddnss.de\0" -"accountant\0" -"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xdb\x8c\xdb\x83\0" -"hasama.oita.jp\0play\0" -"live\0" -"passagens\0" -"okinawa\0" -"kvanangen.no\0" -"reggioemilia.it\0matsusaka.mie.jp\0" -"lom.no\0" -"maritime.museum\0targi.pl\0" -"gildeskal.no\0hk.org\0" +"coloradoplateau.museum\0" +"lc.it\0\xe5\xae\xae\xe5\x9f\x8e.jp\0stokke.no\0" +"kurume.fukuoka.jp\0" +"gratangen.no\0" +"kotohira.kagawa.jp\0ohkura.yamagata.jp\0gateway.museum\0" +"canada.museum\0exnet.su\0" "shinonsen.hyogo.jp\0" -"gmail\0" -"sc.kr\0" -"is-an-anarchist.com\0" -"sch.qa\0" -"lib.nv.us\0" -"hurum.no\0" -"cagliari.it\0" -"stordal.no\0" -"touch.museum\0" -"tozsde.hu\0servehumour.com\0" -"beauty\0" -"kirovograd.ua\0" -"ma.gov.br\0midtre-gauldal.no\0" -"ikusaka.nagano.jp\0gs.ah.no\0" +"sk.ca\0com.zm\0sfr\0" +"kitaura.miyazaki.jp\0githubusercontent.com\0" +"oita.jp\0rwe\0" +"dynu.net\0" +"otake.hiroshima.jp\0" +"kinko.kagoshima.jp\0" +"pippu.hokkaido.jp\0" +"gv.ao\0data\0" +"skydiving.aero\0" +"tsushima.aichi.jp\0date\0cy.eu.org\0servehttp.com\0" +"gv.at\0" +"nakatane.kagoshima.jp\0" +"sakurai.nara.jp\0as.us\0academy\0" +"tadaoka.osaka.jp\0" +"steigen.no\0" +"recreation.aero\0omachi.saga.jp\0aquarium.museum\0" +"gouv.fr\0nanjo.okinawa.jp\0" +"za.net\0" +"etisalat\0dynalias.net\0sp.leg.br\0" +"memorial.museum\0" +"motobu.okinawa.jp\0" +"gs.sf.no\0ro.eu.org\0" +"lincoln\0" +"selfip.info\0" +"mielno.pl\0us-east-1.amazonaws.com\0" +"kazo.saitama.jp\0on-the-web.tv\0" +"sar.it\0" +"omaezaki.shizuoka.jp\0is-into-anime.com\0" +"newjersey.museum\0" +"edunet.tn\0cz.eu.org\0" +"ayase.kanagawa.jp\0" +"kitanakagusuku.okinawa.jp\0rad\xc3\xb8y.no\0maison\0" +"trentinoa-adige.it\0scrysec.com\0" +"kamigori.hyogo.jp\0" +"kashima.saga.jp\0notaires.km\0" +"v.bg\0" +"furukawa.miyagi.jp\0" +"shirahama.wakayama.jp\0" +"gouv.ht\0" +"sodegaura.chiba.jp\0plantation.museum\0" +"taifun-dns.de\0" +"fujinomiya.shizuoka.jp\0luxembourg.museum\0" +"help\0" +"lans.museum\0askvoll.no\0cc.ca.us\0racing\0map.fastlylb.net\0" +"koriyama.fukushima.jp\0communication.museum\0" +"copenhagen.museum\0western.museum\0ski\0" +"konsulat.gov.pl\0" +"comsec\0" +"ravendb.community\0" +"savona.it\0" +"dk.eu.org\0" +"gouv.bj\0" +"aurskog-h\xc3\xb8land.no\0" +"skodje.no\0sky\0" +"koshigaya.saitama.jp\0c.se\0" +"monzaebrianza.it\0" +"inami.toyama.jp\0" +"ptplus.fit\0" +"gouv.ci\0" +"geekgalaxy.com\0" +"pagefrontapp.com\0" +"overhalla.no\0lidl\0si.eu.org\0" +"sugito.saitama.jp\0grajewo.pl\0" +"en.it\0" +"cloudns.club\0" +"crafts.museum\0" +"axis.museum\0" +"nakatombetsu.hokkaido.jp\0" +"kumamoto.jp\0" +"virtuel.museum\0" +"convent.museum\0" +"figueres.museum\0ustka.pl\0" +"vardo.no\0blogdns.org\0" +"life\0" +"eastcoast.museum\0dep.no\0" +"firmdale\0" +"sunndal.no\0servepics.com\0" +"durham.museum\0contact\0" +"settsu.osaka.jp\0" +"bv.nl\0" +"akune.kagoshima.jp\0" +"chiba.jp\0" "nid.io\0" +"\xc3\xa5lesund.no\0" +"komagane.nagano.jp\0" +"tenri.nara.jp\0" +"kasama.ibaraki.jp\0ullensvang.no\0\xd8\xb9\xd9\x85\xd8\xa7\xd9\x86\0de.eu.org\0" +"tondabayashi.osaka.jp\0" +"aso.kumamoto.jp\0" +"br\xc3\xb8nn\xc3\xb8y.no\0here\0" +"kuromatsunai.hokkaido.jp\0everbank\0soy\0from-nv.com\0" +"drammen.no\0" +"on.ca\0" +"univ.sn\0" +"vc.it\0" +"contemporary.museum\0farsund.no\0wang\0" +, + +"obama.nagasaki.jp\0supplies\0" +"s3-eu-west-1.amazonaws.com\0bci.dnstrace.pro\0" +"tab\0" +"krym.ua\0usr.cloud.muni.cz\0" +"sk.eu.org\0" +"\xe0\xb8\x98\xe0\xb8\xb8\xe0\xb8\xa3\xe0\xb8\x81\xe0\xb8\xb4\xe0\xb8\x88.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0fujitsu\0s3-ap-south-1.amazonaws.com\0cn.com\0" +"ks.ua\0" +"asahi.toyama.jp\0other.nf\0guru\0us-east-2.elasticbeanstalk.com\0" +"nordre-land.no\0rackmaze.net\0" +"kanan.osaka.jp\0" +"autos\0" +"gangaviika.no\0" +"baby\0" +"shell.museum\0" +"melhus.no\0" +"\xc3\xa5mot.no\0" +"tax\0" +"ugim.gov.pl\0ks.us\0" +"hioki.kagoshima.jp\0" +"srl\0from-va.com\0" +"epson\0s3-website.ca-central-1.amazonaws.com\0" +"dsmynas.com\0" +"natal.br\0" +"friulive-giulia.it\0photography\0" +"\xe5\xaf\x8c\xe5\xb1\xb1.jp\0sano.tochigi.jp\0" +"tselinograd.su\0lcube-server.de\0" +"bunkyo.tokyo.jp\0srt\0" +"grainger\0" +"genkai.saga.jp\0meteorapp.com\0" +"certmgr.org\0" +"tci\0" +"cc.wv.us\0" +"mansion.museum\0lib.ia.us\0" +"oppeg\xc3\xa5rd.no\0oster\xc3\xb8y.no\0like\0" +"corporation.museum\0" +"foz.br\0yamato.kumamoto.jp\0" +"naie.hokkaido.jp\0" +"9.bg\0yame.fukuoka.jp\0" +"stc\0" +"matsuda.kanagawa.jp\0" +"gol.no\0" +"\xe9\x80\x9a\xe8\xb2\xa9\0" "drayddns.com\0" -"cloudns.pw\0hashbang.sh\0" -"turen.tn\0" -"portland.museum\0" -"lib.vi.us\0" -"x.bg\0sch.sa\0de.eu.org\0" -"ringebu.no\0" -"kvits\xc3\xb8y.no\0" -"aver\xc3\xb8y.no\0" -"m\xc4\x81ori.nz\0" -"seika.kyoto.jp\0" -"townnews-staging.com\0" -"kobayashi.miyazaki.jp\0resistance.museum\0" -"s\xc3\xb8r-varanger.no\0" -"discount\0" -"shinto.gunma.jp\0" -"higashiyama.kyoto.jp\0" -"hashima.gifu.jp\0" -"vanguard\0" -"saijo.ehime.jp\0" -"fr\xc3\xb8ya.no\0abarth\0best\0" -"k12.nh.us\0" -"sunagawa.hokkaido.jp\0" -"eu.int\0" -"tsuchiura.ibaraki.jp\0" -"omaezaki.shizuoka.jp\0sejny.pl\0" -"blogspot.co.za\0" -"sa.au\0" -"auto\0" -"elverum.no\0fairwinds\0" -"umb.it\0ochi.kochi.jp\0" -"tv.bb\0veneto.it\0" -"okinoshima.shimane.jp\0z.se\0" -"gs.of.no\0" -"\xe7\xa6\x8f\xe5\xb3\xb6.jp\0prochowice.pl\0" -"shonai.yamagata.jp\0supply\0" -"ashikaga.tochigi.jp\0stange.no\0" -"gujo.gifu.jp\0bible.museum\0" -"tv.bo\0dyn-o-saur.com\0" -"forli-cesena.it\0mizunami.gifu.jp\0frana.no\0" -"tv.br\0" -"govt.nz\0metlife\0" -"takatsuki.shiga.jp\0wpdevcloud.com\0" -"sa.cr\0\xe5\xa5\x88\xe8\x89\xaf.jp\0kopervik.no\0" -"historisch.museum\0nyny.museum\0" -"k12.vt.us\0is-uberleet.com\0" -"jevnaker.no\0" -"vda.it\0larsson.museum\0maori.nz\0" -"cremona.it\0" -"barsy.net\0" -"emr.it\0" -"\xe5\xba\x83\xe5\xb3\xb6.jp\0" -"ass.km\0v\xc3\xa5gs\xc3\xb8y.no\0" -"etisalat\0" -"noda.chiba.jp\0dominic.ua\0flickr\0sochi.su\0" -"oguchi.aichi.jp\0herokussl.com\0" -"kasuya.fukuoka.jp\0\xd9\x83\xd9\x88\xd9\x85\0" -"cosenza.it\0" -"yalta.ua\0download\0" -"bn.it\0" -"rade.no\0" -"ro.eu.org\0" -"bytom.pl\0" -"onion\0rmit\0homeunix.com\0ybo.faith\0" -"flanders.museum\0" -"london.museum\0\xd9\x85\xd9\x88\xd9\x82\xd8\xb9\0" -"hamburg.museum\0" -"altoadige.it\0house.museum\0dnsiskinky.com\0" -"collection.museum\0countryestate.museum\0netflix\0" -"shirakawa.fukushima.jp\0cherkassy.ua\0" -"dnepropetrovsk.ua\0" -"sc.ug\0" -"sc.tz\0" -"pharmacien.fr\0brunel.museum\0\xe5\x81\xa5\xe5\xba\xb7\0router.management\0" -"finland.museum\0demon.nl\0" -"im.it\0cc.ma.us\0\xe6\xb7\xa1\xe9\xa9\xac\xe9\x94\xa1\0" -"rishiri.hokkaido.jp\0actor\0" -"health\0" -"hirata.fukushima.jp\0daito.osaka.jp\0sch.zm\0" -"sc.us\0" -"my-gateway.de\0" -"ca.eu.org\0" -"moriyoshi.akita.jp\0s3-website.eu-central-1.amazonaws.com\0" -"kr.it\0setouchi.okayama.jp\0cc.nv.us\0" -"nagiso.nagano.jp\0" -"ascoli-piceno.it\0tx.us\0" -"otaki.nagano.jp\0" -"journalism.museum\0" -"\xe9\x9b\x86\xe5\x9b\xa2\0" -"biella.it\0" -"fujimi.saitama.jp\0" -"consulting.aero\0kvafjord.no\0ooguy.com\0" -"shimabara.nagasaki.jp\0yatsuka.shimane.jp\0" -"sakuho.nagano.jp\0twmail.org\0" -"shibata.niigata.jp\0corsica\0" -"gb.com\0" -"takaishi.osaka.jp\0" -"eastcoast.museum\0" -"lib.fl.us\0volkswagen\0" -"si.eu.org\0" -"kisofukushima.nagano.jp\0\xd9\xbe\xd8\xa7\xda\xa9\xd8\xb3\xd8\xaa\xd8\xa7\xd9\x86\0co.com\0selfip.biz\0" -"trentino-stirol.it\0mamurogawa.yamagata.jp\0" -"sa.it\0" -"suzuki\0" -"tv.im\0is-a-player.com\0" -"entomology.museum\0" -"lib.hi.us\0istmein.de\0" -"from-ak.com\0" -"time.no\0homedepot\0" +"us.na\0caseih\0tdk\0" +"narvik.no\0" +"jpmorgan\0" +"selfip.org\0" +"town\0" +"ru.eu.org\0se.eu.org\0" +"langevag.no\0" +"market\0" +"su\xcc\x88""dtirol.it\0" +"cc.ma.us\0" +"tel\0" +"bulsan.it\0" +"masoy.no\0" +"k12.nm.us\0" +"sanofi\0" +"cloudns.info\0" +"lib.ky.us\0" +"obama.fukui.jp\0limo\0" +"a.bg\0r\xc3\xa1isa.no\0" +"cymru.museum\0isa-geek.net\0" +"aq.it\0ba.it\0" +"link\0" +"bozen-suedtirol.it\0minamiminowa.nagano.jp\0cc.al.us\0lima.zone\0" +"toys\0" +"sciencecenters.museum\0" +"guardian\0" +"kongsberg.no\0" +"cc.ny.us\0ca.eu.org\0" +"trentino-alto-adige.it\0kitaaiki.nagano.jp\0lib.al.us\0thd\0" +"halden.no\0" +"fashion\0" +"myftp.biz\0" +"moriyama.shiga.jp\0rsc.cdn77.org\0from-ky.com\0" +"\xe4\xb8\x89\xe9\x87\x8d.jp\0fidelity\0" +"\xe5\xb1\xb1\xe6\xa2\xa8.jp\0" +"somna.no\0" +"productions\0voting\0" +"forde.no\0" +"chikuzen.fukuoka.jp\0plus\0" +"mashike.hokkaido.jp\0" +"leksvik.no\0" +"hagi.yamaguchi.jp\0" +"publ.pt\0" +"1kapp.com\0" +"\xd8\xaa\xd9\x88\xd9\x86\xd8\xb3\0" +"showa.fukushima.jp\0" +"yamatsuri.fukushima.jp\0is-a-designer.com\0" +"cc.ct.us\0" +"takikawa.hokkaido.jp\0*.stolos.io\0" +"cpa.pro\0garden\0" +"wiki.bo\0" +"wiki.br\0" +"itayanagi.aomori.jp\0store.nf\0" +"asahikawa.hokkaido.jp\0fudai.iwate.jp\0" +"dallas.museum\0" +"is-an-anarchist.com\0" +"sakegawa.yamagata.jp\0" +"kanagawa.jp\0yamatotakada.nara.jp\0alabama.museum\0" +"\xd0\xbe\xd0\xbd\xd0\xbb\xd0\xb0\xd0\xb9\xd0\xbd\0" +"tjx\0" +"est-a-la-maison.com\0" +"yn.cn\0" +"funahashi.toyama.jp\0torino.museum\0" +"eiheiji.fukui.jp\0coldwar.museum\0" +"podhale.pl\0airbus\0" +"yamada.iwate.jp\0" +"walmart\0on-web.fr\0" +"friuli-v-giulia.it\0" +"hareid.no\0cc.fl.us\0" +"valled-aosta.it\0" +"shiroishi.saga.jp\0" +"band\0" +"karumai.iwate.jp\0" +"tn.it\0gouv.rw\0" +"spjelkavik.no\0zachpomor.pl\0" +"iwaizumi.iwate.jp\0" +"turek.pl\0\xe5\xb7\xa5\xe8\xa1\x8c\0" +"exhibition.museum\0serveftp.com\0" +"otaki.saitama.jp\0m\xc3\xa1latvuopmi.no\0bank\0" +"lib.fl.us\0social\0" +"bronnoy.no\0hoyanger.no\0gouv.sn\0software\0" +"stalowa-wola.pl\0consulting\0spdns.eu\0" +"kaufen\0" +"tromsa.no\0" +"takatsuki.osaka.jp\0" +"kagamiishi.fukushima.jp\0cd.eu.org\0" +"sondre-land.no\0" +"tennis\0" +"ginoza.okinawa.jp\0" +"s3.eu-central-1.amazonaws.com\0" +"ngo.lk\0" +"beardu.no\0" +"rikuzentakata.iwate.jp\0live\0" +"rotorcraft.aero\0" +"frei.no\0" +"sk\xc3\xa1nit.no\0mazowsze.pl\0cc.id.us\0tunk.org\0" +"laquila.it\0" +"ricoh\0" +"nagi.okayama.jp\0" +"vv.it\0" +"shacknet.nu\0" +"arab\0" +"matsusaka.mie.jp\0cc.wa.us\0" +"daiwa.hiroshima.jp\0dnsking.ch\0" +"sardinia.it\0mihara.kochi.jp\0lanbib.se\0top\0" +"prato.it\0lixil\0" +"nosegawa.nara.jp\0lv.ua\0" +"namegata.ibaraki.jp\0wolomin.pl\0christmas\0" +"sp.gov.br\0" +"dclk\0" +"nesseby.no\0lib.vi.us\0" +"trentinsuedtirol.it\0herokussl.com\0" +"ham-radio-op.net\0" +"shiogama.miyagi.jp\0jobs.tt\0" +"kawara.fukuoka.jp\0" +"nsw.au\0divtasvuodna.no\0" +"res.aero\0" +"kagamino.okayama.jp\0alvdal.no\0" +"enonic.io\0" +"mex.com\0" +"devices.resinstaging.io\0" +"nebraska.museum\0" +"jamison.museum\0" +"esp.br\0" +"muosat.no\0" +"chiyoda.gunma.jp\0" +"monza-e-della-brianza.it\0okutama.tokyo.jp\0sn\xc3\xa5""ase.no\0s\xc3\xb8rreisa.no\0email\0" +"cuiaba.br\0" +"yasugi.shimane.jp\0ngo.ph\0store.ve\0" +"shimabara.nagasaki.jp\0" +"friuli-venezia-giulia.it\0" +"zaporizhzhe.ua\0mortgage\0" +"brunel.museum\0" +"my.id\0kita.kyoto.jp\0kawatana.nagasaki.jp\0mugi.tokushima.jp\0" +"ubs\0kalmykia.su\0cust.dev.thingdust.io\0" +"newholland\0trv\0" +"assn.lk\0spdns.de\0" +"embroidery.museum\0" +"shiriuchi.hokkaido.jp\0" +"utah.museum\0forsand.no\0mycd.eu\0" +"fukuoka.jp\0so.gov.pl\0" +"romsa.no\0" +"odate.akita.jp\0anamizu.ishikawa.jp\0tateyama.toyama.jp\0bodo.no\0holdings\0" +"cc.mt.us\0cc.nd.us\0" +"go.dyndns.org\0" +"\xd8\xa7\xd9\x8a\xd8\xb1\xd8\xa7\xd9\x86.ir\0alta.no\0" +"ukiha.fukuoka.jp\0" +"sites.static.land\0" +"stordal.no\0" +"katsuragi.nara.jp\0" +"katori.chiba.jp\0" +"firm.ht\0sener\0" +"lib.md.us\0from-nj.com\0za.org\0" +"tokyo.jp\0higashiizu.shizuoka.jp\0" +"t.bg\0shimotsuke.tochigi.jp\0gouv.km\0" +"verran.no\0" +"tui\0" +"uri.arpa\0firm.in\0ureshino.mie.jp\0flynnhub.com\0" +"notaires.fr\0*.elb.amazonaws.com\0" +"bt.it\0gjesdal.no\0" +"*.kitakyushu.jp\0shijonawate.osaka.jp\0cloud.goog\0" +"aikawa.kanagawa.jp\0" +"edogawa.tokyo.jp\0\xe5\xa4\xa7\xe4\xbc\x97\xe6\xb1\xbd\xe8\xbd\xa6\0" +"kalmykia.ru\0" +"enna.it\0leitungsen.de\0" +"morotsuka.miyazaki.jp\0nichinan.tottori.jp\0burghof.museum\0\xe3\x83\x95\xe3\x82\xa1\xe3\x83\x83\xe3\x82\xb7\xe3\x83\xa7\xe3\x83\xb3\0" +"ryuoh.shiga.jp\0" +"fortal.br\0!city.nagoya.jp\0kamoenai.hokkaido.jp\0int.eu.org\0" +"floro.no\0holt\xc3\xa5len.no\0" +"condos\0stream\0" +"supply\0bmoattachments.org\0" +"to.leg.br\0" +"kanzaki.saga.jp\0store.ro\0" +"jl.cn\0taiki.mie.jp\0tvs\0" +"jerusalem.museum\0" +"gouv.ml\0""3utilities.com\0" +"a.se\0pramerica\0" +"money.museum\0" +"firm.co\0" +"ono.fukushima.jp\0nordreisa.no\0" +"room\0" +"paragliding.aero\0pri.ee\0hobby-site.com\0" +"pasadena.museum\0" +"newmexico.museum\0" +"bremanger.no\0ga.us\0" +"ostroleka.pl\0store.st\0s3-website.eu-west-3.amazonaws.com\0" +"firm.dk\0" +"fineart.museum\0" +"osaka.jp\0" +"trentinsu\xcc\x88""dtirol.it\0" +"torahime.shiga.jp\0unusualperson.com\0" +"priv.hu\0tn.us\0alpha-myqnapcloud.com\0" +"si.it\0miyashiro.saitama.jp\0" +"*.awdev.ca\0" +"tsukumi.oita.jp\0" +"cc.sd.us\0" +"md.ci\0kaneyama.fukushima.jp\0" +"kakamigahara.gifu.jp\0lib.dc.us\0" +"vologda.su\0" +"\xd8\xa8\xd8\xa7\xd8\xb1\xd8\xaa\0" +"yotsukaido.chiba.jp\0motorcycle.museum\0" +"bugatti\0" +"ogawa.nagano.jp\0dentist\0" +"chitose.hokkaido.jp\0debian.net\0" +"chicago.museum\0newhampshire.museum\0stavanger.no\0" +"n\xc3\xa1vuotna.no\0" +"can.museum\0oceanographic.museum\0definima.net\0" +"telefonica\0" +"chrome\0" +"cal.it\0" +"living\0cyon.site\0" +"va.it\0" +"trust\0" +"kakogawa.hyogo.jp\0" +"group\0" +"ngo.za\0" +"ong.br\0" +"\xe0\xa8\xad\xe0\xa8\xbe\xe0\xa8\xb0\xe0\xa8\xa4\0" +"morena.br\0" +"s3.cn-north-1.amazonaws.com.cn\0" +"yura.wakayama.jp\0dnsupdater.de\0" +"shirataka.yamagata.jp\0" +"army\0dynalias.org\0" +"fukuroi.shizuoka.jp\0la.us\0" +"priv.at\0" +"kira.aichi.jp\0nagai.yamagata.jp\0kristiansand.no\0" +"sr.gov.pl\0" +"abogado\0" +"asahi.ibaraki.jp\0" +"\xe7\xa7\x8b\xe7\x94\xb0.jp\0yakumo.hokkaido.jp\0higashikagawa.kagawa.jp\0dnepropetrovsk.ua\0" +"askoy.no\0" +"fishing\0" +"tamano.okayama.jp\0" +"arpa\0*.sensiosite.cloud\0" +"birkenes.no\0sejny.pl\0" +"7.bg\0uno\0" +"hisayama.fukuoka.jp\0delivery\0" +"adm.br\0skanit.no\0" +"praxi\0getmyip.com\0" +"lib.vt.us\0" +"friuliv-giulia.it\0" +"agrar.hu\0" +"williamsburg.museum\0" +"minamioguni.kumamoto.jp\0" +"uol\0" +"beskidy.pl\0df.leg.br\0" +"archi\0" +"2000.hu\0kyoto.jp\0mitoyo.kagawa.jp\0" +"lt.it\0" +"cosenza.it\0va.no\0" +"musica.ar\0cuisinella\0" +"mus.mi.us\0" +"chiryu.aichi.jp\0kyiv.ua\0" +"services.aero\0takahama.fukui.jp\0yanagawa.fukuoka.jp\0kautokeino.no\0" +"fl\xc3\xa5.no\0" +"ups\0" +"tonosho.kagawa.jp\0" +"forum.hu\0is-a-personaltrainer.com\0" +"musica.bo\0otsuchi.iwate.jp\0adygeya.su\0" +"broker.aero\0yonabaru.okinawa.jp\0" +"s3-us-east-2.amazonaws.com\0" +"ao.it\0" +"firm.ve\0*.ex.futurecms.at\0" +"shiiba.miyazaki.jp\0management\0" +"ichinohe.iwate.jp\0lardal.no\0" +"blogdns.net\0" +"lazio.it\0" +"trentinoaadige.it\0asda\0" +"arte\0" +"bulsan-suedtirol.it\0egyptian.museum\0" +"kerryhotels\0" +"hgtv\0" +"\xe0\xb8\x84\xe0\xb8\xad\xe0\xb8\xa1\0" +"lib.ms.us\0lib.nc.us\0" +"valle-d-aosta.it\0komatsu.ishikawa.jp\0ringebu.no\0" +"sagamihara.kanagawa.jp\0" +"ug.gov.pl\0" +"taranto.it\0" +"ap-southeast-2.elasticbeanstalk.com\0" +"ogi.saga.jp\0mill.museum\0" +"health.nz\0" +"adygeya.ru\0" +"gru.br\0dyn.cosidns.de\0" +"bbva\0tmall\0" +"oshima.yamaguchi.jp\0sumy.ua\0" +"shiga.jp\0sakawa.kochi.jp\0" +"drive\0s3-ca-central-1.amazonaws.com\0" +"mielec.pl\0" +"minamiawaji.hyogo.jp\0okayama.okayama.jp\0baltimore.museum\0" +"paleo.museum\0eidsberg.no\0" +"hotels\0" +"aero.tt\0" +"deal\0" +"drud.io\0" +"alstahaug.no\0uconnect\0" +"ryukyu\0" +"suzuka.mie.jp\0ch.eu.org\0firewall-gateway.net\0" +"naha.okinawa.jp\0" +"entertainment.aero\0store.bb\0t.se\0vet\0" +"l\xc3\xa1hppi.no\0" +"brumunddal.no\0" +"aero.mv\0kwpsp.gov.pl\0" +"firm.ro\0" +"eu-west-1.elasticbeanstalk.com\0" +"keisen.fukuoka.jp\0dynv6.net\0" +"klepp.no\0" +"matsubushi.saitama.jp\0" +"takazaki.miyazaki.jp\0irish\0" +"taishi.hyogo.jp\0luster.no\0" +"ol.no\0" +"vallee-aoste.it\0" +"sannohe.aomori.jp\0kumamoto.kumamoto.jp\0" +"vacations\0" +"va.us\0" +"asia\0" +"hamburg\0" +"agents.aero\0\xd9\x82\xd8\xb7\xd8\xb1\0" +"sula.no\0\xe0\xae\x9a\xe0\xae\xbf\xe0\xae\x99\xe0\xaf\x8d\xe0\xae\x95\xe0\xae\xaa\xe0\xaf\x8d\xe0\xae\xaa\xe0\xaf\x82\xe0\xae\xb0\xe0\xaf\x8d\0" +"benevento.it\0" +"yonezawa.yamagata.jp\0" +"giessen.museum\0" +"venezia.it\0serveirc.com\0" +"dyr\xc3\xb8y.no\0" +"toba.mie.jp\0" +"higashi.fukushima.jp\0skoczow.pl\0" +"store.dk\0" +"esashi.hokkaido.jp\0lib.sc.us\0" +"komae.tokyo.jp\0sells-it.net\0nalchik.ru\0" +"daigo.ibaraki.jp\0kirkenes.no\0nowtv\0" +"shiroi.chiba.jp\0kakegawa.shizuoka.jp\0mining.museum\0" +"vig\0\xd8\xa8\xd9\x8a\xd8\xaa\xd9\x83\0" +"myddns.rocks\0" +"muos\xc3\xa1t.no\0" +"oygarden.no\0" +"gs.mr.no\0" +"vin\0" +"florence.it\0vip\0nalchik.su\0" +"saitama.jp\0asnes.no\0" +"tateshina.nagano.jp\0kamitsue.oita.jp\0firm.nf\0" +"wy.us\0" +"vt.it\0" +"lerdal.no\0" +"groks-this.info\0" +"fujisawa.iwate.jp\0" +"tas.au\0ibara.okayama.jp\0" +"lt.ua\0" +"health.museum\0" +"pfizer\0" +"toride.ibaraki.jp\0salangen.no\0" +"toyonaka.osaka.jp\0charity\0" +"izena.okinawa.jp\0school.museum\0" +"l-o-g-i-n.de\0" +"health.vn\0dyndns.biz\0" +"friuli-ve-giulia.it\0vegarshei.no\0" +"nahari.kochi.jp\0pohl\0" +"dyndns-blog.com\0" +"suldal.no\0md.us\0" +"nord-aurdal.no\0" +"higashi.fukuoka.jp\0" +"gran.no\0" +"app.os.stg.fedoraproject.org\0" +"katsushika.tokyo.jp\0nanbu.yamanashi.jp\0anquan\0cloudns.eu\0" +"honbetsu.hokkaido.jp\0" +"salzburg.museum\0sorum.no\0" +"asaminami.hiroshima.jp\0" +"is-a-llama.com\0" +"selfip.biz\0" +"malatvuopmi.no\0rivne.ua\0lib.in.us\0" +"\xe5\xb1\xb1\xe5\xbd\xa2.jp\0" +"shikaoi.hokkaido.jp\0buyshouses.net\0" +"lind\xc3\xa5s.no\0tarnobrzeg.pl\0" +"forex\0" +"andriabarlettatrani.it\0" +"\xe0\xb9\x80\xe0\xb8\x99\xe0\xb9\x87\xe0\xb8\x95.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" +"toho.fukuoka.jp\0" +"nationalfirearms.museum\0" +"aioi.hyogo.jp\0at.eu.org\0georgia.su\0" +"toei.aichi.jp\0onagawa.miyagi.jp\0" +"to.gov.br\0\xe5\x80\x8b\xe4\xba\xba.hk\0blogsyte.com\0" +"software.aero\0safe\0" +"is-a-patsfan.org\0" +"worse-than.tv\0" +"gucci\0" +"svizzera.museum\0" +"cust.prod.thingdust.io\0" +"contemporaryart.museum\0" +"\xc3\xb8ksnes.no\0" +"communications.museum\0" +"hb.cn\0" +"noho.st\0" +"k12.oh.us\0today\0" +"hayakawa.yamanashi.jp\0" +"heroy.more-og-romsdal.no\0grondar.za\0" +"vard\xc3\xb8.no\0" +"kvam.no\0" +"r.bg\0tcm.museum\0levanger.no\0cricket\0" +"hashbang.sh\0" +"holiday\0" +"priv.pl\0" +"miyazaki.miyazaki.jp\0cloudns.in\0" +"habikino.osaka.jp\0dell\0" +"weber\0" +"br.it\0cb.it\0" +"creditunion\0" +"shitara.aichi.jp\0" +"matsukawa.nagano.jp\0\xe0\xa4\x95\xe0\xa5\x89\xe0\xa4\xae\0" +"madrid.museum\0redumbrella\0" +"po.it\0ozora.hokkaido.jp\0" +"trentinosud-tirol.it\0" +"chernigov.ua\0k12.ca.us\0\xe4\xb8\xad\xe5\x9b\xbd\0" +"taketomi.okinawa.jp\0mine.nu\0dray-dns.de\0" +"kunitachi.tokyo.jp\0" +"cloudns.cc\0" +"nakamura.kochi.jp\0valer.hedmark.no\0drud.us\0" +"fr\xc3\xb8ya.no\0" +"wsa.gov.pl\0" +"veterinaire.km\0" +"abudhabi\0" +"komono.mie.jp\0*.futurecms.at\0" +"rebun.hokkaido.jp\0\xe4\xb8\xad\xe5\x9c\x8b\0" +"fhsk.se\0" +"priv.no\0" +"mjondalen.no\0in.net\0" +"computer.museum\0" +"iraq.museum\0lund.no\0" +"vercelli.it\0" +"\xe3\x83\x9d\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\x88\0mysecuritycamera.com\0" +"monzaedellabrianza.it\0dnsdojo.org\0" +"tarama.okinawa.jp\0" +"toyoake.aichi.jp\0ichikawamisato.yamanashi.jp\0" +"mb.ca\0francaise.museum\0" +"fbx-os.fr\0" +"topology.museum\0" +"miyoshi.aichi.jp\0lib.de.us\0" +"medizinhistorisches.museum\0salon\0" +"sale\0" +"ashibetsu.hokkaido.jp\0\xc3\xa5l.no\0brand.se\0" +"shioya.tochigi.jp\0" +"pilots.museum\0" +"priv.me\0haugesund.no\0" +"time.no\0healthcare\0" +"gallery.museum\0" +"tadotsu.kagawa.jp\0" +"durban\0wed\0" +"antiques.museum\0" +"sandnes.no\0" +"royken.no\0" +"veterinaire.fr\0" +"bnr.la\0" +"am.br\0training\0edu.eu.org\0" +"asuke.aichi.jp\0" +"gr.it\0porn\0" +"prof.pr\0mckinsey\0\xe9\xa6\x99\xe6\xa0\xbc\xe9\x87\x8c\xe6\x8b\x89\0" +"act.edu.au\0atsugi.kanagawa.jp\0ventures\0at-band-camp.net\0" +"kasamatsu.gifu.jp\0" +"basilicata.it\0" +"tatsuno.hyogo.jp\0kunohe.iwate.jp\0vt.us\0ownip.net\0" +"siellak.no\0" +"gr.jp\0" +"trondheim.no\0" +"svalbard.no\0" +"niki.hokkaido.jp\0delaware.museum\0" +"mosj\xc3\xb8""en.no\0" +"yuza.yamagata.jp\0" +"dental\0sharp\0*.magentosite.cloud\0" +"dgca.aero\0" +"df.gov.br\0post\0" +"iz.hr\0" +"abc.br\0desi\0" +"dni.us\0" +"aoki.nagano.jp\0" +"bir.ru\0" +"sakura.tochigi.jp\0" +"gs.ah.no\0" +"college\0" +"her\xc3\xb8y.m\xc3\xb8re-og-romsdal.no\0" +"abira.hokkaido.jp\0" +"karlsoy.no\0" +"dance\0" +"sakuho.nagano.jp\0" +"!city.sendai.jp\0chijiwa.nagasaki.jp\0" +"empresa.bo\0" +"nishigo.fukushima.jp\0anthropology.museum\0" +"git-repos.de\0" +"americanart.museum\0" +"s3.us-east-2.amazonaws.com\0wmflabs.org\0" +"for-better.biz\0" +"final\0" +"test-iserv.de\0" +"colonialwilliamsburg.museum\0" +"5.bg\0" +"stjohn.museum\0win\0" +"r\xc3\xa5holt.no\0insure\0" +"spreadbetting\0" +"yamada.toyama.jp\0on-aptible.com\0" +"cipriani\0" +"srv.br\0from-de.com\0gotdns.com\0" +"selfip.com\0" +"nationwide\0" +"bruxelles.museum\0" +"okuma.fukushima.jp\0silk.museum\0" +"opole.pl\0" +"fm.br\0s3-external-1.amazonaws.com\0" +"tamaki.mie.jp\0sarl\0" +"mb.it\0" +"tarui.gifu.jp\0fujiidera.osaka.jp\0t3l3p0rt.net\0" +"\xd8\xa7\xd8\xb1\xd8\xa7\xd9\x85\xd9\x83\xd9\x88\0" +"karasjohka.no\0" +"shikama.miyagi.jp\0" +"gen.mi.us\0" +"amagasaki.hyogo.jp\0togakushi.nagano.jp\0kirovograd.ua\0" +"sor-fron.no\0" +"k12.ma.us\0" +"\xe7\xbb\x84\xe7\xb9\x94.hk\0wassamu.hokkaido.jp\0arakawa.tokyo.jp\0" +"onojo.fukuoka.jp\0horonobe.hokkaido.jp\0" +"g12.br\0" +"honai.ehime.jp\0bilbao.museum\0" +"tj.cn\0oyer.no\0" "reggio-emilia.it\0" -"tv.it\0" -"\xd9\xbe\xd8\xa7\xd9\x83\xd8\xb3\xd8\xaa\xd8\xa7\xd9\x86\0attorney\0" +"weir\0" +"miasta.pl\0cloudns.us\0" +"rj.leg.br\0" +"zushi.kanagawa.jp\0chiropractic.museum\0forum\0" +"rzgw.gov.pl\0cistron.nl\0" +"wme\0" +"shirako.chiba.jp\0spacekit.io\0" +"\xc3\xa5krehamn.no\0averoy.no\0" +"resistance.museum\0" +"firebaseapp.com\0" +"hanyu.saitama.jp\0sandiego.museum\0" +"workshop.museum\0" +"homesecuritypc.com\0" +"from-or.com\0" +"honeywell\0sells-for-u.com\0" +"\xe0\xb4\xad\xe0\xb4\xbe\xe0\xb4\xb0\xe0\xb4\xa4\xe0\xb4\x82\0" +"hirono.iwate.jp\0" +"chita.aichi.jp\0" +"save\0" +"toyooka.hyogo.jp\0" +"lib.ne.us\0" +"ichikawa.chiba.jp\0" +"imari.saga.jp\0" +"oslo.no\0" +"hinode.tokyo.jp\0" +"deloitte\0\xe6\x89\x8b\xe8\xa1\xa8\0" +"n\xc3\xb8tter\xc3\xb8y.no\0is-into-cartoons.com\0" +"kepno.pl\0" +"rexroth\0" +"cheltenham.museum\0" +"au.eu.org\0be.eu.org\0" +"lel.br\0" +"hitachiomiya.ibaraki.jp\0" +"alessandria.it\0tsu.mie.jp\0wow\0xenapponazure.com\0" +"warabi.saitama.jp\0" +"a.ssl.fastly.net\0" +"nakanojo.gunma.jp\0" +"mitsuke.niigata.jp\0tama.tokyo.jp\0" +"r.se\0saxo\0" +"google\0" +"xz.cn\0" +"civilization.museum\0" +"*.sch.uk\0" +"livorno.it\0medecin.km\0" +"s3.dualstack.ap-southeast-2.amazonaws.com\0" +"fm.it\0owani.aomori.jp\0kasai.hyogo.jp\0" +"midsund.no\0" +"kaga.ishikawa.jp\0" +"eigersund.no\0" +"izumo.shimane.jp\0" +"fr\xc3\xa6na.no\0" +"taishi.osaka.jp\0quebec\0" +"illustration.museum\0" +"takinoue.hokkaido.jp\0" +"vald-aosta.it\0audi\0" +"barlettatraniandria.it\0samsclub\0" +"marshalls\0no-ip.org\0" +"\xe6\x85\x88\xe5\x96\x84\0" +"froya.no\0" +"ube.yamaguchi.jp\0" +"kota.aichi.jp\0hitachi.ibaraki.jp\0wildlife.museum\0s\xc3\xb8mna.no\0" +"bg.eu.org\0" +"wtc\0dagestan.ru\0" +"\xe6\x84\x9b\xe7\x9f\xa5.jp\0" +"clubmed\0wtf\0" +"tagajo.miyagi.jp\0" +"krasnodar.su\0" +"basel.museum\0beer\0" +"niepce.museum\0" +"amber.museum\0england.museum\0" +"rishiri.hokkaido.jp\0" +"vr.it\0dagestan.su\0" +"bod\xc3\xb8.no\0" +"b\xc3\xa1hcavuotna.no\0" +"crotone.it\0" +"viking\0" +"tsuru.yamanashi.jp\0" +"ba.leg.br\0" +"kizu.kyoto.jp\0kvanangen.no\0trysil.no\0\xe5\x80\x8b\xe4\xba\xba.\xe9\xa6\x99\xe6\xb8\xaf\0" +"midori.gunma.jp\0jewish.museum\0" +"\xd0\xbe\xd1\x80\xd0\xb3.\xd1\x81\xd1\x80\xd0\xb1\0" +"k12.wa.us\0bplaced.com\0" +"shimamaki.hokkaido.jp\0" +"barsy.mobi\0" +"liaison\0" +"fm.no\0" +"hiroo.hokkaido.jp\0" +"motegi.tochigi.jp\0" +"kakuda.miyagi.jp\0\xe6\x89\x8b\xe6\x9c\xba\0" +"ogano.saitama.jp\0" +"fuchu.hiroshima.jp\0" +"amusement.aero\0kaneyama.yamagata.jp\0" +"ownprovider.com\0" +"siljan.no\0" +"mosvik.no\0" +"red.sv\0" +"tananger.no\0" +"yamanouchi.nagano.jp\0" +"\xe6\x96\xb0\xe9\x97\xbb\0" +"remotewd.com\0" +"flor\xc3\xb8.no\0cloudns.pw\0" +"ditchyourip.com\0" +"hida.gifu.jp\0" +"sogne.no\0" +"hopto.me\0" +"now-dns.top\0" +"vestnes.no\0" +"yoshinogari.saga.jp\0" +"reggio-calabria.it\0cartoonart.museum\0" +"shinto.gunma.jp\0scholarships\0" +"mansions.museum\0readmyblog.org\0" +"media\0" +"yosemite.museum\0no-ip.info\0" +"newport.museum\0" +"kitagata.saga.jp\0" +"american.museum\0" +"xin\0" +"tatebayashi.gunma.jp\0" +"jefferson.museum\0casino\0\xd9\x83\xd9\x88\xd9\x85\0hr.eu.org\0" +"tsumagoi.gunma.jp\0" +"ne.jp\0" +"k12.nv.us\0" +"withyoutube.com\0" +"aguni.okinawa.jp\0ne.ke\0civilwar.museum\0" +"p.bg\0" +"santoandre.br\0yahiko.niigata.jp\0songdalen.no\0" +"fiat\0homes\0" +"schweiz.museum\0de.us\0" +"yasuoka.nagano.jp\0nextdirect\0" +"ne.kr\0" +"shimofusa.chiba.jp\0project.museum\0" +"nobeoka.miyazaki.jp\0" +"\xe7\x8f\xa0\xe5\xae\x9d\0" +"mutsu.aomori.jp\0" +"voyage\0" +"is-a-geek.com\0" +"lillesand.no\0" +"tottori.tottori.jp\0" +"wada.nagano.jp\0rr.leg.br\0" +"mat.br\0" +"chernihiv.ua\0cloudaccess.host\0" +"planetarium.museum\0is-a-cpa.com\0" +"www.ro\0grozny.su\0" +"nikolaev.ua\0" +"am.leg.br\0" +"fido\0softbank\0" +"tjome.no\0" +"kuzumaki.iwate.jp\0appspot.com\0" +"loppa.no\0clinic\0" +"\xe6\x8b\x9b\xe8\x81\x98\0" +"kamaishi.iwate.jp\0" +"\xe3\x82\xaf\xe3\x83\xa9\xe3\x82\xa6\xe3\x83\x89\0" +"r\xc3\xa6lingen.no\0" +"narashino.chiba.jp\0" +"takayama.gifu.jp\0" +"indianmarket.museum\0" +"rs.leg.br\0sc.leg.br\0" +"tienda\0" +"zagan.pl\0mein-iserv.de\0" +"dnsdojo.net\0" +"texas.museum\0" +"miyagi.jp\0artdeco.museum\0global\0" +"blockbuster\0guitars\0" +"kasuga.hyogo.jp\0tube\0servegame.com\0" +"gemological.museum\0fuossko.no\0" +"taito.tokyo.jp\0" +"kami.kochi.jp\0" +"myfritz.net\0" +"tula.su\0" +"wanouchi.gifu.jp\0" +"ibaraki.ibaraki.jp\0ar.com\0" +"from-ny.net\0neat-url.com\0" +"kayabe.hokkaido.jp\0grozny.ru\0" +"ne.pw\0" +"s\xc3\xa1lat.no\0" +"onyourside\0from-id.com\0" +"anani.br\0" +"cc.tx.us\0" +"k\xc3\xa1r\xc3\xa1\xc5\xa1johka.no\0" +"emilia-romagna.it\0frog.museum\0" +"phoenix.museum\0km.ua\0" +"nx.cn\0tsuwano.shimane.jp\0" +"art.museum\0" +"*.0emm.com\0" +"lexus\0" +"oguchi.aichi.jp\0" +"television.museum\0" +"mil.ac\0best\0dyndns-server.com\0" +"naturalsciences.museum\0" +"mil.ae\0" +"obuse.nagano.jp\0" +"mil.al\0heritage.museum\0skj\xc3\xa5k.no\0" +"bytom.pl\0" +"auto\0" +"ama.shimane.jp\0" +"mil.ba\0steiermark.museum\0" +"mil.ar\0ap.leg.br\0" +"eisenbahn.museum\0" +"murakami.niigata.jp\0" +"vestre-slidre.no\0" +"balsan-su\xcc\x88""dtirol.it\0" +"nis.za\0" +"mil.az\0" +"rj.gov.br\0" +"fot.br\0landrover\0" +"3.bg\0" +"crew.aero\0mil.bo\0" +"kainan.tokushima.jp\0" +"mil.br\0sauherad.no\0ne.ug\0prudential\0dyndns-mail.com\0" +"medecin.fr\0" +"is-very-evil.org\0" +"ne.tz\0blogspot.com.cy\0rn.leg.br\0" +"sera.hiroshima.jp\0accenture\0" +"fujimi.saitama.jp\0malopolska.pl\0" +"gamvik.no\0" +"mil.by\0" +"kurate.fukuoka.jp\0omi.niigata.jp\0hockey\0" +"mil.cl\0" +"mil.cn\0ne.us\0" +"mil.co\0\xe5\xb2\x90\xe9\x98\x9c.jp\0" +"blogspot.com.ee\0" +"gildeskal.no\0film\0" +"\xd9\x85\xd8\xb5\xd8\xb1\0blogspot.com.eg\0" +"fet.no\0" +"nissan\0wpdevcloud.com\0" +"east-kazakhstan.su\0hopto.org\0" +"blogspot.com.ar\0" +"mil.do\0nakasatsunai.hokkaido.jp\0missile.museum\0" +"blogspot.com.au\0" +"mil.ec\0" +"ro.leg.br\0" +"sx.cn\0trentino.it\0nissay\0noip.us\0" +"mil.eg\0cesena-forli.it\0" +"inawashiro.fukushima.jp\0" +"auspost\0" +"vevelstad.no\0nyc.mn\0" +"is-a-geek.org\0" +"design\0blogspot.com.br\0" +"sellsyourhome.org\0" +"\xe0\xae\x87\xe0\xae\xa8\xe0\xaf\x8d\xe0\xae\xa4\xe0\xae\xbf\xe0\xae\xaf\xe0\xae\xbe\0" +"collection.museum\0" +"blogspot.com.by\0soundcast.me\0" +"surgery\0" +"shichinohe.aomori.jp\0*.alces.network\0" +"scor\0" +"scot\0s3-website.eu-west-2.amazonaws.com\0blogspot.com.co\0" +"ca-central-1.elasticbeanstalk.com\0" +"gliwice.pl\0gda.pl\0" +"lig.it\0miyoshi.tokushima.jp\0kahoku.yamagata.jp\0" +"mein-vigor.de\0" +"mil.ge\0" +"\xc3\xb8rsta.no\0mragowo.pl\0" +"honda\0" +"mil.gh\0vossevangen.no\0" +"\xe5\x85\xac\xe5\x8f\xb8.cn\0xfinity\0" +"globo\0" +"xxx\0app.os.fedoraproject.org\0" +"yokosuka.kanagawa.jp\0" +"corsica\0" +"s\xc3\xb8r-odal.no\0omega\0" +"mil.gt\0is-a-hunter.com\0" +"\xe5\x85\xac\xe5\x8f\xb8.hk\0honjo.akita.jp\0" +"chimkent.su\0" +"cs.it\0twmail.cc\0" +"academia.bo\0" +"select\0" +"loan\0place\0" +"mil.hn\0tuva.su\0" +"j\xc3\xb8rpeland.no\0xyz\0blogspot.com.es\0" +"oppdal.no\0rzeszow.pl\0" +"sko.gov.pl\0press\0" +"mil.id\0" +"taishin.fukushima.jp\0tokuyama.yamaguchi.jp\0" +"napoli.it\0correios-e-telecomunica\xc3\xa7\xc3\xb5""es.museum\0" +"fire\0" +"mil.in\0" +"eaton.mi.us\0" +"mil.iq\0" +"badajoz.museum\0p.se\0" +"lawyer\0" +"mibu.tochigi.jp\0\xe8\xb0\xb7\xe6\xad\x8c\0" +"otoineppu.hokkaido.jp\0" +"lacaixa\0" +"fujioka.gunma.jp\0" +"applinzi.com\0" +"fish\0bplaced.net\0" +"mil.jo\0" +"xs4all.space\0" +"onjuku.chiba.jp\0" +"przeworsk.pl\0" +"mo\xc3\xa5reke.no\0pomorskie.pl\0" +"mil.kg\0" +"ba.gov.br\0jogasz.hu\0nanao.ishikawa.jp\0" +"isesaki.gunma.jp\0" +"mochizuki.nagano.jp\0mil.km\0" +"himi.toyama.jp\0camera\0" +"fuel.aero\0servep2p.com\0" +"mil.kr\0ostrowwlkp.pl\0" +"morimachi.shizuoka.jp\0" +"*.compute.amazonaws.com\0" +"iron.museum\0il.eu.org\0" +"haram.no\0" +"mil.kz\0" +"austevoll.no\0" +"eu-central-1.elasticbeanstalk.com\0" +"tonaki.okinawa.jp\0karikatur.museum\0" +"family\0" +"nonoichi.ishikawa.jp\0" +"mil.lv\0" +"mil.mg\0tolga.no\0rsvp\0" +"tamamura.gunma.jp\0osteroy.no\0" +"no-ip.net\0" +"net.ac\0" +"net.ae\0miyakonojo.miyazaki.jp\0loft\0" +"net.af\0belem.br\0" +"net.ag\0" +"guovdageaidnu.no\0workisboring.com\0" +"net.ai\0mil.mv\0" +"mil.ng\0knowsitall.info\0hu.eu.org\0ie.eu.org\0" +"net.al\0mil.my\0mil.ni\0" +"mil.mz\0you\0" +"yusuhara.kochi.jp\0" +"bearalv\xc3\xa1hki.no\0" +"net.ba\0yalta.ua\0" +"net.ar\0net.bb\0mil.no\0" +"bushey.museum\0" +"money\0" +"net.au\0" +"net.bh\0" +"\xd7\xa7\xd7\x95\xd7\x9d\0" +"net.az\0coop.ht\0" +"hs.kr\0" +"nov.ru\0" +"net.bm\0mil.nz\0" +"net.bn\0" +"net.bo\0saves-the-whales.com\0" +"sa.gov.au\0ladbrokes\0" +"net.br\0sanok.pl\0" +"net.bs\0" +"net.bt\0" +"ravendb.run\0" +"yasuda.kochi.jp\0\xe4\xbf\xa1\xe6\x81\xaf\0" +"jaguar\0myasustor.com\0" +"mil.pe\0" +"net.ci\0yokote.akita.jp\0" +"net.bz\0" +"\xd8\xa7\xdb\x8c\xd8\xb1\xd8\xa7\xd9\x86.ir\0mil.ph\0prod\0noip.me\0" +"mykolaiv.ua\0nov.su\0" +"net.cm\0prof\0" +"net.cn\0" +"net.co\0mil.pl\0" +"kochi.kochi.jp\0" +"presse.km\0discount\0" +"blogspot.com.mt\0" +"mil.qa\0" +"net.cu\0" +"takahagi.ibaraki.jp\0blogspot.com.ng\0" +"net.cw\0tysfjord.no\0" +"coop.br\0humanities.museum\0\xe0\xa6\xad\xe0\xa6\xbe\xe0\xa6\xb0\xe0\xa6\xa4\0se.leg.br\0" +"net.cy\0geelvinck.museum\0volyn.ua\0" +"sc.cn\0kumiyama.kyoto.jp\0" +"mil.py\0" +"net.dm\0ikeda.nagano.jp\0" +"net.do\0" +"ak.us\0" +"ipifony.net\0" +"net.ec\0" +"h\xc3\xb8ylandet.no\0pulawy.pl\0" +"seto.aichi.jp\0" +"net.eg\0\xc3\xb8vre-eiker.no\0" +"venice.it\0is-a-player.com\0" +"net.dz\0" +"sciencesnaturelles.museum\0sandvik\0" +"oh.us\0" +"kumano.mie.jp\0" +"rr.gov.br\0" +"ms.it\0nieruchomosci.pl\0" +"xerox\0" +"trd.br\0\xe6\x95\x99\xe8\x82\xb2.hk\0presse.ml\0" +"ogori.fukuoka.jp\0hokksund.no\0" +"trentino-aadige.it\0tsurugi.ishikawa.jp\0cc.mn.us\0" +"net.et\0" +"nanae.hokkaido.jp\0caravan\0" +"\xe0\xa4\xb8\xe0\xa4\x82\xe0\xa4\x97\xe0\xa4\xa0\xe0\xa4\xa8\0" +"gjovik.no\0" +"mil.ru\0endoftheinternet.org\0" +"council.aero\0" +"mil.rw\0" +"am.gov.br\0mil.sh\0" +"bolt.hu\0hotel.tz\0" +"tsukiyono.gunma.jp\0bahcavuotna.no\0" +"deatnu.no\0" +"maringa.br\0usui.fukuoka.jp\0bnpparibas\0blogspot.com.tr\0" +"dyndns-pics.com\0" +"nogi.tochigi.jp\0" +"tono.iwate.jp\0" +"n.bg\0net.ge\0" +"yun\0" +"net.gg\0mil.st\0" +"lur\xc3\xb8y.no\0dc.us\0" +"taketa.oita.jp\0" +"net.gl\0mil.sy\0s3-eu-west-3.amazonaws.com\0" +"bn.it\0ms.kr\0malvik.no\0mil.tj\0" +"rs.gov.br\0sc.gov.br\0net.gn\0nakagawa.fukuoka.jp\0" +"net.gp\0oirase.aomori.jp\0oketo.hokkaido.jp\0mil.tm\0ivanovo.su\0" +"eurovision\0" +"net.gr\0mil.to\0" +"rochester.museum\0" +"net.gt\0tec.mi.us\0" +"net.gu\0sardegna.it\0koshu.yamanashi.jp\0yorkshire.museum\0tr\xc3\xa6na.no\0mil.tr\0" +"net.gy\0trentino-altoadige.it\0" +"mil.tw\0" +"net.hk\0" +"mil.tz\0" +"industria.bo\0net.hn\0" +"bozen-su\xcc\x88""dtirol.it\0faith\0" +"urn.arpa\0" +"net.ht\0net.id\0" +"emiliaromagna.it\0moma.museum\0" +"matsudo.chiba.jp\0mil.vc\0" +"nishi.fukuoka.jp\0" +"mil.ve\0" +"kitamoto.saitama.jp\0chizu.tottori.jp\0s\xc3\xb8rum.no\0" +"mizumaki.fukuoka.jp\0bounceme.net\0" +"net.il\0delmenhorst.museum\0ulvik.no\0mil.uy\0" +"net.im\0mihama.mie.jp\0" +"net.in\0odda.no\0s\xc3\xa1l\xc3\xa1t.no\0" +"barclays\0" +"net.iq\0" +"net.ir\0naustdal.no\0" +"net.is\0" +"net.je\0s3-website.ap-northeast-2.amazonaws.com\0" +"kyuragi.saga.jp\0" +"medical.museum\0" +"yoita.niigata.jp\0" +"tachikawa.tokyo.jp\0kvinnherad.no\0is-an-engineer.com\0" +"badaddja.no\0" +"aktyubinsk.su\0" +"net.jo\0" +"quest\0" +"trogstad.no\0" +"hofu.yamaguchi.jp\0tel.tr\0" +"net.kg\0" +"okinawa.jp\0zip\0" +"net.ki\0diet\0" +"manno.kagawa.jp\0omiya.saitama.jp\0vaapste.no\0gr.eu.org\0" +"ln.cn\0" +"saogonca.br\0" +"net.kn\0seat\0" +"uki.kumamoto.jp\0net.la\0" +"sc.ke\0net.lb\0" +"net.lc\0" +"recipes\0" +"harvestcelebration.museum\0chrysler\0" +"santabarbara.museum\0" +"chikusei.ibaraki.jp\0itoman.okinawa.jp\0net.kw\0" +"blogspot.com.uy\0" +"net.ky\0googlecode.com\0" +"net.kz\0selbu.no\0" +"ap.gov.br\0ishikawa.okinawa.jp\0net.lk\0law.pro\0" +"dyndns-at-work.com\0" +"sc.kr\0" +"net.ma\0cupcake.is\0" +"net.lr\0boats\0" +"kamikoani.akita.jp\0" +"mil.za\0oracle\0" +"net.me\0vadso.no\0game-host.org\0" +"not.br\0net.lv\0" +"scrapper-site.net\0" +"capebreton.museum\0" +"ichinoseki.iwate.jp\0net.ly\0online\0" +"santamaria.br\0net.mk\0from-ma.com\0" +"net.ml\0" +"hadano.kanagawa.jp\0k12.gu.us\0" +"rn.gov.br\0" +"of.by\0hotel.lk\0net.mo\0" +"mil.zm\0" +"accident-prevention.aero\0net.ms\0rnrt.tn\0" +"net.mt\0" +"net.mu\0ap.gov.pl\0" +"net.mv\0net.nf\0" +"muika.niigata.jp\0net.mw\0net.ng\0foundation\0feste-ip.net\0" +"net.mx\0k12.ut.us\0" +"net.my\0net.ni\0" +"net.mz\0mil.zw\0" +"avocat.fr\0" +"gyeongnam.kr\0lavangen.no\0" +"net.nr\0tjmaxx\0" +"radio.br\0accesscam.org\0" +"incheon.kr\0seek\0" +"maritimo.museum\0abarth\0kurgan.su\0" +"molise.it\0" +"net.nz\0" +"b\xc3\xb8.telemark.no\0net.om\0" +"ro.gov.br\0valle-daosta.it\0est-mon-blogueur.com\0nh-serv.co.uk\0" +"claims\0\xe5\x98\x89\xe9\x87\x8c\xe5\xa4\xa7\xe9\x85\x92\xe5\xba\x97\0" +"granvin.no\0net.pa\0" +"cq.cn\0" +"nsupdate.info\0" +"daisen.akita.jp\0barum.no\0" +"net.pe\0" +"love\0" +"oe.yamagata.jp\0" +"drangedal.no\0net.ph\0" +"mar.it\0" +"\xd9\x81\xd9\x84\xd8\xb3\xd8\xb7\xd9\x8a\xd9\x86\0" +"shinjo.yamagata.jp\0oppegard.no\0net.pk\0" +"net.pl\0" +"nc.tr\0" +"1.bg\0fvg.it\0net.pn\0" +"ogasawara.tokyo.jp\0" +"net.qa\0" +"ako.hyogo.jp\0net.pr\0from-me.org\0" +"fujishiro.ibaraki.jp\0higashiyamato.tokyo.jp\0net.ps\0" +"kitadaito.okinawa.jp\0fundacio.museum\0net.pt\0\xe3\x82\xb0\xe3\x83\xbc\xe3\x82\xb0\xe3\x83\xab\0" +"assassination.museum\0loans\0" +"qc.com\0" +"kui.hiroshima.jp\0" +"net.py\0ddns.me\0" +"sennan.osaka.jp\0kofu.yamanashi.jp\0" +"juedisches.museum\0" +"andoy.no\0rogers\0" +"ms.us\0nc.us\0" +"akishima.tokyo.jp\0" +"kyotamba.kyoto.jp\0" +"arna.no\0" +"freight.aero\0cc.ky.us\0shell\0" +"hoylandet.no\0" +"hotel.hu\0barclaycard\0" +"b\xc3\xa1jddar.no\0juniper\0" +"n\xc3\xa5\xc3\xa5mesjevuemie.no\0" +"!www.ck\0ruhr\0" +"fi.cr\0panama.museum\0k12.me.us\0" +"net.sa\0\xe5\x85\xac\xe5\x8f\xb8.\xe9\xa6\x99\xe6\xb8\xaf\0" +"hokuto.hokkaido.jp\0net.sb\0" +"\xe5\xb2\xa1\xe5\xb1\xb1.jp\0saltdal.no\0net.sc\0" +"net.sd\0" +"net.ru\0" +"exposed\0resindevice.io\0" +"net.rw\0net.sg\0nohost.me\0" +"net.sh\0app.lmpm.com\0" +"horokanai.hokkaido.jp\0" +"akrehamn.no\0meraker.no\0net.sl\0" +"asaka.saitama.jp\0" +"ishikawa.jp\0net.so\0" +"ws.na\0" +"namdalseid.no\0dscloud.me\0" +"net.st\0" +"szczytno.pl\0" +"sigdal.no\0metlife\0" +"wif.gov.pl\0pixolino.com\0" +"net.th\0" +"tako.chiba.jp\0net.sy\0" +"noto.ishikawa.jp\0net.tj\0immobilien\0" +"isa.kagoshima.jp\0is-a-geek.net\0" +"taira.toyama.jp\0net.tm\0k12.ar.us\0" +"net.tn\0is-a-chef.org\0" +"net.to\0melbourne\0" +"from-ok.com\0" +"net.ua\0mypep.link\0" +"net.tr\0" +"kishiwada.osaka.jp\0bygland.no\0" +"assedic.fr\0omuta.fukuoka.jp\0hyuga.miyazaki.jp\0net.tt\0" +"is-a-rockstar.com\0" +"net.tw\0" +"columbia.museum\0" +"cyou\0" +"gov.nc.tr\0net.uk\0alfaromeo\0" +"de.com\0" +"emerck\0" +"obninsk.su\0townnews-staging.com\0" +"soundandvision.museum\0grimstad.no\0" +"sakuragawa.ibaraki.jp\0" +"net.vc\0" +"sciences.museum\0sc.ug\0" +"izumi.osaka.jp\0troms\xc3\xb8.no\0net.ve\0" +"sc.tz\0" +"net.uy\0net.vi\0servegame.org\0" +"gs.hl.no\0coop.tt\0net.uz\0" +"yoshida.saitama.jp\0" +"kamisunagawa.hokkaido.jp\0v\xc3\xa5g\xc3\xa5.no\0termez.su\0" +"net.vn\0" +"vapor.cloud\0" +"sc.us\0store\0" +"sakae.nagano.jp\0ibaraki.osaka.jp\0net.vu\0" +"chocolate.museum\0" +"coop.mv\0b.ssl.fastly.net\0" +"coop.mw\0" +"swatch\0" +"works.aero\0minamata.kumamoto.jp\0" +"jobs\0tranoy.no\0" +"webhop.biz\0" +"n.se\0net.ws\0" +"lib.pa.us\0" +"aurland.no\0" +"dyndns-web.com\0" +"kitami.hokkaido.jp\0" +"tottori.jp\0" +"forli\xcc\x80-cesena.it\0youth.museum\0" +"dish\0" +"touch.museum\0\xe4\xbc\x81\xe4\xb8\x9a\0" +"fi.it\0fastlylb.net\0" +"homesense\0" +"of.no\0" +"loten.no\0olayan\0" +"mifune.kumamoto.jp\0" +"sv.it\0joboji.iwate.jp\0" +"wien\0" +"wuoz.gov.pl\0" +"hyogo.jp\0" +"net.za\0" +"swiebodzin.pl\0" +"ogawara.miyagi.jp\0is-a-chef.com\0" +"sveio.no\0" +"vet.br\0schokoladen.museum\0dnsalias.com\0" +"yaotsu.gifu.jp\0" +"def.br\0net.zm\0" +"atsuma.hokkaido.jp\0ohira.tochigi.jp\0coop.py\0" +"shichikashuku.miyagi.jp\0" +"sauda.no\0" +"szczecin.pl\0" +"press.aero\0" +"loabat.no\0mattel\0" +"ota.gunma.jp\0" +"odessa.ua\0netlify.com\0" +"asakuchi.okayama.jp\0" +"se.gov.br\0presse.ci\0" +"saintlouis.museum\0" +"tome.miyagi.jp\0" +"us-gov-west-1.elasticbeanstalk.com\0" +"fuoisku.no\0cc.vi.us\0" +"financial\0" +"vipsinaapp.com\0" +"ltd.co.im\0" +"ed.ao\0myfirewall.org\0" +"raholt.no\0" +"jeonnam.kr\0" +"coop.km\0" +"boston.museum\0clothing\0" +"abeno.osaka.jp\0" +"kudoyama.wakayama.jp\0" +"entomology.museum\0mopar\0" +"ngrok.io\0" +"sa.au\0samegawa.fukushima.jp\0" +"recife.br\0poivron.org\0" +"hizen.saga.jp\0" +"sango.nara.jp\0minato.tokyo.jp\0lugs.org.uk\0" +"sling\0" +"fetsund.no\0" +"ed.ci\0numata.gunma.jp\0seranishi.hiroshima.jp\0vagsoy.no\0" +"s3-us-west-2.amazonaws.com\0" +"zippo\0" +"ogawa.ibaraki.jp\0omi.nagano.jp\0" +"trentin-sued-tirol.it\0tomobe.ibaraki.jp\0setouchi.okayama.jp\0" +"\xe9\xab\x98\xe7\x9f\xa5.jp\0" +"ed.cr\0" +"gob.ar\0shimoichi.nara.jp\0" +"osoyro.no\0" +"aibetsu.hokkaido.jp\0ce.leg.br\0" +"presse.fr\0tsubame.niigata.jp\0michigan.museum\0" +"hoteles\0" +"wiki\0" +"sand\xc3\xb8y.no\0" +"sa.cr\0is-a-bruinsfan.org\0" +"kharkov.ua\0" +"gob.bo\0lib.wy.us\0" +"hasura.app\0" +"utsunomiya.tochigi.jp\0" +"maintenance.aero\0" +"skype\0" +"kaluga.su\0" +"nishitosa.kochi.jp\0obanazawa.yamagata.jp\0nv.us\0" +"manx.museum\0\xe6\x96\xb0\xe5\x8a\xa0\xe5\x9d\xa1\0" +"ome.tokyo.jp\0" +"gob.cl\0na.it\0" +"kiwi.nz\0" +"buzen.fukuoka.jp\0gs.rl.no\0read-books.org\0servehalflife.com\0" +"k12.ak.us\0" +"uklugs.org\0" +"skedsmokorset.no\0" +"kerryproperties\0" +"kinokawa.wakayama.jp\0forsale\0" +"marnardal.no\0psp.gov.pl\0\xd0\xb0\xd0\xba.\xd1\x81\xd1\x80\xd0\xb1\0" +"kppsp.gov.pl\0" +"seoul.kr\0sa.gov.pl\0cieszyn.pl\0" +"kimino.wakayama.jp\0macys\0marketing\0" +"gmail\0" +"\xce\xb5\xce\xbb\0" +"gob.do\0heimatunduhren.museum\0" +"it.ao\0alsace\0" +"research.museum\0" +"l.bg\0" +"gob.ec\0kanra.gunma.jp\0vega.no\0zp.gov.pl\0" +"agr.br\0wine\0" +"\xd0\xba\xd0\xb0\xd1\x82\xd0\xbe\xd0\xbb\xd0\xb8\xd0\xba\0" +"bl.it\0" +"encyclopedic.museum\0boutique\0" +"res.in\0" +"stjordalshalsen.no\0" +"gob.es\0\xe6\xb2\x96\xe7\xb8\x84.jp\0sexy\0" +"pi.it\0onga.fukuoka.jp\0" +"maif\0" +"barefoot\0" +"alt.za\0" +"pescara.it\0" +"s3.eu-west-2.amazonaws.com\0" +"yasaka.nagano.jp\0hinohara.tokyo.jp\0" +"motorcycles\0my-wan.de\0" +"dating\0" +"k12.pr.us\0" +"kopervik.no\0" +"abr.it\0" +"tunes\0" +"iida.nagano.jp\0" +"sarufutsu.hokkaido.jp\0parliament.nz\0" +"omaha.museum\0flir\0" +"barueri.br\0" +"daejeon.kr\0" +"desa.id\0" +"s\xc3\xb8gne.no\0pila.pl\0" +"baghdad.museum\0" +"gob.gt\0shizukuishi.iwate.jp\0oy.lc\0" +"health\0" +"\xd8\xa7\xdb\x8c\xd8\xb1\xd8\xa7\xd9\x86\0" +"qld.gov.au\0eidfjord.no\0\xe6\x95\x99\xe8\x82\xb2.\xe9\xa6\x99\xe6\xb8\xaf\0" +"sex.hu\0" +"from-ar.com\0barsyonline.co.uk\0" +"gob.hn\0sa.it\0kotoura.tottori.jp\0" +"ed.jp\0" +"podzone.net\0" +"sytes.net\0" +"bayern\0" +"umig.gov.pl\0" +"radio\0" +"herad.no\0lancia\0" +"shinyoshitomi.fukuoka.jp\0jorpeland.no\0trafficplex.cloud\0" +"salud.bo\0atami.shizuoka.jp\0" +"is-by.us\0" +"mypets.ws\0mypi.co\0" +"dubai\0" +"suzaka.nagano.jp\0" +"vn.ua\0" +"yonaguni.okinawa.jp\0" +"washingtondc.museum\0" +"nt.au\0express\0" +"r\xc3\xa5""de.no\0ia.us\0definima.io\0" +"minobu.yamanashi.jp\0" +"takanabe.miyazaki.jp\0" +"rehab\0" +"nt.ca\0leikanger.no\0" +"co.ae\0shibukawa.gunma.jp\0" +"aoste.it\0" +"co.ag\0" +"davvesiida.no\0bostik\0" +"airforce\0" +"motoyama.kochi.jp\0potager.org\0" +"fukui.jp\0oregon.museum\0" +"co.ao\0" +"creation.museum\0" +"co.bb\0" +"chirurgiens-dentistes.fr\0toyoura.hokkaido.jp\0" +"co.at\0""1337.pictures\0" +"noticias.bo\0" +"co.bi\0kagawa.jp\0" +"unnan.shimane.jp\0freebox-os.com\0" +"handa.aichi.jp\0" +"makurazaki.kagoshima.jp\0fuettertdasnetz.de\0" +"co.ca\0" +"lancashire.museum\0" +"kasugai.aichi.jp\0" +"rieti.it\0\xe7\xb6\xb2\xe8\xb7\xaf.tw\0" +"co.bw\0" +"co.ci\0komatsushima.tokushima.jp\0" +"co.cl\0" +"co.cm\0" +"kutchan.hokkaido.jp\0" +"watches\0" +"co.cr\0fukuchi.fukuoka.jp\0" +"bike\0" +"chambagri.fr\0toya.hokkaido.jp\0gob.mx\0allfinanz\0" +"gob.ni\0" +"fr.eu.org\0" +"sanda.hyogo.jp\0co.cz\0" +"matsubara.osaka.jp\0co.dk\0" +"moriguchi.osaka.jp\0lviv.ua\0" +"webhop.me\0" +"algard.no\0" +"demon.nl\0" +"oarai.ibaraki.jp\0" +"ed.pw\0" +"asti.it\0" +"ethnology.museum\0" +"mishima.shizuoka.jp\0" +"carbonia-iglesias.it\0" +"maebashi.gunma.jp\0gob.pa\0golffan.us\0" +"amakusa.kumamoto.jp\0sex.pl\0" +"milan.it\0" +"magazine.aero\0kaminoyama.yamagata.jp\0" +"ntr.br\0\xe9\x95\xb7\xe5\xb4\x8e.jp\0kuwana.mie.jp\0gob.pe\0" +"takasaki.gunma.jp\0" +"adult.ht\0vikna.no\0poznan.pl\0" +"kagoshima.jp\0takehara.hiroshima.jp\0voagat.no\0" +"gob.pk\0" +"auction\0" +"arida.wakayama.jp\0" +"evenassi.no\0writesthisblog.com\0" +"kiyosato.hokkaido.jp\0" +"co.gg\0" +"holmestrand.no\0bing\0kitchen\0" +"urbinopesaro.it\0misato.saitama.jp\0" +"ag.it\0kalisz.pl\0boston\0" +"vic.gov.au\0co.gl\0" +"utazu.kagawa.jp\0better-than.tv\0" +"foggia.it\0" +"nodum.co\0" +"lierne.no\0joburg\0" +"sado.niigata.jp\0" +"stathelle.no\0" +"co.gy\0" +"monash\0" +"komatsu\0" +"ono.hyogo.jp\0" +"journalism.museum\0" +"sa.com\0" +"hicam.net\0" +"co.id\0\xe9\x95\xb7\xe9\x87\x8e.jp\0dominic.ua\0" +"co.hu\0dontexist.net\0cya.gg\0" +"uchinada.ishikawa.jp\0" +"n\xc3\xa6r\xc3\xb8y.no\0" +"modena.it\0afamilycompany\0" +"is-a-chef.net\0" +"sjc.br\0" +"co.il\0" +"co.im\0seiro.niigata.jp\0ap-southeast-1.elasticbeanstalk.com\0s3-sa-east-1.amazonaws.com\0" +"co.in\0guide\0" +"co.ir\0nodum.io\0" +"trentinoaltoadige.it\0co.it\0yachiyo.chiba.jp\0polkowice.pl\0" +"co.je\0gob.sv\0" +"graz.museum\0" +"wroclaw.pl\0" +"iyo.ehime.jp\0" +"osakasayama.osaka.jp\0" +"campania.it\0" +"co.jp\0diamonds\0" +"stpetersburg.museum\0" +"bronnoysund.no\0lomza.pl\0" +"takko.aomori.jp\0co.ke\0" +"kisarazu.chiba.jp\0" +"ota.tokyo.jp\0rybnik.pl\0" +"sm\xc3\xb8la.no\0vaksdal.no\0" +"*.kawasaki.jp\0us.eu.org\0" +"is-an-actress.com\0" +"l.se\0" +"loab\xc3\xa1t.no\0" +"co.kr\0donostia.museum\0" +"co.lc\0" +"zoology.museum\0gob.ve\0go.leg.br\0" +"s3.dualstack.ap-northeast-2.amazonaws.com\0" +"eu-west-2.elasticbeanstalk.com\0" +"omigawa.chiba.jp\0" +"build\0" +"fg.it\0ruovat.no\0" +"point2this.com\0" +"kunitomi.miyazaki.jp\0co.ma\0nt.no\0ballangen.no\0" +"trani-barletta-andria.it\0" +"bhz.br\0co.ls\0" +"co.me\0" +"co.mg\0" +"hatsukaichi.hiroshima.jp\0" +"kameoka.kyoto.jp\0fredrikstad.no\0" +"isshiki.aichi.jp\0" +"bologna.it\0" +"theater.museum\0" +"ekloges.cy\0" +"padova.it\0" +"gosen.niigata.jp\0co.na\0" +"mo.cn\0" +"is-a-nascarfan.com\0" +"\xe0\xb8\xa8\xe0\xb8\xb6\xe0\xb8\x81\xe0\xb8\xa9\xe0\xb8\xb2.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" +"co.mu\0hitra.no\0" +"gose.nara.jp\0" +"co.mw\0prime\0" +"co.ni\0" +"co.mz\0" +"higashikawa.hokkaido.jp\0co.nl\0" +"co.no\0" +"higashi.okinawa.jp\0" +"seven\0" +"oirm.gov.pl\0\xd9\xbe\xd8\xa7\xd9\x83\xd8\xb3\xd8\xaa\xd8\xa7\xd9\x86\0" +"h\xc3\xa6gebostad.no\0" +"mj\xc3\xb8ndalen.no\0" +"sakai.fukui.jp\0" +"ce.gov.br\0co.nz\0" +"co.om\0" +"flog.br\0" +"bj.cn\0" +"miasa.nagano.jp\0nishikata.tochigi.jp\0bergbau.museum\0" +"trentinostirol.it\0" +"okazaki.aichi.jp\0" +"nedre-eiker.no\0" +"uryu.hokkaido.jp\0" +"shriram\0" +"brussels\0" +"co.pl\0" +"valle.no\0" +"co.pn\0" +"vanylven.no\0jprs\0\xe6\x94\xbf\xe5\xba\x9c\0" +"hakone.kanagawa.jp\0nt.ro\0" +"portal.museum\0gmina.pl\0" +"schwarz\0" +"wakayama.wakayama.jp\0" +"locus\0" +"caa.aero\0co.pw\0volkswagen\0" +"exchange.aero\0shimamoto.osaka.jp\0" +"coffee\0" +"nes.buskerud.no\0" +"vlog.br\0" +"*.compute.estate\0" +"filatelia.museum\0" +"*.otap.co\0" +"st.no\0" +"aosta-valley.it\0" +"r\xc3\xb8yrvik.no\0" +"alwaysdata.net\0" +"sec.ps\0" +"wroc.pl\0" +"sukumo.kochi.jp\0" +"bielawa.pl\0co.rs\0od.ua\0" +"minamiise.mie.jp\0dst.mi.us\0" +"cancerresearch\0" +"urausu.hokkaido.jp\0co.rw\0" +"tabayama.yamanashi.jp\0" +"kg.kr\0mulhouse.museum\0" +"g\xc3\xa1ivuotna.no\0" +"hiroshima.jp\0" +"lefrak\0" +"co.st\0futurehosting.at\0" +"maritime.museum\0" +"mo.it\0co.th\0" +"koza.wakayama.jp\0" +"co.sz\0co.tj\0club.tw\0" +"co.tm\0" +"broadcast.museum\0latino\0" +"muko.kyoto.jp\0berlevag.no\0shaw\0" +"mutual\0co.ua\0dynvpn.de\0" +"co.tt\0codespot.com\0" +"anpachi.gifu.jp\0florist\0" +"starachowice.pl\0lenug.su\0" +"co.ug\0from-ga.com\0" +"hitachi\0" +"watch-and-clock.museum\0co.tz\0" +"co.uk\0" +"b\xc3\xb8mlo.no\0" +"tw.cn\0" +"j.bg\0dell-ogliastra.it\0" +"cherkassy.ua\0" +"co.us\0stufftoread.com\0" +"navigation.aero\0" +"co.ve\0" +"nisshin.aichi.jp\0" +"ebino.miyazaki.jp\0co.vi\0" +"toyotsu.fukuoka.jp\0co.uz\0" +"is-a-cubicle-slave.com\0cloud.metacentrum.cz\0" +"shibetsu.hokkaido.jp\0" +"minamiizu.shizuoka.jp\0" +"pg.it\0" +"cooperativa.bo\0" +"gs.tr.no\0" +"vallee-d-aoste.it\0" +"cc.or.us\0" +"eun.eg\0" +"vads\xc3\xb8.no\0travelersinsurance\0dnshome.de\0" +"helsinki.museum\0" +"inagi.tokyo.jp\0sola.no\0" +"dyndns.tv\0" +"imb.br\0" +"weibo\0" +"nombre.bo\0" +"lib.nv.us\0okinawa\0" +"soc.lk\0" +"ninomiya.kanagawa.jp\0ing.pa\0" +"finland.museum\0" +"kariya.aichi.jp\0cbg.ru\0" +"aostavalley.it\0taipei\0" +"trieste.it\0koganei.tokyo.jp\0bloomberg\0" +"circle\0ro.im\0" +"ono.fukui.jp\0" +"kaizuka.osaka.jp\0" +"indianapolis.museum\0" +"ufcfan.org\0" +"finnoy.no\0" +"ro.it\0" +"sa-east-1.elasticbeanstalk.com\0" +"panerai\0from-mo.com\0" +"shirakawa.fukushima.jp\0historyofscience.museum\0kids.museum\0" +"gotemba.shizuoka.jp\0co.za\0" +"agro.bo\0" +"parliament.cy\0" +"dyndns.ws\0" +"marker.no\0" +"moonscale.net\0" +"nakamichi.yamanashi.jp\0" +"nakayama.yamagata.jp\0" +"co.zm\0" +"shinanomachi.nagano.jp\0xihuan\0" +"rissa.no\0" +"trentino-sud-tirol.it\0funabashi.chiba.jp\0podlasie.pl\0" +"podzone.org\0" +"safety.aero\0" +"neyagawa.osaka.jp\0marylhurst.museum\0co.zw\0" +"haboro.hokkaido.jp\0" +"fukushima.jp\0" +"channel\0shia\0" +"kita.osaka.jp\0v\xc3\xa5ler.hedmark.no\0" +"higashiura.aichi.jp\0chintai\0navoi.su\0" +"\xe5\x8c\x97\xe6\xb5\xb7\xe9\x81\x93.jp\0" +"\xe0\xb0\xad\xe0\xb0\xbe\xe0\xb0\xb0\xe0\xb0\xa4\xe0\xb1\x8d\0" +"chikuhoku.nagano.jp\0toga.toyama.jp\0" +"balsan-sudtirol.it\0" +"ismaili\0\xe5\xbe\xae\xe5\x8d\x9a\0" +"sinaapp.com\0" +"trentin-su\xcc\x88""d-tirol.it\0lecco.it\0" +"itabashi.tokyo.jp\0" +"farmequipment.museum\0dr.na\0" +"host\0gb.com\0" +"\xe4\xba\xac\xe9\x83\xbd.jp\0" +"akita.akita.jp\0shimogo.fukushima.jp\0" +"furubira.hokkaido.jp\0idrett.no\0" +"ginan.gifu.jp\0" +"minato.osaka.jp\0pyatigorsk.ru\0" +"\xe0\xa6\xad\xe0\xa6\xbe\xe0\xa7\xb0\xe0\xa6\xa4\0" +"web.bo\0from-ct.com\0" +"erimo.hokkaido.jp\0" +"test.tj\0" +"games.hu\0kawakami.nagano.jp\0" +"technology.museum\0" +"target\0" +"web.co\0" +"repbody.aero\0" +"\xd0\xbf\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0" +"sondrio.it\0circus.museum\0" +"plo.ps\0" +"savannahga.museum\0" +"web.do\0" +"ide.kyoto.jp\0civilisation.museum\0" +"caxias.br\0" +"valle-aosta.it\0global.ssl.fastly.net\0" +"geology.museum\0" +"sweden.museum\0" +"yashio.saitama.jp\0mo.us\0vodka\0" +"test.ru\0" +"troitsk.su\0" +"hirara.okinawa.jp\0mymediapc.net\0" +"glug.org.uk\0" +"modum.no\0" +"eti.br\0game.tw\0from-pa.com\0" +"kamakura.kanagawa.jp\0" +"blogdns.com\0" +"foodnetwork\0" +"k12.mi.us\0" +"toyotomi.hokkaido.jp\0" +"r.cdn77.net\0" +"yachimata.chiba.jp\0" +"is-into-cars.com\0" +"trentin-suedtirol.it\0" +"tecnologia.bo\0az.us\0" +"tado.mie.jp\0" +"suedtirol.it\0shop\0" +"from-dc.com\0" +"matsue.shimane.jp\0" +"horse\0" +"web.gu\0" +"show\0" +"kawachinagano.osaka.jp\0reise\0" +"neues.museum\0" +"steam.museum\0" +"cc.nm.us\0" +"genting\0" +"go.gov.br\0" +"higashishirakawa.gifu.jp\0clinton.museum\0" +"web.id\0dr.tr\0" +"genova.it\0" +"dynserv.org\0zapto.org\0" +"lib.nm.us\0\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4\0ath.cx\0" +"bo.telemark.no\0" +"gamagori.aichi.jp\0" +"dyn.ddnss.de\0" +"muroran.hokkaido.jp\0" +"xen.prgmr.com\0" +"svn-repos.de\0" +"\xe7\xa6\x8f\xe5\xb2\xa1.jp\0" +"\xd9\x83\xd8\xa7\xd8\xab\xd9\x88\xd9\x84\xd9\x8a\xd9\x83\0" +"tochigi.jp\0" +"kouhoku.saga.jp\0" +"s3.ap-south-1.amazonaws.com\0" +"pz.it\0" +"voss.no\0" +"tochio.niigata.jp\0" +"akashi.hyogo.jp\0" +"yorii.saitama.jp\0" +"palmas.br\0" +"lenvik.no\0sport\0" +"v\xc3\xa5ler.\xc3\xb8stfold.no\0es.eu.org\0" +"molde.no\0strand.no\0k12.ri.us\0homeip.net\0" +"horology.museum\0" +"trento.it\0toyota\0khakassia.su\0" +"travel.pl\0" +"ggf.br\0karmoy.no\0" +"mimata.miyazaki.jp\0fedje.no\0ltda\0cloudns.pro\0" +"costume.museum\0" +"web.lk\0" +"hornindal.no\0" +"okayama.jp\0" +"!city.kobe.jp\0chikuho.fukuoka.jp\0" +"fe.it\0is-very-sweet.org\0" +"air-traffic-control.aero\0" +"sr.it\0konan.aichi.jp\0" +"natori.miyagi.jp\0" +"ginowan.okinawa.jp\0" +"date.hokkaido.jp\0" +"konyvelo.hu\0newyork.museum\0" +"pubol.museum\0" +"web.nf\0" +"cremona.it\0" +"web.ni\0" +"treviso.it\0temp-dns.com\0" +"kumano.hiroshima.jp\0" +"bergen.no\0hermes\0" +"narviika.no\0" +"kuriyama.hokkaido.jp\0" +"kwp.gov.pl\0sucks\0" +"hino.tottori.jp\0firewall-gateway.de\0" +"custom.metacentrum.cz\0" +"photography.museum\0" +"search\0" +"partners\0" +"nakagusuku.okinawa.jp\0" +"koeln.museum\0" +"friulivgiulia.it\0" +"pe.ca\0" +"riik.ee\0nagiso.nagano.jp\0giske.no\0" +"ivgu.no\0" +"works\0" +"world\0" +"matera.it\0" +"cim.br\0web.pk\0is-a-celticsfan.org\0" +"taiji.wakayama.jp\0cruise\0" +"travel.tt\0" +"sokndal.no\0" +"k12.wi.us\0mc.eu.org\0" +"nishiwaki.hyogo.jp\0" +"hob\xc3\xb8l.no\0" +"repair\0" +"miyota.nagano.jp\0mesaverde.museum\0oregontrail.museum\0" +"hitachinaka.ibaraki.jp\0and.museum\0" +"patria.bo\0koka.shiga.jp\0" +"starnberg.museum\0" +"ooguy.com\0" +"udono.mie.jp\0" +"\xe5\xa4\xa9\xe4\xb8\xbb\xe6\x95\x99\0" +"\xe5\xb3\xb6\xe6\xa0\xb9.jp\0" +"is-gone.com\0" +"kadena.okinawa.jp\0" +"trani-andria-barletta.it\0" +"koto.tokyo.jp\0" +"dontexist.org\0*.triton.zone\0" +"sande.vestfold.no\0" +"lt.eu.org\0" +"cloudeity.net\0" +"mikawa.yamagata.jp\0" +"izumiotsu.osaka.jp\0" +"reviews\0" +"adv.br\0vefsn.no\0" +"oyabe.toyama.jp\0roros.no\0" +"nissedal.no\0" +"izumozaki.niigata.jp\0" +"kure.hiroshima.jp\0koge.tottori.jp\0" +"yamamoto.miyagi.jp\0" +"kitakata.fukushima.jp\0press.museum\0" +"noda.iwate.jp\0skierv\xc3\xa1.no\0" +"hm.no\0eid.no\0cloudns.asia\0" +"\xe7\xae\x87\xe4\xba\xba.hk\0r\xc3\xb8yken.no\0from-il.com\0" +"pisz.pl\0" +"nishiizu.shizuoka.jp\0web.tj\0" +"kamitonda.wakayama.jp\0silk\0" +"inatsuki.fukuoka.jp\0futbol\0" +"ebiz.tw\0" +"valdaosta.it\0" +"hashimoto.wakayama.jp\0my-firewall.org\0" +"mizusawa.iwate.jp\0web.tr\0" +"bradesco\0" +"us-west-1.elasticbeanstalk.com\0" +"hobby-site.org\0" +"os.hedmark.no\0" +"agro.pl\0" +"gos.pk\0" +"k12.mn.us\0" +"arts.co\0freemasonry.museum\0troandin.no\0is-an-artist.com\0" +"kasuga.fukuoka.jp\0barsy.co.uk\0" +"minami.kyoto.jp\0" +"sina\0" +"h.bg\0" +"budapest\0schokokeks.net\0" +"tamayu.shimane.jp\0web.ve\0" +"iwafune.tochigi.jp\0" +"chtr.k12.ma.us\0dyn-vpn.de\0" +"yanaizu.fukushima.jp\0barsy.support\0" +"*.cryptonomic.net\0" +"catania.it\0cc.as.us\0" +"kunstunddesign.museum\0tokyo\0" +"cleaning\0" +"elblag.pl\0" +"takahama.aichi.jp\0" +"pe.it\0" +"hanggliding.aero\0" +"limited\0" +"toyo.kochi.jp\0" +"comunica\xc3\xa7\xc3\xb5""es.museum\0is-lost.org\0fi.eu.org\0" +"webredirect.org\0" +"food\0" +"pharmacien.fr\0" +"homedepot\0" +"lib.oh.us\0" +"wakuya.miyagi.jp\0jolster.no\0" +"kunigami.okinawa.jp\0sanfrancisco.museum\0" +"namie.fukushima.jp\0" +"ama.aichi.jp\0ashiya.fukuoka.jp\0" +"takagi.nagano.jp\0webspace.rocks\0" +"suifu.ibaraki.jp\0pe.kr\0" +"andria-barletta-trani.it\0" +"fbxos.fr\0*.in.futurecms.at\0" +"nose.osaka.jp\0grong.no\0malselv.no\0" +"aknoluokta.no\0" +"ac.ae\0" +"rm.it\0" +"ciencia.bo\0ebina.kanagawa.jp\0web.za\0is-found.org\0" +"fla.no\0" +"nakagawa.tokushima.jp\0" +"textile.museum\0linkyard.cloud\0" +"taiki.hokkaido.jp\0" +"ac.at\0" +"ac.be\0" +"minakami.gunma.jp\0" +"torino.it\0ikeda.gifu.jp\0" +"uz.ua\0ford\0" +"kl\xc3\xa6""bu.no\0" +"withgoogle.com\0" +"kitakata.miyazaki.jp\0nikko.tochigi.jp\0bialystok.pl\0" +"veneto.it\0*.kobe.jp\0kawai.nara.jp\0" +"hk.com\0" +"h\xc3\xa5.no\0cloudns.org\0" +"ac.ci\0" +"ltd.cy\0plc.co.im\0hikimi.shimane.jp\0comcast\0" +"site\0" +"ac.cn\0\xe5\xa4\xa7\xe9\x98\xaa.jp\0" +"aosta.it\0" +"ambulance.aero\0!city.sapporo.jp\0" +"ac.cr\0cuneo.it\0" +"bolivia.bo\0meland.no\0us-4.evennode.com\0" +"ac.cy\0tsubetsu.hokkaido.jp\0" +"public.museum\0" +"habmer.no\0" +"sakyo.kyoto.jp\0eastafrica.museum\0square.museum\0" +"shintomi.miyazaki.jp\0russia.museum\0" +"gorlice.pl\0" +"tamba.hyogo.jp\0norton\0" +"tomika.gifu.jp\0" +"blog\0" +"12hp.de\0" +"\xd0\xb1\xd0\xb5\xd0\xbb\0" +"music.museum\0" +"yoga\0" +"nanporo.hokkaido.jp\0meet\0" +"mazury.pl\0" +"inashiki.ibaraki.jp\0" +"ltd.gi\0adv.mz\0hosting-cluster.nl\0" +"tsuga.tochigi.jp\0" +"suita.osaka.jp\0ap-northeast-3.elasticbeanstalk.com\0" +"qh.cn\0kiwa.mie.jp\0" +"nome.pt\0" +"perso.ht\0nexus\0" +"arts.ve\0netbank\0""12hp.at\0" +"sicilia.it\0" +"ac.gn\0quebec.museum\0rovno.ua\0ltd.hk\0" +"anan.tokushima.jp\0" +"nantan.kyoto.jp\0" +"walbrzych.pl\0" +"us-3.evennode.com\0" +"ina.ibaraki.jp\0labor.museum\0skjervoy.no\0wellbeingzone.eu\0" +"rodoy.no\0" +"cc.ks.us\0" +"berg.no\0singles\0mk.eu.org\0" +"akaiwa.okayama.jp\0" +"12hp.ch\0" +"analytics\0" +"gwangju.kr\0" +"ac.id\0" +"arakawa.saitama.jp\0us.com\0" +"mail.pl\0" +"tobetsu.hokkaido.jp\0kuju.oita.jp\0" +"furniture\0" +"lug.org.uk\0" +"ac.il\0" +"ac.im\0watarai.mie.jp\0flanders.museum\0" +"ac.in\0africa.com\0" +"logistics.aero\0progressive\0space-to-rent.com\0" +"*.elb.amazonaws.com.cn\0" +"ac.ir\0is-a-landscaper.com\0" +"lukow.pl\0" +"kamisato.saitama.jp\0" +"manchester.museum\0" +"bible\0" +"arts.museum\0author\0" +"ac.jp\0uda.nara.jp\0" +"langev\xc3\xa5g.no\0" +"ichikawa.hyogo.jp\0gyokuto.kumamoto.jp\0chernovtsy.ua\0" +"ac.ke\0blue\0" +"uw.gov.pl\0from-hi.com\0" +"toshima.tokyo.jp\0steinkjer.no\0dp.ua\0" +"hk.cn\0" +"oga.akita.jp\0" +"\xc3\xa1k\xc5\x8boluokta.no\0" +"imperia.it\0ltd.lk\0" +"yatsushiro.kumamoto.jp\0" +"\xd9\x87\xd9\x85\xd8\xb1\xd8\xa7\xd9\x87\0" +"cnpy.gdn\0" +"ac.kr\0" +"arts.ro\0" +"us-2.evennode.com\0" +"shinkamigoto.nagasaki.jp\0" +"warman\0barsyonline.com\0" }; static const quint16 tldChunkCount = 2; -static const quint32 tldChunks[] = {65533, 98615}; +static const quint32 tldChunks[] = {65532, 101260}; QT_END_NAMESPACE From 4dc251879c129710298ec9f9360490daed6a6a59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Tue, 9 Oct 2018 09:50:24 +0200 Subject: [PATCH 0003/1650] Ssl: Fix contrived crash when calling resume If you, directly after connecting, call "ignoreSslErrors()" followed by "resume()" then you will most likely crash. It is very contrived and there's no reason to do this. Change-Id: I949a303238f5012296d0e84eb76173764eb9de2e Reviewed-by: Timur Pocheptsov --- src/network/ssl/qsslsocket.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 4273904c12..ee157082ea 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -388,6 +388,9 @@ QSslSocket::~QSslSocket() */ void QSslSocket::resume() { + Q_D(QSslSocket); + if (!d->paused) + return; // continuing might emit signals, rather do this through the event loop QMetaObject::invokeMethod(this, "_q_resumeImplementation", Qt::QueuedConnection); } @@ -2573,6 +2576,7 @@ void QSslSocketPrivate::_q_resumeImplementation() if (verifyErrorsHaveBeenIgnored()) { continueHandshake(); } else { + Q_ASSERT(!sslErrors.isEmpty()); setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError, sslErrors.constFirst().errorString()); plainSocket->disconnectFromHost(); return; From 091a386eaf91ad8932332a8aefc2df793de59f6c Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Tue, 9 Oct 2018 11:01:37 +0200 Subject: [PATCH 0004/1650] Use native visual ID when creating GBM surfaces for KMS According to the Khronos documentation, gbm_surface_create() will give a BAD_MATCH error if the format does not match the EGL_NATIVE_VISUAL_ID. Newer drivers have started to enforce this. Change-Id: I61360b0f52965ad8057e7de8f824ffca64fea904 Reviewed-by: Laszlo Agocs Reviewed-by: Dominik Holland --- .../eglfs_kms/qeglfskmsgbmscreen.cpp | 24 +++++++++++++++---- .../eglfs_kms/qeglfskmsgbmscreen.h | 2 +- .../eglfs_kms/qeglfskmsgbmwindow.cpp | 2 +- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp index 4742143121..1b52bdf3ec 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp @@ -148,16 +148,32 @@ QPlatformCursor *QEglFSKmsGbmScreen::cursor() const } } -gbm_surface *QEglFSKmsGbmScreen::createSurface() +gbm_surface *QEglFSKmsGbmScreen::createSurface(EGLConfig eglConfig) { if (!m_gbm_surface) { - uint32_t gbmFormat = drmFormatToGbmFormat(m_output.drm_format); - qCDebug(qLcEglfsKmsDebug, "Creating gbm_surface for screen %s with format 0x%x", qPrintable(name()), gbmFormat); - m_gbm_surface = gbm_surface_create(static_cast(device())->gbmDevice(), + qCDebug(qLcEglfsKmsDebug, "Creating gbm_surface for screen %s", qPrintable(name())); + + const auto gbmDevice = static_cast(device())->gbmDevice(); + EGLint native_format = -1; + EGLBoolean success = eglGetConfigAttrib(display(), eglConfig, EGL_NATIVE_VISUAL_ID, &native_format); + qCDebug(qLcEglfsKmsDebug) << "Got native format" << hex << native_format << dec << "from eglGetConfigAttrib() with return code" << bool(success); + + if (success) + m_gbm_surface = gbm_surface_create(gbmDevice, + rawGeometry().width(), + rawGeometry().height(), + native_format, + GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); + + if (!m_gbm_surface) { // fallback for older drivers + uint32_t gbmFormat = drmFormatToGbmFormat(m_output.drm_format); + qCDebug(qLcEglfsKmsDebug, "Could not create surface with EGL_NATIVE_VISUAL_ID, falling back to format %x", gbmFormat); + m_gbm_surface = gbm_surface_create(gbmDevice, rawGeometry().width(), rawGeometry().height(), gbmFormat, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); + } } return m_gbm_surface; // not owned, gets destroyed in QEglFSKmsGbmIntegration::destroyNativeWindow() via QEglFSKmsGbmWindow::invalidateSurface() } diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h index f5a2122723..b94f44b7b1 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h @@ -59,7 +59,7 @@ public: QPlatformCursor *cursor() const override; - gbm_surface *createSurface(); + gbm_surface *createSurface(EGLConfig eglConfig); void resetSurface(); void initCloning(QPlatformScreen *screenThisScreenClones, diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp index 110a592dec..65a7c4f38a 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp @@ -53,7 +53,7 @@ void QEglFSKmsGbmWindow::resetSurface() m_config = QEglFSDeviceIntegration::chooseConfig(display, platformFormat); m_format = q_glFormatFromConfig(display, m_config, platformFormat); // One fullscreen window per screen -> the native window is simply the gbm_surface the screen created. - m_window = reinterpret_cast(gbmScreen->createSurface()); + m_window = reinterpret_cast(gbmScreen->createSurface(m_config)); PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC createPlatformWindowSurface = nullptr; const char *extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); From dc5f9d0c3101f95185d3c562d001e0af18f46a0b Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 2 Oct 2018 15:05:32 +0200 Subject: [PATCH 0005/1650] Only use a translucent background if there is support for alpha Change-Id: Ia8d9e543fac4b6e790fa38cf04c5a782d72d72df Reviewed-by: Eirik Aavitsland Reviewed-by: Gatis Paeglis --- .../platforms/xcb/nativepainting/qbackingstore_x11.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/xcb/nativepainting/qbackingstore_x11.cpp b/src/plugins/platforms/xcb/nativepainting/qbackingstore_x11.cpp index 8851ea59e5..ed482e5dae 100644 --- a/src/plugins/platforms/xcb/nativepainting/qbackingstore_x11.cpp +++ b/src/plugins/platforms/xcb/nativepainting/qbackingstore_x11.cpp @@ -62,8 +62,10 @@ QXcbNativeBackingStore::QXcbNativeBackingStore(QWindow *window) : QPlatformBackingStore(window) , m_translucentBackground(false) { - if (QXcbWindow *w = static_cast(window->handle())) - m_translucentBackground = w->connection()->hasXRender() && QImage::toPixelFormat(w->imageFormat()).alphaSize() > 0; + if (QXcbWindow *w = static_cast(window->handle())) { + m_translucentBackground = w->connection()->hasXRender() && + QImage::toPixelFormat(w->imageFormat()).alphaUsage() == QPixelFormat::UsesAlpha; + } } QXcbNativeBackingStore::~QXcbNativeBackingStore() From 0d7c049e4407bf0db8d1eca1ea248c6d6b739c8c Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Mon, 8 Oct 2018 14:12:14 +0200 Subject: [PATCH 0006/1650] Update bundled libpng to version 1.6.35 The remaining diff to clean 1.6.35 is archived in the qtpatches.diff file. [ChangeLog][Third-Party Code] libpng was updated to version 1.6.35 Change-Id: I925b3d95f6da20e12fc3274b4713e3fea05094f7 Reviewed-by: Kai Koehne Reviewed-by: Liang Qi --- src/3rdparty/libpng/ANNOUNCE | 49 +- src/3rdparty/libpng/CHANGES | 58 +- src/3rdparty/libpng/INSTALL | 2 +- src/3rdparty/libpng/LICENSE | 6 +- src/3rdparty/libpng/README | 4 +- src/3rdparty/libpng/libpng-manual.txt | 72 +- src/3rdparty/libpng/png.c | 40 +- src/3rdparty/libpng/png.h | 80 +- src/3rdparty/libpng/pngconf.h | 29 +- src/3rdparty/libpng/pngget.c | 17 +- src/3rdparty/libpng/pnginfo.h | 14 +- src/3rdparty/libpng/pnglibconf.h | 6 +- src/3rdparty/libpng/pngpread.c | 38 +- src/3rdparty/libpng/pngpriv.h | 44 +- src/3rdparty/libpng/pngread.c | 12 +- src/3rdparty/libpng/pngrio.c | 12 +- src/3rdparty/libpng/pngrtran.c | 1846 +++++++++++------------ src/3rdparty/libpng/pngrutil.c | 71 +- src/3rdparty/libpng/pngset.c | 18 +- src/3rdparty/libpng/pngstruct.h | 22 +- src/3rdparty/libpng/pngtrans.c | 18 +- src/3rdparty/libpng/pngwio.c | 10 +- src/3rdparty/libpng/pngwrite.c | 9 +- src/3rdparty/libpng/pngwtran.c | 10 +- src/3rdparty/libpng/pngwutil.c | 161 +- src/3rdparty/libpng/qt_attribution.json | 4 +- src/3rdparty/libpng/qtpatches.diff | 8 +- 27 files changed, 1355 insertions(+), 1305 deletions(-) diff --git a/src/3rdparty/libpng/ANNOUNCE b/src/3rdparty/libpng/ANNOUNCE index 0f66c0d1da..9fc9021b5a 100644 --- a/src/3rdparty/libpng/ANNOUNCE +++ b/src/3rdparty/libpng/ANNOUNCE @@ -1,35 +1,48 @@ -Libpng 1.6.34 - September 29, 2017 +Libpng 1.6.35 - July 15, 2018 -This is a public release of libpng, intended for use in production codes. +This is a public release of libpng, intended for use in production code. Files available for download: -Source files with LF line endings (for Unix/Linux) and with a -"configure" script +Source files with LF line endings (for Unix/Linux): - libpng-1.6.34.tar.xz (LZMA-compressed, recommended) - libpng-1.6.34.tar.gz + libpng-1.6.35.tar.xz (LZMA-compressed, recommended) + libpng-1.6.35.tar.gz -Source files with CRLF line endings (for Windows), without the -"configure" script +Source files with CRLF line endings (for Windows): - lpng1634.7z (LZMA-compressed, recommended) - lpng1634.zip + lp1635.7z (LZMA-compressed, recommended) + lp1635.zip Other information: - libpng-1.6.34-README.txt - libpng-1.6.34-LICENSE.txt - libpng-1.6.34-*.asc (armored detached GPG signatures) + libpng-1.6.35-README.txt + libpng-1.6.35-LICENSE.txt -Changes since the last public release (1.6.33): - Removed contrib/pngsuite/i*.png; some of these were incorrect and caused - test failures. +Changes since the last public release (1.6.34): + + Restored 21 of the contrib/pngsuite/i*.png, which do not cause test + failures. Placed the remainder in contrib/pngsuite/interlaced/i*.png. + Added calls to png_set_*() transforms commonly used by browsers to + the fuzzer. + Removed some unnecessary brackets in pngrtran.c + Fixed miscellaneous typos (Patch by github user "luzpaz"). + Change "ASM C" to "C ASM" in CMakeLists.txt + Fixed incorrect handling of bKGD chunk in sub-8-bit files (Cosmin) + Added hardware optimization directories to zip and 7z distributions. + Fixed incorrect bitmask for options. + Fixed many spelling typos. + Make png_get_iCCP consistent with man page (allow compression-type argument + to be NULL, bug report by Lenard Szolnoki). + Replaced the remaining uses of png_size_t with size_t (Cosmin) + Fixed the calculation of row_factor in png_check_chunk_length + (reported by Thuan Pham in SourceForge issue #278) + Added missing parentheses to a macro definition + (suggested by "irwir" in GitHub issue #216) Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit https://lists.sourceforge.net/lists/listinfo/png-mng-implement -to subscribe) -or to glennrp at users.sourceforge.net +to subscribe). Glenn R-P diff --git a/src/3rdparty/libpng/CHANGES b/src/3rdparty/libpng/CHANGES index 4b82118910..0ed6a11872 100644 --- a/src/3rdparty/libpng/CHANGES +++ b/src/3rdparty/libpng/CHANGES @@ -1,4 +1,3 @@ -#if 0 CHANGES - changes for libpng version 0.1 [March 29, 1995] @@ -1454,7 +1453,7 @@ Version 1.2.6beta4 [July 28, 2004] sequential read support. Added some "#if PNG_WRITE_SUPPORTED" blocks. Added #ifdef to remove some redundancy in png_malloc_default(). - Use png_malloc instead of png_zalloc to allocate the pallete. + Use png_malloc instead of png_zalloc to allocate the palette. Version 1.0.16rc1 and 1.2.6rc1 [August 4, 2004] Fixed buffer overflow vulnerability (CVE-2004-0597) in png_handle_tRNS(). @@ -3259,7 +3258,7 @@ Version 1.5.2beta01 [February 13, 2011] Revised PNG_EXPORTA macro to not use an empty parameter, to accommodate the old VisualC++ preprocessor. Turned on interlace handling in png_read_png(). - Fixed gcc pendantic warnings. + Fixed gcc pedantic warnings. Handle longjmp in Cygwin. Fixed png_get_current_row_number() in the interlaced case. Cleaned up ALPHA flags and transformations. @@ -3359,7 +3358,7 @@ Version 1.5.3beta05 [May 6, 2011] Pass "" instead of '\0' to png_default_error() in png_err(). This mistake was introduced in libpng-1.2.20beta01. This fixes CVE-2011-2691. Added PNG_WRITE_OPTIMIZE_CMF_SUPPORTED macro to make the zlib "CMF" byte - optimization configureable. + optimization configurable. IDAT compression failed if preceded by a compressed text chunk (bug introduced in libpng-1.5.3beta01-02). This was because the attempt to reset the zlib stream in png_write_IDAT happened after the first IDAT @@ -3643,7 +3642,7 @@ Version 1.5.6beta05 [October 12, 2011] Fixed bug in png_write_chunk_header() debug print, introduced in 1.5.6beta01. Version 1.5.6beta06 [October 17, 2011] - Removed two redundant tests for unitialized row. + Removed two redundant tests for uninitialized row. Fixed a relatively harmless memory overwrite in compressed text writing with a 1 byte zlib buffer. Add ability to call png_read_update_info multiple times to pngvalid.c. @@ -3689,7 +3688,7 @@ Version 1.5.7beta01 [November 4, 2011] crash. The pngmem.c implementation of png_malloc() included a cast to png_size_t which would fail on large allocations on 16-bit systems. Fix for the preprocessor of the Intel C compiler. The preprocessor - splits adjacent @ signs with a space; this changes the concatentation + splits adjacent @ signs with a space; this changes the concatenation token from @-@-@ to PNG_JOIN; that should work with all compiler preprocessors. Paeth filter speed improvements from work by Siarhei Siamashka. This @@ -3735,7 +3734,7 @@ Version 1.5.7beta03 [November 17, 2011] gray (on palette) itself. Fixes for C++ compilation using g++ When libpng source is compiled using g++. The compiler imposes C++ rules on the C source; thus it - is desireable to make the source work with either C or C++ rules + is desirable to make the source work with either C or C++ rules without throwing away useful error information. This change adds png_voidcast to allow C semantic (void*) cases or the corresponding C++ static_cast operation, as appropriate. @@ -4061,7 +4060,7 @@ Version 1.6.0beta17 [March 10, 2012] possible to call png_inflate() incrementally. A warning is no longer issued if the language tag or translated keyword in the iTXt chunk has zero length. - If benign errors are disabled use maximum window on ancilliary inflate. + If benign errors are disabled use maximum window on ancillary inflate. This works round a bug introduced in 1.5.4 where compressed ancillary chunks could end up with a too-small windowBits value in the deflate header. @@ -4176,7 +4175,7 @@ Version 1.6.0beta27 [August 11, 2012] declared even though the functions are never actually defined. This change provides a dummy definition so that the declarations work, yet any implementation will fail to compile because of an incomplete type. - Re-eliminated the use of strcpy() in pngtest.c. An unncessary use of + Re-eliminated the use of strcpy() in pngtest.c. An unnecessary use of strcpy() was accidentally re-introduced in libpng16; this change replaces it with strncpy(). Eliminated use of png_sizeof(); use sizeof() instead. @@ -4309,7 +4308,7 @@ Version 1.6.0beta31 [November 1, 2012] resulting in VS2010 having to update the files. Removed non-working ICC profile support code that was mostly added to libpng-1.6.0beta29 and beta30. There was too much code for too little - gain; implementing full ICC color correction may be desireable but is left + gain; implementing full ICC color correction may be desirable but is left up to applications. Version 1.6.0beta32 [November 25, 2012] @@ -4592,7 +4591,7 @@ Version 1.6.3beta07 [June 8, 2013] the optimizations ('check' vs 'api') are exposed in the public header files except that the new setting PNG_ARM_NEON_OPT documents how libpng makes the decision about whether or not to use the optimizations. - Protect symbol prefixing against CC/CPPFLAGS/CFLAGS useage. + Protect symbol prefixing against CC/CPPFLAGS/CFLAGS usage. Previous iOS/Xcode fixes for the ARM NEON optimizations moved the test on __ARM_NEON__ from configure time to compile time. This breaks symbol prefixing because the definition of the special png_init_filter_functions @@ -5635,7 +5634,7 @@ Version 1.6.24beta02 [June 23, 2016] to All and adds a list of the warnings that need to be turned off. This is semi-documentary; the intent is to tell libpng users which warnings have been examined and judged non-fixable at present. The warning about - structure padding is fixable, but it would be a signficant change (moving + structure padding is fixable, but it would be a significant change (moving structure members around). Version 1.6.24beta03 [July 4, 2016] @@ -5781,7 +5780,7 @@ Version 1.6.28rc01 [January 3, 2017] Added option to Cmake build allowing a custom location of zlib to be specified in a scenario where libpng is being built as a subproject alongside zlib by another project (Sam Serrels). - Changed png_ptr->options from a png_byte to png_uint_32, to accomodate + Changed png_ptr->options from a png_byte to png_uint_32, to accommodate up to 16 options. Version 1.6.28rc02 [January 4, 2017] @@ -5932,7 +5931,7 @@ Version 1.6.32beta04 [August 2, 2017] Update libpng.3 and libpng-manual.txt about eXIf functions. Version 1.6.32beta05 [August 2, 2017] - Restored png_get_eXIf() and png_set_eXIf() to maintain API compatability. + Restored png_get_eXIf() and png_set_eXIf() to maintain API compatibility. Version 1.6.32beta06 [August 2, 2017] Removed png_get_eXIf_1() and png_set_eXIf_1(). @@ -6038,14 +6037,35 @@ Version 1.6.33 [September 28, 2017] Add end_info structure and png_read_end() to the libpng fuzzer. Version 1.6.34 [September 29, 2017] - Removed contrib/pngsuite/i*.png; some of these were incorrect and caused - test failures. + Removed contrib/pngsuite/i*.png; some of them caused test failures. + +Version 1.6.35beta01 [March 6, 2018] + Restored 21 of the contrib/pngsuite/i*.png, which do not cause test + failures. Placed the remainder in contrib/pngsuite/interlaced/i*.png. + Added calls to png_set_*() transforms commonly used by browsers to + the fuzzer. + Removed some unnecessary brackets in pngrtran.c + Fixed miscellaneous typos (Patch by github user "luzpaz"). + Change "ASM C" to "C ASM" in CMakeLists.txt + Fixed incorrect handling of bKGD chunk in sub-8-bit files (Cosmin) + Added hardware optimization directories to zip and 7z distributions. + Fixed incorrect bitmask for options. + Fixed many spelling typos. + +Version 1.6.35beta02 [March 28, 2018] + Make png_get_iCCP consistent with man page (allow compression-type argument + to be NULL, bug report by Lenard Szolnoki). + +Version 1.6.35 [July 15, 2018] + Replaced the remaining uses of png_size_t with size_t (Cosmin) + Fixed the calculation of row_factor in png_check_chunk_length + (reported by Thuan Pham in SourceForge issue #278) + Added missing parentheses to a macro definition + (suggested by "irwir" in GitHub issue #216) Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit https://lists.sourceforge.net/lists/listinfo/png-mng-implement -to subscribe) -or to glennrp at users.sourceforge.net +to subscribe). Glenn R-P -#endif diff --git a/src/3rdparty/libpng/INSTALL b/src/3rdparty/libpng/INSTALL index e8edb7240f..4c17022515 100644 --- a/src/3rdparty/libpng/INSTALL +++ b/src/3rdparty/libpng/INSTALL @@ -284,7 +284,7 @@ those sections that are actually used will be loaded into memory. XIV. Enabling or disabling hardware optimizations -Certain hardware capabilites, such as the Intel SSE instructions, +Certain hardware capabilities, such as the Intel SSE instructions, are normally detected at run time. Enable them with configure options such as one of diff --git a/src/3rdparty/libpng/LICENSE b/src/3rdparty/libpng/LICENSE index 4cda4fa0ad..6ee9c8f554 100644 --- a/src/3rdparty/libpng/LICENSE +++ b/src/3rdparty/libpng/LICENSE @@ -10,8 +10,8 @@ this sentence. This code is released under the libpng license. -libpng versions 1.0.7, July 1, 2000 through 1.6.34, September 29, 2017 are -Copyright (c) 2000-2002, 2004, 2006-2017 Glenn Randers-Pehrson, are +libpng versions 1.0.7, July 1, 2000 through 1.6.35, July 15, 2018 are +Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson, are derived from libpng-1.0.6, and are distributed according to the same disclaimer and license as libpng-1.0.6 with the following individuals added to the list of Contributing Authors: @@ -130,4 +130,4 @@ any encryption software. See the EAR, paragraphs 734.3(b)(3) and Glenn Randers-Pehrson glennrp at users.sourceforge.net -September 29, 2017 +July 15, 2018 diff --git a/src/3rdparty/libpng/README b/src/3rdparty/libpng/README index 0da5a5ef83..f098b27f39 100644 --- a/src/3rdparty/libpng/README +++ b/src/3rdparty/libpng/README @@ -1,4 +1,4 @@ -README for libpng version 1.6.34 - September 29, 2017 (shared library 16.0) +README for libpng version 1.6.35 - July 15, 2018 (shared library 16.0) See the note about version numbers near the top of png.h See INSTALL for instructions on how to install libpng. @@ -118,7 +118,7 @@ development group. Send comments/corrections/commendations to png-mng-implement at lists.sourceforge.net (subscription required; visit https://lists.sourceforge.net/lists/listinfo/png-mng-implement -to subscribe) or to glennrp at users.sourceforge.net +to subscribe). You can't reach Guy, the original libpng author, at the addresses given in previous versions of this document. He and Andreas will diff --git a/src/3rdparty/libpng/libpng-manual.txt b/src/3rdparty/libpng/libpng-manual.txt index d4407ef2ea..b14a534163 100644 --- a/src/3rdparty/libpng/libpng-manual.txt +++ b/src/3rdparty/libpng/libpng-manual.txt @@ -1,9 +1,8 @@ libpng-manual.txt - A description on how to use and modify libpng - libpng version 1.6.34 - September 29, 2017 + libpng version 1.6.35 - July 15, 2018 Updated and distributed by Glenn Randers-Pehrson - - Copyright (c) 1998-2017 Glenn Randers-Pehrson + Copyright (c) 1998-2018 Glenn Randers-Pehrson This document is released under the libpng license. For conditions of distribution and use, see the disclaimer @@ -11,7 +10,7 @@ libpng-manual.txt - A description on how to use and modify libpng Based on: - libpng versions 0.97, January 1998, through 1.6.34 - September 29, 2017 + libpng versions 0.97, January 1998, through 1.6.35 - July 15, 2018 Updated and distributed by Glenn Randers-Pehrson Copyright (c) 1998-2017 Glenn Randers-Pehrson @@ -348,18 +347,18 @@ Customizing libpng. FILE *fp = fopen(file_name, "rb"); if (!fp) { - return (ERROR); + return ERROR; } if (fread(header, 1, number, fp) != number) { - return (ERROR); + return ERROR; } is_png = !png_sig_cmp(header, 0, number); if (!is_png) { - return (NOT_PNG); + return NOT_PNG; } Next, png_struct and png_info need to be allocated and initialized. In @@ -378,7 +377,7 @@ create the structure, so your application should check for that. user_error_fn, user_warning_fn); if (!png_ptr) - return (ERROR); + return ERROR; png_infop info_ptr = png_create_info_struct(png_ptr); @@ -386,7 +385,7 @@ create the structure, so your application should check for that. { png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); - return (ERROR); + return ERROR; } If you want to use your own memory allocation routines, @@ -421,7 +420,7 @@ free any memory. png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(fp); - return (ERROR); + return ERROR; } Pass (png_infopp)NULL instead of &end_info if you didn't create @@ -503,7 +502,7 @@ input stream. You must supply the function png_byte name[5]; png_byte *data; - png_size_t size; + size_t size; /* Note that libpng has already taken care of the CRC handling */ @@ -512,9 +511,9 @@ input stream. You must supply the function unknown chunk structure, process it, and return one of the following: */ - return (-n); /* chunk had an error */ - return (0); /* did not recognize */ - return (n); /* success */ + return -n; /* chunk had an error */ + return 0; /* did not recognize */ + return n; /* success */ } (You can give your function another name that you like instead of @@ -1003,7 +1002,7 @@ chunks to be assumed to be encoded using sRGB. png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC); In this case the output is assumed to be something like an sRGB conformant -display preceeded by a power-law lookup table of power 1.45. This is how +display preceded by a power-law lookup table of power 1.45. This is how early Mac systems behaved. png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR); @@ -1055,7 +1054,7 @@ faster.) When the default gamma of PNG files doesn't match the output gamma. If you have PNG files with no gamma information png_set_alpha_mode allows -you to provide a default gamma, but it also sets the ouput gamma to the +you to provide a default gamma, but it also sets the output gamma to the matching value. If you know your PNG files have a gamma that doesn't match the output you can take advantage of the fact that png_set_alpha_mode always sets the output gamma but only sets the PNG @@ -2409,7 +2408,7 @@ separate. { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); - return (ERROR); + return ERROR; } png_read_end(png_ptr, end_info); @@ -2549,7 +2548,7 @@ png_infop info_ptr; user_error_fn, user_warning_fn); if (!png_ptr) - return (ERROR); + return ERROR; info_ptr = png_create_info_struct(png_ptr); @@ -2557,14 +2556,14 @@ png_infop info_ptr; { png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); - return (ERROR); + return ERROR; } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); - return (ERROR); + return ERROR; } /* This one's new. You can provide functions @@ -2598,7 +2597,7 @@ png_infop info_ptr; { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); - return (ERROR); + return ERROR; } /* This one's new also. Simply give it a chunk @@ -2742,7 +2741,7 @@ custom writing functions. See the discussion under Customizing libpng. FILE *fp = fopen(file_name, "wb"); if (!fp) - return (ERROR); + return ERROR; Next, png_struct and png_info need to be allocated and initialized. As these can be both relatively large, you may not want to store these @@ -2757,14 +2756,14 @@ both "png_ptr"; you can call them anything you like, such as user_error_fn, user_warning_fn); if (!png_ptr) - return (ERROR); + return ERROR; png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_write_struct(&png_ptr, (png_infopp)NULL); - return (ERROR); + return ERROR; } If you want to use your own memory allocation routines, @@ -2791,7 +2790,7 @@ section below for more information on the libpng error handling. { png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); - return (ERROR); + return ERROR; } ... return; @@ -3779,7 +3778,7 @@ in-memory bitmap formats or to be written from the same formats. If these formats do not accommodate your needs then you can, and should, use the more sophisticated APIs above - these support a wide variety of in-memory formats and a wide variety of sophisticated transformations to those formats as well -as a wide variety of APIs to manipulate ancilliary information. +as a wide variety of APIs to manipulate ancillary information. To read a PNG file using the simplified API: @@ -4102,7 +4101,7 @@ READ APIs The PNG header is read from the stdio FILE object. int png_image_begin_read_from_memory(png_imagep image, - png_const_voidp memory, png_size_t size) + png_const_voidp memory, size_t size) The PNG header is read from the given memory buffer. @@ -4255,10 +4254,10 @@ png_get_io_ptr(). For example: The replacement I/O functions must have prototypes as follows: void user_read_data(png_structp png_ptr, - png_bytep data, png_size_t length); + png_bytep data, size_t length); void user_write_data(png_structp png_ptr, - png_bytep data, png_size_t length); + png_bytep data, size_t length); void user_flush_data(png_structp png_ptr); @@ -4784,7 +4783,7 @@ behavior in case the application runs out of memory part-way through the process. We changed the prototypes of png_get_compression_buffer_size() and -png_set_compression_buffer_size() to work with png_size_t instead of +png_set_compression_buffer_size() to work with size_t instead of png_uint_32. Support for numbered error messages was removed by default, since we @@ -5255,9 +5254,8 @@ or you can browse it with a web browser at https://github.com/glennrp/libpng or https://sourceforge.net/p/libpng/code/ci/libpng16/tree/ -Patches can be sent to glennrp at users.sourceforge.net or to -png-mng-implement at lists.sourceforge.net or you can upload them to -the libpng bug tracker at +Patches can be sent to png-mng-implement at lists.sourceforge.net or +you can upload them to the libpng bug tracker at https://libpng.sourceforge.io/ @@ -5266,9 +5264,9 @@ or as a "pull request" to https://github.com/glennrp/libpng/pulls We also accept patches built from the tar or zip distributions, and -simple verbal discriptions of bug fixes, reported either to the +simple verbal descriptions of bug fixes, reported either to the SourceForge bug tracker, to the png-mng-implement at lists.sf.net -mailing list, as github issues, or directly to glennrp. +mailing list, as github issues. XV. Coding style @@ -5289,7 +5287,7 @@ braces on separate lines: The braces can be omitted from simple one-line actions: if (condition) - return (0); + return 0; We use 3-space indentation, except for continued statements which are usually indented the same as the first line of the statement @@ -5414,7 +5412,7 @@ Since the PNG Development group is an ad-hoc body, we can't make an official declaration. This is your unofficial assurance that libpng from version 0.71 and -upward through 1.6.34 are Y2K compliant. It is my belief that earlier +upward through 1.6.35 are Y2K compliant. It is my belief that earlier versions were also Y2K compliant. Libpng only has two year fields. One is a 2-byte unsigned integer diff --git a/src/3rdparty/libpng/png.c b/src/3rdparty/libpng/png.c index ff02c56518..a25afebcc8 100644 --- a/src/3rdparty/libpng/png.c +++ b/src/3rdparty/libpng/png.c @@ -1,8 +1,8 @@ /* png.c - location for general purpose libpng functions * - * Last changed in libpng 1.6.33 [September 28, 2017] - * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson + * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -14,7 +14,7 @@ #include "pngpriv.h" /* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_6_34 Your_png_h_is_not_version_1_6_34; +typedef png_libpng_version_1_6_35 Your_png_h_is_not_version_1_6_35; #ifdef __GNUC__ /* The version tests may need to be added to, but the problem warning has @@ -71,7 +71,7 @@ png_set_sig_bytes(png_structrp png_ptr, int num_bytes) * PNG signature (this is the same behavior as strcmp, memcmp, etc). */ int PNGAPI -png_sig_cmp(png_const_bytep sig, png_size_t start, png_size_t num_to_check) +png_sig_cmp(png_const_bytep sig, size_t start, size_t num_to_check) { png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; @@ -136,7 +136,7 @@ png_reset_crc(png_structrp png_ptr) * trouble of calculating it. */ void /* PRIVATE */ -png_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, png_size_t length) +png_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, size_t length) { int need_crc = 1; @@ -421,7 +421,7 @@ png_destroy_info_struct(png_const_structrp png_ptr, png_infopp info_ptr_ptr) * those cases where it does anything other than a memset. */ PNG_FUNCTION(void,PNGAPI -png_info_init_3,(png_infopp ptr_ptr, png_size_t png_info_struct_size), +png_info_init_3,(png_infopp ptr_ptr, size_t png_info_struct_size), PNG_DEPRECATED) { png_inforp info_ptr = *ptr_ptr; @@ -816,15 +816,15 @@ png_get_copyright(png_const_structrp png_ptr) #else # ifdef __STDC__ return PNG_STRING_NEWLINE \ - "libpng version 1.6.34 - September 29, 2017" PNG_STRING_NEWLINE \ - "Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson" \ + "libpng version 1.6.35 - July 15, 2018" PNG_STRING_NEWLINE \ + "Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \ PNG_STRING_NEWLINE \ "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ PNG_STRING_NEWLINE; # else - return "libpng version 1.6.34 - September 29, 2017\ - Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson\ + return "libpng version 1.6.35 - July 15, 2018\ + Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson\ Copyright (c) 1996-1997 Andreas Dilger\ Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."; # endif @@ -942,7 +942,7 @@ png_handle_as_unknown(png_const_structrp png_ptr, png_const_bytep chunk_name) /* The code is the fifth byte after each four byte string. Historically this * code was always searched from the end of the list, this is no longer - * necessary because the 'set' routine handles duplicate entries correcty. + * necessary because the 'set' routine handles duplicate entries correctly. */ do /* num_chunk_list > 0, so at least one */ { @@ -2067,7 +2067,7 @@ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace, */ /* Data checks (could be skipped). These checks must be independent of the - * version number; however, the version number doesn't accomodate changes in + * version number; however, the version number doesn't accommodate changes in * the header fields (just the known tags and the interpretation of the * data.) */ @@ -2707,7 +2707,7 @@ png_check_IHDR(png_const_structrp png_ptr, #if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) /* ASCII to fp functions */ -/* Check an ASCII formated floating point value, see the more detailed +/* Check an ASCII formatted floating point value, see the more detailed * comments in pngpriv.h */ /* The following is used internally to preserve the sticky flags */ @@ -2715,11 +2715,11 @@ png_check_IHDR(png_const_structrp png_ptr, #define png_fp_set(state, value) ((state) = (value) | ((state) & PNG_FP_STICKY)) int /* PRIVATE */ -png_check_fp_number(png_const_charp string, png_size_t size, int *statep, +png_check_fp_number(png_const_charp string, size_t size, int *statep, png_size_tp whereami) { int state = *statep; - png_size_t i = *whereami; + size_t i = *whereami; while (i < size) { @@ -2842,10 +2842,10 @@ PNG_FP_End: /* The same but for a complete string. */ int -png_check_fp_string(png_const_charp string, png_size_t size) +png_check_fp_string(png_const_charp string, size_t size) { int state=0; - png_size_t char_index=0; + size_t char_index=0; if (png_check_fp_number(string, size, &state, &char_index) != 0 && (char_index == size || string[char_index] == 0)) @@ -2906,7 +2906,7 @@ png_pow10(int power) #pragma GCC diagnostic warning "-Wstrict-overflow=2" #endif /* GCC_STRICT_OVERFLOW */ void /* PRIVATE */ -png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size, +png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size, double fp, unsigned int precision) { /* We use standard functions from math.h, but not printf because @@ -3237,7 +3237,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size, */ void /* PRIVATE */ png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii, - png_size_t size, png_fixed_point fp) + size_t size, png_fixed_point fp) { /* Require space for 10 decimal digits, a decimal point, a minus sign and a * trailing \0, 13 characters: @@ -4344,7 +4344,7 @@ png_set_option(png_structrp png_ptr, int option, int onoff) png_uint_32 setting = (2U + (onoff != 0)) << option; png_uint_32 current = png_ptr->options; - png_ptr->options = (png_uint_32)(((current & ~mask) | setting) & 0xff); + png_ptr->options = (png_uint_32)((current & ~mask) | setting); return (int)(current & mask) >> option; } diff --git a/src/3rdparty/libpng/png.h b/src/3rdparty/libpng/png.h index 4c873f5c22..19e464cc17 100644 --- a/src/3rdparty/libpng/png.h +++ b/src/3rdparty/libpng/png.h @@ -1,9 +1,9 @@ /* png.h - header file for PNG reference library * - * libpng version 1.6.34, September 29, 2017 + * libpng version 1.6.35, July 15, 2018 * - * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -12,7 +12,7 @@ * Authors and maintainers: * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat * libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger - * libpng versions 0.97, January 1998, through 1.6.34, September 29, 2017: + * libpng versions 0.97, January 1998, through 1.6.35, July 15, 2018: * Glenn Randers-Pehrson. * See also "Contributing Authors", below. */ @@ -25,8 +25,8 @@ * * This code is released under the libpng license. * - * libpng versions 1.0.7, July 1, 2000 through 1.6.34, September 29, 2017 are - * Copyright (c) 2000-2002, 2004, 2006-2017 Glenn Randers-Pehrson, are + * libpng versions 1.0.7, July 1, 2000 through 1.6.35, July 15, 2018 are + * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson, are * derived from libpng-1.0.6, and are distributed according to the same * disclaimer and license as libpng-1.0.6 with the following individuals * added to the list of Contributing Authors: @@ -213,7 +213,7 @@ * ... * 1.5.30 15 10527 15.so.15.30[.0] * ... - * 1.6.34 16 10633 16.so.16.34[.0] + * 1.6.35 16 10635 16.so.16.35[.0] * * Henceforth the source version will match the shared-library major * and minor numbers; the shared-library major version number will be @@ -241,13 +241,13 @@ * Y2K compliance in libpng: * ========================= * - * September 29, 2017 + * July 15, 2018 * * Since the PNG Development group is an ad-hoc body, we can't make * an official declaration. * * This is your unofficial assurance that libpng from version 0.71 and - * upward through 1.6.34 are Y2K compliant. It is my belief that + * upward through 1.6.35 are Y2K compliant. It is my belief that * earlier versions were also Y2K compliant. * * Libpng only has two year fields. One is a 2-byte unsigned integer @@ -309,8 +309,8 @@ */ /* Version information for png.h - this should match the version in png.c */ -#define PNG_LIBPNG_VER_STRING "1.6.34" -#define PNG_HEADER_VERSION_STRING " libpng version 1.6.34 - September 29, 2017\n" +#define PNG_LIBPNG_VER_STRING "1.6.35" +#define PNG_HEADER_VERSION_STRING " libpng version 1.6.35 - July 15, 2018\n" #define PNG_LIBPNG_VER_SONUM 16 #define PNG_LIBPNG_VER_DLLNUM 16 @@ -318,13 +318,13 @@ /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ #define PNG_LIBPNG_VER_MAJOR 1 #define PNG_LIBPNG_VER_MINOR 6 -#define PNG_LIBPNG_VER_RELEASE 34 +#define PNG_LIBPNG_VER_RELEASE 35 /* This should match the numeric part of the final component of * PNG_LIBPNG_VER_STRING, omitting any leading zero: */ -#define PNG_LIBPNG_VER_BUILD 0 +#define PNG_LIBPNG_VER_BUILD 02 /* Release Status */ #define PNG_LIBPNG_BUILD_ALPHA 1 @@ -341,7 +341,7 @@ #define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with PNG_LIBPNG_BUILD_PRIVATE */ -#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE +#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_BETA /* Careful here. At one time, Guy wanted to use 082, but that would be octal. * We must not include leading zeros. @@ -349,7 +349,7 @@ * version 1.0.0 was mis-numbered 100 instead of 10000). From * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release */ -#define PNG_LIBPNG_VER 10634 /* 1.6.34 */ +#define PNG_LIBPNG_VER 10635 /* 1.6.35 */ /* Library configuration: these options cannot be changed after * the library has been built. @@ -459,7 +459,7 @@ extern "C" { /* This triggers a compiler error in png.c, if png.c and png.h * do not agree upon the version number. */ -typedef char* png_libpng_version_1_6_34; +typedef char* png_libpng_version_1_6_35; /* Basic control structions. Read libpng-manual.txt or libpng.3 for more info. * @@ -600,8 +600,8 @@ typedef struct png_text_struct png_charp key; /* keyword, 1-79 character description of "text" */ png_charp text; /* comment, may be an empty string (ie "") or a NULL pointer */ - png_size_t text_length; /* length of the text string */ - png_size_t itxt_length; /* length of the itxt string */ + size_t text_length; /* length of the text string */ + size_t itxt_length; /* length of the itxt string */ png_charp lang; /* language code, 0-79 characters or a NULL pointer */ png_charp lang_key; /* keyword translated UTF-8 string, 0 or more @@ -654,7 +654,7 @@ typedef struct png_unknown_chunk_t { png_byte name[5]; /* Textual chunk name with '\0' terminator */ png_byte *data; /* Data, should not be modified on read! */ - png_size_t size; + size_t size; /* On write 'location' must be set using the flag values listed below. * Notice that on read it is set by libpng however the values stored have @@ -679,7 +679,7 @@ typedef png_unknown_chunk * * png_unknown_chunkpp; /* Maximum positive integer used in PNG is (2^31)-1 */ #define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL) #define PNG_UINT_32_MAX ((png_uint_32)(-1)) -#define PNG_SIZE_MAX ((png_size_t)(-1)) +#define PNG_SIZE_MAX ((size_t)(-1)) /* These are constants for fixed point values encoded in the * PNG specification manner (x100000) @@ -785,7 +785,7 @@ typedef png_unknown_chunk * * png_unknown_chunkpp; typedef struct png_row_info_struct { png_uint_32 width; /* width of row */ - png_size_t rowbytes; /* number of bytes in row */ + size_t rowbytes; /* number of bytes in row */ png_byte color_type; /* color type of row */ png_byte bit_depth; /* bit depth of row */ png_byte channels; /* number of channels (1, 2, 3, or 4) */ @@ -804,7 +804,7 @@ typedef png_row_info * * png_row_infopp; * expected to return the read data in the buffer. */ typedef PNG_CALLBACK(void, *png_error_ptr, (png_structp, png_const_charp)); -typedef PNG_CALLBACK(void, *png_rw_ptr, (png_structp, png_bytep, png_size_t)); +typedef PNG_CALLBACK(void, *png_rw_ptr, (png_structp, png_bytep, size_t)); typedef PNG_CALLBACK(void, *png_flush_ptr, (png_structp)); typedef PNG_CALLBACK(void, *png_read_status_ptr, (png_structp, png_uint_32, int)); @@ -941,8 +941,8 @@ PNG_EXPORT(2, void, png_set_sig_bytes, (png_structrp png_ptr, int num_bytes)); * signature, and non-zero otherwise. Having num_to_check == 0 or * start > 7 will always fail (ie return non-zero). */ -PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, png_size_t start, - png_size_t num_to_check)); +PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, size_t start, + size_t num_to_check)); /* Simple signature checking function. This is the same as calling * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n). @@ -961,11 +961,11 @@ PNG_EXPORTA(5, png_structp, png_create_write_struct, png_error_ptr warn_fn), PNG_ALLOCATED); -PNG_EXPORT(6, png_size_t, png_get_compression_buffer_size, +PNG_EXPORT(6, size_t, png_get_compression_buffer_size, (png_const_structrp png_ptr)); PNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structrp png_ptr, - png_size_t size)); + size_t size)); /* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp * match up. @@ -1018,7 +1018,7 @@ PNG_EXPORT(13, void, png_write_sig, (png_structrp png_ptr)); /* Write a PNG chunk - size, type, (optional) data, CRC. */ PNG_EXPORT(14, void, png_write_chunk, (png_structrp png_ptr, png_const_bytep - chunk_name, png_const_bytep data, png_size_t length)); + chunk_name, png_const_bytep data, size_t length)); /* Write the start of a PNG chunk - length and chunk name. */ PNG_EXPORT(15, void, png_write_chunk_start, (png_structrp png_ptr, @@ -1026,7 +1026,7 @@ PNG_EXPORT(15, void, png_write_chunk_start, (png_structrp png_ptr, /* Write the data of a PNG chunk started with png_write_chunk_start(). */ PNG_EXPORT(16, void, png_write_chunk_data, (png_structrp png_ptr, - png_const_bytep data, png_size_t length)); + png_const_bytep data, size_t length)); /* Finish a chunk started with png_write_chunk_start() (includes CRC). */ PNG_EXPORT(17, void, png_write_chunk_end, (png_structrp png_ptr)); @@ -1040,7 +1040,7 @@ PNG_EXPORTA(18, png_infop, png_create_info_struct, (png_const_structrp png_ptr), * the API will be removed in the future. */ PNG_EXPORTA(19, void, png_info_init_3, (png_infopp info_ptr, - png_size_t png_info_struct_size), PNG_DEPRECATED); + size_t png_info_struct_size), PNG_DEPRECATED); /* Writes all the PNG information before the image. */ PNG_EXPORT(20, void, png_write_info_before_PLTE, @@ -1137,7 +1137,7 @@ PNG_EXPORT(35, void, png_build_grayscale_palette, (int bit_depth, * corresponding composited pixel, and the color channels are unassociated * (not premultiplied). The gamma encoded color channels must be scaled * according to the contribution and to do this it is necessary to undo - * the encoding, scale the color values, perform the composition and reencode + * the encoding, scale the color values, perform the composition and re-encode * the values. This is the 'PNG' mode. * * The alternative is to 'associate' the alpha with the color information by @@ -1193,7 +1193,7 @@ PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structrp png_ptr, * * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC); * In this case the output is assumed to be something like an sRGB conformant - * display preceeded by a power-law lookup table of power 1.45. This is how + * display preceded by a power-law lookup table of power 1.45. This is how * early Mac systems behaved. * * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR); @@ -1240,7 +1240,7 @@ PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structrp png_ptr, * * When the default gamma of PNG files doesn't match the output gamma. * If you have PNG files with no gamma information png_set_alpha_mode allows - * you to provide a default gamma, but it also sets the ouput gamma to the + * you to provide a default gamma, but it also sets the output gamma to the * matching value. If you know your PNG files have a gamma that doesn't * match the output you can take advantage of the fact that * png_set_alpha_mode always sets the output gamma but only sets the PNG @@ -1691,7 +1691,7 @@ PNG_EXPORT(218, png_byte, png_get_current_pass_number, (png_const_structrp)); * chunk will cause an error at this point unless it is to be saved. * positive: The chunk was handled, libpng will ignore/discard it. * - * See "INTERACTION WTIH USER CHUNK CALLBACKS" below for important notes about + * See "INTERACTION WITH USER CHUNK CALLBACKS" below for important notes about * how this behavior will change in libpng 1.7 */ PNG_EXPORT(88, void, png_set_read_user_chunk_fn, (png_structrp png_ptr, @@ -1716,7 +1716,7 @@ PNG_EXPORT(91, png_voidp, png_get_progressive_ptr, /* Function to be called when data becomes available */ PNG_EXPORT(92, void, png_process_data, (png_structrp png_ptr, - png_inforp info_ptr, png_bytep buffer, png_size_t buffer_size)); + png_inforp info_ptr, png_bytep buffer, size_t buffer_size)); /* A function which may be called *only* within png_process_data to stop the * processing of any more data. The function returns the number of bytes @@ -1725,7 +1725,7 @@ PNG_EXPORT(92, void, png_process_data, (png_structrp png_ptr, * 'save' is set to true the routine will first save all the pending data and * will always return 0. */ -PNG_EXPORT(219, png_size_t, png_process_data_pause, (png_structrp, int save)); +PNG_EXPORT(219, size_t, png_process_data_pause, (png_structrp, int save)); /* A function which may be called *only* outside (after) a call to * png_process_data. It returns the number of bytes of data to skip in the @@ -1870,7 +1870,7 @@ PNG_EXPORT(110, png_uint_32, png_get_valid, (png_const_structrp png_ptr, png_const_inforp info_ptr, png_uint_32 flag)); /* Returns number of bytes needed to hold a transformed row. */ -PNG_EXPORT(111, png_size_t, png_get_rowbytes, (png_const_structrp png_ptr, +PNG_EXPORT(111, size_t, png_get_rowbytes, (png_const_structrp png_ptr, png_const_inforp info_ptr)); #ifdef PNG_INFO_IMAGE_SUPPORTED @@ -2239,7 +2239,7 @@ PNG_EXPORT(171, void, png_set_sCAL_s, (png_const_structrp png_ptr, * to specifying "NEVER", however when "AS_DEFAULT" is used for specific chunks * it simply resets the behavior to the libpng default. * - * INTERACTION WTIH USER CHUNK CALLBACKS: + * INTERACTION WITH USER CHUNK CALLBACKS: * The per-chunk handling is always used when there is a png_user_chunk_ptr * callback and the callback returns 0; the chunk is then always stored *unless* * it is critical and the per-chunk setting is other than ALWAYS. Notice that @@ -2658,7 +2658,7 @@ PNG_EXPORT(243, int, png_get_palette_max, (png_const_structp png_ptr, * The simplified API hides the details of both libpng and the PNG file format * itself. It allows PNG files to be read into a very limited number of * in-memory bitmap formats or to be written from the same formats. If these - * formats do not accomodate your needs then you can, and should, use the more + * formats do not accommodate your needs then you can, and should, use the more * sophisticated APIs above - these support a wide variety of in-memory formats * and a wide variety of sophisticated transformations to those formats as well * as a wide variety of APIs to manipulate ancillary information. @@ -3020,7 +3020,7 @@ PNG_EXPORT(235, int, png_image_begin_read_from_stdio, (png_imagep image, #endif /* STDIO */ PNG_EXPORT(236, int, png_image_begin_read_from_memory, (png_imagep image, - png_const_voidp memory, png_size_t size)); + png_const_voidp memory, size_t size)); /* The PNG header is read from the given memory buffer. */ PNG_EXPORT(237, int, png_image_finish_read, (png_imagep image, @@ -3133,7 +3133,7 @@ PNG_EXPORT(245, int, png_image_write_to_memory, (png_imagep image, void *memory, * than or equal to the original value. * * If the function returns false and *memory_bytes was not changed an error - * occured during write. If *memory_bytes was changed, or is not 0 if + * occurred during write. If *memory_bytes was changed, or is not 0 if * 'memory' was NULL, the write would have succeeded but for the memory * buffer being too small. *memory_bytes contains the required number of * bytes and will be bigger that the original value. @@ -3217,7 +3217,7 @@ PNG_EXPORT(245, int, png_image_write_to_memory, (png_imagep image, void *memory, * option and 'onoff' is 0 (off) or non-0 (on). The value returned is given * by the PNG_OPTION_ defines below. * - * HARDWARE: normally hardware capabilites, such as the Intel SSE instructions, + * HARDWARE: normally hardware capabilities, such as the Intel SSE instructions, * are detected at run time, however sometimes it may be impossible * to do this in user mode, in which case it is necessary to discover * the capabilities in an OS specific way. Such capabilities are diff --git a/src/3rdparty/libpng/pngconf.h b/src/3rdparty/libpng/pngconf.h index d13b13e57a..a4646bab85 100644 --- a/src/3rdparty/libpng/pngconf.h +++ b/src/3rdparty/libpng/pngconf.h @@ -1,9 +1,9 @@ /* pngconf.h - machine configurable file for libpng * - * libpng version 1.6.34, September 29, 2017 + * libpng version 1.6.35, July 15, 2018 * - * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson + * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -127,7 +127,7 @@ * * These cases only differ if the operating system does not use the C * calling convention, at present this just means the above cases - * (x86 DOS/Windows sytems) and, even then, this does not apply to + * (x86 DOS/Windows systems) and, even then, this does not apply to * Cygwin running on those systems. * * Note that the value must be defined in pnglibconf.h so that what @@ -515,8 +515,10 @@ # error "libpng requires an unsigned 32-bit (or more) type" #endif -/* Prior to 1.6.0 it was possible to disable the use of size_t, 1.6.0, however, - * requires an ISOC90 compiler and relies on consistent behavior of sizeof. +/* Prior to 1.6.0, it was possible to disable the use of size_t and ptrdiff_t. + * From 1.6.0 onwards, an ISO C90 compiler, as well as a standard-compliant + * behavior of sizeof and ptrdiff_t are required. + * The legacy typedefs are provided here for backwards compatibility. */ typedef size_t png_size_t; typedef ptrdiff_t png_ptrdiff_t; @@ -537,13 +539,12 @@ typedef ptrdiff_t png_ptrdiff_t; # endif #endif -/* png_alloc_size_t is guaranteed to be no smaller than png_size_t, and no - * smaller than png_uint_32. Casts from png_size_t or png_uint_32 to - * png_alloc_size_t are not necessary; in fact, it is recommended not to use - * them at all so that the compiler can complain when something turns out to be - * problematic. +/* png_alloc_size_t is guaranteed to be no smaller than size_t, and no smaller + * than png_uint_32. Casts from size_t or png_uint_32 to png_alloc_size_t are + * not necessary; in fact, it is recommended not to use them at all, so that + * the compiler can complain when something turns out to be problematic. * - * Casts in the other direction (from png_alloc_size_t to png_size_t or + * Casts in the other direction (from png_alloc_size_t to size_t or * png_uint_32) should be explicitly applied; however, we do not expect to * encounter practical situations that require such conversions. * @@ -553,7 +554,7 @@ typedef ptrdiff_t png_ptrdiff_t; #ifdef PNG_SMALL_SIZE_T typedef png_uint_32 png_alloc_size_t; #else - typedef png_size_t png_alloc_size_t; + typedef size_t png_alloc_size_t; #endif /* Prior to 1.6.0 libpng offered limited support for Microsoft C compiler @@ -589,8 +590,8 @@ typedef char * png_charp; typedef const char * png_const_charp; typedef png_fixed_point * png_fixed_point_p; typedef const png_fixed_point * png_const_fixed_point_p; -typedef png_size_t * png_size_tp; -typedef const png_size_t * png_const_size_tp; +typedef size_t * png_size_tp; +typedef const size_t * png_const_size_tp; #ifdef PNG_STDIO_SUPPORTED typedef FILE * png_FILE_p; diff --git a/src/3rdparty/libpng/pngget.c b/src/3rdparty/libpng/pngget.c index 26e9fb1c35..2325508f1d 100644 --- a/src/3rdparty/libpng/pngget.c +++ b/src/3rdparty/libpng/pngget.c @@ -1,8 +1,8 @@ /* pngget.c - retrieval of values from info struct * - * Last changed in libpng 1.6.32 [August 24, 2017] - * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson + * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -26,7 +26,7 @@ png_get_valid(png_const_structrp png_ptr, png_const_inforp info_ptr, return(0); } -png_size_t PNGAPI +size_t PNGAPI png_get_rowbytes(png_const_structrp png_ptr, png_const_inforp info_ptr) { if (png_ptr != NULL && info_ptr != NULL) @@ -367,7 +367,7 @@ png_get_y_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr) static png_fixed_point png_fixed_inches_from_microns(png_const_structrp png_ptr, png_int_32 microns) { - /* Convert from metres * 1,000,000 to inches * 100,000, meters to + /* Convert from meters * 1,000,000 to inches * 100,000, meters to * inches is simply *(100/2.54), so we want *(10/2.54) == 500/127. * Notice that this can overflow - a warning is output and 0 is * returned. @@ -741,8 +741,7 @@ png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP) != 0 && - name != NULL && compression_type != NULL && profile != NULL && - proflen != NULL) + name != NULL && profile != NULL && proflen != NULL) { *name = info_ptr->iccp_name; *profile = info_ptr->iccp_profile; @@ -750,11 +749,13 @@ png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, /* This is somewhat irrelevant since the profile data returned has * actually been uncompressed. */ - *compression_type = PNG_COMPRESSION_TYPE_BASE; + if (compression_type != NULL) + *compression_type = PNG_COMPRESSION_TYPE_BASE; return (PNG_INFO_iCCP); } return (0); + } #endif @@ -1164,7 +1165,7 @@ png_get_user_chunk_ptr(png_const_structrp png_ptr) } #endif -png_size_t PNGAPI +size_t PNGAPI png_get_compression_buffer_size(png_const_structrp png_ptr) { if (png_ptr == NULL) diff --git a/src/3rdparty/libpng/pnginfo.h b/src/3rdparty/libpng/pnginfo.h index d5f6149dbd..2fcf868dac 100644 --- a/src/3rdparty/libpng/pnginfo.h +++ b/src/3rdparty/libpng/pnginfo.h @@ -1,8 +1,8 @@ /* pnginfo.h - header file for PNG reference library * - * Last changed in libpng 1.6.1 [March 28, 2013] - * Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson + * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 1998-2002,2004,2006-2013,2018 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -55,10 +55,10 @@ struct png_info_def { /* The following are necessary for every PNG file */ - png_uint_32 width; /* width of image in pixels (from IHDR) */ - png_uint_32 height; /* height of image in pixels (from IHDR) */ - png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */ - png_size_t rowbytes; /* bytes needed to hold an untransformed row */ + png_uint_32 width; /* width of image in pixels (from IHDR) */ + png_uint_32 height; /* height of image in pixels (from IHDR) */ + png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */ + size_t rowbytes; /* bytes needed to hold an untransformed row */ png_colorp palette; /* array of color values (valid & PNG_INFO_PLTE) */ png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */ png_uint_16 num_trans; /* number of transparent palette color (tRNS) */ @@ -247,7 +247,7 @@ defined(PNG_READ_BACKGROUND_SUPPORTED) /* The sCAL chunk describes the actual physical dimensions of the * subject matter of the graphic. The chunk contains a unit specification * a byte value, and two ASCII strings representing floating-point - * values. The values are width and height corresponsing to one pixel + * values. The values are width and height corresponding to one pixel * in the image. Data values are valid if (valid & PNG_INFO_sCAL) is * non-zero. */ diff --git a/src/3rdparty/libpng/pnglibconf.h b/src/3rdparty/libpng/pnglibconf.h index 53b5e442c4..00acecc69b 100644 --- a/src/3rdparty/libpng/pnglibconf.h +++ b/src/3rdparty/libpng/pnglibconf.h @@ -1,10 +1,10 @@ -/* libpng 1.6.34 STANDARD API DEFINITION */ +/* libpng 1.6.35 STANDARD API DEFINITION */ /* pnglibconf.h - library build configuration */ -/* Libpng version 1.6.34 - September 29, 2017 */ +/* Libpng version 1.6.35 - July 15, 2018 */ -/* Copyright (c) 1998-2017 Glenn Randers-Pehrson */ +/* Copyright (c) 1998-2018 Glenn Randers-Pehrson */ /* This code is released under the libpng license. */ /* For conditions of distribution and use, see the disclaimer */ diff --git a/src/3rdparty/libpng/pngpread.c b/src/3rdparty/libpng/pngpread.c index fbe361dc34..c4ba51c4d4 100644 --- a/src/3rdparty/libpng/pngpread.c +++ b/src/3rdparty/libpng/pngpread.c @@ -1,8 +1,8 @@ /* pngpread.c - read a png file in push mode * - * Last changed in libpng 1.6.32 [August 24, 2017] - * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson + * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -34,7 +34,7 @@ if (png_ptr->buffer_size < N) \ void PNGAPI png_process_data(png_structrp png_ptr, png_inforp info_ptr, - png_bytep buffer, png_size_t buffer_size) + png_bytep buffer, size_t buffer_size) { if (png_ptr == NULL || info_ptr == NULL) return; @@ -47,7 +47,7 @@ png_process_data(png_structrp png_ptr, png_inforp info_ptr, } } -png_size_t PNGAPI +size_t PNGAPI png_process_data_pause(png_structrp png_ptr, int save) { if (png_ptr != NULL) @@ -60,7 +60,7 @@ png_process_data_pause(png_structrp png_ptr, int save) else { /* This includes any pending saved bytes: */ - png_size_t remaining = png_ptr->buffer_size; + size_t remaining = png_ptr->buffer_size; png_ptr->buffer_size = 0; /* So subtract the saved buffer size, unless all the data @@ -133,8 +133,8 @@ png_process_some_data(png_structrp png_ptr, png_inforp info_ptr) void /* PRIVATE */ png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr) { - png_size_t num_checked = png_ptr->sig_bytes, /* SAFE, does not exceed 8 */ - num_to_check = 8 - num_checked; + size_t num_checked = png_ptr->sig_bytes; /* SAFE, does not exceed 8 */ + size_t num_to_check = 8 - num_checked; if (png_ptr->buffer_size < num_to_check) { @@ -418,7 +418,7 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr) } void PNGCBAPI -png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length) +png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, size_t length) { png_bytep ptr; @@ -428,7 +428,7 @@ png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length) ptr = buffer; if (png_ptr->save_buffer_size != 0) { - png_size_t save_size; + size_t save_size; if (length < png_ptr->save_buffer_size) save_size = length; @@ -445,7 +445,7 @@ png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length) } if (length != 0 && png_ptr->current_buffer_size != 0) { - png_size_t save_size; + size_t save_size; if (length < png_ptr->current_buffer_size) save_size = length; @@ -467,7 +467,7 @@ png_push_save_buffer(png_structrp png_ptr) { if (png_ptr->save_buffer_ptr != png_ptr->save_buffer) { - png_size_t i, istop; + size_t i, istop; png_bytep sp; png_bytep dp; @@ -482,7 +482,7 @@ png_push_save_buffer(png_structrp png_ptr) if (png_ptr->save_buffer_size + png_ptr->current_buffer_size > png_ptr->save_buffer_max) { - png_size_t new_max; + size_t new_max; png_bytep old_buffer; if (png_ptr->save_buffer_size > PNG_SIZE_MAX - @@ -494,7 +494,7 @@ png_push_save_buffer(png_structrp png_ptr) new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256; old_buffer = png_ptr->save_buffer; png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr, - (png_size_t)new_max); + (size_t)new_max); if (png_ptr->save_buffer == NULL) { @@ -522,7 +522,7 @@ png_push_save_buffer(png_structrp png_ptr) void /* PRIVATE */ png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer, - png_size_t buffer_length) + size_t buffer_length) { png_ptr->current_buffer = buffer; png_ptr->current_buffer_size = buffer_length; @@ -562,7 +562,7 @@ png_push_read_IDAT(png_structrp png_ptr) if (png_ptr->idat_size != 0 && png_ptr->save_buffer_size != 0) { - png_size_t save_size = png_ptr->save_buffer_size; + size_t save_size = png_ptr->save_buffer_size; png_uint_32 idat_size = png_ptr->idat_size; /* We want the smaller of 'idat_size' and 'current_buffer_size', but they @@ -572,7 +572,7 @@ png_push_read_IDAT(png_structrp png_ptr) * will break on either 16-bit or 64-bit platforms. */ if (idat_size < save_size) - save_size = (png_size_t)idat_size; + save_size = (size_t)idat_size; else idat_size = (png_uint_32)save_size; @@ -589,7 +589,7 @@ png_push_read_IDAT(png_structrp png_ptr) if (png_ptr->idat_size != 0 && png_ptr->current_buffer_size != 0) { - png_size_t save_size = png_ptr->current_buffer_size; + size_t save_size = png_ptr->current_buffer_size; png_uint_32 idat_size = png_ptr->idat_size; /* We want the smaller of 'idat_size' and 'current_buffer_size', but they @@ -598,7 +598,7 @@ png_push_read_IDAT(png_structrp png_ptr) * larger - this cannot overflow. */ if (idat_size < save_size) - save_size = (png_size_t)idat_size; + save_size = (size_t)idat_size; else idat_size = (png_uint_32)save_size; @@ -625,7 +625,7 @@ png_push_read_IDAT(png_structrp png_ptr) void /* PRIVATE */ png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer, - png_size_t buffer_length) + size_t buffer_length) { /* The caller checks for a non-zero buffer length. */ if (!(buffer_length > 0) || buffer == NULL) diff --git a/src/3rdparty/libpng/pngpriv.h b/src/3rdparty/libpng/pngpriv.h index 922fe80c29..e43862a886 100644 --- a/src/3rdparty/libpng/pngpriv.h +++ b/src/3rdparty/libpng/pngpriv.h @@ -1,8 +1,8 @@ /* pngpriv.h - private declarations for use inside libpng * - * Last changed in libpng 1.6.32 [August 24, 2017] - * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson + * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -216,7 +216,11 @@ defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \ (defined(_M_IX86_FP) && _M_IX86_FP >= 2) # define PNG_INTEL_SSE_OPT 1 +# else +# define PNG_INTEL_SSE_OPT 0 # endif +# else +# define PNG_INTEL_SSE_OPT 0 # endif #endif @@ -240,6 +244,8 @@ # if PNG_INTEL_SSE_IMPLEMENTATION > 0 # define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_sse2 # endif +#else +# define PNG_INTEL_SSE_IMPLEMENTATION 0 #endif #if PNG_MIPS_MSA_OPT > 0 @@ -742,8 +748,8 @@ /* Added to libpng-1.2.6 JB */ #define PNG_ROWBYTES(pixel_bits, width) \ ((pixel_bits) >= 8 ? \ - ((png_size_t)(width) * (((png_size_t)(pixel_bits)) >> 3)) : \ - (( ((png_size_t)(width) * ((png_size_t)(pixel_bits))) + 7) >> 3) ) + ((size_t)(width) * (((size_t)(pixel_bits)) >> 3)) : \ + (( ((size_t)(width) * ((size_t)(pixel_bits))) + 7) >> 3) ) /* This returns the number of trailing bits in the last byte of a row, 0 if the * last byte is completely full of pixels. It is, in principle, (pixel_bits x @@ -931,7 +937,7 @@ * PNG files the -I directives must match. * * The most likely explanation is that you passed a -I in CFLAGS. This will - * not work; all the preprocessor directories and in particular all the -I + * not work; all the preprocessor directives and in particular all the -I * directives must be in CPPFLAGS. */ #endif @@ -1060,15 +1066,15 @@ PNG_INTERNAL_FUNCTION(void,png_zfree,(voidpf png_ptr, voidpf ptr),PNG_EMPTY); */ PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_read_data,(png_structp png_ptr, - png_bytep data, png_size_t length),PNG_EMPTY); + png_bytep data, size_t length),PNG_EMPTY); #ifdef PNG_PROGRESSIVE_READ_SUPPORTED PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_push_fill_buffer,(png_structp png_ptr, - png_bytep buffer, png_size_t length),PNG_EMPTY); + png_bytep buffer, size_t length),PNG_EMPTY); #endif PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_write_data,(png_structp png_ptr, - png_bytep data, png_size_t length),PNG_EMPTY); + png_bytep data, size_t length),PNG_EMPTY); #ifdef PNG_WRITE_FLUSH_SUPPORTED # ifdef PNG_STDIO_SUPPORTED @@ -1082,7 +1088,7 @@ PNG_INTERNAL_FUNCTION(void,png_reset_crc,(png_structrp png_ptr),PNG_EMPTY); /* Write the "data" buffer to whatever output you are using */ PNG_INTERNAL_FUNCTION(void,png_write_data,(png_structrp png_ptr, - png_const_bytep data, png_size_t length),PNG_EMPTY); + png_const_bytep data, size_t length),PNG_EMPTY); /* Read and check the PNG file signature */ PNG_INTERNAL_FUNCTION(void,png_read_sig,(png_structrp png_ptr, @@ -1094,7 +1100,7 @@ PNG_INTERNAL_FUNCTION(png_uint_32,png_read_chunk_header,(png_structrp png_ptr), /* Read data from whatever input you are using into the "data" buffer */ PNG_INTERNAL_FUNCTION(void,png_read_data,(png_structrp png_ptr, png_bytep data, - png_size_t length),PNG_EMPTY); + size_t length),PNG_EMPTY); /* Read bytes into buf, and update png_ptr->crc */ PNG_INTERNAL_FUNCTION(void,png_crc_read,(png_structrp png_ptr, png_bytep buf, @@ -1112,7 +1118,7 @@ PNG_INTERNAL_FUNCTION(int,png_crc_error,(png_structrp png_ptr),PNG_EMPTY); * since this is the maximum buffer size we can specify. */ PNG_INTERNAL_FUNCTION(void,png_calculate_crc,(png_structrp png_ptr, - png_const_bytep ptr, png_size_t length),PNG_EMPTY); + png_const_bytep ptr, size_t length),PNG_EMPTY); #ifdef PNG_WRITE_FLUSH_SUPPORTED PNG_INTERNAL_FUNCTION(void,png_flush,(png_structrp png_ptr),PNG_EMPTY); @@ -1195,7 +1201,7 @@ PNG_INTERNAL_FUNCTION(void,png_write_hIST,(png_structrp png_ptr, /* Chunks that have keywords */ #ifdef PNG_WRITE_tEXt_SUPPORTED PNG_INTERNAL_FUNCTION(void,png_write_tEXt,(png_structrp png_ptr, - png_const_charp key, png_const_charp text, png_size_t text_len),PNG_EMPTY); + png_const_charp key, png_const_charp text, size_t text_len),PNG_EMPTY); #endif #ifdef PNG_WRITE_zTXt_SUPPORTED @@ -1588,10 +1594,10 @@ PNG_INTERNAL_FUNCTION(void,png_push_check_crc,(png_structrp png_ptr),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_push_save_buffer,(png_structrp png_ptr), PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_push_restore_buffer,(png_structrp png_ptr, - png_bytep buffer, png_size_t buffer_length),PNG_EMPTY); + png_bytep buffer, size_t buffer_length),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_push_read_IDAT,(png_structrp png_ptr),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_process_IDAT_data,(png_structrp png_ptr, - png_bytep buffer, png_size_t buffer_length),PNG_EMPTY); + png_bytep buffer, size_t buffer_length),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_push_process_row,(png_structrp png_ptr), PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_push_handle_unknown,(png_structrp png_ptr, @@ -1861,13 +1867,13 @@ PNG_INTERNAL_FUNCTION(void,png_chunk_report,(png_const_structrp png_ptr, #ifdef PNG_FLOATING_POINT_SUPPORTED PNG_INTERNAL_FUNCTION(void,png_ascii_from_fp,(png_const_structrp png_ptr, - png_charp ascii, png_size_t size, double fp, unsigned int precision), + png_charp ascii, size_t size, double fp, unsigned int precision), PNG_EMPTY); #endif /* FLOATING_POINT */ #ifdef PNG_FIXED_POINT_SUPPORTED PNG_INTERNAL_FUNCTION(void,png_ascii_from_fixed,(png_const_structrp png_ptr, - png_charp ascii, png_size_t size, png_fixed_point fp),PNG_EMPTY); + png_charp ascii, size_t size, png_fixed_point fp),PNG_EMPTY); #endif /* FIXED_POINT */ #endif /* sCAL */ @@ -1960,7 +1966,7 @@ PNG_INTERNAL_FUNCTION(void,png_ascii_from_fixed,(png_const_structrp png_ptr, * the problem character.) This has not been tested within libpng. */ PNG_INTERNAL_FUNCTION(int,png_check_fp_number,(png_const_charp string, - png_size_t size, int *statep, png_size_tp whereami),PNG_EMPTY); + size_t size, int *statep, png_size_tp whereami),PNG_EMPTY); /* This is the same but it checks a complete string and returns true * only if it just contains a floating point number. As of 1.5.4 this @@ -1969,7 +1975,7 @@ PNG_INTERNAL_FUNCTION(int,png_check_fp_number,(png_const_charp string, * for negative or zero values using the sticky flag. */ PNG_INTERNAL_FUNCTION(int,png_check_fp_string,(png_const_charp string, - png_size_t size),PNG_EMPTY); + size_t size),PNG_EMPTY); #endif /* pCAL || sCAL */ #if defined(PNG_GAMMA_SUPPORTED) ||\ @@ -2044,7 +2050,7 @@ typedef struct png_control png_voidp error_buf; /* Always a jmp_buf at present. */ png_const_bytep memory; /* Memory buffer. */ - png_size_t size; /* Size of the memory buffer. */ + size_t size; /* Size of the memory buffer. */ unsigned int for_write :1; /* Otherwise it is a read structure */ unsigned int owned_file :1; /* We own the file in io_ptr */ diff --git a/src/3rdparty/libpng/pngread.c b/src/3rdparty/libpng/pngread.c index da32e9ad9c..bff7503ee3 100644 --- a/src/3rdparty/libpng/pngread.c +++ b/src/3rdparty/libpng/pngread.c @@ -1,8 +1,8 @@ /* pngread.c - read a PNG file * - * Last changed in libpng 1.6.33 [September 28, 2017] - * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson + * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -1532,7 +1532,7 @@ png_image_begin_read_from_file(png_imagep image, const char *file_name) #endif /* STDIO */ static void PNGCBAPI -png_image_memory_read(png_structp png_ptr, png_bytep out, png_size_t need) +png_image_memory_read(png_structp png_ptr, png_bytep out, size_t need) { if (png_ptr != NULL) { @@ -1543,7 +1543,7 @@ png_image_memory_read(png_structp png_ptr, png_bytep out, png_size_t need) if (cp != NULL) { png_const_bytep memory = cp->memory; - png_size_t size = cp->size; + size_t size = cp->size; if (memory != NULL && size >= need) { @@ -1562,7 +1562,7 @@ png_image_memory_read(png_structp png_ptr, png_bytep out, png_size_t need) } int PNGAPI png_image_begin_read_from_memory(png_imagep image, - png_const_voidp memory, png_size_t size) + png_const_voidp memory, size_t size) { if (image != NULL && image->version == PNG_IMAGE_VERSION) { @@ -4150,7 +4150,7 @@ png_image_finish_read(png_imagep image, png_const_colorp background, * * NOTE: this will be changed in 1.7 because PNG_IMAGE_BUFFER_SIZE * will be changed to use png_alloc_size_t; bigger images can be - * accomodated on 64-bit systems. + * accommodated on 64-bit systems. */ if (image->height <= 0xffffffffU/PNG_IMAGE_PIXEL_COMPONENT_SIZE(image->format)/check) diff --git a/src/3rdparty/libpng/pngrio.c b/src/3rdparty/libpng/pngrio.c index 7e26e855ca..372221483f 100644 --- a/src/3rdparty/libpng/pngrio.c +++ b/src/3rdparty/libpng/pngrio.c @@ -1,8 +1,8 @@ /* pngrio.c - functions for data input * - * Last changed in libpng 1.6.24 [August 4, 2016] - * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson + * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -29,7 +29,7 @@ * to read more than 64K on a 16-bit machine. */ void /* PRIVATE */ -png_read_data(png_structrp png_ptr, png_bytep data, png_size_t length) +png_read_data(png_structrp png_ptr, png_bytep data, size_t length) { png_debug1(4, "reading %d bytes", (int)length); @@ -47,14 +47,14 @@ png_read_data(png_structrp png_ptr, png_bytep data, png_size_t length) * than changing the library. */ void PNGCBAPI -png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +png_default_read_data(png_structp png_ptr, png_bytep data, size_t length) { - png_size_t check; + size_t check; if (png_ptr == NULL) return; - /* fread() returns 0 on error, so it is OK to store this in a png_size_t + /* fread() returns 0 on error, so it is OK to store this in a size_t * instead of an int, which is what fread() actually returns. */ check = fread(data, 1, length, png_voidcast(png_FILE_p, png_ptr->io_ptr)); diff --git a/src/3rdparty/libpng/pngrtran.c b/src/3rdparty/libpng/pngrtran.c index c189650313..67d1f249a6 100644 --- a/src/3rdparty/libpng/pngrtran.c +++ b/src/3rdparty/libpng/pngrtran.c @@ -1,8 +1,8 @@ /* pngrtran.c - transforms the data in a row for PNG readers * - * Last changed in libpng 1.6.33 [September 28, 2017] - * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson + * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -292,7 +292,7 @@ png_set_alpha_mode_fixed(png_structrp png_ptr, int mode, * who use the inverse of the gamma value accidentally! Since some of these * values are reasonable this may have to be changed: * - * 1.6.x: changed from 0.07..3 to 0.01..100 (to accomodate the optimal 16-bit + * 1.6.x: changed from 0.07..3 to 0.01..100 (to accommodate the optimal 16-bit * gamma of 36, and its reciprocal.) */ if (output_gamma < 1000 || output_gamma > 10000000) @@ -747,7 +747,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette, int num_red = (1 << PNG_QUANTIZE_RED_BITS); int num_green = (1 << PNG_QUANTIZE_GREEN_BITS); int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS); - png_size_t num_entries = ((png_size_t)1 << total_bits); + size_t num_entries = ((size_t)1 << total_bits); png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr, (png_alloc_size_t)(num_entries * (sizeof (png_byte)))); @@ -1317,7 +1317,7 @@ png_init_read_transformations(png_structrp png_ptr) else if (png_ptr->screen_gamma != 0) /* The converse - assume the file matches the screen, note that this - * perhaps undesireable default can (from 1.5.4) be changed by calling + * perhaps undesirable default can (from 1.5.4) be changed by calling * png_set_alpha_mode (even if the alpha handling mode isn't required * or isn't changed from the default.) */ @@ -1885,7 +1885,7 @@ png_init_read_transformations(png_structrp png_ptr) png_ptr->transformations &= ~PNG_SHIFT; - /* significant bits can be in the range 1 to 7 for a meaninful result, if + /* significant bits can be in the range 1 to 7 for a meaningful result, if * the number of significant bits is 0 then no shift is done (this is an * error condition which is silently ignored.) */ @@ -2151,8 +2151,8 @@ png_do_unpack(png_row_infop row_info, png_bytep row) { case 1: { - png_bytep sp = row + (png_size_t)((row_width - 1) >> 3); - png_bytep dp = row + (png_size_t)row_width - 1; + png_bytep sp = row + (size_t)((row_width - 1) >> 3); + png_bytep dp = row + (size_t)row_width - 1; png_uint_32 shift = 7U - ((row_width + 7U) & 0x07); for (i = 0; i < row_width; i++) { @@ -2175,8 +2175,8 @@ png_do_unpack(png_row_infop row_info, png_bytep row) case 2: { - png_bytep sp = row + (png_size_t)((row_width - 1) >> 2); - png_bytep dp = row + (png_size_t)row_width - 1; + png_bytep sp = row + (size_t)((row_width - 1) >> 2); + png_bytep dp = row + (size_t)row_width - 1; png_uint_32 shift = ((3U - ((row_width + 3U) & 0x03)) << 1); for (i = 0; i < row_width; i++) { @@ -2198,8 +2198,8 @@ png_do_unpack(png_row_infop row_info, png_bytep row) case 4: { - png_bytep sp = row + (png_size_t)((row_width - 1) >> 1); - png_bytep dp = row + (png_size_t)row_width - 1; + png_bytep sp = row + (size_t)((row_width - 1) >> 1); + png_bytep dp = row + (size_t)row_width - 1; png_uint_32 shift = ((1U - ((row_width + 1U) & 0x01)) << 2); for (i = 0; i < row_width; i++) { @@ -2463,95 +2463,94 @@ png_do_chop(png_row_infop row_info, png_bytep row) static void png_do_read_swap_alpha(png_row_infop row_info, png_bytep row) { + png_uint_32 row_width = row_info->width; + png_debug(1, "in png_do_read_swap_alpha"); + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { - png_uint_32 row_width = row_info->width; - if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + /* This converts from RGBA to ARGB */ + if (row_info->bit_depth == 8) { - /* This converts from RGBA to ARGB */ - if (row_info->bit_depth == 8) + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_byte save; + png_uint_32 i; + + for (i = 0; i < row_width; i++) { - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_byte save; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - save = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = save; - } + save = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = save; } - -#ifdef PNG_READ_16BIT_SUPPORTED - /* This converts from RRGGBBAA to AARRGGBB */ - else - { - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_byte save[2]; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - save[0] = *(--sp); - save[1] = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = save[0]; - *(--dp) = save[1]; - } - } -#endif } - else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) +#ifdef PNG_READ_16BIT_SUPPORTED + /* This converts from RRGGBBAA to AARRGGBB */ + else { - /* This converts from GA to AG */ - if (row_info->bit_depth == 8) - { - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_byte save; - png_uint_32 i; + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_byte save[2]; + png_uint_32 i; - for (i = 0; i < row_width; i++) - { - save = *(--sp); - *(--dp) = *(--sp); - *(--dp) = save; - } + for (i = 0; i < row_width; i++) + { + save[0] = *(--sp); + save[1] = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = save[0]; + *(--dp) = save[1]; } + } +#endif + } + + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + /* This converts from GA to AG */ + if (row_info->bit_depth == 8) + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_byte save; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + save = *(--sp); + *(--dp) = *(--sp); + *(--dp) = save; + } + } #ifdef PNG_READ_16BIT_SUPPORTED - /* This converts from GGAA to AAGG */ - else - { - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_byte save[2]; - png_uint_32 i; + /* This converts from GGAA to AAGG */ + else + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_byte save[2]; + png_uint_32 i; - for (i = 0; i < row_width; i++) - { - save[0] = *(--sp); - save[1] = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = save[0]; - *(--dp) = save[1]; - } + for (i = 0; i < row_width; i++) + { + save[0] = *(--sp); + save[1] = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = save[0]; + *(--dp) = save[1]; } -#endif } +#endif } } #endif @@ -2681,8 +2680,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, if ((flags & PNG_FLAG_FILLER_AFTER) != 0) { /* This changes the data from G to GX */ - png_bytep sp = row + (png_size_t)row_width; - png_bytep dp = sp + (png_size_t)row_width; + png_bytep sp = row + (size_t)row_width; + png_bytep dp = sp + (size_t)row_width; for (i = 1; i < row_width; i++) { *(--dp) = lo_filler; @@ -2697,8 +2696,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, else { /* This changes the data from G to XG */ - png_bytep sp = row + (png_size_t)row_width; - png_bytep dp = sp + (png_size_t)row_width; + png_bytep sp = row + (size_t)row_width; + png_bytep dp = sp + (size_t)row_width; for (i = 0; i < row_width; i++) { *(--dp) = *(--sp); @@ -2716,8 +2715,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, if ((flags & PNG_FLAG_FILLER_AFTER) != 0) { /* This changes the data from GG to GGXX */ - png_bytep sp = row + (png_size_t)row_width * 2; - png_bytep dp = sp + (png_size_t)row_width * 2; + png_bytep sp = row + (size_t)row_width * 2; + png_bytep dp = sp + (size_t)row_width * 2; for (i = 1; i < row_width; i++) { *(--dp) = lo_filler; @@ -2735,8 +2734,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, else { /* This changes the data from GG to XXGG */ - png_bytep sp = row + (png_size_t)row_width * 2; - png_bytep dp = sp + (png_size_t)row_width * 2; + png_bytep sp = row + (size_t)row_width * 2; + png_bytep dp = sp + (size_t)row_width * 2; for (i = 0; i < row_width; i++) { *(--dp) = *(--sp); @@ -2758,8 +2757,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, if ((flags & PNG_FLAG_FILLER_AFTER) != 0) { /* This changes the data from RGB to RGBX */ - png_bytep sp = row + (png_size_t)row_width * 3; - png_bytep dp = sp + (png_size_t)row_width; + png_bytep sp = row + (size_t)row_width * 3; + png_bytep dp = sp + (size_t)row_width; for (i = 1; i < row_width; i++) { *(--dp) = lo_filler; @@ -2776,8 +2775,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, else { /* This changes the data from RGB to XRGB */ - png_bytep sp = row + (png_size_t)row_width * 3; - png_bytep dp = sp + (png_size_t)row_width; + png_bytep sp = row + (size_t)row_width * 3; + png_bytep dp = sp + (size_t)row_width; for (i = 0; i < row_width; i++) { *(--dp) = *(--sp); @@ -2797,8 +2796,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, if ((flags & PNG_FLAG_FILLER_AFTER) != 0) { /* This changes the data from RRGGBB to RRGGBBXX */ - png_bytep sp = row + (png_size_t)row_width * 6; - png_bytep dp = sp + (png_size_t)row_width * 2; + png_bytep sp = row + (size_t)row_width * 6; + png_bytep dp = sp + (size_t)row_width * 2; for (i = 1; i < row_width; i++) { *(--dp) = lo_filler; @@ -2820,8 +2819,8 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, else { /* This changes the data from RRGGBB to XXRRGGBB */ - png_bytep sp = row + (png_size_t)row_width * 6; - png_bytep dp = sp + (png_size_t)row_width * 2; + png_bytep sp = row + (size_t)row_width * 6; + png_bytep dp = sp + (size_t)row_width * 2; for (i = 0; i < row_width; i++) { *(--dp) = *(--sp); @@ -2862,8 +2861,8 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) if (row_info->bit_depth == 8) { /* This changes G to RGB */ - png_bytep sp = row + (png_size_t)row_width - 1; - png_bytep dp = sp + (png_size_t)row_width * 2; + png_bytep sp = row + (size_t)row_width - 1; + png_bytep dp = sp + (size_t)row_width * 2; for (i = 0; i < row_width; i++) { *(dp--) = *sp; @@ -2875,8 +2874,8 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) else { /* This changes GG to RRGGBB */ - png_bytep sp = row + (png_size_t)row_width * 2 - 1; - png_bytep dp = sp + (png_size_t)row_width * 4; + png_bytep sp = row + (size_t)row_width * 2 - 1; + png_bytep dp = sp + (size_t)row_width * 4; for (i = 0; i < row_width; i++) { *(dp--) = *sp; @@ -2894,8 +2893,8 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) if (row_info->bit_depth == 8) { /* This changes GA to RGBA */ - png_bytep sp = row + (png_size_t)row_width * 2 - 1; - png_bytep dp = sp + (png_size_t)row_width * 2; + png_bytep sp = row + (size_t)row_width * 2 - 1; + png_bytep dp = sp + (size_t)row_width * 2; for (i = 0; i < row_width; i++) { *(dp--) = *(sp--); @@ -2908,8 +2907,8 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) else { /* This changes GGAA to RRGGBBAA */ - png_bytep sp = row + (png_size_t)row_width * 4 - 1; - png_bytep dp = sp + (png_size_t)row_width * 4; + png_bytep sp = row + (size_t)row_width * 4 - 1; + png_bytep dp = sp + (size_t)row_width * 4; for (i = 0; i < row_width; i++) { *(dp--) = *(sp--); @@ -2980,7 +2979,7 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) * values this results in an implicit assumption that the original PNG RGB * values were linear. * - * Other integer coefficents can be used via png_set_rgb_to_gray(). Because + * Other integer coefficients can be used via png_set_rgb_to_gray(). Because * the API takes just red and green coefficients the blue coefficient is * calculated to make the sum 32768. This will result in different rounding * to that used above. @@ -3209,419 +3208,229 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr) png_debug(1, "in png_do_compose"); + switch (row_info->color_type) { - switch (row_info->color_type) + case PNG_COLOR_TYPE_GRAY: { - case PNG_COLOR_TYPE_GRAY: + switch (row_info->bit_depth) { - switch (row_info->bit_depth) + case 1: { - case 1: + sp = row; + shift = 7; + for (i = 0; i < row_width; i++) { - sp = row; - shift = 7; - for (i = 0; i < row_width; i++) + if ((png_uint_16)((*sp >> shift) & 0x01) + == png_ptr->trans_color.gray) { - if ((png_uint_16)((*sp >> shift) & 0x01) - == png_ptr->trans_color.gray) - { - unsigned int tmp = *sp & (0x7f7f >> (7 - shift)); - tmp |= - (unsigned int)(png_ptr->background.gray << shift); - *sp = (png_byte)(tmp & 0xff); - } - - if (shift == 0) - { - shift = 7; - sp++; - } - - else - shift--; + unsigned int tmp = *sp & (0x7f7f >> (7 - shift)); + tmp |= + (unsigned int)(png_ptr->background.gray << shift); + *sp = (png_byte)(tmp & 0xff); } - break; - } - case 2: - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_table != NULL) + if (shift == 0) { - sp = row; - shift = 6; - for (i = 0; i < row_width; i++) - { - if ((png_uint_16)((*sp >> shift) & 0x03) - == png_ptr->trans_color.gray) - { - unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); - tmp |= - (unsigned int)png_ptr->background.gray << shift; - *sp = (png_byte)(tmp & 0xff); - } - - else - { - unsigned int p = (*sp >> shift) & 0x03; - unsigned int g = (gamma_table [p | (p << 2) | - (p << 4) | (p << 6)] >> 6) & 0x03; - unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); - tmp |= (unsigned int)(g << shift); - *sp = (png_byte)(tmp & 0xff); - } - - if (shift == 0) - { - shift = 6; - sp++; - } - - else - shift -= 2; - } + shift = 7; + sp++; } else -#endif - { - sp = row; - shift = 6; - for (i = 0; i < row_width; i++) - { - if ((png_uint_16)((*sp >> shift) & 0x03) - == png_ptr->trans_color.gray) - { - unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); - tmp |= - (unsigned int)png_ptr->background.gray << shift; - *sp = (png_byte)(tmp & 0xff); - } - - if (shift == 0) - { - shift = 6; - sp++; - } - - else - shift -= 2; - } - } - break; + shift--; } - - case 4: - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_table != NULL) - { - sp = row; - shift = 4; - for (i = 0; i < row_width; i++) - { - if ((png_uint_16)((*sp >> shift) & 0x0f) - == png_ptr->trans_color.gray) - { - unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); - tmp |= - (unsigned int)(png_ptr->background.gray << shift); - *sp = (png_byte)(tmp & 0xff); - } - - else - { - unsigned int p = (*sp >> shift) & 0x0f; - unsigned int g = (gamma_table[p | (p << 4)] >> 4) & - 0x0f; - unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); - tmp |= (unsigned int)(g << shift); - *sp = (png_byte)(tmp & 0xff); - } - - if (shift == 0) - { - shift = 4; - sp++; - } - - else - shift -= 4; - } - } - - else -#endif - { - sp = row; - shift = 4; - for (i = 0; i < row_width; i++) - { - if ((png_uint_16)((*sp >> shift) & 0x0f) - == png_ptr->trans_color.gray) - { - unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); - tmp |= - (unsigned int)(png_ptr->background.gray << shift); - *sp = (png_byte)(tmp & 0xff); - } - - if (shift == 0) - { - shift = 4; - sp++; - } - - else - shift -= 4; - } - } - break; - } - - case 8: - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_table != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp++) - { - if (*sp == png_ptr->trans_color.gray) - *sp = (png_byte)png_ptr->background.gray; - - else - *sp = gamma_table[*sp]; - } - } - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp++) - { - if (*sp == png_ptr->trans_color.gray) - *sp = (png_byte)png_ptr->background.gray; - } - } - break; - } - - case 16: - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_16 != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp += 2) - { - png_uint_16 v; - - v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - - if (v == png_ptr->trans_color.gray) - { - /* Background is already in screen gamma */ - *sp = (png_byte)((png_ptr->background.gray >> 8) - & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.gray - & 0xff); - } - - else - { - v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - } - } - } - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp += 2) - { - png_uint_16 v; - - v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - - if (v == png_ptr->trans_color.gray) - { - *sp = (png_byte)((png_ptr->background.gray >> 8) - & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.gray - & 0xff); - } - } - } - break; - } - - default: - break; + break; } - break; - } - case PNG_COLOR_TYPE_RGB: - { - if (row_info->bit_depth == 8) + case 2: { #ifdef PNG_READ_GAMMA_SUPPORTED if (gamma_table != NULL) { sp = row; - for (i = 0; i < row_width; i++, sp += 3) + shift = 6; + for (i = 0; i < row_width; i++) { - if (*sp == png_ptr->trans_color.red && - *(sp + 1) == png_ptr->trans_color.green && - *(sp + 2) == png_ptr->trans_color.blue) + if ((png_uint_16)((*sp >> shift) & 0x03) + == png_ptr->trans_color.gray) { - *sp = (png_byte)png_ptr->background.red; - *(sp + 1) = (png_byte)png_ptr->background.green; - *(sp + 2) = (png_byte)png_ptr->background.blue; + unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); + tmp |= + (unsigned int)png_ptr->background.gray << shift; + *sp = (png_byte)(tmp & 0xff); } else { - *sp = gamma_table[*sp]; - *(sp + 1) = gamma_table[*(sp + 1)]; - *(sp + 2) = gamma_table[*(sp + 2)]; + unsigned int p = (*sp >> shift) & 0x03; + unsigned int g = (gamma_table [p | (p << 2) | + (p << 4) | (p << 6)] >> 6) & 0x03; + unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); + tmp |= (unsigned int)(g << shift); + *sp = (png_byte)(tmp & 0xff); } + + if (shift == 0) + { + shift = 6; + sp++; + } + + else + shift -= 2; + } + } + + else +#endif + { + sp = row; + shift = 6; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> shift) & 0x03) + == png_ptr->trans_color.gray) + { + unsigned int tmp = *sp & (0x3f3f >> (6 - shift)); + tmp |= + (unsigned int)png_ptr->background.gray << shift; + *sp = (png_byte)(tmp & 0xff); + } + + if (shift == 0) + { + shift = 6; + sp++; + } + + else + shift -= 2; + } + } + break; + } + + case 4: + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_table != NULL) + { + sp = row; + shift = 4; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> shift) & 0x0f) + == png_ptr->trans_color.gray) + { + unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); + tmp |= + (unsigned int)(png_ptr->background.gray << shift); + *sp = (png_byte)(tmp & 0xff); + } + + else + { + unsigned int p = (*sp >> shift) & 0x0f; + unsigned int g = (gamma_table[p | (p << 4)] >> 4) & + 0x0f; + unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); + tmp |= (unsigned int)(g << shift); + *sp = (png_byte)(tmp & 0xff); + } + + if (shift == 0) + { + shift = 4; + sp++; + } + + else + shift -= 4; + } + } + + else +#endif + { + sp = row; + shift = 4; + for (i = 0; i < row_width; i++) + { + if ((png_uint_16)((*sp >> shift) & 0x0f) + == png_ptr->trans_color.gray) + { + unsigned int tmp = *sp & (0x0f0f >> (4 - shift)); + tmp |= + (unsigned int)(png_ptr->background.gray << shift); + *sp = (png_byte)(tmp & 0xff); + } + + if (shift == 0) + { + shift = 4; + sp++; + } + + else + shift -= 4; + } + } + break; + } + + case 8: + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_table != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp++) + { + if (*sp == png_ptr->trans_color.gray) + *sp = (png_byte)png_ptr->background.gray; + + else + *sp = gamma_table[*sp]; } } else #endif { sp = row; - for (i = 0; i < row_width; i++, sp += 3) + for (i = 0; i < row_width; i++, sp++) { - if (*sp == png_ptr->trans_color.red && - *(sp + 1) == png_ptr->trans_color.green && - *(sp + 2) == png_ptr->trans_color.blue) - { - *sp = (png_byte)png_ptr->background.red; - *(sp + 1) = (png_byte)png_ptr->background.green; - *(sp + 2) = (png_byte)png_ptr->background.blue; - } + if (*sp == png_ptr->trans_color.gray) + *sp = (png_byte)png_ptr->background.gray; } } + break; } - else /* if (row_info->bit_depth == 16) */ + + case 16: { #ifdef PNG_READ_GAMMA_SUPPORTED if (gamma_16 != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp += 6) - { - png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - - png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) - + *(sp + 3)); - - png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) - + *(sp + 5)); - - if (r == png_ptr->trans_color.red && - g == png_ptr->trans_color.green && - b == png_ptr->trans_color.blue) - { - /* Background is already in screen gamma */ - *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); - *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) - & 0xff); - *(sp + 3) = (png_byte)(png_ptr->background.green - & 0xff); - *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) - & 0xff); - *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); - } - - else - { - png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - - v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; - *(sp + 2) = (png_byte)((v >> 8) & 0xff); - *(sp + 3) = (png_byte)(v & 0xff); - - v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; - *(sp + 4) = (png_byte)((v >> 8) & 0xff); - *(sp + 5) = (png_byte)(v & 0xff); - } - } - } - - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp += 6) - { - png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - - png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) - + *(sp + 3)); - - png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) - + *(sp + 5)); - - if (r == png_ptr->trans_color.red && - g == png_ptr->trans_color.green && - b == png_ptr->trans_color.blue) - { - *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); - *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) - & 0xff); - *(sp + 3) = (png_byte)(png_ptr->background.green - & 0xff); - *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) - & 0xff); - *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); - } - } - } - } - break; - } - - case PNG_COLOR_TYPE_GRAY_ALPHA: - { - if (row_info->bit_depth == 8) - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_to_1 != NULL && gamma_from_1 != NULL && - gamma_table != NULL) { sp = row; for (i = 0; i < row_width; i++, sp += 2) { - png_uint_16 a = *(sp + 1); + png_uint_16 v; - if (a == 0xff) - *sp = gamma_table[*sp]; + v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - else if (a == 0) + if (v == png_ptr->trans_color.gray) { /* Background is already in screen gamma */ - *sp = (png_byte)png_ptr->background.gray; + *sp = (png_byte)((png_ptr->background.gray >> 8) + & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.gray + & 0xff); } else { - png_byte v, w; - - v = gamma_to_1[*sp]; - png_composite(w, v, a, png_ptr->background_1.gray); - if (optimize == 0) - w = gamma_from_1[w]; - *sp = w; + v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); } } } @@ -3631,298 +3440,486 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr) sp = row; for (i = 0; i < row_width; i++, sp += 2) { - png_byte a = *(sp + 1); + png_uint_16 v; - if (a == 0) - *sp = (png_byte)png_ptr->background.gray; + v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - else if (a < 0xff) - png_composite(*sp, *sp, a, png_ptr->background.gray); - } - } - } - else /* if (png_ptr->bit_depth == 16) */ - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_16 != NULL && gamma_16_from_1 != NULL && - gamma_16_to_1 != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp += 4) - { - png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8) - + *(sp + 3)); - - if (a == (png_uint_16)0xffff) - { - png_uint_16 v; - - v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - } - - else if (a == 0) - { - /* Background is already in screen gamma */ - *sp = (png_byte)((png_ptr->background.gray >> 8) - & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); - } - - else - { - png_uint_16 g, v, w; - - g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; - png_composite_16(v, g, a, png_ptr->background_1.gray); - if (optimize != 0) - w = v; - else - w = gamma_16_from_1[(v & 0xff) >> - gamma_shift][v >> 8]; - *sp = (png_byte)((w >> 8) & 0xff); - *(sp + 1) = (png_byte)(w & 0xff); - } - } - } - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp += 4) - { - png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8) - + *(sp + 3)); - - if (a == 0) + if (v == png_ptr->trans_color.gray) { *sp = (png_byte)((png_ptr->background.gray >> 8) - & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); - } - - else if (a < 0xffff) - { - png_uint_16 g, v; - - g = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - png_composite_16(v, g, a, png_ptr->background.gray); - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); + & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.gray + & 0xff); } } } + break; } - break; + + default: + break; } - - case PNG_COLOR_TYPE_RGB_ALPHA: - { - if (row_info->bit_depth == 8) - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_to_1 != NULL && gamma_from_1 != NULL && - gamma_table != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp += 4) - { - png_byte a = *(sp + 3); - - if (a == 0xff) - { - *sp = gamma_table[*sp]; - *(sp + 1) = gamma_table[*(sp + 1)]; - *(sp + 2) = gamma_table[*(sp + 2)]; - } - - else if (a == 0) - { - /* Background is already in screen gamma */ - *sp = (png_byte)png_ptr->background.red; - *(sp + 1) = (png_byte)png_ptr->background.green; - *(sp + 2) = (png_byte)png_ptr->background.blue; - } - - else - { - png_byte v, w; - - v = gamma_to_1[*sp]; - png_composite(w, v, a, png_ptr->background_1.red); - if (optimize == 0) w = gamma_from_1[w]; - *sp = w; - - v = gamma_to_1[*(sp + 1)]; - png_composite(w, v, a, png_ptr->background_1.green); - if (optimize == 0) w = gamma_from_1[w]; - *(sp + 1) = w; - - v = gamma_to_1[*(sp + 2)]; - png_composite(w, v, a, png_ptr->background_1.blue); - if (optimize == 0) w = gamma_from_1[w]; - *(sp + 2) = w; - } - } - } - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp += 4) - { - png_byte a = *(sp + 3); - - if (a == 0) - { - *sp = (png_byte)png_ptr->background.red; - *(sp + 1) = (png_byte)png_ptr->background.green; - *(sp + 2) = (png_byte)png_ptr->background.blue; - } - - else if (a < 0xff) - { - png_composite(*sp, *sp, a, png_ptr->background.red); - - png_composite(*(sp + 1), *(sp + 1), a, - png_ptr->background.green); - - png_composite(*(sp + 2), *(sp + 2), a, - png_ptr->background.blue); - } - } - } - } - else /* if (row_info->bit_depth == 16) */ - { -#ifdef PNG_READ_GAMMA_SUPPORTED - if (gamma_16 != NULL && gamma_16_from_1 != NULL && - gamma_16_to_1 != NULL) - { - sp = row; - for (i = 0; i < row_width; i++, sp += 8) - { - png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) - << 8) + (png_uint_16)(*(sp + 7))); - - if (a == (png_uint_16)0xffff) - { - png_uint_16 v; - - v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - - v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; - *(sp + 2) = (png_byte)((v >> 8) & 0xff); - *(sp + 3) = (png_byte)(v & 0xff); - - v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; - *(sp + 4) = (png_byte)((v >> 8) & 0xff); - *(sp + 5) = (png_byte)(v & 0xff); - } - - else if (a == 0) - { - /* Background is already in screen gamma */ - *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); - *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) - & 0xff); - *(sp + 3) = (png_byte)(png_ptr->background.green - & 0xff); - *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) - & 0xff); - *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); - } - - else - { - png_uint_16 v, w; - - v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; - png_composite_16(w, v, a, png_ptr->background_1.red); - if (optimize == 0) - w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >> - 8]; - *sp = (png_byte)((w >> 8) & 0xff); - *(sp + 1) = (png_byte)(w & 0xff); - - v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)]; - png_composite_16(w, v, a, png_ptr->background_1.green); - if (optimize == 0) - w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >> - 8]; - - *(sp + 2) = (png_byte)((w >> 8) & 0xff); - *(sp + 3) = (png_byte)(w & 0xff); - - v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)]; - png_composite_16(w, v, a, png_ptr->background_1.blue); - if (optimize == 0) - w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >> - 8]; - - *(sp + 4) = (png_byte)((w >> 8) & 0xff); - *(sp + 5) = (png_byte)(w & 0xff); - } - } - } - - else -#endif - { - sp = row; - for (i = 0; i < row_width; i++, sp += 8) - { - png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) - << 8) + (png_uint_16)(*(sp + 7))); - - if (a == 0) - { - *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); - *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); - *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) - & 0xff); - *(sp + 3) = (png_byte)(png_ptr->background.green - & 0xff); - *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) - & 0xff); - *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); - } - - else if (a < 0xffff) - { - png_uint_16 v; - - png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) - + *(sp + 3)); - png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) - + *(sp + 5)); - - png_composite_16(v, r, a, png_ptr->background.red); - *sp = (png_byte)((v >> 8) & 0xff); - *(sp + 1) = (png_byte)(v & 0xff); - - png_composite_16(v, g, a, png_ptr->background.green); - *(sp + 2) = (png_byte)((v >> 8) & 0xff); - *(sp + 3) = (png_byte)(v & 0xff); - - png_composite_16(v, b, a, png_ptr->background.blue); - *(sp + 4) = (png_byte)((v >> 8) & 0xff); - *(sp + 5) = (png_byte)(v & 0xff); - } - } - } - } - break; - } - - default: - break; + break; } + + case PNG_COLOR_TYPE_RGB: + { + if (row_info->bit_depth == 8) + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_table != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 3) + { + if (*sp == png_ptr->trans_color.red && + *(sp + 1) == png_ptr->trans_color.green && + *(sp + 2) == png_ptr->trans_color.blue) + { + *sp = (png_byte)png_ptr->background.red; + *(sp + 1) = (png_byte)png_ptr->background.green; + *(sp + 2) = (png_byte)png_ptr->background.blue; + } + + else + { + *sp = gamma_table[*sp]; + *(sp + 1) = gamma_table[*(sp + 1)]; + *(sp + 2) = gamma_table[*(sp + 2)]; + } + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 3) + { + if (*sp == png_ptr->trans_color.red && + *(sp + 1) == png_ptr->trans_color.green && + *(sp + 2) == png_ptr->trans_color.blue) + { + *sp = (png_byte)png_ptr->background.red; + *(sp + 1) = (png_byte)png_ptr->background.green; + *(sp + 2) = (png_byte)png_ptr->background.blue; + } + } + } + } + else /* if (row_info->bit_depth == 16) */ + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_16 != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 6) + { + png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + + png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) + + *(sp + 3)); + + png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) + + *(sp + 5)); + + if (r == png_ptr->trans_color.red && + g == png_ptr->trans_color.green && + b == png_ptr->trans_color.blue) + { + /* Background is already in screen gamma */ + *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); + *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) + & 0xff); + *(sp + 3) = (png_byte)(png_ptr->background.green + & 0xff); + *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) + & 0xff); + *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); + } + + else + { + png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + + v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; + *(sp + 2) = (png_byte)((v >> 8) & 0xff); + *(sp + 3) = (png_byte)(v & 0xff); + + v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; + *(sp + 4) = (png_byte)((v >> 8) & 0xff); + *(sp + 5) = (png_byte)(v & 0xff); + } + } + } + + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 6) + { + png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + + png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) + + *(sp + 3)); + + png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) + + *(sp + 5)); + + if (r == png_ptr->trans_color.red && + g == png_ptr->trans_color.green && + b == png_ptr->trans_color.blue) + { + *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); + *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) + & 0xff); + *(sp + 3) = (png_byte)(png_ptr->background.green + & 0xff); + *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) + & 0xff); + *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); + } + } + } + } + break; + } + + case PNG_COLOR_TYPE_GRAY_ALPHA: + { + if (row_info->bit_depth == 8) + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_to_1 != NULL && gamma_from_1 != NULL && + gamma_table != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 2) + { + png_uint_16 a = *(sp + 1); + + if (a == 0xff) + *sp = gamma_table[*sp]; + + else if (a == 0) + { + /* Background is already in screen gamma */ + *sp = (png_byte)png_ptr->background.gray; + } + + else + { + png_byte v, w; + + v = gamma_to_1[*sp]; + png_composite(w, v, a, png_ptr->background_1.gray); + if (optimize == 0) + w = gamma_from_1[w]; + *sp = w; + } + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 2) + { + png_byte a = *(sp + 1); + + if (a == 0) + *sp = (png_byte)png_ptr->background.gray; + + else if (a < 0xff) + png_composite(*sp, *sp, a, png_ptr->background.gray); + } + } + } + else /* if (png_ptr->bit_depth == 16) */ + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_16 != NULL && gamma_16_from_1 != NULL && + gamma_16_to_1 != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 4) + { + png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8) + + *(sp + 3)); + + if (a == (png_uint_16)0xffff) + { + png_uint_16 v; + + v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + } + + else if (a == 0) + { + /* Background is already in screen gamma */ + *sp = (png_byte)((png_ptr->background.gray >> 8) + & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); + } + + else + { + png_uint_16 g, v, w; + + g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; + png_composite_16(v, g, a, png_ptr->background_1.gray); + if (optimize != 0) + w = v; + else + w = gamma_16_from_1[(v & 0xff) >> + gamma_shift][v >> 8]; + *sp = (png_byte)((w >> 8) & 0xff); + *(sp + 1) = (png_byte)(w & 0xff); + } + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 4) + { + png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8) + + *(sp + 3)); + + if (a == 0) + { + *sp = (png_byte)((png_ptr->background.gray >> 8) + & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff); + } + + else if (a < 0xffff) + { + png_uint_16 g, v; + + g = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + png_composite_16(v, g, a, png_ptr->background.gray); + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + } + } + } + } + break; + } + + case PNG_COLOR_TYPE_RGB_ALPHA: + { + if (row_info->bit_depth == 8) + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_to_1 != NULL && gamma_from_1 != NULL && + gamma_table != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 4) + { + png_byte a = *(sp + 3); + + if (a == 0xff) + { + *sp = gamma_table[*sp]; + *(sp + 1) = gamma_table[*(sp + 1)]; + *(sp + 2) = gamma_table[*(sp + 2)]; + } + + else if (a == 0) + { + /* Background is already in screen gamma */ + *sp = (png_byte)png_ptr->background.red; + *(sp + 1) = (png_byte)png_ptr->background.green; + *(sp + 2) = (png_byte)png_ptr->background.blue; + } + + else + { + png_byte v, w; + + v = gamma_to_1[*sp]; + png_composite(w, v, a, png_ptr->background_1.red); + if (optimize == 0) w = gamma_from_1[w]; + *sp = w; + + v = gamma_to_1[*(sp + 1)]; + png_composite(w, v, a, png_ptr->background_1.green); + if (optimize == 0) w = gamma_from_1[w]; + *(sp + 1) = w; + + v = gamma_to_1[*(sp + 2)]; + png_composite(w, v, a, png_ptr->background_1.blue); + if (optimize == 0) w = gamma_from_1[w]; + *(sp + 2) = w; + } + } + } + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 4) + { + png_byte a = *(sp + 3); + + if (a == 0) + { + *sp = (png_byte)png_ptr->background.red; + *(sp + 1) = (png_byte)png_ptr->background.green; + *(sp + 2) = (png_byte)png_ptr->background.blue; + } + + else if (a < 0xff) + { + png_composite(*sp, *sp, a, png_ptr->background.red); + + png_composite(*(sp + 1), *(sp + 1), a, + png_ptr->background.green); + + png_composite(*(sp + 2), *(sp + 2), a, + png_ptr->background.blue); + } + } + } + } + else /* if (row_info->bit_depth == 16) */ + { +#ifdef PNG_READ_GAMMA_SUPPORTED + if (gamma_16 != NULL && gamma_16_from_1 != NULL && + gamma_16_to_1 != NULL) + { + sp = row; + for (i = 0; i < row_width; i++, sp += 8) + { + png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) + << 8) + (png_uint_16)(*(sp + 7))); + + if (a == (png_uint_16)0xffff) + { + png_uint_16 v; + + v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + + v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; + *(sp + 2) = (png_byte)((v >> 8) & 0xff); + *(sp + 3) = (png_byte)(v & 0xff); + + v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; + *(sp + 4) = (png_byte)((v >> 8) & 0xff); + *(sp + 5) = (png_byte)(v & 0xff); + } + + else if (a == 0) + { + /* Background is already in screen gamma */ + *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); + *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) + & 0xff); + *(sp + 3) = (png_byte)(png_ptr->background.green + & 0xff); + *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) + & 0xff); + *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); + } + + else + { + png_uint_16 v, w; + + v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; + png_composite_16(w, v, a, png_ptr->background_1.red); + if (optimize == 0) + w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >> + 8]; + *sp = (png_byte)((w >> 8) & 0xff); + *(sp + 1) = (png_byte)(w & 0xff); + + v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)]; + png_composite_16(w, v, a, png_ptr->background_1.green); + if (optimize == 0) + w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >> + 8]; + + *(sp + 2) = (png_byte)((w >> 8) & 0xff); + *(sp + 3) = (png_byte)(w & 0xff); + + v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)]; + png_composite_16(w, v, a, png_ptr->background_1.blue); + if (optimize == 0) + w = gamma_16_from_1[((w & 0xff) >> gamma_shift)][w >> + 8]; + + *(sp + 4) = (png_byte)((w >> 8) & 0xff); + *(sp + 5) = (png_byte)(w & 0xff); + } + } + } + + else +#endif + { + sp = row; + for (i = 0; i < row_width; i++, sp += 8) + { + png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) + << 8) + (png_uint_16)(*(sp + 7))); + + if (a == 0) + { + *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff); + *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff); + *(sp + 2) = (png_byte)((png_ptr->background.green >> 8) + & 0xff); + *(sp + 3) = (png_byte)(png_ptr->background.green + & 0xff); + *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8) + & 0xff); + *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff); + } + + else if (a < 0xffff) + { + png_uint_16 v; + + png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) + + *(sp + 3)); + png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) + + *(sp + 5)); + + png_composite_16(v, r, a, png_ptr->background.red); + *sp = (png_byte)((v >> 8) & 0xff); + *(sp + 1) = (png_byte)(v & 0xff); + + png_composite_16(v, g, a, png_ptr->background.green); + *(sp + 2) = (png_byte)((v >> 8) & 0xff); + *(sp + 3) = (png_byte)(v & 0xff); + + png_composite_16(v, b, a, png_ptr->background.blue); + *(sp + 4) = (png_byte)((v >> 8) & 0xff); + *(sp + 5) = (png_byte)(v & 0xff); + } + } + } + } + break; + } + + default: + break; } } #endif /* READ_BACKGROUND || READ_ALPHA_MODE */ @@ -4220,8 +4217,8 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, { case 1: { - sp = row + (png_size_t)((row_width - 1) >> 3); - dp = row + (png_size_t)row_width - 1; + sp = row + (size_t)((row_width - 1) >> 3); + dp = row + (size_t)row_width - 1; shift = 7 - (int)((row_width + 7) & 0x07); for (i = 0; i < row_width; i++) { @@ -4247,8 +4244,8 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, case 2: { - sp = row + (png_size_t)((row_width - 1) >> 2); - dp = row + (png_size_t)row_width - 1; + sp = row + (size_t)((row_width - 1) >> 2); + dp = row + (size_t)row_width - 1; shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); for (i = 0; i < row_width; i++) { @@ -4270,8 +4267,8 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, case 4: { - sp = row + (png_size_t)((row_width - 1) >> 1); - dp = row + (png_size_t)row_width - 1; + sp = row + (size_t)((row_width - 1) >> 1); + dp = row + (size_t)row_width - 1; shift = (int)((row_width & 0x01) << 2); for (i = 0; i < row_width; i++) { @@ -4304,8 +4301,8 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, { if (num_trans > 0) { - sp = row + (png_size_t)row_width - 1; - dp = row + ((png_size_t)row_width << 2) - 1; + sp = row + (size_t)row_width - 1; + dp = row + ((size_t)row_width << 2) - 1; for (i = 0; i < row_width; i++) { @@ -4329,8 +4326,8 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, else { - sp = row + (png_size_t)row_width - 1; - dp = row + (png_size_t)(row_width * 3) - 1; + sp = row + (size_t)row_width - 1; + dp = row + (size_t)(row_width * 3) - 1; for (i = 0; i < row_width; i++) { @@ -4365,195 +4362,130 @@ png_do_expand(png_row_infop row_info, png_bytep row, png_debug(1, "in png_do_expand"); + if (row_info->color_type == PNG_COLOR_TYPE_GRAY) { - if (row_info->color_type == PNG_COLOR_TYPE_GRAY) + unsigned int gray = trans_color != NULL ? trans_color->gray : 0; + + if (row_info->bit_depth < 8) { - unsigned int gray = trans_color != NULL ? trans_color->gray : 0; - - if (row_info->bit_depth < 8) + switch (row_info->bit_depth) { - switch (row_info->bit_depth) + case 1: { - case 1: - { - gray = (gray & 0x01) * 0xff; - sp = row + (png_size_t)((row_width - 1) >> 3); - dp = row + (png_size_t)row_width - 1; - shift = 7 - (int)((row_width + 7) & 0x07); - for (i = 0; i < row_width; i++) - { - if ((*sp >> shift) & 0x01) - *dp = 0xff; - - else - *dp = 0; - - if (shift == 7) - { - shift = 0; - sp--; - } - - else - shift++; - - dp--; - } - break; - } - - case 2: - { - gray = (gray & 0x03) * 0x55; - sp = row + (png_size_t)((row_width - 1) >> 2); - dp = row + (png_size_t)row_width - 1; - shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); - for (i = 0; i < row_width; i++) - { - value = (*sp >> shift) & 0x03; - *dp = (png_byte)(value | (value << 2) | (value << 4) | - (value << 6)); - if (shift == 6) - { - shift = 0; - sp--; - } - - else - shift += 2; - - dp--; - } - break; - } - - case 4: - { - gray = (gray & 0x0f) * 0x11; - sp = row + (png_size_t)((row_width - 1) >> 1); - dp = row + (png_size_t)row_width - 1; - shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); - for (i = 0; i < row_width; i++) - { - value = (*sp >> shift) & 0x0f; - *dp = (png_byte)(value | (value << 4)); - if (shift == 4) - { - shift = 0; - sp--; - } - - else - shift = 4; - - dp--; - } - break; - } - - default: - break; - } - - row_info->bit_depth = 8; - row_info->pixel_depth = 8; - row_info->rowbytes = row_width; - } - - if (trans_color != NULL) - { - if (row_info->bit_depth == 8) - { - gray = gray & 0xff; - sp = row + (png_size_t)row_width - 1; - dp = row + ((png_size_t)row_width << 1) - 1; - + gray = (gray & 0x01) * 0xff; + sp = row + (size_t)((row_width - 1) >> 3); + dp = row + (size_t)row_width - 1; + shift = 7 - (int)((row_width + 7) & 0x07); for (i = 0; i < row_width; i++) { - if ((*sp & 0xffU) == gray) - *dp-- = 0; + if ((*sp >> shift) & 0x01) + *dp = 0xff; else - *dp-- = 0xff; + *dp = 0; - *dp-- = *sp--; - } - } - - else if (row_info->bit_depth == 16) - { - unsigned int gray_high = (gray >> 8) & 0xff; - unsigned int gray_low = gray & 0xff; - sp = row + row_info->rowbytes - 1; - dp = row + (row_info->rowbytes << 1) - 1; - for (i = 0; i < row_width; i++) - { - if ((*(sp - 1) & 0xffU) == gray_high && - (*(sp) & 0xffU) == gray_low) + if (shift == 7) { - *dp-- = 0; - *dp-- = 0; + shift = 0; + sp--; } else - { - *dp-- = 0xff; - *dp-- = 0xff; - } + shift++; - *dp-- = *sp--; - *dp-- = *sp--; + dp--; } + break; } - row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA; - row_info->channels = 2; - row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1); - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, - row_width); + case 2: + { + gray = (gray & 0x03) * 0x55; + sp = row + (size_t)((row_width - 1) >> 2); + dp = row + (size_t)row_width - 1; + shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); + for (i = 0; i < row_width; i++) + { + value = (*sp >> shift) & 0x03; + *dp = (png_byte)(value | (value << 2) | (value << 4) | + (value << 6)); + if (shift == 6) + { + shift = 0; + sp--; + } + + else + shift += 2; + + dp--; + } + break; + } + + case 4: + { + gray = (gray & 0x0f) * 0x11; + sp = row + (size_t)((row_width - 1) >> 1); + dp = row + (size_t)row_width - 1; + shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); + for (i = 0; i < row_width; i++) + { + value = (*sp >> shift) & 0x0f; + *dp = (png_byte)(value | (value << 4)); + if (shift == 4) + { + shift = 0; + sp--; + } + + else + shift = 4; + + dp--; + } + break; + } + + default: + break; } + + row_info->bit_depth = 8; + row_info->pixel_depth = 8; + row_info->rowbytes = row_width; } - else if (row_info->color_type == PNG_COLOR_TYPE_RGB && - trans_color != NULL) + + if (trans_color != NULL) { if (row_info->bit_depth == 8) { - png_byte red = (png_byte)(trans_color->red & 0xff); - png_byte green = (png_byte)(trans_color->green & 0xff); - png_byte blue = (png_byte)(trans_color->blue & 0xff); - sp = row + (png_size_t)row_info->rowbytes - 1; - dp = row + ((png_size_t)row_width << 2) - 1; + gray = gray & 0xff; + sp = row + (size_t)row_width - 1; + dp = row + ((size_t)row_width << 1) - 1; + for (i = 0; i < row_width; i++) { - if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue) + if ((*sp & 0xffU) == gray) *dp-- = 0; else *dp-- = 0xff; *dp-- = *sp--; - *dp-- = *sp--; - *dp-- = *sp--; } } + else if (row_info->bit_depth == 16) { - png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff); - png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff); - png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff); - png_byte red_low = (png_byte)(trans_color->red & 0xff); - png_byte green_low = (png_byte)(trans_color->green & 0xff); - png_byte blue_low = (png_byte)(trans_color->blue & 0xff); + unsigned int gray_high = (gray >> 8) & 0xff; + unsigned int gray_low = gray & 0xff; sp = row + row_info->rowbytes - 1; - dp = row + ((png_size_t)row_width << 3) - 1; + dp = row + (row_info->rowbytes << 1) - 1; for (i = 0; i < row_width; i++) { - if (*(sp - 5) == red_high && - *(sp - 4) == red_low && - *(sp - 3) == green_high && - *(sp - 2) == green_low && - *(sp - 1) == blue_high && - *(sp ) == blue_low) + if ((*(sp - 1) & 0xffU) == gray_high && + (*(sp) & 0xffU) == gray_low) { *dp-- = 0; *dp-- = 0; @@ -4567,18 +4499,81 @@ png_do_expand(png_row_infop row_info, png_bytep row, *dp-- = *sp--; *dp-- = *sp--; - *dp-- = *sp--; - *dp-- = *sp--; - *dp-- = *sp--; - *dp-- = *sp--; } } - row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA; - row_info->channels = 4; - row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2); - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); + + row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA; + row_info->channels = 2; + row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, + row_width); } } + else if (row_info->color_type == PNG_COLOR_TYPE_RGB && + trans_color != NULL) + { + if (row_info->bit_depth == 8) + { + png_byte red = (png_byte)(trans_color->red & 0xff); + png_byte green = (png_byte)(trans_color->green & 0xff); + png_byte blue = (png_byte)(trans_color->blue & 0xff); + sp = row + (size_t)row_info->rowbytes - 1; + dp = row + ((size_t)row_width << 2) - 1; + for (i = 0; i < row_width; i++) + { + if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue) + *dp-- = 0; + + else + *dp-- = 0xff; + + *dp-- = *sp--; + *dp-- = *sp--; + *dp-- = *sp--; + } + } + else if (row_info->bit_depth == 16) + { + png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff); + png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff); + png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff); + png_byte red_low = (png_byte)(trans_color->red & 0xff); + png_byte green_low = (png_byte)(trans_color->green & 0xff); + png_byte blue_low = (png_byte)(trans_color->blue & 0xff); + sp = row + row_info->rowbytes - 1; + dp = row + ((size_t)row_width << 3) - 1; + for (i = 0; i < row_width; i++) + { + if (*(sp - 5) == red_high && + *(sp - 4) == red_low && + *(sp - 3) == green_high && + *(sp - 2) == green_low && + *(sp - 1) == blue_high && + *(sp ) == blue_low) + { + *dp-- = 0; + *dp-- = 0; + } + + else + { + *dp-- = 0xff; + *dp-- = 0xff; + } + + *dp-- = *sp--; + *dp-- = *sp--; + *dp-- = *sp--; + *dp-- = *sp--; + *dp-- = *sp--; + *dp-- = *sp--; + } + } + row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA; + row_info->channels = 4; + row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); + } } #endif @@ -4760,8 +4755,7 @@ png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info) &(png_ptr->trans_color)); else - png_do_expand(row_info, png_ptr->row_buf + 1, - NULL); + png_do_expand(row_info, png_ptr->row_buf + 1, NULL); } } #endif @@ -4985,7 +4979,7 @@ png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info) (png_ptr, /* png_ptr */ row_info, /* row_info: */ /* png_uint_32 width; width of row */ - /* png_size_t rowbytes; number of bytes in row */ + /* size_t rowbytes; number of bytes in row */ /* png_byte color_type; color type of pixels */ /* png_byte bit_depth; bit depth of samples */ /* png_byte channels; number of channels (1-4) */ diff --git a/src/3rdparty/libpng/pngrutil.c b/src/3rdparty/libpng/pngrutil.c index 8692933bd8..7001f1976e 100644 --- a/src/3rdparty/libpng/pngrutil.c +++ b/src/3rdparty/libpng/pngrutil.c @@ -1,8 +1,8 @@ /* pngrutil.c - utilities to read a PNG file * - * Last changed in libpng 1.6.33 [September 28, 2017] - * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson + * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -102,7 +102,7 @@ png_get_int_32)(png_const_bytep buf) png_uint_16 (PNGAPI png_get_uint_16)(png_const_bytep buf) { - /* ANSI-C requires an int value to accomodate at least 16 bits so this + /* ANSI-C requires an int value to accommodate at least 16 bits so this * works and allows the compiler not to worry about possible narrowing * on 32-bit systems. (Pre-ANSI systems did not make integers smaller * than 16 bits either.) @@ -120,7 +120,7 @@ png_get_uint_16)(png_const_bytep buf) void /* PRIVATE */ png_read_sig(png_structrp png_ptr, png_inforp info_ptr) { - png_size_t num_checked, num_to_check; + size_t num_checked, num_to_check; /* Exit if the user application does not expect a signature. */ if (png_ptr->sig_bytes >= 8) @@ -1648,7 +1648,7 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) int entry_size, i; png_uint_32 skip = 0; png_uint_32 dl; - png_size_t max_dl; + size_t max_dl; png_debug(1, "in png_handle_sPLT"); @@ -1997,6 +1997,15 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) else if ((png_ptr->color_type & PNG_COLOR_MASK_COLOR) == 0) /* GRAY */ { + if (png_ptr->bit_depth <= 8) + { + if (buf[0] != 0 || buf[1] >= (unsigned int)(1 << png_ptr->bit_depth)) + { + png_chunk_benign_error(png_ptr, "invalid gray level"); + return; + } + } + background.index = 0; background.red = background.green = @@ -2006,6 +2015,15 @@ png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) else { + if (png_ptr->bit_depth <= 8) + { + if (buf[0] != 0 || buf[2] != 0 || buf[4] != 0) + { + png_chunk_benign_error(png_ptr, "invalid color"); + return; + } + } + background.index = 0; background.red = png_get_uint_16(buf); background.green = png_get_uint_16(buf + 2); @@ -2359,7 +2377,7 @@ void /* PRIVATE */ png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { png_bytep buffer; - png_size_t i; + size_t i; int state; png_debug(1, "in png_handle_sCAL"); @@ -2429,7 +2447,7 @@ png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) else { - png_size_t heighti = i; + size_t heighti = i; state = 0; if (png_check_fp_number((png_const_charp)buffer, length, @@ -2867,7 +2885,7 @@ png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length) { PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name); /* The following is safe because of the PNG_SIZE_MAX init above */ - png_ptr->unknown_chunk.size = (png_size_t)length/*SAFE*/; + png_ptr->unknown_chunk.size = (size_t)length/*SAFE*/; /* 'mode' is a flag array, only the bottom four bits matter here */ png_ptr->unknown_chunk.location = (png_byte)png_ptr->mode/*SAFE*/; @@ -3149,10 +3167,13 @@ png_check_chunk_length(png_const_structrp png_ptr, const png_uint_32 length) { png_alloc_size_t idat_limit = PNG_UINT_31_MAX; size_t row_factor = - (png_ptr->width * png_ptr->channels * (png_ptr->bit_depth > 8? 2: 1) - + 1 + (png_ptr->interlaced? 6: 0)); + (size_t)png_ptr->width + * (size_t)png_ptr->channels + * (png_ptr->bit_depth > 8? 2: 1) + + 1 + + (png_ptr->interlaced? 6: 0); if (png_ptr->height > PNG_UINT_32_MAX/row_factor) - idat_limit=PNG_UINT_31_MAX; + idat_limit = PNG_UINT_31_MAX; else idat_limit = png_ptr->height * row_factor; row_factor = row_factor > 32566? 32566 : row_factor; @@ -3679,8 +3700,8 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, { case 1: { - png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3); - png_bytep dp = row + (png_size_t)((final_width - 1) >> 3); + png_bytep sp = row + (size_t)((row_info->width - 1) >> 3); + png_bytep dp = row + (size_t)((final_width - 1) >> 3); unsigned int sshift, dshift; unsigned int s_start, s_end; int s_inc; @@ -3806,8 +3827,8 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, case 4: { - png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1); - png_bytep dp = row + (png_size_t)((final_width - 1) >> 1); + png_bytep sp = row + (size_t)((row_info->width - 1) >> 1); + png_bytep dp = row + (size_t)((final_width - 1) >> 1); unsigned int sshift, dshift; unsigned int s_start, s_end; int s_inc; @@ -3869,12 +3890,12 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, default: { - png_size_t pixel_bytes = (row_info->pixel_depth >> 3); + size_t pixel_bytes = (row_info->pixel_depth >> 3); - png_bytep sp = row + (png_size_t)(row_info->width - 1) + png_bytep sp = row + (size_t)(row_info->width - 1) * pixel_bytes; - png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes; + png_bytep dp = row + (size_t)(final_width - 1) * pixel_bytes; int jstop = (int)png_pass_inc[pass]; png_uint_32 i; @@ -3911,8 +3932,8 @@ static void png_read_filter_row_sub(png_row_infop row_info, png_bytep row, png_const_bytep prev_row) { - png_size_t i; - png_size_t istop = row_info->rowbytes; + size_t i; + size_t istop = row_info->rowbytes; unsigned int bpp = (row_info->pixel_depth + 7) >> 3; png_bytep rp = row + bpp; @@ -3929,8 +3950,8 @@ static void png_read_filter_row_up(png_row_infop row_info, png_bytep row, png_const_bytep prev_row) { - png_size_t i; - png_size_t istop = row_info->rowbytes; + size_t i; + size_t istop = row_info->rowbytes; png_bytep rp = row; png_const_bytep pp = prev_row; @@ -3945,11 +3966,11 @@ static void png_read_filter_row_avg(png_row_infop row_info, png_bytep row, png_const_bytep prev_row) { - png_size_t i; + size_t i; png_bytep rp = row; png_const_bytep pp = prev_row; unsigned int bpp = (row_info->pixel_depth + 7) >> 3; - png_size_t istop = row_info->rowbytes - bpp; + size_t istop = row_info->rowbytes - bpp; for (i = 0; i < bpp; i++) { @@ -4385,7 +4406,7 @@ png_read_start_row(png_structrp png_ptr) static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; unsigned int max_pixel_depth; - png_size_t row_bytes; + size_t row_bytes; png_debug(1, "in png_read_start_row"); diff --git a/src/3rdparty/libpng/pngset.c b/src/3rdparty/libpng/pngset.c index 6f3a1ee11e..7cf54d9248 100644 --- a/src/3rdparty/libpng/pngset.c +++ b/src/3rdparty/libpng/pngset.c @@ -1,8 +1,8 @@ /* pngset.c - storage of image information into info struct * - * Last changed in libpng 1.6.32 [August 24, 2017] - * Copyright (c) 1998-2017 Glenn Randers-Pehrson + * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 1998-2018 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -313,7 +313,7 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams, png_const_charp units, png_charpp params) { - png_size_t length; + size_t length; int i; png_debug1(1, "in %s storage function", "pCAL"); @@ -390,7 +390,7 @@ png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, memcpy(info_ptr->pcal_units, units, length); info_ptr->pcal_params = png_voidcast(png_charpp, png_malloc_warn(png_ptr, - (png_size_t)(((unsigned int)nparams + 1) * (sizeof (png_charp))))); + (size_t)(((unsigned int)nparams + 1) * (sizeof (png_charp))))); if (info_ptr->pcal_params == NULL) { @@ -430,7 +430,7 @@ void PNGAPI png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr, int unit, png_const_charp swidth, png_const_charp sheight) { - png_size_t lengthw = 0, lengthh = 0; + size_t lengthw = 0, lengthh = 0; png_debug1(1, "in %s storage function", "sCAL"); @@ -691,7 +691,7 @@ png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, { png_charp new_iccp_name; png_bytep new_iccp_profile; - png_size_t length; + size_t length; png_debug1(1, "in %s storage function", "iCCP"); @@ -1018,7 +1018,7 @@ png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr, /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */ info_ptr->trans_alpha = png_voidcast(png_bytep, png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH)); - memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans); + memcpy(info_ptr->trans_alpha, trans_alpha, (size_t)num_trans); } png_ptr->trans_alpha = info_ptr->trans_alpha; } @@ -1098,7 +1098,7 @@ png_set_sPLT(png_const_structrp png_ptr, do { - png_size_t length; + size_t length; /* Skip invalid input entries */ if (entries->name == NULL || entries->entries == NULL) @@ -1563,7 +1563,7 @@ png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr, #endif void PNGAPI -png_set_compression_buffer_size(png_structrp png_ptr, png_size_t size) +png_set_compression_buffer_size(png_structrp png_ptr, size_t size) { if (png_ptr == NULL) return; diff --git a/src/3rdparty/libpng/pngstruct.h b/src/3rdparty/libpng/pngstruct.h index d83f971253..699e8ac68a 100644 --- a/src/3rdparty/libpng/pngstruct.h +++ b/src/3rdparty/libpng/pngstruct.h @@ -1,8 +1,8 @@ /* pngstruct.h - header file for PNG reference library * - * Last changed in libpng 1.6.32 [August 24, 2017] - * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson + * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -47,7 +47,7 @@ /* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib * can handle at once. This type need be no larger than 16 bits (so maximum of * 65535), this define allows us to discover how big it is, but limited by the - * maximuum for png_size_t. The value can be overriden in a library build + * maximum for size_t. The value can be overridden in a library build * (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably * lower value (e.g. 255 works). A lower value may help memory usage (slightly) * and may even improve performance on some systems (and degrade it on others.) @@ -214,7 +214,7 @@ struct png_struct_def png_uint_32 height; /* height of image in pixels */ png_uint_32 num_rows; /* number of rows in current pass */ png_uint_32 usr_width; /* width of row at start of write */ - png_size_t rowbytes; /* size of row in bytes */ + size_t rowbytes; /* size of row in bytes */ png_uint_32 iwidth; /* width of current interlaced row in pixels */ png_uint_32 row_number; /* current row in interlace pass */ png_uint_32 chunk_name; /* PNG_CHUNK() id of current chunk */ @@ -232,7 +232,7 @@ struct png_struct_def png_bytep try_row; /* buffer to save trial row when filtering */ png_bytep tst_row; /* buffer to save best trial row when filtering */ #endif - png_size_t info_rowbytes; /* Added in 1.5.4: cache of updated row bytes */ + size_t info_rowbytes; /* Added in 1.5.4: cache of updated row bytes */ png_uint_32 idat_size; /* current IDAT size for read */ png_uint_32 crc; /* current chunk CRC value */ @@ -307,7 +307,7 @@ struct png_struct_def #endif #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) - png_color_8 shift; /* shift for significant bit tranformation */ + png_color_8 shift; /* shift for significant bit transformation */ #endif #if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \ @@ -328,10 +328,10 @@ struct png_struct_def png_bytep current_buffer; /* buffer for recently used data */ png_uint_32 push_length; /* size of current input chunk */ png_uint_32 skip_length; /* bytes to skip in input data */ - png_size_t save_buffer_size; /* amount of data now in save_buffer */ - png_size_t save_buffer_max; /* total size of save_buffer */ - png_size_t buffer_size; /* total amount of available input data */ - png_size_t current_buffer_size; /* amount of data now in current_buffer */ + size_t save_buffer_size; /* amount of data now in save_buffer */ + size_t save_buffer_max; /* total size of save_buffer */ + size_t buffer_size; /* total amount of available input data */ + size_t current_buffer_size; /* amount of data now in current_buffer */ int process_mode; /* what push library is currently doing */ int cur_palette; /* current push library palette index */ @@ -451,7 +451,7 @@ struct png_struct_def #endif /* New member added in libpng-1.2.26 */ - png_size_t old_big_row_buf_size; + size_t old_big_row_buf_size; #ifdef PNG_READ_SUPPORTED /* New member added in libpng-1.2.30 */ diff --git a/src/3rdparty/libpng/pngtrans.c b/src/3rdparty/libpng/pngtrans.c index 6882f0fd7b..de84aa6d6b 100644 --- a/src/3rdparty/libpng/pngtrans.c +++ b/src/3rdparty/libpng/pngtrans.c @@ -1,8 +1,8 @@ /* pngtrans.c - transforms the data in a row (used by both readers and writers) * - * Last changed in libpng 1.6.33 [September 28, 2017] - * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson + * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -269,8 +269,8 @@ png_do_invert(png_row_infop row_info, png_bytep row) if (row_info->color_type == PNG_COLOR_TYPE_GRAY) { png_bytep rp = row; - png_size_t i; - png_size_t istop = row_info->rowbytes; + size_t i; + size_t istop = row_info->rowbytes; for (i = 0; i < istop; i++) { @@ -283,8 +283,8 @@ png_do_invert(png_row_infop row_info, png_bytep row) row_info->bit_depth == 8) { png_bytep rp = row; - png_size_t i; - png_size_t istop = row_info->rowbytes; + size_t i; + size_t istop = row_info->rowbytes; for (i = 0; i < istop; i += 2) { @@ -298,8 +298,8 @@ png_do_invert(png_row_infop row_info, png_bytep row) row_info->bit_depth == 16) { png_bytep rp = row; - png_size_t i; - png_size_t istop = row_info->rowbytes; + size_t i; + size_t istop = row_info->rowbytes; for (i = 0; i < istop; i += 4) { @@ -609,7 +609,7 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start) return; /* The filler channel has gone already */ /* Fix the rowbytes value. */ - row_info->rowbytes = (png_size_t)(dp-row); + row_info->rowbytes = (size_t)(dp-row); } #endif diff --git a/src/3rdparty/libpng/pngwio.c b/src/3rdparty/libpng/pngwio.c index 37c7c3a7f0..e5391687a2 100644 --- a/src/3rdparty/libpng/pngwio.c +++ b/src/3rdparty/libpng/pngwio.c @@ -1,8 +1,8 @@ /* pngwio.c - functions for data output * - * Last changed in libpng 1.6.24 [August 4, 2016] - * Copyright (c) 1998-2002,2004,2006-2014,2016 Glenn Randers-Pehrson + * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 1998-2002,2004,2006-2014,2016,2018 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -30,7 +30,7 @@ */ void /* PRIVATE */ -png_write_data(png_structrp png_ptr, png_const_bytep data, png_size_t length) +png_write_data(png_structrp png_ptr, png_const_bytep data, size_t length) { /* NOTE: write_data_fn must not change the buffer! */ if (png_ptr->write_data_fn != NULL ) @@ -48,9 +48,9 @@ png_write_data(png_structrp png_ptr, png_const_bytep data, png_size_t length) * than changing the library. */ void PNGCBAPI -png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) +png_default_write_data(png_structp png_ptr, png_bytep data, size_t length) { - png_size_t check; + size_t check; if (png_ptr == NULL) return; diff --git a/src/3rdparty/libpng/pngwrite.c b/src/3rdparty/libpng/pngwrite.c index a16d77ce00..5bd87f373e 100644 --- a/src/3rdparty/libpng/pngwrite.c +++ b/src/3rdparty/libpng/pngwrite.c @@ -1,8 +1,8 @@ /* pngwrite.c - general routines to write a PNG file * - * Last changed in libpng 1.6.32 [August 24, 2017] - * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson + * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -1636,7 +1636,7 @@ png_write_image_16bit(png_voidp argument) * calculation can be done to 15 bits of accuracy; however, the output needs to * be scaled in the range 0..255*65535, so include that scaling here. */ -# define UNP_RECIPROCAL(alpha) ((((0xffff*0xff)<<7)+(alpha>>1))/alpha) +# define UNP_RECIPROCAL(alpha) ((((0xffff*0xff)<<7)+((alpha)>>1))/(alpha)) static png_byte png_unpremultiply(png_uint_32 component, png_uint_32 alpha, @@ -2162,8 +2162,7 @@ png_image_write_main(png_voidp argument) static void (PNGCBAPI -image_memory_write)(png_structp png_ptr, png_bytep/*const*/ data, - png_size_t size) +image_memory_write)(png_structp png_ptr, png_bytep/*const*/ data, size_t size) { png_image_write_control *display = png_voidcast(png_image_write_control*, png_ptr->io_ptr/*backdoor: png_get_io_ptr(png_ptr)*/); diff --git a/src/3rdparty/libpng/pngwtran.c b/src/3rdparty/libpng/pngwtran.c index 377b43e5ca..3a1e0a21d2 100644 --- a/src/3rdparty/libpng/pngwtran.c +++ b/src/3rdparty/libpng/pngwtran.c @@ -1,8 +1,8 @@ /* pngwtran.c - transforms the data in a row for PNG writers * - * Last changed in libpng 1.6.26 [October 20, 2016] - * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson + * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -212,9 +212,9 @@ png_do_shift(png_row_infop row_info, png_bytep row, if (row_info->bit_depth < 8) { png_bytep bp = row; - png_size_t i; + size_t i; unsigned int mask; - png_size_t row_bytes = row_info->rowbytes; + size_t row_bytes = row_info->rowbytes; if (bit_depth->gray == 1 && row_info->bit_depth == 2) mask = 0x55; @@ -514,7 +514,7 @@ png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info) (png_ptr, /* png_ptr */ row_info, /* row_info: */ /* png_uint_32 width; width of row */ - /* png_size_t rowbytes; number of bytes in row */ + /* size_t rowbytes; number of bytes in row */ /* png_byte color_type; color type of pixels */ /* png_byte bit_depth; bit depth of samples */ /* png_byte channels; number of channels (1-4) */ diff --git a/src/3rdparty/libpng/pngwutil.c b/src/3rdparty/libpng/pngwutil.c index 0d4fb1336c..ab431e712c 100644 --- a/src/3rdparty/libpng/pngwutil.c +++ b/src/3rdparty/libpng/pngwutil.c @@ -1,8 +1,8 @@ /* pngwutil.c - utilities to write a PNG file * - * Last changed in libpng 1.6.32 [August 24, 2017] - * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson + * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -59,7 +59,7 @@ png_write_sig(png_structrp png_ptr) /* Write the rest of the 8 byte signature */ png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes], - (png_size_t)(8 - png_ptr->sig_bytes)); + (size_t)(8 - png_ptr->sig_bytes)); if (png_ptr->sig_bytes < 3) png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; @@ -124,8 +124,7 @@ png_write_chunk_start(png_structrp png_ptr, png_const_bytep chunk_string, * given to png_write_chunk_header(). */ void PNGAPI -png_write_chunk_data(png_structrp png_ptr, png_const_bytep data, - png_size_t length) +png_write_chunk_data(png_structrp png_ptr, png_const_bytep data, size_t length) { /* Write the data, and run the CRC over it */ if (png_ptr == NULL) @@ -160,7 +159,7 @@ png_write_chunk_end(png_structrp png_ptr) /* Write the crc in a single operation */ png_save_uint_32(buf, png_ptr->crc); - png_write_data(png_ptr, buf, (png_size_t)4); + png_write_data(png_ptr, buf, 4); } /* Write a PNG chunk all at once. The type is an array of ASCII characters @@ -174,7 +173,7 @@ png_write_chunk_end(png_structrp png_ptr) */ static void png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name, - png_const_bytep data, png_size_t length) + png_const_bytep data, size_t length) { if (png_ptr == NULL) return; @@ -191,7 +190,7 @@ png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name, /* This is the API that calls the internal function above. */ void PNGAPI png_write_chunk(png_structrp png_ptr, png_const_bytep chunk_string, - png_const_bytep data, png_size_t length) + png_const_bytep data, size_t length) { png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data, length); @@ -820,7 +819,7 @@ png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height, buf[12] = (png_byte)interlace_type; /* Write the chunk */ - png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13); + png_write_complete_chunk(png_ptr, png_IHDR, buf, 13); if ((png_ptr->do_filter) == PNG_NO_FILTERS) { @@ -889,7 +888,7 @@ png_write_PLTE(png_structrp png_ptr, png_const_colorp palette, buf[0] = pal_ptr->red; buf[1] = pal_ptr->green; buf[2] = pal_ptr->blue; - png_write_chunk_data(png_ptr, buf, (png_size_t)3); + png_write_chunk_data(png_ptr, buf, 3); } #else @@ -903,7 +902,7 @@ png_write_PLTE(png_structrp png_ptr, png_const_colorp palette, buf[0] = pal_ptr[i].red; buf[1] = pal_ptr[i].green; buf[2] = pal_ptr[i].blue; - png_write_chunk_data(png_ptr, buf, (png_size_t)3); + png_write_chunk_data(png_ptr, buf, 3); } #endif @@ -1075,7 +1074,7 @@ png_write_IEND(png_structrp png_ptr) { png_debug(1, "in png_write_IEND"); - png_write_complete_chunk(png_ptr, png_IEND, NULL, (png_size_t)0); + png_write_complete_chunk(png_ptr, png_IEND, NULL, 0); png_ptr->mode |= PNG_HAVE_IEND; } @@ -1090,7 +1089,7 @@ png_write_gAMA_fixed(png_structrp png_ptr, png_fixed_point file_gamma) /* file_gamma is saved in 1/100,000ths */ png_save_uint_32(buf, (png_uint_32)file_gamma); - png_write_complete_chunk(png_ptr, png_gAMA, buf, (png_size_t)4); + png_write_complete_chunk(png_ptr, png_gAMA, buf, 4); } #endif @@ -1108,7 +1107,7 @@ png_write_sRGB(png_structrp png_ptr, int srgb_intent) "Invalid sRGB rendering intent specified"); buf[0]=(png_byte)srgb_intent; - png_write_complete_chunk(png_ptr, png_sRGB, buf, (png_size_t)1); + png_write_complete_chunk(png_ptr, png_sRGB, buf, 1); } #endif @@ -1182,8 +1181,8 @@ png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette) png_uint_32 name_len; png_byte new_name[80]; png_byte entrybuf[10]; - png_size_t entry_size = (spalette->depth == 8 ? 6 : 10); - png_size_t palette_size = entry_size * (png_size_t)spalette->nentries; + size_t entry_size = (spalette->depth == 8 ? 6 : 10); + size_t palette_size = entry_size * (size_t)spalette->nentries; png_sPLT_entryp ep; #ifndef PNG_POINTER_INDEXING_SUPPORTED int i; @@ -1200,10 +1199,9 @@ png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette) png_write_chunk_header(png_ptr, png_sPLT, (png_uint_32)(name_len + 2 + palette_size)); - png_write_chunk_data(png_ptr, (png_bytep)new_name, - (png_size_t)(name_len + 1)); + png_write_chunk_data(png_ptr, (png_bytep)new_name, (size_t)(name_len + 1)); - png_write_chunk_data(png_ptr, &spalette->depth, (png_size_t)1); + png_write_chunk_data(png_ptr, &spalette->depth, 1); /* Loop through each palette entry, writing appropriately */ #ifdef PNG_POINTER_INDEXING_SUPPORTED @@ -1265,7 +1263,7 @@ void /* PRIVATE */ png_write_sBIT(png_structrp png_ptr, png_const_color_8p sbit, int color_type) { png_byte buf[4]; - png_size_t size; + size_t size; png_debug(1, "in png_write_sBIT"); @@ -1365,7 +1363,7 @@ png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha, /* Write the chunk out as it is */ png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha, - (png_size_t)num_trans); + (size_t)num_trans); } else if (color_type == PNG_COLOR_TYPE_GRAY) @@ -1380,7 +1378,7 @@ png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha, } png_save_uint_16(buf, tran->gray); - png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)2); + png_write_complete_chunk(png_ptr, png_tRNS, buf, 2); } else if (color_type == PNG_COLOR_TYPE_RGB) @@ -1400,7 +1398,7 @@ png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha, return; } - png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)6); + png_write_complete_chunk(png_ptr, png_tRNS, buf, 6); } else @@ -1433,7 +1431,7 @@ png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type) } buf[0] = back->index; - png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)1); + png_write_complete_chunk(png_ptr, png_bKGD, buf, 1); } else if ((color_type & PNG_COLOR_MASK_COLOR) != 0) @@ -1454,7 +1452,7 @@ png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type) return; } - png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)6); + png_write_complete_chunk(png_ptr, png_bKGD, buf, 6); } else @@ -1468,7 +1466,7 @@ png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type) } png_save_uint_16(buf, back->gray); - png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)2); + png_write_complete_chunk(png_ptr, png_bKGD, buf, 2); } } #endif @@ -1488,7 +1486,7 @@ png_write_eXIf(png_structrp png_ptr, png_bytep exif, int num_exif) for (i = 0; i < num_exif; i++) { buf[0] = exif[i]; - png_write_chunk_data(png_ptr, buf, (png_size_t)1); + png_write_chunk_data(png_ptr, buf, 1); } png_write_chunk_end(png_ptr); @@ -1519,7 +1517,7 @@ png_write_hIST(png_structrp png_ptr, png_const_uint_16p hist, int num_hist) for (i = 0; i < num_hist; i++) { png_save_uint_16(buf, hist[i]); - png_write_chunk_data(png_ptr, buf, (png_size_t)2); + png_write_chunk_data(png_ptr, buf, 2); } png_write_chunk_end(png_ptr); @@ -1530,7 +1528,7 @@ png_write_hIST(png_structrp png_ptr, png_const_uint_16p hist, int num_hist) /* Write a tEXt chunk */ void /* PRIVATE */ png_write_tEXt(png_structrp png_ptr, png_const_charp key, png_const_charp text, - png_size_t text_len) + size_t text_len) { png_uint_32 key_len; png_byte new_key[80]; @@ -1627,7 +1625,7 @@ png_write_iTXt(png_structrp png_ptr, int compression, png_const_charp key, png_const_charp lang, png_const_charp lang_key, png_const_charp text) { png_uint_32 key_len, prefix_len; - png_size_t lang_len, lang_key_len; + size_t lang_len, lang_key_len; png_byte new_key[82]; compression_state comp; @@ -1737,7 +1735,7 @@ png_write_oFFs(png_structrp png_ptr, png_int_32 x_offset, png_int_32 y_offset, png_save_int_32(buf + 4, y_offset); buf[8] = (png_byte)unit_type; - png_write_complete_chunk(png_ptr, png_oFFs, buf, (png_size_t)9); + png_write_complete_chunk(png_ptr, png_oFFs, buf, 9); } #endif #ifdef PNG_WRITE_pCAL_SUPPORTED @@ -1748,7 +1746,7 @@ png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0, png_charpp params) { png_uint_32 purpose_len; - png_size_t units_len, total_len; + size_t units_len, total_len; png_size_tp params_len; png_byte buf[10]; png_byte new_purpose[80]; @@ -1772,7 +1770,7 @@ png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0, total_len = purpose_len + units_len + 10; params_len = (png_size_tp)png_malloc(png_ptr, - (png_alloc_size_t)((png_alloc_size_t)nparams * (sizeof (png_size_t)))); + (png_alloc_size_t)((png_alloc_size_t)nparams * (sizeof (size_t)))); /* Find the length of each parameter, making sure we don't count the * null terminator for the last parameter. @@ -1792,8 +1790,8 @@ png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0, png_save_int_32(buf + 4, X1); buf[8] = (png_byte)type; buf[9] = (png_byte)nparams; - png_write_chunk_data(png_ptr, buf, (png_size_t)10); - png_write_chunk_data(png_ptr, (png_const_bytep)units, (png_size_t)units_len); + png_write_chunk_data(png_ptr, buf, 10); + png_write_chunk_data(png_ptr, (png_const_bytep)units, (size_t)units_len); for (i = 0; i < nparams; i++) { @@ -1812,7 +1810,7 @@ png_write_sCAL_s(png_structrp png_ptr, int unit, png_const_charp width, png_const_charp height) { png_byte buf[64]; - png_size_t wlen, hlen, total_len; + size_t wlen, hlen, total_len; png_debug(1, "in png_write_sCAL_s"); @@ -1853,7 +1851,7 @@ png_write_pHYs(png_structrp png_ptr, png_uint_32 x_pixels_per_unit, png_save_uint_32(buf + 4, y_pixels_per_unit); buf[8] = (png_byte)unit_type; - png_write_complete_chunk(png_ptr, png_pHYs, buf, (png_size_t)9); + png_write_complete_chunk(png_ptr, png_pHYs, buf, 9); } #endif @@ -1883,7 +1881,7 @@ png_write_tIME(png_structrp png_ptr, png_const_timep mod_time) buf[5] = mod_time->minute; buf[6] = mod_time->second; - png_write_complete_chunk(png_ptr, png_tIME, buf, (png_size_t)7); + png_write_complete_chunk(png_ptr, png_tIME, buf, 7); } #endif @@ -2073,8 +2071,8 @@ png_write_finish_row(png_structrp png_ptr) { if (png_ptr->prev_row != NULL) memset(png_ptr->prev_row, 0, - (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels* - png_ptr->usr_bit_depth, png_ptr->width)) + 1); + PNG_ROWBYTES(png_ptr->usr_channels * + png_ptr->usr_bit_depth, png_ptr->width) + 1); return; } @@ -2130,7 +2128,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) for (i = png_pass_start[pass]; i < row_width; i += png_pass_inc[pass]) { - sp = row + (png_size_t)(i >> 3); + sp = row + (size_t)(i >> 3); value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01; d |= (value << shift); @@ -2168,7 +2166,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) for (i = png_pass_start[pass]; i < row_width; i += png_pass_inc[pass]) { - sp = row + (png_size_t)(i >> 2); + sp = row + (size_t)(i >> 2); value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03; d |= (value << shift); @@ -2204,7 +2202,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) for (i = png_pass_start[pass]; i < row_width; i += png_pass_inc[pass]) { - sp = row + (png_size_t)(i >> 1); + sp = row + (size_t)(i >> 1); value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f; d |= (value << shift); @@ -2230,7 +2228,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) png_bytep dp; png_uint_32 i; png_uint_32 row_width = row_info->width; - png_size_t pixel_bytes; + size_t pixel_bytes; /* Start at the beginning */ dp = row; @@ -2243,7 +2241,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) i += png_pass_inc[pass]) { /* Find out where the original pixel is */ - sp = row + (png_size_t)i * pixel_bytes; + sp = row + (size_t)i * pixel_bytes; /* Move the pixel */ if (dp != sp) @@ -2274,16 +2272,16 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) */ static void /* PRIVATE */ png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row, - png_size_t row_bytes); + size_t row_bytes); #ifdef PNG_WRITE_FILTER_SUPPORTED -static png_size_t /* PRIVATE */ +static size_t /* PRIVATE */ png_setup_sub_row(png_structrp png_ptr, const png_uint_32 bpp, - const png_size_t row_bytes, const png_size_t lmins) + size_t row_bytes, size_t lmins) { png_bytep rp, dp, lp; - png_size_t i; - png_size_t sum = 0; + size_t i; + size_t sum = 0; unsigned int v; png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB; @@ -2318,10 +2316,10 @@ png_setup_sub_row(png_structrp png_ptr, const png_uint_32 bpp, static void /* PRIVATE */ png_setup_sub_row_only(png_structrp png_ptr, const png_uint_32 bpp, - const png_size_t row_bytes) + size_t row_bytes) { png_bytep rp, dp, lp; - png_size_t i; + size_t i; png_ptr->try_row[0] = PNG_FILTER_VALUE_SUB; @@ -2338,13 +2336,12 @@ png_setup_sub_row_only(png_structrp png_ptr, const png_uint_32 bpp, } } -static png_size_t /* PRIVATE */ -png_setup_up_row(png_structrp png_ptr, const png_size_t row_bytes, - const png_size_t lmins) +static size_t /* PRIVATE */ +png_setup_up_row(png_structrp png_ptr, size_t row_bytes, size_t lmins) { png_bytep rp, dp, pp; - png_size_t i; - png_size_t sum = 0; + size_t i; + size_t sum = 0; unsigned int v; png_ptr->try_row[0] = PNG_FILTER_VALUE_UP; @@ -2367,10 +2364,10 @@ png_setup_up_row(png_structrp png_ptr, const png_size_t row_bytes, return (sum); } static void /* PRIVATE */ -png_setup_up_row_only(png_structrp png_ptr, const png_size_t row_bytes) +png_setup_up_row_only(png_structrp png_ptr, size_t row_bytes) { png_bytep rp, dp, pp; - png_size_t i; + size_t i; png_ptr->try_row[0] = PNG_FILTER_VALUE_UP; @@ -2382,13 +2379,13 @@ png_setup_up_row_only(png_structrp png_ptr, const png_size_t row_bytes) } } -static png_size_t /* PRIVATE */ +static size_t /* PRIVATE */ png_setup_avg_row(png_structrp png_ptr, const png_uint_32 bpp, - const png_size_t row_bytes, const png_size_t lmins) + size_t row_bytes, size_t lmins) { png_bytep rp, dp, pp, lp; png_uint_32 i; - png_size_t sum = 0; + size_t sum = 0; unsigned int v; png_ptr->try_row[0] = PNG_FILTER_VALUE_AVG; @@ -2424,7 +2421,7 @@ png_setup_avg_row(png_structrp png_ptr, const png_uint_32 bpp, } static void /* PRIVATE */ png_setup_avg_row_only(png_structrp png_ptr, const png_uint_32 bpp, - const png_size_t row_bytes) + size_t row_bytes) { png_bytep rp, dp, pp, lp; png_uint_32 i; @@ -2444,13 +2441,13 @@ png_setup_avg_row_only(png_structrp png_ptr, const png_uint_32 bpp, } } -static png_size_t /* PRIVATE */ +static size_t /* PRIVATE */ png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp, - const png_size_t row_bytes, const png_size_t lmins) + size_t row_bytes, size_t lmins) { png_bytep rp, dp, pp, cp, lp; - png_size_t i; - png_size_t sum = 0; + size_t i; + size_t sum = 0; unsigned int v; png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH; @@ -2507,10 +2504,10 @@ png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp, } static void /* PRIVATE */ png_setup_paeth_row_only(png_structrp png_ptr, const png_uint_32 bpp, - const png_size_t row_bytes) + size_t row_bytes) { png_bytep rp, dp, pp, cp, lp; - png_size_t i; + size_t i; png_ptr->try_row[0] = PNG_FILTER_VALUE_PAETH; @@ -2559,8 +2556,8 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) png_bytep row_buf; png_bytep best_row; png_uint_32 bpp; - png_size_t mins; - png_size_t row_bytes = row_info->rowbytes; + size_t mins; + size_t row_bytes = row_info->rowbytes; png_debug(1, "in png_write_find_filter"); @@ -2615,8 +2612,8 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) * 'none' filter. */ png_bytep rp; - png_size_t sum = 0; - png_size_t i; + size_t sum = 0; + size_t i; unsigned int v; { @@ -2644,8 +2641,8 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) else if ((filter_to_do & PNG_FILTER_SUB) != 0) { - png_size_t sum; - png_size_t lmins = mins; + size_t sum; + size_t lmins = mins; sum = png_setup_sub_row(png_ptr, bpp, row_bytes, lmins); @@ -2670,8 +2667,8 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) else if ((filter_to_do & PNG_FILTER_UP) != 0) { - png_size_t sum; - png_size_t lmins = mins; + size_t sum; + size_t lmins = mins; sum = png_setup_up_row(png_ptr, row_bytes, lmins); @@ -2696,8 +2693,8 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) else if ((filter_to_do & PNG_FILTER_AVG) != 0) { - png_size_t sum; - png_size_t lmins = mins; + size_t sum; + size_t lmins = mins; sum= png_setup_avg_row(png_ptr, bpp, row_bytes, lmins); @@ -2722,8 +2719,8 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) else if ((filter_to_do & PNG_FILTER_PAETH) != 0) { - png_size_t sum; - png_size_t lmins = mins; + size_t sum; + size_t lmins = mins; sum = png_setup_paeth_row(png_ptr, bpp, row_bytes, lmins); @@ -2748,7 +2745,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info) /* Do the actual writing of a previously filtered row. */ static void png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row, - png_size_t full_row_length/*includes filter byte*/) + size_t full_row_length/*includes filter byte*/) { png_debug(1, "in png_write_filtered_row"); diff --git a/src/3rdparty/libpng/qt_attribution.json b/src/3rdparty/libpng/qt_attribution.json index 23fb903bdd..f9039a50f6 100644 --- a/src/3rdparty/libpng/qt_attribution.json +++ b/src/3rdparty/libpng/qt_attribution.json @@ -6,11 +6,11 @@ "Description": "libpng is the official PNG reference library.", "Homepage": "http://www.libpng.org/pub/png/libpng.html", - "Version": "1.6.34", + "Version": "1.6.35", "License": "libpng License", "LicenseId": "Libpng", "LicenseFile": "LICENSE", - "Copyright": "Copyright (c) 1998-2017 Glenn Randers-Pehrson + "Copyright": "Copyright (c) 1998-2018 Glenn Randers-Pehrson Copyright (c) 2000-2017 Simon-Pierre Cadieux Copyright (c) 2000-2017 Eric S. Raymond Copyright (c) 2000-2017 Mans Rullgard diff --git a/src/3rdparty/libpng/qtpatches.diff b/src/3rdparty/libpng/qtpatches.diff index 82ee104545..508d5874e4 100644 --- a/src/3rdparty/libpng/qtpatches.diff +++ b/src/3rdparty/libpng/qtpatches.diff @@ -1,5 +1,5 @@ diff --git a/src/3rdparty/libpng/pngpriv.h b/src/3rdparty/libpng/pngpriv.h -index c466d4b..f7a4547 100644 +index 3581f67919..e43862a886 100644 --- a/src/3rdparty/libpng/pngpriv.h +++ b/src/3rdparty/libpng/pngpriv.h @@ -23,6 +23,12 @@ @@ -15,7 +15,7 @@ index c466d4b..f7a4547 100644 /* Feature Test Macros. The following are defined here to ensure that correctly * implemented libraries reveal the APIs libpng needs to build and hide those * that are not needed and potentially damaging to the compilation. -@@ -219,6 +225,11 @@ +@@ -305,6 +311,11 @@ # endif #endif /* Setting PNG_BUILD_DLL if required */ @@ -27,7 +27,7 @@ index c466d4b..f7a4547 100644 /* See pngconf.h for more details: the builder of the library may set this on * the command line to the right thing for the specific compilation system or it * may be automagically set above (at present we know of no system where it does -@@ -447,6 +458,9 @@ +@@ -543,6 +554,9 @@ #if defined(WIN32) || defined(_Windows) || defined(_WINDOWS) || \ defined(_WIN32) || defined(__WIN32__) # include /* defines _WINDOWS_ macro */ @@ -37,7 +37,7 @@ index c466d4b..f7a4547 100644 #endif #endif /* PNG_VERSION_INFO_ONLY */ -@@ -457,7 +471,7 @@ +@@ -553,7 +567,7 @@ /* Memory model/platform independent fns */ #ifndef PNG_ABORT From 0509383cf2852f2aebd1efd75413835747c8f341 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 12 Oct 2018 09:15:00 +0200 Subject: [PATCH 0007/1650] Bump copyright year in executable metadata Change-Id: I67d06eae963c7fbbbbf13c5f9ab1195cbc5d7eb1 Reviewed-by: Oswald Buddenhagen --- mkspecs/features/qt_targets.prf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/qt_targets.prf b/mkspecs/features/qt_targets.prf index 49f7e6bd43..317d975b71 100644 --- a/mkspecs/features/qt_targets.prf +++ b/mkspecs/features/qt_targets.prf @@ -1,4 +1,4 @@ QMAKE_TARGET_COMPANY = The Qt Company Ltd. isEmpty(QMAKE_TARGET_PRODUCT): QMAKE_TARGET_PRODUCT = Qt5 isEmpty(QMAKE_TARGET_DESCRIPTION): QMAKE_TARGET_DESCRIPTION = C++ Application Development Framework -QMAKE_TARGET_COPYRIGHT = Copyright (C) 2017 The Qt Company Ltd. +QMAKE_TARGET_COPYRIGHT = Copyright (C) 2018 The Qt Company Ltd. From c593492d1678a2ec08f1bfffcb572459b3bc6c00 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Wed, 26 Sep 2018 15:39:35 +0200 Subject: [PATCH 0008/1650] Modernize the "animation" feature Change-Id: Ibc164b3df3cf87db569ef4813de458a9067b7f7d Reviewed-by: Edward Welbourne Reviewed-by: Oswald Buddenhagen --- .../animation/sub-attaq/qanimationstate.cpp | 5 ---- .../animation/sub-attaq/qanimationstate.h | 5 ---- examples/widgets/widgets.pro | 1 + src/corelib/animation/qabstractanimation.cpp | 4 --- src/corelib/animation/qabstractanimation.h | 10 ++----- src/corelib/animation/qabstractanimation_p.h | 4 +-- src/corelib/animation/qanimationgroup.cpp | 4 --- src/corelib/animation/qanimationgroup.h | 7 ++--- src/corelib/animation/qanimationgroup_p.h | 4 +-- .../animation/qparallelanimationgroup.cpp | 4 --- .../animation/qparallelanimationgroup.h | 7 ++--- .../animation/qparallelanimationgroup_p.h | 4 +-- src/corelib/animation/qpauseanimation.cpp | 5 ---- src/corelib/animation/qpauseanimation.h | 7 ++--- src/corelib/animation/qpropertyanimation.cpp | 4 --- src/corelib/animation/qpropertyanimation.h | 7 ++--- src/corelib/animation/qpropertyanimation_p.h | 4 +-- .../animation/qsequentialanimationgroup.cpp | 4 --- .../animation/qsequentialanimationgroup.h | 7 ++--- .../animation/qsequentialanimationgroup_p.h | 4 +-- src/corelib/animation/qvariantanimation.cpp | 4 --- src/corelib/animation/qvariantanimation.h | 7 ++--- src/corelib/animation/qvariantanimation_p.h | 4 +-- src/corelib/corelib.pro | 2 +- .../statemachine/qabstracttransition.cpp | 2 +- .../statemachine/qabstracttransition.h | 4 +-- .../statemachine/qabstracttransition_p.h | 2 +- src/corelib/statemachine/qstatemachine.cpp | 30 +++++++++---------- src/corelib/statemachine/qstatemachine.h | 8 ++--- src/corelib/statemachine/qstatemachine_p.h | 2 +- src/gui/animation/qguivariantanimation.cpp | 4 --- src/gui/gui.pro | 2 +- src/gui/kernel/qguiapplication.cpp | 4 +-- src/widgets/configure.json | 4 +-- src/widgets/itemviews/qcolumnview.cpp | 16 +++++----- src/widgets/itemviews/qcolumnview_p.h | 4 ++- src/widgets/itemviews/qtreeview.cpp | 28 ++++++++--------- src/widgets/itemviews/qtreeview.h | 4 +-- src/widgets/itemviews/qtreeview_p.h | 6 ++-- src/widgets/styles/qcommonstyle.cpp | 4 ++- src/widgets/styles/qcommonstyle.h | 2 +- src/widgets/styles/qcommonstyle_p.h | 9 +++--- src/widgets/styles/qfusionstyle.cpp | 12 ++++---- src/widgets/styles/qstyleanimation.cpp | 4 --- src/widgets/styles/qstyleanimation_p.h | 6 ++-- src/widgets/styles/qstylesheetstyle.cpp | 2 ++ src/widgets/styles/qwindowsstyle.cpp | 2 ++ src/widgets/styles/styles.pri | 7 +++-- src/widgets/util/qscroller.cpp | 18 +++++------ src/widgets/util/qscroller_p.h | 6 ++-- src/widgets/widgets/qlineedit_p.cpp | 4 ++- src/widgets/widgets/qlineedit_p.h | 4 +-- src/widgets/widgets/qtabbar.cpp | 6 ++-- src/widgets/widgets/qtabbar_p.h | 10 ++++--- src/widgets/widgets/qwidgetanimator.cpp | 18 ++++++----- src/widgets/widgets/qwidgetanimator_p.h | 2 +- .../itemviews/qtreeview/tst_qtreeview.cpp | 6 ++-- 57 files changed, 149 insertions(+), 211 deletions(-) diff --git a/examples/widgets/animation/sub-attaq/qanimationstate.cpp b/examples/widgets/animation/sub-attaq/qanimationstate.cpp index 82bfdbf4b9..ae24af6da3 100644 --- a/examples/widgets/animation/sub-attaq/qanimationstate.cpp +++ b/examples/widgets/animation/sub-attaq/qanimationstate.cpp @@ -80,9 +80,6 @@ machine.start(); \sa QState, {The Animation Framework} */ - -#ifndef QT_NO_ANIMATION - /*! Constructs a new state with the given \a parent state. */ @@ -155,5 +152,3 @@ bool QAnimationState::event(QEvent *e) } QT_END_NAMESPACE - -#endif diff --git a/examples/widgets/animation/sub-attaq/qanimationstate.h b/examples/widgets/animation/sub-attaq/qanimationstate.h index 06ab4dfbcf..063b119058 100644 --- a/examples/widgets/animation/sub-attaq/qanimationstate.h +++ b/examples/widgets/animation/sub-attaq/qanimationstate.h @@ -61,9 +61,6 @@ QT_BEGIN_NAMESPACE - -#ifndef QT_NO_ANIMATION - class QAbstractAnimation; class QAnimationState : public QState @@ -89,8 +86,6 @@ private: QAbstractAnimation *m_animation; }; -#endif - QT_END_NAMESPACE #endif // QANIMATIONSTATE_H diff --git a/examples/widgets/widgets.pro b/examples/widgets/widgets.pro index f9d863b69e..7e52125125 100644 --- a/examples/widgets/widgets.pro +++ b/examples/widgets/widgets.pro @@ -27,4 +27,5 @@ qtHaveModule(gui):qtConfig(opengl): \ contains(DEFINES, QT_NO_CURSOR): SUBDIRS -= mainwindows !qtConfig(draganddrop): SUBDIRS -= draganddrop +!qtConfig(animation): SUBDIRS -= animation mac:SUBDIRS += mac diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index b3db200ed1..4d7ce038dd 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -153,8 +153,6 @@ #include #include -#ifndef QT_NO_ANIMATION - #define DEFAULT_TIMER_INTERVAL 16 #define PAUSE_TIMER_COARSE_THRESHOLD 2000 @@ -1485,5 +1483,3 @@ QT_END_NAMESPACE #include "moc_qabstractanimation.cpp" #include "moc_qabstractanimation_p.cpp" - -#endif //QT_NO_ANIMATION diff --git a/src/corelib/animation/qabstractanimation.h b/src/corelib/animation/qabstractanimation.h index 0ff6bc5176..25b5726d56 100644 --- a/src/corelib/animation/qabstractanimation.h +++ b/src/corelib/animation/qabstractanimation.h @@ -42,11 +42,10 @@ #include +QT_REQUIRE_CONFIG(animation); + QT_BEGIN_NAMESPACE - -#ifndef QT_NO_ANIMATION - class QAnimationGroup; class QSequentialAnimationGroup; class QAnimationDriver; @@ -169,11 +168,6 @@ private: }; - - - -#endif //QT_NO_ANIMATION - QT_END_NAMESPACE #endif // QABSTRACTANIMATION_H diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h index 5593046e48..3b6e8d6cc4 100644 --- a/src/corelib/animation/qabstractanimation_p.h +++ b/src/corelib/animation/qabstractanimation_p.h @@ -58,7 +58,7 @@ #include #include -#ifndef QT_NO_ANIMATION +QT_REQUIRE_CONFIG(animation); QT_BEGIN_NAMESPACE @@ -296,6 +296,4 @@ private: QT_END_NAMESPACE -#endif //QT_NO_ANIMATION - #endif //QABSTRACTANIMATION_P_H diff --git a/src/corelib/animation/qanimationgroup.cpp b/src/corelib/animation/qanimationgroup.cpp index 486dc149ea..f47d99eb68 100644 --- a/src/corelib/animation/qanimationgroup.cpp +++ b/src/corelib/animation/qanimationgroup.cpp @@ -86,8 +86,6 @@ #include #include "qanimationgroup_p.h" -#ifndef QT_NO_ANIMATION - #include QT_BEGIN_NAMESPACE @@ -300,5 +298,3 @@ void QAnimationGroupPrivate::animationRemoved(int index, QAbstractAnimation *) QT_END_NAMESPACE #include "moc_qanimationgroup.cpp" - -#endif //QT_NO_ANIMATION diff --git a/src/corelib/animation/qanimationgroup.h b/src/corelib/animation/qanimationgroup.h index 136ad3ca9f..7c7666f251 100644 --- a/src/corelib/animation/qanimationgroup.h +++ b/src/corelib/animation/qanimationgroup.h @@ -42,11 +42,10 @@ #include +QT_REQUIRE_CONFIG(animation); + QT_BEGIN_NAMESPACE - -#ifndef QT_NO_ANIMATION - class QAnimationGroupPrivate; class Q_CORE_EXPORT QAnimationGroup : public QAbstractAnimation { @@ -74,8 +73,6 @@ private: Q_DECLARE_PRIVATE(QAnimationGroup) }; -#endif //QT_NO_ANIMATION - QT_END_NAMESPACE #endif //QANIMATIONGROUP_H diff --git a/src/corelib/animation/qanimationgroup_p.h b/src/corelib/animation/qanimationgroup_p.h index 31c2cd08e8..ff759d11fd 100644 --- a/src/corelib/animation/qanimationgroup_p.h +++ b/src/corelib/animation/qanimationgroup_p.h @@ -57,7 +57,7 @@ #include "private/qabstractanimation_p.h" -#ifndef QT_NO_ANIMATION +QT_REQUIRE_CONFIG(animation); QT_BEGIN_NAMESPACE @@ -89,6 +89,4 @@ public: QT_END_NAMESPACE -#endif //QT_NO_ANIMATION - #endif //QANIMATIONGROUP_P_H diff --git a/src/corelib/animation/qparallelanimationgroup.cpp b/src/corelib/animation/qparallelanimationgroup.cpp index e4dfc1bd6e..1dcf006dd3 100644 --- a/src/corelib/animation/qparallelanimationgroup.cpp +++ b/src/corelib/animation/qparallelanimationgroup.cpp @@ -72,8 +72,6 @@ #include "qparallelanimationgroup_p.h" //#define QANIMATION_DEBUG -#ifndef QT_NO_ANIMATION - QT_BEGIN_NAMESPACE typedef QList::ConstIterator AnimationListConstIt; @@ -339,5 +337,3 @@ bool QParallelAnimationGroup::event(QEvent *event) QT_END_NAMESPACE #include "moc_qparallelanimationgroup.cpp" - -#endif //QT_NO_ANIMATION diff --git a/src/corelib/animation/qparallelanimationgroup.h b/src/corelib/animation/qparallelanimationgroup.h index 09a439ef24..683d933861 100644 --- a/src/corelib/animation/qparallelanimationgroup.h +++ b/src/corelib/animation/qparallelanimationgroup.h @@ -42,11 +42,10 @@ #include +QT_REQUIRE_CONFIG(animation); + QT_BEGIN_NAMESPACE - -#ifndef QT_NO_ANIMATION - class QParallelAnimationGroupPrivate; class Q_CORE_EXPORT QParallelAnimationGroup : public QAnimationGroup { @@ -72,8 +71,6 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_uncontrolledAnimationFinished()) }; -#endif //QT_NO_ANIMATION - QT_END_NAMESPACE #endif // QPARALLELANIMATIONGROUP diff --git a/src/corelib/animation/qparallelanimationgroup_p.h b/src/corelib/animation/qparallelanimationgroup_p.h index 1c9c3072f7..fc8f809d5a 100644 --- a/src/corelib/animation/qparallelanimationgroup_p.h +++ b/src/corelib/animation/qparallelanimationgroup_p.h @@ -55,7 +55,7 @@ #include "private/qanimationgroup_p.h" #include -#ifndef QT_NO_ANIMATION +QT_REQUIRE_CONFIG(animation); QT_BEGIN_NAMESPACE @@ -86,6 +86,4 @@ public: QT_END_NAMESPACE -#endif //QT_NO_ANIMATION - #endif //QPARALLELANIMATIONGROUP_P_H diff --git a/src/corelib/animation/qpauseanimation.cpp b/src/corelib/animation/qpauseanimation.cpp index 654ba701da..5f8a8b3590 100644 --- a/src/corelib/animation/qpauseanimation.cpp +++ b/src/corelib/animation/qpauseanimation.cpp @@ -64,9 +64,6 @@ #include "qpauseanimation.h" #include "qabstractanimation_p.h" - -#ifndef QT_NO_ANIMATION - QT_BEGIN_NAMESPACE class QPauseAnimationPrivate : public QAbstractAnimationPrivate @@ -150,5 +147,3 @@ void QPauseAnimation::updateCurrentTime(int) QT_END_NAMESPACE #include "moc_qpauseanimation.cpp" - -#endif //QT_NO_ANIMATION diff --git a/src/corelib/animation/qpauseanimation.h b/src/corelib/animation/qpauseanimation.h index e2095a39d6..6bdbeefdbd 100644 --- a/src/corelib/animation/qpauseanimation.h +++ b/src/corelib/animation/qpauseanimation.h @@ -42,11 +42,10 @@ #include +QT_REQUIRE_CONFIG(animation); + QT_BEGIN_NAMESPACE - -#ifndef QT_NO_ANIMATION - class QPauseAnimationPrivate; class Q_CORE_EXPORT QPauseAnimation : public QAbstractAnimation @@ -70,8 +69,6 @@ private: Q_DECLARE_PRIVATE(QPauseAnimation) }; -#endif //QT_NO_ANIMATION - QT_END_NAMESPACE #endif // QPAUSEANIMATION_H diff --git a/src/corelib/animation/qpropertyanimation.cpp b/src/corelib/animation/qpropertyanimation.cpp index 5ba2a1fa73..174121516b 100644 --- a/src/corelib/animation/qpropertyanimation.cpp +++ b/src/corelib/animation/qpropertyanimation.cpp @@ -93,8 +93,6 @@ #include -#ifndef QT_NO_ANIMATION - QT_BEGIN_NAMESPACE void QPropertyAnimationPrivate::updateMetaProperty() @@ -315,5 +313,3 @@ void QPropertyAnimation::updateState(QAbstractAnimation::State newState, #include "moc_qpropertyanimation.cpp" QT_END_NAMESPACE - -#endif //QT_NO_ANIMATION diff --git a/src/corelib/animation/qpropertyanimation.h b/src/corelib/animation/qpropertyanimation.h index 3270591d1d..a1caafcad5 100644 --- a/src/corelib/animation/qpropertyanimation.h +++ b/src/corelib/animation/qpropertyanimation.h @@ -42,11 +42,10 @@ #include +QT_REQUIRE_CONFIG(animation); + QT_BEGIN_NAMESPACE - -#ifndef QT_NO_ANIMATION - class QPropertyAnimationPrivate; class Q_CORE_EXPORT QPropertyAnimation : public QVariantAnimation { @@ -75,8 +74,6 @@ private: Q_DECLARE_PRIVATE(QPropertyAnimation) }; -#endif //QT_NO_ANIMATION - QT_END_NAMESPACE #endif // QPROPERTYANIMATION_H diff --git a/src/corelib/animation/qpropertyanimation_p.h b/src/corelib/animation/qpropertyanimation_p.h index cfb1f247e0..479762f573 100644 --- a/src/corelib/animation/qpropertyanimation_p.h +++ b/src/corelib/animation/qpropertyanimation_p.h @@ -55,7 +55,7 @@ #include "private/qvariantanimation_p.h" -#ifndef QT_NO_ANIMATION +QT_REQUIRE_CONFIG(animation); QT_BEGIN_NAMESPACE @@ -83,6 +83,4 @@ public: QT_END_NAMESPACE -#endif //QT_NO_ANIMATION - #endif //QPROPERTYANIMATION_P_H diff --git a/src/corelib/animation/qsequentialanimationgroup.cpp b/src/corelib/animation/qsequentialanimationgroup.cpp index f5f538337e..8af6b33722 100644 --- a/src/corelib/animation/qsequentialanimationgroup.cpp +++ b/src/corelib/animation/qsequentialanimationgroup.cpp @@ -83,8 +83,6 @@ #include -#ifndef QT_NO_ANIMATION - QT_BEGIN_NAMESPACE typedef QList::ConstIterator AnimationListConstIt; @@ -582,5 +580,3 @@ void QSequentialAnimationGroupPrivate::animationRemoved(int index, QAbstractAnim QT_END_NAMESPACE #include "moc_qsequentialanimationgroup.cpp" - -#endif //QT_NO_ANIMATION diff --git a/src/corelib/animation/qsequentialanimationgroup.h b/src/corelib/animation/qsequentialanimationgroup.h index 1c8e67d256..a33ff07abf 100644 --- a/src/corelib/animation/qsequentialanimationgroup.h +++ b/src/corelib/animation/qsequentialanimationgroup.h @@ -42,11 +42,10 @@ #include +QT_REQUIRE_CONFIG(animation); + QT_BEGIN_NAMESPACE - -#ifndef QT_NO_ANIMATION - class QPauseAnimation; class QSequentialAnimationGroupPrivate; @@ -82,8 +81,6 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_uncontrolledAnimationFinished()) }; -#endif //QT_NO_ANIMATION - QT_END_NAMESPACE #endif //QSEQUENTIALANIMATIONGROUP_H diff --git a/src/corelib/animation/qsequentialanimationgroup_p.h b/src/corelib/animation/qsequentialanimationgroup_p.h index e4f3d9c96a..88dac4f566 100644 --- a/src/corelib/animation/qsequentialanimationgroup_p.h +++ b/src/corelib/animation/qsequentialanimationgroup_p.h @@ -54,7 +54,7 @@ #include "qsequentialanimationgroup.h" #include "private/qanimationgroup_p.h" -#ifndef QT_NO_ANIMATION +QT_REQUIRE_CONFIG(animation); QT_BEGIN_NAMESPACE @@ -107,6 +107,4 @@ public: QT_END_NAMESPACE -#endif //QT_NO_ANIMATION - #endif //QSEQUENTIALANIMATIONGROUP_P_H diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp index 3c90d71c7d..df533c5f4d 100644 --- a/src/corelib/animation/qvariantanimation.cpp +++ b/src/corelib/animation/qvariantanimation.cpp @@ -46,8 +46,6 @@ #include -#ifndef QT_NO_ANIMATION - QT_BEGIN_NAMESPACE /*! @@ -700,5 +698,3 @@ void QVariantAnimation::updateCurrentTime(int) QT_END_NAMESPACE #include "moc_qvariantanimation.cpp" - -#endif //QT_NO_ANIMATION diff --git a/src/corelib/animation/qvariantanimation.h b/src/corelib/animation/qvariantanimation.h index d6346e1706..e47fa14b1c 100644 --- a/src/corelib/animation/qvariantanimation.h +++ b/src/corelib/animation/qvariantanimation.h @@ -46,11 +46,10 @@ #include #include +QT_REQUIRE_CONFIG(animation); + QT_BEGIN_NAMESPACE - -#ifndef QT_NO_ANIMATION - class QVariantAnimationPrivate; class Q_CORE_EXPORT QVariantAnimation : public QAbstractAnimation { @@ -116,8 +115,6 @@ void qRegisterAnimationInterpolator(QVariant (*func)(const T &from, const T &to, QVariantAnimation::registerInterpolator(reinterpret_cast(reinterpret_cast(func)), qMetaTypeId()); } -#endif //QT_NO_ANIMATION - QT_END_NAMESPACE #endif //QVARIANTANIMATION_H diff --git a/src/corelib/animation/qvariantanimation_p.h b/src/corelib/animation/qvariantanimation_p.h index 9f0f2e3030..57b59cf876 100644 --- a/src/corelib/animation/qvariantanimation_p.h +++ b/src/corelib/animation/qvariantanimation_p.h @@ -60,7 +60,7 @@ #include -#ifndef QT_NO_ANIMATION +QT_REQUIRE_CONFIG(animation); QT_BEGIN_NAMESPACE @@ -129,6 +129,4 @@ template inline QVariant _q_interpolateVariant(const T &from, const QT_END_NAMESPACE -#endif //QT_NO_ANIMATION - #endif //QVARIANTANIMATION_P_H diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro index 7f62a6f1b0..1e4823f566 100644 --- a/src/corelib/corelib.pro +++ b/src/corelib/corelib.pro @@ -31,7 +31,7 @@ ANDROID_PERMISSIONS = \ # OpenBSD 6.0 will include environ in libc. freebsd|openbsd: QMAKE_LFLAGS_NOUNDEF = -include(animation/animation.pri) +qtConfig(animation): include(animation/animation.pri) include(global/global.pri) include(thread/thread.pri) include(tools/tools.pri) diff --git a/src/corelib/statemachine/qabstracttransition.cpp b/src/corelib/statemachine/qabstracttransition.cpp index 272e681fb4..ebf33e120a 100644 --- a/src/corelib/statemachine/qabstracttransition.cpp +++ b/src/corelib/statemachine/qabstracttransition.cpp @@ -334,7 +334,7 @@ QStateMachine *QAbstractTransition::machine() const return d->machine(); } -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) /*! Adds the given \a animation to this transition. diff --git a/src/corelib/statemachine/qabstracttransition.h b/src/corelib/statemachine/qabstracttransition.h index 9b35e0cdb6..18e12d3eb6 100644 --- a/src/corelib/statemachine/qabstracttransition.h +++ b/src/corelib/statemachine/qabstracttransition.h @@ -53,7 +53,7 @@ class QAbstractState; class QState; class QStateMachine; -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) class QAbstractAnimation; #endif @@ -86,7 +86,7 @@ public: QStateMachine *machine() const; -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) void addAnimation(QAbstractAnimation *animation); void removeAnimation(QAbstractAnimation *animation); QList animations() const; diff --git a/src/corelib/statemachine/qabstracttransition_p.h b/src/corelib/statemachine/qabstracttransition_p.h index e11514670e..663d777c75 100644 --- a/src/corelib/statemachine/qabstracttransition_p.h +++ b/src/corelib/statemachine/qabstracttransition_p.h @@ -85,7 +85,7 @@ public: QVector > targetStates; QAbstractTransition::TransitionType transitionType; -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) QList animations; #endif }; diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index 24734f99ac..7388d496d9 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -59,7 +59,7 @@ #include "qeventtransition_p.h" #endif -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) #include "qpropertyanimation.h" #include "qanimationgroup.h" #include @@ -167,7 +167,7 @@ QT_BEGIN_NAMESPACE \sa start(), stop(), started(), stopped(), runningChanged() */ -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) /*! \property QStateMachine::animated @@ -401,7 +401,7 @@ QStateMachinePrivate::QStateMachinePrivate() error = QStateMachine::NoError; globalRestorePolicy = QState::DontRestoreProperties; signalEventGenerator = 0; -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) animated = true; #endif } @@ -700,12 +700,12 @@ void QStateMachinePrivate::microstep(QEvent *event, const QList selectedAnimations = selectAnimations(enabledTransitions); #endif enterStates(event, exitedStates, enteredStates, statesForDefaultEntry, assignmentsForEnteredStates -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) , selectedAnimations #endif ); @@ -827,7 +827,7 @@ void QStateMachinePrivate::exitStates(QEvent *event, const QListcallOnExit(event); -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) terminateActiveAnimations(s, assignmentsForEnteredStates); #else Q_UNUSED(assignmentsForEnteredStates); @@ -942,7 +942,7 @@ void QStateMachinePrivate::enterStates(QEvent *event, const QList &statesToEnter_sorted, const QSet &statesForDefaultEntry, QHash > &propertyAssignmentsForState -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) , const QList &selectedAnimations #endif ) @@ -958,7 +958,7 @@ void QStateMachinePrivate::enterStates(QEvent *event, const QList pendingRestorables; QHash > assignmentsForEnteredStates = computePropertyAssignments(enteredStates, pendingRestorables); -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) QList selectedAnimations = selectAnimations(transitions); #endif // enterStates() will set stopProcessingReason to Finished if a final @@ -1822,7 +1822,7 @@ void QStateMachinePrivate::_q_start() stopProcessingReason = EventQueueEmpty; enterStates(&nullEvent, exitedStates, enteredStates, statesForDefaultEntry, assignmentsForEnteredStates -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) , selectedAnimations #endif ); @@ -2957,7 +2957,7 @@ void QStateMachine::onExit(QEvent *event) QState::onExit(event); } -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) /*! Returns whether animations are enabled for this state machine. @@ -3004,7 +3004,7 @@ void QStateMachine::removeDefaultAnimation(QAbstractAnimation *animation) d->defaultAnimations.removeAll(animation); } -#endif // QT_NO_ANIMATION +#endif // animation // Begin moc-generated code -- modify carefully (check "HAND EDIT" parts)! diff --git a/src/corelib/statemachine/qstatemachine.h b/src/corelib/statemachine/qstatemachine.h index fd90b86fd5..e520285437 100644 --- a/src/corelib/statemachine/qstatemachine.h +++ b/src/corelib/statemachine/qstatemachine.h @@ -60,7 +60,7 @@ class Q_CORE_EXPORT QStateMachine : public QState Q_PROPERTY(QString errorString READ errorString) Q_PROPERTY(QState::RestorePolicy globalRestorePolicy READ globalRestorePolicy WRITE setGlobalRestorePolicy) Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged) -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) Q_PROPERTY(bool animated READ isAnimated WRITE setAnimated) #endif public: @@ -122,14 +122,14 @@ public: bool isRunning() const; -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) bool isAnimated() const; void setAnimated(bool enabled); void addDefaultAnimation(QAbstractAnimation *animation); QList defaultAnimations() const; void removeDefaultAnimation(QAbstractAnimation *animation); -#endif // QT_NO_ANIMATION +#endif // animation QState::RestorePolicy globalRestorePolicy() const; void setGlobalRestorePolicy(QState::RestorePolicy restorePolicy); @@ -175,7 +175,7 @@ private: Q_DECLARE_PRIVATE(QStateMachine) Q_PRIVATE_SLOT(d_func(), void _q_start()) Q_PRIVATE_SLOT(d_func(), void _q_process()) -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) Q_PRIVATE_SLOT(d_func(), void _q_animationFinished()) #endif Q_PRIVATE_SLOT(d_func(), void _q_startDelayedEventTimer(int, int)) diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h index c28b162305..f3366ca5f7 100644 --- a/src/corelib/statemachine/qstatemachine_p.h +++ b/src/corelib/statemachine/qstatemachine_p.h @@ -297,7 +297,7 @@ public: void initializeAnimations(QAbstractState *state, const QList &selectedAnimations, const QList &exitedStates_sorted, QHash > &assignmentsForEnteredStates); -#endif // QT_NO_ANIMATION +#endif // animation QSignalEventGenerator *signalEventGenerator; diff --git a/src/gui/animation/qguivariantanimation.cpp b/src/gui/animation/qguivariantanimation.cpp index b72764e048..a5b6d8b95c 100644 --- a/src/gui/animation/qguivariantanimation.cpp +++ b/src/gui/animation/qguivariantanimation.cpp @@ -38,8 +38,6 @@ ****************************************************************************/ #include -#ifndef QT_NO_ANIMATION - #include #include #include @@ -90,5 +88,3 @@ static void qUnregisterGuiGetInterpolator() Q_DESTRUCTOR_FUNCTION(qUnregisterGuiGetInterpolator) QT_END_NAMESPACE - -#endif //QT_NO_ANIMATION diff --git a/src/gui/gui.pro b/src/gui/gui.pro index 759d6f3cbf..06c9cd3939 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -45,7 +45,7 @@ include(painting/painting.pri) include(util/util.pri) include(math3d/math3d.pri) include(opengl/opengl.pri) -include(animation/animation.pri) +qtConfig(animation): include(animation/animation.pri) include(itemmodels/itemmodels.pri) include(vulkan/vulkan.pri) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index e81c88cc71..193712a7a7 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -204,7 +204,7 @@ QInputDeviceManager *QGuiApplicationPrivate::m_inputDeviceManager = 0; static qreal fontSmoothingGamma = 1.7; extern void qRegisterGuiVariant(); -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) extern void qRegisterGuiGetInterpolator(); #endif @@ -1517,7 +1517,7 @@ void QGuiApplicationPrivate::init() // trigger registering of QVariant's GUI types qRegisterGuiVariant(); -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) // trigger registering of animation interpolators qRegisterGuiGetInterpolator(); #endif diff --git a/src/widgets/configure.json b/src/widgets/configure.json index b3a5227d26..cc9019dfdd 100644 --- a/src/widgets/configure.json +++ b/src/widgets/configure.json @@ -47,7 +47,7 @@ }, "style-mac": { "label": "macOS", - "condition": "config.osx", + "condition": "config.osx && features.animation", "output": [ "privateFeature", "styles" ] }, "style-windows": { @@ -56,7 +56,7 @@ }, "style-windowsvista": { "label": "WindowsVista", - "condition": "features.style-windows && config.win32 && !config.winrt && tests.uxtheme", + "condition": "features.style-windows && features.animation && config.win32 && !config.winrt && tests.uxtheme", "output": [ "privateFeature", "styles" ] }, "style-android": { diff --git a/src/widgets/itemviews/qcolumnview.cpp b/src/widgets/itemviews/qcolumnview.cpp index 5100d2a427..1fe17721ba 100644 --- a/src/widgets/itemviews/qcolumnview.cpp +++ b/src/widgets/itemviews/qcolumnview.cpp @@ -103,12 +103,12 @@ void QColumnViewPrivate::initialize() { Q_Q(QColumnView); q->setTextElideMode(Qt::ElideMiddle); -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) QObject::connect(¤tAnimation, SIGNAL(finished()), q, SLOT(_q_changeCurrentColumn())); currentAnimation.setTargetObject(hbar); currentAnimation.setPropertyName("value"); currentAnimation.setEasingCurve(QEasingCurve::InOutQuad); -#endif //QT_NO_ANIMATION +#endif // animation delete itemDelegate; q->setItemDelegate(new QColumnViewDelegate(q)); } @@ -258,12 +258,12 @@ void QColumnView::scrollTo(const QModelIndex &index, ScrollHint hint) if (!index.isValid() || d->columns.isEmpty()) return; -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) if (d->currentAnimation.state() == QPropertyAnimation::Running) return; d->currentAnimation.stop(); -#endif //QT_NO_ANIMATION +#endif // animation // Fill up what is needed to get to index d->closeColumns(index, true); @@ -326,13 +326,13 @@ void QColumnView::scrollTo(const QModelIndex &index, ScrollHint hint) } } -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) if (const int animationDuration = style()->styleHint(QStyle::SH_Widget_Animation_Duration, 0, this)) { d->currentAnimation.setDuration(animationDuration); d->currentAnimation.setEndValue(newScrollbarValue); d->currentAnimation.start(); } else -#endif //QT_NO_ANIMATION +#endif // animation { horizontalScrollBar()->setValue(newScrollbarValue); } @@ -402,10 +402,10 @@ void QColumnView::resizeEvent(QResizeEvent *event) void QColumnViewPrivate::updateScrollbars() { Q_Q(QColumnView); -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) if (currentAnimation.state() == QPropertyAnimation::Running) return; -#endif //QT_NO_ANIMATION +#endif // animation // find the total horizontal length of the laid out columns int horizontalLength = 0; diff --git a/src/widgets/itemviews/qcolumnview_p.h b/src/widgets/itemviews/qcolumnview_p.h index 850ab02747..9f0d2a40dc 100644 --- a/src/widgets/itemviews/qcolumnview_p.h +++ b/src/widgets/itemviews/qcolumnview_p.h @@ -57,7 +57,9 @@ #include #include +#if QT_CONFIG(animation) #include +#endif #include #include #include @@ -169,7 +171,7 @@ public: QVector columnSizes; // used during init and corner moving bool showResizeGrips; int offset; -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) QPropertyAnimation currentAnimation; #endif QWidget *previewWidget; diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index fbfbe56246..7f99a2c6cb 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -1334,12 +1334,12 @@ void QTreeView::paintEvent(QPaintEvent *event) Q_D(QTreeView); d->executePostedLayout(); QPainter painter(viewport()); -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) if (d->isAnimating()) { drawTree(&painter, event->region() - d->animatedOperation.rect()); d->drawAnimatedOperation(&painter); } else -#endif //QT_NO_ANIMATION +#endif // animation { drawTree(&painter, event->region()); #if QT_CONFIG(draganddrop) @@ -3056,10 +3056,10 @@ void QTreeViewPrivate::initialize() header->setStretchLastSection(true); header->setDefaultAlignment(Qt::AlignLeft|Qt::AlignVCenter); q->setHeader(header); -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) animationsEnabled = q->style()->styleHint(QStyle::SH_Widget_Animation_Duration, 0, q) > 0; QObject::connect(&animatedOperation, SIGNAL(finished()), q, SLOT(_q_endAnimatedOperation())); -#endif //QT_NO_ANIMATION +#endif // animation } void QTreeViewPrivate::expand(int item, bool emitSignal) @@ -3072,10 +3072,10 @@ void QTreeViewPrivate::expand(int item, bool emitSignal) if (index.flags() & Qt::ItemNeverHasChildren) return; -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) if (emitSignal && animationsEnabled) prepareAnimatedOperation(item, QVariantAnimation::Forward); -#endif //QT_NO_ANIMATION +#endif // animation //if already animating, stateBeforeAnimation is set to the correct value if (state != QAbstractItemView::AnimatingState) stateBeforeAnimation = state; @@ -3089,10 +3089,10 @@ void QTreeViewPrivate::expand(int item, bool emitSignal) model->fetchMore(index); if (emitSignal) { emit q->expanded(index); -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) if (animationsEnabled) beginAnimatedOperation(); -#endif //QT_NO_ANIMATION +#endif // animation } } @@ -3147,10 +3147,10 @@ void QTreeViewPrivate::collapse(int item, bool emitSignal) if (it == expandedIndexes.end() || viewItems.at(item).expanded == false) return; // nothing to do -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) if (emitSignal && animationsEnabled) prepareAnimatedOperation(item, QVariantAnimation::Backward); -#endif //QT_NO_ANIMATION +#endif // animation //if already animating, stateBeforeAnimation is set to the correct value if (state != QAbstractItemView::AnimatingState) @@ -3168,14 +3168,14 @@ void QTreeViewPrivate::collapse(int item, bool emitSignal) if (emitSignal) { emit q->collapsed(modelIndex); -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) if (animationsEnabled) beginAnimatedOperation(); -#endif //QT_NO_ANIMATION +#endif // animation } } -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) void QTreeViewPrivate::prepareAnimatedOperation(int item, QVariantAnimation::Direction direction) { animatedOperation.item = item; @@ -3280,7 +3280,7 @@ void QTreeViewPrivate::_q_endAnimatedOperation() q->updateGeometries(); viewport->update(); } -#endif //QT_NO_ANIMATION +#endif // animation void QTreeViewPrivate::_q_modelAboutToBeReset() { diff --git a/src/widgets/itemviews/qtreeview.h b/src/widgets/itemviews/qtreeview.h index 09ce0e3fff..33dbf1c1ce 100644 --- a/src/widgets/itemviews/qtreeview.h +++ b/src/widgets/itemviews/qtreeview.h @@ -230,9 +230,9 @@ private: Q_DECLARE_PRIVATE(QTreeView) Q_DISABLE_COPY(QTreeView) -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) Q_PRIVATE_SLOT(d_func(), void _q_endAnimatedOperation()) -#endif //QT_NO_ANIMATION +#endif // animation Q_PRIVATE_SLOT(d_func(), void _q_modelAboutToBeReset()) Q_PRIVATE_SLOT(d_func(), void _q_sortIndicatorChanged(int column, Qt::SortOrder order)) }; diff --git a/src/widgets/itemviews/qtreeview_p.h b/src/widgets/itemviews/qtreeview_p.h index 9a391ee88a..061bd1fc57 100644 --- a/src/widgets/itemviews/qtreeview_p.h +++ b/src/widgets/itemviews/qtreeview_p.h @@ -53,7 +53,9 @@ #include #include "private/qabstractitemview_p.h" +#if QT_CONFIG(animation) #include +#endif #include #include @@ -105,7 +107,7 @@ public: QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const override; void adjustViewOptionsForIndex(QStyleOptionViewItem *option, const QModelIndex ¤t) const override; -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) struct AnimatedOperation : public QVariantAnimation { int item; @@ -123,7 +125,7 @@ public: void drawAnimatedOperation(QPainter *painter) const; QPixmap renderTreeToPixmapForAnimation(const QRect &rect) const; void _q_endAnimatedOperation(); -#endif //QT_NO_ANIMATION +#endif // animation void expand(int item, bool emitSignal); void collapse(int item, bool emitSignal); diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 3b9186e61a..735ae6b080 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -105,7 +105,9 @@ #include #include #include +#if QT_CONFIG(animation) #include +#endif #include @@ -1195,7 +1197,7 @@ void QCommonStylePrivate::tabLayout(const QStyleOptionTab *opt, const QWidget *w } #endif // QT_CONFIG(tabbar) -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) /*! \internal */ QList QCommonStylePrivate::animationTargets() const { diff --git a/src/widgets/styles/qcommonstyle.h b/src/widgets/styles/qcommonstyle.h index f39915295e..78c5171717 100644 --- a/src/widgets/styles/qcommonstyle.h +++ b/src/widgets/styles/qcommonstyle.h @@ -97,7 +97,7 @@ protected: private: Q_DECLARE_PRIVATE(QCommonStyle) Q_DISABLE_COPY(QCommonStyle) -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) Q_PRIVATE_SLOT(d_func(), void _q_removeAnimation()) #endif }; diff --git a/src/widgets/styles/qcommonstyle_p.h b/src/widgets/styles/qcommonstyle_p.h index 93db75ac2d..b347c8563a 100644 --- a/src/widgets/styles/qcommonstyle_p.h +++ b/src/widgets/styles/qcommonstyle_p.h @@ -43,8 +43,9 @@ #include #include "qcommonstyle.h" #include "qstyle_p.h" +#if QT_CONFIG(animation) #include "qstyleanimation_p.h" - +#endif #include "qstyleoption.h" QT_BEGIN_NAMESPACE @@ -76,7 +77,7 @@ public: ~QCommonStylePrivate() { -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) qDeleteAll(animations); #endif #if QT_CONFIG(itemviews) @@ -115,7 +116,7 @@ public: #endif int animationFps; -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) void _q_removeAnimation(); QList animationTargets() const; @@ -125,7 +126,7 @@ public: private: mutable QHash animations; -#endif // QT_NO_ANIMATION +#endif // animation }; QT_END_NAMESPACE diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp index 7474cd23d6..5231f04df9 100644 --- a/src/widgets/styles/qfusionstyle.cpp +++ b/src/widgets/styles/qfusionstyle.cpp @@ -1429,14 +1429,14 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio painter->drawRoundedRect(progressBar.adjusted(1, 1, -1, -1), 1, 1); if (!indeterminate) { -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) (const_cast(d))->stopAnimation(option->styleObject); #endif } else { highlightedGradientStartColor.setAlpha(120); painter->setPen(QPen(highlightedGradientStartColor, 9.0)); painter->setClipRect(progressBar.adjusted(1, 1, -1, -1)); -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) if (QProgressStyleAnimation *animation = qobject_cast(d->animation(option->styleObject))) step = animation->animationStep() % 22; else @@ -2463,7 +2463,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption styleObject->setProperty("_q_stylestate", static_cast(scrollBar->state)); styleObject->setProperty("_q_stylecontrols", static_cast(scrollBar->activeSubControls)); -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) // if the scrollbar is transient or its attributes, geometry or // state has changed, the opacity is reset back to 100% opaque opacity = 1.0; @@ -2481,10 +2481,10 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption } else if (anim && anim->mode() == QScrollbarStyleAnimation::Deactivating) { d->stopAnimation(styleObject); } -#endif // !QT_NO_ANIMATION +#endif // animation } -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) QScrollbarStyleAnimation *anim = qobject_cast(d->animation(styleObject)); if (anim && anim->mode() == QScrollbarStyleAnimation::Deactivating) { // once a scrollbar was active (hovered/pressed), it retains @@ -2513,7 +2513,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption } } painter->setOpacity(opacity); -#endif // !QT_NO_ANIMATION +#endif // animation } bool transient = proxy()->styleHint(SH_ScrollBar_Transient, option, widget); diff --git a/src/widgets/styles/qstyleanimation.cpp b/src/widgets/styles/qstyleanimation.cpp index 0b8e32be19..b9202eae69 100644 --- a/src/widgets/styles/qstyleanimation.cpp +++ b/src/widgets/styles/qstyleanimation.cpp @@ -39,8 +39,6 @@ #include "qstyleanimation_p.h" -#ifndef QT_NO_ANIMATION - #include #include #include @@ -367,5 +365,3 @@ void QScrollbarStyleAnimation::updateCurrentTime(int time) QT_END_NAMESPACE #include "moc_qstyleanimation_p.cpp" - -#endif //QT_NO_ANIMATION diff --git a/src/widgets/styles/qstyleanimation_p.h b/src/widgets/styles/qstyleanimation_p.h index a2ad4a91da..d28fc6ebab 100644 --- a/src/widgets/styles/qstyleanimation_p.h +++ b/src/widgets/styles/qstyleanimation_p.h @@ -45,9 +45,9 @@ #include "qdatetime.h" #include "qimage.h" -QT_BEGIN_NAMESPACE +QT_REQUIRE_CONFIG(animation); -#ifndef QT_NO_ANIMATION +QT_BEGIN_NAMESPACE // // W A R N I N G @@ -201,8 +201,6 @@ private: bool _active; }; -#endif // QT_NO_ANIMATION - QT_END_NAMESPACE #endif // QSTYLEANIMATION_P_H diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index c046ac52f9..ceede9e72f 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -84,7 +84,9 @@ #include #endif #include +#if QT_CONFIG(animation) #include +#endif #if QT_CONFIG(tabbar) #include #endif diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp index 7c9d917784..80ce8419f8 100644 --- a/src/widgets/styles/qwindowsstyle.cpp +++ b/src/widgets/styles/qwindowsstyle.cpp @@ -86,7 +86,9 @@ #include #include +#if QT_CONFIG(animation) #include +#endif #include diff --git a/src/widgets/styles/styles.pri b/src/widgets/styles/styles.pri index 0c0f8b7bc7..821c40af81 100644 --- a/src/widgets/styles/styles.pri +++ b/src/widgets/styles/styles.pri @@ -3,7 +3,6 @@ HEADERS += \ styles/qdrawutil.h \ styles/qstyle.h \ - styles/qstyleanimation_p.h \ styles/qstylefactory.h \ styles/qstyleoption.h \ styles/qstyleplugin.h \ @@ -21,7 +20,6 @@ HEADERS += \ SOURCES += \ styles/qdrawutil.cpp \ styles/qstyle.cpp \ - styles/qstyleanimation.cpp \ styles/qstylefactory.cpp \ styles/qstyleoption.cpp \ styles/qstyleplugin.cpp \ @@ -37,6 +35,11 @@ RESOURCES += styles/qstyle.qrc include($$OUT_PWD/qtwidgets-config.pri) +qtConfig(animation) { + HEADERS += styles/qstyleanimation_p.h + SOURCES += styles/qstyleanimation.cpp +} + qtConfig(style-windows) { HEADERS += styles/qwindowsstyle_p.h styles/qwindowsstyle_p_p.h SOURCES += styles/qwindowsstyle.cpp diff --git a/src/widgets/util/qscroller.cpp b/src/widgets/util/qscroller.cpp index 903a141e49..ea8168b55c 100644 --- a/src/widgets/util/qscroller.cpp +++ b/src/widgets/util/qscroller.cpp @@ -191,7 +191,7 @@ static qreal progressForValue(const QEasingCurve &curve, qreal value) } -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) class QScrollTimer : public QAbstractAnimation { public: @@ -230,7 +230,7 @@ private: bool ignoreUpdate; int skip; }; -#endif // QT_NO_ANIMATION +#endif // animation /*! \class QScroller @@ -896,7 +896,7 @@ QScrollerPrivate::QScrollerPrivate(QScroller *q, QObject *_target) , snapIntervalX(0.0) , snapFirstY(-1.0) , snapIntervalY(0.0) -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) , scrollTimer(new QScrollTimer(this)) #endif , q_ptr(q) @@ -938,7 +938,7 @@ const char *QScrollerPrivate::inputName(QScroller::Input input) void QScrollerPrivate::targetDestroyed() { -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) scrollTimer->stop(); #endif delete q_ptr; @@ -966,7 +966,7 @@ void QScrollerPrivate::timerTick() } } -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) scrollTimer->stop(); #endif } @@ -1690,7 +1690,7 @@ void QScrollerPrivate::setState(QScroller::State newstate) switch (newstate) { case QScroller::Inactive: -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) scrollTimer->stop(); #endif @@ -1702,7 +1702,7 @@ void QScrollerPrivate::setState(QScroller::State newstate) break; case QScroller::Pressed: -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) scrollTimer->stop(); #endif @@ -1712,14 +1712,14 @@ void QScrollerPrivate::setState(QScroller::State newstate) case QScroller::Dragging: dragDistance = QPointF(0, 0); -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) if (state == QScroller::Pressed) scrollTimer->start(); #endif break; case QScroller::Scrolling: -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) scrollTimer->start(); #endif break; diff --git a/src/widgets/util/qscroller_p.h b/src/widgets/util/qscroller_p.h index 5e0c359514..13e2032a5c 100644 --- a/src/widgets/util/qscroller_p.h +++ b/src/widgets/util/qscroller_p.h @@ -64,7 +64,9 @@ #include #include #include +#if QT_CONFIG(animation) #include +#endif QT_BEGIN_NAMESPACE @@ -72,7 +74,7 @@ QT_BEGIN_NAMESPACE class QFlickGestureRecognizer; #endif -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) class QScrollTimer; #endif class QScrollerPrivate : public QObject @@ -196,7 +198,7 @@ public: QElapsedTimer monotonicTimer; QPointF releaseVelocity; // the starting velocity of the scrolling state -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) QScrollTimer *scrollTimer; #endif diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp index 0eeff196a8..cccb44c4ef 100644 --- a/src/widgets/widgets/qlineedit_p.cpp +++ b/src/widgets/widgets/qlineedit_p.cpp @@ -57,7 +57,9 @@ #include "qlist.h" #endif #include +#if QT_CONFIG(animation) #include +#endif #include #include @@ -390,7 +392,7 @@ void QLineEditIconButton::setOpacity(qreal value) } } -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) void QLineEditIconButton::startOpacityAnimation(qreal endValue) { QPropertyAnimation *animation = new QPropertyAnimation(this, QByteArrayLiteral("opacity")); diff --git a/src/widgets/widgets/qlineedit_p.h b/src/widgets/widgets/qlineedit_p.h index 71a67e3d10..7cd91dfc29 100644 --- a/src/widgets/widgets/qlineedit_p.h +++ b/src/widgets/widgets/qlineedit_p.h @@ -89,7 +89,7 @@ public: qreal opacity() const { return m_opacity; } void setOpacity(qreal value); -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) void animateShow(bool visible) { startOpacityAnimation(visible ? 1.0 : 0.0); } #endif @@ -101,7 +101,7 @@ private slots: void updateCursor(); private: -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) void startOpacityAnimation(qreal endValue); #endif QLineEditPrivate *lineEditPrivate() const; diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp index 8af70d0f9c..98e15c8f17 100644 --- a/src/widgets/widgets/qtabbar.cpp +++ b/src/widgets/widgets/qtabbar.cpp @@ -2109,13 +2109,13 @@ void QTabBarPrivate::moveTabFinished(int index) Q_Q(QTabBar); bool cleanup = (pressedIndex == index) || (pressedIndex == -1) || !validIndex(index); bool allAnimationsFinished = true; -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) for(int i = 0; allAnimationsFinished && i < tabList.count(); ++i) { const Tab &t = tabList.at(i); if (t.animation && t.animation->state() == QAbstractAnimation::Running) allAnimationsFinished = false; } -#endif //QT_NO_ANIMATION +#endif // animation if (allAnimationsFinished && cleanup) { if(movingTab) movingTab->setVisible(false); // We might not get a mouse release @@ -2680,7 +2680,7 @@ void CloseButton::paintEvent(QPaintEvent *) style()->drawPrimitive(QStyle::PE_IndicatorTabClose, &opt, &p, this); } -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) void QTabBarPrivate::Tab::TabBarAnimation::updateCurrentValue(const QVariant ¤t) { priv->moveTab(priv->tabList.indexOf(*tab), current.toInt()); diff --git a/src/widgets/widgets/qtabbar_p.h b/src/widgets/widgets/qtabbar_p.h index 1092878f2c..04f07c7cec 100644 --- a/src/widgets/widgets/qtabbar_p.h +++ b/src/widgets/widgets/qtabbar_p.h @@ -58,7 +58,9 @@ #include #include #include +#if QT_CONFIG(animation) #include +#endif #define ANIMATION_DURATION 250 @@ -107,9 +109,9 @@ public: inline Tab(const QIcon &ico, const QString &txt) : enabled(true) , shortcutId(0), text(txt), icon(ico), leftWidget(0), rightWidget(0), lastTab(-1), dragOffset(0) -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) , animation(0) -#endif //QT_NO_ANIMATION +#endif // animation {} bool operator==(const Tab &other) const { return &other == this; } bool enabled; @@ -136,7 +138,7 @@ public: QString accessibleName; #endif -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) ~Tab() { delete animation; } struct TabBarAnimation : public QVariantAnimation { TabBarAnimation(Tab *t, QTabBarPrivate *_priv) : tab(t), priv(_priv) @@ -166,7 +168,7 @@ public: #else void startAnimation(QTabBarPrivate *priv, int duration) { Q_UNUSED(duration); priv->moveTabFinished(priv->tabList.indexOf(*this)); } -#endif //QT_NO_ANIMATION +#endif // animation }; QList tabList; mutable QHash textSizes; diff --git a/src/widgets/widgets/qwidgetanimator.cpp b/src/widgets/widgets/qwidgetanimator.cpp index b6828a14ef..b1e527e3b6 100644 --- a/src/widgets/widgets/qwidgetanimator.cpp +++ b/src/widgets/widgets/qwidgetanimator.cpp @@ -37,15 +37,17 @@ ** ****************************************************************************/ +#include "qwidgetanimator_p.h" + +#if QT_CONFIG(animation) #include +#endif #include #include #if QT_CONFIG(mainwindow) #include #endif -#include "qwidgetanimator_p.h" - QT_BEGIN_NAMESPACE QWidgetAnimator::QWidgetAnimator(QMainWindowLayout *layout) : m_mainWindowLayout(layout) @@ -54,7 +56,7 @@ QWidgetAnimator::QWidgetAnimator(QMainWindowLayout *layout) : m_mainWindowLayout void QWidgetAnimator::abort(QWidget *w) { -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) const auto it = m_animation_map.constFind(w); if (it == m_animation_map.cend()) return; @@ -68,16 +70,16 @@ void QWidgetAnimator::abort(QWidget *w) #endif #else Q_UNUSED(w); //there is no animation to abort -#endif //QT_NO_ANIMATION +#endif // animation } -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) void QWidgetAnimator::animationFinished() { QPropertyAnimation *anim = qobject_cast(sender()); abort(static_cast(anim->targetObject())); } -#endif //QT_NO_ANIMATION +#endif // animation void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, bool animate) { @@ -91,7 +93,7 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo const QRect final_geometry = _final_geometry.isValid() || widget->isWindow() ? _final_geometry : QRect(QPoint(-500 - widget->width(), -500 - widget->height()), widget->size()); -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) //If the QStyle has animations, animate if (const int animationDuration = widget->style()->styleHint(QStyle::SH_Widget_Animation_Duration, 0, widget)) { AnimationMap::const_iterator it = m_animation_map.constFind(widget); @@ -106,7 +108,7 @@ void QWidgetAnimator::animate(QWidget *widget, const QRect &_final_geometry, boo connect(anim, SIGNAL(finished()), SLOT(animationFinished())); anim->start(QPropertyAnimation::DeleteWhenStopped); } else -#endif //QT_NO_ANIMATION +#endif // animation { //we do it in one shot widget->setGeometry(final_geometry); diff --git a/src/widgets/widgets/qwidgetanimator_p.h b/src/widgets/widgets/qwidgetanimator_p.h index 90be22c271..920cc3ffc8 100644 --- a/src/widgets/widgets/qwidgetanimator_p.h +++ b/src/widgets/widgets/qwidgetanimator_p.h @@ -73,7 +73,7 @@ public: void abort(QWidget *widget); -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) private Q_SLOTS: void animationFinished(); #endif diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index 1ea1843abe..34cdcd5bf7 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -112,7 +112,7 @@ private slots: void expandAndCollapse(); void expandAndCollapseAll(); void expandWithNoChildren(); -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) void quickExpandCollapse(); #endif void keyboardNavigation(); @@ -4401,7 +4401,7 @@ void tst_QTreeView::testInitialFocus() QCOMPARE(treeWidget.currentIndex().column(), 2); } -#ifndef QT_NO_ANIMATION +#if QT_CONFIG(animation) void tst_QTreeView::quickExpandCollapse() { //this unit tests makes sure the state after the animation is restored correctly @@ -4433,7 +4433,7 @@ void tst_QTreeView::quickExpandCollapse() QCOMPARE(tree.state(), initialState); } -#endif +#endif // animation void tst_QTreeView::taskQTBUG_37813_crash() { From 4e7b58629a0a431fbd5c0ba287c3958efd05da13 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Thu, 13 Sep 2018 12:45:20 +0200 Subject: [PATCH 0009/1650] Modernize the "big_codecs" feature Change-Id: Ic23f4a1f81a21711cd81aaa2942b493aca5b38b8 Reviewed-by: Edward Welbourne Reviewed-by: Oswald Buddenhagen --- src/corelib/codecs/codecs.pri | 32 +++++++++++++++------------- src/corelib/codecs/qbig5codec.cpp | 2 -- src/corelib/codecs/qbig5codec_p.h | 6 ++---- src/corelib/codecs/qeucjpcodec.cpp | 3 --- src/corelib/codecs/qeucjpcodec_p.h | 6 ++---- src/corelib/codecs/qeuckrcodec.cpp | 3 --- src/corelib/codecs/qeuckrcodec_p.h | 6 ++---- src/corelib/codecs/qgb18030codec.cpp | 4 ---- src/corelib/codecs/qgb18030codec_p.h | 6 ++---- src/corelib/codecs/qjiscodec.cpp | 3 --- src/corelib/codecs/qjiscodec_p.h | 6 ++---- src/corelib/codecs/qjpunicode.cpp | 4 ---- src/corelib/codecs/qjpunicode_p.h | 6 ++---- src/corelib/codecs/qsjiscodec.cpp | 2 -- src/corelib/codecs/qsjiscodec_p.h | 6 ++---- src/corelib/codecs/qtextcodec.cpp | 8 +++---- 16 files changed, 35 insertions(+), 68 deletions(-) diff --git a/src/corelib/codecs/codecs.pri b/src/corelib/codecs/codecs.pri index dc8974d13f..5af388a149 100644 --- a/src/corelib/codecs/codecs.pri +++ b/src/corelib/codecs/codecs.pri @@ -23,22 +23,24 @@ qtConfig(icu) { SOURCES += \ codecs/qicucodec.cpp } else { - HEADERS += \ - codecs/qgb18030codec_p.h \ - codecs/qeucjpcodec_p.h \ - codecs/qjiscodec_p.h \ - codecs/qsjiscodec_p.h \ - codecs/qeuckrcodec_p.h \ - codecs/qbig5codec_p.h + qtConfig(big_codecs) { + HEADERS += \ + codecs/qgb18030codec_p.h \ + codecs/qeucjpcodec_p.h \ + codecs/qjiscodec_p.h \ + codecs/qsjiscodec_p.h \ + codecs/qeuckrcodec_p.h \ + codecs/qbig5codec_p.h - SOURCES += \ - codecs/qgb18030codec.cpp \ - codecs/qjpunicode.cpp \ - codecs/qeucjpcodec.cpp \ - codecs/qjiscodec.cpp \ - codecs/qsjiscodec.cpp \ - codecs/qeuckrcodec.cpp \ - codecs/qbig5codec.cpp + SOURCES += \ + codecs/qgb18030codec.cpp \ + codecs/qjpunicode.cpp \ + codecs/qeucjpcodec.cpp \ + codecs/qjiscodec.cpp \ + codecs/qsjiscodec.cpp \ + codecs/qeuckrcodec.cpp \ + codecs/qbig5codec.cpp + } qtConfig(iconv) { HEADERS += codecs/qiconvcodec_p.h diff --git a/src/corelib/codecs/qbig5codec.cpp b/src/corelib/codecs/qbig5codec.cpp index bfd07408b8..381bf3f790 100644 --- a/src/corelib/codecs/qbig5codec.cpp +++ b/src/corelib/codecs/qbig5codec.cpp @@ -41,7 +41,6 @@ QT_BEGIN_NAMESPACE -#ifndef QT_NO_BIG_CODECS static int qt_Big5hkscsToUnicode(const uchar *s, uint *pwc); static int qt_UnicodeToBig5hkscs(uint wc, uchar *r); @@ -12661,6 +12660,5 @@ int qt_UnicodeToBig5hkscs (uint wc, uchar *r) /* ====================================================================== */ -#endif // QT_NO_BIG_CODECS QT_END_NAMESPACE diff --git a/src/corelib/codecs/qbig5codec_p.h b/src/corelib/codecs/qbig5codec_p.h index 9dbcf41a6d..2db8377ee3 100644 --- a/src/corelib/codecs/qbig5codec_p.h +++ b/src/corelib/codecs/qbig5codec_p.h @@ -59,9 +59,9 @@ #include #include -QT_BEGIN_NAMESPACE +QT_REQUIRE_CONFIG(big_codecs); -#ifndef QT_NO_BIG_CODECS +QT_BEGIN_NAMESPACE class QBig5Codec : public QTextCodec { public: @@ -91,8 +91,6 @@ public: QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const; }; -#endif // QT_NO_BIG_CODECS - QT_END_NAMESPACE #endif // QBIG5CODEC_P_H diff --git a/src/corelib/codecs/qeucjpcodec.cpp b/src/corelib/codecs/qeucjpcodec.cpp index c3131fe601..3192f355d8 100644 --- a/src/corelib/codecs/qeucjpcodec.cpp +++ b/src/corelib/codecs/qeucjpcodec.cpp @@ -76,8 +76,6 @@ QT_BEGIN_NAMESPACE -#ifndef QT_NO_BIG_CODECS - static const uchar Ss2 = 0x8e; // Single Shift 2 static const uchar Ss3 = 0x8f; // Single Shift 3 @@ -255,6 +253,5 @@ QByteArray QEucJpCodec::_name() { return "EUC-JP"; } -#endif // QT_NO_BIG_CODECS QT_END_NAMESPACE diff --git a/src/corelib/codecs/qeucjpcodec_p.h b/src/corelib/codecs/qeucjpcodec_p.h index 98ad286e9e..535e830ad0 100644 --- a/src/corelib/codecs/qeucjpcodec_p.h +++ b/src/corelib/codecs/qeucjpcodec_p.h @@ -84,9 +84,9 @@ #include #include -QT_BEGIN_NAMESPACE +QT_REQUIRE_CONFIG(big_codecs); -#ifndef QT_NO_BIG_CODECS +QT_BEGIN_NAMESPACE class QEucJpCodec : public QTextCodec { public: @@ -108,8 +108,6 @@ protected: const QJpUnicodeConv *conv; }; -#endif // QT_NO_BIG_CODECS - QT_END_NAMESPACE #endif // QEUCJPCODEC_P_H diff --git a/src/corelib/codecs/qeuckrcodec.cpp b/src/corelib/codecs/qeuckrcodec.cpp index ec5253c7f9..47657cc01f 100644 --- a/src/corelib/codecs/qeuckrcodec.cpp +++ b/src/corelib/codecs/qeuckrcodec.cpp @@ -72,7 +72,6 @@ QT_BEGIN_NAMESPACE -#ifndef QT_NO_BIG_CODECS unsigned int qt_Ksc5601ToUnicode(unsigned int code); unsigned int qt_UnicodeToKsc5601(unsigned int unicode); @@ -3523,6 +3522,4 @@ QString QCP949Codec::convertToUnicode(const char* chars, int len, ConverterState return result; } -#endif // QT_NO_BIG_CODECS - QT_END_NAMESPACE diff --git a/src/corelib/codecs/qeuckrcodec_p.h b/src/corelib/codecs/qeuckrcodec_p.h index 2cf950a350..9e85ca8c20 100644 --- a/src/corelib/codecs/qeuckrcodec_p.h +++ b/src/corelib/codecs/qeuckrcodec_p.h @@ -80,9 +80,9 @@ #include #include -QT_BEGIN_NAMESPACE +QT_REQUIRE_CONFIG(big_codecs); -#ifndef QT_NO_BIG_CODECS +QT_BEGIN_NAMESPACE class QEucKrCodec : public QTextCodec { public: @@ -112,8 +112,6 @@ public: QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const; }; -#endif // QT_NO_BIG_CODECS - QT_END_NAMESPACE #endif // QEUCKRCODEC_P_H diff --git a/src/corelib/codecs/qgb18030codec.cpp b/src/corelib/codecs/qgb18030codec.cpp index 04e4bef4cd..4206eacb6f 100644 --- a/src/corelib/codecs/qgb18030codec.cpp +++ b/src/corelib/codecs/qgb18030codec.cpp @@ -45,8 +45,6 @@ #include "qgb18030codec_p.h" -#ifndef QT_NO_BIG_CODECS - QT_BEGIN_NAMESPACE #define InRange(c, lower, upper) (((c) >= (lower)) && ((c) <= (upper))) @@ -9116,5 +9114,3 @@ int qt_UnicodeToGbk(uint uni, uchar *gbchar) { } QT_END_NAMESPACE - -#endif // QT_NO_BIG_CODECS diff --git a/src/corelib/codecs/qgb18030codec_p.h b/src/corelib/codecs/qgb18030codec_p.h index dd136aeddb..2fea21b5b3 100644 --- a/src/corelib/codecs/qgb18030codec_p.h +++ b/src/corelib/codecs/qgb18030codec_p.h @@ -57,9 +57,9 @@ #include #include -QT_BEGIN_NAMESPACE +QT_REQUIRE_CONFIG(big_codecs); -#ifndef QT_NO_BIG_CODECS +QT_BEGIN_NAMESPACE class QGb18030Codec : public QTextCodec { public: @@ -108,8 +108,6 @@ public: QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const; }; -#endif // QT_NO_BIG_CODECS - QT_END_NAMESPACE #endif // QGB18030CODEC_P_H diff --git a/src/corelib/codecs/qjiscodec.cpp b/src/corelib/codecs/qjiscodec.cpp index a8625db054..77ec2adafd 100644 --- a/src/corelib/codecs/qjiscodec.cpp +++ b/src/corelib/codecs/qjiscodec.cpp @@ -52,7 +52,6 @@ QT_BEGIN_NAMESPACE -#ifndef QT_NO_BIG_CODECS enum { Esc = 0x1b, So = 0x0e, // Shift Out @@ -369,6 +368,4 @@ QList QJisCodec::_aliases() return list; } -#endif // QT_NO_BIG_CODECS - QT_END_NAMESPACE diff --git a/src/corelib/codecs/qjiscodec_p.h b/src/corelib/codecs/qjiscodec_p.h index 4db8728817..c3eda25bdf 100644 --- a/src/corelib/codecs/qjiscodec_p.h +++ b/src/corelib/codecs/qjiscodec_p.h @@ -84,9 +84,9 @@ #include #include -QT_BEGIN_NAMESPACE +QT_REQUIRE_CONFIG(big_codecs); -#ifndef QT_NO_BIG_CODECS +QT_BEGIN_NAMESPACE class QJisCodec : public QTextCodec { public: @@ -108,8 +108,6 @@ protected: const QJpUnicodeConv *conv; }; -#endif // QT_NO_BIG_CODECS - QT_END_NAMESPACE #endif // QJISCODEC_P_H diff --git a/src/corelib/codecs/qjpunicode.cpp b/src/corelib/codecs/qjpunicode.cpp index 0209843ecf..a3f3448bb6 100644 --- a/src/corelib/codecs/qjpunicode.cpp +++ b/src/corelib/codecs/qjpunicode.cpp @@ -50,8 +50,6 @@ QT_BEGIN_NAMESPACE -#ifndef QT_NO_BIG_CODECS - #define USE_JISX0212 #define Q_STRICT @@ -10734,6 +10732,4 @@ uint QJpUnicodeConv::unicodeToCp932(uint h, uint l) const \internal */ -#endif // QT_NO_BIG_CODECS - QT_END_NAMESPACE diff --git a/src/corelib/codecs/qjpunicode_p.h b/src/corelib/codecs/qjpunicode_p.h index 4fa2b9f757..9d1cdf3bf0 100644 --- a/src/corelib/codecs/qjpunicode_p.h +++ b/src/corelib/codecs/qjpunicode_p.h @@ -82,9 +82,9 @@ #include -QT_BEGIN_NAMESPACE +QT_REQUIRE_CONFIG(big_codecs); -#ifndef QT_NO_BIG_CODECS +QT_BEGIN_NAMESPACE class QJpUnicodeConv { public: @@ -180,8 +180,6 @@ private: int rule; }; -#endif // QT_NO_BIG_CODECS - QT_END_NAMESPACE #endif // QJPUNICODE_P_H diff --git a/src/corelib/codecs/qsjiscodec.cpp b/src/corelib/codecs/qsjiscodec.cpp index ba342c9c53..4f5f9069cd 100644 --- a/src/corelib/codecs/qsjiscodec.cpp +++ b/src/corelib/codecs/qsjiscodec.cpp @@ -52,7 +52,6 @@ QT_BEGIN_NAMESPACE -#ifndef QT_NO_BIG_CODECS enum { Esc = 0x1b }; @@ -223,6 +222,5 @@ QList QSjisCodec::_aliases() << "MS_Kanji"; return list; } -#endif // QT_NO_BIG_CODECS QT_END_NAMESPACE diff --git a/src/corelib/codecs/qsjiscodec_p.h b/src/corelib/codecs/qsjiscodec_p.h index 7dfa6f7fe4..9d7ea5d6d2 100644 --- a/src/corelib/codecs/qsjiscodec_p.h +++ b/src/corelib/codecs/qsjiscodec_p.h @@ -84,9 +84,9 @@ #include #include -QT_BEGIN_NAMESPACE +QT_REQUIRE_CONFIG(big_codecs); -#ifndef QT_NO_BIG_CODECS +QT_BEGIN_NAMESPACE class QSjisCodec : public QTextCodec { public: @@ -108,8 +108,6 @@ protected: const QJpUnicodeConv *conv; }; -#endif // QT_NO_BIG_CODECS - QT_END_NAMESPACE #endif // QSJISCODEC_P_H diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp index 1541c498e6..58fc72c9ce 100644 --- a/src/corelib/codecs/qtextcodec.cpp +++ b/src/corelib/codecs/qtextcodec.cpp @@ -69,7 +69,7 @@ # include "qwindowscodec_p.h" #endif # include "qsimplecodec_p.h" -#if !defined(QT_NO_BIG_CODECS) +#if QT_CONFIG(big_codecs) # ifndef Q_OS_INTEGRITY # include "qgb18030codec_p.h" # include "qeucjpcodec_p.h" @@ -78,7 +78,7 @@ # include "qeuckrcodec_p.h" # include "qbig5codec_p.h" # endif // !Q_OS_INTEGRITY -#endif // !QT_NO_BIG_CODECS +#endif // big_codecs #endif // icu #endif // QT_BOOTSTRAPPED @@ -275,7 +275,7 @@ static void setup() for (int i = 0; i < QSimpleTextCodec::numSimpleCodecs; ++i) (void)new QSimpleTextCodec(i); -# if !defined(QT_NO_BIG_CODECS) && !defined(Q_OS_INTEGRITY) +# if QT_CONFIG(big_codecs) && !defined(Q_OS_INTEGRITY) (void)new QGb18030Codec; (void)new QGbkCodec; (void)new QGb2312Codec; @@ -286,7 +286,7 @@ static void setup() (void)new QCP949Codec; (void)new QBig5Codec; (void)new QBig5hkscsCodec; -# endif // !QT_NO_BIG_CODECS && !Q_OS_INTEGRITY +# endif // big_codecs && !Q_OS_INTEGRITY #if QT_CONFIG(iconv) (void) new QIconvCodec; #endif From 9c8ca26a4829d5ce810c9653fec3dfe48717f0b1 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Fri, 28 Sep 2018 10:33:48 +0200 Subject: [PATCH 0010/1650] Modernize the "codecs" feature Change-Id: Idee19112581bff64a2e0b8e331dd3d779aca165b Reviewed-by: Edward Welbourne Reviewed-by: Oswald Buddenhagen --- src/corelib/codecs/codecs.pri | 14 ++++++++++---- src/corelib/codecs/qicucodec.cpp | 2 +- src/corelib/codecs/qisciicodec.cpp | 4 ---- src/corelib/codecs/qisciicodec_p.h | 6 ++---- src/corelib/codecs/qtextcodec.cpp | 6 ++++-- src/corelib/codecs/qtsciicodec.cpp | 4 ---- src/corelib/codecs/qtsciicodec_p.h | 6 ++---- src/corelib/global/qconfig-bootstrapped.h | 1 - 8 files changed, 19 insertions(+), 24 deletions(-) diff --git a/src/corelib/codecs/codecs.pri b/src/corelib/codecs/codecs.pri index 5af388a149..d86d446c72 100644 --- a/src/corelib/codecs/codecs.pri +++ b/src/corelib/codecs/codecs.pri @@ -1,22 +1,28 @@ # Qt core library codecs module HEADERS += \ - codecs/qisciicodec_p.h \ codecs/qlatincodec_p.h \ codecs/qsimplecodec_p.h \ codecs/qtextcodec_p.h \ codecs/qtextcodec.h \ - codecs/qtsciicodec_p.h \ codecs/qutfcodec_p.h SOURCES += \ - codecs/qisciicodec.cpp \ codecs/qlatincodec.cpp \ codecs/qsimplecodec.cpp \ codecs/qtextcodec.cpp \ - codecs/qtsciicodec.cpp \ codecs/qutfcodec.cpp +qtConfig(codecs) { + HEADERS += \ + codecs/qisciicodec_p.h \ + codecs/qtsciicodec_p.h + + SOURCES += \ + codecs/qisciicodec.cpp \ + codecs/qtsciicodec.cpp +} + qtConfig(icu) { HEADERS += \ codecs/qicucodec_p.h diff --git a/src/corelib/codecs/qicucodec.cpp b/src/corelib/codecs/qicucodec.cpp index ee9f1d0048..06a6d95e82 100644 --- a/src/corelib/codecs/qicucodec.cpp +++ b/src/corelib/codecs/qicucodec.cpp @@ -373,7 +373,7 @@ static QTextCodec *loadQtCodec(const char *name) return new QUtf32LECodec; if (!strcmp(name, "ISO-8859-16") || !strcmp(name, "latin10") || !strcmp(name, "iso-ir-226")) return new QSimpleTextCodec(13 /* == 8859-16*/); -#ifndef QT_NO_CODECS +#if QT_CONFIG(codecs) if (!strcmp(name, "TSCII")) return new QTsciiCodec; if (!qstrnicmp(name, "iscii", 5)) diff --git a/src/corelib/codecs/qisciicodec.cpp b/src/corelib/codecs/qisciicodec.cpp index 499e8549a7..d9a86d77c7 100644 --- a/src/corelib/codecs/qisciicodec.cpp +++ b/src/corelib/codecs/qisciicodec.cpp @@ -40,8 +40,6 @@ #include "qtextcodec_p.h" #include "qlist.h" -#ifndef QT_NO_CODECS - QT_BEGIN_NAMESPACE /*! @@ -291,5 +289,3 @@ QString QIsciiCodec::convertToUnicode(const char* chars, int len, ConverterState } QT_END_NAMESPACE - -#endif // QT_NO_CODECS diff --git a/src/corelib/codecs/qisciicodec_p.h b/src/corelib/codecs/qisciicodec_p.h index f818e7d83e..2c1b3ca9e0 100644 --- a/src/corelib/codecs/qisciicodec_p.h +++ b/src/corelib/codecs/qisciicodec_p.h @@ -54,9 +54,9 @@ #include #include "QtCore/qtextcodec.h" -QT_BEGIN_NAMESPACE +QT_REQUIRE_CONFIG(codecs); -#ifndef QT_NO_CODECS +QT_BEGIN_NAMESPACE class QIsciiCodec : public QTextCodec { public: @@ -75,8 +75,6 @@ private: int idx; }; -#endif // QT_NO_CODECS - QT_END_NAMESPACE #endif // QISCIICODEC_P_H diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp index 58fc72c9ce..790921610a 100644 --- a/src/corelib/codecs/qtextcodec.cpp +++ b/src/corelib/codecs/qtextcodec.cpp @@ -57,8 +57,10 @@ #include "qlatincodec_p.h" #if !defined(QT_BOOTSTRAPPED) +#if QT_CONFIG(codecs) # include "qtsciicodec_p.h" # include "qisciicodec_p.h" +#endif #if QT_CONFIG(icu) #include "qicucodec_p.h" #else @@ -268,7 +270,7 @@ static void setup() return; initialized = true; -#if !defined(QT_NO_CODECS) && !defined(QT_BOOTSTRAPPED) +#if QT_CONFIG(codecs) && !defined(QT_BOOTSTRAPPED) (void)new QTsciiCodec; for (int i = 0; i < 9; ++i) (void)new QIsciiCodec(i); @@ -293,7 +295,7 @@ static void setup() #if defined(Q_OS_WIN32) (void) new QWindowsLocalCodec; #endif // Q_OS_WIN32 -#endif // !QT_NO_CODECS && !QT_BOOTSTRAPPED +#endif // codecs && !QT_BOOTSTRAPPED (void)new QUtf16Codec; (void)new QUtf16BECodec; diff --git a/src/corelib/codecs/qtsciicodec.cpp b/src/corelib/codecs/qtsciicodec.cpp index 49f38d1789..936fc4206d 100644 --- a/src/corelib/codecs/qtsciicodec.cpp +++ b/src/corelib/codecs/qtsciicodec.cpp @@ -44,8 +44,6 @@ #include "qtsciicodec_p.h" #include "qlist.h" -#ifndef QT_NO_CODECS - QT_BEGIN_NAMESPACE static unsigned char qt_UnicodeToTSCII(ushort u1, ushort u2, ushort u3); @@ -493,5 +491,3 @@ static unsigned int qt_TSCIIToUnicode(uint code, uint *s) } QT_END_NAMESPACE - -#endif // QT_NO_CODECS diff --git a/src/corelib/codecs/qtsciicodec_p.h b/src/corelib/codecs/qtsciicodec_p.h index 78f9350a19..9247098e36 100644 --- a/src/corelib/codecs/qtsciicodec_p.h +++ b/src/corelib/codecs/qtsciicodec_p.h @@ -83,9 +83,9 @@ #include #include "QtCore/qtextcodec.h" -QT_BEGIN_NAMESPACE +QT_REQUIRE_CONFIG(codecs); -#ifndef QT_NO_CODECS +QT_BEGIN_NAMESPACE class QTsciiCodec : public QTextCodec { public: @@ -98,8 +98,6 @@ public: QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const override; }; -#endif // QT_NO_CODECS - QT_END_NAMESPACE #endif // QTSCIICODEC_P_H diff --git a/src/corelib/global/qconfig-bootstrapped.h b/src/corelib/global/qconfig-bootstrapped.h index 499fd4c9e8..da66e3bcd3 100644 --- a/src/corelib/global/qconfig-bootstrapped.h +++ b/src/corelib/global/qconfig-bootstrapped.h @@ -130,7 +130,6 @@ #define QT_NO_TEXTCODEC #define QT_FEATURE_textcodec -1 #else -#define QT_NO_CODECS #define QT_FEATURE_codecs -1 #define QT_FEATURE_commandlineparser 1 #define QT_FEATURE_textcodec 1 From 3eebadc1734463afa469dcd08eab8c5d2557dec6 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Fri, 28 Sep 2018 11:40:10 +0200 Subject: [PATCH 0011/1650] Modernize the "mimetype" feature Change-Id: I9b67c2cbc0891a38ece18d521c86fbc7344dce7a Reviewed-by: Edward Welbourne Reviewed-by: Oswald Buddenhagen --- src/corelib/mimetypes/qmimedatabase.cpp | 4 ---- src/corelib/mimetypes/qmimedatabase.h | 3 +-- src/corelib/mimetypes/qmimedatabase_p.h | 3 +-- src/corelib/mimetypes/qmimeglobpattern.cpp | 4 ---- src/corelib/mimetypes/qmimeglobpattern_p.h | 3 +-- src/corelib/mimetypes/qmimemagicrule.cpp | 4 ---- src/corelib/mimetypes/qmimemagicrule_p.h | 3 +-- src/corelib/mimetypes/qmimemagicrulematcher.cpp | 3 --- src/corelib/mimetypes/qmimemagicrulematcher_p.h | 3 +-- src/corelib/mimetypes/qmimeprovider.cpp | 4 ---- src/corelib/mimetypes/qmimeprovider_p.h | 3 +-- src/corelib/mimetypes/qmimetype.cpp | 4 ---- src/corelib/mimetypes/qmimetype.h | 3 +-- src/corelib/mimetypes/qmimetype_p.h | 3 +-- src/corelib/mimetypes/qmimetypeparser.cpp | 4 ---- src/corelib/mimetypes/qmimetypeparser_p.h | 3 +-- src/gui/image/qicon.cpp | 6 ++++-- .../themes/genericunix/qgenericunixthemes.cpp | 2 ++ src/plugins/platforms/cocoa/qcocoaprintdevice.h | 2 ++ src/plugins/platforms/cocoa/qcocoaprintdevice.mm | 4 ++++ src/plugins/platformthemes/platformthemes.pro | 2 +- src/plugins/printsupport/cups/qppdprintdevice.cpp | 2 +- src/plugins/printsupport/cups/qppdprintdevice.h | 2 +- src/printsupport/kernel/qplatformprintdevice.cpp | 10 ++++++---- src/printsupport/kernel/qplatformprintdevice.h | 8 +++++--- src/printsupport/kernel/qprintdevice.cpp | 8 ++++---- src/printsupport/kernel/qprintdevice_p.h | 2 +- src/widgets/dialogs/qfiledialog.cpp | 10 ++++++---- src/widgets/dialogs/qfiledialog.h | 2 +- 29 files changed, 47 insertions(+), 67 deletions(-) diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp index 68e3c8f10d..b31fef5bf5 100644 --- a/src/corelib/mimetypes/qmimedatabase.cpp +++ b/src/corelib/mimetypes/qmimedatabase.cpp @@ -40,8 +40,6 @@ #include // always first -#ifndef QT_NO_MIMETYPE - #include "qmimedatabase.h" #include "qmimedatabase_p.h" @@ -803,5 +801,3 @@ QList QMimeDatabase::allMimeTypes() const */ QT_END_NAMESPACE - -#endif // QT_NO_MIMETYPE diff --git a/src/corelib/mimetypes/qmimedatabase.h b/src/corelib/mimetypes/qmimedatabase.h index 358f0ab779..9111e5a04c 100644 --- a/src/corelib/mimetypes/qmimedatabase.h +++ b/src/corelib/mimetypes/qmimedatabase.h @@ -43,7 +43,7 @@ #include -#ifndef QT_NO_MIMETYPE +QT_REQUIRE_CONFIG(mimetype); #include @@ -92,5 +92,4 @@ private: QT_END_NAMESPACE -#endif // QT_NO_MIMETYPE #endif // QMIMEDATABASE_H diff --git a/src/corelib/mimetypes/qmimedatabase_p.h b/src/corelib/mimetypes/qmimedatabase_p.h index 1c38f46115..1e605d9a24 100644 --- a/src/corelib/mimetypes/qmimedatabase_p.h +++ b/src/corelib/mimetypes/qmimedatabase_p.h @@ -54,7 +54,7 @@ #include "qmimetype.h" -#ifndef QT_NO_MIMETYPE +QT_REQUIRE_CONFIG(mimetype); #include "qmimetype_p.h" #include "qmimeglobpattern_p.h" @@ -116,5 +116,4 @@ public: QT_END_NAMESPACE -#endif // QT_NO_MIMETYPE #endif // QMIMEDATABASE_P_H diff --git a/src/corelib/mimetypes/qmimeglobpattern.cpp b/src/corelib/mimetypes/qmimeglobpattern.cpp index e7b2b879a1..cd42b4da83 100644 --- a/src/corelib/mimetypes/qmimeglobpattern.cpp +++ b/src/corelib/mimetypes/qmimeglobpattern.cpp @@ -39,8 +39,6 @@ #include "qmimeglobpattern_p.h" -#ifndef QT_NO_MIMETYPE - #include #include #include @@ -239,5 +237,3 @@ void QMimeAllGlobPatterns::clear() } QT_END_NAMESPACE - -#endif // QT_NO_MIMETYPE diff --git a/src/corelib/mimetypes/qmimeglobpattern_p.h b/src/corelib/mimetypes/qmimeglobpattern_p.h index 103729c4ff..bb6f64320b 100644 --- a/src/corelib/mimetypes/qmimeglobpattern_p.h +++ b/src/corelib/mimetypes/qmimeglobpattern_p.h @@ -53,7 +53,7 @@ #include -#ifndef QT_NO_MIMETYPE +QT_REQUIRE_CONFIG(mimetype); #include #include @@ -162,5 +162,4 @@ public: QT_END_NAMESPACE -#endif // QT_NO_MIMETYPE #endif // QMIMEGLOBPATTERN_P_H diff --git a/src/corelib/mimetypes/qmimemagicrule.cpp b/src/corelib/mimetypes/qmimemagicrule.cpp index 9dadebc999..a97fe5bdc4 100644 --- a/src/corelib/mimetypes/qmimemagicrule.cpp +++ b/src/corelib/mimetypes/qmimemagicrule.cpp @@ -42,8 +42,6 @@ #include "qmimemagicrule_p.h" -#ifndef QT_NO_MIMETYPE - #include "qmimetypeparser_p.h" #include #include @@ -364,5 +362,3 @@ bool QMimeMagicRule::matches(const QByteArray &data) const } QT_END_NAMESPACE - -#endif // QT_NO_MIMETYPE diff --git a/src/corelib/mimetypes/qmimemagicrule_p.h b/src/corelib/mimetypes/qmimemagicrule_p.h index 9b27ef2657..6962a6ca59 100644 --- a/src/corelib/mimetypes/qmimemagicrule_p.h +++ b/src/corelib/mimetypes/qmimemagicrule_p.h @@ -53,7 +53,7 @@ #include -#ifndef QT_NO_MIMETYPE +QT_REQUIRE_CONFIG(mimetype); #include #include @@ -125,5 +125,4 @@ Q_DECLARE_SHARED(QMimeMagicRule) QT_END_NAMESPACE -#endif // QT_NO_MIMETYPE #endif // QMIMEMAGICRULE_H diff --git a/src/corelib/mimetypes/qmimemagicrulematcher.cpp b/src/corelib/mimetypes/qmimemagicrulematcher.cpp index b5194d3543..8f44fd2f80 100644 --- a/src/corelib/mimetypes/qmimemagicrulematcher.cpp +++ b/src/corelib/mimetypes/qmimemagicrulematcher.cpp @@ -41,8 +41,6 @@ #include "qmimemagicrulematcher_p.h" -#ifndef QT_NO_MIMETYPE - #include "qmimetype_p.h" QT_BEGIN_NAMESPACE @@ -106,4 +104,3 @@ unsigned QMimeMagicRuleMatcher::priority() const } QT_END_NAMESPACE -#endif // QT_NO_MIMETYPE diff --git a/src/corelib/mimetypes/qmimemagicrulematcher_p.h b/src/corelib/mimetypes/qmimemagicrulematcher_p.h index 5e3d5306c0..5e74e2e3fc 100644 --- a/src/corelib/mimetypes/qmimemagicrulematcher_p.h +++ b/src/corelib/mimetypes/qmimemagicrulematcher_p.h @@ -53,7 +53,7 @@ #include "qmimemagicrule_p.h" -#ifndef QT_NO_MIMETYPE +QT_REQUIRE_CONFIG(mimetype); #include #include @@ -94,5 +94,4 @@ Q_DECLARE_SHARED(QMimeMagicRuleMatcher) QT_END_NAMESPACE -#endif // QT_NO_MIMETYPE #endif // QMIMEMAGICRULEMATCHER_P_H diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp index 90a16886a9..c4a8458243 100644 --- a/src/corelib/mimetypes/qmimeprovider.cpp +++ b/src/corelib/mimetypes/qmimeprovider.cpp @@ -40,8 +40,6 @@ #include "qmimeprovider_p.h" -#ifndef QT_NO_MIMETYPE - #include "qmimetypeparser_p.h" #include #include "qmimemagicrulematcher_p.h" @@ -757,5 +755,3 @@ void QMimeXMLProvider::addMagicMatcher(const QMimeMagicRuleMatcher &matcher) } QT_END_NAMESPACE - -#endif // QT_NO_MIMETYPE diff --git a/src/corelib/mimetypes/qmimeprovider_p.h b/src/corelib/mimetypes/qmimeprovider_p.h index b2be545cf8..875ff9e0eb 100644 --- a/src/corelib/mimetypes/qmimeprovider_p.h +++ b/src/corelib/mimetypes/qmimeprovider_p.h @@ -54,7 +54,7 @@ #include "qmimedatabase_p.h" -#ifndef QT_NO_MIMETYPE +QT_REQUIRE_CONFIG(mimetype); #include "qmimeglobpattern_p.h" #include @@ -173,5 +173,4 @@ private: QT_END_NAMESPACE -#endif // QT_NO_MIMETYPE #endif // QMIMEPROVIDER_P_H diff --git a/src/corelib/mimetypes/qmimetype.cpp b/src/corelib/mimetypes/qmimetype.cpp index d7590ecf1f..50b8eae5c3 100644 --- a/src/corelib/mimetypes/qmimetype.cpp +++ b/src/corelib/mimetypes/qmimetype.cpp @@ -40,8 +40,6 @@ #include "qmimetype.h" -#ifndef QT_NO_MIMETYPE - #include "qmimetype_p.h" #include "qmimedatabase_p.h" #include "qmimeprovider_p.h" @@ -526,5 +524,3 @@ QDebug operator<<(QDebug debug, const QMimeType &mime) #endif QT_END_NAMESPACE - -#endif // QT_NO_MIMETYPE diff --git a/src/corelib/mimetypes/qmimetype.h b/src/corelib/mimetypes/qmimetype.h index def4034f8a..8287f1434b 100644 --- a/src/corelib/mimetypes/qmimetype.h +++ b/src/corelib/mimetypes/qmimetype.h @@ -43,7 +43,7 @@ #include -#ifndef QT_NO_MIMETYPE +QT_REQUIRE_CONFIG(mimetype); #include #include @@ -135,5 +135,4 @@ Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QMimeType &mime); QT_END_NAMESPACE -#endif // QT_NO_MIMETYPE #endif // QMIMETYPE_H diff --git a/src/corelib/mimetypes/qmimetype_p.h b/src/corelib/mimetypes/qmimetype_p.h index aa38a1adf5..5a36e6613c 100644 --- a/src/corelib/mimetypes/qmimetype_p.h +++ b/src/corelib/mimetypes/qmimetype_p.h @@ -54,7 +54,7 @@ #include #include "qmimetype.h" -#ifndef QT_NO_MIMETYPE +QT_REQUIRE_CONFIG(mimetype); #include #include @@ -124,5 +124,4 @@ QT_END_NAMESPACE QT_END_NAMESPACE #endif -#endif // QT_NO_MIMETYPE #endif // QMIMETYPE_P_H diff --git a/src/corelib/mimetypes/qmimetypeparser.cpp b/src/corelib/mimetypes/qmimetypeparser.cpp index 0a55560ab0..7ff695bbc3 100644 --- a/src/corelib/mimetypes/qmimetypeparser.cpp +++ b/src/corelib/mimetypes/qmimetypeparser.cpp @@ -41,8 +41,6 @@ #include "qmimetypeparser_p.h" -#ifndef QT_NO_MIMETYPE - #include "qmimetype_p.h" #include "qmimemagicrulematcher_p.h" @@ -341,5 +339,3 @@ bool QMimeTypeParserBase::parse(QIODevice *dev, const QString &fileName, QString } QT_END_NAMESPACE - -#endif // QT_NO_MIMETYPE diff --git a/src/corelib/mimetypes/qmimetypeparser_p.h b/src/corelib/mimetypes/qmimetypeparser_p.h index 0ce39e701c..6e3f5fd556 100644 --- a/src/corelib/mimetypes/qmimetypeparser_p.h +++ b/src/corelib/mimetypes/qmimetypeparser_p.h @@ -54,7 +54,7 @@ #include "qmimedatabase_p.h" -#ifndef QT_NO_MIMETYPE +QT_REQUIRE_CONFIG(mimetype); #include "qmimeprovider_p.h" @@ -129,5 +129,4 @@ private: QT_END_NAMESPACE -#endif // QT_NO_MIMETYPE #endif // MIMETYPEPARSER_P_H diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index 32fa9e75ac..635fdc3a68 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -47,8 +47,10 @@ #include "private/qiconloader_p.h" #include "qpainter.h" #include "qfileinfo.h" +#if QT_CONFIG(mimetype) #include #include +#endif #include "qpixmapcache.h" #include "qvariant.h" #include "qcache.h" @@ -1079,10 +1081,10 @@ void QIcon::addFile(const QString &fileName, const QSize &size, Mode mode, State QFileInfo info(fileName); QIconEngine *engine = iconEngineFromSuffix(fileName, info.suffix()); -#ifndef QT_NO_MIMETYPE +#if QT_CONFIG(mimetype) if (!engine) engine = iconEngineFromSuffix(fileName, QMimeDatabase().mimeTypeForFile(info).preferredSuffix()); -#endif // !QT_NO_MIMETYPE +#endif // mimetype d = new QIconPrivate(engine ? engine : new QPixmapIconEngine); } diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp index 63a860f251..43d49cbbc8 100644 --- a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp +++ b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp @@ -49,7 +49,9 @@ #include #include #include +#if QT_CONFIG(mimetype) #include +#endif #include #include #include diff --git a/src/plugins/platforms/cocoa/qcocoaprintdevice.h b/src/plugins/platforms/cocoa/qcocoaprintdevice.h index 20b27f3286..d267343b0e 100644 --- a/src/plugins/platforms/cocoa/qcocoaprintdevice.h +++ b/src/plugins/platforms/cocoa/qcocoaprintdevice.h @@ -98,7 +98,9 @@ protected: void loadOutputBins() const override; void loadDuplexModes() const override; void loadColorModes() const override; +#if QT_CONFIG(mimetype) void loadMimeTypes() const override; +#endif private: QPageSize createPageSize(const PMPaper &paper) const; diff --git a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm index bfe6cd09b6..0c54a3b771 100644 --- a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm +++ b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm @@ -39,7 +39,9 @@ #include "qcocoaprintdevice.h" +#if QT_CONFIG(mimetype) #include +#endif #include QT_BEGIN_NAMESPACE @@ -417,6 +419,7 @@ QPrint::ColorMode QCocoaPrintDevice::defaultColorMode() const return QPrint::GrayScale; } +#if QT_CONFIG(mimetype) void QCocoaPrintDevice::loadMimeTypes() const { // TODO Check how settings affect returned list @@ -438,6 +441,7 @@ void QCocoaPrintDevice::loadMimeTypes() const } m_haveMimeTypes = true; } +#endif // mimetype bool QCocoaPrintDevice::openPpdFile() { diff --git a/src/plugins/platformthemes/platformthemes.pro b/src/plugins/platformthemes/platformthemes.pro index 17b1d91c6a..02ed3406e7 100644 --- a/src/plugins/platformthemes/platformthemes.pro +++ b/src/plugins/platformthemes/platformthemes.pro @@ -1,6 +1,6 @@ TEMPLATE = subdirs QT_FOR_CONFIG += widgets-private -qtConfig(dbus):qtConfig(regularexpression): SUBDIRS += flatpak +qtConfig(dbus):qtConfig(regularexpression):qtConfig(mimetype): SUBDIRS += flatpak qtHaveModule(widgets):qtConfig(gtk3): SUBDIRS += gtk3 diff --git a/src/plugins/printsupport/cups/qppdprintdevice.cpp b/src/plugins/printsupport/cups/qppdprintdevice.cpp index 340b1a1ff4..f0a8105d21 100644 --- a/src/plugins/printsupport/cups/qppdprintdevice.cpp +++ b/src/plugins/printsupport/cups/qppdprintdevice.cpp @@ -463,7 +463,7 @@ bool QPpdPrintDevice::isFeatureAvailable(QPrintDevice::PrintDevicePropertyKey ke return QPlatformPrintDevice::isFeatureAvailable(key, params); } -#ifndef QT_NO_MIMETYPE +#if QT_CONFIG(mimetype) void QPpdPrintDevice::loadMimeTypes() const { // TODO No CUPS api? Need to manually load CUPS mime.types file? diff --git a/src/plugins/printsupport/cups/qppdprintdevice.h b/src/plugins/printsupport/cups/qppdprintdevice.h index 9867083bd7..596f9aa3f5 100644 --- a/src/plugins/printsupport/cups/qppdprintdevice.h +++ b/src/plugins/printsupport/cups/qppdprintdevice.h @@ -100,7 +100,7 @@ protected: void loadOutputBins() const override; void loadDuplexModes() const override; void loadColorModes() const override; -#ifndef QT_NO_MIMETYPE +#if QT_CONFIG(mimetype) void loadMimeTypes() const override; #endif diff --git a/src/printsupport/kernel/qplatformprintdevice.cpp b/src/printsupport/kernel/qplatformprintdevice.cpp index 8dba402a6e..8c905889db 100644 --- a/src/printsupport/kernel/qplatformprintdevice.cpp +++ b/src/printsupport/kernel/qplatformprintdevice.cpp @@ -61,7 +61,7 @@ QPlatformPrintDevice::QPlatformPrintDevice() m_haveOutputBins(false), m_haveDuplexModes(false), m_haveColorModes(false) -#ifndef QT_NO_MIMETYPE +#if QT_CONFIG(mimetype) , m_haveMimeTypes(false) #endif { @@ -79,7 +79,7 @@ QPlatformPrintDevice::QPlatformPrintDevice(const QString &id) m_haveOutputBins(false), m_haveDuplexModes(false), m_haveColorModes(false) -#ifndef QT_NO_MIMETYPE +#if QT_CONFIG(mimetype) , m_haveMimeTypes(false) #endif { @@ -376,10 +376,11 @@ QVector QPlatformPrintDevice::supportedColorModes() const return m_colorModes; } -#ifndef QT_NO_MIMETYPE +#if QT_CONFIG(mimetype) void QPlatformPrintDevice::loadMimeTypes() const { } +#endif // mimetype QVariant QPlatformPrintDevice::property(QPrintDevice::PrintDevicePropertyKey key) const { @@ -404,13 +405,14 @@ bool QPlatformPrintDevice::isFeatureAvailable(QPrintDevice::PrintDevicePropertyK return false; } +#if QT_CONFIG(mimetype) QList QPlatformPrintDevice::supportedMimeTypes() const { if (!m_haveMimeTypes) loadMimeTypes(); return m_mimeTypes; } -#endif // QT_NO_MIMETYPE +#endif // mimetype QPageSize QPlatformPrintDevice::createPageSize(const QString &key, const QSize &size, const QString &localizedName) { diff --git a/src/printsupport/kernel/qplatformprintdevice.h b/src/printsupport/kernel/qplatformprintdevice.h index a988518547..76f03dea7e 100644 --- a/src/printsupport/kernel/qplatformprintdevice.h +++ b/src/printsupport/kernel/qplatformprintdevice.h @@ -57,7 +57,9 @@ #include #include +#if QT_CONFIG(mimetype) #include +#endif #include @@ -125,7 +127,7 @@ public: virtual bool setProperty(QPrintDevice::PrintDevicePropertyKey key, const QVariant &value); virtual bool isFeatureAvailable(QPrintDevice::PrintDevicePropertyKey key, const QVariant ¶ms) const; -#ifndef QT_NO_MIMETYPE +#if QT_CONFIG(mimetype) virtual QList supportedMimeTypes() const; #endif @@ -139,7 +141,7 @@ protected: virtual void loadOutputBins() const; virtual void loadDuplexModes() const; virtual void loadColorModes() const; -#ifndef QT_NO_MIMETYPE +#if QT_CONFIG(mimetype) virtual void loadMimeTypes() const; #endif @@ -178,7 +180,7 @@ protected: mutable bool m_haveColorModes; mutable QVector m_colorModes; -#ifndef QT_NO_MIMETYPE +#if QT_CONFIG(mimetype) mutable bool m_haveMimeTypes; mutable QList m_mimeTypes; #endif diff --git a/src/printsupport/kernel/qprintdevice.cpp b/src/printsupport/kernel/qprintdevice.cpp index 50fc14169d..7fca3e45bf 100644 --- a/src/printsupport/kernel/qprintdevice.cpp +++ b/src/printsupport/kernel/qprintdevice.cpp @@ -260,12 +260,12 @@ bool QPrintDevice::isFeatureAvailable(PrintDevicePropertyKey key, const QVariant return isValid() ? d->isFeatureAvailable(key, params) : false; } -#ifndef QT_NO_MIMETYPE +#if QT_CONFIG(mimetype) QList QPrintDevice::supportedMimeTypes() const { return isValid() ? d->supportedMimeTypes() : QList(); } -#endif // QT_NO_MIMETYPE +#endif // mimetype # ifndef QT_NO_DEBUG_STREAM void QPrintDevice::format(QDebug debug) const @@ -296,7 +296,7 @@ void QPrintDevice::format(QDebug debug) const debug << "), defaultResolution=" << defaultResolution() << ", defaultDuplexMode=" << defaultDuplexMode() << ", defaultColorMode="<< defaultColorMode(); -# ifndef QT_NO_MIMETYPE +# if QT_CONFIG(mimetype) const QList mimeTypes = supportedMimeTypes(); if (!mimeTypes.isEmpty()) { debug << ", supportedMimeTypes=("; @@ -304,7 +304,7 @@ void QPrintDevice::format(QDebug debug) const debug << " \"" << mimeType.name() << '"'; debug << ')'; } -# endif // !QT_NO_MIMETYPE +# endif // mimetype } else { debug << "null"; } diff --git a/src/printsupport/kernel/qprintdevice_p.h b/src/printsupport/kernel/qprintdevice_p.h index 562ccd2057..a2b18f08cf 100644 --- a/src/printsupport/kernel/qprintdevice_p.h +++ b/src/printsupport/kernel/qprintdevice_p.h @@ -139,7 +139,7 @@ public: bool setProperty(PrintDevicePropertyKey key, const QVariant &value); bool isFeatureAvailable(PrintDevicePropertyKey key, const QVariant ¶ms) const; -#ifndef QT_NO_MIMETYPE +#if QT_CONFIG(mimetype) QList supportedMimeTypes() const; #endif diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index ecd2ab6776..778e8556c7 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -59,7 +59,9 @@ #include #include #include +#if QT_CONFIG(mimetype) #include +#endif #include #include #include "ui_qfiledialog.h" @@ -1515,7 +1517,7 @@ void QFileDialog::setFilter(QDir::Filters filters) d->showHiddenAction->setChecked((filters & QDir::Hidden)); } -#ifndef QT_NO_MIMETYPE +#if QT_CONFIG(mimetype) static QString nameFilterForMime(const QString &mimeType) { @@ -1596,7 +1598,7 @@ void QFileDialog::selectMimeTypeFilter(const QString &filter) } } -#endif // QT_NO_MIMETYPE +#endif // mimetype /*! * \since 5.9 @@ -1609,7 +1611,7 @@ QString QFileDialog::selectedMimeTypeFilter() const if (!d->usingWidgets()) mimeTypeFilter = d->selectedMimeTypeFilter_sys(); -#ifndef QT_NO_MIMETYPE +#if QT_CONFIG(mimetype) if (mimeTypeFilter.isNull() && !d->options->mimeTypeFilters().isEmpty()) { const auto nameFilter = selectedNameFilter(); const auto mimeTypes = d->options->mimeTypeFilters(); @@ -3034,7 +3036,7 @@ void QFileDialogPrivate::createWidgets() if (!options->sidebarUrls().isEmpty()) q->setSidebarUrls(options->sidebarUrls()); q->setDirectoryUrl(options->initialDirectory()); -#ifndef QT_NO_MIMETYPE +#if QT_CONFIG(mimetype) if (!options->mimeTypeFilters().isEmpty()) q->setMimeTypeFilters(options->mimeTypeFilters()); else diff --git a/src/widgets/dialogs/qfiledialog.h b/src/widgets/dialogs/qfiledialog.h index 1cbd690f24..b9a49d3d18 100644 --- a/src/widgets/dialogs/qfiledialog.h +++ b/src/widgets/dialogs/qfiledialog.h @@ -127,7 +127,7 @@ public: QString selectedMimeTypeFilter() const; QString selectedNameFilter() const; -#ifndef QT_NO_MIMETYPE +#if QT_CONFIG(mimetype) void setMimeTypeFilters(const QStringList &filters); QStringList mimeTypeFilters() const; void selectMimeTypeFilter(const QString &filter); From b7887f9b4faad2227691a2af589e9d7680d6ae08 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 19 Sep 2018 00:05:54 -0500 Subject: [PATCH 0012/1650] Linux: Remove our use of syscall() for statx(2) and renameat2(2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Those system calls are present in glibc 2.28. Instead of using syscall(3) to place the system calls directly, let's use only the glibc functions. That also means we no longer accept ENOSYS from either function, if they were detected in glibc. Change-Id: I44e7d800c68141bdaae0fffd1555b4b8fe63786b Reviewed-by: Oswald Buddenhagen Reviewed-by: Lars Knoll Reviewed-by: Jüri Valdmann --- src/corelib/global/minimum-linux_p.h | 7 +++- src/corelib/io/qfilesystemengine_unix.cpp | 45 ++--------------------- 2 files changed, 9 insertions(+), 43 deletions(-) diff --git a/src/corelib/global/minimum-linux_p.h b/src/corelib/global/minimum-linux_p.h index bad2488b4d..9c074e13ba 100644 --- a/src/corelib/global/minimum-linux_p.h +++ b/src/corelib/global/minimum-linux_p.h @@ -75,9 +75,14 @@ QT_BEGIN_NAMESPACE * - accept4 2.6.28 * - renameat2 3.16 QT_CONFIG(renameat2) * - getrandom 3.17 QT_CONFIG(getentropy) + * - statx 4.11 QT_CONFIG(statx) */ -#if QT_CONFIG(getentropy) +#if QT_CONFIG(statx) +# define MINLINUX_MAJOR 4 +# define MINLINUX_MINOR 11 +# define MINLINUX_PATCH 0 +#elif QT_CONFIG(getentropy) # define MINLINUX_MAJOR 3 # define MINLINUX_MINOR 17 # define MINLINUX_PATCH 0 diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index deb4a9f220..40e8f82a80 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 Intel Corporation. +** Copyright (C) 2018 Intel Corporation. ** Copyright (C) 2016 The Qt Company Ltd. ** Copyright (C) 2013 Samuel Gaist ** Contact: https://www.qt.io/licensing/ @@ -88,7 +88,6 @@ extern "C" NSString *NSTemporaryDirectory(); #if defined(Q_OS_LINUX) # include -# include # include # include @@ -96,28 +95,6 @@ extern "C" NSString *NSTemporaryDirectory(); #ifndef FICLONE # define FICLONE _IOW(0x94, 9, int) #endif - -# if defined(Q_OS_ANDROID) -// renameat2() and statx() are disabled on Android because quite a few systems -// come with sandboxes that kill applications that make system calls outside a -// whitelist and several Android vendors can't be bothered to update the list. -# undef SYS_renameat2 -# undef SYS_statx -# undef STATX_BASIC_STATS -# else -# if !QT_CONFIG(renameat2) && defined(SYS_renameat2) -static int renameat2(int oldfd, const char *oldpath, int newfd, const char *newpath, unsigned flags) -{ return syscall(SYS_renameat2, oldfd, oldpath, newfd, newpath, flags); } -# endif - -# if !QT_CONFIG(statx) && defined(SYS_statx) -# include -static int statx(int dirfd, const char *pathname, int flag, unsigned mask, struct statx *statxbuf) -{ return syscall(SYS_statx, dirfd, pathname, flag, mask, statxbuf); } -# elif !QT_CONFIG(statx) && !defined(SYS_statx) -# undef STATX_BASIC_STATS -# endif -# endif // !Q_OS_ANDROID #endif #ifndef STATX_ALL @@ -331,22 +308,8 @@ mtime(const T &statBuffer, int) #ifdef STATX_BASIC_STATS static int qt_real_statx(int fd, const char *pathname, int flags, struct statx *statxBuffer) { -#ifdef Q_ATOMIC_INT8_IS_SUPPORTED - static QBasicAtomicInteger statxTested = Q_BASIC_ATOMIC_INITIALIZER(0); -#else - static QBasicAtomicInt statxTested = Q_BASIC_ATOMIC_INITIALIZER(0); -#endif - - if (statxTested.load() == -1) - return -ENOSYS; - unsigned mask = STATX_BASIC_STATS | STATX_BTIME; int ret = statx(fd, pathname, flags, mask, statxBuffer); - if (ret == -1 && errno == ENOSYS) { - statxTested.store(-1); - return -ENOSYS; - } - statxTested.store(1); return ret == -1 ? -errno : 0; } @@ -1282,14 +1245,12 @@ bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSy if (Q_UNLIKELY(srcPath.isEmpty() || tgtPath.isEmpty())) return emptyFileEntryWarning(), false; -#if defined(RENAME_NOREPLACE) && (QT_CONFIG(renameat2) || defined(SYS_renameat2)) +#if defined(RENAME_NOREPLACE) && QT_CONFIG(renameat2) if (renameat2(AT_FDCWD, srcPath, AT_FDCWD, tgtPath, RENAME_NOREPLACE) == 0) return true; - // If we're using syscall(), check for ENOSYS; - // if renameat2 came from libc, we don't accept ENOSYS. // We can also get EINVAL for some non-local filesystems. - if ((QT_CONFIG(renameat2) || errno != ENOSYS) && errno != EINVAL) { + if (errno != EINVAL) { error = QSystemError(errno, QSystemError::StandardLibraryError); return false; } From bbe08d6b686456297ad4ab8c0923c3126e02e2b3 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Wed, 3 Oct 2018 09:59:06 +0200 Subject: [PATCH 0013/1650] QCss: properly parse functions which contains additional spaces When there were additional spaces between the function definition and the first parameter, the parser failed to parse it when it contained another function (e.g. 'qlineargradient(... rgb() ...)'). The reason for this was that ::until() needs the function at index-1 so it can correctly count the opening parenthesis. Fixes: QTBUG-61795 Change-Id: I992f556e7f8cd45550f83bc90aa8de2b4e905574 Reviewed-by: Richard Moe Gustavsen --- src/gui/text/qcssparser.cpp | 4 +++- tests/auto/gui/text/qcssparser/tst_qcssparser.cpp | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp index 70623939e1..325fd26a31 100644 --- a/src/gui/text/qcssparser.cpp +++ b/src/gui/text/qcssparser.cpp @@ -2707,8 +2707,10 @@ bool Parser::parseFunction(QString *name, QString *args) { *name = lexem(); name->chop(1); + // until(RPAREN) needs FUNCTION token at index-1 to work properly + int start = index; skipSpace(); - const int start = index; + std::swap(start, index); if (!until(RPAREN)) return false; for (int i = start; i < index - 1; ++i) args->append(symbols.at(i).lexem()); diff --git a/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp b/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp index 2a53f5d633..cfd24a8701 100644 --- a/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp +++ b/tests/auto/gui/text/qcssparser/tst_qcssparser.cpp @@ -1509,6 +1509,12 @@ void tst_QCssParser::gradient_data() "spread: repeat, stop:0.2 rgb(1, 2, 3), stop:0.5 rgba(1, 2, 3, 4))" << "conical" << QPointF(4, 2) << QPointF() << 2 << qreal(0.2) << QColor(1, 2, 3) << qreal(0.5) << QColor(1, 2, 3, 4); + // spaces before first function parameter lead to parser errors + QTest::newRow("QTBUG-61795") << + "selection-background-color: qconicalgradient( cx: 4, cy : 2, angle: 23, " + "spread: repeat, stop:0.2 rgb( 1, 2, 3), stop:0.5 rgba( 1, 2, 3, 4))" << "conical" << QPointF(4, 2) << QPointF() + << 2 << qreal(0.2) << QColor(1, 2, 3) << qreal(0.5) << QColor(1, 2, 3, 4); + /* won't pass: stop values are expected to be sorted QTest::newRow("unsorted-stop") << "selection-background: lineargradient(x1:0, y1:0, x2:0, y2:1, " From 656e89f875ad2008ca16cc673b687a22daa294c9 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Tue, 9 Oct 2018 07:44:46 +0200 Subject: [PATCH 0014/1650] qnsview_keys - fix a typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit that resulted in 'Cmd' reported as combo of Qt::Meta/Qt::Control and Qt::KeypadModifier. Task-number: QTBUG-71006 Change-Id: I3dddc56f4d404a1ceefb21d57ac120b6273456ec Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qnsview_keys.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qnsview_keys.mm b/src/plugins/platforms/cocoa/qnsview_keys.mm index 28db532ddc..ad751279bb 100644 --- a/src/plugins/platforms/cocoa/qnsview_keys.mm +++ b/src/plugins/platforms/cocoa/qnsview_keys.mm @@ -53,7 +53,7 @@ qtMods |= Qt::AltModifier; if (modifierFlags & NSEventModifierFlagCommand) qtMods |= dontSwapCtrlAndMeta ? Qt::MetaModifier : Qt::ControlModifier; - if (modifierFlags & NSEventModifierFlagCommand) + if (modifierFlags & NSEventModifierFlagNumericPad) qtMods |= Qt::KeypadModifier; return qtMods; } From 0a7aebadfbb3534284546aa3ca8612314c08f136 Mon Sep 17 00:00:00 2001 From: Miguel Costa Date: Tue, 26 Jun 2018 16:56:45 +0200 Subject: [PATCH 0015/1650] Update ANGLE to chromium/3280 Change-Id: I0802c0d7486f772d361f87a544d6c5af937f4ca1 Reviewed-by: Friedemann Kleint --- src/3rdparty/angle/AUTHORS | 9 +- src/3rdparty/angle/CONTRIBUTORS | 20 + src/3rdparty/angle/LICENSE | 64 +- src/3rdparty/angle/SYSTEMINFO_LICENSE | 22 - src/3rdparty/angle/TRACEEVENT_LICENSE | 27 - src/3rdparty/angle/id/commit.h | 14 + src/3rdparty/angle/include/EGL/egl.h | 24 +- src/3rdparty/angle/include/EGL/eglext.h | 464 +- src/3rdparty/angle/include/EGL/eglext_angle.h | 170 + src/3rdparty/angle/include/EGL/eglplatform.h | 31 +- src/3rdparty/angle/include/GLES2/gl2.h | 14 +- src/3rdparty/angle/include/GLES2/gl2ext.h | 544 +- .../angle/include/GLES2/gl2ext_angle.h | 551 ++ src/3rdparty/angle/include/GLES3/gl3ext.h | 24 - .../angle/include/GLSLANG/ShaderLang.h | 625 +- .../angle/include/GLSLANG/ShaderVars.h | 161 +- src/3rdparty/angle/include/KHR/khrplatform.h | 9 +- src/3rdparty/angle/include/angle_gl.h | 5 - src/3rdparty/angle/include/export.h | 8 +- .../angle/include/platform/Platform.h | 389 +- .../angle/include/platform/WorkaroundsD3D.h | 130 + .../angle/src/common/BitSetIterator.h | 156 - src/3rdparty/angle/src/common/Color.h | 53 + src/3rdparty/angle/src/common/Color.inl | 37 + .../angle/src/common/MemoryBuffer.cpp | 105 +- src/3rdparty/angle/src/common/MemoryBuffer.h | 55 +- src/3rdparty/angle/src/common/Optional.h | 33 +- src/3rdparty/angle/src/common/angleutils.cpp | 62 +- src/3rdparty/angle/src/common/angleutils.h | 131 +- src/3rdparty/angle/src/common/bitset_utils.h | 498 ++ src/3rdparty/angle/src/common/debug.cpp | 236 +- src/3rdparty/angle/src/common/debug.h | 268 +- .../angle/src/common/event_tracer.cpp | 37 +- src/3rdparty/angle/src/common/event_tracer.h | 14 +- src/3rdparty/angle/src/common/mathutil.cpp | 20 +- src/3rdparty/angle/src/common/mathutil.h | 577 +- src/3rdparty/angle/src/common/matrix_utils.h | 37 + src/3rdparty/angle/src/common/platform.h | 47 +- .../angle/src/common/string_utils.cpp | 77 + src/3rdparty/angle/src/common/string_utils.h | 38 +- src/3rdparty/angle/src/common/system_utils.h | 27 + .../angle/src/common/system_utils_linux.cpp | 89 + .../angle/src/common/system_utils_mac.cpp | 94 + .../angle/src/common/system_utils_win.cpp | 79 + .../src/common/third_party/base/README.angle | 27 + .../third_party/base/anglebase/base_export.h | 13 + .../base/anglebase/containers/mru_cache.h | 275 + .../third_party/base/anglebase/logging.h | 26 + .../third_party/base/anglebase/macros.h | 17 + .../base/anglebase/numerics/OWNERS | 3 + .../anglebase/numerics/safe_conversions.h | 179 + .../numerics/safe_conversions_impl.h | 274 + .../base/anglebase/numerics/safe_math.h | 329 + .../base/anglebase/numerics/safe_math_impl.h | 575 ++ .../numerics/safe_numerics_unittest.cc | 771 ++ .../common/third_party/base/anglebase/sha1.cc | 245 + .../common/third_party/base/anglebase/sha1.h | 36 + .../base/anglebase/sys_byteorder.h | 49 + .../src/common/third_party/smhasher/LICENSE | 23 + .../common/third_party/smhasher/README.angle | 14 + .../third_party/smhasher/src/PMurHash.cpp | 320 + .../third_party/smhasher/src/PMurHash.h | 59 + src/3rdparty/angle/src/common/tls.cpp | 4 +- .../src/common/uniform_type_info_autogen.cpp | 275 + src/3rdparty/angle/src/common/utilities.cpp | 344 +- src/3rdparty/angle/src/common/utilities.h | 97 +- src/3rdparty/angle/src/common/vector_utils.h | 523 ++ .../src/compiler/fuzz/translator_fuzzer.cpp | 179 + .../compiler/preprocessor/DiagnosticsBase.cpp | 214 +- .../compiler/preprocessor/DiagnosticsBase.h | 17 +- .../preprocessor/DirectiveHandlerBase.cpp | 2 +- .../preprocessor/DirectiveHandlerBase.h | 6 +- .../compiler/preprocessor/DirectiveParser.cpp | 630 +- .../compiler/preprocessor/DirectiveParser.h | 24 +- .../compiler/preprocessor/ExpressionParser.h | 8 +- .../compiler/preprocessor/ExpressionParser.y | 85 +- .../angle/src/compiler/preprocessor/Input.cpp | 31 +- .../angle/src/compiler/preprocessor/Input.h | 26 +- .../angle/src/compiler/preprocessor/Lexer.cpp | 2 +- .../angle/src/compiler/preprocessor/Lexer.h | 4 +- .../angle/src/compiler/preprocessor/Macro.cpp | 35 +- .../angle/src/compiler/preprocessor/Macro.h | 12 +- .../compiler/preprocessor/MacroExpander.cpp | 297 +- .../src/compiler/preprocessor/MacroExpander.h | 55 +- .../compiler/preprocessor/Preprocessor.cpp | 72 +- .../src/compiler/preprocessor/Preprocessor.h | 20 +- .../compiler/preprocessor/SourceLocation.h | 12 +- .../angle/src/compiler/preprocessor/Token.cpp | 21 +- .../angle/src/compiler/preprocessor/Token.h | 29 +- .../src/compiler/preprocessor/Tokenizer.h | 17 +- .../src/compiler/preprocessor/Tokenizer.l | 55 +- .../src/compiler/preprocessor/numeric_lex.h | 18 +- .../src/compiler/preprocessor/pp_utils.h | 18 - .../compiler/translator/ASTMetadataHLSL.cpp | 155 +- .../src/compiler/translator/ASTMetadataHLSL.h | 17 +- .../translator/AddAndTrueToLoopCondition.cpp | 59 + .../translator/AddAndTrueToLoopCondition.h | 20 + .../translator/AddDefaultReturnStatements.cpp | 58 + .../translator/AddDefaultReturnStatements.h | 22 + .../ArrayReturnValueToOutParameter.cpp | 235 +- .../ArrayReturnValueToOutParameter.h | 14 +- .../angle/src/compiler/translator/BaseTypes.h | 970 ++- .../BreakVariableAliasingInInnerLoops.cpp | 107 + .../BreakVariableAliasingInInnerLoops.h | 23 + .../translator/BuiltInFunctionEmulator.cpp | 336 +- .../translator/BuiltInFunctionEmulator.h | 188 +- .../BuiltInFunctionEmulatorGLSL.cpp | 166 +- .../translator/BuiltInFunctionEmulatorGLSL.h | 21 +- .../BuiltInFunctionEmulatorHLSL.cpp | 569 +- .../translator/BuiltInFunctionEmulatorHLSL.h | 11 + .../angle/src/compiler/translator/Cache.cpp | 41 +- .../angle/src/compiler/translator/Cache.h | 36 +- .../angle/src/compiler/translator/CallDAG.cpp | 277 +- .../angle/src/compiler/translator/CallDAG.h | 16 +- .../compiler/translator/ClampPointSize.cpp | 47 + .../src/compiler/translator/ClampPointSize.h | 22 + .../angle/src/compiler/translator/CodeGen.cpp | 89 +- .../compiler/translator/CollectVariables.cpp | 869 +++ .../compiler/translator/CollectVariables.h | 37 + .../angle/src/compiler/translator/Common.h | 73 +- .../src/compiler/translator/Compiler.cpp | 1211 ++-- .../angle/src/compiler/translator/Compiler.h | 221 +- .../src/compiler/translator/ConstantUnion.cpp | 681 ++ .../src/compiler/translator/ConstantUnion.h | 399 +- ...reAndInitBuiltinsForInstancedMultiview.cpp | 221 + ...lareAndInitBuiltinsForInstancedMultiview.h | 48 + .../translator/DeferGlobalInitializers.cpp | 147 + .../translator/DeferGlobalInitializers.h | 32 + .../compiler/translator/DetectCallDepth.cpp | 185 - .../src/compiler/translator/DetectCallDepth.h | 78 - .../translator/DetectDiscontinuity.cpp | 191 - .../compiler/translator/DetectDiscontinuity.h | 71 - .../src/compiler/translator/Diagnostics.cpp | 105 +- .../src/compiler/translator/Diagnostics.h | 46 +- .../compiler/translator/DirectiveHandler.cpp | 137 +- .../compiler/translator/DirectiveHandler.h | 14 +- .../EmulateGLFragColorBroadcast.cpp | 129 + .../translator/EmulateGLFragColorBroadcast.h | 31 + .../compiler/translator/EmulatePrecision.cpp | 878 ++- .../compiler/translator/EmulatePrecision.h | 25 +- .../ExpandIntegerPowExpressions.cpp | 153 + .../translator/ExpandIntegerPowExpressions.h | 29 + .../compiler/translator/ExtensionBehavior.cpp | 96 + .../compiler/translator/ExtensionBehavior.h | 61 +- .../src/compiler/translator/ExtensionGLSL.cpp | 5 + .../src/compiler/translator/ExtensionGLSL.h | 7 +- .../src/compiler/translator/FindMain.cpp | 38 + .../angle/src/compiler/translator/FindMain.h | 23 + .../compiler/translator/FindSymbolNode.cpp | 58 + .../src/compiler/translator/FindSymbolNode.h | 27 + .../compiler/translator/FlagStd140Structs.cpp | 92 +- .../compiler/translator/FlagStd140Structs.h | 37 +- .../src/compiler/translator/ForLoopUnroll.cpp | 97 - .../src/compiler/translator/ForLoopUnroll.h | 53 - .../src/compiler/translator/HashNames.cpp | 72 + .../angle/src/compiler/translator/HashNames.h | 14 +- .../compiler/translator/ImageFunctionHLSL.cpp | 304 + .../compiler/translator/ImageFunctionHLSL.h | 76 + .../src/compiler/translator/InfoSink.cpp | 38 +- .../angle/src/compiler/translator/InfoSink.h | 78 +- .../src/compiler/translator/Initialize.cpp | 1212 +++- .../src/compiler/translator/Initialize.h | 23 +- .../src/compiler/translator/InitializeDll.cpp | 15 +- .../src/compiler/translator/InitializeDll.h | 6 +- .../compiler/translator/InitializeGlobals.h | 2 +- .../translator/InitializeParseContext.cpp | 42 - .../translator/InitializeParseContext.h | 17 - .../translator/InitializeVariables.cpp | 337 +- .../compiler/translator/InitializeVariables.h | 64 +- .../src/compiler/translator/IntermNode.cpp | 4164 ++++++----- .../src/compiler/translator/IntermNode.h | 901 ++- .../translator/IntermNodePatternMatcher.cpp | 157 + .../translator/IntermNodePatternMatcher.h | 75 + .../compiler/translator/IntermNode_util.cpp | 254 + .../src/compiler/translator/IntermNode_util.h | 60 + .../compiler/translator/IntermTraverse.cpp | 646 +- .../src/compiler/translator/IntermTraverse.h | 355 + .../src/compiler/translator/Intermediate.cpp | 508 -- .../src/compiler/translator/Intermediate.h | 75 - .../translator/IsASTDepthBelowLimit.cpp | 51 + .../translator/IsASTDepthBelowLimit.h | 20 + .../src/compiler/translator/LoopInfo.cpp | 211 - .../angle/src/compiler/translator/LoopInfo.h | 80 - .../angle/src/compiler/translator/MMap.h | 56 - .../src/compiler/translator/NodeSearch.h | 19 +- .../src/compiler/translator/Operator.cpp | 500 +- .../angle/src/compiler/translator/Operator.h | 126 +- .../src/compiler/translator/OutputESSL.cpp | 17 +- .../src/compiler/translator/OutputESSL.h | 23 +- .../src/compiler/translator/OutputGLSL.cpp | 80 +- .../src/compiler/translator/OutputGLSL.h | 17 +- .../compiler/translator/OutputGLSLBase.cpp | 1856 +++-- .../src/compiler/translator/OutputGLSLBase.h | 76 +- .../src/compiler/translator/OutputHLSL.cpp | 3674 ++++------ .../src/compiler/translator/OutputHLSL.h | 182 +- .../src/compiler/translator/OutputTree.cpp | 682 ++ .../src/compiler/translator/OutputTree.h | 22 + .../compiler/translator/OutputVulkanGLSL.cpp | 80 + .../compiler/translator/OutputVulkanGLSL.h | 34 + .../angle/src/compiler/translator/ParamType.h | 102 + .../src/compiler/translator/ParseContext.cpp | 6382 ++++++++++------ .../src/compiler/translator/ParseContext.h | 751 +- .../src/compiler/translator/PoolAlloc.cpp | 227 +- .../angle/src/compiler/translator/PoolAlloc.h | 224 +- .../angle/src/compiler/translator/Pragma.h | 9 +- .../translator/PruneEmptyDeclarations.cpp | 81 - .../translator/PruneEmptyDeclarations.h | 15 - .../src/compiler/translator/PruneNoOps.cpp | 156 + .../src/compiler/translator/PruneNoOps.h | 24 + .../compiler/translator/QualifierAlive.cpp | 58 - .../src/compiler/translator/QualifierAlive.h | 12 - .../compiler/translator/QualifierTypes.cpp | 784 ++ .../src/compiler/translator/QualifierTypes.h | 191 + .../translator/RecordConstantPrecision.cpp | 94 +- .../translator/RecordConstantPrecision.h | 23 +- .../translator/RegenerateStructNames.cpp | 34 +- .../translator/RegenerateStructNames.h | 20 +- .../translator/RemoveArrayLengthMethod.cpp | 83 + .../translator/RemoveArrayLengthMethod.h | 29 + .../translator/RemoveDynamicIndexing.cpp | 319 +- .../translator/RemoveDynamicIndexing.h | 12 +- .../RemoveEmptySwitchStatements.cpp | 56 + .../translator/RemoveEmptySwitchStatements.h | 18 + .../translator/RemoveInvariantDeclaration.cpp | 43 + .../translator/RemoveInvariantDeclaration.h | 18 + ...moveNoOpCasesFromEndOfSwitchStatements.cpp | 116 + ...RemoveNoOpCasesFromEndOfSwitchStatements.h | 21 + .../src/compiler/translator/RemovePow.cpp | 36 +- .../angle/src/compiler/translator/RemovePow.h | 5 +- .../translator/RemoveSwitchFallThrough.cpp | 209 +- .../translator/RemoveSwitchFallThrough.h | 42 +- .../RemoveUnreferencedVariables.cpp | 358 + .../translator/RemoveUnreferencedVariables.h | 24 + .../src/compiler/translator/RenameFunction.h | 36 - .../compiler/translator/RewriteDoWhile.cpp | 64 +- .../src/compiler/translator/RewriteDoWhile.h | 9 +- .../compiler/translator/RewriteElseBlocks.cpp | 126 +- .../compiler/translator/RewriteElseBlocks.h | 8 +- .../translator/RewriteTexelFetchOffset.cpp | 154 + .../translator/RewriteTexelFetchOffset.h | 28 + .../RewriteUnaryMinusOperatorFloat.cpp | 94 + .../RewriteUnaryMinusOperatorFloat.h | 19 + .../RewriteUnaryMinusOperatorInt.cpp | 112 + .../translator/RewriteUnaryMinusOperatorInt.h | 20 + .../translator/RunAtTheEndOfShader.cpp | 112 + .../compiler/translator/RunAtTheEndOfShader.h | 23 + .../ScalarizeVecAndMatConstructorArgs.cpp | 283 +- .../ScalarizeVecAndMatConstructorArgs.h | 47 +- .../src/compiler/translator/SearchSymbol.cpp | 3 +- .../src/compiler/translator/SearchSymbol.h | 4 +- .../SeparateArrayInitialization.cpp | 68 +- .../translator/SeparateArrayInitialization.h | 6 +- .../translator/SeparateDeclarations.cpp | 52 +- .../translator/SeparateDeclarations.h | 7 +- .../SeparateExpressionsReturningArrays.cpp | 141 +- .../SeparateExpressionsReturningArrays.h | 12 +- .../angle/src/compiler/translator/Severity.h | 22 + .../src/compiler/translator/ShaderLang.cpp | 456 +- .../src/compiler/translator/ShaderVars.cpp | 397 +- .../translator/SimplifyArrayAssignment.cpp | 38 - .../translator/SimplifyArrayAssignment.h | 25 - .../translator/SimplifyLoopConditions.cpp | 300 + .../translator/SimplifyLoopConditions.h | 25 + .../translator/SplitSequenceOperator.cpp | 171 + .../translator/SplitSequenceOperator.h | 28 + .../src/compiler/translator/StructureHLSL.cpp | 466 +- .../src/compiler/translator/StructureHLSL.h | 43 +- .../src/compiler/translator/SymbolTable.cpp | 448 +- .../src/compiler/translator/SymbolTable.h | 486 +- .../compiler/translator/SymbolUniqueId.cpp | 28 + .../src/compiler/translator/SymbolUniqueId.h | 36 + .../translator/TextureFunctionHLSL.cpp | 1322 ++++ .../compiler/translator/TextureFunctionHLSL.h | 76 + .../compiler/translator/TranslatorESSL.cpp | 146 +- .../src/compiler/translator/TranslatorESSL.h | 15 +- .../compiler/translator/TranslatorGLSL.cpp | 214 +- .../src/compiler/translator/TranslatorGLSL.h | 17 +- .../compiler/translator/TranslatorHLSL.cpp | 119 +- .../src/compiler/translator/TranslatorHLSL.h | 21 +- .../compiler/translator/TranslatorVulkan.cpp | 173 + .../compiler/translator/TranslatorVulkan.h | 34 + .../angle/src/compiler/translator/Types.cpp | 1047 ++- .../angle/src/compiler/translator/Types.h | 697 +- .../translator/UnfoldShortCircuit.cpp | 185 - .../compiler/translator/UnfoldShortCircuit.h | 38 - .../translator/UnfoldShortCircuitAST.cpp | 44 +- .../translator/UnfoldShortCircuitAST.h | 12 +- .../translator/UnfoldShortCircuitToIf.cpp | 322 +- .../translator/UnfoldShortCircuitToIf.h | 13 +- .../src/compiler/translator/UniformHLSL.cpp | 438 +- .../src/compiler/translator/UniformHLSL.h | 85 +- .../translator/UseInterfaceBlockFields.cpp | 105 + .../translator/UseInterfaceBlockFields.h | 30 + .../src/compiler/translator/UtilsHLSL.cpp | 794 +- .../angle/src/compiler/translator/UtilsHLSL.h | 85 +- .../translator/ValidateGlobalInitializer.cpp | 62 +- .../translator/ValidateGlobalInitializer.h | 11 +- .../translator/ValidateLimitations.cpp | 393 +- .../compiler/translator/ValidateLimitations.h | 58 +- .../translator/ValidateMaxParameters.cpp | 29 + .../translator/ValidateMaxParameters.h | 21 + .../compiler/translator/ValidateOutputs.cpp | 120 +- .../src/compiler/translator/ValidateOutputs.h | 34 +- .../compiler/translator/ValidateSwitch.cpp | 179 +- .../src/compiler/translator/ValidateSwitch.h | 52 +- .../translator/ValidateVaryingLocations.cpp | 174 + .../translator/ValidateVaryingLocations.h | 25 + .../src/compiler/translator/VariableInfo.cpp | 673 -- .../src/compiler/translator/VariableInfo.h | 77 - .../compiler/translator/VariablePacker.cpp | 394 +- .../src/compiler/translator/VariablePacker.h | 39 +- .../VectorizeVectorScalarArithmetic.cpp | 284 + .../VectorizeVectorScalarArithmetic.h | 25 + .../src/compiler/translator/VersionGLSL.cpp | 153 +- .../src/compiler/translator/VersionGLSL.h | 14 +- .../WrapSwitchStatementsInBlocks.cpp | 132 + .../translator/WrapSwitchStatementsInBlocks.h | 22 + .../src/compiler/translator/blocklayout.cpp | 191 +- .../src/compiler/translator/blocklayout.h | 77 +- .../compiler/translator/blocklayoutHLSL.cpp | 63 +- .../src/compiler/translator/blocklayoutHLSL.h | 32 +- .../src/compiler/translator/compilerdebug.cpp | 37 - .../src/compiler/translator/compilerdebug.h | 53 - .../translator/depgraph/DependencyGraph.cpp | 95 - .../translator/depgraph/DependencyGraph.h | 199 - .../depgraph/DependencyGraphBuilder.cpp | 255 - .../depgraph/DependencyGraphBuilder.h | 199 - .../depgraph/DependencyGraphOutput.cpp | 64 - .../depgraph/DependencyGraphOutput.h | 31 - .../depgraph/DependencyGraphTraverse.cpp | 69 - .../emulated_builtin_function_data_hlsl.json | 1382 ++++ ...mulated_builtin_functions_hlsl_autogen.cpp | 859 +++ .../angle/src/compiler/translator/glslang.h | 16 +- .../angle/src/compiler/translator/glslang.l | 183 +- .../angle/src/compiler/translator/glslang.y | 1039 ++- .../src/compiler/translator/intermOut.cpp | 626 -- .../src/compiler/translator/length_limits.h | 7 +- .../src/compiler/translator/parseConst.cpp | 264 - .../timing/RestrictFragmentShaderTiming.cpp | 130 - .../timing/RestrictFragmentShaderTiming.h | 39 - .../timing/RestrictVertexShaderTiming.cpp | 17 - .../timing/RestrictVertexShaderTiming.h | 32 - .../angle/src/compiler/translator/util.cpp | 784 +- .../angle/src/compiler/translator/util.h | 60 +- .../angle/src/gpu_info_util/SystemInfo.cpp | 171 + .../angle/src/gpu_info_util/SystemInfo.h | 73 + .../src/gpu_info_util/SystemInfo_internal.h | 38 + .../src/gpu_info_util/SystemInfo_libpci.cpp | 132 + .../src/gpu_info_util/SystemInfo_linux.cpp | 144 + .../angle/src/gpu_info_util/SystemInfo_mac.mm | 170 + .../src/gpu_info_util/SystemInfo_win.cpp | 251 + .../src/gpu_info_util/SystemInfo_x11.cpp | 53 + src/3rdparty/angle/src/id/commit.h | 3 - .../angle/src/image_util/copyimage.cpp | 22 + .../renderer/d3d => image_util}/copyimage.h | 15 +- .../renderer/d3d => image_util}/copyimage.inl | 10 +- .../angle/src/image_util/generatemip.h | 34 + .../d3d => image_util}/generatemip.inl | 14 +- .../angle/src/image_util/imageformats.cpp | 1722 +++++ .../angle/src/image_util/imageformats.h | 700 ++ .../angle/src/image_util/loadimage.cpp | 1323 ++++ src/3rdparty/angle/src/image_util/loadimage.h | 658 ++ .../renderer/d3d => image_util}/loadimage.inl | 33 +- .../d3d => image_util}/loadimage_etc.cpp | 686 +- .../angle/src/libANGLE/AttributeMap.cpp | 85 +- .../angle/src/libANGLE/AttributeMap.h | 22 +- .../angle/src/libANGLE/BinaryStream.h | 97 +- src/3rdparty/angle/src/libANGLE/Buffer.cpp | 187 +- src/3rdparty/angle/src/libANGLE/Buffer.h | 104 +- src/3rdparty/angle/src/libANGLE/Caps.cpp | 948 ++- src/3rdparty/angle/src/libANGLE/Caps.h | 289 +- src/3rdparty/angle/src/libANGLE/Compiler.cpp | 143 +- src/3rdparty/angle/src/libANGLE/Compiler.h | 20 +- src/3rdparty/angle/src/libANGLE/Config.cpp | 36 +- src/3rdparty/angle/src/libANGLE/Config.h | 11 +- src/3rdparty/angle/src/libANGLE/Constants.h | 40 +- src/3rdparty/angle/src/libANGLE/Context.cpp | 5770 +++++++++++---- src/3rdparty/angle/src/libANGLE/Context.h | 1043 ++- .../angle/src/libANGLE/ContextState.cpp | 839 +++ .../angle/src/libANGLE/ContextState.h | 164 + src/3rdparty/angle/src/libANGLE/Data.cpp | 56 - src/3rdparty/angle/src/libANGLE/Data.h | 72 - src/3rdparty/angle/src/libANGLE/Debug.cpp | 24 + src/3rdparty/angle/src/libANGLE/Debug.h | 9 + src/3rdparty/angle/src/libANGLE/Device.cpp | 21 +- src/3rdparty/angle/src/libANGLE/Display.cpp | 818 ++- src/3rdparty/angle/src/libANGLE/Display.h | 124 +- src/3rdparty/angle/src/libANGLE/Error.cpp | 58 +- src/3rdparty/angle/src/libANGLE/Error.h | 205 +- src/3rdparty/angle/src/libANGLE/Error.inl | 32 +- .../angle/src/libANGLE/ErrorStrings.h | 173 + src/3rdparty/angle/src/libANGLE/Fence.cpp | 48 +- src/3rdparty/angle/src/libANGLE/Fence.h | 16 +- .../angle/src/libANGLE/Framebuffer.cpp | 2221 ++++-- src/3rdparty/angle/src/libANGLE/Framebuffer.h | 317 +- .../src/libANGLE/FramebufferAttachment.cpp | 227 +- .../src/libANGLE/FramebufferAttachment.h | 230 +- .../angle/src/libANGLE/HandleAllocator.cpp | 34 +- .../angle/src/libANGLE/HandleAllocator.h | 8 +- .../src/libANGLE/HandleRangeAllocator.cpp | 229 + .../angle/src/libANGLE/HandleRangeAllocator.h | 60 + src/3rdparty/angle/src/libANGLE/Image.cpp | 207 +- src/3rdparty/angle/src/libANGLE/Image.h | 66 +- .../angle/src/libANGLE/ImageIndex.cpp | 130 +- src/3rdparty/angle/src/libANGLE/ImageIndex.h | 14 +- .../angle/src/libANGLE/IndexRangeCache.cpp | 8 + .../angle/src/libANGLE/IndexRangeCache.h | 3 + .../angle/src/libANGLE/LoggingAnnotator.cpp | 44 + .../angle/src/libANGLE/LoggingAnnotator.h | 31 + .../angle/src/libANGLE/MemoryProgramCache.cpp | 772 ++ .../angle/src/libANGLE/MemoryProgramCache.h | 130 + .../angle/src/libANGLE/PackedGLEnums.h | 111 + .../src/libANGLE/PackedGLEnums_autogen.cpp | 174 + .../src/libANGLE/PackedGLEnums_autogen.h | 84 + src/3rdparty/angle/src/libANGLE/Path.cpp | 78 + src/3rdparty/angle/src/libANGLE/Path.h | 71 + src/3rdparty/angle/src/libANGLE/Platform.cpp | 56 +- src/3rdparty/angle/src/libANGLE/Program.cpp | 3135 ++++---- src/3rdparty/angle/src/libANGLE/Program.h | 669 +- .../src/libANGLE/ProgramLinkedResources.cpp | 1040 +++ .../src/libANGLE/ProgramLinkedResources.h | 274 + .../angle/src/libANGLE/ProgramPipeline.cpp | 65 + .../angle/src/libANGLE/ProgramPipeline.h | 65 + src/3rdparty/angle/src/libANGLE/Query.h | 3 +- .../angle/src/libANGLE/RefCountObject.cpp | 39 - .../angle/src/libANGLE/RefCountObject.h | 90 +- .../angle/src/libANGLE/Renderbuffer.cpp | 147 +- .../angle/src/libANGLE/Renderbuffer.h | 43 +- .../angle/src/libANGLE/ResourceManager.cpp | 779 +- .../angle/src/libANGLE/ResourceManager.h | 326 +- src/3rdparty/angle/src/libANGLE/ResourceMap.h | 305 + src/3rdparty/angle/src/libANGLE/Sampler.cpp | 73 +- src/3rdparty/angle/src/libANGLE/Sampler.h | 19 +- src/3rdparty/angle/src/libANGLE/Shader.cpp | 387 +- src/3rdparty/angle/src/libANGLE/Shader.h | 212 +- .../angle/src/libANGLE/SizedMRUCache.h | 174 + src/3rdparty/angle/src/libANGLE/State.cpp | 1256 +++- src/3rdparty/angle/src/libANGLE/State.h | 348 +- src/3rdparty/angle/src/libANGLE/Stream.cpp | 271 + src/3rdparty/angle/src/libANGLE/Stream.h | 143 + src/3rdparty/angle/src/libANGLE/Surface.cpp | 389 +- src/3rdparty/angle/src/libANGLE/Surface.h | 163 +- src/3rdparty/angle/src/libANGLE/Texture.cpp | 1945 +++-- src/3rdparty/angle/src/libANGLE/Texture.h | 357 +- src/3rdparty/angle/src/libANGLE/Thread.cpp | 91 + src/3rdparty/angle/src/libANGLE/Thread.h | 51 + .../angle/src/libANGLE/TransformFeedback.cpp | 169 +- .../angle/src/libANGLE/TransformFeedback.h | 81 +- src/3rdparty/angle/src/libANGLE/Uniform.cpp | 205 +- src/3rdparty/angle/src/libANGLE/Uniform.h | 132 +- .../{renderer/d3d => }/VaryingPacking.cpp | 357 +- .../{renderer/d3d => }/VaryingPacking.h | 99 +- src/3rdparty/angle/src/libANGLE/Version.h | 15 +- src/3rdparty/angle/src/libANGLE/Version.inl | 38 +- .../angle/src/libANGLE/VertexArray.cpp | 237 +- src/3rdparty/angle/src/libANGLE/VertexArray.h | 186 +- .../angle/src/libANGLE/VertexAttribute.cpp | 122 +- .../angle/src/libANGLE/VertexAttribute.h | 84 +- .../angle/src/libANGLE/VertexAttribute.inl | 47 +- src/3rdparty/angle/src/libANGLE/Workarounds.h | 29 + .../angle/src/libANGLE/WorkerThread.cpp | 157 + .../angle/src/libANGLE/WorkerThread.h | 284 + .../angle/src/libANGLE/angletypes.cpp | 170 +- src/3rdparty/angle/src/libANGLE/angletypes.h | 305 +- .../angle/src/libANGLE/angletypes.inl | 47 +- .../src/libANGLE/entry_points_enum_autogen.h | 336 + .../libANGLE/es3_copy_conversion_formats.json | 44 + .../es3_copy_conversion_table_autogen.cpp | 171 + .../es3_format_type_combinations.json | 171 + src/3rdparty/angle/src/libANGLE/features.h | 12 + .../angle/src/libANGLE/format_map_autogen.cpp | 1570 ++++ .../angle/src/libANGLE/format_map_data.json | 142 + .../angle/src/libANGLE/formatutils.cpp | 1361 +++- src/3rdparty/angle/src/libANGLE/formatutils.h | 143 +- .../angle/src/libANGLE/histogram_macros.h | 67 +- .../angle/src/libANGLE/packed_gl_enums.json | 35 + src/3rdparty/angle/src/libANGLE/params.cpp | 68 + src/3rdparty/angle/src/libANGLE/params.h | 228 + .../angle/src/libANGLE/queryconversions.cpp | 212 +- .../angle/src/libANGLE/queryconversions.h | 87 +- .../angle/src/libANGLE/queryutils.cpp | 1916 +++++ src/3rdparty/angle/src/libANGLE/queryutils.h | 162 + .../angle/src/libANGLE/renderer/BufferImpl.h | 49 +- .../src/libANGLE/renderer/BufferImpl_mock.h | 30 +- .../src/libANGLE/renderer/ContextImpl.cpp | 119 + .../angle/src/libANGLE/renderer/ContextImpl.h | 186 + .../src/libANGLE/renderer/DisplayImpl.cpp | 25 +- .../angle/src/libANGLE/renderer/DisplayImpl.h | 60 +- .../src/libANGLE/renderer/EGLImplFactory.h | 68 + .../angle/src/libANGLE/renderer/Format.h | 105 + .../libANGLE/renderer/Format_ID_autogen.inl | 147 + .../renderer/Format_table_autogen.cpp | 434 ++ .../FramebufferAttachmentObjectImpl.h | 54 + .../src/libANGLE/renderer/FramebufferImpl.h | 61 +- .../libANGLE/renderer/FramebufferImpl_mock.h | 49 +- .../src/libANGLE/renderer/GLImplFactory.h | 93 + .../angle/src/libANGLE/renderer/Image.h | 77 - .../angle/src/libANGLE/renderer/ImageImpl.h | 16 +- .../src/libANGLE/renderer/ImageImpl_mock.h | 10 +- .../angle/src/libANGLE/renderer/ImplFactory.h | 74 - .../angle/src/libANGLE/renderer/PathImpl.h | 36 + .../src/libANGLE/renderer/ProgramImpl.cpp | 152 - .../angle/src/libANGLE/renderer/ProgramImpl.h | 68 +- .../src/libANGLE/renderer/ProgramImpl_mock.h | 29 +- .../libANGLE/renderer/ProgramPipelineImpl.h | 32 + .../libANGLE/renderer/RenderbufferImpl.cpp | 21 - .../src/libANGLE/renderer/RenderbufferImpl.h | 22 +- .../libANGLE/renderer/RenderbufferImpl_mock.h | 13 +- .../angle/src/libANGLE/renderer/Renderer.cpp | 62 - .../angle/src/libANGLE/renderer/Renderer.h | 121 - .../angle/src/libANGLE/renderer/SamplerImpl.h | 20 +- .../angle/src/libANGLE/renderer/ShaderImpl.h | 12 +- .../libANGLE/renderer/StreamProducerImpl.h | 39 + .../src/libANGLE/renderer/SurfaceImpl.cpp | 8 +- .../angle/src/libANGLE/renderer/SurfaceImpl.h | 35 +- .../renderer/{FenceSyncImpl.h => SyncImpl.h} | 11 +- .../src/libANGLE/renderer/TextureImpl.cpp | 63 + .../angle/src/libANGLE/renderer/TextureImpl.h | 122 +- .../src/libANGLE/renderer/TextureImpl_mock.h | 114 +- .../libANGLE/renderer/TransformFeedbackImpl.h | 9 +- .../renderer/TransformFeedbackImpl_mock.h | 8 +- .../src/libANGLE/renderer/VertexArrayImpl.h | 14 +- .../angle/src/libANGLE/renderer/Workarounds.h | 74 - .../libANGLE/renderer/angle_format_data.json | 24 + .../libANGLE/renderer/angle_format_map.json | 132 + .../src/libANGLE/renderer/d3d/BufferD3D.cpp | 222 +- .../src/libANGLE/renderer/d3d/BufferD3D.h | 54 +- .../src/libANGLE/renderer/d3d/CompilerD3D.cpp | 10 + .../src/libANGLE/renderer/d3d/CompilerD3D.h | 4 +- .../src/libANGLE/renderer/d3d/DeviceD3D.cpp | 27 +- .../src/libANGLE/renderer/d3d/DeviceD3D.h | 2 +- .../src/libANGLE/renderer/d3d/DisplayD3D.cpp | 195 +- .../src/libANGLE/renderer/d3d/DisplayD3D.h | 43 +- .../src/libANGLE/renderer/d3d/DynamicHLSL.cpp | 718 +- .../src/libANGLE/renderer/d3d/DynamicHLSL.h | 123 +- .../src/libANGLE/renderer/d3d/EGLImageD3D.cpp | 89 +- .../src/libANGLE/renderer/d3d/EGLImageD3D.h | 27 +- .../libANGLE/renderer/d3d/FramebufferD3D.cpp | 305 +- .../libANGLE/renderer/d3d/FramebufferD3D.h | 81 +- .../libANGLE/renderer/d3d/HLSLCompiler.cpp | 86 +- .../src/libANGLE/renderer/d3d/HLSLCompiler.h | 12 +- .../src/libANGLE/renderer/d3d/ImageD3D.cpp | 30 + .../src/libANGLE/renderer/d3d/ImageD3D.h | 41 +- .../src/libANGLE/renderer/d3d/IndexBuffer.cpp | 27 +- .../src/libANGLE/renderer/d3d/IndexBuffer.h | 4 +- .../renderer/d3d/IndexDataManager.cpp | 256 +- .../libANGLE/renderer/d3d/IndexDataManager.h | 42 +- .../libANGLE/renderer/d3d/NativeWindowD3D.cpp | 23 + .../libANGLE/renderer/d3d/NativeWindowD3D.h | 38 + .../src/libANGLE/renderer/d3d/ProgramD3D.cpp | 2289 +++--- .../src/libANGLE/renderer/d3d/ProgramD3D.h | 329 +- .../libANGLE/renderer/d3d/RenderTargetD3D.h | 6 +- .../libANGLE/renderer/d3d/RenderbufferD3D.cpp | 77 +- .../libANGLE/renderer/d3d/RenderbufferD3D.h | 25 +- .../src/libANGLE/renderer/d3d/RendererD3D.cpp | 717 +- .../src/libANGLE/renderer/d3d/RendererD3D.h | 383 +- .../src/libANGLE/renderer/d3d/SamplerD3D.h | 2 +- .../src/libANGLE/renderer/d3d/ShaderD3D.cpp | 100 +- .../src/libANGLE/renderer/d3d/ShaderD3D.h | 44 +- .../renderer/d3d/ShaderExecutableD3D.cpp | 16 +- .../renderer/d3d/ShaderExecutableD3D.h | 7 +- .../src/libANGLE/renderer/d3d/SurfaceD3D.cpp | 274 +- .../src/libANGLE/renderer/d3d/SurfaceD3D.h | 95 +- .../libANGLE/renderer/d3d/SwapChainD3D.cpp | 34 + .../src/libANGLE/renderer/d3d/SwapChainD3D.h | 53 +- .../src/libANGLE/renderer/d3d/TextureD3D.cpp | 3102 +++++--- .../src/libANGLE/renderer/d3d/TextureD3D.h | 836 ++- .../libANGLE/renderer/d3d/TextureStorage.cpp | 39 - .../libANGLE/renderer/d3d/TextureStorage.h | 44 +- .../renderer/d3d/TransformFeedbackD3D.cpp | 46 - .../renderer/d3d/TransformFeedbackD3D.h | 35 - .../libANGLE/renderer/d3d/VertexBuffer.cpp | 401 +- .../src/libANGLE/renderer/d3d/VertexBuffer.h | 116 +- .../renderer/d3d/VertexDataManager.cpp | 770 +- .../libANGLE/renderer/d3d/VertexDataManager.h | 108 +- .../libANGLE/renderer/d3d/WorkaroundsD3D.h | 66 - .../src/libANGLE/renderer/d3d/copyimage.cpp | 22 - .../libANGLE/renderer/d3d/d3d11/Blit11.cpp | 2532 ++++--- .../src/libANGLE/renderer/d3d/d3d11/Blit11.h | 224 +- .../libANGLE/renderer/d3d/d3d11/Buffer11.cpp | 1471 ++-- .../libANGLE/renderer/d3d/d3d11/Buffer11.h | 172 +- .../libANGLE/renderer/d3d/d3d11/Clear11.cpp | 1222 ++-- .../src/libANGLE/renderer/d3d/d3d11/Clear11.h | 105 +- .../libANGLE/renderer/d3d/d3d11/Context11.cpp | 405 ++ .../libANGLE/renderer/d3d/d3d11/Context11.h | 155 + .../renderer/d3d/d3d11/DebugAnnotator11.cpp | 47 +- .../renderer/d3d/d3d11/DebugAnnotator11.h | 6 +- .../libANGLE/renderer/d3d/d3d11/Fence11.cpp | 107 +- .../src/libANGLE/renderer/d3d/d3d11/Fence11.h | 11 +- .../renderer/d3d/d3d11/Framebuffer11.cpp | 473 +- .../renderer/d3d/d3d11/Framebuffer11.h | 78 +- .../libANGLE/renderer/d3d/d3d11/Image11.cpp | 593 +- .../src/libANGLE/renderer/d3d/d3d11/Image11.h | 59 +- .../renderer/d3d/d3d11/IndexBuffer11.cpp | 62 +- .../renderer/d3d/d3d11/IndexBuffer11.h | 23 +- .../renderer/d3d/d3d11/InputLayoutCache.cpp | 468 +- .../renderer/d3d/d3d11/InputLayoutCache.h | 142 +- .../renderer/d3d/d3d11/NativeWindow.h | 97 - .../renderer/d3d/d3d11/NativeWindow11.h | 38 + .../renderer/d3d/d3d11/PixelTransfer11.cpp | 199 +- .../renderer/d3d/d3d11/PixelTransfer11.h | 34 +- .../renderer/d3d/d3d11/ProgramPipeline11.cpp | 24 + .../renderer/d3d/d3d11/ProgramPipeline11.h | 27 + .../libANGLE/renderer/d3d/d3d11/Query11.cpp | 373 +- .../src/libANGLE/renderer/d3d/d3d11/Query11.h | 47 +- .../renderer/d3d/d3d11/RenderStateCache.cpp | 547 +- .../renderer/d3d/d3d11/RenderStateCache.h | 137 +- .../renderer/d3d/d3d11/RenderTarget11.cpp | 341 +- .../renderer/d3d/d3d11/RenderTarget11.h | 90 +- .../renderer/d3d/d3d11/Renderer11.cpp | 4242 ++++++----- .../libANGLE/renderer/d3d/d3d11/Renderer11.h | 565 +- .../renderer/d3d/d3d11/ResourceManager11.cpp | 533 ++ .../renderer/d3d/d3d11/ResourceManager11.h | 366 + .../renderer/d3d/d3d11/ShaderExecutable11.cpp | 111 +- .../renderer/d3d/d3d11/ShaderExecutable11.h | 41 +- .../renderer/d3d/d3d11/StateManager11.cpp | 2863 ++++++-- .../renderer/d3d/d3d11/StateManager11.h | 490 +- .../renderer/d3d/d3d11/StreamProducerNV12.cpp | 102 + .../renderer/d3d/d3d11/StreamProducerNV12.h | 44 + .../renderer/d3d/d3d11/SwapChain11.cpp | 754 +- .../libANGLE/renderer/d3d/d3d11/SwapChain11.h | 111 +- .../renderer/d3d/d3d11/TextureStorage11.cpp | 3813 +++++----- .../renderer/d3d/d3d11/TextureStorage11.h | 547 +- .../d3d/d3d11/TransformFeedback11.cpp | 124 + .../renderer/d3d/d3d11/TransformFeedback11.h | 60 + .../libANGLE/renderer/d3d/d3d11/Trim11.cpp | 9 +- .../src/libANGLE/renderer/d3d/d3d11/Trim11.h | 4 +- .../renderer/d3d/d3d11/VertexArray11.cpp | 413 ++ .../renderer/d3d/d3d11/VertexArray11.h | 82 +- .../renderer/d3d/d3d11/VertexBuffer11.cpp | 149 +- .../renderer/d3d/d3d11/VertexBuffer11.h | 25 +- .../renderer/d3d/d3d11/copyvertex.inl | 45 +- .../renderer/d3d/d3d11/dxgi_format_data.json | 118 + .../d3d/d3d11/dxgi_format_map_autogen.cpp | 516 ++ .../renderer/d3d/d3d11/dxgi_support_data.json | 623 +- .../renderer/d3d/d3d11/dxgi_support_table.cpp | 1898 ++++- .../renderer/d3d/d3d11/dxgi_support_table.h | 5 + .../renderer/d3d/d3d11/formatutils11.cpp | 1144 ++- .../renderer/d3d/d3d11/formatutils11.h | 56 +- .../d3d/d3d11/gen_load_functions_table.cpp | 0 .../internal_format_initializer_table.cpp | 170 - .../d3d11/internal_format_initializer_table.h | 31 - .../d3d/d3d11/load_functions_data.json | 1116 --- .../renderer/d3d/d3d11/load_functions_table.h | 31 - .../d3d11/load_functions_table_autogen.cpp | 2098 ------ .../renderer/d3d/d3d11/renderer11_utils.cpp | 3051 +++++--- .../renderer/d3d/d3d11/renderer11_utils.h | 381 +- .../renderer/d3d/d3d11/shaders/Clear11.hlsl | 654 +- .../d3d/d3d11/shaders/MultiplyAlpha.hlsl | 131 + .../d3d/d3d11/shaders/Passthrough2D11.hlsl | 11 + .../d3d11/shaders/ResolveDepthStencil.hlsl | 56 + .../compiled/passthroughrgba2dms11ps.h | 155 + .../d3d/d3d11/swizzle_format_data.json | 77 - .../renderer/d3d/d3d11/swizzle_format_info.h | 51 - .../d3d/d3d11/swizzle_format_info_autogen.cpp | 203 - .../d3d/d3d11/texture_format_data.json | 1199 ++- .../d3d/d3d11/texture_format_map.json | 78 + .../d3d/d3d11/texture_format_table.cpp | 35 + .../renderer/d3d/d3d11/texture_format_table.h | 85 +- .../d3d11/texture_format_table_autogen.cpp | 3041 ++++---- .../d3d/d3d11/texture_format_table_utils.h | 85 + ...tiveWindow.cpp => NativeWindow11Win32.cpp} | 145 +- .../d3d/d3d11/win32/NativeWindow11Win32.h | 53 + .../d3d11/winrt/CoreWindowNativeWindow.cpp | 67 +- .../d3d/d3d11/winrt/CoreWindowNativeWindow.h | 48 +- .../d3d11/winrt/InspectableNativeWindow.cpp | 131 +- .../d3d/d3d11/winrt/InspectableNativeWindow.h | 38 +- .../d3d/d3d11/winrt/NativeWindow11WinRT.cpp | 126 + .../d3d/d3d11/winrt/NativeWindow11WinRT.h | 51 + .../winrt/SwapChainPanelNativeWindow.cpp | 61 +- .../d3d11/winrt/SwapChainPanelNativeWindow.h | 10 +- .../src/libANGLE/renderer/d3d/d3d9/Blit9.cpp | 438 +- .../src/libANGLE/renderer/d3d/d3d9/Blit9.h | 82 +- .../libANGLE/renderer/d3d/d3d9/Buffer9.cpp | 82 +- .../src/libANGLE/renderer/d3d/d3d9/Buffer9.h | 46 +- .../libANGLE/renderer/d3d/d3d9/Context9.cpp | 303 + .../src/libANGLE/renderer/d3d/d3d9/Context9.h | 151 + .../renderer/d3d/d3d9/DebugAnnotator9.h | 4 +- .../src/libANGLE/renderer/d3d/d3d9/Fence9.cpp | 19 +- .../src/libANGLE/renderer/d3d/d3d9/Fence9.h | 2 +- .../renderer/d3d/d3d9/Framebuffer9.cpp | 201 +- .../libANGLE/renderer/d3d/d3d9/Framebuffer9.h | 36 +- .../src/libANGLE/renderer/d3d/d3d9/Image9.cpp | 303 +- .../src/libANGLE/renderer/d3d/d3d9/Image9.h | 44 +- .../renderer/d3d/d3d9/IndexBuffer9.cpp | 33 +- .../libANGLE/renderer/d3d/d3d9/IndexBuffer9.h | 16 +- .../renderer/d3d/d3d9/NativeWindow9.cpp | 39 + .../renderer/d3d/d3d9/NativeWindow9.h | 35 + .../src/libANGLE/renderer/d3d/d3d9/Query9.cpp | 82 +- .../src/libANGLE/renderer/d3d/d3d9/Query9.h | 18 +- .../renderer/d3d/d3d9/RenderTarget9.cpp | 3 +- .../renderer/d3d/d3d9/RenderTarget9.h | 6 +- .../libANGLE/renderer/d3d/d3d9/Renderer9.cpp | 2168 +++--- .../libANGLE/renderer/d3d/d3d9/Renderer9.h | 401 +- .../libANGLE/renderer/d3d/d3d9/ShaderCache.h | 10 +- .../renderer/d3d/d3d9/ShaderExecutable9.cpp | 6 +- .../renderer/d3d/d3d9/ShaderExecutable9.h | 2 +- .../renderer/d3d/d3d9/StateManager9.cpp | 96 +- .../renderer/d3d/d3d9/StateManager9.h | 13 +- .../libANGLE/renderer/d3d/d3d9/SwapChain9.cpp | 125 +- .../libANGLE/renderer/d3d/d3d9/SwapChain9.h | 30 +- .../renderer/d3d/d3d9/TextureStorage9.cpp | 219 +- .../renderer/d3d/d3d9/TextureStorage9.h | 84 +- .../libANGLE/renderer/d3d/d3d9/VertexArray9.h | 24 +- .../renderer/d3d/d3d9/VertexBuffer9.cpp | 94 +- .../renderer/d3d/d3d9/VertexBuffer9.h | 18 +- .../d3d/d3d9/VertexDeclarationCache.cpp | 46 +- .../d3d/d3d9/VertexDeclarationCache.h | 1 + .../renderer/d3d/d3d9/formatutils9.cpp | 325 +- .../libANGLE/renderer/d3d/d3d9/formatutils9.h | 26 +- .../renderer/d3d/d3d9/renderer9_utils.cpp | 104 +- .../renderer/d3d/d3d9/renderer9_utils.h | 11 +- .../renderer/d3d/d3d9/shaders/Blit.ps | 34 + .../renderer/d3d/d3d9/shaders/Blit.vs | 18 +- .../libANGLE/renderer/d3d/formatutilsD3D.cpp | 147 - .../libANGLE/renderer/d3d/formatutilsD3D.h | 28 +- .../src/libANGLE/renderer/d3d/generatemip.h | 28 - .../src/libANGLE/renderer/d3d/imageformats.h | 1999 ----- .../src/libANGLE/renderer/d3d/loadimage.cpp | 697 -- .../src/libANGLE/renderer/d3d/loadimage.h | 201 - .../libANGLE/renderer/d3d/loadimageSSE2.cpp | 125 - .../src/libANGLE/renderer/d3d/loadimage_etc.h | 140 - .../src/libANGLE/renderer/driver_utils.cpp | 120 + .../src/libANGLE/renderer/driver_utils.h | 73 + .../renderer/load_functions_data.json | 602 ++ .../libANGLE/renderer/load_functions_table.h | 22 + .../renderer/load_functions_table_autogen.cpp | 2459 +++++++ .../src/libANGLE/renderer/renderer_utils.cpp | 549 ++ .../src/libANGLE/renderer/renderer_utils.h | 254 + .../angle/src/libANGLE/signal_utils.h | 187 + .../angle/src/libANGLE/validationEGL.cpp | 2015 ++++- .../angle/src/libANGLE/validationEGL.h | 119 +- .../angle/src/libANGLE/validationES.cpp | 5667 +++++++++++---- .../angle/src/libANGLE/validationES.h | 555 +- .../angle/src/libANGLE/validationES2.cpp | 6451 ++++++++++++++--- .../angle/src/libANGLE/validationES2.h | 605 +- .../angle/src/libANGLE/validationES3.cpp | 3662 +++++++--- .../angle/src/libANGLE/validationES3.h | 415 +- .../angle/src/libANGLE/validationES31.cpp | 1786 +++++ .../angle/src/libANGLE/validationES31.h | 325 + src/3rdparty/angle/src/libEGL/libEGL.cpp | 117 + src/3rdparty/angle/src/libEGL/libEGL.def | 125 +- .../angle/src/libEGL/libEGL_mingw32.def | 125 +- src/3rdparty/angle/src/libEGL/libEGLd.def | 125 +- .../angle/src/libEGL/libEGLd_mingw32.def | 48 - .../angle/src/libGLESv2/entry_points_egl.cpp | 1522 ++-- .../src/libGLESv2/entry_points_egl_ext.cpp | 784 +- .../src/libGLESv2/entry_points_egl_ext.h | 67 +- .../src/libGLESv2/entry_points_gles_2_0.cpp | 4155 ----------- .../src/libGLESv2/entry_points_gles_2_0.h | 163 - .../entry_points_gles_2_0_autogen.cpp | 2612 +++++++ .../libGLESv2/entry_points_gles_2_0_autogen.h | 297 + .../libGLESv2/entry_points_gles_2_0_ext.cpp | 2932 ++++++-- .../src/libGLESv2/entry_points_gles_2_0_ext.h | 610 +- .../src/libGLESv2/entry_points_gles_3_0.cpp | 3057 -------- .../src/libGLESv2/entry_points_gles_3_0.h | 125 - .../entry_points_gles_3_0_autogen.cpp | 2084 ++++++ .../libGLESv2/entry_points_gles_3_0_autogen.h | 284 + .../libGLESv2/entry_points_gles_3_0_ext.cpp | 14 - .../src/libGLESv2/entry_points_gles_3_0_ext.h | 23 - .../entry_points_gles_3_1_autogen.cpp | 1430 ++++ .../libGLESv2/entry_points_gles_3_1_autogen.h | 228 + .../angle/src/libGLESv2/global_state.cpp | 266 +- .../angle/src/libGLESv2/global_state.h | 28 +- .../angle/src/libGLESv2/libGLESv2.cpp | 1344 +++- .../angle/src/libGLESv2/libGLESv2.def | 105 +- .../angle/src/libGLESv2/libGLESv2_mingw32.def | 714 +- .../angle/src/libGLESv2/libGLESv2d.def | 105 +- .../src/libGLESv2/libGLESv2d_mingw32.def | 316 - src/3rdparty/angle/src/libGLESv2/proc_table.h | 24 + .../src/libGLESv2/proc_table_autogen.cpp | 548 ++ .../angle/src/libGLESv2/proc_table_data.json | 662 ++ .../compiler/ArrayBoundsClamper.cpp | 10 +- .../third_party/compiler/ArrayBoundsClamper.h | 10 +- .../angle/src/third_party/libXNVCtrl/LICENSE | 22 + .../angle/src/third_party/libXNVCtrl/NVCtrl.c | 1240 ++++ .../angle/src/third_party/libXNVCtrl/NVCtrl.h | 4365 +++++++++++ .../src/third_party/libXNVCtrl/NVCtrlLib.h | 707 ++ .../src/third_party/libXNVCtrl/README.angle | 14 + .../src/third_party/libXNVCtrl/nv_control.h | 652 ++ .../angle/src/third_party/murmurhash/LICENSE | 2 - .../third_party/murmurhash/MurmurHash3.cpp | 335 - .../src/third_party/murmurhash/MurmurHash3.h | 37 - .../src/third_party/systeminfo/SystemInfo.cpp | 2 +- .../src/third_party/trace_event/trace_event.h | 52 +- ...-ANGLE-Improve-Windows-Phone-Support.patch | 464 -- ...e-pixel-sizes-in-the-XAML-swap-chain.patch | 135 + .../patches/0001-Fix-build-for-MinGW.patch | 26 + ...upport-for-querying-platform-device.patch} | 48 +- ...ically-load-D3D-compiler-from-a-list.patch | 62 - .../0002-ANGLE-Fix-build-for-ARM.patch | 43 + ...002-ANGLE-Fix-compilation-with-MinGW.patch | 892 --- ...-Store-D3D-Trim-and-Level-9-require.patch} | 23 +- ...ows-Phone-to-communicate-swap-region.patch | 146 - ...of-shared-handles-for-WinRT-applicat.patch | 37 + ...-ANGLE-Fix-compilation-without-d3d11.patch | 59 - ...initialization-of-zero-sized-window.patch} | 18 +- ...ckering-on-resize-when-D3D9-is-used.patch} | 84 +- ...1-Suppress-keyboard-handling-of-DXGI.patch | 45 - ... 0007-ANGLE-Fix-resizing-of-windows.patch} | 39 +- ...e-pixel-sizes-in-the-XAML-swap-chain.patch | 401 - ...ull-screen-update-if-the-the-window-.patch | 40 + ...Uniform-v-functions-to-work-properly.patch | 31 - ...orWantedComponents-not-ignoring-attr.patch | 67 + ...ltisampling-to-avoid-crash-in-Qt-app.patch | 41 + ...e-of-shared-handles-for-WinRT-WinPho.patch | 57 - ...pport-for-shared-handles-in-warp-mod.patch | 44 - ...with-ltcg-on-Visual-Studio-2015-Upda.patch | 110 - ...3D11_QDTD_AVAILABLE-to-check-struct-.patch | 32 - ...e-usage-of-auto_ptr-in-MacroExpander.patch | 31 - src/angle/src/common/common.pri | 3 +- src/angle/src/common/gles_common.pri | 314 +- .../compiler/preprocessor/preprocessor.pro | 7 +- src/angle/src/compiler/translator.pro | 87 +- src/angle/src/config.pri | 2 +- .../itemviews/qtableview/tst_qtableview.cpp | 1 + 816 files changed, 167666 insertions(+), 78248 deletions(-) delete mode 100644 src/3rdparty/angle/SYSTEMINFO_LICENSE delete mode 100644 src/3rdparty/angle/TRACEEVENT_LICENSE create mode 100644 src/3rdparty/angle/id/commit.h create mode 100644 src/3rdparty/angle/include/EGL/eglext_angle.h create mode 100644 src/3rdparty/angle/include/GLES2/gl2ext_angle.h delete mode 100644 src/3rdparty/angle/include/GLES3/gl3ext.h create mode 100644 src/3rdparty/angle/include/platform/WorkaroundsD3D.h delete mode 100644 src/3rdparty/angle/src/common/BitSetIterator.h create mode 100644 src/3rdparty/angle/src/common/Color.h create mode 100644 src/3rdparty/angle/src/common/Color.inl create mode 100644 src/3rdparty/angle/src/common/bitset_utils.h create mode 100644 src/3rdparty/angle/src/common/system_utils.h create mode 100644 src/3rdparty/angle/src/common/system_utils_linux.cpp create mode 100644 src/3rdparty/angle/src/common/system_utils_mac.cpp create mode 100644 src/3rdparty/angle/src/common/system_utils_win.cpp create mode 100644 src/3rdparty/angle/src/common/third_party/base/README.angle create mode 100644 src/3rdparty/angle/src/common/third_party/base/anglebase/base_export.h create mode 100644 src/3rdparty/angle/src/common/third_party/base/anglebase/containers/mru_cache.h create mode 100644 src/3rdparty/angle/src/common/third_party/base/anglebase/logging.h create mode 100644 src/3rdparty/angle/src/common/third_party/base/anglebase/macros.h create mode 100644 src/3rdparty/angle/src/common/third_party/base/anglebase/numerics/OWNERS create mode 100644 src/3rdparty/angle/src/common/third_party/base/anglebase/numerics/safe_conversions.h create mode 100644 src/3rdparty/angle/src/common/third_party/base/anglebase/numerics/safe_conversions_impl.h create mode 100644 src/3rdparty/angle/src/common/third_party/base/anglebase/numerics/safe_math.h create mode 100644 src/3rdparty/angle/src/common/third_party/base/anglebase/numerics/safe_math_impl.h create mode 100644 src/3rdparty/angle/src/common/third_party/base/anglebase/numerics/safe_numerics_unittest.cc create mode 100644 src/3rdparty/angle/src/common/third_party/base/anglebase/sha1.cc create mode 100644 src/3rdparty/angle/src/common/third_party/base/anglebase/sha1.h create mode 100644 src/3rdparty/angle/src/common/third_party/base/anglebase/sys_byteorder.h create mode 100644 src/3rdparty/angle/src/common/third_party/smhasher/LICENSE create mode 100644 src/3rdparty/angle/src/common/third_party/smhasher/README.angle create mode 100644 src/3rdparty/angle/src/common/third_party/smhasher/src/PMurHash.cpp create mode 100644 src/3rdparty/angle/src/common/third_party/smhasher/src/PMurHash.h create mode 100644 src/3rdparty/angle/src/common/uniform_type_info_autogen.cpp create mode 100644 src/3rdparty/angle/src/common/vector_utils.h create mode 100644 src/3rdparty/angle/src/compiler/fuzz/translator_fuzzer.cpp delete mode 100644 src/3rdparty/angle/src/compiler/preprocessor/pp_utils.h create mode 100644 src/3rdparty/angle/src/compiler/translator/AddAndTrueToLoopCondition.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/AddAndTrueToLoopCondition.h create mode 100644 src/3rdparty/angle/src/compiler/translator/AddDefaultReturnStatements.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/AddDefaultReturnStatements.h create mode 100644 src/3rdparty/angle/src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/BreakVariableAliasingInInnerLoops.h create mode 100644 src/3rdparty/angle/src/compiler/translator/ClampPointSize.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/ClampPointSize.h create mode 100644 src/3rdparty/angle/src/compiler/translator/CollectVariables.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/CollectVariables.h create mode 100644 src/3rdparty/angle/src/compiler/translator/ConstantUnion.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.h create mode 100644 src/3rdparty/angle/src/compiler/translator/DeferGlobalInitializers.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/DeferGlobalInitializers.h delete mode 100644 src/3rdparty/angle/src/compiler/translator/DetectCallDepth.cpp delete mode 100644 src/3rdparty/angle/src/compiler/translator/DetectCallDepth.h delete mode 100644 src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.cpp delete mode 100644 src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.h create mode 100644 src/3rdparty/angle/src/compiler/translator/EmulateGLFragColorBroadcast.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/EmulateGLFragColorBroadcast.h create mode 100644 src/3rdparty/angle/src/compiler/translator/ExpandIntegerPowExpressions.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/ExpandIntegerPowExpressions.h create mode 100644 src/3rdparty/angle/src/compiler/translator/ExtensionBehavior.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/FindMain.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/FindMain.h create mode 100644 src/3rdparty/angle/src/compiler/translator/FindSymbolNode.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/FindSymbolNode.h delete mode 100644 src/3rdparty/angle/src/compiler/translator/ForLoopUnroll.cpp delete mode 100644 src/3rdparty/angle/src/compiler/translator/ForLoopUnroll.h create mode 100644 src/3rdparty/angle/src/compiler/translator/HashNames.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/ImageFunctionHLSL.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/ImageFunctionHLSL.h delete mode 100644 src/3rdparty/angle/src/compiler/translator/InitializeParseContext.cpp delete mode 100644 src/3rdparty/angle/src/compiler/translator/InitializeParseContext.h create mode 100644 src/3rdparty/angle/src/compiler/translator/IntermNodePatternMatcher.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/IntermNodePatternMatcher.h create mode 100644 src/3rdparty/angle/src/compiler/translator/IntermNode_util.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/IntermNode_util.h create mode 100644 src/3rdparty/angle/src/compiler/translator/IntermTraverse.h delete mode 100644 src/3rdparty/angle/src/compiler/translator/Intermediate.cpp delete mode 100644 src/3rdparty/angle/src/compiler/translator/Intermediate.h create mode 100644 src/3rdparty/angle/src/compiler/translator/IsASTDepthBelowLimit.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/IsASTDepthBelowLimit.h delete mode 100644 src/3rdparty/angle/src/compiler/translator/LoopInfo.cpp delete mode 100644 src/3rdparty/angle/src/compiler/translator/LoopInfo.h delete mode 100644 src/3rdparty/angle/src/compiler/translator/MMap.h create mode 100644 src/3rdparty/angle/src/compiler/translator/OutputTree.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/OutputTree.h create mode 100644 src/3rdparty/angle/src/compiler/translator/OutputVulkanGLSL.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/OutputVulkanGLSL.h create mode 100644 src/3rdparty/angle/src/compiler/translator/ParamType.h delete mode 100644 src/3rdparty/angle/src/compiler/translator/PruneEmptyDeclarations.cpp delete mode 100644 src/3rdparty/angle/src/compiler/translator/PruneEmptyDeclarations.h create mode 100644 src/3rdparty/angle/src/compiler/translator/PruneNoOps.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/PruneNoOps.h delete mode 100644 src/3rdparty/angle/src/compiler/translator/QualifierAlive.cpp delete mode 100644 src/3rdparty/angle/src/compiler/translator/QualifierAlive.h create mode 100644 src/3rdparty/angle/src/compiler/translator/QualifierTypes.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/QualifierTypes.h create mode 100644 src/3rdparty/angle/src/compiler/translator/RemoveArrayLengthMethod.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/RemoveArrayLengthMethod.h create mode 100644 src/3rdparty/angle/src/compiler/translator/RemoveEmptySwitchStatements.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/RemoveEmptySwitchStatements.h create mode 100644 src/3rdparty/angle/src/compiler/translator/RemoveInvariantDeclaration.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/RemoveInvariantDeclaration.h create mode 100644 src/3rdparty/angle/src/compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.h create mode 100644 src/3rdparty/angle/src/compiler/translator/RemoveUnreferencedVariables.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/RemoveUnreferencedVariables.h delete mode 100644 src/3rdparty/angle/src/compiler/translator/RenameFunction.h create mode 100644 src/3rdparty/angle/src/compiler/translator/RewriteTexelFetchOffset.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/RewriteTexelFetchOffset.h create mode 100644 src/3rdparty/angle/src/compiler/translator/RewriteUnaryMinusOperatorFloat.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/RewriteUnaryMinusOperatorFloat.h create mode 100644 src/3rdparty/angle/src/compiler/translator/RewriteUnaryMinusOperatorInt.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/RewriteUnaryMinusOperatorInt.h create mode 100644 src/3rdparty/angle/src/compiler/translator/RunAtTheEndOfShader.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/RunAtTheEndOfShader.h create mode 100644 src/3rdparty/angle/src/compiler/translator/Severity.h delete mode 100644 src/3rdparty/angle/src/compiler/translator/SimplifyArrayAssignment.cpp delete mode 100644 src/3rdparty/angle/src/compiler/translator/SimplifyArrayAssignment.h create mode 100644 src/3rdparty/angle/src/compiler/translator/SimplifyLoopConditions.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/SimplifyLoopConditions.h create mode 100644 src/3rdparty/angle/src/compiler/translator/SplitSequenceOperator.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/SplitSequenceOperator.h create mode 100644 src/3rdparty/angle/src/compiler/translator/SymbolUniqueId.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/SymbolUniqueId.h create mode 100644 src/3rdparty/angle/src/compiler/translator/TextureFunctionHLSL.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/TextureFunctionHLSL.h create mode 100644 src/3rdparty/angle/src/compiler/translator/TranslatorVulkan.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/TranslatorVulkan.h delete mode 100644 src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuit.cpp delete mode 100644 src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuit.h create mode 100644 src/3rdparty/angle/src/compiler/translator/UseInterfaceBlockFields.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/UseInterfaceBlockFields.h create mode 100644 src/3rdparty/angle/src/compiler/translator/ValidateMaxParameters.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/ValidateMaxParameters.h create mode 100644 src/3rdparty/angle/src/compiler/translator/ValidateVaryingLocations.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/ValidateVaryingLocations.h delete mode 100644 src/3rdparty/angle/src/compiler/translator/VariableInfo.cpp delete mode 100644 src/3rdparty/angle/src/compiler/translator/VariableInfo.h create mode 100644 src/3rdparty/angle/src/compiler/translator/VectorizeVectorScalarArithmetic.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/VectorizeVectorScalarArithmetic.h create mode 100644 src/3rdparty/angle/src/compiler/translator/WrapSwitchStatementsInBlocks.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/WrapSwitchStatementsInBlocks.h delete mode 100644 src/3rdparty/angle/src/compiler/translator/compilerdebug.cpp delete mode 100644 src/3rdparty/angle/src/compiler/translator/compilerdebug.h delete mode 100644 src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraph.cpp delete mode 100644 src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraph.h delete mode 100644 src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.cpp delete mode 100644 src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.h delete mode 100644 src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphOutput.cpp delete mode 100644 src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphOutput.h delete mode 100644 src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphTraverse.cpp create mode 100644 src/3rdparty/angle/src/compiler/translator/emulated_builtin_function_data_hlsl.json create mode 100644 src/3rdparty/angle/src/compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp delete mode 100644 src/3rdparty/angle/src/compiler/translator/intermOut.cpp delete mode 100644 src/3rdparty/angle/src/compiler/translator/parseConst.cpp delete mode 100644 src/3rdparty/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp delete mode 100644 src/3rdparty/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.h delete mode 100644 src/3rdparty/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp delete mode 100644 src/3rdparty/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.h create mode 100644 src/3rdparty/angle/src/gpu_info_util/SystemInfo.cpp create mode 100644 src/3rdparty/angle/src/gpu_info_util/SystemInfo.h create mode 100644 src/3rdparty/angle/src/gpu_info_util/SystemInfo_internal.h create mode 100644 src/3rdparty/angle/src/gpu_info_util/SystemInfo_libpci.cpp create mode 100644 src/3rdparty/angle/src/gpu_info_util/SystemInfo_linux.cpp create mode 100644 src/3rdparty/angle/src/gpu_info_util/SystemInfo_mac.mm create mode 100644 src/3rdparty/angle/src/gpu_info_util/SystemInfo_win.cpp create mode 100644 src/3rdparty/angle/src/gpu_info_util/SystemInfo_x11.cpp delete mode 100644 src/3rdparty/angle/src/id/commit.h create mode 100644 src/3rdparty/angle/src/image_util/copyimage.cpp rename src/3rdparty/angle/src/{libANGLE/renderer/d3d => image_util}/copyimage.h (77%) rename src/3rdparty/angle/src/{libANGLE/renderer/d3d => image_util}/copyimage.inl (69%) create mode 100644 src/3rdparty/angle/src/image_util/generatemip.h rename src/3rdparty/angle/src/{libANGLE/renderer/d3d => image_util}/generatemip.inl (98%) create mode 100644 src/3rdparty/angle/src/image_util/imageformats.cpp create mode 100644 src/3rdparty/angle/src/image_util/imageformats.h create mode 100644 src/3rdparty/angle/src/image_util/loadimage.cpp create mode 100644 src/3rdparty/angle/src/image_util/loadimage.h rename src/3rdparty/angle/src/{libANGLE/renderer/d3d => image_util}/loadimage.inl (79%) rename src/3rdparty/angle/src/{libANGLE/renderer/d3d => image_util}/loadimage_etc.cpp (69%) create mode 100644 src/3rdparty/angle/src/libANGLE/ContextState.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/ContextState.h delete mode 100644 src/3rdparty/angle/src/libANGLE/Data.cpp delete mode 100644 src/3rdparty/angle/src/libANGLE/Data.h create mode 100644 src/3rdparty/angle/src/libANGLE/ErrorStrings.h create mode 100644 src/3rdparty/angle/src/libANGLE/HandleRangeAllocator.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/HandleRangeAllocator.h create mode 100644 src/3rdparty/angle/src/libANGLE/LoggingAnnotator.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/LoggingAnnotator.h create mode 100644 src/3rdparty/angle/src/libANGLE/MemoryProgramCache.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/MemoryProgramCache.h create mode 100644 src/3rdparty/angle/src/libANGLE/PackedGLEnums.h create mode 100644 src/3rdparty/angle/src/libANGLE/PackedGLEnums_autogen.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/PackedGLEnums_autogen.h create mode 100644 src/3rdparty/angle/src/libANGLE/Path.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/Path.h create mode 100644 src/3rdparty/angle/src/libANGLE/ProgramLinkedResources.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/ProgramLinkedResources.h create mode 100644 src/3rdparty/angle/src/libANGLE/ProgramPipeline.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/ProgramPipeline.h delete mode 100644 src/3rdparty/angle/src/libANGLE/RefCountObject.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/ResourceMap.h create mode 100644 src/3rdparty/angle/src/libANGLE/SizedMRUCache.h create mode 100644 src/3rdparty/angle/src/libANGLE/Stream.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/Stream.h create mode 100644 src/3rdparty/angle/src/libANGLE/Thread.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/Thread.h rename src/3rdparty/angle/src/libANGLE/{renderer/d3d => }/VaryingPacking.cpp (51%) rename src/3rdparty/angle/src/libANGLE/{renderer/d3d => }/VaryingPacking.h (66%) create mode 100644 src/3rdparty/angle/src/libANGLE/Workarounds.h create mode 100644 src/3rdparty/angle/src/libANGLE/WorkerThread.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/WorkerThread.h create mode 100644 src/3rdparty/angle/src/libANGLE/entry_points_enum_autogen.h create mode 100644 src/3rdparty/angle/src/libANGLE/es3_copy_conversion_formats.json create mode 100644 src/3rdparty/angle/src/libANGLE/es3_copy_conversion_table_autogen.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/es3_format_type_combinations.json create mode 100644 src/3rdparty/angle/src/libANGLE/format_map_autogen.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/format_map_data.json create mode 100644 src/3rdparty/angle/src/libANGLE/packed_gl_enums.json create mode 100644 src/3rdparty/angle/src/libANGLE/params.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/params.h create mode 100644 src/3rdparty/angle/src/libANGLE/queryutils.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/queryutils.h create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/ContextImpl.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/ContextImpl.h create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/EGLImplFactory.h create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/Format.h create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/Format_ID_autogen.inl create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/Format_table_autogen.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/FramebufferAttachmentObjectImpl.h create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/GLImplFactory.h delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/Image.h delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/ImplFactory.h create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/PathImpl.h delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/ProgramImpl.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/ProgramPipelineImpl.h delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/RenderbufferImpl.cpp delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/Renderer.cpp delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/Renderer.h create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/StreamProducerImpl.h rename src/3rdparty/angle/src/libANGLE/renderer/{FenceSyncImpl.h => SyncImpl.h} (76%) create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/TextureImpl.cpp delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/Workarounds.h create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/angle_format_data.json create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/angle_format_map.json create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/NativeWindowD3D.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/NativeWindowD3D.h create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/SwapChainD3D.cpp delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureStorage.cpp delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/TransformFeedbackD3D.cpp delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/TransformFeedbackD3D.h delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/WorkaroundsD3D.h delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/copyimage.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Context11.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Context11.h delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow11.h create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ProgramPipeline11.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ProgramPipeline11.h create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.h create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StreamProducerNV12.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StreamProducerNV12.h create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.h create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_format_data.json create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_format_map_autogen.cpp delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/gen_load_functions_table.cpp delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.cpp delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.h delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_data.json delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_table.h delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_table_autogen.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/MultiplyAlpha.hlsl create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/ResolveDepthStencil.hlsl create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dms11ps.h delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_data.json delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_info.h delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_info_autogen.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_map.json create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_utils.h rename src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/{NativeWindow.cpp => NativeWindow11Win32.cpp} (51%) create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.h create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/NativeWindow11WinRT.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/NativeWindow11WinRT.h create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Context9.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Context9.h create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.h delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/formatutilsD3D.cpp delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/generatemip.h delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/imageformats.h delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage.cpp delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage.h delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimageSSE2.cpp delete mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage_etc.h create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/driver_utils.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/driver_utils.h create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/load_functions_data.json create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/load_functions_table.h create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/load_functions_table_autogen.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/renderer_utils.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/renderer_utils.h create mode 100644 src/3rdparty/angle/src/libANGLE/signal_utils.h create mode 100644 src/3rdparty/angle/src/libANGLE/validationES31.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/validationES31.h delete mode 100644 src/3rdparty/angle/src/libEGL/libEGLd_mingw32.def delete mode 100644 src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0.h create mode 100644 src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_autogen.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_autogen.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0.h create mode 100644 src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0_autogen.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0_autogen.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0_ext.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0_ext.h create mode 100644 src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_1_autogen.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_1_autogen.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def create mode 100644 src/3rdparty/angle/src/libGLESv2/proc_table.h create mode 100644 src/3rdparty/angle/src/libGLESv2/proc_table_autogen.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/proc_table_data.json create mode 100644 src/3rdparty/angle/src/third_party/libXNVCtrl/LICENSE create mode 100644 src/3rdparty/angle/src/third_party/libXNVCtrl/NVCtrl.c create mode 100644 src/3rdparty/angle/src/third_party/libXNVCtrl/NVCtrl.h create mode 100644 src/3rdparty/angle/src/third_party/libXNVCtrl/NVCtrlLib.h create mode 100644 src/3rdparty/angle/src/third_party/libXNVCtrl/README.angle create mode 100644 src/3rdparty/angle/src/third_party/libXNVCtrl/nv_control.h delete mode 100644 src/3rdparty/angle/src/third_party/murmurhash/LICENSE delete mode 100644 src/3rdparty/angle/src/third_party/murmurhash/MurmurHash3.cpp delete mode 100644 src/3rdparty/angle/src/third_party/murmurhash/MurmurHash3.h delete mode 100644 src/angle/patches/0001-ANGLE-Improve-Windows-Phone-Support.patch create mode 100644 src/angle/patches/0001-ANGLE-Use-pixel-sizes-in-the-XAML-swap-chain.patch create mode 100644 src/angle/patches/0001-Fix-build-for-MinGW.patch rename src/angle/patches/{0003-ANGLE-Add-support-for-querying-platform-device.patch => 0002-ANGLE-Add-support-for-querying-platform-device.patch} (70%) delete mode 100644 src/angle/patches/0002-ANGLE-Dynamically-load-D3D-compiler-from-a-list.patch create mode 100644 src/angle/patches/0002-ANGLE-Fix-build-for-ARM.patch delete mode 100644 src/angle/patches/0002-ANGLE-Fix-compilation-with-MinGW.patch rename src/angle/patches/{0006-ANGLE-Fix-Windows-Store-D3D-Trim-and-Level-9-requirements.patch => 0003-ANGLE-Fix-Windows-Store-D3D-Trim-and-Level-9-require.patch} (79%) delete mode 100644 src/angle/patches/0004-ANGLE-Allow-Windows-Phone-to-communicate-swap-region.patch create mode 100644 src/angle/patches/0004-ANGLE-fix-usage-of-shared-handles-for-WinRT-applicat.patch delete mode 100644 src/angle/patches/0005-ANGLE-Fix-compilation-without-d3d11.patch rename src/angle/patches/{0012-ANGLE-Fix-initialization-of-zero-sized-window.patch => 0005-ANGLE-Fix-initialization-of-zero-sized-window.patch} (72%) rename src/angle/patches/{0014-ANGLE-Fix-flickering-on-resize-when-D3D9-is-used.patch => 0006-ANGLE-Fix-flickering-on-resize-when-D3D9-is-used.patch} (60%) delete mode 100644 src/angle/patches/0007-ANGLE-D3D11-Suppress-keyboard-handling-of-DXGI.patch rename src/angle/patches/{0016-ANGLE-Fix-resizing-of-windows.patch => 0007-ANGLE-Fix-resizing-of-windows.patch} (64%) delete mode 100644 src/angle/patches/0008-ANGLE-Use-pixel-sizes-in-the-XAML-swap-chain.patch create mode 100644 src/angle/patches/0008-ANGLE-winrt-Do-full-screen-update-if-the-the-window-.patch delete mode 100644 src/angle/patches/0009-ANGLE-glGetUniform-v-functions-to-work-properly.patch create mode 100644 src/angle/patches/0009-Revert-Fix-scanForWantedComponents-not-ignoring-attr.patch create mode 100644 src/angle/patches/0010-ANGLE-Disable-multisampling-to-avoid-crash-in-Qt-app.patch delete mode 100644 src/angle/patches/0010-ANGLE-fixed-usage-of-shared-handles-for-WinRT-WinPho.patch delete mode 100644 src/angle/patches/0011-ANGLE-Disable-support-for-shared-handles-in-warp-mod.patch delete mode 100644 src/angle/patches/0013-ANGLE-Fix-crash-with-ltcg-on-Visual-Studio-2015-Upda.patch delete mode 100644 src/angle/patches/0015-ANGLE-Use-ANGLE_D3D11_QDTD_AVAILABLE-to-check-struct-.patch delete mode 100644 src/angle/patches/0017-Remove-usage-of-auto_ptr-in-MacroExpander.patch diff --git a/src/3rdparty/angle/AUTHORS b/src/3rdparty/angle/AUTHORS index 8de8fbddf6..5dacdf8fbd 100644 --- a/src/3rdparty/angle/AUTHORS +++ b/src/3rdparty/angle/AUTHORS @@ -1,4 +1,4 @@ -# This is the official list of The ANGLE Project Authors +# This is the official list of The ANGLE Project Authors # for copyright purposes. # This file is distinct from the CONTRIBUTORS files. # See the latter for an explanation. @@ -26,6 +26,7 @@ Microsoft Open Technologies, Inc. NVIDIA Corporation Opera Software ASA The Qt Company Ltd. +Advanced Micro Devices, Inc. Jacek Caban Mark Callow @@ -42,3 +43,9 @@ Yuri O'Donnell Josh Soref Maks Naumov Jinyoung Hur +Sebastian Bergstein +James Ross-Gowan +Nickolay Artamonov +Ihsan Akmal +Andrei Volykhin +Jérôme Duval diff --git a/src/3rdparty/angle/CONTRIBUTORS b/src/3rdparty/angle/CONTRIBUTORS index 71e13b7a15..a767773b33 100644 --- a/src/3rdparty/angle/CONTRIBUTORS +++ b/src/3rdparty/angle/CONTRIBUTORS @@ -41,6 +41,7 @@ Google Inc. Justin Schuh Scott Graham Corentin Wallez + Kai Ninomiya Adobe Systems Inc. Alexandru Chiculita @@ -64,12 +65,21 @@ Intel Corporation Andy Chen Josh Triplett Sudarsana Nagineni + Jiajia Qin + Jiawei Shao + Jie Chen + Qiankun Miao + Bryan Bernhart + Yunchao He + Xinghua Cao + Brandon Jones Klarälvdalens Datakonsult AB Milian Wolff Mozilla Corp. Ehsan Akhgari + Edwin Flores Jeff Gilbert Mike Hommey Benoit Jacob @@ -85,6 +95,10 @@ David Kilzer Jacek Caban Tibor den Ouden Régis Fénéon +Sebastian Bergstein +James Ross-Gowan +Andrei Volykhin +Jérôme Duval Microsoft Corporation Cooper Partin @@ -101,7 +115,13 @@ NVIDIA Corporation Arun Patole Qingqing Deng Kimmo Kinnunen + Sami Väisänen + Martin Radev Opera Software ASA Daniel Bratell Tomasz Moniuszko + David Landell + +Advanced Micro Devices, Inc. + Russ Lind diff --git a/src/3rdparty/angle/LICENSE b/src/3rdparty/angle/LICENSE index dc322e998d..bdacb32e36 100644 --- a/src/3rdparty/angle/LICENSE +++ b/src/3rdparty/angle/LICENSE @@ -1,32 +1,32 @@ -Copyright (C) 2002-2013 The ANGLE Project Authors. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - Neither the name of TransGaming Inc., Google Inc., 3DLabs Inc. - Ltd., nor the names of their contributors may be used to endorse - or promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. +// Copyright (C) 2002-2013 The ANGLE Project Authors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of TransGaming Inc., Google Inc., 3DLabs Inc. +// Ltd., nor the names of their contributors may be used to endorse +// or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. diff --git a/src/3rdparty/angle/SYSTEMINFO_LICENSE b/src/3rdparty/angle/SYSTEMINFO_LICENSE deleted file mode 100644 index c12444e3bc..0000000000 --- a/src/3rdparty/angle/SYSTEMINFO_LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (C) 2009 Apple Inc. All Rights Reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/3rdparty/angle/TRACEEVENT_LICENSE b/src/3rdparty/angle/TRACEEVENT_LICENSE deleted file mode 100644 index 34d6cd9268..0000000000 --- a/src/3rdparty/angle/TRACEEVENT_LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright 2013 The Chromium Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/3rdparty/angle/id/commit.h b/src/3rdparty/angle/id/commit.h new file mode 100644 index 0000000000..4c89a657c5 --- /dev/null +++ b/src/3rdparty/angle/id/commit.h @@ -0,0 +1,14 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// commit.h: +// This is a default commit hash header, when git is not available. +// + +#define ANGLE_COMMIT_HASH "unknown hash" +#define ANGLE_COMMIT_HASH_SIZE 12 +#define ANGLE_COMMIT_DATE "unknown date" + +#define ANGLE_DISABLE_PROGRAM_BINARY_LOAD diff --git a/src/3rdparty/angle/include/EGL/egl.h b/src/3rdparty/angle/include/EGL/egl.h index 9f9e021804..29f30d94de 100644 --- a/src/3rdparty/angle/include/EGL/egl.h +++ b/src/3rdparty/angle/include/EGL/egl.h @@ -6,7 +6,7 @@ extern "C" { #endif /* -** Copyright (c) 2013-2015 The Khronos Group Inc. +** Copyright (c) 2013-2017 The Khronos Group Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a ** copy of this software and/or associated documentation files (the @@ -31,14 +31,14 @@ extern "C" { ** This header is generated from the Khronos OpenGL / OpenGL ES XML ** API Registry. The current version of the Registry, generator scripts ** used to make the header, and the header can be found at -** http://www.opengl.org/registry/ +** http://www.opengl.org/registry/egl ** -** Khronos $Revision: 31566 $ on $Date: 2015-06-23 08:48:48 -0700 (Tue, 23 Jun 2015) $ +** Khronos $Revision$ on $Date$ */ #include -/* Generated on date 20150623 */ +/* Generated on date 20161230 */ /* Generated C header for: * API: egl @@ -78,7 +78,7 @@ typedef void (*__eglMustCastToProperFunctionPointerType)(void); #define EGL_CONFIG_ID 0x3028 #define EGL_CORE_NATIVE_ENGINE 0x305B #define EGL_DEPTH_SIZE 0x3025 -#define EGL_DONT_CARE ((EGLint)-1) +#define EGL_DONT_CARE EGL_CAST(EGLint,-1) #define EGL_DRAW 0x3059 #define EGL_EXTENSIONS 0x3055 #define EGL_FALSE 0 @@ -95,9 +95,9 @@ typedef void (*__eglMustCastToProperFunctionPointerType)(void); #define EGL_NONE 0x3038 #define EGL_NON_CONFORMANT_CONFIG 0x3051 #define EGL_NOT_INITIALIZED 0x3001 -#define EGL_NO_CONTEXT ((EGLContext)0) -#define EGL_NO_DISPLAY ((EGLDisplay)0) -#define EGL_NO_SURFACE ((EGLSurface)0) +#define EGL_NO_CONTEXT EGL_CAST(EGLContext,0) +#define EGL_NO_DISPLAY EGL_CAST(EGLDisplay,0) +#define EGL_NO_SURFACE EGL_CAST(EGLSurface,0) #define EGL_PBUFFER_BIT 0x0001 #define EGL_PIXMAP_BIT 0x0002 #define EGL_READ 0x305A @@ -197,7 +197,7 @@ typedef void *EGLClientBuffer; #define EGL_RGB_BUFFER 0x308E #define EGL_SINGLE_BUFFER 0x3085 #define EGL_SWAP_BEHAVIOR 0x3093 -#define EGL_UNKNOWN ((EGLint)-1) +#define EGL_UNKNOWN EGL_CAST(EGLint,-1) #define EGL_VERTICAL_RESOLUTION 0x3091 EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI (EGLenum api); EGLAPI EGLenum EGLAPIENTRY eglQueryAPI (void); @@ -224,7 +224,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient (void); #ifndef EGL_VERSION_1_4 #define EGL_VERSION_1_4 1 -#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0) +#define EGL_DEFAULT_DISPLAY EGL_CAST(EGLNativeDisplayType,0) #define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200 #define EGL_MULTISAMPLE_RESOLVE 0x3099 #define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A @@ -266,7 +266,7 @@ typedef void *EGLImage; #define EGL_FOREVER 0xFFFFFFFFFFFFFFFFull #define EGL_TIMEOUT_EXPIRED 0x30F5 #define EGL_CONDITION_SATISFIED 0x30F6 -#define EGL_NO_SYNC ((EGLSync)0) +#define EGL_NO_SYNC EGL_CAST(EGLSync,0) #define EGL_SYNC_FENCE 0x30F9 #define EGL_GL_COLORSPACE 0x309D #define EGL_GL_COLORSPACE_SRGB 0x3089 @@ -283,7 +283,7 @@ typedef void *EGLImage; #define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x30B7 #define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8 #define EGL_IMAGE_PRESERVED 0x30D2 -#define EGL_NO_IMAGE ((EGLImage)0) +#define EGL_NO_IMAGE EGL_CAST(EGLImage,0) EGLAPI EGLSync EGLAPIENTRY eglCreateSync (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list); EGLAPI EGLBoolean EGLAPIENTRY eglDestroySync (EGLDisplay dpy, EGLSync sync); EGLAPI EGLint EGLAPIENTRY eglClientWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout); diff --git a/src/3rdparty/angle/include/EGL/eglext.h b/src/3rdparty/angle/include/EGL/eglext.h index 83490b8567..79f6ccd418 100644 --- a/src/3rdparty/angle/include/EGL/eglext.h +++ b/src/3rdparty/angle/include/EGL/eglext.h @@ -6,7 +6,7 @@ extern "C" { #endif /* -** Copyright (c) 2013-2015 The Khronos Group Inc. +** Copyright (c) 2013-2017 The Khronos Group Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a ** copy of this software and/or associated documentation files (the @@ -31,14 +31,14 @@ extern "C" { ** This header is generated from the Khronos OpenGL / OpenGL ES XML ** API Registry. The current version of the Registry, generator scripts ** used to make the header, and the header can be found at -** http://www.opengl.org/registry/ +** http://www.khronos.org/registry/egl ** -** Khronos $Revision: 31566 $ on $Date: 2015-06-23 08:48:48 -0700 (Tue, 23 Jun 2015) $ +** Khronos $Git commit SHA1: a732b061e7 $ on $Git commit date: 2017-06-17 23:27:53 +0100 $ */ #include -#define EGL_EGLEXT_VERSION 20150623 +#define EGL_EGLEXT_VERSION 20170627 /* Generated C header for: * API: egl @@ -77,6 +77,13 @@ EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSync64KHR (EGLDisplay dpy, EGLenum type, #define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR 0x0040 #endif /* EGL_KHR_config_attribs */ +#ifndef EGL_KHR_context_flush_control +#define EGL_KHR_context_flush_control 1 +#define EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR 0 +#define EGL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x2097 +#define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098 +#endif /* EGL_KHR_context_flush_control */ + #ifndef EGL_KHR_create_context #define EGL_KHR_create_context 1 #define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098 @@ -99,6 +106,42 @@ EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSync64KHR (EGLDisplay dpy, EGLenum type, #define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31B3 #endif /* EGL_KHR_create_context_no_error */ +#ifndef EGL_KHR_debug +#define EGL_KHR_debug 1 +typedef void *EGLLabelKHR; +typedef void *EGLObjectKHR; +typedef void (EGLAPIENTRY *EGLDEBUGPROCKHR)(EGLenum error,const char *command,EGLint messageType,EGLLabelKHR threadLabel,EGLLabelKHR objectLabel,const char* message); +#define EGL_OBJECT_THREAD_KHR 0x33B0 +#define EGL_OBJECT_DISPLAY_KHR 0x33B1 +#define EGL_OBJECT_CONTEXT_KHR 0x33B2 +#define EGL_OBJECT_SURFACE_KHR 0x33B3 +#define EGL_OBJECT_IMAGE_KHR 0x33B4 +#define EGL_OBJECT_SYNC_KHR 0x33B5 +#define EGL_OBJECT_STREAM_KHR 0x33B6 +#define EGL_DEBUG_MSG_CRITICAL_KHR 0x33B9 +#define EGL_DEBUG_MSG_ERROR_KHR 0x33BA +#define EGL_DEBUG_MSG_WARN_KHR 0x33BB +#define EGL_DEBUG_MSG_INFO_KHR 0x33BC +#define EGL_DEBUG_CALLBACK_KHR 0x33B8 +typedef EGLint (EGLAPIENTRYP PFNEGLDEBUGMESSAGECONTROLKHRPROC) (EGLDEBUGPROCKHR callback, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEBUGKHRPROC) (EGLint attribute, EGLAttrib *value); +typedef EGLint (EGLAPIENTRYP PFNEGLLABELOBJECTKHRPROC) (EGLDisplay display, EGLenum objectType, EGLObjectKHR object, EGLLabelKHR label); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLint EGLAPIENTRY eglDebugMessageControlKHR (EGLDEBUGPROCKHR callback, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDebugKHR (EGLint attribute, EGLAttrib *value); +EGLAPI EGLint EGLAPIENTRY eglLabelObjectKHR (EGLDisplay display, EGLenum objectType, EGLObjectKHR object, EGLLabelKHR label); +#endif +#endif /* EGL_KHR_debug */ + +#ifndef EGL_KHR_display_reference +#define EGL_KHR_display_reference 1 +#define EGL_TRACK_REFERENCES_KHR 0x3352 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBKHRPROC) (EGLDisplay dpy, EGLint name, EGLAttrib *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribKHR (EGLDisplay dpy, EGLint name, EGLAttrib *value); +#endif +#endif /* EGL_KHR_display_reference */ + #ifndef EGL_KHR_fence_sync #define EGL_KHR_fence_sync 1 typedef khronos_utime_nanoseconds_t EGLTimeKHR; @@ -161,7 +204,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR (EGLDisplay dpy, EGLSyncKHR sy #define EGL_KHR_image 1 typedef void *EGLImageKHR; #define EGL_NATIVE_PIXMAP_KHR 0x30B0 -#define EGL_NO_IMAGE_KHR ((EGLImageKHR)0) +#define EGL_NO_IMAGE_KHR EGL_CAST(EGLImageKHR,0) typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list); typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image); #ifdef EGL_EGLEXT_PROTOTYPES @@ -223,6 +266,16 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface64KHR (EGLDisplay dpy, EGLSurface s #endif #endif /* EGL_KHR_lock_surface3 */ +#ifndef EGL_KHR_mutable_render_buffer +#define EGL_KHR_mutable_render_buffer 1 +#define EGL_MUTABLE_RENDER_BUFFER_BIT_KHR 0x1000 +#endif /* EGL_KHR_mutable_render_buffer */ + +#ifndef EGL_KHR_no_config_context +#define EGL_KHR_no_config_context 1 +#define EGL_NO_CONFIG_KHR EGL_CAST(EGLConfig,0) +#endif /* EGL_KHR_no_config_context */ + #ifndef EGL_KHR_partial_update #define EGL_KHR_partial_update 1 #define EGL_BUFFER_AGE_KHR 0x313D @@ -265,7 +318,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSetDamageRegionKHR (EGLDisplay dpy, EGLSurface #define EGL_SYNC_REUSABLE_KHR 0x30FA #define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001 #define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFFull -#define EGL_NO_SYNC_KHR ((EGLSyncKHR)0) +#define EGL_NO_SYNC_KHR EGL_CAST(EGLSyncKHR,0) typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode); #ifdef EGL_EGLEXT_PROTOTYPES EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode); @@ -278,7 +331,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, typedef void *EGLStreamKHR; typedef khronos_uint64_t EGLuint64KHR; #ifdef KHRONOS_SUPPORT_INT64 -#define EGL_NO_STREAM_KHR ((EGLStreamKHR)0) +#define EGL_NO_STREAM_KHR EGL_CAST(EGLStreamKHR,0) #define EGL_CONSUMER_LATENCY_USEC_KHR 0x3210 #define EGL_PRODUCER_FRAME_KHR 0x3212 #define EGL_CONSUMER_FRAME_KHR 0x3213 @@ -306,6 +359,24 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamu64KHR (EGLDisplay dpy, EGLStreamKHR #endif /* KHRONOS_SUPPORT_INT64 */ #endif /* EGL_KHR_stream */ +#ifndef EGL_KHR_stream_attrib +#define EGL_KHR_stream_attrib 1 +#ifdef KHRONOS_SUPPORT_INT64 +typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMATTRIBKHRPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamAttribKHR (EGLDisplay dpy, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglSetStreamAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib value); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib *value); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +#endif +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_KHR_stream_attrib */ + #ifndef EGL_KHR_stream_consumer_gltexture #define EGL_KHR_stream_consumer_gltexture 1 #ifdef EGL_KHR_stream @@ -325,7 +396,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseKHR (EGLDisplay dpy, EGLSt #define EGL_KHR_stream_cross_process_fd 1 typedef int EGLNativeFileDescriptorKHR; #ifdef EGL_KHR_stream -#define EGL_NO_FILE_DESCRIPTOR_KHR ((EGLNativeFileDescriptorKHR)(-1)) +#define EGL_NO_FILE_DESCRIPTOR_KHR EGL_CAST(EGLNativeFileDescriptorKHR,-1) typedef EGLNativeFileDescriptorKHR (EGLAPIENTRYP PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor); #ifdef EGL_EGLEXT_PROTOTYPES @@ -402,11 +473,28 @@ EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncsANDROID (EGLDisplay dpy, EGLSetBlobF #endif #endif /* EGL_ANDROID_blob_cache */ +#ifndef EGL_ANDROID_create_native_client_buffer +#define EGL_ANDROID_create_native_client_buffer 1 +#define EGL_NATIVE_BUFFER_USAGE_ANDROID 0x3143 +#define EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID 0x00000001 +#define EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID 0x00000002 +#define EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID 0x00000004 +typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLCREATENATIVECLIENTBUFFERANDROIDPROC) (const EGLint *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLClientBuffer EGLAPIENTRY eglCreateNativeClientBufferANDROID (const EGLint *attrib_list); +#endif +#endif /* EGL_ANDROID_create_native_client_buffer */ + #ifndef EGL_ANDROID_framebuffer_target #define EGL_ANDROID_framebuffer_target 1 #define EGL_FRAMEBUFFER_TARGET_ANDROID 0x3147 #endif /* EGL_ANDROID_framebuffer_target */ +#ifndef EGL_ANDROID_front_buffer_auto_refresh +#define EGL_ANDROID_front_buffer_auto_refresh 1 +#define EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID 0x314C +#endif /* EGL_ANDROID_front_buffer_auto_refresh */ + #ifndef EGL_ANDROID_image_native_buffer #define EGL_ANDROID_image_native_buffer 1 #define EGL_NATIVE_BUFFER_ANDROID 0x3140 @@ -424,6 +512,15 @@ EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID (EGLDisplay dpy, EGLSyncKHR #endif #endif /* EGL_ANDROID_native_fence_sync */ +#ifndef EGL_ANDROID_presentation_time +#define EGL_ANDROID_presentation_time 1 +typedef khronos_stime_nanoseconds_t EGLnsecsANDROID; +typedef EGLBoolean (EGLAPIENTRYP PFNEGLPRESENTATIONTIMEANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLnsecsANDROID time); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglPresentationTimeANDROID (EGLDisplay dpy, EGLSurface surface, EGLnsecsANDROID time); +#endif +#endif /* EGL_ANDROID_presentation_time */ + #ifndef EGL_ANDROID_recordable #define EGL_ANDROID_recordable 1 #define EGL_RECORDABLE_ANDROID 0x3142 @@ -440,11 +537,6 @@ EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID (EGLDisplay dpy, EGLSyncKHR #define EGL_D3D11_DEVICE_ANGLE 0x33A1 #endif /* EGL_ANGLE_device_d3d */ -#ifndef EGL_ANGLE_keyed_mutex -#define EGL_ANGLE_keyed_mutex 1 -#define EGL_DXGI_KEYED_MUTEX_ANGLE 0x33A2 -#endif /* EGL_ANGLE_keyed_mutex */ - #ifndef EGL_ANGLE_query_surface_pointer #define EGL_ANGLE_query_surface_pointer 1 typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value); @@ -453,87 +545,30 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu #endif #endif /* EGL_ANGLE_query_surface_pointer */ -#ifndef EGL_ANGLE_software_display -#define EGL_ANGLE_software_display 1 -#define EGL_SOFTWARE_DISPLAY_ANGLE ((EGLNativeDisplayType)-1) -#endif /* EGL_ANGLE_software_display */ - -#ifndef EGL_ANGLE_direct3d_display -#define EGL_ANGLE_direct3d_display 1 -#define EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ((EGLNativeDisplayType)-2) -#define EGL_D3D11_ONLY_DISPLAY_ANGLE ((EGLNativeDisplayType)-3) -#endif /* EGL_ANGLE_direct3d_display */ - #ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle #define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1 #endif /* EGL_ANGLE_surface_d3d_texture_2d_share_handle */ -#ifndef EGL_ANGLE_direct_composition -#define EGL_ANGLE_direct_composition 1 -#define EGL_DIRECT_COMPOSITION_ANGLE 0x33A5 -#endif /* EGL_ANGLE_direct_composition */ - -#ifndef EGL_ANGLE_platform_angle -#define EGL_ANGLE_platform_angle 1 -#define EGL_PLATFORM_ANGLE_ANGLE 0x3202 -#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203 -#define EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE 0x3204 -#define EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE 0x3205 -#define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3206 -#endif /* EGL_ANGLE_platform_angle */ - -#ifndef EGL_ANGLE_platform_angle_d3d -#define EGL_ANGLE_platform_angle_d3d 1 -#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3207 -#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208 -#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE 0x3209 -#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE 0x320A -#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE 0x320B -#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE 0x320C -#define EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE 0x320F -#endif /* EGL_ANGLE_platform_angle_d3d */ - -#ifndef EGL_ANGLE_platform_angle_opengl -#define EGL_ANGLE_platform_angle_opengl 1 -#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320D -#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320E -#endif /* EGL_ANGLE_platform_angle_opengl */ - #ifndef EGL_ANGLE_window_fixed_size #define EGL_ANGLE_window_fixed_size 1 #define EGL_FIXED_SIZE_ANGLE 0x3201 #endif /* EGL_ANGLE_window_fixed_size */ -#ifndef EGL_ANGLE_x11_visual -#define EGL_ANGLE_x11_visual -#define EGL_X11_VISUAL_ID_ANGLE 0x33A3 -#endif /* EGL_ANGLE_x11_visual */ - -#ifndef EGL_ANGLE_flexible_surface_compatibility -#define EGL_ANGLE_flexible_surface_compatibility 1 -#define EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE 0x33A6 -#endif /* EGL_ANGLE_flexible_surface_compatibility */ - -#ifndef EGL_ANGLE_surface_orientation -#define EGL_ANGLE_surface_orientation -#define EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE 0x33A7 -#define EGL_SURFACE_ORIENTATION_ANGLE 0x33A8 -#define EGL_SURFACE_ORIENTATION_INVERT_X_ANGLE 0x0001 -#define EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE 0x0002 -#endif /* EGL_ANGLE_surface_orientation */ - -#ifndef EGL_ANGLE_experimental_present_path -#define EGL_ANGLE_experimental_present_path -#define EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE 0x33A4 -#define EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE 0x33A9 -#define EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE 0x33AA -#endif /* EGL_ANGLE_experimental_present_path */ +#ifndef EGL_ARM_implicit_external_sync +#define EGL_ARM_implicit_external_sync 1 +#define EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM 0x328A +#endif /* EGL_ARM_implicit_external_sync */ #ifndef EGL_ARM_pixmap_multisample_discard #define EGL_ARM_pixmap_multisample_discard 1 #define EGL_DISCARD_SAMPLES_ARM 0x3286 #endif /* EGL_ARM_pixmap_multisample_discard */ +#ifndef EGL_EXT_bind_to_front +#define EGL_EXT_bind_to_front 1 +#define EGL_FRONT_BUFFER_EXT 0x3464 +#endif /* EGL_EXT_bind_to_front */ + #ifndef EGL_EXT_buffer_age #define EGL_EXT_buffer_age 1 #define EGL_BUFFER_AGE_EXT 0x313D @@ -543,6 +578,30 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu #define EGL_EXT_client_extensions 1 #endif /* EGL_EXT_client_extensions */ +#ifndef EGL_EXT_compositor +#define EGL_EXT_compositor 1 +#define EGL_PRIMARY_COMPOSITOR_CONTEXT_EXT 0x3460 +#define EGL_EXTERNAL_REF_ID_EXT 0x3461 +#define EGL_COMPOSITOR_DROP_NEWEST_FRAME_EXT 0x3462 +#define EGL_COMPOSITOR_KEEP_NEWEST_FRAME_EXT 0x3463 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETCONTEXTLISTEXTPROC) (const EGLint *external_ref_ids, EGLint num_entries); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETCONTEXTATTRIBUTESEXTPROC) (EGLint external_ref_id, const EGLint *context_attributes, EGLint num_entries); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETWINDOWLISTEXTPROC) (EGLint external_ref_id, const EGLint *external_win_ids, EGLint num_entries); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETWINDOWATTRIBUTESEXTPROC) (EGLint external_win_id, const EGLint *window_attributes, EGLint num_entries); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORBINDTEXWINDOWEXTPROC) (EGLint external_win_id); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETSIZEEXTPROC) (EGLint external_win_id, EGLint width, EGLint height); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSWAPPOLICYEXTPROC) (EGLint external_win_id, EGLint policy); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetContextListEXT (const EGLint *external_ref_ids, EGLint num_entries); +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetContextAttributesEXT (EGLint external_ref_id, const EGLint *context_attributes, EGLint num_entries); +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetWindowListEXT (EGLint external_ref_id, const EGLint *external_win_ids, EGLint num_entries); +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetWindowAttributesEXT (EGLint external_win_id, const EGLint *window_attributes, EGLint num_entries); +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorBindTexWindowEXT (EGLint external_win_id); +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetSizeEXT (EGLint external_win_id, EGLint width, EGLint height); +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSwapPolicyEXT (EGLint external_win_id, EGLint policy); +#endif +#endif /* EGL_EXT_compositor */ + #ifndef EGL_EXT_create_context_robustness #define EGL_EXT_create_context_robustness 1 #define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF @@ -554,7 +613,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu #ifndef EGL_EXT_device_base #define EGL_EXT_device_base 1 typedef void *EGLDeviceEXT; -#define EGL_NO_DEVICE_EXT ((EGLDeviceEXT)(0)) +#define EGL_NO_DEVICE_EXT EGL_CAST(EGLDeviceEXT,0) #define EGL_BAD_DEVICE_EXT 0x322B #define EGL_DEVICE_EXT 0x322C typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICEATTRIBEXTPROC) (EGLDeviceEXT device, EGLint attribute, EGLAttrib *value); @@ -569,16 +628,6 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint a #endif #endif /* EGL_EXT_device_base */ -#ifndef EGL_ANGLE_device_creation -#define EGL_ANGLE_device_creation 1 -typedef EGLDeviceEXT (EGLAPIENTRYP PFNEGLCREATEDEVICEANGLEPROC) (EGLint device_type, void *native_device, const EGLAttrib *attrib_list); -typedef EGLBoolean (EGLAPIENTRYP PFNEGLRELEASEDEVICEANGLEPROC) (EGLDeviceEXT device); -#ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLDeviceEXT EGLAPIENTRY eglCreateDeviceANGLE (EGLint device_type, void *native_device, const EGLAttrib *attrib_list); -EGLAPI EGLBoolean EGLAPIENTRY eglReleaseDeviceANGLE (EGLDeviceEXT device); -#endif -#endif /* EGL_ANGLE_device_creation */ - #ifndef EGL_EXT_device_drm #define EGL_EXT_device_drm 1 #define EGL_DRM_DEVICE_FILE_EXT 0x3233 @@ -597,6 +646,36 @@ EGLAPI EGLBoolean EGLAPIENTRY eglReleaseDeviceANGLE (EGLDeviceEXT device); #define EGL_EXT_device_query 1 #endif /* EGL_EXT_device_query */ +#ifndef EGL_EXT_gl_colorspace_bt2020_linear +#define EGL_EXT_gl_colorspace_bt2020_linear 1 +#define EGL_GL_COLORSPACE_BT2020_LINEAR_EXT 0x333F +#endif /* EGL_EXT_gl_colorspace_bt2020_linear */ + +#ifndef EGL_EXT_gl_colorspace_bt2020_pq +#define EGL_EXT_gl_colorspace_bt2020_pq 1 +#define EGL_GL_COLORSPACE_BT2020_PQ_EXT 0x3340 +#endif /* EGL_EXT_gl_colorspace_bt2020_pq */ + +#ifndef EGL_EXT_gl_colorspace_display_p3 +#define EGL_EXT_gl_colorspace_display_p3 1 +#define EGL_GL_COLORSPACE_DISPLAY_P3_EXT 0x3363 +#endif /* EGL_EXT_gl_colorspace_display_p3 */ + +#ifndef EGL_EXT_gl_colorspace_display_p3_linear +#define EGL_EXT_gl_colorspace_display_p3_linear 1 +#define EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT 0x3362 +#endif /* EGL_EXT_gl_colorspace_display_p3_linear */ + +#ifndef EGL_EXT_gl_colorspace_scrgb +#define EGL_EXT_gl_colorspace_scrgb 1 +#define EGL_GL_COLORSPACE_SCRGB_EXT 0x3351 +#endif /* EGL_EXT_gl_colorspace_scrgb */ + +#ifndef EGL_EXT_gl_colorspace_scrgb_linear +#define EGL_EXT_gl_colorspace_scrgb_linear 1 +#define EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT 0x3350 +#endif /* EGL_EXT_gl_colorspace_scrgb_linear */ + #ifndef EGL_EXT_image_dma_buf_import #define EGL_EXT_image_dma_buf_import 1 #define EGL_LINUX_DMA_BUF_EXT 0x3270 @@ -623,6 +702,34 @@ EGLAPI EGLBoolean EGLAPIENTRY eglReleaseDeviceANGLE (EGLDeviceEXT device); #define EGL_YUV_CHROMA_SITING_0_5_EXT 0x3285 #endif /* EGL_EXT_image_dma_buf_import */ +#ifndef EGL_EXT_image_dma_buf_import_modifiers +#define EGL_EXT_image_dma_buf_import_modifiers 1 +#define EGL_DMA_BUF_PLANE3_FD_EXT 0x3440 +#define EGL_DMA_BUF_PLANE3_OFFSET_EXT 0x3441 +#define EGL_DMA_BUF_PLANE3_PITCH_EXT 0x3442 +#define EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT 0x3443 +#define EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT 0x3444 +#define EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT 0x3445 +#define EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT 0x3446 +#define EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT 0x3447 +#define EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT 0x3448 +#define EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT 0x3449 +#define EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT 0x344A +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDMABUFFORMATSEXTPROC) (EGLDisplay dpy, EGLint max_formats, EGLint *formats, EGLint *num_formats); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDMABUFMODIFIERSEXTPROC) (EGLDisplay dpy, EGLint format, EGLint max_modifiers, EGLuint64KHR *modifiers, EGLBoolean *external_only, EGLint *num_modifiers); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDmaBufFormatsEXT (EGLDisplay dpy, EGLint max_formats, EGLint *formats, EGLint *num_formats); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDmaBufModifiersEXT (EGLDisplay dpy, EGLint format, EGLint max_modifiers, EGLuint64KHR *modifiers, EGLBoolean *external_only, EGLint *num_modifiers); +#endif +#endif /* EGL_EXT_image_dma_buf_import_modifiers */ + +#ifndef EGL_EXT_image_implicit_sync_control +#define EGL_EXT_image_implicit_sync_control 1 +#define EGL_IMPORT_SYNC_TYPE_EXT 0x3470 +#define EGL_IMPORT_IMPLICIT_SYNC_EXT 0x3471 +#define EGL_IMPORT_EXPLICIT_SYNC_EXT 0x3472 +#endif /* EGL_EXT_image_implicit_sync_control */ + #ifndef EGL_EXT_multiview_window #define EGL_EXT_multiview_window 1 #define EGL_MULTIVIEW_VIEW_COUNT_EXT 0x3134 @@ -632,8 +739,8 @@ EGLAPI EGLBoolean EGLAPIENTRY eglReleaseDeviceANGLE (EGLDeviceEXT device); #define EGL_EXT_output_base 1 typedef void *EGLOutputLayerEXT; typedef void *EGLOutputPortEXT; -#define EGL_NO_OUTPUT_LAYER_EXT ((EGLOutputLayerEXT)0) -#define EGL_NO_OUTPUT_PORT_EXT ((EGLOutputPortEXT)0) +#define EGL_NO_OUTPUT_LAYER_EXT EGL_CAST(EGLOutputLayerEXT,0) +#define EGL_NO_OUTPUT_PORT_EXT EGL_CAST(EGLOutputPortEXT,0) #define EGL_BAD_OUTPUT_LAYER_EXT 0x322D #define EGL_BAD_OUTPUT_PORT_EXT 0x322E #define EGL_SWAP_INTERVAL_EXT 0x322F @@ -670,6 +777,13 @@ EGLAPI const char *EGLAPIENTRY eglQueryOutputPortStringEXT (EGLDisplay dpy, EGLO #define EGL_OPENWF_PORT_ID_EXT 0x3239 #endif /* EGL_EXT_output_openwf */ +#ifndef EGL_EXT_pixel_format_float +#define EGL_EXT_pixel_format_float 1 +#define EGL_COLOR_COMPONENT_TYPE_EXT 0x3339 +#define EGL_COLOR_COMPONENT_TYPE_FIXED_EXT 0x333A +#define EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT 0x333B +#endif /* EGL_EXT_pixel_format_float */ + #ifndef EGL_EXT_platform_base #define EGL_EXT_platform_base 1 typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void *native_display, const EGLint *attrib_list); @@ -698,9 +812,13 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT (EGLDisplay dpy, #define EGL_PLATFORM_X11_SCREEN_EXT 0x31D6 #endif /* EGL_EXT_platform_x11 */ +#ifndef EGL_EXT_protected_content +#define EGL_EXT_protected_content 1 +#define EGL_PROTECTED_CONTENT_EXT 0x32C0 +#endif /* EGL_EXT_protected_content */ + #ifndef EGL_EXT_protected_surface #define EGL_EXT_protected_surface 1 -#define EGL_PROTECTED_CONTENT_EXT 0x32C0 #endif /* EGL_EXT_protected_surface */ #ifndef EGL_EXT_stream_consumer_egloutput @@ -711,6 +829,27 @@ EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerOutputEXT (EGLDisplay dpy, EGLStr #endif #endif /* EGL_EXT_stream_consumer_egloutput */ +#ifndef EGL_EXT_surface_CTA861_3_metadata +#define EGL_EXT_surface_CTA861_3_metadata 1 +#define EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT 0x3360 +#define EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT 0x3361 +#endif /* EGL_EXT_surface_CTA861_3_metadata */ + +#ifndef EGL_EXT_surface_SMPTE2086_metadata +#define EGL_EXT_surface_SMPTE2086_metadata 1 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT 0x3341 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT 0x3342 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT 0x3343 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT 0x3344 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT 0x3345 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT 0x3346 +#define EGL_SMPTE2086_WHITE_POINT_X_EXT 0x3347 +#define EGL_SMPTE2086_WHITE_POINT_Y_EXT 0x3348 +#define EGL_SMPTE2086_MAX_LUMINANCE_EXT 0x3349 +#define EGL_SMPTE2086_MIN_LUMINANCE_EXT 0x334A +#define EGL_METADATA_SCALING_EXT 50000 +#endif /* EGL_EXT_surface_SMPTE2086_metadata */ + #ifndef EGL_EXT_swap_buffers_with_damage #define EGL_EXT_swap_buffers_with_damage 1 typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); @@ -779,6 +918,12 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI (EGLDisplay dpy, EGLConfi #define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103 #endif /* EGL_IMG_context_priority */ +#ifndef EGL_IMG_image_plane_attribs +#define EGL_IMG_image_plane_attribs 1 +#define EGL_NATIVE_BUFFER_MULTIPLANE_SEPARATE_IMG 0x3105 +#define EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG 0x3106 +#endif /* EGL_IMG_image_plane_attribs */ + #ifndef EGL_MESA_drm_image #define EGL_MESA_drm_image 1 #define EGL_DRM_BUFFER_FORMAT_MESA 0x31D0 @@ -811,6 +956,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageMESA (EGLDisplay dpy, EGLImage #define EGL_PLATFORM_GBM_MESA 0x31D7 #endif /* EGL_MESA_platform_gbm */ +#ifndef EGL_MESA_platform_surfaceless +#define EGL_MESA_platform_surfaceless 1 +#define EGL_PLATFORM_SURFACELESS_MESA 0x31DD +#endif /* EGL_MESA_platform_surfaceless */ + #ifndef EGL_NOK_swap_region #define EGL_NOK_swap_region 1 typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects); @@ -894,6 +1044,129 @@ EGLAPI EGLBoolean EGLAPIENTRY eglPostSubBufferNV (EGLDisplay dpy, EGLSurface sur #endif #endif /* EGL_NV_post_sub_buffer */ +#ifndef EGL_NV_robustness_video_memory_purge +#define EGL_NV_robustness_video_memory_purge 1 +#define EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x334C +#endif /* EGL_NV_robustness_video_memory_purge */ + +#ifndef EGL_NV_stream_consumer_gltexture_yuv +#define EGL_NV_stream_consumer_gltexture_yuv 1 +#define EGL_YUV_PLANE0_TEXTURE_UNIT_NV 0x332C +#define EGL_YUV_PLANE1_TEXTURE_UNIT_NV 0x332D +#define EGL_YUV_PLANE2_TEXTURE_UNIT_NV 0x332E +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLAttrib *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalAttribsNV (EGLDisplay dpy, EGLStreamKHR stream, EGLAttrib *attrib_list); +#endif +#endif /* EGL_NV_stream_consumer_gltexture_yuv */ + +#ifndef EGL_NV_stream_cross_display +#define EGL_NV_stream_cross_display 1 +#define EGL_STREAM_CROSS_DISPLAY_NV 0x334E +#endif /* EGL_NV_stream_cross_display */ + +#ifndef EGL_NV_stream_cross_object +#define EGL_NV_stream_cross_object 1 +#define EGL_STREAM_CROSS_OBJECT_NV 0x334D +#endif /* EGL_NV_stream_cross_object */ + +#ifndef EGL_NV_stream_cross_partition +#define EGL_NV_stream_cross_partition 1 +#define EGL_STREAM_CROSS_PARTITION_NV 0x323F +#endif /* EGL_NV_stream_cross_partition */ + +#ifndef EGL_NV_stream_cross_process +#define EGL_NV_stream_cross_process 1 +#define EGL_STREAM_CROSS_PROCESS_NV 0x3245 +#endif /* EGL_NV_stream_cross_process */ + +#ifndef EGL_NV_stream_cross_system +#define EGL_NV_stream_cross_system 1 +#define EGL_STREAM_CROSS_SYSTEM_NV 0x334F +#endif /* EGL_NV_stream_cross_system */ + +#ifndef EGL_NV_stream_fifo_next +#define EGL_NV_stream_fifo_next 1 +#define EGL_PENDING_FRAME_NV 0x3329 +#define EGL_STREAM_TIME_PENDING_NV 0x332A +#endif /* EGL_NV_stream_fifo_next */ + +#ifndef EGL_NV_stream_fifo_synchronous +#define EGL_NV_stream_fifo_synchronous 1 +#define EGL_STREAM_FIFO_SYNCHRONOUS_NV 0x3336 +#endif /* EGL_NV_stream_fifo_synchronous */ + +#ifndef EGL_NV_stream_frame_limits +#define EGL_NV_stream_frame_limits 1 +#define EGL_PRODUCER_MAX_FRAME_HINT_NV 0x3337 +#define EGL_CONSUMER_MAX_FRAME_HINT_NV 0x3338 +#endif /* EGL_NV_stream_frame_limits */ + +#ifndef EGL_NV_stream_metadata +#define EGL_NV_stream_metadata 1 +#define EGL_MAX_STREAM_METADATA_BLOCKS_NV 0x3250 +#define EGL_MAX_STREAM_METADATA_BLOCK_SIZE_NV 0x3251 +#define EGL_MAX_STREAM_METADATA_TOTAL_SIZE_NV 0x3252 +#define EGL_PRODUCER_METADATA_NV 0x3253 +#define EGL_CONSUMER_METADATA_NV 0x3254 +#define EGL_PENDING_METADATA_NV 0x3328 +#define EGL_METADATA0_SIZE_NV 0x3255 +#define EGL_METADATA1_SIZE_NV 0x3256 +#define EGL_METADATA2_SIZE_NV 0x3257 +#define EGL_METADATA3_SIZE_NV 0x3258 +#define EGL_METADATA0_TYPE_NV 0x3259 +#define EGL_METADATA1_TYPE_NV 0x325A +#define EGL_METADATA2_TYPE_NV 0x325B +#define EGL_METADATA3_TYPE_NV 0x325C +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBNVPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETSTREAMMETADATANVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLint n, EGLint offset, EGLint size, const void *data); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMMETADATANVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum name, EGLint n, EGLint offset, EGLint size, void *data); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribNV (EGLDisplay dpy, EGLint attribute, EGLAttrib *value); +EGLAPI EGLBoolean EGLAPIENTRY eglSetStreamMetadataNV (EGLDisplay dpy, EGLStreamKHR stream, EGLint n, EGLint offset, EGLint size, const void *data); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamMetadataNV (EGLDisplay dpy, EGLStreamKHR stream, EGLenum name, EGLint n, EGLint offset, EGLint size, void *data); +#endif +#endif /* EGL_NV_stream_metadata */ + +#ifndef EGL_NV_stream_remote +#define EGL_NV_stream_remote 1 +#define EGL_STREAM_STATE_INITIALIZING_NV 0x3240 +#define EGL_STREAM_TYPE_NV 0x3241 +#define EGL_STREAM_PROTOCOL_NV 0x3242 +#define EGL_STREAM_ENDPOINT_NV 0x3243 +#define EGL_STREAM_LOCAL_NV 0x3244 +#define EGL_STREAM_PRODUCER_NV 0x3247 +#define EGL_STREAM_CONSUMER_NV 0x3248 +#define EGL_STREAM_PROTOCOL_FD_NV 0x3246 +#endif /* EGL_NV_stream_remote */ + +#ifndef EGL_NV_stream_reset +#define EGL_NV_stream_reset 1 +#define EGL_SUPPORT_RESET_NV 0x3334 +#define EGL_SUPPORT_REUSE_NV 0x3335 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLRESETSTREAMNVPROC) (EGLDisplay dpy, EGLStreamKHR stream); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglResetStreamNV (EGLDisplay dpy, EGLStreamKHR stream); +#endif +#endif /* EGL_NV_stream_reset */ + +#ifndef EGL_NV_stream_socket +#define EGL_NV_stream_socket 1 +#define EGL_STREAM_PROTOCOL_SOCKET_NV 0x324B +#define EGL_SOCKET_HANDLE_NV 0x324C +#define EGL_SOCKET_TYPE_NV 0x324D +#endif /* EGL_NV_stream_socket */ + +#ifndef EGL_NV_stream_socket_inet +#define EGL_NV_stream_socket_inet 1 +#define EGL_SOCKET_TYPE_INET_NV 0x324F +#endif /* EGL_NV_stream_socket_inet */ + +#ifndef EGL_NV_stream_socket_unix +#define EGL_NV_stream_socket_unix 1 +#define EGL_SOCKET_TYPE_UNIX_NV 0x324E +#endif /* EGL_NV_stream_socket_unix */ + #ifndef EGL_NV_stream_sync #define EGL_NV_stream_sync 1 #define EGL_SYNC_NEW_FRAME_NV 0x321F @@ -920,7 +1193,7 @@ typedef khronos_utime_nanoseconds_t EGLTimeNV; #define EGL_SYNC_TYPE_NV 0x30ED #define EGL_SYNC_CONDITION_NV 0x30EE #define EGL_SYNC_FENCE_NV 0x30EF -#define EGL_NO_SYNC_NV ((EGLSyncNV)0) +#define EGL_NO_SYNC_NV EGL_CAST(EGLSyncNV,0) typedef EGLSyncNV (EGLAPIENTRYP PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list); typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync); typedef EGLBoolean (EGLAPIENTRYP PFNEGLFENCENVPROC) (EGLSyncNV sync); @@ -961,6 +1234,9 @@ EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV (void); #define EGL_NATIVE_SURFACE_TIZEN 0x32A1 #endif /* EGL_TIZEN_image_native_surface */ +/* ANGLE EGL extensions */ +#include "eglext_angle.h" + #ifdef __cplusplus } #endif diff --git a/src/3rdparty/angle/include/EGL/eglext_angle.h b/src/3rdparty/angle/include/EGL/eglext_angle.h new file mode 100644 index 0000000000..95f0902838 --- /dev/null +++ b/src/3rdparty/angle/include/EGL/eglext_angle.h @@ -0,0 +1,170 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// eglext_angle.h: ANGLE modifications to the eglext.h header file. +// Currently we don't include this file directly, we patch eglext.h +// to include it implicitly so it is visible throughout our code. + +#ifndef INCLUDE_EGL_EGLEXT_ANGLE_ +#define INCLUDE_EGL_EGLEXT_ANGLE_ + +// clang-format off + +#ifndef EGL_ANGLE_robust_resource_initialization +#define EGL_ANGLE_robust_resource_initialization 1 +#define EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE 0x3453 +#endif /* EGL_ANGLE_robust_resource_initialization */ + +#ifndef EGL_ANGLE_keyed_mutex +#define EGL_ANGLE_keyed_mutex 1 +#define EGL_DXGI_KEYED_MUTEX_ANGLE 0x33A2 +#endif /* EGL_ANGLE_keyed_mutex */ + +#ifndef EGL_ANGLE_d3d_texture_client_buffer +#define EGL_ANGLE_d3d_texture_client_buffer 1 +#define EGL_D3D_TEXTURE_ANGLE 0x33A3 +#endif /* EGL_ANGLE_d3d_texture_client_buffer */ + +#ifndef EGL_ANGLE_software_display +#define EGL_ANGLE_software_display 1 +#define EGL_SOFTWARE_DISPLAY_ANGLE ((EGLNativeDisplayType)-1) +#endif /* EGL_ANGLE_software_display */ + +#ifndef EGL_ANGLE_direct3d_display +#define EGL_ANGLE_direct3d_display 1 +#define EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ((EGLNativeDisplayType)-2) +#define EGL_D3D11_ONLY_DISPLAY_ANGLE ((EGLNativeDisplayType)-3) +#endif /* EGL_ANGLE_direct3d_display */ + +#ifndef EGL_ANGLE_direct_composition +#define EGL_ANGLE_direct_composition 1 +#define EGL_DIRECT_COMPOSITION_ANGLE 0x33A5 +#endif /* EGL_ANGLE_direct_composition */ + +#ifndef EGL_ANGLE_platform_angle +#define EGL_ANGLE_platform_angle 1 +#define EGL_PLATFORM_ANGLE_ANGLE 0x3202 +#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203 +#define EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE 0x3204 +#define EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE 0x3205 +#define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3206 +#define EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE 0x3451 +#endif /* EGL_ANGLE_platform_angle */ + +#ifndef EGL_ANGLE_platform_angle_d3d +#define EGL_ANGLE_platform_angle_d3d 1 +#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3207 +#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208 +#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE 0x3209 +#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE 0x320A +#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE 0x320B +#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE 0x320C +#define EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE 0x320F +#endif /* EGL_ANGLE_platform_angle_d3d */ + +#ifndef EGL_ANGLE_platform_angle_opengl +#define EGL_ANGLE_platform_angle_opengl 1 +#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320D +#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320E +#endif /* EGL_ANGLE_platform_angle_opengl */ + +#ifndef EGL_ANGLE_platform_angle_null +#define EGL_ANGLE_platform_angle_null 1 +#define EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE 0x33AE +#endif /* EGL_ANGLE_platform_angle_null */ + +#ifndef EGL_ANGLE_platform_angle_vulkan +#define EGL_ANGLE_platform_angle_vulkan 1 +#define EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE 0x3450 +#endif /* EGL_ANGLE_platform_angle_vulkan */ + +#ifndef EGL_ANGLE_x11_visual +#define EGL_ANGLE_x11_visual +#define EGL_X11_VISUAL_ID_ANGLE 0x33A3 +#endif /* EGL_ANGLE_x11_visual */ + +#ifndef EGL_ANGLE_flexible_surface_compatibility +#define EGL_ANGLE_flexible_surface_compatibility 1 +#define EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE 0x33A6 +#endif /* EGL_ANGLE_flexible_surface_compatibility */ + +#ifndef EGL_ANGLE_surface_orientation +#define EGL_ANGLE_surface_orientation +#define EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE 0x33A7 +#define EGL_SURFACE_ORIENTATION_ANGLE 0x33A8 +#define EGL_SURFACE_ORIENTATION_INVERT_X_ANGLE 0x0001 +#define EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE 0x0002 +#endif /* EGL_ANGLE_surface_orientation */ + +#ifndef EGL_ANGLE_experimental_present_path +#define EGL_ANGLE_experimental_present_path +#define EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE 0x33A4 +#define EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE 0x33A9 +#define EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE 0x33AA +#endif /* EGL_ANGLE_experimental_present_path */ + +#ifndef EGL_ANGLE_stream_producer_d3d_texture_nv12 +#define EGL_ANGLE_stream_producer_d3d_texture_nv12 +#define EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE 0x33AB +typedef EGLBoolean(EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERD3DTEXTURENV12ANGLEPROC)(EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +typedef EGLBoolean(EGLAPIENTRYP PFNEGLSTREAMPOSTD3DTEXTURENV12ANGLEPROC)(EGLDisplay dpy, EGLStreamKHR stream, void *texture, const EGLAttrib *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglCreateStreamProducerD3DTextureNV12ANGLE(EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamPostD3DTextureNV12ANGLE(EGLDisplay dpy, EGLStreamKHR stream, void *texture, const EGLAttrib *attrib_list); +#endif +#endif /* EGL_ANGLE_stream_producer_d3d_texture_nv12 */ + +#ifndef EGL_ANGLE_create_context_webgl_compatibility +#define EGL_ANGLE_create_context_webgl_compatibility 1 +#define EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE 0x3AAC +#endif /* EGL_ANGLE_create_context_webgl_compatibility */ + +#ifndef EGL_ANGLE_display_texture_share_group +#define EGL_ANGLE_display_texture_share_group 1 +#define EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE 0x3AAF +#endif /* EGL_ANGLE_display_texture_share_group */ + +#ifndef EGL_CHROMIUM_create_context_bind_generates_resource +#define EGL_CHROMIUM_create_context_bind_generates_resource 1 +#define EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM 0x3AAD +#endif /* EGL_CHROMIUM_create_context_bind_generates_resource */ + +#ifndef EGL_ANGLE_create_context_client_arrays +#define EGL_ANGLE_create_context_client_arrays 1 +#define EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE 0x3452 +#endif /* EGL_ANGLE_create_context_client_arrays */ + +#ifndef EGL_ANGLE_device_creation +#define EGL_ANGLE_device_creation 1 +typedef EGLDeviceEXT(EGLAPIENTRYP PFNEGLCREATEDEVICEANGLEPROC) (EGLint device_type, void *native_device, const EGLAttrib *attrib_list); +typedef EGLBoolean(EGLAPIENTRYP PFNEGLRELEASEDEVICEANGLEPROC) (EGLDeviceEXT device); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLDeviceEXT EGLAPIENTRY eglCreateDeviceANGLE(EGLint device_type, void *native_device, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglReleaseDeviceANGLE(EGLDeviceEXT device); +#endif +#endif /* EGL_ANGLE_device_creation */ + +#ifndef EGL_ANGLE_program_cache_control +#define EGL_ANGLE_program_cache_control 1 +#define EGL_PROGRAM_CACHE_SIZE_ANGLE 0x3455 +#define EGL_PROGRAM_CACHE_KEY_LENGTH_ANGLE 0x3456 +#define EGL_PROGRAM_CACHE_RESIZE_ANGLE 0x3457 +#define EGL_PROGRAM_CACHE_TRIM_ANGLE 0x3458 +#define EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE 0x3459 +typedef EGLint (EGLAPIENTRYP PFNEGLPROGRAMCACHEGETATTRIBANGLEPROC) (EGLDisplay dpy, EGLenum attrib); +typedef void (EGLAPIENTRYP PFNEGLPROGRAMCACHEQUERYANGLEPROC) (EGLDisplay dpy, EGLint index, void *key, EGLint *keysize, void *binary, EGLint *binarysize); +typedef void (EGLAPIENTRYP PFNEGPROGRAMCACHELPOPULATEANGLEPROC) (EGLDisplay dpy, const void *key, EGLint keysize, const void *binary, EGLint binarysize); +typedef EGLint (EGLAPIENTRYP PFNEGLPROGRAMCACHERESIZEANGLEPROC) (EGLDisplay dpy, EGLint limit, EGLenum mode); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLint EGLAPIENTRY eglProgramCacheGetAttribANGLE(EGLDisplay dpy, EGLenum attrib); +EGLAPI void EGLAPIENTRY eglProgramCacheQueryANGLE(EGLDisplay dpy, EGLint index, void *key, EGLint *keysize, void *binary, EGLint *binarysize); +EGLAPI void EGLAPIENTRY eglProgramCachePopulateANGLE(EGLDisplay dpy, const void *key, EGLint keysize, const void *binary, EGLint binarysize); +EGLAPI EGLint EGLAPIENTRY eglProgramCacheResizeANGLE(EGLDisplay dpy, EGLint limit, EGLenum mode); +#endif +#endif /* EGL_ANGLE_program_cache_control */ + +// clang-format on + +#endif // INCLUDE_EGL_EGLEXT_ANGLE_ diff --git a/src/3rdparty/angle/include/EGL/eglplatform.h b/src/3rdparty/angle/include/EGL/eglplatform.h index 6d550da9cd..333448be34 100644 --- a/src/3rdparty/angle/include/EGL/eglplatform.h +++ b/src/3rdparty/angle/include/EGL/eglplatform.h @@ -2,7 +2,7 @@ #define __eglplatform_h_ /* -** Copyright (c) 2007-2013 The Khronos Group Inc. +** Copyright (c) 2007-2016 The Khronos Group Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a ** copy of this software and/or associated documentation files (the @@ -83,7 +83,8 @@ typedef HWND EGLNativeWindowType; typedef IInspectable* EGLNativeWindowType; #endif -#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */ +#elif defined(__APPLE__) || defined(__WINSCW__) || defined(__SYMBIAN32__) || \ + defined(__Fuchsia__) || defined(__HAIKU__) typedef int EGLNativeDisplayType; typedef void *EGLNativeWindowType; @@ -105,6 +106,12 @@ typedef intptr_t EGLNativeDisplayType; typedef intptr_t EGLNativeWindowType; typedef intptr_t EGLNativePixmapType; +#elif defined(WL_EGL_PLATFORM) + +typedef struct wl_display *EGLNativeDisplayType; +typedef struct wl_egl_pixmap *EGLNativePixmapType; +typedef struct wl_egl_window *EGLNativeWindowType; + #elif defined(__unix__) /* X11 (tentative) */ @@ -115,18 +122,6 @@ typedef Display *EGLNativeDisplayType; typedef Pixmap EGLNativePixmapType; typedef Window EGLNativeWindowType; -#elif defined(__GNUC__) && ( defined(__APPLE_CPP__) || defined(__APPLE_CC__) || defined(__MACOS_CLASSIC__) ) - -#if defined(__OBJC__) -@class CALayer; -#else -class CALayer; -#endif - -typedef void *EGLNativeDisplayType; -typedef void *EGLNativePixmapType; -typedef CALayer *EGLNativeWindowType; - #else #error "Platform not recognized" #endif @@ -146,4 +141,12 @@ typedef EGLNativeWindowType NativeWindowType; */ typedef khronos_int32_t EGLint; + +/* C++ / C typecast macros for special EGL handle values */ +#if defined(__cplusplus) +#define EGL_CAST(type, value) (static_cast(value)) +#else +#define EGL_CAST(type, value) ((type) (value)) +#endif + #endif /* __eglplatform_h */ diff --git a/src/3rdparty/angle/include/GLES2/gl2.h b/src/3rdparty/angle/include/GLES2/gl2.h index 027e1f7136..975c3dc495 100644 --- a/src/3rdparty/angle/include/GLES2/gl2.h +++ b/src/3rdparty/angle/include/GLES2/gl2.h @@ -6,7 +6,7 @@ extern "C" { #endif /* -** Copyright (c) 2013-2015 The Khronos Group Inc. +** Copyright (c) 2013-2017 The Khronos Group Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a ** copy of this software and/or associated documentation files (the @@ -31,9 +31,7 @@ extern "C" { ** This header is generated from the Khronos OpenGL / OpenGL ES XML ** API Registry. The current version of the Registry, generator scripts ** used to make the header, and the header can be found at -** http://www.opengl.org/registry/ -** -** Khronos $Revision: 31811 $ on $Date: 2015-08-10 00:01:11 -0700 (Mon, 10 Aug 2015) $ +** https://github.com/KhronosGroup/OpenGL-Registry */ #include @@ -42,7 +40,11 @@ extern "C" { #define GL_APIENTRYP GL_APIENTRY* #endif -/* Generated on date 20150809 */ +#ifndef GL_GLES_PROTOTYPES +#define GL_GLES_PROTOTYPES 1 +#endif + +/* Generated on date 20170325 */ /* Generated C header for: * API: gles2 @@ -520,7 +522,7 @@ typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GL typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v); typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); typedef void (GL_APIENTRYP PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height); -#ifdef GL_GLEXT_PROTOTYPES +#if GL_GLES_PROTOTYPES GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture); GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader); GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name); diff --git a/src/3rdparty/angle/include/GLES2/gl2ext.h b/src/3rdparty/angle/include/GLES2/gl2ext.h index 51886a2dcb..4def3ced4b 100644 --- a/src/3rdparty/angle/include/GLES2/gl2ext.h +++ b/src/3rdparty/angle/include/GLES2/gl2ext.h @@ -6,7 +6,7 @@ extern "C" { #endif /* -** Copyright (c) 2013-2015 The Khronos Group Inc. +** Copyright (c) 2013-2017 The Khronos Group Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a ** copy of this software and/or associated documentation files (the @@ -31,16 +31,14 @@ extern "C" { ** This header is generated from the Khronos OpenGL / OpenGL ES XML ** API Registry. The current version of the Registry, generator scripts ** used to make the header, and the header can be found at -** http://www.opengl.org/registry/ -** -** Khronos $Revision: 31902 $ on $Date: 2015-09-03 15:44:53 -0700 (Thu, 03 Sep 2015) $ +** https://github.com/KhronosGroup/OpenGL-Registry */ #ifndef GL_APIENTRYP #define GL_APIENTRYP GL_APIENTRY* #endif -/* Generated on date 20150903 */ +/* Generated on date 20170613 */ /* Generated C header for: * API: gles2 @@ -225,6 +223,10 @@ GL_APICALL void GL_APIENTRY glGetnUniformuivKHR (GLuint program, GLint location, #define GL_KHR_texture_compression_astc_ldr 1 #endif /* GL_KHR_texture_compression_astc_ldr */ +#ifndef GL_KHR_texture_compression_astc_sliced_3d +#define GL_KHR_texture_compression_astc_sliced_3d 1 +#endif /* GL_KHR_texture_compression_astc_sliced_3d */ + #ifndef GL_OES_EGL_image #define GL_OES_EGL_image 1 typedef void *GLeglImageOES; @@ -748,6 +750,34 @@ GL_APICALL GLboolean GL_APIENTRY glIsVertexArrayOES (GLuint array); #define GL_INT_10_10_10_2_OES 0x8DF7 #endif /* GL_OES_vertex_type_10_10_10_2 */ +#ifndef GL_OES_viewport_array +#define GL_OES_viewport_array 1 +#define GL_MAX_VIEWPORTS_OES 0x825B +#define GL_VIEWPORT_SUBPIXEL_BITS_OES 0x825C +#define GL_VIEWPORT_BOUNDS_RANGE_OES 0x825D +#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX_OES 0x825F +typedef void (GL_APIENTRYP PFNGLVIEWPORTARRAYVOESPROC) (GLuint first, GLsizei count, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLVIEWPORTINDEXEDFOESPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); +typedef void (GL_APIENTRYP PFNGLVIEWPORTINDEXEDFVOESPROC) (GLuint index, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLSCISSORARRAYVOESPROC) (GLuint first, GLsizei count, const GLint *v); +typedef void (GL_APIENTRYP PFNGLSCISSORINDEXEDOESPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLSCISSORINDEXEDVOESPROC) (GLuint index, const GLint *v); +typedef void (GL_APIENTRYP PFNGLDEPTHRANGEARRAYFVOESPROC) (GLuint first, GLsizei count, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLDEPTHRANGEINDEXEDFOESPROC) (GLuint index, GLfloat n, GLfloat f); +typedef void (GL_APIENTRYP PFNGLGETFLOATI_VOESPROC) (GLenum target, GLuint index, GLfloat *data); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glViewportArrayvOES (GLuint first, GLsizei count, const GLfloat *v); +GL_APICALL void GL_APIENTRY glViewportIndexedfOES (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); +GL_APICALL void GL_APIENTRY glViewportIndexedfvOES (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glScissorArrayvOES (GLuint first, GLsizei count, const GLint *v); +GL_APICALL void GL_APIENTRY glScissorIndexedOES (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glScissorIndexedvOES (GLuint index, const GLint *v); +GL_APICALL void GL_APIENTRY glDepthRangeArrayfvOES (GLuint first, GLsizei count, const GLfloat *v); +GL_APICALL void GL_APIENTRY glDepthRangeIndexedfOES (GLuint index, GLfloat n, GLfloat f); +GL_APICALL void GL_APIENTRY glGetFloati_vOES (GLenum target, GLuint index, GLfloat *data); +#endif +#endif /* GL_OES_viewport_array */ + #ifndef GL_AMD_compressed_3DC_texture #define GL_AMD_compressed_3DC_texture 1 #define GL_3DC_X_AMD 0x87F9 @@ -1021,6 +1051,10 @@ GL_APICALL void GL_APIENTRY glGetSyncivAPPLE (GLsync sync, GLenum pname, GLsizei #define GL_SHADER_BINARY_DMP 0x9250 #endif /* GL_DMP_shader_binary */ +#ifndef GL_EXT_EGL_image_array +#define GL_EXT_EGL_image_array 1 +#endif /* GL_EXT_EGL_image_array */ + #ifndef GL_EXT_YUV_target #define GL_EXT_YUV_target 1 #define GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT 0x8BE7 @@ -1082,6 +1116,31 @@ GL_APICALL void GL_APIENTRY glBufferStorageEXT (GLenum target, GLsizeiptr size, #endif #endif /* GL_EXT_buffer_storage */ +#ifndef GL_EXT_clear_texture +#define GL_EXT_clear_texture 1 +typedef void (GL_APIENTRYP PFNGLCLEARTEXIMAGEEXTPROC) (GLuint texture, GLint level, GLenum format, GLenum type, const void *data); +typedef void (GL_APIENTRYP PFNGLCLEARTEXSUBIMAGEEXTPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glClearTexImageEXT (GLuint texture, GLint level, GLenum format, GLenum type, const void *data); +GL_APICALL void GL_APIENTRY glClearTexSubImageEXT (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data); +#endif +#endif /* GL_EXT_clear_texture */ + +#ifndef GL_EXT_clip_cull_distance +#define GL_EXT_clip_cull_distance 1 +#define GL_MAX_CLIP_DISTANCES_EXT 0x0D32 +#define GL_MAX_CULL_DISTANCES_EXT 0x82F9 +#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT 0x82FA +#define GL_CLIP_DISTANCE0_EXT 0x3000 +#define GL_CLIP_DISTANCE1_EXT 0x3001 +#define GL_CLIP_DISTANCE2_EXT 0x3002 +#define GL_CLIP_DISTANCE3_EXT 0x3003 +#define GL_CLIP_DISTANCE4_EXT 0x3004 +#define GL_CLIP_DISTANCE5_EXT 0x3005 +#define GL_CLIP_DISTANCE6_EXT 0x3006 +#define GL_CLIP_DISTANCE7_EXT 0x3007 +#endif /* GL_EXT_clip_cull_distance */ + #ifndef GL_EXT_color_buffer_float #define GL_EXT_color_buffer_float 1 #endif /* GL_EXT_color_buffer_float */ @@ -1096,6 +1155,10 @@ GL_APICALL void GL_APIENTRY glBufferStorageEXT (GLenum target, GLsizeiptr size, #define GL_UNSIGNED_NORMALIZED_EXT 0x8C17 #endif /* GL_EXT_color_buffer_half_float */ +#ifndef GL_EXT_conservative_depth +#define GL_EXT_conservative_depth 1 +#endif /* GL_EXT_conservative_depth */ + #ifndef GL_EXT_copy_image #define GL_EXT_copy_image 1 typedef void (GL_APIENTRYP PFNGLCOPYIMAGESUBDATAEXTPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); @@ -1267,6 +1330,27 @@ GL_APICALL void GL_APIENTRY glDrawElementsInstancedEXT (GLenum mode, GLsizei cou #endif #endif /* GL_EXT_draw_instanced */ +#ifndef GL_EXT_draw_transform_feedback +#define GL_EXT_draw_transform_feedback 1 +typedef void (GL_APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKEXTPROC) (GLenum mode, GLuint id); +typedef void (GL_APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDEXTPROC) (GLenum mode, GLuint id, GLsizei instancecount); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawTransformFeedbackEXT (GLenum mode, GLuint id); +GL_APICALL void GL_APIENTRY glDrawTransformFeedbackInstancedEXT (GLenum mode, GLuint id, GLsizei instancecount); +#endif +#endif /* GL_EXT_draw_transform_feedback */ + +#ifndef GL_EXT_external_buffer +#define GL_EXT_external_buffer 1 +typedef void *GLeglClientBufferEXT; +typedef void (GL_APIENTRYP PFNGLBUFFERSTORAGEEXTERNALEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags); +typedef void (GL_APIENTRYP PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBufferStorageExternalEXT (GLenum target, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags); +GL_APICALL void GL_APIENTRY glNamedBufferStorageExternalEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags); +#endif +#endif /* GL_EXT_external_buffer */ + #ifndef GL_EXT_float_blend #define GL_EXT_float_blend 1 #endif /* GL_EXT_float_blend */ @@ -1345,6 +1429,85 @@ GL_APICALL void GL_APIENTRY glFlushMappedBufferRangeEXT (GLenum target, GLintptr #endif #endif /* GL_EXT_map_buffer_range */ +#ifndef GL_EXT_memory_object +#define GL_EXT_memory_object 1 +#define GL_TEXTURE_TILING_EXT 0x9580 +#define GL_DEDICATED_MEMORY_OBJECT_EXT 0x9581 +#define GL_PROTECTED_MEMORY_OBJECT_EXT 0x959B +#define GL_NUM_TILING_TYPES_EXT 0x9582 +#define GL_TILING_TYPES_EXT 0x9583 +#define GL_OPTIMAL_TILING_EXT 0x9584 +#define GL_LINEAR_TILING_EXT 0x9585 +#define GL_NUM_DEVICE_UUIDS_EXT 0x9596 +#define GL_DEVICE_UUID_EXT 0x9597 +#define GL_DRIVER_UUID_EXT 0x9598 +#define GL_UUID_SIZE_EXT 16 +typedef void (GL_APIENTRYP PFNGLGETUNSIGNEDBYTEVEXTPROC) (GLenum pname, GLubyte *data); +typedef void (GL_APIENTRYP PFNGLGETUNSIGNEDBYTEI_VEXTPROC) (GLenum target, GLuint index, GLubyte *data); +typedef void (GL_APIENTRYP PFNGLDELETEMEMORYOBJECTSEXTPROC) (GLsizei n, const GLuint *memoryObjects); +typedef GLboolean (GL_APIENTRYP PFNGLISMEMORYOBJECTEXTPROC) (GLuint memoryObject); +typedef void (GL_APIENTRYP PFNGLCREATEMEMORYOBJECTSEXTPROC) (GLsizei n, GLuint *memoryObjects); +typedef void (GL_APIENTRYP PFNGLMEMORYOBJECTPARAMETERIVEXTPROC) (GLuint memoryObject, GLenum pname, const GLint *params); +typedef void (GL_APIENTRYP PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC) (GLuint memoryObject, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGEMEM2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGEMEM3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +typedef void (GL_APIENTRYP PFNGLBUFFERSTORAGEMEMEXTPROC) (GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGEMEM2DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC) (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGEMEM3DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC) (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +typedef void (GL_APIENTRYP PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC) (GLuint buffer, GLsizeiptr size, GLuint memory, GLuint64 offset); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetUnsignedBytevEXT (GLenum pname, GLubyte *data); +GL_APICALL void GL_APIENTRY glGetUnsignedBytei_vEXT (GLenum target, GLuint index, GLubyte *data); +GL_APICALL void GL_APIENTRY glDeleteMemoryObjectsEXT (GLsizei n, const GLuint *memoryObjects); +GL_APICALL GLboolean GL_APIENTRY glIsMemoryObjectEXT (GLuint memoryObject); +GL_APICALL void GL_APIENTRY glCreateMemoryObjectsEXT (GLsizei n, GLuint *memoryObjects); +GL_APICALL void GL_APIENTRY glMemoryObjectParameterivEXT (GLuint memoryObject, GLenum pname, const GLint *params); +GL_APICALL void GL_APIENTRY glGetMemoryObjectParameterivEXT (GLuint memoryObject, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glTexStorageMem2DEXT (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset); +GL_APICALL void GL_APIENTRY glTexStorageMem2DMultisampleEXT (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +GL_APICALL void GL_APIENTRY glTexStorageMem3DEXT (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset); +GL_APICALL void GL_APIENTRY glTexStorageMem3DMultisampleEXT (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +GL_APICALL void GL_APIENTRY glBufferStorageMemEXT (GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset); +GL_APICALL void GL_APIENTRY glTextureStorageMem2DEXT (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset); +GL_APICALL void GL_APIENTRY glTextureStorageMem2DMultisampleEXT (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +GL_APICALL void GL_APIENTRY glTextureStorageMem3DEXT (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset); +GL_APICALL void GL_APIENTRY glTextureStorageMem3DMultisampleEXT (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +GL_APICALL void GL_APIENTRY glNamedBufferStorageMemEXT (GLuint buffer, GLsizeiptr size, GLuint memory, GLuint64 offset); +#endif +#endif /* GL_EXT_memory_object */ + +#ifndef GL_EXT_memory_object_fd +#define GL_EXT_memory_object_fd 1 +#define GL_HANDLE_TYPE_OPAQUE_FD_EXT 0x9586 +typedef void (GL_APIENTRYP PFNGLIMPORTMEMORYFDEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, GLint fd); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glImportMemoryFdEXT (GLuint memory, GLuint64 size, GLenum handleType, GLint fd); +#endif +#endif /* GL_EXT_memory_object_fd */ + +#ifndef GL_EXT_memory_object_win32 +#define GL_EXT_memory_object_win32 1 +#define GL_HANDLE_TYPE_OPAQUE_WIN32_EXT 0x9587 +#define GL_HANDLE_TYPE_OPAQUE_WIN32_KMT_EXT 0x9588 +#define GL_DEVICE_LUID_EXT 0x9599 +#define GL_DEVICE_NODE_MASK_EXT 0x959A +#define GL_LUID_SIZE_EXT 8 +#define GL_HANDLE_TYPE_D3D12_TILEPOOL_EXT 0x9589 +#define GL_HANDLE_TYPE_D3D12_RESOURCE_EXT 0x958A +#define GL_HANDLE_TYPE_D3D11_IMAGE_EXT 0x958B +#define GL_HANDLE_TYPE_D3D11_IMAGE_KMT_EXT 0x958C +typedef void (GL_APIENTRYP PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, void *handle); +typedef void (GL_APIENTRYP PFNGLIMPORTMEMORYWIN32NAMEEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, const void *name); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glImportMemoryWin32HandleEXT (GLuint memory, GLuint64 size, GLenum handleType, void *handle); +GL_APICALL void GL_APIENTRY glImportMemoryWin32NameEXT (GLuint memory, GLuint64 size, GLenum handleType, const void *name); +#endif +#endif /* GL_EXT_memory_object_win32 */ + #ifndef GL_EXT_multi_draw_arrays #define GL_EXT_multi_draw_arrays 1 typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); @@ -1408,6 +1571,15 @@ GL_APICALL void GL_APIENTRY glGetIntegeri_vEXT (GLenum target, GLuint index, GLi #define GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT 0x8D6A #endif /* GL_EXT_occlusion_query_boolean */ +#ifndef GL_EXT_polygon_offset_clamp +#define GL_EXT_polygon_offset_clamp 1 +#define GL_POLYGON_OFFSET_CLAMP_EXT 0x8E1B +typedef void (GL_APIENTRYP PFNGLPOLYGONOFFSETCLAMPEXTPROC) (GLfloat factor, GLfloat units, GLfloat clamp); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glPolygonOffsetClampEXT (GLfloat factor, GLfloat units, GLfloat clamp); +#endif +#endif /* GL_EXT_polygon_offset_clamp */ + #ifndef GL_EXT_post_depth_coverage #define GL_EXT_post_depth_coverage 1 #endif /* GL_EXT_post_depth_coverage */ @@ -1421,6 +1593,12 @@ GL_APICALL void GL_APIENTRY glPrimitiveBoundingBoxEXT (GLfloat minX, GLfloat min #endif #endif /* GL_EXT_primitive_bounding_box */ +#ifndef GL_EXT_protected_textures +#define GL_EXT_protected_textures 1 +#define GL_CONTEXT_FLAG_PROTECTED_CONTENT_BIT_EXT 0x00000010 +#define GL_TEXTURE_PROTECTED_EXT 0x8BFA +#endif /* GL_EXT_protected_textures */ + #ifndef GL_EXT_pvrtc_sRGB #define GL_EXT_pvrtc_sRGB 1 #define GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT 0x8A54 @@ -1495,6 +1673,53 @@ GL_APICALL void GL_APIENTRY glGetnUniformivEXT (GLuint program, GLint location, #define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 #endif /* GL_EXT_sRGB_write_control */ +#ifndef GL_EXT_semaphore +#define GL_EXT_semaphore 1 +#define GL_LAYOUT_GENERAL_EXT 0x958D +#define GL_LAYOUT_COLOR_ATTACHMENT_EXT 0x958E +#define GL_LAYOUT_DEPTH_STENCIL_ATTACHMENT_EXT 0x958F +#define GL_LAYOUT_DEPTH_STENCIL_READ_ONLY_EXT 0x9590 +#define GL_LAYOUT_SHADER_READ_ONLY_EXT 0x9591 +#define GL_LAYOUT_TRANSFER_SRC_EXT 0x9592 +#define GL_LAYOUT_TRANSFER_DST_EXT 0x9593 +typedef void (GL_APIENTRYP PFNGLGENSEMAPHORESEXTPROC) (GLsizei n, GLuint *semaphores); +typedef void (GL_APIENTRYP PFNGLDELETESEMAPHORESEXTPROC) (GLsizei n, const GLuint *semaphores); +typedef GLboolean (GL_APIENTRYP PFNGLISSEMAPHOREEXTPROC) (GLuint semaphore); +typedef void (GL_APIENTRYP PFNGLSEMAPHOREPARAMETERUI64VEXTPROC) (GLuint semaphore, GLenum pname, const GLuint64 *params); +typedef void (GL_APIENTRYP PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC) (GLuint semaphore, GLenum pname, GLuint64 *params); +typedef void (GL_APIENTRYP PFNGLWAITSEMAPHOREEXTPROC) (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *srcLayouts); +typedef void (GL_APIENTRYP PFNGLSIGNALSEMAPHOREEXTPROC) (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *dstLayouts); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGenSemaphoresEXT (GLsizei n, GLuint *semaphores); +GL_APICALL void GL_APIENTRY glDeleteSemaphoresEXT (GLsizei n, const GLuint *semaphores); +GL_APICALL GLboolean GL_APIENTRY glIsSemaphoreEXT (GLuint semaphore); +GL_APICALL void GL_APIENTRY glSemaphoreParameterui64vEXT (GLuint semaphore, GLenum pname, const GLuint64 *params); +GL_APICALL void GL_APIENTRY glGetSemaphoreParameterui64vEXT (GLuint semaphore, GLenum pname, GLuint64 *params); +GL_APICALL void GL_APIENTRY glWaitSemaphoreEXT (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *srcLayouts); +GL_APICALL void GL_APIENTRY glSignalSemaphoreEXT (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *dstLayouts); +#endif +#endif /* GL_EXT_semaphore */ + +#ifndef GL_EXT_semaphore_fd +#define GL_EXT_semaphore_fd 1 +typedef void (GL_APIENTRYP PFNGLIMPORTSEMAPHOREFDEXTPROC) (GLuint semaphore, GLenum handleType, GLint fd); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glImportSemaphoreFdEXT (GLuint semaphore, GLenum handleType, GLint fd); +#endif +#endif /* GL_EXT_semaphore_fd */ + +#ifndef GL_EXT_semaphore_win32 +#define GL_EXT_semaphore_win32 1 +#define GL_HANDLE_TYPE_D3D12_FENCE_EXT 0x9594 +#define GL_D3D12_FENCE_VALUE_EXT 0x9595 +typedef void (GL_APIENTRYP PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC) (GLuint semaphore, GLenum handleType, void *handle); +typedef void (GL_APIENTRYP PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC) (GLuint semaphore, GLenum handleType, const void *name); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glImportSemaphoreWin32HandleEXT (GLuint semaphore, GLenum handleType, void *handle); +GL_APICALL void GL_APIENTRY glImportSemaphoreWin32NameEXT (GLuint semaphore, GLenum handleType, const void *name); +#endif +#endif /* GL_EXT_semaphore_win32 */ + #ifndef GL_EXT_separate_shader_objects #define GL_EXT_separate_shader_objects 1 #define GL_ACTIVE_PROGRAM_EXT 0x8259 @@ -1600,6 +1825,10 @@ GL_APICALL void GL_APIENTRY glProgramUniformMatrix4x3fvEXT (GLuint program, GLin #define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52 #endif /* GL_EXT_shader_framebuffer_fetch */ +#ifndef GL_EXT_shader_group_vote +#define GL_EXT_shader_group_vote 1 +#endif /* GL_EXT_shader_group_vote */ + #ifndef GL_EXT_shader_implicit_conversions #define GL_EXT_shader_implicit_conversions 1 #endif /* GL_EXT_shader_implicit_conversions */ @@ -1612,6 +1841,10 @@ GL_APICALL void GL_APIENTRY glProgramUniformMatrix4x3fvEXT (GLuint program, GLin #define GL_EXT_shader_io_blocks 1 #endif /* GL_EXT_shader_io_blocks */ +#ifndef GL_EXT_shader_non_constant_global_initializers +#define GL_EXT_shader_non_constant_global_initializers 1 +#endif /* GL_EXT_shader_non_constant_global_initializers */ + #ifndef GL_EXT_shader_pixel_local_storage #define GL_EXT_shader_pixel_local_storage 1 #define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT 0x8F63 @@ -1619,6 +1852,21 @@ GL_APICALL void GL_APIENTRY glProgramUniformMatrix4x3fvEXT (GLuint program, GLin #define GL_SHADER_PIXEL_LOCAL_STORAGE_EXT 0x8F64 #endif /* GL_EXT_shader_pixel_local_storage */ +#ifndef GL_EXT_shader_pixel_local_storage2 +#define GL_EXT_shader_pixel_local_storage2 1 +#define GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_FAST_SIZE_EXT 0x9650 +#define GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_SIZE_EXT 0x9651 +#define GL_FRAMEBUFFER_INCOMPLETE_INSUFFICIENT_SHADER_COMBINED_LOCAL_STORAGE_EXT 0x9652 +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC) (GLuint target, GLsizei size); +typedef GLsizei (GL_APIENTRYP PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC) (GLuint target); +typedef void (GL_APIENTRYP PFNGLCLEARPIXELLOCALSTORAGEUIEXTPROC) (GLsizei offset, GLsizei n, const GLuint *values); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glFramebufferPixelLocalStorageSizeEXT (GLuint target, GLsizei size); +GL_APICALL GLsizei GL_APIENTRY glGetFramebufferPixelLocalStorageSizeEXT (GLuint target); +GL_APICALL void GL_APIENTRY glClearPixelLocalStorageuiEXT (GLsizei offset, GLsizei n, const GLuint *values); +#endif +#endif /* GL_EXT_shader_pixel_local_storage2 */ + #ifndef GL_EXT_shader_texture_lod #define GL_EXT_shader_texture_lod 1 #endif /* GL_EXT_shader_texture_lod */ @@ -1652,6 +1900,10 @@ GL_APICALL void GL_APIENTRY glTexPageCommitmentEXT (GLenum target, GLint level, #endif #endif /* GL_EXT_sparse_texture */ +#ifndef GL_EXT_sparse_texture2 +#define GL_EXT_sparse_texture2 1 +#endif /* GL_EXT_sparse_texture2 */ + #ifndef GL_EXT_tessellation_point_size #define GL_EXT_tessellation_point_size 1 #endif /* GL_EXT_tessellation_point_size */ @@ -1755,6 +2007,11 @@ GL_APICALL void GL_APIENTRY glTexBufferRangeEXT (GLenum target, GLenum internalf #endif #endif /* GL_EXT_texture_buffer */ +#ifndef GL_EXT_texture_compression_astc_decode_mode +#define GL_EXT_texture_compression_astc_decode_mode 1 +#define GL_TEXTURE_ASTC_DECODE_PRECISION_EXT 0x8F69 +#endif /* GL_EXT_texture_compression_astc_decode_mode */ + #ifndef GL_EXT_texture_compression_dxt1 #define GL_EXT_texture_compression_dxt1 1 #define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 @@ -1884,11 +2141,67 @@ GL_APICALL void GL_APIENTRY glTextureViewEXT (GLuint texture, GLenum target, GLu #define GL_UNPACK_SKIP_PIXELS_EXT 0x0CF4 #endif /* GL_EXT_unpack_subimage */ +#ifndef GL_EXT_win32_keyed_mutex +#define GL_EXT_win32_keyed_mutex 1 +typedef GLboolean (GL_APIENTRYP PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC) (GLuint memory, GLuint64 key, GLuint timeout); +typedef GLboolean (GL_APIENTRYP PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC) (GLuint memory, GLuint64 key); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL GLboolean GL_APIENTRY glAcquireKeyedMutexWin32EXT (GLuint memory, GLuint64 key, GLuint timeout); +GL_APICALL GLboolean GL_APIENTRY glReleaseKeyedMutexWin32EXT (GLuint memory, GLuint64 key); +#endif +#endif /* GL_EXT_win32_keyed_mutex */ + +#ifndef GL_EXT_window_rectangles +#define GL_EXT_window_rectangles 1 +#define GL_INCLUSIVE_EXT 0x8F10 +#define GL_EXCLUSIVE_EXT 0x8F11 +#define GL_WINDOW_RECTANGLE_EXT 0x8F12 +#define GL_WINDOW_RECTANGLE_MODE_EXT 0x8F13 +#define GL_MAX_WINDOW_RECTANGLES_EXT 0x8F14 +#define GL_NUM_WINDOW_RECTANGLES_EXT 0x8F15 +typedef void (GL_APIENTRYP PFNGLWINDOWRECTANGLESEXTPROC) (GLenum mode, GLsizei count, const GLint *box); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glWindowRectanglesEXT (GLenum mode, GLsizei count, const GLint *box); +#endif +#endif /* GL_EXT_window_rectangles */ + #ifndef GL_FJ_shader_binary_GCCSO #define GL_FJ_shader_binary_GCCSO 1 #define GL_GCCSO_SHADER_BINARY_FJ 0x9260 #endif /* GL_FJ_shader_binary_GCCSO */ +#ifndef GL_IMG_bindless_texture +#define GL_IMG_bindless_texture 1 +typedef GLuint64 (GL_APIENTRYP PFNGLGETTEXTUREHANDLEIMGPROC) (GLuint texture); +typedef GLuint64 (GL_APIENTRYP PFNGLGETTEXTURESAMPLERHANDLEIMGPROC) (GLuint texture, GLuint sampler); +typedef void (GL_APIENTRYP PFNGLUNIFORMHANDLEUI64IMGPROC) (GLint location, GLuint64 value); +typedef void (GL_APIENTRYP PFNGLUNIFORMHANDLEUI64VIMGPROC) (GLint location, GLsizei count, const GLuint64 *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64IMGPROC) (GLuint program, GLint location, GLuint64 value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64VIMGPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *values); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL GLuint64 GL_APIENTRY glGetTextureHandleIMG (GLuint texture); +GL_APICALL GLuint64 GL_APIENTRY glGetTextureSamplerHandleIMG (GLuint texture, GLuint sampler); +GL_APICALL void GL_APIENTRY glUniformHandleui64IMG (GLint location, GLuint64 value); +GL_APICALL void GL_APIENTRY glUniformHandleui64vIMG (GLint location, GLsizei count, const GLuint64 *value); +GL_APICALL void GL_APIENTRY glProgramUniformHandleui64IMG (GLuint program, GLint location, GLuint64 value); +GL_APICALL void GL_APIENTRY glProgramUniformHandleui64vIMG (GLuint program, GLint location, GLsizei count, const GLuint64 *values); +#endif +#endif /* GL_IMG_bindless_texture */ + +#ifndef GL_IMG_framebuffer_downsample +#define GL_IMG_framebuffer_downsample 1 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_AND_DOWNSAMPLE_IMG 0x913C +#define GL_NUM_DOWNSAMPLE_SCALES_IMG 0x913D +#define GL_DOWNSAMPLE_SCALES_IMG 0x913E +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SCALE_IMG 0x913F +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DDOWNSAMPLEIMGPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint xscale, GLint yscale); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERDOWNSAMPLEIMGPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer, GLint xscale, GLint yscale); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glFramebufferTexture2DDownsampleIMG (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint xscale, GLint yscale); +GL_APICALL void GL_APIENTRY glFramebufferTextureLayerDownsampleIMG (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer, GLint xscale, GLint yscale); +#endif +#endif /* GL_IMG_framebuffer_downsample */ + #ifndef GL_IMG_multisampled_render_to_texture #define GL_IMG_multisampled_render_to_texture 1 #define GL_RENDERBUFFER_SAMPLES_IMG 0x9133 @@ -1933,6 +2246,18 @@ GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleIMG (GLenum target, #define GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG 0x9138 #endif /* GL_IMG_texture_compression_pvrtc2 */ +#ifndef GL_IMG_texture_filter_cubic +#define GL_IMG_texture_filter_cubic 1 +#define GL_CUBIC_IMG 0x9139 +#define GL_CUBIC_MIPMAP_NEAREST_IMG 0x913A +#define GL_CUBIC_MIPMAP_LINEAR_IMG 0x913B +#endif /* GL_IMG_texture_filter_cubic */ + +#ifndef GL_INTEL_conservative_rasterization +#define GL_INTEL_conservative_rasterization 1 +#define GL_CONSERVATIVE_RASTERIZATION_INTEL 0x83FE +#endif /* GL_INTEL_conservative_rasterization */ + #ifndef GL_INTEL_framebuffer_CMAA #define GL_INTEL_framebuffer_CMAA 1 typedef void (GL_APIENTRYP PFNGLAPPLYFRAMEBUFFERATTACHMENTCMAAINTELPROC) (void); @@ -1987,6 +2312,14 @@ GL_APICALL void GL_APIENTRY glGetPerfQueryInfoINTEL (GLuint queryId, GLuint quer #endif #endif /* GL_INTEL_performance_query */ +#ifndef GL_MESA_shader_integer_functions +#define GL_MESA_shader_integer_functions 1 +#endif /* GL_MESA_shader_integer_functions */ + +#ifndef GL_NVX_blend_equation_advanced_multi_draw_buffers +#define GL_NVX_blend_equation_advanced_multi_draw_buffers 1 +#endif /* GL_NVX_blend_equation_advanced_multi_draw_buffers */ + #ifndef GL_NV_bindless_texture #define GL_NV_bindless_texture 1 typedef GLuint64 (GL_APIENTRYP PFNGLGETTEXTUREHANDLENVPROC) (GLuint texture); @@ -2109,6 +2442,17 @@ GL_APICALL void GL_APIENTRY glSubpixelPrecisionBiasNV (GLuint xbits, GLuint ybit #endif #endif /* GL_NV_conservative_raster */ +#ifndef GL_NV_conservative_raster_pre_snap_triangles +#define GL_NV_conservative_raster_pre_snap_triangles 1 +#define GL_CONSERVATIVE_RASTER_MODE_NV 0x954D +#define GL_CONSERVATIVE_RASTER_MODE_POST_SNAP_NV 0x954E +#define GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_TRIANGLES_NV 0x954F +typedef void (GL_APIENTRYP PFNGLCONSERVATIVERASTERPARAMETERINVPROC) (GLenum pname, GLint param); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glConservativeRasterParameteriNV (GLenum pname, GLint param); +#endif +#endif /* GL_NV_conservative_raster_pre_snap_triangles */ + #ifndef GL_NV_copy_buffer #define GL_NV_copy_buffer 1 #define GL_COPY_READ_BUFFER_NV 0x8F36 @@ -2194,6 +2538,23 @@ GL_APICALL void GL_APIENTRY glDrawElementsInstancedNV (GLenum mode, GLsizei coun #endif #endif /* GL_NV_draw_instanced */ +#ifndef GL_NV_draw_vulkan_image +#define GL_NV_draw_vulkan_image 1 +typedef void (GL_APIENTRY *GLVULKANPROCNV)(void); +typedef void (GL_APIENTRYP PFNGLDRAWVKIMAGENVPROC) (GLuint64 vkImage, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); +typedef GLVULKANPROCNV (GL_APIENTRYP PFNGLGETVKPROCADDRNVPROC) (const GLchar *name); +typedef void (GL_APIENTRYP PFNGLWAITVKSEMAPHORENVPROC) (GLuint64 vkSemaphore); +typedef void (GL_APIENTRYP PFNGLSIGNALVKSEMAPHORENVPROC) (GLuint64 vkSemaphore); +typedef void (GL_APIENTRYP PFNGLSIGNALVKFENCENVPROC) (GLuint64 vkFence); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawVkImageNV (GLuint64 vkImage, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); +GL_APICALL GLVULKANPROCNV GL_APIENTRY glGetVkProcAddrNV (const GLchar *name); +GL_APICALL void GL_APIENTRY glWaitVkSemaphoreNV (GLuint64 vkSemaphore); +GL_APICALL void GL_APIENTRY glSignalVkSemaphoreNV (GLuint64 vkSemaphore); +GL_APICALL void GL_APIENTRY glSignalVkFenceNV (GLuint64 vkFence); +#endif +#endif /* GL_NV_draw_vulkan_image */ + #ifndef GL_NV_explicit_attrib_location #define GL_NV_explicit_attrib_location 1 #endif /* GL_NV_explicit_attrib_location */ @@ -2296,6 +2657,109 @@ GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleNV (GLenum target, G #define GL_NV_geometry_shader_passthrough 1 #endif /* GL_NV_geometry_shader_passthrough */ +#ifndef GL_NV_gpu_shader5 +#define GL_NV_gpu_shader5 1 +typedef khronos_int64_t GLint64EXT; +typedef khronos_uint64_t GLuint64EXT; +#define GL_INT64_NV 0x140E +#define GL_UNSIGNED_INT64_NV 0x140F +#define GL_INT8_NV 0x8FE0 +#define GL_INT8_VEC2_NV 0x8FE1 +#define GL_INT8_VEC3_NV 0x8FE2 +#define GL_INT8_VEC4_NV 0x8FE3 +#define GL_INT16_NV 0x8FE4 +#define GL_INT16_VEC2_NV 0x8FE5 +#define GL_INT16_VEC3_NV 0x8FE6 +#define GL_INT16_VEC4_NV 0x8FE7 +#define GL_INT64_VEC2_NV 0x8FE9 +#define GL_INT64_VEC3_NV 0x8FEA +#define GL_INT64_VEC4_NV 0x8FEB +#define GL_UNSIGNED_INT8_NV 0x8FEC +#define GL_UNSIGNED_INT8_VEC2_NV 0x8FED +#define GL_UNSIGNED_INT8_VEC3_NV 0x8FEE +#define GL_UNSIGNED_INT8_VEC4_NV 0x8FEF +#define GL_UNSIGNED_INT16_NV 0x8FF0 +#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1 +#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2 +#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3 +#define GL_UNSIGNED_INT64_VEC2_NV 0x8FF5 +#define GL_UNSIGNED_INT64_VEC3_NV 0x8FF6 +#define GL_UNSIGNED_INT64_VEC4_NV 0x8FF7 +#define GL_FLOAT16_NV 0x8FF8 +#define GL_FLOAT16_VEC2_NV 0x8FF9 +#define GL_FLOAT16_VEC3_NV 0x8FFA +#define GL_FLOAT16_VEC4_NV 0x8FFB +#define GL_PATCHES 0x000E +typedef void (GL_APIENTRYP PFNGLUNIFORM1I64NVPROC) (GLint location, GLint64EXT x); +typedef void (GL_APIENTRYP PFNGLUNIFORM2I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y); +typedef void (GL_APIENTRYP PFNGLUNIFORM3I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (GL_APIENTRYP PFNGLUNIFORM4I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (GL_APIENTRYP PFNGLUNIFORM1I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM2I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM3I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM4I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM1UI64NVPROC) (GLint location, GLuint64EXT x); +typedef void (GL_APIENTRYP PFNGLUNIFORM2UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y); +typedef void (GL_APIENTRYP PFNGLUNIFORM3UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (GL_APIENTRYP PFNGLUNIFORM4UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (GL_APIENTRYP PFNGLUNIFORM1UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM2UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM3UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM4UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (GL_APIENTRYP PFNGLGETUNIFORMI64VNVPROC) (GLuint program, GLint location, GLint64EXT *params); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1I64NVPROC) (GLuint program, GLint location, GLint64EXT x); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glUniform1i64NV (GLint location, GLint64EXT x); +GL_APICALL void GL_APIENTRY glUniform2i64NV (GLint location, GLint64EXT x, GLint64EXT y); +GL_APICALL void GL_APIENTRY glUniform3i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +GL_APICALL void GL_APIENTRY glUniform4i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +GL_APICALL void GL_APIENTRY glUniform1i64vNV (GLint location, GLsizei count, const GLint64EXT *value); +GL_APICALL void GL_APIENTRY glUniform2i64vNV (GLint location, GLsizei count, const GLint64EXT *value); +GL_APICALL void GL_APIENTRY glUniform3i64vNV (GLint location, GLsizei count, const GLint64EXT *value); +GL_APICALL void GL_APIENTRY glUniform4i64vNV (GLint location, GLsizei count, const GLint64EXT *value); +GL_APICALL void GL_APIENTRY glUniform1ui64NV (GLint location, GLuint64EXT x); +GL_APICALL void GL_APIENTRY glUniform2ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y); +GL_APICALL void GL_APIENTRY glUniform3ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +GL_APICALL void GL_APIENTRY glUniform4ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +GL_APICALL void GL_APIENTRY glUniform1ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); +GL_APICALL void GL_APIENTRY glUniform2ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); +GL_APICALL void GL_APIENTRY glUniform3ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); +GL_APICALL void GL_APIENTRY glUniform4ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); +GL_APICALL void GL_APIENTRY glGetUniformi64vNV (GLuint program, GLint location, GLint64EXT *params); +GL_APICALL void GL_APIENTRY glProgramUniform1i64NV (GLuint program, GLint location, GLint64EXT x); +GL_APICALL void GL_APIENTRY glProgramUniform2i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y); +GL_APICALL void GL_APIENTRY glProgramUniform3i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +GL_APICALL void GL_APIENTRY glProgramUniform4i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +GL_APICALL void GL_APIENTRY glProgramUniform1i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +GL_APICALL void GL_APIENTRY glProgramUniform2i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +GL_APICALL void GL_APIENTRY glProgramUniform3i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +GL_APICALL void GL_APIENTRY glProgramUniform4i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +GL_APICALL void GL_APIENTRY glProgramUniform1ui64NV (GLuint program, GLint location, GLuint64EXT x); +GL_APICALL void GL_APIENTRY glProgramUniform2ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y); +GL_APICALL void GL_APIENTRY glProgramUniform3ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +GL_APICALL void GL_APIENTRY glProgramUniform4ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +GL_APICALL void GL_APIENTRY glProgramUniform1ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +GL_APICALL void GL_APIENTRY glProgramUniform2ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +GL_APICALL void GL_APIENTRY glProgramUniform3ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +GL_APICALL void GL_APIENTRY glProgramUniform4ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +#endif +#endif /* GL_NV_gpu_shader5 */ + #ifndef GL_NV_image_formats #define GL_NV_image_formats 1 #endif /* GL_NV_image_formats */ @@ -2702,6 +3166,10 @@ GL_APICALL void GL_APIENTRY glResolveDepthValuesNV (void); #define GL_NV_sample_mask_override_coverage 1 #endif /* GL_NV_sample_mask_override_coverage */ +#ifndef GL_NV_shader_atomic_fp16_vector +#define GL_NV_shader_atomic_fp16_vector 1 +#endif /* GL_NV_shader_atomic_fp16_vector */ + #ifndef GL_NV_shader_noperspective_interpolation #define GL_NV_shader_noperspective_interpolation 1 #endif /* GL_NV_shader_noperspective_interpolation */ @@ -2768,11 +3236,32 @@ GL_APICALL GLboolean GL_APIENTRY glIsEnablediNV (GLenum target, GLuint index); #define GL_NV_viewport_array2 1 #endif /* GL_NV_viewport_array2 */ +#ifndef GL_NV_viewport_swizzle +#define GL_NV_viewport_swizzle 1 +#define GL_VIEWPORT_SWIZZLE_POSITIVE_X_NV 0x9350 +#define GL_VIEWPORT_SWIZZLE_NEGATIVE_X_NV 0x9351 +#define GL_VIEWPORT_SWIZZLE_POSITIVE_Y_NV 0x9352 +#define GL_VIEWPORT_SWIZZLE_NEGATIVE_Y_NV 0x9353 +#define GL_VIEWPORT_SWIZZLE_POSITIVE_Z_NV 0x9354 +#define GL_VIEWPORT_SWIZZLE_NEGATIVE_Z_NV 0x9355 +#define GL_VIEWPORT_SWIZZLE_POSITIVE_W_NV 0x9356 +#define GL_VIEWPORT_SWIZZLE_NEGATIVE_W_NV 0x9357 +#define GL_VIEWPORT_SWIZZLE_X_NV 0x9358 +#define GL_VIEWPORT_SWIZZLE_Y_NV 0x9359 +#define GL_VIEWPORT_SWIZZLE_Z_NV 0x935A +#define GL_VIEWPORT_SWIZZLE_W_NV 0x935B +typedef void (GL_APIENTRYP PFNGLVIEWPORTSWIZZLENVPROC) (GLuint index, GLenum swizzlex, GLenum swizzley, GLenum swizzlez, GLenum swizzlew); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glViewportSwizzleNV (GLuint index, GLenum swizzlex, GLenum swizzley, GLenum swizzlez, GLenum swizzlew); +#endif +#endif /* GL_NV_viewport_swizzle */ + #ifndef GL_OVR_multiview #define GL_OVR_multiview 1 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR 0x9630 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR 0x9632 #define GL_MAX_VIEWS_OVR 0x9631 +#define GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR 0x9633 typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glFramebufferTextureMultiviewOVR (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); @@ -2783,6 +3272,14 @@ GL_APICALL void GL_APIENTRY glFramebufferTextureMultiviewOVR (GLenum target, GLe #define GL_OVR_multiview2 1 #endif /* GL_OVR_multiview2 */ +#ifndef GL_OVR_multiview_multisampled_render_to_texture +#define GL_OVR_multiview_multisampled_render_to_texture 1 +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLsizei samples, GLint baseViewIndex, GLsizei numViews); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glFramebufferTextureMultisampleMultiviewOVR (GLenum target, GLenum attachment, GLuint texture, GLint level, GLsizei samples, GLint baseViewIndex, GLsizei numViews); +#endif +#endif /* GL_OVR_multiview_multisampled_render_to_texture */ + #ifndef GL_QCOM_alpha_test #define GL_QCOM_alpha_test 1 #define GL_ALPHA_TEST_QCOM 0x0BC0 @@ -2863,11 +3360,32 @@ GL_APICALL void GL_APIENTRY glExtGetProgramBinarySourceQCOM (GLuint program, GLe #endif #endif /* GL_QCOM_extended_get2 */ +#ifndef GL_QCOM_framebuffer_foveated +#define GL_QCOM_framebuffer_foveated 1 +#define GL_FOVEATION_ENABLE_BIT_QCOM 0x00000001 +#define GL_FOVEATION_SCALED_BIN_METHOD_BIT_QCOM 0x00000002 +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERFOVEATIONCONFIGQCOMPROC) (GLuint framebuffer, GLuint numLayers, GLuint focalPointsPerLayer, GLuint requestedFeatures, GLuint *providedFeatures); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERFOVEATIONPARAMETERSQCOMPROC) (GLuint framebuffer, GLuint layer, GLuint focalPoint, GLfloat focalX, GLfloat focalY, GLfloat gainX, GLfloat gainY, GLfloat foveaArea); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glFramebufferFoveationConfigQCOM (GLuint framebuffer, GLuint numLayers, GLuint focalPointsPerLayer, GLuint requestedFeatures, GLuint *providedFeatures); +GL_APICALL void GL_APIENTRY glFramebufferFoveationParametersQCOM (GLuint framebuffer, GLuint layer, GLuint focalPoint, GLfloat focalX, GLfloat focalY, GLfloat gainX, GLfloat gainY, GLfloat foveaArea); +#endif +#endif /* GL_QCOM_framebuffer_foveated */ + #ifndef GL_QCOM_perfmon_global_mode #define GL_QCOM_perfmon_global_mode 1 #define GL_PERFMON_GLOBAL_MODE_QCOM 0x8FA0 #endif /* GL_QCOM_perfmon_global_mode */ +#ifndef GL_QCOM_shader_framebuffer_fetch_noncoherent +#define GL_QCOM_shader_framebuffer_fetch_noncoherent 1 +#define GL_FRAMEBUFFER_FETCH_NONCOHERENT_QCOM 0x96A2 +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERFETCHBARRIERQCOMPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glFramebufferFetchBarrierQCOM (void); +#endif +#endif /* GL_QCOM_shader_framebuffer_fetch_noncoherent */ + #ifndef GL_QCOM_tiled_rendering #define GL_QCOM_tiled_rendering 1 #define GL_COLOR_BUFFER_BIT0_QCOM 0x00000001 @@ -2920,20 +3438,8 @@ GL_APICALL void GL_APIENTRY glEndTilingQCOM (GLbitfield preserveMask); #define GL_SHADER_BINARY_VIV 0x8FC4 #endif /* GL_VIV_shader_binary */ -#ifndef GL_ANGLE_lossy_etc_decode -#define GL_ANGLE_lossy_etc_decode 1 -#define GL_ETC1_RGB8_LOSSY_DECODE_ANGLE 0x9690 -#define GL_COMPRESSED_R11_LOSSY_DECODE_EAC_ANGLE 0x9691 -#define GL_COMPRESSED_SIGNED_R11_LOSSY_DECODE_EAC_ANGLE 0x9692 -#define GL_COMPRESSED_RG11_LOSSY_DECODE_EAC_ANGLE 0x9693 -#define GL_COMPRESSED_SIGNED_RG11_LOSSY_DECODE_EAC_ANGLE 0x9694 -#define GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE 0x9695 -#define GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE 0x9696 -#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE 0x9697 -#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE 0x9698 -#define GL_COMPRESSED_RGBA8_LOSSY_DECODE_ETC2_EAC_ANGLE 0x9699 -#define GL_COMPRESSED_SRGB8_ALPHA8_LOSSY_DECODE_ETC2_EAC_ANGLE 0x969A -#endif /* GL_ANGLE_lossy_etc_decode */ +/* ANGLE GLES2 extensions */ +#include "gl2ext_angle.h" #ifdef __cplusplus } diff --git a/src/3rdparty/angle/include/GLES2/gl2ext_angle.h b/src/3rdparty/angle/include/GLES2/gl2ext_angle.h new file mode 100644 index 0000000000..fc5a4bf35d --- /dev/null +++ b/src/3rdparty/angle/include/GLES2/gl2ext_angle.h @@ -0,0 +1,551 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// gl2ext_angle.h: ANGLE modifications to the gl2ext.h header file. +// Currently we don't include this file directly, we patch gl2ext.h +// to include it implicitly so it is visible throughout our code. + +#ifndef INCLUDE_GLES2_GL2EXT_ANGLE_H_ +#define INCLUDE_GLES2_GL2EXT_ANGLE_H_ + +// clang-format off + +#ifndef GL_ANGLE_client_arrays +#define GL_ANGLE_client_arrays 1 +#define GL_CLIENT_ARRAYS_ANGLE 0x93AA +#endif /* GL_ANGLE_client_arrays */ + +#ifndef GL_ANGLE_request_extension +#define GL_ANGLE_request_extension 1 +#define GL_REQUESTABLE_EXTENSIONS_ANGLE 0x93A8 +#define GL_NUM_REQUESTABLE_EXTENSIONS_ANGLE 0x93A8 +typedef void (GL_APIENTRYP PFNGLREQUESTEXTENSIONANGLEPROC) (const GLchar *name); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRequestExtensionANGLE (const GLchar *name); +#endif +#endif /* GL_ANGLE_webgl_compatibility */ + +#ifndef GL_ANGLE_robust_resource_initialization +#define GL_ANGLE_robust_resource_initialization 1 +#define GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE 0x93AB +#endif /* GL_ANGLE_robust_resource_initialization */ + +#ifndef GL_CHROMIUM_framebuffer_mixed_samples +#define GL_CHROMIUM_frambuffer_mixed_samples 1 +#define GL_COVERAGE_MODULATION_CHROMIUM 0x9332 +typedef void (GL_APIENTRYP PFNGLCOVERAGEMODULATIONCHROMIUMPROC) (GLenum components); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glCoverageModulationCHROMIUM(GLenum components); +#endif +#endif /* GL_CHROMIUM_framebuffer_mixed_samples */ + +#ifndef GL_CHROMIUM_bind_generates_resource +#define GL_CHROMIUM_bind_generates_resource 1 +#define GL_BIND_GENERATES_RESOURCE_CHROMIUM 0x9244 +#endif /* GL_CHROMIUM_bind_generates_resource */ + +// needed by NV_path_rendering (and thus CHROMIUM_path_rendering) +// but CHROMIUM_path_rendering only needs MatrixLoadfEXT, MatrixLoadIdentityEXT +#ifndef GL_EXT_direct_state_access +#define GL_EXT_direct_state_access 1 +typedef void(GL_APIENTRYP PFNGLMATRIXLOADFEXTPROC)(GLenum matrixMode, const GLfloat *m); +typedef void(GL_APIENTRYP PFNGLMATRIXLOADIDENTITYEXTPROC)(GLenum matrixMode); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glMatrixLoadfEXT(GLenum matrixMode, const GLfloat *m); +GL_APICALL void GL_APIENTRY glMatrixLoadIdentityEXT(GLenum matrixMode); +#endif +#endif /* GL_EXT_direct_state_access */ + +#ifndef GL_CHROMIUM_path_rendering +#define GL_CHROMIUM_path_rendering 1 +#define GL_PATH_MODELVIEW_CHROMIUM 0x1700 +#define GL_PATH_PROJECTION_CHROMIUM 0x1701 +#define GL_CLOSE_PATH_CHROMIUM 0x00 +#define GL_MOVE_TO_CHROMIUM 0x02 +#define GL_LINE_TO_CHROMIUM 0x04 +#define GL_QUADRATIC_CURVE_TO_CHROMIUM 0x0A +#define GL_CUBIC_CURVE_TO_CHROMIUM 0x0C +#define GL_CONIC_CURVE_TO_CHROMIUM 0x1A +#define GL_PATH_MODELVIEW_MATRIX_CHROMIUM 0x0BA6 +#define GL_PATH_PROJECTION_MATRIX_CHROMIUM 0x0BA7 +#define GL_PATH_STROKE_WIDTH_CHROMIUM 0x9075 +#define GL_PATH_END_CAPS_CHROMIUM 0x9076 +#define GL_PATH_JOIN_STYLE_CHROMIUM 0x9079 +#define GL_PATH_MITER_LIMIT_CHROMIUM 0x907a +#define GL_PATH_STROKE_BOUND_CHROMIUM 0x9086 +#define GL_FLAT_CHROMIUM 0x1D00 +#define GL_SQUARE_CHROMIUM 0x90a3 +#define GL_ROUND_CHROMIUM 0x90a4 +#define GL_BEVEL_CHROMIUM 0x90A6 +#define GL_MITER_REVERT_CHROMIUM 0x90A7 +#define GL_COUNT_UP_CHROMIUM 0x9088 +#define GL_COUNT_DOWN_CHROMIUM 0x9089 +#define GL_CONVEX_HULL_CHROMIUM 0x908B +#define GL_BOUNDING_BOX_CHROMIUM 0x908D +#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM 0x909C +#define GL_EYE_LINEAR_CHROMIUM 0x2400 +#define GL_OBJECT_LINEAR_CHROMIUM 0x2401 +#define GL_CONSTANT_CHROMIUM 0x8576 +#define GL_TRANSLATE_X_CHROMIUM 0x908E +#define GL_TRANSLATE_Y_CHROMIUM 0x908F +#define GL_TRANSLATE_2D_CHROMIUM 0x9090 +#define GL_TRANSLATE_3D_CHROMIUM 0x9091 +#define GL_AFFINE_2D_CHROMIUM 0x9092 +#define GL_AFFINE_3D_CHROMIUM 0x9094 +#define GL_TRANSPOSE_AFFINE_2D_CHROMIUM 0x9096 +#define GL_TRANSPOSE_AFFINE_3D_CHROMIUM 0x9098 +typedef void(GL_APIENTRYP PFNGLMATRIXLOADFCHROMIUMPROC)(GLenum matrixMode, const GLfloat *m); +typedef void(GL_APIENTRYP PFNGLMATRIXLOADIDENTITYCHROMIUMPROC)(GLenum matrixMode); +typedef GLuint(GL_APIENTRYP PFNGLGENPATHSCHROMIUMPROC)(GLsizei range); +typedef void(GL_APIENTRYP PFNGLDELETEPATHSCHROMIUMPROC)(GLuint path, GLsizei range); +typedef GLboolean(GL_APIENTRYP PFNGLISPATHCHROMIUMPROC)(GLuint path); +typedef void(GL_APIENTRYP PFNGLPATHCOMMANDSCHROMIUMPROC)(GLuint path, + GLsizei numCommands, + const GLubyte *commands, + GLsizei numCoords, + GLenum coordType, + const void *coords); +typedef void(GL_APIENTRYP PFNGLPATHPARAMETERICHROMIUMPROC)(GLuint path, GLenum pname, GLint value); +typedef void(GL_APIENTRYP PFNGLPATHPARAMETERFCHROMIUMPROC)(GLuint path, + GLenum pname, + GLfloat value); +typedef void(GL_APIENTRYP PFNGLGETPATHPARAMETERIVCHROMIUMPROC)(GLuint path, + GLenum pname, + GLint *value); +typedef void(GL_APIENTRYP PFNGLGETPATHPARAMETERFVCHROMIUMPROC)(GLuint path, + GLenum pname, + GLfloat *value); +typedef void(GL_APIENTRYP PFNGLPATHSTENCILFUNCCHROMIUMPROC)(GLenum func, GLint ref, GLuint mask); +typedef void(GL_APIENTRYP PFNGLSTENCILFILLPATHCHROMIUMPROC)(GLuint path, + GLenum fillMode, + GLuint mask); +typedef void(GL_APIENTRYP PFNGLSTENCILSTROKEPATHCHROMIUMPROC)(GLuint path, + GLint reference, + GLuint mask); +typedef void(GL_APIENTRYP PFNGLCOVERFILLPATHCHROMIUMPROC)(GLuint path, GLenum coverMode); +typedef void(GL_APIENTRYP PFNGLCOVERSTROKEPATHCHROMIUMPROC)(GLuint path, GLenum coverMode); +typedef void(GL_APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHCHROMIUMPROC)(GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode); +typedef void(GL_APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHCHROMIUMPROC)(GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode); +typedef void(GL_APIENTRYP PFNGLCOVERFILLPATHINSTANCEDCHROMIUMPROC)(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); +typedef void(GL_APIENTRYP PFNGLCOVERSTROKEPATHINSTANCEDCHROMIUMPROC)( + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); +typedef void(GL_APIENTRYP PFNGLSTENCILFILLPATHINSTANCEDCHROMIUMPROC)( + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); +typedef void(GL_APIENTRYP PFNGLSTENCILSTROKEPATHINSTANCEDCHROMIUMPROC)( + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); +typedef void(GL_APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDCHROMIUMPROC)( + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); +typedef void(GL_APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDCHROMIUMPROC)( + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); + +typedef void(GL_APIENTRY PFNGLBINDFRAGMENTINPUTLOCATIONCHROMIUMPROC)(GLuint program, + GLint location, + const GLchar *name); +typedef void(GL_APIENTRYP PFNGLPROGRAMPATHFRAGMENTINPUTGENCHROMIUMPROC)(GLuint program, + GLint location, + GLenum genMode, + GLint components, + const GLfloat *coeffs); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glMatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat *m); +GL_APICALL void GL_APIENTRY glMatrixLoadIdentityCHROMIUM(GLenum matrixMode); +GL_APICALL GLuint GL_APIENTRY glGenPathsCHROMIUM(GLsizei range); +GL_APICALL void GL_APIENTRY glDeletePathsCHROMIUM(GLuint path, GLsizei range); +GL_APICALL GLboolean GL_APIENTRY glIsPathCHROMIUM(GLuint path); +GL_APICALL void GL_APIENTRY glPathCommandsCHROMIUM(GLuint path, + GLsizei numCommands, + const GLubyte *commands, + GLsizei numCoords, + GLenum coordType, + const void *coords); +GL_APICALL void GL_APIENTRY glPathParameteriCHROMIUM(GLuint path, GLenum pname, GLint value); +GL_APICALL void GL_APIENTRY glPathParameterfCHROMIUM(GLuint path, GLenum pname, GLfloat value); +GL_APICALL void GL_APIENTRY glGetPathParameterivCHROMIUM(GLuint path, GLenum pname, GLint *value); +GL_APICALL void GL_APIENTRY glGetPathParameterfvCHROMIUM(GLuint path, GLenum pname, GLfloat *value); +GL_APICALL void GL_APIENTRY glPathStencilFuncCHROMIUM(GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilFillPathCHROMIUM(GLuint path, GLenum fillMode, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilStrokePathCHROMIUM(GLuint path, GLint reference, GLuint mask); +GL_APICALL void GL_APIENTRY glCoverFillPathCHROMIUM(GLuint path, GLenum coverMode); +GL_APICALL void GL_APIENTRY glCoverStrokePathCHROMIUM(GLuint path, GLenum coverMode); +GL_APICALL void GL_APIENTRY glStencilThenCoverFillPathCHROMIUM(GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode); +GL_APICALL void GL_APIENTRY glStencilThenCoverStrokePathCHROMIUM(GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode); +GL_APICALL void GL_APIENTRY glCoverFillPathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); +GL_APICALL void GL_APIENTRY glCoverStrokePathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); +GL_APICALL void GL_APIENTRY glStencilFillPathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); +GL_APICALL void GL_APIENTRY glStencilStrokePathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); +GL_APICALL void GL_APIENTRY +glStencilThenCoverFillPathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); + +GL_APICALL void GL_APIENTRY +glStencilThenCoverStrokePathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); + +GL_APICALL void GL_APIENTRY glBindFragmentInputLocationCHROMIUM(GLuint program, + GLint location, + const GLchar *name); +GL_APICALL void GL_APIENTRY glProgramPathFragmentInputGenCHROMIUM(GLuint program, + GLint location, + GLenum genMode, + GLint components, + const GLfloat *coeffs); + +#endif +#endif /* GL_CHROMIUM_path_rendering */ + +#ifndef GL_CHROMIUM_copy_texture +#define GL_CHROMIUM_copy_texture 1 +typedef void(GL_APIENTRYP PFNGLCOPYTEXTURECHROMIUMPROC)(GLuint sourceId, + GLint sourceLevel, + GLenum destTarget, + GLuint destId, + GLint destLevel, + GLint internalFormat, + GLenum destType, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha); +typedef void(GL_APIENTRYP PFNGLCOPYSUBTEXTURECHROMIUMPROC)(GLuint sourceId, + GLint sourceLevel, + GLenum destTarget, + GLuint destId, + GLint destLevel, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glCopyTextureCHROMIUM(GLuint sourceId, + GLint sourceLevel, + GLenum destTarget, + GLuint destId, + GLint destLevel, + GLint internalFormat, + GLenum destType, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha); +GL_APICALL void GL_APIENTRY glCopySubTextureCHROMIUM(GLuint sourceId, + GLint sourceLevel, + GLenum destTarget, + GLuint destId, + GLint destLevel, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha); +#endif +#endif /* GL_CHROMIUM_copy_texture */ + +#ifndef GL_CHROMIUM_compressed_copy_texture +#define GL_CHROMIUM_compressed_copy_texture 1 +typedef void(GL_APIENTRYP PFNGLCOMPRESSEDCOPYTEXTURECHROMIUMPROC)(GLuint sourceId, GLuint destId); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glCompressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId); +#endif +#endif /* GL_CHROMIUM_compressed_copy_texture */ + +#ifndef GL_CHROMIUM_sync_query +#define GL_CHROMIUM_sync_query 1 +#define GL_COMMANDS_COMPLETED_CHROMIUM 0x84F7 +#endif /* GL_CHROMIUM_sync_query */ + +#ifndef GL_EXT_texture_compression_s3tc_srgb +#define GL_EXT_texture_compression_s3tc_srgb 1 +#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F +#endif /* GL_EXT_texture_compression_s3tc_srgb */ + +#ifndef GL_ANGLE_lossy_etc_decode +#define GL_ANGLE_lossy_etc_decode 1 +#define GL_ETC1_RGB8_LOSSY_DECODE_ANGLE 0x9690 +#define GL_COMPRESSED_R11_LOSSY_DECODE_EAC_ANGLE 0x9691 +#define GL_COMPRESSED_SIGNED_R11_LOSSY_DECODE_EAC_ANGLE 0x9692 +#define GL_COMPRESSED_RG11_LOSSY_DECODE_EAC_ANGLE 0x9693 +#define GL_COMPRESSED_SIGNED_RG11_LOSSY_DECODE_EAC_ANGLE 0x9694 +#define GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE 0x9695 +#define GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE 0x9696 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE 0x9697 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE 0x9698 +#define GL_COMPRESSED_RGBA8_LOSSY_DECODE_ETC2_EAC_ANGLE 0x9699 +#define GL_COMPRESSED_SRGB8_ALPHA8_LOSSY_DECODE_ETC2_EAC_ANGLE 0x969A +#endif /* GL_ANGLE_lossy_etc_decode */ + +#ifndef GL_ANGLE_robust_client_memory +#define GL_ANGLE_robust_client_memory 1 +typedef void (GL_APIENTRYP PFNGLGETBOOLEANVROBUSTANGLE) (GLenum pname, GLsizei bufSize, GLsizei *length, GLboolean *data); +typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETFLOATVROBUSTANGLE) (GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *data); +typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVROBUSTANGLE) (GLenum target, GLenum attachment, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETINTEGERVROBUSTANGLE) (GLenum pname, GLsizei bufSize, GLsizei *length, GLint *data); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMIVROBUSTANGLE) (GLuint program, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETSHADERIVROBUSTANGLE) (GLuint shader, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERFVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETUNIFORMFVROBUSTANGLE) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETUNIFORMIVROBUSTANGLE) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBFVROBUSTANGLE) (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIVROBUSTANGLE) (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVROBUSTANGLE) (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, void **pointer); +typedef void (GL_APIENTRYP PFNGLREADPIXELSROBUSTANGLE) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLsizei *length, GLsizei *columns, GLsizei *rows, void *pixels); +typedef void (GL_APIENTRYP PFNGLTEXIMAGE2DROBUSTANGLE) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLsizei bufSize, const void *pixels); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, const GLfloat *params); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, const GLint *params); +typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE2DROBUSTANGLE) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, const void *pixels); +typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DROBUSTANGLE) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, GLsizei bufSize, const void *pixels); +typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DROBUSTANGLE) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, const void *pixels); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DROBUSTANGLE) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, GLsizei bufSize, const void *data); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DROBUSTANGLE) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, GLsizei bufSize, const void *data); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DROBUSTANGLE) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, GLsizei bufSize, const void *data); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DROBUSTANGLE) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, GLsizei bufSize, const void *data); +typedef void (GL_APIENTRYP PFNGLGETQUERYIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUIVROBUSTANGLE) (GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params); +typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, void **params); +typedef void (GL_APIENTRYP PFNGLGETINTEGERI_VROBUSTANGLE) (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLint *data); +typedef void (GL_APIENTRYP PFNGETINTERNALFORMATIVROBUSTANGLE) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIIVROBUSTANGLE) (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIUIVROBUSTANGLE) (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params); +typedef void (GL_APIENTRYP PFNGLGETUNIFORMUIVROBUSTANGLE) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLuint *params); +typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVROBUSTANGLE) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETINTEGER64VROBUSTANGLE) (GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *data); +typedef void (GL_APIENTRYP PFNGLGETINTEGER64I_VROBUSTANGLE) (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLint64 *data); +typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERI64VROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *params); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, const GLint *param); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERFVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, const GLfloat *param); +typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERFVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMINTERFACEIVROBUSTANGLE) (GLuint program, GLenum programInterface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETBOOLEANI_VROBUSTANGLE) (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLboolean *data); +typedef void (GL_APIENTRYP PFNGLGETMULTISAMPLEFVROBUSTANGLE) (GLenum pname, GLuint index, GLsizei bufSize, GLsizei *length, GLfloat *val); +typedef void (GL_APIENTRYP PFNGLGETTEXLEVELPARAMETERIVROBUSTANGLE) (GLenum target, GLint level, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETTEXLEVELPARAMETERFVROBUSTANGLE) (GLenum target, GLint level, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETPOINTERVROBUSTANGLEROBUSTANGLE) (GLenum pname, GLsizei bufSize, GLsizei *length, void **params); +typedef void (GL_APIENTRYP PFNGLREADNPIXELSROBUSTANGLE) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLsizei *length, GLsizei *columns, GLsizei *rows, void *data); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVROBUSTANGLE) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVROBUSTANGLE) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMUIVROBUSTANGLE) (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLuint *params); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, const GLint *params); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIUIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, const GLuint *params); +typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIUIVROBUSTANGLE) (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIIVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, const GLint *param); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIUIVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, const GLuint *param); +typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIIVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVROBUSTANGLE) (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTIVROBUSTANGLE)(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTI64VROBUSTANGLE)(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUI64VROBUSTANGLE)(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint64 *params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetBooleanvRobustANGLE (GLenum pname, GLsizei bufSize, GLsizei *length, GLboolean *data); +GL_APICALL void GL_APIENTRY glGetBufferParameterivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +GL_APICALL void GL_APIENTRY glGetFloatvRobustANGLE (GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *data); +GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameterivRobustANGLE (GLenum target, GLenum attachment, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +GL_APICALL void GL_APIENTRY glGetIntegervRobustANGLE (GLenum pname, GLsizei bufSize, GLsizei *length, GLint *data); +GL_APICALL void GL_APIENTRY glGetProgramivRobustANGLE (GLuint program, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +GL_APICALL void GL_APIENTRY glGetRenderbufferParameterivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +GL_APICALL void GL_APIENTRY glGetShaderivRobustANGLE (GLuint shader, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +GL_APICALL void GL_APIENTRY glGetTexParameterfvRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetTexParameterivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +GL_APICALL void GL_APIENTRY glGetUniformfvRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetUniformivRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLint *params); +GL_APICALL void GL_APIENTRY glGetVertexAttribfvRobustANGLE (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetVertexAttribivRobustANGLE (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +GL_APICALL void GL_APIENTRY glGetVertexAttribPointervRobustANGLE (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, void **pointer); +GL_APICALL void GL_APIENTRY glReadPixelsRobustANGLE (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLsizei *length, GLsizei *columns, GLsizei *rows, void *pixels); +GL_APICALL void GL_APIENTRY glTexImage2DRobustANGLE (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLsizei bufSize, const void *pixels); +GL_APICALL void GL_APIENTRY glTexParameterfvRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, const GLfloat *params); +GL_APICALL void GL_APIENTRY glTexParameterivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, const GLint *params); +GL_APICALL void GL_APIENTRY glTexSubImage2DRobustANGLE (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, const void *pixels); +GL_APICALL void GL_APIENTRY glTexImage3DRobustANGLE (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, GLsizei bufSize, const void *pixels); +GL_APICALL void GL_APIENTRY glTexSubImage3DRobustANGLE (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, const void *pixels); +GL_APICALL void GL_APIENTRY glCompressedTexImage2DRobustANGLE(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, GLsizei bufSize, const void *data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage2DRobustANGLE(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, GLsizei bufSize, const void *data); +GL_APICALL void GL_APIENTRY glCompressedTexImage3DRobustANGLE(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, GLsizei bufSize, const void *data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage3DRobustANGLE(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, GLsizei bufSize, const void *data); +GL_APICALL void GL_APIENTRY glGetQueryivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectuivRobustANGLE (GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params); +GL_APICALL void GL_APIENTRY glGetBufferPointervRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, void **params); +GL_APICALL void GL_APIENTRY glGetIntegeri_vRobustANGLE (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLint *data); +GL_APICALL void GL_APIENTRY glGetInternalformativRobustANGLE (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +GL_APICALL void GL_APIENTRY glGetVertexAttribIivRobustANGLE (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +GL_APICALL void GL_APIENTRY glGetVertexAttribIuivRobustANGLE (GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params); +GL_APICALL void GL_APIENTRY glGetUniformuivRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLuint *params); +GL_APICALL void GL_APIENTRY glGetActiveUniformBlockivRobustANGLE (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +GL_APICALL void GL_APIENTRY glGetInteger64vRobustANGLE (GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *data); +GL_APICALL void GL_APIENTRY glGetInteger64i_vRobustANGLE (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLint64 *data); +GL_APICALL void GL_APIENTRY glGetBufferParameteri64vRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *params); +GL_APICALL void GL_APIENTRY glSamplerParameterivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, const GLint *param); +GL_APICALL void GL_APIENTRY glSamplerParameterfvRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, const GLfloat *param); +GL_APICALL void GL_APIENTRY glGetSamplerParameterivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +GL_APICALL void GL_APIENTRY glGetSamplerParameterfvRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetFramebufferParameterivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +GL_APICALL void GL_APIENTRY glGetProgramInterfaceivRobustANGLE (GLuint program, GLenum programInterface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +GL_APICALL void GL_APIENTRY glGetBooleani_vRobustANGLE (GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLboolean *data); +GL_APICALL void GL_APIENTRY glGetMultisamplefvRobustANGLE (GLenum pname, GLuint index, GLsizei bufSize, GLsizei *length, GLfloat *val); +GL_APICALL void GL_APIENTRY glGetTexLevelParameterivRobustANGLE (GLenum target, GLint level, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +GL_APICALL void GL_APIENTRY glGetTexLevelParameterfvRobustANGLE (GLenum target, GLint level, GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetPointervRobustANGLERobustANGLE (GLenum pname, GLsizei bufSize, GLsizei *length, void **params); +GL_APICALL void GL_APIENTRY glReadnPixelsRobustANGLE (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLsizei *length, GLsizei *columns, GLsizei *rows, void *data); +GL_APICALL void GL_APIENTRY glGetnUniformfvRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetnUniformivRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLint *params); +GL_APICALL void GL_APIENTRY glGetnUniformuivRobustANGLE (GLuint program, GLint location, GLsizei bufSize, GLsizei *length, GLuint *params); +GL_APICALL void GL_APIENTRY glTexParameterIivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, const GLint *params); +GL_APICALL void GL_APIENTRY glTexParameterIuivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, const GLuint *params); +GL_APICALL void GL_APIENTRY glGetTexParameterIivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +GL_APICALL void GL_APIENTRY glGetTexParameterIuivRobustANGLE (GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params); +GL_APICALL void GL_APIENTRY glSamplerParameterIivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, const GLint *param); +GL_APICALL void GL_APIENTRY glSamplerParameterIuivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, const GLuint *param); +GL_APICALL void GL_APIENTRY glGetSamplerParameterIivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +GL_APICALL void GL_APIENTRY glGetSamplerParameterIuivRobustANGLE (GLuint sampler, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectivRobustANGLE(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjecti64vRobustANGLE(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectui64vRobustANGLE(GLuint id, GLenum pname, GLsizei bufSize, GLsizei *length, GLuint64 *params); +#endif +#endif /* GL_ANGLE_robust_client_memory */ + +#ifndef GL_ANGLE_program_cache_control +#define GL_ANGLE_program_cache_control 1 +#define GL_PROGRAM_CACHE_ENABLED_ANGLE 0x93AC +#endif /* GL_ANGLE_program_cache_control */ + +#ifndef GL_ANGLE_multiview +#define GL_ANGLE_multiview 1 +// The next four enums coincide with the enums introduced by the GL_OVR_multiview extension and use the values reserved by that extension. +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE 0x9630 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE 0x9632 +#define GL_MAX_VIEWS_ANGLE 0x9631 +#define GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_ANGLE 0x9633 +// The next four enums are reserved specifically for ANGLE. +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE 0x969B +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE 0x969C +#define GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE 0x969D +#define GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE 0x969E +typedef void(GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTIVIEWLAYEREDANGLE)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); +typedef void(GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTIVIEWSIDEBYSIDEANGLE)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLsizei numViews, const GLint *viewportOffsets); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glFramebufferTextureMultiviewLayeredANGLE(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); +GL_APICALL void GL_APIENTRY glFramebufferTextureMultiviewSideBySideANGLE(GLenum target, GLenum attachment, GLuint texture, GLint level, GLsizei numViews, const GLint *viewportOffsets); +#endif +#endif /* GL_ANGLE_multiview */ + +#ifndef GL_ANGLE_texture_rectangle +#define GL_ANGLE_texture_rectangle 1 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE 0x84F8 +#define GL_TEXTURE_RECTANGLE_ANGLE 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_ANGLE 0x84F6 +#define GL_SAMPLER_2D_RECT_ANGLE 0x8B63 +#endif /* GL_ANGLE_texture_rectangle */ + +// clang-format on + +#endif // INCLUDE_GLES2_GL2EXT_ANGLE_H_ diff --git a/src/3rdparty/angle/include/GLES3/gl3ext.h b/src/3rdparty/angle/include/GLES3/gl3ext.h deleted file mode 100644 index 4d4ea96c4d..0000000000 --- a/src/3rdparty/angle/include/GLES3/gl3ext.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef __gl3ext_h_ -#define __gl3ext_h_ - -/* $Revision: 17809 $ on $Date:: 2012-05-14 08:03:36 -0700 #$ */ - -/* - * This document is licensed under the SGI Free Software B License Version - * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . - */ - -/* OpenGL ES 3 Extensions - * - * After an OES extension's interactions with OpenGl ES 3.0 have been documented, - * its tokens and function definitions should be added to this file in a manner - * that does not conflict with gl2ext.h or gl3.h. - * - * Tokens and function definitions for extensions that have become standard - * features in OpenGL ES 3.0 will not be added to this file. - * - * Applications using OpenGL-ES-2-only extensions should include gl2ext.h - */ - -#endif /* __gl3ext_h_ */ - diff --git a/src/3rdparty/angle/include/GLSLANG/ShaderLang.h b/src/3rdparty/angle/include/GLSLANG/ShaderLang.h index d02723e760..1468bb1464 100644 --- a/src/3rdparty/angle/include/GLSLANG/ShaderLang.h +++ b/src/3rdparty/angle/include/GLSLANG/ShaderLang.h @@ -6,27 +6,11 @@ #ifndef GLSLANG_SHADERLANG_H_ #define GLSLANG_SHADERLANG_H_ -#if defined(COMPONENT_BUILD) && !defined(ANGLE_TRANSLATOR_STATIC) -#if defined(_WIN32) || defined(_WIN64) - -#if defined(ANGLE_TRANSLATOR_IMPLEMENTATION) -#define COMPILER_EXPORT __declspec(dllexport) -#else -#define COMPILER_EXPORT __declspec(dllimport) -#endif // defined(ANGLE_TRANSLATOR_IMPLEMENTATION) - -#else // defined(_WIN32) || defined(_WIN64) -#define COMPILER_EXPORT __attribute__((visibility("default"))) -#endif - -#else // defined(COMPONENT_BUILD) && !defined(ANGLE_TRANSLATOR_STATIC) -#define COMPILER_EXPORT -#endif - #include #include "KHR/khrplatform.h" +#include #include #include #include @@ -36,51 +20,26 @@ // and the shading language compiler. // -namespace sh -{ -// GLenum alias -typedef unsigned int GLenum; -} - -// Must be included after GLenum proxy typedef // Note: make sure to increment ANGLE_SH_VERSION when changing ShaderVars.h #include "ShaderVars.h" // Version number for shader translation API. // It is incremented every time the API changes. -#define ANGLE_SH_VERSION 143 +#define ANGLE_SH_VERSION 190 -typedef enum { - SH_GLES2_SPEC = 0x8B40, - SH_WEBGL_SPEC = 0x8B41, +enum ShShaderSpec +{ + SH_GLES2_SPEC, + SH_WEBGL_SPEC, - SH_GLES3_SPEC = 0x8B86, - SH_WEBGL2_SPEC = 0x8B87, + SH_GLES3_SPEC, + SH_WEBGL2_SPEC, - // The CSS Shaders spec is a subset of the WebGL spec. - // - // In both CSS vertex and fragment shaders, ANGLE: - // (1) Reserves the "css_" prefix. - // (2) Renames the main function to css_main. - // (3) Disables the gl_MaxDrawBuffers built-in. - // - // In CSS fragment shaders, ANGLE: - // (1) Disables the gl_FragColor built-in. - // (2) Disables the gl_FragData built-in. - // (3) Enables the css_MixColor built-in. - // (4) Enables the css_ColorMatrix built-in. - // - // After passing a CSS shader through ANGLE, the browser is expected to append - // a new main function to it. - // This new main function will call the css_main function. - // It may also perform additional operations like varying assignment, texture - // access, and gl_FragColor assignment in order to implement the CSS Shaders - // blend modes. - // - SH_CSS_SHADERS_SPEC = 0x8B42 -} ShShaderSpec; + SH_GLES3_1_SPEC, + SH_WEBGL3_SPEC, +}; -typedef enum +enum ShShaderOutput { // ESSL output only supported in some configurations. SH_ESSL_OUTPUT = 0x8B45, @@ -99,147 +58,224 @@ typedef enum SH_GLSL_440_CORE_OUTPUT = 0x8B87, SH_GLSL_450_CORE_OUTPUT = 0x8B88, - // HLSL output only supported in some configurations. - // Deprecated: - SH_HLSL_OUTPUT = 0x8B48, - SH_HLSL9_OUTPUT = 0x8B48, - SH_HLSL11_OUTPUT = 0x8B49, - // Prefer using these to specify HLSL output type: SH_HLSL_3_0_OUTPUT = 0x8B48, // D3D 9 SH_HLSL_4_1_OUTPUT = 0x8B49, // D3D 11 - SH_HLSL_4_0_FL9_3_OUTPUT = 0x8B4A // D3D 11 feature level 9_3 -} ShShaderOutput; + SH_HLSL_4_0_FL9_3_OUTPUT = 0x8B4A, // D3D 11 feature level 9_3 + + // Output specialized GLSL to be fed to glslang for Vulkan SPIR. + SH_GLSL_VULKAN_OUTPUT = 0x8B4B, +}; // Compile options. -typedef enum { - SH_VALIDATE = 0, - SH_VALIDATE_LOOP_INDEXING = 0x0001, - SH_INTERMEDIATE_TREE = 0x0002, - SH_OBJECT_CODE = 0x0004, - SH_VARIABLES = 0x0008, - SH_LINE_DIRECTIVES = 0x0010, - SH_SOURCE_PATH = 0x0020, - SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX = 0x0040, - // If a sampler array index happens to be a loop index, - // 1) if its type is integer, unroll the loop. - // 2) if its type is float, fail the shader compile. - // This is to work around a mac driver bug. - SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX = 0x0080, +// The Compile options type is defined in ShaderVars.h, to allow ANGLE to import the ShaderVars +// header without needing the ShaderLang header. This avoids some conflicts with glslang. - // This is needed only as a workaround for certain OpenGL driver bugs. - SH_EMULATE_BUILT_IN_FUNCTIONS = 0x0100, +const ShCompileOptions SH_VALIDATE = 0; +const ShCompileOptions SH_VALIDATE_LOOP_INDEXING = UINT64_C(1) << 0; +const ShCompileOptions SH_INTERMEDIATE_TREE = UINT64_C(1) << 1; +const ShCompileOptions SH_OBJECT_CODE = UINT64_C(1) << 2; +const ShCompileOptions SH_VARIABLES = UINT64_C(1) << 3; +const ShCompileOptions SH_LINE_DIRECTIVES = UINT64_C(1) << 4; +const ShCompileOptions SH_SOURCE_PATH = UINT64_C(1) << 5; - // This is an experimental flag to enforce restrictions that aim to prevent - // timing attacks. - // It generates compilation errors for shaders that could expose sensitive - // texture information via the timing channel. - // To use this flag, you must compile the shader under the WebGL spec - // (using the SH_WEBGL_SPEC flag). - SH_TIMING_RESTRICTIONS = 0x0200, +// This flag will keep invariant declaration for input in fragment shader for GLSL >=4.20 on AMD. +// From GLSL >= 4.20, it's optional to add invariant for fragment input, but GPU vendors have +// different implementations about this. Some drivers forbid invariant in fragment for GLSL>= 4.20, +// e.g. Linux Mesa, some drivers treat that as optional, e.g. NVIDIA, some drivers require invariant +// must match between vertex and fragment shader, e.g. AMD. The behavior on AMD is obviously wrong. +// Remove invariant for input in fragment shader to workaround the restriction on Intel Mesa. +// But don't remove on AMD Linux to avoid triggering the bug on AMD. +const ShCompileOptions SH_DONT_REMOVE_INVARIANT_FOR_FRAGMENT_INPUT = UINT64_C(1) << 6; - // This flag prints the dependency graph that is used to enforce timing - // restrictions on fragment shaders. - // This flag only has an effect if all of the following are true: - // - The shader spec is SH_WEBGL_SPEC. - // - The compile options contain the SH_TIMING_RESTRICTIONS flag. - // - The shader type is GL_FRAGMENT_SHADER. - SH_DEPENDENCY_GRAPH = 0x0400, +// Due to spec difference between GLSL 4.1 or lower and ESSL3, some platforms (for example, Mac OSX +// core profile) require a variable's "invariant"/"centroid" qualifiers to match between vertex and +// fragment shader. A simple solution to allow such shaders to link is to omit the two qualifiers. +// AMD driver in Linux requires invariant qualifier to match between vertex and fragment shaders, +// while ESSL3 disallows invariant qualifier in fragment shader and GLSL >= 4.2 doesn't require +// invariant qualifier to match between shaders. Remove invariant qualifier from vertex shader to +// workaround AMD driver bug. +// Note that the two flags take effect on ESSL3 input shaders translated to GLSL 4.1 or lower and to +// GLSL 4.2 or newer on Linux AMD. +// TODO(zmo): This is not a good long-term solution. Simply dropping these qualifiers may break some +// developers' content. A more complex workaround of dynamically generating, compiling, and +// re-linking shaders that use these qualifiers should be implemented. +const ShCompileOptions SH_REMOVE_INVARIANT_AND_CENTROID_FOR_ESSL3 = UINT64_C(1) << 7; - // Enforce the GLSL 1.017 Appendix A section 7 packing restrictions. - // This flag only enforces (and can only enforce) the packing - // restrictions for uniform variables in both vertex and fragment - // shaders. ShCheckVariablesWithinPackingLimits() lets embedders - // enforce the packing restrictions for varying variables during - // program link time. - SH_ENFORCE_PACKING_RESTRICTIONS = 0x0800, +// This flag works around bug in Intel Mac drivers related to abs(i) where +// i is an integer. +const ShCompileOptions SH_EMULATE_ABS_INT_FUNCTION = UINT64_C(1) << 8; - // This flag ensures all indirect (expression-based) array indexing - // is clamped to the bounds of the array. This ensures, for example, - // that you cannot read off the end of a uniform, whether an array - // vec234, or mat234 type. The ShArrayIndexClampingStrategy enum, - // specified in the ShBuiltInResources when constructing the - // compiler, selects the strategy for the clamping implementation. - SH_CLAMP_INDIRECT_ARRAY_BOUNDS = 0x1000, +// Enforce the GLSL 1.017 Appendix A section 7 packing restrictions. +// This flag only enforces (and can only enforce) the packing +// restrictions for uniform variables in both vertex and fragment +// shaders. ShCheckVariablesWithinPackingLimits() lets embedders +// enforce the packing restrictions for varying variables during +// program link time. +const ShCompileOptions SH_ENFORCE_PACKING_RESTRICTIONS = UINT64_C(1) << 9; - // This flag limits the complexity of an expression. - SH_LIMIT_EXPRESSION_COMPLEXITY = 0x2000, +// This flag ensures all indirect (expression-based) array indexing +// is clamped to the bounds of the array. This ensures, for example, +// that you cannot read off the end of a uniform, whether an array +// vec234, or mat234 type. The ShArrayIndexClampingStrategy enum, +// specified in the ShBuiltInResources when constructing the +// compiler, selects the strategy for the clamping implementation. +const ShCompileOptions SH_CLAMP_INDIRECT_ARRAY_BOUNDS = UINT64_C(1) << 10; - // This flag limits the depth of the call stack. - SH_LIMIT_CALL_STACK_DEPTH = 0x4000, +// This flag limits the complexity of an expression. +const ShCompileOptions SH_LIMIT_EXPRESSION_COMPLEXITY = UINT64_C(1) << 11; - // This flag initializes gl_Position to vec4(0,0,0,0) at the - // beginning of the vertex shader's main(), and has no effect in the - // fragment shader. It is intended as a workaround for drivers which - // incorrectly fail to link programs if gl_Position is not written. - SH_INIT_GL_POSITION = 0x8000, +// This flag limits the depth of the call stack. +const ShCompileOptions SH_LIMIT_CALL_STACK_DEPTH = UINT64_C(1) << 12; - // This flag replaces - // "a && b" with "a ? b : false", - // "a || b" with "a ? true : b". - // This is to work around a MacOSX driver bug that |b| is executed - // independent of |a|'s value. - SH_UNFOLD_SHORT_CIRCUIT = 0x10000, +// This flag initializes gl_Position to vec4(0,0,0,0) at the +// beginning of the vertex shader's main(), and has no effect in the +// fragment shader. It is intended as a workaround for drivers which +// incorrectly fail to link programs if gl_Position is not written. +const ShCompileOptions SH_INIT_GL_POSITION = UINT64_C(1) << 13; - // This flag initializes varyings without static use in vertex shader - // at the beginning of main(), and has no effects in the fragment shader. - // It is intended as a workaround for drivers which incorrectly optimize - // out such varyings and cause a link failure. - SH_INIT_VARYINGS_WITHOUT_STATIC_USE = 0x20000, +// This flag replaces +// "a && b" with "a ? b : false", +// "a || b" with "a ? true : b". +// This is to work around a MacOSX driver bug that |b| is executed +// independent of |a|'s value. +const ShCompileOptions SH_UNFOLD_SHORT_CIRCUIT = UINT64_C(1) << 14; - // This flag scalarizes vec/ivec/bvec/mat constructor args. - // It is intended as a workaround for Linux/Mac driver bugs. - SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS = 0x40000, +// This flag initializes output variables to 0 at the beginning of main(). +// It is to avoid undefined behaviors. +const ShCompileOptions SH_INIT_OUTPUT_VARIABLES = UINT64_C(1) << 15; - // This flag overwrites a struct name with a unique prefix. - // It is intended as a workaround for drivers that do not handle - // struct scopes correctly, including all Mac drivers and Linux AMD. - SH_REGENERATE_STRUCT_NAMES = 0x80000, +// This flag scalarizes vec/ivec/bvec/mat constructor args. +// It is intended as a workaround for Linux/Mac driver bugs. +const ShCompileOptions SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS = UINT64_C(1) << 16; - // This flag makes the compiler not prune unused function early in the - // compilation process. Pruning coupled with SH_LIMIT_CALL_STACK_DEPTH - // helps avoid bad shaders causing stack overflows. - SH_DONT_PRUNE_UNUSED_FUNCTIONS = 0x100000, +// This flag overwrites a struct name with a unique prefix. +// It is intended as a workaround for drivers that do not handle +// struct scopes correctly, including all Mac drivers and Linux AMD. +const ShCompileOptions SH_REGENERATE_STRUCT_NAMES = UINT64_C(1) << 17; - // This flag works around a bug in NVIDIA 331 series drivers related - // to pow(x, y) where y is a constant vector. - SH_REMOVE_POW_WITH_CONSTANT_EXPONENT = 0x200000, +// This flag makes the compiler not prune unused function early in the +// compilation process. Pruning coupled with SH_LIMIT_CALL_STACK_DEPTH +// helps avoid bad shaders causing stack overflows. +const ShCompileOptions SH_DONT_PRUNE_UNUSED_FUNCTIONS = UINT64_C(1) << 18; - // This flag works around bugs in Mac drivers related to do-while by - // transforming them into an other construct. - SH_REWRITE_DO_WHILE_LOOPS = 0x400000, -} ShCompileOptions; +// This flag works around a bug in NVIDIA 331 series drivers related +// to pow(x, y) where y is a constant vector. +const ShCompileOptions SH_REMOVE_POW_WITH_CONSTANT_EXPONENT = UINT64_C(1) << 19; + +// This flag works around bugs in Mac drivers related to do-while by +// transforming them into an other construct. +const ShCompileOptions SH_REWRITE_DO_WHILE_LOOPS = UINT64_C(1) << 20; + +// This flag works around a bug in the HLSL compiler optimizer that folds certain +// constant pow expressions incorrectly. Only applies to the HLSL back-end. It works +// by expanding the integer pow expressions into a series of multiplies. +const ShCompileOptions SH_EXPAND_SELECT_HLSL_INTEGER_POW_EXPRESSIONS = UINT64_C(1) << 21; + +// Flatten "#pragma STDGL invariant(all)" into the declarations of +// varying variables and built-in GLSL variables. This compiler +// option is enabled automatically when needed. +const ShCompileOptions SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL = UINT64_C(1) << 22; + +// Some drivers do not take into account the base level of the texture in the results of the +// HLSL GetDimensions builtin. This flag instructs the compiler to manually add the base level +// offsetting. +const ShCompileOptions SH_HLSL_GET_DIMENSIONS_IGNORES_BASE_LEVEL = UINT64_C(1) << 23; + +// This flag works around an issue in translating GLSL function texelFetchOffset on +// INTEL drivers. It works by translating texelFetchOffset into texelFetch. +const ShCompileOptions SH_REWRITE_TEXELFETCHOFFSET_TO_TEXELFETCH = UINT64_C(1) << 24; + +// This flag works around condition bug of for and while loops in Intel Mac OSX drivers. +// Condition calculation is not correct. Rewrite it from "CONDITION" to "CONDITION && true". +const ShCompileOptions SH_ADD_AND_TRUE_TO_LOOP_CONDITION = UINT64_C(1) << 25; + +// This flag works around a bug in evaluating unary minus operator on integer on some INTEL +// drivers. It works by translating -(int) into ~(int) + 1. +const ShCompileOptions SH_REWRITE_INTEGER_UNARY_MINUS_OPERATOR = UINT64_C(1) << 26; + +// This flag works around a bug in evaluating isnan() on some INTEL D3D and Mac OSX drivers. +// It works by using an expression to emulate this function. +const ShCompileOptions SH_EMULATE_ISNAN_FLOAT_FUNCTION = UINT64_C(1) << 27; + +// This flag will use all uniforms of unused std140 and shared uniform blocks at the +// beginning of the vertex/fragment shader's main(). It is intended as a workaround for Mac +// drivers with shader version 4.10. In those drivers, they will treat unused +// std140 and shared uniform blocks' members as inactive. However, WebGL2.0 based on +// OpenGL ES3.0.4 requires all members of a named uniform block declared with a shared or std140 +// layout qualifier to be considered active. The uniform block itself is also considered active. +const ShCompileOptions SH_USE_UNUSED_STANDARD_SHARED_BLOCKS = UINT64_C(1) << 28; + +// This flag works around a bug in unary minus operator on float numbers on Intel +// Mac OSX 10.11 drivers. It works by translating -float into 0.0 - float. +const ShCompileOptions SH_REWRITE_FLOAT_UNARY_MINUS_OPERATOR = UINT64_C(1) << 29; + +// This flag works around a bug in evaluating atan(y, x) on some NVIDIA OpenGL drivers. +// It works by using an expression to emulate this function. +const ShCompileOptions SH_EMULATE_ATAN2_FLOAT_FUNCTION = UINT64_C(1) << 30; + +// Set to 1 to translate gl_ViewID_OVR to an uniform so that the extension can be emulated. +// "uniform highp uint ViewID_OVR". +const ShCompileOptions SH_TRANSLATE_VIEWID_OVR_TO_UNIFORM = UINT64_C(1) << 31; + +// Set to initialize uninitialized local and global temporary variables. Should only be used with +// GLSL output. In HLSL output variables are initialized regardless of if this flag is set. +const ShCompileOptions SH_INITIALIZE_UNINITIALIZED_LOCALS = UINT64_C(1) << 32; + +// The flag modifies the shader in the following way: +// Every occurrence of gl_InstanceID is replaced by the global temporary variable InstanceID. +// Every occurrence of gl_ViewID_OVR is replaced by the varying variable ViewID_OVR. +// At the beginning of the body of main() in a vertex shader the following initializers are added: +// ViewID_OVR = uint(gl_InstanceID) % num_views; +// InstanceID = gl_InstanceID / num_views; +// ViewID_OVR is added as a varying variable to both the vertex and fragment shaders. +const ShCompileOptions SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW = UINT64_C(1) << 33; + +// With the flag enabled the GLSL/ESSL vertex shader is modified to include code for viewport +// selection in the following way: +// - Code to enable the extension NV_viewport_array2 is included. +// - Code to select the viewport index or layer is inserted at the beginning of main after +// ViewID_OVR's initialization. +// - A declaration of the uniform multiviewBaseViewLayerIndex. +// Note: The SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW flag also has to be enabled to have the +// temporary variable ViewID_OVR declared and initialized. +const ShCompileOptions SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER = UINT64_C(1) << 34; + +// If the flag is enabled, gl_PointSize is clamped to the maximum point size specified in +// ShBuiltInResources in vertex shaders. +const ShCompileOptions SH_CLAMP_POINT_SIZE = UINT64_C(1) << 35; + +// Turn some arithmetic operations that operate on a float vector-scalar pair into vector-vector +// operations. This is done recursively. Some scalar binary operations inside vector constructors +// are also turned into vector operations. +// +// This is targeted to work around a bug in NVIDIA OpenGL drivers that was reproducible on NVIDIA +// driver version 387.92. It works around the most common occurrences of the bug. +const ShCompileOptions SH_REWRITE_VECTOR_SCALAR_ARITHMETIC = UINT64_C(1) << 36; + +// Don't use loops to initialize uninitialized variables. Only has an effect if some kind of +// variable initialization is turned on. +const ShCompileOptions SH_DONT_USE_LOOPS_TO_INITIALIZE_VARIABLES = UINT64_C(1) << 37; // Defines alternate strategies for implementing array index clamping. -typedef enum { - // Use the clamp intrinsic for array index clamping. - SH_CLAMP_WITH_CLAMP_INTRINSIC = 1, +enum ShArrayIndexClampingStrategy +{ + // Use the clamp intrinsic for array index clamping. + SH_CLAMP_WITH_CLAMP_INTRINSIC = 1, - // Use a user-defined function for array index clamping. - SH_CLAMP_WITH_USER_DEFINED_INT_CLAMP_FUNCTION -} ShArrayIndexClampingStrategy; - -// -// Driver must call this first, once, before doing any other -// compiler operations. -// If the function succeeds, the return value is true, else false. -// -COMPILER_EXPORT bool ShInitialize(); -// -// Driver should call this at shutdown. -// If the function succeeds, the return value is true, else false. -// -COMPILER_EXPORT bool ShFinalize(); + // Use a user-defined function for array index clamping. + SH_CLAMP_WITH_USER_DEFINED_INT_CLAMP_FUNCTION +}; // The 64 bits hash function. The first parameter is the input string; the // second parameter is the string length. -typedef khronos_uint64_t (*ShHashFunction64)(const char*, size_t); +using ShHashFunction64 = khronos_uint64_t (*)(const char *, size_t); // // Implementation dependent built-in resources (constants and extensions). // The names for these resources has been obtained by stripping gl_/GL_. // -typedef struct +struct ShBuiltInResources { // Constants. int MaxVertexAttribs; @@ -255,6 +291,8 @@ typedef struct // Set to 1 to enable the extension, else 0. int OES_standard_derivatives; int OES_EGL_image_external; + int OES_EGL_image_external_essl3; + int NV_EGL_stream_consumer_external; int ARB_texture_rectangle; int EXT_blend_func_extended; int EXT_draw_buffers; @@ -264,6 +302,9 @@ typedef struct int EXT_shader_framebuffer_fetch; int NV_shader_framebuffer_fetch; int ARM_shader_framebuffer_fetch; + int OVR_multiview; + int EXT_YUV_target; + int OES_geometry_shader; // Set to 1 to enable replacing GL_EXT_draw_buffers #extension directives // with GL_NV_draw_buffers in ESSL output. This flag can be used to emulate @@ -290,6 +331,9 @@ typedef struct // GLES SL version 100 gl_MaxDualSourceDrawBuffersEXT value for EXT_blend_func_extended. int MaxDualSourceDrawBuffers; + // Value of GL_MAX_VIEWS_OVR. + int MaxViewsOVR; + // Name Hashing. // Set a 64 bit hash function to enable user-defined name hashing. // Default is NULL. @@ -299,19 +343,107 @@ typedef struct // Default is SH_CLAMP_WITH_CLAMP_INTRINSIC. ShArrayIndexClampingStrategy ArrayIndexClampingStrategy; - // The maximum complexity an expression can be. + // The maximum complexity an expression can be when SH_LIMIT_EXPRESSION_COMPLEXITY is turned on. int MaxExpressionComplexity; // The maximum depth a call stack can be. int MaxCallStackDepth; -} ShBuiltInResources; -// -// Initialize built-in resources with minimum expected values. -// Parameters: -// resources: The object to initialize. Will be comparable with memcmp. -// -COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources *resources); + // The maximum number of parameters a function can have when SH_LIMIT_EXPRESSION_COMPLEXITY is + // turned on. + int MaxFunctionParameters; + + // GLES 3.1 constants + + // texture gather offset constraints. + int MinProgramTextureGatherOffset; + int MaxProgramTextureGatherOffset; + + // maximum number of available image units + int MaxImageUnits; + + // maximum number of image uniforms in a vertex shader + int MaxVertexImageUniforms; + + // maximum number of image uniforms in a fragment shader + int MaxFragmentImageUniforms; + + // maximum number of image uniforms in a compute shader + int MaxComputeImageUniforms; + + // maximum total number of image uniforms in a program + int MaxCombinedImageUniforms; + + // maximum number of uniform locations + int MaxUniformLocations; + + // maximum number of ssbos and images in a shader + int MaxCombinedShaderOutputResources; + + // maximum number of groups in each dimension + std::array MaxComputeWorkGroupCount; + // maximum number of threads per work group in each dimension + std::array MaxComputeWorkGroupSize; + + // maximum number of total uniform components + int MaxComputeUniformComponents; + + // maximum number of texture image units in a compute shader + int MaxComputeTextureImageUnits; + + // maximum number of atomic counters in a compute shader + int MaxComputeAtomicCounters; + + // maximum number of atomic counter buffers in a compute shader + int MaxComputeAtomicCounterBuffers; + + // maximum number of atomic counters in a vertex shader + int MaxVertexAtomicCounters; + + // maximum number of atomic counters in a fragment shader + int MaxFragmentAtomicCounters; + + // maximum number of atomic counters in a program + int MaxCombinedAtomicCounters; + + // maximum binding for an atomic counter + int MaxAtomicCounterBindings; + + // maximum number of atomic counter buffers in a vertex shader + int MaxVertexAtomicCounterBuffers; + + // maximum number of atomic counter buffers in a fragment shader + int MaxFragmentAtomicCounterBuffers; + + // maximum number of atomic counter buffers in a program + int MaxCombinedAtomicCounterBuffers; + + // maximum number of buffer object storage in machine units + int MaxAtomicCounterBufferSize; + + // maximum number of uniform block bindings + int MaxUniformBufferBindings; + + // maximum number of shader storage buffer bindings + int MaxShaderStorageBufferBindings; + + // maximum point size (higher limit from ALIASED_POINT_SIZE_RANGE) + float MaxPointSize; + + // OES_geometry_shader constants + int MaxGeometryUniformComponents; + int MaxGeometryUniformBlocks; + int MaxGeometryInputComponents; + int MaxGeometryOutputComponents; + int MaxGeometryOutputVertices; + int MaxGeometryTotalOutputComponents; + int MaxGeometryTextureImageUnits; + int MaxGeometryAtomicCounterBuffers; + int MaxGeometryAtomicCounters; + int MaxGeometryShaderStorageBlocks; + int MaxGeometryShaderInvocations; + int MaxGeometryImageUniforms; +}; // // ShHandle held by but opaque to the driver. It is allocated, @@ -320,43 +452,60 @@ COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources *resources); // // If handle creation fails, 0 will be returned. // -typedef void *ShHandle; +using ShHandle = void *; + +namespace sh +{ // -// Returns the a concatenated list of the items in ShBuiltInResources as a -// null-terminated string. +// Driver must call this first, once, before doing any other compiler operations. +// If the function succeeds, the return value is true, else false. +// +bool Initialize(); +// +// Driver should call this at shutdown. +// If the function succeeds, the return value is true, else false. +// +bool Finalize(); + +// +// Initialize built-in resources with minimum expected values. +// Parameters: +// resources: The object to initialize. Will be comparable with memcmp. +// +void InitBuiltInResources(ShBuiltInResources *resources); + +// +// Returns the a concatenated list of the items in ShBuiltInResources as a null-terminated string. // This function must be updated whenever ShBuiltInResources is changed. // Parameters: // handle: Specifies the handle of the compiler to be used. -COMPILER_EXPORT const std::string &ShGetBuiltInResourcesString(const ShHandle handle); +const std::string &GetBuiltInResourcesString(const ShHandle handle); // // Driver calls these to create and destroy compiler objects. // -// Returns the handle of constructed compiler, null if the requested compiler is -// not supported. +// Returns the handle of constructed compiler, null if the requested compiler is not supported. // Parameters: // type: Specifies the type of shader - GL_FRAGMENT_SHADER or GL_VERTEX_SHADER. -// spec: Specifies the language spec the compiler must conform to - -// SH_GLES2_SPEC or SH_WEBGL_SPEC. +// spec: Specifies the language spec the compiler must conform to - SH_GLES2_SPEC or SH_WEBGL_SPEC. // output: Specifies the output code type - for example SH_ESSL_OUTPUT, SH_GLSL_OUTPUT, // SH_HLSL_3_0_OUTPUT or SH_HLSL_4_1_OUTPUT. Note: Each output type may only // be supported in some configurations. // resources: Specifies the built-in resources. -COMPILER_EXPORT ShHandle ShConstructCompiler( - sh::GLenum type, - ShShaderSpec spec, - ShShaderOutput output, - const ShBuiltInResources *resources); -COMPILER_EXPORT void ShDestruct(ShHandle handle); +ShHandle ConstructCompiler(sh::GLenum type, + ShShaderSpec spec, + ShShaderOutput output, + const ShBuiltInResources *resources); +void Destruct(ShHandle handle); // // Compiles the given shader source. // If the function succeeds, the return value is true, else false. // Parameters: // handle: Specifies the handle of compiler to be used. -// shaderStrings: Specifies an array of pointers to null-terminated strings -// containing the shader source code. +// shaderStrings: Specifies an array of pointers to null-terminated strings containing the shader +// source code. // numStrings: Specifies the number of elements in shaderStrings array. // compileOptions: A mask containing the following parameters: // SH_VALIDATE: Validates shader to ensure that it conforms to the spec @@ -368,45 +517,41 @@ COMPILER_EXPORT void ShDestruct(ShHandle handle); // There is no need to specify this parameter when // compiling for WebGL - it is implied. // SH_INTERMEDIATE_TREE: Writes intermediate tree to info log. -// Can be queried by calling ShGetInfoLog(). +// Can be queried by calling sh::GetInfoLog(). // SH_OBJECT_CODE: Translates intermediate tree to glsl or hlsl shader. -// Can be queried by calling ShGetObjectCode(). +// Can be queried by calling sh::GetObjectCode(). // SH_VARIABLES: Extracts attributes, uniforms, and varyings. // Can be queried by calling ShGetVariableInfo(). // -COMPILER_EXPORT bool ShCompile( - const ShHandle handle, - const char * const shaderStrings[], - size_t numStrings, - int compileOptions); +bool Compile(const ShHandle handle, + const char *const shaderStrings[], + size_t numStrings, + ShCompileOptions compileOptions); // Clears the results from the previous compilation. -COMPILER_EXPORT void ShClearResults(const ShHandle handle); +void ClearResults(const ShHandle handle); // Return the version of the shader language. -COMPILER_EXPORT int ShGetShaderVersion(const ShHandle handle); +int GetShaderVersion(const ShHandle handle); // Return the currently set language output type. -COMPILER_EXPORT ShShaderOutput ShGetShaderOutputType( - const ShHandle handle); +ShShaderOutput GetShaderOutputType(const ShHandle handle); // Returns null-terminated information log for a compiled shader. // Parameters: // handle: Specifies the compiler -COMPILER_EXPORT const std::string &ShGetInfoLog(const ShHandle handle); +const std::string &GetInfoLog(const ShHandle handle); // Returns null-terminated object code for a compiled shader. // Parameters: // handle: Specifies the compiler -COMPILER_EXPORT const std::string &ShGetObjectCode(const ShHandle handle); +const std::string &GetObjectCode(const ShHandle handle); -// Returns a (original_name, hash) map containing all the user defined -// names in the shader, including variable names, function names, struct -// names, and struct field names. +// Returns a (original_name, hash) map containing all the user defined names in the shader, +// including variable names, function names, struct names, and struct field names. // Parameters: // handle: Specifies the compiler -COMPILER_EXPORT const std::map *ShGetNameHashingMap( - const ShHandle handle); +const std::map *GetNameHashingMap(const ShHandle handle); // Shader variable inspection. // Returns a pointer to a list of variables of the designated type. @@ -414,52 +559,50 @@ COMPILER_EXPORT const std::map *ShGetNameHashingMap( // Returns NULL on failure. // Parameters: // handle: Specifies the compiler -COMPILER_EXPORT const std::vector *ShGetUniforms(const ShHandle handle); -COMPILER_EXPORT const std::vector *ShGetVaryings(const ShHandle handle); -COMPILER_EXPORT const std::vector *ShGetAttributes(const ShHandle handle); -COMPILER_EXPORT const std::vector *ShGetOutputVariables(const ShHandle handle); -COMPILER_EXPORT const std::vector *ShGetInterfaceBlocks(const ShHandle handle); +const std::vector *GetUniforms(const ShHandle handle); +const std::vector *GetVaryings(const ShHandle handle); +const std::vector *GetInputVaryings(const ShHandle handle); +const std::vector *GetOutputVaryings(const ShHandle handle); +const std::vector *GetAttributes(const ShHandle handle); +const std::vector *GetOutputVariables(const ShHandle handle); +const std::vector *GetInterfaceBlocks(const ShHandle handle); +const std::vector *GetUniformBlocks(const ShHandle handle); +const std::vector *GetShaderStorageBlocks(const ShHandle handle); +sh::WorkGroupSize GetComputeShaderLocalGroupSize(const ShHandle handle); +// Returns the number of views specified through the num_views layout qualifier. If num_views is +// not set, the function returns -1. +int GetVertexShaderNumViews(const ShHandle handle); -typedef struct -{ - sh::GLenum type; - int size; -} ShVariableInfo; - -// Returns true if the passed in variables pack in maxVectors following -// the packing rules from the GLSL 1.017 spec, Appendix A, section 7. +// Returns true if the passed in variables pack in maxVectors followingthe packing rules from the +// GLSL 1.017 spec, Appendix A, section 7. // Returns false otherwise. Also look at the SH_ENFORCE_PACKING_RESTRICTIONS // flag above. // Parameters: // maxVectors: the available rows of registers. -// varInfoArray: an array of variable info (types and sizes). -// varInfoArraySize: the size of the variable array. -COMPILER_EXPORT bool ShCheckVariablesWithinPackingLimits( - int maxVectors, - ShVariableInfo *varInfoArray, - size_t varInfoArraySize); +// variables: an array of variables. +bool CheckVariablesWithinPackingLimits(int maxVectors, + const std::vector &variables); -// Gives the compiler-assigned register for an interface block. +// Gives the compiler-assigned register for a uniform block. // The method writes the value to the output variable "indexOut". -// Returns true if it found a valid interface block, false otherwise. +// Returns true if it found a valid uniform block, false otherwise. // Parameters: // handle: Specifies the compiler -// interfaceBlockName: Specifies the interface block +// uniformBlockName: Specifies the uniform block // indexOut: output variable that stores the assigned register -COMPILER_EXPORT bool ShGetInterfaceBlockRegister(const ShHandle handle, - const std::string &interfaceBlockName, - unsigned int *indexOut); +bool GetUniformBlockRegister(const ShHandle handle, + const std::string &uniformBlockName, + unsigned int *indexOut); -// Gives the compiler-assigned register for uniforms in the default -// interface block. -// The method writes the value to the output variable "indexOut". -// Returns true if it found a valid default uniform, false otherwise. -// Parameters: -// handle: Specifies the compiler -// interfaceBlockName: Specifies the uniform -// indexOut: output variable that stores the assigned register -COMPILER_EXPORT bool ShGetUniformRegister(const ShHandle handle, - const std::string &uniformName, - unsigned int *indexOut); +// Gives a map from uniform names to compiler-assigned registers in the default uniform block. +// Note that the map contains also registers of samplers that have been extracted from structs. +const std::map *GetUniformRegisterMap(const ShHandle handle); + +GLenum GetGeometryShaderInputPrimitiveType(const ShHandle handle); +GLenum GetGeometryShaderOutputPrimitiveType(const ShHandle handle); +int GetGeometryShaderInvocations(const ShHandle handle); +int GetGeometryShaderMaxVertices(const ShHandle handle); + +} // namespace sh #endif // GLSLANG_SHADERLANG_H_ diff --git a/src/3rdparty/angle/include/GLSLANG/ShaderVars.h b/src/3rdparty/angle/include/GLSLANG/ShaderVars.h index af9b65b7f5..709428aebf 100644 --- a/src/3rdparty/angle/include/GLSLANG/ShaderVars.h +++ b/src/3rdparty/angle/include/GLSLANG/ShaderVars.h @@ -10,15 +10,18 @@ #ifndef GLSLANG_SHADERVARS_H_ #define GLSLANG_SHADERVARS_H_ +#include +#include #include #include -#include -// Assume ShaderLang.h is included before ShaderVars.h, for sh::GLenum -// Note: make sure to increment ANGLE_SH_VERSION when changing ShaderVars.h +// This type is defined here to simplify ANGLE's integration with glslang for SPIRv. +using ShCompileOptions = uint64_t; namespace sh { +// GLenum alias +typedef unsigned int GLenum; // Varying interpolation qualifier, see section 4.3.9 of the ESSL 3.00.4 spec enum InterpolationType @@ -29,30 +32,65 @@ enum InterpolationType }; // Validate link & SSO consistency of interpolation qualifiers -COMPILER_EXPORT bool InterpolationTypesMatch(InterpolationType a, InterpolationType b); +bool InterpolationTypesMatch(InterpolationType a, InterpolationType b); // Uniform block layout qualifier, see section 4.3.8.3 of the ESSL 3.00.4 spec enum BlockLayoutType { BLOCKLAYOUT_STANDARD, + BLOCKLAYOUT_STD140 = BLOCKLAYOUT_STANDARD, + BLOCKLAYOUT_STD430, // Shader storage block layout qualifier BLOCKLAYOUT_PACKED, BLOCKLAYOUT_SHARED }; +// Interface Blocks, see section 4.3.9 of the ESSL 3.10 spec +enum class BlockType +{ + BLOCK_UNIFORM, + BLOCK_BUFFER, + + // Required in OpenGL ES 3.1 extension GL_OES_shader_io_blocks. + // TODO(jiawei.shao@intel.com): add BLOCK_OUT. + BLOCK_IN +}; + // Base class for all variables defined in shaders, including Varyings, Uniforms, etc // Note: we must override the copy constructor and assignment operator so we can // work around excessive GCC binary bloating: // See https://code.google.com/p/angleproject/issues/detail?id=697 -struct COMPILER_EXPORT ShaderVariable +struct ShaderVariable { ShaderVariable(); + ShaderVariable(GLenum typeIn); ShaderVariable(GLenum typeIn, unsigned int arraySizeIn); ~ShaderVariable(); ShaderVariable(const ShaderVariable &other); ShaderVariable &operator=(const ShaderVariable &other); - bool isArray() const { return arraySize > 0; } - unsigned int elementCount() const { return std::max(1u, arraySize); } + bool isArrayOfArrays() const { return arraySizes.size() >= 2u; } + bool isArray() const { return !arraySizes.empty(); } + unsigned int getArraySizeProduct() const; + + // Array size 0 means not an array when passed to or returned from these functions. + // Note that setArraySize() is deprecated and should not be used inside ANGLE. + unsigned int getOutermostArraySize() const { return isArray() ? arraySizes.back() : 0; } + void setArraySize(unsigned int size); + + // Turn this ShaderVariable from an array into a specific element in that array. Will update + // flattenedOffsetInParentArrays. + void indexIntoArray(unsigned int arrayIndex); + + // Get the nth nested array size from the top. Caller is responsible for range checking + // arrayNestingIndex. + unsigned int getNestedArraySize(unsigned int arrayNestingIndex) const; + + // This function should only be used with variables that are of a basic type or an array of a + // basic type. Shader interface variables that are enumerated according to rules in GLES 3.1 + // spec section 7.3.1.1 page 77 are fine. For those variables the return value should match the + // ARRAY_SIZE value that can be queried through the API. + unsigned int getBasicTypeElementCount() const; + bool isStruct() const { return !fields.empty(); } // All of the shader's variables are described using nested data @@ -70,20 +108,32 @@ struct COMPILER_EXPORT ShaderVariable const ShaderVariable **leafVar, std::string* originalFullName) const; - bool isBuiltIn() const { return name.compare(0, 3, "gl_") == 0; } + bool isBuiltIn() const; GLenum type; GLenum precision; std::string name; std::string mappedName; - unsigned int arraySize; + + // Used to make an array type. Outermost array size is stored at the end of the vector. + std::vector arraySizes; + + // Offset of this variable in parent arrays. In case the parent is an array of arrays, the + // offset is outerArrayElement * innerArraySize + innerArrayElement. + // For example, if there's a variable declared as size 3 array of size 4 array of int: + // int a[3][4]; + // then the flattenedOffsetInParentArrays of a[2] would be 2. + // and flattenedOffsetInParentArrays of a[2][1] would be 2*4 + 1 = 9. + unsigned int flattenedOffsetInParentArrays; + bool staticUse; std::vector fields; std::string structName; protected: bool isSameVariableAtLinkTime(const ShaderVariable &other, - bool matchPrecision) const; + bool matchPrecision, + bool matchName) const; bool operator==(const ShaderVariable &other) const; bool operator!=(const ShaderVariable &other) const @@ -92,7 +142,21 @@ struct COMPILER_EXPORT ShaderVariable } }; -struct COMPILER_EXPORT Uniform : public ShaderVariable +// A variable with an integer location to pass back to the GL API: either uniform (can have location +// in GLES3.1+), vertex shader input or fragment shader output. +struct VariableWithLocation : public ShaderVariable +{ + VariableWithLocation(); + ~VariableWithLocation(); + VariableWithLocation(const VariableWithLocation &other); + VariableWithLocation &operator=(const VariableWithLocation &other); + bool operator==(const VariableWithLocation &other) const; + bool operator!=(const VariableWithLocation &other) const { return !operator==(other); } + + int location; +}; + +struct Uniform : public VariableWithLocation { Uniform(); ~Uniform(); @@ -104,28 +168,17 @@ struct COMPILER_EXPORT Uniform : public ShaderVariable return !operator==(other); } + int binding; + int offset; + // Decide whether two uniforms are the same at shader link time, // assuming one from vertex shader and the other from fragment shader. - // See GLSL ES Spec 3.00.3, sec 4.3.5. + // GLSL ES Spec 3.00.3, section 4.3.5. + // GLSL ES Spec 3.10.4, section 4.4.5 bool isSameUniformAtLinkTime(const Uniform &other) const; }; -// An interface variable is a variable which passes data between the GL data structures and the -// shader execution: either vertex shader inputs or fragment shader outputs. These variables can -// have integer locations to pass back to the GL API. -struct COMPILER_EXPORT InterfaceVariable : public ShaderVariable -{ - InterfaceVariable(); - ~InterfaceVariable(); - InterfaceVariable(const InterfaceVariable &other); - InterfaceVariable &operator=(const InterfaceVariable &other); - bool operator==(const InterfaceVariable &other) const; - bool operator!=(const InterfaceVariable &other) const { return !operator==(other); } - - int location; -}; - -struct COMPILER_EXPORT Attribute : public InterfaceVariable +struct Attribute : public VariableWithLocation { Attribute(); ~Attribute(); @@ -135,7 +188,7 @@ struct COMPILER_EXPORT Attribute : public InterfaceVariable bool operator!=(const Attribute &other) const { return !operator==(other); } }; -struct COMPILER_EXPORT OutputVariable : public InterfaceVariable +struct OutputVariable : public VariableWithLocation { OutputVariable(); ~OutputVariable(); @@ -145,7 +198,7 @@ struct COMPILER_EXPORT OutputVariable : public InterfaceVariable bool operator!=(const OutputVariable &other) const { return !operator==(other); } }; -struct COMPILER_EXPORT InterfaceBlockField : public ShaderVariable +struct InterfaceBlockField : public ShaderVariable { InterfaceBlockField(); ~InterfaceBlockField(); @@ -167,7 +220,7 @@ struct COMPILER_EXPORT InterfaceBlockField : public ShaderVariable bool isRowMajorLayout; }; -struct COMPILER_EXPORT Varying : public ShaderVariable +struct Varying : public VariableWithLocation { Varying(); ~Varying(); @@ -193,7 +246,7 @@ struct COMPILER_EXPORT Varying : public ShaderVariable bool isInvariant; }; -struct COMPILER_EXPORT InterfaceBlock +struct InterfaceBlock { InterfaceBlock(); ~InterfaceBlock(); @@ -202,6 +255,15 @@ struct COMPILER_EXPORT InterfaceBlock // Fields from blocks with non-empty instance names are prefixed with the block name. std::string fieldPrefix() const; + std::string fieldMappedPrefix() const; + + // Decide whether two interface blocks are the same at shader link time. + bool isSameInterfaceBlockAtLinkTime(const InterfaceBlock &other) const; + + bool isBuiltIn() const; + + bool isArray() const { return arraySize > 0; } + unsigned int elementCount() const { return std::max(1u, arraySize); } std::string name; std::string mappedName; @@ -209,10 +271,45 @@ struct COMPILER_EXPORT InterfaceBlock unsigned int arraySize; BlockLayoutType layout; bool isRowMajorLayout; + int binding; bool staticUse; + BlockType blockType; std::vector fields; }; +struct WorkGroupSize +{ + // Must have a trivial default constructor since it is used in YYSTYPE. + WorkGroupSize() = default; + explicit constexpr WorkGroupSize(int initialSize) + : localSizeQualifiers{initialSize, initialSize, initialSize} + { + } + + void fill(int fillValue); + void setLocalSize(int localSizeX, int localSizeY, int localSizeZ); + + int &operator[](size_t index); + int operator[](size_t index) const; + size_t size() const; + + // Checks whether two work group size declarations match. + // Two work group size declarations are the same if the explicitly specified elements are the + // same or if one of them is specified as one and the other one is not specified + bool isWorkGroupSizeMatching(const WorkGroupSize &right) const; + + // Checks whether any of the values are set. + bool isAnyValueSet() const; + + // Checks whether all of the values are set. + bool isDeclared() const; + + // Checks whether either all of the values are set, or none of them are. + bool isLocalSizeValid() const; + + std::array localSizeQualifiers; +}; + } // namespace sh #endif // GLSLANG_SHADERVARS_H_ diff --git a/src/3rdparty/angle/include/KHR/khrplatform.h b/src/3rdparty/angle/include/KHR/khrplatform.h index c9e6f17d34..68fca48271 100644 --- a/src/3rdparty/angle/include/KHR/khrplatform.h +++ b/src/3rdparty/angle/include/KHR/khrplatform.h @@ -26,7 +26,7 @@ /* Khronos platform-specific types and definitions. * - * $Revision: 23298 $ on $Date: 2013-09-30 17:07:13 -0700 (Mon, 30 Sep 2013) $ + * $Revision: 32517 $ on $Date: 2016-03-11 02:41:19 -0800 (Fri, 11 Mar 2016) $ * * Adopters may modify this file to suit their platform. Adopters are * encouraged to submit platform specific modifications to the Khronos @@ -101,6 +101,9 @@ # define KHRONOS_APICALL __declspec(dllimport) #elif defined (__SYMBIAN32__) # define KHRONOS_APICALL IMPORT_C +#elif defined(__ANDROID__) +# include +# define KHRONOS_APICALL __attribute__((visibility("default"))) __NDK_FPABI__ #else # define KHRONOS_APICALL #endif @@ -223,7 +226,7 @@ typedef signed short int khronos_int16_t; typedef unsigned short int khronos_uint16_t; /* - * Types that differ between LLP64 and LP64 architectures - in LLP64, + * Types that differ between LLP64 and LP64 architectures - in LLP64, * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears * to be the only LLP64 architecture in current use. */ @@ -279,4 +282,4 @@ typedef enum { KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM } khronos_boolean_enum_t; -#endif /* __khrplatform_h_ */ +#endif /* __khrplatform_h_ */ \ No newline at end of file diff --git a/src/3rdparty/angle/include/angle_gl.h b/src/3rdparty/angle/include/angle_gl.h index 18de80b60b..b70a31c273 100644 --- a/src/3rdparty/angle/include/angle_gl.h +++ b/src/3rdparty/angle/include/angle_gl.h @@ -16,9 +16,4 @@ #include "GLES3/gl31.h" #include "GLES3/gl32.h" -// The following enum is used in ANGLE, but is from desktop GL -#ifndef GL_SAMPLER_2D_RECT_ARB -#define GL_SAMPLER_2D_RECT_ARB 0x8B63 -#endif - #endif // ANGLEGL_H_ diff --git a/src/3rdparty/angle/include/export.h b/src/3rdparty/angle/include/export.h index cdf6245d6d..cf144f92a5 100644 --- a/src/3rdparty/angle/include/export.h +++ b/src/3rdparty/angle/include/export.h @@ -9,14 +9,17 @@ #ifndef LIBGLESV2_EXPORT_H_ #define LIBGLESV2_EXPORT_H_ +#if !defined(ANGLE_EXPORT) #if defined(_WIN32) -# if defined(LIBGLESV2_IMPLEMENTATION) || defined(LIBANGLE_IMPLEMENTATION) +#if defined(LIBGLESV2_IMPLEMENTATION) || defined(LIBANGLE_IMPLEMENTATION) || \ + defined(LIBANGLE_UTIL_IMPLEMENTATION) # define ANGLE_EXPORT __declspec(dllexport) # else # define ANGLE_EXPORT __declspec(dllimport) # endif #elif defined(__GNUC__) -# if defined(LIBGLESV2_IMPLEMENTATION) || defined(LIBANGLE_IMPLEMENTATION) +#if defined(LIBGLESV2_IMPLEMENTATION) || defined(LIBANGLE_IMPLEMENTATION) || \ + defined(LIBANGLE_UTIL_IMPLEMENTATION) # define ANGLE_EXPORT __attribute__((visibility ("default"))) # else # define ANGLE_EXPORT @@ -24,5 +27,6 @@ #else # define ANGLE_EXPORT #endif +#endif // !defined(ANGLE_EXPORT) #endif // LIBGLESV2_EXPORT_H_ diff --git a/src/3rdparty/angle/include/platform/Platform.h b/src/3rdparty/angle/include/platform/Platform.h index 0e8cdf477f..aa1221a86e 100644 --- a/src/3rdparty/angle/include/platform/Platform.h +++ b/src/3rdparty/angle/include/platform/Platform.h @@ -10,15 +10,16 @@ #define ANGLE_PLATFORM_H #include +#include #if defined(_WIN32) # if !defined(LIBANGLE_IMPLEMENTATION) # define ANGLE_PLATFORM_EXPORT __declspec(dllimport) +# else +# define ANGLE_PLATFORM_EXPORT __declspec(dllexport) # endif -#elif defined(__GNUC__) -# if defined(LIBANGLE_IMPLEMENTATION) -# define ANGLE_PLATFORM_EXPORT __attribute__((visibility ("default"))) -# endif +#elif defined(__GNUC__) || defined(__clang__) +# define ANGLE_PLATFORM_EXPORT __attribute__((visibility ("default"))) #endif #if !defined(ANGLE_PLATFORM_EXPORT) # define ANGLE_PLATFORM_EXPORT @@ -32,137 +33,295 @@ namespace angle { +struct WorkaroundsD3D; +using TraceEventHandle = uint64_t; +using EGLDisplayType = void *; +struct PlatformMethods; -class Platform +// Use a C-like API to not trigger undefined calling behaviour. +// Avoid using decltype here to work around sanitizer limitations. +// TODO(jmadill): Use decltype here if/when UBSAN is fixed. + +// System -------------------------------------------------------------- + +// Wall clock time in seconds since the epoch. +// TODO(jmadill): investigate using an ANGLE internal time library +using CurrentTimeFunc = double (*)(PlatformMethods *platform); +inline double DefaultCurrentTime(PlatformMethods *platform) { - public: + return 0.0; +} - // System -------------------------------------------------------------- +// Monotonically increasing time in seconds from an arbitrary fixed point in the past. +// This function is expected to return at least millisecond-precision values. For this reason, +// it is recommended that the fixed point be no further in the past than the epoch. +using MonotonicallyIncreasingTimeFunc = double (*)(PlatformMethods *platform); +inline double DefaultMonotonicallyIncreasingTime(PlatformMethods *platform) +{ + return 0.0; +} - // Wall clock time in seconds since the epoch. - // TODO(jmadill): investigate using an ANGLE internal time library - virtual double currentTime() { return 0; } +// Logging ------------------------------------------------------------ - // Monotonically increasing time in seconds from an arbitrary fixed point in the past. - // This function is expected to return at least millisecond-precision values. For this reason, - // it is recommended that the fixed point be no further in the past than the epoch. - virtual double monotonicallyIncreasingTime() { return 0; } +// Log an error message within the platform implementation. +using LogErrorFunc = void (*)(PlatformMethods *platform, const char *errorMessage); +inline void DefaultLogError(PlatformMethods *platform, const char *errorMessage) +{ +} - // Logging ------------------------------------------------------------ +// Log a warning message within the platform implementation. +using LogWarningFunc = void (*)(PlatformMethods *platform, const char *warningMessage); +inline void DefaultLogWarning(PlatformMethods *platform, const char *warningMessage) +{ +} - // Log an error message within the platform implementation. - virtual void logError(const char *errorMessage) {} +// Log an info message within the platform implementation. +using LogInfoFunc = void (*)(PlatformMethods *platform, const char *infoMessage); +inline void DefaultLogInfo(PlatformMethods *platform, const char *infoMessage) +{ +} - // Log a warning message within the platform implementation. - virtual void logWarning(const char *warningMessage) {} +// Tracing -------- - // Log an info message within the platform implementation. - virtual void logInfo(const char *infoMessage) {} +// Get a pointer to the enabled state of the given trace category. The +// embedder can dynamically change the enabled state as trace event +// recording is started and stopped by the application. Only long-lived +// literal strings should be given as the category name. The implementation +// expects the returned pointer to be held permanently in a local static. If +// the unsigned char is non-zero, tracing is enabled. If tracing is enabled, +// addTraceEvent is expected to be called by the trace event macros. +using GetTraceCategoryEnabledFlagFunc = const unsigned char *(*)(PlatformMethods *platform, + const char *categoryName); +inline const unsigned char *DefaultGetTraceCategoryEnabledFlag(PlatformMethods *platform, + const char *categoryName) +{ + return nullptr; +} - // Tracing -------- +// +// Add a trace event to the platform tracing system. Depending on the actual +// enabled state, this event may be recorded or dropped. +// - phase specifies the type of event: +// - BEGIN ('B'): Marks the beginning of a scoped event. +// - END ('E'): Marks the end of a scoped event. +// - COMPLETE ('X'): Marks the beginning of a scoped event, but doesn't +// need a matching END event. Instead, at the end of the scope, +// updateTraceEventDuration() must be called with the TraceEventHandle +// returned from addTraceEvent(). +// - INSTANT ('I'): Standalone, instantaneous event. +// - START ('S'): Marks the beginning of an asynchronous event (the end +// event can occur in a different scope or thread). The id parameter is +// used to match START/FINISH pairs. +// - FINISH ('F'): Marks the end of an asynchronous event. +// - COUNTER ('C'): Used to trace integer quantities that change over +// time. The argument values are expected to be of type int. +// - METADATA ('M'): Reserved for internal use. +// - categoryEnabled is the pointer returned by getTraceCategoryEnabledFlag. +// - name is the name of the event. Also used to match BEGIN/END and +// START/FINISH pairs. +// - id optionally allows events of the same name to be distinguished from +// each other. For example, to trace the consutruction and destruction of +// objects, specify the pointer as the id parameter. +// - timestamp should be a time value returned from monotonicallyIncreasingTime. +// - numArgs specifies the number of elements in argNames, argTypes, and +// argValues. +// - argNames is the array of argument names. Use long-lived literal strings +// or specify the COPY flag. +// - argTypes is the array of argument types: +// - BOOL (1): bool +// - UINT (2): unsigned long long +// - INT (3): long long +// - DOUBLE (4): double +// - POINTER (5): void* +// - STRING (6): char* (long-lived null-terminated char* string) +// - COPY_STRING (7): char* (temporary null-terminated char* string) +// - CONVERTABLE (8): WebConvertableToTraceFormat +// - argValues is the array of argument values. Each value is the unsigned +// long long member of a union of all supported types. +// - flags can be 0 or one or more of the following, ORed together: +// - COPY (0x1): treat all strings (name, argNames and argValues of type +// string) as temporary so that they will be copied by addTraceEvent. +// - HAS_ID (0x2): use the id argument to uniquely identify the event for +// matching with other events of the same name. +// - MANGLE_ID (0x4): specify this flag if the id parameter is the value +// of a pointer. +using AddTraceEventFunc = angle::TraceEventHandle (*)(PlatformMethods *platform, + char phase, + const unsigned char *categoryEnabledFlag, + const char *name, + unsigned long long id, + double timestamp, + int numArgs, + const char **argNames, + const unsigned char *argTypes, + const unsigned long long *argValues, + unsigned char flags); +inline angle::TraceEventHandle DefaultAddTraceEvent(PlatformMethods *platform, + char phase, + const unsigned char *categoryEnabledFlag, + const char *name, + unsigned long long id, + double timestamp, + int numArgs, + const char **argNames, + const unsigned char *argTypes, + const unsigned long long *argValues, + unsigned char flags) +{ + return 0; +} - // Get a pointer to the enabled state of the given trace category. The - // embedder can dynamically change the enabled state as trace event - // recording is started and stopped by the application. Only long-lived - // literal strings should be given as the category name. The implementation - // expects the returned pointer to be held permanently in a local static. If - // the unsigned char is non-zero, tracing is enabled. If tracing is enabled, - // addTraceEvent is expected to be called by the trace event macros. - virtual const unsigned char *getTraceCategoryEnabledFlag(const char *categoryName) { return 0; } +// Set the duration field of a COMPLETE trace event. +using UpdateTraceEventDurationFunc = void (*)(PlatformMethods *platform, + const unsigned char *categoryEnabledFlag, + const char *name, + angle::TraceEventHandle eventHandle); +inline void DefaultUpdateTraceEventDuration(PlatformMethods *platform, + const unsigned char *categoryEnabledFlag, + const char *name, + angle::TraceEventHandle eventHandle) +{ +} - typedef uint64_t TraceEventHandle; - - // Add a trace event to the platform tracing system. Depending on the actual - // enabled state, this event may be recorded or dropped. - // - phase specifies the type of event: - // - BEGIN ('B'): Marks the beginning of a scoped event. - // - END ('E'): Marks the end of a scoped event. - // - COMPLETE ('X'): Marks the beginning of a scoped event, but doesn't - // need a matching END event. Instead, at the end of the scope, - // updateTraceEventDuration() must be called with the TraceEventHandle - // returned from addTraceEvent(). - // - INSTANT ('I'): Standalone, instantaneous event. - // - START ('S'): Marks the beginning of an asynchronous event (the end - // event can occur in a different scope or thread). The id parameter is - // used to match START/FINISH pairs. - // - FINISH ('F'): Marks the end of an asynchronous event. - // - COUNTER ('C'): Used to trace integer quantities that change over - // time. The argument values are expected to be of type int. - // - METADATA ('M'): Reserved for internal use. - // - categoryEnabled is the pointer returned by getTraceCategoryEnabledFlag. - // - name is the name of the event. Also used to match BEGIN/END and - // START/FINISH pairs. - // - id optionally allows events of the same name to be distinguished from - // each other. For example, to trace the consutruction and destruction of - // objects, specify the pointer as the id parameter. - // - timestamp should be a time value returned from monotonicallyIncreasingTime. - // - numArgs specifies the number of elements in argNames, argTypes, and - // argValues. - // - argNames is the array of argument names. Use long-lived literal strings - // or specify the COPY flag. - // - argTypes is the array of argument types: - // - BOOL (1): bool - // - UINT (2): unsigned long long - // - INT (3): long long - // - DOUBLE (4): double - // - POINTER (5): void* - // - STRING (6): char* (long-lived null-terminated char* string) - // - COPY_STRING (7): char* (temporary null-terminated char* string) - // - CONVERTABLE (8): WebConvertableToTraceFormat - // - argValues is the array of argument values. Each value is the unsigned - // long long member of a union of all supported types. - // - flags can be 0 or one or more of the following, ORed together: - // - COPY (0x1): treat all strings (name, argNames and argValues of type - // string) as temporary so that they will be copied by addTraceEvent. - // - HAS_ID (0x2): use the id argument to uniquely identify the event for - // matching with other events of the same name. - // - MANGLE_ID (0x4): specify this flag if the id parameter is the value - // of a pointer. - virtual TraceEventHandle addTraceEvent(char phase, - const unsigned char *categoryEnabledFlag, +// Callbacks for reporting histogram data. +// CustomCounts histogram has exponential bucket sizes, so that min=1, max=1000000, bucketCount=50 +// would do. +using HistogramCustomCountsFunc = void (*)(PlatformMethods *platform, const char *name, - unsigned long long id, - double timestamp, - int numArgs, - const char **argNames, - const unsigned char *argTypes, - const unsigned long long *argValues, - unsigned char flags) - { - return 0; - } + int sample, + int min, + int max, + int bucketCount); +inline void DefaultHistogramCustomCounts(PlatformMethods *platform, + const char *name, + int sample, + int min, + int max, + int bucketCount) +{ +} +// Enumeration histogram buckets are linear, boundaryValue should be larger than any possible sample +// value. +using HistogramEnumerationFunc = void (*)(PlatformMethods *platform, + const char *name, + int sample, + int boundaryValue); +inline void DefaultHistogramEnumeration(PlatformMethods *platform, + const char *name, + int sample, + int boundaryValue) +{ +} +// Unlike enumeration histograms, sparse histograms only allocate memory for non-empty buckets. +using HistogramSparseFunc = void (*)(PlatformMethods *platform, const char *name, int sample); +inline void DefaultHistogramSparse(PlatformMethods *platform, const char *name, int sample) +{ +} +// Boolean histograms track two-state variables. +using HistogramBooleanFunc = void (*)(PlatformMethods *platform, const char *name, bool sample); +inline void DefaultHistogramBoolean(PlatformMethods *platform, const char *name, bool sample) +{ +} - // Set the duration field of a COMPLETE trace event. - virtual void updateTraceEventDuration(const unsigned char *categoryEnabledFlag, const char *name, TraceEventHandle eventHandle) { } +// Allows us to programatically override ANGLE's default workarounds for testing purposes. +using OverrideWorkaroundsD3DFunc = void (*)(PlatformMethods *platform, + angle::WorkaroundsD3D *workaroundsD3D); +inline void DefaultOverrideWorkaroundsD3D(PlatformMethods *platform, + angle::WorkaroundsD3D *workaroundsD3D) +{ +} - // Callbacks for reporting histogram data. - // CustomCounts histogram has exponential bucket sizes, so that min=1, max=1000000, bucketCount=50 would do. - virtual void histogramCustomCounts(const char *name, int sample, int min, int max, int bucketCount) { } - // Enumeration histogram buckets are linear, boundaryValue should be larger than any possible sample value. - virtual void histogramEnumeration(const char *name, int sample, int boundaryValue) { } - // Unlike enumeration histograms, sparse histograms only allocate memory for non-empty buckets. - virtual void histogramSparse(const char *name, int sample) { } - // Boolean histograms track two-state variables. - virtual void histogramBoolean(const char *name, bool sample) { } +// Callback on a successful program link with the program binary. Can be used to store +// shaders to disk. Keys are a 160-bit SHA-1 hash. +using ProgramKeyType = std::array; +using CacheProgramFunc = void (*)(PlatformMethods *platform, + const ProgramKeyType &key, + size_t programSize, + const uint8_t *programBytes); +inline void DefaultCacheProgram(PlatformMethods *platform, + const ProgramKeyType &key, + size_t programSize, + const uint8_t *programBytes) +{ +} - protected: - virtual ~Platform() { } +// Platform methods are enumerated here once. +#define ANGLE_PLATFORM_OP(OP) \ + OP(currentTime, CurrentTime) \ + OP(monotonicallyIncreasingTime, MonotonicallyIncreasingTime) \ + OP(logError, LogError) \ + OP(logWarning, LogWarning) \ + OP(logInfo, LogInfo) \ + OP(getTraceCategoryEnabledFlag, GetTraceCategoryEnabledFlag) \ + OP(addTraceEvent, AddTraceEvent) \ + OP(updateTraceEventDuration, UpdateTraceEventDuration) \ + OP(histogramCustomCounts, HistogramCustomCounts) \ + OP(histogramEnumeration, HistogramEnumeration) \ + OP(histogramSparse, HistogramSparse) \ + OP(histogramBoolean, HistogramBoolean) \ + OP(overrideWorkaroundsD3D, OverrideWorkaroundsD3D) \ + OP(cacheProgram, CacheProgram) + +#define ANGLE_PLATFORM_METHOD_DEF(Name, CapsName) CapsName##Func Name = Default##CapsName; + +struct ANGLE_PLATFORM_EXPORT PlatformMethods +{ + PlatformMethods(); + + // User data pointer for any implementation specific members. Put it at the start of the + // platform structure so it doesn't become overwritten if one version of the platform + // adds or removes new members. + void *context = 0; + + ANGLE_PLATFORM_OP(ANGLE_PLATFORM_METHOD_DEF); }; -} +#undef ANGLE_PLATFORM_METHOD_DEF -extern "C" +// Subtract one to account for the context pointer. +constexpr unsigned int g_NumPlatformMethods = (sizeof(PlatformMethods) / sizeof(uintptr_t)) - 1; + +#define ANGLE_PLATFORM_METHOD_STRING(Name) #Name +#define ANGLE_PLATFORM_METHOD_STRING2(Name, CapsName) ANGLE_PLATFORM_METHOD_STRING(Name), + +constexpr const char *const g_PlatformMethodNames[g_NumPlatformMethods] = { + ANGLE_PLATFORM_OP(ANGLE_PLATFORM_METHOD_STRING2)}; + +#undef ANGLE_PLATFORM_METHOD_STRING2 +#undef ANGLE_PLATFORM_METHOD_STRING + +} // namespace angle + +extern "C" { + +// Gets the platform methods on the passed-in EGL display. If the method name signature does not +// match the compiled signature for this ANGLE, false is returned. On success true is returned. +// The application should set any platform methods it cares about on the returned pointer. +// If display is not valid, behaviour is undefined. + +ANGLE_PLATFORM_EXPORT bool ANGLE_APIENTRY ANGLEGetDisplayPlatform(angle::EGLDisplayType display, + const char *const methodNames[], + unsigned int methodNameCount, + void *context, + void *platformMethodsOut); + +// Sets the platform methods back to their defaults. +// If display is not valid, behaviour is undefined. +ANGLE_PLATFORM_EXPORT void ANGLE_APIENTRY ANGLEResetDisplayPlatform(angle::EGLDisplayType display); + +} // extern "C" + +namespace angle { +typedef bool(ANGLE_APIENTRY *GetDisplayPlatformFunc)(angle::EGLDisplayType, + const char *const *, + unsigned int, + void *, + void *); +typedef void(ANGLE_APIENTRY *ResetDisplayPlatformFunc)(angle::EGLDisplayType); +} // namespace angle -typedef void (ANGLE_APIENTRY *ANGLEPlatformInitializeFunc)(angle::Platform*); -ANGLE_PLATFORM_EXPORT void ANGLE_APIENTRY ANGLEPlatformInitialize(angle::Platform*); - -typedef void (ANGLE_APIENTRY *ANGLEPlatformShutdownFunc)(); -ANGLE_PLATFORM_EXPORT void ANGLE_APIENTRY ANGLEPlatformShutdown(); - -typedef angle::Platform *(ANGLE_APIENTRY *ANGLEPlatformCurrentFunc)(); -ANGLE_PLATFORM_EXPORT angle::Platform *ANGLE_APIENTRY ANGLEPlatformCurrent(); - -} +// This function is not exported +angle::PlatformMethods *ANGLEPlatformCurrent(); #endif // ANGLE_PLATFORM_H diff --git a/src/3rdparty/angle/include/platform/WorkaroundsD3D.h b/src/3rdparty/angle/include/platform/WorkaroundsD3D.h new file mode 100644 index 0000000000..cc2abbf1d2 --- /dev/null +++ b/src/3rdparty/angle/include/platform/WorkaroundsD3D.h @@ -0,0 +1,130 @@ +// +// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// WorkaroundsD3D.h: Workarounds for D3D driver bugs and other issues. + +#ifndef ANGLE_PLATFORM_WORKAROUNDSD3D_H_ +#define ANGLE_PLATFORM_WORKAROUNDSD3D_H_ + +// TODO(jmadill,zmo,geofflang): make a workarounds library that can operate +// independent of ANGLE's renderer. Workarounds should also be accessible +// outside of the Renderer. + +namespace angle +{ +struct CompilerWorkaroundsD3D +{ + bool skipOptimization = false; + bool useMaxOptimization = false; + + // IEEE strictness needs to be enabled for NANs to work. + bool enableIEEEStrictness = false; +}; + +struct WorkaroundsD3D +{ + // On some systems, having extra rendertargets than necessary slows down the shader. + // We can fix this by optimizing those out of the shader. At the same time, we can + // work around a bug on some nVidia drivers that they ignore "null" render targets + // in D3D11, by compacting the active color attachments list to omit null entries. + bool mrtPerfWorkaround = false; + + bool setDataFasterThanImageUpload = false; + + // Some renderers can't disable mipmaps on a mipmapped texture (i.e. solely sample from level + // zero, and ignore the other levels). D3D11 Feature Level 10+ does this by setting MaxLOD to + // 0.0f in the Sampler state. D3D9 sets D3DSAMP_MIPFILTER to D3DTEXF_NONE. There is no + // equivalent to this in D3D11 Feature Level 9_3. This causes problems when (for example) an + // application creates a mipmapped texture2D, but sets GL_TEXTURE_MIN_FILTER to GL_NEAREST + // (i.e disables mipmaps). To work around this, D3D11 FL9_3 has to create two copies of the + // texture. The textures' level zeros are identical, but only one texture has mips. + bool zeroMaxLodWorkaround = false; + + // Some renderers do not support Geometry Shaders so the Geometry Shader-based PointSprite + // emulation will not work. To work around this, D3D11 FL9_3 has to use a different pointsprite + // emulation that is implemented using instanced quads. + bool useInstancedPointSpriteEmulation = false; + + // A bug fixed in NVIDIA driver version 347.88 < x <= 368.81 triggers a TDR when using + // CopySubresourceRegion from a staging texture to a depth/stencil in D3D11. The workaround + // is to use UpdateSubresource to trigger an extra copy. We disable this workaround on newer + // NVIDIA driver versions because of a second driver bug present with the workaround enabled. + // (See: http://anglebug.com/1452) + bool depthStencilBlitExtraCopy = false; + + // The HLSL optimizer has a bug with optimizing "pow" in certain integer-valued expressions. + // We can work around this by expanding the pow into a series of multiplies if we're running + // under the affected compiler. + bool expandIntegerPowExpressions = false; + + // NVIDIA drivers sometimes write out-of-order results to StreamOut buffers when transform + // feedback is used to repeatedly write to the same buffer positions. + bool flushAfterEndingTransformFeedback = false; + + // Some drivers (NVIDIA) do not take into account the base level of the texture in the results + // of the HLSL GetDimensions builtin. + bool getDimensionsIgnoresBaseLevel = false; + + // On some Intel drivers, HLSL's function texture.Load returns 0 when the parameter Location + // is negative, even if the sum of Offset and Location is in range. This may cause errors when + // translating GLSL's function texelFetchOffset into texture.Load, as it is valid for + // texelFetchOffset to use negative texture coordinates as its parameter P when the sum of P + // and Offset is in range. To work around this, we translate texelFetchOffset into texelFetch + // by adding Offset directly to Location before reading the texture. + bool preAddTexelFetchOffsets = false; + + // On some AMD drivers, 1x1 and 2x2 mips of depth/stencil textures aren't sampled correctly. + // We can work around this bug by doing an internal blit to a temporary single-channel texture + // before we sample. + bool emulateTinyStencilTextures = false; + + // In Intel driver, the data with format DXGI_FORMAT_B5G6R5_UNORM will be parsed incorrectly. + // This workaroud will disable B5G6R5 support when it's Intel driver. By default, it will use + // R8G8B8A8 format. This bug is fixed in version 4539 on Intel drivers. + bool disableB5G6R5Support = false; + + // On some Intel drivers, evaluating unary minus operator on integer may get wrong answer in + // vertex shaders. To work around this bug, we translate -(int) into ~(int)+1. + // This driver bug is fixed in 20.19.15.4624. + bool rewriteUnaryMinusOperator = false; + + // On some Intel drivers, using isnan() on highp float will get wrong answer. To work around + // this bug, we use an expression to emulate function isnan(). + // Tracking bug: https://crbug.com/650547 + // This driver bug is fixed in 21.20.16.4542. + bool emulateIsnanFloat = false; + + // On some Intel drivers, using clear() may not take effect. To work around this bug, we call + // clear() twice on these platforms. + // Tracking bug: https://crbug.com/655534 + bool callClearTwice = false; + + // On some Intel drivers, copying from staging storage to constant buffer storage does not + // seem to work. Work around this by keeping system memory storage as a canonical reference + // for buffer data. + // D3D11-only workaround. See http://crbug.com/593024. + bool useSystemMemoryForConstantBuffers = false; + + // This workaround is for the ANGLE_multiview extension. If enabled the viewport or render + // target slice will be selected in the geometry shader stage. The workaround flag is added to + // make it possible to select the code path in end2end and performance tests. + bool selectViewInGeometryShader = false; + + // When rendering with no render target on D3D, two bugs lead to incorrect behavior on Intel + // drivers < 4815. The rendering samples always pass neglecting discard statements in pixel + // shader. + // 1. If rendertarget is not set, the pixel shader will be recompiled to drop 'SV_TARGET'. + // When using a pixel shader with no 'SV_TARGET' in a draw, the pixels are always generated even + // if they should be discard by 'discard' statements. + // 2. If ID3D11BlendState.RenderTarget[].RenderTargetWriteMask is 0 and rendertarget is not set, + // then rendering samples also pass neglecting discard statements in pixel shader. + // So we add a dummy texture as render target in such case. See http://anglebug.com/2152 + bool addDummyTextureNoRenderTarget = false; +}; + +} // namespace angle + +#endif // ANGLE_PLATFORM_WORKAROUNDSD3D_H_ diff --git a/src/3rdparty/angle/src/common/BitSetIterator.h b/src/3rdparty/angle/src/common/BitSetIterator.h deleted file mode 100644 index 3248ce44c9..0000000000 --- a/src/3rdparty/angle/src/common/BitSetIterator.h +++ /dev/null @@ -1,156 +0,0 @@ -// -// Copyright 2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// BitSetIterator: -// A helper class to quickly bitscan bitsets for set bits. -// - -#ifndef COMMON_BITSETITERATOR_H_ -#define COMMON_BITSETITERATOR_H_ - -#include - -#include - -#include "common/angleutils.h" -#include "common/debug.h" -#include "common/mathutil.h" -#include "common/platform.h" - -namespace angle -{ -template -class BitSetIterator final -{ - public: - BitSetIterator(const std::bitset &bitset); - BitSetIterator(const BitSetIterator &other); - BitSetIterator &operator=(const BitSetIterator &other); - - class Iterator final - { - public: - Iterator(const std::bitset &bits); - Iterator &operator++(); - - bool operator==(const Iterator &other) const; - bool operator!=(const Iterator &other) const; - unsigned long operator*() const { return mCurrentBit; } - - private: - unsigned long getNextBit(); - - static const size_t BitsPerWord = sizeof(unsigned long) * 8; - std::bitset mBits; - unsigned long mCurrentBit; - unsigned long mOffset; - }; - - Iterator begin() const { return Iterator(mBits); } - Iterator end() const { return Iterator(std::bitset(0)); } - - private: - const std::bitset mBits; -}; - -template -BitSetIterator::BitSetIterator(const std::bitset &bitset) - : mBits(bitset) -{ -} - -template -BitSetIterator::BitSetIterator(const BitSetIterator &other) - : mBits(other.mBits) -{ -} - -template -BitSetIterator &BitSetIterator::operator=(const BitSetIterator &other) -{ - mBits = other.mBits; - return *this; -} - -template -BitSetIterator::Iterator::Iterator(const std::bitset &bits) - : mBits(bits), mCurrentBit(0), mOffset(0) -{ - if (bits.any()) - { - mCurrentBit = getNextBit(); - } - else - { - mOffset = static_cast(rx::roundUp(N, BitsPerWord)); - } -} - -template -typename BitSetIterator::Iterator &BitSetIterator::Iterator::operator++() -{ - ASSERT(mBits.any()); - mBits.set(mCurrentBit - mOffset, 0); - mCurrentBit = getNextBit(); - return *this; -} - -inline unsigned long ScanForward(unsigned long bits) -{ - ASSERT(bits != 0); -#if defined(ANGLE_PLATFORM_WINDOWS) - unsigned long firstBitIndex = 0ul; - unsigned char ret = _BitScanForward(&firstBitIndex, bits); - ASSERT(ret != 0); - UNUSED_ASSERTION_VARIABLE(ret); - return firstBitIndex; -#elif defined(ANGLE_PLATFORM_POSIX) - return static_cast(__builtin_ctzl(bits)); -#else -#error Please implement bit-scan-forward for your platform! -#endif -} - -template -bool BitSetIterator::Iterator::operator==(const Iterator &other) const -{ - return mOffset == other.mOffset && mBits == other.mBits; -} - -template -bool BitSetIterator::Iterator::operator!=(const Iterator &other) const -{ - return !(*this == other); -} - -template -unsigned long BitSetIterator::Iterator::getNextBit() -{ - static std::bitset wordMask(std::numeric_limits::max()); - - while (mOffset < N) - { - unsigned long wordBits = (mBits & wordMask).to_ulong(); - if (wordBits != 0ul) - { - return ScanForward(wordBits) + mOffset; - } - - mBits >>= BitsPerWord; - mOffset += BitsPerWord; - } - return 0; -} - -// Helper to avoid needing to specify the template parameter size -template -BitSetIterator IterateBitSet(const std::bitset &bitset) -{ - return BitSetIterator(bitset); -} - -} // angle - -#endif // COMMON_BITSETITERATOR_H_ diff --git a/src/3rdparty/angle/src/common/Color.h b/src/3rdparty/angle/src/common/Color.h new file mode 100644 index 0000000000..2b4d2f6fba --- /dev/null +++ b/src/3rdparty/angle/src/common/Color.h @@ -0,0 +1,53 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Color.h : Defines the Color type used throughout the ANGLE libraries + +#ifndef COMMON_COLOR_H_ +#define COMMON_COLOR_H_ + +namespace angle +{ + +template +struct Color +{ + T red; + T green; + T blue; + T alpha; + + Color(); + Color(T r, T g, T b, T a); +}; + +template +bool operator==(const Color &a, const Color &b); + +template +bool operator!=(const Color &a, const Color &b); + +typedef Color ColorF; +typedef Color ColorI; +typedef Color ColorUI; + +} // namespace angle + +// TODO: Move this fully into the angle namespace +namespace gl +{ + +template +using Color = angle::Color; +using ColorF = angle::ColorF; +using ColorI = angle::ColorI; +using ColorUI = angle::ColorUI; + +} // namespace gl + +#include "Color.inl" + +#endif // COMMON_COLOR_H_ diff --git a/src/3rdparty/angle/src/common/Color.inl b/src/3rdparty/angle/src/common/Color.inl new file mode 100644 index 0000000000..c3073256b5 --- /dev/null +++ b/src/3rdparty/angle/src/common/Color.inl @@ -0,0 +1,37 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Color.inl : Inline definitions of some functions from Color.h + +namespace angle +{ + +template +Color::Color() : Color(0, 0, 0, 0) +{ +} + +template +Color::Color(T r, T g, T b, T a) : red(r), green(g), blue(b), alpha(a) +{ +} + +template +bool operator==(const Color &a, const Color &b) +{ + return a.red == b.red && + a.green == b.green && + a.blue == b.blue && + a.alpha == b.alpha; +} + +template +bool operator!=(const Color &a, const Color &b) +{ + return !(a == b); +} + +} // namespace angle diff --git a/src/3rdparty/angle/src/common/MemoryBuffer.cpp b/src/3rdparty/angle/src/common/MemoryBuffer.cpp index e7a3fb4a2b..6f5188c69c 100644 --- a/src/3rdparty/angle/src/common/MemoryBuffer.cpp +++ b/src/3rdparty/angle/src/common/MemoryBuffer.cpp @@ -11,19 +11,18 @@ #include "common/debug.h" -namespace rx +namespace angle { -MemoryBuffer::MemoryBuffer() - : mSize(0), - mData(NULL) +// MemoryBuffer implementation. +MemoryBuffer::MemoryBuffer() : mSize(0), mData(nullptr) { } MemoryBuffer::~MemoryBuffer() { free(mData); - mData = NULL; + mData = nullptr; } bool MemoryBuffer::resize(size_t size) @@ -31,7 +30,7 @@ bool MemoryBuffer::resize(size_t size) if (size == 0) { free(mData); - mData = NULL; + mData = nullptr; mSize = 0; return true; } @@ -42,8 +41,8 @@ bool MemoryBuffer::resize(size_t size) } // Only reallocate if the size has changed. - uint8_t *newMemory = reinterpret_cast(malloc(sizeof(uint8_t) * size)); - if (newMemory == NULL) + uint8_t *newMemory = reinterpret_cast(malloc(sizeof(uint8_t) * size)); + if (newMemory == nullptr) { return false; } @@ -61,20 +60,96 @@ bool MemoryBuffer::resize(size_t size) return true; } -size_t MemoryBuffer::size() const +void MemoryBuffer::fill(uint8_t datum) { - return mSize; + if (!empty()) + { + std::fill(mData, mData + mSize, datum); + } } -const uint8_t *MemoryBuffer::data() const +MemoryBuffer::MemoryBuffer(MemoryBuffer &&other) : MemoryBuffer() { - return mData; + *this = std::move(other); } -uint8_t *MemoryBuffer::data() +MemoryBuffer &MemoryBuffer::operator=(MemoryBuffer &&other) { - ASSERT(mData); - return mData; + std::swap(mSize, other.mSize); + std::swap(mData, other.mData); + return *this; } +// ScratchBuffer implementation. + +ScratchBuffer::ScratchBuffer(uint32_t lifetime) : mLifetime(lifetime), mResetCounter(lifetime) +{ } + +ScratchBuffer::~ScratchBuffer() +{ +} + +bool ScratchBuffer::get(size_t requestedSize, MemoryBuffer **memoryBufferOut) +{ + return getImpl(requestedSize, memoryBufferOut, Optional::Invalid()); +} + +bool ScratchBuffer::getInitialized(size_t requestedSize, + MemoryBuffer **memoryBufferOut, + uint8_t initValue) +{ + return getImpl(requestedSize, memoryBufferOut, Optional(initValue)); +} + +bool ScratchBuffer::getImpl(size_t requestedSize, + MemoryBuffer **memoryBufferOut, + Optional initValue) +{ + if (mScratchMemory.size() == requestedSize) + { + mResetCounter = mLifetime; + *memoryBufferOut = &mScratchMemory; + return true; + } + + if (mScratchMemory.size() > requestedSize) + { + tick(); + } + + if (mResetCounter == 0 || mScratchMemory.size() < requestedSize) + { + mScratchMemory.resize(0); + if (!mScratchMemory.resize(requestedSize)) + { + return false; + } + mResetCounter = mLifetime; + if (initValue.valid()) + { + mScratchMemory.fill(initValue.value()); + } + } + + ASSERT(mScratchMemory.size() >= requestedSize); + + *memoryBufferOut = &mScratchMemory; + return true; +} + +void ScratchBuffer::tick() +{ + if (mResetCounter > 0) + { + --mResetCounter; + } +} + +void ScratchBuffer::clear() +{ + mResetCounter = mLifetime; + mScratchMemory.resize(0); +} + +} // namespace angle diff --git a/src/3rdparty/angle/src/common/MemoryBuffer.h b/src/3rdparty/angle/src/common/MemoryBuffer.h index ec621cbca7..f76b9ee62e 100644 --- a/src/3rdparty/angle/src/common/MemoryBuffer.h +++ b/src/3rdparty/angle/src/common/MemoryBuffer.h @@ -7,32 +7,71 @@ #ifndef COMMON_MEMORYBUFFER_H_ #define COMMON_MEMORYBUFFER_H_ +#include "common/Optional.h" #include "common/angleutils.h" +#include "common/debug.h" -#include #include +#include -namespace rx +namespace angle { -class MemoryBuffer : angle::NonCopyable +class MemoryBuffer final : NonCopyable { public: MemoryBuffer(); ~MemoryBuffer(); + MemoryBuffer(MemoryBuffer &&other); + MemoryBuffer &operator=(MemoryBuffer &&other); + bool resize(size_t size); - size_t size() const; + size_t size() const { return mSize; } bool empty() const { return mSize == 0; } - const uint8_t *data() const; - uint8_t *data(); + const uint8_t *data() const { return mData; } + uint8_t *data() + { + ASSERT(mData); + return mData; + } + + void fill(uint8_t datum); private: size_t mSize; uint8_t *mData; }; -} +class ScratchBuffer final : NonCopyable +{ + public: + // If we request a scratch buffer requesting a smaller size this many times, release and + // recreate the scratch buffer. This ensures we don't have a degenerate case where we are stuck + // hogging memory. + ScratchBuffer(uint32_t lifetime); + ~ScratchBuffer(); -#endif // COMMON_MEMORYBUFFER_H_ + // Returns true with a memory buffer of the requested size, or false on failure. + bool get(size_t requestedSize, MemoryBuffer **memoryBufferOut); + + // Same as get, but ensures new values are initialized to a fixed constant. + bool getInitialized(size_t requestedSize, MemoryBuffer **memoryBufferOut, uint8_t initValue); + + // Ticks the release counter for the scratch buffer. Also done implicitly in get(). + void tick(); + + void clear(); + + private: + bool getImpl(size_t requestedSize, MemoryBuffer **memoryBufferOut, Optional initValue); + + const uint32_t mLifetime; + uint32_t mResetCounter; + MemoryBuffer mScratchMemory; +}; + +} // namespace angle + +#endif // COMMON_MEMORYBUFFER_H_ diff --git a/src/3rdparty/angle/src/common/Optional.h b/src/3rdparty/angle/src/common/Optional.h index 256f38f329..822de4de51 100644 --- a/src/3rdparty/angle/src/common/Optional.h +++ b/src/3rdparty/angle/src/common/Optional.h @@ -10,23 +10,16 @@ #ifndef COMMON_OPTIONAL_H_ #define COMMON_OPTIONAL_H_ +#include + template struct Optional { - Optional() - : mValid(false), - mValue(T()) - {} + Optional() : mValid(false), mValue(T()) {} - explicit Optional(const T &valueIn) - : mValid(true), - mValue(valueIn) - {} + Optional(const T &valueIn) : mValid(true), mValue(valueIn) {} - Optional(const Optional &other) - : mValid(other.mValid), - mValue(other.mValue) - {} + Optional(const Optional &other) : mValid(other.mValid), mValue(other.mValue) {} Optional &operator=(const Optional &other) { @@ -49,10 +42,7 @@ struct Optional return *this; } - void reset() - { - mValid = false; - } + void reset() { mValid = false; } static Optional Invalid() { return Optional(); } @@ -64,14 +54,15 @@ struct Optional return ((mValid == other.mValid) && (!mValid || (mValue == other.mValue))); } - bool operator!=(const Optional &other) const - { - return !(*this == other); - } + bool operator!=(const Optional &other) const { return !(*this == other); } + + bool operator==(const T &value) const { return mValid && (mValue == value); } + + bool operator!=(const T &value) const { return !(*this == value); } private: bool mValid; T mValue; }; -#endif // COMMON_OPTIONAL_H_ +#endif // COMMON_OPTIONAL_H_ diff --git a/src/3rdparty/angle/src/common/angleutils.cpp b/src/3rdparty/angle/src/common/angleutils.cpp index 7099c21730..739d12a767 100644 --- a/src/3rdparty/angle/src/common/angleutils.cpp +++ b/src/3rdparty/angle/src/common/angleutils.cpp @@ -14,39 +14,61 @@ namespace angle { +// dirtyPointer is a special value that will make the comparison with any valid pointer fail and +// force the renderer to re-apply the state. const uintptr_t DirtyPointer = std::numeric_limits::max(); } +std::string ArrayString(unsigned int i) +{ + // We assume that UINT_MAX and GL_INVALID_INDEX are equal. + ASSERT(i != UINT_MAX); + + std::stringstream strstr; + strstr << "["; + strstr << i; + strstr << "]"; + return strstr.str(); +} + +std::string ArrayIndexString(const std::vector &indices) +{ + std::stringstream strstr; + + for (auto indicesIt = indices.rbegin(); indicesIt != indices.rend(); ++indicesIt) + { + // We assume that UINT_MAX and GL_INVALID_INDEX are equal. + ASSERT(*indicesIt != UINT_MAX); + strstr << "["; + strstr << (*indicesIt); + strstr << "]"; + } + + return strstr.str(); +} + size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector& outBuffer) { + // The state of the va_list passed to vsnprintf is undefined after the call, do a copy in case + // we need to grow the buffer. + va_list varargCopy; + va_copy(varargCopy, vararg); + // Attempt to just print to the current buffer - int len = vsnprintf(&(outBuffer.front()), outBuffer.size(), fmt, vararg); + int len = vsnprintf(&(outBuffer.front()), outBuffer.size(), fmt, varargCopy); + va_end(varargCopy); + if (len < 0 || static_cast(len) >= outBuffer.size()) { // Buffer was not large enough, calculate the required size and resize the buffer - len = vsnprintf(NULL, 0, fmt, vararg); + len = vsnprintf(nullptr, 0, fmt, vararg); outBuffer.resize(len + 1); // Print again - len = vsnprintf(&(outBuffer.front()), outBuffer.size(), fmt, vararg); + va_copy(varargCopy, vararg); + len = vsnprintf(&(outBuffer.front()), outBuffer.size(), fmt, varargCopy); + va_end(varargCopy); } ASSERT(len >= 0); return static_cast(len); } - -std::string FormatString(const char *fmt, va_list vararg) -{ - static std::vector buffer(512); - - size_t len = FormatStringIntoVector(fmt, vararg, buffer); - return std::string(&buffer[0], len); -} - -std::string FormatString(const char *fmt, ...) -{ - va_list vararg; - va_start(vararg, fmt); - std::string result = FormatString(fmt, vararg); - va_end(vararg); - return result; -} diff --git a/src/3rdparty/angle/src/common/angleutils.h b/src/3rdparty/angle/src/common/angleutils.h index a0178fd414..ad32a2f03a 100644 --- a/src/3rdparty/angle/src/common/angleutils.h +++ b/src/3rdparty/angle/src/common/angleutils.h @@ -23,25 +23,59 @@ namespace angle { +#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11) +using Microsoft::WRL::ComPtr; +#endif // defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11) + class NonCopyable { - public: + protected: NonCopyable() = default; ~NonCopyable() = default; - protected: + + private: NonCopyable(const NonCopyable&) = delete; void operator=(const NonCopyable&) = delete; }; extern const uintptr_t DirtyPointer; -} + +} // namespace angle template -inline size_t ArraySize(T(&)[N]) +constexpr inline size_t ArraySize(T (&)[N]) { return N; } +template +class WrappedArray final : angle::NonCopyable +{ + public: + template + constexpr WrappedArray(const T (&data)[N]) : mArray(&data[0]), mSize(N) + { + } + + constexpr WrappedArray() : mArray(nullptr), mSize(0) {} + constexpr WrappedArray(const T *data, size_t size) : mArray(data), mSize(size) {} + + WrappedArray(WrappedArray &&other) : WrappedArray() + { + std::swap(mArray, other.mArray); + std::swap(mSize, other.mSize); + } + + ~WrappedArray() {} + + constexpr const T *get() const { return mArray; } + constexpr size_t size() const { return mSize; } + + private: + const T *mArray; + size_t mSize; +}; + template void SafeRelease(T (&resourceBlock)[N]) { @@ -57,15 +91,15 @@ void SafeRelease(T& resource) if (resource) { resource->Release(); - resource = NULL; + resource = nullptr; } } template -void SafeDelete(T*& resource) +void SafeDelete(T *&resource) { delete resource; - resource = NULL; + resource = nullptr; } template @@ -82,7 +116,7 @@ template void SafeDeleteArray(T*& resource) { delete[] resource; - resource = NULL; + resource = nullptr; } // Provide a less-than function for comparing structs @@ -126,23 +160,11 @@ inline const char* MakeStaticString(const std::string &str) return strings.insert(str).first->c_str(); } -inline std::string ArrayString(unsigned int i) -{ - // We assume UINT_MAX and GL_INVALID_INDEX are equal - // See DynamicHLSL.cpp - if (i == UINT_MAX) - { - return ""; - } +std::string ArrayString(unsigned int i); - std::stringstream strstr; - - strstr << "["; - strstr << i; - strstr << "]"; - - return strstr.str(); -} +// Indices are stored in vectors with the outermost index in the back. In the output of the function +// the indices are reversed. +std::string ArrayIndexString(const std::vector &indices); inline std::string Str(int i) { @@ -156,17 +178,76 @@ size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector std::string FormatString(const char *fmt, va_list vararg); std::string FormatString(const char *fmt, ...); +template +std::string ToString(const T &value) +{ + std::ostringstream o; + o << value; + return o.str(); +} + // snprintf is not defined with MSVC prior to to msvc14 #if defined(_MSC_VER) && _MSC_VER < 1900 #define snprintf _snprintf #endif +#define GL_BGRX8_ANGLEX 0x6ABA +#define GL_BGR565_ANGLEX 0x6ABB #define GL_BGRA4_ANGLEX 0x6ABC #define GL_BGR5_A1_ANGLEX 0x6ABD #define GL_INT_64_ANGLEX 0x6ABE -#define GL_STRUCT_ANGLEX 0x6ABF +#define GL_UINT_64_ANGLEX 0x6ABF +#define GL_BGRA8_SRGB_ANGLEX 0x6AC0 // Hidden enum for the NULL D3D device type. #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE 0x6AC0 +// TODO(jmadill): Clean this up at some point. +#define EGL_PLATFORM_ANGLE_PLATFORM_METHODS_ANGLEX 0x9999 + +#define ANGLE_TRY_CHECKED_MATH(result) \ + if (!result.IsValid()) \ + { \ + return gl::InternalError() << "Integer overflow."; \ + } + +// The below inlining code lifted from V8. +#if defined(__clang__) || (defined(__GNUC__) && defined(__has_attribute)) +#define ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE (__has_attribute(always_inline)) +#define ANGLE_HAS___FORCEINLINE 0 +#elif defined(_MSC_VER) +#define ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE 0 +#define ANGLE_HAS___FORCEINLINE 1 +#else +#define ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE 0 +#define ANGLE_HAS___FORCEINLINE 0 +#endif + +#if defined(NDEBUG) && ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE +#define ANGLE_INLINE inline __attribute__((always_inline)) +#elif defined(NDEBUG) && ANGLE_HAS___FORCEINLINE +#define ANGLE_INLINE __forceinline +#else +#define ANGLE_INLINE inline +#endif + +#ifndef ANGLE_STRINGIFY +#define ANGLE_STRINGIFY(x) #x +#endif + +#ifndef ANGLE_MACRO_STRINGIFY +#define ANGLE_MACRO_STRINGIFY(x) ANGLE_STRINGIFY(x) +#endif + +// Detect support for C++17 [[nodiscard]] +#if !defined(__has_cpp_attribute) +#define __has_cpp_attribute(name) 0 +#endif // !defined(__has_cpp_attribute) + +#if __has_cpp_attribute(nodiscard) +#define ANGLE_NO_DISCARD [[nodiscard]] +#else +#define ANGLE_NO_DISCARD +#endif // __has_cpp_attribute(nodiscard) + #endif // COMMON_ANGLEUTILS_H_ diff --git a/src/3rdparty/angle/src/common/bitset_utils.h b/src/3rdparty/angle/src/common/bitset_utils.h new file mode 100644 index 0000000000..4166a562a7 --- /dev/null +++ b/src/3rdparty/angle/src/common/bitset_utils.h @@ -0,0 +1,498 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// bitset_utils: +// Bitset-related helper classes, such as a fast iterator to scan for set bits. +// + +#ifndef COMMON_BITSETITERATOR_H_ +#define COMMON_BITSETITERATOR_H_ + +#include + +#include + +#include "common/angleutils.h" +#include "common/debug.h" +#include "common/mathutil.h" +#include "common/platform.h" + +namespace angle +{ + +template +class BitSetT final +{ + public: + class Reference final + { + public: + ~Reference() {} + Reference &operator=(bool x) + { + mParent->set(mBit, x); + return *this; + } + explicit operator bool() const { return mParent->test(mBit); } + + private: + friend class BitSetT; + + Reference(BitSetT *parent, std::size_t bit) : mParent(parent), mBit(bit) {} + + BitSetT *mParent; + std::size_t mBit; + }; + + class Iterator final + { + public: + Iterator(const BitSetT &bits); + Iterator &operator++(); + + bool operator==(const Iterator &other) const; + bool operator!=(const Iterator &other) const; + std::size_t operator*() const; + + private: + std::size_t getNextBit(); + + BitSetT mBitsCopy; + std::size_t mCurrentBit; + }; + + BitSetT(); + BitSetT(BitsT value); + ~BitSetT(); + + BitSetT(const BitSetT &other); + BitSetT &operator=(const BitSetT &other); + + bool operator==(const BitSetT &other) const; + bool operator!=(const BitSetT &other) const; + + constexpr bool operator[](std::size_t pos) const; + Reference operator[](std::size_t pos) { return Reference(this, pos); } + + bool test(std::size_t pos) const; + + bool all() const; + bool any() const; + bool none() const; + std::size_t count() const; + + constexpr std::size_t size() const { return N; } + + BitSetT &operator&=(const BitSetT &other); + BitSetT &operator|=(const BitSetT &other); + BitSetT &operator^=(const BitSetT &other); + BitSetT operator~() const; + + BitSetT operator<<(std::size_t pos) const; + BitSetT &operator<<=(std::size_t pos); + BitSetT operator>>(std::size_t pos) const; + BitSetT &operator>>=(std::size_t pos); + + BitSetT &set(); + BitSetT &set(std::size_t pos, bool value = true); + + BitSetT &reset(); + BitSetT &reset(std::size_t pos); + + BitSetT &flip(); + BitSetT &flip(std::size_t pos); + + unsigned long to_ulong() const { return static_cast(mBits); } + BitsT bits() const { return mBits; } + + Iterator begin() const { return Iterator(*this); } + Iterator end() const { return Iterator(BitSetT()); } + + private: + constexpr static BitsT Bit(std::size_t x) { return (static_cast(1) << x); } + constexpr static BitsT Mask(std::size_t x) { return ((Bit(x - 1) - 1) << 1) + 1; } + + BitsT mBits; +}; + +template +class IterableBitSet : public std::bitset +{ + public: + IterableBitSet() {} + IterableBitSet(const std::bitset &implicitBitSet) : std::bitset(implicitBitSet) {} + + class Iterator final + { + public: + Iterator(const std::bitset &bits); + Iterator &operator++(); + + bool operator==(const Iterator &other) const; + bool operator!=(const Iterator &other) const; + unsigned long operator*() const { return mCurrentBit; } + + private: + unsigned long getNextBit(); + + static constexpr size_t BitsPerWord = sizeof(uint32_t) * 8; + std::bitset mBits; + unsigned long mCurrentBit; + unsigned long mOffset; + }; + + Iterator begin() const { return Iterator(*this); } + Iterator end() const { return Iterator(std::bitset(0)); } +}; + +template +IterableBitSet::Iterator::Iterator(const std::bitset &bitset) + : mBits(bitset), mCurrentBit(0), mOffset(0) +{ + if (mBits.any()) + { + mCurrentBit = getNextBit(); + } + else + { + mOffset = static_cast(rx::roundUp(N, BitsPerWord)); + } +} + +template +typename IterableBitSet::Iterator &IterableBitSet::Iterator::operator++() +{ + ASSERT(mBits.any()); + mBits.set(mCurrentBit - mOffset, 0); + mCurrentBit = getNextBit(); + return *this; +} + +template +bool IterableBitSet::Iterator::operator==(const Iterator &other) const +{ + return mOffset == other.mOffset && mBits == other.mBits; +} + +template +bool IterableBitSet::Iterator::operator!=(const Iterator &other) const +{ + return !(*this == other); +} + +template +unsigned long IterableBitSet::Iterator::getNextBit() +{ + // TODO(jmadill): Use 64-bit scan when possible. + static constexpr std::bitset wordMask(std::numeric_limits::max()); + + while (mOffset < N) + { + uint32_t wordBits = static_cast((mBits & wordMask).to_ulong()); + if (wordBits != 0) + { + return gl::ScanForward(wordBits) + mOffset; + } + + mBits >>= BitsPerWord; + mOffset += BitsPerWord; + } + return 0; +} + +template +BitSetT::BitSetT() : mBits(0) +{ + static_assert(N > 0, "Bitset type cannot support zero bits."); + static_assert(N <= sizeof(BitsT) * 8, "Bitset type cannot support a size this large."); +} + +template +BitSetT::BitSetT(BitsT value) : mBits(value & Mask(N)) +{ +} + +template +BitSetT::~BitSetT() +{ +} + +template +BitSetT::BitSetT(const BitSetT &other) : mBits(other.mBits) +{ +} + +template +BitSetT &BitSetT::operator=(const BitSetT &other) +{ + mBits = other.mBits; + return *this; +} + +template +bool BitSetT::operator==(const BitSetT &other) const +{ + return mBits == other.mBits; +} + +template +bool BitSetT::operator!=(const BitSetT &other) const +{ + return mBits != other.mBits; +} + +template +constexpr bool BitSetT::operator[](std::size_t pos) const +{ + return test(pos); +} + +template +bool BitSetT::test(std::size_t pos) const +{ + return (mBits & Bit(pos)) != 0; +} + +template +bool BitSetT::all() const +{ + ASSERT(mBits == (mBits & Mask(N))); + return mBits == Mask(N); +} + +template +bool BitSetT::any() const +{ + ASSERT(mBits == (mBits & Mask(N))); + return (mBits != 0); +} + +template +bool BitSetT::none() const +{ + ASSERT(mBits == (mBits & Mask(N))); + return (mBits == 0); +} + +template +std::size_t BitSetT::count() const +{ + return gl::BitCount(mBits); +} + +template +BitSetT &BitSetT::operator&=(const BitSetT &other) +{ + mBits &= other.mBits; + return *this; +} + +template +BitSetT &BitSetT::operator|=(const BitSetT &other) +{ + mBits |= other.mBits; + return *this; +} + +template +BitSetT &BitSetT::operator^=(const BitSetT &other) +{ + mBits = (mBits ^ other.mBits) & Mask(N); + return *this; +} + +template +BitSetT BitSetT::operator~() const +{ + return BitSetT(~mBits & Mask(N)); +} + +template +BitSetT BitSetT::operator<<(std::size_t pos) const +{ + return BitSetT((mBits << pos) & Mask(N)); +} + +template +BitSetT &BitSetT::operator<<=(std::size_t pos) +{ + mBits = (mBits << pos & Mask(N)); + return *this; +} + +template +BitSetT BitSetT::operator>>(std::size_t pos) const +{ + return BitSetT(mBits >> pos); +} + +template +BitSetT &BitSetT::operator>>=(std::size_t pos) +{ + mBits = ((mBits >> pos) & Mask(N)); + return *this; +} + +template +BitSetT &BitSetT::set() +{ + mBits = Mask(N); + return *this; +} + +template +BitSetT &BitSetT::set(std::size_t pos, bool value) +{ + if (value) + { + mBits |= Bit(pos); + } + else + { + reset(pos); + } + return *this; +} + +template +BitSetT &BitSetT::reset() +{ + mBits = 0; + return *this; +} + +template +BitSetT &BitSetT::reset(std::size_t pos) +{ + mBits &= ~Bit(pos); + return *this; +} + +template +BitSetT &BitSetT::flip() +{ + mBits ^= Mask(N); + return *this; +} + +template +BitSetT &BitSetT::flip(std::size_t pos) +{ + mBits ^= Bit(pos); + return *this; +} + +template +BitSetT::Iterator::Iterator(const BitSetT &bits) : mBitsCopy(bits), mCurrentBit(0) +{ + if (bits.any()) + { + mCurrentBit = getNextBit(); + } +} + +template +typename BitSetT::Iterator &BitSetT::Iterator::operator++() +{ + ASSERT(mBitsCopy.any()); + mBitsCopy.reset(mCurrentBit); + mCurrentBit = getNextBit(); + return *this; +} + +template +bool BitSetT::Iterator::operator==(const Iterator &other) const +{ + return mBitsCopy == other.mBitsCopy; +} + +template +bool BitSetT::Iterator::operator!=(const Iterator &other) const +{ + return !(*this == other); +} + +template +std::size_t BitSetT::Iterator::operator*() const +{ + return mCurrentBit; +} + +template +std::size_t BitSetT::Iterator::getNextBit() +{ + if (mBitsCopy.none()) + { + return 0; + } + + return gl::ScanForward(mBitsCopy.mBits); +} + +template +using BitSet32 = BitSetT; + +// ScanForward for 64-bits requires a 64-bit implementation. +#if defined(ANGLE_IS_64_BIT_CPU) +template +using BitSet64 = BitSetT; +#endif // defined(ANGLE_IS_64_BIT_CPU) + +namespace priv +{ + +template +using EnableIfBitsFit = typename std::enable_if::type; + +template +struct GetBitSet +{ + using Type = IterableBitSet; +}; + +// Prefer 64-bit bitsets on 64-bit CPUs. They seem faster than 32-bit. +#if defined(ANGLE_IS_64_BIT_CPU) +template +struct GetBitSet> +{ + using Type = BitSet64; +}; +#else +template +struct GetBitSet> +{ + using Type = BitSet32; +}; +#endif // defined(ANGLE_IS_64_BIT_CPU) + +} // namespace priv + +template +using BitSet = typename priv::GetBitSet::Type; + +} // angle + +template +inline angle::BitSetT operator&(const angle::BitSetT &lhs, + const angle::BitSetT &rhs) +{ + return angle::BitSetT(lhs.bits() & rhs.bits()); +} + +template +inline angle::BitSetT operator|(const angle::BitSetT &lhs, + const angle::BitSetT &rhs) +{ + return angle::BitSetT(lhs.bits() | rhs.bits()); +} + +template +inline angle::BitSetT operator^(const angle::BitSetT &lhs, + const angle::BitSetT &rhs) +{ + return angle::BitSetT(lhs.bits() ^ rhs.bits()); +} + +#endif // COMMON_BITSETITERATOR_H_ diff --git a/src/3rdparty/angle/src/common/debug.cpp b/src/3rdparty/angle/src/common/debug.cpp index 1fcc062908..b02e80be5f 100644 --- a/src/3rdparty/angle/src/common/debug.cpp +++ b/src/3rdparty/angle/src/common/debug.cpp @@ -7,92 +7,61 @@ // debug.cpp: Debugging utilities. #include "common/debug.h" -#include "common/platform.h" -#include "common/angleutils.h" #include -#include -#include + +#include #include +#include +#include +#include + +#include "common/angleutils.h" +#include "common/Optional.h" namespace gl { namespace { -enum DebugTraceOutputType -{ - DebugTraceOutputTypeNone, - DebugTraceOutputTypeSetMarker, - DebugTraceOutputTypeBeginEvent -}; DebugAnnotator *g_debugAnnotator = nullptr; -void output(bool traceInDebugOnly, MessageType messageType, DebugTraceOutputType outputType, - const char *format, va_list vararg) +constexpr std::array g_logSeverityNames = { + {"EVENT", "WARN", "ERR"}}; + +constexpr const char *LogSeverityName(int severity) { - if (DebugAnnotationsActive()) - { - static std::vector buffer(512); - size_t len = FormatStringIntoVector(format, vararg, buffer); - std::wstring formattedWideMessage(buffer.begin(), buffer.begin() + len); - - ASSERT(g_debugAnnotator != nullptr); - switch (outputType) - { - case DebugTraceOutputTypeNone: - break; - case DebugTraceOutputTypeBeginEvent: - g_debugAnnotator->beginEvent(formattedWideMessage.c_str()); - break; - case DebugTraceOutputTypeSetMarker: - g_debugAnnotator->setMarker(formattedWideMessage.c_str()); - break; - } - } - - std::string formattedMessage; - UNUSED_VARIABLE(formattedMessage); - -#if !defined(NDEBUG) && defined(_MSC_VER) - if (messageType == MESSAGE_ERR) - { - if (formattedMessage.empty()) - { - formattedMessage = FormatString(format, vararg); - } - OutputDebugStringA(formattedMessage.c_str()); - } -#endif - -#if defined(ANGLE_ENABLE_DEBUG_TRACE) -#if defined(NDEBUG) - if (traceInDebugOnly) - { - return; - } -#endif // NDEBUG - if (formattedMessage.empty()) - { - formattedMessage = FormatString(format, vararg); - } - - static std::ofstream file(TRACE_OUTPUT_FILE, std::ofstream::app); - if (file) - { - file.write(formattedMessage.c_str(), formattedMessage.length()); - file.flush(); - } - -#if defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER) - OutputDebugStringA(formattedMessage.c_str()); -#endif // ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER - -#endif // ANGLE_ENABLE_DEBUG_TRACE + return (severity >= 0 && severity < LOG_NUM_SEVERITIES) ? g_logSeverityNames[severity] + : "UNKNOWN"; } -} // namespace +bool ShouldCreateLogMessage(LogSeverity severity) +{ +#if defined(ANGLE_TRACE_ENABLED) + return true; +#elif defined(ANGLE_ENABLE_ASSERTS) + return severity == LOG_ERR; +#else + return false; +#endif +} + +} // namespace + +namespace priv +{ + +bool ShouldCreatePlatformLogMessage(LogSeverity severity) +{ +#if defined(ANGLE_TRACE_ENABLED) + return true; +#else + return severity != LOG_EVENT; +#endif +} + +} // namespace priv bool DebugAnnotationsActive() { @@ -103,6 +72,11 @@ bool DebugAnnotationsActive() #endif } +bool DebugAnnotationsInitialized() +{ + return g_debugAnnotator != nullptr; +} + void InitializeDebugAnnotations(DebugAnnotator *debugAnnotator) { UninitializeDebugAnnotations(); @@ -115,25 +89,20 @@ void UninitializeDebugAnnotations() g_debugAnnotator = nullptr; } -void trace(bool traceInDebugOnly, MessageType messageType, const char *format, ...) -{ - va_list vararg; - va_start(vararg, format); - output(traceInDebugOnly, messageType, DebugTraceOutputTypeSetMarker, format, vararg); - va_end(vararg); -} - -ScopedPerfEventHelper::ScopedPerfEventHelper(const char* format, ...) +ScopedPerfEventHelper::ScopedPerfEventHelper(const char *format, ...) { #if !defined(ANGLE_ENABLE_DEBUG_TRACE) if (!DebugAnnotationsActive()) { return; } -#endif // !ANGLE_ENABLE_DEBUG_TRACE +#endif // !ANGLE_ENABLE_DEBUG_TRACE + va_list vararg; va_start(vararg, format); - output(true, MESSAGE_EVENT, DebugTraceOutputTypeBeginEvent, format, vararg); + std::vector buffer(512); + size_t len = FormatStringIntoVector(format, vararg, buffer); + ANGLE_LOG(EVENT) << std::string(&buffer[0], len); va_end(vararg); } @@ -145,4 +114,107 @@ ScopedPerfEventHelper::~ScopedPerfEventHelper() } } +LogMessage::LogMessage(const char *function, int line, LogSeverity severity) + : mFunction(function), mLine(line), mSeverity(severity) +{ + // EVENT() does not require additional function(line) info. + if (mSeverity != LOG_EVENT) + { + mStream << mFunction << "(" << mLine << "): "; + } } + +LogMessage::~LogMessage() +{ + if (DebugAnnotationsInitialized() && (mSeverity == LOG_ERR || mSeverity == LOG_WARN)) + { + g_debugAnnotator->logMessage(*this); + } + else + { + Trace(getSeverity(), getMessage().c_str()); + } +} + +void Trace(LogSeverity severity, const char *message) +{ + if (!ShouldCreateLogMessage(severity)) + { + return; + } + + std::string str(message); + + if (DebugAnnotationsActive()) + { + std::wstring formattedWideMessage(str.begin(), str.end()); + + switch (severity) + { + case LOG_EVENT: + g_debugAnnotator->beginEvent(formattedWideMessage.c_str()); + break; + default: + g_debugAnnotator->setMarker(formattedWideMessage.c_str()); + break; + } + } + + if (severity == LOG_ERR) + { + // Note: we use fprintf because includes static initializers. + fprintf(stderr, "%s: %s\n", LogSeverityName(severity), str.c_str()); + } + +#if defined(ANGLE_PLATFORM_WINDOWS) && \ + (defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER) || !defined(NDEBUG)) +#if !defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER) + if (severity == LOG_ERR) +#endif // !defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER) + { + OutputDebugStringA(str.c_str()); + } +#endif + +#if defined(ANGLE_ENABLE_DEBUG_TRACE) +#if defined(NDEBUG) + if (severity == LOG_EVENT || severity == LOG_WARN) + { + return; + } +#endif // defined(NDEBUG) + static std::ofstream file(TRACE_OUTPUT_FILE, std::ofstream::app); + if (file) + { + file << LogSeverityName(severity) << ": " << str << std::endl; + file.flush(); + } +#endif // defined(ANGLE_ENABLE_DEBUG_TRACE) +} + +LogSeverity LogMessage::getSeverity() const +{ + return mSeverity; +} + +std::string LogMessage::getMessage() const +{ + return mStream.str(); +} + +#if defined(ANGLE_PLATFORM_WINDOWS) +std::ostream &operator<<(std::ostream &os, const FmtHR &fmt) +{ + os << "HRESULT: "; + return FmtHexInt(os, fmt.mHR); +} + +std::ostream &operator<<(std::ostream &os, const FmtErr &fmt) +{ + os << "error: "; + return FmtHexInt(os, fmt.mErr); +} + +#endif // defined(ANGLE_PLATFORM_WINDOWS) + +} // namespace gl diff --git a/src/3rdparty/angle/src/common/debug.h b/src/3rdparty/angle/src/common/debug.h index 64cfef4cd9..290a4e8bb7 100644 --- a/src/3rdparty/angle/src/common/debug.h +++ b/src/3rdparty/angle/src/common/debug.h @@ -11,6 +11,10 @@ #include #include + +#include +#include +#include #include #include "common/angleutils.h" @@ -22,17 +26,6 @@ namespace gl { -enum MessageType -{ - MESSAGE_TRACE, - MESSAGE_FIXME, - MESSAGE_ERR, - MESSAGE_EVENT, -}; - -// Outputs text to the debugging log, or the debugging window -void trace(bool traceInDebugOnly, MessageType messageType, const char *format, ...); - // Pairs a D3D begin event with an end event. class ScopedPerfEventHelper : angle::NonCopyable { @@ -41,50 +34,177 @@ class ScopedPerfEventHelper : angle::NonCopyable ~ScopedPerfEventHelper(); }; +using LogSeverity = int; +// Note: the log severities are used to index into the array of names, +// see g_logSeverityNames. +constexpr LogSeverity LOG_EVENT = 0; +constexpr LogSeverity LOG_WARN = 1; +constexpr LogSeverity LOG_ERR = 2; +constexpr LogSeverity LOG_NUM_SEVERITIES = 3; + +void Trace(LogSeverity severity, const char *message); + +// This class more or less represents a particular log message. You +// create an instance of LogMessage and then stream stuff to it. +// When you finish streaming to it, ~LogMessage is called and the +// full message gets streamed to the appropriate destination. +// +// You shouldn't actually use LogMessage's constructor to log things, +// though. You should use the ERR() and WARN() macros. +class LogMessage : angle::NonCopyable +{ + public: + // Used for ANGLE_LOG(severity). + LogMessage(const char *function, int line, LogSeverity severity); + ~LogMessage(); + std::ostream &stream() { return mStream; } + + LogSeverity getSeverity() const; + std::string getMessage() const; + + private: + const char *mFunction; + const int mLine; + const LogSeverity mSeverity; + + std::ostringstream mStream; +}; + // Wraps the D3D9/D3D11 debug annotation functions. +// Also handles redirecting logging destination. class DebugAnnotator : angle::NonCopyable { public: - DebugAnnotator() { }; + DebugAnnotator(){}; virtual ~DebugAnnotator() { }; virtual void beginEvent(const wchar_t *eventName) = 0; virtual void endEvent() = 0; virtual void setMarker(const wchar_t *markerName) = 0; virtual bool getStatus() = 0; + // Log Message Handler that gets passed every log message, + // when debug annotations are initialized, + // replacing default handling by LogMessage. + virtual void logMessage(const LogMessage &msg) const = 0; }; void InitializeDebugAnnotations(DebugAnnotator *debugAnnotator); void UninitializeDebugAnnotations(); bool DebugAnnotationsActive(); +bool DebugAnnotationsInitialized(); +namespace priv +{ +// This class is used to explicitly ignore values in the conditional logging macros. This avoids +// compiler warnings like "value computed is not used" and "statement has no effect". +class LogMessageVoidify +{ + public: + LogMessageVoidify() {} + // This has to be an operator with a precedence lower than << but higher than ?: + void operator&(std::ostream &) {} +}; + +// Used by ANGLE_LOG_IS_ON to lazy-evaluate stream arguments. +bool ShouldCreatePlatformLogMessage(LogSeverity severity); + +template +std::ostream &FmtHex(std::ostream &os, T value) +{ + os << "0x"; + + std::ios_base::fmtflags oldFlags = os.flags(); + std::streamsize oldWidth = os.width(); + std::ostream::char_type oldFill = os.fill(); + + os << std::hex << std::uppercase << std::setw(N) << std::setfill('0') << value; + + os.flags(oldFlags); + os.width(oldWidth); + os.fill(oldFill); + + return os; } +} // namespace priv + +#if defined(ANGLE_PLATFORM_WINDOWS) +class FmtHR +{ + public: + explicit FmtHR(HRESULT hresult) : mHR(hresult) {} + private: + HRESULT mHR; + friend std::ostream &operator<<(std::ostream &os, const FmtHR &fmt); +}; + +class FmtErr +{ + public: + explicit FmtErr(DWORD err) : mErr(err) {} + + private: + DWORD mErr; + friend std::ostream &operator<<(std::ostream &os, const FmtErr &fmt); +}; +#endif // defined(ANGLE_PLATFORM_WINDOWS) + +template +std::ostream &FmtHexShort(std::ostream &os, T value) +{ + return priv::FmtHex<4>(os, value); +} + +template +std::ostream &FmtHexInt(std::ostream &os, T value) +{ + return priv::FmtHex<8>(os, value); +} + +// A few definitions of macros that don't generate much code. These are used +// by ANGLE_LOG(). Since these are used all over our code, it's +// better to have compact code for these operations. +#define COMPACT_ANGLE_LOG_EX_EVENT(ClassName, ...) \ + ::gl::ClassName(__FUNCTION__, __LINE__, ::gl::LOG_EVENT, ##__VA_ARGS__) +#define COMPACT_ANGLE_LOG_EX_WARN(ClassName, ...) \ + ::gl::ClassName(__FUNCTION__, __LINE__, ::gl::LOG_WARN, ##__VA_ARGS__) +#define COMPACT_ANGLE_LOG_EX_ERR(ClassName, ...) \ + ::gl::ClassName(__FUNCTION__, __LINE__, ::gl::LOG_ERR, ##__VA_ARGS__) + +#define COMPACT_ANGLE_LOG_EVENT COMPACT_ANGLE_LOG_EX_EVENT(LogMessage) +#define COMPACT_ANGLE_LOG_WARN COMPACT_ANGLE_LOG_EX_WARN(LogMessage) +#define COMPACT_ANGLE_LOG_ERR COMPACT_ANGLE_LOG_EX_ERR(LogMessage) + +#define ANGLE_LOG_IS_ON(severity) (::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_##severity)) + +// Helper macro which avoids evaluating the arguments to a stream if the condition doesn't hold. +// Condition is evaluated once and only once. +#define ANGLE_LAZY_STREAM(stream, condition) \ + !(condition) ? static_cast(0) : ::gl::priv::LogMessageVoidify() & (stream) + +// We use the preprocessor's merging operator, "##", so that, e.g., +// ANGLE_LOG(EVENT) becomes the token COMPACT_ANGLE_LOG_EVENT. There's some funny +// subtle difference between ostream member streaming functions (e.g., +// ostream::operator<<(int) and ostream non-member streaming functions +// (e.g., ::operator<<(ostream&, string&): it turns out that it's +// impossible to stream something like a string directly to an unnamed +// ostream. We employ a neat hack by calling the stream() member +// function of LogMessage which seems to avoid the problem. +#define ANGLE_LOG_STREAM(severity) COMPACT_ANGLE_LOG_##severity.stream() + +#define ANGLE_LOG(severity) ANGLE_LAZY_STREAM(ANGLE_LOG_STREAM(severity), ANGLE_LOG_IS_ON(severity)) + +} // namespace gl #if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS) #define ANGLE_TRACE_ENABLED #endif #define ANGLE_EMPTY_STATEMENT for (;;) break - -// A macro to output a trace of a function call and its arguments to the debugging log -#if defined(ANGLE_TRACE_ENABLED) -#define TRACE(message, ...) gl::trace(true, gl::MESSAGE_TRACE, "trace: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__) -#else -#define TRACE(message, ...) (void(0)) +#if !defined(NDEBUG) || defined(ANGLE_ENABLE_RELEASE_ASSERTS) +#define ANGLE_ENABLE_ASSERTS #endif -// A macro to output a function call and its arguments to the debugging log, to denote an item in need of fixing. -#if defined(ANGLE_TRACE_ENABLED) -#define FIXME(message, ...) gl::trace(false, gl::MESSAGE_FIXME, "fixme: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__) -#else -#define FIXME(message, ...) (void(0)) -#endif - -// A macro to output a function call and its arguments to the debugging log, in case of error. -#if defined(ANGLE_TRACE_ENABLED) -#define ERR(message, ...) gl::trace(false, gl::MESSAGE_ERR, "err: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__) -#else -#define ERR(message, ...) (void(0)) -#endif +#define WARN() ANGLE_LOG(WARN) +#define ERR() ANGLE_LOG(ERR) // A macro to log a performance event around a scope. #if defined(ANGLE_TRACE_ENABLED) @@ -97,54 +217,70 @@ bool DebugAnnotationsActive(); #define EVENT(message, ...) (void(0)) #endif -#if defined(ANGLE_TRACE_ENABLED) -#undef ANGLE_TRACE_ENABLED +#if defined(COMPILER_GCC) || defined(__clang__) +#define ANGLE_CRASH() __builtin_trap() +#else +#define ANGLE_CRASH() ((void)(*(volatile char *)0 = 0)) #endif -// A macro asserting a condition and outputting failures to the debug log #if !defined(NDEBUG) -#define ASSERT(expression) { \ - if(!(expression)) \ - ERR("\t! Assert failed in %s(%d): %s\n", __FUNCTION__, __LINE__, #expression); \ - assert(expression); \ - } ANGLE_EMPTY_STATEMENT -#define UNUSED_ASSERTION_VARIABLE(variable) +#define ANGLE_ASSERT_IMPL(expression) assert(expression) #else -#define ASSERT(expression) (void(0)) -#define UNUSED_ASSERTION_VARIABLE(variable) ((void)variable) -#endif +// TODO(jmadill): Detect if debugger is attached and break. +#define ANGLE_ASSERT_IMPL(expression) ANGLE_CRASH() +#endif // !defined(NDEBUG) + +// A macro asserting a condition and outputting failures to the debug log +#if defined(ANGLE_ENABLE_ASSERTS) +#define ASSERT(expression) \ + (expression ? static_cast(0) : ((ERR() << "\t! Assert failed in " << __FUNCTION__ << "(" \ + << __LINE__ << "): " << #expression), \ + ANGLE_ASSERT_IMPL(expression))) +#else +// These are just dummy values. +#define COMPACT_ANGLE_LOG_EX_ASSERT(ClassName, ...) \ + COMPACT_ANGLE_LOG_EX_EVENT(ClassName, ##__VA_ARGS__) +#define COMPACT_ANGLE_LOG_ASSERT COMPACT_ANGLE_LOG_EVENT +namespace gl +{ +constexpr LogSeverity LOG_ASSERT = LOG_EVENT; +} // namespace gl + +#define ASSERT(condition) \ + ANGLE_LAZY_STREAM(ANGLE_LOG_STREAM(ASSERT), false ? !(condition) : false) \ + << "Check failed: " #condition ". " +#endif // defined(ANGLE_ENABLE_ASSERTS) #define UNUSED_VARIABLE(variable) ((void)variable) // A macro to indicate unimplemented functionality - -#if defined (ANGLE_TEST_CONFIG) +#ifndef NOASSERT_UNIMPLEMENTED #define NOASSERT_UNIMPLEMENTED 1 #endif -// Define NOASSERT_UNIMPLEMENTED to non zero to skip the assert fail in the unimplemented checks -// This will allow us to test with some automated test suites (eg dEQP) without crashing -#ifndef NOASSERT_UNIMPLEMENTED -#define NOASSERT_UNIMPLEMENTED 0 -#endif - -#if !defined(NDEBUG) -#define UNIMPLEMENTED() { \ - FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__); \ - assert(NOASSERT_UNIMPLEMENTED); \ - } ANGLE_EMPTY_STATEMENT -#else - #define UNIMPLEMENTED() FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__) -#endif +#if defined(ANGLE_TRACE_ENABLED) || defined(ANGLE_ENABLE_ASSERTS) +#define UNIMPLEMENTED() \ + { \ + ERR() << "\t! Unimplemented: " << __FUNCTION__ << "(" << __FILE__ << ":" << __LINE__ \ + << ")"; \ + ASSERT(NOASSERT_UNIMPLEMENTED); \ + } \ + ANGLE_EMPTY_STATEMENT // A macro for code which is not expected to be reached under valid assumptions -#if !defined(NDEBUG) -#define UNREACHABLE() { \ - ERR("\t! Unreachable reached: %s(%d)\n", __FUNCTION__, __LINE__); \ - assert(false); \ - } ANGLE_EMPTY_STATEMENT +#define UNREACHABLE() \ + ((ERR() << "\t! Unreachable reached: " << __FUNCTION__ << "(" << __FILE__ << ":" << __LINE__ \ + << ")"), \ + ASSERT(false)) #else - #define UNREACHABLE() ERR("\t! Unreachable reached: %s(%d)\n", __FUNCTION__, __LINE__) -#endif +#define UNIMPLEMENTED() \ + { \ + ASSERT(NOASSERT_UNIMPLEMENTED); \ + } \ + ANGLE_EMPTY_STATEMENT + +// A macro for code which is not expected to be reached under valid assumptions +#define UNREACHABLE() ASSERT(false) +#endif // defined(ANGLE_TRACE_ENABLED) || defined(ANGLE_ENABLE_ASSERTS) #endif // COMMON_DEBUG_H_ diff --git a/src/3rdparty/angle/src/common/event_tracer.cpp b/src/3rdparty/angle/src/common/event_tracer.cpp index c9eb5e3073..6dc8458acc 100644 --- a/src/3rdparty/angle/src/common/event_tracer.cpp +++ b/src/3rdparty/angle/src/common/event_tracer.cpp @@ -11,10 +11,11 @@ namespace angle const unsigned char *GetTraceCategoryEnabledFlag(const char *name) { - angle::Platform *platform = ANGLEPlatformCurrent(); + auto *platform = ANGLEPlatformCurrent(); ASSERT(platform); - const unsigned char *categoryEnabledFlag = platform->getTraceCategoryEnabledFlag(name); + const unsigned char *categoryEnabledFlag = + platform->getTraceCategoryEnabledFlag(platform, name); if (categoryEnabledFlag != nullptr) { return categoryEnabledFlag; @@ -24,33 +25,31 @@ const unsigned char *GetTraceCategoryEnabledFlag(const char *name) return &disabled; } -Platform::TraceEventHandle AddTraceEvent(char phase, const unsigned char* categoryGroupEnabled, const char* name, unsigned long long id, - int numArgs, const char** argNames, const unsigned char* argTypes, - const unsigned long long* argValues, unsigned char flags) +angle::TraceEventHandle AddTraceEvent(char phase, + const unsigned char *categoryGroupEnabled, + const char *name, + unsigned long long id, + int numArgs, + const char **argNames, + const unsigned char *argTypes, + const unsigned long long *argValues, + unsigned char flags) { - angle::Platform *platform = ANGLEPlatformCurrent(); + auto *platform = ANGLEPlatformCurrent(); ASSERT(platform); - double timestamp = platform->monotonicallyIncreasingTime(); + double timestamp = platform->monotonicallyIncreasingTime(platform); if (timestamp != 0) { - angle::Platform::TraceEventHandle handle = - platform->addTraceEvent(phase, - categoryGroupEnabled, - name, - id, - timestamp, - numArgs, - argNames, - argTypes, - argValues, - flags); + angle::TraceEventHandle handle = + platform->addTraceEvent(platform, phase, categoryGroupEnabled, name, id, timestamp, + numArgs, argNames, argTypes, argValues, flags); ASSERT(handle != 0); return handle; } - return static_cast(0); + return static_cast(0); } } // namespace angle diff --git a/src/3rdparty/angle/src/common/event_tracer.h b/src/3rdparty/angle/src/common/event_tracer.h index ed70f249d2..9b30c750c1 100644 --- a/src/3rdparty/angle/src/common/event_tracer.h +++ b/src/3rdparty/angle/src/common/event_tracer.h @@ -12,11 +12,15 @@ namespace angle { const unsigned char *GetTraceCategoryEnabledFlag(const char* name); -Platform::TraceEventHandle AddTraceEvent(char phase, const unsigned char* categoryGroupEnabled, const char* name, - unsigned long long id, int numArgs, const char** argNames, - const unsigned char* argTypes, const unsigned long long* argValues, - unsigned char flags); - +angle::TraceEventHandle AddTraceEvent(char phase, + const unsigned char *categoryGroupEnabled, + const char *name, + unsigned long long id, + int numArgs, + const char **argNames, + const unsigned char *argTypes, + const unsigned long long *argValues, + unsigned char flags); } #endif // COMMON_EVENT_TRACER_H_ diff --git a/src/3rdparty/angle/src/common/mathutil.cpp b/src/3rdparty/angle/src/common/mathutil.cpp index 927b6ebebe..5db997c664 100644 --- a/src/3rdparty/angle/src/common/mathutil.cpp +++ b/src/3rdparty/angle/src/common/mathutil.cpp @@ -14,6 +14,9 @@ namespace gl { +namespace +{ + struct RGB9E5Data { unsigned int R : 9; @@ -23,17 +26,20 @@ struct RGB9E5Data }; // B is the exponent bias (15) -static const int g_sharedexp_bias = 15; +constexpr int g_sharedexp_bias = 15; // N is the number of mantissa bits per component (9) -static const int g_sharedexp_mantissabits = 9; +constexpr int g_sharedexp_mantissabits = 9; // Emax is the maximum allowed biased exponent value (31) -static const int g_sharedexp_maxexponent = 31; +constexpr int g_sharedexp_maxexponent = 31; -static const float g_sharedexp_max = ((pow(2.0f, g_sharedexp_mantissabits) - 1) / - pow(2.0f, g_sharedexp_mantissabits)) * - pow(2.0f, g_sharedexp_maxexponent - g_sharedexp_bias); +constexpr float g_sharedexp_max = + ((static_cast(1 << g_sharedexp_mantissabits) - 1) / + static_cast(1 << g_sharedexp_mantissabits)) * + static_cast(1 << (g_sharedexp_maxexponent - g_sharedexp_bias)); + +} // anonymous namespace unsigned int convertRGBFloatsTo999E5(float red, float green, float blue) { @@ -64,4 +70,4 @@ void convert999E5toRGBFloats(unsigned int input, float *red, float *green, float *blue = inputData->B * pow(2.0f, (int)inputData->E - g_sharedexp_bias - g_sharedexp_mantissabits); } -} +} // namespace gl diff --git a/src/3rdparty/angle/src/common/mathutil.h b/src/3rdparty/angle/src/common/mathutil.h index 3de62aef10..372e432066 100644 --- a/src/3rdparty/angle/src/common/mathutil.h +++ b/src/3rdparty/angle/src/common/mathutil.h @@ -9,9 +9,6 @@ #ifndef COMMON_MATHUTIL_H_ #define COMMON_MATHUTIL_H_ -#include "common/debug.h" -#include "common/platform.h" - #include #include #include @@ -19,25 +16,27 @@ #include #include +#include + +#include "common/debug.h" +#include "common/platform.h" + +namespace angle +{ +using base::CheckedNumeric; +using base::IsValueInRangeForNumericType; +} + namespace gl { const unsigned int Float32One = 0x3F800000; const unsigned short Float16One = 0x3C00; -struct Vector4 -{ - Vector4() {} - Vector4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {} - - float x; - float y; - float z; - float w; -}; - -inline bool isPow2(int x) +template +inline bool isPow2(T x) { + static_assert(std::is_integral::value, "isPow2 must be called on an integer type."); return (x & (x - 1)) == 0 && (x != 0); } @@ -61,37 +60,52 @@ inline unsigned int ceilPow2(unsigned int x) return x; } -inline int clampToInt(unsigned int x) -{ - return static_cast(std::min(x, static_cast(std::numeric_limits::max()))); -} - template inline DestT clampCast(SrcT value) { - static const DestT destLo = std::numeric_limits::min(); - static const DestT destHi = std::numeric_limits::max(); - static const SrcT srcLo = static_cast(destLo); - static const SrcT srcHi = static_cast(destHi); + // For floating-point types with denormalization, min returns the minimum positive normalized + // value. To find the value that has no values less than it, use numeric_limits::lowest. + constexpr const long double destLo = + static_cast(std::numeric_limits::lowest()); + constexpr const long double destHi = + static_cast(std::numeric_limits::max()); + constexpr const long double srcLo = + static_cast(std::numeric_limits::lowest()); + constexpr long double srcHi = static_cast(std::numeric_limits::max()); - // When value is outside of or equal to the limits for DestT we use the DestT limit directly. - // This avoids undefined behaviors due to loss of precision when converting from floats to - // integers: - // destHi for ints is 2147483647 but the closest float number is around 2147483648, so when - // doing a conversion from float to int we run into an UB because the float is outside of the - // range representable by the int. - if (value <= srcLo) + if (destHi < srcHi) { - return destLo; + DestT destMax = std::numeric_limits::max(); + if (value >= static_cast(destMax)) + { + return destMax; + } } - else if (value >= srcHi) + + if (destLo > srcLo) { - return destHi; - } - else - { - return static_cast(value); + DestT destLow = std::numeric_limits::lowest(); + if (value <= static_cast(destLow)) + { + return destLow; + } } + + return static_cast(value); +} + +// Specialize clampCast for bool->int conversion to avoid MSVS 2015 performance warning when the max +// value is casted to the source type. +template <> +inline unsigned int clampCast(bool value) +{ + return static_cast(value); +} + +template <> +inline int clampCast(bool value) +{ + return static_cast(value); } template @@ -127,7 +141,7 @@ inline unsigned int unorm(float x) inline bool supportsSSE2() { -#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) +#if defined(ANGLE_USE_SSE) static bool checked = false; static bool supports = false; @@ -136,21 +150,22 @@ inline bool supportsSSE2() return supports; } - int info[4]; - __cpuid(info, 0); - - if (info[0] >= 1) +#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) { - __cpuid(info, 1); + int info[4]; + __cpuid(info, 0); - supports = (info[3] >> 26) & 1; + if (info[0] >= 1) + { + __cpuid(info, 1); + + supports = (info[3] >> 26) & 1; + } } - +#endif // defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) checked = true; - return supports; -#else - UNIMPLEMENTED(); +#else // defined(ANGLE_USE_SSE) return false; #endif } @@ -467,6 +482,43 @@ inline T shiftData(T input) return (input & mask) << inputBitStart; } +inline unsigned int CountLeadingZeros(uint32_t x) +{ + // Use binary search to find the amount of leading zeros. + unsigned int zeros = 32u; + uint32_t y; + + y = x >> 16u; + if (y != 0) + { + zeros = zeros - 16u; + x = y; + } + y = x >> 8u; + if (y != 0) + { + zeros = zeros - 8u; + x = y; + } + y = x >> 4u; + if (y != 0) + { + zeros = zeros - 4u; + x = y; + } + y = x >> 2u; + if (y != 0) + { + zeros = zeros - 2u; + x = y; + } + y = x >> 1u; + if (y != 0) + { + return zeros - 2u; + } + return zeros - x; +} inline unsigned char average(unsigned char a, unsigned char b) { @@ -520,38 +572,65 @@ inline unsigned int averageFloat10(unsigned int a, unsigned int b) } template -struct Range +class Range { + public: Range() {} - Range(T lo, T hi) : start(lo), end(hi) { ASSERT(lo <= hi); } + Range(T lo, T hi) : mLow(lo), mHigh(hi) {} - T start; - T end; - - T length() const { return end - start; } + T length() const { return (empty() ? 0 : (mHigh - mLow)); } bool intersects(Range other) { - if (start <= other.start) + if (mLow <= other.mLow) { - return other.start < end; + return other.mLow < mHigh; } else { - return start < other.end; + return mLow < other.mHigh; } } + // Assumes that end is non-inclusive.. for example, extending to 5 will make "end" 6. void extend(T value) { - start = value > start ? value : start; - end = value < end ? value : end; + mLow = value < mLow ? value : mLow; + mHigh = value >= mHigh ? (value + 1) : mHigh; } - bool empty() const + bool empty() const { return mHigh <= mLow; } + + bool contains(T value) const { return value >= mLow && value < mHigh; } + + class Iterator final { - return end <= start; - } + public: + Iterator(T value) : mCurrent(value) {} + + Iterator &operator++() + { + mCurrent++; + return *this; + } + bool operator==(const Iterator &other) const { return mCurrent == other.mCurrent; } + bool operator!=(const Iterator &other) const { return mCurrent != other.mCurrent; } + T operator*() const { return mCurrent; } + + private: + T mCurrent; + }; + + Iterator begin() const { return Iterator(mLow); } + + Iterator end() const { return Iterator(mHigh); } + + T low() const { return mLow; } + T high() const { return mHigh; } + + private: + T mLow; + T mHigh; }; typedef Range RangeI; @@ -577,6 +656,22 @@ struct IndexRange size_t vertexIndexCount; }; +// Combine a floating-point value representing a mantissa (x) and an integer exponent (exp) into a +// floating-point value. As in GLSL ldexp() built-in. +inline float Ldexp(float x, int exp) +{ + if (exp > 128) + { + return std::numeric_limits::infinity(); + } + if (exp < -126) + { + return 0.0f; + } + double result = static_cast(x) * std::pow(2.0, static_cast(exp)); + return static_cast(result); +} + // First, both normalized floating-point values are converted into 16-bit integer values. // Then, the results are packed into the returned 32-bit unsigned integer. // The first float value will be written to the least significant bits of the output; @@ -632,6 +727,86 @@ inline void unpackUnorm2x16(uint32_t u, float *f1, float *f2) *f2 = static_cast(mostSignificantBits) / 65535.0f; } +// Helper functions intended to be used only here. +namespace priv +{ + +inline uint8_t ToPackedUnorm8(float f) +{ + return static_cast(roundf(clamp(f, 0.0f, 1.0f) * 255.0f)); +} + +inline int8_t ToPackedSnorm8(float f) +{ + return static_cast(roundf(clamp(f, -1.0f, 1.0f) * 127.0f)); +} + +} // namespace priv + +// Packs 4 normalized unsigned floating-point values to a single 32-bit unsigned integer. Works +// similarly to packUnorm2x16. The floats are clamped to the range 0.0 to 1.0, and written to the +// unsigned integer starting from the least significant bits. +inline uint32_t PackUnorm4x8(float f1, float f2, float f3, float f4) +{ + uint8_t bits[4]; + bits[0] = priv::ToPackedUnorm8(f1); + bits[1] = priv::ToPackedUnorm8(f2); + bits[2] = priv::ToPackedUnorm8(f3); + bits[3] = priv::ToPackedUnorm8(f4); + uint32_t result = 0u; + for (int i = 0; i < 4; ++i) + { + int shift = i * 8; + result |= (static_cast(bits[i]) << shift); + } + return result; +} + +// Unpacks 4 normalized unsigned floating-point values from a single 32-bit unsigned integer into f. +// Works similarly to unpackUnorm2x16. The floats are unpacked starting from the least significant +// bits. +inline void UnpackUnorm4x8(uint32_t u, float *f) +{ + for (int i = 0; i < 4; ++i) + { + int shift = i * 8; + uint8_t bits = static_cast((u >> shift) & 0xFF); + f[i] = static_cast(bits) / 255.0f; + } +} + +// Packs 4 normalized signed floating-point values to a single 32-bit unsigned integer. The floats +// are clamped to the range -1.0 to 1.0, and written to the unsigned integer starting from the least +// significant bits. +inline uint32_t PackSnorm4x8(float f1, float f2, float f3, float f4) +{ + int8_t bits[4]; + bits[0] = priv::ToPackedSnorm8(f1); + bits[1] = priv::ToPackedSnorm8(f2); + bits[2] = priv::ToPackedSnorm8(f3); + bits[3] = priv::ToPackedSnorm8(f4); + uint32_t result = 0u; + for (int i = 0; i < 4; ++i) + { + int shift = i * 8; + result |= ((static_cast(bits[i]) & 0xFF) << shift); + } + return result; +} + +// Unpacks 4 normalized signed floating-point values from a single 32-bit unsigned integer into f. +// Works similarly to unpackSnorm2x16. The floats are unpacked starting from the least significant +// bits, and clamped to the range -1.0 to 1.0. +inline void UnpackSnorm4x8(uint32_t u, float *f) +{ + for (int i = 0; i < 4; ++i) + { + int shift = i * 8; + int8_t bits = static_cast((u >> shift) & 0xFF); + f[i] = clamp(static_cast(bits) / 127.0f, -1.0f, 1.0f); + } +} + // Returns an unsigned integer obtained by converting the two floating-point values to the 16-bit // floating-point representation found in the OpenGL ES Specification, and then packing these // two 16-bit integers into a 32-bit unsigned integer. @@ -658,6 +833,179 @@ inline void unpackHalf2x16(uint32_t u, float *f1, float *f2) *f2 = float16ToFloat32(mostSignificantBits); } +inline uint8_t sRGBToLinear(uint8_t srgbValue) +{ + float value = srgbValue / 255.0f; + if (value <= 0.04045f) + { + value = value / 12.92f; + } + else + { + value = std::pow((value + 0.055f) / 1.055f, 2.4f); + } + return static_cast(clamp(value * 255.0f + 0.5f, 0.0f, 255.0f)); +} + +inline uint8_t linearToSRGB(uint8_t linearValue) +{ + float value = linearValue / 255.0f; + if (value <= 0.0f) + { + value = 0.0f; + } + else if (value < 0.0031308f) + { + value = value * 12.92f; + } + else if (value < 1.0f) + { + value = std::pow(value, 0.41666f) * 1.055f - 0.055f; + } + else + { + value = 1.0f; + } + return static_cast(clamp(value * 255.0f + 0.5f, 0.0f, 255.0f)); +} + +// Reverse the order of the bits. +inline uint32_t BitfieldReverse(uint32_t value) +{ + // TODO(oetuaho@nvidia.com): Optimize this if needed. There don't seem to be compiler intrinsics + // for this, and right now it's not used in performance-critical paths. + uint32_t result = 0u; + for (size_t j = 0u; j < 32u; ++j) + { + result |= (((value >> j) & 1u) << (31u - j)); + } + return result; +} + +// Count the 1 bits. +#if defined(ANGLE_PLATFORM_WINDOWS) +#if defined(_M_ARM) +inline int BitCount(uint32_t bits) +{ + bits = bits - ((bits >> 1) & 0x55555555); + bits = (bits & 0x33333333) + ((bits >> 2) & 0x33333333); + return (((bits + (bits >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24; +} +#else // _M_ARM +inline int BitCount(uint32_t bits) +{ + return static_cast(__popcnt(bits)); +} +#if defined(ANGLE_IS_64_BIT_CPU) +inline int BitCount(uint64_t bits) +{ + return static_cast(__popcnt64(bits)); +} +#endif // !_M_ARM +#endif // defined(ANGLE_IS_64_BIT_CPU) +#endif // defined(ANGLE_PLATFORM_WINDOWS) + +#if defined(ANGLE_PLATFORM_POSIX) +inline int BitCount(uint32_t bits) +{ + return __builtin_popcount(bits); +} + +#if defined(ANGLE_IS_64_BIT_CPU) +inline int BitCount(uint64_t bits) +{ + return __builtin_popcountll(bits); +} +#endif // defined(ANGLE_IS_64_BIT_CPU) +#endif // defined(ANGLE_PLATFORM_POSIX) + +#if defined(ANGLE_PLATFORM_WINDOWS) +// Return the index of the least significant bit set. Indexing is such that bit 0 is the least +// significant bit. Implemented for different bit widths on different platforms. +inline unsigned long ScanForward(uint32_t bits) +{ + ASSERT(bits != 0u); + unsigned long firstBitIndex = 0ul; + unsigned char ret = _BitScanForward(&firstBitIndex, bits); + ASSERT(ret != 0u); + return firstBitIndex; +} + +#if defined(ANGLE_IS_64_BIT_CPU) +inline unsigned long ScanForward(uint64_t bits) +{ + ASSERT(bits != 0u); + unsigned long firstBitIndex = 0ul; + unsigned char ret = _BitScanForward64(&firstBitIndex, bits); + ASSERT(ret != 0u); + return firstBitIndex; +} +#endif // defined(ANGLE_IS_64_BIT_CPU) +#endif // defined(ANGLE_PLATFORM_WINDOWS) + +#if defined(ANGLE_PLATFORM_POSIX) +inline unsigned long ScanForward(uint32_t bits) +{ + ASSERT(bits != 0u); + return static_cast(__builtin_ctz(bits)); +} + +#if defined(ANGLE_IS_64_BIT_CPU) +inline unsigned long ScanForward(uint64_t bits) +{ + ASSERT(bits != 0u); + return static_cast(__builtin_ctzll(bits)); +} +#endif // defined(ANGLE_IS_64_BIT_CPU) +#endif // defined(ANGLE_PLATFORM_POSIX) + +// Return the index of the most significant bit set. Indexing is such that bit 0 is the least +// significant bit. +inline unsigned long ScanReverse(unsigned long bits) +{ + ASSERT(bits != 0u); +#if defined(ANGLE_PLATFORM_WINDOWS) + unsigned long lastBitIndex = 0ul; + unsigned char ret = _BitScanReverse(&lastBitIndex, bits); + ASSERT(ret != 0u); + return lastBitIndex; +#elif defined(ANGLE_PLATFORM_POSIX) + return static_cast(sizeof(unsigned long) * CHAR_BIT - 1 - __builtin_clzl(bits)); +#else +#error Please implement bit-scan-reverse for your platform! +#endif +} + +// Returns -1 on 0, otherwise the index of the least significant 1 bit as in GLSL. +template +int FindLSB(T bits) +{ + static_assert(std::is_integral::value, "must be integral type."); + if (bits == 0u) + { + return -1; + } + else + { + return static_cast(ScanForward(bits)); + } +} + +// Returns -1 on 0, otherwise the index of the most significant 1 bit as in GLSL. +template +int FindMSB(T bits) +{ + static_assert(std::is_integral::value, "must be integral type."); + if (bits == 0u) + { + return -1; + } + else + { + return static_cast(ScanReverse(bits)); + } +} + // Returns whether the argument is Not a Number. // IEEE 754 single precision NaN representation: Exponent(8 bits) - 255, Mantissa(23 bits) - non-zero. inline bool isNaN(float f) @@ -676,15 +1024,92 @@ inline bool isInf(float f) return ((bitCast(f) & 0x7f800000u) == 0x7f800000u) && !(bitCast(f) & 0x7fffffu); } +namespace priv +{ +template +struct iSquareRoot +{ + static constexpr unsigned int solve() + { + return (R * R > N) + ? 0 + : ((R * R == N) ? R : static_cast(iSquareRoot::value)); + } + enum Result + { + value = iSquareRoot::solve() + }; +}; + +template +struct iSquareRoot +{ + enum result + { + value = N + }; +}; + +} // namespace priv + +template +constexpr unsigned int iSquareRoot() +{ + return priv::iSquareRoot::value; } +// Sum, difference and multiplication operations for signed ints that wrap on 32-bit overflow. +// +// Unsigned types are defined to do arithmetic modulo 2^n in C++. For signed types, overflow +// behavior is undefined. + +template +inline T WrappingSum(T lhs, T rhs) +{ + uint32_t lhsUnsigned = static_cast(lhs); + uint32_t rhsUnsigned = static_cast(rhs); + return static_cast(lhsUnsigned + rhsUnsigned); +} + +template +inline T WrappingDiff(T lhs, T rhs) +{ + uint32_t lhsUnsigned = static_cast(lhs); + uint32_t rhsUnsigned = static_cast(rhs); + return static_cast(lhsUnsigned - rhsUnsigned); +} + +inline int32_t WrappingMul(int32_t lhs, int32_t rhs) +{ + int64_t lhsWide = static_cast(lhs); + int64_t rhsWide = static_cast(rhs); + // The multiplication is guaranteed not to overflow. + int64_t resultWide = lhsWide * rhsWide; + // Implement the desired wrapping behavior by masking out the high-order 32 bits. + resultWide = resultWide & 0xffffffffll; + // Casting to a narrower signed type is fine since the casted value is representable in the + // narrower type. + return static_cast(resultWide); +} + +} // namespace gl + namespace rx { template T roundUp(const T value, const T alignment) { - return value + alignment - 1 - (value - 1) % alignment; + auto temp = value + alignment - static_cast(1); + return temp - temp % alignment; +} + +template +angle::CheckedNumeric CheckedRoundUp(const T value, const T alignment) +{ + angle::CheckedNumeric checkedValue(value); + angle::CheckedNumeric checkedAlignment(alignment); + return roundUp(checkedValue, checkedAlignment); } inline unsigned int UnsignedCeilDivide(unsigned int value, unsigned int divisor) @@ -693,26 +1118,6 @@ inline unsigned int UnsignedCeilDivide(unsigned int value, unsigned int divisor) return (divided + ((value % divisor == 0) ? 0 : 1)); } -template -inline bool IsUnsignedAdditionSafe(T lhs, T rhs) -{ - static_assert(!std::numeric_limits::is_signed, "T must be unsigned."); - return (rhs <= std::numeric_limits::max() - lhs); -} - -template -inline bool IsUnsignedMultiplicationSafe(T lhs, T rhs) -{ - static_assert(!std::numeric_limits::is_signed, "T must be unsigned."); - return (lhs == T(0) || rhs == T(0) || (rhs <= std::numeric_limits::max() / lhs)); -} - -template -inline bool IsIntegerCastSafe(BigIntT bigValue) -{ - return (static_cast(static_cast(bigValue)) == bigValue); -} - #if defined(_MSC_VER) #define ANGLE_ROTL(x,y) _rotl(x,y) @@ -730,8 +1135,8 @@ inline uint16_t RotR16(uint16_t x, int8_t r) return (x >> r) | (x << (16 - r)); } -#define ANGLE_ROTL(x,y) RotL(x,y) -#define ANGLE_ROTR16(x,y) RotR16(x,y) +#define ANGLE_ROTL(x, y) ::rx::RotL(x, y) +#define ANGLE_ROTR16(x, y) ::rx::RotR16(x, y) #endif // namespace rx diff --git a/src/3rdparty/angle/src/common/matrix_utils.h b/src/3rdparty/angle/src/common/matrix_utils.h index 6f3187c3e8..aa3f89536e 100644 --- a/src/3rdparty/angle/src/common/matrix_utils.h +++ b/src/3rdparty/angle/src/common/matrix_utils.h @@ -16,6 +16,7 @@ #include #include "common/debug.h" +#include "common/mathutil.h" namespace angle { @@ -337,6 +338,42 @@ class Matrix return result; } + void setToIdentity() + { + ASSERT(rows() == columns()); + + const auto one = T(1); + const auto zero = T(0); + + for (auto &e : mElements) + e = zero; + + for (unsigned int i = 0; i < rows(); ++i) + { + const auto pos = i * columns() + (i % columns()); + mElements[pos] = one; + } + } + + template + static void setToIdentity(T(&matrix)[Size]) + { + static_assert(gl::iSquareRoot() != 0, "Matrix is not square."); + + const auto cols = gl::iSquareRoot(); + const auto one = T(1); + const auto zero = T(0); + + for (auto &e : matrix) + e = zero; + + for (unsigned int i = 0; i < cols; ++i) + { + const auto pos = i * cols + (i % cols); + matrix[pos] = one; + } + } + private: std::vector mElements; unsigned int mRows; diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h index be4cb94987..47cd57b999 100644 --- a/src/3rdparty/angle/src/common/platform.h +++ b/src/3rdparty/angle/src/common/platform.h @@ -27,7 +27,9 @@ defined(__sun) || \ defined(__GLIBC__) || \ defined(__GNU__) || \ - defined(__QNX__) + defined(__QNX__) || \ + defined(__Fuchsia__) || \ + defined(__HAIKU__) # define ANGLE_PLATFORM_POSIX 1 #else # error Unsupported platform. @@ -57,28 +59,22 @@ # endif # if defined(ANGLE_ENABLE_D3D11) -# include -# include -# include -# if defined(__MINGW32__) && !defined(__d3d11sdklayers_h__) -# define ANGLE_MINGW32_COMPAT -# endif -# if defined(_MSC_VER) && _MSC_VER >= 1800 -# define ANGLE_ENABLE_D3D11_1 -# endif -# if defined(ANGLE_ENABLE_D3D11_1) -# include -# include -# endif -# include +#include +#include +#include +#include +#include +#include # endif +#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11) +#include +#endif + # if defined(ANGLE_ENABLE_WINDOWS_STORE) # include # if defined(_DEBUG) -# if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP # include -# endif # include # endif # endif @@ -87,8 +83,21 @@ # undef far #endif -#if !defined(_M_ARM) && !defined(ANGLE_PLATFORM_ANDROID) -# define ANGLE_USE_SSE +#if defined(_MSC_VER) && !defined(_M_ARM) +#include +#define ANGLE_USE_SSE +#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) && !defined(__MINGW32__) +#include +#define ANGLE_USE_SSE #endif +// Mips and arm devices need to include stddef for size_t. +#if defined(__mips__) || defined(__arm__) || defined(__aarch64__) +#include +#endif + +// The MemoryBarrier function name collides with a macro under Windows +// We will undef the macro so that the function name does not get replaced +#undef MemoryBarrier + #endif // COMMON_PLATFORM_H_ diff --git a/src/3rdparty/angle/src/common/string_utils.cpp b/src/3rdparty/angle/src/common/string_utils.cpp index acb0376bf9..26f384bb2a 100644 --- a/src/3rdparty/angle/src/common/string_utils.cpp +++ b/src/3rdparty/angle/src/common/string_utils.cpp @@ -9,9 +9,14 @@ #include "string_utils.h" +#include +#include +#include #include #include +#include "common/platform.h" + namespace angle { @@ -133,4 +138,76 @@ bool ReadFileToString(const std::string &path, std::string *stringOut) return !inFile.fail(); } +Optional> WidenString(size_t length, const char *cString) +{ + std::vector wcstring(length + 1); +#if !defined(ANGLE_PLATFORM_WINDOWS) + size_t written = mbstowcs(wcstring.data(), cString, length + 1); + if (written == 0) + { + return Optional>::Invalid(); + } +#else + size_t convertedChars = 0; + errno_t err = mbstowcs_s(&convertedChars, wcstring.data(), length + 1, cString, _TRUNCATE); + if (err != 0) + { + return Optional>::Invalid(); + } +#endif + return Optional>(wcstring); } + +bool BeginsWith(const std::string &str, const std::string &prefix) +{ + return strncmp(str.c_str(), prefix.c_str(), prefix.length()) == 0; +} + +bool BeginsWith(const std::string &str, const char *prefix) +{ + return strncmp(str.c_str(), prefix, strlen(prefix)) == 0; +} + +bool BeginsWith(const char *str, const char *prefix) +{ + return strncmp(str, prefix, strlen(prefix)) == 0; +} + +bool BeginsWith(const std::string &str, const std::string &prefix, const size_t prefixLength) +{ + return strncmp(str.c_str(), prefix.c_str(), prefixLength) == 0; +} + +bool EndsWith(const std::string &str, const char *suffix) +{ + const auto len = strlen(suffix); + if (len > str.size()) + return false; + + const char *end = str.c_str() + str.size() - len; + + return memcmp(end, suffix, len) == 0; +} + +void ToLower(std::string *str) +{ + for (auto &ch : *str) + { + ch = static_cast(::tolower(ch)); + } +} + +bool ReplaceSubstring(std::string *str, + const std::string &substring, + const std::string &replacement) +{ + size_t replacePos = str->find(substring); + if (replacePos == std::string::npos) + { + return false; + } + str->replace(replacePos, substring.size(), replacement); + return true; +} + +} // namespace angle diff --git a/src/3rdparty/angle/src/common/string_utils.h b/src/3rdparty/angle/src/common/string_utils.h index 131b17e086..07bf1ff81a 100644 --- a/src/3rdparty/angle/src/common/string_utils.h +++ b/src/3rdparty/angle/src/common/string_utils.h @@ -13,6 +13,8 @@ #include #include +#include "common/Optional.h" + namespace angle { @@ -44,6 +46,40 @@ bool HexStringToUInt(const std::string &input, unsigned int *uintOut); bool ReadFileToString(const std::string &path, std::string *stringOut); -} +Optional> WidenString(size_t length, const char *cString); + +// Check if the string str begins with the given prefix. +// The comparison is case sensitive. +bool BeginsWith(const std::string &str, const std::string &prefix); + +// Check if the string str begins with the given prefix. +// Prefix may not be NULL and needs to be NULL terminated. +// The comparison is case sensitive. +bool BeginsWith(const std::string &str, const char *prefix); + +// Check if the string str begins with the given prefix. +// str and prefix may not be NULL and need to be NULL terminated. +// The comparison is case sensitive. +bool BeginsWith(const char *str, const char *prefix); + +// Check if the string str begins with the first prefixLength characters of the given prefix. +// The length of the prefix string should be greater than or equal to prefixLength. +// The comparison is case sensitive. +bool BeginsWith(const std::string &str, const std::string &prefix, const size_t prefixLength); + +// Check if the string str ends with the given suffix. +// Suffix may not be NUL and needs to be NULL terminated. +// The comparison is case sensitive. +bool EndsWith(const std::string& str, const char* suffix); + +// Convert to lower-case. +void ToLower(std::string *str); + +// Replaces the substring 'substring' in 'str' with 'replacement'. Returns true if successful. +bool ReplaceSubstring(std::string *str, + const std::string &substring, + const std::string &replacement); + +} // namespace angle #endif // LIBANGLE_STRING_UTILS_H_ diff --git a/src/3rdparty/angle/src/common/system_utils.h b/src/3rdparty/angle/src/common/system_utils.h new file mode 100644 index 0000000000..d61faa53fd --- /dev/null +++ b/src/3rdparty/angle/src/common/system_utils.h @@ -0,0 +1,27 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// system_utils.h: declaration of OS-specific utility functions + +#ifndef COMMON_SYSTEM_UTILS_H_ +#define COMMON_SYSTEM_UTILS_H_ + +#include "common/angleutils.h" +#include "common/Optional.h" + +namespace angle +{ + +const char *GetExecutablePath(); +const char *GetExecutableDirectory(); +const char *GetSharedLibraryExtension(); +Optional GetCWD(); +bool SetCWD(const char *dirName); +bool SetEnvironmentVar(const char *variableName, const char *value); + +} // namespace angle + +#endif // COMMON_SYSTEM_UTILS_H_ diff --git a/src/3rdparty/angle/src/common/system_utils_linux.cpp b/src/3rdparty/angle/src/common/system_utils_linux.cpp new file mode 100644 index 0000000000..98ab4cce6d --- /dev/null +++ b/src/3rdparty/angle/src/common/system_utils_linux.cpp @@ -0,0 +1,89 @@ +// +// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// system_utils_linux.cpp: Implementation of OS-specific functions for Linux + +#include "system_utils.h" + +#include +#include +#include +#include + +#include + +namespace angle +{ + +namespace +{ + +std::string GetExecutablePathImpl() +{ + // We cannot use lstat to get the size of /proc/self/exe as it always returns 0 + // so we just use a big buffer and hope the path fits in it. + char path[4096]; + + ssize_t result = readlink("/proc/self/exe", path, sizeof(path) - 1); + if (result < 0 || static_cast(result) >= sizeof(path) - 1) + { + return ""; + } + + path[result] = '\0'; + return path; +} + +std::string GetExecutableDirectoryImpl() +{ + std::string executablePath = GetExecutablePath(); + size_t lastPathSepLoc = executablePath.find_last_of("/"); + return (lastPathSepLoc != std::string::npos) ? executablePath.substr(0, lastPathSepLoc) : ""; +} + +} // anonymous namespace + +const char *GetExecutablePath() +{ + // TODO(jmadill): Make global static string thread-safe. + const static std::string &exePath = GetExecutablePathImpl(); + return exePath.c_str(); +} + +const char *GetExecutableDirectory() +{ + // TODO(jmadill): Make global static string thread-safe. + const static std::string &exeDir = GetExecutableDirectoryImpl(); + return exeDir.c_str(); +} + +const char *GetSharedLibraryExtension() +{ + return "so"; +} + +Optional GetCWD() +{ + std::array pathBuf; + char *result = getcwd(pathBuf.data(), pathBuf.size()); + if (result == nullptr) + { + return Optional::Invalid(); + } + return std::string(pathBuf.data()); +} + +bool SetCWD(const char *dirName) +{ + return (chdir(dirName) == 0); +} + +bool SetEnvironmentVar(const char *variableName, const char *value) +{ + return (setenv(variableName, value, 1) == 0); +} + +} // namespace angle diff --git a/src/3rdparty/angle/src/common/system_utils_mac.cpp b/src/3rdparty/angle/src/common/system_utils_mac.cpp new file mode 100644 index 0000000000..03b9185ab1 --- /dev/null +++ b/src/3rdparty/angle/src/common/system_utils_mac.cpp @@ -0,0 +1,94 @@ +// +// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// system_utils_osx.cpp: Implementation of OS-specific functions for OSX + +#include "system_utils.h" + +#include + +#include +#include +#include + +#include + +namespace angle +{ + +namespace +{ + +std::string GetExecutablePathImpl() +{ + std::string result; + + uint32_t size = 0; + _NSGetExecutablePath(nullptr, &size); + + std::vector buffer; + buffer.resize(size + 1); + + _NSGetExecutablePath(buffer.data(), &size); + buffer[size] = '\0'; + + if (!strrchr(buffer.data(), '/')) + { + return ""; + } + return buffer.data(); +} + +std::string GetExecutableDirectoryImpl() +{ + std::string executablePath = GetExecutablePath(); + size_t lastPathSepLoc = executablePath.find_last_of("/"); + return (lastPathSepLoc != std::string::npos) ? executablePath.substr(0, lastPathSepLoc) : ""; +} + +} // anonymous namespace + +const char *GetExecutablePath() +{ + // TODO(jmadill): Make global static string thread-safe. + const static std::string &exePath = GetExecutablePathImpl(); + return exePath.c_str(); +} + +const char *GetExecutableDirectory() +{ + // TODO(jmadill): Make global static string thread-safe. + const static std::string &exeDir = GetExecutableDirectoryImpl(); + return exeDir.c_str(); +} + +const char *GetSharedLibraryExtension() +{ + return "dylib"; +} + +Optional GetCWD() +{ + std::array pathBuf; + char *result = getcwd(pathBuf.data(), pathBuf.size()); + if (result == nullptr) + { + return Optional::Invalid(); + } + return std::string(pathBuf.data()); +} + +bool SetCWD(const char *dirName) +{ + return (chdir(dirName) == 0); +} + +bool SetEnvironmentVar(const char *variableName, const char *value) +{ + return (setenv(variableName, value, 1) == 0); +} + +} // namespace angle diff --git a/src/3rdparty/angle/src/common/system_utils_win.cpp b/src/3rdparty/angle/src/common/system_utils_win.cpp new file mode 100644 index 0000000000..6bb2bfbd3f --- /dev/null +++ b/src/3rdparty/angle/src/common/system_utils_win.cpp @@ -0,0 +1,79 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// system_utils_win.cpp: Implementation of OS-specific functions for Windows + +#include "system_utils.h" + +#include +#include +#include +#include + +namespace angle +{ + +namespace +{ + +std::string GetExecutablePathImpl() +{ + std::array executableFileBuf; + DWORD executablePathLen = GetModuleFileNameA(nullptr, executableFileBuf.data(), + static_cast(executableFileBuf.size())); + return (executablePathLen > 0 ? std::string(executableFileBuf.data()) : ""); +} + +std::string GetExecutableDirectoryImpl() +{ + std::string executablePath = GetExecutablePath(); + size_t lastPathSepLoc = executablePath.find_last_of("\\/"); + return (lastPathSepLoc != std::string::npos) ? executablePath.substr(0, lastPathSepLoc) : ""; +} + +} // anonymous namespace + +const char *GetExecutablePath() +{ + // TODO(jmadill): Make global static string thread-safe. + const static std::string &exePath = GetExecutablePathImpl(); + return exePath.c_str(); +} + +const char *GetExecutableDirectory() +{ + // TODO(jmadill): Make global static string thread-safe. + const static std::string &exeDir = GetExecutableDirectoryImpl(); + return exeDir.c_str(); +} + +const char *GetSharedLibraryExtension() +{ + return "dll"; +} + +Optional GetCWD() +{ + std::array pathBuf; + DWORD result = GetCurrentDirectoryA(static_cast(pathBuf.size()), pathBuf.data()); + if (result == 0) + { + return Optional::Invalid(); + } + return std::string(pathBuf.data()); +} + +bool SetCWD(const char *dirName) +{ + return (SetCurrentDirectoryA(dirName) == TRUE); +} + +bool SetEnvironmentVar(const char *variableName, const char *value) +{ + return (SetEnvironmentVariableA(variableName, value) == TRUE); +} + +} // namespace angle diff --git a/src/3rdparty/angle/src/common/third_party/base/README.angle b/src/3rdparty/angle/src/common/third_party/base/README.angle new file mode 100644 index 0000000000..ca0943bc99 --- /dev/null +++ b/src/3rdparty/angle/src/common/third_party/base/README.angle @@ -0,0 +1,27 @@ +Name: Chromium base:: helper Classes +Short Name: base::numerics, base::MRUCachem, base::SHA1 +Version: +URL: https://chromium.googlesource.com/chromium/src/base/+/master +SOURCE CODE: Copy the Chromium folder manually into this folder and run git cl format. +Date: 24/05/2017 +Revision: 28b5bbb227d331c01e6ff9b2f8729732135aadc7 (Chromium) +Security Critical: no +License: Chromium +License File: LICENSE in Chromium/src + +Description: +base::numerics is a library for doing some simple safe math and conversions. +base::MRUCache is a few collections of most-recently-used caching structures. +base::SHA1 is a secure hashing algorithm. + +To update the checkout, simply overwrite the folder with Chromium's latest, apply +the appropriate namespace, and make sure the paths are correct (anglebase/ instead of +base/), and update the header guards and macros. + +Modifications: + +- the file scope is now anglebase/ from base/ to prevent include conflicts. +- anglebase/logging.h defines (D)CHECK to be ASSERT to be compatible with ANGLE. +- the headers use namespace angle::base instead of base:: to avoid ODR + violations when ANGLE code is mixed with Chromium code. +- header guards and macros are changed from BASE to ANGLEBASE to prevent conflicts. diff --git a/src/3rdparty/angle/src/common/third_party/base/anglebase/base_export.h b/src/3rdparty/angle/src/common/third_party/base/anglebase/base_export.h new file mode 100644 index 0000000000..1af5485336 --- /dev/null +++ b/src/3rdparty/angle/src/common/third_party/base/anglebase/base_export.h @@ -0,0 +1,13 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// base_export.h: Compatiblity hacks for importing Chromium's base/SHA1. + +#ifndef ANGLEBASE_BASE_EXPORT_H_ +#define ANGLEBASE_BASE_EXPORT_H_ + +#define ANGLEBASE_EXPORT + +#endif // ANGLEBASE_BASE_EXPORT_H_ \ No newline at end of file diff --git a/src/3rdparty/angle/src/common/third_party/base/anglebase/containers/mru_cache.h b/src/3rdparty/angle/src/common/third_party/base/anglebase/containers/mru_cache.h new file mode 100644 index 0000000000..fe4fec5768 --- /dev/null +++ b/src/3rdparty/angle/src/common/third_party/base/anglebase/containers/mru_cache.h @@ -0,0 +1,275 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file contains a template for a Most Recently Used cache that allows +// constant-time access to items using a key, but easy identification of the +// least-recently-used items for removal. Each key can only be associated with +// one payload item at a time. +// +// The key object will be stored twice, so it should support efficient copying. +// +// NOTE: While all operations are O(1), this code is written for +// legibility rather than optimality. If future profiling identifies this as +// a bottleneck, there is room for smaller values of 1 in the O(1). :] + +#ifndef ANGLEBASE_CONTAINERS_MRU_CACHE_H_ +#define ANGLEBASE_CONTAINERS_MRU_CACHE_H_ + +#include + +#include +#include +#include +#include +#include +#include + +#include "anglebase/logging.h" +#include "anglebase/macros.h" + +namespace angle +{ + +namespace base +{ + +// MRUCacheBase ---------------------------------------------------------------- + +// This template is used to standardize map type containers that can be used +// by MRUCacheBase. This level of indirection is necessary because of the way +// that template template params and default template params interact. +template +struct MRUCacheStandardMap +{ + typedef std::map Type; +}; + +// Base class for the MRU cache specializations defined below. +template class MapType = MRUCacheStandardMap> +class MRUCacheBase +{ + public: + // The payload of the list. This maintains a copy of the key so we can + // efficiently delete things given an element of the list. + typedef std::pair value_type; + + private: + typedef std::list PayloadList; + typedef + typename MapType::Type KeyIndex; + + public: + typedef typename PayloadList::size_type size_type; + + typedef typename PayloadList::iterator iterator; + typedef typename PayloadList::const_iterator const_iterator; + typedef typename PayloadList::reverse_iterator reverse_iterator; + typedef typename PayloadList::const_reverse_iterator const_reverse_iterator; + + enum + { + NO_AUTO_EVICT = 0 + }; + + // The max_size is the size at which the cache will prune its members to when + // a new item is inserted. If the caller wants to manager this itself (for + // example, maybe it has special work to do when something is evicted), it + // can pass NO_AUTO_EVICT to not restrict the cache size. + explicit MRUCacheBase(size_type max_size) : max_size_(max_size) {} + + virtual ~MRUCacheBase() {} + + size_type max_size() const { return max_size_; } + + // Inserts a payload item with the given key. If an existing item has + // the same key, it is removed prior to insertion. An iterator indicating the + // inserted item will be returned (this will always be the front of the list). + // + // The payload will be forwarded. + template + iterator Put(const KeyType &key, Payload &&payload) + { + // Remove any existing payload with that key. + typename KeyIndex::iterator index_iter = index_.find(key); + if (index_iter != index_.end()) + { + // Erase the reference to it. The index reference will be replaced in the + // code below. + Erase(index_iter->second); + } + else if (max_size_ != NO_AUTO_EVICT) + { + // New item is being inserted which might make it larger than the maximum + // size: kick the oldest thing out if necessary. + ShrinkToSize(max_size_ - 1); + } + + ordering_.emplace_front(key, std::forward(payload)); + index_.emplace(key, ordering_.begin()); + return ordering_.begin(); + } + + // Retrieves the contents of the given key, or end() if not found. This method + // has the side effect of moving the requested item to the front of the + // recency list. + iterator Get(const KeyType &key) + { + typename KeyIndex::iterator index_iter = index_.find(key); + if (index_iter == index_.end()) + return end(); + typename PayloadList::iterator iter = index_iter->second; + + // Move the touched item to the front of the recency ordering. + ordering_.splice(ordering_.begin(), ordering_, iter); + return ordering_.begin(); + } + + // Retrieves the payload associated with a given key and returns it via + // result without affecting the ordering (unlike Get). + iterator Peek(const KeyType &key) + { + typename KeyIndex::const_iterator index_iter = index_.find(key); + if (index_iter == index_.end()) + return end(); + return index_iter->second; + } + + const_iterator Peek(const KeyType &key) const + { + typename KeyIndex::const_iterator index_iter = index_.find(key); + if (index_iter == index_.end()) + return end(); + return index_iter->second; + } + + // Exchanges the contents of |this| by the contents of the |other|. + void Swap(MRUCacheBase &other) + { + ordering_.swap(other.ordering_); + index_.swap(other.index_); + std::swap(max_size_, other.max_size_); + } + + // Erases the item referenced by the given iterator. An iterator to the item + // following it will be returned. The iterator must be valid. + iterator Erase(iterator pos) + { + index_.erase(pos->first); + return ordering_.erase(pos); + } + + // MRUCache entries are often processed in reverse order, so we add this + // convenience function (not typically defined by STL containers). + reverse_iterator Erase(reverse_iterator pos) + { + // We have to actually give it the incremented iterator to delete, since + // the forward iterator that base() returns is actually one past the item + // being iterated over. + return reverse_iterator(Erase((++pos).base())); + } + + // Shrinks the cache so it only holds |new_size| items. If |new_size| is + // bigger or equal to the current number of items, this will do nothing. + void ShrinkToSize(size_type new_size) + { + for (size_type i = size(); i > new_size; i--) + Erase(rbegin()); + } + + // Deletes everything from the cache. + void Clear() + { + index_.clear(); + ordering_.clear(); + } + + // Returns the number of elements in the cache. + size_type size() const + { + // We don't use ordering_.size() for the return value because + // (as a linked list) it can be O(n). + DCHECK(index_.size() == ordering_.size()); + return index_.size(); + } + + // Allows iteration over the list. Forward iteration starts with the most + // recent item and works backwards. + // + // Note that since these iterators are actually iterators over a list, you + // can keep them as you insert or delete things (as long as you don't delete + // the one you are pointing to) and they will still be valid. + iterator begin() { return ordering_.begin(); } + const_iterator begin() const { return ordering_.begin(); } + iterator end() { return ordering_.end(); } + const_iterator end() const { return ordering_.end(); } + + reverse_iterator rbegin() { return ordering_.rbegin(); } + const_reverse_iterator rbegin() const { return ordering_.rbegin(); } + reverse_iterator rend() { return ordering_.rend(); } + const_reverse_iterator rend() const { return ordering_.rend(); } + + bool empty() const { return ordering_.empty(); } + + private: + PayloadList ordering_; + KeyIndex index_; + + size_type max_size_; + + DISALLOW_COPY_AND_ASSIGN(MRUCacheBase); +}; + +// MRUCache -------------------------------------------------------------------- + +// A container that does not do anything to free its data. Use this when storing +// value types (as opposed to pointers) in the list. +template > +class MRUCache : public MRUCacheBase +{ + private: + using ParentType = MRUCacheBase; + + public: + // See MRUCacheBase, noting the possibility of using NO_AUTO_EVICT. + explicit MRUCache(typename ParentType::size_type max_size) : ParentType(max_size) {} + virtual ~MRUCache() {} + + private: + DISALLOW_COPY_AND_ASSIGN(MRUCache); +}; + +// HashingMRUCache ------------------------------------------------------------ + +template +struct MRUCacheHashMap +{ + typedef std::unordered_map Type; +}; + +// This class is similar to MRUCache, except that it uses std::unordered_map as +// the map type instead of std::map. Note that your KeyType must be hashable to +// use this cache or you need to provide a hashing class. +template > +class HashingMRUCache : public MRUCacheBase +{ + private: + using ParentType = MRUCacheBase; + + public: + // See MRUCacheBase, noting the possibility of using NO_AUTO_EVICT. + explicit HashingMRUCache(typename ParentType::size_type max_size) : ParentType(max_size) {} + virtual ~HashingMRUCache() {} + + private: + DISALLOW_COPY_AND_ASSIGN(HashingMRUCache); +}; + +} // namespace base + +} // namespace angle + +#endif // ANGLEBASE_CONTAINERS_MRU_CACHE_H_ diff --git a/src/3rdparty/angle/src/common/third_party/base/anglebase/logging.h b/src/3rdparty/angle/src/common/third_party/base/anglebase/logging.h new file mode 100644 index 0000000000..85ad82b47d --- /dev/null +++ b/src/3rdparty/angle/src/common/third_party/base/anglebase/logging.h @@ -0,0 +1,26 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// logging.h: Compatiblity hacks for importing Chromium's base/numerics. + +#ifndef ANGLEBASE_LOGGING_H_ +#define ANGLEBASE_LOGGING_H_ + +#include "common/debug.h" + +#ifndef DCHECK +#define DCHECK(X) ASSERT(X) +#endif + +#ifndef CHECK +#define CHECK(X) ASSERT(X) +#endif + +// Unfortunately ANGLE relies on ASSERT being an empty statement, which these libs don't respect. +#ifndef NOTREACHED +#define NOTREACHED() UNREACHABLE() +#endif + +#endif // ANGLEBASE_LOGGING_H_ diff --git a/src/3rdparty/angle/src/common/third_party/base/anglebase/macros.h b/src/3rdparty/angle/src/common/third_party/base/anglebase/macros.h new file mode 100644 index 0000000000..06391784e4 --- /dev/null +++ b/src/3rdparty/angle/src/common/third_party/base/anglebase/macros.h @@ -0,0 +1,17 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// macros.h: Compatiblity hacks for importing Chromium's MRUCache. + +#ifndef ANGLEBASE_MACROS_H_ +#define ANGLEBASE_MACROS_H_ + +// A macro to disallow the copy constructor and operator= functions. +// This should be used in the private: declarations for a class. +#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName &) = delete; \ + void operator=(const TypeName &) = delete + +#endif // ANGLEBASE_MACROS_H_ diff --git a/src/3rdparty/angle/src/common/third_party/base/anglebase/numerics/OWNERS b/src/3rdparty/angle/src/common/third_party/base/anglebase/numerics/OWNERS new file mode 100644 index 0000000000..41f35fc79b --- /dev/null +++ b/src/3rdparty/angle/src/common/third_party/base/anglebase/numerics/OWNERS @@ -0,0 +1,3 @@ +jschuh@chromium.org +tsepez@chromium.org + diff --git a/src/3rdparty/angle/src/common/third_party/base/anglebase/numerics/safe_conversions.h b/src/3rdparty/angle/src/common/third_party/base/anglebase/numerics/safe_conversions.h new file mode 100644 index 0000000000..43babc31a8 --- /dev/null +++ b/src/3rdparty/angle/src/common/third_party/base/anglebase/numerics/safe_conversions.h @@ -0,0 +1,179 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ANGLEBASE_NUMERICS_SAFE_CONVERSIONS_H_ +#define ANGLEBASE_NUMERICS_SAFE_CONVERSIONS_H_ + +#include + +#include +#include + +#include "anglebase/logging.h" +#include "anglebase/numerics/safe_conversions_impl.h" + +namespace angle +{ + +namespace base +{ + +// Convenience function that returns true if the supplied value is in range +// for the destination type. +template +constexpr bool IsValueInRangeForNumericType(Src value) +{ + return internal::DstRangeRelationToSrcRange(value) == internal::RANGE_VALID; +} + +// Convenience function for determining if a numeric value is negative without +// throwing compiler warnings on: unsigned(value) < 0. +template +constexpr typename std::enable_if::is_signed, bool>::type IsValueNegative( + T value) +{ + static_assert(std::numeric_limits::is_specialized, "Argument must be numeric."); + return value < 0; +} + +template +constexpr typename std::enable_if::is_signed, bool>::type IsValueNegative(T) +{ + static_assert(std::numeric_limits::is_specialized, "Argument must be numeric."); + return false; +} + +// checked_cast<> is analogous to static_cast<> for numeric types, +// except that it CHECKs that the specified numeric conversion will not +// overflow or underflow. NaN source will always trigger a CHECK. +template +inline Dst checked_cast(Src value) +{ + CHECK(IsValueInRangeForNumericType(value)); + return static_cast(value); +} + +// HandleNaN will cause this class to CHECK(false). +struct SaturatedCastNaNBehaviorCheck +{ + template + static T HandleNaN() + { + CHECK(false); + return T(); + } +}; + +// HandleNaN will return 0 in this case. +struct SaturatedCastNaNBehaviorReturnZero +{ + template + static constexpr T HandleNaN() + { + return T(); + } +}; + +namespace internal +{ +// This wrapper is used for C++11 constexpr support by avoiding the declaration +// of local variables in the saturated_cast template function. +template +constexpr Dst saturated_cast_impl(const Src value, const RangeConstraint constraint) +{ + return constraint == RANGE_VALID + ? static_cast(value) + : (constraint == RANGE_UNDERFLOW + ? std::numeric_limits::min() + : (constraint == RANGE_OVERFLOW + ? std::numeric_limits::max() + : (constraint == RANGE_INVALID + ? NaNHandler::template HandleNaN() + : (NOTREACHED(), static_cast(value))))); +} +} // namespace internal + +// saturated_cast<> is analogous to static_cast<> for numeric types, except +// that the specified numeric conversion will saturate rather than overflow or +// underflow. NaN assignment to an integral will defer the behavior to a +// specified class. By default, it will return 0. +template +constexpr Dst saturated_cast(Src value) +{ + return std::numeric_limits::is_iec559 + ? static_cast(value) // Floating point optimization. + : internal::saturated_cast_impl( + value, internal::DstRangeRelationToSrcRange(value)); +} + +// strict_cast<> is analogous to static_cast<> for numeric types, except that +// it will cause a compile failure if the destination type is not large enough +// to contain any value in the source type. It performs no runtime checking. +template +constexpr Dst strict_cast(Src value) +{ + static_assert(std::numeric_limits::is_specialized, "Argument must be numeric."); + static_assert(std::numeric_limits::is_specialized, "Result must be numeric."); + static_assert((internal::StaticDstRangeRelationToSrcRange::value == + internal::NUMERIC_RANGE_CONTAINED), + "The numeric conversion is out of range for this type. You " + "should probably use one of the following conversion " + "mechanisms on the value you want to pass:\n" + "- base::checked_cast\n" + "- base::saturated_cast\n" + "- base::CheckedNumeric"); + + return static_cast(value); +} + +// StrictNumeric implements compile time range checking between numeric types by +// wrapping assignment operations in a strict_cast. This class is intended to be +// used for function arguments and return types, to ensure the destination type +// can always contain the source type. This is essentially the same as enforcing +// -Wconversion in gcc and C4302 warnings on MSVC, but it can be applied +// incrementally at API boundaries, making it easier to convert code so that it +// compiles cleanly with truncation warnings enabled. +// This template should introduce no runtime overhead, but it also provides no +// runtime checking of any of the associated mathematical operations. Use +// CheckedNumeric for runtime range checks of the actual value being assigned. +template +class StrictNumeric +{ + public: + typedef T type; + + constexpr StrictNumeric() : value_(0) {} + + // Copy constructor. + template + constexpr StrictNumeric(const StrictNumeric &rhs) : value_(strict_cast(rhs.value_)) + { + } + + // This is not an explicit constructor because we implicitly upgrade regular + // numerics to StrictNumerics to make them easier to use. + template + constexpr StrictNumeric(Src value) : value_(strict_cast(value)) + { + } + + // The numeric cast operator basically handles all the magic. + template + constexpr operator Dst() const + { + return strict_cast(value_); + } + + private: + const T value_; +}; + +// Explicitly make a shorter size_t typedef for convenience. +typedef StrictNumeric SizeT; + +} // namespace base + +} // namespace angle + +#endif // ANGLEBASE_NUMERICS_SAFE_CONVERSIONS_H_ diff --git a/src/3rdparty/angle/src/common/third_party/base/anglebase/numerics/safe_conversions_impl.h b/src/3rdparty/angle/src/common/third_party/base/anglebase/numerics/safe_conversions_impl.h new file mode 100644 index 0000000000..10ed6c7a7f --- /dev/null +++ b/src/3rdparty/angle/src/common/third_party/base/anglebase/numerics/safe_conversions_impl.h @@ -0,0 +1,274 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ANGLEBASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ +#define ANGLEBASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ + +#include +#include + +#include +#include + +namespace angle +{ + +namespace base +{ +namespace internal +{ + +// The std library doesn't provide a binary max_exponent for integers, however +// we can compute one by adding one to the number of non-sign bits. This allows +// for accurate range comparisons between floating point and integer types. +template +struct MaxExponent +{ + static_assert(std::is_arithmetic::value, "Argument must be numeric."); + static const int value = + std::numeric_limits::is_iec559 + ? std::numeric_limits::max_exponent + : (sizeof(NumericType) * CHAR_BIT + 1 - std::numeric_limits::is_signed); +}; + +enum IntegerRepresentation +{ + INTEGER_REPRESENTATION_UNSIGNED, + INTEGER_REPRESENTATION_SIGNED +}; + +// A range for a given nunmeric Src type is contained for a given numeric Dst +// type if both numeric_limits::max() <= numeric_limits::max() and +// numeric_limits::min() >= numeric_limits::min() are true. +// We implement this as template specializations rather than simple static +// comparisons to ensure type correctness in our comparisons. +enum NumericRangeRepresentation +{ + NUMERIC_RANGE_NOT_CONTAINED, + NUMERIC_RANGE_CONTAINED +}; + +// Helper templates to statically determine if our destination type can contain +// maximum and minimum values represented by the source type. + +template ::is_signed + ? INTEGER_REPRESENTATION_SIGNED + : INTEGER_REPRESENTATION_UNSIGNED, + IntegerRepresentation SrcSign = std::numeric_limits::is_signed + ? INTEGER_REPRESENTATION_SIGNED + : INTEGER_REPRESENTATION_UNSIGNED> +struct StaticDstRangeRelationToSrcRange; + +// Same sign: Dst is guaranteed to contain Src only if its range is equal or +// larger. +template +struct StaticDstRangeRelationToSrcRange +{ + static const NumericRangeRepresentation value = + MaxExponent::value >= MaxExponent::value ? NUMERIC_RANGE_CONTAINED + : NUMERIC_RANGE_NOT_CONTAINED; +}; + +// Unsigned to signed: Dst is guaranteed to contain source only if its range is +// larger. +template +struct StaticDstRangeRelationToSrcRange +{ + static const NumericRangeRepresentation value = + MaxExponent::value > MaxExponent::value ? NUMERIC_RANGE_CONTAINED + : NUMERIC_RANGE_NOT_CONTAINED; +}; + +// Signed to unsigned: Dst cannot be statically determined to contain Src. +template +struct StaticDstRangeRelationToSrcRange +{ + static const NumericRangeRepresentation value = NUMERIC_RANGE_NOT_CONTAINED; +}; + +enum RangeConstraint : unsigned char +{ + RANGE_VALID = 0x0, // Value can be represented by the destination type. + RANGE_UNDERFLOW = 0x1, // Value would overflow. + RANGE_OVERFLOW = 0x2, // Value would underflow. + RANGE_INVALID = RANGE_UNDERFLOW | RANGE_OVERFLOW // Invalid (i.e. NaN). +}; + +// Helper function for coercing an int back to a RangeContraint. +constexpr RangeConstraint GetRangeConstraint(int integer_range_constraint) +{ + // TODO(jschuh): Once we get full C++14 support we want this + // assert(integer_range_constraint >= RANGE_VALID && + // integer_range_constraint <= RANGE_INVALID) + return static_cast(integer_range_constraint); +} + +// This function creates a RangeConstraint from an upper and lower bound +// check by taking advantage of the fact that only NaN can be out of range in +// both directions at once. +constexpr inline RangeConstraint GetRangeConstraint(bool is_in_upper_bound, bool is_in_lower_bound) +{ + return GetRangeConstraint((is_in_upper_bound ? 0 : RANGE_OVERFLOW) | + (is_in_lower_bound ? 0 : RANGE_UNDERFLOW)); +} + +// The following helper template addresses a corner case in range checks for +// conversion from a floating-point type to an integral type of smaller range +// but larger precision (e.g. float -> unsigned). The problem is as follows: +// 1. Integral maximum is always one less than a power of two, so it must be +// truncated to fit the mantissa of the floating point. The direction of +// rounding is implementation defined, but by default it's always IEEE +// floats, which round to nearest and thus result in a value of larger +// magnitude than the integral value. +// Example: float f = UINT_MAX; // f is 4294967296f but UINT_MAX +// // is 4294967295u. +// 2. If the floating point value is equal to the promoted integral maximum +// value, a range check will erroneously pass. +// Example: (4294967296f <= 4294967295u) // This is true due to a precision +// // loss in rounding up to float. +// 3. When the floating point value is then converted to an integral, the +// resulting value is out of range for the target integral type and +// thus is implementation defined. +// Example: unsigned u = (float)INT_MAX; // u will typically overflow to 0. +// To fix this bug we manually truncate the maximum value when the destination +// type is an integral of larger precision than the source floating-point type, +// such that the resulting maximum is represented exactly as a floating point. +template +struct NarrowingRange +{ + typedef typename std::numeric_limits SrcLimits; + typedef typename std::numeric_limits DstLimits; + // The following logic avoids warnings where the max function is + // instantiated with invalid values for a bit shift (even though + // such a function can never be called). + static const int shift = (MaxExponent::value > MaxExponent::value && + SrcLimits::digits < DstLimits::digits && + SrcLimits::is_iec559 && + DstLimits::is_integer) + ? (DstLimits::digits - SrcLimits::digits) + : 0; + + static constexpr Dst max() + { + // We use UINTMAX_C below to avoid compiler warnings about shifting floating + // points. Since it's a compile time calculation, it shouldn't have any + // performance impact. + return DstLimits::max() - static_cast((UINTMAX_C(1) << shift) - 1); + } + + static constexpr Dst min() + { + return std::numeric_limits::is_iec559 ? -DstLimits::max() : DstLimits::min(); + } +}; + +template ::is_signed + ? INTEGER_REPRESENTATION_SIGNED + : INTEGER_REPRESENTATION_UNSIGNED, + IntegerRepresentation SrcSign = std::numeric_limits::is_signed + ? INTEGER_REPRESENTATION_SIGNED + : INTEGER_REPRESENTATION_UNSIGNED, + NumericRangeRepresentation DstRange = StaticDstRangeRelationToSrcRange::value> +struct DstRangeRelationToSrcRangeImpl; + +// The following templates are for ranges that must be verified at runtime. We +// split it into checks based on signedness to avoid confusing casts and +// compiler warnings on signed an unsigned comparisons. + +// Dst range is statically determined to contain Src: Nothing to check. +template +struct DstRangeRelationToSrcRangeImpl +{ + static constexpr RangeConstraint Check(Src value) { return RANGE_VALID; } +}; + +// Signed to signed narrowing: Both the upper and lower boundaries may be +// exceeded. +template +struct DstRangeRelationToSrcRangeImpl +{ + static constexpr RangeConstraint Check(Src value) + { + return GetRangeConstraint((value <= NarrowingRange::max()), + (value >= NarrowingRange::min())); + } +}; + +// Unsigned to unsigned narrowing: Only the upper boundary can be exceeded. +template +struct DstRangeRelationToSrcRangeImpl +{ + static constexpr RangeConstraint Check(Src value) + { + return GetRangeConstraint(value <= NarrowingRange::max(), true); + } +}; + +// Unsigned to signed: The upper boundary may be exceeded. +template +struct DstRangeRelationToSrcRangeImpl +{ + static constexpr RangeConstraint Check(Src value) + { + return sizeof(Dst) > sizeof(Src) + ? RANGE_VALID + : GetRangeConstraint(value <= static_cast(NarrowingRange::max()), + true); + } +}; + +// Signed to unsigned: The upper boundary may be exceeded for a narrower Dst, +// and any negative value exceeds the lower boundary. +template +struct DstRangeRelationToSrcRangeImpl +{ + static constexpr RangeConstraint Check(Src value) + { + return (MaxExponent::value >= MaxExponent::value) + ? GetRangeConstraint(true, value >= static_cast(0)) + : GetRangeConstraint(value <= static_cast(NarrowingRange::max()), + value >= static_cast(0)); + } +}; + +template +constexpr RangeConstraint DstRangeRelationToSrcRange(Src value) +{ + static_assert(std::numeric_limits::is_specialized, "Argument must be numeric."); + static_assert(std::numeric_limits::is_specialized, "Result must be numeric."); + return DstRangeRelationToSrcRangeImpl::Check(value); +} + +} // namespace internal +} // namespace base + +} // namespace angle + +#endif // ANGLEBASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ diff --git a/src/3rdparty/angle/src/common/third_party/base/anglebase/numerics/safe_math.h b/src/3rdparty/angle/src/common/third_party/base/anglebase/numerics/safe_math.h new file mode 100644 index 0000000000..3af4db63f7 --- /dev/null +++ b/src/3rdparty/angle/src/common/third_party/base/anglebase/numerics/safe_math.h @@ -0,0 +1,329 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ANGLEBASE_NUMERICS_SAFE_MATH_H_ +#define ANGLEBASE_NUMERICS_SAFE_MATH_H_ + +#include + +#include +#include + +#include "anglebase/logging.h" +#include "anglebase/numerics/safe_math_impl.h" + +namespace angle +{ + +namespace base +{ + +namespace internal +{ + +// CheckedNumeric implements all the logic and operators for detecting integer +// boundary conditions such as overflow, underflow, and invalid conversions. +// The CheckedNumeric type implicitly converts from floating point and integer +// data types, and contains overloads for basic arithmetic operations (i.e.: +, +// -, *, /, %). +// +// The following methods convert from CheckedNumeric to standard numeric values: +// IsValid() - Returns true if the underlying numeric value is valid (i.e. has +// has not wrapped and is not the result of an invalid conversion). +// ValueOrDie() - Returns the underlying value. If the state is not valid this +// call will crash on a CHECK. +// ValueOrDefault() - Returns the current value, or the supplied default if the +// state is not valid. +// ValueFloating() - Returns the underlying floating point value (valid only +// only for floating point CheckedNumeric types). +// +// Bitwise operations are explicitly not supported, because correct +// handling of some cases (e.g. sign manipulation) is ambiguous. Comparison +// operations are explicitly not supported because they could result in a crash +// on a CHECK condition. You should use patterns like the following for these +// operations: +// Bitwise operation: +// CheckedNumeric checked_int = untrusted_input_value; +// int x = checked_int.ValueOrDefault(0) | kFlagValues; +// Comparison: +// CheckedNumeric checked_size = untrusted_input_value; +// checked_size += HEADER LENGTH; +// if (checked_size.IsValid() && checked_size.ValueOrDie() < buffer_size) +// Do stuff... +template +class CheckedNumeric +{ + static_assert(std::is_arithmetic::value, "CheckedNumeric: T must be a numeric type."); + + public: + typedef T type; + + CheckedNumeric() {} + + // Copy constructor. + template + CheckedNumeric(const CheckedNumeric &rhs) : state_(rhs.ValueUnsafe(), rhs.validity()) + { + } + + template + CheckedNumeric(Src value, RangeConstraint validity) : state_(value, validity) + { + } + + // This is not an explicit constructor because we implicitly upgrade regular + // numerics to CheckedNumerics to make them easier to use. + template + CheckedNumeric(Src value) // NOLINT(runtime/explicit) + : state_(value) + { + static_assert(std::numeric_limits::is_specialized, "Argument must be numeric."); + } + + // This is not an explicit constructor because we want a seamless conversion + // from StrictNumeric types. + template + CheckedNumeric(StrictNumeric value) // NOLINT(runtime/explicit) + : state_(static_cast(value)) + { + } + + // IsValid() is the public API to test if a CheckedNumeric is currently valid. + bool IsValid() const { return validity() == RANGE_VALID; } + + // ValueOrDie() The primary accessor for the underlying value. If the current + // state is not valid it will CHECK and crash. + T ValueOrDie() const + { + CHECK(IsValid()); + return state_.value(); + } + + // ValueOrDefault(T default_value) A convenience method that returns the + // current value if the state is valid, and the supplied default_value for + // any other state. + T ValueOrDefault(T default_value) const { return IsValid() ? state_.value() : default_value; } + + // ValueFloating() - Since floating point values include their validity state, + // we provide an easy method for extracting them directly, without a risk of + // crashing on a CHECK. + T ValueFloating() const + { + static_assert(std::numeric_limits::is_iec559, "Argument must be float."); + return CheckedNumeric::cast(*this).ValueUnsafe(); + } + + // validity() - DO NOT USE THIS IN EXTERNAL CODE - It is public right now for + // tests and to avoid a big matrix of friend operator overloads. But the + // values it returns are likely to change in the future. + // Returns: current validity state (i.e. valid, overflow, underflow, nan). + // TODO(jschuh): crbug.com/332611 Figure out and implement semantics for + // saturation/wrapping so we can expose this state consistently and implement + // saturated arithmetic. + RangeConstraint validity() const { return state_.validity(); } + + // ValueUnsafe() - DO NOT USE THIS IN EXTERNAL CODE - It is public right now + // for tests and to avoid a big matrix of friend operator overloads. But the + // values it returns are likely to change in the future. + // Returns: the raw numeric value, regardless of the current state. + // TODO(jschuh): crbug.com/332611 Figure out and implement semantics for + // saturation/wrapping so we can expose this state consistently and implement + // saturated arithmetic. + T ValueUnsafe() const { return state_.value(); } + + // Prototypes for the supported arithmetic operator overloads. + template + CheckedNumeric &operator+=(Src rhs); + template + CheckedNumeric &operator-=(Src rhs); + template + CheckedNumeric &operator*=(Src rhs); + template + CheckedNumeric &operator/=(Src rhs); + template + CheckedNumeric &operator%=(Src rhs); + + CheckedNumeric operator-() const + { + RangeConstraint validity; + T value = CheckedNeg(state_.value(), &validity); + // Negation is always valid for floating point. + if (std::numeric_limits::is_iec559) + return CheckedNumeric(value); + + validity = GetRangeConstraint(state_.validity() | validity); + return CheckedNumeric(value, validity); + } + + CheckedNumeric Abs() const + { + RangeConstraint validity; + T value = CheckedAbs(state_.value(), &validity); + // Absolute value is always valid for floating point. + if (std::numeric_limits::is_iec559) + return CheckedNumeric(value); + + validity = GetRangeConstraint(state_.validity() | validity); + return CheckedNumeric(value, validity); + } + + // This function is available only for integral types. It returns an unsigned + // integer of the same width as the source type, containing the absolute value + // of the source, and properly handling signed min. + CheckedNumeric::type> UnsignedAbs() const + { + return CheckedNumeric::type>( + CheckedUnsignedAbs(state_.value()), state_.validity()); + } + + CheckedNumeric &operator++() + { + *this += 1; + return *this; + } + + CheckedNumeric operator++(int) + { + CheckedNumeric value = *this; + *this += 1; + return value; + } + + CheckedNumeric &operator--() + { + *this -= 1; + return *this; + } + + CheckedNumeric operator--(int) + { + CheckedNumeric value = *this; + *this -= 1; + return value; + } + + // These static methods behave like a convenience cast operator targeting + // the desired CheckedNumeric type. As an optimization, a reference is + // returned when Src is the same type as T. + template + static CheckedNumeric cast( + Src u, + typename std::enable_if::is_specialized, int>::type = 0) + { + return u; + } + + template + static CheckedNumeric cast( + const CheckedNumeric &u, + typename std::enable_if::value, int>::type = 0) + { + return u; + } + + static const CheckedNumeric &cast(const CheckedNumeric &u) { return u; } + + private: + template + struct UnderlyingType + { + using type = NumericType; + }; + + template + struct UnderlyingType> + { + using type = NumericType; + }; + + CheckedNumericState state_; +}; + +// This is the boilerplate for the standard arithmetic operator overloads. A +// macro isn't the prettiest solution, but it beats rewriting these five times. +// Some details worth noting are: +// * We apply the standard arithmetic promotions. +// * We skip range checks for floating points. +// * We skip range checks for destination integers with sufficient range. +// TODO(jschuh): extract these out into templates. +#define ANGLEBASE_NUMERIC_ARITHMETIC_OPERATORS(NAME, OP, COMPOUND_OP) \ + /* Binary arithmetic operator for CheckedNumerics of the same type. */ \ + template \ + CheckedNumeric::type> operator OP( \ + const CheckedNumeric &lhs, const CheckedNumeric &rhs) \ + { \ + typedef typename ArithmeticPromotion::type Promotion; \ + /* Floating point always takes the fast path */ \ + if (std::numeric_limits::is_iec559) \ + return CheckedNumeric(lhs.ValueUnsafe() OP rhs.ValueUnsafe()); \ + if (IsIntegerArithmeticSafe::value) \ + return CheckedNumeric(lhs.ValueUnsafe() OP rhs.ValueUnsafe(), \ + GetRangeConstraint(rhs.validity() | lhs.validity())); \ + RangeConstraint validity = RANGE_VALID; \ + T result = \ + static_cast(Checked##NAME(static_cast(lhs.ValueUnsafe()), \ + static_cast(rhs.ValueUnsafe()), &validity)); \ + return CheckedNumeric( \ + result, GetRangeConstraint(validity | lhs.validity() | rhs.validity())); \ + } \ + /* Assignment arithmetic operator implementation from CheckedNumeric. */ \ + template \ + template \ + CheckedNumeric &CheckedNumeric::operator COMPOUND_OP(Src rhs) \ + { \ + *this = CheckedNumeric::cast(*this) \ + OP CheckedNumeric::type>::cast(rhs); \ + return *this; \ + } \ + /* Binary arithmetic operator for CheckedNumeric of different type. */ \ + template \ + CheckedNumeric::type> operator OP( \ + const CheckedNumeric &lhs, const CheckedNumeric &rhs) \ + { \ + typedef typename ArithmeticPromotion::type Promotion; \ + if (IsIntegerArithmeticSafe::value) \ + return CheckedNumeric(lhs.ValueUnsafe() OP rhs.ValueUnsafe(), \ + GetRangeConstraint(rhs.validity() | lhs.validity())); \ + return CheckedNumeric::cast(lhs) OP CheckedNumeric::cast(rhs); \ + } \ + /* Binary arithmetic operator for left CheckedNumeric and right numeric. */ \ + template ::value>::type * = nullptr> \ + CheckedNumeric::type> operator OP( \ + const CheckedNumeric &lhs, Src rhs) \ + { \ + typedef typename ArithmeticPromotion::type Promotion; \ + if (IsIntegerArithmeticSafe::value) \ + return CheckedNumeric(lhs.ValueUnsafe() OP rhs, lhs.validity()); \ + return CheckedNumeric::cast(lhs) OP CheckedNumeric::cast(rhs); \ + } \ + /* Binary arithmetic operator for left numeric and right CheckedNumeric. */ \ + template ::value>::type * = nullptr> \ + CheckedNumeric::type> operator OP( \ + Src lhs, const CheckedNumeric &rhs) \ + { \ + typedef typename ArithmeticPromotion::type Promotion; \ + if (IsIntegerArithmeticSafe::value) \ + return CheckedNumeric(lhs OP rhs.ValueUnsafe(), rhs.validity()); \ + return CheckedNumeric::cast(lhs) OP CheckedNumeric::cast(rhs); \ + } + +ANGLEBASE_NUMERIC_ARITHMETIC_OPERATORS(Add, +, +=) +ANGLEBASE_NUMERIC_ARITHMETIC_OPERATORS(Sub, -, -=) +ANGLEBASE_NUMERIC_ARITHMETIC_OPERATORS(Mul, *, *=) +ANGLEBASE_NUMERIC_ARITHMETIC_OPERATORS(Div, /, /=) +ANGLEBASE_NUMERIC_ARITHMETIC_OPERATORS(Mod, %, %=) + +#undef ANGLEBASE_NUMERIC_ARITHMETIC_OPERATORS + +} // namespace internal + +using internal::CheckedNumeric; + +} // namespace base + +} // namespace angle + +#endif // ANGLEBASE_NUMERICS_SAFE_MATH_H_ diff --git a/src/3rdparty/angle/src/common/third_party/base/anglebase/numerics/safe_math_impl.h b/src/3rdparty/angle/src/common/third_party/base/anglebase/numerics/safe_math_impl.h new file mode 100644 index 0000000000..2831cc6ceb --- /dev/null +++ b/src/3rdparty/angle/src/common/third_party/base/anglebase/numerics/safe_math_impl.h @@ -0,0 +1,575 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ANGLEBASE_NUMERICS_SAFE_MATH_IMPL_H_ +#define ANGLEBASE_NUMERICS_SAFE_MATH_IMPL_H_ + +#include +#include + +#include +#include +#include +#include +#include + +#include "anglebase/numerics/safe_conversions.h" + +namespace angle +{ + +namespace base +{ +namespace internal +{ + +// Everything from here up to the floating point operations is portable C++, +// but it may not be fast. This code could be split based on +// platform/architecture and replaced with potentially faster implementations. + +// Integer promotion templates used by the portable checked integer arithmetic. +template +struct IntegerForSizeAndSign; +template <> +struct IntegerForSizeAndSign<1, true> +{ + typedef int8_t type; +}; +template <> +struct IntegerForSizeAndSign<1, false> +{ + typedef uint8_t type; +}; +template <> +struct IntegerForSizeAndSign<2, true> +{ + typedef int16_t type; +}; +template <> +struct IntegerForSizeAndSign<2, false> +{ + typedef uint16_t type; +}; +template <> +struct IntegerForSizeAndSign<4, true> +{ + typedef int32_t type; +}; +template <> +struct IntegerForSizeAndSign<4, false> +{ + typedef uint32_t type; +}; +template <> +struct IntegerForSizeAndSign<8, true> +{ + typedef int64_t type; +}; +template <> +struct IntegerForSizeAndSign<8, false> +{ + typedef uint64_t type; +}; + +// WARNING: We have no IntegerForSizeAndSign<16, *>. If we ever add one to +// support 128-bit math, then the ArithmeticPromotion template below will need +// to be updated (or more likely replaced with a decltype expression). + +template +struct UnsignedIntegerForSize +{ + typedef + typename std::enable_if::is_integer, + typename IntegerForSizeAndSign::type>::type + type; +}; + +template +struct SignedIntegerForSize +{ + typedef + typename std::enable_if::is_integer, + typename IntegerForSizeAndSign::type>::type + type; +}; + +template +struct TwiceWiderInteger +{ + typedef typename std::enable_if< + std::numeric_limits::is_integer, + typename IntegerForSizeAndSign::is_signed>::type>::type type; +}; + +template +struct PositionOfSignBit +{ + static const typename std::enable_if::is_integer, size_t>::type + value = CHAR_BIT * sizeof(Integer) - 1; +}; + +// This is used for UnsignedAbs, where we need to support floating-point +// template instantiations even though we don't actually support the operations. +// However, there is no corresponding implementation of e.g. CheckedUnsignedAbs, +// so the float versions will not compile. +template ::is_integer, + bool IsFloat = std::numeric_limits::is_iec559> +struct UnsignedOrFloatForSize; + +template +struct UnsignedOrFloatForSize +{ + typedef typename UnsignedIntegerForSize::type type; +}; + +template +struct UnsignedOrFloatForSize +{ + typedef Numeric type; +}; + +// Helper templates for integer manipulations. + +template +constexpr bool HasSignBit(T x) +{ + // Cast to unsigned since right shift on signed is undefined. + return !!(static_cast::type>(x) >> + PositionOfSignBit::value); +} + +// This wrapper undoes the standard integer promotions. +template +constexpr T BinaryComplement(T x) +{ + return static_cast(~x); +} + +// Here are the actual portable checked integer math implementations. +// TODO(jschuh): Break this code out from the enable_if pattern and find a clean +// way to coalesce things into the CheckedNumericState specializations below. + +template +typename std::enable_if::is_integer, T>::type +CheckedAdd(T x, T y, RangeConstraint *validity) +{ + // Since the value of x+y is undefined if we have a signed type, we compute + // it using the unsigned type of the same size. + typedef typename UnsignedIntegerForSize::type UnsignedDst; + UnsignedDst ux = static_cast(x); + UnsignedDst uy = static_cast(y); + UnsignedDst uresult = static_cast(ux + uy); + // Addition is valid if the sign of (x + y) is equal to either that of x or + // that of y. + if (std::numeric_limits::is_signed) + { + if (HasSignBit(BinaryComplement(static_cast((uresult ^ ux) & (uresult ^ uy))))) + { + *validity = RANGE_VALID; + } + else + { // Direction of wrap is inverse of result sign. + *validity = HasSignBit(uresult) ? RANGE_OVERFLOW : RANGE_UNDERFLOW; + } + } + else + { // Unsigned is either valid or overflow. + *validity = BinaryComplement(x) >= y ? RANGE_VALID : RANGE_OVERFLOW; + } + return static_cast(uresult); +} + +template +typename std::enable_if::is_integer, T>::type +CheckedSub(T x, T y, RangeConstraint *validity) +{ + // Since the value of x+y is undefined if we have a signed type, we compute + // it using the unsigned type of the same size. + typedef typename UnsignedIntegerForSize::type UnsignedDst; + UnsignedDst ux = static_cast(x); + UnsignedDst uy = static_cast(y); + UnsignedDst uresult = static_cast(ux - uy); + // Subtraction is valid if either x and y have same sign, or (x-y) and x have + // the same sign. + if (std::numeric_limits::is_signed) + { + if (HasSignBit(BinaryComplement(static_cast((uresult ^ ux) & (ux ^ uy))))) + { + *validity = RANGE_VALID; + } + else + { // Direction of wrap is inverse of result sign. + *validity = HasSignBit(uresult) ? RANGE_OVERFLOW : RANGE_UNDERFLOW; + } + } + else + { // Unsigned is either valid or underflow. + *validity = x >= y ? RANGE_VALID : RANGE_UNDERFLOW; + } + return static_cast(uresult); +} + +// Integer multiplication is a bit complicated. In the fast case we just +// we just promote to a twice wider type, and range check the result. In the +// slow case we need to manually check that the result won't be truncated by +// checking with division against the appropriate bound. +template +typename std::enable_if::is_integer && sizeof(T) * 2 <= sizeof(uintmax_t), + T>::type +CheckedMul(T x, T y, RangeConstraint *validity) +{ + typedef typename TwiceWiderInteger::type IntermediateType; + IntermediateType tmp = static_cast(x) * static_cast(y); + *validity = DstRangeRelationToSrcRange(tmp); + return static_cast(tmp); +} + +template +typename std::enable_if::is_integer && std::numeric_limits::is_signed && + (sizeof(T) * 2 > sizeof(uintmax_t)), + T>::type +CheckedMul(T x, T y, RangeConstraint *validity) +{ + // If either side is zero then the result will be zero. + if (!x || !y) + { + *validity = RANGE_VALID; + return static_cast(0); + } + else if (x > 0) + { + if (y > 0) + *validity = x <= std::numeric_limits::max() / y ? RANGE_VALID : RANGE_OVERFLOW; + else + *validity = y >= std::numeric_limits::min() / x ? RANGE_VALID : RANGE_UNDERFLOW; + } + else + { + if (y > 0) + *validity = x >= std::numeric_limits::min() / y ? RANGE_VALID : RANGE_UNDERFLOW; + else + *validity = y >= std::numeric_limits::max() / x ? RANGE_VALID : RANGE_OVERFLOW; + } + + return static_cast(x * y); +} + +template +typename std::enable_if::is_integer && !std::numeric_limits::is_signed && + (sizeof(T) * 2 > sizeof(uintmax_t)), + T>::type +CheckedMul(T x, T y, RangeConstraint *validity) +{ + *validity = (y == 0 || x <= std::numeric_limits::max() / y) ? RANGE_VALID : RANGE_OVERFLOW; + return static_cast(x * y); +} + +// Division just requires a check for an invalid negation on signed min/-1. +template +T CheckedDiv(T x, + T y, + RangeConstraint *validity, + typename std::enable_if::is_integer, int>::type = 0) +{ + if (std::numeric_limits::is_signed && x == std::numeric_limits::min() && + y == static_cast(-1)) + { + *validity = RANGE_OVERFLOW; + return std::numeric_limits::min(); + } + + *validity = RANGE_VALID; + return static_cast(x / y); +} + +template +typename std::enable_if::is_integer && std::numeric_limits::is_signed, + T>::type +CheckedMod(T x, T y, RangeConstraint *validity) +{ + *validity = y > 0 ? RANGE_VALID : RANGE_INVALID; + return static_cast(x % y); +} + +template +typename std::enable_if::is_integer && !std::numeric_limits::is_signed, + T>::type +CheckedMod(T x, T y, RangeConstraint *validity) +{ + *validity = RANGE_VALID; + return static_cast(x % y); +} + +template +typename std::enable_if::is_integer && std::numeric_limits::is_signed, + T>::type +CheckedNeg(T value, RangeConstraint *validity) +{ + *validity = value != std::numeric_limits::min() ? RANGE_VALID : RANGE_OVERFLOW; + // The negation of signed min is min, so catch that one. + return static_cast(-value); +} + +template +typename std::enable_if::is_integer && !std::numeric_limits::is_signed, + T>::type +CheckedNeg(T value, RangeConstraint *validity) +{ + // The only legal unsigned negation is zero. + *validity = value ? RANGE_UNDERFLOW : RANGE_VALID; + return static_cast(-static_cast::type>(value)); +} + +template +typename std::enable_if::is_integer && std::numeric_limits::is_signed, + T>::type +CheckedAbs(T value, RangeConstraint *validity) +{ + *validity = value != std::numeric_limits::min() ? RANGE_VALID : RANGE_OVERFLOW; + return static_cast(std::abs(value)); +} + +template +typename std::enable_if::is_integer && !std::numeric_limits::is_signed, + T>::type +CheckedAbs(T value, RangeConstraint *validity) +{ + // T is unsigned, so |value| must already be positive. + *validity = RANGE_VALID; + return value; +} + +template +typename std::enable_if::is_integer && std::numeric_limits::is_signed, + typename UnsignedIntegerForSize::type>::type +CheckedUnsignedAbs(T value) +{ + typedef typename UnsignedIntegerForSize::type UnsignedT; + return value == std::numeric_limits::min() + ? static_cast(std::numeric_limits::max()) + 1 + : static_cast(std::abs(value)); +} + +template +typename std::enable_if::is_integer && !std::numeric_limits::is_signed, + T>::type +CheckedUnsignedAbs(T value) +{ + // T is unsigned, so |value| must already be positive. + return static_cast(value); +} + +// These are the floating point stubs that the compiler needs to see. Only the +// negation operation is ever called. +#define ANGLEBASE_FLOAT_ARITHMETIC_STUBS(NAME) \ + template \ + typename std::enable_if::is_iec559, T>::type Checked##NAME( \ + T, T, RangeConstraint *) \ + { \ + NOTREACHED(); \ + return static_cast(0); \ + } + +ANGLEBASE_FLOAT_ARITHMETIC_STUBS(Add) +ANGLEBASE_FLOAT_ARITHMETIC_STUBS(Sub) +ANGLEBASE_FLOAT_ARITHMETIC_STUBS(Mul) +ANGLEBASE_FLOAT_ARITHMETIC_STUBS(Div) +ANGLEBASE_FLOAT_ARITHMETIC_STUBS(Mod) + +#undef ANGLEBASE_FLOAT_ARITHMETIC_STUBS + +template +typename std::enable_if::is_iec559, T>::type CheckedNeg(T value, + RangeConstraint *) +{ + return static_cast(-value); +} + +template +typename std::enable_if::is_iec559, T>::type CheckedAbs(T value, + RangeConstraint *) +{ + return static_cast(std::abs(value)); +} + +// Floats carry around their validity state with them, but integers do not. So, +// we wrap the underlying value in a specialization in order to hide that detail +// and expose an interface via accessors. +enum NumericRepresentation +{ + NUMERIC_INTEGER, + NUMERIC_FLOATING, + NUMERIC_UNKNOWN +}; + +template +struct GetNumericRepresentation +{ + static const NumericRepresentation value = + std::numeric_limits::is_integer + ? NUMERIC_INTEGER + : (std::numeric_limits::is_iec559 ? NUMERIC_FLOATING : NUMERIC_UNKNOWN); +}; + +template ::value> +class CheckedNumericState +{ +}; + +// Integrals require quite a bit of additional housekeeping to manage state. +template +class CheckedNumericState +{ + private: + T value_; + RangeConstraint validity_ : CHAR_BIT; // Actually requires only two bits. + + public: + template + friend class CheckedNumericState; + + CheckedNumericState() : value_(0), validity_(RANGE_VALID) {} + + template + CheckedNumericState(Src value, RangeConstraint validity) + : value_(static_cast(value)), + validity_(GetRangeConstraint(validity | DstRangeRelationToSrcRange(value))) + { + static_assert(std::numeric_limits::is_specialized, "Argument must be numeric."); + } + + // Copy constructor. + template + CheckedNumericState(const CheckedNumericState &rhs) + : value_(static_cast(rhs.value())), + validity_(GetRangeConstraint(rhs.validity() | DstRangeRelationToSrcRange(rhs.value()))) + { + } + + template + explicit CheckedNumericState( + Src value, + typename std::enable_if::is_specialized, int>::type = 0) + : value_(static_cast(value)), validity_(DstRangeRelationToSrcRange(value)) + { + } + + RangeConstraint validity() const { return validity_; } + T value() const { return value_; } +}; + +// Floating points maintain their own validity, but need translation wrappers. +template +class CheckedNumericState +{ + private: + T value_; + + public: + template + friend class CheckedNumericState; + + CheckedNumericState() : value_(0.0) {} + + template + CheckedNumericState( + Src value, + RangeConstraint validity, + typename std::enable_if::is_integer, int>::type = 0) + { + switch (DstRangeRelationToSrcRange(value)) + { + case RANGE_VALID: + value_ = static_cast(value); + break; + + case RANGE_UNDERFLOW: + value_ = -std::numeric_limits::infinity(); + break; + + case RANGE_OVERFLOW: + value_ = std::numeric_limits::infinity(); + break; + + case RANGE_INVALID: + value_ = std::numeric_limits::quiet_NaN(); + break; + + default: + NOTREACHED(); + } + } + + template + explicit CheckedNumericState( + Src value, + typename std::enable_if::is_specialized, int>::type = 0) + : value_(static_cast(value)) + { + } + + // Copy constructor. + template + CheckedNumericState(const CheckedNumericState &rhs) : value_(static_cast(rhs.value())) + { + } + + RangeConstraint validity() const + { + return GetRangeConstraint(value_ <= std::numeric_limits::max(), + value_ >= -std::numeric_limits::max()); + } + T value() const { return value_; } +}; + +// For integers less than 128-bit and floats 32-bit or larger, we have the type +// with the larger maximum exponent take precedence. +enum ArithmeticPromotionCategory +{ + LEFT_PROMOTION, + RIGHT_PROMOTION +}; + +template ::value > MaxExponent::value) ? LEFT_PROMOTION + : RIGHT_PROMOTION> +struct ArithmeticPromotion; + +template +struct ArithmeticPromotion +{ + typedef Lhs type; +}; + +template +struct ArithmeticPromotion +{ + typedef Rhs type; +}; + +// We can statically check if operations on the provided types can wrap, so we +// can skip the checked operations if they're not needed. So, for an integer we +// care if the destination type preserves the sign and is twice the width of +// the source. +template +struct IsIntegerArithmeticSafe +{ + static const bool value = + !std::numeric_limits::is_iec559 && + StaticDstRangeRelationToSrcRange::value == NUMERIC_RANGE_CONTAINED && + sizeof(T) >= (2 * sizeof(Lhs)) && + StaticDstRangeRelationToSrcRange::value != NUMERIC_RANGE_CONTAINED && + sizeof(T) >= (2 * sizeof(Rhs)); +}; + +} // namespace internal +} // namespace base + +} // namespace angle + +#endif // ANGLEBASE_NUMERICS_SAFE_MATH_IMPL_H_ diff --git a/src/3rdparty/angle/src/common/third_party/base/anglebase/numerics/safe_numerics_unittest.cc b/src/3rdparty/angle/src/common/third_party/base/anglebase/numerics/safe_numerics_unittest.cc new file mode 100644 index 0000000000..052d850427 --- /dev/null +++ b/src/3rdparty/angle/src/common/third_party/base/anglebase/numerics/safe_numerics_unittest.cc @@ -0,0 +1,771 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include +#include + +#include +#include + +#include "base/compiler_specific.h" +#include "base/numerics/safe_conversions.h" +#include "base/numerics/safe_math.h" +#include "build/build_config.h" +#include "testing/gtest/include/gtest/gtest.h" + +#if defined(COMPILER_MSVC) && defined(ARCH_CPU_32_BITS) +#include +#endif + +using std::numeric_limits; +using base::CheckedNumeric; +using base::checked_cast; +using base::IsValueInRangeForNumericType; +using base::IsValueNegative; +using base::SizeT; +using base::StrictNumeric; +using base::saturated_cast; +using base::strict_cast; +using base::internal::MaxExponent; +using base::internal::RANGE_VALID; +using base::internal::RANGE_INVALID; +using base::internal::RANGE_OVERFLOW; +using base::internal::RANGE_UNDERFLOW; +using base::internal::SignedIntegerForSize; + +// These tests deliberately cause arithmetic overflows. If the compiler is +// aggressive enough, it can const fold these overflows. Disable warnings about +// overflows for const expressions. +#if defined(OS_WIN) +#pragma warning(disable : 4756) +#endif + +// This is a helper function for finding the maximum value in Src that can be +// wholy represented as the destination floating-point type. +template +Dst GetMaxConvertibleToFloat() +{ + typedef numeric_limits DstLimits; + typedef numeric_limits SrcLimits; + static_assert(SrcLimits::is_specialized, "Source must be numeric."); + static_assert(DstLimits::is_specialized, "Destination must be numeric."); + CHECK(DstLimits::is_iec559); + + if (SrcLimits::digits <= DstLimits::digits && + MaxExponent::value <= MaxExponent::value) + return SrcLimits::max(); + Src max = SrcLimits::max() / 2 + (SrcLimits::is_integer ? 1 : 0); + while (max != static_cast(static_cast(max))) + { + max /= 2; + } + return static_cast(max); +} + +// Helper macros to wrap displaying the conversion types and line numbers. +#define TEST_EXPECTED_VALIDITY(expected, actual) \ + EXPECT_EQ(expected, CheckedNumeric(actual).IsValid()) \ + << "Result test: Value " << +(actual).ValueUnsafe() << " as " << dst << " on line " \ + << line; + +#define TEST_EXPECTED_SUCCESS(actual) TEST_EXPECTED_VALIDITY(true, actual) +#define TEST_EXPECTED_FAILURE(actual) TEST_EXPECTED_VALIDITY(false, actual) + +#define TEST_EXPECTED_VALUE(expected, actual) \ + EXPECT_EQ(static_cast(expected), CheckedNumeric(actual).ValueUnsafe()) \ + << "Result test: Value " << +((actual).ValueUnsafe()) << " as " << dst << " on line " \ + << line; + +// Signed integer arithmetic. +template +static void TestSpecializedArithmetic( + const char *dst, + int line, + typename std::enable_if::is_integer && numeric_limits::is_signed, + int>::type = 0) +{ + typedef numeric_limits DstLimits; + TEST_EXPECTED_FAILURE(-CheckedNumeric(DstLimits::min())); + TEST_EXPECTED_FAILURE(CheckedNumeric(DstLimits::min()).Abs()); + TEST_EXPECTED_VALUE(1, CheckedNumeric(-1).Abs()); + + TEST_EXPECTED_SUCCESS(CheckedNumeric(DstLimits::max()) + -1); + TEST_EXPECTED_FAILURE(CheckedNumeric(DstLimits::min()) + -1); + TEST_EXPECTED_FAILURE(CheckedNumeric(-DstLimits::max()) + -DstLimits::max()); + + TEST_EXPECTED_FAILURE(CheckedNumeric(DstLimits::min()) - 1); + TEST_EXPECTED_SUCCESS(CheckedNumeric(DstLimits::min()) - -1); + TEST_EXPECTED_FAILURE(CheckedNumeric(DstLimits::max()) - -DstLimits::max()); + TEST_EXPECTED_FAILURE(CheckedNumeric(-DstLimits::max()) - DstLimits::max()); + + TEST_EXPECTED_FAILURE(CheckedNumeric(DstLimits::min()) * 2); + + TEST_EXPECTED_FAILURE(CheckedNumeric(DstLimits::min()) / -1); + TEST_EXPECTED_VALUE(0, CheckedNumeric(-1) / 2); + + // Modulus is legal only for integers. + TEST_EXPECTED_VALUE(0, CheckedNumeric() % 1); + TEST_EXPECTED_VALUE(0, CheckedNumeric(1) % 1); + TEST_EXPECTED_VALUE(-1, CheckedNumeric(-1) % 2); + TEST_EXPECTED_FAILURE(CheckedNumeric(-1) % -2); + TEST_EXPECTED_VALUE(0, CheckedNumeric(DstLimits::min()) % 2); + TEST_EXPECTED_VALUE(1, CheckedNumeric(DstLimits::max()) % 2); + // Test all the different modulus combinations. + TEST_EXPECTED_VALUE(0, CheckedNumeric(1) % CheckedNumeric(1)); + TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric(1)); + TEST_EXPECTED_VALUE(0, CheckedNumeric(1) % 1); + CheckedNumeric checked_dst = 1; + TEST_EXPECTED_VALUE(0, checked_dst %= 1); +} + +// Unsigned integer arithmetic. +template +static void TestSpecializedArithmetic( + const char *dst, + int line, + typename std::enable_if::is_integer && !numeric_limits::is_signed, + int>::type = 0) +{ + typedef numeric_limits DstLimits; + TEST_EXPECTED_SUCCESS(-CheckedNumeric(DstLimits::min())); + TEST_EXPECTED_SUCCESS(CheckedNumeric(DstLimits::min()).Abs()); + TEST_EXPECTED_FAILURE(CheckedNumeric(DstLimits::min()) + -1); + TEST_EXPECTED_FAILURE(CheckedNumeric(DstLimits::min()) - 1); + TEST_EXPECTED_VALUE(0, CheckedNumeric(DstLimits::min()) * 2); + TEST_EXPECTED_VALUE(0, CheckedNumeric(1) / 2); + TEST_EXPECTED_SUCCESS(CheckedNumeric(DstLimits::min()).UnsignedAbs()); + TEST_EXPECTED_SUCCESS(CheckedNumeric::type>( + std::numeric_limits::type>::min()) + .UnsignedAbs()); + + // Modulus is legal only for integers. + TEST_EXPECTED_VALUE(0, CheckedNumeric() % 1); + TEST_EXPECTED_VALUE(0, CheckedNumeric(1) % 1); + TEST_EXPECTED_VALUE(1, CheckedNumeric(1) % 2); + TEST_EXPECTED_VALUE(0, CheckedNumeric(DstLimits::min()) % 2); + TEST_EXPECTED_VALUE(1, CheckedNumeric(DstLimits::max()) % 2); + // Test all the different modulus combinations. + TEST_EXPECTED_VALUE(0, CheckedNumeric(1) % CheckedNumeric(1)); + TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric(1)); + TEST_EXPECTED_VALUE(0, CheckedNumeric(1) % 1); + CheckedNumeric checked_dst = 1; + TEST_EXPECTED_VALUE(0, checked_dst %= 1); +} + +// Floating point arithmetic. +template +void TestSpecializedArithmetic( + const char *dst, + int line, + typename std::enable_if::is_iec559, int>::type = 0) +{ + typedef numeric_limits DstLimits; + TEST_EXPECTED_SUCCESS(-CheckedNumeric(DstLimits::min())); + + TEST_EXPECTED_SUCCESS(CheckedNumeric(DstLimits::min()).Abs()); + TEST_EXPECTED_VALUE(1, CheckedNumeric(-1).Abs()); + + TEST_EXPECTED_SUCCESS(CheckedNumeric(DstLimits::min()) + -1); + TEST_EXPECTED_SUCCESS(CheckedNumeric(DstLimits::max()) + 1); + TEST_EXPECTED_FAILURE(CheckedNumeric(-DstLimits::max()) + -DstLimits::max()); + + TEST_EXPECTED_FAILURE(CheckedNumeric(DstLimits::max()) - -DstLimits::max()); + TEST_EXPECTED_FAILURE(CheckedNumeric(-DstLimits::max()) - DstLimits::max()); + + TEST_EXPECTED_SUCCESS(CheckedNumeric(DstLimits::min()) * 2); + + TEST_EXPECTED_VALUE(-0.5, CheckedNumeric(-1.0) / 2); + EXPECT_EQ(static_cast(1.0), CheckedNumeric(1.0).ValueFloating()); +} + +// Generic arithmetic tests. +template +static void TestArithmetic(const char *dst, int line) +{ + typedef numeric_limits DstLimits; + + EXPECT_EQ(true, CheckedNumeric().IsValid()); + EXPECT_EQ( + false, + CheckedNumeric(CheckedNumeric(DstLimits::max()) * DstLimits::max()).IsValid()); + EXPECT_EQ(static_cast(0), CheckedNumeric().ValueOrDie()); + EXPECT_EQ(static_cast(0), CheckedNumeric().ValueOrDefault(1)); + EXPECT_EQ(static_cast(1), + CheckedNumeric(CheckedNumeric(DstLimits::max()) * DstLimits::max()) + .ValueOrDefault(1)); + + // Test the operator combinations. + TEST_EXPECTED_VALUE(2, CheckedNumeric(1) + CheckedNumeric(1)); + TEST_EXPECTED_VALUE(0, CheckedNumeric(1) - CheckedNumeric(1)); + TEST_EXPECTED_VALUE(1, CheckedNumeric(1) * CheckedNumeric(1)); + TEST_EXPECTED_VALUE(1, CheckedNumeric(1) / CheckedNumeric(1)); + TEST_EXPECTED_VALUE(2, 1 + CheckedNumeric(1)); + TEST_EXPECTED_VALUE(0, 1 - CheckedNumeric(1)); + TEST_EXPECTED_VALUE(1, 1 * CheckedNumeric(1)); + TEST_EXPECTED_VALUE(1, 1 / CheckedNumeric(1)); + TEST_EXPECTED_VALUE(2, CheckedNumeric(1) + 1); + TEST_EXPECTED_VALUE(0, CheckedNumeric(1) - 1); + TEST_EXPECTED_VALUE(1, CheckedNumeric(1) * 1); + TEST_EXPECTED_VALUE(1, CheckedNumeric(1) / 1); + CheckedNumeric checked_dst = 1; + TEST_EXPECTED_VALUE(2, checked_dst += 1); + checked_dst = 1; + TEST_EXPECTED_VALUE(0, checked_dst -= 1); + checked_dst = 1; + TEST_EXPECTED_VALUE(1, checked_dst *= 1); + checked_dst = 1; + TEST_EXPECTED_VALUE(1, checked_dst /= 1); + + // Generic negation. + TEST_EXPECTED_VALUE(0, -CheckedNumeric()); + TEST_EXPECTED_VALUE(-1, -CheckedNumeric(1)); + TEST_EXPECTED_VALUE(1, -CheckedNumeric(-1)); + TEST_EXPECTED_VALUE(static_cast(DstLimits::max() * -1), + -CheckedNumeric(DstLimits::max())); + + // Generic absolute value. + TEST_EXPECTED_VALUE(0, CheckedNumeric().Abs()); + TEST_EXPECTED_VALUE(1, CheckedNumeric(1).Abs()); + TEST_EXPECTED_VALUE(DstLimits::max(), CheckedNumeric(DstLimits::max()).Abs()); + + // Generic addition. + TEST_EXPECTED_VALUE(1, (CheckedNumeric() + 1)); + TEST_EXPECTED_VALUE(2, (CheckedNumeric(1) + 1)); + TEST_EXPECTED_VALUE(0, (CheckedNumeric(-1) + 1)); + TEST_EXPECTED_SUCCESS(CheckedNumeric(DstLimits::min()) + 1); + TEST_EXPECTED_FAILURE(CheckedNumeric(DstLimits::max()) + DstLimits::max()); + + // Generic subtraction. + TEST_EXPECTED_VALUE(-1, (CheckedNumeric() - 1)); + TEST_EXPECTED_VALUE(0, (CheckedNumeric(1) - 1)); + TEST_EXPECTED_VALUE(-2, (CheckedNumeric(-1) - 1)); + TEST_EXPECTED_SUCCESS(CheckedNumeric(DstLimits::max()) - 1); + + // Generic multiplication. + TEST_EXPECTED_VALUE(0, (CheckedNumeric() * 1)); + TEST_EXPECTED_VALUE(1, (CheckedNumeric(1) * 1)); + TEST_EXPECTED_VALUE(-2, (CheckedNumeric(-1) * 2)); + TEST_EXPECTED_VALUE(0, (CheckedNumeric(0) * 0)); + TEST_EXPECTED_VALUE(0, (CheckedNumeric(-1) * 0)); + TEST_EXPECTED_VALUE(0, (CheckedNumeric(0) * -1)); + TEST_EXPECTED_FAILURE(CheckedNumeric(DstLimits::max()) * DstLimits::max()); + + // Generic division. + TEST_EXPECTED_VALUE(0, CheckedNumeric() / 1); + TEST_EXPECTED_VALUE(1, CheckedNumeric(1) / 1); + TEST_EXPECTED_VALUE(DstLimits::min() / 2, CheckedNumeric(DstLimits::min()) / 2); + TEST_EXPECTED_VALUE(DstLimits::max() / 2, CheckedNumeric(DstLimits::max()) / 2); + + TestSpecializedArithmetic(dst, line); +} + +// Helper macro to wrap displaying the conversion types and line numbers. +#define TEST_ARITHMETIC(Dst) TestArithmetic(#Dst, __LINE__) + +TEST(SafeNumerics, SignedIntegerMath) +{ + TEST_ARITHMETIC(int8_t); + TEST_ARITHMETIC(int); + TEST_ARITHMETIC(intptr_t); + TEST_ARITHMETIC(intmax_t); +} + +TEST(SafeNumerics, UnsignedIntegerMath) +{ + TEST_ARITHMETIC(uint8_t); + TEST_ARITHMETIC(unsigned int); + TEST_ARITHMETIC(uintptr_t); + TEST_ARITHMETIC(uintmax_t); +} + +TEST(SafeNumerics, FloatingPointMath) +{ + TEST_ARITHMETIC(float); + TEST_ARITHMETIC(double); +} + +// Enumerates the five different conversions types we need to test. +enum NumericConversionType +{ + SIGN_PRESERVING_VALUE_PRESERVING, + SIGN_PRESERVING_NARROW, + SIGN_TO_UNSIGN_WIDEN_OR_EQUAL, + SIGN_TO_UNSIGN_NARROW, + UNSIGN_TO_SIGN_NARROW_OR_EQUAL, +}; + +// Template covering the different conversion tests. +template +struct TestNumericConversion +{ +}; + +// EXPECT_EQ wrappers providing specific detail on test failures. +#define TEST_EXPECTED_RANGE(expected, actual) \ + EXPECT_EQ(expected, base::internal::DstRangeRelationToSrcRange(actual)) \ + << "Conversion test: " << src << " value " << actual << " to " << dst << " on line " \ + << line; + +template +struct TestNumericConversion +{ + static void Test(const char *dst, const char *src, int line) + { + typedef numeric_limits SrcLimits; + typedef numeric_limits DstLimits; + // Integral to floating. + static_assert( + (DstLimits::is_iec559 && SrcLimits::is_integer) || + // Not floating to integral and... + (!(DstLimits::is_integer && SrcLimits::is_iec559) && + // Same sign, same numeric, source is narrower or same. + ((SrcLimits::is_signed == DstLimits::is_signed && sizeof(Dst) >= sizeof(Src)) || + // Or signed destination and source is smaller + (DstLimits::is_signed && sizeof(Dst) > sizeof(Src)))), + "Comparison must be sign preserving and value preserving"); + + const CheckedNumeric checked_dst = SrcLimits::max(); + TEST_EXPECTED_SUCCESS(checked_dst); + if (MaxExponent::value > MaxExponent::value) + { + if (MaxExponent::value >= MaxExponent::value * 2 - 1) + { + // At least twice larger type. + TEST_EXPECTED_SUCCESS(SrcLimits::max() * checked_dst); + } + else + { // Larger, but not at least twice as large. + TEST_EXPECTED_FAILURE(SrcLimits::max() * checked_dst); + TEST_EXPECTED_SUCCESS(checked_dst + 1); + } + } + else + { // Same width type. + TEST_EXPECTED_FAILURE(checked_dst + 1); + } + + TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max()); + TEST_EXPECTED_RANGE(RANGE_VALID, static_cast(1)); + if (SrcLimits::is_iec559) + { + TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max() * static_cast(-1)); + TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); + TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); + TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); + } + else if (numeric_limits::is_signed) + { + TEST_EXPECTED_RANGE(RANGE_VALID, static_cast(-1)); + TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min()); + } + } +}; + +template +struct TestNumericConversion +{ + static void Test(const char *dst, const char *src, int line) + { + typedef numeric_limits SrcLimits; + typedef numeric_limits DstLimits; + static_assert(SrcLimits::is_signed == DstLimits::is_signed, + "Destination and source sign must be the same"); + static_assert(sizeof(Dst) < sizeof(Src) || (DstLimits::is_integer && SrcLimits::is_iec559), + "Destination must be narrower than source"); + + const CheckedNumeric checked_dst; + TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max()); + TEST_EXPECTED_VALUE(1, checked_dst + static_cast(1)); + TEST_EXPECTED_FAILURE(checked_dst - SrcLimits::max()); + + TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); + TEST_EXPECTED_RANGE(RANGE_VALID, static_cast(1)); + if (SrcLimits::is_iec559) + { + TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1); + TEST_EXPECTED_RANGE(RANGE_VALID, static_cast(-1)); + TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); + TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); + TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); + if (DstLimits::is_integer) + { + if (SrcLimits::digits < DstLimits::digits) + { + TEST_EXPECTED_RANGE(RANGE_OVERFLOW, static_cast(DstLimits::max())); + } + else + { + TEST_EXPECTED_RANGE(RANGE_VALID, static_cast(DstLimits::max())); + } + TEST_EXPECTED_RANGE(RANGE_VALID, + static_cast(GetMaxConvertibleToFloat())); + TEST_EXPECTED_RANGE(RANGE_VALID, static_cast(DstLimits::min())); + } + } + else if (SrcLimits::is_signed) + { + TEST_EXPECTED_VALUE(-1, checked_dst - static_cast(1)); + TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min()); + TEST_EXPECTED_RANGE(RANGE_VALID, static_cast(-1)); + } + else + { + TEST_EXPECTED_FAILURE(checked_dst - static_cast(1)); + TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min()); + } + } +}; + +template +struct TestNumericConversion +{ + static void Test(const char *dst, const char *src, int line) + { + typedef numeric_limits SrcLimits; + typedef numeric_limits DstLimits; + static_assert(sizeof(Dst) >= sizeof(Src), + "Destination must be equal or wider than source."); + static_assert(SrcLimits::is_signed, "Source must be signed"); + static_assert(!DstLimits::is_signed, "Destination must be unsigned"); + + const CheckedNumeric checked_dst; + TEST_EXPECTED_VALUE(SrcLimits::max(), checked_dst + SrcLimits::max()); + TEST_EXPECTED_FAILURE(checked_dst + static_cast(-1)); + TEST_EXPECTED_FAILURE(checked_dst + -SrcLimits::max()); + + TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min()); + TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max()); + TEST_EXPECTED_RANGE(RANGE_VALID, static_cast(1)); + TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast(-1)); + } +}; + +template +struct TestNumericConversion +{ + static void Test(const char *dst, const char *src, int line) + { + typedef numeric_limits SrcLimits; + typedef numeric_limits DstLimits; + static_assert( + (DstLimits::is_integer && SrcLimits::is_iec559) || (sizeof(Dst) < sizeof(Src)), + "Destination must be narrower than source."); + static_assert(SrcLimits::is_signed, "Source must be signed."); + static_assert(!DstLimits::is_signed, "Destination must be unsigned."); + + const CheckedNumeric checked_dst; + TEST_EXPECTED_VALUE(1, checked_dst + static_cast(1)); + TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max()); + TEST_EXPECTED_FAILURE(checked_dst + static_cast(-1)); + TEST_EXPECTED_FAILURE(checked_dst + -SrcLimits::max()); + + TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); + TEST_EXPECTED_RANGE(RANGE_VALID, static_cast(1)); + TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast(-1)); + if (SrcLimits::is_iec559) + { + TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1); + TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); + TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); + TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); + if (DstLimits::is_integer) + { + if (SrcLimits::digits < DstLimits::digits) + { + TEST_EXPECTED_RANGE(RANGE_OVERFLOW, static_cast(DstLimits::max())); + } + else + { + TEST_EXPECTED_RANGE(RANGE_VALID, static_cast(DstLimits::max())); + } + TEST_EXPECTED_RANGE(RANGE_VALID, + static_cast(GetMaxConvertibleToFloat())); + TEST_EXPECTED_RANGE(RANGE_VALID, static_cast(DstLimits::min())); + } + } + else + { + TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min()); + } + } +}; + +template +struct TestNumericConversion +{ + static void Test(const char *dst, const char *src, int line) + { + typedef numeric_limits SrcLimits; + typedef numeric_limits DstLimits; + static_assert(sizeof(Dst) <= sizeof(Src), + "Destination must be narrower or equal to source."); + static_assert(!SrcLimits::is_signed, "Source must be unsigned."); + static_assert(DstLimits::is_signed, "Destination must be signed."); + + const CheckedNumeric checked_dst; + TEST_EXPECTED_VALUE(1, checked_dst + static_cast(1)); + TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max()); + TEST_EXPECTED_VALUE(SrcLimits::min(), checked_dst + SrcLimits::min()); + + TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min()); + TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); + TEST_EXPECTED_RANGE(RANGE_VALID, static_cast(1)); + } +}; + +// Helper macro to wrap displaying the conversion types and line numbers +#define TEST_NUMERIC_CONVERSION(d, s, t) TestNumericConversion::Test(#d, #s, __LINE__) + +TEST(SafeNumerics, IntMinOperations) +{ + TEST_NUMERIC_CONVERSION(int8_t, int8_t, SIGN_PRESERVING_VALUE_PRESERVING); + TEST_NUMERIC_CONVERSION(uint8_t, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING); + + TEST_NUMERIC_CONVERSION(int8_t, int, SIGN_PRESERVING_NARROW); + TEST_NUMERIC_CONVERSION(uint8_t, unsigned int, SIGN_PRESERVING_NARROW); + TEST_NUMERIC_CONVERSION(int8_t, float, SIGN_PRESERVING_NARROW); + + TEST_NUMERIC_CONVERSION(uint8_t, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL); + + TEST_NUMERIC_CONVERSION(uint8_t, int, SIGN_TO_UNSIGN_NARROW); + TEST_NUMERIC_CONVERSION(uint8_t, intmax_t, SIGN_TO_UNSIGN_NARROW); + TEST_NUMERIC_CONVERSION(uint8_t, float, SIGN_TO_UNSIGN_NARROW); + + TEST_NUMERIC_CONVERSION(int8_t, unsigned int, UNSIGN_TO_SIGN_NARROW_OR_EQUAL); + TEST_NUMERIC_CONVERSION(int8_t, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL); +} + +TEST(SafeNumerics, IntOperations) +{ + TEST_NUMERIC_CONVERSION(int, int, SIGN_PRESERVING_VALUE_PRESERVING); + TEST_NUMERIC_CONVERSION(unsigned int, unsigned int, SIGN_PRESERVING_VALUE_PRESERVING); + TEST_NUMERIC_CONVERSION(int, int8_t, SIGN_PRESERVING_VALUE_PRESERVING); + TEST_NUMERIC_CONVERSION(unsigned int, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING); + TEST_NUMERIC_CONVERSION(int, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING); + + TEST_NUMERIC_CONVERSION(int, intmax_t, SIGN_PRESERVING_NARROW); + TEST_NUMERIC_CONVERSION(unsigned int, uintmax_t, SIGN_PRESERVING_NARROW); + TEST_NUMERIC_CONVERSION(int, float, SIGN_PRESERVING_NARROW); + TEST_NUMERIC_CONVERSION(int, double, SIGN_PRESERVING_NARROW); + + TEST_NUMERIC_CONVERSION(unsigned int, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL); + TEST_NUMERIC_CONVERSION(unsigned int, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL); + + TEST_NUMERIC_CONVERSION(unsigned int, intmax_t, SIGN_TO_UNSIGN_NARROW); + TEST_NUMERIC_CONVERSION(unsigned int, float, SIGN_TO_UNSIGN_NARROW); + TEST_NUMERIC_CONVERSION(unsigned int, double, SIGN_TO_UNSIGN_NARROW); + + TEST_NUMERIC_CONVERSION(int, unsigned int, UNSIGN_TO_SIGN_NARROW_OR_EQUAL); + TEST_NUMERIC_CONVERSION(int, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL); +} + +TEST(SafeNumerics, IntMaxOperations) +{ + TEST_NUMERIC_CONVERSION(intmax_t, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING); + TEST_NUMERIC_CONVERSION(uintmax_t, uintmax_t, SIGN_PRESERVING_VALUE_PRESERVING); + TEST_NUMERIC_CONVERSION(intmax_t, int, SIGN_PRESERVING_VALUE_PRESERVING); + TEST_NUMERIC_CONVERSION(uintmax_t, unsigned int, SIGN_PRESERVING_VALUE_PRESERVING); + TEST_NUMERIC_CONVERSION(intmax_t, unsigned int, SIGN_PRESERVING_VALUE_PRESERVING); + TEST_NUMERIC_CONVERSION(intmax_t, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING); + + TEST_NUMERIC_CONVERSION(intmax_t, float, SIGN_PRESERVING_NARROW); + TEST_NUMERIC_CONVERSION(intmax_t, double, SIGN_PRESERVING_NARROW); + + TEST_NUMERIC_CONVERSION(uintmax_t, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL); + TEST_NUMERIC_CONVERSION(uintmax_t, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL); + + TEST_NUMERIC_CONVERSION(uintmax_t, float, SIGN_TO_UNSIGN_NARROW); + TEST_NUMERIC_CONVERSION(uintmax_t, double, SIGN_TO_UNSIGN_NARROW); + + TEST_NUMERIC_CONVERSION(intmax_t, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL); +} + +TEST(SafeNumerics, FloatOperations) +{ + TEST_NUMERIC_CONVERSION(float, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING); + TEST_NUMERIC_CONVERSION(float, uintmax_t, SIGN_PRESERVING_VALUE_PRESERVING); + TEST_NUMERIC_CONVERSION(float, int, SIGN_PRESERVING_VALUE_PRESERVING); + TEST_NUMERIC_CONVERSION(float, unsigned int, SIGN_PRESERVING_VALUE_PRESERVING); + + TEST_NUMERIC_CONVERSION(float, double, SIGN_PRESERVING_NARROW); +} + +TEST(SafeNumerics, DoubleOperations) +{ + TEST_NUMERIC_CONVERSION(double, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING); + TEST_NUMERIC_CONVERSION(double, uintmax_t, SIGN_PRESERVING_VALUE_PRESERVING); + TEST_NUMERIC_CONVERSION(double, int, SIGN_PRESERVING_VALUE_PRESERVING); + TEST_NUMERIC_CONVERSION(double, unsigned int, SIGN_PRESERVING_VALUE_PRESERVING); +} + +TEST(SafeNumerics, SizeTOperations) +{ + TEST_NUMERIC_CONVERSION(size_t, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL); + TEST_NUMERIC_CONVERSION(int, size_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL); +} + +TEST(SafeNumerics, CastTests) +{ +// MSVC catches and warns that we're forcing saturation in these tests. +// Since that's intentional, we need to shut this warning off. +#if defined(COMPILER_MSVC) +#pragma warning(disable : 4756) +#endif + + int small_positive = 1; + int small_negative = -1; + double double_small = 1.0; + double double_large = numeric_limits::max(); + double double_infinity = numeric_limits::infinity(); + double double_large_int = numeric_limits::max(); + double double_small_int = numeric_limits::min(); + + // Just test that the casts compile, since the other tests cover logic. + EXPECT_EQ(0, checked_cast(static_cast(0))); + EXPECT_EQ(0, strict_cast(static_cast(0))); + EXPECT_EQ(0, strict_cast(static_cast(0))); + EXPECT_EQ(0U, strict_cast(static_cast(0))); + EXPECT_EQ(1ULL, static_cast(StrictNumeric(1U))); + EXPECT_EQ(1ULL, static_cast(SizeT(1U))); + EXPECT_EQ(1U, static_cast(StrictNumeric(1U))); + + EXPECT_TRUE(CheckedNumeric(StrictNumeric(1U)).IsValid()); + EXPECT_TRUE(CheckedNumeric(StrictNumeric(1U)).IsValid()); + EXPECT_FALSE(CheckedNumeric(StrictNumeric(-1)).IsValid()); + + EXPECT_TRUE(IsValueNegative(-1)); + EXPECT_TRUE(IsValueNegative(numeric_limits::min())); + EXPECT_FALSE(IsValueNegative(numeric_limits::min())); + EXPECT_TRUE(IsValueNegative(-numeric_limits::max())); + EXPECT_FALSE(IsValueNegative(0)); + EXPECT_FALSE(IsValueNegative(1)); + EXPECT_FALSE(IsValueNegative(0u)); + EXPECT_FALSE(IsValueNegative(1u)); + EXPECT_FALSE(IsValueNegative(numeric_limits::max())); + EXPECT_FALSE(IsValueNegative(numeric_limits::max())); + EXPECT_FALSE(IsValueNegative(numeric_limits::max())); + + // These casts and coercions will fail to compile: + // EXPECT_EQ(0, strict_cast(static_cast(0))); + // EXPECT_EQ(0, strict_cast(static_cast(0))); + // EXPECT_EQ(1ULL, StrictNumeric(1)); + // EXPECT_EQ(1, StrictNumeric(1U)); + + // Test various saturation corner cases. + EXPECT_EQ(saturated_cast(small_negative), static_cast(small_negative)); + EXPECT_EQ(saturated_cast(small_positive), static_cast(small_positive)); + EXPECT_EQ(saturated_cast(small_negative), static_cast(0)); + EXPECT_EQ(saturated_cast(double_small), static_cast(double_small)); + EXPECT_EQ(saturated_cast(double_large), numeric_limits::max()); + EXPECT_EQ(saturated_cast(double_large), double_infinity); + EXPECT_EQ(saturated_cast(-double_large), -double_infinity); + EXPECT_EQ(numeric_limits::min(), saturated_cast(double_small_int)); + EXPECT_EQ(numeric_limits::max(), saturated_cast(double_large_int)); + + float not_a_number = + std::numeric_limits::infinity() - std::numeric_limits::infinity(); + EXPECT_TRUE(std::isnan(not_a_number)); + EXPECT_EQ(0, saturated_cast(not_a_number)); +} + +#if GTEST_HAS_DEATH_TEST + +TEST(SafeNumerics, SaturatedCastChecks) +{ + float not_a_number = + std::numeric_limits::infinity() - std::numeric_limits::infinity(); + EXPECT_TRUE(std::isnan(not_a_number)); + EXPECT_DEATH((saturated_cast(not_a_number)), ""); +} + +#endif // GTEST_HAS_DEATH_TEST + +TEST(SafeNumerics, IsValueInRangeForNumericType) +{ + EXPECT_TRUE(IsValueInRangeForNumericType(0)); + EXPECT_TRUE(IsValueInRangeForNumericType(1)); + EXPECT_TRUE(IsValueInRangeForNumericType(2)); + EXPECT_FALSE(IsValueInRangeForNumericType(-1)); + EXPECT_TRUE(IsValueInRangeForNumericType(0xffffffffu)); + EXPECT_TRUE(IsValueInRangeForNumericType(UINT64_C(0xffffffff))); + EXPECT_FALSE(IsValueInRangeForNumericType(UINT64_C(0x100000000))); + EXPECT_FALSE(IsValueInRangeForNumericType(UINT64_C(0x100000001))); + EXPECT_FALSE(IsValueInRangeForNumericType(std::numeric_limits::min())); + EXPECT_FALSE(IsValueInRangeForNumericType(std::numeric_limits::min())); + + EXPECT_TRUE(IsValueInRangeForNumericType(0)); + EXPECT_TRUE(IsValueInRangeForNumericType(1)); + EXPECT_TRUE(IsValueInRangeForNumericType(2)); + EXPECT_TRUE(IsValueInRangeForNumericType(-1)); + EXPECT_TRUE(IsValueInRangeForNumericType(0x7fffffff)); + EXPECT_TRUE(IsValueInRangeForNumericType(0x7fffffffu)); + EXPECT_FALSE(IsValueInRangeForNumericType(0x80000000u)); + EXPECT_FALSE(IsValueInRangeForNumericType(0xffffffffu)); + EXPECT_FALSE(IsValueInRangeForNumericType(INT64_C(0x80000000))); + EXPECT_FALSE(IsValueInRangeForNumericType(INT64_C(0xffffffff))); + EXPECT_FALSE(IsValueInRangeForNumericType(INT64_C(0x100000000))); + EXPECT_TRUE(IsValueInRangeForNumericType(std::numeric_limits::min())); + EXPECT_TRUE(IsValueInRangeForNumericType( + static_cast(std::numeric_limits::min()))); + EXPECT_FALSE(IsValueInRangeForNumericType( + static_cast(std::numeric_limits::min()) - 1)); + EXPECT_FALSE(IsValueInRangeForNumericType(std::numeric_limits::min())); + + EXPECT_TRUE(IsValueInRangeForNumericType(0)); + EXPECT_TRUE(IsValueInRangeForNumericType(1)); + EXPECT_TRUE(IsValueInRangeForNumericType(2)); + EXPECT_FALSE(IsValueInRangeForNumericType(-1)); + EXPECT_TRUE(IsValueInRangeForNumericType(0xffffffffu)); + EXPECT_TRUE(IsValueInRangeForNumericType(UINT64_C(0xffffffff))); + EXPECT_TRUE(IsValueInRangeForNumericType(UINT64_C(0x100000000))); + EXPECT_TRUE(IsValueInRangeForNumericType(UINT64_C(0x100000001))); + EXPECT_FALSE(IsValueInRangeForNumericType(std::numeric_limits::min())); + EXPECT_FALSE(IsValueInRangeForNumericType(INT64_C(-1))); + EXPECT_FALSE(IsValueInRangeForNumericType(std::numeric_limits::min())); + + EXPECT_TRUE(IsValueInRangeForNumericType(0)); + EXPECT_TRUE(IsValueInRangeForNumericType(1)); + EXPECT_TRUE(IsValueInRangeForNumericType(2)); + EXPECT_TRUE(IsValueInRangeForNumericType(-1)); + EXPECT_TRUE(IsValueInRangeForNumericType(0x7fffffff)); + EXPECT_TRUE(IsValueInRangeForNumericType(0x7fffffffu)); + EXPECT_TRUE(IsValueInRangeForNumericType(0x80000000u)); + EXPECT_TRUE(IsValueInRangeForNumericType(0xffffffffu)); + EXPECT_TRUE(IsValueInRangeForNumericType(INT64_C(0x80000000))); + EXPECT_TRUE(IsValueInRangeForNumericType(INT64_C(0xffffffff))); + EXPECT_TRUE(IsValueInRangeForNumericType(INT64_C(0x100000000))); + EXPECT_TRUE(IsValueInRangeForNumericType(INT64_C(0x7fffffffffffffff))); + EXPECT_TRUE(IsValueInRangeForNumericType(UINT64_C(0x7fffffffffffffff))); + EXPECT_FALSE(IsValueInRangeForNumericType(UINT64_C(0x8000000000000000))); + EXPECT_FALSE(IsValueInRangeForNumericType(UINT64_C(0xffffffffffffffff))); + EXPECT_TRUE(IsValueInRangeForNumericType(std::numeric_limits::min())); + EXPECT_TRUE(IsValueInRangeForNumericType( + static_cast(std::numeric_limits::min()))); + EXPECT_TRUE(IsValueInRangeForNumericType(std::numeric_limits::min())); +} + +TEST(SafeNumerics, CompoundNumericOperations) +{ + CheckedNumeric a = 1; + CheckedNumeric b = 2; + CheckedNumeric c = 3; + CheckedNumeric d = 4; + a += b; + EXPECT_EQ(3, a.ValueOrDie()); + a -= c; + EXPECT_EQ(0, a.ValueOrDie()); + d /= b; + EXPECT_EQ(2, d.ValueOrDie()); + d *= d; + EXPECT_EQ(4, d.ValueOrDie()); + + CheckedNumeric too_large = std::numeric_limits::max(); + EXPECT_TRUE(too_large.IsValid()); + too_large += d; + EXPECT_FALSE(too_large.IsValid()); + too_large -= d; + EXPECT_FALSE(too_large.IsValid()); + too_large /= d; + EXPECT_FALSE(too_large.IsValid()); +} diff --git a/src/3rdparty/angle/src/common/third_party/base/anglebase/sha1.cc b/src/3rdparty/angle/src/common/third_party/base/anglebase/sha1.cc new file mode 100644 index 0000000000..cb88ba06e1 --- /dev/null +++ b/src/3rdparty/angle/src/common/third_party/base/anglebase/sha1.cc @@ -0,0 +1,245 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "anglebase/sha1.h" + +#include +#include +#include + +#include "anglebase/sys_byteorder.h" + +namespace angle +{ + +namespace base +{ + +// Implementation of SHA-1. Only handles data in byte-sized blocks, +// which simplifies the code a fair bit. + +// Identifier names follow notation in FIPS PUB 180-3, where you'll +// also find a description of the algorithm: +// http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf + +// Usage example: +// +// SecureHashAlgorithm sha; +// while(there is data to hash) +// sha.Update(moredata, size of data); +// sha.Final(); +// memcpy(somewhere, sha.Digest(), 20); +// +// to reuse the instance of sha, call sha.Init(); + +// TODO(jhawkins): Replace this implementation with a per-platform +// implementation using each platform's crypto library. See +// http://crbug.com/47218 + +class SecureHashAlgorithm +{ + public: + SecureHashAlgorithm() { Init(); } + + static const int kDigestSizeBytes; + + void Init(); + void Update(const void *data, size_t nbytes); + void Final(); + + // 20 bytes of message digest. + const unsigned char *Digest() const { return reinterpret_cast(H); } + + private: + void Pad(); + void Process(); + + uint32_t A, B, C, D, E; + + uint32_t H[5]; + + union { + uint32_t W[80]; + uint8_t M[64]; + }; + + uint32_t cursor; + uint64_t l; +}; + +static inline uint32_t f(uint32_t t, uint32_t B, uint32_t C, uint32_t D) +{ + if (t < 20) + { + return (B & C) | ((~B) & D); + } + else if (t < 40) + { + return B ^ C ^ D; + } + else if (t < 60) + { + return (B & C) | (B & D) | (C & D); + } + else + { + return B ^ C ^ D; + } +} + +static inline uint32_t S(uint32_t n, uint32_t X) +{ + return (X << n) | (X >> (32 - n)); +} + +static inline uint32_t K(uint32_t t) +{ + if (t < 20) + { + return 0x5a827999; + } + else if (t < 40) + { + return 0x6ed9eba1; + } + else if (t < 60) + { + return 0x8f1bbcdc; + } + else + { + return 0xca62c1d6; + } +} + +const int SecureHashAlgorithm::kDigestSizeBytes = 20; + +void SecureHashAlgorithm::Init() +{ + A = 0; + B = 0; + C = 0; + D = 0; + E = 0; + cursor = 0; + l = 0; + H[0] = 0x67452301; + H[1] = 0xefcdab89; + H[2] = 0x98badcfe; + H[3] = 0x10325476; + H[4] = 0xc3d2e1f0; +} + +void SecureHashAlgorithm::Final() +{ + Pad(); + Process(); + + for (int t = 0; t < 5; ++t) + H[t] = ByteSwap(H[t]); +} + +void SecureHashAlgorithm::Update(const void *data, size_t nbytes) +{ + const uint8_t *d = reinterpret_cast(data); + while (nbytes--) + { + M[cursor++] = *d++; + if (cursor >= 64) + Process(); + l += 8; + } +} + +void SecureHashAlgorithm::Pad() +{ + M[cursor++] = 0x80; + + if (cursor > 64 - 8) + { + // pad out to next block + while (cursor < 64) + M[cursor++] = 0; + + Process(); + } + + while (cursor < 64 - 8) + M[cursor++] = 0; + + M[cursor++] = (l >> 56) & 0xff; + M[cursor++] = (l >> 48) & 0xff; + M[cursor++] = (l >> 40) & 0xff; + M[cursor++] = (l >> 32) & 0xff; + M[cursor++] = (l >> 24) & 0xff; + M[cursor++] = (l >> 16) & 0xff; + M[cursor++] = (l >> 8) & 0xff; + M[cursor++] = l & 0xff; +} + +void SecureHashAlgorithm::Process() +{ + uint32_t t; + + // Each a...e corresponds to a section in the FIPS 180-3 algorithm. + + // a. + // + // W and M are in a union, so no need to memcpy. + // memcpy(W, M, sizeof(M)); + for (t = 0; t < 16; ++t) + W[t] = ByteSwap(W[t]); + + // b. + for (t = 16; t < 80; ++t) + W[t] = S(1, W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]); + + // c. + A = H[0]; + B = H[1]; + C = H[2]; + D = H[3]; + E = H[4]; + + // d. + for (t = 0; t < 80; ++t) + { + uint32_t TEMP = S(5, A) + f(t, B, C, D) + E + W[t] + K(t); + E = D; + D = C; + C = S(30, B); + B = A; + A = TEMP; + } + + // e. + H[0] += A; + H[1] += B; + H[2] += C; + H[3] += D; + H[4] += E; + + cursor = 0; +} + +std::string SHA1HashString(const std::string &str) +{ + char hash[SecureHashAlgorithm::kDigestSizeBytes]; + SHA1HashBytes(reinterpret_cast(str.c_str()), str.length(), + reinterpret_cast(hash)); + return std::string(hash, SecureHashAlgorithm::kDigestSizeBytes); +} + +void SHA1HashBytes(const unsigned char *data, size_t len, unsigned char *hash) +{ + SecureHashAlgorithm sha; + sha.Update(data, len); + sha.Final(); + + memcpy(hash, sha.Digest(), SecureHashAlgorithm::kDigestSizeBytes); +} + +} // namespace base + +} // namespace angle diff --git a/src/3rdparty/angle/src/common/third_party/base/anglebase/sha1.h b/src/3rdparty/angle/src/common/third_party/base/anglebase/sha1.h new file mode 100644 index 0000000000..a60908814f --- /dev/null +++ b/src/3rdparty/angle/src/common/third_party/base/anglebase/sha1.h @@ -0,0 +1,36 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ANGLEBASE_SHA1_H_ +#define ANGLEBASE_SHA1_H_ + +#include + +#include + +#include "anglebase/base_export.h" + +namespace angle +{ + +namespace base +{ + +// These functions perform SHA-1 operations. + +static const size_t kSHA1Length = 20; // Length in bytes of a SHA-1 hash. + +// Computes the SHA-1 hash of the input string |str| and returns the full +// hash. +ANGLEBASE_EXPORT std::string SHA1HashString(const std::string &str); + +// Computes the SHA-1 hash of the |len| bytes in |data| and puts the hash +// in |hash|. |hash| must be kSHA1Length bytes long. +ANGLEBASE_EXPORT void SHA1HashBytes(const unsigned char *data, size_t len, unsigned char *hash); + +} // namespace base + +} // namespace angle + +#endif // ANGLEBASE_SHA1_H_ diff --git a/src/3rdparty/angle/src/common/third_party/base/anglebase/sys_byteorder.h b/src/3rdparty/angle/src/common/third_party/base/anglebase/sys_byteorder.h new file mode 100644 index 0000000000..43d1777f26 --- /dev/null +++ b/src/3rdparty/angle/src/common/third_party/base/anglebase/sys_byteorder.h @@ -0,0 +1,49 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// sys_byteorder.h: Compatiblity hacks for importing Chromium's base/SHA1. + +#ifndef ANGLEBASE_SYS_BYTEORDER_H_ +#define ANGLEBASE_SYS_BYTEORDER_H_ + +namespace angle +{ + +namespace base +{ + +// Returns a value with all bytes in |x| swapped, i.e. reverses the endianness. +inline uint16_t ByteSwap(uint16_t x) +{ +#if defined(_MSC_VER) + return _byteswap_ushort(x); +#else + return __builtin_bswap16(x); +#endif +} + +inline uint32_t ByteSwap(uint32_t x) +{ +#if defined(_MSC_VER) + return _byteswap_ulong(x); +#else + return __builtin_bswap32(x); +#endif +} + +inline uint64_t ByteSwap(uint64_t x) +{ +#if defined(_MSC_VER) + return _byteswap_uint64(x); +#else + return __builtin_bswap64(x); +#endif +} + +} // namespace base + +} // namespace angle + +#endif // ANGLEBASE_SYS_BYTEORDER_H_ \ No newline at end of file diff --git a/src/3rdparty/angle/src/common/third_party/smhasher/LICENSE b/src/3rdparty/angle/src/common/third_party/smhasher/LICENSE new file mode 100644 index 0000000000..3f18a844ad --- /dev/null +++ b/src/3rdparty/angle/src/common/third_party/smhasher/LICENSE @@ -0,0 +1,23 @@ +All MurmurHash source files are placed in the public domain. + +The license below applies to all other code in SMHasher: + +Copyright (c) 2011 Google, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/src/3rdparty/angle/src/common/third_party/smhasher/README.angle b/src/3rdparty/angle/src/common/third_party/smhasher/README.angle new file mode 100644 index 0000000000..b84ea3249b --- /dev/null +++ b/src/3rdparty/angle/src/common/third_party/smhasher/README.angle @@ -0,0 +1,14 @@ +Name: SMHasher +URL: http://code.google.com/p/smhasher/ +Version: 0 +Revision: 147 +License: MIT, Public Domain +License File: LICENSE +Security Critical: yes + +Description: +This is a library containing the MurmurHash3 function, and a hashing function +test suite. + +Licenses are MIT (SMHasher) and Public Domain (MurmurHash). + diff --git a/src/3rdparty/angle/src/common/third_party/smhasher/src/PMurHash.cpp b/src/3rdparty/angle/src/common/third_party/smhasher/src/PMurHash.cpp new file mode 100644 index 0000000000..071bc31539 --- /dev/null +++ b/src/3rdparty/angle/src/common/third_party/smhasher/src/PMurHash.cpp @@ -0,0 +1,320 @@ +/*----------------------------------------------------------------------------- + * MurmurHash3 was written by Austin Appleby, and is placed in the public + * domain. + * + * This implementation was written by Shane Day, and is also public domain. + * + * This is a portable ANSI C implementation of MurmurHash3_x86_32 (Murmur3A) + * with support for progressive processing. + */ + +/*----------------------------------------------------------------------------- + +If you want to understand the MurmurHash algorithm you would be much better +off reading the original source. Just point your browser at: +http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp + + +What this version provides? + +1. Progressive data feeding. Useful when the entire payload to be hashed +does not fit in memory or when the data is streamed through the application. +Also useful when hashing a number of strings with a common prefix. A partial +hash of a prefix string can be generated and reused for each suffix string. + +2. Portability. Plain old C so that it should compile on any old compiler. +Both CPU endian and access-alignment neutral, but avoiding inefficient code +when possible depending on CPU capabilities. + +3. Drop in. I personally like nice self contained public domain code, making it +easy to pilfer without loads of refactoring to work properly in the existing +application code & makefile structure and mucking around with licence files. +Just copy PMurHash.h and PMurHash.c and you're ready to go. + + +How does it work? + +We can only process entire 32 bit chunks of input, except for the very end +that may be shorter. So along with the partial hash we need to give back to +the caller a carry containing up to 3 bytes that we were unable to process. +This carry also needs to record the number of bytes the carry holds. I use +the low 2 bits as a count (0..3) and the carry bytes are shifted into the +high byte in stream order. + +To handle endianess I simply use a macro that reads a uint32_t and define +that macro to be a direct read on little endian machines, a read and swap +on big endian machines, or a byte-by-byte read if the endianess is unknown. + +-----------------------------------------------------------------------------*/ + + +#include "PMurHash.h" + +/* I used ugly type names in the header to avoid potential conflicts with + * application or system typedefs & defines. Since I'm not including any more + * headers below here I can rename these so that the code reads like C99 */ +#undef uint32_t +#define uint32_t MH_UINT32 +#undef uint8_t +#define uint8_t MH_UINT8 + +/* MSVC warnings we choose to ignore */ +#if defined(_MSC_VER) + #pragma warning(disable: 4127) /* conditional expression is constant */ +#endif + +/*----------------------------------------------------------------------------- + * Endianess, misalignment capabilities and util macros + * + * The following 3 macros are defined in this section. The other macros defined + * are only needed to help derive these 3. + * + * READ_UINT32(x) Read a little endian unsigned 32-bit int + * UNALIGNED_SAFE Defined if READ_UINT32 works on non-word boundaries + * ROTL32(x,r) Rotate x left by r bits + */ + +/* Convention is to define __BYTE_ORDER == to one of these values */ +#if !defined(__BIG_ENDIAN) + #define __BIG_ENDIAN 4321 +#endif +#if !defined(__LITTLE_ENDIAN) + #define __LITTLE_ENDIAN 1234 +#endif + +/* I386 */ +#if defined(_M_IX86) || defined(__i386__) || defined(__i386) || defined(i386) + #define __BYTE_ORDER __LITTLE_ENDIAN + #define UNALIGNED_SAFE +#endif + +/* gcc 'may' define __LITTLE_ENDIAN__ or __BIG_ENDIAN__ to 1 (Note the trailing __), + * or even _LITTLE_ENDIAN or _BIG_ENDIAN (Note the single _ prefix) */ +#if !defined(__BYTE_ORDER) + #if defined(__LITTLE_ENDIAN__) && __LITTLE_ENDIAN__==1 || defined(_LITTLE_ENDIAN) && _LITTLE_ENDIAN==1 + #define __BYTE_ORDER __LITTLE_ENDIAN + #elif defined(__BIG_ENDIAN__) && __BIG_ENDIAN__==1 || defined(_BIG_ENDIAN) && _BIG_ENDIAN==1 + #define __BYTE_ORDER __BIG_ENDIAN + #endif +#endif + +/* gcc (usually) defines xEL/EB macros for ARM and MIPS endianess */ +#if !defined(__BYTE_ORDER) + #if defined(__ARMEL__) || defined(__MIPSEL__) + #define __BYTE_ORDER __LITTLE_ENDIAN + #endif + #if defined(__ARMEB__) || defined(__MIPSEB__) + #define __BYTE_ORDER __BIG_ENDIAN + #endif +#endif + +/* Now find best way we can to READ_UINT32 */ +#if __BYTE_ORDER==__LITTLE_ENDIAN + /* CPU endian matches murmurhash algorithm, so read 32-bit word directly */ + #define READ_UINT32(ptr) (*((uint32_t*)(ptr))) +#elif __BYTE_ORDER==__BIG_ENDIAN + /* TODO: Add additional cases below where a compiler provided bswap32 is available */ + #if defined(__GNUC__) && (__GNUC__>4 || (__GNUC__==4 && __GNUC_MINOR__>=3)) + #define READ_UINT32(ptr) (__builtin_bswap32(*((uint32_t*)(ptr)))) + #else + /* Without a known fast bswap32 we're just as well off doing this */ + #define READ_UINT32(ptr) (ptr[0]|ptr[1]<<8|ptr[2]<<16|ptr[3]<<24) + #define UNALIGNED_SAFE + #endif +#else + /* Unknown endianess so last resort is to read individual bytes */ + #define READ_UINT32(ptr) (ptr[0]|ptr[1]<<8|ptr[2]<<16|ptr[3]<<24) + + /* Since we're not doing word-reads we can skip the messing about with realignment */ + #define UNALIGNED_SAFE +#endif + +/* Find best way to ROTL32 */ +#if defined(_MSC_VER) + #include /* Microsoft put _rotl declaration in here */ + #define ROTL32(x,r) _rotl(x,r) +#else + /* gcc recognises this code and generates a rotate instruction for CPUs with one */ + #define ROTL32(x,r) (((uint32_t)x << r) | ((uint32_t)x >> (32 - r))) +#endif + + +/*----------------------------------------------------------------------------- + * Core murmurhash algorithm macros */ + +#define C1 (0xcc9e2d51) +#define C2 (0x1b873593) + +/* This is the main processing body of the algorithm. It operates + * on each full 32-bits of input. */ +#define DOBLOCK(h1, k1) do{ \ + k1 *= C1; \ + k1 = ROTL32(k1,15); \ + k1 *= C2; \ + \ + h1 ^= k1; \ + h1 = ROTL32(h1,13); \ + h1 = h1*5+0xe6546b64; \ + }while(0) + + +/* Append unaligned bytes to carry, forcing hash churn if we have 4 bytes */ +/* cnt=bytes to process, h1=name of h1 var, c=carry, n=bytes in c, ptr/len=payload */ +#define DOBYTES(cnt, h1, c, n, ptr, len) do{ \ + int _i = cnt; \ + while(_i--) { \ + c = c>>8 | *ptr++<<24; \ + n++; len--; \ + if(n==4) { \ + DOBLOCK(h1, c); \ + n = 0; \ + } \ + } }while(0) + +/*---------------------------------------------------------------------------*/ + +namespace angle +{ +/* Main hashing function. Initialise carry to 0 and h1 to 0 or an initial seed + * if wanted. Both ph1 and pcarry are required arguments. */ +void PMurHash32_Process(uint32_t *ph1, uint32_t *pcarry, const void *key, int len) +{ + uint32_t h1 = *ph1; + uint32_t c = *pcarry; + + const uint8_t *ptr = (uint8_t*)key; + const uint8_t *end; + + /* Extract carry count from low 2 bits of c value */ + int n = c & 3; + +#if defined(UNALIGNED_SAFE) + /* This CPU handles unaligned word access */ + + /* Consume any carry bytes */ + int i = (4-n) & 3; + if(i && i <= len) { + DOBYTES(i, h1, c, n, ptr, len); + } + + /* Process 32-bit chunks */ + end = ptr + len/4*4; + for( ; ptr < end ; ptr+=4) { + uint32_t k1 = READ_UINT32(ptr); + DOBLOCK(h1, k1); + } + +#else /*UNALIGNED_SAFE*/ + /* This CPU does not handle unaligned word access */ + + /* Consume enough so that the next data byte is word aligned */ + int i = -(long)ptr & 3; + if(i && i <= len) { + DOBYTES(i, h1, c, n, ptr, len); + } + + /* We're now aligned. Process in aligned blocks. Specialise for each possible carry count */ + end = ptr + len/4*4; + switch(n) { /* how many bytes in c */ + case 0: /* c=[----] w=[3210] b=[3210]=w c'=[----] */ + for( ; ptr < end ; ptr+=4) { + uint32_t k1 = READ_UINT32(ptr); + DOBLOCK(h1, k1); + } + break; + case 1: /* c=[0---] w=[4321] b=[3210]=c>>24|w<<8 c'=[4---] */ + for( ; ptr < end ; ptr+=4) { + uint32_t k1 = c>>24; + c = READ_UINT32(ptr); + k1 |= c<<8; + DOBLOCK(h1, k1); + } + break; + case 2: /* c=[10--] w=[5432] b=[3210]=c>>16|w<<16 c'=[54--] */ + for( ; ptr < end ; ptr+=4) { + uint32_t k1 = c>>16; + c = READ_UINT32(ptr); + k1 |= c<<16; + DOBLOCK(h1, k1); + } + break; + case 3: /* c=[210-] w=[6543] b=[3210]=c>>8|w<<24 c'=[654-] */ + for( ; ptr < end ; ptr+=4) { + uint32_t k1 = c>>8; + c = READ_UINT32(ptr); + k1 |= c<<24; + DOBLOCK(h1, k1); + } + } +#endif /*UNALIGNED_SAFE*/ + + /* Advance over whole 32-bit chunks, possibly leaving 1..3 bytes */ + len -= len/4*4; + + /* Append any remaining bytes into carry */ + DOBYTES(len, h1, c, n, ptr, len); + + /* Copy out new running hash and carry */ + *ph1 = h1; + *pcarry = (c & ~0xff) | n; +} + +/*---------------------------------------------------------------------------*/ + +/* Finalize a hash. To match the original Murmur3A the total_length must be provided */ +uint32_t PMurHash32_Result(uint32_t h, uint32_t carry, uint32_t total_length) +{ + uint32_t k1; + int n = carry & 3; + if(n) { + k1 = carry >> (4-n)*8; + k1 *= C1; k1 = ROTL32(k1,15); k1 *= C2; h ^= k1; + } + h ^= total_length; + + /* fmix */ + h ^= h >> 16; + h *= 0x85ebca6b; + h ^= h >> 13; + h *= 0xc2b2ae35; + h ^= h >> 16; + + return h; +} + +/*---------------------------------------------------------------------------*/ + +/* Murmur3A compatable all-at-once */ +uint32_t PMurHash32(uint32_t seed, const void *key, int len) +{ + uint32_t h1=seed, carry=0; + PMurHash32_Process(&h1, &carry, key, len); + return PMurHash32_Result(h1, carry, len); +} + +/*---------------------------------------------------------------------------*/ + +/* Provide an API suitable for smhasher */ +void PMurHash32_test(const void *key, int len, uint32_t seed, void *out) +{ + uint32_t h1=seed, carry=0; + const uint8_t *ptr = (uint8_t*)key; + const uint8_t *end = ptr + len; + +#if 0 /* Exercise the progressive processing */ + while(ptr < end) { + //const uint8_t *mid = ptr + rand()%(end-ptr)+1; + const uint8_t *mid = ptr + (rand()&0xF); + mid = mid= 199901L ) + #include + #define MH_UINT32 uint32_t +#endif + +/* Otherwise try testing against max value macros from limit.h */ +#if !defined(MH_UINT32) + #include + #if (USHRT_MAX == 0xffffffffUL) + #define MH_UINT32 unsigned short + #elif (UINT_MAX == 0xffffffffUL) + #define MH_UINT32 unsigned int + #elif (ULONG_MAX == 0xffffffffUL) + #define MH_UINT32 unsigned long + #endif +#endif + +#if !defined(MH_UINT32) + #error Unable to determine type name for unsigned 32-bit int +#endif + +/* I'm yet to work on a platform where 'unsigned char' is not 8 bits */ +#define MH_UINT8 unsigned char + + +/* ------------------------------------------------------------------------- */ +/* Prototypes */ + +namespace angle +{ +void PMurHash32_Process(MH_UINT32 *ph1, MH_UINT32 *pcarry, const void *key, int len); +MH_UINT32 PMurHash32_Result(MH_UINT32 h1, MH_UINT32 carry, MH_UINT32 total_length); +MH_UINT32 PMurHash32(MH_UINT32 seed, const void *key, int len); + +void PMurHash32_test(const void *key, int len, MH_UINT32 seed, void *out); +} diff --git a/src/3rdparty/angle/src/common/tls.cpp b/src/3rdparty/angle/src/common/tls.cpp index cb1b32d325..10a10252f4 100644 --- a/src/3rdparty/angle/src/common/tls.cpp +++ b/src/3rdparty/angle/src/common/tls.cpp @@ -56,7 +56,7 @@ TLSIndex CreateTLSIndex() #elif defined(ANGLE_PLATFORM_POSIX) // Create global pool key - if ((pthread_key_create(&index, NULL)) != 0) + if ((pthread_key_create(&index, nullptr)) != 0) { index = TLS_INVALID_INDEX; } @@ -133,7 +133,7 @@ void *GetTLSValue(TLSIndex index) assert(index != TLS_INVALID_INDEX && "GetTLSValue(): Invalid TLS Index"); if (index == TLS_INVALID_INDEX) { - return NULL; + return nullptr; } #ifdef ANGLE_PLATFORM_WINDOWS diff --git a/src/3rdparty/angle/src/common/uniform_type_info_autogen.cpp b/src/3rdparty/angle/src/common/uniform_type_info_autogen.cpp new file mode 100644 index 0000000000..9c199128a4 --- /dev/null +++ b/src/3rdparty/angle/src/common/uniform_type_info_autogen.cpp @@ -0,0 +1,275 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_uniform_type_table.py. +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Uniform type info table: +// Metadata about a particular uniform format, indexed by GL type. + +#include +#include "common/utilities.h" + +using namespace angle; + +namespace gl +{ + +namespace +{ +constexpr std::array kInfoTable = { + {{GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_NONE, 0, 0, 0, 0, 0 * 0, 0 * 0, false, false, false}, + {GL_BOOL, GL_BOOL, GL_NONE, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint), sizeof(GLint) * 4, + sizeof(GLint) * 1, false, false, false}, + {GL_BOOL_VEC2, GL_BOOL, GL_NONE, GL_NONE, GL_BOOL_VEC2, 1, 2, 2, sizeof(GLint), + sizeof(GLint) * 4, sizeof(GLint) * 2, false, false, false}, + {GL_BOOL_VEC3, GL_BOOL, GL_NONE, GL_NONE, GL_BOOL_VEC3, 1, 3, 3, sizeof(GLint), + sizeof(GLint) * 4, sizeof(GLint) * 3, false, false, false}, + {GL_BOOL_VEC4, GL_BOOL, GL_NONE, GL_NONE, GL_BOOL_VEC4, 1, 4, 4, sizeof(GLint), + sizeof(GLint) * 4, sizeof(GLint) * 4, false, false, false}, + {GL_FLOAT, GL_FLOAT, GL_NONE, GL_NONE, GL_BOOL, 1, 1, 1, sizeof(GLfloat), sizeof(GLfloat) * 4, + sizeof(GLfloat) * 1, false, false, false}, + {GL_FLOAT_MAT2, GL_FLOAT, GL_NONE, GL_FLOAT_MAT2, GL_NONE, 2, 2, 4, sizeof(GLfloat), + sizeof(GLfloat) * 8, sizeof(GLfloat) * 4, false, true, false}, + {GL_FLOAT_MAT2x3, GL_FLOAT, GL_NONE, GL_FLOAT_MAT3x2, GL_NONE, 3, 2, 6, sizeof(GLfloat), + sizeof(GLfloat) * 12, sizeof(GLfloat) * 6, false, true, false}, + {GL_FLOAT_MAT2x4, GL_FLOAT, GL_NONE, GL_FLOAT_MAT4x2, GL_NONE, 4, 2, 8, sizeof(GLfloat), + sizeof(GLfloat) * 16, sizeof(GLfloat) * 8, false, true, false}, + {GL_FLOAT_MAT3, GL_FLOAT, GL_NONE, GL_FLOAT_MAT3, GL_NONE, 3, 3, 9, sizeof(GLfloat), + sizeof(GLfloat) * 12, sizeof(GLfloat) * 9, false, true, false}, + {GL_FLOAT_MAT3x2, GL_FLOAT, GL_NONE, GL_FLOAT_MAT2x3, GL_NONE, 2, 3, 6, sizeof(GLfloat), + sizeof(GLfloat) * 8, sizeof(GLfloat) * 6, false, true, false}, + {GL_FLOAT_MAT3x4, GL_FLOAT, GL_NONE, GL_FLOAT_MAT4x3, GL_NONE, 4, 3, 12, sizeof(GLfloat), + sizeof(GLfloat) * 16, sizeof(GLfloat) * 12, false, true, false}, + {GL_FLOAT_MAT4, GL_FLOAT, GL_NONE, GL_FLOAT_MAT4, GL_NONE, 4, 4, 16, sizeof(GLfloat), + sizeof(GLfloat) * 16, sizeof(GLfloat) * 16, false, true, false}, + {GL_FLOAT_MAT4x2, GL_FLOAT, GL_NONE, GL_FLOAT_MAT2x4, GL_NONE, 2, 4, 8, sizeof(GLfloat), + sizeof(GLfloat) * 8, sizeof(GLfloat) * 8, false, true, false}, + {GL_FLOAT_MAT4x3, GL_FLOAT, GL_NONE, GL_FLOAT_MAT3x4, GL_NONE, 3, 4, 12, sizeof(GLfloat), + sizeof(GLfloat) * 12, sizeof(GLfloat) * 12, false, true, false}, + {GL_FLOAT_VEC2, GL_FLOAT, GL_NONE, GL_NONE, GL_BOOL_VEC2, 1, 2, 2, sizeof(GLfloat), + sizeof(GLfloat) * 4, sizeof(GLfloat) * 2, false, false, false}, + {GL_FLOAT_VEC3, GL_FLOAT, GL_NONE, GL_NONE, GL_BOOL_VEC3, 1, 3, 3, sizeof(GLfloat), + sizeof(GLfloat) * 4, sizeof(GLfloat) * 3, false, false, false}, + {GL_FLOAT_VEC4, GL_FLOAT, GL_NONE, GL_NONE, GL_BOOL_VEC4, 1, 4, 4, sizeof(GLfloat), + sizeof(GLfloat) * 4, sizeof(GLfloat) * 4, false, false, false}, + {GL_IMAGE_2D, GL_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint), + sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, true}, + {GL_IMAGE_2D_ARRAY, GL_INT, GL_TEXTURE_2D_ARRAY, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint), + sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, true}, + {GL_IMAGE_3D, GL_INT, GL_TEXTURE_3D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint), + sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, true}, + {GL_IMAGE_CUBE, GL_INT, GL_TEXTURE_CUBE_MAP, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint), + sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, true}, + {GL_INT, GL_INT, GL_NONE, GL_NONE, GL_BOOL, 1, 1, 1, sizeof(GLint), sizeof(GLint) * 4, + sizeof(GLint) * 1, false, false, false}, + {GL_INT_IMAGE_2D, GL_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint), + sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, true}, + {GL_INT_IMAGE_2D_ARRAY, GL_INT, GL_TEXTURE_2D_ARRAY, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint), + sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, true}, + {GL_INT_IMAGE_3D, GL_INT, GL_TEXTURE_3D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint), + sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, true}, + {GL_INT_IMAGE_CUBE, GL_INT, GL_TEXTURE_CUBE_MAP, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint), + sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, true}, + {GL_INT_SAMPLER_2D, GL_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint), + sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false}, + {GL_INT_SAMPLER_2D_ARRAY, GL_INT, GL_TEXTURE_2D_ARRAY, GL_NONE, GL_NONE, 1, 1, 1, + sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false}, + {GL_INT_SAMPLER_2D_MULTISAMPLE, GL_INT, GL_TEXTURE_2D_MULTISAMPLE, GL_NONE, GL_NONE, 1, 1, 1, + sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false}, + {GL_INT_SAMPLER_3D, GL_INT, GL_TEXTURE_3D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint), + sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false}, + {GL_INT_SAMPLER_CUBE, GL_INT, GL_TEXTURE_CUBE_MAP, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint), + sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false}, + {GL_INT_VEC2, GL_INT, GL_NONE, GL_NONE, GL_BOOL_VEC2, 1, 2, 2, sizeof(GLint), + sizeof(GLint) * 4, sizeof(GLint) * 2, false, false, false}, + {GL_INT_VEC3, GL_INT, GL_NONE, GL_NONE, GL_BOOL_VEC3, 1, 3, 3, sizeof(GLint), + sizeof(GLint) * 4, sizeof(GLint) * 3, false, false, false}, + {GL_INT_VEC4, GL_INT, GL_NONE, GL_NONE, GL_BOOL_VEC4, 1, 4, 4, sizeof(GLint), + sizeof(GLint) * 4, sizeof(GLint) * 4, false, false, false}, + {GL_SAMPLER_2D, GL_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint), + sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false}, + {GL_SAMPLER_2D_ARRAY, GL_INT, GL_TEXTURE_2D_ARRAY, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint), + sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false}, + {GL_SAMPLER_2D_ARRAY_SHADOW, GL_INT, GL_TEXTURE_2D_ARRAY, GL_NONE, GL_NONE, 1, 1, 1, + sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false}, + {GL_SAMPLER_2D_MULTISAMPLE, GL_INT, GL_TEXTURE_2D_MULTISAMPLE, GL_NONE, GL_NONE, 1, 1, 1, + sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false}, + {GL_SAMPLER_2D_RECT_ANGLE, GL_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint), + sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false}, + {GL_SAMPLER_2D_SHADOW, GL_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint), + sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false}, + {GL_SAMPLER_3D, GL_INT, GL_TEXTURE_3D, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint), + sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false}, + {GL_SAMPLER_CUBE, GL_INT, GL_TEXTURE_CUBE_MAP, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint), + sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false}, + {GL_SAMPLER_CUBE_SHADOW, GL_INT, GL_TEXTURE_CUBE_MAP, GL_NONE, GL_NONE, 1, 1, 1, sizeof(GLint), + sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false}, + {GL_SAMPLER_EXTERNAL_OES, GL_INT, GL_TEXTURE_EXTERNAL_OES, GL_NONE, GL_NONE, 1, 1, 1, + sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false}, + {GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_NONE, GL_NONE, GL_BOOL, 1, 1, 1, sizeof(GLuint), + sizeof(GLuint) * 4, sizeof(GLuint) * 1, false, false, false}, + {GL_UNSIGNED_INT_ATOMIC_COUNTER, GL_UNSIGNED_INT, GL_NONE, GL_NONE, GL_NONE, 1, 1, 1, + sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, false, false, false}, + {GL_UNSIGNED_INT_IMAGE_2D, GL_UNSIGNED_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, 1, 1, 1, + sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, false, false, true}, + {GL_UNSIGNED_INT_IMAGE_2D_ARRAY, GL_UNSIGNED_INT, GL_TEXTURE_2D_ARRAY, GL_NONE, GL_NONE, 1, 1, + 1, sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, false, false, true}, + {GL_UNSIGNED_INT_IMAGE_3D, GL_UNSIGNED_INT, GL_TEXTURE_3D, GL_NONE, GL_NONE, 1, 1, 1, + sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, false, false, true}, + {GL_UNSIGNED_INT_IMAGE_CUBE, GL_UNSIGNED_INT, GL_TEXTURE_CUBE_MAP, GL_NONE, GL_NONE, 1, 1, 1, + sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, false, false, true}, + {GL_UNSIGNED_INT_SAMPLER_2D, GL_UNSIGNED_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, 1, 1, 1, + sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, true, false, false}, + {GL_UNSIGNED_INT_SAMPLER_2D_ARRAY, GL_UNSIGNED_INT, GL_TEXTURE_2D_ARRAY, GL_NONE, GL_NONE, 1, + 1, 1, sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, true, false, false}, + {GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE, GL_UNSIGNED_INT, GL_TEXTURE_2D_MULTISAMPLE, GL_NONE, + GL_NONE, 1, 1, 1, sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, true, false, false}, + {GL_UNSIGNED_INT_SAMPLER_3D, GL_UNSIGNED_INT, GL_TEXTURE_3D, GL_NONE, GL_NONE, 1, 1, 1, + sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, true, false, false}, + {GL_UNSIGNED_INT_SAMPLER_CUBE, GL_UNSIGNED_INT, GL_TEXTURE_CUBE_MAP, GL_NONE, GL_NONE, 1, 1, 1, + sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, true, false, false}, + {GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT, GL_NONE, GL_NONE, GL_BOOL_VEC2, 1, 2, 2, + sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 2, false, false, false}, + {GL_UNSIGNED_INT_VEC3, GL_UNSIGNED_INT, GL_NONE, GL_NONE, GL_BOOL_VEC3, 1, 3, 3, + sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 3, false, false, false}, + {GL_UNSIGNED_INT_VEC4, GL_UNSIGNED_INT, GL_NONE, GL_NONE, GL_BOOL_VEC4, 1, 4, 4, + sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 4, false, false, false}}}; + +size_t GetTypeInfoIndex(GLenum uniformType) +{ + switch (uniformType) + { + case GL_NONE: + return 0; + case GL_BOOL: + return 1; + case GL_BOOL_VEC2: + return 2; + case GL_BOOL_VEC3: + return 3; + case GL_BOOL_VEC4: + return 4; + case GL_FLOAT: + return 5; + case GL_FLOAT_MAT2: + return 6; + case GL_FLOAT_MAT2x3: + return 7; + case GL_FLOAT_MAT2x4: + return 8; + case GL_FLOAT_MAT3: + return 9; + case GL_FLOAT_MAT3x2: + return 10; + case GL_FLOAT_MAT3x4: + return 11; + case GL_FLOAT_MAT4: + return 12; + case GL_FLOAT_MAT4x2: + return 13; + case GL_FLOAT_MAT4x3: + return 14; + case GL_FLOAT_VEC2: + return 15; + case GL_FLOAT_VEC3: + return 16; + case GL_FLOAT_VEC4: + return 17; + case GL_IMAGE_2D: + return 18; + case GL_IMAGE_2D_ARRAY: + return 19; + case GL_IMAGE_3D: + return 20; + case GL_IMAGE_CUBE: + return 21; + case GL_INT: + return 22; + case GL_INT_IMAGE_2D: + return 23; + case GL_INT_IMAGE_2D_ARRAY: + return 24; + case GL_INT_IMAGE_3D: + return 25; + case GL_INT_IMAGE_CUBE: + return 26; + case GL_INT_SAMPLER_2D: + return 27; + case GL_INT_SAMPLER_2D_ARRAY: + return 28; + case GL_INT_SAMPLER_2D_MULTISAMPLE: + return 29; + case GL_INT_SAMPLER_3D: + return 30; + case GL_INT_SAMPLER_CUBE: + return 31; + case GL_INT_VEC2: + return 32; + case GL_INT_VEC3: + return 33; + case GL_INT_VEC4: + return 34; + case GL_SAMPLER_2D: + return 35; + case GL_SAMPLER_2D_ARRAY: + return 36; + case GL_SAMPLER_2D_ARRAY_SHADOW: + return 37; + case GL_SAMPLER_2D_MULTISAMPLE: + return 38; + case GL_SAMPLER_2D_RECT_ANGLE: + return 39; + case GL_SAMPLER_2D_SHADOW: + return 40; + case GL_SAMPLER_3D: + return 41; + case GL_SAMPLER_CUBE: + return 42; + case GL_SAMPLER_CUBE_SHADOW: + return 43; + case GL_SAMPLER_EXTERNAL_OES: + return 44; + case GL_UNSIGNED_INT: + return 45; + case GL_UNSIGNED_INT_ATOMIC_COUNTER: + return 46; + case GL_UNSIGNED_INT_IMAGE_2D: + return 47; + case GL_UNSIGNED_INT_IMAGE_2D_ARRAY: + return 48; + case GL_UNSIGNED_INT_IMAGE_3D: + return 49; + case GL_UNSIGNED_INT_IMAGE_CUBE: + return 50; + case GL_UNSIGNED_INT_SAMPLER_2D: + return 51; + case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: + return 52; + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: + return 53; + case GL_UNSIGNED_INT_SAMPLER_3D: + return 54; + case GL_UNSIGNED_INT_SAMPLER_CUBE: + return 55; + case GL_UNSIGNED_INT_VEC2: + return 56; + case GL_UNSIGNED_INT_VEC3: + return 57; + case GL_UNSIGNED_INT_VEC4: + return 58; + default: + UNREACHABLE(); + return 0; + } +} +} // anonymous namespace + +const UniformTypeInfo &GetUniformTypeInfo(GLenum uniformType) +{ + ASSERT(kInfoTable[GetTypeInfoIndex(uniformType)].type == uniformType); + return kInfoTable[GetTypeInfoIndex(uniformType)]; +} + +} // namespace gl diff --git a/src/3rdparty/angle/src/common/utilities.cpp b/src/3rdparty/angle/src/common/utilities.cpp index 2ab913b10f..6dae9cc51f 100644 --- a/src/3rdparty/angle/src/common/utilities.cpp +++ b/src/3rdparty/angle/src/common/utilities.cpp @@ -124,24 +124,42 @@ GLenum VariableComponentType(GLenum type) return GL_FLOAT; case GL_INT: case GL_SAMPLER_2D: + case GL_SAMPLER_2D_RECT_ANGLE: case GL_SAMPLER_3D: case GL_SAMPLER_CUBE: case GL_SAMPLER_2D_ARRAY: + case GL_SAMPLER_EXTERNAL_OES: + case GL_SAMPLER_2D_MULTISAMPLE: case GL_INT_SAMPLER_2D: case GL_INT_SAMPLER_3D: case GL_INT_SAMPLER_CUBE: case GL_INT_SAMPLER_2D_ARRAY: + case GL_INT_SAMPLER_2D_MULTISAMPLE: case GL_UNSIGNED_INT_SAMPLER_2D: case GL_UNSIGNED_INT_SAMPLER_3D: case GL_UNSIGNED_INT_SAMPLER_CUBE: case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: case GL_SAMPLER_2D_SHADOW: case GL_SAMPLER_CUBE_SHADOW: case GL_SAMPLER_2D_ARRAY_SHADOW: case GL_INT_VEC2: case GL_INT_VEC3: case GL_INT_VEC4: - return GL_INT; + case GL_IMAGE_2D: + case GL_INT_IMAGE_2D: + case GL_UNSIGNED_INT_IMAGE_2D: + case GL_IMAGE_3D: + case GL_INT_IMAGE_3D: + case GL_UNSIGNED_INT_IMAGE_3D: + case GL_IMAGE_2D_ARRAY: + case GL_INT_IMAGE_2D_ARRAY: + case GL_UNSIGNED_INT_IMAGE_2D_ARRAY: + case GL_IMAGE_CUBE: + case GL_INT_IMAGE_CUBE: + case GL_UNSIGNED_INT_IMAGE_CUBE: + case GL_UNSIGNED_INT_ATOMIC_COUNTER: + return GL_INT; case GL_UNSIGNED_INT: case GL_UNSIGNED_INT_VEC2: case GL_UNSIGNED_INT_VEC3: @@ -211,7 +229,6 @@ int VariableRowCount(GLenum type) switch (type) { case GL_NONE: - case GL_STRUCT_ANGLEX: return 0; case GL_BOOL: case GL_FLOAT: @@ -234,19 +251,35 @@ int VariableRowCount(GLenum type) case GL_SAMPLER_CUBE: case GL_SAMPLER_2D_ARRAY: case GL_SAMPLER_EXTERNAL_OES: - case GL_SAMPLER_2D_RECT_ARB: + case GL_SAMPLER_2D_RECT_ANGLE: + case GL_SAMPLER_2D_MULTISAMPLE: case GL_INT_SAMPLER_2D: case GL_INT_SAMPLER_3D: case GL_INT_SAMPLER_CUBE: case GL_INT_SAMPLER_2D_ARRAY: + case GL_INT_SAMPLER_2D_MULTISAMPLE: case GL_UNSIGNED_INT_SAMPLER_2D: case GL_UNSIGNED_INT_SAMPLER_3D: case GL_UNSIGNED_INT_SAMPLER_CUBE: case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: case GL_SAMPLER_2D_SHADOW: case GL_SAMPLER_CUBE_SHADOW: case GL_SAMPLER_2D_ARRAY_SHADOW: - return 1; + case GL_IMAGE_2D: + case GL_INT_IMAGE_2D: + case GL_UNSIGNED_INT_IMAGE_2D: + case GL_IMAGE_2D_ARRAY: + case GL_INT_IMAGE_2D_ARRAY: + case GL_UNSIGNED_INT_IMAGE_2D_ARRAY: + case GL_IMAGE_3D: + case GL_INT_IMAGE_3D: + case GL_UNSIGNED_INT_IMAGE_3D: + case GL_IMAGE_CUBE: + case GL_INT_IMAGE_CUBE: + case GL_UNSIGNED_INT_IMAGE_CUBE: + case GL_UNSIGNED_INT_ATOMIC_COUNTER: + return 1; case GL_FLOAT_MAT2: case GL_FLOAT_MAT3x2: case GL_FLOAT_MAT4x2: @@ -271,7 +304,6 @@ int VariableColumnCount(GLenum type) switch (type) { case GL_NONE: - case GL_STRUCT_ANGLEX: return 0; case GL_BOOL: case GL_FLOAT: @@ -281,20 +313,36 @@ int VariableColumnCount(GLenum type) case GL_SAMPLER_3D: case GL_SAMPLER_CUBE: case GL_SAMPLER_2D_ARRAY: + case GL_SAMPLER_2D_MULTISAMPLE: case GL_INT_SAMPLER_2D: case GL_INT_SAMPLER_3D: case GL_INT_SAMPLER_CUBE: case GL_INT_SAMPLER_2D_ARRAY: + case GL_INT_SAMPLER_2D_MULTISAMPLE: case GL_SAMPLER_EXTERNAL_OES: - case GL_SAMPLER_2D_RECT_ARB: + case GL_SAMPLER_2D_RECT_ANGLE: case GL_UNSIGNED_INT_SAMPLER_2D: case GL_UNSIGNED_INT_SAMPLER_3D: case GL_UNSIGNED_INT_SAMPLER_CUBE: case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: case GL_SAMPLER_2D_SHADOW: case GL_SAMPLER_CUBE_SHADOW: case GL_SAMPLER_2D_ARRAY_SHADOW: - return 1; + case GL_IMAGE_2D: + case GL_INT_IMAGE_2D: + case GL_UNSIGNED_INT_IMAGE_2D: + case GL_IMAGE_3D: + case GL_INT_IMAGE_3D: + case GL_UNSIGNED_INT_IMAGE_3D: + case GL_IMAGE_2D_ARRAY: + case GL_INT_IMAGE_2D_ARRAY: + case GL_UNSIGNED_INT_IMAGE_2D_ARRAY: + case GL_IMAGE_CUBE: + case GL_INT_IMAGE_CUBE: + case GL_UNSIGNED_INT_IMAGE_CUBE: + case GL_UNSIGNED_INT_ATOMIC_COUNTER: + return 1; case GL_BOOL_VEC2: case GL_FLOAT_VEC2: case GL_INT_VEC2: @@ -334,14 +382,19 @@ bool IsSamplerType(GLenum type) case GL_SAMPLER_3D: case GL_SAMPLER_CUBE: case GL_SAMPLER_2D_ARRAY: + case GL_SAMPLER_EXTERNAL_OES: + case GL_SAMPLER_2D_MULTISAMPLE: + case GL_SAMPLER_2D_RECT_ANGLE: case GL_INT_SAMPLER_2D: case GL_INT_SAMPLER_3D: case GL_INT_SAMPLER_CUBE: case GL_INT_SAMPLER_2D_ARRAY: + case GL_INT_SAMPLER_2D_MULTISAMPLE: case GL_UNSIGNED_INT_SAMPLER_2D: case GL_UNSIGNED_INT_SAMPLER_3D: case GL_UNSIGNED_INT_SAMPLER_CUBE: case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: case GL_SAMPLER_2D_SHADOW: case GL_SAMPLER_CUBE_SHADOW: case GL_SAMPLER_2D_ARRAY_SHADOW: @@ -351,6 +404,38 @@ bool IsSamplerType(GLenum type) return false; } +bool IsImageType(GLenum type) +{ + switch (type) + { + case GL_IMAGE_2D: + case GL_INT_IMAGE_2D: + case GL_UNSIGNED_INT_IMAGE_2D: + case GL_IMAGE_3D: + case GL_INT_IMAGE_3D: + case GL_UNSIGNED_INT_IMAGE_3D: + case GL_IMAGE_2D_ARRAY: + case GL_INT_IMAGE_2D_ARRAY: + case GL_UNSIGNED_INT_IMAGE_2D_ARRAY: + case GL_IMAGE_CUBE: + case GL_INT_IMAGE_CUBE: + case GL_UNSIGNED_INT_IMAGE_CUBE: + return true; + } + return false; +} + +bool IsAtomicCounterType(GLenum type) +{ + return type == GL_UNSIGNED_INT_ATOMIC_COUNTER; +} + +bool IsOpaqueType(GLenum type) +{ + // ESSL 3.10 section 4.1.7 defines opaque types as: samplers, images and atomic counters. + return IsImageType(type) || IsSamplerType(type) || IsAtomicCounterType(type); +} + GLenum SamplerTypeToTextureType(GLenum samplerType) { switch (samplerType) @@ -361,6 +446,9 @@ GLenum SamplerTypeToTextureType(GLenum samplerType) case GL_SAMPLER_2D_SHADOW: return GL_TEXTURE_2D; + case GL_SAMPLER_EXTERNAL_OES: + return GL_TEXTURE_EXTERNAL_OES; + case GL_SAMPLER_CUBE: case GL_INT_SAMPLER_CUBE: case GL_UNSIGNED_INT_SAMPLER_CUBE: @@ -378,6 +466,14 @@ GLenum SamplerTypeToTextureType(GLenum samplerType) case GL_UNSIGNED_INT_SAMPLER_3D: return GL_TEXTURE_3D; + case GL_SAMPLER_2D_MULTISAMPLE: + case GL_INT_SAMPLER_2D_MULTISAMPLE: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: + return GL_TEXTURE_2D_MULTISAMPLE; + + case GL_SAMPLER_2D_RECT_ANGLE: + return GL_TEXTURE_RECTANGLE_ANGLE; + default: UNREACHABLE(); return 0; @@ -531,6 +627,21 @@ bool IsTriangleMode(GLenum drawMode) return false; } +bool IsIntegerFormat(GLenum unsizedFormat) +{ + switch (unsizedFormat) + { + case GL_RGBA_INTEGER: + case GL_RGB_INTEGER: + case GL_RG_INTEGER: + case GL_RED_INTEGER: + return true; + + default: + return false; + } +} + // [OpenGL ES SL 3.00.4] Section 11 p. 120 // Vertex Outs/Fragment Ins packing priorities int VariableSortOrder(GLenum type) @@ -586,21 +697,37 @@ int VariableSortOrder(GLenum type) case GL_SAMPLER_2D: case GL_SAMPLER_CUBE: case GL_SAMPLER_EXTERNAL_OES: - case GL_SAMPLER_2D_RECT_ARB: + case GL_SAMPLER_2D_RECT_ANGLE: case GL_SAMPLER_2D_ARRAY: + case GL_SAMPLER_2D_MULTISAMPLE: case GL_SAMPLER_3D: case GL_INT_SAMPLER_2D: case GL_INT_SAMPLER_3D: case GL_INT_SAMPLER_CUBE: case GL_INT_SAMPLER_2D_ARRAY: + case GL_INT_SAMPLER_2D_MULTISAMPLE: case GL_UNSIGNED_INT_SAMPLER_2D: case GL_UNSIGNED_INT_SAMPLER_3D: case GL_UNSIGNED_INT_SAMPLER_CUBE: case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: + case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: case GL_SAMPLER_2D_SHADOW: case GL_SAMPLER_2D_ARRAY_SHADOW: case GL_SAMPLER_CUBE_SHADOW: - return 6; + case GL_IMAGE_2D: + case GL_INT_IMAGE_2D: + case GL_UNSIGNED_INT_IMAGE_2D: + case GL_IMAGE_3D: + case GL_INT_IMAGE_3D: + case GL_UNSIGNED_INT_IMAGE_3D: + case GL_IMAGE_2D_ARRAY: + case GL_INT_IMAGE_2D_ARRAY: + case GL_UNSIGNED_INT_IMAGE_2D_ARRAY: + case GL_IMAGE_CUBE: + case GL_INT_IMAGE_CUBE: + case GL_UNSIGNED_INT_IMAGE_CUBE: + case GL_UNSIGNED_INT_ATOMIC_COUNTER: + return 6; default: UNREACHABLE(); @@ -608,51 +735,128 @@ int VariableSortOrder(GLenum type) } } -std::string ParseUniformName(const std::string &name, size_t *outSubscript) +std::string ParseResourceName(const std::string &name, std::vector *outSubscripts) { - // Strip any trailing array operator and retrieve the subscript - size_t open = name.find_last_of('['); - size_t close = name.find_last_of(']'); - bool hasIndex = (open != std::string::npos) && (close == name.length() - 1); - if (!hasIndex) + if (outSubscripts) { - if (outSubscript) - { - *outSubscript = GL_INVALID_INDEX; - } - return name; + outSubscripts->clear(); } - - if (outSubscript) + // Strip any trailing array indexing operators and retrieve the subscripts. + size_t baseNameLength = name.length(); + bool hasIndex = true; + while (hasIndex) { - int index = atoi(name.substr(open + 1).c_str()); - if (index >= 0) + size_t open = name.find_last_of('[', baseNameLength - 1); + size_t close = name.find_last_of(']', baseNameLength - 1); + hasIndex = (open != std::string::npos) && (close == baseNameLength - 1); + if (hasIndex) { - *outSubscript = index; - } - else - { - *outSubscript = GL_INVALID_INDEX; + baseNameLength = open; + if (outSubscripts) + { + int index = atoi(name.substr(open + 1).c_str()); + if (index >= 0) + { + outSubscripts->push_back(index); + } + else + { + outSubscripts->push_back(GL_INVALID_INDEX); + } + } } } - return name.substr(0, open); + return name.substr(0, baseNameLength); } -unsigned int ParseAndStripArrayIndex(std::string *name) +unsigned int ArraySizeProduct(const std::vector &arraySizes) { - unsigned int subscript = GL_INVALID_INDEX; + unsigned int arraySizeProduct = 1u; + for (unsigned int arraySize : arraySizes) + { + arraySizeProduct *= arraySize; + } + return arraySizeProduct; +} + +unsigned int ParseArrayIndex(const std::string &name, size_t *nameLengthWithoutArrayIndexOut) +{ + ASSERT(nameLengthWithoutArrayIndexOut != nullptr); // Strip any trailing array operator and retrieve the subscript - size_t open = name->find_last_of('['); - size_t close = name->find_last_of(']'); - if (open != std::string::npos && close == name->length() - 1) + size_t open = name.find_last_of('['); + if (open != std::string::npos && name.back() == ']') { - subscript = atoi(name->c_str() + open + 1); - name->erase(open); + bool indexIsValidDecimalNumber = true; + for (size_t i = open + 1; i < name.length() - 1u; ++i) + { + if (!isdigit(name[i])) + { + indexIsValidDecimalNumber = false; + break; + } + } + if (indexIsValidDecimalNumber) + { + errno = 0; // reset global error flag. + unsigned long subscript = + strtoul(name.c_str() + open + 1, /*endptr*/ nullptr, /*radix*/ 10); + + // Check if resulting integer is out-of-range or conversion error. + if ((subscript <= static_cast(UINT_MAX)) && + !(subscript == ULONG_MAX && errno == ERANGE) && !(errno != 0 && subscript == 0)) + { + *nameLengthWithoutArrayIndexOut = open; + return static_cast(subscript); + } + } } - return subscript; + *nameLengthWithoutArrayIndexOut = name.length(); + return GL_INVALID_INDEX; +} + +const char *GetGenericErrorMessage(GLenum error) +{ + switch (error) + { + case GL_NO_ERROR: + return ""; + case GL_INVALID_ENUM: + return "Invalid enum."; + case GL_INVALID_VALUE: + return "Invalid value."; + case GL_INVALID_OPERATION: + return "Invalid operation."; + case GL_STACK_OVERFLOW: + return "Stack overflow."; + case GL_STACK_UNDERFLOW: + return "Stack underflow."; + case GL_OUT_OF_MEMORY: + return "Out of memory."; + case GL_INVALID_FRAMEBUFFER_OPERATION: + return "Invalid framebuffer operation."; + default: + UNREACHABLE(); + return "Unknown error."; + } +} + +unsigned int ElementTypeSize(GLenum elementType) +{ + switch (elementType) + { + case GL_UNSIGNED_BYTE: + return sizeof(GLubyte); + case GL_UNSIGNED_SHORT: + return sizeof(GLushort); + case GL_UNSIGNED_INT: + return sizeof(GLuint); + default: + UNREACHABLE(); + return 0; + } } } // namespace gl @@ -710,8 +914,53 @@ bool IsRenderbufferTarget(EGLenum target) { return target == EGL_GL_RENDERBUFFER_KHR; } + +const char *GetGenericErrorMessage(EGLint error) +{ + switch (error) + { + case EGL_SUCCESS: + return ""; + case EGL_NOT_INITIALIZED: + return "Not initialized."; + case EGL_BAD_ACCESS: + return "Bad access."; + case EGL_BAD_ALLOC: + return "Bad allocation."; + case EGL_BAD_ATTRIBUTE: + return "Bad attribute."; + case EGL_BAD_CONFIG: + return "Bad config."; + case EGL_BAD_CONTEXT: + return "Bad context."; + case EGL_BAD_CURRENT_SURFACE: + return "Bad current surface."; + case EGL_BAD_DISPLAY: + return "Bad display."; + case EGL_BAD_MATCH: + return "Bad match."; + case EGL_BAD_NATIVE_WINDOW: + return "Bad native window."; + case EGL_BAD_PARAMETER: + return "Bad parameter."; + case EGL_BAD_SURFACE: + return "Bad surface."; + case EGL_CONTEXT_LOST: + return "Context lost."; + case EGL_BAD_STREAM_KHR: + return "Bad stream."; + case EGL_BAD_STATE_KHR: + return "Bad state."; + case EGL_BAD_DEVICE_EXT: + return "Bad device."; + default: + UNREACHABLE(); + return "Unknown error."; + } } +} // namespace egl + namespace egl_gl { GLenum EGLCubeMapTargetToGLCubeMapTarget(EGLenum eglTarget) @@ -748,7 +997,26 @@ GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer) { return static_cast(reinterpret_cast(buffer)); } +} // namespace egl_gl + +namespace gl_egl +{ +EGLenum GLComponentTypeToEGLColorComponentType(GLenum glComponentType) +{ + switch (glComponentType) + { + case GL_FLOAT: + return EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT; + + case GL_UNSIGNED_NORMALIZED: + return EGL_COLOR_COMPONENT_TYPE_FIXED_EXT; + + default: + UNREACHABLE(); + return EGL_NONE; + } } +} // namespace gl_egl #if !defined(ANGLE_ENABLE_WINDOWS_STORE) std::string getTempPath() diff --git a/src/3rdparty/angle/src/common/utilities.h b/src/3rdparty/angle/src/common/utilities.h index dc09011a26..f2f9c63d0e 100644 --- a/src/3rdparty/angle/src/common/utilities.h +++ b/src/3rdparty/angle/src/common/utilities.h @@ -12,9 +12,10 @@ #include #include -#include "angle_gl.h" -#include #include +#include +#include +#include "angle_gl.h" #include "common/mathutil.h" @@ -26,10 +27,12 @@ GLenum VariableComponentType(GLenum type); size_t VariableComponentSize(GLenum type); size_t VariableInternalSize(GLenum type); size_t VariableExternalSize(GLenum type); -GLenum VariableBoolVectorType(GLenum type); int VariableRowCount(GLenum type); int VariableColumnCount(GLenum type); bool IsSamplerType(GLenum type); +bool IsImageType(GLenum type); +bool IsAtomicCounterType(GLenum type); +bool IsOpaqueType(GLenum type); GLenum SamplerTypeToTextureType(GLenum samplerType); bool IsMatrixType(GLenum type); GLenum TransposeMatrixType(GLenum type); @@ -37,6 +40,7 @@ int VariableRegisterCount(GLenum type); int MatrixRegisterCount(GLenum type, bool isRowMajorMatrix); int MatrixComponentCount(GLenum type, bool isRowMajorMatrix); int VariableSortOrder(GLenum type); +GLenum VariableBoolVectorType(GLenum type); int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize); @@ -46,9 +50,12 @@ bool IsCubeMapTextureTarget(GLenum target); size_t CubeMapTextureTargetToLayerIndex(GLenum target); GLenum LayerIndexToCubeMapTextureTarget(size_t index); -// Parse the base uniform name and array index. Returns the base name of the uniform. outSubscript is -// set to GL_INVALID_INDEX if the provided name is not an array or the array index is invalid. -std::string ParseUniformName(const std::string &name, size_t *outSubscript); +// Parse the base resource name and array indices. Returns the base name of the resource. +// If the provided name doesn't index an array, the outSubscripts vector will be empty. +// If the provided name indexes an array, the outSubscripts vector will contain indices with +// outermost array indices in the back. If an array index is invalid, GL_INVALID_INDEX is added to +// outSubscripts. +std::string ParseResourceName(const std::string &name, std::vector *outSubscripts); // Find the range of index values in the provided indices pointer. Primitive restart indices are // only counted in the range if primitive restart is disabled. @@ -61,14 +68,71 @@ IndexRange ComputeIndexRange(GLenum indexType, GLuint GetPrimitiveRestartIndex(GLenum indexType); bool IsTriangleMode(GLenum drawMode); +bool IsIntegerFormat(GLenum unsizedFormat); -// [OpenGL ES 3.0.2] Section 2.3.1 page 14 -// Data Conversion For State-Setting Commands -// Floating-point values are rounded to the nearest integer, instead of truncated, as done by static_cast. -template outT iround(GLfloat value) { return static_cast(value > 0.0f ? floor(value + 0.5f) : ceil(value - 0.5f)); } -template outT uiround(GLfloat value) { return static_cast(value + 0.5f); } +// Returns the product of the sizes in the vector, or 1 if the vector is empty. Doesn't currently +// perform overflow checks. +unsigned int ArraySizeProduct(const std::vector &arraySizes); -unsigned int ParseAndStripArrayIndex(std::string *name); +// Return the array index at the end of name, and write the length of name before the final array +// index into nameLengthWithoutArrayIndexOut. In case name doesn't include an array index, return +// GL_INVALID_INDEX and write the length of the original string. +unsigned int ParseArrayIndex(const std::string &name, size_t *nameLengthWithoutArrayIndexOut); + +struct UniformTypeInfo final : angle::NonCopyable +{ + constexpr UniformTypeInfo(GLenum type, + GLenum componentType, + GLenum samplerTextureType, + GLenum transposedMatrixType, + GLenum boolVectorType, + int rowCount, + int columnCount, + int componentCount, + size_t componentSize, + size_t internalSize, + size_t externalSize, + bool isSampler, + bool isMatrixType, + bool isImageType) + : type(type), + componentType(componentType), + samplerTextureType(samplerTextureType), + transposedMatrixType(transposedMatrixType), + boolVectorType(boolVectorType), + rowCount(rowCount), + columnCount(columnCount), + componentCount(componentCount), + componentSize(componentSize), + internalSize(internalSize), + externalSize(externalSize), + isSampler(isSampler), + isMatrixType(isMatrixType), + isImageType(isImageType) + { + } + + GLenum type; + GLenum componentType; + GLenum samplerTextureType; + GLenum transposedMatrixType; + GLenum boolVectorType; + int rowCount; + int columnCount; + int componentCount; + size_t componentSize; + size_t internalSize; + size_t externalSize; + bool isSampler; + bool isMatrixType; + bool isImageType; +}; + +const UniformTypeInfo &GetUniformTypeInfo(GLenum uniformType); + +const char *GetGenericErrorMessage(GLenum error); + +unsigned int ElementTypeSize(GLenum elementType); } // namespace gl @@ -81,7 +145,9 @@ size_t CubeMapTextureTargetToLayerIndex(EGLenum target); EGLenum LayerIndexToCubeMapTextureTarget(size_t index); bool IsTextureTarget(EGLenum target); bool IsRenderbufferTarget(EGLenum target); -} + +const char *GetGenericErrorMessage(EGLint error); +} // namespace egl namespace egl_gl { @@ -90,6 +156,11 @@ GLenum EGLImageTargetToGLTextureTarget(EGLenum eglTarget); GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer); } +namespace gl_egl +{ +EGLenum GLComponentTypeToEGLColorComponentType(GLenum glComponentType); +} // namespace gl_egl + #if !defined(ANGLE_ENABLE_WINDOWS_STORE) std::string getTempPath(); void writeFile(const char* path, const void* data, size_t size); diff --git a/src/3rdparty/angle/src/common/vector_utils.h b/src/3rdparty/angle/src/common/vector_utils.h new file mode 100644 index 0000000000..9f5bee1a4a --- /dev/null +++ b/src/3rdparty/angle/src/common/vector_utils.h @@ -0,0 +1,523 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// vector_utils.h: Utility classes implementing various vector operations + +#ifndef COMMON_VECTOR_UTILS_H_ +#define COMMON_VECTOR_UTILS_H_ + +#include +#include +#include +#include + +namespace angle +{ + +template +class Vector; + +using Vector2 = Vector<2, float>; +using Vector3 = Vector<3, float>; +using Vector4 = Vector<4, float>; + +using Vector2I = Vector<2, int>; +using Vector3I = Vector<3, int>; +using Vector4I = Vector<4, int>; + +using Vector2U = Vector<2, unsigned int>; +using Vector3U = Vector<3, unsigned int>; +using Vector4U = Vector<4, unsigned int>; + +template +class VectorBase +{ + public: + using VectorN = Vector; + + // Constructors + VectorBase() = default; + explicit VectorBase(Type element); + + template + VectorBase(const VectorBase &other); + + template + VectorBase(const Arg1 &arg1, const Arg2 &arg2, const Args &... args); + + // Access the vector backing storage directly + const Type *data() const { return mData; } + Type *data() { return mData; } + constexpr size_t size() const { return Dimension; } + + // Load or store the pointer from / to raw data + static VectorN Load(const Type *source); + static void Store(const VectorN &source, Type *destination); + + // Index the vector + Type &operator[](size_t i) { return mData[i]; } + const Type &operator[](size_t i) const { return mData[i]; } + + // Basic arithmetic operations + VectorN operator+() const; + VectorN operator-() const; + VectorN operator+(const VectorN &other) const; + VectorN operator-(const VectorN &other) const; + VectorN operator*(const VectorN &other) const; + VectorN operator/(const VectorN &other) const; + VectorN operator*(Type other) const; + VectorN operator/(Type other) const; + friend VectorN operator*(Type a, const VectorN &b) { return b * a; } + + // Compound arithmetic operations + VectorN &operator+=(const VectorN &other); + VectorN &operator-=(const VectorN &other); + VectorN &operator*=(const VectorN &other); + VectorN &operator/=(const VectorN &other); + VectorN &operator*=(Type other); + VectorN &operator/=(Type other); + + // Comparison operators + bool operator==(const VectorN &other) const; + bool operator!=(const VectorN &other) const; + + // Other arithmetic operations + Type length() const; + Type lengthSquared() const; + Type dot(const VectorBase &other) const; + VectorN normalized() const; + + protected: + template + void initWithList(const Vector &arg1, const Args &... args); + + // Some old compilers consider this function an alternative for initWithList(Vector) + // when the variant above is more precise. Use SFINAE on the return value to hide + // this variant for non-arithmetic types. The return value is still void. + template + typename std::enable_if::value>::type initWithList( + OtherType arg1, + const Args &... args); + + template + void initWithList() const; + + template + friend class VectorBase; + + Type mData[Dimension]; +}; + +template +std::ostream &operator<<(std::ostream &ostream, const VectorBase &vector); + +template +class Vector<2, Type> : public VectorBase<2, Type> +{ + public: + // Import the constructors defined in VectorBase + using VectorBase<2, Type>::VectorBase; + + // Element shorthands + Type &x() { return this->mData[0]; } + Type &y() { return this->mData[1]; } + + const Type &x() const { return this->mData[0]; } + const Type &y() const { return this->mData[1]; } +}; + +template +std::ostream &operator<<(std::ostream &ostream, const Vector<2, Type> &vector); + +template +class Vector<3, Type> : public VectorBase<3, Type> +{ + public: + // Import the constructors defined in VectorBase + using VectorBase<3, Type>::VectorBase; + + // Additional operations + Vector<3, Type> cross(const Vector<3, Type> &other) const; + + // Element shorthands + Type &x() { return this->mData[0]; } + Type &y() { return this->mData[1]; } + Type &z() { return this->mData[2]; } + + const Type &x() const { return this->mData[0]; } + const Type &y() const { return this->mData[1]; } + const Type &z() const { return this->mData[2]; } +}; + +template +std::ostream &operator<<(std::ostream &ostream, const Vector<3, Type> &vector); + +template +class Vector<4, Type> : public VectorBase<4, Type> +{ + public: + // Import the constructors defined in VectorBase + using VectorBase<4, Type>::VectorBase; + + // Element shorthands + Type &x() { return this->mData[0]; } + Type &y() { return this->mData[1]; } + Type &z() { return this->mData[2]; } + Type &w() { return this->mData[3]; } + + const Type &x() const { return this->mData[0]; } + const Type &y() const { return this->mData[1]; } + const Type &z() const { return this->mData[2]; } + const Type &w() const { return this->mData[3]; } +}; + +template +std::ostream &operator<<(std::ostream &ostream, const Vector<4, Type> &vector); + +// Implementation of constructors and misc operations + +template +VectorBase::VectorBase(Type element) +{ + for (size_t i = 0; i < Dimension; ++i) + { + mData[i] = element; + } +} + +template +template +VectorBase::VectorBase(const VectorBase &other) +{ + for (size_t i = 0; i < Dimension; ++i) + { + mData[i] = static_cast(other.mData[i]); + } +} + +// Ideally we would like to have only two constructors: +// - a scalar constructor that takes Type as a parameter +// - a compound constructor +// However if we define the compound constructor for when it has a single arguments, then calling +// Vector2(0.0) will be ambiguous. To solve this we take advantage of there being a single compound +// constructor with a single argument, which is the copy constructor. We end up with three +// constructors: +// - the scalar constructor +// - the copy constructor +// - the compound constructor for two or more arguments, hence the arg1, and arg2 here. +template +template +VectorBase::VectorBase(const Arg1 &arg1, const Arg2 &arg2, const Args &... args) +{ + initWithList<0>(arg1, arg2, args...); +} + +template +template +void VectorBase::initWithList(const Vector &arg1, + const Args &... args) +{ + static_assert(CurrentIndex + OtherDimension <= Dimension, + "Too much data in the vector constructor."); + for (size_t i = 0; i < OtherDimension; ++i) + { + mData[CurrentIndex + i] = static_cast(arg1.mData[i]); + } + initWithList(args...); +} + +template +template +typename std::enable_if::value>::type +VectorBase::initWithList(OtherType arg1, const Args &... args) +{ + static_assert(CurrentIndex + 1 <= Dimension, "Too much data in the vector constructor."); + mData[CurrentIndex] = static_cast(arg1); + initWithList(args...); +} + +template +template +void VectorBase::initWithList() const +{ + static_assert(CurrentIndex == Dimension, "Not enough data in the vector constructor."); +} + +template +Vector VectorBase::Load(const Type *source) +{ + Vector result; + for (size_t i = 0; i < Dimension; ++i) + { + result.mData[i] = source[i]; + } + return result; +} + +template +void VectorBase::Store(const Vector &source, Type *destination) +{ + for (size_t i = 0; i < Dimension; ++i) + { + destination[i] = source.mData[i]; + } +} + +// Implementation of basic arithmetic operations +template +Vector VectorBase::operator+() const +{ + Vector result; + for (size_t i = 0; i < Dimension; ++i) + { + result.mData[i] = +mData[i]; + } + return result; +} + +template +Vector VectorBase::operator-() const +{ + Vector result; + for (size_t i = 0; i < Dimension; ++i) + { + result.mData[i] = -mData[i]; + } + return result; +} + +template +Vector VectorBase::operator+( + const Vector &other) const +{ + Vector result; + for (size_t i = 0; i < Dimension; ++i) + { + result.mData[i] = mData[i] + other.mData[i]; + } + return result; +} + +template +Vector VectorBase::operator-( + const Vector &other) const +{ + Vector result; + for (size_t i = 0; i < Dimension; ++i) + { + result.mData[i] = mData[i] - other.mData[i]; + } + return result; +} + +template +Vector VectorBase::operator*( + const Vector &other) const +{ + Vector result; + for (size_t i = 0; i < Dimension; ++i) + { + result.mData[i] = mData[i] * other.mData[i]; + } + return result; +} + +template +Vector VectorBase::operator/( + const Vector &other) const +{ + Vector result; + for (size_t i = 0; i < Dimension; ++i) + { + result.mData[i] = mData[i] / other.mData[i]; + } + return result; +} + +template +Vector VectorBase::operator*(Type other) const +{ + Vector result; + for (size_t i = 0; i < Dimension; ++i) + { + result.mData[i] = mData[i] * other; + } + return result; +} + +template +Vector VectorBase::operator/(Type other) const +{ + Vector result; + for (size_t i = 0; i < Dimension; ++i) + { + result.mData[i] = mData[i] / other; + } + return result; +} + +// Implementation of compound arithmetic operations +template +Vector &VectorBase::operator+=( + const Vector &other) +{ + for (size_t i = 0; i < Dimension; ++i) + { + mData[i] += other.mData[i]; + } + return *reinterpret_cast *>(this); +} + +template +Vector &VectorBase::operator-=( + const Vector &other) +{ + for (size_t i = 0; i < Dimension; ++i) + { + mData[i] -= other.mData[i]; + } + return *reinterpret_cast *>(this); +} + +template +Vector &VectorBase::operator*=( + const Vector &other) +{ + for (size_t i = 0; i < Dimension; ++i) + { + mData[i] *= other.mData[i]; + } + return *reinterpret_cast *>(this); +} + +template +Vector &VectorBase::operator/=( + const Vector &other) +{ + for (size_t i = 0; i < Dimension; ++i) + { + mData[i] /= other.mData[i]; + } + return *reinterpret_cast *>(this); +} + +template +Vector &VectorBase::operator*=(Type other) +{ + for (size_t i = 0; i < Dimension; ++i) + { + mData[i] *= other; + } + return *reinterpret_cast *>(this); +} + +template +Vector &VectorBase::operator/=(Type other) +{ + for (size_t i = 0; i < Dimension; ++i) + { + mData[i] /= other; + } + return *reinterpret_cast *>(this); +} + +// Implementation of comparison operators +template +bool VectorBase::operator==(const Vector &other) const +{ + for (size_t i = 0; i < Dimension; ++i) + { + if (mData[i] != other.mData[i]) + { + return false; + } + } + return true; +} + +template +bool VectorBase::operator!=(const Vector &other) const +{ + return !(*this == other); +} + +// Implementation of other arithmetic operations +template +Type VectorBase::length() const +{ + static_assert(std::is_floating_point::value, + "VectorN::length is only defined for floating point vectors"); + return std::sqrt(lengthSquared()); +} + +template +Type VectorBase::lengthSquared() const +{ + return dot(*this); +} + +template +Type VectorBase::dot(const VectorBase &other) const +{ + Type sum = Type(); + for (size_t i = 0; i < Dimension; ++i) + { + sum += mData[i] * other.mData[i]; + } + return sum; +} + +template +std::ostream &operator<<(std::ostream &ostream, const VectorBase &vector) +{ + ostream << "[ "; + for (size_t elementIdx = 0; elementIdx < Dimension; elementIdx++) + { + if (elementIdx > 0) + { + ostream << ", "; + } + ostream << vector.data()[elementIdx]; + } + ostream << " ]"; + return ostream; +} + +template +Vector VectorBase::normalized() const +{ + static_assert(std::is_floating_point::value, + "VectorN::normalized is only defined for floating point vectors"); + return *this / length(); +} + +template +std::ostream &operator<<(std::ostream &ostream, const Vector<2, Type> &vector) +{ + return ostream << static_cast &>(vector); +} + +template +Vector<3, Type> Vector<3, Type>::cross(const Vector<3, Type> &other) const +{ + return Vector<3, Type>(y() * other.z() - z() * other.y(), z() * other.x() - x() * other.z(), + x() * other.y() - y() * other.x()); +} + +template +std::ostream &operator<<(std::ostream &ostream, const Vector<3, Type> &vector) +{ + return ostream << static_cast &>(vector); +} + +template +std::ostream &operator<<(std::ostream &ostream, const Vector<4, Type> &vector) +{ + return ostream << static_cast &>(vector); +} + +} // namespace angle + +#endif // COMMON_VECTOR_UTILS_H_ diff --git a/src/3rdparty/angle/src/compiler/fuzz/translator_fuzzer.cpp b/src/3rdparty/angle/src/compiler/fuzz/translator_fuzzer.cpp new file mode 100644 index 0000000000..910af8be6f --- /dev/null +++ b/src/3rdparty/angle/src/compiler/fuzz/translator_fuzzer.cpp @@ -0,0 +1,179 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// translator_fuzzer.cpp: A libfuzzer fuzzer for the shader translator. + +#include +#include +#include +#include +#include + +#include "angle_gl.h" +#include "compiler/translator/Compiler.h" +#include "compiler/translator/util.h" + +using namespace sh; + +struct TranslatorCacheKey +{ + bool operator==(const TranslatorCacheKey &other) const + { + return type == other.type && spec == other.spec && output == other.output; + } + + uint32_t type = 0; + uint32_t spec = 0; + uint32_t output = 0; +}; + +namespace std +{ + +template <> +struct hash +{ + std::size_t operator()(const TranslatorCacheKey &k) const + { + return (hash()(k.type) << 1) ^ (hash()(k.spec) >> 1) ^ + hash()(k.output); + } +}; +} // namespace std + +struct TCompilerDeleter +{ + void operator()(TCompiler *compiler) const { DeleteCompiler(compiler); } +}; + +using UniqueTCompiler = std::unique_ptr; + +static std::unordered_map translators; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + // Reserve some size for future compile options + const size_t kHeaderSize = 128; + + if (size <= kHeaderSize) + { + return 0; + } + + // Make sure the rest of data will be a valid C string so that we don't have to copy it. + if (data[size - 1] != 0) + { + return 0; + } + + uint32_t type = *reinterpret_cast(data); + uint32_t spec = *reinterpret_cast(data + 4); + uint32_t output = *reinterpret_cast(data + 8); + uint64_t options = *reinterpret_cast(data + 12); + + if (type != GL_FRAGMENT_SHADER && type != GL_VERTEX_SHADER) + { + return 0; + } + + if (spec != SH_GLES2_SPEC && type != SH_WEBGL_SPEC && spec != SH_GLES3_SPEC && + spec != SH_WEBGL2_SPEC) + { + return 0; + } + + ShShaderOutput shaderOutput = static_cast(output); + if (!(IsOutputGLSL(shaderOutput) || IsOutputESSL(shaderOutput)) && + (options & SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER) != 0u) + { + // This compiler option is only available in ESSL and GLSL. + return 0; + } + + std::vector validOutputs; + validOutputs.push_back(SH_ESSL_OUTPUT); + validOutputs.push_back(SH_GLSL_COMPATIBILITY_OUTPUT); + validOutputs.push_back(SH_GLSL_130_OUTPUT); + validOutputs.push_back(SH_GLSL_140_OUTPUT); + validOutputs.push_back(SH_GLSL_150_CORE_OUTPUT); + validOutputs.push_back(SH_GLSL_330_CORE_OUTPUT); + validOutputs.push_back(SH_GLSL_400_CORE_OUTPUT); + validOutputs.push_back(SH_GLSL_410_CORE_OUTPUT); + validOutputs.push_back(SH_GLSL_420_CORE_OUTPUT); + validOutputs.push_back(SH_GLSL_430_CORE_OUTPUT); + validOutputs.push_back(SH_GLSL_440_CORE_OUTPUT); + validOutputs.push_back(SH_GLSL_450_CORE_OUTPUT); + validOutputs.push_back(SH_HLSL_3_0_OUTPUT); + validOutputs.push_back(SH_HLSL_4_1_OUTPUT); + validOutputs.push_back(SH_HLSL_4_0_FL9_3_OUTPUT); + bool found = false; + for (auto valid : validOutputs) + { + found = found || (valid == output); + } + if (!found) + { + return 0; + } + + size -= kHeaderSize; + data += kHeaderSize; + + if (!sh::Initialize()) + { + return 0; + } + + TranslatorCacheKey key; + key.type = type; + key.spec = spec; + key.output = output; + + if (translators.find(key) == translators.end()) + { + UniqueTCompiler translator( + ConstructCompiler(type, static_cast(spec), shaderOutput)); + + if (translator == nullptr) + { + return 0; + } + + ShBuiltInResources resources; + sh::InitBuiltInResources(&resources); + + // Enable all the extensions to have more coverage + resources.OES_standard_derivatives = 1; + resources.OES_EGL_image_external = 1; + resources.OES_EGL_image_external_essl3 = 1; + resources.NV_EGL_stream_consumer_external = 1; + resources.ARB_texture_rectangle = 1; + resources.EXT_blend_func_extended = 1; + resources.EXT_draw_buffers = 1; + resources.EXT_frag_depth = 1; + resources.EXT_shader_texture_lod = 1; + resources.WEBGL_debug_shader_precision = 1; + resources.EXT_shader_framebuffer_fetch = 1; + resources.NV_shader_framebuffer_fetch = 1; + resources.ARM_shader_framebuffer_fetch = 1; + resources.EXT_YUV_target = 1; + resources.MaxDualSourceDrawBuffers = 1; + + if (!translator->Init(resources)) + { + return 0; + } + + translators[key] = std::move(translator); + } + + auto &translator = translators[key]; + + const char *shaderStrings[] = {reinterpret_cast(data)}; + translator->compile(shaderStrings, 1, options); + + return 0; +} diff --git a/src/3rdparty/angle/src/compiler/preprocessor/DiagnosticsBase.cpp b/src/3rdparty/angle/src/compiler/preprocessor/DiagnosticsBase.cpp index 68c6e9cea4..c89bc9fa76 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/DiagnosticsBase.cpp +++ b/src/3rdparty/angle/src/compiler/preprocessor/DiagnosticsBase.cpp @@ -4,9 +4,9 @@ // found in the LICENSE file. // -#include "DiagnosticsBase.h" +#include "compiler/preprocessor/DiagnosticsBase.h" -#include +#include "common/debug.h" namespace pp { @@ -15,122 +15,128 @@ Diagnostics::~Diagnostics() { } -void Diagnostics::report(ID id, - const SourceLocation &loc, - const std::string &text) +void Diagnostics::report(ID id, const SourceLocation &loc, const std::string &text) { - // TODO(alokp): Keep a count of errors and warnings. print(id, loc, text); } -Diagnostics::Severity Diagnostics::severity(ID id) +bool Diagnostics::isError(ID id) { if ((id > PP_ERROR_BEGIN) && (id < PP_ERROR_END)) - return PP_ERROR; + return true; if ((id > PP_WARNING_BEGIN) && (id < PP_WARNING_END)) - return PP_WARNING; + return false; - assert(false); - return PP_ERROR; + UNREACHABLE(); + return true; } -std::string Diagnostics::message(ID id) +const char *Diagnostics::message(ID id) { switch (id) { - // Errors begin. - case PP_INTERNAL_ERROR: - return "internal error"; - case PP_OUT_OF_MEMORY: - return "out of memory"; - case PP_INVALID_CHARACTER: - return "invalid character"; - case PP_INVALID_NUMBER: - return "invalid number"; - case PP_INTEGER_OVERFLOW: - return "integer overflow"; - case PP_FLOAT_OVERFLOW: - return "float overflow"; - case PP_TOKEN_TOO_LONG: - return "token too long"; - case PP_INVALID_EXPRESSION: - return "invalid expression"; - case PP_DIVISION_BY_ZERO: - return "division by zero"; - case PP_EOF_IN_COMMENT: - return "unexpected end of file found in comment"; - case PP_UNEXPECTED_TOKEN: - return "unexpected token"; - case PP_DIRECTIVE_INVALID_NAME: - return "invalid directive name"; - case PP_MACRO_NAME_RESERVED: - return "macro name is reserved"; - case PP_MACRO_REDEFINED: - return "macro redefined"; - case PP_MACRO_PREDEFINED_REDEFINED: - return "predefined macro redefined"; - case PP_MACRO_PREDEFINED_UNDEFINED: - return "predefined macro undefined"; - case PP_MACRO_UNTERMINATED_INVOCATION: - return "unterminated macro invocation"; - case PP_MACRO_TOO_FEW_ARGS: - return "Not enough arguments for macro"; - case PP_MACRO_TOO_MANY_ARGS: - return "Too many arguments for macro"; - case PP_MACRO_DUPLICATE_PARAMETER_NAMES: - return "duplicate macro parameter name"; - case PP_CONDITIONAL_ENDIF_WITHOUT_IF: - return "unexpected #endif found without a matching #if"; - case PP_CONDITIONAL_ELSE_WITHOUT_IF: - return "unexpected #else found without a matching #if"; - case PP_CONDITIONAL_ELSE_AFTER_ELSE: - return "unexpected #else found after another #else"; - case PP_CONDITIONAL_ELIF_WITHOUT_IF: - return "unexpected #elif found without a matching #if"; - case PP_CONDITIONAL_ELIF_AFTER_ELSE: - return "unexpected #elif found after #else"; - case PP_CONDITIONAL_UNTERMINATED: - return "unexpected end of file found in conditional block"; - case PP_INVALID_EXTENSION_NAME: - return "invalid extension name"; - case PP_INVALID_EXTENSION_BEHAVIOR: - return "invalid extension behavior"; - case PP_INVALID_EXTENSION_DIRECTIVE: - return "invalid extension directive"; - case PP_INVALID_VERSION_NUMBER: - return "invalid version number"; - case PP_INVALID_VERSION_DIRECTIVE: - return "invalid version directive"; - case PP_VERSION_NOT_FIRST_STATEMENT: - return "#version directive must occur before anything else, " - "except for comments and white space"; - case PP_VERSION_NOT_FIRST_LINE_ESSL3: - return "#version directive must occur on the first line of the shader"; - case PP_INVALID_LINE_NUMBER: - return "invalid line number"; - case PP_INVALID_FILE_NUMBER: - return "invalid file number"; - case PP_INVALID_LINE_DIRECTIVE: - return "invalid line directive"; - case PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL3: - return "extension directive must occur before any non-preprocessor tokens in ESSL3"; - // Errors end. - // Warnings begin. - case PP_EOF_IN_DIRECTIVE: - return "unexpected end of file found in directive"; - case PP_CONDITIONAL_UNEXPECTED_TOKEN: - return "unexpected token after conditional expression"; - case PP_UNRECOGNIZED_PRAGMA: - return "unrecognized pragma"; - case PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL1: - return "extension directive should occur before any non-preprocessor tokens"; - case PP_WARNING_MACRO_NAME_RESERVED: - return "macro name with a double underscore is reserved - unintented behavior is possible"; - // Warnings end. - default: - assert(false); - return ""; + // Errors begin. + case PP_INTERNAL_ERROR: + return "internal error"; + case PP_OUT_OF_MEMORY: + return "out of memory"; + case PP_INVALID_CHARACTER: + return "invalid character"; + case PP_INVALID_NUMBER: + return "invalid number"; + case PP_INTEGER_OVERFLOW: + return "integer overflow"; + case PP_FLOAT_OVERFLOW: + return "float overflow"; + case PP_TOKEN_TOO_LONG: + return "token too long"; + case PP_INVALID_EXPRESSION: + return "invalid expression"; + case PP_DIVISION_BY_ZERO: + return "division by zero"; + case PP_EOF_IN_COMMENT: + return "unexpected end of file found in comment"; + case PP_UNEXPECTED_TOKEN: + return "unexpected token"; + case PP_DIRECTIVE_INVALID_NAME: + return "invalid directive name"; + case PP_MACRO_NAME_RESERVED: + return "macro name is reserved"; + case PP_MACRO_REDEFINED: + return "macro redefined"; + case PP_MACRO_PREDEFINED_REDEFINED: + return "predefined macro redefined"; + case PP_MACRO_PREDEFINED_UNDEFINED: + return "predefined macro undefined"; + case PP_MACRO_UNTERMINATED_INVOCATION: + return "unterminated macro invocation"; + case PP_MACRO_UNDEFINED_WHILE_INVOKED: + return "macro undefined while being invoked"; + case PP_MACRO_TOO_FEW_ARGS: + return "Not enough arguments for macro"; + case PP_MACRO_TOO_MANY_ARGS: + return "Too many arguments for macro"; + case PP_MACRO_DUPLICATE_PARAMETER_NAMES: + return "duplicate macro parameter name"; + case PP_MACRO_INVOCATION_CHAIN_TOO_DEEP: + return "macro invocation chain too deep"; + case PP_CONDITIONAL_ENDIF_WITHOUT_IF: + return "unexpected #endif found without a matching #if"; + case PP_CONDITIONAL_ELSE_WITHOUT_IF: + return "unexpected #else found without a matching #if"; + case PP_CONDITIONAL_ELSE_AFTER_ELSE: + return "unexpected #else found after another #else"; + case PP_CONDITIONAL_ELIF_WITHOUT_IF: + return "unexpected #elif found without a matching #if"; + case PP_CONDITIONAL_ELIF_AFTER_ELSE: + return "unexpected #elif found after #else"; + case PP_CONDITIONAL_UNTERMINATED: + return "unexpected end of file found in conditional block"; + case PP_INVALID_EXTENSION_NAME: + return "invalid extension name"; + case PP_INVALID_EXTENSION_BEHAVIOR: + return "invalid extension behavior"; + case PP_INVALID_EXTENSION_DIRECTIVE: + return "invalid extension directive"; + case PP_INVALID_VERSION_NUMBER: + return "invalid version number"; + case PP_INVALID_VERSION_DIRECTIVE: + return "invalid version directive"; + case PP_VERSION_NOT_FIRST_STATEMENT: + return "#version directive must occur before anything else, " + "except for comments and white space"; + case PP_VERSION_NOT_FIRST_LINE_ESSL3: + return "#version directive must occur on the first line of the shader"; + case PP_INVALID_LINE_NUMBER: + return "invalid line number"; + case PP_INVALID_FILE_NUMBER: + return "invalid file number"; + case PP_INVALID_LINE_DIRECTIVE: + return "invalid line directive"; + case PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL3: + return "extension directive must occur before any non-preprocessor tokens in ESSL3"; + case PP_UNDEFINED_SHIFT: + return "shift exponent is negative or undefined"; + case PP_TOKENIZER_ERROR: + return "internal tokenizer error"; + // Errors end. + // Warnings begin. + case PP_EOF_IN_DIRECTIVE: + return "unexpected end of file found in directive"; + case PP_CONDITIONAL_UNEXPECTED_TOKEN: + return "unexpected token after conditional expression"; + case PP_UNRECOGNIZED_PRAGMA: + return "unrecognized pragma"; + case PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL1: + return "extension directive should occur before any non-preprocessor tokens"; + case PP_WARNING_MACRO_NAME_RESERVED: + return "macro name with a double underscore is reserved - unintented behavior is " + "possible"; + // Warnings end. + default: + UNREACHABLE(); + return ""; } } diff --git a/src/3rdparty/angle/src/compiler/preprocessor/DiagnosticsBase.h b/src/3rdparty/angle/src/compiler/preprocessor/DiagnosticsBase.h index d26c174f01..ea37614606 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/DiagnosticsBase.h +++ b/src/3rdparty/angle/src/compiler/preprocessor/DiagnosticsBase.h @@ -19,11 +19,6 @@ struct SourceLocation; class Diagnostics { public: - enum Severity - { - PP_ERROR, - PP_WARNING - }; enum ID { PP_ERROR_BEGIN, @@ -44,9 +39,11 @@ class Diagnostics PP_MACRO_PREDEFINED_REDEFINED, PP_MACRO_PREDEFINED_UNDEFINED, PP_MACRO_UNTERMINATED_INVOCATION, + PP_MACRO_UNDEFINED_WHILE_INVOKED, PP_MACRO_TOO_FEW_ARGS, PP_MACRO_TOO_MANY_ARGS, PP_MACRO_DUPLICATE_PARAMETER_NAMES, + PP_MACRO_INVOCATION_CHAIN_TOO_DEEP, PP_CONDITIONAL_ENDIF_WITHOUT_IF, PP_CONDITIONAL_ELSE_WITHOUT_IF, PP_CONDITIONAL_ELSE_AFTER_ELSE, @@ -65,6 +62,8 @@ class Diagnostics PP_INVALID_FILE_NUMBER, PP_INVALID_LINE_DIRECTIVE, PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL3, + PP_UNDEFINED_SHIFT, + PP_TOKENIZER_ERROR, PP_ERROR_END, PP_WARNING_BEGIN, @@ -80,12 +79,10 @@ class Diagnostics void report(ID id, const SourceLocation &loc, const std::string &text); protected: - Severity severity(ID id); - std::string message(ID id); + bool isError(ID id); + const char *message(ID id); - virtual void print(ID id, - const SourceLocation &loc, - const std::string &text) = 0; + virtual void print(ID id, const SourceLocation &loc, const std::string &text) = 0; }; } // namespace pp diff --git a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.cpp b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.cpp index ef35c6ed50..049dae9071 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.cpp +++ b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.cpp @@ -4,7 +4,7 @@ // found in the LICENSE file. // -#include "DirectiveHandlerBase.h" +#include "compiler/preprocessor/DirectiveHandlerBase.h" namespace pp { diff --git a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h index cf67895764..6c81d015f5 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h +++ b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h @@ -23,8 +23,7 @@ class DirectiveHandler public: virtual ~DirectiveHandler(); - virtual void handleError(const SourceLocation &loc, - const std::string &msg) = 0; + virtual void handleError(const SourceLocation &loc, const std::string &msg) = 0; // Handle pragma of form: #pragma name[(value)] virtual void handlePragma(const SourceLocation &loc, @@ -36,8 +35,7 @@ class DirectiveHandler const std::string &name, const std::string &behavior) = 0; - virtual void handleVersion(const SourceLocation &loc, - int version) = 0; + virtual void handleVersion(const SourceLocation &loc, int version) = 0; }; } // namespace pp diff --git a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp index 2faa331378..f6c5763990 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp +++ b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp @@ -4,21 +4,22 @@ // found in the LICENSE file. // -#include "DirectiveParser.h" +#include "compiler/preprocessor/DirectiveParser.h" #include -#include #include #include -#include "DiagnosticsBase.h" -#include "DirectiveHandlerBase.h" -#include "ExpressionParser.h" -#include "MacroExpander.h" -#include "Token.h" -#include "Tokenizer.h" +#include "common/debug.h" +#include "compiler/preprocessor/DiagnosticsBase.h" +#include "compiler/preprocessor/DirectiveHandlerBase.h" +#include "compiler/preprocessor/ExpressionParser.h" +#include "compiler/preprocessor/MacroExpander.h" +#include "compiler/preprocessor/Token.h" +#include "compiler/preprocessor/Tokenizer.h" -namespace { +namespace +{ enum DirectiveType { DIRECTIVE_NONE, @@ -39,19 +40,19 @@ enum DirectiveType DirectiveType getDirective(const pp::Token *token) { - const char kDirectiveDefine[] = "define"; - const char kDirectiveUndef[] = "undef"; - const char kDirectiveIf[] = "if"; - const char kDirectiveIfdef[] = "ifdef"; - const char kDirectiveIfndef[] = "ifndef"; - const char kDirectiveElse[] = "else"; - const char kDirectiveElif[] = "elif"; - const char kDirectiveEndif[] = "endif"; - const char kDirectiveError[] = "error"; - const char kDirectivePragma[] = "pragma"; + const char kDirectiveDefine[] = "define"; + const char kDirectiveUndef[] = "undef"; + const char kDirectiveIf[] = "if"; + const char kDirectiveIfdef[] = "ifdef"; + const char kDirectiveIfndef[] = "ifndef"; + const char kDirectiveElse[] = "else"; + const char kDirectiveElif[] = "elif"; + const char kDirectiveEndif[] = "endif"; + const char kDirectiveError[] = "error"; + const char kDirectivePragma[] = "pragma"; const char kDirectiveExtension[] = "extension"; - const char kDirectiveVersion[] = "version"; - const char kDirectiveLine[] = "line"; + const char kDirectiveVersion[] = "version"; + const char kDirectiveLine[] = "line"; if (token->type != pp::Token::IDENTIFIER) return DIRECTIVE_NONE; @@ -90,15 +91,15 @@ bool isConditionalDirective(DirectiveType directive) { switch (directive) { - case DIRECTIVE_IF: - case DIRECTIVE_IFDEF: - case DIRECTIVE_IFNDEF: - case DIRECTIVE_ELSE: - case DIRECTIVE_ELIF: - case DIRECTIVE_ENDIF: - return true; - default: - return false; + case DIRECTIVE_IF: + case DIRECTIVE_IFDEF: + case DIRECTIVE_IFNDEF: + case DIRECTIVE_ELSE: + case DIRECTIVE_ELIF: + case DIRECTIVE_ENDIF: + return true; + default: + return false; } } @@ -110,7 +111,7 @@ bool isEOD(const pp::Token *token) void skipUntilEOD(pp::Lexer *lexer, pp::Token *token) { - while(!isEOD(token)) + while (!isEOD(token)) { lexer->lex(token); } @@ -118,8 +119,8 @@ void skipUntilEOD(pp::Lexer *lexer, pp::Token *token) bool isMacroNameReserved(const std::string &name) { - // Names prefixed with "GL_" are reserved. - return (name.substr(0, 3) == "GL_"); + // Names prefixed with "GL_" and the name "defined" are reserved. + return name == "defined" || (name.substr(0, 3) == "GL_"); } bool hasDoubleUnderscores(const std::string &name) @@ -127,11 +128,10 @@ bool hasDoubleUnderscores(const std::string &name) return (name.find("__") != std::string::npos); } -bool isMacroPredefined(const std::string &name, - const pp::MacroSet ¯oSet) +bool isMacroPredefined(const std::string &name, const pp::MacroSet ¯oSet) { pp::MacroSet::const_iterator iter = macroSet.find(name); - return iter != macroSet.end() ? iter->second.predefined : false; + return iter != macroSet.end() ? iter->second->predefined : false; } } // namespace anonymous @@ -139,17 +139,83 @@ bool isMacroPredefined(const std::string &name, namespace pp { +class DefinedParser : public Lexer +{ + public: + DefinedParser(Lexer *lexer, const MacroSet *macroSet, Diagnostics *diagnostics) + : mLexer(lexer), mMacroSet(macroSet), mDiagnostics(diagnostics) + { + } + + protected: + void lex(Token *token) override + { + const char kDefined[] = "defined"; + + mLexer->lex(token); + if (token->type != Token::IDENTIFIER) + return; + if (token->text != kDefined) + return; + + bool paren = false; + mLexer->lex(token); + if (token->type == '(') + { + paren = true; + mLexer->lex(token); + } + + if (token->type != Token::IDENTIFIER) + { + mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); + skipUntilEOD(mLexer, token); + return; + } + MacroSet::const_iterator iter = mMacroSet->find(token->text); + std::string expression = iter != mMacroSet->end() ? "1" : "0"; + + if (paren) + { + mLexer->lex(token); + if (token->type != ')') + { + mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, + token->text); + skipUntilEOD(mLexer, token); + return; + } + } + + // We have a valid defined operator. + // Convert the current token into a CONST_INT token. + token->type = Token::CONST_INT; + token->text = expression; + } + + private: + Lexer *mLexer; + const MacroSet *mMacroSet; + Diagnostics *mDiagnostics; +}; + DirectiveParser::DirectiveParser(Tokenizer *tokenizer, MacroSet *macroSet, Diagnostics *diagnostics, - DirectiveHandler *directiveHandler) + DirectiveHandler *directiveHandler, + int maxMacroExpansionDepth) : mPastFirstStatement(false), mSeenNonPreprocessorToken(false), mTokenizer(tokenizer), mMacroSet(macroSet), mDiagnostics(diagnostics), mDirectiveHandler(directiveHandler), - mShaderVersion(100) + mShaderVersion(100), + mMaxMacroExpansionDepth(maxMacroExpansionDepth) +{ +} + +DirectiveParser::~DirectiveParser() { } @@ -174,21 +240,20 @@ void DirectiveParser::lex(Token *token) if (!mConditionalStack.empty()) { const ConditionalBlock &block = mConditionalStack.back(); - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNTERMINATED, - block.location, block.type); + mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNTERMINATED, block.location, + block.type); } break; } - } - while (skipping() || (token->type == '\n')); + } while (skipping() || (token->type == '\n')); mPastFirstStatement = true; } void DirectiveParser::parseDirective(Token *token) { - assert(token->type == Token::PP_HASH); + ASSERT(token->type == Token::PP_HASH); mTokenizer->lex(token); if (isEOD(token)) @@ -207,86 +272,83 @@ void DirectiveParser::parseDirective(Token *token) return; } - switch(directive) + switch (directive) { - case DIRECTIVE_NONE: - mDiagnostics->report(Diagnostics::PP_DIRECTIVE_INVALID_NAME, - token->location, token->text); - skipUntilEOD(mTokenizer, token); - break; - case DIRECTIVE_DEFINE: - parseDefine(token); - break; - case DIRECTIVE_UNDEF: - parseUndef(token); - break; - case DIRECTIVE_IF: - parseIf(token); - break; - case DIRECTIVE_IFDEF: - parseIfdef(token); - break; - case DIRECTIVE_IFNDEF: - parseIfndef(token); - break; - case DIRECTIVE_ELSE: - parseElse(token); - break; - case DIRECTIVE_ELIF: - parseElif(token); - break; - case DIRECTIVE_ENDIF: - parseEndif(token); - break; - case DIRECTIVE_ERROR: - parseError(token); - break; - case DIRECTIVE_PRAGMA: - parsePragma(token); - break; - case DIRECTIVE_EXTENSION: - parseExtension(token); - break; - case DIRECTIVE_VERSION: - parseVersion(token); - break; - case DIRECTIVE_LINE: - parseLine(token); - break; - default: - assert(false); - break; + case DIRECTIVE_NONE: + mDiagnostics->report(Diagnostics::PP_DIRECTIVE_INVALID_NAME, token->location, + token->text); + skipUntilEOD(mTokenizer, token); + break; + case DIRECTIVE_DEFINE: + parseDefine(token); + break; + case DIRECTIVE_UNDEF: + parseUndef(token); + break; + case DIRECTIVE_IF: + parseIf(token); + break; + case DIRECTIVE_IFDEF: + parseIfdef(token); + break; + case DIRECTIVE_IFNDEF: + parseIfndef(token); + break; + case DIRECTIVE_ELSE: + parseElse(token); + break; + case DIRECTIVE_ELIF: + parseElif(token); + break; + case DIRECTIVE_ENDIF: + parseEndif(token); + break; + case DIRECTIVE_ERROR: + parseError(token); + break; + case DIRECTIVE_PRAGMA: + parsePragma(token); + break; + case DIRECTIVE_EXTENSION: + parseExtension(token); + break; + case DIRECTIVE_VERSION: + parseVersion(token); + break; + case DIRECTIVE_LINE: + parseLine(token); + break; + default: + UNREACHABLE(); + break; } skipUntilEOD(mTokenizer, token); if (token->type == Token::LAST) { - mDiagnostics->report(Diagnostics::PP_EOF_IN_DIRECTIVE, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_EOF_IN_DIRECTIVE, token->location, token->text); } } void DirectiveParser::parseDefine(Token *token) { - assert(getDirective(token) == DIRECTIVE_DEFINE); + ASSERT(getDirective(token) == DIRECTIVE_DEFINE); mTokenizer->lex(token); if (token->type != Token::IDENTIFIER) { - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); return; } if (isMacroPredefined(token->text, *mMacroSet)) { - mDiagnostics->report(Diagnostics::PP_MACRO_PREDEFINED_REDEFINED, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_MACRO_PREDEFINED_REDEFINED, token->location, + token->text); return; } if (isMacroNameReserved(token->text)) { - mDiagnostics->report(Diagnostics::PP_MACRO_NAME_RESERVED, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_MACRO_NAME_RESERVED, token->location, token->text); return; } // Using double underscores is allowed, but may result in unintended @@ -300,39 +362,37 @@ void DirectiveParser::parseDefine(Token *token) token->text); } - Macro macro; - macro.type = Macro::kTypeObj; - macro.name = token->text; + std::shared_ptr macro = std::make_shared(); + macro->type = Macro::kTypeObj; + macro->name = token->text; mTokenizer->lex(token); if (token->type == '(' && !token->hasLeadingSpace()) { // Function-like macro. Collect arguments. - macro.type = Macro::kTypeFunc; + macro->type = Macro::kTypeFunc; do { mTokenizer->lex(token); if (token->type != Token::IDENTIFIER) break; - if (std::find(macro.parameters.begin(), macro.parameters.end(), token->text) != macro.parameters.end()) + if (std::find(macro->parameters.begin(), macro->parameters.end(), token->text) != + macro->parameters.end()) { mDiagnostics->report(Diagnostics::PP_MACRO_DUPLICATE_PARAMETER_NAMES, token->location, token->text); return; } - macro.parameters.push_back(token->text); + macro->parameters.push_back(token->text); mTokenizer->lex(token); // Get ','. - } - while (token->type == ','); + } while (token->type == ','); if (token->type != ')') { - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, - token->location, - token->text); + mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); return; } mTokenizer->lex(token); // Get ')'. @@ -344,47 +404,51 @@ void DirectiveParser::parseDefine(Token *token) // list. Resetting it also allows us to reuse Token::equals() to // compare macros. token->location = SourceLocation(); - macro.replacements.push_back(*token); + macro->replacements.push_back(*token); mTokenizer->lex(token); } - if (!macro.replacements.empty()) + if (!macro->replacements.empty()) { // Whitespace preceding the replacement list is not considered part of // the replacement list for either form of macro. - macro.replacements.front().setHasLeadingSpace(false); + macro->replacements.front().setHasLeadingSpace(false); } // Check for macro redefinition. - MacroSet::const_iterator iter = mMacroSet->find(macro.name); - if (iter != mMacroSet->end() && !macro.equals(iter->second)) + MacroSet::const_iterator iter = mMacroSet->find(macro->name); + if (iter != mMacroSet->end() && !macro->equals(*iter->second)) { - mDiagnostics->report(Diagnostics::PP_MACRO_REDEFINED, - token->location, - macro.name); + mDiagnostics->report(Diagnostics::PP_MACRO_REDEFINED, token->location, macro->name); return; } - mMacroSet->insert(std::make_pair(macro.name, macro)); + mMacroSet->insert(std::make_pair(macro->name, macro)); } void DirectiveParser::parseUndef(Token *token) { - assert(getDirective(token) == DIRECTIVE_UNDEF); + ASSERT(getDirective(token) == DIRECTIVE_UNDEF); mTokenizer->lex(token); if (token->type != Token::IDENTIFIER) { - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); return; } MacroSet::iterator iter = mMacroSet->find(token->text); if (iter != mMacroSet->end()) { - if (iter->second.predefined) + if (iter->second->predefined) { - mDiagnostics->report(Diagnostics::PP_MACRO_PREDEFINED_UNDEFINED, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_MACRO_PREDEFINED_UNDEFINED, token->location, + token->text); + return; + } + else if (iter->second->expansionCount > 0) + { + mDiagnostics->report(Diagnostics::PP_MACRO_UNDEFINED_WHILE_INVOKED, token->location, + token->text); + return; } else { @@ -395,38 +459,37 @@ void DirectiveParser::parseUndef(Token *token) mTokenizer->lex(token); if (!isEOD(token)) { - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); skipUntilEOD(mTokenizer, token); } } void DirectiveParser::parseIf(Token *token) { - assert(getDirective(token) == DIRECTIVE_IF); + ASSERT(getDirective(token) == DIRECTIVE_IF); parseConditionalIf(token); } void DirectiveParser::parseIfdef(Token *token) { - assert(getDirective(token) == DIRECTIVE_IFDEF); + ASSERT(getDirective(token) == DIRECTIVE_IFDEF); parseConditionalIf(token); } void DirectiveParser::parseIfndef(Token *token) { - assert(getDirective(token) == DIRECTIVE_IFNDEF); + ASSERT(getDirective(token) == DIRECTIVE_IFNDEF); parseConditionalIf(token); } void DirectiveParser::parseElse(Token *token) { - assert(getDirective(token) == DIRECTIVE_ELSE); + ASSERT(getDirective(token) == DIRECTIVE_ELSE); if (mConditionalStack.empty()) { - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELSE_WITHOUT_IF, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELSE_WITHOUT_IF, token->location, + token->text); skipUntilEOD(mTokenizer, token); return; } @@ -440,34 +503,34 @@ void DirectiveParser::parseElse(Token *token) } if (block.foundElseGroup) { - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELSE_AFTER_ELSE, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELSE_AFTER_ELSE, token->location, + token->text); skipUntilEOD(mTokenizer, token); return; } - block.foundElseGroup = true; - block.skipGroup = block.foundValidGroup; + block.foundElseGroup = true; + block.skipGroup = block.foundValidGroup; block.foundValidGroup = true; // Check if there are extra tokens after #else. mTokenizer->lex(token); if (!isEOD(token)) { - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, token->location, + token->text); skipUntilEOD(mTokenizer, token); } } void DirectiveParser::parseElif(Token *token) { - assert(getDirective(token) == DIRECTIVE_ELIF); + ASSERT(getDirective(token) == DIRECTIVE_ELIF); if (mConditionalStack.empty()) { - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELIF_WITHOUT_IF, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELIF_WITHOUT_IF, token->location, + token->text); skipUntilEOD(mTokenizer, token); return; } @@ -481,8 +544,8 @@ void DirectiveParser::parseElif(Token *token) } if (block.foundElseGroup) { - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELIF_AFTER_ELSE, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELIF_AFTER_ELSE, token->location, + token->text); skipUntilEOD(mTokenizer, token); return; } @@ -495,19 +558,19 @@ void DirectiveParser::parseElif(Token *token) return; } - int expression = parseExpressionIf(token); - block.skipGroup = expression == 0; + int expression = parseExpressionIf(token); + block.skipGroup = expression == 0; block.foundValidGroup = expression != 0; } void DirectiveParser::parseEndif(Token *token) { - assert(getDirective(token) == DIRECTIVE_ENDIF); + ASSERT(getDirective(token) == DIRECTIVE_ENDIF); if (mConditionalStack.empty()) { - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ENDIF_WITHOUT_IF, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ENDIF_WITHOUT_IF, token->location, + token->text); skipUntilEOD(mTokenizer, token); return; } @@ -518,15 +581,15 @@ void DirectiveParser::parseEndif(Token *token) mTokenizer->lex(token); if (!isEOD(token)) { - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, token->location, + token->text); skipUntilEOD(mTokenizer, token); } } void DirectiveParser::parseError(Token *token) { - assert(getDirective(token) == DIRECTIVE_ERROR); + ASSERT(getDirective(token) == DIRECTIVE_ERROR); std::ostringstream stream; mTokenizer->lex(token); @@ -541,7 +604,7 @@ void DirectiveParser::parseError(Token *token) // Parses pragma of form: #pragma name[(value)]. void DirectiveParser::parsePragma(Token *token) { - assert(getDirective(token) == DIRECTIVE_PRAGMA); + ASSERT(getDirective(token) == DIRECTIVE_PRAGMA); enum State { @@ -563,25 +626,25 @@ void DirectiveParser::parsePragma(Token *token) } while ((token->type != '\n') && (token->type != Token::LAST)) { - switch(state++) + switch (state++) { - case PRAGMA_NAME: - name = token->text; - valid = valid && (token->type == Token::IDENTIFIER); - break; - case LEFT_PAREN: - valid = valid && (token->type == '('); - break; - case PRAGMA_VALUE: - value = token->text; - valid = valid && (token->type == Token::IDENTIFIER); - break; - case RIGHT_PAREN: - valid = valid && (token->type == ')'); - break; - default: - valid = false; - break; + case PRAGMA_NAME: + name = token->text; + valid = valid && (token->type == Token::IDENTIFIER); + break; + case LEFT_PAREN: + valid = valid && (token->type == '('); + break; + case PRAGMA_VALUE: + value = token->text; + valid = valid && (token->type == Token::IDENTIFIER); + break; + case RIGHT_PAREN: + valid = valid && (token->type == ')'); + break; + default: + valid = false; + break; } mTokenizer->lex(token); } @@ -591,8 +654,7 @@ void DirectiveParser::parsePragma(Token *token) (state == RIGHT_PAREN + 1)); // With value. if (!valid) { - mDiagnostics->report(Diagnostics::PP_UNRECOGNIZED_PRAGMA, - token->location, name); + mDiagnostics->report(Diagnostics::PP_UNRECOGNIZED_PRAGMA, token->location, name); } else if (state > PRAGMA_NAME) // Do not notify for empty pragma. { @@ -602,7 +664,7 @@ void DirectiveParser::parsePragma(Token *token) void DirectiveParser::parseExtension(Token *token) { - assert(getDirective(token) == DIRECTIVE_EXTENSION); + ASSERT(getDirective(token) == DIRECTIVE_EXTENSION); enum State { @@ -620,47 +682,49 @@ void DirectiveParser::parseExtension(Token *token) { switch (state++) { - case EXT_NAME: - if (valid && (token->type != Token::IDENTIFIER)) - { - mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_NAME, - token->location, token->text); - valid = false; - } - if (valid) name = token->text; - break; - case COLON: - if (valid && (token->type != ':')) - { - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, - token->location, token->text); - valid = false; - } - break; - case EXT_BEHAVIOR: - if (valid && (token->type != Token::IDENTIFIER)) - { - mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_BEHAVIOR, - token->location, token->text); - valid = false; - } - if (valid) behavior = token->text; - break; - default: - if (valid) - { - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, - token->location, token->text); - valid = false; - } - break; + case EXT_NAME: + if (valid && (token->type != Token::IDENTIFIER)) + { + mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_NAME, token->location, + token->text); + valid = false; + } + if (valid) + name = token->text; + break; + case COLON: + if (valid && (token->type != ':')) + { + mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, + token->text); + valid = false; + } + break; + case EXT_BEHAVIOR: + if (valid && (token->type != Token::IDENTIFIER)) + { + mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_BEHAVIOR, + token->location, token->text); + valid = false; + } + if (valid) + behavior = token->text; + break; + default: + if (valid) + { + mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, + token->text); + valid = false; + } + break; } mTokenizer->lex(token); } if (valid && (state != EXT_BEHAVIOR + 1)) { - mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_DIRECTIVE, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_DIRECTIVE, token->location, + token->text); valid = false; } if (valid && mSeenNonPreprocessorToken) @@ -683,12 +747,12 @@ void DirectiveParser::parseExtension(Token *token) void DirectiveParser::parseVersion(Token *token) { - assert(getDirective(token) == DIRECTIVE_VERSION); + ASSERT(getDirective(token) == DIRECTIVE_VERSION); if (mPastFirstStatement) { - mDiagnostics->report(Diagnostics::PP_VERSION_NOT_FIRST_STATEMENT, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_VERSION_NOT_FIRST_STATEMENT, token->location, + token->text); skipUntilEOD(mTokenizer, token); return; } @@ -700,47 +764,47 @@ void DirectiveParser::parseVersion(Token *token) VERSION_ENDLINE }; - bool valid = true; + bool valid = true; int version = 0; - int state = VERSION_NUMBER; + int state = VERSION_NUMBER; mTokenizer->lex(token); while (valid && (token->type != '\n') && (token->type != Token::LAST)) { switch (state) { - case VERSION_NUMBER: - if (token->type != Token::CONST_INT) - { - mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_NUMBER, - token->location, token->text); + case VERSION_NUMBER: + if (token->type != Token::CONST_INT) + { + mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_NUMBER, token->location, + token->text); + valid = false; + } + if (valid && !token->iValue(&version)) + { + mDiagnostics->report(Diagnostics::PP_INTEGER_OVERFLOW, token->location, + token->text); + valid = false; + } + if (valid) + { + state = (version < 300) ? VERSION_ENDLINE : VERSION_PROFILE; + } + break; + case VERSION_PROFILE: + if (token->type != Token::IDENTIFIER || token->text != "es") + { + mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_DIRECTIVE, token->location, + token->text); + valid = false; + } + state = VERSION_ENDLINE; + break; + default: + mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, + token->text); valid = false; - } - if (valid && !token->iValue(&version)) - { - mDiagnostics->report(Diagnostics::PP_INTEGER_OVERFLOW, - token->location, token->text); - valid = false; - } - if (valid) - { - state = (version < 300) ? VERSION_ENDLINE : VERSION_PROFILE; - } - break; - case VERSION_PROFILE: - if (token->type != Token::IDENTIFIER || token->text != "es") - { - mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_DIRECTIVE, - token->location, token->text); - valid = false; - } - state = VERSION_ENDLINE; - break; - default: - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, - token->location, token->text); - valid = false; - break; + break; } mTokenizer->lex(token); @@ -748,15 +812,15 @@ void DirectiveParser::parseVersion(Token *token) if (valid && (state != VERSION_ENDLINE)) { - mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_DIRECTIVE, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_DIRECTIVE, token->location, + token->text); valid = false; } if (valid && version >= 300 && token->location.line > 1) { - mDiagnostics->report(Diagnostics::PP_VERSION_NOT_FIRST_LINE_ESSL3, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_VERSION_NOT_FIRST_LINE_ESSL3, token->location, + token->text); valid = false; } @@ -770,13 +834,13 @@ void DirectiveParser::parseVersion(Token *token) void DirectiveParser::parseLine(Token *token) { - assert(getDirective(token) == DIRECTIVE_LINE); + ASSERT(getDirective(token) == DIRECTIVE_LINE); - bool valid = true; + bool valid = true; bool parsedFileNumber = false; int line = 0, file = 0; - MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, false); + MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, mMaxMacroExpansionDepth); // Lex the first token after "#line" so we can check it for EOD. macroExpander.lex(token); @@ -814,8 +878,8 @@ void DirectiveParser::parseLine(Token *token) { if (valid) { - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, + token->text); valid = false; } skipUntilEOD(mTokenizer, token); @@ -835,14 +899,14 @@ bool DirectiveParser::skipping() const if (mConditionalStack.empty()) return false; - const ConditionalBlock& block = mConditionalStack.back(); + const ConditionalBlock &block = mConditionalStack.back(); return block.skipBlock || block.skipGroup; } void DirectiveParser::parseConditionalIf(Token *token) { ConditionalBlock block; - block.type = token->text; + block.type = token->text; block.location = token->location; if (skipping()) @@ -861,20 +925,20 @@ void DirectiveParser::parseConditionalIf(Token *token) int expression = 0; switch (directive) { - case DIRECTIVE_IF: - expression = parseExpressionIf(token); - break; - case DIRECTIVE_IFDEF: - expression = parseExpressionIfdef(token); - break; - case DIRECTIVE_IFNDEF: - expression = parseExpressionIfdef(token) == 0 ? 1 : 0; - break; - default: - assert(false); - break; + case DIRECTIVE_IF: + expression = parseExpressionIf(token); + break; + case DIRECTIVE_IFDEF: + expression = parseExpressionIfdef(token); + break; + case DIRECTIVE_IFNDEF: + expression = parseExpressionIfdef(token) == 0 ? 1 : 0; + break; + default: + UNREACHABLE(); + break; } - block.skipGroup = expression == 0; + block.skipGroup = expression == 0; block.foundValidGroup = expression != 0; } mConditionalStack.push_back(block); @@ -882,16 +946,16 @@ void DirectiveParser::parseConditionalIf(Token *token) int DirectiveParser::parseExpressionIf(Token *token) { - assert((getDirective(token) == DIRECTIVE_IF) || - (getDirective(token) == DIRECTIVE_ELIF)); + ASSERT((getDirective(token) == DIRECTIVE_IF) || (getDirective(token) == DIRECTIVE_ELIF)); - MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, true); + DefinedParser definedParser(mTokenizer, mMacroSet, mDiagnostics); + MacroExpander macroExpander(&definedParser, mMacroSet, mDiagnostics, mMaxMacroExpansionDepth); ExpressionParser expressionParser(¯oExpander, mDiagnostics); int expression = 0; ExpressionParser::ErrorSettings errorSettings; errorSettings.integerLiteralsMustFit32BitSignedRange = false; - errorSettings.unexpectedIdentifier = Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN; + errorSettings.unexpectedIdentifier = Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN; bool valid = true; expressionParser.parse(token, &expression, false, errorSettings, &valid); @@ -899,8 +963,8 @@ int DirectiveParser::parseExpressionIf(Token *token) // Check if there are tokens after #if expression. if (!isEOD(token)) { - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, token->location, + token->text); skipUntilEOD(mTokenizer, token); } @@ -909,27 +973,25 @@ int DirectiveParser::parseExpressionIf(Token *token) int DirectiveParser::parseExpressionIfdef(Token *token) { - assert((getDirective(token) == DIRECTIVE_IFDEF) || - (getDirective(token) == DIRECTIVE_IFNDEF)); + ASSERT((getDirective(token) == DIRECTIVE_IFDEF) || (getDirective(token) == DIRECTIVE_IFNDEF)); mTokenizer->lex(token); if (token->type != Token::IDENTIFIER) { - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text); skipUntilEOD(mTokenizer, token); return 0; } MacroSet::const_iterator iter = mMacroSet->find(token->text); - int expression = iter != mMacroSet->end() ? 1 : 0; + int expression = iter != mMacroSet->end() ? 1 : 0; // Check if there are tokens after #ifdef expression. mTokenizer->lex(token); if (!isEOD(token)) { - mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, - token->location, token->text); + mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, token->location, + token->text); skipUntilEOD(mTokenizer, token); } return expression; diff --git a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.h b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.h index 2888e289ce..29c30a8239 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.h +++ b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.h @@ -7,10 +7,9 @@ #ifndef COMPILER_PREPROCESSOR_DIRECTIVEPARSER_H_ #define COMPILER_PREPROCESSOR_DIRECTIVEPARSER_H_ -#include "Lexer.h" -#include "Macro.h" -#include "pp_utils.h" -#include "SourceLocation.h" +#include "compiler/preprocessor/Lexer.h" +#include "compiler/preprocessor/Macro.h" +#include "compiler/preprocessor/SourceLocation.h" namespace pp { @@ -25,13 +24,13 @@ class DirectiveParser : public Lexer DirectiveParser(Tokenizer *tokenizer, MacroSet *macroSet, Diagnostics *diagnostics, - DirectiveHandler *directiveHandler); + DirectiveHandler *directiveHandler, + int maxMacroExpansionDepth); + ~DirectiveParser() override; void lex(Token *token) override; private: - PP_DISALLOW_COPY_AND_ASSIGN(DirectiveParser); - void parseDirective(Token *token); void parseDefine(Token *token); void parseUndef(Token *token); @@ -62,22 +61,21 @@ class DirectiveParser : public Lexer bool foundElseGroup; ConditionalBlock() - : skipBlock(false), - skipGroup(false), - foundValidGroup(false), - foundElseGroup(false) + : skipBlock(false), skipGroup(false), foundValidGroup(false), foundElseGroup(false) { } }; bool mPastFirstStatement; - bool mSeenNonPreprocessorToken; // Tracks if a non-preprocessor token has been seen yet. Some macros, such as - // #extension must be declared before all shader code. + bool mSeenNonPreprocessorToken; // Tracks if a non-preprocessor token has been seen yet. Some + // macros, such as + // #extension must be declared before all shader code. std::vector mConditionalStack; Tokenizer *mTokenizer; MacroSet *mMacroSet; Diagnostics *mDiagnostics; DirectiveHandler *mDirectiveHandler; int mShaderVersion; + int mMaxMacroExpansionDepth; }; } // namespace pp diff --git a/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.h b/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.h index 841c67b61c..0f2901b878 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.h +++ b/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.h @@ -7,8 +7,8 @@ #ifndef COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_ #define COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_ -#include "DiagnosticsBase.h" -#include "pp_utils.h" +#include "common/angleutils.h" +#include "compiler/preprocessor/DiagnosticsBase.h" namespace pp { @@ -16,7 +16,7 @@ namespace pp class Lexer; struct Token; -class ExpressionParser +class ExpressionParser : angle::NonCopyable { public: struct ErrorSettings @@ -34,8 +34,6 @@ class ExpressionParser bool *valid); private: - PP_DISALLOW_COPY_AND_ASSIGN(ExpressionParser); - Lexer *mLexer; Diagnostics *mDiagnostics; }; diff --git a/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.y b/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.y index 7b5d9e9cee..68d7cc3958 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.y +++ b/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.y @@ -41,17 +41,15 @@ WHICH GENERATES THE GLSL ES preprocessor expression parser. #include #include +#include #include "DiagnosticsBase.h" #include "Lexer.h" #include "Token.h" +#include "common/mathutil.h" -#if defined(_MSC_VER) -typedef __int64 YYSTYPE; -#else -#include -typedef intmax_t YYSTYPE; -#endif // _MSC_VER +typedef int32_t YYSTYPE; +typedef uint32_t UNSIGNED_TYPE; #define YYENABLE_NLS 0 #define YYLTYPE_IS_TRIVIAL 1 @@ -196,16 +194,57 @@ expression $$ = $1 < $3; } | expression TOK_OP_RIGHT expression { - $$ = $1 >> $3; + if ($3 < 0 || $3 > 31) + { + if (!context->isIgnoringErrors()) + { + std::ostringstream stream; + stream << $1 << " >> " << $3; + std::string text = stream.str(); + context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT, + context->token->location, + text.c_str()); + *(context->valid) = false; + } + $$ = static_cast(0); + } + else if ($1 < 0) + { + // Logical shift right. + $$ = static_cast(static_cast($1) >> $3); + } + else + { + $$ = $1 >> $3; + } } | expression TOK_OP_LEFT expression { - $$ = $1 << $3; + if ($3 < 0 || $3 > 31) + { + if (!context->isIgnoringErrors()) + { + std::ostringstream stream; + stream << $1 << " << " << $3; + std::string text = stream.str(); + context->diagnostics->report(pp::Diagnostics::PP_UNDEFINED_SHIFT, + context->token->location, + text.c_str()); + *(context->valid) = false; + } + $$ = static_cast(0); + } + else + { + // Logical shift left. Casting to unsigned is needed to ensure there's no signed integer + // overflow, which some tools treat as an error. + $$ = static_cast(static_cast($1) << $3); + } } | expression '-' expression { - $$ = $1 - $3; + $$ = gl::WrappingDiff($1, $3); } | expression '+' expression { - $$ = $1 + $3; + $$ = gl::WrappingSum($1, $3); } | expression '%' expression { if ($3 == 0) @@ -222,6 +261,12 @@ expression } $$ = static_cast(0); } + else if (($1 == std::numeric_limits::min()) && ($3 == -1)) + { + // Check for the special case where the minimum representable number is + // divided by -1. If left alone this has undefined results. + $$ = 0; + } else { $$ = $1 % $3; @@ -242,13 +287,20 @@ expression } $$ = static_cast(0); } + else if (($1 == std::numeric_limits::min()) && ($3 == -1)) + { + // Check for the special case where the minimum representable number is + // divided by -1. If left alone this leads to integer overflow in C++, which + // has undefined results. + $$ = std::numeric_limits::max(); + } else { $$ = $1 / $3; } } | expression '*' expression { - $$ = $1 * $3; + $$ = gl::WrappingMul($1, $3); } | '!' expression %prec TOK_UNARY { $$ = ! $2; @@ -257,7 +309,16 @@ expression $$ = ~ $2; } | '-' expression %prec TOK_UNARY { - $$ = - $2; + // Check for negation of minimum representable integer to prevent undefined signed int + // overflow. + if ($2 == std::numeric_limits::min()) + { + $$ = std::numeric_limits::min(); + } + else + { + $$ = -$2; + } } | '+' expression %prec TOK_UNARY { $$ = + $2; diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Input.cpp b/src/3rdparty/angle/src/compiler/preprocessor/Input.cpp index 5541d46f72..0f2327b823 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/Input.cpp +++ b/src/3rdparty/angle/src/compiler/preprocessor/Input.cpp @@ -4,12 +4,13 @@ // found in the LICENSE file. // -#include "Input.h" +#include "compiler/preprocessor/Input.h" #include -#include #include +#include "common/debug.h" + namespace pp { @@ -17,9 +18,12 @@ Input::Input() : mCount(0), mString(0) { } -Input::Input(size_t count, const char *const string[], const int length[]) : - mCount(count), - mString(string) +Input::~Input() +{ +} + +Input::Input(size_t count, const char *const string[], const int length[]) + : mCount(count), mString(string) { mLength.reserve(mCount); for (size_t i = 0; i < mCount; ++i) @@ -32,7 +36,7 @@ Input::Input(size_t count, const char *const string[], const int length[]) : const char *Input::skipChar() { // This function should only be called when there is a character to skip. - assert(mReadLoc.cIndex < mLength[mReadLoc.sIndex]); + ASSERT(mReadLoc.cIndex < mLength[mReadLoc.sIndex]); ++mReadLoc.cIndex; if (mReadLoc.cIndex == mLength[mReadLoc.sIndex]) { @@ -61,6 +65,11 @@ size_t Input::read(char *buf, size_t maxSize, int *lineNo) { // Line continuation of backslash + newline. skipChar(); + // Fake an EOF if the line number would overflow. + if (*lineNo == INT_MAX) + { + return 0; + } ++(*lineNo); } else if (c != nullptr && (*c) == '\r') @@ -71,6 +80,11 @@ size_t Input::read(char *buf, size_t maxSize, int *lineNo) { skipChar(); } + // Fake an EOF if the line number would overflow. + if (*lineNo == INT_MAX) + { + return 0; + } ++(*lineNo); } else @@ -86,7 +100,7 @@ size_t Input::read(char *buf, size_t maxSize, int *lineNo) while ((nRead < maxRead) && (mReadLoc.sIndex < mCount)) { size_t size = mLength[mReadLoc.sIndex] - mReadLoc.cIndex; - size = std::min(size, maxSize); + size = std::min(size, maxSize); for (size_t i = 0; i < size; ++i) { // Stop if a possible line continuation is encountered. @@ -94,7 +108,7 @@ size_t Input::read(char *buf, size_t maxSize, int *lineNo) // and increments line number if necessary. if (*(mString[mReadLoc.sIndex] + mReadLoc.cIndex + i) == '\\') { - size = i; + size = i; maxRead = nRead + size; // Stop reading right before the backslash. } } @@ -113,4 +127,3 @@ size_t Input::read(char *buf, size_t maxSize, int *lineNo) } } // namespace pp - diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Input.h b/src/3rdparty/angle/src/compiler/preprocessor/Input.h index a1de7ddd86..8c7c7ee19e 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/Input.h +++ b/src/3rdparty/angle/src/compiler/preprocessor/Input.h @@ -7,7 +7,7 @@ #ifndef COMPILER_PREPROCESSOR_INPUT_H_ #define COMPILER_PREPROCESSOR_INPUT_H_ -#include +#include #include namespace pp @@ -18,20 +18,12 @@ class Input { public: Input(); + ~Input(); Input(size_t count, const char *const string[], const int length[]); - size_t count() const - { - return mCount; - } - const char *string(size_t index) const - { - return mString[index]; - } - size_t length(size_t index) const - { - return mLength[index]; - } + size_t count() const { return mCount; } + const char *string(size_t index) const { return mString[index]; } + size_t length(size_t index) const { return mLength[index]; } size_t read(char *buf, size_t maxSize, int *lineNo); @@ -40,11 +32,7 @@ class Input size_t sIndex; // String index; size_t cIndex; // Char index. - Location() - : sIndex(0), - cIndex(0) - { - } + Location() : sIndex(0), cIndex(0) {} }; const Location &readLoc() const { return mReadLoc; } @@ -55,7 +43,7 @@ class Input // Input. size_t mCount; - const char * const *mString; + const char *const *mString; std::vector mLength; Location mReadLoc; diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Lexer.cpp b/src/3rdparty/angle/src/compiler/preprocessor/Lexer.cpp index 7c663ee761..89cb3cf44e 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/Lexer.cpp +++ b/src/3rdparty/angle/src/compiler/preprocessor/Lexer.cpp @@ -4,7 +4,7 @@ // found in the LICENSE file. // -#include "Lexer.h" +#include "compiler/preprocessor/Lexer.h" namespace pp { diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Lexer.h b/src/3rdparty/angle/src/compiler/preprocessor/Lexer.h index 990dc5e21d..775bc0a202 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/Lexer.h +++ b/src/3rdparty/angle/src/compiler/preprocessor/Lexer.h @@ -7,12 +7,14 @@ #ifndef COMPILER_PREPROCESSOR_LEXER_H_ #define COMPILER_PREPROCESSOR_LEXER_H_ +#include "common/angleutils.h" + namespace pp { struct Token; -class Lexer +class Lexer : angle::NonCopyable { public: virtual ~Lexer(); diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Macro.cpp b/src/3rdparty/angle/src/compiler/preprocessor/Macro.cpp index 4c4d5fd2e2..52e2312fe6 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/Macro.cpp +++ b/src/3rdparty/angle/src/compiler/preprocessor/Macro.cpp @@ -4,40 +4,41 @@ // found in the LICENSE file. // -#include "Macro.h" +#include "compiler/preprocessor/Macro.h" -#include - -#include "Token.h" +#include "common/angleutils.h" +#include "compiler/preprocessor/Token.h" namespace pp { +Macro::Macro() : predefined(false), disabled(false), expansionCount(0), type(kTypeObj) +{ +} + +Macro::~Macro() +{ +} + bool Macro::equals(const Macro &other) const { - return (type == other.type) && - (name == other.name) && - (parameters == other.parameters) && + return (type == other.type) && (name == other.name) && (parameters == other.parameters) && (replacements == other.replacements); } void PredefineMacro(MacroSet *macroSet, const char *name, int value) { - std::ostringstream stream; - stream << value; - Token token; token.type = Token::CONST_INT; - token.text = stream.str(); + token.text = ToString(value); - Macro macro; - macro.predefined = true; - macro.type = Macro::kTypeObj; - macro.name = name; - macro.replacements.push_back(token); + std::shared_ptr macro = std::make_shared(); + macro->predefined = true; + macro->type = Macro::kTypeObj; + macro->name = name; + macro->replacements.push_back(token); (*macroSet)[name] = macro; } } // namespace pp - diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Macro.h b/src/3rdparty/angle/src/compiler/preprocessor/Macro.h index 31ee22c26a..c42e172ef9 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/Macro.h +++ b/src/3rdparty/angle/src/compiler/preprocessor/Macro.h @@ -8,6 +8,7 @@ #define COMPILER_PREPROCESSOR_MACRO_H_ #include +#include #include #include @@ -26,16 +27,13 @@ struct Macro typedef std::vector Parameters; typedef std::vector Replacements; - Macro() - : predefined(false), - disabled(false), - type(kTypeObj) - { - } + Macro(); + ~Macro(); bool equals(const Macro &other) const; bool predefined; mutable bool disabled; + mutable int expansionCount; Type type; std::string name; @@ -43,7 +41,7 @@ struct Macro Replacements replacements; }; -typedef std::map MacroSet; +typedef std::map> MacroSet; void PredefineMacro(MacroSet *macroSet, const char *name, int value); diff --git a/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.cpp b/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.cpp index e878ee345a..d88d3a6853 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.cpp +++ b/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.cpp @@ -4,20 +4,25 @@ // found in the LICENSE file. // -#include "MacroExpander.h" +#include "compiler/preprocessor/MacroExpander.h" #include -#include -#include "DiagnosticsBase.h" -#include "Token.h" +#include "common/debug.h" +#include "compiler/preprocessor/DiagnosticsBase.h" +#include "compiler/preprocessor/Token.h" namespace pp { +namespace +{ + +const size_t kMaxContextTokens = 10000; + class TokenLexer : public Lexer { - public: + public: typedef std::vector TokenVector; TokenLexer(TokenVector *tokens) @@ -39,26 +44,61 @@ class TokenLexer : public Lexer } } - private: - PP_DISALLOW_COPY_AND_ASSIGN(TokenLexer); - + private: TokenVector mTokens; TokenVector::const_iterator mIter; }; +} // anonymous namespace + +class MacroExpander::ScopedMacroReenabler final : angle::NonCopyable +{ + public: + ScopedMacroReenabler(MacroExpander *expander); + ~ScopedMacroReenabler(); + + private: + MacroExpander *mExpander; +}; + +MacroExpander::ScopedMacroReenabler::ScopedMacroReenabler(MacroExpander *expander) + : mExpander(expander) +{ + mExpander->mDeferReenablingMacros = true; +} + +MacroExpander::ScopedMacroReenabler::~ScopedMacroReenabler() +{ + mExpander->mDeferReenablingMacros = false; + for (auto macro : mExpander->mMacrosToReenable) + { + // Copying the string here by using substr is a check for use-after-free. It detects + // use-after-free more reliably than just toggling the disabled flag. + ASSERT(macro->name.substr() != ""); + macro->disabled = false; + } + mExpander->mMacrosToReenable.clear(); +} + MacroExpander::MacroExpander(Lexer *lexer, MacroSet *macroSet, Diagnostics *diagnostics, - bool parseDefined) - : mLexer(lexer), mMacroSet(macroSet), mDiagnostics(diagnostics), mParseDefined(parseDefined) + int allowedMacroExpansionDepth) + : mLexer(lexer), + mMacroSet(macroSet), + mDiagnostics(diagnostics), + mTotalTokensInContexts(0), + mAllowedMacroExpansionDepth(allowedMacroExpansionDepth), + mDeferReenablingMacros(false) { } MacroExpander::~MacroExpander() { - for (std::size_t i = 0; i < mContextStack.size(); ++i) + ASSERT(mMacrosToReenable.empty()); + for (MacroContext *context : mContextStack) { - delete mContextStack[i]; + delete context; } } @@ -66,54 +106,11 @@ void MacroExpander::lex(Token *token) { while (true) { - const char kDefined[] = "defined"; - getToken(token); if (token->type != Token::IDENTIFIER) break; - // Defined operator is parsed here since it may be generated by macro expansion. - // Defined operator produced by macro expansion has undefined behavior according to C++ - // spec, which the GLSL spec references (see C++14 draft spec section 16.1.4), but this - // behavior is needed for passing dEQP tests, which enforce stricter compatibility between - // implementations. - if (mParseDefined && token->text == kDefined) - { - bool paren = false; - getToken(token); - if (token->type == '(') - { - paren = true; - getToken(token); - } - if (token->type != Token::IDENTIFIER) - { - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, - token->text); - break; - } - auto iter = mMacroSet->find(token->text); - std::string expression = iter != mMacroSet->end() ? "1" : "0"; - - if (paren) - { - getToken(token); - if (token->type != ')') - { - mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, - token->text); - break; - } - } - - // We have a valid defined operator. - // Convert the current token into a CONST_INT token. - token->type = Token::CONST_INT; - token->text = expression; - break; - } - if (token->expansionDisabled()) break; @@ -121,17 +118,22 @@ void MacroExpander::lex(Token *token) if (iter == mMacroSet->end()) break; - const Macro& macro = iter->second; - if (macro.disabled) + std::shared_ptr macro = iter->second; + if (macro->disabled) { // If a particular token is not expanded, it is never expanded. token->setExpansionDisabled(true); break; } - if ((macro.type == Macro::kTypeFunc) && !isNextTokenLeftParen()) + + // Bump the expansion count before peeking if the next token is a '(' + // otherwise there could be a #undef of the macro before the next token. + macro->expansionCount++; + if ((macro->type == Macro::kTypeFunc) && !isNextTokenLeftParen()) { // If the token immediately after the macro name is not a '(', // this macro should not be expanded. + macro->expansionCount--; break; } @@ -160,6 +162,7 @@ void MacroExpander::getToken(Token *token) } else { + ASSERT(mTotalTokensInContexts == 0); mLexer->lex(token); } } @@ -170,11 +173,11 @@ void MacroExpander::ungetToken(const Token &token) { MacroContext *context = mContextStack.back(); context->unget(); - assert(context->replacements[context->index] == token); + ASSERT(context->replacements[context->index] == token); } else { - assert(!mReserveToken.get()); + ASSERT(!mReserveToken.get()); mReserveToken.reset(new Token(token)); } } @@ -190,37 +193,48 @@ bool MacroExpander::isNextTokenLeftParen() return lparen; } -bool MacroExpander::pushMacro(const Macro ¯o, const Token &identifier) +bool MacroExpander::pushMacro(std::shared_ptr macro, const Token &identifier) { - assert(!macro.disabled); - assert(!identifier.expansionDisabled()); - assert(identifier.type == Token::IDENTIFIER); - assert(identifier.text == macro.name); + ASSERT(!macro->disabled); + ASSERT(!identifier.expansionDisabled()); + ASSERT(identifier.type == Token::IDENTIFIER); + ASSERT(identifier.text == macro->name); std::vector replacements; - if (!expandMacro(macro, identifier, &replacements)) + if (!expandMacro(*macro, identifier, &replacements)) return false; // Macro is disabled for expansion until it is popped off the stack. - macro.disabled = true; + macro->disabled = true; MacroContext *context = new MacroContext; - context->macro = ¯o; + context->macro = macro; context->replacements.swap(replacements); mContextStack.push_back(context); + mTotalTokensInContexts += context->replacements.size(); return true; } void MacroExpander::popMacro() { - assert(!mContextStack.empty()); + ASSERT(!mContextStack.empty()); MacroContext *context = mContextStack.back(); mContextStack.pop_back(); - assert(context->empty()); - assert(context->macro->disabled); - context->macro->disabled = false; + ASSERT(context->empty()); + ASSERT(context->macro->disabled); + ASSERT(context->macro->expansionCount > 0); + if (mDeferReenablingMacros) + { + mMacrosToReenable.push_back(context->macro); + } + else + { + context->macro->disabled = false; + } + context->macro->expansionCount--; + mTotalTokensInContexts -= context->replacements.size(); delete context; } @@ -237,33 +251,28 @@ bool MacroExpander::expandMacro(const Macro ¯o, SourceLocation replacementLocation = identifier.location; if (macro.type == Macro::kTypeObj) { - replacements->assign(macro.replacements.begin(), - macro.replacements.end()); + replacements->assign(macro.replacements.begin(), macro.replacements.end()); if (macro.predefined) { const char kLine[] = "__LINE__"; const char kFile[] = "__FILE__"; - assert(replacements->size() == 1); - Token& repl = replacements->front(); + ASSERT(replacements->size() == 1); + Token &repl = replacements->front(); if (macro.name == kLine) { - std::ostringstream stream; - stream << identifier.location.line; - repl.text = stream.str(); + repl.text = ToString(identifier.location.line); } else if (macro.name == kFile) { - std::ostringstream stream; - stream << identifier.location.file; - repl.text = stream.str(); + repl.text = ToString(identifier.location.file); } } } else { - assert(macro.type == Macro::kTypeFunc); + ASSERT(macro.type == Macro::kTypeFunc); std::vector args; args.reserve(macro.parameters.size()); if (!collectMacroArgs(macro, identifier, &args, &replacementLocation)) @@ -274,7 +283,7 @@ bool MacroExpander::expandMacro(const Macro ¯o, for (std::size_t i = 0; i < replacements->size(); ++i) { - Token& repl = replacements->at(i); + Token &repl = replacements->at(i); if (i == 0) { // The first token in the replacement list inherits the padding @@ -294,45 +303,52 @@ bool MacroExpander::collectMacroArgs(const Macro ¯o, { Token token; getToken(&token); - assert(token.type == '('); + ASSERT(token.type == '('); args->push_back(MacroArg()); - for (int openParens = 1; openParens != 0; ) + + // Defer reenabling macros until args collection is finished to avoid the possibility of + // infinite recursion. Otherwise infinite recursion might happen when expanding the args after + // macros have been popped from the context stack when parsing the args. + ScopedMacroReenabler deferReenablingMacros(this); + + int openParens = 1; + while (openParens != 0) { getToken(&token); if (token.type == Token::LAST) { - mDiagnostics->report(Diagnostics::PP_MACRO_UNTERMINATED_INVOCATION, - identifier.location, identifier.text); + mDiagnostics->report(Diagnostics::PP_MACRO_UNTERMINATED_INVOCATION, identifier.location, + identifier.text); // Do not lose EOF token. ungetToken(token); return false; } - bool isArg = false; // True if token is part of the current argument. + bool isArg = false; // True if token is part of the current argument. switch (token.type) { - case '(': - ++openParens; - isArg = true; - break; - case ')': - --openParens; - isArg = openParens != 0; - *closingParenthesisLocation = token.location; - break; - case ',': - // The individual arguments are separated by comma tokens, but - // the comma tokens between matching inner parentheses do not - // seperate arguments. - if (openParens == 1) - args->push_back(MacroArg()); - isArg = openParens != 1; - break; - default: - isArg = true; - break; + case '(': + ++openParens; + isArg = true; + break; + case ')': + --openParens; + isArg = openParens != 0; + *closingParenthesisLocation = token.location; + break; + case ',': + // The individual arguments are separated by comma tokens, but + // the comma tokens between matching inner parentheses do not + // seperate arguments. + if (openParens == 1) + args->push_back(MacroArg()); + isArg = openParens != 1; + break; + default: + isArg = true; + break; } if (isArg) { @@ -353,9 +369,9 @@ bool MacroExpander::collectMacroArgs(const Macro ¯o, // Validate the number of arguments. if (args->size() != params.size()) { - Diagnostics::ID id = args->size() < macro.parameters.size() ? - Diagnostics::PP_MACRO_TOO_FEW_ARGS : - Diagnostics::PP_MACRO_TOO_MANY_ARGS; + Diagnostics::ID id = args->size() < macro.parameters.size() + ? Diagnostics::PP_MACRO_TOO_FEW_ARGS + : Diagnostics::PP_MACRO_TOO_MANY_ARGS; mDiagnostics->report(id, identifier.location, identifier.text); return false; } @@ -363,11 +379,17 @@ bool MacroExpander::collectMacroArgs(const Macro ¯o, // Pre-expand each argument before substitution. // This step expands each argument individually before they are // inserted into the macro body. - for (std::size_t i = 0; i < args->size(); ++i) + size_t numTokens = 0; + for (auto &arg : *args) { - MacroArg &arg = args->at(i); TokenLexer lexer(&arg); - MacroExpander expander(&lexer, mMacroSet, mDiagnostics, mParseDefined); + if (mAllowedMacroExpansionDepth < 1) + { + mDiagnostics->report(Diagnostics::PP_MACRO_INVOCATION_CHAIN_TOO_DEEP, token.location, + token.text); + return false; + } + MacroExpander expander(&lexer, mMacroSet, mDiagnostics, mAllowedMacroExpansionDepth - 1); arg.clear(); expander.lex(&token); @@ -375,6 +397,12 @@ bool MacroExpander::collectMacroArgs(const Macro ¯o, { arg.push_back(token); expander.lex(&token); + numTokens++; + if (numTokens + mTotalTokensInContexts > kMaxContextTokens) + { + mDiagnostics->report(Diagnostics::PP_OUT_OF_MEMORY, token.location, token.text); + return false; + } } } return true; @@ -386,6 +414,14 @@ void MacroExpander::replaceMacroParams(const Macro ¯o, { for (std::size_t i = 0; i < macro.replacements.size(); ++i) { + if (!replacements->empty() && + replacements->size() + mTotalTokensInContexts > kMaxContextTokens) + { + const Token &token = replacements->back(); + mDiagnostics->report(Diagnostics::PP_OUT_OF_MEMORY, token.location, token.text); + return; + } + const Token &repl = macro.replacements[i]; if (repl.type != Token::IDENTIFIER) { @@ -396,15 +432,15 @@ void MacroExpander::replaceMacroParams(const Macro ¯o, // TODO(alokp): Optimize this. // There is no need to search for macro params every time. // The param index can be cached with the replacement token. - Macro::Parameters::const_iterator iter = std::find( - macro.parameters.begin(), macro.parameters.end(), repl.text); + Macro::Parameters::const_iterator iter = + std::find(macro.parameters.begin(), macro.parameters.end(), repl.text); if (iter == macro.parameters.end()) { replacements->push_back(repl); continue; } - std::size_t iArg = std::distance(macro.parameters.begin(), iter); + std::size_t iArg = std::distance(macro.parameters.begin(), iter); const MacroArg &arg = args[iArg]; if (arg.empty()) { @@ -418,5 +454,28 @@ void MacroExpander::replaceMacroParams(const Macro ¯o, } } -} // namespace pp +MacroExpander::MacroContext::MacroContext() : macro(0), index(0) +{ +} +MacroExpander::MacroContext::~MacroContext() +{ +} + +bool MacroExpander::MacroContext::empty() const +{ + return index == replacements.size(); +} + +const Token &MacroExpander::MacroContext::get() +{ + return replacements[index++]; +} + +void MacroExpander::MacroContext::unget() +{ + ASSERT(index > 0); + --index; +} + +} // namespace pp diff --git a/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.h b/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.h index dc870f626f..fae7676fb0 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.h +++ b/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.h @@ -7,13 +7,11 @@ #ifndef COMPILER_PREPROCESSOR_MACROEXPANDER_H_ #define COMPILER_PREPROCESSOR_MACROEXPANDER_H_ -#include #include #include -#include "Lexer.h" -#include "Macro.h" -#include "pp_utils.h" +#include "compiler/preprocessor/Lexer.h" +#include "compiler/preprocessor/Macro.h" namespace pp { @@ -24,24 +22,23 @@ struct SourceLocation; class MacroExpander : public Lexer { public: - MacroExpander(Lexer *lexer, MacroSet *macroSet, Diagnostics *diagnostics, bool parseDefined); + MacroExpander(Lexer *lexer, + MacroSet *macroSet, + Diagnostics *diagnostics, + int allowedMacroExpansionDepth); ~MacroExpander() override; void lex(Token *token) override; private: - PP_DISALLOW_COPY_AND_ASSIGN(MacroExpander); - void getToken(Token *token); void ungetToken(const Token &token); bool isNextTokenLeftParen(); - bool pushMacro(const Macro ¯o, const Token &identifier); + bool pushMacro(std::shared_ptr macro, const Token &identifier); void popMacro(); - bool expandMacro(const Macro ¯o, - const Token &identifier, - std::vector *replacements); + bool expandMacro(const Macro ¯o, const Token &identifier, std::vector *replacements); typedef std::vector MacroArg; bool collectMacroArgs(const Macro ¯o, @@ -54,37 +51,31 @@ class MacroExpander : public Lexer struct MacroContext { - const Macro *macro; + MacroContext(); + ~MacroContext(); + bool empty() const; + const Token &get(); + void unget(); + + std::shared_ptr macro; std::size_t index; std::vector replacements; - - MacroContext() - : macro(0), - index(0) - { - } - bool empty() const - { - return index == replacements.size(); - } - const Token &get() - { - return replacements[index++]; - } - void unget() - { - assert(index > 0); - --index; - } }; Lexer *mLexer; MacroSet *mMacroSet; Diagnostics *mDiagnostics; - bool mParseDefined; std::unique_ptr mReserveToken; std::vector mContextStack; + size_t mTotalTokensInContexts; + + int mAllowedMacroExpansionDepth; + + bool mDeferReenablingMacros; + std::vector> mMacrosToReenable; + + class ScopedMacroReenabler; }; } // namespace pp diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.cpp b/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.cpp index aeb9c46f9d..349c7b06c7 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.cpp +++ b/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.cpp @@ -4,16 +4,15 @@ // found in the LICENSE file. // -#include "Preprocessor.h" +#include "compiler/preprocessor/Preprocessor.h" -#include - -#include "DiagnosticsBase.h" -#include "DirectiveParser.h" -#include "Macro.h" -#include "MacroExpander.h" -#include "Token.h" -#include "Tokenizer.h" +#include "common/debug.h" +#include "compiler/preprocessor/DiagnosticsBase.h" +#include "compiler/preprocessor/DirectiveParser.h" +#include "compiler/preprocessor/Macro.h" +#include "compiler/preprocessor/MacroExpander.h" +#include "compiler/preprocessor/Token.h" +#include "compiler/preprocessor/Tokenizer.h" namespace pp { @@ -26,19 +25,26 @@ struct PreprocessorImpl DirectiveParser directiveParser; MacroExpander macroExpander; - PreprocessorImpl(Diagnostics *diag, DirectiveHandler *directiveHandler) + PreprocessorImpl(Diagnostics *diag, + DirectiveHandler *directiveHandler, + const PreprocessorSettings &settings) : diagnostics(diag), tokenizer(diag), - directiveParser(&tokenizer, ¯oSet, diag, directiveHandler), - macroExpander(&directiveParser, ¯oSet, diag, false) + directiveParser(&tokenizer, + ¯oSet, + diag, + directiveHandler, + settings.maxMacroExpansionDepth), + macroExpander(&directiveParser, ¯oSet, diag, settings.maxMacroExpansionDepth) { } }; Preprocessor::Preprocessor(Diagnostics *diagnostics, - DirectiveHandler *directiveHandler) + DirectiveHandler *directiveHandler, + const PreprocessorSettings &settings) { - mImpl = new PreprocessorImpl(diagnostics, directiveHandler); + mImpl = new PreprocessorImpl(diagnostics, directiveHandler, settings); } Preprocessor::~Preprocessor() @@ -46,9 +52,7 @@ Preprocessor::~Preprocessor() delete mImpl; } -bool Preprocessor::init(size_t count, - const char * const string[], - const int length[]) +bool Preprocessor::init(size_t count, const char *const string[], const int length[]) { static const int kDefaultGLSLVersion = 100; @@ -74,23 +78,23 @@ void Preprocessor::lex(Token *token) mImpl->macroExpander.lex(token); switch (token->type) { - // We should not be returning internal preprocessing tokens. - // Convert preprocessing tokens to compiler tokens or report - // diagnostics. - case Token::PP_HASH: - assert(false); - break; - case Token::PP_NUMBER: - mImpl->diagnostics->report(Diagnostics::PP_INVALID_NUMBER, - token->location, token->text); - break; - case Token::PP_OTHER: - mImpl->diagnostics->report(Diagnostics::PP_INVALID_CHARACTER, - token->location, token->text); - break; - default: - validToken = true; - break; + // We should not be returning internal preprocessing tokens. + // Convert preprocessing tokens to compiler tokens or report + // diagnostics. + case Token::PP_HASH: + UNREACHABLE(); + break; + case Token::PP_NUMBER: + mImpl->diagnostics->report(Diagnostics::PP_INVALID_NUMBER, token->location, + token->text); + break; + case Token::PP_OTHER: + mImpl->diagnostics->report(Diagnostics::PP_INVALID_CHARACTER, token->location, + token->text); + break; + default: + validToken = true; + break; } } } diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.h b/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.h index fe25daa123..2fe504f7f9 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.h +++ b/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.h @@ -7,9 +7,9 @@ #ifndef COMPILER_PREPROCESSOR_PREPROCESSOR_H_ #define COMPILER_PREPROCESSOR_PREPROCESSOR_H_ -#include +#include -#include "pp_utils.h" +#include "common/angleutils.h" namespace pp { @@ -19,10 +19,18 @@ class DirectiveHandler; struct PreprocessorImpl; struct Token; -class Preprocessor +struct PreprocessorSettings : private angle::NonCopyable +{ + PreprocessorSettings() : maxMacroExpansionDepth(1000) {} + int maxMacroExpansionDepth; +}; + +class Preprocessor : angle::NonCopyable { public: - Preprocessor(Diagnostics *diagnostics, DirectiveHandler *directiveHandler); + Preprocessor(Diagnostics *diagnostics, + DirectiveHandler *directiveHandler, + const PreprocessorSettings &settings); ~Preprocessor(); // count: specifies the number of elements in the string and length arrays. @@ -34,7 +42,7 @@ class Preprocessor // Each element in the length array may contain the length of the // corresponding string or a value less than 0 to indicate that the string // is null terminated. - bool init(size_t count, const char * const string[], const int length[]); + bool init(size_t count, const char *const string[], const int length[]); // Adds a pre-defined macro. void predefineMacro(const char *name, int value); @@ -44,8 +52,6 @@ class Preprocessor void setMaxTokenSize(size_t maxTokenSize); private: - PP_DISALLOW_COPY_AND_ASSIGN(Preprocessor); - PreprocessorImpl *mImpl; }; diff --git a/src/3rdparty/angle/src/compiler/preprocessor/SourceLocation.h b/src/3rdparty/angle/src/compiler/preprocessor/SourceLocation.h index af8a8d5d19..51908a3b4b 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/SourceLocation.h +++ b/src/3rdparty/angle/src/compiler/preprocessor/SourceLocation.h @@ -12,16 +12,8 @@ namespace pp struct SourceLocation { - SourceLocation() - : file(0), - line(0) - { - } - SourceLocation(int f, int l) - : file(f), - line(l) - { - } + SourceLocation() : file(0), line(0) {} + SourceLocation(int f, int l) : file(f), line(l) {} bool equals(const SourceLocation &other) const { diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Token.cpp b/src/3rdparty/angle/src/compiler/preprocessor/Token.cpp index d102654747..ce0ce94f49 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/Token.cpp +++ b/src/3rdparty/angle/src/compiler/preprocessor/Token.cpp @@ -4,28 +4,25 @@ // found in the LICENSE file. // -#include "Token.h" +#include "compiler/preprocessor/Token.h" -#include - -#include "numeric_lex.h" +#include "common/debug.h" +#include "compiler/preprocessor/numeric_lex.h" namespace pp { void Token::reset() { - type = 0; - flags = 0; + type = 0; + flags = 0; location = SourceLocation(); text.clear(); } bool Token::equals(const Token &other) const { - return (type == other.type) && - (flags == other.flags) && - (location == other.location) && + return (type == other.type) && (flags == other.flags) && (location == other.location) && (text == other.text); } @@ -55,19 +52,19 @@ void Token::setExpansionDisabled(bool disable) bool Token::iValue(int *value) const { - assert(type == CONST_INT); + ASSERT(type == CONST_INT); return numeric_lex_int(text, value); } bool Token::uValue(unsigned int *value) const { - assert(type == CONST_INT); + ASSERT(type == CONST_INT); return numeric_lex_int(text, value); } bool Token::fValue(float *value) const { - assert(type == CONST_FLOAT); + ASSERT(type == CONST_FLOAT); return numeric_lex_float(text, value); } diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Token.h b/src/3rdparty/angle/src/compiler/preprocessor/Token.h index 347c47e307..26732ab64d 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/Token.h +++ b/src/3rdparty/angle/src/compiler/preprocessor/Token.h @@ -10,7 +10,7 @@ #include #include -#include "SourceLocation.h" +#include "compiler/preprocessor/SourceLocation.h" namespace pp { @@ -19,7 +19,9 @@ struct Token { enum Type { - LAST = 0, // EOF. + // Calling this ERROR causes a conflict with wingdi.h + GOT_ERROR = -1, + LAST = 0, // EOF. IDENTIFIER = 258, @@ -62,33 +64,20 @@ struct Token EXPANSION_DISABLED = 1 << 2 }; - Token() - : type(0), - flags(0) - { - } + Token() : type(0), flags(0) {} void reset(); bool equals(const Token &other) const; // Returns true if this is the first token on line. // It disregards any leading whitespace. - bool atStartOfLine() const - { - return (flags & AT_START_OF_LINE) != 0; - } + bool atStartOfLine() const { return (flags & AT_START_OF_LINE) != 0; } void setAtStartOfLine(bool start); - bool hasLeadingSpace() const - { - return (flags & HAS_LEADING_SPACE) != 0; - } + bool hasLeadingSpace() const { return (flags & HAS_LEADING_SPACE) != 0; } void setHasLeadingSpace(bool space); - bool expansionDisabled() const - { - return (flags & EXPANSION_DISABLED) != 0; - } + bool expansionDisabled() const { return (flags & EXPANSION_DISABLED) != 0; } void setExpansionDisabled(bool disable); // Converts text into numeric value for CONST_INT and CONST_FLOAT token. @@ -113,7 +102,7 @@ inline bool operator!=(const Token &lhs, const Token &rhs) return !lhs.equals(rhs); } -extern std::ostream &operator<<(std::ostream &out, const Token &token); +std::ostream &operator<<(std::ostream &out, const Token &token); } // namepsace pp diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.h b/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.h index 49e64fa209..af4fd7ce7b 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.h +++ b/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.h @@ -7,9 +7,9 @@ #ifndef COMPILER_PREPROCESSOR_TOKENIZER_H_ #define COMPILER_PREPROCESSOR_TOKENIZER_H_ -#include "Input.h" -#include "Lexer.h" -#include "pp_utils.h" +#include "common/angleutils.h" +#include "compiler/preprocessor/Input.h" +#include "compiler/preprocessor/Lexer.h" namespace pp { @@ -34,9 +34,9 @@ class Tokenizer : public Lexer }; Tokenizer(Diagnostics *diagnostics); - ~Tokenizer(); + ~Tokenizer() override; - bool init(size_t count, const char * const string[], const int length[]); + bool init(size_t count, const char *const string[], const int length[]); void setFileNumber(int file); void setLineNumber(int line); @@ -45,13 +45,12 @@ class Tokenizer : public Lexer void lex(Token *token) override; private: - PP_DISALLOW_COPY_AND_ASSIGN(Tokenizer); bool initScanner(); void destroyScanner(); - void *mHandle; // Scanner handle. - Context mContext; // Scanner extra. - size_t mMaxTokenSize; // Maximum token size + void *mHandle; // Scanner handle. + Context mContext; // Scanner extra. + size_t mMaxTokenSize; // Maximum token size }; } // namespace pp diff --git a/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.l b/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.l index d316da88b1..096812d45f 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.l +++ b/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.l @@ -27,10 +27,10 @@ IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh. #pragma warning(disable: 4005) #endif -#include "Tokenizer.h" +#include "compiler/preprocessor/Tokenizer.h" -#include "DiagnosticsBase.h" -#include "Token.h" +#include "compiler/preprocessor/DiagnosticsBase.h" +#include "compiler/preprocessor/Token.h" #if defined(__GNUC__) // Triggered by the auto-generated yy_fatal_error function. @@ -110,7 +110,14 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".") "/*" { BEGIN(COMMENT); } [^*\r\n]+ "*" -{NEWLINE} { ++yylineno; } +{NEWLINE} { + if (yylineno == INT_MAX) + { + *yylval = "Integer overflow on line number"; + return pp::Token::GOT_ERROR; + } + ++yylineno; +} "*/" { yyextra->leadingSpace = true; BEGIN(INITIAL); @@ -237,13 +244,16 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".") [ \t\v\f]+ { yyextra->leadingSpace = true; } {NEWLINE} { + if (yylineno == INT_MAX) + { + *yylval = "Integer overflow on line number"; + return pp::Token::GOT_ERROR; + } ++yylineno; yylval->assign(1, '\n'); return '\n'; } -\\{NEWLINE} { ++yylineno; } - . { yylval->assign(1, yytext[0]); return pp::Token::PP_OTHER; @@ -267,11 +277,17 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".") yylloc->line = yylineno; yylval->clear(); - if (YY_START == COMMENT) + // Line number overflows fake EOFs to exit early, check for this case. + if (yylineno == INT_MAX) { + yyextra->diagnostics->report(pp::Diagnostics::PP_TOKENIZER_ERROR, + pp::SourceLocation(yyfileno, yylineno), + "Integer overflow on line number"); + } + else if (YY_START == COMMENT) { yyextra->diagnostics->report(pp::Diagnostics::PP_EOF_IN_COMMENT, pp::SourceLocation(yyfileno, yylineno), - ""); + "EOF while in a comment"); } yyterminate(); } @@ -280,9 +296,7 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".") namespace pp { -Tokenizer::Tokenizer(Diagnostics *diagnostics) - : mHandle(0), - mMaxTokenSize(256) +Tokenizer::Tokenizer(Diagnostics *diagnostics) : mHandle(nullptr), mMaxTokenSize(256) { mContext.diagnostics = diagnostics; } @@ -320,7 +334,18 @@ void Tokenizer::setMaxTokenSize(size_t maxTokenSize) void Tokenizer::lex(Token *token) { - token->type = yylex(&token->text, &token->location, mHandle); + int tokenType = yylex(&token->text, &token->location, mHandle); + + if (tokenType == Token::GOT_ERROR) + { + mContext.diagnostics->report(Diagnostics::PP_TOKENIZER_ERROR, token->location, token->text); + token->type = Token::LAST; + } + else + { + token->type = tokenType; + } + if (token->text.size() > mMaxTokenSize) { mContext.diagnostics->report(Diagnostics::PP_TOKEN_TOO_LONG, @@ -339,7 +364,7 @@ void Tokenizer::lex(Token *token) bool Tokenizer::initScanner() { - if ((mHandle == NULL) && yylex_init_extra(&mContext, &mHandle)) + if ((mHandle == nullptr) && yylex_init_extra(&mContext, &mHandle)) return false; yyrestart(0, mHandle); @@ -348,11 +373,11 @@ bool Tokenizer::initScanner() void Tokenizer::destroyScanner() { - if (mHandle == NULL) + if (mHandle == nullptr) return; yylex_destroy(mHandle); - mHandle = NULL; + mHandle = nullptr; } } // namespace pp diff --git a/src/3rdparty/angle/src/compiler/preprocessor/numeric_lex.h b/src/3rdparty/angle/src/compiler/preprocessor/numeric_lex.h index b32e42253f..6ea779ab8f 100644 --- a/src/3rdparty/angle/src/compiler/preprocessor/numeric_lex.h +++ b/src/3rdparty/angle/src/compiler/preprocessor/numeric_lex.h @@ -9,15 +9,15 @@ #ifndef COMPILER_PREPROCESSOR_NUMERICLEX_H_ #define COMPILER_PREPROCESSOR_NUMERICLEX_H_ +#include #include -namespace pp { +namespace pp +{ inline std::ios::fmtflags numeric_base_int(const std::string &str) { - if ((str.size() >= 2) && - (str[0] == '0') && - (str[1] == 'x' || str[1] == 'X')) + if ((str.size() >= 2) && (str[0] == '0') && (str[1] == 'x' || str[1] == 'X')) { return std::ios::hex; } @@ -33,7 +33,7 @@ inline std::ios::fmtflags numeric_base_int(const std::string &str) // of the correct form. They can only fail if the parsed value is too big, // in which case false is returned. -template +template bool numeric_lex_int(const std::string &str, IntType *value) { std::istringstream stream(str); @@ -45,7 +45,7 @@ bool numeric_lex_int(const std::string &str, IntType *value) return !stream.fail(); } -template +template bool numeric_lex_float(const std::string &str, FloatType *value) { // On 64-bit Intel Android, istringstream is broken. Until this is fixed in @@ -63,10 +63,10 @@ bool numeric_lex_float(const std::string &str, FloatType *value) stream.imbue(std::locale::classic()); stream >> (*value); - return !stream.fail(); + return !stream.fail() && std::isfinite(*value); #endif } -} // namespace pp. +} // namespace pp. -#endif // COMPILER_PREPROCESSOR_NUMERICLEX_H_ +#endif // COMPILER_PREPROCESSOR_NUMERICLEX_H_ diff --git a/src/3rdparty/angle/src/compiler/preprocessor/pp_utils.h b/src/3rdparty/angle/src/compiler/preprocessor/pp_utils.h deleted file mode 100644 index 9fba9385c5..0000000000 --- a/src/3rdparty/angle/src/compiler/preprocessor/pp_utils.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// pp_utils.h: Common preprocessor utilities - -#ifndef COMPILER_PREPROCESSOR_PPUTILS_H_ -#define COMPILER_PREPROCESSOR_PPUTILS_H_ - -// A macro to disallow the copy constructor and operator= functions -// This must be used in the private: declarations for a class. -#define PP_DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName &); \ - void operator=(const TypeName &) - -#endif // COMPILER_PREPROCESSOR_PPUTILS_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/ASTMetadataHLSL.cpp b/src/3rdparty/angle/src/compiler/translator/ASTMetadataHLSL.cpp index 31bfae9966..b04fc28259 100644 --- a/src/3rdparty/angle/src/compiler/translator/ASTMetadataHLSL.cpp +++ b/src/3rdparty/angle/src/compiler/translator/ASTMetadataHLSL.cpp @@ -9,8 +9,12 @@ #include "compiler/translator/ASTMetadataHLSL.h" #include "compiler/translator/CallDAG.h" +#include "compiler/translator/IntermTraverse.h" #include "compiler/translator/SymbolTable.h" +namespace sh +{ + namespace { @@ -29,9 +33,22 @@ class PullGradient : public TIntermTraverser mDag(dag) { ASSERT(index < metadataList->size()); + + // ESSL 100 builtin gradient functions + mGradientBuiltinFunctions.insert("texture2D"); + mGradientBuiltinFunctions.insert("texture2DProj"); + mGradientBuiltinFunctions.insert("textureCube"); + + // ESSL 300 builtin gradient functions + mGradientBuiltinFunctions.insert("texture"); + mGradientBuiltinFunctions.insert("textureProj"); + mGradientBuiltinFunctions.insert("textureOffset"); + mGradientBuiltinFunctions.insert("textureProjOffset"); + + // ESSL 310 doesn't add builtin gradient functions } - void traverse(TIntermAggregate *node) + void traverse(TIntermFunctionDefinition *node) { node->traverse(this); ASSERT(mParents.empty()); @@ -59,7 +76,7 @@ class PullGradient : public TIntermTraverser ASSERT(mParents.back() == node); mParents.pop_back(); // A control flow's using a gradient means its parents are too. - if (mMetadata->mControlFlowsContainingGradient.count(node)> 0 && !mParents.empty()) + if (mMetadata->mControlFlowsContainingGradient.count(node) > 0 && !mParents.empty()) { mMetadata->mControlFlowsContainingGradient.insert(mParents.back()); } @@ -72,9 +89,9 @@ class PullGradient : public TIntermTraverser return true; } - bool visitSelection(Visit visit, TIntermSelection *selection) override + bool visitIfElse(Visit visit, TIntermIfElse *ifElse) override { - visitControlFlow(visit, selection); + visitControlFlow(visit, ifElse); return true; } @@ -84,11 +101,12 @@ class PullGradient : public TIntermTraverser { switch (node->getOp()) { - case EOpDFdx: - case EOpDFdy: - onGradient(); - default: - break; + case EOpDFdx: + case EOpDFdy: + case EOpFwidth: + onGradient(); + default: + break; } } @@ -99,28 +117,22 @@ class PullGradient : public TIntermTraverser { if (visit == PreVisit) { - if (node->getOp() == EOpFunctionCall) + if (node->getOp() == EOpCallFunctionInAST) { - if (node->isUserDefined()) - { - size_t calleeIndex = mDag.findIndex(node); - ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex); - UNUSED_ASSERTION_VARIABLE(mIndex); + size_t calleeIndex = mDag.findIndex(node->getFunctionSymbolInfo()); + ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex); - if ((*mMetadataList)[calleeIndex].mUsesGradient) { - onGradient(); - } + if ((*mMetadataList)[calleeIndex].mUsesGradient) + { + onGradient(); } - else + } + else if (node->getOp() == EOpCallBuiltInFunction) + { + if (mGradientBuiltinFunctions.find(node->getFunctionSymbolInfo()->getName()) != + mGradientBuiltinFunctions.end()) { - TString name = TFunction::unmangleName(node->getName()); - - if (name == "texture2D" || - name == "texture2DProj" || - name == "textureCube") - { - onGradient(); - } + onGradient(); } } } @@ -136,7 +148,10 @@ class PullGradient : public TIntermTraverser // Contains a stack of the control flow nodes that are parents of the node being // currently visited. It is used to mark control flows using a gradient. - std::vector mParents; + std::vector mParents; + + // A list of builtin functions that use gradients + std::set mGradientBuiltinFunctions; }; // Traverses the AST of a function definition to compute the the discontinuous loops @@ -157,7 +172,7 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser { } - void traverse(TIntermAggregate *node) + void traverse(TIntermFunctionDefinition *node) { node->traverse(this); ASSERT(mLoopsAndSwitches.empty()); @@ -196,7 +211,7 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser return true; } - bool visitSelection(Visit visit, TIntermSelection *node) override + bool visitIfElse(Visit visit, TIntermIfElse *node) override { if (visit == PreVisit) { @@ -222,7 +237,7 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser { switch (node->getFlowOp()) { - case EOpBreak: + case EOpBreak: { ASSERT(!mLoopsAndSwitches.empty()); TIntermLoop *loop = mLoopsAndSwitches.back()->getAsLoopNode(); @@ -232,11 +247,11 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser } } break; - case EOpContinue: + case EOpContinue: { ASSERT(!mLoopsAndSwitches.empty()); TIntermLoop *loop = nullptr; - size_t i = mLoopsAndSwitches.size(); + size_t i = mLoopsAndSwitches.size(); while (loop == nullptr && i > 0) { --i; @@ -246,23 +261,23 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser mMetadata->mDiscontinuousLoops.insert(loop); } break; - case EOpKill: - case EOpReturn: - // A return or discard jumps out of all the enclosing loops - if (!mLoopsAndSwitches.empty()) - { - for (TIntermNode *intermNode : mLoopsAndSwitches) + case EOpKill: + case EOpReturn: + // A return or discard jumps out of all the enclosing loops + if (!mLoopsAndSwitches.empty()) { - TIntermLoop *loop = intermNode->getAsLoopNode(); - if (loop) + for (TIntermNode *intermNode : mLoopsAndSwitches) { - mMetadata->mDiscontinuousLoops.insert(loop); + TIntermLoop *loop = intermNode->getAsLoopNode(); + if (loop) + { + mMetadata->mDiscontinuousLoops.insert(loop); + } } } - } - break; - default: - UNREACHABLE(); + break; + default: + UNREACHABLE(); } } @@ -271,18 +286,14 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser bool visitAggregate(Visit visit, TIntermAggregate *node) override { - if (visit == PreVisit && node->getOp() == EOpFunctionCall) + if (visit == PreVisit && node->getOp() == EOpCallFunctionInAST) { - if (node->isUserDefined()) - { - size_t calleeIndex = mDag.findIndex(node); - ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex); - UNUSED_ASSERTION_VARIABLE(mIndex); + size_t calleeIndex = mDag.findIndex(node->getFunctionSymbolInfo()); + ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex); - if ((*mMetadataList)[calleeIndex].mHasGradientLoopInCallGraph) - { - onGradientLoop(); - } + if ((*mMetadataList)[calleeIndex].mHasGradientLoopInCallGraph) + { + onGradientLoop(); } } @@ -309,8 +320,8 @@ class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser size_t mIndex; const CallDAG &mDag; - std::vector mLoopsAndSwitches; - std::vector mIfs; + std::vector mLoopsAndSwitches; + std::vector mIfs; }; // Tags all the functions called in a discontinuous loop @@ -327,7 +338,7 @@ class PushDiscontinuousLoops : public TIntermTraverser { } - void traverse(TIntermAggregate *node) + void traverse(TIntermFunctionDefinition *node) { node->traverse(this); ASSERT(mNestedDiscont == (mMetadata->mCalledInDiscontinuousLoop ? 1 : 0)); @@ -353,18 +364,17 @@ class PushDiscontinuousLoops : public TIntermTraverser { switch (node->getOp()) { - case EOpFunctionCall: - if (visit == PreVisit && node->isUserDefined() && mNestedDiscont > 0) - { - size_t calleeIndex = mDag.findIndex(node); - ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex); - UNUSED_ASSERTION_VARIABLE(mIndex); + case EOpCallFunctionInAST: + if (visit == PreVisit && mNestedDiscont > 0) + { + size_t calleeIndex = mDag.findIndex(node->getFunctionSymbolInfo()); + ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex); - (*mMetadataList)[calleeIndex].mCalledInDiscontinuousLoop = true; - } - break; - default: - break; + (*mMetadataList)[calleeIndex].mCalledInDiscontinuousLoop = true; + } + break; + default: + break; } return true; } @@ -377,7 +387,6 @@ class PushDiscontinuousLoops : public TIntermTraverser int mNestedDiscont; }; - } bool ASTMetadataHLSL::hasGradientInCallGraph(TIntermLoop *node) @@ -385,7 +394,7 @@ bool ASTMetadataHLSL::hasGradientInCallGraph(TIntermLoop *node) return mControlFlowsContainingGradient.count(node) > 0; } -bool ASTMetadataHLSL::hasGradientLoop(TIntermSelection *node) +bool ASTMetadataHLSL::hasGradientLoop(TIntermIfElse *node) { return mIfsContainingGradientLoop.count(node) > 0; } @@ -449,3 +458,5 @@ MetadataList CreateASTMetadataHLSL(TIntermNode *root, const CallDAG &callDag) return metadataList; } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/ASTMetadataHLSL.h b/src/3rdparty/angle/src/compiler/translator/ASTMetadataHLSL.h index 39e671e3e0..550a522b86 100644 --- a/src/3rdparty/angle/src/compiler/translator/ASTMetadataHLSL.h +++ b/src/3rdparty/angle/src/compiler/translator/ASTMetadataHLSL.h @@ -12,9 +12,12 @@ #include #include +namespace sh +{ + class CallDAG; class TIntermNode; -class TIntermSelection; +class TIntermIfElse; class TIntermLoop; struct ASTMetadataHLSL @@ -30,21 +33,21 @@ struct ASTMetadataHLSL // Here "something uses a gradient" means here that it either contains a // gradient operation, or a call to a function that uses a gradient. bool hasGradientInCallGraph(TIntermLoop *node); - bool hasGradientLoop(TIntermSelection *node); + bool hasGradientLoop(TIntermIfElse *node); // Does the function use a gradient. bool mUsesGradient; // Even if usesGradient is true, some control flow might not use a gradient // so we store the set of all gradient-using control flows. - std::set mControlFlowsContainingGradient; + std::set mControlFlowsContainingGradient; // Remember information about the discontinuous loops and which functions // are called in such loops. bool mCalledInDiscontinuousLoop; bool mHasGradientLoopInCallGraph; - std::set mDiscontinuousLoops; - std::set mIfsContainingGradientLoop; + std::set mDiscontinuousLoops; + std::set mIfsContainingGradientLoop; // Will we need to generate a Lod0 version of the function. bool mNeedsLod0; @@ -55,4 +58,6 @@ typedef std::vector MetadataList; // Return the AST analysis result, in the order defined by the call DAG MetadataList CreateASTMetadataHLSL(TIntermNode *root, const CallDAG &callDag); -#endif // COMPILER_TRANSLATOR_ASTMETADATAHLSL_H_ +} // namespace sh + +#endif // COMPILER_TRANSLATOR_ASTMETADATAHLSL_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/AddAndTrueToLoopCondition.cpp b/src/3rdparty/angle/src/compiler/translator/AddAndTrueToLoopCondition.cpp new file mode 100644 index 0000000000..6a05104233 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/AddAndTrueToLoopCondition.cpp @@ -0,0 +1,59 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/translator/AddAndTrueToLoopCondition.h" + +#include "compiler/translator/IntermTraverse.h" + +namespace sh +{ + +namespace +{ + +// An AST traverser that rewrites for and while loops by replacing "condition" with +// "condition && true" to work around condition bug on Intel Mac. +class AddAndTrueToLoopConditionTraverser : public TIntermTraverser +{ + public: + AddAndTrueToLoopConditionTraverser() : TIntermTraverser(true, false, false) {} + + bool visitLoop(Visit, TIntermLoop *loop) override + { + // do-while loop doesn't have this bug. + if (loop->getType() != ELoopFor && loop->getType() != ELoopWhile) + { + return true; + } + + // For loop may not have a condition. + if (loop->getCondition() == nullptr) + { + return true; + } + + // Constant true. + TConstantUnion *trueConstant = new TConstantUnion(); + trueConstant->setBConst(true); + TIntermTyped *trueValue = new TIntermConstantUnion(trueConstant, TType(EbtBool)); + + // CONDITION && true. + TIntermBinary *andOp = new TIntermBinary(EOpLogicalAnd, loop->getCondition(), trueValue); + loop->setCondition(andOp); + + return true; + } +}; + +} // anonymous namespace + +void AddAndTrueToLoopCondition(TIntermNode *root) +{ + AddAndTrueToLoopConditionTraverser traverser; + root->traverse(&traverser); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/AddAndTrueToLoopCondition.h b/src/3rdparty/angle/src/compiler/translator/AddAndTrueToLoopCondition.h new file mode 100644 index 0000000000..34debe0ed9 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/AddAndTrueToLoopCondition.h @@ -0,0 +1,20 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Rewrite condition in for and while loops to work around driver bug on Intel Mac. + +#ifndef COMPILER_TRANSLATOR_ADDANDTRUETOLOOPCONDITION_H_ +#define COMPILER_TRANSLATOR_ADDANDTRUETOLOOPCONDITION_H_ + +class TIntermNode; +namespace sh +{ + +void AddAndTrueToLoopCondition(TIntermNode *root); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_ADDANDTRUETOLOOPCONDITION_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/AddDefaultReturnStatements.cpp b/src/3rdparty/angle/src/compiler/translator/AddDefaultReturnStatements.cpp new file mode 100644 index 0000000000..4dfe60c0bc --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/AddDefaultReturnStatements.cpp @@ -0,0 +1,58 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// AddDefaultReturnStatements.cpp: Add default return statements to functions that do not end in a +// return. +// + +#include "compiler/translator/AddDefaultReturnStatements.h" + +#include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermNode_util.h" +#include "compiler/translator/util.h" + +namespace sh +{ + +namespace +{ + +bool NeedsReturnStatement(TIntermFunctionDefinition *node, TType *returnType) +{ + *returnType = node->getFunctionPrototype()->getType(); + if (returnType->getBasicType() == EbtVoid) + { + return false; + } + + TIntermBlock *bodyNode = node->getBody(); + TIntermBranch *returnNode = bodyNode->getSequence()->back()->getAsBranchNode(); + if (returnNode != nullptr && returnNode->getFlowOp() == EOpReturn) + { + return false; + } + + return true; +} + +} // anonymous namespace + +void AddDefaultReturnStatements(TIntermBlock *root) +{ + TType returnType; + for (TIntermNode *node : *root->getSequence()) + { + TIntermFunctionDefinition *definition = node->getAsFunctionDefinition(); + if (definition != nullptr && NeedsReturnStatement(definition, &returnType)) + { + TIntermBranch *branch = new TIntermBranch(EOpReturn, CreateZeroNode(returnType)); + + TIntermBlock *bodyNode = definition->getBody(); + bodyNode->getSequence()->push_back(branch); + } + } +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/AddDefaultReturnStatements.h b/src/3rdparty/angle/src/compiler/translator/AddDefaultReturnStatements.h new file mode 100644 index 0000000000..40a70ad8c2 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/AddDefaultReturnStatements.h @@ -0,0 +1,22 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// AddDefaultReturnStatements.h: Add default return statements to functions that do not end in a +// return. +// + +#ifndef COMPILER_TRANSLATOR_ADDDEFAULTRETURNSTATEMENTS_H_ +#define COMPILER_TRANSLATOR_ADDDEFAULTRETURNSTATEMENTS_H_ + +class TIntermBlock; + +namespace sh +{ + +void AddDefaultReturnStatements(TIntermBlock *root); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_ADDDEFAULTRETURNSTATEMENTS_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/ArrayReturnValueToOutParameter.cpp b/src/3rdparty/angle/src/compiler/translator/ArrayReturnValueToOutParameter.cpp index 510ade84c1..17721fb0dc 100644 --- a/src/3rdparty/angle/src/compiler/translator/ArrayReturnValueToOutParameter.cpp +++ b/src/3rdparty/angle/src/compiler/translator/ArrayReturnValueToOutParameter.cpp @@ -3,17 +3,23 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// The ArrayReturnValueToOutParameter function changes return values of an array type to out parameters in -// function definitions, prototypes, and call sites. +// The ArrayReturnValueToOutParameter function changes return values of an array type to out +// parameters in function definitions, prototypes, and call sites. #include "compiler/translator/ArrayReturnValueToOutParameter.h" -#include "compiler/translator/IntermNode.h" +#include + +#include "compiler/translator/IntermTraverse.h" +#include "compiler/translator/SymbolTable.h" + +namespace sh +{ namespace { -void CopyAggregateChildren(TIntermAggregate *from, TIntermAggregate *to) +void CopyAggregateChildren(TIntermAggregateBase *from, TIntermAggregateBase *to) { const TIntermSequence *fromSequence = from->getSequence(); for (size_t ii = 0; ii < fromSequence->size(); ++ii) @@ -22,156 +28,153 @@ void CopyAggregateChildren(TIntermAggregate *from, TIntermAggregate *to) } } -TIntermSymbol *CreateReturnValueSymbol(const TType &type) +TIntermSymbol *CreateReturnValueSymbol(const TSymbolUniqueId &id, const TType &type) { - TIntermSymbol *node = new TIntermSymbol(0, "angle_return", type); + TIntermSymbol *node = new TIntermSymbol(id, "angle_return", type); node->setInternal(true); + node->getTypePointer()->setQualifier(EvqOut); return node; } -TIntermSymbol *CreateReturnValueOutSymbol(const TType &type) +TIntermAggregate *CreateReplacementCall(TIntermAggregate *originalCall, + TIntermTyped *returnValueTarget) { - TType outType(type); - outType.setQualifier(EvqOut); - return CreateReturnValueSymbol(outType); -} - -TIntermAggregate *CreateReplacementCall(TIntermAggregate *originalCall, TIntermTyped *returnValueTarget) -{ - TIntermAggregate *replacementCall = new TIntermAggregate(EOpFunctionCall); - replacementCall->setType(TType(EbtVoid)); - replacementCall->setUserDefined(); - replacementCall->setNameObj(originalCall->getNameObj()); - replacementCall->setFunctionId(originalCall->getFunctionId()); - replacementCall->setLine(originalCall->getLine()); - TIntermSequence *replacementParameters = replacementCall->getSequence(); - TIntermSequence *originalParameters = originalCall->getSequence(); - for (auto ¶m : *originalParameters) + TIntermSequence *replacementArguments = new TIntermSequence(); + TIntermSequence *originalArguments = originalCall->getSequence(); + for (auto &arg : *originalArguments) { - replacementParameters->push_back(param); + replacementArguments->push_back(arg); } - replacementParameters->push_back(returnValueTarget); + replacementArguments->push_back(returnValueTarget); + TIntermAggregate *replacementCall = TIntermAggregate::CreateFunctionCall( + TType(EbtVoid), originalCall->getFunctionSymbolInfo()->getId(), + originalCall->getFunctionSymbolInfo()->getNameObj(), replacementArguments); + replacementCall->setLine(originalCall->getLine()); return replacementCall; } class ArrayReturnValueToOutParameterTraverser : private TIntermTraverser { public: - static void apply(TIntermNode *root, unsigned int *temporaryIndex); - private: - ArrayReturnValueToOutParameterTraverser(); + static void apply(TIntermNode *root, TSymbolTable *symbolTable); + private: + ArrayReturnValueToOutParameterTraverser(TSymbolTable *symbolTable); + + bool visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *node) override; + bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override; bool visitAggregate(Visit visit, TIntermAggregate *node) override; bool visitBranch(Visit visit, TIntermBranch *node) override; bool visitBinary(Visit visit, TIntermBinary *node) override; - bool mInFunctionWithArrayReturnValue; + // Set when traversal is inside a function with array return value. + TIntermFunctionDefinition *mFunctionWithArrayReturnValue; + + // Map from function symbol ids to array return value ids. + std::map mReturnValueIds; }; -void ArrayReturnValueToOutParameterTraverser::apply(TIntermNode *root, unsigned int *temporaryIndex) +void ArrayReturnValueToOutParameterTraverser::apply(TIntermNode *root, TSymbolTable *symbolTable) { - ArrayReturnValueToOutParameterTraverser arrayReturnValueToOutParam; - arrayReturnValueToOutParam.useTemporaryIndex(temporaryIndex); + ArrayReturnValueToOutParameterTraverser arrayReturnValueToOutParam(symbolTable); root->traverse(&arrayReturnValueToOutParam); arrayReturnValueToOutParam.updateTree(); } -ArrayReturnValueToOutParameterTraverser::ArrayReturnValueToOutParameterTraverser() - : TIntermTraverser(true, false, true), - mInFunctionWithArrayReturnValue(false) +ArrayReturnValueToOutParameterTraverser::ArrayReturnValueToOutParameterTraverser( + TSymbolTable *symbolTable) + : TIntermTraverser(true, false, true, symbolTable), mFunctionWithArrayReturnValue(nullptr) { } +bool ArrayReturnValueToOutParameterTraverser::visitFunctionDefinition( + Visit visit, + TIntermFunctionDefinition *node) +{ + if (node->getFunctionPrototype()->isArray() && visit == PreVisit) + { + // Replacing the function header is done on visitFunctionPrototype(). + mFunctionWithArrayReturnValue = node; + } + if (visit == PostVisit) + { + mFunctionWithArrayReturnValue = nullptr; + } + return true; +} + +bool ArrayReturnValueToOutParameterTraverser::visitFunctionPrototype(Visit visit, + TIntermFunctionPrototype *node) +{ + if (visit == PreVisit && node->isArray()) + { + // Replace the whole prototype node with another node that has the out parameter + // added. Also set the function to return void. + TIntermFunctionPrototype *replacement = + new TIntermFunctionPrototype(TType(EbtVoid), node->getFunctionSymbolInfo()->getId()); + CopyAggregateChildren(node, replacement); + const TSymbolUniqueId &functionId = node->getFunctionSymbolInfo()->getId(); + if (mReturnValueIds.find(functionId.get()) == mReturnValueIds.end()) + { + mReturnValueIds[functionId.get()] = new TSymbolUniqueId(mSymbolTable); + } + replacement->getSequence()->push_back( + CreateReturnValueSymbol(*mReturnValueIds[functionId.get()], node->getType())); + *replacement->getFunctionSymbolInfo() = *node->getFunctionSymbolInfo(); + replacement->setLine(node->getLine()); + + queueReplacement(replacement, OriginalNode::IS_DROPPED); + } + return false; +} + bool ArrayReturnValueToOutParameterTraverser::visitAggregate(Visit visit, TIntermAggregate *node) { - if (visit == PreVisit) + ASSERT(!node->isArray() || node->getOp() != EOpCallInternalRawFunction); + if (visit == PreVisit && node->isArray() && node->getOp() == EOpCallFunctionInAST) { - if (node->isArray()) + // Handle call sites where the returned array is not assigned. + // Examples where f() is a function returning an array: + // 1. f(); + // 2. another_array == f(); + // 3. another_function(f()); + // 4. return f(); + // Cases 2 to 4 are already converted to simpler cases by + // SeparateExpressionsReturningArrays, so we only need to worry about the case where a + // function call returning an array forms an expression by itself. + TIntermBlock *parentBlock = getParentNode()->getAsBlock(); + if (parentBlock) { - if (node->getOp() == EOpFunction) - { - // Replace the parameters child node of the function definition with another node - // that has the out parameter added. - // Also set the function to return void. - - TIntermAggregate *params = node->getSequence()->front()->getAsAggregate(); - ASSERT(params != nullptr && params->getOp() == EOpParameters); - - TIntermAggregate *replacementParams = new TIntermAggregate; - replacementParams->setOp(EOpParameters); - CopyAggregateChildren(params, replacementParams); - replacementParams->getSequence()->push_back(CreateReturnValueOutSymbol(node->getType())); - replacementParams->setLine(params->getLine()); - - mReplacements.push_back(NodeUpdateEntry(node, params, replacementParams, false)); - - node->setType(TType(EbtVoid)); - - mInFunctionWithArrayReturnValue = true; - } - else if (node->getOp() == EOpPrototype) - { - // Replace the whole prototype node with another node that has the out parameter added. - TIntermAggregate *replacement = new TIntermAggregate; - replacement->setOp(EOpPrototype); - CopyAggregateChildren(node, replacement); - replacement->getSequence()->push_back(CreateReturnValueOutSymbol(node->getType())); - replacement->setUserDefined(); - replacement->setNameObj(node->getNameObj()); - replacement->setFunctionId(node->getFunctionId()); - replacement->setLine(node->getLine()); - replacement->setType(TType(EbtVoid)); - - mReplacements.push_back(NodeUpdateEntry(getParentNode(), node, replacement, false)); - } - else if (node->getOp() == EOpFunctionCall) - { - // Handle call sites where the returned array is not assigned. - // Examples where f() is a function returning an array: - // 1. f(); - // 2. another_array == f(); - // 3. another_function(f()); - // 4. return f(); - // Cases 2 to 4 are already converted to simpler cases by SeparateExpressionsReturningArrays, so we - // only need to worry about the case where a function call returning an array forms an expression by - // itself. - TIntermAggregate *parentAgg = getParentNode()->getAsAggregate(); - if (parentAgg != nullptr && parentAgg->getOp() == EOpSequence) - { - nextTemporaryIndex(); - TIntermSequence replacements; - replacements.push_back(createTempDeclaration(node->getType())); - TIntermSymbol *returnSymbol = createTempSymbol(node->getType()); - replacements.push_back(CreateReplacementCall(node, returnSymbol)); - mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(parentAgg, node, replacements)); - } - return false; - } - } - } - else if (visit == PostVisit) - { - if (node->getOp() == EOpFunction) - { - mInFunctionWithArrayReturnValue = false; + nextTemporaryId(); + TIntermSequence replacements; + replacements.push_back(createTempDeclaration(node->getType())); + TIntermSymbol *returnSymbol = createTempSymbol(node->getType()); + replacements.push_back(CreateReplacementCall(node, returnSymbol)); + mMultiReplacements.push_back( + NodeReplaceWithMultipleEntry(parentBlock, node, replacements)); } + return false; } return true; } bool ArrayReturnValueToOutParameterTraverser::visitBranch(Visit visit, TIntermBranch *node) { - if (mInFunctionWithArrayReturnValue && node->getFlowOp() == EOpReturn) + if (mFunctionWithArrayReturnValue && node->getFlowOp() == EOpReturn) { // Instead of returning a value, assign to the out parameter and then return. TIntermSequence replacements; - TIntermBinary *replacementAssignment = new TIntermBinary(EOpAssign); TIntermTyped *expression = node->getExpression(); ASSERT(expression != nullptr); - replacementAssignment->setLeft(CreateReturnValueSymbol(expression->getType())); - replacementAssignment->setRight(node->getExpression()); - replacementAssignment->setType(expression->getType()); + const TSymbolUniqueId &functionId = + mFunctionWithArrayReturnValue->getFunctionSymbolInfo()->getId(); + ASSERT(mReturnValueIds.find(functionId.get()) != mReturnValueIds.end()); + const TSymbolUniqueId &returnValueId = *mReturnValueIds[functionId.get()]; + TIntermSymbol *returnValueSymbol = + CreateReturnValueSymbol(returnValueId, expression->getType()); + TIntermBinary *replacementAssignment = + new TIntermBinary(EOpAssign, returnValueSymbol, expression); replacementAssignment->setLine(expression->getLine()); replacements.push_back(replacementAssignment); @@ -179,7 +182,8 @@ bool ArrayReturnValueToOutParameterTraverser::visitBranch(Visit visit, TIntermBr replacementBranch->setLine(node->getLine()); replacements.push_back(replacementBranch); - mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(getParentNode()->getAsAggregate(), node, replacements)); + mMultiReplacements.push_back( + NodeReplaceWithMultipleEntry(getParentNode()->getAsBlock(), node, replacements)); } return false; } @@ -189,18 +193,21 @@ bool ArrayReturnValueToOutParameterTraverser::visitBinary(Visit visit, TIntermBi if (node->getOp() == EOpAssign && node->getLeft()->isArray()) { TIntermAggregate *rightAgg = node->getRight()->getAsAggregate(); - if (rightAgg != nullptr && rightAgg->getOp() == EOpFunctionCall && rightAgg->isUserDefined()) + ASSERT(rightAgg == nullptr || rightAgg->getOp() != EOpCallInternalRawFunction); + if (rightAgg != nullptr && rightAgg->getOp() == EOpCallFunctionInAST) { TIntermAggregate *replacementCall = CreateReplacementCall(rightAgg, node->getLeft()); - mReplacements.push_back(NodeUpdateEntry(getParentNode(), node, replacementCall, false)); + queueReplacement(replacementCall, OriginalNode::IS_DROPPED); } } return false; } -} // namespace +} // namespace -void ArrayReturnValueToOutParameter(TIntermNode *root, unsigned int *temporaryIndex) +void ArrayReturnValueToOutParameter(TIntermNode *root, TSymbolTable *symbolTable) { - ArrayReturnValueToOutParameterTraverser::apply(root, temporaryIndex); + ArrayReturnValueToOutParameterTraverser::apply(root, symbolTable); } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/ArrayReturnValueToOutParameter.h b/src/3rdparty/angle/src/compiler/translator/ArrayReturnValueToOutParameter.h index 983e203e62..469c7a3b14 100644 --- a/src/3rdparty/angle/src/compiler/translator/ArrayReturnValueToOutParameter.h +++ b/src/3rdparty/angle/src/compiler/translator/ArrayReturnValueToOutParameter.h @@ -3,14 +3,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// The ArrayReturnValueToOutParameter function changes return values of an array type to out parameters in -// function definitions, prototypes and call sites. +// The ArrayReturnValueToOutParameter function changes return values of an array type to out +// parameters in function definitions, prototypes and call sites. #ifndef COMPILER_TRANSLATOR_ARRAYRETURNVALUETOOUTPARAMETER_H_ #define COMPILER_TRANSLATOR_ARRAYRETURNVALUETOOUTPARAMETER_H_ -class TIntermNode; +namespace sh +{ -void ArrayReturnValueToOutParameter(TIntermNode *root, unsigned int *temporaryIndex); +class TIntermNode; +class TSymbolTable; + +void ArrayReturnValueToOutParameter(TIntermNode *root, TSymbolTable *symbolTable); + +} // namespace sh #endif // COMPILER_TRANSLATOR_ARRAYRETURNVALUETOOUTPARAMETER_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/BaseTypes.h b/src/3rdparty/angle/src/compiler/translator/BaseTypes.h index 0ed6d0e62f..b2070f3baf 100644 --- a/src/3rdparty/angle/src/compiler/translator/BaseTypes.h +++ b/src/3rdparty/angle/src/compiler/translator/BaseTypes.h @@ -7,7 +7,14 @@ #ifndef COMPILER_TRANSLATOR_BASETYPES_H_ #define COMPILER_TRANSLATOR_BASETYPES_H_ +#include +#include + #include "common/debug.h" +#include "GLSLANG/ShaderLang.h" + +namespace sh +{ // // Precision qualifiers @@ -24,14 +31,18 @@ enum TPrecision EbpLast }; -inline const char* getPrecisionString(TPrecision p) +inline const char *getPrecisionString(TPrecision p) { - switch(p) + switch (p) { - case EbpHigh: return "highp"; break; - case EbpMedium: return "mediump"; break; - case EbpLow: return "lowp"; break; - default: return "mediump"; break; // Safest fallback + case EbpHigh: + return "highp"; + case EbpMedium: + return "mediump"; + case EbpLow: + return "lowp"; + default: + return "mediump"; // Safest fallback } } @@ -54,69 +65,243 @@ enum TBasicType EbtIVec, // non type: represents ivec2, ivec3, and ivec4 EbtUVec, // non type: represents uvec2, uvec3, and uvec4 EbtBVec, // non type: represents bvec2, bvec3, and bvec4 + EbtYuvCscStandardEXT, // Only valid if EXT_YUV_target exists. EbtGuardSamplerBegin, // non type: see implementation of IsSampler() EbtSampler2D, EbtSampler3D, EbtSamplerCube, EbtSampler2DArray, - EbtSamplerExternalOES, // Only valid if OES_EGL_image_external exists. - EbtSampler2DRect, // Only valid if GL_ARB_texture_rectangle exists. + EbtSamplerExternalOES, // Only valid if OES_EGL_image_external exists. + EbtSamplerExternal2DY2YEXT, // Only valid if GL_EXT_YUV_target exists. + EbtSampler2DRect, // Only valid if GL_ARB_texture_rectangle exists. + EbtSampler2DMS, EbtISampler2D, EbtISampler3D, EbtISamplerCube, EbtISampler2DArray, + EbtISampler2DMS, EbtUSampler2D, EbtUSampler3D, EbtUSamplerCube, EbtUSampler2DArray, + EbtUSampler2DMS, EbtSampler2DShadow, EbtSamplerCubeShadow, EbtSampler2DArrayShadow, - EbtGuardSamplerEnd, // non type: see implementation of IsSampler() - EbtGSampler2D, // non type: represents sampler2D, isampler2D, and usampler2D - EbtGSampler3D, // non type: represents sampler3D, isampler3D, and usampler3D - EbtGSamplerCube, // non type: represents samplerCube, isamplerCube, and usamplerCube - EbtGSampler2DArray, // non type: represents sampler2DArray, isampler2DArray, and usampler2DArray + EbtGuardSamplerEnd, // non type: see implementation of IsSampler() + EbtGSampler2D, // non type: represents sampler2D, isampler2D, and usampler2D + EbtGSampler3D, // non type: represents sampler3D, isampler3D, and usampler3D + EbtGSamplerCube, // non type: represents samplerCube, isamplerCube, and usamplerCube + EbtGSampler2DArray, // non type: represents sampler2DArray, isampler2DArray, and + // usampler2DArray + EbtGSampler2DMS, // non type: represents sampler2DMS, isampler2DMS, and usampler2DMS + + // images + EbtGuardImageBegin, + EbtImage2D, + EbtIImage2D, + EbtUImage2D, + EbtImage3D, + EbtIImage3D, + EbtUImage3D, + EbtImage2DArray, + EbtIImage2DArray, + EbtUImage2DArray, + EbtImageCube, + EbtIImageCube, + EbtUImageCube, + EbtGuardImageEnd, + + EbtGuardGImageBegin, + EbtGImage2D, // non type: represents image2D, uimage2D, iimage2D + EbtGImage3D, // non type: represents image3D, uimage3D, iimage3D + EbtGImage2DArray, // non type: represents image2DArray, uimage2DArray, iimage2DArray + EbtGImageCube, // non type: represents imageCube, uimageCube, iimageCube + EbtGuardGImageEnd, + EbtStruct, EbtInterfaceBlock, - EbtAddress, // should be deprecated?? + EbtAddress, // should be deprecated?? + + EbtAtomicCounter, // end of list EbtLast }; -const char* getBasicString(TBasicType t); +inline TBasicType convertGImageToFloatImage(TBasicType type) +{ + switch (type) + { + case EbtGImage2D: + return EbtImage2D; + case EbtGImage3D: + return EbtImage3D; + case EbtGImage2DArray: + return EbtImage2DArray; + case EbtGImageCube: + return EbtImageCube; + default: + UNREACHABLE(); + } + return EbtLast; +} + +inline TBasicType convertGImageToIntImage(TBasicType type) +{ + switch (type) + { + case EbtGImage2D: + return EbtIImage2D; + case EbtGImage3D: + return EbtIImage3D; + case EbtGImage2DArray: + return EbtIImage2DArray; + case EbtGImageCube: + return EbtIImageCube; + default: + UNREACHABLE(); + } + return EbtLast; +} + +inline TBasicType convertGImageToUnsignedImage(TBasicType type) +{ + switch (type) + { + case EbtGImage2D: + return EbtUImage2D; + case EbtGImage3D: + return EbtUImage3D; + case EbtGImage2DArray: + return EbtUImage2DArray; + case EbtGImageCube: + return EbtUImageCube; + default: + UNREACHABLE(); + } + return EbtLast; +} + +const char *getBasicString(TBasicType t); inline bool IsSampler(TBasicType type) { return type > EbtGuardSamplerBegin && type < EbtGuardSamplerEnd; } +inline bool IsImage(TBasicType type) +{ + return type > EbtGuardImageBegin && type < EbtGuardImageEnd; +} + +inline bool IsGImage(TBasicType type) +{ + return type > EbtGuardGImageBegin && type < EbtGuardGImageEnd; +} + +inline bool IsAtomicCounter(TBasicType type) +{ + return type == EbtAtomicCounter; +} + +inline bool IsOpaqueType(TBasicType type) +{ + return IsSampler(type) || IsImage(type) || IsAtomicCounter(type); +} + inline bool IsIntegerSampler(TBasicType type) { switch (type) { - case EbtISampler2D: - case EbtISampler3D: - case EbtISamplerCube: - case EbtISampler2DArray: - case EbtUSampler2D: - case EbtUSampler3D: - case EbtUSamplerCube: - case EbtUSampler2DArray: - return true; - case EbtSampler2D: - case EbtSampler3D: - case EbtSamplerCube: - case EbtSamplerExternalOES: - case EbtSampler2DRect: - case EbtSampler2DArray: - case EbtSampler2DShadow: - case EbtSamplerCubeShadow: - case EbtSampler2DArrayShadow: - return false; - default: - assert(!IsSampler(type)); + case EbtISampler2D: + case EbtISampler3D: + case EbtISamplerCube: + case EbtISampler2DArray: + case EbtISampler2DMS: + case EbtUSampler2D: + case EbtUSampler3D: + case EbtUSamplerCube: + case EbtUSampler2DArray: + case EbtUSampler2DMS: + return true; + case EbtSampler2D: + case EbtSampler3D: + case EbtSamplerCube: + case EbtSamplerExternalOES: + case EbtSamplerExternal2DY2YEXT: + case EbtSampler2DRect: + case EbtSampler2DArray: + case EbtSampler2DShadow: + case EbtSamplerCubeShadow: + case EbtSampler2DArrayShadow: + case EbtSampler2DMS: + return false; + default: + assert(!IsSampler(type)); + } + + return false; +} + +inline bool IsSampler2DMS(TBasicType type) +{ + switch (type) + { + case EbtSampler2DMS: + case EbtISampler2DMS: + case EbtUSampler2DMS: + return true; + default: + return false; + } +} + +inline bool IsFloatImage(TBasicType type) +{ + switch (type) + { + case EbtImage2D: + case EbtImage3D: + case EbtImage2DArray: + case EbtImageCube: + return true; + default: + break; + } + + return false; +} + +inline bool IsIntegerImage(TBasicType type) +{ + + switch (type) + { + case EbtIImage2D: + case EbtIImage3D: + case EbtIImage2DArray: + case EbtIImageCube: + return true; + default: + break; + } + + return false; +} + +inline bool IsUnsignedImage(TBasicType type) +{ + + switch (type) + { + case EbtUImage2D: + case EbtUImage3D: + case EbtUImage2DArray: + case EbtUImageCube: + return true; + default: + break; } return false; @@ -126,27 +311,31 @@ inline bool IsSampler2D(TBasicType type) { switch (type) { - case EbtSampler2D: - case EbtISampler2D: - case EbtUSampler2D: - case EbtSampler2DArray: - case EbtISampler2DArray: - case EbtUSampler2DArray: - case EbtSampler2DRect: - case EbtSamplerExternalOES: - case EbtSampler2DShadow: - case EbtSampler2DArrayShadow: - return true; - case EbtSampler3D: - case EbtISampler3D: - case EbtUSampler3D: - case EbtISamplerCube: - case EbtUSamplerCube: - case EbtSamplerCube: - case EbtSamplerCubeShadow: - return false; - default: - assert(!IsSampler(type)); + case EbtSampler2D: + case EbtISampler2D: + case EbtUSampler2D: + case EbtSampler2DArray: + case EbtISampler2DArray: + case EbtUSampler2DArray: + case EbtSampler2DRect: + case EbtSamplerExternalOES: + case EbtSamplerExternal2DY2YEXT: + case EbtSampler2DShadow: + case EbtSampler2DArrayShadow: + case EbtSampler2DMS: + case EbtISampler2DMS: + case EbtUSampler2DMS: + return true; + case EbtSampler3D: + case EbtISampler3D: + case EbtUSampler3D: + case EbtISamplerCube: + case EbtUSamplerCube: + case EbtSamplerCube: + case EbtSamplerCubeShadow: + return false; + default: + assert(!IsSampler(type)); } return false; @@ -156,27 +345,31 @@ inline bool IsSamplerCube(TBasicType type) { switch (type) { - case EbtSamplerCube: - case EbtISamplerCube: - case EbtUSamplerCube: - case EbtSamplerCubeShadow: - return true; - case EbtSampler2D: - case EbtSampler3D: - case EbtSamplerExternalOES: - case EbtSampler2DRect: - case EbtSampler2DArray: - case EbtISampler2D: - case EbtISampler3D: - case EbtISampler2DArray: - case EbtUSampler2D: - case EbtUSampler3D: - case EbtUSampler2DArray: - case EbtSampler2DShadow: - case EbtSampler2DArrayShadow: - return false; - default: - assert(!IsSampler(type)); + case EbtSamplerCube: + case EbtISamplerCube: + case EbtUSamplerCube: + case EbtSamplerCubeShadow: + return true; + case EbtSampler2D: + case EbtSampler3D: + case EbtSamplerExternalOES: + case EbtSamplerExternal2DY2YEXT: + case EbtSampler2DRect: + case EbtSampler2DArray: + case EbtSampler2DMS: + case EbtISampler2D: + case EbtISampler3D: + case EbtISampler2DArray: + case EbtISampler2DMS: + case EbtUSampler2D: + case EbtUSampler3D: + case EbtUSampler2DArray: + case EbtUSampler2DMS: + case EbtSampler2DShadow: + case EbtSampler2DArrayShadow: + return false; + default: + assert(!IsSampler(type)); } return false; @@ -186,27 +379,31 @@ inline bool IsSampler3D(TBasicType type) { switch (type) { - case EbtSampler3D: - case EbtISampler3D: - case EbtUSampler3D: - return true; - case EbtSampler2D: - case EbtSamplerCube: - case EbtSamplerExternalOES: - case EbtSampler2DRect: - case EbtSampler2DArray: - case EbtISampler2D: - case EbtISamplerCube: - case EbtISampler2DArray: - case EbtUSampler2D: - case EbtUSamplerCube: - case EbtUSampler2DArray: - case EbtSampler2DShadow: - case EbtSamplerCubeShadow: - case EbtSampler2DArrayShadow: - return false; - default: - assert(!IsSampler(type)); + case EbtSampler3D: + case EbtISampler3D: + case EbtUSampler3D: + return true; + case EbtSampler2D: + case EbtSamplerCube: + case EbtSamplerExternalOES: + case EbtSamplerExternal2DY2YEXT: + case EbtSampler2DRect: + case EbtSampler2DArray: + case EbtSampler2DMS: + case EbtISampler2D: + case EbtISamplerCube: + case EbtISampler2DArray: + case EbtISampler2DMS: + case EbtUSampler2D: + case EbtUSamplerCube: + case EbtUSampler2DArray: + case EbtUSampler2DMS: + case EbtSampler2DShadow: + case EbtSamplerCubeShadow: + case EbtSampler2DArrayShadow: + return false; + default: + assert(!IsSampler(type)); } return false; @@ -216,27 +413,31 @@ inline bool IsSamplerArray(TBasicType type) { switch (type) { - case EbtSampler2DArray: - case EbtISampler2DArray: - case EbtUSampler2DArray: - case EbtSampler2DArrayShadow: - return true; - case EbtSampler2D: - case EbtISampler2D: - case EbtUSampler2D: - case EbtSampler2DRect: - case EbtSamplerExternalOES: - case EbtSampler3D: - case EbtISampler3D: - case EbtUSampler3D: - case EbtISamplerCube: - case EbtUSamplerCube: - case EbtSamplerCube: - case EbtSampler2DShadow: - case EbtSamplerCubeShadow: - return false; - default: - assert(!IsSampler(type)); + case EbtSampler2DArray: + case EbtISampler2DArray: + case EbtUSampler2DArray: + case EbtSampler2DArrayShadow: + return true; + case EbtSampler2D: + case EbtISampler2D: + case EbtUSampler2D: + case EbtSampler2DRect: + case EbtSamplerExternalOES: + case EbtSamplerExternal2DY2YEXT: + case EbtSampler3D: + case EbtISampler3D: + case EbtUSampler3D: + case EbtISamplerCube: + case EbtUSamplerCube: + case EbtSamplerCube: + case EbtSampler2DShadow: + case EbtSamplerCubeShadow: + case EbtSampler2DMS: + case EbtISampler2DMS: + case EbtUSampler2DMS: + return false; + default: + assert(!IsSampler(type)); } return false; @@ -246,27 +447,131 @@ inline bool IsShadowSampler(TBasicType type) { switch (type) { - case EbtSampler2DShadow: - case EbtSamplerCubeShadow: - case EbtSampler2DArrayShadow: - return true; - case EbtISampler2D: - case EbtISampler3D: - case EbtISamplerCube: - case EbtISampler2DArray: - case EbtUSampler2D: - case EbtUSampler3D: - case EbtUSamplerCube: - case EbtUSampler2DArray: - case EbtSampler2D: - case EbtSampler3D: - case EbtSamplerCube: - case EbtSamplerExternalOES: - case EbtSampler2DRect: - case EbtSampler2DArray: - return false; - default: - assert(!IsSampler(type)); + case EbtSampler2DShadow: + case EbtSamplerCubeShadow: + case EbtSampler2DArrayShadow: + return true; + case EbtISampler2D: + case EbtISampler3D: + case EbtISamplerCube: + case EbtISampler2DArray: + case EbtISampler2DMS: + case EbtUSampler2D: + case EbtUSampler3D: + case EbtUSamplerCube: + case EbtUSampler2DArray: + case EbtUSampler2DMS: + case EbtSampler2D: + case EbtSampler3D: + case EbtSamplerCube: + case EbtSamplerExternalOES: + case EbtSamplerExternal2DY2YEXT: + case EbtSampler2DRect: + case EbtSampler2DArray: + case EbtSampler2DMS: + return false; + default: + assert(!IsSampler(type)); + } + + return false; +} + +inline bool IsImage2D(TBasicType type) +{ + switch (type) + { + case EbtImage2D: + case EbtIImage2D: + case EbtUImage2D: + return true; + case EbtImage3D: + case EbtIImage3D: + case EbtUImage3D: + case EbtImage2DArray: + case EbtIImage2DArray: + case EbtUImage2DArray: + case EbtImageCube: + case EbtIImageCube: + case EbtUImageCube: + return false; + default: + assert(!IsImage(type)); + } + + return false; +} + +inline bool IsImage3D(TBasicType type) +{ + switch (type) + { + case EbtImage3D: + case EbtIImage3D: + case EbtUImage3D: + return true; + case EbtImage2D: + case EbtIImage2D: + case EbtUImage2D: + case EbtImage2DArray: + case EbtIImage2DArray: + case EbtUImage2DArray: + case EbtImageCube: + case EbtIImageCube: + case EbtUImageCube: + return false; + default: + assert(!IsImage(type)); + } + + return false; +} + +inline bool IsImage2DArray(TBasicType type) +{ + switch (type) + { + case EbtImage2DArray: + case EbtIImage2DArray: + case EbtUImage2DArray: + return true; + case EbtImage2D: + case EbtIImage2D: + case EbtUImage2D: + case EbtImage3D: + case EbtIImage3D: + case EbtUImage3D: + case EbtImageCube: + case EbtIImageCube: + case EbtUImageCube: + return false; + default: + assert(!IsImage(type)); + } + + return false; +} + +inline bool IsImageCube(TBasicType type) +{ + switch (type) + { + case EbtImageCube: + case EbtIImageCube: + case EbtUImageCube: + return true; + case EbtImage2D: + case EbtIImage2D: + case EbtUImage2D: + case EbtImage3D: + case EbtIImage3D: + case EbtUImage3D: + case EbtImage2DArray: + case EbtIImage2DArray: + case EbtUImage2DArray: + return false; + default: + assert(!IsImage(type)); } return false; @@ -279,7 +584,7 @@ inline bool IsInteger(TBasicType type) inline bool SupportsPrecision(TBasicType type) { - return type == EbtFloat || type == EbtInt || type == EbtUInt || IsSampler(type); + return type == EbtFloat || type == EbtInt || type == EbtUInt || IsOpaqueType(type); } // @@ -297,6 +602,7 @@ enum TQualifier EvqVaryingIn, // readonly, fragment shaders only EvqVaryingOut, // vertex shaders only read/write EvqUniform, // Readonly, vertex and fragment + EvqBuffer, // read/write, vertex, fragment and compute shader EvqVertexIn, // Vertex shader input EvqFragmentOut, // Fragment shader output @@ -311,6 +617,7 @@ enum TQualifier // built-ins read by vertex shader EvqInstanceID, + EvqVertexID, // built-ins written by vertex shader EvqPosition, @@ -331,24 +638,77 @@ enum TQualifier EvqSecondaryFragColorEXT, // EXT_blend_func_extended EvqSecondaryFragDataEXT, // EXT_blend_func_extended + EvqViewIDOVR, // OVR_multiview + EvqViewportIndex, // gl_ViewportIndex + // built-ins written by the shader_framebuffer_fetch extension(s) EvqLastFragColor, EvqLastFragData, // GLSL ES 3.0 vertex output and fragment input - EvqSmooth, // Incomplete qualifier, smooth is the default - EvqFlat, // Incomplete qualifier - EvqSmoothOut = EvqSmooth, - EvqFlatOut = EvqFlat, + EvqSmooth, // Incomplete qualifier, smooth is the default + EvqFlat, // Incomplete qualifier + EvqCentroid, // Incomplete qualifier + EvqSmoothOut, + EvqFlatOut, EvqCentroidOut, // Implies smooth EvqSmoothIn, EvqFlatIn, EvqCentroidIn, // Implies smooth + // GLSL ES 3.1 compute shader special variables + EvqShared, + EvqComputeIn, + EvqNumWorkGroups, + EvqWorkGroupSize, + EvqWorkGroupID, + EvqLocalInvocationID, + EvqGlobalInvocationID, + EvqLocalInvocationIndex, + + // GLSL ES 3.1 memory qualifiers + EvqReadOnly, + EvqWriteOnly, + EvqCoherent, + EvqRestrict, + EvqVolatile, + + // GLSL ES 3.1 extension OES_geometry_shader qualifiers + EvqGeometryIn, + EvqGeometryOut, + EvqPerVertexIn, // gl_in + EvqPrimitiveIDIn, // gl_PrimitiveIDIn + EvqInvocationID, // gl_InvocationID + EvqPrimitiveID, // gl_PrimitiveID + EvqLayer, // gl_Layer + // end of list EvqLast }; +inline bool IsQualifierUnspecified(TQualifier qualifier) +{ + return (qualifier == EvqTemporary || qualifier == EvqGlobal); +} + +enum TLayoutImageInternalFormat +{ + EiifUnspecified, + EiifRGBA32F, + EiifRGBA16F, + EiifR32F, + EiifRGBA32UI, + EiifRGBA16UI, + EiifRGBA8UI, + EiifR32UI, + EiifRGBA32I, + EiifRGBA16I, + EiifRGBA8I, + EiifR32I, + EiifRGBA8, + EiifRGBA8_SNORM +}; + enum TLayoutMatrixPacking { EmpUnspecified, @@ -361,36 +721,165 @@ enum TLayoutBlockStorage EbsUnspecified, EbsShared, EbsPacked, - EbsStd140 + EbsStd140, + EbsStd430 +}; + +enum TYuvCscStandardEXT +{ + EycsUndefined, + EycsItu601, + EycsItu601FullRange, + EycsItu709 +}; + +enum TLayoutPrimitiveType +{ + EptUndefined, + EptPoints, + EptLines, + EptLinesAdjacency, + EptTriangles, + EptTrianglesAdjacency, + EptLineStrip, + EptTriangleStrip }; struct TLayoutQualifier { - int location; - TLayoutMatrixPacking matrixPacking; - TLayoutBlockStorage blockStorage; + // Must have a trivial default constructor since it is used in YYSTYPE. + TLayoutQualifier() = default; - static TLayoutQualifier create() - { - TLayoutQualifier layoutQualifier; - - layoutQualifier.location = -1; - layoutQualifier.matrixPacking = EmpUnspecified; - layoutQualifier.blockStorage = EbsUnspecified; - - return layoutQualifier; - } + constexpr static TLayoutQualifier Create() { return TLayoutQualifier(0); } bool isEmpty() const { - return location == -1 && matrixPacking == EmpUnspecified && blockStorage == EbsUnspecified; + return location == -1 && binding == -1 && offset == -1 && numViews == -1 && yuv == false && + matrixPacking == EmpUnspecified && blockStorage == EbsUnspecified && + !localSize.isAnyValueSet() && imageInternalFormat == EiifUnspecified && + primitiveType == EptUndefined && invocations == 0 && maxVertices == -1; + } + + bool isCombinationValid() const + { + bool workSizeSpecified = localSize.isAnyValueSet(); + bool numViewsSet = (numViews != -1); + bool geometryShaderSpecified = + (primitiveType != EptUndefined) || (invocations != 0) || (maxVertices != -1); + bool otherLayoutQualifiersSpecified = + (location != -1 || binding != -1 || matrixPacking != EmpUnspecified || + blockStorage != EbsUnspecified || imageInternalFormat != EiifUnspecified); + + // we can have either the work group size specified, or number of views, + // or yuv layout qualifier, or the other layout qualifiers. + return (workSizeSpecified ? 1 : 0) + (numViewsSet ? 1 : 0) + (yuv ? 1 : 0) + + (otherLayoutQualifiersSpecified ? 1 : 0) + (geometryShaderSpecified ? 1 : 0) <= + 1; + } + + bool isLocalSizeEqual(const sh::WorkGroupSize &localSizeIn) const + { + return localSize.isWorkGroupSizeMatching(localSizeIn); + } + + int location; + unsigned int locationsSpecified; + TLayoutMatrixPacking matrixPacking; + TLayoutBlockStorage blockStorage; + + // Compute shader layout qualifiers. + sh::WorkGroupSize localSize; + + int binding; + int offset; + + // Image format layout qualifier + TLayoutImageInternalFormat imageInternalFormat; + + // OVR_multiview num_views. + int numViews; + + // EXT_YUV_target yuv layout qualifier. + bool yuv; + + // OES_geometry_shader layout qualifiers. + TLayoutPrimitiveType primitiveType; + int invocations; + int maxVertices; + + private: + explicit constexpr TLayoutQualifier(int /*placeholder*/) + : location(-1), + locationsSpecified(0), + matrixPacking(EmpUnspecified), + blockStorage(EbsUnspecified), + localSize(-1), + binding(-1), + offset(-1), + imageInternalFormat(EiifUnspecified), + numViews(-1), + yuv(false), + primitiveType(EptUndefined), + invocations(0), + maxVertices(-1) + { } }; +struct TMemoryQualifier +{ + // Must have a trivial default constructor since it is used in YYSTYPE. + TMemoryQualifier() = default; + + bool isEmpty() const + { + return !readonly && !writeonly && !coherent && !restrictQualifier && !volatileQualifier; + } + + constexpr static TMemoryQualifier Create() { return TMemoryQualifier(0); } + + // GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers + // An image can be qualified as both readonly and writeonly. It still can be can be used with + // imageSize(). + bool readonly; + bool writeonly; + bool coherent; + + // restrict and volatile are reserved keywords in C/C++ + bool restrictQualifier; + bool volatileQualifier; + + private: + explicit constexpr TMemoryQualifier(int /*placeholder*/) + : readonly(false), + writeonly(false), + coherent(false), + restrictQualifier(false), + volatileQualifier(false) + { + } +}; + +inline const char *getWorkGroupSizeString(size_t dimension) +{ + switch (dimension) + { + case 0u: + return "local_size_x"; + case 1u: + return "local_size_y"; + case 2u: + return "local_size_z"; + default: + UNREACHABLE(); + return "dimension out of bounds"; + } +} + // -// This is just for debug print out, carried along with the definitions above. +// This is just for debug and error message print out, carried along with the definitions above. // -inline const char* getQualifierString(TQualifier q) +inline const char *getQualifierString(TQualifier q) { // clang-format off switch(q) @@ -402,6 +891,7 @@ inline const char* getQualifierString(TQualifier q) case EvqVaryingIn: return "varying"; case EvqVaryingOut: return "varying"; case EvqUniform: return "uniform"; + case EvqBuffer: return "buffer"; case EvqVertexIn: return "in"; case EvqFragmentOut: return "out"; case EvqVertexOut: return "out"; @@ -411,6 +901,7 @@ inline const char* getQualifierString(TQualifier q) case EvqInOut: return "inout"; case EvqConstReadOnly: return "const"; case EvqInstanceID: return "InstanceID"; + case EvqVertexID: return "VertexID"; case EvqPosition: return "Position"; case EvqPointSize: return "PointSize"; case EvqFragCoord: return "FragCoord"; @@ -422,54 +913,161 @@ inline const char* getQualifierString(TQualifier q) case EvqFragDepth: return "FragDepth"; case EvqSecondaryFragColorEXT: return "SecondaryFragColorEXT"; case EvqSecondaryFragDataEXT: return "SecondaryFragDataEXT"; + case EvqViewIDOVR: return "ViewIDOVR"; + case EvqViewportIndex: return "ViewportIndex"; + case EvqLayer: return "Layer"; case EvqLastFragColor: return "LastFragColor"; case EvqLastFragData: return "LastFragData"; case EvqSmoothOut: return "smooth out"; - case EvqCentroidOut: return "centroid out"; + case EvqCentroidOut: return "smooth centroid out"; case EvqFlatOut: return "flat out"; case EvqSmoothIn: return "smooth in"; case EvqFlatIn: return "flat in"; - case EvqCentroidIn: return "centroid in"; + case EvqCentroidIn: return "smooth centroid in"; + case EvqCentroid: return "centroid"; + case EvqFlat: return "flat"; + case EvqSmooth: return "smooth"; + case EvqShared: return "shared"; + case EvqComputeIn: return "in"; + case EvqNumWorkGroups: return "NumWorkGroups"; + case EvqWorkGroupSize: return "WorkGroupSize"; + case EvqWorkGroupID: return "WorkGroupID"; + case EvqLocalInvocationID: return "LocalInvocationID"; + case EvqGlobalInvocationID: return "GlobalInvocationID"; + case EvqLocalInvocationIndex: return "LocalInvocationIndex"; + case EvqReadOnly: return "readonly"; + case EvqWriteOnly: return "writeonly"; + case EvqGeometryIn: return "in"; + case EvqGeometryOut: return "out"; + case EvqPerVertexIn: return "gl_in"; default: UNREACHABLE(); return "unknown qualifier"; } // clang-format on } -inline const char* getMatrixPackingString(TLayoutMatrixPacking mpq) +inline const char *getMatrixPackingString(TLayoutMatrixPacking mpq) { switch (mpq) { - case EmpUnspecified: return "mp_unspecified"; - case EmpRowMajor: return "row_major"; - case EmpColumnMajor: return "column_major"; - default: UNREACHABLE(); return "unknown matrix packing"; + case EmpUnspecified: + return "mp_unspecified"; + case EmpRowMajor: + return "row_major"; + case EmpColumnMajor: + return "column_major"; + default: + UNREACHABLE(); + return "unknown matrix packing"; } } -inline const char* getBlockStorageString(TLayoutBlockStorage bsq) +inline const char *getBlockStorageString(TLayoutBlockStorage bsq) { switch (bsq) { - case EbsUnspecified: return "bs_unspecified"; - case EbsShared: return "shared"; - case EbsPacked: return "packed"; - case EbsStd140: return "std140"; - default: UNREACHABLE(); return "unknown block storage"; + case EbsUnspecified: + return "bs_unspecified"; + case EbsShared: + return "shared"; + case EbsPacked: + return "packed"; + case EbsStd140: + return "std140"; + case EbsStd430: + return "std430"; + default: + UNREACHABLE(); + return "unknown block storage"; } } -inline const char* getInterpolationString(TQualifier q) +inline const char *getImageInternalFormatString(TLayoutImageInternalFormat iifq) { - switch(q) + switch (iifq) { - case EvqSmoothOut: return "smooth"; break; - case EvqCentroidOut: return "centroid"; break; - case EvqFlatOut: return "flat"; break; - case EvqSmoothIn: return "smooth"; break; - case EvqCentroidIn: return "centroid"; break; - case EvqFlatIn: return "flat"; break; - default: UNREACHABLE(); return "unknown interpolation"; + case EiifRGBA32F: + return "rgba32f"; + case EiifRGBA16F: + return "rgba16f"; + case EiifR32F: + return "r32f"; + case EiifRGBA32UI: + return "rgba32ui"; + case EiifRGBA16UI: + return "rgba16ui"; + case EiifRGBA8UI: + return "rgba8ui"; + case EiifR32UI: + return "r32ui"; + case EiifRGBA32I: + return "rgba32i"; + case EiifRGBA16I: + return "rgba16i"; + case EiifRGBA8I: + return "rgba8i"; + case EiifR32I: + return "r32i"; + case EiifRGBA8: + return "rgba8"; + case EiifRGBA8_SNORM: + return "rgba8_snorm"; + default: + UNREACHABLE(); + return "unknown internal image format"; } } -#endif // COMPILER_TRANSLATOR_BASETYPES_H_ +inline TYuvCscStandardEXT getYuvCscStandardEXT(const std::string &str) +{ + if (str == "itu_601") + return EycsItu601; + else if (str == "itu_601_full_range") + return EycsItu601FullRange; + else if (str == "itu_709") + return EycsItu709; + return EycsUndefined; +} + +inline const char *getYuvCscStandardEXTString(TYuvCscStandardEXT ycsq) +{ + switch (ycsq) + { + case EycsItu601: + return "itu_601"; + case EycsItu601FullRange: + return "itu_601_full_range"; + case EycsItu709: + return "itu_709"; + default: + UNREACHABLE(); + return "unknown color space conversion standard"; + } +} + +inline const char *getGeometryShaderPrimitiveTypeString(TLayoutPrimitiveType primitiveType) +{ + switch (primitiveType) + { + case EptPoints: + return "points"; + case EptLines: + return "lines"; + case EptTriangles: + return "triangles"; + case EptLinesAdjacency: + return "lines_adjacency"; + case EptTrianglesAdjacency: + return "triangles_adjacency"; + case EptLineStrip: + return "line_strip"; + case EptTriangleStrip: + return "triangle_strip"; + default: + UNREACHABLE(); + return "unknown geometry shader primitive type"; + } +} + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_BASETYPES_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp b/src/3rdparty/angle/src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp new file mode 100644 index 0000000000..d6a1e025de --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp @@ -0,0 +1,107 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// BreakVariableAliasingInInnerLoops.h: To optimize simple assignments, the HLSL compiler frontend +// may record a variable as aliasing another. Sometimes the alias information gets garbled +// so we work around this issue by breaking the aliasing chain in inner loops. + +#include "BreakVariableAliasingInInnerLoops.h" + +#include "compiler/translator/IntermNode_util.h" +#include "compiler/translator/IntermTraverse.h" + +// A HLSL compiler developer gave us more details on the root cause and the workaround needed: +// The root problem is that if the HLSL compiler is applying aliasing information even on +// incomplete simulations (in this case, a single pass). The bug is triggered by an assignment +// that comes from a series of assignments, possibly with swizzled or ternary operators with +// known conditionals, where the source is before the loop. +// So, a workaround is to add a +0 term to variables the first time they are assigned to in +// an inner loop (if they are declared in an outside scope, otherwise there is no need). +// This will break the aliasing chain. + +// For simplicity here we add a +0 to any assignment that is in at least two nested loops. Because +// the bug only shows up with swizzles, and ternary assignment, whole array or whole structure +// assignment don't need a workaround. + +namespace sh +{ + +namespace +{ + +class AliasingBreaker : public TIntermTraverser +{ + public: + AliasingBreaker() : TIntermTraverser(true, false, true) {} + + protected: + bool visitBinary(Visit visit, TIntermBinary *binary) + { + if (visit != PreVisit) + { + return false; + } + + if (mLoopLevel < 2 || !binary->isAssignment()) + { + return true; + } + + TIntermTyped *B = binary->getRight(); + TType type = B->getType(); + + if (!type.isScalar() && !type.isVector() && !type.isMatrix()) + { + return true; + } + + if (type.isArray() || IsSampler(type.getBasicType())) + { + return true; + } + + // We have a scalar / vector / matrix assignment with loop depth 2. + // Transform it from + // A = B + // to + // A = (B + typeof(0)); + + TIntermBinary *bPlusZero = new TIntermBinary(EOpAdd, B, CreateZeroNode(type)); + bPlusZero->setLine(B->getLine()); + + binary->replaceChildNode(B, bPlusZero); + + return true; + } + + bool visitLoop(Visit visit, TIntermLoop *loop) + { + if (visit == PreVisit) + { + mLoopLevel++; + } + else + { + ASSERT(mLoopLevel > 0); + mLoopLevel--; + } + + return true; + } + + private: + int mLoopLevel = 0; +}; + +} // anonymous namespace + +void BreakVariableAliasingInInnerLoops(TIntermNode *root) +{ + AliasingBreaker breaker; + root->traverse(&breaker); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/BreakVariableAliasingInInnerLoops.h b/src/3rdparty/angle/src/compiler/translator/BreakVariableAliasingInInnerLoops.h new file mode 100644 index 0000000000..b1d906f919 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/BreakVariableAliasingInInnerLoops.h @@ -0,0 +1,23 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// BreakVariableAliasingInInnerLoops.h: To optimize simple assignments, the HLSL compiler frontend +// may record a variable as aliasing another. Sometimes the alias information gets garbled +// so we work around this issue by breaking the aliasing chain in inner loops. + +#ifndef COMPILER_TRANSLATOR_BREAKVARIABLEALIASINGININNERLOOPS_H_ +#define COMPILER_TRANSLATOR_BREAKVARIABLEALIASINGININNERLOOPS_H_ + +class TIntermNode; + +namespace sh +{ + +void BreakVariableAliasingInInnerLoops(TIntermNode *root); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_BREAKVARIABLEALIASINGININNERLOOPS_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp b/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp index 0c7f149ee6..905e634fd1 100644 --- a/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp +++ b/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulator.cpp @@ -4,16 +4,20 @@ // found in the LICENSE file. // -#include "angle_gl.h" #include "compiler/translator/BuiltInFunctionEmulator.h" +#include "angle_gl.h" +#include "compiler/translator/Cache.h" +#include "compiler/translator/IntermTraverse.h" #include "compiler/translator/SymbolTable.h" +namespace sh +{ + class BuiltInFunctionEmulator::BuiltInFunctionEmulationMarker : public TIntermTraverser { public: BuiltInFunctionEmulationMarker(BuiltInFunctionEmulator &emulator) - : TIntermTraverser(true, false, false), - mEmulator(emulator) + : TIntermTraverser(true, false, false), mEmulator(emulator) { } @@ -21,7 +25,8 @@ class BuiltInFunctionEmulator::BuiltInFunctionEmulationMarker : public TIntermTr { if (visit == PreVisit) { - bool needToEmulate = mEmulator.SetFunctionCalled(node->getOp(), node->getOperand()->getType()); + bool needToEmulate = + mEmulator.setFunctionCalled(node->getOp(), node->getOperand()->getType()); if (needToEmulate) node->setUseEmulatedFunction(); } @@ -32,48 +37,23 @@ class BuiltInFunctionEmulator::BuiltInFunctionEmulationMarker : public TIntermTr { if (visit == PreVisit) { - // Here we handle all the built-in functions instead of the ones we + // Here we handle all the built-in functions mapped to ops, not just the ones that are // currently identified as problematic. - switch (node->getOp()) + if (node->isConstructor() || node->isFunctionCall()) { - case EOpLessThan: - case EOpGreaterThan: - case EOpLessThanEqual: - case EOpGreaterThanEqual: - case EOpVectorEqual: - case EOpVectorNotEqual: - case EOpMod: - case EOpPow: - case EOpAtan: - case EOpMin: - case EOpMax: - case EOpClamp: - case EOpMix: - case EOpStep: - case EOpSmoothStep: - case EOpDistance: - case EOpDot: - case EOpCross: - case EOpFaceForward: - case EOpReflect: - case EOpRefract: - case EOpOuterProduct: - case EOpMul: - break; - default: - return true; + return true; } const TIntermSequence &sequence = *(node->getSequence()); - bool needToEmulate = false; - // Right now we only handle built-in functions with two or three parameters. + bool needToEmulate = false; + // Right now we only handle built-in functions with two to four parameters. if (sequence.size() == 2) { TIntermTyped *param1 = sequence[0]->getAsTyped(); TIntermTyped *param2 = sequence[1]->getAsTyped(); if (!param1 || !param2) return true; - needToEmulate = mEmulator.SetFunctionCalled( - node->getOp(), param1->getType(), param2->getType()); + needToEmulate = mEmulator.setFunctionCalled(node->getOp(), param1->getType(), + param2->getType()); } else if (sequence.size() == 3) { @@ -82,8 +62,20 @@ class BuiltInFunctionEmulator::BuiltInFunctionEmulationMarker : public TIntermTr TIntermTyped *param3 = sequence[2]->getAsTyped(); if (!param1 || !param2 || !param3) return true; - needToEmulate = mEmulator.SetFunctionCalled( - node->getOp(), param1->getType(), param2->getType(), param3->getType()); + needToEmulate = mEmulator.setFunctionCalled(node->getOp(), param1->getType(), + param2->getType(), param3->getType()); + } + else if (sequence.size() == 4) + { + TIntermTyped *param1 = sequence[0]->getAsTyped(); + TIntermTyped *param2 = sequence[1]->getAsTyped(); + TIntermTyped *param3 = sequence[2]->getAsTyped(); + TIntermTyped *param4 = sequence[3]->getAsTyped(); + if (!param1 || !param2 || !param3 || !param4) + return true; + needToEmulate = + mEmulator.setFunctionCalled(node->getOp(), param1->getType(), param2->getType(), + param3->getType(), param4->getType()); } else { @@ -101,130 +93,245 @@ class BuiltInFunctionEmulator::BuiltInFunctionEmulationMarker : public TIntermTr }; BuiltInFunctionEmulator::BuiltInFunctionEmulator() -{} - -void BuiltInFunctionEmulator::addEmulatedFunction(TOperator op, const TType *param, - const char *emulatedFunctionDefinition) { - mEmulatedFunctions[FunctionId(op, param)] = std::string(emulatedFunctionDefinition); } -void BuiltInFunctionEmulator::addEmulatedFunction(TOperator op, const TType *param1, const TType *param2, - const char *emulatedFunctionDefinition) +FunctionId BuiltInFunctionEmulator::addEmulatedFunction(TOperator op, + const TType *param, + const char *emulatedFunctionDefinition) { - mEmulatedFunctions[FunctionId(op, param1, param2)] = std::string(emulatedFunctionDefinition); + FunctionId id(op, param); + mEmulatedFunctions[id] = std::string(emulatedFunctionDefinition); + return id; } -void BuiltInFunctionEmulator::addEmulatedFunction(TOperator op, const TType *param1, const TType *param2, - const TType *param3, const char *emulatedFunctionDefinition) +FunctionId BuiltInFunctionEmulator::addEmulatedFunction(TOperator op, + const TType *param1, + const TType *param2, + const char *emulatedFunctionDefinition) { - mEmulatedFunctions[FunctionId(op, param1, param2, param3)] = std::string(emulatedFunctionDefinition); + FunctionId id(op, param1, param2); + mEmulatedFunctions[id] = std::string(emulatedFunctionDefinition); + return id; } -bool BuiltInFunctionEmulator::IsOutputEmpty() const +FunctionId BuiltInFunctionEmulator::addEmulatedFunctionWithDependency( + const FunctionId &dependency, + TOperator op, + const TType *param1, + const TType *param2, + const char *emulatedFunctionDefinition) +{ + FunctionId id(op, param1, param2); + mEmulatedFunctions[id] = std::string(emulatedFunctionDefinition); + mFunctionDependencies[id] = dependency; + return id; +} + +FunctionId BuiltInFunctionEmulator::addEmulatedFunction(TOperator op, + const TType *param1, + const TType *param2, + const TType *param3, + const char *emulatedFunctionDefinition) +{ + FunctionId id(op, param1, param2, param3); + mEmulatedFunctions[id] = std::string(emulatedFunctionDefinition); + return id; +} + +FunctionId BuiltInFunctionEmulator::addEmulatedFunction(TOperator op, + const TType *param1, + const TType *param2, + const TType *param3, + const TType *param4, + const char *emulatedFunctionDefinition) +{ + FunctionId id(op, param1, param2, param3, param4); + mEmulatedFunctions[id] = std::string(emulatedFunctionDefinition); + return id; +} + +FunctionId BuiltInFunctionEmulator::addEmulatedFunctionWithDependency( + const FunctionId &dependency, + TOperator op, + const TType *param1, + const TType *param2, + const TType *param3, + const TType *param4, + const char *emulatedFunctionDefinition) +{ + FunctionId id(op, param1, param2, param3, param4); + mEmulatedFunctions[id] = std::string(emulatedFunctionDefinition); + mFunctionDependencies[id] = dependency; + return id; +} + +bool BuiltInFunctionEmulator::isOutputEmpty() const { return (mFunctions.size() == 0); } -void BuiltInFunctionEmulator::OutputEmulatedFunctions(TInfoSinkBase &out) const +void BuiltInFunctionEmulator::outputEmulatedFunctions(TInfoSinkBase &out) const { + for (const auto &function : mFunctions) + { + const char *body = findEmulatedFunction(function); + ASSERT(body); + out << body; + out << "\n\n"; + } +} + +bool BuiltInFunctionEmulator::setFunctionCalled(TOperator op, const TType ¶m) +{ + return setFunctionCalled(FunctionId(op, ¶m)); +} + +bool BuiltInFunctionEmulator::setFunctionCalled(TOperator op, + const TType ¶m1, + const TType ¶m2) +{ + return setFunctionCalled(FunctionId(op, ¶m1, ¶m2)); +} + +bool BuiltInFunctionEmulator::setFunctionCalled(TOperator op, + const TType ¶m1, + const TType ¶m2, + const TType ¶m3) +{ + return setFunctionCalled(FunctionId(op, ¶m1, ¶m2, ¶m3)); +} + +bool BuiltInFunctionEmulator::setFunctionCalled(TOperator op, + const TType ¶m1, + const TType ¶m2, + const TType ¶m3, + const TType ¶m4) +{ + return setFunctionCalled(FunctionId(op, ¶m1, ¶m2, ¶m3, ¶m4)); +} + +const char *BuiltInFunctionEmulator::findEmulatedFunction(const FunctionId &functionId) const +{ + for (const auto &queryFunction : mQueryFunctions) + { + const char *result = queryFunction(functionId); + if (result) + { + return result; + } + } + + const auto &result = mEmulatedFunctions.find(functionId); + if (result != mEmulatedFunctions.end()) + { + return result->second.c_str(); + } + + return nullptr; +} + +bool BuiltInFunctionEmulator::setFunctionCalled(const FunctionId &functionId) +{ + if (!findEmulatedFunction(functionId)) + { + return false; + } + for (size_t i = 0; i < mFunctions.size(); ++i) { - out << mEmulatedFunctions.find(mFunctions[i])->second << "\n\n"; + if (mFunctions[i] == functionId) + return true; } -} - -bool BuiltInFunctionEmulator::SetFunctionCalled(TOperator op, const TType ¶m) -{ - return SetFunctionCalled(FunctionId(op, ¶m)); -} - -bool BuiltInFunctionEmulator::SetFunctionCalled(TOperator op, const TType ¶m1, const TType ¶m2) -{ - return SetFunctionCalled(FunctionId(op, ¶m1, ¶m2)); -} - -bool BuiltInFunctionEmulator::SetFunctionCalled(TOperator op, - const TType ¶m1, const TType ¶m2, const TType ¶m3) -{ - return SetFunctionCalled(FunctionId(op, ¶m1, ¶m2, ¶m3)); -} - -bool BuiltInFunctionEmulator::SetFunctionCalled(const FunctionId &functionId) -{ - if (mEmulatedFunctions.find(functionId) != mEmulatedFunctions.end()) + // If the function depends on another, mark the dependency as called. + auto dependency = mFunctionDependencies.find(functionId); + if (dependency != mFunctionDependencies.end()) { - for (size_t i = 0; i < mFunctions.size(); ++i) - { - if (mFunctions[i] == functionId) - return true; - } - // Copy the functionId if it needs to be stored, to make sure that the TType pointers inside - // remain valid and constant. - mFunctions.push_back(functionId.getCopy()); - return true; + setFunctionCalled((*dependency).second); } - return false; + // Copy the functionId if it needs to be stored, to make sure that the TType pointers inside + // remain valid and constant. + mFunctions.push_back(functionId.getCopy()); + return true; } -void BuiltInFunctionEmulator::MarkBuiltInFunctionsForEmulation(TIntermNode *root) +void BuiltInFunctionEmulator::markBuiltInFunctionsForEmulation(TIntermNode *root) { ASSERT(root); - if (mEmulatedFunctions.empty()) + if (mEmulatedFunctions.empty() && mQueryFunctions.empty()) return; BuiltInFunctionEmulationMarker marker(*this); root->traverse(&marker); } -void BuiltInFunctionEmulator::Cleanup() +void BuiltInFunctionEmulator::cleanup() { mFunctions.clear(); + mFunctionDependencies.clear(); } -//static -TString BuiltInFunctionEmulator::GetEmulatedFunctionName( - const TString &name) +void BuiltInFunctionEmulator::addFunctionMap(BuiltinQueryFunc queryFunc) { - ASSERT(name[name.length() - 1] == '('); - return "webgl_" + name.substr(0, name.length() - 1) + "_emu("; + mQueryFunctions.push_back(queryFunc); } -BuiltInFunctionEmulator::FunctionId::FunctionId(TOperator op, const TType *param) +// static +void BuiltInFunctionEmulator::WriteEmulatedFunctionName(TInfoSinkBase &out, const char *name) +{ + ASSERT(name[strlen(name) - 1] != '('); + out << name << "_emu"; +} + +FunctionId::FunctionId() + : mOp(EOpNull), + mParam1(TCache::getType(EbtVoid)), + mParam2(TCache::getType(EbtVoid)), + mParam3(TCache::getType(EbtVoid)), + mParam4(TCache::getType(EbtVoid)) +{ +} + +FunctionId::FunctionId(TOperator op, const TType *param) : mOp(op), mParam1(param), - mParam2(new TType(EbtVoid)), - mParam3(new TType(EbtVoid)) + mParam2(TCache::getType(EbtVoid)), + mParam3(TCache::getType(EbtVoid)), + mParam4(TCache::getType(EbtVoid)) { } -BuiltInFunctionEmulator::FunctionId::FunctionId(TOperator op, const TType *param1, const TType *param2) +FunctionId::FunctionId(TOperator op, const TType *param1, const TType *param2) : mOp(op), mParam1(param1), mParam2(param2), - mParam3(new TType(EbtVoid)) + mParam3(TCache::getType(EbtVoid)), + mParam4(TCache::getType(EbtVoid)) { } -BuiltInFunctionEmulator::FunctionId::FunctionId(TOperator op, - const TType *param1, const TType *param2, const TType *param3) - : mOp(op), - mParam1(param1), - mParam2(param2), - mParam3(param3) +FunctionId::FunctionId(TOperator op, const TType *param1, const TType *param2, const TType *param3) + : mOp(op), mParam1(param1), mParam2(param2), mParam3(param3), mParam4(TCache::getType(EbtVoid)) { } -bool BuiltInFunctionEmulator::FunctionId::operator==(const BuiltInFunctionEmulator::FunctionId &other) const +FunctionId::FunctionId(TOperator op, + const TType *param1, + const TType *param2, + const TType *param3, + const TType *param4) + : mOp(op), mParam1(param1), mParam2(param2), mParam3(param3), mParam4(param4) { - return (mOp == other.mOp && - *mParam1 == *other.mParam1 && - *mParam2 == *other.mParam2 && - *mParam3 == *other.mParam3); } -bool BuiltInFunctionEmulator::FunctionId::operator<(const BuiltInFunctionEmulator::FunctionId &other) const +bool FunctionId::operator==(const FunctionId &other) const +{ + return (mOp == other.mOp && *mParam1 == *other.mParam1 && *mParam2 == *other.mParam2 && + *mParam3 == *other.mParam3 && *mParam4 == *other.mParam4); +} + +bool FunctionId::operator<(const FunctionId &other) const { if (mOp != other.mOp) return mOp < other.mOp; @@ -233,11 +340,16 @@ bool BuiltInFunctionEmulator::FunctionId::operator<(const BuiltInFunctionEmulato if (*mParam2 != *other.mParam2) return *mParam2 < *other.mParam2; if (*mParam3 != *other.mParam3) - return *mParam3 < *other.mParam3; - return false; // all fields are equal + return *mParam3 < *other.mParam3; + if (*mParam4 != *other.mParam4) + return *mParam4 < *other.mParam4; + return false; // all fields are equal } -BuiltInFunctionEmulator::FunctionId BuiltInFunctionEmulator::FunctionId::getCopy() const +FunctionId FunctionId::getCopy() const { - return FunctionId(mOp, new TType(*mParam1), new TType(*mParam2), new TType(*mParam3)); + return FunctionId(mOp, new TType(*mParam1), new TType(*mParam2), new TType(*mParam3), + new TType(*mParam4)); } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulator.h b/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulator.h index 6976edfd57..5f15f66224 100644 --- a/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulator.h +++ b/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulator.h @@ -9,77 +9,175 @@ #include "compiler/translator/InfoSink.h" #include "compiler/translator/IntermNode.h" +#include "compiler/translator/ParamType.h" + +namespace sh +{ + +struct MiniFunctionId +{ + constexpr MiniFunctionId(TOperator op = EOpNull, + ParamType paramType1 = ParamType::Void, + ParamType paramType2 = ParamType::Void, + ParamType paramType3 = ParamType::Void, + ParamType paramType4 = ParamType::Void) + : op(op), + paramType1(paramType1), + paramType2(paramType2), + paramType3(paramType3), + paramType4(paramType4) + { + } + + TOperator op; + ParamType paramType1; + ParamType paramType2; + ParamType paramType3; + ParamType paramType4; +}; + +class FunctionId final +{ + public: + FunctionId(); + FunctionId(TOperator op, const TType *param); + FunctionId(TOperator op, const TType *param1, const TType *param2); + FunctionId(TOperator op, const TType *param1, const TType *param2, const TType *param3); + FunctionId(TOperator op, + const TType *param1, + const TType *param2, + const TType *param3, + const TType *param4); + + FunctionId(const FunctionId &) = default; + FunctionId &operator=(const FunctionId &) = default; + + bool operator==(const FunctionId &other) const; + bool operator<(const FunctionId &other) const; + + FunctionId getCopy() const; + + private: + friend bool operator==(const MiniFunctionId &miniId, const FunctionId &functionId); + TOperator mOp; + + // The memory that these TType objects use is freed by PoolAllocator. The + // BuiltInFunctionEmulator's lifetime can extend until after the memory pool is freed, but + // that's not an issue since this class never destructs these objects. + const TType *mParam1; + const TType *mParam2; + const TType *mParam3; + const TType *mParam4; +}; + +inline bool operator==(ParamType paramType, const TType *type) +{ + return SameParamType(paramType, type->getBasicType(), type->getNominalSize(), + type->getSecondarySize()); +} + +inline bool operator==(const MiniFunctionId &miniId, const FunctionId &functionId) +{ + return miniId.op == functionId.mOp && miniId.paramType1 == functionId.mParam1 && + miniId.paramType2 == functionId.mParam2 && miniId.paramType3 == functionId.mParam3 && + miniId.paramType4 == functionId.mParam4; +} + +using BuiltinQueryFunc = const char *(const FunctionId &); // -// This class decides which built-in functions need to be replaced with the -// emulated ones. -// It can be used to work around driver bugs or implement functions that are -// not natively implemented on a specific platform. +// This class decides which built-in functions need to be replaced with the emulated ones. It can be +// used to work around driver bugs or implement functions that are not natively implemented on a +// specific platform. // class BuiltInFunctionEmulator { public: BuiltInFunctionEmulator(); - void MarkBuiltInFunctionsForEmulation(TIntermNode *root); + void markBuiltInFunctionsForEmulation(TIntermNode *root); - void Cleanup(); + void cleanup(); - // "name(" becomes "webgl_name_emu(". - static TString GetEmulatedFunctionName(const TString &name); + // "name" gets written as "name_emu". + static void WriteEmulatedFunctionName(TInfoSinkBase &out, const char *name); - bool IsOutputEmpty() const; + bool isOutputEmpty() const; - // Output function emulation definition. This should be before any other - // shader source. - void OutputEmulatedFunctions(TInfoSinkBase &out) const; + // Output function emulation definition. This should be before any other shader source. + void outputEmulatedFunctions(TInfoSinkBase &out) const; // Add functions that need to be emulated. - void addEmulatedFunction(TOperator op, const TType *param, const char *emulatedFunctionDefinition); - void addEmulatedFunction(TOperator op, const TType *param1, const TType *param2, - const char *emulatedFunctionDefinition); - void addEmulatedFunction(TOperator op, const TType *param1, const TType *param2, const TType *param3, - const char *emulatedFunctionDefinition); + FunctionId addEmulatedFunction(TOperator op, + const TType *param, + const char *emulatedFunctionDefinition); + FunctionId addEmulatedFunction(TOperator op, + const TType *param1, + const TType *param2, + const char *emulatedFunctionDefinition); + FunctionId addEmulatedFunction(TOperator op, + const TType *param1, + const TType *param2, + const TType *param3, + const char *emulatedFunctionDefinition); + FunctionId addEmulatedFunction(TOperator op, + const TType *param1, + const TType *param2, + const TType *param3, + const TType *param4, + const char *emulatedFunctionDefinition); + + FunctionId addEmulatedFunctionWithDependency(const FunctionId &dependency, + TOperator op, + const TType *param1, + const TType *param2, + const char *emulatedFunctionDefinition); + FunctionId addEmulatedFunctionWithDependency(const FunctionId &dependency, + TOperator op, + const TType *param1, + const TType *param2, + const TType *param3, + const TType *param4, + const char *emulatedFunctionDefinition); + + void addFunctionMap(BuiltinQueryFunc queryFunc); private: class BuiltInFunctionEmulationMarker; - // Records that a function is called by the shader and might need to be - // emulated. If the function is not in mEmulatedFunctions, this becomes a - // no-op. Returns true if the function call needs to be replaced with an - // emulated one. - bool SetFunctionCalled(TOperator op, const TType ¶m); - bool SetFunctionCalled(TOperator op, const TType ¶m1, const TType ¶m2); - bool SetFunctionCalled(TOperator op, const TType ¶m1, const TType ¶m2, const TType ¶m3); + // Records that a function is called by the shader and might need to be emulated. If the + // function is not in mEmulatedFunctions, this becomes a no-op. Returns true if the function + // call needs to be replaced with an emulated one. + bool setFunctionCalled(TOperator op, const TType ¶m); + bool setFunctionCalled(TOperator op, const TType ¶m1, const TType ¶m2); + bool setFunctionCalled(TOperator op, + const TType ¶m1, + const TType ¶m2, + const TType ¶m3); + bool setFunctionCalled(TOperator op, + const TType ¶m1, + const TType ¶m2, + const TType ¶m3, + const TType ¶m4); - class FunctionId { - public: - FunctionId(TOperator op, const TType *param); - FunctionId(TOperator op, const TType *param1, const TType *param2); - FunctionId(TOperator op, const TType *param1, const TType *param2, const TType *param3); + bool setFunctionCalled(const FunctionId &functionId); - bool operator==(const FunctionId &other) const; - bool operator<(const FunctionId &other) const; - - FunctionId getCopy() const; - private: - TOperator mOp; - - // The memory that these TType objects use is freed by PoolAllocator. The BuiltInFunctionEmulator's lifetime - // can extend until after the memory pool is freed, but that's not an issue since this class never destructs - // these objects. - const TType *mParam1; - const TType *mParam2; - const TType *mParam3; - }; - - bool SetFunctionCalled(const FunctionId &functionId); + const char *findEmulatedFunction(const FunctionId &functionId) const; // Map from function id to emulated function definition std::map mEmulatedFunctions; + // Map from dependent functions to their dependencies. This structure allows each function to + // have at most one dependency. + std::map mFunctionDependencies; + // Called function ids std::vector mFunctions; + + // Constexpr function tables. + std::vector mQueryFunctions; }; +} // namespace sh + #endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATOR_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp b/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp index 098560d110..27ee04da35 100644 --- a/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp +++ b/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp @@ -11,47 +11,147 @@ #include "compiler/translator/SymbolTable.h" #include "compiler/translator/VersionGLSL.h" -void InitBuiltInFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu, sh::GLenum shaderType) +namespace sh { - // we use macros here instead of function definitions to work around more GLSL - // compiler bugs, in particular on NVIDIA hardware on Mac OSX. Macros are - // problematic because if the argument has side-effects they will be repeatedly - // evaluated. This is unlikely to show up in real shaders, but is something to - // consider. + +void InitBuiltInAbsFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu, + sh::GLenum shaderType) +{ + if (shaderType == GL_VERTEX_SHADER) + { + const TType *int1 = TCache::getType(EbtInt); + emu->addEmulatedFunction(EOpAbs, int1, "int abs_emu(int x) { return x * sign(x); }"); + } +} + +void InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu, + int targetGLSLVersion) +{ + // isnan() is supported since GLSL 1.3. + if (targetGLSLVersion < GLSL_VERSION_130) + return; const TType *float1 = TCache::getType(EbtFloat); const TType *float2 = TCache::getType(EbtFloat, 2); const TType *float3 = TCache::getType(EbtFloat, 3); const TType *float4 = TCache::getType(EbtFloat, 4); - if (shaderType == GL_FRAGMENT_SHADER) + // !(x > 0.0 || x < 0.0 || x == 0.0) will be optimized and always equal to false. + emu->addEmulatedFunction( + EOpIsNan, float1, + "bool isnan_emu(float x) { return (x > 0.0 || x < 0.0) ? false : x != 0.0; }"); + emu->addEmulatedFunction( + EOpIsNan, float2, + "bvec2 isnan_emu(vec2 x)\n" + "{\n" + " bvec2 isnan;\n" + " for (int i = 0; i < 2; i++)\n" + " {\n" + " isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n" + " }\n" + " return isnan;\n" + "}\n"); + emu->addEmulatedFunction( + EOpIsNan, float3, + "bvec3 isnan_emu(vec3 x)\n" + "{\n" + " bvec3 isnan;\n" + " for (int i = 0; i < 3; i++)\n" + " {\n" + " isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n" + " }\n" + " return isnan;\n" + "}\n"); + emu->addEmulatedFunction( + EOpIsNan, float4, + "bvec4 isnan_emu(vec4 x)\n" + "{\n" + " bvec4 isnan;\n" + " for (int i = 0; i < 4; i++)\n" + " {\n" + " isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n" + " }\n" + " return isnan;\n" + "}\n"); +} + +void InitBuiltInAtanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu) +{ + const TType *float1 = TCache::getType(EbtFloat); + auto floatFuncId = emu->addEmulatedFunction( + EOpAtan, float1, float1, + "emu_precision float atan_emu(emu_precision float y, emu_precision " + "float x)\n" + "{\n" + " if (x > 0.0) return atan(y / x);\n" + " else if (x < 0.0 && y >= 0.0) return atan(y / x) + 3.14159265;\n" + " else if (x < 0.0 && y < 0.0) return atan(y / x) - 3.14159265;\n" + " else return 1.57079632 * sign(y);\n" + "}\n"); + for (int dim = 2; dim <= 4; ++dim) { - emu->addEmulatedFunction(EOpCos, float1, "webgl_emu_precision float webgl_cos_emu(webgl_emu_precision float a) { return cos(a); }"); - emu->addEmulatedFunction(EOpCos, float2, "webgl_emu_precision vec2 webgl_cos_emu(webgl_emu_precision vec2 a) { return cos(a); }"); - emu->addEmulatedFunction(EOpCos, float3, "webgl_emu_precision vec3 webgl_cos_emu(webgl_emu_precision vec3 a) { return cos(a); }"); - emu->addEmulatedFunction(EOpCos, float4, "webgl_emu_precision vec4 webgl_cos_emu(webgl_emu_precision vec4 a) { return cos(a); }"); + const TType *floatVec = TCache::getType(EbtFloat, static_cast(dim)); + std::stringstream ss; + ss << "emu_precision vec" << dim << " atan_emu(emu_precision vec" << dim + << " y, emu_precision vec" << dim << " x)\n" + << "{\n" + " return vec" + << dim << "("; + for (int i = 0; i < dim; ++i) + { + ss << "atan_emu(y[" << i << "], x[" << i << "])"; + if (i < dim - 1) + { + ss << ", "; + } + } + ss << ");\n" + "}\n"; + emu->addEmulatedFunctionWithDependency(floatFuncId, EOpAtan, floatVec, floatVec, + ss.str().c_str()); } - emu->addEmulatedFunction(EOpDistance, float1, float1, "#define webgl_distance_emu(x, y) ((x) >= (y) ? (x) - (y) : (y) - (x))"); - emu->addEmulatedFunction(EOpDot, float1, float1, "#define webgl_dot_emu(x, y) ((x) * (y))"); - emu->addEmulatedFunction(EOpLength, float1, "#define webgl_length_emu(x) ((x) >= 0.0 ? (x) : -(x))"); - emu->addEmulatedFunction(EOpNormalize, float1, "#define webgl_normalize_emu(x) ((x) == 0.0 ? 0.0 : ((x) > 0.0 ? 1.0 : -1.0))"); - emu->addEmulatedFunction(EOpReflect, float1, float1, "#define webgl_reflect_emu(I, N) ((I) - 2.0 * (N) * (I) * (N))"); } // Emulate built-in functions missing from GLSL 1.30 and higher -void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator *emu, sh::GLenum shaderType, +void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator *emu, + sh::GLenum shaderType, int targetGLSLVersion) { + // Emulate packUnorm2x16 and unpackUnorm2x16 (GLSL 4.10) + if (targetGLSLVersion < GLSL_VERSION_410) + { + const TType *float2 = TCache::getType(EbtFloat, 2); + const TType *uint1 = TCache::getType(EbtUInt); + + // clang-format off + emu->addEmulatedFunction(EOpPackUnorm2x16, float2, + "uint packUnorm2x16_emu(vec2 v)\n" + "{\n" + " int x = int(round(clamp(v.x, 0.0, 1.0) * 65535.0));\n" + " int y = int(round(clamp(v.y, 0.0, 1.0) * 65535.0));\n" + " return uint((y << 16) | (x & 0xFFFF));\n" + "}\n"); + + emu->addEmulatedFunction(EOpUnpackUnorm2x16, uint1, + "vec2 unpackUnorm2x16_emu(uint u)\n" + "{\n" + " float x = float(u & 0xFFFFu) / 65535.0;\n" + " float y = float(u >> 16) / 65535.0;\n" + " return vec2(x, y);\n" + "}\n"); + // clang-format on + } + // Emulate packSnorm2x16, packHalf2x16, unpackSnorm2x16, and unpackHalf2x16 (GLSL 4.20) // by using floatBitsToInt, floatBitsToUint, intBitsToFloat, and uintBitsToFloat (GLSL 3.30). if (targetGLSLVersion >= GLSL_VERSION_330 && targetGLSLVersion < GLSL_VERSION_420) { const TType *float2 = TCache::getType(EbtFloat, 2); - const TType *uint1 = TCache::getType(EbtUInt); + const TType *uint1 = TCache::getType(EbtUInt); // clang-format off emu->addEmulatedFunction(EOpPackSnorm2x16, float2, - "uint webgl_packSnorm2x16_emu(vec2 v)\n" + "uint packSnorm2x16_emu(vec2 v)\n" "{\n" " #if defined(GL_ARB_shading_language_packing)\n" " return packSnorm2x16(v);\n" @@ -63,28 +163,28 @@ void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator "}\n"); emu->addEmulatedFunction(EOpUnpackSnorm2x16, uint1, "#if !defined(GL_ARB_shading_language_packing)\n" - " float webgl_fromSnorm(uint x)\n" + " float fromSnorm(uint x)\n" " {\n" " int xi = (int(x) & 0x7FFF) - (int(x) & 0x8000);\n" " return clamp(float(xi) / 32767.0, -1.0, 1.0);\n" " }\n" "#endif\n" "\n" - "vec2 webgl_unpackSnorm2x16_emu(uint u)\n" + "vec2 unpackSnorm2x16_emu(uint u)\n" "{\n" " #if defined(GL_ARB_shading_language_packing)\n" " return unpackSnorm2x16(u);\n" " #else\n" " uint y = (u >> 16);\n" " uint x = u;\n" - " return vec2(webgl_fromSnorm(x), webgl_fromSnorm(y));\n" + " return vec2(fromSnorm(x), fromSnorm(y));\n" " #endif\n" "}\n"); - // Functions uint webgl_f32tof16(float val) and float webgl_f16tof32(uint val) are + // Functions uint f32tof16(float val) and float f16tof32(uint val) are // based on the OpenGL redbook Appendix Session "Floating-Point Formats Used in OpenGL". emu->addEmulatedFunction(EOpPackHalf2x16, float2, "#if !defined(GL_ARB_shading_language_packing)\n" - " uint webgl_f32tof16(float val)\n" + " uint f32tof16(float val)\n" " {\n" " uint f32 = floatBitsToUint(val);\n" " uint f16 = 0u;\n" @@ -119,19 +219,19 @@ void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator " }\n" "#endif\n" "\n" - "uint webgl_packHalf2x16_emu(vec2 v)\n" + "uint packHalf2x16_emu(vec2 v)\n" "{\n" " #if defined(GL_ARB_shading_language_packing)\n" " return packHalf2x16(v);\n" " #else\n" - " uint x = webgl_f32tof16(v.x);\n" - " uint y = webgl_f32tof16(v.y);\n" + " uint x = f32tof16(v.x);\n" + " uint y = f32tof16(v.y);\n" " return (y << 16) | x;\n" " #endif\n" "}\n"); emu->addEmulatedFunction(EOpUnpackHalf2x16, uint1, "#if !defined(GL_ARB_shading_language_packing)\n" - " float webgl_f16tof32(uint val)\n" + " float f16tof32(uint val)\n" " {\n" " uint sign = (val & 0x8000u) << 16;\n" " int exponent = int((val & 0x7C00u) >> 10);\n" @@ -155,7 +255,9 @@ void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator " float scale;\n" " if(exponent < 0)\n" " {\n" - " scale = 1.0 / (1 << -exponent);\n" + " // The negative unary operator is buggy on OSX.\n" + " // Work around this by using abs instead.\n" + " scale = 1.0 / (1 << abs(exponent));\n" " }\n" " else\n" " {\n" @@ -174,16 +276,18 @@ void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator " }\n" "#endif\n" "\n" - "vec2 webgl_unpackHalf2x16_emu(uint u)\n" + "vec2 unpackHalf2x16_emu(uint u)\n" "{\n" " #if defined(GL_ARB_shading_language_packing)\n" " return unpackHalf2x16(u);\n" " #else\n" " uint y = (u >> 16);\n" " uint x = u & 0xFFFFu;\n" - " return vec2(webgl_f16tof32(x), webgl_f16tof32(y));\n" + " return vec2(f16tof32(x), f16tof32(y));\n" " #endif\n" "}\n"); // clang-format on } } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h b/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h index 56242598af..e1b4779bd5 100644 --- a/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h +++ b/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h @@ -9,17 +9,32 @@ #include "GLSLANG/ShaderLang.h" +namespace sh +{ class BuiltInFunctionEmulator; // -// This is only a workaround for OpenGL driver bugs, and isn't needed in general. +// This works around bug in Intel Mac drivers. // -void InitBuiltInFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu, sh::GLenum shaderType); +void InitBuiltInAbsFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu, + sh::GLenum shaderType); + +// +// This works around isnan() bug in Intel Mac drivers +// +void InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu, + int targetGLSLVersion); +// +// This works around atan(y, x) bug in NVIDIA drivers. +// +void InitBuiltInAtanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu); // // This function is emulating built-in functions missing from GLSL 1.30 and higher. // -void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator *emu, sh::GLenum shaderType, +void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator *emu, + sh::GLenum shaderType, int targetGLSLVersion); +} // namespace sh #endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORGLSL_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp b/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp index 50e15cbc28..e78d86d00a 100644 --- a/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp +++ b/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp @@ -8,434 +8,177 @@ #include "compiler/translator/BuiltInFunctionEmulator.h" #include "compiler/translator/BuiltInFunctionEmulatorHLSL.h" #include "compiler/translator/SymbolTable.h" +#include "compiler/translator/VersionGLSL.h" -void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu) +namespace sh { + +// Defined in emulated_builtin_functions_hlsl_autogen.cpp. +const char *FindHLSLFunction(const FunctionId &functionID); + +void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator *emu, + int targetGLSLVersion) +{ + if (targetGLSLVersion < GLSL_VERSION_130) + return; + TType *float1 = new TType(EbtFloat); TType *float2 = new TType(EbtFloat, 2); TType *float3 = new TType(EbtFloat, 3); TType *float4 = new TType(EbtFloat, 4); - emu->addEmulatedFunction(EOpMod, float1, float1, - "float webgl_mod_emu(float x, float y)\n" - "{\n" - " return x - y * floor(x / y);\n" - "}\n" - "\n"); - emu->addEmulatedFunction(EOpMod, float2, float2, - "float2 webgl_mod_emu(float2 x, float2 y)\n" - "{\n" - " return x - y * floor(x / y);\n" - "}\n" - "\n"); - emu->addEmulatedFunction(EOpMod, float2, float1, - "float2 webgl_mod_emu(float2 x, float y)\n" - "{\n" - " return x - y * floor(x / y);\n" - "}\n" - "\n"); - emu->addEmulatedFunction(EOpMod, float3, float3, - "float3 webgl_mod_emu(float3 x, float3 y)\n" - "{\n" - " return x - y * floor(x / y);\n" - "}\n" - "\n"); - emu->addEmulatedFunction(EOpMod, float3, float1, - "float3 webgl_mod_emu(float3 x, float y)\n" - "{\n" - " return x - y * floor(x / y);\n" - "}\n" - "\n"); - emu->addEmulatedFunction(EOpMod, float4, float4, - "float4 webgl_mod_emu(float4 x, float4 y)\n" - "{\n" - " return x - y * floor(x / y);\n" - "}\n" - "\n"); - emu->addEmulatedFunction(EOpMod, float4, float1, - "float4 webgl_mod_emu(float4 x, float y)\n" - "{\n" - " return x - y * floor(x / y);\n" - "}\n" - "\n"); + emu->addEmulatedFunction(EOpIsNan, float1, + "bool isnan_emu(float x)\n" + "{\n" + " return (x > 0.0 || x < 0.0) ? false : x != 0.0;\n" + "}\n" + "\n"); - emu->addEmulatedFunction(EOpFaceForward, float1, float1, float1, - "float webgl_faceforward_emu(float N, float I, float Nref)\n" + emu->addEmulatedFunction( + EOpIsNan, float2, + "bool2 isnan_emu(float2 x)\n" "{\n" - " if(dot(Nref, I) >= 0)\n" + " bool2 isnan;\n" + " for (int i = 0; i < 2; i++)\n" " {\n" - " return -N;\n" + " isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n" " }\n" - " else\n" + " return isnan;\n" + "}\n"); + + emu->addEmulatedFunction( + EOpIsNan, float3, + "bool3 isnan_emu(float3 x)\n" + "{\n" + " bool3 isnan;\n" + " for (int i = 0; i < 3; i++)\n" " {\n" - " return N;\n" + " isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n" " }\n" - "}\n" - "\n"); - emu->addEmulatedFunction(EOpFaceForward, float2, float2, float2, - "float2 webgl_faceforward_emu(float2 N, float2 I, float2 Nref)\n" + " return isnan;\n" + "}\n"); + + emu->addEmulatedFunction( + EOpIsNan, float4, + "bool4 isnan_emu(float4 x)\n" "{\n" - " if(dot(Nref, I) >= 0)\n" + " bool4 isnan;\n" + " for (int i = 0; i < 4; i++)\n" " {\n" - " return -N;\n" + " isnan[i] = (x[i] > 0.0 || x[i] < 0.0) ? false : x[i] != 0.0;\n" " }\n" - " else\n" - " {\n" - " return N;\n" - " }\n" - "}\n" - "\n"); - emu->addEmulatedFunction(EOpFaceForward, float3, float3, float3, - "float3 webgl_faceforward_emu(float3 N, float3 I, float3 Nref)\n" - "{\n" - " if(dot(Nref, I) >= 0)\n" - " {\n" - " return -N;\n" - " }\n" - " else\n" - " {\n" - " return N;\n" - " }\n" - "}\n" - "\n"); - emu->addEmulatedFunction(EOpFaceForward, float4, float4, float4, - "float4 webgl_faceforward_emu(float4 N, float4 I, float4 Nref)\n" - "{\n" - " if(dot(Nref, I) >= 0)\n" - " {\n" - " return -N;\n" - " }\n" - " else\n" - " {\n" - " return N;\n" - " }\n" - "}\n" - "\n"); - - emu->addEmulatedFunction(EOpAtan, float1, float1, - "float webgl_atan_emu(float y, float x)\n" - "{\n" - " if(x == 0 && y == 0) x = 1;\n" // Avoid producing a NaN - " return atan2(y, x);\n" + " return isnan;\n" "}\n"); - emu->addEmulatedFunction(EOpAtan, float2, float2, - "float2 webgl_atan_emu(float2 y, float2 x)\n" - "{\n" - " if(x[0] == 0 && y[0] == 0) x[0] = 1;\n" - " if(x[1] == 0 && y[1] == 0) x[1] = 1;\n" - " return float2(atan2(y[0], x[0]), atan2(y[1], x[1]));\n" - "}\n"); - emu->addEmulatedFunction(EOpAtan, float3, float3, - "float3 webgl_atan_emu(float3 y, float3 x)\n" - "{\n" - " if(x[0] == 0 && y[0] == 0) x[0] = 1;\n" - " if(x[1] == 0 && y[1] == 0) x[1] = 1;\n" - " if(x[2] == 0 && y[2] == 0) x[2] = 1;\n" - " return float3(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], x[2]));\n" - "}\n"); - emu->addEmulatedFunction(EOpAtan, float4, float4, - "float4 webgl_atan_emu(float4 y, float4 x)\n" - "{\n" - " if(x[0] == 0 && y[0] == 0) x[0] = 1;\n" - " if(x[1] == 0 && y[1] == 0) x[1] = 1;\n" - " if(x[2] == 0 && y[2] == 0) x[2] = 1;\n" - " if(x[3] == 0 && y[3] == 0) x[3] = 1;\n" - " return float4(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], x[2]), atan2(y[3], x[3]));\n" - "}\n"); - - emu->addEmulatedFunction(EOpAsinh, float1, - "float webgl_asinh_emu(in float x) {\n" - " return log(x + sqrt(pow(x, 2.0) + 1.0));\n" - "}\n"); - emu->addEmulatedFunction(EOpAsinh, float2, - "float2 webgl_asinh_emu(in float2 x) {\n" - " return log(x + sqrt(pow(x, 2.0) + 1.0));\n" - "}\n"); - emu->addEmulatedFunction(EOpAsinh, float3, - "float3 webgl_asinh_emu(in float3 x) {\n" - " return log(x + sqrt(pow(x, 2.0) + 1.0));\n" - "}\n"); - emu->addEmulatedFunction(EOpAsinh, float4, - "float4 webgl_asinh_emu(in float4 x) {\n" - " return log(x + sqrt(pow(x, 2.0) + 1.0));\n" - "}\n"); - - emu->addEmulatedFunction(EOpAcosh, float1, - "float webgl_acosh_emu(in float x) {\n" - " return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n" - "}\n"); - emu->addEmulatedFunction(EOpAcosh, float2, - "float2 webgl_acosh_emu(in float2 x) {\n" - " return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n" - "}\n"); - emu->addEmulatedFunction(EOpAcosh, float3, - "float3 webgl_acosh_emu(in float3 x) {\n" - " return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n" - "}\n"); - emu->addEmulatedFunction(EOpAcosh, float4, - "float4 webgl_acosh_emu(in float4 x) {\n" - " return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n" - "}\n"); - - emu->addEmulatedFunction(EOpAtanh, float1, - "float webgl_atanh_emu(in float x) {\n" - " return 0.5 * log((1.0 + x) / (1.0 - x));\n" - "}\n"); - emu->addEmulatedFunction(EOpAtanh, float2, - "float2 webgl_atanh_emu(in float2 x) {\n" - " return 0.5 * log((1.0 + x) / (1.0 - x));\n" - "}\n"); - emu->addEmulatedFunction(EOpAtanh, float3, - "float3 webgl_atanh_emu(in float3 x) {\n" - " return 0.5 * log((1.0 + x) / (1.0 - x));\n" - "}\n"); - emu->addEmulatedFunction(EOpAtanh, float4, - "float4 webgl_atanh_emu(in float4 x) {\n" - " return 0.5 * log((1.0 + x) / (1.0 - x));\n" - "}\n"); - - emu->addEmulatedFunction(EOpRoundEven, float1, - "float webgl_roundEven_emu(in float x) {\n" - " return (frac(x) == 0.5 && trunc(x) % 2.0 == 0.0) ? trunc(x) : round(x);\n" - "}\n"); - emu->addEmulatedFunction(EOpRoundEven, float2, - "float2 webgl_roundEven_emu(in float2 x) {\n" - " float2 v;\n" - " v[0] = (frac(x[0]) == 0.5 && trunc(x[0]) % 2.0 == 0.0) ? trunc(x[0]) : round(x[0]);\n" - " v[1] = (frac(x[1]) == 0.5 && trunc(x[1]) % 2.0 == 0.0) ? trunc(x[1]) : round(x[1]);\n" - " return v;\n" - "}\n"); - emu->addEmulatedFunction(EOpRoundEven, float3, - "float3 webgl_roundEven_emu(in float3 x) {\n" - " float3 v;\n" - " v[0] = (frac(x[0]) == 0.5 && trunc(x[0]) % 2.0 == 0.0) ? trunc(x[0]) : round(x[0]);\n" - " v[1] = (frac(x[1]) == 0.5 && trunc(x[1]) % 2.0 == 0.0) ? trunc(x[1]) : round(x[1]);\n" - " v[2] = (frac(x[2]) == 0.5 && trunc(x[2]) % 2.0 == 0.0) ? trunc(x[2]) : round(x[2]);\n" - " return v;\n" - "}\n"); - emu->addEmulatedFunction(EOpRoundEven, float4, - "float4 webgl_roundEven_emu(in float4 x) {\n" - " float4 v;\n" - " v[0] = (frac(x[0]) == 0.5 && trunc(x[0]) % 2.0 == 0.0) ? trunc(x[0]) : round(x[0]);\n" - " v[1] = (frac(x[1]) == 0.5 && trunc(x[1]) % 2.0 == 0.0) ? trunc(x[1]) : round(x[1]);\n" - " v[2] = (frac(x[2]) == 0.5 && trunc(x[2]) % 2.0 == 0.0) ? trunc(x[2]) : round(x[2]);\n" - " v[3] = (frac(x[3]) == 0.5 && trunc(x[3]) % 2.0 == 0.0) ? trunc(x[3]) : round(x[3]);\n" - " return v;\n" - "}\n"); - - emu->addEmulatedFunction(EOpPackSnorm2x16, float2, - "int webgl_toSnorm(in float x) {\n" - " return int(round(clamp(x, -1.0, 1.0) * 32767.0));\n" - "}\n" - "\n" - "uint webgl_packSnorm2x16_emu(in float2 v) {\n" - " int x = webgl_toSnorm(v.x);\n" - " int y = webgl_toSnorm(v.y);\n" - " return (asuint(y) << 16) | (asuint(x) & 0xffffu);\n" - "}\n"); - emu->addEmulatedFunction(EOpPackUnorm2x16, float2, - "uint webgl_toUnorm(in float x) {\n" - " return uint(round(clamp(x, 0.0, 1.0) * 65535.0));\n" - "}\n" - "\n" - "uint webgl_packUnorm2x16_emu(in float2 v) {\n" - " uint x = webgl_toUnorm(v.x);\n" - " uint y = webgl_toUnorm(v.y);\n" - " return (y << 16) | x;\n" - "}\n"); - emu->addEmulatedFunction(EOpPackHalf2x16, float2, - "uint webgl_packHalf2x16_emu(in float2 v) {\n" - " uint x = f32tof16(v.x);\n" - " uint y = f32tof16(v.y);\n" - " return (y << 16) | x;\n" - "}\n"); - - TType *uint1 = new TType(EbtUInt); - - emu->addEmulatedFunction(EOpUnpackSnorm2x16, uint1, - "float webgl_fromSnorm(in uint x) {\n" - " int xi = asint(x & 0x7fffu) - asint(x & 0x8000u);\n" - " return clamp(float(xi) / 32767.0, -1.0, 1.0);\n" - "}\n" - "\n" - "float2 webgl_unpackSnorm2x16_emu(in uint u) {\n" - " uint y = (u >> 16);\n" - " uint x = u;\n" - " return float2(webgl_fromSnorm(x), webgl_fromSnorm(y));\n" - "}\n"); - emu->addEmulatedFunction(EOpUnpackUnorm2x16, uint1, - "float webgl_fromUnorm(in uint x) {\n" - " return float(x) / 65535.0;\n" - "}\n" - "\n" - "float2 webgl_unpackUnorm2x16_emu(in uint u) {\n" - " uint y = (u >> 16);\n" - " uint x = u & 0xffffu;\n" - " return float2(webgl_fromUnorm(x), webgl_fromUnorm(y));\n" - "}\n"); - emu->addEmulatedFunction(EOpUnpackHalf2x16, uint1, - "float2 webgl_unpackHalf2x16_emu(in uint u) {\n" - " uint y = (u >> 16);\n" - " uint x = u & 0xffffu;\n" - " return float2(f16tof32(x), f16tof32(y));\n" - "}\n"); - - // The matrix resulting from outer product needs to be transposed - // (matrices are stored as transposed to simplify element access in HLSL). - // So the function should return transpose(c * r) where c is a column vector - // and r is a row vector. This can be simplified by using the following - // formula: - // transpose(c * r) = transpose(r) * transpose(c) - // transpose(r) and transpose(c) are in a sense free, since to get the - // transpose of r, we simply can build a column matrix out of the original - // vector instead of a row matrix. - emu->addEmulatedFunction(EOpOuterProduct, float2, float2, - "float2x2 webgl_outerProduct_emu(in float2 c, in float2 r) {\n" - " return mul(float2x1(r), float1x2(c));\n" - "}\n"); - emu->addEmulatedFunction(EOpOuterProduct, float3, float3, - "float3x3 webgl_outerProduct_emu(in float3 c, in float3 r) {\n" - " return mul(float3x1(r), float1x3(c));\n" - "}\n"); - emu->addEmulatedFunction(EOpOuterProduct, float4, float4, - "float4x4 webgl_outerProduct_emu(in float4 c, in float4 r) {\n" - " return mul(float4x1(r), float1x4(c));\n" - "}\n"); - - emu->addEmulatedFunction(EOpOuterProduct, float3, float2, - "float2x3 webgl_outerProduct_emu(in float3 c, in float2 r) {\n" - " return mul(float2x1(r), float1x3(c));\n" - "}\n"); - emu->addEmulatedFunction(EOpOuterProduct, float2, float3, - "float3x2 webgl_outerProduct_emu(in float2 c, in float3 r) {\n" - " return mul(float3x1(r), float1x2(c));\n" - "}\n"); - emu->addEmulatedFunction(EOpOuterProduct, float4, float2, - "float2x4 webgl_outerProduct_emu(in float4 c, in float2 r) {\n" - " return mul(float2x1(r), float1x4(c));\n" - "}\n"); - emu->addEmulatedFunction(EOpOuterProduct, float2, float4, - "float4x2 webgl_outerProduct_emu(in float2 c, in float4 r) {\n" - " return mul(float4x1(r), float1x2(c));\n" - "}\n"); - emu->addEmulatedFunction(EOpOuterProduct, float4, float3, - "float3x4 webgl_outerProduct_emu(in float4 c, in float3 r) {\n" - " return mul(float3x1(r), float1x4(c));\n" - "}\n"); - emu->addEmulatedFunction(EOpOuterProduct, float3, float4, - "float4x3 webgl_outerProduct_emu(in float3 c, in float4 r) {\n" - " return mul(float4x1(r), float1x3(c));\n" - "}\n"); - - TType *mat2 = new TType(EbtFloat, 2, 2); - TType *mat3 = new TType(EbtFloat, 3, 3); - TType *mat4 = new TType(EbtFloat, 4, 4); - - // Remember here that the parameter matrix is actually the transpose - // of the matrix that we're trying to invert, and the resulting matrix - // should also be the transpose of the inverse. - - // When accessing the parameter matrix with m[a][b] it can be thought of so - // that a is the column and b is the row of the matrix that we're inverting. - - // We calculate the inverse as the adjugate matrix divided by the - // determinant of the matrix being inverted. However, as the result needs - // to be transposed, we actually use of the transpose of the adjugate matrix - // which happens to be the cofactor matrix. That's stored in "cof". - - // We don't need to care about divide-by-zero since results are undefined - // for singular or poorly-conditioned matrices. - - emu->addEmulatedFunction(EOpInverse, mat2, - "float2x2 webgl_inverse_emu(in float2x2 m) {\n" - " float2x2 cof = { m[1][1], -m[0][1], -m[1][0], m[0][0] };\n" - " return cof / determinant(transpose(m));\n" - "}\n"); - - // cofAB is the cofactor for column A and row B. - - emu->addEmulatedFunction(EOpInverse, mat3, - "float3x3 webgl_inverse_emu(in float3x3 m) {\n" - " float cof00 = m[1][1] * m[2][2] - m[2][1] * m[1][2];\n" - " float cof01 = -(m[1][0] * m[2][2] - m[2][0] * m[1][2]);\n" - " float cof02 = m[1][0] * m[2][1] - m[2][0] * m[1][1];\n" - " float cof10 = -(m[0][1] * m[2][2] - m[2][1] * m[0][2]);\n" - " float cof11 = m[0][0] * m[2][2] - m[2][0] * m[0][2];\n" - " float cof12 = -(m[0][0] * m[2][1] - m[2][0] * m[0][1]);\n" - " float cof20 = m[0][1] * m[1][2] - m[1][1] * m[0][2];\n" - " float cof21 = -(m[0][0] * m[1][2] - m[1][0] * m[0][2]);\n" - " float cof22 = m[0][0] * m[1][1] - m[1][0] * m[0][1];\n" - " float3x3 cof = { cof00, cof10, cof20, cof01, cof11, cof21, cof02, cof12, cof22 };\n" - " return cof / determinant(transpose(m));\n" - "}\n"); - - emu->addEmulatedFunction(EOpInverse, mat4, - "float4x4 webgl_inverse_emu(in float4x4 m) {\n" - " float cof00 = m[1][1] * m[2][2] * m[3][3] + m[2][1] * m[3][2] * m[1][3] + m[3][1] * m[1][2] * m[2][3]" - " - m[1][1] * m[3][2] * m[2][3] - m[2][1] * m[1][2] * m[3][3] - m[3][1] * m[2][2] * m[1][3];\n" - " float cof01 = -(m[1][0] * m[2][2] * m[3][3] + m[2][0] * m[3][2] * m[1][3] + m[3][0] * m[1][2] * m[2][3]" - " - m[1][0] * m[3][2] * m[2][3] - m[2][0] * m[1][2] * m[3][3] - m[3][0] * m[2][2] * m[1][3]);\n" - " float cof02 = m[1][0] * m[2][1] * m[3][3] + m[2][0] * m[3][1] * m[1][3] + m[3][0] * m[1][1] * m[2][3]" - " - m[1][0] * m[3][1] * m[2][3] - m[2][0] * m[1][1] * m[3][3] - m[3][0] * m[2][1] * m[1][3];\n" - " float cof03 = -(m[1][0] * m[2][1] * m[3][2] + m[2][0] * m[3][1] * m[1][2] + m[3][0] * m[1][1] * m[2][2]" - " - m[1][0] * m[3][1] * m[2][2] - m[2][0] * m[1][1] * m[3][2] - m[3][0] * m[2][1] * m[1][2]);\n" - " float cof10 = -(m[0][1] * m[2][2] * m[3][3] + m[2][1] * m[3][2] * m[0][3] + m[3][1] * m[0][2] * m[2][3]" - " - m[0][1] * m[3][2] * m[2][3] - m[2][1] * m[0][2] * m[3][3] - m[3][1] * m[2][2] * m[0][3]);\n" - " float cof11 = m[0][0] * m[2][2] * m[3][3] + m[2][0] * m[3][2] * m[0][3] + m[3][0] * m[0][2] * m[2][3]" - " - m[0][0] * m[3][2] * m[2][3] - m[2][0] * m[0][2] * m[3][3] - m[3][0] * m[2][2] * m[0][3];\n" - " float cof12 = -(m[0][0] * m[2][1] * m[3][3] + m[2][0] * m[3][1] * m[0][3] + m[3][0] * m[0][1] * m[2][3]" - " - m[0][0] * m[3][1] * m[2][3] - m[2][0] * m[0][1] * m[3][3] - m[3][0] * m[2][1] * m[0][3]);\n" - " float cof13 = m[0][0] * m[2][1] * m[3][2] + m[2][0] * m[3][1] * m[0][2] + m[3][0] * m[0][1] * m[2][2]" - " - m[0][0] * m[3][1] * m[2][2] - m[2][0] * m[0][1] * m[3][2] - m[3][0] * m[2][1] * m[0][2];\n" - " float cof20 = m[0][1] * m[1][2] * m[3][3] + m[1][1] * m[3][2] * m[0][3] + m[3][1] * m[0][2] * m[1][3]" - " - m[0][1] * m[3][2] * m[1][3] - m[1][1] * m[0][2] * m[3][3] - m[3][1] * m[1][2] * m[0][3];\n" - " float cof21 = -(m[0][0] * m[1][2] * m[3][3] + m[1][0] * m[3][2] * m[0][3] + m[3][0] * m[0][2] * m[1][3]" - " - m[0][0] * m[3][2] * m[1][3] - m[1][0] * m[0][2] * m[3][3] - m[3][0] * m[1][2] * m[0][3]);\n" - " float cof22 = m[0][0] * m[1][1] * m[3][3] + m[1][0] * m[3][1] * m[0][3] + m[3][0] * m[0][1] * m[1][3]" - " - m[0][0] * m[3][1] * m[1][3] - m[1][0] * m[0][1] * m[3][3] - m[3][0] * m[1][1] * m[0][3];\n" - " float cof23 = -(m[0][0] * m[1][1] * m[3][2] + m[1][0] * m[3][1] * m[0][2] + m[3][0] * m[0][1] * m[1][2]" - " - m[0][0] * m[3][1] * m[1][2] - m[1][0] * m[0][1] * m[3][2] - m[3][0] * m[1][1] * m[0][2]);\n" - " float cof30 = -(m[0][1] * m[1][2] * m[2][3] + m[1][1] * m[2][2] * m[0][3] + m[2][1] * m[0][2] * m[1][3]" - " - m[0][1] * m[2][2] * m[1][3] - m[1][1] * m[0][2] * m[2][3] - m[2][1] * m[1][2] * m[0][3]);\n" - " float cof31 = m[0][0] * m[1][2] * m[2][3] + m[1][0] * m[2][2] * m[0][3] + m[2][0] * m[0][2] * m[1][3]" - " - m[0][0] * m[2][2] * m[1][3] - m[1][0] * m[0][2] * m[2][3] - m[2][0] * m[1][2] * m[0][3];\n" - " float cof32 = -(m[0][0] * m[1][1] * m[2][3] + m[1][0] * m[2][1] * m[0][3] + m[2][0] * m[0][1] * m[1][3]" - " - m[0][0] * m[2][1] * m[1][3] - m[1][0] * m[0][1] * m[2][3] - m[2][0] * m[1][1] * m[0][3]);\n" - " float cof33 = m[0][0] * m[1][1] * m[2][2] + m[1][0] * m[2][1] * m[0][2] + m[2][0] * m[0][1] * m[1][2]" - " - m[0][0] * m[2][1] * m[1][2] - m[1][0] * m[0][1] * m[2][2] - m[2][0] * m[1][1] * m[0][2];\n" - " float4x4 cof = { cof00, cof10, cof20, cof30, cof01, cof11, cof21, cof31," - " cof02, cof12, cof22, cof32, cof03, cof13, cof23, cof33 };\n" - " return cof / determinant(transpose(m));\n" - "}\n"); - - TType *bool1 = new TType(EbtBool); - TType *bool2 = new TType(EbtBool, 2); - TType *bool3 = new TType(EbtBool, 3); - TType *bool4 = new TType(EbtBool, 4); - - // Emulate ESSL3 variant of mix that takes last argument as boolean vector. - // genType mix (genType x, genType y, genBType a): Selects which vector each returned component comes from. - // For a component of 'a' that is false, the corresponding component of 'x' is returned.For a component of 'a' that is true, - // the corresponding component of 'y' is returned. - emu->addEmulatedFunction(EOpMix, float1, float1, bool1, - "float webgl_mix_emu(float x, float y, bool a)\n" - "{\n" - " return a ? y : x;\n" - "}\n"); - emu->addEmulatedFunction(EOpMix, float2, float2, bool2, - "float2 webgl_mix_emu(float2 x, float2 y, bool2 a)\n" - "{\n" - " return a ? y : x;\n" - "}\n"); - emu->addEmulatedFunction(EOpMix, float3, float3, bool3, - "float3 webgl_mix_emu(float3 x, float3 y, bool3 a)\n" - "{\n" - " return a ? y : x;\n" - "}\n"); - emu->addEmulatedFunction(EOpMix, float4, float4, bool4, - "float4 webgl_mix_emu(float4 x, float4 y, bool4 a)\n" - "{\n" - " return a ? y : x;\n" - "}\n"); - } + +void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu) +{ + TType *int1 = new TType(EbtInt); + TType *int2 = new TType(EbtInt, 2); + TType *int3 = new TType(EbtInt, 3); + TType *int4 = new TType(EbtInt, 4); + TType *uint1 = new TType(EbtUInt); + TType *uint2 = new TType(EbtUInt, 2); + TType *uint3 = new TType(EbtUInt, 3); + TType *uint4 = new TType(EbtUInt, 4); + + emu->addFunctionMap(FindHLSLFunction); + + // (a + b2^16) * (c + d2^16) = ac + (ad + bc) * 2^16 + bd * 2^32 + // Also note that below, a * d + ((a * c) >> 16) is guaranteed not to overflow, because: + // a <= 0xffff, d <= 0xffff, ((a * c) >> 16) <= 0xffff and 0xffff * 0xffff + 0xffff = 0xffff0000 + FunctionId umulExtendedUint1 = emu->addEmulatedFunction( + EOpUmulExtended, uint1, uint1, uint1, uint1, + "void umulExtended_emu(uint x, uint y, out uint msb, out uint lsb)\n" + "{\n" + " lsb = x * y;\n" + " uint a = (x & 0xffffu);\n" + " uint b = (x >> 16);\n" + " uint c = (y & 0xffffu);\n" + " uint d = (y >> 16);\n" + " uint ad = a * d + ((a * c) >> 16);\n" + " uint bc = b * c;\n" + " uint carry = uint(ad > (0xffffffffu - bc));\n" + " msb = ((ad + bc) >> 16) + (carry << 16) + b * d;\n" + "}\n"); + emu->addEmulatedFunctionWithDependency( + umulExtendedUint1, EOpUmulExtended, uint2, uint2, uint2, uint2, + "void umulExtended_emu(uint2 x, uint2 y, out uint2 msb, out uint2 lsb)\n" + "{\n" + " umulExtended_emu(x.x, y.x, msb.x, lsb.x);\n" + " umulExtended_emu(x.y, y.y, msb.y, lsb.y);\n" + "}\n"); + emu->addEmulatedFunctionWithDependency( + umulExtendedUint1, EOpUmulExtended, uint3, uint3, uint3, uint3, + "void umulExtended_emu(uint3 x, uint3 y, out uint3 msb, out uint3 lsb)\n" + "{\n" + " umulExtended_emu(x.x, y.x, msb.x, lsb.x);\n" + " umulExtended_emu(x.y, y.y, msb.y, lsb.y);\n" + " umulExtended_emu(x.z, y.z, msb.z, lsb.z);\n" + "}\n"); + emu->addEmulatedFunctionWithDependency( + umulExtendedUint1, EOpUmulExtended, uint4, uint4, uint4, uint4, + "void umulExtended_emu(uint4 x, uint4 y, out uint4 msb, out uint4 lsb)\n" + "{\n" + " umulExtended_emu(x.x, y.x, msb.x, lsb.x);\n" + " umulExtended_emu(x.y, y.y, msb.y, lsb.y);\n" + " umulExtended_emu(x.z, y.z, msb.z, lsb.z);\n" + " umulExtended_emu(x.w, y.w, msb.w, lsb.w);\n" + "}\n"); + + // The imul emulation does two's complement negation on the lsb and msb manually in case the + // result needs to be negative. + // TODO(oetuaho): Note that this code doesn't take one edge case into account, where x or y is + // -2^31. abs(-2^31) is undefined. + FunctionId imulExtendedInt1 = emu->addEmulatedFunctionWithDependency( + umulExtendedUint1, EOpImulExtended, int1, int1, int1, int1, + "void imulExtended_emu(int x, int y, out int msb, out int lsb)\n" + "{\n" + " uint unsignedMsb;\n" + " uint unsignedLsb;\n" + " bool negative = (x < 0) != (y < 0);\n" + " umulExtended_emu(uint(abs(x)), uint(abs(y)), unsignedMsb, unsignedLsb);\n" + " lsb = asint(unsignedLsb);\n" + " msb = asint(unsignedMsb);\n" + " if (negative)\n" + " {\n" + " lsb = ~lsb;\n" + " msb = ~msb;\n" + " if (lsb == 0xffffffff)\n" + " {\n" + " lsb = 0;\n" + " msb += 1;\n" + " }\n" + " else\n" + " {\n" + " lsb += 1;\n" + " }\n" + " }\n" + "}\n"); + emu->addEmulatedFunctionWithDependency( + imulExtendedInt1, EOpImulExtended, int2, int2, int2, int2, + "void imulExtended_emu(int2 x, int2 y, out int2 msb, out int2 lsb)\n" + "{\n" + " imulExtended_emu(x.x, y.x, msb.x, lsb.x);\n" + " imulExtended_emu(x.y, y.y, msb.y, lsb.y);\n" + "}\n"); + emu->addEmulatedFunctionWithDependency( + imulExtendedInt1, EOpImulExtended, int3, int3, int3, int3, + "void imulExtended_emu(int3 x, int3 y, out int3 msb, out int3 lsb)\n" + "{\n" + " imulExtended_emu(x.x, y.x, msb.x, lsb.x);\n" + " imulExtended_emu(x.y, y.y, msb.y, lsb.y);\n" + " imulExtended_emu(x.z, y.z, msb.z, lsb.z);\n" + "}\n"); + emu->addEmulatedFunctionWithDependency( + imulExtendedInt1, EOpImulExtended, int4, int4, int4, int4, + "void imulExtended_emu(int4 x, int4 y, out int4 msb, out int4 lsb)\n" + "{\n" + " imulExtended_emu(x.x, y.x, msb.x, lsb.x);\n" + " imulExtended_emu(x.y, y.y, msb.y, lsb.y);\n" + " imulExtended_emu(x.z, y.z, msb.z, lsb.z);\n" + " imulExtended_emu(x.w, y.w, msb.w, lsb.w);\n" + "}\n"); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h b/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h index 4c45a93dc4..48da73f58e 100644 --- a/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h +++ b/src/3rdparty/angle/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h @@ -9,8 +9,19 @@ #include "GLSLANG/ShaderLang.h" +namespace sh +{ + class BuiltInFunctionEmulator; void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu); +// +// This works around isnan() bug on some Intel drivers. +// +void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator *emu, + int targetGLSLVersion); + +} // namespace sh + #endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORHLSL_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/Cache.cpp b/src/3rdparty/angle/src/compiler/translator/Cache.cpp index 57a43700ca..417e82403a 100644 --- a/src/3rdparty/angle/src/compiler/translator/Cache.cpp +++ b/src/3rdparty/angle/src/compiler/translator/Cache.cpp @@ -12,21 +12,20 @@ #include "common/debug.h" #include "compiler/translator/Cache.h" +namespace sh +{ + namespace { class TScopedAllocator : angle::NonCopyable { public: - TScopedAllocator(TPoolAllocator *allocator) - : mPreviousAllocator(GetGlobalPoolAllocator()) + TScopedAllocator(TPoolAllocator *allocator) : mPreviousAllocator(GetGlobalPoolAllocator()) { SetGlobalPoolAllocator(allocator); } - ~TScopedAllocator() - { - SetGlobalPoolAllocator(mPreviousAllocator); - } + ~TScopedAllocator() { SetGlobalPoolAllocator(mPreviousAllocator); } private: TPoolAllocator *mPreviousAllocator; @@ -40,28 +39,28 @@ TCache::TypeKey::TypeKey(TBasicType basicType, unsigned char primarySize, unsigned char secondarySize) { - static_assert(sizeof(components) <= sizeof(value), - "TypeKey::value is too small"); + static_assert(sizeof(components) <= sizeof(value), "TypeKey::value is too small"); const size_t MaxEnumValue = std::numeric_limits::max(); - UNUSED_ASSERTION_VARIABLE(MaxEnumValue); // TODO: change to static_assert() once we deprecate MSVC 2013 support - ASSERT(MaxEnumValue >= EbtLast && - MaxEnumValue >= EbpLast && - MaxEnumValue >= EvqLast && + ASSERT(MaxEnumValue >= EbtLast && MaxEnumValue >= EbpLast && MaxEnumValue >= EvqLast && "TypeKey::EnumComponentType is too small"); - value = 0; - components.basicType = static_cast(basicType); - components.precision = static_cast(precision); - components.qualifier = static_cast(qualifier); - components.primarySize = primarySize; + value = 0; + components.basicType = static_cast(basicType); + components.precision = static_cast(precision); + components.qualifier = static_cast(qualifier); + components.primarySize = primarySize; components.secondarySize = secondarySize; } TCache *TCache::sCache = nullptr; +TCache::TCache() +{ +} + void TCache::initialize() { if (sCache == nullptr) @@ -81,8 +80,7 @@ const TType *TCache::getType(TBasicType basicType, unsigned char primarySize, unsigned char secondarySize) { - TypeKey key(basicType, precision, qualifier, - primarySize, secondarySize); + TypeKey key(basicType, precision, qualifier, primarySize, secondarySize); auto it = sCache->mTypes.find(key); if (it != sCache->mTypes.end()) { @@ -91,10 +89,11 @@ const TType *TCache::getType(TBasicType basicType, TScopedAllocator scopedAllocator(&sCache->mAllocator); - TType *type = new TType(basicType, precision, qualifier, - primarySize, secondarySize); + TType *type = new TType(basicType, precision, qualifier, primarySize, secondarySize); type->realize(); sCache->mTypes.insert(std::make_pair(key, type)); return type; } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/Cache.h b/src/3rdparty/angle/src/compiler/translator/Cache.h index 1d2abb77e1..a182b07f51 100644 --- a/src/3rdparty/angle/src/compiler/translator/Cache.h +++ b/src/3rdparty/angle/src/compiler/translator/Cache.h @@ -16,33 +16,31 @@ #include "compiler/translator/Types.h" #include "compiler/translator/PoolAlloc.h" +namespace sh +{ + class TCache { public: - static void initialize(); static void destroy(); - static const TType *getType(TBasicType basicType, - TPrecision precision) + static const TType *getType(TBasicType basicType, TPrecision precision) { - return getType(basicType, precision, EvqTemporary, - 1, 1); + return getType(basicType, precision, EvqTemporary, 1, 1); } static const TType *getType(TBasicType basicType, - unsigned char primarySize = 1, + unsigned char primarySize = 1, unsigned char secondarySize = 1) { - return getType(basicType, EbpUndefined, EvqGlobal, - primarySize, secondarySize); + return getType(basicType, EbpUndefined, EvqGlobal, primarySize, secondarySize); } static const TType *getType(TBasicType basicType, TQualifier qualifier, - unsigned char primarySize = 1, + unsigned char primarySize = 1, unsigned char secondarySize = 1) { - return getType(basicType, EbpUndefined, qualifier, - primarySize, secondarySize); + return getType(basicType, EbpUndefined, qualifier, primarySize, secondarySize); } static const TType *getType(TBasicType basicType, TPrecision precision, @@ -51,12 +49,9 @@ class TCache unsigned char secondarySize); private: - TCache() - { - } + TCache(); - union TypeKey - { + union TypeKey { TypeKey(TBasicType basicType, TPrecision precision, TQualifier qualifier, @@ -74,12 +69,9 @@ class TCache } components; uint64_t value; - bool operator < (const TypeKey &other) const - { - return value < other.value; - } + bool operator<(const TypeKey &other) const { return value < other.value; } }; - typedef std::map TypeMap; + typedef std::map TypeMap; TypeMap mTypes; TPoolAllocator mAllocator; @@ -87,4 +79,6 @@ class TCache static TCache *sCache; }; +} // namespace sh + #endif // COMPILER_TRANSLATOR_CACHE_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/CallDAG.cpp b/src/3rdparty/angle/src/compiler/translator/CallDAG.cpp index 10f0eb937c..5f54e80898 100644 --- a/src/3rdparty/angle/src/compiler/translator/CallDAG.cpp +++ b/src/3rdparty/angle/src/compiler/translator/CallDAG.cpp @@ -9,16 +9,22 @@ // order. #include "compiler/translator/CallDAG.h" -#include "compiler/translator/InfoSink.h" + +#include "compiler/translator/Diagnostics.h" +#include "compiler/translator/IntermTraverse.h" +#include "compiler/translator/SymbolTable.h" + +namespace sh +{ // The CallDAGCreator does all the processing required to create the CallDAG // structure so that the latter contains only the necessary variables. class CallDAG::CallDAGCreator : public TIntermTraverser { public: - CallDAGCreator(TInfoSinkBase *info) + CallDAGCreator(TDiagnostics *diagnostics) : TIntermTraverser(true, false, true), - mCreationInfo(info), + mDiagnostics(diagnostics), mCurrentFunction(nullptr), mCurrentIndex(0) { @@ -35,7 +41,6 @@ class CallDAG::CallDAGCreator : public TIntermTraverser InitResult result = assignIndicesInternal(&it.second); if (result != INITDAG_SUCCESS) { - *mCreationInfo << "\n"; return result; } } @@ -44,6 +49,7 @@ class CallDAG::CallDAGCreator : public TIntermTraverser skipped++; } } + ASSERT(mFunctions.size() == mCurrentIndex + skipped); return INITDAG_SUCCESS; } @@ -75,147 +81,196 @@ class CallDAG::CallDAGCreator : public TIntermTraverser record.callees.push_back(static_cast(callee->index)); } - (*idToIndex)[data.node->getFunctionId()] = static_cast(data.index); + (*idToIndex)[data.node->getFunctionSymbolInfo()->getId().get()] = + static_cast(data.index); } } private: - struct CreatorFunctionData { - CreatorFunctionData() - : node(nullptr), - index(0), - indexAssigned(false), - visiting(false) - { - } + CreatorFunctionData() : node(nullptr), index(0), indexAssigned(false), visiting(false) {} - std::set callees; - TIntermAggregate *node; + std::set callees; + TIntermFunctionDefinition *node; TString name; size_t index; bool indexAssigned; bool visiting; }; + bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override + { + // Create the record if need be and remember the node. + if (visit == PreVisit) + { + auto it = mFunctions.find(node->getFunctionSymbolInfo()->getId().get()); + + if (it == mFunctions.end()) + { + mCurrentFunction = &mFunctions[node->getFunctionSymbolInfo()->getId().get()]; + mCurrentFunction->name = node->getFunctionSymbolInfo()->getName(); + } + else + { + mCurrentFunction = &it->second; + ASSERT(mCurrentFunction->name == node->getFunctionSymbolInfo()->getName()); + } + + mCurrentFunction->node = node; + } + else if (visit == PostVisit) + { + mCurrentFunction = nullptr; + } + return true; + } + + bool visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *node) override + { + ASSERT(visit == PreVisit); + if (mCurrentFunction != nullptr) + { + return false; + } + + // Function declaration, create an empty record. + auto &record = mFunctions[node->getFunctionSymbolInfo()->getId().get()]; + record.name = node->getFunctionSymbolInfo()->getName(); + + // No need to traverse the parameters. + return false; + } + // Aggregates the AST node for each function as well as the name of the functions called by it bool visitAggregate(Visit visit, TIntermAggregate *node) override { - switch (node->getOp()) + if (visit == PreVisit && node->getOp() == EOpCallFunctionInAST) { - case EOpPrototype: - if (visit == PreVisit) + // Function call, add the callees + auto it = mFunctions.find(node->getFunctionSymbolInfo()->getId().get()); + ASSERT(it != mFunctions.end()); + + // We might be traversing the initializer of a global variable. Even though function + // calls in global scope are forbidden by the parser, some subsequent AST + // transformations can add them to emulate particular features. + if (mCurrentFunction) { - // Function declaration, create an empty record. - auto& record = mFunctions[node->getName()]; - record.name = node->getName(); + mCurrentFunction->callees.insert(&it->second); } - break; - case EOpFunction: - { - // Function definition, create the record if need be and remember the node. - if (visit == PreVisit) - { - auto it = mFunctions.find(node->getName()); - - if (it == mFunctions.end()) - { - mCurrentFunction = &mFunctions[node->getName()]; - } - else - { - mCurrentFunction = &it->second; - } - - mCurrentFunction->node = node; - mCurrentFunction->name = node->getName(); - - } - else if (visit == PostVisit) - { - mCurrentFunction = nullptr; - } - break; - } - case EOpFunctionCall: - { - // Function call, add the callees - if (visit == PreVisit) - { - // Do not handle calls to builtin functions - if (node->isUserDefined()) - { - auto it = mFunctions.find(node->getName()); - ASSERT(it != mFunctions.end()); - - // We might be in a top-level function call to set a global variable - if (mCurrentFunction) - { - mCurrentFunction->callees.insert(&it->second); - } - } - } - break; - } - default: - break; } return true; } // Recursively assigns indices to a sub DAG - InitResult assignIndicesInternal(CreatorFunctionData *function) + InitResult assignIndicesInternal(CreatorFunctionData *root) { - ASSERT(function); + // Iterative implementation of the index assignment algorithm. A recursive version + // would be prettier but since the CallDAG creation runs before the limiting of the + // call depth, we might get stack overflows (computation of the call depth uses the + // CallDAG). - if (!function->node) - { - *mCreationInfo << "Undefined function '" << function->name - << ")' used in the following call chain:"; - return INITDAG_UNDEFINED; - } + ASSERT(root); - if (function->indexAssigned) + if (root->indexAssigned) { return INITDAG_SUCCESS; } - if (function->visiting) - { - if (mCreationInfo) - { - *mCreationInfo << "Recursive function call in the following call chain:" << function->name; - } - return INITDAG_RECURSION; - } - function->visiting = true; + // If we didn't have to detect recursion, functionsToProcess could be a simple queue + // in which we add the function being processed's callees. However in order to detect + // recursion we need to know which functions we are currently visiting. For that reason + // functionsToProcess will look like a concatenation of segments of the form + // [F visiting = true, subset of F callees with visiting = false] and the following + // segment (if any) will be start with a callee of F. + // This way we can remember when we started visiting a function, to put visiting back + // to false. + TVector functionsToProcess; + functionsToProcess.push_back(root); - for (auto &callee : function->callees) + InitResult result = INITDAG_SUCCESS; + + std::stringstream errorStream; + + while (!functionsToProcess.empty()) { - InitResult result = assignIndicesInternal(callee); + CreatorFunctionData *function = functionsToProcess.back(); + + if (function->visiting) + { + function->visiting = false; + function->index = mCurrentIndex++; + function->indexAssigned = true; + + functionsToProcess.pop_back(); + continue; + } + + if (!function->node) + { + errorStream << "Undefined function '" << function->name + << ")' used in the following call chain:"; + result = INITDAG_UNDEFINED; + break; + } + + if (function->indexAssigned) + { + functionsToProcess.pop_back(); + continue; + } + + function->visiting = true; + + for (auto callee : function->callees) + { + functionsToProcess.push_back(callee); + + // Check if the callee is already being visited after pushing it so that it appears + // in the chain printed in the info log. + if (callee->visiting) + { + errorStream << "Recursive function call in the following call chain:"; + result = INITDAG_RECURSION; + break; + } + } + if (result != INITDAG_SUCCESS) { - // We know that there is an issue with the call chain in the AST, - // print the link of the chain we were processing. - if (mCreationInfo) - { - *mCreationInfo << " <- " << function->name << ")"; - } - return result; + break; } } - function->index = mCurrentIndex++; - function->indexAssigned = true; + // The call chain is made of the function we were visiting when the error was detected. + if (result != INITDAG_SUCCESS) + { + bool first = true; + for (auto function : functionsToProcess) + { + if (function->visiting) + { + if (!first) + { + errorStream << " -> "; + } + errorStream << function->name << ")"; + first = false; + } + } + if (mDiagnostics) + { + std::string errorStr = errorStream.str(); + mDiagnostics->globalError(errorStr.c_str()); + } + } - function->visiting = false; - return INITDAG_SUCCESS; + return result; } - TInfoSinkBase *mCreationInfo; + TDiagnostics *mDiagnostics; - std::map mFunctions; + std::map mFunctions; CreatorFunctionData *mCurrentFunction; size_t mCurrentIndex; }; @@ -232,13 +287,9 @@ CallDAG::~CallDAG() const size_t CallDAG::InvalidIndex = std::numeric_limits::max(); -size_t CallDAG::findIndex(const TIntermAggregate *function) const +size_t CallDAG::findIndex(const TFunctionSymbolInfo *functionInfo) const { - TOperator op = function->getOp(); - ASSERT(op == EOpPrototype || op == EOpFunction || op == EOpFunctionCall); - UNUSED_ASSERTION_VARIABLE(op); - - auto it = mFunctionIdToIndex.find(function->getFunctionId()); + auto it = mFunctionIdToIndex.find(functionInfo->getId().get()); if (it == mFunctionIdToIndex.end()) { @@ -258,7 +309,7 @@ const CallDAG::Record &CallDAG::getRecordFromIndex(size_t index) const const CallDAG::Record &CallDAG::getRecord(const TIntermAggregate *function) const { - size_t index = findIndex(function); + size_t index = findIndex(function->getFunctionSymbolInfo()); ASSERT(index != InvalidIndex && index < mRecords.size()); return mRecords[index]; } @@ -274,9 +325,9 @@ void CallDAG::clear() mFunctionIdToIndex.clear(); } -CallDAG::InitResult CallDAG::init(TIntermNode *root, TInfoSinkBase *info) +CallDAG::InitResult CallDAG::init(TIntermNode *root, TDiagnostics *diagnostics) { - CallDAGCreator creator(info); + CallDAGCreator creator(diagnostics); // Creates the mapping of functions to callees root->traverse(&creator); @@ -291,3 +342,5 @@ CallDAG::InitResult CallDAG::init(TIntermNode *root, TInfoSinkBase *info) creator.fillDataStructures(&mRecords, &mFunctionIdToIndex); return INITDAG_SUCCESS; } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/CallDAG.h b/src/3rdparty/angle/src/compiler/translator/CallDAG.h index 06c377db00..155081c9a2 100644 --- a/src/3rdparty/angle/src/compiler/translator/CallDAG.h +++ b/src/3rdparty/angle/src/compiler/translator/CallDAG.h @@ -14,8 +14,9 @@ #include #include "compiler/translator/IntermNode.h" -#include "compiler/translator/VariableInfo.h" +namespace sh +{ // The translator needs to analyze the the graph of the function calls // to run checks and analyses; since in GLSL recursion is not allowed @@ -24,7 +25,7 @@ // can be reused by multiple analyses. // // It stores a vector of function records, with one record per function. -// Records are accessed by index but a mangled function name can be converted +// Records are accessed by index but a function symbol id can be converted // to the index of the corresponding record. The records mostly contain the // AST node of the function and the indices of the function's callees. // @@ -41,7 +42,7 @@ class CallDAG : angle::NonCopyable struct Record { std::string name; - TIntermAggregate *node; + TIntermFunctionDefinition *node; std::vector callees; }; @@ -53,11 +54,11 @@ class CallDAG : angle::NonCopyable }; // Returns INITDAG_SUCCESS if it was able to create the DAG, otherwise prints - // the initialization error in info, if present. - InitResult init(TIntermNode *root, TInfoSinkBase *info); + // the initialization error in diagnostics, if present. + InitResult init(TIntermNode *root, TDiagnostics *diagnostics); // Returns InvalidIndex if the function wasn't found - size_t findIndex(const TIntermAggregate *function) const; + size_t findIndex(const TFunctionSymbolInfo *functionInfo) const; const Record &getRecordFromIndex(size_t index) const; const Record &getRecord(const TIntermAggregate *function) const; @@ -65,6 +66,7 @@ class CallDAG : angle::NonCopyable void clear(); const static size_t InvalidIndex; + private: std::vector mRecords; std::map mFunctionIdToIndex; @@ -72,4 +74,6 @@ class CallDAG : angle::NonCopyable class CallDAGCreator; }; +} // namespace sh + #endif // COMPILER_TRANSLATOR_CALLDAG_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/ClampPointSize.cpp b/src/3rdparty/angle/src/compiler/translator/ClampPointSize.cpp new file mode 100644 index 0000000000..8598a137f5 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/ClampPointSize.cpp @@ -0,0 +1,47 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ClampPointSize.cpp: Limit the value that is written to gl_PointSize. +// + +#include "compiler/translator/ClampPointSize.h" + +#include "compiler/translator/FindSymbolNode.h" +#include "compiler/translator/IntermNode_util.h" +#include "compiler/translator/RunAtTheEndOfShader.h" +#include "compiler/translator/SymbolTable.h" + +namespace sh +{ + +void ClampPointSize(TIntermBlock *root, float maxPointSize, TSymbolTable *symbolTable) +{ + // Only clamp gl_PointSize if it's used in the shader. + if (!FindSymbolNode(root, TString("gl_PointSize"), EbtFloat)) + { + return; + } + + TIntermSymbol *pointSizeNode = ReferenceBuiltInVariable("gl_PointSize", *symbolTable, 100); + + TConstantUnion *maxPointSizeConstant = new TConstantUnion(); + maxPointSizeConstant->setFConst(maxPointSize); + TIntermConstantUnion *maxPointSizeNode = + new TIntermConstantUnion(maxPointSizeConstant, TType(EbtFloat, EbpHigh, EvqConst)); + + // min(gl_PointSize, maxPointSize) + TIntermSequence *minArguments = new TIntermSequence(); + minArguments->push_back(pointSizeNode->deepCopy()); + minArguments->push_back(maxPointSizeNode); + TIntermTyped *clampedPointSize = + CreateBuiltInFunctionCallNode("min", minArguments, *symbolTable, 100); + + // gl_PointSize = min(gl_PointSize, maxPointSize) + TIntermBinary *assignPointSize = new TIntermBinary(EOpAssign, pointSizeNode, clampedPointSize); + + RunAtTheEndOfShader(root, assignPointSize, symbolTable); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/ClampPointSize.h b/src/3rdparty/angle/src/compiler/translator/ClampPointSize.h new file mode 100644 index 0000000000..0c71ae6b0d --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/ClampPointSize.h @@ -0,0 +1,22 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ClampPointSize.h: Limit the value that is written to gl_PointSize. +// + +#ifndef COMPILER_TRANSLATOR_CLAMPPOINTSIZE_H_ +#define COMPILER_TRANSLATOR_CLAMPPOINTSIZE_H_ + +namespace sh +{ + +class TIntermBlock; +class TSymbolTable; + +void ClampPointSize(TIntermBlock *root, float maxPointSize, TSymbolTable *symbolTable); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_CLAMPPOINTSIZE_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/CodeGen.cpp b/src/3rdparty/angle/src/compiler/translator/CodeGen.cpp index f099bccf15..3e25cc2339 100644 --- a/src/3rdparty/angle/src/compiler/translator/CodeGen.cpp +++ b/src/3rdparty/angle/src/compiler/translator/CodeGen.cpp @@ -6,71 +6,70 @@ #ifdef ANGLE_ENABLE_ESSL #include "compiler/translator/TranslatorESSL.h" -#endif +#endif // ANGLE_ENABLE_ESSL #ifdef ANGLE_ENABLE_GLSL #include "compiler/translator/TranslatorGLSL.h" -#endif +#endif // ANGLE_ENABLE_GLSL #ifdef ANGLE_ENABLE_HLSL #include "compiler/translator/TranslatorHLSL.h" -#endif // ANGLE_ENABLE_HLSL +#endif // ANGLE_ENABLE_HLSL + +#ifdef ANGLE_ENABLE_VULKAN +#include "compiler/translator/TranslatorVulkan.h" +#endif // ANGLE_ENABLE_VULKAN + +#include "compiler/translator/util.h" + +namespace sh +{ // // This function must be provided to create the actual // compile object used by higher level code. It returns // a subclass of TCompiler. // -TCompiler* ConstructCompiler( - sh::GLenum type, ShShaderSpec spec, ShShaderOutput output) +TCompiler *ConstructCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output) { - switch (output) { - case SH_ESSL_OUTPUT: #ifdef ANGLE_ENABLE_ESSL + if (IsOutputESSL(output)) + { return new TranslatorESSL(type, spec); -#else - // This compiler is not supported in this - // configuration. Return NULL per the ShConstructCompiler API. - return nullptr; -#endif // ANGLE_ENABLE_ESSL - case SH_GLSL_130_OUTPUT: - case SH_GLSL_140_OUTPUT: - case SH_GLSL_150_CORE_OUTPUT: - case SH_GLSL_330_CORE_OUTPUT: - case SH_GLSL_400_CORE_OUTPUT: - case SH_GLSL_410_CORE_OUTPUT: - case SH_GLSL_420_CORE_OUTPUT: - case SH_GLSL_430_CORE_OUTPUT: - case SH_GLSL_440_CORE_OUTPUT: - case SH_GLSL_450_CORE_OUTPUT: - case SH_GLSL_COMPATIBILITY_OUTPUT: -#ifdef ANGLE_ENABLE_GLSL - return new TranslatorGLSL(type, spec, output); -#else - // This compiler is not supported in this - // configuration. Return NULL per the ShConstructCompiler API. - return nullptr; -#endif // ANGLE_ENABLE_GLSL - case SH_HLSL_3_0_OUTPUT: - case SH_HLSL_4_1_OUTPUT: - case SH_HLSL_4_0_FL9_3_OUTPUT: -#ifdef ANGLE_ENABLE_HLSL - return new TranslatorHLSL(type, spec, output); -#else - // This compiler is not supported in this - // configuration. Return NULL per the ShConstructCompiler API. - return nullptr; -#endif // ANGLE_ENABLE_HLSL - default: - // Unknown format. Return NULL per the ShConstructCompiler API. - return nullptr; } +#endif // ANGLE_ENABLE_ESSL + +#ifdef ANGLE_ENABLE_GLSL + if (IsOutputGLSL(output)) + { + return new TranslatorGLSL(type, spec, output); + } +#endif // ANGLE_ENABLE_GLSL + +#ifdef ANGLE_ENABLE_HLSL + if (IsOutputHLSL(output)) + { + return new TranslatorHLSL(type, spec, output); + } +#endif // ANGLE_ENABLE_HLSL + +#ifdef ANGLE_ENABLE_VULKAN + if (IsOutputVulkan(output)) + { + return new TranslatorVulkan(type, spec); + } +#endif // ANGLE_ENABLE_VULKAN + + // Unsupported compiler or unknown format. Return nullptr per the sh::ConstructCompiler API. + return nullptr; } // // Delete the compiler made by ConstructCompiler // -void DeleteCompiler(TCompiler* compiler) +void DeleteCompiler(TCompiler *compiler) { - delete compiler; + SafeDelete(compiler); } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/CollectVariables.cpp b/src/3rdparty/angle/src/compiler/translator/CollectVariables.cpp new file mode 100644 index 0000000000..bd8cbc971a --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/CollectVariables.cpp @@ -0,0 +1,869 @@ +// +// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// CollectVariables.cpp: Collect lists of shader interface variables based on the AST. + +#include "compiler/translator/CollectVariables.h" + +#include "angle_gl.h" +#include "common/utilities.h" +#include "compiler/translator/HashNames.h" +#include "compiler/translator/IntermTraverse.h" +#include "compiler/translator/SymbolTable.h" +#include "compiler/translator/util.h" + +namespace sh +{ + +namespace +{ + +BlockLayoutType GetBlockLayoutType(TLayoutBlockStorage blockStorage) +{ + switch (blockStorage) + { + case EbsPacked: + return BLOCKLAYOUT_PACKED; + case EbsShared: + return BLOCKLAYOUT_SHARED; + case EbsStd140: + return BLOCKLAYOUT_STD140; + case EbsStd430: + return BLOCKLAYOUT_STD430; + default: + UNREACHABLE(); + return BLOCKLAYOUT_SHARED; + } +} + +// TODO(jiawei.shao@intel.com): implement GL_OES_shader_io_blocks. +BlockType GetBlockType(TQualifier qualifier) +{ + switch (qualifier) + { + case EvqUniform: + return BlockType::BLOCK_UNIFORM; + case EvqBuffer: + return BlockType::BLOCK_BUFFER; + case EvqPerVertexIn: + return BlockType::BLOCK_IN; + default: + UNREACHABLE(); + return BlockType::BLOCK_UNIFORM; + } +} + +template +VarT *FindVariable(const TString &name, std::vector *infoList) +{ + // TODO(zmo): optimize this function. + for (size_t ii = 0; ii < infoList->size(); ++ii) + { + if ((*infoList)[ii].name.c_str() == name) + return &((*infoList)[ii]); + } + + return nullptr; +} + +// Note that this shouldn't be called for interface blocks - static use information is collected for +// individual fields in case of interface blocks. +void MarkStaticallyUsed(ShaderVariable *variable) +{ + if (!variable->staticUse) + { + if (variable->isStruct()) + { + // Conservatively assume all fields are statically used as well. + for (auto &field : variable->fields) + { + MarkStaticallyUsed(&field); + } + } + variable->staticUse = true; + } +} + +ShaderVariable *FindVariableInInterfaceBlock(const TString &name, + const TInterfaceBlock *interfaceBlock, + std::vector *infoList) +{ + ASSERT(interfaceBlock); + InterfaceBlock *namedBlock = FindVariable(interfaceBlock->name(), infoList); + ASSERT(namedBlock); + + // Set static use on the parent interface block here + namedBlock->staticUse = true; + return FindVariable(name, &namedBlock->fields); +} + +// Traverses the intermediate tree to collect all attributes, uniforms, varyings, fragment outputs, +// and interface blocks. +class CollectVariablesTraverser : public TIntermTraverser +{ + public: + CollectVariablesTraverser(std::vector *attribs, + std::vector *outputVariables, + std::vector *uniforms, + std::vector *inputVaryings, + std::vector *outputVaryings, + std::vector *uniformBlocks, + std::vector *shaderStorageBlocks, + std::vector *inBlocks, + ShHashFunction64 hashFunction, + TSymbolTable *symbolTable, + int shaderVersion, + GLenum shaderType, + const TExtensionBehavior &extensionBehavior); + + void visitSymbol(TIntermSymbol *symbol) override; + bool visitDeclaration(Visit, TIntermDeclaration *node) override; + bool visitBinary(Visit visit, TIntermBinary *binaryNode) override; + + private: + std::string getMappedName(const TName &name) const; + + void setCommonVariableProperties(const TType &type, + const TName &name, + ShaderVariable *variableOut) const; + + Attribute recordAttribute(const TIntermSymbol &variable) const; + OutputVariable recordOutputVariable(const TIntermSymbol &variable) const; + Varying recordVarying(const TIntermSymbol &variable) const; + void recordInterfaceBlock(const TType &interfaceBlockType, + InterfaceBlock *interfaceBlock) const; + Uniform recordUniform(const TIntermSymbol &variable) const; + + void setBuiltInInfoFromSymbolTable(const char *name, ShaderVariable *info); + + void recordBuiltInVaryingUsed(const char *name, + bool *addedFlag, + std::vector *varyings); + void recordBuiltInFragmentOutputUsed(const char *name, bool *addedFlag); + void recordBuiltInAttributeUsed(const char *name, bool *addedFlag); + InterfaceBlock *recordGLInUsed(const TType &glInType); + InterfaceBlock *findNamedInterfaceBlock(const TString &name) const; + + std::vector *mAttribs; + std::vector *mOutputVariables; + std::vector *mUniforms; + std::vector *mInputVaryings; + std::vector *mOutputVaryings; + std::vector *mUniformBlocks; + std::vector *mShaderStorageBlocks; + std::vector *mInBlocks; + + std::map mInterfaceBlockFields; + + // Shader uniforms + bool mDepthRangeAdded; + + // Vertex Shader builtins + bool mInstanceIDAdded; + bool mVertexIDAdded; + bool mPointSizeAdded; + + // Vertex Shader and Geometry Shader builtins + bool mPositionAdded; + + // Fragment Shader builtins + bool mPointCoordAdded; + bool mFrontFacingAdded; + bool mFragCoordAdded; + bool mLastFragDataAdded; + bool mFragColorAdded; + bool mFragDataAdded; + bool mFragDepthEXTAdded; + bool mFragDepthAdded; + bool mSecondaryFragColorEXTAdded; + bool mSecondaryFragDataEXTAdded; + + // Geometry Shader builtins + bool mPerVertexInAdded; + bool mPrimitiveIDInAdded; + bool mInvocationIDAdded; + + // Geometry Shader and Fragment Shader builtins + bool mPrimitiveIDAdded; + bool mLayerAdded; + + ShHashFunction64 mHashFunction; + + int mShaderVersion; + GLenum mShaderType; + const TExtensionBehavior &mExtensionBehavior; +}; + +CollectVariablesTraverser::CollectVariablesTraverser( + std::vector *attribs, + std::vector *outputVariables, + std::vector *uniforms, + std::vector *inputVaryings, + std::vector *outputVaryings, + std::vector *uniformBlocks, + std::vector *shaderStorageBlocks, + std::vector *inBlocks, + ShHashFunction64 hashFunction, + TSymbolTable *symbolTable, + int shaderVersion, + GLenum shaderType, + const TExtensionBehavior &extensionBehavior) + : TIntermTraverser(true, false, false, symbolTable), + mAttribs(attribs), + mOutputVariables(outputVariables), + mUniforms(uniforms), + mInputVaryings(inputVaryings), + mOutputVaryings(outputVaryings), + mUniformBlocks(uniformBlocks), + mShaderStorageBlocks(shaderStorageBlocks), + mInBlocks(inBlocks), + mDepthRangeAdded(false), + mInstanceIDAdded(false), + mVertexIDAdded(false), + mPointSizeAdded(false), + mPositionAdded(false), + mPointCoordAdded(false), + mFrontFacingAdded(false), + mFragCoordAdded(false), + mLastFragDataAdded(false), + mFragColorAdded(false), + mFragDataAdded(false), + mFragDepthEXTAdded(false), + mFragDepthAdded(false), + mSecondaryFragColorEXTAdded(false), + mSecondaryFragDataEXTAdded(false), + mPerVertexInAdded(false), + mPrimitiveIDInAdded(false), + mInvocationIDAdded(false), + mPrimitiveIDAdded(false), + mLayerAdded(false), + mHashFunction(hashFunction), + mShaderVersion(shaderVersion), + mShaderType(shaderType), + mExtensionBehavior(extensionBehavior) +{ +} + +std::string CollectVariablesTraverser::getMappedName(const TName &name) const +{ + return HashName(name, mHashFunction, nullptr).c_str(); +} + +void CollectVariablesTraverser::setBuiltInInfoFromSymbolTable(const char *name, + ShaderVariable *info) +{ + TVariable *symbolTableVar = + reinterpret_cast(mSymbolTable->findBuiltIn(name, mShaderVersion)); + ASSERT(symbolTableVar); + const TType &type = symbolTableVar->getType(); + + info->name = name; + info->mappedName = name; + info->type = GLVariableType(type); + info->precision = GLVariablePrecision(type); + if (auto *arraySizes = type.getArraySizes()) + { + info->arraySizes.assign(arraySizes->begin(), arraySizes->end()); + } +} + +void CollectVariablesTraverser::recordBuiltInVaryingUsed(const char *name, + bool *addedFlag, + std::vector *varyings) +{ + ASSERT(varyings); + if (!(*addedFlag)) + { + Varying info; + setBuiltInInfoFromSymbolTable(name, &info); + info.staticUse = true; + info.isInvariant = mSymbolTable->isVaryingInvariant(name); + varyings->push_back(info); + (*addedFlag) = true; + } +} + +void CollectVariablesTraverser::recordBuiltInFragmentOutputUsed(const char *name, bool *addedFlag) +{ + if (!(*addedFlag)) + { + OutputVariable info; + setBuiltInInfoFromSymbolTable(name, &info); + info.staticUse = true; + mOutputVariables->push_back(info); + (*addedFlag) = true; + } +} + +void CollectVariablesTraverser::recordBuiltInAttributeUsed(const char *name, bool *addedFlag) +{ + if (!(*addedFlag)) + { + Attribute info; + setBuiltInInfoFromSymbolTable(name, &info); + info.staticUse = true; + info.location = -1; + mAttribs->push_back(info); + (*addedFlag) = true; + } +} + +InterfaceBlock *CollectVariablesTraverser::recordGLInUsed(const TType &glInType) +{ + if (!mPerVertexInAdded) + { + ASSERT(glInType.getQualifier() == EvqPerVertexIn); + InterfaceBlock info; + recordInterfaceBlock(glInType, &info); + info.staticUse = true; + + mPerVertexInAdded = true; + mInBlocks->push_back(info); + return &mInBlocks->back(); + } + else + { + return FindVariable("gl_PerVertex", mInBlocks); + } +} + +// We want to check whether a uniform/varying is statically used +// because we only count the used ones in packing computing. +// Also, gl_FragCoord, gl_PointCoord, and gl_FrontFacing count +// toward varying counting if they are statically used in a fragment +// shader. +void CollectVariablesTraverser::visitSymbol(TIntermSymbol *symbol) +{ + ASSERT(symbol != nullptr); + + if (symbol->getName().isInternal()) + { + // Internal variables are not collected. + return; + } + + ShaderVariable *var = nullptr; + const TString &symbolName = symbol->getName().getString(); + + if (IsVaryingIn(symbol->getQualifier())) + { + var = FindVariable(symbolName, mInputVaryings); + } + else if (IsVaryingOut(symbol->getQualifier())) + { + var = FindVariable(symbolName, mOutputVaryings); + } + else if (symbol->getType().getBasicType() == EbtInterfaceBlock) + { + UNREACHABLE(); + } + else if (symbolName == "gl_DepthRange") + { + ASSERT(symbol->getQualifier() == EvqUniform); + + if (!mDepthRangeAdded) + { + Uniform info; + const char kName[] = "gl_DepthRange"; + info.name = kName; + info.mappedName = kName; + info.type = GL_NONE; + info.precision = GL_NONE; + info.staticUse = true; + + ShaderVariable nearInfo(GL_FLOAT); + const char kNearName[] = "near"; + nearInfo.name = kNearName; + nearInfo.mappedName = kNearName; + nearInfo.precision = GL_HIGH_FLOAT; + nearInfo.staticUse = true; + + ShaderVariable farInfo(GL_FLOAT); + const char kFarName[] = "far"; + farInfo.name = kFarName; + farInfo.mappedName = kFarName; + farInfo.precision = GL_HIGH_FLOAT; + farInfo.staticUse = true; + + ShaderVariable diffInfo(GL_FLOAT); + const char kDiffName[] = "diff"; + diffInfo.name = kDiffName; + diffInfo.mappedName = kDiffName; + diffInfo.precision = GL_HIGH_FLOAT; + diffInfo.staticUse = true; + + info.fields.push_back(nearInfo); + info.fields.push_back(farInfo); + info.fields.push_back(diffInfo); + + mUniforms->push_back(info); + mDepthRangeAdded = true; + } + } + else + { + switch (symbol->getQualifier()) + { + case EvqAttribute: + case EvqVertexIn: + var = FindVariable(symbolName, mAttribs); + break; + case EvqFragmentOut: + var = FindVariable(symbolName, mOutputVariables); + break; + case EvqUniform: + { + const TInterfaceBlock *interfaceBlock = symbol->getType().getInterfaceBlock(); + if (interfaceBlock) + { + var = FindVariableInInterfaceBlock(symbolName, interfaceBlock, mUniformBlocks); + } + else + { + var = FindVariable(symbolName, mUniforms); + } + + // It's an internal error to reference an undefined user uniform + ASSERT(symbolName.compare(0, 3, "gl_") != 0 || var); + } + break; + case EvqBuffer: + { + const TInterfaceBlock *interfaceBlock = symbol->getType().getInterfaceBlock(); + var = + FindVariableInInterfaceBlock(symbolName, interfaceBlock, mShaderStorageBlocks); + } + break; + case EvqFragCoord: + recordBuiltInVaryingUsed("gl_FragCoord", &mFragCoordAdded, mInputVaryings); + return; + case EvqFrontFacing: + recordBuiltInVaryingUsed("gl_FrontFacing", &mFrontFacingAdded, mInputVaryings); + return; + case EvqPointCoord: + recordBuiltInVaryingUsed("gl_PointCoord", &mPointCoordAdded, mInputVaryings); + return; + case EvqInstanceID: + // Whenever the SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW option is set, + // gl_InstanceID is added inside expressions to initialize ViewID_OVR and + // InstanceID. gl_InstanceID is not added to the symbol table for ESSL1 shaders + // which makes it necessary to populate the type information explicitly instead of + // extracting it from the symbol table. + if (!mInstanceIDAdded) + { + Attribute info; + const char kName[] = "gl_InstanceID"; + info.name = kName; + info.mappedName = kName; + info.type = GL_INT; + info.precision = GL_HIGH_INT; // Defined by spec. + info.staticUse = true; + info.location = -1; + mAttribs->push_back(info); + mInstanceIDAdded = true; + } + return; + case EvqVertexID: + recordBuiltInAttributeUsed("gl_VertexID", &mVertexIDAdded); + return; + case EvqPosition: + recordBuiltInVaryingUsed("gl_Position", &mPositionAdded, mOutputVaryings); + return; + case EvqPointSize: + recordBuiltInVaryingUsed("gl_PointSize", &mPointSizeAdded, mOutputVaryings); + return; + case EvqLastFragData: + recordBuiltInVaryingUsed("gl_LastFragData", &mLastFragDataAdded, mInputVaryings); + return; + case EvqFragColor: + recordBuiltInFragmentOutputUsed("gl_FragColor", &mFragColorAdded); + return; + case EvqFragData: + if (!mFragDataAdded) + { + OutputVariable info; + setBuiltInInfoFromSymbolTable("gl_FragData", &info); + if (!IsExtensionEnabled(mExtensionBehavior, TExtension::EXT_draw_buffers)) + { + ASSERT(info.arraySizes.size() == 1u); + info.arraySizes.back() = 1u; + } + info.staticUse = true; + mOutputVariables->push_back(info); + mFragDataAdded = true; + } + return; + case EvqFragDepthEXT: + recordBuiltInFragmentOutputUsed("gl_FragDepthEXT", &mFragDepthEXTAdded); + return; + case EvqFragDepth: + recordBuiltInFragmentOutputUsed("gl_FragDepth", &mFragDepthAdded); + return; + case EvqSecondaryFragColorEXT: + recordBuiltInFragmentOutputUsed("gl_SecondaryFragColorEXT", + &mSecondaryFragColorEXTAdded); + return; + case EvqSecondaryFragDataEXT: + recordBuiltInFragmentOutputUsed("gl_SecondaryFragDataEXT", + &mSecondaryFragDataEXTAdded); + return; + case EvqInvocationID: + recordBuiltInVaryingUsed("gl_InvocationID", &mInvocationIDAdded, mInputVaryings); + break; + case EvqPrimitiveIDIn: + recordBuiltInVaryingUsed("gl_PrimitiveIDIn", &mPrimitiveIDInAdded, mInputVaryings); + break; + case EvqPrimitiveID: + if (mShaderType == GL_GEOMETRY_SHADER_OES) + { + recordBuiltInVaryingUsed("gl_PrimitiveID", &mPrimitiveIDAdded, mOutputVaryings); + } + else + { + ASSERT(mShaderType == GL_FRAGMENT_SHADER); + recordBuiltInVaryingUsed("gl_PrimitiveID", &mPrimitiveIDAdded, mInputVaryings); + } + break; + case EvqLayer: + if (mShaderType == GL_GEOMETRY_SHADER_OES) + { + recordBuiltInVaryingUsed("gl_Layer", &mLayerAdded, mOutputVaryings); + } + else if (mShaderType == GL_FRAGMENT_SHADER) + { + recordBuiltInVaryingUsed("gl_Layer", &mLayerAdded, mInputVaryings); + } + else + { + ASSERT(mShaderType == GL_VERTEX_SHADER && + IsExtensionEnabled(mExtensionBehavior, TExtension::OVR_multiview)); + } + break; + default: + break; + } + } + if (var) + { + MarkStaticallyUsed(var); + } +} + +void CollectVariablesTraverser::setCommonVariableProperties(const TType &type, + const TName &name, + ShaderVariable *variableOut) const +{ + ASSERT(variableOut); + + const TStructure *structure = type.getStruct(); + + if (!structure) + { + variableOut->type = GLVariableType(type); + variableOut->precision = GLVariablePrecision(type); + } + else + { + // Structures use a NONE type that isn't exposed outside ANGLE. + variableOut->type = GL_NONE; + variableOut->structName = structure->name().c_str(); + + const TFieldList &fields = structure->fields(); + + for (TField *field : fields) + { + // Regardless of the variable type (uniform, in/out etc.) its fields are always plain + // ShaderVariable objects. + ShaderVariable fieldVariable; + setCommonVariableProperties(*field->type(), TName(field->name()), &fieldVariable); + variableOut->fields.push_back(fieldVariable); + } + } + variableOut->name = name.getString().c_str(); + variableOut->mappedName = getMappedName(name); + + if (auto *arraySizes = type.getArraySizes()) + { + variableOut->arraySizes.assign(arraySizes->begin(), arraySizes->end()); + } +} + +Attribute CollectVariablesTraverser::recordAttribute(const TIntermSymbol &variable) const +{ + const TType &type = variable.getType(); + ASSERT(!type.getStruct()); + + Attribute attribute; + setCommonVariableProperties(type, variable.getName(), &attribute); + + attribute.location = type.getLayoutQualifier().location; + return attribute; +} + +OutputVariable CollectVariablesTraverser::recordOutputVariable(const TIntermSymbol &variable) const +{ + const TType &type = variable.getType(); + ASSERT(!type.getStruct()); + + OutputVariable outputVariable; + setCommonVariableProperties(type, variable.getName(), &outputVariable); + + outputVariable.location = type.getLayoutQualifier().location; + return outputVariable; +} + +Varying CollectVariablesTraverser::recordVarying(const TIntermSymbol &variable) const +{ + const TType &type = variable.getType(); + + Varying varying; + setCommonVariableProperties(type, variable.getName(), &varying); + varying.location = type.getLayoutQualifier().location; + + switch (type.getQualifier()) + { + case EvqVaryingIn: + case EvqVaryingOut: + case EvqVertexOut: + case EvqSmoothOut: + case EvqFlatOut: + case EvqCentroidOut: + case EvqGeometryOut: + if (mSymbolTable->isVaryingInvariant(std::string(variable.getSymbol().c_str())) || + type.isInvariant()) + { + varying.isInvariant = true; + } + break; + default: + break; + } + + varying.interpolation = GetInterpolationType(type.getQualifier()); + return varying; +} + +// TODO(jiawei.shao@intel.com): implement GL_OES_shader_io_blocks. +void CollectVariablesTraverser::recordInterfaceBlock(const TType &interfaceBlockType, + InterfaceBlock *interfaceBlock) const +{ + ASSERT(interfaceBlockType.getBasicType() == EbtInterfaceBlock); + ASSERT(interfaceBlock); + + const TInterfaceBlock *blockType = interfaceBlockType.getInterfaceBlock(); + ASSERT(blockType); + + interfaceBlock->name = blockType->name().c_str(); + interfaceBlock->mappedName = getMappedName(TName(blockType->name())); + interfaceBlock->instanceName = + (blockType->hasInstanceName() ? blockType->instanceName().c_str() : ""); + ASSERT(!interfaceBlockType.isArrayOfArrays()); // Disallowed by GLSL ES 3.10 section 4.3.9 + interfaceBlock->arraySize = interfaceBlockType.isArray() ? interfaceBlockType.getOutermostArraySize() : 0; + + interfaceBlock->blockType = GetBlockType(interfaceBlockType.getQualifier()); + if (interfaceBlock->blockType == BlockType::BLOCK_UNIFORM || + interfaceBlock->blockType == BlockType::BLOCK_BUFFER) + { + interfaceBlock->isRowMajorLayout = (blockType->matrixPacking() == EmpRowMajor); + interfaceBlock->binding = blockType->blockBinding(); + interfaceBlock->layout = GetBlockLayoutType(blockType->blockStorage()); + } + + // Gather field information + for (const TField *field : blockType->fields()) + { + const TType &fieldType = *field->type(); + + InterfaceBlockField fieldVariable; + setCommonVariableProperties(fieldType, TName(field->name()), &fieldVariable); + fieldVariable.isRowMajorLayout = + (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor); + interfaceBlock->fields.push_back(fieldVariable); + } +} + +Uniform CollectVariablesTraverser::recordUniform(const TIntermSymbol &variable) const +{ + Uniform uniform; + setCommonVariableProperties(variable.getType(), variable.getName(), &uniform); + uniform.binding = variable.getType().getLayoutQualifier().binding; + uniform.location = variable.getType().getLayoutQualifier().location; + uniform.offset = variable.getType().getLayoutQualifier().offset; + return uniform; +} + +bool CollectVariablesTraverser::visitDeclaration(Visit, TIntermDeclaration *node) +{ + const TIntermSequence &sequence = *(node->getSequence()); + ASSERT(!sequence.empty()); + + const TIntermTyped &typedNode = *(sequence.front()->getAsTyped()); + TQualifier qualifier = typedNode.getQualifier(); + + bool isShaderVariable = qualifier == EvqAttribute || qualifier == EvqVertexIn || + qualifier == EvqFragmentOut || qualifier == EvqUniform || + IsVarying(qualifier); + + if (typedNode.getBasicType() != EbtInterfaceBlock && !isShaderVariable) + { + return true; + } + + for (TIntermNode *variableNode : sequence) + { + // The only case in which the sequence will not contain a TIntermSymbol node is + // initialization. It will contain a TInterBinary node in that case. Since attributes, + // uniforms, varyings, outputs and interface blocks cannot be initialized in a shader, we + // must have only TIntermSymbol nodes in the sequence in the cases we are interested in. + const TIntermSymbol &variable = *variableNode->getAsSymbolNode(); + if (variable.getName().isInternal()) + { + // Internal variables are not collected. + continue; + } + + // TODO(jiawei.shao@intel.com): implement GL_OES_shader_io_blocks. + if (typedNode.getBasicType() == EbtInterfaceBlock) + { + InterfaceBlock interfaceBlock; + recordInterfaceBlock(variable.getType(), &interfaceBlock); + + switch (qualifier) + { + case EvqUniform: + mUniformBlocks->push_back(interfaceBlock); + break; + case EvqBuffer: + mShaderStorageBlocks->push_back(interfaceBlock); + break; + default: + UNREACHABLE(); + } + } + else + { + switch (qualifier) + { + case EvqAttribute: + case EvqVertexIn: + mAttribs->push_back(recordAttribute(variable)); + break; + case EvqFragmentOut: + mOutputVariables->push_back(recordOutputVariable(variable)); + break; + case EvqUniform: + mUniforms->push_back(recordUniform(variable)); + break; + default: + if (IsVaryingIn(qualifier)) + { + mInputVaryings->push_back(recordVarying(variable)); + } + else + { + ASSERT(IsVaryingOut(qualifier)); + mOutputVaryings->push_back(recordVarying(variable)); + } + break; + } + } + } + + // None of the recorded variables can have initializers, so we don't need to traverse the + // declarators. + return false; +} + +// TODO(jiawei.shao@intel.com): add search on mInBlocks and mOutBlocks when implementing +// GL_OES_shader_io_blocks. +InterfaceBlock *CollectVariablesTraverser::findNamedInterfaceBlock(const TString &blockName) const +{ + InterfaceBlock *namedBlock = FindVariable(blockName, mUniformBlocks); + if (!namedBlock) + { + namedBlock = FindVariable(blockName, mShaderStorageBlocks); + } + return namedBlock; +} + +bool CollectVariablesTraverser::visitBinary(Visit, TIntermBinary *binaryNode) +{ + if (binaryNode->getOp() == EOpIndexDirectInterfaceBlock) + { + // NOTE: we do not determine static use for individual blocks of an array + TIntermTyped *blockNode = binaryNode->getLeft()->getAsTyped(); + ASSERT(blockNode); + + TIntermConstantUnion *constantUnion = binaryNode->getRight()->getAsConstantUnion(); + ASSERT(constantUnion); + + InterfaceBlock *namedBlock = nullptr; + + bool traverseIndexExpression = false; + TIntermBinary *interfaceIndexingNode = blockNode->getAsBinaryNode(); + if (interfaceIndexingNode) + { + TIntermTyped *interfaceNode = interfaceIndexingNode->getLeft()->getAsTyped(); + ASSERT(interfaceNode); + + const TType &interfaceType = interfaceNode->getType(); + if (interfaceType.getQualifier() == EvqPerVertexIn) + { + namedBlock = recordGLInUsed(interfaceType); + ASSERT(namedBlock); + + // We need to continue traversing to collect useful variables in the index + // expression of gl_in. + traverseIndexExpression = true; + } + } + + const TInterfaceBlock *interfaceBlock = blockNode->getType().getInterfaceBlock(); + if (!namedBlock) + { + namedBlock = findNamedInterfaceBlock(interfaceBlock->name()); + } + ASSERT(namedBlock); + namedBlock->staticUse = true; + unsigned int fieldIndex = static_cast(constantUnion->getIConst(0)); + ASSERT(fieldIndex < namedBlock->fields.size()); + namedBlock->fields[fieldIndex].staticUse = true; + + if (traverseIndexExpression) + { + ASSERT(interfaceIndexingNode); + interfaceIndexingNode->getRight()->traverse(this); + } + return false; + } + + return true; +} + +} // anonymous namespace + +void CollectVariables(TIntermBlock *root, + std::vector *attributes, + std::vector *outputVariables, + std::vector *uniforms, + std::vector *inputVaryings, + std::vector *outputVaryings, + std::vector *uniformBlocks, + std::vector *shaderStorageBlocks, + std::vector *inBlocks, + ShHashFunction64 hashFunction, + TSymbolTable *symbolTable, + int shaderVersion, + GLenum shaderType, + const TExtensionBehavior &extensionBehavior) +{ + CollectVariablesTraverser collect(attributes, outputVariables, uniforms, inputVaryings, + outputVaryings, uniformBlocks, shaderStorageBlocks, inBlocks, + hashFunction, symbolTable, shaderVersion, shaderType, + extensionBehavior); + root->traverse(&collect); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/CollectVariables.h b/src/3rdparty/angle/src/compiler/translator/CollectVariables.h new file mode 100644 index 0000000000..4d0d1192e0 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/CollectVariables.h @@ -0,0 +1,37 @@ +// +// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// CollectVariables.h: Collect lists of shader interface variables based on the AST. + +#ifndef COMPILER_TRANSLATOR_COLLECTVARIABLES_H_ +#define COMPILER_TRANSLATOR_COLLECTVARIABLES_H_ + +#include + +#include "compiler/translator/ExtensionBehavior.h" + +namespace sh +{ + +class TIntermBlock; +class TSymbolTable; + +void CollectVariables(TIntermBlock *root, + std::vector *attributes, + std::vector *outputVariables, + std::vector *uniforms, + std::vector *inputVaryings, + std::vector *outputVaryings, + std::vector *uniformBlocks, + std::vector *shaderStorageBlocks, + std::vector *inBlocks, + ShHashFunction64 hashFunction, + TSymbolTable *symbolTable, + int shaderVersion, + GLenum shaderType, + const TExtensionBehavior &extensionBehavior); +} + +#endif // COMPILER_TRANSLATOR_COLLECTVARIABLES_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/Common.h b/src/3rdparty/angle/src/compiler/translator/Common.h index 60223232af..cb3a680d85 100644 --- a/src/3rdparty/angle/src/compiler/translator/Common.h +++ b/src/3rdparty/angle/src/compiler/translator/Common.h @@ -10,15 +10,21 @@ #include #include #include +#include #include #include #include #include "common/angleutils.h" #include "common/debug.h" +#include "common/third_party/smhasher/src/PMurHash.h" #include "compiler/translator/PoolAlloc.h" -struct TSourceLoc { +namespace sh +{ + +struct TSourceLoc +{ int first_file; int first_line; int last_file; @@ -29,25 +35,25 @@ struct TSourceLoc { // Put POOL_ALLOCATOR_NEW_DELETE in base classes to make them use this scheme. // #define POOL_ALLOCATOR_NEW_DELETE() \ - void* operator new(size_t s) { return GetGlobalPoolAllocator()->allocate(s); } \ - void* operator new(size_t, void *_Where) { return (_Where); } \ - void operator delete(void*) { } \ - void operator delete(void *, void *) { } \ - void* operator new[](size_t s) { return GetGlobalPoolAllocator()->allocate(s); } \ - void* operator new[](size_t, void *_Where) { return (_Where); } \ - void operator delete[](void*) { } \ - void operator delete[](void *, void *) { } + void *operator new(size_t s) { return GetGlobalPoolAllocator()->allocate(s); } \ + void *operator new(size_t, void *_Where) { return (_Where); } \ + void operator delete(void *) {} \ + void operator delete(void *, void *) {} \ + void *operator new[](size_t s) { return GetGlobalPoolAllocator()->allocate(s); } \ + void *operator new[](size_t, void *_Where) { return (_Where); } \ + void operator delete[](void *) {} \ + void operator delete[](void *, void *) {} // // Pool version of string. // typedef pool_allocator TStringAllocator; -typedef std::basic_string , TStringAllocator> TString; +typedef std::basic_string, TStringAllocator> TString; typedef std::basic_ostringstream, TStringAllocator> TStringStream; -inline TString* NewPoolTString(const char* s) +inline TString *NewPoolTString(const char *s) { - void* memory = GetGlobalPoolAllocator()->allocate(sizeof(TString)); - return new(memory) TString(s); + void *memory = GetGlobalPoolAllocator()->allocate(sizeof(TString)); + return new (memory) TString(s); } // @@ -64,21 +70,44 @@ template class TVector : public std::vector> { public: + POOL_ALLOCATOR_NEW_DELETE(); + typedef typename std::vector>::size_type size_type; TVector() : std::vector>() {} TVector(const pool_allocator &a) : std::vector>(a) {} TVector(size_type i) : std::vector>(i) {} }; +template , class CMP = std::equal_to> +class TUnorderedMap : public std::unordered_map>> +{ + public: + POOL_ALLOCATOR_NEW_DELETE(); + typedef pool_allocator> tAllocator; + + TUnorderedMap() : std::unordered_map() {} + // use correct two-stage name lookup supported in gcc 3.4 and above + TUnorderedMap(const tAllocator &a) + : std::unordered_map( + std::unordered_map::key_compare(), + a) + { + } +}; + template > class TMap : public std::map>> { public: + POOL_ALLOCATOR_NEW_DELETE(); typedef pool_allocator> tAllocator; TMap() : std::map() {} // use correct two-stage name lookup supported in gcc 3.4 and above - TMap(const tAllocator& a) : std::map(std::map::key_compare(), a) {} + TMap(const tAllocator &a) + : std::map(std::map::key_compare(), a) + { + } }; // Integer to TString conversion @@ -92,4 +121,18 @@ inline TString str(T i) return buffer; } -#endif // COMPILER_TRANSLATOR_COMMON_H_ +} // namespace sh + +namespace std +{ +template <> +struct hash +{ + size_t operator()(const sh::TString &s) const + { + return angle::PMurHash32(0, s.data(), static_cast(s.length())); + } +}; +} // namespace std + +#endif // COMPILER_TRANSLATOR_COMMON_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/Compiler.cpp b/src/3rdparty/angle/src/compiler/translator/Compiler.cpp index 18524ce569..2f411cb58c 100644 --- a/src/3rdparty/angle/src/compiler/translator/Compiler.cpp +++ b/src/3rdparty/angle/src/compiler/translator/Compiler.cpp @@ -4,91 +4,193 @@ // found in the LICENSE file. // -#include "compiler/translator/Cache.h" #include "compiler/translator/Compiler.h" -#include "compiler/translator/CallDAG.h" -#include "compiler/translator/ForLoopUnroll.h" -#include "compiler/translator/Initialize.h" -#include "compiler/translator/InitializeParseContext.h" -#include "compiler/translator/InitializeVariables.h" -#include "compiler/translator/ParseContext.h" -#include "compiler/translator/PruneEmptyDeclarations.h" -#include "compiler/translator/RegenerateStructNames.h" -#include "compiler/translator/RemovePow.h" -#include "compiler/translator/RenameFunction.h" -#include "compiler/translator/RewriteDoWhile.h" -#include "compiler/translator/ScalarizeVecAndMatConstructorArgs.h" -#include "compiler/translator/UnfoldShortCircuitAST.h" -#include "compiler/translator/ValidateLimitations.h" -#include "compiler/translator/ValidateOutputs.h" -#include "compiler/translator/VariablePacker.h" -#include "compiler/translator/depgraph/DependencyGraph.h" -#include "compiler/translator/depgraph/DependencyGraphOutput.h" -#include "compiler/translator/timing/RestrictFragmentShaderTiming.h" -#include "compiler/translator/timing/RestrictVertexShaderTiming.h" -#include "third_party/compiler/ArrayBoundsClamper.h" + +#include + #include "angle_gl.h" #include "common/utilities.h" +#include "compiler/translator/AddAndTrueToLoopCondition.h" +#include "compiler/translator/Cache.h" +#include "compiler/translator/CallDAG.h" +#include "compiler/translator/ClampPointSize.h" +#include "compiler/translator/CollectVariables.h" +#include "compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.h" +#include "compiler/translator/DeferGlobalInitializers.h" +#include "compiler/translator/EmulateGLFragColorBroadcast.h" +#include "compiler/translator/EmulatePrecision.h" +#include "compiler/translator/Initialize.h" +#include "compiler/translator/InitializeVariables.h" +#include "compiler/translator/IntermNodePatternMatcher.h" +#include "compiler/translator/IsASTDepthBelowLimit.h" +#include "compiler/translator/OutputTree.h" +#include "compiler/translator/ParseContext.h" +#include "compiler/translator/PruneNoOps.h" +#include "compiler/translator/RegenerateStructNames.h" +#include "compiler/translator/RemoveArrayLengthMethod.h" +#include "compiler/translator/RemoveEmptySwitchStatements.h" +#include "compiler/translator/RemoveInvariantDeclaration.h" +#include "compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.h" +#include "compiler/translator/RemovePow.h" +#include "compiler/translator/RemoveUnreferencedVariables.h" +#include "compiler/translator/RewriteDoWhile.h" +#include "compiler/translator/ScalarizeVecAndMatConstructorArgs.h" +#include "compiler/translator/SeparateDeclarations.h" +#include "compiler/translator/SimplifyLoopConditions.h" +#include "compiler/translator/SplitSequenceOperator.h" +#include "compiler/translator/UnfoldShortCircuitAST.h" +#include "compiler/translator/UseInterfaceBlockFields.h" +#include "compiler/translator/ValidateLimitations.h" +#include "compiler/translator/ValidateMaxParameters.h" +#include "compiler/translator/ValidateOutputs.h" +#include "compiler/translator/ValidateVaryingLocations.h" +#include "compiler/translator/VariablePacker.h" +#include "compiler/translator/VectorizeVectorScalarArithmetic.h" +#include "compiler/translator/util.h" +#include "third_party/compiler/ArrayBoundsClamper.h" + +namespace sh +{ + +namespace +{ + +#if defined(ANGLE_ENABLE_FUZZER_CORPUS_OUTPUT) +void DumpFuzzerCase(char const *const *shaderStrings, + size_t numStrings, + uint32_t type, + uint32_t spec, + uint32_t output, + uint64_t options) +{ + static int fileIndex = 0; + + std::ostringstream o; + o << "corpus/" << fileIndex++ << ".sample"; + std::string s = o.str(); + + // Must match the input format of the fuzzer + FILE *f = fopen(s.c_str(), "w"); + fwrite(&type, sizeof(type), 1, f); + fwrite(&spec, sizeof(spec), 1, f); + fwrite(&output, sizeof(output), 1, f); + fwrite(&options, sizeof(options), 1, f); + + char zero[128 - 20] = {0}; + fwrite(&zero, 128 - 20, 1, f); + + for (size_t i = 0; i < numStrings; i++) + { + fwrite(shaderStrings[i], sizeof(char), strlen(shaderStrings[i]), f); + } + fwrite(&zero, 1, 1, f); + + fclose(f); +} +#endif // defined(ANGLE_ENABLE_FUZZER_CORPUS_OUTPUT) +} // anonymous namespace bool IsWebGLBasedSpec(ShShaderSpec spec) { - return (spec == SH_WEBGL_SPEC || - spec == SH_CSS_SHADERS_SPEC || - spec == SH_WEBGL2_SPEC); + return (spec == SH_WEBGL_SPEC || spec == SH_WEBGL2_SPEC || spec == SH_WEBGL3_SPEC); } bool IsGLSL130OrNewer(ShShaderOutput output) { - return (output == SH_GLSL_130_OUTPUT || - output == SH_GLSL_140_OUTPUT || - output == SH_GLSL_150_CORE_OUTPUT || - output == SH_GLSL_330_CORE_OUTPUT || - output == SH_GLSL_400_CORE_OUTPUT || - output == SH_GLSL_410_CORE_OUTPUT || - output == SH_GLSL_420_CORE_OUTPUT || - output == SH_GLSL_430_CORE_OUTPUT || - output == SH_GLSL_440_CORE_OUTPUT || - output == SH_GLSL_450_CORE_OUTPUT); + return (output == SH_GLSL_130_OUTPUT || output == SH_GLSL_140_OUTPUT || + output == SH_GLSL_150_CORE_OUTPUT || output == SH_GLSL_330_CORE_OUTPUT || + output == SH_GLSL_400_CORE_OUTPUT || output == SH_GLSL_410_CORE_OUTPUT || + output == SH_GLSL_420_CORE_OUTPUT || output == SH_GLSL_430_CORE_OUTPUT || + output == SH_GLSL_440_CORE_OUTPUT || output == SH_GLSL_450_CORE_OUTPUT); +} + +bool IsGLSL420OrNewer(ShShaderOutput output) +{ + return (output == SH_GLSL_420_CORE_OUTPUT || output == SH_GLSL_430_CORE_OUTPUT || + output == SH_GLSL_440_CORE_OUTPUT || output == SH_GLSL_450_CORE_OUTPUT); +} + +bool IsGLSL410OrOlder(ShShaderOutput output) +{ + return (output == SH_GLSL_130_OUTPUT || output == SH_GLSL_140_OUTPUT || + output == SH_GLSL_150_CORE_OUTPUT || output == SH_GLSL_330_CORE_OUTPUT || + output == SH_GLSL_400_CORE_OUTPUT || output == SH_GLSL_410_CORE_OUTPUT); +} + +bool RemoveInvariant(sh::GLenum shaderType, + int shaderVersion, + ShShaderOutput outputType, + ShCompileOptions compileOptions) +{ + if ((compileOptions & SH_DONT_REMOVE_INVARIANT_FOR_FRAGMENT_INPUT) == 0 && + shaderType == GL_FRAGMENT_SHADER && IsGLSL420OrNewer(outputType)) + return true; + + if ((compileOptions & SH_REMOVE_INVARIANT_AND_CENTROID_FOR_ESSL3) != 0 && + shaderVersion >= 300 && shaderType == GL_VERTEX_SHADER) + return true; + + return false; } size_t GetGlobalMaxTokenSize(ShShaderSpec spec) { - // WebGL defines a max token legnth of 256, while ES2 leaves max token + // WebGL defines a max token length of 256, while ES2 leaves max token // size undefined. ES3 defines a max size of 1024 characters. switch (spec) { - case SH_WEBGL_SPEC: - case SH_CSS_SHADERS_SPEC: - return 256; - default: - return 1024; + case SH_WEBGL_SPEC: + return 256; + default: + return 1024; } } -namespace { +int GetMaxUniformVectorsForShaderType(GLenum shaderType, const ShBuiltInResources &resources) +{ + switch (shaderType) + { + case GL_VERTEX_SHADER: + return resources.MaxVertexUniformVectors; + case GL_FRAGMENT_SHADER: + return resources.MaxFragmentUniformVectors; + + // TODO (jiawei.shao@intel.com): check if we need finer-grained component counting + case GL_COMPUTE_SHADER: + return resources.MaxComputeUniformComponents / 4; + case GL_GEOMETRY_SHADER_OES: + return resources.MaxGeometryUniformComponents / 4; + default: + UNREACHABLE(); + return -1; + } +} + +namespace +{ class TScopedPoolAllocator { public: - TScopedPoolAllocator(TPoolAllocator* allocator) : mAllocator(allocator) + TScopedPoolAllocator(TPoolAllocator *allocator) : mAllocator(allocator) { mAllocator->push(); SetGlobalPoolAllocator(mAllocator); } ~TScopedPoolAllocator() { - SetGlobalPoolAllocator(NULL); + SetGlobalPoolAllocator(nullptr); mAllocator->pop(); } private: - TPoolAllocator* mAllocator; + TPoolAllocator *mAllocator; }; class TScopedSymbolTableLevel { public: - TScopedSymbolTableLevel(TSymbolTable* table) : mTable(table) + TScopedSymbolTableLevel(TSymbolTable *table) : mTable(table) { ASSERT(mTable->atBuiltInLevel()); mTable->push(); @@ -100,23 +202,25 @@ class TScopedSymbolTableLevel } private: - TSymbolTable* mTable; + TSymbolTable *mTable; }; int MapSpecToShaderVersion(ShShaderSpec spec) { switch (spec) { - case SH_GLES2_SPEC: - case SH_WEBGL_SPEC: - case SH_CSS_SHADERS_SPEC: - return 100; - case SH_GLES3_SPEC: - case SH_WEBGL2_SPEC: - return 300; - default: - UNREACHABLE(); - return 0; + case SH_GLES2_SPEC: + case SH_WEBGL_SPEC: + return 100; + case SH_GLES3_SPEC: + case SH_WEBGL2_SPEC: + return 300; + case SH_GLES3_1_SPEC: + case SH_WEBGL3_SPEC: + return 310; + default: + UNREACHABLE(); + return 0; } } @@ -130,22 +234,31 @@ TShHandleBase::TShHandleBase() TShHandleBase::~TShHandleBase() { - SetGlobalPoolAllocator(NULL); + SetGlobalPoolAllocator(nullptr); allocator.popAll(); } TCompiler::TCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output) - : shaderType(type), + : variablesCollected(false), + mGLPositionInitialized(false), + shaderType(type), shaderSpec(spec), outputType(output), maxUniformVectors(0), maxExpressionComplexity(0), maxCallStackDepth(0), + maxFunctionParameters(0), fragmentPrecisionHigh(false), clampingStrategy(SH_CLAMP_WITH_CLAMP_INTRINSIC), builtInFunctionEmulator(), - mSourcePath(NULL), - mTemporaryIndex(0) + mDiagnostics(infoSink.info), + mSourcePath(nullptr), + mComputeShaderLocalSizeDeclared(false), + mComputeShaderLocalSize(1), + mGeometryShaderMaxVertices(-1), + mGeometryShaderInvocations(0), + mGeometryShaderInputPrimitiveType(EptUndefined), + mGeometryShaderOutputPrimitiveType(EptUndefined) { } @@ -153,7 +266,7 @@ TCompiler::~TCompiler() { } -bool TCompiler::shouldRunLoopAndIndexingValidation(int compileOptions) const +bool TCompiler::shouldRunLoopAndIndexingValidation(ShCompileOptions compileOptions) const { // If compiling an ESSL 1.00 shader for WebGL, or if its been requested through the API, // validate loop and indexing as well (to verify that the shader only uses minimal functionality @@ -162,14 +275,15 @@ bool TCompiler::shouldRunLoopAndIndexingValidation(int compileOptions) const (compileOptions & SH_VALIDATE_LOOP_INDEXING); } -bool TCompiler::Init(const ShBuiltInResources& resources) +bool TCompiler::Init(const ShBuiltInResources &resources) { shaderVersion = 100; - maxUniformVectors = (shaderType == GL_VERTEX_SHADER) ? - resources.MaxVertexUniformVectors : - resources.MaxFragmentUniformVectors; + + maxUniformVectors = GetMaxUniformVectorsForShaderType(shaderType, resources); + maxExpressionComplexity = resources.MaxExpressionComplexity; - maxCallStackDepth = resources.MaxCallStackDepth; + maxCallStackDepth = resources.MaxCallStackDepth; + maxFunctionParameters = resources.MaxFunctionParameters; SetGlobalPoolAllocator(&allocator); @@ -187,15 +301,16 @@ bool TCompiler::Init(const ShBuiltInResources& resources) return true; } -TIntermNode *TCompiler::compileTreeForTesting(const char* const shaderStrings[], - size_t numStrings, int compileOptions) +TIntermBlock *TCompiler::compileTreeForTesting(const char *const shaderStrings[], + size_t numStrings, + ShCompileOptions compileOptions) { return compileTreeImpl(shaderStrings, numStrings, compileOptions); } -TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[], - size_t numStrings, - const int compileOptions) +TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[], + size_t numStrings, + const ShCompileOptions compileOptions) { clearResults(); @@ -213,191 +328,347 @@ TIntermNode *TCompiler::compileTreeImpl(const char *const shaderStrings[], ++firstSource; } - TIntermediate intermediate(infoSink); - TParseContext parseContext(symbolTable, extensionBehavior, intermediate, shaderType, shaderSpec, - compileOptions, true, infoSink, getResources()); + TParseContext parseContext(symbolTable, extensionBehavior, shaderType, shaderSpec, + compileOptions, true, &mDiagnostics, getResources()); parseContext.setFragmentPrecisionHighOnESSL1(fragmentPrecisionHigh); - SetGlobalParseContext(&parseContext); // We preserve symbols at the built-in level from compile-to-compile. // Start pushing the user-defined symbols at global level. TScopedSymbolTableLevel scopedSymbolLevel(&symbolTable); // Parse shader. - bool success = - (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], nullptr, &parseContext) == 0) && - (parseContext.getTreeRoot() != nullptr); - - shaderVersion = parseContext.getShaderVersion(); - if (success && MapSpecToShaderVersion(shaderSpec) < shaderVersion) + if (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], nullptr, + &parseContext) != 0) { - infoSink.info.prefix(EPrefixError); - infoSink.info << "unsupported shader version"; - success = false; + return nullptr; } - TIntermNode *root = nullptr; - - if (success) + if (parseContext.getTreeRoot() == nullptr) { - mPragma = parseContext.pragma(); - if (mPragma.stdgl.invariantAll) - { - symbolTable.setGlobalInvariant(); - } - - root = parseContext.getTreeRoot(); - root = intermediate.postProcess(root); - - // Highp might have been auto-enabled based on shader version - fragmentPrecisionHigh = parseContext.getFragmentPrecisionHigh(); - - // Disallow expressions deemed too complex. - if (success && (compileOptions & SH_LIMIT_EXPRESSION_COMPLEXITY)) - success = limitExpressionComplexity(root); - - // Create the function DAG and check there is no recursion - if (success) - success = initCallDag(root); - - if (success && (compileOptions & SH_LIMIT_CALL_STACK_DEPTH)) - success = checkCallDepth(); - - // Checks which functions are used and if "main" exists - if (success) - { - functionMetadata.clear(); - functionMetadata.resize(mCallDag.size()); - success = tagUsedFunctions(); - } - - if (success && !(compileOptions & SH_DONT_PRUNE_UNUSED_FUNCTIONS)) - success = pruneUnusedFunctions(root); - - // Prune empty declarations to work around driver bugs and to keep declaration output simple. - if (success) - PruneEmptyDeclarations(root); - - if (success && shaderVersion == 300 && shaderType == GL_FRAGMENT_SHADER) - success = validateOutputs(root); - - if (success && shouldRunLoopAndIndexingValidation(compileOptions)) - success = validateLimitations(root); - - if (success && (compileOptions & SH_TIMING_RESTRICTIONS)) - success = enforceTimingRestrictions(root, (compileOptions & SH_DEPENDENCY_GRAPH) != 0); - - if (success && shaderSpec == SH_CSS_SHADERS_SPEC) - rewriteCSSShader(root); - - // Unroll for-loop markup needs to happen after validateLimitations pass. - if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX)) - { - ForLoopUnrollMarker marker(ForLoopUnrollMarker::kIntegerIndex, - shouldRunLoopAndIndexingValidation(compileOptions)); - root->traverse(&marker); - } - if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX)) - { - ForLoopUnrollMarker marker(ForLoopUnrollMarker::kSamplerArrayIndex, - shouldRunLoopAndIndexingValidation(compileOptions)); - root->traverse(&marker); - if (marker.samplerArrayIndexIsFloatLoopIndex()) - { - infoSink.info.prefix(EPrefixError); - infoSink.info << "sampler array index is float loop index"; - success = false; - } - } - - // Built-in function emulation needs to happen after validateLimitations pass. - if (success) - { - initBuiltInFunctionEmulator(&builtInFunctionEmulator, compileOptions); - builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(root); - } - - // Clamping uniform array bounds needs to happen after validateLimitations pass. - if (success && (compileOptions & SH_CLAMP_INDIRECT_ARRAY_BOUNDS)) - arrayBoundsClamper.MarkIndirectArrayBoundsForClamping(root); - - // gl_Position is always written in compatibility output mode - if (success && shaderType == GL_VERTEX_SHADER && - ((compileOptions & SH_INIT_GL_POSITION) || - (outputType == SH_GLSL_COMPATIBILITY_OUTPUT))) - initializeGLPosition(root); - - // This pass might emit short circuits so keep it before the short circuit unfolding - if (success && (compileOptions & SH_REWRITE_DO_WHILE_LOOPS)) - RewriteDoWhile(root, getTemporaryIndex()); - - if (success && (compileOptions & SH_UNFOLD_SHORT_CIRCUIT)) - { - UnfoldShortCircuitAST unfoldShortCircuit; - root->traverse(&unfoldShortCircuit); - unfoldShortCircuit.updateTree(); - } - - if (success && (compileOptions & SH_REMOVE_POW_WITH_CONSTANT_EXPONENT)) - { - RemovePow(root); - } - - if (success && shouldCollectVariables(compileOptions)) - { - collectVariables(root); - if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS) - { - success = enforcePackingRestrictions(); - if (!success) - { - infoSink.info.prefix(EPrefixError); - infoSink.info << "too many uniforms"; - } - } - if (success && shaderType == GL_VERTEX_SHADER && - (compileOptions & SH_INIT_VARYINGS_WITHOUT_STATIC_USE)) - initializeVaryingsWithoutStaticUse(root); - } - - if (success && (compileOptions & SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS)) - { - ScalarizeVecAndMatConstructorArgs scalarizer( - shaderType, fragmentPrecisionHigh); - root->traverse(&scalarizer); - } - - if (success && (compileOptions & SH_REGENERATE_STRUCT_NAMES)) - { - RegenerateStructNames gen(symbolTable, shaderVersion); - root->traverse(&gen); - } + return nullptr; } - SetGlobalParseContext(NULL); - if (success) - return root; + setASTMetadata(parseContext); - return NULL; + if (MapSpecToShaderVersion(shaderSpec) < shaderVersion) + { + mDiagnostics.globalError("unsupported shader version"); + return nullptr; + } + + TIntermBlock *root = parseContext.getTreeRoot(); + if (!checkAndSimplifyAST(root, parseContext, compileOptions)) + { + return nullptr; + } + + return root; } -bool TCompiler::compile(const char* const shaderStrings[], - size_t numStrings, int compileOptions) +void TCompiler::setASTMetadata(const TParseContext &parseContext) { + shaderVersion = parseContext.getShaderVersion(); + + mPragma = parseContext.pragma(); + symbolTable.setGlobalInvariant(mPragma.stdgl.invariantAll); + + mComputeShaderLocalSizeDeclared = parseContext.isComputeShaderLocalSizeDeclared(); + mComputeShaderLocalSize = parseContext.getComputeShaderLocalSize(); + + mNumViews = parseContext.getNumViews(); + + // Highp might have been auto-enabled based on shader version + fragmentPrecisionHigh = parseContext.getFragmentPrecisionHigh(); + + if (shaderType == GL_GEOMETRY_SHADER_OES) + { + mGeometryShaderInputPrimitiveType = parseContext.getGeometryShaderInputPrimitiveType(); + mGeometryShaderOutputPrimitiveType = parseContext.getGeometryShaderOutputPrimitiveType(); + mGeometryShaderMaxVertices = parseContext.getGeometryShaderMaxVertices(); + mGeometryShaderInvocations = parseContext.getGeometryShaderInvocations(); + } +} + +bool TCompiler::checkAndSimplifyAST(TIntermBlock *root, + const TParseContext &parseContext, + ShCompileOptions compileOptions) +{ + // Disallow expressions deemed too complex. + if ((compileOptions & SH_LIMIT_EXPRESSION_COMPLEXITY) && !limitExpressionComplexity(root)) + { + return false; + } + + // We prune no-ops to work around driver bugs and to keep AST processing and output simple. + // The following kinds of no-ops are pruned: + // 1. Empty declarations "int;". + // 2. Literal statements: "1.0;". The ESSL output doesn't define a default precision + // for float, so float literal statements would end up with no precision which is + // invalid ESSL. + // After this empty declarations are not allowed in the AST. + PruneNoOps(root); + + // In case the last case inside a switch statement is a certain type of no-op, GLSL + // compilers in drivers may not accept it. In this case we clean up the dead code from the + // end of switch statements. This is also required because PruneNoOps may have left switch + // statements that only contained an empty declaration inside the final case in an invalid + // state. Relies on that PruneNoOps has already been run. + RemoveNoOpCasesFromEndOfSwitchStatements(root, &symbolTable); + + // Remove empty switch statements - this makes output simpler. + RemoveEmptySwitchStatements(root); + + // Create the function DAG and check there is no recursion + if (!initCallDag(root)) + { + return false; + } + + if ((compileOptions & SH_LIMIT_CALL_STACK_DEPTH) && !checkCallDepth()) + { + return false; + } + + // Checks which functions are used and if "main" exists + functionMetadata.clear(); + functionMetadata.resize(mCallDag.size()); + if (!tagUsedFunctions()) + { + return false; + } + + if (!(compileOptions & SH_DONT_PRUNE_UNUSED_FUNCTIONS)) + { + pruneUnusedFunctions(root); + } + + if (shaderVersion >= 310 && !ValidateVaryingLocations(root, &mDiagnostics, shaderType)) + { + return false; + } + + if (shaderVersion >= 300 && shaderType == GL_FRAGMENT_SHADER && + !ValidateOutputs(root, getExtensionBehavior(), compileResources.MaxDrawBuffers, + &mDiagnostics)) + { + return false; + } + + if (shouldRunLoopAndIndexingValidation(compileOptions) && + !ValidateLimitations(root, shaderType, &symbolTable, shaderVersion, &mDiagnostics)) + { + return false; + } + + // Fail compilation if precision emulation not supported. + if (getResources().WEBGL_debug_shader_precision && getPragma().debugShaderPrecision && + !EmulatePrecision::SupportedInLanguage(outputType)) + { + mDiagnostics.globalError("Precision emulation not supported for this output type."); + return false; + } + + // Clamping uniform array bounds needs to happen after validateLimitations pass. + if (compileOptions & SH_CLAMP_INDIRECT_ARRAY_BOUNDS) + { + arrayBoundsClamper.MarkIndirectArrayBoundsForClamping(root); + } + + if ((compileOptions & SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW) && + parseContext.isExtensionEnabled(TExtension::OVR_multiview) && + getShaderType() != GL_COMPUTE_SHADER) + { + DeclareAndInitBuiltinsForInstancedMultiview(root, mNumViews, shaderType, compileOptions, + outputType, &symbolTable); + } + + // This pass might emit short circuits so keep it before the short circuit unfolding + if (compileOptions & SH_REWRITE_DO_WHILE_LOOPS) + RewriteDoWhile(root, &symbolTable); + + if (compileOptions & SH_ADD_AND_TRUE_TO_LOOP_CONDITION) + sh::AddAndTrueToLoopCondition(root); + + if (compileOptions & SH_UNFOLD_SHORT_CIRCUIT) + { + UnfoldShortCircuitAST unfoldShortCircuit; + root->traverse(&unfoldShortCircuit); + unfoldShortCircuit.updateTree(); + } + + if (compileOptions & SH_REMOVE_POW_WITH_CONSTANT_EXPONENT) + { + RemovePow(root); + } + + if (compileOptions & SH_REGENERATE_STRUCT_NAMES) + { + RegenerateStructNames gen(&symbolTable, shaderVersion); + root->traverse(&gen); + } + + if (shaderType == GL_FRAGMENT_SHADER && shaderVersion == 100 && + compileResources.EXT_draw_buffers && compileResources.MaxDrawBuffers > 1 && + IsExtensionEnabled(extensionBehavior, TExtension::EXT_draw_buffers)) + { + EmulateGLFragColorBroadcast(root, compileResources.MaxDrawBuffers, &outputVariables, + &symbolTable, shaderVersion); + } + + // Split multi declarations and remove calls to array length(). + // Note that SimplifyLoopConditions needs to be run before any other AST transformations + // that may need to generate new statements from loop conditions or loop expressions. + SimplifyLoopConditions( + root, + IntermNodePatternMatcher::kMultiDeclaration | IntermNodePatternMatcher::kArrayLengthMethod, + &getSymbolTable(), getShaderVersion()); + + // Note that separate declarations need to be run before other AST transformations that + // generate new statements from expressions. + SeparateDeclarations(root); + + SplitSequenceOperator(root, IntermNodePatternMatcher::kArrayLengthMethod, &getSymbolTable(), + getShaderVersion()); + + RemoveArrayLengthMethod(root); + + RemoveUnreferencedVariables(root, &symbolTable); + + // Built-in function emulation needs to happen after validateLimitations pass. + // TODO(jmadill): Remove global pool allocator. + GetGlobalPoolAllocator()->lock(); + initBuiltInFunctionEmulator(&builtInFunctionEmulator, compileOptions); + GetGlobalPoolAllocator()->unlock(); + builtInFunctionEmulator.markBuiltInFunctionsForEmulation(root); + + if (compileOptions & SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS) + { + ScalarizeVecAndMatConstructorArgs(root, shaderType, fragmentPrecisionHigh, &symbolTable); + } + + if (shouldCollectVariables(compileOptions)) + { + ASSERT(!variablesCollected); + CollectVariables(root, &attributes, &outputVariables, &uniforms, &inputVaryings, + &outputVaryings, &uniformBlocks, &shaderStorageBlocks, &inBlocks, + hashFunction, &symbolTable, shaderVersion, shaderType, extensionBehavior); + collectInterfaceBlocks(); + variablesCollected = true; + if (compileOptions & SH_USE_UNUSED_STANDARD_SHARED_BLOCKS) + { + useAllMembersInUnusedStandardAndSharedBlocks(root); + } + if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS) + { + // Returns true if, after applying the packing rules in the GLSL ES 1.00.17 spec + // Appendix A, section 7, the shader does not use too many uniforms. + if (!CheckVariablesInPackingLimits(maxUniformVectors, uniforms)) + { + mDiagnostics.globalError("too many uniforms"); + return false; + } + } + if (compileOptions & SH_INIT_OUTPUT_VARIABLES) + { + initializeOutputVariables(root); + } + } + + // Removing invariant declarations must be done after collecting variables. + // Otherwise, built-in invariant declarations don't apply. + if (RemoveInvariant(shaderType, shaderVersion, outputType, compileOptions)) + { + RemoveInvariantDeclaration(root); + } + + // gl_Position is always written in compatibility output mode. + // It may have been already initialized among other output variables, in that case we don't + // need to initialize it twice. + if (shaderType == GL_VERTEX_SHADER && !mGLPositionInitialized && + ((compileOptions & SH_INIT_GL_POSITION) || (outputType == SH_GLSL_COMPATIBILITY_OUTPUT))) + { + initializeGLPosition(root); + mGLPositionInitialized = true; + } + + // DeferGlobalInitializers needs to be run before other AST transformations that generate new + // statements from expressions. But it's fine to run DeferGlobalInitializers after the above + // SplitSequenceOperator and RemoveArrayLengthMethod since they only have an effect on the AST + // on ESSL >= 3.00, and the initializers that need to be deferred can only exist in ESSL < 3.00. + bool initializeLocalsAndGlobals = + (compileOptions & SH_INITIALIZE_UNINITIALIZED_LOCALS) && !IsOutputHLSL(getOutputType()); + bool canUseLoopsToInitialize = !(compileOptions & SH_DONT_USE_LOOPS_TO_INITIALIZE_VARIABLES); + DeferGlobalInitializers(root, initializeLocalsAndGlobals, canUseLoopsToInitialize, &symbolTable); + + if (initializeLocalsAndGlobals) + { + // Initialize uninitialized local variables. + // In some cases initializing can generate extra statements in the parent block, such as + // when initializing nameless structs or initializing arrays in ESSL 1.00. In that case + // we need to first simplify loop conditions. We've already separated declarations + // earlier, which is also required. If we don't follow the Appendix A limitations, loop + // init statements can declare arrays or nameless structs and have multiple + // declarations. + + if (!shouldRunLoopAndIndexingValidation(compileOptions)) + { + SimplifyLoopConditions(root, + IntermNodePatternMatcher::kArrayDeclaration | + IntermNodePatternMatcher::kNamelessStructDeclaration, + &getSymbolTable(), getShaderVersion()); + } + + InitializeUninitializedLocals(root, getShaderVersion(), canUseLoopsToInitialize, + &getSymbolTable()); + } + + if (getShaderType() == GL_VERTEX_SHADER && (compileOptions & SH_CLAMP_POINT_SIZE)) + { + ClampPointSize(root, compileResources.MaxPointSize, &getSymbolTable()); + } + + if (compileOptions & SH_REWRITE_VECTOR_SCALAR_ARITHMETIC) + { + VectorizeVectorScalarArithmetic(root, &getSymbolTable()); + } + + return true; +} + +bool TCompiler::compile(const char *const shaderStrings[], + size_t numStrings, + ShCompileOptions compileOptionsIn) +{ +#if defined(ANGLE_ENABLE_FUZZER_CORPUS_OUTPUT) + DumpFuzzerCase(shaderStrings, numStrings, shaderType, shaderSpec, outputType, compileOptionsIn); +#endif // defined(ANGLE_ENABLE_FUZZER_CORPUS_OUTPUT) + if (numStrings == 0) return true; + ShCompileOptions compileOptions = compileOptionsIn; + + // Apply key workarounds. + if (shouldFlattenPragmaStdglInvariantAll()) + { + // This should be harmless to do in all cases, but for the moment, do it only conditionally. + compileOptions |= SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL; + } + TScopedPoolAllocator scopedAlloc(&allocator); - TIntermNode *root = compileTreeImpl(shaderStrings, numStrings, compileOptions); + TIntermBlock *root = compileTreeImpl(shaderStrings, numStrings, compileOptions); if (root) { if (compileOptions & SH_INTERMEDIATE_TREE) - TIntermediate::outputTree(root, infoSink.info); + OutputTree(root, infoSink.info); if (compileOptions & SH_OBJECT_CODE) - translate(root, compileOptions); + { + PerformanceDiagnostics perfDiagnostics(&mDiagnostics); + translate(root, compileOptions, &perfDiagnostics); + } // The IntermNode tree doesn't need to be deleted here, since the // memory will be freed in a big chunk by the PoolAllocator. @@ -408,37 +679,38 @@ bool TCompiler::compile(const char* const shaderStrings[], bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources) { + if (resources.MaxDrawBuffers < 1) + { + return false; + } + if (resources.EXT_blend_func_extended && resources.MaxDualSourceDrawBuffers < 1) + { + return false; + } + compileResources = resources; setResourceString(); - assert(symbolTable.isEmpty()); - symbolTable.push(); // COMMON_BUILTINS - symbolTable.push(); // ESSL1_BUILTINS - symbolTable.push(); // ESSL3_BUILTINS + ASSERT(symbolTable.isEmpty()); + symbolTable.push(); // COMMON_BUILTINS + symbolTable.push(); // ESSL1_BUILTINS + symbolTable.push(); // ESSL3_BUILTINS + symbolTable.push(); // ESSL3_1_BUILTINS + symbolTable.push(); // GLSL_BUILTINS - TPublicType integer; - integer.type = EbtInt; - integer.primarySize = 1; - integer.secondarySize = 1; - integer.array = false; - - TPublicType floatingPoint; - floatingPoint.type = EbtFloat; - floatingPoint.primarySize = 1; - floatingPoint.secondarySize = 1; - floatingPoint.array = false; - - switch(shaderType) + switch (shaderType) { - case GL_FRAGMENT_SHADER: - symbolTable.setDefaultPrecision(integer, EbpMedium); - break; - case GL_VERTEX_SHADER: - symbolTable.setDefaultPrecision(integer, EbpHigh); - symbolTable.setDefaultPrecision(floatingPoint, EbpHigh); - break; - default: - assert(false && "Language not supported"); + case GL_FRAGMENT_SHADER: + symbolTable.setDefaultPrecision(EbtInt, EbpMedium); + break; + case GL_VERTEX_SHADER: + case GL_COMPUTE_SHADER: + case GL_GEOMETRY_SHADER_OES: + symbolTable.setDefaultPrecision(EbtInt, EbpHigh); + symbolTable.setDefaultPrecision(EbtFloat, EbpHigh); + break; + default: + UNREACHABLE(); } // Set defaults for sampler types that have default precision, even those that are // only available if an extension exists. @@ -447,9 +719,13 @@ bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources) initSamplerDefaultPrecision(EbtSamplerCube); // SamplerExternalOES is specified in the extension to have default precision. initSamplerDefaultPrecision(EbtSamplerExternalOES); + // SamplerExternal2DY2YEXT is specified in the extension to have default precision. + initSamplerDefaultPrecision(EbtSamplerExternal2DY2YEXT); // It isn't specified whether Sampler2DRect has default precision. initSamplerDefaultPrecision(EbtSampler2DRect); + symbolTable.setDefaultPrecision(EbtAtomicCounter, EbpHigh); + InsertBuiltInFunctions(shaderType, shaderSpec, resources, symbolTable); IdentifyBuiltIns(shaderType, shaderSpec, resources, symbolTable); @@ -460,87 +736,149 @@ bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources) void TCompiler::initSamplerDefaultPrecision(TBasicType samplerType) { ASSERT(samplerType > EbtGuardSamplerBegin && samplerType < EbtGuardSamplerEnd); - TPublicType sampler; - sampler.primarySize = 1; - sampler.secondarySize = 1; - sampler.array = false; - sampler.type = samplerType; - symbolTable.setDefaultPrecision(sampler, EbpLow); + symbolTable.setDefaultPrecision(samplerType, EbpLow); } void TCompiler::setResourceString() { std::ostringstream strstream; + + // clang-format off strstream << ":MaxVertexAttribs:" << compileResources.MaxVertexAttribs - << ":MaxVertexUniformVectors:" << compileResources.MaxVertexUniformVectors - << ":MaxVaryingVectors:" << compileResources.MaxVaryingVectors - << ":MaxVertexTextureImageUnits:" << compileResources.MaxVertexTextureImageUnits - << ":MaxCombinedTextureImageUnits:" << compileResources.MaxCombinedTextureImageUnits - << ":MaxTextureImageUnits:" << compileResources.MaxTextureImageUnits - << ":MaxFragmentUniformVectors:" << compileResources.MaxFragmentUniformVectors - << ":MaxDrawBuffers:" << compileResources.MaxDrawBuffers - << ":OES_standard_derivatives:" << compileResources.OES_standard_derivatives - << ":OES_EGL_image_external:" << compileResources.OES_EGL_image_external - << ":ARB_texture_rectangle:" << compileResources.ARB_texture_rectangle - << ":EXT_draw_buffers:" << compileResources.EXT_draw_buffers - << ":FragmentPrecisionHigh:" << compileResources.FragmentPrecisionHigh - << ":MaxExpressionComplexity:" << compileResources.MaxExpressionComplexity - << ":MaxCallStackDepth:" << compileResources.MaxCallStackDepth - << ":EXT_blend_func_extended:" << compileResources.EXT_blend_func_extended - << ":EXT_frag_depth:" << compileResources.EXT_frag_depth - << ":EXT_shader_texture_lod:" << compileResources.EXT_shader_texture_lod - << ":EXT_shader_framebuffer_fetch:" << compileResources.EXT_shader_framebuffer_fetch - << ":NV_shader_framebuffer_fetch:" << compileResources.NV_shader_framebuffer_fetch - << ":ARM_shader_framebuffer_fetch:" << compileResources.ARM_shader_framebuffer_fetch - << ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors - << ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors - << ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset - << ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset - << ":MaxDualSourceDrawBuffers:" << compileResources.MaxDualSourceDrawBuffers - << ":NV_draw_buffers:" << compileResources.NV_draw_buffers - << ":WEBGL_debug_shader_precision:" << compileResources.WEBGL_debug_shader_precision; + << ":MaxVertexUniformVectors:" << compileResources.MaxVertexUniformVectors + << ":MaxVaryingVectors:" << compileResources.MaxVaryingVectors + << ":MaxVertexTextureImageUnits:" << compileResources.MaxVertexTextureImageUnits + << ":MaxCombinedTextureImageUnits:" << compileResources.MaxCombinedTextureImageUnits + << ":MaxTextureImageUnits:" << compileResources.MaxTextureImageUnits + << ":MaxFragmentUniformVectors:" << compileResources.MaxFragmentUniformVectors + << ":MaxDrawBuffers:" << compileResources.MaxDrawBuffers + << ":OES_standard_derivatives:" << compileResources.OES_standard_derivatives + << ":OES_EGL_image_external:" << compileResources.OES_EGL_image_external + << ":OES_EGL_image_external_essl3:" << compileResources.OES_EGL_image_external_essl3 + << ":NV_EGL_stream_consumer_external:" << compileResources.NV_EGL_stream_consumer_external + << ":ARB_texture_rectangle:" << compileResources.ARB_texture_rectangle + << ":EXT_draw_buffers:" << compileResources.EXT_draw_buffers + << ":FragmentPrecisionHigh:" << compileResources.FragmentPrecisionHigh + << ":MaxExpressionComplexity:" << compileResources.MaxExpressionComplexity + << ":MaxCallStackDepth:" << compileResources.MaxCallStackDepth + << ":MaxFunctionParameters:" << compileResources.MaxFunctionParameters + << ":EXT_blend_func_extended:" << compileResources.EXT_blend_func_extended + << ":EXT_frag_depth:" << compileResources.EXT_frag_depth + << ":EXT_shader_texture_lod:" << compileResources.EXT_shader_texture_lod + << ":EXT_shader_framebuffer_fetch:" << compileResources.EXT_shader_framebuffer_fetch + << ":NV_shader_framebuffer_fetch:" << compileResources.NV_shader_framebuffer_fetch + << ":ARM_shader_framebuffer_fetch:" << compileResources.ARM_shader_framebuffer_fetch + << ":OVR_multiview:" << compileResources.OVR_multiview + << ":EXT_YUV_target:" << compileResources.EXT_YUV_target + << ":OES_geometry_shader:" << compileResources.OES_geometry_shader + << ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors + << ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors + << ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset + << ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset + << ":MaxDualSourceDrawBuffers:" << compileResources.MaxDualSourceDrawBuffers + << ":MaxViewsOVR:" << compileResources.MaxViewsOVR + << ":NV_draw_buffers:" << compileResources.NV_draw_buffers + << ":WEBGL_debug_shader_precision:" << compileResources.WEBGL_debug_shader_precision + << ":MinProgramTextureGatherOffset:" << compileResources.MinProgramTextureGatherOffset + << ":MaxProgramTextureGatherOffset:" << compileResources.MaxProgramTextureGatherOffset + << ":MaxImageUnits:" << compileResources.MaxImageUnits + << ":MaxVertexImageUniforms:" << compileResources.MaxVertexImageUniforms + << ":MaxFragmentImageUniforms:" << compileResources.MaxFragmentImageUniforms + << ":MaxComputeImageUniforms:" << compileResources.MaxComputeImageUniforms + << ":MaxCombinedImageUniforms:" << compileResources.MaxCombinedImageUniforms + << ":MaxCombinedShaderOutputResources:" << compileResources.MaxCombinedShaderOutputResources + << ":MaxComputeWorkGroupCountX:" << compileResources.MaxComputeWorkGroupCount[0] + << ":MaxComputeWorkGroupCountY:" << compileResources.MaxComputeWorkGroupCount[1] + << ":MaxComputeWorkGroupCountZ:" << compileResources.MaxComputeWorkGroupCount[2] + << ":MaxComputeWorkGroupSizeX:" << compileResources.MaxComputeWorkGroupSize[0] + << ":MaxComputeWorkGroupSizeY:" << compileResources.MaxComputeWorkGroupSize[1] + << ":MaxComputeWorkGroupSizeZ:" << compileResources.MaxComputeWorkGroupSize[2] + << ":MaxComputeUniformComponents:" << compileResources.MaxComputeUniformComponents + << ":MaxComputeTextureImageUnits:" << compileResources.MaxComputeTextureImageUnits + << ":MaxComputeAtomicCounters:" << compileResources.MaxComputeAtomicCounters + << ":MaxComputeAtomicCounterBuffers:" << compileResources.MaxComputeAtomicCounterBuffers + << ":MaxVertexAtomicCounters:" << compileResources.MaxVertexAtomicCounters + << ":MaxFragmentAtomicCounters:" << compileResources.MaxFragmentAtomicCounters + << ":MaxCombinedAtomicCounters:" << compileResources.MaxCombinedAtomicCounters + << ":MaxAtomicCounterBindings:" << compileResources.MaxAtomicCounterBindings + << ":MaxVertexAtomicCounterBuffers:" << compileResources.MaxVertexAtomicCounterBuffers + << ":MaxFragmentAtomicCounterBuffers:" << compileResources.MaxFragmentAtomicCounterBuffers + << ":MaxCombinedAtomicCounterBuffers:" << compileResources.MaxCombinedAtomicCounterBuffers + << ":MaxAtomicCounterBufferSize:" << compileResources.MaxAtomicCounterBufferSize + << ":MaxGeometryUniformComponents:" << compileResources.MaxGeometryUniformComponents + << ":MaxGeometryUniformBlocks:" << compileResources.MaxGeometryUniformBlocks + << ":MaxGeometryInputComponents:" << compileResources.MaxGeometryInputComponents + << ":MaxGeometryOutputComponents:" << compileResources.MaxGeometryOutputComponents + << ":MaxGeometryOutputVertices:" << compileResources.MaxGeometryOutputVertices + << ":MaxGeometryTotalOutputComponents:" << compileResources.MaxGeometryTotalOutputComponents + << ":MaxGeometryTextureImageUnits:" << compileResources.MaxGeometryTextureImageUnits + << ":MaxGeometryAtomicCounterBuffers:" << compileResources.MaxGeometryAtomicCounterBuffers + << ":MaxGeometryAtomicCounters:" << compileResources.MaxGeometryAtomicCounters + << ":MaxGeometryShaderStorageBlocks:" << compileResources.MaxGeometryShaderStorageBlocks + << ":MaxGeometryShaderInvocations:" << compileResources.MaxGeometryShaderInvocations + << ":MaxGeometryImageUniforms:" << compileResources.MaxGeometryImageUniforms; + // clang-format on builtInResourcesString = strstream.str(); } +void TCompiler::collectInterfaceBlocks() +{ + ASSERT(interfaceBlocks.empty()); + interfaceBlocks.reserve(uniformBlocks.size() + shaderStorageBlocks.size() + inBlocks.size()); + interfaceBlocks.insert(interfaceBlocks.end(), uniformBlocks.begin(), uniformBlocks.end()); + interfaceBlocks.insert(interfaceBlocks.end(), shaderStorageBlocks.begin(), + shaderStorageBlocks.end()); + interfaceBlocks.insert(interfaceBlocks.end(), inBlocks.begin(), inBlocks.end()); +} + void TCompiler::clearResults() { arrayBoundsClamper.Cleanup(); infoSink.info.erase(); infoSink.obj.erase(); infoSink.debug.erase(); + mDiagnostics.resetErrorCount(); attributes.clear(); outputVariables.clear(); uniforms.clear(); - expandedUniforms.clear(); - varyings.clear(); + inputVaryings.clear(); + outputVaryings.clear(); interfaceBlocks.clear(); + uniformBlocks.clear(); + shaderStorageBlocks.clear(); + inBlocks.clear(); + variablesCollected = false; + mGLPositionInitialized = false; - builtInFunctionEmulator.Cleanup(); + mNumViews = -1; + + mGeometryShaderInputPrimitiveType = EptUndefined; + mGeometryShaderOutputPrimitiveType = EptUndefined; + mGeometryShaderInvocations = 0; + mGeometryShaderMaxVertices = -1; + + builtInFunctionEmulator.cleanup(); nameMap.clear(); - mSourcePath = NULL; - mTemporaryIndex = 0; + mSourcePath = nullptr; } bool TCompiler::initCallDag(TIntermNode *root) { mCallDag.clear(); - switch (mCallDag.init(root, &infoSink.info)) + switch (mCallDag.init(root, &mDiagnostics)) { - case CallDAG::INITDAG_SUCCESS: - return true; - case CallDAG::INITDAG_RECURSION: - infoSink.info.prefix(EPrefixError); - infoSink.info << "Function recursion detected"; - return false; - case CallDAG::INITDAG_UNDEFINED: - infoSink.info.prefix(EPrefixError); - infoSink.info << "Unimplemented function detected"; - return false; + case CallDAG::INITDAG_SUCCESS: + return true; + case CallDAG::INITDAG_RECURSION: + case CallDAG::INITDAG_UNDEFINED: + // Error message has already been written out. + ASSERT(mDiagnostics.numErrors() > 0); + return false; } UNREACHABLE(); @@ -553,7 +891,7 @@ bool TCompiler::checkCallDepth() for (size_t i = 0; i < mCallDag.size(); i++) { - int depth = 0; + int depth = 0; auto &record = mCallDag.getRecordFromIndex(i); for (auto &calleeIndex : record.callees) @@ -566,19 +904,19 @@ bool TCompiler::checkCallDepth() if (depth >= maxCallStackDepth) { // Trace back the function chain to have a meaningful info log. - infoSink.info.prefix(EPrefixError); - infoSink.info << "Call stack too deep (larger than " << maxCallStackDepth - << ") with the following call chain: " << record.name; + std::stringstream errorStream; + errorStream << "Call stack too deep (larger than " << maxCallStackDepth + << ") with the following call chain: " << record.name; int currentFunction = static_cast(i); - int currentDepth = depth; + int currentDepth = depth; while (currentFunction != -1) { - infoSink.info << " -> " << mCallDag.getRecordFromIndex(currentFunction).name; + errorStream << " -> " << mCallDag.getRecordFromIndex(currentFunction).name; int nextFunction = -1; - for (auto& calleeIndex : mCallDag.getRecordFromIndex(currentFunction).callees) + for (auto &calleeIndex : mCallDag.getRecordFromIndex(currentFunction).callees) { if (depths[calleeIndex] == currentDepth - 1) { @@ -590,6 +928,9 @@ bool TCompiler::checkCallDepth() currentFunction = nextFunction; } + std::string errorStr = errorStream.str(); + mDiagnostics.globalError(errorStr.c_str()); + return false; } } @@ -602,15 +943,14 @@ bool TCompiler::tagUsedFunctions() // Search from main, starting from the end of the DAG as it usually is the root. for (size_t i = mCallDag.size(); i-- > 0;) { - if (mCallDag.getRecordFromIndex(i).name == "main(") + if (mCallDag.getRecordFromIndex(i).name == "main") { internalTagUsedFunction(i); return true; } } - infoSink.info.prefix(EPrefixError); - infoSink.info << "Missing main()\n"; + mDiagnostics.globalError("Missing main()"); return false; } @@ -634,30 +974,35 @@ class TCompiler::UnusedPredicate { public: UnusedPredicate(const CallDAG *callDag, const std::vector *metadatas) - : mCallDag(callDag), - mMetadatas(metadatas) + : mCallDag(callDag), mMetadatas(metadatas) { } - bool operator ()(TIntermNode *node) + bool operator()(TIntermNode *node) { - const TIntermAggregate *asAggregate = node->getAsAggregate(); + const TIntermFunctionPrototype *asFunctionPrototype = node->getAsFunctionPrototypeNode(); + const TIntermFunctionDefinition *asFunctionDefinition = node->getAsFunctionDefinition(); - if (asAggregate == nullptr) + const TFunctionSymbolInfo *functionInfo = nullptr; + + if (asFunctionDefinition) + { + functionInfo = asFunctionDefinition->getFunctionSymbolInfo(); + } + else if (asFunctionPrototype) + { + functionInfo = asFunctionPrototype->getFunctionSymbolInfo(); + } + if (functionInfo == nullptr) { return false; } - if (!(asAggregate->getOp() == EOpFunction || asAggregate->getOp() == EOpPrototype)) - { - return false; - } - - size_t callDagIndex = mCallDag->findIndex(asAggregate); + size_t callDagIndex = mCallDag->findIndex(functionInfo); if (callDagIndex == CallDAG::InvalidIndex) { // This happens only for unimplemented prototypes which are thus unused - ASSERT(asAggregate->getOp() == EOpPrototype); + ASSERT(asFunctionPrototype); return true; } @@ -670,157 +1015,97 @@ class TCompiler::UnusedPredicate const std::vector *mMetadatas; }; -bool TCompiler::pruneUnusedFunctions(TIntermNode *root) +void TCompiler::pruneUnusedFunctions(TIntermBlock *root) { - TIntermAggregate *rootNode = root->getAsAggregate(); - ASSERT(rootNode != nullptr); - UnusedPredicate isUnused(&mCallDag, &functionMetadata); - TIntermSequence *sequence = rootNode->getSequence(); + TIntermSequence *sequence = root->getSequence(); if (!sequence->empty()) { - sequence->erase(std::remove_if(sequence->begin(), sequence->end(), isUnused), sequence->end()); + sequence->erase(std::remove_if(sequence->begin(), sequence->end(), isUnused), + sequence->end()); + } +} + +bool TCompiler::limitExpressionComplexity(TIntermBlock *root) +{ + if (!IsASTDepthBelowLimit(root, maxExpressionComplexity)) + { + mDiagnostics.globalError("Expression too complex."); + return false; + } + + if (!ValidateMaxParameters(root, maxFunctionParameters)) + { + mDiagnostics.globalError("Function has too many parameters."); + return false; } return true; } -bool TCompiler::validateOutputs(TIntermNode* root) +bool TCompiler::shouldCollectVariables(ShCompileOptions compileOptions) { - ValidateOutputs validateOutputs(getExtensionBehavior(), compileResources.MaxDrawBuffers); - root->traverse(&validateOutputs); - return (validateOutputs.validateAndCountErrors(infoSink.info) == 0); + return (compileOptions & SH_VARIABLES) != 0; } -void TCompiler::rewriteCSSShader(TIntermNode* root) +bool TCompiler::wereVariablesCollected() const { - RenameFunction renamer("main(", "css_main("); - root->traverse(&renamer); + return variablesCollected; } -bool TCompiler::validateLimitations(TIntermNode* root) +void TCompiler::initializeGLPosition(TIntermBlock *root) { - ValidateLimitations validate(shaderType, &infoSink.info); - root->traverse(&validate); - return validate.numErrors() == 0; + InitVariableList list; + sh::ShaderVariable var(GL_FLOAT_VEC4); + var.name = "gl_Position"; + list.push_back(var); + InitializeVariables(root, list, &symbolTable, shaderVersion, extensionBehavior, false); } -bool TCompiler::enforceTimingRestrictions(TIntermNode* root, bool outputGraph) +void TCompiler::useAllMembersInUnusedStandardAndSharedBlocks(TIntermBlock *root) { - if (shaderSpec != SH_WEBGL_SPEC) + sh::InterfaceBlockList list; + + for (auto block : uniformBlocks) { - infoSink.info << "Timing restrictions must be enforced under the WebGL spec."; - return false; + if (!block.staticUse && + (block.layout == sh::BLOCKLAYOUT_STD140 || block.layout == sh::BLOCKLAYOUT_SHARED)) + { + list.push_back(block); + } } - if (shaderType == GL_FRAGMENT_SHADER) + sh::UseInterfaceBlockFields(root, list, symbolTable); +} + +void TCompiler::initializeOutputVariables(TIntermBlock *root) +{ + InitVariableList list; + if (shaderType == GL_VERTEX_SHADER || shaderType == GL_GEOMETRY_SHADER_OES) { - TDependencyGraph graph(root); - - // Output any errors first. - bool success = enforceFragmentShaderTimingRestrictions(graph); - - // Then, output the dependency graph. - if (outputGraph) + for (auto var : outputVaryings) { - TDependencyGraphOutput output(infoSink.info); - output.outputAllSpanningTrees(graph); + list.push_back(var); + if (var.name == "gl_Position") + { + ASSERT(!mGLPositionInitialized); + mGLPositionInitialized = true; + } } - - return success; } else { - return enforceVertexShaderTimingRestrictions(root); - } -} - -bool TCompiler::limitExpressionComplexity(TIntermNode* root) -{ - TMaxDepthTraverser traverser(maxExpressionComplexity+1); - root->traverse(&traverser); - - if (traverser.getMaxDepth() > maxExpressionComplexity) - { - infoSink.info << "Expression too complex."; - return false; - } - - return true; -} - -bool TCompiler::enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph) -{ - RestrictFragmentShaderTiming restrictor(infoSink.info); - restrictor.enforceRestrictions(graph); - return restrictor.numErrors() == 0; -} - -bool TCompiler::enforceVertexShaderTimingRestrictions(TIntermNode* root) -{ - RestrictVertexShaderTiming restrictor(infoSink.info); - restrictor.enforceRestrictions(root); - return restrictor.numErrors() == 0; -} - -void TCompiler::collectVariables(TIntermNode* root) -{ - sh::CollectVariables collect(&attributes, - &outputVariables, - &uniforms, - &varyings, - &interfaceBlocks, - hashFunction, - symbolTable); - root->traverse(&collect); - - // This is for enforcePackingRestriction(). - sh::ExpandUniforms(uniforms, &expandedUniforms); -} - -bool TCompiler::enforcePackingRestrictions() -{ - VariablePacker packer; - return packer.CheckVariablesWithinPackingLimits(maxUniformVectors, expandedUniforms); -} - -void TCompiler::initializeGLPosition(TIntermNode* root) -{ - InitializeVariables::InitVariableInfoList variables; - InitializeVariables::InitVariableInfo var( - "gl_Position", TType(EbtFloat, EbpUndefined, EvqPosition, 4)); - variables.push_back(var); - InitializeVariables initializer(variables); - root->traverse(&initializer); -} - -void TCompiler::initializeVaryingsWithoutStaticUse(TIntermNode* root) -{ - InitializeVariables::InitVariableInfoList variables; - for (size_t ii = 0; ii < varyings.size(); ++ii) - { - const sh::Varying& varying = varyings[ii]; - if (varying.staticUse) - continue; - unsigned char primarySize = static_cast(gl::VariableColumnCount(varying.type)); - unsigned char secondarySize = static_cast(gl::VariableRowCount(varying.type)); - TType type(EbtFloat, EbpUndefined, EvqVaryingOut, primarySize, secondarySize, varying.isArray()); - TString name = varying.name.c_str(); - if (varying.isArray()) + ASSERT(shaderType == GL_FRAGMENT_SHADER); + for (auto var : outputVariables) { - type.setArraySize(varying.arraySize); - name = name.substr(0, name.find_first_of('[')); + list.push_back(var); } - - InitializeVariables::InitVariableInfo var(name, type); - variables.push_back(var); } - InitializeVariables initializer(variables); - root->traverse(&initializer); + InitializeVariables(root, list, &symbolTable, shaderVersion, extensionBehavior, false); } -const TExtensionBehavior& TCompiler::getExtensionBehavior() const +const TExtensionBehavior &TCompiler::getExtensionBehavior() const { return extensionBehavior; } @@ -830,12 +1115,12 @@ const char *TCompiler::getSourcePath() const return mSourcePath; } -const ShBuiltInResources& TCompiler::getResources() const +const ShBuiltInResources &TCompiler::getResources() const { return compileResources; } -const ArrayBoundsClamper& TCompiler::getArrayBoundsClamper() const +const ArrayBoundsClamper &TCompiler::getArrayBoundsClamper() const { return arrayBoundsClamper; } @@ -845,14 +1130,40 @@ ShArrayIndexClampingStrategy TCompiler::getArrayIndexClampingStrategy() const return clampingStrategy; } -const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const +const BuiltInFunctionEmulator &TCompiler::getBuiltInFunctionEmulator() const { return builtInFunctionEmulator; } -void TCompiler::writePragma() +void TCompiler::writePragma(ShCompileOptions compileOptions) { - TInfoSinkBase &sink = infoSink.obj; - if (mPragma.stdgl.invariantAll) - sink << "#pragma STDGL invariant(all)\n"; + if (!(compileOptions & SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL)) + { + TInfoSinkBase &sink = infoSink.obj; + if (mPragma.stdgl.invariantAll) + sink << "#pragma STDGL invariant(all)\n"; + } } + +bool TCompiler::isVaryingDefined(const char *varyingName) +{ + ASSERT(variablesCollected); + for (size_t ii = 0; ii < inputVaryings.size(); ++ii) + { + if (inputVaryings[ii].name == varyingName) + { + return true; + } + } + for (size_t ii = 0; ii < outputVaryings.size(); ++ii) + { + if (outputVaryings[ii].name == varyingName) + { + return true; + } + } + + return false; +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/Compiler.h b/src/3rdparty/angle/src/compiler/translator/Compiler.h index c00a8f97aa..753cfb8e7b 100644 --- a/src/3rdparty/angle/src/compiler/translator/Compiler.h +++ b/src/3rdparty/angle/src/compiler/translator/Compiler.h @@ -14,25 +14,29 @@ // This should not be included by driver code. // +#include + #include "compiler/translator/BuiltInFunctionEmulator.h" #include "compiler/translator/CallDAG.h" +#include "compiler/translator/Diagnostics.h" #include "compiler/translator/ExtensionBehavior.h" #include "compiler/translator/HashNames.h" #include "compiler/translator/InfoSink.h" #include "compiler/translator/Pragma.h" #include "compiler/translator/SymbolTable.h" -#include "compiler/translator/VariableInfo.h" #include "third_party/compiler/ArrayBoundsClamper.h" +namespace sh +{ + class TCompiler; -class TDependencyGraph; +class TParseContext; #ifdef ANGLE_ENABLE_HLSL class TranslatorHLSL; -#endif // ANGLE_ENABLE_HLSL +#endif // ANGLE_ENABLE_HLSL // -// Helper function to identify specs that are based on the WebGL spec, -// like the CSS Shaders spec. +// Helper function to identify specs that are based on the WebGL spec. // bool IsWebGLBasedSpec(ShShaderSpec spec); @@ -40,20 +44,31 @@ bool IsWebGLBasedSpec(ShShaderSpec spec); // Helper function to check if the shader type is GLSL. // bool IsGLSL130OrNewer(ShShaderOutput output); +bool IsGLSL420OrNewer(ShShaderOutput output); +bool IsGLSL410OrOlder(ShShaderOutput output); + +// +// Helper function to check if the invariant qualifier can be removed. +// +bool RemoveInvariant(sh::GLenum shaderType, + int shaderVersion, + ShShaderOutput outputType, + ShCompileOptions compileOptions); // // The base class used to back handles returned to the driver. // -class TShHandleBase { -public: +class TShHandleBase +{ + public: TShHandleBase(); virtual ~TShHandleBase(); - virtual TCompiler* getAsCompiler() { return 0; } + virtual TCompiler *getAsCompiler() { return 0; } #ifdef ANGLE_ENABLE_HLSL - virtual TranslatorHLSL* getAsTranslatorHLSL() { return 0; } -#endif // ANGLE_ENABLE_HLSL + virtual TranslatorHLSL *getAsTranslatorHLSL() { return 0; } +#endif // ANGLE_ENABLE_HLSL -protected: + protected: // Memory allocator. Allocates and tracks memory required by the compiler. // Deallocates all memory when compiler is destructed. TPoolAllocator allocator; @@ -70,20 +85,26 @@ class TCompiler : public TShHandleBase ~TCompiler() override; TCompiler *getAsCompiler() override { return this; } - bool Init(const ShBuiltInResources& resources); + bool Init(const ShBuiltInResources &resources); // compileTreeForTesting should be used only when tests require access to // the AST. Users of this function need to manually manage the global pool - // allocator. Returns NULL whenever there are compilation errors. - TIntermNode *compileTreeForTesting(const char* const shaderStrings[], - size_t numStrings, int compileOptions); + // allocator. Returns nullptr whenever there are compilation errors. + TIntermBlock *compileTreeForTesting(const char *const shaderStrings[], + size_t numStrings, + ShCompileOptions compileOptions); - bool compile(const char* const shaderStrings[], - size_t numStrings, int compileOptions); + bool compile(const char *const shaderStrings[], + size_t numStrings, + ShCompileOptions compileOptions); // Get results of the last compilation. int getShaderVersion() const { return shaderVersion; } - TInfoSink& getInfoSink() { return infoSink; } + TInfoSink &getInfoSink() { return infoSink; } + + bool isComputeShaderLocalSizeDeclared() const { return mComputeShaderLocalSizeDeclared; } + const sh::WorkGroupSize &getComputeShaderLocalSize() const { return mComputeShaderLocalSize; } + int getNumViews() const { return mNumViews; } // Clears the results from the previous compilation. void clearResults(); @@ -91,86 +112,94 @@ class TCompiler : public TShHandleBase const std::vector &getAttributes() const { return attributes; } const std::vector &getOutputVariables() const { return outputVariables; } const std::vector &getUniforms() const { return uniforms; } - const std::vector &getVaryings() const { return varyings; } + const std::vector &getInputVaryings() const { return inputVaryings; } + const std::vector &getOutputVaryings() const { return outputVaryings; } const std::vector &getInterfaceBlocks() const { return interfaceBlocks; } + const std::vector &getUniformBlocks() const { return uniformBlocks; } + const std::vector &getShaderStorageBlocks() const + { + return shaderStorageBlocks; + } + const std::vector &getInBlocks() const { return inBlocks; } ShHashFunction64 getHashFunction() const { return hashFunction; } - NameMap& getNameMap() { return nameMap; } - TSymbolTable& getSymbolTable() { return symbolTable; } + NameMap &getNameMap() { return nameMap; } + TSymbolTable &getSymbolTable() { return symbolTable; } ShShaderSpec getShaderSpec() const { return shaderSpec; } ShShaderOutput getOutputType() const { return outputType; } const std::string &getBuiltInResourcesString() const { return builtInResourcesString; } - bool shouldRunLoopAndIndexingValidation(int compileOptions) const; + bool shouldRunLoopAndIndexingValidation(ShCompileOptions compileOptions) const; // Get the resources set by InitBuiltInSymbolTable - const ShBuiltInResources& getResources() const; + const ShBuiltInResources &getResources() const; + + int getGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; } + int getGeometryShaderInvocations() const { return mGeometryShaderInvocations; } + TLayoutPrimitiveType getGeometryShaderInputPrimitiveType() const + { + return mGeometryShaderInputPrimitiveType; + } + TLayoutPrimitiveType getGeometryShaderOutputPrimitiveType() const + { + return mGeometryShaderOutputPrimitiveType; + } + + sh::GLenum getShaderType() const { return shaderType; } protected: - sh::GLenum getShaderType() const { return shaderType; } // Initialize symbol-table with built-in symbols. - bool InitBuiltInSymbolTable(const ShBuiltInResources& resources); + bool InitBuiltInSymbolTable(const ShBuiltInResources &resources); // Compute the string representation of the built-in resources void setResourceString(); // Return false if the call depth is exceeded. bool checkCallDepth(); - // Returns true if a program has no conflicting or missing fragment outputs - bool validateOutputs(TIntermNode* root); - // Rewrites a shader's intermediate tree according to the CSS Shaders spec. - void rewriteCSSShader(TIntermNode* root); - // Returns true if the given shader does not exceed the minimum - // functionality mandated in GLSL 1.0 spec Appendix A. - bool validateLimitations(TIntermNode* root); - // Collect info for all attribs, uniforms, varyings. - void collectVariables(TIntermNode* root); // Add emulated functions to the built-in function emulator. - virtual void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions) {}; - // Translate to object code. - virtual void translate(TIntermNode *root, int compileOptions) = 0; - // Returns true if, after applying the packing rules in the GLSL 1.017 spec - // Appendix A, section 7, the shader does not use too many uniforms. - bool enforcePackingRestrictions(); - // Insert statements to initialize varyings without static use in the beginning - // of main(). It is to work around a Mac driver where such varyings in a vertex - // shader may be optimized out incorrectly at compile time, causing a link failure. - // This function should only be applied to vertex shaders. - void initializeVaryingsWithoutStaticUse(TIntermNode* root); + virtual void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, + ShCompileOptions compileOptions){}; + // Translate to object code. May generate performance warnings through the diagnostics. + virtual void translate(TIntermBlock *root, + ShCompileOptions compileOptions, + PerformanceDiagnostics *perfDiagnostics) = 0; + // Insert statements to reference all members in unused uniform blocks with standard and shared + // layout. This is to work around a Mac driver that treats unused standard/shared + // uniform blocks as inactive. + void useAllMembersInUnusedStandardAndSharedBlocks(TIntermBlock *root); + // Insert statements to initialize output variables in the beginning of main(). + // This is to avoid undefined behaviors. + void initializeOutputVariables(TIntermBlock *root); // Insert gl_Position = vec4(0,0,0,0) to the beginning of main(). // It is to work around a Linux driver bug where missing this causes compile failure // while spec says it is allowed. // This function should only be applied to vertex shaders. - void initializeGLPosition(TIntermNode* root); - // Returns true if the shader passes the restrictions that aim to prevent timing attacks. - bool enforceTimingRestrictions(TIntermNode* root, bool outputGraph); - // Returns true if the shader does not use samplers. - bool enforceVertexShaderTimingRestrictions(TIntermNode* root); - // Returns true if the shader does not use sampler dependent values to affect control - // flow or in operations whose time can depend on the input values. - bool enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph); + void initializeGLPosition(TIntermBlock *root); // Return true if the maximum expression complexity is below the limit. - bool limitExpressionComplexity(TIntermNode* root); + bool limitExpressionComplexity(TIntermBlock *root); // Get built-in extensions with default behavior. - const TExtensionBehavior& getExtensionBehavior() const; + const TExtensionBehavior &getExtensionBehavior() const; const char *getSourcePath() const; - const TPragma& getPragma() const { return mPragma; } - void writePragma(); - unsigned int *getTemporaryIndex() { return &mTemporaryIndex; } + const TPragma &getPragma() const { return mPragma; } + void writePragma(ShCompileOptions compileOptions); + // Relies on collectVariables having been called. + bool isVaryingDefined(const char *varyingName); - const ArrayBoundsClamper& getArrayBoundsClamper() const; + const ArrayBoundsClamper &getArrayBoundsClamper() const; ShArrayIndexClampingStrategy getArrayIndexClampingStrategy() const; - const BuiltInFunctionEmulator& getBuiltInFunctionEmulator() const; + const BuiltInFunctionEmulator &getBuiltInFunctionEmulator() const; + virtual bool shouldFlattenPragmaStdglInvariantAll() = 0; + virtual bool shouldCollectVariables(ShCompileOptions compileOptions); + + bool wereVariablesCollected() const; std::vector attributes; std::vector outputVariables; std::vector uniforms; - std::vector expandedUniforms; - std::vector varyings; + std::vector inputVaryings; + std::vector outputVaryings; std::vector interfaceBlocks; - - virtual bool shouldCollectVariables(int compileOptions) - { - return (compileOptions & SH_VARIABLES) != 0; - } + std::vector uniformBlocks; + std::vector shaderStorageBlocks; + std::vector inBlocks; private: // Creates the function call DAG for further analysis, returning false if there is a recursion @@ -181,13 +210,28 @@ class TCompiler : public TShHandleBase void initSamplerDefaultPrecision(TBasicType samplerType); + void collectInterfaceBlocks(); + + bool variablesCollected; + + bool mGLPositionInitialized; + // Removes unused function declarations and prototypes from the AST class UnusedPredicate; - bool pruneUnusedFunctions(TIntermNode *root); + void pruneUnusedFunctions(TIntermBlock *root); - TIntermNode *compileTreeImpl(const char *const shaderStrings[], - size_t numStrings, - const int compileOptions); + TIntermBlock *compileTreeImpl(const char *const shaderStrings[], + size_t numStrings, + const ShCompileOptions compileOptions); + + // Fetches and stores shader metadata that is not stored within the AST itself, such as shader + // version. + void setASTMetadata(const TParseContext &parseContext); + + // Does checks that need to be run after parsing is complete and returns true if they pass. + bool checkAndSimplifyAST(TIntermBlock *root, + const TParseContext &parseContext, + ShCompileOptions compileOptions); sh::GLenum shaderType; ShShaderSpec shaderSpec; @@ -195,10 +239,7 @@ class TCompiler : public TShHandleBase struct FunctionMetadata { - FunctionMetadata() - : used(false) - { - } + FunctionMetadata() : used(false) {} bool used; }; @@ -208,6 +249,7 @@ class TCompiler : public TShHandleBase int maxUniformVectors; int maxExpressionComplexity; int maxCallStackDepth; + int maxFunctionParameters; ShBuiltInResources compileResources; std::string builtInResourcesString; @@ -225,16 +267,28 @@ class TCompiler : public TShHandleBase // Results of compilation. int shaderVersion; - TInfoSink infoSink; // Output sink. - const char *mSourcePath; // Path of source file or NULL + TInfoSink infoSink; // Output sink. + TDiagnostics mDiagnostics; + const char *mSourcePath; // Path of source file or NULL + + // compute shader local group size + bool mComputeShaderLocalSizeDeclared; + sh::WorkGroupSize mComputeShaderLocalSize; + + // GL_OVR_multiview num_views. + int mNumViews; + + // geometry shader parameters. + int mGeometryShaderMaxVertices; + int mGeometryShaderInvocations; + TLayoutPrimitiveType mGeometryShaderInputPrimitiveType; + TLayoutPrimitiveType mGeometryShaderOutputPrimitiveType; // name hashing. ShHashFunction64 hashFunction; NameMap nameMap; TPragma mPragma; - - unsigned int mTemporaryIndex; }; // @@ -246,8 +300,9 @@ class TCompiler : public TShHandleBase // destroy the machine dependent objects, which contain the // above machine independent information. // -TCompiler* ConstructCompiler( - sh::GLenum type, ShShaderSpec spec, ShShaderOutput output); -void DeleteCompiler(TCompiler*); +TCompiler *ConstructCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output); +void DeleteCompiler(TCompiler *); -#endif // COMPILER_TRANSLATOR_COMPILER_H_ +} // namespace sh + +#endif // COMPILER_TRANSLATOR_COMPILER_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/ConstantUnion.cpp b/src/3rdparty/angle/src/compiler/translator/ConstantUnion.cpp new file mode 100644 index 0000000000..7004aedee3 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/ConstantUnion.cpp @@ -0,0 +1,681 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ConstantUnion: Constant folding helper class. + +#include "compiler/translator/ConstantUnion.h" + +#include "common/mathutil.h" +#include "compiler/translator/Diagnostics.h" + +namespace sh +{ + +namespace +{ + +float CheckedSum(float lhs, float rhs, TDiagnostics *diag, const TSourceLoc &line) +{ + float result = lhs + rhs; + if (gl::isNaN(result) && !gl::isNaN(lhs) && !gl::isNaN(rhs)) + { + diag->warning(line, "Constant folded undefined addition generated NaN", "+"); + } + else if (gl::isInf(result) && !gl::isInf(lhs) && !gl::isInf(rhs)) + { + diag->warning(line, "Constant folded addition overflowed to infinity", "+"); + } + return result; +} + +float CheckedDiff(float lhs, float rhs, TDiagnostics *diag, const TSourceLoc &line) +{ + float result = lhs - rhs; + if (gl::isNaN(result) && !gl::isNaN(lhs) && !gl::isNaN(rhs)) + { + diag->warning(line, "Constant folded undefined subtraction generated NaN", "-"); + } + else if (gl::isInf(result) && !gl::isInf(lhs) && !gl::isInf(rhs)) + { + diag->warning(line, "Constant folded subtraction overflowed to infinity", "-"); + } + return result; +} + +float CheckedMul(float lhs, float rhs, TDiagnostics *diag, const TSourceLoc &line) +{ + float result = lhs * rhs; + if (gl::isNaN(result) && !gl::isNaN(lhs) && !gl::isNaN(rhs)) + { + diag->warning(line, "Constant folded undefined multiplication generated NaN", "*"); + } + else if (gl::isInf(result) && !gl::isInf(lhs) && !gl::isInf(rhs)) + { + diag->warning(line, "Constant folded multiplication overflowed to infinity", "*"); + } + return result; +} + +bool IsValidShiftOffset(const TConstantUnion &rhs) +{ + return (rhs.getType() == EbtInt && (rhs.getIConst() >= 0 && rhs.getIConst() <= 31)) || + (rhs.getType() == EbtUInt && rhs.getUConst() <= 31u); +} + +} // anonymous namespace + +TConstantUnion::TConstantUnion() +{ + iConst = 0; + type = EbtVoid; +} + +int TConstantUnion::getIConst() const +{ + ASSERT(type == EbtInt); + return iConst; +} + +unsigned int TConstantUnion::getUConst() const +{ + ASSERT(type == EbtUInt); + return uConst; +} + +float TConstantUnion::getFConst() const +{ + ASSERT(type == EbtFloat); + return fConst; +} + +bool TConstantUnion::getBConst() const +{ + ASSERT(type == EbtBool); + return bConst; +} + +TYuvCscStandardEXT TConstantUnion::getYuvCscStandardEXTConst() const +{ + ASSERT(type == EbtYuvCscStandardEXT); + return yuvCscStandardEXTConst; +} + +bool TConstantUnion::cast(TBasicType newType, const TConstantUnion &constant) +{ + switch (newType) + { + case EbtFloat: + switch (constant.type) + { + case EbtInt: + setFConst(static_cast(constant.getIConst())); + break; + case EbtUInt: + setFConst(static_cast(constant.getUConst())); + break; + case EbtBool: + setFConst(static_cast(constant.getBConst())); + break; + case EbtFloat: + setFConst(static_cast(constant.getFConst())); + break; + default: + return false; + } + break; + case EbtInt: + switch (constant.type) + { + case EbtInt: + setIConst(static_cast(constant.getIConst())); + break; + case EbtUInt: + setIConst(static_cast(constant.getUConst())); + break; + case EbtBool: + setIConst(static_cast(constant.getBConst())); + break; + case EbtFloat: + setIConst(static_cast(constant.getFConst())); + break; + default: + return false; + } + break; + case EbtUInt: + switch (constant.type) + { + case EbtInt: + setUConst(static_cast(constant.getIConst())); + break; + case EbtUInt: + setUConst(static_cast(constant.getUConst())); + break; + case EbtBool: + setUConst(static_cast(constant.getBConst())); + break; + case EbtFloat: + setUConst(static_cast(constant.getFConst())); + break; + default: + return false; + } + break; + case EbtBool: + switch (constant.type) + { + case EbtInt: + setBConst(constant.getIConst() != 0); + break; + case EbtUInt: + setBConst(constant.getUConst() != 0); + break; + case EbtBool: + setBConst(constant.getBConst()); + break; + case EbtFloat: + setBConst(constant.getFConst() != 0.0f); + break; + default: + return false; + } + break; + case EbtStruct: // Struct fields don't get cast + switch (constant.type) + { + case EbtInt: + setIConst(constant.getIConst()); + break; + case EbtUInt: + setUConst(constant.getUConst()); + break; + case EbtBool: + setBConst(constant.getBConst()); + break; + case EbtFloat: + setFConst(constant.getFConst()); + break; + default: + return false; + } + break; + default: + return false; + } + + return true; +} + +bool TConstantUnion::operator==(const int i) const +{ + return i == iConst; +} + +bool TConstantUnion::operator==(const unsigned int u) const +{ + return u == uConst; +} + +bool TConstantUnion::operator==(const float f) const +{ + return f == fConst; +} + +bool TConstantUnion::operator==(const bool b) const +{ + return b == bConst; +} + +bool TConstantUnion::operator==(const TYuvCscStandardEXT s) const +{ + return s == yuvCscStandardEXTConst; +} + +bool TConstantUnion::operator==(const TConstantUnion &constant) const +{ + if (constant.type != type) + return false; + + switch (type) + { + case EbtInt: + return constant.iConst == iConst; + case EbtUInt: + return constant.uConst == uConst; + case EbtFloat: + return constant.fConst == fConst; + case EbtBool: + return constant.bConst == bConst; + case EbtYuvCscStandardEXT: + return constant.yuvCscStandardEXTConst == yuvCscStandardEXTConst; + default: + return false; + } +} + +bool TConstantUnion::operator!=(const int i) const +{ + return !operator==(i); +} + +bool TConstantUnion::operator!=(const unsigned int u) const +{ + return !operator==(u); +} + +bool TConstantUnion::operator!=(const float f) const +{ + return !operator==(f); +} + +bool TConstantUnion::operator!=(const bool b) const +{ + return !operator==(b); +} + +bool TConstantUnion::operator!=(const TYuvCscStandardEXT s) const +{ + return !operator==(s); +} + +bool TConstantUnion::operator!=(const TConstantUnion &constant) const +{ + return !operator==(constant); +} + +bool TConstantUnion::operator>(const TConstantUnion &constant) const +{ + ASSERT(type == constant.type); + switch (type) + { + case EbtInt: + return iConst > constant.iConst; + case EbtUInt: + return uConst > constant.uConst; + case EbtFloat: + return fConst > constant.fConst; + default: + return false; // Invalid operation, handled at semantic analysis + } +} + +bool TConstantUnion::operator<(const TConstantUnion &constant) const +{ + ASSERT(type == constant.type); + switch (type) + { + case EbtInt: + return iConst < constant.iConst; + case EbtUInt: + return uConst < constant.uConst; + case EbtFloat: + return fConst < constant.fConst; + default: + return false; // Invalid operation, handled at semantic analysis + } +} + +// static +TConstantUnion TConstantUnion::add(const TConstantUnion &lhs, + const TConstantUnion &rhs, + TDiagnostics *diag, + const TSourceLoc &line) +{ + TConstantUnion returnValue; + ASSERT(lhs.type == rhs.type); + switch (lhs.type) + { + case EbtInt: + returnValue.setIConst(gl::WrappingSum(lhs.iConst, rhs.iConst)); + break; + case EbtUInt: + returnValue.setUConst(gl::WrappingSum(lhs.uConst, rhs.uConst)); + break; + case EbtFloat: + returnValue.setFConst(CheckedSum(lhs.fConst, rhs.fConst, diag, line)); + break; + default: + UNREACHABLE(); + } + + return returnValue; +} + +// static +TConstantUnion TConstantUnion::sub(const TConstantUnion &lhs, + const TConstantUnion &rhs, + TDiagnostics *diag, + const TSourceLoc &line) +{ + TConstantUnion returnValue; + ASSERT(lhs.type == rhs.type); + switch (lhs.type) + { + case EbtInt: + returnValue.setIConst(gl::WrappingDiff(lhs.iConst, rhs.iConst)); + break; + case EbtUInt: + returnValue.setUConst(gl::WrappingDiff(lhs.uConst, rhs.uConst)); + break; + case EbtFloat: + returnValue.setFConst(CheckedDiff(lhs.fConst, rhs.fConst, diag, line)); + break; + default: + UNREACHABLE(); + } + + return returnValue; +} + +// static +TConstantUnion TConstantUnion::mul(const TConstantUnion &lhs, + const TConstantUnion &rhs, + TDiagnostics *diag, + const TSourceLoc &line) +{ + TConstantUnion returnValue; + ASSERT(lhs.type == rhs.type); + switch (lhs.type) + { + case EbtInt: + returnValue.setIConst(gl::WrappingMul(lhs.iConst, rhs.iConst)); + break; + case EbtUInt: + // Unsigned integer math in C++ is defined to be done in modulo 2^n, so we rely on that + // to implement wrapping multiplication. + returnValue.setUConst(lhs.uConst * rhs.uConst); + break; + case EbtFloat: + returnValue.setFConst(CheckedMul(lhs.fConst, rhs.fConst, diag, line)); + break; + default: + UNREACHABLE(); + } + + return returnValue; +} + +TConstantUnion TConstantUnion::operator%(const TConstantUnion &constant) const +{ + TConstantUnion returnValue; + ASSERT(type == constant.type); + switch (type) + { + case EbtInt: + returnValue.setIConst(iConst % constant.iConst); + break; + case EbtUInt: + returnValue.setUConst(uConst % constant.uConst); + break; + default: + UNREACHABLE(); + } + + return returnValue; +} + +// static +TConstantUnion TConstantUnion::rshift(const TConstantUnion &lhs, + const TConstantUnion &rhs, + TDiagnostics *diag, + const TSourceLoc &line) +{ + TConstantUnion returnValue; + ASSERT(lhs.type == EbtInt || lhs.type == EbtUInt); + ASSERT(rhs.type == EbtInt || rhs.type == EbtUInt); + if (!IsValidShiftOffset(rhs)) + { + diag->warning(line, "Undefined shift (operand out of range)", ">>"); + switch (lhs.type) + { + case EbtInt: + returnValue.setIConst(0); + break; + case EbtUInt: + returnValue.setUConst(0u); + break; + default: + UNREACHABLE(); + } + return returnValue; + } + + switch (lhs.type) + { + case EbtInt: + { + unsigned int shiftOffset = 0; + switch (rhs.type) + { + case EbtInt: + shiftOffset = static_cast(rhs.iConst); + break; + case EbtUInt: + shiftOffset = rhs.uConst; + break; + default: + UNREACHABLE(); + } + if (shiftOffset > 0) + { + // ESSL 3.00.6 section 5.9: "If E1 is a signed integer, the right-shift will extend + // the sign bit." In C++ shifting negative integers is undefined, so we implement + // extending the sign bit manually. + int lhsSafe = lhs.iConst; + if (lhsSafe == std::numeric_limits::min()) + { + // The min integer needs special treatment because only bit it has set is the + // sign bit, which we clear later to implement safe right shift of negative + // numbers. + lhsSafe = -0x40000000; + --shiftOffset; + } + if (shiftOffset > 0) + { + bool extendSignBit = false; + if (lhsSafe < 0) + { + extendSignBit = true; + // Clear the sign bit so that bitshift right is defined in C++. + lhsSafe &= 0x7fffffff; + ASSERT(lhsSafe > 0); + } + returnValue.setIConst(lhsSafe >> shiftOffset); + + // Manually fill in the extended sign bit if necessary. + if (extendSignBit) + { + int extendedSignBit = static_cast(0xffffffffu << (31 - shiftOffset)); + returnValue.setIConst(returnValue.getIConst() | extendedSignBit); + } + } + else + { + returnValue.setIConst(lhsSafe); + } + } + else + { + returnValue.setIConst(lhs.iConst); + } + break; + } + case EbtUInt: + switch (rhs.type) + { + case EbtInt: + returnValue.setUConst(lhs.uConst >> rhs.iConst); + break; + case EbtUInt: + returnValue.setUConst(lhs.uConst >> rhs.uConst); + break; + default: + UNREACHABLE(); + } + break; + + default: + UNREACHABLE(); + } + return returnValue; +} + +// static +TConstantUnion TConstantUnion::lshift(const TConstantUnion &lhs, + const TConstantUnion &rhs, + TDiagnostics *diag, + const TSourceLoc &line) +{ + TConstantUnion returnValue; + ASSERT(lhs.type == EbtInt || lhs.type == EbtUInt); + ASSERT(rhs.type == EbtInt || rhs.type == EbtUInt); + if (!IsValidShiftOffset(rhs)) + { + diag->warning(line, "Undefined shift (operand out of range)", "<<"); + switch (lhs.type) + { + case EbtInt: + returnValue.setIConst(0); + break; + case EbtUInt: + returnValue.setUConst(0u); + break; + default: + UNREACHABLE(); + } + return returnValue; + } + + switch (lhs.type) + { + case EbtInt: + switch (rhs.type) + { + // Cast to unsigned integer before shifting, since ESSL 3.00.6 section 5.9 says that + // lhs is "interpreted as a bit pattern". This also avoids the possibility of signed + // integer overflow or undefined shift of a negative integer. + case EbtInt: + returnValue.setIConst( + static_cast(static_cast(lhs.iConst) << rhs.iConst)); + break; + case EbtUInt: + returnValue.setIConst( + static_cast(static_cast(lhs.iConst) << rhs.uConst)); + break; + default: + UNREACHABLE(); + } + break; + + case EbtUInt: + switch (rhs.type) + { + case EbtInt: + returnValue.setUConst(lhs.uConst << rhs.iConst); + break; + case EbtUInt: + returnValue.setUConst(lhs.uConst << rhs.uConst); + break; + default: + UNREACHABLE(); + } + break; + + default: + UNREACHABLE(); + } + return returnValue; +} + +TConstantUnion TConstantUnion::operator&(const TConstantUnion &constant) const +{ + TConstantUnion returnValue; + ASSERT(constant.type == EbtInt || constant.type == EbtUInt); + switch (type) + { + case EbtInt: + returnValue.setIConst(iConst & constant.iConst); + break; + case EbtUInt: + returnValue.setUConst(uConst & constant.uConst); + break; + default: + UNREACHABLE(); + } + + return returnValue; +} + +TConstantUnion TConstantUnion::operator|(const TConstantUnion &constant) const +{ + TConstantUnion returnValue; + ASSERT(type == constant.type); + switch (type) + { + case EbtInt: + returnValue.setIConst(iConst | constant.iConst); + break; + case EbtUInt: + returnValue.setUConst(uConst | constant.uConst); + break; + default: + UNREACHABLE(); + } + + return returnValue; +} + +TConstantUnion TConstantUnion::operator^(const TConstantUnion &constant) const +{ + TConstantUnion returnValue; + ASSERT(type == constant.type); + switch (type) + { + case EbtInt: + returnValue.setIConst(iConst ^ constant.iConst); + break; + case EbtUInt: + returnValue.setUConst(uConst ^ constant.uConst); + break; + default: + UNREACHABLE(); + } + + return returnValue; +} + +TConstantUnion TConstantUnion::operator&&(const TConstantUnion &constant) const +{ + TConstantUnion returnValue; + ASSERT(type == constant.type); + switch (type) + { + case EbtBool: + returnValue.setBConst(bConst && constant.bConst); + break; + default: + UNREACHABLE(); + } + + return returnValue; +} + +TConstantUnion TConstantUnion::operator||(const TConstantUnion &constant) const +{ + TConstantUnion returnValue; + ASSERT(type == constant.type); + switch (type) + { + case EbtBool: + returnValue.setBConst(bConst || constant.bConst); + break; + default: + UNREACHABLE(); + } + + return returnValue; +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/ConstantUnion.h b/src/3rdparty/angle/src/compiler/translator/ConstantUnion.h index a86d27f3ff..c1b3db9070 100644 --- a/src/3rdparty/angle/src/compiler/translator/ConstantUnion.h +++ b/src/3rdparty/angle/src/compiler/translator/ConstantUnion.h @@ -9,340 +9,109 @@ #include +#include "compiler/translator/Common.h" #include "compiler/translator/BaseTypes.h" -class TConstantUnion { -public: +namespace sh +{ + +class TDiagnostics; + +class TConstantUnion +{ + public: POOL_ALLOCATOR_NEW_DELETE(); - TConstantUnion() + TConstantUnion(); + + bool cast(TBasicType newType, const TConstantUnion &constant); + + void setIConst(int i) { - iConst = 0; - type = EbtVoid; + iConst = i; + type = EbtInt; } - - bool cast(TBasicType newType, const TConstantUnion &constant) + void setUConst(unsigned int u) { - switch (newType) - { - case EbtFloat: - switch (constant.type) - { - case EbtInt: setFConst(static_cast(constant.getIConst())); break; - case EbtUInt: setFConst(static_cast(constant.getUConst())); break; - case EbtBool: setFConst(static_cast(constant.getBConst())); break; - case EbtFloat: setFConst(static_cast(constant.getFConst())); break; - default: return false; - } - break; - case EbtInt: - switch (constant.type) - { - case EbtInt: setIConst(static_cast(constant.getIConst())); break; - case EbtUInt: setIConst(static_cast(constant.getUConst())); break; - case EbtBool: setIConst(static_cast(constant.getBConst())); break; - case EbtFloat: setIConst(static_cast(constant.getFConst())); break; - default: return false; - } - break; - case EbtUInt: - switch (constant.type) - { - case EbtInt: setUConst(static_cast(constant.getIConst())); break; - case EbtUInt: setUConst(static_cast(constant.getUConst())); break; - case EbtBool: setUConst(static_cast(constant.getBConst())); break; - case EbtFloat: setUConst(static_cast(constant.getFConst())); break; - default: return false; - } - break; - case EbtBool: - switch (constant.type) - { - case EbtInt: setBConst(constant.getIConst() != 0); break; - case EbtUInt: setBConst(constant.getUConst() != 0); break; - case EbtBool: setBConst(constant.getBConst()); break; - case EbtFloat: setBConst(constant.getFConst() != 0.0f); break; - default: return false; - } - break; - case EbtStruct: // Struct fields don't get cast - switch (constant.type) - { - case EbtInt: setIConst(constant.getIConst()); break; - case EbtUInt: setUConst(constant.getUConst()); break; - case EbtBool: setBConst(constant.getBConst()); break; - case EbtFloat: setFConst(constant.getFConst()); break; - default: return false; - } - break; - default: - return false; - } - - return true; + uConst = u; + type = EbtUInt; } - - void setIConst(int i) {iConst = i; type = EbtInt; } - void setUConst(unsigned int u) { uConst = u; type = EbtUInt; } - void setFConst(float f) {fConst = f; type = EbtFloat; } - void setBConst(bool b) {bConst = b; type = EbtBool; } - - int getIConst() const { return iConst; } - unsigned int getUConst() const { return uConst; } - float getFConst() const { return fConst; } - bool getBConst() const { return bConst; } - - bool operator==(const int i) const + void setFConst(float f) { - return i == iConst; + fConst = f; + type = EbtFloat; } - - bool operator==(const unsigned int u) const + void setBConst(bool b) { - return u == uConst; + bConst = b; + type = EbtBool; } - bool operator==(const float f) const + void setYuvCscStandardEXTConst(TYuvCscStandardEXT s) { - return f == fConst; + yuvCscStandardEXTConst = s; + type = EbtYuvCscStandardEXT; } - bool operator==(const bool b) const - { - return b == bConst; - } + int getIConst() const; + unsigned int getUConst() const; + float getFConst() const; + bool getBConst() const; + TYuvCscStandardEXT getYuvCscStandardEXTConst() const; - bool operator==(const TConstantUnion& constant) const - { - if (constant.type != type) - return false; - - switch (type) { - case EbtInt: - return constant.iConst == iConst; - case EbtUInt: - return constant.uConst == uConst; - case EbtFloat: - return constant.fConst == fConst; - case EbtBool: - return constant.bConst == bConst; - default: - return false; - } - } - - bool operator!=(const int i) const - { - return !operator==(i); - } - - bool operator!=(const unsigned int u) const - { - return !operator==(u); - } - - bool operator!=(const float f) const - { - return !operator==(f); - } - - bool operator!=(const bool b) const - { - return !operator==(b); - } - - bool operator!=(const TConstantUnion& constant) const - { - return !operator==(constant); - } - - bool operator>(const TConstantUnion& constant) const - { - assert(type == constant.type); - switch (type) { - case EbtInt: - return iConst > constant.iConst; - case EbtUInt: - return uConst > constant.uConst; - case EbtFloat: - return fConst > constant.fConst; - default: - return false; // Invalid operation, handled at semantic analysis - } - } - - bool operator<(const TConstantUnion& constant) const - { - assert(type == constant.type); - switch (type) { - case EbtInt: - return iConst < constant.iConst; - case EbtUInt: - return uConst < constant.uConst; - case EbtFloat: - return fConst < constant.fConst; - default: - return false; // Invalid operation, handled at semantic analysis - } - } - - TConstantUnion operator+(const TConstantUnion& constant) const - { - TConstantUnion returnValue; - assert(type == constant.type); - switch (type) { - case EbtInt: returnValue.setIConst(iConst + constant.iConst); break; - case EbtUInt: returnValue.setUConst(uConst + constant.uConst); break; - case EbtFloat: returnValue.setFConst(fConst + constant.fConst); break; - default: assert(false && "Default missing"); - } - - return returnValue; - } - - TConstantUnion operator-(const TConstantUnion& constant) const - { - TConstantUnion returnValue; - assert(type == constant.type); - switch (type) { - case EbtInt: returnValue.setIConst(iConst - constant.iConst); break; - case EbtUInt: returnValue.setUConst(uConst - constant.uConst); break; - case EbtFloat: returnValue.setFConst(fConst - constant.fConst); break; - default: assert(false && "Default missing"); - } - - return returnValue; - } - - TConstantUnion operator*(const TConstantUnion& constant) const - { - TConstantUnion returnValue; - assert(type == constant.type); - switch (type) { - case EbtInt: returnValue.setIConst(iConst * constant.iConst); break; - case EbtUInt: returnValue.setUConst(uConst * constant.uConst); break; - case EbtFloat: returnValue.setFConst(fConst * constant.fConst); break; - default: assert(false && "Default missing"); - } - - return returnValue; - } - - TConstantUnion operator%(const TConstantUnion& constant) const - { - TConstantUnion returnValue; - assert(type == constant.type); - switch (type) { - case EbtInt: returnValue.setIConst(iConst % constant.iConst); break; - case EbtUInt: returnValue.setUConst(uConst % constant.uConst); break; - default: assert(false && "Default missing"); - } - - return returnValue; - } - - TConstantUnion operator>>(const TConstantUnion& constant) const - { - TConstantUnion returnValue; - assert(type == constant.type); - switch (type) { - case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break; - case EbtUInt: returnValue.setUConst(uConst >> constant.uConst); break; - default: assert(false && "Default missing"); - } - - return returnValue; - } - - TConstantUnion operator<<(const TConstantUnion& constant) const - { - TConstantUnion returnValue; - // The signedness of the second parameter might be different, but we - // don't care, since the result is undefined if the second parameter is - // negative, and aliasing should not be a problem with unions. - assert(constant.type == EbtInt || constant.type == EbtUInt); - switch (type) { - case EbtInt: returnValue.setIConst(iConst << constant.iConst); break; - case EbtUInt: returnValue.setUConst(uConst << constant.uConst); break; - default: assert(false && "Default missing"); - } - - return returnValue; - } - - TConstantUnion operator&(const TConstantUnion& constant) const - { - TConstantUnion returnValue; - assert(constant.type == EbtInt || constant.type == EbtUInt); - switch (type) { - case EbtInt: returnValue.setIConst(iConst & constant.iConst); break; - case EbtUInt: returnValue.setUConst(uConst & constant.uConst); break; - default: assert(false && "Default missing"); - } - - return returnValue; - } - - TConstantUnion operator|(const TConstantUnion& constant) const - { - TConstantUnion returnValue; - assert(type == constant.type); - switch (type) { - case EbtInt: returnValue.setIConst(iConst | constant.iConst); break; - case EbtUInt: returnValue.setUConst(uConst | constant.uConst); break; - default: assert(false && "Default missing"); - } - - return returnValue; - } - - TConstantUnion operator^(const TConstantUnion& constant) const - { - TConstantUnion returnValue; - assert(type == constant.type); - switch (type) { - case EbtInt: returnValue.setIConst(iConst ^ constant.iConst); break; - case EbtUInt: returnValue.setUConst(uConst ^ constant.uConst); break; - default: assert(false && "Default missing"); - } - - return returnValue; - } - - TConstantUnion operator&&(const TConstantUnion& constant) const - { - TConstantUnion returnValue; - assert(type == constant.type); - switch (type) { - case EbtBool: returnValue.setBConst(bConst && constant.bConst); break; - default: assert(false && "Default missing"); - } - - return returnValue; - } - - TConstantUnion operator||(const TConstantUnion& constant) const - { - TConstantUnion returnValue; - assert(type == constant.type); - switch (type) { - case EbtBool: returnValue.setBConst(bConst || constant.bConst); break; - default: assert(false && "Default missing"); - } - - return returnValue; - } + bool operator==(const int i) const; + bool operator==(const unsigned int u) const; + bool operator==(const float f) const; + bool operator==(const bool b) const; + bool operator==(const TYuvCscStandardEXT s) const; + bool operator==(const TConstantUnion &constant) const; + bool operator!=(const int i) const; + bool operator!=(const unsigned int u) const; + bool operator!=(const float f) const; + bool operator!=(const bool b) const; + bool operator!=(const TYuvCscStandardEXT s) const; + bool operator!=(const TConstantUnion &constant) const; + bool operator>(const TConstantUnion &constant) const; + bool operator<(const TConstantUnion &constant) const; + static TConstantUnion add(const TConstantUnion &lhs, + const TConstantUnion &rhs, + TDiagnostics *diag, + const TSourceLoc &line); + static TConstantUnion sub(const TConstantUnion &lhs, + const TConstantUnion &rhs, + TDiagnostics *diag, + const TSourceLoc &line); + static TConstantUnion mul(const TConstantUnion &lhs, + const TConstantUnion &rhs, + TDiagnostics *diag, + const TSourceLoc &line); + TConstantUnion operator%(const TConstantUnion &constant) const; + static TConstantUnion rshift(const TConstantUnion &lhs, + const TConstantUnion &rhs, + TDiagnostics *diag, + const TSourceLoc &line); + static TConstantUnion lshift(const TConstantUnion &lhs, + const TConstantUnion &rhs, + TDiagnostics *diag, + const TSourceLoc &line); + TConstantUnion operator&(const TConstantUnion &constant) const; + TConstantUnion operator|(const TConstantUnion &constant) const; + TConstantUnion operator^(const TConstantUnion &constant) const; + TConstantUnion operator&&(const TConstantUnion &constant) const; + TConstantUnion operator||(const TConstantUnion &constant) const; TBasicType getType() const { return type; } -private: - - union { - int iConst; // used for ivec, scalar ints - unsigned int uConst; // used for uvec, scalar uints - bool bConst; // used for bvec, scalar bools - float fConst; // used for vec, mat, scalar floats - } ; + private: + union { + int iConst; // used for ivec, scalar ints + unsigned int uConst; // used for uvec, scalar uints + bool bConst; // used for bvec, scalar bools + float fConst; // used for vec, mat, scalar floats + TYuvCscStandardEXT yuvCscStandardEXTConst; + }; TBasicType type; }; -#endif // COMPILER_TRANSLATOR_CONSTANTUNION_H_ +} // namespace sh + +#endif // COMPILER_TRANSLATOR_CONSTANTUNION_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.cpp b/src/3rdparty/angle/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.cpp new file mode 100644 index 0000000000..ce9828f1f9 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.cpp @@ -0,0 +1,221 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Applies the necessary AST transformations to support multiview rendering through instancing. +// Check the header file For more information. +// + +#include "compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.h" + +#include "compiler/translator/FindMain.h" +#include "compiler/translator/InitializeVariables.h" +#include "compiler/translator/IntermNode_util.h" +#include "compiler/translator/IntermTraverse.h" +#include "compiler/translator/SymbolTable.h" +#include "compiler/translator/util.h" + +namespace sh +{ + +namespace +{ + +class ReplaceVariableTraverser : public TIntermTraverser +{ + public: + ReplaceVariableTraverser(const TString &symbolName, TIntermSymbol *newSymbol) + : TIntermTraverser(true, false, false), mSymbolName(symbolName), mNewSymbol(newSymbol) + { + } + + void visitSymbol(TIntermSymbol *node) override + { + TName &name = node->getName(); + if (name.getString() == mSymbolName) + { + queueReplacement(mNewSymbol->deepCopy(), OriginalNode::IS_DROPPED); + } + } + + private: + TString mSymbolName; + TIntermSymbol *mNewSymbol; +}; + +TIntermSymbol *CreateGLInstanceIDSymbol(const TSymbolTable &symbolTable) +{ + return ReferenceBuiltInVariable("gl_InstanceID", symbolTable, 300); +} + +// Adds the InstanceID and ViewID_OVR initializers to the end of the initializers' sequence. +void InitializeViewIDAndInstanceID(TIntermTyped *viewIDSymbol, + TIntermTyped *instanceIDSymbol, + unsigned numberOfViews, + const TSymbolTable &symbolTable, + TIntermSequence *initializers) +{ + // Create an unsigned numberOfViews node. + TConstantUnion *numberOfViewsUnsignedConstant = new TConstantUnion(); + numberOfViewsUnsignedConstant->setUConst(numberOfViews); + TIntermConstantUnion *numberOfViewsUint = + new TIntermConstantUnion(numberOfViewsUnsignedConstant, TType(EbtUInt, EbpHigh, EvqConst)); + + // Create a uint(gl_InstanceID) node. + TIntermSequence *glInstanceIDSymbolCastArguments = new TIntermSequence(); + glInstanceIDSymbolCastArguments->push_back(CreateGLInstanceIDSymbol(symbolTable)); + TIntermAggregate *glInstanceIDAsUint = TIntermAggregate::CreateConstructor( + TType(EbtUInt, EbpHigh, EvqTemporary), glInstanceIDSymbolCastArguments); + + // Create a uint(gl_InstanceID) / numberOfViews node. + TIntermBinary *normalizedInstanceID = + new TIntermBinary(EOpDiv, glInstanceIDAsUint, numberOfViewsUint); + + // Create an int(uint(gl_InstanceID) / numberOfViews) node. + TIntermSequence *normalizedInstanceIDCastArguments = new TIntermSequence(); + normalizedInstanceIDCastArguments->push_back(normalizedInstanceID); + TIntermAggregate *normalizedInstanceIDAsInt = TIntermAggregate::CreateConstructor( + TType(EbtInt, EbpHigh, EvqTemporary), normalizedInstanceIDCastArguments); + + // Create an InstanceID = int(uint(gl_InstanceID) / numberOfViews) node. + TIntermBinary *instanceIDInitializer = + new TIntermBinary(EOpAssign, instanceIDSymbol->deepCopy(), normalizedInstanceIDAsInt); + initializers->push_back(instanceIDInitializer); + + // Create a uint(gl_InstanceID) % numberOfViews node. + TIntermBinary *normalizedViewID = + new TIntermBinary(EOpIMod, glInstanceIDAsUint->deepCopy(), numberOfViewsUint->deepCopy()); + + // Create a ViewID_OVR = uint(gl_InstanceID) % numberOfViews node. + TIntermBinary *viewIDInitializer = + new TIntermBinary(EOpAssign, viewIDSymbol->deepCopy(), normalizedViewID); + initializers->push_back(viewIDInitializer); +} + +// Replaces every occurrence of a symbol with the name specified in symbolName with newSymbolNode. +void ReplaceSymbol(TIntermBlock *root, const TString &symbolName, TIntermSymbol *newSymbolNode) +{ + ReplaceVariableTraverser traverser(symbolName, newSymbolNode); + root->traverse(&traverser); + traverser.updateTree(); +} + +void DeclareGlobalVariable(TIntermBlock *root, TIntermTyped *typedNode) +{ + TIntermSequence *globalSequence = root->getSequence(); + TIntermDeclaration *declaration = new TIntermDeclaration(); + declaration->appendDeclarator(typedNode->deepCopy()); + globalSequence->insert(globalSequence->begin(), declaration); +} + +// Adds a branch to write int(ViewID_OVR) to either gl_ViewportIndex or gl_Layer. The branch is +// added to the end of the initializers' sequence. +void SelectViewIndexInVertexShader(TIntermTyped *viewIDSymbol, + TIntermTyped *multiviewBaseViewLayerIndexSymbol, + TIntermSequence *initializers, + const TSymbolTable &symbolTable) +{ + // Create an int(ViewID_OVR) node. + TIntermSequence *viewIDSymbolCastArguments = new TIntermSequence(); + viewIDSymbolCastArguments->push_back(viewIDSymbol); + TIntermAggregate *viewIDAsInt = TIntermAggregate::CreateConstructor( + TType(EbtInt, EbpHigh, EvqTemporary), viewIDSymbolCastArguments); + + // Create a gl_ViewportIndex node. + TIntermSymbol *viewportIndexSymbol = + ReferenceBuiltInVariable("gl_ViewportIndex", symbolTable, 0); + + // Create a { gl_ViewportIndex = int(ViewID_OVR) } node. + TIntermBlock *viewportIndexInitializerInBlock = new TIntermBlock(); + viewportIndexInitializerInBlock->appendStatement( + new TIntermBinary(EOpAssign, viewportIndexSymbol, viewIDAsInt)); + + // Create a gl_Layer node. + TIntermSymbol *layerSymbol = ReferenceBuiltInVariable("gl_Layer", symbolTable, 0); + + // Create an int(ViewID_OVR) + multiviewBaseViewLayerIndex node + TIntermBinary *sumOfViewIDAndBaseViewIndex = + new TIntermBinary(EOpAdd, viewIDAsInt->deepCopy(), multiviewBaseViewLayerIndexSymbol); + + // Create a { gl_Layer = int(ViewID_OVR) + multiviewBaseViewLayerIndex } node. + TIntermBlock *layerInitializerInBlock = new TIntermBlock(); + layerInitializerInBlock->appendStatement( + new TIntermBinary(EOpAssign, layerSymbol, sumOfViewIDAndBaseViewIndex)); + + // Create a node to compare whether the base view index uniform is less than zero. + TIntermBinary *multiviewBaseViewLayerIndexZeroComparison = + new TIntermBinary(EOpLessThan, multiviewBaseViewLayerIndexSymbol->deepCopy(), + CreateZeroNode(TType(EbtInt, EbpHigh, EvqConst))); + + // Create an if-else statement to select the code path. + TIntermIfElse *multiviewBranch = + new TIntermIfElse(multiviewBaseViewLayerIndexZeroComparison, + viewportIndexInitializerInBlock, layerInitializerInBlock); + + initializers->push_back(multiviewBranch); +} + +} // namespace + +void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root, + unsigned numberOfViews, + GLenum shaderType, + ShCompileOptions compileOptions, + ShShaderOutput shaderOutput, + TSymbolTable *symbolTable) +{ + ASSERT(shaderType == GL_VERTEX_SHADER || shaderType == GL_FRAGMENT_SHADER); + + TQualifier viewIDQualifier = (shaderType == GL_VERTEX_SHADER) ? EvqFlatOut : EvqFlatIn; + TIntermSymbol *viewIDSymbol = new TIntermSymbol(symbolTable->nextUniqueId(), "ViewID_OVR", + TType(EbtUInt, EbpHigh, viewIDQualifier)); + viewIDSymbol->setInternal(true); + + DeclareGlobalVariable(root, viewIDSymbol); + ReplaceSymbol(root, "gl_ViewID_OVR", viewIDSymbol); + if (shaderType == GL_VERTEX_SHADER) + { + // Replacing gl_InstanceID with InstanceID should happen before adding the initializers of + // InstanceID and ViewID. + TIntermSymbol *instanceIDSymbol = new TIntermSymbol( + symbolTable->nextUniqueId(), "InstanceID", TType(EbtInt, EbpHigh, EvqGlobal)); + instanceIDSymbol->setInternal(true); + DeclareGlobalVariable(root, instanceIDSymbol); + ReplaceSymbol(root, "gl_InstanceID", instanceIDSymbol); + + TIntermSequence *initializers = new TIntermSequence(); + InitializeViewIDAndInstanceID(viewIDSymbol, instanceIDSymbol, numberOfViews, *symbolTable, + initializers); + + // The AST transformation which adds the expression to select the viewport index should + // be done only for the GLSL and ESSL output. + const bool selectView = (compileOptions & SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER) != 0u; + // Assert that if the view is selected in the vertex shader, then the output is + // either GLSL or ESSL. + ASSERT(!selectView || IsOutputGLSL(shaderOutput) || IsOutputESSL(shaderOutput)); + if (selectView) + { + // Add a uniform to switch between side-by-side and layered rendering. + TIntermSymbol *multiviewBaseViewLayerIndexSymbol = + new TIntermSymbol(symbolTable->nextUniqueId(), "multiviewBaseViewLayerIndex", + TType(EbtInt, EbpHigh, EvqUniform)); + multiviewBaseViewLayerIndexSymbol->setInternal(true); + DeclareGlobalVariable(root, multiviewBaseViewLayerIndexSymbol); + + // Setting a value to gl_ViewportIndex or gl_Layer should happen after ViewID_OVR's + // initialization. + SelectViewIndexInVertexShader(viewIDSymbol->deepCopy(), + multiviewBaseViewLayerIndexSymbol->deepCopy(), + initializers, *symbolTable); + } + + // Insert initializers at the beginning of main(). + TIntermBlock *initializersBlock = new TIntermBlock(); + initializersBlock->getSequence()->swap(*initializers); + TIntermBlock *mainBody = FindMainBody(root); + mainBody->getSequence()->insert(mainBody->getSequence()->begin(), initializersBlock); + } +} + +} // namespace sh \ No newline at end of file diff --git a/src/3rdparty/angle/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.h b/src/3rdparty/angle/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.h new file mode 100644 index 0000000000..b4ab05fd0e --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.h @@ -0,0 +1,48 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Regardless of the shader type, the following AST transformations are applied: +// - Add declaration of View_ID_OVR. +// - Replace every occurrence of gl_ViewID_OVR with ViewID_OVR, mark ViewID_OVR as internal and +// declare it as a flat varying. +// +// If the shader type is a vertex shader, the following AST transformations are applied: +// - Replace every occurrence of gl_InstanceID with InstanceID, mark InstanceID as internal and set +// its qualifier to EvqTemporary. +// - Add initializers of ViewID_OVR and InstanceID to the beginning of the body of main. The pass +// should be executed before any variables get collected so that usage of gl_InstanceID is recorded. +// - If the output is ESSL or GLSL and the SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER option is +// enabled, the expression +// "if (multiviewBaseViewLayerIndex < 0) { +// gl_ViewportIndex = int(ViewID_OVR); +// } else { +// gl_Layer = int(ViewID_OVR) + multiviewBaseViewLayerIndex; +// }" +// is added after ViewID and InstanceID are initialized. Also, MultiviewRenderPath is added as a +// uniform. +// + +#ifndef COMPILER_TRANSLATOR_DECLAREANDINITBUILTINSFORINSTANCEDMULTIVIEW_H_ +#define COMPILER_TRANSLATOR_DECLAREANDINITBUILTINSFORINSTANCEDMULTIVIEW_H_ + +#include "GLSLANG/ShaderLang.h" +#include "angle_gl.h" + +namespace sh +{ + +class TIntermBlock; +class TSymbolTable; + +void DeclareAndInitBuiltinsForInstancedMultiview(TIntermBlock *root, + unsigned numberOfViews, + GLenum shaderType, + ShCompileOptions compileOptions, + ShShaderOutput shaderOutput, + TSymbolTable *symbolTable); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_DECLAREANDINITBUILTINSFORINSTANCEDMULTIVIEW_H_ \ No newline at end of file diff --git a/src/3rdparty/angle/src/compiler/translator/DeferGlobalInitializers.cpp b/src/3rdparty/angle/src/compiler/translator/DeferGlobalInitializers.cpp new file mode 100644 index 0000000000..67d51ea87b --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/DeferGlobalInitializers.cpp @@ -0,0 +1,147 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// DeferGlobalInitializers is an AST traverser that moves global initializers into a separate +// function that is called in the beginning of main(). This enables initialization of globals with +// uniforms or non-constant globals, as allowed by the WebGL spec. Some initializers referencing +// non-constants may need to be unfolded into if statements in HLSL - this kind of steps should be +// done after DeferGlobalInitializers is run. Note that it's important that the function definition +// is at the end of the shader, as some globals may be declared after main(). +// +// It can also initialize all uninitialized globals. +// + +#include "compiler/translator/DeferGlobalInitializers.h" + +#include "compiler/translator/FindMain.h" +#include "compiler/translator/InitializeVariables.h" +#include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermNode_util.h" +#include "compiler/translator/SymbolTable.h" + +namespace sh +{ + +namespace +{ + +void GetDeferredInitializers(TIntermDeclaration *declaration, + bool initializeUninitializedGlobals, + bool canUseLoopsToInitialize, + TIntermSequence *deferredInitializersOut, + TSymbolTable *symbolTable) +{ + // SeparateDeclarations should have already been run. + ASSERT(declaration->getSequence()->size() == 1); + + TIntermNode *declarator = declaration->getSequence()->back(); + TIntermBinary *init = declarator->getAsBinaryNode(); + if (init) + { + TIntermSymbol *symbolNode = init->getLeft()->getAsSymbolNode(); + ASSERT(symbolNode); + TIntermTyped *expression = init->getRight(); + + if ((expression->getQualifier() != EvqConst || + (expression->getAsConstantUnion() == nullptr && + !expression->isConstructorWithOnlyConstantUnionParameters()))) + { + // For variables which are not constant, defer their real initialization until + // after we initialize uniforms. + // Deferral is done also in any cases where the variable has not been constant + // folded, since otherwise there's a chance that HLSL output will generate extra + // statements from the initializer expression. + + // Change const global to a regular global if its initialization is deferred. + // This can happen if ANGLE has not been able to fold the constant expression used + // as an initializer. + ASSERT(symbolNode->getQualifier() == EvqConst || + symbolNode->getQualifier() == EvqGlobal); + if (symbolNode->getQualifier() == EvqConst) + { + symbolNode->getTypePointer()->setQualifier(EvqGlobal); + } + + TIntermBinary *deferredInit = + new TIntermBinary(EOpAssign, symbolNode->deepCopy(), init->getRight()); + deferredInitializersOut->push_back(deferredInit); + + // Remove the initializer from the global scope and just declare the global instead. + declaration->replaceChildNode(init, symbolNode); + } + } + else if (initializeUninitializedGlobals) + { + TIntermSymbol *symbolNode = declarator->getAsSymbolNode(); + ASSERT(symbolNode); + + // Ignore ANGLE internal variables. + if (symbolNode->getName().isInternal()) + return; + + if (symbolNode->getQualifier() == EvqGlobal && symbolNode->getSymbol() != "") + { + TIntermSequence *initCode = + CreateInitCode(symbolNode, canUseLoopsToInitialize, symbolTable); + deferredInitializersOut->insert(deferredInitializersOut->end(), initCode->begin(), + initCode->end()); + } + } +} + +void InsertInitCallToMain(TIntermBlock *root, + TIntermSequence *deferredInitializers, + TSymbolTable *symbolTable) +{ + TIntermBlock *initGlobalsBlock = new TIntermBlock(); + initGlobalsBlock->getSequence()->swap(*deferredInitializers); + + TSymbolUniqueId initGlobalsFunctionId(symbolTable); + + const char *kInitGlobalsFunctionName = "initGlobals"; + + TIntermFunctionPrototype *initGlobalsFunctionPrototype = + CreateInternalFunctionPrototypeNode(TType(), kInitGlobalsFunctionName, initGlobalsFunctionId); + root->getSequence()->insert(root->getSequence()->begin(), initGlobalsFunctionPrototype); + TIntermFunctionDefinition *initGlobalsFunctionDefinition = CreateInternalFunctionDefinitionNode( + TType(), kInitGlobalsFunctionName, initGlobalsBlock, initGlobalsFunctionId); + root->appendStatement(initGlobalsFunctionDefinition); + + TIntermAggregate *initGlobalsCall = CreateInternalFunctionCallNode( + TType(), kInitGlobalsFunctionName, initGlobalsFunctionId, new TIntermSequence()); + + TIntermBlock *mainBody = FindMainBody(root); + mainBody->getSequence()->insert(mainBody->getSequence()->begin(), initGlobalsCall); +} + +} // namespace + +void DeferGlobalInitializers(TIntermBlock *root, + bool initializeUninitializedGlobals, + bool canUseLoopsToInitialize, + TSymbolTable *symbolTable) +{ + TIntermSequence *deferredInitializers = new TIntermSequence(); + + // Loop over all global statements and process the declarations. This is simpler than using a + // traverser. + for (TIntermNode *statement : *root->getSequence()) + { + TIntermDeclaration *declaration = statement->getAsDeclarationNode(); + if (declaration) + { + GetDeferredInitializers(declaration, initializeUninitializedGlobals, + canUseLoopsToInitialize, deferredInitializers, symbolTable); + } + } + + // Add the function with initialization and the call to that. + if (!deferredInitializers->empty()) + { + InsertInitCallToMain(root, deferredInitializers, symbolTable); + } +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/DeferGlobalInitializers.h b/src/3rdparty/angle/src/compiler/translator/DeferGlobalInitializers.h new file mode 100644 index 0000000000..86930a585f --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/DeferGlobalInitializers.h @@ -0,0 +1,32 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// DeferGlobalInitializers is an AST traverser that moves global initializers into a separate +// function that is called in the beginning of main(). This enables initialization of globals with +// uniforms or non-constant globals, as allowed by the WebGL spec. Some initializers referencing +// non-constants may need to be unfolded into if statements in HLSL - this kind of steps should be +// done after DeferGlobalInitializers is run. Note that it's important that the function definition +// is at the end of the shader, as some globals may be declared after main(). +// +// It can also initialize all uninitialized globals. +// + +#ifndef COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_ +#define COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_ + +namespace sh +{ + +class TIntermBlock; +class TSymbolTable; + +void DeferGlobalInitializers(TIntermBlock *root, + bool initializeUninitializedGlobals, + bool canUseLoopsToInitialize, + TSymbolTable *symbolTable); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_DEFERGLOBALINITIALIZERS_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/DetectCallDepth.cpp b/src/3rdparty/angle/src/compiler/translator/DetectCallDepth.cpp deleted file mode 100644 index 0dc5d22709..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/DetectCallDepth.cpp +++ /dev/null @@ -1,185 +0,0 @@ -// -// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/translator/DetectCallDepth.h" -#include "compiler/translator/InfoSink.h" - -DetectCallDepth::FunctionNode::FunctionNode(const TString& fname) - : name(fname), - visit(PreVisit) -{ -} - -const TString& DetectCallDepth::FunctionNode::getName() const -{ - return name; -} - -void DetectCallDepth::FunctionNode::addCallee( - DetectCallDepth::FunctionNode* callee) -{ - for (size_t i = 0; i < callees.size(); ++i) { - if (callees[i] == callee) - return; - } - callees.push_back(callee); -} - -int DetectCallDepth::FunctionNode::detectCallDepth(DetectCallDepth* detectCallDepth, int depth) -{ - ASSERT(visit == PreVisit); - ASSERT(detectCallDepth); - - int retMaxDepth = depth; - visit = InVisit; - for (size_t i = 0; i < callees.size(); ++i) { - switch (callees[i]->visit) { - case InVisit: - // cycle detected, i.e., recursion detected. - return kInfiniteCallDepth; - case PostVisit: - break; - case PreVisit: { - // Check before we recurse so we don't go too depth - if (detectCallDepth->checkExceedsMaxDepth(depth)) - return depth; - int callDepth = callees[i]->detectCallDepth(detectCallDepth, depth + 1); - // Check after we recurse so we can exit immediately and provide info. - if (detectCallDepth->checkExceedsMaxDepth(callDepth)) { - detectCallDepth->getInfoSink().info << "<-" << callees[i]->getName(); - return callDepth; - } - retMaxDepth = std::max(callDepth, retMaxDepth); - break; - } - default: - UNREACHABLE(); - break; - } - } - visit = PostVisit; - return retMaxDepth; -} - -void DetectCallDepth::FunctionNode::reset() -{ - visit = PreVisit; -} - -DetectCallDepth::DetectCallDepth(TInfoSink& infoSink, bool limitCallStackDepth, int maxCallStackDepth) - : TIntermTraverser(true, false, true, false), - currentFunction(NULL), - infoSink(infoSink), - maxDepth(limitCallStackDepth ? maxCallStackDepth : FunctionNode::kInfiniteCallDepth) -{ -} - -DetectCallDepth::~DetectCallDepth() -{ - for (size_t i = 0; i < functions.size(); ++i) - delete functions[i]; -} - -bool DetectCallDepth::visitAggregate(Visit visit, TIntermAggregate* node) -{ - switch (node->getOp()) - { - case EOpPrototype: - // Function declaration. - // Don't add FunctionNode here because node->getName() is the - // unmangled function name. - break; - case EOpFunction: { - // Function definition. - if (visit == PreVisit) { - currentFunction = findFunctionByName(node->getName()); - if (currentFunction == NULL) { - currentFunction = new FunctionNode(node->getName()); - functions.push_back(currentFunction); - } - } else if (visit == PostVisit) { - currentFunction = NULL; - } - break; - } - case EOpFunctionCall: { - // Function call. - if (visit == PreVisit) { - FunctionNode* func = findFunctionByName(node->getName()); - if (func == NULL) { - func = new FunctionNode(node->getName()); - functions.push_back(func); - } - if (currentFunction) - currentFunction->addCallee(func); - } - break; - } - default: - break; - } - return true; -} - -bool DetectCallDepth::checkExceedsMaxDepth(int depth) -{ - return depth >= maxDepth; -} - -void DetectCallDepth::resetFunctionNodes() -{ - for (size_t i = 0; i < functions.size(); ++i) { - functions[i]->reset(); - } -} - -DetectCallDepth::ErrorCode DetectCallDepth::detectCallDepthForFunction(FunctionNode* func) -{ - currentFunction = NULL; - resetFunctionNodes(); - - int maxCallDepth = func->detectCallDepth(this, 1); - - if (maxCallDepth == FunctionNode::kInfiniteCallDepth) - return kErrorRecursion; - - if (maxCallDepth >= maxDepth) - return kErrorMaxDepthExceeded; - - return kErrorNone; -} - -DetectCallDepth::ErrorCode DetectCallDepth::detectCallDepth() -{ - if (maxDepth != FunctionNode::kInfiniteCallDepth) { - // Check all functions because the driver may fail on them - // TODO: Before detectingRecursion, strip unused functions. - for (size_t i = 0; i < functions.size(); ++i) { - ErrorCode error = detectCallDepthForFunction(functions[i]); - if (error != kErrorNone) - return error; - } - } else { - FunctionNode* main = findFunctionByName("main("); - if (main == NULL) - return kErrorMissingMain; - - return detectCallDepthForFunction(main); - } - - return kErrorNone; -} - -DetectCallDepth::FunctionNode* DetectCallDepth::findFunctionByName( - const TString& name) -{ - for (size_t i = 0; i < functions.size(); ++i) { - if (functions[i]->getName() == name) - return functions[i]; - } - return NULL; -} - diff --git a/src/3rdparty/angle/src/compiler/translator/DetectCallDepth.h b/src/3rdparty/angle/src/compiler/translator/DetectCallDepth.h deleted file mode 100644 index 8dd1391e67..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/DetectCallDepth.h +++ /dev/null @@ -1,78 +0,0 @@ -// -// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_TRANSLATOR_DETECTCALLDEPTH_H_ -#define COMPILER_TRANSLATOR_DETECTCALLDEPTH_H_ - -#include -#include "compiler/translator/IntermNode.h" -#include "compiler/translator/VariableInfo.h" - -class TInfoSink; - -// Traverses intermediate tree to detect function recursion. -class DetectCallDepth : public TIntermTraverser { -public: - enum ErrorCode { - kErrorMissingMain, - kErrorRecursion, - kErrorMaxDepthExceeded, - kErrorNone - }; - - DetectCallDepth(TInfoSink& infoSync, bool limitCallStackDepth, int maxCallStackDepth); - ~DetectCallDepth(); - - virtual bool visitAggregate(Visit, TIntermAggregate*); - - bool checkExceedsMaxDepth(int depth); - - ErrorCode detectCallDepth(); - -private: - class FunctionNode { - public: - static const int kInfiniteCallDepth = INT_MAX; - - FunctionNode(const TString& fname); - - const TString& getName() const; - - // If a function is already in the callee list, this becomes a no-op. - void addCallee(FunctionNode* callee); - - // Returns kInifinityCallDepth if recursive function calls are detected. - int detectCallDepth(DetectCallDepth* detectCallDepth, int depth); - - // Reset state. - void reset(); - - private: - // mangled function name is unique. - TString name; - - // functions that are directly called by this function. - TVector callees; - - Visit visit; - }; - - ErrorCode detectCallDepthForFunction(FunctionNode* func); - FunctionNode* findFunctionByName(const TString& name); - void resetFunctionNodes(); - - TInfoSink& getInfoSink() { return infoSink; } - - TVector functions; - FunctionNode* currentFunction; - TInfoSink& infoSink; - int maxDepth; - - DetectCallDepth(const DetectCallDepth&); - void operator=(const DetectCallDepth&); -}; - -#endif // COMPILER_TRANSLATOR_DETECTCALLDEPTH_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.cpp b/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.cpp deleted file mode 100644 index f98d32b2b7..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.cpp +++ /dev/null @@ -1,191 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Contains analysis utilities for dealing with HLSL's lack of support for -// the use of intrinsic functions which (implicitly or explicitly) compute -// gradients of functions with discontinuities. -// - -#include "compiler/translator/DetectDiscontinuity.h" - -#include "compiler/translator/ParseContext.h" - -namespace sh -{ - -// Detect Loop Discontinuity - -bool DetectLoopDiscontinuity::traverse(TIntermNode *node) -{ - mLoopDepth = 0; - mLoopDiscontinuity = false; - node->traverse(this); - return mLoopDiscontinuity; -} - -bool DetectLoopDiscontinuity::visitLoop(Visit visit, TIntermLoop *loop) -{ - if (visit == PreVisit) - { - ++mLoopDepth; - } - else if (visit == PostVisit) - { - --mLoopDepth; - } - - return true; -} - -bool DetectLoopDiscontinuity::visitBranch(Visit visit, TIntermBranch *node) -{ - if (mLoopDiscontinuity) - { - return false; - } - - if (!mLoopDepth) - { - return true; - } - - switch (node->getFlowOp()) - { - case EOpKill: - break; - case EOpBreak: - case EOpContinue: - case EOpReturn: - mLoopDiscontinuity = true; - break; - default: UNREACHABLE(); - } - - return !mLoopDiscontinuity; -} - -bool DetectLoopDiscontinuity::visitAggregate(Visit visit, TIntermAggregate *node) -{ - return !mLoopDiscontinuity; -} - -bool containsLoopDiscontinuity(TIntermNode *node) -{ - DetectLoopDiscontinuity detectLoopDiscontinuity; - return detectLoopDiscontinuity.traverse(node); -} - -// Detect Any Loop - -bool DetectAnyLoop::traverse(TIntermNode *node) -{ - mHasLoop = false; - node->traverse(this); - return mHasLoop; -} - -bool DetectAnyLoop::visitLoop(Visit visit, TIntermLoop *loop) -{ - mHasLoop = true; - return false; -} - -// The following definitions stop all traversal when we have found a loop -bool DetectAnyLoop::visitBinary(Visit, TIntermBinary *) -{ - return !mHasLoop; -} - -bool DetectAnyLoop::visitUnary(Visit, TIntermUnary *) -{ - return !mHasLoop; -} - -bool DetectAnyLoop::visitSelection(Visit, TIntermSelection *) -{ - return !mHasLoop; -} - -bool DetectAnyLoop::visitAggregate(Visit, TIntermAggregate *) -{ - return !mHasLoop; -} - -bool DetectAnyLoop::visitBranch(Visit, TIntermBranch *) -{ - return !mHasLoop; -} - -bool containsAnyLoop(TIntermNode *node) -{ - DetectAnyLoop detectAnyLoop; - return detectAnyLoop.traverse(node); -} - -// Detect Gradient Operation - -bool DetectGradientOperation::traverse(TIntermNode *node) -{ - mGradientOperation = false; - node->traverse(this); - return mGradientOperation; -} - -bool DetectGradientOperation::visitUnary(Visit visit, TIntermUnary *node) -{ - if (mGradientOperation) - { - return false; - } - - switch (node->getOp()) - { - case EOpDFdx: - case EOpDFdy: - mGradientOperation = true; - default: - break; - } - - return !mGradientOperation; -} - -bool DetectGradientOperation::visitAggregate(Visit visit, TIntermAggregate *node) -{ - if (mGradientOperation) - { - return false; - } - - if (node->getOp() == EOpFunctionCall) - { - if (!node->isUserDefined()) - { - TString name = TFunction::unmangleName(node->getName()); - - if (name == "texture2D" || - name == "texture2DProj" || - name == "textureCube") - { - mGradientOperation = true; - } - } - else - { - // When a user defined function is called, we have to - // conservatively assume it to contain gradient operations - mGradientOperation = true; - } - } - - return !mGradientOperation; -} - -bool containsGradientOperation(TIntermNode *node) -{ - DetectGradientOperation detectGradientOperation; - return detectGradientOperation.traverse(node); -} -} diff --git a/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.h b/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.h deleted file mode 100644 index 623be13533..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/DetectDiscontinuity.h +++ /dev/null @@ -1,71 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Contains analysis utilities for dealing with HLSL's lack of support for -// the use of intrinsic functions which (implicitly or explicitly) compute -// gradients of functions with discontinuities. -// - -#ifndef COMPILER_TRANSLATOR_DETECTDISCONTINUITY_H_ -#define COMPILER_TRANSLATOR_DETECTDISCONTINUITY_H_ - -#include "compiler/translator/IntermNode.h" - -namespace sh -{ -// Checks whether a loop can run for a variable number of iterations -class DetectLoopDiscontinuity : public TIntermTraverser -{ - public: - bool traverse(TIntermNode *node); - - protected: - bool visitBranch(Visit visit, TIntermBranch *node); - bool visitLoop(Visit visit, TIntermLoop *loop); - bool visitAggregate(Visit visit, TIntermAggregate *node); - - int mLoopDepth; - bool mLoopDiscontinuity; -}; - -bool containsLoopDiscontinuity(TIntermNode *node); - -// Checks for the existence of any loop -class DetectAnyLoop : public TIntermTraverser -{ -public: - bool traverse(TIntermNode *node); - -protected: - bool visitBinary(Visit, TIntermBinary *); - bool visitUnary(Visit, TIntermUnary *); - bool visitSelection(Visit, TIntermSelection *); - bool visitAggregate(Visit, TIntermAggregate *); - bool visitLoop(Visit, TIntermLoop *); - bool visitBranch(Visit, TIntermBranch *); - - bool mHasLoop; -}; - -bool containsAnyLoop(TIntermNode *node); - -// Checks for intrinsic functions which compute gradients -class DetectGradientOperation : public TIntermTraverser -{ - public: - bool traverse(TIntermNode *node); - - protected: - bool visitUnary(Visit visit, TIntermUnary *node); - bool visitAggregate(Visit visit, TIntermAggregate *node); - - bool mGradientOperation; -}; - -bool containsGradientOperation(TIntermNode *node); - -} - -#endif // COMPILER_TRANSLATOR_DETECTDISCONTINUITY_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/Diagnostics.cpp b/src/3rdparty/angle/src/compiler/translator/Diagnostics.cpp index 593137fb0a..1744e5ab3e 100644 --- a/src/3rdparty/angle/src/compiler/translator/Diagnostics.cpp +++ b/src/3rdparty/angle/src/compiler/translator/Diagnostics.cpp @@ -7,13 +7,15 @@ #include "compiler/translator/Diagnostics.h" #include "common/debug.h" -#include "compiler/translator/InfoSink.h" #include "compiler/preprocessor/SourceLocation.h" +#include "compiler/translator/Common.h" +#include "compiler/translator/InfoSink.h" -TDiagnostics::TDiagnostics(TInfoSink& infoSink) : - mInfoSink(infoSink), - mNumErrors(0), - mNumWarnings(0) +namespace sh +{ + +TDiagnostics::TDiagnostics(TInfoSinkBase &infoSink) + : mInfoSink(infoSink), mNumErrors(0), mNumWarnings(0) { } @@ -22,37 +24,82 @@ TDiagnostics::~TDiagnostics() } void TDiagnostics::writeInfo(Severity severity, - const pp::SourceLocation& loc, - const std::string& reason, - const std::string& token, - const std::string& extra) + const pp::SourceLocation &loc, + const char *reason, + const char *token) { - TPrefixType prefix = EPrefixNone; switch (severity) { - case PP_ERROR: - ++mNumErrors; - prefix = EPrefixError; - break; - case PP_WARNING: - ++mNumWarnings; - prefix = EPrefixWarning; - break; - default: - UNREACHABLE(); - break; + case SH_ERROR: + ++mNumErrors; + break; + case SH_WARNING: + ++mNumWarnings; + break; + default: + UNREACHABLE(); + break; } - TInfoSinkBase& sink = mInfoSink.info; /* VC++ format: file(linenum) : error #: 'token' : extrainfo */ - sink.prefix(prefix); - sink.location(loc.file, loc.line); - sink << "'" << token << "' : " << reason << " " << extra << "\n"; + mInfoSink.prefix(severity); + mInfoSink.location(loc.file, loc.line); + mInfoSink << "'" << token << "' : " << reason << "\n"; } -void TDiagnostics::print(ID id, - const pp::SourceLocation& loc, - const std::string& text) +void TDiagnostics::globalError(const char *message) { - writeInfo(severity(id), loc, message(id), text, ""); + ++mNumErrors; + mInfoSink.prefix(SH_ERROR); + mInfoSink << message << "\n"; } + +void TDiagnostics::error(const pp::SourceLocation &loc, const char *reason, const char *token) +{ + writeInfo(SH_ERROR, loc, reason, token); +} + +void TDiagnostics::warning(const pp::SourceLocation &loc, const char *reason, const char *token) +{ + writeInfo(SH_WARNING, loc, reason, token); +} + +void TDiagnostics::error(const TSourceLoc &loc, const char *reason, const char *token) +{ + pp::SourceLocation srcLoc; + srcLoc.file = loc.first_file; + srcLoc.line = loc.first_line; + error(srcLoc, reason, token); +} + +void TDiagnostics::warning(const TSourceLoc &loc, const char *reason, const char *token) +{ + pp::SourceLocation srcLoc; + srcLoc.file = loc.first_file; + srcLoc.line = loc.first_line; + warning(srcLoc, reason, token); +} + +void TDiagnostics::print(ID id, const pp::SourceLocation &loc, const std::string &text) +{ + writeInfo(isError(id) ? SH_ERROR : SH_WARNING, loc, message(id), text.c_str()); +} + +void TDiagnostics::resetErrorCount() +{ + mNumErrors = 0; + mNumWarnings = 0; +} + +PerformanceDiagnostics::PerformanceDiagnostics(TDiagnostics *diagnostics) + : mDiagnostics(diagnostics) +{ + ASSERT(diagnostics); +} + +void PerformanceDiagnostics::warning(const TSourceLoc &loc, const char *reason, const char *token) +{ + mDiagnostics->warning(loc, reason, token); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/Diagnostics.h b/src/3rdparty/angle/src/compiler/translator/Diagnostics.h index bc26e4584f..55b88991df 100644 --- a/src/3rdparty/angle/src/compiler/translator/Diagnostics.h +++ b/src/3rdparty/angle/src/compiler/translator/Diagnostics.h @@ -9,33 +9,59 @@ #include "common/angleutils.h" #include "compiler/preprocessor/DiagnosticsBase.h" +#include "compiler/translator/Severity.h" -class TInfoSink; +namespace sh +{ + +class TInfoSinkBase; +struct TSourceLoc; class TDiagnostics : public pp::Diagnostics, angle::NonCopyable { public: - TDiagnostics(TInfoSink& infoSink); + TDiagnostics(TInfoSinkBase &infoSink); ~TDiagnostics() override; - TInfoSink& infoSink() { return mInfoSink; } - int numErrors() const { return mNumErrors; } int numWarnings() const { return mNumWarnings; } - void writeInfo(Severity severity, - const pp::SourceLocation& loc, - const std::string& reason, - const std::string& token, - const std::string& extra); + void error(const pp::SourceLocation &loc, const char *reason, const char *token); + void warning(const pp::SourceLocation &loc, const char *reason, const char *token); + + void error(const TSourceLoc &loc, const char *reason, const char *token); + void warning(const TSourceLoc &loc, const char *reason, const char *token); + + void globalError(const char *message); + + void resetErrorCount(); protected: + void writeInfo(Severity severity, + const pp::SourceLocation &loc, + const char *reason, + const char *token); + void print(ID id, const pp::SourceLocation &loc, const std::string &text) override; private: - TInfoSink& mInfoSink; + TInfoSinkBase &mInfoSink; int mNumErrors; int mNumWarnings; }; +// Diagnostics wrapper to use when the code is only allowed to generate warnings. +class PerformanceDiagnostics : public angle::NonCopyable +{ + public: + PerformanceDiagnostics(TDiagnostics *diagnostics); + + void warning(const TSourceLoc &loc, const char *reason, const char *token); + + private: + TDiagnostics *mDiagnostics; +}; + +} // namespace sh + #endif // COMPILER_TRANSLATOR_DIAGNOSTICS_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.cpp b/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.cpp index ff8a69efa5..485e66670c 100644 --- a/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.cpp +++ b/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.cpp @@ -12,17 +12,24 @@ #include "common/debug.h" #include "compiler/translator/Diagnostics.h" -static TBehavior getBehavior(const std::string& str) +namespace sh +{ + +static TBehavior getBehavior(const std::string &str) { const char kRequire[] = "require"; - const char kEnable[] = "enable"; + const char kEnable[] = "enable"; const char kDisable[] = "disable"; - const char kWarn[] = "warn"; + const char kWarn[] = "warn"; - if (str == kRequire) return EBhRequire; - else if (str == kEnable) return EBhEnable; - else if (str == kDisable) return EBhDisable; - else if (str == kWarn) return EBhWarn; + if (str == kRequire) + return EBhRequire; + else if (str == kEnable) + return EBhEnable; + else if (str == kDisable) + return EBhDisable; + else if (str == kWarn) + return EBhWarn; return EBhUndefined; } @@ -43,30 +50,29 @@ TDirectiveHandler::~TDirectiveHandler() { } -void TDirectiveHandler::handleError(const pp::SourceLocation& loc, - const std::string& msg) +void TDirectiveHandler::handleError(const pp::SourceLocation &loc, const std::string &msg) { - mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, msg, "", ""); + mDiagnostics.error(loc, msg.c_str(), ""); } -void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc, - const std::string& name, - const std::string& value, +void TDirectiveHandler::handlePragma(const pp::SourceLocation &loc, + const std::string &name, + const std::string &value, bool stdgl) { if (stdgl) { const char kInvariant[] = "invariant"; - const char kAll[] = "all"; + const char kAll[] = "all"; if (name == kInvariant && value == kAll) { if (mShaderVersion == 300 && mShaderType == GL_FRAGMENT_SHADER) { // ESSL 3.00.4 section 4.6.1 - mDiagnostics.writeInfo( - pp::Diagnostics::PP_ERROR, loc, - "#pragma STDGL invariant(all) can not be used in fragment shader", name, value); + mDiagnostics.error( + loc, "#pragma STDGL invariant(all) can not be used in fragment shader", + name.c_str()); } mPragma.stdgl.invariantAll = true; } @@ -77,30 +83,39 @@ void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc, } else { - const char kOptimize[] = "optimize"; - const char kDebug[] = "debug"; + const char kOptimize[] = "optimize"; + const char kDebug[] = "debug"; const char kDebugShaderPrecision[] = "webgl_debug_shader_precision"; - const char kOn[] = "on"; - const char kOff[] = "off"; + const char kOn[] = "on"; + const char kOff[] = "off"; bool invalidValue = false; if (name == kOptimize) { - if (value == kOn) mPragma.optimize = true; - else if (value == kOff) mPragma.optimize = false; - else invalidValue = true; + if (value == kOn) + mPragma.optimize = true; + else if (value == kOff) + mPragma.optimize = false; + else + invalidValue = true; } else if (name == kDebug) { - if (value == kOn) mPragma.debug = true; - else if (value == kOff) mPragma.debug = false; - else invalidValue = true; + if (value == kOn) + mPragma.debug = true; + else if (value == kOff) + mPragma.debug = false; + else + invalidValue = true; } else if (name == kDebugShaderPrecision && mDebugShaderPrecisionSupported) { - if (value == kOn) mPragma.debugShaderPrecision = true; - else if (value == kOff) mPragma.debugShaderPrecision = false; - else invalidValue = true; + if (value == kOn) + mPragma.debugShaderPrecision = true; + else if (value == kOff) + mPragma.debugShaderPrecision = false; + else + invalidValue = true; } else { @@ -110,24 +125,21 @@ void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc, if (invalidValue) { - mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, - "invalid pragma value", value, - "'on' or 'off' expected"); + mDiagnostics.error(loc, "invalid pragma value - 'on' or 'off' expected", value.c_str()); } } } -void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc, - const std::string& name, - const std::string& behavior) +void TDirectiveHandler::handleExtension(const pp::SourceLocation &loc, + const std::string &name, + const std::string &behavior) { const char kExtAll[] = "all"; TBehavior behaviorVal = getBehavior(behavior); if (behaviorVal == EBhUndefined) { - mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, - "behavior", name, "invalid"); + mDiagnostics.error(loc, "behavior invalid", name.c_str()); return; } @@ -135,15 +147,11 @@ void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc, { if (behaviorVal == EBhRequire) { - mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, - "extension", name, - "cannot have 'require' behavior"); + mDiagnostics.error(loc, "extension cannot have 'require' behavior", name.c_str()); } else if (behaviorVal == EBhEnable) { - mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, - "extension", name, - "cannot have 'enable' behavior"); + mDiagnostics.error(loc, "extension cannot have 'enable' behavior", name.c_str()); } else { @@ -154,36 +162,32 @@ void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc, return; } - TExtensionBehavior::iterator iter = mExtensionBehavior.find(name); + TExtensionBehavior::iterator iter = mExtensionBehavior.find(GetExtensionByName(name.c_str())); if (iter != mExtensionBehavior.end()) { iter->second = behaviorVal; return; } - pp::Diagnostics::Severity severity = pp::Diagnostics::PP_ERROR; - switch (behaviorVal) { - case EBhRequire: - severity = pp::Diagnostics::PP_ERROR; - break; - case EBhEnable: - case EBhWarn: - case EBhDisable: - severity = pp::Diagnostics::PP_WARNING; - break; - default: - UNREACHABLE(); - break; + switch (behaviorVal) + { + case EBhRequire: + mDiagnostics.error(loc, "extension is not supported", name.c_str()); + break; + case EBhEnable: + case EBhWarn: + case EBhDisable: + mDiagnostics.warning(loc, "extension is not supported", name.c_str()); + break; + default: + UNREACHABLE(); + break; } - mDiagnostics.writeInfo(severity, loc, - "extension", name, "is not supported"); } -void TDirectiveHandler::handleVersion(const pp::SourceLocation& loc, - int version) +void TDirectiveHandler::handleVersion(const pp::SourceLocation &loc, int version) { - if (version == 100 || - version == 300) + if (version == 100 || version == 300 || version == 310) { mShaderVersion = version; } @@ -192,7 +196,8 @@ void TDirectiveHandler::handleVersion(const pp::SourceLocation& loc, std::stringstream stream; stream << version; std::string str = stream.str(); - mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, - "version number", str, "not supported"); + mDiagnostics.error(loc, "version number not supported", str.c_str()); } } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.h b/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.h index 00eb49114e..8e8cb9bbf6 100644 --- a/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.h +++ b/src/3rdparty/angle/src/compiler/translator/DirectiveHandler.h @@ -13,6 +13,8 @@ #include "compiler/preprocessor/DirectiveHandlerBase.h" #include "GLSLANG/ShaderLang.h" +namespace sh +{ class TDiagnostics; class TDirectiveHandler : public pp::DirectiveHandler, angle::NonCopyable @@ -25,8 +27,8 @@ class TDirectiveHandler : public pp::DirectiveHandler, angle::NonCopyable bool debugShaderPrecisionSupported); ~TDirectiveHandler() override; - const TPragma& pragma() const { return mPragma; } - const TExtensionBehavior& extensionBehavior() const { return mExtensionBehavior; } + const TPragma &pragma() const { return mPragma; } + const TExtensionBehavior &extensionBehavior() const { return mExtensionBehavior; } void handleError(const pp::SourceLocation &loc, const std::string &msg) override; @@ -43,11 +45,13 @@ class TDirectiveHandler : public pp::DirectiveHandler, angle::NonCopyable private: TPragma mPragma; - TExtensionBehavior& mExtensionBehavior; - TDiagnostics& mDiagnostics; - int& mShaderVersion; + TExtensionBehavior &mExtensionBehavior; + TDiagnostics &mDiagnostics; + int &mShaderVersion; sh::GLenum mShaderType; bool mDebugShaderPrecisionSupported; }; +} // namespace sh + #endif // COMPILER_TRANSLATOR_DIRECTIVEHANDLER_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/EmulateGLFragColorBroadcast.cpp b/src/3rdparty/angle/src/compiler/translator/EmulateGLFragColorBroadcast.cpp new file mode 100644 index 0000000000..189ea341eb --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/EmulateGLFragColorBroadcast.cpp @@ -0,0 +1,129 @@ +// +// Copyright (c) 2002-2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// gl_FragColor needs to broadcast to all color buffers in ES2 if +// GL_EXT_draw_buffers is explicitly enabled in a fragment shader. +// +// We emulate this by replacing all gl_FragColor with gl_FragData[0], and in the end +// of main() function, assigning gl_FragData[1], ..., gl_FragData[maxDrawBuffers-1] +// with gl_FragData[0]. +// + +#include "compiler/translator/EmulateGLFragColorBroadcast.h" + +#include "compiler/translator/IntermNode_util.h" +#include "compiler/translator/IntermTraverse.h" +#include "compiler/translator/RunAtTheEndOfShader.h" + +namespace sh +{ + +namespace +{ + +class GLFragColorBroadcastTraverser : public TIntermTraverser +{ + public: + GLFragColorBroadcastTraverser(int maxDrawBuffers, TSymbolTable *symbolTable, int shaderVersion) + : TIntermTraverser(true, false, false, symbolTable), + mGLFragColorUsed(false), + mMaxDrawBuffers(maxDrawBuffers), + mShaderVersion(shaderVersion) + { + } + + void broadcastGLFragColor(TIntermBlock *root); + + bool isGLFragColorUsed() const { return mGLFragColorUsed; } + + protected: + void visitSymbol(TIntermSymbol *node) override; + + TIntermBinary *constructGLFragDataNode(int index) const; + TIntermBinary *constructGLFragDataAssignNode(int index) const; + + private: + bool mGLFragColorUsed; + int mMaxDrawBuffers; + const int mShaderVersion; +}; + +TIntermBinary *GLFragColorBroadcastTraverser::constructGLFragDataNode(int index) const +{ + TIntermSymbol *symbol = + ReferenceBuiltInVariable(TString("gl_FragData"), *mSymbolTable, mShaderVersion); + TIntermTyped *indexNode = CreateIndexNode(index); + + TIntermBinary *binary = new TIntermBinary(EOpIndexDirect, symbol, indexNode); + return binary; +} + +TIntermBinary *GLFragColorBroadcastTraverser::constructGLFragDataAssignNode(int index) const +{ + TIntermTyped *fragDataIndex = constructGLFragDataNode(index); + TIntermTyped *fragDataZero = constructGLFragDataNode(0); + + return new TIntermBinary(EOpAssign, fragDataIndex, fragDataZero); +} + +void GLFragColorBroadcastTraverser::visitSymbol(TIntermSymbol *node) +{ + if (node->getSymbol() == "gl_FragColor") + { + queueReplacement(constructGLFragDataNode(0), OriginalNode::IS_DROPPED); + mGLFragColorUsed = true; + } +} + +void GLFragColorBroadcastTraverser::broadcastGLFragColor(TIntermBlock *root) +{ + ASSERT(mMaxDrawBuffers > 1); + if (!mGLFragColorUsed) + { + return; + } + + TIntermBlock *broadcastBlock = new TIntermBlock(); + // Now insert statements + // gl_FragData[1] = gl_FragData[0]; + // ... + // gl_FragData[maxDrawBuffers - 1] = gl_FragData[0]; + for (int colorIndex = 1; colorIndex < mMaxDrawBuffers; ++colorIndex) + { + broadcastBlock->appendStatement(constructGLFragDataAssignNode(colorIndex)); + } + RunAtTheEndOfShader(root, broadcastBlock, mSymbolTable); +} + +} // namespace anonymous + +void EmulateGLFragColorBroadcast(TIntermBlock *root, + int maxDrawBuffers, + std::vector *outputVariables, + TSymbolTable *symbolTable, + int shaderVersion) +{ + ASSERT(maxDrawBuffers > 1); + GLFragColorBroadcastTraverser traverser(maxDrawBuffers, symbolTable, shaderVersion); + root->traverse(&traverser); + if (traverser.isGLFragColorUsed()) + { + traverser.updateTree(); + traverser.broadcastGLFragColor(root); + for (auto &var : *outputVariables) + { + if (var.name == "gl_FragColor") + { + // TODO(zmo): Find a way to keep the original variable information. + var.name = "gl_FragData"; + var.mappedName = "gl_FragData"; + var.arraySizes.push_back(maxDrawBuffers); + ASSERT(var.arraySizes.size() == 1u); + } + } + } +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/EmulateGLFragColorBroadcast.h b/src/3rdparty/angle/src/compiler/translator/EmulateGLFragColorBroadcast.h new file mode 100644 index 0000000000..e652b7e07e --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/EmulateGLFragColorBroadcast.h @@ -0,0 +1,31 @@ +// +// Copyright (c) 2002-2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Emulate gl_FragColor broadcast behaviors in ES2 where +// GL_EXT_draw_buffers is explicitly enabled in a fragment shader. +// + +#ifndef COMPILER_TRANSLATOR_EMULATEGLFRAGCOLORBROADCAST_H_ +#define COMPILER_TRANSLATOR_EMULATEGLFRAGCOLORBROADCAST_H_ + +#include + +namespace sh +{ +struct OutputVariable; +class TIntermBlock; +class TSymbolTable; + +// Replace all gl_FragColor with gl_FragData[0], and in the end of main() function, +// assign gl_FragData[1] ... gl_FragData[maxDrawBuffers - 1] with gl_FragData[0]. +// If gl_FragColor is in outputVariables, it is replaced by gl_FragData. +void EmulateGLFragColorBroadcast(TIntermBlock *root, + int maxDrawBuffers, + std::vector *outputVariables, + TSymbolTable *symbolTable, + int shaderVersion); +} + +#endif // COMPILER_TRANSLATOR_EMULATEGLFRAGCOLORBROADCAST_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/EmulatePrecision.cpp b/src/3rdparty/angle/src/compiler/translator/EmulatePrecision.cpp index 4a7fa54155..ba09fd77df 100644 --- a/src/3rdparty/angle/src/compiler/translator/EmulatePrecision.cpp +++ b/src/3rdparty/angle/src/compiler/translator/EmulatePrecision.cpp @@ -6,88 +6,206 @@ #include "compiler/translator/EmulatePrecision.h" +#include + +namespace sh +{ + namespace { -static void writeVectorPrecisionEmulationHelpers( - TInfoSinkBase& sink, ShShaderOutput outputLanguage, unsigned int size) +class RoundingHelperWriter : angle::NonCopyable { - std::stringstream vecTypeStrStr; - if (outputLanguage == SH_ESSL_OUTPUT) - vecTypeStrStr << "highp "; - vecTypeStrStr << "vec" << size; - std::string vecType = vecTypeStrStr.str(); + public: + static RoundingHelperWriter *createHelperWriter(const ShShaderOutput outputLanguage); - sink << - vecType << " angle_frm(in " << vecType << " v) {\n" - " v = clamp(v, -65504.0, 65504.0);\n" - " " << vecType << " exponent = floor(log2(abs(v) + 1e-30)) - 10.0;\n" - " bvec" << size << " isNonZero = greaterThanEqual(exponent, vec" << size << "(-25.0));\n" - " v = v * exp2(-exponent);\n" - " v = sign(v) * floor(abs(v));\n" - " return v * exp2(exponent) * vec" << size << "(isNonZero);\n" - "}\n"; + void writeCommonRoundingHelpers(TInfoSinkBase &sink, const int shaderVersion); + void writeCompoundAssignmentHelper(TInfoSinkBase &sink, + const char *lType, + const char *rType, + const char *opStr, + const char *opNameStr); - sink << - vecType << " angle_frl(in " << vecType << " v) {\n" - " v = clamp(v, -2.0, 2.0);\n" - " v = v * 256.0;\n" - " v = sign(v) * floor(abs(v));\n" - " return v * 0.00390625;\n" - "}\n"; -} + virtual ~RoundingHelperWriter() {} -static void writeMatrixPrecisionEmulationHelper( - TInfoSinkBase& sink, ShShaderOutput outputLanguage, unsigned int size, const char *functionName) + protected: + RoundingHelperWriter(const ShShaderOutput outputLanguage) : mOutputLanguage(outputLanguage) {} + RoundingHelperWriter() = delete; + + const ShShaderOutput mOutputLanguage; + + private: + virtual std::string getTypeString(const char *glslType) = 0; + virtual void writeFloatRoundingHelpers(TInfoSinkBase &sink) = 0; + virtual void writeVectorRoundingHelpers(TInfoSinkBase &sink, const unsigned int size) = 0; + virtual void writeMatrixRoundingHelper(TInfoSinkBase &sink, + const unsigned int columns, + const unsigned int rows, + const char *functionName) = 0; +}; + +class RoundingHelperWriterGLSL : public RoundingHelperWriter { - std::stringstream matTypeStrStr; - if (outputLanguage == SH_ESSL_OUTPUT) - matTypeStrStr << "highp "; - matTypeStrStr << "mat" << size; - std::string matType = matTypeStrStr.str(); - - sink << matType << " " << functionName << "(in " << matType << " m) {\n" - " " << matType << " rounded;\n"; - - for (unsigned int i = 0; i < size; ++i) + public: + RoundingHelperWriterGLSL(const ShShaderOutput outputLanguage) + : RoundingHelperWriter(outputLanguage) { - sink << " rounded[" << i << "] = " << functionName << "(m[" << i << "]);\n"; } - sink << " return rounded;\n" - "}\n"; + private: + std::string getTypeString(const char *glslType) override; + void writeFloatRoundingHelpers(TInfoSinkBase &sink) override; + void writeVectorRoundingHelpers(TInfoSinkBase &sink, const unsigned int size) override; + void writeMatrixRoundingHelper(TInfoSinkBase &sink, + const unsigned int columns, + const unsigned int rows, + const char *functionName) override; +}; + +class RoundingHelperWriterESSL : public RoundingHelperWriterGLSL +{ + public: + RoundingHelperWriterESSL(const ShShaderOutput outputLanguage) + : RoundingHelperWriterGLSL(outputLanguage) + { + } + + private: + std::string getTypeString(const char *glslType) override; +}; + +class RoundingHelperWriterHLSL : public RoundingHelperWriter +{ + public: + RoundingHelperWriterHLSL(const ShShaderOutput outputLanguage) + : RoundingHelperWriter(outputLanguage) + { + } + + private: + std::string getTypeString(const char *glslType) override; + void writeFloatRoundingHelpers(TInfoSinkBase &sink) override; + void writeVectorRoundingHelpers(TInfoSinkBase &sink, const unsigned int size) override; + void writeMatrixRoundingHelper(TInfoSinkBase &sink, + const unsigned int columns, + const unsigned int rows, + const char *functionName) override; +}; + +RoundingHelperWriter *RoundingHelperWriter::createHelperWriter(const ShShaderOutput outputLanguage) +{ + ASSERT(EmulatePrecision::SupportedInLanguage(outputLanguage)); + switch (outputLanguage) + { + case SH_HLSL_4_1_OUTPUT: + return new RoundingHelperWriterHLSL(outputLanguage); + case SH_ESSL_OUTPUT: + return new RoundingHelperWriterESSL(outputLanguage); + default: + return new RoundingHelperWriterGLSL(outputLanguage); + } } -static void writeCommonPrecisionEmulationHelpers(TInfoSinkBase& sink, ShShaderOutput outputLanguage) +void RoundingHelperWriter::writeCommonRoundingHelpers(TInfoSinkBase &sink, const int shaderVersion) { // Write the angle_frm functions that round floating point numbers to // half precision, and angle_frl functions that round them to minimum lowp // precision. + writeFloatRoundingHelpers(sink); + writeVectorRoundingHelpers(sink, 2); + writeVectorRoundingHelpers(sink, 3); + writeVectorRoundingHelpers(sink, 4); + if (shaderVersion > 100) + { + for (unsigned int columns = 2; columns <= 4; ++columns) + { + for (unsigned int rows = 2; rows <= 4; ++rows) + { + writeMatrixRoundingHelper(sink, columns, rows, "angle_frm"); + writeMatrixRoundingHelper(sink, columns, rows, "angle_frl"); + } + } + } + else + { + for (unsigned int size = 2; size <= 4; ++size) + { + writeMatrixRoundingHelper(sink, size, size, "angle_frm"); + writeMatrixRoundingHelper(sink, size, size, "angle_frl"); + } + } +} + +void RoundingHelperWriter::writeCompoundAssignmentHelper(TInfoSinkBase &sink, + const char *lType, + const char *rType, + const char *opStr, + const char *opNameStr) +{ + std::string lTypeStr = getTypeString(lType); + std::string rTypeStr = getTypeString(rType); + + // Note that y should be passed through angle_frm at the function call site, + // but x can't be passed through angle_frm there since it is an inout parameter. + // So only pass x and the result through angle_frm here. + // clang-format off + sink << + lTypeStr << " angle_compound_" << opNameStr << "_frm(inout " << lTypeStr << " x, in " << rTypeStr << " y) {\n" + " x = angle_frm(angle_frm(x) " << opStr << " y);\n" + " return x;\n" + "}\n"; + sink << + lTypeStr << " angle_compound_" << opNameStr << "_frl(inout " << lTypeStr << " x, in " << rTypeStr << " y) {\n" + " x = angle_frl(angle_frl(x) " << opStr << " y);\n" + " return x;\n" + "}\n"; + // clang-format on +} + +std::string RoundingHelperWriterGLSL::getTypeString(const char *glslType) +{ + return glslType; +} + +std::string RoundingHelperWriterESSL::getTypeString(const char *glslType) +{ + std::stringstream typeStrStr; + typeStrStr << "highp " << glslType; + return typeStrStr.str(); +} + +void RoundingHelperWriterGLSL::writeFloatRoundingHelpers(TInfoSinkBase &sink) +{ // Unoptimized version of angle_frm for single floats: // - // int webgl_maxNormalExponent(in int exponentBits) { + // int webgl_maxNormalExponent(in int exponentBits) + // { // int possibleExponents = int(exp2(float(exponentBits))); // int exponentBias = possibleExponents / 2 - 1; // int allExponentBitsOne = possibleExponents - 1; // return (allExponentBitsOne - 1) - exponentBias; // } // - // float angle_frm(in float x) { + // float angle_frm(in float x) + // { // int mantissaBits = 10; // int exponentBits = 5; // float possibleMantissas = exp2(float(mantissaBits)); // float mantissaMax = 2.0 - 1.0 / possibleMantissas; // int maxNE = webgl_maxNormalExponent(exponentBits); // float max = exp2(float(maxNE)) * mantissaMax; - // if (x > max) { + // if (x > max) + // { // return max; // } - // if (x < -max) { + // if (x < -max) + // { // return -max; // } // float exponent = floor(log2(abs(x))); - // if (abs(x) == 0.0 || exponent < -float(maxNE)) { + // if (abs(x) == 0.0 || exponent < -float(maxNE)) + // { // return 0.0 * sign(x) // } // x = x * exp2(-(exponent - float(mantissaBits))); @@ -109,140 +227,215 @@ static void writeCommonPrecisionEmulationHelpers(TInfoSinkBase& sink, ShShaderOu // numbers will be flushed to zero either way (2^-15 is the smallest // normal positive number), this does not introduce any error. - std::string floatType = "float"; - if (outputLanguage == SH_ESSL_OUTPUT) - floatType = "highp float"; + std::string floatType = getTypeString("float"); + + // clang-format off + sink << + floatType << " angle_frm(in " << floatType << " x) {\n" + " x = clamp(x, -65504.0, 65504.0);\n" + " " << floatType << " exponent = floor(log2(abs(x) + 1e-30)) - 10.0;\n" + " bool isNonZero = (exponent >= -25.0);\n" + " x = x * exp2(-exponent);\n" + " x = sign(x) * floor(abs(x));\n" + " return x * exp2(exponent) * float(isNonZero);\n" + "}\n"; sink << - floatType << " angle_frm(in " << floatType << " x) {\n" - " x = clamp(x, -65504.0, 65504.0);\n" - " " << floatType << " exponent = floor(log2(abs(x) + 1e-30)) - 10.0;\n" - " bool isNonZero = (exponent >= -25.0);\n" - " x = x * exp2(-exponent);\n" - " x = sign(x) * floor(abs(x));\n" - " return x * exp2(exponent) * float(isNonZero);\n" - "}\n"; - - sink << - floatType << " angle_frl(in " << floatType << " x) {\n" - " x = clamp(x, -2.0, 2.0);\n" - " x = x * 256.0;\n" - " x = sign(x) * floor(abs(x));\n" - " return x * 0.00390625;\n" - "}\n"; - - writeVectorPrecisionEmulationHelpers(sink, outputLanguage, 2); - writeVectorPrecisionEmulationHelpers(sink, outputLanguage, 3); - writeVectorPrecisionEmulationHelpers(sink, outputLanguage, 4); - for (unsigned int size = 2; size <= 4; ++size) - { - writeMatrixPrecisionEmulationHelper(sink, outputLanguage, size, "angle_frm"); - writeMatrixPrecisionEmulationHelper(sink, outputLanguage, size, "angle_frl"); - } + floatType << " angle_frl(in " << floatType << " x) {\n" + " x = clamp(x, -2.0, 2.0);\n" + " x = x * 256.0;\n" + " x = sign(x) * floor(abs(x));\n" + " return x * 0.00390625;\n" + "}\n"; + // clang-format on } -static void writeCompoundAssignmentPrecisionEmulation( - TInfoSinkBase& sink, ShShaderOutput outputLanguage, - const char *lType, const char *rType, const char *opStr, const char *opNameStr) +void RoundingHelperWriterGLSL::writeVectorRoundingHelpers(TInfoSinkBase &sink, + const unsigned int size) { - std::string lTypeStr = lType; - std::string rTypeStr = rType; - if (outputLanguage == SH_ESSL_OUTPUT) - { - std::stringstream lTypeStrStr; - lTypeStrStr << "highp " << lType; - lTypeStr = lTypeStrStr.str(); - std::stringstream rTypeStrStr; - rTypeStrStr << "highp " << rType; - rTypeStr = rTypeStrStr.str(); - } + std::stringstream vecTypeStrStr; + vecTypeStrStr << "vec" << size; + std::string vecType = getTypeString(vecTypeStrStr.str().c_str()); - // Note that y should be passed through angle_frm at the function call site, - // but x can't be passed through angle_frm there since it is an inout parameter. - // So only pass x and the result through angle_frm here. + // clang-format off sink << - lTypeStr << " angle_compound_" << opNameStr << "_frm(inout " << lTypeStr << " x, in " << rTypeStr << " y) {\n" - " x = angle_frm(angle_frm(x) " << opStr << " y);\n" - " return x;\n" - "}\n"; + vecType << " angle_frm(in " << vecType << " v) {\n" + " v = clamp(v, -65504.0, 65504.0);\n" + " " << vecType << " exponent = floor(log2(abs(v) + 1e-30)) - 10.0;\n" + " bvec" << size << " isNonZero = greaterThanEqual(exponent, vec" << size << "(-25.0));\n" + " v = v * exp2(-exponent);\n" + " v = sign(v) * floor(abs(v));\n" + " return v * exp2(exponent) * vec" << size << "(isNonZero);\n" + "}\n"; + sink << - lTypeStr << " angle_compound_" << opNameStr << "_frl(inout " << lTypeStr << " x, in " << rTypeStr << " y) {\n" - " x = angle_frl(angle_frm(x) " << opStr << " y);\n" - " return x;\n" - "}\n"; + vecType << " angle_frl(in " << vecType << " v) {\n" + " v = clamp(v, -2.0, 2.0);\n" + " v = v * 256.0;\n" + " v = sign(v) * floor(abs(v));\n" + " return v * 0.00390625;\n" + "}\n"; + // clang-format on } -const char *getFloatTypeStr(const TType& type) +void RoundingHelperWriterGLSL::writeMatrixRoundingHelper(TInfoSinkBase &sink, + const unsigned int columns, + const unsigned int rows, + const char *functionName) { - switch (type.getNominalSize()) + std::stringstream matTypeStrStr; + matTypeStrStr << "mat" << columns; + if (rows != columns) + { + matTypeStrStr << "x" << rows; + } + std::string matType = getTypeString(matTypeStrStr.str().c_str()); + + sink << matType << " " << functionName << "(in " << matType << " m) {\n" + << " " << matType << " rounded;\n"; + + for (unsigned int i = 0; i < columns; ++i) + { + sink << " rounded[" << i << "] = " << functionName << "(m[" << i << "]);\n"; + } + + sink << " return rounded;\n" + "}\n"; +} + +static const char *GetHLSLTypeStr(const char *floatTypeStr) +{ + if (strcmp(floatTypeStr, "float") == 0) { - case 1: return "float"; - case 2: - switch(type.getSecondarySize()) - { - case 1: - return "vec2"; - case 2: - return "mat2"; - case 3: - return "mat2x3"; - case 4: - return "mat2x4"; - default: - UNREACHABLE(); - return NULL; - } - case 3: - switch(type.getSecondarySize()) - { - case 1: - return "vec3"; - case 2: - return "mat3x2"; - case 3: - return "mat3"; - case 4: - return "mat3x4"; - default: - UNREACHABLE(); - return NULL; - } - case 4: - switch(type.getSecondarySize()) - { - case 1: - return "vec4"; - case 2: - return "mat4x2"; - case 3: - return "mat4x3"; - case 4: - return "mat4"; - default: - UNREACHABLE(); - return NULL; - } - default: - UNREACHABLE(); - return NULL; } + if (strcmp(floatTypeStr, "vec2") == 0) + { + return "float2"; + } + if (strcmp(floatTypeStr, "vec3") == 0) + { + return "float3"; + } + if (strcmp(floatTypeStr, "vec4") == 0) + { + return "float4"; + } + if (strcmp(floatTypeStr, "mat2") == 0) + { + return "float2x2"; + } + if (strcmp(floatTypeStr, "mat3") == 0) + { + return "float3x3"; + } + if (strcmp(floatTypeStr, "mat4") == 0) + { + return "float4x4"; + } + if (strcmp(floatTypeStr, "mat2x3") == 0) + { + return "float2x3"; + } + if (strcmp(floatTypeStr, "mat2x4") == 0) + { + return "float2x4"; + } + if (strcmp(floatTypeStr, "mat3x2") == 0) + { + return "float3x2"; + } + if (strcmp(floatTypeStr, "mat3x4") == 0) + { + return "float3x4"; + } + if (strcmp(floatTypeStr, "mat4x2") == 0) + { + return "float4x2"; + } + if (strcmp(floatTypeStr, "mat4x3") == 0) + { + return "float4x3"; + } + UNREACHABLE(); + return nullptr; +} + +std::string RoundingHelperWriterHLSL::getTypeString(const char *glslType) +{ + return GetHLSLTypeStr(glslType); +} + +void RoundingHelperWriterHLSL::writeFloatRoundingHelpers(TInfoSinkBase &sink) +{ + // In HLSL scalars are the same as 1-vectors. + writeVectorRoundingHelpers(sink, 1); +} + +void RoundingHelperWriterHLSL::writeVectorRoundingHelpers(TInfoSinkBase &sink, + const unsigned int size) +{ + std::stringstream vecTypeStrStr; + vecTypeStrStr << "float" << size; + std::string vecType = vecTypeStrStr.str(); + + // clang-format off + sink << + vecType << " angle_frm(" << vecType << " v) {\n" + " v = clamp(v, -65504.0, 65504.0);\n" + " " << vecType << " exponent = floor(log2(abs(v) + 1e-30)) - 10.0;\n" + " bool" << size << " isNonZero = exponent < -25.0;\n" + " v = v * exp2(-exponent);\n" + " v = sign(v) * floor(abs(v));\n" + " return v * exp2(exponent) * (float" << size << ")(isNonZero);\n" + "}\n"; + + sink << + vecType << " angle_frl(" << vecType << " v) {\n" + " v = clamp(v, -2.0, 2.0);\n" + " v = v * 256.0;\n" + " v = sign(v) * floor(abs(v));\n" + " return v * 0.00390625;\n" + "}\n"; + // clang-format on +} + +void RoundingHelperWriterHLSL::writeMatrixRoundingHelper(TInfoSinkBase &sink, + const unsigned int columns, + const unsigned int rows, + const char *functionName) +{ + std::stringstream matTypeStrStr; + matTypeStrStr << "float" << columns << "x" << rows; + std::string matType = matTypeStrStr.str(); + + sink << matType << " " << functionName << "(" << matType << " m) {\n" + << " " << matType << " rounded;\n"; + + for (unsigned int i = 0; i < columns; ++i) + { + sink << " rounded[" << i << "] = " << functionName << "(m[" << i << "]);\n"; + } + + sink << " return rounded;\n" + "}\n"; } bool canRoundFloat(const TType &type) { - return type.getBasicType() == EbtFloat && !type.isNonSquareMatrix() && !type.isArray() && - (type.getPrecision() == EbpLow || type.getPrecision() == EbpMedium); + return type.getBasicType() == EbtFloat && !type.isArray() && + (type.getPrecision() == EbpLow || type.getPrecision() == EbpMedium); } -TIntermAggregate *createInternalFunctionCallNode(TString name, TIntermNode *child) +TIntermAggregate *createInternalFunctionCallNode(const TType &type, + TString name, + TIntermSequence *arguments) { - TIntermAggregate *callNode = new TIntermAggregate(); - callNode->setOp(EOpFunctionCall); - TName nameObj(TFunction::mangleName(name)); + TName nameObj(name); nameObj.setInternal(true); - callNode->setNameObj(nameObj); - callNode->getSequence()->push_back(child); + TIntermAggregate *callNode = + TIntermAggregate::Create(type, EOpCallInternalRawFunction, arguments); + callNode->getFunctionSymbolInfo()->setNameObj(nameObj); return callNode; } @@ -252,63 +445,92 @@ TIntermAggregate *createRoundingFunctionCallNode(TIntermTyped *roundedChild) if (roundedChild->getPrecision() == EbpMedium) roundFunctionName = "angle_frm"; else - roundFunctionName = "angle_frl"; - return createInternalFunctionCallNode(roundFunctionName, roundedChild); + roundFunctionName = "angle_frl"; + TIntermSequence *arguments = new TIntermSequence(); + arguments->push_back(roundedChild); + TIntermAggregate *callNode = + createInternalFunctionCallNode(roundedChild->getType(), roundFunctionName, arguments); + callNode->getFunctionSymbolInfo()->setKnownToNotHaveSideEffects(true); + return callNode; } -TIntermAggregate *createCompoundAssignmentFunctionCallNode(TIntermTyped *left, TIntermTyped *right, const char *opNameStr) +TIntermAggregate *createCompoundAssignmentFunctionCallNode(TIntermTyped *left, + TIntermTyped *right, + const char *opNameStr) { std::stringstream strstr; if (left->getPrecision() == EbpMedium) strstr << "angle_compound_" << opNameStr << "_frm"; else strstr << "angle_compound_" << opNameStr << "_frl"; - TString functionName = strstr.str().c_str(); - TIntermAggregate *callNode = createInternalFunctionCallNode(functionName, left); - callNode->getSequence()->push_back(right); - return callNode; + TString functionName = strstr.str().c_str(); + TIntermSequence *arguments = new TIntermSequence(); + arguments->push_back(left); + arguments->push_back(right); + return createInternalFunctionCallNode(left->getType(), functionName, arguments); } -bool parentUsesResult(TIntermNode* parent, TIntermNode* node) +bool ParentUsesResult(TIntermNode *parent, TIntermTyped *node) { if (!parent) { return false; } - TIntermAggregate *aggParent = parent->getAsAggregate(); - // If the parent's op is EOpSequence, the result is not assigned anywhere, + TIntermBlock *blockParent = parent->getAsBlock(); + // If the parent is a block, the result is not assigned anywhere, // so rounding it is not needed. In particular, this can avoid a lot of // unnecessary rounding of unused return values of assignment. - if (aggParent && aggParent->getOp() == EOpSequence) + if (blockParent) { return false; } - if (aggParent && aggParent->getOp() == EOpComma && (aggParent->getSequence()->back() != node)) + TIntermBinary *binaryParent = parent->getAsBinaryNode(); + if (binaryParent && binaryParent->getOp() == EOpComma && (binaryParent->getRight() != node)) { return false; } return true; } +bool ParentConstructorTakesCareOfRounding(TIntermNode *parent, TIntermTyped *node) +{ + if (!parent) + { + return false; + } + TIntermAggregate *parentConstructor = parent->getAsAggregate(); + if (!parentConstructor || parentConstructor->getOp() != EOpConstruct) + { + return false; + } + if (parentConstructor->getPrecision() != node->getPrecision()) + { + return false; + } + return canRoundFloat(parentConstructor->getType()); +} + } // namespace anonymous -EmulatePrecision::EmulatePrecision(const TSymbolTable &symbolTable, int shaderVersion) +EmulatePrecision::EmulatePrecision(TSymbolTable *symbolTable, int shaderVersion) : TLValueTrackingTraverser(true, true, true, symbolTable, shaderVersion), mDeclaringVariables(false) -{} +{ +} void EmulatePrecision::visitSymbol(TIntermSymbol *node) { - if (canRoundFloat(node->getType()) && !mDeclaringVariables && !isLValueRequiredHere()) + TIntermNode *parent = getParentNode(); + if (canRoundFloat(node->getType()) && ParentUsesResult(parent, node) && + !ParentConstructorTakesCareOfRounding(parent, node) && !mDeclaringVariables && + !isLValueRequiredHere()) { - TIntermNode *parent = getParentNode(); TIntermNode *replacement = createRoundingFunctionCallNode(node); - mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, true)); + queueReplacement(replacement, OriginalNode::BECOMES_CHILD); } } - bool EmulatePrecision::visitBinary(Visit visit, TIntermBinary *node) { bool visitChildren = true; @@ -319,189 +541,211 @@ bool EmulatePrecision::visitBinary(Visit visit, TIntermBinary *node) if (op == EOpInitialize && visit == InVisit) mDeclaringVariables = false; - if ((op == EOpIndexDirectStruct || op == EOpVectorSwizzle) && visit == InVisit) + if ((op == EOpIndexDirectStruct) && visit == InVisit) visitChildren = false; if (visit != PreVisit) return visitChildren; - const TType& type = node->getType(); - bool roundFloat = canRoundFloat(type); + const TType &type = node->getType(); + bool roundFloat = canRoundFloat(type); - if (roundFloat) { - switch (op) { - // Math operators that can result in a float may need to apply rounding to the return - // value. Note that in the case of assignment, the rounding is applied to its return - // value here, not the value being assigned. - case EOpAssign: - case EOpAdd: - case EOpSub: - case EOpMul: - case EOpDiv: - case EOpVectorTimesScalar: - case EOpVectorTimesMatrix: - case EOpMatrixTimesVector: - case EOpMatrixTimesScalar: - case EOpMatrixTimesMatrix: - { - TIntermNode *parent = getParentNode(); - if (!parentUsesResult(parent, node)) + if (roundFloat) + { + switch (op) + { + // Math operators that can result in a float may need to apply rounding to the return + // value. Note that in the case of assignment, the rounding is applied to its return + // value here, not the value being assigned. + case EOpAssign: + case EOpAdd: + case EOpSub: + case EOpMul: + case EOpDiv: + case EOpVectorTimesScalar: + case EOpVectorTimesMatrix: + case EOpMatrixTimesVector: + case EOpMatrixTimesScalar: + case EOpMatrixTimesMatrix: { + TIntermNode *parent = getParentNode(); + if (!ParentUsesResult(parent, node) || + ParentConstructorTakesCareOfRounding(parent, node)) + { + break; + } + TIntermNode *replacement = createRoundingFunctionCallNode(node); + queueReplacement(replacement, OriginalNode::BECOMES_CHILD); break; } - TIntermNode *replacement = createRoundingFunctionCallNode(node); - mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, true)); - break; - } - // Compound assignment cases need to replace the operator with a function call. - case EOpAddAssign: - { - mEmulateCompoundAdd.insert(TypePair(getFloatTypeStr(type), getFloatTypeStr(node->getRight()->getType()))); - TIntermNode *parent = getParentNode(); - TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(node->getLeft(), node->getRight(), "add"); - mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, false)); - break; - } - case EOpSubAssign: - { - mEmulateCompoundSub.insert(TypePair(getFloatTypeStr(type), getFloatTypeStr(node->getRight()->getType()))); - TIntermNode *parent = getParentNode(); - TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(node->getLeft(), node->getRight(), "sub"); - mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, false)); - break; - } - case EOpMulAssign: - case EOpVectorTimesMatrixAssign: - case EOpVectorTimesScalarAssign: - case EOpMatrixTimesScalarAssign: - case EOpMatrixTimesMatrixAssign: - { - mEmulateCompoundMul.insert(TypePair(getFloatTypeStr(type), getFloatTypeStr(node->getRight()->getType()))); - TIntermNode *parent = getParentNode(); - TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(node->getLeft(), node->getRight(), "mul"); - mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, false)); - break; - } - case EOpDivAssign: - { - mEmulateCompoundDiv.insert(TypePair(getFloatTypeStr(type), getFloatTypeStr(node->getRight()->getType()))); - TIntermNode *parent = getParentNode(); - TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(node->getLeft(), node->getRight(), "div"); - mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, false)); - break; - } - default: - // The rest of the binary operations should not need precision emulation. - break; + // Compound assignment cases need to replace the operator with a function call. + case EOpAddAssign: + { + mEmulateCompoundAdd.insert( + TypePair(type.getBuiltInTypeNameString(), + node->getRight()->getType().getBuiltInTypeNameString())); + TIntermNode *replacement = createCompoundAssignmentFunctionCallNode( + node->getLeft(), node->getRight(), "add"); + queueReplacement(replacement, OriginalNode::IS_DROPPED); + break; + } + case EOpSubAssign: + { + mEmulateCompoundSub.insert( + TypePair(type.getBuiltInTypeNameString(), + node->getRight()->getType().getBuiltInTypeNameString())); + TIntermNode *replacement = createCompoundAssignmentFunctionCallNode( + node->getLeft(), node->getRight(), "sub"); + queueReplacement(replacement, OriginalNode::IS_DROPPED); + break; + } + case EOpMulAssign: + case EOpVectorTimesMatrixAssign: + case EOpVectorTimesScalarAssign: + case EOpMatrixTimesScalarAssign: + case EOpMatrixTimesMatrixAssign: + { + mEmulateCompoundMul.insert( + TypePair(type.getBuiltInTypeNameString(), + node->getRight()->getType().getBuiltInTypeNameString())); + TIntermNode *replacement = createCompoundAssignmentFunctionCallNode( + node->getLeft(), node->getRight(), "mul"); + queueReplacement(replacement, OriginalNode::IS_DROPPED); + break; + } + case EOpDivAssign: + { + mEmulateCompoundDiv.insert( + TypePair(type.getBuiltInTypeNameString(), + node->getRight()->getType().getBuiltInTypeNameString())); + TIntermNode *replacement = createCompoundAssignmentFunctionCallNode( + node->getLeft(), node->getRight(), "div"); + queueReplacement(replacement, OriginalNode::IS_DROPPED); + break; + } + default: + // The rest of the binary operations should not need precision emulation. + break; } } return visitChildren; } +bool EmulatePrecision::visitDeclaration(Visit visit, TIntermDeclaration *node) +{ + // Variable or interface block declaration. + if (visit == PreVisit) + { + mDeclaringVariables = true; + } + else if (visit == InVisit) + { + mDeclaringVariables = true; + } + else + { + mDeclaringVariables = false; + } + return true; +} + +bool EmulatePrecision::visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *node) +{ + return false; +} + +bool EmulatePrecision::visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *node) +{ + return false; +} + bool EmulatePrecision::visitAggregate(Visit visit, TIntermAggregate *node) { - bool visitChildren = true; + if (visit != PreVisit) + return true; switch (node->getOp()) { - case EOpSequence: - case EOpConstructStruct: - case EOpFunction: - break; - case EOpPrototype: - visitChildren = false; - break; - case EOpParameters: - visitChildren = false; - break; - case EOpInvariantDeclaration: - visitChildren = false; - break; - case EOpDeclaration: - // Variable declaration. - if (visit == PreVisit) - { - mDeclaringVariables = true; - } - else if (visit == InVisit) - { - mDeclaringVariables = true; - } - else - { - mDeclaringVariables = false; - } - break; - case EOpFunctionCall: - { - // Function call. - if (visit == PreVisit) - { - // User-defined function return values are not rounded, this relies on that - // calculations producing the value were rounded. + case EOpCallInternalRawFunction: + case EOpCallFunctionInAST: + // User-defined function return values are not rounded. The calculations that produced + // the value inside the function definition should have been rounded. + break; + case EOpConstruct: + if (node->getBasicType() == EbtStruct) + { + break; + } + default: TIntermNode *parent = getParentNode(); - if (canRoundFloat(node->getType()) && !isInFunctionMap(node) && - parentUsesResult(parent, node)) + if (canRoundFloat(node->getType()) && ParentUsesResult(parent, node) && + !ParentConstructorTakesCareOfRounding(parent, node)) { TIntermNode *replacement = createRoundingFunctionCallNode(node); - mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, true)); + queueReplacement(replacement, OriginalNode::BECOMES_CHILD); } - } - break; - } - default: - TIntermNode *parent = getParentNode(); - if (canRoundFloat(node->getType()) && visit == PreVisit && parentUsesResult(parent, node)) - { - TIntermNode *replacement = createRoundingFunctionCallNode(node); - mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, true)); - } - break; + break; } - return visitChildren; + return true; } bool EmulatePrecision::visitUnary(Visit visit, TIntermUnary *node) { switch (node->getOp()) { - case EOpNegative: - case EOpVectorLogicalNot: - case EOpLogicalNot: - case EOpPostIncrement: - case EOpPostDecrement: - case EOpPreIncrement: - case EOpPreDecrement: - break; - default: - if (canRoundFloat(node->getType()) && visit == PreVisit) - { - TIntermNode *parent = getParentNode(); - TIntermNode *replacement = createRoundingFunctionCallNode(node); - mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, true)); - } - break; + case EOpNegative: + case EOpLogicalNot: + case EOpPostIncrement: + case EOpPostDecrement: + case EOpPreIncrement: + case EOpPreDecrement: + case EOpLogicalNotComponentWise: + break; + default: + if (canRoundFloat(node->getType()) && visit == PreVisit) + { + TIntermNode *replacement = createRoundingFunctionCallNode(node); + queueReplacement(replacement, OriginalNode::BECOMES_CHILD); + } + break; } return true; } -void EmulatePrecision::writeEmulationHelpers(TInfoSinkBase& sink, ShShaderOutput outputLanguage) +void EmulatePrecision::writeEmulationHelpers(TInfoSinkBase &sink, + const int shaderVersion, + const ShShaderOutput outputLanguage) { - // Other languages not yet supported - ASSERT(outputLanguage == SH_GLSL_COMPATIBILITY_OUTPUT || - IsGLSL130OrNewer(outputLanguage) || - outputLanguage == SH_ESSL_OUTPUT); - writeCommonPrecisionEmulationHelpers(sink, outputLanguage); + std::unique_ptr roundingHelperWriter( + RoundingHelperWriter::createHelperWriter(outputLanguage)); + + roundingHelperWriter->writeCommonRoundingHelpers(sink, shaderVersion); EmulationSet::const_iterator it; for (it = mEmulateCompoundAdd.begin(); it != mEmulateCompoundAdd.end(); it++) - writeCompoundAssignmentPrecisionEmulation(sink, outputLanguage, it->lType, it->rType, "+", "add"); + roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "+", "add"); for (it = mEmulateCompoundSub.begin(); it != mEmulateCompoundSub.end(); it++) - writeCompoundAssignmentPrecisionEmulation(sink, outputLanguage, it->lType, it->rType, "-", "sub"); + roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "-", "sub"); for (it = mEmulateCompoundDiv.begin(); it != mEmulateCompoundDiv.end(); it++) - writeCompoundAssignmentPrecisionEmulation(sink, outputLanguage, it->lType, it->rType, "/", "div"); + roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "/", "div"); for (it = mEmulateCompoundMul.begin(); it != mEmulateCompoundMul.end(); it++) - writeCompoundAssignmentPrecisionEmulation(sink, outputLanguage, it->lType, it->rType, "*", "mul"); + roundingHelperWriter->writeCompoundAssignmentHelper(sink, it->lType, it->rType, "*", "mul"); } +// static +bool EmulatePrecision::SupportedInLanguage(const ShShaderOutput outputLanguage) +{ + switch (outputLanguage) + { + case SH_HLSL_4_1_OUTPUT: + case SH_ESSL_OUTPUT: + return true; + default: + // Other languages not yet supported + return (outputLanguage == SH_GLSL_COMPATIBILITY_OUTPUT || + sh::IsGLSL130OrNewer(outputLanguage)); + } +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/EmulatePrecision.h b/src/3rdparty/angle/src/compiler/translator/EmulatePrecision.h index 08177b3414..8044465410 100644 --- a/src/3rdparty/angle/src/compiler/translator/EmulatePrecision.h +++ b/src/3rdparty/angle/src/compiler/translator/EmulatePrecision.h @@ -7,34 +7,43 @@ #ifndef COMPILER_TRANSLATOR_EMULATE_PRECISION_H_ #define COMPILER_TRANSLATOR_EMULATE_PRECISION_H_ +#include "GLSLANG/ShaderLang.h" #include "common/angleutils.h" #include "compiler/translator/Compiler.h" #include "compiler/translator/InfoSink.h" -#include "compiler/translator/IntermNode.h" -#include "GLSLANG/ShaderLang.h" +#include "compiler/translator/IntermTraverse.h" // This class gathers all compound assignments from the AST and can then write // the functions required for their precision emulation. This way there is no // need to write a huge number of variations of the emulated compound assignment // to every translated shader with emulation enabled. +namespace sh +{ + class EmulatePrecision : public TLValueTrackingTraverser { public: - EmulatePrecision(const TSymbolTable &symbolTable, int shaderVersion); + EmulatePrecision(TSymbolTable *symbolTable, int shaderVersion); void visitSymbol(TIntermSymbol *node) override; bool visitBinary(Visit visit, TIntermBinary *node) override; bool visitUnary(Visit visit, TIntermUnary *node) override; bool visitAggregate(Visit visit, TIntermAggregate *node) override; + bool visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *node) override; + bool visitDeclaration(Visit visit, TIntermDeclaration *node) override; + bool visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *node) override; - void writeEmulationHelpers(TInfoSinkBase& sink, ShShaderOutput outputLanguage); + void writeEmulationHelpers(TInfoSinkBase &sink, + const int shaderVersion, + const ShShaderOutput outputLanguage); + + static bool SupportedInLanguage(const ShShaderOutput outputLanguage); private: struct TypePair { - TypePair(const char *l, const char *r) - : lType(l), rType(r) { } + TypePair(const char *l, const char *r) : lType(l), rType(r) {} const char *lType; const char *rType; @@ -42,7 +51,7 @@ class EmulatePrecision : public TLValueTrackingTraverser struct TypePairComparator { - bool operator() (const TypePair& l, const TypePair& r) const + bool operator()(const TypePair &l, const TypePair &r) const { if (l.lType == r.lType) return l.rType < r.rType; @@ -59,4 +68,6 @@ class EmulatePrecision : public TLValueTrackingTraverser bool mDeclaringVariables; }; +} // namespace sh + #endif // COMPILER_TRANSLATOR_EMULATE_PRECISION_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/ExpandIntegerPowExpressions.cpp b/src/3rdparty/angle/src/compiler/translator/ExpandIntegerPowExpressions.cpp new file mode 100644 index 0000000000..f17dd73657 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/ExpandIntegerPowExpressions.cpp @@ -0,0 +1,153 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Implementation of the integer pow expressions HLSL bug workaround. +// See header for more info. + +#include "compiler/translator/ExpandIntegerPowExpressions.h" + +#include +#include + +#include "compiler/translator/IntermTraverse.h" + +namespace sh +{ + +namespace +{ + +class Traverser : public TIntermTraverser +{ + public: + static void Apply(TIntermNode *root, TSymbolTable *symbolTable); + + private: + Traverser(TSymbolTable *symbolTable); + bool visitAggregate(Visit visit, TIntermAggregate *node) override; + void nextIteration(); + + bool mFound = false; +}; + +// static +void Traverser::Apply(TIntermNode *root, TSymbolTable *symbolTable) +{ + Traverser traverser(symbolTable); + do + { + traverser.nextIteration(); + root->traverse(&traverser); + if (traverser.mFound) + { + traverser.updateTree(); + } + } while (traverser.mFound); +} + +Traverser::Traverser(TSymbolTable *symbolTable) : TIntermTraverser(true, false, false, symbolTable) +{ +} + +void Traverser::nextIteration() +{ + mFound = false; + nextTemporaryId(); +} + +bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node) +{ + if (mFound) + { + return false; + } + + // Test 0: skip non-pow operators. + if (node->getOp() != EOpPow) + { + return true; + } + + const TIntermSequence *sequence = node->getSequence(); + ASSERT(sequence->size() == 2u); + const TIntermConstantUnion *constantNode = sequence->at(1)->getAsConstantUnion(); + + // Test 1: check for a single constant. + if (!constantNode || constantNode->getNominalSize() != 1) + { + return true; + } + + const TConstantUnion *constant = constantNode->getUnionArrayPointer(); + + TConstantUnion asFloat; + asFloat.cast(EbtFloat, *constant); + + float value = asFloat.getFConst(); + + // Test 2: value is in the problematic range. + if (value < -5.0f || value > 9.0f) + { + return true; + } + + // Test 3: value is integer or pretty close to an integer. + float absval = std::abs(value); + float frac = absval - std::round(absval); + if (frac > 0.0001f) + { + return true; + } + + // Test 4: skip -1, 0, and 1 + int exponent = static_cast(value); + int n = std::abs(exponent); + if (n < 2) + { + return true; + } + + // Potential problem case detected, apply workaround. + nextTemporaryId(); + + TIntermTyped *lhs = sequence->at(0)->getAsTyped(); + ASSERT(lhs); + + TIntermDeclaration *init = createTempInitDeclaration(lhs); + TIntermTyped *current = createTempSymbol(lhs->getType()); + + insertStatementInParentBlock(init); + + // Create a chain of n-1 multiples. + for (int i = 1; i < n; ++i) + { + TIntermBinary *mul = new TIntermBinary(EOpMul, current, createTempSymbol(lhs->getType())); + mul->setLine(node->getLine()); + current = mul; + } + + // For negative pow, compute the reciprocal of the positive pow. + if (exponent < 0) + { + TConstantUnion *oneVal = new TConstantUnion(); + oneVal->setFConst(1.0f); + TIntermConstantUnion *oneNode = new TIntermConstantUnion(oneVal, node->getType()); + TIntermBinary *div = new TIntermBinary(EOpDiv, oneNode, current); + current = div; + } + + queueReplacement(current, OriginalNode::IS_DROPPED); + mFound = true; + return false; +} + +} // anonymous namespace + +void ExpandIntegerPowExpressions(TIntermNode *root, TSymbolTable *symbolTable) +{ + Traverser::Apply(root, symbolTable); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/ExpandIntegerPowExpressions.h b/src/3rdparty/angle/src/compiler/translator/ExpandIntegerPowExpressions.h new file mode 100644 index 0000000000..0074e5d663 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/ExpandIntegerPowExpressions.h @@ -0,0 +1,29 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// This mutating tree traversal works around a bug in the HLSL compiler optimizer with "pow" that +// manifests under the following conditions: +// +// - If pow() has a literal exponent value +// - ... and this value is integer or within 10e-6 of an integer +// - ... and it is in {-4, -3, -2, 2, 3, 4, 5, 6, 7, 8} +// +// The workaround is to replace the pow with a series of multiplies. +// See http://anglebug.com/851 + +#ifndef COMPILER_TRANSLATOR_EXPANDINTEGERPOWEXPRESSIONS_H_ +#define COMPILER_TRANSLATOR_EXPANDINTEGERPOWEXPRESSIONS_H_ + +namespace sh +{ + +class TIntermNode; +class TSymbolTable; + +void ExpandIntegerPowExpressions(TIntermNode *root, TSymbolTable *symbolTable); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_EXPANDINTEGERPOWEXPRESSIONS_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/ExtensionBehavior.cpp b/src/3rdparty/angle/src/compiler/translator/ExtensionBehavior.cpp new file mode 100644 index 0000000000..3f910b9050 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/ExtensionBehavior.cpp @@ -0,0 +1,96 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ExtensionBehavior.cpp: Extension name enumeration and data structures for storing extension +// behavior. + +#include "compiler/translator/ExtensionBehavior.h" + +#include "common/debug.h" + +#include + +#define LIST_EXTENSIONS(OP) \ + OP(ARB_texture_rectangle) \ + OP(ARM_shader_framebuffer_fetch) \ + OP(EXT_blend_func_extended) \ + OP(EXT_draw_buffers) \ + OP(EXT_frag_depth) \ + OP(EXT_geometry_shader) \ + OP(EXT_shader_framebuffer_fetch) \ + OP(EXT_shader_texture_lod) \ + OP(EXT_YUV_target) \ + OP(NV_EGL_stream_consumer_external) \ + OP(NV_shader_framebuffer_fetch) \ + OP(OES_EGL_image_external) \ + OP(OES_EGL_image_external_essl3) \ + OP(OES_geometry_shader) \ + OP(OES_standard_derivatives) \ + OP(OVR_multiview) + +namespace sh +{ + +#define RETURN_EXTENSION_NAME_CASE(ext) \ + case TExtension::ext: \ + return "GL_" #ext; + +const char *GetExtensionNameString(TExtension extension) +{ + switch (extension) + { + LIST_EXTENSIONS(RETURN_EXTENSION_NAME_CASE) + default: + UNREACHABLE(); + return ""; + } +} + +#define RETURN_EXTENSION_IF_NAME_MATCHES(ext) \ + if (strcmp(extWithoutGLPrefix, #ext) == 0) \ + { \ + return TExtension::ext; \ + } + +TExtension GetExtensionByName(const char *extension) +{ + // If first characters of the extension don't equal "GL_", early out. + if (strncmp(extension, "GL_", 3) != 0) + { + return TExtension::UNDEFINED; + } + const char *extWithoutGLPrefix = extension + 3; + + LIST_EXTENSIONS(RETURN_EXTENSION_IF_NAME_MATCHES) + + return TExtension::UNDEFINED; +} + +const char *GetBehaviorString(TBehavior b) +{ + switch (b) + { + case EBhRequire: + return "require"; + case EBhEnable: + return "enable"; + case EBhWarn: + return "warn"; + case EBhDisable: + return "disable"; + default: + return nullptr; + } +} + +bool IsExtensionEnabled(const TExtensionBehavior &extBehavior, TExtension extension) +{ + ASSERT(extension != TExtension::UNDEFINED); + auto iter = extBehavior.find(extension); + return iter != extBehavior.end() && + (iter->second == EBhEnable || iter->second == EBhRequire || iter->second == EBhWarn); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/ExtensionBehavior.h b/src/3rdparty/angle/src/compiler/translator/ExtensionBehavior.h index 782c1c9217..09cc03f10f 100644 --- a/src/3rdparty/angle/src/compiler/translator/ExtensionBehavior.h +++ b/src/3rdparty/angle/src/compiler/translator/ExtensionBehavior.h @@ -3,41 +3,58 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // +// ExtensionBehavior.h: Extension name enumeration and data structures for storing extension +// behavior. #ifndef COMPILER_TRANSLATOR_EXTENSIONBEHAVIOR_H_ #define COMPILER_TRANSLATOR_EXTENSIONBEHAVIOR_H_ #include -#include -typedef enum +namespace sh +{ + +enum class TExtension +{ + UNDEFINED, // Special value used to indicate no extension. + + ARB_texture_rectangle, + ARM_shader_framebuffer_fetch, + EXT_blend_func_extended, + EXT_draw_buffers, + EXT_frag_depth, + EXT_geometry_shader, + EXT_shader_framebuffer_fetch, + EXT_shader_texture_lod, + EXT_YUV_target, + NV_EGL_stream_consumer_external, + NV_shader_framebuffer_fetch, + OES_EGL_image_external, + OES_EGL_image_external_essl3, + OES_geometry_shader, + OES_standard_derivatives, + OVR_multiview +}; + +enum TBehavior { EBhRequire, EBhEnable, EBhWarn, EBhDisable, EBhUndefined -} TBehavior; +}; -inline const char* getBehaviorString(TBehavior b) -{ - switch(b) - { - case EBhRequire: return "require"; - case EBhEnable: return "enable"; - case EBhWarn: return "warn"; - case EBhDisable: return "disable"; - default: return NULL; - } -} +const char *GetExtensionNameString(TExtension extension); +TExtension GetExtensionByName(const char *extension); -// Mapping between extension name and behavior. -typedef std::map TExtensionBehavior; +const char *GetBehaviorString(TBehavior b); -inline bool IsExtensionEnabled(const TExtensionBehavior &extBehavior, const char *extension) -{ - auto iter = extBehavior.find(extension); - return iter != extBehavior.end() && (iter->second == EBhEnable || iter->second == EBhRequire); -} +// Mapping between extension id and behavior. +typedef std::map TExtensionBehavior; -#endif // COMPILER_TRANSLATOR_EXTENSIONBEHAVIOR_H_ +bool IsExtensionEnabled(const TExtensionBehavior &extBehavior, TExtension extension); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_EXTENSIONBEHAVIOR_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/ExtensionGLSL.cpp b/src/3rdparty/angle/src/compiler/translator/ExtensionGLSL.cpp index d7f45f7eef..5b5dc580e9 100644 --- a/src/3rdparty/angle/src/compiler/translator/ExtensionGLSL.cpp +++ b/src/3rdparty/angle/src/compiler/translator/ExtensionGLSL.cpp @@ -10,6 +10,9 @@ #include "compiler/translator/VersionGLSL.h" +namespace sh +{ + TExtensionGLSL::TExtensionGLSL(ShShaderOutput output) : TIntermTraverser(true, false, false), mTargetVersion(ShaderOutputTypeToGLSLVersion(output)) { @@ -98,3 +101,5 @@ void TExtensionGLSL::checkOperator(TIntermOperator *node) break; } } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/ExtensionGLSL.h b/src/3rdparty/angle/src/compiler/translator/ExtensionGLSL.h index 6bb84d612d..a1b9cb2225 100644 --- a/src/3rdparty/angle/src/compiler/translator/ExtensionGLSL.h +++ b/src/3rdparty/angle/src/compiler/translator/ExtensionGLSL.h @@ -12,7 +12,10 @@ #include #include -#include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermTraverse.h" + +namespace sh +{ // Traverses the intermediate tree to determine which GLSL extensions are required // to support the shader. @@ -36,4 +39,6 @@ class TExtensionGLSL : public TIntermTraverser std::set mRequiredExtensions; }; +} // namespace sh + #endif // COMPILER_TRANSLATOR_EXTENSIONGLSL_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/FindMain.cpp b/src/3rdparty/angle/src/compiler/translator/FindMain.cpp new file mode 100644 index 0000000000..7417fbac8a --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/FindMain.cpp @@ -0,0 +1,38 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// FindMain.cpp: Find the main() function definition in a given AST. + +#include "compiler/translator/FindMain.h" + +#include "compiler/translator/IntermNode.h" + +namespace sh +{ + +TIntermFunctionDefinition *FindMain(TIntermBlock *root) +{ + for (TIntermNode *node : *root->getSequence()) + { + TIntermFunctionDefinition *nodeFunction = node->getAsFunctionDefinition(); + if (nodeFunction != nullptr && nodeFunction->getFunctionSymbolInfo()->isMain()) + { + return nodeFunction; + } + } + return nullptr; +} + +TIntermBlock *FindMainBody(TIntermBlock *root) +{ + TIntermFunctionDefinition *main = FindMain(root); + ASSERT(main != nullptr); + TIntermBlock *mainBody = main->getBody(); + ASSERT(mainBody != nullptr); + return mainBody; +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/FindMain.h b/src/3rdparty/angle/src/compiler/translator/FindMain.h new file mode 100644 index 0000000000..bf2c45d871 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/FindMain.h @@ -0,0 +1,23 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// FindMain.h: Adds functions to get the main function definition and its body. + +#ifndef COMPILER_TRANSLATOR_FINDMAIN_H_ +#define COMPILER_TRANSLATOR_FINDMAIN_H_ + +namespace sh +{ + +class TIntermBlock; +class TIntermFunctionDefinition; + +TIntermFunctionDefinition *FindMain(TIntermBlock *root); +TIntermBlock *FindMainBody(TIntermBlock *root); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_FINDMAIN_H_ \ No newline at end of file diff --git a/src/3rdparty/angle/src/compiler/translator/FindSymbolNode.cpp b/src/3rdparty/angle/src/compiler/translator/FindSymbolNode.cpp new file mode 100644 index 0000000000..a2a10f128d --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/FindSymbolNode.cpp @@ -0,0 +1,58 @@ +// +// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// FindSymbol.cpp: +// Utility for finding a symbol node inside an AST tree. + +#include "compiler/translator/FindSymbolNode.h" + +#include "compiler/translator/IntermTraverse.h" + +namespace sh +{ + +namespace +{ + +class SymbolFinder : public TIntermTraverser +{ + public: + SymbolFinder(const TString &symbolName, TBasicType basicType) + : TIntermTraverser(true, false, false), + mSymbolName(symbolName), + mNodeFound(nullptr), + mBasicType(basicType) + { + } + + void visitSymbol(TIntermSymbol *node) + { + if (node->getBasicType() == mBasicType && node->getSymbol() == mSymbolName) + { + mNodeFound = node; + } + } + + bool isFound() const { return mNodeFound != nullptr; } + const TIntermSymbol *getNode() const { return mNodeFound; } + + private: + TString mSymbolName; + TIntermSymbol *mNodeFound; + TBasicType mBasicType; +}; + +} // anonymous namespace + +const TIntermSymbol *FindSymbolNode(TIntermNode *root, + const TString &symbolName, + TBasicType basicType) +{ + SymbolFinder finder(symbolName, basicType); + root->traverse(&finder); + return finder.getNode(); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/FindSymbolNode.h b/src/3rdparty/angle/src/compiler/translator/FindSymbolNode.h new file mode 100644 index 0000000000..08dfb9a222 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/FindSymbolNode.h @@ -0,0 +1,27 @@ +// +// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// FindSymbolNode.h: +// Utility for finding a symbol node inside an AST tree. + +#ifndef COMPILER_TRANSLATOR_FIND_SYMBOL_H_ +#define COMPILER_TRANSLATOR_FIND_SYMBOL_H_ + +#include "compiler/translator/BaseTypes.h" +#include "compiler/translator/Common.h" + +namespace sh +{ + +class TIntermNode; +class TIntermSymbol; + +const TIntermSymbol *FindSymbolNode(TIntermNode *root, + const TString &symbolName, + TBasicType basicType); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_FIND_SYMBOL_H_ \ No newline at end of file diff --git a/src/3rdparty/angle/src/compiler/translator/FlagStd140Structs.cpp b/src/3rdparty/angle/src/compiler/translator/FlagStd140Structs.cpp index a751b768b7..fba837f55c 100644 --- a/src/3rdparty/angle/src/compiler/translator/FlagStd140Structs.cpp +++ b/src/3rdparty/angle/src/compiler/translator/FlagStd140Structs.cpp @@ -3,75 +3,73 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // +// FlagStd140Structs.cpp: Find structs in std140 blocks, where the padding added in the translator +// conflicts with the "natural" unpadded type. #include "compiler/translator/FlagStd140Structs.h" +#include "compiler/translator/IntermTraverse.h" + namespace sh { -bool FlagStd140Structs::visitBinary(Visit visit, TIntermBinary *binaryNode) +namespace { - if (binaryNode->getRight()->getBasicType() == EbtStruct) + +class FlagStd140StructsTraverser : public TIntermTraverser +{ + public: + FlagStd140StructsTraverser() : TIntermTraverser(true, false, false) {} + + const std::vector getMappedStructs() const { return mMappedStructs; } + + protected: + bool visitDeclaration(Visit visit, TIntermDeclaration *node) override; + + private: + void mapBlockStructMembers(TIntermSymbol *blockDeclarator, TInterfaceBlock *block); + + std::vector mMappedStructs; +}; + +void FlagStd140StructsTraverser::mapBlockStructMembers(TIntermSymbol *blockDeclarator, + TInterfaceBlock *block) +{ + for (auto *field : block->fields()) { - switch (binaryNode->getOp()) + if (field->type()->getBasicType() == EbtStruct) { - case EOpIndexDirectInterfaceBlock: - case EOpIndexDirectStruct: - if (isInStd140InterfaceBlock(binaryNode->getLeft())) - { - mFlaggedNodes.push_back(binaryNode); - } - break; - - default: break; + MappedStruct mappedStruct; + mappedStruct.blockDeclarator = blockDeclarator; + mappedStruct.field = field; + mMappedStructs.push_back(mappedStruct); } - return false; - } - - if (binaryNode->getOp() == EOpIndexDirectStruct) - { - return false; - } - - return visit == PreVisit; -} - -void FlagStd140Structs::visitSymbol(TIntermSymbol *symbol) -{ - if (isInStd140InterfaceBlock(symbol) && symbol->getBasicType() == EbtStruct) - { - mFlaggedNodes.push_back(symbol); } } -bool FlagStd140Structs::isInStd140InterfaceBlock(TIntermTyped *node) const +bool FlagStd140StructsTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node) { - TIntermBinary *binaryNode = node->getAsBinaryNode(); - - if (binaryNode) + TIntermTyped *declarator = node->getSequence()->back()->getAsTyped(); + if (declarator->getBasicType() == EbtInterfaceBlock) { - return isInStd140InterfaceBlock(binaryNode->getLeft()); + TInterfaceBlock *block = declarator->getType().getInterfaceBlock(); + if (block->blockStorage() == EbsStd140) + { + mapBlockStructMembers(declarator->getAsSymbolNode(), block); + } } - - const TType &type = node->getType(); - - // determine if we are in the standard layout - const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock(); - if (interfaceBlock) - { - return (interfaceBlock->blockStorage() == EbsStd140); - } - return false; } -std::vector FlagStd140ValueStructs(TIntermNode *node) +} // anonymous namespace + +std::vector FlagStd140Structs(TIntermNode *node) { - FlagStd140Structs flaggingTraversal; + FlagStd140StructsTraverser flaggingTraversal; node->traverse(&flaggingTraversal); - return flaggingTraversal.getFlaggedNodes(); + return flaggingTraversal.getMappedStructs(); } -} +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/FlagStd140Structs.h b/src/3rdparty/angle/src/compiler/translator/FlagStd140Structs.h index cfcd775af7..f548d8b6ed 100644 --- a/src/3rdparty/angle/src/compiler/translator/FlagStd140Structs.h +++ b/src/3rdparty/angle/src/compiler/translator/FlagStd140Structs.h @@ -3,41 +3,28 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // +// FlagStd140Structs.h: Find structs in std140 blocks, where the padding added in the translator +// conflicts with the "natural" unpadded type. #ifndef COMPILER_TRANSLATOR_FLAGSTD140STRUCTS_H_ #define COMPILER_TRANSLATOR_FLAGSTD140STRUCTS_H_ -#include "compiler/translator/IntermNode.h" +#include namespace sh { -// This class finds references to nested structs of std140 blocks that access -// the nested struct "by value", where the padding added in the translator -// conflicts with the "natural" unpadded type. -class FlagStd140Structs : public TIntermTraverser +class TField; +class TIntermNode; +class TIntermSymbol; + +struct MappedStruct { - public: - - FlagStd140Structs() - : TIntermTraverser(true, false, false) - { - } - - const std::vector getFlaggedNodes() const { return mFlaggedNodes; } - - protected: - bool visitBinary(Visit visit, TIntermBinary *binaryNode) override; - void visitSymbol(TIntermSymbol *symbol) override; - - private: - bool isInStd140InterfaceBlock(TIntermTyped *node) const; - - std::vector mFlaggedNodes; + TIntermSymbol *blockDeclarator; + TField *field; }; -std::vector FlagStd140ValueStructs(TIntermNode *node); - +std::vector FlagStd140Structs(TIntermNode *node); } -#endif // COMPILER_TRANSLATOR_FLAGSTD140STRUCTS_H_ +#endif // COMPILER_TRANSLATOR_FLAGSTD140STRUCTS_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/ForLoopUnroll.cpp b/src/3rdparty/angle/src/compiler/translator/ForLoopUnroll.cpp deleted file mode 100644 index 4cc1c26a13..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/ForLoopUnroll.cpp +++ /dev/null @@ -1,97 +0,0 @@ -// -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/translator/ForLoopUnroll.h" - -#include "compiler/translator/ValidateLimitations.h" -#include "angle_gl.h" - -bool ForLoopUnrollMarker::visitBinary(Visit, TIntermBinary *node) -{ - if (mUnrollCondition != kSamplerArrayIndex) - return true; - - // If a sampler array index is also the loop index, - // 1) if the index type is integer, mark the loop for unrolling; - // 2) if the index type if float, set a flag to later fail compile. - switch (node->getOp()) - { - case EOpIndexIndirect: - if (node->getLeft() != NULL && node->getRight() != NULL && node->getLeft()->getAsSymbolNode()) - { - TIntermSymbol *symbol = node->getLeft()->getAsSymbolNode(); - if (IsSampler(symbol->getBasicType()) && symbol->isArray() && !mLoopStack.empty()) - { - mVisitSamplerArrayIndexNodeInsideLoop = true; - node->getRight()->traverse(this); - mVisitSamplerArrayIndexNodeInsideLoop = false; - // We have already visited all the children. - return false; - } - } - break; - default: - break; - } - return true; -} - -bool ForLoopUnrollMarker::visitLoop(Visit, TIntermLoop *node) -{ - bool canBeUnrolled = mHasRunLoopValidation; - if (!mHasRunLoopValidation) - { - canBeUnrolled = ValidateLimitations::IsLimitedForLoop(node); - } - if (mUnrollCondition == kIntegerIndex && canBeUnrolled) - { - // Check if loop index type is integer. - // This is called after ValidateLimitations pass, so the loop has the limited form specified - // in ESSL 1.00 appendix A. - TIntermSequence *declSeq = node->getInit()->getAsAggregate()->getSequence(); - TIntermSymbol *symbol = (*declSeq)[0]->getAsBinaryNode()->getLeft()->getAsSymbolNode(); - if (symbol->getBasicType() == EbtInt) - node->setUnrollFlag(true); - } - - TIntermNode *body = node->getBody(); - if (body != nullptr) - { - if (canBeUnrolled) - { - mLoopStack.push(node); - body->traverse(this); - mLoopStack.pop(); - } - else - { - body->traverse(this); - } - } - // The loop is fully processed - no need to visit children. - return false; -} - -void ForLoopUnrollMarker::visitSymbol(TIntermSymbol* symbol) -{ - if (!mVisitSamplerArrayIndexNodeInsideLoop) - return; - TIntermLoop *loop = mLoopStack.findLoop(symbol); - if (loop) - { - switch (symbol->getBasicType()) - { - case EbtFloat: - mSamplerArrayIndexIsFloatLoopIndex = true; - break; - case EbtInt: - loop->setUnrollFlag(true); - break; - default: - UNREACHABLE(); - } - } -} diff --git a/src/3rdparty/angle/src/compiler/translator/ForLoopUnroll.h b/src/3rdparty/angle/src/compiler/translator/ForLoopUnroll.h deleted file mode 100644 index 9c49ecad33..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/ForLoopUnroll.h +++ /dev/null @@ -1,53 +0,0 @@ -// -// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_TRANSLATOR_FORLOOPUNROLL_H_ -#define COMPILER_TRANSLATOR_FORLOOPUNROLL_H_ - -#include "compiler/translator/LoopInfo.h" - -// This class detects for-loops that needs to be unrolled. -// Currently we support two unroll conditions: -// 1) kForLoopWithIntegerIndex: unroll if the index type is integer. -// 2) kForLoopWithSamplerArrayIndex: unroll where a sampler array index -// is also the loop integer index, and reject and fail a compile -// where a sampler array index is also the loop float index. -class ForLoopUnrollMarker : public TIntermTraverser -{ - public: - enum UnrollCondition - { - kIntegerIndex, - kSamplerArrayIndex - }; - - ForLoopUnrollMarker(UnrollCondition condition, bool hasRunLoopValidation) - : TIntermTraverser(true, false, false), - mUnrollCondition(condition), - mSamplerArrayIndexIsFloatLoopIndex(false), - mVisitSamplerArrayIndexNodeInsideLoop(false), - mHasRunLoopValidation(hasRunLoopValidation) - { - } - - bool visitBinary(Visit, TIntermBinary *node) override; - bool visitLoop(Visit, TIntermLoop *node) override; - void visitSymbol(TIntermSymbol *node) override; - - bool samplerArrayIndexIsFloatLoopIndex() const - { - return mSamplerArrayIndexIsFloatLoopIndex; - } - - private: - UnrollCondition mUnrollCondition; - TLoopStack mLoopStack; - bool mSamplerArrayIndexIsFloatLoopIndex; - bool mVisitSamplerArrayIndexNodeInsideLoop; - bool mHasRunLoopValidation; -}; - -#endif // COMPILER_TRANSLATOR_FORLOOPUNROLL_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/HashNames.cpp b/src/3rdparty/angle/src/compiler/translator/HashNames.cpp new file mode 100644 index 0000000000..6bc90faf94 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/HashNames.cpp @@ -0,0 +1,72 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/translator/HashNames.h" + +#include "compiler/translator/IntermNode.h" + +namespace sh +{ + +namespace +{ + +// GLSL ES 3.00.6 section 3.9: the maximum length of an identifier is 1024 characters. +static const unsigned int kESSLMaxIdentifierLength = 1024u; + +static const char *kHashedNamePrefix = "webgl_"; + +// Can't prefix with just _ because then we might introduce a double underscore, which is not safe +// in GLSL (ESSL 3.00.6 section 3.8: All identifiers containing a double underscore are reserved for +// use by the underlying implementation). u is short for user-defined. +static const char *kUnhashedNamePrefix = "_u"; +static const unsigned int kUnhashedNamePrefixLength = 2u; + +TString HashName(const TString &name, ShHashFunction64 hashFunction) +{ + ASSERT(!name.empty()); + ASSERT(hashFunction); + khronos_uint64_t number = (*hashFunction)(name.c_str(), name.length()); + TStringStream stream; + stream << kHashedNamePrefix << std::hex << number; + TString hashedName = stream.str(); + return hashedName; +} + +} // anonymous namespace + +TString HashName(const TName &name, ShHashFunction64 hashFunction, NameMap *nameMap) +{ + if (name.getString().empty() || name.isInternal()) + { + return name.getString(); + } + if (hashFunction == nullptr) + { + if (name.getString().length() + kUnhashedNamePrefixLength > kESSLMaxIdentifierLength) + { + // If the identifier length is already close to the limit, we can't prefix it. This is + // not a problem since there are no builtins or ANGLE's internal variables that would + // have as long names and could conflict. + return name.getString(); + } + return kUnhashedNamePrefix + name.getString(); + } + if (nameMap) + { + NameMap::const_iterator it = nameMap->find(name.getString().c_str()); + if (it != nameMap->end()) + return it->second.c_str(); + } + TString hashedName = HashName(name.getString(), hashFunction); + if (nameMap) + { + (*nameMap)[name.getString().c_str()] = hashedName.c_str(); + } + return hashedName; +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/HashNames.h b/src/3rdparty/angle/src/compiler/translator/HashNames.h index 09c959f9da..28e861b309 100644 --- a/src/3rdparty/angle/src/compiler/translator/HashNames.h +++ b/src/3rdparty/angle/src/compiler/translator/HashNames.h @@ -9,10 +9,20 @@ #include -#include "compiler/translator/IntermNode.h" +#include "GLSLANG/ShaderLang.h" +#include "compiler/translator/Common.h" -#define HASHED_NAME_PREFIX "webgl_" +namespace sh +{ typedef std::map NameMap; +class TName; + +// Hash user-defined name for GLSL output, with special handling for internal names. +// The nameMap parameter is optional and is used to cache hashed names if set. +TString HashName(const TName &name, ShHashFunction64 hashFunction, NameMap *nameMap); + +} // namespace sh + #endif // COMPILER_TRANSLATOR_HASHNAMES_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/ImageFunctionHLSL.cpp b/src/3rdparty/angle/src/compiler/translator/ImageFunctionHLSL.cpp new file mode 100644 index 0000000000..40b5e1f1e2 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/ImageFunctionHLSL.cpp @@ -0,0 +1,304 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ImageFunctionHLSL: Class for writing implementations of ESSL image functions into HLSL output. +// + +#include "compiler/translator/ImageFunctionHLSL.h" +#include "compiler/translator/UtilsHLSL.h" + +namespace sh +{ + +// static +void ImageFunctionHLSL::OutputImageFunctionArgumentList( + TInfoSinkBase &out, + const ImageFunctionHLSL::ImageFunction &imageFunction) +{ + if (imageFunction.readonly) + { + out << TextureString(imageFunction.image, imageFunction.imageInternalFormat) << " tex"; + } + else + { + out << RWTextureString(imageFunction.image, imageFunction.imageInternalFormat) << " tex"; + } + + if (imageFunction.method == ImageFunctionHLSL::ImageFunction::Method::LOAD || + imageFunction.method == ImageFunctionHLSL::ImageFunction::Method::STORE) + { + switch (imageFunction.image) + { + case EbtImage2D: + case EbtIImage2D: + case EbtUImage2D: + out << ", int2 p"; + break; + case EbtImage3D: + case EbtIImage3D: + case EbtUImage3D: + case EbtImageCube: + case EbtIImageCube: + case EbtUImageCube: + case EbtImage2DArray: + case EbtIImage2DArray: + case EbtUImage2DArray: + out << ", int3 p"; + break; + default: + UNREACHABLE(); + } + + if (imageFunction.method == ImageFunctionHLSL::ImageFunction::Method::STORE) + { + switch (imageFunction.image) + { + case EbtImage2D: + case EbtImage3D: + case EbtImageCube: + case EbtImage2DArray: + out << ", float4 data"; + break; + case EbtIImage2D: + case EbtIImage3D: + case EbtIImageCube: + case EbtIImage2DArray: + out << ", int4 data"; + break; + case EbtUImage2D: + case EbtUImage3D: + case EbtUImageCube: + case EbtUImage2DArray: + out << ", uint4 data"; + break; + default: + UNREACHABLE(); + } + } + } +} + +// static +void ImageFunctionHLSL::OutputImageSizeFunctionBody( + TInfoSinkBase &out, + const ImageFunctionHLSL::ImageFunction &imageFunction, + const TString &imageReference) +{ + if (IsImage3D(imageFunction.image) || IsImage2DArray(imageFunction.image) || + IsImageCube(imageFunction.image)) + { + // "depth" stores either the number of layers in an array texture or 3D depth + out << " uint width; uint height; uint depth;\n" + << " " << imageReference << ".GetDimensions(width, height, depth);\n"; + } + else if (IsImage2D(imageFunction.image)) + { + out << " uint width; uint height;\n" + << " " << imageReference << ".GetDimensions(width, height);\n"; + } + else + UNREACHABLE(); + + if (strcmp(imageFunction.getReturnType(), "int3") == 0) + { + out << " return int3(width, height, depth);\n"; + } + else + { + out << " return int2(width, height);\n"; + } +} + +// static +void ImageFunctionHLSL::OutputImageLoadFunctionBody( + TInfoSinkBase &out, + const ImageFunctionHLSL::ImageFunction &imageFunction, + const TString &imageReference) +{ + if (IsImage3D(imageFunction.image) || IsImage2DArray(imageFunction.image) || + IsImageCube(imageFunction.image)) + { + out << " return " << imageReference << "[uint3(p.x, p.y, p.z)];\n"; + } + else if (IsImage2D(imageFunction.image)) + { + out << " return " << imageReference << "[uint2(p.x, p.y)];\n"; + } + else + UNREACHABLE(); +} + +// static +void ImageFunctionHLSL::OutputImageStoreFunctionBody( + TInfoSinkBase &out, + const ImageFunctionHLSL::ImageFunction &imageFunction, + const TString &imageReference) +{ + if (IsImage3D(imageFunction.image) || IsImage2DArray(imageFunction.image) || + IsImage2D(imageFunction.image) || IsImageCube(imageFunction.image)) + { + out << " " << imageReference << "[p] = data;\n"; + } + else + UNREACHABLE(); +} + +TString ImageFunctionHLSL::ImageFunction::name() const +{ + TString name = "gl_image"; + if (readonly) + { + name += TextureTypeSuffix(image, imageInternalFormat); + } + else + { + name += RWTextureTypeSuffix(image, imageInternalFormat); + } + + switch (method) + { + case Method::SIZE: + name += "Size"; + break; + case Method::LOAD: + name += "Load"; + break; + case Method::STORE: + name += "Store"; + break; + default: + UNREACHABLE(); + } + + return name; +} + +const char *ImageFunctionHLSL::ImageFunction::getReturnType() const +{ + if (method == ImageFunction::Method::SIZE) + { + switch (image) + { + case EbtImage2D: + case EbtIImage2D: + case EbtUImage2D: + case EbtImageCube: + case EbtIImageCube: + case EbtUImageCube: + return "int2"; + case EbtImage3D: + case EbtIImage3D: + case EbtUImage3D: + case EbtImage2DArray: + case EbtIImage2DArray: + case EbtUImage2DArray: + return "int3"; + default: + UNREACHABLE(); + } + } + else if (method == ImageFunction::Method::LOAD) + { + switch (image) + { + case EbtImage2D: + case EbtImage3D: + case EbtImageCube: + case EbtImage2DArray: + return "float4"; + case EbtIImage2D: + case EbtIImage3D: + case EbtIImageCube: + case EbtIImage2DArray: + return "int4"; + case EbtUImage2D: + case EbtUImage3D: + case EbtUImageCube: + case EbtUImage2DArray: + return "uint4"; + default: + UNREACHABLE(); + } + } + else if (method == ImageFunction::Method::STORE) + { + return "void"; + } + else + { + UNREACHABLE(); + } + return ""; +} + +bool ImageFunctionHLSL::ImageFunction::operator<(const ImageFunction &rhs) const +{ + return std::tie(image, imageInternalFormat, readonly, method) < + std::tie(rhs.image, rhs.imageInternalFormat, rhs.readonly, rhs.method); +} + +TString ImageFunctionHLSL::useImageFunction(const TString &name, + const TBasicType &type, + TLayoutImageInternalFormat imageInternalFormat, + bool readonly) +{ + ASSERT(IsImage(type)); + ImageFunction imageFunction; + imageFunction.image = type; + imageFunction.imageInternalFormat = imageInternalFormat; + imageFunction.readonly = readonly; + + if (name == "imageSize") + { + imageFunction.method = ImageFunction::Method::SIZE; + } + else if (name == "imageLoad") + { + imageFunction.method = ImageFunction::Method::LOAD; + } + else if (name == "imageStore") + { + imageFunction.method = ImageFunction::Method::STORE; + } + else + UNREACHABLE(); + + mUsesImage.insert(imageFunction); + return imageFunction.name(); +} + +void ImageFunctionHLSL::imageFunctionHeader(TInfoSinkBase &out) +{ + for (const ImageFunction &imageFunction : mUsesImage) + { + // Function header + out << imageFunction.getReturnType() << " " << imageFunction.name() << "("; + + OutputImageFunctionArgumentList(out, imageFunction); + + out << ")\n" + "{\n"; + + TString imageReference("tex"); + + if (imageFunction.method == ImageFunction::Method::SIZE) + { + OutputImageSizeFunctionBody(out, imageFunction, imageReference); + } + else if (imageFunction.method == ImageFunction::Method::LOAD) + { + OutputImageLoadFunctionBody(out, imageFunction, imageReference); + } + else + { + OutputImageStoreFunctionBody(out, imageFunction, imageReference); + } + + out << "}\n" + "\n"; + } +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/ImageFunctionHLSL.h b/src/3rdparty/angle/src/compiler/translator/ImageFunctionHLSL.h new file mode 100644 index 0000000000..9db17a6bbf --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/ImageFunctionHLSL.h @@ -0,0 +1,76 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ImageFunctionHLSL: Class for writing implementations of ESSL image functions into HLSL output. +// + +#ifndef COMPILER_TRANSLATOR_IMAGEFUNCTIONHLSL_H_ +#define COMPILER_TRANSLATOR_IMAGEFUNCTIONHLSL_H_ + +#include + +#include "GLSLANG/ShaderLang.h" +#include "compiler/translator/BaseTypes.h" +#include "compiler/translator/Common.h" +#include "compiler/translator/InfoSink.h" +#include "compiler/translator/Types.h" + +namespace sh +{ + +class ImageFunctionHLSL final : angle::NonCopyable +{ + public: + // Returns the name of the image function implementation to caller. + // The name that's passed in is the name of the GLSL image function that it should implement. + TString useImageFunction(const TString &name, + const TBasicType &type, + TLayoutImageInternalFormat imageInternalFormat, + bool readonly); + + void imageFunctionHeader(TInfoSinkBase &out); + + private: + struct ImageFunction + { + // See ESSL 3.10.4 section 8.12 for reference about what the different methods below do. + enum class Method + { + SIZE, + LOAD, + STORE + }; + + TString name() const; + + bool operator<(const ImageFunction &rhs) const; + + const char *getReturnType() const; + + TBasicType image; + TLayoutImageInternalFormat imageInternalFormat; + bool readonly; + Method method; + }; + + static void OutputImageFunctionArgumentList( + TInfoSinkBase &out, + const ImageFunctionHLSL::ImageFunction &imageFunction); + static void OutputImageSizeFunctionBody(TInfoSinkBase &out, + const ImageFunctionHLSL::ImageFunction &imageFunction, + const TString &imageReference); + static void OutputImageLoadFunctionBody(TInfoSinkBase &out, + const ImageFunctionHLSL::ImageFunction &imageFunction, + const TString &imageReference); + static void OutputImageStoreFunctionBody(TInfoSinkBase &out, + const ImageFunctionHLSL::ImageFunction &imageFunction, + const TString &imageReference); + using ImageFunctionSet = std::set; + ImageFunctionSet mUsesImage; +}; + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_IMAGEFUNCTIONHLSL_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/InfoSink.cpp b/src/3rdparty/angle/src/compiler/translator/InfoSink.cpp index cd59658ff7..db26aa67e8 100644 --- a/src/3rdparty/angle/src/compiler/translator/InfoSink.cpp +++ b/src/3rdparty/angle/src/compiler/translator/InfoSink.cpp @@ -6,32 +6,27 @@ #include "compiler/translator/InfoSink.h" -void TInfoSinkBase::prefix(TPrefixType p) { - switch(p) { - case EPrefixNone: - break; - case EPrefixWarning: +namespace sh +{ + +void TInfoSinkBase::prefix(Severity severity) +{ + switch (severity) + { + case SH_WARNING: sink.append("WARNING: "); break; - case EPrefixError: + case SH_ERROR: sink.append("ERROR: "); break; - case EPrefixInternalError: - sink.append("INTERNAL ERROR: "); - break; - case EPrefixUnimplemented: - sink.append("UNIMPLEMENTED: "); - break; - case EPrefixNote: - sink.append("NOTE: "); - break; default: sink.append("UNKOWN ERROR: "); break; } } -void TInfoSinkBase::location(int file, int line) { +void TInfoSinkBase::location(int file, int line) +{ TPersistStringStream stream; if (line) stream << file << ":" << line; @@ -42,13 +37,4 @@ void TInfoSinkBase::location(int file, int line) { sink.append(stream.str()); } -void TInfoSinkBase::location(const TSourceLoc& loc) { - location(loc.first_file, loc.first_line); -} - -void TInfoSinkBase::message(TPrefixType p, const TSourceLoc& loc, const char* m) { - prefix(p); - location(loc); - sink.append(m); - sink.append("\n"); -} +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/InfoSink.h b/src/3rdparty/angle/src/compiler/translator/InfoSink.h index f47fafa8ee..2705f48d59 100644 --- a/src/3rdparty/angle/src/compiler/translator/InfoSink.h +++ b/src/3rdparty/angle/src/compiler/translator/InfoSink.h @@ -10,38 +10,32 @@ #include #include #include "compiler/translator/Common.h" +#include "compiler/translator/Severity.h" + +namespace sh +{ // Returns the fractional part of the given floating-point number. -inline float fractionalPart(float f) { - float intPart = 0.0f; - return modff(f, &intPart); +inline float fractionalPart(float f) +{ + float intPart = 0.0f; + return modff(f, &intPart); } -// -// TPrefixType is used to centralize how info log messages start. -// See below. -// -enum TPrefixType { - EPrefixNone, - EPrefixWarning, - EPrefixError, - EPrefixInternalError, - EPrefixUnimplemented, - EPrefixNote -}; - // // Encapsulate info logs for all objects that have them. // // The methods are a general set of tools for getting a variety of // messages and types inserted into the log. // -class TInfoSinkBase { -public: +class TInfoSinkBase +{ + public: TInfoSinkBase() {} template - TInfoSinkBase& operator<<(const T& t) { + TInfoSinkBase &operator<<(const T &t) + { TPersistStringStream stream; stream << t; sink.append(stream.str()); @@ -49,33 +43,41 @@ public: } // Override << operator for specific types. It is faster to append strings // and characters directly to the sink. - TInfoSinkBase& operator<<(char c) { + TInfoSinkBase &operator<<(char c) + { sink.append(1, c); return *this; } - TInfoSinkBase& operator<<(const char* str) { + TInfoSinkBase &operator<<(const char *str) + { sink.append(str); return *this; } - TInfoSinkBase& operator<<(const TPersistString& str) { + TInfoSinkBase &operator<<(const TPersistString &str) + { sink.append(str); return *this; } - TInfoSinkBase& operator<<(const TString& str) { + TInfoSinkBase &operator<<(const TString &str) + { sink.append(str.c_str()); return *this; } // Make sure floats are written with correct precision. - TInfoSinkBase& operator<<(float f) { + TInfoSinkBase &operator<<(float f) + { // Make sure that at least one decimal point is written. If a number // does not have a fractional part, the default precision format does // not write the decimal portion which gets interpreted as integer by // the compiler. TPersistStringStream stream; - if (fractionalPart(f) == 0.0f) { + if (fractionalPart(f) == 0.0f) + { stream.precision(1); stream << std::showpoint << std::fixed << f; - } else { + } + else + { stream.unsetf(std::ios::fixed); stream.unsetf(std::ios::scientific); stream.precision(8); @@ -85,8 +87,9 @@ public: return *this; } // Write boolean values as their names instead of integral value. - TInfoSinkBase& operator<<(bool b) { - const char* str = b ? "true" : "false"; + TInfoSinkBase &operator<<(bool b) + { + const char *str = b ? "true" : "false"; sink.append(str); return *this; } @@ -94,23 +97,24 @@ public: void erase() { sink.clear(); } int size() { return static_cast(sink.size()); } - const TPersistString& str() const { return sink; } - const char* c_str() const { return sink.c_str(); } + const TPersistString &str() const { return sink; } + const char *c_str() const { return sink.c_str(); } - void prefix(TPrefixType p); + void prefix(Severity severity); void location(int file, int line); - void location(const TSourceLoc& loc); - void message(TPrefixType p, const TSourceLoc& loc, const char* m); -private: + private: TPersistString sink; }; -class TInfoSink { -public: +class TInfoSink +{ + public: TInfoSinkBase info; TInfoSinkBase debug; TInfoSinkBase obj; }; -#endif // COMPILER_TRANSLATOR_INFOSINK_H_ +} // namespace sh + +#endif // COMPILER_TRANSLATOR_INFOSINK_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/Initialize.cpp b/src/3rdparty/angle/src/compiler/translator/Initialize.cpp index 2f51aada7f..6f8baee96b 100644 --- a/src/3rdparty/angle/src/compiler/translator/Initialize.cpp +++ b/src/3rdparty/angle/src/compiler/translator/Initialize.cpp @@ -6,7 +6,7 @@ // // Create symbols that declare built-in definitions, add built-ins that -// cannot be expressed in the files, and establish mappings between +// cannot be expressed in the files, and establish mappings between // built-in functions and operators. // @@ -16,18 +16,25 @@ #include "compiler/translator/IntermNode.h" #include "angle_gl.h" -void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInResources &resources, TSymbolTable &symbolTable) +namespace sh { - const TType *float1 = TCache::getType(EbtFloat); - const TType *float2 = TCache::getType(EbtFloat, 2); - const TType *float3 = TCache::getType(EbtFloat, 3); - const TType *float4 = TCache::getType(EbtFloat, 4); - const TType *int1 = TCache::getType(EbtInt); - const TType *int2 = TCache::getType(EbtInt, 2); - const TType *int3 = TCache::getType(EbtInt, 3); - const TType *uint1 = TCache::getType(EbtUInt); - const TType *bool1 = TCache::getType(EbtBool); - const TType *genType = TCache::getType(EbtGenType); + +void InsertBuiltInFunctions(sh::GLenum type, + ShShaderSpec spec, + const ShBuiltInResources &resources, + TSymbolTable &symbolTable) +{ + const TType *voidType = TCache::getType(EbtVoid); + const TType *float1 = TCache::getType(EbtFloat); + const TType *float2 = TCache::getType(EbtFloat, 2); + const TType *float3 = TCache::getType(EbtFloat, 3); + const TType *float4 = TCache::getType(EbtFloat, 4); + const TType *int1 = TCache::getType(EbtInt); + const TType *int2 = TCache::getType(EbtInt, 2); + const TType *int3 = TCache::getType(EbtInt, 3); + const TType *uint1 = TCache::getType(EbtUInt); + const TType *bool1 = TCache::getType(EbtBool); + const TType *genType = TCache::getType(EbtGenType); const TType *genIType = TCache::getType(EbtGenIType); const TType *genUType = TCache::getType(EbtGenUType); const TType *genBType = TCache::getType(EbtGenBType); @@ -35,113 +42,117 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR // // Angle and Trigonometric Functions. // - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpRadians, genType, "radians", genType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpDegrees, genType, "degrees", genType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSin, genType, "sin", genType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpCos, genType, "cos", genType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpTan, genType, "tan", genType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAsin, genType, "asin", genType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAcos, genType, "acos", genType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAtan, genType, "atan", genType, genType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAtan, genType, "atan", genType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpSinh, genType, "sinh", genType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpCosh, genType, "cosh", genType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTanh, genType, "tanh", genType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpAsinh, genType, "asinh", genType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpAcosh, genType, "acosh", genType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpAtanh, genType, "atanh", genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpRadians, genType, genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpDegrees, genType, genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpSin, genType, genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpCos, genType, genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpTan, genType, genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpAsin, genType, genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpAcos, genType, genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpAtan, genType, genType, genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpAtan, genType, genType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpSinh, genType, genType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpCosh, genType, genType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpTanh, genType, genType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpAsinh, genType, genType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpAcosh, genType, genType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpAtanh, genType, genType); // // Exponential Functions. // - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpPow, genType, "pow", genType, genType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpExp, genType, "exp", genType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLog, genType, "log", genType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpExp2, genType, "exp2", genType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLog2, genType, "log2", genType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSqrt, genType, "sqrt", genType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpInverseSqrt, genType, "inversesqrt", genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpPow, genType, genType, genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpExp, genType, genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpLog, genType, genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpExp2, genType, genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpLog2, genType, genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpSqrt, genType, genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpInverseSqrt, genType, genType); // // Common Functions. // - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAbs, genType, "abs", genType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpAbs, genIType, "abs", genIType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSign, genType, "sign", genType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpSign, genIType, "sign", genIType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpFloor, genType, "floor", genType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTrunc, genType, "trunc", genType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpRound, genType, "round", genType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpRoundEven, genType, "roundEven", genType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpCeil, genType, "ceil", genType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpFract, genType, "fract", genType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMod, genType, "mod", genType, float1); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMod, genType, "mod", genType, genType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMin, genType, "min", genType, float1); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMin, genType, "min", genType, genType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMin, genIType, "min", genIType, genIType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMin, genIType, "min", genIType, int1); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMin, genUType, "min", genUType, genUType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMin, genUType, "min", genUType, uint1); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMax, genType, "max", genType, float1); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMax, genType, "max", genType, genType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMax, genIType, "max", genIType, genIType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMax, genIType, "max", genIType, int1); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMax, genUType, "max", genUType, genUType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMax, genUType, "max", genUType, uint1); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpClamp, genType, "clamp", genType, float1, float1); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpClamp, genType, "clamp", genType, genType, genType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpClamp, genIType, "clamp", genIType, int1, int1); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpClamp, genIType, "clamp", genIType, genIType, genIType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpClamp, genUType, "clamp", genUType, uint1, uint1); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpClamp, genUType, "clamp", genUType, genUType, genUType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMix, genType, "mix", genType, genType, float1); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMix, genType, "mix", genType, genType, genType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMix, genType, "mix", genType, genType, genBType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpStep, genType, "step", genType, genType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpStep, genType, "step", float1, genType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSmoothStep, genType, "smoothstep", genType, genType, genType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpSmoothStep, genType, "smoothstep", float1, float1, genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpAbs, genType, genType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpAbs, genIType, genIType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpSign, genType, genType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpSign, genIType, genIType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpFloor, genType, genType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpTrunc, genType, genType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpRound, genType, genType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpRoundEven, genType, genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpCeil, genType, genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpFract, genType, genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpMod, genType, genType, float1); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpMod, genType, genType, genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpMin, genType, genType, float1); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpMin, genType, genType, genType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMin, genIType, genIType, genIType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMin, genIType, genIType, int1); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMin, genUType, genUType, genUType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMin, genUType, genUType, uint1); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpMax, genType, genType, float1); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpMax, genType, genType, genType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMax, genIType, genIType, genIType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMax, genIType, genIType, int1); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMax, genUType, genUType, genUType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMax, genUType, genUType, uint1); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpClamp, genType, genType, float1, float1); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpClamp, genType, genType, genType, genType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpClamp, genIType, genIType, int1, int1); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpClamp, genIType, genIType, genIType, genIType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpClamp, genUType, genUType, uint1, uint1); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpClamp, genUType, genUType, genUType, genUType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpMix, genType, genType, genType, float1); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpMix, genType, genType, genType, genType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMix, genType, genType, genType, genBType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpStep, genType, genType, genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpStep, genType, float1, genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpSmoothStep, genType, genType, genType, genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpSmoothStep, genType, float1, float1, genType); - const TType *outFloat1 = TCache::getType(EbtFloat, EvqOut); - const TType *outFloat2 = TCache::getType(EbtFloat, EvqOut, 2); - const TType *outFloat3 = TCache::getType(EbtFloat, EvqOut, 3); - const TType *outFloat4 = TCache::getType(EbtFloat, EvqOut, 4); + const TType *outGenType = TCache::getType(EbtGenType, EvqOut); + const TType *outGenIType = TCache::getType(EbtGenIType, EvqOut); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpModf, float1, "modf", float1, outFloat1); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpModf, float2, "modf", float2, outFloat2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpModf, float3, "modf", float3, outFloat3); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpModf, float4, "modf", float4, outFloat4); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpModf, genType, genType, outGenType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpIsNan, genBType, "isnan", genType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpIsInf, genBType, "isinf", genType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpFloatBitsToInt, genIType, "floatBitsToInt", genType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpFloatBitsToUint, genUType, "floatBitsToUint", genType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpIntBitsToFloat, genType, "intBitsToFloat", genIType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpUintBitsToFloat, genType, "uintBitsToFloat", genUType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpIsNan, genBType, genType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpIsInf, genBType, genType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpFloatBitsToInt, genIType, genType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpFloatBitsToUint, genUType, genType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpIntBitsToFloat, genType, genIType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpUintBitsToFloat, genType, genUType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpPackSnorm2x16, uint1, "packSnorm2x16", float2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpPackUnorm2x16, uint1, "packUnorm2x16", float2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpPackHalf2x16, uint1, "packHalf2x16", float2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpUnpackSnorm2x16, float2, "unpackSnorm2x16", uint1); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpUnpackUnorm2x16, float2, "unpackUnorm2x16", uint1); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpUnpackHalf2x16, float2, "unpackHalf2x16", uint1); + symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpFrexp, genType, genType, outGenIType); + symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpLdexp, genType, genType, genIType); + + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpPackSnorm2x16, uint1, float2); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpPackUnorm2x16, uint1, float2); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpPackHalf2x16, uint1, float2); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpUnpackSnorm2x16, float2, uint1); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpUnpackUnorm2x16, float2, uint1); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpUnpackHalf2x16, float2, uint1); + + symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpPackUnorm4x8, uint1, float4); + symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpPackSnorm4x8, uint1, float4); + symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpUnpackUnorm4x8, float4, uint1); + symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpUnpackSnorm4x8, float4, uint1); // // Geometric Functions. // - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLength, float1, "length", genType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpDistance, float1, "distance", genType, genType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpDot, float1, "dot", genType, genType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpCross, float3, "cross", float3, float3); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpNormalize, genType, "normalize", genType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpFaceForward, genType, "faceforward", genType, genType, genType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpReflect, genType, "reflect", genType, genType); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpRefract, genType, "refract", genType, genType, float1); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpLength, float1, genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpDistance, float1, genType, genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpDot, float1, genType, genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpCross, float3, float3, float3); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpNormalize, genType, genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpFaceforward, genType, genType, genType, + genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpReflect, genType, genType, genType); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpRefract, genType, genType, genType, float1); - const TType *mat2 = TCache::getType(EbtFloat, 2, 2); - const TType *mat3 = TCache::getType(EbtFloat, 3, 3); - const TType *mat4 = TCache::getType(EbtFloat, 4, 4); + const TType *mat2 = TCache::getType(EbtFloat, 2, 2); + const TType *mat3 = TCache::getType(EbtFloat, 3, 3); + const TType *mat4 = TCache::getType(EbtFloat, 4, 4); const TType *mat2x3 = TCache::getType(EbtFloat, 2, 3); const TType *mat3x2 = TCache::getType(EbtFloat, 3, 2); const TType *mat2x4 = TCache::getType(EbtFloat, 2, 4); @@ -152,45 +163,45 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR // // Matrix Functions. // - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMul, mat2, "matrixCompMult", mat2, mat2); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMul, mat3, "matrixCompMult", mat3, mat3); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpMul, mat4, "matrixCompMult", mat4, mat4); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat2x3, "matrixCompMult", mat2x3, mat2x3); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat3x2, "matrixCompMult", mat3x2, mat3x2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat2x4, "matrixCompMult", mat2x4, mat2x4); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat4x2, "matrixCompMult", mat4x2, mat4x2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat3x4, "matrixCompMult", mat3x4, mat3x4); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpMul, mat4x3, "matrixCompMult", mat4x3, mat4x3); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpMulMatrixComponentWise, mat2, mat2, mat2); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpMulMatrixComponentWise, mat3, mat3, mat3); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpMulMatrixComponentWise, mat4, mat4, mat4); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat2x3, mat2x3, mat2x3); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat3x2, mat3x2, mat3x2); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat2x4, mat2x4, mat2x4); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat4x2, mat4x2, mat4x2); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat3x4, mat3x4, mat3x4); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpMulMatrixComponentWise, mat4x3, mat4x3, mat4x3); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat2, "outerProduct", float2, float2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat3, "outerProduct", float3, float3); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat4, "outerProduct", float4, float4); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat2x3, "outerProduct", float3, float2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat3x2, "outerProduct", float2, float3); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat2x4, "outerProduct", float4, float2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat4x2, "outerProduct", float2, float4); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat3x4, "outerProduct", float4, float3); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpOuterProduct, mat4x3, "outerProduct", float3, float4); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat2, float2, float2); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat3, float3, float3); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat4, float4, float4); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat2x3, float3, float2); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat3x2, float2, float3); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat2x4, float4, float2); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat4x2, float2, float4); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat3x4, float4, float3); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpOuterProduct, mat4x3, float3, float4); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat2, "transpose", mat2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat3, "transpose", mat3); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat4, "transpose", mat4); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat2x3, "transpose", mat3x2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat3x2, "transpose", mat2x3); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat2x4, "transpose", mat4x2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat4x2, "transpose", mat2x4); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat3x4, "transpose", mat4x3); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpTranspose, mat4x3, "transpose", mat3x4); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat2, mat2); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat3, mat3); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat4, mat4); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat2x3, mat3x2); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat3x2, mat2x3); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat2x4, mat4x2); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat4x2, mat2x4); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat3x4, mat4x3); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpTranspose, mat4x3, mat3x4); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpDeterminant, float1, "determinant", mat2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpDeterminant, float1, "determinant", mat3); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpDeterminant, float1, "determinant", mat4); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpDeterminant, float1, mat2); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpDeterminant, float1, mat3); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpDeterminant, float1, mat4); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpInverse, mat2, "inverse", mat2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpInverse, mat3, "inverse", mat3); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpInverse, mat4, "inverse", mat4); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpInverse, mat2, mat2); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpInverse, mat3, mat3); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpInverse, mat4, mat4); - const TType *vec = TCache::getType(EbtVec); + const TType *vec = TCache::getType(EbtVec); const TType *ivec = TCache::getType(EbtIVec); const TType *uvec = TCache::getType(EbtUVec); const TType *bvec = TCache::getType(EbtBVec); @@ -198,31 +209,62 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR // // Vector relational functions. // - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLessThan, bvec, "lessThan", vec, vec); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLessThan, bvec, "lessThan", ivec, ivec); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpLessThan, bvec, "lessThan", uvec, uvec); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLessThanEqual, bvec, "lessThanEqual", vec, vec); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpLessThanEqual, bvec, "lessThanEqual", ivec, ivec); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpLessThanEqual, bvec, "lessThanEqual", uvec, uvec); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpGreaterThan, bvec, "greaterThan", vec, vec); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpGreaterThan, bvec, "greaterThan", ivec, ivec); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpGreaterThan, bvec, "greaterThan", uvec, uvec); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpGreaterThanEqual, bvec, "greaterThanEqual", vec, vec); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpGreaterThanEqual, bvec, "greaterThanEqual", ivec, ivec); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpGreaterThanEqual, bvec, "greaterThanEqual", uvec, uvec); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorEqual, bvec, "equal", vec, vec); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorEqual, bvec, "equal", ivec, ivec); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpVectorEqual, bvec, "equal", uvec, uvec); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorEqual, bvec, "equal", bvec, bvec); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorNotEqual, bvec, "notEqual", vec, vec); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorNotEqual, bvec, "notEqual", ivec, ivec); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpVectorNotEqual, bvec, "notEqual", uvec, uvec); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorNotEqual, bvec, "notEqual", bvec, bvec); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAny, bool1, "any", bvec); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpAll, bool1, "all", bvec); - symbolTable.insertBuiltIn(COMMON_BUILTINS, EOpVectorLogicalNot, bvec, "not", bvec); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpLessThanComponentWise, bvec, vec, vec); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpLessThanComponentWise, bvec, ivec, ivec); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpLessThanComponentWise, bvec, uvec, uvec); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpLessThanEqualComponentWise, bvec, vec, vec); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpLessThanEqualComponentWise, bvec, ivec, ivec); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpLessThanEqualComponentWise, bvec, uvec, uvec); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpGreaterThanComponentWise, bvec, vec, vec); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpGreaterThanComponentWise, bvec, ivec, ivec); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpGreaterThanComponentWise, bvec, uvec, uvec); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpGreaterThanEqualComponentWise, bvec, vec, vec); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpGreaterThanEqualComponentWise, bvec, ivec, + ivec); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpGreaterThanEqualComponentWise, bvec, uvec, uvec); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpEqualComponentWise, bvec, vec, vec); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpEqualComponentWise, bvec, ivec, ivec); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpEqualComponentWise, bvec, uvec, uvec); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpEqualComponentWise, bvec, bvec, bvec); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpNotEqualComponentWise, bvec, vec, vec); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpNotEqualComponentWise, bvec, ivec, ivec); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpNotEqualComponentWise, bvec, uvec, uvec); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpNotEqualComponentWise, bvec, bvec, bvec); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpAny, bool1, bvec); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpAll, bool1, bvec); + symbolTable.insertBuiltInOp(COMMON_BUILTINS, EOpLogicalNotComponentWise, bvec, bvec); - const TType *sampler2D = TCache::getType(EbtSampler2D); + // + // Integer functions + // + const TType *outGenUType = TCache::getType(EbtGenUType, EvqOut); + + symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldExtract, genIType, genIType, int1, + int1); + symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldExtract, genUType, genUType, int1, + int1); + symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldInsert, genIType, genIType, genIType, + int1, int1); + symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldInsert, genUType, genUType, genUType, + int1, int1); + symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldReverse, genIType, genIType); + symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitfieldReverse, genUType, genUType); + symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitCount, genIType, genIType); + symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpBitCount, genIType, genUType); + symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpFindLSB, genIType, genIType); + symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpFindLSB, genIType, genUType); + symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpFindMSB, genIType, genIType); + symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpFindMSB, genIType, genUType); + symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpUaddCarry, genUType, genUType, genUType, + outGenUType); + symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpUsubBorrow, genUType, genUType, genUType, + outGenUType); + symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpUmulExtended, voidType, genUType, genUType, + outGenUType, outGenUType); + symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpImulExtended, voidType, genIType, genIType, + outGenIType, outGenIType); + + const TType *sampler2D = TCache::getType(EbtSampler2D); const TType *samplerCube = TCache::getType(EbtSamplerCube); // @@ -233,13 +275,15 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float4); symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "textureCube", samplerCube, float3); - if (resources.OES_EGL_image_external) + if (resources.OES_EGL_image_external || resources.NV_EGL_stream_consumer_external) { const TType *samplerExternalOES = TCache::getType(EbtSamplerExternalOES); symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", samplerExternalOES, float2); - symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", samplerExternalOES, float3); - symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", samplerExternalOES, float4); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", samplerExternalOES, + float3); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", samplerExternalOES, + float4); } if (resources.ARB_texture_rectangle) @@ -247,8 +291,10 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR const TType *sampler2DRect = TCache::getType(EbtSampler2DRect); symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DRect", sampler2DRect, float2); - symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DRectProj", sampler2DRect, float3); - symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DRectProj", sampler2DRect, float4); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DRectProj", sampler2DRect, + float3); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DRectProj", sampler2DRect, + float4); } if (resources.EXT_shader_texture_lod) @@ -256,49 +302,68 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR /* The *Grad* variants are new to both vertex and fragment shaders; the fragment * shader specific pieces are added separately below. */ - symbolTable.insertBuiltIn(ESSL1_BUILTINS, "GL_EXT_shader_texture_lod", float4, "texture2DGradEXT", sampler2D, float2, float2, float2); - symbolTable.insertBuiltIn(ESSL1_BUILTINS, "GL_EXT_shader_texture_lod", float4, "texture2DProjGradEXT", sampler2D, float3, float2, float2); - symbolTable.insertBuiltIn(ESSL1_BUILTINS, "GL_EXT_shader_texture_lod", float4, "texture2DProjGradEXT", sampler2D, float4, float2, float2); - symbolTable.insertBuiltIn(ESSL1_BUILTINS, "GL_EXT_shader_texture_lod", float4, "textureCubeGradEXT", samplerCube, float3, float3, float3); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4, + "texture2DGradEXT", sampler2D, float2, float2, float2); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4, + "texture2DProjGradEXT", sampler2D, float3, float2, float2); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4, + "texture2DProjGradEXT", sampler2D, float4, float2, float2); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4, + "textureCubeGradEXT", samplerCube, float3, float3, float3); } if (type == GL_FRAGMENT_SHADER) { symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2D", sampler2D, float2, float1); - symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float3, float1); - symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float4, float1); - symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "textureCube", samplerCube, float3, float1); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float3, + float1); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProj", sampler2D, float4, + float1); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "textureCube", samplerCube, float3, + float1); if (resources.OES_standard_derivatives) { - symbolTable.insertBuiltIn(ESSL1_BUILTINS, EOpDFdx, "GL_OES_standard_derivatives", genType, "dFdx", genType); - symbolTable.insertBuiltIn(ESSL1_BUILTINS, EOpDFdy, "GL_OES_standard_derivatives", genType, "dFdy", genType); - symbolTable.insertBuiltIn(ESSL1_BUILTINS, EOpFwidth, "GL_OES_standard_derivatives", genType, "fwidth", genType); + symbolTable.insertBuiltInOp(ESSL1_BUILTINS, EOpDFdx, + TExtension::OES_standard_derivatives, genType, genType); + symbolTable.insertBuiltInOp(ESSL1_BUILTINS, EOpDFdy, + TExtension::OES_standard_derivatives, genType, genType); + symbolTable.insertBuiltInOp(ESSL1_BUILTINS, EOpFwidth, + TExtension::OES_standard_derivatives, genType, genType); } if (resources.EXT_shader_texture_lod) { - symbolTable.insertBuiltIn(ESSL1_BUILTINS, "GL_EXT_shader_texture_lod", float4, "texture2DLodEXT", sampler2D, float2, float1); - symbolTable.insertBuiltIn(ESSL1_BUILTINS, "GL_EXT_shader_texture_lod", float4, "texture2DProjLodEXT", sampler2D, float3, float1); - symbolTable.insertBuiltIn(ESSL1_BUILTINS, "GL_EXT_shader_texture_lod", float4, "texture2DProjLodEXT", sampler2D, float4, float1); - symbolTable.insertBuiltIn(ESSL1_BUILTINS, "GL_EXT_shader_texture_lod", float4, "textureCubeLodEXT", samplerCube, float3, float1); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4, + "texture2DLodEXT", sampler2D, float2, float1); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4, + "texture2DProjLodEXT", sampler2D, float3, float1); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4, + "texture2DProjLodEXT", sampler2D, float4, float1); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, TExtension::EXT_shader_texture_lod, float4, + "textureCubeLodEXT", samplerCube, float3, float1); } } if (type == GL_VERTEX_SHADER) { - symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DLod", sampler2D, float2, float1); - symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjLod", sampler2D, float3, float1); - symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjLod", sampler2D, float4, float1); - symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "textureCubeLod", samplerCube, float3, float1); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DLod", sampler2D, float2, + float1); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjLod", sampler2D, float3, + float1); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "texture2DProjLod", sampler2D, float4, + float1); + symbolTable.insertBuiltIn(ESSL1_BUILTINS, float4, "textureCubeLod", samplerCube, float3, + float1); } const TType *gvec4 = TCache::getType(EbtGVec4); - const TType *gsampler2D = TCache::getType(EbtGSampler2D); - const TType *gsamplerCube = TCache::getType(EbtGSamplerCube); - const TType *gsampler3D = TCache::getType(EbtGSampler3D); + const TType *gsampler2D = TCache::getType(EbtGSampler2D); + const TType *gsamplerCube = TCache::getType(EbtGSamplerCube); + const TType *gsampler3D = TCache::getType(EbtGSampler3D); const TType *gsampler2DArray = TCache::getType(EbtGSampler2DArray); + const TType *gsampler2DMS = TCache::getType(EbtGSampler2DMS); // // Texture Functions for GLSL ES 3.0 @@ -315,32 +380,91 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsamplerCube, float3, float1); symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler2DArray, float3, float1); + if (resources.OES_EGL_image_external_essl3) + { + const TType *samplerExternalOES = TCache::getType(EbtSamplerExternalOES); + + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "texture", samplerExternalOES, float2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES, + float3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES, + float4); + } + + if (resources.EXT_YUV_target) + { + const TType *samplerExternal2DY2YEXT = TCache::getType(EbtSamplerExternal2DY2YEXT); + + symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "texture", + samplerExternal2DY2YEXT, float2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "textureProj", + samplerExternal2DY2YEXT, float3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "textureProj", + samplerExternal2DY2YEXT, float4); + + const TType *yuvCscStandardEXT = TCache::getType(EbtYuvCscStandardEXT); + + symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float3, "rgb_2_yuv", + float3, yuvCscStandardEXT); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float3, "yuv_2_rgb", + float3, yuvCscStandardEXT); + } + if (type == GL_FRAGMENT_SHADER) { symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2D, float2, float1); symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler3D, float3, float1); symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsamplerCube, float3, float1); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2DArray, float3, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2DArray, float3, + float1); symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float3, float1); symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float4, float1); symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler3D, float4, float1); + + if (resources.OES_EGL_image_external_essl3) + { + const TType *samplerExternalOES = TCache::getType(EbtSamplerExternalOES); + + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "texture", samplerExternalOES, float2, + float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES, + float3, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES, + float4, float1); + } + + if (resources.EXT_YUV_target) + { + const TType *samplerExternal2DY2YEXT = TCache::getType(EbtSamplerExternal2DY2YEXT); + + symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "texture", + samplerExternal2DY2YEXT, float2, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, + "textureProj", samplerExternal2DY2YEXT, float3, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, + "textureProj", samplerExternal2DY2YEXT, float4, float1); + } } - const TType *sampler2DShadow = TCache::getType(EbtSampler2DShadow); - const TType *samplerCubeShadow = TCache::getType(EbtSamplerCubeShadow); + const TType *sampler2DShadow = TCache::getType(EbtSampler2DShadow); + const TType *samplerCubeShadow = TCache::getType(EbtSamplerCubeShadow); const TType *sampler2DArrayShadow = TCache::getType(EbtSampler2DArrayShadow); symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "texture", sampler2DShadow, float3); symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "texture", samplerCubeShadow, float4); symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "texture", sampler2DArrayShadow, float4); symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProj", sampler2DShadow, float4); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureLod", sampler2DShadow, float3, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureLod", sampler2DShadow, float3, + float1); if (type == GL_FRAGMENT_SHADER) { - symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "texture", sampler2DShadow, float3, float1); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "texture", samplerCubeShadow, float4, float1); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProj", sampler2DShadow, float4, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "texture", sampler2DShadow, float3, + float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "texture", samplerCubeShadow, float4, + float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProj", sampler2DShadow, float4, + float1); } symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", gsampler2D, int1); @@ -350,135 +474,398 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", sampler2DShadow, int1); symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", samplerCubeShadow, int1); symbolTable.insertBuiltIn(ESSL3_BUILTINS, int3, "textureSize", sampler2DArrayShadow, int1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", gsampler2DMS); + + if (resources.OES_EGL_image_external_essl3) + { + const TType *samplerExternalOES = TCache::getType(EbtSamplerExternalOES); + + symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", samplerExternalOES, int1); + } + + if (resources.EXT_YUV_target) + { + const TType *samplerExternal2DY2YEXT = TCache::getType(EbtSamplerExternal2DY2YEXT); + + symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, int2, "textureSize", + samplerExternal2DY2YEXT, int1); + } if (type == GL_FRAGMENT_SHADER) { - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpDFdx, genType, "dFdx", genType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpDFdy, genType, "dFdy", genType); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpFwidth, genType, "fwidth", genType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpDFdx, genType, genType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpDFdy, genType, genType); + symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpFwidth, genType, genType); } symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2D, float2, int2); symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler3D, float3, int3); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureOffset", sampler2DShadow, float3, int2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2DArray, float3, int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureOffset", sampler2DShadow, float3, + int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2DArray, float3, + int2); if (type == GL_FRAGMENT_SHADER) { - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2D, float2, int2, float1); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler3D, float3, int3, float1); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureOffset", sampler2DShadow, float3, int2, float1); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2DArray, float3, int2, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2D, float2, int2, + float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler3D, float3, int3, + float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureOffset", sampler2DShadow, float3, + int2, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureOffset", gsampler2DArray, float3, + int2, float1); } symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float3, int2); symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float4, int2); symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler3D, float4, int3); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjOffset", sampler2DShadow, float4, int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjOffset", sampler2DShadow, float4, + int2); if (type == GL_FRAGMENT_SHADER) { - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float3, int2, float1); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float4, int2, float1); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler3D, float4, int3, float1); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjOffset", sampler2DShadow, float4, int2, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float3, + int2, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler2D, float4, + int2, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjOffset", gsampler3D, float4, + int3, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjOffset", sampler2DShadow, + float4, int2, float1); } - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLodOffset", gsampler2D, float2, float1, int2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLodOffset", gsampler3D, float3, float1, int3); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureLodOffset", sampler2DShadow, float3, float1, int2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLodOffset", gsampler2DArray, float3, float1, int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLodOffset", gsampler2D, float2, float1, + int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLodOffset", gsampler3D, float3, float1, + int3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureLodOffset", sampler2DShadow, float3, + float1, int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLodOffset", gsampler2DArray, float3, + float1, int2); symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLod", gsampler2D, float3, float1); symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLod", gsampler2D, float4, float1); symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLod", gsampler3D, float4, float1); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjLod", sampler2DShadow, float4, float1); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjLod", sampler2DShadow, float4, + float1); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLodOffset", gsampler2D, float3, float1, int2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLodOffset", gsampler2D, float4, float1, int2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLodOffset", gsampler3D, float4, float1, int3); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjLodOffset", sampler2DShadow, float4, float1, int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLodOffset", gsampler2D, float3, + float1, int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLodOffset", gsampler2D, float4, + float1, int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjLodOffset", gsampler3D, float4, + float1, int3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjLodOffset", sampler2DShadow, + float4, float1, int2); symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler2D, int2, int1); symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler3D, int3, int1); symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler2DArray, int3, int1); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler2D, int2, int1, int2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler3D, int3, int1, int3); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler2DArray, int3, int1, int2); + if (resources.OES_EGL_image_external_essl3) + { + const TType *samplerExternalOES = TCache::getType(EbtSamplerExternalOES); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsampler2D, float2, float2, float2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsampler3D, float3, float3, float3); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsamplerCube, float3, float3, float3); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureGrad", sampler2DShadow, float3, float2, float2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureGrad", samplerCubeShadow, float4, float3, float3); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsampler2DArray, float3, float2, float2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureGrad", sampler2DArrayShadow, float4, float2, float2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "texelFetch", samplerExternalOES, int2, + int1); + } - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGradOffset", gsampler2D, float2, float2, float2, int2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGradOffset", gsampler3D, float3, float3, float3, int3); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureGradOffset", sampler2DShadow, float3, float2, float2, int2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGradOffset", gsampler2DArray, float3, float2, float2, int2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureGradOffset", sampler2DArrayShadow, float4, float2, float2, int2); + if (resources.EXT_YUV_target) + { + const TType *samplerExternal2DY2YEXT = TCache::getType(EbtSamplerExternal2DY2YEXT); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGrad", gsampler2D, float3, float2, float2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGrad", gsampler2D, float4, float2, float2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGrad", gsampler3D, float4, float3, float3); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjGrad", sampler2DShadow, float4, float2, float2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, TExtension::EXT_YUV_target, float4, "texelFetch", + samplerExternal2DY2YEXT, int2, int1); + } - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGradOffset", gsampler2D, float3, float2, float2, int2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGradOffset", gsampler2D, float4, float2, float2, int2); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGradOffset", gsampler3D, float4, float3, float3, int3); - symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjGradOffset", sampler2DShadow, float4, float2, float2, int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler2D, int2, int1, + int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler3D, int3, int1, + int3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler2DArray, int3, + int1, int2); + + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsampler2D, float2, float2, + float2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsampler3D, float3, float3, + float3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsamplerCube, float3, float3, + float3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureGrad", sampler2DShadow, float3, + float2, float2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureGrad", samplerCubeShadow, float4, + float3, float3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGrad", gsampler2DArray, float3, float2, + float2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureGrad", sampler2DArrayShadow, float4, + float2, float2); + + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGradOffset", gsampler2D, float2, + float2, float2, int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGradOffset", gsampler3D, float3, + float3, float3, int3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureGradOffset", sampler2DShadow, float3, + float2, float2, int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureGradOffset", gsampler2DArray, float3, + float2, float2, int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureGradOffset", sampler2DArrayShadow, + float4, float2, float2, int2); + + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGrad", gsampler2D, float3, float2, + float2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGrad", gsampler2D, float4, float2, + float2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGrad", gsampler3D, float4, float3, + float3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjGrad", sampler2DShadow, float4, + float2, float2); + + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGradOffset", gsampler2D, float3, + float2, float2, int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGradOffset", gsampler2D, float4, + float2, float2, int2); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProjGradOffset", gsampler3D, float4, + float3, float3, int3); + symbolTable.insertBuiltIn(ESSL3_BUILTINS, float1, "textureProjGradOffset", sampler2DShadow, + float4, float2, float2, int2); + + const TType *atomicCounter = TCache::getType(EbtAtomicCounter); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicCounter", atomicCounter); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicCounterIncrement", atomicCounter); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicCounterDecrement", atomicCounter); + + // Insert all atomic memory functions + const TType *int1InOut = TCache::getType(EbtInt, EvqInOut); + const TType *uint1InOut = TCache::getType(EbtUInt, EvqInOut); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicAdd", uint1InOut, uint1); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicAdd", int1InOut, int1); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicMin", uint1InOut, uint1); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicMin", int1InOut, int1); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicMax", uint1InOut, uint1); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicMax", int1InOut, int1); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicAnd", uint1InOut, uint1); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicAnd", int1InOut, int1); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicOr", uint1InOut, uint1); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicOr", int1InOut, int1); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicXor", uint1InOut, uint1); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicXor", int1InOut, int1); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicExchange", uint1InOut, uint1); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicExchange", int1InOut, int1); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, uint1, "atomicCompSwap", uint1InOut, uint1, uint1); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int1, "atomicCompSwap", int1InOut, int1, int1); + + const TType *gimage2D = TCache::getType(EbtGImage2D); + const TType *gimage3D = TCache::getType(EbtGImage3D); + const TType *gimage2DArray = TCache::getType(EbtGImage2DArray); + const TType *gimageCube = TCache::getType(EbtGImageCube); + + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimage2D, int2, gvec4); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimage3D, int3, gvec4); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimage2DArray, int3, gvec4); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, voidType, "imageStore", gimageCube, int3, gvec4); + + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimage2D, int2); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimage3D, int3); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimage2DArray, int3); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "imageLoad", gimageCube, int3); + + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int2, "imageSize", gimage2D); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int3, "imageSize", gimage3D); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int3, "imageSize", gimage2DArray); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, int2, "imageSize", gimageCube); + + symbolTable.insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpMemoryBarrier, voidType, + "memoryBarrier"); + symbolTable.insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpMemoryBarrierAtomicCounter, + voidType, "memoryBarrierAtomicCounter"); + symbolTable.insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpMemoryBarrierBuffer, + voidType, "memoryBarrierBuffer"); + symbolTable.insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpMemoryBarrierImage, voidType, + "memoryBarrierImage"); + + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "texelFetch", gsampler2DMS, int2, int1); + + // Insert all variations of textureGather. + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsampler2D, float2); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsampler2D, float2, int1); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsampler2DArray, float3); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsampler2DArray, float3, + int1); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsamplerCube, float3); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGather", gsamplerCube, float3, int1); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", sampler2DShadow, float2); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", sampler2DShadow, float2, + float1); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", sampler2DArrayShadow, + float3); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", sampler2DArrayShadow, + float3, float1); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", samplerCubeShadow, float3); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGather", samplerCubeShadow, float3, + float1); + + // Insert all variations of textureGatherOffset. + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGatherOffset", gsampler2D, float2, + int2); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGatherOffset", gsampler2D, float2, + int2, int1); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGatherOffset", gsampler2DArray, + float3, int2); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, gvec4, "textureGatherOffset", gsampler2DArray, + float3, int2, int1); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGatherOffset", sampler2DShadow, + float2, float1, int2); + symbolTable.insertBuiltIn(ESSL3_1_BUILTINS, float4, "textureGatherOffset", sampler2DArrayShadow, + float3, float1, int2); + + if (type == GL_COMPUTE_SHADER) + { + symbolTable.insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpBarrier, voidType, + "barrier"); + symbolTable.insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpMemoryBarrierShared, + voidType, "memoryBarrierShared"); + symbolTable.insertBuiltInFunctionNoParameters(ESSL3_1_BUILTINS, EOpGroupMemoryBarrier, + voidType, "groupMemoryBarrier"); + } + + if (type == GL_GEOMETRY_SHADER_OES) + { + TExtension extension = TExtension::OES_geometry_shader; + symbolTable.insertBuiltInFunctionNoParametersExt(ESSL3_1_BUILTINS, extension, EOpEmitVertex, + voidType, "EmitVertex"); + symbolTable.insertBuiltInFunctionNoParametersExt(ESSL3_1_BUILTINS, extension, + EOpEndPrimitive, voidType, "EndPrimitive"); + } // // Depth range in window coordinates // - TFieldList *fields = NewPoolTFieldList(); + TFieldList *fields = NewPoolTFieldList(); TSourceLoc zeroSourceLoc = {0, 0, 0, 0}; - TField *near = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("near"), zeroSourceLoc); - TField *far = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("far"), zeroSourceLoc); - TField *diff = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("diff"), zeroSourceLoc); + auto highpFloat1 = new TType(EbtFloat, EbpHigh, EvqGlobal, 1); + TField *near = new TField(highpFloat1, NewPoolTString("near"), zeroSourceLoc); + TField *far = new TField(highpFloat1, NewPoolTString("far"), zeroSourceLoc); + TField *diff = new TField(highpFloat1, NewPoolTString("diff"), zeroSourceLoc); fields->push_back(near); fields->push_back(far); fields->push_back(diff); - TStructure *depthRangeStruct = new TStructure(NewPoolTString("gl_DepthRangeParameters"), fields); - TVariable *depthRangeParameters = new TVariable(&depthRangeStruct->name(), depthRangeStruct, true); - symbolTable.insert(COMMON_BUILTINS, depthRangeParameters); - TVariable *depthRange = new TVariable(NewPoolTString("gl_DepthRange"), TType(depthRangeStruct)); - depthRange->setQualifier(EvqUniform); - symbolTable.insert(COMMON_BUILTINS, depthRange); + TStructure *depthRangeStruct = + new TStructure(&symbolTable, NewPoolTString("gl_DepthRangeParameters"), fields); + symbolTable.insertStructType(COMMON_BUILTINS, depthRangeStruct); + TType depthRangeType(depthRangeStruct); + depthRangeType.setQualifier(EvqUniform); + symbolTable.insertVariable(COMMON_BUILTINS, "gl_DepthRange", depthRangeType); // // Implementation dependent built-in constants. // - symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexAttribs", resources.MaxVertexAttribs); - symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexUniformVectors", resources.MaxVertexUniformVectors); - symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexTextureImageUnits", resources.MaxVertexTextureImageUnits); - symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxCombinedTextureImageUnits", resources.MaxCombinedTextureImageUnits); - symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxTextureImageUnits", resources.MaxTextureImageUnits); - symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxFragmentUniformVectors", resources.MaxFragmentUniformVectors); + symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexAttribs", resources.MaxVertexAttribs, + EbpMedium); + symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexUniformVectors", + resources.MaxVertexUniformVectors, EbpMedium); + symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxVertexTextureImageUnits", + resources.MaxVertexTextureImageUnits, EbpMedium); + symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxCombinedTextureImageUnits", + resources.MaxCombinedTextureImageUnits, EbpMedium); + symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxTextureImageUnits", + resources.MaxTextureImageUnits, EbpMedium); + symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxFragmentUniformVectors", + resources.MaxFragmentUniformVectors, EbpMedium); - symbolTable.insertConstInt(ESSL1_BUILTINS, "gl_MaxVaryingVectors", resources.MaxVaryingVectors); + symbolTable.insertConstInt(ESSL1_BUILTINS, "gl_MaxVaryingVectors", resources.MaxVaryingVectors, + EbpMedium); - if (spec != SH_CSS_SHADERS_SPEC) + symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxDrawBuffers", resources.MaxDrawBuffers, + EbpMedium); + if (resources.EXT_blend_func_extended) { - symbolTable.insertConstInt(COMMON_BUILTINS, "gl_MaxDrawBuffers", resources.MaxDrawBuffers); - if (resources.EXT_blend_func_extended) - { - symbolTable.insertConstIntExt(COMMON_BUILTINS, "GL_EXT_blend_func_extended", - "gl_MaxDualSourceDrawBuffersEXT", - resources.MaxDualSourceDrawBuffers); - } + symbolTable.insertConstIntExt(COMMON_BUILTINS, TExtension::EXT_blend_func_extended, + "gl_MaxDualSourceDrawBuffersEXT", + resources.MaxDualSourceDrawBuffers, EbpMedium); } - symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxVertexOutputVectors", resources.MaxVertexOutputVectors); - symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxFragmentInputVectors", resources.MaxFragmentInputVectors); - symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MinProgramTexelOffset", resources.MinProgramTexelOffset); - symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxProgramTexelOffset", resources.MaxProgramTexelOffset); + symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxVertexOutputVectors", + resources.MaxVertexOutputVectors, EbpMedium); + symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxFragmentInputVectors", + resources.MaxFragmentInputVectors, EbpMedium); + symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MinProgramTexelOffset", + resources.MinProgramTexelOffset, EbpMedium); + symbolTable.insertConstInt(ESSL3_BUILTINS, "gl_MaxProgramTexelOffset", + resources.MaxProgramTexelOffset, EbpMedium); + + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxImageUnits", resources.MaxImageUnits, + EbpMedium); + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxVertexImageUniforms", + resources.MaxVertexImageUniforms, EbpMedium); + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxFragmentImageUniforms", + resources.MaxFragmentImageUniforms, EbpMedium); + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxComputeImageUniforms", + resources.MaxComputeImageUniforms, EbpMedium); + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxCombinedImageUniforms", + resources.MaxCombinedImageUniforms, EbpMedium); + + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxCombinedShaderOutputResources", + resources.MaxCombinedShaderOutputResources, EbpMedium); + + symbolTable.insertConstIvec3(ESSL3_1_BUILTINS, "gl_MaxComputeWorkGroupCount", + resources.MaxComputeWorkGroupCount, EbpHigh); + symbolTable.insertConstIvec3(ESSL3_1_BUILTINS, "gl_MaxComputeWorkGroupSize", + resources.MaxComputeWorkGroupSize, EbpHigh); + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxComputeUniformComponents", + resources.MaxComputeUniformComponents, EbpMedium); + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxComputeTextureImageUnits", + resources.MaxComputeTextureImageUnits, EbpMedium); + + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxComputeAtomicCounters", + resources.MaxComputeAtomicCounters, EbpMedium); + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxComputeAtomicCounterBuffers", + resources.MaxComputeAtomicCounterBuffers, EbpMedium); + + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxVertexAtomicCounters", + resources.MaxVertexAtomicCounters, EbpMedium); + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxFragmentAtomicCounters", + resources.MaxFragmentAtomicCounters, EbpMedium); + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxCombinedAtomicCounters", + resources.MaxCombinedAtomicCounters, EbpMedium); + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxAtomicCounterBindings", + resources.MaxAtomicCounterBindings, EbpMedium); + + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxVertexAtomicCounterBuffers", + resources.MaxVertexAtomicCounterBuffers, EbpMedium); + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxFragmentAtomicCounterBuffers", + resources.MaxFragmentAtomicCounterBuffers, EbpMedium); + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxCombinedAtomicCounterBuffers", + resources.MaxCombinedAtomicCounterBuffers, EbpMedium); + symbolTable.insertConstInt(ESSL3_1_BUILTINS, "gl_MaxAtomicCounterBufferSize", + resources.MaxAtomicCounterBufferSize, EbpMedium); + + if (resources.OES_geometry_shader) + { + TExtension ext = TExtension::OES_geometry_shader; + symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryInputComponents", + resources.MaxGeometryInputComponents, EbpMedium); + symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryOutputComponents", + resources.MaxGeometryOutputComponents, EbpMedium); + symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryImageUniforms", + resources.MaxGeometryImageUniforms, EbpMedium); + symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryTextureImageUnits", + resources.MaxGeometryTextureImageUnits, EbpMedium); + symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryOutputVertices", + resources.MaxGeometryOutputVertices, EbpMedium); + symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryTotalOutputComponents", + resources.MaxGeometryTotalOutputComponents, EbpMedium); + symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryUniformComponents", + resources.MaxGeometryUniformComponents, EbpMedium); + symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryAtomicCounters", + resources.MaxGeometryAtomicCounters, EbpMedium); + symbolTable.insertConstIntExt(ESSL3_1_BUILTINS, ext, "gl_MaxGeometryAtomicCounterBuffers", + resources.MaxGeometryAtomicCounterBuffers, EbpMedium); + } } -void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec, +void IdentifyBuiltIns(sh::GLenum type, + ShShaderSpec spec, const ShBuiltInResources &resources, TSymbolTable &symbolTable) { @@ -486,136 +873,263 @@ void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec, // Insert some special built-in variables that are not in // the built-in header files. // + + if (resources.OVR_multiview && type != GL_COMPUTE_SHADER) + { + symbolTable.insertVariableExt(ESSL3_BUILTINS, TExtension::OVR_multiview, "gl_ViewID_OVR", + TType(EbtUInt, EbpHigh, EvqViewIDOVR, 1)); + + // ESSL 1.00 doesn't have unsigned integers, so gl_ViewID_OVR is a signed integer in ESSL + // 1.00. This is specified in the WEBGL_multiview spec. + symbolTable.insertVariableExt(ESSL1_BUILTINS, TExtension::OVR_multiview, "gl_ViewID_OVR", + TType(EbtInt, EbpHigh, EvqViewIDOVR, 1)); + } + switch (type) { - case GL_FRAGMENT_SHADER: - symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FragCoord"), - TType(EbtFloat, EbpMedium, EvqFragCoord, 4))); - symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FrontFacing"), - TType(EbtBool, EbpUndefined, EvqFrontFacing, 1))); - symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_PointCoord"), - TType(EbtFloat, EbpMedium, EvqPointCoord, 2))); - - // - // In CSS Shaders, gl_FragColor, gl_FragData, and gl_MaxDrawBuffers are not available. - // Instead, css_MixColor and css_ColorMatrix are available. - // - if (spec != SH_CSS_SHADERS_SPEC) + case GL_FRAGMENT_SHADER: { - symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragColor"), - TType(EbtFloat, EbpMedium, EvqFragColor, 4))); - TType fragData(EbtFloat, EbpMedium, EvqFragData, 4, 1, true); - fragData.setArraySize(resources.MaxDrawBuffers); - symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragData"), fragData)); + symbolTable.insertVariable(COMMON_BUILTINS, "gl_FragCoord", + TType(EbtFloat, EbpMedium, EvqFragCoord, 4)); + symbolTable.insertVariable(COMMON_BUILTINS, "gl_FrontFacing", + TType(EbtBool, EbpUndefined, EvqFrontFacing, 1)); + symbolTable.insertVariable(COMMON_BUILTINS, "gl_PointCoord", + TType(EbtFloat, EbpMedium, EvqPointCoord, 2)); + + symbolTable.insertVariable(ESSL1_BUILTINS, "gl_FragColor", + TType(EbtFloat, EbpMedium, EvqFragColor, 4)); + TType fragData(EbtFloat, EbpMedium, EvqFragData, 4); + if (spec != SH_WEBGL2_SPEC && spec != SH_WEBGL3_SPEC) + { + fragData.makeArray(resources.MaxDrawBuffers); + } + else + { + fragData.makeArray(1u); + } + symbolTable.insertVariable(ESSL1_BUILTINS, "gl_FragData", fragData); if (resources.EXT_blend_func_extended) { - symbolTable.insert( - ESSL1_BUILTINS, "GL_EXT_blend_func_extended", - new TVariable(NewPoolTString("gl_SecondaryFragColorEXT"), - TType(EbtFloat, EbpMedium, EvqSecondaryFragColorEXT, 4))); - TType secondaryFragData(EbtFloat, EbpMedium, EvqSecondaryFragDataEXT, 4, 1, true); - secondaryFragData.setArraySize(resources.MaxDualSourceDrawBuffers); - symbolTable.insert( - ESSL1_BUILTINS, "GL_EXT_blend_func_extended", - new TVariable(NewPoolTString("gl_SecondaryFragDataEXT"), secondaryFragData)); + symbolTable.insertVariableExt( + ESSL1_BUILTINS, TExtension::EXT_blend_func_extended, "gl_SecondaryFragColorEXT", + TType(EbtFloat, EbpMedium, EvqSecondaryFragColorEXT, 4)); + TType secondaryFragData(EbtFloat, EbpMedium, EvqSecondaryFragDataEXT, 4, 1); + secondaryFragData.makeArray(resources.MaxDualSourceDrawBuffers); + symbolTable.insertVariableExt(ESSL1_BUILTINS, TExtension::EXT_blend_func_extended, + "gl_SecondaryFragDataEXT", secondaryFragData); } if (resources.EXT_frag_depth) { - symbolTable.insert( - ESSL1_BUILTINS, "GL_EXT_frag_depth", - new TVariable( - NewPoolTString("gl_FragDepthEXT"), - TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium, - EvqFragDepthEXT, 1))); + symbolTable.insertVariableExt( + ESSL1_BUILTINS, TExtension::EXT_frag_depth, "gl_FragDepthEXT", + TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium, + EvqFragDepthEXT, 1)); } - symbolTable.insert(ESSL3_BUILTINS, - new TVariable(NewPoolTString("gl_FragDepth"), - TType(EbtFloat, EbpHigh, EvqFragDepth, 1))); + symbolTable.insertVariable(ESSL3_BUILTINS, "gl_FragDepth", + TType(EbtFloat, EbpHigh, EvqFragDepth, 1)); if (resources.EXT_shader_framebuffer_fetch || resources.NV_shader_framebuffer_fetch) { - TType lastFragData(EbtFloat, EbpMedium, EvqLastFragData, 4, 1, true); - lastFragData.setArraySize(resources.MaxDrawBuffers); + TType lastFragData(EbtFloat, EbpMedium, EvqLastFragData, 4, 1); + lastFragData.makeArray(resources.MaxDrawBuffers); if (resources.EXT_shader_framebuffer_fetch) { - symbolTable.insert(ESSL1_BUILTINS, "GL_EXT_shader_framebuffer_fetch", - new TVariable(NewPoolTString("gl_LastFragData"), lastFragData)); + symbolTable.insertVariableExt(ESSL1_BUILTINS, + TExtension::EXT_shader_framebuffer_fetch, + "gl_LastFragData", lastFragData); } else if (resources.NV_shader_framebuffer_fetch) { - symbolTable.insert(ESSL1_BUILTINS, "GL_NV_shader_framebuffer_fetch", - new TVariable(NewPoolTString("gl_LastFragColor"), - TType(EbtFloat, EbpMedium, EvqLastFragColor, 4))); - symbolTable.insert(ESSL1_BUILTINS, "GL_NV_shader_framebuffer_fetch", - new TVariable(NewPoolTString("gl_LastFragData"), lastFragData)); + symbolTable.insertVariableExt( + ESSL1_BUILTINS, TExtension::NV_shader_framebuffer_fetch, "gl_LastFragColor", + TType(EbtFloat, EbpMedium, EvqLastFragColor, 4)); + symbolTable.insertVariableExt(ESSL1_BUILTINS, + TExtension::NV_shader_framebuffer_fetch, + "gl_LastFragData", lastFragData); } } else if (resources.ARM_shader_framebuffer_fetch) { - symbolTable.insert(ESSL1_BUILTINS, "GL_ARM_shader_framebuffer_fetch", - new TVariable(NewPoolTString("gl_LastFragColorARM"), - TType(EbtFloat, EbpMedium, EvqLastFragColor, 4))); + symbolTable.insertVariableExt( + ESSL1_BUILTINS, TExtension::ARM_shader_framebuffer_fetch, "gl_LastFragColorARM", + TType(EbtFloat, EbpMedium, EvqLastFragColor, 4)); } + + if (resources.OES_geometry_shader) + { + TExtension extension = TExtension::OES_geometry_shader; + symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_PrimitiveID", + TType(EbtInt, EbpHigh, EvqPrimitiveID, 1)); + symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_Layer", + TType(EbtInt, EbpHigh, EvqLayer, 1)); + } + + break; } - else + case GL_VERTEX_SHADER: { - symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("css_MixColor"), - TType(EbtFloat, EbpMedium, EvqGlobal, 4))); - symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("css_ColorMatrix"), - TType(EbtFloat, EbpMedium, EvqGlobal, 4, 4))); + symbolTable.insertVariable(COMMON_BUILTINS, "gl_Position", + TType(EbtFloat, EbpHigh, EvqPosition, 4)); + symbolTable.insertVariable(COMMON_BUILTINS, "gl_PointSize", + TType(EbtFloat, EbpMedium, EvqPointSize, 1)); + symbolTable.insertVariable(ESSL3_BUILTINS, "gl_InstanceID", + TType(EbtInt, EbpHigh, EvqInstanceID, 1)); + symbolTable.insertVariable(ESSL3_BUILTINS, "gl_VertexID", + TType(EbtInt, EbpHigh, EvqVertexID, 1)); + + // For internal use by ANGLE - not exposed to the parser. + symbolTable.insertVariable(GLSL_BUILTINS, "gl_ViewportIndex", + TType(EbtInt, EbpHigh, EvqViewportIndex)); + // gl_Layer exists in other shader stages in ESSL, but not in vertex shader so far. + symbolTable.insertVariable(GLSL_BUILTINS, "gl_Layer", TType(EbtInt, EbpHigh, EvqLayer)); + break; + } + case GL_COMPUTE_SHADER: + { + symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_NumWorkGroups", + TType(EbtUInt, EbpUndefined, EvqNumWorkGroups, 3)); + symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_WorkGroupSize", + TType(EbtUInt, EbpUndefined, EvqWorkGroupSize, 3)); + symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_WorkGroupID", + TType(EbtUInt, EbpUndefined, EvqWorkGroupID, 3)); + symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_LocalInvocationID", + TType(EbtUInt, EbpUndefined, EvqLocalInvocationID, 3)); + symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_GlobalInvocationID", + TType(EbtUInt, EbpUndefined, EvqGlobalInvocationID, 3)); + symbolTable.insertVariable(ESSL3_1_BUILTINS, "gl_LocalInvocationIndex", + TType(EbtUInt, EbpUndefined, EvqLocalInvocationIndex, 1)); + break; } - break; + case GL_GEOMETRY_SHADER_OES: + { + TExtension extension = TExtension::OES_geometry_shader; - case GL_VERTEX_SHADER: - symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_Position"), - TType(EbtFloat, EbpHigh, EvqPosition, 4))); - symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_PointSize"), - TType(EbtFloat, EbpMedium, EvqPointSize, 1))); - symbolTable.insert(ESSL3_BUILTINS, new TVariable(NewPoolTString("gl_InstanceID"), - TType(EbtInt, EbpHigh, EvqInstanceID, 1))); - break; + // Add built-in interface block gl_PerVertex and the built-in array gl_in. + // TODO(jiawei.shao@intel.com): implement GL_OES_geometry_point_size. + const TString *glPerVertexString = NewPoolTString("gl_PerVertex"); + symbolTable.insertInterfaceBlockNameExt(ESSL3_1_BUILTINS, extension, glPerVertexString); - default: - assert(false && "Language not supported"); + TFieldList *fieldList = NewPoolTFieldList(); + TSourceLoc zeroSourceLoc = {0, 0, 0, 0}; + TField *glPositionField = new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4), + NewPoolTString("gl_Position"), zeroSourceLoc); + fieldList->push_back(glPositionField); + + TInterfaceBlock *glInBlock = new TInterfaceBlock( + glPerVertexString, fieldList, NewPoolTString("gl_in"), TLayoutQualifier::Create()); + + // The array size of gl_in is undefined until we get a valid input primitive + // declaration. + TType glInType(glInBlock, EvqPerVertexIn, TLayoutQualifier::Create()); + glInType.makeArray(0u); + symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_in", glInType); + + TType glPositionType(EbtFloat, EbpHigh, EvqPosition, 4); + glPositionType.setInterfaceBlock(new TInterfaceBlock( + glPerVertexString, fieldList, nullptr, TLayoutQualifier::Create())); + symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_Position", + glPositionType); + symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_PrimitiveIDIn", + TType(EbtInt, EbpHigh, EvqPrimitiveIDIn, 1)); + symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_InvocationID", + TType(EbtInt, EbpHigh, EvqInvocationID, 1)); + symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_PrimitiveID", + TType(EbtInt, EbpHigh, EvqPrimitiveID, 1)); + symbolTable.insertVariableExt(ESSL3_1_BUILTINS, extension, "gl_Layer", + TType(EbtInt, EbpHigh, EvqLayer, 1)); + + break; + } + default: + UNREACHABLE(); } } -void InitExtensionBehavior(const ShBuiltInResources& resources, - TExtensionBehavior& extBehavior) +void InitExtensionBehavior(const ShBuiltInResources &resources, TExtensionBehavior &extBehavior) { if (resources.OES_standard_derivatives) - extBehavior["GL_OES_standard_derivatives"] = EBhUndefined; + { + extBehavior[TExtension::OES_standard_derivatives] = EBhUndefined; + } if (resources.OES_EGL_image_external) - extBehavior["GL_OES_EGL_image_external"] = EBhUndefined; + { + extBehavior[TExtension::OES_EGL_image_external] = EBhUndefined; + } + if (resources.OES_EGL_image_external_essl3) + { + extBehavior[TExtension::OES_EGL_image_external_essl3] = EBhUndefined; + } + if (resources.NV_EGL_stream_consumer_external) + { + extBehavior[TExtension::NV_EGL_stream_consumer_external] = EBhUndefined; + } if (resources.ARB_texture_rectangle) - extBehavior["GL_ARB_texture_rectangle"] = EBhUndefined; + { + // Special: ARB_texture_rectangle extension does not follow the standard for #extension + // directives - it is enabled by default. An extension directive may still disable it. + extBehavior[TExtension::ARB_texture_rectangle] = EBhEnable; + } if (resources.EXT_blend_func_extended) - extBehavior["GL_EXT_blend_func_extended"] = EBhUndefined; + { + extBehavior[TExtension::EXT_blend_func_extended] = EBhUndefined; + } if (resources.EXT_draw_buffers) - extBehavior["GL_EXT_draw_buffers"] = EBhUndefined; + { + extBehavior[TExtension::EXT_draw_buffers] = EBhUndefined; + } if (resources.EXT_frag_depth) - extBehavior["GL_EXT_frag_depth"] = EBhUndefined; + { + extBehavior[TExtension::EXT_frag_depth] = EBhUndefined; + } if (resources.EXT_shader_texture_lod) - extBehavior["GL_EXT_shader_texture_lod"] = EBhUndefined; + { + extBehavior[TExtension::EXT_shader_texture_lod] = EBhUndefined; + } if (resources.EXT_shader_framebuffer_fetch) - extBehavior["GL_EXT_shader_framebuffer_fetch"] = EBhUndefined; + { + extBehavior[TExtension::EXT_shader_framebuffer_fetch] = EBhUndefined; + } if (resources.NV_shader_framebuffer_fetch) - extBehavior["GL_NV_shader_framebuffer_fetch"] = EBhUndefined; + { + extBehavior[TExtension::NV_shader_framebuffer_fetch] = EBhUndefined; + } if (resources.ARM_shader_framebuffer_fetch) - extBehavior["GL_ARM_shader_framebuffer_fetch"] = EBhUndefined; + { + extBehavior[TExtension::ARM_shader_framebuffer_fetch] = EBhUndefined; + } + if (resources.OVR_multiview) + { + extBehavior[TExtension::OVR_multiview] = EBhUndefined; + } + if (resources.EXT_YUV_target) + { + extBehavior[TExtension::EXT_YUV_target] = EBhUndefined; + } + if (resources.OES_geometry_shader) + { + extBehavior[TExtension::OES_geometry_shader] = EBhUndefined; + extBehavior[TExtension::EXT_geometry_shader] = EBhUndefined; + } } void ResetExtensionBehavior(TExtensionBehavior &extBehavior) { - for (auto ext_iter = extBehavior.begin(); - ext_iter != extBehavior.end(); - ++ext_iter) + for (auto &ext : extBehavior) { - ext_iter->second = EBhUndefined; + if (ext.first == TExtension::ARB_texture_rectangle) + { + ext.second = EBhEnable; + } + else + { + ext.second = EBhUndefined; + } } } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/Initialize.h b/src/3rdparty/angle/src/compiler/translator/Initialize.h index c43ce3417a..2e61218a0f 100644 --- a/src/3rdparty/angle/src/compiler/translator/Initialize.h +++ b/src/3rdparty/angle/src/compiler/translator/Initialize.h @@ -11,14 +11,21 @@ #include "compiler/translator/Compiler.h" #include "compiler/translator/SymbolTable.h" -void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInResources &resources, TSymbolTable &table); +namespace sh +{ -void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec, - const ShBuiltInResources& resources, - TSymbolTable& symbolTable); +void InsertBuiltInFunctions(sh::GLenum type, + ShShaderSpec spec, + const ShBuiltInResources &resources, + TSymbolTable &table); -void InitExtensionBehavior(const ShBuiltInResources& resources, - TExtensionBehavior& extensionBehavior); +void IdentifyBuiltIns(sh::GLenum type, + ShShaderSpec spec, + const ShBuiltInResources &resources, + TSymbolTable &symbolTable); + +void InitExtensionBehavior(const ShBuiltInResources &resources, + TExtensionBehavior &extensionBehavior); // Resets the behavior of the extensions listed in |extensionBehavior| to the // undefined state. These extensions will only be those initially supported in @@ -26,4 +33,6 @@ void InitExtensionBehavior(const ShBuiltInResources& resources, // extensions will remain unsupported. void ResetExtensionBehavior(TExtensionBehavior &extensionBehavior); -#endif // COMPILER_TRANSLATOR_INITIALIZE_H_ +} // namespace sh + +#endif // COMPILER_TRANSLATOR_INITIALIZE_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/InitializeDll.cpp b/src/3rdparty/angle/src/compiler/translator/InitializeDll.cpp index 713965389f..43c215f52b 100644 --- a/src/3rdparty/angle/src/compiler/translator/InitializeDll.cpp +++ b/src/3rdparty/angle/src/compiler/translator/InitializeDll.cpp @@ -7,24 +7,22 @@ #include "compiler/translator/Cache.h" #include "compiler/translator/InitializeDll.h" #include "compiler/translator/InitializeGlobals.h" -#include "compiler/translator/InitializeParseContext.h" #include "common/platform.h" #include +namespace sh +{ + bool InitProcess() { - if (!InitializePoolIndex()) { + if (!InitializePoolIndex()) + { assert(0 && "InitProcess(): Failed to initalize global pool"); return false; } - if (!InitializeParseContextIndex()) { - assert(0 && "InitProcess(): Failed to initalize parse context"); - return false; - } - TCache::initialize(); return true; @@ -32,7 +30,8 @@ bool InitProcess() void DetachProcess() { - FreeParseContextIndex(); FreePoolIndex(); TCache::destroy(); } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/InitializeDll.h b/src/3rdparty/angle/src/compiler/translator/InitializeDll.h index 4c400760f6..87f7251470 100644 --- a/src/3rdparty/angle/src/compiler/translator/InitializeDll.h +++ b/src/3rdparty/angle/src/compiler/translator/InitializeDll.h @@ -6,8 +6,10 @@ #ifndef COMPILER_TRANSLATOR_INITIALIZEDLL_H_ #define COMPILER_TRANSLATOR_INITIALIZEDLL_H_ +namespace sh +{ bool InitProcess(); void DetachProcess(); +} // namespace sh -#endif // COMPILER_TRANSLATOR_INITIALIZEDLL_H_ - +#endif // COMPILER_TRANSLATOR_INITIALIZEDLL_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/InitializeGlobals.h b/src/3rdparty/angle/src/compiler/translator/InitializeGlobals.h index 8c65cb28da..9a67ed0e04 100644 --- a/src/3rdparty/angle/src/compiler/translator/InitializeGlobals.h +++ b/src/3rdparty/angle/src/compiler/translator/InitializeGlobals.h @@ -10,4 +10,4 @@ bool InitializePoolIndex(); void FreePoolIndex(); -#endif // COMPILER_TRANSLATOR_INITIALIZEGLOBALS_H_ +#endif // COMPILER_TRANSLATOR_INITIALIZEGLOBALS_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/InitializeParseContext.cpp b/src/3rdparty/angle/src/compiler/translator/InitializeParseContext.cpp deleted file mode 100644 index c35cedb348..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/InitializeParseContext.cpp +++ /dev/null @@ -1,42 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/translator/InitializeParseContext.h" - -#include "common/tls.h" - -#include - -TLSIndex GlobalParseContextIndex = TLS_INVALID_INDEX; - -bool InitializeParseContextIndex() -{ - assert(GlobalParseContextIndex == TLS_INVALID_INDEX); - - GlobalParseContextIndex = CreateTLSIndex(); - return GlobalParseContextIndex != TLS_INVALID_INDEX; -} - -void FreeParseContextIndex() -{ - assert(GlobalParseContextIndex != TLS_INVALID_INDEX); - - DestroyTLSIndex(GlobalParseContextIndex); - GlobalParseContextIndex = TLS_INVALID_INDEX; -} - -void SetGlobalParseContext(TParseContext* context) -{ - assert(GlobalParseContextIndex != TLS_INVALID_INDEX); - SetTLSValue(GlobalParseContextIndex, context); -} - -TParseContext* GetGlobalParseContext() -{ - assert(GlobalParseContextIndex != TLS_INVALID_INDEX); - return static_cast(GetTLSValue(GlobalParseContextIndex)); -} - diff --git a/src/3rdparty/angle/src/compiler/translator/InitializeParseContext.h b/src/3rdparty/angle/src/compiler/translator/InitializeParseContext.h deleted file mode 100644 index 70dac702e2..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/InitializeParseContext.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_TRANSLATOR_INITIALIZEPARSECONTEXT_H_ -#define COMPILER_TRANSLATOR_INITIALIZEPARSECONTEXT_H_ - -bool InitializeParseContextIndex(); -void FreeParseContextIndex(); - -class TParseContext; -extern void SetGlobalParseContext(TParseContext* context); -extern TParseContext* GetGlobalParseContext(); - -#endif // COMPILER_TRANSLATOR_INITIALIZEPARSECONTEXT_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/InitializeVariables.cpp b/src/3rdparty/angle/src/compiler/translator/InitializeVariables.cpp index 86d3e6bc83..aa1a042fac 100644 --- a/src/3rdparty/angle/src/compiler/translator/InitializeVariables.cpp +++ b/src/3rdparty/angle/src/compiler/translator/InitializeVariables.cpp @@ -6,112 +6,285 @@ #include "compiler/translator/InitializeVariables.h" +#include "angle_gl.h" #include "common/debug.h" +#include "compiler/translator/FindMain.h" +#include "compiler/translator/IntermNode_util.h" +#include "compiler/translator/IntermTraverse.h" +#include "compiler/translator/SymbolTable.h" +#include "compiler/translator/util.h" + +namespace sh +{ namespace { -TIntermConstantUnion *constructFloatConstUnionNode(const TType &type) -{ - TType myType = type; - unsigned char size = static_cast(myType.getNominalSize()); - if (myType.isMatrix()) - size *= size; - TConstantUnion *u = new TConstantUnion[size]; - for (int ii = 0; ii < size; ++ii) - u[ii].setFConst(0.0f); +void AddArrayZeroInitSequence(const TIntermTyped *initializedNode, + bool canUseLoopsToInitialize, + TIntermSequence *initSequenceOut, + TSymbolTable *symbolTable); - myType.clearArrayness(); - myType.setQualifier(EvqConst); - TIntermConstantUnion *node = new TIntermConstantUnion(u, myType); - return node; +void AddStructZeroInitSequence(const TIntermTyped *initializedNode, + bool canUseLoopsToInitialize, + TIntermSequence *initSequenceOut, + TSymbolTable *symbolTable); + +TIntermBinary *CreateZeroInitAssignment(const TIntermTyped *initializedNode) +{ + TIntermTyped *zero = CreateZeroNode(initializedNode->getType()); + return new TIntermBinary(EOpAssign, initializedNode->deepCopy(), zero); } -TIntermConstantUnion *constructIndexNode(int index) +void AddZeroInitSequence(const TIntermTyped *initializedNode, + bool canUseLoopsToInitialize, + TIntermSequence *initSequenceOut, + TSymbolTable *symbolTable) { - TConstantUnion *u = new TConstantUnion[1]; - u[0].setIConst(index); - - TType type(EbtInt, EbpUndefined, EvqConst, 1); - TIntermConstantUnion *node = new TIntermConstantUnion(u, type); - return node; -} - -} // namespace anonymous - -bool InitializeVariables::visitAggregate(Visit visit, TIntermAggregate *node) -{ - bool visitChildren = !mCodeInserted; - switch (node->getOp()) + if (initializedNode->isArray()) { - case EOpSequence: - break; - case EOpFunction: - { - // Function definition. - ASSERT(visit == PreVisit); - if (node->getName() == "main(") - { - TIntermSequence *sequence = node->getSequence(); - ASSERT((sequence->size() == 1) || (sequence->size() == 2)); - TIntermAggregate *body = NULL; - if (sequence->size() == 1) - { - body = new TIntermAggregate(EOpSequence); - sequence->push_back(body); - } - else - { - body = (*sequence)[1]->getAsAggregate(); - } - ASSERT(body); - insertInitCode(body->getSequence()); - mCodeInserted = true; - } - break; - } - default: - visitChildren = false; - break; + AddArrayZeroInitSequence(initializedNode, canUseLoopsToInitialize, initSequenceOut, + symbolTable); + } + else if (initializedNode->getType().isStructureContainingArrays() || + initializedNode->getType().isNamelessStruct()) + { + AddStructZeroInitSequence(initializedNode, canUseLoopsToInitialize, initSequenceOut, + symbolTable); + } + else + { + initSequenceOut->push_back(CreateZeroInitAssignment(initializedNode)); } - return visitChildren; } -void InitializeVariables::insertInitCode(TIntermSequence *sequence) +void AddStructZeroInitSequence(const TIntermTyped *initializedNode, + bool canUseLoopsToInitialize, + TIntermSequence *initSequenceOut, + TSymbolTable *symbolTable) { - for (size_t ii = 0; ii < mVariables.size(); ++ii) + ASSERT(initializedNode->getBasicType() == EbtStruct); + const TStructure *structType = initializedNode->getType().getStruct(); + for (int i = 0; i < static_cast(structType->fields().size()); ++i) { - const InitVariableInfo &varInfo = mVariables[ii]; + TIntermBinary *element = new TIntermBinary(EOpIndexDirectStruct, + initializedNode->deepCopy(), CreateIndexNode(i)); + // Structs can't be defined inside structs, so the type of a struct field can't be a + // nameless struct. + ASSERT(!element->getType().isNamelessStruct()); + AddZeroInitSequence(element, canUseLoopsToInitialize, initSequenceOut, symbolTable); + } +} - if (varInfo.type.isArray()) +void AddArrayZeroInitStatementList(const TIntermTyped *initializedNode, + bool canUseLoopsToInitialize, + TIntermSequence *initSequenceOut, + TSymbolTable *symbolTable) +{ + for (unsigned int i = 0; i < initializedNode->getOutermostArraySize(); ++i) + { + TIntermBinary *element = + new TIntermBinary(EOpIndexDirect, initializedNode->deepCopy(), CreateIndexNode(i)); + AddZeroInitSequence(element, canUseLoopsToInitialize, initSequenceOut, symbolTable); + } +} + +void AddArrayZeroInitForLoop(const TIntermTyped *initializedNode, + TIntermSequence *initSequenceOut, + TSymbolTable *symbolTable) +{ + ASSERT(initializedNode->isArray()); + TSymbolUniqueId indexSymbol(symbolTable); + + TIntermSymbol *indexSymbolNode = CreateTempSymbolNode(indexSymbol, TType(EbtInt), EvqTemporary); + TIntermDeclaration *indexInit = + CreateTempInitDeclarationNode(indexSymbol, CreateZeroNode(TType(EbtInt)), EvqTemporary); + TIntermConstantUnion *arraySizeNode = CreateIndexNode(initializedNode->getOutermostArraySize()); + TIntermBinary *indexSmallerThanSize = + new TIntermBinary(EOpLessThan, indexSymbolNode->deepCopy(), arraySizeNode); + TIntermUnary *indexIncrement = new TIntermUnary(EOpPreIncrement, indexSymbolNode->deepCopy()); + + TIntermBlock *forLoopBody = new TIntermBlock(); + TIntermSequence *forLoopBodySeq = forLoopBody->getSequence(); + + TIntermBinary *element = new TIntermBinary(EOpIndexIndirect, initializedNode->deepCopy(), + indexSymbolNode->deepCopy()); + AddZeroInitSequence(element, true, forLoopBodySeq, symbolTable); + + TIntermLoop *forLoop = + new TIntermLoop(ELoopFor, indexInit, indexSmallerThanSize, indexIncrement, forLoopBody); + initSequenceOut->push_back(forLoop); +} + +void AddArrayZeroInitSequence(const TIntermTyped *initializedNode, + bool canUseLoopsToInitialize, + TIntermSequence *initSequenceOut, + TSymbolTable *symbolTable) +{ + // The array elements are assigned one by one to keep the AST compatible with ESSL 1.00 which + // doesn't have array assignment. We'll do this either with a for loop or just a list of + // statements assigning to each array index. Note that it is important to have the array init in + // the right order to workaround http://crbug.com/709317 + bool isSmallArray = initializedNode->getOutermostArraySize() <= 1u || + (initializedNode->getBasicType() != EbtStruct && + !initializedNode->getType().isArrayOfArrays() && + initializedNode->getOutermostArraySize() <= 3u); + if (initializedNode->getQualifier() == EvqFragData || + initializedNode->getQualifier() == EvqFragmentOut || isSmallArray || + !canUseLoopsToInitialize) + { + // Fragment outputs should not be indexed by non-constant indices. + // Also it doesn't make sense to use loops to initialize very small arrays. + AddArrayZeroInitStatementList(initializedNode, canUseLoopsToInitialize, initSequenceOut, + symbolTable); + } + else + { + AddArrayZeroInitForLoop(initializedNode, initSequenceOut, symbolTable); + } +} + +void InsertInitCode(TIntermSequence *mainBody, + const InitVariableList &variables, + TSymbolTable *symbolTable, + int shaderVersion, + const TExtensionBehavior &extensionBehavior, + bool canUseLoopsToInitialize) +{ + for (const auto &var : variables) + { + TString name = TString(var.name.c_str()); + size_t pos = name.find_last_of('['); + if (pos != TString::npos) { - for (int index = varInfo.type.getArraySize() - 1; index >= 0; --index) + name = name.substr(0, pos); + } + + TIntermTyped *initializedSymbol = nullptr; + if (var.isBuiltIn()) + { + initializedSymbol = ReferenceBuiltInVariable(name, *symbolTable, shaderVersion); + if (initializedSymbol->getQualifier() == EvqFragData && + !IsExtensionEnabled(extensionBehavior, TExtension::EXT_draw_buffers)) { - TIntermBinary *assign = new TIntermBinary(EOpAssign); - sequence->insert(sequence->begin(), assign); - - TIntermBinary *indexDirect = new TIntermBinary(EOpIndexDirect); - TIntermSymbol *symbol = new TIntermSymbol(0, varInfo.name, varInfo.type); - indexDirect->setLeft(symbol); - TIntermConstantUnion *indexNode = constructIndexNode(index); - indexDirect->setRight(indexNode); - - assign->setLeft(indexDirect); - - TIntermConstantUnion *zeroConst = constructFloatConstUnionNode(varInfo.type); - assign->setRight(zeroConst); + // If GL_EXT_draw_buffers is disabled, only the 0th index of gl_FragData can be + // written to. + // TODO(oetuaho): This is a bit hacky and would be better to remove, if we came up + // with a good way to do it. Right now "gl_FragData" in symbol table is initialized + // to have the array size of MaxDrawBuffers, and the initialization happens before + // the shader sets the extensions it is using. + initializedSymbol = + new TIntermBinary(EOpIndexDirect, initializedSymbol, CreateIndexNode(0)); } } else { - TIntermBinary *assign = new TIntermBinary(EOpAssign); - sequence->insert(sequence->begin(), assign); - TIntermSymbol *symbol = new TIntermSymbol(0, varInfo.name, varInfo.type); - assign->setLeft(symbol); - TIntermConstantUnion *zeroConst = constructFloatConstUnionNode(varInfo.type); - assign->setRight(zeroConst); + initializedSymbol = ReferenceGlobalVariable(name, *symbolTable); } + ASSERT(initializedSymbol != nullptr); + TIntermSequence *initCode = + CreateInitCode(initializedSymbol, canUseLoopsToInitialize, symbolTable); + mainBody->insert(mainBody->begin(), initCode->begin(), initCode->end()); } } +class InitializeLocalsTraverser : public TIntermTraverser +{ + public: + InitializeLocalsTraverser(int shaderVersion, + TSymbolTable *symbolTable, + bool canUseLoopsToInitialize) + : TIntermTraverser(true, false, false, symbolTable), + mShaderVersion(shaderVersion), + mCanUseLoopsToInitialize(canUseLoopsToInitialize) + { + } + + protected: + bool visitDeclaration(Visit visit, TIntermDeclaration *node) override + { + for (TIntermNode *declarator : *node->getSequence()) + { + if (!mInGlobalScope && !declarator->getAsBinaryNode()) + { + TIntermSymbol *symbol = declarator->getAsSymbolNode(); + ASSERT(symbol); + if (symbol->getSymbol() == "") + { + continue; + } + + // Arrays may need to be initialized one element at a time, since ESSL 1.00 does not + // support array constructors or assigning arrays. + bool arrayConstructorUnavailable = + (symbol->isArray() || symbol->getType().isStructureContainingArrays()) && + mShaderVersion == 100; + // Nameless struct constructors can't be referred to, so they also need to be + // initialized one element at a time. + // TODO(oetuaho): Check if it makes sense to initialize using a loop, even if we + // could use an initializer. It could at least reduce code size for very large + // arrays, but could hurt runtime performance. + if (arrayConstructorUnavailable || symbol->getType().isNamelessStruct()) + { + // SimplifyLoopConditions should have been run so the parent node of this node + // should not be a loop. + ASSERT(getParentNode()->getAsLoopNode() == nullptr); + // SeparateDeclarations should have already been run, so we don't need to worry + // about further declarators in this declaration depending on the effects of + // this declarator. + ASSERT(node->getSequence()->size() == 1); + insertStatementsInParentBlock( + TIntermSequence(), + *CreateInitCode(symbol, mCanUseLoopsToInitialize, mSymbolTable)); + } + else + { + TIntermBinary *init = + new TIntermBinary(EOpInitialize, symbol, CreateZeroNode(symbol->getType())); + queueReplacementWithParent(node, symbol, init, OriginalNode::BECOMES_CHILD); + } + } + } + return false; + } + + private: + int mShaderVersion; + bool mCanUseLoopsToInitialize; +}; + +} // namespace anonymous + +TIntermSequence *CreateInitCode(const TIntermTyped *initializedSymbol, + bool canUseLoopsToInitialize, + TSymbolTable *symbolTable) +{ + TIntermSequence *initCode = new TIntermSequence(); + AddZeroInitSequence(initializedSymbol, canUseLoopsToInitialize, initCode, symbolTable); + return initCode; +} + +void InitializeUninitializedLocals(TIntermBlock *root, + int shaderVersion, + bool canUseLoopsToInitialize, + TSymbolTable *symbolTable) +{ + InitializeLocalsTraverser traverser(shaderVersion, symbolTable, canUseLoopsToInitialize); + root->traverse(&traverser); + traverser.updateTree(); +} + +void InitializeVariables(TIntermBlock *root, + const InitVariableList &vars, + TSymbolTable *symbolTable, + int shaderVersion, + const TExtensionBehavior &extensionBehavior, + bool canUseLoopsToInitialize) +{ + TIntermBlock *body = FindMainBody(root); + InsertInitCode(body->getSequence(), vars, symbolTable, shaderVersion, extensionBehavior, + canUseLoopsToInitialize); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/InitializeVariables.h b/src/3rdparty/angle/src/compiler/translator/InitializeVariables.h index 2a141ec91c..1a7b3c0f24 100644 --- a/src/3rdparty/angle/src/compiler/translator/InitializeVariables.h +++ b/src/3rdparty/angle/src/compiler/translator/InitializeVariables.h @@ -7,45 +7,47 @@ #ifndef COMPILER_TRANSLATOR_INITIALIZEVARIABLES_H_ #define COMPILER_TRANSLATOR_INITIALIZEVARIABLES_H_ +#include + +#include "compiler/translator/ExtensionBehavior.h" #include "compiler/translator/IntermNode.h" -class InitializeVariables : public TIntermTraverser +namespace sh { - public: - struct InitVariableInfo - { - TString name; - TType type; +class TSymbolTable; - InitVariableInfo(const TString &_name, const TType &_type) - : name(_name), - type(_type) - { - } - }; - typedef TVector InitVariableInfoList; +typedef std::vector InitVariableList; - InitializeVariables(const InitVariableInfoList &vars) - : TIntermTraverser(true, false, false), - mVariables(vars), - mCodeInserted(false) - { - } +// For all of the functions below: If canUseLoopsToInitialize is set, for loops are used instead of +// a large number of initializers where it can make sense, such as for initializing large arrays. - protected: - bool visitBinary(Visit, TIntermBinary *node) override { return false; } - bool visitUnary(Visit, TIntermUnary *node) override { return false; } - bool visitSelection(Visit, TIntermSelection *node) override { return false; } - bool visitLoop(Visit, TIntermLoop *node) override { return false; } - bool visitBranch(Visit, TIntermBranch *node) override { return false; } +// Return a sequence of assignment operations to initialize "initializedSymbol". initializedSymbol +// may be an array, struct or any combination of these, as long as it contains only basic types. +TIntermSequence *CreateInitCode(const TIntermTyped *initializedSymbol, + bool canUseLoopsToInitialize, + TSymbolTable *symbolTable); - bool visitAggregate(Visit visit, TIntermAggregate *node) override; +// Initialize all uninitialized local variables, so that undefined behavior is avoided. +void InitializeUninitializedLocals(TIntermBlock *root, + int shaderVersion, + bool canUseLoopsToInitialize, + TSymbolTable *symbolTable); - private: - void insertInitCode(TIntermSequence *sequence); +// This function can initialize all the types that CreateInitCode is able to initialize. All +// variables must be globals which can be found in the symbol table. For now it is used for the +// following two scenarios: +// 1. Initializing gl_Position; +// 2. Initializing output variables referred to in the shader source. +// Note: The type of each lvalue in an initializer is retrieved from the symbol table. gl_FragData +// requires special handling because the number of indices which can be initialized is determined by +// enabled extensions. +void InitializeVariables(TIntermBlock *root, + const InitVariableList &vars, + TSymbolTable *symbolTable, + int shaderVersion, + const TExtensionBehavior &extensionBehavior, + bool canUseLoopsToInitialize); - InitVariableInfoList mVariables; - bool mCodeInserted; -}; +} // namespace sh #endif // COMPILER_TRANSLATOR_INITIALIZEVARIABLES_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/IntermNode.cpp b/src/3rdparty/angle/src/compiler/translator/IntermNode.cpp index 2a92860088..a57ffcb4bc 100644 --- a/src/3rdparty/angle/src/compiler/translator/IntermNode.cpp +++ b/src/3rdparty/angle/src/compiler/translator/IntermNode.cpp @@ -17,14 +17,18 @@ #include "common/mathutil.h" #include "common/matrix_utils.h" -#include "compiler/translator/HashNames.h" +#include "compiler/translator/Diagnostics.h" #include "compiler/translator/IntermNode.h" #include "compiler/translator/SymbolTable.h" +#include "compiler/translator/util.h" + +namespace sh +{ namespace { -const float kPi = 3.14159265358979323846f; +const float kPi = 3.14159265358979323846f; const float kDegreesToRadiansMultiplier = kPi / 180.0f; const float kRadiansToDegreesMultiplier = 180.0f / kPi; @@ -33,72 +37,40 @@ TPrecision GetHigherPrecision(TPrecision left, TPrecision right) return left > right ? left : right; } -bool ValidateMultiplication(TOperator op, const TType &left, const TType &right) -{ - switch (op) - { - case EOpMul: - case EOpMulAssign: - return left.getNominalSize() == right.getNominalSize() && - left.getSecondarySize() == right.getSecondarySize(); - case EOpVectorTimesScalar: - case EOpVectorTimesScalarAssign: - return true; - case EOpVectorTimesMatrix: - return left.getNominalSize() == right.getRows(); - case EOpVectorTimesMatrixAssign: - return left.getNominalSize() == right.getRows() && - left.getNominalSize() == right.getCols(); - case EOpMatrixTimesVector: - return left.getCols() == right.getNominalSize(); - case EOpMatrixTimesScalar: - case EOpMatrixTimesScalarAssign: - return true; - case EOpMatrixTimesMatrix: - return left.getCols() == right.getRows(); - case EOpMatrixTimesMatrixAssign: - return left.getCols() == right.getCols() && - left.getRows() == right.getRows(); - - default: - UNREACHABLE(); - return false; - } -} - TConstantUnion *Vectorize(const TConstantUnion &constant, size_t size) { TConstantUnion *constUnion = new TConstantUnion[size]; for (unsigned int i = 0; i < size; ++i) - constUnion[i] = constant; + constUnion[i] = constant; return constUnion; } -void UndefinedConstantFoldingError(const TSourceLoc &loc, TOperator op, TBasicType basicType, - TInfoSink &infoSink, TConstantUnion *result) +void UndefinedConstantFoldingError(const TSourceLoc &loc, + TOperator op, + TBasicType basicType, + TDiagnostics *diagnostics, + TConstantUnion *result) { - std::stringstream constantFoldingErrorStream; - constantFoldingErrorStream << "'" << GetOperatorString(op) - << "' operation result is undefined for the values passed in"; - infoSink.info.message(EPrefixWarning, loc, constantFoldingErrorStream.str().c_str()); + diagnostics->warning(loc, "operation result is undefined for the values passed in", + GetOperatorString(op)); switch (basicType) { - case EbtFloat : - result->setFConst(0.0f); - break; - case EbtInt: - result->setIConst(0); - break; - case EbtUInt: - result->setUConst(0u); - break; - case EbtBool: - result->setBConst(false); - break; - default: - break; + case EbtFloat: + result->setFConst(0.0f); + break; + case EbtInt: + result->setIConst(0); + break; + case EbtUInt: + result->setUConst(0u); + break; + case EbtBool: + result->setBConst(false); + break; + default: + break; } } @@ -123,7 +95,7 @@ float VectorDotProduct(const TConstantUnion *paramArray1, return result; } -TIntermTyped *CreateFoldedNode(TConstantUnion *constArray, +TIntermTyped *CreateFoldedNode(const TConstantUnion *constArray, const TIntermTyped *originalNode, TQualifier qualifier) { @@ -145,8 +117,9 @@ angle::Matrix GetMatrix(const TConstantUnion *paramArray, for (size_t i = 0; i < rows * cols; i++) elements.push_back(paramArray[i].getFConst()); // Transpose is used since the Matrix constructor expects arguments in row-major order, - // whereas the paramArray is in column-major order. - return angle::Matrix(elements, rows, cols).transpose(); + // whereas the paramArray is in column-major order. Rows/cols parameters are also flipped below + // so that the created matrix will have the expected dimensions after the transpose. + return angle::Matrix(elements, cols, rows).transpose(); } angle::Matrix GetMatrix(const TConstantUnion *paramArray, const unsigned int &size) @@ -163,7 +136,7 @@ void SetUnionArrayFromMatrix(const angle::Matrix &m, TConstantUnion *resu { // Transpose is used since the input Matrix is in row-major order, // whereas the actual result should be in column-major order. - angle::Matrix result = m.transpose(); + angle::Matrix result = m.transpose(); std::vector resultElements = result.elements(); for (size_t i = 0; i < resultElements.size(); i++) resultArray[i].setFConst(resultElements[i]); @@ -171,7 +144,6 @@ void SetUnionArrayFromMatrix(const angle::Matrix &m, TConstantUnion *resu } // namespace anonymous - //////////////////////////////////////////////////////////////// // // Member functions of the nodes used for building the tree. @@ -181,90 +153,214 @@ void SetUnionArrayFromMatrix(const angle::Matrix &m, TConstantUnion *resu void TIntermTyped::setTypePreservePrecision(const TType &t) { TPrecision precision = getPrecision(); - mType = t; + mType = t; ASSERT(mType.getBasicType() != EbtBool || precision == EbpUndefined); mType.setPrecision(precision); } #define REPLACE_IF_IS(node, type, original, replacement) \ - if (node == original) { \ - node = static_cast(replacement); \ - return true; \ + if (node == original) \ + { \ + node = static_cast(replacement); \ + return true; \ } -bool TIntermLoop::replaceChildNode( - TIntermNode *original, TIntermNode *replacement) +bool TIntermLoop::replaceChildNode(TIntermNode *original, TIntermNode *replacement) { + ASSERT(original != nullptr); // This risks replacing multiple children. REPLACE_IF_IS(mInit, TIntermNode, original, replacement); REPLACE_IF_IS(mCond, TIntermTyped, original, replacement); REPLACE_IF_IS(mExpr, TIntermTyped, original, replacement); - REPLACE_IF_IS(mBody, TIntermAggregate, original, replacement); + REPLACE_IF_IS(mBody, TIntermBlock, original, replacement); return false; } -bool TIntermBranch::replaceChildNode( - TIntermNode *original, TIntermNode *replacement) +bool TIntermBranch::replaceChildNode(TIntermNode *original, TIntermNode *replacement) { REPLACE_IF_IS(mExpression, TIntermTyped, original, replacement); return false; } -bool TIntermBinary::replaceChildNode( - TIntermNode *original, TIntermNode *replacement) +bool TIntermSwizzle::replaceChildNode(TIntermNode *original, TIntermNode *replacement) +{ + ASSERT(original->getAsTyped()->getType() == replacement->getAsTyped()->getType()); + REPLACE_IF_IS(mOperand, TIntermTyped, original, replacement); + return false; +} + +bool TIntermBinary::replaceChildNode(TIntermNode *original, TIntermNode *replacement) { REPLACE_IF_IS(mLeft, TIntermTyped, original, replacement); REPLACE_IF_IS(mRight, TIntermTyped, original, replacement); return false; } -bool TIntermUnary::replaceChildNode( - TIntermNode *original, TIntermNode *replacement) +bool TIntermUnary::replaceChildNode(TIntermNode *original, TIntermNode *replacement) { + ASSERT(original->getAsTyped()->getType() == replacement->getAsTyped()->getType()); REPLACE_IF_IS(mOperand, TIntermTyped, original, replacement); return false; } -bool TIntermAggregate::replaceChildNode( - TIntermNode *original, TIntermNode *replacement) +bool TIntermInvariantDeclaration::replaceChildNode(TIntermNode *original, TIntermNode *replacement) { - for (size_t ii = 0; ii < mSequence.size(); ++ii) + REPLACE_IF_IS(mSymbol, TIntermSymbol, original, replacement); + return false; +} + +bool TIntermFunctionDefinition::replaceChildNode(TIntermNode *original, TIntermNode *replacement) +{ + REPLACE_IF_IS(mPrototype, TIntermFunctionPrototype, original, replacement); + REPLACE_IF_IS(mBody, TIntermBlock, original, replacement); + return false; +} + +bool TIntermAggregate::replaceChildNode(TIntermNode *original, TIntermNode *replacement) +{ + return replaceChildNodeInternal(original, replacement); +} + +bool TIntermBlock::replaceChildNode(TIntermNode *original, TIntermNode *replacement) +{ + return replaceChildNodeInternal(original, replacement); +} + +bool TIntermFunctionPrototype::replaceChildNode(TIntermNode *original, TIntermNode *replacement) +{ + return replaceChildNodeInternal(original, replacement); +} + +bool TIntermDeclaration::replaceChildNode(TIntermNode *original, TIntermNode *replacement) +{ + return replaceChildNodeInternal(original, replacement); +} + +bool TIntermAggregateBase::replaceChildNodeInternal(TIntermNode *original, TIntermNode *replacement) +{ + for (size_t ii = 0; ii < getSequence()->size(); ++ii) { - REPLACE_IF_IS(mSequence[ii], TIntermNode, original, replacement); + REPLACE_IF_IS((*getSequence())[ii], TIntermNode, original, replacement); } return false; } -bool TIntermAggregate::replaceChildNodeWithMultiple(TIntermNode *original, TIntermSequence replacements) +bool TIntermAggregateBase::replaceChildNodeWithMultiple(TIntermNode *original, + const TIntermSequence &replacements) { - for (auto it = mSequence.begin(); it < mSequence.end(); ++it) + for (auto it = getSequence()->begin(); it < getSequence()->end(); ++it) { if (*it == original) { - it = mSequence.erase(it); - mSequence.insert(it, replacements.begin(), replacements.end()); + it = getSequence()->erase(it); + getSequence()->insert(it, replacements.begin(), replacements.end()); return true; } } return false; } -bool TIntermAggregate::insertChildNodes(TIntermSequence::size_type position, TIntermSequence insertions) +bool TIntermAggregateBase::insertChildNodes(TIntermSequence::size_type position, + const TIntermSequence &insertions) { - if (position > mSequence.size()) + if (position > getSequence()->size()) { return false; } - auto it = mSequence.begin() + position; - mSequence.insert(it, insertions.begin(), insertions.end()); + auto it = getSequence()->begin() + position; + getSequence()->insert(it, insertions.begin(), insertions.end()); return true; } +TIntermAggregate *TIntermAggregate::CreateFunctionCall(const TFunction &func, + TIntermSequence *arguments) +{ + TIntermAggregate *callNode = + new TIntermAggregate(func.getReturnType(), EOpCallFunctionInAST, arguments); + callNode->getFunctionSymbolInfo()->setFromFunction(func); + return callNode; +} + +TIntermAggregate *TIntermAggregate::CreateFunctionCall(const TType &type, + const TSymbolUniqueId &id, + const TName &name, + TIntermSequence *arguments) +{ + TIntermAggregate *callNode = new TIntermAggregate(type, EOpCallFunctionInAST, arguments); + callNode->getFunctionSymbolInfo()->setId(id); + callNode->getFunctionSymbolInfo()->setNameObj(name); + return callNode; +} + +TIntermAggregate *TIntermAggregate::CreateBuiltInFunctionCall(const TFunction &func, + TIntermSequence *arguments) +{ + TIntermAggregate *callNode = + new TIntermAggregate(func.getReturnType(), EOpCallBuiltInFunction, arguments); + callNode->getFunctionSymbolInfo()->setFromFunction(func); + // Note that name needs to be set before texture function type is determined. + callNode->setBuiltInFunctionPrecision(); + return callNode; +} + +TIntermAggregate *TIntermAggregate::CreateConstructor(const TType &type, + TIntermSequence *arguments) +{ + return new TIntermAggregate(type, EOpConstruct, arguments); +} + +TIntermAggregate *TIntermAggregate::Create(const TType &type, + TOperator op, + TIntermSequence *arguments) +{ + TIntermAggregate *node = new TIntermAggregate(type, op, arguments); + ASSERT(op != EOpCallFunctionInAST); // Should use CreateFunctionCall + ASSERT(op != EOpCallBuiltInFunction); // Should use CreateBuiltInFunctionCall + ASSERT(!node->isConstructor()); // Should use CreateConstructor + return node; +} + +TIntermAggregate::TIntermAggregate(const TType &type, TOperator op, TIntermSequence *arguments) + : TIntermOperator(op), mUseEmulatedFunction(false), mGotPrecisionFromChildren(false) +{ + if (arguments != nullptr) + { + mArguments.swap(*arguments); + } + setTypePrecisionAndQualifier(type); +} + +void TIntermAggregate::setTypePrecisionAndQualifier(const TType &type) +{ + setType(type); + mType.setQualifier(EvqTemporary); + if (!isFunctionCall()) + { + if (isConstructor()) + { + // Structs should not be precision qualified, the individual members may be. + // Built-in types on the other hand should be precision qualified. + if (getBasicType() != EbtStruct) + { + setPrecisionFromChildren(); + } + } + else + { + setPrecisionForBuiltInOp(); + } + if (areChildrenConstQualified()) + { + mType.setQualifier(EvqConst); + } + } +} + bool TIntermAggregate::areChildrenConstQualified() { - for (TIntermNode *&child : mSequence) + for (TIntermNode *&arg : mArguments) { - TIntermTyped *typed = child->getAsTyped(); - if (typed && typed->getQualifier() != EvqConst) + TIntermTyped *typedArg = arg->getAsTyped(); + if (typedArg && typedArg->getQualifier() != EvqConst) { return false; } @@ -281,9 +377,9 @@ void TIntermAggregate::setPrecisionFromChildren() return; } - TPrecision precision = EbpUndefined; - TIntermSequence::iterator childIter = mSequence.begin(); - while (childIter != mSequence.end()) + TPrecision precision = EbpUndefined; + TIntermSequence::iterator childIter = mArguments.begin(); + while (childIter != mArguments.end()) { TIntermTyped *typed = (*childIter)->getAsTyped(); if (typed) @@ -293,51 +389,149 @@ void TIntermAggregate::setPrecisionFromChildren() mType.setPrecision(precision); } +void TIntermAggregate::setPrecisionForBuiltInOp() +{ + ASSERT(!isConstructor()); + ASSERT(!isFunctionCall()); + if (!setPrecisionForSpecialBuiltInOp()) + { + setPrecisionFromChildren(); + } +} + +bool TIntermAggregate::setPrecisionForSpecialBuiltInOp() +{ + switch (mOp) + { + case EOpBitfieldExtract: + mType.setPrecision(mArguments[0]->getAsTyped()->getPrecision()); + mGotPrecisionFromChildren = true; + return true; + case EOpBitfieldInsert: + mType.setPrecision(GetHigherPrecision(mArguments[0]->getAsTyped()->getPrecision(), + mArguments[1]->getAsTyped()->getPrecision())); + mGotPrecisionFromChildren = true; + return true; + case EOpUaddCarry: + case EOpUsubBorrow: + mType.setPrecision(EbpHigh); + return true; + default: + return false; + } +} + void TIntermAggregate::setBuiltInFunctionPrecision() { // All built-ins returning bool should be handled as ops, not functions. ASSERT(getBasicType() != EbtBool); + ASSERT(mOp == EOpCallBuiltInFunction); TPrecision precision = EbpUndefined; - TIntermSequence::iterator childIter = mSequence.begin(); - while (childIter != mSequence.end()) + for (TIntermNode *arg : mArguments) { - TIntermTyped *typed = (*childIter)->getAsTyped(); + TIntermTyped *typed = arg->getAsTyped(); // ESSL spec section 8: texture functions get their precision from the sampler. if (typed && IsSampler(typed->getBasicType())) { precision = typed->getPrecision(); break; } - ++childIter; } // ESSL 3.0 spec section 8: textureSize always gets highp precision. // All other functions that take a sampler are assumed to be texture functions. - if (mName.getString().find("textureSize") == 0) + if (mFunctionInfo.getName().find("textureSize") == 0) mType.setPrecision(EbpHigh); else mType.setPrecision(precision); } -bool TIntermSelection::replaceChildNode( - TIntermNode *original, TIntermNode *replacement) +TString TIntermAggregate::getSymbolTableMangledName() const +{ + ASSERT(!isConstructor()); + switch (mOp) + { + case EOpCallInternalRawFunction: + case EOpCallBuiltInFunction: + case EOpCallFunctionInAST: + return TFunction::GetMangledNameFromCall(mFunctionInfo.getName(), mArguments); + default: + TString opString = GetOperatorString(mOp); + return TFunction::GetMangledNameFromCall(opString, mArguments); + } +} + +bool TIntermAggregate::hasSideEffects() const +{ + if (isFunctionCall() && mFunctionInfo.isKnownToNotHaveSideEffects()) + { + for (TIntermNode *arg : mArguments) + { + if (arg->getAsTyped()->hasSideEffects()) + { + return true; + } + } + return false; + } + // Conservatively assume most aggregate operators have side-effects + return true; +} + +void TIntermBlock::appendStatement(TIntermNode *statement) +{ + // Declaration nodes with no children can appear if it was an empty declaration or if all the + // declarators just added constants to the symbol table instead of generating code. We still + // need to add the declaration to the AST in that case because it might be relevant to the + // validity of switch/case. + if (statement != nullptr) + { + mStatements.push_back(statement); + } +} + +void TIntermFunctionPrototype::appendParameter(TIntermSymbol *parameter) +{ + ASSERT(parameter != nullptr); + mParameters.push_back(parameter); +} + +void TIntermDeclaration::appendDeclarator(TIntermTyped *declarator) +{ + ASSERT(declarator != nullptr); + ASSERT(declarator->getAsSymbolNode() != nullptr || + (declarator->getAsBinaryNode() != nullptr && + declarator->getAsBinaryNode()->getOp() == EOpInitialize)); + ASSERT(mDeclarators.empty() || + declarator->getType().sameNonArrayType(mDeclarators.back()->getAsTyped()->getType())); + mDeclarators.push_back(declarator); +} + +bool TIntermTernary::replaceChildNode(TIntermNode *original, TIntermNode *replacement) { REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement); - REPLACE_IF_IS(mTrueBlock, TIntermNode, original, replacement); - REPLACE_IF_IS(mFalseBlock, TIntermNode, original, replacement); + REPLACE_IF_IS(mTrueExpression, TIntermTyped, original, replacement); + REPLACE_IF_IS(mFalseExpression, TIntermTyped, original, replacement); return false; } -bool TIntermSwitch::replaceChildNode( - TIntermNode *original, TIntermNode *replacement) +bool TIntermIfElse::replaceChildNode(TIntermNode *original, TIntermNode *replacement) +{ + REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement); + REPLACE_IF_IS(mTrueBlock, TIntermBlock, original, replacement); + REPLACE_IF_IS(mFalseBlock, TIntermBlock, original, replacement); + return false; +} + +bool TIntermSwitch::replaceChildNode(TIntermNode *original, TIntermNode *replacement) { REPLACE_IF_IS(mInit, TIntermTyped, original, replacement); - REPLACE_IF_IS(mStatementList, TIntermAggregate, original, replacement); + REPLACE_IF_IS(mStatementList, TIntermBlock, original, replacement); + ASSERT(mStatementList); return false; } -bool TIntermCase::replaceChildNode( - TIntermNode *original, TIntermNode *replacement) +bool TIntermCase::replaceChildNode(TIntermNode *original, TIntermNode *replacement) { REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement); return false; @@ -351,28 +545,104 @@ TIntermTyped::TIntermTyped(const TIntermTyped &node) : TIntermNode(), mType(node mLine = node.mLine; } +bool TIntermTyped::isConstructorWithOnlyConstantUnionParameters() +{ + TIntermAggregate *constructor = getAsAggregate(); + if (!constructor || !constructor->isConstructor()) + { + return false; + } + for (TIntermNode *&node : *constructor->getSequence()) + { + if (!node->getAsConstantUnion()) + return false; + } + return true; +} + TIntermConstantUnion::TIntermConstantUnion(const TIntermConstantUnion &node) : TIntermTyped(node) { mUnionArrayPointer = node.mUnionArrayPointer; } +void TFunctionSymbolInfo::setFromFunction(const TFunction &function) +{ + setName(function.getName()); + setId(TSymbolUniqueId(function)); +} + +TFunctionSymbolInfo::TFunctionSymbolInfo(const TSymbolUniqueId &id) + : mId(new TSymbolUniqueId(id)), mKnownToNotHaveSideEffects(false) +{ +} + +TFunctionSymbolInfo::TFunctionSymbolInfo(const TFunctionSymbolInfo &info) + : mName(info.mName), mId(nullptr), mKnownToNotHaveSideEffects(info.mKnownToNotHaveSideEffects) +{ + if (info.mId) + { + mId = new TSymbolUniqueId(*info.mId); + } +} + +TFunctionSymbolInfo &TFunctionSymbolInfo::operator=(const TFunctionSymbolInfo &info) +{ + mName = info.mName; + if (info.mId) + { + mId = new TSymbolUniqueId(*info.mId); + } + else + { + mId = nullptr; + } + return *this; +} + +void TFunctionSymbolInfo::setId(const TSymbolUniqueId &id) +{ + mId = new TSymbolUniqueId(id); +} + +const TSymbolUniqueId &TFunctionSymbolInfo::getId() const +{ + ASSERT(mId); + return *mId; +} + TIntermAggregate::TIntermAggregate(const TIntermAggregate &node) : TIntermOperator(node), - mName(node.mName), - mUserDefined(node.mUserDefined), - mFunctionId(node.mFunctionId), mUseEmulatedFunction(node.mUseEmulatedFunction), - mGotPrecisionFromChildren(node.mGotPrecisionFromChildren) + mGotPrecisionFromChildren(node.mGotPrecisionFromChildren), + mFunctionInfo(node.mFunctionInfo) { - for (TIntermNode *child : node.mSequence) + for (TIntermNode *arg : node.mArguments) { - TIntermTyped *typedChild = child->getAsTyped(); - ASSERT(typedChild != nullptr); - TIntermTyped *childCopy = typedChild->deepCopy(); - mSequence.push_back(childCopy); + TIntermTyped *typedArg = arg->getAsTyped(); + ASSERT(typedArg != nullptr); + TIntermTyped *argCopy = typedArg->deepCopy(); + mArguments.push_back(argCopy); } } +TIntermAggregate *TIntermAggregate::shallowCopy() const +{ + TIntermSequence *copySeq = new TIntermSequence(); + copySeq->insert(copySeq->begin(), getSequence()->begin(), getSequence()->end()); + TIntermAggregate *copyNode = new TIntermAggregate(mType, mOp, copySeq); + *copyNode->getFunctionSymbolInfo() = mFunctionInfo; + copyNode->setLine(mLine); + return copyNode; +} + +TIntermSwizzle::TIntermSwizzle(const TIntermSwizzle &node) : TIntermTyped(node) +{ + TIntermTyped *operandCopy = node.mOperand->deepCopy(); + ASSERT(operandCopy != nullptr); + mOperand = operandCopy; + mSwizzleOffsets = node.mSwizzleOffsets; +} + TIntermBinary::TIntermBinary(const TIntermBinary &node) : TIntermOperator(node), mAddIndexClamp(node.mAddIndexClamp) { @@ -391,106 +661,141 @@ TIntermUnary::TIntermUnary(const TIntermUnary &node) mOperand = operandCopy; } -TIntermSelection::TIntermSelection(const TIntermSelection &node) : TIntermTyped(node) +TIntermTernary::TIntermTernary(const TIntermTernary &node) : TIntermTyped(node) { - // Only supported for ternary nodes, not if statements. - TIntermTyped *trueTyped = node.mTrueBlock->getAsTyped(); - TIntermTyped *falseTyped = node.mFalseBlock->getAsTyped(); - ASSERT(trueTyped != nullptr); - ASSERT(falseTyped != nullptr); TIntermTyped *conditionCopy = node.mCondition->deepCopy(); - TIntermTyped *trueCopy = trueTyped->deepCopy(); - TIntermTyped *falseCopy = falseTyped->deepCopy(); + TIntermTyped *trueCopy = node.mTrueExpression->deepCopy(); + TIntermTyped *falseCopy = node.mFalseExpression->deepCopy(); ASSERT(conditionCopy != nullptr && trueCopy != nullptr && falseCopy != nullptr); - mCondition = conditionCopy; - mTrueBlock = trueCopy; - mFalseBlock = falseCopy; + mCondition = conditionCopy; + mTrueExpression = trueCopy; + mFalseExpression = falseCopy; } -// -// Say whether or not an operation node changes the value of a variable. -// bool TIntermOperator::isAssignment() const { - switch (mOp) - { - case EOpPostIncrement: - case EOpPostDecrement: - case EOpPreIncrement: - case EOpPreDecrement: - case EOpAssign: - case EOpAddAssign: - case EOpSubAssign: - case EOpMulAssign: - case EOpVectorTimesMatrixAssign: - case EOpVectorTimesScalarAssign: - case EOpMatrixTimesScalarAssign: - case EOpMatrixTimesMatrixAssign: - case EOpDivAssign: - case EOpIModAssign: - case EOpBitShiftLeftAssign: - case EOpBitShiftRightAssign: - case EOpBitwiseAndAssign: - case EOpBitwiseXorAssign: - case EOpBitwiseOrAssign: - return true; - default: - return false; - } + return IsAssignment(mOp); } bool TIntermOperator::isMultiplication() const { switch (mOp) { - case EOpMul: - case EOpMatrixTimesMatrix: - case EOpMatrixTimesVector: - case EOpMatrixTimesScalar: - case EOpVectorTimesMatrix: - case EOpVectorTimesScalar: - return true; - default: - return false; + case EOpMul: + case EOpMatrixTimesMatrix: + case EOpMatrixTimesVector: + case EOpMatrixTimesScalar: + case EOpVectorTimesMatrix: + case EOpVectorTimesScalar: + return true; + default: + return false; } } -// -// returns true if the operator is for one of the constructors -// bool TIntermOperator::isConstructor() const +{ + return (mOp == EOpConstruct); +} + +bool TIntermOperator::isFunctionCall() const { switch (mOp) { - case EOpConstructVec2: - case EOpConstructVec3: - case EOpConstructVec4: - case EOpConstructMat2: - case EOpConstructMat2x3: - case EOpConstructMat2x4: - case EOpConstructMat3x2: - case EOpConstructMat3: - case EOpConstructMat3x4: - case EOpConstructMat4x2: - case EOpConstructMat4x3: - case EOpConstructMat4: - case EOpConstructFloat: - case EOpConstructIVec2: - case EOpConstructIVec3: - case EOpConstructIVec4: - case EOpConstructInt: - case EOpConstructUVec2: - case EOpConstructUVec3: - case EOpConstructUVec4: - case EOpConstructUInt: - case EOpConstructBVec2: - case EOpConstructBVec3: - case EOpConstructBVec4: - case EOpConstructBool: - case EOpConstructStruct: - return true; - default: - return false; + case EOpCallFunctionInAST: + case EOpCallBuiltInFunction: + case EOpCallInternalRawFunction: + return true; + default: + return false; + } +} + +TOperator TIntermBinary::GetMulOpBasedOnOperands(const TType &left, const TType &right) +{ + if (left.isMatrix()) + { + if (right.isMatrix()) + { + return EOpMatrixTimesMatrix; + } + else + { + if (right.isVector()) + { + return EOpMatrixTimesVector; + } + else + { + return EOpMatrixTimesScalar; + } + } + } + else + { + if (right.isMatrix()) + { + if (left.isVector()) + { + return EOpVectorTimesMatrix; + } + else + { + return EOpMatrixTimesScalar; + } + } + else + { + // Neither operand is a matrix. + if (left.isVector() == right.isVector()) + { + // Leave as component product. + return EOpMul; + } + else + { + return EOpVectorTimesScalar; + } + } + } +} + +TOperator TIntermBinary::GetMulAssignOpBasedOnOperands(const TType &left, const TType &right) +{ + if (left.isMatrix()) + { + if (right.isMatrix()) + { + return EOpMatrixTimesMatrixAssign; + } + else + { + // right should be scalar, but this may not be validated yet. + return EOpMatrixTimesScalarAssign; + } + } + else + { + if (right.isMatrix()) + { + // Left should be a vector, but this may not be validated yet. + return EOpVectorTimesMatrixAssign; + } + else + { + // Neither operand is a matrix. + if (left.isVector() == right.isVector()) + { + // Leave as component product. + return EOpMulAssign; + } + else + { + // left should be vector and right should be scalar, but this may not be validated + // yet. + return EOpVectorTimesScalarAssign; + } + } } } @@ -498,70 +803,281 @@ bool TIntermOperator::isConstructor() const // Make sure the type of a unary operator is appropriate for its // combination of operation and operand type. // -void TIntermUnary::promote(const TType *funcReturnType) +void TIntermUnary::promote() { - switch (mOp) + if (mOp == EOpArrayLength) { - case EOpFloatBitsToInt: - case EOpFloatBitsToUint: - case EOpIntBitsToFloat: - case EOpUintBitsToFloat: - case EOpPackSnorm2x16: - case EOpPackUnorm2x16: - case EOpPackHalf2x16: - case EOpUnpackSnorm2x16: - case EOpUnpackUnorm2x16: - mType.setPrecision(EbpHigh); - break; - case EOpUnpackHalf2x16: - mType.setPrecision(EbpMedium); - break; - default: - setType(mOperand->getType()); + // Special case: the qualifier of .length() doesn't depend on the operand qualifier. + setType(TType(EbtInt, EbpUndefined, EvqConst)); + return; } - if (funcReturnType != nullptr) + TQualifier resultQualifier = EvqTemporary; + if (mOperand->getQualifier() == EvqConst) + resultQualifier = EvqConst; + + unsigned char operandPrimarySize = + static_cast(mOperand->getType().getNominalSize()); + switch (mOp) { - if (funcReturnType->getBasicType() == EbtBool) + case EOpFloatBitsToInt: + setType(TType(EbtInt, EbpHigh, resultQualifier, operandPrimarySize)); + break; + case EOpFloatBitsToUint: + setType(TType(EbtUInt, EbpHigh, resultQualifier, operandPrimarySize)); + break; + case EOpIntBitsToFloat: + case EOpUintBitsToFloat: + setType(TType(EbtFloat, EbpHigh, resultQualifier, operandPrimarySize)); + break; + case EOpPackSnorm2x16: + case EOpPackUnorm2x16: + case EOpPackHalf2x16: + case EOpPackUnorm4x8: + case EOpPackSnorm4x8: + setType(TType(EbtUInt, EbpHigh, resultQualifier)); + break; + case EOpUnpackSnorm2x16: + case EOpUnpackUnorm2x16: + setType(TType(EbtFloat, EbpHigh, resultQualifier, 2)); + break; + case EOpUnpackHalf2x16: + setType(TType(EbtFloat, EbpMedium, resultQualifier, 2)); + break; + case EOpUnpackUnorm4x8: + case EOpUnpackSnorm4x8: + setType(TType(EbtFloat, EbpMedium, resultQualifier, 4)); + break; + case EOpAny: + case EOpAll: + setType(TType(EbtBool, EbpUndefined, resultQualifier)); + break; + case EOpLength: + case EOpDeterminant: + setType(TType(EbtFloat, mOperand->getType().getPrecision(), resultQualifier)); + break; + case EOpTranspose: + setType(TType(EbtFloat, mOperand->getType().getPrecision(), resultQualifier, + static_cast(mOperand->getType().getRows()), + static_cast(mOperand->getType().getCols()))); + break; + case EOpIsInf: + case EOpIsNan: + setType(TType(EbtBool, EbpUndefined, resultQualifier, operandPrimarySize)); + break; + case EOpBitfieldReverse: + setType(TType(mOperand->getBasicType(), EbpHigh, resultQualifier, operandPrimarySize)); + break; + case EOpBitCount: + setType(TType(EbtInt, EbpLow, resultQualifier, operandPrimarySize)); + break; + case EOpFindLSB: + setType(TType(EbtInt, EbpLow, resultQualifier, operandPrimarySize)); + break; + case EOpFindMSB: + setType(TType(EbtInt, EbpLow, resultQualifier, operandPrimarySize)); + break; + default: + setType(mOperand->getType()); + mType.setQualifier(resultQualifier); + break; + } +} + +TIntermSwizzle::TIntermSwizzle(TIntermTyped *operand, const TVector &swizzleOffsets) + : TIntermTyped(TType(EbtFloat, EbpUndefined)), + mOperand(operand), + mSwizzleOffsets(swizzleOffsets) +{ + ASSERT(mSwizzleOffsets.size() <= 4); + promote(); +} + +TIntermUnary::TIntermUnary(TOperator op, TIntermTyped *operand) + : TIntermOperator(op), mOperand(operand), mUseEmulatedFunction(false) +{ + promote(); +} + +TIntermBinary::TIntermBinary(TOperator op, TIntermTyped *left, TIntermTyped *right) + : TIntermOperator(op), mLeft(left), mRight(right), mAddIndexClamp(false) +{ + promote(); +} + +TIntermInvariantDeclaration::TIntermInvariantDeclaration(TIntermSymbol *symbol, const TSourceLoc &line) + : TIntermNode(), mSymbol(symbol) +{ + ASSERT(symbol); + setLine(line); +} + +TIntermTernary::TIntermTernary(TIntermTyped *cond, + TIntermTyped *trueExpression, + TIntermTyped *falseExpression) + : TIntermTyped(trueExpression->getType()), + mCondition(cond), + mTrueExpression(trueExpression), + mFalseExpression(falseExpression) +{ + getTypePointer()->setQualifier( + TIntermTernary::DetermineQualifier(cond, trueExpression, falseExpression)); +} + +TIntermLoop::TIntermLoop(TLoopType type, + TIntermNode *init, + TIntermTyped *cond, + TIntermTyped *expr, + TIntermBlock *body) + : mType(type), mInit(init), mCond(cond), mExpr(expr), mBody(body) +{ + // Declaration nodes with no children can appear if all the declarators just added constants to + // the symbol table instead of generating code. They're no-ops so don't add them to the tree. + if (mInit && mInit->getAsDeclarationNode() && + mInit->getAsDeclarationNode()->getSequence()->empty()) + { + mInit = nullptr; + } +} + +TIntermIfElse::TIntermIfElse(TIntermTyped *cond, TIntermBlock *trueB, TIntermBlock *falseB) + : TIntermNode(), mCondition(cond), mTrueBlock(trueB), mFalseBlock(falseB) +{ + // Prune empty false blocks so that there won't be unnecessary operations done on it. + if (mFalseBlock && mFalseBlock->getSequence()->empty()) + { + mFalseBlock = nullptr; + } +} + +TIntermSwitch::TIntermSwitch(TIntermTyped *init, TIntermBlock *statementList) + : TIntermNode(), mInit(init), mStatementList(statementList) +{ + ASSERT(mStatementList); +} + +void TIntermSwitch::setStatementList(TIntermBlock *statementList) +{ + ASSERT(statementList); + mStatementList = statementList; +} + +// static +TQualifier TIntermTernary::DetermineQualifier(TIntermTyped *cond, + TIntermTyped *trueExpression, + TIntermTyped *falseExpression) +{ + if (cond->getQualifier() == EvqConst && trueExpression->getQualifier() == EvqConst && + falseExpression->getQualifier() == EvqConst) + { + return EvqConst; + } + return EvqTemporary; +} + +TIntermTyped *TIntermTernary::fold() +{ + if (mCondition->getAsConstantUnion()) + { + if (mCondition->getAsConstantUnion()->getBConst(0)) { - // Bool types should not have precision. - setType(*funcReturnType); + mTrueExpression->getTypePointer()->setQualifier(mType.getQualifier()); + return mTrueExpression; } else { - // Precision of the node has been set based on the operand. - setTypePreservePrecision(*funcReturnType); + mFalseExpression->getTypePointer()->setQualifier(mType.getQualifier()); + return mFalseExpression; } } - - if (mOperand->getQualifier() == EvqConst) - mType.setQualifier(EvqConst); - else - mType.setQualifier(EvqTemporary); + return this; } -// -// Establishes the type of the resultant operation, as well as -// makes the operator the correct one for the operands. -// -// For lots of operations it should already be established that the operand -// combination is valid, but returns false if operator can't work on operands. -// -bool TIntermBinary::promote(TInfoSink &infoSink) +void TIntermSwizzle::promote() { - ASSERT(mLeft->isArray() == mRight->isArray()); + TQualifier resultQualifier = EvqTemporary; + if (mOperand->getQualifier() == EvqConst) + resultQualifier = EvqConst; + + auto numFields = mSwizzleOffsets.size(); + setType(TType(mOperand->getBasicType(), mOperand->getPrecision(), resultQualifier, + static_cast(numFields))); +} + +bool TIntermSwizzle::hasDuplicateOffsets() const +{ + int offsetCount[4] = {0u, 0u, 0u, 0u}; + for (const auto offset : mSwizzleOffsets) + { + offsetCount[offset]++; + if (offsetCount[offset] > 1) + { + return true; + } + } + return false; +} + +bool TIntermSwizzle::offsetsMatch(int offset) const +{ + return mSwizzleOffsets.size() == 1 && mSwizzleOffsets[0] == offset; +} + +void TIntermSwizzle::writeOffsetsAsXYZW(TInfoSinkBase *out) const +{ + for (const int offset : mSwizzleOffsets) + { + switch (offset) + { + case 0: + *out << "x"; + break; + case 1: + *out << "y"; + break; + case 2: + *out << "z"; + break; + case 3: + *out << "w"; + break; + default: + UNREACHABLE(); + } + } +} + +TQualifier TIntermBinary::GetCommaQualifier(int shaderVersion, + const TIntermTyped *left, + const TIntermTyped *right) +{ + // ESSL3.00 section 12.43: The result of a sequence operator is not a constant-expression. + if (shaderVersion >= 300 || left->getQualifier() != EvqConst || + right->getQualifier() != EvqConst) + { + return EvqTemporary; + } + return EvqConst; +} + +// Establishes the type of the result of the binary operation. +void TIntermBinary::promote() +{ + ASSERT(!isMultiplication() || + mOp == GetMulOpBasedOnOperands(mLeft->getType(), mRight->getType())); + + // Comma is handled as a special case. Note that the comma node qualifier depends on the shader + // version and so is not being set here. + if (mOp == EOpComma) + { + setType(mRight->getType()); + return; + } - // // Base assumption: just make the type the same as the left // operand. Then only deviations from this need be coded. - // setType(mLeft->getType()); - // The result gets promoted to the highest precision. - TPrecision higherPrecision = GetHigherPrecision( - mLeft->getPrecision(), mRight->getPrecision()); - getTypePointer()->setPrecision(higherPrecision); - TQualifier resultQualifier = EvqConst; // Binary operations results in temporary variables unless both // operands are const. @@ -571,8 +1087,56 @@ bool TIntermBinary::promote(TInfoSink &infoSink) getTypePointer()->setQualifier(EvqTemporary); } - const int nominalSize = - std::max(mLeft->getNominalSize(), mRight->getNominalSize()); + // Handle indexing ops. + switch (mOp) + { + case EOpIndexDirect: + case EOpIndexIndirect: + if (mLeft->isArray()) + { + mType.toArrayElementType(); + } + else if (mLeft->isMatrix()) + { + setType(TType(mLeft->getBasicType(), mLeft->getPrecision(), resultQualifier, + static_cast(mLeft->getRows()))); + } + else if (mLeft->isVector()) + { + setType(TType(mLeft->getBasicType(), mLeft->getPrecision(), resultQualifier)); + } + else + { + UNREACHABLE(); + } + return; + case EOpIndexDirectStruct: + { + const TFieldList &fields = mLeft->getType().getStruct()->fields(); + const int i = mRight->getAsConstantUnion()->getIConst(0); + setType(*fields[i]->type()); + getTypePointer()->setQualifier(resultQualifier); + return; + } + case EOpIndexDirectInterfaceBlock: + { + const TFieldList &fields = mLeft->getType().getInterfaceBlock()->fields(); + const int i = mRight->getAsConstantUnion()->getIConst(0); + setType(*fields[i]->type()); + getTypePointer()->setQualifier(resultQualifier); + return; + } + default: + break; + } + + ASSERT(mLeft->isArray() == mRight->isArray()); + + // The result gets promoted to the highest precision. + TPrecision higherPrecision = GetHigherPrecision(mLeft->getPrecision(), mRight->getPrecision()); + getTypePointer()->setPrecision(higherPrecision); + + const int nominalSize = std::max(mLeft->getNominalSize(), mRight->getNominalSize()); // // All scalars or structs. Code after this test assumes this case is removed! @@ -581,316 +1145,319 @@ bool TIntermBinary::promote(TInfoSink &infoSink) { switch (mOp) { - // - // Promote to conditional - // - case EOpEqual: - case EOpNotEqual: - case EOpLessThan: - case EOpGreaterThan: - case EOpLessThanEqual: - case EOpGreaterThanEqual: - setType(TType(EbtBool, EbpUndefined)); - break; + // + // Promote to conditional + // + case EOpEqual: + case EOpNotEqual: + case EOpLessThan: + case EOpGreaterThan: + case EOpLessThanEqual: + case EOpGreaterThanEqual: + setType(TType(EbtBool, EbpUndefined, resultQualifier)); + break; - // - // And and Or operate on conditionals - // - case EOpLogicalAnd: - case EOpLogicalXor: - case EOpLogicalOr: - ASSERT(mLeft->getBasicType() == EbtBool && mRight->getBasicType() == EbtBool); - setType(TType(EbtBool, EbpUndefined)); - break; + // + // And and Or operate on conditionals + // + case EOpLogicalAnd: + case EOpLogicalXor: + case EOpLogicalOr: + ASSERT(mLeft->getBasicType() == EbtBool && mRight->getBasicType() == EbtBool); + setType(TType(EbtBool, EbpUndefined, resultQualifier)); + break; - default: - break; + default: + break; } - return true; + return; } // If we reach here, at least one of the operands is vector or matrix. // The other operand could be a scalar, vector, or matrix. - // Can these two operands be combined? - // TBasicType basicType = mLeft->getBasicType(); + switch (mOp) { - case EOpMul: - if (!mLeft->isMatrix() && mRight->isMatrix()) - { - if (mLeft->isVector()) + case EOpMul: + break; + case EOpMatrixTimesScalar: + if (mRight->isMatrix()) { - mOp = EOpVectorTimesMatrix; - setType(TType(basicType, higherPrecision, resultQualifier, - static_cast(mRight->getCols()), 1)); - } - else - { - mOp = EOpMatrixTimesScalar; setType(TType(basicType, higherPrecision, resultQualifier, static_cast(mRight->getCols()), static_cast(mRight->getRows()))); } - } - else if (mLeft->isMatrix() && !mRight->isMatrix()) - { - if (mRight->isVector()) - { - mOp = EOpMatrixTimesVector; - setType(TType(basicType, higherPrecision, resultQualifier, - static_cast(mLeft->getRows()), 1)); - } - else - { - mOp = EOpMatrixTimesScalar; - } - } - else if (mLeft->isMatrix() && mRight->isMatrix()) - { - mOp = EOpMatrixTimesMatrix; + break; + case EOpMatrixTimesVector: + setType(TType(basicType, higherPrecision, resultQualifier, + static_cast(mLeft->getRows()), 1)); + break; + case EOpMatrixTimesMatrix: setType(TType(basicType, higherPrecision, resultQualifier, static_cast(mRight->getCols()), static_cast(mLeft->getRows()))); - } - else if (!mLeft->isMatrix() && !mRight->isMatrix()) - { - if (mLeft->isVector() && mRight->isVector()) - { - // leave as component product - } - else if (mLeft->isVector() || mRight->isVector()) - { - mOp = EOpVectorTimesScalar; - setType(TType(basicType, higherPrecision, resultQualifier, - static_cast(nominalSize), 1)); - } - } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), - "Missing elses"); - return false; - } - - if (!ValidateMultiplication(mOp, mLeft->getType(), mRight->getType())) - { - return false; - } - break; - - case EOpMulAssign: - if (!mLeft->isMatrix() && mRight->isMatrix()) - { - if (mLeft->isVector()) - { - mOp = EOpVectorTimesMatrixAssign; - } - else - { - return false; - } - } - else if (mLeft->isMatrix() && !mRight->isMatrix()) - { - if (mRight->isVector()) - { - return false; - } - else - { - mOp = EOpMatrixTimesScalarAssign; - } - } - else if (mLeft->isMatrix() && mRight->isMatrix()) - { - mOp = EOpMatrixTimesMatrixAssign; + break; + case EOpVectorTimesScalar: setType(TType(basicType, higherPrecision, resultQualifier, - static_cast(mRight->getCols()), - static_cast(mLeft->getRows()))); - } - else if (!mLeft->isMatrix() && !mRight->isMatrix()) + static_cast(nominalSize), 1)); + break; + case EOpVectorTimesMatrix: + setType(TType(basicType, higherPrecision, resultQualifier, + static_cast(mRight->getCols()), 1)); + break; + case EOpMulAssign: + case EOpVectorTimesScalarAssign: + case EOpVectorTimesMatrixAssign: + case EOpMatrixTimesScalarAssign: + case EOpMatrixTimesMatrixAssign: + ASSERT(mOp == GetMulAssignOpBasedOnOperands(mLeft->getType(), mRight->getType())); + break; + case EOpAssign: + case EOpInitialize: + ASSERT((mLeft->getNominalSize() == mRight->getNominalSize()) && + (mLeft->getSecondarySize() == mRight->getSecondarySize())); + break; + case EOpAdd: + case EOpSub: + case EOpDiv: + case EOpIMod: + case EOpBitShiftLeft: + case EOpBitShiftRight: + case EOpBitwiseAnd: + case EOpBitwiseXor: + case EOpBitwiseOr: + case EOpAddAssign: + case EOpSubAssign: + case EOpDivAssign: + case EOpIModAssign: + case EOpBitShiftLeftAssign: + case EOpBitShiftRightAssign: + case EOpBitwiseAndAssign: + case EOpBitwiseXorAssign: + case EOpBitwiseOrAssign: { - if (mLeft->isVector() && mRight->isVector()) - { - // leave as component product - } - else if (mLeft->isVector() || mRight->isVector()) - { - if (!mLeft->isVector()) - return false; - mOp = EOpVectorTimesScalarAssign; - setType(TType(basicType, higherPrecision, resultQualifier, - static_cast(mLeft->getNominalSize()), 1)); - } - } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), - "Missing elses"); - return false; - } - - if (!ValidateMultiplication(mOp, mLeft->getType(), mRight->getType())) - { - return false; - } - break; - - case EOpAssign: - case EOpInitialize: - // No more additional checks are needed. - ASSERT((mLeft->getNominalSize() == mRight->getNominalSize()) && - (mLeft->getSecondarySize() == mRight->getSecondarySize())); - break; - case EOpAdd: - case EOpSub: - case EOpDiv: - case EOpIMod: - case EOpBitShiftLeft: - case EOpBitShiftRight: - case EOpBitwiseAnd: - case EOpBitwiseXor: - case EOpBitwiseOr: - case EOpAddAssign: - case EOpSubAssign: - case EOpDivAssign: - case EOpIModAssign: - case EOpBitShiftLeftAssign: - case EOpBitShiftRightAssign: - case EOpBitwiseAndAssign: - case EOpBitwiseXorAssign: - case EOpBitwiseOrAssign: - if ((mLeft->isMatrix() && mRight->isVector()) || - (mLeft->isVector() && mRight->isMatrix())) - { - return false; - } - - // Are the sizes compatible? - if (mLeft->getNominalSize() != mRight->getNominalSize() || - mLeft->getSecondarySize() != mRight->getSecondarySize()) - { - // If the nominal sizes of operands do not match: - // One of them must be a scalar. - if (!mLeft->isScalar() && !mRight->isScalar()) - return false; - - // In the case of compound assignment other than multiply-assign, - // the right side needs to be a scalar. Otherwise a vector/matrix - // would be assigned to a scalar. A scalar can't be shifted by a - // vector either. - if (!mRight->isScalar() && - (isAssignment() || - mOp == EOpBitShiftLeft || - mOp == EOpBitShiftRight)) - return false; - } - - { - const int secondarySize = std::max( - mLeft->getSecondarySize(), mRight->getSecondarySize()); + const int secondarySize = + std::max(mLeft->getSecondarySize(), mRight->getSecondarySize()); setType(TType(basicType, higherPrecision, resultQualifier, static_cast(nominalSize), static_cast(secondarySize))); - if (mLeft->isArray()) - { - ASSERT(mLeft->getArraySize() == mRight->getArraySize()); - mType.setArraySize(mLeft->getArraySize()); - } + ASSERT(!mLeft->isArray() && !mRight->isArray()); + break; } - break; + case EOpEqual: + case EOpNotEqual: + case EOpLessThan: + case EOpGreaterThan: + case EOpLessThanEqual: + case EOpGreaterThanEqual: + ASSERT((mLeft->getNominalSize() == mRight->getNominalSize()) && + (mLeft->getSecondarySize() == mRight->getSecondarySize())); + setType(TType(EbtBool, EbpUndefined, resultQualifier)); + break; - case EOpEqual: - case EOpNotEqual: - case EOpLessThan: - case EOpGreaterThan: - case EOpLessThanEqual: - case EOpGreaterThanEqual: - ASSERT((mLeft->getNominalSize() == mRight->getNominalSize()) && - (mLeft->getSecondarySize() == mRight->getSecondarySize())); - setType(TType(EbtBool, EbpUndefined)); - break; - - default: - return false; + case EOpIndexDirect: + case EOpIndexIndirect: + case EOpIndexDirectInterfaceBlock: + case EOpIndexDirectStruct: + // These ops should be already fully handled. + UNREACHABLE(); + break; + default: + UNREACHABLE(); + break; } - return true; } -TIntermTyped *TIntermBinary::fold(TInfoSink &infoSink) +const TConstantUnion *TIntermConstantUnion::foldIndexing(int index) { - TIntermConstantUnion *leftConstant = mLeft->getAsConstantUnion(); - TIntermConstantUnion *rightConstant = mRight->getAsConstantUnion(); - if (leftConstant == nullptr || rightConstant == nullptr) + if (isArray()) { + ASSERT(index < static_cast(getType().getOutermostArraySize())); + TType arrayElementType = getType(); + arrayElementType.toArrayElementType(); + size_t arrayElementSize = arrayElementType.getObjectSize(); + return &mUnionArrayPointer[arrayElementSize * index]; + } + else if (isMatrix()) + { + ASSERT(index < getType().getCols()); + int size = getType().getRows(); + return &mUnionArrayPointer[size * index]; + } + else if (isVector()) + { + ASSERT(index < getType().getNominalSize()); + return &mUnionArrayPointer[index]; + } + else + { + UNREACHABLE(); return nullptr; } - TConstantUnion *constArray = leftConstant->foldBinary(mOp, rightConstant, infoSink); - - // Nodes may be constant folded without being qualified as constant. - TQualifier resultQualifier = EvqConst; - if (mLeft->getQualifier() != EvqConst || mRight->getQualifier() != EvqConst) - { - resultQualifier = EvqTemporary; - } - return CreateFoldedNode(constArray, this, resultQualifier); } -TIntermTyped *TIntermUnary::fold(TInfoSink &infoSink) +TIntermTyped *TIntermSwizzle::fold() { TIntermConstantUnion *operandConstant = mOperand->getAsConstantUnion(); if (operandConstant == nullptr) { - return nullptr; + return this; } - TConstantUnion *constArray = nullptr; + TConstantUnion *constArray = new TConstantUnion[mSwizzleOffsets.size()]; + for (size_t i = 0; i < mSwizzleOffsets.size(); ++i) + { + constArray[i] = *operandConstant->foldIndexing(mSwizzleOffsets.at(i)); + } + return CreateFoldedNode(constArray, this, mType.getQualifier()); +} + +TIntermTyped *TIntermBinary::fold(TDiagnostics *diagnostics) +{ + TIntermConstantUnion *leftConstant = mLeft->getAsConstantUnion(); + TIntermConstantUnion *rightConstant = mRight->getAsConstantUnion(); switch (mOp) { - case EOpAny: - case EOpAll: - case EOpLength: - case EOpTranspose: - case EOpDeterminant: - case EOpInverse: - case EOpPackSnorm2x16: - case EOpUnpackSnorm2x16: - case EOpPackUnorm2x16: - case EOpUnpackUnorm2x16: - case EOpPackHalf2x16: - case EOpUnpackHalf2x16: - constArray = operandConstant->foldUnaryWithDifferentReturnType(mOp, infoSink); - break; - default: - constArray = operandConstant->foldUnaryWithSameReturnType(mOp, infoSink); - break; + case EOpComma: + { + if (mLeft->hasSideEffects()) + { + return this; + } + mRight->getTypePointer()->setQualifier(mType.getQualifier()); + return mRight; + } + case EOpIndexDirect: + { + if (leftConstant == nullptr || rightConstant == nullptr) + { + return this; + } + int index = rightConstant->getIConst(0); + + const TConstantUnion *constArray = leftConstant->foldIndexing(index); + if (!constArray) + { + return this; + } + return CreateFoldedNode(constArray, this, mType.getQualifier()); + } + case EOpIndexDirectStruct: + { + if (leftConstant == nullptr || rightConstant == nullptr) + { + return this; + } + const TFieldList &fields = mLeft->getType().getStruct()->fields(); + size_t index = static_cast(rightConstant->getIConst(0)); + + size_t previousFieldsSize = 0; + for (size_t i = 0; i < index; ++i) + { + previousFieldsSize += fields[i]->type()->getObjectSize(); + } + + const TConstantUnion *constArray = leftConstant->getUnionArrayPointer(); + return CreateFoldedNode(constArray + previousFieldsSize, this, mType.getQualifier()); + } + case EOpIndexIndirect: + case EOpIndexDirectInterfaceBlock: + // Can never be constant folded. + return this; + default: + { + if (leftConstant == nullptr || rightConstant == nullptr) + { + return this; + } + TConstantUnion *constArray = + leftConstant->foldBinary(mOp, rightConstant, diagnostics, mLeft->getLine()); + if (!constArray) + { + return this; + } + + // Nodes may be constant folded without being qualified as constant. + return CreateFoldedNode(constArray, this, mType.getQualifier()); + } + } +} + +TIntermTyped *TIntermUnary::fold(TDiagnostics *diagnostics) +{ + TConstantUnion *constArray = nullptr; + + if (mOp == EOpArrayLength) + { + // The size of runtime-sized arrays may only be determined at runtime. + if (mOperand->hasSideEffects() || mOperand->getType().isUnsizedArray()) + { + return this; + } + constArray = new TConstantUnion[1]; + constArray->setIConst(mOperand->getOutermostArraySize()); + } + else + { + TIntermConstantUnion *operandConstant = mOperand->getAsConstantUnion(); + if (operandConstant == nullptr) + { + return this; + } + + switch (mOp) + { + case EOpAny: + case EOpAll: + case EOpLength: + case EOpTranspose: + case EOpDeterminant: + case EOpInverse: + case EOpPackSnorm2x16: + case EOpUnpackSnorm2x16: + case EOpPackUnorm2x16: + case EOpUnpackUnorm2x16: + case EOpPackHalf2x16: + case EOpUnpackHalf2x16: + case EOpPackUnorm4x8: + case EOpPackSnorm4x8: + case EOpUnpackUnorm4x8: + case EOpUnpackSnorm4x8: + constArray = operandConstant->foldUnaryNonComponentWise(mOp); + break; + default: + constArray = operandConstant->foldUnaryComponentWise(mOp, diagnostics); + break; + } + } + if (constArray == nullptr) + { + return this; } // Nodes may be constant folded without being qualified as constant. - TQualifier resultQualifier = mOperand->getQualifier() == EvqConst ? EvqConst : EvqTemporary; - return CreateFoldedNode(constArray, this, resultQualifier); + return CreateFoldedNode(constArray, this, mType.getQualifier()); } -TIntermTyped *TIntermAggregate::fold(TInfoSink &infoSink) +TIntermTyped *TIntermAggregate::fold(TDiagnostics *diagnostics) { // Make sure that all params are constant before actual constant folding. for (auto *param : *getSequence()) { if (param->getAsConstantUnion() == nullptr) { - return nullptr; + return this; } } TConstantUnion *constArray = nullptr; if (isConstructor()) - constArray = TIntermConstantUnion::FoldAggregateConstructor(this, infoSink); + constArray = TIntermConstantUnion::FoldAggregateConstructor(this); else - constArray = TIntermConstantUnion::FoldAggregateBuiltIn(this, infoSink); + constArray = TIntermConstantUnion::FoldAggregateBuiltIn(this, diagnostics); // Nodes may be constant folded without being qualified as constant. - TQualifier resultQualifier = areChildrenConstQualified() ? EvqConst : EvqTemporary; - return CreateFoldedNode(constArray, this, resultQualifier); + return CreateFoldedNode(constArray, this, getQualifier()); } // @@ -899,15 +1466,15 @@ TIntermTyped *TIntermAggregate::fold(TInfoSink &infoSink) // // Returns the constant value to keep using or nullptr. // -TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUnion *rightNode, TInfoSink &infoSink) +TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, + TIntermConstantUnion *rightNode, + TDiagnostics *diagnostics, + const TSourceLoc &line) { const TConstantUnion *leftArray = getUnionArrayPointer(); const TConstantUnion *rightArray = rightNode->getUnionArrayPointer(); - if (!leftArray) - return nullptr; - if (!rightArray) - return nullptr; + ASSERT(leftArray && rightArray); size_t objectSize = getType().getObjectSize(); @@ -919,48 +1486,45 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUn else if (rightNode->getType().getObjectSize() > 1 && objectSize == 1) { // for a case like float f = 1.2 + vec4(2, 3, 4, 5); - leftArray = Vectorize(*getUnionArrayPointer(), rightNode->getType().getObjectSize()); + leftArray = Vectorize(*getUnionArrayPointer(), rightNode->getType().getObjectSize()); objectSize = rightNode->getType().getObjectSize(); } TConstantUnion *resultArray = nullptr; - switch(op) + switch (op) { - case EOpAdd: - resultArray = new TConstantUnion[objectSize]; - for (size_t i = 0; i < objectSize; i++) - resultArray[i] = leftArray[i] + rightArray[i]; - break; - case EOpSub: - resultArray = new TConstantUnion[objectSize]; - for (size_t i = 0; i < objectSize; i++) - resultArray[i] = leftArray[i] - rightArray[i]; - break; + case EOpAdd: + resultArray = new TConstantUnion[objectSize]; + for (size_t i = 0; i < objectSize; i++) + resultArray[i] = + TConstantUnion::add(leftArray[i], rightArray[i], diagnostics, line); + break; + case EOpSub: + resultArray = new TConstantUnion[objectSize]; + for (size_t i = 0; i < objectSize; i++) + resultArray[i] = + TConstantUnion::sub(leftArray[i], rightArray[i], diagnostics, line); + break; - case EOpMul: - case EOpVectorTimesScalar: - case EOpMatrixTimesScalar: - resultArray = new TConstantUnion[objectSize]; - for (size_t i = 0; i < objectSize; i++) - resultArray[i] = leftArray[i] * rightArray[i]; - break; + case EOpMul: + case EOpVectorTimesScalar: + case EOpMatrixTimesScalar: + resultArray = new TConstantUnion[objectSize]; + for (size_t i = 0; i < objectSize; i++) + resultArray[i] = + TConstantUnion::mul(leftArray[i], rightArray[i], diagnostics, line); + break; - case EOpMatrixTimesMatrix: + case EOpMatrixTimesMatrix: { - if (getType().getBasicType() != EbtFloat || - rightNode->getBasicType() != EbtFloat) - { - infoSink.info.message( - EPrefixInternalError, getLine(), - "Constant Folding cannot be done for matrix multiply"); - return nullptr; - } + // TODO(jmadll): This code should check for overflows. + ASSERT(getType().getBasicType() == EbtFloat && rightNode->getBasicType() == EbtFloat); - const int leftCols = getCols(); - const int leftRows = getRows(); - const int rightCols = rightNode->getType().getCols(); - const int rightRows = rightNode->getType().getRows(); + const int leftCols = getCols(); + const int leftRows = getRows(); + const int rightCols = rightNode->getType().getCols(); + const int rightRows = rightNode->getType().getRows(); const int resultCols = rightCols; const int resultRows = leftRows; @@ -975,94 +1539,155 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUn resultArray[resultRows * column + row].setFConst( resultArray[resultRows * column + row].getFConst() + leftArray[i * leftRows + row].getFConst() * - rightArray[column * rightRows + i].getFConst()); + rightArray[column * rightRows + i].getFConst()); } } } } break; - case EOpDiv: - case EOpIMod: + case EOpDiv: + case EOpIMod: { resultArray = new TConstantUnion[objectSize]; for (size_t i = 0; i < objectSize; i++) { switch (getType().getBasicType()) { - case EbtFloat: - if (rightArray[i] == 0.0f) - { - infoSink.info.message(EPrefixWarning, getLine(), - "Divide by zero error during constant folding"); - resultArray[i].setFConst(leftArray[i].getFConst() < 0 ? -FLT_MAX : FLT_MAX); - } - else + case EbtFloat: { ASSERT(op == EOpDiv); - resultArray[i].setFConst(leftArray[i].getFConst() / rightArray[i].getFConst()); - } - break; - - case EbtInt: - if (rightArray[i] == 0) - { - infoSink.info.message(EPrefixWarning, getLine(), - "Divide by zero error during constant folding"); - resultArray[i].setIConst(INT_MAX); - } - else - { - if (op == EOpDiv) + float dividend = leftArray[i].getFConst(); + float divisor = rightArray[i].getFConst(); + if (divisor == 0.0f) { - resultArray[i].setIConst(leftArray[i].getIConst() / rightArray[i].getIConst()); + if (dividend == 0.0f) + { + diagnostics->warning( + getLine(), + "Zero divided by zero during constant folding generated NaN", + "/"); + resultArray[i].setFConst(std::numeric_limits::quiet_NaN()); + } + else + { + diagnostics->warning(getLine(), + "Divide by zero during constant folding", "/"); + bool negativeResult = + std::signbit(dividend) != std::signbit(divisor); + resultArray[i].setFConst( + negativeResult ? -std::numeric_limits::infinity() + : std::numeric_limits::infinity()); + } + } + else if (gl::isInf(dividend) && gl::isInf(divisor)) + { + diagnostics->warning(getLine(), + "Infinity divided by infinity during constant " + "folding generated NaN", + "/"); + resultArray[i].setFConst(std::numeric_limits::quiet_NaN()); } else { - ASSERT(op == EOpIMod); - resultArray[i].setIConst(leftArray[i].getIConst() % rightArray[i].getIConst()); + float result = dividend / divisor; + if (!gl::isInf(dividend) && gl::isInf(result)) + { + diagnostics->warning( + getLine(), "Constant folded division overflowed to infinity", + "/"); + } + resultArray[i].setFConst(result); } + break; } - break; - - case EbtUInt: - if (rightArray[i] == 0) - { - infoSink.info.message(EPrefixWarning, getLine(), - "Divide by zero error during constant folding"); - resultArray[i].setUConst(UINT_MAX); - } - else - { - if (op == EOpDiv) + case EbtInt: + if (rightArray[i] == 0) { - resultArray[i].setUConst(leftArray[i].getUConst() / rightArray[i].getUConst()); + diagnostics->warning( + getLine(), "Divide by zero error during constant folding", "/"); + resultArray[i].setIConst(INT_MAX); } else { - ASSERT(op == EOpIMod); - resultArray[i].setUConst(leftArray[i].getUConst() % rightArray[i].getUConst()); + int lhs = leftArray[i].getIConst(); + int divisor = rightArray[i].getIConst(); + if (op == EOpDiv) + { + // Check for the special case where the minimum representable number + // is + // divided by -1. If left alone this leads to integer overflow in + // C++. + // ESSL 3.00.6 section 4.1.3 Integers: + // "However, for the case where the minimum representable value is + // divided by -1, it is allowed to return either the minimum + // representable value or the maximum representable value." + if (lhs == -0x7fffffff - 1 && divisor == -1) + { + resultArray[i].setIConst(0x7fffffff); + } + else + { + resultArray[i].setIConst(lhs / divisor); + } + } + else + { + ASSERT(op == EOpIMod); + if (lhs < 0 || divisor < 0) + { + // ESSL 3.00.6 section 5.9: Results of modulus are undefined + // when + // either one of the operands is negative. + diagnostics->warning(getLine(), + "Negative modulus operator operand " + "encountered during constant folding", + "%"); + resultArray[i].setIConst(0); + } + else + { + resultArray[i].setIConst(lhs % divisor); + } + } } - } - break; + break; - default: - infoSink.info.message(EPrefixInternalError, getLine(), - "Constant folding cannot be done for \"/\""); - return nullptr; + case EbtUInt: + if (rightArray[i] == 0) + { + diagnostics->warning( + getLine(), "Divide by zero error during constant folding", "/"); + resultArray[i].setUConst(UINT_MAX); + } + else + { + if (op == EOpDiv) + { + resultArray[i].setUConst(leftArray[i].getUConst() / + rightArray[i].getUConst()); + } + else + { + ASSERT(op == EOpIMod); + resultArray[i].setUConst(leftArray[i].getUConst() % + rightArray[i].getUConst()); + } + } + break; + + default: + UNREACHABLE(); + return nullptr; } } } break; - case EOpMatrixTimesVector: + case EOpMatrixTimesVector: { - if (rightNode->getBasicType() != EbtFloat) - { - infoSink.info.message(EPrefixInternalError, getLine(), - "Constant Folding cannot be done for matrix times vector"); - return nullptr; - } + // TODO(jmadll): This code should check for overflows. + ASSERT(rightNode->getBasicType() == EbtFloat); const int matrixCols = getCols(); const int matrixRows = getRows(); @@ -1074,22 +1699,19 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUn resultArray[matrixRow].setFConst(0.0f); for (int col = 0; col < matrixCols; col++) { - resultArray[matrixRow].setFConst(resultArray[matrixRow].getFConst() + - leftArray[col * matrixRows + matrixRow].getFConst() * - rightArray[col].getFConst()); + resultArray[matrixRow].setFConst( + resultArray[matrixRow].getFConst() + + leftArray[col * matrixRows + matrixRow].getFConst() * + rightArray[col].getFConst()); } } } break; - case EOpVectorTimesMatrix: + case EOpVectorTimesMatrix: { - if (getType().getBasicType() != EbtFloat) - { - infoSink.info.message(EPrefixInternalError, getLine(), - "Constant Folding cannot be done for vector times matrix"); - return nullptr; - } + // TODO(jmadll): This code should check for overflows. + ASSERT(getType().getBasicType() == EbtFloat); const int matrixCols = rightNode->getType().getCols(); const int matrixRows = rightNode->getType().getRows(); @@ -1101,15 +1723,16 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUn resultArray[matrixCol].setFConst(0.0f); for (int matrixRow = 0; matrixRow < matrixRows; matrixRow++) { - resultArray[matrixCol].setFConst(resultArray[matrixCol].getFConst() + - leftArray[matrixRow].getFConst() * - rightArray[matrixCol * matrixRows + matrixRow].getFConst()); + resultArray[matrixCol].setFConst( + resultArray[matrixCol].getFConst() + + leftArray[matrixRow].getFConst() * + rightArray[matrixCol * matrixRows + matrixRow].getFConst()); } } } break; - case EOpLogicalAnd: + case EOpLogicalAnd: { resultArray = new TConstantUnion[objectSize]; for (size_t i = 0; i < objectSize; i++) @@ -1119,7 +1742,7 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUn } break; - case EOpLogicalOr: + case EOpLogicalOr: { resultArray = new TConstantUnion[objectSize]; for (size_t i = 0; i < objectSize; i++) @@ -1129,79 +1752,74 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUn } break; - case EOpLogicalXor: + case EOpLogicalXor: { + ASSERT(getType().getBasicType() == EbtBool); resultArray = new TConstantUnion[objectSize]; for (size_t i = 0; i < objectSize; i++) { - switch (getType().getBasicType()) - { - case EbtBool: - resultArray[i].setBConst(leftArray[i] != rightArray[i]); - break; - default: - UNREACHABLE(); - break; - } + resultArray[i].setBConst(leftArray[i] != rightArray[i]); } } break; - case EOpBitwiseAnd: - resultArray = new TConstantUnion[objectSize]; - for (size_t i = 0; i < objectSize; i++) - resultArray[i] = leftArray[i] & rightArray[i]; - break; - case EOpBitwiseXor: - resultArray = new TConstantUnion[objectSize]; - for (size_t i = 0; i < objectSize; i++) - resultArray[i] = leftArray[i] ^ rightArray[i]; - break; - case EOpBitwiseOr: - resultArray = new TConstantUnion[objectSize]; - for (size_t i = 0; i < objectSize; i++) - resultArray[i] = leftArray[i] | rightArray[i]; - break; - case EOpBitShiftLeft: - resultArray = new TConstantUnion[objectSize]; - for (size_t i = 0; i < objectSize; i++) - resultArray[i] = leftArray[i] << rightArray[i]; - break; - case EOpBitShiftRight: - resultArray = new TConstantUnion[objectSize]; - for (size_t i = 0; i < objectSize; i++) - resultArray[i] = leftArray[i] >> rightArray[i]; - break; + case EOpBitwiseAnd: + resultArray = new TConstantUnion[objectSize]; + for (size_t i = 0; i < objectSize; i++) + resultArray[i] = leftArray[i] & rightArray[i]; + break; + case EOpBitwiseXor: + resultArray = new TConstantUnion[objectSize]; + for (size_t i = 0; i < objectSize; i++) + resultArray[i] = leftArray[i] ^ rightArray[i]; + break; + case EOpBitwiseOr: + resultArray = new TConstantUnion[objectSize]; + for (size_t i = 0; i < objectSize; i++) + resultArray[i] = leftArray[i] | rightArray[i]; + break; + case EOpBitShiftLeft: + resultArray = new TConstantUnion[objectSize]; + for (size_t i = 0; i < objectSize; i++) + resultArray[i] = + TConstantUnion::lshift(leftArray[i], rightArray[i], diagnostics, line); + break; + case EOpBitShiftRight: + resultArray = new TConstantUnion[objectSize]; + for (size_t i = 0; i < objectSize; i++) + resultArray[i] = + TConstantUnion::rshift(leftArray[i], rightArray[i], diagnostics, line); + break; - case EOpLessThan: - ASSERT(objectSize == 1); - resultArray = new TConstantUnion[1]; - resultArray->setBConst(*leftArray < *rightArray); - break; + case EOpLessThan: + ASSERT(objectSize == 1); + resultArray = new TConstantUnion[1]; + resultArray->setBConst(*leftArray < *rightArray); + break; - case EOpGreaterThan: - ASSERT(objectSize == 1); - resultArray = new TConstantUnion[1]; - resultArray->setBConst(*leftArray > *rightArray); - break; + case EOpGreaterThan: + ASSERT(objectSize == 1); + resultArray = new TConstantUnion[1]; + resultArray->setBConst(*leftArray > *rightArray); + break; - case EOpLessThanEqual: - ASSERT(objectSize == 1); - resultArray = new TConstantUnion[1]; - resultArray->setBConst(!(*leftArray > *rightArray)); - break; + case EOpLessThanEqual: + ASSERT(objectSize == 1); + resultArray = new TConstantUnion[1]; + resultArray->setBConst(!(*leftArray > *rightArray)); + break; - case EOpGreaterThanEqual: - ASSERT(objectSize == 1); - resultArray = new TConstantUnion[1]; - resultArray->setBConst(!(*leftArray < *rightArray)); - break; + case EOpGreaterThanEqual: + ASSERT(objectSize == 1); + resultArray = new TConstantUnion[1]; + resultArray->setBConst(!(*leftArray < *rightArray)); + break; - case EOpEqual: - case EOpNotEqual: + case EOpEqual: + case EOpNotEqual: { resultArray = new TConstantUnion[1]; - bool equal = true; + bool equal = true; for (size_t i = 0; i < objectSize; i++) { if (leftArray[i] != rightArray[i]) @@ -1221,38 +1839,29 @@ TConstantUnion *TIntermConstantUnion::foldBinary(TOperator op, TIntermConstantUn } break; - default: - infoSink.info.message( - EPrefixInternalError, getLine(), - "Invalid operator for constant folding"); - return nullptr; + default: + UNREACHABLE(); + return nullptr; } return resultArray; } -// -// The fold functions see if an operation on a constant can be done in place, -// without generating run-time code. -// -// Returns the constant value to keep using or nullptr. -// -TConstantUnion *TIntermConstantUnion::foldUnaryWithDifferentReturnType(TOperator op, TInfoSink &infoSink) +// The fold functions do operations on a constant at GLSL compile time, without generating run-time +// code. Returns the constant value to keep using. Nullptr should not be returned. +TConstantUnion *TIntermConstantUnion::foldUnaryNonComponentWise(TOperator op) { - // - // Do operations where the return type has a different number of components compared to the operand type. - // + // Do operations where the return type may have a different number of components compared to the + // operand type. const TConstantUnion *operandArray = getUnionArrayPointer(); - if (!operandArray) - return nullptr; + ASSERT(operandArray); - size_t objectSize = getType().getObjectSize(); + size_t objectSize = getType().getObjectSize(); TConstantUnion *resultArray = nullptr; switch (op) { - case EOpAny: - if (getType().getBasicType() == EbtBool) - { + case EOpAny: + ASSERT(getType().getBasicType() == EbtBool); resultArray = new TConstantUnion(); resultArray->setBConst(false); for (size_t i = 0; i < objectSize; i++) @@ -1264,16 +1873,9 @@ TConstantUnion *TIntermConstantUnion::foldUnaryWithDifferentReturnType(TOperator } } break; - } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - } - case EOpAll: - if (getType().getBasicType() == EbtBool) - { + case EOpAll: + ASSERT(getType().getBasicType() == EbtBool); resultArray = new TConstantUnion(); resultArray->setBConst(true); for (size_t i = 0; i < objectSize; i++) @@ -1285,89 +1887,55 @@ TConstantUnion *TIntermConstantUnion::foldUnaryWithDifferentReturnType(TOperator } } break; - } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - } - case EOpLength: - if (getType().getBasicType() == EbtFloat) - { + case EOpLength: + ASSERT(getType().getBasicType() == EbtFloat); resultArray = new TConstantUnion(); resultArray->setFConst(VectorLength(operandArray, objectSize)); break; - } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - } - case EOpTranspose: - if (getType().getBasicType() == EbtFloat) + case EOpTranspose: { + ASSERT(getType().getBasicType() == EbtFloat); resultArray = new TConstantUnion[objectSize]; angle::Matrix result = - GetMatrix(operandArray, getType().getNominalSize(), getType().getSecondarySize()).transpose(); + GetMatrix(operandArray, getType().getRows(), getType().getCols()).transpose(); SetUnionArrayFromMatrix(result, resultArray); break; } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - } - case EOpDeterminant: - if (getType().getBasicType() == EbtFloat) + case EOpDeterminant: { + ASSERT(getType().getBasicType() == EbtFloat); unsigned int size = getType().getNominalSize(); ASSERT(size >= 2 && size <= 4); resultArray = new TConstantUnion(); resultArray->setFConst(GetMatrix(operandArray, size).determinant()); break; } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - } - case EOpInverse: - if (getType().getBasicType() == EbtFloat) + case EOpInverse: { + ASSERT(getType().getBasicType() == EbtFloat); unsigned int size = getType().getNominalSize(); ASSERT(size >= 2 && size <= 4); - resultArray = new TConstantUnion[objectSize]; + resultArray = new TConstantUnion[objectSize]; angle::Matrix result = GetMatrix(operandArray, size).inverse(); SetUnionArrayFromMatrix(result, resultArray); break; } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - } - case EOpPackSnorm2x16: - if (getType().getBasicType() == EbtFloat) - { + case EOpPackSnorm2x16: + ASSERT(getType().getBasicType() == EbtFloat); ASSERT(getType().getNominalSize() == 2); resultArray = new TConstantUnion(); - resultArray->setUConst(gl::packSnorm2x16(operandArray[0].getFConst(), operandArray[1].getFConst())); + resultArray->setUConst( + gl::packSnorm2x16(operandArray[0].getFConst(), operandArray[1].getFConst())); break; - } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - } - case EOpUnpackSnorm2x16: - if (getType().getBasicType() == EbtUInt) + case EOpUnpackSnorm2x16: { + ASSERT(getType().getBasicType() == EbtUInt); resultArray = new TConstantUnion[2]; float f1, f2; gl::unpackSnorm2x16(operandArray[0].getUConst(), &f1, &f2); @@ -1375,29 +1943,18 @@ TConstantUnion *TIntermConstantUnion::foldUnaryWithDifferentReturnType(TOperator resultArray[1].setFConst(f2); break; } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - } - case EOpPackUnorm2x16: - if (getType().getBasicType() == EbtFloat) - { + case EOpPackUnorm2x16: + ASSERT(getType().getBasicType() == EbtFloat); ASSERT(getType().getNominalSize() == 2); resultArray = new TConstantUnion(); - resultArray->setUConst(gl::packUnorm2x16(operandArray[0].getFConst(), operandArray[1].getFConst())); + resultArray->setUConst( + gl::packUnorm2x16(operandArray[0].getFConst(), operandArray[1].getFConst())); break; - } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - } - case EOpUnpackUnorm2x16: - if (getType().getBasicType() == EbtUInt) + case EOpUnpackUnorm2x16: { + ASSERT(getType().getBasicType() == EbtUInt); resultArray = new TConstantUnion[2]; float f1, f2; gl::unpackUnorm2x16(operandArray[0].getUConst(), &f1, &f2); @@ -1405,29 +1962,18 @@ TConstantUnion *TIntermConstantUnion::foldUnaryWithDifferentReturnType(TOperator resultArray[1].setFConst(f2); break; } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - } - case EOpPackHalf2x16: - if (getType().getBasicType() == EbtFloat) - { + case EOpPackHalf2x16: + ASSERT(getType().getBasicType() == EbtFloat); ASSERT(getType().getNominalSize() == 2); resultArray = new TConstantUnion(); - resultArray->setUConst(gl::packHalf2x16(operandArray[0].getFConst(), operandArray[1].getFConst())); + resultArray->setUConst( + gl::packHalf2x16(operandArray[0].getFConst(), operandArray[1].getFConst())); break; - } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - } - case EOpUnpackHalf2x16: - if (getType().getBasicType() == EbtUInt) + case EOpUnpackHalf2x16: { + ASSERT(getType().getBasicType() == EbtUInt); resultArray = new TConstantUnion[2]; float f1, f2; gl::unpackHalf2x16(operandArray[0].getUConst(), &f1, &f2); @@ -1435,274 +1981,301 @@ TConstantUnion *TIntermConstantUnion::foldUnaryWithDifferentReturnType(TOperator resultArray[1].setFConst(f2); break; } - else - { - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - } - break; - default: - break; + case EOpPackUnorm4x8: + { + ASSERT(getType().getBasicType() == EbtFloat); + resultArray = new TConstantUnion(); + resultArray->setUConst( + gl::PackUnorm4x8(operandArray[0].getFConst(), operandArray[1].getFConst(), + operandArray[2].getFConst(), operandArray[3].getFConst())); + break; + } + case EOpPackSnorm4x8: + { + ASSERT(getType().getBasicType() == EbtFloat); + resultArray = new TConstantUnion(); + resultArray->setUConst( + gl::PackSnorm4x8(operandArray[0].getFConst(), operandArray[1].getFConst(), + operandArray[2].getFConst(), operandArray[3].getFConst())); + break; + } + case EOpUnpackUnorm4x8: + { + ASSERT(getType().getBasicType() == EbtUInt); + resultArray = new TConstantUnion[4]; + float f[4]; + gl::UnpackUnorm4x8(operandArray[0].getUConst(), f); + for (size_t i = 0; i < 4; ++i) + { + resultArray[i].setFConst(f[i]); + } + break; + } + case EOpUnpackSnorm4x8: + { + ASSERT(getType().getBasicType() == EbtUInt); + resultArray = new TConstantUnion[4]; + float f[4]; + gl::UnpackSnorm4x8(operandArray[0].getUConst(), f); + for (size_t i = 0; i < 4; ++i) + { + resultArray[i].setFConst(f[i]); + } + break; + } + + default: + UNREACHABLE(); + break; } return resultArray; } -TConstantUnion *TIntermConstantUnion::foldUnaryWithSameReturnType(TOperator op, TInfoSink &infoSink) +TConstantUnion *TIntermConstantUnion::foldUnaryComponentWise(TOperator op, + TDiagnostics *diagnostics) { - // - // Do unary operations where the return type is the same as operand type. - // + // Do unary operations where each component of the result is computed based on the corresponding + // component of the operand. Also folds normalize, though the divisor in that case takes all + // components into account. const TConstantUnion *operandArray = getUnionArrayPointer(); - if (!operandArray) - return nullptr; + ASSERT(operandArray); size_t objectSize = getType().getObjectSize(); TConstantUnion *resultArray = new TConstantUnion[objectSize]; for (size_t i = 0; i < objectSize; i++) { - switch(op) + switch (op) { - case EOpNegative: - switch (getType().getBasicType()) - { - case EbtFloat: - resultArray[i].setFConst(-operandArray[i].getFConst()); + case EOpNegative: + switch (getType().getBasicType()) + { + case EbtFloat: + resultArray[i].setFConst(-operandArray[i].getFConst()); + break; + case EbtInt: + if (operandArray[i] == std::numeric_limits::min()) + { + // The minimum representable integer doesn't have a positive + // counterpart, rather the negation overflows and in ESSL is supposed to + // wrap back to the minimum representable integer. Make sure that we + // don't actually let the negation overflow, which has undefined + // behavior in C++. + resultArray[i].setIConst(std::numeric_limits::min()); + } + else + { + resultArray[i].setIConst(-operandArray[i].getIConst()); + } + break; + case EbtUInt: + if (operandArray[i] == 0x80000000u) + { + resultArray[i].setUConst(0x80000000u); + } + else + { + resultArray[i].setUConst(static_cast( + -static_cast(operandArray[i].getUConst()))); + } + break; + default: + UNREACHABLE(); + return nullptr; + } break; - case EbtInt: - resultArray[i].setIConst(-operandArray[i].getIConst()); - break; - case EbtUInt: - resultArray[i].setUConst(static_cast( - -static_cast(operandArray[i].getUConst()))); - break; - default: - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - } - break; - case EOpPositive: - switch (getType().getBasicType()) - { - case EbtFloat: - resultArray[i].setFConst(operandArray[i].getFConst()); + case EOpPositive: + switch (getType().getBasicType()) + { + case EbtFloat: + resultArray[i].setFConst(operandArray[i].getFConst()); + break; + case EbtInt: + resultArray[i].setIConst(operandArray[i].getIConst()); + break; + case EbtUInt: + resultArray[i].setUConst(static_cast( + static_cast(operandArray[i].getUConst()))); + break; + default: + UNREACHABLE(); + return nullptr; + } break; - case EbtInt: - resultArray[i].setIConst(operandArray[i].getIConst()); - break; - case EbtUInt: - resultArray[i].setUConst(static_cast( - static_cast(operandArray[i].getUConst()))); - break; - default: - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - } - break; - case EOpLogicalNot: - // this code is written for possible future use, - // will not get executed currently - switch (getType().getBasicType()) - { - case EbtBool: - resultArray[i].setBConst(!operandArray[i].getBConst()); + case EOpLogicalNot: + switch (getType().getBasicType()) + { + case EbtBool: + resultArray[i].setBConst(!operandArray[i].getBConst()); + break; + default: + UNREACHABLE(); + return nullptr; + } break; - default: - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - } - break; - case EOpBitwiseNot: - switch (getType().getBasicType()) - { - case EbtInt: - resultArray[i].setIConst(~operandArray[i].getIConst()); + case EOpBitwiseNot: + switch (getType().getBasicType()) + { + case EbtInt: + resultArray[i].setIConst(~operandArray[i].getIConst()); + break; + case EbtUInt: + resultArray[i].setUConst(~operandArray[i].getUConst()); + break; + default: + UNREACHABLE(); + return nullptr; + } break; - case EbtUInt: - resultArray[i].setUConst(~operandArray[i].getUConst()); - break; - default: - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - } - break; - case EOpRadians: - if (getType().getBasicType() == EbtFloat) - { + case EOpRadians: + ASSERT(getType().getBasicType() == EbtFloat); resultArray[i].setFConst(kDegreesToRadiansMultiplier * operandArray[i].getFConst()); break; - } - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - case EOpDegrees: - if (getType().getBasicType() == EbtFloat) - { + case EOpDegrees: + ASSERT(getType().getBasicType() == EbtFloat); resultArray[i].setFConst(kRadiansToDegreesMultiplier * operandArray[i].getFConst()); break; - } - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - case EOpSin: - if (!foldFloatTypeUnary(operandArray[i], &sinf, infoSink, &resultArray[i])) - return nullptr; - break; - - case EOpCos: - if (!foldFloatTypeUnary(operandArray[i], &cosf, infoSink, &resultArray[i])) - return nullptr; - break; - - case EOpTan: - if (!foldFloatTypeUnary(operandArray[i], &tanf, infoSink, &resultArray[i])) - return nullptr; - break; - - case EOpAsin: - // For asin(x), results are undefined if |x| > 1, we are choosing to set result to 0. - if (getType().getBasicType() == EbtFloat && fabsf(operandArray[i].getFConst()) > 1.0f) - UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]); - else if (!foldFloatTypeUnary(operandArray[i], &asinf, infoSink, &resultArray[i])) - return nullptr; - break; - - case EOpAcos: - // For acos(x), results are undefined if |x| > 1, we are choosing to set result to 0. - if (getType().getBasicType() == EbtFloat && fabsf(operandArray[i].getFConst()) > 1.0f) - UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]); - else if (!foldFloatTypeUnary(operandArray[i], &acosf, infoSink, &resultArray[i])) - return nullptr; - break; - - case EOpAtan: - if (!foldFloatTypeUnary(operandArray[i], &atanf, infoSink, &resultArray[i])) - return nullptr; - break; - - case EOpSinh: - if (!foldFloatTypeUnary(operandArray[i], &sinhf, infoSink, &resultArray[i])) - return nullptr; - break; - - case EOpCosh: - if (!foldFloatTypeUnary(operandArray[i], &coshf, infoSink, &resultArray[i])) - return nullptr; - break; - - case EOpTanh: - if (!foldFloatTypeUnary(operandArray[i], &tanhf, infoSink, &resultArray[i])) - return nullptr; - break; - - case EOpAsinh: - if (!foldFloatTypeUnary(operandArray[i], &asinhf, infoSink, &resultArray[i])) - return nullptr; - break; - - case EOpAcosh: - // For acosh(x), results are undefined if x < 1, we are choosing to set result to 0. - if (getType().getBasicType() == EbtFloat && operandArray[i].getFConst() < 1.0f) - UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]); - else if (!foldFloatTypeUnary(operandArray[i], &acoshf, infoSink, &resultArray[i])) - return nullptr; - break; - - case EOpAtanh: - // For atanh(x), results are undefined if |x| >= 1, we are choosing to set result to 0. - if (getType().getBasicType() == EbtFloat && fabsf(operandArray[i].getFConst()) >= 1.0f) - UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]); - else if (!foldFloatTypeUnary(operandArray[i], &atanhf, infoSink, &resultArray[i])) - return nullptr; - break; - - case EOpAbs: - switch (getType().getBasicType()) - { - case EbtFloat: - resultArray[i].setFConst(fabsf(operandArray[i].getFConst())); + case EOpSin: + foldFloatTypeUnary(operandArray[i], &sinf, &resultArray[i]); break; - case EbtInt: - resultArray[i].setIConst(abs(operandArray[i].getIConst())); - break; - default: - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - } - break; - case EOpSign: - switch (getType().getBasicType()) - { - case EbtFloat: + case EOpCos: + foldFloatTypeUnary(operandArray[i], &cosf, &resultArray[i]); + break; + + case EOpTan: + foldFloatTypeUnary(operandArray[i], &tanf, &resultArray[i]); + break; + + case EOpAsin: + // For asin(x), results are undefined if |x| > 1, we are choosing to set result to + // 0. + if (fabsf(operandArray[i].getFConst()) > 1.0f) + UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), + diagnostics, &resultArray[i]); + else + foldFloatTypeUnary(operandArray[i], &asinf, &resultArray[i]); + break; + + case EOpAcos: + // For acos(x), results are undefined if |x| > 1, we are choosing to set result to + // 0. + if (fabsf(operandArray[i].getFConst()) > 1.0f) + UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), + diagnostics, &resultArray[i]); + else + foldFloatTypeUnary(operandArray[i], &acosf, &resultArray[i]); + break; + + case EOpAtan: + foldFloatTypeUnary(operandArray[i], &atanf, &resultArray[i]); + break; + + case EOpSinh: + foldFloatTypeUnary(operandArray[i], &sinhf, &resultArray[i]); + break; + + case EOpCosh: + foldFloatTypeUnary(operandArray[i], &coshf, &resultArray[i]); + break; + + case EOpTanh: + foldFloatTypeUnary(operandArray[i], &tanhf, &resultArray[i]); + break; + + case EOpAsinh: + foldFloatTypeUnary(operandArray[i], &asinhf, &resultArray[i]); + break; + + case EOpAcosh: + // For acosh(x), results are undefined if x < 1, we are choosing to set result to 0. + if (operandArray[i].getFConst() < 1.0f) + UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), + diagnostics, &resultArray[i]); + else + foldFloatTypeUnary(operandArray[i], &acoshf, &resultArray[i]); + break; + + case EOpAtanh: + // For atanh(x), results are undefined if |x| >= 1, we are choosing to set result to + // 0. + if (fabsf(operandArray[i].getFConst()) >= 1.0f) + UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), + diagnostics, &resultArray[i]); + else + foldFloatTypeUnary(operandArray[i], &atanhf, &resultArray[i]); + break; + + case EOpAbs: + switch (getType().getBasicType()) { - float fConst = operandArray[i].getFConst(); - float fResult = 0.0f; - if (fConst > 0.0f) - fResult = 1.0f; - else if (fConst < 0.0f) - fResult = -1.0f; - resultArray[i].setFConst(fResult); + case EbtFloat: + resultArray[i].setFConst(fabsf(operandArray[i].getFConst())); + break; + case EbtInt: + resultArray[i].setIConst(abs(operandArray[i].getIConst())); + break; + default: + UNREACHABLE(); + return nullptr; } break; - case EbtInt: + + case EOpSign: + switch (getType().getBasicType()) { - int iConst = operandArray[i].getIConst(); - int iResult = 0; - if (iConst > 0) - iResult = 1; - else if (iConst < 0) - iResult = -1; - resultArray[i].setIConst(iResult); + case EbtFloat: + { + float fConst = operandArray[i].getFConst(); + float fResult = 0.0f; + if (fConst > 0.0f) + fResult = 1.0f; + else if (fConst < 0.0f) + fResult = -1.0f; + resultArray[i].setFConst(fResult); + break; + } + case EbtInt: + { + int iConst = operandArray[i].getIConst(); + int iResult = 0; + if (iConst > 0) + iResult = 1; + else if (iConst < 0) + iResult = -1; + resultArray[i].setIConst(iResult); + break; + } + default: + UNREACHABLE(); + return nullptr; } break; - default: - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - } - break; - case EOpFloor: - if (!foldFloatTypeUnary(operandArray[i], &floorf, infoSink, &resultArray[i])) - return nullptr; - break; + case EOpFloor: + foldFloatTypeUnary(operandArray[i], &floorf, &resultArray[i]); + break; - case EOpTrunc: - if (!foldFloatTypeUnary(operandArray[i], &truncf, infoSink, &resultArray[i])) - return nullptr; - break; + case EOpTrunc: + foldFloatTypeUnary(operandArray[i], &truncf, &resultArray[i]); + break; - case EOpRound: - if (!foldFloatTypeUnary(operandArray[i], &roundf, infoSink, &resultArray[i])) - return nullptr; - break; + case EOpRound: + foldFloatTypeUnary(operandArray[i], &roundf, &resultArray[i]); + break; - case EOpRoundEven: - if (getType().getBasicType() == EbtFloat) + case EOpRoundEven: { + ASSERT(getType().getBasicType() == EbtFloat); float x = operandArray[i].getFConst(); float result; float fractPart = modff(x, &result); @@ -1713,197 +2286,226 @@ TConstantUnion *TIntermConstantUnion::foldUnaryWithSameReturnType(TOperator op, resultArray[i].setFConst(result); break; } - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - case EOpCeil: - if (!foldFloatTypeUnary(operandArray[i], &ceilf, infoSink, &resultArray[i])) - return nullptr; - break; + case EOpCeil: + foldFloatTypeUnary(operandArray[i], &ceilf, &resultArray[i]); + break; - case EOpFract: - if (getType().getBasicType() == EbtFloat) + case EOpFract: { + ASSERT(getType().getBasicType() == EbtFloat); float x = operandArray[i].getFConst(); resultArray[i].setFConst(x - floorf(x)); break; } - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - case EOpIsNan: - if (getType().getBasicType() == EbtFloat) - { + case EOpIsNan: + ASSERT(getType().getBasicType() == EbtFloat); resultArray[i].setBConst(gl::isNaN(operandArray[0].getFConst())); break; - } - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - case EOpIsInf: - if (getType().getBasicType() == EbtFloat) - { + case EOpIsInf: + ASSERT(getType().getBasicType() == EbtFloat); resultArray[i].setBConst(gl::isInf(operandArray[0].getFConst())); break; - } - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - case EOpFloatBitsToInt: - if (getType().getBasicType() == EbtFloat) - { + case EOpFloatBitsToInt: + ASSERT(getType().getBasicType() == EbtFloat); resultArray[i].setIConst(gl::bitCast(operandArray[0].getFConst())); break; - } - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - case EOpFloatBitsToUint: - if (getType().getBasicType() == EbtFloat) - { + case EOpFloatBitsToUint: + ASSERT(getType().getBasicType() == EbtFloat); resultArray[i].setUConst(gl::bitCast(operandArray[0].getFConst())); break; - } - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - case EOpIntBitsToFloat: - if (getType().getBasicType() == EbtInt) - { + case EOpIntBitsToFloat: + ASSERT(getType().getBasicType() == EbtInt); resultArray[i].setFConst(gl::bitCast(operandArray[0].getIConst())); break; - } - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - case EOpUintBitsToFloat: - if (getType().getBasicType() == EbtUInt) - { + case EOpUintBitsToFloat: + ASSERT(getType().getBasicType() == EbtUInt); resultArray[i].setFConst(gl::bitCast(operandArray[0].getUConst())); break; - } - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - case EOpExp: - if (!foldFloatTypeUnary(operandArray[i], &expf, infoSink, &resultArray[i])) - return nullptr; - break; + case EOpExp: + foldFloatTypeUnary(operandArray[i], &expf, &resultArray[i]); + break; - case EOpLog: - // For log(x), results are undefined if x <= 0, we are choosing to set result to 0. - if (getType().getBasicType() == EbtFloat && operandArray[i].getFConst() <= 0.0f) - UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]); - else if (!foldFloatTypeUnary(operandArray[i], &logf, infoSink, &resultArray[i])) - return nullptr; - break; + case EOpLog: + // For log(x), results are undefined if x <= 0, we are choosing to set result to 0. + if (operandArray[i].getFConst() <= 0.0f) + UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), + diagnostics, &resultArray[i]); + else + foldFloatTypeUnary(operandArray[i], &logf, &resultArray[i]); + break; - case EOpExp2: - if (!foldFloatTypeUnary(operandArray[i], &exp2f, infoSink, &resultArray[i])) - return nullptr; - break; + case EOpExp2: + foldFloatTypeUnary(operandArray[i], &exp2f, &resultArray[i]); + break; - case EOpLog2: - // For log2(x), results are undefined if x <= 0, we are choosing to set result to 0. - // And log2f is not available on some plarforms like old android, so just using log(x)/log(2) here. - if (getType().getBasicType() == EbtFloat && operandArray[i].getFConst() <= 0.0f) - UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]); - else if (!foldFloatTypeUnary(operandArray[i], &logf, infoSink, &resultArray[i])) - return nullptr; - else - resultArray[i].setFConst(resultArray[i].getFConst() / logf(2.0f)); - break; + case EOpLog2: + // For log2(x), results are undefined if x <= 0, we are choosing to set result to 0. + // And log2f is not available on some plarforms like old android, so just using + // log(x)/log(2) here. + if (operandArray[i].getFConst() <= 0.0f) + UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), + diagnostics, &resultArray[i]); + else + { + foldFloatTypeUnary(operandArray[i], &logf, &resultArray[i]); + resultArray[i].setFConst(resultArray[i].getFConst() / logf(2.0f)); + } + break; - case EOpSqrt: - // For sqrt(x), results are undefined if x < 0, we are choosing to set result to 0. - if (getType().getBasicType() == EbtFloat && operandArray[i].getFConst() < 0.0f) - UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]); - else if (!foldFloatTypeUnary(operandArray[i], &sqrtf, infoSink, &resultArray[i])) - return nullptr; - break; + case EOpSqrt: + // For sqrt(x), results are undefined if x < 0, we are choosing to set result to 0. + if (operandArray[i].getFConst() < 0.0f) + UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), + diagnostics, &resultArray[i]); + else + foldFloatTypeUnary(operandArray[i], &sqrtf, &resultArray[i]); + break; - case EOpInverseSqrt: - // There is no stdlib built-in function equavalent for GLES built-in inversesqrt(), - // so getting the square root first using builtin function sqrt() and then taking its inverse. - // Also, for inversesqrt(x), results are undefined if x <= 0, we are choosing to set result to 0. - if (getType().getBasicType() == EbtFloat && operandArray[i].getFConst() <= 0.0f) - UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, &resultArray[i]); - else if (!foldFloatTypeUnary(operandArray[i], &sqrtf, infoSink, &resultArray[i])) - return nullptr; - else - resultArray[i].setFConst(1.0f / resultArray[i].getFConst()); - break; + case EOpInverseSqrt: + // There is no stdlib built-in function equavalent for GLES built-in inversesqrt(), + // so getting the square root first using builtin function sqrt() and then taking + // its inverse. + // Also, for inversesqrt(x), results are undefined if x <= 0, we are choosing to set + // result to 0. + if (operandArray[i].getFConst() <= 0.0f) + UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), + diagnostics, &resultArray[i]); + else + { + foldFloatTypeUnary(operandArray[i], &sqrtf, &resultArray[i]); + resultArray[i].setFConst(1.0f / resultArray[i].getFConst()); + } + break; - case EOpVectorLogicalNot: - if (getType().getBasicType() == EbtBool) - { + case EOpLogicalNotComponentWise: + ASSERT(getType().getBasicType() == EbtBool); resultArray[i].setBConst(!operandArray[i].getBConst()); break; - } - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return nullptr; - case EOpNormalize: - if (getType().getBasicType() == EbtFloat) + case EOpNormalize: { - float x = operandArray[i].getFConst(); + ASSERT(getType().getBasicType() == EbtFloat); + float x = operandArray[i].getFConst(); float length = VectorLength(operandArray, objectSize); if (length) resultArray[i].setFConst(x / length); else - UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), infoSink, - &resultArray[i]); + UndefinedConstantFoldingError(getLine(), op, getType().getBasicType(), + diagnostics, &resultArray[i]); break; } - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - - case EOpDFdx: - case EOpDFdy: - case EOpFwidth: - if (getType().getBasicType() == EbtFloat) + case EOpBitfieldReverse: { + uint32_t value; + if (getType().getBasicType() == EbtInt) + { + value = static_cast(operandArray[i].getIConst()); + } + else + { + ASSERT(getType().getBasicType() == EbtUInt); + value = operandArray[i].getUConst(); + } + uint32_t result = gl::BitfieldReverse(value); + if (getType().getBasicType() == EbtInt) + { + resultArray[i].setIConst(static_cast(result)); + } + else + { + resultArray[i].setUConst(result); + } + break; + } + case EOpBitCount: + { + uint32_t value; + if (getType().getBasicType() == EbtInt) + { + value = static_cast(operandArray[i].getIConst()); + } + else + { + ASSERT(getType().getBasicType() == EbtUInt); + value = operandArray[i].getUConst(); + } + int result = gl::BitCount(value); + resultArray[i].setIConst(result); + break; + } + case EOpFindLSB: + { + uint32_t value; + if (getType().getBasicType() == EbtInt) + { + value = static_cast(operandArray[i].getIConst()); + } + else + { + ASSERT(getType().getBasicType() == EbtUInt); + value = operandArray[i].getUConst(); + } + resultArray[i].setIConst(gl::FindLSB(value)); + break; + } + case EOpFindMSB: + { + uint32_t value; + if (getType().getBasicType() == EbtInt) + { + int intValue = operandArray[i].getIConst(); + value = static_cast(intValue); + if (intValue < 0) + { + // Look for zero instead of one in value. This also handles the intValue == + // -1 special case, where the return value needs to be -1. + value = ~value; + } + } + else + { + ASSERT(getType().getBasicType() == EbtUInt); + value = operandArray[i].getUConst(); + } + resultArray[i].setIConst(gl::FindMSB(value)); + break; + } + case EOpDFdx: + case EOpDFdy: + case EOpFwidth: + ASSERT(getType().getBasicType() == EbtFloat); // Derivatives of constant arguments should be 0. resultArray[i].setFConst(0.0f); break; - } - infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant"); - return nullptr; - default: - return nullptr; + default: + return nullptr; } } return resultArray; } -bool TIntermConstantUnion::foldFloatTypeUnary(const TConstantUnion ¶meter, FloatTypeUnaryFunc builtinFunc, - TInfoSink &infoSink, TConstantUnion *result) const +void TIntermConstantUnion::foldFloatTypeUnary(const TConstantUnion ¶meter, + FloatTypeUnaryFunc builtinFunc, + TConstantUnion *result) const { ASSERT(builtinFunc); - if (getType().getBasicType() == EbtFloat) - { - result->setFConst(builtinFunc(parameter.getFConst())); - return true; - } - - infoSink.info.message( - EPrefixInternalError, getLine(), - "Unary operation not folded into constant"); - return false; + ASSERT(getType().getBasicType() == EbtFloat); + result->setFConst(builtinFunc(parameter.getFConst())); } // static -TConstantUnion *TIntermConstantUnion::FoldAggregateConstructor(TIntermAggregate *aggregate, - TInfoSink &infoSink) +TConstantUnion *TIntermConstantUnion::FoldAggregateConstructor(TIntermAggregate *aggregate) { ASSERT(aggregate->getSequence()->size() > 0u); size_t resultSize = aggregate->getType().getObjectSize(); @@ -1958,7 +2560,7 @@ TConstantUnion *TIntermConstantUnion::FoldAggregateConstructor(TIntermAggregate int argumentCols = argumentConstant->getType().getCols(); int argumentRows = argumentConstant->getType().getRows(); int resultCols = aggregate->getType().getCols(); - int resultRows = aggregate->getType().getRows(); + int resultRows = aggregate->getType().getRows(); for (int col = 0; col < resultCols; ++col) { for (int row = 0; row < resultRows; ++row) @@ -2001,664 +2603,728 @@ TConstantUnion *TIntermConstantUnion::FoldAggregateConstructor(TIntermAggregate return resultArray; } -// static -TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *aggregate, TInfoSink &infoSink) +bool TIntermAggregate::CanFoldAggregateBuiltInOp(TOperator op) { - TOperator op = aggregate->getOp(); - TIntermSequence *sequence = aggregate->getSequence(); - unsigned int paramsCount = static_cast(sequence->size()); - std::vector unionArrays(paramsCount); - std::vector objectSizes(paramsCount); + switch (op) + { + case EOpAtan: + case EOpPow: + case EOpMod: + case EOpMin: + case EOpMax: + case EOpClamp: + case EOpMix: + case EOpStep: + case EOpSmoothStep: + case EOpLdexp: + case EOpMulMatrixComponentWise: + case EOpOuterProduct: + case EOpEqualComponentWise: + case EOpNotEqualComponentWise: + case EOpLessThanComponentWise: + case EOpLessThanEqualComponentWise: + case EOpGreaterThanComponentWise: + case EOpGreaterThanEqualComponentWise: + case EOpDistance: + case EOpDot: + case EOpCross: + case EOpFaceforward: + case EOpReflect: + case EOpRefract: + case EOpBitfieldExtract: + case EOpBitfieldInsert: + return true; + default: + return false; + } +} + +// static +TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *aggregate, + TDiagnostics *diagnostics) +{ + TOperator op = aggregate->getOp(); + TIntermSequence *arguments = aggregate->getSequence(); + unsigned int argsCount = static_cast(arguments->size()); + std::vector unionArrays(argsCount); + std::vector objectSizes(argsCount); size_t maxObjectSize = 0; TBasicType basicType = EbtVoid; TSourceLoc loc; - for (unsigned int i = 0; i < paramsCount; i++) + for (unsigned int i = 0; i < argsCount; i++) { - TIntermConstantUnion *paramConstant = (*sequence)[i]->getAsConstantUnion(); - ASSERT(paramConstant != nullptr); // Should be checked already. + TIntermConstantUnion *argConstant = (*arguments)[i]->getAsConstantUnion(); + ASSERT(argConstant != nullptr); // Should be checked already. if (i == 0) { - basicType = paramConstant->getType().getBasicType(); - loc = paramConstant->getLine(); + basicType = argConstant->getType().getBasicType(); + loc = argConstant->getLine(); } - unionArrays[i] = paramConstant->getUnionArrayPointer(); - objectSizes[i] = paramConstant->getType().getObjectSize(); + unionArrays[i] = argConstant->getUnionArrayPointer(); + objectSizes[i] = argConstant->getType().getObjectSize(); if (objectSizes[i] > maxObjectSize) maxObjectSize = objectSizes[i]; } - if (!(*sequence)[0]->getAsTyped()->isMatrix()) + if (!(*arguments)[0]->getAsTyped()->isMatrix() && aggregate->getOp() != EOpOuterProduct) { - for (unsigned int i = 0; i < paramsCount; i++) + for (unsigned int i = 0; i < argsCount; i++) if (objectSizes[i] != maxObjectSize) unionArrays[i] = Vectorize(*unionArrays[i], maxObjectSize); } TConstantUnion *resultArray = nullptr; - if (paramsCount == 2) + + switch (op) { - // - // Binary built-in - // - switch (op) + case EOpAtan: { - case EOpAtan: + ASSERT(basicType == EbtFloat); + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) { - if (basicType == EbtFloat) - { - resultArray = new TConstantUnion[maxObjectSize]; - for (size_t i = 0; i < maxObjectSize; i++) - { - float y = unionArrays[0][i].getFConst(); - float x = unionArrays[1][i].getFConst(); - // Results are undefined if x and y are both 0. - if (x == 0.0f && y == 0.0f) - UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]); - else - resultArray[i].setFConst(atan2f(y, x)); - } - } + float y = unionArrays[0][i].getFConst(); + float x = unionArrays[1][i].getFConst(); + // Results are undefined if x and y are both 0. + if (x == 0.0f && y == 0.0f) + UndefinedConstantFoldingError(loc, op, basicType, diagnostics, &resultArray[i]); else - UNREACHABLE(); + resultArray[i].setFConst(atan2f(y, x)); } break; - - case EOpPow: - { - if (basicType == EbtFloat) - { - resultArray = new TConstantUnion[maxObjectSize]; - for (size_t i = 0; i < maxObjectSize; i++) - { - float x = unionArrays[0][i].getFConst(); - float y = unionArrays[1][i].getFConst(); - // Results are undefined if x < 0. - // Results are undefined if x = 0 and y <= 0. - if (x < 0.0f) - UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]); - else if (x == 0.0f && y <= 0.0f) - UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]); - else - resultArray[i].setFConst(powf(x, y)); - } - } - else - UNREACHABLE(); - } - break; - - case EOpMod: - { - if (basicType == EbtFloat) - { - resultArray = new TConstantUnion[maxObjectSize]; - for (size_t i = 0; i < maxObjectSize; i++) - { - float x = unionArrays[0][i].getFConst(); - float y = unionArrays[1][i].getFConst(); - resultArray[i].setFConst(x - y * floorf(x / y)); - } - } - else - UNREACHABLE(); - } - break; - - case EOpMin: - { - resultArray = new TConstantUnion[maxObjectSize]; - for (size_t i = 0; i < maxObjectSize; i++) - { - switch (basicType) - { - case EbtFloat: - resultArray[i].setFConst(std::min(unionArrays[0][i].getFConst(), unionArrays[1][i].getFConst())); - break; - case EbtInt: - resultArray[i].setIConst(std::min(unionArrays[0][i].getIConst(), unionArrays[1][i].getIConst())); - break; - case EbtUInt: - resultArray[i].setUConst(std::min(unionArrays[0][i].getUConst(), unionArrays[1][i].getUConst())); - break; - default: - UNREACHABLE(); - break; - } - } - } - break; - - case EOpMax: - { - resultArray = new TConstantUnion[maxObjectSize]; - for (size_t i = 0; i < maxObjectSize; i++) - { - switch (basicType) - { - case EbtFloat: - resultArray[i].setFConst(std::max(unionArrays[0][i].getFConst(), unionArrays[1][i].getFConst())); - break; - case EbtInt: - resultArray[i].setIConst(std::max(unionArrays[0][i].getIConst(), unionArrays[1][i].getIConst())); - break; - case EbtUInt: - resultArray[i].setUConst(std::max(unionArrays[0][i].getUConst(), unionArrays[1][i].getUConst())); - break; - default: - UNREACHABLE(); - break; - } - } - } - break; - - case EOpStep: - { - if (basicType == EbtFloat) - { - resultArray = new TConstantUnion[maxObjectSize]; - for (size_t i = 0; i < maxObjectSize; i++) - resultArray[i].setFConst(unionArrays[1][i].getFConst() < unionArrays[0][i].getFConst() ? 0.0f : 1.0f); - } - else - UNREACHABLE(); - } - break; - - case EOpLessThan: - { - resultArray = new TConstantUnion[maxObjectSize]; - for (size_t i = 0; i < maxObjectSize; i++) - { - switch (basicType) - { - case EbtFloat: - resultArray[i].setBConst(unionArrays[0][i].getFConst() < unionArrays[1][i].getFConst()); - break; - case EbtInt: - resultArray[i].setBConst(unionArrays[0][i].getIConst() < unionArrays[1][i].getIConst()); - break; - case EbtUInt: - resultArray[i].setBConst(unionArrays[0][i].getUConst() < unionArrays[1][i].getUConst()); - break; - default: - UNREACHABLE(); - break; - } - } - } - break; - - case EOpLessThanEqual: - { - resultArray = new TConstantUnion[maxObjectSize]; - for (size_t i = 0; i < maxObjectSize; i++) - { - switch (basicType) - { - case EbtFloat: - resultArray[i].setBConst(unionArrays[0][i].getFConst() <= unionArrays[1][i].getFConst()); - break; - case EbtInt: - resultArray[i].setBConst(unionArrays[0][i].getIConst() <= unionArrays[1][i].getIConst()); - break; - case EbtUInt: - resultArray[i].setBConst(unionArrays[0][i].getUConst() <= unionArrays[1][i].getUConst()); - break; - default: - UNREACHABLE(); - break; - } - } - } - break; - - case EOpGreaterThan: - { - resultArray = new TConstantUnion[maxObjectSize]; - for (size_t i = 0; i < maxObjectSize; i++) - { - switch (basicType) - { - case EbtFloat: - resultArray[i].setBConst(unionArrays[0][i].getFConst() > unionArrays[1][i].getFConst()); - break; - case EbtInt: - resultArray[i].setBConst(unionArrays[0][i].getIConst() > unionArrays[1][i].getIConst()); - break; - case EbtUInt: - resultArray[i].setBConst(unionArrays[0][i].getUConst() > unionArrays[1][i].getUConst()); - break; - default: - UNREACHABLE(); - break; - } - } - } - break; - - case EOpGreaterThanEqual: - { - resultArray = new TConstantUnion[maxObjectSize]; - for (size_t i = 0; i < maxObjectSize; i++) - { - switch (basicType) - { - case EbtFloat: - resultArray[i].setBConst(unionArrays[0][i].getFConst() >= unionArrays[1][i].getFConst()); - break; - case EbtInt: - resultArray[i].setBConst(unionArrays[0][i].getIConst() >= unionArrays[1][i].getIConst()); - break; - case EbtUInt: - resultArray[i].setBConst(unionArrays[0][i].getUConst() >= unionArrays[1][i].getUConst()); - break; - default: - UNREACHABLE(); - break; - } - } - } - break; - - case EOpVectorEqual: - { - resultArray = new TConstantUnion[maxObjectSize]; - for (size_t i = 0; i < maxObjectSize; i++) - { - switch (basicType) - { - case EbtFloat: - resultArray[i].setBConst(unionArrays[0][i].getFConst() == unionArrays[1][i].getFConst()); - break; - case EbtInt: - resultArray[i].setBConst(unionArrays[0][i].getIConst() == unionArrays[1][i].getIConst()); - break; - case EbtUInt: - resultArray[i].setBConst(unionArrays[0][i].getUConst() == unionArrays[1][i].getUConst()); - break; - case EbtBool: - resultArray[i].setBConst(unionArrays[0][i].getBConst() == unionArrays[1][i].getBConst()); - break; - default: - UNREACHABLE(); - break; - } - } - } - break; - - case EOpVectorNotEqual: - { - resultArray = new TConstantUnion[maxObjectSize]; - for (size_t i = 0; i < maxObjectSize; i++) - { - switch (basicType) - { - case EbtFloat: - resultArray[i].setBConst(unionArrays[0][i].getFConst() != unionArrays[1][i].getFConst()); - break; - case EbtInt: - resultArray[i].setBConst(unionArrays[0][i].getIConst() != unionArrays[1][i].getIConst()); - break; - case EbtUInt: - resultArray[i].setBConst(unionArrays[0][i].getUConst() != unionArrays[1][i].getUConst()); - break; - case EbtBool: - resultArray[i].setBConst(unionArrays[0][i].getBConst() != unionArrays[1][i].getBConst()); - break; - default: - UNREACHABLE(); - break; - } - } - } - break; - - case EOpDistance: - if (basicType == EbtFloat) - { - TConstantUnion *distanceArray = new TConstantUnion[maxObjectSize]; - resultArray = new TConstantUnion(); - for (size_t i = 0; i < maxObjectSize; i++) - { - float x = unionArrays[0][i].getFConst(); - float y = unionArrays[1][i].getFConst(); - distanceArray[i].setFConst(x - y); - } - resultArray->setFConst(VectorLength(distanceArray, maxObjectSize)); - } - else - UNREACHABLE(); - break; - - case EOpDot: - - if (basicType == EbtFloat) - { - resultArray = new TConstantUnion(); - resultArray->setFConst(VectorDotProduct(unionArrays[0], unionArrays[1], maxObjectSize)); - } - else - UNREACHABLE(); - break; - - case EOpCross: - if (basicType == EbtFloat && maxObjectSize == 3) - { - resultArray = new TConstantUnion[maxObjectSize]; - float x0 = unionArrays[0][0].getFConst(); - float x1 = unionArrays[0][1].getFConst(); - float x2 = unionArrays[0][2].getFConst(); - float y0 = unionArrays[1][0].getFConst(); - float y1 = unionArrays[1][1].getFConst(); - float y2 = unionArrays[1][2].getFConst(); - resultArray[0].setFConst(x1 * y2 - y1 * x2); - resultArray[1].setFConst(x2 * y0 - y2 * x0); - resultArray[2].setFConst(x0 * y1 - y0 * x1); - } - else - UNREACHABLE(); - break; - - case EOpReflect: - if (basicType == EbtFloat) - { - // genType reflect (genType I, genType N) : - // For the incident vector I and surface orientation N, returns the reflection direction: - // I - 2 * dot(N, I) * N. - resultArray = new TConstantUnion[maxObjectSize]; - float dotProduct = VectorDotProduct(unionArrays[1], unionArrays[0], maxObjectSize); - for (size_t i = 0; i < maxObjectSize; i++) - { - float result = unionArrays[0][i].getFConst() - - 2.0f * dotProduct * unionArrays[1][i].getFConst(); - resultArray[i].setFConst(result); - } - } - else - UNREACHABLE(); - break; - - case EOpMul: - if (basicType == EbtFloat && (*sequence)[0]->getAsTyped()->isMatrix() && - (*sequence)[1]->getAsTyped()->isMatrix()) - { - // Perform component-wise matrix multiplication. - resultArray = new TConstantUnion[maxObjectSize]; - int size = (*sequence)[0]->getAsTyped()->getNominalSize(); - angle::Matrix result = - GetMatrix(unionArrays[0], size).compMult(GetMatrix(unionArrays[1], size)); - SetUnionArrayFromMatrix(result, resultArray); - } - else - UNREACHABLE(); - break; - - case EOpOuterProduct: - if (basicType == EbtFloat) - { - size_t numRows = (*sequence)[0]->getAsTyped()->getType().getObjectSize(); - size_t numCols = (*sequence)[1]->getAsTyped()->getType().getObjectSize(); - resultArray = new TConstantUnion[numRows * numCols]; - angle::Matrix result = - GetMatrix(unionArrays[0], 1, static_cast(numCols)) - .outerProduct(GetMatrix(unionArrays[1], static_cast(numRows), 1)); - SetUnionArrayFromMatrix(result, resultArray); - } - else - UNREACHABLE(); - break; - - default: - UNREACHABLE(); - // TODO: Add constant folding support for other built-in operations that take 2 parameters and not handled above. - return nullptr; } - } - else if (paramsCount == 3) - { - // - // Ternary built-in - // - switch (op) + + case EOpPow: { - case EOpClamp: + ASSERT(basicType == EbtFloat); + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) { - resultArray = new TConstantUnion[maxObjectSize]; - for (size_t i = 0; i < maxObjectSize; i++) + float x = unionArrays[0][i].getFConst(); + float y = unionArrays[1][i].getFConst(); + // Results are undefined if x < 0. + // Results are undefined if x = 0 and y <= 0. + if (x < 0.0f) + UndefinedConstantFoldingError(loc, op, basicType, diagnostics, &resultArray[i]); + else if (x == 0.0f && y <= 0.0f) + UndefinedConstantFoldingError(loc, op, basicType, diagnostics, &resultArray[i]); + else + resultArray[i].setFConst(powf(x, y)); + } + break; + } + + case EOpMod: + { + ASSERT(basicType == EbtFloat); + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) + { + float x = unionArrays[0][i].getFConst(); + float y = unionArrays[1][i].getFConst(); + resultArray[i].setFConst(x - y * floorf(x / y)); + } + break; + } + + case EOpMin: + { + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) + { + switch (basicType) { - switch (basicType) - { - case EbtFloat: - { - float x = unionArrays[0][i].getFConst(); - float min = unionArrays[1][i].getFConst(); - float max = unionArrays[2][i].getFConst(); - // Results are undefined if min > max. - if (min > max) - UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]); - else - resultArray[i].setFConst(gl::clamp(x, min, max)); - } + case EbtFloat: + resultArray[i].setFConst( + std::min(unionArrays[0][i].getFConst(), unionArrays[1][i].getFConst())); break; - case EbtInt: - { - int x = unionArrays[0][i].getIConst(); - int min = unionArrays[1][i].getIConst(); - int max = unionArrays[2][i].getIConst(); - // Results are undefined if min > max. - if (min > max) - UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]); - else - resultArray[i].setIConst(gl::clamp(x, min, max)); - } + case EbtInt: + resultArray[i].setIConst( + std::min(unionArrays[0][i].getIConst(), unionArrays[1][i].getIConst())); break; - case EbtUInt: - { - unsigned int x = unionArrays[0][i].getUConst(); - unsigned int min = unionArrays[1][i].getUConst(); - unsigned int max = unionArrays[2][i].getUConst(); - // Results are undefined if min > max. - if (min > max) - UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]); - else - resultArray[i].setUConst(gl::clamp(x, min, max)); - } + case EbtUInt: + resultArray[i].setUConst( + std::min(unionArrays[0][i].getUConst(), unionArrays[1][i].getUConst())); break; - default: + default: UNREACHABLE(); break; - } } } break; - - case EOpMix: - { - if (basicType == EbtFloat) - { - resultArray = new TConstantUnion[maxObjectSize]; - for (size_t i = 0; i < maxObjectSize; i++) - { - float x = unionArrays[0][i].getFConst(); - float y = unionArrays[1][i].getFConst(); - TBasicType type = (*sequence)[2]->getAsTyped()->getType().getBasicType(); - if (type == EbtFloat) - { - // Returns the linear blend of x and y, i.e., x * (1 - a) + y * a. - float a = unionArrays[2][i].getFConst(); - resultArray[i].setFConst(x * (1.0f - a) + y * a); - } - else // 3rd parameter is EbtBool - { - ASSERT(type == EbtBool); - // Selects which vector each returned component comes from. - // For a component of a that is false, the corresponding component of x is returned. - // For a component of a that is true, the corresponding component of y is returned. - bool a = unionArrays[2][i].getBConst(); - resultArray[i].setFConst(a ? y : x); - } - } - } - else - UNREACHABLE(); - } - break; - - case EOpSmoothStep: - { - if (basicType == EbtFloat) - { - resultArray = new TConstantUnion[maxObjectSize]; - for (size_t i = 0; i < maxObjectSize; i++) - { - float edge0 = unionArrays[0][i].getFConst(); - float edge1 = unionArrays[1][i].getFConst(); - float x = unionArrays[2][i].getFConst(); - // Results are undefined if edge0 >= edge1. - if (edge0 >= edge1) - { - UndefinedConstantFoldingError(loc, op, basicType, infoSink, &resultArray[i]); - } - else - { - // Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and performs smooth - // Hermite interpolation between 0 and 1 when edge0 < x < edge1. - float t = gl::clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f); - resultArray[i].setFConst(t * t * (3.0f - 2.0f * t)); - } - } - } - else - UNREACHABLE(); - } - break; - - case EOpFaceForward: - if (basicType == EbtFloat) - { - // genType faceforward(genType N, genType I, genType Nref) : - // If dot(Nref, I) < 0 return N, otherwise return -N. - resultArray = new TConstantUnion[maxObjectSize]; - float dotProduct = VectorDotProduct(unionArrays[2], unionArrays[1], maxObjectSize); - for (size_t i = 0; i < maxObjectSize; i++) - { - if (dotProduct < 0) - resultArray[i].setFConst(unionArrays[0][i].getFConst()); - else - resultArray[i].setFConst(-unionArrays[0][i].getFConst()); - } - } - else - UNREACHABLE(); - break; - - case EOpRefract: - if (basicType == EbtFloat) - { - // genType refract(genType I, genType N, float eta) : - // For the incident vector I and surface normal N, and the ratio of indices of refraction eta, - // return the refraction vector. The result is computed by - // k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I)) - // if (k < 0.0) - // return genType(0.0) - // else - // return eta * I - (eta * dot(N, I) + sqrt(k)) * N - resultArray = new TConstantUnion[maxObjectSize]; - float dotProduct = VectorDotProduct(unionArrays[1], unionArrays[0], maxObjectSize); - for (size_t i = 0; i < maxObjectSize; i++) - { - float eta = unionArrays[2][i].getFConst(); - float k = 1.0f - eta * eta * (1.0f - dotProduct * dotProduct); - if (k < 0.0f) - resultArray[i].setFConst(0.0f); - else - resultArray[i].setFConst(eta * unionArrays[0][i].getFConst() - - (eta * dotProduct + sqrtf(k)) * unionArrays[1][i].getFConst()); - } - } - else - UNREACHABLE(); - break; - - default: - UNREACHABLE(); - // TODO: Add constant folding support for other built-in operations that take 3 parameters and not handled above. - return nullptr; } + + case EOpMax: + { + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) + { + switch (basicType) + { + case EbtFloat: + resultArray[i].setFConst( + std::max(unionArrays[0][i].getFConst(), unionArrays[1][i].getFConst())); + break; + case EbtInt: + resultArray[i].setIConst( + std::max(unionArrays[0][i].getIConst(), unionArrays[1][i].getIConst())); + break; + case EbtUInt: + resultArray[i].setUConst( + std::max(unionArrays[0][i].getUConst(), unionArrays[1][i].getUConst())); + break; + default: + UNREACHABLE(); + break; + } + } + break; + } + + case EOpStep: + { + ASSERT(basicType == EbtFloat); + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) + resultArray[i].setFConst( + unionArrays[1][i].getFConst() < unionArrays[0][i].getFConst() ? 0.0f : 1.0f); + break; + } + + case EOpLessThanComponentWise: + { + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) + { + switch (basicType) + { + case EbtFloat: + resultArray[i].setBConst(unionArrays[0][i].getFConst() < + unionArrays[1][i].getFConst()); + break; + case EbtInt: + resultArray[i].setBConst(unionArrays[0][i].getIConst() < + unionArrays[1][i].getIConst()); + break; + case EbtUInt: + resultArray[i].setBConst(unionArrays[0][i].getUConst() < + unionArrays[1][i].getUConst()); + break; + default: + UNREACHABLE(); + break; + } + } + break; + } + + case EOpLessThanEqualComponentWise: + { + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) + { + switch (basicType) + { + case EbtFloat: + resultArray[i].setBConst(unionArrays[0][i].getFConst() <= + unionArrays[1][i].getFConst()); + break; + case EbtInt: + resultArray[i].setBConst(unionArrays[0][i].getIConst() <= + unionArrays[1][i].getIConst()); + break; + case EbtUInt: + resultArray[i].setBConst(unionArrays[0][i].getUConst() <= + unionArrays[1][i].getUConst()); + break; + default: + UNREACHABLE(); + break; + } + } + break; + } + + case EOpGreaterThanComponentWise: + { + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) + { + switch (basicType) + { + case EbtFloat: + resultArray[i].setBConst(unionArrays[0][i].getFConst() > + unionArrays[1][i].getFConst()); + break; + case EbtInt: + resultArray[i].setBConst(unionArrays[0][i].getIConst() > + unionArrays[1][i].getIConst()); + break; + case EbtUInt: + resultArray[i].setBConst(unionArrays[0][i].getUConst() > + unionArrays[1][i].getUConst()); + break; + default: + UNREACHABLE(); + break; + } + } + break; + } + case EOpGreaterThanEqualComponentWise: + { + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) + { + switch (basicType) + { + case EbtFloat: + resultArray[i].setBConst(unionArrays[0][i].getFConst() >= + unionArrays[1][i].getFConst()); + break; + case EbtInt: + resultArray[i].setBConst(unionArrays[0][i].getIConst() >= + unionArrays[1][i].getIConst()); + break; + case EbtUInt: + resultArray[i].setBConst(unionArrays[0][i].getUConst() >= + unionArrays[1][i].getUConst()); + break; + default: + UNREACHABLE(); + break; + } + } + } + break; + + case EOpEqualComponentWise: + { + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) + { + switch (basicType) + { + case EbtFloat: + resultArray[i].setBConst(unionArrays[0][i].getFConst() == + unionArrays[1][i].getFConst()); + break; + case EbtInt: + resultArray[i].setBConst(unionArrays[0][i].getIConst() == + unionArrays[1][i].getIConst()); + break; + case EbtUInt: + resultArray[i].setBConst(unionArrays[0][i].getUConst() == + unionArrays[1][i].getUConst()); + break; + case EbtBool: + resultArray[i].setBConst(unionArrays[0][i].getBConst() == + unionArrays[1][i].getBConst()); + break; + default: + UNREACHABLE(); + break; + } + } + break; + } + + case EOpNotEqualComponentWise: + { + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) + { + switch (basicType) + { + case EbtFloat: + resultArray[i].setBConst(unionArrays[0][i].getFConst() != + unionArrays[1][i].getFConst()); + break; + case EbtInt: + resultArray[i].setBConst(unionArrays[0][i].getIConst() != + unionArrays[1][i].getIConst()); + break; + case EbtUInt: + resultArray[i].setBConst(unionArrays[0][i].getUConst() != + unionArrays[1][i].getUConst()); + break; + case EbtBool: + resultArray[i].setBConst(unionArrays[0][i].getBConst() != + unionArrays[1][i].getBConst()); + break; + default: + UNREACHABLE(); + break; + } + } + break; + } + + case EOpDistance: + { + ASSERT(basicType == EbtFloat); + TConstantUnion *distanceArray = new TConstantUnion[maxObjectSize]; + resultArray = new TConstantUnion(); + for (size_t i = 0; i < maxObjectSize; i++) + { + float x = unionArrays[0][i].getFConst(); + float y = unionArrays[1][i].getFConst(); + distanceArray[i].setFConst(x - y); + } + resultArray->setFConst(VectorLength(distanceArray, maxObjectSize)); + break; + } + + case EOpDot: + ASSERT(basicType == EbtFloat); + resultArray = new TConstantUnion(); + resultArray->setFConst(VectorDotProduct(unionArrays[0], unionArrays[1], maxObjectSize)); + break; + + case EOpCross: + { + ASSERT(basicType == EbtFloat && maxObjectSize == 3); + resultArray = new TConstantUnion[maxObjectSize]; + float x0 = unionArrays[0][0].getFConst(); + float x1 = unionArrays[0][1].getFConst(); + float x2 = unionArrays[0][2].getFConst(); + float y0 = unionArrays[1][0].getFConst(); + float y1 = unionArrays[1][1].getFConst(); + float y2 = unionArrays[1][2].getFConst(); + resultArray[0].setFConst(x1 * y2 - y1 * x2); + resultArray[1].setFConst(x2 * y0 - y2 * x0); + resultArray[2].setFConst(x0 * y1 - y0 * x1); + break; + } + + case EOpReflect: + { + ASSERT(basicType == EbtFloat); + // genType reflect (genType I, genType N) : + // For the incident vector I and surface orientation N, returns the reflection + // direction: + // I - 2 * dot(N, I) * N. + resultArray = new TConstantUnion[maxObjectSize]; + float dotProduct = VectorDotProduct(unionArrays[1], unionArrays[0], maxObjectSize); + for (size_t i = 0; i < maxObjectSize; i++) + { + float result = unionArrays[0][i].getFConst() - + 2.0f * dotProduct * unionArrays[1][i].getFConst(); + resultArray[i].setFConst(result); + } + break; + } + + case EOpMulMatrixComponentWise: + { + ASSERT(basicType == EbtFloat && (*arguments)[0]->getAsTyped()->isMatrix() && + (*arguments)[1]->getAsTyped()->isMatrix()); + // Perform component-wise matrix multiplication. + resultArray = new TConstantUnion[maxObjectSize]; + int size = (*arguments)[0]->getAsTyped()->getNominalSize(); + angle::Matrix result = + GetMatrix(unionArrays[0], size).compMult(GetMatrix(unionArrays[1], size)); + SetUnionArrayFromMatrix(result, resultArray); + break; + } + + case EOpOuterProduct: + { + ASSERT(basicType == EbtFloat); + size_t numRows = (*arguments)[0]->getAsTyped()->getType().getObjectSize(); + size_t numCols = (*arguments)[1]->getAsTyped()->getType().getObjectSize(); + resultArray = new TConstantUnion[numRows * numCols]; + angle::Matrix result = + GetMatrix(unionArrays[0], static_cast(numRows), 1) + .outerProduct(GetMatrix(unionArrays[1], 1, static_cast(numCols))); + SetUnionArrayFromMatrix(result, resultArray); + break; + } + + case EOpClamp: + { + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) + { + switch (basicType) + { + case EbtFloat: + { + float x = unionArrays[0][i].getFConst(); + float min = unionArrays[1][i].getFConst(); + float max = unionArrays[2][i].getFConst(); + // Results are undefined if min > max. + if (min > max) + UndefinedConstantFoldingError(loc, op, basicType, diagnostics, + &resultArray[i]); + else + resultArray[i].setFConst(gl::clamp(x, min, max)); + break; + } + + case EbtInt: + { + int x = unionArrays[0][i].getIConst(); + int min = unionArrays[1][i].getIConst(); + int max = unionArrays[2][i].getIConst(); + // Results are undefined if min > max. + if (min > max) + UndefinedConstantFoldingError(loc, op, basicType, diagnostics, + &resultArray[i]); + else + resultArray[i].setIConst(gl::clamp(x, min, max)); + break; + } + case EbtUInt: + { + unsigned int x = unionArrays[0][i].getUConst(); + unsigned int min = unionArrays[1][i].getUConst(); + unsigned int max = unionArrays[2][i].getUConst(); + // Results are undefined if min > max. + if (min > max) + UndefinedConstantFoldingError(loc, op, basicType, diagnostics, + &resultArray[i]); + else + resultArray[i].setUConst(gl::clamp(x, min, max)); + break; + } + default: + UNREACHABLE(); + break; + } + } + break; + } + + case EOpMix: + { + ASSERT(basicType == EbtFloat); + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) + { + float x = unionArrays[0][i].getFConst(); + float y = unionArrays[1][i].getFConst(); + TBasicType type = (*arguments)[2]->getAsTyped()->getType().getBasicType(); + if (type == EbtFloat) + { + // Returns the linear blend of x and y, i.e., x * (1 - a) + y * a. + float a = unionArrays[2][i].getFConst(); + resultArray[i].setFConst(x * (1.0f - a) + y * a); + } + else // 3rd parameter is EbtBool + { + ASSERT(type == EbtBool); + // Selects which vector each returned component comes from. + // For a component of a that is false, the corresponding component of x is + // returned. + // For a component of a that is true, the corresponding component of y is + // returned. + bool a = unionArrays[2][i].getBConst(); + resultArray[i].setFConst(a ? y : x); + } + } + break; + } + + case EOpSmoothStep: + { + ASSERT(basicType == EbtFloat); + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) + { + float edge0 = unionArrays[0][i].getFConst(); + float edge1 = unionArrays[1][i].getFConst(); + float x = unionArrays[2][i].getFConst(); + // Results are undefined if edge0 >= edge1. + if (edge0 >= edge1) + { + UndefinedConstantFoldingError(loc, op, basicType, diagnostics, &resultArray[i]); + } + else + { + // Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and performs smooth + // Hermite interpolation between 0 and 1 when edge0 < x < edge1. + float t = gl::clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f); + resultArray[i].setFConst(t * t * (3.0f - 2.0f * t)); + } + } + break; + } + + case EOpLdexp: + { + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; i++) + { + float x = unionArrays[0][i].getFConst(); + int exp = unionArrays[1][i].getIConst(); + if (exp > 128) + { + UndefinedConstantFoldingError(loc, op, basicType, diagnostics, &resultArray[i]); + } + else + { + resultArray[i].setFConst(gl::Ldexp(x, exp)); + } + } + break; + } + + case EOpFaceforward: + { + ASSERT(basicType == EbtFloat); + // genType faceforward(genType N, genType I, genType Nref) : + // If dot(Nref, I) < 0 return N, otherwise return -N. + resultArray = new TConstantUnion[maxObjectSize]; + float dotProduct = VectorDotProduct(unionArrays[2], unionArrays[1], maxObjectSize); + for (size_t i = 0; i < maxObjectSize; i++) + { + if (dotProduct < 0) + resultArray[i].setFConst(unionArrays[0][i].getFConst()); + else + resultArray[i].setFConst(-unionArrays[0][i].getFConst()); + } + break; + } + + case EOpRefract: + { + ASSERT(basicType == EbtFloat); + // genType refract(genType I, genType N, float eta) : + // For the incident vector I and surface normal N, and the ratio of indices of + // refraction eta, + // return the refraction vector. The result is computed by + // k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I)) + // if (k < 0.0) + // return genType(0.0) + // else + // return eta * I - (eta * dot(N, I) + sqrt(k)) * N + resultArray = new TConstantUnion[maxObjectSize]; + float dotProduct = VectorDotProduct(unionArrays[1], unionArrays[0], maxObjectSize); + for (size_t i = 0; i < maxObjectSize; i++) + { + float eta = unionArrays[2][i].getFConst(); + float k = 1.0f - eta * eta * (1.0f - dotProduct * dotProduct); + if (k < 0.0f) + resultArray[i].setFConst(0.0f); + else + resultArray[i].setFConst(eta * unionArrays[0][i].getFConst() - + (eta * dotProduct + sqrtf(k)) * + unionArrays[1][i].getFConst()); + } + break; + } + case EOpBitfieldExtract: + { + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; ++i) + { + int offset = unionArrays[1][0].getIConst(); + int bits = unionArrays[2][0].getIConst(); + if (bits == 0) + { + if (aggregate->getBasicType() == EbtInt) + { + resultArray[i].setIConst(0); + } + else + { + ASSERT(aggregate->getBasicType() == EbtUInt); + resultArray[i].setUConst(0); + } + } + else if (offset < 0 || bits < 0 || offset >= 32 || bits > 32 || offset + bits > 32) + { + UndefinedConstantFoldingError(loc, op, aggregate->getBasicType(), diagnostics, + &resultArray[i]); + } + else + { + // bits can be 32 here, so we need to avoid bit shift overflow. + uint32_t maskMsb = 1u << (bits - 1); + uint32_t mask = ((maskMsb - 1u) | maskMsb) << offset; + if (aggregate->getBasicType() == EbtInt) + { + uint32_t value = static_cast(unionArrays[0][i].getIConst()); + uint32_t resultUnsigned = (value & mask) >> offset; + if ((resultUnsigned & maskMsb) != 0) + { + // The most significant bits (from bits+1 to the most significant bit) + // should be set to 1. + uint32_t higherBitsMask = ((1u << (32 - bits)) - 1u) << bits; + resultUnsigned |= higherBitsMask; + } + resultArray[i].setIConst(static_cast(resultUnsigned)); + } + else + { + ASSERT(aggregate->getBasicType() == EbtUInt); + uint32_t value = unionArrays[0][i].getUConst(); + resultArray[i].setUConst((value & mask) >> offset); + } + } + } + break; + } + case EOpBitfieldInsert: + { + resultArray = new TConstantUnion[maxObjectSize]; + for (size_t i = 0; i < maxObjectSize; ++i) + { + int offset = unionArrays[2][0].getIConst(); + int bits = unionArrays[3][0].getIConst(); + if (bits == 0) + { + if (aggregate->getBasicType() == EbtInt) + { + int32_t base = unionArrays[0][i].getIConst(); + resultArray[i].setIConst(base); + } + else + { + ASSERT(aggregate->getBasicType() == EbtUInt); + uint32_t base = unionArrays[0][i].getUConst(); + resultArray[i].setUConst(base); + } + } + else if (offset < 0 || bits < 0 || offset >= 32 || bits > 32 || offset + bits > 32) + { + UndefinedConstantFoldingError(loc, op, aggregate->getBasicType(), diagnostics, + &resultArray[i]); + } + else + { + // bits can be 32 here, so we need to avoid bit shift overflow. + uint32_t maskMsb = 1u << (bits - 1); + uint32_t insertMask = ((maskMsb - 1u) | maskMsb) << offset; + uint32_t baseMask = ~insertMask; + if (aggregate->getBasicType() == EbtInt) + { + uint32_t base = static_cast(unionArrays[0][i].getIConst()); + uint32_t insert = static_cast(unionArrays[1][i].getIConst()); + uint32_t resultUnsigned = + (base & baseMask) | ((insert << offset) & insertMask); + resultArray[i].setIConst(static_cast(resultUnsigned)); + } + else + { + ASSERT(aggregate->getBasicType() == EbtUInt); + uint32_t base = unionArrays[0][i].getUConst(); + uint32_t insert = unionArrays[1][i].getUConst(); + resultArray[i].setUConst((base & baseMask) | + ((insert << offset) & insertMask)); + } + } + } + break; + } + + default: + UNREACHABLE(); + return nullptr; } return resultArray; } -// static -TString TIntermTraverser::hash(const TString &name, ShHashFunction64 hashFunction) -{ - if (hashFunction == NULL || name.empty()) - return name; - khronos_uint64_t number = (*hashFunction)(name.c_str(), name.length()); - TStringStream stream; - stream << HASHED_NAME_PREFIX << std::hex << number; - TString hashedName = stream.str(); - return hashedName; -} - -void TIntermTraverser::updateTree() -{ - for (size_t ii = 0; ii < mInsertions.size(); ++ii) - { - const NodeInsertMultipleEntry &insertion = mInsertions[ii]; - ASSERT(insertion.parent); - if (!insertion.insertionsAfter.empty()) - { - bool inserted = insertion.parent->insertChildNodes(insertion.position + 1, - insertion.insertionsAfter); - ASSERT(inserted); - UNUSED_ASSERTION_VARIABLE(inserted); - } - if (!insertion.insertionsBefore.empty()) - { - bool inserted = - insertion.parent->insertChildNodes(insertion.position, insertion.insertionsBefore); - ASSERT(inserted); - UNUSED_ASSERTION_VARIABLE(inserted); - } - } - for (size_t ii = 0; ii < mReplacements.size(); ++ii) - { - const NodeUpdateEntry &replacement = mReplacements[ii]; - ASSERT(replacement.parent); - bool replaced = replacement.parent->replaceChildNode( - replacement.original, replacement.replacement); - ASSERT(replaced); - UNUSED_ASSERTION_VARIABLE(replaced); - - if (!replacement.originalBecomesChildOfReplacement) - { - // In AST traversing, a parent is visited before its children. - // After we replace a node, if its immediate child is to - // be replaced, we need to make sure we don't update the replaced - // node; instead, we update the replacement node. - for (size_t jj = ii + 1; jj < mReplacements.size(); ++jj) - { - NodeUpdateEntry &replacement2 = mReplacements[jj]; - if (replacement2.parent == replacement.original) - replacement2.parent = replacement.replacement; - } - } - } - for (size_t ii = 0; ii < mMultiReplacements.size(); ++ii) - { - const NodeReplaceWithMultipleEntry &replacement = mMultiReplacements[ii]; - ASSERT(replacement.parent); - bool replaced = replacement.parent->replaceChildNodeWithMultiple( - replacement.original, replacement.replacements); - ASSERT(replaced); - UNUSED_ASSERTION_VARIABLE(replaced); - } - - mInsertions.clear(); - mReplacements.clear(); - mMultiReplacements.clear(); -} +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/IntermNode.h b/src/3rdparty/angle/src/compiler/translator/IntermNode.h index ad500e2b1f..2170916201 100644 --- a/src/3rdparty/angle/src/compiler/translator/IntermNode.h +++ b/src/3rdparty/angle/src/compiler/translator/IntermNode.h @@ -25,14 +25,27 @@ #include "compiler/translator/Common.h" #include "compiler/translator/ConstantUnion.h" #include "compiler/translator/Operator.h" +#include "compiler/translator/SymbolUniqueId.h" #include "compiler/translator/Types.h" +namespace sh +{ + +class TDiagnostics; + class TIntermTraverser; class TIntermAggregate; +class TIntermBlock; +class TIntermInvariantDeclaration; +class TIntermDeclaration; +class TIntermFunctionPrototype; +class TIntermFunctionDefinition; +class TIntermSwizzle; class TIntermBinary; class TIntermUnary; class TIntermConstantUnion; -class TIntermSelection; +class TIntermTernary; +class TIntermIfElse; class TIntermSwitch; class TIntermCase; class TIntermTyped; @@ -41,8 +54,10 @@ class TIntermLoop; class TInfoSink; class TInfoSinkBase; class TIntermRaw; +class TIntermBranch; class TSymbolTable; +class TFunction; // Encapsulate an identifier string and track whether it is coming from the original shader code // (not internal) or from ANGLE (internal). Usually internal names shouldn't be decorated or hashed. @@ -79,7 +94,7 @@ class TIntermNode : angle::NonCopyable mLine.first_file = mLine.last_file = 0; mLine.first_line = mLine.last_line = 0; } - virtual ~TIntermNode() { } + virtual ~TIntermNode() {} const TSourceLoc &getLine() const { return mLine; } void setLine(const TSourceLoc &l) { mLine = l; } @@ -87,20 +102,27 @@ class TIntermNode : angle::NonCopyable virtual void traverse(TIntermTraverser *) = 0; virtual TIntermTyped *getAsTyped() { return 0; } virtual TIntermConstantUnion *getAsConstantUnion() { return 0; } + virtual TIntermFunctionDefinition *getAsFunctionDefinition() { return nullptr; } virtual TIntermAggregate *getAsAggregate() { return 0; } + virtual TIntermBlock *getAsBlock() { return nullptr; } + virtual TIntermFunctionPrototype *getAsFunctionPrototypeNode() { return nullptr; } + virtual TIntermInvariantDeclaration *getAsInvariantDeclarationNode() { return nullptr; } + virtual TIntermDeclaration *getAsDeclarationNode() { return nullptr; } + virtual TIntermSwizzle *getAsSwizzleNode() { return nullptr; } virtual TIntermBinary *getAsBinaryNode() { return 0; } virtual TIntermUnary *getAsUnaryNode() { return 0; } - virtual TIntermSelection *getAsSelectionNode() { return 0; } + virtual TIntermTernary *getAsTernaryNode() { return nullptr; } + virtual TIntermIfElse *getAsIfElseNode() { return nullptr; } virtual TIntermSwitch *getAsSwitchNode() { return 0; } virtual TIntermCase *getAsCaseNode() { return 0; } virtual TIntermSymbol *getAsSymbolNode() { return 0; } virtual TIntermLoop *getAsLoopNode() { return 0; } virtual TIntermRaw *getAsRawNode() { return 0; } + virtual TIntermBranch *getAsBranchNode() { return 0; } // Replace a child node. Return true if |original| is a child // node and it is replaced; otherwise, return false. - virtual bool replaceChildNode( - TIntermNode *original, TIntermNode *replacement) = 0; + virtual bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) = 0; protected: TSourceLoc mLine; @@ -121,12 +143,15 @@ struct TIntermNodePair class TIntermTyped : public TIntermNode { public: - TIntermTyped(const TType &t) : mType(t) { } + TIntermTyped(const TType &t) : mType(t) {} virtual TIntermTyped *deepCopy() const = 0; TIntermTyped *getAsTyped() override { return this; } + // True if executing the expression represented by this node affects state, like values of + // variables. False if the executing the expression only computes its return value without + // affecting state. May return true conservatively. virtual bool hasSideEffects() const = 0; void setType(const TType &t) { mType = t; } @@ -137,6 +162,7 @@ class TIntermTyped : public TIntermNode TBasicType getBasicType() const { return mType.getBasicType(); } TQualifier getQualifier() const { return mType.getQualifier(); } TPrecision getPrecision() const { return mType.getPrecision(); } + TMemoryQualifier getMemoryQualifier() const { return mType.getMemoryQualifier(); } int getCols() const { return mType.getCols(); } int getRows() const { return mType.getRows(); } int getNominalSize() const { return mType.getNominalSize(); } @@ -144,14 +170,16 @@ class TIntermTyped : public TIntermNode bool isInterfaceBlock() const { return mType.isInterfaceBlock(); } bool isMatrix() const { return mType.isMatrix(); } - bool isArray() const { return mType.isArray(); } + bool isArray() const { return mType.isArray(); } bool isVector() const { return mType.isVector(); } bool isScalar() const { return mType.isScalar(); } bool isScalarInt() const { return mType.isScalarInt(); } const char *getBasicString() const { return mType.getBasicString(); } TString getCompleteString() const { return mType.getCompleteString(); } - int getArraySize() const { return mType.getArraySize(); } + unsigned int getOutermostArraySize() const { return mType.getOutermostArraySize(); } + + bool isConstructorWithOnlyConstantUnionParameters(); protected: TType mType; @@ -176,10 +204,7 @@ class TIntermLoop : public TIntermNode TIntermNode *init, TIntermTyped *cond, TIntermTyped *expr, - TIntermAggregate *body) - : mType(type), mInit(init), mCond(cond), mExpr(expr), mBody(body), mUnrollFlag(false) - { - } + TIntermBlock *body); TIntermLoop *getAsLoopNode() override { return this; } void traverse(TIntermTraverser *it) override; @@ -189,19 +214,19 @@ class TIntermLoop : public TIntermNode TIntermNode *getInit() { return mInit; } TIntermTyped *getCondition() { return mCond; } TIntermTyped *getExpression() { return mExpr; } - TIntermAggregate *getBody() { return mBody; } + TIntermBlock *getBody() { return mBody; } - void setUnrollFlag(bool flag) { mUnrollFlag = flag; } - bool getUnrollFlag() const { return mUnrollFlag; } + void setInit(TIntermNode *init) { mInit = init; } + void setCondition(TIntermTyped *condition) { mCond = condition; } + void setExpression(TIntermTyped *expression) { mExpr = expression; } + void setBody(TIntermBlock *body) { mBody = body; } protected: TLoopType mType; - TIntermNode *mInit; // for-loop initialization - TIntermTyped *mCond; // loop exit condition - TIntermTyped *mExpr; // for-loop expression - TIntermAggregate *mBody; // loop body - - bool mUnrollFlag; // Whether the loop should be unrolled or not. + TIntermNode *mInit; // for-loop initialization + TIntermTyped *mCond; // loop exit condition + TIntermTyped *mExpr; // for-loop expression + TIntermBlock *mBody; // loop body }; // @@ -210,17 +235,16 @@ class TIntermLoop : public TIntermNode class TIntermBranch : public TIntermNode { public: - TIntermBranch(TOperator op, TIntermTyped *e) - : mFlowOp(op), - mExpression(e) { } + TIntermBranch(TOperator op, TIntermTyped *e) : mFlowOp(op), mExpression(e) {} void traverse(TIntermTraverser *it) override; + TIntermBranch *getAsBranchNode() override { return this; } bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override; TOperator getFlowOp() { return mFlowOp; } - TIntermTyped* getExpression() { return mExpression; } + TIntermTyped *getExpression() { return mExpression; } -protected: + protected: TOperator mFlowOp; TIntermTyped *mExpression; // non-zero except for "return exp;" statements }; @@ -234,7 +258,7 @@ class TIntermSymbol : public TIntermTyped // if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym. // If sym comes from per process globalpoolallocator, then it causes increased memory usage // per compile it is essential to use "symbol = sym" to assign to symbol - TIntermSymbol(int id, const TString &symbol, const TType &type) + TIntermSymbol(const TSymbolUniqueId &id, const TString &symbol, const TType &type) : TIntermTyped(type), mId(id), mSymbol(symbol) { } @@ -243,11 +267,10 @@ class TIntermSymbol : public TIntermTyped bool hasSideEffects() const override { return false; } - int getId() const { return mId; } + int getId() const { return mId.get(); } const TString &getSymbol() const { return mSymbol.getString(); } const TName &getName() const { return mSymbol; } - - void setId(int newId) { mId = newId; } + TName &getName() { return mSymbol; } void setInternal(bool internal) { mSymbol.setInternal(internal); } @@ -256,7 +279,7 @@ class TIntermSymbol : public TIntermTyped bool replaceChildNode(TIntermNode *, TIntermNode *) override { return false; } protected: - int mId; + const TSymbolUniqueId mId; TName mSymbol; private: @@ -269,9 +292,7 @@ class TIntermSymbol : public TIntermTyped class TIntermRaw : public TIntermTyped { public: - TIntermRaw(const TType &type, const TString &rawText) - : TIntermTyped(type), - mRawText(rawText) { } + TIntermRaw(const TType &type, const TString &rawText) : TIntermTyped(type), mRawText(rawText) {} TIntermRaw(const TIntermRaw &) = delete; TIntermTyped *deepCopy() const override @@ -305,6 +326,7 @@ class TIntermConstantUnion : public TIntermTyped TIntermConstantUnion(const TConstantUnion *unionPointer, const TType &type) : TIntermTyped(type), mUnionArrayPointer(unionPointer) { + ASSERT(unionPointer); } TIntermTyped *deepCopy() const override { return new TIntermConstantUnion(*this); } @@ -332,6 +354,7 @@ class TIntermConstantUnion : public TIntermTyped void replaceConstantUnion(const TConstantUnion *safeConstantUnion) { + ASSERT(safeConstantUnion); // Previous union pointer freed on pool deallocation. mUnionArrayPointer = safeConstantUnion; } @@ -340,21 +363,27 @@ class TIntermConstantUnion : public TIntermTyped void traverse(TIntermTraverser *it) override; bool replaceChildNode(TIntermNode *, TIntermNode *) override { return false; } - TConstantUnion *foldBinary(TOperator op, TIntermConstantUnion *rightNode, TInfoSink &infoSink); - TConstantUnion *foldUnaryWithDifferentReturnType(TOperator op, TInfoSink &infoSink); - TConstantUnion *foldUnaryWithSameReturnType(TOperator op, TInfoSink &infoSink); + TConstantUnion *foldBinary(TOperator op, + TIntermConstantUnion *rightNode, + TDiagnostics *diagnostics, + const TSourceLoc &line); + const TConstantUnion *foldIndexing(int index); + TConstantUnion *foldUnaryNonComponentWise(TOperator op); + TConstantUnion *foldUnaryComponentWise(TOperator op, TDiagnostics *diagnostics); - static TConstantUnion *FoldAggregateConstructor(TIntermAggregate *aggregate, - TInfoSink &infoSink); - static TConstantUnion *FoldAggregateBuiltIn(TIntermAggregate *aggregate, TInfoSink &infoSink); + static TConstantUnion *FoldAggregateConstructor(TIntermAggregate *aggregate); + static TConstantUnion *FoldAggregateBuiltIn(TIntermAggregate *aggregate, + TDiagnostics *diagnostics); protected: // Same data may be shared between multiple constant unions, so it can't be modified. const TConstantUnion *mUnionArrayPointer; private: - typedef float(*FloatTypeUnaryFunc) (float); - bool foldFloatTypeUnary(const TConstantUnion ¶meter, FloatTypeUnaryFunc builtinFunc, TInfoSink &infoSink, TConstantUnion *result) const; + typedef float (*FloatTypeUnaryFunc)(float); + void foldFloatTypeUnary(const TConstantUnion ¶meter, + FloatTypeUnaryFunc builtinFunc, + TConstantUnion *result) const; TIntermConstantUnion(const TIntermConstantUnion &node); // Note: not deleted, just private! }; @@ -366,25 +395,57 @@ class TIntermOperator : public TIntermTyped { public: TOperator getOp() const { return mOp; } - void setOp(TOperator op) { mOp = op; } bool isAssignment() const; bool isMultiplication() const; bool isConstructor() const; + // Returns true for calls mapped to EOpCall*, false for built-ins that have their own specific + // ops. + bool isFunctionCall() const; + bool hasSideEffects() const override { return isAssignment(); } protected: - TIntermOperator(TOperator op) - : TIntermTyped(TType(EbtFloat, EbpUndefined)), - mOp(op) {} - TIntermOperator(TOperator op, const TType &type) - : TIntermTyped(type), - mOp(op) {} + TIntermOperator(TOperator op) : TIntermTyped(TType(EbtFloat, EbpUndefined)), mOp(op) {} + TIntermOperator(TOperator op, const TType &type) : TIntermTyped(type), mOp(op) {} TIntermOperator(const TIntermOperator &) = default; - TOperator mOp; + const TOperator mOp; +}; + +// Node for vector swizzles. +class TIntermSwizzle : public TIntermTyped +{ + public: + // This constructor determines the type of the node based on the operand. + TIntermSwizzle(TIntermTyped *operand, const TVector &swizzleOffsets); + + TIntermTyped *deepCopy() const override { return new TIntermSwizzle(*this); } + + TIntermSwizzle *getAsSwizzleNode() override { return this; }; + void traverse(TIntermTraverser *it) override; + bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override; + + bool hasSideEffects() const override { return mOperand->hasSideEffects(); } + + TIntermTyped *getOperand() { return mOperand; } + void writeOffsetsAsXYZW(TInfoSinkBase *out) const; + + bool hasDuplicateOffsets() const; + bool offsetsMatch(int offset) const; + + TIntermTyped *fold(); + + protected: + TIntermTyped *mOperand; + TVector mSwizzleOffsets; + + private: + void promote(); + + TIntermSwizzle(const TIntermSwizzle &node); // Note: not deleted, just private! }; // @@ -393,12 +454,17 @@ class TIntermOperator : public TIntermTyped class TIntermBinary : public TIntermOperator { public: - TIntermBinary(TOperator op) - : TIntermOperator(op), - mAddIndexClamp(false) {} + // This constructor determines the type of the binary node based on the operands and op. + TIntermBinary(TOperator op, TIntermTyped *left, TIntermTyped *right); TIntermTyped *deepCopy() const override { return new TIntermBinary(*this); } + static TOperator GetMulOpBasedOnOperands(const TType &left, const TType &right); + static TOperator GetMulAssignOpBasedOnOperands(const TType &left, const TType &right); + static TQualifier GetCommaQualifier(int shaderVersion, + const TIntermTyped *left, + const TIntermTyped *right); + TIntermBinary *getAsBinaryNode() override { return this; }; void traverse(TIntermTraverser *it) override; bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override; @@ -408,24 +474,23 @@ class TIntermBinary : public TIntermOperator return isAssignment() || mLeft->hasSideEffects() || mRight->hasSideEffects(); } - void setLeft(TIntermTyped *node) { mLeft = node; } - void setRight(TIntermTyped *node) { mRight = node; } TIntermTyped *getLeft() const { return mLeft; } TIntermTyped *getRight() const { return mRight; } - bool promote(TInfoSink &); - TIntermTyped *fold(TInfoSink &infoSink); + TIntermTyped *fold(TDiagnostics *diagnostics); void setAddIndexClamp() { mAddIndexClamp = true; } bool getAddIndexClamp() { return mAddIndexClamp; } protected: - TIntermTyped* mLeft; - TIntermTyped* mRight; + TIntermTyped *mLeft; + TIntermTyped *mRight; // If set to true, wrap any EOpIndexIndirect with a clamp to bounds. bool mAddIndexClamp; private: + void promote(); + TIntermBinary(const TIntermBinary &node); // Note: not deleted, just private! }; @@ -435,14 +500,7 @@ class TIntermBinary : public TIntermOperator class TIntermUnary : public TIntermOperator { public: - TIntermUnary(TOperator op, const TType &type) - : TIntermOperator(op, type), - mOperand(NULL), - mUseEmulatedFunction(false) {} - TIntermUnary(TOperator op) - : TIntermOperator(op), - mOperand(NULL), - mUseEmulatedFunction(false) {} + TIntermUnary(TOperator op, TIntermTyped *operand); TIntermTyped *deepCopy() const override { return new TIntermUnary(*this); } @@ -452,10 +510,8 @@ class TIntermUnary : public TIntermOperator bool hasSideEffects() const override { return isAssignment() || mOperand->hasSideEffects(); } - void setOperand(TIntermTyped *operand) { mOperand = operand; } TIntermTyped *getOperand() { return mOperand; } - void promote(const TType *funcReturnType); - TIntermTyped *fold(TInfoSink &infoSink); + TIntermTyped *fold(TDiagnostics *diagnostics); void setUseEmulatedFunction() { mUseEmulatedFunction = true; } bool getUseEmulatedFunction() { return mUseEmulatedFunction; } @@ -468,125 +524,348 @@ class TIntermUnary : public TIntermOperator bool mUseEmulatedFunction; private: + void promote(); + TIntermUnary(const TIntermUnary &node); // note: not deleted, just private! }; +class TFunctionSymbolInfo +{ + public: + POOL_ALLOCATOR_NEW_DELETE(); + TFunctionSymbolInfo(const TSymbolUniqueId &id); + TFunctionSymbolInfo() : mId(nullptr), mKnownToNotHaveSideEffects(false) {} + + TFunctionSymbolInfo(const TFunctionSymbolInfo &info); + TFunctionSymbolInfo &operator=(const TFunctionSymbolInfo &info); + + void setFromFunction(const TFunction &function); + + void setNameObj(const TName &name) { mName = name; } + const TName &getNameObj() const { return mName; } + + const TString &getName() const { return mName.getString(); } + void setName(const TString &name) { mName.setString(name); } + bool isMain() const { return mName.getString() == "main"; } + + void setKnownToNotHaveSideEffects(bool knownToNotHaveSideEffects) + { + mKnownToNotHaveSideEffects = knownToNotHaveSideEffects; + } + bool isKnownToNotHaveSideEffects() const { return mKnownToNotHaveSideEffects; } + + void setId(const TSymbolUniqueId &functionId); + const TSymbolUniqueId &getId() const; + + bool isImageFunction() const + { + return getName() == "imageSize" || getName() == "imageLoad" || getName() == "imageStore"; + } + + private: + TName mName; + TSymbolUniqueId *mId; + bool mKnownToNotHaveSideEffects; +}; + typedef TVector TIntermSequence; typedef TVector TQualifierList; // -// Nodes that operate on an arbitrary sized set of children. +// This is just to help yacc. // -class TIntermAggregate : public TIntermOperator +struct TIntermFunctionCallOrMethod +{ + TIntermSequence *arguments; + TIntermNode *thisNode; +}; + +// Interface for node classes that have an arbitrarily sized set of children. +class TIntermAggregateBase { public: - TIntermAggregate() - : TIntermOperator(EOpNull), - mUserDefined(false), - mUseEmulatedFunction(false), - mGotPrecisionFromChildren(false) - { - } - TIntermAggregate(TOperator op) - : TIntermOperator(op), - mUseEmulatedFunction(false), - mGotPrecisionFromChildren(false) - { - } - ~TIntermAggregate() { } + virtual ~TIntermAggregateBase() {} + + virtual TIntermSequence *getSequence() = 0; + virtual const TIntermSequence *getSequence() const = 0; + + bool replaceChildNodeWithMultiple(TIntermNode *original, const TIntermSequence &replacements); + bool insertChildNodes(TIntermSequence::size_type position, const TIntermSequence &insertions); + + protected: + TIntermAggregateBase() {} + + bool replaceChildNodeInternal(TIntermNode *original, TIntermNode *replacement); +}; + +// +// Nodes that operate on an arbitrary sized set of children. +// +class TIntermAggregate : public TIntermOperator, public TIntermAggregateBase +{ + public: + static TIntermAggregate *CreateFunctionCall(const TFunction &func, TIntermSequence *arguments); + + // If using this, ensure that there's a consistent function definition with the same symbol id + // added to the AST. + static TIntermAggregate *CreateFunctionCall(const TType &type, + const TSymbolUniqueId &id, + const TName &name, + TIntermSequence *arguments); + + static TIntermAggregate *CreateBuiltInFunctionCall(const TFunction &func, + TIntermSequence *arguments); + static TIntermAggregate *CreateConstructor(const TType &type, + TIntermSequence *arguments); + static TIntermAggregate *Create(const TType &type, TOperator op, TIntermSequence *arguments); + ~TIntermAggregate() {} // Note: only supported for nodes that can be a part of an expression. TIntermTyped *deepCopy() const override { return new TIntermAggregate(*this); } + TIntermAggregate *shallowCopy() const; + TIntermAggregate *getAsAggregate() override { return this; } void traverse(TIntermTraverser *it) override; bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override; - bool replaceChildNodeWithMultiple(TIntermNode *original, TIntermSequence replacements); - bool insertChildNodes(TIntermSequence::size_type position, TIntermSequence insertions); - // Conservatively assume function calls and other aggregate operators have side-effects - bool hasSideEffects() const override { return true; } - TIntermTyped *fold(TInfoSink &infoSink); - TIntermSequence *getSequence() { return &mSequence; } + bool hasSideEffects() const override; - void setNameObj(const TName &name) { mName = name; } - const TName &getNameObj() const { return mName; } + static bool CanFoldAggregateBuiltInOp(TOperator op); + TIntermTyped *fold(TDiagnostics *diagnostics); - void setName(const TString &name) { mName.setString(name); } - const TString &getName() const { return mName.getString(); } + TIntermSequence *getSequence() override { return &mArguments; } + const TIntermSequence *getSequence() const override { return &mArguments; } - void setUserDefined() { mUserDefined = true; } - bool isUserDefined() const { return mUserDefined; } - - void setFunctionId(int functionId) { mFunctionId = functionId; } - int getFunctionId() const { return mFunctionId; } + TString getSymbolTableMangledName() const; void setUseEmulatedFunction() { mUseEmulatedFunction = true; } bool getUseEmulatedFunction() { return mUseEmulatedFunction; } - bool areChildrenConstQualified(); - void setPrecisionFromChildren(); - void setBuiltInFunctionPrecision(); - // Returns true if changing parameter precision may affect the return value. bool gotPrecisionFromChildren() const { return mGotPrecisionFromChildren; } + TFunctionSymbolInfo *getFunctionSymbolInfo() { return &mFunctionInfo; } + const TFunctionSymbolInfo *getFunctionSymbolInfo() const { return &mFunctionInfo; } + protected: - TIntermSequence mSequence; - TName mName; - bool mUserDefined; // used for user defined function names - int mFunctionId; + TIntermSequence mArguments; // If set to true, replace the built-in function call with an emulated one - // to work around driver bugs. + // to work around driver bugs. Only for calls mapped to ops other than EOpCall*. bool mUseEmulatedFunction; bool mGotPrecisionFromChildren; + TFunctionSymbolInfo mFunctionInfo; + private: + TIntermAggregate(const TType &type, TOperator op, TIntermSequence *arguments); + TIntermAggregate(const TIntermAggregate &node); // note: not deleted, just private! + + void setTypePrecisionAndQualifier(const TType &type); + + bool areChildrenConstQualified(); + + void setPrecisionFromChildren(); + + void setPrecisionForBuiltInOp(); + + // Returns true if precision was set according to special rules for this built-in. + bool setPrecisionForSpecialBuiltInOp(); + + // Used for built-in functions under EOpCallBuiltInFunction. The function name in the symbol + // info needs to be set before calling this. + void setBuiltInFunctionPrecision(); }; -// -// For if tests. -// -class TIntermSelection : public TIntermTyped +// A list of statements. Either the root node which contains declarations and function definitions, +// or a block that can be marked with curly braces {}. +class TIntermBlock : public TIntermNode, public TIntermAggregateBase { public: - TIntermSelection(TIntermTyped *cond, TIntermNode *trueB, TIntermNode *falseB) - : TIntermTyped(TType(EbtVoid, EbpUndefined)), - mCondition(cond), - mTrueBlock(trueB), - mFalseBlock(falseB) {} - TIntermSelection(TIntermTyped *cond, TIntermNode *trueB, TIntermNode *falseB, - const TType &type) - : TIntermTyped(type), - mCondition(cond), - mTrueBlock(trueB), - mFalseBlock(falseB) {} + TIntermBlock() : TIntermNode() {} + ~TIntermBlock() {} - // Note: only supported for ternary operator nodes. - TIntermTyped *deepCopy() const override { return new TIntermSelection(*this); } + TIntermBlock *getAsBlock() override { return this; } + void traverse(TIntermTraverser *it) override; + bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override; + + // Only intended for initially building the block. + void appendStatement(TIntermNode *statement); + + TIntermSequence *getSequence() override { return &mStatements; } + const TIntermSequence *getSequence() const override { return &mStatements; } + + protected: + TIntermSequence mStatements; +}; + +// Function prototype. May be in the AST either as a function prototype declaration or as a part of +// a function definition. The type of the node is the function return type. +class TIntermFunctionPrototype : public TIntermTyped, public TIntermAggregateBase +{ + public: + // TODO(oetuaho@nvidia.com): See if TFunctionSymbolInfo could be added to constructor + // parameters. + TIntermFunctionPrototype(const TType &type, const TSymbolUniqueId &id) + : TIntermTyped(type), mFunctionInfo(id) + { + } + ~TIntermFunctionPrototype() {} + + TIntermFunctionPrototype *getAsFunctionPrototypeNode() override { return this; } + void traverse(TIntermTraverser *it) override; + bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override; + + TIntermTyped *deepCopy() const override + { + UNREACHABLE(); + return nullptr; + } + bool hasSideEffects() const override + { + UNREACHABLE(); + return true; + } + + // Only intended for initially building the declaration. + void appendParameter(TIntermSymbol *parameter); + + TIntermSequence *getSequence() override { return &mParameters; } + const TIntermSequence *getSequence() const override { return &mParameters; } + + TFunctionSymbolInfo *getFunctionSymbolInfo() { return &mFunctionInfo; } + const TFunctionSymbolInfo *getFunctionSymbolInfo() const { return &mFunctionInfo; } + + protected: + TIntermSequence mParameters; + + TFunctionSymbolInfo mFunctionInfo; +}; + +// Node for function definitions. The prototype child node stores the function header including +// parameters, and the body child node stores the function body. +class TIntermFunctionDefinition : public TIntermNode +{ + public: + TIntermFunctionDefinition(TIntermFunctionPrototype *prototype, TIntermBlock *body) + : TIntermNode(), mPrototype(prototype), mBody(body) + { + ASSERT(prototype != nullptr); + ASSERT(body != nullptr); + } + + TIntermFunctionDefinition *getAsFunctionDefinition() override { return this; } + void traverse(TIntermTraverser *it) override; + bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override; + + TIntermFunctionPrototype *getFunctionPrototype() const { return mPrototype; } + TIntermBlock *getBody() const { return mBody; } + + const TFunctionSymbolInfo *getFunctionSymbolInfo() const + { + return mPrototype->getFunctionSymbolInfo(); + } + + private: + TIntermFunctionPrototype *mPrototype; + TIntermBlock *mBody; +}; + +// Struct, interface block or variable declaration. Can contain multiple variable declarators. +class TIntermDeclaration : public TIntermNode, public TIntermAggregateBase +{ + public: + TIntermDeclaration() : TIntermNode() {} + ~TIntermDeclaration() {} + + TIntermDeclaration *getAsDeclarationNode() override { return this; } + void traverse(TIntermTraverser *it) override; + bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override; + + // Only intended for initially building the declaration. + // The declarator node should be either TIntermSymbol or TIntermBinary with op set to + // EOpInitialize. + void appendDeclarator(TIntermTyped *declarator); + + TIntermSequence *getSequence() override { return &mDeclarators; } + const TIntermSequence *getSequence() const override { return &mDeclarators; } + protected: + TIntermSequence mDeclarators; +}; + +// Specialized declarations for attributing invariance. +class TIntermInvariantDeclaration : public TIntermNode +{ + public: + TIntermInvariantDeclaration(TIntermSymbol *symbol, const TSourceLoc &line); + + virtual TIntermInvariantDeclaration *getAsInvariantDeclarationNode() override { return this; } + + TIntermSymbol *getSymbol() { return mSymbol; } void traverse(TIntermTraverser *it) override; bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override; - // Conservatively assume selections have side-effects - bool hasSideEffects() const override { return true; } + private: + TIntermSymbol *mSymbol; +}; - bool usesTernaryOperator() const { return getBasicType() != EbtVoid; } - TIntermNode *getCondition() const { return mCondition; } - TIntermNode *getTrueBlock() const { return mTrueBlock; } - TIntermNode *getFalseBlock() const { return mFalseBlock; } - TIntermSelection *getAsSelectionNode() override { return this; } +// For ternary operators like a ? b : c. +class TIntermTernary : public TIntermTyped +{ + public: + TIntermTernary(TIntermTyped *cond, TIntermTyped *trueExpression, TIntermTyped *falseExpression); + + void traverse(TIntermTraverser *it) override; + bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override; + + TIntermTyped *getCondition() const { return mCondition; } + TIntermTyped *getTrueExpression() const { return mTrueExpression; } + TIntermTyped *getFalseExpression() const { return mFalseExpression; } + TIntermTernary *getAsTernaryNode() override { return this; } + + TIntermTyped *deepCopy() const override { return new TIntermTernary(*this); } + + bool hasSideEffects() const override + { + return mCondition->hasSideEffects() || mTrueExpression->hasSideEffects() || + mFalseExpression->hasSideEffects(); + } + + TIntermTyped *fold(); + + private: + TIntermTernary(const TIntermTernary &node); // Note: not deleted, just private! + + static TQualifier DetermineQualifier(TIntermTyped *cond, + TIntermTyped *trueExpression, + TIntermTyped *falseExpression); + + TIntermTyped *mCondition; + TIntermTyped *mTrueExpression; + TIntermTyped *mFalseExpression; +}; + +class TIntermIfElse : public TIntermNode +{ + public: + TIntermIfElse(TIntermTyped *cond, TIntermBlock *trueB, TIntermBlock *falseB); + + void traverse(TIntermTraverser *it) override; + bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override; + + TIntermTyped *getCondition() const { return mCondition; } + TIntermBlock *getTrueBlock() const { return mTrueBlock; } + TIntermBlock *getFalseBlock() const { return mFalseBlock; } + TIntermIfElse *getAsIfElseNode() override { return this; } protected: TIntermTyped *mCondition; - TIntermNode *mTrueBlock; - TIntermNode *mFalseBlock; - - private: - TIntermSelection(const TIntermSelection &node); // Note: not deleted, just private! + TIntermBlock *mTrueBlock; + TIntermBlock *mFalseBlock; }; // @@ -595,26 +874,22 @@ class TIntermSelection : public TIntermTyped class TIntermSwitch : public TIntermNode { public: - TIntermSwitch(TIntermTyped *init, TIntermAggregate *statementList) - : TIntermNode(), - mInit(init), - mStatementList(statementList) - { - } + TIntermSwitch(TIntermTyped *init, TIntermBlock *statementList); void traverse(TIntermTraverser *it) override; - bool replaceChildNode( - TIntermNode *original, TIntermNode *replacement) override; + bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override; TIntermSwitch *getAsSwitchNode() override { return this; } TIntermTyped *getInit() { return mInit; } - TIntermAggregate *getStatementList() { return mStatementList; } - void setStatementList(TIntermAggregate *statementList) { mStatementList = statementList; } + TIntermBlock *getStatementList() { return mStatementList; } + + // Must be called with a non-null statementList. + void setStatementList(TIntermBlock *statementList); protected: TIntermTyped *mInit; - TIntermAggregate *mStatementList; + TIntermBlock *mStatementList; }; // @@ -623,15 +898,10 @@ class TIntermSwitch : public TIntermNode class TIntermCase : public TIntermNode { public: - TIntermCase(TIntermTyped *condition) - : TIntermNode(), - mCondition(condition) - { - } + TIntermCase(TIntermTyped *condition) : TIntermNode(), mCondition(condition) {} void traverse(TIntermTraverser *it) override; - bool replaceChildNode( - TIntermNode *original, TIntermNode *replacement) override; + bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override; TIntermCase *getAsCaseNode() override { return this; } @@ -642,321 +912,6 @@ class TIntermCase : public TIntermNode TIntermTyped *mCondition; }; -enum Visit -{ - PreVisit, - InVisit, - PostVisit -}; - -// -// For traversing the tree. User should derive from this class overriding the visit functions, -// and then pass an object of the subclass to a traverse method of a node. -// -// The traverse*() functions may also be overridden do other bookkeeping on the tree to provide -// contextual information to the visit functions, such as whether the node is the target of an -// assignment. -// -// When using this, just fill in the methods for nodes you want visited. -// Return false from a pre-visit to skip visiting that node's subtree. -// -class TIntermTraverser : angle::NonCopyable -{ - public: - POOL_ALLOCATOR_NEW_DELETE(); - TIntermTraverser(bool preVisit, bool inVisit, bool postVisit) - : preVisit(preVisit), - inVisit(inVisit), - postVisit(postVisit), - mDepth(0), - mMaxDepth(0), - mTemporaryIndex(nullptr) - { - } - virtual ~TIntermTraverser() {} - - virtual void visitSymbol(TIntermSymbol *node) {} - virtual void visitRaw(TIntermRaw *node) {} - virtual void visitConstantUnion(TIntermConstantUnion *node) {} - virtual bool visitBinary(Visit visit, TIntermBinary *node) { return true; } - virtual bool visitUnary(Visit visit, TIntermUnary *node) { return true; } - virtual bool visitSelection(Visit visit, TIntermSelection *node) { return true; } - virtual bool visitSwitch(Visit visit, TIntermSwitch *node) { return true; } - virtual bool visitCase(Visit visit, TIntermCase *node) { return true; } - virtual bool visitAggregate(Visit visit, TIntermAggregate *node) { return true; } - virtual bool visitLoop(Visit visit, TIntermLoop *node) { return true; } - virtual bool visitBranch(Visit visit, TIntermBranch *node) { return true; } - - // The traverse functions contain logic for iterating over the children of the node - // and calling the visit functions in the appropriate places. They also track some - // context that may be used by the visit functions. - virtual void traverseSymbol(TIntermSymbol *node); - virtual void traverseRaw(TIntermRaw *node); - virtual void traverseConstantUnion(TIntermConstantUnion *node); - virtual void traverseBinary(TIntermBinary *node); - virtual void traverseUnary(TIntermUnary *node); - virtual void traverseSelection(TIntermSelection *node); - virtual void traverseSwitch(TIntermSwitch *node); - virtual void traverseCase(TIntermCase *node); - virtual void traverseAggregate(TIntermAggregate *node); - virtual void traverseLoop(TIntermLoop *node); - virtual void traverseBranch(TIntermBranch *node); - - int getMaxDepth() const { return mMaxDepth; } - - // Return the original name if hash function pointer is NULL; - // otherwise return the hashed name. - static TString hash(const TString &name, ShHashFunction64 hashFunction); - - // If traversers need to replace nodes, they can add the replacements in - // mReplacements/mMultiReplacements during traversal and the user of the traverser should call - // this function after traversal to perform them. - void updateTree(); - - // Start creating temporary symbols from the given temporary symbol index + 1. - void useTemporaryIndex(unsigned int *temporaryIndex); - - protected: - void incrementDepth(TIntermNode *current) - { - mDepth++; - mMaxDepth = std::max(mMaxDepth, mDepth); - mPath.push_back(current); - } - - void decrementDepth() - { - mDepth--; - mPath.pop_back(); - } - - TIntermNode *getParentNode() - { - return mPath.size() == 0 ? NULL : mPath.back(); - } - - void pushParentBlock(TIntermAggregate *node); - void incrementParentBlockPos(); - void popParentBlock(); - - bool parentNodeIsBlock() - { - return !mParentBlockStack.empty() && getParentNode() == mParentBlockStack.back().node; - } - - const bool preVisit; - const bool inVisit; - const bool postVisit; - - int mDepth; - int mMaxDepth; - - // All the nodes from root to the current node's parent during traversing. - TVector mPath; - - // To replace a single node with another on the parent node - struct NodeUpdateEntry - { - NodeUpdateEntry(TIntermNode *_parent, - TIntermNode *_original, - TIntermNode *_replacement, - bool _originalBecomesChildOfReplacement) - : parent(_parent), - original(_original), - replacement(_replacement), - originalBecomesChildOfReplacement(_originalBecomesChildOfReplacement) {} - - TIntermNode *parent; - TIntermNode *original; - TIntermNode *replacement; - bool originalBecomesChildOfReplacement; - }; - - // To replace a single node with multiple nodes on the parent aggregate node - struct NodeReplaceWithMultipleEntry - { - NodeReplaceWithMultipleEntry(TIntermAggregate *_parent, TIntermNode *_original, TIntermSequence _replacements) - : parent(_parent), - original(_original), - replacements(_replacements) - { - } - - TIntermAggregate *parent; - TIntermNode *original; - TIntermSequence replacements; - }; - - // To insert multiple nodes on the parent aggregate node - struct NodeInsertMultipleEntry - { - NodeInsertMultipleEntry(TIntermAggregate *_parent, - TIntermSequence::size_type _position, - TIntermSequence _insertionsBefore, - TIntermSequence _insertionsAfter) - : parent(_parent), - position(_position), - insertionsBefore(_insertionsBefore), - insertionsAfter(_insertionsAfter) - { - } - - TIntermAggregate *parent; - TIntermSequence::size_type position; - TIntermSequence insertionsBefore; - TIntermSequence insertionsAfter; - }; - - // During traversing, save all the changes that need to happen into - // mReplacements/mMultiReplacements, then do them by calling updateTree(). - // Multi replacements are processed after single replacements. - std::vector mReplacements; - std::vector mMultiReplacements; - std::vector mInsertions; - - // Helper to insert statements in the parent block (sequence) of the node currently being traversed. - // The statements will be inserted before the node being traversed once updateTree is called. - // Should only be called during PreVisit or PostVisit from sequence nodes. - // Note that inserting more than one set of nodes to the same parent node on a single updateTree call is not - // supported. - void insertStatementsInParentBlock(const TIntermSequence &insertions); - - // Same as above, but supports simultaneous insertion of statements before and after the node - // currently being traversed. - void insertStatementsInParentBlock(const TIntermSequence &insertionsBefore, - const TIntermSequence &insertionsAfter); - - // Helper to create a temporary symbol node with the given qualifier. - TIntermSymbol *createTempSymbol(const TType &type, TQualifier qualifier); - // Helper to create a temporary symbol node. - TIntermSymbol *createTempSymbol(const TType &type); - // Create a node that declares but doesn't initialize a temporary symbol. - TIntermAggregate *createTempDeclaration(const TType &type); - // Create a node that initializes the current temporary symbol with initializer having the given qualifier. - TIntermAggregate *createTempInitDeclaration(TIntermTyped *initializer, TQualifier qualifier); - // Create a node that initializes the current temporary symbol with initializer. - TIntermAggregate *createTempInitDeclaration(TIntermTyped *initializer); - // Create a node that assigns rightNode to the current temporary symbol. - TIntermBinary *createTempAssignment(TIntermTyped *rightNode); - // Increment temporary symbol index. - void nextTemporaryIndex(); - - private: - struct ParentBlock - { - ParentBlock(TIntermAggregate *nodeIn, TIntermSequence::size_type posIn) - : node(nodeIn), - pos(posIn) - { - } - - TIntermAggregate *node; - TIntermSequence::size_type pos; - }; - // All the code blocks from the root to the current node's parent during traversal. - std::vector mParentBlockStack; - - unsigned int *mTemporaryIndex; -}; - -// Traverser parent class that tracks where a node is a destination of a write operation and so is -// required to be an l-value. -class TLValueTrackingTraverser : public TIntermTraverser -{ - public: - TLValueTrackingTraverser(bool preVisit, - bool inVisit, - bool postVisit, - const TSymbolTable &symbolTable, - int shaderVersion) - : TIntermTraverser(preVisit, inVisit, postVisit), - mOperatorRequiresLValue(false), - mInFunctionCallOutParameter(false), - mSymbolTable(symbolTable), - mShaderVersion(shaderVersion) - { - } - virtual ~TLValueTrackingTraverser() {} - - void traverseBinary(TIntermBinary *node) override; - void traverseUnary(TIntermUnary *node) override; - void traverseAggregate(TIntermAggregate *node) override; - - protected: - bool isLValueRequiredHere() const - { - return mOperatorRequiresLValue || mInFunctionCallOutParameter; - } - - // Return true if the prototype or definition of the function being called has been encountered - // during traversal. - bool isInFunctionMap(const TIntermAggregate *callNode) const; - - private: - // Track whether an l-value is required in the node that is currently being traversed by the - // surrounding operator. - // Use isLValueRequiredHere to check all conditions which require an l-value. - void setOperatorRequiresLValue(bool lValueRequired) - { - mOperatorRequiresLValue = lValueRequired; - } - bool operatorRequiresLValue() const { return mOperatorRequiresLValue; } - - // Add a function encountered during traversal to the function map. - void addToFunctionMap(const TName &name, TIntermSequence *paramSequence); - - // Return the parameters sequence from the function definition or prototype. - TIntermSequence *getFunctionParameters(const TIntermAggregate *callNode); - - // Track whether an l-value is required inside a function call. - void setInFunctionCallOutParameter(bool inOutParameter); - bool isInFunctionCallOutParameter() const; - - bool mOperatorRequiresLValue; - bool mInFunctionCallOutParameter; - - struct TNameComparator - { - bool operator()(const TName &a, const TName &b) const - { - int compareResult = a.getString().compare(b.getString()); - if (compareResult != 0) - return compareResult < 0; - // Internal functions may have same names as non-internal functions. - return !a.isInternal() && b.isInternal(); - } - }; - - // Map from mangled function names to their parameter sequences - TMap mFunctionMap; - - const TSymbolTable &mSymbolTable; - const int mShaderVersion; -}; - -// -// For traversing the tree, and computing max depth. -// Takes a maximum depth limit to prevent stack overflow. -// -class TMaxDepthTraverser : public TIntermTraverser -{ - public: - POOL_ALLOCATOR_NEW_DELETE(); - TMaxDepthTraverser(int depthLimit) - : TIntermTraverser(true, true, false), - mDepthLimit(depthLimit) { } - - bool visitBinary(Visit, TIntermBinary *) override { return depthCheck(); } - bool visitUnary(Visit, TIntermUnary *) override { return depthCheck(); } - bool visitSelection(Visit, TIntermSelection *) override { return depthCheck(); } - bool visitAggregate(Visit, TIntermAggregate *) override { return depthCheck(); } - bool visitLoop(Visit, TIntermLoop *) override { return depthCheck(); } - bool visitBranch(Visit, TIntermBranch *) override { return depthCheck(); } - - protected: - bool depthCheck() const { return mMaxDepth < mDepthLimit; } - - int mDepthLimit; -}; +} // namespace sh #endif // COMPILER_TRANSLATOR_INTERMNODE_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/IntermNodePatternMatcher.cpp b/src/3rdparty/angle/src/compiler/translator/IntermNodePatternMatcher.cpp new file mode 100644 index 0000000000..567e8f7440 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/IntermNodePatternMatcher.cpp @@ -0,0 +1,157 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// IntermNodePatternMatcher is a helper class for matching node trees to given patterns. +// It can be used whenever the same checks for certain node structures are common to multiple AST +// traversers. +// + +#include "compiler/translator/IntermNodePatternMatcher.h" + +#include "compiler/translator/IntermNode.h" + +namespace sh +{ + +IntermNodePatternMatcher::IntermNodePatternMatcher(const unsigned int mask) : mMask(mask) +{ +} + +// static +bool IntermNodePatternMatcher::IsDynamicIndexingOfVectorOrMatrix(TIntermBinary *node) +{ + return node->getOp() == EOpIndexIndirect && !node->getLeft()->isArray() && + node->getLeft()->getBasicType() != EbtStruct; +} + +bool IntermNodePatternMatcher::matchInternal(TIntermBinary *node, TIntermNode *parentNode) +{ + if ((mMask & kExpressionReturningArray) != 0) + { + if (node->isArray() && node->getOp() == EOpAssign && parentNode != nullptr && + !parentNode->getAsBlock()) + { + return true; + } + } + + if ((mMask & kUnfoldedShortCircuitExpression) != 0) + { + if (node->getRight()->hasSideEffects() && + (node->getOp() == EOpLogicalOr || node->getOp() == EOpLogicalAnd)) + { + return true; + } + } + return false; +} + +bool IntermNodePatternMatcher::match(TIntermUnary *node) +{ + if ((mMask & kArrayLengthMethod) != 0) + { + if (node->getOp() == EOpArrayLength) + { + return true; + } + } + return false; +} + +bool IntermNodePatternMatcher::match(TIntermBinary *node, TIntermNode *parentNode) +{ + // L-value tracking information is needed to check for dynamic indexing in L-value. + // Traversers that don't track l-values can still use this class and match binary nodes with + // this variation of this method if they don't need to check for dynamic indexing in l-values. + ASSERT((mMask & kDynamicIndexingOfVectorOrMatrixInLValue) == 0); + return matchInternal(node, parentNode); +} + +bool IntermNodePatternMatcher::match(TIntermBinary *node, + TIntermNode *parentNode, + bool isLValueRequiredHere) +{ + if (matchInternal(node, parentNode)) + { + return true; + } + if ((mMask & kDynamicIndexingOfVectorOrMatrixInLValue) != 0) + { + if (isLValueRequiredHere && IsDynamicIndexingOfVectorOrMatrix(node)) + { + return true; + } + } + return false; +} + +bool IntermNodePatternMatcher::match(TIntermAggregate *node, TIntermNode *parentNode) +{ + if ((mMask & kExpressionReturningArray) != 0) + { + if (parentNode != nullptr) + { + TIntermBinary *parentBinary = parentNode->getAsBinaryNode(); + bool parentIsAssignment = + (parentBinary != nullptr && + (parentBinary->getOp() == EOpAssign || parentBinary->getOp() == EOpInitialize)); + + if (node->getType().isArray() && !parentIsAssignment && + (node->isConstructor() || node->isFunctionCall()) && !parentNode->getAsBlock()) + { + return true; + } + } + } + return false; +} + +bool IntermNodePatternMatcher::match(TIntermTernary *node) +{ + if ((mMask & kUnfoldedShortCircuitExpression) != 0) + { + return true; + } + return false; +} + +bool IntermNodePatternMatcher::match(TIntermDeclaration *node) +{ + if ((mMask & kMultiDeclaration) != 0) + { + if (node->getSequence()->size() > 1) + { + return true; + } + } + if ((mMask & kArrayDeclaration) != 0) + { + if (node->getSequence()->front()->getAsTyped()->getType().isStructureContainingArrays()) + { + return true; + } + // Need to check from all declarators whether they are arrays since that may vary between + // declarators. + for (TIntermNode *declarator : *node->getSequence()) + { + if (declarator->getAsTyped()->isArray()) + { + return true; + } + } + } + if ((mMask & kNamelessStructDeclaration) != 0) + { + TIntermTyped *declarator = node->getSequence()->front()->getAsTyped(); + if (declarator->getBasicType() == EbtStruct && + declarator->getType().getStruct()->name() == "") + { + return true; + } + } + return false; +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/IntermNodePatternMatcher.h b/src/3rdparty/angle/src/compiler/translator/IntermNodePatternMatcher.h new file mode 100644 index 0000000000..997fc2ef10 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/IntermNodePatternMatcher.h @@ -0,0 +1,75 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// IntermNodePatternMatcher is a helper class for matching node trees to given patterns. +// It can be used whenever the same checks for certain node structures are common to multiple AST +// traversers. +// + +#ifndef COMPILER_TRANSLATOR_INTERMNODEPATTERNMATCHER_H_ +#define COMPILER_TRANSLATOR_INTERMNODEPATTERNMATCHER_H_ + +namespace sh +{ + +class TIntermAggregate; +class TIntermBinary; +class TIntermDeclaration; +class TIntermNode; +class TIntermTernary; +class TIntermUnary; + +class IntermNodePatternMatcher +{ + public: + static bool IsDynamicIndexingOfVectorOrMatrix(TIntermBinary *node); + + enum PatternType + { + // Matches expressions that are unfolded to if statements by UnfoldShortCircuitToIf + kUnfoldedShortCircuitExpression = 0x0001, + + // Matches expressions that return arrays with the exception of simple statements where a + // constructor or function call result is assigned. + kExpressionReturningArray = 0x0001 << 1, + + // Matches dynamic indexing of vectors or matrices in l-values. + kDynamicIndexingOfVectorOrMatrixInLValue = 0x0001 << 2, + + // Matches declarations with more than one declared variables. + kMultiDeclaration = 0x0001 << 3, + + // Matches declarations of arrays. + kArrayDeclaration = 0x0001 << 4, + + // Matches declarations of structs where the struct type does not have a name. + kNamelessStructDeclaration = 0x0001 << 5, + + // Matches array length() method. + kArrayLengthMethod = 0x0001 << 6 + }; + IntermNodePatternMatcher(const unsigned int mask); + + bool match(TIntermUnary *node); + + bool match(TIntermBinary *node, TIntermNode *parentNode); + + // Use this version for checking binary node matches in case you're using flag + // kDynamicIndexingOfVectorOrMatrixInLValue. + bool match(TIntermBinary *node, TIntermNode *parentNode, bool isLValueRequiredHere); + + bool match(TIntermAggregate *node, TIntermNode *parentNode); + bool match(TIntermTernary *node); + bool match(TIntermDeclaration *node); + + private: + const unsigned int mMask; + + bool matchInternal(TIntermBinary *node, TIntermNode *parentNode); +}; + +} // namespace sh + +#endif diff --git a/src/3rdparty/angle/src/compiler/translator/IntermNode_util.cpp b/src/3rdparty/angle/src/compiler/translator/IntermNode_util.cpp new file mode 100644 index 0000000000..9f1f596c43 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/IntermNode_util.cpp @@ -0,0 +1,254 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// IntermNode_util.cpp: High-level utilities for creating AST nodes and node hierarchies. Mostly +// meant to be used in AST transforms. + +#include "compiler/translator/IntermNode_util.h" + +#include "compiler/translator/SymbolTable.h" + +namespace sh +{ + +namespace +{ + +TName GetInternalFunctionName(const char *name) +{ + TString nameStr(name); + TName nameObj(nameStr); + nameObj.setInternal(true); + return nameObj; +} + +const TFunction *LookUpBuiltInFunction(const TString &name, + const TIntermSequence *arguments, + const TSymbolTable &symbolTable, + int shaderVersion) +{ + TString mangledName = TFunction::GetMangledNameFromCall(name, *arguments); + TSymbol *symbol = symbolTable.findBuiltIn(mangledName, shaderVersion); + if (symbol) + { + ASSERT(symbol->isFunction()); + return static_cast(symbol); + } + return nullptr; +} + +} // anonymous namespace + +TIntermFunctionPrototype *CreateInternalFunctionPrototypeNode(const TType &returnType, + const char *name, + const TSymbolUniqueId &functionId) +{ + TIntermFunctionPrototype *functionNode = new TIntermFunctionPrototype(returnType, functionId); + functionNode->getFunctionSymbolInfo()->setNameObj(GetInternalFunctionName(name)); + return functionNode; +} + +TIntermFunctionDefinition *CreateInternalFunctionDefinitionNode(const TType &returnType, + const char *name, + TIntermBlock *functionBody, + const TSymbolUniqueId &functionId) +{ + TIntermFunctionPrototype *prototypeNode = + CreateInternalFunctionPrototypeNode(returnType, name, functionId); + return new TIntermFunctionDefinition(prototypeNode, functionBody); +} + +TIntermAggregate *CreateInternalFunctionCallNode(const TType &returnType, + const char *name, + const TSymbolUniqueId &functionId, + TIntermSequence *arguments) +{ + TIntermAggregate *functionNode = TIntermAggregate::CreateFunctionCall( + returnType, functionId, GetInternalFunctionName(name), arguments); + return functionNode; +} + +TIntermTyped *CreateZeroNode(const TType &type) +{ + TType constType(type); + constType.setQualifier(EvqConst); + + if (!type.isArray() && type.getBasicType() != EbtStruct) + { + size_t size = constType.getObjectSize(); + TConstantUnion *u = new TConstantUnion[size]; + for (size_t i = 0; i < size; ++i) + { + switch (type.getBasicType()) + { + case EbtFloat: + u[i].setFConst(0.0f); + break; + case EbtInt: + u[i].setIConst(0); + break; + case EbtUInt: + u[i].setUConst(0u); + break; + case EbtBool: + u[i].setBConst(false); + break; + default: + // CreateZeroNode is called by ParseContext that keeps parsing even when an + // error occurs, so it is possible for CreateZeroNode to be called with + // non-basic types. This happens only on error condition but CreateZeroNode + // needs to return a value with the correct type to continue the typecheck. + // That's why we handle non-basic type by setting whatever value, we just need + // the type to be right. + u[i].setIConst(42); + break; + } + } + + TIntermConstantUnion *node = new TIntermConstantUnion(u, constType); + return node; + } + + if (type.getBasicType() == EbtVoid) + { + // Void array. This happens only on error condition, similarly to the case above. We don't + // have a constructor operator for void, so this needs special handling. We'll end up with a + // value without the array type, but that should not be a problem. + while (constType.isArray()) + { + constType.toArrayElementType(); + } + return CreateZeroNode(constType); + } + + TIntermSequence *arguments = new TIntermSequence(); + + if (type.isArray()) + { + TType elementType(type); + elementType.toArrayElementType(); + + size_t arraySize = type.getOutermostArraySize(); + for (size_t i = 0; i < arraySize; ++i) + { + arguments->push_back(CreateZeroNode(elementType)); + } + } + else + { + ASSERT(type.getBasicType() == EbtStruct); + + const TStructure *structure = type.getStruct(); + for (const auto &field : structure->fields()) + { + arguments->push_back(CreateZeroNode(*field->type())); + } + } + + return TIntermAggregate::CreateConstructor(constType, arguments); +} + +TIntermConstantUnion *CreateIndexNode(int index) +{ + TConstantUnion *u = new TConstantUnion[1]; + u[0].setIConst(index); + + TType type(EbtInt, EbpUndefined, EvqConst, 1); + TIntermConstantUnion *node = new TIntermConstantUnion(u, type); + return node; +} + +TIntermConstantUnion *CreateBoolNode(bool value) +{ + TConstantUnion *u = new TConstantUnion[1]; + u[0].setBConst(value); + + TType type(EbtBool, EbpUndefined, EvqConst, 1); + TIntermConstantUnion *node = new TIntermConstantUnion(u, type); + return node; +} + +TIntermSymbol *CreateTempSymbolNode(const TSymbolUniqueId &id, + const TType &type, + TQualifier qualifier) +{ + TInfoSinkBase symbolNameOut; + symbolNameOut << "s" << id.get(); + TString symbolName = symbolNameOut.c_str(); + + TIntermSymbol *node = new TIntermSymbol(id, symbolName, type); + node->setInternal(true); + + ASSERT(qualifier == EvqTemporary || qualifier == EvqConst || qualifier == EvqGlobal); + node->getTypePointer()->setQualifier(qualifier); + + // TODO(oetuaho): Might be useful to sanitize layout qualifier etc. on the type of the created + // symbol. This might need to be done in other places as well. + return node; +} + +TIntermDeclaration *CreateTempInitDeclarationNode(const TSymbolUniqueId &id, + TIntermTyped *initializer, + TQualifier qualifier) +{ + ASSERT(initializer != nullptr); + TIntermSymbol *tempSymbol = CreateTempSymbolNode(id, initializer->getType(), qualifier); + TIntermDeclaration *tempDeclaration = new TIntermDeclaration(); + TIntermBinary *tempInit = new TIntermBinary(EOpInitialize, tempSymbol, initializer); + tempDeclaration->appendDeclarator(tempInit); + return tempDeclaration; +} + +TIntermBlock *EnsureBlock(TIntermNode *node) +{ + if (node == nullptr) + return nullptr; + TIntermBlock *blockNode = node->getAsBlock(); + if (blockNode != nullptr) + return blockNode; + + blockNode = new TIntermBlock(); + blockNode->setLine(node->getLine()); + blockNode->appendStatement(node); + return blockNode; +} + +TIntermSymbol *ReferenceGlobalVariable(const TString &name, const TSymbolTable &symbolTable) +{ + TVariable *var = reinterpret_cast(symbolTable.findGlobal(name)); + ASSERT(var); + return new TIntermSymbol(var->getUniqueId(), name, var->getType()); +} + +TIntermSymbol *ReferenceBuiltInVariable(const TString &name, + const TSymbolTable &symbolTable, + int shaderVersion) +{ + const TVariable *var = + reinterpret_cast(symbolTable.findBuiltIn(name, shaderVersion, true)); + ASSERT(var); + return new TIntermSymbol(var->getUniqueId(), name, var->getType()); +} + +TIntermTyped *CreateBuiltInFunctionCallNode(const TString &name, + TIntermSequence *arguments, + const TSymbolTable &symbolTable, + int shaderVersion) +{ + const TFunction *fn = LookUpBuiltInFunction(name, arguments, symbolTable, shaderVersion); + ASSERT(fn); + TOperator op = fn->getBuiltInOp(); + if (op != EOpNull) + { + if (arguments->size() == 1) + { + return new TIntermUnary(op, arguments->at(0)->getAsTyped()); + } + return TIntermAggregate::Create(fn->getReturnType(), op, arguments); + } + return TIntermAggregate::CreateBuiltInFunctionCall(*fn, arguments); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/IntermNode_util.h b/src/3rdparty/angle/src/compiler/translator/IntermNode_util.h new file mode 100644 index 0000000000..6f3b0674f0 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/IntermNode_util.h @@ -0,0 +1,60 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// IntermNode_util.h: High-level utilities for creating AST nodes and node hierarchies. Mostly meant +// to be used in AST transforms. + +#ifndef COMPILER_TRANSLATOR_INTERMNODEUTIL_H_ +#define COMPILER_TRANSLATOR_INTERMNODEUTIL_H_ + +#include "compiler/translator/IntermNode.h" + +namespace sh +{ + +TIntermFunctionPrototype *CreateInternalFunctionPrototypeNode(const TType &returnType, + const char *name, + const TSymbolUniqueId &functionId); +TIntermFunctionDefinition *CreateInternalFunctionDefinitionNode(const TType &returnType, + const char *name, + TIntermBlock *functionBody, + const TSymbolUniqueId &functionId); +TIntermAggregate *CreateInternalFunctionCallNode(const TType &returnType, + const char *name, + const TSymbolUniqueId &functionId, + TIntermSequence *arguments); + +TIntermTyped *CreateZeroNode(const TType &type); +TIntermConstantUnion *CreateIndexNode(int index); +TIntermConstantUnion *CreateBoolNode(bool value); + +TIntermSymbol *CreateTempSymbolNode(const TSymbolUniqueId &id, + const TType &type, + TQualifier qualifier); +TIntermDeclaration *CreateTempInitDeclarationNode(const TSymbolUniqueId &id, + TIntermTyped *initializer, + TQualifier qualifier); + +// If the input node is nullptr, return nullptr. +// If the input node is a block node, return it. +// If the input node is not a block node, put it inside a block node and return that. +TIntermBlock *EnsureBlock(TIntermNode *node); + +// Should be called from inside Compiler::compileTreeImpl() where the global level is in scope. +TIntermSymbol *ReferenceGlobalVariable(const TString &name, const TSymbolTable &symbolTable); + +// Note: this can access desktop GLSL built-ins that are hidden from the parser. +TIntermSymbol *ReferenceBuiltInVariable(const TString &name, + const TSymbolTable &symbolTable, + int shaderVersion); + +TIntermTyped *CreateBuiltInFunctionCallNode(const TString &name, + TIntermSequence *arguments, + const TSymbolTable &symbolTable, + int shaderVersion); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_INTERMNODEUTIL_H_ \ No newline at end of file diff --git a/src/3rdparty/angle/src/compiler/translator/IntermTraverse.cpp b/src/3rdparty/angle/src/compiler/translator/IntermTraverse.cpp index 7b588ca5a3..6c25c6c35a 100644 --- a/src/3rdparty/angle/src/compiler/translator/IntermTraverse.cpp +++ b/src/3rdparty/angle/src/compiler/translator/IntermTraverse.cpp @@ -4,10 +4,15 @@ // found in the LICENSE file. // -#include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermTraverse.h" + #include "compiler/translator/InfoSink.h" +#include "compiler/translator/IntermNode_util.h" #include "compiler/translator/SymbolTable.h" +namespace sh +{ + void TIntermSymbol::traverse(TIntermTraverser *it) { it->traverseSymbol(this); @@ -23,6 +28,11 @@ void TIntermConstantUnion::traverse(TIntermTraverser *it) it->traverseConstantUnion(this); } +void TIntermSwizzle::traverse(TIntermTraverser *it) +{ + it->traverseSwizzle(this); +} + void TIntermBinary::traverse(TIntermTraverser *it) { it->traverseBinary(this); @@ -33,9 +43,14 @@ void TIntermUnary::traverse(TIntermTraverser *it) it->traverseUnary(this); } -void TIntermSelection::traverse(TIntermTraverser *it) +void TIntermTernary::traverse(TIntermTraverser *it) { - it->traverseSelection(this); + it->traverseTernary(this); +} + +void TIntermIfElse::traverse(TIntermTraverser *it) +{ + it->traverseIfElse(this); } void TIntermSwitch::traverse(TIntermTraverser *it) @@ -48,6 +63,31 @@ void TIntermCase::traverse(TIntermTraverser *it) it->traverseCase(this); } +void TIntermFunctionDefinition::traverse(TIntermTraverser *it) +{ + it->traverseFunctionDefinition(this); +} + +void TIntermBlock::traverse(TIntermTraverser *it) +{ + it->traverseBlock(this); +} + +void TIntermInvariantDeclaration::traverse(TIntermTraverser *it) +{ + it->traverseInvariantDeclaration(this); +} + +void TIntermDeclaration::traverse(TIntermTraverser *it) +{ + it->traverseDeclaration(this); +} + +void TIntermFunctionPrototype::traverse(TIntermTraverser *it) +{ + it->traverseFunctionPrototype(this); +} + void TIntermAggregate::traverse(TIntermTraverser *it) { it->traverseAggregate(this); @@ -63,7 +103,35 @@ void TIntermBranch::traverse(TIntermTraverser *it) it->traverseBranch(this); } -void TIntermTraverser::pushParentBlock(TIntermAggregate *node) +TIntermTraverser::TIntermTraverser(bool preVisit, + bool inVisit, + bool postVisit, + TSymbolTable *symbolTable) + : preVisit(preVisit), + inVisit(inVisit), + postVisit(postVisit), + mDepth(-1), + mMaxDepth(0), + mInGlobalScope(true), + mSymbolTable(symbolTable), + mTemporaryId(nullptr) +{ +} + +TIntermTraverser::~TIntermTraverser() +{ +} + +const TIntermBlock *TIntermTraverser::getParentBlock() const +{ + if (!mParentBlockStack.empty()) + { + return mParentBlockStack.back().node; + } + return nullptr; +} + +void TIntermTraverser::pushParentBlock(TIntermBlock *node) { mParentBlockStack.push_back(ParentBlock(node, 0)); } @@ -89,23 +157,32 @@ void TIntermTraverser::insertStatementsInParentBlock(const TIntermSequence &inse const TIntermSequence &insertionsAfter) { ASSERT(!mParentBlockStack.empty()); - NodeInsertMultipleEntry insert(mParentBlockStack.back().node, mParentBlockStack.back().pos, - insertionsBefore, insertionsAfter); + ParentBlock &parentBlock = mParentBlockStack.back(); + if (mPath.back() == parentBlock.node) + { + ASSERT(mParentBlockStack.size() >= 2u); + // The current node is a block node, so the parent block is not the topmost one in the block + // stack, but the one below that. + parentBlock = mParentBlockStack.at(mParentBlockStack.size() - 2u); + } + NodeInsertMultipleEntry insert(parentBlock.node, parentBlock.pos, insertionsBefore, + insertionsAfter); mInsertions.push_back(insert); } +void TIntermTraverser::insertStatementInParentBlock(TIntermNode *statement) +{ + TIntermSequence insertions; + insertions.push_back(statement); + insertStatementsInParentBlock(insertions); +} + TIntermSymbol *TIntermTraverser::createTempSymbol(const TType &type, TQualifier qualifier) { - // Each traversal uses at most one temporary variable, so the index stays the same within a single traversal. - TInfoSinkBase symbolNameOut; - ASSERT(mTemporaryIndex != nullptr); - symbolNameOut << "s" << (*mTemporaryIndex); - TString symbolName = symbolNameOut.c_str(); - - TIntermSymbol *node = new TIntermSymbol(0, symbolName, type); - node->setInternal(true); - node->getTypePointer()->setQualifier(qualifier); - return node; + ASSERT(mTemporaryId != nullptr); + // nextTemporaryId() needs to be called when the code wants to start using another temporary + // symbol. + return CreateTempSymbolNode(*mTemporaryId, type, qualifier); } TIntermSymbol *TIntermTraverser::createTempSymbol(const TType &type) @@ -113,27 +190,22 @@ TIntermSymbol *TIntermTraverser::createTempSymbol(const TType &type) return createTempSymbol(type, EvqTemporary); } -TIntermAggregate *TIntermTraverser::createTempDeclaration(const TType &type) +TIntermDeclaration *TIntermTraverser::createTempDeclaration(const TType &type) { - TIntermAggregate *tempDeclaration = new TIntermAggregate(EOpDeclaration); - tempDeclaration->getSequence()->push_back(createTempSymbol(type)); + ASSERT(mTemporaryId != nullptr); + TIntermDeclaration *tempDeclaration = new TIntermDeclaration(); + tempDeclaration->appendDeclarator(CreateTempSymbolNode(*mTemporaryId, type, EvqTemporary)); return tempDeclaration; } -TIntermAggregate *TIntermTraverser::createTempInitDeclaration(TIntermTyped *initializer, TQualifier qualifier) +TIntermDeclaration *TIntermTraverser::createTempInitDeclaration(TIntermTyped *initializer, + TQualifier qualifier) { - ASSERT(initializer != nullptr); - TIntermSymbol *tempSymbol = createTempSymbol(initializer->getType(), qualifier); - TIntermAggregate *tempDeclaration = new TIntermAggregate(EOpDeclaration); - TIntermBinary *tempInit = new TIntermBinary(EOpInitialize); - tempInit->setLeft(tempSymbol); - tempInit->setRight(initializer); - tempInit->setType(tempSymbol->getType()); - tempDeclaration->getSequence()->push_back(tempInit); - return tempDeclaration; + ASSERT(mTemporaryId != nullptr); + return CreateTempInitDeclarationNode(*mTemporaryId, initializer, qualifier); } -TIntermAggregate *TIntermTraverser::createTempInitDeclaration(TIntermTyped *initializer) +TIntermDeclaration *TIntermTraverser::createTempInitDeclaration(TIntermTyped *initializer) { return createTempInitDeclaration(initializer, EvqTemporary); } @@ -142,39 +214,38 @@ TIntermBinary *TIntermTraverser::createTempAssignment(TIntermTyped *rightNode) { ASSERT(rightNode != nullptr); TIntermSymbol *tempSymbol = createTempSymbol(rightNode->getType()); - TIntermBinary *assignment = new TIntermBinary(EOpAssign); - assignment->setLeft(tempSymbol); - assignment->setRight(rightNode); - assignment->setType(tempSymbol->getType()); + TIntermBinary *assignment = new TIntermBinary(EOpAssign, tempSymbol, rightNode); return assignment; } -void TIntermTraverser::useTemporaryIndex(unsigned int *temporaryIndex) +void TIntermTraverser::nextTemporaryId() { - mTemporaryIndex = temporaryIndex; + ASSERT(mSymbolTable); + if (!mTemporaryId) + { + mTemporaryId = new TSymbolUniqueId(mSymbolTable); + return; + } + *mTemporaryId = TSymbolUniqueId(mSymbolTable); } -void TIntermTraverser::nextTemporaryIndex() +void TLValueTrackingTraverser::addToFunctionMap(const TSymbolUniqueId &id, + TIntermSequence *paramSequence) { - ASSERT(mTemporaryIndex != nullptr); - ++(*mTemporaryIndex); -} - -void TLValueTrackingTraverser::addToFunctionMap(const TName &name, TIntermSequence *paramSequence) -{ - mFunctionMap[name] = paramSequence; + mFunctionMap[id.get()] = paramSequence; } bool TLValueTrackingTraverser::isInFunctionMap(const TIntermAggregate *callNode) const { - ASSERT(callNode->getOp() == EOpFunctionCall); - return (mFunctionMap.find(callNode->getNameObj()) != mFunctionMap.end()); + ASSERT(callNode->getOp() == EOpCallFunctionInAST); + return (mFunctionMap.find(callNode->getFunctionSymbolInfo()->getId().get()) != + mFunctionMap.end()); } TIntermSequence *TLValueTrackingTraverser::getFunctionParameters(const TIntermAggregate *callNode) { ASSERT(isInFunctionMap(callNode)); - return mFunctionMap[callNode->getNameObj()]; + return mFunctionMap[callNode->getFunctionSymbolInfo()->getId().get()]; } void TLValueTrackingTraverser::setInFunctionCallOutParameter(bool inOutParameter) @@ -203,19 +274,41 @@ bool TLValueTrackingTraverser::isInFunctionCallOutParameter() const // void TIntermTraverser::traverseSymbol(TIntermSymbol *node) { + ScopedNodeInTraversalPath addToPath(this, node); visitSymbol(node); } void TIntermTraverser::traverseConstantUnion(TIntermConstantUnion *node) { + ScopedNodeInTraversalPath addToPath(this, node); visitConstantUnion(node); } +void TIntermTraverser::traverseSwizzle(TIntermSwizzle *node) +{ + ScopedNodeInTraversalPath addToPath(this, node); + + bool visit = true; + + if (preVisit) + visit = visitSwizzle(PreVisit, node); + + if (visit) + { + node->getOperand()->traverse(this); + } + + if (visit && postVisit) + visitSwizzle(PostVisit, node); +} + // // Traverse a binary node. // void TIntermTraverser::traverseBinary(TIntermBinary *node) { + ScopedNodeInTraversalPath addToPath(this, node); + bool visit = true; // @@ -229,8 +322,6 @@ void TIntermTraverser::traverseBinary(TIntermBinary *node) // if (visit) { - incrementDepth(node); - if (node->getLeft()) node->getLeft()->traverse(this); @@ -239,8 +330,6 @@ void TIntermTraverser::traverseBinary(TIntermBinary *node) if (visit && node->getRight()) node->getRight()->traverse(this); - - decrementDepth(); } // @@ -253,6 +342,8 @@ void TIntermTraverser::traverseBinary(TIntermBinary *node) void TLValueTrackingTraverser::traverseBinary(TIntermBinary *node) { + ScopedNodeInTraversalPath addToPath(this, node); + bool visit = true; // @@ -266,8 +357,6 @@ void TLValueTrackingTraverser::traverseBinary(TIntermBinary *node) // if (visit) { - incrementDepth(node); - // Some binary operations like indexing can be inside an expression which must be an // l-value. bool parentOperatorRequiresLValue = operatorRequiresLValue(); @@ -302,8 +391,6 @@ void TLValueTrackingTraverser::traverseBinary(TIntermBinary *node) setOperatorRequiresLValue(parentOperatorRequiresLValue); setInFunctionCallOutParameter(parentInFunctionCallOutParameter); - - decrementDepth(); } // @@ -319,6 +406,8 @@ void TLValueTrackingTraverser::traverseBinary(TIntermBinary *node) // void TIntermTraverser::traverseUnary(TIntermUnary *node) { + ScopedNodeInTraversalPath addToPath(this, node); + bool visit = true; if (preVisit) @@ -326,11 +415,7 @@ void TIntermTraverser::traverseUnary(TIntermUnary *node) if (visit) { - incrementDepth(node); - node->getOperand()->traverse(this); - - decrementDepth(); } if (visit && postVisit) @@ -339,6 +424,8 @@ void TIntermTraverser::traverseUnary(TIntermUnary *node) void TLValueTrackingTraverser::traverseUnary(TIntermUnary *node) { + ScopedNodeInTraversalPath addToPath(this, node); + bool visit = true; if (preVisit) @@ -346,8 +433,6 @@ void TLValueTrackingTraverser::traverseUnary(TIntermUnary *node) if (visit) { - incrementDepth(node); - ASSERT(!operatorRequiresLValue()); switch (node->getOp()) { @@ -364,19 +449,155 @@ void TLValueTrackingTraverser::traverseUnary(TIntermUnary *node) node->getOperand()->traverse(this); setOperatorRequiresLValue(false); - - decrementDepth(); } if (visit && postVisit) visitUnary(PostVisit, node); } -// +// Traverse a function definition node. +void TIntermTraverser::traverseFunctionDefinition(TIntermFunctionDefinition *node) +{ + ScopedNodeInTraversalPath addToPath(this, node); + + bool visit = true; + + if (preVisit) + visit = visitFunctionDefinition(PreVisit, node); + + if (visit) + { + mInGlobalScope = false; + + node->getFunctionPrototype()->traverse(this); + if (inVisit) + visit = visitFunctionDefinition(InVisit, node); + node->getBody()->traverse(this); + + mInGlobalScope = true; + } + + if (visit && postVisit) + visitFunctionDefinition(PostVisit, node); +} + +// Traverse a block node. +void TIntermTraverser::traverseBlock(TIntermBlock *node) +{ + ScopedNodeInTraversalPath addToPath(this, node); + pushParentBlock(node); + + bool visit = true; + + TIntermSequence *sequence = node->getSequence(); + + if (preVisit) + visit = visitBlock(PreVisit, node); + + if (visit) + { + for (auto *child : *sequence) + { + child->traverse(this); + if (visit && inVisit) + { + if (child != sequence->back()) + visit = visitBlock(InVisit, node); + } + + incrementParentBlockPos(); + } + } + + if (visit && postVisit) + visitBlock(PostVisit, node); + + popParentBlock(); +} + +void TIntermTraverser::traverseInvariantDeclaration(TIntermInvariantDeclaration *node) +{ + ScopedNodeInTraversalPath addToPath(this, node); + + bool visit = true; + + if (preVisit) + { + visit = visitInvariantDeclaration(PreVisit, node); + } + + if (visit) + { + node->getSymbol()->traverse(this); + if (postVisit) + { + visitInvariantDeclaration(PostVisit, node); + } + } +} + +// Traverse a declaration node. +void TIntermTraverser::traverseDeclaration(TIntermDeclaration *node) +{ + ScopedNodeInTraversalPath addToPath(this, node); + + bool visit = true; + + TIntermSequence *sequence = node->getSequence(); + + if (preVisit) + visit = visitDeclaration(PreVisit, node); + + if (visit) + { + for (auto *child : *sequence) + { + child->traverse(this); + if (visit && inVisit) + { + if (child != sequence->back()) + visit = visitDeclaration(InVisit, node); + } + } + } + + if (visit && postVisit) + visitDeclaration(PostVisit, node); +} + +void TIntermTraverser::traverseFunctionPrototype(TIntermFunctionPrototype *node) +{ + ScopedNodeInTraversalPath addToPath(this, node); + + bool visit = true; + + TIntermSequence *sequence = node->getSequence(); + + if (preVisit) + visit = visitFunctionPrototype(PreVisit, node); + + if (visit) + { + for (auto *child : *sequence) + { + child->traverse(this); + if (visit && inVisit) + { + if (child != sequence->back()) + visit = visitFunctionPrototype(InVisit, node); + } + } + } + + if (visit && postVisit) + visitFunctionPrototype(PostVisit, node); +} + // Traverse an aggregate node. Same comments in binary node apply here. -// void TIntermTraverser::traverseAggregate(TIntermAggregate *node) { + ScopedNodeInTraversalPath addToPath(this, node); + bool visit = true; TIntermSequence *sequence = node->getSequence(); @@ -386,11 +607,6 @@ void TIntermTraverser::traverseAggregate(TIntermAggregate *node) if (visit) { - incrementDepth(node); - - if (node->getOp() == EOpSequence) - pushParentBlock(node); - for (auto *child : *sequence) { child->traverse(this); @@ -399,118 +615,196 @@ void TIntermTraverser::traverseAggregate(TIntermAggregate *node) if (child != sequence->back()) visit = visitAggregate(InVisit, node); } - - if (node->getOp() == EOpSequence) - incrementParentBlockPos(); } - - if (node->getOp() == EOpSequence) - popParentBlock(); - - decrementDepth(); } if (visit && postVisit) visitAggregate(PostVisit, node); } +bool TIntermTraverser::CompareInsertion(const NodeInsertMultipleEntry &a, + const NodeInsertMultipleEntry &b) +{ + if (a.parent != b.parent) + { + return a.parent > b.parent; + } + return a.position > b.position; +} + +void TIntermTraverser::updateTree() +{ + // Sort the insertions so that insertion position is decreasing. This way multiple insertions to + // the same parent node are handled correctly. + std::sort(mInsertions.begin(), mInsertions.end(), CompareInsertion); + for (size_t ii = 0; ii < mInsertions.size(); ++ii) + { + // We can't know here what the intended ordering of two insertions to the same position is, + // so it is not supported. + ASSERT(ii == 0 || mInsertions[ii].position != mInsertions[ii - 1].position || + mInsertions[ii].parent != mInsertions[ii - 1].parent); + const NodeInsertMultipleEntry &insertion = mInsertions[ii]; + ASSERT(insertion.parent); + if (!insertion.insertionsAfter.empty()) + { + bool inserted = insertion.parent->insertChildNodes(insertion.position + 1, + insertion.insertionsAfter); + ASSERT(inserted); + } + if (!insertion.insertionsBefore.empty()) + { + bool inserted = + insertion.parent->insertChildNodes(insertion.position, insertion.insertionsBefore); + ASSERT(inserted); + } + } + for (size_t ii = 0; ii < mReplacements.size(); ++ii) + { + const NodeUpdateEntry &replacement = mReplacements[ii]; + ASSERT(replacement.parent); + bool replaced = + replacement.parent->replaceChildNode(replacement.original, replacement.replacement); + ASSERT(replaced); + + if (!replacement.originalBecomesChildOfReplacement) + { + // In AST traversing, a parent is visited before its children. + // After we replace a node, if its immediate child is to + // be replaced, we need to make sure we don't update the replaced + // node; instead, we update the replacement node. + for (size_t jj = ii + 1; jj < mReplacements.size(); ++jj) + { + NodeUpdateEntry &replacement2 = mReplacements[jj]; + if (replacement2.parent == replacement.original) + replacement2.parent = replacement.replacement; + } + } + } + for (size_t ii = 0; ii < mMultiReplacements.size(); ++ii) + { + const NodeReplaceWithMultipleEntry &replacement = mMultiReplacements[ii]; + ASSERT(replacement.parent); + bool replaced = replacement.parent->replaceChildNodeWithMultiple(replacement.original, + replacement.replacements); + ASSERT(replaced); + } + + clearReplacementQueue(); +} + +void TIntermTraverser::clearReplacementQueue() +{ + mReplacements.clear(); + mMultiReplacements.clear(); + mInsertions.clear(); +} + +void TIntermTraverser::queueReplacement(TIntermNode *replacement, OriginalNode originalStatus) +{ + queueReplacementWithParent(getParentNode(), mPath.back(), replacement, originalStatus); +} + +void TIntermTraverser::queueReplacementWithParent(TIntermNode *parent, + TIntermNode *original, + TIntermNode *replacement, + OriginalNode originalStatus) +{ + bool originalBecomesChild = (originalStatus == OriginalNode::BECOMES_CHILD); + mReplacements.push_back(NodeUpdateEntry(parent, original, replacement, originalBecomesChild)); +} + +TLValueTrackingTraverser::TLValueTrackingTraverser(bool preVisit, + bool inVisit, + bool postVisit, + TSymbolTable *symbolTable, + int shaderVersion) + : TIntermTraverser(preVisit, inVisit, postVisit, symbolTable), + mOperatorRequiresLValue(false), + mInFunctionCallOutParameter(false), + mShaderVersion(shaderVersion) +{ + ASSERT(symbolTable); +} + +void TLValueTrackingTraverser::traverseFunctionPrototype(TIntermFunctionPrototype *node) +{ + TIntermSequence *sequence = node->getSequence(); + addToFunctionMap(node->getFunctionSymbolInfo()->getId(), sequence); + + TIntermTraverser::traverseFunctionPrototype(node); +} + void TLValueTrackingTraverser::traverseAggregate(TIntermAggregate *node) { + ScopedNodeInTraversalPath addToPath(this, node); + bool visit = true; TIntermSequence *sequence = node->getSequence(); - switch (node->getOp()) - { - case EOpFunction: - { - TIntermAggregate *params = sequence->front()->getAsAggregate(); - ASSERT(params != nullptr); - ASSERT(params->getOp() == EOpParameters); - addToFunctionMap(node->getNameObj(), params->getSequence()); - break; - } - case EOpPrototype: - addToFunctionMap(node->getNameObj(), sequence); - break; - default: - break; - } if (preVisit) visit = visitAggregate(PreVisit, node); if (visit) { - bool inFunctionMap = false; - if (node->getOp() == EOpFunctionCall) + if (node->getOp() == EOpCallFunctionInAST) { - inFunctionMap = isInFunctionMap(node); - if (!inFunctionMap) + if (isInFunctionMap(node)) { - // The function is not user-defined - it is likely built-in texture function. - // Assume that those do not have out parameters. - setInFunctionCallOutParameter(false); - } - } - - incrementDepth(node); - - if (inFunctionMap) - { - TIntermSequence *params = getFunctionParameters(node); - TIntermSequence::iterator paramIter = params->begin(); - for (auto *child : *sequence) - { - ASSERT(paramIter != params->end()); - TQualifier qualifier = (*paramIter)->getAsTyped()->getQualifier(); - setInFunctionCallOutParameter(qualifier == EvqOut || qualifier == EvqInOut); - - child->traverse(this); - if (visit && inVisit) + TIntermSequence *params = getFunctionParameters(node); + TIntermSequence::iterator paramIter = params->begin(); + for (auto *child : *sequence) { - if (child != sequence->back()) - visit = visitAggregate(InVisit, node); - } + ASSERT(paramIter != params->end()); + TQualifier qualifier = (*paramIter)->getAsTyped()->getQualifier(); + setInFunctionCallOutParameter(qualifier == EvqOut || qualifier == EvqInOut); - ++paramIter; + child->traverse(this); + if (visit && inVisit) + { + if (child != sequence->back()) + visit = visitAggregate(InVisit, node); + } + + ++paramIter; + } + } + else + { + // The node might not be in the function map in case we're in the middle of + // transforming the AST, and have inserted function call nodes without inserting the + // function definitions yet. + setInFunctionCallOutParameter(false); + for (auto *child : *sequence) + { + child->traverse(this); + if (visit && inVisit) + { + if (child != sequence->back()) + visit = visitAggregate(InVisit, node); + } + } } setInFunctionCallOutParameter(false); } else { - if (node->getOp() == EOpSequence) - pushParentBlock(node); - // Find the built-in function corresponding to this op so that we can determine the // in/out qualifiers of its parameters. TFunction *builtInFunc = nullptr; - TString opString = GetOperatorString(node->getOp()); - if (!node->isConstructor() && !opString.empty()) + if (!node->isFunctionCall() && !node->isConstructor()) { - // The return type doesn't affect the mangled name of the function, which is used - // to look it up from the symbol table. - TType dummyReturnType; - TFunction call(&opString, &dummyReturnType, node->getOp()); - for (auto *child : *sequence) - { - TType *paramType = child->getAsTyped()->getTypePointer(); - TConstParameter p(paramType); - call.addParameter(p); - } - - TSymbol *sym = mSymbolTable.findBuiltIn(call.getMangledName(), mShaderVersion); - if (sym != nullptr && sym->isFunction()) - { - builtInFunc = static_cast(sym); - ASSERT(builtInFunc->getParamCount() == sequence->size()); - } + builtInFunc = static_cast( + mSymbolTable->findBuiltIn(node->getSymbolTableMangledName(), mShaderVersion)); } size_t paramIndex = 0; for (auto *child : *sequence) { + // This assumes that raw functions called with + // EOpCallInternalRawFunction don't have out parameters. TQualifier qualifier = EvqIn; if (builtInFunc != nullptr) qualifier = builtInFunc->getParam(paramIndex).type->getQualifier(); @@ -523,19 +817,11 @@ void TLValueTrackingTraverser::traverseAggregate(TIntermAggregate *node) visit = visitAggregate(InVisit, node); } - if (node->getOp() == EOpSequence) - incrementParentBlockPos(); - ++paramIndex; } setInFunctionCallOutParameter(false); - - if (node->getOp() == EOpSequence) - popParentBlock(); } - - decrementDepth(); } if (visit && postVisit) @@ -543,28 +829,51 @@ void TLValueTrackingTraverser::traverseAggregate(TIntermAggregate *node) } // -// Traverse a selection node. Same comments in binary node apply here. +// Traverse a ternary node. Same comments in binary node apply here. // -void TIntermTraverser::traverseSelection(TIntermSelection *node) +void TIntermTraverser::traverseTernary(TIntermTernary *node) { + ScopedNodeInTraversalPath addToPath(this, node); + bool visit = true; if (preVisit) - visit = visitSelection(PreVisit, node); + visit = visitTernary(PreVisit, node); + + if (visit) + { + node->getCondition()->traverse(this); + if (node->getTrueExpression()) + node->getTrueExpression()->traverse(this); + if (node->getFalseExpression()) + node->getFalseExpression()->traverse(this); + } + + if (visit && postVisit) + visitTernary(PostVisit, node); +} + +// Traverse an if-else node. Same comments in binary node apply here. +void TIntermTraverser::traverseIfElse(TIntermIfElse *node) +{ + ScopedNodeInTraversalPath addToPath(this, node); + + bool visit = true; + + if (preVisit) + visit = visitIfElse(PreVisit, node); if (visit) { - incrementDepth(node); node->getCondition()->traverse(this); if (node->getTrueBlock()) node->getTrueBlock()->traverse(this); if (node->getFalseBlock()) node->getFalseBlock()->traverse(this); - decrementDepth(); } if (visit && postVisit) - visitSelection(PostVisit, node); + visitIfElse(PostVisit, node); } // @@ -572,6 +881,8 @@ void TIntermTraverser::traverseSelection(TIntermSelection *node) // void TIntermTraverser::traverseSwitch(TIntermSwitch *node) { + ScopedNodeInTraversalPath addToPath(this, node); + bool visit = true; if (preVisit) @@ -579,13 +890,11 @@ void TIntermTraverser::traverseSwitch(TIntermSwitch *node) if (visit) { - incrementDepth(node); node->getInit()->traverse(this); if (inVisit) visit = visitSwitch(InVisit, node); if (visit && node->getStatementList()) node->getStatementList()->traverse(this); - decrementDepth(); } if (visit && postVisit) @@ -597,13 +906,17 @@ void TIntermTraverser::traverseSwitch(TIntermSwitch *node) // void TIntermTraverser::traverseCase(TIntermCase *node) { + ScopedNodeInTraversalPath addToPath(this, node); + bool visit = true; if (preVisit) visit = visitCase(PreVisit, node); if (visit && node->getCondition()) + { node->getCondition()->traverse(this); + } if (visit && postVisit) visitCase(PostVisit, node); @@ -614,6 +927,8 @@ void TIntermTraverser::traverseCase(TIntermCase *node) // void TIntermTraverser::traverseLoop(TIntermLoop *node) { + ScopedNodeInTraversalPath addToPath(this, node); + bool visit = true; if (preVisit) @@ -621,8 +936,6 @@ void TIntermTraverser::traverseLoop(TIntermLoop *node) if (visit) { - incrementDepth(node); - if (node->getInit()) node->getInit()->traverse(this); @@ -634,8 +947,6 @@ void TIntermTraverser::traverseLoop(TIntermLoop *node) if (node->getExpression()) node->getExpression()->traverse(this); - - decrementDepth(); } if (visit && postVisit) @@ -647,6 +958,8 @@ void TIntermTraverser::traverseLoop(TIntermLoop *node) // void TIntermTraverser::traverseBranch(TIntermBranch *node) { + ScopedNodeInTraversalPath addToPath(this, node); + bool visit = true; if (preVisit) @@ -654,9 +967,7 @@ void TIntermTraverser::traverseBranch(TIntermBranch *node) if (visit && node->getExpression()) { - incrementDepth(node); node->getExpression()->traverse(this); - decrementDepth(); } if (visit && postVisit) @@ -665,5 +976,8 @@ void TIntermTraverser::traverseBranch(TIntermBranch *node) void TIntermTraverser::traverseRaw(TIntermRaw *node) { + ScopedNodeInTraversalPath addToPath(this, node); visitRaw(node); } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/IntermTraverse.h b/src/3rdparty/angle/src/compiler/translator/IntermTraverse.h new file mode 100644 index 0000000000..f0300b586b --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/IntermTraverse.h @@ -0,0 +1,355 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// IntermTraverse.h : base classes for AST traversers that walk the AST and +// also have the ability to transform it by replacing nodes. + +#ifndef COMPILER_TRANSLATOR_INTERMTRAVERSE_H_ +#define COMPILER_TRANSLATOR_INTERMTRAVERSE_H_ + +#include "compiler/translator/IntermNode.h" + +namespace sh +{ + +class TSymbolTable; +class TSymbolUniqueId; + +enum Visit +{ + PreVisit, + InVisit, + PostVisit +}; + +// For traversing the tree. User should derive from this class overriding the visit functions, +// and then pass an object of the subclass to a traverse method of a node. +// +// The traverse*() functions may also be overridden to do other bookkeeping on the tree to provide +// contextual information to the visit functions, such as whether the node is the target of an +// assignment. This is complex to maintain and so should only be done in special cases. +// +// When using this, just fill in the methods for nodes you want visited. +// Return false from a pre-visit to skip visiting that node's subtree. +class TIntermTraverser : angle::NonCopyable +{ + public: + POOL_ALLOCATOR_NEW_DELETE(); + TIntermTraverser(bool preVisit, + bool inVisit, + bool postVisit, + TSymbolTable *symbolTable = nullptr); + virtual ~TIntermTraverser(); + + virtual void visitSymbol(TIntermSymbol *node) {} + virtual void visitRaw(TIntermRaw *node) {} + virtual void visitConstantUnion(TIntermConstantUnion *node) {} + virtual bool visitSwizzle(Visit visit, TIntermSwizzle *node) { return true; } + virtual bool visitBinary(Visit visit, TIntermBinary *node) { return true; } + virtual bool visitUnary(Visit visit, TIntermUnary *node) { return true; } + virtual bool visitTernary(Visit visit, TIntermTernary *node) { return true; } + virtual bool visitIfElse(Visit visit, TIntermIfElse *node) { return true; } + virtual bool visitSwitch(Visit visit, TIntermSwitch *node) { return true; } + virtual bool visitCase(Visit visit, TIntermCase *node) { return true; } + virtual bool visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *node) + { + return true; + } + virtual bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) + { + return true; + } + virtual bool visitAggregate(Visit visit, TIntermAggregate *node) { return true; } + virtual bool visitBlock(Visit visit, TIntermBlock *node) { return true; } + virtual bool visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *node) + { + return true; + } + virtual bool visitDeclaration(Visit visit, TIntermDeclaration *node) { return true; } + virtual bool visitLoop(Visit visit, TIntermLoop *node) { return true; } + virtual bool visitBranch(Visit visit, TIntermBranch *node) { return true; } + + // The traverse functions contain logic for iterating over the children of the node + // and calling the visit functions in the appropriate places. They also track some + // context that may be used by the visit functions. + virtual void traverseSymbol(TIntermSymbol *node); + virtual void traverseRaw(TIntermRaw *node); + virtual void traverseConstantUnion(TIntermConstantUnion *node); + virtual void traverseSwizzle(TIntermSwizzle *node); + virtual void traverseBinary(TIntermBinary *node); + virtual void traverseUnary(TIntermUnary *node); + virtual void traverseTernary(TIntermTernary *node); + virtual void traverseIfElse(TIntermIfElse *node); + virtual void traverseSwitch(TIntermSwitch *node); + virtual void traverseCase(TIntermCase *node); + virtual void traverseFunctionPrototype(TIntermFunctionPrototype *node); + virtual void traverseFunctionDefinition(TIntermFunctionDefinition *node); + virtual void traverseAggregate(TIntermAggregate *node); + virtual void traverseBlock(TIntermBlock *node); + virtual void traverseInvariantDeclaration(TIntermInvariantDeclaration *node); + virtual void traverseDeclaration(TIntermDeclaration *node); + virtual void traverseLoop(TIntermLoop *node); + virtual void traverseBranch(TIntermBranch *node); + + int getMaxDepth() const { return mMaxDepth; } + + // If traversers need to replace nodes, they can add the replacements in + // mReplacements/mMultiReplacements during traversal and the user of the traverser should call + // this function after traversal to perform them. + void updateTree(); + + protected: + // Should only be called from traverse*() functions + void incrementDepth(TIntermNode *current) + { + mDepth++; + mMaxDepth = std::max(mMaxDepth, mDepth); + mPath.push_back(current); + } + + // Should only be called from traverse*() functions + void decrementDepth() + { + mDepth--; + mPath.pop_back(); + } + + // RAII helper for incrementDepth/decrementDepth + class ScopedNodeInTraversalPath + { + public: + ScopedNodeInTraversalPath(TIntermTraverser *traverser, TIntermNode *current) + : mTraverser(traverser) + { + mTraverser->incrementDepth(current); + } + ~ScopedNodeInTraversalPath() { mTraverser->decrementDepth(); } + + private: + TIntermTraverser *mTraverser; + }; + + TIntermNode *getParentNode() { return mPath.size() <= 1 ? nullptr : mPath[mPath.size() - 2u]; } + + // Return the nth ancestor of the node being traversed. getAncestorNode(0) == getParentNode() + TIntermNode *getAncestorNode(unsigned int n) + { + if (mPath.size() > n + 1u) + { + return mPath[mPath.size() - n - 2u]; + } + return nullptr; + } + + const TIntermBlock *getParentBlock() const; + + void pushParentBlock(TIntermBlock *node); + void incrementParentBlockPos(); + void popParentBlock(); + + // To replace a single node with multiple nodes in the parent aggregate. May be used with blocks + // but also with other nodes like declarations. + struct NodeReplaceWithMultipleEntry + { + NodeReplaceWithMultipleEntry(TIntermAggregateBase *_parent, + TIntermNode *_original, + TIntermSequence _replacements) + : parent(_parent), original(_original), replacements(_replacements) + { + } + + TIntermAggregateBase *parent; + TIntermNode *original; + TIntermSequence replacements; + }; + + // Helper to insert statements in the parent block of the node currently being traversed. + // The statements will be inserted before the node being traversed once updateTree is called. + // Should only be called during PreVisit or PostVisit if called from block nodes. + // Note that two insertions to the same position in the same block are not supported. + void insertStatementsInParentBlock(const TIntermSequence &insertions); + + // Same as above, but supports simultaneous insertion of statements before and after the node + // currently being traversed. + void insertStatementsInParentBlock(const TIntermSequence &insertionsBefore, + const TIntermSequence &insertionsAfter); + + // Helper to insert a single statement. + void insertStatementInParentBlock(TIntermNode *statement); + + // Helper to create a temporary symbol node with the given qualifier. + TIntermSymbol *createTempSymbol(const TType &type, TQualifier qualifier); + // Helper to create a temporary symbol node. + TIntermSymbol *createTempSymbol(const TType &type); + // Create a node that declares but doesn't initialize a temporary symbol. + TIntermDeclaration *createTempDeclaration(const TType &type); + // Create a node that initializes the current temporary symbol with initializer. The symbol will + // have the given qualifier. + TIntermDeclaration *createTempInitDeclaration(TIntermTyped *initializer, TQualifier qualifier); + // Create a node that initializes the current temporary symbol with initializer. + TIntermDeclaration *createTempInitDeclaration(TIntermTyped *initializer); + // Create a node that assigns rightNode to the current temporary symbol. + TIntermBinary *createTempAssignment(TIntermTyped *rightNode); + // Increment temporary symbol index. + void nextTemporaryId(); + + enum class OriginalNode + { + BECOMES_CHILD, + IS_DROPPED + }; + + void clearReplacementQueue(); + + // Replace the node currently being visited with replacement. + void queueReplacement(TIntermNode *replacement, OriginalNode originalStatus); + // Explicitly specify a node to replace with replacement. + void queueReplacementWithParent(TIntermNode *parent, + TIntermNode *original, + TIntermNode *replacement, + OriginalNode originalStatus); + + const bool preVisit; + const bool inVisit; + const bool postVisit; + + int mDepth; + int mMaxDepth; + + bool mInGlobalScope; + + // During traversing, save all the changes that need to happen into + // mReplacements/mMultiReplacements, then do them by calling updateTree(). + // Multi replacements are processed after single replacements. + std::vector mMultiReplacements; + + TSymbolTable *mSymbolTable; + + private: + // To insert multiple nodes into the parent block. + struct NodeInsertMultipleEntry + { + NodeInsertMultipleEntry(TIntermBlock *_parent, + TIntermSequence::size_type _position, + TIntermSequence _insertionsBefore, + TIntermSequence _insertionsAfter) + : parent(_parent), + position(_position), + insertionsBefore(_insertionsBefore), + insertionsAfter(_insertionsAfter) + { + } + + TIntermBlock *parent; + TIntermSequence::size_type position; + TIntermSequence insertionsBefore; + TIntermSequence insertionsAfter; + }; + + static bool CompareInsertion(const NodeInsertMultipleEntry &a, + const NodeInsertMultipleEntry &b); + + // To replace a single node with another on the parent node + struct NodeUpdateEntry + { + NodeUpdateEntry(TIntermNode *_parent, + TIntermNode *_original, + TIntermNode *_replacement, + bool _originalBecomesChildOfReplacement) + : parent(_parent), + original(_original), + replacement(_replacement), + originalBecomesChildOfReplacement(_originalBecomesChildOfReplacement) + { + } + + TIntermNode *parent; + TIntermNode *original; + TIntermNode *replacement; + bool originalBecomesChildOfReplacement; + }; + + struct ParentBlock + { + ParentBlock(TIntermBlock *nodeIn, TIntermSequence::size_type posIn) + : node(nodeIn), pos(posIn) + { + } + + TIntermBlock *node; + TIntermSequence::size_type pos; + }; + + std::vector mInsertions; + std::vector mReplacements; + + // All the nodes from root to the current node during traversing. + TVector mPath; + + // All the code blocks from the root to the current node's parent during traversal. + std::vector mParentBlockStack; + + TSymbolUniqueId *mTemporaryId; +}; + +// Traverser parent class that tracks where a node is a destination of a write operation and so is +// required to be an l-value. +class TLValueTrackingTraverser : public TIntermTraverser +{ + public: + TLValueTrackingTraverser(bool preVisit, + bool inVisit, + bool postVisit, + TSymbolTable *symbolTable, + int shaderVersion); + virtual ~TLValueTrackingTraverser() {} + + void traverseBinary(TIntermBinary *node) final; + void traverseUnary(TIntermUnary *node) final; + void traverseFunctionPrototype(TIntermFunctionPrototype *node) final; + void traverseAggregate(TIntermAggregate *node) final; + + protected: + bool isLValueRequiredHere() const + { + return mOperatorRequiresLValue || mInFunctionCallOutParameter; + } + + private: + // Track whether an l-value is required in the node that is currently being traversed by the + // surrounding operator. + // Use isLValueRequiredHere to check all conditions which require an l-value. + void setOperatorRequiresLValue(bool lValueRequired) + { + mOperatorRequiresLValue = lValueRequired; + } + bool operatorRequiresLValue() const { return mOperatorRequiresLValue; } + + // Add a function encountered during traversal to the function map. + void addToFunctionMap(const TSymbolUniqueId &id, TIntermSequence *paramSequence); + + // Return true if the prototype or definition of the function being called has been encountered + // during traversal. + bool isInFunctionMap(const TIntermAggregate *callNode) const; + + // Return the parameters sequence from the function definition or prototype. + TIntermSequence *getFunctionParameters(const TIntermAggregate *callNode); + + // Track whether an l-value is required inside a function call. + void setInFunctionCallOutParameter(bool inOutParameter); + bool isInFunctionCallOutParameter() const; + + bool mOperatorRequiresLValue; + bool mInFunctionCallOutParameter; + + // Map from function symbol id values to their parameter sequences + TMap mFunctionMap; + + const int mShaderVersion; +}; + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_INTERMTRAVERSE_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/Intermediate.cpp b/src/3rdparty/angle/src/compiler/translator/Intermediate.cpp deleted file mode 100644 index 0adb7212b7..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/Intermediate.cpp +++ /dev/null @@ -1,508 +0,0 @@ -// -// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// -// Build the intermediate representation. -// - -#include -#include -#include - -#include "compiler/translator/Intermediate.h" -#include "compiler/translator/SymbolTable.h" - -//////////////////////////////////////////////////////////////////////////// -// -// First set of functions are to help build the intermediate representation. -// These functions are not member functions of the nodes. -// They are called from parser productions. -// -///////////////////////////////////////////////////////////////////////////// - -// -// Add a terminal node for an identifier in an expression. -// -// Returns the added node. -// -TIntermSymbol *TIntermediate::addSymbol( - int id, const TString &name, const TType &type, const TSourceLoc &line) -{ - TIntermSymbol *node = new TIntermSymbol(id, name, type); - node->setLine(line); - - return node; -} - -// -// Connect two nodes with a new parent that does a binary operation on the nodes. -// -// Returns the added node. -// -TIntermTyped *TIntermediate::addBinaryMath( - TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &line) -{ - // - // Need a new node holding things together then. Make - // one and promote it to the right type. - // - TIntermBinary *node = new TIntermBinary(op); - node->setLine(line); - - node->setLeft(left); - node->setRight(right); - if (!node->promote(mInfoSink)) - return NULL; - - // See if we can fold constants. - TIntermTyped *foldedNode = node->fold(mInfoSink); - if (foldedNode) - return foldedNode; - - return node; -} - -// -// Connect two nodes through an assignment. -// -// Returns the added node. -// -TIntermTyped *TIntermediate::addAssign( - TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &line) -{ - if (left->getType().getStruct() || right->getType().getStruct()) - { - if (left->getType() != right->getType()) - { - return NULL; - } - } - - TIntermBinary *node = new TIntermBinary(op); - node->setLine(line); - - node->setLeft(left); - node->setRight(right); - if (!node->promote(mInfoSink)) - return NULL; - - return node; -} - -// -// Connect two nodes through an index operator, where the left node is the base -// of an array or struct, and the right node is a direct or indirect offset. -// -// Returns the added node. -// The caller should set the type of the returned node. -// -TIntermTyped *TIntermediate::addIndex( - TOperator op, TIntermTyped *base, TIntermTyped *index, const TSourceLoc &line) -{ - TIntermBinary *node = new TIntermBinary(op); - node->setLine(line); - node->setLeft(base); - node->setRight(index); - - // caller should set the type - - return node; -} - -// -// Add one node as the parent of another that it operates on. -// -// Returns the added node. -// -TIntermTyped *TIntermediate::addUnaryMath( - TOperator op, TIntermTyped *child, const TSourceLoc &line, const TType *funcReturnType) -{ - // - // Make a new node for the operator. - // - TIntermUnary *node = new TIntermUnary(op); - node->setLine(line); - node->setOperand(child); - node->promote(funcReturnType); - - TIntermTyped *foldedNode = node->fold(mInfoSink); - if (foldedNode) - return foldedNode; - - return node; -} - -// -// This is the safe way to change the operator on an aggregate, as it -// does lots of error checking and fixing. Especially for establishing -// a function call's operation on it's set of parameters. Sequences -// of instructions are also aggregates, but they just direnctly set -// their operator to EOpSequence. -// -// Returns an aggregate node, which could be the one passed in if -// it was already an aggregate but no operator was set. -// -TIntermAggregate *TIntermediate::setAggregateOperator( - TIntermNode *node, TOperator op, const TSourceLoc &line) -{ - TIntermAggregate *aggNode; - - // - // Make sure we have an aggregate. If not turn it into one. - // - if (node) - { - aggNode = node->getAsAggregate(); - if (aggNode == NULL || aggNode->getOp() != EOpNull) - { - // - // Make an aggregate containing this node. - // - aggNode = new TIntermAggregate(); - aggNode->getSequence()->push_back(node); - } - } - else - { - aggNode = new TIntermAggregate(); - } - - // - // Set the operator. - // - aggNode->setOp(op); - aggNode->setLine(line); - - return aggNode; -} - -// -// Safe way to combine two nodes into an aggregate. Works with null pointers, -// a node that's not a aggregate yet, etc. -// -// Returns the resulting aggregate, unless 0 was passed in for -// both existing nodes. -// -TIntermAggregate *TIntermediate::growAggregate( - TIntermNode *left, TIntermNode *right, const TSourceLoc &line) -{ - if (left == NULL && right == NULL) - return NULL; - - TIntermAggregate *aggNode = NULL; - if (left) - aggNode = left->getAsAggregate(); - if (!aggNode || aggNode->getOp() != EOpNull) - { - aggNode = new TIntermAggregate; - if (left) - aggNode->getSequence()->push_back(left); - } - - if (right) - aggNode->getSequence()->push_back(right); - - aggNode->setLine(line); - - return aggNode; -} - -// -// Turn an existing node into an aggregate. -// -// Returns an aggregate, unless NULL was passed in for the existing node. -// -TIntermAggregate *TIntermediate::makeAggregate( - TIntermNode *node, const TSourceLoc &line) -{ - if (node == NULL) - return NULL; - - TIntermAggregate *aggNode = new TIntermAggregate; - aggNode->getSequence()->push_back(node); - - aggNode->setLine(line); - - return aggNode; -} - -// If the input node is nullptr, return nullptr. -// If the input node is a sequence (block) node, return it. -// If the input node is not a sequence node, put it inside a sequence node and return that. -TIntermAggregate *TIntermediate::ensureSequence(TIntermNode *node) -{ - if (node == nullptr) - return nullptr; - TIntermAggregate *aggNode = node->getAsAggregate(); - if (aggNode != nullptr && aggNode->getOp() == EOpSequence) - return aggNode; - - aggNode = makeAggregate(node, node->getLine()); - aggNode->setOp(EOpSequence); - return aggNode; -} - -// -// For "if" test nodes. There are three children; a condition, -// a true path, and a false path. The two paths are in the -// nodePair. -// -// Returns the selection node created. -// -TIntermNode *TIntermediate::addSelection( - TIntermTyped *cond, TIntermNodePair nodePair, const TSourceLoc &line) -{ - // - // For compile time constant selections, prune the code and - // test now. - // - - if (cond->getAsConstantUnion()) - { - if (cond->getAsConstantUnion()->getBConst(0) == true) - { - return nodePair.node1 ? setAggregateOperator( - nodePair.node1, EOpSequence, nodePair.node1->getLine()) : NULL; - } - else - { - return nodePair.node2 ? setAggregateOperator( - nodePair.node2, EOpSequence, nodePair.node2->getLine()) : NULL; - } - } - - TIntermSelection *node = new TIntermSelection( - cond, ensureSequence(nodePair.node1), ensureSequence(nodePair.node2)); - node->setLine(line); - - return node; -} - -TIntermTyped *TIntermediate::addComma(TIntermTyped *left, - TIntermTyped *right, - const TSourceLoc &line, - int shaderVersion) -{ - TQualifier resultQualifier = EvqConst; - // ESSL3.00 section 12.43: The result of a sequence operator is not a constant-expression. - if (shaderVersion >= 300 || left->getQualifier() != EvqConst || - right->getQualifier() != EvqConst) - { - resultQualifier = EvqTemporary; - } - - TIntermTyped *commaNode = nullptr; - if (!left->hasSideEffects()) - { - commaNode = right; - } - else - { - commaNode = growAggregate(left, right, line); - commaNode->getAsAggregate()->setOp(EOpComma); - commaNode->setType(right->getType()); - } - commaNode->getTypePointer()->setQualifier(resultQualifier); - return commaNode; -} - -// -// For "?:" test nodes. There are three children; a condition, -// a true path, and a false path. The two paths are specified -// as separate parameters. -// -// Returns the selection node created, or one of trueBlock and falseBlock if the expression could be folded. -// -TIntermTyped *TIntermediate::addSelection(TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, - const TSourceLoc &line) -{ - TQualifier resultQualifier = EvqTemporary; - if (cond->getQualifier() == EvqConst && trueBlock->getQualifier() == EvqConst && - falseBlock->getQualifier() == EvqConst) - { - resultQualifier = EvqConst; - } - // Note that the node resulting from here can be a constant union without being qualified as - // constant. - if (cond->getAsConstantUnion()) - { - if (cond->getAsConstantUnion()->getBConst(0)) - { - trueBlock->getTypePointer()->setQualifier(resultQualifier); - return trueBlock; - } - else - { - falseBlock->getTypePointer()->setQualifier(resultQualifier); - return falseBlock; - } - } - - // - // Make a selection node. - // - TIntermSelection *node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType()); - node->getTypePointer()->setQualifier(resultQualifier); - node->setLine(line); - - return node; -} - -TIntermSwitch *TIntermediate::addSwitch( - TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &line) -{ - TIntermSwitch *node = new TIntermSwitch(init, statementList); - node->setLine(line); - - return node; -} - -TIntermCase *TIntermediate::addCase( - TIntermTyped *condition, const TSourceLoc &line) -{ - TIntermCase *node = new TIntermCase(condition); - node->setLine(line); - - return node; -} - -// -// Constant terminal nodes. Has a union that contains bool, float or int constants -// -// Returns the constant union node created. -// - -TIntermConstantUnion *TIntermediate::addConstantUnion(const TConstantUnion *constantUnion, - const TType &type, - const TSourceLoc &line) -{ - TIntermConstantUnion *node = new TIntermConstantUnion(constantUnion, type); - node->setLine(line); - - return node; -} - -TIntermTyped *TIntermediate::addSwizzle( - TVectorFields &fields, const TSourceLoc &line) -{ - - TIntermAggregate *node = new TIntermAggregate(EOpSequence); - - node->setLine(line); - TIntermConstantUnion *constIntNode; - TIntermSequence *sequenceVector = node->getSequence(); - TConstantUnion *unionArray; - - for (int i = 0; i < fields.num; i++) - { - unionArray = new TConstantUnion[1]; - unionArray->setIConst(fields.offsets[i]); - constIntNode = addConstantUnion( - unionArray, TType(EbtInt, EbpUndefined, EvqConst), line); - sequenceVector->push_back(constIntNode); - } - - return node; -} - -// -// Create loop nodes. -// -TIntermNode *TIntermediate::addLoop( - TLoopType type, TIntermNode *init, TIntermTyped *cond, TIntermTyped *expr, - TIntermNode *body, const TSourceLoc &line) -{ - TIntermNode *node = new TIntermLoop(type, init, cond, expr, ensureSequence(body)); - node->setLine(line); - - return node; -} - -// -// Add branches. -// -TIntermBranch* TIntermediate::addBranch( - TOperator branchOp, const TSourceLoc &line) -{ - return addBranch(branchOp, 0, line); -} - -TIntermBranch* TIntermediate::addBranch( - TOperator branchOp, TIntermTyped *expression, const TSourceLoc &line) -{ - TIntermBranch *node = new TIntermBranch(branchOp, expression); - node->setLine(line); - - return node; -} - -// -// This is to be executed once the final root is put on top by the parsing -// process. -// -TIntermAggregate *TIntermediate::postProcess(TIntermNode *root) -{ - if (root == nullptr) - return nullptr; - - // - // Finish off the top level sequence, if any - // - TIntermAggregate *aggRoot = root->getAsAggregate(); - if (aggRoot != nullptr && aggRoot->getOp() == EOpNull) - { - aggRoot->setOp(EOpSequence); - } - else if (aggRoot == nullptr || aggRoot->getOp() != EOpSequence) - { - aggRoot = new TIntermAggregate(EOpSequence); - aggRoot->setLine(root->getLine()); - aggRoot->getSequence()->push_back(root); - } - - return aggRoot; -} - -TIntermTyped *TIntermediate::foldAggregateBuiltIn(TIntermAggregate *aggregate) -{ - switch (aggregate->getOp()) - { - case EOpAtan: - case EOpPow: - case EOpMod: - case EOpMin: - case EOpMax: - case EOpClamp: - case EOpMix: - case EOpStep: - case EOpSmoothStep: - case EOpMul: - case EOpOuterProduct: - case EOpLessThan: - case EOpLessThanEqual: - case EOpGreaterThan: - case EOpGreaterThanEqual: - case EOpVectorEqual: - case EOpVectorNotEqual: - case EOpDistance: - case EOpDot: - case EOpCross: - case EOpFaceForward: - case EOpReflect: - case EOpRefract: - return aggregate->fold(mInfoSink); - default: - // TODO: Add support for folding array constructors - if (aggregate->isConstructor() && !aggregate->isArray()) - { - return aggregate->fold(mInfoSink); - } - // Constant folding not supported for the built-in. - return nullptr; - } - - return nullptr; -} diff --git a/src/3rdparty/angle/src/compiler/translator/Intermediate.h b/src/3rdparty/angle/src/compiler/translator/Intermediate.h deleted file mode 100644 index f723fc7648..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/Intermediate.h +++ /dev/null @@ -1,75 +0,0 @@ -// -// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_TRANSLATOR_INTERMEDIATE_H_ -#define COMPILER_TRANSLATOR_INTERMEDIATE_H_ - -#include "compiler/translator/IntermNode.h" - -struct TVectorFields -{ - int offsets[4]; - int num; -}; - -// -// Set of helper functions to help parse and build the tree. -// -class TInfoSink; -class TIntermediate -{ - public: - POOL_ALLOCATOR_NEW_DELETE(); - TIntermediate(TInfoSink &i) - : mInfoSink(i) { } - - TIntermSymbol *addSymbol( - int id, const TString &, const TType &, const TSourceLoc &); - TIntermTyped *addBinaryMath( - TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &); - TIntermTyped *addAssign( - TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &); - TIntermTyped *addIndex( - TOperator op, TIntermTyped *base, TIntermTyped *index, const TSourceLoc &); - TIntermTyped *addUnaryMath( - TOperator op, TIntermTyped *child, const TSourceLoc &line, const TType *funcReturnType); - TIntermAggregate *growAggregate( - TIntermNode *left, TIntermNode *right, const TSourceLoc &); - TIntermAggregate *makeAggregate(TIntermNode *node, const TSourceLoc &); - TIntermAggregate *ensureSequence(TIntermNode *node); - TIntermAggregate *setAggregateOperator(TIntermNode *, TOperator, const TSourceLoc &); - TIntermNode *addSelection(TIntermTyped *cond, TIntermNodePair code, const TSourceLoc &); - TIntermTyped *addSelection(TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, - const TSourceLoc &line); - TIntermSwitch *addSwitch( - TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &line); - TIntermCase *addCase( - TIntermTyped *condition, const TSourceLoc &line); - TIntermTyped *addComma(TIntermTyped *left, - TIntermTyped *right, - const TSourceLoc &line, - int shaderVersion); - TIntermConstantUnion *addConstantUnion(const TConstantUnion *constantUnion, - const TType &type, - const TSourceLoc &line); - TIntermNode *addLoop(TLoopType, TIntermNode *, TIntermTyped *, TIntermTyped *, - TIntermNode *, const TSourceLoc &); - TIntermBranch *addBranch(TOperator, const TSourceLoc &); - TIntermBranch *addBranch(TOperator, TIntermTyped *, const TSourceLoc &); - TIntermTyped *addSwizzle(TVectorFields &, const TSourceLoc &); - TIntermAggregate *postProcess(TIntermNode *root); - - static void outputTree(TIntermNode *, TInfoSinkBase &); - - TIntermTyped *foldAggregateBuiltIn(TIntermAggregate *aggregate); - - private: - void operator=(TIntermediate &); // prevent assignments - - TInfoSink & mInfoSink; -}; - -#endif // COMPILER_TRANSLATOR_INTERMEDIATE_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/IsASTDepthBelowLimit.cpp b/src/3rdparty/angle/src/compiler/translator/IsASTDepthBelowLimit.cpp new file mode 100644 index 0000000000..aaad4f3c68 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/IsASTDepthBelowLimit.cpp @@ -0,0 +1,51 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/translator/IsASTDepthBelowLimit.h" + +#include "compiler/translator/IntermTraverse.h" + +namespace sh +{ + +namespace +{ + +// Traverse the tree and compute max depth. Takes a maximum depth limit to prevent stack overflow. +class MaxDepthTraverser : public TIntermTraverser +{ + public: + MaxDepthTraverser(int depthLimit) : TIntermTraverser(true, true, false), mDepthLimit(depthLimit) + { + } + + bool visitBinary(Visit, TIntermBinary *) override { return depthCheck(); } + bool visitUnary(Visit, TIntermUnary *) override { return depthCheck(); } + bool visitTernary(Visit, TIntermTernary *) override { return depthCheck(); } + bool visitSwizzle(Visit, TIntermSwizzle *) override { return depthCheck(); } + bool visitIfElse(Visit, TIntermIfElse *) override { return depthCheck(); } + bool visitAggregate(Visit, TIntermAggregate *) override { return depthCheck(); } + bool visitBlock(Visit, TIntermBlock *) override { return depthCheck(); } + bool visitLoop(Visit, TIntermLoop *) override { return depthCheck(); } + bool visitBranch(Visit, TIntermBranch *) override { return depthCheck(); } + + protected: + bool depthCheck() const { return mMaxDepth < mDepthLimit; } + + int mDepthLimit; +}; + +} // anonymous namespace + +bool IsASTDepthBelowLimit(TIntermNode *root, int maxDepth) +{ + MaxDepthTraverser traverser(maxDepth + 1); + root->traverse(&traverser); + + return traverser.getMaxDepth() <= maxDepth; +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/IsASTDepthBelowLimit.h b/src/3rdparty/angle/src/compiler/translator/IsASTDepthBelowLimit.h new file mode 100644 index 0000000000..ef2f02c974 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/IsASTDepthBelowLimit.h @@ -0,0 +1,20 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// IsASTDepthBelowLimit: Check whether AST depth is below a specific limit. + +#ifndef COMPILER_TRANSLATOR_ISASTDEPTHBELOWLIMIT_H_ +#define COMPILER_TRANSLATOR_ISASTDEPTHBELOWLIMIT_H_ + +namespace sh +{ + +class TIntermNode; + +bool IsASTDepthBelowLimit(TIntermNode *root, int maxDepth); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_ISASTDEPTHBELOWLIMIT_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/LoopInfo.cpp b/src/3rdparty/angle/src/compiler/translator/LoopInfo.cpp deleted file mode 100644 index d931a18a23..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/LoopInfo.cpp +++ /dev/null @@ -1,211 +0,0 @@ -// -// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/translator/LoopInfo.h" - -namespace -{ - -int EvaluateIntConstant(TIntermConstantUnion *node) -{ - ASSERT(node && node->getUnionArrayPointer()); - return node->getIConst(0); -} - -int GetLoopIntIncrement(TIntermLoop *node) -{ - TIntermNode *expr = node->getExpression(); - // for expression has one of the following forms: - // loop_index++ - // loop_index-- - // loop_index += constant_expression - // loop_index -= constant_expression - // ++loop_index - // --loop_index - // The last two forms are not specified in the spec, but I am assuming - // its an oversight. - TIntermUnary *unOp = expr->getAsUnaryNode(); - TIntermBinary *binOp = unOp ? NULL : expr->getAsBinaryNode(); - - TOperator op = EOpNull; - TIntermConstantUnion *incrementNode = NULL; - if (unOp) - { - op = unOp->getOp(); - } - else if (binOp) - { - op = binOp->getOp(); - ASSERT(binOp->getRight()); - incrementNode = binOp->getRight()->getAsConstantUnion(); - ASSERT(incrementNode); - } - - int increment = 0; - // The operator is one of: ++ -- += -=. - switch (op) - { - case EOpPostIncrement: - case EOpPreIncrement: - ASSERT(unOp && !binOp); - increment = 1; - break; - case EOpPostDecrement: - case EOpPreDecrement: - ASSERT(unOp && !binOp); - increment = -1; - break; - case EOpAddAssign: - ASSERT(!unOp && binOp); - increment = EvaluateIntConstant(incrementNode); - break; - case EOpSubAssign: - ASSERT(!unOp && binOp); - increment = - EvaluateIntConstant(incrementNode); - break; - default: - UNREACHABLE(); - } - - return increment; -} - -} // namespace anonymous - -TLoopIndexInfo::TLoopIndexInfo() - : mId(-1), - mType(EbtVoid), - mInitValue(0), - mStopValue(0), - mIncrementValue(0), - mOp(EOpNull), - mCurrentValue(0) -{ -} - -void TLoopIndexInfo::fillInfo(TIntermLoop *node) -{ - if (node == NULL) - return; - - // Here we assume all the operations are valid, because the loop node is - // already validated in ValidateLimitations. - TIntermSequence *declSeq = - node->getInit()->getAsAggregate()->getSequence(); - TIntermBinary *declInit = (*declSeq)[0]->getAsBinaryNode(); - TIntermSymbol *symbol = declInit->getLeft()->getAsSymbolNode(); - - mId = symbol->getId(); - mType = symbol->getBasicType(); - - if (mType == EbtInt) - { - TIntermConstantUnion* initNode = declInit->getRight()->getAsConstantUnion(); - mInitValue = EvaluateIntConstant(initNode); - mCurrentValue = mInitValue; - mIncrementValue = GetLoopIntIncrement(node); - - TIntermBinary* binOp = node->getCondition()->getAsBinaryNode(); - mStopValue = EvaluateIntConstant( - binOp->getRight()->getAsConstantUnion()); - mOp = binOp->getOp(); - } -} - -bool TLoopIndexInfo::satisfiesLoopCondition() const -{ - // Relational operator is one of: > >= < <= == or !=. - switch (mOp) - { - case EOpEqual: - return (mCurrentValue == mStopValue); - case EOpNotEqual: - return (mCurrentValue != mStopValue); - case EOpLessThan: - return (mCurrentValue < mStopValue); - case EOpGreaterThan: - return (mCurrentValue > mStopValue); - case EOpLessThanEqual: - return (mCurrentValue <= mStopValue); - case EOpGreaterThanEqual: - return (mCurrentValue >= mStopValue); - default: - UNREACHABLE(); - return false; - } -} - -TLoopInfo::TLoopInfo() - : loop(NULL) -{ -} - -TLoopInfo::TLoopInfo(TIntermLoop *node) - : loop(node) -{ - index.fillInfo(node); -} - -TIntermLoop *TLoopStack::findLoop(TIntermSymbol *symbol) -{ - if (!symbol) - return NULL; - for (iterator iter = begin(); iter != end(); ++iter) - { - if (iter->index.getId() == symbol->getId()) - return iter->loop; - } - return NULL; -} - -TLoopIndexInfo *TLoopStack::getIndexInfo(TIntermSymbol *symbol) -{ - if (!symbol) - return NULL; - for (iterator iter = begin(); iter != end(); ++iter) - { - if (iter->index.getId() == symbol->getId()) - return &(iter->index); - } - return NULL; -} - -void TLoopStack::step() -{ - ASSERT(!empty()); - rbegin()->index.step(); -} - -bool TLoopStack::satisfiesLoopCondition() -{ - ASSERT(!empty()); - return rbegin()->index.satisfiesLoopCondition(); -} - -bool TLoopStack::needsToReplaceSymbolWithValue(TIntermSymbol *symbol) -{ - TIntermLoop *loop = findLoop(symbol); - return loop && loop->getUnrollFlag(); -} - -int TLoopStack::getLoopIndexValue(TIntermSymbol *symbol) -{ - TLoopIndexInfo *info = getIndexInfo(symbol); - ASSERT(info); - return info->getCurrentValue(); -} - -void TLoopStack::push(TIntermLoop *loop) -{ - TLoopInfo info(loop); - push_back(info); -} - -void TLoopStack::pop() -{ - pop_back(); -} - diff --git a/src/3rdparty/angle/src/compiler/translator/LoopInfo.h b/src/3rdparty/angle/src/compiler/translator/LoopInfo.h deleted file mode 100644 index ec73fd0fa5..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/LoopInfo.h +++ /dev/null @@ -1,80 +0,0 @@ -// -// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_TRANSLATOR_LOOPINFO_H_ -#define COMPILER_TRANSLATOR_LOOPINFO_H_ - -#include "compiler/translator/IntermNode.h" - -class TLoopIndexInfo -{ - public: - TLoopIndexInfo(); - - // If type is EbtInt, fill all fields of the structure with info - // extracted from a loop node. - // If type is not EbtInt, only fill id and type. - void fillInfo(TIntermLoop *node); - - int getId() const { return mId; } - void setId(int id) { mId = id; } - TBasicType getType() const { return mType; } - void setType(TBasicType type) { mType = type; } - int getCurrentValue() const { return mCurrentValue; } - - void step() { mCurrentValue += mIncrementValue; } - - // Check if the current value satisfies the loop condition. - bool satisfiesLoopCondition() const; - - private: - int mId; - TBasicType mType; // Either EbtInt or EbtFloat - - // Below fields are only valid if the index's type is int. - int mInitValue; - int mStopValue; - int mIncrementValue; - TOperator mOp; - int mCurrentValue; -}; - -struct TLoopInfo -{ - TLoopIndexInfo index; - TIntermLoop *loop; - - TLoopInfo(); - TLoopInfo(TIntermLoop *node); -}; - -class TLoopStack : public TVector -{ - public: - // Search loop stack for a loop whose index matches the input symbol. - TIntermLoop *findLoop(TIntermSymbol *symbol); - - // Find the loop index info in the loop stack by the input symbol. - TLoopIndexInfo *getIndexInfo(TIntermSymbol *symbol); - - // Update the currentValue for the next loop iteration. - void step(); - - // Return false if loop condition is no longer satisfied. - bool satisfiesLoopCondition(); - - // Check if the symbol is the index of a loop that's unrolled. - bool needsToReplaceSymbolWithValue(TIntermSymbol *symbol); - - // Return the current value of a given loop index symbol. - int getLoopIndexValue(TIntermSymbol *symbol); - - void push(TIntermLoop *info); - void pop(); -}; - -#endif // COMPILER_TRANSLATOR_LOOPINFO_H_ - diff --git a/src/3rdparty/angle/src/compiler/translator/MMap.h b/src/3rdparty/angle/src/compiler/translator/MMap.h deleted file mode 100644 index fca843992b..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/MMap.h +++ /dev/null @@ -1,56 +0,0 @@ -// -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_TRANSLATOR_MMAP_H_ -#define COMPILER_TRANSLATOR_MMAP_H_ - -// -// Encapsulate memory mapped files -// - -class TMMap { -public: - TMMap(const char* fileName) : - fSize(-1), // -1 is the error value returned by GetFileSize() - fp(NULL), - fBuff(0) // 0 is the error value returned by MapViewOfFile() - { - if ((fp = fopen(fileName, "r")) == NULL) - return; - char c = getc(fp); - fSize = 0; - while (c != EOF) { - fSize++; - c = getc(fp); - } - if (c == EOF) - fSize++; - rewind(fp); - fBuff = (char*)malloc(sizeof(char) * fSize); - int count = 0; - c = getc(fp); - while (c != EOF) { - fBuff[count++] = c; - c = getc(fp); - } - fBuff[count++] = c; - } - - char* getData() { return fBuff; } - int getSize() { return fSize; } - - ~TMMap() { - if (fp != NULL) - fclose(fp); - } - -private: - int fSize; // size of file to map in - FILE *fp; - char* fBuff; // the actual data; -}; - -#endif // COMPILER_TRANSLATOR_MMAP_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/NodeSearch.h b/src/3rdparty/angle/src/compiler/translator/NodeSearch.h index b13b1baabb..af86b8bde4 100644 --- a/src/3rdparty/angle/src/compiler/translator/NodeSearch.h +++ b/src/3rdparty/angle/src/compiler/translator/NodeSearch.h @@ -9,7 +9,7 @@ #ifndef COMPILER_TRANSLATOR_NODESEARCH_H_ #define COMPILER_TRANSLATOR_NODESEARCH_H_ -#include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermTraverse.h" namespace sh { @@ -18,10 +18,7 @@ template class NodeSearchTraverser : public TIntermTraverser { public: - NodeSearchTraverser() - : TIntermTraverser(true, false, false), - mFound(false) - {} + NodeSearchTraverser() : TIntermTraverser(true, false, false), mFound(false) {} bool found() const { return mFound; } @@ -43,17 +40,17 @@ class FindDiscard : public NodeSearchTraverser { switch (node->getFlowOp()) { - case EOpKill: - mFound = true; - break; + case EOpKill: + mFound = true; + break; - default: break; + default: + break; } return !mFound; } }; - } -#endif // COMPILER_TRANSLATOR_NODESEARCH_H_ +#endif // COMPILER_TRANSLATOR_NODESEARCH_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/Operator.cpp b/src/3rdparty/angle/src/compiler/translator/Operator.cpp index 20e47f290e..7a2156611a 100644 --- a/src/3rdparty/angle/src/compiler/translator/Operator.cpp +++ b/src/3rdparty/angle/src/compiler/translator/Operator.cpp @@ -10,192 +10,376 @@ const char *GetOperatorString(TOperator op) { switch (op) { - // Note: ops from EOpNull to EOpPrototype can't be handled here. + // Note: EOpNull and EOpCall* can't be handled here. - case EOpNegative: return "-"; - case EOpPositive: return "+"; - case EOpLogicalNot: return "!"; - case EOpVectorLogicalNot: return "not"; - case EOpBitwiseNot: return "~"; + case EOpNegative: + return "-"; + case EOpPositive: + return "+"; + case EOpLogicalNot: + return "!"; + case EOpBitwiseNot: + return "~"; - case EOpPostIncrement: return "++"; - case EOpPostDecrement: return "--"; - case EOpPreIncrement: return "++"; - case EOpPreDecrement: return "--"; + case EOpPostIncrement: + return "++"; + case EOpPostDecrement: + return "--"; + case EOpPreIncrement: + return "++"; + case EOpPreDecrement: + return "--"; - case EOpAdd: return "+"; - case EOpSub: return "-"; - case EOpMul: return "*"; - case EOpDiv: return "/"; - case EOpIMod: return "%"; - case EOpEqual: return "=="; - case EOpNotEqual: return "!="; - case EOpVectorEqual: return "equal"; - case EOpVectorNotEqual: return "notEqual"; - case EOpLessThan: return "<"; - case EOpGreaterThan: return ">"; - case EOpLessThanEqual: return "<="; - case EOpGreaterThanEqual: return ">="; - case EOpComma: return ","; + case EOpArrayLength: + return ".length()"; - // Fall-through. - case EOpVectorTimesScalar: - case EOpVectorTimesMatrix: - case EOpMatrixTimesVector: - case EOpMatrixTimesScalar: return "*"; + case EOpAdd: + return "+"; + case EOpSub: + return "-"; + case EOpMul: + return "*"; + case EOpDiv: + return "/"; + case EOpIMod: + return "%"; - case EOpLogicalOr: return "||"; - case EOpLogicalXor: return "^^"; - case EOpLogicalAnd: return "&&"; + case EOpEqual: + return "=="; + case EOpNotEqual: + return "!="; + case EOpLessThan: + return "<"; + case EOpGreaterThan: + return ">"; + case EOpLessThanEqual: + return "<="; + case EOpGreaterThanEqual: + return ">="; - case EOpBitShiftLeft: return "<<"; - case EOpBitShiftRight: return ">>"; + case EOpEqualComponentWise: + return "equal"; + case EOpNotEqualComponentWise: + return "notEqual"; + case EOpLessThanComponentWise: + return "lessThan"; + case EOpGreaterThanComponentWise: + return "greaterThan"; + case EOpLessThanEqualComponentWise: + return "lessThanEqual"; + case EOpGreaterThanEqualComponentWise: + return "greaterThanEqual"; - case EOpBitwiseAnd: return "&"; - case EOpBitwiseXor: return "^"; - case EOpBitwiseOr: return "|"; + case EOpComma: + return ","; - // Fall-through. - case EOpIndexDirect: - case EOpIndexIndirect: return "[]"; + // Fall-through. + case EOpVectorTimesScalar: + case EOpVectorTimesMatrix: + case EOpMatrixTimesVector: + case EOpMatrixTimesScalar: + case EOpMatrixTimesMatrix: + return "*"; - case EOpIndexDirectStruct: - case EOpIndexDirectInterfaceBlock: return "."; + case EOpLogicalOr: + return "||"; + case EOpLogicalXor: + return "^^"; + case EOpLogicalAnd: + return "&&"; - case EOpVectorSwizzle: return "."; + case EOpBitShiftLeft: + return "<<"; + case EOpBitShiftRight: + return ">>"; - case EOpRadians: return "radians"; - case EOpDegrees: return "degrees"; - case EOpSin: return "sin"; - case EOpCos: return "cos"; - case EOpTan: return "tan"; - case EOpAsin: return "asin"; - case EOpAcos: return "acos"; - case EOpAtan: return "atan"; + case EOpBitwiseAnd: + return "&"; + case EOpBitwiseXor: + return "^"; + case EOpBitwiseOr: + return "|"; - case EOpSinh: return "sinh"; - case EOpCosh: return "cosh"; - case EOpTanh: return "tanh"; - case EOpAsinh: return "asinh"; - case EOpAcosh: return "acosh"; - case EOpAtanh: return "atanh"; + // Fall-through. + case EOpIndexDirect: + case EOpIndexIndirect: + return "[]"; - case EOpPow: return "pow"; - case EOpExp: return "exp"; - case EOpLog: return "log"; - case EOpExp2: return "exp2"; - case EOpLog2: return "log2"; - case EOpSqrt: return "sqrt"; - case EOpInverseSqrt: return "inversesqrt"; + case EOpIndexDirectStruct: + case EOpIndexDirectInterfaceBlock: + return "."; - case EOpAbs: return "abs"; - case EOpSign: return "sign"; - case EOpFloor: return "floor"; - case EOpTrunc: return "trunc"; - case EOpRound: return "round"; - case EOpRoundEven: return "roundEven"; - case EOpCeil: return "ceil"; - case EOpFract: return "fract"; - case EOpMod: return "mod"; - case EOpModf: return "modf"; - case EOpMin: return "min"; - case EOpMax: return "max"; - case EOpClamp: return "clamp"; - case EOpMix: return "mix"; - case EOpStep: return "step"; - case EOpSmoothStep: return "smoothstep"; - case EOpIsNan: return "isnan"; - case EOpIsInf: return "isinf"; + case EOpRadians: + return "radians"; + case EOpDegrees: + return "degrees"; + case EOpSin: + return "sin"; + case EOpCos: + return "cos"; + case EOpTan: + return "tan"; + case EOpAsin: + return "asin"; + case EOpAcos: + return "acos"; + case EOpAtan: + return "atan"; - case EOpFloatBitsToInt: return "floatBitsToInt"; - case EOpFloatBitsToUint: return "floatBitsToUint"; - case EOpIntBitsToFloat: return "intBitsToFloat"; - case EOpUintBitsToFloat: return "uintBitsToFloat"; + case EOpSinh: + return "sinh"; + case EOpCosh: + return "cosh"; + case EOpTanh: + return "tanh"; + case EOpAsinh: + return "asinh"; + case EOpAcosh: + return "acosh"; + case EOpAtanh: + return "atanh"; - case EOpPackSnorm2x16: return "packSnorm2x16"; - case EOpPackUnorm2x16: return "packUnorm2x16"; - case EOpPackHalf2x16: return "packHalf2x16"; - case EOpUnpackSnorm2x16: return "unpackSnorm2x16"; - case EOpUnpackUnorm2x16: return "unpackUnorm2x16"; - case EOpUnpackHalf2x16: return "unpackHalf2x16"; + case EOpPow: + return "pow"; + case EOpExp: + return "exp"; + case EOpLog: + return "log"; + case EOpExp2: + return "exp2"; + case EOpLog2: + return "log2"; + case EOpSqrt: + return "sqrt"; + case EOpInverseSqrt: + return "inversesqrt"; - case EOpLength: return "length"; - case EOpDistance: return "distance"; - case EOpDot: return "dot"; - case EOpCross: return "cross"; - case EOpNormalize: return "normalize"; - case EOpFaceForward: return "faceforward"; - case EOpReflect: return "reflect"; - case EOpRefract: return "refract"; + case EOpAbs: + return "abs"; + case EOpSign: + return "sign"; + case EOpFloor: + return "floor"; + case EOpTrunc: + return "trunc"; + case EOpRound: + return "round"; + case EOpRoundEven: + return "roundEven"; + case EOpCeil: + return "ceil"; + case EOpFract: + return "fract"; + case EOpMod: + return "mod"; + case EOpModf: + return "modf"; + case EOpMin: + return "min"; + case EOpMax: + return "max"; + case EOpClamp: + return "clamp"; + case EOpMix: + return "mix"; + case EOpStep: + return "step"; + case EOpSmoothStep: + return "smoothstep"; + case EOpIsNan: + return "isnan"; + case EOpIsInf: + return "isinf"; - case EOpDFdx: return "dFdx"; - case EOpDFdy: return "dFdy"; - case EOpFwidth: return "fwidth"; + case EOpFloatBitsToInt: + return "floatBitsToInt"; + case EOpFloatBitsToUint: + return "floatBitsToUint"; + case EOpIntBitsToFloat: + return "intBitsToFloat"; + case EOpUintBitsToFloat: + return "uintBitsToFloat"; - case EOpMatrixTimesMatrix: return "*"; + case EOpFrexp: + return "frexp"; + case EOpLdexp: + return "ldexp"; - case EOpOuterProduct: return "outerProduct"; - case EOpTranspose: return "transpose"; - case EOpDeterminant: return "determinant"; - case EOpInverse: return "inverse"; + case EOpPackSnorm2x16: + return "packSnorm2x16"; + case EOpPackUnorm2x16: + return "packUnorm2x16"; + case EOpPackHalf2x16: + return "packHalf2x16"; + case EOpUnpackSnorm2x16: + return "unpackSnorm2x16"; + case EOpUnpackUnorm2x16: + return "unpackUnorm2x16"; + case EOpUnpackHalf2x16: + return "unpackHalf2x16"; - case EOpAny: return "any"; - case EOpAll: return "all"; + case EOpPackUnorm4x8: + return "packUnorm4x8"; + case EOpPackSnorm4x8: + return "packSnorm4x8"; + case EOpUnpackUnorm4x8: + return "unpackUnorm4x8"; + case EOpUnpackSnorm4x8: + return "unpackSnorm4x8"; - case EOpKill: return "kill"; - case EOpReturn: return "return"; - case EOpBreak: return "break"; - case EOpContinue: return "continue"; + case EOpLength: + return "length"; + case EOpDistance: + return "distance"; + case EOpDot: + return "dot"; + case EOpCross: + return "cross"; + case EOpNormalize: + return "normalize"; + case EOpFaceforward: + return "faceforward"; + case EOpReflect: + return "reflect"; + case EOpRefract: + return "refract"; - case EOpConstructInt: return "int"; - case EOpConstructUInt: return "uint"; - case EOpConstructBool: return "bool"; - case EOpConstructFloat: return "float"; - case EOpConstructVec2: return "vec2"; - case EOpConstructVec3: return "vec3"; - case EOpConstructVec4: return "vec4"; - case EOpConstructBVec2: return "bvec2"; - case EOpConstructBVec3: return "bvec3"; - case EOpConstructBVec4: return "bvec4"; - case EOpConstructIVec2: return "ivec2"; - case EOpConstructIVec3: return "ivec3"; - case EOpConstructIVec4: return "ivec4"; - case EOpConstructUVec2: return "uvec2"; - case EOpConstructUVec3: return "uvec3"; - case EOpConstructUVec4: return "uvec4"; - case EOpConstructMat2: return "mat2"; - case EOpConstructMat2x3: return "mat2x3"; - case EOpConstructMat2x4: return "mat2x4"; - case EOpConstructMat3x2: return "mat3x2"; - case EOpConstructMat3: return "mat3"; - case EOpConstructMat3x4: return "mat3x4"; - case EOpConstructMat4x2: return "mat4x2"; - case EOpConstructMat4x3: return "mat4x3"; - case EOpConstructMat4: return "mat4"; - // Note: EOpConstructStruct can't be handled here + case EOpDFdx: + return "dFdx"; + case EOpDFdy: + return "dFdy"; + case EOpFwidth: + return "fwidth"; - case EOpAssign: return "="; - case EOpInitialize: return "="; - case EOpAddAssign: return "+="; - case EOpSubAssign: return "-="; + case EOpMulMatrixComponentWise: + return "matrixCompMult"; + case EOpOuterProduct: + return "outerProduct"; + case EOpTranspose: + return "transpose"; + case EOpDeterminant: + return "determinant"; + case EOpInverse: + return "inverse"; - // Fall-through. - case EOpMulAssign: - case EOpVectorTimesMatrixAssign: - case EOpVectorTimesScalarAssign: - case EOpMatrixTimesScalarAssign: - case EOpMatrixTimesMatrixAssign: return "*="; + case EOpAny: + return "any"; + case EOpAll: + return "all"; + case EOpLogicalNotComponentWise: + return "not"; - case EOpDivAssign: return "/="; - case EOpIModAssign: return "%="; - case EOpBitShiftLeftAssign: return "<<="; - case EOpBitShiftRightAssign: return ">>="; - case EOpBitwiseAndAssign: return "&="; - case EOpBitwiseXorAssign: return "^="; - case EOpBitwiseOrAssign: return "|="; + case EOpBitfieldExtract: + return "bitfieldExtract"; + case EOpBitfieldInsert: + return "bitfieldInsert"; + case EOpBitfieldReverse: + return "bitfieldReverse"; + case EOpBitCount: + return "bitCount"; + case EOpFindLSB: + return "findLSB"; + case EOpFindMSB: + return "findMSB"; + case EOpUaddCarry: + return "uaddCarry"; + case EOpUsubBorrow: + return "usubBorrow"; + case EOpUmulExtended: + return "umulExtended"; + case EOpImulExtended: + return "imulExtended"; - default: break; + case EOpKill: + return "kill"; + case EOpReturn: + return "return"; + case EOpBreak: + return "break"; + case EOpContinue: + return "continue"; + + case EOpAssign: + return "="; + case EOpInitialize: + return "="; + case EOpAddAssign: + return "+="; + case EOpSubAssign: + return "-="; + + // Fall-through. + case EOpMulAssign: + case EOpVectorTimesMatrixAssign: + case EOpVectorTimesScalarAssign: + case EOpMatrixTimesScalarAssign: + case EOpMatrixTimesMatrixAssign: + return "*="; + + case EOpDivAssign: + return "/="; + case EOpIModAssign: + return "%="; + case EOpBitShiftLeftAssign: + return "<<="; + case EOpBitShiftRightAssign: + return ">>="; + case EOpBitwiseAndAssign: + return "&="; + case EOpBitwiseXorAssign: + return "^="; + case EOpBitwiseOrAssign: + return "|="; + case EOpBarrier: + return "barrier"; + case EOpMemoryBarrier: + return "memoryBarrier"; + case EOpMemoryBarrierAtomicCounter: + return "memoryBarrierAtomicCounter"; + case EOpMemoryBarrierBuffer: + return "memoryBarrierBuffer"; + case EOpMemoryBarrierImage: + return "memoryBarrierImage"; + case EOpMemoryBarrierShared: + return "memoryBarrierShared"; + case EOpGroupMemoryBarrier: + return "groupMemoryBarrier"; + + case EOpEmitVertex: + return "EmitVertex"; + case EOpEndPrimitive: + return "EndPrimitive"; + default: + break; } return ""; } +bool IsAssignment(TOperator op) +{ + switch (op) + { + case EOpPostIncrement: + case EOpPostDecrement: + case EOpPreIncrement: + case EOpPreDecrement: + case EOpAssign: + case EOpAddAssign: + case EOpSubAssign: + case EOpMulAssign: + case EOpVectorTimesMatrixAssign: + case EOpVectorTimesScalarAssign: + case EOpMatrixTimesScalarAssign: + case EOpMatrixTimesMatrixAssign: + case EOpDivAssign: + case EOpIModAssign: + case EOpBitShiftLeftAssign: + case EOpBitShiftRightAssign: + case EOpBitwiseAndAssign: + case EOpBitwiseXorAssign: + case EOpBitwiseOrAssign: + return true; + default: + return false; + } +} \ No newline at end of file diff --git a/src/3rdparty/angle/src/compiler/translator/Operator.h b/src/3rdparty/angle/src/compiler/translator/Operator.h index b0efb8f48b..72f3dbf3f6 100644 --- a/src/3rdparty/angle/src/compiler/translator/Operator.h +++ b/src/3rdparty/angle/src/compiler/translator/Operator.h @@ -12,15 +12,21 @@ // enum TOperator { - EOpNull, // if in a node, should only mean a node is still being built - EOpSequence, // denotes a list of statements, or parameters, etc. - EOpFunctionCall, - EOpFunction, // For function definition - EOpParameters, // an aggregate listing the parameters to a function + EOpNull, // if in a node, should only mean a node is still being built - EOpDeclaration, - EOpInvariantDeclaration, // Specialized declarations for attributing invariance - EOpPrototype, + // Call a function defined in the AST. This might be a user-defined function or a function + // inserted by an AST transformation. + EOpCallFunctionInAST, + + // Call an internal helper function with a raw implementation - the implementation can't be + // subject to AST transformations. Raw functions have a few constraints to keep them compatible + // with AST traversers: + // * They should not return arrays. + // * They should not have out parameters. + EOpCallInternalRawFunction, + + // Call a built-in function like a texture or image function. + EOpCallBuiltInFunction, // // Unary operators @@ -29,7 +35,6 @@ enum TOperator EOpNegative, EOpPositive, EOpLogicalNot, - EOpVectorLogicalNot, EOpBitwiseNot, EOpPostIncrement, @@ -37,8 +42,11 @@ enum TOperator EOpPreIncrement, EOpPreDecrement, + EOpArrayLength, + // - // binary operations + // binary operations (ones with special GLSL syntax are used in TIntermBinary nodes, others in + // TIntermAggregate nodes) // EOpAdd, @@ -46,20 +54,28 @@ enum TOperator EOpMul, EOpDiv, EOpIMod, + EOpEqual, EOpNotEqual, - EOpVectorEqual, - EOpVectorNotEqual, EOpLessThan, EOpGreaterThan, EOpLessThanEqual, EOpGreaterThanEqual, + + EOpEqualComponentWise, + EOpNotEqualComponentWise, + EOpLessThanComponentWise, + EOpLessThanEqualComponentWise, + EOpGreaterThanComponentWise, + EOpGreaterThanEqualComponentWise, + EOpComma, EOpVectorTimesScalar, EOpVectorTimesMatrix, EOpMatrixTimesVector, EOpMatrixTimesScalar, + EOpMatrixTimesMatrix, EOpLogicalOr, EOpLogicalXor, @@ -77,10 +93,8 @@ enum TOperator EOpIndexDirectStruct, EOpIndexDirectInterfaceBlock, - EOpVectorSwizzle, - // - // Built-in functions potentially mapped to operators + // Built-in functions mapped to operators (either unary or with multiple parameters) // EOpRadians, @@ -131,6 +145,9 @@ enum TOperator EOpIntBitsToFloat, EOpUintBitsToFloat, + EOpFrexp, + EOpLdexp, + EOpPackSnorm2x16, EOpPackUnorm2x16, EOpPackHalf2x16, @@ -138,21 +155,25 @@ enum TOperator EOpUnpackUnorm2x16, EOpUnpackHalf2x16, + EOpPackUnorm4x8, + EOpPackSnorm4x8, + EOpUnpackUnorm4x8, + EOpUnpackSnorm4x8, + EOpLength, EOpDistance, EOpDot, EOpCross, EOpNormalize, - EOpFaceForward, + EOpFaceforward, EOpReflect, EOpRefract, - EOpDFdx, // Fragment only, OES_standard_derivatives extension - EOpDFdy, // Fragment only, OES_standard_derivatives extension - EOpFwidth, // Fragment only, OES_standard_derivatives extension - - EOpMatrixTimesMatrix, + EOpDFdx, // Fragment only, OES_standard_derivatives extension + EOpDFdy, // Fragment only, OES_standard_derivatives extension + EOpFwidth, // Fragment only, OES_standard_derivatives extension + EOpMulMatrixComponentWise, EOpOuterProduct, EOpTranspose, EOpDeterminant, @@ -160,46 +181,33 @@ enum TOperator EOpAny, EOpAll, + EOpLogicalNotComponentWise, + + EOpBitfieldExtract, + EOpBitfieldInsert, + EOpBitfieldReverse, + EOpBitCount, + EOpFindLSB, + EOpFindMSB, + EOpUaddCarry, + EOpUsubBorrow, + EOpUmulExtended, + EOpImulExtended, // // Branch // - EOpKill, // Fragment only + EOpKill, // Fragment only EOpReturn, EOpBreak, EOpContinue, // - // Constructors + // Constructor // - EOpConstructInt, - EOpConstructUInt, - EOpConstructBool, - EOpConstructFloat, - EOpConstructVec2, - EOpConstructVec3, - EOpConstructVec4, - EOpConstructBVec2, - EOpConstructBVec3, - EOpConstructBVec4, - EOpConstructIVec2, - EOpConstructIVec3, - EOpConstructIVec4, - EOpConstructUVec2, - EOpConstructUVec3, - EOpConstructUVec4, - EOpConstructMat2, - EOpConstructMat2x3, - EOpConstructMat2x4, - EOpConstructMat3x2, - EOpConstructMat3, - EOpConstructMat3x4, - EOpConstructMat4x2, - EOpConstructMat4x3, - EOpConstructMat4, - EOpConstructStruct, + EOpConstruct, // // moves @@ -222,10 +230,26 @@ enum TOperator EOpBitShiftRightAssign, EOpBitwiseAndAssign, EOpBitwiseXorAssign, - EOpBitwiseOrAssign + EOpBitwiseOrAssign, + + // barriers + EOpBarrier, + EOpMemoryBarrier, + EOpMemoryBarrierAtomicCounter, + EOpMemoryBarrierBuffer, + EOpMemoryBarrierImage, + EOpMemoryBarrierShared, + EOpGroupMemoryBarrier, + + // Geometry only + EOpEmitVertex, + EOpEndPrimitive }; // Returns the string corresponding to the operator in GLSL -const char* GetOperatorString(TOperator op); +const char *GetOperatorString(TOperator op); + +// Say whether or not a binary or unary operation changes the value of a variable. +bool IsAssignment(TOperator op); #endif // COMPILER_TRANSLATOR_OPERATOR_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/OutputESSL.cpp b/src/3rdparty/angle/src/compiler/translator/OutputESSL.cpp index 77e0a8fb37..50626c91c0 100644 --- a/src/3rdparty/angle/src/compiler/translator/OutputESSL.cpp +++ b/src/3rdparty/angle/src/compiler/translator/OutputESSL.cpp @@ -6,20 +6,27 @@ #include "compiler/translator/OutputESSL.h" +namespace sh +{ + TOutputESSL::TOutputESSL(TInfoSinkBase &objSink, ShArrayIndexClampingStrategy clampingStrategy, ShHashFunction64 hashFunction, NameMap &nameMap, - TSymbolTable &symbolTable, + TSymbolTable *symbolTable, + sh::GLenum shaderType, int shaderVersion, - bool forceHighp) + bool forceHighp, + ShCompileOptions compileOptions) : TOutputGLSLBase(objSink, clampingStrategy, hashFunction, nameMap, symbolTable, + shaderType, shaderVersion, - SH_ESSL_OUTPUT), + SH_ESSL_OUTPUT, + compileOptions), mForceHighp(forceHighp) { } @@ -29,10 +36,12 @@ bool TOutputESSL::writeVariablePrecision(TPrecision precision) if (precision == EbpUndefined) return false; - TInfoSinkBase& out = objSink(); + TInfoSinkBase &out = objSink(); if (mForceHighp) out << getPrecisionString(EbpHigh); else out << getPrecisionString(precision); return true; } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/OutputESSL.h b/src/3rdparty/angle/src/compiler/translator/OutputESSL.h index c5a963499e..e0c7bf2ae6 100644 --- a/src/3rdparty/angle/src/compiler/translator/OutputESSL.h +++ b/src/3rdparty/angle/src/compiler/translator/OutputESSL.h @@ -9,22 +9,29 @@ #include "compiler/translator/OutputGLSLBase.h" +namespace sh +{ + class TOutputESSL : public TOutputGLSLBase { -public: - TOutputESSL(TInfoSinkBase& objSink, + public: + TOutputESSL(TInfoSinkBase &objSink, ShArrayIndexClampingStrategy clampingStrategy, ShHashFunction64 hashFunction, - NameMap& nameMap, - TSymbolTable& symbolTable, + NameMap &nameMap, + TSymbolTable *symbolTable, + sh::GLenum shaderType, int shaderVersion, - bool forceHighp); + bool forceHighp, + ShCompileOptions compileOptions); -protected: - bool writeVariablePrecision(TPrecision precision) override; + protected: + bool writeVariablePrecision(TPrecision precision) override; -private: + private: bool mForceHighp; }; +} // namespace sh + #endif // COMPILER_TRANSLATOR_OUTPUTESSL_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/OutputGLSL.cpp b/src/3rdparty/angle/src/compiler/translator/OutputGLSL.cpp index 431425020a..1bad05dab9 100644 --- a/src/3rdparty/angle/src/compiler/translator/OutputGLSL.cpp +++ b/src/3rdparty/angle/src/compiler/translator/OutputGLSL.cpp @@ -6,20 +6,29 @@ #include "compiler/translator/OutputGLSL.h" -TOutputGLSL::TOutputGLSL(TInfoSinkBase& objSink, +#include "compiler/translator/Compiler.h" + +namespace sh +{ + +TOutputGLSL::TOutputGLSL(TInfoSinkBase &objSink, ShArrayIndexClampingStrategy clampingStrategy, ShHashFunction64 hashFunction, - NameMap& nameMap, - TSymbolTable& symbolTable, + NameMap &nameMap, + TSymbolTable *symbolTable, + sh::GLenum shaderType, int shaderVersion, - ShShaderOutput output) + ShShaderOutput output, + ShCompileOptions compileOptions) : TOutputGLSLBase(objSink, clampingStrategy, hashFunction, nameMap, symbolTable, + shaderType, shaderVersion, - output) + output, + compileOptions) { } @@ -30,18 +39,18 @@ bool TOutputGLSL::writeVariablePrecision(TPrecision) void TOutputGLSL::visitSymbol(TIntermSymbol *node) { - TInfoSinkBase& out = objSink(); + TInfoSinkBase &out = objSink(); const TString &symbol = node->getSymbol(); if (symbol == "gl_FragDepthEXT") { out << "gl_FragDepth"; } - else if (symbol == "gl_FragColor" && IsGLSL130OrNewer(getShaderOutput())) + else if (symbol == "gl_FragColor" && sh::IsGLSL130OrNewer(getShaderOutput())) { out << "webgl_FragColor"; } - else if (symbol == "gl_FragData" && IsGLSL130OrNewer(getShaderOutput())) + else if (symbol == "gl_FragData" && sh::IsGLSL130OrNewer(getShaderOutput())) { out << "webgl_FragData"; } @@ -59,44 +68,43 @@ void TOutputGLSL::visitSymbol(TIntermSymbol *node) } } -TString TOutputGLSL::translateTextureFunction(TString &name) +TString TOutputGLSL::translateTextureFunction(const TString &name) { - static const char *simpleRename[] = { - "texture2DLodEXT", "texture2DLod", - "texture2DProjLodEXT", "texture2DProjLod", - "textureCubeLodEXT", "textureCubeLod", - "texture2DGradEXT", "texture2DGradARB", - "texture2DProjGradEXT", "texture2DProjGradARB", - "textureCubeGradEXT", "textureCubeGradARB", - NULL, NULL - }; + static const char *simpleRename[] = {"texture2DLodEXT", + "texture2DLod", + "texture2DProjLodEXT", + "texture2DProjLod", + "textureCubeLodEXT", + "textureCubeLod", + "texture2DGradEXT", + "texture2DGradARB", + "texture2DProjGradEXT", + "texture2DProjGradARB", + "textureCubeGradEXT", + "textureCubeGradARB", + nullptr, + nullptr}; static const char *legacyToCoreRename[] = { - "texture2D", "texture", - "texture2DProj", "textureProj", - "texture2DLod", "textureLod", - "texture2DProjLod", "textureProjLod", - "texture2DRect", "texture", - "textureCube", "texture", + "texture2D", "texture", "texture2DProj", "textureProj", "texture2DLod", "textureLod", + "texture2DProjLod", "textureProjLod", "texture2DRect", "texture", "textureCube", "texture", "textureCubeLod", "textureLod", // Extensions - "texture2DLodEXT", "textureLod", - "texture2DProjLodEXT", "textureProjLod", - "textureCubeLodEXT", "textureLod", - "texture2DGradEXT", "textureGrad", - "texture2DProjGradEXT", "textureProjGrad", - "textureCubeGradEXT", "textureGrad", - NULL, NULL - }; - const char **mapping = (IsGLSL130OrNewer(getShaderOutput())) ? - legacyToCoreRename : simpleRename; + "texture2DLodEXT", "textureLod", "texture2DProjLodEXT", "textureProjLod", + "textureCubeLodEXT", "textureLod", "texture2DGradEXT", "textureGrad", + "texture2DProjGradEXT", "textureProjGrad", "textureCubeGradEXT", "textureGrad", nullptr, + nullptr}; + const char **mapping = + (sh::IsGLSL130OrNewer(getShaderOutput())) ? legacyToCoreRename : simpleRename; - for (int i = 0; mapping[i] != NULL; i += 2) + for (int i = 0; mapping[i] != nullptr; i += 2) { if (name == mapping[i]) { - return mapping[i+1]; + return mapping[i + 1]; } } return name; } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/OutputGLSL.h b/src/3rdparty/angle/src/compiler/translator/OutputGLSL.h index 9b1aca4eab..c80abec1a6 100644 --- a/src/3rdparty/angle/src/compiler/translator/OutputGLSL.h +++ b/src/3rdparty/angle/src/compiler/translator/OutputGLSL.h @@ -9,21 +9,28 @@ #include "compiler/translator/OutputGLSLBase.h" +namespace sh +{ + class TOutputGLSL : public TOutputGLSLBase { public: - TOutputGLSL(TInfoSinkBase& objSink, + TOutputGLSL(TInfoSinkBase &objSink, ShArrayIndexClampingStrategy clampingStrategy, ShHashFunction64 hashFunction, - NameMap& nameMap, - TSymbolTable& symbolTable, + NameMap &nameMap, + TSymbolTable *symbolTable, + sh::GLenum shaderType, int shaderVersion, - ShShaderOutput output); + ShShaderOutput output, + ShCompileOptions compileOptions); protected: bool writeVariablePrecision(TPrecision) override; void visitSymbol(TIntermSymbol *node) override; - TString translateTextureFunction(TString &name) override; + TString translateTextureFunction(const TString &name) override; }; +} // namespace sh + #endif // COMPILER_TRANSLATOR_OUTPUTGLSL_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp b/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp index f048b050b7..edaf2ebebf 100644 --- a/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp +++ b/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.cpp @@ -6,32 +6,33 @@ #include "compiler/translator/OutputGLSLBase.h" +#include "angle_gl.h" #include "common/debug.h" +#include "common/mathutil.h" +#include "compiler/translator/Compiler.h" +#include "compiler/translator/util.h" #include +namespace sh +{ + namespace { -TString arrayBrackets(const TType &type) -{ - ASSERT(type.isArray()); - TInfoSinkBase out; - out << "[" << type.getArraySize() << "]"; - return TString(out.c_str()); -} bool isSingleStatement(TIntermNode *node) { - if (const TIntermAggregate *aggregate = node->getAsAggregate()) + if (node->getAsFunctionDefinition()) { - return (aggregate->getOp() != EOpFunction) && - (aggregate->getOp() != EOpSequence); + return false; } - else if (const TIntermSelection *selection = node->getAsSelectionNode()) + else if (node->getAsBlock()) { - // Ternary operators are usually part of an assignment operator. - // This handles those rare cases in which they are all by themselves. - return selection->usesTernaryOperator(); + return false; + } + else if (node->getAsIfElseNode()) + { + return false; } else if (node->getAsLoopNode()) { @@ -48,29 +49,79 @@ bool isSingleStatement(TIntermNode *node) return true; } +class CommaSeparatedListItemPrefixGenerator +{ + public: + CommaSeparatedListItemPrefixGenerator() : mFirst(true) {} + private: + bool mFirst; + + friend TInfoSinkBase &operator<<(TInfoSinkBase &out, + CommaSeparatedListItemPrefixGenerator &gen); +}; + +TInfoSinkBase &operator<<(TInfoSinkBase &out, CommaSeparatedListItemPrefixGenerator &gen) +{ + if (gen.mFirst) + { + gen.mFirst = false; + } + else + { + out << ", "; + } + return out; +} + } // namespace TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase &objSink, ShArrayIndexClampingStrategy clampingStrategy, ShHashFunction64 hashFunction, NameMap &nameMap, - TSymbolTable &symbolTable, + TSymbolTable *symbolTable, + sh::GLenum shaderType, int shaderVersion, - ShShaderOutput output) - : TIntermTraverser(true, true, true), + ShShaderOutput output, + ShCompileOptions compileOptions) + : TIntermTraverser(true, true, true, symbolTable), mObjSink(objSink), - mDeclaringVariables(false), + mDeclaringVariable(false), mClampingStrategy(clampingStrategy), mHashFunction(hashFunction), mNameMap(nameMap), - mSymbolTable(symbolTable), + mShaderType(shaderType), mShaderVersion(shaderVersion), - mOutput(output) + mOutput(output), + mCompileOptions(compileOptions) { } -void TOutputGLSLBase::writeTriplet( - Visit visit, const char *preStr, const char *inStr, const char *postStr) +void TOutputGLSLBase::writeInvariantQualifier(const TType &type) +{ + if (!sh::RemoveInvariant(mShaderType, mShaderVersion, mOutput, mCompileOptions)) + { + TInfoSinkBase &out = objSink(); + out << "invariant "; + } +} + +void TOutputGLSLBase::writeFloat(TInfoSinkBase &out, float f) +{ + if ((gl::isInf(f) || gl::isNaN(f)) && mShaderVersion >= 300) + { + out << "uintBitsToFloat(" << gl::bitCast(f) << "u)"; + } + else + { + out << std::min(FLT_MAX, std::max(-FLT_MAX, f)); + } +} + +void TOutputGLSLBase::writeTriplet(Visit visit, + const char *preStr, + const char *inStr, + const char *postStr) { TInfoSinkBase &out = objSink(); if (visit == PreVisit && preStr) @@ -81,69 +132,181 @@ void TOutputGLSLBase::writeTriplet( out << postStr; } -void TOutputGLSLBase::writeBuiltInFunctionTriplet( - Visit visit, const char *preStr, bool useEmulatedFunction) +void TOutputGLSLBase::writeBuiltInFunctionTriplet(Visit visit, + TOperator op, + bool useEmulatedFunction) { - TString preString = useEmulatedFunction ? - BuiltInFunctionEmulator::GetEmulatedFunctionName(preStr) : preStr; - writeTriplet(visit, preString.c_str(), ", ", ")"); + TInfoSinkBase &out = objSink(); + if (visit == PreVisit) + { + const char *opStr(GetOperatorString(op)); + if (useEmulatedFunction) + { + BuiltInFunctionEmulator::WriteEmulatedFunctionName(out, opStr); + } + else + { + out << opStr; + } + out << "("; + } + else + { + writeTriplet(visit, nullptr, ", ", ")"); + } } -void TOutputGLSLBase::writeLayoutQualifier(const TType &type) +void TOutputGLSLBase::writeLayoutQualifier(TIntermTyped *variable) { - if (type.getQualifier() == EvqFragmentOut || type.getQualifier() == EvqVertexIn) + const TType &type = variable->getType(); + + if (!NeedsToWriteLayoutQualifier(type)) + { + return; + } + + TInfoSinkBase &out = objSink(); + const TLayoutQualifier &layoutQualifier = type.getLayoutQualifier(); + out << "layout("; + + CommaSeparatedListItemPrefixGenerator listItemPrefix; + + if (type.getQualifier() == EvqFragmentOut || type.getQualifier() == EvqVertexIn || + IsVarying(type.getQualifier())) { - const TLayoutQualifier &layoutQualifier = type.getLayoutQualifier(); if (layoutQualifier.location >= 0) { - TInfoSinkBase &out = objSink(); - out << "layout(location = " << layoutQualifier.location << ") "; + out << listItemPrefix << "location = " << layoutQualifier.location; } } + + if (type.getQualifier() == EvqFragmentOut) + { + if (layoutQualifier.yuv == true) + { + out << listItemPrefix << "yuv"; + } + } + + if (IsOpaqueType(type.getBasicType())) + { + if (layoutQualifier.binding >= 0) + { + out << listItemPrefix << "binding = " << layoutQualifier.binding; + } + } + + if (IsImage(type.getBasicType())) + { + if (layoutQualifier.imageInternalFormat != EiifUnspecified) + { + ASSERT(type.getQualifier() == EvqTemporary || type.getQualifier() == EvqUniform); + out << listItemPrefix + << getImageInternalFormatString(layoutQualifier.imageInternalFormat); + } + } + + if (IsAtomicCounter(type.getBasicType())) + { + out << listItemPrefix << "offset = " << layoutQualifier.offset; + } + + out << ") "; +} + +const char *TOutputGLSLBase::mapQualifierToString(TQualifier qualifier) +{ + if (sh::IsGLSL410OrOlder(mOutput) && mShaderVersion >= 300 && + (mCompileOptions & SH_REMOVE_INVARIANT_AND_CENTROID_FOR_ESSL3) != 0) + { + switch (qualifier) + { + // The return string is consistent with sh::getQualifierString() from + // BaseTypes.h minus the "centroid" keyword. + case EvqCentroid: + return ""; + case EvqCentroidIn: + return "smooth in"; + case EvqCentroidOut: + return "smooth out"; + default: + break; + } + } + if (sh::IsGLSL130OrNewer(mOutput)) + { + switch (qualifier) + { + case EvqAttribute: + return "in"; + case EvqVaryingIn: + return "in"; + case EvqVaryingOut: + return "out"; + default: + break; + } + } + return sh::getQualifierString(qualifier); } void TOutputGLSLBase::writeVariableType(const TType &type) { - TInfoSinkBase &out = objSink(); + TQualifier qualifier = type.getQualifier(); + TInfoSinkBase &out = objSink(); if (type.isInvariant()) { - out << "invariant "; + writeInvariantQualifier(type); } if (type.getBasicType() == EbtInterfaceBlock) { TInterfaceBlock *interfaceBlock = type.getInterfaceBlock(); declareInterfaceBlockLayout(interfaceBlock); } - TQualifier qualifier = type.getQualifier(); if (qualifier != EvqTemporary && qualifier != EvqGlobal) { - if (IsGLSL130OrNewer(mOutput)) + const char *qualifierString = mapQualifierToString(qualifier); + if (qualifierString && qualifierString[0] != '\0') { - switch (qualifier) - { - case EvqAttribute: - out << "in "; - break; - case EvqVaryingIn: - out << "in "; - break; - case EvqVaryingOut: - out << "out "; - break; - default: - out << type.getQualifierString() << " "; - break; - } - } - else - { - out << type.getQualifierString() << " "; + out << qualifierString << " "; } } + + const TMemoryQualifier &memoryQualifier = type.getMemoryQualifier(); + if (memoryQualifier.readonly) + { + ASSERT(IsImage(type.getBasicType())); + out << "readonly "; + } + + if (memoryQualifier.writeonly) + { + ASSERT(IsImage(type.getBasicType())); + out << "writeonly "; + } + + if (memoryQualifier.coherent) + { + ASSERT(IsImage(type.getBasicType())); + out << "coherent "; + } + + if (memoryQualifier.restrictQualifier) + { + ASSERT(IsImage(type.getBasicType())); + out << "restrict "; + } + + if (memoryQualifier.volatileQualifier) + { + ASSERT(IsImage(type.getBasicType())); + out << "volatile "; + } + // Declare the struct if we have not done so already. if (type.getBasicType() == EbtStruct && !structDeclared(type.getStruct())) { - TStructure *structure = type.getStruct(); + const TStructure *structure = type.getStruct(); declareStruct(structure); @@ -168,20 +331,18 @@ void TOutputGLSLBase::writeVariableType(const TType &type) void TOutputGLSLBase::writeFunctionParameters(const TIntermSequence &args) { TInfoSinkBase &out = objSink(); - for (TIntermSequence::const_iterator iter = args.begin(); - iter != args.end(); ++iter) + for (TIntermSequence::const_iterator iter = args.begin(); iter != args.end(); ++iter) { const TIntermSymbol *arg = (*iter)->getAsSymbolNode(); - ASSERT(arg != NULL); + ASSERT(arg != nullptr); const TType &type = arg->getType(); writeVariableType(type); - const TString &name = arg->getSymbol(); - if (!name.empty()) - out << " " << hashName(name); + if (!arg->getName().getString().empty()) + out << " " << hashName(arg->getName()); if (type.isArray()) - out << arrayBrackets(type); + out << ArrayString(type); // Put a comma if this is not the last argument. if (iter != args.end() - 1) @@ -189,21 +350,21 @@ void TOutputGLSLBase::writeFunctionParameters(const TIntermSequence &args) } } -const TConstantUnion *TOutputGLSLBase::writeConstantUnion( - const TType &type, const TConstantUnion *pConstUnion) +const TConstantUnion *TOutputGLSLBase::writeConstantUnion(const TType &type, + const TConstantUnion *pConstUnion) { TInfoSinkBase &out = objSink(); if (type.getBasicType() == EbtStruct) { const TStructure *structure = type.getStruct(); - out << hashName(structure->name()) << "("; + out << hashName(TName(structure->name())) << "("; const TFieldList &fields = structure->fields(); for (size_t i = 0; i < fields.size(); ++i) { const TType *fieldType = fields[i]->type(); - ASSERT(fieldType != NULL); + ASSERT(fieldType != nullptr); pConstUnion = writeConstantUnion(*fieldType, pConstUnion); if (i != fields.size() - 1) out << ", "; @@ -212,7 +373,7 @@ const TConstantUnion *TOutputGLSLBase::writeConstantUnion( } else { - size_t size = type.getObjectSize(); + size_t size = type.getObjectSize(); bool writeType = size > 1; if (writeType) out << getTypeName(type) << "("; @@ -220,19 +381,23 @@ const TConstantUnion *TOutputGLSLBase::writeConstantUnion( { switch (pConstUnion->getType()) { - case EbtFloat: - out << std::min(FLT_MAX, std::max(-FLT_MAX, pConstUnion->getFConst())); - break; - case EbtInt: - out << pConstUnion->getIConst(); - break; - case EbtUInt: - out << pConstUnion->getUConst() << "u"; - break; - case EbtBool: - out << pConstUnion->getBConst(); - break; - default: UNREACHABLE(); + case EbtFloat: + writeFloat(out, pConstUnion->getFConst()); + break; + case EbtInt: + out << pConstUnion->getIConst(); + break; + case EbtUInt: + out << pConstUnion->getUConst() << "u"; + break; + case EbtBool: + out << pConstUnion->getBConst(); + break; + case EbtYuvCscStandardEXT: + out << getYuvCscStandardEXTString(pConstUnion->getYuvCscStandardEXTConst()); + break; + default: + UNREACHABLE(); } if (i != size - 1) out << ", "; @@ -243,20 +408,20 @@ const TConstantUnion *TOutputGLSLBase::writeConstantUnion( return pConstUnion; } -void TOutputGLSLBase::writeConstructorTriplet(Visit visit, const TType &type, const char *constructorBaseType) +void TOutputGLSLBase::writeConstructorTriplet(Visit visit, const TType &type) { TInfoSinkBase &out = objSink(); if (visit == PreVisit) { if (type.isArray()) { - out << constructorBaseType; - out << arrayBrackets(type); + out << getTypeName(type); + out << ArrayString(type); out << "("; } else { - out << constructorBaseType << "("; + out << getTypeName(type) << "("; } } else @@ -268,13 +433,10 @@ void TOutputGLSLBase::writeConstructorTriplet(Visit visit, const TType &type, co void TOutputGLSLBase::visitSymbol(TIntermSymbol *node) { TInfoSinkBase &out = objSink(); - if (mLoopUnrollStack.needsToReplaceSymbolWithValue(node)) - out << mLoopUnrollStack.getLoopIndexValue(node); - else - out << hashVariableName(node->getSymbol()); + out << hashVariableName(node->getName()); - if (mDeclaringVariables && node->getType().isArray()) - out << arrayBrackets(node->getType()); + if (mDeclaringVariable && node->getType().isArray()) + out << ArrayString(node->getType()); } void TOutputGLSLBase::visitConstantUnion(TIntermConstantUnion *node) @@ -282,241 +444,246 @@ void TOutputGLSLBase::visitConstantUnion(TIntermConstantUnion *node) writeConstantUnion(node->getType(), node->getUnionArrayPointer()); } +bool TOutputGLSLBase::visitSwizzle(Visit visit, TIntermSwizzle *node) +{ + TInfoSinkBase &out = objSink(); + if (visit == PostVisit) + { + out << "."; + node->writeOffsetsAsXYZW(&out); + } + return true; +} + bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary *node) { bool visitChildren = true; TInfoSinkBase &out = objSink(); switch (node->getOp()) { - case EOpInitialize: - if (visit == InVisit) - { - out << " = "; - // RHS of initialize is not being declared. - mDeclaringVariables = false; - } - break; - case EOpAssign: - writeTriplet(visit, "(", " = ", ")"); - break; - case EOpAddAssign: - writeTriplet(visit, "(", " += ", ")"); - break; - case EOpSubAssign: - writeTriplet(visit, "(", " -= ", ")"); - break; - case EOpDivAssign: - writeTriplet(visit, "(", " /= ", ")"); - break; - case EOpIModAssign: - writeTriplet(visit, "(", " %= ", ")"); - break; - // Notice the fall-through. - case EOpMulAssign: - case EOpVectorTimesMatrixAssign: - case EOpVectorTimesScalarAssign: - case EOpMatrixTimesScalarAssign: - case EOpMatrixTimesMatrixAssign: - writeTriplet(visit, "(", " *= ", ")"); - break; - case EOpBitShiftLeftAssign: - writeTriplet(visit, "(", " <<= ", ")"); - break; - case EOpBitShiftRightAssign: - writeTriplet(visit, "(", " >>= ", ")"); - break; - case EOpBitwiseAndAssign: - writeTriplet(visit, "(", " &= ", ")"); - break; - case EOpBitwiseXorAssign: - writeTriplet(visit, "(", " ^= ", ")"); - break; - case EOpBitwiseOrAssign: - writeTriplet(visit, "(", " |= ", ")"); - break; - - case EOpIndexDirect: - writeTriplet(visit, NULL, "[", "]"); - break; - case EOpIndexIndirect: - if (node->getAddIndexClamp()) - { + case EOpComma: + writeTriplet(visit, "(", ", ", ")"); + break; + case EOpInitialize: if (visit == InVisit) { - if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC) - out << "[int(clamp(float("; - else - out << "[webgl_int_clamp("; + out << " = "; + // RHS of initialize is not being declared. + mDeclaringVariable = false; } - else if (visit == PostVisit) + break; + case EOpAssign: + writeTriplet(visit, "(", " = ", ")"); + break; + case EOpAddAssign: + writeTriplet(visit, "(", " += ", ")"); + break; + case EOpSubAssign: + writeTriplet(visit, "(", " -= ", ")"); + break; + case EOpDivAssign: + writeTriplet(visit, "(", " /= ", ")"); + break; + case EOpIModAssign: + writeTriplet(visit, "(", " %= ", ")"); + break; + // Notice the fall-through. + case EOpMulAssign: + case EOpVectorTimesMatrixAssign: + case EOpVectorTimesScalarAssign: + case EOpMatrixTimesScalarAssign: + case EOpMatrixTimesMatrixAssign: + writeTriplet(visit, "(", " *= ", ")"); + break; + case EOpBitShiftLeftAssign: + writeTriplet(visit, "(", " <<= ", ")"); + break; + case EOpBitShiftRightAssign: + writeTriplet(visit, "(", " >>= ", ")"); + break; + case EOpBitwiseAndAssign: + writeTriplet(visit, "(", " &= ", ")"); + break; + case EOpBitwiseXorAssign: + writeTriplet(visit, "(", " ^= ", ")"); + break; + case EOpBitwiseOrAssign: + writeTriplet(visit, "(", " |= ", ")"); + break; + + case EOpIndexDirect: + writeTriplet(visit, nullptr, "[", "]"); + break; + case EOpIndexIndirect: + if (node->getAddIndexClamp()) { - int maxSize; - TIntermTyped *left = node->getLeft(); - TType leftType = left->getType(); - - if (left->isArray()) + if (visit == InVisit) { - // The shader will fail validation if the array length is not > 0. - maxSize = leftType.getArraySize() - 1; + if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC) + out << "[int(clamp(float("; + else + out << "[webgl_int_clamp("; } - else + else if (visit == PostVisit) { - maxSize = leftType.getNominalSize() - 1; - } + TIntermTyped *left = node->getLeft(); + TType leftType = left->getType(); - if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC) - out << "), 0.0, float(" << maxSize << ")))]"; - else - out << ", 0, " << maxSize << ")]"; + if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC) + out << "), 0.0, float("; + else + out << ", 0, "; + + if (leftType.isUnsizedArray()) + { + // For runtime-sized arrays in ESSL 3.10 we need to call the length method + // to get the length to clamp against. See ESSL 3.10 section 4.1.9. Note + // that a runtime-sized array expression is guaranteed not to have side + // effects, so it's fine to add the expression to the output twice. + ASSERT(mShaderVersion >= 310); + ASSERT(!left->hasSideEffects()); + left->traverse(this); + out << ".length() - 1"; + } + else + { + int maxSize; + if (leftType.isArray()) + { + maxSize = static_cast(leftType.getOutermostArraySize()) - 1; + } + else + { + maxSize = leftType.getNominalSize() - 1; + } + out << maxSize; + } + if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC) + out << ")))]"; + else + out << ")]"; + } } - } - else - { - writeTriplet(visit, NULL, "[", "]"); - } - break; - case EOpIndexDirectStruct: - if (visit == InVisit) - { - // Here we are writing out "foo.bar", where "foo" is struct - // and "bar" is field. In AST, it is represented as a binary - // node, where left child represents "foo" and right child "bar". - // The node itself represents ".". The struct field "bar" is - // actually stored as an index into TStructure::fields. - out << "."; - const TStructure *structure = node->getLeft()->getType().getStruct(); - const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion(); - const TField *field = structure->fields()[index->getIConst(0)]; - - TString fieldName = field->name(); - if (!mSymbolTable.findBuiltIn(structure->name(), mShaderVersion)) - fieldName = hashName(fieldName); - - out << fieldName; - visitChildren = false; - } - break; - case EOpIndexDirectInterfaceBlock: - if (visit == InVisit) - { - out << "."; - const TInterfaceBlock *interfaceBlock = node->getLeft()->getType().getInterfaceBlock(); - const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion(); - const TField *field = interfaceBlock->fields()[index->getIConst(0)]; - - TString fieldName = field->name(); - ASSERT(!mSymbolTable.findBuiltIn(interfaceBlock->name(), mShaderVersion)); - fieldName = hashName(fieldName); - - out << fieldName; - visitChildren = false; - } - break; - case EOpVectorSwizzle: - if (visit == InVisit) - { - out << "."; - TIntermAggregate *rightChild = node->getRight()->getAsAggregate(); - TIntermSequence *sequence = rightChild->getSequence(); - for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); ++sit) + else { - TIntermConstantUnion *element = (*sit)->getAsConstantUnion(); - ASSERT(element->getBasicType() == EbtInt); - ASSERT(element->getNominalSize() == 1); - const TConstantUnion& data = element->getUnionArrayPointer()[0]; - ASSERT(data.getType() == EbtInt); - switch (data.getIConst()) - { - case 0: - out << "x"; - break; - case 1: - out << "y"; - break; - case 2: - out << "z"; - break; - case 3: - out << "w"; - break; - default: - UNREACHABLE(); - } + writeTriplet(visit, nullptr, "[", "]"); } - visitChildren = false; - } - break; + break; + case EOpIndexDirectStruct: + if (visit == InVisit) + { + // Here we are writing out "foo.bar", where "foo" is struct + // and "bar" is field. In AST, it is represented as a binary + // node, where left child represents "foo" and right child "bar". + // The node itself represents ".". The struct field "bar" is + // actually stored as an index into TStructure::fields. + out << "."; + const TStructure *structure = node->getLeft()->getType().getStruct(); + const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion(); + const TField *field = structure->fields()[index->getIConst(0)]; - case EOpAdd: - writeTriplet(visit, "(", " + ", ")"); - break; - case EOpSub: - writeTriplet(visit, "(", " - ", ")"); - break; - case EOpMul: - writeTriplet(visit, "(", " * ", ")"); - break; - case EOpDiv: - writeTriplet(visit, "(", " / ", ")"); - break; - case EOpIMod: - writeTriplet(visit, "(", " % ", ")"); - break; - case EOpBitShiftLeft: - writeTriplet(visit, "(", " << ", ")"); - break; - case EOpBitShiftRight: - writeTriplet(visit, "(", " >> ", ")"); - break; - case EOpBitwiseAnd: - writeTriplet(visit, "(", " & ", ")"); - break; - case EOpBitwiseXor: - writeTriplet(visit, "(", " ^ ", ")"); - break; - case EOpBitwiseOr: - writeTriplet(visit, "(", " | ", ")"); - break; + TString fieldName = field->name(); + if (!mSymbolTable->findBuiltIn(structure->name(), mShaderVersion)) + fieldName = hashName(TName(fieldName)); - case EOpEqual: - writeTriplet(visit, "(", " == ", ")"); - break; - case EOpNotEqual: - writeTriplet(visit, "(", " != ", ")"); - break; - case EOpLessThan: - writeTriplet(visit, "(", " < ", ")"); - break; - case EOpGreaterThan: - writeTriplet(visit, "(", " > ", ")"); - break; - case EOpLessThanEqual: - writeTriplet(visit, "(", " <= ", ")"); - break; - case EOpGreaterThanEqual: - writeTriplet(visit, "(", " >= ", ")"); - break; + out << fieldName; + visitChildren = false; + } + break; + case EOpIndexDirectInterfaceBlock: + if (visit == InVisit) + { + out << "."; + const TInterfaceBlock *interfaceBlock = + node->getLeft()->getType().getInterfaceBlock(); + const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion(); + const TField *field = interfaceBlock->fields()[index->getIConst(0)]; - // Notice the fall-through. - case EOpVectorTimesScalar: - case EOpVectorTimesMatrix: - case EOpMatrixTimesVector: - case EOpMatrixTimesScalar: - case EOpMatrixTimesMatrix: - writeTriplet(visit, "(", " * ", ")"); - break; + TString fieldName = field->name(); + if (!mSymbolTable->findBuiltIn(interfaceBlock->name(), mShaderVersion)) + { + fieldName = hashName(TName(fieldName)); + } + else + { + ASSERT(interfaceBlock->name() == "gl_PerVertex"); + } - case EOpLogicalOr: - writeTriplet(visit, "(", " || ", ")"); - break; - case EOpLogicalXor: - writeTriplet(visit, "(", " ^^ ", ")"); - break; - case EOpLogicalAnd: - writeTriplet(visit, "(", " && ", ")"); - break; - default: - UNREACHABLE(); + out << fieldName; + visitChildren = false; + } + break; + + case EOpAdd: + writeTriplet(visit, "(", " + ", ")"); + break; + case EOpSub: + writeTriplet(visit, "(", " - ", ")"); + break; + case EOpMul: + writeTriplet(visit, "(", " * ", ")"); + break; + case EOpDiv: + writeTriplet(visit, "(", " / ", ")"); + break; + case EOpIMod: + writeTriplet(visit, "(", " % ", ")"); + break; + case EOpBitShiftLeft: + writeTriplet(visit, "(", " << ", ")"); + break; + case EOpBitShiftRight: + writeTriplet(visit, "(", " >> ", ")"); + break; + case EOpBitwiseAnd: + writeTriplet(visit, "(", " & ", ")"); + break; + case EOpBitwiseXor: + writeTriplet(visit, "(", " ^ ", ")"); + break; + case EOpBitwiseOr: + writeTriplet(visit, "(", " | ", ")"); + break; + + case EOpEqual: + writeTriplet(visit, "(", " == ", ")"); + break; + case EOpNotEqual: + writeTriplet(visit, "(", " != ", ")"); + break; + case EOpLessThan: + writeTriplet(visit, "(", " < ", ")"); + break; + case EOpGreaterThan: + writeTriplet(visit, "(", " > ", ")"); + break; + case EOpLessThanEqual: + writeTriplet(visit, "(", " <= ", ")"); + break; + case EOpGreaterThanEqual: + writeTriplet(visit, "(", " >= ", ")"); + break; + + // Notice the fall-through. + case EOpVectorTimesScalar: + case EOpVectorTimesMatrix: + case EOpMatrixTimesVector: + case EOpMatrixTimesScalar: + case EOpMatrixTimesMatrix: + writeTriplet(visit, "(", " * ", ")"); + break; + + case EOpLogicalOr: + writeTriplet(visit, "(", " || ", ")"); + break; + case EOpLogicalXor: + writeTriplet(visit, "(", " ^^ ", ")"); + break; + case EOpLogicalAnd: + writeTriplet(visit, "(", " && ", ")"); + break; + default: + UNREACHABLE(); } return visitChildren; @@ -529,237 +696,148 @@ bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary *node) switch (node->getOp()) { - case EOpNegative: preString = "(-"; break; - case EOpPositive: preString = "(+"; break; - case EOpVectorLogicalNot: preString = "not("; break; - case EOpLogicalNot: preString = "(!"; break; - case EOpBitwiseNot: preString = "(~"; break; + case EOpNegative: + preString = "(-"; + break; + case EOpPositive: + preString = "(+"; + break; + case EOpLogicalNot: + preString = "(!"; + break; + case EOpBitwiseNot: + preString = "(~"; + break; - case EOpPostIncrement: preString = "("; postString = "++)"; break; - case EOpPostDecrement: preString = "("; postString = "--)"; break; - case EOpPreIncrement: preString = "(++"; break; - case EOpPreDecrement: preString = "(--"; break; + case EOpPostIncrement: + preString = "("; + postString = "++)"; + break; + case EOpPostDecrement: + preString = "("; + postString = "--)"; + break; + case EOpPreIncrement: + preString = "(++"; + break; + case EOpPreDecrement: + preString = "(--"; + break; + case EOpArrayLength: + preString = "(("; + postString = ").length())"; + break; - case EOpRadians: - preString = "radians("; - break; - case EOpDegrees: - preString = "degrees("; - break; - case EOpSin: - preString = "sin("; - break; - case EOpCos: - preString = "cos("; - break; - case EOpTan: - preString = "tan("; - break; - case EOpAsin: - preString = "asin("; - break; - case EOpAcos: - preString = "acos("; - break; - case EOpAtan: - preString = "atan("; - break; - - case EOpSinh: - preString = "sinh("; - break; - case EOpCosh: - preString = "cosh("; - break; - case EOpTanh: - preString = "tanh("; - break; - case EOpAsinh: - preString = "asinh("; - break; - case EOpAcosh: - preString = "acosh("; - break; - case EOpAtanh: - preString = "atanh("; - break; - - case EOpExp: - preString = "exp("; - break; - case EOpLog: - preString = "log("; - break; - case EOpExp2: - preString = "exp2("; - break; - case EOpLog2: - preString = "log2("; - break; - case EOpSqrt: - preString = "sqrt("; - break; - case EOpInverseSqrt: - preString = "inversesqrt("; - break; - - case EOpAbs: - preString = "abs("; - break; - case EOpSign: - preString = "sign("; - break; - case EOpFloor: - preString = "floor("; - break; - case EOpTrunc: - preString = "trunc("; - break; - case EOpRound: - preString = "round("; - break; - case EOpRoundEven: - preString = "roundEven("; - break; - case EOpCeil: - preString = "ceil("; - break; - case EOpFract: - preString = "fract("; - break; - case EOpIsNan: - preString = "isnan("; - break; - case EOpIsInf: - preString = "isinf("; - break; - - case EOpFloatBitsToInt: - preString = "floatBitsToInt("; - break; - case EOpFloatBitsToUint: - preString = "floatBitsToUint("; - break; - case EOpIntBitsToFloat: - preString = "intBitsToFloat("; - break; - case EOpUintBitsToFloat: - preString = "uintBitsToFloat("; - break; - - case EOpPackSnorm2x16: - preString = "packSnorm2x16("; - break; - case EOpPackUnorm2x16: - preString = "packUnorm2x16("; - break; - case EOpPackHalf2x16: - preString = "packHalf2x16("; - break; - case EOpUnpackSnorm2x16: - preString = "unpackSnorm2x16("; - break; - case EOpUnpackUnorm2x16: - preString = "unpackUnorm2x16("; - break; - case EOpUnpackHalf2x16: - preString = "unpackHalf2x16("; - break; - - case EOpLength: - preString = "length("; - break; - case EOpNormalize: - preString = "normalize("; - break; - - case EOpDFdx: - preString = "dFdx("; - break; - case EOpDFdy: - preString = "dFdy("; - break; - case EOpFwidth: - preString = "fwidth("; - break; - - case EOpTranspose: - preString = "transpose("; - break; - case EOpDeterminant: - preString = "determinant("; - break; - case EOpInverse: - preString = "inverse("; - break; - - case EOpAny: - preString = "any("; - break; - case EOpAll: - preString = "all("; - break; - - default: - UNREACHABLE(); + case EOpRadians: + case EOpDegrees: + case EOpSin: + case EOpCos: + case EOpTan: + case EOpAsin: + case EOpAcos: + case EOpAtan: + case EOpSinh: + case EOpCosh: + case EOpTanh: + case EOpAsinh: + case EOpAcosh: + case EOpAtanh: + case EOpExp: + case EOpLog: + case EOpExp2: + case EOpLog2: + case EOpSqrt: + case EOpInverseSqrt: + case EOpAbs: + case EOpSign: + case EOpFloor: + case EOpTrunc: + case EOpRound: + case EOpRoundEven: + case EOpCeil: + case EOpFract: + case EOpIsNan: + case EOpIsInf: + case EOpFloatBitsToInt: + case EOpFloatBitsToUint: + case EOpIntBitsToFloat: + case EOpUintBitsToFloat: + case EOpPackSnorm2x16: + case EOpPackUnorm2x16: + case EOpPackHalf2x16: + case EOpUnpackSnorm2x16: + case EOpUnpackUnorm2x16: + case EOpUnpackHalf2x16: + case EOpPackUnorm4x8: + case EOpPackSnorm4x8: + case EOpUnpackUnorm4x8: + case EOpUnpackSnorm4x8: + case EOpLength: + case EOpNormalize: + case EOpDFdx: + case EOpDFdy: + case EOpFwidth: + case EOpTranspose: + case EOpDeterminant: + case EOpInverse: + case EOpAny: + case EOpAll: + case EOpLogicalNotComponentWise: + case EOpBitfieldReverse: + case EOpBitCount: + case EOpFindLSB: + case EOpFindMSB: + writeBuiltInFunctionTriplet(visit, node->getOp(), node->getUseEmulatedFunction()); + return true; + default: + UNREACHABLE(); } - if (visit == PreVisit && node->getUseEmulatedFunction()) - preString = BuiltInFunctionEmulator::GetEmulatedFunctionName(preString); - writeTriplet(visit, preString.c_str(), NULL, postString.c_str()); + writeTriplet(visit, preString.c_str(), nullptr, postString.c_str()); return true; } -bool TOutputGLSLBase::visitSelection(Visit visit, TIntermSelection *node) +bool TOutputGLSLBase::visitTernary(Visit visit, TIntermTernary *node) +{ + TInfoSinkBase &out = objSink(); + // Notice two brackets at the beginning and end. The outer ones + // encapsulate the whole ternary expression. This preserves the + // order of precedence when ternary expressions are used in a + // compound expression, i.e., c = 2 * (a < b ? 1 : 2). + out << "(("; + node->getCondition()->traverse(this); + out << ") ? ("; + node->getTrueExpression()->traverse(this); + out << ") : ("; + node->getFalseExpression()->traverse(this); + out << "))"; + return false; +} + +bool TOutputGLSLBase::visitIfElse(Visit visit, TIntermIfElse *node) { TInfoSinkBase &out = objSink(); - if (node->usesTernaryOperator()) - { - // Notice two brackets at the beginning and end. The outer ones - // encapsulate the whole ternary expression. This preserves the - // order of precedence when ternary expressions are used in a - // compound expression, i.e., c = 2 * (a < b ? 1 : 2). - out << "(("; - node->getCondition()->traverse(this); - out << ") ? ("; - node->getTrueBlock()->traverse(this); - out << ") : ("; - node->getFalseBlock()->traverse(this); - out << "))"; - } - else - { - out << "if ("; - node->getCondition()->traverse(this); - out << ")\n"; + out << "if ("; + node->getCondition()->traverse(this); + out << ")\n"; - incrementDepth(node); - visitCodeBlock(node->getTrueBlock()); + visitCodeBlock(node->getTrueBlock()); - if (node->getFalseBlock()) - { - out << "else\n"; - visitCodeBlock(node->getFalseBlock()); - } - decrementDepth(); + if (node->getFalseBlock()) + { + out << "else\n"; + visitCodeBlock(node->getFalseBlock()); } return false; } bool TOutputGLSLBase::visitSwitch(Visit visit, TIntermSwitch *node) { - if (node->getStatementList()) - { - writeTriplet(visit, "switch (", ") ", nullptr); - // The curly braces get written when visiting the statementList aggregate - } - else - { - // No statementList, so it won't output curly braces - writeTriplet(visit, "switch (", ") {", "}\n"); - } + ASSERT(node->getStatementList()); + writeTriplet(visit, "switch (", ") ", nullptr); + // The curly braces get written when visiting the statementList aggregate return true; } @@ -778,369 +856,208 @@ bool TOutputGLSLBase::visitCase(Visit visit, TIntermCase *node) } } +bool TOutputGLSLBase::visitBlock(Visit visit, TIntermBlock *node) +{ + TInfoSinkBase &out = objSink(); + // Scope the blocks except when at the global scope. + if (mDepth > 0) + { + out << "{\n"; + } + + for (TIntermSequence::const_iterator iter = node->getSequence()->begin(); + iter != node->getSequence()->end(); ++iter) + { + TIntermNode *curNode = *iter; + ASSERT(curNode != nullptr); + curNode->traverse(this); + + if (isSingleStatement(curNode)) + out << ";\n"; + } + + // Scope the blocks except when at the global scope. + if (mDepth > 0) + { + out << "}\n"; + } + return false; +} + +bool TOutputGLSLBase::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) +{ + TIntermFunctionPrototype *prototype = node->getFunctionPrototype(); + prototype->traverse(this); + visitCodeBlock(node->getBody()); + + // Fully processed; no need to visit children. + return false; +} + +bool TOutputGLSLBase::visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *node) +{ + TInfoSinkBase &out = objSink(); + ASSERT(visit == PreVisit); + const TIntermSymbol *symbol = node->getSymbol(); + out << "invariant " << hashVariableName(symbol->getName()); + return false; +} + +bool TOutputGLSLBase::visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *node) +{ + TInfoSinkBase &out = objSink(); + ASSERT(visit == PreVisit); + + const TType &type = node->getType(); + writeVariableType(type); + if (type.isArray()) + out << ArrayString(type); + + out << " " << hashFunctionNameIfNeeded(*node->getFunctionSymbolInfo()); + + out << "("; + writeFunctionParameters(*(node->getSequence())); + out << ")"; + + return false; +} + bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node) { - bool visitChildren = true; - TInfoSinkBase &out = objSink(); - bool useEmulatedFunction = (visit == PreVisit && node->getUseEmulatedFunction()); + bool visitChildren = true; + TInfoSinkBase &out = objSink(); switch (node->getOp()) { - case EOpSequence: - // Scope the sequences except when at the global scope. - if (mDepth > 0) - { - out << "{\n"; - } - - incrementDepth(node); - for (TIntermSequence::const_iterator iter = node->getSequence()->begin(); - iter != node->getSequence()->end(); ++iter) - { - TIntermNode *curNode = *iter; - ASSERT(curNode != NULL); - curNode->traverse(this); - - if (isSingleStatement(curNode)) - out << ";\n"; - } - decrementDepth(); - - // Scope the sequences except when at the global scope. - if (mDepth > 0) - { - out << "}\n"; - } - visitChildren = false; - break; - case EOpPrototype: - // Function declaration. - ASSERT(visit == PreVisit); - { - const TType &type = node->getType(); - writeVariableType(type); - if (type.isArray()) - out << arrayBrackets(type); - } - - out << " " << hashFunctionNameIfNeeded(node->getNameObj()); - - out << "("; - writeFunctionParameters(*(node->getSequence())); - out << ")"; - - visitChildren = false; - break; - case EOpFunction: { - // Function definition. - ASSERT(visit == PreVisit); - { - const TType &type = node->getType(); - writeVariableType(type); - if (type.isArray()) - out << arrayBrackets(type); - } - - out << " " << hashFunctionNameIfNeeded(node->getNameObj()); - - incrementDepth(node); - // Function definition node contains one or two children nodes - // representing function parameters and function body. The latter - // is not present in case of empty function bodies. - const TIntermSequence &sequence = *(node->getSequence()); - ASSERT((sequence.size() == 1) || (sequence.size() == 2)); - TIntermSequence::const_iterator seqIter = sequence.begin(); - - // Traverse function parameters. - TIntermAggregate *params = (*seqIter)->getAsAggregate(); - ASSERT(params != NULL); - ASSERT(params->getOp() == EOpParameters); - params->traverse(this); - - // Traverse function body. - TIntermAggregate *body = ++seqIter != sequence.end() ? - (*seqIter)->getAsAggregate() : NULL; - visitCodeBlock(body); - decrementDepth(); - - // Fully processed; no need to visit children. - visitChildren = false; - break; - } - case EOpFunctionCall: - // Function call. - if (visit == PreVisit) - out << hashFunctionNameIfNeeded(node->getNameObj()) << "("; - else if (visit == InVisit) - out << ", "; - else - out << ")"; - break; - case EOpParameters: - // Function parameters. - ASSERT(visit == PreVisit); - out << "("; - writeFunctionParameters(*(node->getSequence())); - out << ")"; - visitChildren = false; - break; - case EOpDeclaration: - // Variable declaration. - if (visit == PreVisit) - { - const TIntermSequence &sequence = *(node->getSequence()); - const TIntermTyped *variable = sequence.front()->getAsTyped(); - writeLayoutQualifier(variable->getType()); - writeVariableType(variable->getType()); - out << " "; - mDeclaringVariables = true; - } - else if (visit == InVisit) - { - out << ", "; - mDeclaringVariables = true; - } - else - { - mDeclaringVariables = false; - } - break; - case EOpInvariantDeclaration: - // Invariant declaration. - ASSERT(visit == PreVisit); - { - const TIntermSequence *sequence = node->getSequence(); - ASSERT(sequence && sequence->size() == 1); - const TIntermSymbol *symbol = sequence->front()->getAsSymbolNode(); - ASSERT(symbol); - out << "invariant " << hashVariableName(symbol->getSymbol()); - } - visitChildren = false; - break; - case EOpConstructFloat: - writeConstructorTriplet(visit, node->getType(), "float"); - break; - case EOpConstructVec2: - writeConstructorTriplet(visit, node->getType(), "vec2"); - break; - case EOpConstructVec3: - writeConstructorTriplet(visit, node->getType(), "vec3"); - break; - case EOpConstructVec4: - writeConstructorTriplet(visit, node->getType(), "vec4"); - break; - case EOpConstructBool: - writeConstructorTriplet(visit, node->getType(), "bool"); - break; - case EOpConstructBVec2: - writeConstructorTriplet(visit, node->getType(), "bvec2"); - break; - case EOpConstructBVec3: - writeConstructorTriplet(visit, node->getType(), "bvec3"); - break; - case EOpConstructBVec4: - writeConstructorTriplet(visit, node->getType(), "bvec4"); - break; - case EOpConstructInt: - writeConstructorTriplet(visit, node->getType(), "int"); - break; - case EOpConstructIVec2: - writeConstructorTriplet(visit, node->getType(), "ivec2"); - break; - case EOpConstructIVec3: - writeConstructorTriplet(visit, node->getType(), "ivec3"); - break; - case EOpConstructIVec4: - writeConstructorTriplet(visit, node->getType(), "ivec4"); - break; - case EOpConstructUInt: - writeConstructorTriplet(visit, node->getType(), "uint"); - break; - case EOpConstructUVec2: - writeConstructorTriplet(visit, node->getType(), "uvec2"); - break; - case EOpConstructUVec3: - writeConstructorTriplet(visit, node->getType(), "uvec3"); - break; - case EOpConstructUVec4: - writeConstructorTriplet(visit, node->getType(), "uvec4"); - break; - case EOpConstructMat2: - writeConstructorTriplet(visit, node->getType(), "mat2"); - break; - case EOpConstructMat2x3: - writeConstructorTriplet(visit, node->getType(), "mat2x3"); - break; - case EOpConstructMat2x4: - writeConstructorTriplet(visit, node->getType(), "mat2x4"); - break; - case EOpConstructMat3x2: - writeConstructorTriplet(visit, node->getType(), "mat3x2"); - break; - case EOpConstructMat3: - writeConstructorTriplet(visit, node->getType(), "mat3"); - break; - case EOpConstructMat3x4: - writeConstructorTriplet(visit, node->getType(), "mat3x4"); - break; - case EOpConstructMat4x2: - writeConstructorTriplet(visit, node->getType(), "mat4x2"); - break; - case EOpConstructMat4x3: - writeConstructorTriplet(visit, node->getType(), "mat4x3"); - break; - case EOpConstructMat4: - writeConstructorTriplet(visit, node->getType(), "mat4"); - break; - case EOpConstructStruct: - { - const TType &type = node->getType(); - ASSERT(type.getBasicType() == EbtStruct); - TString constructorName = hashName(type.getStruct()->name()); - writeConstructorTriplet(visit, node->getType(), constructorName.c_str()); + case EOpCallFunctionInAST: + case EOpCallInternalRawFunction: + case EOpCallBuiltInFunction: + // Function call. + if (visit == PreVisit) + { + if (node->getOp() == EOpCallBuiltInFunction) + { + out << translateTextureFunction(node->getFunctionSymbolInfo()->getName()); + } + else + { + out << hashFunctionNameIfNeeded(*node->getFunctionSymbolInfo()); + } + out << "("; + } + else if (visit == InVisit) + out << ", "; + else + out << ")"; + break; + case EOpConstruct: + writeConstructorTriplet(visit, node->getType()); break; - } - case EOpOuterProduct: - writeBuiltInFunctionTriplet(visit, "outerProduct(", useEmulatedFunction); - break; - - case EOpLessThan: - writeBuiltInFunctionTriplet(visit, "lessThan(", useEmulatedFunction); - break; - case EOpGreaterThan: - writeBuiltInFunctionTriplet(visit, "greaterThan(", useEmulatedFunction); - break; - case EOpLessThanEqual: - writeBuiltInFunctionTriplet(visit, "lessThanEqual(", useEmulatedFunction); - break; - case EOpGreaterThanEqual: - writeBuiltInFunctionTriplet(visit, "greaterThanEqual(", useEmulatedFunction); - break; - case EOpVectorEqual: - writeBuiltInFunctionTriplet(visit, "equal(", useEmulatedFunction); - break; - case EOpVectorNotEqual: - writeBuiltInFunctionTriplet(visit, "notEqual(", useEmulatedFunction); - break; - case EOpComma: - writeTriplet(visit, "(", ", ", ")"); - break; - - case EOpMod: - writeBuiltInFunctionTriplet(visit, "mod(", useEmulatedFunction); - break; - case EOpModf: - writeBuiltInFunctionTriplet(visit, "modf(", useEmulatedFunction); - break; - case EOpPow: - writeBuiltInFunctionTriplet(visit, "pow(", useEmulatedFunction); - break; - case EOpAtan: - writeBuiltInFunctionTriplet(visit, "atan(", useEmulatedFunction); - break; - case EOpMin: - writeBuiltInFunctionTriplet(visit, "min(", useEmulatedFunction); - break; - case EOpMax: - writeBuiltInFunctionTriplet(visit, "max(", useEmulatedFunction); - break; - case EOpClamp: - writeBuiltInFunctionTriplet(visit, "clamp(", useEmulatedFunction); - break; - case EOpMix: - writeBuiltInFunctionTriplet(visit, "mix(", useEmulatedFunction); - break; - case EOpStep: - writeBuiltInFunctionTriplet(visit, "step(", useEmulatedFunction); - break; - case EOpSmoothStep: - writeBuiltInFunctionTriplet(visit, "smoothstep(", useEmulatedFunction); - break; - case EOpDistance: - writeBuiltInFunctionTriplet(visit, "distance(", useEmulatedFunction); - break; - case EOpDot: - writeBuiltInFunctionTriplet(visit, "dot(", useEmulatedFunction); - break; - case EOpCross: - writeBuiltInFunctionTriplet(visit, "cross(", useEmulatedFunction); - break; - case EOpFaceForward: - writeBuiltInFunctionTriplet(visit, "faceforward(", useEmulatedFunction); - break; - case EOpReflect: - writeBuiltInFunctionTriplet(visit, "reflect(", useEmulatedFunction); - break; - case EOpRefract: - writeBuiltInFunctionTriplet(visit, "refract(", useEmulatedFunction); - break; - case EOpMul: - writeBuiltInFunctionTriplet(visit, "matrixCompMult(", useEmulatedFunction); - break; - - default: - UNREACHABLE(); + case EOpEqualComponentWise: + case EOpNotEqualComponentWise: + case EOpLessThanComponentWise: + case EOpGreaterThanComponentWise: + case EOpLessThanEqualComponentWise: + case EOpGreaterThanEqualComponentWise: + case EOpMod: + case EOpModf: + case EOpPow: + case EOpAtan: + case EOpMin: + case EOpMax: + case EOpClamp: + case EOpMix: + case EOpStep: + case EOpSmoothStep: + case EOpFrexp: + case EOpLdexp: + case EOpDistance: + case EOpDot: + case EOpCross: + case EOpFaceforward: + case EOpReflect: + case EOpRefract: + case EOpMulMatrixComponentWise: + case EOpOuterProduct: + case EOpBitfieldExtract: + case EOpBitfieldInsert: + case EOpUaddCarry: + case EOpUsubBorrow: + case EOpUmulExtended: + case EOpImulExtended: + case EOpBarrier: + case EOpMemoryBarrier: + case EOpMemoryBarrierAtomicCounter: + case EOpMemoryBarrierBuffer: + case EOpMemoryBarrierImage: + case EOpMemoryBarrierShared: + case EOpGroupMemoryBarrier: + case EOpEmitVertex: + case EOpEndPrimitive: + writeBuiltInFunctionTriplet(visit, node->getOp(), node->getUseEmulatedFunction()); + break; + default: + UNREACHABLE(); } return visitChildren; } +bool TOutputGLSLBase::visitDeclaration(Visit visit, TIntermDeclaration *node) +{ + TInfoSinkBase &out = objSink(); + + // Variable declaration. + if (visit == PreVisit) + { + const TIntermSequence &sequence = *(node->getSequence()); + TIntermTyped *variable = sequence.front()->getAsTyped(); + writeLayoutQualifier(variable); + writeVariableType(variable->getType()); + if (variable->getAsSymbolNode() == nullptr || + !variable->getAsSymbolNode()->getSymbol().empty()) + { + out << " "; + } + mDeclaringVariable = true; + } + else if (visit == InVisit) + { + UNREACHABLE(); + } + else + { + mDeclaringVariable = false; + } + return true; +} + bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop *node) { TInfoSinkBase &out = objSink(); - incrementDepth(node); - TLoopType loopType = node->getType(); - // Only for loops can be unrolled - ASSERT(!node->getUnrollFlag() || loopType == ELoopFor); - if (loopType == ELoopFor) // for loop { - if (!node->getUnrollFlag()) - { - out << "for ("; - if (node->getInit()) - node->getInit()->traverse(this); - out << "; "; + out << "for ("; + if (node->getInit()) + node->getInit()->traverse(this); + out << "; "; - if (node->getCondition()) - node->getCondition()->traverse(this); - out << "; "; + if (node->getCondition()) + node->getCondition()->traverse(this); + out << "; "; - if (node->getExpression()) - node->getExpression()->traverse(this); - out << ")\n"; + if (node->getExpression()) + node->getExpression()->traverse(this); + out << ")\n"; - visitCodeBlock(node->getBody()); - } - else - { - // Need to put a one-iteration loop here to handle break. - TIntermSequence *declSeq = - node->getInit()->getAsAggregate()->getSequence(); - TIntermSymbol *indexSymbol = - (*declSeq)[0]->getAsBinaryNode()->getLeft()->getAsSymbolNode(); - TString name = hashVariableName(indexSymbol->getSymbol()); - out << "for (int " << name << " = 0; " - << name << " < 1; " - << "++" << name << ")\n"; - - out << "{\n"; - mLoopUnrollStack.push(node); - while (mLoopUnrollStack.satisfiesLoopCondition()) - { - visitCodeBlock(node->getBody()); - mLoopUnrollStack.step(); - } - mLoopUnrollStack.pop(); - out << "}\n"; - } + visitCodeBlock(node->getBody()); } else if (loopType == ELoopWhile) // while loop { out << "while ("; - ASSERT(node->getCondition() != NULL); + ASSERT(node->getCondition() != nullptr); node->getCondition()->traverse(this); out << ")\n"; @@ -1154,13 +1071,11 @@ bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop *node) visitCodeBlock(node->getBody()); out << "while ("; - ASSERT(node->getCondition() != NULL); + ASSERT(node->getCondition() != nullptr); node->getCondition()->traverse(this); out << ");\n"; } - decrementDepth(); - // No need to visit children. They have been already processed in // this function. return false; @@ -1170,29 +1085,29 @@ bool TOutputGLSLBase::visitBranch(Visit visit, TIntermBranch *node) { switch (node->getFlowOp()) { - case EOpKill: - writeTriplet(visit, "discard", NULL, NULL); - break; - case EOpBreak: - writeTriplet(visit, "break", NULL, NULL); - break; - case EOpContinue: - writeTriplet(visit, "continue", NULL, NULL); - break; - case EOpReturn: - writeTriplet(visit, "return ", NULL, NULL); - break; - default: - UNREACHABLE(); + case EOpKill: + writeTriplet(visit, "discard", nullptr, nullptr); + break; + case EOpBreak: + writeTriplet(visit, "break", nullptr, nullptr); + break; + case EOpContinue: + writeTriplet(visit, "continue", nullptr, nullptr); + break; + case EOpReturn: + writeTriplet(visit, "return ", nullptr, nullptr); + break; + default: + UNREACHABLE(); } return true; } -void TOutputGLSLBase::visitCodeBlock(TIntermNode *node) +void TOutputGLSLBase::visitCodeBlock(TIntermBlock *node) { TInfoSinkBase &out = objSink(); - if (node != NULL) + if (node != nullptr) { node->traverse(this); // Single statements not part of a sequence need to be terminated @@ -1208,76 +1123,41 @@ void TOutputGLSLBase::visitCodeBlock(TIntermNode *node) TString TOutputGLSLBase::getTypeName(const TType &type) { - TInfoSinkBase out; - if (type.isMatrix()) - { - out << "mat"; - out << type.getNominalSize(); - if (type.getSecondarySize() != type.getNominalSize()) - { - out << "x" << type.getSecondarySize(); - } - } - else if (type.isVector()) - { - switch (type.getBasicType()) - { - case EbtFloat: - out << "vec"; - break; - case EbtInt: - out << "ivec"; - break; - case EbtBool: - out << "bvec"; - break; - case EbtUInt: - out << "uvec"; - break; - default: - UNREACHABLE(); - } - out << type.getNominalSize(); - } - else - { - if (type.getBasicType() == EbtStruct) - out << hashName(type.getStruct()->name()); - else - out << type.getBasicString(); - } - return TString(out.c_str()); + return GetTypeName(type, mHashFunction, &mNameMap); } -TString TOutputGLSLBase::hashName(const TString &name) +TString TOutputGLSLBase::hashName(const TName &name) { - if (mHashFunction == NULL || name.empty()) - return name; - NameMap::const_iterator it = mNameMap.find(name.c_str()); - if (it != mNameMap.end()) - return it->second.c_str(); - TString hashedName = TIntermTraverser::hash(name, mHashFunction); - mNameMap[name.c_str()] = hashedName.c_str(); - return hashedName; + return HashName(name, mHashFunction, &mNameMap); } -TString TOutputGLSLBase::hashVariableName(const TString &name) +TString TOutputGLSLBase::hashVariableName(const TName &name) { - if (mSymbolTable.findBuiltIn(name, mShaderVersion) != NULL) - return name; + if (mSymbolTable->findBuiltIn(name.getString(), mShaderVersion) != nullptr || + name.getString().substr(0, 3) == "gl_") + { + if (mCompileOptions & SH_TRANSLATE_VIEWID_OVR_TO_UNIFORM && + name.getString() == "gl_ViewID_OVR") + { + TName uniformName(TString("ViewID_OVR")); + uniformName.setInternal(true); + return hashName(uniformName); + } + return name.getString(); + } return hashName(name); } -TString TOutputGLSLBase::hashFunctionNameIfNeeded(const TName &mangledName) +TString TOutputGLSLBase::hashFunctionNameIfNeeded(const TFunctionSymbolInfo &info) { - TString mangledStr = mangledName.getString(); - TString name = TFunction::unmangleName(mangledStr); - if (mSymbolTable.findBuiltIn(mangledStr, mShaderVersion) != nullptr || name == "main") - return translateTextureFunction(name); - if (mangledName.isInternal()) - return name; + if (info.isMain()) + { + return info.getName(); + } else - return hashName(name); + { + return hashName(info.getNameObj()); + } } bool TOutputGLSLBase::structDeclared(const TStructure *structure) const @@ -1295,16 +1175,16 @@ void TOutputGLSLBase::declareStruct(const TStructure *structure) { TInfoSinkBase &out = objSink(); - out << "struct " << hashName(structure->name()) << "{\n"; + out << "struct " << hashName(TName(structure->name())) << "{\n"; const TFieldList &fields = structure->fields(); for (size_t i = 0; i < fields.size(); ++i) { const TField *field = fields[i]; if (writeVariablePrecision(field->type()->getPrecision())) out << " "; - out << getTypeName(*field->type()) << " " << hashName(field->name()); + out << getTypeName(*field->type()) << " " << hashName(TName(field->name())); if (field->type()->isArray()) - out << arrayBrackets(*field->type()); + out << ArrayString(*field->type()); out << ";\n"; } out << "}"; @@ -1332,6 +1212,10 @@ void TOutputGLSLBase::declareInterfaceBlockLayout(const TInterfaceBlock *interfa out << "std140"; break; + case EbsStd430: + out << "std430"; + break; + default: UNREACHABLE(); break; @@ -1339,6 +1223,12 @@ void TOutputGLSLBase::declareInterfaceBlockLayout(const TInterfaceBlock *interfa out << ", "; + if (interfaceBlock->blockBinding() > 0) + { + out << "binding = " << interfaceBlock->blockBinding(); + out << ", "; + } + switch (interfaceBlock->matrixPacking()) { case EmpUnspecified: @@ -1363,17 +1253,105 @@ void TOutputGLSLBase::declareInterfaceBlock(const TInterfaceBlock *interfaceBloc { TInfoSinkBase &out = objSink(); - out << hashName(interfaceBlock->name()) << "{\n"; + out << hashName(TName(interfaceBlock->name())) << "{\n"; const TFieldList &fields = interfaceBlock->fields(); for (size_t i = 0; i < fields.size(); ++i) { const TField *field = fields[i]; if (writeVariablePrecision(field->type()->getPrecision())) out << " "; - out << getTypeName(*field->type()) << " " << hashName(field->name()); + out << getTypeName(*field->type()) << " " << hashName(TName(field->name())); if (field->type()->isArray()) - out << arrayBrackets(*field->type()); + out << ArrayString(*field->type()); out << ";\n"; } out << "}"; } + +void WriteGeometryShaderLayoutQualifiers(TInfoSinkBase &out, + sh::TLayoutPrimitiveType inputPrimitive, + int invocations, + sh::TLayoutPrimitiveType outputPrimitive, + int maxVertices) +{ + // Omit 'invocations = 1' + if (inputPrimitive != EptUndefined || invocations > 1) + { + out << "layout ("; + + if (inputPrimitive != EptUndefined) + { + out << getGeometryShaderPrimitiveTypeString(inputPrimitive); + } + + if (invocations > 1) + { + if (inputPrimitive != EptUndefined) + { + out << ", "; + } + out << "invocations = " << invocations; + } + out << ") in;\n"; + } + + if (outputPrimitive != EptUndefined || maxVertices != -1) + { + out << "layout ("; + + if (outputPrimitive != EptUndefined) + { + out << getGeometryShaderPrimitiveTypeString(outputPrimitive); + } + + if (maxVertices != -1) + { + if (outputPrimitive != EptUndefined) + { + out << ", "; + } + out << "max_vertices = " << maxVertices; + } + out << ") out;\n"; + } +} + +// If SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS is enabled, layout qualifiers are spilled whenever +// variables with specified layout qualifiers are copied. Additional checks are needed against the +// type and storage qualifier of the variable to verify that layout qualifiers have to be outputted. +// TODO (mradev): Fix layout qualifier spilling in ScalarizeVecAndMatConstructorArgs and remove +// NeedsToWriteLayoutQualifier. +bool NeedsToWriteLayoutQualifier(const TType &type) +{ + if (type.getBasicType() == EbtInterfaceBlock) + { + return false; + } + + const TLayoutQualifier &layoutQualifier = type.getLayoutQualifier(); + + if ((type.getQualifier() == EvqFragmentOut || type.getQualifier() == EvqVertexIn || + IsVarying(type.getQualifier())) && + layoutQualifier.location >= 0) + { + return true; + } + + if (type.getQualifier() == EvqFragmentOut && layoutQualifier.yuv == true) + { + return true; + } + + if (IsOpaqueType(type.getBasicType()) && layoutQualifier.binding != -1) + { + return true; + } + + if (IsImage(type.getBasicType()) && layoutQualifier.imageInternalFormat != EiifUnspecified) + { + return true; + } + return false; +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.h b/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.h index 2ae82d15b2..592a310be4 100644 --- a/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.h +++ b/src/3rdparty/angle/src/compiler/translator/OutputGLSLBase.h @@ -9,9 +9,12 @@ #include -#include "compiler/translator/IntermNode.h" -#include "compiler/translator/LoopInfo.h" -#include "compiler/translator/ParseContext.h" +#include "compiler/translator/HashNames.h" +#include "compiler/translator/InfoSink.h" +#include "compiler/translator/IntermTraverse.h" + +namespace sh +{ class TOutputGLSLBase : public TIntermTraverser { @@ -20,48 +23,58 @@ class TOutputGLSLBase : public TIntermTraverser ShArrayIndexClampingStrategy clampingStrategy, ShHashFunction64 hashFunction, NameMap &nameMap, - TSymbolTable& symbolTable, + TSymbolTable *symbolTable, + sh::GLenum shaderType, int shaderVersion, - ShShaderOutput output); + ShShaderOutput output, + ShCompileOptions compileOptions); - ShShaderOutput getShaderOutput() const - { - return mOutput; - } + ShShaderOutput getShaderOutput() const { return mOutput; } + + // Return the original name if hash function pointer is NULL; + // otherwise return the hashed name. Has special handling for internal names, which are not + // hashed. + TString hashName(const TName &name); protected: TInfoSinkBase &objSink() { return mObjSink; } + void writeFloat(TInfoSinkBase &out, float f); void writeTriplet(Visit visit, const char *preStr, const char *inStr, const char *postStr); - void writeLayoutQualifier(const TType &type); + virtual void writeLayoutQualifier(TIntermTyped *variable); + void writeInvariantQualifier(const TType &type); void writeVariableType(const TType &type); virtual bool writeVariablePrecision(TPrecision precision) = 0; void writeFunctionParameters(const TIntermSequence &args); const TConstantUnion *writeConstantUnion(const TType &type, const TConstantUnion *pConstUnion); - void writeConstructorTriplet(Visit visit, const TType &type, const char *constructorBaseType); + void writeConstructorTriplet(Visit visit, const TType &type); TString getTypeName(const TType &type); void visitSymbol(TIntermSymbol *node) override; void visitConstantUnion(TIntermConstantUnion *node) override; + bool visitSwizzle(Visit visit, TIntermSwizzle *node) override; bool visitBinary(Visit visit, TIntermBinary *node) override; bool visitUnary(Visit visit, TIntermUnary *node) override; - bool visitSelection(Visit visit, TIntermSelection *node) override; + bool visitTernary(Visit visit, TIntermTernary *node) override; + bool visitIfElse(Visit visit, TIntermIfElse *node) override; bool visitSwitch(Visit visit, TIntermSwitch *node) override; bool visitCase(Visit visit, TIntermCase *node) override; + bool visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *node) override; + bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override; bool visitAggregate(Visit visit, TIntermAggregate *node) override; + bool visitBlock(Visit visit, TIntermBlock *node) override; + bool visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *node) override; + bool visitDeclaration(Visit visit, TIntermDeclaration *node) override; bool visitLoop(Visit visit, TIntermLoop *node) override; bool visitBranch(Visit visit, TIntermBranch *node) override; - void visitCodeBlock(TIntermNode *node); + void visitCodeBlock(TIntermBlock *node); - // Return the original name if hash function pointer is NULL; - // otherwise return the hashed name. - TString hashName(const TString &name); // Same as hashName(), but without hashing built-in variables. - TString hashVariableName(const TString &name); - // Same as hashName(), but without hashing built-in functions and with unmangling. - TString hashFunctionNameIfNeeded(const TName &mangledName); + TString hashVariableName(const TName &name); + // Same as hashName(), but without hashing internal functions or "main". + TString hashFunctionNameIfNeeded(const TFunctionSymbolInfo &info); // Used to translate function names for differences between ESSL and GLSL - virtual TString translateTextureFunction(TString &name) { return name; } + virtual TString translateTextureFunction(const TString &name) { return name; } private: bool structDeclared(const TStructure *structure) const; @@ -70,17 +83,16 @@ class TOutputGLSLBase : public TIntermTraverser void declareInterfaceBlockLayout(const TInterfaceBlock *interfaceBlock); void declareInterfaceBlock(const TInterfaceBlock *interfaceBlock); - void writeBuiltInFunctionTriplet(Visit visit, const char *preStr, bool useEmulatedFunction); + void writeBuiltInFunctionTriplet(Visit visit, TOperator op, bool useEmulatedFunction); + + const char *mapQualifierToString(TQualifier qialifier); TInfoSinkBase &mObjSink; - bool mDeclaringVariables; + bool mDeclaringVariable; // This set contains all the ids of the structs from every scope. std::set mDeclaredStructs; - // Stack of loops that need to be unrolled. - TLoopStack mLoopUnrollStack; - ShArrayIndexClampingStrategy mClampingStrategy; // name hashing. @@ -88,11 +100,23 @@ class TOutputGLSLBase : public TIntermTraverser NameMap &mNameMap; - TSymbolTable &mSymbolTable; + sh::GLenum mShaderType; const int mShaderVersion; ShShaderOutput mOutput; + + ShCompileOptions mCompileOptions; }; +void WriteGeometryShaderLayoutQualifiers(TInfoSinkBase &out, + sh::TLayoutPrimitiveType inputPrimitive, + int invocations, + sh::TLayoutPrimitiveType outputPrimitive, + int maxVertices); + +bool NeedsToWriteLayoutQualifier(const TType &type); + +} // namespace sh + #endif // COMPILER_TRANSLATOR_OUTPUTGLSLBASE_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/OutputHLSL.cpp b/src/3rdparty/angle/src/compiler/translator/OutputHLSL.cpp index 253b96696c..d5ff761430 100644 --- a/src/3rdparty/angle/src/compiler/translator/OutputHLSL.cpp +++ b/src/3rdparty/angle/src/compiler/translator/OutputHLSL.cpp @@ -15,33 +15,95 @@ #include "common/utilities.h" #include "compiler/translator/BuiltInFunctionEmulator.h" #include "compiler/translator/BuiltInFunctionEmulatorHLSL.h" -#include "compiler/translator/FlagStd140Structs.h" +#include "compiler/translator/ImageFunctionHLSL.h" #include "compiler/translator/InfoSink.h" #include "compiler/translator/NodeSearch.h" #include "compiler/translator/RemoveSwitchFallThrough.h" #include "compiler/translator/SearchSymbol.h" #include "compiler/translator/StructureHLSL.h" +#include "compiler/translator/TextureFunctionHLSL.h" #include "compiler/translator/TranslatorHLSL.h" #include "compiler/translator/UniformHLSL.h" #include "compiler/translator/UtilsHLSL.h" #include "compiler/translator/blocklayout.h" #include "compiler/translator/util.h" +namespace sh +{ + namespace { -bool IsSequence(TIntermNode *node) +TString ArrayHelperFunctionName(const char *prefix, const TType &type) { - return node->getAsAggregate() != nullptr && node->getAsAggregate()->getOp() == EOpSequence; + TStringStream fnName; + fnName << prefix << "_"; + if (type.isArray()) + { + for (unsigned int arraySize : *type.getArraySizes()) + { + fnName << arraySize << "_"; + } + } + fnName << TypeString(type); + return fnName.str(); } -void WriteSingleConstant(TInfoSinkBase &out, const TConstantUnion *const constUnion) +bool IsDeclarationWrittenOut(TIntermDeclaration *node) +{ + TIntermSequence *sequence = node->getSequence(); + TIntermTyped *variable = (*sequence)[0]->getAsTyped(); + ASSERT(sequence->size() == 1); + ASSERT(variable); + return (variable->getQualifier() == EvqTemporary || variable->getQualifier() == EvqGlobal || + variable->getQualifier() == EvqConst); +} + +bool IsInStd140InterfaceBlock(TIntermTyped *node) +{ + TIntermBinary *binaryNode = node->getAsBinaryNode(); + + if (binaryNode) + { + return IsInStd140InterfaceBlock(binaryNode->getLeft()); + } + + const TType &type = node->getType(); + + // determine if we are in the standard layout + const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock(); + if (interfaceBlock) + { + return (interfaceBlock->blockStorage() == EbsStd140); + } + + return false; +} + +} // anonymous namespace + +void OutputHLSL::writeFloat(TInfoSinkBase &out, float f) +{ + // This is known not to work for NaN on all drivers but make the best effort to output NaNs + // regardless. + if ((gl::isInf(f) || gl::isNaN(f)) && mShaderVersion >= 300 && + mOutputType == SH_HLSL_4_1_OUTPUT) + { + out << "asfloat(" << gl::bitCast(f) << "u)"; + } + else + { + out << std::min(FLT_MAX, std::max(-FLT_MAX, f)); + } +} + +void OutputHLSL::writeSingleConstant(TInfoSinkBase &out, const TConstantUnion *const constUnion) { ASSERT(constUnion != nullptr); switch (constUnion->getType()) { case EbtFloat: - out << std::min(FLT_MAX, std::max(-FLT_MAX, constUnion->getFConst())); + writeFloat(out, constUnion->getFConst()); break; case EbtInt: out << constUnion->getIConst(); @@ -57,14 +119,14 @@ void WriteSingleConstant(TInfoSinkBase &out, const TConstantUnion *const constUn } } -const TConstantUnion *WriteConstantUnionArray(TInfoSinkBase &out, - const TConstantUnion *const constUnion, - const size_t size) +const TConstantUnion *OutputHLSL::writeConstantUnionArray(TInfoSinkBase &out, + const TConstantUnion *const constUnion, + const size_t size) { const TConstantUnion *constUnionIterated = constUnion; for (size_t i = 0; i < size; i++, constUnionIterated++) { - WriteSingleConstant(out, constUnionIterated); + writeSingleConstant(out, constUnionIterated); if (i != size - 1) { @@ -74,71 +136,17 @@ const TConstantUnion *WriteConstantUnionArray(TInfoSinkBase &out, return constUnionIterated; } -} // namespace - -namespace sh -{ - -TString OutputHLSL::TextureFunction::name() const -{ - TString name = "gl_texture"; - - // We need to include full the sampler type in the function name to make the signature unique - // on D3D11, where samplers are passed to texture functions as indices. - name += TextureTypeSuffix(this->sampler); - - if (proj) - { - name += "Proj"; - } - - if (offset) - { - name += "Offset"; - } - - switch(method) - { - case IMPLICIT: break; - case BIAS: break; // Extra parameter makes the signature unique - case LOD: name += "Lod"; break; - case LOD0: name += "Lod0"; break; - case LOD0BIAS: name += "Lod0"; break; // Extra parameter makes the signature unique - case SIZE: name += "Size"; break; - case FETCH: name += "Fetch"; break; - case GRAD: name += "Grad"; break; - default: UNREACHABLE(); - } - - return name + "("; -} - -bool OutputHLSL::TextureFunction::operator<(const TextureFunction &rhs) const -{ - if (sampler < rhs.sampler) return true; - if (sampler > rhs.sampler) return false; - - if (coords < rhs.coords) return true; - if (coords > rhs.coords) return false; - - if (!proj && rhs.proj) return true; - if (proj && !rhs.proj) return false; - - if (!offset && rhs.offset) return true; - if (offset && !rhs.offset) return false; - - if (method < rhs.method) return true; - if (method > rhs.method) return false; - - return false; -} - -OutputHLSL::OutputHLSL(sh::GLenum shaderType, int shaderVersion, - const TExtensionBehavior &extensionBehavior, - const char *sourcePath, ShShaderOutput outputType, - int numRenderTargets, const std::vector &uniforms, - int compileOptions) - : TIntermTraverser(true, true, true), +OutputHLSL::OutputHLSL(sh::GLenum shaderType, + int shaderVersion, + const TExtensionBehavior &extensionBehavior, + const char *sourcePath, + ShShaderOutput outputType, + int numRenderTargets, + const std::vector &uniforms, + ShCompileOptions compileOptions, + TSymbolTable *symbolTable, + PerformanceDiagnostics *perfDiagnostics) + : TIntermTraverser(true, true, true, symbolTable), mShaderType(shaderType), mShaderVersion(shaderVersion), mExtensionBehavior(extensionBehavior), @@ -146,51 +154,66 @@ OutputHLSL::OutputHLSL(sh::GLenum shaderType, int shaderVersion, mOutputType(outputType), mCompileOptions(compileOptions), mNumRenderTargets(numRenderTargets), - mCurrentFunctionMetadata(nullptr) + mCurrentFunctionMetadata(nullptr), + mPerfDiagnostics(perfDiagnostics) { mInsideFunction = false; - mUsesFragColor = false; - mUsesFragData = false; - mUsesDepthRange = false; - mUsesFragCoord = false; - mUsesPointCoord = false; - mUsesFrontFacing = false; - mUsesPointSize = false; - mUsesInstanceID = false; - mUsesFragDepth = false; - mUsesXor = false; - mUsesDiscardRewriting = false; - mUsesNestedBreak = false; + mUsesFragColor = false; + mUsesFragData = false; + mUsesDepthRange = false; + mUsesFragCoord = false; + mUsesPointCoord = false; + mUsesFrontFacing = false; + mUsesPointSize = false; + mUsesInstanceID = false; + mHasMultiviewExtensionEnabled = + IsExtensionEnabled(mExtensionBehavior, TExtension::OVR_multiview); + mUsesViewID = false; + mUsesVertexID = false; + mUsesFragDepth = false; + mUsesNumWorkGroups = false; + mUsesWorkGroupID = false; + mUsesLocalInvocationID = false; + mUsesGlobalInvocationID = false; + mUsesLocalInvocationIndex = false; + mUsesXor = false; + mUsesDiscardRewriting = false; + mUsesNestedBreak = false; mRequiresIEEEStrictCompiling = false; mUniqueIndex = 0; - mOutputLod0Function = false; + mOutputLod0Function = false; mInsideDiscontinuousLoop = false; - mNestedLoopDepth = 0; + mNestedLoopDepth = 0; - mExcessiveLoopIndex = NULL; + mExcessiveLoopIndex = nullptr; - mStructureHLSL = new StructureHLSL; - mUniformHLSL = new UniformHLSL(mStructureHLSL, outputType, uniforms); + mStructureHLSL = new StructureHLSL; + mUniformHLSL = new UniformHLSL(shaderType, mStructureHLSL, outputType, uniforms); + mTextureFunctionHLSL = new TextureFunctionHLSL; + mImageFunctionHLSL = new ImageFunctionHLSL; if (mOutputType == SH_HLSL_3_0_OUTPUT) { // Fragment shaders need dx_DepthRange, dx_ViewCoords and dx_DepthFront. - // Vertex shaders need a slightly different set: dx_DepthRange, dx_ViewCoords and dx_ViewAdjust. + // Vertex shaders need a slightly different set: dx_DepthRange, dx_ViewCoords and + // dx_ViewAdjust. // In both cases total 3 uniform registers need to be reserved. mUniformHLSL->reserveUniformRegisters(3); } // Reserve registers for the default uniform block and driver constants - mUniformHLSL->reserveInterfaceBlockRegisters(2); + mUniformHLSL->reserveUniformBlockRegisters(2); } OutputHLSL::~OutputHLSL() { SafeDelete(mStructureHLSL); SafeDelete(mUniformHLSL); + SafeDelete(mTextureFunctionHLSL); + SafeDelete(mImageFunctionHLSL); for (auto &eqFunction : mStructEqualityFunctions) { SafeDelete(eqFunction); @@ -203,71 +226,48 @@ OutputHLSL::~OutputHLSL() void OutputHLSL::output(TIntermNode *treeRoot, TInfoSinkBase &objSink) { - const std::vector &flaggedStructs = FlagStd140ValueStructs(treeRoot); - makeFlaggedStructMaps(flaggedStructs); - BuiltInFunctionEmulator builtInFunctionEmulator; InitBuiltInFunctionEmulatorForHLSL(&builtInFunctionEmulator); - builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(treeRoot); + if ((mCompileOptions & SH_EMULATE_ISNAN_FLOAT_FUNCTION) != 0) + { + InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(&builtInFunctionEmulator, + mShaderVersion); + } + + builtInFunctionEmulator.markBuiltInFunctionsForEmulation(treeRoot); // Now that we are done changing the AST, do the analyses need for HLSL generation - CallDAG::InitResult success = mCallDag.init(treeRoot, &objSink); + CallDAG::InitResult success = mCallDag.init(treeRoot, nullptr); ASSERT(success == CallDAG::INITDAG_SUCCESS); - UNUSED_ASSERTION_VARIABLE(success); mASTMetadataList = CreateASTMetadataHLSL(treeRoot, mCallDag); + const std::vector std140Structs = FlagStd140Structs(treeRoot); + // TODO(oetuaho): The std140Structs could be filtered based on which ones actually get used in + // the shader code. When we add shader storage blocks we might also consider an alternative + // solution, since the struct mapping won't work very well for shader storage blocks. + // Output the body and footer first to determine what has to go in the header mInfoSinkStack.push(&mBody); treeRoot->traverse(this); mInfoSinkStack.pop(); mInfoSinkStack.push(&mFooter); - if (!mDeferredGlobalInitializers.empty()) - { - writeDeferredGlobalInitializers(mFooter); - } mInfoSinkStack.pop(); mInfoSinkStack.push(&mHeader); - header(mHeader, &builtInFunctionEmulator); + header(mHeader, std140Structs, &builtInFunctionEmulator); mInfoSinkStack.pop(); objSink << mHeader.c_str(); objSink << mBody.c_str(); objSink << mFooter.c_str(); - builtInFunctionEmulator.Cleanup(); + builtInFunctionEmulator.cleanup(); } -void OutputHLSL::makeFlaggedStructMaps(const std::vector &flaggedStructs) +const std::map &OutputHLSL::getUniformBlockRegisterMap() const { - for (unsigned int structIndex = 0; structIndex < flaggedStructs.size(); structIndex++) - { - TIntermTyped *flaggedNode = flaggedStructs[structIndex]; - - TInfoSinkBase structInfoSink; - mInfoSinkStack.push(&structInfoSink); - - // This will mark the necessary block elements as referenced - flaggedNode->traverse(this); - - TString structName(structInfoSink.c_str()); - mInfoSinkStack.pop(); - - mFlaggedStructOriginalNames[flaggedNode] = structName; - - for (size_t pos = structName.find('.'); pos != std::string::npos; pos = structName.find('.')) - { - structName.erase(pos, 1); - } - - mFlaggedStructMappedNames[flaggedNode] = "map" + structName; - } -} - -const std::map &OutputHLSL::getInterfaceBlockRegisterMap() const -{ - return mUniformHLSL->getInterfaceBlockRegisterMap(); + return mUniformHLSL->getUniformBlockRegisterMap(); } const std::map &OutputHLSL::getUniformRegisterMap() const @@ -275,95 +275,161 @@ const std::map &OutputHLSL::getUniformRegisterMap() c return mUniformHLSL->getUniformRegisterMap(); } -int OutputHLSL::vectorSize(const TType &type) const -{ - int elementSize = type.isMatrix() ? type.getCols() : 1; - int arraySize = type.isArray() ? type.getArraySize() : 1; - - return elementSize * arraySize; -} - -TString OutputHLSL::structInitializerString(int indent, const TStructure &structure, const TString &rhsStructName) +TString OutputHLSL::structInitializerString(int indent, + const TType &type, + const TString &name) const { TString init; - TString preIndentString; - TString fullIndentString; - - for (int spaces = 0; spaces < (indent * 4); spaces++) + TString indentString; + for (int spaces = 0; spaces < indent; spaces++) { - preIndentString += ' '; + indentString += " "; } - for (int spaces = 0; spaces < ((indent+1) * 4); spaces++) + if (type.isArray()) { - fullIndentString += ' '; - } - - init += preIndentString + "{\n"; - - const TFieldList &fields = structure.fields(); - for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) - { - const TField &field = *fields[fieldIndex]; - const TString &fieldName = rhsStructName + "." + Decorate(field.name()); - const TType &fieldType = *field.type(); - - if (fieldType.getStruct()) + init += indentString + "{\n"; + for (unsigned int arrayIndex = 0u; arrayIndex < type.getOutermostArraySize(); ++arrayIndex) { - init += structInitializerString(indent + 1, *fieldType.getStruct(), fieldName); - } - else - { - init += fullIndentString + fieldName + ",\n"; + TStringStream indexedString; + indexedString << name << "[" << arrayIndex << "]"; + TType elementType = type; + elementType.toArrayElementType(); + init += structInitializerString(indent + 1, elementType, indexedString.str()); + if (arrayIndex < type.getOutermostArraySize() - 1) + { + init += ","; + } + init += "\n"; } + init += indentString + "}"; } + else if (type.getBasicType() == EbtStruct) + { + init += indentString + "{\n"; + const TStructure &structure = *type.getStruct(); + const TFieldList &fields = structure.fields(); + for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) + { + const TField &field = *fields[fieldIndex]; + const TString &fieldName = name + "." + Decorate(field.name()); + const TType &fieldType = *field.type(); - init += preIndentString + "}" + (indent == 0 ? ";" : ",") + "\n"; + init += structInitializerString(indent + 1, fieldType, fieldName); + if (fieldIndex < fields.size() - 1) + { + init += ","; + } + init += "\n"; + } + init += indentString + "}"; + } + else + { + init += indentString + name; + } return init; } -void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *builtInFunctionEmulator) +TString OutputHLSL::generateStructMapping(const std::vector &std140Structs) const +{ + TString mappedStructs; + + for (auto &mappedStruct : std140Structs) + { + TInterfaceBlock *interfaceBlock = + mappedStruct.blockDeclarator->getType().getInterfaceBlock(); + const TString &interfaceBlockName = interfaceBlock->name(); + const TName &instanceName = mappedStruct.blockDeclarator->getName(); + if (mReferencedUniformBlocks.count(interfaceBlockName) == 0 && + (instanceName.getString() == "" || + mReferencedUniformBlocks.count(instanceName.getString()) == 0)) + { + continue; + } + + unsigned int instanceCount = 1u; + bool isInstanceArray = mappedStruct.blockDeclarator->isArray(); + if (isInstanceArray) + { + instanceCount = mappedStruct.blockDeclarator->getOutermostArraySize(); + } + + for (unsigned int instanceArrayIndex = 0; instanceArrayIndex < instanceCount; + ++instanceArrayIndex) + { + TString originalName; + TString mappedName("map"); + + if (instanceName.getString() != "") + { + unsigned int instanceStringArrayIndex = GL_INVALID_INDEX; + if (isInstanceArray) + instanceStringArrayIndex = instanceArrayIndex; + TString instanceString = mUniformHLSL->uniformBlockInstanceString( + *interfaceBlock, instanceStringArrayIndex); + originalName += instanceString; + mappedName += instanceString; + originalName += "."; + mappedName += "_"; + } + + TString fieldName = Decorate(mappedStruct.field->name()); + originalName += fieldName; + mappedName += fieldName; + + TType *structType = mappedStruct.field->type(); + mappedStructs += + "static " + Decorate(structType->getStruct()->name()) + " " + mappedName; + + if (structType->isArray()) + { + mappedStructs += ArrayString(*mappedStruct.field->type()); + } + + mappedStructs += " =\n"; + mappedStructs += structInitializerString(0, *structType, originalName); + mappedStructs += ";\n"; + } + } + return mappedStructs; +} + +void OutputHLSL::header(TInfoSinkBase &out, + const std::vector &std140Structs, + const BuiltInFunctionEmulator *builtInFunctionEmulator) const { TString varyings; TString attributes; - TString flaggedStructs; + TString mappedStructs = generateStructMapping(std140Structs); - for (std::map::const_iterator flaggedStructIt = mFlaggedStructMappedNames.begin(); flaggedStructIt != mFlaggedStructMappedNames.end(); flaggedStructIt++) + for (ReferencedSymbols::const_iterator varying = mReferencedVaryings.begin(); + varying != mReferencedVaryings.end(); varying++) { - TIntermTyped *structNode = flaggedStructIt->first; - const TString &mappedName = flaggedStructIt->second; - const TStructure &structure = *structNode->getType().getStruct(); - const TString &originalName = mFlaggedStructOriginalNames[structNode]; - - flaggedStructs += "static " + Decorate(structure.name()) + " " + mappedName + " =\n"; - flaggedStructs += structInitializerString(0, structure, originalName); - flaggedStructs += "\n"; - } - - for (ReferencedSymbols::const_iterator varying = mReferencedVaryings.begin(); varying != mReferencedVaryings.end(); varying++) - { - const TType &type = varying->second->getType(); + const TType &type = varying->second->getType(); const TString &name = varying->second->getSymbol(); // Program linking depends on this exact format - varyings += "static " + InterpolationString(type.getQualifier()) + " " + TypeString(type) + " " + - Decorate(name) + ArrayString(type) + " = " + initializer(type) + ";\n"; + varyings += "static " + InterpolationString(type.getQualifier()) + " " + TypeString(type) + + " " + Decorate(name) + ArrayString(type) + " = " + initializer(type) + ";\n"; } - for (ReferencedSymbols::const_iterator attribute = mReferencedAttributes.begin(); attribute != mReferencedAttributes.end(); attribute++) + for (ReferencedSymbols::const_iterator attribute = mReferencedAttributes.begin(); + attribute != mReferencedAttributes.end(); attribute++) { - const TType &type = attribute->second->getType(); + const TType &type = attribute->second->getType(); const TString &name = attribute->second->getSymbol(); - attributes += "static " + TypeString(type) + " " + Decorate(name) + ArrayString(type) + " = " + initializer(type) + ";\n"; + attributes += "static " + TypeString(type) + " " + Decorate(name) + ArrayString(type) + + " = " + initializer(type) + ";\n"; } out << mStructureHLSL->structsHeader(); - mUniformHLSL->uniformsHeader(out, mOutputType, mReferencedUniforms); - out << mUniformHLSL->interfaceBlocksHeader(mReferencedInterfaceBlocks); + mUniformHLSL->uniformsHeader(out, mOutputType, mReferencedUniforms, mSymbolTable); + out << mUniformHLSL->uniformBlocksHeader(mReferencedUniformBlocks); if (!mEqualityFunctions.empty()) { @@ -415,22 +481,24 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built if (mShaderType == GL_FRAGMENT_SHADER) { - TExtensionBehavior::const_iterator iter = mExtensionBehavior.find("GL_EXT_draw_buffers"); - const bool usingMRTExtension = (iter != mExtensionBehavior.end() && (iter->second == EBhEnable || iter->second == EBhRequire)); + const bool usingMRTExtension = + IsExtensionEnabled(mExtensionBehavior, TExtension::EXT_draw_buffers); out << "// Varyings\n"; - out << varyings; + out << varyings; out << "\n"; if (mShaderVersion >= 300) { - for (ReferencedSymbols::const_iterator outputVariableIt = mReferencedOutputVariables.begin(); outputVariableIt != mReferencedOutputVariables.end(); outputVariableIt++) + for (ReferencedSymbols::const_iterator outputVariableIt = + mReferencedOutputVariables.begin(); + outputVariableIt != mReferencedOutputVariables.end(); outputVariableIt++) { const TString &variableName = outputVariableIt->first; - const TType &variableType = outputVariableIt->second->getType(); + const TType &variableType = outputVariableIt->second->getType(); - out << "static " + TypeString(variableType) + " out_" + variableName + ArrayString(variableType) + - " = " + initializer(variableType) + ";\n"; + out << "static " + TypeString(variableType) + " out_" + variableName + + ArrayString(variableType) + " = " + initializer(variableType) + ";\n"; } } else @@ -438,7 +506,7 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built const unsigned int numColorValues = usingMRTExtension ? mNumRenderTargets : 1; out << "static float4 gl_Color[" << numColorValues << "] =\n" - "{\n"; + "{\n"; for (unsigned int i = 0; i < numColorValues; i++) { out << " float4(0, 0, 0, 0)"; @@ -512,6 +580,18 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built out << " float2 dx_ViewScale : packoffset(c3);\n"; } + if (mHasMultiviewExtensionEnabled) + { + // We have to add a value which we can use to keep track of which multi-view code + // path is to be selected in the GS. + out << " float multiviewSelectViewportIndex : packoffset(c3.z);\n"; + } + + if (mOutputType == SH_HLSL_4_1_OUTPUT) + { + mUniformHLSL->samplerMetadataUniforms(out, "c4"); + } + out << "};\n"; } else @@ -536,15 +616,16 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built if (mUsesDepthRange) { - out << "static gl_DepthRangeParameters gl_DepthRange = {dx_DepthRange.x, dx_DepthRange.y, dx_DepthRange.z};\n" + out << "static gl_DepthRangeParameters gl_DepthRange = {dx_DepthRange.x, " + "dx_DepthRange.y, dx_DepthRange.z};\n" "\n"; } - if (!flaggedStructs.empty()) + if (!mappedStructs.empty()) { - out << "// Std140 Structures accessed by value\n"; + out << "// Structures from std140 blocks with padding removed\n"; out << "\n"; - out << flaggedStructs; + out << mappedStructs; out << "\n"; } @@ -563,10 +644,10 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built out << "#define GL_USES_FRAG_DATA\n"; } } - else // Vertex shader + else if (mShaderType == GL_VERTEX_SHADER) { out << "// Attributes\n"; - out << attributes; + out << attributes; out << "\n" "static float4 gl_Position = float4(0, 0, 0, 0);\n"; @@ -580,9 +661,14 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built out << "static int gl_InstanceID;"; } + if (mUsesVertexID) + { + out << "static int gl_VertexID;"; + } + out << "\n" "// Varyings\n"; - out << varyings; + out << varyings; out << "\n"; if (mUsesDepthRange) @@ -599,7 +685,7 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built if (mOutputType == SH_HLSL_4_1_OUTPUT || mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT) { out << "cbuffer DriverConstants : register(b1)\n" - "{\n"; + "{\n"; if (mUsesDepthRange) { @@ -614,6 +700,18 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built out << " float2 dx_ViewCoords : packoffset(c2);\n"; out << " float2 dx_ViewScale : packoffset(c3);\n"; + if (mHasMultiviewExtensionEnabled) + { + // We have to add a value which we can use to keep track of which multi-view code + // path is to be selected in the GS. + out << " float multiviewSelectViewportIndex : packoffset(c3.z);\n"; + } + + if (mOutputType == SH_HLSL_4_1_OUTPUT) + { + mUniformHLSL->samplerMetadataUniforms(out, "c4"); + } + out << "};\n" "\n"; } @@ -631,740 +729,62 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built if (mUsesDepthRange) { - out << "static gl_DepthRangeParameters gl_DepthRange = {dx_DepthRange.x, dx_DepthRange.y, dx_DepthRange.z};\n" + out << "static gl_DepthRangeParameters gl_DepthRange = {dx_DepthRange.x, " + "dx_DepthRange.y, dx_DepthRange.z};\n" "\n"; } - if (!flaggedStructs.empty()) + if (!mappedStructs.empty()) { - out << "// Std140 Structures accessed by value\n"; + out << "// Structures from std140 blocks with padding removed\n"; out << "\n"; - out << flaggedStructs; + out << mappedStructs; out << "\n"; } } - - for (TextureFunctionSet::const_iterator textureFunction = mUsesTexture.begin(); textureFunction != mUsesTexture.end(); textureFunction++) + else // Compute shader { - // Return type - if (textureFunction->method == TextureFunction::SIZE) - { - switch(textureFunction->sampler) - { - case EbtSampler2D: out << "int2 "; break; - case EbtSampler3D: out << "int3 "; break; - case EbtSamplerCube: out << "int2 "; break; - case EbtSampler2DArray: out << "int3 "; break; - case EbtISampler2D: out << "int2 "; break; - case EbtISampler3D: out << "int3 "; break; - case EbtISamplerCube: out << "int2 "; break; - case EbtISampler2DArray: out << "int3 "; break; - case EbtUSampler2D: out << "int2 "; break; - case EbtUSampler3D: out << "int3 "; break; - case EbtUSamplerCube: out << "int2 "; break; - case EbtUSampler2DArray: out << "int3 "; break; - case EbtSampler2DShadow: out << "int2 "; break; - case EbtSamplerCubeShadow: out << "int2 "; break; - case EbtSampler2DArrayShadow: out << "int3 "; break; - default: UNREACHABLE(); - } - } - else // Sampling function - { - switch(textureFunction->sampler) - { - case EbtSampler2D: out << "float4 "; break; - case EbtSampler3D: out << "float4 "; break; - case EbtSamplerCube: out << "float4 "; break; - case EbtSampler2DArray: out << "float4 "; break; - case EbtISampler2D: out << "int4 "; break; - case EbtISampler3D: out << "int4 "; break; - case EbtISamplerCube: out << "int4 "; break; - case EbtISampler2DArray: out << "int4 "; break; - case EbtUSampler2D: out << "uint4 "; break; - case EbtUSampler3D: out << "uint4 "; break; - case EbtUSamplerCube: out << "uint4 "; break; - case EbtUSampler2DArray: out << "uint4 "; break; - case EbtSampler2DShadow: out << "float "; break; - case EbtSamplerCubeShadow: out << "float "; break; - case EbtSampler2DArrayShadow: out << "float "; break; - default: UNREACHABLE(); - } - } + ASSERT(mShaderType == GL_COMPUTE_SHADER); - // Function name - out << textureFunction->name(); - - // Argument list - int hlslCoords = 4; - - if (mOutputType == SH_HLSL_3_0_OUTPUT) - { - switch(textureFunction->sampler) - { - case EbtSampler2D: out << "sampler2D s"; hlslCoords = 2; break; - case EbtSamplerCube: out << "samplerCUBE s"; hlslCoords = 3; break; - default: UNREACHABLE(); - } - - switch(textureFunction->method) - { - case TextureFunction::IMPLICIT: break; - case TextureFunction::BIAS: hlslCoords = 4; break; - case TextureFunction::LOD: hlslCoords = 4; break; - case TextureFunction::LOD0: hlslCoords = 4; break; - case TextureFunction::LOD0BIAS: hlslCoords = 4; break; - default: UNREACHABLE(); - } - } - else - { - hlslCoords = HLSLTextureCoordsCount(textureFunction->sampler); - if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT) - { - out << TextureString(textureFunction->sampler) << " x, " - << SamplerString(textureFunction->sampler) << " s"; - } - else - { - ASSERT(mOutputType == SH_HLSL_4_1_OUTPUT); - out << "const uint samplerIndex"; - } - } - - if (textureFunction->method == TextureFunction::FETCH) // Integer coordinates - { - switch(textureFunction->coords) - { - case 2: out << ", int2 t"; break; - case 3: out << ", int3 t"; break; - default: UNREACHABLE(); - } - } - else // Floating-point coordinates (except textureSize) - { - switch(textureFunction->coords) - { - case 1: out << ", int lod"; break; // textureSize() - case 2: out << ", float2 t"; break; - case 3: out << ", float3 t"; break; - case 4: out << ", float4 t"; break; - default: UNREACHABLE(); - } - } - - if (textureFunction->method == TextureFunction::GRAD) - { - switch(textureFunction->sampler) - { - case EbtSampler2D: - case EbtISampler2D: - case EbtUSampler2D: - case EbtSampler2DArray: - case EbtISampler2DArray: - case EbtUSampler2DArray: - case EbtSampler2DShadow: - case EbtSampler2DArrayShadow: - out << ", float2 ddx, float2 ddy"; - break; - case EbtSampler3D: - case EbtISampler3D: - case EbtUSampler3D: - case EbtSamplerCube: - case EbtISamplerCube: - case EbtUSamplerCube: - case EbtSamplerCubeShadow: - out << ", float3 ddx, float3 ddy"; - break; - default: UNREACHABLE(); - } - } - - switch(textureFunction->method) - { - case TextureFunction::IMPLICIT: break; - case TextureFunction::BIAS: break; // Comes after the offset parameter - case TextureFunction::LOD: out << ", float lod"; break; - case TextureFunction::LOD0: break; - case TextureFunction::LOD0BIAS: break; // Comes after the offset parameter - case TextureFunction::SIZE: break; - case TextureFunction::FETCH: out << ", int mip"; break; - case TextureFunction::GRAD: break; - default: UNREACHABLE(); - } - - if (textureFunction->offset) - { - switch(textureFunction->sampler) - { - case EbtSampler2D: out << ", int2 offset"; break; - case EbtSampler3D: out << ", int3 offset"; break; - case EbtSampler2DArray: out << ", int2 offset"; break; - case EbtISampler2D: out << ", int2 offset"; break; - case EbtISampler3D: out << ", int3 offset"; break; - case EbtISampler2DArray: out << ", int2 offset"; break; - case EbtUSampler2D: out << ", int2 offset"; break; - case EbtUSampler3D: out << ", int3 offset"; break; - case EbtUSampler2DArray: out << ", int2 offset"; break; - case EbtSampler2DShadow: out << ", int2 offset"; break; - case EbtSampler2DArrayShadow: out << ", int2 offset"; break; - default: UNREACHABLE(); - } - } - - if (textureFunction->method == TextureFunction::BIAS || - textureFunction->method == TextureFunction::LOD0BIAS) - { - out << ", float bias"; - } - - out << ")\n" + out << "cbuffer DriverConstants : register(b1)\n" "{\n"; - - // In some cases we use a variable to store the texture/sampler objects, but to work around - // a D3D11 compiler bug related to discard inside a loop that is conditional on texture - // sampling we need to call the function directly on a reference to the array. The bug was - // found using dEQP-GLES3.functional.shaders.discard*loop_texture* tests. - TString textureReference("x"); - TString samplerReference("s"); - if (mOutputType == SH_HLSL_4_1_OUTPUT) + if (mUsesNumWorkGroups) { - TString suffix = TextureGroupSuffix(textureFunction->sampler); - if (TextureGroup(textureFunction->sampler) == HLSL_TEXTURE_2D) - { - textureReference = TString("textures") + suffix + "[samplerIndex]"; - samplerReference = TString("samplers") + suffix + "[samplerIndex]"; - } - else - { - out << " const uint textureIndex = samplerIndex - textureIndexOffset" << suffix - << ";\n"; - textureReference = TString("textures") + suffix + "[textureIndex]"; - out << " const uint samplerArrayIndex = samplerIndex - samplerIndexOffset" - << suffix << ";\n"; - samplerReference = TString("samplers") + suffix + "[samplerArrayIndex]"; - } + out << " uint3 gl_NumWorkGroups : packoffset(c0);\n"; + } + ASSERT(mOutputType == SH_HLSL_4_1_OUTPUT); + mUniformHLSL->samplerMetadataUniforms(out, "c1"); + out << "};\n"; + + // Follow built-in variables would be initialized in + // DynamicHLSL::generateComputeShaderLinkHLSL, if they + // are used in compute shader. + if (mUsesWorkGroupID) + { + out << "static uint3 gl_WorkGroupID = uint3(0, 0, 0);\n"; } - if (textureFunction->method == TextureFunction::SIZE) + if (mUsesLocalInvocationID) { - if (IsSampler2D(textureFunction->sampler) || IsSamplerCube(textureFunction->sampler)) - { - if (IsSamplerArray(textureFunction->sampler)) - { - out << " uint width; uint height; uint layers; uint numberOfLevels;\n" - << " " << textureReference - << ".GetDimensions(lod, width, height, layers, numberOfLevels);\n"; - } - else - { - out << " uint width; uint height; uint numberOfLevels;\n" - << " " << textureReference - << ".GetDimensions(lod, width, height, numberOfLevels);\n"; - } - } - else if (IsSampler3D(textureFunction->sampler)) - { - out << " uint width; uint height; uint depth; uint numberOfLevels;\n" - << " " << textureReference - << ".GetDimensions(lod, width, height, depth, numberOfLevels);\n"; - } - else UNREACHABLE(); - - switch(textureFunction->sampler) - { - case EbtSampler2D: out << " return int2(width, height);"; break; - case EbtSampler3D: out << " return int3(width, height, depth);"; break; - case EbtSamplerCube: out << " return int2(width, height);"; break; - case EbtSampler2DArray: out << " return int3(width, height, layers);"; break; - case EbtISampler2D: out << " return int2(width, height);"; break; - case EbtISampler3D: out << " return int3(width, height, depth);"; break; - case EbtISamplerCube: out << " return int2(width, height);"; break; - case EbtISampler2DArray: out << " return int3(width, height, layers);"; break; - case EbtUSampler2D: out << " return int2(width, height);"; break; - case EbtUSampler3D: out << " return int3(width, height, depth);"; break; - case EbtUSamplerCube: out << " return int2(width, height);"; break; - case EbtUSampler2DArray: out << " return int3(width, height, layers);"; break; - case EbtSampler2DShadow: out << " return int2(width, height);"; break; - case EbtSamplerCubeShadow: out << " return int2(width, height);"; break; - case EbtSampler2DArrayShadow: out << " return int3(width, height, layers);"; break; - default: UNREACHABLE(); - } - } - else - { - if (IsIntegerSampler(textureFunction->sampler) && IsSamplerCube(textureFunction->sampler)) - { - out << " float width; float height; float layers; float levels;\n"; - - out << " uint mip = 0;\n"; - - out << " " << textureReference - << ".GetDimensions(mip, width, height, layers, levels);\n"; - - out << " bool xMajor = abs(t.x) > abs(t.y) && abs(t.x) > abs(t.z);\n"; - out << " bool yMajor = abs(t.y) > abs(t.z) && abs(t.y) > abs(t.x);\n"; - out << " bool zMajor = abs(t.z) > abs(t.x) && abs(t.z) > abs(t.y);\n"; - out << " bool negative = (xMajor && t.x < 0.0f) || (yMajor && t.y < 0.0f) || (zMajor && t.z < 0.0f);\n"; - - // FACE_POSITIVE_X = 000b - // FACE_NEGATIVE_X = 001b - // FACE_POSITIVE_Y = 010b - // FACE_NEGATIVE_Y = 011b - // FACE_POSITIVE_Z = 100b - // FACE_NEGATIVE_Z = 101b - out << " int face = (int)negative + (int)yMajor * 2 + (int)zMajor * 4;\n"; - - out << " float u = xMajor ? -t.z : (yMajor && t.y < 0.0f ? -t.x : t.x);\n"; - out << " float v = yMajor ? t.z : (negative ? t.y : -t.y);\n"; - out << " float m = xMajor ? t.x : (yMajor ? t.y : t.z);\n"; - - out << " t.x = (u * 0.5f / m) + 0.5f;\n"; - out << " t.y = (v * 0.5f / m) + 0.5f;\n"; - - // Mip level computation. - if (textureFunction->method == TextureFunction::IMPLICIT) - { - out << " float2 tSized = float2(t.x * width, t.y * height);\n" - " float2 dx = ddx(tSized);\n" - " float2 dy = ddy(tSized);\n" - " float lod = 0.5f * log2(max(dot(dx, dx), dot(dy, dy)));\n" - " mip = uint(min(max(round(lod), 0), levels - 1));\n" - << " " << textureReference - << ".GetDimensions(mip, width, height, layers, levels);\n"; - } - } - else if (IsIntegerSampler(textureFunction->sampler) && - textureFunction->method != TextureFunction::FETCH) - { - if (IsSampler2D(textureFunction->sampler)) - { - if (IsSamplerArray(textureFunction->sampler)) - { - out << " float width; float height; float layers; float levels;\n"; - - if (textureFunction->method == TextureFunction::LOD0) - { - out << " uint mip = 0;\n"; - } - else if (textureFunction->method == TextureFunction::LOD0BIAS) - { - out << " uint mip = bias;\n"; - } - else - { - - out << " " << textureReference - << ".GetDimensions(0, width, height, layers, levels);\n"; - if (textureFunction->method == TextureFunction::IMPLICIT || - textureFunction->method == TextureFunction::BIAS) - { - out << " float2 tSized = float2(t.x * width, t.y * height);\n" - " float dx = length(ddx(tSized));\n" - " float dy = length(ddy(tSized));\n" - " float lod = log2(max(dx, dy));\n"; - - if (textureFunction->method == TextureFunction::BIAS) - { - out << " lod += bias;\n"; - } - } - else if (textureFunction->method == TextureFunction::GRAD) - { - out << " float lod = log2(max(length(ddx), length(ddy)));\n"; - } - - out << " uint mip = uint(min(max(round(lod), 0), levels - 1));\n"; - } - - out << " " << textureReference - << ".GetDimensions(mip, width, height, layers, levels);\n"; - } - else - { - out << " float width; float height; float levels;\n"; - - if (textureFunction->method == TextureFunction::LOD0) - { - out << " uint mip = 0;\n"; - } - else if (textureFunction->method == TextureFunction::LOD0BIAS) - { - out << " uint mip = bias;\n"; - } - else - { - out << " " << textureReference - << ".GetDimensions(0, width, height, levels);\n"; - - if (textureFunction->method == TextureFunction::IMPLICIT || - textureFunction->method == TextureFunction::BIAS) - { - out << " float2 tSized = float2(t.x * width, t.y * height);\n" - " float dx = length(ddx(tSized));\n" - " float dy = length(ddy(tSized));\n" - " float lod = log2(max(dx, dy));\n"; - - if (textureFunction->method == TextureFunction::BIAS) - { - out << " lod += bias;\n"; - } - } - else if (textureFunction->method == TextureFunction::GRAD) - { - out << " float lod = log2(max(length(ddx), length(ddy)));\n"; - } - - out << " uint mip = uint(min(max(round(lod), 0), levels - 1));\n"; - } - - out << " " << textureReference - << ".GetDimensions(mip, width, height, levels);\n"; - } - } - else if (IsSampler3D(textureFunction->sampler)) - { - out << " float width; float height; float depth; float levels;\n"; - - if (textureFunction->method == TextureFunction::LOD0) - { - out << " uint mip = 0;\n"; - } - else if (textureFunction->method == TextureFunction::LOD0BIAS) - { - out << " uint mip = bias;\n"; - } - else - { - out << " " << textureReference - << ".GetDimensions(0, width, height, depth, levels);\n"; - - if (textureFunction->method == TextureFunction::IMPLICIT || - textureFunction->method == TextureFunction::BIAS) - { - out << " float3 tSized = float3(t.x * width, t.y * height, t.z * " - "depth);\n" - " float dx = length(ddx(tSized));\n" - " float dy = length(ddy(tSized));\n" - " float lod = log2(max(dx, dy));\n"; - - if (textureFunction->method == TextureFunction::BIAS) - { - out << " lod += bias;\n"; - } - } - else if (textureFunction->method == TextureFunction::GRAD) - { - out << " float lod = log2(max(length(ddx), length(ddy)));\n"; - } - - out << " uint mip = uint(min(max(round(lod), 0), levels - 1));\n"; - } - - out << " " << textureReference - << ".GetDimensions(mip, width, height, depth, levels);\n"; - } - else UNREACHABLE(); - } - - out << " return "; - - // HLSL intrinsic - if (mOutputType == SH_HLSL_3_0_OUTPUT) - { - switch(textureFunction->sampler) - { - case EbtSampler2D: out << "tex2D"; break; - case EbtSamplerCube: out << "texCUBE"; break; - default: UNREACHABLE(); - } - - switch(textureFunction->method) - { - case TextureFunction::IMPLICIT: - out << "(" << samplerReference << ", "; - break; - case TextureFunction::BIAS: - out << "bias(" << samplerReference << ", "; - break; - case TextureFunction::LOD: - out << "lod(" << samplerReference << ", "; - break; - case TextureFunction::LOD0: - out << "lod(" << samplerReference << ", "; - break; - case TextureFunction::LOD0BIAS: - out << "lod(" << samplerReference << ", "; - break; - default: UNREACHABLE(); - } - } - else if (mOutputType == SH_HLSL_4_1_OUTPUT || mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT) - { - if (textureFunction->method == TextureFunction::GRAD) - { - if (IsIntegerSampler(textureFunction->sampler)) - { - out << "" << textureReference << ".Load("; - } - else if (IsShadowSampler(textureFunction->sampler)) - { - out << "" << textureReference << ".SampleCmpLevelZero(" << samplerReference - << ", "; - } - else - { - out << "" << textureReference << ".SampleGrad(" << samplerReference << ", "; - } - } - else if (IsIntegerSampler(textureFunction->sampler) || - textureFunction->method == TextureFunction::FETCH) - { - out << "" << textureReference << ".Load("; - } - else if (IsShadowSampler(textureFunction->sampler)) - { - switch(textureFunction->method) - { - case TextureFunction::IMPLICIT: - out << "" << textureReference << ".SampleCmp(" << samplerReference - << ", "; - break; - case TextureFunction::BIAS: - out << "" << textureReference << ".SampleCmp(" << samplerReference - << ", "; - break; - case TextureFunction::LOD: - out << "" << textureReference << ".SampleCmp(" << samplerReference - << ", "; - break; - case TextureFunction::LOD0: - out << "" << textureReference << ".SampleCmpLevelZero(" - << samplerReference << ", "; - break; - case TextureFunction::LOD0BIAS: - out << "" << textureReference << ".SampleCmpLevelZero(" - << samplerReference << ", "; - break; - default: UNREACHABLE(); - } - } - else - { - switch(textureFunction->method) - { - case TextureFunction::IMPLICIT: - out << "" << textureReference << ".Sample(" << samplerReference << ", "; - break; - case TextureFunction::BIAS: - out << "" << textureReference << ".SampleBias(" << samplerReference - << ", "; - break; - case TextureFunction::LOD: - out << "" << textureReference << ".SampleLevel(" << samplerReference - << ", "; - break; - case TextureFunction::LOD0: - out << "" << textureReference << ".SampleLevel(" << samplerReference - << ", "; - break; - case TextureFunction::LOD0BIAS: - out << "" << textureReference << ".SampleLevel(" << samplerReference - << ", "; - break; - default: UNREACHABLE(); - } - } - } - else UNREACHABLE(); - - // Integer sampling requires integer addresses - TString addressx = ""; - TString addressy = ""; - TString addressz = ""; - TString close = ""; - - if (IsIntegerSampler(textureFunction->sampler) || - textureFunction->method == TextureFunction::FETCH) - { - switch(hlslCoords) - { - case 2: out << "int3("; break; - case 3: out << "int4("; break; - default: UNREACHABLE(); - } - - // Convert from normalized floating-point to integer - if (textureFunction->method != TextureFunction::FETCH) - { - addressx = "int(floor(width * frac(("; - addressy = "int(floor(height * frac(("; - - if (IsSamplerArray(textureFunction->sampler)) - { - addressz = "int(max(0, min(layers - 1, floor(0.5 + "; - } - else if (IsSamplerCube(textureFunction->sampler)) - { - addressz = "(((("; - } - else - { - addressz = "int(floor(depth * frac(("; - } - - close = "))))"; - } - } - else - { - switch(hlslCoords) - { - case 2: out << "float2("; break; - case 3: out << "float3("; break; - case 4: out << "float4("; break; - default: UNREACHABLE(); - } - } - - TString proj = ""; // Only used for projected textures - - if (textureFunction->proj) - { - switch(textureFunction->coords) - { - case 3: proj = " / t.z"; break; - case 4: proj = " / t.w"; break; - default: UNREACHABLE(); - } - } - - out << addressx + ("t.x" + proj) + close + ", " + addressy + ("t.y" + proj) + close; - - if (mOutputType == SH_HLSL_3_0_OUTPUT) - { - if (hlslCoords >= 3) - { - if (textureFunction->coords < 3) - { - out << ", 0"; - } - else - { - out << ", t.z" + proj; - } - } - - if (hlslCoords == 4) - { - switch(textureFunction->method) - { - case TextureFunction::BIAS: out << ", bias"; break; - case TextureFunction::LOD: out << ", lod"; break; - case TextureFunction::LOD0: out << ", 0"; break; - case TextureFunction::LOD0BIAS: out << ", bias"; break; - default: UNREACHABLE(); - } - } - - out << "));\n"; - } - else if (mOutputType == SH_HLSL_4_1_OUTPUT || mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT) - { - if (hlslCoords >= 3) - { - if (IsIntegerSampler(textureFunction->sampler) && IsSamplerCube(textureFunction->sampler)) - { - out << ", face"; - } - else - { - out << ", " + addressz + ("t.z" + proj) + close; - } - } - - if (textureFunction->method == TextureFunction::GRAD) - { - if (IsIntegerSampler(textureFunction->sampler)) - { - out << ", mip)"; - } - else if (IsShadowSampler(textureFunction->sampler)) - { - // Compare value - if (textureFunction->proj) - { - // According to ESSL 3.00.4 sec 8.8 p95 on textureProj: - // The resulting third component of P' in the shadow forms is used as Dref - out << "), t.z" << proj; - } - else - { - switch(textureFunction->coords) - { - case 3: out << "), t.z"; break; - case 4: out << "), t.w"; break; - default: UNREACHABLE(); - } - } - } - else - { - out << "), ddx, ddy"; - } - } - else if (IsIntegerSampler(textureFunction->sampler) || - textureFunction->method == TextureFunction::FETCH) - { - out << ", mip)"; - } - else if (IsShadowSampler(textureFunction->sampler)) - { - // Compare value - if (textureFunction->proj) - { - // According to ESSL 3.00.4 sec 8.8 p95 on textureProj: - // The resulting third component of P' in the shadow forms is used as Dref - out << "), t.z" << proj; - } - else - { - switch(textureFunction->coords) - { - case 3: out << "), t.z"; break; - case 4: out << "), t.w"; break; - default: UNREACHABLE(); - } - } - } - else - { - switch(textureFunction->method) - { - case TextureFunction::IMPLICIT: out << ")"; break; - case TextureFunction::BIAS: out << "), bias"; break; - case TextureFunction::LOD: out << "), lod"; break; - case TextureFunction::LOD0: out << "), 0"; break; - case TextureFunction::LOD0BIAS: out << "), bias"; break; - default: UNREACHABLE(); - } - } - - if (textureFunction->offset) - { - out << ", offset"; - } - - out << ");"; - } - else UNREACHABLE(); + out << "static uint3 gl_LocalInvocationID = uint3(0, 0, 0);\n"; } - out << "\n" - "}\n" - "\n"; + if (mUsesGlobalInvocationID) + { + out << "static uint3 gl_GlobalInvocationID = uint3(0, 0, 0);\n"; + } + + if (mUsesLocalInvocationIndex) + { + out << "static uint gl_LocalInvocationIndex = uint(0);\n"; + } } + bool getDimensionsIgnoresBaseLevel = + (mCompileOptions & SH_HLSL_GET_DIMENSIONS_IGNORES_BASE_LEVEL) != 0; + mTextureFunctionHLSL->textureFunctionHeader(out, mOutputType, getDimensionsIgnoresBaseLevel); + mImageFunctionHLSL->imageFunctionHeader(out); + if (mUsesFragCoord) { out << "#define GL_USES_FRAG_COORD\n"; @@ -1385,6 +805,16 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built out << "#define GL_USES_POINT_SIZE\n"; } + if (mHasMultiviewExtensionEnabled) + { + out << "#define GL_ANGLE_MULTIVIEW_ENABLED\n"; + } + + if (mUsesViewID) + { + out << "#define GL_USES_VIEW_ID\n"; + } + if (mUsesFragDepth) { out << "#define GL_USES_FRAG_DEPTH\n"; @@ -1395,6 +825,31 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built out << "#define GL_USES_DEPTH_RANGE\n"; } + if (mUsesNumWorkGroups) + { + out << "#define GL_USES_NUM_WORK_GROUPS\n"; + } + + if (mUsesWorkGroupID) + { + out << "#define GL_USES_WORK_GROUP_ID\n"; + } + + if (mUsesLocalInvocationID) + { + out << "#define GL_USES_LOCAL_INVOCATION_ID\n"; + } + + if (mUsesGlobalInvocationID) + { + out << "#define GL_USES_GLOBAL_INVOCATION_ID\n"; + } + + if (mUsesLocalInvocationIndex) + { + out << "#define GL_USES_LOCAL_INVOCATION_INDEX\n"; + } + if (mUsesXor) { out << "bool xor(bool p, bool q)\n" @@ -1404,7 +859,7 @@ void OutputHLSL::header(TInfoSinkBase &out, const BuiltInFunctionEmulator *built "\n"; } - builtInFunctionEmulator->OutputEmulatedFunctions(out); + builtInFunctionEmulator->outputEmulatedFunctions(out); } void OutputHLSL::visitSymbol(TIntermSymbol *node) @@ -1412,10 +867,9 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node) TInfoSinkBase &out = getInfoSink(); // Handle accessing std140 structs by value - if (mFlaggedStructMappedNames.count(node) > 0) + if (IsInStd140InterfaceBlock(node) && node->getBasicType() == EbtStruct) { - out << mFlaggedStructMappedNames[node]; - return; + out << "map"; } TString name = node->getSymbol(); @@ -1427,25 +881,25 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node) } else { + const TType &nodeType = node->getType(); TQualifier qualifier = node->getQualifier(); + ensureStructDefined(nodeType); + if (qualifier == EvqUniform) { - const TType &nodeType = node->getType(); const TInterfaceBlock *interfaceBlock = nodeType.getInterfaceBlock(); if (interfaceBlock) { - mReferencedInterfaceBlocks[interfaceBlock->name()] = node; + mReferencedUniformBlocks[interfaceBlock->name()] = node; } else { mReferencedUniforms[name] = node; } - ensureStructDefined(nodeType); - - out << DecorateUniform(name, nodeType); + out << DecorateVariableIfNeeded(node->getName()); } else if (qualifier == EvqAttribute || qualifier == EvqVertexIn) { @@ -1456,6 +910,10 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node) { mReferencedVaryings[name] = node; out << Decorate(name); + if (name == "ViewID_OVR") + { + mUsesViewID = true; + } } else if (qualifier == EvqFragmentOut) { @@ -1497,14 +955,44 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node) mUsesInstanceID = true; out << name; } + else if (qualifier == EvqVertexID) + { + mUsesVertexID = true; + out << name; + } else if (name == "gl_FragDepthEXT" || name == "gl_FragDepth") { mUsesFragDepth = true; out << "gl_Depth"; } + else if (qualifier == EvqNumWorkGroups) + { + mUsesNumWorkGroups = true; + out << name; + } + else if (qualifier == EvqWorkGroupID) + { + mUsesWorkGroupID = true; + out << name; + } + else if (qualifier == EvqLocalInvocationID) + { + mUsesLocalInvocationID = true; + out << name; + } + else if (qualifier == EvqGlobalInvocationID) + { + mUsesGlobalInvocationID = true; + out << name; + } + else if (qualifier == EvqLocalInvocationIndex) + { + mUsesLocalInvocationIndex = true; + out << name; + } else { - out << DecorateIfNeeded(node->getName()); + out << DecorateVariableIfNeeded(node->getName()); } } } @@ -1553,315 +1041,372 @@ void OutputHLSL::outputEqual(Visit visit, const TType &type, TOperator op, TInfo } } +void OutputHLSL::outputAssign(Visit visit, const TType &type, TInfoSinkBase &out) +{ + if (type.isArray()) + { + const TString &functionName = addArrayAssignmentFunction(type); + outputTriplet(out, visit, (functionName + "(").c_str(), ", ", ")"); + } + else + { + outputTriplet(out, visit, "(", " = ", ")"); + } +} + +bool OutputHLSL::ancestorEvaluatesToSamplerInStruct() +{ + for (unsigned int n = 0u; getAncestorNode(n) != nullptr; ++n) + { + TIntermNode *ancestor = getAncestorNode(n); + const TIntermBinary *ancestorBinary = ancestor->getAsBinaryNode(); + if (ancestorBinary == nullptr) + { + return false; + } + switch (ancestorBinary->getOp()) + { + case EOpIndexDirectStruct: + { + const TStructure *structure = ancestorBinary->getLeft()->getType().getStruct(); + const TIntermConstantUnion *index = + ancestorBinary->getRight()->getAsConstantUnion(); + const TField *field = structure->fields()[index->getIConst(0)]; + if (IsSampler(field->type()->getBasicType())) + { + return true; + } + break; + } + case EOpIndexDirect: + break; + default: + // Returning a sampler from indirect indexing is not supported. + return false; + } + } + return false; +} + +bool OutputHLSL::visitSwizzle(Visit visit, TIntermSwizzle *node) +{ + TInfoSinkBase &out = getInfoSink(); + if (visit == PostVisit) + { + out << "."; + node->writeOffsetsAsXYZW(&out); + } + return true; +} + bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) { TInfoSinkBase &out = getInfoSink(); - // Handle accessing std140 structs by value - if (mFlaggedStructMappedNames.count(node) > 0) - { - out << mFlaggedStructMappedNames[node]; - return false; - } - switch (node->getOp()) { - case EOpAssign: - if (node->getLeft()->isArray()) - { - TIntermAggregate *rightAgg = node->getRight()->getAsAggregate(); - if (rightAgg != nullptr && rightAgg->isConstructor()) + case EOpComma: + outputTriplet(out, visit, "(", ", ", ")"); + break; + case EOpAssign: + if (node->isArray()) { - const TString &functionName = addArrayConstructIntoFunction(node->getType()); - out << functionName << "("; - node->getLeft()->traverse(this); - TIntermSequence *seq = rightAgg->getSequence(); - for (auto &arrayElement : *seq) + TIntermAggregate *rightAgg = node->getRight()->getAsAggregate(); + if (rightAgg != nullptr && rightAgg->isConstructor()) { - out << ", "; - arrayElement->traverse(this); + const TString &functionName = addArrayConstructIntoFunction(node->getType()); + out << functionName << "("; + node->getLeft()->traverse(this); + TIntermSequence *seq = rightAgg->getSequence(); + for (auto &arrayElement : *seq) + { + out << ", "; + arrayElement->traverse(this); + } + out << ")"; + return false; } - out << ")"; - return false; + // ArrayReturnValueToOutParameter should have eliminated expressions where a + // function call is assigned. + ASSERT(rightAgg == nullptr); } - // ArrayReturnValueToOutParameter should have eliminated expressions where a function call is assigned. - ASSERT(rightAgg == nullptr || rightAgg->getOp() != EOpFunctionCall); - - const TString &functionName = addArrayAssignmentFunction(node->getType()); - outputTriplet(out, visit, (functionName + "(").c_str(), ", ", ")"); - } - else - { - outputTriplet(out, visit, "(", " = ", ")"); - } - break; - case EOpInitialize: - if (visit == PreVisit) - { - // GLSL allows to write things like "float x = x;" where a new variable x is defined - // and the value of an existing variable x is assigned. HLSL uses C semantics (the - // new variable is created before the assignment is evaluated), so we need to convert - // this to "float t = x, x = t;". - - TIntermSymbol *symbolNode = node->getLeft()->getAsSymbolNode(); - ASSERT(symbolNode); - TIntermTyped *expression = node->getRight(); - - // TODO (jmadill): do a 'deep' scan to know if an expression is statically const - if (symbolNode->getQualifier() == EvqGlobal && expression->getQualifier() != EvqConst) + outputAssign(visit, node->getType(), out); + break; + case EOpInitialize: + if (visit == PreVisit) { - // For variables which are not constant, defer their real initialization until - // after we initialize uniforms. - TIntermBinary *deferredInit = new TIntermBinary(EOpAssign); - deferredInit->setLeft(node->getLeft()); - deferredInit->setRight(node->getRight()); - deferredInit->setType(node->getType()); - mDeferredGlobalInitializers.push_back(deferredInit); - const TString &initString = initializer(node->getType()); - node->setRight(new TIntermRaw(node->getType(), initString)); + TIntermSymbol *symbolNode = node->getLeft()->getAsSymbolNode(); + ASSERT(symbolNode); + TIntermTyped *expression = node->getRight(); + + // Global initializers must be constant at this point. + ASSERT(symbolNode->getQualifier() != EvqGlobal || + canWriteAsHLSLLiteral(expression)); + + // GLSL allows to write things like "float x = x;" where a new variable x is defined + // and the value of an existing variable x is assigned. HLSL uses C semantics (the + // new variable is created before the assignment is evaluated), so we need to + // convert + // this to "float t = x, x = t;". + if (writeSameSymbolInitializer(out, symbolNode, expression)) + { + // Skip initializing the rest of the expression + return false; + } + else if (writeConstantInitialization(out, symbolNode, expression)) + { + return false; + } } - else if (writeSameSymbolInitializer(out, symbolNode, expression)) + else if (visit == InVisit) { - // Skip initializing the rest of the expression - return false; + out << " = "; } - else if (writeConstantInitialization(out, symbolNode, expression)) + break; + case EOpAddAssign: + outputTriplet(out, visit, "(", " += ", ")"); + break; + case EOpSubAssign: + outputTriplet(out, visit, "(", " -= ", ")"); + break; + case EOpMulAssign: + outputTriplet(out, visit, "(", " *= ", ")"); + break; + case EOpVectorTimesScalarAssign: + outputTriplet(out, visit, "(", " *= ", ")"); + break; + case EOpMatrixTimesScalarAssign: + outputTriplet(out, visit, "(", " *= ", ")"); + break; + case EOpVectorTimesMatrixAssign: + if (visit == PreVisit) { - return false; + out << "("; } - } - else if (visit == InVisit) + else if (visit == InVisit) + { + out << " = mul("; + node->getLeft()->traverse(this); + out << ", transpose("; + } + else + { + out << ")))"; + } + break; + case EOpMatrixTimesMatrixAssign: + if (visit == PreVisit) + { + out << "("; + } + else if (visit == InVisit) + { + out << " = transpose(mul(transpose("; + node->getLeft()->traverse(this); + out << "), transpose("; + } + else + { + out << "))))"; + } + break; + case EOpDivAssign: + outputTriplet(out, visit, "(", " /= ", ")"); + break; + case EOpIModAssign: + outputTriplet(out, visit, "(", " %= ", ")"); + break; + case EOpBitShiftLeftAssign: + outputTriplet(out, visit, "(", " <<= ", ")"); + break; + case EOpBitShiftRightAssign: + outputTriplet(out, visit, "(", " >>= ", ")"); + break; + case EOpBitwiseAndAssign: + outputTriplet(out, visit, "(", " &= ", ")"); + break; + case EOpBitwiseXorAssign: + outputTriplet(out, visit, "(", " ^= ", ")"); + break; + case EOpBitwiseOrAssign: + outputTriplet(out, visit, "(", " |= ", ")"); + break; + case EOpIndexDirect: { - out << " = "; - } - break; - case EOpAddAssign: - outputTriplet(out, visit, "(", " += ", ")"); - break; - case EOpSubAssign: - outputTriplet(out, visit, "(", " -= ", ")"); - break; - case EOpMulAssign: - outputTriplet(out, visit, "(", " *= ", ")"); - break; - case EOpVectorTimesScalarAssign: - outputTriplet(out, visit, "(", " *= ", ")"); - break; - case EOpMatrixTimesScalarAssign: - outputTriplet(out, visit, "(", " *= ", ")"); - break; - case EOpVectorTimesMatrixAssign: - if (visit == PreVisit) - { - out << "("; - } - else if (visit == InVisit) - { - out << " = mul("; - node->getLeft()->traverse(this); - out << ", transpose("; - } - else - { - out << ")))"; - } - break; - case EOpMatrixTimesMatrixAssign: - if (visit == PreVisit) - { - out << "("; - } - else if (visit == InVisit) - { - out << " = transpose(mul(transpose("; - node->getLeft()->traverse(this); - out << "), transpose("; - } - else - { - out << "))))"; - } - break; - case EOpDivAssign: - outputTriplet(out, visit, "(", " /= ", ")"); - break; - case EOpIModAssign: - outputTriplet(out, visit, "(", " %= ", ")"); - break; - case EOpBitShiftLeftAssign: - outputTriplet(out, visit, "(", " <<= ", ")"); - break; - case EOpBitShiftRightAssign: - outputTriplet(out, visit, "(", " >>= ", ")"); - break; - case EOpBitwiseAndAssign: - outputTriplet(out, visit, "(", " &= ", ")"); - break; - case EOpBitwiseXorAssign: - outputTriplet(out, visit, "(", " ^= ", ")"); - break; - case EOpBitwiseOrAssign: - outputTriplet(out, visit, "(", " |= ", ")"); - break; - case EOpIndexDirect: - { - const TType& leftType = node->getLeft()->getType(); + const TType &leftType = node->getLeft()->getType(); if (leftType.isInterfaceBlock()) { if (visit == PreVisit) { - TInterfaceBlock* interfaceBlock = leftType.getInterfaceBlock(); + TInterfaceBlock *interfaceBlock = leftType.getInterfaceBlock(); const int arrayIndex = node->getRight()->getAsConstantUnion()->getIConst(0); - mReferencedInterfaceBlocks[interfaceBlock->instanceName()] = node->getLeft()->getAsSymbolNode(); - out << mUniformHLSL->interfaceBlockInstanceString(*interfaceBlock, arrayIndex); + mReferencedUniformBlocks[interfaceBlock->instanceName()] = + node->getLeft()->getAsSymbolNode(); + out << mUniformHLSL->uniformBlockInstanceString(*interfaceBlock, arrayIndex); return false; } } + else if (ancestorEvaluatesToSamplerInStruct()) + { + // All parts of an expression that access a sampler in a struct need to use _ as + // separator to access the sampler variable that has been moved out of the struct. + outputTriplet(out, visit, "", "_", ""); + } else { outputTriplet(out, visit, "", "[", "]"); } } break; - case EOpIndexIndirect: - // We do not currently support indirect references to interface blocks - ASSERT(node->getLeft()->getBasicType() != EbtInterfaceBlock); - outputTriplet(out, visit, "", "[", "]"); - break; - case EOpIndexDirectStruct: - if (visit == InVisit) + case EOpIndexIndirect: + // We do not currently support indirect references to interface blocks + ASSERT(node->getLeft()->getBasicType() != EbtInterfaceBlock); + outputTriplet(out, visit, "", "[", "]"); + break; + case EOpIndexDirectStruct: { - const TStructure* structure = node->getLeft()->getType().getStruct(); - const TIntermConstantUnion* index = node->getRight()->getAsConstantUnion(); - const TField* field = structure->fields()[index->getIConst(0)]; - out << "." + DecorateField(field->name(), *structure); + const TStructure *structure = node->getLeft()->getType().getStruct(); + const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion(); + const TField *field = structure->fields()[index->getIConst(0)]; - return false; - } - break; - case EOpIndexDirectInterfaceBlock: - if (visit == InVisit) - { - const TInterfaceBlock* interfaceBlock = node->getLeft()->getType().getInterfaceBlock(); - const TIntermConstantUnion* index = node->getRight()->getAsConstantUnion(); - const TField* field = interfaceBlock->fields()[index->getIConst(0)]; - out << "." + Decorate(field->name()); - - return false; - } - break; - case EOpVectorSwizzle: - if (visit == InVisit) - { - out << "."; - - TIntermAggregate *swizzle = node->getRight()->getAsAggregate(); - - if (swizzle) + // In cases where indexing returns a sampler, we need to access the sampler variable + // that has been moved out of the struct. + bool indexingReturnsSampler = IsSampler(field->type()->getBasicType()); + if (visit == PreVisit && indexingReturnsSampler) { - TIntermSequence *sequence = swizzle->getSequence(); - - for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); sit++) - { - TIntermConstantUnion *element = (*sit)->getAsConstantUnion(); - - if (element) - { - int i = element->getIConst(0); - - switch (i) - { - case 0: out << "x"; break; - case 1: out << "y"; break; - case 2: out << "z"; break; - case 3: out << "w"; break; - default: UNREACHABLE(); - } - } - else UNREACHABLE(); - } + // Samplers extracted from structs have "angle" prefix to avoid name conflicts. + // This prefix is only output at the beginning of the indexing expression, which + // may have multiple parts. + out << "angle"; } - else UNREACHABLE(); + if (!indexingReturnsSampler) + { + // All parts of an expression that access a sampler in a struct need to use _ as + // separator to access the sampler variable that has been moved out of the struct. + indexingReturnsSampler = ancestorEvaluatesToSamplerInStruct(); + } + if (visit == InVisit) + { + if (indexingReturnsSampler) + { + out << "_" + field->name(); + } + else + { + out << "." + DecorateField(field->name(), *structure); + } - return false; // Fully processed + return false; + } } break; - case EOpAdd: - outputTriplet(out, visit, "(", " + ", ")"); - break; - case EOpSub: - outputTriplet(out, visit, "(", " - ", ")"); - break; - case EOpMul: - outputTriplet(out, visit, "(", " * ", ")"); - break; - case EOpDiv: - outputTriplet(out, visit, "(", " / ", ")"); - break; - case EOpIMod: - outputTriplet(out, visit, "(", " % ", ")"); - break; - case EOpBitShiftLeft: - outputTriplet(out, visit, "(", " << ", ")"); - break; - case EOpBitShiftRight: - outputTriplet(out, visit, "(", " >> ", ")"); - break; - case EOpBitwiseAnd: - outputTriplet(out, visit, "(", " & ", ")"); - break; - case EOpBitwiseXor: - outputTriplet(out, visit, "(", " ^ ", ")"); - break; - case EOpBitwiseOr: - outputTriplet(out, visit, "(", " | ", ")"); - break; - case EOpEqual: - case EOpNotEqual: - outputEqual(visit, node->getLeft()->getType(), node->getOp(), out); - break; - case EOpLessThan: - outputTriplet(out, visit, "(", " < ", ")"); - break; - case EOpGreaterThan: - outputTriplet(out, visit, "(", " > ", ")"); - break; - case EOpLessThanEqual: - outputTriplet(out, visit, "(", " <= ", ")"); - break; - case EOpGreaterThanEqual: - outputTriplet(out, visit, "(", " >= ", ")"); - break; - case EOpVectorTimesScalar: - outputTriplet(out, visit, "(", " * ", ")"); - break; - case EOpMatrixTimesScalar: - outputTriplet(out, visit, "(", " * ", ")"); - break; - case EOpVectorTimesMatrix: - outputTriplet(out, visit, "mul(", ", transpose(", "))"); - break; - case EOpMatrixTimesVector: - outputTriplet(out, visit, "mul(transpose(", "), ", ")"); - break; - case EOpMatrixTimesMatrix: - outputTriplet(out, visit, "transpose(mul(transpose(", "), transpose(", ")))"); - break; - case EOpLogicalOr: - // HLSL doesn't short-circuit ||, so we assume that || affected by short-circuiting have been unfolded. - ASSERT(!node->getRight()->hasSideEffects()); - outputTriplet(out, visit, "(", " || ", ")"); - return true; - case EOpLogicalXor: - mUsesXor = true; - outputTriplet(out, visit, "xor(", ", ", ")"); - break; - case EOpLogicalAnd: - // HLSL doesn't short-circuit &&, so we assume that && affected by short-circuiting have been unfolded. - ASSERT(!node->getRight()->hasSideEffects()); - outputTriplet(out, visit, "(", " && ", ")"); - return true; - default: UNREACHABLE(); + case EOpIndexDirectInterfaceBlock: + { + bool structInStd140Block = + node->getBasicType() == EbtStruct && IsInStd140InterfaceBlock(node->getLeft()); + if (visit == PreVisit && structInStd140Block) + { + out << "map"; + } + if (visit == InVisit) + { + const TInterfaceBlock *interfaceBlock = + node->getLeft()->getType().getInterfaceBlock(); + const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion(); + const TField *field = interfaceBlock->fields()[index->getIConst(0)]; + if (structInStd140Block) + { + out << "_"; + } + else + { + out << "."; + } + out << Decorate(field->name()); + + return false; + } + break; + } + case EOpAdd: + outputTriplet(out, visit, "(", " + ", ")"); + break; + case EOpSub: + outputTriplet(out, visit, "(", " - ", ")"); + break; + case EOpMul: + outputTriplet(out, visit, "(", " * ", ")"); + break; + case EOpDiv: + outputTriplet(out, visit, "(", " / ", ")"); + break; + case EOpIMod: + outputTriplet(out, visit, "(", " % ", ")"); + break; + case EOpBitShiftLeft: + outputTriplet(out, visit, "(", " << ", ")"); + break; + case EOpBitShiftRight: + outputTriplet(out, visit, "(", " >> ", ")"); + break; + case EOpBitwiseAnd: + outputTriplet(out, visit, "(", " & ", ")"); + break; + case EOpBitwiseXor: + outputTriplet(out, visit, "(", " ^ ", ")"); + break; + case EOpBitwiseOr: + outputTriplet(out, visit, "(", " | ", ")"); + break; + case EOpEqual: + case EOpNotEqual: + outputEqual(visit, node->getLeft()->getType(), node->getOp(), out); + break; + case EOpLessThan: + outputTriplet(out, visit, "(", " < ", ")"); + break; + case EOpGreaterThan: + outputTriplet(out, visit, "(", " > ", ")"); + break; + case EOpLessThanEqual: + outputTriplet(out, visit, "(", " <= ", ")"); + break; + case EOpGreaterThanEqual: + outputTriplet(out, visit, "(", " >= ", ")"); + break; + case EOpVectorTimesScalar: + outputTriplet(out, visit, "(", " * ", ")"); + break; + case EOpMatrixTimesScalar: + outputTriplet(out, visit, "(", " * ", ")"); + break; + case EOpVectorTimesMatrix: + outputTriplet(out, visit, "mul(", ", transpose(", "))"); + break; + case EOpMatrixTimesVector: + outputTriplet(out, visit, "mul(transpose(", "), ", ")"); + break; + case EOpMatrixTimesMatrix: + outputTriplet(out, visit, "transpose(mul(transpose(", "), transpose(", ")))"); + break; + case EOpLogicalOr: + // HLSL doesn't short-circuit ||, so we assume that || affected by short-circuiting have + // been unfolded. + ASSERT(!node->getRight()->hasSideEffects()); + outputTriplet(out, visit, "(", " || ", ")"); + return true; + case EOpLogicalXor: + mUsesXor = true; + outputTriplet(out, visit, "xor(", ", ", ")"); + break; + case EOpLogicalAnd: + // HLSL doesn't short-circuit &&, so we assume that && affected by short-circuiting have + // been unfolded. + ASSERT(!node->getRight()->hasSideEffects()); + outputTriplet(out, visit, "(", " && ", ")"); + return true; + default: + UNREACHABLE(); } return true; @@ -1879,9 +1424,6 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node) case EOpPositive: outputTriplet(out, visit, "(+", "", ")"); break; - case EOpVectorLogicalNot: - outputTriplet(out, visit, "(!", "", ")"); - break; case EOpLogicalNot: outputTriplet(out, visit, "(!", "", ")"); break; @@ -1933,534 +1475,485 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node) case EOpTanh: outputTriplet(out, visit, "tanh(", "", ")"); break; - case EOpAsinh: - ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(out, visit, "asinh("); - break; - case EOpAcosh: - ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(out, visit, "acosh("); - break; - case EOpAtanh: - ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(out, visit, "atanh("); - break; - case EOpExp: - outputTriplet(out, visit, "exp(", "", ")"); - break; - case EOpLog: - outputTriplet(out, visit, "log(", "", ")"); - break; - case EOpExp2: - outputTriplet(out, visit, "exp2(", "", ")"); - break; - case EOpLog2: - outputTriplet(out, visit, "log2(", "", ")"); - break; - case EOpSqrt: - outputTriplet(out, visit, "sqrt(", "", ")"); - break; - case EOpInverseSqrt: - outputTriplet(out, visit, "rsqrt(", "", ")"); - break; - case EOpAbs: - outputTriplet(out, visit, "abs(", "", ")"); - break; - case EOpSign: - outputTriplet(out, visit, "sign(", "", ")"); - break; - case EOpFloor: - outputTriplet(out, visit, "floor(", "", ")"); - break; - case EOpTrunc: - outputTriplet(out, visit, "trunc(", "", ")"); - break; - case EOpRound: - outputTriplet(out, visit, "round(", "", ")"); - break; - case EOpRoundEven: - ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(out, visit, "roundEven("); - break; - case EOpCeil: - outputTriplet(out, visit, "ceil(", "", ")"); - break; - case EOpFract: - outputTriplet(out, visit, "frac(", "", ")"); - break; - case EOpIsNan: - outputTriplet(out, visit, "isnan(", "", ")"); - mRequiresIEEEStrictCompiling = true; - break; - case EOpIsInf: - outputTriplet(out, visit, "isinf(", "", ")"); - break; - case EOpFloatBitsToInt: - outputTriplet(out, visit, "asint(", "", ")"); - break; - case EOpFloatBitsToUint: - outputTriplet(out, visit, "asuint(", "", ")"); - break; - case EOpIntBitsToFloat: - outputTriplet(out, visit, "asfloat(", "", ")"); - break; - case EOpUintBitsToFloat: - outputTriplet(out, visit, "asfloat(", "", ")"); - break; - case EOpPackSnorm2x16: - ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(out, visit, "packSnorm2x16("); - break; - case EOpPackUnorm2x16: - ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(out, visit, "packUnorm2x16("); - break; - case EOpPackHalf2x16: - ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(out, visit, "packHalf2x16("); - break; - case EOpUnpackSnorm2x16: - ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(out, visit, "unpackSnorm2x16("); - break; - case EOpUnpackUnorm2x16: - ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(out, visit, "unpackUnorm2x16("); - break; - case EOpUnpackHalf2x16: - ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(out, visit, "unpackHalf2x16("); - break; - case EOpLength: - outputTriplet(out, visit, "length(", "", ")"); - break; - case EOpNormalize: - outputTriplet(out, visit, "normalize(", "", ")"); - break; - case EOpDFdx: - if(mInsideDiscontinuousLoop || mOutputLod0Function) - { - outputTriplet(out, visit, "(", "", ", 0.0)"); - } - else - { - outputTriplet(out, visit, "ddx(", "", ")"); - } - break; - case EOpDFdy: - if(mInsideDiscontinuousLoop || mOutputLod0Function) - { - outputTriplet(out, visit, "(", "", ", 0.0)"); - } - else - { - outputTriplet(out, visit, "ddy(", "", ")"); - } - break; - case EOpFwidth: - if(mInsideDiscontinuousLoop || mOutputLod0Function) - { - outputTriplet(out, visit, "(", "", ", 0.0)"); - } - else - { - outputTriplet(out, visit, "fwidth(", "", ")"); - } - break; - case EOpTranspose: - outputTriplet(out, visit, "transpose(", "", ")"); - break; - case EOpDeterminant: - outputTriplet(out, visit, "determinant(transpose(", "", "))"); - break; - case EOpInverse: - ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(out, visit, "inverse("); - break; + case EOpAsinh: + case EOpAcosh: + case EOpAtanh: + ASSERT(node->getUseEmulatedFunction()); + writeEmulatedFunctionTriplet(out, visit, node->getOp()); + break; + case EOpExp: + outputTriplet(out, visit, "exp(", "", ")"); + break; + case EOpLog: + outputTriplet(out, visit, "log(", "", ")"); + break; + case EOpExp2: + outputTriplet(out, visit, "exp2(", "", ")"); + break; + case EOpLog2: + outputTriplet(out, visit, "log2(", "", ")"); + break; + case EOpSqrt: + outputTriplet(out, visit, "sqrt(", "", ")"); + break; + case EOpInverseSqrt: + outputTriplet(out, visit, "rsqrt(", "", ")"); + break; + case EOpAbs: + outputTriplet(out, visit, "abs(", "", ")"); + break; + case EOpSign: + outputTriplet(out, visit, "sign(", "", ")"); + break; + case EOpFloor: + outputTriplet(out, visit, "floor(", "", ")"); + break; + case EOpTrunc: + outputTriplet(out, visit, "trunc(", "", ")"); + break; + case EOpRound: + outputTriplet(out, visit, "round(", "", ")"); + break; + case EOpRoundEven: + ASSERT(node->getUseEmulatedFunction()); + writeEmulatedFunctionTriplet(out, visit, node->getOp()); + break; + case EOpCeil: + outputTriplet(out, visit, "ceil(", "", ")"); + break; + case EOpFract: + outputTriplet(out, visit, "frac(", "", ")"); + break; + case EOpIsNan: + if (node->getUseEmulatedFunction()) + writeEmulatedFunctionTriplet(out, visit, node->getOp()); + else + outputTriplet(out, visit, "isnan(", "", ")"); + mRequiresIEEEStrictCompiling = true; + break; + case EOpIsInf: + outputTriplet(out, visit, "isinf(", "", ")"); + break; + case EOpFloatBitsToInt: + outputTriplet(out, visit, "asint(", "", ")"); + break; + case EOpFloatBitsToUint: + outputTriplet(out, visit, "asuint(", "", ")"); + break; + case EOpIntBitsToFloat: + outputTriplet(out, visit, "asfloat(", "", ")"); + break; + case EOpUintBitsToFloat: + outputTriplet(out, visit, "asfloat(", "", ")"); + break; + case EOpPackSnorm2x16: + case EOpPackUnorm2x16: + case EOpPackHalf2x16: + case EOpUnpackSnorm2x16: + case EOpUnpackUnorm2x16: + case EOpUnpackHalf2x16: + case EOpPackUnorm4x8: + case EOpPackSnorm4x8: + case EOpUnpackUnorm4x8: + case EOpUnpackSnorm4x8: + ASSERT(node->getUseEmulatedFunction()); + writeEmulatedFunctionTriplet(out, visit, node->getOp()); + break; + case EOpLength: + outputTriplet(out, visit, "length(", "", ")"); + break; + case EOpNormalize: + outputTriplet(out, visit, "normalize(", "", ")"); + break; + case EOpDFdx: + if (mInsideDiscontinuousLoop || mOutputLod0Function) + { + outputTriplet(out, visit, "(", "", ", 0.0)"); + } + else + { + outputTriplet(out, visit, "ddx(", "", ")"); + } + break; + case EOpDFdy: + if (mInsideDiscontinuousLoop || mOutputLod0Function) + { + outputTriplet(out, visit, "(", "", ", 0.0)"); + } + else + { + outputTriplet(out, visit, "ddy(", "", ")"); + } + break; + case EOpFwidth: + if (mInsideDiscontinuousLoop || mOutputLod0Function) + { + outputTriplet(out, visit, "(", "", ", 0.0)"); + } + else + { + outputTriplet(out, visit, "fwidth(", "", ")"); + } + break; + case EOpTranspose: + outputTriplet(out, visit, "transpose(", "", ")"); + break; + case EOpDeterminant: + outputTriplet(out, visit, "determinant(transpose(", "", "))"); + break; + case EOpInverse: + ASSERT(node->getUseEmulatedFunction()); + writeEmulatedFunctionTriplet(out, visit, node->getOp()); + break; - case EOpAny: - outputTriplet(out, visit, "any(", "", ")"); - break; - case EOpAll: - outputTriplet(out, visit, "all(", "", ")"); - break; - default: UNREACHABLE(); + case EOpAny: + outputTriplet(out, visit, "any(", "", ")"); + break; + case EOpAll: + outputTriplet(out, visit, "all(", "", ")"); + break; + case EOpLogicalNotComponentWise: + outputTriplet(out, visit, "(!", "", ")"); + break; + case EOpBitfieldReverse: + outputTriplet(out, visit, "reversebits(", "", ")"); + break; + case EOpBitCount: + outputTriplet(out, visit, "countbits(", "", ")"); + break; + case EOpFindLSB: + // Note that it's unclear from the HLSL docs what this returns for 0, but this is tested + // in GLSLTest and results are consistent with GL. + outputTriplet(out, visit, "firstbitlow(", "", ")"); + break; + case EOpFindMSB: + // Note that it's unclear from the HLSL docs what this returns for 0 or -1, but this is + // tested in GLSLTest and results are consistent with GL. + outputTriplet(out, visit, "firstbithigh(", "", ")"); + break; + default: + UNREACHABLE(); } return true; } +TString OutputHLSL::samplerNamePrefixFromStruct(TIntermTyped *node) +{ + if (node->getAsSymbolNode()) + { + return node->getAsSymbolNode()->getSymbol(); + } + TIntermBinary *nodeBinary = node->getAsBinaryNode(); + switch (nodeBinary->getOp()) + { + case EOpIndexDirect: + { + int index = nodeBinary->getRight()->getAsConstantUnion()->getIConst(0); + + TInfoSinkBase prefixSink; + prefixSink << samplerNamePrefixFromStruct(nodeBinary->getLeft()) << "_" << index; + return TString(prefixSink.c_str()); + } + case EOpIndexDirectStruct: + { + const TStructure *s = nodeBinary->getLeft()->getAsTyped()->getType().getStruct(); + int index = nodeBinary->getRight()->getAsConstantUnion()->getIConst(0); + const TField *field = s->fields()[index]; + + TInfoSinkBase prefixSink; + prefixSink << samplerNamePrefixFromStruct(nodeBinary->getLeft()) << "_" + << field->name(); + return TString(prefixSink.c_str()); + } + default: + UNREACHABLE(); + return TString(""); + } +} + +bool OutputHLSL::visitBlock(Visit visit, TIntermBlock *node) +{ + TInfoSinkBase &out = getInfoSink(); + + if (mInsideFunction) + { + outputLineDirective(out, node->getLine().first_line); + out << "{\n"; + } + + for (TIntermNode *statement : *node->getSequence()) + { + outputLineDirective(out, statement->getLine().first_line); + + statement->traverse(this); + + // Don't output ; after case labels, they're terminated by : + // This is needed especially since outputting a ; after a case statement would turn empty + // case statements into non-empty case statements, disallowing fall-through from them. + // Also the output code is clearer if we don't output ; after statements where it is not + // needed: + // * if statements + // * switch statements + // * blocks + // * function definitions + // * loops (do-while loops output the semicolon in VisitLoop) + // * declarations that don't generate output. + if (statement->getAsCaseNode() == nullptr && statement->getAsIfElseNode() == nullptr && + statement->getAsBlock() == nullptr && statement->getAsLoopNode() == nullptr && + statement->getAsSwitchNode() == nullptr && + statement->getAsFunctionDefinition() == nullptr && + (statement->getAsDeclarationNode() == nullptr || + IsDeclarationWrittenOut(statement->getAsDeclarationNode())) && + statement->getAsInvariantDeclarationNode() == nullptr) + { + out << ";\n"; + } + } + + if (mInsideFunction) + { + outputLineDirective(out, node->getLine().last_line); + out << "}\n"; + } + + return false; +} + +bool OutputHLSL::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) +{ + TInfoSinkBase &out = getInfoSink(); + + ASSERT(mCurrentFunctionMetadata == nullptr); + + size_t index = mCallDag.findIndex(node->getFunctionSymbolInfo()); + ASSERT(index != CallDAG::InvalidIndex); + mCurrentFunctionMetadata = &mASTMetadataList[index]; + + out << TypeString(node->getFunctionPrototype()->getType()) << " "; + + TIntermSequence *parameters = node->getFunctionPrototype()->getSequence(); + + if (node->getFunctionSymbolInfo()->isMain()) + { + out << "gl_main("; + } + else + { + out << DecorateFunctionIfNeeded(node->getFunctionSymbolInfo()->getNameObj()) + << DisambiguateFunctionName(parameters) << (mOutputLod0Function ? "Lod0(" : "("); + } + + for (unsigned int i = 0; i < parameters->size(); i++) + { + TIntermSymbol *symbol = (*parameters)[i]->getAsSymbolNode(); + + if (symbol) + { + ensureStructDefined(symbol->getType()); + + out << argumentString(symbol); + + if (i < parameters->size() - 1) + { + out << ", "; + } + } + else + UNREACHABLE(); + } + + out << ")\n"; + + mInsideFunction = true; + // The function body node will output braces. + node->getBody()->traverse(this); + mInsideFunction = false; + + mCurrentFunctionMetadata = nullptr; + + bool needsLod0 = mASTMetadataList[index].mNeedsLod0; + if (needsLod0 && !mOutputLod0Function && mShaderType == GL_FRAGMENT_SHADER) + { + ASSERT(!node->getFunctionSymbolInfo()->isMain()); + mOutputLod0Function = true; + node->traverse(this); + mOutputLod0Function = false; + } + + return false; +} + +bool OutputHLSL::visitDeclaration(Visit visit, TIntermDeclaration *node) +{ + if (visit == PreVisit) + { + TIntermSequence *sequence = node->getSequence(); + TIntermTyped *variable = (*sequence)[0]->getAsTyped(); + ASSERT(sequence->size() == 1); + ASSERT(variable); + + if (IsDeclarationWrittenOut(node)) + { + TInfoSinkBase &out = getInfoSink(); + ensureStructDefined(variable->getType()); + + if (!variable->getAsSymbolNode() || + variable->getAsSymbolNode()->getSymbol() != "") // Variable declaration + { + if (!mInsideFunction) + { + out << "static "; + } + + out << TypeString(variable->getType()) + " "; + + TIntermSymbol *symbol = variable->getAsSymbolNode(); + + if (symbol) + { + symbol->traverse(this); + out << ArrayString(symbol->getType()); + out << " = " + initializer(symbol->getType()); + } + else + { + variable->traverse(this); + } + } + else if (variable->getAsSymbolNode() && + variable->getAsSymbolNode()->getSymbol() == "") // Type (struct) declaration + { + ASSERT(variable->getBasicType() == EbtStruct); + // ensureStructDefined has already been called. + } + else + UNREACHABLE(); + } + else if (IsVaryingOut(variable->getQualifier())) + { + TIntermSymbol *symbol = variable->getAsSymbolNode(); + ASSERT(symbol); // Varying declarations can't have initializers. + + // Vertex outputs which are declared but not written to should still be declared to + // allow successful linking. + mReferencedVaryings[symbol->getSymbol()] = symbol; + } + } + return false; +} + +bool OutputHLSL::visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *node) +{ + // Do not do any translation + return false; +} + +bool OutputHLSL::visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *node) +{ + TInfoSinkBase &out = getInfoSink(); + + ASSERT(visit == PreVisit); + size_t index = mCallDag.findIndex(node->getFunctionSymbolInfo()); + // Skip the prototype if it is not implemented (and thus not used) + if (index == CallDAG::InvalidIndex) + { + return false; + } + + TIntermSequence *arguments = node->getSequence(); + + TString name = DecorateFunctionIfNeeded(node->getFunctionSymbolInfo()->getNameObj()); + out << TypeString(node->getType()) << " " << name << DisambiguateFunctionName(arguments) + << (mOutputLod0Function ? "Lod0(" : "("); + + for (unsigned int i = 0; i < arguments->size(); i++) + { + TIntermSymbol *symbol = (*arguments)[i]->getAsSymbolNode(); + ASSERT(symbol != nullptr); + + out << argumentString(symbol); + + if (i < arguments->size() - 1) + { + out << ", "; + } + } + + out << ");\n"; + + // Also prototype the Lod0 variant if needed + bool needsLod0 = mASTMetadataList[index].mNeedsLod0; + if (needsLod0 && !mOutputLod0Function && mShaderType == GL_FRAGMENT_SHADER) + { + mOutputLod0Function = true; + node->traverse(this); + mOutputLod0Function = false; + } + + return false; +} + bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) { TInfoSinkBase &out = getInfoSink(); switch (node->getOp()) { - case EOpSequence: - { - if (mInsideFunction) - { - outputLineDirective(out, node->getLine().first_line); - out << "{\n"; - } - - for (TIntermSequence::iterator sit = node->getSequence()->begin(); sit != node->getSequence()->end(); sit++) - { - outputLineDirective(out, (*sit)->getLine().first_line); - - (*sit)->traverse(this); - - // Don't output ; after case labels, they're terminated by : - // This is needed especially since outputting a ; after a case statement would turn empty - // case statements into non-empty case statements, disallowing fall-through from them. - // Also no need to output ; after selection (if) statements or sequences. This is done just - // for code clarity. - TIntermSelection *asSelection = (*sit)->getAsSelectionNode(); - ASSERT(asSelection == nullptr || !asSelection->usesTernaryOperator()); - if ((*sit)->getAsCaseNode() == nullptr && asSelection == nullptr && !IsSequence(*sit)) - out << ";\n"; - } - - if (mInsideFunction) - { - outputLineDirective(out, node->getLine().last_line); - out << "}\n"; - } - - return false; - } - case EOpDeclaration: - if (visit == PreVisit) - { - TIntermSequence *sequence = node->getSequence(); - TIntermTyped *variable = (*sequence)[0]->getAsTyped(); - ASSERT(sequence->size() == 1); - - if (variable && - (variable->getQualifier() == EvqTemporary || - variable->getQualifier() == EvqGlobal || variable->getQualifier() == EvqConst)) - { - ensureStructDefined(variable->getType()); - - if (!variable->getAsSymbolNode() || variable->getAsSymbolNode()->getSymbol() != "") // Variable declaration - { - if (!mInsideFunction) - { - out << "static "; - } - - out << TypeString(variable->getType()) + " "; - - TIntermSymbol *symbol = variable->getAsSymbolNode(); - - if (symbol) - { - symbol->traverse(this); - out << ArrayString(symbol->getType()); - out << " = " + initializer(symbol->getType()); - } - else - { - variable->traverse(this); - } - } - else if (variable->getAsSymbolNode() && variable->getAsSymbolNode()->getSymbol() == "") // Type (struct) declaration - { - // Already added to constructor map - } - else UNREACHABLE(); - } - else if (variable && IsVaryingOut(variable->getQualifier())) - { - for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); sit++) - { - TIntermSymbol *symbol = (*sit)->getAsSymbolNode(); - - if (symbol) - { - // Vertex (output) varyings which are declared but not written to should still be declared to allow successful linking - mReferencedVaryings[symbol->getSymbol()] = symbol; - } - else - { - (*sit)->traverse(this); - } - } - } - - return false; - } - else if (visit == InVisit) - { - out << ", "; - } - break; - case EOpInvariantDeclaration: - // Do not do any translation - return false; - case EOpPrototype: - if (visit == PreVisit) - { - size_t index = mCallDag.findIndex(node); - // Skip the prototype if it is not implemented (and thus not used) - if (index == CallDAG::InvalidIndex) - { - return false; - } - - TString name = DecorateFunctionIfNeeded(node->getNameObj()); - out << TypeString(node->getType()) << " " << name - << (mOutputLod0Function ? "Lod0(" : "("); - - TIntermSequence *arguments = node->getSequence(); - - for (unsigned int i = 0; i < arguments->size(); i++) - { - TIntermSymbol *symbol = (*arguments)[i]->getAsSymbolNode(); - - if (symbol) - { - out << argumentString(symbol); - - if (i < arguments->size() - 1) - { - out << ", "; - } - } - else UNREACHABLE(); - } - - out << ");\n"; - - // Also prototype the Lod0 variant if needed - bool needsLod0 = mASTMetadataList[index].mNeedsLod0; - if (needsLod0 && !mOutputLod0Function && mShaderType == GL_FRAGMENT_SHADER) - { - mOutputLod0Function = true; - node->traverse(this); - mOutputLod0Function = false; - } - - return false; - } - break; - case EOpComma: - outputTriplet(out, visit, "(", ", ", ")"); - break; - case EOpFunction: - { - ASSERT(mCurrentFunctionMetadata == nullptr); - TString name = TFunction::unmangleName(node->getNameObj().getString()); - - size_t index = mCallDag.findIndex(node); - ASSERT(index != CallDAG::InvalidIndex); - mCurrentFunctionMetadata = &mASTMetadataList[index]; - - out << TypeString(node->getType()) << " "; - - if (name == "main") - { - out << "gl_main("; - } - else - { - out << DecorateFunctionIfNeeded(node->getNameObj()) - << (mOutputLod0Function ? "Lod0(" : "("); - } - - TIntermSequence *sequence = node->getSequence(); - TIntermSequence *arguments = (*sequence)[0]->getAsAggregate()->getSequence(); - - for (unsigned int i = 0; i < arguments->size(); i++) - { - TIntermSymbol *symbol = (*arguments)[i]->getAsSymbolNode(); - - if (symbol) - { - ensureStructDefined(symbol->getType()); - - out << argumentString(symbol); - - if (i < arguments->size() - 1) - { - out << ", "; - } - } - else UNREACHABLE(); - } - - out << ")\n"; - - if (sequence->size() > 1) - { - mInsideFunction = true; - TIntermNode *body = (*sequence)[1]; - // The function body node will output braces. - ASSERT(IsSequence(body)); - body->traverse(this); - mInsideFunction = false; - } - else - { - out << "{}\n"; - } - - mCurrentFunctionMetadata = nullptr; - - bool needsLod0 = mASTMetadataList[index].mNeedsLod0; - if (needsLod0 && !mOutputLod0Function && mShaderType == GL_FRAGMENT_SHADER) - { - ASSERT(name != "main"); - mOutputLod0Function = true; - node->traverse(this); - mOutputLod0Function = false; - } - - return false; - } - break; - case EOpFunctionCall: + case EOpCallBuiltInFunction: + case EOpCallFunctionInAST: + case EOpCallInternalRawFunction: { TIntermSequence *arguments = node->getSequence(); bool lod0 = mInsideDiscontinuousLoop || mOutputLod0Function; - if (node->isUserDefined()) + if (node->getOp() == EOpCallFunctionInAST) { if (node->isArray()) { UNIMPLEMENTED(); } - size_t index = mCallDag.findIndex(node); + size_t index = mCallDag.findIndex(node->getFunctionSymbolInfo()); ASSERT(index != CallDAG::InvalidIndex); lod0 &= mASTMetadataList[index].mNeedsLod0; - out << DecorateFunctionIfNeeded(node->getNameObj()) << (lod0 ? "Lod0(" : "("); + out << DecorateFunctionIfNeeded(node->getFunctionSymbolInfo()->getNameObj()); + out << DisambiguateFunctionName(node->getSequence()); + out << (lod0 ? "Lod0(" : "("); + } + else if (node->getOp() == EOpCallInternalRawFunction) + { + // This path is used for internal functions that don't have their definitions in the + // AST, such as precision emulation functions. + out << DecorateFunctionIfNeeded(node->getFunctionSymbolInfo()->getNameObj()) << "("; + } + else if (node->getFunctionSymbolInfo()->isImageFunction()) + { + TString name = node->getFunctionSymbolInfo()->getName(); + TType type = (*arguments)[0]->getAsTyped()->getType(); + TString imageFunctionName = mImageFunctionHLSL->useImageFunction( + name, type.getBasicType(), type.getLayoutQualifier().imageInternalFormat, + type.getMemoryQualifier().readonly); + out << imageFunctionName << "("; } else { - TString name = TFunction::unmangleName(node->getNameObj().getString()); + const TString &name = node->getFunctionSymbolInfo()->getName(); TBasicType samplerType = (*arguments)[0]->getAsTyped()->getType().getBasicType(); - - TextureFunction textureFunction; - textureFunction.sampler = samplerType; - textureFunction.coords = (*arguments)[1]->getAsTyped()->getNominalSize(); - textureFunction.method = TextureFunction::IMPLICIT; - textureFunction.proj = false; - textureFunction.offset = false; - - if (name == "texture2D" || name == "textureCube" || name == "texture") + int coords = 0; // textureSize(gsampler2DMS) doesn't have a second argument. + if (arguments->size() > 1) { - textureFunction.method = TextureFunction::IMPLICIT; + coords = (*arguments)[1]->getAsTyped()->getNominalSize(); } - else if (name == "texture2DProj" || name == "textureProj") - { - textureFunction.method = TextureFunction::IMPLICIT; - textureFunction.proj = true; - } - else if (name == "texture2DLod" || name == "textureCubeLod" || name == "textureLod" || - name == "texture2DLodEXT" || name == "textureCubeLodEXT") - { - textureFunction.method = TextureFunction::LOD; - } - else if (name == "texture2DProjLod" || name == "textureProjLod" || name == "texture2DProjLodEXT") - { - textureFunction.method = TextureFunction::LOD; - textureFunction.proj = true; - } - else if (name == "textureSize") - { - textureFunction.method = TextureFunction::SIZE; - } - else if (name == "textureOffset") - { - textureFunction.method = TextureFunction::IMPLICIT; - textureFunction.offset = true; - } - else if (name == "textureProjOffset") - { - textureFunction.method = TextureFunction::IMPLICIT; - textureFunction.offset = true; - textureFunction.proj = true; - } - else if (name == "textureLodOffset") - { - textureFunction.method = TextureFunction::LOD; - textureFunction.offset = true; - } - else if (name == "textureProjLodOffset") - { - textureFunction.method = TextureFunction::LOD; - textureFunction.proj = true; - textureFunction.offset = true; - } - else if (name == "texelFetch") - { - textureFunction.method = TextureFunction::FETCH; - } - else if (name == "texelFetchOffset") - { - textureFunction.method = TextureFunction::FETCH; - textureFunction.offset = true; - } - else if (name == "textureGrad" || name == "texture2DGradEXT") - { - textureFunction.method = TextureFunction::GRAD; - } - else if (name == "textureGradOffset") - { - textureFunction.method = TextureFunction::GRAD; - textureFunction.offset = true; - } - else if (name == "textureProjGrad" || name == "texture2DProjGradEXT" || name == "textureCubeGradEXT") - { - textureFunction.method = TextureFunction::GRAD; - textureFunction.proj = true; - } - else if (name == "textureProjGradOffset") - { - textureFunction.method = TextureFunction::GRAD; - textureFunction.proj = true; - textureFunction.offset = true; - } - else UNREACHABLE(); - - if (textureFunction.method == TextureFunction::IMPLICIT) // Could require lod 0 or have a bias argument - { - unsigned int mandatoryArgumentCount = 2; // All functions have sampler and coordinate arguments - - if (textureFunction.offset) - { - mandatoryArgumentCount++; - } - - bool bias = (arguments->size() > mandatoryArgumentCount); // Bias argument is optional - - if (lod0 || mShaderType == GL_VERTEX_SHADER) - { - if (bias) - { - textureFunction.method = TextureFunction::LOD0BIAS; - } - else - { - textureFunction.method = TextureFunction::LOD0; - } - } - else if (bias) - { - textureFunction.method = TextureFunction::BIAS; - } - } - - mUsesTexture.insert(textureFunction); - - out << textureFunction.name(); + TString textureFunctionName = mTextureFunctionHLSL->useTextureFunction( + name, samplerType, coords, arguments->size(), lod0, mShaderType); + out << textureFunctionName << "("; } for (TIntermSequence::iterator arg = arguments->begin(); arg != arguments->end(); arg++) { - if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT && - IsSampler((*arg)->getAsTyped()->getBasicType())) + TIntermTyped *typedArg = (*arg)->getAsTyped(); + if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT && IsSampler(typedArg->getBasicType())) { out << "texture_"; (*arg)->traverse(this); @@ -2469,6 +1962,29 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) (*arg)->traverse(this); + if (typedArg->getType().isStructureContainingSamplers()) + { + const TType &argType = typedArg->getType(); + TVector samplerSymbols; + TString structName = samplerNamePrefixFromStruct(typedArg); + argType.createSamplerSymbols("angle_" + structName, "", &samplerSymbols, + nullptr, mSymbolTable); + for (const TIntermSymbol *sampler : samplerSymbols) + { + if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT) + { + out << ", texture_" << sampler->getSymbol(); + out << ", sampler_" << sampler->getSymbol(); + } + else + { + // In case of HLSL 4.1+, this symbol is the sampler index, and in case + // of D3D9, it's the sampler variable. + out << ", " + sampler->getSymbol(); + } + } + } + if (arg < arguments->end() - 1) { out << ", "; @@ -2479,160 +1995,79 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) return false; } - break; - case EOpParameters: - outputTriplet(out, visit, "(", ", ", ")\n{\n"); + case EOpConstruct: + outputConstructor(out, visit, node); break; - case EOpConstructFloat: - outputConstructor(out, visit, node->getType(), "vec1", node->getSequence()); - break; - case EOpConstructVec2: - outputConstructor(out, visit, node->getType(), "vec2", node->getSequence()); - break; - case EOpConstructVec3: - outputConstructor(out, visit, node->getType(), "vec3", node->getSequence()); - break; - case EOpConstructVec4: - outputConstructor(out, visit, node->getType(), "vec4", node->getSequence()); - break; - case EOpConstructBool: - outputConstructor(out, visit, node->getType(), "bvec1", node->getSequence()); - break; - case EOpConstructBVec2: - outputConstructor(out, visit, node->getType(), "bvec2", node->getSequence()); - break; - case EOpConstructBVec3: - outputConstructor(out, visit, node->getType(), "bvec3", node->getSequence()); - break; - case EOpConstructBVec4: - outputConstructor(out, visit, node->getType(), "bvec4", node->getSequence()); - break; - case EOpConstructInt: - outputConstructor(out, visit, node->getType(), "ivec1", node->getSequence()); - break; - case EOpConstructIVec2: - outputConstructor(out, visit, node->getType(), "ivec2", node->getSequence()); - break; - case EOpConstructIVec3: - outputConstructor(out, visit, node->getType(), "ivec3", node->getSequence()); - break; - case EOpConstructIVec4: - outputConstructor(out, visit, node->getType(), "ivec4", node->getSequence()); - break; - case EOpConstructUInt: - outputConstructor(out, visit, node->getType(), "uvec1", node->getSequence()); - break; - case EOpConstructUVec2: - outputConstructor(out, visit, node->getType(), "uvec2", node->getSequence()); - break; - case EOpConstructUVec3: - outputConstructor(out, visit, node->getType(), "uvec3", node->getSequence()); - break; - case EOpConstructUVec4: - outputConstructor(out, visit, node->getType(), "uvec4", node->getSequence()); - break; - case EOpConstructMat2: - outputConstructor(out, visit, node->getType(), "mat2", node->getSequence()); - break; - case EOpConstructMat2x3: - outputConstructor(out, visit, node->getType(), "mat2x3", node->getSequence()); - break; - case EOpConstructMat2x4: - outputConstructor(out, visit, node->getType(), "mat2x4", node->getSequence()); - break; - case EOpConstructMat3x2: - outputConstructor(out, visit, node->getType(), "mat3x2", node->getSequence()); - break; - case EOpConstructMat3: - outputConstructor(out, visit, node->getType(), "mat3", node->getSequence()); - break; - case EOpConstructMat3x4: - outputConstructor(out, visit, node->getType(), "mat3x4", node->getSequence()); - break; - case EOpConstructMat4x2: - outputConstructor(out, visit, node->getType(), "mat4x2", node->getSequence()); - break; - case EOpConstructMat4x3: - outputConstructor(out, visit, node->getType(), "mat4x3", node->getSequence()); - break; - case EOpConstructMat4: - outputConstructor(out, visit, node->getType(), "mat4", node->getSequence()); - break; - case EOpConstructStruct: - { - if (node->getType().isArray()) - { - UNIMPLEMENTED(); - } - const TString &structName = StructNameString(*node->getType().getStruct()); - mStructureHLSL->addConstructor(node->getType(), structName, node->getSequence()); - outputTriplet(out, visit, (structName + "_ctor(").c_str(), ", ", ")"); - } - break; - case EOpLessThan: - outputTriplet(out, visit, "(", " < ", ")"); - break; - case EOpGreaterThan: - outputTriplet(out, visit, "(", " > ", ")"); - break; - case EOpLessThanEqual: - outputTriplet(out, visit, "(", " <= ", ")"); - break; - case EOpGreaterThanEqual: - outputTriplet(out, visit, "(", " >= ", ")"); - break; - case EOpVectorEqual: + case EOpEqualComponentWise: outputTriplet(out, visit, "(", " == ", ")"); break; - case EOpVectorNotEqual: + case EOpNotEqualComponentWise: outputTriplet(out, visit, "(", " != ", ")"); break; - case EOpMod: - ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(out, visit, "mod("); - break; - case EOpModf: - outputTriplet(out, visit, "modf(", ", ", ")"); - break; - case EOpPow: - outputTriplet(out, visit, "pow(", ", ", ")"); - break; - case EOpAtan: - ASSERT(node->getSequence()->size() == 2); // atan(x) is a unary operator - ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(out, visit, "atan("); - break; - case EOpMin: - outputTriplet(out, visit, "min(", ", ", ")"); - break; - case EOpMax: - outputTriplet(out, visit, "max(", ", ", ")"); - break; - case EOpClamp: - outputTriplet(out, visit, "clamp(", ", ", ")"); - break; - case EOpMix: + case EOpLessThanComponentWise: + outputTriplet(out, visit, "(", " < ", ")"); + break; + case EOpGreaterThanComponentWise: + outputTriplet(out, visit, "(", " > ", ")"); + break; + case EOpLessThanEqualComponentWise: + outputTriplet(out, visit, "(", " <= ", ")"); + break; + case EOpGreaterThanEqualComponentWise: + outputTriplet(out, visit, "(", " >= ", ")"); + break; + case EOpMod: + ASSERT(node->getUseEmulatedFunction()); + writeEmulatedFunctionTriplet(out, visit, node->getOp()); + break; + case EOpModf: + outputTriplet(out, visit, "modf(", ", ", ")"); + break; + case EOpPow: + outputTriplet(out, visit, "pow(", ", ", ")"); + break; + case EOpAtan: + ASSERT(node->getSequence()->size() == 2); // atan(x) is a unary operator + ASSERT(node->getUseEmulatedFunction()); + writeEmulatedFunctionTriplet(out, visit, node->getOp()); + break; + case EOpMin: + outputTriplet(out, visit, "min(", ", ", ")"); + break; + case EOpMax: + outputTriplet(out, visit, "max(", ", ", ")"); + break; + case EOpClamp: + outputTriplet(out, visit, "clamp(", ", ", ")"); + break; + case EOpMix: { TIntermTyped *lastParamNode = (*(node->getSequence()))[2]->getAsTyped(); if (lastParamNode->getType().getBasicType() == EbtBool) { - // There is no HLSL equivalent for ESSL3 built-in "genType mix (genType x, genType y, genBType a)", + // There is no HLSL equivalent for ESSL3 built-in "genType mix (genType x, genType + // y, genBType a)", // so use emulated version. ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(out, visit, "mix("); + writeEmulatedFunctionTriplet(out, visit, node->getOp()); } else { outputTriplet(out, visit, "lerp(", ", ", ")"); } + break; } - break; case EOpStep: outputTriplet(out, visit, "step(", ", ", ")"); break; case EOpSmoothStep: outputTriplet(out, visit, "smoothstep(", ", ", ")"); break; + case EOpFrexp: + case EOpLdexp: + ASSERT(node->getUseEmulatedFunction()); + writeEmulatedFunctionTriplet(out, visit, node->getOp()); + break; case EOpDistance: outputTriplet(out, visit, "distance(", ", ", ")"); break; @@ -2642,30 +2077,40 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) case EOpCross: outputTriplet(out, visit, "cross(", ", ", ")"); break; - case EOpFaceForward: - ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(out, visit, "faceforward("); - break; - case EOpReflect: - outputTriplet(out, visit, "reflect(", ", ", ")"); - break; - case EOpRefract: - outputTriplet(out, visit, "refract(", ", ", ")"); - break; - case EOpOuterProduct: - ASSERT(node->getUseEmulatedFunction()); - writeEmulatedFunctionTriplet(out, visit, "outerProduct("); - break; - case EOpMul: - outputTriplet(out, visit, "(", " * ", ")"); - break; - default: UNREACHABLE(); + case EOpFaceforward: + ASSERT(node->getUseEmulatedFunction()); + writeEmulatedFunctionTriplet(out, visit, node->getOp()); + break; + case EOpReflect: + outputTriplet(out, visit, "reflect(", ", ", ")"); + break; + case EOpRefract: + outputTriplet(out, visit, "refract(", ", ", ")"); + break; + case EOpOuterProduct: + ASSERT(node->getUseEmulatedFunction()); + writeEmulatedFunctionTriplet(out, visit, node->getOp()); + break; + case EOpMulMatrixComponentWise: + outputTriplet(out, visit, "(", " * ", ")"); + break; + case EOpBitfieldExtract: + case EOpBitfieldInsert: + case EOpUaddCarry: + case EOpUsubBorrow: + case EOpUmulExtended: + case EOpImulExtended: + ASSERT(node->getUseEmulatedFunction()); + writeEmulatedFunctionTriplet(out, visit, node->getOp()); + break; + default: + UNREACHABLE(); } return true; } -void OutputHLSL::writeSelection(TInfoSinkBase &out, TIntermSelection *node) +void OutputHLSL::writeIfElse(TInfoSinkBase &out, TIntermIfElse *node) { out << "if ("; @@ -2680,8 +2125,6 @@ void OutputHLSL::writeSelection(TInfoSinkBase &out, TIntermSelection *node) if (node->getTrueBlock()) { // The trueBlock child node will output braces. - ASSERT(IsSequence(node->getTrueBlock())); - node->getTrueBlock()->traverse(this); // Detect true discard @@ -2702,9 +2145,7 @@ void OutputHLSL::writeSelection(TInfoSinkBase &out, TIntermSelection *node) outputLineDirective(out, node->getFalseBlock()->getLine().first_line); - // Either this is "else if" or the falseBlock child node will output braces. - ASSERT(IsSequence(node->getFalseBlock()) || node->getFalseBlock()->getAsSelectionNode() != nullptr); - + // The falseBlock child node will output braces. node->getFalseBlock()->traverse(this); outputLineDirective(out, node->getFalseBlock()->getLine().first_line); @@ -2720,18 +2161,19 @@ void OutputHLSL::writeSelection(TInfoSinkBase &out, TIntermSelection *node) } } -bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node) +bool OutputHLSL::visitTernary(Visit, TIntermTernary *) +{ + // Ternary ops should have been already converted to something else in the AST. HLSL ternary + // operator doesn't short-circuit, so it's not the same as the GLSL ternary operator. + UNREACHABLE(); + return false; +} + +bool OutputHLSL::visitIfElse(Visit visit, TIntermIfElse *node) { TInfoSinkBase &out = getInfoSink(); - ASSERT(!node->usesTernaryOperator()); - - if (!mInsideFunction) - { - // This is part of unfolded global initialization. - mDeferredGlobalInitializers.push_back(node); - return false; - } + ASSERT(mInsideFunction); // D3D errors when there is a gradient operation in a loop in an unflattened if. if (mShaderType == GL_FRAGMENT_SHADER && mCurrentFunctionMetadata->hasGradientLoop(node)) @@ -2739,7 +2181,7 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node) out << "FLATTEN "; } - writeSelection(out, node); + writeIfElse(out, node); return false; } @@ -2748,17 +2190,13 @@ bool OutputHLSL::visitSwitch(Visit visit, TIntermSwitch *node) { TInfoSinkBase &out = getInfoSink(); - if (node->getStatementList()) + ASSERT(node->getStatementList()); + if (visit == PreVisit) { - node->setStatementList(RemoveSwitchFallThrough::removeFallThrough(node->getStatementList())); - outputTriplet(out, visit, "switch (", ") ", ""); - // The curly braces get written when visiting the statementList aggregate - } - else - { - // No statementList, so it won't output curly braces - outputTriplet(out, visit, "switch (", ") {", "}\n"); + node->setStatementList(RemoveSwitchFallThrough(node->getStatementList(), mPerfDiagnostics)); } + outputTriplet(out, visit, "switch (", ") ", ""); + // The curly braces get written when visiting the statementList block. return true; } @@ -2789,8 +2227,8 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node) mNestedLoopDepth++; bool wasDiscontinuous = mInsideDiscontinuousLoop; - mInsideDiscontinuousLoop = mInsideDiscontinuousLoop || - mCurrentFunctionMetadata->mDiscontinuousLoops.count(node) > 0; + mInsideDiscontinuousLoop = + mInsideDiscontinuousLoop || mCurrentFunctionMetadata->mDiscontinuousLoops.count(node) > 0; TInfoSinkBase &out = getInfoSink(); @@ -2843,7 +2281,6 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node) if (node->getBody()) { // The loop body node will output braces. - ASSERT(IsSequence(node->getBody())); node->getBody()->traverse(this); } else @@ -2858,11 +2295,11 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node) if (node->getType() == ELoopDoWhile) { outputLineDirective(out, node->getCondition()->getLine().first_line); - out << "while(\n"; + out << "while ("; node->getCondition()->traverse(this); - out << ");"; + out << ");\n"; } out << "}\n"; @@ -2875,89 +2312,47 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node) bool OutputHLSL::visitBranch(Visit visit, TIntermBranch *node) { - TInfoSinkBase &out = getInfoSink(); - - switch (node->getFlowOp()) + if (visit == PreVisit) { - case EOpKill: - outputTriplet(out, visit, "discard;\n", "", ""); - break; - case EOpBreak: - if (visit == PreVisit) - { - if (mNestedLoopDepth > 1) - { - mUsesNestedBreak = true; - } + TInfoSinkBase &out = getInfoSink(); - if (mExcessiveLoopIndex) - { - out << "{Break"; - mExcessiveLoopIndex->traverse(this); - out << " = true; break;}\n"; - } - else - { - out << "break;\n"; - } - } - break; - case EOpContinue: - outputTriplet(out, visit, "continue;\n", "", ""); - break; - case EOpReturn: - if (visit == PreVisit) + switch (node->getFlowOp()) { - if (node->getExpression()) - { - out << "return "; - } - else - { - out << "return;\n"; - } - } - else if (visit == PostVisit) - { - if (node->getExpression()) - { - out << ";\n"; - } - } - break; - default: UNREACHABLE(); - } - - return true; -} - -bool OutputHLSL::isSingleStatement(TIntermNode *node) -{ - TIntermAggregate *aggregate = node->getAsAggregate(); - - if (aggregate) - { - if (aggregate->getOp() == EOpSequence) - { - return false; - } - else if (aggregate->getOp() == EOpDeclaration) - { - // Declaring multiple comma-separated variables must be considered multiple statements - // because each individual declaration has side effects which are visible in the next. - return false; - } - else - { - for (TIntermSequence::iterator sit = aggregate->getSequence()->begin(); sit != aggregate->getSequence()->end(); sit++) - { - if (!isSingleStatement(*sit)) + case EOpKill: + out << "discard"; + break; + case EOpBreak: + if (mNestedLoopDepth > 1) { - return false; + mUsesNestedBreak = true; } - } - return true; + if (mExcessiveLoopIndex) + { + out << "{Break"; + mExcessiveLoopIndex->traverse(this); + out << " = true; break;}\n"; + } + else + { + out << "break"; + } + break; + case EOpContinue: + out << "continue"; + break; + case EOpReturn: + if (node->getExpression()) + { + out << "return "; + } + else + { + out << "return"; + } + break; + default: + UNREACHABLE(); } } @@ -2965,28 +2360,29 @@ bool OutputHLSL::isSingleStatement(TIntermNode *node) } // Handle loops with more than 254 iterations (unsupported by D3D9) by splitting them -// (The D3D documentation says 255 iterations, but the compiler complains at anything more than 254). +// (The D3D documentation says 255 iterations, but the compiler complains at anything more than +// 254). bool OutputHLSL::handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node) { const int MAX_LOOP_ITERATIONS = 254; // Parse loops of the form: // for(int index = initial; index [comparator] limit; index += increment) - TIntermSymbol *index = NULL; + TIntermSymbol *index = nullptr; TOperator comparator = EOpNull; - int initial = 0; - int limit = 0; - int increment = 0; + int initial = 0; + int limit = 0; + int increment = 0; // Parse index name and intial value if (node->getInit()) { - TIntermAggregate *init = node->getInit()->getAsAggregate(); + TIntermDeclaration *init = node->getInit()->getAsDeclarationNode(); if (init) { TIntermSequence *sequence = init->getSequence(); - TIntermTyped *variable = (*sequence)[0]->getAsTyped(); + TIntermTyped *variable = (*sequence)[0]->getAsTyped(); if (variable && variable->getQualifier() == EvqTemporary) { @@ -2994,14 +2390,14 @@ bool OutputHLSL::handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node) if (assign->getOp() == EOpInitialize) { - TIntermSymbol *symbol = assign->getLeft()->getAsSymbolNode(); + TIntermSymbol *symbol = assign->getLeft()->getAsSymbolNode(); TIntermConstantUnion *constant = assign->getRight()->getAsConstantUnion(); if (symbol && constant) { if (constant->getBasicType() == EbtInt && constant->isScalar()) { - index = symbol; + index = symbol; initial = constant->getIConst(0); } } @@ -3011,7 +2407,7 @@ bool OutputHLSL::handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node) } // Parse comparator and limit value - if (index != NULL && node->getCondition()) + if (index != nullptr && node->getCondition()) { TIntermBinary *test = node->getCondition()->getAsBinaryNode(); @@ -3024,21 +2420,21 @@ bool OutputHLSL::handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node) if (constant->getBasicType() == EbtInt && constant->isScalar()) { comparator = test->getOp(); - limit = constant->getIConst(0); + limit = constant->getIConst(0); } } } } // Parse increment - if (index != NULL && comparator != EOpNull && node->getExpression()) + if (index != nullptr && comparator != EOpNull && node->getExpression()) { TIntermBinary *binaryTerminal = node->getExpression()->getAsBinaryNode(); - TIntermUnary *unaryTerminal = node->getExpression()->getAsUnaryNode(); + TIntermUnary *unaryTerminal = node->getExpression()->getAsUnaryNode(); if (binaryTerminal) { - TOperator op = binaryTerminal->getOp(); + TOperator op = binaryTerminal->getOp(); TIntermConstantUnion *constant = binaryTerminal->getRight()->getAsConstantUnion(); if (constant) @@ -3049,9 +2445,14 @@ bool OutputHLSL::handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node) switch (op) { - case EOpAddAssign: increment = value; break; - case EOpSubAssign: increment = -value; break; - default: UNIMPLEMENTED(); + case EOpAddAssign: + increment = value; + break; + case EOpSubAssign: + increment = -value; + break; + default: + UNIMPLEMENTED(); } } } @@ -3062,16 +2463,25 @@ bool OutputHLSL::handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node) switch (op) { - case EOpPostIncrement: increment = 1; break; - case EOpPostDecrement: increment = -1; break; - case EOpPreIncrement: increment = 1; break; - case EOpPreDecrement: increment = -1; break; - default: UNIMPLEMENTED(); + case EOpPostIncrement: + increment = 1; + break; + case EOpPostDecrement: + increment = -1; + break; + case EOpPreIncrement: + increment = 1; + break; + case EOpPreDecrement: + increment = -1; + break; + default: + UNIMPLEMENTED(); } } } - if (index != NULL && comparator != EOpNull && increment != 0) + if (index != nullptr && comparator != EOpNull && increment != 0) { if (comparator == EOpLessThanEqual) { @@ -3085,11 +2495,11 @@ bool OutputHLSL::handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node) if (iterations <= MAX_LOOP_ITERATIONS) { - return false; // Not an excessive loop + return false; // Not an excessive loop } TIntermSymbol *restoreIndex = mExcessiveLoopIndex; - mExcessiveLoopIndex = index; + mExcessiveLoopIndex = index; out << "{int "; index->traverse(this); @@ -3111,13 +2521,14 @@ bool OutputHLSL::handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node) out << ") {\n"; } - if (iterations <= MAX_LOOP_ITERATIONS) // Last loop fragment + if (iterations <= MAX_LOOP_ITERATIONS) // Last loop fragment { - mExcessiveLoopIndex = NULL; // Stops setting the Break flag + mExcessiveLoopIndex = nullptr; // Stops setting the Break flag } // for(int index = initial; index < clampedLimit; index += increment) - const char *unroll = mCurrentFunctionMetadata->hasGradientInCallGraph(node) ? "LOOP" : ""; + const char *unroll = + mCurrentFunctionMetadata->hasGradientInCallGraph(node) ? "LOOP" : ""; out << unroll << " for("; index->traverse(this); @@ -3163,10 +2574,11 @@ bool OutputHLSL::handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node) return true; } - else UNIMPLEMENTED(); + else + UNIMPLEMENTED(); } - return false; // Not handled as an excessive loop + return false; // Not handled as an excessive loop } void OutputHLSL::outputTriplet(TInfoSinkBase &out, @@ -3218,7 +2630,7 @@ TString OutputHLSL::argumentString(const TIntermSymbol *symbol) } else { - nameStr = DecorateIfNeeded(name); + nameStr = DecorateVariableIfNeeded(name); } if (IsSampler(type.getBasicType())) @@ -3238,7 +2650,44 @@ TString OutputHLSL::argumentString(const TIntermSymbol *symbol) } } - return QualifierString(qualifier) + " " + TypeString(type) + " " + nameStr + ArrayString(type); + TStringStream argString; + argString << QualifierString(qualifier) << " " << TypeString(type) << " " << nameStr + << ArrayString(type); + + // If the structure parameter contains samplers, they need to be passed into the function as + // separate parameters. HLSL doesn't natively support samplers in structs. + if (type.isStructureContainingSamplers()) + { + ASSERT(qualifier != EvqOut && qualifier != EvqInOut); + TVector samplerSymbols; + type.createSamplerSymbols("angle" + nameStr, "", &samplerSymbols, nullptr, mSymbolTable); + for (const TIntermSymbol *sampler : samplerSymbols) + { + const TType &samplerType = sampler->getType(); + if (mOutputType == SH_HLSL_4_1_OUTPUT) + { + argString << ", const uint " << sampler->getSymbol() << ArrayString(samplerType); + } + else if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT) + { + ASSERT(IsSampler(samplerType.getBasicType())); + argString << ", " << QualifierString(qualifier) << " " + << TextureString(samplerType.getBasicType()) << " texture_" + << sampler->getSymbol() << ArrayString(samplerType) << ", " + << QualifierString(qualifier) << " " + << SamplerString(samplerType.getBasicType()) << " sampler_" + << sampler->getSymbol() << ArrayString(samplerType); + } + else + { + ASSERT(IsSampler(samplerType.getBasicType())); + argString << ", " << QualifierString(qualifier) << " " << TypeString(samplerType) + << " " << sampler->getSymbol() << ArrayString(samplerType); + } + } + } + + return argString.str(); } TString OutputHLSL::initializer(const TType &type) @@ -3259,22 +2708,24 @@ TString OutputHLSL::initializer(const TType &type) return "{" + string + "}"; } -void OutputHLSL::outputConstructor(TInfoSinkBase &out, - Visit visit, - const TType &type, - const char *name, - const TIntermSequence *parameters) +void OutputHLSL::outputConstructor(TInfoSinkBase &out, Visit visit, TIntermAggregate *node) { - if (type.isArray()) - { - UNIMPLEMENTED(); - } + // Array constructors should have been already pruned from the code. + ASSERT(!node->getType().isArray()); if (visit == PreVisit) { - mStructureHLSL->addConstructor(type, name, parameters); - - out << name << "("; + TString constructorName; + if (node->getBasicType() == EbtStruct) + { + constructorName = mStructureHLSL->addStructConstructor(*node->getType().getStruct()); + } + else + { + constructorName = + mStructureHLSL->addBuiltInConstructor(node->getType(), node->getSequence()); + } + out << constructorName << "("; } else if (visit == InVisit) { @@ -3292,12 +2743,12 @@ const TConstantUnion *OutputHLSL::writeConstantUnion(TInfoSinkBase &out, { const TConstantUnion *constUnionIterated = constUnion; - const TStructure* structure = type.getStruct(); + const TStructure *structure = type.getStruct(); if (structure) { - out << StructNameString(*structure) + "_ctor("; + out << mStructureHLSL->addStructConstructor(*structure) << "("; - const TFieldList& fields = structure->fields(); + const TFieldList &fields = structure->fields(); for (size_t i = 0; i < fields.size(); i++) { @@ -3314,14 +2765,14 @@ const TConstantUnion *OutputHLSL::writeConstantUnion(TInfoSinkBase &out, } else { - size_t size = type.getObjectSize(); + size_t size = type.getObjectSize(); bool writeType = size > 1; if (writeType) { out << TypeString(type) << "("; } - constUnionIterated = WriteConstantUnionArray(out, constUnionIterated, size); + constUnionIterated = writeConstantUnionArray(out, constUnionIterated, size); if (writeType) { out << ")"; @@ -3331,13 +2782,23 @@ const TConstantUnion *OutputHLSL::writeConstantUnion(TInfoSinkBase &out, return constUnionIterated; } -void OutputHLSL::writeEmulatedFunctionTriplet(TInfoSinkBase &out, Visit visit, const char *preStr) +void OutputHLSL::writeEmulatedFunctionTriplet(TInfoSinkBase &out, Visit visit, TOperator op) { - TString preString = BuiltInFunctionEmulator::GetEmulatedFunctionName(preStr); - outputTriplet(out, visit, preString.c_str(), ", ", ")"); + if (visit == PreVisit) + { + const char *opStr = GetOperatorString(op); + BuiltInFunctionEmulator::WriteEmulatedFunctionName(out, opStr); + out << "("; + } + else + { + outputTriplet(out, visit, nullptr, ", ", ")"); + } } -bool OutputHLSL::writeSameSymbolInitializer(TInfoSinkBase &out, TIntermSymbol *symbolNode, TIntermTyped *expression) +bool OutputHLSL::writeSameSymbolInitializer(TInfoSinkBase &out, + TIntermSymbol *symbolNode, + TIntermTyped *expression) { sh::SearchSymbol searchSymbol(symbolNode->getSymbol()); expression->traverse(&searchSymbol); @@ -3362,52 +2823,40 @@ bool OutputHLSL::canWriteAsHLSLLiteral(TIntermTyped *expression) { // We support writing constant unions and constructors that only take constant unions as // parameters as HLSL literals. - if (expression->getAsConstantUnion()) - { - return true; - } - if (expression->getQualifier() != EvqConst || !expression->getAsAggregate() || - !expression->getAsAggregate()->isConstructor()) - { - return false; - } - TIntermAggregate *constructor = expression->getAsAggregate(); - for (TIntermNode *&node : *constructor->getSequence()) - { - if (!node->getAsConstantUnion()) - return false; - } - return true; + return !expression->getType().isArrayOfArrays() && + (expression->getAsConstantUnion() || + expression->isConstructorWithOnlyConstantUnionParameters()); } bool OutputHLSL::writeConstantInitialization(TInfoSinkBase &out, TIntermSymbol *symbolNode, - TIntermTyped *expression) + TIntermTyped *initializer) { - if (canWriteAsHLSLLiteral(expression)) + if (canWriteAsHLSLLiteral(initializer)) { symbolNode->traverse(this); - if (expression->getType().isArray()) + ASSERT(!symbolNode->getType().isArrayOfArrays()); + if (symbolNode->getType().isArray()) { - out << "[" << expression->getType().getArraySize() << "]"; + out << "[" << symbolNode->getType().getOutermostArraySize() << "]"; } out << " = {"; - if (expression->getAsConstantUnion()) + if (initializer->getAsConstantUnion()) { - TIntermConstantUnion *nodeConst = expression->getAsConstantUnion(); + TIntermConstantUnion *nodeConst = initializer->getAsConstantUnion(); const TConstantUnion *constUnion = nodeConst->getUnionArrayPointer(); - WriteConstantUnionArray(out, constUnion, nodeConst->getType().getObjectSize()); + writeConstantUnionArray(out, constUnion, nodeConst->getType().getObjectSize()); } else { - TIntermAggregate *constructor = expression->getAsAggregate(); + TIntermAggregate *constructor = initializer->getAsAggregate(); ASSERT(constructor != nullptr); for (TIntermNode *&node : *constructor->getSequence()) { TIntermConstantUnion *nodeConst = node->getAsConstantUnion(); ASSERT(nodeConst); const TConstantUnion *constUnion = nodeConst->getUnionArrayPointer(); - WriteConstantUnionArray(out, constUnion, nodeConst->getType().getObjectSize()); + writeConstantUnionArray(out, constUnion, nodeConst->getType().getObjectSize()); if (node != constructor->getSequence()->back()) { out << ", "; @@ -3420,47 +2869,6 @@ bool OutputHLSL::writeConstantInitialization(TInfoSinkBase &out, return false; } -void OutputHLSL::writeDeferredGlobalInitializers(TInfoSinkBase &out) -{ - out << "#define ANGLE_USES_DEFERRED_INIT\n" - << "\n" - << "void initializeDeferredGlobals()\n" - << "{\n"; - - for (const auto &deferredGlobal : mDeferredGlobalInitializers) - { - TIntermBinary *binary = deferredGlobal->getAsBinaryNode(); - TIntermSelection *selection = deferredGlobal->getAsSelectionNode(); - if (binary != nullptr) - { - TIntermSymbol *symbol = binary->getLeft()->getAsSymbolNode(); - TIntermTyped *expression = binary->getRight(); - ASSERT(symbol); - ASSERT(symbol->getQualifier() == EvqGlobal && expression->getQualifier() != EvqConst); - - out << " " << Decorate(symbol->getSymbol()) << " = "; - - if (!writeSameSymbolInitializer(out, symbol, expression)) - { - ASSERT(mInfoSinkStack.top() == &out); - expression->traverse(this); - } - out << ";\n"; - } - else if (selection != nullptr) - { - writeSelection(out, selection); - } - else - { - UNREACHABLE(); - } - } - - out << "}\n" - << "\n"; -} - TString OutputHLSL::addStructEqualityFunction(const TStructure &structure) { const TFieldList &fields = structure.fields(); @@ -3476,18 +2884,19 @@ TString OutputHLSL::addStructEqualityFunction(const TStructure &structure) const TString &structNameString = StructNameString(structure); StructEqualityFunction *function = new StructEqualityFunction(); - function->structure = &structure; - function->functionName = "angle_eq_" + structNameString; + function->structure = &structure; + function->functionName = "angle_eq_" + structNameString; TInfoSinkBase fnOut; - fnOut << "bool " << function->functionName << "(" << structNameString << " a, " << structNameString + " b)\n" + fnOut << "bool " << function->functionName << "(" << structNameString << " a, " + << structNameString + " b)\n" << "{\n" " return "; for (size_t i = 0; i < fields.size(); i++) { - const TField *field = fields[i]; + const TField *field = fields[i]; const TType *fieldType = field->type(); const TString &fieldNameA = "a." + Decorate(field->name()); @@ -3507,7 +2916,8 @@ TString OutputHLSL::addStructEqualityFunction(const TStructure &structure) fnOut << ")"; } - fnOut << ";\n" << "}\n"; + fnOut << ";\n" + << "}\n"; function->functionDefinition = fnOut.c_str(); @@ -3517,7 +2927,7 @@ TString OutputHLSL::addStructEqualityFunction(const TStructure &structure) return function->functionName; } -TString OutputHLSL::addArrayEqualityFunction(const TType& type) +TString OutputHLSL::addArrayEqualityFunction(const TType &type) { for (const auto &eqFunction : mArrayEqualityFunctions) { @@ -3527,33 +2937,31 @@ TString OutputHLSL::addArrayEqualityFunction(const TType& type) } } - const TString &typeName = TypeString(type); + TType elementType(type); + elementType.toArrayElementType(); ArrayHelperFunction *function = new ArrayHelperFunction(); - function->type = type; + function->type = type; - TInfoSinkBase fnNameOut; - fnNameOut << "angle_eq_" << type.getArraySize() << "_" << typeName; - function->functionName = fnNameOut.c_str(); - - TType nonArrayType = type; - nonArrayType.clearArrayness(); + function->functionName = ArrayHelperFunctionName("angle_eq", type); TInfoSinkBase fnOut; - fnOut << "bool " << function->functionName << "(" - << typeName << " a[" << type.getArraySize() << "], " - << typeName << " b[" << type.getArraySize() << "])\n" + const TString &typeName = TypeString(type); + fnOut << "bool " << function->functionName << "(" << typeName << " a" << ArrayString(type) + << ", " << typeName << " b" << ArrayString(type) << ")\n" << "{\n" - " for (int i = 0; i < " << type.getArraySize() << "; ++i)\n" + " for (int i = 0; i < " + << type.getOutermostArraySize() + << "; ++i)\n" " {\n" " if ("; - outputEqual(PreVisit, nonArrayType, EOpNotEqual, fnOut); + outputEqual(PreVisit, elementType, EOpNotEqual, fnOut); fnOut << "a[i]"; - outputEqual(InVisit, nonArrayType, EOpNotEqual, fnOut); + outputEqual(InVisit, elementType, EOpNotEqual, fnOut); fnOut << "b[i]"; - outputEqual(PostVisit, nonArrayType, EOpNotEqual, fnOut); + outputEqual(PostVisit, elementType, EOpNotEqual, fnOut); fnOut << ") { return false; }\n" " }\n" @@ -3568,7 +2976,7 @@ TString OutputHLSL::addArrayEqualityFunction(const TType& type) return function->functionName; } -TString OutputHLSL::addArrayAssignmentFunction(const TType& type) +TString OutputHLSL::addArrayAssignmentFunction(const TType &type) { for (const auto &assignFunction : mArrayAssignmentFunctions) { @@ -3578,26 +2986,35 @@ TString OutputHLSL::addArrayAssignmentFunction(const TType& type) } } - const TString &typeName = TypeString(type); + TType elementType(type); + elementType.toArrayElementType(); ArrayHelperFunction function; function.type = type; - TInfoSinkBase fnNameOut; - fnNameOut << "angle_assign_" << type.getArraySize() << "_" << typeName; - function.functionName = fnNameOut.c_str(); + function.functionName = ArrayHelperFunctionName("angle_assign", type); TInfoSinkBase fnOut; - fnOut << "void " << function.functionName << "(out " - << typeName << " a[" << type.getArraySize() << "], " - << typeName << " b[" << type.getArraySize() << "])\n" - << "{\n" - " for (int i = 0; i < " << type.getArraySize() << "; ++i)\n" - " {\n" - " a[i] = b[i];\n" - " }\n" - "}\n"; + const TString &typeName = TypeString(type); + fnOut << "void " << function.functionName << "(out " << typeName << " a" << ArrayString(type) + << ", " << typeName << " b" << ArrayString(type) << ")\n" + << "{\n" + " for (int i = 0; i < " + << type.getOutermostArraySize() + << "; ++i)\n" + " {\n" + " "; + + outputAssign(PreVisit, elementType, fnOut); + fnOut << "a[i]"; + outputAssign(InVisit, elementType, fnOut); + fnOut << "b[i]"; + outputAssign(PostVisit, elementType, fnOut); + + fnOut << ";\n" + " }\n" + "}\n"; function.functionDefinition = fnOut.c_str(); @@ -3606,7 +3023,7 @@ TString OutputHLSL::addArrayAssignmentFunction(const TType& type) return function.functionName; } -TString OutputHLSL::addArrayConstructIntoFunction(const TType& type) +TString OutputHLSL::addArrayConstructIntoFunction(const TType &type) { for (const auto &constructIntoFunction : mArrayConstructIntoFunctions) { @@ -3616,29 +3033,34 @@ TString OutputHLSL::addArrayConstructIntoFunction(const TType& type) } } - const TString &typeName = TypeString(type); + TType elementType(type); + elementType.toArrayElementType(); ArrayHelperFunction function; function.type = type; - TInfoSinkBase fnNameOut; - fnNameOut << "angle_construct_into_" << type.getArraySize() << "_" << typeName; - function.functionName = fnNameOut.c_str(); + function.functionName = ArrayHelperFunctionName("angle_construct_into", type); TInfoSinkBase fnOut; - fnOut << "void " << function.functionName << "(out " - << typeName << " a[" << type.getArraySize() << "]"; - for (int i = 0; i < type.getArraySize(); ++i) + const TString &typeName = TypeString(type); + fnOut << "void " << function.functionName << "(out " << typeName << " a" << ArrayString(type); + for (unsigned int i = 0u; i < type.getOutermostArraySize(); ++i) { - fnOut << ", " << typeName << " b" << i; + fnOut << ", " << typeName << " b" << i << ArrayString(elementType); } fnOut << ")\n" "{\n"; - for (int i = 0; i < type.getArraySize(); ++i) + for (unsigned int i = 0u; i < type.getOutermostArraySize(); ++i) { - fnOut << " a[" << i << "] = b" << i << ";\n"; + fnOut << " "; + outputAssign(PreVisit, elementType, fnOut); + fnOut << "a[" << i << "]"; + outputAssign(InVisit, elementType, fnOut); + fnOut << "b" << i; + outputAssign(PostVisit, elementType, fnOut); + fnOut << ";\n"; } fnOut << "}\n"; @@ -3651,14 +3073,12 @@ TString OutputHLSL::addArrayConstructIntoFunction(const TType& type) void OutputHLSL::ensureStructDefined(const TType &type) { - TStructure *structure = type.getStruct(); - + const TStructure *structure = type.getStruct(); if (structure) { - mStructureHLSL->addConstructor(type, StructNameString(*structure), nullptr); + ASSERT(type.getBasicType() == EbtStruct); + mStructureHLSL->ensureStructDefined(*structure); } } - - -} +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/OutputHLSL.h b/src/3rdparty/angle/src/compiler/translator/OutputHLSL.h index 8756d0ba4c..014f4f5002 100644 --- a/src/3rdparty/angle/src/compiler/translator/OutputHLSL.h +++ b/src/3rdparty/angle/src/compiler/translator/OutputHLSL.h @@ -8,67 +8,94 @@ #define COMPILER_TRANSLATOR_OUTPUTHLSL_H_ #include -#include #include #include #include "angle_gl.h" #include "compiler/translator/ASTMetadataHLSL.h" -#include "compiler/translator/IntermNode.h" -#include "compiler/translator/ParseContext.h" +#include "compiler/translator/Compiler.h" +#include "compiler/translator/FlagStd140Structs.h" +#include "compiler/translator/IntermTraverse.h" class BuiltInFunctionEmulator; namespace sh { -class UnfoldShortCircuit; class StructureHLSL; +class TextureFunctionHLSL; +class TSymbolTable; +class ImageFunctionHLSL; +class UnfoldShortCircuit; class UniformHLSL; -typedef std::map ReferencedSymbols; +typedef std::map ReferencedSymbols; class OutputHLSL : public TIntermTraverser { public: - OutputHLSL(sh::GLenum shaderType, int shaderVersion, - const TExtensionBehavior &extensionBehavior, - const char *sourcePath, ShShaderOutput outputType, - int numRenderTargets, const std::vector &uniforms, - int compileOptions); + OutputHLSL(sh::GLenum shaderType, + int shaderVersion, + const TExtensionBehavior &extensionBehavior, + const char *sourcePath, + ShShaderOutput outputType, + int numRenderTargets, + const std::vector &uniforms, + ShCompileOptions compileOptions, + TSymbolTable *symbolTable, + PerformanceDiagnostics *perfDiagnostics); ~OutputHLSL(); void output(TIntermNode *treeRoot, TInfoSinkBase &objSink); - const std::map &getInterfaceBlockRegisterMap() const; + const std::map &getUniformBlockRegisterMap() const; const std::map &getUniformRegisterMap() const; static TString initializer(const TType &type); - TInfoSinkBase &getInfoSink() { ASSERT(!mInfoSinkStack.empty()); return *mInfoSinkStack.top(); } + TInfoSinkBase &getInfoSink() + { + ASSERT(!mInfoSinkStack.empty()); + return *mInfoSinkStack.top(); + } static bool canWriteAsHLSLLiteral(TIntermTyped *expression); protected: - void header(TInfoSinkBase &out, const BuiltInFunctionEmulator *builtInFunctionEmulator); + void header(TInfoSinkBase &out, + const std::vector &std140Structs, + const BuiltInFunctionEmulator *builtInFunctionEmulator) const; + + void writeFloat(TInfoSinkBase &out, float f); + void writeSingleConstant(TInfoSinkBase &out, const TConstantUnion *const constUnion); + const TConstantUnion *writeConstantUnionArray(TInfoSinkBase &out, + const TConstantUnion *const constUnion, + const size_t size); // Visit AST nodes and output their code to the body stream - void visitSymbol(TIntermSymbol*); - void visitRaw(TIntermRaw*); - void visitConstantUnion(TIntermConstantUnion*); - bool visitBinary(Visit visit, TIntermBinary*); - bool visitUnary(Visit visit, TIntermUnary*); - bool visitSelection(Visit visit, TIntermSelection*); - bool visitSwitch(Visit visit, TIntermSwitch *); - bool visitCase(Visit visit, TIntermCase *); - bool visitAggregate(Visit visit, TIntermAggregate*); - bool visitLoop(Visit visit, TIntermLoop*); - bool visitBranch(Visit visit, TIntermBranch*); + void visitSymbol(TIntermSymbol *) override; + void visitRaw(TIntermRaw *) override; + void visitConstantUnion(TIntermConstantUnion *) override; + bool visitSwizzle(Visit visit, TIntermSwizzle *node) override; + bool visitBinary(Visit visit, TIntermBinary *) override; + bool visitUnary(Visit visit, TIntermUnary *) override; + bool visitTernary(Visit visit, TIntermTernary *) override; + bool visitIfElse(Visit visit, TIntermIfElse *) override; + bool visitSwitch(Visit visit, TIntermSwitch *) override; + bool visitCase(Visit visit, TIntermCase *) override; + bool visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *node) override; + bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override; + bool visitAggregate(Visit visit, TIntermAggregate *) override; + bool visitBlock(Visit visit, TIntermBlock *node) override; + bool visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *node) override; + bool visitDeclaration(Visit visit, TIntermDeclaration *node) override; + bool visitLoop(Visit visit, TIntermLoop *) override; + bool visitBranch(Visit visit, TIntermBranch *) override; - bool isSingleStatement(TIntermNode *node); bool handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node); - // Emit one of three strings depending on traverse phase. Called with literal strings so using const char* instead of TString. + // Emit one of three strings depending on traverse phase. Called with literal strings so using + // const char* instead of TString. void outputTriplet(TInfoSinkBase &out, Visit visit, const char *preString, @@ -76,32 +103,28 @@ class OutputHLSL : public TIntermTraverser const char *postString); void outputLineDirective(TInfoSinkBase &out, int line); TString argumentString(const TIntermSymbol *symbol); - int vectorSize(const TType &type) const; - // Emit constructor. Called with literal names so using const char* instead of TString. - void outputConstructor(TInfoSinkBase &out, - Visit visit, - const TType &type, - const char *name, - const TIntermSequence *parameters); + void outputConstructor(TInfoSinkBase &out, Visit visit, TIntermAggregate *node); const TConstantUnion *writeConstantUnion(TInfoSinkBase &out, const TType &type, const TConstantUnion *constUnion); void outputEqual(Visit visit, const TType &type, TOperator op, TInfoSinkBase &out); + void outputAssign(Visit visit, const TType &type, TInfoSinkBase &out); - void writeEmulatedFunctionTriplet(TInfoSinkBase &out, Visit visit, const char *preStr); - void makeFlaggedStructMaps(const std::vector &flaggedStructs); + void writeEmulatedFunctionTriplet(TInfoSinkBase &out, Visit visit, TOperator op); - // Returns true if it found a 'same symbol' initializer (initializer that references the variable it's initting) - bool writeSameSymbolInitializer(TInfoSinkBase &out, TIntermSymbol *symbolNode, TIntermTyped *expression); + // Returns true if it found a 'same symbol' initializer (initializer that references the + // variable it's initting) + bool writeSameSymbolInitializer(TInfoSinkBase &out, + TIntermSymbol *symbolNode, + TIntermTyped *expression); // Returns true if variable initializer could be written using literal {} notation. bool writeConstantInitialization(TInfoSinkBase &out, TIntermSymbol *symbolNode, TIntermTyped *expression); - void writeDeferredGlobalInitializers(TInfoSinkBase &out); - void writeSelection(TInfoSinkBase &out, TIntermSelection *node); + void writeIfElse(TInfoSinkBase &out, TIntermIfElse *node); // Returns the function name TString addStructEqualityFunction(const TStructure &structure); @@ -117,7 +140,7 @@ class OutputHLSL : public TIntermTraverser const TExtensionBehavior &mExtensionBehavior; const char *mSourcePath; const ShShaderOutput mOutputType; - int mCompileOptions; + ShCompileOptions mCompileOptions; bool mInsideFunction; @@ -126,49 +149,23 @@ class OutputHLSL : public TIntermTraverser TInfoSinkBase mBody; TInfoSinkBase mFooter; - // A stack is useful when we want to traverse in the header, or in helper functions, but not always - // write to the body. Instead use an InfoSink stack to keep our current state intact. + // A stack is useful when we want to traverse in the header, or in helper functions, but not + // always write to the body. Instead use an InfoSink stack to keep our current state intact. // TODO (jmadill): Just passing an InfoSink in function parameters would be simpler. std::stack mInfoSinkStack; ReferencedSymbols mReferencedUniforms; - ReferencedSymbols mReferencedInterfaceBlocks; + ReferencedSymbols mReferencedUniformBlocks; ReferencedSymbols mReferencedAttributes; ReferencedSymbols mReferencedVaryings; ReferencedSymbols mReferencedOutputVariables; StructureHLSL *mStructureHLSL; UniformHLSL *mUniformHLSL; - - struct TextureFunction - { - enum Method - { - IMPLICIT, // Mipmap LOD determined implicitly (standard lookup) - BIAS, - LOD, - LOD0, - LOD0BIAS, - SIZE, // textureSize() - FETCH, - GRAD - }; - - TBasicType sampler; - int coords; - bool proj; - bool offset; - Method method; - - TString name() const; - - bool operator<(const TextureFunction &rhs) const; - }; - - typedef std::set TextureFunctionSet; + TextureFunctionHLSL *mTextureFunctionHLSL; + ImageFunctionHLSL *mImageFunctionHLSL; // Parameters determining what goes in the header output - TextureFunctionSet mUsesTexture; bool mUsesFragColor; bool mUsesFragData; bool mUsesDepthRange; @@ -177,16 +174,23 @@ class OutputHLSL : public TIntermTraverser bool mUsesFrontFacing; bool mUsesPointSize; bool mUsesInstanceID; + bool mHasMultiviewExtensionEnabled; + bool mUsesViewID; + bool mUsesVertexID; bool mUsesFragDepth; + bool mUsesNumWorkGroups; + bool mUsesWorkGroupID; + bool mUsesLocalInvocationID; + bool mUsesGlobalInvocationID; + bool mUsesLocalInvocationIndex; bool mUsesXor; bool mUsesDiscardRewriting; bool mUsesNestedBreak; bool mRequiresIEEEStrictCompiling; - int mNumRenderTargets; - int mUniqueIndex; // For creating unique names + int mUniqueIndex; // For creating unique names CallDAG mCallDag; MetadataList mASTMetadataList; @@ -197,15 +201,7 @@ class OutputHLSL : public TIntermTraverser TIntermSymbol *mExcessiveLoopIndex; - TString structInitializerString(int indent, const TStructure &structure, const TString &rhsStructName); - - std::map mFlaggedStructMappedNames; - std::map mFlaggedStructOriginalNames; - - // Some initializers may have been unfolded into if statements, thus we can't evaluate all initializers - // at global static scope in HLSL. Instead, we can initialize these static globals inside a helper function. - // This also enables initialization of globals with uniforms. - TIntermSequence mDeferredGlobalInitializers; + TString structInitializerString(int indent, const TType &type, const TString &name) const; struct HelperFunction { @@ -219,28 +215,34 @@ class OutputHLSL : public TIntermTraverser // which we add the functions, since nested structures call each other recursively, and // structure equality functions may need to call array equality functions and vice versa. // The ownership of the pointers is maintained by the type-specific arrays. - std::vector mEqualityFunctions; + std::vector mEqualityFunctions; struct StructEqualityFunction : public HelperFunction { const TStructure *structure; }; - std::vector mStructEqualityFunctions; + std::vector mStructEqualityFunctions; struct ArrayHelperFunction : public HelperFunction { TType type; }; - std::vector mArrayEqualityFunctions; + std::vector mArrayEqualityFunctions; std::vector mArrayAssignmentFunctions; - // The construct-into functions are functions that fill an N-element array passed as an out parameter - // with the other N parameters of the function. This is used to work around that arrays can't be - // return values in HLSL. + // The construct-into functions are functions that fill an N-element array passed as an out + // parameter with the other N parameters of the function. This is used to work around that + // arrays can't be return values in HLSL. std::vector mArrayConstructIntoFunctions; -}; + PerformanceDiagnostics *mPerfDiagnostics; + + private: + TString generateStructMapping(const std::vector &std140Structs) const; + TString samplerNamePrefixFromStruct(TIntermTyped *node); + bool ancestorEvaluatesToSamplerInStruct(); +}; } -#endif // COMPILER_TRANSLATOR_OUTPUTHLSL_H_ +#endif // COMPILER_TRANSLATOR_OUTPUTHLSL_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/OutputTree.cpp b/src/3rdparty/angle/src/compiler/translator/OutputTree.cpp new file mode 100644 index 0000000000..25e8298af3 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/OutputTree.cpp @@ -0,0 +1,682 @@ +// +// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/translator/IntermTraverse.h" +#include "compiler/translator/SymbolTable.h" + +namespace sh +{ + +namespace +{ + +void OutputFunction(TInfoSinkBase &out, const char *str, TFunctionSymbolInfo *info) +{ + const char *internal = info->getNameObj().isInternal() ? " (internal function)" : ""; + out << str << internal << ": " << info->getNameObj().getString() << " (symbol id " + << info->getId().get() << ")"; +} + +// Two purposes: +// 1. Show an example of how to iterate tree. Functions can also directly call traverse() on +// children themselves to have finer grained control over the process than shown here, though +// that's not recommended if it can be avoided. +// 2. Print out a text based description of the tree. + +// The traverser subclass is used to carry along data from node to node in the traversal. +class TOutputTraverser : public TIntermTraverser +{ + public: + TOutputTraverser(TInfoSinkBase &out) : TIntermTraverser(true, false, false), mOut(out) {} + + protected: + void visitSymbol(TIntermSymbol *) override; + void visitConstantUnion(TIntermConstantUnion *) override; + bool visitSwizzle(Visit visit, TIntermSwizzle *node) override; + bool visitBinary(Visit visit, TIntermBinary *) override; + bool visitUnary(Visit visit, TIntermUnary *) override; + bool visitTernary(Visit visit, TIntermTernary *node) override; + bool visitIfElse(Visit visit, TIntermIfElse *node) override; + bool visitSwitch(Visit visit, TIntermSwitch *node) override; + bool visitCase(Visit visit, TIntermCase *node) override; + bool visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *node) override; + bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override; + bool visitAggregate(Visit visit, TIntermAggregate *) override; + bool visitBlock(Visit visit, TIntermBlock *) override; + bool visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *node) override; + bool visitDeclaration(Visit visit, TIntermDeclaration *node) override; + bool visitLoop(Visit visit, TIntermLoop *) override; + bool visitBranch(Visit visit, TIntermBranch *) override; + + TInfoSinkBase &mOut; +}; + +// +// Helper functions for printing, not part of traversing. +// +void OutputTreeText(TInfoSinkBase &out, TIntermNode *node, const int depth) +{ + int i; + + out.location(node->getLine().first_file, node->getLine().first_line); + + for (i = 0; i < depth; ++i) + out << " "; +} + +// +// The rest of the file are the traversal functions. The last one +// is the one that starts the traversal. +// +// Return true from interior nodes to have the external traversal +// continue on to children. If you process children yourself, +// return false. +// + +void TOutputTraverser::visitSymbol(TIntermSymbol *node) +{ + OutputTreeText(mOut, node, mDepth); + + mOut << "'" << node->getSymbol() << "' "; + mOut << "(symbol id " << node->getId() << ") "; + mOut << "(" << node->getCompleteString() << ")"; + mOut << "\n"; +} + +bool TOutputTraverser::visitSwizzle(Visit visit, TIntermSwizzle *node) +{ + OutputTreeText(mOut, node, mDepth); + mOut << "vector swizzle ("; + node->writeOffsetsAsXYZW(&mOut); + mOut << ")"; + + mOut << " (" << node->getCompleteString() << ")"; + mOut << "\n"; + return true; +} + +bool TOutputTraverser::visitBinary(Visit visit, TIntermBinary *node) +{ + OutputTreeText(mOut, node, mDepth); + + switch (node->getOp()) + { + case EOpComma: + mOut << "comma"; + break; + case EOpAssign: + mOut << "move second child to first child"; + break; + case EOpInitialize: + mOut << "initialize first child with second child"; + break; + case EOpAddAssign: + mOut << "add second child into first child"; + break; + case EOpSubAssign: + mOut << "subtract second child into first child"; + break; + case EOpMulAssign: + mOut << "multiply second child into first child"; + break; + case EOpVectorTimesMatrixAssign: + mOut << "matrix mult second child into first child"; + break; + case EOpVectorTimesScalarAssign: + mOut << "vector scale second child into first child"; + break; + case EOpMatrixTimesScalarAssign: + mOut << "matrix scale second child into first child"; + break; + case EOpMatrixTimesMatrixAssign: + mOut << "matrix mult second child into first child"; + break; + case EOpDivAssign: + mOut << "divide second child into first child"; + break; + case EOpIModAssign: + mOut << "modulo second child into first child"; + break; + case EOpBitShiftLeftAssign: + mOut << "bit-wise shift first child left by second child"; + break; + case EOpBitShiftRightAssign: + mOut << "bit-wise shift first child right by second child"; + break; + case EOpBitwiseAndAssign: + mOut << "bit-wise and second child into first child"; + break; + case EOpBitwiseXorAssign: + mOut << "bit-wise xor second child into first child"; + break; + case EOpBitwiseOrAssign: + mOut << "bit-wise or second child into first child"; + break; + + case EOpIndexDirect: + mOut << "direct index"; + break; + case EOpIndexIndirect: + mOut << "indirect index"; + break; + case EOpIndexDirectStruct: + mOut << "direct index for structure"; + break; + case EOpIndexDirectInterfaceBlock: + mOut << "direct index for interface block"; + break; + + case EOpAdd: + mOut << "add"; + break; + case EOpSub: + mOut << "subtract"; + break; + case EOpMul: + mOut << "component-wise multiply"; + break; + case EOpDiv: + mOut << "divide"; + break; + case EOpIMod: + mOut << "modulo"; + break; + case EOpBitShiftLeft: + mOut << "bit-wise shift left"; + break; + case EOpBitShiftRight: + mOut << "bit-wise shift right"; + break; + case EOpBitwiseAnd: + mOut << "bit-wise and"; + break; + case EOpBitwiseXor: + mOut << "bit-wise xor"; + break; + case EOpBitwiseOr: + mOut << "bit-wise or"; + break; + + case EOpEqual: + mOut << "Compare Equal"; + break; + case EOpNotEqual: + mOut << "Compare Not Equal"; + break; + case EOpLessThan: + mOut << "Compare Less Than"; + break; + case EOpGreaterThan: + mOut << "Compare Greater Than"; + break; + case EOpLessThanEqual: + mOut << "Compare Less Than or Equal"; + break; + case EOpGreaterThanEqual: + mOut << "Compare Greater Than or Equal"; + break; + + case EOpVectorTimesScalar: + mOut << "vector-scale"; + break; + case EOpVectorTimesMatrix: + mOut << "vector-times-matrix"; + break; + case EOpMatrixTimesVector: + mOut << "matrix-times-vector"; + break; + case EOpMatrixTimesScalar: + mOut << "matrix-scale"; + break; + case EOpMatrixTimesMatrix: + mOut << "matrix-multiply"; + break; + + case EOpLogicalOr: + mOut << "logical-or"; + break; + case EOpLogicalXor: + mOut << "logical-xor"; + break; + case EOpLogicalAnd: + mOut << "logical-and"; + break; + default: + mOut << ""; + } + + mOut << " (" << node->getCompleteString() << ")"; + + mOut << "\n"; + + // Special handling for direct indexes. Because constant + // unions are not aware they are struct indexes, treat them + // here where we have that contextual knowledge. + if (node->getOp() == EOpIndexDirectStruct || node->getOp() == EOpIndexDirectInterfaceBlock) + { + node->getLeft()->traverse(this); + + TIntermConstantUnion *intermConstantUnion = node->getRight()->getAsConstantUnion(); + ASSERT(intermConstantUnion); + + OutputTreeText(mOut, intermConstantUnion, mDepth + 1); + + // The following code finds the field name from the constant union + const TConstantUnion *constantUnion = intermConstantUnion->getUnionArrayPointer(); + const TStructure *structure = node->getLeft()->getType().getStruct(); + const TInterfaceBlock *interfaceBlock = node->getLeft()->getType().getInterfaceBlock(); + ASSERT(structure || interfaceBlock); + + const TFieldList &fields = structure ? structure->fields() : interfaceBlock->fields(); + + const TField *field = fields[constantUnion->getIConst()]; + + mOut << constantUnion->getIConst() << " (field '" << field->name() << "')"; + + mOut << "\n"; + + return false; + } + + return true; +} + +bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary *node) +{ + OutputTreeText(mOut, node, mDepth); + + switch (node->getOp()) + { + // Give verbose names for ops that have special syntax and some built-in functions that are + // easy to confuse with others, but mostly use GLSL names for functions. + case EOpNegative: + mOut << "Negate value"; + break; + case EOpPositive: + mOut << "Positive sign"; + break; + case EOpLogicalNot: + mOut << "negation"; + break; + case EOpBitwiseNot: + mOut << "bit-wise not"; + break; + + case EOpPostIncrement: + mOut << "Post-Increment"; + break; + case EOpPostDecrement: + mOut << "Post-Decrement"; + break; + case EOpPreIncrement: + mOut << "Pre-Increment"; + break; + case EOpPreDecrement: + mOut << "Pre-Decrement"; + break; + + case EOpArrayLength: + mOut << "Array length"; + break; + + case EOpLogicalNotComponentWise: + mOut << "component-wise not"; + break; + + default: + mOut << GetOperatorString(node->getOp()); + break; + } + + mOut << " (" << node->getCompleteString() << ")"; + + mOut << "\n"; + + return true; +} + +bool TOutputTraverser::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) +{ + OutputTreeText(mOut, node, mDepth); + mOut << "Function Definition:\n"; + mOut << "\n"; + return true; +} + +bool TOutputTraverser::visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *node) +{ + OutputTreeText(mOut, node, mDepth); + mOut << "Invariant Declaration:\n"; + return true; +} + +bool TOutputTraverser::visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *node) +{ + OutputTreeText(mOut, node, mDepth); + OutputFunction(mOut, "Function Prototype", node->getFunctionSymbolInfo()); + mOut << " (" << node->getCompleteString() << ")"; + mOut << "\n"; + + return true; +} + +bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate *node) +{ + OutputTreeText(mOut, node, mDepth); + + if (node->getOp() == EOpNull) + { + mOut.prefix(SH_ERROR); + mOut << "node is still EOpNull!\n"; + return true; + } + + // Give verbose names for some built-in functions that are easy to confuse with others, but + // mostly use GLSL names for functions. + switch (node->getOp()) + { + case EOpCallFunctionInAST: + OutputFunction(mOut, "Call an user-defined function", node->getFunctionSymbolInfo()); + break; + case EOpCallInternalRawFunction: + OutputFunction(mOut, "Call an internal function with raw implementation", + node->getFunctionSymbolInfo()); + break; + case EOpCallBuiltInFunction: + OutputFunction(mOut, "Call a built-in function", node->getFunctionSymbolInfo()); + break; + + case EOpConstruct: + // The type of the constructor will be printed below. + mOut << "Construct"; + break; + + case EOpEqualComponentWise: + mOut << "component-wise equal"; + break; + case EOpNotEqualComponentWise: + mOut << "component-wise not equal"; + break; + case EOpLessThanComponentWise: + mOut << "component-wise less than"; + break; + case EOpGreaterThanComponentWise: + mOut << "component-wise greater than"; + break; + case EOpLessThanEqualComponentWise: + mOut << "component-wise less than or equal"; + break; + case EOpGreaterThanEqualComponentWise: + mOut << "component-wise greater than or equal"; + break; + + case EOpDot: + mOut << "dot product"; + break; + case EOpCross: + mOut << "cross product"; + break; + case EOpMulMatrixComponentWise: + mOut << "component-wise multiply"; + break; + + default: + mOut << GetOperatorString(node->getOp()); + break; + } + + mOut << " (" << node->getCompleteString() << ")"; + + mOut << "\n"; + + return true; +} + +bool TOutputTraverser::visitBlock(Visit visit, TIntermBlock *node) +{ + OutputTreeText(mOut, node, mDepth); + mOut << "Code block\n"; + + return true; +} + +bool TOutputTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node) +{ + OutputTreeText(mOut, node, mDepth); + mOut << "Declaration\n"; + + return true; +} + +bool TOutputTraverser::visitTernary(Visit visit, TIntermTernary *node) +{ + OutputTreeText(mOut, node, mDepth); + + mOut << "Ternary selection"; + mOut << " (" << node->getCompleteString() << ")\n"; + + ++mDepth; + + OutputTreeText(mOut, node, mDepth); + mOut << "Condition\n"; + node->getCondition()->traverse(this); + + OutputTreeText(mOut, node, mDepth); + if (node->getTrueExpression()) + { + mOut << "true case\n"; + node->getTrueExpression()->traverse(this); + } + if (node->getFalseExpression()) + { + OutputTreeText(mOut, node, mDepth); + mOut << "false case\n"; + node->getFalseExpression()->traverse(this); + } + + --mDepth; + + return false; +} + +bool TOutputTraverser::visitIfElse(Visit visit, TIntermIfElse *node) +{ + OutputTreeText(mOut, node, mDepth); + + mOut << "If test\n"; + + ++mDepth; + + OutputTreeText(mOut, node, mDepth); + mOut << "Condition\n"; + node->getCondition()->traverse(this); + + OutputTreeText(mOut, node, mDepth); + if (node->getTrueBlock()) + { + mOut << "true case\n"; + node->getTrueBlock()->traverse(this); + } + else + { + mOut << "true case is null\n"; + } + + if (node->getFalseBlock()) + { + OutputTreeText(mOut, node, mDepth); + mOut << "false case\n"; + node->getFalseBlock()->traverse(this); + } + + --mDepth; + + return false; +} + +bool TOutputTraverser::visitSwitch(Visit visit, TIntermSwitch *node) +{ + OutputTreeText(mOut, node, mDepth); + + mOut << "Switch\n"; + + return true; +} + +bool TOutputTraverser::visitCase(Visit visit, TIntermCase *node) +{ + OutputTreeText(mOut, node, mDepth); + + if (node->getCondition() == nullptr) + { + mOut << "Default\n"; + } + else + { + mOut << "Case\n"; + } + + return true; +} + +void TOutputTraverser::visitConstantUnion(TIntermConstantUnion *node) +{ + size_t size = node->getType().getObjectSize(); + + for (size_t i = 0; i < size; i++) + { + OutputTreeText(mOut, node, mDepth); + switch (node->getUnionArrayPointer()[i].getType()) + { + case EbtBool: + if (node->getUnionArrayPointer()[i].getBConst()) + mOut << "true"; + else + mOut << "false"; + + mOut << " (" + << "const bool" + << ")"; + mOut << "\n"; + break; + case EbtFloat: + mOut << node->getUnionArrayPointer()[i].getFConst(); + mOut << " (const float)\n"; + break; + case EbtInt: + mOut << node->getUnionArrayPointer()[i].getIConst(); + mOut << " (const int)\n"; + break; + case EbtUInt: + mOut << node->getUnionArrayPointer()[i].getUConst(); + mOut << " (const uint)\n"; + break; + case EbtYuvCscStandardEXT: + mOut << getYuvCscStandardEXTString( + node->getUnionArrayPointer()[i].getYuvCscStandardEXTConst()); + mOut << " (const yuvCscStandardEXT)\n"; + break; + default: + mOut.prefix(SH_ERROR); + mOut << "Unknown constant\n"; + break; + } + } +} + +bool TOutputTraverser::visitLoop(Visit visit, TIntermLoop *node) +{ + OutputTreeText(mOut, node, mDepth); + + mOut << "Loop with condition "; + if (node->getType() == ELoopDoWhile) + mOut << "not "; + mOut << "tested first\n"; + + ++mDepth; + + OutputTreeText(mOut, node, mDepth); + if (node->getCondition()) + { + mOut << "Loop Condition\n"; + node->getCondition()->traverse(this); + } + else + { + mOut << "No loop condition\n"; + } + + OutputTreeText(mOut, node, mDepth); + if (node->getBody()) + { + mOut << "Loop Body\n"; + node->getBody()->traverse(this); + } + else + { + mOut << "No loop body\n"; + } + + if (node->getExpression()) + { + OutputTreeText(mOut, node, mDepth); + mOut << "Loop Terminal Expression\n"; + node->getExpression()->traverse(this); + } + + --mDepth; + + return false; +} + +bool TOutputTraverser::visitBranch(Visit visit, TIntermBranch *node) +{ + OutputTreeText(mOut, node, mDepth); + + switch (node->getFlowOp()) + { + case EOpKill: + mOut << "Branch: Kill"; + break; + case EOpBreak: + mOut << "Branch: Break"; + break; + case EOpContinue: + mOut << "Branch: Continue"; + break; + case EOpReturn: + mOut << "Branch: Return"; + break; + default: + mOut << "Branch: Unknown Branch"; + break; + } + + if (node->getExpression()) + { + mOut << " with expression\n"; + ++mDepth; + node->getExpression()->traverse(this); + --mDepth; + } + else + { + mOut << "\n"; + } + + return false; +} + +} // anonymous namespace + +void OutputTree(TIntermNode *root, TInfoSinkBase &out) +{ + TOutputTraverser it(out); + ASSERT(root); + root->traverse(&it); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/OutputTree.h b/src/3rdparty/angle/src/compiler/translator/OutputTree.h new file mode 100644 index 0000000000..9f11989cb1 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/OutputTree.h @@ -0,0 +1,22 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Output the AST intermediate representation of the GLSL code. + +#ifndef COMPILER_TRANSLATOR_OUTPUTTREE_H_ +#define COMPILER_TRANSLATOR_OUTPUTTREE_H_ + +namespace sh +{ + +class TIntermNode; +class TInfoSinkBase; + +// Output the AST along with metadata. +void OutputTree(TIntermNode *root, TInfoSinkBase &out); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_OUTPUTTREE_H_ \ No newline at end of file diff --git a/src/3rdparty/angle/src/compiler/translator/OutputVulkanGLSL.cpp b/src/3rdparty/angle/src/compiler/translator/OutputVulkanGLSL.cpp new file mode 100644 index 0000000000..6d11deb898 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/OutputVulkanGLSL.cpp @@ -0,0 +1,80 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// OutputVulkanGLSL: +// Code that outputs shaders that fit GL_KHR_vulkan_glsl. +// The shaders are then fed into glslang to spit out SPIR-V (libANGLE-side). +// See: https://www.khronos.org/registry/vulkan/specs/misc/GL_KHR_vulkan_glsl.txt +// + +#include "compiler/translator/OutputVulkanGLSL.h" + +#include "compiler/translator/util.h" + +namespace sh +{ + +TOutputVulkanGLSL::TOutputVulkanGLSL(TInfoSinkBase &objSink, + ShArrayIndexClampingStrategy clampingStrategy, + ShHashFunction64 hashFunction, + NameMap &nameMap, + TSymbolTable *symbolTable, + sh::GLenum shaderType, + int shaderVersion, + ShShaderOutput output, + ShCompileOptions compileOptions) + : TOutputGLSL(objSink, + clampingStrategy, + hashFunction, + nameMap, + symbolTable, + shaderType, + shaderVersion, + output, + compileOptions) +{ +} + +// TODO(jmadill): This is not complete. +void TOutputVulkanGLSL::writeLayoutQualifier(TIntermTyped *variable) +{ + const TType &type = variable->getType(); + + bool needsCustomLayout = + (type.getQualifier() == EvqAttribute || type.getQualifier() == EvqFragmentOut || + type.getQualifier() == EvqVertexIn || IsVarying(type.getQualifier()) || + IsSampler(type.getBasicType())); + + if (!NeedsToWriteLayoutQualifier(type) && !needsCustomLayout) + { + return; + } + + TInfoSinkBase &out = objSink(); + const TLayoutQualifier &layoutQualifier = type.getLayoutQualifier(); + out << "layout("; + + // This isn't super clean, but it gets the job done. + // See corresponding code in GlslangWrapper.cpp. + // TODO(jmadill): Ensure declarations are separated. + + TIntermSymbol *symbol = variable->getAsSymbolNode(); + ASSERT(symbol); + + if (needsCustomLayout) + { + out << "@@ LAYOUT-" << symbol->getName().getString() << " @@"; + } + + if (IsImage(type.getBasicType()) && layoutQualifier.imageInternalFormat != EiifUnspecified) + { + ASSERT(type.getQualifier() == EvqTemporary || type.getQualifier() == EvqUniform); + out << getImageInternalFormatString(layoutQualifier.imageInternalFormat); + } + + out << ") "; +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/OutputVulkanGLSL.h b/src/3rdparty/angle/src/compiler/translator/OutputVulkanGLSL.h new file mode 100644 index 0000000000..6e5da8b53e --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/OutputVulkanGLSL.h @@ -0,0 +1,34 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// OutputVulkanGLSL: +// Code that outputs shaders that fit GL_KHR_vulkan_glsl. +// The shaders are then fed into glslang to spit out SPIR-V (libANGLE-side). +// See: https://www.khronos.org/registry/vulkan/specs/misc/GL_KHR_vulkan_glsl.txt +// + +#include "compiler/translator/OutputGLSL.h" + +namespace sh +{ + +class TOutputVulkanGLSL : public TOutputGLSL +{ + public: + TOutputVulkanGLSL(TInfoSinkBase &objSink, + ShArrayIndexClampingStrategy clampingStrategy, + ShHashFunction64 hashFunction, + NameMap &nameMap, + TSymbolTable *symbolTable, + sh::GLenum shaderType, + int shaderVersion, + ShShaderOutput output, + ShCompileOptions compileOptions); + + protected: + void writeLayoutQualifier(TIntermTyped *variable) override; +}; + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/ParamType.h b/src/3rdparty/angle/src/compiler/translator/ParamType.h new file mode 100644 index 0000000000..dddb4e9901 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/ParamType.h @@ -0,0 +1,102 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ParamType: +// Helper type for built-in function emulator tables. Defines types for parameters. + +#ifndef COMPILER_TRANSLATOR_PARAMTYPE_H_ +#define COMPILER_TRANSLATOR_PARAMTYPE_H_ + +#include "common/angleutils.h" +#include "compiler/translator/BaseTypes.h" + +namespace sh +{ + +enum class ParamType : uint8_t +{ + Void, + Bool1, + Bool2, + Bool3, + Bool4, + Float1, + Float2, + Float3, + Float4, + Int1, + Int2, + Int3, + Int4, + Mat2, + Mat3, + Mat4, + Uint1, + Uint2, + Uint3, + Uint4, + Last, +}; + +struct ParamTypeInfo +{ + ParamType self; + TBasicType basicType; + int primarySize; + int secondarySize; +}; + +constexpr ParamTypeInfo g_ParamTypeInfo[] = { + {ParamType::Void, EbtVoid, 1, 1}, {ParamType::Bool1, EbtBool, 1, 1}, + {ParamType::Bool2, EbtBool, 2, 1}, {ParamType::Bool3, EbtBool, 3, 1}, + {ParamType::Bool4, EbtBool, 4, 1}, {ParamType::Float1, EbtFloat, 1, 1}, + {ParamType::Float2, EbtFloat, 2, 1}, {ParamType::Float3, EbtFloat, 3, 1}, + {ParamType::Float4, EbtFloat, 4, 1}, {ParamType::Int1, EbtInt, 1, 1}, + {ParamType::Int2, EbtInt, 2, 1}, {ParamType::Int3, EbtInt, 3, 1}, + {ParamType::Int4, EbtInt, 4, 1}, {ParamType::Mat2, EbtFloat, 2, 2}, + {ParamType::Mat3, EbtFloat, 3, 3}, {ParamType::Mat4, EbtFloat, 4, 4}, + {ParamType::Uint1, EbtUInt, 1, 1}, {ParamType::Uint2, EbtUInt, 2, 1}, + {ParamType::Uint3, EbtUInt, 3, 1}, {ParamType::Uint4, EbtUInt, 4, 1}, +}; + +constexpr size_t ParamTypeIndex(ParamType paramType) +{ + return static_cast(paramType); +} + +constexpr size_t NumParamTypes() +{ + return ParamTypeIndex(ParamType::Last); +} + +static_assert(ArraySize(g_ParamTypeInfo) == NumParamTypes(), "Invalid array size"); + +constexpr TBasicType GetBasicType(ParamType paramType) +{ + return g_ParamTypeInfo[ParamTypeIndex(paramType)].basicType; +} + +constexpr int GetPrimarySize(ParamType paramType) +{ + return g_ParamTypeInfo[ParamTypeIndex(paramType)].primarySize; +} + +constexpr int GetSecondarySize(ParamType paramType) +{ + return g_ParamTypeInfo[ParamTypeIndex(paramType)].secondarySize; +} + +constexpr bool SameParamType(ParamType paramType, + TBasicType basicType, + int primarySize, + int secondarySize) +{ + return GetBasicType(paramType) == basicType && primarySize == GetPrimarySize(paramType) && + secondarySize == GetSecondarySize(paramType); +} + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_PARAMTYPE_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/ParseContext.cpp b/src/3rdparty/angle/src/compiler/translator/ParseContext.cpp index 235351cf41..c97f91d781 100644 --- a/src/3rdparty/angle/src/compiler/translator/ParseContext.cpp +++ b/src/3rdparty/angle/src/compiler/translator/ParseContext.cpp @@ -9,34 +9,252 @@ #include #include +#include "common/mathutil.h" #include "compiler/preprocessor/SourceLocation.h" #include "compiler/translator/Cache.h" -#include "compiler/translator/glslang.h" -#include "compiler/translator/ValidateSwitch.h" +#include "compiler/translator/IntermNode_util.h" #include "compiler/translator/ValidateGlobalInitializer.h" +#include "compiler/translator/ValidateSwitch.h" +#include "compiler/translator/glslang.h" #include "compiler/translator/util.h" +namespace sh +{ + /////////////////////////////////////////////////////////////////////// // // Sub- vector and matrix fields // //////////////////////////////////////////////////////////////////////// -// -// Look at a '.' field selector string and change it into offsets -// for a vector. -// -bool TParseContext::parseVectorFields(const TString &compString, - int vecSize, - TVectorFields &fields, - const TSourceLoc &line) +namespace { - fields.num = (int)compString.size(); - if (fields.num > 4) + +const int kWebGLMaxStructNesting = 4; + +const std::array kAtomicBuiltin = {{"atomicAdd", "atomicMin", "atomicMax", + "atomicAnd", "atomicOr", "atomicXor", + "atomicExchange", "atomicCompSwap"}}; + +bool IsAtomicBuiltin(const TString &name) +{ + for (size_t i = 0; i < kAtomicBuiltin.size(); ++i) + { + if (name.compare(kAtomicBuiltin[i]) == 0) + { + return true; + } + } + return false; +} + +bool ContainsSampler(const TStructure *structType); + +bool ContainsSampler(const TType &type) +{ + if (IsSampler(type.getBasicType())) + { + return true; + } + if (type.getBasicType() == EbtStruct) + { + return ContainsSampler(type.getStruct()); + } + + return false; +} + +bool ContainsSampler(const TStructure *structType) +{ + for (const auto &field : structType->fields()) + { + if (ContainsSampler(*field->type())) + return true; + } + return false; +} + +// Get a token from an image argument to use as an error message token. +const char *GetImageArgumentToken(TIntermTyped *imageNode) +{ + ASSERT(IsImage(imageNode->getBasicType())); + while (imageNode->getAsBinaryNode() && + (imageNode->getAsBinaryNode()->getOp() == EOpIndexIndirect || + imageNode->getAsBinaryNode()->getOp() == EOpIndexDirect)) + { + imageNode = imageNode->getAsBinaryNode()->getLeft(); + } + TIntermSymbol *imageSymbol = imageNode->getAsSymbolNode(); + if (imageSymbol) + { + return imageSymbol->getSymbol().c_str(); + } + return "image"; +} + +bool CanSetDefaultPrecisionOnType(const TPublicType &type) +{ + if (!SupportsPrecision(type.getBasicType())) + { + return false; + } + if (type.getBasicType() == EbtUInt) + { + // ESSL 3.00.4 section 4.5.4 + return false; + } + if (type.isAggregate()) + { + // Not allowed to set for aggregate types + return false; + } + return true; +} + +// Map input primitive types to input array sizes in a geometry shader. +GLuint GetGeometryShaderInputArraySize(TLayoutPrimitiveType primitiveType) +{ + switch (primitiveType) + { + case EptPoints: + return 1u; + case EptLines: + return 2u; + case EptTriangles: + return 3u; + case EptLinesAdjacency: + return 4u; + case EptTrianglesAdjacency: + return 6u; + default: + UNREACHABLE(); + return 0u; + } +} + +bool IsBufferOrSharedVariable(TIntermTyped *var) +{ + if (var->isInterfaceBlock() || var->getQualifier() == EvqBuffer || + var->getQualifier() == EvqShared) + { + return true; + } + return false; +} + +} // namespace + +// This tracks each binding point's current default offset for inheritance of subsequent +// variables using the same binding, and keeps offsets unique and non overlapping. +// See GLSL ES 3.1, section 4.4.6. +class TParseContext::AtomicCounterBindingState +{ + public: + AtomicCounterBindingState() : mDefaultOffset(0) {} + // Inserts a new span and returns -1 if overlapping, else returns the starting offset of + // newly inserted span. + int insertSpan(int start, size_t length) + { + gl::RangeI newSpan(start, start + static_cast(length)); + for (const auto &span : mSpans) + { + if (newSpan.intersects(span)) + { + return -1; + } + } + mSpans.push_back(newSpan); + mDefaultOffset = newSpan.high(); + return start; + } + // Inserts a new span starting from the default offset. + int appendSpan(size_t length) { return insertSpan(mDefaultOffset, length); } + void setDefaultOffset(int offset) { mDefaultOffset = offset; } + + private: + int mDefaultOffset; + std::vector mSpans; +}; + +TParseContext::TParseContext(TSymbolTable &symt, + TExtensionBehavior &ext, + sh::GLenum type, + ShShaderSpec spec, + ShCompileOptions options, + bool checksPrecErrors, + TDiagnostics *diagnostics, + const ShBuiltInResources &resources) + : symbolTable(symt), + mDeferredNonEmptyDeclarationErrorCheck(false), + mShaderType(type), + mShaderSpec(spec), + mCompileOptions(options), + mShaderVersion(100), + mTreeRoot(nullptr), + mLoopNestingLevel(0), + mStructNestingLevel(0), + mSwitchNestingLevel(0), + mCurrentFunctionType(nullptr), + mFunctionReturnsValue(false), + mChecksPrecisionErrors(checksPrecErrors), + mFragmentPrecisionHighOnESSL1(false), + mDefaultUniformMatrixPacking(EmpColumnMajor), + mDefaultUniformBlockStorage(sh::IsWebGLBasedSpec(spec) ? EbsStd140 : EbsShared), + mDefaultBufferMatrixPacking(EmpColumnMajor), + mDefaultBufferBlockStorage(sh::IsWebGLBasedSpec(spec) ? EbsStd140 : EbsShared), + mDiagnostics(diagnostics), + mDirectiveHandler(ext, + *mDiagnostics, + mShaderVersion, + mShaderType, + resources.WEBGL_debug_shader_precision == 1), + mPreprocessor(mDiagnostics, &mDirectiveHandler, pp::PreprocessorSettings()), + mScanner(nullptr), + mUsesFragData(false), + mUsesFragColor(false), + mUsesSecondaryOutputs(false), + mMinProgramTexelOffset(resources.MinProgramTexelOffset), + mMaxProgramTexelOffset(resources.MaxProgramTexelOffset), + mMinProgramTextureGatherOffset(resources.MinProgramTextureGatherOffset), + mMaxProgramTextureGatherOffset(resources.MaxProgramTextureGatherOffset), + mComputeShaderLocalSizeDeclared(false), + mComputeShaderLocalSize(-1), + mNumViews(-1), + mMaxNumViews(resources.MaxViewsOVR), + mMaxImageUnits(resources.MaxImageUnits), + mMaxCombinedTextureImageUnits(resources.MaxCombinedTextureImageUnits), + mMaxUniformLocations(resources.MaxUniformLocations), + mMaxUniformBufferBindings(resources.MaxUniformBufferBindings), + mMaxAtomicCounterBindings(resources.MaxAtomicCounterBindings), + mMaxShaderStorageBufferBindings(resources.MaxShaderStorageBufferBindings), + mDeclaringFunction(false), + mGeometryShaderInputPrimitiveType(EptUndefined), + mGeometryShaderOutputPrimitiveType(EptUndefined), + mGeometryShaderInvocations(0), + mGeometryShaderMaxVertices(-1), + mMaxGeometryShaderInvocations(resources.MaxGeometryShaderInvocations), + mMaxGeometryShaderMaxVertices(resources.MaxGeometryOutputVertices), + mGeometryShaderInputArraySize(0u) +{ +} + +TParseContext::~TParseContext() +{ +} + +bool TParseContext::parseVectorFields(const TSourceLoc &line, + const TString &compString, + int vecSize, + TVector *fieldOffsets) +{ + ASSERT(fieldOffsets); + size_t fieldCount = compString.size(); + if (fieldCount > 4u) { error(line, "illegal vector field selection", compString.c_str()); return false; } + fieldOffsets->resize(fieldCount); enum { @@ -45,57 +263,57 @@ bool TParseContext::parseVectorFields(const TString &compString, estpq } fieldSet[4]; - for (int i = 0; i < fields.num; ++i) + for (unsigned int i = 0u; i < fieldOffsets->size(); ++i) { switch (compString[i]) { case 'x': - fields.offsets[i] = 0; + (*fieldOffsets)[i] = 0; fieldSet[i] = exyzw; break; case 'r': - fields.offsets[i] = 0; + (*fieldOffsets)[i] = 0; fieldSet[i] = ergba; break; case 's': - fields.offsets[i] = 0; + (*fieldOffsets)[i] = 0; fieldSet[i] = estpq; break; case 'y': - fields.offsets[i] = 1; + (*fieldOffsets)[i] = 1; fieldSet[i] = exyzw; break; case 'g': - fields.offsets[i] = 1; + (*fieldOffsets)[i] = 1; fieldSet[i] = ergba; break; case 't': - fields.offsets[i] = 1; + (*fieldOffsets)[i] = 1; fieldSet[i] = estpq; break; case 'z': - fields.offsets[i] = 2; + (*fieldOffsets)[i] = 2; fieldSet[i] = exyzw; break; case 'b': - fields.offsets[i] = 2; + (*fieldOffsets)[i] = 2; fieldSet[i] = ergba; break; case 'p': - fields.offsets[i] = 2; + (*fieldOffsets)[i] = 2; fieldSet[i] = estpq; break; case 'w': - fields.offsets[i] = 3; + (*fieldOffsets)[i] = 3; fieldSet[i] = exyzw; break; case 'a': - fields.offsets[i] = 3; + (*fieldOffsets)[i] = 3; fieldSet[i] = ergba; break; case 'q': - fields.offsets[i] = 3; + (*fieldOffsets)[i] = 3; fieldSet[i] = estpq; break; default: @@ -104,9 +322,9 @@ bool TParseContext::parseVectorFields(const TString &compString, } } - for (int i = 0; i < fields.num; ++i) + for (unsigned int i = 0u; i < fieldOffsets->size(); ++i) { - if (fields.offsets[i] >= vecSize) + if ((*fieldOffsets)[i] >= vecSize) { error(line, "vector field selection out of range", compString.c_str()); return false; @@ -132,52 +350,31 @@ bool TParseContext::parseVectorFields(const TString &compString, // //////////////////////////////////////////////////////////////////////// -// -// Track whether errors have occurred. -// -void TParseContext::recover() -{ -} - // // Used by flex/bison to output all syntax and parsing errors. // -void TParseContext::error(const TSourceLoc &loc, - const char *reason, - const char *token, - const char *extraInfo) +void TParseContext::error(const TSourceLoc &loc, const char *reason, const char *token) { - pp::SourceLocation srcLoc; - srcLoc.file = loc.first_file; - srcLoc.line = loc.first_line; - mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, srcLoc, reason, token, extraInfo); + mDiagnostics->error(loc, reason, token); } -void TParseContext::warning(const TSourceLoc &loc, - const char *reason, - const char *token, - const char *extraInfo) +void TParseContext::warning(const TSourceLoc &loc, const char *reason, const char *token) { - pp::SourceLocation srcLoc; - srcLoc.file = loc.first_file; - srcLoc.line = loc.first_line; - mDiagnostics.writeInfo(pp::Diagnostics::PP_WARNING, srcLoc, reason, token, extraInfo); + mDiagnostics->warning(loc, reason, token); } void TParseContext::outOfRangeError(bool isError, const TSourceLoc &loc, const char *reason, - const char *token, - const char *extraInfo) + const char *token) { if (isError) { - error(loc, reason, token, extraInfo); - recover(); + error(loc, reason, token); } else { - warning(loc, reason, token, extraInfo); + warning(loc, reason, token); } } @@ -186,10 +383,10 @@ void TParseContext::outOfRangeError(bool isError, // void TParseContext::assignError(const TSourceLoc &line, const char *op, TString left, TString right) { - std::stringstream extraInfoStream; - extraInfoStream << "cannot convert from '" << right << "' to '" << left << "'"; - std::string extraInfo = extraInfoStream.str(); - error(line, "", op, extraInfo.c_str()); + std::stringstream reasonStream; + reasonStream << "cannot convert from '" << right << "' to '" << left << "'"; + std::string reason = reasonStream.str(); + error(line, reason.c_str(), op); } // @@ -197,11 +394,12 @@ void TParseContext::assignError(const TSourceLoc &line, const char *op, TString // void TParseContext::unaryOpError(const TSourceLoc &line, const char *op, TString operand) { - std::stringstream extraInfoStream; - extraInfoStream << "no operation '" << op << "' exists that takes an operand of type " - << operand << " (or there is no acceptable conversion)"; - std::string extraInfo = extraInfoStream.str(); - error(line, " wrong operand type", op, extraInfo.c_str()); + std::stringstream reasonStream; + reasonStream << "wrong operand type - no operation '" << op + << "' exists that takes an operand of type " << operand + << " (or there is no acceptable conversion)"; + std::string reason = reasonStream.str(); + error(line, reason.c_str(), op); } // @@ -212,102 +410,85 @@ void TParseContext::binaryOpError(const TSourceLoc &line, TString left, TString right) { - std::stringstream extraInfoStream; - extraInfoStream << "no operation '" << op << "' exists that takes a left-hand operand of type '" - << left << "' and a right operand of type '" << right - << "' (or there is no acceptable conversion)"; - std::string extraInfo = extraInfoStream.str(); - error(line, " wrong operand types ", op, extraInfo.c_str()); + std::stringstream reasonStream; + reasonStream << "wrong operand types - no operation '" << op + << "' exists that takes a left-hand operand of type '" << left + << "' and a right operand of type '" << right + << "' (or there is no acceptable conversion)"; + std::string reason = reasonStream.str(); + error(line, reason.c_str(), op); } -bool TParseContext::precisionErrorCheck(const TSourceLoc &line, - TPrecision precision, - TBasicType type) +void TParseContext::checkPrecisionSpecified(const TSourceLoc &line, + TPrecision precision, + TBasicType type) { if (!mChecksPrecisionErrors) - return false; + return; + + if (precision != EbpUndefined && !SupportsPrecision(type)) + { + error(line, "illegal type for precision qualifier", getBasicString(type)); + } + if (precision == EbpUndefined) { switch (type) { case EbtFloat: error(line, "No precision specified for (float)", ""); - return true; + return; case EbtInt: case EbtUInt: UNREACHABLE(); // there's always a predeclared qualifier error(line, "No precision specified (int)", ""); - return true; + return; default: - if (IsSampler(type)) + if (IsOpaqueType(type)) { - error(line, "No precision specified (sampler)", ""); - return true; + error(line, "No precision specified", getBasicString(type)); + return; } } } - return false; } -// // Both test and if necessary, spit out an error, to see if the node is really // an l-value that can be operated on this way. -// -// Returns true if the was an error. -// -bool TParseContext::lValueErrorCheck(const TSourceLoc &line, const char *op, TIntermTyped *node) +bool TParseContext::checkCanBeLValue(const TSourceLoc &line, const char *op, TIntermTyped *node) { - TIntermSymbol *symNode = node->getAsSymbolNode(); - TIntermBinary *binaryNode = node->getAsBinaryNode(); + TIntermSymbol *symNode = node->getAsSymbolNode(); + TIntermBinary *binaryNode = node->getAsBinaryNode(); + TIntermSwizzle *swizzleNode = node->getAsSwizzleNode(); + + if (swizzleNode) + { + bool ok = checkCanBeLValue(line, op, swizzleNode->getOperand()); + if (ok && swizzleNode->hasDuplicateOffsets()) + { + error(line, " l-value of swizzle cannot have duplicate components", op); + return false; + } + return ok; + } if (binaryNode) { - bool errorReturn; - switch (binaryNode->getOp()) { case EOpIndexDirect: case EOpIndexIndirect: case EOpIndexDirectStruct: case EOpIndexDirectInterfaceBlock: - return lValueErrorCheck(line, op, binaryNode->getLeft()); - case EOpVectorSwizzle: - errorReturn = lValueErrorCheck(line, op, binaryNode->getLeft()); - if (!errorReturn) - { - int offset[4] = {0, 0, 0, 0}; - - TIntermTyped *rightNode = binaryNode->getRight(); - TIntermAggregate *aggrNode = rightNode->getAsAggregate(); - - for (TIntermSequence::iterator p = aggrNode->getSequence()->begin(); - p != aggrNode->getSequence()->end(); p++) - { - int value = (*p)->getAsTyped()->getAsConstantUnion()->getIConst(0); - offset[value]++; - if (offset[value] > 1) - { - error(line, " l-value of swizzle cannot have duplicate components", op); - - return true; - } - } - } - - return errorReturn; + return checkCanBeLValue(line, op, binaryNode->getLeft()); default: break; } error(line, " l-value required", op); - - return true; + return false; } - const char *symbol = 0; - if (symNode != 0) - symbol = symNode->getSymbol().c_str(); - - const char *message = 0; + std::string message; switch (node->getQualifier()) { case EvqConst: @@ -320,9 +501,11 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc &line, const char *op, TIn message = "can't modify an attribute"; break; case EvqFragmentIn: - message = "can't modify an input"; - break; case EvqVertexIn: + case EvqGeometryIn: + case EvqFlatIn: + case EvqSmoothIn: + case EvqCentroidIn: message = "can't modify an input"; break; case EvqUniform: @@ -340,6 +523,51 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc &line, const char *op, TIn case EvqPointCoord: message = "can't modify gl_PointCoord"; break; + case EvqNumWorkGroups: + message = "can't modify gl_NumWorkGroups"; + break; + case EvqWorkGroupSize: + message = "can't modify gl_WorkGroupSize"; + break; + case EvqWorkGroupID: + message = "can't modify gl_WorkGroupID"; + break; + case EvqLocalInvocationID: + message = "can't modify gl_LocalInvocationID"; + break; + case EvqGlobalInvocationID: + message = "can't modify gl_GlobalInvocationID"; + break; + case EvqLocalInvocationIndex: + message = "can't modify gl_LocalInvocationIndex"; + break; + case EvqViewIDOVR: + message = "can't modify gl_ViewID_OVR"; + break; + case EvqComputeIn: + message = "can't modify work group size variable"; + break; + case EvqPerVertexIn: + message = "can't modify any member in gl_in"; + break; + case EvqPrimitiveIDIn: + message = "can't modify gl_PrimitiveIDIn"; + break; + case EvqInvocationID: + message = "can't modify gl_InvocationID"; + break; + case EvqPrimitiveID: + if (mShaderType == GL_FRAGMENT_SHADER) + { + message = "can't modify gl_PrimitiveID in a fragment shader"; + } + break; + case EvqLayer: + if (mShaderType == GL_FRAGMENT_SHADER) + { + message = "can't modify gl_Layer in a fragment shader"; + } + break; default: // // Type that can't be written to? @@ -348,287 +576,270 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc &line, const char *op, TIn { message = "can't modify void"; } - if (IsSampler(node->getBasicType())) + if (IsOpaqueType(node->getBasicType())) { - message = "can't modify a sampler"; + message = "can't modify a variable with type "; + message += getBasicString(node->getBasicType()); + } + else if (node->getMemoryQualifier().readonly) + { + message = "can't modify a readonly variable"; } } - if (message == 0 && binaryNode == 0 && symNode == 0) + if (message.empty() && binaryNode == 0 && symNode == 0) { - error(line, " l-value required", op); + error(line, "l-value required", op); - return true; + return false; } // // Everything else is okay, no error. // - if (message == 0) - return false; + if (message.empty()) + return true; // // If we get here, we have an error and a message. // if (symNode) { - std::stringstream extraInfoStream; - extraInfoStream << "\"" << symbol << "\" (" << message << ")"; - std::string extraInfo = extraInfoStream.str(); - error(line, " l-value required", op, extraInfo.c_str()); + const char *symbol = symNode->getSymbol().c_str(); + std::stringstream reasonStream; + reasonStream << "l-value required (" << message << " \"" << symbol << "\")"; + std::string reason = reasonStream.str(); + error(line, reason.c_str(), op); } else { - std::stringstream extraInfoStream; - extraInfoStream << "(" << message << ")"; - std::string extraInfo = extraInfoStream.str(); - error(line, " l-value required", op, extraInfo.c_str()); - } - - return true; -} - -// -// Both test, and if necessary spit out an error, to see if the node is really -// a constant. -// -// Returns true if the was an error. -// -bool TParseContext::constErrorCheck(TIntermTyped *node) -{ - if (node->getQualifier() == EvqConst) - return false; - - error(node->getLine(), "constant expression required", ""); - - return true; -} - -// -// Both test, and if necessary spit out an error, to see if the node is really -// an integer. -// -// Returns true if the was an error. -// -bool TParseContext::integerErrorCheck(TIntermTyped *node, const char *token) -{ - if (node->isScalarInt()) - return false; - - error(node->getLine(), "integer expression required", token); - - return true; -} - -// -// Both test, and if necessary spit out an error, to see if we are currently -// globally scoped. -// -// Returns true if the was an error. -// -bool TParseContext::globalErrorCheck(const TSourceLoc &line, bool global, const char *token) -{ - if (global) - return false; - - error(line, "only allowed at global scope", token); - - return true; -} - -// -// For now, keep it simple: if it starts "gl_", it's reserved, independent -// of scope. Except, if the symbol table is at the built-in push-level, -// which is when we are parsing built-ins. -// Also checks for "webgl_" and "_webgl_" reserved identifiers if parsing a -// webgl shader. -// -// Returns true if there was an error. -// -bool TParseContext::reservedErrorCheck(const TSourceLoc &line, const TString &identifier) -{ - static const char *reservedErrMsg = "reserved built-in name"; - if (!symbolTable.atBuiltInLevel()) - { - if (identifier.compare(0, 3, "gl_") == 0) - { - error(line, reservedErrMsg, "gl_"); - return true; - } - if (IsWebGLBasedSpec(mShaderSpec)) - { - if (identifier.compare(0, 6, "webgl_") == 0) - { - error(line, reservedErrMsg, "webgl_"); - return true; - } - if (identifier.compare(0, 7, "_webgl_") == 0) - { - error(line, reservedErrMsg, "_webgl_"); - return true; - } - if (mShaderSpec == SH_CSS_SHADERS_SPEC && identifier.compare(0, 4, "css_") == 0) - { - error(line, reservedErrMsg, "css_"); - return true; - } - } - if (identifier.find("__") != TString::npos) - { - error(line, - "identifiers containing two consecutive underscores (__) are reserved as " - "possible future keywords", - identifier.c_str()); - return true; - } + std::stringstream reasonStream; + reasonStream << "l-value required (" << message << ")"; + std::string reason = reasonStream.str(); + error(line, reason.c_str(), op); } return false; } -// -// Make sure there is enough data provided to the constructor to build -// something of the type of the constructor. Also returns the type of -// the constructor. -// -// Returns true if there was an error in construction. -// -bool TParseContext::constructorErrorCheck(const TSourceLoc &line, - TIntermNode *argumentsNode, - TFunction &function, - TOperator op, - TType *type) +// Both test, and if necessary spit out an error, to see if the node is really +// a constant. +void TParseContext::checkIsConst(TIntermTyped *node) { - *type = function.getReturnType(); - - bool constructingMatrix = false; - switch (op) + if (node->getQualifier() != EvqConst) { - case EOpConstructMat2: - case EOpConstructMat2x3: - case EOpConstructMat2x4: - case EOpConstructMat3x2: - case EOpConstructMat3: - case EOpConstructMat3x4: - case EOpConstructMat4x2: - case EOpConstructMat4x3: - case EOpConstructMat4: - constructingMatrix = true; - break; - default: - break; + error(node->getLine(), "constant expression required", ""); } +} - // - // Note: It's okay to have too many components available, but not okay to have unused - // arguments. 'full' will go to true when enough args have been seen. If we loop - // again, there is an extra argument, so 'overfull' will become true. - // - - size_t size = 0; - bool constType = true; - bool full = false; - bool overFull = false; - bool matrixInMatrix = false; - bool arrayArg = false; - for (size_t i = 0; i < function.getParamCount(); ++i) +// Both test, and if necessary spit out an error, to see if the node is really +// an integer. +void TParseContext::checkIsScalarInteger(TIntermTyped *node, const char *token) +{ + if (!node->isScalarInt()) { - const TConstParameter ¶m = function.getParam(i); - size += param.type->getObjectSize(); - - if (constructingMatrix && param.type->isMatrix()) - matrixInMatrix = true; - if (full) - overFull = true; - if (op != EOpConstructStruct && !type->isArray() && size >= type->getObjectSize()) - full = true; - if (param.type->getQualifier() != EvqConst) - constType = false; - if (param.type->isArray()) - arrayArg = true; + error(node->getLine(), "integer expression required", token); } +} - if (constType) - type->setQualifier(EvqConst); - - if (type->isArray()) +// Both test, and if necessary spit out an error, to see if we are currently +// globally scoped. +bool TParseContext::checkIsAtGlobalLevel(const TSourceLoc &line, const char *token) +{ + if (!symbolTable.atGlobalLevel()) { - if (type->isUnsizedArray()) + error(line, "only allowed at global scope", token); + return false; + } + return true; +} + +// ESSL 3.00.5 sections 3.8 and 3.9. +// If it starts "gl_" or contains two consecutive underscores, it's reserved. +// Also checks for "webgl_" and "_webgl_" reserved identifiers if parsing a webgl shader. +bool TParseContext::checkIsNotReserved(const TSourceLoc &line, const TString &identifier) +{ + static const char *reservedErrMsg = "reserved built-in name"; + if (identifier.compare(0, 3, "gl_") == 0) + { + error(line, reservedErrMsg, "gl_"); + return false; + } + if (sh::IsWebGLBasedSpec(mShaderSpec)) + { + if (identifier.compare(0, 6, "webgl_") == 0) { - type->setArraySize(static_cast(function.getParamCount())); + error(line, reservedErrMsg, "webgl_"); + return false; } - else if (static_cast(type->getArraySize()) != function.getParamCount()) + if (identifier.compare(0, 7, "_webgl_") == 0) { - error(line, "array constructor needs one argument per array element", "constructor"); - return true; + error(line, reservedErrMsg, "_webgl_"); + return false; } } - - if (arrayArg && op != EOpConstructStruct) - { - error(line, "constructing from a non-dereferenced array", "constructor"); - return true; - } - - if (matrixInMatrix && !type->isArray()) - { - if (function.getParamCount() != 1) - { - error(line, "constructing matrix from matrix can only take one argument", - "constructor"); - return true; - } - } - - if (overFull) - { - error(line, "too many arguments", "constructor"); - return true; - } - - if (op == EOpConstructStruct && !type->isArray() && - type->getStruct()->fields().size() != function.getParamCount()) + if (identifier.find("__") != TString::npos) { error(line, - "Number of constructor parameters does not match the number of structure fields", - "constructor"); - return true; + "identifiers containing two consecutive underscores (__) are reserved as " + "possible future keywords", + identifier.c_str()); + return false; } + return true; +} - if (!type->isMatrix() || !matrixInMatrix) - { - if ((op != EOpConstructStruct && size != 1 && size < type->getObjectSize()) || - (op == EOpConstructStruct && size < type->getObjectSize())) - { - error(line, "not enough data provided for construction", "constructor"); - return true; - } - } - - if (argumentsNode == nullptr) +// Make sure the argument types are correct for constructing a specific type. +bool TParseContext::checkConstructorArguments(const TSourceLoc &line, + const TIntermSequence *arguments, + const TType &type) +{ + if (arguments->empty()) { error(line, "constructor does not have any arguments", "constructor"); - return true; + return false; } - TIntermAggregate *argumentsAgg = argumentsNode->getAsAggregate(); - for (TIntermNode *&argNode : *argumentsAgg->getSequence()) + for (TIntermNode *arg : *arguments) { - TIntermTyped *argTyped = argNode->getAsTyped(); + const TIntermTyped *argTyped = arg->getAsTyped(); ASSERT(argTyped != nullptr); - if (op != EOpConstructStruct && IsSampler(argTyped->getBasicType())) + if (type.getBasicType() != EbtStruct && IsOpaqueType(argTyped->getBasicType())) { - error(line, "cannot convert a sampler", "constructor"); - return true; + std::string reason("cannot convert a variable with type "); + reason += getBasicString(argTyped->getBasicType()); + error(line, reason.c_str(), "constructor"); + return false; + } + else if (argTyped->getMemoryQualifier().writeonly) + { + error(line, "cannot convert a variable with writeonly", "constructor"); + return false; } if (argTyped->getBasicType() == EbtVoid) { error(line, "cannot convert a void", "constructor"); - return true; + return false; } } - return false; + if (type.isArray()) + { + // The size of an unsized constructor should already have been determined. + ASSERT(!type.isUnsizedArray()); + if (static_cast(type.getOutermostArraySize()) != arguments->size()) + { + error(line, "array constructor needs one argument per array element", "constructor"); + return false; + } + // GLSL ES 3.00 section 5.4.4: Each argument must be the same type as the element type of + // the array. + for (TIntermNode *const &argNode : *arguments) + { + const TType &argType = argNode->getAsTyped()->getType(); + if (mShaderVersion < 310 && argType.isArray()) + { + error(line, "constructing from a non-dereferenced array", "constructor"); + return false; + } + if (!argType.isElementTypeOf(type)) + { + error(line, "Array constructor argument has an incorrect type", "constructor"); + return false; + } + } + } + else if (type.getBasicType() == EbtStruct) + { + const TFieldList &fields = type.getStruct()->fields(); + if (fields.size() != arguments->size()) + { + error(line, + "Number of constructor parameters does not match the number of structure fields", + "constructor"); + return false; + } + + for (size_t i = 0; i < fields.size(); i++) + { + if (i >= arguments->size() || + (*arguments)[i]->getAsTyped()->getType() != *fields[i]->type()) + { + error(line, "Structure constructor arguments do not match structure fields", + "constructor"); + return false; + } + } + } + else + { + // We're constructing a scalar, vector, or matrix. + + // Note: It's okay to have too many components available, but not okay to have unused + // arguments. 'full' will go to true when enough args have been seen. If we loop again, + // there is an extra argument, so 'overFull' will become true. + + size_t size = 0; + bool full = false; + bool overFull = false; + bool matrixArg = false; + for (TIntermNode *arg : *arguments) + { + const TIntermTyped *argTyped = arg->getAsTyped(); + ASSERT(argTyped != nullptr); + + if (argTyped->getBasicType() == EbtStruct) + { + error(line, "a struct cannot be used as a constructor argument for this type", + "constructor"); + return false; + } + if (argTyped->getType().isArray()) + { + error(line, "constructing from a non-dereferenced array", "constructor"); + return false; + } + if (argTyped->getType().isMatrix()) + { + matrixArg = true; + } + + size += argTyped->getType().getObjectSize(); + if (full) + { + overFull = true; + } + if (size >= type.getObjectSize()) + { + full = true; + } + } + + if (type.isMatrix() && matrixArg) + { + if (arguments->size() != 1) + { + error(line, "constructing matrix from matrix can only take one argument", + "constructor"); + return false; + } + } + else + { + if (size != 1 && size < type.getObjectSize()) + { + error(line, "not enough data provided for construction", "constructor"); + return false; + } + if (overFull) + { + error(line, "too many arguments", "constructor"); + return false; + } + } + } + + return true; } // This function checks to see if a void variable has been declared and raise an error message for @@ -636,126 +847,116 @@ bool TParseContext::constructorErrorCheck(const TSourceLoc &line, // // returns true in case of an error // -bool TParseContext::voidErrorCheck(const TSourceLoc &line, +bool TParseContext::checkIsNonVoid(const TSourceLoc &line, const TString &identifier, const TBasicType &type) { if (type == EbtVoid) { error(line, "illegal use of type 'void'", identifier.c_str()); - return true; + return false; } - return false; + return true; } // This function checks to see if the node (for the expression) contains a scalar boolean expression -// or not -// -// returns true in case of an error -// -bool TParseContext::boolErrorCheck(const TSourceLoc &line, const TIntermTyped *type) +// or not. +bool TParseContext::checkIsScalarBool(const TSourceLoc &line, const TIntermTyped *type) { - if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) + if (type->getBasicType() != EbtBool || !type->isScalar()) { error(line, "boolean expression expected", ""); - return true; + return false; } - - return false; + return true; } // This function checks to see if the node (for the expression) contains a scalar boolean expression -// or not -// -// returns true in case of an error -// -bool TParseContext::boolErrorCheck(const TSourceLoc &line, const TPublicType &pType) +// or not. +void TParseContext::checkIsScalarBool(const TSourceLoc &line, const TPublicType &pType) { - if (pType.type != EbtBool || pType.isAggregate()) + if (pType.getBasicType() != EbtBool || pType.isAggregate()) { error(line, "boolean expression expected", ""); - return true; } - - return false; } -bool TParseContext::samplerErrorCheck(const TSourceLoc &line, - const TPublicType &pType, - const char *reason) +bool TParseContext::checkIsNotOpaqueType(const TSourceLoc &line, + const TTypeSpecifierNonArray &pType, + const char *reason) { if (pType.type == EbtStruct) { - if (containsSampler(*pType.userDef)) + if (ContainsSampler(pType.userDef)) { - error(line, reason, getBasicString(pType.type), "(structure contains a sampler)"); - - return true; + std::stringstream reasonStream; + reasonStream << reason << " (structure contains a sampler)"; + std::string reasonStr = reasonStream.str(); + error(line, reasonStr.c_str(), getBasicString(pType.type)); + return false; } - - return false; - } - else if (IsSampler(pType.type)) - { - error(line, reason, getBasicString(pType.type)); - + // only samplers need to be checked from structs, since other opaque types can't be struct + // members. return true; } + else if (IsOpaqueType(pType.type)) + { + error(line, reason, getBasicString(pType.type)); + return false; + } - return false; + return true; } -bool TParseContext::locationDeclaratorListCheck(const TSourceLoc &line, const TPublicType &pType) +void TParseContext::checkDeclaratorLocationIsNotSpecified(const TSourceLoc &line, + const TPublicType &pType) { if (pType.layoutQualifier.location != -1) { error(line, "location must only be specified for a single input or output variable", "location"); - return true; } - - return false; } -bool TParseContext::parameterSamplerErrorCheck(const TSourceLoc &line, - TQualifier qualifier, - const TType &type) +void TParseContext::checkLocationIsNotSpecified(const TSourceLoc &location, + const TLayoutQualifier &layoutQualifier) { - if ((qualifier == EvqOut || qualifier == EvqInOut) && type.getBasicType() != EbtStruct && - IsSampler(type.getBasicType())) + if (layoutQualifier.location != -1) { - error(line, "samplers cannot be output parameters", type.getBasicString()); - return true; - } - - return false; -} - -bool TParseContext::containsSampler(const TType &type) -{ - if (IsSampler(type.getBasicType())) - return true; - - if (type.getBasicType() == EbtStruct || type.isInterfaceBlock()) - { - const TFieldList &fields = type.getStruct()->fields(); - for (unsigned int i = 0; i < fields.size(); ++i) + const char *errorMsg = "invalid layout qualifier: only valid on program inputs and outputs"; + if (mShaderVersion >= 310) { - if (containsSampler(*fields[i]->type())) - return true; + errorMsg = + "invalid layout qualifier: only valid on shader inputs, outputs, and uniforms"; } + error(location, errorMsg, "location"); + } +} + +void TParseContext::checkStd430IsForShaderStorageBlock(const TSourceLoc &location, + const TLayoutBlockStorage &blockStorage, + const TQualifier &qualifier) +{ + if (blockStorage == EbsStd430 && qualifier != EvqBuffer) + { + error(location, "The std430 layout is supported only for shader storage blocks.", "std430"); + } +} + +void TParseContext::checkOutParameterIsNotOpaqueType(const TSourceLoc &line, + TQualifier qualifier, + const TType &type) +{ + ASSERT(qualifier == EvqOut || qualifier == EvqInOut); + if (IsOpaqueType(type.getBasicType())) + { + error(line, "opaque types cannot be output parameters", type.getBasicString()); } - - return false; } -// // Do size checking for an array type's size. -// -// Returns true if there was an error. -// -bool TParseContext::arraySizeErrorCheck(const TSourceLoc &line, TIntermTyped *expr, int &size) +unsigned int TParseContext::checkIsValidArraySize(const TSourceLoc &line, TIntermTyped *expr) { TIntermConstantUnion *constant = expr->getAsConstantUnion(); @@ -765,36 +966,32 @@ bool TParseContext::arraySizeErrorCheck(const TSourceLoc &line, TIntermTyped *ex if (expr->getQualifier() != EvqConst || constant == nullptr || !constant->isScalarInt()) { error(line, "array size must be a constant integer expression", ""); - size = 1; - return true; + return 1u; } - unsigned int unsignedSize = 0; + unsigned int size = 0u; if (constant->getBasicType() == EbtUInt) { - unsignedSize = constant->getUConst(0); - size = static_cast(unsignedSize); + size = constant->getUConst(0); } else { - size = constant->getIConst(0); + int signedSize = constant->getIConst(0); - if (size < 0) + if (signedSize < 0) { error(line, "array size must be non-negative", ""); - size = 1; - return true; + return 1u; } - unsignedSize = static_cast(size); + size = static_cast(signedSize); } - if (size == 0) + if (size == 0u) { error(line, "array size must be greater than zero", ""); - size = 1; - return true; + return 1u; } // The size of arrays is restricted here to prevent issues further down the @@ -802,76 +999,80 @@ bool TParseContext::arraySizeErrorCheck(const TSourceLoc &line, TIntermTyped *ex // 4096 registers so this should be reasonable even for aggressively optimizable code. const unsigned int sizeLimit = 65536; - if (unsignedSize > sizeLimit) + if (size > sizeLimit) { error(line, "array size too large", ""); - size = 1; - return true; + return 1u; } - return false; + return size; } -// // See if this qualifier can be an array. -// -// Returns true if there is an error. -// -bool TParseContext::arrayQualifierErrorCheck(const TSourceLoc &line, const TPublicType &type) +bool TParseContext::checkIsValidQualifierForArray(const TSourceLoc &line, + const TPublicType &elementQualifier) { - if ((type.qualifier == EvqAttribute) || (type.qualifier == EvqVertexIn) || - (type.qualifier == EvqConst && mShaderVersion < 300)) + if ((elementQualifier.qualifier == EvqAttribute) || + (elementQualifier.qualifier == EvqVertexIn) || + (elementQualifier.qualifier == EvqConst && mShaderVersion < 300)) { error(line, "cannot declare arrays of this qualifier", - TType(type).getCompleteString().c_str()); - return true; + TType(elementQualifier).getQualifierString()); + return false; } - return false; + return true; } -// -// See if this type can be an array. -// -// Returns true if there is an error. -// -bool TParseContext::arrayTypeErrorCheck(const TSourceLoc &line, const TPublicType &type) +// See if this element type can be formed into an array. +bool TParseContext::checkArrayElementIsNotArray(const TSourceLoc &line, + const TPublicType &elementType) { - // - // Can the type be an array? - // - if (type.array) + if (mShaderVersion < 310 && elementType.isArray()) { - error(line, "cannot declare arrays of arrays", TType(type).getCompleteString().c_str()); - return true; + error(line, "cannot declare arrays of arrays", + TType(elementType).getCompleteString().c_str()); + return false; + } + return true; +} + +// Check if this qualified element type can be formed into an array. This is only called when array +// brackets are associated with an identifier in a declaration, like this: +// float a[2]; +// Similar checks are done in addFullySpecifiedType for array declarations where the array brackets +// are associated with the type, like this: +// float[2] a; +bool TParseContext::checkIsValidTypeAndQualifierForArray(const TSourceLoc &indexLocation, + const TPublicType &elementType) +{ + if (!checkArrayElementIsNotArray(indexLocation, elementType)) + { + return false; } // In ESSL1.00 shaders, structs cannot be varying (section 4.3.5). This is checked elsewhere. // In ESSL3.00 shaders, struct inputs/outputs are allowed but not arrays of structs (section // 4.3.4). - if (mShaderVersion >= 300 && type.type == EbtStruct && sh::IsVarying(type.qualifier)) + if (mShaderVersion >= 300 && elementType.getBasicType() == EbtStruct && + sh::IsVarying(elementType.qualifier)) { - error(line, "cannot declare arrays of structs of this qualifier", - TType(type).getCompleteString().c_str()); - return true; + error(indexLocation, "cannot declare arrays of structs of this qualifier", + TType(elementType).getCompleteString().c_str()); + return false; } - - return false; + return checkIsValidQualifierForArray(indexLocation, elementType); } -// // Enforce non-initializer type/qualifier rules. -// -// Returns true if there was an error. -// -bool TParseContext::nonInitErrorCheck(const TSourceLoc &line, - const TString &identifier, - TPublicType *type) +void TParseContext::checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line, + const TString &identifier, + TType *type) { ASSERT(type != nullptr); - if (type->qualifier == EvqConst) + if (type->getQualifier() == EvqConst) { // Make the qualifier make sense. - type->qualifier = EvqTemporary; + type->setQualifier(EvqTemporary); // Generate informative error messages for ESSL1. // In ESSL3 arrays and structures containing arrays can be constant. @@ -886,15 +1087,10 @@ bool TParseContext::nonInitErrorCheck(const TSourceLoc &line, { error(line, "variables with qualifier 'const' must be initialized", identifier.c_str()); } - - return true; } - if (type->isUnsizedArray()) - { - error(line, "implicitly sized arrays need to be initialized", identifier.c_str()); - return true; - } - return false; + // This will make the type sized if it isn't sized yet. + checkIsNotUnsizedArray(line, "implicitly sized arrays need to be initialized", + identifier.c_str(), type); } // Do some simple checks that are shared between all variable declarations, @@ -909,18 +1105,27 @@ bool TParseContext::declareVariable(const TSourceLoc &line, { ASSERT((*variable) == nullptr); - bool needsReservedErrorCheck = true; + checkBindingIsValid(line, type); + + bool needsReservedCheck = true; // gl_LastFragData may be redeclared with a new precision qualifier if (type.isArray() && identifier.compare(0, 15, "gl_LastFragData") == 0) { const TVariable *maxDrawBuffers = static_cast( symbolTable.findBuiltIn("gl_MaxDrawBuffers", mShaderVersion)); - if (type.getArraySize() == maxDrawBuffers->getConstPointer()->getIConst()) + if (type.isArrayOfArrays()) + { + error(line, "redeclaration of gl_LastFragData as an array of arrays", + identifier.c_str()); + return false; + } + else if (static_cast(type.getOutermostArraySize()) == + maxDrawBuffers->getConstPointer()->getIConst()) { if (TSymbol *builtInSymbol = symbolTable.findBuiltIn(identifier, mShaderVersion)) { - needsReservedErrorCheck = extensionErrorCheck(line, builtInSymbol->getExtension()); + needsReservedCheck = !checkCanUseExtension(line, builtInSymbol->getExtension()); } } else @@ -931,77 +1136,237 @@ bool TParseContext::declareVariable(const TSourceLoc &line, } } - if (needsReservedErrorCheck && reservedErrorCheck(line, identifier)) + if (needsReservedCheck && !checkIsNotReserved(line, identifier)) return false; - (*variable) = new TVariable(&identifier, type); - if (!symbolTable.declare(*variable)) + (*variable) = symbolTable.declareVariable(&identifier, type); + if (!(*variable)) { error(line, "redefinition", identifier.c_str()); - *variable = nullptr; return false; } - if (voidErrorCheck(line, identifier, type.getBasicType())) + if (!checkIsNonVoid(line, identifier, type.getBasicType())) return false; return true; } -bool TParseContext::paramErrorCheck(const TSourceLoc &line, - TQualifier qualifier, - TQualifier paramQualifier, - TType *type) +void TParseContext::checkIsParameterQualifierValid( + const TSourceLoc &line, + const TTypeQualifierBuilder &typeQualifierBuilder, + TType *type) { - if (qualifier != EvqConst && qualifier != EvqTemporary) + // The only parameter qualifiers a parameter can have are in, out, inout or const. + TTypeQualifier typeQualifier = typeQualifierBuilder.getParameterTypeQualifier(mDiagnostics); + + if (typeQualifier.qualifier == EvqOut || typeQualifier.qualifier == EvqInOut) { - error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier)); - return true; - } - if (qualifier == EvqConst && paramQualifier != EvqIn) - { - error(line, "qualifier not allowed with ", getQualifierString(qualifier), - getQualifierString(paramQualifier)); - return true; + checkOutParameterIsNotOpaqueType(line, typeQualifier.qualifier, *type); } - if (qualifier == EvqConst) - type->setQualifier(EvqConstReadOnly); + if (!IsImage(type->getBasicType())) + { + checkMemoryQualifierIsNotSpecified(typeQualifier.memoryQualifier, line); + } else - type->setQualifier(paramQualifier); + { + type->setMemoryQualifier(typeQualifier.memoryQualifier); + } - return false; + type->setQualifier(typeQualifier.qualifier); + + if (typeQualifier.precision != EbpUndefined) + { + type->setPrecision(typeQualifier.precision); + } } -bool TParseContext::extensionErrorCheck(const TSourceLoc &line, const TString &extension) +template +bool TParseContext::checkCanUseOneOfExtensions(const TSourceLoc &line, + const std::array &extensions) { - const TExtensionBehavior &extBehavior = extensionBehavior(); - TExtensionBehavior::const_iterator iter = extBehavior.find(extension.c_str()); - if (iter == extBehavior.end()) + ASSERT(!extensions.empty()); + const TExtensionBehavior &extBehavior = extensionBehavior(); + + bool canUseWithWarning = false; + bool canUseWithoutWarning = false; + + const char *errorMsgString = ""; + TExtension errorMsgExtension = TExtension::UNDEFINED; + + for (TExtension extension : extensions) { - error(line, "extension", extension.c_str(), "is not supported"); - return true; - } - // In GLSL ES, an extension's default behavior is "disable". - if (iter->second == EBhDisable || iter->second == EBhUndefined) - { - error(line, "extension", extension.c_str(), "is disabled"); - return true; - } - if (iter->second == EBhWarn) - { - warning(line, "extension", extension.c_str(), "is being used"); - return false; + auto extIter = extBehavior.find(extension); + if (canUseWithWarning) + { + // We already have an extension that we can use, but with a warning. + // See if we can use the alternative extension without a warning. + if (extIter == extBehavior.end()) + { + continue; + } + if (extIter->second == EBhEnable || extIter->second == EBhRequire) + { + canUseWithoutWarning = true; + break; + } + continue; + } + if (extIter == extBehavior.end()) + { + errorMsgString = "extension is not supported"; + errorMsgExtension = extension; + } + else if (extIter->second == EBhUndefined || extIter->second == EBhDisable) + { + errorMsgString = "extension is disabled"; + errorMsgExtension = extension; + } + else if (extIter->second == EBhWarn) + { + errorMsgExtension = extension; + canUseWithWarning = true; + } + else + { + ASSERT(extIter->second == EBhEnable || extIter->second == EBhRequire); + canUseWithoutWarning = true; + break; + } } + if (canUseWithoutWarning) + { + return true; + } + if (canUseWithWarning) + { + warning(line, "extension is being used", GetExtensionNameString(errorMsgExtension)); + return true; + } + error(line, errorMsgString, GetExtensionNameString(errorMsgExtension)); return false; } -// These checks are common for all declarations starting a declarator list, and declarators that -// follow an empty declaration. -// -bool TParseContext::singleDeclarationErrorCheck(const TPublicType &publicType, - const TSourceLoc &identifierLocation) +template bool TParseContext::checkCanUseOneOfExtensions( + const TSourceLoc &line, + const std::array &extensions); +template bool TParseContext::checkCanUseOneOfExtensions( + const TSourceLoc &line, + const std::array &extensions); +template bool TParseContext::checkCanUseOneOfExtensions( + const TSourceLoc &line, + const std::array &extensions); + +bool TParseContext::checkCanUseExtension(const TSourceLoc &line, TExtension extension) +{ + ASSERT(extension != TExtension::UNDEFINED); + ASSERT(extension != TExtension::EXT_geometry_shader); + if (extension == TExtension::OES_geometry_shader) + { + // OES_geometry_shader and EXT_geometry_shader are always interchangeable. + constexpr std::array extensions{ + {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}}; + return checkCanUseOneOfExtensions(line, extensions); + } + return checkCanUseOneOfExtensions(line, std::array{{extension}}); +} + +// ESSL 3.00.6 section 4.8 Empty Declarations: "The combinations of qualifiers that cause +// compile-time or link-time errors are the same whether or not the declaration is empty". +// This function implements all the checks that are done on qualifiers regardless of if the +// declaration is empty. +void TParseContext::declarationQualifierErrorCheck(const sh::TQualifier qualifier, + const sh::TLayoutQualifier &layoutQualifier, + const TSourceLoc &location) +{ + if (qualifier == EvqShared && !layoutQualifier.isEmpty()) + { + error(location, "Shared memory declarations cannot have layout specified", "layout"); + } + + if (layoutQualifier.matrixPacking != EmpUnspecified) + { + error(location, "layout qualifier only valid for interface blocks", + getMatrixPackingString(layoutQualifier.matrixPacking)); + return; + } + + if (layoutQualifier.blockStorage != EbsUnspecified) + { + error(location, "layout qualifier only valid for interface blocks", + getBlockStorageString(layoutQualifier.blockStorage)); + return; + } + + if (qualifier == EvqFragmentOut) + { + if (layoutQualifier.location != -1 && layoutQualifier.yuv == true) + { + error(location, "invalid layout qualifier combination", "yuv"); + return; + } + } + else + { + checkYuvIsNotSpecified(location, layoutQualifier.yuv); + } + + // If multiview extension is enabled, "in" qualifier is allowed in the vertex shader in previous + // parsing steps. So it needs to be checked here. + if (isExtensionEnabled(TExtension::OVR_multiview) && mShaderVersion < 300 && + qualifier == EvqVertexIn) + { + error(location, "storage qualifier supported in GLSL ES 3.00 and above only", "in"); + } + + bool canHaveLocation = qualifier == EvqVertexIn || qualifier == EvqFragmentOut; + if (mShaderVersion >= 310) + { + canHaveLocation = canHaveLocation || qualifier == EvqUniform || IsVarying(qualifier); + // We're not checking whether the uniform location is in range here since that depends on + // the type of the variable. + // The type can only be fully determined for non-empty declarations. + } + if (!canHaveLocation) + { + checkLocationIsNotSpecified(location, layoutQualifier); + } +} + +void TParseContext::atomicCounterQualifierErrorCheck(const TPublicType &publicType, + const TSourceLoc &location) +{ + if (publicType.precision != EbpHigh) + { + error(location, "Can only be highp", "atomic counter"); + } + // dEQP enforces compile error if location is specified. See uniform_location.test. + if (publicType.layoutQualifier.location != -1) + { + error(location, "location must not be set for atomic_uint", "layout"); + } + if (publicType.layoutQualifier.binding == -1) + { + error(location, "no binding specified", "atomic counter"); + } +} + +void TParseContext::emptyDeclarationErrorCheck(const TType &type, const TSourceLoc &location) +{ + if (type.isUnsizedArray()) + { + // ESSL3 spec section 4.1.9: Array declaration which leaves the size unspecified is an + // error. It is assumed that this applies to empty declarations as well. + error(location, "empty array declaration needs to specify a size", ""); + } +} + +// These checks are done for all declarations that are non-empty. They're done for non-empty +// declarations starting a declarator list, and declarators that follow an empty declaration. +void TParseContext::nonEmptyDeclarationErrorCheck(const TPublicType &publicType, + const TSourceLoc &identifierLocation) { switch (publicType.qualifier) { @@ -1010,105 +1375,363 @@ bool TParseContext::singleDeclarationErrorCheck(const TPublicType &publicType, case EvqAttribute: case EvqVertexIn: case EvqFragmentOut: - if (publicType.type == EbtStruct) + case EvqComputeIn: + if (publicType.getBasicType() == EbtStruct) { error(identifierLocation, "cannot be used with a structure", getQualifierString(publicType.qualifier)); - return true; + return; } - + break; + case EvqBuffer: + if (publicType.getBasicType() != EbtInterfaceBlock) + { + error(identifierLocation, + "cannot declare buffer variables at global scope(outside a block)", + getQualifierString(publicType.qualifier)); + return; + } + break; default: break; } - + std::string reason(getBasicString(publicType.getBasicType())); + reason += "s must be uniform"; if (publicType.qualifier != EvqUniform && - samplerErrorCheck(identifierLocation, publicType, "samplers must be uniform")) + !checkIsNotOpaqueType(identifierLocation, publicType.typeSpecifierNonArray, reason.c_str())) { - return true; + return; + } + + if ((publicType.qualifier != EvqTemporary && publicType.qualifier != EvqGlobal && + publicType.qualifier != EvqConst) && + publicType.getBasicType() == EbtYuvCscStandardEXT) + { + error(identifierLocation, "cannot be used with a yuvCscStandardEXT", + getQualifierString(publicType.qualifier)); + return; + } + + if (mShaderVersion >= 310 && publicType.qualifier == EvqUniform) + { + // Valid uniform declarations can't be unsized arrays since uniforms can't be initialized. + // But invalid shaders may still reach here with an unsized array declaration. + TType type(publicType); + if (!type.isUnsizedArray()) + { + checkUniformLocationInRange(identifierLocation, type.getLocationCount(), + publicType.layoutQualifier); + } } // check for layout qualifier issues const TLayoutQualifier layoutQualifier = publicType.layoutQualifier; - if (layoutQualifier.matrixPacking != EmpUnspecified) + if (IsImage(publicType.getBasicType())) { - error(identifierLocation, "layout qualifier", - getMatrixPackingString(layoutQualifier.matrixPacking), - "only valid for interface blocks"); - return true; + + switch (layoutQualifier.imageInternalFormat) + { + case EiifRGBA32F: + case EiifRGBA16F: + case EiifR32F: + case EiifRGBA8: + case EiifRGBA8_SNORM: + if (!IsFloatImage(publicType.getBasicType())) + { + error(identifierLocation, + "internal image format requires a floating image type", + getBasicString(publicType.getBasicType())); + return; + } + break; + case EiifRGBA32I: + case EiifRGBA16I: + case EiifRGBA8I: + case EiifR32I: + if (!IsIntegerImage(publicType.getBasicType())) + { + error(identifierLocation, + "internal image format requires an integer image type", + getBasicString(publicType.getBasicType())); + return; + } + break; + case EiifRGBA32UI: + case EiifRGBA16UI: + case EiifRGBA8UI: + case EiifR32UI: + if (!IsUnsignedImage(publicType.getBasicType())) + { + error(identifierLocation, + "internal image format requires an unsigned image type", + getBasicString(publicType.getBasicType())); + return; + } + break; + case EiifUnspecified: + error(identifierLocation, "layout qualifier", "No image internal format specified"); + return; + default: + error(identifierLocation, "layout qualifier", "unrecognized token"); + return; + } + + // GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers + switch (layoutQualifier.imageInternalFormat) + { + case EiifR32F: + case EiifR32I: + case EiifR32UI: + break; + default: + if (!publicType.memoryQualifier.readonly && !publicType.memoryQualifier.writeonly) + { + error(identifierLocation, "layout qualifier", + "Except for images with the r32f, r32i and r32ui format qualifiers, " + "image variables must be qualified readonly and/or writeonly"); + return; + } + break; + } + } + else + { + checkInternalFormatIsNotSpecified(identifierLocation, layoutQualifier.imageInternalFormat); + checkMemoryQualifierIsNotSpecified(publicType.memoryQualifier, identifierLocation); } - if (layoutQualifier.blockStorage != EbsUnspecified) + if (IsAtomicCounter(publicType.getBasicType())) { - error(identifierLocation, "layout qualifier", - getBlockStorageString(layoutQualifier.blockStorage), - "only valid for interface blocks"); - return true; + atomicCounterQualifierErrorCheck(publicType, identifierLocation); } - - if (publicType.qualifier != EvqVertexIn && publicType.qualifier != EvqFragmentOut && - layoutLocationErrorCheck(identifierLocation, publicType.layoutQualifier)) + else { - return true; + checkOffsetIsNotSpecified(identifierLocation, layoutQualifier.offset); } - - return false; } -bool TParseContext::layoutLocationErrorCheck(const TSourceLoc &location, - const TLayoutQualifier &layoutQualifier) +void TParseContext::checkBindingIsValid(const TSourceLoc &identifierLocation, const TType &type) { - if (layoutQualifier.location != -1) + TLayoutQualifier layoutQualifier = type.getLayoutQualifier(); + // Note that the ESSL 3.10 section 4.4.5 is not particularly clear on how the binding qualifier + // on arrays of arrays should be handled. We interpret the spec so that the binding value is + // incremented for each element of the innermost nested arrays. This is in line with how arrays + // of arrays of blocks are specified to behave in GLSL 4.50 and a conservative interpretation + // when it comes to which shaders are accepted by the compiler. + int arrayTotalElementCount = type.getArraySizeProduct(); + if (IsImage(type.getBasicType())) { - error(location, "invalid layout qualifier:", "location", - "only valid on program inputs and outputs"); - return true; + checkImageBindingIsValid(identifierLocation, layoutQualifier.binding, + arrayTotalElementCount); + } + else if (IsSampler(type.getBasicType())) + { + checkSamplerBindingIsValid(identifierLocation, layoutQualifier.binding, + arrayTotalElementCount); + } + else if (IsAtomicCounter(type.getBasicType())) + { + checkAtomicCounterBindingIsValid(identifierLocation, layoutQualifier.binding); + } + else + { + ASSERT(!IsOpaqueType(type.getBasicType())); + checkBindingIsNotSpecified(identifierLocation, layoutQualifier.binding); } - - return false; } -bool TParseContext::functionCallLValueErrorCheck(const TFunction *fnCandidate, - TIntermAggregate *aggregate) +void TParseContext::checkLayoutQualifierSupported(const TSourceLoc &location, + const TString &layoutQualifierName, + int versionRequired) +{ + + if (mShaderVersion < versionRequired) + { + error(location, "invalid layout qualifier: not supported", layoutQualifierName.c_str()); + } +} + +bool TParseContext::checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location, + const TLayoutQualifier &layoutQualifier) +{ + const sh::WorkGroupSize &localSize = layoutQualifier.localSize; + for (size_t i = 0u; i < localSize.size(); ++i) + { + if (localSize[i] != -1) + { + error(location, + "invalid layout qualifier: only valid when used with 'in' in a compute shader " + "global layout declaration", + getWorkGroupSizeString(i)); + return false; + } + } + + return true; +} + +void TParseContext::checkInternalFormatIsNotSpecified(const TSourceLoc &location, + TLayoutImageInternalFormat internalFormat) +{ + if (internalFormat != EiifUnspecified) + { + error(location, "invalid layout qualifier: only valid when used with images", + getImageInternalFormatString(internalFormat)); + } +} + +void TParseContext::checkBindingIsNotSpecified(const TSourceLoc &location, int binding) +{ + if (binding != -1) + { + error(location, + "invalid layout qualifier: only valid when used with opaque types or blocks", + "binding"); + } +} + +void TParseContext::checkOffsetIsNotSpecified(const TSourceLoc &location, int offset) +{ + if (offset != -1) + { + error(location, "invalid layout qualifier: only valid when used with atomic counters", + "offset"); + } +} + +void TParseContext::checkImageBindingIsValid(const TSourceLoc &location, + int binding, + int arrayTotalElementCount) +{ + // Expects arraySize to be 1 when setting binding for only a single variable. + if (binding >= 0 && binding + arrayTotalElementCount > mMaxImageUnits) + { + error(location, "image binding greater than gl_MaxImageUnits", "binding"); + } +} + +void TParseContext::checkSamplerBindingIsValid(const TSourceLoc &location, + int binding, + int arrayTotalElementCount) +{ + // Expects arraySize to be 1 when setting binding for only a single variable. + if (binding >= 0 && binding + arrayTotalElementCount > mMaxCombinedTextureImageUnits) + { + error(location, "sampler binding greater than maximum texture units", "binding"); + } +} + +void TParseContext::checkBlockBindingIsValid(const TSourceLoc &location, + const TQualifier &qualifier, + int binding, + int arraySize) +{ + int size = (arraySize == 0 ? 1 : arraySize); + if (qualifier == EvqUniform) + { + if (binding + size > mMaxUniformBufferBindings) + { + error(location, "uniform block binding greater than MAX_UNIFORM_BUFFER_BINDINGS", + "binding"); + } + } + else if (qualifier == EvqBuffer) + { + if (binding + size > mMaxShaderStorageBufferBindings) + { + error(location, + "shader storage block binding greater than MAX_SHADER_STORAGE_BUFFER_BINDINGS", + "binding"); + } + } +} +void TParseContext::checkAtomicCounterBindingIsValid(const TSourceLoc &location, int binding) +{ + if (binding >= mMaxAtomicCounterBindings) + { + error(location, "atomic counter binding greater than gl_MaxAtomicCounterBindings", + "binding"); + } +} + +void TParseContext::checkUniformLocationInRange(const TSourceLoc &location, + int objectLocationCount, + const TLayoutQualifier &layoutQualifier) +{ + int loc = layoutQualifier.location; + if (loc >= 0 && loc + objectLocationCount > mMaxUniformLocations) + { + error(location, "Uniform location out of range", "location"); + } +} + +void TParseContext::checkYuvIsNotSpecified(const TSourceLoc &location, bool yuv) +{ + if (yuv != false) + { + error(location, "invalid layout qualifier: only valid on program outputs", "yuv"); + } +} + +void TParseContext::functionCallRValueLValueErrorCheck(const TFunction *fnCandidate, + TIntermAggregate *fnCall) { for (size_t i = 0; i < fnCandidate->getParamCount(); ++i) { TQualifier qual = fnCandidate->getParam(i).type->getQualifier(); + TIntermTyped *argument = (*(fnCall->getSequence()))[i]->getAsTyped(); + if (!IsImage(argument->getBasicType()) && (IsQualifierUnspecified(qual) || qual == EvqIn || + qual == EvqInOut || qual == EvqConstReadOnly)) + { + if (argument->getMemoryQualifier().writeonly) + { + error(argument->getLine(), + "Writeonly value cannot be passed for 'in' or 'inout' parameters.", + fnCall->getFunctionSymbolInfo()->getName().c_str()); + return; + } + } if (qual == EvqOut || qual == EvqInOut) { - TIntermTyped *node = (*(aggregate->getSequence()))[i]->getAsTyped(); - if (lValueErrorCheck(node->getLine(), "assign", node)) + if (!checkCanBeLValue(argument->getLine(), "assign", argument)) { - error(node->getLine(), - "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error"); - recover(); - return true; + error(argument->getLine(), + "Constant value cannot be passed for 'out' or 'inout' parameters.", + fnCall->getFunctionSymbolInfo()->getName().c_str()); + return; } } } - return false; } -void TParseContext::es3InvariantErrorCheck(const TQualifier qualifier, - const TSourceLoc &invariantLocation) +void TParseContext::checkInvariantVariableQualifier(bool invariant, + const TQualifier qualifier, + const TSourceLoc &invariantLocation) { - if (!sh::IsVaryingOut(qualifier) && qualifier != EvqFragmentOut) + if (!invariant) + return; + + if (mShaderVersion < 300) { - error(invariantLocation, "Only out variables can be invariant.", "invariant"); - recover(); + // input variables in the fragment shader can be also qualified as invariant + if (!sh::CanBeInvariantESSL1(qualifier)) + { + error(invariantLocation, "Cannot be qualified as invariant.", "invariant"); + } + } + else + { + if (!sh::CanBeInvariantESSL3OrGreater(qualifier)) + { + error(invariantLocation, "Cannot be qualified as invariant.", "invariant"); + } } } -bool TParseContext::supportsExtension(const char *extension) +bool TParseContext::isExtensionEnabled(TExtension extension) const { - const TExtensionBehavior &extbehavior = extensionBehavior(); - TExtensionBehavior::const_iterator iter = extbehavior.find(extension); - return (iter != extbehavior.end()); -} - -bool TParseContext::isExtensionEnabled(const char *extension) const -{ - return ::IsExtensionEnabled(extensionBehavior(), extension); + return IsExtensionEnabled(extensionBehavior(), extension); } void TParseContext::handleExtensionDirective(const TSourceLoc &loc, @@ -1132,6 +1755,32 @@ void TParseContext::handlePragmaDirective(const TSourceLoc &loc, mDirectiveHandler.handlePragma(srcLoc, name, value, stdgl); } +sh::WorkGroupSize TParseContext::getComputeShaderLocalSize() const +{ + sh::WorkGroupSize result(-1); + for (size_t i = 0u; i < result.size(); ++i) + { + if (mComputeShaderLocalSizeDeclared && mComputeShaderLocalSize[i] == -1) + { + result[i] = 1; + } + else + { + result[i] = mComputeShaderLocalSize[i]; + } + } + return result; +} + +TIntermConstantUnion *TParseContext::addScalarLiteral(const TConstantUnion *constantUnion, + const TSourceLoc &line) +{ + TIntermConstantUnion *node = new TIntermConstantUnion( + constantUnion, TType(constantUnion->getType(), EbpUndefined, EvqConst)); + node->setLine(line); + return node; +} + ///////////////////////////////////////////////////////////////////////////////// // // Non-Errors. @@ -1142,70 +1791,64 @@ const TVariable *TParseContext::getNamedVariable(const TSourceLoc &location, const TString *name, const TSymbol *symbol) { - const TVariable *variable = NULL; - if (!symbol) { error(location, "undeclared identifier", name->c_str()); - recover(); + return nullptr; } - else if (!symbol->isVariable()) + + if (!symbol->isVariable()) { error(location, "variable expected", name->c_str()); - recover(); + return nullptr; } - else + + const TVariable *variable = static_cast(symbol); + + if (variable->getExtension() != TExtension::UNDEFINED) { - variable = static_cast(symbol); - - if (symbolTable.findBuiltIn(variable->getName(), mShaderVersion) && - !variable->getExtension().empty() && - extensionErrorCheck(location, variable->getExtension())) - { - recover(); - } - - // Reject shaders using both gl_FragData and gl_FragColor - TQualifier qualifier = variable->getType().getQualifier(); - if (qualifier == EvqFragData || qualifier == EvqSecondaryFragDataEXT) - { - mUsesFragData = true; - } - else if (qualifier == EvqFragColor || qualifier == EvqSecondaryFragColorEXT) - { - mUsesFragColor = true; - } - if (qualifier == EvqSecondaryFragDataEXT || qualifier == EvqSecondaryFragColorEXT) - { - mUsesSecondaryOutputs = true; - } - - // This validation is not quite correct - it's only an error to write to - // both FragData and FragColor. For simplicity, and because users shouldn't - // be rewarded for reading from undefined varaibles, return an error - // if they are both referenced, rather than assigned. - if (mUsesFragData && mUsesFragColor) - { - const char *errorMessage = "cannot use both gl_FragData and gl_FragColor"; - if (mUsesSecondaryOutputs) - { - errorMessage = - "cannot use both output variable sets (gl_FragData, gl_SecondaryFragDataEXT)" - " and (gl_FragColor, gl_SecondaryFragColorEXT)"; - } - error(location, errorMessage, name->c_str()); - recover(); - } + checkCanUseExtension(location, variable->getExtension()); } - if (!variable) + // Reject shaders using both gl_FragData and gl_FragColor + TQualifier qualifier = variable->getType().getQualifier(); + if (qualifier == EvqFragData || qualifier == EvqSecondaryFragDataEXT) { - TType type(EbtFloat, EbpUndefined); - TVariable *fakeVariable = new TVariable(name, type); - symbolTable.declare(fakeVariable); - variable = fakeVariable; + mUsesFragData = true; + } + else if (qualifier == EvqFragColor || qualifier == EvqSecondaryFragColorEXT) + { + mUsesFragColor = true; + } + if (qualifier == EvqSecondaryFragDataEXT || qualifier == EvqSecondaryFragColorEXT) + { + mUsesSecondaryOutputs = true; } + // This validation is not quite correct - it's only an error to write to + // both FragData and FragColor. For simplicity, and because users shouldn't + // be rewarded for reading from undefined varaibles, return an error + // if they are both referenced, rather than assigned. + if (mUsesFragData && mUsesFragColor) + { + const char *errorMessage = "cannot use both gl_FragData and gl_FragColor"; + if (mUsesSecondaryOutputs) + { + errorMessage = + "cannot use both output variable sets (gl_FragData, gl_SecondaryFragDataEXT)" + " and (gl_FragColor, gl_SecondaryFragColorEXT)"; + } + error(location, errorMessage, name->c_str()); + } + + // GLSL ES 3.1 Revision 4, 7.1.3 Compute Shader Special Variables + if (getShaderType() == GL_COMPUTE_SHADER && !mComputeShaderLocalSizeDeclared && + qualifier == EvqWorkGroupSize) + { + error(location, + "It is an error to use gl_WorkGroupSize before declaring the local group size", + "gl_WorkGroupSize"); + } return variable; } @@ -1215,75 +1858,82 @@ TIntermTyped *TParseContext::parseVariableIdentifier(const TSourceLoc &location, { const TVariable *variable = getNamedVariable(location, name, symbol); + if (!variable) + { + TIntermTyped *node = CreateZeroNode(TType(EbtFloat, EbpHigh, EvqConst)); + node->setLine(location); + return node; + } + + const TType &variableType = variable->getType(); + TIntermTyped *node = nullptr; + if (variable->getConstPointer()) { const TConstantUnion *constArray = variable->getConstPointer(); - return intermediate.addConstantUnion(constArray, variable->getType(), location); + node = new TIntermConstantUnion(constArray, variableType); + } + else if (variableType.getQualifier() == EvqWorkGroupSize && mComputeShaderLocalSizeDeclared) + { + // gl_WorkGroupSize can be used to size arrays according to the ESSL 3.10.4 spec, so it + // needs to be added to the AST as a constant and not as a symbol. + sh::WorkGroupSize workGroupSize = getComputeShaderLocalSize(); + TConstantUnion *constArray = new TConstantUnion[3]; + for (size_t i = 0; i < 3; ++i) + { + constArray[i].setUConst(static_cast(workGroupSize[i])); + } + + ASSERT(variableType.getBasicType() == EbtUInt); + ASSERT(variableType.getObjectSize() == 3); + + TType type(variableType); + type.setQualifier(EvqConst); + node = new TIntermConstantUnion(constArray, type); + } + else if ((mGeometryShaderInputPrimitiveType != EptUndefined) && + (variableType.getQualifier() == EvqPerVertexIn)) + { + ASSERT(mGeometryShaderInputArraySize > 0u); + + node = new TIntermSymbol(variable->getUniqueId(), variable->getName(), variableType); + node->getTypePointer()->sizeOutermostUnsizedArray(mGeometryShaderInputArraySize); } else { - return intermediate.addSymbol(variable->getUniqueId(), variable->getName(), - variable->getType(), location); + node = new TIntermSymbol(variable->getUniqueId(), variable->getName(), variableType); } + ASSERT(node != nullptr); + node->setLine(location); + return node; } -// -// Look up a function name in the symbol table, and make sure it is a function. -// -// Return the function symbol if found, otherwise 0. -// -const TFunction *TParseContext::findFunction(const TSourceLoc &line, - TFunction *call, - int inputShaderVersion, - bool *builtIn) -{ - // First find by unmangled name to check whether the function name has been - // hidden by a variable name or struct typename. - // If a function is found, check for one with a matching argument list. - const TSymbol *symbol = symbolTable.find(call->getName(), inputShaderVersion, builtIn); - if (symbol == 0 || symbol->isFunction()) - { - symbol = symbolTable.find(call->getMangledName(), inputShaderVersion, builtIn); - } - - if (symbol == 0) - { - error(line, "no matching overloaded function found", call->getName().c_str()); - return 0; - } - - if (!symbol->isFunction()) - { - error(line, "function name expected", call->getName().c_str()); - return 0; - } - - return static_cast(symbol); -} - -// // Initializers show up in several places in the grammar. Have one set of // code to handle them here. // -// Returns true on error, false if no error -// +// Returns true on success. bool TParseContext::executeInitializer(const TSourceLoc &line, const TString &identifier, - const TPublicType &pType, + TType type, TIntermTyped *initializer, - TIntermNode **intermNode) + TIntermBinary **initNode) { - ASSERT(intermNode != nullptr); - TType type = TType(pType); + ASSERT(initNode != nullptr); + ASSERT(*initNode == nullptr); TVariable *variable = nullptr; if (type.isUnsizedArray()) { - type.setArraySize(initializer->getArraySize()); + // In case initializer is not an array or type has more dimensions than initializer, this + // will default to setting array sizes to 1. We have not checked yet whether the initializer + // actually is an array or not. Having a non-array initializer for an unsized array will + // result in an error later, so we don't generate an error message here. + auto *arraySizes = initializer->getType().getArraySizes(); + type.sizeUnsizedArrays(arraySizes); } if (!declareVariable(line, identifier, type, &variable)) { - return true; + return false; } bool globalInitWarning = false; @@ -1293,7 +1943,7 @@ bool TParseContext::executeInitializer(const TSourceLoc &line, // Error message does not completely match behavior with ESSL 1.00, but // we want to steer developers towards only using constant expressions. error(line, "global variable initializers must be constant expressions", "="); - return true; + return false; } if (globalInitWarning) { @@ -1312,7 +1962,7 @@ bool TParseContext::executeInitializer(const TSourceLoc &line, { error(line, " cannot initialize this type of qualifier ", variable->getType().getQualifierString()); - return true; + return false; } // // test for and propagate constant @@ -1322,19 +1972,20 @@ bool TParseContext::executeInitializer(const TSourceLoc &line, { if (qualifier != initializer->getType().getQualifier()) { - std::stringstream extraInfoStream; - extraInfoStream << "'" << variable->getType().getCompleteString() << "'"; - std::string extraInfo = extraInfoStream.str(); - error(line, " assigning non-constant to", "=", extraInfo.c_str()); + std::stringstream reasonStream; + reasonStream << "assigning non-constant to '" << variable->getType().getCompleteString() + << "'"; + std::string reason = reasonStream.str(); + error(line, reason.c_str(), "="); variable->getType().setQualifier(EvqTemporary); - return true; + return false; } if (type != initializer->getType()) { error(line, " non-matching types for const initializer ", variable->getType().getQualifierString()); variable->getType().setQualifier(EvqTemporary); - return true; + return false; } // Save the constant folded value to the variable if possible. For example array @@ -1345,8 +1996,8 @@ bool TParseContext::executeInitializer(const TSourceLoc &line, if (initializer->getAsConstantUnion()) { variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer()); - *intermNode = nullptr; - return false; + ASSERT(*initNode == nullptr); + return true; } else if (initializer->getAsSymbolNode()) { @@ -1358,84 +2009,220 @@ bool TParseContext::executeInitializer(const TSourceLoc &line, if (constArray) { variable->shareConstPointer(constArray); - *intermNode = nullptr; - return false; + ASSERT(*initNode == nullptr); + return true; } } } - TIntermSymbol *intermSymbol = intermediate.addSymbol( - variable->getUniqueId(), variable->getName(), variable->getType(), line); - *intermNode = createAssign(EOpInitialize, intermSymbol, initializer, line); - if (*intermNode == nullptr) + TIntermSymbol *intermSymbol = + new TIntermSymbol(variable->getUniqueId(), variable->getName(), variable->getType()); + intermSymbol->setLine(line); + *initNode = createAssign(EOpInitialize, intermSymbol, initializer, line); + if (*initNode == nullptr) { assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString()); - return true; + return false; } - return false; + return true; } -TPublicType TParseContext::addFullySpecifiedType(TQualifier qualifier, - bool invariant, - TLayoutQualifier layoutQualifier, +TIntermNode *TParseContext::addConditionInitializer(const TPublicType &pType, + const TString &identifier, + TIntermTyped *initializer, + const TSourceLoc &loc) +{ + checkIsScalarBool(loc, pType); + TIntermBinary *initNode = nullptr; + TType type(pType); + if (executeInitializer(loc, identifier, type, initializer, &initNode)) + { + // The initializer is valid. The init condition needs to have a node - either the + // initializer node, or a constant node in case the initialized variable is const and won't + // be recorded in the AST. + if (initNode == nullptr) + { + return initializer; + } + else + { + TIntermDeclaration *declaration = new TIntermDeclaration(); + declaration->appendDeclarator(initNode); + return declaration; + } + } + return nullptr; +} + +TIntermNode *TParseContext::addLoop(TLoopType type, + TIntermNode *init, + TIntermNode *cond, + TIntermTyped *expr, + TIntermNode *body, + const TSourceLoc &line) +{ + TIntermNode *node = nullptr; + TIntermTyped *typedCond = nullptr; + if (cond) + { + typedCond = cond->getAsTyped(); + } + if (cond == nullptr || typedCond) + { + if (type == ELoopDoWhile) + { + checkIsScalarBool(line, typedCond); + } + // In the case of other loops, it was checked before that the condition is a scalar boolean. + ASSERT(mDiagnostics->numErrors() > 0 || typedCond == nullptr || + (typedCond->getBasicType() == EbtBool && !typedCond->isArray() && + !typedCond->isVector())); + + node = new TIntermLoop(type, init, typedCond, expr, EnsureBlock(body)); + node->setLine(line); + return node; + } + + ASSERT(type != ELoopDoWhile); + + TIntermDeclaration *declaration = cond->getAsDeclarationNode(); + ASSERT(declaration); + TIntermBinary *declarator = declaration->getSequence()->front()->getAsBinaryNode(); + ASSERT(declarator->getLeft()->getAsSymbolNode()); + + // The condition is a declaration. In the AST representation we don't support declarations as + // loop conditions. Wrap the loop to a block that declares the condition variable and contains + // the loop. + TIntermBlock *block = new TIntermBlock(); + + TIntermDeclaration *declareCondition = new TIntermDeclaration(); + declareCondition->appendDeclarator(declarator->getLeft()->deepCopy()); + block->appendStatement(declareCondition); + + TIntermBinary *conditionInit = new TIntermBinary(EOpAssign, declarator->getLeft()->deepCopy(), + declarator->getRight()->deepCopy()); + TIntermLoop *loop = new TIntermLoop(type, init, conditionInit, expr, EnsureBlock(body)); + block->appendStatement(loop); + loop->setLine(line); + block->setLine(line); + return block; +} + +TIntermNode *TParseContext::addIfElse(TIntermTyped *cond, + TIntermNodePair code, + const TSourceLoc &loc) +{ + bool isScalarBool = checkIsScalarBool(loc, cond); + + // For compile time constant conditions, prune the code now. + if (isScalarBool && cond->getAsConstantUnion()) + { + if (cond->getAsConstantUnion()->getBConst(0) == true) + { + return EnsureBlock(code.node1); + } + else + { + return EnsureBlock(code.node2); + } + } + + TIntermIfElse *node = new TIntermIfElse(cond, EnsureBlock(code.node1), EnsureBlock(code.node2)); + node->setLine(loc); + + return node; +} + +void TParseContext::addFullySpecifiedType(TPublicType *typeSpecifier) +{ + checkPrecisionSpecified(typeSpecifier->getLine(), typeSpecifier->precision, + typeSpecifier->getBasicType()); + + if (mShaderVersion < 300 && typeSpecifier->isArray()) + { + error(typeSpecifier->getLine(), "not supported", "first-class array"); + typeSpecifier->clearArrayness(); + } +} + +TPublicType TParseContext::addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder, const TPublicType &typeSpecifier) { + TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics); + TPublicType returnType = typeSpecifier; - returnType.qualifier = qualifier; - returnType.invariant = invariant; - returnType.layoutQualifier = layoutQualifier; + returnType.qualifier = typeQualifier.qualifier; + returnType.invariant = typeQualifier.invariant; + returnType.layoutQualifier = typeQualifier.layoutQualifier; + returnType.memoryQualifier = typeQualifier.memoryQualifier; + returnType.precision = typeSpecifier.precision; + + if (typeQualifier.precision != EbpUndefined) + { + returnType.precision = typeQualifier.precision; + } + + checkPrecisionSpecified(typeSpecifier.getLine(), returnType.precision, + typeSpecifier.getBasicType()); + + checkInvariantVariableQualifier(returnType.invariant, returnType.qualifier, + typeSpecifier.getLine()); + + checkWorkGroupSizeIsNotSpecified(typeSpecifier.getLine(), returnType.layoutQualifier); if (mShaderVersion < 300) { - if (typeSpecifier.array) + if (typeSpecifier.isArray()) { - error(typeSpecifier.line, "not supported", "first-class array"); - recover(); + error(typeSpecifier.getLine(), "not supported", "first-class array"); returnType.clearArrayness(); } - if (qualifier == EvqAttribute && - (typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt)) + if (returnType.qualifier == EvqAttribute && + (typeSpecifier.getBasicType() == EbtBool || typeSpecifier.getBasicType() == EbtInt)) { - error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier)); - recover(); + error(typeSpecifier.getLine(), "cannot be bool or int", + getQualifierString(returnType.qualifier)); } - if ((qualifier == EvqVaryingIn || qualifier == EvqVaryingOut) && - (typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt)) + if ((returnType.qualifier == EvqVaryingIn || returnType.qualifier == EvqVaryingOut) && + (typeSpecifier.getBasicType() == EbtBool || typeSpecifier.getBasicType() == EbtInt)) { - error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier)); - recover(); + error(typeSpecifier.getLine(), "cannot be bool or int", + getQualifierString(returnType.qualifier)); } } else { - if (!layoutQualifier.isEmpty()) + if (!returnType.layoutQualifier.isEmpty()) { - if (globalErrorCheck(typeSpecifier.line, symbolTable.atGlobalLevel(), "layout")) - { - recover(); - } + checkIsAtGlobalLevel(typeSpecifier.getLine(), "layout"); } - if (sh::IsVarying(qualifier) || qualifier == EvqVertexIn || qualifier == EvqFragmentOut) + if (sh::IsVarying(returnType.qualifier) || returnType.qualifier == EvqVertexIn || + returnType.qualifier == EvqFragmentOut) { - es3InputOutputTypeCheck(qualifier, typeSpecifier, typeSpecifier.line); + checkInputOutputTypeIsValidES3(returnType.qualifier, typeSpecifier, + typeSpecifier.getLine()); + } + if (returnType.qualifier == EvqComputeIn) + { + error(typeSpecifier.getLine(), "'in' can be only used to specify the local group size", + "in"); } } return returnType; } -void TParseContext::es3InputOutputTypeCheck(const TQualifier qualifier, - const TPublicType &type, - const TSourceLoc &qualifierLocation) +void TParseContext::checkInputOutputTypeIsValidES3(const TQualifier qualifier, + const TPublicType &type, + const TSourceLoc &qualifierLocation) { // An input/output variable can never be bool or a sampler. Samplers are checked elsewhere. - if (type.type == EbtBool) + if (type.getBasicType() == EbtBool) { error(qualifierLocation, "cannot be bool", getQualifierString(qualifier)); - recover(); } // Specific restrictions apply for vertex shader inputs and fragment shader outputs. @@ -1443,21 +2230,19 @@ void TParseContext::es3InputOutputTypeCheck(const TQualifier qualifier, { case EvqVertexIn: // ESSL 3.00 section 4.3.4 - if (type.array) + if (type.isArray()) { error(qualifierLocation, "cannot be array", getQualifierString(qualifier)); - recover(); } - // Vertex inputs with a struct type are disallowed in singleDeclarationErrorCheck + // Vertex inputs with a struct type are disallowed in nonEmptyDeclarationErrorCheck return; case EvqFragmentOut: // ESSL 3.00 section 4.3.6 - if (type.isMatrix()) + if (type.typeSpecifierNonArray.isMatrix()) { error(qualifierLocation, "cannot be matrix", getQualifierString(qualifier)); - recover(); } - // Fragment outputs with a struct type are disallowed in singleDeclarationErrorCheck + // Fragment outputs with a struct type are disallowed in nonEmptyDeclarationErrorCheck return; default: break; @@ -1466,506 +2251,997 @@ void TParseContext::es3InputOutputTypeCheck(const TQualifier qualifier, // Vertex shader outputs / fragment shader inputs have a different, slightly more lenient set of // restrictions. bool typeContainsIntegers = - (type.type == EbtInt || type.type == EbtUInt || type.isStructureContainingType(EbtInt) || - type.isStructureContainingType(EbtUInt)); + (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt || + type.isStructureContainingType(EbtInt) || type.isStructureContainingType(EbtUInt)); if (typeContainsIntegers && qualifier != EvqFlatIn && qualifier != EvqFlatOut) { error(qualifierLocation, "must use 'flat' interpolation here", getQualifierString(qualifier)); - recover(); } - if (type.type == EbtStruct) + if (type.getBasicType() == EbtStruct) { // ESSL 3.00 sections 4.3.4 and 4.3.6. // These restrictions are only implied by the ESSL 3.00 spec, but // the ESSL 3.10 spec lists these restrictions explicitly. - if (type.array) + if (type.isArray()) { error(qualifierLocation, "cannot be an array of structures", getQualifierString(qualifier)); - recover(); } if (type.isStructureContainingArrays()) { error(qualifierLocation, "cannot be a structure containing an array", getQualifierString(qualifier)); - recover(); } if (type.isStructureContainingType(EbtStruct)) { error(qualifierLocation, "cannot be a structure containing a structure", getQualifierString(qualifier)); - recover(); } if (type.isStructureContainingType(EbtBool)) { error(qualifierLocation, "cannot be a structure containing a bool", getQualifierString(qualifier)); - recover(); } } } -TIntermAggregate *TParseContext::parseSingleDeclaration(TPublicType &publicType, - const TSourceLoc &identifierOrTypeLocation, - const TString &identifier) +void TParseContext::checkLocalVariableConstStorageQualifier(const TQualifierWrapperBase &qualifier) { - TIntermSymbol *symbol = - intermediate.addSymbol(0, identifier, TType(publicType), identifierOrTypeLocation); + if (qualifier.getType() == QtStorage) + { + const TStorageQualifierWrapper &storageQualifier = + static_cast(qualifier); + if (!declaringFunction() && storageQualifier.getQualifier() != EvqConst && + !symbolTable.atGlobalLevel()) + { + error(storageQualifier.getLine(), + "Local variables can only use the const storage qualifier.", + storageQualifier.getQualifierString().c_str()); + } + } +} + +void TParseContext::checkMemoryQualifierIsNotSpecified(const TMemoryQualifier &memoryQualifier, + const TSourceLoc &location) +{ + const std::string reason( + "Only allowed with shader storage blocks, variables declared within shader storage blocks " + "and variables declared as image types."); + if (memoryQualifier.readonly) + { + error(location, reason.c_str(), "readonly"); + } + if (memoryQualifier.writeonly) + { + error(location, reason.c_str(), "writeonly"); + } + if (memoryQualifier.coherent) + { + error(location, reason.c_str(), "coherent"); + } + if (memoryQualifier.restrictQualifier) + { + error(location, reason.c_str(), "restrict"); + } + if (memoryQualifier.volatileQualifier) + { + error(location, reason.c_str(), "volatile"); + } +} + +// Make sure there is no offset overlapping, and store the newly assigned offset to "type" in +// intermediate tree. +void TParseContext::checkAtomicCounterOffsetDoesNotOverlap(bool forceAppend, + const TSourceLoc &loc, + TType *type) +{ + if (!IsAtomicCounter(type->getBasicType())) + { + return; + } + + const size_t size = type->isArray() ? kAtomicCounterArrayStride * type->getArraySizeProduct() + : kAtomicCounterSize; + TLayoutQualifier layoutQualifier = type->getLayoutQualifier(); + auto &bindingState = mAtomicCounterBindingStates[layoutQualifier.binding]; + int offset; + if (layoutQualifier.offset == -1 || forceAppend) + { + offset = bindingState.appendSpan(size); + } + else + { + offset = bindingState.insertSpan(layoutQualifier.offset, size); + } + if (offset == -1) + { + error(loc, "Offset overlapping", "atomic counter"); + return; + } + layoutQualifier.offset = offset; + type->setLayoutQualifier(layoutQualifier); +} + +void TParseContext::checkGeometryShaderInputAndSetArraySize(const TSourceLoc &location, + const char *token, + TType *type) +{ + if (IsGeometryShaderInput(mShaderType, type->getQualifier())) + { + if (type->isArray() && type->getOutermostArraySize() == 0u) + { + // Set size for the unsized geometry shader inputs if they are declared after a valid + // input primitive declaration. + if (mGeometryShaderInputPrimitiveType != EptUndefined) + { + ASSERT(mGeometryShaderInputArraySize > 0u); + type->sizeOutermostUnsizedArray(mGeometryShaderInputArraySize); + } + else + { + // [GLSL ES 3.2 SPEC Chapter 4.4.1.2] + // An input can be declared without an array size if there is a previous layout + // which specifies the size. + error(location, + "Missing a valid input primitive declaration before declaring an unsized " + "array input", + token); + } + } + else if (type->isArray()) + { + setGeometryShaderInputArraySize(type->getOutermostArraySize(), location); + } + else + { + error(location, "Geometry shader input variable must be declared as an array", token); + } + } +} + +TIntermDeclaration *TParseContext::parseSingleDeclaration( + TPublicType &publicType, + const TSourceLoc &identifierOrTypeLocation, + const TString &identifier) +{ + TType type(publicType); + if ((mCompileOptions & SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL) && + mDirectiveHandler.pragma().stdgl.invariantAll) + { + TQualifier qualifier = type.getQualifier(); + + // The directive handler has already taken care of rejecting invalid uses of this pragma + // (for example, in ESSL 3.00 fragment shaders), so at this point, flatten it into all + // affected variable declarations: + // + // 1. Built-in special variables which are inputs to the fragment shader. (These are handled + // elsewhere, in TranslatorGLSL.) + // + // 2. Outputs from vertex shaders in ESSL 1.00 and 3.00 (EvqVaryingOut and EvqVertexOut). It + // is actually less likely that there will be bugs in the handling of ESSL 3.00 shaders, but + // the way this is currently implemented we have to enable this compiler option before + // parsing the shader and determining the shading language version it uses. If this were + // implemented as a post-pass, the workaround could be more targeted. + // + // 3. Inputs in ESSL 1.00 fragment shaders (EvqVaryingIn). This is somewhat in violation of + // the specification, but there are desktop OpenGL drivers that expect that this is the + // behavior of the #pragma when specified in ESSL 1.00 fragment shaders. + if (qualifier == EvqVaryingOut || qualifier == EvqVertexOut || qualifier == EvqVaryingIn) + { + type.setInvariant(true); + } + } + + checkGeometryShaderInputAndSetArraySize(identifierOrTypeLocation, identifier.c_str(), &type); + + declarationQualifierErrorCheck(publicType.qualifier, publicType.layoutQualifier, + identifierOrTypeLocation); bool emptyDeclaration = (identifier == ""); + mDeferredNonEmptyDeclarationErrorCheck = emptyDeclaration; - mDeferredSingleDeclarationErrorCheck = emptyDeclaration; - + TIntermSymbol *symbol = nullptr; if (emptyDeclaration) { - if (publicType.isUnsizedArray()) + emptyDeclarationErrorCheck(type, identifierOrTypeLocation); + // In most cases we don't need to create a symbol node for an empty declaration. + // But if the empty declaration is declaring a struct type, the symbol node will store that. + if (type.getBasicType() == EbtStruct) { - // ESSL3 spec section 4.1.9: Array declaration which leaves the size unspecified is an - // error. It is assumed that this applies to empty declarations as well. - error(identifierOrTypeLocation, "empty array declaration needs to specify a size", - identifier.c_str()); + symbol = new TIntermSymbol(symbolTable.getEmptySymbolId(), "", type); + } + else if (IsAtomicCounter(publicType.getBasicType())) + { + setAtomicCounterBindingDefaultOffset(publicType, identifierOrTypeLocation); } } else { - if (singleDeclarationErrorCheck(publicType, identifierOrTypeLocation)) - recover(); + nonEmptyDeclarationErrorCheck(publicType, identifierOrTypeLocation); - if (nonInitErrorCheck(identifierOrTypeLocation, identifier, &publicType)) - recover(); + checkCanBeDeclaredWithoutInitializer(identifierOrTypeLocation, identifier, &type); + + checkAtomicCounterOffsetDoesNotOverlap(false, identifierOrTypeLocation, &type); TVariable *variable = nullptr; - if (!declareVariable(identifierOrTypeLocation, identifier, TType(publicType), &variable)) - recover(); + declareVariable(identifierOrTypeLocation, identifier, type, &variable); - if (variable && symbol) - symbol->setId(variable->getUniqueId()); + if (variable) + { + symbol = new TIntermSymbol(variable->getUniqueId(), identifier, type); + } } - return intermediate.makeAggregate(symbol, identifierOrTypeLocation); + TIntermDeclaration *declaration = new TIntermDeclaration(); + declaration->setLine(identifierOrTypeLocation); + if (symbol) + { + symbol->setLine(identifierOrTypeLocation); + declaration->appendDeclarator(symbol); + } + return declaration; } -TIntermAggregate *TParseContext::parseSingleArrayDeclaration(TPublicType &publicType, - const TSourceLoc &identifierLocation, - const TString &identifier, - const TSourceLoc &indexLocation, - TIntermTyped *indexExpression) -{ - mDeferredSingleDeclarationErrorCheck = false; - - if (singleDeclarationErrorCheck(publicType, identifierLocation)) - recover(); - - if (nonInitErrorCheck(identifierLocation, identifier, &publicType)) - recover(); - - if (arrayTypeErrorCheck(indexLocation, publicType) || - arrayQualifierErrorCheck(indexLocation, publicType)) - { - recover(); - } - - TType arrayType(publicType); - - int size; - if (arraySizeErrorCheck(identifierLocation, indexExpression, size)) - { - recover(); - } - // Make the type an array even if size check failed. - // This ensures useless error messages regarding the variable's non-arrayness won't follow. - arrayType.setArraySize(size); - - TVariable *variable = nullptr; - if (!declareVariable(identifierLocation, identifier, arrayType, &variable)) - recover(); - - TIntermSymbol *symbol = intermediate.addSymbol(0, identifier, arrayType, identifierLocation); - if (variable && symbol) - symbol->setId(variable->getUniqueId()); - - return intermediate.makeAggregate(symbol, identifierLocation); -} - -TIntermAggregate *TParseContext::parseSingleInitDeclaration(const TPublicType &publicType, - const TSourceLoc &identifierLocation, - const TString &identifier, - const TSourceLoc &initLocation, - TIntermTyped *initializer) -{ - mDeferredSingleDeclarationErrorCheck = false; - - if (singleDeclarationErrorCheck(publicType, identifierLocation)) - recover(); - - TIntermNode *intermNode = nullptr; - if (!executeInitializer(identifierLocation, identifier, publicType, initializer, &intermNode)) - { - // - // Build intermediate representation - // - return intermNode ? intermediate.makeAggregate(intermNode, initLocation) : nullptr; - } - else - { - recover(); - return nullptr; - } -} - -TIntermAggregate *TParseContext::parseSingleArrayInitDeclaration( - TPublicType &publicType, +TIntermDeclaration *TParseContext::parseSingleArrayDeclaration( + TPublicType &elementType, const TSourceLoc &identifierLocation, const TString &identifier, const TSourceLoc &indexLocation, - TIntermTyped *indexExpression, + const TVector &arraySizes) +{ + mDeferredNonEmptyDeclarationErrorCheck = false; + + declarationQualifierErrorCheck(elementType.qualifier, elementType.layoutQualifier, + identifierLocation); + + nonEmptyDeclarationErrorCheck(elementType, identifierLocation); + + checkIsValidTypeAndQualifierForArray(indexLocation, elementType); + + TType arrayType(elementType); + arrayType.makeArrays(arraySizes); + + checkGeometryShaderInputAndSetArraySize(indexLocation, identifier.c_str(), &arrayType); + + checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &arrayType); + + checkAtomicCounterOffsetDoesNotOverlap(false, identifierLocation, &arrayType); + + TVariable *variable = nullptr; + declareVariable(identifierLocation, identifier, arrayType, &variable); + + TIntermDeclaration *declaration = new TIntermDeclaration(); + declaration->setLine(identifierLocation); + + if (variable) + { + TIntermSymbol *symbol = new TIntermSymbol(variable->getUniqueId(), identifier, arrayType); + symbol->setLine(identifierLocation); + declaration->appendDeclarator(symbol); + } + + return declaration; +} + +TIntermDeclaration *TParseContext::parseSingleInitDeclaration(const TPublicType &publicType, + const TSourceLoc &identifierLocation, + const TString &identifier, + const TSourceLoc &initLocation, + TIntermTyped *initializer) +{ + mDeferredNonEmptyDeclarationErrorCheck = false; + + declarationQualifierErrorCheck(publicType.qualifier, publicType.layoutQualifier, + identifierLocation); + + nonEmptyDeclarationErrorCheck(publicType, identifierLocation); + + TIntermDeclaration *declaration = new TIntermDeclaration(); + declaration->setLine(identifierLocation); + + TIntermBinary *initNode = nullptr; + TType type(publicType); + if (executeInitializer(identifierLocation, identifier, type, initializer, &initNode)) + { + if (initNode) + { + declaration->appendDeclarator(initNode); + } + } + return declaration; +} + +TIntermDeclaration *TParseContext::parseSingleArrayInitDeclaration( + TPublicType &elementType, + const TSourceLoc &identifierLocation, + const TString &identifier, + const TSourceLoc &indexLocation, + const TVector &arraySizes, const TSourceLoc &initLocation, TIntermTyped *initializer) { - mDeferredSingleDeclarationErrorCheck = false; + mDeferredNonEmptyDeclarationErrorCheck = false; - if (singleDeclarationErrorCheck(publicType, identifierLocation)) - recover(); + declarationQualifierErrorCheck(elementType.qualifier, elementType.layoutQualifier, + identifierLocation); - if (arrayTypeErrorCheck(indexLocation, publicType) || - arrayQualifierErrorCheck(indexLocation, publicType)) - { - recover(); - } + nonEmptyDeclarationErrorCheck(elementType, identifierLocation); - TPublicType arrayType(publicType); + checkIsValidTypeAndQualifierForArray(indexLocation, elementType); - int size = 0; - // If indexExpression is nullptr, then the array will eventually get its size implicitly from - // the initializer. - if (indexExpression != nullptr && - arraySizeErrorCheck(identifierLocation, indexExpression, size)) - { - recover(); - } - // Make the type an array even if size check failed. - // This ensures useless error messages regarding the variable's non-arrayness won't follow. - arrayType.setArraySize(size); + TType arrayType(elementType); + arrayType.makeArrays(arraySizes); + + TIntermDeclaration *declaration = new TIntermDeclaration(); + declaration->setLine(identifierLocation); // initNode will correspond to the whole of "type b[n] = initializer". - TIntermNode *initNode = nullptr; - if (!executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode)) + TIntermBinary *initNode = nullptr; + if (executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode)) { - return initNode ? intermediate.makeAggregate(initNode, initLocation) : nullptr; - } - else - { - recover(); - return nullptr; + if (initNode) + { + declaration->appendDeclarator(initNode); + } } + + return declaration; } -TIntermAggregate *TParseContext::parseInvariantDeclaration(const TSourceLoc &invariantLoc, - const TSourceLoc &identifierLoc, - const TString *identifier, - const TSymbol *symbol) +TIntermInvariantDeclaration *TParseContext::parseInvariantDeclaration( + const TTypeQualifierBuilder &typeQualifierBuilder, + const TSourceLoc &identifierLoc, + const TString *identifier, + const TSymbol *symbol) { - // invariant declaration - if (globalErrorCheck(invariantLoc, symbolTable.atGlobalLevel(), "invariant varying")) - { - recover(); - } + TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics); + if (!typeQualifier.invariant) + { + error(identifierLoc, "Expected invariant", identifier->c_str()); + return nullptr; + } + if (!checkIsAtGlobalLevel(identifierLoc, "invariant varying")) + { + return nullptr; + } if (!symbol) { error(identifierLoc, "undeclared identifier declared as invariant", identifier->c_str()); - recover(); return nullptr; } - else + if (!IsQualifierUnspecified(typeQualifier.qualifier)) { - const TString kGlFrontFacing("gl_FrontFacing"); - if (*identifier == kGlFrontFacing) - { - error(identifierLoc, "identifier should not be declared as invariant", - identifier->c_str()); - recover(); - return nullptr; - } - symbolTable.addInvariantVarying(std::string(identifier->c_str())); - const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol); - ASSERT(variable); - const TType &type = variable->getType(); - TIntermSymbol *intermSymbol = - intermediate.addSymbol(variable->getUniqueId(), *identifier, type, identifierLoc); - - TIntermAggregate *aggregate = intermediate.makeAggregate(intermSymbol, identifierLoc); - aggregate->setOp(EOpInvariantDeclaration); - return aggregate; + error(identifierLoc, "invariant declaration specifies qualifier", + getQualifierString(typeQualifier.qualifier)); } + if (typeQualifier.precision != EbpUndefined) + { + error(identifierLoc, "invariant declaration specifies precision", + getPrecisionString(typeQualifier.precision)); + } + if (!typeQualifier.layoutQualifier.isEmpty()) + { + error(identifierLoc, "invariant declaration specifies layout", "'layout'"); + } + + const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol); + if (!variable) + { + return nullptr; + } + const TType &type = variable->getType(); + + checkInvariantVariableQualifier(typeQualifier.invariant, type.getQualifier(), + typeQualifier.line); + checkMemoryQualifierIsNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line); + + symbolTable.addInvariantVarying(std::string(identifier->c_str())); + + TIntermSymbol *intermSymbol = new TIntermSymbol(variable->getUniqueId(), *identifier, type); + intermSymbol->setLine(identifierLoc); + + return new TIntermInvariantDeclaration(intermSymbol, identifierLoc); } -TIntermAggregate *TParseContext::parseDeclarator(TPublicType &publicType, - TIntermAggregate *aggregateDeclaration, - const TSourceLoc &identifierLocation, - const TString &identifier) +void TParseContext::parseDeclarator(TPublicType &publicType, + const TSourceLoc &identifierLocation, + const TString &identifier, + TIntermDeclaration *declarationOut) { // If the declaration starting this declarator list was empty (example: int,), some checks were // not performed. - if (mDeferredSingleDeclarationErrorCheck) + if (mDeferredNonEmptyDeclarationErrorCheck) { - if (singleDeclarationErrorCheck(publicType, identifierLocation)) - recover(); - mDeferredSingleDeclarationErrorCheck = false; + nonEmptyDeclarationErrorCheck(publicType, identifierLocation); + mDeferredNonEmptyDeclarationErrorCheck = false; } - if (locationDeclaratorListCheck(identifierLocation, publicType)) - recover(); - - if (nonInitErrorCheck(identifierLocation, identifier, &publicType)) - recover(); + checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType); TVariable *variable = nullptr; - if (!declareVariable(identifierLocation, identifier, TType(publicType), &variable)) - recover(); + TType type(publicType); - TIntermSymbol *symbol = - intermediate.addSymbol(0, identifier, TType(publicType), identifierLocation); - if (variable && symbol) - symbol->setId(variable->getUniqueId()); + checkGeometryShaderInputAndSetArraySize(identifierLocation, identifier.c_str(), &type); - return intermediate.growAggregate(aggregateDeclaration, symbol, identifierLocation); + checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &type); + + checkAtomicCounterOffsetDoesNotOverlap(true, identifierLocation, &type); + + declareVariable(identifierLocation, identifier, type, &variable); + + if (variable) + { + TIntermSymbol *symbol = new TIntermSymbol(variable->getUniqueId(), identifier, type); + symbol->setLine(identifierLocation); + declarationOut->appendDeclarator(symbol); + } } -TIntermAggregate *TParseContext::parseArrayDeclarator(TPublicType &publicType, - TIntermAggregate *aggregateDeclaration, - const TSourceLoc &identifierLocation, - const TString &identifier, - const TSourceLoc &arrayLocation, - TIntermTyped *indexExpression) +void TParseContext::parseArrayDeclarator(TPublicType &elementType, + const TSourceLoc &identifierLocation, + const TString &identifier, + const TSourceLoc &arrayLocation, + const TVector &arraySizes, + TIntermDeclaration *declarationOut) { // If the declaration starting this declarator list was empty (example: int,), some checks were // not performed. - if (mDeferredSingleDeclarationErrorCheck) + if (mDeferredNonEmptyDeclarationErrorCheck) { - if (singleDeclarationErrorCheck(publicType, identifierLocation)) - recover(); - mDeferredSingleDeclarationErrorCheck = false; + nonEmptyDeclarationErrorCheck(elementType, identifierLocation); + mDeferredNonEmptyDeclarationErrorCheck = false; } - if (locationDeclaratorListCheck(identifierLocation, publicType)) - recover(); + checkDeclaratorLocationIsNotSpecified(identifierLocation, elementType); - if (nonInitErrorCheck(identifierLocation, identifier, &publicType)) - recover(); + if (checkIsValidTypeAndQualifierForArray(arrayLocation, elementType)) + { + TType arrayType(elementType); + arrayType.makeArrays(arraySizes); - if (arrayTypeErrorCheck(arrayLocation, publicType) || - arrayQualifierErrorCheck(arrayLocation, publicType)) - { - recover(); - } - else - { - TType arrayType = TType(publicType); - int size; - if (arraySizeErrorCheck(arrayLocation, indexExpression, size)) - { - recover(); - } - arrayType.setArraySize(size); + checkGeometryShaderInputAndSetArraySize(identifierLocation, identifier.c_str(), &arrayType); + + checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &arrayType); + + checkAtomicCounterOffsetDoesNotOverlap(true, identifierLocation, &arrayType); TVariable *variable = nullptr; - if (!declareVariable(identifierLocation, identifier, arrayType, &variable)) - recover(); + declareVariable(identifierLocation, identifier, arrayType, &variable); - TIntermSymbol *symbol = - intermediate.addSymbol(0, identifier, arrayType, identifierLocation); - if (variable && symbol) - symbol->setId(variable->getUniqueId()); - - return intermediate.growAggregate(aggregateDeclaration, symbol, identifierLocation); + if (variable) + { + TIntermSymbol *symbol = + new TIntermSymbol(variable->getUniqueId(), identifier, arrayType); + symbol->setLine(identifierLocation); + declarationOut->appendDeclarator(symbol); + } } - - return nullptr; } -TIntermAggregate *TParseContext::parseInitDeclarator(const TPublicType &publicType, - TIntermAggregate *aggregateDeclaration, - const TSourceLoc &identifierLocation, - const TString &identifier, - const TSourceLoc &initLocation, - TIntermTyped *initializer) +void TParseContext::parseInitDeclarator(const TPublicType &publicType, + const TSourceLoc &identifierLocation, + const TString &identifier, + const TSourceLoc &initLocation, + TIntermTyped *initializer, + TIntermDeclaration *declarationOut) { // If the declaration starting this declarator list was empty (example: int,), some checks were // not performed. - if (mDeferredSingleDeclarationErrorCheck) + if (mDeferredNonEmptyDeclarationErrorCheck) { - if (singleDeclarationErrorCheck(publicType, identifierLocation)) - recover(); - mDeferredSingleDeclarationErrorCheck = false; + nonEmptyDeclarationErrorCheck(publicType, identifierLocation); + mDeferredNonEmptyDeclarationErrorCheck = false; } - if (locationDeclaratorListCheck(identifierLocation, publicType)) - recover(); + checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType); - TIntermNode *intermNode = nullptr; - if (!executeInitializer(identifierLocation, identifier, publicType, initializer, &intermNode)) + TIntermBinary *initNode = nullptr; + TType type(publicType); + if (executeInitializer(identifierLocation, identifier, type, initializer, &initNode)) { // // build the intermediate representation // - if (intermNode) + if (initNode) { - return intermediate.growAggregate(aggregateDeclaration, intermNode, initLocation); + declarationOut->appendDeclarator(initNode); } - else - { - return aggregateDeclaration; - } - } - else - { - recover(); - return nullptr; } } -TIntermAggregate *TParseContext::parseArrayInitDeclarator(const TPublicType &publicType, - TIntermAggregate *aggregateDeclaration, - const TSourceLoc &identifierLocation, - const TString &identifier, - const TSourceLoc &indexLocation, - TIntermTyped *indexExpression, - const TSourceLoc &initLocation, - TIntermTyped *initializer) +void TParseContext::parseArrayInitDeclarator(const TPublicType &elementType, + const TSourceLoc &identifierLocation, + const TString &identifier, + const TSourceLoc &indexLocation, + const TVector &arraySizes, + const TSourceLoc &initLocation, + TIntermTyped *initializer, + TIntermDeclaration *declarationOut) { // If the declaration starting this declarator list was empty (example: int,), some checks were // not performed. - if (mDeferredSingleDeclarationErrorCheck) + if (mDeferredNonEmptyDeclarationErrorCheck) { - if (singleDeclarationErrorCheck(publicType, identifierLocation)) - recover(); - mDeferredSingleDeclarationErrorCheck = false; + nonEmptyDeclarationErrorCheck(elementType, identifierLocation); + mDeferredNonEmptyDeclarationErrorCheck = false; } - if (locationDeclaratorListCheck(identifierLocation, publicType)) - recover(); + checkDeclaratorLocationIsNotSpecified(identifierLocation, elementType); - if (arrayTypeErrorCheck(indexLocation, publicType) || - arrayQualifierErrorCheck(indexLocation, publicType)) - { - recover(); - } + checkIsValidTypeAndQualifierForArray(indexLocation, elementType); - TPublicType arrayType(publicType); - - int size = 0; - // If indexExpression is nullptr, then the array will eventually get its size implicitly from - // the initializer. - if (indexExpression != nullptr && - arraySizeErrorCheck(identifierLocation, indexExpression, size)) - { - recover(); - } - // Make the type an array even if size check failed. - // This ensures useless error messages regarding the variable's non-arrayness won't follow. - arrayType.setArraySize(size); + TType arrayType(elementType); + arrayType.makeArrays(arraySizes); // initNode will correspond to the whole of "b[n] = initializer". - TIntermNode *initNode = nullptr; - if (!executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode)) + TIntermBinary *initNode = nullptr; + if (executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode)) { if (initNode) { - return intermediate.growAggregate(aggregateDeclaration, initNode, initLocation); + declarationOut->appendDeclarator(initNode); } - else + } +} + +TIntermNode *TParseContext::addEmptyStatement(const TSourceLoc &location) +{ + // It's simpler to parse an empty statement as a constant expression rather than having a + // different type of node just for empty statements, that will be pruned from the AST anyway. + TIntermNode *node = CreateZeroNode(TType(EbtInt, EbpMedium)); + node->setLine(location); + return node; +} + +void TParseContext::setAtomicCounterBindingDefaultOffset(const TPublicType &publicType, + const TSourceLoc &location) +{ + const TLayoutQualifier &layoutQualifier = publicType.layoutQualifier; + checkAtomicCounterBindingIsValid(location, layoutQualifier.binding); + if (layoutQualifier.binding == -1 || layoutQualifier.offset == -1) + { + error(location, "Requires both binding and offset", "layout"); + return; + } + mAtomicCounterBindingStates[layoutQualifier.binding].setDefaultOffset(layoutQualifier.offset); +} + +void TParseContext::parseDefaultPrecisionQualifier(const TPrecision precision, + const TPublicType &type, + const TSourceLoc &loc) +{ + if ((precision == EbpHigh) && (getShaderType() == GL_FRAGMENT_SHADER) && + !getFragmentPrecisionHigh()) + { + error(loc, "precision is not supported in fragment shader", "highp"); + } + + if (!CanSetDefaultPrecisionOnType(type)) + { + error(loc, "illegal type argument for default precision qualifier", + getBasicString(type.getBasicType())); + return; + } + symbolTable.setDefaultPrecision(type.getBasicType(), precision); +} + +bool TParseContext::checkPrimitiveTypeMatchesTypeQualifier(const TTypeQualifier &typeQualifier) +{ + switch (typeQualifier.layoutQualifier.primitiveType) + { + case EptLines: + case EptLinesAdjacency: + case EptTriangles: + case EptTrianglesAdjacency: + return typeQualifier.qualifier == EvqGeometryIn; + + case EptLineStrip: + case EptTriangleStrip: + return typeQualifier.qualifier == EvqGeometryOut; + + case EptPoints: + return true; + + default: + UNREACHABLE(); + return false; + } +} + +void TParseContext::setGeometryShaderInputArraySize(unsigned int inputArraySize, + const TSourceLoc &line) +{ + if (mGeometryShaderInputArraySize == 0u) + { + mGeometryShaderInputArraySize = inputArraySize; + } + else if (mGeometryShaderInputArraySize != inputArraySize) + { + error(line, + "Array size or input primitive declaration doesn't match the size of earlier sized " + "array inputs.", + "layout"); + } +} + +bool TParseContext::parseGeometryShaderInputLayoutQualifier(const TTypeQualifier &typeQualifier) +{ + ASSERT(typeQualifier.qualifier == EvqGeometryIn); + + const TLayoutQualifier &layoutQualifier = typeQualifier.layoutQualifier; + + if (layoutQualifier.maxVertices != -1) + { + error(typeQualifier.line, + "max_vertices can only be declared in 'out' layout in a geometry shader", "layout"); + return false; + } + + // Set mGeometryInputPrimitiveType if exists + if (layoutQualifier.primitiveType != EptUndefined) + { + if (!checkPrimitiveTypeMatchesTypeQualifier(typeQualifier)) { - return aggregateDeclaration; + error(typeQualifier.line, "invalid primitive type for 'in' layout", "layout"); + return false; } + + if (mGeometryShaderInputPrimitiveType == EptUndefined) + { + mGeometryShaderInputPrimitiveType = layoutQualifier.primitiveType; + setGeometryShaderInputArraySize( + GetGeometryShaderInputArraySize(mGeometryShaderInputPrimitiveType), + typeQualifier.line); + } + else if (mGeometryShaderInputPrimitiveType != layoutQualifier.primitiveType) + { + error(typeQualifier.line, "primitive doesn't match earlier input primitive declaration", + "layout"); + return false; + } + } + + // Set mGeometryInvocations if exists + if (layoutQualifier.invocations > 0) + { + if (mGeometryShaderInvocations == 0) + { + mGeometryShaderInvocations = layoutQualifier.invocations; + } + else if (mGeometryShaderInvocations != layoutQualifier.invocations) + { + error(typeQualifier.line, "invocations contradicts to the earlier declaration", + "layout"); + return false; + } + } + + return true; +} + +bool TParseContext::parseGeometryShaderOutputLayoutQualifier(const TTypeQualifier &typeQualifier) +{ + ASSERT(typeQualifier.qualifier == EvqGeometryOut); + + const TLayoutQualifier &layoutQualifier = typeQualifier.layoutQualifier; + + if (layoutQualifier.invocations > 0) + { + error(typeQualifier.line, + "invocations can only be declared in 'in' layout in a geometry shader", "layout"); + return false; + } + + // Set mGeometryOutputPrimitiveType if exists + if (layoutQualifier.primitiveType != EptUndefined) + { + if (!checkPrimitiveTypeMatchesTypeQualifier(typeQualifier)) + { + error(typeQualifier.line, "invalid primitive type for 'out' layout", "layout"); + return false; + } + + if (mGeometryShaderOutputPrimitiveType == EptUndefined) + { + mGeometryShaderOutputPrimitiveType = layoutQualifier.primitiveType; + } + else if (mGeometryShaderOutputPrimitiveType != layoutQualifier.primitiveType) + { + error(typeQualifier.line, + "primitive doesn't match earlier output primitive declaration", "layout"); + return false; + } + } + + // Set mGeometryMaxVertices if exists + if (layoutQualifier.maxVertices > -1) + { + if (mGeometryShaderMaxVertices == -1) + { + mGeometryShaderMaxVertices = layoutQualifier.maxVertices; + } + else if (mGeometryShaderMaxVertices != layoutQualifier.maxVertices) + { + error(typeQualifier.line, "max_vertices contradicts to the earlier declaration", + "layout"); + return false; + } + } + + return true; +} + +void TParseContext::parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder) +{ + TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics); + const TLayoutQualifier layoutQualifier = typeQualifier.layoutQualifier; + + checkInvariantVariableQualifier(typeQualifier.invariant, typeQualifier.qualifier, + typeQualifier.line); + + // It should never be the case, but some strange parser errors can send us here. + if (layoutQualifier.isEmpty()) + { + error(typeQualifier.line, "Error during layout qualifier parsing.", "?"); + return; + } + + if (!layoutQualifier.isCombinationValid()) + { + error(typeQualifier.line, "invalid layout qualifier combination", "layout"); + return; + } + + checkBindingIsNotSpecified(typeQualifier.line, layoutQualifier.binding); + + checkMemoryQualifierIsNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line); + + checkInternalFormatIsNotSpecified(typeQualifier.line, layoutQualifier.imageInternalFormat); + + checkYuvIsNotSpecified(typeQualifier.line, layoutQualifier.yuv); + + checkOffsetIsNotSpecified(typeQualifier.line, layoutQualifier.offset); + + checkStd430IsForShaderStorageBlock(typeQualifier.line, layoutQualifier.blockStorage, + typeQualifier.qualifier); + + if (typeQualifier.qualifier == EvqComputeIn) + { + if (mComputeShaderLocalSizeDeclared && + !layoutQualifier.isLocalSizeEqual(mComputeShaderLocalSize)) + { + error(typeQualifier.line, "Work group size does not match the previous declaration", + "layout"); + return; + } + + if (mShaderVersion < 310) + { + error(typeQualifier.line, "in type qualifier supported in GLSL ES 3.10 only", "layout"); + return; + } + + if (!layoutQualifier.localSize.isAnyValueSet()) + { + error(typeQualifier.line, "No local work group size specified", "layout"); + return; + } + + const TVariable *maxComputeWorkGroupSize = static_cast( + symbolTable.findBuiltIn("gl_MaxComputeWorkGroupSize", mShaderVersion)); + + const TConstantUnion *maxComputeWorkGroupSizeData = + maxComputeWorkGroupSize->getConstPointer(); + + for (size_t i = 0u; i < layoutQualifier.localSize.size(); ++i) + { + if (layoutQualifier.localSize[i] != -1) + { + mComputeShaderLocalSize[i] = layoutQualifier.localSize[i]; + const int maxComputeWorkGroupSizeValue = maxComputeWorkGroupSizeData[i].getIConst(); + if (mComputeShaderLocalSize[i] < 1 || + mComputeShaderLocalSize[i] > maxComputeWorkGroupSizeValue) + { + std::stringstream reasonStream; + reasonStream << "invalid value: Value must be at least 1 and no greater than " + << maxComputeWorkGroupSizeValue; + const std::string &reason = reasonStream.str(); + + error(typeQualifier.line, reason.c_str(), getWorkGroupSizeString(i)); + return; + } + } + } + + mComputeShaderLocalSizeDeclared = true; + } + else if (typeQualifier.qualifier == EvqGeometryIn) + { + if (mShaderVersion < 310) + { + error(typeQualifier.line, "in type qualifier supported in GLSL ES 3.10 only", "layout"); + return; + } + + if (!parseGeometryShaderInputLayoutQualifier(typeQualifier)) + { + return; + } + } + else if (typeQualifier.qualifier == EvqGeometryOut) + { + if (mShaderVersion < 310) + { + error(typeQualifier.line, "out type qualifier supported in GLSL ES 3.10 only", + "layout"); + return; + } + + if (!parseGeometryShaderOutputLayoutQualifier(typeQualifier)) + { + return; + } + } + else if (isExtensionEnabled(TExtension::OVR_multiview) && + typeQualifier.qualifier == EvqVertexIn) + { + // This error is only specified in WebGL, but tightens unspecified behavior in the native + // specification. + if (mNumViews != -1 && layoutQualifier.numViews != mNumViews) + { + error(typeQualifier.line, "Number of views does not match the previous declaration", + "layout"); + return; + } + + if (layoutQualifier.numViews == -1) + { + error(typeQualifier.line, "No num_views specified", "layout"); + return; + } + + if (layoutQualifier.numViews > mMaxNumViews) + { + error(typeQualifier.line, "num_views greater than the value of GL_MAX_VIEWS_OVR", + "layout"); + return; + } + + mNumViews = layoutQualifier.numViews; } else { - recover(); - return nullptr; + if (!checkWorkGroupSizeIsNotSpecified(typeQualifier.line, layoutQualifier)) + { + return; + } + + if (typeQualifier.qualifier != EvqUniform && typeQualifier.qualifier != EvqBuffer) + { + error(typeQualifier.line, "invalid qualifier: global layout can only be set for blocks", + getQualifierString(typeQualifier.qualifier)); + return; + } + + if (mShaderVersion < 300) + { + error(typeQualifier.line, "layout qualifiers supported in GLSL ES 3.00 and above", + "layout"); + return; + } + + checkLocationIsNotSpecified(typeQualifier.line, layoutQualifier); + + if (layoutQualifier.matrixPacking != EmpUnspecified) + { + if (typeQualifier.qualifier == EvqUniform) + { + mDefaultUniformMatrixPacking = layoutQualifier.matrixPacking; + } + else if (typeQualifier.qualifier == EvqBuffer) + { + mDefaultBufferMatrixPacking = layoutQualifier.matrixPacking; + } + } + + if (layoutQualifier.blockStorage != EbsUnspecified) + { + if (typeQualifier.qualifier == EvqUniform) + { + mDefaultUniformBlockStorage = layoutQualifier.blockStorage; + } + else if (typeQualifier.qualifier == EvqBuffer) + { + mDefaultBufferBlockStorage = layoutQualifier.blockStorage; + } + } } } -void TParseContext::parseGlobalLayoutQualifier(const TPublicType &typeQualifier) +TIntermFunctionPrototype *TParseContext::createPrototypeNodeFromFunction( + const TFunction &function, + const TSourceLoc &location, + bool insertParametersToSymbolTable) { - if (typeQualifier.qualifier != EvqUniform) - { - error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier), - "global layout must be uniform"); - recover(); - return; - } + checkIsNotReserved(location, function.getName()); - const TLayoutQualifier layoutQualifier = typeQualifier.layoutQualifier; - ASSERT(!layoutQualifier.isEmpty()); - - if (mShaderVersion < 300) - { - error(typeQualifier.line, "layout qualifiers supported in GLSL ES 3.00 only", "layout"); - recover(); - return; - } - - if (layoutLocationErrorCheck(typeQualifier.line, typeQualifier.layoutQualifier)) - { - recover(); - return; - } - - if (layoutQualifier.matrixPacking != EmpUnspecified) - { - mDefaultMatrixPacking = layoutQualifier.matrixPacking; - } - - if (layoutQualifier.blockStorage != EbsUnspecified) - { - mDefaultBlockStorage = layoutQualifier.blockStorage; - } -} - -TIntermAggregate *TParseContext::addFunctionPrototypeDeclaration(const TFunction &function, - const TSourceLoc &location) -{ - // Note: symbolTableFunction could be the same as function if this is the first declaration. - // Either way the instance in the symbol table is used to track whether the function is declared - // multiple times. - TFunction *symbolTableFunction = - static_cast(symbolTable.find(function.getMangledName(), getShaderVersion())); - if (symbolTableFunction->hasPrototypeDeclaration() && mShaderVersion == 100) - { - // ESSL 1.00.17 section 4.2.7. - // Doesn't apply to ESSL 3.00.4: see section 4.2.3. - error(location, "duplicate function prototype declarations are not allowed", "function"); - recover(); - } - symbolTableFunction->setHasPrototypeDeclaration(); - - TIntermAggregate *prototype = new TIntermAggregate; - prototype->setType(function.getReturnType()); - prototype->setName(function.getMangledName()); - prototype->setFunctionId(function.getUniqueId()); + TIntermFunctionPrototype *prototype = + new TIntermFunctionPrototype(function.getReturnType(), TSymbolUniqueId(function)); + // TODO(oetuaho@nvidia.com): Instead of converting the function information here, the node could + // point to the data that already exists in the symbol table. + prototype->getFunctionSymbolInfo()->setFromFunction(function); + prototype->setLine(location); for (size_t i = 0; i < function.getParamCount(); i++) { const TConstParameter ¶m = function.getParam(i); - if (param.name != 0) - { - TVariable variable(param.name, *param.type); - TIntermSymbol *paramSymbol = intermediate.addSymbol( - variable.getUniqueId(), variable.getName(), variable.getType(), location); - prototype = intermediate.growAggregate(prototype, paramSymbol, location); + TIntermSymbol *symbol = nullptr; + + // If the parameter has no name, it's not an error, just don't add it to symbol table (could + // be used for unused args). + if (param.name != nullptr) + { + // Insert the parameter in the symbol table. + if (insertParametersToSymbolTable) + { + TVariable *variable = symbolTable.declareVariable(param.name, *param.type); + if (variable) + { + symbol = new TIntermSymbol(variable->getUniqueId(), variable->getName(), + variable->getType()); + } + else + { + error(location, "redefinition", param.name->c_str()); + } + } + // Unsized type of a named parameter should have already been checked and sanitized. + ASSERT(!param.type->isUnsizedArray()); } else { - TIntermSymbol *paramSymbol = intermediate.addSymbol(0, "", *param.type, location); - prototype = intermediate.growAggregate(prototype, paramSymbol, location); + if (param.type->isUnsizedArray()) + { + error(location, "function parameter array must be sized at compile time", "[]"); + // We don't need to size the arrays since the parameter is unnamed and hence + // inaccessible. + } } + if (!symbol) + { + // The parameter had no name or declaring the symbol failed - either way, add a nameless + // symbol. + symbol = new TIntermSymbol(symbolTable.getEmptySymbolId(), "", *param.type); + } + symbol->setLine(location); + prototype->appendParameter(symbol); } + return prototype; +} - prototype->setOp(EOpPrototype); +TIntermFunctionPrototype *TParseContext::addFunctionPrototypeDeclaration( + const TFunction &parsedFunction, + const TSourceLoc &location) +{ + // Note: function found from the symbol table could be the same as parsedFunction if this is the + // first declaration. Either way the instance in the symbol table is used to track whether the + // function is declared multiple times. + TFunction *function = static_cast( + symbolTable.find(parsedFunction.getMangledName(), getShaderVersion())); + if (function->hasPrototypeDeclaration() && mShaderVersion == 100) + { + // ESSL 1.00.17 section 4.2.7. + // Doesn't apply to ESSL 3.00.4: see section 4.2.3. + error(location, "duplicate function prototype declarations are not allowed", "function"); + } + function->setHasPrototypeDeclaration(); + + TIntermFunctionPrototype *prototype = + createPrototypeNodeFromFunction(*function, location, false); symbolTable.pop(); @@ -1973,135 +3249,80 @@ TIntermAggregate *TParseContext::addFunctionPrototypeDeclaration(const TFunction { // ESSL 3.00.4 section 4.2.4. error(location, "local function prototype declarations are not allowed", "function"); - recover(); } return prototype; } -TIntermAggregate *TParseContext::addFunctionDefinition(const TFunction &function, - TIntermAggregate *functionPrototype, - TIntermAggregate *functionBody, - const TSourceLoc &location) +TIntermFunctionDefinition *TParseContext::addFunctionDefinition( + TIntermFunctionPrototype *functionPrototype, + TIntermBlock *functionBody, + const TSourceLoc &location) { - //?? Check that all paths return a value if return type != void ? - // May be best done as post process phase on intermediate code + // Check that non-void functions have at least one return statement. if (mCurrentFunctionType->getBasicType() != EbtVoid && !mFunctionReturnsValue) { - error(location, "function does not return a value:", "", function.getName().c_str()); - recover(); + error(location, "function does not return a value:", + functionPrototype->getFunctionSymbolInfo()->getName().c_str()); } - TIntermAggregate *aggregate = - intermediate.growAggregate(functionPrototype, functionBody, location); - intermediate.setAggregateOperator(aggregate, EOpFunction, location); - aggregate->setName(function.getMangledName().c_str()); - aggregate->setType(function.getReturnType()); - aggregate->setFunctionId(function.getUniqueId()); + if (functionBody == nullptr) + { + functionBody = new TIntermBlock(); + functionBody->setLine(location); + } + TIntermFunctionDefinition *functionNode = + new TIntermFunctionDefinition(functionPrototype, functionBody); + functionNode->setLine(location); symbolTable.pop(); - return aggregate; + return functionNode; } -void TParseContext::parseFunctionPrototype(const TSourceLoc &location, - TFunction *function, - TIntermAggregate **aggregateOut) +void TParseContext::parseFunctionDefinitionHeader(const TSourceLoc &location, + TFunction **function, + TIntermFunctionPrototype **prototypeOut) { + ASSERT(function); + ASSERT(*function); const TSymbol *builtIn = - symbolTable.findBuiltIn(function->getMangledName(), getShaderVersion()); + symbolTable.findBuiltIn((*function)->getMangledName(), getShaderVersion()); if (builtIn) { - error(location, "built-in functions cannot be redefined", function->getName().c_str()); - recover(); + error(location, "built-in functions cannot be redefined", (*function)->getName().c_str()); } - - TFunction *prevDec = - static_cast(symbolTable.find(function->getMangledName(), getShaderVersion())); - // - // Note: 'prevDec' could be 'function' if this is the first time we've seen function - // as it would have just been put in the symbol table. Otherwise, we're looking up - // an earlier occurance. - // - if (prevDec->isDefined()) + else { - // Then this function already has a body. - error(location, "function already has a body", function->getName().c_str()); - recover(); - } - prevDec->setDefined(); - // - // Overload the unique ID of the definition to be the same unique ID as the declaration. - // Eventually we will probably want to have only a single definition and just swap the - // arguments to be the definition's arguments. - // - function->setUniqueId(prevDec->getUniqueId()); + TFunction *prevDec = static_cast( + symbolTable.find((*function)->getMangledName(), getShaderVersion())); - // Raise error message if main function takes any parameters or return anything other than void - if (function->getName() == "main") - { - if (function->getParamCount() > 0) + // Note: 'prevDec' could be 'function' if this is the first time we've seen function as it + // would have just been put in the symbol table. Otherwise, we're looking up an earlier + // occurance. + if (*function != prevDec) { - error(location, "function cannot take any parameter(s)", function->getName().c_str()); - recover(); + // Swap the parameters of the previous declaration to the parameters of the function + // definition (parameter names may differ). + prevDec->swapParameters(**function); + + // The function definition will share the same symbol as any previous declaration. + *function = prevDec; } - if (function->getReturnType().getBasicType() != EbtVoid) + + if ((*function)->isDefined()) { - error(location, "", function->getReturnType().getBasicString(), - "main function cannot return a value"); - recover(); + error(location, "function already has a body", (*function)->getName().c_str()); } + + (*function)->setDefined(); } - // - // Remember the return type for later checking for RETURN statements. - // - mCurrentFunctionType = &(prevDec->getReturnType()); + // Remember the return type for later checking for return statements. + mCurrentFunctionType = &((*function)->getReturnType()); mFunctionReturnsValue = false; - // - // Insert parameters into the symbol table. - // If the parameter has no name, it's not an error, just don't insert it - // (could be used for unused args). - // - // Also, accumulate the list of parameters into the HIL, so lower level code - // knows where to find parameters. - // - TIntermAggregate *paramNodes = new TIntermAggregate; - for (size_t i = 0; i < function->getParamCount(); i++) - { - const TConstParameter ¶m = function->getParam(i); - if (param.name != 0) - { - TVariable *variable = new TVariable(param.name, *param.type); - // - // Insert the parameters with name in the symbol table. - // - if (!symbolTable.declare(variable)) - { - error(location, "redefinition", variable->getName().c_str()); - recover(); - paramNodes = intermediate.growAggregate( - paramNodes, intermediate.addSymbol(0, "", *param.type, location), location); - continue; - } - - // - // Add the parameter to the HIL - // - TIntermSymbol *symbol = intermediate.addSymbol( - variable->getUniqueId(), variable->getName(), variable->getType(), location); - - paramNodes = intermediate.growAggregate(paramNodes, symbol, location); - } - else - { - paramNodes = intermediate.growAggregate( - paramNodes, intermediate.addSymbol(0, "", *param.type, location), location); - } - } - intermediate.setAggregateOperator(paramNodes, EOpParameters, location); - *aggregateOut = paramNodes; + *prototypeOut = createPrototypeNodeFromFunction(**function, location, true); setLoopNestingLevel(0); } @@ -2117,22 +3338,42 @@ TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TF // TFunction *prevDec = static_cast(symbolTable.find(function->getMangledName(), getShaderVersion())); - if (prevDec) + + for (size_t i = 0u; i < function->getParamCount(); ++i) + { + auto ¶m = function->getParam(i); + if (param.type->isStructSpecifier()) + { + // ESSL 3.00.6 section 12.10. + error(location, "Function parameter type cannot be a structure definition", + function->getName().c_str()); + } + } + + if (getShaderVersion() >= 300 && + symbolTable.hasUnmangledBuiltInForShaderVersion(function->getName().c_str(), + getShaderVersion())) + { + // With ESSL 3.00 and above, names of built-in functions cannot be redeclared as functions. + // Therefore overloading or redefining builtin functions is an error. + error(location, "Name of a built-in function cannot be redeclared as function", + function->getName().c_str()); + } + else if (prevDec) { if (prevDec->getReturnType() != function->getReturnType()) { - error(location, "overloaded functions must have the same return type", + error(location, "function must have the same return type in all of its declarations", function->getReturnType().getBasicString()); - recover(); } for (size_t i = 0; i < prevDec->getParamCount(); ++i) { if (prevDec->getParam(i).type->getQualifier() != function->getParam(i).type->getQualifier()) { - error(location, "overloaded functions must have the same parameter qualifiers", + error(location, + "function must have the same parameter qualifiers in all of its declarations", function->getParam(i).type->getQualifierString()); - recover(); } } } @@ -2145,22 +3386,33 @@ TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TF { if (!prevSym->isFunction()) { - error(location, "redefinition", function->getName().c_str(), "function"); - recover(); + error(location, "redefinition of a function", function->getName().c_str()); } } else { // Insert the unmangled name to detect potential future redefinition as a variable. - TFunction *newFunction = - new TFunction(NewPoolTString(function->getName().c_str()), &function->getReturnType()); - symbolTable.getOuterLevel()->insertUnmangled(newFunction); + symbolTable.getOuterLevel()->insertUnmangled(function); } // We're at the inner scope level of the function's arguments and body statement. // Add the function prototype to the surrounding scope instead. symbolTable.getOuterLevel()->insert(function); + // Raise error message if main function takes any parameters or return anything other than void + if (function->getName() == "main") + { + if (function->getParamCount() > 0) + { + error(location, "function cannot take any parameter(s)", "main"); + } + if (function->getReturnType().getBasicType() != EbtVoid) + { + error(location, "main function cannot return a value", + function->getReturnType().getBasicString()); + } + } + // // If this is a redeclaration, it could also be a definition, in which case, we want to use the // variable names from this one, and not the one that's @@ -2169,420 +3421,302 @@ TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TF return function; } -TFunction *TParseContext::addConstructorFunc(const TPublicType &publicTypeIn) +TFunction *TParseContext::parseFunctionHeader(const TPublicType &type, + const TString *name, + const TSourceLoc &location) { - TPublicType publicType = publicTypeIn; - if (publicType.isStructSpecifier) + if (type.qualifier != EvqGlobal && type.qualifier != EvqTemporary) { - error(publicType.line, "constructor can't be a structure definition", - getBasicString(publicType.type)); - recover(); + error(location, "no qualifiers allowed for function return", + getQualifierString(type.qualifier)); } - - TOperator op = EOpNull; - if (publicType.userDef) + if (!type.layoutQualifier.isEmpty()) { - op = EOpConstructStruct; + error(location, "no qualifiers allowed for function return", "layout"); } - else + // make sure an opaque type is not involved as well... + std::string reason(getBasicString(type.getBasicType())); + reason += "s can't be function return values"; + checkIsNotOpaqueType(location, type.typeSpecifierNonArray, reason.c_str()); + if (mShaderVersion < 300) { - switch (publicType.type) + // Array return values are forbidden, but there's also no valid syntax for declaring array + // return values in ESSL 1.00. + ASSERT(!type.isArray() || mDiagnostics->numErrors() > 0); + + if (type.isStructureContainingArrays()) { - case EbtFloat: - if (publicType.isMatrix()) - { - switch (publicType.getCols()) - { - case 2: - switch (publicType.getRows()) - { - case 2: - op = EOpConstructMat2; - break; - case 3: - op = EOpConstructMat2x3; - break; - case 4: - op = EOpConstructMat2x4; - break; - } - break; - case 3: - switch (publicType.getRows()) - { - case 2: - op = EOpConstructMat3x2; - break; - case 3: - op = EOpConstructMat3; - break; - case 4: - op = EOpConstructMat3x4; - break; - } - break; - case 4: - switch (publicType.getRows()) - { - case 2: - op = EOpConstructMat4x2; - break; - case 3: - op = EOpConstructMat4x3; - break; - case 4: - op = EOpConstructMat4; - break; - } - break; - } - } - else - { - switch (publicType.getNominalSize()) - { - case 1: - op = EOpConstructFloat; - break; - case 2: - op = EOpConstructVec2; - break; - case 3: - op = EOpConstructVec3; - break; - case 4: - op = EOpConstructVec4; - break; - } - } - break; - - case EbtInt: - switch (publicType.getNominalSize()) - { - case 1: - op = EOpConstructInt; - break; - case 2: - op = EOpConstructIVec2; - break; - case 3: - op = EOpConstructIVec3; - break; - case 4: - op = EOpConstructIVec4; - break; - } - break; - - case EbtUInt: - switch (publicType.getNominalSize()) - { - case 1: - op = EOpConstructUInt; - break; - case 2: - op = EOpConstructUVec2; - break; - case 3: - op = EOpConstructUVec3; - break; - case 4: - op = EOpConstructUVec4; - break; - } - break; - - case EbtBool: - switch (publicType.getNominalSize()) - { - case 1: - op = EOpConstructBool; - break; - case 2: - op = EOpConstructBVec2; - break; - case 3: - op = EOpConstructBVec3; - break; - case 4: - op = EOpConstructBVec4; - break; - } - break; - - default: - break; - } - - if (op == EOpNull) - { - error(publicType.line, "cannot construct this type", getBasicString(publicType.type)); - recover(); - publicType.type = EbtFloat; - op = EOpConstructFloat; + // ESSL 1.00.17 section 6.1 Function Definitions + error(location, "structures containing arrays can't be function return values", + TType(type).getCompleteString().c_str()); } } - TString tempString; - const TType *type = new TType(publicType); - return new TFunction(&tempString, type, op); + // Add the function as a prototype after parsing it (we do not support recursion) + return new TFunction(&symbolTable, name, new TType(type)); +} + +TFunction *TParseContext::addNonConstructorFunc(const TString *name, const TSourceLoc &loc) +{ + const TType *returnType = TCache::getType(EbtVoid, EbpUndefined); + return new TFunction(&symbolTable, name, returnType); +} + +TFunction *TParseContext::addConstructorFunc(const TPublicType &publicType) +{ + if (mShaderVersion < 300 && publicType.isArray()) + { + error(publicType.getLine(), "array constructor supported in GLSL ES 3.00 and above only", + "[]"); + } + if (publicType.isStructSpecifier()) + { + error(publicType.getLine(), "constructor can't be a structure definition", + getBasicString(publicType.getBasicType())); + } + + TType *type = new TType(publicType); + if (!type->canBeConstructed()) + { + error(publicType.getLine(), "cannot construct this type", + getBasicString(publicType.getBasicType())); + type->setBasicType(EbtFloat); + } + + return new TFunction(&symbolTable, nullptr, type, EOpConstruct); +} + +void TParseContext::checkIsNotUnsizedArray(const TSourceLoc &line, + const char *errorMessage, + const char *token, + TType *arrayType) +{ + if (arrayType->isUnsizedArray()) + { + error(line, errorMessage, token); + arrayType->sizeUnsizedArrays(nullptr); + } +} + +TParameter TParseContext::parseParameterDeclarator(TType *type, + const TString *name, + const TSourceLoc &nameLoc) +{ + ASSERT(type); + checkIsNotUnsizedArray(nameLoc, "function parameter array must specify a size", name->c_str(), + type); + if (type->getBasicType() == EbtVoid) + { + error(nameLoc, "illegal use of type 'void'", name->c_str()); + } + checkIsNotReserved(nameLoc, *name); + TParameter param = {name, type}; + return param; +} + +TParameter TParseContext::parseParameterDeclarator(const TPublicType &publicType, + const TString *name, + const TSourceLoc &nameLoc) +{ + TType *type = new TType(publicType); + return parseParameterDeclarator(type, name, nameLoc); +} + +TParameter TParseContext::parseParameterArrayDeclarator(const TString *name, + const TSourceLoc &nameLoc, + const TVector &arraySizes, + const TSourceLoc &arrayLoc, + TPublicType *elementType) +{ + checkArrayElementIsNotArray(arrayLoc, *elementType); + TType *arrayType = new TType(*elementType); + arrayType->makeArrays(arraySizes); + return parseParameterDeclarator(arrayType, name, nameLoc); +} + +bool TParseContext::checkUnsizedArrayConstructorArgumentDimensionality(TIntermSequence *arguments, + TType type, + const TSourceLoc &line) +{ + if (arguments->empty()) + { + error(line, "implicitly sized array constructor must have at least one argument", "[]"); + return false; + } + for (TIntermNode *arg : *arguments) + { + TIntermTyped *element = arg->getAsTyped(); + ASSERT(element); + size_t dimensionalityFromElement = element->getType().getNumArraySizes() + 1u; + if (dimensionalityFromElement > type.getNumArraySizes()) + { + error(line, "constructing from a non-dereferenced array", "constructor"); + return false; + } + else if (dimensionalityFromElement < type.getNumArraySizes()) + { + if (dimensionalityFromElement == 1u) + { + error(line, "implicitly sized array of arrays constructor argument is not an array", + "constructor"); + } + else + { + error(line, + "implicitly sized array of arrays constructor argument dimensionality is too " + "low", + "constructor"); + } + return false; + } + } + return true; } // This function is used to test for the correctness of the parameters passed to various constructor // functions and also convert them to the right datatype if it is allowed and required. // -// Returns 0 for an error or the constructed node (aggregate or typed) for no error. +// Returns a node to add to the tree regardless of if an error was generated or not. // -TIntermTyped *TParseContext::addConstructor(TIntermNode *arguments, - TType *type, - TOperator op, - TFunction *fnCall, +TIntermTyped *TParseContext::addConstructor(TIntermSequence *arguments, + TType type, const TSourceLoc &line) { - TIntermAggregate *constructor = arguments->getAsAggregate(); - ASSERT(constructor != nullptr); - - if (type->isArray()) + if (type.isUnsizedArray()) { - // GLSL ES 3.00 section 5.4.4: Each argument must be the same type as the element type of - // the array. - TIntermSequence *args = constructor->getSequence(); - for (size_t i = 0; i < args->size(); i++) + if (!checkUnsizedArrayConstructorArgumentDimensionality(arguments, type, line)) { - const TType &argType = (*args)[i]->getAsTyped()->getType(); - // It has already been checked that the argument is not an array. - ASSERT(!argType.isArray()); - if (!argType.sameElementType(*type)) + type.sizeUnsizedArrays(nullptr); + return CreateZeroNode(type); + } + TIntermTyped *firstElement = arguments->at(0)->getAsTyped(); + ASSERT(firstElement); + if (type.getOutermostArraySize() == 0u) + { + type.sizeOutermostUnsizedArray(static_cast(arguments->size())); + } + for (size_t i = 0; i < firstElement->getType().getNumArraySizes(); ++i) + { + if ((*type.getArraySizes())[i] == 0u) { - error(line, "Array constructor argument has an incorrect type", "Error"); - recover(); - return nullptr; + type.setArraySize(i, (*firstElement->getType().getArraySizes())[i]); } } + ASSERT(!type.isUnsizedArray()); } - else if (op == EOpConstructStruct) + + if (!checkConstructorArguments(line, arguments, type)) { - const TFieldList &fields = type->getStruct()->fields(); - TIntermSequence *args = constructor->getSequence(); - - for (size_t i = 0; i < fields.size(); i++) - { - if (i >= args->size() || (*args)[i]->getAsTyped()->getType() != *fields[i]->type()) - { - error(line, "Structure constructor arguments do not match structure fields", - "Error"); - recover(); - - return 0; - } - } + return CreateZeroNode(type); } - // Turn the argument list itself into a constructor - constructor->setOp(op); - constructor->setLine(line); - ASSERT(constructor->isConstructor()); + TIntermAggregate *constructorNode = TIntermAggregate::CreateConstructor(type, arguments); + constructorNode->setLine(line); - // Need to set type before setPrecisionFromChildren() because bool doesn't have precision. - constructor->setType(*type); - - // Structs should not be precision qualified, the individual members may be. - // Built-in types on the other hand should be precision qualified. - if (op != EOpConstructStruct) + // TODO(oetuaho@nvidia.com): Add support for folding array constructors. + if (!constructorNode->isArray()) { - constructor->setPrecisionFromChildren(); - type->setPrecision(constructor->getPrecision()); + return constructorNode->fold(mDiagnostics); } - - TIntermTyped *constConstructor = intermediate.foldAggregateBuiltIn(constructor); - if (constConstructor) - { - return constConstructor; - } - - return constructor; -} - -// -// This function returns the tree representation for the vector field(s) being accessed from contant -// vector. -// If only one component of vector is accessed (v.x or v[0] where v is a contant vector), then a -// contant node is returned, else an aggregate node is returned (for v.xy). The input to this -// function could either be the symbol node or it could be the intermediate tree representation of -// accessing fields in a constant structure or column of a constant matrix. -// -TIntermTyped *TParseContext::addConstVectorNode(TVectorFields &fields, - TIntermConstantUnion *node, - const TSourceLoc &line, - bool outOfRangeIndexIsError) -{ - const TConstantUnion *unionArray = node->getUnionArrayPointer(); - ASSERT(unionArray); - - TConstantUnion *constArray = new TConstantUnion[fields.num]; - - for (int i = 0; i < fields.num; i++) - { - if (fields.offsets[i] >= node->getType().getNominalSize()) - { - std::stringstream extraInfoStream; - extraInfoStream << "vector field selection out of range '" << fields.offsets[i] << "'"; - std::string extraInfo = extraInfoStream.str(); - outOfRangeError(outOfRangeIndexIsError, line, "", "[", extraInfo.c_str()); - fields.offsets[i] = node->getType().getNominalSize() - 1; - } - - constArray[i] = unionArray[fields.offsets[i]]; - } - return intermediate.addConstantUnion(constArray, node->getType(), line); -} - -// -// This function returns the column being accessed from a constant matrix. The values are retrieved -// from the symbol table and parse-tree is built for a vector (each column of a matrix is a vector). -// The input to the function could either be a symbol node (m[0] where m is a constant matrix)that -// represents a constant matrix or it could be the tree representation of the constant matrix -// (s.m1[0] where s is a constant structure) -// -TIntermTyped *TParseContext::addConstMatrixNode(int index, - TIntermConstantUnion *node, - const TSourceLoc &line, - bool outOfRangeIndexIsError) -{ - if (index >= node->getType().getCols()) - { - std::stringstream extraInfoStream; - extraInfoStream << "matrix field selection out of range '" << index << "'"; - std::string extraInfo = extraInfoStream.str(); - outOfRangeError(outOfRangeIndexIsError, line, "", "[", extraInfo.c_str()); - index = node->getType().getCols() - 1; - } - - const TConstantUnion *unionArray = node->getUnionArrayPointer(); - int size = node->getType().getCols(); - return intermediate.addConstantUnion(&unionArray[size * index], node->getType(), line); -} - -// -// This function returns an element of an array accessed from a constant array. The values are -// retrieved from the symbol table and parse-tree is built for the type of the element. The input -// to the function could either be a symbol node (a[0] where a is a constant array)that represents a -// constant array or it could be the tree representation of the constant array (s.a1[0] where s is a -// constant structure) -// -TIntermTyped *TParseContext::addConstArrayNode(int index, - TIntermConstantUnion *node, - const TSourceLoc &line, - bool outOfRangeIndexIsError) -{ - TType arrayElementType = node->getType(); - arrayElementType.clearArrayness(); - - if (index >= node->getType().getArraySize()) - { - std::stringstream extraInfoStream; - extraInfoStream << "array field selection out of range '" << index << "'"; - std::string extraInfo = extraInfoStream.str(); - outOfRangeError(outOfRangeIndexIsError, line, "", "[", extraInfo.c_str()); - index = node->getType().getArraySize() - 1; - } - size_t arrayElementSize = arrayElementType.getObjectSize(); - const TConstantUnion *unionArray = node->getUnionArrayPointer(); - return intermediate.addConstantUnion(&unionArray[arrayElementSize * index], node->getType(), - line); -} - -// -// This function returns the value of a particular field inside a constant structure from the symbol -// table. -// If there is an embedded/nested struct, it appropriately calls addConstStructNested or -// addConstStructFromAggr function and returns the parse-tree with the values of the embedded/nested -// struct. -// -TIntermTyped *TParseContext::addConstStruct(const TString &identifier, - TIntermTyped *node, - const TSourceLoc &line) -{ - const TFieldList &fields = node->getType().getStruct()->fields(); - size_t instanceSize = 0; - - for (size_t index = 0; index < fields.size(); ++index) - { - if (fields[index]->name() == identifier) - { - break; - } - else - { - instanceSize += fields[index]->type()->getObjectSize(); - } - } - - TIntermTyped *typedNode; - TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion(); - if (tempConstantNode) - { - const TConstantUnion *constArray = tempConstantNode->getUnionArrayPointer(); - - // type will be changed in the calling function - typedNode = intermediate.addConstantUnion(constArray + instanceSize, - tempConstantNode->getType(), line); - } - else - { - error(line, "Cannot offset into the structure", "Error"); - recover(); - - return 0; - } - - return typedNode; + return constructorNode; } // // Interface/uniform blocks +// TODO(jiawei.shao@intel.com): implement GL_OES_shader_io_blocks. // -TIntermAggregate *TParseContext::addInterfaceBlock(const TPublicType &typeQualifier, - const TSourceLoc &nameLine, - const TString &blockName, - TFieldList *fieldList, - const TString *instanceName, - const TSourceLoc &instanceLine, - TIntermTyped *arrayIndex, - const TSourceLoc &arrayIndexLine) +TIntermDeclaration *TParseContext::addInterfaceBlock( + const TTypeQualifierBuilder &typeQualifierBuilder, + const TSourceLoc &nameLine, + const TString &blockName, + TFieldList *fieldList, + const TString *instanceName, + const TSourceLoc &instanceLine, + TIntermTyped *arrayIndex, + const TSourceLoc &arrayIndexLine) { - if (reservedErrorCheck(nameLine, blockName)) - recover(); + checkIsNotReserved(nameLine, blockName); - if (typeQualifier.qualifier != EvqUniform) + TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics); + + if (mShaderVersion < 310 && typeQualifier.qualifier != EvqUniform) { - error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier), - "interface blocks must be uniform"); - recover(); + error(typeQualifier.line, + "invalid qualifier: interface blocks must be uniform in version lower than GLSL ES " + "3.10", + getQualifierString(typeQualifier.qualifier)); } + else if (typeQualifier.qualifier != EvqUniform && typeQualifier.qualifier != EvqBuffer) + { + error(typeQualifier.line, "invalid qualifier: interface blocks must be uniform or buffer", + getQualifierString(typeQualifier.qualifier)); + } + + if (typeQualifier.invariant) + { + error(typeQualifier.line, "invalid qualifier on interface block member", "invariant"); + } + + if (typeQualifier.qualifier != EvqBuffer) + { + checkMemoryQualifierIsNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line); + } + + // add array index + unsigned int arraySize = 0; + if (arrayIndex != nullptr) + { + arraySize = checkIsValidArraySize(arrayIndexLine, arrayIndex); + } + + if (mShaderVersion < 310) + { + checkBindingIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.binding); + } + else + { + checkBlockBindingIsValid(typeQualifier.line, typeQualifier.qualifier, + typeQualifier.layoutQualifier.binding, arraySize); + } + + checkYuvIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.yuv); TLayoutQualifier blockLayoutQualifier = typeQualifier.layoutQualifier; - if (layoutLocationErrorCheck(typeQualifier.line, blockLayoutQualifier)) - { - recover(); - } + checkLocationIsNotSpecified(typeQualifier.line, blockLayoutQualifier); + checkStd430IsForShaderStorageBlock(typeQualifier.line, blockLayoutQualifier.blockStorage, + typeQualifier.qualifier); if (blockLayoutQualifier.matrixPacking == EmpUnspecified) { - blockLayoutQualifier.matrixPacking = mDefaultMatrixPacking; + if (typeQualifier.qualifier == EvqUniform) + { + blockLayoutQualifier.matrixPacking = mDefaultUniformMatrixPacking; + } + else if (typeQualifier.qualifier == EvqBuffer) + { + blockLayoutQualifier.matrixPacking = mDefaultBufferMatrixPacking; + } } if (blockLayoutQualifier.blockStorage == EbsUnspecified) { - blockLayoutQualifier.blockStorage = mDefaultBlockStorage; + if (typeQualifier.qualifier == EvqUniform) + { + blockLayoutQualifier.blockStorage = mDefaultUniformBlockStorage; + } + else if (typeQualifier.qualifier == EvqBuffer) + { + blockLayoutQualifier.blockStorage = mDefaultBufferBlockStorage; + } } - TSymbol *blockNameSymbol = new TInterfaceBlockName(&blockName); - if (!symbolTable.declare(blockNameSymbol)) + checkWorkGroupSizeIsNotSpecified(nameLine, blockLayoutQualifier); + + checkInternalFormatIsNotSpecified(nameLine, blockLayoutQualifier.imageInternalFormat); + + if (!symbolTable.declareInterfaceBlockName(&blockName)) { - error(nameLine, "redefinition", blockName.c_str(), "interface block name"); - recover(); + error(nameLine, "redefinition of an interface block name", blockName.c_str()); } // check for sampler types and apply layout qualifiers @@ -2590,38 +3724,53 @@ TIntermAggregate *TParseContext::addInterfaceBlock(const TPublicType &typeQualif { TField *field = (*fieldList)[memberIndex]; TType *fieldType = field->type(); - if (IsSampler(fieldType->getBasicType())) + if (IsOpaqueType(fieldType->getBasicType())) { - error(field->line(), "unsupported type", fieldType->getBasicString(), - "sampler types are not allowed in interface blocks"); - recover(); + std::string reason("unsupported type - "); + reason += fieldType->getBasicString(); + reason += " types are not allowed in interface blocks"; + error(field->line(), reason.c_str(), fieldType->getBasicString()); } const TQualifier qualifier = fieldType->getQualifier(); switch (qualifier) { case EvqGlobal: + break; case EvqUniform: + if (typeQualifier.qualifier == EvqBuffer) + { + error(field->line(), "invalid qualifier on shader storage block member", + getQualifierString(qualifier)); + } + break; + case EvqBuffer: + if (typeQualifier.qualifier == EvqUniform) + { + error(field->line(), "invalid qualifier on uniform block member", + getQualifierString(qualifier)); + } break; default: error(field->line(), "invalid qualifier on interface block member", getQualifierString(qualifier)); - recover(); break; } + if (fieldType->isInvariant()) + { + error(field->line(), "invalid qualifier on interface block member", "invariant"); + } + // check layout qualifiers TLayoutQualifier fieldLayoutQualifier = fieldType->getLayoutQualifier(); - if (layoutLocationErrorCheck(field->line(), fieldLayoutQualifier)) - { - recover(); - } + checkLocationIsNotSpecified(field->line(), fieldLayoutQualifier); + checkBindingIsNotSpecified(field->line(), fieldLayoutQualifier.binding); if (fieldLayoutQualifier.blockStorage != EbsUnspecified) { - error(field->line(), "invalid layout qualifier:", - getBlockStorageString(fieldLayoutQualifier.blockStorage), "cannot be used here"); - recover(); + error(field->line(), "invalid layout qualifier: cannot be used here", + getBlockStorageString(fieldLayoutQualifier.blockStorage)); } if (fieldLayoutQualifier.matrixPacking == EmpUnspecified) @@ -2630,29 +3779,51 @@ TIntermAggregate *TParseContext::addInterfaceBlock(const TPublicType &typeQualif } else if (!fieldType->isMatrix() && fieldType->getBasicType() != EbtStruct) { - warning(field->line(), "extraneous layout qualifier:", - getMatrixPackingString(fieldLayoutQualifier.matrixPacking), - "only has an effect on matrix types"); + warning(field->line(), + "extraneous layout qualifier: only has an effect on matrix types", + getMatrixPackingString(fieldLayoutQualifier.matrixPacking)); } fieldType->setLayoutQualifier(fieldLayoutQualifier); - } - // add array index - int arraySize = 0; - if (arrayIndex != NULL) - { - if (arraySizeErrorCheck(arrayIndexLine, arrayIndex, arraySize)) - recover(); + if (mShaderVersion < 310 || memberIndex != fieldList->size() - 1u || + typeQualifier.qualifier != EvqBuffer) + { + // ESSL 3.10 spec section 4.1.9 allows for runtime-sized arrays. + checkIsNotUnsizedArray(field->line(), + "array members of interface blocks must specify a size", + field->name().c_str(), field->type()); + } + + if (typeQualifier.qualifier == EvqBuffer) + { + // set memory qualifiers + // GLSL ES 3.10 session 4.9 [Memory Access Qualifiers]. When a block declaration is + // qualified with a memory qualifier, it is as if all of its members were declared with + // the same memory qualifier. + const TMemoryQualifier &blockMemoryQualifier = typeQualifier.memoryQualifier; + TMemoryQualifier fieldMemoryQualifier = fieldType->getMemoryQualifier(); + fieldMemoryQualifier.readonly |= blockMemoryQualifier.readonly; + fieldMemoryQualifier.writeonly |= blockMemoryQualifier.writeonly; + fieldMemoryQualifier.coherent |= blockMemoryQualifier.coherent; + fieldMemoryQualifier.restrictQualifier |= blockMemoryQualifier.restrictQualifier; + fieldMemoryQualifier.volatileQualifier |= blockMemoryQualifier.volatileQualifier; + // TODO(jiajia.qin@intel.com): Decide whether if readonly and writeonly buffer variable + // is legal. See bug https://github.com/KhronosGroup/OpenGL-API/issues/7 + fieldType->setMemoryQualifier(fieldMemoryQualifier); + } } TInterfaceBlock *interfaceBlock = - new TInterfaceBlock(&blockName, fieldList, instanceName, arraySize, blockLayoutQualifier); - TType interfaceBlockType(interfaceBlock, typeQualifier.qualifier, blockLayoutQualifier, - arraySize); + new TInterfaceBlock(&blockName, fieldList, instanceName, blockLayoutQualifier); + TType interfaceBlockType(interfaceBlock, typeQualifier.qualifier, blockLayoutQualifier); + if (arrayIndex != nullptr) + { + interfaceBlockType.makeArray(arraySize); + } TString symbolName = ""; - int symbolId = 0; + const TSymbolUniqueId *symbolId = nullptr; if (!instanceName) { @@ -2665,60 +3836,64 @@ TIntermAggregate *TParseContext::addInterfaceBlock(const TPublicType &typeQualif // set parent pointer of the field variable fieldType->setInterfaceBlock(interfaceBlock); - TVariable *fieldVariable = new TVariable(&field->name(), *fieldType); - fieldVariable->setQualifier(typeQualifier.qualifier); + TVariable *fieldVariable = symbolTable.declareVariable(&field->name(), *fieldType); - if (!symbolTable.declare(fieldVariable)) + if (fieldVariable) { - error(field->line(), "redefinition", field->name().c_str(), - "interface block member name"); - recover(); + fieldVariable->setQualifier(typeQualifier.qualifier); + } + else + { + error(field->line(), "redefinition of an interface block member name", + field->name().c_str()); } } + symbolId = &symbolTable.getEmptySymbolId(); } else { - if (reservedErrorCheck(instanceLine, *instanceName)) - recover(); + checkIsNotReserved(instanceLine, *instanceName); // add a symbol for this interface block - TVariable *instanceTypeDef = new TVariable(instanceName, interfaceBlockType, false); - instanceTypeDef->setQualifier(typeQualifier.qualifier); - - if (!symbolTable.declare(instanceTypeDef)) + TVariable *instanceTypeDef = symbolTable.declareVariable(instanceName, interfaceBlockType); + if (instanceTypeDef) { - error(instanceLine, "redefinition", instanceName->c_str(), - "interface block instance name"); - recover(); + instanceTypeDef->setQualifier(typeQualifier.qualifier); + symbolId = &instanceTypeDef->getUniqueId(); } - - symbolId = instanceTypeDef->getUniqueId(); - symbolName = instanceTypeDef->getName(); + else + { + error(instanceLine, "redefinition of an interface block instance name", + instanceName->c_str()); + } + symbolName = *instanceName; } - TIntermAggregate *aggregate = intermediate.makeAggregate( - intermediate.addSymbol(symbolId, symbolName, interfaceBlockType, typeQualifier.line), - nameLine); - aggregate->setOp(EOpDeclaration); + TIntermDeclaration *declaration = nullptr; + + if (symbolId) + { + TIntermSymbol *blockSymbol = new TIntermSymbol(*symbolId, symbolName, interfaceBlockType); + blockSymbol->setLine(typeQualifier.line); + declaration = new TIntermDeclaration(); + declaration->appendDeclarator(blockSymbol); + declaration->setLine(nameLine); + } exitStructDeclaration(); - return aggregate; + return declaration; } -bool TParseContext::enterStructDeclaration(const TSourceLoc &line, const TString &identifier) +void TParseContext::enterStructDeclaration(const TSourceLoc &line, const TString &identifier) { ++mStructNestingLevel; // Embedded structure definitions are not supported per GLSL ES spec. - // They aren't allowed in GLSL either, but we need to detect this here - // so we don't rely on the GLSL compiler to catch it. + // ESSL 1.00.17 section 10.9. ESSL 3.00.6 section 12.11. if (mStructNestingLevel > 1) { - error(line, "", "Embedded struct definitions are not allowed"); - return true; + error(line, "Embedded struct definitions are not allowed", "struct"); } - - return false; } void TParseContext::exitStructDeclaration() @@ -2726,22 +3901,16 @@ void TParseContext::exitStructDeclaration() --mStructNestingLevel; } -namespace +void TParseContext::checkIsBelowStructNestingLimit(const TSourceLoc &line, const TField &field) { -const int kWebGLMaxStructNesting = 4; - -} // namespace - -bool TParseContext::structNestingErrorCheck(const TSourceLoc &line, const TField &field) -{ - if (!IsWebGLBasedSpec(mShaderSpec)) + if (!sh::IsWebGLBasedSpec(mShaderSpec)) { - return false; + return; } if (field.type()->getBasicType() != EbtStruct) { - return false; + return; } // We're already inside a structure definition at this point, so add @@ -2752,11 +3921,9 @@ bool TParseContext::structNestingErrorCheck(const TSourceLoc &line, const TField reasonStream << "Reference of struct type " << field.type()->getStruct()->name().c_str() << " exceeds maximum allowed nesting level of " << kWebGLMaxStructNesting; std::string reason = reasonStream.str(); - error(line, reason.c_str(), field.name().c_str(), ""); - return true; + error(line, reason.c_str(), field.name().c_str()); + return; } - - return false; } // @@ -2766,8 +3933,6 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc &location, TIntermTyped *indexExpression) { - TIntermTyped *indexedExpression = NULL; - if (!baseExpression->isArray() && !baseExpression->isMatrix() && !baseExpression->isVector()) { if (baseExpression->getAsSymbolNode()) @@ -2779,7 +3944,18 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression, { error(location, " left of '[' is not of type array, matrix, or vector ", "expression"); } - recover(); + + return CreateZeroNode(TType(EbtFloat, EbpHigh, EvqConst)); + } + + if (baseExpression->getQualifier() == EvqPerVertexIn) + { + ASSERT(mShaderType == GL_GEOMETRY_SHADER_OES); + if (mGeometryShaderInputPrimitiveType == EptUndefined) + { + error(location, "missing input primitive declaration before indexing gl_in.", "["); + return CreateZeroNode(TType(EbtFloat, EbpHigh, EvqConst)); + } } TIntermConstantUnion *indexConstantUnion = indexExpression->getAsConstantUnion(); @@ -2792,174 +3968,139 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression, { if (baseExpression->isInterfaceBlock()) { - error( - location, "", "[", - "array indexes for interface blocks arrays must be constant integral expressions"); - recover(); + // TODO(jiawei.shao@intel.com): implement GL_OES_shader_io_blocks. + switch (baseExpression->getQualifier()) + { + case EvqPerVertexIn: + break; + case EvqUniform: + case EvqBuffer: + error(location, + "array indexes for uniform block arrays and shader storage block arrays " + "must be constant integral expressions", + "["); + break; + default: + // We can reach here only in error cases. + ASSERT(mDiagnostics->numErrors() > 0); + break; + } } else if (baseExpression->getQualifier() == EvqFragmentOut) { - error(location, "", "[", - "array indexes for fragment outputs must be constant integral expressions"); - recover(); + error(location, + "array indexes for fragment outputs must be constant integral expressions", "["); } else if (mShaderSpec == SH_WEBGL2_SPEC && baseExpression->getQualifier() == EvqFragData) { - error(location, "", "[", "array index for gl_FragData must be constant zero"); - recover(); + error(location, "array index for gl_FragData must be constant zero", "["); } } if (indexConstantUnion) { - // If the index is not qualified as constant, the behavior in the spec is undefined. This - // applies even if ANGLE has been able to constant fold it (ANGLE may constant fold - // expressions that are not constant expressions). The most compatible way to handle this - // case is to report a warning instead of an error and force the index to be in the - // correct range. + // If an out-of-range index is not qualified as constant, the behavior in the spec is + // undefined. This applies even if ANGLE has been able to constant fold it (ANGLE may + // constant fold expressions that are not constant expressions). The most compatible way to + // handle this case is to report a warning instead of an error and force the index to be in + // the correct range. bool outOfRangeIndexIsError = indexExpression->getQualifier() == EvqConst; - int index = indexConstantUnion->getIConst(0); + int index = 0; + if (indexConstantUnion->getBasicType() == EbtInt) + { + index = indexConstantUnion->getIConst(0); + } + else if (indexConstantUnion->getBasicType() == EbtUInt) + { + index = static_cast(indexConstantUnion->getUConst(0)); + } + + int safeIndex = -1; + if (index < 0) { - std::stringstream infoStream; - infoStream << index; - std::string info = infoStream.str(); - outOfRangeError(outOfRangeIndexIsError, location, "negative index", info.c_str()); - index = 0; + outOfRangeError(outOfRangeIndexIsError, location, "index expression is negative", "[]"); + safeIndex = 0; } - TIntermConstantUnion *baseConstantUnion = baseExpression->getAsConstantUnion(); - if (baseConstantUnion) - { - if (baseExpression->isArray()) - { - // constant folding for array indexing - indexedExpression = - addConstArrayNode(index, baseConstantUnion, location, outOfRangeIndexIsError); - } - else if (baseExpression->isVector()) - { - // constant folding for vector indexing - TVectorFields fields; - fields.num = 1; - fields.offsets[0] = - index; // need to do it this way because v.xy sends fields integer array - indexedExpression = - addConstVectorNode(fields, baseConstantUnion, location, outOfRangeIndexIsError); - } - else if (baseExpression->isMatrix()) - { - // constant folding for matrix indexing - indexedExpression = - addConstMatrixNode(index, baseConstantUnion, location, outOfRangeIndexIsError); - } - } - else - { - int safeIndex = -1; + if (!baseExpression->getType().isUnsizedArray()) + { if (baseExpression->isArray()) { if (baseExpression->getQualifier() == EvqFragData && index > 0) { - if (mShaderSpec == SH_WEBGL2_SPEC) + if (!isExtensionEnabled(TExtension::EXT_draw_buffers)) { - // Error has been already generated if index is not const. - if (indexExpression->getQualifier() == EvqConst) - { - error(location, "", "[", - "array index for gl_FragData must be constant zero"); - recover(); - } - safeIndex = 0; - } - else if (!isExtensionEnabled("GL_EXT_draw_buffers")) - { - outOfRangeError(outOfRangeIndexIsError, location, "", "[", + outOfRangeError(outOfRangeIndexIsError, location, "array index for gl_FragData must be zero when " - "GL_EXT_draw_buffers is disabled"); + "GL_EXT_draw_buffers is disabled", + "[]"); safeIndex = 0; } } // Only do generic out-of-range check if similar error hasn't already been reported. - if (safeIndex < 0 && index >= baseExpression->getType().getArraySize()) + if (safeIndex < 0) { - std::stringstream extraInfoStream; - extraInfoStream << "array index out of range '" << index << "'"; - std::string extraInfo = extraInfoStream.str(); - outOfRangeError(outOfRangeIndexIsError, location, "", "[", extraInfo.c_str()); - safeIndex = baseExpression->getType().getArraySize() - 1; + safeIndex = checkIndexLessThan(outOfRangeIndexIsError, location, index, + baseExpression->getOutermostArraySize(), + "array index out of range"); } } - else if ((baseExpression->isVector() || baseExpression->isMatrix()) && - baseExpression->getType().getNominalSize() <= index) + else if (baseExpression->isMatrix()) { - std::stringstream extraInfoStream; - extraInfoStream << "field selection out of range '" << index << "'"; - std::string extraInfo = extraInfoStream.str(); - outOfRangeError(outOfRangeIndexIsError, location, "", "[", extraInfo.c_str()); - safeIndex = baseExpression->getType().getNominalSize() - 1; + safeIndex = checkIndexLessThan(outOfRangeIndexIsError, location, index, + baseExpression->getType().getCols(), + "matrix field selection out of range"); + } + else if (baseExpression->isVector()) + { + safeIndex = checkIndexLessThan(outOfRangeIndexIsError, location, index, + baseExpression->getType().getNominalSize(), + "vector field selection out of range"); } + ASSERT(safeIndex >= 0); // Data of constant unions can't be changed, because it may be shared with other // constant unions or even builtins, like gl_MaxDrawBuffers. Instead use a new // sanitized object. - if (safeIndex != -1) + if (safeIndex != index || indexConstantUnion->getBasicType() != EbtInt) { TConstantUnion *safeConstantUnion = new TConstantUnion(); safeConstantUnion->setIConst(safeIndex); indexConstantUnion->replaceConstantUnion(safeConstantUnion); + indexConstantUnion->getTypePointer()->setBasicType(EbtInt); } - indexedExpression = - intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location); + TIntermBinary *node = + new TIntermBinary(EOpIndexDirect, baseExpression, indexExpression); + node->setLine(location); + return node->fold(mDiagnostics); } } - else - { - indexedExpression = - intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location); - } - if (indexedExpression == 0) - { - TConstantUnion *unionArray = new TConstantUnion[1]; - unionArray->setFConst(0.0f); - indexedExpression = - intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), location); - } - else if (baseExpression->isArray()) - { - TType indexedType = baseExpression->getType(); - indexedType.clearArrayness(); - indexedExpression->setType(indexedType); - } - else if (baseExpression->isMatrix()) - { - indexedExpression->setType(TType(baseExpression->getBasicType(), - baseExpression->getPrecision(), EvqTemporary, - static_cast(baseExpression->getRows()))); - } - else if (baseExpression->isVector()) - { - indexedExpression->setType( - TType(baseExpression->getBasicType(), baseExpression->getPrecision(), EvqTemporary)); - } - else - { - indexedExpression->setType(baseExpression->getType()); - } + TIntermBinary *node = new TIntermBinary(EOpIndexIndirect, baseExpression, indexExpression); + node->setLine(location); + // Indirect indexing can never be constant folded. + return node; +} - if (baseExpression->getType().getQualifier() == EvqConst && - indexExpression->getType().getQualifier() == EvqConst) +int TParseContext::checkIndexLessThan(bool outOfRangeIndexIsError, + const TSourceLoc &location, + int index, + int arraySize, + const char *reason) +{ + // Should not reach here with an unsized / runtime-sized array. + ASSERT(arraySize > 0); + if (index >= arraySize) { - indexedExpression->getTypePointer()->setQualifier(EvqConst); + std::stringstream reasonStream; + reasonStream << reason << " '" << index << "'"; + std::string token = reasonStream.str(); + outOfRangeError(outOfRangeIndexIsError, location, reason, "[]"); + return arraySize - 1; } - else - { - indexedExpression->getTypePointer()->setQualifier(EvqTemporary); - } - - return indexedExpression; + return index; } TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpression, @@ -2967,62 +4108,37 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre const TString &fieldString, const TSourceLoc &fieldLocation) { - TIntermTyped *indexedExpression = NULL; - if (baseExpression->isArray()) { error(fieldLocation, "cannot apply dot operator to an array", "."); - recover(); + return baseExpression; } if (baseExpression->isVector()) { - TVectorFields fields; - if (!parseVectorFields(fieldString, baseExpression->getNominalSize(), fields, - fieldLocation)) + TVector fieldOffsets; + if (!parseVectorFields(fieldLocation, fieldString, baseExpression->getNominalSize(), + &fieldOffsets)) { - fields.num = 1; - fields.offsets[0] = 0; - recover(); + fieldOffsets.resize(1); + fieldOffsets[0] = 0; } + TIntermSwizzle *node = new TIntermSwizzle(baseExpression, fieldOffsets); + node->setLine(dotLocation); - if (baseExpression->getAsConstantUnion()) - { - // constant folding for vector fields - indexedExpression = addConstVectorNode(fields, baseExpression->getAsConstantUnion(), - fieldLocation, true); - } - else - { - TIntermTyped *index = intermediate.addSwizzle(fields, fieldLocation); - indexedExpression = - intermediate.addIndex(EOpVectorSwizzle, baseExpression, index, dotLocation); - } - if (indexedExpression == nullptr) - { - recover(); - indexedExpression = baseExpression; - } - else - { - // Note that the qualifier set here will be corrected later. - indexedExpression->setType(TType(baseExpression->getBasicType(), - baseExpression->getPrecision(), EvqTemporary, - (unsigned char)(fieldString).size())); - } + return node->fold(); } else if (baseExpression->getBasicType() == EbtStruct) { - bool fieldFound = false; const TFieldList &fields = baseExpression->getType().getStruct()->fields(); if (fields.empty()) { error(dotLocation, "structure has no fields", "Internal Error"); - recover(); - indexedExpression = baseExpression; + return baseExpression; } else { + bool fieldFound = false; unsigned int i; for (i = 0; i < fields.size(); ++i) { @@ -3034,50 +4150,31 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre } if (fieldFound) { - if (baseExpression->getAsConstantUnion()) - { - indexedExpression = addConstStruct(fieldString, baseExpression, dotLocation); - if (indexedExpression == 0) - { - recover(); - indexedExpression = baseExpression; - } - else - { - indexedExpression->setType(*fields[i]->type()); - } - } - else - { - TConstantUnion *unionArray = new TConstantUnion[1]; - unionArray->setIConst(i); - TIntermTyped *index = intermediate.addConstantUnion( - unionArray, *fields[i]->type(), fieldLocation); - indexedExpression = intermediate.addIndex(EOpIndexDirectStruct, baseExpression, - index, dotLocation); - indexedExpression->setType(*fields[i]->type()); - } + TIntermTyped *index = CreateIndexNode(i); + index->setLine(fieldLocation); + TIntermBinary *node = + new TIntermBinary(EOpIndexDirectStruct, baseExpression, index); + node->setLine(dotLocation); + return node->fold(mDiagnostics); } else { error(dotLocation, " no such field in structure", fieldString.c_str()); - recover(); - indexedExpression = baseExpression; + return baseExpression; } } } else if (baseExpression->isInterfaceBlock()) { - bool fieldFound = false; const TFieldList &fields = baseExpression->getType().getInterfaceBlock()->fields(); if (fields.empty()) { error(dotLocation, "interface block has no fields", "Internal Error"); - recover(); - indexedExpression = baseExpression; + return baseExpression; } else { + bool fieldFound = false; unsigned int i; for (i = 0; i < fields.size(); ++i) { @@ -3089,19 +4186,18 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre } if (fieldFound) { - TConstantUnion *unionArray = new TConstantUnion[1]; - unionArray->setIConst(i); - TIntermTyped *index = - intermediate.addConstantUnion(unionArray, *fields[i]->type(), fieldLocation); - indexedExpression = intermediate.addIndex(EOpIndexDirectInterfaceBlock, - baseExpression, index, dotLocation); - indexedExpression->setType(*fields[i]->type()); + TIntermTyped *index = CreateIndexNode(i); + index->setLine(fieldLocation); + TIntermBinary *node = + new TIntermBinary(EOpIndexDirectInterfaceBlock, baseExpression, index); + node->setLine(dotLocation); + // Indexing interface blocks can never be constant folded. + return node; } else { error(dotLocation, " no such field in interface block", fieldString.c_str()); - recover(); - indexedExpression = baseExpression; + return baseExpression; } } } @@ -3119,39 +4215,36 @@ TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpre "side", fieldString.c_str()); } - recover(); - indexedExpression = baseExpression; + return baseExpression; } - - if (baseExpression->getQualifier() == EvqConst) - { - indexedExpression->getTypePointer()->setQualifier(EvqConst); - } - else - { - indexedExpression->getTypePointer()->setQualifier(EvqTemporary); - } - - return indexedExpression; } TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc &qualifierTypeLine) { - TLayoutQualifier qualifier; - - qualifier.location = -1; - qualifier.matrixPacking = EmpUnspecified; - qualifier.blockStorage = EbsUnspecified; + TLayoutQualifier qualifier = TLayoutQualifier::Create(); if (qualifierType == "shared") { + if (sh::IsWebGLBasedSpec(mShaderSpec)) + { + error(qualifierTypeLine, "Only std140 layout is allowed in WebGL", "shared"); + } qualifier.blockStorage = EbsShared; } else if (qualifierType == "packed") { + if (sh::IsWebGLBasedSpec(mShaderSpec)) + { + error(qualifierTypeLine, "Only std140 layout is allowed in WebGL", "packed"); + } qualifier.blockStorage = EbsPacked; } + else if (qualifierType == "std430") + { + checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); + qualifier.blockStorage = EbsStd430; + } else if (qualifierType == "std140") { qualifier.blockStorage = EbsStd140; @@ -3166,208 +4259,554 @@ TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierTyp } else if (qualifierType == "location") { - error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), - "location requires an argument"); - recover(); + error(qualifierTypeLine, "invalid layout qualifier: location requires an argument", + qualifierType.c_str()); } + else if (qualifierType == "yuv" && mShaderType == GL_FRAGMENT_SHADER) + { + if (checkCanUseExtension(qualifierTypeLine, TExtension::EXT_YUV_target)) + { + qualifier.yuv = true; + } + } + else if (qualifierType == "rgba32f") + { + checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); + qualifier.imageInternalFormat = EiifRGBA32F; + } + else if (qualifierType == "rgba16f") + { + checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); + qualifier.imageInternalFormat = EiifRGBA16F; + } + else if (qualifierType == "r32f") + { + checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); + qualifier.imageInternalFormat = EiifR32F; + } + else if (qualifierType == "rgba8") + { + checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); + qualifier.imageInternalFormat = EiifRGBA8; + } + else if (qualifierType == "rgba8_snorm") + { + checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); + qualifier.imageInternalFormat = EiifRGBA8_SNORM; + } + else if (qualifierType == "rgba32i") + { + checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); + qualifier.imageInternalFormat = EiifRGBA32I; + } + else if (qualifierType == "rgba16i") + { + checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); + qualifier.imageInternalFormat = EiifRGBA16I; + } + else if (qualifierType == "rgba8i") + { + checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); + qualifier.imageInternalFormat = EiifRGBA8I; + } + else if (qualifierType == "r32i") + { + checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); + qualifier.imageInternalFormat = EiifR32I; + } + else if (qualifierType == "rgba32ui") + { + checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); + qualifier.imageInternalFormat = EiifRGBA32UI; + } + else if (qualifierType == "rgba16ui") + { + checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); + qualifier.imageInternalFormat = EiifRGBA16UI; + } + else if (qualifierType == "rgba8ui") + { + checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); + qualifier.imageInternalFormat = EiifRGBA8UI; + } + else if (qualifierType == "r32ui") + { + checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); + qualifier.imageInternalFormat = EiifR32UI; + } + else if (qualifierType == "points" && mShaderType == GL_GEOMETRY_SHADER_OES && + checkCanUseExtension(qualifierTypeLine, TExtension::OES_geometry_shader)) + { + checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); + qualifier.primitiveType = EptPoints; + } + else if (qualifierType == "lines" && mShaderType == GL_GEOMETRY_SHADER_OES && + checkCanUseExtension(qualifierTypeLine, TExtension::OES_geometry_shader)) + { + checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); + qualifier.primitiveType = EptLines; + } + else if (qualifierType == "lines_adjacency" && mShaderType == GL_GEOMETRY_SHADER_OES && + checkCanUseExtension(qualifierTypeLine, TExtension::OES_geometry_shader)) + { + checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); + qualifier.primitiveType = EptLinesAdjacency; + } + else if (qualifierType == "triangles" && mShaderType == GL_GEOMETRY_SHADER_OES && + checkCanUseExtension(qualifierTypeLine, TExtension::OES_geometry_shader)) + { + checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); + qualifier.primitiveType = EptTriangles; + } + else if (qualifierType == "triangles_adjacency" && mShaderType == GL_GEOMETRY_SHADER_OES && + checkCanUseExtension(qualifierTypeLine, TExtension::OES_geometry_shader)) + { + checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); + qualifier.primitiveType = EptTrianglesAdjacency; + } + else if (qualifierType == "line_strip" && mShaderType == GL_GEOMETRY_SHADER_OES && + checkCanUseExtension(qualifierTypeLine, TExtension::OES_geometry_shader)) + { + checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); + qualifier.primitiveType = EptLineStrip; + } + else if (qualifierType == "triangle_strip" && mShaderType == GL_GEOMETRY_SHADER_OES && + checkCanUseExtension(qualifierTypeLine, TExtension::OES_geometry_shader)) + { + checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); + qualifier.primitiveType = EptTriangleStrip; + } + else { error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str()); - recover(); } return qualifier; } +void TParseContext::parseLocalSize(const TString &qualifierType, + const TSourceLoc &qualifierTypeLine, + int intValue, + const TSourceLoc &intValueLine, + const std::string &intValueString, + size_t index, + sh::WorkGroupSize *localSize) +{ + checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); + if (intValue < 1) + { + std::stringstream reasonStream; + reasonStream << "out of range: " << getWorkGroupSizeString(index) << " must be positive"; + std::string reason = reasonStream.str(); + error(intValueLine, reason.c_str(), intValueString.c_str()); + } + (*localSize)[index] = intValue; +} + +void TParseContext::parseNumViews(int intValue, + const TSourceLoc &intValueLine, + const std::string &intValueString, + int *numViews) +{ + // This error is only specified in WebGL, but tightens unspecified behavior in the native + // specification. + if (intValue < 1) + { + error(intValueLine, "out of range: num_views must be positive", intValueString.c_str()); + } + *numViews = intValue; +} + +void TParseContext::parseInvocations(int intValue, + const TSourceLoc &intValueLine, + const std::string &intValueString, + int *numInvocations) +{ + // Although SPEC isn't clear whether invocations can be less than 1, we add this limit because + // it doesn't make sense to accept invocations <= 0. + if (intValue < 1 || intValue > mMaxGeometryShaderInvocations) + { + error(intValueLine, + "out of range: invocations must be in the range of [1, " + "MAX_GEOMETRY_SHADER_INVOCATIONS_OES]", + intValueString.c_str()); + } + else + { + *numInvocations = intValue; + } +} + +void TParseContext::parseMaxVertices(int intValue, + const TSourceLoc &intValueLine, + const std::string &intValueString, + int *maxVertices) +{ + // Although SPEC isn't clear whether max_vertices can be less than 0, we add this limit because + // it doesn't make sense to accept max_vertices < 0. + if (intValue < 0 || intValue > mMaxGeometryShaderMaxVertices) + { + error( + intValueLine, + "out of range: max_vertices must be in the range of [0, gl_MaxGeometryOutputVertices]", + intValueString.c_str()); + } + else + { + *maxVertices = intValue; + } +} + TLayoutQualifier TParseContext::parseLayoutQualifier(const TString &qualifierType, const TSourceLoc &qualifierTypeLine, - const TString &intValueString, int intValue, const TSourceLoc &intValueLine) { - TLayoutQualifier qualifier; + TLayoutQualifier qualifier = TLayoutQualifier::Create(); - qualifier.location = -1; - qualifier.matrixPacking = EmpUnspecified; - qualifier.blockStorage = EbsUnspecified; + std::string intValueString = Str(intValue); - if (qualifierType != "location") - { - error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str(), - "only location may have arguments"); - recover(); - } - else + if (qualifierType == "location") { // must check that location is non-negative if (intValue < 0) { - error(intValueLine, "out of range:", intValueString.c_str(), - "location must be non-negative"); - recover(); + error(intValueLine, "out of range: location must be non-negative", + intValueString.c_str()); } else { - qualifier.location = intValue; + qualifier.location = intValue; + qualifier.locationsSpecified = 1; } } + else if (qualifierType == "binding") + { + checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); + if (intValue < 0) + { + error(intValueLine, "out of range: binding must be non-negative", + intValueString.c_str()); + } + else + { + qualifier.binding = intValue; + } + } + else if (qualifierType == "offset") + { + checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310); + if (intValue < 0) + { + error(intValueLine, "out of range: offset must be non-negative", + intValueString.c_str()); + } + else + { + qualifier.offset = intValue; + } + } + else if (qualifierType == "local_size_x") + { + parseLocalSize(qualifierType, qualifierTypeLine, intValue, intValueLine, intValueString, 0u, + &qualifier.localSize); + } + else if (qualifierType == "local_size_y") + { + parseLocalSize(qualifierType, qualifierTypeLine, intValue, intValueLine, intValueString, 1u, + &qualifier.localSize); + } + else if (qualifierType == "local_size_z") + { + parseLocalSize(qualifierType, qualifierTypeLine, intValue, intValueLine, intValueString, 2u, + &qualifier.localSize); + } + else if (qualifierType == "num_views" && mShaderType == GL_VERTEX_SHADER) + { + if (checkCanUseExtension(qualifierTypeLine, TExtension::OVR_multiview)) + { + parseNumViews(intValue, intValueLine, intValueString, &qualifier.numViews); + } + } + else if (qualifierType == "invocations" && mShaderType == GL_GEOMETRY_SHADER_OES && + checkCanUseExtension(qualifierTypeLine, TExtension::OES_geometry_shader)) + { + parseInvocations(intValue, intValueLine, intValueString, &qualifier.invocations); + } + else if (qualifierType == "max_vertices" && mShaderType == GL_GEOMETRY_SHADER_OES && + checkCanUseExtension(qualifierTypeLine, TExtension::OES_geometry_shader)) + { + parseMaxVertices(intValue, intValueLine, intValueString, &qualifier.maxVertices); + } + + else + { + error(qualifierTypeLine, "invalid layout qualifier", qualifierType.c_str()); + } return qualifier; } -TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualifier, - TLayoutQualifier rightQualifier) +TTypeQualifierBuilder *TParseContext::createTypeQualifierBuilder(const TSourceLoc &loc) { - TLayoutQualifier joinedQualifier = leftQualifier; - - if (rightQualifier.location != -1) - { - joinedQualifier.location = rightQualifier.location; - } - if (rightQualifier.matrixPacking != EmpUnspecified) - { - joinedQualifier.matrixPacking = rightQualifier.matrixPacking; - } - if (rightQualifier.blockStorage != EbsUnspecified) - { - joinedQualifier.blockStorage = rightQualifier.blockStorage; - } - - return joinedQualifier; + return new TTypeQualifierBuilder( + new TStorageQualifierWrapper(symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary, loc), + mShaderVersion); } -TPublicType TParseContext::joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, - TQualifier interpolationQualifier, - const TSourceLoc &storageLoc, - TQualifier storageQualifier) +TStorageQualifierWrapper *TParseContext::parseGlobalStorageQualifier(TQualifier qualifier, + const TSourceLoc &loc) { - TQualifier mergedQualifier = EvqSmoothIn; + checkIsAtGlobalLevel(loc, getQualifierString(qualifier)); + return new TStorageQualifierWrapper(qualifier, loc); +} - if (storageQualifier == EvqFragmentIn) +TStorageQualifierWrapper *TParseContext::parseVaryingQualifier(const TSourceLoc &loc) +{ + if (getShaderType() == GL_VERTEX_SHADER) { - if (interpolationQualifier == EvqSmooth) - mergedQualifier = EvqSmoothIn; - else if (interpolationQualifier == EvqFlat) - mergedQualifier = EvqFlatIn; - else - UNREACHABLE(); + return parseGlobalStorageQualifier(EvqVaryingOut, loc); } - else if (storageQualifier == EvqCentroidIn) - { - if (interpolationQualifier == EvqSmooth) - mergedQualifier = EvqCentroidIn; - else if (interpolationQualifier == EvqFlat) - mergedQualifier = EvqFlatIn; - else - UNREACHABLE(); - } - else if (storageQualifier == EvqVertexOut) - { - if (interpolationQualifier == EvqSmooth) - mergedQualifier = EvqSmoothOut; - else if (interpolationQualifier == EvqFlat) - mergedQualifier = EvqFlatOut; - else - UNREACHABLE(); - } - else if (storageQualifier == EvqCentroidOut) - { - if (interpolationQualifier == EvqSmooth) - mergedQualifier = EvqCentroidOut; - else if (interpolationQualifier == EvqFlat) - mergedQualifier = EvqFlatOut; - else - UNREACHABLE(); - } - else - { - error(interpolationLoc, - "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", - getInterpolationString(interpolationQualifier)); - recover(); + return parseGlobalStorageQualifier(EvqVaryingIn, loc); +} - mergedQualifier = storageQualifier; +TStorageQualifierWrapper *TParseContext::parseInQualifier(const TSourceLoc &loc) +{ + if (declaringFunction()) + { + return new TStorageQualifierWrapper(EvqIn, loc); } - TPublicType type; - type.setBasic(EbtVoid, mergedQualifier, storageLoc); - return type; + switch (getShaderType()) + { + case GL_VERTEX_SHADER: + { + if (mShaderVersion < 300 && !isExtensionEnabled(TExtension::OVR_multiview)) + { + error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "in"); + } + return new TStorageQualifierWrapper(EvqVertexIn, loc); + } + case GL_FRAGMENT_SHADER: + { + if (mShaderVersion < 300) + { + error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "in"); + } + return new TStorageQualifierWrapper(EvqFragmentIn, loc); + } + case GL_COMPUTE_SHADER: + { + return new TStorageQualifierWrapper(EvqComputeIn, loc); + } + case GL_GEOMETRY_SHADER_OES: + { + return new TStorageQualifierWrapper(EvqGeometryIn, loc); + } + default: + { + UNREACHABLE(); + return new TStorageQualifierWrapper(EvqLast, loc); + } + } +} + +TStorageQualifierWrapper *TParseContext::parseOutQualifier(const TSourceLoc &loc) +{ + if (declaringFunction()) + { + return new TStorageQualifierWrapper(EvqOut, loc); + } + switch (getShaderType()) + { + case GL_VERTEX_SHADER: + { + if (mShaderVersion < 300) + { + error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "out"); + } + return new TStorageQualifierWrapper(EvqVertexOut, loc); + } + case GL_FRAGMENT_SHADER: + { + if (mShaderVersion < 300) + { + error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "out"); + } + return new TStorageQualifierWrapper(EvqFragmentOut, loc); + } + case GL_COMPUTE_SHADER: + { + error(loc, "storage qualifier isn't supported in compute shaders", "out"); + return new TStorageQualifierWrapper(EvqLast, loc); + } + case GL_GEOMETRY_SHADER_OES: + { + return new TStorageQualifierWrapper(EvqGeometryOut, loc); + } + default: + { + UNREACHABLE(); + return new TStorageQualifierWrapper(EvqLast, loc); + } + } +} + +TStorageQualifierWrapper *TParseContext::parseInOutQualifier(const TSourceLoc &loc) +{ + if (!declaringFunction()) + { + error(loc, "invalid qualifier: can be only used with function parameters", "inout"); + } + return new TStorageQualifierWrapper(EvqInOut, loc); +} + +TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualifier, + TLayoutQualifier rightQualifier, + const TSourceLoc &rightQualifierLocation) +{ + return sh::JoinLayoutQualifiers(leftQualifier, rightQualifier, rightQualifierLocation, + mDiagnostics); +} + +TField *TParseContext::parseStructDeclarator(TString *identifier, const TSourceLoc &loc) +{ + checkIsNotReserved(loc, *identifier); + TType *type = new TType(EbtVoid, EbpUndefined); + return new TField(type, identifier, loc); +} + +TField *TParseContext::parseStructArrayDeclarator(TString *identifier, + const TSourceLoc &loc, + const TVector &arraySizes, + const TSourceLoc &arraySizeLoc) +{ + checkIsNotReserved(loc, *identifier); + + TType *type = new TType(EbtVoid, EbpUndefined); + type->makeArrays(arraySizes); + + return new TField(type, identifier, loc); +} + +void TParseContext::checkDoesNotHaveDuplicateFieldName(const TFieldList::const_iterator begin, + const TFieldList::const_iterator end, + const TString &name, + const TSourceLoc &location) +{ + for (auto fieldIter = begin; fieldIter != end; ++fieldIter) + { + if ((*fieldIter)->name() == name) + { + error(location, "duplicate field name in structure", name.c_str()); + } + } +} + +TFieldList *TParseContext::addStructFieldList(TFieldList *fields, const TSourceLoc &location) +{ + for (TFieldList::const_iterator fieldIter = fields->begin(); fieldIter != fields->end(); + ++fieldIter) + { + checkDoesNotHaveDuplicateFieldName(fields->begin(), fieldIter, (*fieldIter)->name(), + location); + } + return fields; +} + +TFieldList *TParseContext::combineStructFieldLists(TFieldList *processedFields, + const TFieldList *newlyAddedFields, + const TSourceLoc &location) +{ + for (TField *field : *newlyAddedFields) + { + checkDoesNotHaveDuplicateFieldName(processedFields->begin(), processedFields->end(), + field->name(), location); + processedFields->push_back(field); + } + return processedFields; +} + +TFieldList *TParseContext::addStructDeclaratorListWithQualifiers( + const TTypeQualifierBuilder &typeQualifierBuilder, + TPublicType *typeSpecifier, + TFieldList *fieldList) +{ + TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics); + + typeSpecifier->qualifier = typeQualifier.qualifier; + typeSpecifier->layoutQualifier = typeQualifier.layoutQualifier; + typeSpecifier->memoryQualifier = typeQualifier.memoryQualifier; + typeSpecifier->invariant = typeQualifier.invariant; + if (typeQualifier.precision != EbpUndefined) + { + typeSpecifier->precision = typeQualifier.precision; + } + return addStructDeclaratorList(*typeSpecifier, fieldList); } TFieldList *TParseContext::addStructDeclaratorList(const TPublicType &typeSpecifier, - TFieldList *fieldList) + TFieldList *declaratorList) { - if (voidErrorCheck(typeSpecifier.line, (*fieldList)[0]->name(), typeSpecifier.type)) + checkPrecisionSpecified(typeSpecifier.getLine(), typeSpecifier.precision, + typeSpecifier.getBasicType()); + + checkIsNonVoid(typeSpecifier.getLine(), (*declaratorList)[0]->name(), + typeSpecifier.getBasicType()); + + checkWorkGroupSizeIsNotSpecified(typeSpecifier.getLine(), typeSpecifier.layoutQualifier); + + for (TField *declarator : *declaratorList) { - recover(); + // Don't allow arrays of arrays in ESSL < 3.10. + if (declarator->type()->isArray()) + { + checkArrayElementIsNotArray(typeSpecifier.getLine(), typeSpecifier); + } + + auto *declaratorArraySizes = declarator->type()->getArraySizes(); + + TType *type = declarator->type(); + *type = TType(typeSpecifier); + if (declaratorArraySizes != nullptr) + { + for (unsigned int arraySize : *declaratorArraySizes) + { + type->makeArray(arraySize); + } + } + + checkIsBelowStructNestingLimit(typeSpecifier.getLine(), *declarator); } - for (unsigned int i = 0; i < fieldList->size(); ++i) - { - // - // Careful not to replace already known aspects of type, like array-ness - // - TType *type = (*fieldList)[i]->type(); - type->setBasicType(typeSpecifier.type); - type->setPrimarySize(typeSpecifier.primarySize); - type->setSecondarySize(typeSpecifier.secondarySize); - type->setPrecision(typeSpecifier.precision); - type->setQualifier(typeSpecifier.qualifier); - type->setLayoutQualifier(typeSpecifier.layoutQualifier); - - // don't allow arrays of arrays - if (type->isArray()) - { - if (arrayTypeErrorCheck(typeSpecifier.line, typeSpecifier)) - recover(); - } - if (typeSpecifier.array) - type->setArraySize(typeSpecifier.arraySize); - if (typeSpecifier.userDef) - { - type->setStruct(typeSpecifier.userDef->getStruct()); - } - - if (structNestingErrorCheck(typeSpecifier.line, *(*fieldList)[i])) - { - recover(); - } - } - - return fieldList; + return declaratorList; } -TPublicType TParseContext::addStructure(const TSourceLoc &structLine, - const TSourceLoc &nameLine, - const TString *structName, - TFieldList *fieldList) +TTypeSpecifierNonArray TParseContext::addStructure(const TSourceLoc &structLine, + const TSourceLoc &nameLine, + const TString *structName, + TFieldList *fieldList) { - TStructure *structure = new TStructure(structName, fieldList); - TType *structureType = new TType(structure); + TStructure *structure = new TStructure(&symbolTable, structName, fieldList); // Store a bool in the struct if we're at global scope, to allow us to // skip the local struct scoping workaround in HLSL. - structure->setUniqueId(TSymbolTable::nextUniqueId()); structure->setAtGlobalScope(symbolTable.atGlobalLevel()); if (!structName->empty()) { - if (reservedErrorCheck(nameLine, *structName)) + checkIsNotReserved(nameLine, *structName); + if (!symbolTable.declareStructType(structure)) { - recover(); - } - TVariable *userTypeDef = new TVariable(structName, *structureType, true); - if (!symbolTable.declare(userTypeDef)) - { - error(nameLine, "redefinition", structName->c_str(), "struct"); - recover(); + error(nameLine, "redefinition of a struct", structName->c_str()); } } // ensure we do not specify any storage qualifiers on the struct members for (unsigned int typeListIndex = 0; typeListIndex < fieldList->size(); typeListIndex++) { - const TField &field = *(*fieldList)[typeListIndex]; + TField &field = *(*fieldList)[typeListIndex]; const TQualifier qualifier = field.type()->getQualifier(); switch (qualifier) { @@ -3377,22 +4816,37 @@ TPublicType TParseContext::addStructure(const TSourceLoc &structLine, default: error(field.line(), "invalid qualifier on struct member", getQualifierString(qualifier)); - recover(); break; } + if (field.type()->isInvariant()) + { + error(field.line(), "invalid qualifier on struct member", "invariant"); + } + // ESSL 3.10 section 4.1.8 -- atomic_uint or images are not allowed as structure member. + if (IsImage(field.type()->getBasicType()) || IsAtomicCounter(field.type()->getBasicType())) + { + error(field.line(), "disallowed type in struct", field.type()->getBasicString()); + } + + checkIsNotUnsizedArray(field.line(), "array members of structs must specify a size", + field.name().c_str(), field.type()); + + checkMemoryQualifierIsNotSpecified(field.type()->getMemoryQualifier(), field.line()); + + checkBindingIsNotSpecified(field.line(), field.type()->getLayoutQualifier().binding); + + checkLocationIsNotSpecified(field.line(), field.type()->getLayoutQualifier()); } - TPublicType publicType; - publicType.setBasic(EbtStruct, EvqTemporary, structLine); - publicType.userDef = structureType; - publicType.isStructSpecifier = true; + TTypeSpecifierNonArray typeSpecifierNonArray; + typeSpecifierNonArray.initializeStruct(structure, true, structLine); exitStructDeclaration(); - return publicType; + return typeSpecifierNonArray; } TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init, - TIntermAggregate *statementList, + TIntermBlock *statementList, const TSourceLoc &loc) { TBasicType switchType = init->getBasicType(); @@ -3401,26 +4855,18 @@ TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init, { error(init->getLine(), "init-expression in a switch statement must be a scalar integer", "switch"); - recover(); return nullptr; } - if (statementList) + ASSERT(statementList); + if (!ValidateSwitchStatementList(switchType, mShaderVersion, mDiagnostics, statementList, loc)) { - if (!ValidateSwitch::validate(switchType, this, statementList, loc)) - { - recover(); - return nullptr; - } - } - - TIntermSwitch *node = intermediate.addSwitch(init, statementList, loc); - if (node == nullptr) - { - error(loc, "erroneous switch statement", "switch"); - recover(); + ASSERT(mDiagnostics->numErrors() > 0); return nullptr; } + + TIntermSwitch *node = new TIntermSwitch(init, statementList); + node->setLine(loc); return node; } @@ -3429,20 +4875,17 @@ TIntermCase *TParseContext::addCase(TIntermTyped *condition, const TSourceLoc &l if (mSwitchNestingLevel == 0) { error(loc, "case labels need to be inside switch statements", "case"); - recover(); return nullptr; } if (condition == nullptr) { error(loc, "case label must have a condition", "case"); - recover(); return nullptr; } if ((condition->getBasicType() != EbtInt && condition->getBasicType() != EbtUInt) || condition->isMatrix() || condition->isArray() || condition->isVector()) { error(condition->getLine(), "case label must be a scalar integer", "case"); - recover(); } TIntermConstantUnion *conditionConst = condition->getAsConstantUnion(); // TODO(oetuaho@nvidia.com): Get rid of the conditionConst == nullptr check once all constant @@ -3451,15 +4894,9 @@ TIntermCase *TParseContext::addCase(TIntermTyped *condition, const TSourceLoc &l if (condition->getQualifier() != EvqConst || conditionConst == nullptr) { error(condition->getLine(), "case label must be constant", "case"); - recover(); - } - TIntermCase *node = intermediate.addCase(condition, loc); - if (node == nullptr) - { - error(loc, "erroneous case statement", "case"); - recover(); - return nullptr; } + TIntermCase *node = new TIntermCase(condition); + node->setLine(loc); return node; } @@ -3468,28 +4905,18 @@ TIntermCase *TParseContext::addDefault(const TSourceLoc &loc) if (mSwitchNestingLevel == 0) { error(loc, "default labels need to be inside switch statements", "default"); - recover(); - return nullptr; - } - TIntermCase *node = intermediate.addCase(nullptr, loc); - if (node == nullptr) - { - error(loc, "erroneous default statement", "default"); - recover(); return nullptr; } + TIntermCase *node = new TIntermCase(nullptr); + node->setLine(loc); return node; } TIntermTyped *TParseContext::createUnaryMath(TOperator op, TIntermTyped *child, - const TSourceLoc &loc, - const TType *funcReturnType) + const TSourceLoc &loc) { - if (child == nullptr) - { - return nullptr; - } + ASSERT(child != nullptr); switch (op) { @@ -3497,6 +4924,7 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op, if (child->getBasicType() != EbtBool || child->isMatrix() || child->isArray() || child->isVector()) { + unaryOpError(loc, GetOperatorString(op), child->getCompleteString()); return nullptr; } break; @@ -3504,6 +4932,7 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op, if ((child->getBasicType() != EbtInt && child->getBasicType() != EbtUInt) || child->isMatrix() || child->isArray()) { + unaryOpError(loc, GetOperatorString(op), child->getCompleteString()); return nullptr; } break; @@ -3513,9 +4942,11 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op, case EOpPreDecrement: case EOpNegative: case EOpPositive: - if (child->getBasicType() == EbtStruct || child->getBasicType() == EbtBool || - child->isArray()) + if (child->getBasicType() == EbtStruct || child->isInterfaceBlock() || + child->getBasicType() == EbtBool || child->isArray() || + IsOpaqueType(child->getBasicType())) { + unaryOpError(loc, GetOperatorString(op), child->getCompleteString()); return nullptr; } // Operators for built-ins are already type checked against their prototype. @@ -3523,16 +4954,24 @@ TIntermTyped *TParseContext::createUnaryMath(TOperator op, break; } - return intermediate.addUnaryMath(op, child, loc, funcReturnType); + if (child->getMemoryQualifier().writeonly) + { + unaryOpError(loc, GetOperatorString(op), child->getCompleteString()); + return nullptr; + } + + TIntermUnary *node = new TIntermUnary(op, child); + node->setLine(loc); + + return node->fold(mDiagnostics); } TIntermTyped *TParseContext::addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc) { - TIntermTyped *node = createUnaryMath(op, child, loc, nullptr); + ASSERT(op != EOpNull); + TIntermTyped *node = createUnaryMath(op, child, loc); if (node == nullptr) { - unaryOpError(loc, GetOperatorString(op), child->getCompleteString()); - recover(); return child; } return node; @@ -3542,8 +4981,7 @@ TIntermTyped *TParseContext::addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc) { - if (lValueErrorCheck(loc, GetOperatorString(op), child)) - recover(); + checkCanBeLValue(loc, GetOperatorString(op), child); return addUnaryMath(op, child, loc); } @@ -3552,20 +4990,98 @@ bool TParseContext::binaryOpCommonCheck(TOperator op, TIntermTyped *right, const TSourceLoc &loc) { - if (left->isArray() || right->isArray()) + // Check opaque types are not allowed to be operands in expressions other than array indexing + // and structure member selection. + if (IsOpaqueType(left->getBasicType()) || IsOpaqueType(right->getBasicType())) { + switch (op) + { + case EOpIndexDirect: + case EOpIndexIndirect: + break; + case EOpIndexDirectStruct: + UNREACHABLE(); + + default: + error(loc, "Invalid operation for variables with an opaque type", + GetOperatorString(op)); + return false; + } + } + + if (right->getMemoryQualifier().writeonly) + { + error(loc, "Invalid operation for variables with writeonly", GetOperatorString(op)); + return false; + } + + if (left->getMemoryQualifier().writeonly) + { + switch (op) + { + case EOpAssign: + case EOpInitialize: + case EOpIndexDirect: + case EOpIndexIndirect: + case EOpIndexDirectStruct: + case EOpIndexDirectInterfaceBlock: + break; + default: + error(loc, "Invalid operation for variables with writeonly", GetOperatorString(op)); + return false; + } + } + + if (left->getType().getStruct() || right->getType().getStruct()) + { + switch (op) + { + case EOpIndexDirectStruct: + ASSERT(left->getType().getStruct()); + break; + case EOpEqual: + case EOpNotEqual: + case EOpAssign: + case EOpInitialize: + if (left->getType() != right->getType()) + { + return false; + } + break; + default: + error(loc, "Invalid operation for structs", GetOperatorString(op)); + return false; + } + } + + if (left->isInterfaceBlock() || right->isInterfaceBlock()) + { + switch (op) + { + case EOpIndexDirectInterfaceBlock: + ASSERT(left->getType().getInterfaceBlock()); + break; + default: + error(loc, "Invalid operation for interface blocks", GetOperatorString(op)); + return false; + } + } + + if (left->isArray() != right->isArray()) + { + error(loc, "array / non-array mismatch", GetOperatorString(op)); + return false; + } + + if (left->isArray()) + { + ASSERT(right->isArray()); if (mShaderVersion < 300) { error(loc, "Invalid operation for arrays", GetOperatorString(op)); return false; } - if (left->isArray() != right->isArray()) - { - error(loc, "array / non-array mismatch", GetOperatorString(op)); - return false; - } - switch (op) { case EOpEqual: @@ -3578,7 +5094,7 @@ bool TParseContext::binaryOpCommonCheck(TOperator op, return false; } // At this point, size of implicitly sized arrays should be resolved. - if (left->getArraySize() != right->getArraySize()) + if (*left->getType().getArraySizes() != *right->getType().getArraySizes()) { error(loc, "array size mismatch", GetOperatorString(op)); return false; @@ -3625,8 +5141,10 @@ bool TParseContext::binaryOpCommonCheck(TOperator op, return false; } - // Check that type sizes match exactly on ops that require that. - // Also check restrictions for structs that contain arrays or samplers. + // Check that: + // 1. Type sizes match exactly on ops that require that. + // 2. Restrictions for structs that contain arrays or samplers are respected. + // 3. Arithmetic op type dimensionality restrictions for ops other than multiply are respected. switch (op) { case EOpAssign: @@ -3650,15 +5168,65 @@ bool TParseContext::binaryOpCommonCheck(TOperator op, GetOperatorString(op)); return false; } + + if ((left->getNominalSize() != right->getNominalSize()) || + (left->getSecondarySize() != right->getSecondarySize())) + { + error(loc, "dimension mismatch", GetOperatorString(op)); + return false; + } + break; case EOpLessThan: case EOpGreaterThan: case EOpLessThanEqual: case EOpGreaterThanEqual: - if ((left->getNominalSize() != right->getNominalSize()) || - (left->getSecondarySize() != right->getSecondarySize())) + if (!left->isScalar() || !right->isScalar()) + { + error(loc, "comparison operator only defined for scalars", GetOperatorString(op)); + return false; + } + break; + case EOpAdd: + case EOpSub: + case EOpDiv: + case EOpIMod: + case EOpBitShiftLeft: + case EOpBitShiftRight: + case EOpBitwiseAnd: + case EOpBitwiseXor: + case EOpBitwiseOr: + case EOpAddAssign: + case EOpSubAssign: + case EOpDivAssign: + case EOpIModAssign: + case EOpBitShiftLeftAssign: + case EOpBitShiftRightAssign: + case EOpBitwiseAndAssign: + case EOpBitwiseXorAssign: + case EOpBitwiseOrAssign: + if ((left->isMatrix() && right->isVector()) || (left->isVector() && right->isMatrix())) { return false; } + + // Are the sizes compatible? + if (left->getNominalSize() != right->getNominalSize() || + left->getSecondarySize() != right->getSecondarySize()) + { + // If the nominal sizes of operands do not match: + // One of them must be a scalar. + if (!left->isScalar() && !right->isScalar()) + return false; + + // In the case of compound assignment other than multiply-assign, + // the right side needs to be a scalar. Otherwise a vector/matrix + // would be assigned to a scalar. A scalar can't be shifted by a + // vector either. + if (!right->isScalar() && + (IsAssignment(op) || op == EOpBitShiftLeft || op == EOpBitShiftRight)) + return false; + } + break; default: break; } @@ -3666,6 +5234,49 @@ bool TParseContext::binaryOpCommonCheck(TOperator op, return true; } +bool TParseContext::isMultiplicationTypeCombinationValid(TOperator op, + const TType &left, + const TType &right) +{ + switch (op) + { + case EOpMul: + case EOpMulAssign: + return left.getNominalSize() == right.getNominalSize() && + left.getSecondarySize() == right.getSecondarySize(); + case EOpVectorTimesScalar: + return true; + case EOpVectorTimesScalarAssign: + ASSERT(!left.isMatrix() && !right.isMatrix()); + return left.isVector() && !right.isVector(); + case EOpVectorTimesMatrix: + return left.getNominalSize() == right.getRows(); + case EOpVectorTimesMatrixAssign: + ASSERT(!left.isMatrix() && right.isMatrix()); + return left.isVector() && left.getNominalSize() == right.getRows() && + left.getNominalSize() == right.getCols(); + case EOpMatrixTimesVector: + return left.getCols() == right.getNominalSize(); + case EOpMatrixTimesScalar: + return true; + case EOpMatrixTimesScalarAssign: + ASSERT(left.isMatrix() && !right.isMatrix()); + return !right.isVector(); + case EOpMatrixTimesMatrix: + return left.getCols() == right.getRows(); + case EOpMatrixTimesMatrixAssign: + ASSERT(left.isMatrix() && right.isMatrix()); + // We need to check two things: + // 1. The matrix multiplication step is valid. + // 2. The result will have the same number of columns as the lvalue. + return left.getCols() == right.getRows() && left.getCols() == right.getCols(); + + default: + UNREACHABLE(); + return false; + } +} + TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op, TIntermTyped *left, TIntermTyped *right, @@ -3678,52 +5289,61 @@ TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op, { case EOpEqual: case EOpNotEqual: - break; case EOpLessThan: case EOpGreaterThan: case EOpLessThanEqual: case EOpGreaterThanEqual: - ASSERT(!left->isArray() && !right->isArray()); - if (left->isMatrix() || left->isVector() || left->getBasicType() == EbtStruct) - { - return nullptr; - } break; case EOpLogicalOr: case EOpLogicalXor: case EOpLogicalAnd: - ASSERT(!left->isArray() && !right->isArray()); - if (left->getBasicType() != EbtBool || left->isMatrix() || left->isVector()) + ASSERT(!left->isArray() && !right->isArray() && !left->getType().getStruct() && + !right->getType().getStruct()); + if (left->getBasicType() != EbtBool || !left->isScalar() || !right->isScalar()) { return nullptr; } + // Basic types matching should have been already checked. + ASSERT(right->getBasicType() == EbtBool); break; case EOpAdd: case EOpSub: case EOpDiv: case EOpMul: - ASSERT(!left->isArray() && !right->isArray()); - if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool) + ASSERT(!left->isArray() && !right->isArray() && !left->getType().getStruct() && + !right->getType().getStruct()); + if (left->getBasicType() == EbtBool) { return nullptr; } break; case EOpIMod: - ASSERT(!left->isArray() && !right->isArray()); + ASSERT(!left->isArray() && !right->isArray() && !left->getType().getStruct() && + !right->getType().getStruct()); // Note that this is only for the % operator, not for mod() - if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool || - left->getBasicType() == EbtFloat) + if (left->getBasicType() == EbtBool || left->getBasicType() == EbtFloat) { return nullptr; } break; - // Note that for bitwise ops, type checking is done in promote() to - // share code between ops and compound assignment default: break; } - return intermediate.addBinaryMath(op, left, right, loc); + if (op == EOpMul) + { + op = TIntermBinary::GetMulOpBasedOnOperands(left->getType(), right->getType()); + if (!isMultiplicationTypeCombinationValid(op, left->getType(), right->getType())) + { + return nullptr; + } + } + + TIntermBinary *node = new TIntermBinary(op, left, right); + node->setLine(loc); + + // See if we can fold constants. + return node->fold(mDiagnostics); } TIntermTyped *TParseContext::addBinaryMath(TOperator op, @@ -3736,7 +5356,6 @@ TIntermTyped *TParseContext::addBinaryMath(TOperator op, { binaryOpError(loc, GetOperatorString(op), left->getCompleteString(), right->getCompleteString()); - recover(); return left; } return node; @@ -3748,27 +5367,35 @@ TIntermTyped *TParseContext::addBinaryMathBooleanResult(TOperator op, const TSourceLoc &loc) { TIntermTyped *node = addBinaryMathInternal(op, left, right, loc); - if (node == 0) + if (node == nullptr) { binaryOpError(loc, GetOperatorString(op), left->getCompleteString(), right->getCompleteString()); - recover(); - TConstantUnion *unionArray = new TConstantUnion[1]; - unionArray->setBConst(false); - return intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), - loc); + node = CreateBoolNode(false); + node->setLine(loc); } return node; } -TIntermTyped *TParseContext::createAssign(TOperator op, - TIntermTyped *left, - TIntermTyped *right, - const TSourceLoc &loc) +TIntermBinary *TParseContext::createAssign(TOperator op, + TIntermTyped *left, + TIntermTyped *right, + const TSourceLoc &loc) { if (binaryOpCommonCheck(op, left, right, loc)) { - return intermediate.addAssign(op, left, right, loc); + if (op == EOpMulAssign) + { + op = TIntermBinary::GetMulAssignOpBasedOnOperands(left->getType(), right->getType()); + if (!isMultiplicationTypeCombinationValid(op, left->getType(), right->getType())) + { + return nullptr; + } + } + TIntermBinary *node = new TIntermBinary(op, left, right); + node->setLine(loc); + + return node; } return nullptr; } @@ -3778,11 +5405,11 @@ TIntermTyped *TParseContext::addAssign(TOperator op, TIntermTyped *right, const TSourceLoc &loc) { + checkCanBeLValue(loc, "assign", left); TIntermTyped *node = createAssign(op, left, right, loc); if (node == nullptr) { assignError(loc, "assign", left->getCompleteString(), right->getCompleteString()); - recover(); return left; } return node; @@ -3792,7 +5419,22 @@ TIntermTyped *TParseContext::addComma(TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc) { - return intermediate.addComma(left, right, loc, mShaderVersion); + // WebGL2 section 5.26, the following results in an error: + // "Sequence operator applied to void, arrays, or structs containing arrays" + if (mShaderSpec == SH_WEBGL2_SPEC && + (left->isArray() || left->getBasicType() == EbtVoid || + left->getType().isStructureContainingArrays() || right->isArray() || + right->getBasicType() == EbtVoid || right->getType().isStructureContainingArrays())) + { + error(loc, + "sequence operator is not allowed for void, arrays, or structs containing arrays", + ","); + } + + TIntermBinary *commaNode = new TIntermBinary(EOpComma, left, right); + TQualifier resultQualifier = TIntermBinary::GetCommaQualifier(mShaderVersion, left, right); + commaNode->getTypePointer()->setQualifier(resultQualifier); + return commaNode->fold(mDiagnostics); } TIntermBranch *TParseContext::addBranch(TOperator op, const TSourceLoc &loc) @@ -3803,319 +5445,553 @@ TIntermBranch *TParseContext::addBranch(TOperator op, const TSourceLoc &loc) if (mLoopNestingLevel <= 0) { error(loc, "continue statement only allowed in loops", ""); - recover(); } break; case EOpBreak: if (mLoopNestingLevel <= 0 && mSwitchNestingLevel <= 0) { error(loc, "break statement only allowed in loops and switch statements", ""); - recover(); } break; case EOpReturn: if (mCurrentFunctionType->getBasicType() != EbtVoid) { error(loc, "non-void function must return a value", "return"); - recover(); + } + break; + case EOpKill: + if (mShaderType != GL_FRAGMENT_SHADER) + { + error(loc, "discard supported in fragment shaders only", "discard"); } break; default: - // No checks for discard + UNREACHABLE(); break; } - return intermediate.addBranch(op, loc); + return addBranch(op, nullptr, loc); } TIntermBranch *TParseContext::addBranch(TOperator op, - TIntermTyped *returnValue, + TIntermTyped *expression, const TSourceLoc &loc) { - ASSERT(op == EOpReturn); - mFunctionReturnsValue = true; - if (mCurrentFunctionType->getBasicType() == EbtVoid) + if (expression != nullptr) { - error(loc, "void function cannot return a value", "return"); - recover(); + ASSERT(op == EOpReturn); + mFunctionReturnsValue = true; + if (mCurrentFunctionType->getBasicType() == EbtVoid) + { + error(loc, "void function cannot return a value", "return"); + } + else if (*mCurrentFunctionType != expression->getType()) + { + error(loc, "function return is not matching type:", "return"); + } } - else if (*mCurrentFunctionType != returnValue->getType()) + TIntermBranch *node = new TIntermBranch(op, expression); + node->setLine(loc); + return node; +} + +void TParseContext::checkTextureGather(TIntermAggregate *functionCall) +{ + ASSERT(functionCall->getOp() == EOpCallBuiltInFunction); + const TString &name = functionCall->getFunctionSymbolInfo()->getName(); + bool isTextureGather = (name == "textureGather"); + bool isTextureGatherOffset = (name == "textureGatherOffset"); + if (isTextureGather || isTextureGatherOffset) { - error(loc, "function return is not matching type:", "return"); - recover(); + TIntermNode *componentNode = nullptr; + TIntermSequence *arguments = functionCall->getSequence(); + ASSERT(arguments->size() >= 2u && arguments->size() <= 4u); + const TIntermTyped *sampler = arguments->front()->getAsTyped(); + ASSERT(sampler != nullptr); + switch (sampler->getBasicType()) + { + case EbtSampler2D: + case EbtISampler2D: + case EbtUSampler2D: + case EbtSampler2DArray: + case EbtISampler2DArray: + case EbtUSampler2DArray: + if ((isTextureGather && arguments->size() == 3u) || + (isTextureGatherOffset && arguments->size() == 4u)) + { + componentNode = arguments->back(); + } + break; + case EbtSamplerCube: + case EbtISamplerCube: + case EbtUSamplerCube: + ASSERT(!isTextureGatherOffset); + if (arguments->size() == 3u) + { + componentNode = arguments->back(); + } + break; + case EbtSampler2DShadow: + case EbtSampler2DArrayShadow: + case EbtSamplerCubeShadow: + break; + default: + UNREACHABLE(); + break; + } + if (componentNode) + { + const TIntermConstantUnion *componentConstantUnion = + componentNode->getAsConstantUnion(); + if (componentNode->getAsTyped()->getQualifier() != EvqConst || !componentConstantUnion) + { + error(functionCall->getLine(), "Texture component must be a constant expression", + name.c_str()); + } + else + { + int component = componentConstantUnion->getIConst(0); + if (component < 0 || component > 3) + { + error(functionCall->getLine(), "Component must be in the range [0;3]", + name.c_str()); + } + } + } } - return intermediate.addBranch(op, returnValue, loc); } void TParseContext::checkTextureOffsetConst(TIntermAggregate *functionCall) { - ASSERT(!functionCall->isUserDefined()); - const TString &name = functionCall->getName(); + ASSERT(functionCall->getOp() == EOpCallBuiltInFunction); + const TString &name = functionCall->getFunctionSymbolInfo()->getName(); TIntermNode *offset = nullptr; TIntermSequence *arguments = functionCall->getSequence(); - if (name.compare(0, 16, "texelFetchOffset") == 0 || - name.compare(0, 16, "textureLodOffset") == 0 || - name.compare(0, 20, "textureProjLodOffset") == 0 || - name.compare(0, 17, "textureGradOffset") == 0 || - name.compare(0, 21, "textureProjGradOffset") == 0) + bool useTextureGatherOffsetConstraints = false; + if (name == "texelFetchOffset" || name == "textureLodOffset" || + name == "textureProjLodOffset" || name == "textureGradOffset" || + name == "textureProjGradOffset") { offset = arguments->back(); } - else if (name.compare(0, 13, "textureOffset") == 0 || - name.compare(0, 17, "textureProjOffset") == 0) + else if (name == "textureOffset" || name == "textureProjOffset") { // A bias parameter might follow the offset parameter. ASSERT(arguments->size() >= 3); offset = (*arguments)[2]; } + else if (name == "textureGatherOffset") + { + ASSERT(arguments->size() >= 3u); + const TIntermTyped *sampler = arguments->front()->getAsTyped(); + ASSERT(sampler != nullptr); + switch (sampler->getBasicType()) + { + case EbtSampler2D: + case EbtISampler2D: + case EbtUSampler2D: + case EbtSampler2DArray: + case EbtISampler2DArray: + case EbtUSampler2DArray: + offset = (*arguments)[2]; + break; + case EbtSampler2DShadow: + case EbtSampler2DArrayShadow: + offset = (*arguments)[3]; + break; + default: + UNREACHABLE(); + break; + } + useTextureGatherOffsetConstraints = true; + } if (offset != nullptr) { TIntermConstantUnion *offsetConstantUnion = offset->getAsConstantUnion(); if (offset->getAsTyped()->getQualifier() != EvqConst || !offsetConstantUnion) { - TString unmangledName = TFunction::unmangleName(name); error(functionCall->getLine(), "Texture offset must be a constant expression", - unmangledName.c_str()); - recover(); + name.c_str()); } else { ASSERT(offsetConstantUnion->getBasicType() == EbtInt); size_t size = offsetConstantUnion->getType().getObjectSize(); const TConstantUnion *values = offsetConstantUnion->getUnionArrayPointer(); + int minOffsetValue = useTextureGatherOffsetConstraints ? mMinProgramTextureGatherOffset + : mMinProgramTexelOffset; + int maxOffsetValue = useTextureGatherOffsetConstraints ? mMaxProgramTextureGatherOffset + : mMaxProgramTexelOffset; for (size_t i = 0u; i < size; ++i) { int offsetValue = values[i].getIConst(); - if (offsetValue > mMaxProgramTexelOffset || offsetValue < mMinProgramTexelOffset) + if (offsetValue > maxOffsetValue || offsetValue < minOffsetValue) { std::stringstream tokenStream; tokenStream << offsetValue; std::string token = tokenStream.str(); error(offset->getLine(), "Texture offset value out of valid range", token.c_str()); - recover(); } } } } } -TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, - TIntermNode *paramNode, - TIntermNode *thisNode, - const TSourceLoc &loc, - bool *fatalError) +void TParseContext::checkAtomicMemoryBuiltinFunctions(TIntermAggregate *functionCall) { - *fatalError = false; - TOperator op = fnCall->getBuiltInOp(); - TIntermTyped *callNode = nullptr; - - if (thisNode != nullptr) + const TString &name = functionCall->getFunctionSymbolInfo()->getName(); + if (IsAtomicBuiltin(name)) { - TConstantUnion *unionArray = new TConstantUnion[1]; - int arraySize = 0; - TIntermTyped *typedThis = thisNode->getAsTyped(); - if (fnCall->getName() != "length") + TIntermSequence *arguments = functionCall->getSequence(); + TIntermTyped *memNode = (*arguments)[0]->getAsTyped(); + + if (IsBufferOrSharedVariable(memNode)) { - error(loc, "invalid method", fnCall->getName().c_str()); - recover(); + return; } - else if (paramNode != nullptr) + + while (memNode->getAsBinaryNode()) { - error(loc, "method takes no parameters", "length"); - recover(); - } - else if (typedThis == nullptr || !typedThis->isArray()) - { - error(loc, "length can only be called on arrays", "length"); - recover(); - } - else - { - arraySize = typedThis->getArraySize(); - if (typedThis->getAsSymbolNode() == nullptr) + memNode = memNode->getAsBinaryNode()->getLeft(); + if (IsBufferOrSharedVariable(memNode)) { - // This code path can be hit with expressions like these: - // (a = b).length() - // (func()).length() - // (int[3](0, 1, 2)).length() - // ESSL 3.00 section 5.9 defines expressions so that this is not actually a valid - // expression. - // It allows "An array name with the length method applied" in contrast to GLSL 4.4 - // spec section 5.9 which allows "An array, vector or matrix expression with the - // length method applied". - error(loc, "length can only be called on array names, not on array expressions", - "length"); - recover(); + return; } } - unionArray->setIConst(arraySize); - callNode = - intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), loc); - } - else if (op != EOpNull) - { - // - // Then this should be a constructor. - // Don't go through the symbol table for constructors. - // Their parameters will be verified algorithmically. - // - TType type(EbtVoid, EbpUndefined); // use this to get the type back - if (!constructorErrorCheck(loc, paramNode, *fnCall, op, &type)) - { - // - // It's a constructor, of type 'type'. - // - callNode = addConstructor(paramNode, &type, op, fnCall, loc); - } - if (callNode == nullptr) + error(memNode->getLine(), + "The value passed to the mem argument of an atomic memory function does not " + "correspond to a buffer or shared variable.", + functionCall->getFunctionSymbolInfo()->getName().c_str()); + } +} + +// GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers +void TParseContext::checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall) +{ + ASSERT(functionCall->getOp() == EOpCallBuiltInFunction); + const TString &name = functionCall->getFunctionSymbolInfo()->getName(); + + if (name.compare(0, 5, "image") == 0) + { + TIntermSequence *arguments = functionCall->getSequence(); + TIntermTyped *imageNode = (*arguments)[0]->getAsTyped(); + + const TMemoryQualifier &memoryQualifier = imageNode->getMemoryQualifier(); + + if (name.compare(5, 5, "Store") == 0) { - recover(); - callNode = intermediate.setAggregateOperator(nullptr, op, loc); + if (memoryQualifier.readonly) + { + error(imageNode->getLine(), + "'imageStore' cannot be used with images qualified as 'readonly'", + GetImageArgumentToken(imageNode)); + } } - callNode->setType(type); + else if (name.compare(5, 4, "Load") == 0) + { + if (memoryQualifier.writeonly) + { + error(imageNode->getLine(), + "'imageLoad' cannot be used with images qualified as 'writeonly'", + GetImageArgumentToken(imageNode)); + } + } + } +} + +// GLSL ES 3.10 Revision 4, 13.51 Matching of Memory Qualifiers in Function Parameters +void TParseContext::checkImageMemoryAccessForUserDefinedFunctions( + const TFunction *functionDefinition, + const TIntermAggregate *functionCall) +{ + ASSERT(functionCall->getOp() == EOpCallFunctionInAST); + + const TIntermSequence &arguments = *functionCall->getSequence(); + + ASSERT(functionDefinition->getParamCount() == arguments.size()); + + for (size_t i = 0; i < arguments.size(); ++i) + { + TIntermTyped *typedArgument = arguments[i]->getAsTyped(); + const TType &functionArgumentType = typedArgument->getType(); + const TType &functionParameterType = *functionDefinition->getParam(i).type; + ASSERT(functionArgumentType.getBasicType() == functionParameterType.getBasicType()); + + if (IsImage(functionArgumentType.getBasicType())) + { + const TMemoryQualifier &functionArgumentMemoryQualifier = + functionArgumentType.getMemoryQualifier(); + const TMemoryQualifier &functionParameterMemoryQualifier = + functionParameterType.getMemoryQualifier(); + if (functionArgumentMemoryQualifier.readonly && + !functionParameterMemoryQualifier.readonly) + { + error(functionCall->getLine(), + "Function call discards the 'readonly' qualifier from image", + GetImageArgumentToken(typedArgument)); + } + + if (functionArgumentMemoryQualifier.writeonly && + !functionParameterMemoryQualifier.writeonly) + { + error(functionCall->getLine(), + "Function call discards the 'writeonly' qualifier from image", + GetImageArgumentToken(typedArgument)); + } + + if (functionArgumentMemoryQualifier.coherent && + !functionParameterMemoryQualifier.coherent) + { + error(functionCall->getLine(), + "Function call discards the 'coherent' qualifier from image", + GetImageArgumentToken(typedArgument)); + } + + if (functionArgumentMemoryQualifier.volatileQualifier && + !functionParameterMemoryQualifier.volatileQualifier) + { + error(functionCall->getLine(), + "Function call discards the 'volatile' qualifier from image", + GetImageArgumentToken(typedArgument)); + } + } + } +} + +TIntermSequence *TParseContext::createEmptyArgumentsList() +{ + return new TIntermSequence(); +} + +TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunction *fnCall, + TIntermSequence *arguments, + TIntermNode *thisNode, + const TSourceLoc &loc) +{ + if (thisNode != nullptr) + { + return addMethod(fnCall, arguments, thisNode, loc); + } + + TOperator op = fnCall->getBuiltInOp(); + if (op == EOpConstruct) + { + return addConstructor(arguments, fnCall->getReturnType(), loc); } else { - // - // Not a constructor. Find it in the symbol table. - // - const TFunction *fnCandidate; - bool builtIn; - fnCandidate = findFunction(loc, fnCall, mShaderVersion, &builtIn); - if (fnCandidate) + ASSERT(op == EOpNull); + return addNonConstructorFunctionCall(fnCall, arguments, loc); + } +} + +TIntermTyped *TParseContext::addMethod(TFunction *fnCall, + TIntermSequence *arguments, + TIntermNode *thisNode, + const TSourceLoc &loc) +{ + TIntermTyped *typedThis = thisNode->getAsTyped(); + // It's possible for the name pointer in the TFunction to be null in case it gets parsed as + // a constructor. But such a TFunction can't reach here, since the lexer goes into FIELDS + // mode after a dot, which makes type identifiers to be parsed as FIELD_SELECTION instead. + // So accessing fnCall->getName() below is safe. + if (fnCall->getName() != "length") + { + error(loc, "invalid method", fnCall->getName().c_str()); + } + else if (!arguments->empty()) + { + error(loc, "method takes no parameters", "length"); + } + else if (typedThis == nullptr || !typedThis->isArray()) + { + error(loc, "length can only be called on arrays", "length"); + } + else if (typedThis->getQualifier() == EvqPerVertexIn && + mGeometryShaderInputPrimitiveType == EptUndefined) + { + ASSERT(mShaderType == GL_GEOMETRY_SHADER_OES); + error(loc, "missing input primitive declaration before calling length on gl_in", "length"); + } + else + { + TIntermUnary *node = new TIntermUnary(EOpArrayLength, typedThis); + node->setLine(loc); + return node->fold(mDiagnostics); + } + return CreateZeroNode(TType(EbtInt, EbpUndefined, EvqConst)); +} + +TIntermTyped *TParseContext::addNonConstructorFunctionCall(TFunction *fnCall, + TIntermSequence *arguments, + const TSourceLoc &loc) +{ + // First find by unmangled name to check whether the function name has been + // hidden by a variable name or struct typename. + // If a function is found, check for one with a matching argument list. + bool builtIn; + const TSymbol *symbol = symbolTable.find(fnCall->getName(), mShaderVersion, &builtIn); + if (symbol != nullptr && !symbol->isFunction()) + { + error(loc, "function name expected", fnCall->getName().c_str()); + } + else + { + symbol = symbolTable.find(TFunction::GetMangledNameFromCall(fnCall->getName(), *arguments), + mShaderVersion, &builtIn); + if (symbol == nullptr) { + error(loc, "no matching overloaded function found", fnCall->getName().c_str()); + } + else + { + const TFunction *fnCandidate = static_cast(symbol); // // A declared function. // - if (builtIn && !fnCandidate->getExtension().empty() && - extensionErrorCheck(loc, fnCandidate->getExtension())) + if (builtIn && fnCandidate->getExtension() != TExtension::UNDEFINED) { - recover(); + checkCanUseExtension(loc, fnCandidate->getExtension()); } - op = fnCandidate->getBuiltInOp(); + TOperator op = fnCandidate->getBuiltInOp(); if (builtIn && op != EOpNull) { - // // A function call mapped to a built-in operation. - // if (fnCandidate->getParamCount() == 1) { - // // Treat it like a built-in unary operator. - // - TIntermAggregate *paramAgg = paramNode->getAsAggregate(); - paramNode = paramAgg->getSequence()->front(); - callNode = createUnaryMath(op, paramNode->getAsTyped(), loc, - &fnCandidate->getReturnType()); - if (callNode == nullptr) - { - std::stringstream extraInfoStream; - extraInfoStream - << "built in unary operator function. Type: " - << static_cast(paramNode)->getCompleteString(); - std::string extraInfo = extraInfoStream.str(); - error(paramNode->getLine(), " wrong operand type", "Internal Error", - extraInfo.c_str()); - *fatalError = true; - return nullptr; - } + TIntermNode *unaryParamNode = arguments->front(); + TIntermTyped *callNode = createUnaryMath(op, unaryParamNode->getAsTyped(), loc); + ASSERT(callNode != nullptr); + return callNode; } else { - TIntermAggregate *aggregate = - intermediate.setAggregateOperator(paramNode, op, loc); - aggregate->setType(fnCandidate->getReturnType()); - aggregate->setPrecisionFromChildren(); - if (aggregate->areChildrenConstQualified()) - { - aggregate->getTypePointer()->setQualifier(EvqConst); - } + TIntermAggregate *callNode = + TIntermAggregate::Create(fnCandidate->getReturnType(), op, arguments); + callNode->setLine(loc); // Some built-in functions have out parameters too. - functionCallLValueErrorCheck(fnCandidate, aggregate); + functionCallRValueLValueErrorCheck(fnCandidate, callNode); - // See if we can constant fold a built-in. Note that this may be possible even - // if it is not const-qualified. - TIntermTyped *foldedNode = intermediate.foldAggregateBuiltIn(aggregate); - if (foldedNode) + if (TIntermAggregate::CanFoldAggregateBuiltInOp(callNode->getOp())) { - callNode = foldedNode; + // See if we can constant fold a built-in. Note that this may be possible + // even if it is not const-qualified. + return callNode->fold(mDiagnostics); } else { - callNode = aggregate; + return callNode; } } } else { // This is a real function call - TIntermAggregate *aggregate = - intermediate.setAggregateOperator(paramNode, EOpFunctionCall, loc); - aggregate->setType(fnCandidate->getReturnType()); + TIntermAggregate *callNode = nullptr; - // this is how we know whether the given function is a builtIn function or a user - // defined function - // if builtIn == false, it's a userDefined -> could be an overloaded - // builtIn function also - // if builtIn == true, it's definitely a builtIn function with EOpNull - if (!builtIn) - aggregate->setUserDefined(); - aggregate->setName(fnCandidate->getMangledName()); - aggregate->setFunctionId(fnCandidate->getUniqueId()); - - // This needs to happen after the name is set + // If builtIn == false, the function is user defined - could be an overloaded + // built-in as well. + // if builtIn == true, it's a builtIn function with no op associated with it. + // This needs to happen after the function info including name is set. if (builtIn) { - aggregate->setBuiltInFunctionPrecision(); - - checkTextureOffsetConst(aggregate); + callNode = TIntermAggregate::CreateBuiltInFunctionCall(*fnCandidate, arguments); + checkTextureOffsetConst(callNode); + checkTextureGather(callNode); + checkImageMemoryAccessForBuiltinFunctions(callNode); + checkAtomicMemoryBuiltinFunctions(callNode); + } + else + { + callNode = TIntermAggregate::CreateFunctionCall(*fnCandidate, arguments); + checkImageMemoryAccessForUserDefinedFunctions(fnCandidate, callNode); } - callNode = aggregate; + functionCallRValueLValueErrorCheck(fnCandidate, callNode); - functionCallLValueErrorCheck(fnCandidate, aggregate); + callNode->setLine(loc); + + return callNode; } } - else - { - // error message was put out by findFunction() - // Put on a dummy node for error recovery - TConstantUnion *unionArray = new TConstantUnion[1]; - unionArray->setFConst(0.0f); - callNode = intermediate.addConstantUnion(unionArray, - TType(EbtFloat, EbpUndefined, EvqConst), loc); - recover(); - } } - return callNode; + + // Error message was already written. Put on a dummy node for error recovery. + return CreateZeroNode(TType(EbtFloat, EbpMedium, EvqConst)); } TIntermTyped *TParseContext::addTernarySelection(TIntermTyped *cond, - TIntermTyped *trueBlock, - TIntermTyped *falseBlock, + TIntermTyped *trueExpression, + TIntermTyped *falseExpression, const TSourceLoc &loc) { - if (boolErrorCheck(loc, cond)) - recover(); + if (!checkIsScalarBool(loc, cond)) + { + return falseExpression; + } - if (trueBlock->getType() != falseBlock->getType()) + if (trueExpression->getType() != falseExpression->getType()) { - binaryOpError(loc, ":", trueBlock->getCompleteString(), falseBlock->getCompleteString()); - recover(); - return falseBlock; + std::stringstream reasonStream; + reasonStream << "mismatching ternary operator operand types '" + << trueExpression->getCompleteString() << " and '" + << falseExpression->getCompleteString() << "'"; + std::string reason = reasonStream.str(); + error(loc, reason.c_str(), "?:"); + return falseExpression; } - // ESSL1 sections 5.2 and 5.7: - // ESSL3 section 5.7: + if (IsOpaqueType(trueExpression->getBasicType())) + { + // ESSL 1.00 section 4.1.7 + // ESSL 3.00.6 section 4.1.7 + // Opaque/sampler types are not allowed in most types of expressions, including ternary. + // Note that structs containing opaque types don't need to be checked as structs are + // forbidden below. + error(loc, "ternary operator is not allowed for opaque types", "?:"); + return falseExpression; + } + + if (cond->getMemoryQualifier().writeonly || trueExpression->getMemoryQualifier().writeonly || + falseExpression->getMemoryQualifier().writeonly) + { + error(loc, "ternary operator is not allowed for variables with writeonly", "?:"); + return falseExpression; + } + + // ESSL 1.00.17 sections 5.2 and 5.7: // Ternary operator is not among the operators allowed for structures/arrays. - if (trueBlock->isArray() || trueBlock->getBasicType() == EbtStruct) + // ESSL 3.00.6 section 5.7: + // Ternary operator support is optional for arrays. No certainty that it works across all + // devices with struct either, so we err on the side of caution here. TODO (oetuaho@nvidia.com): + // Would be nice to make the spec and implementation agree completely here. + if (trueExpression->isArray() || trueExpression->getBasicType() == EbtStruct) { - error(loc, "ternary operator is not allowed for structures or arrays", ":"); - recover(); - return falseBlock; + error(loc, "ternary operator is not allowed for structures or arrays", "?:"); + return falseExpression; } - return intermediate.addSelection(cond, trueBlock, falseBlock, loc); + if (trueExpression->getBasicType() == EbtInterfaceBlock) + { + error(loc, "ternary operator is not allowed for interface blocks", "?:"); + return falseExpression; + } + + // WebGL2 section 5.26, the following results in an error: + // "Ternary operator applied to void, arrays, or structs containing arrays" + if (mShaderSpec == SH_WEBGL2_SPEC && trueExpression->getBasicType() == EbtVoid) + { + error(loc, "ternary operator is not allowed for void", "?:"); + return falseExpression; + } + + // Note that the node resulting from here can be a constant union without being qualified as + // constant. + TIntermTernary *node = new TIntermTernary(cond, trueExpression, falseExpression); + node->setLine(loc); + + return node->fold(); } // @@ -4128,7 +6004,7 @@ int PaParseStrings(size_t count, const int length[], TParseContext *context) { - if ((count == 0) || (string == NULL)) + if ((count == 0) || (string == nullptr)) return 1; if (glslang_initialize(context)) @@ -4142,3 +6018,5 @@ int PaParseStrings(size_t count, return (error == 0) && (context->numErrors() == 0) ? 0 : 1; } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/ParseContext.h b/src/3rdparty/angle/src/compiler/translator/ParseContext.h index 1eaf1e5b42..8bfdbd5e3f 100644 --- a/src/3rdparty/angle/src/compiler/translator/ParseContext.h +++ b/src/3rdparty/angle/src/compiler/translator/ParseContext.h @@ -9,10 +9,13 @@ #include "compiler/translator/Compiler.h" #include "compiler/translator/Diagnostics.h" #include "compiler/translator/DirectiveHandler.h" -#include "compiler/translator/Intermediate.h" #include "compiler/translator/SymbolTable.h" +#include "compiler/translator/QualifierTypes.h" #include "compiler/preprocessor/Preprocessor.h" +namespace sh +{ + struct TMatrixFields { bool wholeRow; @@ -30,44 +33,13 @@ class TParseContext : angle::NonCopyable public: TParseContext(TSymbolTable &symt, TExtensionBehavior &ext, - TIntermediate &interm, sh::GLenum type, ShShaderSpec spec, - int options, + ShCompileOptions options, bool checksPrecErrors, - TInfoSink &is, - const ShBuiltInResources &resources) - : intermediate(interm), - symbolTable(symt), - mDeferredSingleDeclarationErrorCheck(false), - mShaderType(type), - mShaderSpec(spec), - mShaderVersion(100), - mTreeRoot(nullptr), - mLoopNestingLevel(0), - mStructNestingLevel(0), - mSwitchNestingLevel(0), - mCurrentFunctionType(nullptr), - mFunctionReturnsValue(false), - mChecksPrecisionErrors(checksPrecErrors), - mFragmentPrecisionHighOnESSL1(false), - mDefaultMatrixPacking(EmpColumnMajor), - mDefaultBlockStorage(EbsShared), - mDiagnostics(is), - mDirectiveHandler(ext, - mDiagnostics, - mShaderVersion, - mShaderType, - resources.WEBGL_debug_shader_precision == 1), - mPreprocessor(&mDiagnostics, &mDirectiveHandler), - mScanner(nullptr), - mUsesFragData(false), - mUsesFragColor(false), - mUsesSecondaryOutputs(false), - mMinProgramTexelOffset(resources.MinProgramTexelOffset), - mMaxProgramTexelOffset(resources.MaxProgramTexelOffset) - { - } + TDiagnostics *diagnostics, + const ShBuiltInResources &resources); + ~TParseContext(); const pp::Preprocessor &getPreprocessor() const { return mPreprocessor; } pp::Preprocessor &getPreprocessor() { return mPreprocessor; } @@ -76,23 +48,18 @@ class TParseContext : angle::NonCopyable int getShaderVersion() const { return mShaderVersion; } sh::GLenum getShaderType() const { return mShaderType; } ShShaderSpec getShaderSpec() const { return mShaderSpec; } - int numErrors() const { return mDiagnostics.numErrors(); } - TInfoSink &infoSink() { return mDiagnostics.infoSink(); } - void error(const TSourceLoc &loc, const char *reason, const char *token, - const char *extraInfo=""); - void warning(const TSourceLoc &loc, const char *reason, const char *token, - const char *extraInfo=""); + int numErrors() const { return mDiagnostics->numErrors(); } + void error(const TSourceLoc &loc, const char *reason, const char *token); + void warning(const TSourceLoc &loc, const char *reason, const char *token); // If isError is false, a warning will be reported instead. void outOfRangeError(bool isError, const TSourceLoc &loc, const char *reason, - const char *token, - const char *extraInfo = ""); + const char *token); - void recover(); - TIntermNode *getTreeRoot() const { return mTreeRoot; } - void setTreeRoot(TIntermNode *treeRoot) { mTreeRoot = treeRoot; } + TIntermBlock *getTreeRoot() const { return mTreeRoot; } + void setTreeRoot(TIntermBlock *treeRoot) { mTreeRoot = treeRoot; } bool getFragmentPrecisionHigh() const { @@ -103,10 +70,7 @@ class TParseContext : angle::NonCopyable mFragmentPrecisionHighOnESSL1 = fragmentPrecisionHigh; } - void setLoopNestingLevel(int loopNestintLevel) - { - mLoopNestingLevel = loopNestintLevel; - } + void setLoopNestingLevel(int loopNestintLevel) { mLoopNestingLevel = loopNestintLevel; } void incrLoopNestingLevel() { ++mLoopNestingLevel; } void decrLoopNestingLevel() { --mLoopNestingLevel; } @@ -114,279 +78,580 @@ class TParseContext : angle::NonCopyable void incrSwitchNestingLevel() { ++mSwitchNestingLevel; } void decrSwitchNestingLevel() { --mSwitchNestingLevel; } + bool isComputeShaderLocalSizeDeclared() const { return mComputeShaderLocalSizeDeclared; } + sh::WorkGroupSize getComputeShaderLocalSize() const; + + int getNumViews() const { return mNumViews; } + + void enterFunctionDeclaration() { mDeclaringFunction = true; } + + void exitFunctionDeclaration() { mDeclaringFunction = false; } + + bool declaringFunction() const { return mDeclaringFunction; } + + TIntermConstantUnion *addScalarLiteral(const TConstantUnion *constantUnion, + const TSourceLoc &line); + // This method is guaranteed to succeed, even if no variable with 'name' exists. - const TVariable *getNamedVariable(const TSourceLoc &location, const TString *name, const TSymbol *symbol); + const TVariable *getNamedVariable(const TSourceLoc &location, + const TString *name, + const TSymbol *symbol); TIntermTyped *parseVariableIdentifier(const TSourceLoc &location, const TString *name, const TSymbol *symbol); - bool parseVectorFields(const TString&, int vecSize, TVectorFields&, const TSourceLoc &line); + // Look at a '.' field selector string and change it into offsets for a vector. + bool parseVectorFields(const TSourceLoc &line, + const TString &compString, + int vecSize, + TVector *fieldOffsets); - bool reservedErrorCheck(const TSourceLoc &line, const TString &identifier); void assignError(const TSourceLoc &line, const char *op, TString left, TString right); void unaryOpError(const TSourceLoc &line, const char *op, TString operand); void binaryOpError(const TSourceLoc &line, const char *op, TString left, TString right); - bool precisionErrorCheck(const TSourceLoc &line, TPrecision precision, TBasicType type); - bool lValueErrorCheck(const TSourceLoc &line, const char *op, TIntermTyped*); - bool constErrorCheck(TIntermTyped *node); - bool integerErrorCheck(TIntermTyped *node, const char *token); - bool globalErrorCheck(const TSourceLoc &line, bool global, const char *token); - bool constructorErrorCheck(const TSourceLoc &line, - TIntermNode *argumentsNode, - TFunction &function, - TOperator op, - TType *type); - bool arraySizeErrorCheck(const TSourceLoc &line, TIntermTyped *expr, int &size); - bool arrayQualifierErrorCheck(const TSourceLoc &line, const TPublicType &type); - bool arrayTypeErrorCheck(const TSourceLoc &line, const TPublicType &type); - bool voidErrorCheck(const TSourceLoc &line, const TString &identifier, const TBasicType &type); - bool boolErrorCheck(const TSourceLoc&, const TIntermTyped*); - bool boolErrorCheck(const TSourceLoc&, const TPublicType&); - bool samplerErrorCheck(const TSourceLoc &line, const TPublicType &pType, const char *reason); - bool locationDeclaratorListCheck(const TSourceLoc &line, const TPublicType &pType); - bool parameterSamplerErrorCheck(const TSourceLoc &line, TQualifier qualifier, const TType &type); - bool paramErrorCheck(const TSourceLoc &line, TQualifier qualifier, TQualifier paramQualifier, TType *type); - bool extensionErrorCheck(const TSourceLoc &line, const TString&); - bool singleDeclarationErrorCheck(const TPublicType &publicType, const TSourceLoc &identifierLocation); - bool layoutLocationErrorCheck(const TSourceLoc &location, const TLayoutQualifier &layoutQualifier); - bool functionCallLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *); - void es3InvariantErrorCheck(const TQualifier qualifier, const TSourceLoc &invariantLocation); - void es3InputOutputTypeCheck(const TQualifier qualifier, - const TPublicType &type, - const TSourceLoc &qualifierLocation); + // Check functions - the ones that return bool return false if an error was generated. + + bool checkIsNotReserved(const TSourceLoc &line, const TString &identifier); + void checkPrecisionSpecified(const TSourceLoc &line, TPrecision precision, TBasicType type); + bool checkCanBeLValue(const TSourceLoc &line, const char *op, TIntermTyped *node); + void checkIsConst(TIntermTyped *node); + void checkIsScalarInteger(TIntermTyped *node, const char *token); + bool checkIsAtGlobalLevel(const TSourceLoc &line, const char *token); + bool checkConstructorArguments(const TSourceLoc &line, + const TIntermSequence *arguments, + const TType &type); + + // Returns a sanitized array size to use (the size is at least 1). + unsigned int checkIsValidArraySize(const TSourceLoc &line, TIntermTyped *expr); + bool checkIsValidQualifierForArray(const TSourceLoc &line, const TPublicType &elementQualifier); + bool checkArrayElementIsNotArray(const TSourceLoc &line, const TPublicType &elementType); + bool checkIsNonVoid(const TSourceLoc &line, const TString &identifier, const TBasicType &type); + bool checkIsScalarBool(const TSourceLoc &line, const TIntermTyped *type); + void checkIsScalarBool(const TSourceLoc &line, const TPublicType &pType); + bool checkIsNotOpaqueType(const TSourceLoc &line, + const TTypeSpecifierNonArray &pType, + const char *reason); + void checkDeclaratorLocationIsNotSpecified(const TSourceLoc &line, const TPublicType &pType); + void checkLocationIsNotSpecified(const TSourceLoc &location, + const TLayoutQualifier &layoutQualifier); + void checkStd430IsForShaderStorageBlock(const TSourceLoc &location, + const TLayoutBlockStorage &blockStorage, + const TQualifier &qualifier); + void checkIsParameterQualifierValid(const TSourceLoc &line, + const TTypeQualifierBuilder &typeQualifierBuilder, + TType *type); + + // Check if at least one of the specified extensions can be used, and generate error/warning as + // appropriate according to the spec. + // This function is only needed for a few different small constant sizes of extension array, and + // we want to avoid unnecessary dynamic allocations. That's why checkCanUseOneOfExtensions is a + // template function rather than one taking a vector. + template + bool checkCanUseOneOfExtensions(const TSourceLoc &line, + const std::array &extensions); + bool checkCanUseExtension(const TSourceLoc &line, TExtension extension); + + // Done for all declarations, whether empty or not. + void declarationQualifierErrorCheck(const sh::TQualifier qualifier, + const sh::TLayoutQualifier &layoutQualifier, + const TSourceLoc &location); + // Done for the first non-empty declarator in a declaration. + void nonEmptyDeclarationErrorCheck(const TPublicType &publicType, + const TSourceLoc &identifierLocation); + // Done only for empty declarations. + void emptyDeclarationErrorCheck(const TType &type, const TSourceLoc &location); + + void checkLayoutQualifierSupported(const TSourceLoc &location, + const TString &layoutQualifierName, + int versionRequired); + bool checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location, + const TLayoutQualifier &layoutQualifier); + void functionCallRValueLValueErrorCheck(const TFunction *fnCandidate, TIntermAggregate *fnCall); + void checkInvariantVariableQualifier(bool invariant, + const TQualifier qualifier, + const TSourceLoc &invariantLocation); + void checkInputOutputTypeIsValidES3(const TQualifier qualifier, + const TPublicType &type, + const TSourceLoc &qualifierLocation); + void checkLocalVariableConstStorageQualifier(const TQualifierWrapperBase &qualifier); const TPragma &pragma() const { return mDirectiveHandler.pragma(); } - const TExtensionBehavior &extensionBehavior() const { return mDirectiveHandler.extensionBehavior(); } - bool supportsExtension(const char *extension); - bool isExtensionEnabled(const char *extension) const; - void handleExtensionDirective(const TSourceLoc &loc, const char *extName, const char *behavior); - void handlePragmaDirective(const TSourceLoc &loc, const char *name, const char *value, bool stdgl); + const TExtensionBehavior &extensionBehavior() const + { + return mDirectiveHandler.extensionBehavior(); + } - bool containsSampler(const TType &type); - const TFunction* findFunction( - const TSourceLoc &line, TFunction *pfnCall, int inputShaderVersion, bool *builtIn = 0); + bool isExtensionEnabled(TExtension extension) const; + void handleExtensionDirective(const TSourceLoc &loc, const char *extName, const char *behavior); + void handlePragmaDirective(const TSourceLoc &loc, + const char *name, + const char *value, + bool stdgl); + + // Returns true on success. *initNode may still be nullptr on success in case the initialization + // is not needed in the AST. bool executeInitializer(const TSourceLoc &line, const TString &identifier, - const TPublicType &pType, + TType type, TIntermTyped *initializer, - TIntermNode **intermNode); + TIntermBinary **initNode); + TIntermNode *addConditionInitializer(const TPublicType &pType, + const TString &identifier, + TIntermTyped *initializer, + const TSourceLoc &loc); + TIntermNode *addLoop(TLoopType type, + TIntermNode *init, + TIntermNode *cond, + TIntermTyped *expr, + TIntermNode *body, + const TSourceLoc &loc); - TPublicType addFullySpecifiedType(TQualifier qualifier, - bool invariant, - TLayoutQualifier layoutQualifier, + // For "if" test nodes. There are three children: a condition, a true path, and a false path. + // The two paths are in TIntermNodePair code. + TIntermNode *addIfElse(TIntermTyped *cond, TIntermNodePair code, const TSourceLoc &loc); + + void addFullySpecifiedType(TPublicType *typeSpecifier); + TPublicType addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder, const TPublicType &typeSpecifier); - TIntermAggregate *parseSingleDeclaration(TPublicType &publicType, - const TSourceLoc &identifierOrTypeLocation, - const TString &identifier); - TIntermAggregate *parseSingleArrayDeclaration(TPublicType &publicType, - const TSourceLoc &identifierLocation, - const TString &identifier, - const TSourceLoc &indexLocation, - TIntermTyped *indexExpression); - TIntermAggregate *parseSingleInitDeclaration(const TPublicType &publicType, - const TSourceLoc &identifierLocation, - const TString &identifier, - const TSourceLoc &initLocation, - TIntermTyped *initializer); + TIntermDeclaration *parseSingleDeclaration(TPublicType &publicType, + const TSourceLoc &identifierOrTypeLocation, + const TString &identifier); + TIntermDeclaration *parseSingleArrayDeclaration(TPublicType &elementType, + const TSourceLoc &identifierLocation, + const TString &identifier, + const TSourceLoc &indexLocation, + const TVector &arraySizes); + TIntermDeclaration *parseSingleInitDeclaration(const TPublicType &publicType, + const TSourceLoc &identifierLocation, + const TString &identifier, + const TSourceLoc &initLocation, + TIntermTyped *initializer); // Parse a declaration like "type a[n] = initializer" // Note that this does not apply to declarations like "type[n] a = initializer" - TIntermAggregate *parseSingleArrayInitDeclaration(TPublicType &publicType, - const TSourceLoc &identifierLocation, - const TString &identifier, - const TSourceLoc &indexLocation, - TIntermTyped *indexExpression, - const TSourceLoc &initLocation, - TIntermTyped *initializer); + TIntermDeclaration *parseSingleArrayInitDeclaration(TPublicType &elementType, + const TSourceLoc &identifierLocation, + const TString &identifier, + const TSourceLoc &indexLocation, + const TVector &arraySizes, + const TSourceLoc &initLocation, + TIntermTyped *initializer); - TIntermAggregate *parseInvariantDeclaration(const TSourceLoc &invariantLoc, - const TSourceLoc &identifierLoc, - const TString *identifier, - const TSymbol *symbol); + TIntermInvariantDeclaration *parseInvariantDeclaration( + const TTypeQualifierBuilder &typeQualifierBuilder, + const TSourceLoc &identifierLoc, + const TString *identifier, + const TSymbol *symbol); - TIntermAggregate *parseDeclarator(TPublicType &publicType, - TIntermAggregate *aggregateDeclaration, - const TSourceLoc &identifierLocation, - const TString &identifier); - TIntermAggregate *parseArrayDeclarator(TPublicType &publicType, - TIntermAggregate *aggregateDeclaration, - const TSourceLoc &identifierLocation, - const TString &identifier, - const TSourceLoc &arrayLocation, - TIntermTyped *indexExpression); - TIntermAggregate *parseInitDeclarator(const TPublicType &publicType, - TIntermAggregate *aggregateDeclaration, - const TSourceLoc &identifierLocation, - const TString &identifier, - const TSourceLoc &initLocation, - TIntermTyped *initializer); + void parseDeclarator(TPublicType &publicType, + const TSourceLoc &identifierLocation, + const TString &identifier, + TIntermDeclaration *declarationOut); + void parseArrayDeclarator(TPublicType &elementType, + const TSourceLoc &identifierLocation, + const TString &identifier, + const TSourceLoc &arrayLocation, + const TVector &arraySizes, + TIntermDeclaration *declarationOut); + void parseInitDeclarator(const TPublicType &publicType, + const TSourceLoc &identifierLocation, + const TString &identifier, + const TSourceLoc &initLocation, + TIntermTyped *initializer, + TIntermDeclaration *declarationOut); // Parse a declarator like "a[n] = initializer" - TIntermAggregate *parseArrayInitDeclarator(const TPublicType &publicType, - TIntermAggregate *aggregateDeclaration, - const TSourceLoc &identifierLocation, - const TString &identifier, - const TSourceLoc &indexLocation, - TIntermTyped *indexExpression, - const TSourceLoc &initLocation, - TIntermTyped *initializer); + void parseArrayInitDeclarator(const TPublicType &elementType, + const TSourceLoc &identifierLocation, + const TString &identifier, + const TSourceLoc &indexLocation, + const TVector &arraySizes, + const TSourceLoc &initLocation, + TIntermTyped *initializer, + TIntermDeclaration *declarationOut); - void parseGlobalLayoutQualifier(const TPublicType &typeQualifier); - TIntermAggregate *addFunctionPrototypeDeclaration(const TFunction &function, - const TSourceLoc &location); - TIntermAggregate *addFunctionDefinition(const TFunction &function, - TIntermAggregate *functionPrototype, - TIntermAggregate *functionBody, - const TSourceLoc &location); - void parseFunctionPrototype(const TSourceLoc &location, - TFunction *function, - TIntermAggregate **aggregateOut); - TFunction *parseFunctionDeclarator(const TSourceLoc &location, - TFunction *function); + TIntermNode *addEmptyStatement(const TSourceLoc &location); + + void parseDefaultPrecisionQualifier(const TPrecision precision, + const TPublicType &type, + const TSourceLoc &loc); + void parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder); + + TIntermFunctionPrototype *addFunctionPrototypeDeclaration(const TFunction &parsedFunction, + const TSourceLoc &location); + TIntermFunctionDefinition *addFunctionDefinition(TIntermFunctionPrototype *functionPrototype, + TIntermBlock *functionBody, + const TSourceLoc &location); + void parseFunctionDefinitionHeader(const TSourceLoc &location, + TFunction **function, + TIntermFunctionPrototype **prototypeOut); + TFunction *parseFunctionDeclarator(const TSourceLoc &location, TFunction *function); + TFunction *parseFunctionHeader(const TPublicType &type, + const TString *name, + const TSourceLoc &location); + TFunction *addNonConstructorFunc(const TString *name, const TSourceLoc &loc); TFunction *addConstructorFunc(const TPublicType &publicType); - TIntermTyped *addConstructor(TIntermNode *arguments, - TType *type, - TOperator op, - TFunction *fnCall, - const TSourceLoc &line); - TIntermTyped *addConstVectorNode(TVectorFields &fields, - TIntermConstantUnion *node, - const TSourceLoc &line, - bool outOfRangeIndexIsError); - TIntermTyped *addConstMatrixNode(int index, - TIntermConstantUnion *node, - const TSourceLoc &line, - bool outOfRangeIndexIsError); - TIntermTyped *addConstArrayNode(int index, - TIntermConstantUnion *node, - const TSourceLoc &line, - bool outOfRangeIndexIsError); - TIntermTyped *addConstStruct( - const TString &identifier, TIntermTyped *node, const TSourceLoc& line); + TParameter parseParameterDeclarator(const TPublicType &publicType, + const TString *name, + const TSourceLoc &nameLoc); + + TParameter parseParameterArrayDeclarator(const TString *name, + const TSourceLoc &nameLoc, + const TVector &arraySizes, + const TSourceLoc &arrayLoc, + TPublicType *elementType); + TIntermTyped *addIndexExpression(TIntermTyped *baseExpression, - const TSourceLoc& location, + const TSourceLoc &location, TIntermTyped *indexExpression); - TIntermTyped* addFieldSelectionExpression(TIntermTyped *baseExpression, + TIntermTyped *addFieldSelectionExpression(TIntermTyped *baseExpression, const TSourceLoc &dotLocation, const TString &fieldString, const TSourceLoc &fieldLocation); + // Parse declarator for a single field + TField *parseStructDeclarator(TString *identifier, const TSourceLoc &loc); + TField *parseStructArrayDeclarator(TString *identifier, + const TSourceLoc &loc, + const TVector &arraySizes, + const TSourceLoc &arraySizeLoc); + + void checkDoesNotHaveDuplicateFieldName(const TFieldList::const_iterator begin, + const TFieldList::const_iterator end, + const TString &name, + const TSourceLoc &location); + TFieldList *addStructFieldList(TFieldList *fields, const TSourceLoc &location); + TFieldList *combineStructFieldLists(TFieldList *processedFields, + const TFieldList *newlyAddedFields, + const TSourceLoc &location); + TFieldList *addStructDeclaratorListWithQualifiers( + const TTypeQualifierBuilder &typeQualifierBuilder, + TPublicType *typeSpecifier, + TFieldList *fieldList); TFieldList *addStructDeclaratorList(const TPublicType &typeSpecifier, TFieldList *fieldList); - TPublicType addStructure(const TSourceLoc &structLine, - const TSourceLoc &nameLine, - const TString *structName, - TFieldList *fieldList); - - TIntermAggregate* addInterfaceBlock(const TPublicType &typeQualifier, + TTypeSpecifierNonArray addStructure(const TSourceLoc &structLine, const TSourceLoc &nameLine, - const TString &blockName, - TFieldList *fieldList, - const TString *instanceName, - const TSourceLoc &instanceLine, - TIntermTyped *arrayIndex, - const TSourceLoc& arrayIndexLine); + const TString *structName, + TFieldList *fieldList); - TLayoutQualifier parseLayoutQualifier( - const TString &qualifierType, const TSourceLoc &qualifierTypeLine); + TIntermDeclaration *addInterfaceBlock(const TTypeQualifierBuilder &typeQualifierBuilder, + const TSourceLoc &nameLine, + const TString &blockName, + TFieldList *fieldList, + const TString *instanceName, + const TSourceLoc &instanceLine, + TIntermTyped *arrayIndex, + const TSourceLoc &arrayIndexLine); + + void parseLocalSize(const TString &qualifierType, + const TSourceLoc &qualifierTypeLine, + int intValue, + const TSourceLoc &intValueLine, + const std::string &intValueString, + size_t index, + sh::WorkGroupSize *localSize); + void parseNumViews(int intValue, + const TSourceLoc &intValueLine, + const std::string &intValueString, + int *numViews); + void parseInvocations(int intValue, + const TSourceLoc &intValueLine, + const std::string &intValueString, + int *numInvocations); + void parseMaxVertices(int intValue, + const TSourceLoc &intValueLine, + const std::string &intValueString, + int *numMaxVertices); + TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, + const TSourceLoc &qualifierTypeLine); TLayoutQualifier parseLayoutQualifier(const TString &qualifierType, const TSourceLoc &qualifierTypeLine, - const TString &intValueString, int intValue, const TSourceLoc &intValueLine); - TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier, TLayoutQualifier rightQualifier); - TPublicType joinInterpolationQualifiers(const TSourceLoc &interpolationLoc, TQualifier interpolationQualifier, - const TSourceLoc &storageLoc, TQualifier storageQualifier); + TTypeQualifierBuilder *createTypeQualifierBuilder(const TSourceLoc &loc); + TStorageQualifierWrapper *parseGlobalStorageQualifier(TQualifier qualifier, + const TSourceLoc &loc); + TStorageQualifierWrapper *parseVaryingQualifier(const TSourceLoc &loc); + TStorageQualifierWrapper *parseInQualifier(const TSourceLoc &loc); + TStorageQualifierWrapper *parseOutQualifier(const TSourceLoc &loc); + TStorageQualifierWrapper *parseInOutQualifier(const TSourceLoc &loc); + TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier, + TLayoutQualifier rightQualifier, + const TSourceLoc &rightQualifierLocation); // Performs an error check for embedded struct declarations. - // Returns true if an error was raised due to the declaration of - // this struct. - bool enterStructDeclaration(const TSourceLoc &line, const TString &identifier); + void enterStructDeclaration(const TSourceLoc &line, const TString &identifier); void exitStructDeclaration(); - bool structNestingErrorCheck(const TSourceLoc &line, const TField &field); + void checkIsBelowStructNestingLimit(const TSourceLoc &line, const TField &field); - TIntermSwitch *addSwitch(TIntermTyped *init, TIntermAggregate *statementList, const TSourceLoc &loc); + TIntermSwitch *addSwitch(TIntermTyped *init, + TIntermBlock *statementList, + const TSourceLoc &loc); TIntermCase *addCase(TIntermTyped *condition, const TSourceLoc &loc); TIntermCase *addDefault(const TSourceLoc &loc); TIntermTyped *addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc); TIntermTyped *addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc); - TIntermTyped *addBinaryMath( - TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc); - TIntermTyped *addBinaryMathBooleanResult( - TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc); - TIntermTyped *addAssign( - TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc); + TIntermTyped *addBinaryMath(TOperator op, + TIntermTyped *left, + TIntermTyped *right, + const TSourceLoc &loc); + TIntermTyped *addBinaryMathBooleanResult(TOperator op, + TIntermTyped *left, + TIntermTyped *right, + const TSourceLoc &loc); + TIntermTyped *addAssign(TOperator op, + TIntermTyped *left, + TIntermTyped *right, + const TSourceLoc &loc); TIntermTyped *addComma(TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc); TIntermBranch *addBranch(TOperator op, const TSourceLoc &loc); - TIntermBranch *addBranch(TOperator op, TIntermTyped *returnValue, const TSourceLoc &loc); + TIntermBranch *addBranch(TOperator op, TIntermTyped *expression, const TSourceLoc &loc); + void checkTextureGather(TIntermAggregate *functionCall); void checkTextureOffsetConst(TIntermAggregate *functionCall); + void checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall); + void checkImageMemoryAccessForUserDefinedFunctions(const TFunction *functionDefinition, + const TIntermAggregate *functionCall); + void checkAtomicMemoryBuiltinFunctions(TIntermAggregate *functionCall); + TIntermSequence *createEmptyArgumentsList(); + + // fnCall is only storing the built-in op, and function name or constructor type. arguments + // has the arguments. TIntermTyped *addFunctionCallOrMethod(TFunction *fnCall, - TIntermNode *paramNode, + TIntermSequence *arguments, TIntermNode *thisNode, - const TSourceLoc &loc, - bool *fatalError); + const TSourceLoc &loc); - TIntermTyped *addTernarySelection( - TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, const TSourceLoc &line); + TIntermTyped *addTernarySelection(TIntermTyped *cond, + TIntermTyped *trueExpression, + TIntermTyped *falseExpression, + const TSourceLoc &line); - // TODO(jmadill): make these private - TIntermediate &intermediate; // to hold and build a parse tree + int getGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; } + int getGeometryShaderInvocations() const + { + return (mGeometryShaderInvocations > 0) ? mGeometryShaderInvocations : 1; + } + TLayoutPrimitiveType getGeometryShaderInputPrimitiveType() const + { + return mGeometryShaderInputPrimitiveType; + } + TLayoutPrimitiveType getGeometryShaderOutputPrimitiveType() const + { + return mGeometryShaderOutputPrimitiveType; + } + + // TODO(jmadill): make this private TSymbolTable &symbolTable; // symbol table that goes with the language currently being parsed private: - bool declareVariable(const TSourceLoc &line, const TString &identifier, const TType &type, TVariable **variable); + class AtomicCounterBindingState; + constexpr static size_t kAtomicCounterSize = 4; + // UNIFORM_ARRAY_STRIDE for atomic counter arrays is an implementation-dependent value which + // can be queried after a program is linked according to ES 3.10 section 7.7.1. This is + // controversial with the offset inheritance as described in ESSL 3.10 section 4.4.6. Currently + // we treat it as always 4 in favour of the original interpretation in + // "ARB_shader_atomic_counters". + // TODO(jie.a.chen@intel.com): Double check this once the spec vagueness is resolved. + // Note that there may be tests in AtomicCounter_test that will need to be updated as well. + constexpr static size_t kAtomicCounterArrayStride = 4; - bool nonInitErrorCheck(const TSourceLoc &line, const TString &identifier, TPublicType *type); + // Returns a clamped index. If it prints out an error message, the token is "[]". + int checkIndexLessThan(bool outOfRangeIndexIsError, + const TSourceLoc &location, + int index, + int arraySize, + const char *reason); - TIntermTyped *addBinaryMathInternal( - TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc); - TIntermTyped *createAssign( - TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc); - // The funcReturnType parameter is expected to be non-null when the operation is a built-in function. - // It is expected to be null for other unary operators. - TIntermTyped *createUnaryMath( - TOperator op, TIntermTyped *child, const TSourceLoc &loc, const TType *funcReturnType); + bool declareVariable(const TSourceLoc &line, + const TString &identifier, + const TType &type, + TVariable **variable); + + void checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line, + const TString &identifier, + TType *type); + + TParameter parseParameterDeclarator(TType *type, + const TString *name, + const TSourceLoc &nameLoc); + + bool checkIsValidTypeAndQualifierForArray(const TSourceLoc &indexLocation, + const TPublicType &elementType); + // Done for all atomic counter declarations, whether empty or not. + void atomicCounterQualifierErrorCheck(const TPublicType &publicType, + const TSourceLoc &location); + + // Assumes that multiplication op has already been set based on the types. + bool isMultiplicationTypeCombinationValid(TOperator op, const TType &left, const TType &right); + + void checkOutParameterIsNotOpaqueType(const TSourceLoc &line, + TQualifier qualifier, + const TType &type); + + void checkInternalFormatIsNotSpecified(const TSourceLoc &location, + TLayoutImageInternalFormat internalFormat); + void checkMemoryQualifierIsNotSpecified(const TMemoryQualifier &memoryQualifier, + const TSourceLoc &location); + void checkAtomicCounterOffsetDoesNotOverlap(bool forceAppend, + const TSourceLoc &loc, + TType *type); + void checkBindingIsValid(const TSourceLoc &identifierLocation, const TType &type); + void checkBindingIsNotSpecified(const TSourceLoc &location, int binding); + void checkOffsetIsNotSpecified(const TSourceLoc &location, int offset); + void checkImageBindingIsValid(const TSourceLoc &location, + int binding, + int arrayTotalElementCount); + void checkSamplerBindingIsValid(const TSourceLoc &location, + int binding, + int arrayTotalElementCount); + void checkBlockBindingIsValid(const TSourceLoc &location, + const TQualifier &qualifier, + int binding, + int arraySize); + void checkAtomicCounterBindingIsValid(const TSourceLoc &location, int binding); + + void checkUniformLocationInRange(const TSourceLoc &location, + int objectLocationCount, + const TLayoutQualifier &layoutQualifier); + + void checkYuvIsNotSpecified(const TSourceLoc &location, bool yuv); + + bool checkUnsizedArrayConstructorArgumentDimensionality(TIntermSequence *arguments, + TType type, + const TSourceLoc &line); + + // Will set the size of the outermost array according to geometry shader input layout. + void checkGeometryShaderInputAndSetArraySize(const TSourceLoc &location, + const char *token, + TType *type); + + // Will size any unsized array type so unsized arrays won't need to be taken into account + // further along the line in parsing. + void checkIsNotUnsizedArray(const TSourceLoc &line, + const char *errorMessage, + const char *token, + TType *arrayType); + + TIntermTyped *addBinaryMathInternal(TOperator op, + TIntermTyped *left, + TIntermTyped *right, + const TSourceLoc &loc); + TIntermBinary *createAssign(TOperator op, + TIntermTyped *left, + TIntermTyped *right, + const TSourceLoc &loc); + TIntermTyped *createUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc); + + TIntermTyped *addMethod(TFunction *fnCall, + TIntermSequence *arguments, + TIntermNode *thisNode, + const TSourceLoc &loc); + TIntermTyped *addConstructor(TIntermSequence *arguments, + TType type, + const TSourceLoc &line); + TIntermTyped *addNonConstructorFunctionCall(TFunction *fnCall, + TIntermSequence *arguments, + const TSourceLoc &loc); // Return true if the checks pass - bool binaryOpCommonCheck( - TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc); + bool binaryOpCommonCheck(TOperator op, + TIntermTyped *left, + TIntermTyped *right, + const TSourceLoc &loc); - // Set to true when the last/current declarator list was started with an empty declaration. - bool mDeferredSingleDeclarationErrorCheck; + TIntermFunctionPrototype *createPrototypeNodeFromFunction(const TFunction &function, + const TSourceLoc &location, + bool insertParametersToSymbolTable); - sh::GLenum mShaderType; // vertex or fragment language (future: pack or unpack) - ShShaderSpec mShaderSpec; // The language specification compiler conforms to - GLES2 or WebGL. + void setAtomicCounterBindingDefaultOffset(const TPublicType &declaration, + const TSourceLoc &location); + + bool checkPrimitiveTypeMatchesTypeQualifier(const TTypeQualifier &typeQualifier); + bool parseGeometryShaderInputLayoutQualifier(const TTypeQualifier &typeQualifier); + bool parseGeometryShaderOutputLayoutQualifier(const TTypeQualifier &typeQualifier); + void setGeometryShaderInputArraySize(unsigned int inputArraySize, const TSourceLoc &line); + + // Set to true when the last/current declarator list was started with an empty declaration. The + // non-empty declaration error check will need to be performed if the empty declaration is + // followed by a declarator. + bool mDeferredNonEmptyDeclarationErrorCheck; + + sh::GLenum mShaderType; // vertex or fragment language (future: pack or unpack) + ShShaderSpec mShaderSpec; // The language specification compiler conforms to - GLES2 or WebGL. + ShCompileOptions mCompileOptions; // Options passed to TCompiler int mShaderVersion; - TIntermNode *mTreeRoot; // root of parse tree being created - int mLoopNestingLevel; // 0 if outside all loops - int mStructNestingLevel; // incremented while parsing a struct declaration - int mSwitchNestingLevel; // 0 if outside all switch statements - const TType *mCurrentFunctionType; // the return type of the function that's currently being parsed - bool mFunctionReturnsValue; // true if a non-void function has a return - bool mChecksPrecisionErrors; // true if an error will be generated when a variable is declared without precision, explicit or implicit. + TIntermBlock *mTreeRoot; // root of parse tree being created + int mLoopNestingLevel; // 0 if outside all loops + int mStructNestingLevel; // incremented while parsing a struct declaration + int mSwitchNestingLevel; // 0 if outside all switch statements + const TType + *mCurrentFunctionType; // the return type of the function that's currently being parsed + bool mFunctionReturnsValue; // true if a non-void function has a return + bool mChecksPrecisionErrors; // true if an error will be generated when a variable is declared + // without precision, explicit or implicit. bool mFragmentPrecisionHighOnESSL1; // true if highp precision is supported when compiling // ESSL1. - TLayoutMatrixPacking mDefaultMatrixPacking; - TLayoutBlockStorage mDefaultBlockStorage; + TLayoutMatrixPacking mDefaultUniformMatrixPacking; + TLayoutBlockStorage mDefaultUniformBlockStorage; + TLayoutMatrixPacking mDefaultBufferMatrixPacking; + TLayoutBlockStorage mDefaultBufferBlockStorage; TString mHashErrMsg; - TDiagnostics mDiagnostics; + TDiagnostics *mDiagnostics; TDirectiveHandler mDirectiveHandler; pp::Preprocessor mPreprocessor; void *mScanner; - bool mUsesFragData; // track if we are using both gl_FragData and gl_FragColor + bool mUsesFragData; // track if we are using both gl_FragData and gl_FragColor bool mUsesFragColor; bool mUsesSecondaryOutputs; // Track if we are using either gl_SecondaryFragData or // gl_Secondary FragColor or both. int mMinProgramTexelOffset; int mMaxProgramTexelOffset; + + int mMinProgramTextureGatherOffset; + int mMaxProgramTextureGatherOffset; + + // keep track of local group size declared in layout. It should be declared only once. + bool mComputeShaderLocalSizeDeclared; + sh::WorkGroupSize mComputeShaderLocalSize; + // keep track of number of views declared in layout. + int mNumViews; + int mMaxNumViews; + int mMaxImageUnits; + int mMaxCombinedTextureImageUnits; + int mMaxUniformLocations; + int mMaxUniformBufferBindings; + int mMaxAtomicCounterBindings; + int mMaxShaderStorageBufferBindings; + + // keeps track whether we are declaring / defining a function + bool mDeclaringFunction; + + // Track the state of each atomic counter binding. + std::map mAtomicCounterBindingStates; + + // Track the geometry shader global parameters declared in layout. + TLayoutPrimitiveType mGeometryShaderInputPrimitiveType; + TLayoutPrimitiveType mGeometryShaderOutputPrimitiveType; + int mGeometryShaderInvocations; + int mGeometryShaderMaxVertices; + int mMaxGeometryShaderInvocations; + int mMaxGeometryShaderMaxVertices; + + // Track if all input array sizes are same and matches the latter input primitive declaration. + unsigned int mGeometryShaderInputArraySize; }; -int PaParseStrings( - size_t count, const char *const string[], const int length[], TParseContext *context); +int PaParseStrings(size_t count, + const char *const string[], + const int length[], + TParseContext *context); -#endif // COMPILER_TRANSLATOR_PARSECONTEXT_H_ +} // namespace sh + +#endif // COMPILER_TRANSLATOR_PARSECONTEXT_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/PoolAlloc.cpp b/src/3rdparty/angle/src/compiler/translator/PoolAlloc.cpp index 887cb66504..0f1cd8b5c9 100644 --- a/src/3rdparty/angle/src/compiler/translator/PoolAlloc.cpp +++ b/src/3rdparty/angle/src/compiler/translator/PoolAlloc.cpp @@ -6,16 +6,16 @@ #include "compiler/translator/PoolAlloc.h" -#include "compiler/translator/InitializeGlobals.h" - -#include "common/platform.h" -#include "common/angleutils.h" -#include "common/tls.h" - #include #include #include +#include "common/angleutils.h" +#include "common/debug.h" +#include "common/platform.h" +#include "common/tls.h" +#include "compiler/translator/InitializeGlobals.h" + TLSIndex PoolIndex = TLS_INVALID_INDEX; bool InitializePoolIndex() @@ -34,13 +34,13 @@ void FreePoolIndex() PoolIndex = TLS_INVALID_INDEX; } -TPoolAllocator* GetGlobalPoolAllocator() +TPoolAllocator *GetGlobalPoolAllocator() { assert(PoolIndex != TLS_INVALID_INDEX); - return static_cast(GetTLSValue(PoolIndex)); + return static_cast(GetTLSValue(PoolIndex)); } -void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator) +void SetGlobalPoolAllocator(TPoolAllocator *poolAllocator) { assert(PoolIndex != TLS_INVALID_INDEX); SetTLSValue(PoolIndex, poolAllocator); @@ -50,20 +50,38 @@ void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator) // Implement the functionality of the TPoolAllocator class, which // is documented in PoolAlloc.h. // -TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment) : - pageSize(growthIncrement), - alignment(allocationAlignment), - freeList(0), - inUseList(0), - numCalls(0), - totalBytes(0) +TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment) + : alignment(allocationAlignment), +#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + pageSize(growthIncrement), + freeList(0), + inUseList(0), + numCalls(0), + totalBytes(0), +#endif + mLocked(false) { + // + // Adjust alignment to be at least pointer aligned and + // power of 2. + // + size_t minAlign = sizeof(void *); + alignment &= ~(minAlign - 1); + if (alignment < minAlign) + alignment = minAlign; + size_t a = 1; + while (a < alignment) + a <<= 1; + alignment = a; + alignmentMask = a - 1; + +#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) // // Don't allow page sizes we know are smaller than all common // OS page sizes. // - if (pageSize < 4*1024) - pageSize = 4*1024; + if (pageSize < 4 * 1024) + pageSize = 4 * 1024; // // A large currentPageOffset indicates a new page needs to @@ -71,35 +89,27 @@ TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment) : // currentPageOffset = pageSize; - // - // Adjust alignment to be at least pointer aligned and - // power of 2. - // - size_t minAlign = sizeof(void*); - alignment &= ~(minAlign - 1); - if (alignment < minAlign) - alignment = minAlign; - size_t a = 1; - while (a < alignment) - a <<= 1; - alignment = a; - alignmentMask = a - 1; - // // Align header skip // headerSkip = minAlign; - if (headerSkip < sizeof(tHeader)) { + if (headerSkip < sizeof(tHeader)) + { headerSkip = (sizeof(tHeader) + alignmentMask) & ~alignmentMask; } +#else // !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + mStack.push_back({}); +#endif } TPoolAllocator::~TPoolAllocator() { - while (inUseList) { - tHeader* next = inUseList->nextPage; +#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + while (inUseList) + { + tHeader *next = inUseList->nextPage; inUseList->~tHeader(); - delete [] reinterpret_cast(inUseList); + delete[] reinterpret_cast(inUseList); inUseList = next; } @@ -107,11 +117,22 @@ TPoolAllocator::~TPoolAllocator() // here, because we did it already when the block was // placed into the free list. // - while (freeList) { - tHeader* next = freeList->nextPage; - delete [] reinterpret_cast(freeList); + while (freeList) + { + tHeader *next = freeList->nextPage; + delete[] reinterpret_cast(freeList); freeList = next; } +#else // !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + for (auto &allocs : mStack) + { + for (auto alloc : allocs) + { + free(alloc); + } + } + mStack.clear(); +#endif } // Support MSVC++ 6.0 @@ -120,28 +141,32 @@ const unsigned char TAllocation::guardBlockEndVal = 0xfe; const unsigned char TAllocation::userDataFill = 0xcd; #ifdef GUARD_BLOCKS - const size_t TAllocation::guardBlockSize = 16; +const size_t TAllocation::guardBlockSize = 16; #else - const size_t TAllocation::guardBlockSize = 0; +const size_t TAllocation::guardBlockSize = 0; #endif // // Check a single guard block for damage // -void TAllocation::checkGuardBlock(unsigned char* blockMem, unsigned char val, const char* locText) const +void TAllocation::checkGuardBlock(unsigned char *blockMem, + unsigned char val, + const char *locText) const { #ifdef GUARD_BLOCKS - for (size_t x = 0; x < guardBlockSize; x++) { - if (blockMem[x] != val) { + for (size_t x = 0; x < guardBlockSize; x++) + { + if (blockMem[x] != val) + { char assertMsg[80]; - // We don't print the assert message. It's here just to be helpful. +// We don't print the assert message. It's here just to be helpful. #if defined(_MSC_VER) - snprintf(assertMsg, sizeof(assertMsg), "PoolAlloc: Damage %s %Iu byte allocation at 0x%p\n", - locText, size, data()); + snprintf(assertMsg, sizeof(assertMsg), + "PoolAlloc: Damage %s %Iu byte allocation at 0x%p\n", locText, size, data()); #else - snprintf(assertMsg, sizeof(assertMsg), "PoolAlloc: Damage %s %zu byte allocation at 0x%p\n", - locText, size, data()); + snprintf(assertMsg, sizeof(assertMsg), + "PoolAlloc: Damage %s %zu byte allocation at 0x%p\n", locText, size, data()); #endif assert(0 && "PoolAlloc: Damage in guard block"); } @@ -149,17 +174,20 @@ void TAllocation::checkGuardBlock(unsigned char* blockMem, unsigned char val, co #endif } - void TPoolAllocator::push() { - tAllocState state = { currentPageOffset, inUseList }; +#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + tAllocState state = {currentPageOffset, inUseList}; + + mStack.push_back(state); - stack.push_back(state); - // // Indicate there is no current page to allocate from. // currentPageOffset = pageSize; +#else // !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + mStack.push_back({}); +#endif } // @@ -171,27 +199,37 @@ void TPoolAllocator::push() // void TPoolAllocator::pop() { - if (stack.size() < 1) + if (mStack.size() < 1) return; - tHeader* page = stack.back().page; - currentPageOffset = stack.back().offset; +#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + tHeader *page = mStack.back().page; + currentPageOffset = mStack.back().offset; - while (inUseList != page) { + while (inUseList != page) + { // invoke destructor to free allocation list inUseList->~tHeader(); - - tHeader* nextInUse = inUseList->nextPage; + + tHeader *nextInUse = inUseList->nextPage; if (inUseList->pageCount > 1) - delete [] reinterpret_cast(inUseList); - else { + delete[] reinterpret_cast(inUseList); + else + { inUseList->nextPage = freeList; - freeList = inUseList; + freeList = inUseList; } inUseList = nextInUse; } - stack.pop_back(); + mStack.pop_back(); +#else // !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + for (auto &alloc : mStack.back()) + { + free(alloc); + } + mStack.pop_back(); +#endif } // @@ -200,12 +238,15 @@ void TPoolAllocator::pop() // void TPoolAllocator::popAll() { - while (stack.size() > 0) + while (mStack.size() > 0) pop(); } -void* TPoolAllocator::allocate(size_t numBytes) +void *TPoolAllocator::allocate(size_t numBytes) { + ASSERT(!mLocked); + +#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) // // Just keep some interesting statistics. // @@ -226,18 +267,20 @@ void* TPoolAllocator::allocate(size_t numBytes) // Do the allocation, most likely case first, for efficiency. // This step could be moved to be inline sometime. // - if (allocationSize <= pageSize - currentPageOffset) { + if (allocationSize <= pageSize - currentPageOffset) + { // // Safe to allocate from currentPageOffset. // - unsigned char* memory = reinterpret_cast(inUseList) + currentPageOffset; + unsigned char *memory = reinterpret_cast(inUseList) + currentPageOffset; currentPageOffset += allocationSize; currentPageOffset = (currentPageOffset + alignmentMask) & ~alignmentMask; return initializeAllocation(inUseList, memory, numBytes); } - if (allocationSize > pageSize - headerSkip) { + if (allocationSize > pageSize - headerSkip) + { // // Do a multi-page allocation. Don't mix these with the others. // The OS is efficient and allocating and free-ing multiple pages. @@ -247,49 +290,71 @@ void* TPoolAllocator::allocate(size_t numBytes) if (numBytesToAlloc < allocationSize) return 0; - tHeader* memory = reinterpret_cast(::new char[numBytesToAlloc]); + tHeader *memory = reinterpret_cast(::new char[numBytesToAlloc]); if (memory == 0) return 0; // Use placement-new to initialize header - new(memory) tHeader(inUseList, (numBytesToAlloc + pageSize - 1) / pageSize); + new (memory) tHeader(inUseList, (numBytesToAlloc + pageSize - 1) / pageSize); inUseList = memory; currentPageOffset = pageSize; // make next allocation come from a new page // No guard blocks for multi-page allocations (yet) - return reinterpret_cast(reinterpret_cast(memory) + headerSkip); + return reinterpret_cast(reinterpret_cast(memory) + headerSkip); } // // Need a simple page to allocate from. // - tHeader* memory; - if (freeList) { - memory = freeList; + tHeader *memory; + if (freeList) + { + memory = freeList; freeList = freeList->nextPage; - } else { - memory = reinterpret_cast(::new char[pageSize]); + } + else + { + memory = reinterpret_cast(::new char[pageSize]); if (memory == 0) return 0; } // Use placement-new to initialize header - new(memory) tHeader(inUseList, 1); + new (memory) tHeader(inUseList, 1); inUseList = memory; - - unsigned char* ret = reinterpret_cast(inUseList) + headerSkip; - currentPageOffset = (headerSkip + allocationSize + alignmentMask) & ~alignmentMask; + + unsigned char *ret = reinterpret_cast(inUseList) + headerSkip; + currentPageOffset = (headerSkip + allocationSize + alignmentMask) & ~alignmentMask; return initializeAllocation(inUseList, ret, numBytes); +#else // !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + void *alloc = malloc(numBytes + alignmentMask); + mStack.back().push_back(alloc); + + intptr_t intAlloc = reinterpret_cast(alloc); + intAlloc = (intAlloc + alignmentMask) & ~alignmentMask; + return reinterpret_cast(intAlloc); +#endif } +void TPoolAllocator::lock() +{ + ASSERT(!mLocked); + mLocked = true; +} + +void TPoolAllocator::unlock() +{ + ASSERT(mLocked); + mLocked = false; +} // // Check all allocations in a list for damage by calling check on each. // void TAllocation::checkAllocList() const { - for (const TAllocation* alloc = this; alloc != 0; alloc = alloc->prevAlloc) + for (const TAllocation *alloc = this; alloc != 0; alloc = alloc->prevAlloc) alloc->check(); } diff --git a/src/3rdparty/angle/src/compiler/translator/PoolAlloc.h b/src/3rdparty/angle/src/compiler/translator/PoolAlloc.h index dab2926c90..ad63bc4cd6 100644 --- a/src/3rdparty/angle/src/compiler/translator/PoolAlloc.h +++ b/src/3rdparty/angle/src/compiler/translator/PoolAlloc.h @@ -13,8 +13,8 @@ // // This header defines an allocator that can be used to efficiently -// allocate a large number of small requests for heap memory, with the -// intention that they are not individually deallocated, but rather +// allocate a large number of small requests for heap memory, with the +// intention that they are not individually deallocated, but rather // collectively deallocated at one time. // // This simultaneously @@ -38,53 +38,58 @@ // If we are using guard blocks, we must track each indivual // allocation. If we aren't using guard blocks, these // never get instantiated, so won't have any impact. -// +// -class TAllocation { -public: - TAllocation(size_t size, unsigned char* mem, TAllocation* prev = 0) : - size(size), mem(mem), prevAlloc(prev) { - // Allocations are bracketed: - // [allocationHeader][initialGuardBlock][userData][finalGuardBlock] - // This would be cleaner with if (guardBlockSize)..., but that - // makes the compiler print warnings about 0 length memsets, - // even with the if() protecting them. +class TAllocation +{ + public: + TAllocation(size_t size, unsigned char *mem, TAllocation *prev = 0) + : size(size), mem(mem), prevAlloc(prev) + { +// Allocations are bracketed: +// [allocationHeader][initialGuardBlock][userData][finalGuardBlock] +// This would be cleaner with if (guardBlockSize)..., but that +// makes the compiler print warnings about 0 length memsets, +// even with the if() protecting them. #ifdef GUARD_BLOCKS memset(preGuard(), guardBlockBeginVal, guardBlockSize); - memset(data(), userDataFill, size); - memset(postGuard(), guardBlockEndVal, guardBlockSize); + memset(data(), userDataFill, size); + memset(postGuard(), guardBlockEndVal, guardBlockSize); #endif } - void check() const { - checkGuardBlock(preGuard(), guardBlockBeginVal, "before"); - checkGuardBlock(postGuard(), guardBlockEndVal, "after"); + void check() const + { + checkGuardBlock(preGuard(), guardBlockBeginVal, "before"); + checkGuardBlock(postGuard(), guardBlockEndVal, "after"); } void checkAllocList() const; // Return total size needed to accomodate user buffer of 'size', // plus our tracking data. - inline static size_t allocationSize(size_t size) { + inline static size_t allocationSize(size_t size) + { return size + 2 * guardBlockSize + headerSize(); } // Offset from surrounding buffer to get to user data buffer. - inline static unsigned char* offsetAllocation(unsigned char* m) { + inline static unsigned char *offsetAllocation(unsigned char *m) + { return m + guardBlockSize + headerSize(); } -private: - void checkGuardBlock(unsigned char* blockMem, unsigned char val, const char* locText) const; + private: + void checkGuardBlock(unsigned char *blockMem, unsigned char val, const char *locText) const; // Find offsets to pre and post guard blocks, and user data buffer - unsigned char* preGuard() const { return mem + headerSize(); } - unsigned char* data() const { return preGuard() + guardBlockSize; } - unsigned char* postGuard() const { return data() + size; } + unsigned char *preGuard() const { return mem + headerSize(); } + unsigned char *data() const { return preGuard() + guardBlockSize; } + unsigned char *postGuard() const { return data() + size; } - size_t size; // size of the user data area - unsigned char* mem; // beginning of our allocation (pts to header) - TAllocation* prevAlloc; // prior allocation in the chain + size_t size; // size of the user data area + unsigned char *mem; // beginning of our allocation (pts to header) + TAllocation *prevAlloc; // prior allocation in the chain // Support MSVC++ 6.0 const static unsigned char guardBlockBeginVal; @@ -101,7 +106,7 @@ private: // // There are several stacks. One is to track the pushing and popping -// of the user, and not yet implemented. The others are simply a +// of the user, and not yet implemented. The others are simply a // repositories of free pages or used pages. // // Page stacks are linked together with a simple header at the beginning @@ -110,12 +115,13 @@ private: // re-use. // // The "page size" used is not, nor must it match, the underlying OS -// page size. But, having it be about that size or equal to a set of +// page size. But, having it be about that size or equal to a set of // pages is likely most optimal. // -class TPoolAllocator { -public: - TPoolAllocator(int growthIncrement = 8*1024, int allocationAlignment = 16); +class TPoolAllocator +{ + public: + TPoolAllocator(int growthIncrement = 8 * 1024, int allocationAlignment = 16); // // Don't call the destructor just to free up the memory, call pop() @@ -143,7 +149,7 @@ public: // Call allocate() to actually acquire memory. Returns 0 if no memory // available, otherwise a properly aligned pointer to 'numBytes' of memory. // - void* allocate(size_t numBytes); + void *allocate(size_t numBytes); // // There is no deallocate. The point of this class is that @@ -152,75 +158,92 @@ public: // by calling pop(), and to not have to solve memory leak problems. // -protected: - friend struct tHeader; - - struct tHeader { - tHeader(tHeader* nextPage, size_t pageCount) : - nextPage(nextPage), - pageCount(pageCount) -#ifdef GUARD_BLOCKS - , lastAllocation(0) -#endif - { } + // Catch unwanted allocations. + // TODO(jmadill): Remove this when we remove the global allocator. + void lock(); + void unlock(); - ~tHeader() { + private: + size_t alignment; // all returned allocations will be aligned at + // this granularity, which will be a power of 2 + size_t alignmentMask; + +#if !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + friend struct tHeader; + + struct tHeader + { + tHeader(tHeader *nextPage, size_t pageCount) + : nextPage(nextPage), + pageCount(pageCount) +#ifdef GUARD_BLOCKS + , + lastAllocation(0) +#endif + { + } + + ~tHeader() + { #ifdef GUARD_BLOCKS if (lastAllocation) lastAllocation->checkAllocList(); #endif } - tHeader* nextPage; + tHeader *nextPage; size_t pageCount; #ifdef GUARD_BLOCKS - TAllocation* lastAllocation; + TAllocation *lastAllocation; #endif }; - struct tAllocState { + struct tAllocState + { size_t offset; - tHeader* page; + tHeader *page; }; typedef std::vector tAllocStack; // Track allocations if and only if we're using guard blocks - void* initializeAllocation(tHeader* block, unsigned char* memory, size_t numBytes) { + void *initializeAllocation(tHeader *block, unsigned char *memory, size_t numBytes) + { #ifdef GUARD_BLOCKS - new(memory) TAllocation(numBytes, memory, block->lastAllocation); - block->lastAllocation = reinterpret_cast(memory); + new (memory) TAllocation(numBytes, memory, block->lastAllocation); + block->lastAllocation = reinterpret_cast(memory); #endif // This is optimized entirely away if GUARD_BLOCKS is not defined. return TAllocation::offsetAllocation(memory); } - size_t pageSize; // granularity of allocation from the OS - size_t alignment; // all returned allocations will be aligned at - // this granularity, which will be a power of 2 - size_t alignmentMask; - size_t headerSkip; // amount of memory to skip to make room for the - // header (basically, size of header, rounded - // up to make it aligned + size_t pageSize; // granularity of allocation from the OS + size_t headerSkip; // amount of memory to skip to make room for the + // header (basically, size of header, rounded + // up to make it aligned size_t currentPageOffset; // next offset in top of inUseList to allocate from - tHeader* freeList; // list of popped memory - tHeader* inUseList; // list of all memory currently being used - tAllocStack stack; // stack of where to allocate from, to partition pool + tHeader *freeList; // list of popped memory + tHeader *inUseList; // list of all memory currently being used + tAllocStack mStack; // stack of where to allocate from, to partition pool - int numCalls; // just an interesting statistic - size_t totalBytes; // just an interesting statistic -private: - TPoolAllocator& operator=(const TPoolAllocator&); // dont allow assignment operator - TPoolAllocator(const TPoolAllocator&); // dont allow default copy constructor + int numCalls; // just an interesting statistic + size_t totalBytes; // just an interesting statistic + +#else // !defined(ANGLE_TRANSLATOR_DISABLE_POOL_ALLOC) + std::vector> mStack; +#endif + + TPoolAllocator &operator=(const TPoolAllocator &); // dont allow assignment operator + TPoolAllocator(const TPoolAllocator &); // dont allow default copy constructor + bool mLocked; }; - // // There could potentially be many pools with pops happening at // different times. But a simple use is to have a global pop // with everyone using the same global allocator. // -extern TPoolAllocator* GetGlobalPoolAllocator(); -extern void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator); +extern TPoolAllocator *GetGlobalPoolAllocator(); +extern void SetGlobalPoolAllocator(TPoolAllocator *poolAllocator); // // This STL compatible allocator is intended to be used as the allocator @@ -229,63 +252,68 @@ extern void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator); // It will use the pools for allocation, and not // do any deallocation, but will still do destruction. // -template -class pool_allocator { -public: +template +class pool_allocator +{ + public: typedef size_t size_type; typedef ptrdiff_t difference_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; + typedef T *pointer; + typedef const T *const_pointer; + typedef T &reference; + typedef const T &const_reference; typedef T value_type; - template - struct rebind { + template + struct rebind + { typedef pool_allocator other; }; pointer address(reference x) const { return &x; } const_pointer address(const_reference x) const { return &x; } - pool_allocator() { } - - template - pool_allocator(const pool_allocator& p) { } + pool_allocator() {} template - pool_allocator& operator=(const pool_allocator& p) { return *this; } + pool_allocator(const pool_allocator &p) + { + } + + template + pool_allocator &operator=(const pool_allocator &p) + { + return *this; + } #if defined(__SUNPRO_CC) && !defined(_RWSTD_ALLOCATOR) // libCStd on some platforms have a different allocate/deallocate interface. // Caller pre-bakes sizeof(T) into 'n' which is the number of bytes to be // allocated, not the number of elements. - void* allocate(size_type n) { - return getAllocator().allocate(n); - } - void* allocate(size_type n, const void*) { - return getAllocator().allocate(n); - } - void deallocate(void*, size_type) {} + void *allocate(size_type n) { return getAllocator().allocate(n); } + void *allocate(size_type n, const void *) { return getAllocator().allocate(n); } + void deallocate(void *, size_type) {} #else - pointer allocate(size_type n) { + pointer allocate(size_type n) + { return reinterpret_cast(getAllocator().allocate(n * sizeof(T))); } - pointer allocate(size_type n, const void*) { + pointer allocate(size_type n, const void *) + { return reinterpret_cast(getAllocator().allocate(n * sizeof(T))); } void deallocate(pointer, size_type) {} #endif // _RWSTD_ALLOCATOR - void construct(pointer p, const T& val) { new ((void *)p) T(val); } + void construct(pointer p, const T &val) { new ((void *)p) T(val); } void destroy(pointer p) { p->T::~T(); } - bool operator==(const pool_allocator& rhs) const { return true; } - bool operator!=(const pool_allocator& rhs) const { return false; } + bool operator==(const pool_allocator &rhs) const { return true; } + bool operator!=(const pool_allocator &rhs) const { return false; } size_type max_size() const { return static_cast(-1) / sizeof(T); } size_type max_size(int size) const { return static_cast(-1) / size; } - TPoolAllocator& getAllocator() const { return *GetGlobalPoolAllocator(); } + TPoolAllocator &getAllocator() const { return *GetGlobalPoolAllocator(); } }; -#endif // COMPILER_TRANSLATOR_POOLALLOC_H_ +#endif // COMPILER_TRANSLATOR_POOLALLOC_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/Pragma.h b/src/3rdparty/angle/src/compiler/translator/Pragma.h index 57b1134970..8c419fc17e 100644 --- a/src/3rdparty/angle/src/compiler/translator/Pragma.h +++ b/src/3rdparty/angle/src/compiler/translator/Pragma.h @@ -11,17 +11,16 @@ struct TPragma { struct STDGL { - STDGL() : invariantAll(false) { } + STDGL() : invariantAll(false) {} bool invariantAll; }; - // By default optimization is turned on and debug is turned off. // Precision emulation is turned on by default, but has no effect unless // the extension is enabled. - TPragma() : optimize(true), debug(false), debugShaderPrecision(true) { } - TPragma(bool o, bool d) : optimize(o), debug(d), debugShaderPrecision(true) { } + TPragma() : optimize(true), debug(false), debugShaderPrecision(true) {} + TPragma(bool o, bool d) : optimize(o), debug(d), debugShaderPrecision(true) {} bool optimize; bool debug; @@ -29,4 +28,4 @@ struct TPragma STDGL stdgl; }; -#endif // COMPILER_TRANSLATOR_PRAGMA_H_ +#endif // COMPILER_TRANSLATOR_PRAGMA_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/PruneEmptyDeclarations.cpp b/src/3rdparty/angle/src/compiler/translator/PruneEmptyDeclarations.cpp deleted file mode 100644 index ef62dbfce7..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/PruneEmptyDeclarations.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// -// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// The PruneEmptyDeclarations function prunes unnecessary empty declarations and declarators from the AST. - -#include "compiler/translator/PruneEmptyDeclarations.h" - -#include "compiler/translator/IntermNode.h" - -namespace -{ - -class PruneEmptyDeclarationsTraverser : private TIntermTraverser -{ - public: - static void apply(TIntermNode *root); - private: - PruneEmptyDeclarationsTraverser(); - bool visitAggregate(Visit, TIntermAggregate *node) override; -}; - -void PruneEmptyDeclarationsTraverser::apply(TIntermNode *root) -{ - PruneEmptyDeclarationsTraverser prune; - root->traverse(&prune); - prune.updateTree(); -} - -PruneEmptyDeclarationsTraverser::PruneEmptyDeclarationsTraverser() - : TIntermTraverser(true, false, false) -{ -} - -bool PruneEmptyDeclarationsTraverser::visitAggregate(Visit, TIntermAggregate *node) -{ - if (node->getOp() == EOpDeclaration) - { - TIntermSequence *sequence = node->getSequence(); - if (sequence->size() >= 1) - { - TIntermSymbol *sym = sequence->front()->getAsSymbolNode(); - // Prune declarations without a variable name, unless it's an interface block declaration. - if (sym != nullptr && sym->getSymbol() == "" && !sym->isInterfaceBlock()) - { - if (sequence->size() > 1) - { - // Generate a replacement that will remove the empty declarator in the beginning of a declarator - // list. Example of a declaration that will be changed: - // float, a; - // will be changed to - // float a; - // This applies also to struct declarations. - TIntermSequence emptyReplacement; - mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(node, sym, emptyReplacement)); - } - else if (sym->getBasicType() != EbtStruct) - { - // Single struct declarations may just declare the struct type and no variables, so they should - // not be pruned. All other single empty declarations can be pruned entirely. Example of an empty - // declaration that will be pruned: - // float; - TIntermSequence emptyReplacement; - TIntermAggregate *parentAgg = getParentNode()->getAsAggregate(); - ASSERT(parentAgg != nullptr); - mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(parentAgg, node, emptyReplacement)); - } - } - } - return false; - } - return true; -} - -} // namespace - -void PruneEmptyDeclarations(TIntermNode *root) -{ - PruneEmptyDeclarationsTraverser::apply(root); -} diff --git a/src/3rdparty/angle/src/compiler/translator/PruneEmptyDeclarations.h b/src/3rdparty/angle/src/compiler/translator/PruneEmptyDeclarations.h deleted file mode 100644 index 122e830902..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/PruneEmptyDeclarations.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// The PruneEmptyDeclarations function prunes unnecessary empty declarations and declarators from the AST. - -#ifndef COMPILER_TRANSLATOR_PRUNEEMPTYDECLARATIONS_H_ -#define COMPILER_TRANSLATOR_PRUNEEMPTYDECLARATIONS_H_ - -class TIntermNode; - -void PruneEmptyDeclarations(TIntermNode *root); - -#endif // COMPILER_TRANSLATOR_PRUNEEMPTYDECLARATIONS_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/PruneNoOps.cpp b/src/3rdparty/angle/src/compiler/translator/PruneNoOps.cpp new file mode 100644 index 0000000000..6c9a02cd1c --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/PruneNoOps.cpp @@ -0,0 +1,156 @@ +// +// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// PruneNoOps.cpp: The PruneNoOps function prunes: +// 1. Empty declarations "int;". Empty declarators will be pruned as well, so for example: +// int , a; +// is turned into +// int a; +// 2. Literal statements: "1.0;". The ESSL output doesn't define a default precision for float, +// so float literal statements would end up with no precision which is invalid ESSL. + +#include "compiler/translator/PruneNoOps.h" + +#include "compiler/translator/IntermTraverse.h" + +namespace sh +{ + +namespace +{ + +bool IsNoOp(TIntermNode *node) +{ + if (node->getAsConstantUnion() != nullptr) + { + return true; + } + bool isEmptyDeclaration = node->getAsDeclarationNode() != nullptr && + node->getAsDeclarationNode()->getSequence()->empty(); + if (isEmptyDeclaration) + { + return true; + } + return false; +} + +class PruneNoOpsTraverser : private TIntermTraverser +{ + public: + static void apply(TIntermBlock *root); + + private: + PruneNoOpsTraverser(); + bool visitDeclaration(Visit, TIntermDeclaration *node) override; + bool visitBlock(Visit visit, TIntermBlock *node) override; + bool visitLoop(Visit visit, TIntermLoop *loop) override; +}; + +void PruneNoOpsTraverser::apply(TIntermBlock *root) +{ + PruneNoOpsTraverser prune; + root->traverse(&prune); + prune.updateTree(); +} + +PruneNoOpsTraverser::PruneNoOpsTraverser() : TIntermTraverser(true, false, false) +{ +} + +bool PruneNoOpsTraverser::visitDeclaration(Visit, TIntermDeclaration *node) +{ + TIntermSequence *sequence = node->getSequence(); + if (sequence->size() >= 1) + { + TIntermSymbol *sym = sequence->front()->getAsSymbolNode(); + // Prune declarations without a variable name, unless it's an interface block declaration. + if (sym != nullptr && sym->getSymbol() == "" && !sym->isInterfaceBlock()) + { + if (sequence->size() > 1) + { + // Generate a replacement that will remove the empty declarator in the beginning of + // a declarator list. Example of a declaration that will be changed: + // float, a; + // will be changed to + // float a; + // This applies also to struct declarations. + TIntermSequence emptyReplacement; + mMultiReplacements.push_back( + NodeReplaceWithMultipleEntry(node, sym, emptyReplacement)); + } + else if (sym->getBasicType() != EbtStruct) + { + // If there are entirely empty non-struct declarations, they result in + // TIntermDeclaration nodes without any children in the parsing stage. These are + // handled in visitBlock and visitLoop. + UNREACHABLE(); + } + else if (sym->getType().getQualifier() != EvqGlobal && + sym->getType().getQualifier() != EvqTemporary) + { + // Single struct declarations may just declare the struct type and no variables, so + // they should not be pruned. Here we handle an empty struct declaration with a + // qualifier, for example like this: + // const struct a { int i; }; + // NVIDIA GL driver version 367.27 doesn't accept this kind of declarations, so we + // convert the declaration to a regular struct declaration. This is okay, since ESSL + // 1.00 spec section 4.1.8 says about structs that "The optional qualifiers only + // apply to any declarators, and are not part of the type being defined for name." + + if (mInGlobalScope) + { + sym->getTypePointer()->setQualifier(EvqGlobal); + } + else + { + sym->getTypePointer()->setQualifier(EvqTemporary); + } + } + } + } + return false; +} + +bool PruneNoOpsTraverser::visitBlock(Visit visit, TIntermBlock *node) +{ + TIntermSequence *statements = node->getSequence(); + + for (TIntermNode *statement : *statements) + { + if (IsNoOp(statement)) + { + TIntermSequence emptyReplacement; + mMultiReplacements.push_back( + NodeReplaceWithMultipleEntry(node, statement, emptyReplacement)); + } + } + + return true; +} + +bool PruneNoOpsTraverser::visitLoop(Visit visit, TIntermLoop *loop) +{ + TIntermTyped *expr = loop->getExpression(); + if (expr != nullptr && IsNoOp(expr)) + { + loop->setExpression(nullptr); + } + TIntermNode *init = loop->getInit(); + if (init != nullptr && IsNoOp(init)) + { + loop->setInit(nullptr); + } + + return true; +} + +} // namespace + +void PruneNoOps(TIntermBlock *root) +{ + PruneNoOpsTraverser::apply(root); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/PruneNoOps.h b/src/3rdparty/angle/src/compiler/translator/PruneNoOps.h new file mode 100644 index 0000000000..c421cecca4 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/PruneNoOps.h @@ -0,0 +1,24 @@ +// +// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// PruneNoOps.h: The PruneNoOps function prunes: +// 1. Empty declarations "int;". Empty declarators will be pruned as well, so for example: +// int , a; +// is turned into +// int a; +// 2. Literal statements: "1.0;". The ESSL output doesn't define a default precision for float, +// so float literal statements would end up with no precision which is invalid ESSL. + +#ifndef COMPILER_TRANSLATOR_PRUNENOOPS_H_ +#define COMPILER_TRANSLATOR_PRUNENOOPS_H_ + +namespace sh +{ +class TIntermBlock; + +void PruneNoOps(TIntermBlock *root); +} + +#endif // COMPILER_TRANSLATOR_PRUNENOOPS_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/QualifierAlive.cpp b/src/3rdparty/angle/src/compiler/translator/QualifierAlive.cpp deleted file mode 100644 index 3d950aab5a..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/QualifierAlive.cpp +++ /dev/null @@ -1,58 +0,0 @@ -// -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/translator/IntermNode.h" - -class TAliveTraverser : public TIntermTraverser { -public: - TAliveTraverser(TQualifier q) : TIntermTraverser(true, false, false, true), found(false), qualifier(q) - { - } - - bool wasFound() { return found; } - -protected: - bool found; - TQualifier qualifier; - - void visitSymbol(TIntermSymbol*); - bool visitSelection(Visit, TIntermSelection*); -}; - -// -// Report whether or not a variable of the given qualifier type -// is guaranteed written. Not always possible to determine if -// it is written conditionally. -// -// ?? It does not do this well yet, this is just a place holder -// that simply determines if it was reference at all, anywhere. -// -bool QualifierWritten(TIntermNode* node, TQualifier qualifier) -{ - TAliveTraverser it(qualifier); - - if (node) - node->traverse(&it); - - return it.wasFound(); -} - -void TAliveTraverser::visitSymbol(TIntermSymbol* node) -{ - // - // If it's what we're looking for, record it. - // - if (node->getQualifier() == qualifier) - found = true; -} - -bool TAliveTraverser::visitSelection(Visit, TIntermSelection*) -{ - if (wasFound()) - return false; - - return true; -} diff --git a/src/3rdparty/angle/src/compiler/translator/QualifierAlive.h b/src/3rdparty/angle/src/compiler/translator/QualifierAlive.h deleted file mode 100644 index 3e4f18012a..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/QualifierAlive.h +++ /dev/null @@ -1,12 +0,0 @@ -// -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_TRANSLATOR_QUALIFIERALIVE_H_ -#define COMPILER_TRANSLATOR_QUALIFIERALIVE_H_ - -bool QualifierWritten(TIntermNode* root, TQualifier); - -#endif // COMPILER_TRANSLATOR_QUALIFIERALIVE_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/QualifierTypes.cpp b/src/3rdparty/angle/src/compiler/translator/QualifierTypes.cpp new file mode 100644 index 0000000000..f748175957 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/QualifierTypes.cpp @@ -0,0 +1,784 @@ +// +// Copyright (c) 2002-2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/translator/QualifierTypes.h" + +#include "compiler/translator/Diagnostics.h" + +#include + +namespace sh +{ + +namespace +{ + +// GLSL ES 3.10 does not impose a strict order on type qualifiers and allows multiple layout +// declarations. +// GLSL ES 3.10 Revision 4, 4.10 Order of Qualification +bool AreTypeQualifierChecksRelaxed(int shaderVersion) +{ + return shaderVersion >= 310; +} + +bool IsScopeQualifier(TQualifier qualifier) +{ + return qualifier == EvqGlobal || qualifier == EvqTemporary; +} + +bool IsScopeQualifierWrapper(const TQualifierWrapperBase *qualifier) +{ + if (qualifier->getType() != QtStorage) + return false; + const TStorageQualifierWrapper *storageQualifier = + static_cast(qualifier); + TQualifier q = storageQualifier->getQualifier(); + return IsScopeQualifier(q); +} + +// Returns true if the invariant for the qualifier sequence holds +bool IsInvariantCorrect(const TTypeQualifierBuilder::QualifierSequence &qualifiers) +{ + // We should have at least one qualifier. + // The first qualifier always tells the scope. + return qualifiers.size() >= 1 && IsScopeQualifierWrapper(qualifiers[0]); +} + +// Returns true if there are qualifiers which have been specified multiple times +// If areQualifierChecksRelaxed is set to true, then layout qualifier repetition is allowed. +bool HasRepeatingQualifiers(const TTypeQualifierBuilder::QualifierSequence &qualifiers, + bool areQualifierChecksRelaxed, + std::string *errorMessage) +{ + bool invariantFound = false; + bool precisionFound = false; + bool layoutFound = false; + bool interpolationFound = false; + + unsigned int locationsSpecified = 0; + bool isOut = false; + + // The iteration starts from one since the first qualifier only reveals the scope of the + // expression. It is inserted first whenever the sequence gets created. + for (size_t i = 1; i < qualifiers.size(); ++i) + { + switch (qualifiers[i]->getType()) + { + case QtInvariant: + { + if (invariantFound) + { + *errorMessage = "The invariant qualifier specified multiple times."; + return true; + } + invariantFound = true; + break; + } + case QtPrecision: + { + if (precisionFound) + { + *errorMessage = "The precision qualifier specified multiple times."; + return true; + } + precisionFound = true; + break; + } + case QtLayout: + { + if (layoutFound && !areQualifierChecksRelaxed) + { + *errorMessage = "The layout qualifier specified multiple times."; + return true; + } + if (invariantFound && !areQualifierChecksRelaxed) + { + // This combination is not correct according to the syntax specified in the + // formal grammar in the ESSL 3.00 spec. In ESSL 3.10 the grammar does not have + // a similar restriction. + *errorMessage = + "The layout qualifier and invariant qualifier cannot coexist in the same " + "declaration according to the grammar."; + return true; + } + layoutFound = true; + const TLayoutQualifier ¤tQualifier = + static_cast(qualifiers[i])->getQualifier(); + locationsSpecified += currentQualifier.locationsSpecified; + break; + } + case QtInterpolation: + { + // 'centroid' is treated as a storage qualifier + // 'flat centroid' will be squashed to 'flat' + // 'smooth centroid' will be squashed to 'centroid' + if (interpolationFound) + { + *errorMessage = "The interpolation qualifier specified multiple times."; + return true; + } + interpolationFound = true; + break; + } + case QtStorage: + { + // Go over all of the storage qualifiers up until the current one and check for + // repetitions. + TQualifier currentQualifier = + static_cast(qualifiers[i])->getQualifier(); + if (currentQualifier == EvqVertexOut || currentQualifier == EvqFragmentOut) + { + isOut = true; + } + for (size_t j = 1; j < i; ++j) + { + if (qualifiers[j]->getType() == QtStorage) + { + const TStorageQualifierWrapper *previousQualifierWrapper = + static_cast(qualifiers[j]); + TQualifier previousQualifier = previousQualifierWrapper->getQualifier(); + if (currentQualifier == previousQualifier) + { + *errorMessage = previousQualifierWrapper->getQualifierString().c_str(); + *errorMessage += " specified multiple times"; + return true; + } + } + } + break; + } + case QtMemory: + { + // Go over all of the memory qualifiers up until the current one and check for + // repetitions. + // Having both readonly and writeonly in a sequence is valid. + // GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers + TQualifier currentQualifier = + static_cast(qualifiers[i])->getQualifier(); + for (size_t j = 1; j < i; ++j) + { + if (qualifiers[j]->getType() == QtMemory) + { + const TMemoryQualifierWrapper *previousQualifierWrapper = + static_cast(qualifiers[j]); + TQualifier previousQualifier = previousQualifierWrapper->getQualifier(); + if (currentQualifier == previousQualifier) + { + *errorMessage = previousQualifierWrapper->getQualifierString().c_str(); + *errorMessage += " specified multiple times"; + return true; + } + } + } + break; + } + default: + UNREACHABLE(); + } + } + + if (locationsSpecified > 1 && isOut) + { + // GLSL ES 3.00.6 section 4.3.8.2 Output Layout Qualifiers + // GLSL ES 3.10 section 4.4.2 Output Layout Qualifiers + // "The qualifier may appear at most once within a declaration." + *errorMessage = "Output layout location specified multiple times."; + return true; + } + + return false; +} + +// GLSL ES 3.00_6, 4.7 Order of Qualification +// The correct order of qualifiers is: +// invariant-qualifier interpolation-qualifier storage-qualifier precision-qualifier +// layout-qualifier has to be before storage-qualifier. +bool AreQualifiersInOrder(const TTypeQualifierBuilder::QualifierSequence &qualifiers, + std::string *errorMessage) +{ + bool foundInterpolation = false; + bool foundStorage = false; + bool foundPrecision = false; + for (size_t i = 1; i < qualifiers.size(); ++i) + { + switch (qualifiers[i]->getType()) + { + case QtInvariant: + if (foundInterpolation || foundStorage || foundPrecision) + { + *errorMessage = "The invariant qualifier has to be first in the expression."; + return false; + } + break; + case QtInterpolation: + if (foundStorage) + { + *errorMessage = "Storage qualifiers have to be after interpolation qualifiers."; + return false; + } + else if (foundPrecision) + { + *errorMessage = + "Precision qualifiers have to be after interpolation qualifiers."; + return false; + } + foundInterpolation = true; + break; + case QtLayout: + if (foundStorage) + { + *errorMessage = "Storage qualifiers have to be after layout qualifiers."; + return false; + } + else if (foundPrecision) + { + *errorMessage = "Precision qualifiers have to be after layout qualifiers."; + return false; + } + break; + case QtStorage: + if (foundPrecision) + { + *errorMessage = "Precision qualifiers have to be after storage qualifiers."; + return false; + } + foundStorage = true; + break; + case QtMemory: + if (foundPrecision) + { + *errorMessage = "Precision qualifiers have to be after memory qualifiers."; + return false; + } + break; + case QtPrecision: + foundPrecision = true; + break; + default: + UNREACHABLE(); + } + } + return true; +} + +struct QualifierComparator +{ + bool operator()(const TQualifierWrapperBase *q1, const TQualifierWrapperBase *q2) + { + return q1->getRank() < q2->getRank(); + } +}; + +void SortSequence(TTypeQualifierBuilder::QualifierSequence &qualifiers) +{ + // We need a stable sorting algorithm since the order of layout-qualifier declarations matter. + // The sorting starts from index 1, instead of 0, since the element at index 0 tells the scope + // and we always want it to be first. + std::stable_sort(qualifiers.begin() + 1, qualifiers.end(), QualifierComparator()); +} + +// Handles the joining of storage qualifiers for variables. +bool JoinVariableStorageQualifier(TQualifier *joinedQualifier, TQualifier storageQualifier) +{ + switch (*joinedQualifier) + { + case EvqGlobal: + *joinedQualifier = storageQualifier; + break; + case EvqTemporary: + { + switch (storageQualifier) + { + case EvqConst: + *joinedQualifier = storageQualifier; + break; + default: + return false; + } + break; + } + case EvqSmooth: + { + switch (storageQualifier) + { + case EvqCentroid: + *joinedQualifier = EvqCentroid; + break; + case EvqVertexOut: + case EvqGeometryOut: + *joinedQualifier = EvqSmoothOut; + break; + case EvqFragmentIn: + case EvqGeometryIn: + *joinedQualifier = EvqSmoothIn; + break; + default: + return false; + } + break; + } + case EvqFlat: + { + switch (storageQualifier) + { + case EvqCentroid: + *joinedQualifier = EvqFlat; + break; + case EvqVertexOut: + case EvqGeometryOut: + *joinedQualifier = EvqFlatOut; + break; + case EvqFragmentIn: + case EvqGeometryIn: + *joinedQualifier = EvqFlatIn; + break; + default: + return false; + } + break; + } + case EvqCentroid: + { + switch (storageQualifier) + { + case EvqVertexOut: + case EvqGeometryOut: + *joinedQualifier = EvqCentroidOut; + break; + case EvqFragmentIn: + case EvqGeometryIn: + *joinedQualifier = EvqCentroidIn; + break; + default: + return false; + } + break; + } + default: + return false; + } + return true; +} + +// Handles the joining of storage qualifiers for a parameter in a function. +bool JoinParameterStorageQualifier(TQualifier *joinedQualifier, TQualifier storageQualifier) +{ + switch (*joinedQualifier) + { + case EvqTemporary: + *joinedQualifier = storageQualifier; + break; + case EvqConst: + { + switch (storageQualifier) + { + case EvqIn: + *joinedQualifier = EvqConstReadOnly; + break; + default: + return false; + } + break; + } + default: + return false; + } + return true; +} + +bool JoinMemoryQualifier(TMemoryQualifier *joinedMemoryQualifier, TQualifier memoryQualifier) +{ + switch (memoryQualifier) + { + case EvqReadOnly: + joinedMemoryQualifier->readonly = true; + break; + case EvqWriteOnly: + joinedMemoryQualifier->writeonly = true; + break; + case EvqCoherent: + joinedMemoryQualifier->coherent = true; + break; + case EvqRestrict: + joinedMemoryQualifier->restrictQualifier = true; + break; + case EvqVolatile: + // Variables having the volatile qualifier are automatcally treated as coherent as well. + // GLSL ES 3.10, Revision 4, 4.9 Memory Access Qualifiers + joinedMemoryQualifier->volatileQualifier = true; + joinedMemoryQualifier->coherent = true; + break; + default: + UNREACHABLE(); + } + return true; +} + +TTypeQualifier GetVariableTypeQualifierFromSortedSequence( + const TTypeQualifierBuilder::QualifierSequence &sortedSequence, + TDiagnostics *diagnostics) +{ + TTypeQualifier typeQualifier( + static_cast(sortedSequence[0])->getQualifier(), + sortedSequence[0]->getLine()); + for (size_t i = 1; i < sortedSequence.size(); ++i) + { + const TQualifierWrapperBase *qualifier = sortedSequence[i]; + bool isQualifierValid = false; + switch (qualifier->getType()) + { + case QtInvariant: + isQualifierValid = true; + typeQualifier.invariant = true; + break; + case QtInterpolation: + { + switch (typeQualifier.qualifier) + { + case EvqGlobal: + isQualifierValid = true; + typeQualifier.qualifier = + static_cast(qualifier) + ->getQualifier(); + break; + default: + isQualifierValid = false; + } + break; + } + case QtLayout: + { + const TLayoutQualifierWrapper *layoutQualifierWrapper = + static_cast(qualifier); + isQualifierValid = true; + typeQualifier.layoutQualifier = sh::JoinLayoutQualifiers( + typeQualifier.layoutQualifier, layoutQualifierWrapper->getQualifier(), + layoutQualifierWrapper->getLine(), diagnostics); + break; + } + case QtStorage: + isQualifierValid = JoinVariableStorageQualifier( + &typeQualifier.qualifier, + static_cast(qualifier)->getQualifier()); + break; + case QtPrecision: + isQualifierValid = true; + typeQualifier.precision = + static_cast(qualifier)->getQualifier(); + ASSERT(typeQualifier.precision != EbpUndefined); + break; + case QtMemory: + isQualifierValid = JoinMemoryQualifier( + &typeQualifier.memoryQualifier, + static_cast(qualifier)->getQualifier()); + break; + default: + UNREACHABLE(); + } + if (!isQualifierValid) + { + const TString &qualifierString = qualifier->getQualifierString(); + diagnostics->error(qualifier->getLine(), "invalid qualifier combination", + qualifierString.c_str()); + break; + } + } + return typeQualifier; +} + +TTypeQualifier GetParameterTypeQualifierFromSortedSequence( + const TTypeQualifierBuilder::QualifierSequence &sortedSequence, + TDiagnostics *diagnostics) +{ + TTypeQualifier typeQualifier(EvqTemporary, sortedSequence[0]->getLine()); + for (size_t i = 1; i < sortedSequence.size(); ++i) + { + const TQualifierWrapperBase *qualifier = sortedSequence[i]; + bool isQualifierValid = false; + switch (qualifier->getType()) + { + case QtInvariant: + case QtInterpolation: + case QtLayout: + break; + case QtMemory: + isQualifierValid = JoinMemoryQualifier( + &typeQualifier.memoryQualifier, + static_cast(qualifier)->getQualifier()); + break; + case QtStorage: + isQualifierValid = JoinParameterStorageQualifier( + &typeQualifier.qualifier, + static_cast(qualifier)->getQualifier()); + break; + case QtPrecision: + isQualifierValid = true; + typeQualifier.precision = + static_cast(qualifier)->getQualifier(); + ASSERT(typeQualifier.precision != EbpUndefined); + break; + default: + UNREACHABLE(); + } + if (!isQualifierValid) + { + const TString &qualifierString = qualifier->getQualifierString(); + diagnostics->error(qualifier->getLine(), "invalid parameter qualifier", + qualifierString.c_str()); + break; + } + } + + switch (typeQualifier.qualifier) + { + case EvqIn: + case EvqConstReadOnly: // const in + case EvqOut: + case EvqInOut: + break; + case EvqConst: + typeQualifier.qualifier = EvqConstReadOnly; + break; + case EvqTemporary: + // no qualifier has been specified, set it to EvqIn which is the default + typeQualifier.qualifier = EvqIn; + break; + default: + diagnostics->error(sortedSequence[0]->getLine(), "Invalid parameter qualifier ", + getQualifierString(typeQualifier.qualifier)); + } + return typeQualifier; +} +} // namespace + +TLayoutQualifier JoinLayoutQualifiers(TLayoutQualifier leftQualifier, + TLayoutQualifier rightQualifier, + const TSourceLoc &rightQualifierLocation, + TDiagnostics *diagnostics) +{ + TLayoutQualifier joinedQualifier = leftQualifier; + + if (rightQualifier.location != -1) + { + joinedQualifier.location = rightQualifier.location; + ++joinedQualifier.locationsSpecified; + } + if (rightQualifier.yuv != false) + { + joinedQualifier.yuv = rightQualifier.yuv; + } + if (rightQualifier.binding != -1) + { + joinedQualifier.binding = rightQualifier.binding; + } + if (rightQualifier.offset != -1) + { + joinedQualifier.offset = rightQualifier.offset; + } + if (rightQualifier.matrixPacking != EmpUnspecified) + { + joinedQualifier.matrixPacking = rightQualifier.matrixPacking; + } + if (rightQualifier.blockStorage != EbsUnspecified) + { + joinedQualifier.blockStorage = rightQualifier.blockStorage; + } + + for (size_t i = 0u; i < rightQualifier.localSize.size(); ++i) + { + if (rightQualifier.localSize[i] != -1) + { + if (joinedQualifier.localSize[i] != -1 && + joinedQualifier.localSize[i] != rightQualifier.localSize[i]) + { + diagnostics->error(rightQualifierLocation, + "Cannot have multiple different work group size specifiers", + getWorkGroupSizeString(i)); + } + joinedQualifier.localSize[i] = rightQualifier.localSize[i]; + } + } + + if (rightQualifier.numViews != -1) + { + joinedQualifier.numViews = rightQualifier.numViews; + } + + if (rightQualifier.imageInternalFormat != EiifUnspecified) + { + joinedQualifier.imageInternalFormat = rightQualifier.imageInternalFormat; + } + + if (rightQualifier.primitiveType != EptUndefined) + { + if (joinedQualifier.primitiveType != EptUndefined && + joinedQualifier.primitiveType != rightQualifier.primitiveType) + { + diagnostics->error(rightQualifierLocation, + "Cannot have multiple different primitive specifiers", + getGeometryShaderPrimitiveTypeString(rightQualifier.primitiveType)); + } + joinedQualifier.primitiveType = rightQualifier.primitiveType; + } + + if (rightQualifier.invocations != 0) + { + if (joinedQualifier.invocations != 0 && + joinedQualifier.invocations != rightQualifier.invocations) + { + diagnostics->error(rightQualifierLocation, + "Cannot have multiple different invocations specifiers", + "invocations"); + } + joinedQualifier.invocations = rightQualifier.invocations; + } + + if (rightQualifier.maxVertices != -1) + { + if (joinedQualifier.maxVertices != -1 && + joinedQualifier.maxVertices != rightQualifier.maxVertices) + { + diagnostics->error(rightQualifierLocation, + "Cannot have multiple different max_vertices specifiers", + "max_vertices"); + } + joinedQualifier.maxVertices = rightQualifier.maxVertices; + } + + return joinedQualifier; +} + +unsigned int TInvariantQualifierWrapper::getRank() const +{ + return 0u; +} + +unsigned int TInterpolationQualifierWrapper::getRank() const +{ + return 1u; +} + +unsigned int TLayoutQualifierWrapper::getRank() const +{ + return 2u; +} + +unsigned int TStorageQualifierWrapper::getRank() const +{ + // Force the 'centroid' auxilary storage qualifier to be always first among all storage + // qualifiers. + if (mStorageQualifier == EvqCentroid) + { + return 3u; + } + else + { + return 4u; + } +} + +unsigned int TMemoryQualifierWrapper::getRank() const +{ + return 4u; +} + +unsigned int TPrecisionQualifierWrapper::getRank() const +{ + return 5u; +} + +TTypeQualifier::TTypeQualifier(TQualifier scope, const TSourceLoc &loc) + : layoutQualifier(TLayoutQualifier::Create()), + memoryQualifier(TMemoryQualifier::Create()), + precision(EbpUndefined), + qualifier(scope), + invariant(false), + line(loc) +{ + ASSERT(IsScopeQualifier(qualifier)); +} + +TTypeQualifierBuilder::TTypeQualifierBuilder(const TStorageQualifierWrapper *scope, + int shaderVersion) + : mShaderVersion(shaderVersion) +{ + ASSERT(IsScopeQualifier(scope->getQualifier())); + mQualifiers.push_back(scope); +} + +void TTypeQualifierBuilder::appendQualifier(const TQualifierWrapperBase *qualifier) +{ + mQualifiers.push_back(qualifier); +} + +bool TTypeQualifierBuilder::checkSequenceIsValid(TDiagnostics *diagnostics) const +{ + bool areQualifierChecksRelaxed = AreTypeQualifierChecksRelaxed(mShaderVersion); + std::string errorMessage; + if (HasRepeatingQualifiers(mQualifiers, areQualifierChecksRelaxed, &errorMessage)) + { + diagnostics->error(mQualifiers[0]->getLine(), errorMessage.c_str(), "qualifier sequence"); + return false; + } + + if (!areQualifierChecksRelaxed && !AreQualifiersInOrder(mQualifiers, &errorMessage)) + { + diagnostics->error(mQualifiers[0]->getLine(), errorMessage.c_str(), "qualifier sequence"); + return false; + } + + return true; +} + +TTypeQualifier TTypeQualifierBuilder::getParameterTypeQualifier(TDiagnostics *diagnostics) const +{ + ASSERT(IsInvariantCorrect(mQualifiers)); + ASSERT(static_cast(mQualifiers[0])->getQualifier() == + EvqTemporary); + + if (!checkSequenceIsValid(diagnostics)) + { + return TTypeQualifier(EvqTemporary, mQualifiers[0]->getLine()); + } + + // If the qualifier checks are relaxed, then it is easier to sort the qualifiers so + // that the order imposed by the GLSL ES 3.00 spec is kept. Then we can use the same code to + // combine the qualifiers. + if (AreTypeQualifierChecksRelaxed(mShaderVersion)) + { + // Copy the qualifier sequence so that we can sort them. + QualifierSequence sortedQualifierSequence = mQualifiers; + SortSequence(sortedQualifierSequence); + return GetParameterTypeQualifierFromSortedSequence(sortedQualifierSequence, diagnostics); + } + return GetParameterTypeQualifierFromSortedSequence(mQualifiers, diagnostics); +} + +TTypeQualifier TTypeQualifierBuilder::getVariableTypeQualifier(TDiagnostics *diagnostics) const +{ + ASSERT(IsInvariantCorrect(mQualifiers)); + + if (!checkSequenceIsValid(diagnostics)) + { + return TTypeQualifier( + static_cast(mQualifiers[0])->getQualifier(), + mQualifiers[0]->getLine()); + } + + // If the qualifier checks are relaxed, then it is easier to sort the qualifiers so + // that the order imposed by the GLSL ES 3.00 spec is kept. Then we can use the same code to + // combine the qualifiers. + if (AreTypeQualifierChecksRelaxed(mShaderVersion)) + { + // Copy the qualifier sequence so that we can sort them. + QualifierSequence sortedQualifierSequence = mQualifiers; + SortSequence(sortedQualifierSequence); + return GetVariableTypeQualifierFromSortedSequence(sortedQualifierSequence, diagnostics); + } + return GetVariableTypeQualifierFromSortedSequence(mQualifiers, diagnostics); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/QualifierTypes.h b/src/3rdparty/angle/src/compiler/translator/QualifierTypes.h new file mode 100644 index 0000000000..10bdeed89d --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/QualifierTypes.h @@ -0,0 +1,191 @@ +// +// Copyright (c) 2002-2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_TRANSLATOR_QUALIFIER_TYPES_H_ +#define COMPILER_TRANSLATOR_QUALIFIER_TYPES_H_ + +#include "common/angleutils.h" +#include "compiler/translator/BaseTypes.h" +#include "compiler/translator/Types.h" + +namespace sh +{ +class TDiagnostics; + +TLayoutQualifier JoinLayoutQualifiers(TLayoutQualifier leftQualifier, + TLayoutQualifier rightQualifier, + const TSourceLoc &rightQualifierLocation, + TDiagnostics *diagnostics); + +enum TQualifierType +{ + QtInvariant, + QtInterpolation, + QtLayout, + QtStorage, + QtPrecision, + QtMemory +}; + +class TQualifierWrapperBase : angle::NonCopyable +{ + public: + POOL_ALLOCATOR_NEW_DELETE(); + TQualifierWrapperBase(const TSourceLoc &line) : mLine(line) {} + virtual ~TQualifierWrapperBase(){}; + virtual TQualifierType getType() const = 0; + virtual TString getQualifierString() const = 0; + virtual unsigned int getRank() const = 0; + const TSourceLoc &getLine() const { return mLine; } + private: + TSourceLoc mLine; +}; + +class TInvariantQualifierWrapper final : public TQualifierWrapperBase +{ + public: + TInvariantQualifierWrapper(const TSourceLoc &line) : TQualifierWrapperBase(line) {} + ~TInvariantQualifierWrapper() {} + + TQualifierType getType() const { return QtInvariant; } + TString getQualifierString() const { return "invariant"; } + unsigned int getRank() const; +}; + +class TInterpolationQualifierWrapper final : public TQualifierWrapperBase +{ + public: + TInterpolationQualifierWrapper(TQualifier interpolationQualifier, const TSourceLoc &line) + : TQualifierWrapperBase(line), mInterpolationQualifier(interpolationQualifier) + { + } + ~TInterpolationQualifierWrapper() {} + + TQualifierType getType() const { return QtInterpolation; } + TString getQualifierString() const { return sh::getQualifierString(mInterpolationQualifier); } + TQualifier getQualifier() const { return mInterpolationQualifier; } + unsigned int getRank() const; + + private: + TQualifier mInterpolationQualifier; +}; + +class TLayoutQualifierWrapper final : public TQualifierWrapperBase +{ + public: + TLayoutQualifierWrapper(TLayoutQualifier layoutQualifier, const TSourceLoc &line) + : TQualifierWrapperBase(line), mLayoutQualifier(layoutQualifier) + { + } + ~TLayoutQualifierWrapper() {} + + TQualifierType getType() const { return QtLayout; } + TString getQualifierString() const { return "layout"; } + const TLayoutQualifier &getQualifier() const { return mLayoutQualifier; } + unsigned int getRank() const; + + private: + TLayoutQualifier mLayoutQualifier; +}; + +class TStorageQualifierWrapper final : public TQualifierWrapperBase +{ + public: + TStorageQualifierWrapper(TQualifier storageQualifier, const TSourceLoc &line) + : TQualifierWrapperBase(line), mStorageQualifier(storageQualifier) + { + } + ~TStorageQualifierWrapper() {} + + TQualifierType getType() const { return QtStorage; } + TString getQualifierString() const { return sh::getQualifierString(mStorageQualifier); } + TQualifier getQualifier() const { return mStorageQualifier; } + unsigned int getRank() const; + + private: + TQualifier mStorageQualifier; +}; + +class TPrecisionQualifierWrapper final : public TQualifierWrapperBase +{ + public: + TPrecisionQualifierWrapper(TPrecision precisionQualifier, const TSourceLoc &line) + : TQualifierWrapperBase(line), mPrecisionQualifier(precisionQualifier) + { + } + ~TPrecisionQualifierWrapper() {} + + TQualifierType getType() const { return QtPrecision; } + TString getQualifierString() const { return sh::getPrecisionString(mPrecisionQualifier); } + TPrecision getQualifier() const { return mPrecisionQualifier; } + unsigned int getRank() const; + + private: + TPrecision mPrecisionQualifier; +}; + +class TMemoryQualifierWrapper final : public TQualifierWrapperBase +{ + public: + TMemoryQualifierWrapper(TQualifier memoryQualifier, const TSourceLoc &line) + : TQualifierWrapperBase(line), mMemoryQualifier(memoryQualifier) + { + } + ~TMemoryQualifierWrapper() {} + + TQualifierType getType() const { return QtMemory; } + TString getQualifierString() const { return sh::getQualifierString(mMemoryQualifier); } + TQualifier getQualifier() const { return mMemoryQualifier; } + unsigned int getRank() const; + + private: + TQualifier mMemoryQualifier; +}; + +// TTypeQualifier tightly covers type_qualifier from the grammar +struct TTypeQualifier +{ + // initializes all of the qualifiers and sets the scope + TTypeQualifier(TQualifier scope, const TSourceLoc &loc); + + TLayoutQualifier layoutQualifier; + TMemoryQualifier memoryQualifier; + TPrecision precision; + TQualifier qualifier; + bool invariant; + TSourceLoc line; +}; + +// TTypeQualifierBuilder contains all of the qualifiers when type_qualifier gets parsed. +// It is to be used to validate the qualifier sequence and build a TTypeQualifier from it. +class TTypeQualifierBuilder : angle::NonCopyable +{ + public: + using QualifierSequence = TVector; + + public: + POOL_ALLOCATOR_NEW_DELETE(); + TTypeQualifierBuilder(const TStorageQualifierWrapper *scope, int shaderVersion); + // Adds the passed qualifier to the end of the sequence. + void appendQualifier(const TQualifierWrapperBase *qualifier); + // Checks for the order of qualification and repeating qualifiers. + bool checkSequenceIsValid(TDiagnostics *diagnostics) const; + // Goes over the qualifier sequence and parses it to form a type qualifier for a function + // parameter. + // The returned object is initialized even if the parsing fails. + TTypeQualifier getParameterTypeQualifier(TDiagnostics *diagnostics) const; + // Goes over the qualifier sequence and parses it to form a type qualifier for a variable. + // The returned object is initialized even if the parsing fails. + TTypeQualifier getVariableTypeQualifier(TDiagnostics *diagnostics) const; + + private: + QualifierSequence mQualifiers; + int mShaderVersion; +}; + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_QUALIFIER_TYPES_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/RecordConstantPrecision.cpp b/src/3rdparty/angle/src/compiler/translator/RecordConstantPrecision.cpp index 14e88b749a..5233a29f19 100644 --- a/src/3rdparty/angle/src/compiler/translator/RecordConstantPrecision.cpp +++ b/src/3rdparty/angle/src/compiler/translator/RecordConstantPrecision.cpp @@ -3,20 +3,24 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// During parsing, all constant expressions are folded to constant union nodes. The expressions that have been -// folded may have had precision qualifiers, which should affect the precision of the consuming operation. -// If the folded constant union nodes are written to output as such they won't have any precision qualifiers, -// and their effect on the precision of the consuming operation is lost. +// During parsing, all constant expressions are folded to constant union nodes. The expressions that +// have been folded may have had precision qualifiers, which should affect the precision of the +// consuming operation. If the folded constant union nodes are written to output as such they won't +// have any precision qualifiers, and their effect on the precision of the consuming operation is +// lost. // -// RecordConstantPrecision is an AST traverser that inspects the precision qualifiers of constants and hoists -// the constants outside the containing expression as precision qualified named variables in case that is -// required for correct precision propagation. +// RecordConstantPrecision is an AST traverser that inspects the precision qualifiers of constants +// and hoists the constants outside the containing expression as precision qualified named variables +// in case that is required for correct precision propagation. // #include "compiler/translator/RecordConstantPrecision.h" #include "compiler/translator/InfoSink.h" -#include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermTraverse.h" + +namespace sh +{ namespace { @@ -24,7 +28,7 @@ namespace class RecordConstantPrecisionTraverser : public TIntermTraverser { public: - RecordConstantPrecisionTraverser(); + RecordConstantPrecisionTraverser(TSymbolTable *symbolTable); void visitConstantUnion(TIntermConstantUnion *node) override; @@ -37,14 +41,18 @@ class RecordConstantPrecisionTraverser : public TIntermTraverser bool mFoundHigherPrecisionConstant; }; -RecordConstantPrecisionTraverser::RecordConstantPrecisionTraverser() - : TIntermTraverser(true, false, true), - mFoundHigherPrecisionConstant(false) +RecordConstantPrecisionTraverser::RecordConstantPrecisionTraverser(TSymbolTable *symbolTable) + : TIntermTraverser(true, false, true, symbolTable), mFoundHigherPrecisionConstant(false) { } bool RecordConstantPrecisionTraverser::operandAffectsParentOperationPrecision(TIntermTyped *operand) { + if (getParentNode()->getAsCaseNode() || getParentNode()->getAsBlock()) + { + return false; + } + const TIntermBinary *parentAsBinary = getParentNode()->getAsBinaryNode(); if (parentAsBinary != nullptr) { @@ -52,15 +60,15 @@ bool RecordConstantPrecisionTraverser::operandAffectsParentOperationPrecision(TI // its precision has no effect. switch (parentAsBinary->getOp()) { - case EOpInitialize: - case EOpAssign: - case EOpIndexDirect: - case EOpIndexDirectStruct: - case EOpIndexDirectInterfaceBlock: - case EOpIndexIndirect: - return false; - default: - break; + case EOpInitialize: + case EOpAssign: + case EOpIndexDirect: + case EOpIndexDirectStruct: + case EOpIndexDirectInterfaceBlock: + case EOpIndexIndirect: + return false; + default: + break; } TIntermTyped *otherOperand = parentAsBinary->getRight(); @@ -68,9 +76,10 @@ bool RecordConstantPrecisionTraverser::operandAffectsParentOperationPrecision(TI { otherOperand = parentAsBinary->getLeft(); } - // If the precision of the other child is at least as high as the precision of the constant, the precision of - // the constant has no effect. - if (otherOperand->getAsConstantUnion() == nullptr && otherOperand->getPrecision() >= operand->getPrecision()) + // If the precision of the other child is at least as high as the precision of the constant, + // the precision of the constant has no effect. + if (otherOperand->getAsConstantUnion() == nullptr && + otherOperand->getPrecision() >= operand->getPrecision()) { return false; } @@ -92,14 +101,15 @@ bool RecordConstantPrecisionTraverser::operandAffectsParentOperationPrecision(TI { return false; } - // If the precision of operands does affect the result, but the precision of any of the other children - // has a precision that's at least as high as the precision of the constant, the precision of the constant - // has no effect. + // If the precision of operands does affect the result, but the precision of any of the + // other children has a precision that's at least as high as the precision of the constant, + // the precision of the constant has no effect. TIntermSequence *parameters = parentAsAggregate->getSequence(); for (TIntermNode *parameter : *parameters) { const TIntermTyped *typedParameter = parameter->getAsTyped(); - if (parameter != operand && typedParameter != nullptr && parameter->getAsConstantUnion() == nullptr && + if (parameter != operand && typedParameter != nullptr && + parameter->getAsConstantUnion() == nullptr && typedParameter->getPrecision() >= operand->getPrecision()) { return false; @@ -114,37 +124,36 @@ void RecordConstantPrecisionTraverser::visitConstantUnion(TIntermConstantUnion * if (mFoundHigherPrecisionConstant) return; - // If the constant has lowp or undefined precision, it can't increase the precision of consuming operations. + // If the constant has lowp or undefined precision, it can't increase the precision of consuming + // operations. if (node->getPrecision() < EbpMedium) return; - // It's possible the node has no effect on the precision of the consuming expression, depending on the - // consuming expression, and the precision of the other parameters of the expression. + // It's possible the node has no effect on the precision of the consuming expression, depending + // on the consuming expression, and the precision of the other parameters of the expression. if (!operandAffectsParentOperationPrecision(node)) return; - // Make the constant a precision-qualified named variable to make sure it affects the precision of the consuming - // expression. + // Make the constant a precision-qualified named variable to make sure it affects the precision + // of the consuming expression. TIntermSequence insertions; insertions.push_back(createTempInitDeclaration(node, EvqConst)); insertStatementsInParentBlock(insertions); - mReplacements.push_back(NodeUpdateEntry(getParentNode(), node, createTempSymbol(node->getType()), false)); + queueReplacement(createTempSymbol(node->getType()), OriginalNode::IS_DROPPED); mFoundHigherPrecisionConstant = true; } void RecordConstantPrecisionTraverser::nextIteration() { - nextTemporaryIndex(); + nextTemporaryId(); mFoundHigherPrecisionConstant = false; } -} // namespace +} // namespace -void RecordConstantPrecision(TIntermNode *root, unsigned int *temporaryIndex) +void RecordConstantPrecision(TIntermNode *root, TSymbolTable *symbolTable) { - RecordConstantPrecisionTraverser traverser; - ASSERT(temporaryIndex != nullptr); - traverser.useTemporaryIndex(temporaryIndex); + RecordConstantPrecisionTraverser traverser(symbolTable); // Iterate as necessary, and reset the traverser between iterations. do { @@ -152,6 +161,7 @@ void RecordConstantPrecision(TIntermNode *root, unsigned int *temporaryIndex) root->traverse(&traverser); if (traverser.foundHigherPrecisionConstant()) traverser.updateTree(); - } - while (traverser.foundHigherPrecisionConstant()); + } while (traverser.foundHigherPrecisionConstant()); } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/RecordConstantPrecision.h b/src/3rdparty/angle/src/compiler/translator/RecordConstantPrecision.h index 2cd401b418..f86c2a8693 100644 --- a/src/3rdparty/angle/src/compiler/translator/RecordConstantPrecision.h +++ b/src/3rdparty/angle/src/compiler/translator/RecordConstantPrecision.h @@ -3,21 +3,26 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// During parsing, all constant expressions are folded to constant union nodes. The expressions that have been -// folded may have had precision qualifiers, which should affect the precision of the consuming operation. -// If the folded constant union nodes are written to output as such they won't have any precision qualifiers, -// and their effect on the precision of the consuming operation is lost. +// During parsing, all constant expressions are folded to constant union nodes. The expressions that +// have been folded may have had precision qualifiers, which should affect the precision of the +// consuming operation. If the folded constant union nodes are written to output as such they won't +// have any precision qualifiers, and their effect on the precision of the consuming operation is +// lost. // -// RecordConstantPrecision is an AST traverser that inspects the precision qualifiers of constants and hoists -// the constants outside the containing expression as precision qualified named variables in case that is -// required for correct precision propagation. +// RecordConstantPrecision is an AST traverser that inspects the precision qualifiers of constants +// and hoists the constants outside the containing expression as precision qualified named variables +// in case that is required for correct precision propagation. // #ifndef COMPILER_TRANSLATOR_RECORDCONSTANTPRECISION_H_ #define COMPILER_TRANSLATOR_RECORDCONSTANTPRECISION_H_ +namespace sh +{ class TIntermNode; +class TSymbolTable; -void RecordConstantPrecision(TIntermNode *root, unsigned int *temporaryIndex); +void RecordConstantPrecision(TIntermNode *root, TSymbolTable *symbolTable); +} // namespace sh -#endif // COMPILER_TRANSLATOR_RECORDCONSTANTPRECISION_H_ +#endif // COMPILER_TRANSLATOR_RECORDCONSTANTPRECISION_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/RegenerateStructNames.cpp b/src/3rdparty/angle/src/compiler/translator/RegenerateStructNames.cpp index 5e0db2ad26..55fb124a42 100644 --- a/src/3rdparty/angle/src/compiler/translator/RegenerateStructNames.cpp +++ b/src/3rdparty/angle/src/compiler/translator/RegenerateStructNames.cpp @@ -7,6 +7,9 @@ #include "common/debug.h" #include "compiler/translator/RegenerateStructNames.h" +namespace sh +{ + void RegenerateStructNames::visitSymbol(TIntermSymbol *symbol) { ASSERT(symbol); @@ -16,7 +19,7 @@ void RegenerateStructNames::visitSymbol(TIntermSymbol *symbol) if (!userType) return; - if (mSymbolTable.findBuiltIn(userType->name(), mShaderVersion)) + if (mSymbolTable->findBuiltIn(userType->name(), mShaderVersion)) { // Built-in struct, do not touch it. return; @@ -53,30 +56,21 @@ void RegenerateStructNames::visitSymbol(TIntermSymbol *symbol) return; } std::string id = Str(uniqueId); - TString tmp = kPrefix + TString(id.c_str()); + TString tmp = kPrefix + TString(id.c_str()); tmp += "_" + userType->name(); userType->setName(tmp); } -bool RegenerateStructNames::visitAggregate(Visit, TIntermAggregate *aggregate) +bool RegenerateStructNames::visitBlock(Visit, TIntermBlock *block) { - ASSERT(aggregate); - switch (aggregate->getOp()) + ++mScopeDepth; + TIntermSequence &sequence = *(block->getSequence()); + for (TIntermNode *node : sequence) { - case EOpSequence: - ++mScopeDepth; - { - TIntermSequence &sequence = *(aggregate->getSequence()); - for (size_t ii = 0; ii < sequence.size(); ++ii) - { - TIntermNode *node = sequence[ii]; - ASSERT(node != NULL); - node->traverse(this); - } - } - --mScopeDepth; - return false; - default: - return true; + node->traverse(this); } + --mScopeDepth; + return false; } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/RegenerateStructNames.h b/src/3rdparty/angle/src/compiler/translator/RegenerateStructNames.h index 3b98e5d709..293720b6a4 100644 --- a/src/3rdparty/angle/src/compiler/translator/RegenerateStructNames.h +++ b/src/3rdparty/angle/src/compiler/translator/RegenerateStructNames.h @@ -7,27 +7,29 @@ #ifndef COMPILER_TRANSLATOR_REGENERATESTRUCTNAMES_H_ #define COMPILER_TRANSLATOR_REGENERATESTRUCTNAMES_H_ -#include "compiler/translator/Intermediate.h" +#include "compiler/translator/IntermTraverse.h" #include "compiler/translator/SymbolTable.h" #include +namespace sh +{ + class RegenerateStructNames : public TIntermTraverser { public: - RegenerateStructNames(const TSymbolTable &symbolTable, - int shaderVersion) - : TIntermTraverser(true, false, false), - mSymbolTable(symbolTable), + RegenerateStructNames(TSymbolTable *symbolTable, int shaderVersion) + : TIntermTraverser(true, false, false, symbolTable), mShaderVersion(shaderVersion), - mScopeDepth(0) {} + mScopeDepth(0) + { + } protected: void visitSymbol(TIntermSymbol *) override; - bool visitAggregate(Visit, TIntermAggregate *) override; + bool visitBlock(Visit, TIntermBlock *block) override; private: - const TSymbolTable &mSymbolTable; int mShaderVersion; // Indicating the depth of the current scope. @@ -38,4 +40,6 @@ class RegenerateStructNames : public TIntermTraverser std::set mDeclaredGlobalStructs; }; +} // namespace sh + #endif // COMPILER_TRANSLATOR_REGENERATESTRUCTNAMES_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/RemoveArrayLengthMethod.cpp b/src/3rdparty/angle/src/compiler/translator/RemoveArrayLengthMethod.cpp new file mode 100644 index 0000000000..e9e6a17013 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/RemoveArrayLengthMethod.cpp @@ -0,0 +1,83 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// RemoveArrayLengthMethod.cpp: +// Fold array length expressions, including cases where the "this" node has side effects. +// Example: +// int i = (a = b).length(); +// int j = (func()).length(); +// becomes: +// (a = b); +// int i = ; +// func(); +// int j = ; +// +// Must be run after SplitSequenceOperator, SimplifyLoopConditions and SeparateDeclarations steps +// have been done to expressions containing calls of the array length method. +// +// Does nothing to length method calls done on runtime-sized arrays. + +#include "compiler/translator/RemoveArrayLengthMethod.h" + +#include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermTraverse.h" + +namespace sh +{ + +namespace +{ + +class RemoveArrayLengthTraverser : public TIntermTraverser +{ + public: + RemoveArrayLengthTraverser() : TIntermTraverser(true, false, false), mFoundArrayLength(false) {} + + bool visitUnary(Visit visit, TIntermUnary *node) override; + + void nextIteration() { mFoundArrayLength = false; } + + bool foundArrayLength() const { return mFoundArrayLength; } + + private: + bool mFoundArrayLength; +}; + +bool RemoveArrayLengthTraverser::visitUnary(Visit visit, TIntermUnary *node) +{ + // The only case where we leave array length() in place is for runtime-sized arrays. + if (node->getOp() == EOpArrayLength && !node->getOperand()->getType().isUnsizedArray()) + { + mFoundArrayLength = true; + if (!node->getOperand()->hasSideEffects()) + { + queueReplacement(node->fold(nullptr), OriginalNode::IS_DROPPED); + return false; + } + insertStatementInParentBlock(node->getOperand()->deepCopy()); + TConstantUnion *constArray = new TConstantUnion[1]; + constArray->setIConst(node->getOperand()->getOutermostArraySize()); + queueReplacement(new TIntermConstantUnion(constArray, node->getType()), + OriginalNode::IS_DROPPED); + return false; + } + return true; +} + +} // anonymous namespace + +void RemoveArrayLengthMethod(TIntermBlock *root) +{ + RemoveArrayLengthTraverser traverser; + do + { + traverser.nextIteration(); + root->traverse(&traverser); + if (traverser.foundArrayLength()) + traverser.updateTree(); + } while (traverser.foundArrayLength()); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/RemoveArrayLengthMethod.h b/src/3rdparty/angle/src/compiler/translator/RemoveArrayLengthMethod.h new file mode 100644 index 0000000000..3b2c6df824 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/RemoveArrayLengthMethod.h @@ -0,0 +1,29 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// RemoveArrayLengthMethod.h: +// Fold array length expressions, including cases where the "this" node has side effects. +// Example: +// int i = (a = b).length(); +// int j = (func()).length(); +// becomes: +// (a = b); +// int i = ; +// func(); +// int j = ; +// +// Must be run after SplitSequenceOperator, SimplifyLoopConditions and SeparateDeclarations steps +// have been done to expressions containing calls of the array length method. +// +// Does nothing to length method calls done on runtime-sized arrays. + +namespace sh +{ + +class TIntermBlock; + +void RemoveArrayLengthMethod(TIntermBlock *root); + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/RemoveDynamicIndexing.cpp b/src/3rdparty/angle/src/compiler/translator/RemoveDynamicIndexing.cpp index 74814f22a7..7766c1abc6 100644 --- a/src/3rdparty/angle/src/compiler/translator/RemoveDynamicIndexing.cpp +++ b/src/3rdparty/angle/src/compiler/translator/RemoveDynamicIndexing.cpp @@ -9,14 +9,20 @@ #include "compiler/translator/RemoveDynamicIndexing.h" +#include "compiler/translator/Diagnostics.h" #include "compiler/translator/InfoSink.h" -#include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermNodePatternMatcher.h" +#include "compiler/translator/IntermNode_util.h" +#include "compiler/translator/IntermTraverse.h" #include "compiler/translator/SymbolTable.h" +namespace sh +{ + namespace { -TName GetIndexFunctionName(const TType &type, bool write) +std::string GetIndexFunctionName(const TType &type, bool write) { TInfoSinkBase nameSink; nameSink << "dyn_index_"; @@ -49,31 +55,29 @@ TName GetIndexFunctionName(const TType &type, bool write) } nameSink << type.getNominalSize(); } - TString nameString = TFunction::mangleName(nameSink.c_str()); - TName name(nameString); - name.setInternal(true); - return name; + return nameSink.str(); } -TIntermSymbol *CreateBaseSymbol(const TType &type, TQualifier qualifier) +TIntermSymbol *CreateBaseSymbol(const TType &type, TQualifier qualifier, TSymbolTable *symbolTable) { - TIntermSymbol *symbol = new TIntermSymbol(0, "base", type); + TIntermSymbol *symbol = new TIntermSymbol(symbolTable->nextUniqueId(), "base", type); symbol->setInternal(true); symbol->getTypePointer()->setQualifier(qualifier); return symbol; } -TIntermSymbol *CreateIndexSymbol() +TIntermSymbol *CreateIndexSymbol(TSymbolTable *symbolTable) { - TIntermSymbol *symbol = new TIntermSymbol(0, "index", TType(EbtInt, EbpHigh)); + TIntermSymbol *symbol = + new TIntermSymbol(symbolTable->nextUniqueId(), "index", TType(EbtInt, EbpHigh)); symbol->setInternal(true); symbol->getTypePointer()->setQualifier(EvqIn); return symbol; } -TIntermSymbol *CreateValueSymbol(const TType &type) +TIntermSymbol *CreateValueSymbol(const TType &type, TSymbolTable *symbolTable) { - TIntermSymbol *symbol = new TIntermSymbol(0, "value", type); + TIntermSymbol *symbol = new TIntermSymbol(symbolTable->nextUniqueId(), "value", type); symbol->setInternal(true); symbol->getTypePointer()->setQualifier(EvqIn); return symbol; @@ -86,38 +90,14 @@ TIntermConstantUnion *CreateIntConstantNode(int i) return new TIntermConstantUnion(constant, TType(EbtInt, EbpHigh)); } -TIntermBinary *CreateIndexDirectBaseSymbolNode(const TType &indexedType, - const TType &fieldType, - const int index, - TQualifier baseQualifier) -{ - TIntermBinary *indexNode = new TIntermBinary(EOpIndexDirect); - indexNode->setType(fieldType); - TIntermSymbol *baseSymbol = CreateBaseSymbol(indexedType, baseQualifier); - indexNode->setLeft(baseSymbol); - indexNode->setRight(CreateIntConstantNode(index)); - return indexNode; -} - -TIntermBinary *CreateAssignValueSymbolNode(TIntermTyped *targetNode, const TType &assignedValueType) -{ - TIntermBinary *assignNode = new TIntermBinary(EOpAssign); - assignNode->setType(assignedValueType); - assignNode->setLeft(targetNode); - assignNode->setRight(CreateValueSymbol(assignedValueType)); - return assignNode; -} - TIntermTyped *EnsureSignedInt(TIntermTyped *node) { if (node->getBasicType() == EbtInt) return node; - TIntermAggregate *convertedNode = new TIntermAggregate(EOpConstructInt); - convertedNode->setType(TType(EbtInt)); - convertedNode->getSequence()->push_back(node); - convertedNode->setPrecisionFromChildren(); - return convertedNode; + TIntermSequence *arguments = new TIntermSequence(); + arguments->push_back(node); + return TIntermAggregate::CreateConstructor(TType(EbtInt), arguments); } TType GetFieldType(const TType &indexedType) @@ -177,7 +157,10 @@ TType GetFieldType(const TType &indexedType) // base[1] = value; // } // Note that else is not used in above functions to avoid the RewriteElseBlocks transformation. -TIntermAggregate *GetIndexFunctionDefinition(TType type, bool write) +TIntermFunctionDefinition *GetIndexFunctionDefinition(TType type, + bool write, + const TSymbolUniqueId &functionId, + TSymbolTable *symbolTable) { ASSERT(!type.isArray()); // Conservatively use highp here, even if the indexed type is not highp. That way the code can't @@ -185,11 +168,9 @@ TIntermAggregate *GetIndexFunctionDefinition(TType type, bool write) // highp values are being indexed in the shader. For HLSL precision doesn't matter, but in // principle this code could be used with multiple backends. type.setPrecision(EbpHigh); - TIntermAggregate *indexingFunction = new TIntermAggregate(EOpFunction); - indexingFunction->setNameObj(GetIndexFunctionName(type, write)); TType fieldType = GetFieldType(type); - int numCases = 0; + int numCases = 0; if (type.isMatrix()) { numCases = type.getCols(); @@ -198,41 +179,43 @@ TIntermAggregate *GetIndexFunctionDefinition(TType type, bool write) { numCases = type.getNominalSize(); } - if (write) + + TType returnType(EbtVoid); + if (!write) { - indexingFunction->setType(TType(EbtVoid)); - } - else - { - indexingFunction->setType(fieldType); + returnType = fieldType; } - TIntermAggregate *paramsNode = new TIntermAggregate(EOpParameters); - TQualifier baseQualifier = EvqInOut; + std::string functionName = GetIndexFunctionName(type, write); + TIntermFunctionPrototype *prototypeNode = + CreateInternalFunctionPrototypeNode(returnType, functionName.c_str(), functionId); + + TQualifier baseQualifier = EvqInOut; if (!write) baseQualifier = EvqIn; - TIntermSymbol *baseParam = CreateBaseSymbol(type, baseQualifier); - paramsNode->getSequence()->push_back(baseParam); - TIntermSymbol *indexParam = CreateIndexSymbol(); - paramsNode->getSequence()->push_back(indexParam); + TIntermSymbol *baseParam = CreateBaseSymbol(type, baseQualifier, symbolTable); + prototypeNode->getSequence()->push_back(baseParam); + TIntermSymbol *indexParam = CreateIndexSymbol(symbolTable); + prototypeNode->getSequence()->push_back(indexParam); + TIntermSymbol *valueParam = nullptr; if (write) { - TIntermSymbol *valueParam = CreateValueSymbol(fieldType); - paramsNode->getSequence()->push_back(valueParam); + valueParam = CreateValueSymbol(fieldType, symbolTable); + prototypeNode->getSequence()->push_back(valueParam); } - indexingFunction->getSequence()->push_back(paramsNode); - TIntermAggregate *statementList = new TIntermAggregate(EOpSequence); + TIntermBlock *statementList = new TIntermBlock(); for (int i = 0; i < numCases; ++i) { TIntermCase *caseNode = new TIntermCase(CreateIntConstantNode(i)); statementList->getSequence()->push_back(caseNode); TIntermBinary *indexNode = - CreateIndexDirectBaseSymbolNode(type, fieldType, i, baseQualifier); + new TIntermBinary(EOpIndexDirect, baseParam->deepCopy(), CreateIndexNode(i)); if (write) { - TIntermBinary *assignNode = CreateAssignValueSymbolNode(indexNode, fieldType); + TIntermBinary *assignNode = + new TIntermBinary(EOpAssign, indexNode, valueParam->deepCopy()); statementList->getSequence()->push_back(assignNode); TIntermBranch *returnNode = new TIntermBranch(EOpReturn, nullptr); statementList->getSequence()->push_back(returnNode); @@ -250,32 +233,33 @@ TIntermAggregate *GetIndexFunctionDefinition(TType type, bool write) TIntermBranch *breakNode = new TIntermBranch(EOpBreak, nullptr); statementList->getSequence()->push_back(breakNode); - TIntermSwitch *switchNode = new TIntermSwitch(CreateIndexSymbol(), statementList); + TIntermSwitch *switchNode = new TIntermSwitch(indexParam->deepCopy(), statementList); - TIntermAggregate *bodyNode = new TIntermAggregate(EOpSequence); + TIntermBlock *bodyNode = new TIntermBlock(); bodyNode->getSequence()->push_back(switchNode); - TIntermBinary *cond = new TIntermBinary(EOpLessThan); + TIntermBinary *cond = + new TIntermBinary(EOpLessThan, indexParam->deepCopy(), CreateIntConstantNode(0)); cond->setType(TType(EbtBool, EbpUndefined)); - cond->setLeft(CreateIndexSymbol()); - cond->setRight(CreateIntConstantNode(0)); // Two blocks: one accesses (either reads or writes) the first element and returns, // the other accesses the last element. - TIntermAggregate *useFirstBlock = new TIntermAggregate(EOpSequence); - TIntermAggregate *useLastBlock = new TIntermAggregate(EOpSequence); + TIntermBlock *useFirstBlock = new TIntermBlock(); + TIntermBlock *useLastBlock = new TIntermBlock(); TIntermBinary *indexFirstNode = - CreateIndexDirectBaseSymbolNode(type, fieldType, 0, baseQualifier); + new TIntermBinary(EOpIndexDirect, baseParam->deepCopy(), CreateIndexNode(0)); TIntermBinary *indexLastNode = - CreateIndexDirectBaseSymbolNode(type, fieldType, numCases - 1, baseQualifier); + new TIntermBinary(EOpIndexDirect, baseParam->deepCopy(), CreateIndexNode(numCases - 1)); if (write) { - TIntermBinary *assignFirstNode = CreateAssignValueSymbolNode(indexFirstNode, fieldType); + TIntermBinary *assignFirstNode = + new TIntermBinary(EOpAssign, indexFirstNode, valueParam->deepCopy()); useFirstBlock->getSequence()->push_back(assignFirstNode); TIntermBranch *returnNode = new TIntermBranch(EOpReturn, nullptr); useFirstBlock->getSequence()->push_back(returnNode); - TIntermBinary *assignLastNode = CreateAssignValueSymbolNode(indexLastNode, fieldType); + TIntermBinary *assignLastNode = + new TIntermBinary(EOpAssign, indexLastNode, valueParam->deepCopy()); useLastBlock->getSequence()->push_back(assignLastNode); } else @@ -286,19 +270,21 @@ TIntermAggregate *GetIndexFunctionDefinition(TType type, bool write) TIntermBranch *returnLastNode = new TIntermBranch(EOpReturn, indexLastNode); useLastBlock->getSequence()->push_back(returnLastNode); } - TIntermSelection *ifNode = new TIntermSelection(cond, useFirstBlock, nullptr); + TIntermIfElse *ifNode = new TIntermIfElse(cond, useFirstBlock, nullptr); bodyNode->getSequence()->push_back(ifNode); bodyNode->getSequence()->push_back(useLastBlock); - indexingFunction->getSequence()->push_back(bodyNode); - + TIntermFunctionDefinition *indexingFunction = + new TIntermFunctionDefinition(prototypeNode, bodyNode); return indexingFunction; } class RemoveDynamicIndexingTraverser : public TLValueTrackingTraverser { public: - RemoveDynamicIndexingTraverser(const TSymbolTable &symbolTable, int shaderVersion); + RemoveDynamicIndexingTraverser(TSymbolTable *symbolTable, + int shaderVersion, + PerformanceDiagnostics *perfDiagnostics); bool visitBinary(Visit visit, TIntermBinary *node) override; @@ -309,10 +295,11 @@ class RemoveDynamicIndexingTraverser : public TLValueTrackingTraverser bool usedTreeInsertion() const { return mUsedTreeInsertion; } protected: - // Sets of types that are indexed. Note that these can not store multiple variants - // of the same type with different precisions - only one precision gets stored. - std::set mIndexedVecAndMatrixTypes; - std::set mWrittenVecAndMatrixTypes; + // Maps of types that are indexed to the indexing function ids used for them. Note that these + // can not store multiple variants of the same type with different precisions - only one + // precision gets stored. + std::map mIndexedVecAndMatrixTypes; + std::map mWrittenVecAndMatrixTypes; bool mUsedTreeInsertion; @@ -321,62 +308,74 @@ class RemoveDynamicIndexingTraverser : public TLValueTrackingTraverser // V[j++][i]++. // where V is an array of vectors, j++ will only be evaluated once. bool mRemoveIndexSideEffectsInSubtree; + + PerformanceDiagnostics *mPerfDiagnostics; }; -RemoveDynamicIndexingTraverser::RemoveDynamicIndexingTraverser(const TSymbolTable &symbolTable, - int shaderVersion) +RemoveDynamicIndexingTraverser::RemoveDynamicIndexingTraverser( + TSymbolTable *symbolTable, + int shaderVersion, + PerformanceDiagnostics *perfDiagnostics) : TLValueTrackingTraverser(true, false, false, symbolTable, shaderVersion), mUsedTreeInsertion(false), - mRemoveIndexSideEffectsInSubtree(false) + mRemoveIndexSideEffectsInSubtree(false), + mPerfDiagnostics(perfDiagnostics) { } void RemoveDynamicIndexingTraverser::insertHelperDefinitions(TIntermNode *root) { - TIntermAggregate *rootAgg = root->getAsAggregate(); - ASSERT(rootAgg != nullptr && rootAgg->getOp() == EOpSequence); + TIntermBlock *rootBlock = root->getAsBlock(); + ASSERT(rootBlock != nullptr); TIntermSequence insertions; - for (TType type : mIndexedVecAndMatrixTypes) + for (auto &type : mIndexedVecAndMatrixTypes) { - insertions.push_back(GetIndexFunctionDefinition(type, false)); + insertions.push_back( + GetIndexFunctionDefinition(type.first, false, *type.second, mSymbolTable)); } - for (TType type : mWrittenVecAndMatrixTypes) + for (auto &type : mWrittenVecAndMatrixTypes) { - insertions.push_back(GetIndexFunctionDefinition(type, true)); + insertions.push_back( + GetIndexFunctionDefinition(type.first, true, *type.second, mSymbolTable)); } - mInsertions.push_back(NodeInsertMultipleEntry(rootAgg, 0, insertions, TIntermSequence())); + rootBlock->insertChildNodes(0, insertions); } // Create a call to dyn_index_*() based on an indirect indexing op node TIntermAggregate *CreateIndexFunctionCall(TIntermBinary *node, - TIntermTyped *indexedNode, - TIntermTyped *index) + TIntermTyped *index, + const TSymbolUniqueId &functionId) { ASSERT(node->getOp() == EOpIndexIndirect); - TIntermAggregate *indexingCall = new TIntermAggregate(EOpFunctionCall); - indexingCall->setLine(node->getLine()); - indexingCall->setUserDefined(); - indexingCall->setNameObj(GetIndexFunctionName(indexedNode->getType(), false)); - indexingCall->getSequence()->push_back(indexedNode); - indexingCall->getSequence()->push_back(index); + TIntermSequence *arguments = new TIntermSequence(); + arguments->push_back(node->getLeft()); + arguments->push_back(index); - TType fieldType = GetFieldType(indexedNode->getType()); - indexingCall->setType(fieldType); + TType fieldType = GetFieldType(node->getLeft()->getType()); + std::string functionName = GetIndexFunctionName(node->getLeft()->getType(), false); + TIntermAggregate *indexingCall = + CreateInternalFunctionCallNode(fieldType, functionName.c_str(), functionId, arguments); + indexingCall->setLine(node->getLine()); + indexingCall->getFunctionSymbolInfo()->setKnownToNotHaveSideEffects(true); return indexingCall; } TIntermAggregate *CreateIndexedWriteFunctionCall(TIntermBinary *node, TIntermTyped *index, - TIntermTyped *writtenValue) + TIntermTyped *writtenValue, + const TSymbolUniqueId &functionId) { - // Deep copy the left node so that two pointers to the same node don't end up in the tree. - TIntermNode *leftCopy = node->getLeft()->deepCopy(); - ASSERT(leftCopy != nullptr && leftCopy->getAsTyped() != nullptr); + ASSERT(node->getOp() == EOpIndexIndirect); + TIntermSequence *arguments = new TIntermSequence(); + // Deep copy the child nodes so that two pointers to the same node don't end up in the tree. + arguments->push_back(node->getLeft()->deepCopy()); + arguments->push_back(index->deepCopy()); + arguments->push_back(writtenValue); + + std::string functionName = GetIndexFunctionName(node->getLeft()->getType(), true); TIntermAggregate *indexedWriteCall = - CreateIndexFunctionCall(node, leftCopy->getAsTyped(), index); - indexedWriteCall->setNameObj(GetIndexFunctionName(node->getLeft()->getType(), true)); - indexedWriteCall->setType(TType(EbtVoid)); - indexedWriteCall->getSequence()->push_back(writtenValue); + CreateInternalFunctionCallNode(TType(EbtVoid), functionName.c_str(), functionId, arguments); + indexedWriteCall->setLine(node->getLine()); return indexedWriteCall; } @@ -397,23 +396,40 @@ bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *nod // Now v_expr[s0] can be safely executed several times without unintended side effects. // Init the temp variable holding the index - TIntermAggregate *initIndex = createTempInitDeclaration(node->getRight()); - TIntermSequence insertions; - insertions.push_back(initIndex); - insertStatementsInParentBlock(insertions); + TIntermDeclaration *initIndex = createTempInitDeclaration(node->getRight()); + insertStatementInParentBlock(initIndex); mUsedTreeInsertion = true; // Replace the index with the temp variable TIntermSymbol *tempIndex = createTempSymbol(node->getRight()->getType()); - NodeUpdateEntry replaceIndex(node, node->getRight(), tempIndex, false); - mReplacements.push_back(replaceIndex); + queueReplacementWithParent(node, node->getRight(), tempIndex, OriginalNode::IS_DROPPED); } - else if (!node->getLeft()->isArray() && node->getLeft()->getBasicType() != EbtStruct) + else if (IntermNodePatternMatcher::IsDynamicIndexingOfVectorOrMatrix(node)) { + mPerfDiagnostics->warning(node->getLine(), + "Performance: dynamic indexing of vectors and " + "matrices is emulated and can be slow.", + "[]"); bool write = isLValueRequiredHere(); - TType type = node->getLeft()->getType(); - mIndexedVecAndMatrixTypes.insert(type); +#if defined(ANGLE_ENABLE_ASSERTS) + // Make sure that IntermNodePatternMatcher is consistent with the slightly differently + // implemented checks in this traverser. + IntermNodePatternMatcher matcher( + IntermNodePatternMatcher::kDynamicIndexingOfVectorOrMatrixInLValue); + ASSERT(matcher.match(node, getParentNode(), isLValueRequiredHere()) == write); +#endif + + const TType &type = node->getLeft()->getType(); + TSymbolUniqueId *indexingFunctionId = new TSymbolUniqueId(mSymbolTable); + if (mIndexedVecAndMatrixTypes.find(type) == mIndexedVecAndMatrixTypes.end()) + { + mIndexedVecAndMatrixTypes[type] = indexingFunctionId; + } + else + { + indexingFunctionId = mIndexedVecAndMatrixTypes[type]; + } if (write) { @@ -432,10 +448,30 @@ bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *nod mRemoveIndexSideEffectsInSubtree = true; return true; } + + TIntermBinary *leftBinary = node->getLeft()->getAsBinaryNode(); + if (leftBinary != nullptr && + IntermNodePatternMatcher::IsDynamicIndexingOfVectorOrMatrix(leftBinary)) + { + // This is a case like: + // mat2 m; + // m[a][b]++; + // Process the child node m[a] first. + return true; + } + // TODO(oetuaho@nvidia.com): This is not optimal if the expression using the value // only writes it and doesn't need the previous value. http://anglebug.com/1116 - mWrittenVecAndMatrixTypes.insert(type); + TSymbolUniqueId *indexedWriteFunctionId = new TSymbolUniqueId(mSymbolTable); + if (mWrittenVecAndMatrixTypes.find(type) == mWrittenVecAndMatrixTypes.end()) + { + mWrittenVecAndMatrixTypes[type] = indexedWriteFunctionId; + } + else + { + indexedWriteFunctionId = mWrittenVecAndMatrixTypes[type]; + } TType fieldType = GetFieldType(type); TIntermSequence insertionsBefore; @@ -443,28 +479,26 @@ bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *nod // Store the index in a temporary signed int variable. TIntermTyped *indexInitializer = EnsureSignedInt(node->getRight()); - TIntermAggregate *initIndex = createTempInitDeclaration(indexInitializer); + TIntermDeclaration *initIndex = createTempInitDeclaration(indexInitializer); initIndex->setLine(node->getLine()); insertionsBefore.push_back(initIndex); - TIntermAggregate *indexingCall = CreateIndexFunctionCall( - node, node->getLeft(), createTempSymbol(indexInitializer->getType())); - - // Create a node for referring to the index after the nextTemporaryIndex() call + // Create a node for referring to the index after the nextTemporaryId() call // below. TIntermSymbol *tempIndex = createTempSymbol(indexInitializer->getType()); - nextTemporaryIndex(); // From now on, creating temporary symbols that refer to the - // field value. + TIntermAggregate *indexingCall = + CreateIndexFunctionCall(node, tempIndex, *indexingFunctionId); + + nextTemporaryId(); // From now on, creating temporary symbols that refer to the + // field value. insertionsBefore.push_back(createTempInitDeclaration(indexingCall)); - TIntermAggregate *indexedWriteCall = - CreateIndexedWriteFunctionCall(node, tempIndex, createTempSymbol(fieldType)); + TIntermAggregate *indexedWriteCall = CreateIndexedWriteFunctionCall( + node, tempIndex, createTempSymbol(fieldType), *indexedWriteFunctionId); insertionsAfter.push_back(indexedWriteCall); insertStatementsInParentBlock(insertionsBefore, insertionsAfter); - NodeUpdateEntry replaceIndex(getParentNode(), node, createTempSymbol(fieldType), - false); - mReplacements.push_back(replaceIndex); + queueReplacement(createTempSymbol(fieldType), OriginalNode::IS_DROPPED); mUsedTreeInsertion = true; } else @@ -476,9 +510,8 @@ bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *nod // If the index_expr is unsigned, we'll convert it to signed. ASSERT(!mRemoveIndexSideEffectsInSubtree); TIntermAggregate *indexingCall = CreateIndexFunctionCall( - node, node->getLeft(), EnsureSignedInt(node->getRight())); - NodeUpdateEntry replaceIndex(getParentNode(), node, indexingCall, false); - mReplacements.push_back(replaceIndex); + node, EnsureSignedInt(node->getRight()), *indexingFunctionId); + queueReplacement(indexingCall, OriginalNode::IS_DROPPED); } } } @@ -489,25 +522,29 @@ void RemoveDynamicIndexingTraverser::nextIteration() { mUsedTreeInsertion = false; mRemoveIndexSideEffectsInSubtree = false; - nextTemporaryIndex(); + nextTemporaryId(); } } // namespace void RemoveDynamicIndexing(TIntermNode *root, - unsigned int *temporaryIndex, - const TSymbolTable &symbolTable, - int shaderVersion) + TSymbolTable *symbolTable, + int shaderVersion, + PerformanceDiagnostics *perfDiagnostics) { - RemoveDynamicIndexingTraverser traverser(symbolTable, shaderVersion); - ASSERT(temporaryIndex != nullptr); - traverser.useTemporaryIndex(temporaryIndex); + RemoveDynamicIndexingTraverser traverser(symbolTable, shaderVersion, perfDiagnostics); do { traverser.nextIteration(); root->traverse(&traverser); traverser.updateTree(); } while (traverser.usedTreeInsertion()); + // TODO(oetuaho@nvidia.com): It might be nicer to add the helper definitions also in the middle + // of traversal. Now the tree ends up in an inconsistent state in the middle, since there are + // function call nodes with no corresponding definition nodes. This needs special handling in + // TIntermLValueTrackingTraverser, and creates intricacies that are not easily apparent from a + // superficial reading of the code. traverser.insertHelperDefinitions(root); - traverser.updateTree(); } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/RemoveDynamicIndexing.h b/src/3rdparty/angle/src/compiler/translator/RemoveDynamicIndexing.h index ae3a93c9b1..543cf569a6 100644 --- a/src/3rdparty/angle/src/compiler/translator/RemoveDynamicIndexing.h +++ b/src/3rdparty/angle/src/compiler/translator/RemoveDynamicIndexing.h @@ -10,12 +10,18 @@ #ifndef COMPILER_TRANSLATOR_REMOVEDYNAMICINDEXING_H_ #define COMPILER_TRANSLATOR_REMOVEDYNAMICINDEXING_H_ +namespace sh +{ + class TIntermNode; class TSymbolTable; +class PerformanceDiagnostics; void RemoveDynamicIndexing(TIntermNode *root, - unsigned int *temporaryIndex, - const TSymbolTable &symbolTable, - int shaderVersion); + TSymbolTable *symbolTable, + int shaderVersion, + PerformanceDiagnostics *perfDiagnostics); + +} // namespace sh #endif // COMPILER_TRANSLATOR_REMOVEDYNAMICINDEXING_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/RemoveEmptySwitchStatements.cpp b/src/3rdparty/angle/src/compiler/translator/RemoveEmptySwitchStatements.cpp new file mode 100644 index 0000000000..b39c912e9c --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/RemoveEmptySwitchStatements.cpp @@ -0,0 +1,56 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// RemoveEmptySwitchStatements.cpp: Remove switch statements that have an empty statement list. + +#include "compiler/translator/RemoveEmptySwitchStatements.h" + +#include "compiler/translator/IntermTraverse.h" + +namespace sh +{ + +namespace +{ + +class RemoveEmptySwitchStatementsTraverser : public TIntermTraverser +{ + public: + RemoveEmptySwitchStatementsTraverser() : TIntermTraverser(true, false, false) {} + + bool visitSwitch(Visit visit, TIntermSwitch *node); +}; + +bool RemoveEmptySwitchStatementsTraverser::visitSwitch(Visit visit, TIntermSwitch *node) +{ + if (node->getStatementList()->getSequence()->empty()) + { + // Just output the init statement. + if (node->getInit()->hasSideEffects()) + { + queueReplacement(node->getInit(), OriginalNode::IS_DROPPED); + } + else + { + TIntermSequence emptyReplacement; + ASSERT(getParentNode()->getAsBlock()); + mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(getParentNode()->getAsBlock(), + node, emptyReplacement)); + } + return false; // Nothing inside the child nodes to traverse. + } + return true; +} + +} // anonymous namespace + +void RemoveEmptySwitchStatements(TIntermBlock *root) +{ + RemoveEmptySwitchStatementsTraverser traverser; + root->traverse(&traverser); + traverser.updateTree(); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/RemoveEmptySwitchStatements.h b/src/3rdparty/angle/src/compiler/translator/RemoveEmptySwitchStatements.h new file mode 100644 index 0000000000..1018a50d82 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/RemoveEmptySwitchStatements.h @@ -0,0 +1,18 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// RemoveEmptySwitchStatements.h: Remove switch statements that have an empty statement list. + +#ifndef COMPILER_TRANSLATOR_REMOVEEMPTYSWITCHSTATEMENTS_H_ +#define COMPILER_TRANSLATOR_REMOVEEMPTYSWITCHSTATEMENTS_H_ + +namespace sh +{ +class TIntermBlock; + +void RemoveEmptySwitchStatements(TIntermBlock *root); +} + +#endif // COMPILER_TRANSLATOR_REMOVEEMPTYSWITCHSTATEMENTS_H_ \ No newline at end of file diff --git a/src/3rdparty/angle/src/compiler/translator/RemoveInvariantDeclaration.cpp b/src/3rdparty/angle/src/compiler/translator/RemoveInvariantDeclaration.cpp new file mode 100644 index 0000000000..4b533dc7b5 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/RemoveInvariantDeclaration.cpp @@ -0,0 +1,43 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/translator/RemoveInvariantDeclaration.h" + +#include "compiler/translator/IntermTraverse.h" + +namespace sh +{ + +namespace +{ + +// An AST traverser that removes invariant declaration for input in fragment shader +// when GLSL >= 4.20 and for output in vertex shader when GLSL < 4.2. +class RemoveInvariantDeclarationTraverser : public TIntermTraverser +{ + public: + RemoveInvariantDeclarationTraverser() : TIntermTraverser(true, false, false) {} + + private: + bool visitInvariantDeclaration(Visit visit, TIntermInvariantDeclaration *node) override + { + TIntermSequence emptyReplacement; + mMultiReplacements.push_back( + NodeReplaceWithMultipleEntry(getParentNode()->getAsBlock(), node, emptyReplacement)); + return false; + } +}; + +} // anonymous namespace + +void RemoveInvariantDeclaration(TIntermNode *root) +{ + RemoveInvariantDeclarationTraverser traverser; + root->traverse(&traverser); + traverser.updateTree(); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/RemoveInvariantDeclaration.h b/src/3rdparty/angle/src/compiler/translator/RemoveInvariantDeclaration.h new file mode 100644 index 0000000000..cf9d4aa4c2 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/RemoveInvariantDeclaration.h @@ -0,0 +1,18 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_TRANSLATOR_REMOVEINVARIANTDECLARATION_H_ +#define COMPILER_TRANSLATOR_REMOVEINVARIANTDECLARATION_H_ + +class TIntermNode; +namespace sh +{ + +void RemoveInvariantDeclaration(TIntermNode *root); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_REMOVEINVARIANTDECLARATION_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.cpp b/src/3rdparty/angle/src/compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.cpp new file mode 100644 index 0000000000..b86d64d7a3 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.cpp @@ -0,0 +1,116 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// RemoveNoOpCasesFromEndOfSwitchStatements.cpp: Clean up cases from the end of a switch statement +// that only contain no-ops. + +#include "compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.h" + +#include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermNode_util.h" +#include "compiler/translator/IntermTraverse.h" +#include "compiler/translator/SymbolTable.h" + +namespace sh +{ + +namespace +{ + +bool AreEmptyBlocks(TIntermSequence *statements, size_t i); + +bool IsEmptyBlock(TIntermNode *node) +{ + TIntermBlock *asBlock = node->getAsBlock(); + if (asBlock) + { + if (asBlock->getSequence()->empty()) + { + return true; + } + return AreEmptyBlocks(asBlock->getSequence(), 0u); + } + // Empty declarations should have already been pruned, otherwise they would need to be handled + // here. Note that declarations for struct types do contain a nameless child node. + ASSERT(node->getAsDeclarationNode() == nullptr || + !node->getAsDeclarationNode()->getSequence()->empty()); + // Pure literal statements should also already be pruned. + ASSERT(node->getAsConstantUnion() == nullptr); + return false; +} + +// Return true if all statements in "statements" starting from index i consist only of empty blocks +// and no-op statements. Returns true also if there are no statements. +bool AreEmptyBlocks(TIntermSequence *statements, size_t i) +{ + for (; i < statements->size(); ++i) + { + if (!IsEmptyBlock(statements->at(i))) + { + return false; + } + } + return true; +} + +void RemoveNoOpCasesFromEndOfStatementList(TIntermBlock *statementList, TSymbolTable *symbolTable) +{ + TIntermSequence *statements = statementList->getSequence(); + + bool foundDeadCase = false; + do + { + if (statements->empty()) + { + return; + } + + // Find the last case label. + size_t i = statements->size(); + while (i > 0u && !(*statements)[i - 1]->getAsCaseNode()) + { + --i; + } + // Now i is the index of the first statement following the last label inside the switch + // statement. + ASSERT(i > 0u); + + foundDeadCase = AreEmptyBlocks(statements, i); + if (foundDeadCase) + { + statements->erase(statements->begin() + (i - 1u), statements->end()); + } + } while (foundDeadCase); +} + +class RemoveNoOpCasesFromEndOfSwitchTraverser : public TIntermTraverser +{ + public: + RemoveNoOpCasesFromEndOfSwitchTraverser(TSymbolTable *symbolTable) + : TIntermTraverser(true, false, false, symbolTable) + { + } + + bool visitSwitch(Visit visit, TIntermSwitch *node) override; +}; + +bool RemoveNoOpCasesFromEndOfSwitchTraverser::visitSwitch(Visit visit, TIntermSwitch *node) +{ + // Here we may mutate the statement list, but it's safe since traversal has not yet reached + // there. + RemoveNoOpCasesFromEndOfStatementList(node->getStatementList(), mSymbolTable); + // Handle also nested switch statements. + return true; +} + +} // anonymous namespace + +void RemoveNoOpCasesFromEndOfSwitchStatements(TIntermBlock *root, TSymbolTable *symbolTable) +{ + RemoveNoOpCasesFromEndOfSwitchTraverser traverser(symbolTable); + root->traverse(&traverser); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.h b/src/3rdparty/angle/src/compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.h new file mode 100644 index 0000000000..ebd75eb774 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.h @@ -0,0 +1,21 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// RemoveNoOpCasesFromEndOfSwitchStatements.h: Clean up cases from the end of a switch statement +// that only contain no-ops. + +#ifndef COMPILER_TRANSLATOR_REMOVENOOPCASESFROMENDOFSWITCHSTATEMENTS_H_ +#define COMPILER_TRANSLATOR_REMOVENOOPCASESFROMENDOFSWITCHSTATEMENTS_H_ + +namespace sh +{ +class TIntermBlock; +class TSymbolTable; + +void RemoveNoOpCasesFromEndOfSwitchStatements(TIntermBlock *root, TSymbolTable *symbolTable); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_REMOVENOOPCASESFROMENDOFSWITCHSTATEMENTS_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/RemovePow.cpp b/src/3rdparty/angle/src/compiler/translator/RemovePow.cpp index 6dbb48da9c..b2cdac55f0 100644 --- a/src/3rdparty/angle/src/compiler/translator/RemovePow.cpp +++ b/src/3rdparty/angle/src/compiler/translator/RemovePow.cpp @@ -11,7 +11,10 @@ #include "compiler/translator/RemovePow.h" #include "compiler/translator/InfoSink.h" -#include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermTraverse.h" + +namespace sh +{ namespace { @@ -43,8 +46,7 @@ class RemovePowTraverser : public TIntermTraverser }; RemovePowTraverser::RemovePowTraverser() - : TIntermTraverser(true, false, false), - mNeedAnotherIteration(false) + : TIntermTraverser(true, false, false), mNeedAnotherIteration(false) { } @@ -52,31 +54,20 @@ bool RemovePowTraverser::visitAggregate(Visit visit, TIntermAggregate *node) { if (IsProblematicPow(node)) { - TInfoSink nullSink; - TIntermTyped *x = node->getSequence()->at(0)->getAsTyped(); TIntermTyped *y = node->getSequence()->at(1)->getAsTyped(); - TIntermUnary *log = new TIntermUnary(EOpLog2); - log->setOperand(x); + TIntermUnary *log = new TIntermUnary(EOpLog2, x); log->setLine(node->getLine()); - log->setType(x->getType()); - TIntermBinary *mul = new TIntermBinary(EOpMul); - mul->setLeft(y); - mul->setRight(log); + TOperator op = TIntermBinary::GetMulOpBasedOnOperands(y->getType(), log->getType()); + TIntermBinary *mul = new TIntermBinary(op, y, log); mul->setLine(node->getLine()); - bool valid = mul->promote(nullSink); - UNUSED_ASSERTION_VARIABLE(valid); - ASSERT(valid); - TIntermUnary *exp = new TIntermUnary(EOpExp2); - exp->setOperand(mul); + TIntermUnary *exp = new TIntermUnary(EOpExp2, mul); exp->setLine(node->getLine()); - exp->setType(node->getType()); - NodeUpdateEntry replacePow(getParentNode(), node, exp, false); - mReplacements.push_back(replacePow); + queueReplacement(exp, OriginalNode::IS_DROPPED); // If the x parameter also needs to be replaced, we need to do that in another traversal, // since it's parent node will change in a way that's not handled correctly by updateTree(). @@ -89,7 +80,7 @@ bool RemovePowTraverser::visitAggregate(Visit visit, TIntermAggregate *node) return true; } -} // namespace +} // namespace void RemovePow(TIntermNode *root) { @@ -100,6 +91,7 @@ void RemovePow(TIntermNode *root) traverser.nextIteration(); root->traverse(&traverser); traverser.updateTree(); - } - while (traverser.needAnotherIteration()); + } while (traverser.needAnotherIteration()); } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/RemovePow.h b/src/3rdparty/angle/src/compiler/translator/RemovePow.h index 40f9d672b2..3cd84988a9 100644 --- a/src/3rdparty/angle/src/compiler/translator/RemovePow.h +++ b/src/3rdparty/angle/src/compiler/translator/RemovePow.h @@ -11,8 +11,11 @@ #ifndef COMPILER_TRANSLATOR_REMOVEPOW_H_ #define COMPILER_TRANSLATOR_REMOVEPOW_H_ +namespace sh +{ class TIntermNode; void RemovePow(TIntermNode *root); +} // namespace sh -#endif // COMPILER_TRANSLATOR_REMOVEPOW_H_ +#endif // COMPILER_TRANSLATOR_REMOVEPOW_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/RemoveSwitchFallThrough.cpp b/src/3rdparty/angle/src/compiler/translator/RemoveSwitchFallThrough.cpp index b278b53436..dea949f448 100644 --- a/src/3rdparty/angle/src/compiler/translator/RemoveSwitchFallThrough.cpp +++ b/src/3rdparty/angle/src/compiler/translator/RemoveSwitchFallThrough.cpp @@ -3,36 +3,91 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // +// RemoveSwitchFallThrough.cpp: Remove fall-through from switch statements. +// Note that it is unsafe to do further AST transformations on the AST generated +// by this function. It leaves duplicate nodes in the AST making replacements +// unreliable. #include "compiler/translator/RemoveSwitchFallThrough.h" -TIntermAggregate *RemoveSwitchFallThrough::removeFallThrough(TIntermAggregate *statementList) +#include "compiler/translator/Diagnostics.h" +#include "compiler/translator/IntermTraverse.h" + +namespace sh { - RemoveSwitchFallThrough rm(statementList); + +namespace +{ + +class RemoveSwitchFallThroughTraverser : public TIntermTraverser +{ + public: + static TIntermBlock *removeFallThrough(TIntermBlock *statementList, + PerformanceDiagnostics *perfDiagnostics); + + private: + RemoveSwitchFallThroughTraverser(TIntermBlock *statementList, + PerformanceDiagnostics *perfDiagnostics); + + void visitSymbol(TIntermSymbol *node) override; + void visitConstantUnion(TIntermConstantUnion *node) override; + bool visitDeclaration(Visit, TIntermDeclaration *node) override; + bool visitBinary(Visit, TIntermBinary *node) override; + bool visitUnary(Visit, TIntermUnary *node) override; + bool visitTernary(Visit visit, TIntermTernary *node) override; + bool visitSwizzle(Visit, TIntermSwizzle *node) override; + bool visitIfElse(Visit visit, TIntermIfElse *node) override; + bool visitSwitch(Visit, TIntermSwitch *node) override; + bool visitCase(Visit, TIntermCase *node) override; + bool visitAggregate(Visit, TIntermAggregate *node) override; + bool visitBlock(Visit, TIntermBlock *node) override; + bool visitLoop(Visit, TIntermLoop *node) override; + bool visitBranch(Visit, TIntermBranch *node) override; + + void outputSequence(TIntermSequence *sequence, size_t startIndex); + void handlePreviousCase(); + + TIntermBlock *mStatementList; + TIntermBlock *mStatementListOut; + bool mLastStatementWasBreak; + TIntermBlock *mPreviousCase; + std::vector mCasesSharingBreak; + PerformanceDiagnostics *mPerfDiagnostics; +}; + +TIntermBlock *RemoveSwitchFallThroughTraverser::removeFallThrough( + TIntermBlock *statementList, + PerformanceDiagnostics *perfDiagnostics) +{ + RemoveSwitchFallThroughTraverser rm(statementList, perfDiagnostics); ASSERT(statementList); statementList->traverse(&rm); - bool lastStatementWasBreak = rm.mLastStatementWasBreak; - rm.mLastStatementWasBreak = true; - rm.handlePreviousCase(); - if (!lastStatementWasBreak) + ASSERT(rm.mPreviousCase || statementList->getSequence()->empty()); + if (!rm.mLastStatementWasBreak && rm.mPreviousCase) { + // Make sure that there's a branch at the end of the final case inside the switch statement. + // This also ensures that any cases that fall through to the final case will get the break. TIntermBranch *finalBreak = new TIntermBranch(EOpBreak, nullptr); - rm.mStatementListOut->getSequence()->push_back(finalBreak); + rm.mPreviousCase->getSequence()->push_back(finalBreak); + rm.mLastStatementWasBreak = true; } + rm.handlePreviousCase(); return rm.mStatementListOut; } -RemoveSwitchFallThrough::RemoveSwitchFallThrough(TIntermAggregate *statementList) +RemoveSwitchFallThroughTraverser::RemoveSwitchFallThroughTraverser( + TIntermBlock *statementList, + PerformanceDiagnostics *perfDiagnostics) : TIntermTraverser(true, false, false), mStatementList(statementList), mLastStatementWasBreak(false), - mPreviousCase(nullptr) + mPreviousCase(nullptr), + mPerfDiagnostics(perfDiagnostics) { - mStatementListOut = new TIntermAggregate(); - mStatementListOut->setOp(EOpSequence); + mStatementListOut = new TIntermBlock(); } -void RemoveSwitchFallThrough::visitSymbol(TIntermSymbol *node) +void RemoveSwitchFallThroughTraverser::visitSymbol(TIntermSymbol *node) { // Note that this assumes that switch statements which don't begin by a case statement // have already been weeded out in validation. @@ -40,36 +95,57 @@ void RemoveSwitchFallThrough::visitSymbol(TIntermSymbol *node) mLastStatementWasBreak = false; } -void RemoveSwitchFallThrough::visitConstantUnion(TIntermConstantUnion *node) +void RemoveSwitchFallThroughTraverser::visitConstantUnion(TIntermConstantUnion *node) { - // Conditions of case labels are not traversed, so this is some other constant - // Could be just a statement like "0;" - mPreviousCase->getSequence()->push_back(node); - mLastStatementWasBreak = false; + // Conditions of case labels are not traversed, so this is a constant statement like "0;". + // These are no-ops so there's no need to add them back to the statement list. Should have + // already been pruned out of the AST, in fact. + UNREACHABLE(); } -bool RemoveSwitchFallThrough::visitBinary(Visit, TIntermBinary *node) +bool RemoveSwitchFallThroughTraverser::visitDeclaration(Visit, TIntermDeclaration *node) { mPreviousCase->getSequence()->push_back(node); mLastStatementWasBreak = false; return false; } -bool RemoveSwitchFallThrough::visitUnary(Visit, TIntermUnary *node) +bool RemoveSwitchFallThroughTraverser::visitBinary(Visit, TIntermBinary *node) { mPreviousCase->getSequence()->push_back(node); mLastStatementWasBreak = false; return false; } -bool RemoveSwitchFallThrough::visitSelection(Visit, TIntermSelection *node) +bool RemoveSwitchFallThroughTraverser::visitUnary(Visit, TIntermUnary *node) { mPreviousCase->getSequence()->push_back(node); mLastStatementWasBreak = false; return false; } -bool RemoveSwitchFallThrough::visitSwitch(Visit, TIntermSwitch *node) +bool RemoveSwitchFallThroughTraverser::visitTernary(Visit, TIntermTernary *node) +{ + mPreviousCase->getSequence()->push_back(node); + mLastStatementWasBreak = false; + return false; +} + +bool RemoveSwitchFallThroughTraverser::visitSwizzle(Visit, TIntermSwizzle *node) +{ + mPreviousCase->getSequence()->push_back(node); + mLastStatementWasBreak = false; + return false; +} + +bool RemoveSwitchFallThroughTraverser::visitIfElse(Visit, TIntermIfElse *node) +{ + mPreviousCase->getSequence()->push_back(node); + mLastStatementWasBreak = false; + return false; +} + +bool RemoveSwitchFallThroughTraverser::visitSwitch(Visit, TIntermSwitch *node) { mPreviousCase->getSequence()->push_back(node); mLastStatementWasBreak = false; @@ -77,7 +153,7 @@ bool RemoveSwitchFallThrough::visitSwitch(Visit, TIntermSwitch *node) return false; } -void RemoveSwitchFallThrough::outputSequence(TIntermSequence *sequence, size_t startIndex) +void RemoveSwitchFallThroughTraverser::outputSequence(TIntermSequence *sequence, size_t startIndex) { for (size_t i = startIndex; i < sequence->size(); ++i) { @@ -85,20 +161,16 @@ void RemoveSwitchFallThrough::outputSequence(TIntermSequence *sequence, size_t s } } -void RemoveSwitchFallThrough::handlePreviousCase() +void RemoveSwitchFallThroughTraverser::handlePreviousCase() { if (mPreviousCase) mCasesSharingBreak.push_back(mPreviousCase); if (mLastStatementWasBreak) { - bool labelsWithNoStatements = true; for (size_t i = 0; i < mCasesSharingBreak.size(); ++i) { - if (mCasesSharingBreak.at(i)->getSequence()->size() > 1) - { - labelsWithNoStatements = false; - } - if (labelsWithNoStatements) + ASSERT(!mCasesSharingBreak.at(i)->getSequence()->empty()); + if (mCasesSharingBreak.at(i)->getSequence()->size() == 1) { // Fall-through is allowed in case the label has no statements. outputSequence(mCasesSharingBreak.at(i)->getSequence(), 0); @@ -106,52 +178,93 @@ void RemoveSwitchFallThrough::handlePreviousCase() else { // Include all the statements that this case can fall through under the same label. + if (mCasesSharingBreak.size() > i + 1u) + { + mPerfDiagnostics->warning(mCasesSharingBreak.at(i)->getLine(), + "Performance: non-empty fall-through cases in " + "switch statements generate extra code.", + "switch"); + } for (size_t j = i; j < mCasesSharingBreak.size(); ++j) { - size_t startIndex = j > i ? 1 : 0; // Add the label only from the first sequence. + size_t startIndex = + j > i ? 1 : 0; // Add the label only from the first sequence. outputSequence(mCasesSharingBreak.at(j)->getSequence(), startIndex); - } } } mCasesSharingBreak.clear(); } mLastStatementWasBreak = false; - mPreviousCase = nullptr; + mPreviousCase = nullptr; } -bool RemoveSwitchFallThrough::visitCase(Visit, TIntermCase *node) +bool RemoveSwitchFallThroughTraverser::visitCase(Visit, TIntermCase *node) { handlePreviousCase(); - mPreviousCase = new TIntermAggregate(); - mPreviousCase->setOp(EOpSequence); + mPreviousCase = new TIntermBlock(); mPreviousCase->getSequence()->push_back(node); + mPreviousCase->setLine(node->getLine()); // Don't traverse the condition of the case statement return false; } -bool RemoveSwitchFallThrough::visitAggregate(Visit, TIntermAggregate *node) -{ - if (node != mStatementList) - { - mPreviousCase->getSequence()->push_back(node); - mLastStatementWasBreak = false; - return false; - } - return true; -} - -bool RemoveSwitchFallThrough::visitLoop(Visit, TIntermLoop *node) +bool RemoveSwitchFallThroughTraverser::visitAggregate(Visit, TIntermAggregate *node) { mPreviousCase->getSequence()->push_back(node); mLastStatementWasBreak = false; return false; } -bool RemoveSwitchFallThrough::visitBranch(Visit, TIntermBranch *node) +bool DoesBlockAlwaysBreak(TIntermBlock *node) +{ + if (node->getSequence()->empty()) + { + return false; + } + + TIntermBlock *lastStatementAsBlock = node->getSequence()->back()->getAsBlock(); + if (lastStatementAsBlock) + { + return DoesBlockAlwaysBreak(lastStatementAsBlock); + } + + TIntermBranch *lastStatementAsBranch = node->getSequence()->back()->getAsBranchNode(); + return lastStatementAsBranch != nullptr; +} + +bool RemoveSwitchFallThroughTraverser::visitBlock(Visit, TIntermBlock *node) +{ + if (node != mStatementList) + { + mPreviousCase->getSequence()->push_back(node); + mLastStatementWasBreak = DoesBlockAlwaysBreak(node); + return false; + } + return true; +} + +bool RemoveSwitchFallThroughTraverser::visitLoop(Visit, TIntermLoop *node) +{ + mPreviousCase->getSequence()->push_back(node); + mLastStatementWasBreak = false; + return false; +} + +bool RemoveSwitchFallThroughTraverser::visitBranch(Visit, TIntermBranch *node) { mPreviousCase->getSequence()->push_back(node); // TODO: Verify that accepting return or continue statements here doesn't cause problems. mLastStatementWasBreak = true; return false; } + +} // anonymous namespace + +TIntermBlock *RemoveSwitchFallThrough(TIntermBlock *statementList, + PerformanceDiagnostics *perfDiagnostics) +{ + return RemoveSwitchFallThroughTraverser::removeFallThrough(statementList, perfDiagnostics); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/RemoveSwitchFallThrough.h b/src/3rdparty/angle/src/compiler/translator/RemoveSwitchFallThrough.h index db8699327c..7a3b1963f2 100644 --- a/src/3rdparty/angle/src/compiler/translator/RemoveSwitchFallThrough.h +++ b/src/3rdparty/angle/src/compiler/translator/RemoveSwitchFallThrough.h @@ -3,41 +3,25 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // +// RemoveSwitchFallThrough.h: Remove fall-through from switch statements. +// Note that it is unsafe to do further AST transformations on the AST generated +// by this function. It leaves duplicate nodes in the AST making replacements +// unreliable. #ifndef COMPILER_TRANSLATOR_REMOVESWITCHFALLTHROUGH_H_ #define COMPILER_TRANSLATOR_REMOVESWITCHFALLTHROUGH_H_ -#include "compiler/translator/IntermNode.h" - -class RemoveSwitchFallThrough : public TIntermTraverser +namespace sh { - public: - // When given a statementList from a switch AST node, return an updated - // statementList that has fall-through removed. - static TIntermAggregate *removeFallThrough(TIntermAggregate *statementList); - private: - RemoveSwitchFallThrough(TIntermAggregate *statementList); +class TIntermBlock; +class PerformanceDiagnostics; - void visitSymbol(TIntermSymbol *node) override; - void visitConstantUnion(TIntermConstantUnion *node) override; - bool visitBinary(Visit, TIntermBinary *node) override; - bool visitUnary(Visit, TIntermUnary *node) override; - bool visitSelection(Visit visit, TIntermSelection *node) override; - bool visitSwitch(Visit, TIntermSwitch *node) override; - bool visitCase(Visit, TIntermCase *node) override; - bool visitAggregate(Visit, TIntermAggregate *node) override; - bool visitLoop(Visit, TIntermLoop *node) override; - bool visitBranch(Visit, TIntermBranch *node) override; +// When given a statementList from a switch AST node, return an updated +// statementList that has fall-through removed. +TIntermBlock *RemoveSwitchFallThrough(TIntermBlock *statementList, + PerformanceDiagnostics *perfDiagnostics); - void outputSequence(TIntermSequence *sequence, size_t startIndex); - void handlePreviousCase(); +} // namespace sh - TIntermAggregate *mStatementList; - TIntermAggregate *mStatementListOut; - bool mLastStatementWasBreak; - TIntermAggregate *mPreviousCase; - std::vector mCasesSharingBreak; -}; - -#endif // COMPILER_TRANSLATOR_REMOVESWITCHFALLTHROUGH_H_ +#endif // COMPILER_TRANSLATOR_REMOVESWITCHFALLTHROUGH_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/RemoveUnreferencedVariables.cpp b/src/3rdparty/angle/src/compiler/translator/RemoveUnreferencedVariables.cpp new file mode 100644 index 0000000000..74b5e73f71 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/RemoveUnreferencedVariables.cpp @@ -0,0 +1,358 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// RemoveUnreferencedVariables.cpp: +// Drop variables that are declared but never referenced in the AST. This avoids adding unnecessary +// initialization code for them. Also removes unreferenced struct types. +// + +#include "compiler/translator/RemoveUnreferencedVariables.h" + +#include "compiler/translator/IntermTraverse.h" +#include "compiler/translator/SymbolTable.h" + +namespace sh +{ + +namespace +{ + +class CollectVariableRefCountsTraverser : public TIntermTraverser +{ + public: + CollectVariableRefCountsTraverser(); + + using RefCountMap = std::unordered_map; + RefCountMap &getSymbolIdRefCounts() { return mSymbolIdRefCounts; } + RefCountMap &getStructIdRefCounts() { return mStructIdRefCounts; } + + void visitSymbol(TIntermSymbol *node) override; + bool visitAggregate(Visit visit, TIntermAggregate *node) override; + bool visitFunctionPrototype(Visit visit, TIntermFunctionPrototype *node) override; + + private: + void incrementStructTypeRefCount(const TType &type); + + RefCountMap mSymbolIdRefCounts; + + // Structure reference counts are counted from symbols, constructors, function calls, function + // return values and from interface block and structure fields. We need to track both function + // calls and function return values since there's a compiler option not to prune unused + // functions. The type of a constant union may also be a struct, but statements that are just a + // constant union are always pruned, and if the constant union is used somehow it will get + // counted by something else. + RefCountMap mStructIdRefCounts; +}; + +CollectVariableRefCountsTraverser::CollectVariableRefCountsTraverser() + : TIntermTraverser(true, false, false) +{ +} + +void CollectVariableRefCountsTraverser::incrementStructTypeRefCount(const TType &type) +{ + if (type.isInterfaceBlock()) + { + const auto *block = type.getInterfaceBlock(); + ASSERT(block); + + // We can end up incrementing ref counts of struct types referenced from an interface block + // multiple times for the same block. This doesn't matter, because interface blocks can't be + // pruned so we'll never do the reverse operation. + for (const auto &field : block->fields()) + { + ASSERT(!field->type()->isInterfaceBlock()); + incrementStructTypeRefCount(*field->type()); + } + return; + } + + const auto *structure = type.getStruct(); + if (structure != nullptr) + { + auto structIter = mStructIdRefCounts.find(structure->uniqueId()); + if (structIter == mStructIdRefCounts.end()) + { + mStructIdRefCounts[structure->uniqueId()] = 1u; + + for (const auto &field : structure->fields()) + { + incrementStructTypeRefCount(*field->type()); + } + + return; + } + ++(structIter->second); + } +} + +void CollectVariableRefCountsTraverser::visitSymbol(TIntermSymbol *node) +{ + incrementStructTypeRefCount(node->getType()); + + auto iter = mSymbolIdRefCounts.find(node->getId()); + if (iter == mSymbolIdRefCounts.end()) + { + mSymbolIdRefCounts[node->getId()] = 1u; + return; + } + ++(iter->second); +} + +bool CollectVariableRefCountsTraverser::visitAggregate(Visit visit, TIntermAggregate *node) +{ + // This tracks struct references in both function calls and constructors. + incrementStructTypeRefCount(node->getType()); + return true; +} + +bool CollectVariableRefCountsTraverser::visitFunctionPrototype(Visit visit, + TIntermFunctionPrototype *node) +{ + incrementStructTypeRefCount(node->getType()); + return true; +} + +// Traverser that removes all unreferenced variables on one traversal. +class RemoveUnreferencedVariablesTraverser : public TIntermTraverser +{ + public: + RemoveUnreferencedVariablesTraverser( + CollectVariableRefCountsTraverser::RefCountMap *symbolIdRefCounts, + CollectVariableRefCountsTraverser::RefCountMap *structIdRefCounts, + TSymbolTable *symbolTable); + + bool visitDeclaration(Visit visit, TIntermDeclaration *node) override; + void visitSymbol(TIntermSymbol *node) override; + bool visitAggregate(Visit visit, TIntermAggregate *node) override; + + // Traverse loop and block nodes in reverse order. Note that this traverser does not track + // parent block positions, so insertStatementInParentBlock is unusable! + void traverseBlock(TIntermBlock *block) override; + void traverseLoop(TIntermLoop *loop) override; + + private: + void removeVariableDeclaration(TIntermDeclaration *node, TIntermTyped *declarator); + void decrementStructTypeRefCount(const TType &type); + + CollectVariableRefCountsTraverser::RefCountMap *mSymbolIdRefCounts; + CollectVariableRefCountsTraverser::RefCountMap *mStructIdRefCounts; + bool mRemoveReferences; +}; + +RemoveUnreferencedVariablesTraverser::RemoveUnreferencedVariablesTraverser( + CollectVariableRefCountsTraverser::RefCountMap *symbolIdRefCounts, + CollectVariableRefCountsTraverser::RefCountMap *structIdRefCounts, + TSymbolTable *symbolTable) + : TIntermTraverser(true, false, true, symbolTable), + mSymbolIdRefCounts(symbolIdRefCounts), + mStructIdRefCounts(structIdRefCounts), + mRemoveReferences(false) +{ +} + +void RemoveUnreferencedVariablesTraverser::decrementStructTypeRefCount(const TType &type) +{ + auto *structure = type.getStruct(); + if (structure != nullptr) + { + ASSERT(mStructIdRefCounts->find(structure->uniqueId()) != mStructIdRefCounts->end()); + unsigned int structRefCount = --(*mStructIdRefCounts)[structure->uniqueId()]; + + if (structRefCount == 0) + { + for (const auto &field : structure->fields()) + { + decrementStructTypeRefCount(*field->type()); + } + } + } +} + +void RemoveUnreferencedVariablesTraverser::removeVariableDeclaration(TIntermDeclaration *node, + TIntermTyped *declarator) +{ + if (declarator->getType().isStructSpecifier() && !declarator->getType().isNamelessStruct()) + { + unsigned int structId = declarator->getType().getStruct()->uniqueId(); + if ((*mStructIdRefCounts)[structId] > 1u) + { + // If this declaration declares a named struct type that is used elsewhere, we need to + // keep it. We can still change the declarator though so that it doesn't declare an + // unreferenced variable. + + // Note that since we're not removing the entire declaration, the struct's reference + // count will end up being one less than the correct refcount. But since the struct + // declaration is kept, the incorrect refcount can't cause any other problems. + + if (declarator->getAsSymbolNode() && declarator->getAsSymbolNode()->getSymbol().empty()) + { + // Already an empty declaration - nothing to do. + return; + } + queueReplacementWithParent(node, declarator, + new TIntermSymbol(mSymbolTable->getEmptySymbolId(), + TString(""), declarator->getType()), + OriginalNode::IS_DROPPED); + return; + } + } + + if (getParentNode()->getAsBlock()) + { + TIntermSequence emptyReplacement; + mMultiReplacements.push_back( + NodeReplaceWithMultipleEntry(getParentNode()->getAsBlock(), node, emptyReplacement)); + } + else + { + ASSERT(getParentNode()->getAsLoopNode()); + queueReplacement(nullptr, OriginalNode::IS_DROPPED); + } +} + +bool RemoveUnreferencedVariablesTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node) +{ + if (visit == PreVisit) + { + // SeparateDeclarations should have already been run. + ASSERT(node->getSequence()->size() == 1u); + + TIntermTyped *declarator = node->getSequence()->back()->getAsTyped(); + ASSERT(declarator); + + // We can only remove variables that are not a part of the shader interface. + TQualifier qualifier = declarator->getQualifier(); + if (qualifier != EvqTemporary && qualifier != EvqGlobal) + { + return true; + } + + bool canRemoveVariable = false; + TIntermSymbol *symbolNode = declarator->getAsSymbolNode(); + if (symbolNode != nullptr) + { + canRemoveVariable = + (*mSymbolIdRefCounts)[symbolNode->getId()] == 1u || symbolNode->getSymbol().empty(); + } + TIntermBinary *initNode = declarator->getAsBinaryNode(); + if (initNode != nullptr) + { + ASSERT(initNode->getLeft()->getAsSymbolNode()); + int symbolId = initNode->getLeft()->getAsSymbolNode()->getId(); + canRemoveVariable = + (*mSymbolIdRefCounts)[symbolId] == 1u && !initNode->getRight()->hasSideEffects(); + } + + if (canRemoveVariable) + { + removeVariableDeclaration(node, declarator); + mRemoveReferences = true; + } + return true; + } + ASSERT(visit == PostVisit); + mRemoveReferences = false; + return true; +} + +void RemoveUnreferencedVariablesTraverser::visitSymbol(TIntermSymbol *node) +{ + if (mRemoveReferences) + { + ASSERT(mSymbolIdRefCounts->find(node->getId()) != mSymbolIdRefCounts->end()); + --(*mSymbolIdRefCounts)[node->getId()]; + + decrementStructTypeRefCount(node->getType()); + } +} + +bool RemoveUnreferencedVariablesTraverser::visitAggregate(Visit visit, TIntermAggregate *node) +{ + if (mRemoveReferences) + { + decrementStructTypeRefCount(node->getType()); + } + return true; +} + +void RemoveUnreferencedVariablesTraverser::traverseBlock(TIntermBlock *node) +{ + // We traverse blocks in reverse order. This way reference counts can be decremented when + // removing initializers, and variables that become unused when initializers are removed can be + // removed on the same traversal. + + ScopedNodeInTraversalPath addToPath(this, node); + + bool visit = true; + + TIntermSequence *sequence = node->getSequence(); + + if (preVisit) + visit = visitBlock(PreVisit, node); + + if (visit) + { + for (auto iter = sequence->rbegin(); iter != sequence->rend(); ++iter) + { + (*iter)->traverse(this); + if (visit && inVisit) + { + if ((iter + 1) != sequence->rend()) + visit = visitBlock(InVisit, node); + } + } + } + + if (visit && postVisit) + visitBlock(PostVisit, node); +} + +void RemoveUnreferencedVariablesTraverser::traverseLoop(TIntermLoop *node) +{ + // We traverse loops in reverse order as well. The loop body gets traversed before the init + // node. + + ScopedNodeInTraversalPath addToPath(this, node); + + bool visit = true; + + if (preVisit) + visit = visitLoop(PreVisit, node); + + if (visit) + { + // We don't need to traverse loop expressions or conditions since they can't be declarations + // in the AST (loops which have a declaration in their condition get transformed in the + // parsing stage). + ASSERT(node->getExpression() == nullptr || + node->getExpression()->getAsDeclarationNode() == nullptr); + ASSERT(node->getCondition() == nullptr || + node->getCondition()->getAsDeclarationNode() == nullptr); + + if (node->getBody()) + node->getBody()->traverse(this); + + if (node->getInit()) + node->getInit()->traverse(this); + } + + if (visit && postVisit) + visitLoop(PostVisit, node); +} + +} // namespace + +void RemoveUnreferencedVariables(TIntermBlock *root, TSymbolTable *symbolTable) +{ + CollectVariableRefCountsTraverser collector; + root->traverse(&collector); + RemoveUnreferencedVariablesTraverser traverser(&collector.getSymbolIdRefCounts(), + &collector.getStructIdRefCounts(), symbolTable); + root->traverse(&traverser); + traverser.updateTree(); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/RemoveUnreferencedVariables.h b/src/3rdparty/angle/src/compiler/translator/RemoveUnreferencedVariables.h new file mode 100644 index 0000000000..39c8327776 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/RemoveUnreferencedVariables.h @@ -0,0 +1,24 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// RemoveUnreferencedVariables.h: +// Drop variables that are declared but never referenced in the AST. This avoids adding unnecessary +// initialization code for them. Also removes unreferenced struct types. +// + +#ifndef COMPILER_TRANSLATOR_REMOVEUNREFERENCEDVARIABLES_H_ +#define COMPILER_TRANSLATOR_REMOVEUNREFERENCEDVARIABLES_H_ + +namespace sh +{ + +class TIntermBlock; +class TSymbolTable; + +void RemoveUnreferencedVariables(TIntermBlock *root, TSymbolTable *symbolTable); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_REMOVEUNREFERENCEDVARIABLES_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/RenameFunction.h b/src/3rdparty/angle/src/compiler/translator/RenameFunction.h deleted file mode 100644 index fd6a365fea..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/RenameFunction.h +++ /dev/null @@ -1,36 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_TRANSLATOR_RENAMEFUNCTION_H_ -#define COMPILER_TRANSLATOR_RENAMEFUNCTION_H_ - -#include "compiler/translator/IntermNode.h" - -// -// Renames a function, including its declaration and any calls to it. -// -class RenameFunction : public TIntermTraverser -{ -public: - RenameFunction(const TString& oldFunctionName, const TString& newFunctionName) - : TIntermTraverser(true, false, false) - , mOldFunctionName(oldFunctionName) - , mNewFunctionName(newFunctionName) {} - - bool visitAggregate(Visit visit, TIntermAggregate *node) override - { - TOperator op = node->getOp(); - if ((op == EOpFunction || op == EOpFunctionCall) && node->getName() == mOldFunctionName) - node->setName(mNewFunctionName); - return true; - } - -private: - const TString mOldFunctionName; - const TString mNewFunctionName; -}; - -#endif // COMPILER_TRANSLATOR_RENAMEFUNCTION_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/RewriteDoWhile.cpp b/src/3rdparty/angle/src/compiler/translator/RewriteDoWhile.cpp index 8347447546..dc3fb7a74e 100644 --- a/src/3rdparty/angle/src/compiler/translator/RewriteDoWhile.cpp +++ b/src/3rdparty/angle/src/compiler/translator/RewriteDoWhile.cpp @@ -9,7 +9,10 @@ #include "compiler/translator/RewriteDoWhile.h" -#include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermTraverse.h" + +namespace sh +{ namespace { @@ -41,17 +44,15 @@ namespace class DoWhileRewriter : public TIntermTraverser { public: - DoWhileRewriter() : TIntermTraverser(true, false, false) {} - - bool visitAggregate(Visit, TIntermAggregate *node) override + DoWhileRewriter(TSymbolTable *symbolTable) : TIntermTraverser(true, false, false, symbolTable) { - // A well-formed AST can only have do-while in EOpSequence which represent lists of - // statements. By doing a prefix traversal we are able to replace the do-while in the - // sequence directly as the content of the do-while will be traversed later. - if (node->getOp() != EOpSequence) - { - return true; - } + } + + bool visitBlock(Visit, TIntermBlock *node) override + { + // A well-formed AST can only have do-while inside TIntermBlock. By doing a prefix traversal + // we are able to replace the do-while in the sequence directly as the content of the + // do-while will be traversed later. TIntermSequence *statements = node->getSequence(); @@ -68,10 +69,13 @@ class DoWhileRewriter : public TIntermTraverser continue; } + // Found a loop to change. + nextTemporaryId(); + TType boolType = TType(EbtBool); // bool temp = false; - TIntermAggregate *tempDeclaration = nullptr; + TIntermDeclaration *tempDeclaration = nullptr; { TConstantUnion *falseConstant = new TConstantUnion(); falseConstant->setBConst(false); @@ -95,23 +99,22 @@ class DoWhileRewriter : public TIntermTraverser // break; // } // } - TIntermSelection *breakIf = nullptr; + TIntermIfElse *breakIf = nullptr; { TIntermBranch *breakStatement = new TIntermBranch(EOpBreak, nullptr); - TIntermAggregate *breakBlock = new TIntermAggregate(EOpSequence); + TIntermBlock *breakBlock = new TIntermBlock(); breakBlock->getSequence()->push_back(breakStatement); - TIntermUnary *negatedCondition = new TIntermUnary(EOpLogicalNot); - negatedCondition->setOperand(loop->getCondition()); + TIntermUnary *negatedCondition = + new TIntermUnary(EOpLogicalNot, loop->getCondition()); - TIntermSelection *innerIf = - new TIntermSelection(negatedCondition, breakBlock, nullptr); + TIntermIfElse *innerIf = new TIntermIfElse(negatedCondition, breakBlock, nullptr); - TIntermAggregate *innerIfBlock = new TIntermAggregate(EOpSequence); + TIntermBlock *innerIfBlock = new TIntermBlock(); innerIfBlock->getSequence()->push_back(innerIf); - breakIf = new TIntermSelection(createTempSymbol(boolType), innerIfBlock, nullptr); + breakIf = new TIntermIfElse(createTempSymbol(boolType), innerIfBlock, nullptr); } // Assemble the replacement loops, reusing the do-while loop's body and inserting our @@ -122,14 +125,10 @@ class DoWhileRewriter : public TIntermTraverser trueConstant->setBConst(true); TIntermTyped *trueValue = new TIntermConstantUnion(trueConstant, boolType); - TIntermAggregate *body = nullptr; - if (loop->getBody() != nullptr) + TIntermBlock *body = loop->getBody(); + if (body == nullptr) { - body = loop->getBody()->getAsAggregate(); - } - else - { - body = new TIntermAggregate(EOpSequence); + body = new TIntermBlock(); } auto sequence = body->getSequence(); sequence->insert(sequence->begin(), assignTrue); @@ -143,8 +142,6 @@ class DoWhileRewriter : public TIntermTraverser replacement.push_back(newLoop); node->replaceChildNodeWithMultiple(loop, replacement); - - nextTemporaryIndex(); } return true; } @@ -152,12 +149,11 @@ class DoWhileRewriter : public TIntermTraverser } // anonymous namespace -void RewriteDoWhile(TIntermNode *root, unsigned int *temporaryIndex) +void RewriteDoWhile(TIntermNode *root, TSymbolTable *symbolTable) { - ASSERT(temporaryIndex != 0); - - DoWhileRewriter rewriter; - rewriter.useTemporaryIndex(temporaryIndex); + DoWhileRewriter rewriter(symbolTable); root->traverse(&rewriter); } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/RewriteDoWhile.h b/src/3rdparty/angle/src/compiler/translator/RewriteDoWhile.h index f6ec1caf06..e83bfc4b56 100644 --- a/src/3rdparty/angle/src/compiler/translator/RewriteDoWhile.h +++ b/src/3rdparty/angle/src/compiler/translator/RewriteDoWhile.h @@ -10,7 +10,14 @@ #ifndef COMPILER_TRANSLATOR_REWRITEDOWHILE_H_ #define COMPILER_TRANSLATOR_REWRITEDOWHILE_H_ +namespace sh +{ + class TIntermNode; -void RewriteDoWhile(TIntermNode *root, unsigned int *temporaryIndex); +class TSymbolTable; + +void RewriteDoWhile(TIntermNode *root, TSymbolTable *symbolTable); + +} // namespace sh #endif // COMPILER_TRANSLATOR_REWRITEDOWHILE_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/RewriteElseBlocks.cpp b/src/3rdparty/angle/src/compiler/translator/RewriteElseBlocks.cpp index 52ede17434..ed1bfad8a8 100644 --- a/src/3rdparty/angle/src/compiler/translator/RewriteElseBlocks.cpp +++ b/src/3rdparty/angle/src/compiler/translator/RewriteElseBlocks.cpp @@ -8,6 +8,9 @@ // #include "compiler/translator/RewriteElseBlocks.h" + +#include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermNode_util.h" #include "compiler/translator/NodeSearch.h" #include "compiler/translator/SymbolTable.h" @@ -20,121 +23,98 @@ namespace class ElseBlockRewriter : public TIntermTraverser { public: - ElseBlockRewriter(); + ElseBlockRewriter(TSymbolTable *symbolTable); protected: - bool visitAggregate(Visit visit, TIntermAggregate *aggregate) override; + bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *aggregate) override; + bool visitBlock(Visit visit, TIntermBlock *block) override; private: - const TType *mFunctionType; + TIntermNode *rewriteIfElse(TIntermIfElse *ifElse); - TIntermNode *rewriteSelection(TIntermSelection *selection); + const TType *mFunctionType; }; -TIntermUnary *MakeNewUnary(TOperator op, TIntermTyped *operand) +ElseBlockRewriter::ElseBlockRewriter(TSymbolTable *symbolTable) + : TIntermTraverser(true, false, true, symbolTable), mFunctionType(nullptr) { - TIntermUnary *unary = new TIntermUnary(op, operand->getType()); - unary->setOperand(operand); - return unary; } -ElseBlockRewriter::ElseBlockRewriter() - : TIntermTraverser(true, false, true), - mFunctionType(NULL) -{} - -bool ElseBlockRewriter::visitAggregate(Visit visit, TIntermAggregate *node) +bool ElseBlockRewriter::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) { - switch (node->getOp()) - { - case EOpSequence: - if (visit == PostVisit) - { - for (size_t statementIndex = 0; statementIndex != node->getSequence()->size(); statementIndex++) - { - TIntermNode *statement = (*node->getSequence())[statementIndex]; - TIntermSelection *selection = statement->getAsSelectionNode(); - if (selection && selection->getFalseBlock() != nullptr) - { - // Check for if / else if - TIntermSelection *elseIfBranch = selection->getFalseBlock()->getAsSelectionNode(); - if (elseIfBranch) - { - selection->replaceChildNode(elseIfBranch, rewriteSelection(elseIfBranch)); - delete elseIfBranch; - } - - (*node->getSequence())[statementIndex] = rewriteSelection(selection); - delete selection; - } - } - } - break; - - case EOpFunction: - // Store the current function context (see comment below) - mFunctionType = ((visit == PreVisit) ? &node->getType() : NULL); - break; - - default: break; - } - + // Store the current function context (see comment below) + mFunctionType = ((visit == PreVisit) ? &node->getFunctionPrototype()->getType() : nullptr); return true; } -TIntermNode *ElseBlockRewriter::rewriteSelection(TIntermSelection *selection) +bool ElseBlockRewriter::visitBlock(Visit visit, TIntermBlock *node) { - ASSERT(selection != nullptr); + if (visit == PostVisit) + { + for (size_t statementIndex = 0; statementIndex != node->getSequence()->size(); + statementIndex++) + { + TIntermNode *statement = (*node->getSequence())[statementIndex]; + TIntermIfElse *ifElse = statement->getAsIfElseNode(); + if (ifElse && ifElse->getFalseBlock() != nullptr) + { + (*node->getSequence())[statementIndex] = rewriteIfElse(ifElse); + } + } + } + return true; +} - nextTemporaryIndex(); +TIntermNode *ElseBlockRewriter::rewriteIfElse(TIntermIfElse *ifElse) +{ + ASSERT(ifElse != nullptr); - TIntermTyped *typedCondition = selection->getCondition()->getAsTyped(); - TIntermAggregate *storeCondition = createTempInitDeclaration(typedCondition); + nextTemporaryId(); - TIntermSelection *falseBlock = nullptr; + TIntermDeclaration *storeCondition = createTempInitDeclaration(ifElse->getCondition()); + + TIntermBlock *falseBlock = nullptr; TType boolType(EbtBool, EbpUndefined, EvqTemporary); - if (selection->getFalseBlock()) + if (ifElse->getFalseBlock()) { - TIntermAggregate *negatedElse = nullptr; + TIntermBlock *negatedElse = nullptr; // crbug.com/346463 // D3D generates error messages claiming a function has no return value, when rewriting // an if-else clause that returns something non-void in a function. By appending dummy // returns (that are unreachable) we can silence this compile error. if (mFunctionType && mFunctionType->getBasicType() != EbtVoid) { - TString typeString = mFunctionType->getStruct() ? mFunctionType->getStruct()->name() : - mFunctionType->getBasicString(); - TString rawText = "return (" + typeString + ")0"; - TIntermRaw *returnNode = new TIntermRaw(*mFunctionType, rawText); - negatedElse = new TIntermAggregate(EOpSequence); - negatedElse->getSequence()->push_back(returnNode); + TIntermNode *returnNode = new TIntermBranch(EOpReturn, CreateZeroNode(*mFunctionType)); + negatedElse = new TIntermBlock(); + negatedElse->appendStatement(returnNode); } TIntermSymbol *conditionSymbolElse = createTempSymbol(boolType); - TIntermUnary *negatedCondition = MakeNewUnary(EOpLogicalNot, conditionSymbolElse); - falseBlock = new TIntermSelection(negatedCondition, - selection->getFalseBlock(), negatedElse); + TIntermUnary *negatedCondition = new TIntermUnary(EOpLogicalNot, conditionSymbolElse); + TIntermIfElse *falseIfElse = + new TIntermIfElse(negatedCondition, ifElse->getFalseBlock(), negatedElse); + falseBlock = EnsureBlock(falseIfElse); } TIntermSymbol *conditionSymbolSel = createTempSymbol(boolType); - TIntermSelection *newSelection = new TIntermSelection(conditionSymbolSel, selection->getTrueBlock(), falseBlock); + TIntermIfElse *newIfElse = + new TIntermIfElse(conditionSymbolSel, ifElse->getTrueBlock(), falseBlock); - TIntermAggregate *block = new TIntermAggregate(EOpSequence); + TIntermBlock *block = new TIntermBlock(); block->getSequence()->push_back(storeCondition); - block->getSequence()->push_back(newSelection); + block->getSequence()->push_back(newIfElse); return block; } -} +} // anonymous namespace -void RewriteElseBlocks(TIntermNode *node, unsigned int *temporaryIndex) +void RewriteElseBlocks(TIntermNode *node, TSymbolTable *symbolTable) { - ElseBlockRewriter rewriter; - rewriter.useTemporaryIndex(temporaryIndex); + ElseBlockRewriter rewriter(symbolTable); node->traverse(&rewriter); } -} +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/RewriteElseBlocks.h b/src/3rdparty/angle/src/compiler/translator/RewriteElseBlocks.h index 24a425e66d..2586b5405c 100644 --- a/src/3rdparty/angle/src/compiler/translator/RewriteElseBlocks.h +++ b/src/3rdparty/angle/src/compiler/translator/RewriteElseBlocks.h @@ -10,13 +10,13 @@ #ifndef COMPILER_TRANSLATOR_REWRITEELSEBLOCKS_H_ #define COMPILER_TRANSLATOR_REWRITEELSEBLOCKS_H_ -#include "compiler/translator/IntermNode.h" - namespace sh { -void RewriteElseBlocks(TIntermNode *node, unsigned int *temporaryIndex); +class TIntermNode; +class TSymbolTable; +void RewriteElseBlocks(TIntermNode *node, TSymbolTable *symbolTable); } -#endif // COMPILER_TRANSLATOR_REWRITEELSEBLOCKS_H_ +#endif // COMPILER_TRANSLATOR_REWRITEELSEBLOCKS_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/RewriteTexelFetchOffset.cpp b/src/3rdparty/angle/src/compiler/translator/RewriteTexelFetchOffset.cpp new file mode 100644 index 0000000000..b602e0c923 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/RewriteTexelFetchOffset.cpp @@ -0,0 +1,154 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Implementation of texelFetchOffset translation issue workaround. +// See header for more info. + +#include "compiler/translator/RewriteTexelFetchOffset.h" + +#include "common/angleutils.h" +#include "compiler/translator/IntermNode_util.h" +#include "compiler/translator/IntermTraverse.h" +#include "compiler/translator/SymbolTable.h" + +namespace sh +{ + +namespace +{ + +class Traverser : public TIntermTraverser +{ + public: + static void Apply(TIntermNode *root, const TSymbolTable &symbolTable, int shaderVersion); + + private: + Traverser(const TSymbolTable &symbolTable, int shaderVersion); + bool visitAggregate(Visit visit, TIntermAggregate *node) override; + void nextIteration(); + + const TSymbolTable *symbolTable; + const int shaderVersion; + bool mFound = false; +}; + +Traverser::Traverser(const TSymbolTable &symbolTable, int shaderVersion) + : TIntermTraverser(true, false, false), symbolTable(&symbolTable), shaderVersion(shaderVersion) +{ +} + +// static +void Traverser::Apply(TIntermNode *root, const TSymbolTable &symbolTable, int shaderVersion) +{ + Traverser traverser(symbolTable, shaderVersion); + do + { + traverser.nextIteration(); + root->traverse(&traverser); + if (traverser.mFound) + { + traverser.updateTree(); + } + } while (traverser.mFound); +} + +void Traverser::nextIteration() +{ + mFound = false; +} + +bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node) +{ + if (mFound) + { + return false; + } + + // Decide if the node represents the call of texelFetchOffset. + if (node->getOp() != EOpCallBuiltInFunction) + { + return true; + } + + if (node->getFunctionSymbolInfo()->getName() != "texelFetchOffset") + { + return true; + } + + // Potential problem case detected, apply workaround. + const TIntermSequence *sequence = node->getSequence(); + ASSERT(sequence->size() == 4u); + + // Decide if the sampler is a 2DArray sampler. In that case position is ivec3 and offset is + // ivec2. + bool is2DArray = sequence->at(1)->getAsTyped()->getNominalSize() == 3 && + sequence->at(3)->getAsTyped()->getNominalSize() == 2; + + // Create new node that represents the call of function texelFetch. + // Its argument list will be: texelFetch(sampler, Position+offset, lod). + + TIntermSequence *texelFetchArguments = new TIntermSequence(); + + // sampler + texelFetchArguments->push_back(sequence->at(0)); + + // Position + TIntermTyped *texCoordNode = sequence->at(1)->getAsTyped(); + ASSERT(texCoordNode); + + // offset + TIntermTyped *offsetNode = nullptr; + ASSERT(sequence->at(3)->getAsTyped()); + if (is2DArray) + { + // For 2DArray samplers, Position is ivec3 and offset is ivec2; + // So offset must be converted into an ivec3 before being added to Position. + TIntermSequence *constructOffsetIvecArguments = new TIntermSequence(); + constructOffsetIvecArguments->push_back(sequence->at(3)->getAsTyped()); + + TIntermTyped *zeroNode = CreateZeroNode(TType(EbtInt)); + constructOffsetIvecArguments->push_back(zeroNode); + + offsetNode = TIntermAggregate::CreateConstructor(texCoordNode->getType(), + constructOffsetIvecArguments); + offsetNode->setLine(texCoordNode->getLine()); + } + else + { + offsetNode = sequence->at(3)->getAsTyped(); + } + + // Position+offset + TIntermBinary *add = new TIntermBinary(EOpAdd, texCoordNode, offsetNode); + add->setLine(texCoordNode->getLine()); + texelFetchArguments->push_back(add); + + // lod + texelFetchArguments->push_back(sequence->at(2)); + + ASSERT(texelFetchArguments->size() == 3u); + + TIntermTyped *texelFetchNode = CreateBuiltInFunctionCallNode("texelFetch", texelFetchArguments, + *symbolTable, shaderVersion); + texelFetchNode->setLine(node->getLine()); + + // Replace the old node by this new node. + queueReplacement(texelFetchNode, OriginalNode::IS_DROPPED); + mFound = true; + return false; +} + +} // anonymous namespace + +void RewriteTexelFetchOffset(TIntermNode *root, const TSymbolTable &symbolTable, int shaderVersion) +{ + // texelFetchOffset is only valid in GLSL 3.0 and later. + if (shaderVersion < 300) + return; + + Traverser::Apply(root, symbolTable, shaderVersion); +} + +} // namespace sh \ No newline at end of file diff --git a/src/3rdparty/angle/src/compiler/translator/RewriteTexelFetchOffset.h b/src/3rdparty/angle/src/compiler/translator/RewriteTexelFetchOffset.h new file mode 100644 index 0000000000..694d709f8e --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/RewriteTexelFetchOffset.h @@ -0,0 +1,28 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// This mutating tree traversal works around an issue on the translation +// from texelFetchOffset into HLSL function Load on INTEL drivers. It +// works by translating texelFetchOffset into texelFetch: +// +// - From: texelFetchOffset(sampler, Position, lod, offset) +// - To: texelFetch(sampler, Position+offset, lod) +// +// See http://anglebug.com/1469 + +#ifndef COMPILER_TRANSLATOR_REWRITE_TEXELFETCHOFFSET_H_ +#define COMPILER_TRANSLATOR_REWRITE_TEXELFETCHOFFSET_H_ + +class TIntermNode; +class TSymbolTable; + +namespace sh +{ + +void RewriteTexelFetchOffset(TIntermNode *root, const TSymbolTable &symbolTable, int shaderVersion); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_REWRITE_TEXELFETCHOFFSET_H_ \ No newline at end of file diff --git a/src/3rdparty/angle/src/compiler/translator/RewriteUnaryMinusOperatorFloat.cpp b/src/3rdparty/angle/src/compiler/translator/RewriteUnaryMinusOperatorFloat.cpp new file mode 100644 index 0000000000..696a49536c --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/RewriteUnaryMinusOperatorFloat.cpp @@ -0,0 +1,94 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/translator/RewriteUnaryMinusOperatorFloat.h" + +#include "compiler/translator/IntermNode_util.h" +#include "compiler/translator/IntermTraverse.h" + +namespace sh +{ + +namespace +{ + +class Traverser : public TIntermTraverser +{ + public: + static void Apply(TIntermNode *root); + + private: + Traverser(); + bool visitUnary(Visit visit, TIntermUnary *node) override; + void nextIteration(); + + bool mFound = false; +}; + +// static +void Traverser::Apply(TIntermNode *root) +{ + Traverser traverser; + do + { + traverser.nextIteration(); + root->traverse(&traverser); + if (traverser.mFound) + { + traverser.updateTree(); + } + } while (traverser.mFound); +} + +Traverser::Traverser() : TIntermTraverser(true, false, false) +{ +} + +void Traverser::nextIteration() +{ + mFound = false; +} + +bool Traverser::visitUnary(Visit visit, TIntermUnary *node) +{ + if (mFound) + { + return false; + } + + // Detect if the current operator is unary minus operator. + if (node->getOp() != EOpNegative) + { + return true; + } + + // Detect if the current operand is a float variable. + TIntermTyped *fValue = node->getOperand(); + if (!fValue->getType().isScalarFloat()) + { + return true; + } + + // 0.0 - float + TIntermTyped *zero = CreateZeroNode(fValue->getType()); + zero->setLine(fValue->getLine()); + TIntermBinary *sub = new TIntermBinary(EOpSub, zero, fValue); + sub->setLine(fValue->getLine()); + + queueReplacement(sub, OriginalNode::IS_DROPPED); + + mFound = true; + return false; +} + +} // anonymous namespace + +void RewriteUnaryMinusOperatorFloat(TIntermNode *root) +{ + Traverser::Apply(root); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/RewriteUnaryMinusOperatorFloat.h b/src/3rdparty/angle/src/compiler/translator/RewriteUnaryMinusOperatorFloat.h new file mode 100644 index 0000000000..ccbfbcbd9e --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/RewriteUnaryMinusOperatorFloat.h @@ -0,0 +1,19 @@ +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Rewrite "-float" to "0.0 - float" to work around unary minus operator on float issue on Intel Mac +// OSX 10.11. + +#ifndef COMPILER_TRANSLATOR_REWRITEUNARYMINUSOPERATORFLOAT_H_ +#define COMPILER_TRANSLATOR_REWRITEUNARYMINUSOPERATORFLOAT_H_ + +class TIntermNode; +namespace sh +{ + +void RewriteUnaryMinusOperatorFloat(TIntermNode *root); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_REWRITEUNARYMINUSOPERATORFLOAT_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/RewriteUnaryMinusOperatorInt.cpp b/src/3rdparty/angle/src/compiler/translator/RewriteUnaryMinusOperatorInt.cpp new file mode 100644 index 0000000000..fe2ef948b4 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/RewriteUnaryMinusOperatorInt.cpp @@ -0,0 +1,112 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Implementation of evaluating unary integer variable bug workaround. +// See header for more info. + +#include "compiler/translator/RewriteUnaryMinusOperatorInt.h" + +#include "compiler/translator/IntermTraverse.h" + +namespace sh +{ + +namespace +{ + +class Traverser : public TIntermTraverser +{ + public: + static void Apply(TIntermNode *root); + + private: + Traverser(); + bool visitUnary(Visit visit, TIntermUnary *node) override; + void nextIteration(); + + bool mFound = false; +}; + +// static +void Traverser::Apply(TIntermNode *root) +{ + Traverser traverser; + do + { + traverser.nextIteration(); + root->traverse(&traverser); + if (traverser.mFound) + { + traverser.updateTree(); + } + } while (traverser.mFound); +} + +Traverser::Traverser() : TIntermTraverser(true, false, false) +{ +} + +void Traverser::nextIteration() +{ + mFound = false; +} + +bool Traverser::visitUnary(Visit visit, TIntermUnary *node) +{ + if (mFound) + { + return false; + } + + // Decide if the current unary operator is unary minus. + if (node->getOp() != EOpNegative) + { + return true; + } + + // Decide if the current operand is an integer variable. + TIntermTyped *opr = node->getOperand(); + if (!opr->getType().isScalarInt()) + { + return true; + } + + // Potential problem case detected, apply workaround: -(int) -> ~(int) + 1. + // ~(int) + TIntermUnary *bitwiseNot = new TIntermUnary(EOpBitwiseNot, opr); + bitwiseNot->setLine(opr->getLine()); + + // Constant 1 (or 1u) + TConstantUnion *one = new TConstantUnion(); + if (opr->getType().getBasicType() == EbtInt) + { + one->setIConst(1); + } + else + { + one->setUConst(1u); + } + TIntermConstantUnion *oneNode = new TIntermConstantUnion(one, opr->getType()); + oneNode->getTypePointer()->setQualifier(EvqConst); + oneNode->setLine(opr->getLine()); + + // ~(int) + 1 + TIntermBinary *add = new TIntermBinary(EOpAdd, bitwiseNot, oneNode); + add->setLine(opr->getLine()); + + queueReplacement(add, OriginalNode::IS_DROPPED); + + mFound = true; + return false; +} + +} // anonymous namespace + +void RewriteUnaryMinusOperatorInt(TIntermNode *root) +{ + Traverser::Apply(root); +} + +} // namespace sh \ No newline at end of file diff --git a/src/3rdparty/angle/src/compiler/translator/RewriteUnaryMinusOperatorInt.h b/src/3rdparty/angle/src/compiler/translator/RewriteUnaryMinusOperatorInt.h new file mode 100644 index 0000000000..50f0c442a7 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/RewriteUnaryMinusOperatorInt.h @@ -0,0 +1,20 @@ +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// This mutating tree traversal works around a bug on evaluating unary +// integer variable on Intel D3D driver. It works by rewriting -(int) to +// ~(int) + 1 when evaluating unary integer variables. + +#ifndef COMPILER_TRANSLATOR_REWRITEUNARYMINUSOPERATORINT_H_ +#define COMPILER_TRANSLATOR_REWRITEUNARYMINUSOPERATORINT_H_ + +class TIntermNode; +namespace sh +{ + +void RewriteUnaryMinusOperatorInt(TIntermNode *root); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_REWRITEUNARYMINUSOPERATORINT_H_ \ No newline at end of file diff --git a/src/3rdparty/angle/src/compiler/translator/RunAtTheEndOfShader.cpp b/src/3rdparty/angle/src/compiler/translator/RunAtTheEndOfShader.cpp new file mode 100644 index 0000000000..3c4209c539 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/RunAtTheEndOfShader.cpp @@ -0,0 +1,112 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// RunAtTheEndOfShader.cpp: Add code to be run at the end of the shader. In case main() contains a +// return statement, this is done by replacing the main() function with another function that calls +// the old main, like this: +// +// void main() { body } +// => +// void main0() { body } +// void main() +// { +// main0(); +// codeToRun +// } +// +// This way the code will get run even if the return statement inside main is executed. +// + +#include "compiler/translator/RunAtTheEndOfShader.h" + +#include "compiler/translator/FindMain.h" +#include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermNode_util.h" +#include "compiler/translator/IntermTraverse.h" +#include "compiler/translator/SymbolTable.h" + +namespace sh +{ + +namespace +{ + +class ContainsReturnTraverser : public TIntermTraverser +{ + public: + ContainsReturnTraverser() : TIntermTraverser(true, false, false), mContainsReturn(false) {} + + bool visitBranch(Visit visit, TIntermBranch *node) override + { + if (node->getFlowOp() == EOpReturn) + { + mContainsReturn = true; + } + return false; + } + + bool containsReturn() { return mContainsReturn; } + + private: + bool mContainsReturn; +}; + +bool ContainsReturn(TIntermNode *node) +{ + ContainsReturnTraverser traverser; + node->traverse(&traverser); + return traverser.containsReturn(); +} + +void WrapMainAndAppend(TIntermBlock *root, + TIntermFunctionDefinition *main, + TIntermNode *codeToRun, + TSymbolTable *symbolTable) +{ + // Replace main() with main0() with the same body. + TSymbolUniqueId oldMainId(symbolTable); + std::stringstream oldMainName; + oldMainName << "main" << oldMainId.get(); + TIntermFunctionDefinition *oldMain = CreateInternalFunctionDefinitionNode( + TType(EbtVoid), oldMainName.str().c_str(), main->getBody(), oldMainId); + + bool replaced = root->replaceChildNode(main, oldMain); + ASSERT(replaced); + + // void main() + TIntermFunctionPrototype *newMainProto = new TIntermFunctionPrototype( + TType(EbtVoid), main->getFunctionPrototype()->getFunctionSymbolInfo()->getId()); + newMainProto->getFunctionSymbolInfo()->setName("main"); + + // { + // main0(); + // codeToRun + // } + TIntermBlock *newMainBody = new TIntermBlock(); + TIntermAggregate *oldMainCall = CreateInternalFunctionCallNode( + TType(EbtVoid), oldMainName.str().c_str(), oldMainId, new TIntermSequence()); + newMainBody->appendStatement(oldMainCall); + newMainBody->appendStatement(codeToRun); + + // Add the new main() to the root node. + TIntermFunctionDefinition *newMain = new TIntermFunctionDefinition(newMainProto, newMainBody); + root->appendStatement(newMain); +} + +} // anonymous namespace + +void RunAtTheEndOfShader(TIntermBlock *root, TIntermNode *codeToRun, TSymbolTable *symbolTable) +{ + TIntermFunctionDefinition *main = FindMain(root); + if (!ContainsReturn(main)) + { + main->getBody()->appendStatement(codeToRun); + return; + } + + WrapMainAndAppend(root, main, codeToRun, symbolTable); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/RunAtTheEndOfShader.h b/src/3rdparty/angle/src/compiler/translator/RunAtTheEndOfShader.h new file mode 100644 index 0000000000..ed94c28dae --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/RunAtTheEndOfShader.h @@ -0,0 +1,23 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// RunAtTheEndOfShader.h: Add code to be run at the end of the shader. +// + +#ifndef COMPILER_TRANSLATOR_RUNATTHEENDOFSHADER_H_ +#define COMPILER_TRANSLATOR_RUNATTHEENDOFSHADER_H_ + +namespace sh +{ + +class TIntermBlock; +class TIntermNode; +class TSymbolTable; + +void RunAtTheEndOfShader(TIntermBlock *root, TIntermNode *codeToRun, TSymbolTable *symbolTable); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_RUNATTHEENDOFSHADER_H_ \ No newline at end of file diff --git a/src/3rdparty/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp b/src/3rdparty/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp index 775c5d8710..746c16e2e6 100644 --- a/src/3rdparty/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp +++ b/src/3rdparty/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp @@ -3,6 +3,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // +// Scalarize vector and matrix constructor args, so that vectors built from components don't have +// matrix arguments, and matrices built from components don't have vector arguments. This avoids +// driver bugs around vector and matrix constructors. +// #include "common/debug.h" #include "compiler/translator/ScalarizeVecAndMatConstructorArgs.h" @@ -11,6 +15,11 @@ #include "angle_gl.h" #include "common/angleutils.h" +#include "compiler/translator/IntermNode_util.h" +#include "compiler/translator/IntermTraverse.h" + +namespace sh +{ namespace { @@ -37,140 +46,93 @@ bool ContainsVectorNode(const TIntermSequence &sequence) return false; } -TIntermConstantUnion *ConstructIndexNode(int index) -{ - TConstantUnion *u = new TConstantUnion[1]; - u[0].setIConst(index); - - TType type(EbtInt, EbpUndefined, EvqConst, 1); - TIntermConstantUnion *node = new TIntermConstantUnion(u, type); - return node; -} - TIntermBinary *ConstructVectorIndexBinaryNode(TIntermSymbol *symbolNode, int index) { - TIntermBinary *binary = new TIntermBinary(EOpIndexDirect); - binary->setLeft(symbolNode); - TIntermConstantUnion *indexNode = ConstructIndexNode(index); - binary->setRight(indexNode); - return binary; + return new TIntermBinary(EOpIndexDirect, symbolNode, CreateIndexNode(index)); } -TIntermBinary *ConstructMatrixIndexBinaryNode( - TIntermSymbol *symbolNode, int colIndex, int rowIndex) +TIntermBinary *ConstructMatrixIndexBinaryNode(TIntermSymbol *symbolNode, int colIndex, int rowIndex) { - TIntermBinary *colVectorNode = - ConstructVectorIndexBinaryNode(symbolNode, colIndex); + TIntermBinary *colVectorNode = ConstructVectorIndexBinaryNode(symbolNode, colIndex); - TIntermBinary *binary = new TIntermBinary(EOpIndexDirect); - binary->setLeft(colVectorNode); - TIntermConstantUnion *rowIndexNode = ConstructIndexNode(rowIndex); - binary->setRight(rowIndexNode); - return binary; + return new TIntermBinary(EOpIndexDirect, colVectorNode, CreateIndexNode(rowIndex)); } -} // namespace anonymous - -bool ScalarizeVecAndMatConstructorArgs::visitAggregate(Visit visit, TIntermAggregate *node) +class ScalarizeArgsTraverser : public TIntermTraverser { - if (visit == PreVisit) + public: + ScalarizeArgsTraverser(sh::GLenum shaderType, + bool fragmentPrecisionHigh, + TSymbolTable *symbolTable) + : TIntermTraverser(true, false, false, symbolTable), + mShaderType(shaderType), + mFragmentPrecisionHigh(fragmentPrecisionHigh) { - switch (node->getOp()) - { - case EOpSequence: - mSequenceStack.push_back(TIntermSequence()); - { - for (TIntermSequence::const_iterator iter = node->getSequence()->begin(); - iter != node->getSequence()->end(); ++iter) - { - TIntermNode *child = *iter; - ASSERT(child != NULL); - child->traverse(this); - mSequenceStack.back().push_back(child); - } - } - if (mSequenceStack.back().size() > node->getSequence()->size()) - { - node->getSequence()->clear(); - *(node->getSequence()) = mSequenceStack.back(); - } - mSequenceStack.pop_back(); - return false; - case EOpConstructVec2: - case EOpConstructVec3: - case EOpConstructVec4: - case EOpConstructBVec2: - case EOpConstructBVec3: - case EOpConstructBVec4: - case EOpConstructIVec2: - case EOpConstructIVec3: - case EOpConstructIVec4: - if (ContainsMatrixNode(*(node->getSequence()))) - scalarizeArgs(node, false, true); - break; - case EOpConstructMat2: - case EOpConstructMat2x3: - case EOpConstructMat2x4: - case EOpConstructMat3x2: - case EOpConstructMat3: - case EOpConstructMat3x4: - case EOpConstructMat4x2: - case EOpConstructMat4x3: - case EOpConstructMat4: - if (ContainsVectorNode(*(node->getSequence()))) - scalarizeArgs(node, true, false); - break; - default: - break; - } + } + + protected: + bool visitAggregate(Visit visit, TIntermAggregate *node) override; + bool visitBlock(Visit visit, TIntermBlock *node) override; + + private: + void scalarizeArgs(TIntermAggregate *aggregate, bool scalarizeVector, bool scalarizeMatrix); + + // If we have the following code: + // mat4 m(0); + // vec4 v(1, m); + // We will rewrite to: + // mat4 m(0); + // mat4 s0 = m; + // vec4 v(1, s0[0][0], s0[0][1], s0[0][2]); + // This function is to create nodes for "mat4 s0 = m;" and insert it to the code sequence. This + // way the possible side effects of the constructor argument will only be evaluated once. + void createTempVariable(TIntermTyped *original); + + std::vector mBlockStack; + + sh::GLenum mShaderType; + bool mFragmentPrecisionHigh; +}; + +bool ScalarizeArgsTraverser::visitAggregate(Visit visit, TIntermAggregate *node) +{ + if (visit == PreVisit && node->getOp() == EOpConstruct) + { + if (node->getType().isVector() && ContainsMatrixNode(*(node->getSequence()))) + scalarizeArgs(node, false, true); + else if (node->getType().isMatrix() && ContainsVectorNode(*(node->getSequence()))) + scalarizeArgs(node, true, false); } return true; } -void ScalarizeVecAndMatConstructorArgs::scalarizeArgs( - TIntermAggregate *aggregate, bool scalarizeVector, bool scalarizeMatrix) +bool ScalarizeArgsTraverser::visitBlock(Visit visit, TIntermBlock *node) +{ + mBlockStack.push_back(TIntermSequence()); + { + for (TIntermNode *child : *node->getSequence()) + { + ASSERT(child != nullptr); + child->traverse(this); + mBlockStack.back().push_back(child); + } + } + if (mBlockStack.back().size() > node->getSequence()->size()) + { + node->getSequence()->clear(); + *(node->getSequence()) = mBlockStack.back(); + } + mBlockStack.pop_back(); + return false; +} + +void ScalarizeArgsTraverser::scalarizeArgs(TIntermAggregate *aggregate, + bool scalarizeVector, + bool scalarizeMatrix) { ASSERT(aggregate); - int size = 0; - switch (aggregate->getOp()) - { - case EOpConstructVec2: - case EOpConstructBVec2: - case EOpConstructIVec2: - size = 2; - break; - case EOpConstructVec3: - case EOpConstructBVec3: - case EOpConstructIVec3: - size = 3; - break; - case EOpConstructVec4: - case EOpConstructBVec4: - case EOpConstructIVec4: - case EOpConstructMat2: - size = 4; - break; - case EOpConstructMat2x3: - case EOpConstructMat3x2: - size = 6; - break; - case EOpConstructMat2x4: - case EOpConstructMat4x2: - size = 8; - break; - case EOpConstructMat3: - size = 9; - break; - case EOpConstructMat3x4: - case EOpConstructMat4x3: - size = 12; - break; - case EOpConstructMat4: - size = 16; - break; - default: - break; - } + ASSERT(!aggregate->isArray()); + int size = static_cast(aggregate->getType().getObjectSize()); TIntermSequence *sequence = aggregate->getSequence(); TIntermSequence original(*sequence); sequence->clear(); @@ -179,12 +141,10 @@ void ScalarizeVecAndMatConstructorArgs::scalarizeArgs( ASSERT(size > 0); TIntermTyped *node = original[ii]->getAsTyped(); ASSERT(node); - TString varName = createTempVariable(node); + createTempVariable(node); if (node->isScalar()) { - TIntermSymbol *symbolNode = - new TIntermSymbol(-1, varName, node->getType()); - sequence->push_back(symbolNode); + sequence->push_back(createTempSymbol(node->getType())); size--; } else if (node->isVector()) @@ -195,17 +155,14 @@ void ScalarizeVecAndMatConstructorArgs::scalarizeArgs( size -= repeat; for (int index = 0; index < repeat; ++index) { - TIntermSymbol *symbolNode = - new TIntermSymbol(-1, varName, node->getType()); - TIntermBinary *newNode = ConstructVectorIndexBinaryNode( - symbolNode, index); + TIntermSymbol *symbolNode = createTempSymbol(node->getType()); + TIntermBinary *newNode = ConstructVectorIndexBinaryNode(symbolNode, index); sequence->push_back(newNode); } } else { - TIntermSymbol *symbolNode = - new TIntermSymbol(-1, varName, node->getType()); + TIntermSymbol *symbolNode = createTempSymbol(node->getType()); sequence->push_back(symbolNode); size -= node->getNominalSize(); } @@ -220,10 +177,9 @@ void ScalarizeVecAndMatConstructorArgs::scalarizeArgs( size -= repeat; while (repeat > 0) { - TIntermSymbol *symbolNode = - new TIntermSymbol(-1, varName, node->getType()); - TIntermBinary *newNode = ConstructMatrixIndexBinaryNode( - symbolNode, colIndex, rowIndex); + TIntermSymbol *symbolNode = createTempSymbol(node->getType()); + TIntermBinary *newNode = + ConstructMatrixIndexBinaryNode(symbolNode, colIndex, rowIndex); sequence->push_back(newNode); rowIndex++; if (rowIndex >= node->getRows()) @@ -236,8 +192,7 @@ void ScalarizeVecAndMatConstructorArgs::scalarizeArgs( } else { - TIntermSymbol *symbolNode = - new TIntermSymbol(-1, varName, node->getType()); + TIntermSymbol *symbolNode = createTempSymbol(node->getType()); sequence->push_back(symbolNode); size -= node->getCols() * node->getRows(); } @@ -245,51 +200,39 @@ void ScalarizeVecAndMatConstructorArgs::scalarizeArgs( } } -TString ScalarizeVecAndMatConstructorArgs::createTempVariable(TIntermTyped *original) +void ScalarizeArgsTraverser::createTempVariable(TIntermTyped *original) { - TString tempVarName = "_webgl_tmp_"; - if (original->isScalar()) - { - tempVarName += "scalar_"; - } - else if (original->isVector()) - { - tempVarName += "vec_"; - } - else - { - ASSERT(original->isMatrix()); - tempVarName += "mat_"; - } - tempVarName += Str(mTempVarCount).c_str(); - mTempVarCount++; - ASSERT(original); - TType type = original->getType(); - type.setQualifier(EvqTemporary); + nextTemporaryId(); + TIntermDeclaration *decl = createTempInitDeclaration(original); - if (mShaderType == GL_FRAGMENT_SHADER && - type.getBasicType() == EbtFloat && + TType type = original->getType(); + if (mShaderType == GL_FRAGMENT_SHADER && type.getBasicType() == EbtFloat && type.getPrecision() == EbpUndefined) { // We use the highest available precision for the temporary variable // to avoid computing the actual precision using the rules defined // in GLSL ES 1.0 Section 4.5.2. - type.setPrecision(mFragmentPrecisionHigh ? EbpHigh : EbpMedium); + TIntermBinary *init = decl->getSequence()->at(0)->getAsBinaryNode(); + init->getTypePointer()->setPrecision(mFragmentPrecisionHigh ? EbpHigh : EbpMedium); + init->getLeft()->getTypePointer()->setPrecision(mFragmentPrecisionHigh ? EbpHigh + : EbpMedium); } - TIntermBinary *init = new TIntermBinary(EOpInitialize); - TIntermSymbol *symbolNode = new TIntermSymbol(-1, tempVarName, type); - init->setLeft(symbolNode); - init->setRight(original); - init->setType(type); - - TIntermAggregate *decl = new TIntermAggregate(EOpDeclaration); - decl->getSequence()->push_back(init); - - ASSERT(mSequenceStack.size() > 0); - TIntermSequence &sequence = mSequenceStack.back(); + ASSERT(mBlockStack.size() > 0); + TIntermSequence &sequence = mBlockStack.back(); sequence.push_back(decl); - - return tempVarName; } + +} // namespace anonymous + +void ScalarizeVecAndMatConstructorArgs(TIntermBlock *root, + sh::GLenum shaderType, + bool fragmentPrecisionHigh, + TSymbolTable *symbolTable) +{ + ScalarizeArgsTraverser scalarizer(shaderType, fragmentPrecisionHigh, symbolTable); + root->traverse(&scalarizer); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h b/src/3rdparty/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h index d7553be23b..b8f782d1ec 100644 --- a/src/3rdparty/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h +++ b/src/3rdparty/angle/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h @@ -3,46 +3,25 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // +// Scalarize vector and matrix constructor args, so that vectors built from components don't have +// matrix arguments, and matrices built from components don't have vector arguments. This avoids +// driver bugs around vector and matrix constructors. +// #ifndef COMPILER_TRANSLATOR_SCALARIZEVECANDMATCONSTRUCTORARGS_H_ #define COMPILER_TRANSLATOR_SCALARIZEVECANDMATCONSTRUCTORARGS_H_ -#include "compiler/translator/IntermNode.h" +#include "GLSLANG/ShaderLang.h" -class ScalarizeVecAndMatConstructorArgs : public TIntermTraverser +namespace sh { - public: - ScalarizeVecAndMatConstructorArgs(sh::GLenum shaderType, - bool fragmentPrecisionHigh) - : TIntermTraverser(true, false, false), - mTempVarCount(0), - mShaderType(shaderType), - mFragmentPrecisionHigh(fragmentPrecisionHigh) {} +class TIntermBlock; +class TSymbolTable; - protected: - bool visitAggregate(Visit visit, TIntermAggregate *node) override; - - private: - void scalarizeArgs(TIntermAggregate *aggregate, - bool scalarizeVector, bool scalarizeMatrix); - - // If we have the following code: - // mat4 m(0); - // vec4 v(1, m); - // We will rewrite to: - // mat4 m(0); - // mat4 _webgl_tmp_mat_0 = m; - // vec4 v(1, _webgl_tmp_mat_0[0][0], _webgl_tmp_mat_0[0][1], _webgl_tmp_mat_0[0][2]); - // This function is to create nodes for "mat4 _webgl_tmp_mat_0 = m;" and insert it to - // the code sequence. - // Return the temporary variable name. - TString createTempVariable(TIntermTyped *original); - - std::vector mSequenceStack; - int mTempVarCount; - - sh::GLenum mShaderType; - bool mFragmentPrecisionHigh; -}; +void ScalarizeVecAndMatConstructorArgs(TIntermBlock *root, + sh::GLenum shaderType, + bool fragmentPrecisionHigh, + TSymbolTable *symbolTable); +} // namespace sh #endif // COMPILER_TRANSLATOR_SCALARIZEVECANDMATCONSTRUCTORARGS_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/SearchSymbol.cpp b/src/3rdparty/angle/src/compiler/translator/SearchSymbol.cpp index cccd4d3ff0..34c644d028 100644 --- a/src/3rdparty/angle/src/compiler/translator/SearchSymbol.cpp +++ b/src/3rdparty/angle/src/compiler/translator/SearchSymbol.cpp @@ -13,8 +13,7 @@ namespace sh { SearchSymbol::SearchSymbol(const TString &symbol) - : TIntermTraverser(true, false, false), - mSymbol(symbol) + : TIntermTraverser(true, false, false), mSymbol(symbol) { match = false; } diff --git a/src/3rdparty/angle/src/compiler/translator/SearchSymbol.h b/src/3rdparty/angle/src/compiler/translator/SearchSymbol.h index 1e5e1700d1..b8379e041f 100644 --- a/src/3rdparty/angle/src/compiler/translator/SearchSymbol.h +++ b/src/3rdparty/angle/src/compiler/translator/SearchSymbol.h @@ -9,7 +9,7 @@ #ifndef COMPILER_TRANSLATOR_SEARCHSYMBOL_H_ #define COMPILER_TRANSLATOR_SEARCHSYMBOL_H_ -#include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermTraverse.h" #include "compiler/translator/ParseContext.h" namespace sh @@ -30,4 +30,4 @@ class SearchSymbol : public TIntermTraverser }; } -#endif // COMPILER_TRANSLATOR_SEARCHSYMBOL_H_ +#endif // COMPILER_TRANSLATOR_SEARCHSYMBOL_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/SeparateArrayInitialization.cpp b/src/3rdparty/angle/src/compiler/translator/SeparateArrayInitialization.cpp index de9050cd80..fe25823e38 100644 --- a/src/3rdparty/angle/src/compiler/translator/SeparateArrayInitialization.cpp +++ b/src/3rdparty/angle/src/compiler/translator/SeparateArrayInitialization.cpp @@ -3,7 +3,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// The SeparateArrayInitialization function splits each array initialization into a declaration and an assignment. +// The SeparateArrayInitialization function splits each array initialization into a declaration and +// an assignment. // Example: // type[n] a = initializer; // will effectively become @@ -20,6 +21,9 @@ #include "compiler/translator/IntermNode.h" #include "compiler/translator/OutputHLSL.h" +namespace sh +{ + namespace { @@ -27,9 +31,10 @@ class SeparateArrayInitTraverser : private TIntermTraverser { public: static void apply(TIntermNode *root); + private: SeparateArrayInitTraverser(); - bool visitAggregate(Visit, TIntermAggregate *node) override; + bool visitDeclaration(Visit, TIntermDeclaration *node) override; }; void SeparateArrayInitTraverser::apply(TIntermNode *root) @@ -39,54 +44,49 @@ void SeparateArrayInitTraverser::apply(TIntermNode *root) separateInit.updateTree(); } -SeparateArrayInitTraverser::SeparateArrayInitTraverser() - : TIntermTraverser(true, false, false) +SeparateArrayInitTraverser::SeparateArrayInitTraverser() : TIntermTraverser(true, false, false) { } -bool SeparateArrayInitTraverser::visitAggregate(Visit, TIntermAggregate *node) +bool SeparateArrayInitTraverser::visitDeclaration(Visit, TIntermDeclaration *node) { - if (node->getOp() == EOpDeclaration) + TIntermSequence *sequence = node->getSequence(); + TIntermBinary *initNode = sequence->back()->getAsBinaryNode(); + if (initNode != nullptr && initNode->getOp() == EOpInitialize) { - TIntermSequence *sequence = node->getSequence(); - TIntermBinary *initNode = sequence->back()->getAsBinaryNode(); - if (initNode != nullptr && initNode->getOp() == EOpInitialize) + TIntermTyped *initializer = initNode->getRight(); + if (initializer->isArray() && !sh::OutputHLSL::canWriteAsHLSLLiteral(initializer)) { - TIntermTyped *initializer = initNode->getRight(); - if (initializer->isArray() && !sh::OutputHLSL::canWriteAsHLSLLiteral(initializer)) - { - // We rely on that array declarations have been isolated to single declarations. - ASSERT(sequence->size() == 1); - TIntermTyped *symbol = initNode->getLeft(); - TIntermAggregate *parentAgg = getParentNode()->getAsAggregate(); - ASSERT(parentAgg != nullptr); + // We rely on that array declarations have been isolated to single declarations. + ASSERT(sequence->size() == 1); + TIntermTyped *symbol = initNode->getLeft(); + TIntermBlock *parentBlock = getParentNode()->getAsBlock(); + ASSERT(parentBlock != nullptr); - TIntermSequence replacements; + TIntermSequence replacements; - TIntermAggregate *replacementDeclaration = new TIntermAggregate; - replacementDeclaration->setOp(EOpDeclaration); - replacementDeclaration->getSequence()->push_back(symbol); - replacementDeclaration->setLine(symbol->getLine()); - replacements.push_back(replacementDeclaration); + TIntermDeclaration *replacementDeclaration = new TIntermDeclaration(); + replacementDeclaration->appendDeclarator(symbol); + replacementDeclaration->setLine(symbol->getLine()); + replacements.push_back(replacementDeclaration); - TIntermBinary *replacementAssignment = new TIntermBinary(EOpAssign); - replacementAssignment->setLeft(symbol); - replacementAssignment->setRight(initializer); - replacementAssignment->setType(initializer->getType()); - replacementAssignment->setLine(symbol->getLine()); - replacements.push_back(replacementAssignment); + TIntermBinary *replacementAssignment = + new TIntermBinary(EOpAssign, symbol, initializer); + replacementAssignment->setLine(symbol->getLine()); + replacements.push_back(replacementAssignment); - mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(parentAgg, node, replacements)); - } + mMultiReplacements.push_back( + NodeReplaceWithMultipleEntry(parentBlock, node, replacements)); } - return false; } - return true; + return false; } -} // namespace +} // namespace void SeparateArrayInitialization(TIntermNode *root) { SeparateArrayInitTraverser::apply(root); } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/SeparateArrayInitialization.h b/src/3rdparty/angle/src/compiler/translator/SeparateArrayInitialization.h index d16357a3af..3a9bb55dd1 100644 --- a/src/3rdparty/angle/src/compiler/translator/SeparateArrayInitialization.h +++ b/src/3rdparty/angle/src/compiler/translator/SeparateArrayInitialization.h @@ -3,7 +3,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// The SeparateArrayInitialization function splits each array initialization into a declaration and an assignment. +// The SeparateArrayInitialization function splits each array initialization into a declaration and +// an assignment. // Example: // type[n] a = initializer; // will effectively become @@ -18,8 +19,11 @@ #ifndef COMPILER_TRANSLATOR_SEPARATEARRAYINITIALIZATION_H_ #define COMPILER_TRANSLATOR_SEPARATEARRAYINITIALIZATION_H_ +namespace sh +{ class TIntermNode; void SeparateArrayInitialization(TIntermNode *root); +} // namespace sh #endif // COMPILER_TRANSLATOR_SEPARATEARRAYINITIALIZATION_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/SeparateDeclarations.cpp b/src/3rdparty/angle/src/compiler/translator/SeparateDeclarations.cpp index d33747f85b..9a066075c0 100644 --- a/src/3rdparty/angle/src/compiler/translator/SeparateDeclarations.cpp +++ b/src/3rdparty/angle/src/compiler/translator/SeparateDeclarations.cpp @@ -5,8 +5,8 @@ // // The SeparateDeclarations function processes declarations, so that in the end each declaration // contains only one declarator. -// This is useful as an intermediate step when initialization needs to be separated from declaration, -// or when things need to be unfolded out of the initializer. +// This is useful as an intermediate step when initialization needs to be separated from +// declaration, or when things need to be unfolded out of the initializer. // Example: // int a[1] = int[1](1), b[1] = int[1](2); // gets transformed when run through this class into the AST equivalent of: @@ -15,7 +15,10 @@ #include "compiler/translator/SeparateDeclarations.h" -#include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermTraverse.h" + +namespace sh +{ namespace { @@ -24,9 +27,10 @@ class SeparateDeclarationsTraverser : private TIntermTraverser { public: static void apply(TIntermNode *root); + private: SeparateDeclarationsTraverser(); - bool visitAggregate(Visit, TIntermAggregate *node) override; + bool visitDeclaration(Visit, TIntermDeclaration *node) override; }; void SeparateDeclarationsTraverser::apply(TIntermNode *root) @@ -41,37 +45,35 @@ SeparateDeclarationsTraverser::SeparateDeclarationsTraverser() { } -bool SeparateDeclarationsTraverser::visitAggregate(Visit, TIntermAggregate *node) +bool SeparateDeclarationsTraverser::visitDeclaration(Visit, TIntermDeclaration *node) { - if (node->getOp() == EOpDeclaration) + TIntermSequence *sequence = node->getSequence(); + if (sequence->size() > 1) { - TIntermSequence *sequence = node->getSequence(); - if (sequence->size() > 1) + TIntermBlock *parentBlock = getParentNode()->getAsBlock(); + ASSERT(parentBlock != nullptr); + + TIntermSequence replacementDeclarations; + for (size_t ii = 0; ii < sequence->size(); ++ii) { - TIntermAggregate *parentAgg = getParentNode()->getAsAggregate(); - ASSERT(parentAgg != nullptr); + TIntermDeclaration *replacementDeclaration = new TIntermDeclaration(); - TIntermSequence replacementDeclarations; - for (size_t ii = 0; ii < sequence->size(); ++ii) - { - TIntermAggregate *replacementDeclaration = new TIntermAggregate; - - replacementDeclaration->setOp(EOpDeclaration); - replacementDeclaration->getSequence()->push_back(sequence->at(ii)); - replacementDeclaration->setLine(sequence->at(ii)->getLine()); - replacementDeclarations.push_back(replacementDeclaration); - } - - mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(parentAgg, node, replacementDeclarations)); + replacementDeclaration->appendDeclarator(sequence->at(ii)->getAsTyped()); + replacementDeclaration->setLine(sequence->at(ii)->getLine()); + replacementDeclarations.push_back(replacementDeclaration); } - return false; + + mMultiReplacements.push_back( + NodeReplaceWithMultipleEntry(parentBlock, node, replacementDeclarations)); } - return true; + return false; } -} // namespace +} // namespace void SeparateDeclarations(TIntermNode *root) { SeparateDeclarationsTraverser::apply(root); } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/SeparateDeclarations.h b/src/3rdparty/angle/src/compiler/translator/SeparateDeclarations.h index 77913ab8bb..8142faea1c 100644 --- a/src/3rdparty/angle/src/compiler/translator/SeparateDeclarations.h +++ b/src/3rdparty/angle/src/compiler/translator/SeparateDeclarations.h @@ -5,8 +5,8 @@ // // The SeparateDeclarations function processes declarations, so that in the end each declaration // contains only one declarator. -// This is useful as an intermediate step when initialization needs to be separated from declaration, -// or when things need to be unfolded out of the initializer. +// This is useful as an intermediate step when initialization needs to be separated from +// declaration, or when things need to be unfolded out of the initializer. // Example: // int a[1] = int[1](1), b[1] = int[1](2); // gets transformed when run through this class into the AST equivalent of: @@ -16,8 +16,11 @@ #ifndef COMPILER_TRANSLATOR_SEPARATEDECLARATIONS_H_ #define COMPILER_TRANSLATOR_SEPARATEDECLARATIONS_H_ +namespace sh +{ class TIntermNode; void SeparateDeclarations(TIntermNode *root); +} // namespace sh #endif // COMPILER_TRANSLATOR_SEPARATEDECLARATIONS_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/SeparateExpressionsReturningArrays.cpp b/src/3rdparty/angle/src/compiler/translator/SeparateExpressionsReturningArrays.cpp index e8e1a21d9c..01d627937c 100644 --- a/src/3rdparty/angle/src/compiler/translator/SeparateExpressionsReturningArrays.cpp +++ b/src/3rdparty/angle/src/compiler/translator/SeparateExpressionsReturningArrays.cpp @@ -3,15 +3,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// SeparateExpressionsReturningArrays splits array-returning expressions that are not array names from more complex -// expressions, assigning them to a temporary variable a#. +// SeparateExpressionsReturningArrays splits array-returning expressions that are not array names +// from more complex expressions, assigning them to a temporary variable a#. // Examples where a, b and c are all arrays: // (a = b) == (a = c) is split into a = b; type[n] a1 = a; a = c; type[n] a2 = a; a1 == a2; // type d = type[n](...)[i]; is split into type[n] a1 = type[n](...); type d = a1[i]; #include "compiler/translator/SeparateExpressionsReturningArrays.h" -#include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermNodePatternMatcher.h" +#include "compiler/translator/IntermTraverse.h" + +namespace sh +{ namespace { @@ -20,7 +24,7 @@ namespace class SeparateExpressionsTraverser : public TIntermTraverser { public: - SeparateExpressionsTraverser(); + SeparateExpressionsTraverser(TSymbolTable *symbolTable); bool visitBinary(Visit visit, TIntermBinary *node) override; bool visitAggregate(Visit visit, TIntermAggregate *node) override; @@ -29,14 +33,17 @@ class SeparateExpressionsTraverser : public TIntermTraverser bool foundArrayExpression() const { return mFoundArrayExpression; } protected: - // Marked to true once an operation that needs to be hoisted out of the expression has been found. - // After that, no more AST updates are performed on that traversal. + // Marked to true once an operation that needs to be hoisted out of the expression has been + // found. After that, no more AST updates are performed on that traversal. bool mFoundArrayExpression; + + IntermNodePatternMatcher mPatternToSeparateMatcher; }; -SeparateExpressionsTraverser::SeparateExpressionsTraverser() - : TIntermTraverser(true, false, false), - mFoundArrayExpression(false) +SeparateExpressionsTraverser::SeparateExpressionsTraverser(TSymbolTable *symbolTable) + : TIntermTraverser(true, false, false, symbolTable), + mFoundArrayExpression(false), + mPatternToSeparateMatcher(IntermNodePatternMatcher::kExpressionReturningArray) { } @@ -45,27 +52,7 @@ SeparateExpressionsTraverser::SeparateExpressionsTraverser() // and also needs to be replaced in its original location by a different node. TIntermBinary *CopyAssignmentNode(TIntermBinary *node) { - TIntermBinary *copyNode = new TIntermBinary(node->getOp()); - copyNode->setLeft(node->getLeft()); - copyNode->setRight(node->getRight()); - copyNode->setType(node->getType()); - return copyNode; -} - -// Performs a shallow copy of a constructor/function call node. -TIntermAggregate *CopyAggregateNode(TIntermAggregate *node) -{ - TIntermAggregate *copyNode = new TIntermAggregate(node->getOp()); - TIntermSequence *copySeq = copyNode->getSequence(); - copySeq->insert(copySeq->begin(), node->getSequence()->begin(), node->getSequence()->end()); - copyNode->setType(node->getType()); - copyNode->setFunctionId(node->getFunctionId()); - if (node->isUserDefined()) - { - copyNode->setUserDefined(); - } - copyNode->setNameObj(node->getNameObj()); - return copyNode; + return new TIntermBinary(node->getOp(), node->getLeft(), node->getRight()); } bool SeparateExpressionsTraverser::visitBinary(Visit visit, TIntermBinary *node) @@ -73,90 +60,59 @@ bool SeparateExpressionsTraverser::visitBinary(Visit visit, TIntermBinary *node) if (mFoundArrayExpression) return false; - // Early return if the expression is not an array or if we're not inside a complex expression. - if (!node->getType().isArray() || parentNodeIsBlock()) + // Return if the expression is not an array or if we're not inside a complex expression. + if (!mPatternToSeparateMatcher.match(node, getParentNode())) return true; - switch (node->getOp()) - { - case EOpAssign: - { - mFoundArrayExpression = true; + ASSERT(node->getOp() == EOpAssign); - TIntermSequence insertions; - insertions.push_back(CopyAssignmentNode(node)); - // TODO(oetuaho): In some cases it would be more optimal to not add the temporary node, but just use the - // original target of the assignment. Care must be taken so that this doesn't happen when the same array - // symbol is a target of assignment more than once in one expression. - insertions.push_back(createTempInitDeclaration(node->getLeft())); - insertStatementsInParentBlock(insertions); + mFoundArrayExpression = true; - NodeUpdateEntry replaceVariable(getParentNode(), node, createTempSymbol(node->getType()), false); - mReplacements.push_back(replaceVariable); - } - return false; - default: - return true; - } + TIntermSequence insertions; + insertions.push_back(CopyAssignmentNode(node)); + // TODO(oetuaho): In some cases it would be more optimal to not add the temporary node, but just + // use the original target of the assignment. Care must be taken so that this doesn't happen + // when the same array symbol is a target of assignment more than once in one expression. + insertions.push_back(createTempInitDeclaration(node->getLeft())); + insertStatementsInParentBlock(insertions); + + queueReplacement(createTempSymbol(node->getType()), OriginalNode::IS_DROPPED); + + return false; } bool SeparateExpressionsTraverser::visitAggregate(Visit visit, TIntermAggregate *node) { if (mFoundArrayExpression) - return false; // No need to traverse further + return false; // No need to traverse further - if (getParentNode() != nullptr) - { - TIntermBinary *parentBinary = getParentNode()->getAsBinaryNode(); - bool parentIsAssignment = (parentBinary != nullptr && - (parentBinary->getOp() == EOpAssign || parentBinary->getOp() == EOpInitialize)); + if (!mPatternToSeparateMatcher.match(node, getParentNode())) + return true; - if (!node->getType().isArray() || parentNodeIsBlock() || parentIsAssignment) - return true; + ASSERT(node->isConstructor() || node->getOp() == EOpCallFunctionInAST); - if (node->isConstructor()) - { - mFoundArrayExpression = true; + mFoundArrayExpression = true; - TIntermSequence insertions; - insertions.push_back(createTempInitDeclaration(CopyAggregateNode(node))); - insertStatementsInParentBlock(insertions); + TIntermSequence insertions; + insertions.push_back(createTempInitDeclaration(node->shallowCopy())); + insertStatementsInParentBlock(insertions); - NodeUpdateEntry replaceVariable(getParentNode(), node, createTempSymbol(node->getType()), false); - mReplacements.push_back(replaceVariable); + queueReplacement(createTempSymbol(node->getType()), OriginalNode::IS_DROPPED); - return false; - } - else if (node->getOp() == EOpFunctionCall) - { - mFoundArrayExpression = true; - - TIntermSequence insertions; - insertions.push_back(createTempInitDeclaration(CopyAggregateNode(node))); - insertStatementsInParentBlock(insertions); - - NodeUpdateEntry replaceVariable(getParentNode(), node, createTempSymbol(node->getType()), false); - mReplacements.push_back(replaceVariable); - - return false; - } - } - return true; + return false; } void SeparateExpressionsTraverser::nextIteration() { mFoundArrayExpression = false; - nextTemporaryIndex(); + nextTemporaryId(); } -} // namespace +} // namespace -void SeparateExpressionsReturningArrays(TIntermNode *root, unsigned int *temporaryIndex) +void SeparateExpressionsReturningArrays(TIntermNode *root, TSymbolTable *symbolTable) { - SeparateExpressionsTraverser traverser; - ASSERT(temporaryIndex != nullptr); - traverser.useTemporaryIndex(temporaryIndex); + SeparateExpressionsTraverser traverser(symbolTable); // Separate one expression at a time, and reset the traverser between iterations. do { @@ -164,6 +120,7 @@ void SeparateExpressionsReturningArrays(TIntermNode *root, unsigned int *tempora root->traverse(&traverser); if (traverser.foundArrayExpression()) traverser.updateTree(); - } - while (traverser.foundArrayExpression()); + } while (traverser.foundArrayExpression()); } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/SeparateExpressionsReturningArrays.h b/src/3rdparty/angle/src/compiler/translator/SeparateExpressionsReturningArrays.h index b178ebb3ec..f8eb438748 100644 --- a/src/3rdparty/angle/src/compiler/translator/SeparateExpressionsReturningArrays.h +++ b/src/3rdparty/angle/src/compiler/translator/SeparateExpressionsReturningArrays.h @@ -3,8 +3,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// SeparateExpressionsReturningArrays splits array-returning expressions that are not array names from more complex -// expressions, assigning them to a temporary variable a#. +// SeparateExpressionsReturningArrays splits array-returning expressions that are not array names +// from more complex expressions, assigning them to a temporary variable a#. // Examples where a, b and c are all arrays: // (a = b) == (a = c) is split into a = b; type[n] a1 = a; a = c; type[n] a2 = a; a1 == a2; // type d = type[n](...)[i]; is split into type[n] a1 = type[n](...); type d = a1[i]; @@ -12,8 +12,12 @@ #ifndef COMPILER_TRANSLATOR_SEPARATEEXPRESSIONSRETURNINGARRAYS_H_ #define COMPILER_TRANSLATOR_SEPARATEEXPRESSIONSRETURNINGARRAYS_H_ +namespace sh +{ class TIntermNode; +class TSymbolTable; -void SeparateExpressionsReturningArrays(TIntermNode *root, unsigned int *temporaryIndex); +void SeparateExpressionsReturningArrays(TIntermNode *root, TSymbolTable *symbolTable); +} // namespace sh -#endif // COMPILER_TRANSLATOR_SEPARATEEXPRESSIONSRETURNINGARRAYS_H_ +#endif // COMPILER_TRANSLATOR_SEPARATEEXPRESSIONSRETURNINGARRAYS_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/Severity.h b/src/3rdparty/angle/src/compiler/translator/Severity.h new file mode 100644 index 0000000000..47808a16a7 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/Severity.h @@ -0,0 +1,22 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_TRANSLATOR_SEVERITY_H_ +#define COMPILER_TRANSLATOR_SEVERITY_H_ + +namespace sh +{ + +// Severity is used to classify info log messages. +enum Severity +{ + SH_WARNING, + SH_ERROR +}; + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_SEVERITY_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/ShaderLang.cpp b/src/3rdparty/angle/src/compiler/translator/ShaderLang.cpp index e257f93e48..eeb13f2ec0 100644 --- a/src/3rdparty/angle/src/compiler/translator/ShaderLang.cpp +++ b/src/3rdparty/angle/src/compiler/translator/ShaderLang.cpp @@ -16,10 +16,13 @@ #include "compiler/translator/length_limits.h" #ifdef ANGLE_ENABLE_HLSL #include "compiler/translator/TranslatorHLSL.h" -#endif // ANGLE_ENABLE_HLSL +#endif // ANGLE_ENABLE_HLSL #include "compiler/translator/VariablePacker.h" #include "angle_gl.h" +namespace sh +{ + namespace { @@ -34,70 +37,109 @@ template const std::vector *GetVariableList(const TCompiler *compiler); template <> -const std::vector *GetVariableList(const TCompiler *compiler) +const std::vector *GetVariableList(const TCompiler *compiler) { return &compiler->getUniforms(); } template <> -const std::vector *GetVariableList(const TCompiler *compiler) +const std::vector *GetVariableList(const TCompiler *compiler) { - return &compiler->getVaryings(); + switch (compiler->getShaderType()) + { + case GL_VERTEX_SHADER: + return &compiler->getOutputVaryings(); + case GL_FRAGMENT_SHADER: + return &compiler->getInputVaryings(); + case GL_COMPUTE_SHADER: + ASSERT(compiler->getOutputVaryings().empty() && compiler->getInputVaryings().empty()); + return &compiler->getOutputVaryings(); + // Since geometry shaders have both input and output varyings, we shouldn't call GetVaryings + // on a geometry shader. + default: + return nullptr; + } } template <> -const std::vector *GetVariableList(const TCompiler *compiler) +const std::vector *GetVariableList(const TCompiler *compiler) { return &compiler->getAttributes(); } template <> -const std::vector *GetVariableList(const TCompiler *compiler) +const std::vector *GetVariableList(const TCompiler *compiler) { return &compiler->getOutputVariables(); } template <> -const std::vector *GetVariableList(const TCompiler *compiler) +const std::vector *GetVariableList(const TCompiler *compiler) { return &compiler->getInterfaceBlocks(); } -template -const std::vector *GetShaderVariables(const ShHandle handle) -{ - if (!handle) - { - return NULL; - } - - TShHandleBase* base = static_cast(handle); - TCompiler* compiler = base->getAsCompiler(); - if (!compiler) - { - return NULL; - } - - return GetVariableList(compiler); -} - TCompiler *GetCompilerFromHandle(ShHandle handle) { if (!handle) - return NULL; + { + return nullptr; + } + TShHandleBase *base = static_cast(handle); return base->getAsCompiler(); } +template +const std::vector *GetShaderVariables(const ShHandle handle) +{ + TCompiler *compiler = GetCompilerFromHandle(handle); + if (!compiler) + { + return nullptr; + } + + return GetVariableList(compiler); +} + #ifdef ANGLE_ENABLE_HLSL TranslatorHLSL *GetTranslatorHLSLFromHandle(ShHandle handle) { if (!handle) - return NULL; + return nullptr; TShHandleBase *base = static_cast(handle); return base->getAsTranslatorHLSL(); } -#endif // ANGLE_ENABLE_HLSL +#endif // ANGLE_ENABLE_HLSL + +GLenum GetGeometryShaderPrimitiveTypeEnum(sh::TLayoutPrimitiveType primitiveType) +{ + switch (primitiveType) + { + case EptPoints: + return GL_POINTS; + case EptLines: + return GL_LINES; + case EptLinesAdjacency: + return GL_LINES_ADJACENCY_EXT; + case EptTriangles: + return GL_TRIANGLES; + case EptTrianglesAdjacency: + return GL_TRIANGLES_ADJACENCY_EXT; + + case EptLineStrip: + return GL_LINE_STRIP; + case EptTriangleStrip: + return GL_TRIANGLE_STRIP; + + case EptUndefined: + return GL_INVALID_VALUE; + + default: + UNREACHABLE(); + return GL_INVALID_VALUE; + } +} } // anonymous namespace @@ -105,7 +147,7 @@ TranslatorHLSL *GetTranslatorHLSLFromHandle(ShHandle handle) // Driver must call this first, once, before doing any other compiler operations. // Subsequent calls to this function are no-op. // -bool ShInitialize() +bool Initialize() { if (!isInitialized) { @@ -117,7 +159,7 @@ bool ShInitialize() // // Cleanup symbol tables // -bool ShFinalize() +bool Finalize() { if (isInitialized) { @@ -130,33 +172,38 @@ bool ShFinalize() // // Initialize built-in resources with minimum expected values. // -void ShInitBuiltInResources(ShBuiltInResources* resources) +void InitBuiltInResources(ShBuiltInResources *resources) { // Make comparable. memset(resources, 0, sizeof(*resources)); // Constants. - resources->MaxVertexAttribs = 8; - resources->MaxVertexUniformVectors = 128; - resources->MaxVaryingVectors = 8; - resources->MaxVertexTextureImageUnits = 0; + resources->MaxVertexAttribs = 8; + resources->MaxVertexUniformVectors = 128; + resources->MaxVaryingVectors = 8; + resources->MaxVertexTextureImageUnits = 0; resources->MaxCombinedTextureImageUnits = 8; - resources->MaxTextureImageUnits = 8; - resources->MaxFragmentUniformVectors = 16; - resources->MaxDrawBuffers = 1; + resources->MaxTextureImageUnits = 8; + resources->MaxFragmentUniformVectors = 16; + resources->MaxDrawBuffers = 1; // Extensions. - resources->OES_standard_derivatives = 0; - resources->OES_EGL_image_external = 0; - resources->ARB_texture_rectangle = 0; - resources->EXT_blend_func_extended = 0; - resources->EXT_draw_buffers = 0; - resources->EXT_frag_depth = 0; - resources->EXT_shader_texture_lod = 0; - resources->WEBGL_debug_shader_precision = 0; - resources->EXT_shader_framebuffer_fetch = 0; - resources->NV_shader_framebuffer_fetch = 0; - resources->ARM_shader_framebuffer_fetch = 0; + resources->OES_standard_derivatives = 0; + resources->OES_EGL_image_external = 0; + resources->OES_EGL_image_external_essl3 = 0; + resources->NV_EGL_stream_consumer_external = 0; + resources->ARB_texture_rectangle = 0; + resources->EXT_blend_func_extended = 0; + resources->EXT_draw_buffers = 0; + resources->EXT_frag_depth = 0; + resources->EXT_shader_texture_lod = 0; + resources->WEBGL_debug_shader_precision = 0; + resources->EXT_shader_framebuffer_fetch = 0; + resources->NV_shader_framebuffer_fetch = 0; + resources->ARM_shader_framebuffer_fetch = 0; + resources->OVR_multiview = 0; + resources->EXT_YUV_target = 0; + resources->OES_geometry_shader = 0; resources->NV_draw_buffers = 0; @@ -164,63 +211,125 @@ void ShInitBuiltInResources(ShBuiltInResources* resources) resources->FragmentPrecisionHigh = 0; // GLSL ES 3.0 constants. - resources->MaxVertexOutputVectors = 16; + resources->MaxVertexOutputVectors = 16; resources->MaxFragmentInputVectors = 15; - resources->MinProgramTexelOffset = -8; - resources->MaxProgramTexelOffset = 7; + resources->MinProgramTexelOffset = -8; + resources->MaxProgramTexelOffset = 7; // Extensions constants. resources->MaxDualSourceDrawBuffers = 0; + resources->MaxViewsOVR = 4; + // Disable name hashing by default. - resources->HashFunction = NULL; + resources->HashFunction = nullptr; resources->ArrayIndexClampingStrategy = SH_CLAMP_WITH_CLAMP_INTRINSIC; resources->MaxExpressionComplexity = 256; - resources->MaxCallStackDepth = 256; + resources->MaxCallStackDepth = 256; + resources->MaxFunctionParameters = 1024; + + // ES 3.1 Revision 4, 7.2 Built-in Constants + + // ES 3.1, Revision 4, 8.13 Texture minification + // "The value of MIN_PROGRAM_TEXTURE_GATHER_OFFSET must be less than or equal to the value of + // MIN_PROGRAM_TEXEL_OFFSET. The value of MAX_PROGRAM_TEXTURE_GATHER_OFFSET must be greater than + // or equal to the value of MAX_PROGRAM_TEXEL_OFFSET" + resources->MinProgramTextureGatherOffset = -8; + resources->MaxProgramTextureGatherOffset = 7; + + resources->MaxImageUnits = 4; + resources->MaxVertexImageUniforms = 0; + resources->MaxFragmentImageUniforms = 0; + resources->MaxComputeImageUniforms = 4; + resources->MaxCombinedImageUniforms = 4; + + resources->MaxUniformLocations = 1024; + + resources->MaxCombinedShaderOutputResources = 4; + + resources->MaxComputeWorkGroupCount[0] = 65535; + resources->MaxComputeWorkGroupCount[1] = 65535; + resources->MaxComputeWorkGroupCount[2] = 65535; + resources->MaxComputeWorkGroupSize[0] = 128; + resources->MaxComputeWorkGroupSize[1] = 128; + resources->MaxComputeWorkGroupSize[2] = 64; + resources->MaxComputeUniformComponents = 512; + resources->MaxComputeTextureImageUnits = 16; + + resources->MaxComputeAtomicCounters = 8; + resources->MaxComputeAtomicCounterBuffers = 1; + + resources->MaxVertexAtomicCounters = 0; + resources->MaxFragmentAtomicCounters = 0; + resources->MaxCombinedAtomicCounters = 8; + resources->MaxAtomicCounterBindings = 1; + + resources->MaxVertexAtomicCounterBuffers = 0; + resources->MaxFragmentAtomicCounterBuffers = 0; + resources->MaxCombinedAtomicCounterBuffers = 1; + resources->MaxAtomicCounterBufferSize = 32; + + resources->MaxUniformBufferBindings = 32; + resources->MaxShaderStorageBufferBindings = 4; + + resources->MaxGeometryUniformComponents = 1024; + resources->MaxGeometryUniformBlocks = 12; + resources->MaxGeometryInputComponents = 64; + resources->MaxGeometryOutputComponents = 64; + resources->MaxGeometryOutputVertices = 256; + resources->MaxGeometryTotalOutputComponents = 1024; + resources->MaxGeometryTextureImageUnits = 16; + resources->MaxGeometryAtomicCounterBuffers = 0; + resources->MaxGeometryAtomicCounters = 0; + resources->MaxGeometryShaderStorageBlocks = 0; + resources->MaxGeometryShaderInvocations = 32; + resources->MaxGeometryImageUniforms = 0; } // // Driver calls these to create and destroy compiler objects. // -ShHandle ShConstructCompiler(sh::GLenum type, ShShaderSpec spec, - ShShaderOutput output, - const ShBuiltInResources* resources) +ShHandle ConstructCompiler(sh::GLenum type, + ShShaderSpec spec, + ShShaderOutput output, + const ShBuiltInResources *resources) { - TShHandleBase* base = static_cast(ConstructCompiler(type, spec, output)); + TShHandleBase *base = static_cast(ConstructCompiler(type, spec, output)); if (base == nullptr) { return 0; } - TCompiler* compiler = base->getAsCompiler(); + TCompiler *compiler = base->getAsCompiler(); if (compiler == nullptr) { return 0; } // Generate built-in symbol table. - if (!compiler->Init(*resources)) { - ShDestruct(base); + if (!compiler->Init(*resources)) + { + Destruct(base); return 0; } - return reinterpret_cast(base); + return reinterpret_cast(base); } -void ShDestruct(ShHandle handle) +void Destruct(ShHandle handle) { if (handle == 0) return; - TShHandleBase* base = static_cast(handle); + TShHandleBase *base = static_cast(handle); if (base->getAsCompiler()) DeleteCompiler(base->getAsCompiler()); } -const std::string &ShGetBuiltInResourcesString(const ShHandle handle) +const std::string &GetBuiltInResourcesString(const ShHandle handle) { TCompiler *compiler = GetCompilerFromHandle(handle); ASSERT(compiler); @@ -234,11 +343,10 @@ const std::string &ShGetBuiltInResourcesString(const ShHandle handle) // Return: The return value of ShCompile is really boolean, indicating // success or failure. // -bool ShCompile( - const ShHandle handle, - const char *const shaderStrings[], - size_t numStrings, - int compileOptions) +bool Compile(const ShHandle handle, + const char *const shaderStrings[], + size_t numStrings, + ShCompileOptions compileOptions) { TCompiler *compiler = GetCompilerFromHandle(handle); ASSERT(compiler); @@ -246,23 +354,23 @@ bool ShCompile( return compiler->compile(shaderStrings, numStrings, compileOptions); } -void ShClearResults(const ShHandle handle) +void ClearResults(const ShHandle handle) { TCompiler *compiler = GetCompilerFromHandle(handle); ASSERT(compiler); compiler->clearResults(); } -int ShGetShaderVersion(const ShHandle handle) +int GetShaderVersion(const ShHandle handle) { - TCompiler* compiler = GetCompilerFromHandle(handle); + TCompiler *compiler = GetCompilerFromHandle(handle); ASSERT(compiler); return compiler->getShaderVersion(); } -ShShaderOutput ShGetShaderOutputType(const ShHandle handle) +ShShaderOutput GetShaderOutputType(const ShHandle handle) { - TCompiler* compiler = GetCompilerFromHandle(handle); + TCompiler *compiler = GetCompilerFromHandle(handle); ASSERT(compiler); return compiler->getOutputType(); } @@ -270,7 +378,7 @@ ShShaderOutput ShGetShaderOutputType(const ShHandle handle) // // Return any compiler log of messages for the application. // -const std::string &ShGetInfoLog(const ShHandle handle) +const std::string &GetInfoLog(const ShHandle handle) { TCompiler *compiler = GetCompilerFromHandle(handle); ASSERT(compiler); @@ -282,7 +390,7 @@ const std::string &ShGetInfoLog(const ShHandle handle) // // Return any object code. // -const std::string &ShGetObjectCode(const ShHandle handle) +const std::string &GetObjectCode(const ShHandle handle) { TCompiler *compiler = GetCompilerFromHandle(handle); ASSERT(compiler); @@ -291,58 +399,107 @@ const std::string &ShGetObjectCode(const ShHandle handle) return infoSink.obj.str(); } -const std::map *ShGetNameHashingMap( - const ShHandle handle) +const std::map *GetNameHashingMap(const ShHandle handle) { TCompiler *compiler = GetCompilerFromHandle(handle); ASSERT(compiler); return &(compiler->getNameMap()); } -const std::vector *ShGetUniforms(const ShHandle handle) +const std::vector *GetUniforms(const ShHandle handle) { - return GetShaderVariables(handle); + return GetShaderVariables(handle); } -const std::vector *ShGetVaryings(const ShHandle handle) +const std::vector *GetInputVaryings(const ShHandle handle) { - return GetShaderVariables(handle); -} - -const std::vector *ShGetAttributes(const ShHandle handle) -{ - return GetShaderVariables(handle); -} - -const std::vector *ShGetOutputVariables(const ShHandle handle) -{ - return GetShaderVariables(handle); -} - -const std::vector *ShGetInterfaceBlocks(const ShHandle handle) -{ - return GetShaderVariables(handle); -} - -bool ShCheckVariablesWithinPackingLimits( - int maxVectors, ShVariableInfo *varInfoArray, size_t varInfoArraySize) -{ - if (varInfoArraySize == 0) - return true; - ASSERT(varInfoArray); - std::vector variables; - for (size_t ii = 0; ii < varInfoArraySize; ++ii) + TCompiler *compiler = GetCompilerFromHandle(handle); + if (compiler == nullptr) { - sh::ShaderVariable var(varInfoArray[ii].type, varInfoArray[ii].size); - variables.push_back(var); + return nullptr; } - VariablePacker packer; - return packer.CheckVariablesWithinPackingLimits(maxVectors, variables); + return &compiler->getInputVaryings(); } -bool ShGetInterfaceBlockRegister(const ShHandle handle, - const std::string &interfaceBlockName, - unsigned int *indexOut) +const std::vector *GetOutputVaryings(const ShHandle handle) +{ + TCompiler *compiler = GetCompilerFromHandle(handle); + if (compiler == nullptr) + { + return nullptr; + } + return &compiler->getOutputVaryings(); +} + +const std::vector *GetVaryings(const ShHandle handle) +{ + return GetShaderVariables(handle); +} + +const std::vector *GetAttributes(const ShHandle handle) +{ + return GetShaderVariables(handle); +} + +const std::vector *GetOutputVariables(const ShHandle handle) +{ + return GetShaderVariables(handle); +} + +const std::vector *GetInterfaceBlocks(const ShHandle handle) +{ + return GetShaderVariables(handle); +} + +const std::vector *GetUniformBlocks(const ShHandle handle) +{ + ASSERT(handle); + TShHandleBase *base = static_cast(handle); + TCompiler *compiler = base->getAsCompiler(); + ASSERT(compiler); + + return &compiler->getUniformBlocks(); +} + +const std::vector *GetShaderStorageBlocks(const ShHandle handle) +{ + ASSERT(handle); + TShHandleBase *base = static_cast(handle); + TCompiler *compiler = base->getAsCompiler(); + ASSERT(compiler); + + return &compiler->getShaderStorageBlocks(); +} + +WorkGroupSize GetComputeShaderLocalGroupSize(const ShHandle handle) +{ + ASSERT(handle); + + TShHandleBase *base = static_cast(handle); + TCompiler *compiler = base->getAsCompiler(); + ASSERT(compiler); + + return compiler->getComputeShaderLocalSize(); +} + +int GetVertexShaderNumViews(const ShHandle handle) +{ + ASSERT(handle); + TShHandleBase *base = static_cast(handle); + TCompiler *compiler = base->getAsCompiler(); + ASSERT(compiler); + + return compiler->getNumViews(); +} + +bool CheckVariablesWithinPackingLimits(int maxVectors, const std::vector &variables) +{ + return CheckVariablesInPackingLimits(maxVectors, variables); +} + +bool GetUniformBlockRegister(const ShHandle handle, + const std::string &uniformBlockName, + unsigned int *indexOut) { #ifdef ANGLE_ENABLE_HLSL ASSERT(indexOut); @@ -350,35 +507,72 @@ bool ShGetInterfaceBlockRegister(const ShHandle handle, TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle); ASSERT(translator); - if (!translator->hasInterfaceBlock(interfaceBlockName)) + if (!translator->hasUniformBlock(uniformBlockName)) { return false; } - *indexOut = translator->getInterfaceBlockRegister(interfaceBlockName); + *indexOut = translator->getUniformBlockRegister(uniformBlockName); return true; #else return false; -#endif // ANGLE_ENABLE_HLSL +#endif // ANGLE_ENABLE_HLSL } -bool ShGetUniformRegister(const ShHandle handle, - const std::string &uniformName, - unsigned int *indexOut) +const std::map *GetUniformRegisterMap(const ShHandle handle) { #ifdef ANGLE_ENABLE_HLSL - ASSERT(indexOut); TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle); ASSERT(translator); - if (!translator->hasUniform(uniformName)) - { - return false; - } - - *indexOut = translator->getUniformRegister(uniformName); - return true; + return translator->getUniformRegisterMap(); #else - return false; -#endif // ANGLE_ENABLE_HLSL + return nullptr; +#endif // ANGLE_ENABLE_HLSL } + +GLenum GetGeometryShaderInputPrimitiveType(const ShHandle handle) +{ + ASSERT(handle); + + TShHandleBase *base = static_cast(handle); + TCompiler *compiler = base->getAsCompiler(); + ASSERT(compiler); + + return GetGeometryShaderPrimitiveTypeEnum(compiler->getGeometryShaderInputPrimitiveType()); +} + +GLenum GetGeometryShaderOutputPrimitiveType(const ShHandle handle) +{ + ASSERT(handle); + + TShHandleBase *base = static_cast(handle); + TCompiler *compiler = base->getAsCompiler(); + ASSERT(compiler); + + return GetGeometryShaderPrimitiveTypeEnum(compiler->getGeometryShaderOutputPrimitiveType()); +} + +int GetGeometryShaderInvocations(const ShHandle handle) +{ + ASSERT(handle); + + TShHandleBase *base = static_cast(handle); + TCompiler *compiler = base->getAsCompiler(); + ASSERT(compiler); + + return compiler->getGeometryShaderInvocations(); +} + +int GetGeometryShaderMaxVertices(const ShHandle handle) +{ + ASSERT(handle); + + TShHandleBase *base = static_cast(handle); + TCompiler *compiler = base->getAsCompiler(); + ASSERT(compiler); + + return compiler->getGeometryShaderMaxVertices(); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp b/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp index 8f931b9bdd..4ab574e935 100644 --- a/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp +++ b/src/3rdparty/angle/src/compiler/translator/ShaderVars.cpp @@ -10,6 +10,7 @@ #include #include "common/debug.h" +#include "common/utilities.h" namespace sh { @@ -21,7 +22,6 @@ InterpolationType GetNonAuxiliaryInterpolationType(InterpolationType interpolati { return (interpolation == INTERPOLATION_CENTROID ? INTERPOLATION_SMOOTH : interpolation); } - } // The ES 3.0 spec is not clear on this point, but the ES 3.1 spec, and discussion // on Khronos.org, clarifies that a smooth/flat mismatch produces a link error, @@ -32,55 +32,58 @@ bool InterpolationTypesMatch(InterpolationType a, InterpolationType b) } ShaderVariable::ShaderVariable() - : type(0), - precision(0), - arraySize(0), - staticUse(false) -{} + : type(0), precision(0), flattenedOffsetInParentArrays(0), staticUse(false) +{ +} + +ShaderVariable::ShaderVariable(GLenum typeIn) + : type(typeIn), precision(0), flattenedOffsetInParentArrays(0), staticUse(false) +{ +} ShaderVariable::ShaderVariable(GLenum typeIn, unsigned int arraySizeIn) - : type(typeIn), - precision(0), - arraySize(arraySizeIn), - staticUse(false) -{} + : type(typeIn), precision(0), flattenedOffsetInParentArrays(0), staticUse(false) +{ + ASSERT(arraySizeIn != 0); + arraySizes.push_back(arraySizeIn); +} ShaderVariable::~ShaderVariable() -{} +{ +} ShaderVariable::ShaderVariable(const ShaderVariable &other) : type(other.type), precision(other.precision), name(other.name), mappedName(other.mappedName), - arraySize(other.arraySize), + arraySizes(other.arraySizes), + flattenedOffsetInParentArrays(other.flattenedOffsetInParentArrays), staticUse(other.staticUse), fields(other.fields), structName(other.structName) -{} +{ +} ShaderVariable &ShaderVariable::operator=(const ShaderVariable &other) { - type = other.type; - precision = other.precision; - name = other.name; + type = other.type; + precision = other.precision; + name = other.name; mappedName = other.mappedName; - arraySize = other.arraySize; - staticUse = other.staticUse; - fields = other.fields; + arraySizes = other.arraySizes; + staticUse = other.staticUse; + flattenedOffsetInParentArrays = other.flattenedOffsetInParentArrays; + fields = other.fields; structName = other.structName; return *this; } bool ShaderVariable::operator==(const ShaderVariable &other) const { - if (type != other.type || - precision != other.precision || - name != other.name || - mappedName != other.mappedName || - arraySize != other.arraySize || - staticUse != other.staticUse || - fields.size() != other.fields.size() || + if (type != other.type || precision != other.precision || name != other.name || + mappedName != other.mappedName || arraySizes != other.arraySizes || + staticUse != other.staticUse || fields.size() != other.fields.size() || structName != other.structName) { return false; @@ -93,9 +96,52 @@ bool ShaderVariable::operator==(const ShaderVariable &other) const return true; } -bool ShaderVariable::findInfoByMappedName( - const std::string &mappedFullName, - const ShaderVariable **leafVar, std::string *originalFullName) const +void ShaderVariable::setArraySize(unsigned int size) +{ + arraySizes.clear(); + if (size != 0) + { + arraySizes.push_back(size); + } +} + +unsigned int ShaderVariable::getArraySizeProduct() const +{ + return gl::ArraySizeProduct(arraySizes); +} + +void ShaderVariable::indexIntoArray(unsigned int arrayIndex) +{ + ASSERT(isArray()); + flattenedOffsetInParentArrays = + arrayIndex + getOutermostArraySize() * flattenedOffsetInParentArrays; + arraySizes.pop_back(); +} + +unsigned int ShaderVariable::getNestedArraySize(unsigned int arrayNestingIndex) const +{ + ASSERT(arraySizes.size() > arrayNestingIndex); + return arraySizes[arraySizes.size() - 1u - arrayNestingIndex]; +} + +unsigned int ShaderVariable::getBasicTypeElementCount() const +{ + // GLES 3.1 Nov 2016 section 7.3.1.1 page 77 specifies that a separate entry should be generated + // for each array element when dealing with an array of arrays or an array of structs. + ASSERT(!isArrayOfArrays()); + ASSERT(!isStruct() || !isArray()); + + // GLES 3.1 Nov 2016 page 82. + if (isArray()) + { + return getOutermostArraySize(); + } + return 1u; +} + +bool ShaderVariable::findInfoByMappedName(const std::string &mappedFullName, + const ShaderVariable **leafVar, + std::string *originalFullName) const { ASSERT(leafVar && originalFullName); // There are three cases: @@ -110,7 +156,7 @@ bool ShaderVariable::findInfoByMappedName( if (mappedFullName != this->mappedName) return false; *originalFullName = this->name; - *leafVar = this; + *leafVar = this; return true; } else @@ -131,13 +177,13 @@ bool ShaderVariable::findInfoByMappedName( if (closePos + 1 == mappedFullName.size()) { *originalFullName = originalName; - *leafVar = this; + *leafVar = this; return true; } else { // In the form of 'a[0].b', so after ']', '.' is expected. - if (mappedFullName[closePos + 1] != '.') + if (mappedFullName[closePos + 1] != '.') return false; remaining = mappedFullName.substr(closePos + 2); // Skip "]." } @@ -149,14 +195,13 @@ bool ShaderVariable::findInfoByMappedName( } for (size_t ii = 0; ii < this->fields.size(); ++ii) { - const ShaderVariable *fieldVar = NULL; + const ShaderVariable *fieldVar = nullptr; std::string originalFieldName; - bool found = fields[ii].findInfoByMappedName( - remaining, &fieldVar, &originalFieldName); + bool found = fields[ii].findInfoByMappedName(remaining, &fieldVar, &originalFieldName); if (found) { *originalFullName = originalName + "." + originalFieldName; - *leafVar = fieldVar; + *leafVar = fieldVar; return true; } } @@ -164,24 +209,33 @@ bool ShaderVariable::findInfoByMappedName( } } -bool ShaderVariable::isSameVariableAtLinkTime( - const ShaderVariable &other, bool matchPrecision) const +bool ShaderVariable::isBuiltIn() const +{ + return (name.size() >= 4 && name[0] == 'g' && name[1] == 'l' && name[2] == '_'); +} + +bool ShaderVariable::isSameVariableAtLinkTime(const ShaderVariable &other, + bool matchPrecision, + bool matchName) const { if (type != other.type) return false; if (matchPrecision && precision != other.precision) return false; - if (name != other.name) + if (matchName && name != other.name) return false; - ASSERT(mappedName == other.mappedName); - if (arraySize != other.arraySize) + ASSERT(!matchName || mappedName == other.mappedName); + if (arraySizes != other.arraySizes) return false; if (fields.size() != other.fields.size()) return false; + + // [OpenGL ES 3.1 SPEC Chapter 7.4.1] + // Variables declared as structures are considered to match in type if and only if structure + // members match in name, type, qualification, and declaration order. for (size_t ii = 0; ii < fields.size(); ++ii) { - if (!fields[ii].isSameVariableAtLinkTime(other.fields[ii], - matchPrecision)) + if (!fields[ii].isSameVariableAtLinkTime(other.fields[ii], matchPrecision, true)) { return false; } @@ -191,53 +245,75 @@ bool ShaderVariable::isSameVariableAtLinkTime( return true; } -Uniform::Uniform() -{} +Uniform::Uniform() : binding(-1), offset(-1) +{ +} Uniform::~Uniform() -{} +{ +} Uniform::Uniform(const Uniform &other) - : ShaderVariable(other) -{} + : VariableWithLocation(other), binding(other.binding), offset(other.offset) +{ +} Uniform &Uniform::operator=(const Uniform &other) { - ShaderVariable::operator=(other); + VariableWithLocation::operator=(other); + binding = other.binding; + offset = other.offset; return *this; } bool Uniform::operator==(const Uniform &other) const { - return ShaderVariable::operator==(other); + return VariableWithLocation::operator==(other) && binding == other.binding && + offset == other.offset; } bool Uniform::isSameUniformAtLinkTime(const Uniform &other) const { - return ShaderVariable::isSameVariableAtLinkTime(other, true); + // Enforce a consistent match. + // https://cvs.khronos.org/bugzilla/show_bug.cgi?id=16261 + if (binding != -1 && other.binding != -1 && binding != other.binding) + { + return false; + } + if (location != -1 && other.location != -1 && location != other.location) + { + return false; + } + if (offset != other.offset) + { + return false; + } + return VariableWithLocation::isSameVariableAtLinkTime(other, true, true); } -InterfaceVariable::InterfaceVariable() : location(-1) -{} +VariableWithLocation::VariableWithLocation() : location(-1) +{ +} -InterfaceVariable::~InterfaceVariable() -{} +VariableWithLocation::~VariableWithLocation() +{ +} -InterfaceVariable::InterfaceVariable(const InterfaceVariable &other) +VariableWithLocation::VariableWithLocation(const VariableWithLocation &other) : ShaderVariable(other), location(other.location) -{} +{ +} -InterfaceVariable &InterfaceVariable::operator=(const InterfaceVariable &other) +VariableWithLocation &VariableWithLocation::operator=(const VariableWithLocation &other) { ShaderVariable::operator=(other); - location = other.location; + location = other.location; return *this; } -bool InterfaceVariable::operator==(const InterfaceVariable &other) const +bool VariableWithLocation::operator==(const VariableWithLocation &other) const { - return (ShaderVariable::operator==(other) && - location == other.location); + return (ShaderVariable::operator==(other) && location == other.location); } Attribute::Attribute() @@ -248,19 +324,19 @@ Attribute::~Attribute() { } -Attribute::Attribute(const Attribute &other) : InterfaceVariable(other) +Attribute::Attribute(const Attribute &other) : VariableWithLocation(other) { } Attribute &Attribute::operator=(const Attribute &other) { - InterfaceVariable::operator=(other); + VariableWithLocation::operator=(other); return *this; } bool Attribute::operator==(const Attribute &other) const { - return InterfaceVariable::operator==(other); + return VariableWithLocation::operator==(other); } OutputVariable::OutputVariable() @@ -271,79 +347,79 @@ OutputVariable::~OutputVariable() { } -OutputVariable::OutputVariable(const OutputVariable &other) : InterfaceVariable(other) +OutputVariable::OutputVariable(const OutputVariable &other) : VariableWithLocation(other) { } OutputVariable &OutputVariable::operator=(const OutputVariable &other) { - InterfaceVariable::operator=(other); + VariableWithLocation::operator=(other); return *this; } bool OutputVariable::operator==(const OutputVariable &other) const { - return InterfaceVariable::operator==(other); + return VariableWithLocation::operator==(other); } -InterfaceBlockField::InterfaceBlockField() - : isRowMajorLayout(false) -{} +InterfaceBlockField::InterfaceBlockField() : isRowMajorLayout(false) +{ +} InterfaceBlockField::~InterfaceBlockField() -{} +{ +} InterfaceBlockField::InterfaceBlockField(const InterfaceBlockField &other) - : ShaderVariable(other), - isRowMajorLayout(other.isRowMajorLayout) -{} + : ShaderVariable(other), isRowMajorLayout(other.isRowMajorLayout) +{ +} InterfaceBlockField &InterfaceBlockField::operator=(const InterfaceBlockField &other) { ShaderVariable::operator=(other); - isRowMajorLayout = other.isRowMajorLayout; + isRowMajorLayout = other.isRowMajorLayout; return *this; } bool InterfaceBlockField::operator==(const InterfaceBlockField &other) const { - return (ShaderVariable::operator==(other) && - isRowMajorLayout == other.isRowMajorLayout); + return (ShaderVariable::operator==(other) && isRowMajorLayout == other.isRowMajorLayout); } bool InterfaceBlockField::isSameInterfaceBlockFieldAtLinkTime( const InterfaceBlockField &other) const { - return (ShaderVariable::isSameVariableAtLinkTime(other, true) && + return (ShaderVariable::isSameVariableAtLinkTime(other, true, true) && isRowMajorLayout == other.isRowMajorLayout); } -Varying::Varying() - : interpolation(INTERPOLATION_SMOOTH), - isInvariant(false) -{} +Varying::Varying() : interpolation(INTERPOLATION_SMOOTH), isInvariant(false) +{ +} Varying::~Varying() -{} +{ +} Varying::Varying(const Varying &other) - : ShaderVariable(other), + : VariableWithLocation(other), interpolation(other.interpolation), isInvariant(other.isInvariant) -{} +{ +} Varying &Varying::operator=(const Varying &other) { - ShaderVariable::operator=(other); - interpolation = other.interpolation; - isInvariant = other.isInvariant; + VariableWithLocation::operator=(other); + interpolation = other.interpolation; + isInvariant = other.isInvariant; return *this; } bool Varying::operator==(const Varying &other) const { - return (ShaderVariable::operator==(other) && - interpolation == other.interpolation && + return (VariableWithLocation::operator==(other) && interpolation == other.interpolation && isInvariant == other.isInvariant); } @@ -354,20 +430,26 @@ bool Varying::isSameVaryingAtLinkTime(const Varying &other) const bool Varying::isSameVaryingAtLinkTime(const Varying &other, int shaderVersion) const { - return (ShaderVariable::isSameVariableAtLinkTime(other, false) && - interpolation == other.interpolation && - (shaderVersion >= 300 || isInvariant == other.isInvariant)); + return (ShaderVariable::isSameVariableAtLinkTime(other, false, false) && + InterpolationTypesMatch(interpolation, other.interpolation) && + (shaderVersion >= 300 || isInvariant == other.isInvariant) && + (location == other.location) && + (name == other.name || (shaderVersion >= 310 && location >= 0))); } InterfaceBlock::InterfaceBlock() : arraySize(0), layout(BLOCKLAYOUT_PACKED), isRowMajorLayout(false), - staticUse(false) -{} + binding(-1), + staticUse(false), + blockType(BlockType::BLOCK_UNIFORM) +{ +} InterfaceBlock::~InterfaceBlock() -{} +{ +} InterfaceBlock::InterfaceBlock(const InterfaceBlock &other) : name(other.name), @@ -376,20 +458,25 @@ InterfaceBlock::InterfaceBlock(const InterfaceBlock &other) arraySize(other.arraySize), layout(other.layout), isRowMajorLayout(other.isRowMajorLayout), + binding(other.binding), staticUse(other.staticUse), + blockType(other.blockType), fields(other.fields) -{} +{ +} InterfaceBlock &InterfaceBlock::operator=(const InterfaceBlock &other) { - name = other.name; - mappedName = other.mappedName; - instanceName = other.instanceName; - arraySize = other.arraySize; - layout = other.layout; + name = other.name; + mappedName = other.mappedName; + instanceName = other.instanceName; + arraySize = other.arraySize; + layout = other.layout; isRowMajorLayout = other.isRowMajorLayout; - staticUse = other.staticUse; - fields = other.fields; + binding = other.binding; + staticUse = other.staticUse; + blockType = other.blockType; + fields = other.fields; return *this; } @@ -398,4 +485,102 @@ std::string InterfaceBlock::fieldPrefix() const return instanceName.empty() ? "" : name; } +std::string InterfaceBlock::fieldMappedPrefix() const +{ + return instanceName.empty() ? "" : mappedName; +} + +bool InterfaceBlock::isSameInterfaceBlockAtLinkTime(const InterfaceBlock &other) const +{ + if (name != other.name || mappedName != other.mappedName || arraySize != other.arraySize || + layout != other.layout || isRowMajorLayout != other.isRowMajorLayout || + binding != other.binding || blockType != other.blockType || + fields.size() != other.fields.size()) + { + return false; + } + + for (size_t fieldIndex = 0; fieldIndex < fields.size(); ++fieldIndex) + { + if (!fields[fieldIndex].isSameInterfaceBlockFieldAtLinkTime(other.fields[fieldIndex])) + { + return false; + } + } + + return true; +} + +bool InterfaceBlock::isBuiltIn() const +{ + return (name.size() >= 4 && name[0] == 'g' && name[1] == 'l' && name[2] == '_'); +} + +void WorkGroupSize::fill(int fillValue) +{ + localSizeQualifiers[0] = fillValue; + localSizeQualifiers[1] = fillValue; + localSizeQualifiers[2] = fillValue; +} + +void WorkGroupSize::setLocalSize(int localSizeX, int localSizeY, int localSizeZ) +{ + localSizeQualifiers[0] = localSizeX; + localSizeQualifiers[1] = localSizeY; + localSizeQualifiers[2] = localSizeZ; +} + +// check that if one of them is less than 1, then all of them are. +// Or if one is positive, then all of them are positive. +bool WorkGroupSize::isLocalSizeValid() const +{ + return ( + (localSizeQualifiers[0] < 1 && localSizeQualifiers[1] < 1 && localSizeQualifiers[2] < 1) || + (localSizeQualifiers[0] > 0 && localSizeQualifiers[1] > 0 && localSizeQualifiers[2] > 0)); +} + +bool WorkGroupSize::isAnyValueSet() const +{ + return localSizeQualifiers[0] > 0 || localSizeQualifiers[1] > 0 || localSizeQualifiers[2] > 0; +} + +bool WorkGroupSize::isDeclared() const +{ + bool localSizeDeclared = localSizeQualifiers[0] > 0; + ASSERT(isLocalSizeValid()); + return localSizeDeclared; +} + +bool WorkGroupSize::isWorkGroupSizeMatching(const WorkGroupSize &right) const +{ + for (size_t i = 0u; i < size(); ++i) + { + bool result = (localSizeQualifiers[i] == right.localSizeQualifiers[i] || + (localSizeQualifiers[i] == 1 && right.localSizeQualifiers[i] == -1) || + (localSizeQualifiers[i] == -1 && right.localSizeQualifiers[i] == 1)); + if (!result) + { + return false; + } + } + return true; +} + +int &WorkGroupSize::operator[](size_t index) +{ + ASSERT(index < size()); + return localSizeQualifiers[index]; +} + +int WorkGroupSize::operator[](size_t index) const +{ + ASSERT(index < size()); + return localSizeQualifiers[index]; +} + +size_t WorkGroupSize::size() const +{ + return 3u; +} + } // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/SimplifyArrayAssignment.cpp b/src/3rdparty/angle/src/compiler/translator/SimplifyArrayAssignment.cpp deleted file mode 100644 index ac5eb67070..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/SimplifyArrayAssignment.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// -// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/translator/SimplifyArrayAssignment.h" - -bool SimplifyArrayAssignment::visitBinary(Visit visit, TIntermBinary *node) -{ - switch (node->getOp()) - { - case EOpAssign: - { - TIntermNode *parent = getParentNode(); - if (node->getLeft()->isArray() && parent != nullptr) - { - TIntermAggregate *parentAgg = parent->getAsAggregate(); - if (parentAgg != nullptr && parentAgg->getOp() == EOpSequence) - { - // This case is fine, the result of the assignment is not used. - break; - } - - // The result of the assignment needs to be stored into a temporary variable, - // the assignment needs to be replaced with a reference to the temporary variable, - // and the temporary variable needs to finally be assigned to the target variable. - - // This also needs to interact correctly with unfolding short circuiting operators. - UNIMPLEMENTED(); - } - } - break; - default: - break; - } - return true; -} diff --git a/src/3rdparty/angle/src/compiler/translator/SimplifyArrayAssignment.h b/src/3rdparty/angle/src/compiler/translator/SimplifyArrayAssignment.h deleted file mode 100644 index 247eb88d72..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/SimplifyArrayAssignment.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// SimplifyArrayAssignment is an AST traverser to replace statements where -// the return value of array assignment is used with statements where -// the return value of array assignment is not used. -// - -#ifndef COMPILER_TRANSLATOR_SIMPLIFYARRAYASSIGNMENT_H_ -#define COMPILER_TRANSLATOR_SIMPLIFYARRAYASSIGNMENT_H_ - -#include "common/angleutils.h" -#include "compiler/translator/IntermNode.h" - -class SimplifyArrayAssignment : public TIntermTraverser -{ - public: - SimplifyArrayAssignment() { } - - virtual bool visitBinary(Visit visit, TIntermBinary *node); -}; - -#endif // COMPILER_TRANSLATOR_SIMPLIFYARRAYASSIGNMENT_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/SimplifyLoopConditions.cpp b/src/3rdparty/angle/src/compiler/translator/SimplifyLoopConditions.cpp new file mode 100644 index 0000000000..9704046839 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/SimplifyLoopConditions.cpp @@ -0,0 +1,300 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// SimplifyLoopConditions is an AST traverser that converts loop conditions and loop expressions +// to regular statements inside the loop. This way further transformations that generate statements +// from loop conditions and loop expressions work correctly. +// + +#include "compiler/translator/SimplifyLoopConditions.h" + +#include "compiler/translator/IntermNodePatternMatcher.h" +#include "compiler/translator/IntermNode_util.h" +#include "compiler/translator/IntermTraverse.h" + +namespace sh +{ + +namespace +{ + +class SimplifyLoopConditionsTraverser : public TLValueTrackingTraverser +{ + public: + SimplifyLoopConditionsTraverser(unsigned int conditionsToSimplifyMask, + TSymbolTable *symbolTable, + int shaderVersion); + + void traverseLoop(TIntermLoop *node) override; + + bool visitUnary(Visit visit, TIntermUnary *node) override; + bool visitBinary(Visit visit, TIntermBinary *node) override; + bool visitAggregate(Visit visit, TIntermAggregate *node) override; + bool visitTernary(Visit visit, TIntermTernary *node) override; + bool visitDeclaration(Visit visit, TIntermDeclaration *node) override; + + bool foundLoopToChange() const { return mFoundLoopToChange; } + + protected: + // Marked to true once an operation that needs to be hoisted out of a loop expression has been + // found. + bool mFoundLoopToChange; + bool mInsideLoopInitConditionOrExpression; + IntermNodePatternMatcher mConditionsToSimplify; +}; + +SimplifyLoopConditionsTraverser::SimplifyLoopConditionsTraverser( + unsigned int conditionsToSimplifyMask, + TSymbolTable *symbolTable, + int shaderVersion) + : TLValueTrackingTraverser(true, false, false, symbolTable, shaderVersion), + mFoundLoopToChange(false), + mInsideLoopInitConditionOrExpression(false), + mConditionsToSimplify(conditionsToSimplifyMask) +{ +} + +// If we're inside a loop initialization, condition, or expression, we check for expressions that +// should be moved out of the loop condition or expression. If one is found, the loop is +// transformed. +// If we're not inside loop initialization, condition, or expression, we only need to traverse nodes +// that may contain loops. + +bool SimplifyLoopConditionsTraverser::visitUnary(Visit visit, TIntermUnary *node) +{ + if (!mInsideLoopInitConditionOrExpression) + return false; + + if (mFoundLoopToChange) + return false; // Already decided to change this loop. + + mFoundLoopToChange = mConditionsToSimplify.match(node); + return !mFoundLoopToChange; +} + +bool SimplifyLoopConditionsTraverser::visitBinary(Visit visit, TIntermBinary *node) +{ + if (!mInsideLoopInitConditionOrExpression) + return false; + + if (mFoundLoopToChange) + return false; // Already decided to change this loop. + + mFoundLoopToChange = mConditionsToSimplify.match(node, getParentNode(), isLValueRequiredHere()); + return !mFoundLoopToChange; +} + +bool SimplifyLoopConditionsTraverser::visitAggregate(Visit visit, TIntermAggregate *node) +{ + if (!mInsideLoopInitConditionOrExpression) + return false; + + if (mFoundLoopToChange) + return false; // Already decided to change this loop. + + mFoundLoopToChange = mConditionsToSimplify.match(node, getParentNode()); + return !mFoundLoopToChange; +} + +bool SimplifyLoopConditionsTraverser::visitTernary(Visit visit, TIntermTernary *node) +{ + if (!mInsideLoopInitConditionOrExpression) + return false; + + if (mFoundLoopToChange) + return false; // Already decided to change this loop. + + mFoundLoopToChange = mConditionsToSimplify.match(node); + return !mFoundLoopToChange; +} + +bool SimplifyLoopConditionsTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node) +{ + if (!mInsideLoopInitConditionOrExpression) + return false; + + if (mFoundLoopToChange) + return false; // Already decided to change this loop. + + mFoundLoopToChange = mConditionsToSimplify.match(node); + return !mFoundLoopToChange; +} + +void SimplifyLoopConditionsTraverser::traverseLoop(TIntermLoop *node) +{ + // Mark that we're inside a loop condition or expression, and determine if the loop needs to be + // transformed. + + ScopedNodeInTraversalPath addToPath(this, node); + + mInsideLoopInitConditionOrExpression = true; + mFoundLoopToChange = false; + + if (!mFoundLoopToChange && node->getInit()) + { + node->getInit()->traverse(this); + } + + if (!mFoundLoopToChange && node->getCondition()) + { + node->getCondition()->traverse(this); + } + + if (!mFoundLoopToChange && node->getExpression()) + { + node->getExpression()->traverse(this); + } + + mInsideLoopInitConditionOrExpression = false; + + if (mFoundLoopToChange) + { + nextTemporaryId(); + + // Replace the loop condition with a boolean variable that's updated on each iteration. + TLoopType loopType = node->getType(); + if (loopType == ELoopWhile) + { + // Transform: + // while (expr) { body; } + // into + // bool s0 = expr; + // while (s0) { { body; } s0 = expr; } + TIntermSequence tempInitSeq; + tempInitSeq.push_back(createTempInitDeclaration(node->getCondition()->deepCopy())); + insertStatementsInParentBlock(tempInitSeq); + + TIntermBlock *newBody = new TIntermBlock(); + if (node->getBody()) + { + newBody->getSequence()->push_back(node->getBody()); + } + newBody->getSequence()->push_back( + createTempAssignment(node->getCondition()->deepCopy())); + + // Can't use queueReplacement to replace old body, since it may have been nullptr. + // It's safe to do the replacements in place here - the new body will still be + // traversed, but that won't create any problems. + node->setBody(newBody); + node->setCondition(createTempSymbol(node->getCondition()->getType())); + } + else if (loopType == ELoopDoWhile) + { + // Transform: + // do { + // body; + // } while (expr); + // into + // bool s0 = true; + // do { + // { body; } + // s0 = expr; + // } while (s0); + TIntermSequence tempInitSeq; + tempInitSeq.push_back(createTempInitDeclaration(CreateBoolNode(true))); + insertStatementsInParentBlock(tempInitSeq); + + TIntermBlock *newBody = new TIntermBlock(); + if (node->getBody()) + { + newBody->getSequence()->push_back(node->getBody()); + } + newBody->getSequence()->push_back( + createTempAssignment(node->getCondition()->deepCopy())); + + // Can't use queueReplacement to replace old body, since it may have been nullptr. + // It's safe to do the replacements in place here - the new body will still be + // traversed, but that won't create any problems. + node->setBody(newBody); + node->setCondition(createTempSymbol(node->getCondition()->getType())); + } + else if (loopType == ELoopFor) + { + // Move the loop condition inside the loop. + // Transform: + // for (init; expr; exprB) { body; } + // into + // { + // init; + // bool s0 = expr; + // while (s0) { + // { body; } + // exprB; + // s0 = expr; + // } + // } + TIntermBlock *loopScope = new TIntermBlock(); + TIntermSequence *loopScopeSequence = loopScope->getSequence(); + + // Insert "init;" + if (node->getInit()) + { + loopScopeSequence->push_back(node->getInit()); + } + + // Insert "bool s0 = expr;" if applicable, "bool s0 = true;" otherwise + TIntermTyped *conditionInitializer = nullptr; + if (node->getCondition()) + { + conditionInitializer = node->getCondition()->deepCopy(); + } + else + { + conditionInitializer = CreateBoolNode(true); + } + loopScopeSequence->push_back(createTempInitDeclaration(conditionInitializer)); + + // Insert "{ body; }" in the while loop + TIntermBlock *whileLoopBody = new TIntermBlock(); + if (node->getBody()) + { + whileLoopBody->getSequence()->push_back(node->getBody()); + } + // Insert "exprB;" in the while loop + if (node->getExpression()) + { + whileLoopBody->getSequence()->push_back(node->getExpression()); + } + // Insert "s0 = expr;" in the while loop + if (node->getCondition()) + { + whileLoopBody->getSequence()->push_back( + createTempAssignment(node->getCondition()->deepCopy())); + } + + // Create "while(s0) { whileLoopBody }" + TIntermLoop *whileLoop = new TIntermLoop( + ELoopWhile, nullptr, createTempSymbol(conditionInitializer->getType()), nullptr, + whileLoopBody); + loopScope->getSequence()->push_back(whileLoop); + queueReplacement(loopScope, OriginalNode::IS_DROPPED); + + // After this the old body node will be traversed and loops inside it may be + // transformed. This is fine, since the old body node will still be in the AST after the + // transformation that's queued here, and transforming loops inside it doesn't need to + // know the exact post-transform path to it. + } + } + + mFoundLoopToChange = false; + + // We traverse the body of the loop even if the loop is transformed. + if (node->getBody()) + node->getBody()->traverse(this); +} + +} // namespace + +void SimplifyLoopConditions(TIntermNode *root, + unsigned int conditionsToSimplifyMask, + TSymbolTable *symbolTable, + int shaderVersion) +{ + SimplifyLoopConditionsTraverser traverser(conditionsToSimplifyMask, symbolTable, shaderVersion); + root->traverse(&traverser); + traverser.updateTree(); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/SimplifyLoopConditions.h b/src/3rdparty/angle/src/compiler/translator/SimplifyLoopConditions.h new file mode 100644 index 0000000000..d8f95cd2c8 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/SimplifyLoopConditions.h @@ -0,0 +1,25 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// SimplifyLoopConditions is an AST traverser that converts loop conditions and loop expressions +// to regular statements inside the loop. This way further transformations that generate statements +// from loop conditions and loop expressions work correctly. +// + +#ifndef COMPILER_TRANSLATOR_SIMPLIFYLOOPCONDITIONS_H_ +#define COMPILER_TRANSLATOR_SIMPLIFYLOOPCONDITIONS_H_ + +namespace sh +{ +class TIntermNode; +class TSymbolTable; + +void SimplifyLoopConditions(TIntermNode *root, + unsigned int conditionsToSimplify, + TSymbolTable *symbolTable, + int shaderVersion); +} // namespace sh + +#endif // COMPILER_TRANSLATOR_SIMPLIFYLOOPCONDITIONS_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/SplitSequenceOperator.cpp b/src/3rdparty/angle/src/compiler/translator/SplitSequenceOperator.cpp new file mode 100644 index 0000000000..5df3154560 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/SplitSequenceOperator.cpp @@ -0,0 +1,171 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// SplitSequenceOperator is an AST traverser that detects sequence operator expressions that +// go through further AST transformations that generate statements, and splits them so that +// possible side effects of earlier parts of the sequence operator expression are guaranteed to be +// evaluated before the latter parts of the sequence operator expression are evaluated. +// + +#include "compiler/translator/SplitSequenceOperator.h" + +#include "compiler/translator/IntermNodePatternMatcher.h" +#include "compiler/translator/IntermTraverse.h" + +namespace sh +{ + +namespace +{ + +class SplitSequenceOperatorTraverser : public TLValueTrackingTraverser +{ + public: + SplitSequenceOperatorTraverser(unsigned int patternsToSplitMask, + TSymbolTable *symbolTable, + int shaderVersion); + + bool visitUnary(Visit visit, TIntermUnary *node) override; + bool visitBinary(Visit visit, TIntermBinary *node) override; + bool visitAggregate(Visit visit, TIntermAggregate *node) override; + bool visitTernary(Visit visit, TIntermTernary *node) override; + + void nextIteration(); + bool foundExpressionToSplit() const { return mFoundExpressionToSplit; } + + protected: + // Marked to true once an operation that needs to be hoisted out of the expression has been + // found. After that, no more AST updates are performed on that traversal. + bool mFoundExpressionToSplit; + int mInsideSequenceOperator; + + IntermNodePatternMatcher mPatternToSplitMatcher; +}; + +SplitSequenceOperatorTraverser::SplitSequenceOperatorTraverser(unsigned int patternsToSplitMask, + TSymbolTable *symbolTable, + int shaderVersion) + : TLValueTrackingTraverser(true, false, true, symbolTable, shaderVersion), + mFoundExpressionToSplit(false), + mInsideSequenceOperator(0), + mPatternToSplitMatcher(patternsToSplitMask) +{ +} + +void SplitSequenceOperatorTraverser::nextIteration() +{ + mFoundExpressionToSplit = false; + mInsideSequenceOperator = 0; + nextTemporaryId(); +} + +bool SplitSequenceOperatorTraverser::visitAggregate(Visit visit, TIntermAggregate *node) +{ + if (mFoundExpressionToSplit) + return false; + + if (mInsideSequenceOperator > 0 && visit == PreVisit) + { + // Detect expressions that need to be simplified + mFoundExpressionToSplit = mPatternToSplitMatcher.match(node, getParentNode()); + return !mFoundExpressionToSplit; + } + + return true; +} + +bool SplitSequenceOperatorTraverser::visitUnary(Visit visit, TIntermUnary *node) +{ + if (mFoundExpressionToSplit) + return false; + + if (mInsideSequenceOperator > 0 && visit == PreVisit) + { + // Detect expressions that need to be simplified + mFoundExpressionToSplit = mPatternToSplitMatcher.match(node); + return !mFoundExpressionToSplit; + } + + return true; +} + +bool SplitSequenceOperatorTraverser::visitBinary(Visit visit, TIntermBinary *node) +{ + if (node->getOp() == EOpComma) + { + if (visit == PreVisit) + { + if (mFoundExpressionToSplit) + { + return false; + } + mInsideSequenceOperator++; + } + else if (visit == PostVisit) + { + // Split sequence operators starting from the outermost one to preserve correct + // execution order. + if (mFoundExpressionToSplit && mInsideSequenceOperator == 1) + { + // Move the left side operand into a separate statement in the parent block. + TIntermSequence insertions; + insertions.push_back(node->getLeft()); + insertStatementsInParentBlock(insertions); + // Replace the comma node with its right side operand. + queueReplacement(node->getRight(), OriginalNode::IS_DROPPED); + } + mInsideSequenceOperator--; + } + return true; + } + + if (mFoundExpressionToSplit) + return false; + + if (mInsideSequenceOperator > 0 && visit == PreVisit) + { + // Detect expressions that need to be simplified + mFoundExpressionToSplit = + mPatternToSplitMatcher.match(node, getParentNode(), isLValueRequiredHere()); + return !mFoundExpressionToSplit; + } + + return true; +} + +bool SplitSequenceOperatorTraverser::visitTernary(Visit visit, TIntermTernary *node) +{ + if (mFoundExpressionToSplit) + return false; + + if (mInsideSequenceOperator > 0 && visit == PreVisit) + { + // Detect expressions that need to be simplified + mFoundExpressionToSplit = mPatternToSplitMatcher.match(node); + return !mFoundExpressionToSplit; + } + + return true; +} + +} // namespace + +void SplitSequenceOperator(TIntermNode *root, + int patternsToSplitMask, + TSymbolTable *symbolTable, + int shaderVersion) +{ + SplitSequenceOperatorTraverser traverser(patternsToSplitMask, symbolTable, shaderVersion); + // Separate one expression at a time, and reset the traverser between iterations. + do + { + traverser.nextIteration(); + root->traverse(&traverser); + if (traverser.foundExpressionToSplit()) + traverser.updateTree(); + } while (traverser.foundExpressionToSplit()); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/SplitSequenceOperator.h b/src/3rdparty/angle/src/compiler/translator/SplitSequenceOperator.h new file mode 100644 index 0000000000..8f1a766775 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/SplitSequenceOperator.h @@ -0,0 +1,28 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// SplitSequenceOperator is an AST traverser that detects sequence operator expressions that +// go through further AST transformations that generate statements, and splits them so that +// possible side effects of earlier parts of the sequence operator expression are guaranteed to be +// evaluated before the latter parts of the sequence operator expression are evaluated. +// + +#ifndef COMPILER_TRANSLATOR_SPLITSEQUENCEOPERATOR_H_ +#define COMPILER_TRANSLATOR_SPLITSEQUENCEOPERATOR_H_ + +namespace sh +{ + +class TIntermNode; +class TSymbolTable; + +void SplitSequenceOperator(TIntermNode *root, + int patternsToSplitMask, + TSymbolTable *symbolTable, + int shaderVersion); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_SPLITSEQUENCEOPERATOR_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/StructureHLSL.cpp b/src/3rdparty/angle/src/compiler/translator/StructureHLSL.cpp index fd1a29c1cd..61a9431ceb 100644 --- a/src/3rdparty/angle/src/compiler/translator/StructureHLSL.cpp +++ b/src/3rdparty/angle/src/compiler/translator/StructureHLSL.cpp @@ -4,7 +4,7 @@ // found in the LICENSE file. // // StructureHLSL.cpp: -// Definitions of methods for HLSL translation of GLSL structures. +// HLSL translation of GLSL constructors and structures. // #include "compiler/translator/StructureHLSL.h" @@ -17,23 +17,94 @@ namespace sh { +namespace +{ + +TString Define(const TStructure &structure, + bool useHLSLRowMajorPacking, + bool useStd140Packing, + Std140PaddingHelper *padHelper) +{ + const TFieldList &fields = structure.fields(); + const bool isNameless = (structure.name() == ""); + const TString &structName = + QualifiedStructNameString(structure, useHLSLRowMajorPacking, useStd140Packing); + const TString declareString = (isNameless ? "struct" : "struct " + structName); + + TString string; + string += declareString + + "\n" + "{\n"; + + for (const TField *field : fields) + { + const TType &fieldType = *field->type(); + if (!IsSampler(fieldType.getBasicType())) + { + const TStructure *fieldStruct = fieldType.getStruct(); + const TString &fieldTypeString = + fieldStruct ? QualifiedStructNameString(*fieldStruct, useHLSLRowMajorPacking, + useStd140Packing) + : TypeString(fieldType); + + if (padHelper) + { + string += padHelper->prePaddingString(fieldType); + } + + string += " " + fieldTypeString + " " + DecorateField(field->name(), structure) + + ArrayString(fieldType) + ";\n"; + + if (padHelper) + { + string += padHelper->postPaddingString(fieldType, useHLSLRowMajorPacking); + } + } + } + + // Nameless structs do not finish with a semicolon and newline, to leave room for an instance + // variable + string += (isNameless ? "} " : "};\n"); + + return string; +} + +TString WriteParameterList(const std::vector ¶meters) +{ + TString parameterList; + for (size_t parameter = 0u; parameter < parameters.size(); parameter++) + { + const TType ¶mType = parameters[parameter]; + + parameterList += TypeString(paramType) + " x" + str(parameter) + ArrayString(paramType); + + if (parameter < parameters.size() - 1u) + { + parameterList += ", "; + } + } + return parameterList; +} + +} // anonymous namespace + Std140PaddingHelper::Std140PaddingHelper(const std::map &structElementIndexes, unsigned *uniqueCounter) - : mPaddingCounter(uniqueCounter), - mElementIndex(0), - mStructElementIndexes(&structElementIndexes) -{} + : mPaddingCounter(uniqueCounter), mElementIndex(0), mStructElementIndexes(&structElementIndexes) +{ +} Std140PaddingHelper::Std140PaddingHelper(const Std140PaddingHelper &other) : mPaddingCounter(other.mPaddingCounter), mElementIndex(other.mElementIndex), mStructElementIndexes(other.mStructElementIndexes) -{} +{ +} Std140PaddingHelper &Std140PaddingHelper::operator=(const Std140PaddingHelper &other) { - mPaddingCounter = other.mPaddingCounter; - mElementIndex = other.mElementIndex; + mPaddingCounter = other.mPaddingCounter; + mElementIndex = other.mElementIndex; mStructElementIndexes = other.mStructElementIndexes; return *this; } @@ -53,7 +124,7 @@ int Std140PaddingHelper::prePadding(const TType &type) return 0; } - const GLenum glType = GLVariableType(type); + const GLenum glType = GLVariableType(type); const int numComponents = gl::VariableComponentCount(glType); if (numComponents >= 4) @@ -70,9 +141,9 @@ int Std140PaddingHelper::prePadding(const TType &type) return 0; } - const int alignment = numComponents == 3 ? 4 : numComponents; + const int alignment = numComponents == 3 ? 4 : numComponents; const int paddingOffset = (mElementIndex % alignment); - const int paddingCount = (paddingOffset != 0 ? (alignment - paddingOffset) : 0); + const int paddingCount = (paddingOffset != 0 ? (alignment - paddingOffset) : 0); mElementIndex += paddingCount; mElementIndex += numComponents; @@ -102,25 +173,26 @@ TString Std140PaddingHelper::postPaddingString(const TType &type, bool useHLSLRo return ""; } - int numComponents = 0; - TStructure *structure = type.getStruct(); + int numComponents = 0; + const TStructure *structure = type.getStruct(); if (type.isMatrix()) { - // This method can also be called from structureString, which does not use layout qualifiers. + // This method can also be called from structureString, which does not use layout + // qualifiers. // Thus, use the method parameter for determining the matrix packing. // // Note HLSL row major packing corresponds to GL API column-major, and vice-versa, since we // wish to always transpose GL matrices to play well with HLSL's matrix array indexing. // const bool isRowMajorMatrix = !useHLSLRowMajorPacking; - const GLenum glType = GLVariableType(type); - numComponents = gl::MatrixComponentCount(glType, isRowMajorMatrix); + const GLenum glType = GLVariableType(type); + numComponents = gl::MatrixComponentCount(glType, isRowMajorMatrix); } else if (structure) { - const TString &structName = QualifiedStructNameString(*structure, - useHLSLRowMajorPacking, true); + const TString &structName = + QualifiedStructNameString(*structure, useHLSLRowMajorPacking, true); numComponents = mStructElementIndexes->find(structName)->second; if (numComponents == 0) @@ -131,7 +203,7 @@ TString Std140PaddingHelper::postPaddingString(const TType &type, bool useHLSLRo else { const GLenum glType = GLVariableType(type); - numComponents = gl::VariableComponentCount(glType); + numComponents = gl::VariableComponentCount(glType); } TString padding; @@ -142,178 +214,183 @@ TString Std140PaddingHelper::postPaddingString(const TType &type, bool useHLSLRo return padding; } -StructureHLSL::StructureHLSL() - : mUniquePaddingCounter(0) -{} +StructureHLSL::StructureHLSL() : mUniquePaddingCounter(0) +{ +} Std140PaddingHelper StructureHLSL::getPaddingHelper() { return Std140PaddingHelper(mStd140StructElementIndexes, &mUniquePaddingCounter); } -TString StructureHLSL::defineQualified(const TStructure &structure, bool useHLSLRowMajorPacking, bool useStd140Packing) +TString StructureHLSL::defineQualified(const TStructure &structure, + bool useHLSLRowMajorPacking, + bool useStd140Packing) { if (useStd140Packing) { Std140PaddingHelper padHelper = getPaddingHelper(); - return define(structure, useHLSLRowMajorPacking, useStd140Packing, &padHelper); + return Define(structure, useHLSLRowMajorPacking, useStd140Packing, &padHelper); } else { - return define(structure, useHLSLRowMajorPacking, useStd140Packing, NULL); + return Define(structure, useHLSLRowMajorPacking, useStd140Packing, nullptr); } } TString StructureHLSL::defineNameless(const TStructure &structure) { - return define(structure, false, false, NULL); + return Define(structure, false, false, nullptr); } -TString StructureHLSL::define(const TStructure &structure, bool useHLSLRowMajorPacking, - bool useStd140Packing, Std140PaddingHelper *padHelper) +StructureHLSL::DefinedStructs::iterator StructureHLSL::defineVariants(const TStructure &structure, + const TString &name) { - const TFieldList &fields = structure.fields(); - const bool isNameless = (structure.name() == ""); - const TString &structName = QualifiedStructNameString(structure, useHLSLRowMajorPacking, - useStd140Packing); - const TString declareString = (isNameless ? "struct" : "struct " + structName); + ASSERT(mDefinedStructs.find(name) == mDefinedStructs.end()); - TString string; - string += declareString + "\n" - "{\n"; - - for (unsigned int i = 0; i < fields.size(); i++) + for (const TField *field : structure.fields()) { - const TField &field = *fields[i]; - const TType &fieldType = *field.type(); - const TStructure *fieldStruct = fieldType.getStruct(); - const TString &fieldTypeString = fieldStruct ? - QualifiedStructNameString(*fieldStruct, useHLSLRowMajorPacking, - useStd140Packing) : - TypeString(fieldType); - - if (padHelper) + const TType *fieldType = field->type(); + if (fieldType->getBasicType() == EbtStruct) { - string += padHelper->prePaddingString(fieldType); - } - - string += " " + fieldTypeString + " " + DecorateField(field.name(), structure) + ArrayString(fieldType) + ";\n"; - - if (padHelper) - { - string += padHelper->postPaddingString(fieldType, useHLSLRowMajorPacking); + ensureStructDefined(*fieldType->getStruct()); } } - // Nameless structs do not finish with a semicolon and newline, to leave room for an instance variable - string += (isNameless ? "} " : "};\n"); + DefinedStructs::iterator addedStruct = + mDefinedStructs.insert(std::make_pair(name, new TStructProperties())).first; + // Add element index + storeStd140ElementIndex(structure, false); + storeStd140ElementIndex(structure, true); - return string; + const TString &structString = defineQualified(structure, false, false); + + ASSERT(std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structString) == + mStructDeclarations.end()); + // Add row-major packed struct for interface blocks + TString rowMajorString = "#pragma pack_matrix(row_major)\n" + + defineQualified(structure, true, false) + + "#pragma pack_matrix(column_major)\n"; + + TString std140String = defineQualified(structure, false, true); + TString std140RowMajorString = "#pragma pack_matrix(row_major)\n" + + defineQualified(structure, true, true) + + "#pragma pack_matrix(column_major)\n"; + + mStructDeclarations.push_back(structString); + mStructDeclarations.push_back(rowMajorString); + mStructDeclarations.push_back(std140String); + mStructDeclarations.push_back(std140RowMajorString); + return addedStruct; } -void StructureHLSL::addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters) +void StructureHLSL::ensureStructDefined(const TStructure &structure) { + const TString name = StructNameString(structure); if (name == "") { - return; // Nameless structures don't have constructors + return; // Nameless structures are not defined + } + if (mDefinedStructs.find(name) == mDefinedStructs.end()) + { + defineVariants(structure, name); + } +} + +TString StructureHLSL::addStructConstructor(const TStructure &structure) +{ + const TString name = StructNameString(structure); + + if (name == "") + { + return TString(); // Nameless structures don't have constructors } - if (type.getStruct() && mStructNames.find(name) != mStructNames.end()) + auto definedStruct = mDefinedStructs.find(name); + if (definedStruct == mDefinedStructs.end()) { - return; // Already added + definedStruct = defineVariants(structure, name); } + const TString constructorFunctionName = TString(name) + "_ctor"; + TString *constructor = &definedStruct->second->constructor; + if (!constructor->empty()) + { + return constructorFunctionName; // Already added + } + *constructor += name + " " + constructorFunctionName + "("; + + std::vector ctorParameters; + const TFieldList &fields = structure.fields(); + for (const TField *field : fields) + { + const TType *fieldType = field->type(); + if (!IsSampler(fieldType->getBasicType())) + { + ctorParameters.push_back(*fieldType); + } + } + // Structs that have sampler members should not have constructor calls, and otherwise structs + // are guaranteed to be non-empty by the grammar. Structs can't contain empty declarations + // either. + ASSERT(!ctorParameters.empty()); + + *constructor += WriteParameterList(ctorParameters); + + *constructor += + ")\n" + "{\n" + " " + + name + " structure = { "; + + for (size_t parameterIndex = 0u; parameterIndex < ctorParameters.size(); ++parameterIndex) + { + *constructor += "x" + str(parameterIndex); + if (parameterIndex < ctorParameters.size() - 1u) + { + *constructor += ", "; + } + } + *constructor += + "};\n" + " return structure;\n" + "}\n"; + + return constructorFunctionName; +} + +TString StructureHLSL::addBuiltInConstructor(const TType &type, const TIntermSequence *parameters) +{ + ASSERT(!type.isArray()); + ASSERT(type.getStruct() == nullptr); + ASSERT(parameters); TType ctorType = type; - ctorType.clearArrayness(); ctorType.setPrecision(EbpHigh); ctorType.setQualifier(EvqTemporary); - typedef std::vector ParameterArray; - ParameterArray ctorParameters; + const TString constructorFunctionName = + TString(type.getBuiltInTypeNameString()) + "_ctor" + DisambiguateFunctionName(parameters); + TString constructor = TypeString(ctorType) + " " + constructorFunctionName + "("; - const TStructure* structure = type.getStruct(); - if (structure) + std::vector ctorParameters; + for (auto parameter : *parameters) { - mStructNames.insert(name); - - // Add element index - storeStd140ElementIndex(*structure, false); - storeStd140ElementIndex(*structure, true); - - const TString &structString = defineQualified(*structure, false, false); - - if (std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structString) == mStructDeclarations.end()) - { - // Add row-major packed struct for interface blocks - TString rowMajorString = "#pragma pack_matrix(row_major)\n" + - defineQualified(*structure, true, false) + - "#pragma pack_matrix(column_major)\n"; - - TString std140String = defineQualified(*structure, false, true); - TString std140RowMajorString = "#pragma pack_matrix(row_major)\n" + - defineQualified(*structure, true, true) + - "#pragma pack_matrix(column_major)\n"; - - mStructDeclarations.push_back(structString); - mStructDeclarations.push_back(rowMajorString); - mStructDeclarations.push_back(std140String); - mStructDeclarations.push_back(std140RowMajorString); - } - - const TFieldList &fields = structure->fields(); - for (unsigned int i = 0; i < fields.size(); i++) - { - ctorParameters.push_back(*fields[i]->type()); - } + const TType ¶mType = parameter->getAsTyped()->getType(); + ASSERT(!paramType.isArray()); + ctorParameters.push_back(paramType); } - else if (parameters) - { - for (TIntermSequence::const_iterator parameter = parameters->begin(); parameter != parameters->end(); parameter++) - { - ctorParameters.push_back((*parameter)->getAsTyped()->getType()); - } - } - else UNREACHABLE(); + constructor += WriteParameterList(ctorParameters); - TString constructor; - - if (ctorType.getStruct()) - { - constructor += name + " " + name + "_ctor("; - } - else // Built-in type - { - constructor += TypeString(ctorType) + " " + name + "("; - } - - for (unsigned int parameter = 0; parameter < ctorParameters.size(); parameter++) - { - const TType ¶mType = ctorParameters[parameter]; - - constructor += TypeString(paramType) + " x" + str(parameter) + ArrayString(paramType); - - if (parameter < ctorParameters.size() - 1) - { - constructor += ", "; - } - } - - constructor += ")\n" - "{\n"; - - if (ctorType.getStruct()) - { - constructor += " " + name + " structure = {"; - } - else - { - constructor += " return " + TypeString(ctorType) + "("; - } + constructor += + ")\n" + "{\n" + " return " + + TypeString(ctorType) + "("; if (ctorType.isMatrix() && ctorParameters.size() == 1) { - int rows = ctorType.getRows(); - int cols = ctorType.getCols(); + int rows = ctorType.getRows(); + int cols = ctorType.getCols(); const TType ¶meter = ctorParameters[0]; if (parameter.isScalar()) @@ -355,7 +432,8 @@ void StructureHLSL::addConstructor(const TType &type, const TString &name, const } else { - ASSERT(rows == 2 && cols == 2 && parameter.isVector() && parameter.getNominalSize() == 4); + ASSERT(rows == 2 && cols == 2 && parameter.isVector() && + parameter.getNominalSize() == 4); constructor += "x0"; } @@ -367,20 +445,13 @@ void StructureHLSL::addConstructor(const TType &type, const TString &name, const while (remainingComponents > 0) { - const TType ¶meter = ctorParameters[parameterIndex]; + const TType ¶meter = ctorParameters[parameterIndex]; const size_t parameterSize = parameter.getObjectSize(); - bool moreParameters = parameterIndex + 1 < ctorParameters.size(); + bool moreParameters = parameterIndex + 1 < ctorParameters.size(); constructor += "x" + str(parameterIndex); - if (ctorType.getStruct()) - { - ASSERT(remainingComponents == parameterSize || moreParameters); - ASSERT(parameterSize <= remainingComponents); - - remainingComponents -= parameterSize; - } - else if (parameter.isScalar()) + if (parameter.isScalar()) { remainingComponents -= parameter.getObjectSize(); } @@ -395,16 +466,26 @@ void StructureHLSL::addConstructor(const TType &type, const TString &name, const { switch (remainingComponents) { - case 1: constructor += ".x"; break; - case 2: constructor += ".xy"; break; - case 3: constructor += ".xyz"; break; - case 4: constructor += ".xyzw"; break; - default: UNREACHABLE(); + case 1: + constructor += ".x"; + break; + case 2: + constructor += ".xy"; + break; + case 3: + constructor += ".xyz"; + break; + case 4: + constructor += ".xyzw"; + break; + default: + UNREACHABLE(); } remainingComponents = 0; } - else UNREACHABLE(); + else + UNREACHABLE(); } else if (parameter.isMatrix()) { @@ -417,10 +498,17 @@ void StructureHLSL::addConstructor(const TType &type, const TString &name, const { switch (remainingComponents) { - case 1: constructor += ".x"; break; - case 2: constructor += ".xy"; break; - case 3: constructor += ".xyz"; break; - default: UNREACHABLE(); + case 1: + constructor += ".x"; + break; + case 2: + constructor += ".xy"; + break; + case 3: + constructor += ".xyz"; + break; + default: + UNREACHABLE(); } remainingComponents = 0; @@ -438,7 +526,10 @@ void StructureHLSL::addConstructor(const TType &type, const TString &name, const column++; } } - else UNREACHABLE(); + else + { + UNREACHABLE(); + } if (moreParameters) { @@ -452,53 +543,52 @@ void StructureHLSL::addConstructor(const TType &type, const TString &name, const } } - if (ctorType.getStruct()) - { - constructor += "};\n" - " return structure;\n" - "}\n"; - } - else - { - constructor += ");\n" - "}\n"; - } + constructor += + ");\n" + "}\n"; - mConstructors.insert(constructor); + mBuiltInConstructors.insert(constructor); + + return constructorFunctionName; } std::string StructureHLSL::structsHeader() const { TInfoSinkBase out; - for (size_t structIndex = 0; structIndex < mStructDeclarations.size(); structIndex++) + for (auto &declaration : mStructDeclarations) { - out << mStructDeclarations[structIndex]; + out << declaration; } - for (Constructors::const_iterator constructor = mConstructors.begin(); - constructor != mConstructors.end(); - constructor++) + for (auto &structure : mDefinedStructs) { - out << *constructor; + out << structure.second->constructor; + } + + for (auto &constructor : mBuiltInConstructors) + { + out << constructor; } return out.str(); } -void StructureHLSL::storeStd140ElementIndex(const TStructure &structure, bool useHLSLRowMajorPacking) +void StructureHLSL::storeStd140ElementIndex(const TStructure &structure, + bool useHLSLRowMajorPacking) { Std140PaddingHelper padHelper = getPaddingHelper(); - const TFieldList &fields = structure.fields(); + const TFieldList &fields = structure.fields(); - for (unsigned int i = 0; i < fields.size(); i++) + for (const TField *field : fields) { - padHelper.prePadding(*fields[i]->type()); + padHelper.prePadding(*field->type()); } - // Add remaining element index to the global map, for use with nested structs in standard layouts + // Add remaining element index to the global map, for use with nested structs in standard + // layouts const TString &structName = QualifiedStructNameString(structure, useHLSLRowMajorPacking, true); mStd140StructElementIndexes[structName] = padHelper.elementIndex(); } -} +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/StructureHLSL.h b/src/3rdparty/angle/src/compiler/translator/StructureHLSL.h index cffe2a41ae..daced8f8d1 100644 --- a/src/3rdparty/angle/src/compiler/translator/StructureHLSL.h +++ b/src/3rdparty/angle/src/compiler/translator/StructureHLSL.h @@ -4,7 +4,7 @@ // found in the LICENSE file. // // StructureHLSL.h: -// Interfaces of methods for HLSL translation of GLSL structures. +// HLSL translation of GLSL constructors and structures. // #ifndef COMPILER_TRANSLATOR_STRUCTUREHLSL_H_ @@ -49,11 +49,14 @@ class StructureHLSL : angle::NonCopyable public: StructureHLSL(); - void addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters); - std::string structsHeader() const; + // Returns the name of the constructor function. + TString addStructConstructor(const TStructure &structure); + TString addBuiltInConstructor(const TType &type, const TIntermSequence *parameters); - TString defineQualified(const TStructure &structure, bool useHLSLRowMajorPacking, bool useStd140Packing); static TString defineNameless(const TStructure &structure); + void ensureStructDefined(const TStructure &structure); + + std::string structsHeader() const; Std140PaddingHelper getPaddingHelper(); @@ -62,20 +65,34 @@ class StructureHLSL : angle::NonCopyable std::map mStd140StructElementIndexes; - typedef std::set StructNames; - StructNames mStructNames; + struct TStructProperties : public angle::NonCopyable + { + POOL_ALLOCATOR_NEW_DELETE(); - typedef std::set Constructors; - Constructors mConstructors; + TStructProperties() {} + // Constructor is an empty string in case the struct doesn't have a constructor yet. + TString constructor; + }; + + // Map from struct name to struct properties. + typedef std::map DefinedStructs; + DefinedStructs mDefinedStructs; + + // Struct declarations need to be kept in a vector instead of having them inside mDefinedStructs + // since maintaining the original order is necessary for nested structs. typedef std::vector StructDeclarations; StructDeclarations mStructDeclarations; - void storeStd140ElementIndex(const TStructure &structure, bool useHLSLRowMajorPacking); - static TString define(const TStructure &structure, bool useHLSLRowMajorPacking, - bool useStd140Packing, Std140PaddingHelper *padHelper); -}; + typedef std::set BuiltInConstructors; + BuiltInConstructors mBuiltInConstructors; + void storeStd140ElementIndex(const TStructure &structure, bool useHLSLRowMajorPacking); + TString defineQualified(const TStructure &structure, + bool useHLSLRowMajorPacking, + bool useStd140Packing); + DefinedStructs::iterator defineVariants(const TStructure &structure, const TString &name); +}; } -#endif // COMPILER_TRANSLATOR_STRUCTUREHLSL_H_ +#endif // COMPILER_TRANSLATOR_STRUCTUREHLSL_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/SymbolTable.cpp b/src/3rdparty/angle/src/compiler/translator/SymbolTable.cpp index dc8f8e3b6b..6c38461469 100644 --- a/src/3rdparty/angle/src/compiler/translator/SymbolTable.cpp +++ b/src/3rdparty/angle/src/compiler/translator/SymbolTable.cpp @@ -3,45 +3,87 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // - -// -// Symbol table for parsing. Most functionaliy and main ideas -// are documented in the header file. +// Symbol table for parsing. The design principles and most of the functionality are documented in +// the header file. // #if defined(_MSC_VER) -#pragma warning(disable: 4718) +#pragma warning(disable : 4718) #endif #include "compiler/translator/SymbolTable.h" + #include "compiler/translator/Cache.h" +#include "compiler/translator/IntermNode.h" #include #include -int TSymbolTable::uniqueIdCounter = 0; +namespace sh +{ + +namespace +{ + +static const char kFunctionMangledNameSeparator = '('; + +} // anonymous namespace + +TSymbol::TSymbol(TSymbolTable *symbolTable, const TString *n) + : uniqueId(symbolTable->nextUniqueId()), name(n), extension(TExtension::UNDEFINED) +{ +} // // Functions have buried pointers to delete. // TFunction::~TFunction() +{ + clearParameters(); +} + +void TFunction::clearParameters() { for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i) delete (*i).type; + parameters.clear(); + mangledName = nullptr; +} + +void TFunction::swapParameters(const TFunction ¶metersSource) +{ + clearParameters(); + for (auto parameter : parametersSource.parameters) + { + addParameter(parameter); + } } const TString *TFunction::buildMangledName() const { - std::string newName = mangleName(getName()).c_str(); + std::string newName = getName().c_str(); + newName += kFunctionMangledNameSeparator; for (const auto &p : parameters) { - newName += p.type->getMangledName().c_str(); + newName += p.type->getMangledName(); } - return NewPoolTString(newName.c_str()); } +const TString &TFunction::GetMangledNameFromCall(const TString &functionName, + const TIntermSequence &arguments) +{ + std::string newName = functionName.c_str(); + newName += kFunctionMangledNameSeparator; + + for (TIntermNode *argument : arguments) + { + newName += argument->getAsTyped()->getType().getMangledName(); + } + return *NewPoolTString(newName.c_str()); +} + // // Symbol table levels are a map of pointers to symbols that have to be deleted. // @@ -53,8 +95,6 @@ TSymbolTableLevel::~TSymbolTableLevel() bool TSymbolTableLevel::insert(TSymbol *symbol) { - symbol->setUniqueId(TSymbolTable::nextUniqueId()); - // returning true means symbol was added to the table tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol)); @@ -63,8 +103,6 @@ bool TSymbolTableLevel::insert(TSymbol *symbol) bool TSymbolTableLevel::insertUnmangled(TFunction *function) { - function->setUniqueId(TSymbolTable::nextUniqueId()); - // returning true means symbol was added to the table tInsertResult result = level.insert(tLevelPair(function->getName(), function)); @@ -80,22 +118,27 @@ TSymbol *TSymbolTableLevel::find(const TString &name) const return (*it).second; } -TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, - bool *builtIn, bool *sameScope) const +TSymbol *TSymbolTable::find(const TString &name, + int shaderVersion, + bool *builtIn, + bool *sameScope) const { int level = currentLevel(); TSymbol *symbol; do { - if (level == ESSL3_BUILTINS && shaderVersion != 300) + if (level == GLSL_BUILTINS) + level--; + if (level == ESSL3_1_BUILTINS && shaderVersion != 310) + level--; + if (level == ESSL3_BUILTINS && shaderVersion < 300) level--; if (level == ESSL1_BUILTINS && shaderVersion != 100) level--; symbol = table[level]->find(name); - } - while (symbol == 0 && --level >= 0); + } while (symbol == 0 && --level >= 0); if (builtIn) *builtIn = (level <= LAST_BUILTIN_LEVEL); @@ -105,12 +148,28 @@ TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, return symbol; } -TSymbol *TSymbolTable::findBuiltIn( - const TString &name, int shaderVersion) const +TSymbol *TSymbolTable::findGlobal(const TString &name) const +{ + ASSERT(table.size() > GLOBAL_LEVEL); + return table[GLOBAL_LEVEL]->find(name); +} + +TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const +{ + return findBuiltIn(name, shaderVersion, false); +} + +TSymbol *TSymbolTable::findBuiltIn(const TString &name, + int shaderVersion, + bool includeGLSLBuiltins) const { for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--) { - if (level == ESSL3_BUILTINS && shaderVersion != 300) + if (level == GLSL_BUILTINS && !includeGLSLBuiltins) + level--; + if (level == ESSL3_1_BUILTINS && shaderVersion != 310) + level--; + if (level == ESSL3_BUILTINS && shaderVersion < 300) level--; if (level == ESSL1_BUILTINS && shaderVersion != 100) level--; @@ -121,7 +180,7 @@ TSymbol *TSymbolTable::findBuiltIn( return symbol; } - return 0; + return nullptr; } TSymbolTable::~TSymbolTable() @@ -135,7 +194,8 @@ bool IsGenType(const TType *type) if (type) { TBasicType basicType = type->getBasicType(); - return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType || basicType == EbtGenBType; + return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType || + basicType == EbtGenBType; } return false; @@ -146,7 +206,8 @@ bool IsVecType(const TType *type) if (type) { TBasicType basicType = type->getBasicType(); - return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec || basicType == EbtBVec; + return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec || + basicType == EbtBVec; } return false; @@ -163,13 +224,19 @@ const TType *SpecificType(const TType *type, int size) ASSERT(!IsVecType(type)); - switch(type->getBasicType()) + switch (type->getBasicType()) { - case EbtGenType: return TCache::getType(EbtFloat, static_cast(size)); - case EbtGenIType: return TCache::getType(EbtInt, static_cast(size)); - case EbtGenUType: return TCache::getType(EbtUInt, static_cast(size)); - case EbtGenBType: return TCache::getType(EbtBool, static_cast(size)); - default: return type; + case EbtGenType: + return TCache::getType(EbtFloat, type->getQualifier(), + static_cast(size)); + case EbtGenIType: + return TCache::getType(EbtInt, type->getQualifier(), static_cast(size)); + case EbtGenUType: + return TCache::getType(EbtUInt, type->getQualifier(), static_cast(size)); + case EbtGenBType: + return TCache::getType(EbtBool, type->getQualifier(), static_cast(size)); + default: + return type; } } @@ -184,65 +251,232 @@ const TType *VectorType(const TType *type, int size) ASSERT(!IsGenType(type)); - switch(type->getBasicType()) + switch (type->getBasicType()) { - case EbtVec: return TCache::getType(EbtFloat, static_cast(size)); - case EbtIVec: return TCache::getType(EbtInt, static_cast(size)); - case EbtUVec: return TCache::getType(EbtUInt, static_cast(size)); - case EbtBVec: return TCache::getType(EbtBool, static_cast(size)); - default: return type; + case EbtVec: + return TCache::getType(EbtFloat, static_cast(size)); + case EbtIVec: + return TCache::getType(EbtInt, static_cast(size)); + case EbtUVec: + return TCache::getType(EbtUInt, static_cast(size)); + case EbtBVec: + return TCache::getType(EbtBool, static_cast(size)); + default: + return type; } } -void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, const char *ext, const TType *rvalue, const char *name, - const TType *ptype1, const TType *ptype2, const TType *ptype3, const TType *ptype4, const TType *ptype5) +TVariable *TSymbolTable::declareVariable(const TString *name, const TType &type) +{ + return insertVariable(currentLevel(), name, type); +} + +TVariable *TSymbolTable::declareStructType(TStructure *str) +{ + return insertStructType(currentLevel(), str); +} + +TInterfaceBlockName *TSymbolTable::declareInterfaceBlockName(const TString *name) +{ + TInterfaceBlockName *blockNameSymbol = new TInterfaceBlockName(this, name); + if (insert(currentLevel(), blockNameSymbol)) + { + return blockNameSymbol; + } + return nullptr; +} + +TInterfaceBlockName *TSymbolTable::insertInterfaceBlockNameExt(ESymbolLevel level, + TExtension ext, + const TString *name) +{ + TInterfaceBlockName *blockNameSymbol = new TInterfaceBlockName(this, name); + if (insert(level, ext, blockNameSymbol)) + { + return blockNameSymbol; + } + return nullptr; +} + +TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const char *name, const TType &type) +{ + return insertVariable(level, NewPoolTString(name), type); +} + +TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const TString *name, const TType &type) +{ + TVariable *var = new TVariable(this, name, type); + if (insert(level, var)) + { + // Do lazy initialization for struct types, so we allocate to the current scope. + if (var->getType().getBasicType() == EbtStruct) + { + var->getType().realize(); + } + return var; + } + return nullptr; +} + +TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level, + TExtension ext, + const char *name, + const TType &type) +{ + TVariable *var = new TVariable(this, NewPoolTString(name), type); + if (insert(level, ext, var)) + { + if (var->getType().getBasicType() == EbtStruct) + { + var->getType().realize(); + } + return var; + } + return nullptr; +} + +TVariable *TSymbolTable::insertStructType(ESymbolLevel level, TStructure *str) +{ + TVariable *var = new TVariable(this, &str->name(), TType(str), true); + if (insert(level, var)) + { + var->getType().realize(); + return var; + } + return nullptr; +} + +void TSymbolTable::insertBuiltIn(ESymbolLevel level, + TOperator op, + TExtension ext, + const TType *rvalue, + const char *name, + const TType *ptype1, + const TType *ptype2, + const TType *ptype3, + const TType *ptype4, + const TType *ptype5) { if (ptype1->getBasicType() == EbtGSampler2D) { + insertUnmangledBuiltInName(name, level); bool gvec4 = (rvalue->getBasicType() == EbtGVec4); - insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5); - insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5); - insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, TCache::getType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, + TCache::getType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, + TCache::getType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, + TCache::getType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5); } else if (ptype1->getBasicType() == EbtGSampler3D) { + insertUnmangledBuiltInName(name, level); bool gvec4 = (rvalue->getBasicType() == EbtGVec4); - insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5); - insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5); - insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, TCache::getType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, + TCache::getType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, + TCache::getType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, + TCache::getType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5); } else if (ptype1->getBasicType() == EbtGSamplerCube) { + insertUnmangledBuiltInName(name, level); bool gvec4 = (rvalue->getBasicType() == EbtGVec4); - insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5); - insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5); - insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, TCache::getType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, + TCache::getType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, + TCache::getType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, + TCache::getType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5); } else if (ptype1->getBasicType() == EbtGSampler2DArray) { + insertUnmangledBuiltInName(name, level); bool gvec4 = (rvalue->getBasicType() == EbtGVec4); - insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5); - insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5); - insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, TCache::getType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, + TCache::getType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, + TCache::getType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, + TCache::getType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5); } - else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3)) + else if (ptype1->getBasicType() == EbtGSampler2DMS) { - ASSERT(!ptype4 && !ptype5); - insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1), SpecificType(ptype2, 1), SpecificType(ptype3, 1)); - insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2), SpecificType(ptype2, 2), SpecificType(ptype3, 2)); - insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3), SpecificType(ptype2, 3), SpecificType(ptype3, 3)); - insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4), SpecificType(ptype2, 4), SpecificType(ptype3, 4)); + insertUnmangledBuiltInName(name, level); + bool gvec4 = (rvalue->getBasicType() == EbtGVec4); + insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, + TCache::getType(EbtSampler2DMS), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, + TCache::getType(EbtISampler2DMS), ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, + TCache::getType(EbtUSampler2DMS), ptype2, ptype3, ptype4, ptype5); + } + else if (IsGImage(ptype1->getBasicType())) + { + insertUnmangledBuiltInName(name, level); + + const TType *floatType = TCache::getType(EbtFloat, 4); + const TType *intType = TCache::getType(EbtInt, 4); + const TType *unsignedType = TCache::getType(EbtUInt, 4); + + const TType *floatImage = + TCache::getType(convertGImageToFloatImage(ptype1->getBasicType())); + const TType *intImage = TCache::getType(convertGImageToIntImage(ptype1->getBasicType())); + const TType *unsignedImage = + TCache::getType(convertGImageToUnsignedImage(ptype1->getBasicType())); + + // GLSL ES 3.10, Revision 4, 8.12 Image Functions + if (rvalue->getBasicType() == EbtGVec4) + { + // imageLoad + insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5); + } + else if (rvalue->getBasicType() == EbtVoid) + { + // imageStore + insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5); + insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5); + insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5); + } + else + { + // imageSize + insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5); + insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5); + } + } + else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3) || + IsGenType(ptype4)) + { + ASSERT(!ptype5); + insertUnmangledBuiltInName(name, level); + insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1), + SpecificType(ptype2, 1), SpecificType(ptype3, 1), SpecificType(ptype4, 1)); + insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2), + SpecificType(ptype2, 2), SpecificType(ptype3, 2), SpecificType(ptype4, 2)); + insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3), + SpecificType(ptype2, 3), SpecificType(ptype3, 3), SpecificType(ptype4, 3)); + insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4), + SpecificType(ptype2, 4), SpecificType(ptype3, 4), SpecificType(ptype4, 4)); } else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3)) { ASSERT(!ptype4 && !ptype5); - insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2), VectorType(ptype2, 2), VectorType(ptype3, 2)); - insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3), VectorType(ptype2, 3), VectorType(ptype3, 3)); - insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4), VectorType(ptype2, 4), VectorType(ptype3, 4)); + insertUnmangledBuiltInName(name, level); + insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2), + VectorType(ptype2, 2), VectorType(ptype3, 2)); + insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3), + VectorType(ptype2, 3), VectorType(ptype3, 3)); + insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4), + VectorType(ptype2, 4), VectorType(ptype3, 4)); } else { - TFunction *function = new TFunction(NewPoolTString(name), rvalue, op, ext); + TFunction *function = new TFunction(this, NewPoolTString(name), rvalue, op, ext); function->addParameter(TConstParameter(ptype1)); @@ -266,10 +500,61 @@ void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, const char *e function->addParameter(TConstParameter(ptype5)); } + ASSERT(hasUnmangledBuiltInAtLevel(name, level)); insert(level, function); } } +void TSymbolTable::insertBuiltInOp(ESymbolLevel level, + TOperator op, + const TType *rvalue, + const TType *ptype1, + const TType *ptype2, + const TType *ptype3, + const TType *ptype4, + const TType *ptype5) +{ + const char *name = GetOperatorString(op); + ASSERT(strlen(name) > 0); + insertUnmangledBuiltInName(name, level); + insertBuiltIn(level, op, TExtension::UNDEFINED, rvalue, name, ptype1, ptype2, ptype3, ptype4, + ptype5); +} + +void TSymbolTable::insertBuiltInOp(ESymbolLevel level, + TOperator op, + TExtension ext, + const TType *rvalue, + const TType *ptype1, + const TType *ptype2, + const TType *ptype3, + const TType *ptype4, + const TType *ptype5) +{ + const char *name = GetOperatorString(op); + insertUnmangledBuiltInName(name, level); + insertBuiltIn(level, op, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5); +} + +void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level, + TOperator op, + const TType *rvalue, + const char *name) +{ + insertUnmangledBuiltInName(name, level); + insert(level, new TFunction(this, NewPoolTString(name), rvalue, op)); +} + +void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level, + TExtension ext, + TOperator op, + const TType *rvalue, + const char *name) +{ + insertUnmangledBuiltInName(name, level); + insert(level, new TFunction(this, NewPoolTString(name), rvalue, op, ext)); +} + TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const { if (!SupportsPrecision(type)) @@ -279,7 +564,7 @@ TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const TBasicType baseType = (type == EbtUInt) ? EbtInt : type; int level = static_cast(precisionStack.size()) - 1; - assert(level >= 0); // Just to be safe. Should not happen. + assert(level >= 0); // Just to be safe. Should not happen. // If we dont find anything we return this. Some types don't have predefined default precision. TPrecision prec = EbpUndefined; while (level >= 0) @@ -294,3 +579,44 @@ TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const } return prec; } + +void TSymbolTable::insertUnmangledBuiltInName(const char *name, ESymbolLevel level) +{ + ASSERT(level >= 0 && level < static_cast(table.size())); + table[level]->insertUnmangledBuiltInName(std::string(name)); +} + +bool TSymbolTable::hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level) +{ + ASSERT(level >= 0 && level < static_cast(table.size())); + return table[level]->hasUnmangledBuiltIn(std::string(name)); +} + +bool TSymbolTable::hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion) +{ + ASSERT(static_cast(table.size()) > LAST_BUILTIN_LEVEL); + + for (int level = LAST_BUILTIN_LEVEL; level >= 0; --level) + { + if (level == ESSL3_1_BUILTINS && shaderVersion != 310) + { + --level; + } + if (level == ESSL3_BUILTINS && shaderVersion < 300) + { + --level; + } + if (level == ESSL1_BUILTINS && shaderVersion != 100) + { + --level; + } + + if (table[level]->hasUnmangledBuiltIn(name)) + { + return true; + } + } + return false; +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/SymbolTable.h b/src/3rdparty/angle/src/compiler/translator/SymbolTable.h index 2706149e3c..5d792ec188 100644 --- a/src/3rdparty/angle/src/compiler/translator/SymbolTable.h +++ b/src/3rdparty/angle/src/compiler/translator/SymbolTable.h @@ -18,7 +18,7 @@ // so that symbol table lookups are never ambiguous. This allows // a simpler symbol table structure. // -// * Pushing and popping of scope, so symbol table will really be a stack +// * Pushing and popping of scope, so symbol table will really be a stack // of symbol tables. Searched from the top, with new inserts going into // the top. // @@ -30,111 +30,78 @@ // are tracked in the intermediate representation, not the symbol table. // +#include #include #include #include "common/angleutils.h" +#include "compiler/translator/ExtensionBehavior.h" #include "compiler/translator/InfoSink.h" #include "compiler/translator/IntermNode.h" +#include "compiler/translator/SymbolUniqueId.h" + +namespace sh +{ // Symbol base class. (Can build functions or variables out of these...) class TSymbol : angle::NonCopyable { public: POOL_ALLOCATOR_NEW_DELETE(); - TSymbol(const TString *n) - : uniqueId(0), - name(n) - { - } + TSymbol(TSymbolTable *symbolTable, const TString *n); + virtual ~TSymbol() { // don't delete name, it's from the pool } - const TString &getName() const - { - return *name; - } - virtual const TString &getMangledName() const - { - return getName(); - } - virtual bool isFunction() const - { - return false; - } - virtual bool isVariable() const - { - return false; - } - void setUniqueId(int id) - { - uniqueId = id; - } - int getUniqueId() const - { - return uniqueId; - } - void relateToExtension(const TString &ext) - { - extension = ext; - } - const TString &getExtension() const - { - return extension; - } + const TString &getName() const { return *name; } + virtual const TString &getMangledName() const { return getName(); } + virtual bool isFunction() const { return false; } + virtual bool isVariable() const { return false; } + const TSymbolUniqueId &getUniqueId() const { return uniqueId; } + void relateToExtension(TExtension ext) { extension = ext; } + TExtension getExtension() const { return extension; } private: - int uniqueId; // For real comparing during code generation + const TSymbolUniqueId uniqueId; const TString *name; - TString extension; + TExtension extension; }; -// Variable class, meaning a symbol that's not a function. -// -// There could be a separate class heirarchy for Constant variables; -// Only one of int, bool, or float, (or none) is correct for -// any particular use, but it's easy to do this way, and doesn't -// seem worth having separate classes, and "getConst" can't simply return -// different values for different types polymorphically, so this is -// just simple and pragmatic. +// Variable, meaning a symbol that's not a function. +// +// May store the value of a constant variable of any type (float, int, bool or struct). class TVariable : public TSymbol { public: - TVariable(const TString *name, const TType &t, bool uT = false) - : TSymbol(name), - type(t), - userType(uT), - unionArray(0) - { - } ~TVariable() override {} bool isVariable() const override { return true; } - TType &getType() - { - return type; - } - const TType &getType() const - { - return type; - } - bool isUserType() const - { - return userType; - } - void setQualifier(TQualifier qualifier) - { - type.setQualifier(qualifier); - } + TType &getType() { return type; } + const TType &getType() const { return type; } + bool isUserType() const { return userType; } + void setQualifier(TQualifier qualifier) { type.setQualifier(qualifier); } const TConstantUnion *getConstPointer() const { return unionArray; } void shareConstPointer(const TConstantUnion *constArray) { unionArray = constArray; } private: + friend class TSymbolTable; + + TVariable(TSymbolTable *symbolTable, + const TString *name, + const TType &t, + bool isUserTypeDefinition = false) + : TSymbol(symbolTable, name), type(t), userType(isUserTypeDefinition), unionArray(0) + { + } + TType type; + + // Set to true if this represents a struct type, as opposed to a variable. bool userType; + // we are assuming that Pool Allocator will free the memory // allocated to unionArray when this object is destroyed. const TConstantUnion *unionArray; @@ -143,34 +110,18 @@ class TVariable : public TSymbol // Immutable version of TParameter. struct TConstParameter { - TConstParameter() - : name(nullptr), - type(nullptr) - { - } - explicit TConstParameter(const TString *n) - : name(n), - type(nullptr) - { - } - explicit TConstParameter(const TType *t) - : name(nullptr), - type(t) - { - } - TConstParameter(const TString *n, const TType *t) - : name(n), - type(t) - { - } + TConstParameter() : name(nullptr), type(nullptr) {} + explicit TConstParameter(const TString *n) : name(n), type(nullptr) {} + explicit TConstParameter(const TType *t) : name(nullptr), type(t) {} + TConstParameter(const TString *n, const TType *t) : name(n), type(t) {} // Both constructor arguments must be const. - TConstParameter(TString *n, TType *t) = delete; + TConstParameter(TString *n, TType *t) = delete; TConstParameter(const TString *n, TType *t) = delete; TConstParameter(TString *n, const TType *t) = delete; - const TString *name; - const TType *type; + const TString *const name; + const TType *const type; }; // The function sub-class of symbols and the parser will need to @@ -183,25 +134,26 @@ struct TParameter TConstParameter turnToConst() { const TString *constName = name; - const TType *constType = type; - name = nullptr; - type = nullptr; + const TType *constType = type; + name = nullptr; + type = nullptr; return TConstParameter(constName, constType); } - TString *name; + const TString *name; TType *type; }; -// The function sub-class of a symbol. +// The function sub-class of a symbol. class TFunction : public TSymbol { public: - TFunction(const TString *name, + TFunction(TSymbolTable *symbolTable, + const TString *name, const TType *retType, - TOperator tOp = EOpNull, - const char *ext = "") - : TSymbol(name), + TOperator tOp = EOpNull, + TExtension ext = TExtension::UNDEFINED) + : TSymbol(symbolTable, name), returnType(retType), mangledName(nullptr), op(tOp), @@ -213,21 +165,14 @@ class TFunction : public TSymbol ~TFunction() override; bool isFunction() const override { return true; } - static TString mangleName(const TString &name) - { - return name + '('; - } - static TString unmangleName(const TString &mangledName) - { - return TString(mangledName.c_str(), mangledName.find_first_of('(')); - } - void addParameter(const TConstParameter &p) { parameters.push_back(p); mangledName = nullptr; } + void swapParameters(const TFunction ¶metersSource); + const TString &getMangledName() const override { if (mangledName == nullptr) @@ -236,31 +181,25 @@ class TFunction : public TSymbol } return *mangledName; } - const TType &getReturnType() const - { - return *returnType; - } - TOperator getBuiltInOp() const - { - return op; - } + static const TString &GetMangledNameFromCall(const TString &functionName, + const TIntermSequence &arguments); + + const TType &getReturnType() const { return *returnType; } + + TOperator getBuiltInOp() const { return op; } void setDefined() { defined = true; } bool isDefined() { return defined; } void setHasPrototypeDeclaration() { mHasPrototypeDeclaration = true; } bool hasPrototypeDeclaration() const { return mHasPrototypeDeclaration; } - size_t getParamCount() const - { - return parameters.size(); - } - const TConstParameter &getParam(size_t i) const - { - return parameters[i]; - } + size_t getParamCount() const { return parameters.size(); } + const TConstParameter &getParam(size_t i) const { return parameters[i]; } private: + void clearParameters(); + const TString *buildMangledName() const; typedef TVector TParamList; @@ -276,12 +215,11 @@ class TFunction : public TSymbol class TInterfaceBlockName : public TSymbol { public: - TInterfaceBlockName(const TString *name) - : TSymbol(name) - { - } + virtual ~TInterfaceBlockName() {} - virtual ~TInterfaceBlockName() + private: + friend class TSymbolTable; + TInterfaceBlockName(TSymbolTable *symbolTable, const TString *name) : TSymbol(symbolTable, name) { } }; @@ -289,14 +227,12 @@ class TInterfaceBlockName : public TSymbol class TSymbolTableLevel { public: - typedef TMap tLevel; + typedef TUnorderedMap tLevel; typedef tLevel::const_iterator const_iterator; typedef const tLevel::value_type tLevelPair; typedef std::pair tInsertResult; - TSymbolTableLevel() - { - } + TSymbolTableLevel() : mGlobalInvariant(false) {} ~TSymbolTableLevel(); bool insert(TSymbol *symbol); @@ -306,25 +242,52 @@ class TSymbolTableLevel TSymbol *find(const TString &name) const; + void addInvariantVarying(const std::string &name) { mInvariantVaryings.insert(name); } + + bool isVaryingInvariant(const std::string &name) + { + return (mGlobalInvariant || mInvariantVaryings.count(name) > 0); + } + + void setGlobalInvariant(bool invariant) { mGlobalInvariant = invariant; } + + void insertUnmangledBuiltInName(const std::string &name) + { + mUnmangledBuiltInNames.insert(name); + } + + bool hasUnmangledBuiltIn(const std::string &name) + { + return mUnmangledBuiltInNames.count(name) > 0; + } + protected: tLevel level; + std::set mInvariantVaryings; + bool mGlobalInvariant; + + private: + std::set mUnmangledBuiltInNames; }; // Define ESymbolLevel as int rather than an enum since level can go // above GLOBAL_LEVEL and cause atBuiltInLevel() to fail if the // compiler optimizes the >= of the last element to ==. typedef int ESymbolLevel; -const int COMMON_BUILTINS = 0; -const int ESSL1_BUILTINS = 1; -const int ESSL3_BUILTINS = 2; -const int LAST_BUILTIN_LEVEL = ESSL3_BUILTINS; -const int GLOBAL_LEVEL = 3; +const int COMMON_BUILTINS = 0; +const int ESSL1_BUILTINS = 1; +const int ESSL3_BUILTINS = 2; +const int ESSL3_1_BUILTINS = 3; +// GLSL_BUILTINS are desktop GLSL builtins that don't exist in ESSL but are used to implement +// features in ANGLE's GLSL backend. They're not visible to the parser. +const int GLSL_BUILTINS = 4; +const int LAST_BUILTIN_LEVEL = GLSL_BUILTINS; +const int GLOBAL_LEVEL = 5; class TSymbolTable : angle::NonCopyable { public: - TSymbolTable() - : mGlobalInvariant(false) + TSymbolTable() : mUniqueIdCounter(0), mEmptySymbolId(this) { // The symbol table cannot be used until push() is called, but // the lack of an initial call to push() can be used to detect @@ -336,18 +299,9 @@ class TSymbolTable : angle::NonCopyable // When the symbol table is initialized with the built-ins, there should // 'push' calls, so that built-ins are at level 0 and the shader // globals are at level 1. - bool isEmpty() const - { - return table.empty(); - } - bool atBuiltInLevel() const - { - return currentLevel() <= LAST_BUILTIN_LEVEL; - } - bool atGlobalLevel() const - { - return currentLevel() <= GLOBAL_LEVEL; - } + bool isEmpty() const { return table.empty(); } + bool atBuiltInLevel() const { return currentLevel() <= LAST_BUILTIN_LEVEL; } + bool atGlobalLevel() const { return currentLevel() == GLOBAL_LEVEL; } void push() { table.push_back(new TSymbolTableLevel); @@ -363,87 +317,159 @@ class TSymbolTable : angle::NonCopyable precisionStack.pop_back(); } - bool declare(TSymbol *symbol) - { - return insert(currentLevel(), symbol); - } + // The declare* entry points are used when parsing and declare symbols at the current scope. + // They return the created symbol in case the declaration was successful, and nullptr if the + // declaration failed due to redefinition. + TVariable *declareVariable(const TString *name, const TType &type); + TVariable *declareStructType(TStructure *str); + TInterfaceBlockName *declareInterfaceBlockName(const TString *name); - bool insert(ESymbolLevel level, TSymbol *symbol) - { - return table[level]->insert(symbol); - } + // The insert* entry points are used when initializing the symbol table with built-ins. + // They return the created symbol in case the declaration was successful, and nullptr if the + // declaration failed due to redefinition. + TVariable *insertVariable(ESymbolLevel level, const char *name, const TType &type); + TVariable *insertVariableExt(ESymbolLevel level, + TExtension ext, + const char *name, + const TType &type); + TVariable *insertStructType(ESymbolLevel level, TStructure *str); + TInterfaceBlockName *insertInterfaceBlockNameExt(ESymbolLevel level, + TExtension ext, + const TString *name); - bool insert(ESymbolLevel level, const char *ext, TSymbol *symbol) + bool insertConstInt(ESymbolLevel level, const char *name, int value, TPrecision precision) { - symbol->relateToExtension(ext); - return table[level]->insert(symbol); - } - - bool insertConstInt(ESymbolLevel level, const char *name, int value) - { - TVariable *constant = new TVariable( - NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConst, 1)); + TVariable *constant = + new TVariable(this, NewPoolTString(name), TType(EbtInt, precision, EvqConst, 1)); TConstantUnion *unionArray = new TConstantUnion[1]; unionArray[0].setIConst(value); constant->shareConstPointer(unionArray); return insert(level, constant); } - bool insertConstIntExt(ESymbolLevel level, const char *ext, const char *name, int value) + bool insertConstIntExt(ESymbolLevel level, + TExtension ext, + const char *name, + int value, + TPrecision precision) { TVariable *constant = - new TVariable(NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConst, 1)); + new TVariable(this, NewPoolTString(name), TType(EbtInt, precision, EvqConst, 1)); TConstantUnion *unionArray = new TConstantUnion[1]; unionArray[0].setIConst(value); constant->shareConstPointer(unionArray); return insert(level, ext, constant); } - void insertBuiltIn(ESymbolLevel level, TOperator op, const char *ext, const TType *rvalue, const char *name, - const TType *ptype1, const TType *ptype2 = 0, const TType *ptype3 = 0, const TType *ptype4 = 0, const TType *ptype5 = 0); - - void insertBuiltIn(ESymbolLevel level, const TType *rvalue, const char *name, - const TType *ptype1, const TType *ptype2 = 0, const TType *ptype3 = 0, const TType *ptype4 = 0, const TType *ptype5 = 0) + bool insertConstIvec3(ESymbolLevel level, + const char *name, + const std::array &values, + TPrecision precision) { - insertBuiltIn(level, EOpNull, "", rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5); + TVariable *constantIvec3 = + new TVariable(this, NewPoolTString(name), TType(EbtInt, precision, EvqConst, 3)); + + TConstantUnion *unionArray = new TConstantUnion[3]; + for (size_t index = 0u; index < 3u; ++index) + { + unionArray[index].setIConst(values[index]); + } + constantIvec3->shareConstPointer(unionArray); + + return insert(level, constantIvec3); } - void insertBuiltIn(ESymbolLevel level, const char *ext, const TType *rvalue, const char *name, - const TType *ptype1, const TType *ptype2 = 0, const TType *ptype3 = 0, const TType *ptype4 = 0, const TType *ptype5 = 0) + void insertBuiltIn(ESymbolLevel level, + TOperator op, + TExtension ext, + const TType *rvalue, + const char *name, + const TType *ptype1, + const TType *ptype2 = 0, + const TType *ptype3 = 0, + const TType *ptype4 = 0, + const TType *ptype5 = 0); + + void insertBuiltIn(ESymbolLevel level, + const TType *rvalue, + const char *name, + const TType *ptype1, + const TType *ptype2 = 0, + const TType *ptype3 = 0, + const TType *ptype4 = 0, + const TType *ptype5 = 0) { + insertUnmangledBuiltInName(name, level); + insertBuiltIn(level, EOpNull, TExtension::UNDEFINED, rvalue, name, ptype1, ptype2, ptype3, + ptype4, ptype5); + } + + void insertBuiltIn(ESymbolLevel level, + TExtension ext, + const TType *rvalue, + const char *name, + const TType *ptype1, + const TType *ptype2 = 0, + const TType *ptype3 = 0, + const TType *ptype4 = 0, + const TType *ptype5 = 0) + { + insertUnmangledBuiltInName(name, level); insertBuiltIn(level, EOpNull, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5); } - void insertBuiltIn(ESymbolLevel level, TOperator op, const TType *rvalue, const char *name, - const TType *ptype1, const TType *ptype2 = 0, const TType *ptype3 = 0, const TType *ptype4 = 0, const TType *ptype5 = 0) - { - insertBuiltIn(level, op, "", rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5); - } + void insertBuiltInOp(ESymbolLevel level, + TOperator op, + const TType *rvalue, + const TType *ptype1, + const TType *ptype2 = 0, + const TType *ptype3 = 0, + const TType *ptype4 = 0, + const TType *ptype5 = 0); + + void insertBuiltInOp(ESymbolLevel level, + TOperator op, + TExtension ext, + const TType *rvalue, + const TType *ptype1, + const TType *ptype2 = 0, + const TType *ptype3 = 0, + const TType *ptype4 = 0, + const TType *ptype5 = 0); + + void insertBuiltInFunctionNoParameters(ESymbolLevel level, + TOperator op, + const TType *rvalue, + const char *name); + + void insertBuiltInFunctionNoParametersExt(ESymbolLevel level, + TExtension ext, + TOperator op, + const TType *rvalue, + const char *name); + + TSymbol *find(const TString &name, + int shaderVersion, + bool *builtIn = nullptr, + bool *sameScope = nullptr) const; + + TSymbol *findGlobal(const TString &name) const; - TSymbol *find(const TString &name, int shaderVersion, - bool *builtIn = NULL, bool *sameScope = NULL) const; TSymbol *findBuiltIn(const TString &name, int shaderVersion) const; - + + TSymbol *findBuiltIn(const TString &name, int shaderVersion, bool includeGLSLBuiltins) const; + TSymbolTableLevel *getOuterLevel() { assert(currentLevel() >= 1); return table[currentLevel() - 1]; } - void dump(TInfoSink &infoSink) const; - - bool setDefaultPrecision(const TPublicType &type, TPrecision prec) + void setDefaultPrecision(TBasicType type, TPrecision prec) { - if (!SupportsPrecision(type.type)) - return false; - if (type.type == EbtUInt) - return false; // ESSL 3.00.4 section 4.5.4 - if (type.isAggregate()) - return false; // Not allowed to set for aggregate types int indexOfLastElement = static_cast(precisionStack.size()) - 1; // Uses map operator [], overwrites the current value - (*precisionStack[indexOfLastElement])[type.type] = prec; - return true; + (*precisionStack[indexOfLastElement])[type] = prec; } // Searches down the precisionStack for a precision qualifier @@ -454,7 +480,8 @@ class TSymbolTable : angle::NonCopyable // "invariant varying_name;". void addInvariantVarying(const std::string &originalName) { - mInvariantVaryings.insert(originalName); + ASSERT(atGlobalLevel()); + table[currentLevel()]->addInvariantVarying(originalName); } // If this returns false, the varying could still be invariant // if it is set as invariant during the varying variable @@ -462,32 +489,57 @@ class TSymbolTable : angle::NonCopyable // variable's type, not here. bool isVaryingInvariant(const std::string &originalName) const { - return (mGlobalInvariant || - mInvariantVaryings.count(originalName) > 0); + ASSERT(atGlobalLevel()); + return table[currentLevel()]->isVaryingInvariant(originalName); } - void setGlobalInvariant() { mGlobalInvariant = true; } - bool getGlobalInvariant() const { return mGlobalInvariant; } - - static int nextUniqueId() + void setGlobalInvariant(bool invariant) { - return ++uniqueIdCounter; + ASSERT(atGlobalLevel()); + table[currentLevel()]->setGlobalInvariant(invariant); } + const TSymbolUniqueId nextUniqueId() { return TSymbolUniqueId(this); } + + // The empty symbol id is shared between all empty string ("") symbols. They are used in the + // AST for unused function parameters and struct type declarations that don't declare a + // variable, for example. + const TSymbolUniqueId &getEmptySymbolId() { return mEmptySymbolId; } + + // Checks whether there is a built-in accessible by a shader with the specified version. + bool hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion); + private: - ESymbolLevel currentLevel() const + friend class TSymbolUniqueId; + int nextUniqueIdValue() { return ++mUniqueIdCounter; } + + ESymbolLevel currentLevel() const { return static_cast(table.size() - 1); } + + TVariable *insertVariable(ESymbolLevel level, const TString *name, const TType &type); + + bool insert(ESymbolLevel level, TSymbol *symbol) { return table[level]->insert(symbol); } + + bool insert(ESymbolLevel level, TExtension ext, TSymbol *symbol) { - return static_cast(table.size() - 1); + symbol->relateToExtension(ext); + return table[level]->insert(symbol); } + // Used to insert unmangled functions to check redeclaration of built-ins in ESSL 3.00 and + // above. + void insertUnmangledBuiltInName(const char *name, ESymbolLevel level); + + bool hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level); + std::vector table; typedef TMap PrecisionStackLevel; - std::vector< PrecisionStackLevel *> precisionStack; + std::vector precisionStack; - std::set mInvariantVaryings; - bool mGlobalInvariant; + int mUniqueIdCounter; - static int uniqueIdCounter; + const TSymbolUniqueId mEmptySymbolId; }; -#endif // COMPILER_TRANSLATOR_SYMBOLTABLE_H_ +} // namespace sh + +#endif // COMPILER_TRANSLATOR_SYMBOLTABLE_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/SymbolUniqueId.cpp b/src/3rdparty/angle/src/compiler/translator/SymbolUniqueId.cpp new file mode 100644 index 0000000000..2a68ae3e70 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/SymbolUniqueId.cpp @@ -0,0 +1,28 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// SymbolUniqueId.cpp: Encapsulates a unique id for a symbol. + +#include "compiler/translator/SymbolUniqueId.h" + +#include "compiler/translator/SymbolTable.h" + +namespace sh +{ + +TSymbolUniqueId::TSymbolUniqueId(TSymbolTable *symbolTable) : mId(symbolTable->nextUniqueIdValue()) +{ +} + +TSymbolUniqueId::TSymbolUniqueId(const TSymbol &symbol) : mId(symbol.getUniqueId().get()) +{ +} + +int TSymbolUniqueId::get() const +{ + return mId; +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/SymbolUniqueId.h b/src/3rdparty/angle/src/compiler/translator/SymbolUniqueId.h new file mode 100644 index 0000000000..4bd5604246 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/SymbolUniqueId.h @@ -0,0 +1,36 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// SymbolUniqueId.h: Encapsulates a unique id for a symbol. + +#ifndef COMPILER_TRANSLATOR_SYMBOLUNIQUEID_H_ +#define COMPILER_TRANSLATOR_SYMBOLUNIQUEID_H_ + +#include "compiler/translator/Common.h" + +namespace sh +{ + +class TSymbolTable; +class TSymbol; + +class TSymbolUniqueId +{ + public: + POOL_ALLOCATOR_NEW_DELETE(); + explicit TSymbolUniqueId(TSymbolTable *symbolTable); + explicit TSymbolUniqueId(const TSymbol &symbol); + TSymbolUniqueId(const TSymbolUniqueId &) = default; + TSymbolUniqueId &operator=(const TSymbolUniqueId &) = default; + + int get() const; + + private: + int mId; +}; + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_SYMBOLUNIQUEID_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/TextureFunctionHLSL.cpp b/src/3rdparty/angle/src/compiler/translator/TextureFunctionHLSL.cpp new file mode 100644 index 0000000000..d2b65a6c56 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/TextureFunctionHLSL.cpp @@ -0,0 +1,1322 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// TextureFunctionHLSL: Class for writing implementations of ESSL texture functions into HLSL +// output. Some of the implementations are straightforward and just call the HLSL equivalent of the +// ESSL texture function, others do more work to emulate ESSL texture sampling or size query +// behavior. +// + +#include "compiler/translator/TextureFunctionHLSL.h" + +#include "compiler/translator/UtilsHLSL.h" + +namespace sh +{ + +namespace +{ + +void OutputIntTexCoordWrap(TInfoSinkBase &out, + const char *wrapMode, + const char *size, + const TString &texCoord, + const TString &texCoordOffset, + const char *texCoordOutName) +{ + // GLES 3.0.4 table 3.22 specifies how the wrap modes work. We don't use the formulas verbatim + // but rather use equivalent formulas that map better to HLSL. + out << "int " << texCoordOutName << ";\n"; + out << "float " << texCoordOutName << "Offset = " << texCoord << " + float(" << texCoordOffset + << ") / " << size << ";\n"; + + // CLAMP_TO_EDGE + out << "if (" << wrapMode << " == 1)\n"; + out << "{\n"; + out << " " << texCoordOutName << " = clamp(int(floor(" << size << " * " << texCoordOutName + << "Offset)), 0, int(" << size << ") - 1);\n"; + out << "}\n"; + + // MIRRORED_REPEAT + out << "else if (" << wrapMode << " == 3)\n"; + out << "{\n"; + out << " float coordWrapped = 1.0 - abs(frac(abs(" << texCoordOutName + << "Offset) * 0.5) * 2.0 - 1.0);\n"; + out << " " << texCoordOutName << " = int(floor(" << size << " * coordWrapped));\n"; + out << "}\n"; + + // REPEAT + out << "else\n"; + out << "{\n"; + out << " " << texCoordOutName << " = int(floor(" << size << " * frac(" << texCoordOutName + << "Offset)));\n"; + out << "}\n"; +} + +void OutputIntTexCoordWraps(TInfoSinkBase &out, + const TextureFunctionHLSL::TextureFunction &textureFunction, + TString *texCoordX, + TString *texCoordY, + TString *texCoordZ) +{ + // Convert from normalized floating-point to integer + out << "int wrapS = samplerMetadata[samplerIndex].wrapModes & 0x3;\n"; + if (textureFunction.offset) + { + OutputIntTexCoordWrap(out, "wrapS", "width", *texCoordX, "offset.x", "tix"); + } + else + { + OutputIntTexCoordWrap(out, "wrapS", "width", *texCoordX, "0", "tix"); + } + *texCoordX = "tix"; + out << "int wrapT = (samplerMetadata[samplerIndex].wrapModes >> 2) & 0x3;\n"; + if (textureFunction.offset) + { + OutputIntTexCoordWrap(out, "wrapT", "height", *texCoordY, "offset.y", "tiy"); + } + else + { + OutputIntTexCoordWrap(out, "wrapT", "height", *texCoordY, "0", "tiy"); + } + *texCoordY = "tiy"; + + if (IsSamplerArray(textureFunction.sampler)) + { + *texCoordZ = "int(max(0, min(layers - 1, floor(0.5 + t.z))))"; + } + else if (!IsSamplerCube(textureFunction.sampler) && !IsSampler2D(textureFunction.sampler)) + { + out << "int wrapR = (samplerMetadata[samplerIndex].wrapModes >> 4) & 0x3;\n"; + if (textureFunction.offset) + { + OutputIntTexCoordWrap(out, "wrapR", "depth", *texCoordZ, "offset.z", "tiz"); + } + else + { + OutputIntTexCoordWrap(out, "wrapR", "depth", *texCoordZ, "0", "tiz"); + } + *texCoordZ = "tiz"; + } +} + +void OutputHLSL4SampleFunctionPrefix(TInfoSinkBase &out, + const TextureFunctionHLSL::TextureFunction &textureFunction, + const TString &textureReference, + const TString &samplerReference) +{ + out << textureReference; + if (IsIntegerSampler(textureFunction.sampler) || + textureFunction.method == TextureFunctionHLSL::TextureFunction::FETCH) + { + out << ".Load("; + return; + } + + if (IsShadowSampler(textureFunction.sampler)) + { + switch (textureFunction.method) + { + case TextureFunctionHLSL::TextureFunction::IMPLICIT: + case TextureFunctionHLSL::TextureFunction::BIAS: + case TextureFunctionHLSL::TextureFunction::LOD: + out << ".SampleCmp("; + break; + case TextureFunctionHLSL::TextureFunction::LOD0: + case TextureFunctionHLSL::TextureFunction::LOD0BIAS: + case TextureFunctionHLSL::TextureFunction::GRAD: + out << ".SampleCmpLevelZero("; + break; + default: + UNREACHABLE(); + } + } + else + { + switch (textureFunction.method) + { + case TextureFunctionHLSL::TextureFunction::IMPLICIT: + out << ".Sample("; + break; + case TextureFunctionHLSL::TextureFunction::BIAS: + out << ".SampleBias("; + break; + case TextureFunctionHLSL::TextureFunction::LOD: + case TextureFunctionHLSL::TextureFunction::LOD0: + case TextureFunctionHLSL::TextureFunction::LOD0BIAS: + out << ".SampleLevel("; + break; + case TextureFunctionHLSL::TextureFunction::GRAD: + out << ".SampleGrad("; + break; + default: + UNREACHABLE(); + } + } + out << samplerReference << ", "; +} + +const char *GetSamplerCoordinateTypeString( + const TextureFunctionHLSL::TextureFunction &textureFunction, + int hlslCoords) +{ + if (IsIntegerSampler(textureFunction.sampler) || + textureFunction.method == TextureFunctionHLSL::TextureFunction::FETCH) + { + switch (hlslCoords) + { + case 2: + if (textureFunction.sampler == EbtSampler2DMS || + textureFunction.sampler == EbtISampler2DMS || + textureFunction.sampler == EbtUSampler2DMS) + return "int2"; + else + return "int3"; + case 3: + return "int4"; + default: + UNREACHABLE(); + } + } + else + { + switch (hlslCoords) + { + case 2: + return "float2"; + case 3: + return "float3"; + case 4: + return "float4"; + default: + UNREACHABLE(); + } + } + return ""; +} + +int GetHLSLCoordCount(const TextureFunctionHLSL::TextureFunction &textureFunction, + ShShaderOutput outputType) +{ + if (outputType == SH_HLSL_3_0_OUTPUT) + { + int hlslCoords = 2; + switch (textureFunction.sampler) + { + case EbtSampler2D: + case EbtSamplerExternalOES: + case EbtSampler2DMS: + hlslCoords = 2; + break; + case EbtSamplerCube: + hlslCoords = 3; + break; + default: + UNREACHABLE(); + } + + switch (textureFunction.method) + { + case TextureFunctionHLSL::TextureFunction::IMPLICIT: + case TextureFunctionHLSL::TextureFunction::GRAD: + return hlslCoords; + case TextureFunctionHLSL::TextureFunction::BIAS: + case TextureFunctionHLSL::TextureFunction::LOD: + case TextureFunctionHLSL::TextureFunction::LOD0: + case TextureFunctionHLSL::TextureFunction::LOD0BIAS: + return 4; + default: + UNREACHABLE(); + } + } + else + { + switch (textureFunction.sampler) + { + case EbtSampler2D: + return 2; + case EbtSampler2DMS: + return 2; + case EbtSampler3D: + return 3; + case EbtSamplerCube: + return 3; + case EbtSampler2DArray: + return 3; + case EbtSamplerExternalOES: + return 2; + case EbtISampler2D: + return 2; + case EbtISampler2DMS: + return 2; + case EbtISampler3D: + return 3; + case EbtISamplerCube: + return 3; + case EbtISampler2DArray: + return 3; + case EbtUSampler2D: + return 2; + case EbtUSampler2DMS: + return 2; + case EbtUSampler3D: + return 3; + case EbtUSamplerCube: + return 3; + case EbtUSampler2DArray: + return 3; + case EbtSampler2DShadow: + return 2; + case EbtSamplerCubeShadow: + return 3; + case EbtSampler2DArrayShadow: + return 3; + default: + UNREACHABLE(); + } + } + return 0; +} + +void OutputTextureFunctionArgumentList(TInfoSinkBase &out, + const TextureFunctionHLSL::TextureFunction &textureFunction, + const ShShaderOutput outputType) +{ + if (outputType == SH_HLSL_3_0_OUTPUT) + { + switch (textureFunction.sampler) + { + case EbtSampler2D: + case EbtSamplerExternalOES: + out << "sampler2D s"; + break; + case EbtSamplerCube: + out << "samplerCUBE s"; + break; + default: + UNREACHABLE(); + } + } + else + { + if (outputType == SH_HLSL_4_0_FL9_3_OUTPUT) + { + out << TextureString(textureFunction.sampler) << " x, " + << SamplerString(textureFunction.sampler) << " s"; + } + else + { + ASSERT(outputType == SH_HLSL_4_1_OUTPUT); + // A bug in the D3D compiler causes some nested sampling operations to fail. + // See http://anglebug.com/1923 + // TODO(jmadill): Reinstate the const keyword when possible. + out << /*"const"*/ "uint samplerIndex"; + } + } + + if (textureFunction.method == + TextureFunctionHLSL::TextureFunction::FETCH) // Integer coordinates + { + switch (textureFunction.coords) + { + case 2: + out << ", int2 t"; + break; + case 3: + out << ", int3 t"; + break; + default: + UNREACHABLE(); + } + } + else // Floating-point coordinates (except textureSize) + { + switch (textureFunction.coords) + { + case 0: + break; // textureSize(gSampler2DMS sampler) + case 1: + out << ", int lod"; + break; // textureSize() + case 2: + out << ", float2 t"; + break; + case 3: + out << ", float3 t"; + break; + case 4: + out << ", float4 t"; + break; + default: + UNREACHABLE(); + } + } + + if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD) + { + switch (textureFunction.sampler) + { + case EbtSampler2D: + case EbtISampler2D: + case EbtUSampler2D: + case EbtSampler2DArray: + case EbtISampler2DArray: + case EbtUSampler2DArray: + case EbtSampler2DShadow: + case EbtSampler2DArrayShadow: + case EbtSamplerExternalOES: + out << ", float2 ddx, float2 ddy"; + break; + case EbtSampler3D: + case EbtISampler3D: + case EbtUSampler3D: + case EbtSamplerCube: + case EbtISamplerCube: + case EbtUSamplerCube: + case EbtSamplerCubeShadow: + out << ", float3 ddx, float3 ddy"; + break; + default: + UNREACHABLE(); + } + } + + switch (textureFunction.method) + { + case TextureFunctionHLSL::TextureFunction::IMPLICIT: + break; + case TextureFunctionHLSL::TextureFunction::BIAS: + break; // Comes after the offset parameter + case TextureFunctionHLSL::TextureFunction::LOD: + out << ", float lod"; + break; + case TextureFunctionHLSL::TextureFunction::LOD0: + break; + case TextureFunctionHLSL::TextureFunction::LOD0BIAS: + break; // Comes after the offset parameter + case TextureFunctionHLSL::TextureFunction::SIZE: + break; + case TextureFunctionHLSL::TextureFunction::FETCH: + if (textureFunction.sampler == EbtSampler2DMS || + textureFunction.sampler == EbtISampler2DMS || + textureFunction.sampler == EbtUSampler2DMS) + out << ", int index"; + else + out << ", int mip"; + break; + case TextureFunctionHLSL::TextureFunction::GRAD: + break; + default: + UNREACHABLE(); + } + + if (textureFunction.offset) + { + switch (textureFunction.sampler) + { + case EbtSampler3D: + case EbtISampler3D: + case EbtUSampler3D: + out << ", int3 offset"; + break; + case EbtSampler2D: + case EbtSampler2DArray: + case EbtISampler2D: + case EbtISampler2DArray: + case EbtUSampler2D: + case EbtUSampler2DArray: + case EbtSampler2DShadow: + case EbtSampler2DArrayShadow: + case EbtSampler2DMS: + case EbtISampler2DMS: + case EbtUSampler2DMS: + case EbtSamplerExternalOES: + out << ", int2 offset"; + break; + default: + UNREACHABLE(); + } + } + + if (textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS || + textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0BIAS) + { + out << ", float bias"; + } +} + +void GetTextureReference(TInfoSinkBase &out, + const TextureFunctionHLSL::TextureFunction &textureFunction, + const ShShaderOutput outputType, + TString *textureReference, + TString *samplerReference) +{ + if (outputType == SH_HLSL_4_1_OUTPUT) + { + TString suffix = TextureGroupSuffix(textureFunction.sampler); + if (TextureGroup(textureFunction.sampler) == HLSL_TEXTURE_2D) + { + *textureReference = TString("textures") + suffix + "[samplerIndex]"; + *samplerReference = TString("samplers") + suffix + "[samplerIndex]"; + } + else + { + out << " const uint textureIndex = samplerIndex - textureIndexOffset" << suffix + << ";\n"; + *textureReference = TString("textures") + suffix + "[textureIndex]"; + out << " const uint samplerArrayIndex = samplerIndex - samplerIndexOffset" << suffix + << ";\n"; + *samplerReference = TString("samplers") + suffix + "[samplerArrayIndex]"; + } + } + else + { + *textureReference = "x"; + *samplerReference = "s"; + } +} + +void OutputTextureSizeFunctionBody(TInfoSinkBase &out, + const TextureFunctionHLSL::TextureFunction &textureFunction, + const TString &textureReference, + bool getDimensionsIgnoresBaseLevel) +{ + if (IsSampler2DMS(textureFunction.sampler)) + { + out << " uint width; uint height; uint samples;\n" + << " " << textureReference << ".GetDimensions(width, height, samples);\n"; + } + else + { + if (getDimensionsIgnoresBaseLevel) + { + out << " int baseLevel = samplerMetadata[samplerIndex].baseLevel;\n"; + } + else + { + out << " int baseLevel = 0;\n"; + } + + if (IsSampler3D(textureFunction.sampler) || IsSamplerArray(textureFunction.sampler) || + (IsIntegerSampler(textureFunction.sampler) && IsSamplerCube(textureFunction.sampler))) + { + // "depth" stores either the number of layers in an array texture or 3D depth + out << " uint width; uint height; uint depth; uint numberOfLevels;\n" + << " " << textureReference + << ".GetDimensions(baseLevel, width, height, depth, numberOfLevels);\n" + << " width = max(width >> lod, 1);\n" + << " height = max(height >> lod, 1);\n"; + + if (!IsSamplerArray(textureFunction.sampler)) + { + out << " depth = max(depth >> lod, 1);\n"; + } + } + else if (IsSampler2D(textureFunction.sampler) || IsSamplerCube(textureFunction.sampler)) + { + out << " uint width; uint height; uint numberOfLevels;\n" + << " " << textureReference + << ".GetDimensions(baseLevel, width, height, numberOfLevels);\n" + << " width = max(width >> lod, 1);\n" + << " height = max(height >> lod, 1);\n"; + } + else + UNREACHABLE(); + } + + if (strcmp(textureFunction.getReturnType(), "int3") == 0) + { + out << " return int3(width, height, depth);\n"; + } + else + { + out << " return int2(width, height);\n"; + } +} + +void ProjectTextureCoordinates(const TextureFunctionHLSL::TextureFunction &textureFunction, + TString *texCoordX, + TString *texCoordY, + TString *texCoordZ) +{ + if (textureFunction.proj) + { + TString proj(""); + switch (textureFunction.coords) + { + case 3: + proj = " / t.z"; + break; + case 4: + proj = " / t.w"; + break; + default: + UNREACHABLE(); + } + *texCoordX = "(" + *texCoordX + proj + ")"; + *texCoordY = "(" + *texCoordY + proj + ")"; + *texCoordZ = "(" + *texCoordZ + proj + ")"; + } +} + +void OutputIntegerTextureSampleFunctionComputations( + TInfoSinkBase &out, + const TextureFunctionHLSL::TextureFunction &textureFunction, + const ShShaderOutput outputType, + const TString &textureReference, + TString *texCoordX, + TString *texCoordY, + TString *texCoordZ) +{ + if (!IsIntegerSampler(textureFunction.sampler)) + { + return; + } + if (IsSamplerCube(textureFunction.sampler)) + { + out << " float width; float height; float layers; float levels;\n"; + + out << " uint mip = 0;\n"; + + out << " " << textureReference + << ".GetDimensions(mip, width, height, layers, levels);\n"; + + out << " bool xMajor = abs(t.x) > abs(t.y) && abs(t.x) > abs(t.z);\n"; + out << " bool yMajor = abs(t.y) > abs(t.z) && abs(t.y) > abs(t.x);\n"; + out << " bool zMajor = abs(t.z) > abs(t.x) && abs(t.z) > abs(t.y);\n"; + out << " bool negative = (xMajor && t.x < 0.0f) || (yMajor && t.y < 0.0f) || " + "(zMajor && t.z < 0.0f);\n"; + + // FACE_POSITIVE_X = 000b + // FACE_NEGATIVE_X = 001b + // FACE_POSITIVE_Y = 010b + // FACE_NEGATIVE_Y = 011b + // FACE_POSITIVE_Z = 100b + // FACE_NEGATIVE_Z = 101b + out << " int face = (int)negative + (int)yMajor * 2 + (int)zMajor * 4;\n"; + + out << " float u = xMajor ? -t.z : (yMajor && t.y < 0.0f ? -t.x : t.x);\n"; + out << " float v = yMajor ? t.z : (negative ? t.y : -t.y);\n"; + out << " float m = xMajor ? t.x : (yMajor ? t.y : t.z);\n"; + + out << " t.x = (u * 0.5f / m) + 0.5f;\n"; + out << " t.y = (v * 0.5f / m) + 0.5f;\n"; + + // Mip level computation. + if (textureFunction.method == TextureFunctionHLSL::TextureFunction::IMPLICIT || + textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD || + textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD) + { + if (textureFunction.method == TextureFunctionHLSL::TextureFunction::IMPLICIT) + { + out << " float2 tSized = float2(t.x * width, t.y * height);\n" + " float2 dx = ddx(tSized);\n" + " float2 dy = ddy(tSized);\n" + " float lod = 0.5f * log2(max(dot(dx, dx), dot(dy, dy)));\n"; + } + else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD) + { + // ESSL 3.00.6 spec section 8.8: "For the cube version, the partial + // derivatives of P are assumed to be in the coordinate system used before + // texture coordinates are projected onto the appropriate cube face." + // ddx[0] and ddy[0] are the derivatives of t.x passed into the function + // ddx[1] and ddy[1] are the derivatives of t.y passed into the function + // ddx[2] and ddy[2] are the derivatives of t.z passed into the function + // Determine the derivatives of u, v and m + out << " float dudx = xMajor ? ddx[2] : (yMajor && t.y < 0.0f ? -ddx[0] " + ": ddx[0]);\n" + " float dudy = xMajor ? ddy[2] : (yMajor && t.y < 0.0f ? -ddy[0] " + ": ddy[0]);\n" + " float dvdx = yMajor ? ddx[2] : (negative ? ddx[1] : -ddx[1]);\n" + " float dvdy = yMajor ? ddy[2] : (negative ? ddy[1] : -ddy[1]);\n" + " float dmdx = xMajor ? ddx[0] : (yMajor ? ddx[1] : ddx[2]);\n" + " float dmdy = xMajor ? ddy[0] : (yMajor ? ddy[1] : ddy[2]);\n"; + // Now determine the derivatives of the face coordinates, using the + // derivatives calculated above. + // d / dx (u(x) * 0.5 / m(x) + 0.5) + // = 0.5 * (m(x) * u'(x) - u(x) * m'(x)) / m(x)^2 + out << " float dfacexdx = 0.5f * (m * dudx - u * dmdx) / (m * m);\n" + " float dfaceydx = 0.5f * (m * dvdx - v * dmdx) / (m * m);\n" + " float dfacexdy = 0.5f * (m * dudy - u * dmdy) / (m * m);\n" + " float dfaceydy = 0.5f * (m * dvdy - v * dmdy) / (m * m);\n" + " float2 sizeVec = float2(width, height);\n" + " float2 faceddx = float2(dfacexdx, dfaceydx) * sizeVec;\n" + " float2 faceddy = float2(dfacexdy, dfaceydy) * sizeVec;\n"; + // Optimization: instead of: log2(max(length(faceddx), length(faceddy))) + // we compute: log2(max(length(faceddx)^2, length(faceddy)^2)) / 2 + out << " float lengthfaceddx2 = dot(faceddx, faceddx);\n" + " float lengthfaceddy2 = dot(faceddy, faceddy);\n" + " float lod = log2(max(lengthfaceddx2, lengthfaceddy2)) * 0.5f;\n"; + } + out << " mip = uint(min(max(round(lod), 0), levels - 1));\n" + << " " << textureReference + << ".GetDimensions(mip, width, height, layers, levels);\n"; + } + + // Convert from normalized floating-point to integer + *texCoordX = "int(floor(width * frac(" + *texCoordX + ")))"; + *texCoordY = "int(floor(height * frac(" + *texCoordY + ")))"; + *texCoordZ = "face"; + } + else if (textureFunction.method != TextureFunctionHLSL::TextureFunction::FETCH) + { + if (IsSampler2D(textureFunction.sampler)) + { + if (IsSamplerArray(textureFunction.sampler)) + { + out << " float width; float height; float layers; float levels;\n"; + + if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0) + { + out << " uint mip = 0;\n"; + } + else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0BIAS) + { + out << " uint mip = bias;\n"; + } + else + { + + out << " " << textureReference + << ".GetDimensions(0, width, height, layers, levels);\n"; + if (textureFunction.method == TextureFunctionHLSL::TextureFunction::IMPLICIT || + textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS) + { + out << " float2 tSized = float2(t.x * width, t.y * height);\n" + " float dx = length(ddx(tSized));\n" + " float dy = length(ddy(tSized));\n" + " float lod = log2(max(dx, dy));\n"; + + if (textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS) + { + out << " lod += bias;\n"; + } + } + else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD) + { + out << " float2 sizeVec = float2(width, height);\n" + " float2 sizeDdx = ddx * sizeVec;\n" + " float2 sizeDdy = ddy * sizeVec;\n" + " float lod = log2(max(dot(sizeDdx, sizeDdx), " + "dot(sizeDdy, sizeDdy))) * 0.5f;\n"; + } + + out << " uint mip = uint(min(max(round(lod), 0), levels - 1));\n"; + } + + out << " " << textureReference + << ".GetDimensions(mip, width, height, layers, levels);\n"; + } + else + { + out << " float width; float height; float levels;\n"; + + if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0) + { + out << " uint mip = 0;\n"; + } + else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0BIAS) + { + out << " uint mip = bias;\n"; + } + else + { + out << " " << textureReference + << ".GetDimensions(0, width, height, levels);\n"; + + if (textureFunction.method == TextureFunctionHLSL::TextureFunction::IMPLICIT || + textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS) + { + out << " float2 tSized = float2(t.x * width, t.y * height);\n" + " float dx = length(ddx(tSized));\n" + " float dy = length(ddy(tSized));\n" + " float lod = log2(max(dx, dy));\n"; + + if (textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS) + { + out << " lod += bias;\n"; + } + } + else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD) + { + out << " float2 sizeVec = float2(width, height);\n" + " float2 sizeDdx = ddx * sizeVec;\n" + " float2 sizeDdy = ddy * sizeVec;\n" + " float lod = log2(max(dot(sizeDdx, sizeDdx), " + "dot(sizeDdy, sizeDdy))) * 0.5f;\n"; + } + + out << " uint mip = uint(min(max(round(lod), 0), levels - 1));\n"; + } + + out << " " << textureReference + << ".GetDimensions(mip, width, height, levels);\n"; + } + } + else if (IsSampler3D(textureFunction.sampler)) + { + out << " float width; float height; float depth; float levels;\n"; + + if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0) + { + out << " uint mip = 0;\n"; + } + else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0BIAS) + { + out << " uint mip = bias;\n"; + } + else + { + out << " " << textureReference + << ".GetDimensions(0, width, height, depth, levels);\n"; + + if (textureFunction.method == TextureFunctionHLSL::TextureFunction::IMPLICIT || + textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS) + { + out << " float3 tSized = float3(t.x * width, t.y * height, t.z * depth);\n" + " float dx = length(ddx(tSized));\n" + " float dy = length(ddy(tSized));\n" + " float lod = log2(max(dx, dy));\n"; + + if (textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS) + { + out << " lod += bias;\n"; + } + } + else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD) + { + out << " float3 sizeVec = float3(width, height, depth);\n" + " float3 sizeDdx = ddx * sizeVec;\n" + " float3 sizeDdy = ddy * sizeVec;\n" + " float lod = log2(max(dot(sizeDdx, sizeDdx), dot(sizeDdy, " + "sizeDdy))) * 0.5f;\n"; + } + + out << " uint mip = uint(min(max(round(lod), 0), levels - 1));\n"; + } + + out << " " << textureReference + << ".GetDimensions(mip, width, height, depth, levels);\n"; + } + else + UNREACHABLE(); + + OutputIntTexCoordWraps(out, textureFunction, texCoordX, texCoordY, texCoordZ); + } +} + +void OutputTextureSampleFunctionReturnStatement( + TInfoSinkBase &out, + const TextureFunctionHLSL::TextureFunction &textureFunction, + const ShShaderOutput outputType, + const TString &textureReference, + const TString &samplerReference, + const TString &texCoordX, + const TString &texCoordY, + const TString &texCoordZ) +{ + out << " return "; + + // HLSL intrinsic + if (outputType == SH_HLSL_3_0_OUTPUT) + { + switch (textureFunction.sampler) + { + case EbtSampler2D: + case EbtSamplerExternalOES: + out << "tex2D"; + break; + case EbtSamplerCube: + out << "texCUBE"; + break; + default: + UNREACHABLE(); + } + + switch (textureFunction.method) + { + case TextureFunctionHLSL::TextureFunction::IMPLICIT: + out << "(" << samplerReference << ", "; + break; + case TextureFunctionHLSL::TextureFunction::BIAS: + out << "bias(" << samplerReference << ", "; + break; + case TextureFunctionHLSL::TextureFunction::LOD: + out << "lod(" << samplerReference << ", "; + break; + case TextureFunctionHLSL::TextureFunction::LOD0: + out << "lod(" << samplerReference << ", "; + break; + case TextureFunctionHLSL::TextureFunction::LOD0BIAS: + out << "lod(" << samplerReference << ", "; + break; + case TextureFunctionHLSL::TextureFunction::GRAD: + out << "grad(" << samplerReference << ", "; + break; + default: + UNREACHABLE(); + } + } + else if (outputType == SH_HLSL_4_1_OUTPUT || outputType == SH_HLSL_4_0_FL9_3_OUTPUT) + { + OutputHLSL4SampleFunctionPrefix(out, textureFunction, textureReference, samplerReference); + } + else + UNREACHABLE(); + + const int hlslCoords = GetHLSLCoordCount(textureFunction, outputType); + + out << GetSamplerCoordinateTypeString(textureFunction, hlslCoords) << "(" << texCoordX << ", " + << texCoordY; + + if (outputType == SH_HLSL_3_0_OUTPUT) + { + if (hlslCoords >= 3) + { + if (textureFunction.coords < 3) + { + out << ", 0"; + } + else + { + out << ", " << texCoordZ; + } + } + + if (hlslCoords == 4) + { + switch (textureFunction.method) + { + case TextureFunctionHLSL::TextureFunction::BIAS: + out << ", bias"; + break; + case TextureFunctionHLSL::TextureFunction::LOD: + out << ", lod"; + break; + case TextureFunctionHLSL::TextureFunction::LOD0: + out << ", 0"; + break; + case TextureFunctionHLSL::TextureFunction::LOD0BIAS: + out << ", bias"; + break; + default: + UNREACHABLE(); + } + } + + out << ")"; + } + else if (outputType == SH_HLSL_4_1_OUTPUT || outputType == SH_HLSL_4_0_FL9_3_OUTPUT) + { + if (hlslCoords >= 3) + { + ASSERT(!IsIntegerSampler(textureFunction.sampler) || + !IsSamplerCube(textureFunction.sampler) || texCoordZ == "face"); + out << ", " << texCoordZ; + } + + if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD) + { + if (IsIntegerSampler(textureFunction.sampler)) + { + out << ", mip)"; + } + else if (IsShadowSampler(textureFunction.sampler)) + { + // Compare value + if (textureFunction.proj) + { + // According to ESSL 3.00.4 sec 8.8 p95 on textureProj: + // The resulting third component of P' in the shadow forms is used as + // Dref + out << "), " << texCoordZ; + } + else + { + switch (textureFunction.coords) + { + case 3: + out << "), t.z"; + break; + case 4: + out << "), t.w"; + break; + default: + UNREACHABLE(); + } + } + } + else + { + out << "), ddx, ddy"; + } + } + else if (IsIntegerSampler(textureFunction.sampler) || + textureFunction.method == TextureFunctionHLSL::TextureFunction::FETCH) + { + if (textureFunction.sampler == EbtSampler2DMS || + textureFunction.sampler == EbtISampler2DMS || + textureFunction.sampler == EbtUSampler2DMS) + out << "), index"; + else + out << ", mip)"; + } + else if (IsShadowSampler(textureFunction.sampler)) + { + // Compare value + if (textureFunction.proj) + { + // According to ESSL 3.00.4 sec 8.8 p95 on textureProj: + // The resulting third component of P' in the shadow forms is used as Dref + out << "), " << texCoordZ; + } + else + { + switch (textureFunction.coords) + { + case 3: + out << "), t.z"; + break; + case 4: + out << "), t.w"; + break; + default: + UNREACHABLE(); + } + } + } + else + { + switch (textureFunction.method) + { + case TextureFunctionHLSL::TextureFunction::IMPLICIT: + out << ")"; + break; + case TextureFunctionHLSL::TextureFunction::BIAS: + out << "), bias"; + break; + case TextureFunctionHLSL::TextureFunction::LOD: + out << "), lod"; + break; + case TextureFunctionHLSL::TextureFunction::LOD0: + out << "), 0"; + break; + case TextureFunctionHLSL::TextureFunction::LOD0BIAS: + out << "), bias"; + break; + default: + UNREACHABLE(); + } + } + + if (textureFunction.offset && + (!IsIntegerSampler(textureFunction.sampler) || + textureFunction.method == TextureFunctionHLSL::TextureFunction::FETCH)) + { + out << ", offset"; + } + } + else + UNREACHABLE(); + + out << ");\n"; // Close the sample function call and return statement +} + +} // Anonymous namespace + +TString TextureFunctionHLSL::TextureFunction::name() const +{ + TString name = "gl_texture"; + + // We need to include full the sampler type in the function name to make the signature unique + // on D3D11, where samplers are passed to texture functions as indices. + name += TextureTypeSuffix(this->sampler); + + if (proj) + { + name += "Proj"; + } + + if (offset) + { + name += "Offset"; + } + + switch (method) + { + case IMPLICIT: + break; + case BIAS: + break; // Extra parameter makes the signature unique + case LOD: + name += "Lod"; + break; + case LOD0: + name += "Lod0"; + break; + case LOD0BIAS: + name += "Lod0"; + break; // Extra parameter makes the signature unique + case SIZE: + name += "Size"; + break; + case FETCH: + name += "Fetch"; + break; + case GRAD: + name += "Grad"; + break; + default: + UNREACHABLE(); + } + + return name; +} + +const char *TextureFunctionHLSL::TextureFunction::getReturnType() const +{ + if (method == TextureFunction::SIZE) + { + switch (sampler) + { + case EbtSampler2D: + case EbtISampler2D: + case EbtUSampler2D: + case EbtSampler2DShadow: + case EbtSamplerCube: + case EbtISamplerCube: + case EbtUSamplerCube: + case EbtSamplerCubeShadow: + case EbtSamplerExternalOES: + case EbtSampler2DMS: + case EbtISampler2DMS: + case EbtUSampler2DMS: + return "int2"; + case EbtSampler3D: + case EbtISampler3D: + case EbtUSampler3D: + case EbtSampler2DArray: + case EbtISampler2DArray: + case EbtUSampler2DArray: + case EbtSampler2DArrayShadow: + return "int3"; + default: + UNREACHABLE(); + } + } + else // Sampling function + { + switch (sampler) + { + case EbtSampler2D: + case EbtSampler2DMS: + case EbtSampler3D: + case EbtSamplerCube: + case EbtSampler2DArray: + case EbtSamplerExternalOES: + return "float4"; + case EbtISampler2D: + case EbtISampler2DMS: + case EbtISampler3D: + case EbtISamplerCube: + case EbtISampler2DArray: + return "int4"; + case EbtUSampler2D: + case EbtUSampler2DMS: + case EbtUSampler3D: + case EbtUSamplerCube: + case EbtUSampler2DArray: + return "uint4"; + case EbtSampler2DShadow: + case EbtSamplerCubeShadow: + case EbtSampler2DArrayShadow: + return "float"; + default: + UNREACHABLE(); + } + } + return ""; +} + +bool TextureFunctionHLSL::TextureFunction::operator<(const TextureFunction &rhs) const +{ + return std::tie(sampler, coords, proj, offset, method) < + std::tie(rhs.sampler, rhs.coords, rhs.proj, rhs.offset, rhs.method); +} + +TString TextureFunctionHLSL::useTextureFunction(const TString &name, + TBasicType samplerType, + int coords, + size_t argumentCount, + bool lod0, + sh::GLenum shaderType) +{ + TextureFunction textureFunction; + textureFunction.sampler = samplerType; + textureFunction.coords = coords; + textureFunction.method = TextureFunction::IMPLICIT; + textureFunction.proj = false; + textureFunction.offset = false; + + if (name == "texture2D" || name == "textureCube" || name == "texture") + { + textureFunction.method = TextureFunction::IMPLICIT; + } + else if (name == "texture2DProj" || name == "textureProj") + { + textureFunction.method = TextureFunction::IMPLICIT; + textureFunction.proj = true; + } + else if (name == "texture2DLod" || name == "textureCubeLod" || name == "textureLod" || + name == "texture2DLodEXT" || name == "textureCubeLodEXT") + { + textureFunction.method = TextureFunction::LOD; + } + else if (name == "texture2DProjLod" || name == "textureProjLod" || + name == "texture2DProjLodEXT") + { + textureFunction.method = TextureFunction::LOD; + textureFunction.proj = true; + } + else if (name == "textureSize") + { + textureFunction.method = TextureFunction::SIZE; + } + else if (name == "textureOffset") + { + textureFunction.method = TextureFunction::IMPLICIT; + textureFunction.offset = true; + } + else if (name == "textureProjOffset") + { + textureFunction.method = TextureFunction::IMPLICIT; + textureFunction.offset = true; + textureFunction.proj = true; + } + else if (name == "textureLodOffset") + { + textureFunction.method = TextureFunction::LOD; + textureFunction.offset = true; + } + else if (name == "textureProjLodOffset") + { + textureFunction.method = TextureFunction::LOD; + textureFunction.proj = true; + textureFunction.offset = true; + } + else if (name == "texelFetch") + { + textureFunction.method = TextureFunction::FETCH; + } + else if (name == "texelFetchOffset") + { + textureFunction.method = TextureFunction::FETCH; + textureFunction.offset = true; + } + else if (name == "textureGrad" || name == "texture2DGradEXT") + { + textureFunction.method = TextureFunction::GRAD; + } + else if (name == "textureGradOffset") + { + textureFunction.method = TextureFunction::GRAD; + textureFunction.offset = true; + } + else if (name == "textureProjGrad" || name == "texture2DProjGradEXT" || + name == "textureCubeGradEXT") + { + textureFunction.method = TextureFunction::GRAD; + textureFunction.proj = true; + } + else if (name == "textureProjGradOffset") + { + textureFunction.method = TextureFunction::GRAD; + textureFunction.proj = true; + textureFunction.offset = true; + } + else + UNREACHABLE(); + + if (textureFunction.method == + TextureFunction::IMPLICIT) // Could require lod 0 or have a bias argument + { + size_t mandatoryArgumentCount = 2; // All functions have sampler and coordinate arguments + + if (textureFunction.offset) + { + mandatoryArgumentCount++; + } + + bool bias = (argumentCount > mandatoryArgumentCount); // Bias argument is optional + + if (lod0 || shaderType == GL_VERTEX_SHADER) + { + if (bias) + { + textureFunction.method = TextureFunction::LOD0BIAS; + } + else + { + textureFunction.method = TextureFunction::LOD0; + } + } + else if (bias) + { + textureFunction.method = TextureFunction::BIAS; + } + } + + mUsesTexture.insert(textureFunction); + return textureFunction.name(); +} + +void TextureFunctionHLSL::textureFunctionHeader(TInfoSinkBase &out, + const ShShaderOutput outputType, + bool getDimensionsIgnoresBaseLevel) +{ + for (const TextureFunction &textureFunction : mUsesTexture) + { + // Function header + out << textureFunction.getReturnType() << " " << textureFunction.name() << "("; + + OutputTextureFunctionArgumentList(out, textureFunction, outputType); + + out << ")\n" + "{\n"; + + // In some cases we use a variable to store the texture/sampler objects, but to work around + // a D3D11 compiler bug related to discard inside a loop that is conditional on texture + // sampling we need to call the function directly on references to the texture and sampler + // arrays. The bug was found using dEQP-GLES3.functional.shaders.discard*loop_texture* + // tests. + TString textureReference; + TString samplerReference; + GetTextureReference(out, textureFunction, outputType, &textureReference, &samplerReference); + + if (textureFunction.method == TextureFunction::SIZE) + { + OutputTextureSizeFunctionBody(out, textureFunction, textureReference, + getDimensionsIgnoresBaseLevel); + } + else + { + TString texCoordX("t.x"); + TString texCoordY("t.y"); + TString texCoordZ("t.z"); + ProjectTextureCoordinates(textureFunction, &texCoordX, &texCoordY, &texCoordZ); + OutputIntegerTextureSampleFunctionComputations(out, textureFunction, outputType, + textureReference, &texCoordX, &texCoordY, + &texCoordZ); + OutputTextureSampleFunctionReturnStatement(out, textureFunction, outputType, + textureReference, samplerReference, + texCoordX, texCoordY, texCoordZ); + } + + out << "}\n" + "\n"; + } +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/TextureFunctionHLSL.h b/src/3rdparty/angle/src/compiler/translator/TextureFunctionHLSL.h new file mode 100644 index 0000000000..68bf8c0898 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/TextureFunctionHLSL.h @@ -0,0 +1,76 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// TextureFunctionHLSL: Class for writing implementations of ESSL texture functions into HLSL +// output. Some of the implementations are straightforward and just call the HLSL equivalent of the +// ESSL texture function, others do more work to emulate ESSL texture sampling or size query +// behavior. +// + +#ifndef COMPILER_TRANSLATOR_TEXTUREFUNCTIONHLSL_H_ +#define COMPILER_TRANSLATOR_TEXTUREFUNCTIONHLSL_H_ + +#include + +#include "compiler/translator/BaseTypes.h" +#include "compiler/translator/Common.h" +#include "compiler/translator/InfoSink.h" +#include "GLSLANG/ShaderLang.h" + +namespace sh +{ + +class TextureFunctionHLSL final : angle::NonCopyable +{ + public: + struct TextureFunction + { + // See ESSL 3.00.6 section 8.8 for reference about what the different methods below do. + enum Method + { + IMPLICIT, // Mipmap LOD determined implicitly (standard lookup) + BIAS, + LOD, + LOD0, + LOD0BIAS, + SIZE, // textureSize() + FETCH, + GRAD + }; + + TString name() const; + + bool operator<(const TextureFunction &rhs) const; + + const char *getReturnType() const; + + TBasicType sampler; + int coords; + bool proj; + bool offset; + Method method; + }; + + // Returns the name of the texture function implementation to call. + // The name that's passed in is the name of the GLSL texture function that it should implement. + TString useTextureFunction(const TString &name, + TBasicType samplerType, + int coords, + size_t argumentCount, + bool lod0, + sh::GLenum shaderType); + + void textureFunctionHeader(TInfoSinkBase &out, + const ShShaderOutput outputType, + bool getDimensionsIgnoresBaseLevel); + + private: + typedef std::set TextureFunctionSet; + TextureFunctionSet mUsesTexture; +}; + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_TEXTUREFUNCTIONHLSL_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.cpp b/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.cpp index 76d006fd11..23c967f944 100644 --- a/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.cpp +++ b/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.cpp @@ -12,21 +12,28 @@ #include "compiler/translator/OutputESSL.h" #include "angle_gl.h" +namespace sh +{ + TranslatorESSL::TranslatorESSL(sh::GLenum type, ShShaderSpec spec) : TCompiler(type, spec, SH_ESSL_OUTPUT) { } -void TranslatorESSL::initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions) +void TranslatorESSL::initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, + ShCompileOptions compileOptions) { - if (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS) + if (compileOptions & SH_EMULATE_ATAN2_FLOAT_FUNCTION) { - InitBuiltInFunctionEmulatorForGLSLWorkarounds(emu, getShaderType()); + InitBuiltInAtanFunctionEmulatorForGLSLWorkarounds(emu); } } -void TranslatorESSL::translate(TIntermNode *root, int) { - TInfoSinkBase& sink = getInfoSink().obj; +void TranslatorESSL::translate(TIntermBlock *root, + ShCompileOptions compileOptions, + PerformanceDiagnostics * /*perfDiagnostics*/) +{ + TInfoSinkBase &sink = getInfoSink().obj; int shaderVer = getShaderVersion(); if (shaderVer > 100) @@ -34,69 +41,144 @@ void TranslatorESSL::translate(TIntermNode *root, int) { sink << "#version " << shaderVer << " es\n"; } - writePragma(); - // Write built-in extension behaviors. - writeExtensionBehavior(); + writeExtensionBehavior(compileOptions); - bool precisionEmulation = getResources().WEBGL_debug_shader_precision && getPragma().debugShaderPrecision; + // Write pragmas after extensions because some drivers consider pragmas + // like non-preprocessor tokens. + writePragma(compileOptions); + + bool precisionEmulation = + getResources().WEBGL_debug_shader_precision && getPragma().debugShaderPrecision; if (precisionEmulation) { - EmulatePrecision emulatePrecision(getSymbolTable(), shaderVer); + EmulatePrecision emulatePrecision(&getSymbolTable(), shaderVer); root->traverse(&emulatePrecision); emulatePrecision.updateTree(); - emulatePrecision.writeEmulationHelpers(sink, SH_ESSL_OUTPUT); + emulatePrecision.writeEmulationHelpers(sink, shaderVer, SH_ESSL_OUTPUT); } - RecordConstantPrecision(root, getTemporaryIndex()); + RecordConstantPrecision(root, &getSymbolTable()); // Write emulated built-in functions if needed. - if (!getBuiltInFunctionEmulator().IsOutputEmpty()) + if (!getBuiltInFunctionEmulator().isOutputEmpty()) { sink << "// BEGIN: Generated code for built-in function emulation\n\n"; if (getShaderType() == GL_FRAGMENT_SHADER) { sink << "#if defined(GL_FRAGMENT_PRECISION_HIGH)\n" - << "#define webgl_emu_precision highp\n" + << "#define emu_precision highp\n" << "#else\n" - << "#define webgl_emu_precision mediump\n" + << "#define emu_precision mediump\n" << "#endif\n\n"; } else { - sink << "#define webgl_emu_precision highp\n"; + sink << "#define emu_precision highp\n"; } - getBuiltInFunctionEmulator().OutputEmulatedFunctions(sink); + getBuiltInFunctionEmulator().outputEmulatedFunctions(sink); sink << "// END: Generated code for built-in function emulation\n\n"; } // Write array bounds clamping emulation if needed. getArrayBoundsClamper().OutputClampingFunctionDefinition(sink); + if (getShaderType() == GL_COMPUTE_SHADER && isComputeShaderLocalSizeDeclared()) + { + const sh::WorkGroupSize &localSize = getComputeShaderLocalSize(); + sink << "layout (local_size_x=" << localSize[0] << ", local_size_y=" << localSize[1] + << ", local_size_z=" << localSize[2] << ") in;\n"; + } + + if (getShaderType() == GL_GEOMETRY_SHADER_OES) + { + WriteGeometryShaderLayoutQualifiers( + sink, getGeometryShaderInputPrimitiveType(), getGeometryShaderInvocations(), + getGeometryShaderOutputPrimitiveType(), getGeometryShaderMaxVertices()); + } + // Write translated shader. TOutputESSL outputESSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(), - getSymbolTable(), shaderVer, precisionEmulation); + &getSymbolTable(), getShaderType(), shaderVer, precisionEmulation, + compileOptions); + + if (compileOptions & SH_TRANSLATE_VIEWID_OVR_TO_UNIFORM) + { + TName uniformName(TString("ViewID_OVR")); + uniformName.setInternal(true); + sink << "highp uniform int " << outputESSL.hashName(uniformName) << ";\n"; + } + root->traverse(&outputESSL); } -void TranslatorESSL::writeExtensionBehavior() { - TInfoSinkBase& sink = getInfoSink().obj; - const TExtensionBehavior& extBehavior = getExtensionBehavior(); - for (TExtensionBehavior::const_iterator iter = extBehavior.begin(); - iter != extBehavior.end(); ++iter) { - if (iter->second != EBhUndefined) { - if (getResources().NV_shader_framebuffer_fetch && iter->first == "GL_EXT_shader_framebuffer_fetch") { +bool TranslatorESSL::shouldFlattenPragmaStdglInvariantAll() +{ + // Not necessary when translating to ESSL. + return false; +} + +void TranslatorESSL::writeExtensionBehavior(ShCompileOptions compileOptions) +{ + TInfoSinkBase &sink = getInfoSink().obj; + const TExtensionBehavior &extBehavior = getExtensionBehavior(); + const bool isMultiviewExtEmulated = + (compileOptions & + (SH_TRANSLATE_VIEWID_OVR_TO_UNIFORM | SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW | + SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER)) != 0u; + for (TExtensionBehavior::const_iterator iter = extBehavior.begin(); iter != extBehavior.end(); + ++iter) + { + if (iter->second != EBhUndefined) + { + const bool isMultiview = (iter->first == TExtension::OVR_multiview); + if (getResources().NV_shader_framebuffer_fetch && + iter->first == TExtension::EXT_shader_framebuffer_fetch) + { sink << "#extension GL_NV_shader_framebuffer_fetch : " - << getBehaviorString(iter->second) << "\n"; - } else if (getResources().NV_draw_buffers && iter->first == "GL_EXT_draw_buffers") { - sink << "#extension GL_NV_draw_buffers : " - << getBehaviorString(iter->second) << "\n"; - } else { - sink << "#extension " << iter->first << " : " - << getBehaviorString(iter->second) << "\n"; + << GetBehaviorString(iter->second) << "\n"; + } + else if (getResources().NV_draw_buffers && iter->first == TExtension::EXT_draw_buffers) + { + sink << "#extension GL_NV_draw_buffers : " << GetBehaviorString(iter->second) + << "\n"; + } + else if (isMultiview && isMultiviewExtEmulated) + { + if (getShaderType() == GL_VERTEX_SHADER && + (compileOptions & SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER) != 0u) + { + // Emit the NV_viewport_array2 extension in a vertex shader if the + // SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER option is set and the + // OVR_multiview(2) extension is requested. + sink << "#extension GL_NV_viewport_array2 : require\n"; + } + } + else if (iter->first == TExtension::OES_geometry_shader) + { + sink << "#ifdef GL_OES_geometry_shader\n" + << "#extension GL_OES_geometry_shader : " << GetBehaviorString(iter->second) + << "\n" + << "#elif defined GL_EXT_geometry_shader\n" + << "#extension GL_EXT_geometry_shader : " << GetBehaviorString(iter->second) + << "\n"; + if (iter->second == EBhRequire) + { + sink << "#else\n" + << "#error \"No geometry shader extensions available.\" // Only generate " + "this if the extension is \"required\"\n"; + } + sink << "#endif\n"; + } + else + { + sink << "#extension " << GetExtensionNameString(iter->first) << " : " + << GetBehaviorString(iter->second) << "\n"; } } } } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.h b/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.h index 2cc61074d4..24dc738513 100644 --- a/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.h +++ b/src/3rdparty/angle/src/compiler/translator/TranslatorESSL.h @@ -9,18 +9,27 @@ #include "compiler/translator/Compiler.h" +namespace sh +{ + class TranslatorESSL : public TCompiler { public: TranslatorESSL(sh::GLenum type, ShShaderSpec spec); protected: - void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions) override; + void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, + ShCompileOptions compileOptions) override; - void translate(TIntermNode *root, int compileOptions) override; + void translate(TIntermBlock *root, + ShCompileOptions compileOptions, + PerformanceDiagnostics *perfDiagnostics) override; + bool shouldFlattenPragmaStdglInvariantAll() override; private: - void writeExtensionBehavior(); + void writeExtensionBehavior(ShCompileOptions compileOptions); }; +} // namespace sh + #endif // COMPILER_TRANSLATOR_TRANSLATORESSL_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp b/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp index 05e9eb310b..a14e69e5d5 100644 --- a/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp +++ b/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp @@ -11,53 +11,116 @@ #include "compiler/translator/EmulatePrecision.h" #include "compiler/translator/ExtensionGLSL.h" #include "compiler/translator/OutputGLSL.h" +#include "compiler/translator/RewriteTexelFetchOffset.h" +#include "compiler/translator/RewriteUnaryMinusOperatorFloat.h" #include "compiler/translator/VersionGLSL.h" -TranslatorGLSL::TranslatorGLSL(sh::GLenum type, - ShShaderSpec spec, - ShShaderOutput output) - : TCompiler(type, spec, output) { +namespace sh +{ + +TranslatorGLSL::TranslatorGLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output) + : TCompiler(type, spec, output) +{ } -void TranslatorGLSL::initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions) +void TranslatorGLSL::initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, + ShCompileOptions compileOptions) { - if (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS) + if (compileOptions & SH_EMULATE_ABS_INT_FUNCTION) { - InitBuiltInFunctionEmulatorForGLSLWorkarounds(emu, getShaderType()); + InitBuiltInAbsFunctionEmulatorForGLSLWorkarounds(emu, getShaderType()); + } + + if (compileOptions & SH_EMULATE_ISNAN_FLOAT_FUNCTION) + { + InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(emu, getShaderVersion()); + } + + if (compileOptions & SH_EMULATE_ATAN2_FLOAT_FUNCTION) + { + InitBuiltInAtanFunctionEmulatorForGLSLWorkarounds(emu); } int targetGLSLVersion = ShaderOutputTypeToGLSLVersion(getOutputType()); InitBuiltInFunctionEmulatorForGLSLMissingFunctions(emu, getShaderType(), targetGLSLVersion); } -void TranslatorGLSL::translate(TIntermNode *root, int compileOptions) +void TranslatorGLSL::translate(TIntermBlock *root, + ShCompileOptions compileOptions, + PerformanceDiagnostics * /*perfDiagnostics*/) { - TInfoSinkBase& sink = getInfoSink().obj; + TInfoSinkBase &sink = getInfoSink().obj; // Write GLSL version. writeVersion(root); - writePragma(); - // Write extension behaviour as needed - writeExtensionBehavior(root); + writeExtensionBehavior(root, compileOptions); - bool precisionEmulation = getResources().WEBGL_debug_shader_precision && getPragma().debugShaderPrecision; + // Write pragmas after extensions because some drivers consider pragmas + // like non-preprocessor tokens. + writePragma(compileOptions); + + // If flattening the global invariant pragma, write invariant declarations for built-in + // variables. It should be harmless to do this twice in the case that the shader also explicitly + // did this. However, it's important to emit invariant qualifiers only for those built-in + // variables that are actually used, to avoid affecting the behavior of the shader. + if ((compileOptions & SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL) != 0 && + getPragma().stdgl.invariantAll && + !sh::RemoveInvariant(getShaderType(), getShaderVersion(), getOutputType(), compileOptions)) + { + ASSERT(wereVariablesCollected()); + + switch (getShaderType()) + { + case GL_VERTEX_SHADER: + sink << "invariant gl_Position;\n"; + + // gl_PointSize should be declared invariant in both ESSL 1.00 and 3.00 fragment + // shaders if it's statically referenced. + conditionallyOutputInvariantDeclaration("gl_PointSize"); + break; + case GL_FRAGMENT_SHADER: + // The preprocessor will reject this pragma if it's used in ESSL 3.00 fragment + // shaders, so we can use simple logic to determine whether to declare these + // variables invariant. + conditionallyOutputInvariantDeclaration("gl_FragCoord"); + conditionallyOutputInvariantDeclaration("gl_PointCoord"); + break; + default: + // Currently not reached, but leave this in for future expansion. + ASSERT(false); + break; + } + } + + if ((compileOptions & SH_REWRITE_TEXELFETCHOFFSET_TO_TEXELFETCH) != 0) + { + sh::RewriteTexelFetchOffset(root, getSymbolTable(), getShaderVersion()); + } + + if ((compileOptions & SH_REWRITE_FLOAT_UNARY_MINUS_OPERATOR) != 0) + { + sh::RewriteUnaryMinusOperatorFloat(root); + } + + bool precisionEmulation = + getResources().WEBGL_debug_shader_precision && getPragma().debugShaderPrecision; if (precisionEmulation) { - EmulatePrecision emulatePrecision(getSymbolTable(), getShaderVersion()); + EmulatePrecision emulatePrecision(&getSymbolTable(), getShaderVersion()); root->traverse(&emulatePrecision); emulatePrecision.updateTree(); - emulatePrecision.writeEmulationHelpers(sink, getOutputType()); + emulatePrecision.writeEmulationHelpers(sink, getShaderVersion(), getOutputType()); } // Write emulated built-in functions if needed. - if (!getBuiltInFunctionEmulator().IsOutputEmpty()) + if (!getBuiltInFunctionEmulator().isOutputEmpty()) { sink << "// BEGIN: Generated code for built-in function emulation\n\n"; - sink << "#define webgl_emu_precision\n\n"; - getBuiltInFunctionEmulator().OutputEmulatedFunctions(sink); + sink << "#define emu_precision\n\n"; + getBuiltInFunctionEmulator().outputEmulatedFunctions(sink); sink << "// END: Generated code for built-in function emulation\n\n"; } @@ -69,7 +132,7 @@ void TranslatorGLSL::translate(TIntermNode *root, int compileOptions) if (getShaderType() == GL_FRAGMENT_SHADER) { const bool mayHaveESSL1SecondaryOutputs = - IsExtensionEnabled(getExtensionBehavior(), "GL_EXT_blend_func_extended") && + IsExtensionEnabled(getExtensionBehavior(), TExtension::EXT_blend_func_extended) && getShaderVersion() == 100; const bool declareGLFragmentOutputs = IsGLSL130OrNewer(getOutputType()); @@ -132,17 +195,48 @@ void TranslatorGLSL::translate(TIntermNode *root, int compileOptions) } } + if (getShaderType() == GL_COMPUTE_SHADER && isComputeShaderLocalSizeDeclared()) + { + const sh::WorkGroupSize &localSize = getComputeShaderLocalSize(); + sink << "layout (local_size_x=" << localSize[0] << ", local_size_y=" << localSize[1] + << ", local_size_z=" << localSize[2] << ") in;\n"; + } + + if (getShaderType() == GL_GEOMETRY_SHADER_OES) + { + WriteGeometryShaderLayoutQualifiers( + sink, getGeometryShaderInputPrimitiveType(), getGeometryShaderInvocations(), + getGeometryShaderOutputPrimitiveType(), getGeometryShaderMaxVertices()); + } + // Write translated shader. - TOutputGLSL outputGLSL(sink, - getArrayIndexClampingStrategy(), - getHashFunction(), - getNameMap(), - getSymbolTable(), - getShaderVersion(), - getOutputType()); + TOutputGLSL outputGLSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(), + &getSymbolTable(), getShaderType(), getShaderVersion(), getOutputType(), + compileOptions); + + if (compileOptions & SH_TRANSLATE_VIEWID_OVR_TO_UNIFORM) + { + TName uniformName(TString("ViewID_OVR")); + uniformName.setInternal(true); + sink << "uniform int " << outputGLSL.hashName(uniformName) << ";\n"; + } + root->traverse(&outputGLSL); } +bool TranslatorGLSL::shouldFlattenPragmaStdglInvariantAll() +{ + // Required when outputting to any GLSL version greater than 1.20, but since ANGLE doesn't + // translate to that version, return true for the next higher version. + return IsGLSL130OrNewer(getOutputType()); +} + +bool TranslatorGLSL::shouldCollectVariables(ShCompileOptions compileOptions) +{ + return (compileOptions & SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL) || + TCompiler::shouldCollectVariables(compileOptions); +} + void TranslatorGLSL::writeVersion(TIntermNode *root) { TVersionGLSL versionGLSL(getShaderType(), getPragma(), getOutputType()); @@ -152,15 +246,15 @@ void TranslatorGLSL::writeVersion(TIntermNode *root) // If there is no version directive in the shader, 110 is implied. if (version > 110) { - TInfoSinkBase& sink = getInfoSink().obj; + TInfoSinkBase &sink = getInfoSink().obj; sink << "#version " << version << "\n"; } } -void TranslatorGLSL::writeExtensionBehavior(TIntermNode *root) +void TranslatorGLSL::writeExtensionBehavior(TIntermNode *root, ShCompileOptions compileOptions) { - TInfoSinkBase& sink = getInfoSink().obj; - const TExtensionBehavior& extBehavior = getExtensionBehavior(); + TInfoSinkBase &sink = getInfoSink().obj; + const TExtensionBehavior &extBehavior = getExtensionBehavior(); for (const auto &iter : extBehavior) { if (iter.second == EBhUndefined) @@ -168,21 +262,58 @@ void TranslatorGLSL::writeExtensionBehavior(TIntermNode *root) continue; } - // For GLSL output, we don't need to emit most extensions explicitly, - // but some we need to translate. - if (iter.first == "GL_EXT_shader_texture_lod") + if (getOutputType() == SH_GLSL_COMPATIBILITY_OUTPUT) { - sink << "#extension GL_ARB_shader_texture_lod : " << getBehaviorString(iter.second) - << "\n"; + // For GLSL output, we don't need to emit most extensions explicitly, + // but some we need to translate in GL compatibility profile. + if (iter.first == TExtension::EXT_shader_texture_lod) + { + sink << "#extension GL_ARB_shader_texture_lod : " << GetBehaviorString(iter.second) + << "\n"; + } + + if (iter.first == TExtension::EXT_draw_buffers) + { + sink << "#extension GL_ARB_draw_buffers : " << GetBehaviorString(iter.second) + << "\n"; + } + + if (iter.first == TExtension::OES_geometry_shader) + { + sink << "#extension GL_ARB_geometry_shader4 : " << GetBehaviorString(iter.second) + << "\n"; + } + } + + const bool isMultiview = (iter.first == TExtension::OVR_multiview); + if (isMultiview && getShaderType() == GL_VERTEX_SHADER && + (compileOptions & SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER) != 0u) + { + // Emit the NV_viewport_array2 extension in a vertex shader if the + // SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER option is set and the OVR_multiview(2) + // extension is requested. + sink << "#extension GL_NV_viewport_array2 : require\n"; } } // GLSL ES 3 explicit location qualifiers need to use an extension before GLSL 330 - if (getShaderVersion() >= 300 && getOutputType() < SH_GLSL_330_CORE_OUTPUT) + if (getShaderVersion() >= 300 && getOutputType() < SH_GLSL_330_CORE_OUTPUT && + getShaderType() != GL_COMPUTE_SHADER) { sink << "#extension GL_ARB_explicit_attrib_location : require\n"; } + // Need to enable gpu_shader5 to have index constant sampler array indexing + if (getOutputType() != SH_ESSL_OUTPUT && getOutputType() < SH_GLSL_400_CORE_OUTPUT && + getShaderVersion() == 100) + { + // Don't use "require" on to avoid breaking WebGL 1 on drivers that silently + // support index constant sampler array indexing, but don't have the extension or + // on drivers that don't have the extension at all as it would break WebGL 1 for + // some users. + sink << "#extension GL_ARB_gpu_shader5 : enable\n"; + } + TExtensionGLSL extensionGLSL(getOutputType()); root->traverse(&extensionGLSL); @@ -195,3 +326,14 @@ void TranslatorGLSL::writeExtensionBehavior(TIntermNode *root) sink << "#extension " << ext << " : require\n"; } } + +void TranslatorGLSL::conditionallyOutputInvariantDeclaration(const char *builtinVaryingName) +{ + if (isVaryingDefined(builtinVaryingName)) + { + TInfoSinkBase &sink = getInfoSink().obj; + sink << "invariant " << builtinVaryingName << ";\n"; + } +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.h b/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.h index 4f07b21980..982d0e5ddc 100644 --- a/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.h +++ b/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.h @@ -9,19 +9,30 @@ #include "compiler/translator/Compiler.h" +namespace sh +{ + class TranslatorGLSL : public TCompiler { public: TranslatorGLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output); protected: - void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions) override; + void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, + ShCompileOptions compileOptions) override; - void translate(TIntermNode *root, int compileOptions) override; + void translate(TIntermBlock *root, + ShCompileOptions compileOptions, + PerformanceDiagnostics *perfDiagnostics) override; + bool shouldFlattenPragmaStdglInvariantAll() override; + bool shouldCollectVariables(ShCompileOptions compileOptions) override; private: void writeVersion(TIntermNode *root); - void writeExtensionBehavior(TIntermNode *root); + void writeExtensionBehavior(TIntermNode *root, ShCompileOptions compileOptions); + void conditionallyOutputInvariantDeclaration(const char *builtinVaryingName); }; +} // namespace sh + #endif // COMPILER_TRANSLATOR_TRANSLATORGLSL_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/TranslatorHLSL.cpp b/src/3rdparty/angle/src/compiler/translator/TranslatorHLSL.cpp index c5d18d21bf..091a649cfc 100644 --- a/src/3rdparty/angle/src/compiler/translator/TranslatorHLSL.cpp +++ b/src/3rdparty/angle/src/compiler/translator/TranslatorHLSL.cpp @@ -6,79 +6,156 @@ #include "compiler/translator/TranslatorHLSL.h" +#include "compiler/translator/AddDefaultReturnStatements.h" #include "compiler/translator/ArrayReturnValueToOutParameter.h" +#include "compiler/translator/BreakVariableAliasingInInnerLoops.h" +#include "compiler/translator/EmulatePrecision.h" +#include "compiler/translator/ExpandIntegerPowExpressions.h" +#include "compiler/translator/IntermNodePatternMatcher.h" #include "compiler/translator/OutputHLSL.h" #include "compiler/translator/RemoveDynamicIndexing.h" +#include "compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.h" #include "compiler/translator/RewriteElseBlocks.h" +#include "compiler/translator/RewriteTexelFetchOffset.h" +#include "compiler/translator/RewriteUnaryMinusOperatorInt.h" #include "compiler/translator/SeparateArrayInitialization.h" #include "compiler/translator/SeparateDeclarations.h" #include "compiler/translator/SeparateExpressionsReturningArrays.h" +#include "compiler/translator/SimplifyLoopConditions.h" +#include "compiler/translator/SplitSequenceOperator.h" #include "compiler/translator/UnfoldShortCircuitToIf.h" +#include "compiler/translator/WrapSwitchStatementsInBlocks.h" + +namespace sh +{ TranslatorHLSL::TranslatorHLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output) : TCompiler(type, spec, output) { } -void TranslatorHLSL::translate(TIntermNode *root, int compileOptions) +void TranslatorHLSL::translate(TIntermBlock *root, + ShCompileOptions compileOptions, + PerformanceDiagnostics *perfDiagnostics) { const ShBuiltInResources &resources = getResources(); - int numRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1; + int numRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1; - SeparateDeclarations(root); + sh::AddDefaultReturnStatements(root); + + // Note that SimplifyLoopConditions needs to be run before any other AST transformations that + // may need to generate new statements from loop conditions or loop expressions. + // Note that SeparateDeclarations has already been run in TCompiler::compileTreeImpl(). + SimplifyLoopConditions(root, + IntermNodePatternMatcher::kExpressionReturningArray | + IntermNodePatternMatcher::kUnfoldedShortCircuitExpression | + IntermNodePatternMatcher::kDynamicIndexingOfVectorOrMatrixInLValue, + &getSymbolTable(), getShaderVersion()); + + SplitSequenceOperator(root, + IntermNodePatternMatcher::kExpressionReturningArray | + IntermNodePatternMatcher::kUnfoldedShortCircuitExpression | + IntermNodePatternMatcher::kDynamicIndexingOfVectorOrMatrixInLValue, + &getSymbolTable(), getShaderVersion()); // Note that SeparateDeclarations needs to be run before UnfoldShortCircuitToIf. - UnfoldShortCircuitToIf(root, getTemporaryIndex()); + UnfoldShortCircuitToIf(root, &getSymbolTable()); - SeparateExpressionsReturningArrays(root, getTemporaryIndex()); + SeparateExpressionsReturningArrays(root, &getSymbolTable()); // Note that SeparateDeclarations needs to be run before SeparateArrayInitialization. SeparateArrayInitialization(root); // HLSL doesn't support arrays as return values, we'll need to make functions that have an array // as a return value to use an out parameter to transfer the array data instead. - ArrayReturnValueToOutParameter(root, getTemporaryIndex()); + ArrayReturnValueToOutParameter(root, &getSymbolTable()); if (!shouldRunLoopAndIndexingValidation(compileOptions)) { // HLSL doesn't support dynamic indexing of vectors and matrices. - RemoveDynamicIndexing(root, getTemporaryIndex(), getSymbolTable(), getShaderVersion()); + RemoveDynamicIndexing(root, &getSymbolTable(), getShaderVersion(), perfDiagnostics); } // Work around D3D9 bug that would manifest in vertex shaders with selection blocks which // use a vertex attribute as a condition, and some related computation in the else block. if (getOutputType() == SH_HLSL_3_0_OUTPUT && getShaderType() == GL_VERTEX_SHADER) { - sh::RewriteElseBlocks(root, getTemporaryIndex()); + sh::RewriteElseBlocks(root, &getSymbolTable()); + } + + // Work around an HLSL compiler frontend aliasing optimization bug. + // TODO(cwallez) The date is 2016-08-25, Microsoft said the bug would be fixed + // in the next release of d3dcompiler.dll, it would be nice to detect the DLL + // version and only apply the workaround if it is too old. + sh::BreakVariableAliasingInInnerLoops(root); + + // WrapSwitchStatementsInBlocks should be called after any AST transformations that might + // introduce variable declarations inside the main scope of any switch statement. + if (WrapSwitchStatementsInBlocks(root)) + { + // The WrapSwitchStatementsInBlocks step might introduce new no-op cases to the end of + // switch statements, so make sure to clean up the AST. + RemoveNoOpCasesFromEndOfSwitchStatements(root, &getSymbolTable()); + } + + bool precisionEmulation = + getResources().WEBGL_debug_shader_precision && getPragma().debugShaderPrecision; + + if (precisionEmulation) + { + EmulatePrecision emulatePrecision(&getSymbolTable(), getShaderVersion()); + root->traverse(&emulatePrecision); + emulatePrecision.updateTree(); + emulatePrecision.writeEmulationHelpers(getInfoSink().obj, getShaderVersion(), + getOutputType()); + } + + if ((compileOptions & SH_EXPAND_SELECT_HLSL_INTEGER_POW_EXPRESSIONS) != 0) + { + sh::ExpandIntegerPowExpressions(root, &getSymbolTable()); + } + + if ((compileOptions & SH_REWRITE_TEXELFETCHOFFSET_TO_TEXELFETCH) != 0) + { + sh::RewriteTexelFetchOffset(root, getSymbolTable(), getShaderVersion()); + } + + if (((compileOptions & SH_REWRITE_INTEGER_UNARY_MINUS_OPERATOR) != 0) && + getShaderType() == GL_VERTEX_SHADER) + { + sh::RewriteUnaryMinusOperatorInt(root); } sh::OutputHLSL outputHLSL(getShaderType(), getShaderVersion(), getExtensionBehavior(), - getSourcePath(), getOutputType(), numRenderTargets, getUniforms(), compileOptions); + getSourcePath(), getOutputType(), numRenderTargets, getUniforms(), + compileOptions, &getSymbolTable(), perfDiagnostics); outputHLSL.output(root, getInfoSink().obj); - mInterfaceBlockRegisterMap = outputHLSL.getInterfaceBlockRegisterMap(); - mUniformRegisterMap = outputHLSL.getUniformRegisterMap(); + mUniformBlockRegisterMap = outputHLSL.getUniformBlockRegisterMap(); + mUniformRegisterMap = outputHLSL.getUniformRegisterMap(); } -bool TranslatorHLSL::hasInterfaceBlock(const std::string &interfaceBlockName) const +bool TranslatorHLSL::shouldFlattenPragmaStdglInvariantAll() { - return (mInterfaceBlockRegisterMap.count(interfaceBlockName) > 0); + // Not necessary when translating to HLSL. + return false; } -unsigned int TranslatorHLSL::getInterfaceBlockRegister(const std::string &interfaceBlockName) const +bool TranslatorHLSL::hasUniformBlock(const std::string &uniformBlockName) const { - ASSERT(hasInterfaceBlock(interfaceBlockName)); - return mInterfaceBlockRegisterMap.find(interfaceBlockName)->second; + return (mUniformBlockRegisterMap.count(uniformBlockName) > 0); } -bool TranslatorHLSL::hasUniform(const std::string &uniformName) const +unsigned int TranslatorHLSL::getUniformBlockRegister(const std::string &uniformBlockName) const { - return (mUniformRegisterMap.count(uniformName) > 0); + ASSERT(hasUniformBlock(uniformBlockName)); + return mUniformBlockRegisterMap.find(uniformBlockName)->second; } -unsigned int TranslatorHLSL::getUniformRegister(const std::string &uniformName) const +const std::map *TranslatorHLSL::getUniformRegisterMap() const { - ASSERT(hasUniform(uniformName)); - return mUniformRegisterMap.find(uniformName)->second; + return &mUniformRegisterMap; } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/TranslatorHLSL.h b/src/3rdparty/angle/src/compiler/translator/TranslatorHLSL.h index 907d816744..d7005a603c 100644 --- a/src/3rdparty/angle/src/compiler/translator/TranslatorHLSL.h +++ b/src/3rdparty/angle/src/compiler/translator/TranslatorHLSL.h @@ -9,26 +9,33 @@ #include "compiler/translator/Compiler.h" +namespace sh +{ + class TranslatorHLSL : public TCompiler { public: TranslatorHLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output); TranslatorHLSL *getAsTranslatorHLSL() override { return this; } - bool hasInterfaceBlock(const std::string &interfaceBlockName) const; - unsigned int getInterfaceBlockRegister(const std::string &interfaceBlockName) const; + bool hasUniformBlock(const std::string &interfaceBlockName) const; + unsigned int getUniformBlockRegister(const std::string &interfaceBlockName) const; - bool hasUniform(const std::string &uniformName) const; - unsigned int getUniformRegister(const std::string &uniformName) const; + const std::map *getUniformRegisterMap() const; protected: - void translate(TIntermNode *root, int compileOptions) override; + void translate(TIntermBlock *root, + ShCompileOptions compileOptions, + PerformanceDiagnostics *perfDiagnostics) override; + bool shouldFlattenPragmaStdglInvariantAll() override; // collectVariables needs to be run always so registers can be assigned. - bool shouldCollectVariables(int compileOptions) override { return true; } + bool shouldCollectVariables(ShCompileOptions compileOptions) override { return true; } - std::map mInterfaceBlockRegisterMap; + std::map mUniformBlockRegisterMap; std::map mUniformRegisterMap; }; +} // namespace sh + #endif // COMPILER_TRANSLATOR_TRANSLATORHLSL_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/TranslatorVulkan.cpp b/src/3rdparty/angle/src/compiler/translator/TranslatorVulkan.cpp new file mode 100644 index 0000000000..0fe2a21f90 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/TranslatorVulkan.cpp @@ -0,0 +1,173 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// TranslatorVulkan: +// A GLSL-based translator that outputs shaders that fit GL_KHR_vulkan_glsl. +// The shaders are then fed into glslang to spit out SPIR-V (libANGLE-side). +// See: https://www.khronos.org/registry/vulkan/specs/misc/GL_KHR_vulkan_glsl.txt +// + +#include "compiler/translator/TranslatorVulkan.h" + +#include "angle_gl.h" +#include "common/utilities.h" +#include "compiler/translator/OutputVulkanGLSL.h" +#include "compiler/translator/util.h" + +namespace sh +{ + +class DeclareDefaultUniformsTraverser : public TIntermTraverser +{ + public: + DeclareDefaultUniformsTraverser(TInfoSinkBase *sink, + ShHashFunction64 hashFunction, + NameMap *nameMap) + : TIntermTraverser(true, true, true), + mSink(sink), + mHashFunction(hashFunction), + mNameMap(nameMap), + mInDefaultUniform(false) + { + } + + bool visitDeclaration(Visit visit, TIntermDeclaration *node) override + { + const TIntermSequence &sequence = *(node->getSequence()); + + // TODO(jmadill): Compound declarations. + ASSERT(sequence.size() == 1); + + TIntermTyped *variable = sequence.front()->getAsTyped(); + const TType &type = variable->getType(); + bool isUniform = (type.getQualifier() == EvqUniform) && !IsOpaqueType(type.getBasicType()); + + if (visit == PreVisit) + { + if (isUniform) + { + (*mSink) << " " << GetTypeName(type, mHashFunction, mNameMap) << " "; + mInDefaultUniform = true; + } + } + else if (visit == InVisit) + { + mInDefaultUniform = isUniform; + } + else if (visit == PostVisit) + { + if (isUniform) + { + (*mSink) << ";\n"; + + // Remove the uniform declaration from the tree so it isn't parsed again. + TIntermSequence emptyReplacement; + mMultiReplacements.push_back(NodeReplaceWithMultipleEntry( + getParentNode()->getAsBlock(), node, emptyReplacement)); + } + + mInDefaultUniform = false; + } + return true; + } + + void visitSymbol(TIntermSymbol *symbol) override + { + if (mInDefaultUniform) + { + const TName &name = symbol->getName(); + ASSERT(name.getString().substr(0, 3) != "gl_"); + (*mSink) << HashName(name, mHashFunction, mNameMap); + } + } + + private: + TInfoSinkBase *mSink; + ShHashFunction64 mHashFunction; + NameMap *mNameMap; + bool mInDefaultUniform; +}; + +TranslatorVulkan::TranslatorVulkan(sh::GLenum type, ShShaderSpec spec) + : TCompiler(type, spec, SH_GLSL_450_CORE_OUTPUT) +{ +} + +void TranslatorVulkan::translate(TIntermBlock *root, + ShCompileOptions compileOptions, + PerformanceDiagnostics * /*perfDiagnostics*/) +{ + TInfoSinkBase &sink = getInfoSink().obj; + + sink << "#version 450 core\n"; + + // Write out default uniforms into a uniform block assigned to a specific set/binding. + int defaultUniformCount = 0; + for (const auto &uniform : getUniforms()) + { + if (!uniform.isBuiltIn() && uniform.staticUse && !gl::IsOpaqueType(uniform.type)) + { + ++defaultUniformCount; + } + } + + if (defaultUniformCount > 0) + { + sink << "\nlayout(@@ DEFAULT-UNIFORMS-SET-BINDING @@) uniform defaultUniforms\n{\n"; + + DeclareDefaultUniformsTraverser defaultTraverser(&sink, getHashFunction(), &getNameMap()); + root->traverse(&defaultTraverser); + defaultTraverser.updateTree(); + + sink << "};\n"; + } + + // Declare gl_FragColor and glFragData as webgl_FragColor and webgl_FragData + // if it's core profile shaders and they are used. + if (getShaderType() == GL_FRAGMENT_SHADER) + { + bool hasGLFragColor = false; + bool hasGLFragData = false; + + for (const auto &outputVar : outputVariables) + { + if (outputVar.name == "gl_FragColor") + { + ASSERT(!hasGLFragColor); + hasGLFragColor = true; + continue; + } + else if (outputVar.name == "gl_FragData") + { + ASSERT(!hasGLFragData); + hasGLFragData = true; + continue; + } + } + ASSERT(!(hasGLFragColor && hasGLFragData)); + if (hasGLFragColor) + { + sink << "layout(location = 0) out vec4 webgl_FragColor;\n"; + } + if (hasGLFragData) + { + sink << "layout(location = 0) out vec4 webgl_FragData[gl_MaxDrawBuffers];\n"; + } + } + + // Write translated shader. + TOutputVulkanGLSL outputGLSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), + getNameMap(), &getSymbolTable(), getShaderType(), + getShaderVersion(), getOutputType(), compileOptions); + root->traverse(&outputGLSL); +} + +bool TranslatorVulkan::shouldFlattenPragmaStdglInvariantAll() +{ + // Not necessary. + return false; +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/TranslatorVulkan.h b/src/3rdparty/angle/src/compiler/translator/TranslatorVulkan.h new file mode 100644 index 0000000000..ef67b15ae1 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/TranslatorVulkan.h @@ -0,0 +1,34 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// TranslatorVulkan: +// A GLSL-based translator that outputs shaders that fit GL_KHR_vulkan_glsl. +// The shaders are then fed into glslang to spit out SPIR-V (libANGLE-side). +// See: https://www.khronos.org/registry/vulkan/specs/misc/GL_KHR_vulkan_glsl.txt +// + +#ifndef COMPILER_TRANSLATOR_TRANSLATORVULKAN_H_ +#define COMPILER_TRANSLATOR_TRANSLATORVULKAN_H_ + +#include "compiler/translator/Compiler.h" + +namespace sh +{ + +class TranslatorVulkan : public TCompiler +{ + public: + TranslatorVulkan(sh::GLenum type, ShShaderSpec spec); + + protected: + void translate(TIntermBlock *root, + ShCompileOptions compileOptions, + PerformanceDiagnostics *perfDiagnostics) override; + bool shouldFlattenPragmaStdglInvariantAll() override; +}; + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_TRANSLATORVULKAN_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/Types.cpp b/src/3rdparty/angle/src/compiler/translator/Types.cpp index 87fdfe0d54..530ffe3aeb 100644 --- a/src/3rdparty/angle/src/compiler/translator/Types.cpp +++ b/src/3rdparty/angle/src/compiler/translator/Types.cpp @@ -5,58 +5,394 @@ // #if defined(_MSC_VER) -#pragma warning(disable: 4718) +#pragma warning(disable : 4718) #endif #include "compiler/translator/Types.h" +#include "compiler/translator/InfoSink.h" +#include "compiler/translator/IntermNode.h" +#include "compiler/translator/SymbolTable.h" #include #include -const char* getBasicString(TBasicType t) +namespace sh +{ + +const char *getBasicString(TBasicType t) { switch (t) { - case EbtVoid: return "void"; break; - case EbtFloat: return "float"; break; - case EbtInt: return "int"; break; - case EbtUInt: return "uint"; break; - case EbtBool: return "bool"; break; - case EbtSampler2D: return "sampler2D"; break; - case EbtSampler3D: return "sampler3D"; break; - case EbtSamplerCube: return "samplerCube"; break; - case EbtSamplerExternalOES: return "samplerExternalOES"; break; - case EbtSampler2DRect: return "sampler2DRect"; break; - case EbtSampler2DArray: return "sampler2DArray"; break; - case EbtISampler2D: return "isampler2D"; break; - case EbtISampler3D: return "isampler3D"; break; - case EbtISamplerCube: return "isamplerCube"; break; - case EbtISampler2DArray: return "isampler2DArray"; break; - case EbtUSampler2D: return "usampler2D"; break; - case EbtUSampler3D: return "usampler3D"; break; - case EbtUSamplerCube: return "usamplerCube"; break; - case EbtUSampler2DArray: return "usampler2DArray"; break; - case EbtSampler2DShadow: return "sampler2DShadow"; break; - case EbtSamplerCubeShadow: return "samplerCubeShadow"; break; - case EbtSampler2DArrayShadow: return "sampler2DArrayShadow"; break; - case EbtStruct: return "structure"; break; - case EbtInterfaceBlock: return "interface block"; break; - default: UNREACHABLE(); return "unknown type"; + case EbtVoid: + return "void"; + case EbtFloat: + return "float"; + case EbtInt: + return "int"; + case EbtUInt: + return "uint"; + case EbtBool: + return "bool"; + case EbtYuvCscStandardEXT: + return "yuvCscStandardEXT"; + case EbtSampler2D: + return "sampler2D"; + case EbtSampler3D: + return "sampler3D"; + case EbtSamplerCube: + return "samplerCube"; + case EbtSamplerExternalOES: + return "samplerExternalOES"; + case EbtSamplerExternal2DY2YEXT: + return "__samplerExternal2DY2YEXT"; + case EbtSampler2DRect: + return "sampler2DRect"; + case EbtSampler2DArray: + return "sampler2DArray"; + case EbtSampler2DMS: + return "sampler2DMS"; + case EbtISampler2D: + return "isampler2D"; + case EbtISampler3D: + return "isampler3D"; + case EbtISamplerCube: + return "isamplerCube"; + case EbtISampler2DArray: + return "isampler2DArray"; + case EbtISampler2DMS: + return "isampler2DMS"; + case EbtUSampler2D: + return "usampler2D"; + case EbtUSampler3D: + return "usampler3D"; + case EbtUSamplerCube: + return "usamplerCube"; + case EbtUSampler2DArray: + return "usampler2DArray"; + case EbtUSampler2DMS: + return "usampler2DMS"; + case EbtSampler2DShadow: + return "sampler2DShadow"; + case EbtSamplerCubeShadow: + return "samplerCubeShadow"; + case EbtSampler2DArrayShadow: + return "sampler2DArrayShadow"; + case EbtStruct: + return "structure"; + case EbtInterfaceBlock: + return "interface block"; + case EbtImage2D: + return "image2D"; + case EbtIImage2D: + return "iimage2D"; + case EbtUImage2D: + return "uimage2D"; + case EbtImage3D: + return "image3D"; + case EbtIImage3D: + return "iimage3D"; + case EbtUImage3D: + return "uimage3D"; + case EbtImage2DArray: + return "image2DArray"; + case EbtIImage2DArray: + return "iimage2DArray"; + case EbtUImage2DArray: + return "uimage2DArray"; + case EbtImageCube: + return "imageCube"; + case EbtIImageCube: + return "iimageCube"; + case EbtUImageCube: + return "uimageCube"; + case EbtAtomicCounter: + return "atomic_uint"; + default: + UNREACHABLE(); + return "unknown type"; } } -TType::TType(const TPublicType &p) - : type(p.type), precision(p.precision), qualifier(p.qualifier), invariant(p.invariant), - layoutQualifier(p.layoutQualifier), primarySize(p.primarySize), secondarySize(p.secondarySize), - array(p.array), arraySize(p.arraySize), interfaceBlock(0), structure(0) +// TType implementation. +TType::TType() + : type(EbtVoid), + precision(EbpUndefined), + qualifier(EvqGlobal), + invariant(false), + memoryQualifier(TMemoryQualifier::Create()), + layoutQualifier(TLayoutQualifier::Create()), + primarySize(0), + secondarySize(0), + mArraySizes(nullptr), + mInterfaceBlock(nullptr), + mStructure(nullptr), + mIsStructSpecifier(false), + mMangledName(nullptr) { - if (p.userDef) - structure = p.userDef->getStruct(); } -bool TStructure::equals(const TStructure &other) const +TType::TType(TBasicType t, unsigned char ps, unsigned char ss) + : type(t), + precision(EbpUndefined), + qualifier(EvqGlobal), + invariant(false), + memoryQualifier(TMemoryQualifier::Create()), + layoutQualifier(TLayoutQualifier::Create()), + primarySize(ps), + secondarySize(ss), + mArraySizes(nullptr), + mInterfaceBlock(nullptr), + mStructure(nullptr), + mIsStructSpecifier(false), + mMangledName(nullptr) { - return (uniqueId() == other.uniqueId()); +} + +TType::TType(TBasicType t, TPrecision p, TQualifier q, unsigned char ps, unsigned char ss) + : type(t), + precision(p), + qualifier(q), + invariant(false), + memoryQualifier(TMemoryQualifier::Create()), + layoutQualifier(TLayoutQualifier::Create()), + primarySize(ps), + secondarySize(ss), + mArraySizes(nullptr), + mInterfaceBlock(nullptr), + mStructure(nullptr), + mIsStructSpecifier(false), + mMangledName(nullptr) +{ +} + +TType::TType(const TPublicType &p) + : type(p.getBasicType()), + precision(p.precision), + qualifier(p.qualifier), + invariant(p.invariant), + memoryQualifier(p.memoryQualifier), + layoutQualifier(p.layoutQualifier), + primarySize(p.getPrimarySize()), + secondarySize(p.getSecondarySize()), + mArraySizes(nullptr), + mInterfaceBlock(nullptr), + mStructure(nullptr), + mIsStructSpecifier(false), + mMangledName(nullptr) +{ + ASSERT(primarySize <= 4); + ASSERT(secondarySize <= 4); + if (p.isArray()) + { + mArraySizes = new TVector(*p.arraySizes); + } + if (p.getUserDef()) + { + mStructure = p.getUserDef(); + mIsStructSpecifier = p.isStructSpecifier(); + } +} + +TType::TType(TStructure *userDef) + : type(EbtStruct), + precision(EbpUndefined), + qualifier(EvqTemporary), + invariant(false), + memoryQualifier(TMemoryQualifier::Create()), + layoutQualifier(TLayoutQualifier::Create()), + primarySize(1), + secondarySize(1), + mArraySizes(nullptr), + mInterfaceBlock(nullptr), + mStructure(userDef), + mIsStructSpecifier(false), + mMangledName(nullptr) +{ +} + +TType::TType(TInterfaceBlock *interfaceBlockIn, + TQualifier qualifierIn, + TLayoutQualifier layoutQualifierIn) + : type(EbtInterfaceBlock), + precision(EbpUndefined), + qualifier(qualifierIn), + invariant(false), + memoryQualifier(TMemoryQualifier::Create()), + layoutQualifier(layoutQualifierIn), + primarySize(1), + secondarySize(1), + mArraySizes(nullptr), + mInterfaceBlock(interfaceBlockIn), + mStructure(0), + mIsStructSpecifier(false), + mMangledName(nullptr) +{ +} + +TType::TType(const TType &t) + : type(t.type), + precision(t.precision), + qualifier(t.qualifier), + invariant(t.invariant), + memoryQualifier(t.memoryQualifier), + layoutQualifier(t.layoutQualifier), + primarySize(t.primarySize), + secondarySize(t.secondarySize), + mArraySizes(t.mArraySizes ? new TVector(*t.mArraySizes) : nullptr), + mInterfaceBlock(t.mInterfaceBlock), + mStructure(t.mStructure), + mIsStructSpecifier(t.mIsStructSpecifier), + mMangledName(t.mMangledName) +{ +} + +TType &TType::operator=(const TType &t) +{ + type = t.type; + precision = t.precision; + qualifier = t.qualifier; + invariant = t.invariant; + memoryQualifier = t.memoryQualifier; + layoutQualifier = t.layoutQualifier; + primarySize = t.primarySize; + secondarySize = t.secondarySize; + mArraySizes = t.mArraySizes ? new TVector(*t.mArraySizes) : nullptr; + mInterfaceBlock = t.mInterfaceBlock; + mStructure = t.mStructure; + mIsStructSpecifier = t.mIsStructSpecifier; + mMangledName = t.mMangledName; + return *this; +} + +bool TType::canBeConstructed() const +{ + switch (type) + { + case EbtFloat: + case EbtInt: + case EbtUInt: + case EbtBool: + case EbtStruct: + return true; + default: + return false; + } +} + +const char *TType::getBuiltInTypeNameString() const +{ + if (isMatrix()) + { + switch (getCols()) + { + case 2: + switch (getRows()) + { + case 2: + return "mat2"; + case 3: + return "mat2x3"; + case 4: + return "mat2x4"; + default: + UNREACHABLE(); + return nullptr; + } + case 3: + switch (getRows()) + { + case 2: + return "mat3x2"; + case 3: + return "mat3"; + case 4: + return "mat3x4"; + default: + UNREACHABLE(); + return nullptr; + } + case 4: + switch (getRows()) + { + case 2: + return "mat4x2"; + case 3: + return "mat4x3"; + case 4: + return "mat4"; + default: + UNREACHABLE(); + return nullptr; + } + default: + UNREACHABLE(); + return nullptr; + } + } + if (isVector()) + { + switch (getBasicType()) + { + case EbtFloat: + switch (getNominalSize()) + { + case 2: + return "vec2"; + case 3: + return "vec3"; + case 4: + return "vec4"; + default: + UNREACHABLE(); + return nullptr; + } + case EbtInt: + switch (getNominalSize()) + { + case 2: + return "ivec2"; + case 3: + return "ivec3"; + case 4: + return "ivec4"; + default: + UNREACHABLE(); + return nullptr; + } + case EbtBool: + switch (getNominalSize()) + { + case 2: + return "bvec2"; + case 3: + return "bvec3"; + case 4: + return "bvec4"; + default: + UNREACHABLE(); + return nullptr; + } + case EbtUInt: + switch (getNominalSize()) + { + case 2: + return "uvec2"; + case 3: + return "uvec3"; + case 4: + return "uvec4"; + default: + UNREACHABLE(); + return nullptr; + } + default: + UNREACHABLE(); + return nullptr; + } + } + ASSERT(getBasicType() != EbtStruct); + ASSERT(getBasicType() != EbtInterfaceBlock); + return getBasicString(); } TString TType::getCompleteString() const @@ -69,8 +405,14 @@ TString TType::getCompleteString() const stream << getQualifierString() << " "; if (precision != EbpUndefined) stream << getPrecisionString() << " "; - if (array) - stream << "array[" << getArraySize() << "] of "; + if (mArraySizes) + { + for (auto arraySizeIter = mArraySizes->rbegin(); arraySizeIter != mArraySizes->rend(); + ++arraySizeIter) + { + stream << "array[" << (*arraySizeIter) << "] of "; + } + } if (isMatrix()) stream << getCols() << "X" << getRows() << " matrix of "; else if (isVector()) @@ -83,7 +425,7 @@ TString TType::getCompleteString() const // // Recursively generate mangled names. // -TString TType::buildMangledName() const +const char *TType::buildMangledName() const { TString mangledName; if (isMatrix()) @@ -93,78 +435,132 @@ TString TType::buildMangledName() const switch (type) { - case EbtFloat: - mangledName += 'f'; - break; - case EbtInt: - mangledName += 'i'; - break; - case EbtUInt: - mangledName += 'u'; - break; - case EbtBool: - mangledName += 'b'; - break; - case EbtSampler2D: - mangledName += "s2"; - break; - case EbtSampler3D: - mangledName += "s3"; - break; - case EbtSamplerCube: - mangledName += "sC"; - break; - case EbtSampler2DArray: - mangledName += "s2a"; - break; - case EbtSamplerExternalOES: - mangledName += "sext"; - break; - case EbtSampler2DRect: - mangledName += "s2r"; - break; - case EbtISampler2D: - mangledName += "is2"; - break; - case EbtISampler3D: - mangledName += "is3"; - break; - case EbtISamplerCube: - mangledName += "isC"; - break; - case EbtISampler2DArray: - mangledName += "is2a"; - break; - case EbtUSampler2D: - mangledName += "us2"; - break; - case EbtUSampler3D: - mangledName += "us3"; - break; - case EbtUSamplerCube: - mangledName += "usC"; - break; - case EbtUSampler2DArray: - mangledName += "us2a"; - break; - case EbtSampler2DShadow: - mangledName += "s2s"; - break; - case EbtSamplerCubeShadow: - mangledName += "sCs"; - break; - case EbtSampler2DArrayShadow: - mangledName += "s2as"; - break; - case EbtStruct: - mangledName += structure->mangledName(); - break; - case EbtInterfaceBlock: - mangledName += interfaceBlock->mangledName(); - break; - default: - // EbtVoid, EbtAddress and non types - break; + case EbtFloat: + mangledName += 'f'; + break; + case EbtInt: + mangledName += 'i'; + break; + case EbtUInt: + mangledName += 'u'; + break; + case EbtBool: + mangledName += 'b'; + break; + case EbtYuvCscStandardEXT: + mangledName += "ycs"; + break; + case EbtSampler2D: + mangledName += "s2"; + break; + case EbtSampler3D: + mangledName += "s3"; + break; + case EbtSamplerCube: + mangledName += "sC"; + break; + case EbtSampler2DArray: + mangledName += "s2a"; + break; + case EbtSamplerExternalOES: + mangledName += "sext"; + break; + case EbtSamplerExternal2DY2YEXT: + mangledName += "sext2y2y"; + break; + case EbtSampler2DRect: + mangledName += "s2r"; + break; + case EbtSampler2DMS: + mangledName += "s2ms"; + break; + case EbtISampler2D: + mangledName += "is2"; + break; + case EbtISampler3D: + mangledName += "is3"; + break; + case EbtISamplerCube: + mangledName += "isC"; + break; + case EbtISampler2DArray: + mangledName += "is2a"; + break; + case EbtISampler2DMS: + mangledName += "is2ms"; + break; + case EbtUSampler2D: + mangledName += "us2"; + break; + case EbtUSampler3D: + mangledName += "us3"; + break; + case EbtUSamplerCube: + mangledName += "usC"; + break; + case EbtUSampler2DArray: + mangledName += "us2a"; + break; + case EbtUSampler2DMS: + mangledName += "us2ms"; + break; + case EbtSampler2DShadow: + mangledName += "s2s"; + break; + case EbtSamplerCubeShadow: + mangledName += "sCs"; + break; + case EbtSampler2DArrayShadow: + mangledName += "s2as"; + break; + case EbtImage2D: + mangledName += "im2"; + break; + case EbtIImage2D: + mangledName += "iim2"; + break; + case EbtUImage2D: + mangledName += "uim2"; + break; + case EbtImage3D: + mangledName += "im3"; + break; + case EbtIImage3D: + mangledName += "iim3"; + break; + case EbtUImage3D: + mangledName += "uim3"; + break; + case EbtImage2DArray: + mangledName += "im2a"; + break; + case EbtIImage2DArray: + mangledName += "iim2a"; + break; + case EbtUImage2DArray: + mangledName += "uim2a"; + break; + case EbtImageCube: + mangledName += "imc"; + break; + case EbtIImageCube: + mangledName += "iimc"; + break; + case EbtUImageCube: + mangledName += "uimc"; + break; + case EbtAtomicCounter: + mangledName += "ac"; + break; + case EbtStruct: + mangledName += mStructure->mangledName(); + break; + case EbtInterfaceBlock: + mangledName += mInterfaceBlock->mangledName(); + break; + default: + // EbtVoid, EbtAddress and non types + break; } if (isMatrix()) @@ -178,15 +574,25 @@ TString TType::buildMangledName() const mangledName += static_cast('0' + getNominalSize()); } - if (isArray()) + if (mArraySizes) { - char buf[20]; - snprintf(buf, sizeof(buf), "%d", arraySize); - mangledName += '['; - mangledName += buf; - mangledName += ']'; + for (unsigned int arraySize : *mArraySizes) + { + char buf[20]; + snprintf(buf, sizeof(buf), "%d", arraySize); + mangledName += '['; + mangledName += buf; + mangledName += ']'; + } } - return mangledName; + + mangledName += ';'; + + // Copy string contents into a pool-allocated buffer, so we never need to call delete. + size_t requiredSize = mangledName.size() + 1; + char *buffer = reinterpret_cast(GetGlobalPoolAllocator()->allocate(requiredSize)); + memcpy(buffer, mangledName.c_str(), requiredSize); + return buffer; } size_t TType::getObjectSize() const @@ -194,23 +600,265 @@ size_t TType::getObjectSize() const size_t totalSize; if (getBasicType() == EbtStruct) - totalSize = structure->objectSize(); + totalSize = mStructure->objectSize(); else totalSize = primarySize * secondarySize; - if (isArray()) + if (totalSize == 0) + return 0; + + if (mArraySizes) { - // TODO: getArraySize() returns an int, not a size_t - size_t currentArraySize = getArraySize(); - if (currentArraySize > INT_MAX / totalSize) - totalSize = INT_MAX; - else - totalSize *= currentArraySize; + for (size_t arraySize : *mArraySizes) + { + if (arraySize > INT_MAX / totalSize) + totalSize = INT_MAX; + else + totalSize *= arraySize; + } } return totalSize; } +int TType::getLocationCount() const +{ + int count = 1; + + if (getBasicType() == EbtStruct) + { + count = mStructure->getLocationCount(); + } + + if (count == 0) + { + return 0; + } + + if (mArraySizes) + { + for (unsigned int arraySize : *mArraySizes) + { + if (arraySize > static_cast(std::numeric_limits::max() / count)) + { + count = std::numeric_limits::max(); + } + else + { + count *= static_cast(arraySize); + } + } + } + + return count; +} + +unsigned int TType::getArraySizeProduct() const +{ + if (!mArraySizes) + return 1u; + + unsigned int product = 1u; + + for (unsigned int arraySize : *mArraySizes) + { + product *= arraySize; + } + return product; +} + +bool TType::isUnsizedArray() const +{ + if (!mArraySizes) + return false; + + for (unsigned int arraySize : *mArraySizes) + { + if (arraySize == 0u) + { + return true; + } + } + return false; +} + +bool TType::sameNonArrayType(const TType &right) const +{ + return (type == right.type && primarySize == right.primarySize && + secondarySize == right.secondarySize && mStructure == right.mStructure); +} + +bool TType::isElementTypeOf(const TType &arrayType) const +{ + if (!sameNonArrayType(arrayType)) + { + return false; + } + if (arrayType.getNumArraySizes() != getNumArraySizes() + 1u) + { + return false; + } + if (isArray()) + { + for (size_t i = 0; i < mArraySizes->size(); ++i) + { + if ((*mArraySizes)[i] != (*arrayType.mArraySizes)[i]) + { + return false; + } + } + } + return true; +} + +void TType::sizeUnsizedArrays(const TVector *newArraySizes) +{ + size_t newArraySizesSize = newArraySizes ? newArraySizes->size() : 0; + for (size_t i = 0u; i < getNumArraySizes(); ++i) + { + if ((*mArraySizes)[i] == 0) + { + if (i < newArraySizesSize) + { + ASSERT(newArraySizes != nullptr); + (*mArraySizes)[i] = (*newArraySizes)[i]; + } + else + { + (*mArraySizes)[i] = 1u; + } + } + } + invalidateMangledName(); +} + +void TType::sizeOutermostUnsizedArray(unsigned int arraySize) +{ + ASSERT(isArray()); + ASSERT(mArraySizes->back() == 0u); + mArraySizes->back() = arraySize; +} + +void TType::setBasicType(TBasicType t) +{ + if (type != t) + { + type = t; + invalidateMangledName(); + } +} + +void TType::setPrimarySize(unsigned char ps) +{ + if (primarySize != ps) + { + ASSERT(ps <= 4); + primarySize = ps; + invalidateMangledName(); + } +} + +void TType::setSecondarySize(unsigned char ss) +{ + if (secondarySize != ss) + { + ASSERT(ss <= 4); + secondarySize = ss; + invalidateMangledName(); + } +} + +void TType::makeArray(unsigned int s) +{ + if (!mArraySizes) + mArraySizes = new TVector(); + + mArraySizes->push_back(s); + invalidateMangledName(); +} + +void TType::makeArrays(const TVector &sizes) +{ + if (!mArraySizes) + mArraySizes = new TVector(); + + mArraySizes->insert(mArraySizes->end(), sizes.begin(), sizes.end()); + invalidateMangledName(); +} + +void TType::setArraySize(size_t arrayDimension, unsigned int s) +{ + ASSERT(mArraySizes != nullptr); + ASSERT(arrayDimension < mArraySizes->size()); + if (mArraySizes->at(arrayDimension) != s) + { + (*mArraySizes)[arrayDimension] = s; + invalidateMangledName(); + } +} + +void TType::toArrayElementType() +{ + ASSERT(mArraySizes != nullptr); + if (mArraySizes->size() > 0) + { + mArraySizes->pop_back(); + invalidateMangledName(); + } +} + +void TType::setInterfaceBlock(TInterfaceBlock *interfaceBlockIn) +{ + if (mInterfaceBlock != interfaceBlockIn) + { + mInterfaceBlock = interfaceBlockIn; + invalidateMangledName(); + } +} + +void TType::setStruct(TStructure *s) +{ + if (mStructure != s) + { + mStructure = s; + invalidateMangledName(); + } +} + +const char *TType::getMangledName() const +{ + if (mMangledName == nullptr) + { + mMangledName = buildMangledName(); + } + + return mMangledName; +} + +void TType::realize() +{ + getMangledName(); +} + +void TType::invalidateMangledName() +{ + mMangledName = nullptr; +} + +// TStructure implementation. +TStructure::TStructure(TSymbolTable *symbolTable, const TString *name, TFieldList *fields) + : TFieldListCollection(name, fields), + mDeepestNesting(0), + mUniqueId(symbolTable->nextUniqueId()), + mAtGlobalScope(false) +{ +} + +bool TStructure::equals(const TStructure &other) const +{ + return (uniqueId() == other.uniqueId()); +} + bool TStructure::containsArrays() const { for (size_t i = 0; i < mFields->size(); ++i) @@ -244,6 +892,66 @@ bool TStructure::containsSamplers() const return false; } +void TType::createSamplerSymbols(const TString &namePrefix, + const TString &apiNamePrefix, + TVector *outputSymbols, + TMap *outputSymbolsToAPINames, + TSymbolTable *symbolTable) const +{ + if (isStructureContainingSamplers()) + { + if (isArray()) + { + TType elementType(*this); + elementType.toArrayElementType(); + for (unsigned int arrayIndex = 0u; arrayIndex < getOutermostArraySize(); ++arrayIndex) + { + TStringStream elementName; + elementName << namePrefix << "_" << arrayIndex; + TStringStream elementApiName; + elementApiName << apiNamePrefix << "[" << arrayIndex << "]"; + elementType.createSamplerSymbols(elementName.str(), elementApiName.str(), + outputSymbols, outputSymbolsToAPINames, + symbolTable); + } + } + else + { + mStructure->createSamplerSymbols(namePrefix, apiNamePrefix, outputSymbols, + outputSymbolsToAPINames, symbolTable); + } + return; + } + + ASSERT(IsSampler(type)); + TIntermSymbol *symbol = new TIntermSymbol(symbolTable->nextUniqueId(), namePrefix, *this); + outputSymbols->push_back(symbol); + if (outputSymbolsToAPINames) + { + (*outputSymbolsToAPINames)[symbol] = apiNamePrefix; + } +} + +void TStructure::createSamplerSymbols(const TString &namePrefix, + const TString &apiNamePrefix, + TVector *outputSymbols, + TMap *outputSymbolsToAPINames, + TSymbolTable *symbolTable) const +{ + ASSERT(containsSamplers()); + for (auto &field : *mFields) + { + const TType *fieldType = field->type(); + if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers()) + { + TString fieldName = namePrefix + "_" + field->name(); + TString fieldApiName = apiNamePrefix + "." + field->name(); + fieldType->createSamplerSymbols(fieldName, fieldApiName, outputSymbols, + outputSymbolsToAPINames, symbolTable); + } + } +} + TString TFieldListCollection::buildMangledName(const TString &mangledNamePrefix) const { TString mangledName(mangledNamePrefix); @@ -259,9 +967,9 @@ TString TFieldListCollection::buildMangledName(const TString &mangledNamePrefix) size_t TFieldListCollection::calculateObjectSize() const { size_t size = 0; - for (size_t i = 0; i < mFields->size(); ++i) + for (const TField *field : *mFields) { - size_t fieldSize = (*mFields)[i]->type()->getObjectSize(); + size_t fieldSize = field->type()->getObjectSize(); if (fieldSize > INT_MAX - size) size = INT_MAX; else @@ -270,6 +978,24 @@ size_t TFieldListCollection::calculateObjectSize() const return size; } +int TFieldListCollection::getLocationCount() const +{ + int count = 0; + for (const TField *field : *mFields) + { + int fieldCount = field->type()->getLocationCount(); + if (fieldCount > std::numeric_limits::max() - count) + { + count = std::numeric_limits::max(); + } + else + { + count += fieldCount; + } + } + return count; +} + int TStructure::calculateDeepestNesting() const { int maxNesting = 0; @@ -277,3 +1003,70 @@ int TStructure::calculateDeepestNesting() const maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting()); return 1 + maxNesting; } + +// TPublicType implementation. +void TPublicType::initialize(const TTypeSpecifierNonArray &typeSpecifier, TQualifier q) +{ + typeSpecifierNonArray = typeSpecifier; + layoutQualifier = TLayoutQualifier::Create(); + memoryQualifier = TMemoryQualifier::Create(); + qualifier = q; + invariant = false; + precision = EbpUndefined; + arraySizes = nullptr; +} + +void TPublicType::initializeBasicType(TBasicType basicType) +{ + typeSpecifierNonArray.type = basicType; + typeSpecifierNonArray.primarySize = 1; + typeSpecifierNonArray.secondarySize = 1; + layoutQualifier = TLayoutQualifier::Create(); + memoryQualifier = TMemoryQualifier::Create(); + qualifier = EvqTemporary; + invariant = false; + precision = EbpUndefined; + arraySizes = nullptr; +} + +bool TPublicType::isStructureContainingArrays() const +{ + if (!typeSpecifierNonArray.userDef) + { + return false; + } + + return typeSpecifierNonArray.userDef->containsArrays(); +} + +bool TPublicType::isStructureContainingType(TBasicType t) const +{ + if (!typeSpecifierNonArray.userDef) + { + return false; + } + + return typeSpecifierNonArray.userDef->containsType(t); +} + +void TPublicType::setArraySizes(TVector *sizes) +{ + arraySizes = sizes; +} + +bool TPublicType::isArray() const +{ + return arraySizes && !arraySizes->empty(); +} + +void TPublicType::clearArrayness() +{ + arraySizes = nullptr; +} + +bool TPublicType::isAggregate() const +{ + return isArray() || typeSpecifierNonArray.isMatrix() || typeSpecifierNonArray.isVector(); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/Types.h b/src/3rdparty/angle/src/compiler/translator/Types.h index c2968dceba..7dc84c5b1c 100644 --- a/src/3rdparty/angle/src/compiler/translator/Types.h +++ b/src/3rdparty/angle/src/compiler/translator/Types.h @@ -12,41 +12,33 @@ #include "compiler/translator/BaseTypes.h" #include "compiler/translator/Common.h" +#include "compiler/translator/SymbolUniqueId.h" + +namespace sh +{ struct TPublicType; class TType; class TSymbol; +class TIntermSymbol; +class TSymbolTable; class TField : angle::NonCopyable { public: POOL_ALLOCATOR_NEW_DELETE(); TField(TType *type, TString *name, const TSourceLoc &line) - : mType(type), - mName(name), - mLine(line) + : mType(type), mName(name), mLine(line) { } // TODO(alokp): We should only return const type. // Fix it by tweaking grammar. - TType *type() - { - return mType; - } - const TType *type() const - { - return mType; - } + TType *type() { return mType; } + const TType *type() const { return mType; } - const TString &name() const - { - return *mName; - } - const TSourceLoc &line() const - { - return mLine; - } + const TString &name() const { return *mName; } + const TSourceLoc &line() const { return mLine; } private: TType *mType; @@ -58,33 +50,28 @@ typedef TVector TFieldList; inline TFieldList *NewPoolTFieldList() { void *memory = GetGlobalPoolAllocator()->allocate(sizeof(TFieldList)); - return new(memory) TFieldList; + return new (memory) TFieldList; } class TFieldListCollection : angle::NonCopyable { public: - const TString &name() const - { - return *mName; - } - const TFieldList &fields() const - { - return *mFields; - } + const TString &name() const { return *mName; } + const TFieldList &fields() const { return *mFields; } size_t objectSize() const { if (mObjectSize == 0) mObjectSize = calculateObjectSize(); return mObjectSize; - }; + } + + // How many locations the field list consumes as a uniform. + int getLocationCount() const; protected: TFieldListCollection(const TString *name, TFieldList *fields) - : mName(name), - mFields(fields), - mObjectSize(0) + : mName(name), mFields(fields), mObjectSize(0) { } TString buildMangledName(const TString &mangledNamePrefix) const; @@ -102,13 +89,7 @@ class TStructure : public TFieldListCollection { public: POOL_ALLOCATOR_NEW_DELETE(); - TStructure(const TString *name, TFieldList *fields) - : TFieldListCollection(name, fields), - mDeepestNesting(0), - mUniqueId(0), - mAtGlobalScope(false) - { - } + TStructure(TSymbolTable *symbolTable, const TString *name, TFieldList *fields); int deepestNesting() const { @@ -120,28 +101,19 @@ class TStructure : public TFieldListCollection bool containsType(TBasicType t) const; bool containsSamplers() const; + void createSamplerSymbols(const TString &namePrefix, + const TString &apiNamePrefix, + TVector *outputSymbols, + TMap *outputSymbolsToAPINames, + TSymbolTable *symbolTable) const; + bool equals(const TStructure &other) const; - void setUniqueId(int uniqueId) - { - mUniqueId = uniqueId; - } + int uniqueId() const { return mUniqueId.get(); } - int uniqueId() const - { - ASSERT(mUniqueId != 0); - return mUniqueId; - } + void setAtGlobalScope(bool atGlobalScope) { mAtGlobalScope = atGlobalScope; } - void setAtGlobalScope(bool atGlobalScope) - { - mAtGlobalScope = atGlobalScope; - } - - bool atGlobalScope() const - { - return mAtGlobalScope; - } + bool atGlobalScope() const { return mAtGlobalScope; } const TString &mangledName() const { @@ -158,13 +130,13 @@ class TStructure : public TFieldListCollection void setName(const TString &name) { TString *mutableName = const_cast(mName); - *mutableName = name; + *mutableName = name; } int calculateDeepestNesting() const; mutable int mDeepestNesting; - int mUniqueId; + const TSymbolUniqueId mUniqueId; bool mAtGlobalScope; }; @@ -172,40 +144,23 @@ class TInterfaceBlock : public TFieldListCollection { public: POOL_ALLOCATOR_NEW_DELETE(); - TInterfaceBlock(const TString *name, TFieldList *fields, const TString *instanceName, - int arraySize, const TLayoutQualifier &layoutQualifier) + TInterfaceBlock(const TString *name, + TFieldList *fields, + const TString *instanceName, + const TLayoutQualifier &layoutQualifier) : TFieldListCollection(name, fields), mInstanceName(instanceName), - mArraySize(arraySize), mBlockStorage(layoutQualifier.blockStorage), - mMatrixPacking(layoutQualifier.matrixPacking) + mMatrixPacking(layoutQualifier.matrixPacking), + mBinding(layoutQualifier.binding) { } - const TString &instanceName() const - { - return *mInstanceName; - } - bool hasInstanceName() const - { - return mInstanceName != NULL; - } - bool isArray() const - { - return mArraySize > 0; - } - int arraySize() const - { - return mArraySize; - } - TLayoutBlockStorage blockStorage() const - { - return mBlockStorage; - } - TLayoutMatrixPacking matrixPacking() const - { - return mMatrixPacking; - } + const TString &instanceName() const { return *mInstanceName; } + bool hasInstanceName() const { return mInstanceName != nullptr; } + TLayoutBlockStorage blockStorage() const { return mBlockStorage; } + TLayoutMatrixPacking matrixPacking() const { return mMatrixPacking; } + int blockBinding() const { return mBinding; } const TString &mangledName() const { if (mMangledName.empty()) @@ -214,10 +169,10 @@ class TInterfaceBlock : public TFieldListCollection } private: - const TString *mInstanceName; // for interface block instance names - int mArraySize; // 0 if not an array + const TString *mInstanceName; // for interface block instance names TLayoutBlockStorage mBlockStorage; TLayoutMatrixPacking mMatrixPacking; + int mBinding; }; // @@ -227,101 +182,42 @@ class TType { public: POOL_ALLOCATOR_NEW_DELETE(); - TType() - : type(EbtVoid), precision(EbpUndefined), qualifier(EvqGlobal), invariant(false), - layoutQualifier(TLayoutQualifier::create()), - primarySize(0), secondarySize(0), array(false), arraySize(0), - interfaceBlock(nullptr), structure(nullptr) - { - } - TType(TBasicType t, unsigned char ps = 1, unsigned char ss = 1) - : type(t), precision(EbpUndefined), qualifier(EvqGlobal), invariant(false), - layoutQualifier(TLayoutQualifier::create()), - primarySize(ps), secondarySize(ss), array(false), arraySize(0), - interfaceBlock(0), structure(0) - { - } - TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, - unsigned char ps = 1, unsigned char ss = 1, bool a = false) - : type(t), precision(p), qualifier(q), invariant(false), - layoutQualifier(TLayoutQualifier::create()), - primarySize(ps), secondarySize(ss), array(a), arraySize(0), - interfaceBlock(0), structure(0) - { - } + TType(); + explicit TType(TBasicType t, unsigned char ps = 1, unsigned char ss = 1); + TType(TBasicType t, + TPrecision p, + TQualifier q = EvqTemporary, + unsigned char ps = 1, + unsigned char ss = 1); explicit TType(const TPublicType &p); - TType(TStructure *userDef, TPrecision p = EbpUndefined) - : type(EbtStruct), precision(p), qualifier(EvqTemporary), invariant(false), - layoutQualifier(TLayoutQualifier::create()), - primarySize(1), secondarySize(1), array(false), arraySize(0), - interfaceBlock(0), structure(userDef) - { - } - TType(TInterfaceBlock *interfaceBlockIn, TQualifier qualifierIn, - TLayoutQualifier layoutQualifierIn, int arraySizeIn) - : type(EbtInterfaceBlock), precision(EbpUndefined), qualifier(qualifierIn), - invariant(false), layoutQualifier(layoutQualifierIn), - primarySize(1), secondarySize(1), array(arraySizeIn > 0), arraySize(arraySizeIn), - interfaceBlock(interfaceBlockIn), structure(0) - { - } + explicit TType(TStructure *userDef); + TType(TInterfaceBlock *interfaceBlockIn, + TQualifier qualifierIn, + TLayoutQualifier layoutQualifierIn); + TType(const TType &t); + TType &operator=(const TType &t); - TType(const TType &) = default; - TType &operator=(const TType &) = default; + TBasicType getBasicType() const { return type; } + void setBasicType(TBasicType t); - TBasicType getBasicType() const - { - return type; - } - void setBasicType(TBasicType t) - { - if (type != t) - { - type = t; - invalidateMangledName(); - } - } + TPrecision getPrecision() const { return precision; } + void setPrecision(TPrecision p) { precision = p; } - TPrecision getPrecision() const - { - return precision; - } - void setPrecision(TPrecision p) - { - precision = p; - } + TQualifier getQualifier() const { return qualifier; } + void setQualifier(TQualifier q) { qualifier = q; } - TQualifier getQualifier() const - { - return qualifier; - } - void setQualifier(TQualifier q) - { - qualifier = q; - } + bool isInvariant() const { return invariant; } - bool isInvariant() const - { - return invariant; - } + void setInvariant(bool i) { invariant = i; } - TLayoutQualifier getLayoutQualifier() const - { - return layoutQualifier; - } - void setLayoutQualifier(TLayoutQualifier lq) - { - layoutQualifier = lq; - } + TMemoryQualifier getMemoryQualifier() const { return memoryQualifier; } + void setMemoryQualifier(const TMemoryQualifier &mq) { memoryQualifier = mq; } - int getNominalSize() const - { - return primarySize; - } - int getSecondarySize() const - { - return secondarySize; - } + TLayoutQualifier getLayoutQualifier() const { return layoutQualifier; } + void setLayoutQualifier(TLayoutQualifier lq) { layoutQualifier = lq; } + + int getNominalSize() const { return primarySize; } + int getSecondarySize() const { return secondarySize; } int getCols() const { ASSERT(isMatrix()); @@ -332,139 +228,82 @@ class TType ASSERT(isMatrix()); return secondarySize; } - void setPrimarySize(unsigned char ps) - { - if (primarySize != ps) - { - primarySize = ps; - invalidateMangledName(); - } - } - void setSecondarySize(unsigned char ss) - { - if (secondarySize != ss) - { - secondarySize = ss; - invalidateMangledName(); - } - } + void setPrimarySize(unsigned char ps); + void setSecondarySize(unsigned char ss); // Full size of single instance of type size_t getObjectSize() const; - bool isMatrix() const - { - return primarySize > 1 && secondarySize > 1; - } - bool isNonSquareMatrix() const - { - return isMatrix() && primarySize != secondarySize; - } - bool isArray() const - { - return array; - } - bool isUnsizedArray() const - { - return array && arraySize == 0; - } - int getArraySize() const - { - return arraySize; - } - void setArraySize(int s) - { - if (!array || arraySize != s) - { - array = true; - arraySize = s; - invalidateMangledName(); - } - } - void clearArrayness() - { - if (array) - { - array = false; - arraySize = 0; - invalidateMangledName(); - } - } + // Get how many locations this type consumes as a uniform. + int getLocationCount() const; - TInterfaceBlock *getInterfaceBlock() const - { - return interfaceBlock; - } - void setInterfaceBlock(TInterfaceBlock *interfaceBlockIn) - { - if (interfaceBlock != interfaceBlockIn) - { - interfaceBlock = interfaceBlockIn; - invalidateMangledName(); - } - } - bool isInterfaceBlock() const - { - return type == EbtInterfaceBlock; + bool isMatrix() const { return primarySize > 1 && secondarySize > 1; } + bool isNonSquareMatrix() const { return isMatrix() && primarySize != secondarySize; } + bool isArray() const { return mArraySizes != nullptr && !mArraySizes->empty(); } + bool isArrayOfArrays() const { return isArray() && mArraySizes->size() > 1u; } + size_t getNumArraySizes() const { return isArray() ? mArraySizes->size() : 0; } + const TVector *getArraySizes() const { return mArraySizes; } + unsigned int getArraySizeProduct() const; + bool isUnsizedArray() const; + unsigned int getOutermostArraySize() const { + ASSERT(isArray()); + return mArraySizes->back(); } + void makeArray(unsigned int s); - bool isVector() const - { - return primarySize > 1 && secondarySize == 1; - } + // sizes contain new outermost array sizes. + void makeArrays(const TVector &sizes); + // Here, the array dimension value 0 corresponds to the innermost array. + void setArraySize(size_t arrayDimension, unsigned int s); + + // Will set unsized array sizes according to newArraySizes. In case there are more + // unsized arrays than there are sizes in newArraySizes, defaults to setting any + // remaining array sizes to 1. + void sizeUnsizedArrays(const TVector *newArraySizes); + + // Will size the outermost array according to arraySize. + void sizeOutermostUnsizedArray(unsigned int arraySize); + + // Note that the array element type might still be an array type in GLSL ES version >= 3.10. + void toArrayElementType(); + + TInterfaceBlock *getInterfaceBlock() const { return mInterfaceBlock; } + void setInterfaceBlock(TInterfaceBlock *interfaceBlockIn); + bool isInterfaceBlock() const { return type == EbtInterfaceBlock; } + + bool isVector() const { return primarySize > 1 && secondarySize == 1; } bool isScalar() const { - return primarySize == 1 && secondarySize == 1 && !structure; - } - bool isScalarInt() const - { - return isScalar() && (type == EbtInt || type == EbtUInt); + return primarySize == 1 && secondarySize == 1 && !mStructure && !isArray(); } + bool isScalarFloat() const { return isScalar() && type == EbtFloat; } + bool isScalarInt() const { return isScalar() && (type == EbtInt || type == EbtUInt); } - TStructure *getStruct() const - { - return structure; - } - void setStruct(TStructure *s) - { - if (structure != s) - { - structure = s; - invalidateMangledName(); - } - } + bool canBeConstructed() const; - const TString &getMangledName() const - { - if (mangled.empty()) - { - mangled = buildMangledName(); - mangled += ';'; - } + TStructure *getStruct() { return mStructure; } + const TStructure *getStruct() const { return mStructure; } + void setStruct(TStructure *s); - return mangled; - } + const char *getMangledName() const; + + bool sameNonArrayType(const TType &right) const; + + // Returns true if arrayType is an array made of this type. + bool isElementTypeOf(const TType &arrayType) const; - bool sameElementType(const TType &right) const - { - return type == right.type && - primarySize == right.primarySize && - secondarySize == right.secondarySize && - structure == right.structure; - } bool operator==(const TType &right) const { - return type == right.type && - primarySize == right.primarySize && - secondarySize == right.secondarySize && - array == right.array && (!array || arraySize == right.arraySize) && - structure == right.structure; + size_t numArraySizesL = getNumArraySizes(); + size_t numArraySizesR = right.getNumArraySizes(); + bool arraySizesEqual = numArraySizesL == numArraySizesR && + (numArraySizesL == 0 || *mArraySizes == *right.mArraySizes); + return type == right.type && primarySize == right.primarySize && + secondarySize == right.secondarySize && arraySizesEqual && + mStructure == right.mStructure; // don't check the qualifier, it's not ever what's being sought after } - bool operator!=(const TType &right) const - { - return !operator==(right); - } + bool operator!=(const TType &right) const { return !operator==(right); } bool operator<(const TType &right) const { if (type != right.type) @@ -473,28 +312,28 @@ class TType return primarySize < right.primarySize; if (secondarySize != right.secondarySize) return secondarySize < right.secondarySize; - if (array != right.array) - return array < right.array; - if (arraySize != right.arraySize) - return arraySize < right.arraySize; - if (structure != right.structure) - return structure < right.structure; + size_t numArraySizesL = getNumArraySizes(); + size_t numArraySizesR = right.getNumArraySizes(); + if (numArraySizesL != numArraySizesR) + return numArraySizesL < numArraySizesR; + for (size_t i = 0; i < numArraySizesL; ++i) + { + if ((*mArraySizes)[i] != (*right.mArraySizes)[i]) + return (*mArraySizes)[i] < (*right.mArraySizes)[i]; + } + if (mStructure != right.mStructure) + return mStructure < right.mStructure; return false; } - const char *getBasicString() const - { - return ::getBasicString(type); - } - const char *getPrecisionString() const - { - return ::getPrecisionString(precision); - } - const char *getQualifierString() const - { - return ::getQualifierString(qualifier); - } + const char *getBasicString() const { return sh::getBasicString(type); } + + const char *getPrecisionString() const { return sh::getPrecisionString(precision); } + const char *getQualifierString() const { return sh::getQualifierString(qualifier); } + + const char *getBuiltInTypeNameString() const; + TString getCompleteString() const; // If this type is a struct, returns the deepest struct nesting of @@ -509,54 +348,112 @@ class TType // For type "nesting2", this method would return 2 -- the number // of structures through which indirection must occur to reach the // deepest field (nesting2.field1.position). - int getDeepestStructNesting() const - { - return structure ? structure->deepestNesting() : 0; - } + int getDeepestStructNesting() const { return mStructure ? mStructure->deepestNesting() : 0; } + + bool isNamelessStruct() const { return mStructure && mStructure->name() == ""; } bool isStructureContainingArrays() const { - return structure ? structure->containsArrays() : false; + return mStructure ? mStructure->containsArrays() : false; } bool isStructureContainingType(TBasicType t) const { - return structure ? structure->containsType(t) : false; + return mStructure ? mStructure->containsType(t) : false; } bool isStructureContainingSamplers() const { - return structure ? structure->containsSamplers() : false; + return mStructure ? mStructure->containsSamplers() : false; } + bool isStructSpecifier() const { return mIsStructSpecifier; } + + void createSamplerSymbols(const TString &namePrefix, + const TString &apiNamePrefix, + TVector *outputSymbols, + TMap *outputSymbolsToAPINames, + TSymbolTable *symbolTable) const; + // Initializes all lazily-initialized members. - void realize() - { - getMangledName(); - } + void realize(); private: - void invalidateMangledName() { mangled = ""; } - TString buildMangledName() const; - size_t getStructSize() const; + void invalidateMangledName(); + const char *buildMangledName() const; TBasicType type; TPrecision precision; TQualifier qualifier; bool invariant; + TMemoryQualifier memoryQualifier; TLayoutQualifier layoutQualifier; - unsigned char primarySize; // size of vector or cols matrix - unsigned char secondarySize; // rows of a matrix - bool array; - int arraySize; + unsigned char primarySize; // size of vector or cols matrix + unsigned char secondarySize; // rows of a matrix - // 0 unless this is an interface block, or interface block member variable - TInterfaceBlock *interfaceBlock; + // Used to make an array type. Outermost array size is stored at the end of the vector. Having 0 + // in this vector means an unsized array. + TVector *mArraySizes; + + // This is set only in the following two cases: + // 1) Represents an interface block. + // 2) Represents the member variable of an unnamed interface block. + // It's nullptr also for members of named interface blocks. + TInterfaceBlock *mInterfaceBlock; // 0 unless this is a struct - TStructure *structure; + TStructure *mStructure; + bool mIsStructSpecifier; - mutable TString mangled; + mutable const char *mMangledName; +}; + +// TTypeSpecifierNonArray stores all of the necessary fields for type_specifier_nonarray from the +// grammar +struct TTypeSpecifierNonArray +{ + TBasicType type; + unsigned char primarySize; // size of vector or cols of matrix + unsigned char secondarySize; // rows of matrix + TStructure *userDef; + TSourceLoc line; + + // true if the type was defined by a struct specifier rather than a reference to a type name. + bool isStructSpecifier; + + void initialize(TBasicType aType, const TSourceLoc &aLine) + { + ASSERT(aType != EbtStruct); + type = aType; + primarySize = 1; + secondarySize = 1; + userDef = nullptr; + line = aLine; + isStructSpecifier = false; + } + + void initializeStruct(TStructure *aUserDef, bool aIsStructSpecifier, const TSourceLoc &aLine) + { + type = EbtStruct; + primarySize = 1; + secondarySize = 1; + userDef = aUserDef; + line = aLine; + isStructSpecifier = aIsStructSpecifier; + } + + void setAggregate(unsigned char size) { primarySize = size; } + + void setMatrix(unsigned char columns, unsigned char rows) + { + ASSERT(columns > 1 && rows > 1 && columns <= 4 && rows <= 4); + primarySize = columns; + secondarySize = rows; + } + + bool isMatrix() const { return primarySize > 1 && secondarySize > 1; } + + bool isVector() const { return primarySize > 1 && secondarySize == 1; } }; // @@ -570,115 +467,43 @@ class TType // struct TPublicType { - TBasicType type; + // Must have a trivial default constructor since it is used in YYSTYPE. + TPublicType() = default; + + void initialize(const TTypeSpecifierNonArray &typeSpecifier, TQualifier q); + void initializeBasicType(TBasicType basicType); + + TBasicType getBasicType() const { return typeSpecifierNonArray.type; } + void setBasicType(TBasicType basicType) { typeSpecifierNonArray.type = basicType; } + + unsigned char getPrimarySize() const { return typeSpecifierNonArray.primarySize; } + unsigned char getSecondarySize() const { return typeSpecifierNonArray.secondarySize; } + + TStructure *getUserDef() const { return typeSpecifierNonArray.userDef; } + const TSourceLoc &getLine() const { return typeSpecifierNonArray.line; } + + bool isStructSpecifier() const { return typeSpecifierNonArray.isStructSpecifier; } + + bool isStructureContainingArrays() const; + bool isStructureContainingType(TBasicType t) const; + void setArraySizes(TVector *sizes); + bool isArray() const; + void clearArrayness(); + bool isAggregate() const; + + TTypeSpecifierNonArray typeSpecifierNonArray; TLayoutQualifier layoutQualifier; + TMemoryQualifier memoryQualifier; TQualifier qualifier; bool invariant; TPrecision precision; - unsigned char primarySize; // size of vector or cols of matrix - unsigned char secondarySize; // rows of matrix - bool array; - int arraySize; - TType *userDef; - TSourceLoc line; - // true if the type was defined by a struct specifier rather than a reference to a type name. - bool isStructSpecifier; - - void setBasic(TBasicType bt, TQualifier q, const TSourceLoc &ln) - { - type = bt; - layoutQualifier = TLayoutQualifier::create(); - qualifier = q; - invariant = false; - precision = EbpUndefined; - primarySize = 1; - secondarySize = 1; - array = false; - arraySize = 0; - userDef = 0; - line = ln; - isStructSpecifier = false; - } - - void setAggregate(unsigned char size) - { - primarySize = size; - } - - void setMatrix(unsigned char c, unsigned char r) - { - ASSERT(c > 1 && r > 1 && c <= 4 && r <= 4); - primarySize = c; - secondarySize = r; - } - - bool isUnsizedArray() const - { - return array && arraySize == 0; - } - void setArraySize(int s) - { - array = true; - arraySize = s; - } - void clearArrayness() - { - array = false; - arraySize = 0; - } - - bool isStructureContainingArrays() const - { - if (!userDef) - { - return false; - } - - return userDef->isStructureContainingArrays(); - } - - bool isStructureContainingType(TBasicType t) const - { - if (!userDef) - { - return false; - } - - return userDef->isStructureContainingType(t); - } - - bool isMatrix() const - { - return primarySize > 1 && secondarySize > 1; - } - - bool isVector() const - { - return primarySize > 1 && secondarySize == 1; - } - - int getCols() const - { - ASSERT(isMatrix()); - return primarySize; - } - - int getRows() const - { - ASSERT(isMatrix()); - return secondarySize; - } - - int getNominalSize() const - { - return primarySize; - } - - bool isAggregate() const - { - return array || isMatrix() || isVector(); - } + // Either nullptr or empty in case the type is not an array. The last element is the outermost + // array size. Note that due to bison restrictions, copies of the public type created by the + // copy constructor share the same arraySizes pointer. + const TVector *arraySizes; }; -#endif // COMPILER_TRANSLATOR_TYPES_H_ +} // namespace sh + +#endif // COMPILER_TRANSLATOR_TYPES_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuit.cpp b/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuit.cpp deleted file mode 100644 index f79f9dd7fb..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuit.cpp +++ /dev/null @@ -1,185 +0,0 @@ -// -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// UnfoldShortCircuit is an AST traverser to output short-circuiting operators as if-else statements. -// The results are assigned to s# temporaries, which are used by the main translator instead of -// the original expression. -// - -#include "compiler/translator/UnfoldShortCircuit.h" - -#include "compiler/translator/InfoSink.h" -#include "compiler/translator/OutputHLSL.h" -#include "compiler/translator/UtilsHLSL.h" - -namespace sh -{ -UnfoldShortCircuit::UnfoldShortCircuit(OutputHLSL *outputHLSL) : mOutputHLSL(outputHLSL) -{ - mTemporaryIndex = 0; -} - -void UnfoldShortCircuit::traverse(TIntermNode *node) -{ - int rewindIndex = mTemporaryIndex; - node->traverse(this); - mTemporaryIndex = rewindIndex; -} - -bool UnfoldShortCircuit::visitBinary(Visit visit, TIntermBinary *node) -{ - TInfoSinkBase &out = mOutputHLSL->getInfoSink(); - - // If our right node doesn't have side effects, we know we don't need to unfold this - // expression: there will be no short-circuiting side effects to avoid - // (note: unfolding doesn't depend on the left node -- it will always be evaluated) - if (!node->getRight()->hasSideEffects()) - { - return true; - } - - switch (node->getOp()) - { - case EOpLogicalOr: - // "x || y" is equivalent to "x ? true : y", which unfolds to "bool s; if(x) s = true; else s = y;", - // and then further simplifies down to "bool s = x; if(!s) s = y;". - { - int i = mTemporaryIndex; - - out << "bool s" << i << ";\n"; - - out << "{\n"; - - mTemporaryIndex = i + 1; - node->getLeft()->traverse(this); - out << "s" << i << " = "; - mTemporaryIndex = i + 1; - node->getLeft()->traverse(mOutputHLSL); - out << ";\n"; - out << "if (!s" << i << ")\n" - "{\n"; - mTemporaryIndex = i + 1; - node->getRight()->traverse(this); - out << " s" << i << " = "; - mTemporaryIndex = i + 1; - node->getRight()->traverse(mOutputHLSL); - out << ";\n" - "}\n"; - - out << "}\n"; - - mTemporaryIndex = i + 1; - } - return false; - case EOpLogicalAnd: - // "x && y" is equivalent to "x ? y : false", which unfolds to "bool s; if(x) s = y; else s = false;", - // and then further simplifies down to "bool s = x; if(s) s = y;". - { - int i = mTemporaryIndex; - - out << "bool s" << i << ";\n"; - - out << "{\n"; - - mTemporaryIndex = i + 1; - node->getLeft()->traverse(this); - out << "s" << i << " = "; - mTemporaryIndex = i + 1; - node->getLeft()->traverse(mOutputHLSL); - out << ";\n"; - out << "if (s" << i << ")\n" - "{\n"; - mTemporaryIndex = i + 1; - node->getRight()->traverse(this); - out << " s" << i << " = "; - mTemporaryIndex = i + 1; - node->getRight()->traverse(mOutputHLSL); - out << ";\n" - "}\n"; - - out << "}\n"; - - mTemporaryIndex = i + 1; - } - return false; - default: - return true; - } -} - -bool UnfoldShortCircuit::visitSelection(Visit visit, TIntermSelection *node) -{ - TInfoSinkBase &out = mOutputHLSL->getInfoSink(); - - // Unfold "b ? x : y" into "type s; if(b) s = x; else s = y;" - if (node->usesTernaryOperator()) - { - int i = mTemporaryIndex; - - out << TypeString(node->getType()) << " s" << i << ";\n"; - - out << "{\n"; - - mTemporaryIndex = i + 1; - node->getCondition()->traverse(this); - out << "if ("; - mTemporaryIndex = i + 1; - node->getCondition()->traverse(mOutputHLSL); - out << ")\n" - "{\n"; - mTemporaryIndex = i + 1; - node->getTrueBlock()->traverse(this); - out << " s" << i << " = "; - mTemporaryIndex = i + 1; - node->getTrueBlock()->traverse(mOutputHLSL); - out << ";\n" - "}\n" - "else\n" - "{\n"; - mTemporaryIndex = i + 1; - node->getFalseBlock()->traverse(this); - out << " s" << i << " = "; - mTemporaryIndex = i + 1; - node->getFalseBlock()->traverse(mOutputHLSL); - out << ";\n" - "}\n"; - - out << "}\n"; - - mTemporaryIndex = i + 1; - } - - return false; -} - -bool UnfoldShortCircuit::visitLoop(Visit visit, TIntermLoop *node) -{ - int rewindIndex = mTemporaryIndex; - - if (node->getInit()) - { - node->getInit()->traverse(this); - } - - if (node->getCondition()) - { - node->getCondition()->traverse(this); - } - - if (node->getExpression()) - { - node->getExpression()->traverse(this); - } - - mTemporaryIndex = rewindIndex; - - return false; -} - -int UnfoldShortCircuit::getNextTemporaryIndex() -{ - return mTemporaryIndex++; -} -} diff --git a/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuit.h b/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuit.h deleted file mode 100644 index eaceb0a0b3..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuit.h +++ /dev/null @@ -1,38 +0,0 @@ -// -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// UnfoldShortCircuit is an AST traverser to output short-circuiting operators as if-else statements -// - -#ifndef COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUIT_H_ -#define COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUIT_H_ - -#include "compiler/translator/IntermNode.h" -#include "compiler/translator/ParseContext.h" - -namespace sh -{ -class OutputHLSL; - -class UnfoldShortCircuit : public TIntermTraverser -{ - public: - UnfoldShortCircuit(OutputHLSL *outputHLSL); - - void traverse(TIntermNode *node); - bool visitBinary(Visit visit, TIntermBinary*); - bool visitSelection(Visit visit, TIntermSelection *node); - bool visitLoop(Visit visit, TIntermLoop *node); - - int getNextTemporaryIndex(); - - protected: - OutputHLSL *const mOutputHLSL; - - int mTemporaryIndex; -}; -} - -#endif // COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUIT_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp b/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp index e50bf202ef..4e4653bbe5 100644 --- a/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp +++ b/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitAST.cpp @@ -6,52 +6,54 @@ #include "compiler/translator/UnfoldShortCircuitAST.h" +namespace sh +{ + namespace { // "x || y" is equivalent to "x ? true : y". -TIntermSelection *UnfoldOR(TIntermTyped *x, TIntermTyped *y) +TIntermTernary *UnfoldOR(TIntermTyped *x, TIntermTyped *y) { - const TType boolType(EbtBool, EbpUndefined); TConstantUnion *u = new TConstantUnion; u->setBConst(true); - TIntermConstantUnion *trueNode = new TIntermConstantUnion( - u, TType(EbtBool, EbpUndefined, EvqConst, 1)); - return new TIntermSelection(x, trueNode, y, boolType); + TIntermConstantUnion *trueNode = + new TIntermConstantUnion(u, TType(EbtBool, EbpUndefined, EvqConst, 1)); + return new TIntermTernary(x, trueNode, y); } // "x && y" is equivalent to "x ? y : false". -TIntermSelection *UnfoldAND(TIntermTyped *x, TIntermTyped *y) +TIntermTernary *UnfoldAND(TIntermTyped *x, TIntermTyped *y) { - const TType boolType(EbtBool, EbpUndefined); TConstantUnion *u = new TConstantUnion; u->setBConst(false); - TIntermConstantUnion *falseNode = new TIntermConstantUnion( - u, TType(EbtBool, EbpUndefined, EvqConst, 1)); - return new TIntermSelection(x, y, falseNode, boolType); + TIntermConstantUnion *falseNode = + new TIntermConstantUnion(u, TType(EbtBool, EbpUndefined, EvqConst, 1)); + return new TIntermTernary(x, y, falseNode); } } // namespace anonymous bool UnfoldShortCircuitAST::visitBinary(Visit visit, TIntermBinary *node) { - TIntermSelection *replacement = NULL; + TIntermTernary *replacement = nullptr; switch (node->getOp()) { - case EOpLogicalOr: - replacement = UnfoldOR(node->getLeft(), node->getRight()); - break; - case EOpLogicalAnd: - replacement = UnfoldAND(node->getLeft(), node->getRight()); - break; - default: - break; + case EOpLogicalOr: + replacement = UnfoldOR(node->getLeft(), node->getRight()); + break; + case EOpLogicalAnd: + replacement = UnfoldAND(node->getLeft(), node->getRight()); + break; + default: + break; } if (replacement) { - mReplacements.push_back( - NodeUpdateEntry(getParentNode(), node, replacement, false)); + queueReplacement(replacement, OriginalNode::IS_DROPPED); } return true; } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitAST.h b/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitAST.h index b92a4e9152..7f377e6f15 100644 --- a/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitAST.h +++ b/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitAST.h @@ -11,7 +11,10 @@ #define COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUITAST_H_ #include "common/angleutils.h" -#include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermTraverse.h" + +namespace sh +{ // This traverser identifies all the short circuit binary nodes that need to // be replaced, and creates the corresponding replacement nodes. However, @@ -20,12 +23,11 @@ class UnfoldShortCircuitAST : public TIntermTraverser { public: - UnfoldShortCircuitAST() - : TIntermTraverser(true, false, false) - { - } + UnfoldShortCircuitAST() : TIntermTraverser(true, false, false) {} bool visitBinary(Visit visit, TIntermBinary *) override; }; +} // namespace sh + #endif // COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUITAST_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitToIf.cpp b/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitToIf.cpp index be23b524d7..774f1fc704 100644 --- a/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitToIf.cpp +++ b/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitToIf.cpp @@ -3,14 +3,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// UnfoldShortCircuitToIf is an AST traverser to convert short-circuiting operators to if-else statements. +// UnfoldShortCircuitToIf is an AST traverser to convert short-circuiting operators to if-else +// statements. // The results are assigned to s# temporaries, which are used by the main translator instead of // the original expression. // #include "compiler/translator/UnfoldShortCircuitToIf.h" -#include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermNodePatternMatcher.h" +#include "compiler/translator/IntermTraverse.h" + +namespace sh +{ namespace { @@ -19,44 +24,26 @@ namespace class UnfoldShortCircuitTraverser : public TIntermTraverser { public: - UnfoldShortCircuitTraverser(); + UnfoldShortCircuitTraverser(TSymbolTable *symbolTable); bool visitBinary(Visit visit, TIntermBinary *node) override; - bool visitAggregate(Visit visit, TIntermAggregate *node) override; - bool visitSelection(Visit visit, TIntermSelection *node) override; - bool visitLoop(Visit visit, TIntermLoop *node) override; + bool visitTernary(Visit visit, TIntermTernary *node) override; void nextIteration(); bool foundShortCircuit() const { return mFoundShortCircuit; } protected: - // Check if the traversal is inside a loop condition or expression, in which case the unfolded - // expression needs to be copied inside the loop. Returns true if the copying is done, in which - // case no further unfolding should be done on the same traversal. - // The parameters are the node that will be unfolded to multiple statements and so can't remain - // inside a loop condition, and its parent. - bool copyLoopConditionOrExpression(TIntermNode *parent, TIntermTyped *node); - // Marked to true once an operation that needs to be unfolded has been found. // After that, no more unfolding is performed on that traversal. bool mFoundShortCircuit; - // Set to the loop node while a loop condition or expression is being traversed. - TIntermLoop *mParentLoop; - // Parent of the loop node while a loop condition or expression is being traversed. - TIntermNode *mLoopParent; - - bool mInLoopCondition; - bool mInLoopExpression; + IntermNodePatternMatcher mPatternToUnfoldMatcher; }; -UnfoldShortCircuitTraverser::UnfoldShortCircuitTraverser() - : TIntermTraverser(true, false, true), +UnfoldShortCircuitTraverser::UnfoldShortCircuitTraverser(TSymbolTable *symbolTable) + : TIntermTraverser(true, false, true, symbolTable), mFoundShortCircuit(false), - mParentLoop(nullptr), - mLoopParent(nullptr), - mInLoopCondition(false), - mInLoopExpression(false) + mPatternToUnfoldMatcher(IntermNodePatternMatcher::kUnfoldedShortCircuitExpression) { } @@ -64,19 +51,23 @@ bool UnfoldShortCircuitTraverser::visitBinary(Visit visit, TIntermBinary *node) { if (mFoundShortCircuit) return false; + + if (visit != PreVisit) + return true; + + if (!mPatternToUnfoldMatcher.match(node, getParentNode())) + return true; + // If our right node doesn't have side effects, we know we don't need to unfold this // expression: there will be no short-circuiting side effects to avoid // (note: unfolding doesn't depend on the left node -- it will always be evaluated) - if (!node->getRight()->hasSideEffects()) - { - return true; - } + ASSERT(node->getRight()->hasSideEffects()); + + mFoundShortCircuit = true; switch (node->getOp()) { - case EOpLogicalOr: - mFoundShortCircuit = true; - if (!copyLoopConditionOrExpression(getParentNode(), node)) + case EOpLogicalOr: { // "x || y" is equivalent to "x ? true : y", which unfolds to "bool s; if(x) s = true; // else s = y;", @@ -88,24 +79,21 @@ bool UnfoldShortCircuitTraverser::visitBinary(Visit visit, TIntermBinary *node) ASSERT(node->getLeft()->getType() == boolType); insertions.push_back(createTempInitDeclaration(node->getLeft())); - TIntermAggregate *assignRightBlock = new TIntermAggregate(EOpSequence); + TIntermBlock *assignRightBlock = new TIntermBlock(); ASSERT(node->getRight()->getType() == boolType); assignRightBlock->getSequence()->push_back(createTempAssignment(node->getRight())); - TIntermUnary *notTempSymbol = new TIntermUnary(EOpLogicalNot, boolType); - notTempSymbol->setOperand(createTempSymbol(boolType)); - TIntermSelection *ifNode = new TIntermSelection(notTempSymbol, assignRightBlock, nullptr); + TIntermUnary *notTempSymbol = + new TIntermUnary(EOpLogicalNot, createTempSymbol(boolType)); + TIntermIfElse *ifNode = new TIntermIfElse(notTempSymbol, assignRightBlock, nullptr); insertions.push_back(ifNode); insertStatementsInParentBlock(insertions); - NodeUpdateEntry replaceVariable(getParentNode(), node, createTempSymbol(boolType), false); - mReplacements.push_back(replaceVariable); + queueReplacement(createTempSymbol(boolType), OriginalNode::IS_DROPPED); + return false; } - return false; - case EOpLogicalAnd: - mFoundShortCircuit = true; - if (!copyLoopConditionOrExpression(getParentNode(), node)) + case EOpLogicalAnd: { // "x && y" is equivalent to "x ? y : false", which unfolds to "bool s; if(x) s = y; // else s = false;", @@ -116,246 +104,75 @@ bool UnfoldShortCircuitTraverser::visitBinary(Visit visit, TIntermBinary *node) ASSERT(node->getLeft()->getType() == boolType); insertions.push_back(createTempInitDeclaration(node->getLeft())); - TIntermAggregate *assignRightBlock = new TIntermAggregate(EOpSequence); + TIntermBlock *assignRightBlock = new TIntermBlock(); ASSERT(node->getRight()->getType() == boolType); assignRightBlock->getSequence()->push_back(createTempAssignment(node->getRight())); - TIntermSelection *ifNode = new TIntermSelection(createTempSymbol(boolType), assignRightBlock, nullptr); + TIntermIfElse *ifNode = + new TIntermIfElse(createTempSymbol(boolType), assignRightBlock, nullptr); insertions.push_back(ifNode); insertStatementsInParentBlock(insertions); - NodeUpdateEntry replaceVariable(getParentNode(), node, createTempSymbol(boolType), false); - mReplacements.push_back(replaceVariable); + queueReplacement(createTempSymbol(boolType), OriginalNode::IS_DROPPED); + return false; } - return false; - default: - return true; + default: + UNREACHABLE(); + return true; } } -bool UnfoldShortCircuitTraverser::visitSelection(Visit visit, TIntermSelection *node) +bool UnfoldShortCircuitTraverser::visitTernary(Visit visit, TIntermTernary *node) { if (mFoundShortCircuit) return false; + if (visit != PreVisit) + return true; + + if (!mPatternToUnfoldMatcher.match(node)) + return true; + + mFoundShortCircuit = true; + // Unfold "b ? x : y" into "type s; if(b) s = x; else s = y;" - if (visit == PreVisit && node->usesTernaryOperator()) - { - mFoundShortCircuit = true; - if (!copyLoopConditionOrExpression(getParentNode(), node)) - { - TIntermSequence insertions; + TIntermSequence insertions; - TIntermSymbol *tempSymbol = createTempSymbol(node->getType()); - TIntermAggregate *tempDeclaration = new TIntermAggregate(EOpDeclaration); - tempDeclaration->getSequence()->push_back(tempSymbol); - insertions.push_back(tempDeclaration); + TIntermDeclaration *tempDeclaration = createTempDeclaration(node->getType()); + insertions.push_back(tempDeclaration); - TIntermAggregate *trueBlock = new TIntermAggregate(EOpSequence); - TIntermBinary *trueAssignment = - createTempAssignment(node->getTrueBlock()->getAsTyped()); - trueBlock->getSequence()->push_back(trueAssignment); + TIntermBlock *trueBlock = new TIntermBlock(); + TIntermBinary *trueAssignment = createTempAssignment(node->getTrueExpression()); + trueBlock->getSequence()->push_back(trueAssignment); - TIntermAggregate *falseBlock = new TIntermAggregate(EOpSequence); - TIntermBinary *falseAssignment = - createTempAssignment(node->getFalseBlock()->getAsTyped()); - falseBlock->getSequence()->push_back(falseAssignment); + TIntermBlock *falseBlock = new TIntermBlock(); + TIntermBinary *falseAssignment = createTempAssignment(node->getFalseExpression()); + falseBlock->getSequence()->push_back(falseAssignment); - TIntermSelection *ifNode = - new TIntermSelection(node->getCondition()->getAsTyped(), trueBlock, falseBlock); - insertions.push_back(ifNode); + TIntermIfElse *ifNode = + new TIntermIfElse(node->getCondition()->getAsTyped(), trueBlock, falseBlock); + insertions.push_back(ifNode); - insertStatementsInParentBlock(insertions); + insertStatementsInParentBlock(insertions); - TIntermSymbol *ternaryResult = createTempSymbol(node->getType()); - NodeUpdateEntry replaceVariable(getParentNode(), node, ternaryResult, false); - mReplacements.push_back(replaceVariable); - } - return false; - } + TIntermSymbol *ternaryResult = createTempSymbol(node->getType()); + queueReplacement(ternaryResult, OriginalNode::IS_DROPPED); - return true; -} - -bool UnfoldShortCircuitTraverser::visitAggregate(Visit visit, TIntermAggregate *node) -{ - if (visit == PreVisit && mFoundShortCircuit) - return false; // No need to traverse further - - if (node->getOp() == EOpComma) - { - ASSERT(visit != PreVisit || !mFoundShortCircuit); - - if (visit == PostVisit && mFoundShortCircuit) - { - // We can be sure that we arrived here because there was a short-circuiting operator - // inside the sequence operator since we only start traversing the sequence operator in - // case a short-circuiting operator has not been found so far. - // We need to unfold the sequence (comma) operator, otherwise the evaluation order of - // statements would be messed up by unfolded operations inside. - // Don't do any other unfolding on this round of traversal. - mReplacements.clear(); - mMultiReplacements.clear(); - mInsertions.clear(); - - if (!copyLoopConditionOrExpression(getParentNode(), node)) - { - TIntermSequence insertions; - TIntermSequence *seq = node->getSequence(); - - TIntermSequence::size_type i = 0; - ASSERT(!seq->empty()); - while (i < seq->size() - 1) - { - TIntermTyped *child = (*seq)[i]->getAsTyped(); - insertions.push_back(child); - ++i; - } - - insertStatementsInParentBlock(insertions); - - NodeUpdateEntry replaceVariable(getParentNode(), node, (*seq)[i], false); - mReplacements.push_back(replaceVariable); - } - } - } - return true; -} - -bool UnfoldShortCircuitTraverser::visitLoop(Visit visit, TIntermLoop *node) -{ - if (visit == PreVisit) - { - if (mFoundShortCircuit) - return false; // No need to traverse further - - mLoopParent = getParentNode(); - mParentLoop = node; - incrementDepth(node); - - if (node->getInit()) - { - node->getInit()->traverse(this); - if (mFoundShortCircuit) - { - decrementDepth(); - return false; - } - } - - if (node->getCondition()) - { - mInLoopCondition = true; - node->getCondition()->traverse(this); - mInLoopCondition = false; - - if (mFoundShortCircuit) - { - decrementDepth(); - return false; - } - } - - if (node->getExpression()) - { - mInLoopExpression = true; - node->getExpression()->traverse(this); - mInLoopExpression = false; - - if (mFoundShortCircuit) - { - decrementDepth(); - return false; - } - } - - if (node->getBody()) - node->getBody()->traverse(this); - - decrementDepth(); - } - return false; -} - -bool UnfoldShortCircuitTraverser::copyLoopConditionOrExpression(TIntermNode *parent, - TIntermTyped *node) -{ - if (mInLoopCondition) - { - mReplacements.push_back( - NodeUpdateEntry(parent, node, createTempSymbol(node->getType()), false)); - TIntermAggregate *body = mParentLoop->getBody(); - TIntermSequence empty; - if (mParentLoop->getType() == ELoopDoWhile) - { - // Declare the temporary variable before the loop. - TIntermSequence insertionsBeforeLoop; - insertionsBeforeLoop.push_back(createTempDeclaration(node->getType())); - insertStatementsInParentBlock(insertionsBeforeLoop); - - // Move a part of do-while loop condition to inside the loop. - TIntermSequence insertionsInLoop; - insertionsInLoop.push_back(createTempAssignment(node)); - mInsertions.push_back(NodeInsertMultipleEntry(body, body->getSequence()->size() - 1, - empty, insertionsInLoop)); - } - else - { - // The loop initializer expression and one copy of the part of the loop condition are - // executed before the loop. They need to be in a new scope. - TIntermAggregate *loopScope = new TIntermAggregate(EOpSequence); - - TIntermNode *initializer = mParentLoop->getInit(); - if (initializer != nullptr) - { - // Move the initializer to the newly created outer scope, so that condition can - // depend on it. - mReplacements.push_back(NodeUpdateEntry(mParentLoop, initializer, nullptr, false)); - loopScope->getSequence()->push_back(initializer); - } - - loopScope->getSequence()->push_back(createTempInitDeclaration(node)); - loopScope->getSequence()->push_back(mParentLoop); - mReplacements.push_back(NodeUpdateEntry(mLoopParent, mParentLoop, loopScope, true)); - - // The second copy of the part of the loop condition is executed inside the loop. - TIntermSequence insertionsInLoop; - insertionsInLoop.push_back(createTempAssignment(node->deepCopy())); - mInsertions.push_back(NodeInsertMultipleEntry(body, body->getSequence()->size() - 1, - empty, insertionsInLoop)); - } - return true; - } - - if (mInLoopExpression) - { - TIntermTyped *movedExpression = mParentLoop->getExpression(); - mReplacements.push_back(NodeUpdateEntry(mParentLoop, movedExpression, nullptr, false)); - TIntermAggregate *body = mParentLoop->getBody(); - TIntermSequence empty; - TIntermSequence insertions; - insertions.push_back(movedExpression); - mInsertions.push_back( - NodeInsertMultipleEntry(body, body->getSequence()->size() - 1, empty, insertions)); - return true; - } return false; } void UnfoldShortCircuitTraverser::nextIteration() { mFoundShortCircuit = false; - nextTemporaryIndex(); + nextTemporaryId(); } -} // namespace +} // namespace -void UnfoldShortCircuitToIf(TIntermNode *root, unsigned int *temporaryIndex) +void UnfoldShortCircuitToIf(TIntermNode *root, TSymbolTable *symbolTable) { - UnfoldShortCircuitTraverser traverser; - ASSERT(temporaryIndex != nullptr); - traverser.useTemporaryIndex(temporaryIndex); + UnfoldShortCircuitTraverser traverser(symbolTable); // Unfold one operator at a time, and reset the traverser between iterations. do { @@ -363,6 +180,7 @@ void UnfoldShortCircuitToIf(TIntermNode *root, unsigned int *temporaryIndex) root->traverse(&traverser); if (traverser.foundShortCircuit()) traverser.updateTree(); - } - while (traverser.foundShortCircuit()); + } while (traverser.foundShortCircuit()); } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitToIf.h b/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitToIf.h index 0fe37b7140..37dd83a8cf 100644 --- a/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitToIf.h +++ b/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitToIf.h @@ -3,7 +3,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// UnfoldShortCircuitToIf is an AST traverser to convert short-circuiting operators to if-else statements. +// UnfoldShortCircuitToIf is an AST traverser to convert short-circuiting operators to if-else +// statements. // The results are assigned to s# temporaries, which are used by the main translator instead of // the original expression. // @@ -11,8 +12,14 @@ #ifndef COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUIT_H_ #define COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUIT_H_ +namespace sh +{ + class TIntermNode; +class TSymbolTable; -void UnfoldShortCircuitToIf(TIntermNode *root, unsigned int *temporaryIndex); +void UnfoldShortCircuitToIf(TIntermNode *root, TSymbolTable *symbolTable); -#endif // COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUIT_H_ +} // namespace sh + +#endif // COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUIT_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/UniformHLSL.cpp b/src/3rdparty/angle/src/compiler/translator/UniformHLSL.cpp index 20961c44c1..9f18509438 100644 --- a/src/3rdparty/angle/src/compiler/translator/UniformHLSL.cpp +++ b/src/3rdparty/angle/src/compiler/translator/UniformHLSL.cpp @@ -4,7 +4,7 @@ // found in the LICENSE file. // // UniformHLSL.cpp: -// Methods for GLSL to HLSL translation for uniforms and interface blocks. +// Methods for GLSL to HLSL translation for uniforms and uniform blocks. // #include "compiler/translator/UniformHLSL.h" @@ -18,6 +18,9 @@ namespace sh { +namespace +{ + static const char *UniformRegisterPrefix(const TType &type) { if (IsSampler(type.getBasicType())) @@ -32,22 +35,23 @@ static const char *UniformRegisterPrefix(const TType &type) static TString InterfaceBlockFieldTypeString(const TField &field, TLayoutBlockStorage blockStorage) { - const TType &fieldType = *field.type(); + const TType &fieldType = *field.type(); const TLayoutMatrixPacking matrixPacking = fieldType.getLayoutQualifier().matrixPacking; ASSERT(matrixPacking != EmpUnspecified); - TStructure *structure = fieldType.getStruct(); + const TStructure *structure = fieldType.getStruct(); if (fieldType.isMatrix()) { // Use HLSL row-major packing for GLSL column-major matrices - const TString &matrixPackString = (matrixPacking == EmpRowMajor ? "column_major" : "row_major"); + const TString &matrixPackString = + (matrixPacking == EmpRowMajor ? "column_major" : "row_major"); return matrixPackString + " " + TypeString(fieldType); } else if (structure) { // Use HLSL row-major packing for GLSL column-major matrices return QualifiedStructNameString(*structure, matrixPacking == EmpColumnMajor, - blockStorage == EbsStd140); + blockStorage == EbsStd140); } else { @@ -60,23 +64,58 @@ static TString InterfaceBlockStructName(const TInterfaceBlock &interfaceBlock) return DecoratePrivate(interfaceBlock.name()) + "_type"; } -UniformHLSL::UniformHLSL(StructureHLSL *structureHLSL, ShShaderOutput outputType, const std::vector &uniforms) +void OutputSamplerIndexArrayInitializer(TInfoSinkBase &out, + const TType &type, + unsigned int startIndex) +{ + out << "{"; + TType elementType(type); + elementType.toArrayElementType(); + for (unsigned int i = 0u; i < type.getOutermostArraySize(); ++i) + { + if (i > 0u) + { + out << ", "; + } + if (elementType.isArray()) + { + OutputSamplerIndexArrayInitializer(out, elementType, + startIndex + i * elementType.getArraySizeProduct()); + } + else + { + out << (startIndex + i); + } + } + out << "}"; +} + +} // anonymous namespace + +UniformHLSL::UniformHLSL(sh::GLenum shaderType, + StructureHLSL *structureHLSL, + ShShaderOutput outputType, + const std::vector &uniforms) : mUniformRegister(0), - mInterfaceBlockRegister(0), - mSamplerRegister(0), + mUniformBlockRegister(0), + mTextureRegister(0), + mRWTextureRegister(0), + mSamplerCount(0), + mShaderType(shaderType), mStructureHLSL(structureHLSL), mOutputType(outputType), mUniforms(uniforms) -{} +{ +} void UniformHLSL::reserveUniformRegisters(unsigned int registerCount) { mUniformRegister = registerCount; } -void UniformHLSL::reserveInterfaceBlockRegisters(unsigned int registerCount) +void UniformHLSL::reserveUniformBlockRegisters(unsigned int registerCount) { - mInterfaceBlockRegister = registerCount; + mUniformBlockRegister = registerCount; } const Uniform *UniformHLSL::findUniformByName(const TString &name) const @@ -89,46 +128,78 @@ const Uniform *UniformHLSL::findUniformByName(const TString &name) const } } - UNREACHABLE(); - return NULL; + return nullptr; } -unsigned int UniformHLSL::declareUniformAndAssignRegister(const TType &type, - const TString &name, - unsigned int *registerCount) +unsigned int UniformHLSL::assignUniformRegister(const TType &type, + const TString &name, + unsigned int *outRegisterCount) { - unsigned int registerIndex = (IsSampler(type.getBasicType()) ? mSamplerRegister : mUniformRegister); - + unsigned int registerIndex; const Uniform *uniform = findUniformByName(name); ASSERT(uniform); - mUniformRegisterMap[uniform->name] = registerIndex; - - ASSERT(registerCount); - *registerCount = HLSLVariableRegisterCount(*uniform, mOutputType); - - if (gl::IsSamplerType(uniform->type)) + if (IsSampler(type.getBasicType()) || + (IsImage(type.getBasicType()) && type.getMemoryQualifier().readonly)) { - mSamplerRegister += *registerCount; + registerIndex = mTextureRegister; + } + else if (IsImage(type.getBasicType())) + { + registerIndex = mRWTextureRegister; } else { - mUniformRegister += *registerCount; + registerIndex = mUniformRegister; } + mUniformRegisterMap[uniform->name] = registerIndex; + + unsigned int registerCount = HLSLVariableRegisterCount(*uniform, mOutputType); + + if (IsSampler(type.getBasicType()) || + (IsImage(type.getBasicType()) && type.getMemoryQualifier().readonly)) + { + mTextureRegister += registerCount; + } + else if (IsImage(type.getBasicType())) + { + mRWTextureRegister += registerCount; + } + else + { + mUniformRegister += registerCount; + } + if (outRegisterCount) + { + *outRegisterCount = registerCount; + } return registerIndex; } -unsigned int UniformHLSL::declareUniformAndAssignRegister(const TType &type, const TString &name) +unsigned int UniformHLSL::assignSamplerInStructUniformRegister(const TType &type, + const TString &name, + unsigned int *outRegisterCount) { - unsigned int registerCount; - return declareUniformAndAssignRegister(type, name, ®isterCount); + // Sampler that is a field of a uniform structure. + ASSERT(IsSampler(type.getBasicType())); + unsigned int registerIndex = mTextureRegister; + mUniformRegisterMap[std::string(name.c_str())] = registerIndex; + unsigned int registerCount = type.isArray() ? type.getArraySizeProduct() : 1u; + mTextureRegister += registerCount; + if (outRegisterCount) + { + *outRegisterCount = registerCount; + } + return registerIndex; } -void UniformHLSL::outputHLSLSamplerUniformGroup(TInfoSinkBase &out, - const HLSLTextureSamplerGroup textureGroup, - const TVector &group, - unsigned int *groupTextureRegisterIndex) +void UniformHLSL::outputHLSLSamplerUniformGroup( + TInfoSinkBase &out, + const HLSLTextureGroup textureGroup, + const TVector &group, + const TMap &samplerInStructSymbolsToAPINames, + unsigned int *groupTextureRegisterIndex) { if (group.empty()) { @@ -140,24 +211,33 @@ void UniformHLSL::outputHLSLSamplerUniformGroup(TInfoSinkBase &out, const TType &type = uniform->getType(); const TString &name = uniform->getSymbol(); unsigned int registerCount; - unsigned int samplerArrayIndex = - declareUniformAndAssignRegister(type, name, ®isterCount); - groupRegisterCount += registerCount; - if (type.isArray()) + + // The uniform might be just a regular sampler or one extracted from a struct. + unsigned int samplerArrayIndex = 0u; + const Uniform *uniformByName = findUniformByName(name); + if (uniformByName) { - out << "static const uint " << DecorateIfNeeded(uniform->getName()) << ArrayString(type) - << " = {"; - for (int i = 0; i < type.getArraySize(); ++i) - { - if (i > 0) - out << ", "; - out << (samplerArrayIndex + i); - } - out << "};\n"; + samplerArrayIndex = assignUniformRegister(type, name, ®isterCount); } else { - out << "static const uint " << DecorateIfNeeded(uniform->getName()) << " = " + ASSERT(samplerInStructSymbolsToAPINames.find(uniform) != + samplerInStructSymbolsToAPINames.end()); + samplerArrayIndex = assignSamplerInStructUniformRegister( + type, samplerInStructSymbolsToAPINames.at(uniform), ®isterCount); + } + groupRegisterCount += registerCount; + + if (type.isArray()) + { + out << "static const uint " << DecorateVariableIfNeeded(uniform->getName()) + << ArrayString(type) << " = "; + OutputSamplerIndexArrayInitializer(out, type, samplerArrayIndex); + out << ";\n"; + } + else + { + out << "static const uint " << DecorateVariableIfNeeded(uniform->getName()) << " = " << samplerArrayIndex << ";\n"; } } @@ -179,9 +259,88 @@ void UniformHLSL::outputHLSLSamplerUniformGroup(TInfoSinkBase &out, *groupTextureRegisterIndex += groupRegisterCount; } +void UniformHLSL::outputHLSL4_0_FL9_3Sampler(TInfoSinkBase &out, + const TType &type, + const TName &name, + const unsigned int registerIndex) +{ + out << "uniform " << SamplerString(type.getBasicType()) << " sampler_" + << DecorateVariableIfNeeded(name) << ArrayString(type) << " : register(s" + << str(registerIndex) << ");\n"; + out << "uniform " << TextureString(type.getBasicType()) << " texture_" + << DecorateVariableIfNeeded(name) << ArrayString(type) << " : register(t" + << str(registerIndex) << ");\n"; +} + +void UniformHLSL::outputHLSL4_1_FL11Texture(TInfoSinkBase &out, + const TType &type, + const TName &name, + const unsigned int registerIndex) +{ + // TODO(xinghua.cao@intel.com): if image2D variable is bound on one layer of Texture3D or + // Texture2DArray. Translate this variable to HLSL Texture3D object or HLSL Texture2DArray + // object, or create a temporary Texture2D to save content of the layer and bind the + // temporary Texture2D to image2D variable. + out << "uniform " + << TextureString(type.getBasicType(), type.getLayoutQualifier().imageInternalFormat) << " " + << DecorateVariableIfNeeded(name) << ArrayString(type) << " : register(t" + << str(registerIndex) << ");\n"; + return; +} + +void UniformHLSL::outputHLSL4_1_FL11RWTexture(TInfoSinkBase &out, + const TType &type, + const TName &name, + const unsigned int registerIndex) +{ + // TODO(xinghua.cao@intel.com): if image2D variable is bound on one layer of Texture3D or + // Texture2DArray. Translate this variable to HLSL RWTexture3D object or HLSL RWTexture2DArray + // object, or create a temporary Texture2D to save content of the layer and bind the + // temporary Texture2D to image2D variable. + if (mShaderType == GL_COMPUTE_SHADER) + { + out << "uniform " + << RWTextureString(type.getBasicType(), type.getLayoutQualifier().imageInternalFormat) + << " " << DecorateVariableIfNeeded(name) << ArrayString(type) << " : register(u" + << str(registerIndex) << ");\n"; + } + else + { + // TODO(xinghua.cao@intel.com): Support images in vertex shader and fragment shader, + // which are needed to sync binding value when linking program. + } + return; +} + +void UniformHLSL::outputUniform(TInfoSinkBase &out, + const TType &type, + const TName &name, + const unsigned int registerIndex) +{ + const TStructure *structure = type.getStruct(); + // If this is a nameless struct, we need to use its full definition, rather than its (empty) + // name. + // TypeString() will invoke defineNameless in this case; qualifier prefixes are unnecessary for + // nameless structs in ES, as nameless structs cannot be used anywhere that layout qualifiers + // are permitted. + const TString &typeName = ((structure && !structure->name().empty()) + ? QualifiedStructNameString(*structure, false, false) + : TypeString(type)); + + const TString ®isterString = + TString("register(") + UniformRegisterPrefix(type) + str(registerIndex) + ")"; + + out << "uniform " << typeName << " "; + + out << DecorateVariableIfNeeded(name); + + out << ArrayString(type) << " : " << registerString << ";\n"; +} + void UniformHLSL::uniformsHeader(TInfoSinkBase &out, ShShaderOutput outputType, - const ReferencedSymbols &referencedUniforms) + const ReferencedSymbols &referencedUniforms, + TSymbolTable *symbolTable) { if (!referencedUniforms.empty()) { @@ -190,45 +349,69 @@ void UniformHLSL::uniformsHeader(TInfoSinkBase &out, // In the case of HLSL 4, sampler uniforms need to be grouped by type before the code is // written. They are grouped based on the combination of the HLSL texture type and // HLSL sampler type, enumerated in HLSLTextureSamplerGroup. - TVector> groupedSamplerUniforms; - groupedSamplerUniforms.resize(HLSL_TEXTURE_MAX + 1); + TVector> groupedSamplerUniforms(HLSL_TEXTURE_MAX + 1); + TMap samplerInStructSymbolsToAPINames; + TVector imageUniformsHLSL41Output; for (auto &uniformIt : referencedUniforms) { // Output regular uniforms. Group sampler uniforms by type. const TIntermSymbol &uniform = *uniformIt.second; - const TType &type = uniform.getType(); - const TString &name = uniform.getSymbol(); + const TType &type = uniform.getType(); + const TName &name = uniform.getName(); if (outputType == SH_HLSL_4_1_OUTPUT && IsSampler(type.getBasicType())) { - HLSLTextureSamplerGroup group = TextureGroup(type.getBasicType()); + HLSLTextureGroup group = TextureGroup(type.getBasicType()); groupedSamplerUniforms[group].push_back(&uniform); } else if (outputType == SH_HLSL_4_0_FL9_3_OUTPUT && IsSampler(type.getBasicType())) { - unsigned int registerIndex = declareUniformAndAssignRegister(type, name); - out << "uniform " << SamplerString(type.getBasicType()) << " sampler_" - << DecorateUniform(name, type) << ArrayString(type) << " : register(s" - << str(registerIndex) << ");\n"; - out << "uniform " << TextureString(type.getBasicType()) << " texture_" - << DecorateUniform(name, type) << ArrayString(type) << " : register(t" - << str(registerIndex) << ");\n"; + unsigned int registerIndex = assignUniformRegister(type, name.getString(), nullptr); + outputHLSL4_0_FL9_3Sampler(out, type, name, registerIndex); + } + else if (outputType == SH_HLSL_4_1_OUTPUT && IsImage(type.getBasicType())) + { + imageUniformsHLSL41Output.push_back(&uniform); } else { - unsigned int registerIndex = declareUniformAndAssignRegister(type, name); - const TStructure *structure = type.getStruct(); - // If this is a nameless struct, we need to use its full definition, rather than its (empty) name. - // TypeString() will invoke defineNameless in this case; qualifier prefixes are unnecessary for - // nameless structs in ES, as nameless structs cannot be used anywhere that layout qualifiers are - // permitted. - const TString &typeName = ((structure && !structure->name().empty()) ? - QualifiedStructNameString(*structure, false, false) : TypeString(type)); + if (type.isStructureContainingSamplers()) + { + TVector samplerSymbols; + TMap symbolsToAPINames; + type.createSamplerSymbols("angle_" + name.getString(), name.getString(), + &samplerSymbols, &symbolsToAPINames, symbolTable); + for (TIntermSymbol *sampler : samplerSymbols) + { + const TType &samplerType = sampler->getType(); - const TString ®isterString = TString("register(") + UniformRegisterPrefix(type) + str(registerIndex) + ")"; + // Will use angle_ prefix instead of regular prefix. + sampler->setInternal(true); + const TName &samplerName = sampler->getName(); - out << "uniform " << typeName << " " << DecorateUniform(name, type) << ArrayString(type) - << " : " << registerString << ";\n"; + if (outputType == SH_HLSL_4_1_OUTPUT) + { + HLSLTextureGroup group = TextureGroup(samplerType.getBasicType()); + groupedSamplerUniforms[group].push_back(sampler); + samplerInStructSymbolsToAPINames[sampler] = symbolsToAPINames[sampler]; + } + else if (outputType == SH_HLSL_4_0_FL9_3_OUTPUT) + { + unsigned int registerIndex = assignSamplerInStructUniformRegister( + samplerType, symbolsToAPINames[sampler], nullptr); + outputHLSL4_0_FL9_3Sampler(out, samplerType, samplerName, registerIndex); + } + else + { + ASSERT(outputType == SH_HLSL_3_0_OUTPUT); + unsigned int registerIndex = assignSamplerInStructUniformRegister( + samplerType, symbolsToAPINames[sampler], nullptr); + outputUniform(out, samplerType, samplerName, registerIndex); + } + } + } + unsigned int registerIndex = assignUniformRegister(type, name.getString(), nullptr); + outputUniform(out, type, name, registerIndex); } } @@ -239,70 +422,114 @@ void UniformHLSL::uniformsHeader(TInfoSinkBase &out, ASSERT(HLSL_TEXTURE_MIN == HLSL_TEXTURE_2D); for (int groupId = HLSL_TEXTURE_MIN; groupId < HLSL_TEXTURE_MAX; ++groupId) { - outputHLSLSamplerUniformGroup(out, HLSLTextureSamplerGroup(groupId), - groupedSamplerUniforms[groupId], - &groupTextureRegisterIndex); + outputHLSLSamplerUniformGroup( + out, HLSLTextureGroup(groupId), groupedSamplerUniforms[groupId], + samplerInStructSymbolsToAPINames, &groupTextureRegisterIndex); + } + mSamplerCount = groupTextureRegisterIndex; + + for (const TIntermSymbol *image : imageUniformsHLSL41Output) + { + const TType &type = image->getType(); + const TName &name = image->getName(); + unsigned int registerIndex = assignUniformRegister(type, name.getString(), nullptr); + if (type.getMemoryQualifier().readonly) + { + outputHLSL4_1_FL11Texture(out, type, name, registerIndex); + } + else + { + outputHLSL4_1_FL11RWTexture(out, type, name, registerIndex); + } } } } -TString UniformHLSL::interfaceBlocksHeader(const ReferencedSymbols &referencedInterfaceBlocks) +void UniformHLSL::samplerMetadataUniforms(TInfoSinkBase &out, const char *reg) +{ + // If mSamplerCount is 0 the shader doesn't use any textures for samplers. + if (mSamplerCount > 0) + { + out << " struct SamplerMetadata\n" + " {\n" + " int baseLevel;\n" + " int internalFormatBits;\n" + " int wrapModes;\n" + " int padding;\n" + " };\n" + " SamplerMetadata samplerMetadata[" + << mSamplerCount << "] : packoffset(" << reg << ");\n"; + } +} + +TString UniformHLSL::uniformBlocksHeader(const ReferencedSymbols &referencedInterfaceBlocks) { TString interfaceBlocks; for (ReferencedSymbols::const_iterator interfaceBlockIt = referencedInterfaceBlocks.begin(); interfaceBlockIt != referencedInterfaceBlocks.end(); interfaceBlockIt++) { - const TType &nodeType = interfaceBlockIt->second->getType(); + const TType &nodeType = interfaceBlockIt->second->getType(); const TInterfaceBlock &interfaceBlock = *nodeType.getInterfaceBlock(); - unsigned int arraySize = static_cast(interfaceBlock.arraySize()); - unsigned int activeRegister = mInterfaceBlockRegister; + // nodeType.isInterfaceBlock() == false means the node is a field of a uniform block which + // doesn't have instance name, so this block cannot be an array. + unsigned int interfaceBlockArraySize = 0u; + if (nodeType.isInterfaceBlock() && nodeType.isArray()) + { + interfaceBlockArraySize = nodeType.getOutermostArraySize(); + } + unsigned int activeRegister = mUniformBlockRegister; - mInterfaceBlockRegisterMap[interfaceBlock.name().c_str()] = activeRegister; - mInterfaceBlockRegister += std::max(1u, arraySize); + mUniformBlockRegisterMap[interfaceBlock.name().c_str()] = activeRegister; + mUniformBlockRegister += std::max(1u, interfaceBlockArraySize); // FIXME: interface block field names if (interfaceBlock.hasInstanceName()) { - interfaceBlocks += interfaceBlockStructString(interfaceBlock); + interfaceBlocks += uniformBlockStructString(interfaceBlock); } - if (arraySize > 0) + if (interfaceBlockArraySize > 0) { - for (unsigned int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) + for (unsigned int arrayIndex = 0; arrayIndex < interfaceBlockArraySize; arrayIndex++) { - interfaceBlocks += interfaceBlockString(interfaceBlock, activeRegister + arrayIndex, arrayIndex); + interfaceBlocks += + uniformBlockString(interfaceBlock, activeRegister + arrayIndex, arrayIndex); } } else { - interfaceBlocks += interfaceBlockString(interfaceBlock, activeRegister, GL_INVALID_INDEX); + interfaceBlocks += uniformBlockString(interfaceBlock, activeRegister, GL_INVALID_INDEX); } } - return (interfaceBlocks.empty() ? "" : ("// Interface Blocks\n\n" + interfaceBlocks)); + return (interfaceBlocks.empty() ? "" : ("// Uniform Blocks\n\n" + interfaceBlocks)); } -TString UniformHLSL::interfaceBlockString(const TInterfaceBlock &interfaceBlock, unsigned int registerIndex, unsigned int arrayIndex) +TString UniformHLSL::uniformBlockString(const TInterfaceBlock &interfaceBlock, + unsigned int registerIndex, + unsigned int arrayIndex) { - const TString &arrayIndexString = (arrayIndex != GL_INVALID_INDEX ? Decorate(str(arrayIndex)) : ""); + const TString &arrayIndexString = + (arrayIndex != GL_INVALID_INDEX ? Decorate(str(arrayIndex)) : ""); const TString &blockName = interfaceBlock.name() + arrayIndexString; TString hlsl; - hlsl += "cbuffer " + blockName + " : register(b" + str(registerIndex) + ")\n" + hlsl += "cbuffer " + blockName + " : register(b" + str(registerIndex) + + ")\n" "{\n"; if (interfaceBlock.hasInstanceName()) { hlsl += " " + InterfaceBlockStructName(interfaceBlock) + " " + - interfaceBlockInstanceString(interfaceBlock, arrayIndex) + ";\n"; + uniformBlockInstanceString(interfaceBlock, arrayIndex) + ";\n"; } else { const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage(); - hlsl += interfaceBlockMembersString(interfaceBlock, blockStorage); + hlsl += uniformBlockMembersString(interfaceBlock, blockStorage); } hlsl += "};\n\n"; @@ -310,13 +537,14 @@ TString UniformHLSL::interfaceBlockString(const TInterfaceBlock &interfaceBlock, return hlsl; } -TString UniformHLSL::interfaceBlockInstanceString(const TInterfaceBlock& interfaceBlock, unsigned int arrayIndex) +TString UniformHLSL::uniformBlockInstanceString(const TInterfaceBlock &interfaceBlock, + unsigned int arrayIndex) { if (!interfaceBlock.hasInstanceName()) { return ""; } - else if (interfaceBlock.isArray()) + else if (arrayIndex != GL_INVALID_INDEX) { return DecoratePrivate(interfaceBlock.instanceName()) + "_" + str(arrayIndex); } @@ -326,7 +554,8 @@ TString UniformHLSL::interfaceBlockInstanceString(const TInterfaceBlock& interfa } } -TString UniformHLSL::interfaceBlockMembersString(const TInterfaceBlock &interfaceBlock, TLayoutBlockStorage blockStorage) +TString UniformHLSL::uniformBlockMembersString(const TInterfaceBlock &interfaceBlock, + TLayoutBlockStorage blockStorage) { TString hlsl; @@ -334,7 +563,7 @@ TString UniformHLSL::interfaceBlockMembersString(const TInterfaceBlock &interfac for (unsigned int typeIndex = 0; typeIndex < interfaceBlock.fields().size(); typeIndex++) { - const TField &field = *interfaceBlock.fields()[typeIndex]; + const TField &field = *interfaceBlock.fields()[typeIndex]; const TType &fieldType = *field.type(); if (blockStorage == EbsStd140) @@ -343,13 +572,15 @@ TString UniformHLSL::interfaceBlockMembersString(const TInterfaceBlock &interfac hlsl += padHelper.prePaddingString(fieldType); } - hlsl += " " + InterfaceBlockFieldTypeString(field, blockStorage) + - " " + Decorate(field.name()) + ArrayString(fieldType) + ";\n"; + hlsl += " " + InterfaceBlockFieldTypeString(field, blockStorage) + " " + + Decorate(field.name()) + ArrayString(fieldType) + ";\n"; - // must pad out after matrices and arrays, where HLSL usually allows itself room to pack stuff + // must pad out after matrices and arrays, where HLSL usually allows itself room to pack + // stuff if (blockStorage == EbsStd140) { - const bool useHLSLRowMajorPacking = (fieldType.getLayoutQualifier().matrixPacking == EmpColumnMajor); + const bool useHLSLRowMajorPacking = + (fieldType.getLayoutQualifier().matrixPacking == EmpColumnMajor); hlsl += padHelper.postPaddingString(fieldType, useHLSLRowMajorPacking); } } @@ -357,14 +588,13 @@ TString UniformHLSL::interfaceBlockMembersString(const TInterfaceBlock &interfac return hlsl; } -TString UniformHLSL::interfaceBlockStructString(const TInterfaceBlock &interfaceBlock) +TString UniformHLSL::uniformBlockStructString(const TInterfaceBlock &interfaceBlock) { const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage(); - return "struct " + InterfaceBlockStructName(interfaceBlock) + "\n" + return "struct " + InterfaceBlockStructName(interfaceBlock) + + "\n" "{\n" + - interfaceBlockMembersString(interfaceBlock, blockStorage) + - "};\n\n"; + uniformBlockMembersString(interfaceBlock, blockStorage) + "};\n\n"; } - } diff --git a/src/3rdparty/angle/src/compiler/translator/UniformHLSL.h b/src/3rdparty/angle/src/compiler/translator/UniformHLSL.h index 0f51f349bb..8784e50533 100644 --- a/src/3rdparty/angle/src/compiler/translator/UniformHLSL.h +++ b/src/3rdparty/angle/src/compiler/translator/UniformHLSL.h @@ -4,7 +4,7 @@ // found in the LICENSE file. // // UniformHLSL.h: -// Methods for GLSL to HLSL translation for uniforms and interface blocks. +// Methods for GLSL to HLSL translation for uniforms and uniform blocks. // #ifndef COMPILER_TRANSLATOR_UNIFORMHLSL_H_ @@ -16,29 +16,35 @@ namespace sh { class StructureHLSL; +class TSymbolTable; class UniformHLSL : angle::NonCopyable { public: - UniformHLSL(StructureHLSL *structureHLSL, ShShaderOutput outputType, const std::vector &uniforms); + UniformHLSL(sh::GLenum shaderType, + StructureHLSL *structureHLSL, + ShShaderOutput outputType, + const std::vector &uniforms); void reserveUniformRegisters(unsigned int registerCount); - void reserveInterfaceBlockRegisters(unsigned int registerCount); - void outputHLSLSamplerUniformGroup(TInfoSinkBase &out, - const HLSLTextureSamplerGroup textureGroup, - const TVector &group, - unsigned int *groupTextureRegisterIndex); + void reserveUniformBlockRegisters(unsigned int registerCount); void uniformsHeader(TInfoSinkBase &out, ShShaderOutput outputType, - const ReferencedSymbols &referencedUniforms); - TString interfaceBlocksHeader(const ReferencedSymbols &referencedInterfaceBlocks); + const ReferencedSymbols &referencedUniforms, + TSymbolTable *symbolTable); + + // Must be called after uniformsHeader + void samplerMetadataUniforms(TInfoSinkBase &out, const char *reg); + + TString uniformBlocksHeader(const ReferencedSymbols &referencedInterfaceBlocks); // Used for direct index references - static TString interfaceBlockInstanceString(const TInterfaceBlock& interfaceBlock, unsigned int arrayIndex); + static TString uniformBlockInstanceString(const TInterfaceBlock &interfaceBlock, + unsigned int arrayIndex); - const std::map &getInterfaceBlockRegisterMap() const + const std::map &getUniformBlockRegisterMap() const { - return mInterfaceBlockRegisterMap; + return mUniformBlockRegisterMap; } const std::map &getUniformRegisterMap() const { @@ -46,28 +52,59 @@ class UniformHLSL : angle::NonCopyable } private: - TString interfaceBlockString(const TInterfaceBlock &interfaceBlock, unsigned int registerIndex, unsigned int arrayIndex); - TString interfaceBlockMembersString(const TInterfaceBlock &interfaceBlock, TLayoutBlockStorage blockStorage); - TString interfaceBlockStructString(const TInterfaceBlock &interfaceBlock); + TString uniformBlockString(const TInterfaceBlock &interfaceBlock, + unsigned int registerIndex, + unsigned int arrayIndex); + TString uniformBlockMembersString(const TInterfaceBlock &interfaceBlock, + TLayoutBlockStorage blockStorage); + TString uniformBlockStructString(const TInterfaceBlock &interfaceBlock); const Uniform *findUniformByName(const TString &name) const; + void outputHLSL4_0_FL9_3Sampler(TInfoSinkBase &out, + const TType &type, + const TName &name, + const unsigned int registerIndex); + void outputHLSL4_1_FL11Texture(TInfoSinkBase &out, + const TType &type, + const TName &name, + const unsigned int registerIndex); + void outputHLSL4_1_FL11RWTexture(TInfoSinkBase &out, + const TType &type, + const TName &name, + const unsigned int registerIndex); + void outputUniform(TInfoSinkBase &out, + const TType &type, + const TName &name, + const unsigned int registerIndex); + // Returns the uniform's register index - unsigned int declareUniformAndAssignRegister(const TType &type, - const TString &name, - unsigned int *registerCount); - unsigned int declareUniformAndAssignRegister(const TType &type, const TString &name); + unsigned int assignUniformRegister(const TType &type, + const TString &name, + unsigned int *outRegisterCount); + unsigned int assignSamplerInStructUniformRegister(const TType &type, + const TString &name, + unsigned int *outRegisterCount); + + void outputHLSLSamplerUniformGroup( + TInfoSinkBase &out, + const HLSLTextureGroup textureGroup, + const TVector &group, + const TMap &samplerInStructSymbolsToAPINames, + unsigned int *groupTextureRegisterIndex); unsigned int mUniformRegister; - unsigned int mInterfaceBlockRegister; - unsigned int mSamplerRegister; + unsigned int mUniformBlockRegister; + unsigned int mTextureRegister; + unsigned int mRWTextureRegister; + unsigned int mSamplerCount; + sh::GLenum mShaderType; StructureHLSL *mStructureHLSL; ShShaderOutput mOutputType; const std::vector &mUniforms; - std::map mInterfaceBlockRegisterMap; + std::map mUniformBlockRegisterMap; std::map mUniformRegisterMap; }; - } -#endif // COMPILER_TRANSLATOR_UNIFORMHLSL_H_ +#endif // COMPILER_TRANSLATOR_UNIFORMHLSL_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/UseInterfaceBlockFields.cpp b/src/3rdparty/angle/src/compiler/translator/UseInterfaceBlockFields.cpp new file mode 100644 index 0000000000..40bd42afad --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/UseInterfaceBlockFields.cpp @@ -0,0 +1,105 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// UseInterfaceBlockFields.cpp: insert statements to reference all members in InterfaceBlock list at +// the beginning of main. This is to work around a Mac driver that treats unused standard/shared +// uniform blocks as inactive. + +#include "compiler/translator/UseInterfaceBlockFields.h" + +#include "compiler/translator/FindMain.h" +#include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermNode_util.h" +#include "compiler/translator/SymbolTable.h" +#include "compiler/translator/util.h" + +namespace sh +{ + +namespace +{ + +void AddNodeUseStatements(TIntermTyped *node, TIntermSequence *sequence) +{ + if (node->isArray()) + { + for (unsigned int i = 0u; i < node->getOutermostArraySize(); ++i) + { + TIntermBinary *element = + new TIntermBinary(EOpIndexDirect, node->deepCopy(), CreateIndexNode(i)); + AddNodeUseStatements(element, sequence); + } + } + else + { + sequence->insert(sequence->begin(), node); + } +} + +void AddFieldUseStatements(const ShaderVariable &var, + TIntermSequence *sequence, + const TSymbolTable &symbolTable) +{ + TString name = TString(var.name.c_str()); + ASSERT(name.find_last_of('[') == TString::npos); + TIntermSymbol *symbol = ReferenceGlobalVariable(name, symbolTable); + AddNodeUseStatements(symbol, sequence); +} + +void InsertUseCode(const InterfaceBlock &block, TIntermTyped *blockNode, TIntermSequence *sequence) +{ + for (unsigned int i = 0; i < block.fields.size(); ++i) + { + TIntermBinary *element = new TIntermBinary(EOpIndexDirectInterfaceBlock, + blockNode->deepCopy(), CreateIndexNode(i)); + sequence->insert(sequence->begin(), element); + } +} + +void InsertUseCode(TIntermSequence *sequence, + const InterfaceBlockList &blocks, + const TSymbolTable &symbolTable) +{ + for (const auto &block : blocks) + { + if (block.instanceName.empty()) + { + for (const auto &var : block.fields) + { + AddFieldUseStatements(var, sequence, symbolTable); + } + } + else if (block.arraySize > 0u) + { + TString name(block.instanceName.c_str()); + TIntermSymbol *arraySymbol = ReferenceGlobalVariable(name, symbolTable); + for (unsigned int i = 0u; i < block.arraySize; ++i) + { + TIntermBinary *elementSymbol = + new TIntermBinary(EOpIndexDirect, arraySymbol->deepCopy(), CreateIndexNode(i)); + InsertUseCode(block, elementSymbol, sequence); + } + } + else + { + TString name(block.instanceName.c_str()); + TIntermSymbol *blockSymbol = ReferenceGlobalVariable(name, symbolTable); + InsertUseCode(block, blockSymbol, sequence); + } + } +} + +} // namespace anonymous + +void UseInterfaceBlockFields(TIntermBlock *root, + const InterfaceBlockList &blocks, + const TSymbolTable &symbolTable) +{ + TIntermBlock *mainBody = FindMainBody(root); + InsertUseCode(mainBody->getSequence(), blocks, symbolTable); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/UseInterfaceBlockFields.h b/src/3rdparty/angle/src/compiler/translator/UseInterfaceBlockFields.h new file mode 100644 index 0000000000..3e2a4815d4 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/UseInterfaceBlockFields.h @@ -0,0 +1,30 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// UseInterfaceBlockFields.h: insert statements to reference all members in InterfaceBlock list at +// the beginning of main. This is to work around a Mac driver that treats unused standard/shared +// uniform blocks as inactive. + +#ifndef COMPILER_TRANSLATOR_USEINTERFACEBLOCKFIELDS_H_ +#define COMPILER_TRANSLATOR_USEINTERFACEBLOCKFIELDS_H_ + +#include + +namespace sh +{ + +class TIntermBlock; +class TSymbolTable; + +using InterfaceBlockList = std::vector; + +void UseInterfaceBlockFields(TIntermBlock *root, + const InterfaceBlockList &blocks, + const TSymbolTable &symbolTable); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_USEINTERFACEBLOCKFIELDS_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/UtilsHLSL.cpp b/src/3rdparty/angle/src/compiler/translator/UtilsHLSL.cpp index 404ccee75d..8a77f0049a 100644 --- a/src/3rdparty/angle/src/compiler/translator/UtilsHLSL.cpp +++ b/src/3rdparty/angle/src/compiler/translator/UtilsHLSL.cpp @@ -27,7 +27,7 @@ TString SamplerString(const TBasicType type) } } -TString SamplerString(HLSLTextureSamplerGroup type) +TString SamplerString(HLSLTextureGroup type) { if (type >= HLSL_COMPARISON_SAMPLER_GROUP_BEGIN && type <= HLSL_COMPARISON_SAMPLER_GROUP_END) { @@ -39,7 +39,8 @@ TString SamplerString(HLSLTextureSamplerGroup type) } } -HLSLTextureSamplerGroup TextureGroup(const TBasicType type) +HLSLTextureGroup TextureGroup(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat) + { switch (type) { @@ -53,6 +54,8 @@ HLSLTextureSamplerGroup TextureGroup(const TBasicType type) return HLSL_TEXTURE_2D_ARRAY; case EbtSampler3D: return HLSL_TEXTURE_3D; + case EbtSampler2DMS: + return HLSL_TEXTURE_2D_MS; case EbtISampler2D: return HLSL_TEXTURE_2D_INT4; case EbtISampler3D: @@ -61,6 +64,8 @@ HLSLTextureSamplerGroup TextureGroup(const TBasicType type) return HLSL_TEXTURE_2D_ARRAY_INT4; case EbtISampler2DArray: return HLSL_TEXTURE_2D_ARRAY_INT4; + case EbtISampler2DMS: + return HLSL_TEXTURE_2D_MS_INT4; case EbtUSampler2D: return HLSL_TEXTURE_2D_UINT4; case EbtUSampler3D: @@ -69,42 +74,196 @@ HLSLTextureSamplerGroup TextureGroup(const TBasicType type) return HLSL_TEXTURE_2D_ARRAY_UINT4; case EbtUSampler2DArray: return HLSL_TEXTURE_2D_ARRAY_UINT4; + case EbtUSampler2DMS: + return HLSL_TEXTURE_2D_MS_UINT4; case EbtSampler2DShadow: return HLSL_TEXTURE_2D_COMPARISON; case EbtSamplerCubeShadow: return HLSL_TEXTURE_CUBE_COMPARISON; case EbtSampler2DArrayShadow: return HLSL_TEXTURE_2D_ARRAY_COMPARISON; + case EbtImage2D: + { + switch (imageInternalFormat) + { + case EiifRGBA32F: + case EiifRGBA16F: + case EiifR32F: + return HLSL_TEXTURE_2D; + case EiifRGBA8: + return HLSL_TEXTURE_2D_UNORM; + case EiifRGBA8_SNORM: + return HLSL_TEXTURE_2D_SNORM; + default: + UNREACHABLE(); + } + } + case EbtIImage2D: + { + switch (imageInternalFormat) + { + case EiifRGBA32I: + case EiifRGBA16I: + case EiifRGBA8I: + case EiifR32I: + return HLSL_TEXTURE_2D_INT4; + default: + UNREACHABLE(); + } + } + case EbtUImage2D: + { + switch (imageInternalFormat) + { + + case EiifRGBA32UI: + case EiifRGBA16UI: + case EiifRGBA8UI: + case EiifR32UI: + return HLSL_TEXTURE_2D_UINT4; + default: + UNREACHABLE(); + } + } + case EbtImage3D: + { + switch (imageInternalFormat) + { + case EiifRGBA32F: + case EiifRGBA16F: + case EiifR32F: + return HLSL_TEXTURE_3D; + case EiifRGBA8: + return HLSL_TEXTURE_3D_UNORM; + case EiifRGBA8_SNORM: + return HLSL_TEXTURE_3D_SNORM; + default: + UNREACHABLE(); + } + } + case EbtIImage3D: + { + switch (imageInternalFormat) + { + case EiifRGBA32I: + case EiifRGBA16I: + case EiifRGBA8I: + case EiifR32I: + return HLSL_TEXTURE_3D_INT4; + default: + UNREACHABLE(); + } + } + case EbtUImage3D: + { + switch (imageInternalFormat) + { + case EiifRGBA32UI: + case EiifRGBA16UI: + case EiifRGBA8UI: + case EiifR32UI: + return HLSL_TEXTURE_3D_UINT4; + default: + UNREACHABLE(); + } + } + case EbtImage2DArray: + case EbtImageCube: + { + switch (imageInternalFormat) + { + case EiifRGBA32F: + case EiifRGBA16F: + case EiifR32F: + return HLSL_TEXTURE_2D_ARRAY; + case EiifRGBA8: + return HLSL_TEXTURE_2D_ARRAY_UNORN; + case EiifRGBA8_SNORM: + return HLSL_TEXTURE_2D_ARRAY_SNORM; + default: + UNREACHABLE(); + } + } + case EbtIImage2DArray: + case EbtIImageCube: + { + switch (imageInternalFormat) + { + case EiifRGBA32I: + case EiifRGBA16I: + case EiifRGBA8I: + case EiifR32I: + return HLSL_TEXTURE_2D_ARRAY_INT4; + default: + UNREACHABLE(); + } + } + case EbtUImage2DArray: + case EbtUImageCube: + { + switch (imageInternalFormat) + { + case EiifRGBA32UI: + case EiifRGBA16UI: + case EiifRGBA8UI: + case EiifR32UI: + return HLSL_TEXTURE_2D_ARRAY_UINT4; + default: + UNREACHABLE(); + } + } default: UNREACHABLE(); } return HLSL_TEXTURE_UNKNOWN; } -TString TextureString(const HLSLTextureSamplerGroup type) +TString TextureString(const HLSLTextureGroup textureGroup) { - switch (type) + switch (textureGroup) { case HLSL_TEXTURE_2D: - return "Texture2D"; + return "Texture2D"; case HLSL_TEXTURE_CUBE: - return "TextureCube"; + return "TextureCube"; case HLSL_TEXTURE_2D_ARRAY: - return "Texture2DArray"; + return "Texture2DArray"; case HLSL_TEXTURE_3D: - return "Texture3D"; + return "Texture3D"; + case HLSL_TEXTURE_2D_UNORM: + return "Texture2D"; + case HLSL_TEXTURE_CUBE_UNORM: + return "TextureCube"; + case HLSL_TEXTURE_2D_ARRAY_UNORN: + return "Texture2DArray"; + case HLSL_TEXTURE_3D_UNORM: + return "Texture3D"; + case HLSL_TEXTURE_2D_SNORM: + return "Texture2D"; + case HLSL_TEXTURE_CUBE_SNORM: + return "TextureCube"; + case HLSL_TEXTURE_2D_ARRAY_SNORM: + return "Texture2DArray"; + case HLSL_TEXTURE_3D_SNORM: + return "Texture3D"; + case HLSL_TEXTURE_2D_MS: + return "Texture2DMS"; case HLSL_TEXTURE_2D_INT4: return "Texture2D"; case HLSL_TEXTURE_3D_INT4: return "Texture3D"; case HLSL_TEXTURE_2D_ARRAY_INT4: return "Texture2DArray"; + case HLSL_TEXTURE_2D_MS_INT4: + return "Texture2DMS"; case HLSL_TEXTURE_2D_UINT4: return "Texture2D"; case HLSL_TEXTURE_3D_UINT4: return "Texture3D"; case HLSL_TEXTURE_2D_ARRAY_UINT4: return "Texture2DArray"; + case HLSL_TEXTURE_2D_MS_UINT4: + return "Texture2DMS"; case HLSL_TEXTURE_2D_COMPARISON: return "Texture2D"; case HLSL_TEXTURE_CUBE_COMPARISON: @@ -115,15 +274,15 @@ TString TextureString(const HLSLTextureSamplerGroup type) UNREACHABLE(); } - return ""; + return ""; } -TString TextureString(const TBasicType type) +TString TextureString(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat) { - return TextureString(TextureGroup(type)); + return TextureString(TextureGroup(type, imageInternalFormat)); } -TString TextureGroupSuffix(const HLSLTextureSamplerGroup type) +TString TextureGroupSuffix(const HLSLTextureGroup type) { switch (type) { @@ -135,18 +294,40 @@ TString TextureGroupSuffix(const HLSLTextureSamplerGroup type) return "2DArray"; case HLSL_TEXTURE_3D: return "3D"; + case HLSL_TEXTURE_2D_UNORM: + return "2D_unorm_float4_"; + case HLSL_TEXTURE_CUBE_UNORM: + return "Cube_unorm_float4_"; + case HLSL_TEXTURE_2D_ARRAY_UNORN: + return "2DArray_unorm_float4_"; + case HLSL_TEXTURE_3D_UNORM: + return "3D_unorm_float4_"; + case HLSL_TEXTURE_2D_SNORM: + return "2D_snorm_float4_"; + case HLSL_TEXTURE_CUBE_SNORM: + return "Cube_snorm_float4_"; + case HLSL_TEXTURE_2D_ARRAY_SNORM: + return "2DArray_snorm_float4_"; + case HLSL_TEXTURE_3D_SNORM: + return "3D_snorm_float4_"; + case HLSL_TEXTURE_2D_MS: + return "2DMS"; case HLSL_TEXTURE_2D_INT4: return "2D_int4_"; case HLSL_TEXTURE_3D_INT4: return "3D_int4_"; case HLSL_TEXTURE_2D_ARRAY_INT4: return "2DArray_int4_"; + case HLSL_TEXTURE_2D_MS_INT4: + return "2DMS_int4_"; case HLSL_TEXTURE_2D_UINT4: return "2D_uint4_"; case HLSL_TEXTURE_3D_UINT4: return "3D_uint4_"; case HLSL_TEXTURE_2D_ARRAY_UINT4: return "2DArray_uint4_"; + case HLSL_TEXTURE_2D_MS_UINT4: + return "2DMS_uint4_"; case HLSL_TEXTURE_2D_COMPARISON: return "2D_comparison"; case HLSL_TEXTURE_CUBE_COMPARISON: @@ -160,12 +341,12 @@ TString TextureGroupSuffix(const HLSLTextureSamplerGroup type) return ""; } -TString TextureGroupSuffix(const TBasicType type) +TString TextureGroupSuffix(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat) { - return TextureGroupSuffix(TextureGroup(type)); + return TextureGroupSuffix(TextureGroup(type, imageInternalFormat)); } -TString TextureTypeSuffix(const TBasicType type) +TString TextureTypeSuffix(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat) { switch (type) { @@ -173,20 +354,340 @@ TString TextureTypeSuffix(const TBasicType type) return "Cube_int4_"; case EbtUSamplerCube: return "Cube_uint4_"; + case EbtSamplerExternalOES: + return "_External"; + case EbtImageCube: + { + switch (imageInternalFormat) + { + case EiifRGBA32F: + case EiifRGBA16F: + case EiifR32F: + return "Cube_float4_"; + case EiifRGBA8: + return "Cube_unorm_float4_"; + case EiifRGBA8_SNORM: + return "Cube_snorm_float4_"; + default: + UNREACHABLE(); + } + } + case EbtIImageCube: + { + switch (imageInternalFormat) + { + case EiifRGBA32I: + case EiifRGBA16I: + case EiifRGBA8I: + case EiifR32I: + return "Cube_int4_"; + default: + UNREACHABLE(); + } + } + case EbtUImageCube: + { + switch (imageInternalFormat) + { + case EiifRGBA32UI: + case EiifRGBA16UI: + case EiifRGBA8UI: + case EiifR32UI: + return "Cube_uint4_"; + default: + UNREACHABLE(); + } + } default: // All other types are identified by their group suffix - return TextureGroupSuffix(type); + return TextureGroupSuffix(type, imageInternalFormat); } } -TString DecorateUniform(const TString &string, const TType &type) +HLSLRWTextureGroup RWTextureGroup(const TBasicType type, + TLayoutImageInternalFormat imageInternalFormat) + { - if (type.getBasicType() == EbtSamplerExternalOES) + switch (type) { - return "ex_" + string; + case EbtImage2D: + { + switch (imageInternalFormat) + { + case EiifRGBA32F: + case EiifRGBA16F: + case EiifR32F: + return HLSL_RWTEXTURE_2D_FLOAT4; + case EiifRGBA8: + return HLSL_RWTEXTURE_2D_UNORM; + case EiifRGBA8_SNORM: + return HLSL_RWTEXTURE_2D_SNORM; + default: + UNREACHABLE(); + } + } + case EbtIImage2D: + { + switch (imageInternalFormat) + { + case EiifRGBA32I: + case EiifRGBA16I: + case EiifRGBA8I: + case EiifR32I: + return HLSL_RWTEXTURE_2D_INT4; + default: + UNREACHABLE(); + } + } + case EbtUImage2D: + { + switch (imageInternalFormat) + { + + case EiifRGBA32UI: + case EiifRGBA16UI: + case EiifRGBA8UI: + case EiifR32UI: + return HLSL_RWTEXTURE_2D_UINT4; + default: + UNREACHABLE(); + } + } + case EbtImage3D: + { + switch (imageInternalFormat) + { + case EiifRGBA32F: + case EiifRGBA16F: + case EiifR32F: + return HLSL_RWTEXTURE_3D_FLOAT4; + case EiifRGBA8: + return HLSL_RWTEXTURE_3D_UNORM; + case EiifRGBA8_SNORM: + return HLSL_RWTEXTURE_3D_SNORM; + default: + UNREACHABLE(); + } + } + case EbtIImage3D: + { + switch (imageInternalFormat) + { + case EiifRGBA32I: + case EiifRGBA16I: + case EiifRGBA8I: + case EiifR32I: + return HLSL_RWTEXTURE_3D_INT4; + default: + UNREACHABLE(); + } + } + case EbtUImage3D: + { + switch (imageInternalFormat) + { + case EiifRGBA32UI: + case EiifRGBA16UI: + case EiifRGBA8UI: + case EiifR32UI: + return HLSL_RWTEXTURE_3D_UINT4; + default: + UNREACHABLE(); + } + } + case EbtImage2DArray: + case EbtImageCube: + { + switch (imageInternalFormat) + { + case EiifRGBA32F: + case EiifRGBA16F: + case EiifR32F: + return HLSL_RWTEXTURE_2D_ARRAY_FLOAT4; + case EiifRGBA8: + return HLSL_RWTEXTURE_2D_ARRAY_UNORN; + case EiifRGBA8_SNORM: + return HLSL_RWTEXTURE_2D_ARRAY_SNORM; + default: + UNREACHABLE(); + } + } + case EbtIImage2DArray: + case EbtIImageCube: + { + switch (imageInternalFormat) + { + case EiifRGBA32I: + case EiifRGBA16I: + case EiifRGBA8I: + case EiifR32I: + return HLSL_RWTEXTURE_2D_ARRAY_INT4; + default: + UNREACHABLE(); + } + } + case EbtUImage2DArray: + case EbtUImageCube: + { + switch (imageInternalFormat) + { + case EiifRGBA32UI: + case EiifRGBA16UI: + case EiifRGBA8UI: + case EiifR32UI: + return HLSL_RWTEXTURE_2D_ARRAY_UINT4; + default: + UNREACHABLE(); + } + } + default: + UNREACHABLE(); + } + return HLSL_RWTEXTURE_UNKNOWN; +} + +TString RWTextureString(const HLSLRWTextureGroup RWTextureGroup) +{ + switch (RWTextureGroup) + { + case HLSL_RWTEXTURE_2D_FLOAT4: + return "RWTexture2D"; + case HLSL_RWTEXTURE_2D_ARRAY_FLOAT4: + return "RWTexture2DArray"; + case HLSL_RWTEXTURE_3D_FLOAT4: + return "RWTexture3D"; + case HLSL_RWTEXTURE_2D_UNORM: + return "RWTexture2D"; + case HLSL_RWTEXTURE_2D_ARRAY_UNORN: + return "RWTexture2DArray"; + case HLSL_RWTEXTURE_3D_UNORM: + return "RWTexture3D"; + case HLSL_RWTEXTURE_2D_SNORM: + return "RWTexture2D"; + case HLSL_RWTEXTURE_2D_ARRAY_SNORM: + return "RWTexture2DArray"; + case HLSL_RWTEXTURE_3D_SNORM: + return "RWTexture3D"; + case HLSL_RWTEXTURE_2D_UINT4: + return "RWTexture2D"; + case HLSL_RWTEXTURE_2D_ARRAY_UINT4: + return "RWTexture2DArray"; + case HLSL_RWTEXTURE_3D_UINT4: + return "RWTexture3D"; + case HLSL_RWTEXTURE_2D_INT4: + return "RWTexture2D"; + case HLSL_RWTEXTURE_2D_ARRAY_INT4: + return "RWTexture2DArray"; + case HLSL_RWTEXTURE_3D_INT4: + return "RWTexture3D"; + default: + UNREACHABLE(); } - return Decorate(string); + return ""; +} + +TString RWTextureString(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat) +{ + return RWTextureString(RWTextureGroup(type, imageInternalFormat)); +} + +TString RWTextureGroupSuffix(const HLSLRWTextureGroup type) +{ + switch (type) + { + case HLSL_RWTEXTURE_2D_FLOAT4: + return "RW2D_float4_"; + case HLSL_RWTEXTURE_2D_ARRAY_FLOAT4: + return "RW2DArray_float4_"; + case HLSL_RWTEXTURE_3D_FLOAT4: + return "RW3D_float4_"; + case HLSL_RWTEXTURE_2D_UNORM: + return "RW2D_unorm_float4_"; + case HLSL_RWTEXTURE_2D_ARRAY_UNORN: + return "RW2DArray_unorm_float4_"; + case HLSL_RWTEXTURE_3D_UNORM: + return "RW3D_unorm_float4_"; + case HLSL_RWTEXTURE_2D_SNORM: + return "RW2D_snorm_float4_"; + case HLSL_RWTEXTURE_2D_ARRAY_SNORM: + return "RW2DArray_snorm_float4_"; + case HLSL_RWTEXTURE_3D_SNORM: + return "RW3D_snorm_float4_"; + case HLSL_RWTEXTURE_2D_UINT4: + return "RW2D_uint4_"; + case HLSL_RWTEXTURE_2D_ARRAY_UINT4: + return "RW2DArray_uint4_"; + case HLSL_RWTEXTURE_3D_UINT4: + return "RW3D_uint4_"; + case HLSL_RWTEXTURE_2D_INT4: + return "RW2D_int4_"; + case HLSL_RWTEXTURE_2D_ARRAY_INT4: + return "RW2DArray_int4_"; + case HLSL_RWTEXTURE_3D_INT4: + return "RW3D_int4_"; + default: + UNREACHABLE(); + } + + return ""; +} + +TString RWTextureGroupSuffix(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat) +{ + return RWTextureGroupSuffix(RWTextureGroup(type, imageInternalFormat)); +} + +TString RWTextureTypeSuffix(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat) +{ + switch (type) + { + case EbtImageCube: + { + switch (imageInternalFormat) + { + case EiifRGBA32F: + case EiifRGBA16F: + case EiifR32F: + return "RWCube_float4_"; + case EiifRGBA8: + return "RWCube_unorm_float4_"; + case EiifRGBA8_SNORM: + return "RWCube_unorm_float4_"; + default: + UNREACHABLE(); + } + } + case EbtIImageCube: + { + switch (imageInternalFormat) + { + case EiifRGBA32I: + case EiifRGBA16I: + case EiifRGBA8I: + case EiifR32I: + return "RWCube_int4_"; + default: + UNREACHABLE(); + } + } + case EbtUImageCube: + { + switch (imageInternalFormat) + { + case EiifRGBA32UI: + case EiifRGBA16UI: + case EiifRGBA8UI: + case EiifR32UI: + return "RWCube_uint4_"; + default: + UNREACHABLE(); + } + } + default: + // All other types are identified by their group suffix + return TextureGroupSuffix(type, imageInternalFormat); + } } TString DecorateField(const TString &string, const TStructure &structure) @@ -214,10 +715,13 @@ TString Decorate(const TString &string) return string; } -TString DecorateIfNeeded(const TName &name) +TString DecorateVariableIfNeeded(const TName &name) { if (name.isInternal()) { + // The name should not have a prefix reserved for user-defined variables or functions. + ASSERT(name.getString().compare(0, 2, "f_") != 0); + ASSERT(name.getString().compare(0, 1, "_") != 0); return name.getString(); } else @@ -230,25 +734,29 @@ TString DecorateFunctionIfNeeded(const TName &name) { if (name.isInternal()) { - return TFunction::unmangleName(name.getString()); - } - else - { - return Decorate(TFunction::unmangleName(name.getString())); + // The name should not have a prefix reserved for user-defined variables or functions. + ASSERT(name.getString().compare(0, 2, "f_") != 0); + ASSERT(name.getString().compare(0, 1, "_") != 0); + return name.getString(); } + ASSERT(name.getString().compare(0, 3, "gl_") != 0); + // Add an additional f prefix to functions so that they're always disambiguated from variables. + // This is necessary in the corner case where a variable declaration hides a function that it + // uses in its initializer. + return "f_" + name.getString(); } TString TypeString(const TType &type) { - const TStructure* structure = type.getStruct(); + const TStructure *structure = type.getStruct(); if (structure) { - const TString& typeName = structure->name(); + const TString &typeName = structure->name(); if (typeName != "") { return StructNameString(*structure); } - else // Nameless structure, define in place + else // Nameless structure, define in place { return StructureHLSL::defineNameless(*structure); } @@ -263,55 +771,73 @@ TString TypeString(const TType &type) { switch (type.getBasicType()) { - case EbtFloat: - switch (type.getNominalSize()) - { - case 1: return "float"; - case 2: return "float2"; - case 3: return "float3"; - case 4: return "float4"; - } - case EbtInt: - switch (type.getNominalSize()) - { - case 1: return "int"; - case 2: return "int2"; - case 3: return "int3"; - case 4: return "int4"; - } - case EbtUInt: - switch (type.getNominalSize()) - { - case 1: return "uint"; - case 2: return "uint2"; - case 3: return "uint3"; - case 4: return "uint4"; - } - case EbtBool: - switch (type.getNominalSize()) - { - case 1: return "bool"; - case 2: return "bool2"; - case 3: return "bool3"; - case 4: return "bool4"; - } - case EbtVoid: - return "void"; - case EbtSampler2D: - case EbtISampler2D: - case EbtUSampler2D: - case EbtSampler2DArray: - case EbtISampler2DArray: - case EbtUSampler2DArray: - return "sampler2D"; - case EbtSamplerCube: - case EbtISamplerCube: - case EbtUSamplerCube: - return "samplerCUBE"; - case EbtSamplerExternalOES: - return "sampler2D"; - default: - break; + case EbtFloat: + switch (type.getNominalSize()) + { + case 1: + return "float"; + case 2: + return "float2"; + case 3: + return "float3"; + case 4: + return "float4"; + } + case EbtInt: + switch (type.getNominalSize()) + { + case 1: + return "int"; + case 2: + return "int2"; + case 3: + return "int3"; + case 4: + return "int4"; + } + case EbtUInt: + switch (type.getNominalSize()) + { + case 1: + return "uint"; + case 2: + return "uint2"; + case 3: + return "uint3"; + case 4: + return "uint4"; + } + case EbtBool: + switch (type.getNominalSize()) + { + case 1: + return "bool"; + case 2: + return "bool2"; + case 3: + return "bool3"; + case 4: + return "bool4"; + } + case EbtVoid: + return "void"; + case EbtSampler2D: + case EbtISampler2D: + case EbtUSampler2D: + case EbtSampler2DArray: + case EbtISampler2DArray: + case EbtUSampler2DArray: + return "sampler2D"; + case EbtSamplerCube: + case EbtISamplerCube: + case EbtUSamplerCube: + return "samplerCUBE"; + case EbtSamplerExternalOES: + return "sampler2D"; + case EbtAtomicCounter: + return "atomic_uint"; + default: + break; } } @@ -336,7 +862,8 @@ TString StructNameString(const TStructure &structure) return "ss" + str(structure.uniqueId()) + "_" + structure.name(); } -TString QualifiedStructNameString(const TStructure &structure, bool useHLSLRowMajorPacking, +TString QualifiedStructNameString(const TStructure &structure, + bool useHLSLRowMajorPacking, bool useStd140Packing) { if (structure.name() == "") @@ -366,17 +893,28 @@ TString InterpolationString(TQualifier qualifier) { switch (qualifier) { - case EvqVaryingIn: return ""; - case EvqFragmentIn: return ""; - case EvqSmoothIn: return "linear"; - case EvqFlatIn: return "nointerpolation"; - case EvqCentroidIn: return "centroid"; - case EvqVaryingOut: return ""; - case EvqVertexOut: return ""; - case EvqSmoothOut: return "linear"; - case EvqFlatOut: return "nointerpolation"; - case EvqCentroidOut: return "centroid"; - default: UNREACHABLE(); + case EvqVaryingIn: + return ""; + case EvqFragmentIn: + return ""; + case EvqSmoothIn: + return "linear"; + case EvqFlatIn: + return "nointerpolation"; + case EvqCentroidIn: + return "centroid"; + case EvqVaryingOut: + return ""; + case EvqVertexOut: + return ""; + case EvqSmoothOut: + return "linear"; + case EvqFlatOut: + return "nointerpolation"; + case EvqCentroidOut: + return "centroid"; + default: + UNREACHABLE(); } return ""; @@ -386,53 +924,47 @@ TString QualifierString(TQualifier qualifier) { switch (qualifier) { - case EvqIn: return "in"; - case EvqOut: return "inout"; // 'out' results in an HLSL error if not all fields are written, for GLSL it's undefined - case EvqInOut: return "inout"; - case EvqConstReadOnly: return "const"; - default: UNREACHABLE(); + case EvqIn: + return "in"; + case EvqOut: + return "inout"; // 'out' results in an HLSL error if not all fields are written, for + // GLSL it's undefined + case EvqInOut: + return "inout"; + case EvqConstReadOnly: + return "const"; + default: + UNREACHABLE(); } return ""; } -int HLSLTextureCoordsCount(const TBasicType samplerType) +TString DisambiguateFunctionName(const TIntermSequence *parameters) { - switch (samplerType) + TString disambiguatingString; + for (auto parameter : *parameters) { - case EbtSampler2D: - return 2; - case EbtSampler3D: - return 3; - case EbtSamplerCube: - return 3; - case EbtSampler2DArray: - return 3; - case EbtISampler2D: - return 2; - case EbtISampler3D: - return 3; - case EbtISamplerCube: - return 3; - case EbtISampler2DArray: - return 3; - case EbtUSampler2D: - return 2; - case EbtUSampler3D: - return 3; - case EbtUSamplerCube: - return 3; - case EbtUSampler2DArray: - return 3; - case EbtSampler2DShadow: - return 2; - case EbtSamplerCubeShadow: - return 3; - case EbtSampler2DArrayShadow: - return 3; - default: - UNREACHABLE(); + const TType ¶mType = parameter->getAsTyped()->getType(); + // Parameter types are only added to function names if they are ambiguous according to the + // native HLSL compiler. Other parameter types are not added to function names to avoid + // making function names longer. + if (paramType.getObjectSize() == 4 && paramType.getBasicType() == EbtFloat) + { + // Disambiguation is needed for float2x2 and float4 parameters. These are the only + // built-in types that HLSL thinks are identical. float2x3 and float3x2 are different + // types, for example. + disambiguatingString += "_" + TypeString(paramType); + } + else if (paramType.getBasicType() == EbtStruct) + { + // Disambiguation is needed for struct parameters, since HLSL thinks that structs with + // the same fields but a different name are identical. + ASSERT(paramType.getStruct()->name() != ""); + disambiguatingString += "_" + TypeString(paramType); + } } - return 0; -} + return disambiguatingString; } + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/UtilsHLSL.h b/src/3rdparty/angle/src/compiler/translator/UtilsHLSL.h index 42444e3a56..daeec8de41 100644 --- a/src/3rdparty/angle/src/compiler/translator/UtilsHLSL.h +++ b/src/3rdparty/angle/src/compiler/translator/UtilsHLSL.h @@ -11,6 +11,7 @@ #define COMPILER_TRANSLATOR_UTILSHLSL_H_ #include +#include "compiler/translator/IntermNode.h" #include "compiler/translator/Types.h" #include "angle_gl.h" @@ -20,22 +21,33 @@ class TName; namespace sh { -// Unique combinations of HLSL Texture type and HLSL Sampler type. -enum HLSLTextureSamplerGroup +// HLSL Texture type for GLSL sampler type and readonly image type. +enum HLSLTextureGroup { - // Regular samplers + // read resources HLSL_TEXTURE_2D, HLSL_TEXTURE_MIN = HLSL_TEXTURE_2D, HLSL_TEXTURE_CUBE, HLSL_TEXTURE_2D_ARRAY, HLSL_TEXTURE_3D, + HLSL_TEXTURE_2D_UNORM, + HLSL_TEXTURE_CUBE_UNORM, + HLSL_TEXTURE_2D_ARRAY_UNORN, + HLSL_TEXTURE_3D_UNORM, + HLSL_TEXTURE_2D_SNORM, + HLSL_TEXTURE_CUBE_SNORM, + HLSL_TEXTURE_2D_ARRAY_SNORM, + HLSL_TEXTURE_3D_SNORM, + HLSL_TEXTURE_2D_MS, HLSL_TEXTURE_2D_INT4, HLSL_TEXTURE_3D_INT4, HLSL_TEXTURE_2D_ARRAY_INT4, + HLSL_TEXTURE_2D_MS_INT4, HLSL_TEXTURE_2D_UINT4, HLSL_TEXTURE_3D_UINT4, HLSL_TEXTURE_2D_ARRAY_UINT4, + HLSL_TEXTURE_2D_MS_UINT4, // Comparison samplers @@ -50,29 +62,68 @@ enum HLSLTextureSamplerGroup HLSL_TEXTURE_MAX = HLSL_TEXTURE_UNKNOWN }; -HLSLTextureSamplerGroup TextureGroup(const TBasicType type); -TString TextureString(const HLSLTextureSamplerGroup type); -TString TextureString(const TBasicType type); -TString TextureGroupSuffix(const HLSLTextureSamplerGroup type); -TString TextureGroupSuffix(const TBasicType type); -TString TextureTypeSuffix(const TBasicType type); +// HLSL RWTexture type for GLSL read and write image type. +enum HLSLRWTextureGroup +{ + // read/write resource + HLSL_RWTEXTURE_2D_FLOAT4, + HLSL_RWTEXTURE_MIN = HLSL_RWTEXTURE_2D_FLOAT4, + HLSL_RWTEXTURE_2D_ARRAY_FLOAT4, + HLSL_RWTEXTURE_3D_FLOAT4, + HLSL_RWTEXTURE_2D_UNORM, + HLSL_RWTEXTURE_2D_ARRAY_UNORN, + HLSL_RWTEXTURE_3D_UNORM, + HLSL_RWTEXTURE_2D_SNORM, + HLSL_RWTEXTURE_2D_ARRAY_SNORM, + HLSL_RWTEXTURE_3D_SNORM, + HLSL_RWTEXTURE_2D_UINT4, + HLSL_RWTEXTURE_2D_ARRAY_UINT4, + HLSL_RWTEXTURE_3D_UINT4, + HLSL_RWTEXTURE_2D_INT4, + HLSL_RWTEXTURE_2D_ARRAY_INT4, + HLSL_RWTEXTURE_3D_INT4, + + HLSL_RWTEXTURE_UNKNOWN, + HLSL_RWTEXTURE_MAX = HLSL_RWTEXTURE_UNKNOWN +}; + +HLSLTextureGroup TextureGroup(const TBasicType type, + TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified); +TString TextureString(const HLSLTextureGroup textureGroup); +TString TextureString(const TBasicType type, + TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified); +TString TextureGroupSuffix(const HLSLTextureGroup type); +TString TextureGroupSuffix(const TBasicType type, + TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified); +TString TextureTypeSuffix(const TBasicType type, + TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified); +HLSLRWTextureGroup RWTextureGroup(const TBasicType type, + TLayoutImageInternalFormat imageInternalFormat); +TString RWTextureString(const HLSLRWTextureGroup textureGroup); +TString RWTextureString(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat); +TString RWTextureGroupSuffix(const HLSLRWTextureGroup type); +TString RWTextureGroupSuffix(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat); +TString RWTextureTypeSuffix(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat); + TString SamplerString(const TBasicType type); -TString SamplerString(HLSLTextureSamplerGroup type); -// Prepends an underscore to avoid naming clashes +TString SamplerString(HLSLTextureGroup type); + +// Adds a prefix to user-defined names to avoid naming clashes. TString Decorate(const TString &string); -TString DecorateIfNeeded(const TName &name); -// Decorates and also unmangles the function name +TString DecorateVariableIfNeeded(const TName &name); TString DecorateFunctionIfNeeded(const TName &name); -TString DecorateUniform(const TString &string, const TType &type); TString DecorateField(const TString &string, const TStructure &structure); TString DecoratePrivate(const TString &privateText); TString TypeString(const TType &type); TString StructNameString(const TStructure &structure); -TString QualifiedStructNameString(const TStructure &structure, bool useHLSLRowMajorPacking, +TString QualifiedStructNameString(const TStructure &structure, + bool useHLSLRowMajorPacking, bool useStd140Packing); TString InterpolationString(TQualifier qualifier); TString QualifierString(TQualifier qualifier); -int HLSLTextureCoordsCount(const TBasicType samplerType); +// Parameters may need to be included in function names to disambiguate between overloaded +// functions. +TString DisambiguateFunctionName(const TIntermSequence *parameters); } -#endif // COMPILER_TRANSLATOR_UTILSHLSL_H_ +#endif // COMPILER_TRANSLATOR_UTILSHLSL_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/ValidateGlobalInitializer.cpp b/src/3rdparty/angle/src/compiler/translator/ValidateGlobalInitializer.cpp index 2461b6a438..492972b60d 100644 --- a/src/3rdparty/angle/src/compiler/translator/ValidateGlobalInitializer.cpp +++ b/src/3rdparty/angle/src/compiler/translator/ValidateGlobalInitializer.cpp @@ -6,8 +6,12 @@ #include "compiler/translator/ValidateGlobalInitializer.h" +#include "compiler/translator/IntermTraverse.h" #include "compiler/translator/ParseContext.h" +namespace sh +{ + namespace { @@ -32,7 +36,8 @@ class ValidateGlobalInitializerTraverser : public TIntermTraverser void ValidateGlobalInitializerTraverser::visitSymbol(TIntermSymbol *node) { - const TSymbol *sym = mContext->symbolTable.find(node->getSymbol(), mContext->getShaderVersion()); + const TSymbol *sym = + mContext->symbolTable.find(node->getSymbol(), mContext->getShaderVersion()); if (sym->isVariable()) { // ESSL 1.00 section 4.3 (or ESSL 3.00 section 4.3): @@ -40,33 +45,36 @@ void ValidateGlobalInitializerTraverser::visitSymbol(TIntermSymbol *node) const TVariable *var = static_cast(sym); switch (var->getType().getQualifier()) { - case EvqConst: - break; - case EvqGlobal: - case EvqTemporary: - case EvqUniform: - // We allow these cases to be compatible with legacy ESSL 1.00 content. - // Implement stricter rules for ESSL 3.00 since there's no legacy content to deal with. - if (mContext->getShaderVersion() >= 300) - { + case EvqConst: + break; + case EvqGlobal: + case EvqTemporary: + case EvqUniform: + // We allow these cases to be compatible with legacy ESSL 1.00 content. + // Implement stricter rules for ESSL 3.00 since there's no legacy content to deal + // with. + if (mContext->getShaderVersion() >= 300) + { + mIsValid = false; + } + else + { + mIssueWarning = true; + } + break; + default: mIsValid = false; - } - else - { - mIssueWarning = true; - } - break; - default: - mIsValid = false; } } } bool ValidateGlobalInitializerTraverser::visitAggregate(Visit visit, TIntermAggregate *node) { - // Disallow calls to user-defined functions and texture lookup functions in global variable initializers. - // This is done simply by disabling all function calls - built-in math functions don't use EOpFunctionCall. - if (node->getOp() == EOpFunctionCall) + // Disallow calls to user-defined functions and texture lookup functions in global variable + // initializers. + // This is done simply by disabling all function calls - built-in math functions don't use + // the function call ops. + if (node->isFunctionCall()) { mIsValid = false; } @@ -92,16 +100,15 @@ bool ValidateGlobalInitializerTraverser::visitUnary(Visit visit, TIntermUnary *n } ValidateGlobalInitializerTraverser::ValidateGlobalInitializerTraverser(const TParseContext *context) - : TIntermTraverser(true, false, false), - mContext(context), - mIsValid(true), - mIssueWarning(false) + : TIntermTraverser(true, false, false), mContext(context), mIsValid(true), mIssueWarning(false) { } -} // namespace +} // namespace -bool ValidateGlobalInitializer(TIntermTyped *initializer, const TParseContext *context, bool *warning) +bool ValidateGlobalInitializer(TIntermTyped *initializer, + const TParseContext *context, + bool *warning) { ValidateGlobalInitializerTraverser validate(context); initializer->traverse(&validate); @@ -110,3 +117,4 @@ bool ValidateGlobalInitializer(TIntermTyped *initializer, const TParseContext *c return validate.isValid(); } +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/ValidateGlobalInitializer.h b/src/3rdparty/angle/src/compiler/translator/ValidateGlobalInitializer.h index c3d2a47eba..2e7570667a 100644 --- a/src/3rdparty/angle/src/compiler/translator/ValidateGlobalInitializer.h +++ b/src/3rdparty/angle/src/compiler/translator/ValidateGlobalInitializer.h @@ -7,10 +7,17 @@ #ifndef COMPILER_TRANSLATOR_VALIDATEGLOBALINITIALIZER_H_ #define COMPILER_TRANSLATOR_VALIDATEGLOBALINITIALIZER_H_ +namespace sh +{ + class TIntermTyped; class TParseContext; // Returns true if the initializer is valid. -bool ValidateGlobalInitializer(TIntermTyped *initializer, const TParseContext *context, bool *warning); +bool ValidateGlobalInitializer(TIntermTyped *initializer, + const TParseContext *context, + bool *warning); -#endif // COMPILER_TRANSLATOR_VALIDATEGLOBALINITIALIZER_H_ +} // namespace sh + +#endif // COMPILER_TRANSLATOR_VALIDATEGLOBALINITIALIZER_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.cpp b/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.cpp index ba8cdd0aa8..941f79ae51 100644 --- a/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.cpp +++ b/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.cpp @@ -5,14 +5,29 @@ // #include "compiler/translator/ValidateLimitations.h" -#include "compiler/translator/InfoSink.h" -#include "compiler/translator/InitializeParseContext.h" -#include "compiler/translator/ParseContext.h" + #include "angle_gl.h" +#include "compiler/translator/Diagnostics.h" +#include "compiler/translator/IntermTraverse.h" +#include "compiler/translator/ParseContext.h" + +namespace sh +{ namespace { +int GetLoopSymbolId(TIntermLoop *loop) +{ + // Here we assume all the operations are valid, because the loop node is + // already validated before this call. + TIntermSequence *declSeq = loop->getInit()->getAsDeclarationNode()->getSequence(); + TIntermBinary *declInit = (*declSeq)[0]->getAsBinaryNode(); + TIntermSymbol *symbol = declInit->getLeft()->getAsSymbolNode(); + + return symbol->getId(); +} + // Traverses a node to check if it represents a constant index expression. // Definition: // constant-index-expressions are a superset of constant-expressions. @@ -25,10 +40,8 @@ namespace class ValidateConstIndexExpr : public TIntermTraverser { public: - ValidateConstIndexExpr(TLoopStack& stack) - : TIntermTraverser(true, false, false), - mValid(true), - mLoopStack(stack) + ValidateConstIndexExpr(const std::vector &loopSymbols) + : TIntermTraverser(true, false, false), mValid(true), mLoopSymbolIds(loopSymbols) { } @@ -41,93 +54,93 @@ class ValidateConstIndexExpr : public TIntermTraverser // constant index expression. if (mValid) { - mValid = (symbol->getQualifier() == EvqConst) || - (mLoopStack.findLoop(symbol)); + bool isLoopSymbol = std::find(mLoopSymbolIds.begin(), mLoopSymbolIds.end(), + symbol->getId()) != mLoopSymbolIds.end(); + mValid = (symbol->getQualifier() == EvqConst) || isLoopSymbol; } } private: bool mValid; - TLoopStack& mLoopStack; + const std::vector mLoopSymbolIds; }; -} // namespace anonymous +// Traverses intermediate tree to ensure that the shader does not exceed the +// minimum functionality mandated in GLSL 1.0 spec, Appendix A. +class ValidateLimitationsTraverser : public TLValueTrackingTraverser +{ + public: + ValidateLimitationsTraverser(sh::GLenum shaderType, + TSymbolTable *symbolTable, + int shaderVersion, + TDiagnostics *diagnostics); -ValidateLimitations::ValidateLimitations(sh::GLenum shaderType, TInfoSinkBase *sink) - : TIntermTraverser(true, false, false), + void visitSymbol(TIntermSymbol *node) override; + bool visitBinary(Visit, TIntermBinary *) override; + bool visitLoop(Visit, TIntermLoop *) override; + + private: + void error(TSourceLoc loc, const char *reason, const char *token); + + bool withinLoopBody() const; + bool isLoopIndex(TIntermSymbol *symbol); + bool validateLoopType(TIntermLoop *node); + + bool validateForLoopHeader(TIntermLoop *node); + // If valid, return the index symbol id; Otherwise, return -1. + int validateForLoopInit(TIntermLoop *node); + bool validateForLoopCond(TIntermLoop *node, int indexSymbolId); + bool validateForLoopExpr(TIntermLoop *node, int indexSymbolId); + + // Returns true if indexing does not exceed the minimum functionality + // mandated in GLSL 1.0 spec, Appendix A, Section 5. + bool isConstExpr(TIntermNode *node); + bool isConstIndexExpr(TIntermNode *node); + bool validateIndexing(TIntermBinary *node); + + sh::GLenum mShaderType; + TDiagnostics *mDiagnostics; + std::vector mLoopSymbolIds; +}; + +ValidateLimitationsTraverser::ValidateLimitationsTraverser(sh::GLenum shaderType, + TSymbolTable *symbolTable, + int shaderVersion, + TDiagnostics *diagnostics) + : TLValueTrackingTraverser(true, false, false, symbolTable, shaderVersion), mShaderType(shaderType), - mSink(sink), - mNumErrors(0), - mValidateIndexing(true), - mValidateInnerLoops(true) + mDiagnostics(diagnostics) { + ASSERT(diagnostics); } -// static -bool ValidateLimitations::IsLimitedForLoop(TIntermLoop *loop) +void ValidateLimitationsTraverser::visitSymbol(TIntermSymbol *node) { - // The shader type doesn't matter in this case. - ValidateLimitations validate(GL_FRAGMENT_SHADER, nullptr); - validate.mValidateIndexing = false; - validate.mValidateInnerLoops = false; - if (!validate.validateLoopType(loop)) - return false; - if (!validate.validateForLoopHeader(loop)) - return false; - TIntermNode *body = loop->getBody(); - if (body != nullptr) + if (isLoopIndex(node) && isLValueRequiredHere()) { - validate.mLoopStack.push(loop); - body->traverse(&validate); - validate.mLoopStack.pop(); + error(node->getLine(), + "Loop index cannot be statically assigned to within the body of the loop", + node->getSymbol().c_str()); } - return (validate.mNumErrors == 0); } -bool ValidateLimitations::visitBinary(Visit, TIntermBinary *node) +bool ValidateLimitationsTraverser::visitBinary(Visit, TIntermBinary *node) { - // Check if loop index is modified in the loop body. - validateOperation(node, node->getLeft()); - // Check indexing. switch (node->getOp()) { - case EOpIndexDirect: - case EOpIndexIndirect: - if (mValidateIndexing) - validateIndexing(node); - break; - default: - break; + case EOpIndexDirect: + case EOpIndexIndirect: + validateIndexing(node); + break; + default: + break; } return true; } -bool ValidateLimitations::visitUnary(Visit, TIntermUnary *node) +bool ValidateLimitationsTraverser::visitLoop(Visit, TIntermLoop *node) { - // Check if loop index is modified in the loop body. - validateOperation(node, node->getOperand()); - - return true; -} - -bool ValidateLimitations::visitAggregate(Visit, TIntermAggregate *node) -{ - switch (node->getOp()) { - case EOpFunctionCall: - validateFunctionCall(node); - break; - default: - break; - } - return true; -} - -bool ValidateLimitations::visitLoop(Visit, TIntermLoop *node) -{ - if (!mValidateInnerLoops) - return true; - if (!validateLoopType(node)) return false; @@ -135,53 +148,45 @@ bool ValidateLimitations::visitLoop(Visit, TIntermLoop *node) return false; TIntermNode *body = node->getBody(); - if (body != NULL) + if (body != nullptr) { - mLoopStack.push(node); + mLoopSymbolIds.push_back(GetLoopSymbolId(node)); body->traverse(this); - mLoopStack.pop(); + mLoopSymbolIds.pop_back(); } // The loop is fully processed - no need to visit children. return false; } -void ValidateLimitations::error(TSourceLoc loc, - const char *reason, const char *token) +void ValidateLimitationsTraverser::error(TSourceLoc loc, const char *reason, const char *token) { - if (mSink) - { - mSink->prefix(EPrefixError); - mSink->location(loc); - (*mSink) << "'" << token << "' : " << reason << "\n"; - } - ++mNumErrors; + mDiagnostics->error(loc, reason, token); } -bool ValidateLimitations::withinLoopBody() const +bool ValidateLimitationsTraverser::withinLoopBody() const { - return !mLoopStack.empty(); + return !mLoopSymbolIds.empty(); } -bool ValidateLimitations::isLoopIndex(TIntermSymbol *symbol) +bool ValidateLimitationsTraverser::isLoopIndex(TIntermSymbol *symbol) { - return mLoopStack.findLoop(symbol) != NULL; + return std::find(mLoopSymbolIds.begin(), mLoopSymbolIds.end(), symbol->getId()) != + mLoopSymbolIds.end(); } -bool ValidateLimitations::validateLoopType(TIntermLoop *node) +bool ValidateLimitationsTraverser::validateLoopType(TIntermLoop *node) { TLoopType type = node->getType(); if (type == ELoopFor) return true; // Reject while and do-while loops. - error(node->getLine(), - "This type of loop is not allowed", - type == ELoopWhile ? "while" : "do"); + error(node->getLine(), "This type of loop is not allowed", type == ELoopWhile ? "while" : "do"); return false; } -bool ValidateLimitations::validateForLoopHeader(TIntermLoop *node) +bool ValidateLimitationsTraverser::validateForLoopHeader(TIntermLoop *node) { ASSERT(node->getType() == ELoopFor); @@ -200,10 +205,10 @@ bool ValidateLimitations::validateForLoopHeader(TIntermLoop *node) return true; } -int ValidateLimitations::validateForLoopInit(TIntermLoop *node) +int ValidateLimitationsTraverser::validateForLoopInit(TIntermLoop *node) { TIntermNode *init = node->getInit(); - if (init == NULL) + if (init == nullptr) { error(node->getLine(), "Missing init declaration", "for"); return -1; @@ -213,8 +218,8 @@ int ValidateLimitations::validateForLoopInit(TIntermLoop *node) // init-declaration has the form: // type-specifier identifier = constant-expression // - TIntermAggregate *decl = init->getAsAggregate(); - if ((decl == NULL) || (decl->getOp() != EOpDeclaration)) + TIntermDeclaration *decl = init->getAsDeclarationNode(); + if (decl == nullptr) { error(init->getLine(), "Invalid init declaration", "for"); return -1; @@ -227,29 +232,28 @@ int ValidateLimitations::validateForLoopInit(TIntermLoop *node) return -1; } TIntermBinary *declInit = (*declSeq)[0]->getAsBinaryNode(); - if ((declInit == NULL) || (declInit->getOp() != EOpInitialize)) + if ((declInit == nullptr) || (declInit->getOp() != EOpInitialize)) { error(decl->getLine(), "Invalid init declaration", "for"); return -1; } TIntermSymbol *symbol = declInit->getLeft()->getAsSymbolNode(); - if (symbol == NULL) + if (symbol == nullptr) { error(declInit->getLine(), "Invalid init declaration", "for"); return -1; } // The loop index has type int or float. TBasicType type = symbol->getBasicType(); - if ((type != EbtInt) && (type != EbtUInt) && (type != EbtFloat)) { - error(symbol->getLine(), - "Invalid type for loop index", getBasicString(type)); + if ((type != EbtInt) && (type != EbtUInt) && (type != EbtFloat)) + { + error(symbol->getLine(), "Invalid type for loop index", getBasicString(type)); return -1; } // The loop index is initialized with constant expression. if (!isConstExpr(declInit->getRight())) { - error(declInit->getLine(), - "Loop index cannot be initialized with non-constant expression", + error(declInit->getLine(), "Loop index cannot be initialized with non-constant expression", symbol->getSymbol().c_str()); return -1; } @@ -257,11 +261,10 @@ int ValidateLimitations::validateForLoopInit(TIntermLoop *node) return symbol->getId(); } -bool ValidateLimitations::validateForLoopCond(TIntermLoop *node, - int indexSymbolId) +bool ValidateLimitationsTraverser::validateForLoopCond(TIntermLoop *node, int indexSymbolId) { TIntermNode *cond = node->getCondition(); - if (cond == NULL) + if (cond == nullptr) { error(node->getLine(), "Missing condition", "for"); return false; @@ -271,45 +274,42 @@ bool ValidateLimitations::validateForLoopCond(TIntermLoop *node, // loop_index relational_operator constant_expression // TIntermBinary *binOp = cond->getAsBinaryNode(); - if (binOp == NULL) + if (binOp == nullptr) { error(node->getLine(), "Invalid condition", "for"); return false; } // Loop index should be to the left of relational operator. TIntermSymbol *symbol = binOp->getLeft()->getAsSymbolNode(); - if (symbol == NULL) + if (symbol == nullptr) { error(binOp->getLine(), "Invalid condition", "for"); return false; } if (symbol->getId() != indexSymbolId) { - error(symbol->getLine(), - "Expected loop index", symbol->getSymbol().c_str()); + error(symbol->getLine(), "Expected loop index", symbol->getSymbol().c_str()); return false; } // Relational operator is one of: > >= < <= == or !=. switch (binOp->getOp()) { - case EOpEqual: - case EOpNotEqual: - case EOpLessThan: - case EOpGreaterThan: - case EOpLessThanEqual: - case EOpGreaterThanEqual: - break; - default: - error(binOp->getLine(), - "Invalid relational operator", - GetOperatorString(binOp->getOp())); - break; + case EOpEqual: + case EOpNotEqual: + case EOpLessThan: + case EOpGreaterThan: + case EOpLessThanEqual: + case EOpGreaterThanEqual: + break; + default: + error(binOp->getLine(), "Invalid relational operator", + GetOperatorString(binOp->getOp())); + break; } // Loop index must be compared with a constant. if (!isConstExpr(binOp->getRight())) { - error(binOp->getLine(), - "Loop index cannot be compared with non-constant expression", + error(binOp->getLine(), "Loop index cannot be compared with non-constant expression", symbol->getSymbol().c_str()); return false; } @@ -317,11 +317,10 @@ bool ValidateLimitations::validateForLoopCond(TIntermLoop *node, return true; } -bool ValidateLimitations::validateForLoopExpr(TIntermLoop *node, - int indexSymbolId) +bool ValidateLimitationsTraverser::validateForLoopExpr(TIntermLoop *node, int indexSymbolId) { TIntermNode *expr = node->getExpression(); - if (expr == NULL) + if (expr == nullptr) { error(node->getLine(), "Missing expression", "for"); return false; @@ -336,60 +335,58 @@ bool ValidateLimitations::validateForLoopExpr(TIntermLoop *node, // --loop_index // The last two forms are not specified in the spec, but I am assuming // its an oversight. - TIntermUnary *unOp = expr->getAsUnaryNode(); - TIntermBinary *binOp = unOp ? NULL : expr->getAsBinaryNode(); + TIntermUnary *unOp = expr->getAsUnaryNode(); + TIntermBinary *binOp = unOp ? nullptr : expr->getAsBinaryNode(); - TOperator op = EOpNull; - TIntermSymbol *symbol = NULL; - if (unOp != NULL) + TOperator op = EOpNull; + TIntermSymbol *symbol = nullptr; + if (unOp != nullptr) { - op = unOp->getOp(); + op = unOp->getOp(); symbol = unOp->getOperand()->getAsSymbolNode(); } - else if (binOp != NULL) + else if (binOp != nullptr) { - op = binOp->getOp(); + op = binOp->getOp(); symbol = binOp->getLeft()->getAsSymbolNode(); } // The operand must be loop index. - if (symbol == NULL) + if (symbol == nullptr) { error(expr->getLine(), "Invalid expression", "for"); return false; } if (symbol->getId() != indexSymbolId) { - error(symbol->getLine(), - "Expected loop index", symbol->getSymbol().c_str()); + error(symbol->getLine(), "Expected loop index", symbol->getSymbol().c_str()); return false; } // The operator is one of: ++ -- += -=. switch (op) { - case EOpPostIncrement: - case EOpPostDecrement: - case EOpPreIncrement: - case EOpPreDecrement: - ASSERT((unOp != NULL) && (binOp == NULL)); - break; - case EOpAddAssign: - case EOpSubAssign: - ASSERT((unOp == NULL) && (binOp != NULL)); - break; - default: - error(expr->getLine(), "Invalid operator", GetOperatorString(op)); - return false; + case EOpPostIncrement: + case EOpPostDecrement: + case EOpPreIncrement: + case EOpPreDecrement: + ASSERT((unOp != nullptr) && (binOp == nullptr)); + break; + case EOpAddAssign: + case EOpSubAssign: + ASSERT((unOp == nullptr) && (binOp != nullptr)); + break; + default: + error(expr->getLine(), "Invalid operator", GetOperatorString(op)); + return false; } // Loop index must be incremented/decremented with a constant. - if (binOp != NULL) + if (binOp != nullptr) { if (!isConstExpr(binOp->getRight())) { - error(binOp->getLine(), - "Loop index cannot be modified by non-constant expression", + error(binOp->getLine(), "Loop index cannot be modified by non-constant expression", symbol->getSymbol().c_str()); return false; } @@ -398,95 +395,31 @@ bool ValidateLimitations::validateForLoopExpr(TIntermLoop *node, return true; } -bool ValidateLimitations::validateFunctionCall(TIntermAggregate *node) -{ - ASSERT(node->getOp() == EOpFunctionCall); - - // If not within loop body, there is nothing to check. - if (!withinLoopBody()) - return true; - - // List of param indices for which loop indices are used as argument. - typedef std::vector ParamIndex; - ParamIndex pIndex; - TIntermSequence *params = node->getSequence(); - for (TIntermSequence::size_type i = 0; i < params->size(); ++i) - { - TIntermSymbol *symbol = (*params)[i]->getAsSymbolNode(); - if (symbol && isLoopIndex(symbol)) - pIndex.push_back(i); - } - // If none of the loop indices are used as arguments, - // there is nothing to check. - if (pIndex.empty()) - return true; - - bool valid = true; - TSymbolTable& symbolTable = GetGlobalParseContext()->symbolTable; - TSymbol* symbol = symbolTable.find(node->getName(), GetGlobalParseContext()->getShaderVersion()); - ASSERT(symbol && symbol->isFunction()); - TFunction *function = static_cast(symbol); - for (ParamIndex::const_iterator i = pIndex.begin(); - i != pIndex.end(); ++i) - { - const TConstParameter ¶m = function->getParam(*i); - TQualifier qual = param.type->getQualifier(); - if ((qual == EvqOut) || (qual == EvqInOut)) - { - error((*params)[*i]->getLine(), - "Loop index cannot be used as argument to a function out or inout parameter", - (*params)[*i]->getAsSymbolNode()->getSymbol().c_str()); - valid = false; - } - } - - return valid; -} - -bool ValidateLimitations::validateOperation(TIntermOperator *node, - TIntermNode* operand) -{ - // Check if loop index is modified in the loop body. - if (!withinLoopBody() || !node->isAssignment()) - return true; - - TIntermSymbol *symbol = operand->getAsSymbolNode(); - if (symbol && isLoopIndex(symbol)) - { - error(node->getLine(), - "Loop index cannot be statically assigned to within the body of the loop", - symbol->getSymbol().c_str()); - } - return true; -} - -bool ValidateLimitations::isConstExpr(TIntermNode *node) +bool ValidateLimitationsTraverser::isConstExpr(TIntermNode *node) { ASSERT(node != nullptr); return node->getAsConstantUnion() != nullptr && node->getAsTyped()->getQualifier() == EvqConst; } -bool ValidateLimitations::isConstIndexExpr(TIntermNode *node) +bool ValidateLimitationsTraverser::isConstIndexExpr(TIntermNode *node) { - ASSERT(node != NULL); + ASSERT(node != nullptr); - ValidateConstIndexExpr validate(mLoopStack); + ValidateConstIndexExpr validate(mLoopSymbolIds); node->traverse(&validate); return validate.isValid(); } -bool ValidateLimitations::validateIndexing(TIntermBinary *node) +bool ValidateLimitationsTraverser::validateIndexing(TIntermBinary *node) { - ASSERT((node->getOp() == EOpIndexDirect) || - (node->getOp() == EOpIndexIndirect)); + ASSERT((node->getOp() == EOpIndexDirect) || (node->getOp() == EOpIndexIndirect)); - bool valid = true; + bool valid = true; TIntermTyped *index = node->getRight(); // The index expession must be a constant-index-expression unless // the operand is a uniform in a vertex shader. TIntermTyped *operand = node->getLeft(); - bool skip = (mShaderType == GL_VERTEX_SHADER) && - (operand->getQualifier() == EvqUniform); + bool skip = (mShaderType == GL_VERTEX_SHADER) && (operand->getQualifier() == EvqUniform); if (!skip && !isConstIndexExpr(index)) { error(index->getLine(), "Index expression must be constant", "[]"); @@ -495,3 +428,17 @@ bool ValidateLimitations::validateIndexing(TIntermBinary *node) return valid; } +} // namespace anonymous + +bool ValidateLimitations(TIntermNode *root, + GLenum shaderType, + TSymbolTable *symbolTable, + int shaderVersion, + TDiagnostics *diagnostics) +{ + ValidateLimitationsTraverser validate(shaderType, symbolTable, shaderVersion, diagnostics); + root->traverse(&validate); + return diagnostics->numErrors() == 0; +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.h b/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.h index 666e38ff5c..9149b8c216 100644 --- a/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.h +++ b/src/3rdparty/angle/src/compiler/translator/ValidateLimitations.h @@ -8,56 +8,20 @@ #define COMPILER_TRANSLATOR_VALIDATELIMITATIONS_H_ #include "compiler/translator/IntermNode.h" -#include "compiler/translator/LoopInfo.h" -class TInfoSinkBase; - -// Traverses intermediate tree to ensure that the shader does not exceed the -// minimum functionality mandated in GLSL 1.0 spec, Appendix A. -class ValidateLimitations : public TIntermTraverser +namespace sh { - public: - ValidateLimitations(sh::GLenum shaderType, TInfoSinkBase *sink); - int numErrors() const { return mNumErrors; } +class TDiagnostics; - bool visitBinary(Visit, TIntermBinary *) override; - bool visitUnary(Visit, TIntermUnary *) override; - bool visitAggregate(Visit, TIntermAggregate *) override; - bool visitLoop(Visit, TIntermLoop *) override; +// Returns true if the given shader does not exceed the minimum functionality mandated in GLSL ES +// 1.00 spec Appendix A. +bool ValidateLimitations(TIntermNode *root, + GLenum shaderType, + TSymbolTable *symbolTable, + int shaderVersion, + TDiagnostics *diagnostics); - static bool IsLimitedForLoop(TIntermLoop *node); +} // namespace sh - private: - void error(TSourceLoc loc, const char *reason, const char *token); - - bool withinLoopBody() const; - bool isLoopIndex(TIntermSymbol *symbol); - bool validateLoopType(TIntermLoop *node); - - bool validateForLoopHeader(TIntermLoop *node); - // If valid, return the index symbol id; Otherwise, return -1. - int validateForLoopInit(TIntermLoop *node); - bool validateForLoopCond(TIntermLoop *node, int indexSymbolId); - bool validateForLoopExpr(TIntermLoop *node, int indexSymbolId); - - // Returns true if none of the loop indices is used as the argument to - // the given function out or inout parameter. - bool validateFunctionCall(TIntermAggregate *node); - bool validateOperation(TIntermOperator *node, TIntermNode *operand); - - // Returns true if indexing does not exceed the minimum functionality - // mandated in GLSL 1.0 spec, Appendix A, Section 5. - bool isConstExpr(TIntermNode *node); - bool isConstIndexExpr(TIntermNode *node); - bool validateIndexing(TIntermBinary *node); - - sh::GLenum mShaderType; - TInfoSinkBase *mSink; - int mNumErrors; - TLoopStack mLoopStack; - bool mValidateIndexing; - bool mValidateInnerLoops; -}; - -#endif // COMPILER_TRANSLATOR_VALIDATELIMITATIONS_H_ +#endif // COMPILER_TRANSLATOR_VALIDATELIMITATIONS_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/ValidateMaxParameters.cpp b/src/3rdparty/angle/src/compiler/translator/ValidateMaxParameters.cpp new file mode 100644 index 0000000000..9dccbf413f --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/ValidateMaxParameters.cpp @@ -0,0 +1,29 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ValidateMaxParameters checks if function definitions have more than a set number of parameters. + +#include "compiler/translator/ValidateMaxParameters.h" + +#include "compiler/translator/IntermNode.h" + +namespace sh +{ + +bool ValidateMaxParameters(TIntermBlock *root, unsigned int maxParameters) +{ + for (TIntermNode *node : *root->getSequence()) + { + TIntermFunctionDefinition *definition = node->getAsFunctionDefinition(); + if (definition != nullptr && + definition->getFunctionPrototype()->getSequence()->size() > maxParameters) + { + return false; + } + } + return true; +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/ValidateMaxParameters.h b/src/3rdparty/angle/src/compiler/translator/ValidateMaxParameters.h new file mode 100644 index 0000000000..dec7597da4 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/ValidateMaxParameters.h @@ -0,0 +1,21 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ValidateMaxParameters checks if function definitions have more than a set number of parameters. + +#ifndef COMPILER_TRANSLATOR_VALIDATEMAXPARAMETERS_H_ +#define COMPILER_TRANSLATOR_VALIDATEMAXPARAMETERS_H_ + +namespace sh +{ + +class TIntermBlock; + +// Return true if valid. +bool ValidateMaxParameters(TIntermBlock *root, unsigned int maxParameters); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_VALIDATEMAXPARAMETERS_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/ValidateOutputs.cpp b/src/3rdparty/angle/src/compiler/translator/ValidateOutputs.cpp index cd37aeacd1..26f0e81ba7 100644 --- a/src/3rdparty/angle/src/compiler/translator/ValidateOutputs.cpp +++ b/src/3rdparty/angle/src/compiler/translator/ValidateOutputs.cpp @@ -3,64 +3,101 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // +// ValidateOutputs validates fragment shader outputs. It checks for conflicting locations, +// out-of-range locations, that locations are specified when using multiple outputs, and YUV output +// validity. #include "compiler/translator/ValidateOutputs.h" + +#include + #include "compiler/translator/InfoSink.h" -#include "compiler/translator/InitializeParseContext.h" +#include "compiler/translator/IntermTraverse.h" #include "compiler/translator/ParseContext.h" +namespace sh +{ + namespace { -void error(int *errorCount, TInfoSinkBase &sink, const TIntermSymbol &symbol, const char *reason) +void error(const TIntermSymbol &symbol, const char *reason, TDiagnostics *diagnostics) { - sink.prefix(EPrefixError); - sink.location(symbol.getLine()); - sink << "'" << symbol.getSymbol() << "' : " << reason << "\n"; - (*errorCount)++; + diagnostics->error(symbol.getLine(), reason, symbol.getSymbol().c_str()); } -} // namespace +class ValidateOutputsTraverser : public TIntermTraverser +{ + public: + ValidateOutputsTraverser(const TExtensionBehavior &extBehavior, int maxDrawBuffers); -ValidateOutputs::ValidateOutputs(const TExtensionBehavior &extBehavior, int maxDrawBuffers) + void validate(TDiagnostics *diagnostics) const; + + void visitSymbol(TIntermSymbol *) override; + + private: + int mMaxDrawBuffers; + bool mAllowUnspecifiedOutputLocationResolution; + bool mUsesFragDepth; + + typedef std::vector OutputVector; + OutputVector mOutputs; + OutputVector mUnspecifiedLocationOutputs; + OutputVector mYuvOutputs; + std::set mVisitedSymbols; +}; + +ValidateOutputsTraverser::ValidateOutputsTraverser(const TExtensionBehavior &extBehavior, + int maxDrawBuffers) : TIntermTraverser(true, false, false), mMaxDrawBuffers(maxDrawBuffers), mAllowUnspecifiedOutputLocationResolution( - IsExtensionEnabled(extBehavior, "GL_EXT_blend_func_extended")) + IsExtensionEnabled(extBehavior, TExtension::EXT_blend_func_extended)), + mUsesFragDepth(false) { } -void ValidateOutputs::visitSymbol(TIntermSymbol *symbol) +void ValidateOutputsTraverser::visitSymbol(TIntermSymbol *symbol) { - TString name = symbol->getSymbol(); + TString name = symbol->getSymbol(); TQualifier qualifier = symbol->getQualifier(); - if (mVisitedSymbols.count(name) == 1) + if (mVisitedSymbols.count(name.c_str()) == 1) return; - mVisitedSymbols.insert(name); + mVisitedSymbols.insert(name.c_str()); if (qualifier == EvqFragmentOut) { - if (symbol->getType().getLayoutQualifier().location == -1) - { - mUnspecifiedLocationOutputs.push_back(symbol); - } - else + if (symbol->getType().getLayoutQualifier().location != -1) { mOutputs.push_back(symbol); } + else if (symbol->getType().getLayoutQualifier().yuv == true) + { + mYuvOutputs.push_back(symbol); + } + else + { + mUnspecifiedLocationOutputs.push_back(symbol); + } + } + else if (qualifier == EvqFragDepth || qualifier == EvqFragDepthEXT) + { + mUsesFragDepth = true; } } -int ValidateOutputs::validateAndCountErrors(TInfoSinkBase &sink) const +void ValidateOutputsTraverser::validate(TDiagnostics *diagnostics) const { + ASSERT(diagnostics); OutputVector validOutputs(mMaxDrawBuffers); - int errorCount = 0; for (const auto &symbol : mOutputs) { const TType &type = symbol->getType(); - const size_t elementCount = static_cast(type.isArray() ? type.getArraySize() : 1); + ASSERT(!type.isArrayOfArrays()); // Disallowed in GLSL ES 3.10 section 4.3.6. + const size_t elementCount = + static_cast(type.isArray() ? type.getOutermostArraySize() : 1u); const size_t location = static_cast(type.getLayoutQualifier().location); ASSERT(type.getLayoutQualifier().location != -1); @@ -75,7 +112,7 @@ int ValidateOutputs::validateAndCountErrors(TInfoSinkBase &sink) const std::stringstream strstr; strstr << "conflicting output locations with previously defined output '" << validOutputs[offsetLocation]->getSymbol() << "'"; - error(&errorCount, sink, *symbol, strstr.str().c_str()); + error(*symbol, strstr.str().c_str(), diagnostics); } else { @@ -87,9 +124,10 @@ int ValidateOutputs::validateAndCountErrors(TInfoSinkBase &sink) const { if (elementCount > 0) { - error(&errorCount, sink, *symbol, + error(*symbol, elementCount > 1 ? "output array locations would exceed MAX_DRAW_BUFFERS" - : "output location must be < MAX_DRAW_BUFFERS"); + : "output location must be < MAX_DRAW_BUFFERS", + diagnostics); } } } @@ -100,9 +138,37 @@ int ValidateOutputs::validateAndCountErrors(TInfoSinkBase &sink) const { for (const auto &symbol : mUnspecifiedLocationOutputs) { - error(&errorCount, sink, *symbol, - "must explicitly specify all locations when using multiple fragment outputs"); + error(*symbol, + "must explicitly specify all locations when using multiple fragment outputs", + diagnostics); + } + } + + if (!mYuvOutputs.empty() && (mYuvOutputs.size() > 1 || mUsesFragDepth || !mOutputs.empty() || + !mUnspecifiedLocationOutputs.empty())) + { + for (const auto &symbol : mYuvOutputs) + { + error(*symbol, + "not allowed to specify yuv qualifier when using depth or multiple color " + "fragment outputs", + diagnostics); } } - return errorCount; } + +} // anonymous namespace + +bool ValidateOutputs(TIntermBlock *root, + const TExtensionBehavior &extBehavior, + int maxDrawBuffers, + TDiagnostics *diagnostics) +{ + ValidateOutputsTraverser validateOutputs(extBehavior, maxDrawBuffers); + root->traverse(&validateOutputs); + int numErrorsBefore = diagnostics->numErrors(); + validateOutputs.validate(diagnostics); + return (diagnostics->numErrors() == numErrorsBefore); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/ValidateOutputs.h b/src/3rdparty/angle/src/compiler/translator/ValidateOutputs.h index 06f63994cd..e41ccd990c 100644 --- a/src/3rdparty/angle/src/compiler/translator/ValidateOutputs.h +++ b/src/3rdparty/angle/src/compiler/translator/ValidateOutputs.h @@ -3,34 +3,28 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // +// ValidateOutputs validates fragment shader outputs. It checks for conflicting locations, +// out-of-range locations, that locations are specified when using multiple outputs, and YUV output +// validity. +// #ifndef COMPILER_TRANSLATOR_VALIDATEOUTPUTS_H_ #define COMPILER_TRANSLATOR_VALIDATEOUTPUTS_H_ #include "compiler/translator/ExtensionBehavior.h" -#include "compiler/translator/IntermNode.h" -#include - -class TInfoSinkBase; - -class ValidateOutputs : public TIntermTraverser +namespace sh { - public: - ValidateOutputs(const TExtensionBehavior &extBehavior, int maxDrawBuffers); - int validateAndCountErrors(TInfoSinkBase &sink) const; +class TIntermBlock; +class TDiagnostics; - void visitSymbol(TIntermSymbol *) override; +// Returns true if the shader has no conflicting or otherwise erroneous fragment outputs. +bool ValidateOutputs(TIntermBlock *root, + const TExtensionBehavior &extBehavior, + int maxDrawBuffers, + TDiagnostics *diagnostics); - private: - int mMaxDrawBuffers; - bool mAllowUnspecifiedOutputLocationResolution; +} // namespace sh - typedef std::vector OutputVector; - OutputVector mOutputs; - OutputVector mUnspecifiedLocationOutputs; - std::set mVisitedSymbols; -}; - -#endif // COMPILER_TRANSLATOR_VALIDATEOUTPUTS_H_ +#endif // COMPILER_TRANSLATOR_VALIDATEOUTPUTS_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/ValidateSwitch.cpp b/src/3rdparty/angle/src/compiler/translator/ValidateSwitch.cpp index 9a4ed33632..9f7a264e58 100644 --- a/src/3rdparty/angle/src/compiler/translator/ValidateSwitch.cpp +++ b/src/3rdparty/angle/src/compiler/translator/ValidateSwitch.cpp @@ -6,21 +6,76 @@ #include "compiler/translator/ValidateSwitch.h" -#include "compiler/translator/ParseContext.h" +#include "compiler/translator/Diagnostics.h" +#include "compiler/translator/IntermTraverse.h" -bool ValidateSwitch::validate(TBasicType switchType, TParseContext *context, - TIntermAggregate *statementList, const TSourceLoc &loc) +namespace sh { - ValidateSwitch validate(switchType, context); + +namespace +{ + +class ValidateSwitch : public TIntermTraverser +{ + public: + static bool validate(TBasicType switchType, + int shaderVersion, + TDiagnostics *diagnostics, + TIntermBlock *statementList, + const TSourceLoc &loc); + + void visitSymbol(TIntermSymbol *) override; + void visitConstantUnion(TIntermConstantUnion *) override; + bool visitDeclaration(Visit, TIntermDeclaration *) override; + bool visitBlock(Visit, TIntermBlock *) override; + bool visitBinary(Visit, TIntermBinary *) override; + bool visitUnary(Visit, TIntermUnary *) override; + bool visitTernary(Visit, TIntermTernary *) override; + bool visitSwizzle(Visit, TIntermSwizzle *) override; + bool visitIfElse(Visit visit, TIntermIfElse *) override; + bool visitSwitch(Visit, TIntermSwitch *) override; + bool visitCase(Visit, TIntermCase *node) override; + bool visitAggregate(Visit, TIntermAggregate *) override; + bool visitLoop(Visit visit, TIntermLoop *) override; + bool visitBranch(Visit, TIntermBranch *) override; + + private: + ValidateSwitch(TBasicType switchType, int shaderVersion, TDiagnostics *context); + + bool validateInternal(const TSourceLoc &loc); + + TBasicType mSwitchType; + int mShaderVersion; + TDiagnostics *mDiagnostics; + bool mCaseTypeMismatch; + bool mFirstCaseFound; + bool mStatementBeforeCase; + bool mLastStatementWasCase; + int mControlFlowDepth; + bool mCaseInsideControlFlow; + int mDefaultCount; + std::set mCasesSigned; + std::set mCasesUnsigned; + bool mDuplicateCases; +}; + +bool ValidateSwitch::validate(TBasicType switchType, + int shaderVersion, + TDiagnostics *diagnostics, + TIntermBlock *statementList, + const TSourceLoc &loc) +{ + ValidateSwitch validate(switchType, shaderVersion, diagnostics); ASSERT(statementList); statementList->traverse(&validate); return validate.validateInternal(loc); } -ValidateSwitch::ValidateSwitch(TBasicType switchType, TParseContext *context) +ValidateSwitch::ValidateSwitch(TBasicType switchType, int shaderVersion, TDiagnostics *diagnostics) : TIntermTraverser(true, false, true), mSwitchType(switchType), - mContext(context), + mShaderVersion(shaderVersion), + mDiagnostics(diagnostics), mCaseTypeMismatch(false), mFirstCaseFound(false), mStatementBeforeCase(false), @@ -29,13 +84,14 @@ ValidateSwitch::ValidateSwitch(TBasicType switchType, TParseContext *context) mCaseInsideControlFlow(false), mDefaultCount(0), mDuplicateCases(false) -{} +{ +} void ValidateSwitch::visitSymbol(TIntermSymbol *) { if (!mFirstCaseFound) mStatementBeforeCase = true; - mLastStatementWasCase = false; + mLastStatementWasCase = false; } void ValidateSwitch::visitConstantUnion(TIntermConstantUnion *) @@ -44,14 +100,33 @@ void ValidateSwitch::visitConstantUnion(TIntermConstantUnion *) // Could be just a statement like "0;" if (!mFirstCaseFound) mStatementBeforeCase = true; - mLastStatementWasCase = false; + mLastStatementWasCase = false; +} + +bool ValidateSwitch::visitDeclaration(Visit, TIntermDeclaration *) +{ + if (!mFirstCaseFound) + mStatementBeforeCase = true; + mLastStatementWasCase = false; + return true; +} + +bool ValidateSwitch::visitBlock(Visit, TIntermBlock *) +{ + if (getParentNode() != nullptr) + { + if (!mFirstCaseFound) + mStatementBeforeCase = true; + mLastStatementWasCase = false; + } + return true; } bool ValidateSwitch::visitBinary(Visit, TIntermBinary *) { if (!mFirstCaseFound) mStatementBeforeCase = true; - mLastStatementWasCase = false; + mLastStatementWasCase = false; return true; } @@ -59,11 +134,27 @@ bool ValidateSwitch::visitUnary(Visit, TIntermUnary *) { if (!mFirstCaseFound) mStatementBeforeCase = true; - mLastStatementWasCase = false; + mLastStatementWasCase = false; return true; } -bool ValidateSwitch::visitSelection(Visit visit, TIntermSelection *) +bool ValidateSwitch::visitTernary(Visit, TIntermTernary *) +{ + if (!mFirstCaseFound) + mStatementBeforeCase = true; + mLastStatementWasCase = false; + return true; +} + +bool ValidateSwitch::visitSwizzle(Visit, TIntermSwizzle *) +{ + if (!mFirstCaseFound) + mStatementBeforeCase = true; + mLastStatementWasCase = false; + return true; +} + +bool ValidateSwitch::visitIfElse(Visit visit, TIntermIfElse *) { if (visit == PreVisit) ++mControlFlowDepth; @@ -71,7 +162,7 @@ bool ValidateSwitch::visitSelection(Visit visit, TIntermSelection *) --mControlFlowDepth; if (!mFirstCaseFound) mStatementBeforeCase = true; - mLastStatementWasCase = false; + mLastStatementWasCase = false; return true; } @@ -79,7 +170,7 @@ bool ValidateSwitch::visitSwitch(Visit, TIntermSwitch *) { if (!mFirstCaseFound) mStatementBeforeCase = true; - mLastStatementWasCase = false; + mLastStatementWasCase = false; // Don't go into nested switch statements return false; } @@ -89,17 +180,17 @@ bool ValidateSwitch::visitCase(Visit, TIntermCase *node) const char *nodeStr = node->hasCondition() ? "case" : "default"; if (mControlFlowDepth > 0) { - mContext->error(node->getLine(), "label statement nested inside control flow", nodeStr); + mDiagnostics->error(node->getLine(), "label statement nested inside control flow", nodeStr); mCaseInsideControlFlow = true; } - mFirstCaseFound = true; + mFirstCaseFound = true; mLastStatementWasCase = true; if (!node->hasCondition()) { ++mDefaultCount; if (mDefaultCount > 1) { - mContext->error(node->getLine(), "duplicate default label", nodeStr); + mDiagnostics->error(node->getLine(), "duplicate default label", nodeStr); } } else @@ -113,8 +204,9 @@ bool ValidateSwitch::visitCase(Visit, TIntermCase *node) TBasicType conditionType = condition->getBasicType(); if (conditionType != mSwitchType) { - mContext->error(condition->getLine(), - "case label type does not match switch init-expression type", nodeStr); + mDiagnostics->error(condition->getLine(), + "case label type does not match switch init-expression type", + nodeStr); mCaseTypeMismatch = true; } @@ -123,7 +215,7 @@ bool ValidateSwitch::visitCase(Visit, TIntermCase *node) int iConst = condition->getIConst(0); if (mCasesSigned.find(iConst) != mCasesSigned.end()) { - mContext->error(condition->getLine(), "duplicate case label", nodeStr); + mDiagnostics->error(condition->getLine(), "duplicate case label", nodeStr); mDuplicateCases = true; } else @@ -136,7 +228,7 @@ bool ValidateSwitch::visitCase(Visit, TIntermCase *node) unsigned int uConst = condition->getUConst(0); if (mCasesUnsigned.find(uConst) != mCasesUnsigned.end()) { - mContext->error(condition->getLine(), "duplicate case label", nodeStr); + mDiagnostics->error(condition->getLine(), "duplicate case label", nodeStr); mDuplicateCases = true; } else @@ -158,7 +250,7 @@ bool ValidateSwitch::visitAggregate(Visit visit, TIntermAggregate *) // This is not the statementList node, but some other node. if (!mFirstCaseFound) mStatementBeforeCase = true; - mLastStatementWasCase = false; + mLastStatementWasCase = false; } return true; } @@ -171,7 +263,7 @@ bool ValidateSwitch::visitLoop(Visit visit, TIntermLoop *) --mControlFlowDepth; if (!mFirstCaseFound) mStatementBeforeCase = true; - mLastStatementWasCase = false; + mLastStatementWasCase = false; return true; } @@ -179,7 +271,7 @@ bool ValidateSwitch::visitBranch(Visit, TIntermBranch *) { if (!mFirstCaseFound) mStatementBeforeCase = true; - mLastStatementWasCase = false; + mLastStatementWasCase = false; return true; } @@ -187,14 +279,41 @@ bool ValidateSwitch::validateInternal(const TSourceLoc &loc) { if (mStatementBeforeCase) { - mContext->error(loc, - "statement before the first label", "switch"); + mDiagnostics->error(loc, "statement before the first label", "switch"); } + bool lastStatementWasCaseError = false; if (mLastStatementWasCase) { - mContext->error(loc, - "no statement between the last label and the end of the switch statement", "switch"); + if (mShaderVersion == 300) + { + lastStatementWasCaseError = true; + // This error has been proposed to be made optional in GLSL ES 3.00, but dEQP tests + // still require it. + mDiagnostics->error( + loc, "no statement between the last label and the end of the switch statement", + "switch"); + } + else + { + // The error has been removed from GLSL ES 3.10. + mDiagnostics->warning( + loc, "no statement between the last label and the end of the switch statement", + "switch"); + } } - return !mStatementBeforeCase && !mLastStatementWasCase && !mCaseInsideControlFlow && - !mCaseTypeMismatch && mDefaultCount <= 1 && !mDuplicateCases; + return !mStatementBeforeCase && !lastStatementWasCaseError && !mCaseInsideControlFlow && + !mCaseTypeMismatch && mDefaultCount <= 1 && !mDuplicateCases; } + +} // anonymous namespace + +bool ValidateSwitchStatementList(TBasicType switchType, + int shaderVersion, + TDiagnostics *diagnostics, + TIntermBlock *statementList, + const TSourceLoc &loc) +{ + return ValidateSwitch::validate(switchType, shaderVersion, diagnostics, statementList, loc); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/ValidateSwitch.h b/src/3rdparty/angle/src/compiler/translator/ValidateSwitch.h index ddbefc5619..2d2dd70f78 100644 --- a/src/3rdparty/angle/src/compiler/translator/ValidateSwitch.h +++ b/src/3rdparty/angle/src/compiler/translator/ValidateSwitch.h @@ -7,46 +7,22 @@ #ifndef COMPILER_TRANSLATOR_VALIDATESWITCH_H_ #define COMPILER_TRANSLATOR_VALIDATESWITCH_H_ -#include "compiler/translator/IntermNode.h" +#include "compiler/translator/BaseTypes.h" +#include "compiler/translator/Common.h" -class TParseContext; - -class ValidateSwitch : public TIntermTraverser +namespace sh { - public: - // Check for errors and output messages any remaining errors on the context. - // Returns true if there are no errors. - static bool validate(TBasicType switchType, TParseContext *context, - TIntermAggregate *statementList, const TSourceLoc &loc); +class TDiagnostics; +class TIntermBlock; - void visitSymbol(TIntermSymbol *) override; - void visitConstantUnion(TIntermConstantUnion *) override; - bool visitBinary(Visit, TIntermBinary *) override; - bool visitUnary(Visit, TIntermUnary *) override; - bool visitSelection(Visit visit, TIntermSelection *) override; - bool visitSwitch(Visit, TIntermSwitch *) override; - bool visitCase(Visit, TIntermCase *node) override; - bool visitAggregate(Visit, TIntermAggregate *) override; - bool visitLoop(Visit visit, TIntermLoop *) override; - bool visitBranch(Visit, TIntermBranch *) override; +// Check for errors and output error messages on the context. +// Returns true if there are no errors. +bool ValidateSwitchStatementList(TBasicType switchType, + int shaderVersion, + TDiagnostics *diagnostics, + TIntermBlock *statementList, + const TSourceLoc &loc); - private: - ValidateSwitch(TBasicType switchType, TParseContext *context); +} // namespace sh - bool validateInternal(const TSourceLoc &loc); - - TBasicType mSwitchType; - TParseContext *mContext; - bool mCaseTypeMismatch; - bool mFirstCaseFound; - bool mStatementBeforeCase; - bool mLastStatementWasCase; - int mControlFlowDepth; - bool mCaseInsideControlFlow; - int mDefaultCount; - std::set mCasesSigned; - std::set mCasesUnsigned; - bool mDuplicateCases; -}; - -#endif // COMPILER_TRANSLATOR_VALIDATESWITCH_H_ +#endif // COMPILER_TRANSLATOR_VALIDATESWITCH_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/ValidateVaryingLocations.cpp b/src/3rdparty/angle/src/compiler/translator/ValidateVaryingLocations.cpp new file mode 100644 index 0000000000..9c36fcea78 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/ValidateVaryingLocations.cpp @@ -0,0 +1,174 @@ +// +// Copyright (c) 2002-2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// The ValidateVaryingLocations function checks if there exists location conflicts on shader +// varyings. +// + +#include "ValidateVaryingLocations.h" + +#include "compiler/translator/Diagnostics.h" +#include "compiler/translator/IntermTraverse.h" +#include "compiler/translator/util.h" + +namespace sh +{ + +namespace +{ + +void error(const TIntermSymbol &symbol, const char *reason, TDiagnostics *diagnostics) +{ + diagnostics->error(symbol.getLine(), reason, symbol.getSymbol().c_str()); +} + +int GetLocationCount(const TIntermSymbol *varying, bool ignoreVaryingArraySize) +{ + const auto &varyingType = varying->getType(); + if (varyingType.getStruct() != nullptr) + { + ASSERT(!varyingType.isArray()); + int totalLocation = 0; + for (const auto *field : varyingType.getStruct()->fields()) + { + const auto *fieldType = field->type(); + ASSERT(fieldType->getStruct() == nullptr && !fieldType->isArray()); + + totalLocation += fieldType->getSecondarySize(); + } + return totalLocation; + } + // [GL_OES_shader_io_blocks SPEC Chapter 4.4.1] + // Geometry shader inputs, tessellation control shader inputs and outputs, and tessellation + // evaluation inputs all have an additional level of arrayness relative to other shader inputs + // and outputs. This outer array level is removed from the type before considering how many + // locations the type consumes. + else if (ignoreVaryingArraySize) + { + // Array-of-arrays cannot be inputs or outputs of a geometry shader. + // (GL_OES_geometry_shader SPEC issues(5)) + ASSERT(!varyingType.isArrayOfArrays()); + return varyingType.getSecondarySize(); + } + else + { + return varyingType.getSecondarySize() * static_cast(varyingType.getArraySizeProduct()); + } +} + +using VaryingVector = std::vector; + +void ValidateShaderInterface(TDiagnostics *diagnostics, + VaryingVector &varyingVector, + bool ignoreVaryingArraySize) +{ + // Location conflicts can only happen when there are two or more varyings in varyingVector. + if (varyingVector.size() <= 1) + { + return; + } + + std::map locationMap; + for (const TIntermSymbol *varying : varyingVector) + { + const int location = varying->getType().getLayoutQualifier().location; + ASSERT(location >= 0); + + const int elementCount = GetLocationCount(varying, ignoreVaryingArraySize); + for (int elementIndex = 0; elementIndex < elementCount; ++elementIndex) + { + const int offsetLocation = location + elementIndex; + if (locationMap.find(offsetLocation) != locationMap.end()) + { + std::stringstream strstr; + strstr << "'" << varying->getSymbol() + << "' conflicting location with previously defined '" + << locationMap[offsetLocation]->getSymbol() << "'"; + error(*varying, strstr.str().c_str(), diagnostics); + } + else + { + locationMap[offsetLocation] = varying; + } + } + } +} + +class ValidateVaryingLocationsTraverser : public TIntermTraverser +{ + public: + ValidateVaryingLocationsTraverser(GLenum shaderType); + void validate(TDiagnostics *diagnostics); + + private: + bool visitDeclaration(Visit visit, TIntermDeclaration *node) override; + bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override; + + VaryingVector mInputVaryingsWithLocation; + VaryingVector mOutputVaryingsWithLocation; + GLenum mShaderType; +}; + +ValidateVaryingLocationsTraverser::ValidateVaryingLocationsTraverser(GLenum shaderType) + : TIntermTraverser(true, false, false), mShaderType(shaderType) +{ +} + +bool ValidateVaryingLocationsTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node) +{ + const TIntermSequence &sequence = *(node->getSequence()); + ASSERT(!sequence.empty()); + + const TIntermSymbol *symbol = sequence.front()->getAsSymbolNode(); + if (symbol == nullptr) + { + return false; + } + + // Collect varyings that have explicit 'location' qualifiers. + const TQualifier qualifier = symbol->getQualifier(); + if (symbol->getType().getLayoutQualifier().location != -1) + { + if (IsVaryingIn(qualifier)) + { + mInputVaryingsWithLocation.push_back(symbol); + } + else if (IsVaryingOut(qualifier)) + { + mOutputVaryingsWithLocation.push_back(symbol); + } + } + + return false; +} + +bool ValidateVaryingLocationsTraverser::visitFunctionDefinition(Visit visit, + TIntermFunctionDefinition *node) +{ + // We stop traversing function definitions because varyings cannot be defined in a function. + return false; +} + +void ValidateVaryingLocationsTraverser::validate(TDiagnostics *diagnostics) +{ + ASSERT(diagnostics); + + ValidateShaderInterface(diagnostics, mInputVaryingsWithLocation, + mShaderType == GL_GEOMETRY_SHADER_OES); + ValidateShaderInterface(diagnostics, mOutputVaryingsWithLocation, false); +} + +} // anonymous namespace + +bool ValidateVaryingLocations(TIntermBlock *root, TDiagnostics *diagnostics, GLenum shaderType) +{ + ValidateVaryingLocationsTraverser varyingValidator(shaderType); + root->traverse(&varyingValidator); + int numErrorsBefore = diagnostics->numErrors(); + varyingValidator.validate(diagnostics); + return (diagnostics->numErrors() == numErrorsBefore); +} + +} // namespace sh \ No newline at end of file diff --git a/src/3rdparty/angle/src/compiler/translator/ValidateVaryingLocations.h b/src/3rdparty/angle/src/compiler/translator/ValidateVaryingLocations.h new file mode 100644 index 0000000000..1e53977c68 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/ValidateVaryingLocations.h @@ -0,0 +1,25 @@ +// +// Copyright (c) 2002-2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// The ValidateVaryingLocations function checks if there exists location conflicts on shader +// varyings. +// + +#ifndef COMPILER_TRANSLATOR_VALIDATEVARYINGLOCATIONS_H_ +#define COMPILER_TRANSLATOR_VALIDATEVARYINGLOCATIONS_H_ + +#include "GLSLANG/ShaderVars.h" + +namespace sh +{ + +class TIntermBlock; +class TDiagnostics; + +bool ValidateVaryingLocations(TIntermBlock *root, TDiagnostics *diagnostics, GLenum shaderType); + +} // namespace sh + +#endif \ No newline at end of file diff --git a/src/3rdparty/angle/src/compiler/translator/VariableInfo.cpp b/src/3rdparty/angle/src/compiler/translator/VariableInfo.cpp deleted file mode 100644 index 3b6aa6a68e..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/VariableInfo.cpp +++ /dev/null @@ -1,673 +0,0 @@ -// -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "angle_gl.h" -#include "compiler/translator/SymbolTable.h" -#include "compiler/translator/VariableInfo.h" -#include "compiler/translator/util.h" -#include "common/utilities.h" - -namespace sh -{ - -namespace -{ - -BlockLayoutType GetBlockLayoutType(TLayoutBlockStorage blockStorage) -{ - switch (blockStorage) - { - case EbsPacked: return BLOCKLAYOUT_PACKED; - case EbsShared: return BLOCKLAYOUT_SHARED; - case EbsStd140: return BLOCKLAYOUT_STANDARD; - default: UNREACHABLE(); return BLOCKLAYOUT_SHARED; - } -} - -void ExpandUserDefinedVariable(const ShaderVariable &variable, - const std::string &name, - const std::string &mappedName, - bool markStaticUse, - std::vector *expanded); - -void ExpandVariable(const ShaderVariable &variable, - const std::string &name, - const std::string &mappedName, - bool markStaticUse, - std::vector *expanded) -{ - if (variable.isStruct()) - { - if (variable.isArray()) - { - for (unsigned int elementIndex = 0; elementIndex < variable.elementCount(); - elementIndex++) - { - std::string lname = name + ::ArrayString(elementIndex); - std::string lmappedName = mappedName + ::ArrayString(elementIndex); - ExpandUserDefinedVariable(variable, lname, lmappedName, markStaticUse, expanded); - } - } - else - { - ExpandUserDefinedVariable(variable, name, mappedName, markStaticUse, expanded); - } - } - else - { - ShaderVariable expandedVar = variable; - - expandedVar.name = name; - expandedVar.mappedName = mappedName; - - // Mark all expanded fields as used if the parent is used - if (markStaticUse) - { - expandedVar.staticUse = true; - } - - if (expandedVar.isArray()) - { - expandedVar.name += "[0]"; - expandedVar.mappedName += "[0]"; - } - - expanded->push_back(expandedVar); - } -} - -void ExpandUserDefinedVariable(const ShaderVariable &variable, - const std::string &name, - const std::string &mappedName, - bool markStaticUse, - std::vector *expanded) -{ - ASSERT(variable.isStruct()); - - const std::vector &fields = variable.fields; - - for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) - { - const ShaderVariable &field = fields[fieldIndex]; - ExpandVariable(field, - name + "." + field.name, - mappedName + "." + field.mappedName, - markStaticUse, - expanded); - } -} - -template -VarT *FindVariable(const TString &name, - std::vector *infoList) -{ - // TODO(zmo): optimize this function. - for (size_t ii = 0; ii < infoList->size(); ++ii) - { - if ((*infoList)[ii].name.c_str() == name) - return &((*infoList)[ii]); - } - - return NULL; -} - -} - -CollectVariables::CollectVariables(std::vector *attribs, - std::vector *outputVariables, - std::vector *uniforms, - std::vector *varyings, - std::vector *interfaceBlocks, - ShHashFunction64 hashFunction, - const TSymbolTable &symbolTable) - : TIntermTraverser(true, false, false), - mAttribs(attribs), - mOutputVariables(outputVariables), - mUniforms(uniforms), - mVaryings(varyings), - mInterfaceBlocks(interfaceBlocks), - mDepthRangeAdded(false), - mPointCoordAdded(false), - mFrontFacingAdded(false), - mFragCoordAdded(false), - mInstanceIDAdded(false), - mPositionAdded(false), - mPointSizeAdded(false), - mLastFragDataAdded(false), - mFragColorAdded(false), - mFragDataAdded(false), - mFragDepthEXTAdded(false), - mFragDepthAdded(false), - mSecondaryFragColorEXTAdded(false), - mSecondaryFragDataEXTAdded(false), - mHashFunction(hashFunction), - mSymbolTable(symbolTable) -{ -} - -// We want to check whether a uniform/varying is statically used -// because we only count the used ones in packing computing. -// Also, gl_FragCoord, gl_PointCoord, and gl_FrontFacing count -// toward varying counting if they are statically used in a fragment -// shader. -void CollectVariables::visitSymbol(TIntermSymbol *symbol) -{ - ASSERT(symbol != NULL); - ShaderVariable *var = NULL; - const TString &symbolName = symbol->getSymbol(); - - if (IsVarying(symbol->getQualifier())) - { - var = FindVariable(symbolName, mVaryings); - } - else if (symbol->getType().getBasicType() == EbtInterfaceBlock) - { - UNREACHABLE(); - } - else if (symbolName == "gl_DepthRange") - { - ASSERT(symbol->getQualifier() == EvqUniform); - - if (!mDepthRangeAdded) - { - Uniform info; - const char kName[] = "gl_DepthRange"; - info.name = kName; - info.mappedName = kName; - info.type = GL_STRUCT_ANGLEX; - info.arraySize = 0; - info.precision = GL_NONE; - info.staticUse = true; - - ShaderVariable nearInfo; - const char kNearName[] = "near"; - nearInfo.name = kNearName; - nearInfo.mappedName = kNearName; - nearInfo.type = GL_FLOAT; - nearInfo.arraySize = 0; - nearInfo.precision = GL_HIGH_FLOAT; - nearInfo.staticUse = true; - - ShaderVariable farInfo; - const char kFarName[] = "far"; - farInfo.name = kFarName; - farInfo.mappedName = kFarName; - farInfo.type = GL_FLOAT; - farInfo.arraySize = 0; - farInfo.precision = GL_HIGH_FLOAT; - farInfo.staticUse = true; - - ShaderVariable diffInfo; - const char kDiffName[] = "diff"; - diffInfo.name = kDiffName; - diffInfo.mappedName = kDiffName; - diffInfo.type = GL_FLOAT; - diffInfo.arraySize = 0; - diffInfo.precision = GL_HIGH_FLOAT; - diffInfo.staticUse = true; - - info.fields.push_back(nearInfo); - info.fields.push_back(farInfo); - info.fields.push_back(diffInfo); - - mUniforms->push_back(info); - mDepthRangeAdded = true; - } - } - else - { - switch (symbol->getQualifier()) - { - case EvqAttribute: - case EvqVertexIn: - var = FindVariable(symbolName, mAttribs); - break; - case EvqFragmentOut: - var = FindVariable(symbolName, mOutputVariables); - break; - case EvqUniform: - { - const TInterfaceBlock *interfaceBlock = symbol->getType().getInterfaceBlock(); - if (interfaceBlock) - { - InterfaceBlock *namedBlock = FindVariable(interfaceBlock->name(), mInterfaceBlocks); - ASSERT(namedBlock); - var = FindVariable(symbolName, &namedBlock->fields); - - // Set static use on the parent interface block here - namedBlock->staticUse = true; - } - else - { - var = FindVariable(symbolName, mUniforms); - } - - // It's an internal error to reference an undefined user uniform - ASSERT(symbolName.compare(0, 3, "gl_") != 0 || var); - } - break; - case EvqFragCoord: - if (!mFragCoordAdded) - { - Varying info; - const char kName[] = "gl_FragCoord"; - info.name = kName; - info.mappedName = kName; - info.type = GL_FLOAT_VEC4; - info.arraySize = 0; - info.precision = GL_MEDIUM_FLOAT; // Defined by spec. - info.staticUse = true; - info.isInvariant = mSymbolTable.isVaryingInvariant(kName); - mVaryings->push_back(info); - mFragCoordAdded = true; - } - return; - case EvqFrontFacing: - if (!mFrontFacingAdded) - { - Varying info; - const char kName[] = "gl_FrontFacing"; - info.name = kName; - info.mappedName = kName; - info.type = GL_BOOL; - info.arraySize = 0; - info.precision = GL_NONE; - info.staticUse = true; - info.isInvariant = mSymbolTable.isVaryingInvariant(kName); - mVaryings->push_back(info); - mFrontFacingAdded = true; - } - return; - case EvqPointCoord: - if (!mPointCoordAdded) - { - Varying info; - const char kName[] = "gl_PointCoord"; - info.name = kName; - info.mappedName = kName; - info.type = GL_FLOAT_VEC2; - info.arraySize = 0; - info.precision = GL_MEDIUM_FLOAT; // Defined by spec. - info.staticUse = true; - info.isInvariant = mSymbolTable.isVaryingInvariant(kName); - mVaryings->push_back(info); - mPointCoordAdded = true; - } - return; - case EvqInstanceID: - if (!mInstanceIDAdded) - { - Attribute info; - const char kName[] = "gl_InstanceID"; - info.name = kName; - info.mappedName = kName; - info.type = GL_INT; - info.arraySize = 0; - info.precision = GL_HIGH_INT; // Defined by spec. - info.staticUse = true; - info.location = -1; - mAttribs->push_back(info); - mInstanceIDAdded = true; - } - return; - case EvqPosition: - if (!mPositionAdded) - { - Varying info; - const char kName[] = "gl_Position"; - info.name = kName; - info.mappedName = kName; - info.type = GL_FLOAT_VEC4; - info.arraySize = 0; - info.precision = GL_HIGH_FLOAT; // Defined by spec. - info.staticUse = true; - info.isInvariant = mSymbolTable.isVaryingInvariant(kName); - mVaryings->push_back(info); - mPositionAdded = true; - } - return; - case EvqPointSize: - if (!mPointSizeAdded) - { - Varying info; - const char kName[] = "gl_PointSize"; - info.name = kName; - info.mappedName = kName; - info.type = GL_FLOAT; - info.arraySize = 0; - info.precision = GL_MEDIUM_FLOAT; // Defined by spec. - info.staticUse = true; - info.isInvariant = mSymbolTable.isVaryingInvariant(kName); - mVaryings->push_back(info); - mPointSizeAdded = true; - } - return; - case EvqLastFragData: - if (!mLastFragDataAdded) - { - Varying info; - const char kName[] = "gl_LastFragData"; - info.name = kName; - info.mappedName = kName; - info.type = GL_FLOAT_VEC4; - info.arraySize = static_cast(mSymbolTable.findBuiltIn("gl_MaxDrawBuffers", 100))->getConstPointer()->getIConst(); - info.precision = GL_MEDIUM_FLOAT; // Defined by spec. - info.staticUse = true; - info.isInvariant = mSymbolTable.isVaryingInvariant(kName); - mVaryings->push_back(info); - mLastFragDataAdded = true; - } - return; - case EvqFragColor: - if (!mFragColorAdded) - { - OutputVariable info; - const char kName[] = "gl_FragColor"; - info.name = kName; - info.mappedName = kName; - info.type = GL_FLOAT_VEC4; - info.arraySize = 0; - info.precision = GL_MEDIUM_FLOAT; // Defined by spec. - info.staticUse = true; - mOutputVariables->push_back(info); - mFragColorAdded = true; - } - return; - case EvqFragData: - if (!mFragDataAdded) - { - OutputVariable info; - const char kName[] = "gl_FragData"; - info.name = kName; - info.mappedName = kName; - info.type = GL_FLOAT_VEC4; - info.arraySize = static_cast( - mSymbolTable.findBuiltIn("gl_MaxDrawBuffers", 100)) - ->getConstPointer() - ->getIConst(); - info.precision = GL_MEDIUM_FLOAT; // Defined by spec. - info.staticUse = true; - mOutputVariables->push_back(info); - mFragDataAdded = true; - } - return; - case EvqFragDepthEXT: - if (!mFragDepthEXTAdded) - { - OutputVariable info; - const char kName[] = "gl_FragDepthEXT"; - info.name = kName; - info.mappedName = kName; - info.type = GL_FLOAT; - info.arraySize = 0; - info.precision = - GLVariablePrecision(static_cast( - mSymbolTable.findBuiltIn("gl_FragDepthEXT", 100)) - ->getType()); - info.staticUse = true; - mOutputVariables->push_back(info); - mFragDepthEXTAdded = true; - } - return; - case EvqFragDepth: - if (!mFragDepthAdded) - { - OutputVariable info; - const char kName[] = "gl_FragDepth"; - info.name = kName; - info.mappedName = kName; - info.type = GL_FLOAT; - info.arraySize = 0; - info.precision = GL_HIGH_FLOAT; - info.staticUse = true; - mOutputVariables->push_back(info); - mFragDepthAdded = true; - } - return; - case EvqSecondaryFragColorEXT: - if (!mSecondaryFragColorEXTAdded) - { - OutputVariable info; - const char kName[] = "gl_SecondaryFragColorEXT"; - info.name = kName; - info.mappedName = kName; - info.type = GL_FLOAT_VEC4; - info.arraySize = 0; - info.precision = GL_MEDIUM_FLOAT; // Defined by spec. - info.staticUse = true; - mOutputVariables->push_back(info); - mSecondaryFragColorEXTAdded = true; - } - return; - case EvqSecondaryFragDataEXT: - if (!mSecondaryFragDataEXTAdded) - { - OutputVariable info; - const char kName[] = "gl_SecondaryFragDataEXT"; - info.name = kName; - info.mappedName = kName; - info.type = GL_FLOAT_VEC4; - - const TVariable *maxDualSourceDrawBuffersVar = static_cast( - mSymbolTable.findBuiltIn("gl_MaxDualSourceDrawBuffersEXT", 100)); - info.arraySize = maxDualSourceDrawBuffersVar->getConstPointer()->getIConst(); - info.precision = GL_MEDIUM_FLOAT; // Defined by spec. - info.staticUse = true; - mOutputVariables->push_back(info); - mSecondaryFragDataEXTAdded = true; - } - return; - default: - break; - } - } - if (var) - { - var->staticUse = true; - } -} - -class NameHashingTraverser : public GetVariableTraverser -{ - public: - NameHashingTraverser(ShHashFunction64 hashFunction, - const TSymbolTable &symbolTable) - : GetVariableTraverser(symbolTable), - mHashFunction(hashFunction) - {} - - private: - void visitVariable(ShaderVariable *variable) override - { - TString stringName = TString(variable->name.c_str()); - variable->mappedName = TIntermTraverser::hash(stringName, mHashFunction).c_str(); - } - - ShHashFunction64 mHashFunction; -}; - -// Attributes, which cannot have struct fields, are a special case -template <> -void CollectVariables::visitVariable(const TIntermSymbol *variable, - std::vector *infoList) const -{ - ASSERT(variable); - const TType &type = variable->getType(); - ASSERT(!type.getStruct()); - - Attribute attribute; - - attribute.type = GLVariableType(type); - attribute.precision = GLVariablePrecision(type); - attribute.name = variable->getSymbol().c_str(); - attribute.arraySize = static_cast(type.getArraySize()); - attribute.mappedName = TIntermTraverser::hash(variable->getSymbol(), mHashFunction).c_str(); - attribute.location = variable->getType().getLayoutQualifier().location; - - infoList->push_back(attribute); -} - -template <> -void CollectVariables::visitVariable(const TIntermSymbol *variable, - std::vector *infoList) const -{ - ASSERT(variable); - const TType &type = variable->getType(); - ASSERT(!type.getStruct()); - - OutputVariable attribute; - - attribute.type = GLVariableType(type); - attribute.precision = GLVariablePrecision(type); - attribute.name = variable->getSymbol().c_str(); - attribute.arraySize = static_cast(type.getArraySize()); - attribute.mappedName = TIntermTraverser::hash(variable->getSymbol(), mHashFunction).c_str(); - attribute.location = variable->getType().getLayoutQualifier().location; - - infoList->push_back(attribute); -} - -template <> -void CollectVariables::visitVariable(const TIntermSymbol *variable, - std::vector *infoList) const -{ - InterfaceBlock interfaceBlock; - const TInterfaceBlock *blockType = variable->getType().getInterfaceBlock(); - ASSERT(blockType); - - interfaceBlock.name = blockType->name().c_str(); - interfaceBlock.mappedName = - TIntermTraverser::hash(blockType->name().c_str(), mHashFunction).c_str(); - interfaceBlock.instanceName = (blockType->hasInstanceName() ? blockType->instanceName().c_str() : ""); - interfaceBlock.arraySize = variable->getArraySize(); - interfaceBlock.isRowMajorLayout = (blockType->matrixPacking() == EmpRowMajor); - interfaceBlock.layout = GetBlockLayoutType(blockType->blockStorage()); - - // Gather field information - for (const TField *field : blockType->fields()) - { - const TType &fieldType = *field->type(); - - NameHashingTraverser traverser(mHashFunction, mSymbolTable); - traverser.traverse(fieldType, field->name(), &interfaceBlock.fields); - - interfaceBlock.fields.back().isRowMajorLayout = (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor); - } - - infoList->push_back(interfaceBlock); -} - -template -void CollectVariables::visitVariable(const TIntermSymbol *variable, - std::vector *infoList) const -{ - NameHashingTraverser traverser(mHashFunction, mSymbolTable); - traverser.traverse(variable->getType(), variable->getSymbol(), infoList); -} - -template -void CollectVariables::visitInfoList(const TIntermSequence &sequence, - std::vector *infoList) const -{ - for (size_t seqIndex = 0; seqIndex < sequence.size(); seqIndex++) - { - const TIntermSymbol *variable = sequence[seqIndex]->getAsSymbolNode(); - // The only case in which the sequence will not contain a - // TIntermSymbol node is initialization. It will contain a - // TInterBinary node in that case. Since attributes, uniforms, - // and varyings cannot be initialized in a shader, we must have - // only TIntermSymbol nodes in the sequence. - ASSERT(variable != NULL); - visitVariable(variable, infoList); - } -} - -bool CollectVariables::visitAggregate(Visit, TIntermAggregate *node) -{ - bool visitChildren = true; - - switch (node->getOp()) - { - case EOpDeclaration: - { - const TIntermSequence &sequence = *(node->getSequence()); - ASSERT(!sequence.empty()); - - const TIntermTyped &typedNode = *(sequence.front()->getAsTyped()); - TQualifier qualifier = typedNode.getQualifier(); - - if (typedNode.getBasicType() == EbtInterfaceBlock) - { - visitInfoList(sequence, mInterfaceBlocks); - visitChildren = false; - } - else if (qualifier == EvqAttribute || qualifier == EvqVertexIn || - qualifier == EvqFragmentOut || qualifier == EvqUniform || - IsVarying(qualifier)) - { - switch (qualifier) - { - case EvqAttribute: - case EvqVertexIn: - visitInfoList(sequence, mAttribs); - break; - case EvqFragmentOut: - visitInfoList(sequence, mOutputVariables); - break; - case EvqUniform: - visitInfoList(sequence, mUniforms); - break; - default: - visitInfoList(sequence, mVaryings); - break; - } - - visitChildren = false; - } - break; - } - default: break; - } - - return visitChildren; -} - -bool CollectVariables::visitBinary(Visit, TIntermBinary *binaryNode) -{ - if (binaryNode->getOp() == EOpIndexDirectInterfaceBlock) - { - // NOTE: we do not determine static use for individual blocks of an array - TIntermTyped *blockNode = binaryNode->getLeft()->getAsTyped(); - ASSERT(blockNode); - - TIntermConstantUnion *constantUnion = binaryNode->getRight()->getAsConstantUnion(); - ASSERT(constantUnion); - - const TInterfaceBlock *interfaceBlock = blockNode->getType().getInterfaceBlock(); - InterfaceBlock *namedBlock = FindVariable(interfaceBlock->name(), mInterfaceBlocks); - ASSERT(namedBlock); - namedBlock->staticUse = true; - - unsigned int fieldIndex = constantUnion->getUConst(0); - ASSERT(fieldIndex < namedBlock->fields.size()); - namedBlock->fields[fieldIndex].staticUse = true; - return false; - } - - return true; -} - -void ExpandUniforms(const std::vector &compact, - std::vector *expanded) -{ - for (size_t variableIndex = 0; variableIndex < compact.size(); variableIndex++) - { - const ShaderVariable &variable = compact[variableIndex]; - ExpandVariable(variable, variable.name, variable.mappedName, variable.staticUse, expanded); - } -} - -} diff --git a/src/3rdparty/angle/src/compiler/translator/VariableInfo.h b/src/3rdparty/angle/src/compiler/translator/VariableInfo.h deleted file mode 100644 index 9498e9b3a0..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/VariableInfo.h +++ /dev/null @@ -1,77 +0,0 @@ -// -// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_TRANSLATOR_VARIABLEINFO_H_ -#define COMPILER_TRANSLATOR_VARIABLEINFO_H_ - -#include - -#include "compiler/translator/IntermNode.h" - -class TSymbolTable; - -namespace sh -{ - -// Traverses intermediate tree to collect all attributes, uniforms, varyings. -class CollectVariables : public TIntermTraverser -{ - public: - CollectVariables(std::vector *attribs, - std::vector *outputVariables, - std::vector *uniforms, - std::vector *varyings, - std::vector *interfaceBlocks, - ShHashFunction64 hashFunction, - const TSymbolTable &symbolTable); - - void visitSymbol(TIntermSymbol *symbol) override; - bool visitAggregate(Visit, TIntermAggregate *node) override; - bool visitBinary(Visit visit, TIntermBinary *binaryNode) override; - - private: - template - void visitVariable(const TIntermSymbol *variable, std::vector *infoList) const; - - template - void visitInfoList(const TIntermSequence &sequence, std::vector *infoList) const; - - std::vector *mAttribs; - std::vector *mOutputVariables; - std::vector *mUniforms; - std::vector *mVaryings; - std::vector *mInterfaceBlocks; - - std::map mInterfaceBlockFields; - - bool mDepthRangeAdded; - bool mPointCoordAdded; - bool mFrontFacingAdded; - bool mFragCoordAdded; - - bool mInstanceIDAdded; - bool mPositionAdded; - bool mPointSizeAdded; - bool mLastFragDataAdded; - bool mFragColorAdded; - bool mFragDataAdded; - bool mFragDepthEXTAdded; - bool mFragDepthAdded; - bool mSecondaryFragColorEXTAdded; - bool mSecondaryFragDataEXTAdded; - - ShHashFunction64 mHashFunction; - - const TSymbolTable &mSymbolTable; -}; - -// Expand struct uniforms to flattened lists of split variables -void ExpandUniforms(const std::vector &compact, - std::vector *expanded); - -} - -#endif // COMPILER_TRANSLATOR_VARIABLEINFO_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/VariablePacker.cpp b/src/3rdparty/angle/src/compiler/translator/VariablePacker.cpp index e69052162a..6dd396ff02 100644 --- a/src/3rdparty/angle/src/compiler/translator/VariablePacker.cpp +++ b/src/3rdparty/angle/src/compiler/translator/VariablePacker.cpp @@ -3,6 +3,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // +// Check whether variables fit within packing limits according to the packing rules from the GLSL ES +// 1.00.17 spec, Appendix A, section 7. #include @@ -11,259 +13,401 @@ #include "compiler/translator/VariablePacker.h" #include "common/utilities.h" -int VariablePacker::GetNumComponentsPerRow(sh::GLenum type) +namespace sh { - switch (type) + +namespace +{ + +// Expand the variable so that struct variables are split into their individual fields. +// Will not set the mappedName or staticUse fields on the expanded variables. +void ExpandVariable(const ShaderVariable &variable, + const std::string &name, + std::vector *expanded); + +void ExpandStructVariable(const ShaderVariable &variable, + const std::string &name, + std::vector *expanded) +{ + ASSERT(variable.isStruct()); + + const std::vector &fields = variable.fields; + + for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) { - case GL_FLOAT_MAT4: - case GL_FLOAT_MAT2: - case GL_FLOAT_MAT2x4: - case GL_FLOAT_MAT3x4: - case GL_FLOAT_MAT4x2: - case GL_FLOAT_MAT4x3: - case GL_FLOAT_VEC4: - case GL_INT_VEC4: - case GL_BOOL_VEC4: - case GL_UNSIGNED_INT_VEC4: - return 4; - case GL_FLOAT_MAT3: - case GL_FLOAT_MAT2x3: - case GL_FLOAT_MAT3x2: - case GL_FLOAT_VEC3: - case GL_INT_VEC3: - case GL_BOOL_VEC3: - case GL_UNSIGNED_INT_VEC3: - return 3; - case GL_FLOAT_VEC2: - case GL_INT_VEC2: - case GL_BOOL_VEC2: - case GL_UNSIGNED_INT_VEC2: - return 2; - default: - ASSERT(gl::VariableComponentCount(type) == 1); - return 1; + const ShaderVariable &field = fields[fieldIndex]; + ExpandVariable(field, name + "." + field.name, expanded); } } -int VariablePacker::GetNumRows(sh::GLenum type) +void ExpandStructArrayVariable(const ShaderVariable &variable, + unsigned int arrayNestingIndex, + const std::string &name, + std::vector *expanded) { - switch (type) + // Nested arrays are processed starting from outermost (arrayNestingIndex 0u) and ending at the + // innermost. + const unsigned int currentArraySize = variable.getNestedArraySize(arrayNestingIndex); + for (unsigned int arrayElement = 0u; arrayElement < currentArraySize; ++arrayElement) { - case GL_FLOAT_MAT4: - case GL_FLOAT_MAT2x4: - case GL_FLOAT_MAT3x4: - case GL_FLOAT_MAT4x3: - case GL_FLOAT_MAT4x2: - return 4; - case GL_FLOAT_MAT3: - case GL_FLOAT_MAT2x3: - case GL_FLOAT_MAT3x2: - return 3; - case GL_FLOAT_MAT2: - return 2; - default: - ASSERT(gl::VariableRowCount(type) == 1); - return 1; + const std::string elementName = name + ArrayString(arrayElement); + if (arrayNestingIndex + 1u < variable.arraySizes.size()) + { + ExpandStructArrayVariable(variable, arrayNestingIndex + 1u, elementName, expanded); + } + else + { + ExpandStructVariable(variable, elementName, expanded); + } } } +void ExpandVariable(const ShaderVariable &variable, + const std::string &name, + std::vector *expanded) +{ + if (variable.isStruct()) + { + if (variable.isArray()) + { + ExpandStructArrayVariable(variable, 0u, name, expanded); + } + else + { + ExpandStructVariable(variable, name, expanded); + } + } + else + { + ShaderVariable expandedVar = variable; + expandedVar.name = name; + + expanded->push_back(expandedVar); + } +} + +int GetVariablePackingRows(const ShaderVariable &variable) +{ + return GetTypePackingRows(variable.type) * variable.getArraySizeProduct(); +} + +class VariablePacker +{ + public: + bool checkExpandedVariablesWithinPackingLimits(unsigned int maxVectors, + std::vector *variables); + + private: + static const int kNumColumns = 4; + static const unsigned kColumnMask = (1 << kNumColumns) - 1; + + unsigned makeColumnFlags(int column, int numComponentsPerRow); + void fillColumns(int topRow, int numRows, int column, int numComponentsPerRow); + bool searchColumn(int column, int numRows, int *destRow, int *destSize); + + int topNonFullRow_; + int bottomNonFullRow_; + int maxRows_; + std::vector rows_; +}; + struct TVariableInfoComparer { bool operator()(const sh::ShaderVariable &lhs, const sh::ShaderVariable &rhs) const { int lhsSortOrder = gl::VariableSortOrder(lhs.type); int rhsSortOrder = gl::VariableSortOrder(rhs.type); - if (lhsSortOrder != rhsSortOrder) { + if (lhsSortOrder != rhsSortOrder) + { return lhsSortOrder < rhsSortOrder; } // Sort by largest first. - return lhs.arraySize > rhs.arraySize; + return lhs.getArraySizeProduct() > rhs.getArraySizeProduct(); } }; unsigned VariablePacker::makeColumnFlags(int column, int numComponentsPerRow) { - return ((kColumnMask << (kNumColumns - numComponentsPerRow)) & - kColumnMask) >> column; + return ((kColumnMask << (kNumColumns - numComponentsPerRow)) & kColumnMask) >> column; } void VariablePacker::fillColumns(int topRow, int numRows, int column, int numComponentsPerRow) { unsigned columnFlags = makeColumnFlags(column, numComponentsPerRow); - for (int r = 0; r < numRows; ++r) { + for (int r = 0; r < numRows; ++r) + { int row = topRow + r; ASSERT((rows_[row] & columnFlags) == 0); rows_[row] |= columnFlags; } } -bool VariablePacker::searchColumn(int column, int numRows, int* destRow, int* destSize) +bool VariablePacker::searchColumn(int column, int numRows, int *destRow, int *destSize) { ASSERT(destRow); - for (; topNonFullRow_ < maxRows_ && rows_[topNonFullRow_] == kColumnMask; - ++topNonFullRow_) { + for (; topNonFullRow_ < maxRows_ && rows_[topNonFullRow_] == kColumnMask; ++topNonFullRow_) + { } - for (; bottomNonFullRow_ >= 0 && rows_[bottomNonFullRow_] == kColumnMask; - --bottomNonFullRow_) { + for (; bottomNonFullRow_ >= 0 && rows_[bottomNonFullRow_] == kColumnMask; --bottomNonFullRow_) + { } - if (bottomNonFullRow_ - topNonFullRow_ + 1 < numRows) { + if (bottomNonFullRow_ - topNonFullRow_ + 1 < numRows) + { return false; } unsigned columnFlags = makeColumnFlags(column, 1); - int topGoodRow = 0; - int smallestGoodTop = -1; + int topGoodRow = 0; + int smallestGoodTop = -1; int smallestGoodSize = maxRows_ + 1; - int bottomRow = bottomNonFullRow_ + 1; - bool found = false; - for (int row = topNonFullRow_; row <= bottomRow; ++row) { + int bottomRow = bottomNonFullRow_ + 1; + bool found = false; + for (int row = topNonFullRow_; row <= bottomRow; ++row) + { bool rowEmpty = row < bottomRow ? ((rows_[row] & columnFlags) == 0) : false; - if (rowEmpty) { - if (!found) { + if (rowEmpty) + { + if (!found) + { topGoodRow = row; - found = true; + found = true; } - } else { - if (found) { + } + else + { + if (found) + { int size = row - topGoodRow; - if (size >= numRows && size < smallestGoodSize) { + if (size >= numRows && size < smallestGoodSize) + { smallestGoodSize = size; - smallestGoodTop = topGoodRow; + smallestGoodTop = topGoodRow; } } found = false; } } - if (smallestGoodTop < 0) { + if (smallestGoodTop < 0) + { return false; } *destRow = smallestGoodTop; - if (destSize) { + if (destSize) + { *destSize = smallestGoodSize; } return true; } -template -bool VariablePacker::CheckVariablesWithinPackingLimits(unsigned int maxVectors, - const std::vector &in_variables) +bool VariablePacker::checkExpandedVariablesWithinPackingLimits( + unsigned int maxVectors, + std::vector *variables) { ASSERT(maxVectors > 0); - maxRows_ = maxVectors; - topNonFullRow_ = 0; + maxRows_ = maxVectors; + topNonFullRow_ = 0; bottomNonFullRow_ = maxRows_ - 1; - std::vector variables(in_variables); // Check whether each variable fits in the available vectors. - for (size_t i = 0; i < variables.size(); i++) { - const sh::ShaderVariable &variable = variables[i]; - if (variable.elementCount() > maxVectors / GetNumRows(variable.type)) { + for (const sh::ShaderVariable &variable : *variables) + { + // Structs should have been expanded before reaching here. + ASSERT(!variable.isStruct()); + if (variable.getArraySizeProduct() > maxVectors / GetTypePackingRows(variable.type)) + { return false; } } // As per GLSL 1.017 Appendix A, Section 7 variables are packed in specific // order by type, then by size of array, largest first. - std::sort(variables.begin(), variables.end(), TVariableInfoComparer()); + std::sort(variables->begin(), variables->end(), TVariableInfoComparer()); rows_.clear(); rows_.resize(maxVectors, 0); // Packs the 4 column variables. size_t ii = 0; - for (; ii < variables.size(); ++ii) { - const sh::ShaderVariable &variable = variables[ii]; - if (GetNumComponentsPerRow(variable.type) != 4) { + for (; ii < variables->size(); ++ii) + { + const sh::ShaderVariable &variable = (*variables)[ii]; + if (GetTypePackingComponentsPerRow(variable.type) != 4) + { break; } - topNonFullRow_ += GetNumRows(variable.type) * variable.elementCount(); + topNonFullRow_ += GetVariablePackingRows(variable); } - if (topNonFullRow_ > maxRows_) { + if (topNonFullRow_ > maxRows_) + { return false; } // Packs the 3 column variables. int num3ColumnRows = 0; - for (; ii < variables.size(); ++ii) { - const sh::ShaderVariable &variable = variables[ii]; - if (GetNumComponentsPerRow(variable.type) != 3) { + for (; ii < variables->size(); ++ii) + { + const sh::ShaderVariable &variable = (*variables)[ii]; + if (GetTypePackingComponentsPerRow(variable.type) != 3) + { break; } - num3ColumnRows += GetNumRows(variable.type) * variable.elementCount(); + num3ColumnRows += GetVariablePackingRows(variable); } - if (topNonFullRow_ + num3ColumnRows > maxRows_) { + if (topNonFullRow_ + num3ColumnRows > maxRows_) + { return false; } fillColumns(topNonFullRow_, num3ColumnRows, 0, 3); // Packs the 2 column variables. - int top2ColumnRow = topNonFullRow_ + num3ColumnRows; - int twoColumnRowsAvailable = maxRows_ - top2ColumnRow; + int top2ColumnRow = topNonFullRow_ + num3ColumnRows; + int twoColumnRowsAvailable = maxRows_ - top2ColumnRow; int rowsAvailableInColumns01 = twoColumnRowsAvailable; int rowsAvailableInColumns23 = twoColumnRowsAvailable; - for (; ii < variables.size(); ++ii) { - const sh::ShaderVariable &variable = variables[ii]; - if (GetNumComponentsPerRow(variable.type) != 2) { + for (; ii < variables->size(); ++ii) + { + const sh::ShaderVariable &variable = (*variables)[ii]; + if (GetTypePackingComponentsPerRow(variable.type) != 2) + { break; } - int numRows = GetNumRows(variable.type) * variable.elementCount(); - if (numRows <= rowsAvailableInColumns01) { + int numRows = GetVariablePackingRows(variable); + if (numRows <= rowsAvailableInColumns01) + { rowsAvailableInColumns01 -= numRows; - } else if (numRows <= rowsAvailableInColumns23) { + } + else if (numRows <= rowsAvailableInColumns23) + { rowsAvailableInColumns23 -= numRows; - } else { + } + else + { return false; } } - int numRowsUsedInColumns01 = - twoColumnRowsAvailable - rowsAvailableInColumns01; - int numRowsUsedInColumns23 = - twoColumnRowsAvailable - rowsAvailableInColumns23; + int numRowsUsedInColumns01 = twoColumnRowsAvailable - rowsAvailableInColumns01; + int numRowsUsedInColumns23 = twoColumnRowsAvailable - rowsAvailableInColumns23; fillColumns(top2ColumnRow, numRowsUsedInColumns01, 0, 2); - fillColumns(maxRows_ - numRowsUsedInColumns23, numRowsUsedInColumns23, - 2, 2); + fillColumns(maxRows_ - numRowsUsedInColumns23, numRowsUsedInColumns23, 2, 2); // Packs the 1 column variables. - for (; ii < variables.size(); ++ii) { - const sh::ShaderVariable &variable = variables[ii]; - ASSERT(1 == GetNumComponentsPerRow(variable.type)); - int numRows = GetNumRows(variable.type) * variable.elementCount(); + for (; ii < variables->size(); ++ii) + { + const sh::ShaderVariable &variable = (*variables)[ii]; + ASSERT(1 == GetTypePackingComponentsPerRow(variable.type)); + int numRows = GetVariablePackingRows(variable); int smallestColumn = -1; - int smallestSize = maxRows_ + 1; - int topRow = -1; - for (int column = 0; column < kNumColumns; ++column) { - int row = 0; + int smallestSize = maxRows_ + 1; + int topRow = -1; + for (int column = 0; column < kNumColumns; ++column) + { + int row = 0; int size = 0; - if (searchColumn(column, numRows, &row, &size)) { - if (size < smallestSize) { - smallestSize = size; + if (searchColumn(column, numRows, &row, &size)) + { + if (size < smallestSize) + { + smallestSize = size; smallestColumn = column; - topRow = row; + topRow = row; } } } - if (smallestColumn < 0) { + if (smallestColumn < 0) + { return false; } fillColumns(topRow, numRows, smallestColumn, 1); } - ASSERT(variables.size() == ii); + ASSERT(variables->size() == ii); return true; } -// Instantiate all possible variable packings -template bool VariablePacker::CheckVariablesWithinPackingLimits(unsigned int, const std::vector &); -template bool VariablePacker::CheckVariablesWithinPackingLimits(unsigned int, const std::vector &); -template bool VariablePacker::CheckVariablesWithinPackingLimits(unsigned int, const std::vector &); -template bool VariablePacker::CheckVariablesWithinPackingLimits(unsigned int, const std::vector &); +} // anonymous namespace + +int GetTypePackingComponentsPerRow(sh::GLenum type) +{ + switch (type) + { + case GL_FLOAT_MAT4: + case GL_FLOAT_MAT2: + case GL_FLOAT_MAT2x4: + case GL_FLOAT_MAT3x4: + case GL_FLOAT_MAT4x2: + case GL_FLOAT_MAT4x3: + case GL_FLOAT_VEC4: + case GL_INT_VEC4: + case GL_BOOL_VEC4: + case GL_UNSIGNED_INT_VEC4: + return 4; + case GL_FLOAT_MAT3: + case GL_FLOAT_MAT2x3: + case GL_FLOAT_MAT3x2: + case GL_FLOAT_VEC3: + case GL_INT_VEC3: + case GL_BOOL_VEC3: + case GL_UNSIGNED_INT_VEC3: + return 3; + case GL_FLOAT_VEC2: + case GL_INT_VEC2: + case GL_BOOL_VEC2: + case GL_UNSIGNED_INT_VEC2: + return 2; + default: + ASSERT(gl::VariableComponentCount(type) == 1); + return 1; + } +} + +int GetTypePackingRows(sh::GLenum type) +{ + switch (type) + { + case GL_FLOAT_MAT4: + case GL_FLOAT_MAT2x4: + case GL_FLOAT_MAT3x4: + case GL_FLOAT_MAT4x3: + case GL_FLOAT_MAT4x2: + return 4; + case GL_FLOAT_MAT3: + case GL_FLOAT_MAT2x3: + case GL_FLOAT_MAT3x2: + return 3; + case GL_FLOAT_MAT2: + return 2; + default: + ASSERT(gl::VariableRowCount(type) == 1); + return 1; + } +} + +template +bool CheckVariablesInPackingLimits(unsigned int maxVectors, const std::vector &variables) +{ + VariablePacker packer; + std::vector expandedVariables; + for (const ShaderVariable &variable : variables) + { + ExpandVariable(variable, variable.name, &expandedVariables); + } + return packer.checkExpandedVariablesWithinPackingLimits(maxVectors, &expandedVariables); +} + +template bool CheckVariablesInPackingLimits( + unsigned int maxVectors, + const std::vector &variables); +template bool CheckVariablesInPackingLimits(unsigned int maxVectors, + const std::vector &variables); + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/VariablePacker.h b/src/3rdparty/angle/src/compiler/translator/VariablePacker.h index 9c80eea618..36b2104cd0 100644 --- a/src/3rdparty/angle/src/compiler/translator/VariablePacker.h +++ b/src/3rdparty/angle/src/compiler/translator/VariablePacker.h @@ -3,39 +3,30 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // +// Check whether variables fit within packing limits according to the packing rules from the GLSL ES +// 1.00.17 spec, Appendix A, section 7. #ifndef COMPILER_TRANSLATOR_VARIABLEPACKER_H_ #define COMPILER_TRANSLATOR_VARIABLEPACKER_H_ #include -#include "compiler/translator/VariableInfo.h" -class VariablePacker { - public: - // Returns true if the passed in variables pack in maxVectors following - // the packing rules from the GLSL 1.017 spec, Appendix A, section 7. - template - bool CheckVariablesWithinPackingLimits(unsigned int maxVectors, - const std::vector &in_variables); +#include - // Gets how many components in a row a data type takes. - static int GetNumComponentsPerRow(sh::GLenum type); +namespace sh +{ - // Gets how many rows a data type takes. - static int GetNumRows(sh::GLenum type); +// Gets how many components in a row a data type takes. +int GetTypePackingComponentsPerRow(sh::GLenum type); - private: - static const int kNumColumns = 4; - static const unsigned kColumnMask = (1 << kNumColumns) - 1; +// Gets how many rows a data type takes. +int GetTypePackingRows(sh::GLenum type); - unsigned makeColumnFlags(int column, int numComponentsPerRow); - void fillColumns(int topRow, int numRows, int column, int numComponentsPerRow); - bool searchColumn(int column, int numRows, int* destRow, int* destSize); +// Returns true if the passed in variables pack in maxVectors. +// T should be ShaderVariable or one of the subclasses of ShaderVariable. +template +bool CheckVariablesInPackingLimits(unsigned int maxVectors, const std::vector &variables); - int topNonFullRow_; - int bottomNonFullRow_; - int maxRows_; - std::vector rows_; -}; +} // namespace sh -#endif // COMPILER_TRANSLATOR_VARIABLEPACKER_H_ +#endif // COMPILER_TRANSLATOR_VARIABLEPACKER_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/VectorizeVectorScalarArithmetic.cpp b/src/3rdparty/angle/src/compiler/translator/VectorizeVectorScalarArithmetic.cpp new file mode 100644 index 0000000000..1e79a60991 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/VectorizeVectorScalarArithmetic.cpp @@ -0,0 +1,284 @@ +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// VectorizeVectorScalarArithmetic.cpp: Turn some arithmetic operations that operate on a float +// vector-scalar pair into vector-vector operations. This is done recursively. Some scalar binary +// operations inside vector constructors are also turned into vector operations. +// +// This is targeted to work around a bug in NVIDIA OpenGL drivers that was reproducible on NVIDIA +// driver version 387.92. It works around the most common occurrences of the bug. + +#include "compiler/translator/VectorizeVectorScalarArithmetic.h" + +#include + +#include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermTraverse.h" + +namespace sh +{ + +namespace +{ + +class VectorizeVectorScalarArithmeticTraverser : public TIntermTraverser +{ + public: + VectorizeVectorScalarArithmeticTraverser(TSymbolTable *symbolTable) + : TIntermTraverser(true, false, false, symbolTable), mReplaced(false) + { + } + + bool didReplaceScalarsWithVectors() { return mReplaced; } + void nextIteration() + { + mReplaced = false; + mModifiedBlocks.clear(); + } + + protected: + bool visitBinary(Visit visit, TIntermBinary *node) override; + bool visitAggregate(Visit visit, TIntermAggregate *node) override; + + private: + // These helpers should only be called from visitAggregate when visiting a constructor. + // argBinary is the only argument of the constructor. + void replaceMathInsideConstructor(TIntermAggregate *node, TIntermBinary *argBinary); + void replaceAssignInsideConstructor(const TIntermAggregate *node, + const TIntermBinary *argBinary); + + static TIntermTyped *Vectorize(TIntermTyped *node, + TType vectorType, + TIntermTraverser::OriginalNode *originalNodeFate); + + bool mReplaced; + std::set mModifiedBlocks; +}; + +TIntermTyped *VectorizeVectorScalarArithmeticTraverser::Vectorize( + TIntermTyped *node, + TType vectorType, + TIntermTraverser::OriginalNode *originalNodeFate) +{ + ASSERT(node->isScalar()); + vectorType.setQualifier(EvqTemporary); + TIntermSequence vectorConstructorArgs; + vectorConstructorArgs.push_back(node); + TIntermAggregate *vectorized = + TIntermAggregate::CreateConstructor(vectorType, &vectorConstructorArgs); + TIntermTyped *vectorizedFolded = vectorized->fold(nullptr); + if (originalNodeFate != nullptr) + { + if (vectorizedFolded != vectorized) + { + *originalNodeFate = OriginalNode::IS_DROPPED; + } + else + { + *originalNodeFate = OriginalNode::BECOMES_CHILD; + } + } + return vectorizedFolded; +} + +bool VectorizeVectorScalarArithmeticTraverser::visitBinary(Visit /*visit*/, TIntermBinary *node) +{ + TIntermTyped *left = node->getLeft(); + TIntermTyped *right = node->getRight(); + ASSERT(left); + ASSERT(right); + switch (node->getOp()) + { + case EOpAdd: + case EOpAddAssign: + // Only these specific ops are necessary to turn into vector ops. + break; + default: + return true; + } + if (node->getBasicType() != EbtFloat) + { + // Only float ops have reproduced the bug. + return true; + } + if (left->isScalar() && right->isVector()) + { + ASSERT(!node->isAssignment()); + ASSERT(!right->isArray()); + OriginalNode originalNodeFate; + TIntermTyped *leftVectorized = Vectorize(left, right->getType(), &originalNodeFate); + queueReplacementWithParent(node, left, leftVectorized, originalNodeFate); + mReplaced = true; + // Don't replace more nodes in the same subtree on this traversal. However, nodes elsewhere + // in the tree may still be replaced. + return false; + } + else if (left->isVector() && right->isScalar()) + { + OriginalNode originalNodeFate; + TIntermTyped *rightVectorized = Vectorize(right, left->getType(), &originalNodeFate); + queueReplacementWithParent(node, right, rightVectorized, originalNodeFate); + mReplaced = true; + // Don't replace more nodes in the same subtree on this traversal. However, nodes elsewhere + // in the tree may still be replaced. + return false; + } + return true; +} + +void VectorizeVectorScalarArithmeticTraverser::replaceMathInsideConstructor( + TIntermAggregate *node, + TIntermBinary *argBinary) +{ + // Turn: + // a * b + // into: + // gvec(a) * gvec(b) + + TIntermTyped *left = argBinary->getLeft(); + TIntermTyped *right = argBinary->getRight(); + ASSERT(left->isScalar() && right->isScalar()); + + TType leftVectorizedType = left->getType(); + leftVectorizedType.setPrimarySize(static_cast(node->getType().getNominalSize())); + TIntermTyped *leftVectorized = Vectorize(left, leftVectorizedType, nullptr); + TType rightVectorizedType = right->getType(); + rightVectorizedType.setPrimarySize( + static_cast(node->getType().getNominalSize())); + TIntermTyped *rightVectorized = Vectorize(right, rightVectorizedType, nullptr); + + TIntermBinary *newArg = new TIntermBinary(argBinary->getOp(), leftVectorized, rightVectorized); + queueReplacementWithParent(node, argBinary, newArg, OriginalNode::IS_DROPPED); +} + +void VectorizeVectorScalarArithmeticTraverser::replaceAssignInsideConstructor( + const TIntermAggregate *node, + const TIntermBinary *argBinary) +{ + // Turn: + // gvec(a *= b); + // into: + // // This is inserted into the parent block: + // gvec s0 = gvec(a); + // + // // This goes where the gvec constructor used to be: + // ((s0 *= b, a = s0.x), s0); + + TIntermTyped *left = argBinary->getLeft(); + TIntermTyped *right = argBinary->getRight(); + ASSERT(left->isScalar() && right->isScalar()); + ASSERT(!left->hasSideEffects()); + + TType vecType = node->getType(); + vecType.setQualifier(EvqTemporary); + + nextTemporaryId(); + // gvec s0 = gvec(a); + // s0 is called "tempAssignmentTarget" below. + TIntermTyped *tempAssignmentTargetInitializer = Vectorize(left->deepCopy(), vecType, nullptr); + TIntermDeclaration *tempAssignmentTargetDeclaration = + createTempInitDeclaration(tempAssignmentTargetInitializer); + + // s0 *= b + TOperator compoundAssignmentOp = argBinary->getOp(); + if (compoundAssignmentOp == EOpMulAssign) + { + compoundAssignmentOp = EOpVectorTimesScalarAssign; + } + TIntermBinary *replacementCompoundAssignment = + new TIntermBinary(compoundAssignmentOp, createTempSymbol(vecType), right->deepCopy()); + + // s0.x + TVector swizzleXOffset; + swizzleXOffset.push_back(0); + TIntermSwizzle *tempAssignmentTargetX = + new TIntermSwizzle(createTempSymbol(vecType), swizzleXOffset); + // a = s0.x + TIntermBinary *replacementAssignBackToTarget = + new TIntermBinary(EOpAssign, left->deepCopy(), tempAssignmentTargetX); + + // s0 *= b, a = s0.x + TIntermBinary *replacementSequenceLeft = + new TIntermBinary(EOpComma, replacementCompoundAssignment, replacementAssignBackToTarget); + // (s0 *= b, a = s0.x), s0 + TIntermBinary *replacementSequence = + new TIntermBinary(EOpComma, replacementSequenceLeft, createTempSymbol(vecType)); + + insertStatementInParentBlock(tempAssignmentTargetDeclaration); + queueReplacement(replacementSequence, OriginalNode::IS_DROPPED); +} + +bool VectorizeVectorScalarArithmeticTraverser::visitAggregate(Visit /*visit*/, + TIntermAggregate *node) +{ + // Transform scalar binary expressions inside vector constructors. + if (!node->isConstructor() || !node->isVector() || node->getSequence()->size() != 1) + { + return true; + } + TIntermTyped *argument = node->getSequence()->back()->getAsTyped(); + ASSERT(argument); + if (!argument->isScalar() || argument->getBasicType() != EbtFloat) + { + return true; + } + TIntermBinary *argBinary = argument->getAsBinaryNode(); + if (!argBinary) + { + return true; + } + + // Only specific ops are necessary to change. + switch (argBinary->getOp()) + { + case EOpMul: + case EOpDiv: + { + replaceMathInsideConstructor(node, argBinary); + mReplaced = true; + // Don't replace more nodes in the same subtree on this traversal. However, nodes + // elsewhere in the tree may still be replaced. + return false; + } + case EOpMulAssign: + case EOpDivAssign: + { + // The case where the left side has side effects is too complicated to deal with, so we + // leave that be. + if (!argBinary->getLeft()->hasSideEffects()) + { + const TIntermBlock *parentBlock = getParentBlock(); + // We can't do more than one insertion to the same block on the same traversal. + if (mModifiedBlocks.find(parentBlock) == mModifiedBlocks.end()) + { + replaceAssignInsideConstructor(node, argBinary); + mModifiedBlocks.insert(parentBlock); + mReplaced = true; + // Don't replace more nodes in the same subtree on this traversal. + // However, nodes elsewhere in the tree may still be replaced. + return false; + } + } + break; + } + default: + return true; + } + return true; +} + +} // anonymous namespace + +void VectorizeVectorScalarArithmetic(TIntermBlock *root, TSymbolTable *symbolTable) +{ + VectorizeVectorScalarArithmeticTraverser traverser(symbolTable); + do + { + traverser.nextIteration(); + root->traverse(&traverser); + traverser.updateTree(); + } while (traverser.didReplaceScalarsWithVectors()); +} + +} // namespace sh \ No newline at end of file diff --git a/src/3rdparty/angle/src/compiler/translator/VectorizeVectorScalarArithmetic.h b/src/3rdparty/angle/src/compiler/translator/VectorizeVectorScalarArithmetic.h new file mode 100644 index 0000000000..69f092e039 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/VectorizeVectorScalarArithmetic.h @@ -0,0 +1,25 @@ +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// VectorizeVectorScalarArithmetic.h: Turn some arithmetic operations that operate on a float +// vector-scalar pair into vector-vector operations. This is done recursively. Some scalar binary +// operations inside vector constructors are also turned into vector operations. +// +// This is targeted to work around a bug in NVIDIA OpenGL drivers that was reproducible on NVIDIA +// driver version 387.92. It works around the most common occurrences of the bug. + +#ifndef COMPILER_TRANSLATOR_VECTORIZEVECTORSCALARARITHMETIC_H_ +#define COMPILER_TRANSLATOR_VECTORIZEVECTORSCALARARITHMETIC_H_ + +namespace sh +{ + +class TIntermBlock; +class TSymbolTable; + +void VectorizeVectorScalarArithmetic(TIntermBlock *root, TSymbolTable *symbolTable); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_VECTORIZEVECTORSCALARARITHMETIC_H_ \ No newline at end of file diff --git a/src/3rdparty/angle/src/compiler/translator/VersionGLSL.cpp b/src/3rdparty/angle/src/compiler/translator/VersionGLSL.cpp index c8718daa10..81688765b8 100644 --- a/src/3rdparty/angle/src/compiler/translator/VersionGLSL.cpp +++ b/src/3rdparty/angle/src/compiler/translator/VersionGLSL.cpp @@ -6,22 +6,40 @@ #include "compiler/translator/VersionGLSL.h" +#include "angle_gl.h" + +namespace sh +{ + int ShaderOutputTypeToGLSLVersion(ShShaderOutput output) { switch (output) { - case SH_GLSL_130_OUTPUT: return GLSL_VERSION_130; - case SH_GLSL_140_OUTPUT: return GLSL_VERSION_140; - case SH_GLSL_150_CORE_OUTPUT: return GLSL_VERSION_150; - case SH_GLSL_330_CORE_OUTPUT: return GLSL_VERSION_330; - case SH_GLSL_400_CORE_OUTPUT: return GLSL_VERSION_400; - case SH_GLSL_410_CORE_OUTPUT: return GLSL_VERSION_410; - case SH_GLSL_420_CORE_OUTPUT: return GLSL_VERSION_420; - case SH_GLSL_430_CORE_OUTPUT: return GLSL_VERSION_430; - case SH_GLSL_440_CORE_OUTPUT: return GLSL_VERSION_440; - case SH_GLSL_450_CORE_OUTPUT: return GLSL_VERSION_450; - case SH_GLSL_COMPATIBILITY_OUTPUT: return GLSL_VERSION_110; - default: UNREACHABLE(); return 0; + case SH_GLSL_130_OUTPUT: + return GLSL_VERSION_130; + case SH_GLSL_140_OUTPUT: + return GLSL_VERSION_140; + case SH_GLSL_150_CORE_OUTPUT: + return GLSL_VERSION_150; + case SH_GLSL_330_CORE_OUTPUT: + return GLSL_VERSION_330; + case SH_GLSL_400_CORE_OUTPUT: + return GLSL_VERSION_400; + case SH_GLSL_410_CORE_OUTPUT: + return GLSL_VERSION_410; + case SH_GLSL_420_CORE_OUTPUT: + return GLSL_VERSION_420; + case SH_GLSL_430_CORE_OUTPUT: + return GLSL_VERSION_430; + case SH_GLSL_440_CORE_OUTPUT: + return GLSL_VERSION_440; + case SH_GLSL_450_CORE_OUTPUT: + return GLSL_VERSION_450; + case SH_GLSL_COMPATIBILITY_OUTPUT: + return GLSL_VERSION_110; + default: + UNREACHABLE(); + return 0; } } @@ -42,9 +60,7 @@ int ShaderOutputTypeToGLSLVersion(ShShaderOutput output) // GLSL 1.2 relaxed the restriction on arrays, section 5.8: "Variables that // are built-in types, entire structures or arrays... are all l-values." // -TVersionGLSL::TVersionGLSL(sh::GLenum type, - const TPragma &pragma, - ShShaderOutput output) +TVersionGLSL::TVersionGLSL(sh::GLenum type, const TPragma &pragma, ShShaderOutput output) : TIntermTraverser(true, false, false) { mVersion = ShaderOutputTypeToGLSLVersion(output); @@ -52,6 +68,10 @@ TVersionGLSL::TVersionGLSL(sh::GLenum type, { ensureVersionIsAtLeast(GLSL_VERSION_120); } + if (type == GL_COMPUTE_SHADER) + { + ensureVersionIsAtLeast(GLSL_VERSION_430); + } } void TVersionGLSL::visitSymbol(TIntermSymbol *node) @@ -62,75 +82,57 @@ void TVersionGLSL::visitSymbol(TIntermSymbol *node) } } +bool TVersionGLSL::visitDeclaration(Visit, TIntermDeclaration *node) +{ + const TIntermSequence &sequence = *(node->getSequence()); + if (sequence.front()->getAsTyped()->getType().isInvariant()) + { + ensureVersionIsAtLeast(GLSL_VERSION_120); + } + return true; +} + +bool TVersionGLSL::visitInvariantDeclaration(Visit, TIntermInvariantDeclaration *node) +{ + ensureVersionIsAtLeast(GLSL_VERSION_120); + return true; +} + +bool TVersionGLSL::visitFunctionPrototype(Visit, TIntermFunctionPrototype *node) +{ + const TIntermSequence ¶ms = *(node->getSequence()); + for (TIntermSequence::const_iterator iter = params.begin(); iter != params.end(); ++iter) + { + const TIntermTyped *param = (*iter)->getAsTyped(); + if (param->isArray()) + { + TQualifier qualifier = param->getQualifier(); + if ((qualifier == EvqOut) || (qualifier == EvqInOut)) + { + ensureVersionIsAtLeast(GLSL_VERSION_120); + break; + } + } + } + // Fully processed. No need to visit children. + return false; +} + bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate *node) { - bool visitChildren = true; - - switch (node->getOp()) + if (node->getOp() == EOpConstruct && node->getType().isMatrix()) { - case EOpSequence: - // We need to visit sequence children to get to global or inner scope. - visitChildren = true; - break; - case EOpDeclaration: + const TIntermSequence &sequence = *(node->getSequence()); + if (sequence.size() == 1) { - const TIntermSequence &sequence = *(node->getSequence()); - if (sequence.front()->getAsTyped()->getType().isInvariant()) + TIntermTyped *typed = sequence.front()->getAsTyped(); + if (typed && typed->isMatrix()) { ensureVersionIsAtLeast(GLSL_VERSION_120); } - break; } - case EOpInvariantDeclaration: - ensureVersionIsAtLeast(GLSL_VERSION_120); - break; - case EOpParameters: - { - const TIntermSequence ¶ms = *(node->getSequence()); - for (TIntermSequence::const_iterator iter = params.begin(); - iter != params.end(); ++iter) - { - const TIntermTyped *param = (*iter)->getAsTyped(); - if (param->isArray()) - { - TQualifier qualifier = param->getQualifier(); - if ((qualifier == EvqOut) || (qualifier == EvqInOut)) - { - ensureVersionIsAtLeast(GLSL_VERSION_120); - break; - } - } - } - // Fully processed. No need to visit children. - visitChildren = false; - break; - } - case EOpConstructMat2: - case EOpConstructMat2x3: - case EOpConstructMat2x4: - case EOpConstructMat3x2: - case EOpConstructMat3: - case EOpConstructMat3x4: - case EOpConstructMat4x2: - case EOpConstructMat4x3: - case EOpConstructMat4: - { - const TIntermSequence &sequence = *(node->getSequence()); - if (sequence.size() == 1) - { - TIntermTyped *typed = sequence.front()->getAsTyped(); - if (typed && typed->isMatrix()) - { - ensureVersionIsAtLeast(GLSL_VERSION_120); - } - } - break; - } - default: - break; } - - return visitChildren; + return true; } void TVersionGLSL::ensureVersionIsAtLeast(int version) @@ -138,3 +140,4 @@ void TVersionGLSL::ensureVersionIsAtLeast(int version) mVersion = std::max(version, mVersion); } +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/VersionGLSL.h b/src/3rdparty/angle/src/compiler/translator/VersionGLSL.h index c41069d42d..8b82eb9615 100644 --- a/src/3rdparty/angle/src/compiler/translator/VersionGLSL.h +++ b/src/3rdparty/angle/src/compiler/translator/VersionGLSL.h @@ -7,10 +7,13 @@ #ifndef COMPILER_TRANSLATOR_VERSIONGLSL_H_ #define COMPILER_TRANSLATOR_VERSIONGLSL_H_ -#include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermTraverse.h" #include "compiler/translator/Pragma.h" +namespace sh +{ + static const int GLSL_VERSION_110 = 110; static const int GLSL_VERSION_120 = 120; static const int GLSL_VERSION_130 = 130; @@ -56,8 +59,11 @@ class TVersionGLSL : public TIntermTraverser // Else 110 is returned. int getVersion() const { return mVersion; } - void visitSymbol(TIntermSymbol *) override; - bool visitAggregate(Visit, TIntermAggregate *) override; + void visitSymbol(TIntermSymbol *node) override; + bool visitAggregate(Visit, TIntermAggregate *node) override; + bool visitInvariantDeclaration(Visit, TIntermInvariantDeclaration *node) override; + bool visitFunctionPrototype(Visit, TIntermFunctionPrototype *node) override; + bool visitDeclaration(Visit, TIntermDeclaration *node) override; private: void ensureVersionIsAtLeast(int version); @@ -65,4 +71,6 @@ class TVersionGLSL : public TIntermTraverser int mVersion; }; +} // namespace sh + #endif // COMPILER_TRANSLATOR_VERSIONGLSL_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/WrapSwitchStatementsInBlocks.cpp b/src/3rdparty/angle/src/compiler/translator/WrapSwitchStatementsInBlocks.cpp new file mode 100644 index 0000000000..85a11c998d --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/WrapSwitchStatementsInBlocks.cpp @@ -0,0 +1,132 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// WrapSwitchStatementsInBlocks.cpp: Wrap switch statements in blocks and declare all switch-scoped +// variables there to make the AST compatible with HLSL output. +// +// switch (init) +// { +// case 0: +// float f; +// default: +// f = 1.0; +// } +// +// becomes +// +// { +// float f; +// switch (init) +// { +// case 0: +// default: +// f = 1.0; +// } +// } + +#include "compiler/translator/WrapSwitchStatementsInBlocks.h" + +#include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermTraverse.h" + +namespace sh +{ + +namespace +{ + +class WrapSwitchStatementsInBlocksTraverser : public TIntermTraverser +{ + public: + WrapSwitchStatementsInBlocksTraverser() : TIntermTraverser(true, false, false), mDidWrap(false) + { + } + + bool visitSwitch(Visit visit, TIntermSwitch *node) override; + + bool didWrap() const { return mDidWrap; } + + private: + bool mDidWrap; +}; + +bool WrapSwitchStatementsInBlocksTraverser::visitSwitch(Visit, TIntermSwitch *node) +{ + std::vector declarations; + TIntermSequence *statementList = node->getStatementList()->getSequence(); + for (TIntermNode *statement : *statementList) + { + TIntermDeclaration *asDeclaration = statement->getAsDeclarationNode(); + if (asDeclaration) + { + declarations.push_back(asDeclaration); + } + } + if (declarations.empty()) + { + // We don't need to wrap the switch if it doesn't contain declarations as its direct + // descendants. + return true; + } + + TIntermBlock *wrapperBlock = new TIntermBlock(); + for (TIntermDeclaration *declaration : declarations) + { + // SeparateDeclarations should have already been run. + ASSERT(declaration->getSequence()->size() == 1); + + TIntermDeclaration *declarationInBlock = new TIntermDeclaration(); + TIntermSymbol *declaratorAsSymbol = declaration->getSequence()->at(0)->getAsSymbolNode(); + if (declaratorAsSymbol) + { + // This is a simple declaration like: "float f;" + // Remove the declaration from inside the switch and put it in the wrapping block. + TIntermSequence emptyReplacement; + mMultiReplacements.push_back(NodeReplaceWithMultipleEntry( + node->getStatementList(), declaration, emptyReplacement)); + + declarationInBlock->appendDeclarator(declaratorAsSymbol->deepCopy()); + } + else + { + // This is an init declaration like: "float f = 0.0;" + // Change the init declaration inside the switch into an assignment and put a plain + // declaration in the wrapping block. + TIntermBinary *declaratorAsBinary = + declaration->getSequence()->at(0)->getAsBinaryNode(); + ASSERT(declaratorAsBinary); + + TIntermBinary *initAssignment = new TIntermBinary( + EOpAssign, declaratorAsBinary->getLeft(), declaratorAsBinary->getRight()); + + queueReplacementWithParent(node->getStatementList(), declaration, initAssignment, + OriginalNode::IS_DROPPED); + + declarationInBlock->appendDeclarator(declaratorAsBinary->getLeft()->deepCopy()); + } + wrapperBlock->appendStatement(declarationInBlock); + } + + wrapperBlock->appendStatement(node); + queueReplacement(wrapperBlock, OriginalNode::BECOMES_CHILD); + mDidWrap = true; + + // Should be fine to process multiple switch statements, even nesting ones in the same + // traversal. + return true; +} + +} // anonymous namespace + +// Wrap switch statements in the AST into blocks when needed. +bool WrapSwitchStatementsInBlocks(TIntermBlock *root) +{ + WrapSwitchStatementsInBlocksTraverser traverser; + root->traverse(&traverser); + traverser.updateTree(); + return traverser.didWrap(); +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/WrapSwitchStatementsInBlocks.h b/src/3rdparty/angle/src/compiler/translator/WrapSwitchStatementsInBlocks.h new file mode 100644 index 0000000000..bc0179926d --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/WrapSwitchStatementsInBlocks.h @@ -0,0 +1,22 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// WrapSwitchStatementsInBlocks.h: Wrap switch statements in blocks and declare all switch-scoped +// variables there to make the AST compatible with HLSL output. + +#ifndef COMPILER_TRANSLATOR_WRAPSWITCHSTATEMENTSINBLOCKS_H_ +#define COMPILER_TRANSLATOR_WRAPSWITCHSTATEMENTSINBLOCKS_H_ + +namespace sh +{ + +class TIntermBlock; + +// Wrap switch statements in the AST into blocks when needed. Returns true if the AST was changed. +bool WrapSwitchStatementsInBlocks(TIntermBlock *root); + +} // namespace sh + +#endif // COMPILER_TRANSLATOR_WRAPSWITCHSTATEMENTSINBLOCKS_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/blocklayout.cpp b/src/3rdparty/angle/src/compiler/translator/blocklayout.cpp index ba6322848e..fd8c450c20 100644 --- a/src/3rdparty/angle/src/compiler/translator/blocklayout.cpp +++ b/src/3rdparty/angle/src/compiler/translator/blocklayout.cpp @@ -15,24 +15,105 @@ namespace sh { -BlockLayoutEncoder::BlockLayoutEncoder() - : mCurrentOffset(0) +namespace +{ +bool IsRowMajorLayout(const InterfaceBlockField &var) +{ + return var.isRowMajorLayout; +} + +bool IsRowMajorLayout(const ShaderVariable &var) +{ + return false; +} + +template +void GetUniformBlockStructMemberInfo(const std::vector &fields, + const std::string &fieldName, + sh::BlockLayoutEncoder *encoder, + bool inRowMajorLayout, + BlockLayoutMap *blockInfoOut) +{ + encoder->enterAggregateType(); + GetUniformBlockInfo(fields, fieldName, encoder, inRowMajorLayout, blockInfoOut); + encoder->exitAggregateType(); +} + +template +void GetUniformBlockStructArrayMemberInfo(const VarT &field, + unsigned int arrayNestingIndex, + const std::string &arrayName, + sh::BlockLayoutEncoder *encoder, + bool inRowMajorLayout, + BlockLayoutMap *blockInfoOut) +{ + // Nested arrays are processed starting from outermost (arrayNestingIndex 0u) and ending at the + // innermost. + const unsigned int currentArraySize = field.getNestedArraySize(arrayNestingIndex); + for (unsigned int arrayElement = 0u; arrayElement < currentArraySize; ++arrayElement) + { + const std::string elementName = arrayName + ArrayString(arrayElement); + if (arrayNestingIndex + 1u < field.arraySizes.size()) + { + GetUniformBlockStructArrayMemberInfo(field, arrayNestingIndex + 1u, elementName, + encoder, inRowMajorLayout, blockInfoOut); + } + else + { + GetUniformBlockStructMemberInfo(field.fields, elementName, encoder, inRowMajorLayout, + blockInfoOut); + } + } +} + +template +void GetUniformBlockArrayOfArraysMemberInfo(const VarT &field, + unsigned int arrayNestingIndex, + const std::string &arrayName, + sh::BlockLayoutEncoder *encoder, + bool inRowMajorLayout, + BlockLayoutMap *blockInfoOut) +{ + const unsigned int currentArraySize = field.getNestedArraySize(arrayNestingIndex); + for (unsigned int arrayElement = 0u; arrayElement < currentArraySize; ++arrayElement) + { + const std::string elementName = arrayName + ArrayString(arrayElement); + if (arrayNestingIndex + 2u < field.arraySizes.size()) + { + GetUniformBlockArrayOfArraysMemberInfo(field, arrayNestingIndex + 1u, elementName, + encoder, inRowMajorLayout, blockInfoOut); + } + else + { + std::vector innermostArraySize( + 1u, field.getNestedArraySize(arrayNestingIndex + 1u)); + (*blockInfoOut)[elementName] = + encoder->encodeType(field.type, innermostArraySize, inRowMajorLayout); + } + } +} + +} // anonymous namespace + +BlockLayoutEncoder::BlockLayoutEncoder() : mCurrentOffset(0) { } -BlockMemberInfo BlockLayoutEncoder::encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix) +BlockMemberInfo BlockLayoutEncoder::encodeType(GLenum type, + const std::vector &arraySizes, + bool isRowMajorMatrix) { int arrayStride; int matrixStride; - getBlockLayoutInfo(type, arraySize, isRowMajorMatrix, &arrayStride, &matrixStride); + getBlockLayoutInfo(type, arraySizes, isRowMajorMatrix, &arrayStride, &matrixStride); const BlockMemberInfo memberInfo(static_cast(mCurrentOffset * BytesPerComponent), static_cast(arrayStride * BytesPerComponent), static_cast(matrixStride * BytesPerComponent), isRowMajorMatrix); - advanceOffset(type, arraySize, isRowMajorMatrix, arrayStride, matrixStride); + advanceOffset(type, arraySizes, isRowMajorMatrix, arrayStride, matrixStride); return memberInfo; } @@ -68,48 +149,56 @@ void Std140BlockEncoder::exitAggregateType() nextRegister(); } -void Std140BlockEncoder::getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut) +void Std140BlockEncoder::getBlockLayoutInfo(GLenum type, + const std::vector &arraySizes, + bool isRowMajorMatrix, + int *arrayStrideOut, + int *matrixStrideOut) { // We assume we are only dealing with 4 byte components (no doubles or half-words currently) ASSERT(gl::VariableComponentSize(gl::VariableComponentType(type)) == BytesPerComponent); size_t baseAlignment = 0; - int matrixStride = 0; - int arrayStride = 0; + int matrixStride = 0; + int arrayStride = 0; if (gl::IsMatrixType(type)) { baseAlignment = ComponentsPerRegister; - matrixStride = ComponentsPerRegister; + matrixStride = ComponentsPerRegister; - if (arraySize > 0) + if (!arraySizes.empty()) { const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix); - arrayStride = ComponentsPerRegister * numRegisters; + arrayStride = ComponentsPerRegister * numRegisters; } } - else if (arraySize > 0) + else if (!arraySizes.empty()) { baseAlignment = ComponentsPerRegister; - arrayStride = ComponentsPerRegister; + arrayStride = ComponentsPerRegister; } else { const int numComponents = gl::VariableComponentCount(type); - baseAlignment = (numComponents == 3 ? 4u : static_cast(numComponents)); + baseAlignment = (numComponents == 3 ? 4u : static_cast(numComponents)); } mCurrentOffset = rx::roundUp(mCurrentOffset, baseAlignment); *matrixStrideOut = matrixStride; - *arrayStrideOut = arrayStride; + *arrayStrideOut = arrayStride; } -void Std140BlockEncoder::advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride) +void Std140BlockEncoder::advanceOffset(GLenum type, + const std::vector &arraySizes, + bool isRowMajorMatrix, + int arrayStride, + int matrixStride) { - if (arraySize > 0) + if (!arraySizes.empty()) { - mCurrentOffset += arrayStride * arraySize; + mCurrentOffset += arrayStride * gl::ArraySizeProduct(arraySizes); } else if (gl::IsMatrixType(type)) { @@ -123,4 +212,70 @@ void Std140BlockEncoder::advanceOffset(GLenum type, unsigned int arraySize, bool } } +template +void GetUniformBlockInfo(const std::vector &fields, + const std::string &prefix, + sh::BlockLayoutEncoder *encoder, + bool inRowMajorLayout, + BlockLayoutMap *blockInfoOut) +{ + for (const VarT &field : fields) + { + // Skip samplers. On Vulkan we use this for the default uniform block, so samplers may be + // included. + if (gl::IsSamplerType(field.type)) + { + continue; + } + + const std::string &fieldName = (prefix.empty() ? field.name : prefix + "." + field.name); + + if (field.isStruct()) + { + bool rowMajorLayout = (inRowMajorLayout || IsRowMajorLayout(field)); + + if (field.isArray()) + { + GetUniformBlockStructArrayMemberInfo(field, 0u, fieldName, encoder, rowMajorLayout, + blockInfoOut); + } + else + { + GetUniformBlockStructMemberInfo(field.fields, fieldName, encoder, rowMajorLayout, + blockInfoOut); + } + } + else if (field.isArrayOfArrays()) + { + bool isRowMajorMatrix = (gl::IsMatrixType(field.type) && inRowMajorLayout); + GetUniformBlockArrayOfArraysMemberInfo(field, 0u, fieldName, encoder, isRowMajorMatrix, + blockInfoOut); + } + else + { + bool isRowMajorMatrix = (gl::IsMatrixType(field.type) && inRowMajorLayout); + (*blockInfoOut)[fieldName] = + encoder->encodeType(field.type, field.arraySizes, isRowMajorMatrix); + } + } } + +template void GetUniformBlockInfo(const std::vector &, + const std::string &, + sh::BlockLayoutEncoder *, + bool, + BlockLayoutMap *); + +template void GetUniformBlockInfo(const std::vector &, + const std::string &, + sh::BlockLayoutEncoder *, + bool, + BlockLayoutMap *); + +template void GetUniformBlockInfo(const std::vector &, + const std::string &, + sh::BlockLayoutEncoder *, + bool, + BlockLayoutMap *); + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/blocklayout.h b/src/3rdparty/angle/src/compiler/translator/blocklayout.h index dd5fe07376..2b7acf4e60 100644 --- a/src/3rdparty/angle/src/compiler/translator/blocklayout.h +++ b/src/3rdparty/angle/src/compiler/translator/blocklayout.h @@ -11,6 +11,7 @@ #define COMMON_BLOCKLAYOUT_H_ #include +#include #include #include "angle_gl.h" @@ -24,42 +25,64 @@ struct Uniform; struct Varying; struct InterfaceBlock; -struct COMPILER_EXPORT BlockMemberInfo +struct BlockMemberInfo { - BlockMemberInfo() : offset(-1), arrayStride(-1), matrixStride(-1), isRowMajorMatrix(false) {} + BlockMemberInfo() + : offset(-1), + arrayStride(-1), + matrixStride(-1), + isRowMajorMatrix(false), + topLevelArrayStride(-1) + { + } BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix) : offset(offset), arrayStride(arrayStride), matrixStride(matrixStride), - isRowMajorMatrix(isRowMajorMatrix) - {} - - static BlockMemberInfo getDefaultBlockInfo() + isRowMajorMatrix(isRowMajorMatrix), + topLevelArrayStride(-1) { - return BlockMemberInfo(-1, -1, -1, false); } + BlockMemberInfo(int offset, + int arrayStride, + int matrixStride, + bool isRowMajorMatrix, + int topLevelArrayStride) + : offset(offset), + arrayStride(arrayStride), + matrixStride(matrixStride), + isRowMajorMatrix(isRowMajorMatrix), + topLevelArrayStride(topLevelArrayStride) + { + } + + static BlockMemberInfo getDefaultBlockInfo() { return BlockMemberInfo(-1, -1, -1, false, -1); } + int offset; int arrayStride; int matrixStride; bool isRowMajorMatrix; + int topLevelArrayStride; // Only used for shader storage block members. }; -class COMPILER_EXPORT BlockLayoutEncoder +class BlockLayoutEncoder { public: BlockLayoutEncoder(); virtual ~BlockLayoutEncoder() {} - BlockMemberInfo encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix); + BlockMemberInfo encodeType(GLenum type, + const std::vector &arraySizes, + bool isRowMajorMatrix); size_t getBlockSize() const { return mCurrentOffset * BytesPerComponent; } virtual void enterAggregateType() = 0; - virtual void exitAggregateType() = 0; + virtual void exitAggregateType() = 0; - static const size_t BytesPerComponent = 4u; + static const size_t BytesPerComponent = 4u; static const unsigned int ComponentsPerRegister = 4u; static size_t getBlockRegister(const BlockMemberInfo &info); @@ -70,14 +93,22 @@ class COMPILER_EXPORT BlockLayoutEncoder void nextRegister(); - virtual void getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut) = 0; - virtual void advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride) = 0; + virtual void getBlockLayoutInfo(GLenum type, + const std::vector &arraySizes, + bool isRowMajorMatrix, + int *arrayStrideOut, + int *matrixStrideOut) = 0; + virtual void advanceOffset(GLenum type, + const std::vector &arraySizes, + bool isRowMajorMatrix, + int arrayStride, + int matrixStride) = 0; }; // Block layout according to the std140 block layout // See "Standard Uniform Block Layout" in Section 2.11.6 of the OpenGL ES 3.0 specification -class COMPILER_EXPORT Std140BlockEncoder : public BlockLayoutEncoder +class Std140BlockEncoder : public BlockLayoutEncoder { public: Std140BlockEncoder(); @@ -87,17 +118,27 @@ class COMPILER_EXPORT Std140BlockEncoder : public BlockLayoutEncoder protected: void getBlockLayoutInfo(GLenum type, - unsigned int arraySize, + const std::vector &arraySizes, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut) override; void advanceOffset(GLenum type, - unsigned int arraySize, + const std::vector &arraySizes, bool isRowMajorMatrix, int arrayStride, int matrixStride) override; }; -} +using BlockLayoutMap = std::map; -#endif // COMMON_BLOCKLAYOUT_H_ +// Only valid to call with ShaderVariable, InterfaceBlockField and Uniform. +template +void GetUniformBlockInfo(const std::vector &fields, + const std::string &prefix, + sh::BlockLayoutEncoder *encoder, + bool inRowMajorLayout, + BlockLayoutMap *blockLayoutMap); + +} // namespace sh + +#endif // COMMON_BLOCKLAYOUT_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/blocklayoutHLSL.cpp b/src/3rdparty/angle/src/compiler/translator/blocklayoutHLSL.cpp index 43119248eb..867821f1ea 100644 --- a/src/3rdparty/angle/src/compiler/translator/blocklayoutHLSL.cpp +++ b/src/3rdparty/angle/src/compiler/translator/blocklayoutHLSL.cpp @@ -15,9 +15,8 @@ namespace sh { -HLSLBlockEncoder::HLSLBlockEncoder(HLSLBlockEncoderStrategy strategy) - : mEncoderStrategy(strategy), - mTransposeMatrices(false) +HLSLBlockEncoder::HLSLBlockEncoder(HLSLBlockEncoderStrategy strategy, bool transposeMatrices) + : mEncoderStrategy(strategy), mTransposeMatrices(transposeMatrices) { } @@ -30,7 +29,11 @@ void HLSLBlockEncoder::exitAggregateType() { } -void HLSLBlockEncoder::getBlockLayoutInfo(GLenum typeIn, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut) +void HLSLBlockEncoder::getBlockLayoutInfo(GLenum typeIn, + const std::vector &arraySizes, + bool isRowMajorMatrix, + int *arrayStrideOut, + int *matrixStrideOut) { GLenum type = (mTransposeMatrices ? gl::TransposeMatrixType(typeIn) : typeIn); @@ -38,14 +41,12 @@ void HLSLBlockEncoder::getBlockLayoutInfo(GLenum typeIn, unsigned int arraySize, ASSERT(gl::VariableComponentSize(gl::VariableComponentType(type)) == BytesPerComponent); int matrixStride = 0; - int arrayStride = 0; + int arrayStride = 0; // if variables are not to be packed, or we're about to // pack a matrix or array, skip to the start of the next // register - if (!isPacked() || - gl::IsMatrixType(type) || - arraySize > 0) + if (!isPacked() || gl::IsMatrixType(type) || !arraySizes.empty()) { nextRegister(); } @@ -54,13 +55,13 @@ void HLSLBlockEncoder::getBlockLayoutInfo(GLenum typeIn, unsigned int arraySize, { matrixStride = ComponentsPerRegister; - if (arraySize > 0) + if (!arraySizes.empty()) { const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix); - arrayStride = ComponentsPerRegister * numRegisters; + arrayStride = ComponentsPerRegister * numRegisters; } } - else if (arraySize > 0) + else if (!arraySizes.empty()) { arrayStride = ComponentsPerRegister; } @@ -74,22 +75,26 @@ void HLSLBlockEncoder::getBlockLayoutInfo(GLenum typeIn, unsigned int arraySize, } *matrixStrideOut = matrixStride; - *arrayStrideOut = arrayStride; + *arrayStrideOut = arrayStride; } -void HLSLBlockEncoder::advanceOffset(GLenum typeIn, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride) +void HLSLBlockEncoder::advanceOffset(GLenum typeIn, + const std::vector &arraySizes, + bool isRowMajorMatrix, + int arrayStride, + int matrixStride) { GLenum type = (mTransposeMatrices ? gl::TransposeMatrixType(typeIn) : typeIn); - if (arraySize > 0) + if (!arraySizes.empty()) { - mCurrentOffset += arrayStride * (arraySize - 1); + mCurrentOffset += arrayStride * (gl::ArraySizeProduct(arraySizes) - 1); } if (gl::IsMatrixType(type)) { ASSERT(matrixStride == ComponentsPerRegister); - const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix); + const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix); const int numComponents = gl::MatrixComponentCount(type, isRowMajorMatrix); mCurrentOffset += ComponentsPerRegister * (numRegisters - 1); mCurrentOffset += numComponents; @@ -109,7 +114,8 @@ void HLSLBlockEncoder::skipRegisters(unsigned int numRegisters) mCurrentOffset += (numRegisters * ComponentsPerRegister); } -HLSLBlockEncoder::HLSLBlockEncoderStrategy HLSLBlockEncoder::GetStrategyFor(ShShaderOutput outputType) +HLSLBlockEncoder::HLSLBlockEncoderStrategy HLSLBlockEncoder::GetStrategyFor( + ShShaderOutput outputType) { switch (outputType) { @@ -129,7 +135,7 @@ void HLSLVariableRegisterCount(const ShaderVarType &variable, HLSLBlockEncoder * { if (variable.isStruct()) { - for (size_t arrayElement = 0; arrayElement < variable.elementCount(); arrayElement++) + for (size_t arrayElement = 0; arrayElement < variable.getArraySizeProduct(); arrayElement++) { encoder->enterAggregateType(); @@ -144,28 +150,17 @@ void HLSLVariableRegisterCount(const ShaderVarType &variable, HLSLBlockEncoder * else { // We operate only on varyings and uniforms, which do not have matrix layout qualifiers - encoder->encodeType(variable.type, variable.arraySize, false); + encoder->encodeType(variable.type, variable.arraySizes, false); } } -unsigned int HLSLVariableRegisterCount(const Varying &variable, bool transposeMatrices) -{ - HLSLBlockEncoder encoder(HLSLBlockEncoder::ENCODE_PACKED); - encoder.setTransposeMatrices(transposeMatrices); - HLSLVariableRegisterCount(variable, &encoder); - - const size_t registerBytes = (encoder.BytesPerComponent * encoder.ComponentsPerRegister); - return static_cast(rx::roundUp(encoder.getBlockSize(), registerBytes) / registerBytes); -} - unsigned int HLSLVariableRegisterCount(const Uniform &variable, ShShaderOutput outputType) { - HLSLBlockEncoder encoder(HLSLBlockEncoder::GetStrategyFor(outputType)); - encoder.setTransposeMatrices(true); + HLSLBlockEncoder encoder(HLSLBlockEncoder::GetStrategyFor(outputType), true); HLSLVariableRegisterCount(variable, &encoder); const size_t registerBytes = (encoder.BytesPerComponent * encoder.ComponentsPerRegister); - return static_cast(rx::roundUp(encoder.getBlockSize(), registerBytes) / registerBytes); -} - + return static_cast(rx::roundUp(encoder.getBlockSize(), registerBytes) / + registerBytes); } +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/blocklayoutHLSL.h b/src/3rdparty/angle/src/compiler/translator/blocklayoutHLSL.h index c61cb1ae57..8f4a51a906 100644 --- a/src/3rdparty/angle/src/compiler/translator/blocklayoutHLSL.h +++ b/src/3rdparty/angle/src/compiler/translator/blocklayoutHLSL.h @@ -24,7 +24,7 @@ namespace sh // The strategy should be ENCODE_LOOSE for D3D9 constant blocks, and ENCODE_PACKED // for everything else (D3D10+ constant blocks and all attributes/varyings). -class COMPILER_EXPORT HLSLBlockEncoder : public BlockLayoutEncoder +class HLSLBlockEncoder : public BlockLayoutEncoder { public: enum HLSLBlockEncoderStrategy @@ -33,30 +33,36 @@ class COMPILER_EXPORT HLSLBlockEncoder : public BlockLayoutEncoder ENCODE_LOOSE }; - HLSLBlockEncoder(HLSLBlockEncoderStrategy strategy); + HLSLBlockEncoder(HLSLBlockEncoderStrategy strategy, bool transposeMatrices); - virtual void enterAggregateType(); - virtual void exitAggregateType(); + void enterAggregateType() override; + void exitAggregateType() override; void skipRegisters(unsigned int numRegisters); bool isPacked() const { return mEncoderStrategy == ENCODE_PACKED; } - void setTransposeMatrices(bool enabled) { mTransposeMatrices = enabled; } static HLSLBlockEncoderStrategy GetStrategyFor(ShShaderOutput outputType); protected: - virtual void getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut); - virtual void advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride); + void getBlockLayoutInfo(GLenum type, + const std::vector &arraySizes, + bool isRowMajorMatrix, + int *arrayStrideOut, + int *matrixStrideOut) override; + void advanceOffset(GLenum type, + const std::vector &arraySizes, + bool isRowMajorMatrix, + int arrayStride, + int matrixStride) override; HLSLBlockEncoderStrategy mEncoderStrategy; bool mTransposeMatrices; }; -// This method returns the number of used registers for a ShaderVariable. It is dependent on the HLSLBlockEncoder -// class to count the number of used registers in a struct (which are individually packed according to the same rules). -COMPILER_EXPORT unsigned int HLSLVariableRegisterCount(const Varying &variable, bool transposeMatrices); -COMPILER_EXPORT unsigned int HLSLVariableRegisterCount(const Uniform &variable, ShShaderOutput outputType); - +// This method returns the number of used registers for a ShaderVariable. It is dependent on the +// HLSLBlockEncoder class to count the number of used registers in a struct (which are individually +// packed according to the same rules). +unsigned int HLSLVariableRegisterCount(const Uniform &variable, ShShaderOutput outputType); } -#endif // COMMON_BLOCKLAYOUTHLSL_H_ +#endif // COMMON_BLOCKLAYOUTHLSL_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/compilerdebug.cpp b/src/3rdparty/angle/src/compiler/translator/compilerdebug.cpp deleted file mode 100644 index 10cbe43b8d..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/compilerdebug.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// debug.cpp: Debugging utilities. - -#include "compiler/translator/compilerdebug.h" - -#include -#include - -#include "compiler/translator/InitializeParseContext.h" -#include "compiler/translator/ParseContext.h" - -#ifdef TRACE_ENABLED -static const int kTraceBufferLen = 1024; - -extern "C" { -void Trace(const char *format, ...) { - if (!format) return; - - TParseContext* parseContext = GetGlobalParseContext(); - if (parseContext) { - char buf[kTraceBufferLen]; - va_list args; - va_start(args, format); - vsnprintf(buf, kTraceBufferLen, format, args); - va_end(args); - - parseContext->trace(buf); - } -} -} // extern "C" -#endif // TRACE_ENABLED - diff --git a/src/3rdparty/angle/src/compiler/translator/compilerdebug.h b/src/3rdparty/angle/src/compiler/translator/compilerdebug.h deleted file mode 100644 index 84a12ad2f8..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/compilerdebug.h +++ /dev/null @@ -1,53 +0,0 @@ -// -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// debug.h: Debugging utilities. - -#ifndef COMPILER_TRANSLATOR_COMPILERDEBUG_H_ -#define COMPILER_TRANSLATOR_COMPILERDEBUG_H_ - -#include - -#ifdef _DEBUG -#define TRACE_ENABLED // define to enable debug message tracing -#endif // _DEBUG - -// Outputs text to the debug log -#ifdef TRACE_ENABLED - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus -void Trace(const char* format, ...); -#ifdef __cplusplus -} -#endif // __cplusplus - -#else // TRACE_ENABLED - -#define Trace(...) ((void)0) - -#endif // TRACE_ENABLED - -// A macro asserting a condition and outputting failures to the debug log -#define ASSERT(expression) do { \ - if(!(expression)) \ - Trace("Assert failed: %s(%d): "#expression"\n", __FUNCTION__, __LINE__); \ - assert(expression); \ -} while(0) - -#define UNIMPLEMENTED() do { \ - Trace("Unimplemented invoked: %s(%d)\n", __FUNCTION__, __LINE__); \ - assert(false); \ -} while(0) - -#define UNREACHABLE() do { \ - Trace("Unreachable reached: %s(%d)\n", __FUNCTION__, __LINE__); \ - assert(false); \ -} while(0) - -#endif // COMPILER_TRANSLATOR_COMPILERDEBUG_H_ - diff --git a/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraph.cpp b/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraph.cpp deleted file mode 100644 index 4dee0dbd2e..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraph.cpp +++ /dev/null @@ -1,95 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/translator/depgraph/DependencyGraph.h" -#include "compiler/translator/depgraph/DependencyGraphBuilder.h" - -TDependencyGraph::TDependencyGraph(TIntermNode* intermNode) -{ - TDependencyGraphBuilder::build(intermNode, this); -} - -TDependencyGraph::~TDependencyGraph() -{ - for (TGraphNodeVector::const_iterator iter = mAllNodes.begin(); iter != mAllNodes.end(); ++iter) - { - TGraphNode* node = *iter; - delete node; - } -} - -TGraphArgument* TDependencyGraph::createArgument(TIntermAggregate* intermFunctionCall, - int argumentNumber) -{ - TGraphArgument* argument = new TGraphArgument(intermFunctionCall, argumentNumber); - mAllNodes.push_back(argument); - return argument; -} - -TGraphFunctionCall* TDependencyGraph::createFunctionCall(TIntermAggregate* intermFunctionCall) -{ - TGraphFunctionCall* functionCall = new TGraphFunctionCall(intermFunctionCall); - mAllNodes.push_back(functionCall); - if (functionCall->getIntermFunctionCall()->isUserDefined()) - mUserDefinedFunctionCalls.push_back(functionCall); - return functionCall; -} - -TGraphSymbol* TDependencyGraph::getOrCreateSymbol(TIntermSymbol* intermSymbol) -{ - TSymbolIdMap::const_iterator iter = mSymbolIdMap.find(intermSymbol->getId()); - - TGraphSymbol* symbol = NULL; - - if (iter != mSymbolIdMap.end()) { - TSymbolIdPair pair = *iter; - symbol = pair.second; - } else { - symbol = new TGraphSymbol(intermSymbol); - mAllNodes.push_back(symbol); - - TSymbolIdPair pair(intermSymbol->getId(), symbol); - mSymbolIdMap.insert(pair); - - // We save all sampler symbols in a collection, so we can start graph traversals from them quickly. - if (IsSampler(intermSymbol->getBasicType())) - mSamplerSymbols.push_back(symbol); - } - - return symbol; -} - -TGraphSelection* TDependencyGraph::createSelection(TIntermSelection* intermSelection) -{ - TGraphSelection* selection = new TGraphSelection(intermSelection); - mAllNodes.push_back(selection); - return selection; -} - -TGraphLoop* TDependencyGraph::createLoop(TIntermLoop* intermLoop) -{ - TGraphLoop* loop = new TGraphLoop(intermLoop); - mAllNodes.push_back(loop); - return loop; -} - -TGraphLogicalOp* TDependencyGraph::createLogicalOp(TIntermBinary* intermLogicalOp) -{ - TGraphLogicalOp* logicalOp = new TGraphLogicalOp(intermLogicalOp); - mAllNodes.push_back(logicalOp); - return logicalOp; -} - -const char* TGraphLogicalOp::getOpString() const -{ - const char* opString = NULL; - switch (getIntermLogicalOp()->getOp()) { - case EOpLogicalAnd: opString = "and"; break; - case EOpLogicalOr: opString = "or"; break; - default: opString = "unknown"; break; - } - return opString; -} diff --git a/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraph.h b/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraph.h deleted file mode 100644 index 2f7f7b9ab8..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraph.h +++ /dev/null @@ -1,199 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPH_H_ -#define COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPH_H_ - -#include "compiler/translator/IntermNode.h" - -#include -#include - -class TGraphNode; -class TGraphParentNode; -class TGraphArgument; -class TGraphFunctionCall; -class TGraphSymbol; -class TGraphSelection; -class TGraphLoop; -class TGraphLogicalOp; -class TDependencyGraphTraverser; -class TDependencyGraphOutput; - -typedef std::set TGraphNodeSet; -typedef std::vector TGraphNodeVector; -typedef std::vector TGraphSymbolVector; -typedef std::vector TFunctionCallVector; - -// -// Base class for all dependency graph nodes. -// -class TGraphNode { -public: - TGraphNode(TIntermNode* node) : intermNode(node) {} - virtual ~TGraphNode() {} - virtual void traverse(TDependencyGraphTraverser* graphTraverser); -protected: - TIntermNode* intermNode; -}; - -// -// Base class for dependency graph nodes that may have children. -// -class TGraphParentNode : public TGraphNode { -public: - TGraphParentNode(TIntermNode* node) : TGraphNode(node) {} - ~TGraphParentNode() override {} - void addDependentNode(TGraphNode* node) { if (node != this) mDependentNodes.insert(node); } - void traverse(TDependencyGraphTraverser *graphTraverser) override; - -private: - TGraphNodeSet mDependentNodes; -}; - -// -// Handle function call arguments. -// -class TGraphArgument : public TGraphParentNode { -public: - TGraphArgument(TIntermAggregate* intermFunctionCall, int argumentNumber) - : TGraphParentNode(intermFunctionCall) - , mArgumentNumber(argumentNumber) {} - ~TGraphArgument() override {} - const TIntermAggregate* getIntermFunctionCall() const { return intermNode->getAsAggregate(); } - int getArgumentNumber() const { return mArgumentNumber; } - void traverse(TDependencyGraphTraverser *graphTraverser) override; - -private: - int mArgumentNumber; -}; - -// -// Handle function calls. -// -class TGraphFunctionCall : public TGraphParentNode { -public: - TGraphFunctionCall(TIntermAggregate* intermFunctionCall) - : TGraphParentNode(intermFunctionCall) {} - ~TGraphFunctionCall() override {} - const TIntermAggregate* getIntermFunctionCall() const { return intermNode->getAsAggregate(); } - void traverse(TDependencyGraphTraverser *graphTraverser) override; -}; - -// -// Handle symbols. -// -class TGraphSymbol : public TGraphParentNode { -public: - TGraphSymbol(TIntermSymbol* intermSymbol) : TGraphParentNode(intermSymbol) {} - ~TGraphSymbol() override {} - const TIntermSymbol* getIntermSymbol() const { return intermNode->getAsSymbolNode(); } - void traverse(TDependencyGraphTraverser *graphTraverser) override; -}; - -// -// Handle if statements and ternary operators. -// -class TGraphSelection : public TGraphNode { -public: - TGraphSelection(TIntermSelection* intermSelection) : TGraphNode(intermSelection) {} - ~TGraphSelection() override {} - const TIntermSelection* getIntermSelection() const { return intermNode->getAsSelectionNode(); } - void traverse(TDependencyGraphTraverser *graphTraverser) override; -}; - -// -// Handle for, do-while, and while loops. -// -class TGraphLoop : public TGraphNode { -public: - TGraphLoop(TIntermLoop* intermLoop) : TGraphNode(intermLoop) {} - ~TGraphLoop() override {} - const TIntermLoop* getIntermLoop() const { return intermNode->getAsLoopNode(); } - void traverse(TDependencyGraphTraverser *graphTraverser) override; -}; - -// -// Handle logical and, or. -// -class TGraphLogicalOp : public TGraphNode { -public: - TGraphLogicalOp(TIntermBinary* intermLogicalOp) : TGraphNode(intermLogicalOp) {} - ~TGraphLogicalOp() override {} - const TIntermBinary* getIntermLogicalOp() const { return intermNode->getAsBinaryNode(); } - const char* getOpString() const; - void traverse(TDependencyGraphTraverser *graphTraverser) override; -}; - -// -// A dependency graph of symbols, function calls, conditions etc. -// -// This class provides an interface to the entry points of the dependency graph. -// -// Dependency graph nodes should be created by using one of the provided "create..." methods. -// This class (and nobody else) manages the memory of the created nodes. -// Nodes may not be removed after being added, so all created nodes will exist while the -// TDependencyGraph instance exists. -// -class TDependencyGraph { -public: - TDependencyGraph(TIntermNode* intermNode); - ~TDependencyGraph(); - const TGraphNodeVector &allNodes() const { return mAllNodes; } - const TGraphSymbolVector &samplerSymbols() const { return mSamplerSymbols; } - const TFunctionCallVector &userDefinedFunctionCalls() const - { - return mUserDefinedFunctionCalls; - } - - TGraphArgument* createArgument(TIntermAggregate* intermFunctionCall, int argumentNumber); - TGraphFunctionCall* createFunctionCall(TIntermAggregate* intermFunctionCall); - TGraphSymbol* getOrCreateSymbol(TIntermSymbol* intermSymbol); - TGraphSelection* createSelection(TIntermSelection* intermSelection); - TGraphLoop* createLoop(TIntermLoop* intermLoop); - TGraphLogicalOp* createLogicalOp(TIntermBinary* intermLogicalOp); -private: - typedef TMap TSymbolIdMap; - typedef std::pair TSymbolIdPair; - - TGraphNodeVector mAllNodes; - TGraphSymbolVector mSamplerSymbols; - TFunctionCallVector mUserDefinedFunctionCalls; - TSymbolIdMap mSymbolIdMap; -}; - -// -// For traversing the dependency graph. Users should derive from this, -// put their traversal specific data in it, and then pass it to a -// traverse method. -// -// When using this, just fill in the methods for nodes you want visited. -// -class TDependencyGraphTraverser : angle::NonCopyable { -public: - TDependencyGraphTraverser() : mDepth(0) {} - virtual ~TDependencyGraphTraverser() {} - - virtual void visitSymbol(TGraphSymbol* symbol) {}; - virtual void visitArgument(TGraphArgument* selection) {}; - virtual void visitFunctionCall(TGraphFunctionCall* functionCall) {}; - virtual void visitSelection(TGraphSelection* selection) {}; - virtual void visitLoop(TGraphLoop* loop) {}; - virtual void visitLogicalOp(TGraphLogicalOp* logicalOp) {}; - - int getDepth() const { return mDepth; } - void incrementDepth() { ++mDepth; } - void decrementDepth() { --mDepth; } - - void clearVisited() { mVisited.clear(); } - void markVisited(TGraphNode* node) { mVisited.insert(node); } - bool isVisited(TGraphNode* node) const { return mVisited.find(node) != mVisited.end(); } -private: - int mDepth; - TGraphNodeSet mVisited; -}; - -#endif // COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPH_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.cpp b/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.cpp deleted file mode 100644 index 1aeb822d51..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.cpp +++ /dev/null @@ -1,255 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/translator/depgraph/DependencyGraphBuilder.h" - -void TDependencyGraphBuilder::build(TIntermNode *node, TDependencyGraph *graph) -{ - TDependencyGraphBuilder builder(graph); - builder.build(node); -} - -bool TDependencyGraphBuilder::visitAggregate( - Visit visit, TIntermAggregate *intermAggregate) -{ - switch (intermAggregate->getOp()) - { - case EOpFunction: - visitFunctionDefinition(intermAggregate); - break; - case EOpFunctionCall: - visitFunctionCall(intermAggregate); - break; - default: - visitAggregateChildren(intermAggregate); - break; - } - return false; -} - -void TDependencyGraphBuilder::visitFunctionDefinition( - TIntermAggregate *intermAggregate) -{ - // Currently, we do not support user defined functions. - if (intermAggregate->getName() != "main(") - return; - - visitAggregateChildren(intermAggregate); -} - -// Takes an expression like "f(x)" and creates a dependency graph like -// "x -> argument 0 -> function call". -void TDependencyGraphBuilder::visitFunctionCall( - TIntermAggregate *intermFunctionCall) -{ - TGraphFunctionCall *functionCall = - mGraph->createFunctionCall(intermFunctionCall); - - // Run through the function call arguments. - int argumentNumber = 0; - TIntermSequence *intermArguments = intermFunctionCall->getSequence(); - for (TIntermSequence::const_iterator iter = intermArguments->begin(); - iter != intermArguments->end(); - ++iter, ++argumentNumber) - { - TNodeSetMaintainer nodeSetMaintainer(this); - - TIntermNode *intermArgument = *iter; - intermArgument->traverse(this); - - if (TParentNodeSet *argumentNodes = mNodeSets.getTopSet()) - { - TGraphArgument *argument = mGraph->createArgument( - intermFunctionCall, argumentNumber); - connectMultipleNodesToSingleNode(argumentNodes, argument); - argument->addDependentNode(functionCall); - } - } - - // Push the leftmost symbol of this function call into the current set of - // dependent symbols to represent the result of this function call. - // Thus, an expression like "y = f(x)" will yield a dependency graph like - // "x -> argument 0 -> function call -> y". - // This line essentially passes the function call node back up to an earlier - // visitAssignment call, which will create the connection "function call -> y". - mNodeSets.insertIntoTopSet(functionCall); -} - -void TDependencyGraphBuilder::visitAggregateChildren( - TIntermAggregate *intermAggregate) -{ - TIntermSequence *sequence = intermAggregate->getSequence(); - for (TIntermSequence::const_iterator iter = sequence->begin(); - iter != sequence->end(); ++iter) - { - TIntermNode *intermChild = *iter; - intermChild->traverse(this); - } -} - -void TDependencyGraphBuilder::visitSymbol(TIntermSymbol *intermSymbol) -{ - // Push this symbol into the set of dependent symbols for the current - // assignment or condition that we are traversing. - TGraphSymbol *symbol = mGraph->getOrCreateSymbol(intermSymbol); - mNodeSets.insertIntoTopSet(symbol); - - // If this symbol is the current leftmost symbol under an assignment, replace - // the previous leftmost symbol with this symbol. - if (!mLeftmostSymbols.empty() && mLeftmostSymbols.top() != &mRightSubtree) - { - mLeftmostSymbols.pop(); - mLeftmostSymbols.push(symbol); - } -} - -bool TDependencyGraphBuilder::visitBinary(Visit visit, TIntermBinary *intermBinary) -{ - TOperator op = intermBinary->getOp(); - if (op == EOpInitialize || intermBinary->isAssignment()) - visitAssignment(intermBinary); - else if (op == EOpLogicalAnd || op == EOpLogicalOr) - visitLogicalOp(intermBinary); - else - visitBinaryChildren(intermBinary); - - return false; -} - -void TDependencyGraphBuilder::visitAssignment(TIntermBinary *intermAssignment) -{ - TIntermTyped *intermLeft = intermAssignment->getLeft(); - if (!intermLeft) - return; - - TGraphSymbol *leftmostSymbol = NULL; - - { - TNodeSetMaintainer nodeSetMaintainer(this); - - { - TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mLeftSubtree); - intermLeft->traverse(this); - leftmostSymbol = mLeftmostSymbols.top(); - - // After traversing the left subtree of this assignment, we should - // have found a real leftmost symbol, and the leftmost symbol should - // not be a placeholder. - ASSERT(leftmostSymbol != &mLeftSubtree); - ASSERT(leftmostSymbol != &mRightSubtree); - } - - if (TIntermTyped *intermRight = intermAssignment->getRight()) - { - TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree); - intermRight->traverse(this); - } - - if (TParentNodeSet *assignmentNodes = mNodeSets.getTopSet()) - connectMultipleNodesToSingleNode(assignmentNodes, leftmostSymbol); - } - - // Push the leftmost symbol of this assignment into the current set of dependent - // symbols to represent the result of this assignment. - // An expression like "a = (b = c)" will yield a dependency graph like - // "c -> b -> a". - // This line essentially passes the leftmost symbol of the nested assignment - // ("b" in this example) back up to the earlier visitAssignment call for the - // outer assignment, which will create the connection "b -> a". - mNodeSets.insertIntoTopSet(leftmostSymbol); -} - -void TDependencyGraphBuilder::visitLogicalOp(TIntermBinary *intermLogicalOp) -{ - if (TIntermTyped *intermLeft = intermLogicalOp->getLeft()) - { - TNodeSetPropagatingMaintainer nodeSetMaintainer(this); - - intermLeft->traverse(this); - if (TParentNodeSet *leftNodes = mNodeSets.getTopSet()) - { - TGraphLogicalOp *logicalOp = mGraph->createLogicalOp(intermLogicalOp); - connectMultipleNodesToSingleNode(leftNodes, logicalOp); - } - } - - if (TIntermTyped *intermRight = intermLogicalOp->getRight()) - { - TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree); - intermRight->traverse(this); - } -} - -void TDependencyGraphBuilder::visitBinaryChildren(TIntermBinary *intermBinary) -{ - if (TIntermTyped *intermLeft = intermBinary->getLeft()) - intermLeft->traverse(this); - - if (TIntermTyped *intermRight = intermBinary->getRight()) - { - TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree); - intermRight->traverse(this); - } -} - -bool TDependencyGraphBuilder::visitSelection( - Visit visit, TIntermSelection *intermSelection) -{ - if (TIntermNode *intermCondition = intermSelection->getCondition()) - { - TNodeSetMaintainer nodeSetMaintainer(this); - - intermCondition->traverse(this); - if (TParentNodeSet *conditionNodes = mNodeSets.getTopSet()) - { - TGraphSelection *selection = mGraph->createSelection(intermSelection); - connectMultipleNodesToSingleNode(conditionNodes, selection); - } - } - - if (TIntermNode *intermTrueBlock = intermSelection->getTrueBlock()) - intermTrueBlock->traverse(this); - - if (TIntermNode *intermFalseBlock = intermSelection->getFalseBlock()) - intermFalseBlock->traverse(this); - - return false; -} - -bool TDependencyGraphBuilder::visitLoop(Visit visit, TIntermLoop *intermLoop) -{ - if (TIntermTyped *intermCondition = intermLoop->getCondition()) - { - TNodeSetMaintainer nodeSetMaintainer(this); - - intermCondition->traverse(this); - if (TParentNodeSet *conditionNodes = mNodeSets.getTopSet()) - { - TGraphLoop *loop = mGraph->createLoop(intermLoop); - connectMultipleNodesToSingleNode(conditionNodes, loop); - } - } - - if (TIntermNode* intermBody = intermLoop->getBody()) - intermBody->traverse(this); - - if (TIntermTyped *intermExpression = intermLoop->getExpression()) - intermExpression->traverse(this); - - return false; -} - - -void TDependencyGraphBuilder::connectMultipleNodesToSingleNode( - TParentNodeSet *nodes, TGraphNode *node) const -{ - for (TParentNodeSet::const_iterator iter = nodes->begin(); - iter != nodes->end(); ++iter) - { - TGraphParentNode *currentNode = *iter; - currentNode->addDependentNode(node); - } -} diff --git a/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.h b/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.h deleted file mode 100644 index c7b54f66b7..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphBuilder.h +++ /dev/null @@ -1,199 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPHBUILDER_H_ -#define COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPHBUILDER_H_ - -#include "compiler/translator/depgraph/DependencyGraph.h" - -// -// Creates a dependency graph of symbols, function calls, conditions etc. by -// traversing a intermediate tree. -// -class TDependencyGraphBuilder : public TIntermTraverser -{ - public: - static void build(TIntermNode *node, TDependencyGraph *graph); - - void visitSymbol(TIntermSymbol *) override; - bool visitBinary(Visit visit, TIntermBinary *) override; - bool visitSelection(Visit visit, TIntermSelection *) override; - bool visitAggregate(Visit visit, TIntermAggregate *) override; - bool visitLoop(Visit visit, TIntermLoop *) override; - - private: - typedef std::stack TSymbolStack; - typedef std::set TParentNodeSet; - - // - // For collecting the dependent nodes of assignments, conditions, etc. - // while traversing the intermediate tree. - // - // This data structure is stack of sets. Each set contains dependency graph - // parent nodes. - // - class TNodeSetStack - { - public: - TNodeSetStack() {}; - ~TNodeSetStack() { clear(); } - - // This should only be called after a pushSet. - // Returns NULL if the top set is empty. - TParentNodeSet *getTopSet() const - { - ASSERT(!mNodeSets.empty()); - TParentNodeSet *topSet = mNodeSets.top(); - return !topSet->empty() ? topSet : NULL; - } - - void pushSet() { mNodeSets.push(new TParentNodeSet()); } - void popSet() - { - ASSERT(!mNodeSets.empty()); - delete mNodeSets.top(); - mNodeSets.pop(); - } - - // Pops the top set and adds its contents to the new top set. - // This should only be called after a pushSet. - // If there is no set below the top set, the top set is just deleted. - void popSetIntoNext() - { - ASSERT(!mNodeSets.empty()); - TParentNodeSet *oldTopSet = mNodeSets.top(); - mNodeSets.pop(); - - if (!mNodeSets.empty()) - { - TParentNodeSet *newTopSet = mNodeSets.top(); - newTopSet->insert(oldTopSet->begin(), oldTopSet->end()); - } - - delete oldTopSet; - } - - // Does nothing if there is no top set. - // This can be called when there is no top set if we are visiting - // symbols that are not under an assignment or condition. - // We don't need to track those symbols. - void insertIntoTopSet(TGraphParentNode *node) - { - if (mNodeSets.empty()) - return; - - mNodeSets.top()->insert(node); - } - - void clear() - { - while (!mNodeSets.empty()) - popSet(); - } - - private: - typedef std::stack TParentNodeSetStack; - - TParentNodeSetStack mNodeSets; - }; - - // - // An instance of this class pushes a new node set when instantiated. - // When the instance goes out of scope, it and pops the node set. - // - class TNodeSetMaintainer : angle::NonCopyable - { - public: - TNodeSetMaintainer(TDependencyGraphBuilder *factory) - : mSets(factory->mNodeSets) - { - mSets.pushSet(); - } - ~TNodeSetMaintainer() { mSets.popSet(); } - protected: - TNodeSetStack &mSets; - }; - - // - // An instance of this class pushes a new node set when instantiated. - // When the instance goes out of scope, it and pops the top node set and adds - // its contents to the new top node set. - // - class TNodeSetPropagatingMaintainer : angle::NonCopyable - { - public: - TNodeSetPropagatingMaintainer(TDependencyGraphBuilder *factory) - : mSets(factory->mNodeSets) - { - mSets.pushSet(); - } - ~TNodeSetPropagatingMaintainer() { mSets.popSetIntoNext(); } - protected: - TNodeSetStack &mSets; - }; - - // - // An instance of this class keeps track of the leftmost symbol while we're - // exploring an assignment. - // It will push the placeholder symbol kLeftSubtree when instantiated under a - // left subtree, and kRightSubtree under a right subtree. - // When it goes out of scope, it will pop the leftmost symbol at the top of the - // scope. - // During traversal, the TDependencyGraphBuilder will replace kLeftSubtree with - // a real symbol. - // kRightSubtree will never be replaced by a real symbol because we are tracking - // the leftmost symbol. - // - class TLeftmostSymbolMaintainer : angle::NonCopyable - { - public: - TLeftmostSymbolMaintainer( - TDependencyGraphBuilder *factory, TGraphSymbol &subtree) - : mLeftmostSymbols(factory->mLeftmostSymbols) - { - mNeedsPlaceholderSymbol = - mLeftmostSymbols.empty() || mLeftmostSymbols.top() != &subtree; - if (mNeedsPlaceholderSymbol) - mLeftmostSymbols.push(&subtree); - } - - ~TLeftmostSymbolMaintainer() - { - if (mNeedsPlaceholderSymbol) - mLeftmostSymbols.pop(); - } - - protected: - TSymbolStack& mLeftmostSymbols; - bool mNeedsPlaceholderSymbol; - }; - - TDependencyGraphBuilder(TDependencyGraph *graph) - : TIntermTraverser(true, false, false), - mLeftSubtree(NULL), - mRightSubtree(NULL), - mGraph(graph) {} - void build(TIntermNode *intermNode) { intermNode->traverse(this); } - - void connectMultipleNodesToSingleNode( - TParentNodeSet *nodes, TGraphNode *node) const; - - void visitAssignment(TIntermBinary *); - void visitLogicalOp(TIntermBinary *); - void visitBinaryChildren(TIntermBinary *); - void visitFunctionDefinition(TIntermAggregate *); - void visitFunctionCall(TIntermAggregate *intermFunctionCall); - void visitAggregateChildren(TIntermAggregate *); - - TGraphSymbol mLeftSubtree; - TGraphSymbol mRightSubtree; - - TDependencyGraph *mGraph; - TNodeSetStack mNodeSets; - TSymbolStack mLeftmostSymbols; -}; - -#endif // COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPHBUILDER_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphOutput.cpp b/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphOutput.cpp deleted file mode 100644 index 32a2f30141..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphOutput.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/translator/depgraph/DependencyGraphOutput.h" - -void TDependencyGraphOutput::outputIndentation() -{ - for (int i = 0; i < getDepth(); ++i) - mSink << " "; -} - -void TDependencyGraphOutput::visitArgument(TGraphArgument* parameter) -{ - outputIndentation(); - mSink << "argument " << parameter->getArgumentNumber() << " of call to " - << parameter->getIntermFunctionCall()->getName() << "\n"; -} - -void TDependencyGraphOutput::visitFunctionCall(TGraphFunctionCall* functionCall) -{ - outputIndentation(); - mSink << "function call " << functionCall->getIntermFunctionCall()->getName() << "\n"; -} - -void TDependencyGraphOutput::visitSymbol(TGraphSymbol* symbol) -{ - outputIndentation(); - mSink << symbol->getIntermSymbol()->getSymbol() << " (symbol id: " - << symbol->getIntermSymbol()->getId() << ")\n"; -} - -void TDependencyGraphOutput::visitSelection(TGraphSelection* selection) -{ - outputIndentation(); - mSink << "selection\n"; -} - -void TDependencyGraphOutput::visitLoop(TGraphLoop* loop) -{ - outputIndentation(); - mSink << "loop condition\n"; -} - -void TDependencyGraphOutput::visitLogicalOp(TGraphLogicalOp* logicalOp) -{ - outputIndentation(); - mSink << "logical " << logicalOp->getOpString() << "\n"; -} - -void TDependencyGraphOutput::outputAllSpanningTrees(TDependencyGraph& graph) -{ - mSink << "\n"; - - for (auto symbol : graph.allNodes()) - { - mSink << "--- Dependency graph spanning tree ---\n"; - clearVisited(); - symbol->traverse(this); - mSink << "\n"; - } -} diff --git a/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphOutput.h b/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphOutput.h deleted file mode 100644 index b201e0a671..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphOutput.h +++ /dev/null @@ -1,31 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPHOUTPUT_H_ -#define COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPHOUTPUT_H_ - -#include "compiler/translator/depgraph/DependencyGraph.h" -#include "compiler/translator/InfoSink.h" - -class TDependencyGraphOutput : public TDependencyGraphTraverser -{ - public: - TDependencyGraphOutput(TInfoSinkBase& sink) : mSink(sink) {} - void visitSymbol(TGraphSymbol* symbol) override; - void visitArgument(TGraphArgument* parameter) override; - void visitFunctionCall(TGraphFunctionCall* functionCall) override; - void visitSelection(TGraphSelection* selection) override; - void visitLoop(TGraphLoop* loop) override; - void visitLogicalOp(TGraphLogicalOp* logicalOp) override; - - void outputAllSpanningTrees(TDependencyGraph& graph); - private: - void outputIndentation(); - - TInfoSinkBase& mSink; -}; - -#endif // COMPILER_TRANSLATOR_DEPGRAPH_DEPENDENCYGRAPHOUTPUT_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphTraverse.cpp b/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphTraverse.cpp deleted file mode 100644 index 197fde97e2..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/depgraph/DependencyGraphTraverse.cpp +++ /dev/null @@ -1,69 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/translator/depgraph/DependencyGraph.h" - -// These methods do a breadth-first traversal through the graph and mark visited nodes. - -void TGraphNode::traverse(TDependencyGraphTraverser* graphTraverser) -{ - graphTraverser->markVisited(this); -} - -void TGraphParentNode::traverse(TDependencyGraphTraverser* graphTraverser) -{ - TGraphNode::traverse(graphTraverser); - - graphTraverser->incrementDepth(); - - // Visit the parent node's children. - for (TGraphNodeSet::const_iterator iter = mDependentNodes.begin(); - iter != mDependentNodes.end(); - ++iter) - { - TGraphNode* node = *iter; - if (!graphTraverser->isVisited(node)) - node->traverse(graphTraverser); - } - - graphTraverser->decrementDepth(); -} - -void TGraphArgument::traverse(TDependencyGraphTraverser* graphTraverser) -{ - graphTraverser->visitArgument(this); - TGraphParentNode::traverse(graphTraverser); -} - -void TGraphFunctionCall::traverse(TDependencyGraphTraverser* graphTraverser) -{ - graphTraverser->visitFunctionCall(this); - TGraphParentNode::traverse(graphTraverser); -} - -void TGraphSymbol::traverse(TDependencyGraphTraverser* graphTraverser) -{ - graphTraverser->visitSymbol(this); - TGraphParentNode::traverse(graphTraverser); -} - -void TGraphSelection::traverse(TDependencyGraphTraverser* graphTraverser) -{ - graphTraverser->visitSelection(this); - TGraphNode::traverse(graphTraverser); -} - -void TGraphLoop::traverse(TDependencyGraphTraverser* graphTraverser) -{ - graphTraverser->visitLoop(this); - TGraphNode::traverse(graphTraverser); -} - -void TGraphLogicalOp::traverse(TDependencyGraphTraverser* graphTraverser) -{ - graphTraverser->visitLogicalOp(this); - TGraphNode::traverse(graphTraverser); -} diff --git a/src/3rdparty/angle/src/compiler/translator/emulated_builtin_function_data_hlsl.json b/src/3rdparty/angle/src/compiler/translator/emulated_builtin_function_data_hlsl.json new file mode 100644 index 0000000000..32e500fe67 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/emulated_builtin_function_data_hlsl.json @@ -0,0 +1,1382 @@ +[ + { + "op":"mod", + "return_type":"float", + "args":[ + "float x", + "float y" + ], + "body":[ + "return x - y * floor(x / y);" + ] + }, + { + "op":"mod", + "return_type":"float2", + "args":[ + "float2 x", + "float2 y" + ], + "body":[ + "return x - y * floor(x / y);" + ] + }, + { + "op":"mod", + "return_type":"float2", + "args":[ + "float2 x", + "float y" + ], + "body":[ + "return x - y * floor(x / y);" + ] + }, + { + "op":"mod", + "return_type":"float3", + "args":[ + "float3 x", + "float3 y" + ], + "body":[ + "return x - y * floor(x / y);" + ] + }, + { + "op":"mod", + "return_type":"float3", + "args":[ + "float3 x", + "float y" + ], + "body":[ + "return x - y * floor(x / y);" + ] + }, + { + "op":"mod", + "return_type":"float4", + "args":[ + "float4 x", + "float4 y" + ], + "body":[ + "return x - y * floor(x / y);" + ] + }, + { + "op":"mod", + "return_type":"float4", + "args":[ + "float4 x", + "float y" + ], + "body":[ + "return x - y * floor(x / y);" + ] + }, + { + "op":"frexp", + "return_type":"float", + "args":[ + "float x", + "out int exp" + ], + "body":[ + "float fexp;", + "float mantissa = frexp(abs(x), fexp) * sign(x);", + "exp = int(fexp);", + "return mantissa;" + ] + }, + { + "op":"frexp", + "return_type":"float2", + "args":[ + "float2 x", + "out int2 exp" + ], + "body":[ + "float2 fexp;", + "float2 mantissa = frexp(abs(x), fexp) * sign(x);", + "exp = int2(fexp);", + "return mantissa;" + ] + }, + { + "op":"frexp", + "return_type":"float3", + "args":[ + "float3 x", + "out int3 exp" + ], + "body":[ + "float3 fexp;", + "float3 mantissa = frexp(abs(x), fexp) * sign(x);", + "exp = int3(fexp);", + "return mantissa;" + ] + }, + { + "op":"frexp", + "return_type":"float4", + "args":[ + "float4 x", + "out int4 exp" + ], + "body":[ + "float4 fexp;", + "float4 mantissa = frexp(abs(x), fexp) * sign(x);", + "exp = int4(fexp);", + "return mantissa;" + ] + }, + { + "op":"ldexp", + "return_type":"float", + "args":[ + "float x", + "int exp" + ], + "body":[ + "return ldexp(x, float(exp));" + ] + }, + { + "op":"ldexp", + "return_type":"float2", + "args":[ + "float2 x", + "int2 exp" + ], + "body":[ + "return ldexp(x, float2(exp));" + ] + }, + { + "op":"ldexp", + "return_type":"float3", + "args":[ + "float3 x", + "int3 exp" + ], + "body":[ + "return ldexp(x, float3(exp));" + ] + }, + { + "op":"ldexp", + "return_type":"float4", + "args":[ + "float4 x", + "int4 exp" + ], + "body":[ + "return ldexp(x, float4(exp));" + ] + }, + { + "op":"faceforward", + "return_type":"float", + "args":[ + "float N", + "float I", + "float Nref" + ], + "body":[ + "if(dot(Nref, I) >= 0)", + "{", + " return -N;", + "}", + "else", + "{", + " return N;", + "}" + ] + }, + { + "op":"faceforward", + "return_type":"float2", + "args":[ + "float2 N", + "float2 I", + "float2 Nref" + ], + "body":[ + "if(dot(Nref, I) >= 0)", + "{", + " return -N;", + "}", + "else", + "{", + " return N;", + "}" + ] + }, + { + "op":"faceforward", + "return_type":"float3", + "args":[ + "float3 N", + "float3 I", + "float3 Nref" + ], + "body":[ + "if(dot(Nref, I) >= 0)", + "{", + " return -N;", + "}", + "else", + "{", + " return N;", + "}" + ] + }, + { + "op":"faceforward", + "return_type":"float4", + "args":[ + "float4 N", + "float4 I", + "float4 Nref" + ], + "body":[ + "if(dot(Nref, I) >= 0)", + "{", + " return -N;", + "}", + "else", + "{", + " return N;", + "}" + ] + }, + { + "op":"atan", + "return_type":"float", + "args":[ + "float y", + "float x" + ], + "body":[ + "if(x == 0 && y == 0) x = 1;", + "return atan2(y, x);" + ] + }, + { + "op":"atan", + "return_type":"float2", + "args":[ + "float2 y", + "float2 x" + ], + "body":[ + "if(x[0] == 0 && y[0] == 0) x[0] = 1;", + "if(x[1] == 0 && y[1] == 0) x[1] = 1;", + "return float2(atan2(y[0], x[0]), atan2(y[1], x[1]));" + ] + }, + { + "op":"atan", + "return_type":"float3", + "args":[ + "float3 y", + "float3 x" + ], + "body":[ + "if(x[0] == 0 && y[0] == 0) x[0] = 1;", + "if(x[1] == 0 && y[1] == 0) x[1] = 1;", + "if(x[2] == 0 && y[2] == 0) x[2] = 1;", + "return float3(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], x[2]));" + ] + }, + { + "op":"atan", + "return_type":"float4", + "args":[ + "float4 y", + "float4 x" + ], + "body":[ + "if(x[0] == 0 && y[0] == 0) x[0] = 1;", + "if(x[1] == 0 && y[1] == 0) x[1] = 1;", + "if(x[2] == 0 && y[2] == 0) x[2] = 1;", + "if(x[3] == 0 && y[3] == 0) x[3] = 1;", + "return float4(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], ", + "x[2]), atan2(y[3], x[3]));" + ] + }, + { + "op":"asinh", + "return_type":"float", + "args":[ + "in float x" + ], + "body":[ + "return log(x + sqrt(pow(x, 2.0) + 1.0));" + ] + }, + { + "op":"asinh", + "return_type":"float2", + "args":[ + "in float2 x" + ], + "body":[ + "return log(x + sqrt(pow(x, 2.0) + 1.0));" + ] + }, + { + "op":"asinh", + "return_type":"float3", + "args":[ + "in float3 x" + ], + "body":[ + "return log(x + sqrt(pow(x, 2.0) + 1.0));" + ] + }, + { + "op":"asinh", + "return_type":"float4", + "args":[ + "in float4 x" + ], + "body":[ + "return log(x + sqrt(pow(x, 2.0) + 1.0));" + ] + }, + { + "op":"acosh", + "return_type":"float", + "args":[ + "in float x" + ], + "body":[ + "return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));" + ] + }, + { + "op":"acosh", + "return_type":"float2", + "args":[ + "in float2 x" + ], + "body":[ + "return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));" + ] + }, + { + "op":"acosh", + "return_type":"float3", + "args":[ + "in float3 x" + ], + "body":[ + "return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));" + ] + }, + { + "op":"acosh", + "return_type":"float4", + "args":[ + "in float4 x" + ], + "body":[ + "return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));" + ] + }, + { + "op":"atanh", + "return_type":"float", + "args":[ + "in float x" + ], + "body":[ + "return 0.5 * log((1.0 + x) / (1.0 - x));" + ] + }, + { + "op":"atanh", + "return_type":"float2", + "args":[ + "in float2 x" + ], + "body":[ + "return 0.5 * log((1.0 + x) / (1.0 - x));" + ] + }, + { + "op":"atanh", + "return_type":"float3", + "args":[ + "in float3 x" + ], + "body":[ + "return 0.5 * log((1.0 + x) / (1.0 - x));" + ] + }, + { + "op":"atanh", + "return_type":"float4", + "args":[ + "in float4 x" + ], + "body":[ + "return 0.5 * log((1.0 + x) / (1.0 - x));" + ] + }, + { + "op":"roundEven", + "return_type":"float", + "args":[ + "in float x" + ], + "body":[ + "return (frac(x) == 0.5 && trunc(x) % 2.0 == 0.0) ? trunc(x) : round(x);" + ] + }, + { + "op":"roundEven", + "return_type":"float2", + "args":[ + "in float2 x" + ], + "body":[ + "float2 v;", + "v[0] = (frac(x[0]) == 0.5 && trunc(x[0]) % 2.0 == 0.0) ? trunc(x[0]) : round(x[0]);", + "v[1] = (frac(x[1]) == 0.5 && trunc(x[1]) % 2.0 == 0.0) ? trunc(x[1]) : round(x[1]);", + "return v;" + ] + }, + { + "op":"roundEven", + "return_type":"float3", + "args":[ + "in float3 x" + ], + "body":[ + "float3 v;", + "v[0] = (frac(x[0]) == 0.5 && trunc(x[0]) % 2.0 == 0.0) ? trunc(x[0]) : round(x[0]);", + "v[1] = (frac(x[1]) == 0.5 && trunc(x[1]) % 2.0 == 0.0) ? trunc(x[1]) : round(x[1]);", + "v[2] = (frac(x[2]) == 0.5 && trunc(x[2]) % 2.0 == 0.0) ? trunc(x[2]) : round(x[2]);", + "return v;" + ] + }, + { + "op":"roundEven", + "return_type":"float4", + "args":[ + "in float4 x" + ], + "body":[ + "float4 v;", + "v[0] = (frac(x[0]) == 0.5 && trunc(x[0]) % 2.0 == 0.0) ? trunc(x[0]) : round(x[0]);", + "v[1] = (frac(x[1]) == 0.5 && trunc(x[1]) % 2.0 == 0.0) ? trunc(x[1]) : round(x[1]);", + "v[2] = (frac(x[2]) == 0.5 && trunc(x[2]) % 2.0 == 0.0) ? trunc(x[2]) : round(x[2]);", + "v[3] = (frac(x[3]) == 0.5 && trunc(x[3]) % 2.0 == 0.0) ? trunc(x[3]) : round(x[3]);", + "return v;" + ] + }, + { + "op":"packSnorm2x16", + "return_type":"uint", + "args":[ + "in float2 v" + ], + "helper":[ + "int webgl_toSnorm16(in float x) {", + " return int(round(clamp(x, -1.0, 1.0) * 32767.0));", + "}" + ], + "body":[ + "int x = webgl_toSnorm16(v.x);", + "int y = webgl_toSnorm16(v.y);", + "return (asuint(y) << 16) | (asuint(x) & 0xffffu);" + ] + }, + { + "op":"packUnorm2x16", + "return_type":"uint", + "args":[ + "in float2 v" + ], + "helper":[ + "uint webgl_toUnorm16(in float x) {", + " return uint(round(clamp(x, 0.0, 1.0) * 65535.0));", + "}" + ], + "body":[ + "uint x = webgl_toUnorm16(v.x);", + "uint y = webgl_toUnorm16(v.y);", + "return (y << 16) | x;" + ] + }, + { + "op":"packHalf2x16", + "return_type":"uint", + "args":[ + "in float2 v" + ], + "body":[ + "uint x = f32tof16(v.x);", + "uint y = f32tof16(v.y);", + "return (y << 16) | x;" + ] + }, + { + "op":"unpackSnorm2x16", + "return_type":"float2", + "args":[ + "in uint u" + ], + "helper":[ + "float webgl_fromSnorm16(in uint x) {", + " int xi = asint(x & 0x7fffu) - asint(x & 0x8000u);", + " return clamp(float(xi) / 32767.0, -1.0, 1.0);", + "}" + ], + "body":[ + "uint y = (u >> 16);", + "uint x = u;", + "return float2(webgl_fromSnorm16(x), webgl_fromSnorm16(y));" + ] + }, + { + "op":"unpackUnorm2x16", + "return_type":"float2", + "args":[ + "in uint u" + ], + "helper":[ + "float webgl_fromUnorm16(in uint x) {", + " return float(x) / 65535.0;", + "}" + ], + "body":[ + "uint y = (u >> 16);", + "uint x = u & 0xffffu;", + "return float2(webgl_fromUnorm16(x), webgl_fromUnorm16(y));" + ] + }, + { + "op":"unpackHalf2x16", + "return_type":"float2", + "args":[ + "in uint u" + ], + "body":[ + "uint y = (u >> 16);", + "uint x = u & 0xffffu;", + "return float2(f16tof32(x), f16tof32(y));" + ] + }, + { + "op":"packSnorm4x8", + "return_type":"uint", + "args":[ + "in float4 v" + ], + "helper":[ + "int webgl_toSnorm8(in float x) {", + " return int(round(clamp(x, -1.0, 1.0) * 127.0));", + "}" + ], + "body":[ + "int x = webgl_toSnorm8(v.x);", + "int y = webgl_toSnorm8(v.y);", + "int z = webgl_toSnorm8(v.z);", + "int w = webgl_toSnorm8(v.w);", + "return ((asuint(w) & 0xffu) << 24) | ((asuint(z) & 0xffu) << 16) ", + "| ((asuint(y) & 0xffu) << 8) | (asuint(x) & 0xffu);" + ] + }, + { + "op":"packUnorm4x8", + "return_type":"uint", + "args":[ + "in float4 v" + ], + "helper":[ + "uint webgl_toUnorm8(in float x) {", + " return uint(round(clamp(x, 0.0, 1.0) * 255.0));", + "}" + ], + "body":[ + "uint x = webgl_toUnorm8(v.x);", + "uint y = webgl_toUnorm8(v.y);", + "uint z = webgl_toUnorm8(v.z);", + "uint w = webgl_toUnorm8(v.w);", + "return (w << 24) | (z << 16) | (y << 8) | x;" + ] + }, + { + "op":"unpackSnorm4x8", + "return_type":"float4", + "args":[ + "in uint u" + ], + "helper":[ + "float webgl_fromSnorm8(in uint x) {", + " int xi = asint(x & 0x7fu) - asint(x & 0x80u);", + " return clamp(float(xi) / 127.0, -1.0, 1.0);", + "}" + ], + "body":[ + "uint w = (u >> 24);", + "uint z = (u >> 16);", + "uint y = (u >> 8);", + "uint x = u;", + "return float4(webgl_fromSnorm8(x), webgl_fromSnorm8(y), ", + "webgl_fromSnorm8(z), webgl_fromSnorm8(w));" + ] + }, + { + "op":"unpackUnorm4x8", + "return_type":"float4", + "args":[ + "in uint u" + ], + "helper":[ + "float webgl_fromUnorm8(in uint x) {", + " return float(x) / 255.0;", + "}" + ], + "body":[ + "uint w = (u >> 24) & 0xffu;", + "uint z = (u >> 16) & 0xffu;", + "uint y = (u >> 8) & 0xffu;", + "uint x = u & 0xffu;", + "return float4(webgl_fromUnorm8(x), webgl_fromUnorm8(y), ", + "webgl_fromUnorm8(z), webgl_fromUnorm8(w));" + ] + }, + { + "comment":[ + "The matrix resulting from outer product needs to be transposed", + "(matrices are stored as transposed to simplify element access in HLSL).", + "So the function should return transpose(c * r) where c is a column vector", + "and r is a row vector. This can be simplified by using the following", + "formula:", + "transpose(c * r) = transpose(r) * transpose(c)", + "transpose(r) and transpose(c) are in a sense free, since to get the", + "transpose of r, we simply can build a column matrix out of the original", + "vector instead of a row matrix." + ], + "op":"outerProduct", + "return_type":"float2x2", + "args":[ + "in float2 c", + "in float2 r" + ], + "body":[ + "return mul(float2x1(r), float1x2(c));" + ] + }, + { + "op":"outerProduct", + "return_type":"float3x3", + "args":[ + "in float3 c", + "in float3 r" + ], + "body":[ + "return mul(float3x1(r), float1x3(c));" + ] + }, + { + "op":"outerProduct", + "return_type":"float4x4", + "args":[ + "in float4 c", + "in float4 r" + ], + "body":[ + "return mul(float4x1(r), float1x4(c));" + ] + }, + { + "op":"outerProduct", + "return_type":"float2x3", + "args":[ + "in float3 c", + "in float2 r" + ], + "body":[ + "return mul(float2x1(r), float1x3(c));" + ] + }, + { + "op":"outerProduct", + "return_type":"float3x2", + "args":[ + "in float2 c", + "in float3 r" + ], + "body":[ + "return mul(float3x1(r), float1x2(c));" + ] + }, + { + "op":"outerProduct", + "return_type":"float2x4", + "args":[ + "in float4 c", + "in float2 r" + ], + "body":[ + "return mul(float2x1(r), float1x4(c));" + ] + }, + { + "op":"outerProduct", + "return_type":"float4x2", + "args":[ + "in float2 c", + "in float4 r" + ], + "body":[ + "return mul(float4x1(r), float1x2(c));" + ] + }, + { + "op":"outerProduct", + "return_type":"float3x4", + "args":[ + "in float4 c", + "in float3 r" + ], + "body":[ + "return mul(float3x1(r), float1x4(c));" + ] + }, + { + "op":"outerProduct", + "return_type":"float4x3", + "args":[ + "in float3 c", + "in float4 r" + ], + "body":[ + "return mul(float4x1(r), float1x3(c));" + ] + }, + { + "comment":[ + "Remember here that the parameter matrix is actually the transpose", + "of the matrix that we're trying to invert, and the resulting matrix", + "should also be the transpose of the inverse.", + "When accessing the parameter matrix with m[a][b] it can be thought of so", + "that a is the column and b is the row of the matrix that we're inverting.", + "We calculate the inverse as the adjugate matrix divided by the", + "determinant of the matrix being inverted. However, as the result needs", + "to be transposed, we actually use of the transpose of the adjugate matrix", + "which happens to be the cofactor matrix. That's stored in 'cof'.", + "We don't need to care about divide-by-zero since results are undefined", + "for singular or poorly-conditioned matrices." + ], + "op":"inverse", + "return_type":"float2x2", + "args":[ + "in float2x2 m" + ], + "body":[ + "float2x2 cof = { m[1][1], -m[0][1], -m[1][0], m[0][0] };", + "return cof / determinant(transpose(m));" + ] + }, + { + "comment":[ + "cofAB is the cofactor for column A and row B." + ], + "op":"inverse", + "return_type":"float3x3", + "args":[ + "in float3x3 m" + ], + "body":[ + "float cof00 = m[1][1] * m[2][2] - m[2][1] * m[1][2];", + "float cof01 = -(m[1][0] * m[2][2] - m[2][0] * m[1][2]);", + "float cof02 = m[1][0] * m[2][1] - m[2][0] * m[1][1];", + "float cof10 = -(m[0][1] * m[2][2] - m[2][1] * m[0][2]);", + "float cof11 = m[0][0] * m[2][2] - m[2][0] * m[0][2];", + "float cof12 = -(m[0][0] * m[2][1] - m[2][0] * m[0][1]);", + "float cof20 = m[0][1] * m[1][2] - m[1][1] * m[0][2];", + "float cof21 = -(m[0][0] * m[1][2] - m[1][0] * m[0][2]);", + "float cof22 = m[0][0] * m[1][1] - m[1][0] * m[0][1];", + "float3x3 cof = { cof00, cof10, cof20, cof01, cof11, cof21, cof02, cof12, cof22 };", + "return cof / determinant(transpose(m));" + ] + }, + { + "op":"inverse", + "return_type":"float4x4", + "args":[ + "in float4x4 m" + ], + "body":[ + "float cof00 = m[1][1] * m[2][2] * m[3][3] + m[2][1] * m[3][2] * m[1][3] + m[3][1] * ", + "m[1][2] * m[2][3]", + " - m[1][1] * m[3][2] * m[2][3] - m[2][1] * m[1][2] * m[3][3] - m[3][1] * m[2][2] * ", + "m[1][3];", + "float cof01 = -(m[1][0] * m[2][2] * m[3][3] + m[2][0] * m[3][2] * m[1][3] + m[3][0] * ", + "m[1][2] * m[2][3]", + " - m[1][0] * m[3][2] * m[2][3] - m[2][0] * m[1][2] * m[3][3] - m[3][0] * m[2][2] * ", + "m[1][3]);", + "float cof02 = m[1][0] * m[2][1] * m[3][3] + m[2][0] * m[3][1] * m[1][3] + m[3][0] * ", + "m[1][1] * m[2][3]", + " - m[1][0] * m[3][1] * m[2][3] - m[2][0] * m[1][1] * m[3][3] - m[3][0] * m[2][1] * ", + "m[1][3];", + "float cof03 = -(m[1][0] * m[2][1] * m[3][2] + m[2][0] * m[3][1] * m[1][2] + m[3][0] * ", + "m[1][1] * m[2][2]", + " - m[1][0] * m[3][1] * m[2][2] - m[2][0] * m[1][1] * m[3][2] - m[3][0] * m[2][1] * ", + "m[1][2]);", + "float cof10 = -(m[0][1] * m[2][2] * m[3][3] + m[2][1] * m[3][2] * m[0][3] + m[3][1] * ", + "m[0][2] * m[2][3]", + " - m[0][1] * m[3][2] * m[2][3] - m[2][1] * m[0][2] * m[3][3] - m[3][1] * m[2][2] * ", + "m[0][3]);", + "float cof11 = m[0][0] * m[2][2] * m[3][3] + m[2][0] * m[3][2] * m[0][3] + m[3][0] * ", + "m[0][2] * m[2][3]", + " - m[0][0] * m[3][2] * m[2][3] - m[2][0] * m[0][2] * m[3][3] - m[3][0] * m[2][2] * ", + "m[0][3];", + "float cof12 = -(m[0][0] * m[2][1] * m[3][3] + m[2][0] * m[3][1] * m[0][3] + m[3][0] * ", + "m[0][1] * m[2][3]", + " - m[0][0] * m[3][1] * m[2][3] - m[2][0] * m[0][1] * m[3][3] - m[3][0] * m[2][1] * ", + "m[0][3]);", + "float cof13 = m[0][0] * m[2][1] * m[3][2] + m[2][0] * m[3][1] * m[0][2] + m[3][0] * ", + "m[0][1] * m[2][2]", + " - m[0][0] * m[3][1] * m[2][2] - m[2][0] * m[0][1] * m[3][2] - m[3][0] * m[2][1] * ", + "m[0][2];", + "float cof20 = m[0][1] * m[1][2] * m[3][3] + m[1][1] * m[3][2] * m[0][3] + m[3][1] * ", + "m[0][2] * m[1][3]", + " - m[0][1] * m[3][2] * m[1][3] - m[1][1] * m[0][2] * m[3][3] - m[3][1] * m[1][2] * ", + "m[0][3];", + "float cof21 = -(m[0][0] * m[1][2] * m[3][3] + m[1][0] * m[3][2] * m[0][3] + m[3][0] * ", + "m[0][2] * m[1][3]", + " - m[0][0] * m[3][2] * m[1][3] - m[1][0] * m[0][2] * m[3][3] - m[3][0] * m[1][2] * ", + "m[0][3]);", + "float cof22 = m[0][0] * m[1][1] * m[3][3] + m[1][0] * m[3][1] * m[0][3] + m[3][0] * ", + "m[0][1] * m[1][3]", + " - m[0][0] * m[3][1] * m[1][3] - m[1][0] * m[0][1] * m[3][3] - m[3][0] * m[1][1] * ", + "m[0][3];", + "float cof23 = -(m[0][0] * m[1][1] * m[3][2] + m[1][0] * m[3][1] * m[0][2] + m[3][0] * ", + "m[0][1] * m[1][2]", + " - m[0][0] * m[3][1] * m[1][2] - m[1][0] * m[0][1] * m[3][2] - m[3][0] * m[1][1] * ", + "m[0][2]);", + "float cof30 = -(m[0][1] * m[1][2] * m[2][3] + m[1][1] * m[2][2] * m[0][3] + m[2][1] * ", + "m[0][2] * m[1][3]", + " - m[0][1] * m[2][2] * m[1][3] - m[1][1] * m[0][2] * m[2][3] - m[2][1] * m[1][2] * ", + "m[0][3]);", + "float cof31 = m[0][0] * m[1][2] * m[2][3] + m[1][0] * m[2][2] * m[0][3] + m[2][0] * ", + "m[0][2] * m[1][3]", + " - m[0][0] * m[2][2] * m[1][3] - m[1][0] * m[0][2] * m[2][3] - m[2][0] * m[1][2] * ", + "m[0][3];", + "float cof32 = -(m[0][0] * m[1][1] * m[2][3] + m[1][0] * m[2][1] * m[0][3] + m[2][0] * ", + "m[0][1] * m[1][3]", + " - m[0][0] * m[2][1] * m[1][3] - m[1][0] * m[0][1] * m[2][3] - m[2][0] * m[1][1] * ", + "m[0][3]);", + "float cof33 = m[0][0] * m[1][1] * m[2][2] + m[1][0] * m[2][1] * m[0][2] + m[2][0] * ", + "m[0][1] * m[1][2]", + " - m[0][0] * m[2][1] * m[1][2] - m[1][0] * m[0][1] * m[2][2] - m[2][0] * m[1][1] * ", + "m[0][2];", + "float4x4 cof = { cof00, cof10, cof20, cof30, cof01, cof11, cof21, cof31,", + " cof02, cof12, cof22, cof32, cof03, cof13, cof23, cof33 };", + "return cof / determinant(transpose(m));" + ] + }, + { + "comment":[ + "Emulate ESSL3 variant of mix that takes last argument as boolean vector.", + "genType mix(genType x, genType y, genBType a): Selects which vector each returned component", + "comes from. For a component of 'a' that is false, the corresponding component of 'x' is", + "returned. For a component of 'a' that is true, the corresponding component of 'y' is returned." + ], + "op":"mix", + "return_type":"float", + "args":[ + "float x", + "float y", + "bool a" + ], + "body":[ + "return a ? y : x;" + ] + }, + { + "op":"mix", + "return_type":"float2", + "args":[ + "float2 x", + "float2 y", + "bool2 a" + ], + "body":[ + "return a ? y : x;" + ] + }, + { + "op":"mix", + "return_type":"float3", + "args":[ + "float3 x", + "float3 y", + "bool3 a" + ], + "body":[ + "return a ? y : x;" + ] + }, + { + "op":"mix", + "return_type":"float4", + "args":[ + "float4 x", + "float4 y", + "bool4 a" + ], + "body":[ + "return a ? y : x;" + ] + }, + { + "op":"bitfieldExtract", + "return_type":"uint", + "args":[ + "uint value", + "int offset", + "int bits" + ], + "body":[ + "if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)", + "{", + " return 0u;", + "}", + "uint maskMsb = (1u << (bits - 1));", + "uint mask = ((maskMsb - 1u) | maskMsb) << offset;", + "return (value & mask) >> offset;" + ] + }, + { + "op":"bitfieldExtract", + "return_type":"uint2", + "args":[ + "uint2 value", + "int offset", + "int bits" + ], + "body":[ + "if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)", + "{", + " return uint2(0u, 0u);", + "}", + "uint maskMsb = (1u << (bits - 1));", + "uint mask = ((maskMsb - 1u) | maskMsb) << offset;", + "return (value & mask) >> offset;" + ] + }, + { + "op":"bitfieldExtract", + "return_type":"uint3", + "args":[ + "uint3 value", + "int offset", + "int bits" + ], + "body":[ + "if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)", + "{", + " return uint3(0u, 0u, 0u);", + "}", + "uint maskMsb = (1u << (bits - 1));", + "uint mask = ((maskMsb - 1u) | maskMsb) << offset;", + "return (value & mask) >> offset;" + ] + }, + { + "op":"bitfieldExtract", + "return_type":"uint4", + "args":[ + "uint4 value", + "int offset", + "int bits" + ], + "body":[ + "if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)", + "{", + " return uint4(0u, 0u, 0u, 0u);", + "}", + "uint maskMsb = (1u << (bits - 1));", + "uint mask = ((maskMsb - 1u) | maskMsb) << offset;", + "return (value & mask) >> offset;" + ] + }, + { + "op":"bitfieldExtract", + "return_type":"int", + "args":[ + "int value", + "int offset", + "int bits" + ], + "body":[ + "if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)", + "{", + " return 0;", + "}", + "uint maskMsb = (1u << (bits - 1));", + "uint mask = ((maskMsb - 1u) | maskMsb) << offset;", + "uint resultUnsigned = (asuint(value) & mask) >> offset;", + "if (bits != 32 && (resultUnsigned & maskMsb) != 0)", + "{", + " uint higherBitsMask = ((1u << (32 - bits)) - 1u) << bits;", + " resultUnsigned |= higherBitsMask;", + "}", + "return asint(resultUnsigned);" + ] + }, + { + "op":"bitfieldExtract", + "return_type":"int2", + "args":[ + "int2 value", + "int offset", + "int bits" + ], + "body":[ + "if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)", + "{", + " return int2(0, 0);", + "}", + "uint maskMsb = (1u << (bits - 1));", + "uint mask = ((maskMsb - 1u) | maskMsb) << offset;", + "uint2 resultUnsigned = (asuint(value) & mask) >> offset;", + "if (bits != 32)", + "{", + " uint higherBitsMask = ((1u << (32 - bits)) - 1u) << bits;", + " resultUnsigned |= ((resultUnsigned & maskMsb) >> (bits - 1)) * higherBitsMask;", + "}", + "return asint(resultUnsigned);" + ] + }, + { + "op":"bitfieldExtract", + "return_type":"int3", + "args":[ + "int3 value", + "int offset", + "int bits" + ], + "body":[ + "if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)", + "{", + " return int3(0, 0, 0);", + "}", + "uint maskMsb = (1u << (bits - 1));", + "uint mask = ((maskMsb - 1u) | maskMsb) << offset;", + "uint3 resultUnsigned = (asuint(value) & mask) >> offset;", + "if (bits != 32)", + "{", + " uint higherBitsMask = ((1u << (32 - bits)) - 1u) << bits;", + " resultUnsigned |= ((resultUnsigned & maskMsb) >> (bits - 1)) * higherBitsMask;", + "}", + "return asint(resultUnsigned);" + ] + }, + { + "op":"bitfieldExtract", + "return_type":"int4", + "args":[ + "int4 value", + "int offset", + "int bits" + ], + "body":[ + "if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)", + "{", + " return int4(0, 0, 0, 0);", + "}", + "uint maskMsb = (1u << (bits - 1));", + "uint mask = ((maskMsb - 1u) | maskMsb) << offset;", + "uint4 resultUnsigned = (asuint(value) & mask) >> offset;", + "if (bits != 32)", + "{", + " uint higherBitsMask = ((1u << (32 - bits)) - 1u) << bits;", + " resultUnsigned |= ((resultUnsigned & maskMsb) >> (bits - 1)) * higherBitsMask;", + "}", + "return asint(resultUnsigned);" + ] + }, + { + "op":"bitfieldInsert", + "return_type":"uint", + "args":[ + "uint base", + "uint insert", + "int offset", + "int bits" + ], + "body":[ + "if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)", + "{", + " return base;", + "}", + "uint maskMsb = (1u << (bits - 1));", + "uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;", + "uint baseMask = ~insertMask;", + "return (base & baseMask) | ((insert << offset) & insertMask);" + ] + }, + { + "op":"bitfieldInsert", + "return_type":"uint2", + "args":[ + "uint2 base", + "uint2 insert", + "int offset", + "int bits" + ], + "body":[ + "if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)", + "{", + " return base;", + "}", + "uint maskMsb = (1u << (bits - 1));", + "uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;", + "uint baseMask = ~insertMask;", + "return (base & baseMask) | ((insert << offset) & insertMask);" + ] + }, + { + "op":"bitfieldInsert", + "return_type":"uint3", + "args":[ + "uint3 base", + "uint3 insert", + "int offset", + "int bits" + ], + "body":[ + "if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)", + "{", + " return base;", + "}", + "uint maskMsb = (1u << (bits - 1));", + "uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;", + "uint baseMask = ~insertMask;", + "return (base & baseMask) | ((insert << offset) & insertMask);" + ] + }, + { + "op":"bitfieldInsert", + "return_type":"uint4", + "args":[ + "uint4 base", + "uint4 insert", + "int offset", + "int bits" + ], + "body":[ + "if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)", + "{", + " return base;", + "}", + "uint maskMsb = (1u << (bits - 1));", + "uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;", + "uint baseMask = ~insertMask;", + "return (base & baseMask) | ((insert << offset) & insertMask);" + ] + }, + { + "op":"bitfieldInsert", + "return_type":"int", + "args":[ + "int base", + "int insert", + "int offset", + "int bits" + ], + "body":[ + "if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)", + "{", + " return base;", + "}", + "uint maskMsb = (1u << (bits - 1));", + "uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;", + "uint baseMask = ~insertMask;", + "uint resultUnsigned = (asuint(base) & baseMask) | ((asuint(insert) << offset) & ", + " insertMask);", + "return asint(resultUnsigned);" + ] + }, + { + "op":"bitfieldInsert", + "return_type":"int2", + "args":[ + "int2 base", + "int2 insert", + "int offset", + "int bits" + ], + "body":[ + "if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)", + "{", + " return base;", + "}", + "uint maskMsb = (1u << (bits - 1));", + "uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;", + "uint baseMask = ~insertMask;", + "uint2 resultUnsigned = (asuint(base) & baseMask) | ((asuint(insert) << offset) & ", + " insertMask);", + "return asint(resultUnsigned);" + ] + }, + { + "op":"bitfieldInsert", + "return_type":"int3", + "args":[ + "int3 base", + "int3 insert", + "int offset", + "int bits" + ], + "body":[ + "if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)", + "{", + " return base;", + "}", + "uint maskMsb = (1u << (bits - 1));", + "uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;", + "uint baseMask = ~insertMask;", + "uint3 resultUnsigned = (asuint(base) & baseMask) | ((asuint(insert) << offset) & ", + " insertMask);", + "return asint(resultUnsigned);" + ] + }, + { + "op":"bitfieldInsert", + "return_type":"int4", + "args":[ + "int4 base", + "int4 insert", + "int offset", + "int bits" + ], + "body":[ + "if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)", + "{", + " return base;", + "}", + "uint maskMsb = (1u << (bits - 1));", + "uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;", + "uint baseMask = ~insertMask;", + "uint4 resultUnsigned = (asuint(base) & baseMask) | ((asuint(insert) << offset) & ", + "insertMask);", + "return asint(resultUnsigned);" + ] + }, + { + "op":"uaddCarry", + "return_type":"uint", + "args":[ + "uint x", + "uint y", + "out uint carry" + ], + "body":[ + "carry = uint(x > (0xffffffffu - y));", + "return x + y;" + ] + }, + { + "op":"uaddCarry", + "return_type":"uint2", + "args":[ + "uint2 x", + "uint2 y", + "out uint2 carry" + ], + "body":[ + "carry = uint2(x > (0xffffffffu - y));", + "return x + y;" + ] + }, + { + "op":"uaddCarry", + "return_type":"uint3", + "args":[ + "uint3 x", + "uint3 y", + "out uint3 carry" + ], + "body":[ + "carry = uint3(x > (0xffffffffu - y));", + "return x + y;" + ] + }, + { + "op":"uaddCarry", + "return_type":"uint4", + "args":[ + "uint4 x", + "uint4 y", + "out uint4 carry" + ], + "body":[ + "carry = uint4(x > (0xffffffffu - y));", + "return x + y;" + ] + }, + { + "op":"usubBorrow", + "return_type":"uint", + "args":[ + "uint x", + "uint y", + "out uint borrow" + ], + "body":[ + "borrow = uint(x < y);", + "return x - y;" + ] + }, + { + "op":"usubBorrow", + "return_type":"uint2", + "args":[ + "uint2 x", + "uint2 y", + "out uint2 borrow" + ], + "body":[ + "borrow = uint2(x < y);", + "return x - y;" + ] + }, + { + "op":"usubBorrow", + "return_type":"uint3", + "args":[ + "uint3 x", + "uint3 y", + "out uint3 borrow" + ], + "body":[ + "borrow = uint3(x < y);", + "return x - y;" + ] + }, + { + "op":"usubBorrow", + "return_type":"uint4", + "args":[ + "uint4 x", + "uint4 y", + "out uint4 borrow" + ], + "body":[ + "borrow = uint4(x < y);", + "return x - y;" + ] + } +] diff --git a/src/3rdparty/angle/src/compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp b/src/3rdparty/angle/src/compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp new file mode 100644 index 0000000000..288da5e0f5 --- /dev/null +++ b/src/3rdparty/angle/src/compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp @@ -0,0 +1,859 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_emulated_builtin_function_tables.py using data from +// emulated_builtin_function_data_hlsl.json. +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// emulated_builtin_functions_hlsl: +// HLSL code for emulating GLSL builtin functions not present in HLSL. + +#include "compiler/translator/BuiltInFunctionEmulator.h" + +namespace sh +{ + +namespace +{ + +struct FunctionPair +{ + constexpr FunctionPair(const MiniFunctionId &idIn, const char *bodyIn) : id(idIn), body(bodyIn) + { + } + + MiniFunctionId id; + const char *body; +}; + +constexpr FunctionPair g_hlslFunctions[] = { + {{EOpMod, ParamType::Float1, ParamType::Float1}, + "float mod_emu(float x, float y)\n" + "{\n" + " return x - y * floor(x / y);\n" + "}\n"}, + {{EOpMod, ParamType::Float2, ParamType::Float2}, + "float2 mod_emu(float2 x, float2 y)\n" + "{\n" + " return x - y * floor(x / y);\n" + "}\n"}, + {{EOpMod, ParamType::Float2, ParamType::Float1}, + "float2 mod_emu(float2 x, float y)\n" + "{\n" + " return x - y * floor(x / y);\n" + "}\n"}, + {{EOpMod, ParamType::Float3, ParamType::Float3}, + "float3 mod_emu(float3 x, float3 y)\n" + "{\n" + " return x - y * floor(x / y);\n" + "}\n"}, + {{EOpMod, ParamType::Float3, ParamType::Float1}, + "float3 mod_emu(float3 x, float y)\n" + "{\n" + " return x - y * floor(x / y);\n" + "}\n"}, + {{EOpMod, ParamType::Float4, ParamType::Float4}, + "float4 mod_emu(float4 x, float4 y)\n" + "{\n" + " return x - y * floor(x / y);\n" + "}\n"}, + {{EOpMod, ParamType::Float4, ParamType::Float1}, + "float4 mod_emu(float4 x, float y)\n" + "{\n" + " return x - y * floor(x / y);\n" + "}\n"}, + {{EOpFrexp, ParamType::Float1, ParamType::Int1}, + "float frexp_emu(float x, out int exp)\n" + "{\n" + " float fexp;\n" + " float mantissa = frexp(abs(x), fexp) * sign(x);\n" + " exp = int(fexp);\n" + " return mantissa;\n" + "}\n"}, + {{EOpFrexp, ParamType::Float2, ParamType::Int2}, + "float2 frexp_emu(float2 x, out int2 exp)\n" + "{\n" + " float2 fexp;\n" + " float2 mantissa = frexp(abs(x), fexp) * sign(x);\n" + " exp = int2(fexp);\n" + " return mantissa;\n" + "}\n"}, + {{EOpFrexp, ParamType::Float3, ParamType::Int3}, + "float3 frexp_emu(float3 x, out int3 exp)\n" + "{\n" + " float3 fexp;\n" + " float3 mantissa = frexp(abs(x), fexp) * sign(x);\n" + " exp = int3(fexp);\n" + " return mantissa;\n" + "}\n"}, + {{EOpFrexp, ParamType::Float4, ParamType::Int4}, + "float4 frexp_emu(float4 x, out int4 exp)\n" + "{\n" + " float4 fexp;\n" + " float4 mantissa = frexp(abs(x), fexp) * sign(x);\n" + " exp = int4(fexp);\n" + " return mantissa;\n" + "}\n"}, + {{EOpLdexp, ParamType::Float1, ParamType::Int1}, + "float ldexp_emu(float x, int exp)\n" + "{\n" + " return ldexp(x, float(exp));\n" + "}\n"}, + {{EOpLdexp, ParamType::Float2, ParamType::Int2}, + "float2 ldexp_emu(float2 x, int2 exp)\n" + "{\n" + " return ldexp(x, float2(exp));\n" + "}\n"}, + {{EOpLdexp, ParamType::Float3, ParamType::Int3}, + "float3 ldexp_emu(float3 x, int3 exp)\n" + "{\n" + " return ldexp(x, float3(exp));\n" + "}\n"}, + {{EOpLdexp, ParamType::Float4, ParamType::Int4}, + "float4 ldexp_emu(float4 x, int4 exp)\n" + "{\n" + " return ldexp(x, float4(exp));\n" + "}\n"}, + {{EOpFaceforward, ParamType::Float1, ParamType::Float1, ParamType::Float1}, + "float faceforward_emu(float N, float I, float Nref)\n" + "{\n" + " if(dot(Nref, I) >= 0)\n" + " {\n" + " return -N;\n" + " }\n" + " else\n" + " {\n" + " return N;\n" + " }\n" + "}\n"}, + {{EOpFaceforward, ParamType::Float2, ParamType::Float2, ParamType::Float2}, + "float2 faceforward_emu(float2 N, float2 I, float2 Nref)\n" + "{\n" + " if(dot(Nref, I) >= 0)\n" + " {\n" + " return -N;\n" + " }\n" + " else\n" + " {\n" + " return N;\n" + " }\n" + "}\n"}, + {{EOpFaceforward, ParamType::Float3, ParamType::Float3, ParamType::Float3}, + "float3 faceforward_emu(float3 N, float3 I, float3 Nref)\n" + "{\n" + " if(dot(Nref, I) >= 0)\n" + " {\n" + " return -N;\n" + " }\n" + " else\n" + " {\n" + " return N;\n" + " }\n" + "}\n"}, + {{EOpFaceforward, ParamType::Float4, ParamType::Float4, ParamType::Float4}, + "float4 faceforward_emu(float4 N, float4 I, float4 Nref)\n" + "{\n" + " if(dot(Nref, I) >= 0)\n" + " {\n" + " return -N;\n" + " }\n" + " else\n" + " {\n" + " return N;\n" + " }\n" + "}\n"}, + {{EOpAtan, ParamType::Float1, ParamType::Float1}, + "float atan_emu(float y, float x)\n" + "{\n" + " if(x == 0 && y == 0) x = 1;\n" + " return atan2(y, x);\n" + "}\n"}, + {{EOpAtan, ParamType::Float2, ParamType::Float2}, + "float2 atan_emu(float2 y, float2 x)\n" + "{\n" + " if(x[0] == 0 && y[0] == 0) x[0] = 1;\n" + " if(x[1] == 0 && y[1] == 0) x[1] = 1;\n" + " return float2(atan2(y[0], x[0]), atan2(y[1], x[1]));\n" + "}\n"}, + {{EOpAtan, ParamType::Float3, ParamType::Float3}, + "float3 atan_emu(float3 y, float3 x)\n" + "{\n" + " if(x[0] == 0 && y[0] == 0) x[0] = 1;\n" + " if(x[1] == 0 && y[1] == 0) x[1] = 1;\n" + " if(x[2] == 0 && y[2] == 0) x[2] = 1;\n" + " return float3(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], x[2]));\n" + "}\n"}, + {{EOpAtan, ParamType::Float4, ParamType::Float4}, + "float4 atan_emu(float4 y, float4 x)\n" + "{\n" + " if(x[0] == 0 && y[0] == 0) x[0] = 1;\n" + " if(x[1] == 0 && y[1] == 0) x[1] = 1;\n" + " if(x[2] == 0 && y[2] == 0) x[2] = 1;\n" + " if(x[3] == 0 && y[3] == 0) x[3] = 1;\n" + " return float4(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], \n" + " x[2]), atan2(y[3], x[3]));\n" + "}\n"}, + {{EOpAsinh, ParamType::Float1}, + "float asinh_emu(in float x)\n" + "{\n" + " return log(x + sqrt(pow(x, 2.0) + 1.0));\n" + "}\n"}, + {{EOpAsinh, ParamType::Float2}, + "float2 asinh_emu(in float2 x)\n" + "{\n" + " return log(x + sqrt(pow(x, 2.0) + 1.0));\n" + "}\n"}, + {{EOpAsinh, ParamType::Float3}, + "float3 asinh_emu(in float3 x)\n" + "{\n" + " return log(x + sqrt(pow(x, 2.0) + 1.0));\n" + "}\n"}, + {{EOpAsinh, ParamType::Float4}, + "float4 asinh_emu(in float4 x)\n" + "{\n" + " return log(x + sqrt(pow(x, 2.0) + 1.0));\n" + "}\n"}, + {{EOpAcosh, ParamType::Float1}, + "float acosh_emu(in float x)\n" + "{\n" + " return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n" + "}\n"}, + {{EOpAcosh, ParamType::Float2}, + "float2 acosh_emu(in float2 x)\n" + "{\n" + " return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n" + "}\n"}, + {{EOpAcosh, ParamType::Float3}, + "float3 acosh_emu(in float3 x)\n" + "{\n" + " return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n" + "}\n"}, + {{EOpAcosh, ParamType::Float4}, + "float4 acosh_emu(in float4 x)\n" + "{\n" + " return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n" + "}\n"}, + {{EOpAtanh, ParamType::Float1}, + "float atanh_emu(in float x)\n" + "{\n" + " return 0.5 * log((1.0 + x) / (1.0 - x));\n" + "}\n"}, + {{EOpAtanh, ParamType::Float2}, + "float2 atanh_emu(in float2 x)\n" + "{\n" + " return 0.5 * log((1.0 + x) / (1.0 - x));\n" + "}\n"}, + {{EOpAtanh, ParamType::Float3}, + "float3 atanh_emu(in float3 x)\n" + "{\n" + " return 0.5 * log((1.0 + x) / (1.0 - x));\n" + "}\n"}, + {{EOpAtanh, ParamType::Float4}, + "float4 atanh_emu(in float4 x)\n" + "{\n" + " return 0.5 * log((1.0 + x) / (1.0 - x));\n" + "}\n"}, + {{EOpRoundEven, ParamType::Float1}, + "float roundEven_emu(in float x)\n" + "{\n" + " return (frac(x) == 0.5 && trunc(x) % 2.0 == 0.0) ? trunc(x) : round(x);\n" + "}\n"}, + {{EOpRoundEven, ParamType::Float2}, + "float2 roundEven_emu(in float2 x)\n" + "{\n" + " float2 v;\n" + " v[0] = (frac(x[0]) == 0.5 && trunc(x[0]) % 2.0 == 0.0) ? trunc(x[0]) : round(x[0]);\n" + " v[1] = (frac(x[1]) == 0.5 && trunc(x[1]) % 2.0 == 0.0) ? trunc(x[1]) : round(x[1]);\n" + " return v;\n" + "}\n"}, + {{EOpRoundEven, ParamType::Float3}, + "float3 roundEven_emu(in float3 x)\n" + "{\n" + " float3 v;\n" + " v[0] = (frac(x[0]) == 0.5 && trunc(x[0]) % 2.0 == 0.0) ? trunc(x[0]) : round(x[0]);\n" + " v[1] = (frac(x[1]) == 0.5 && trunc(x[1]) % 2.0 == 0.0) ? trunc(x[1]) : round(x[1]);\n" + " v[2] = (frac(x[2]) == 0.5 && trunc(x[2]) % 2.0 == 0.0) ? trunc(x[2]) : round(x[2]);\n" + " return v;\n" + "}\n"}, + {{EOpRoundEven, ParamType::Float4}, + "float4 roundEven_emu(in float4 x)\n" + "{\n" + " float4 v;\n" + " v[0] = (frac(x[0]) == 0.5 && trunc(x[0]) % 2.0 == 0.0) ? trunc(x[0]) : round(x[0]);\n" + " v[1] = (frac(x[1]) == 0.5 && trunc(x[1]) % 2.0 == 0.0) ? trunc(x[1]) : round(x[1]);\n" + " v[2] = (frac(x[2]) == 0.5 && trunc(x[2]) % 2.0 == 0.0) ? trunc(x[2]) : round(x[2]);\n" + " v[3] = (frac(x[3]) == 0.5 && trunc(x[3]) % 2.0 == 0.0) ? trunc(x[3]) : round(x[3]);\n" + " return v;\n" + "}\n"}, + {{EOpPackSnorm2x16, ParamType::Float2}, + "int webgl_toSnorm16(in float x) {\n" + " return int(round(clamp(x, -1.0, 1.0) * 32767.0));\n" + "}\n" + "uint packSnorm2x16_emu(in float2 v)\n" + "{\n" + " int x = webgl_toSnorm16(v.x);\n" + " int y = webgl_toSnorm16(v.y);\n" + " return (asuint(y) << 16) | (asuint(x) & 0xffffu);\n" + "}\n"}, + {{EOpPackUnorm2x16, ParamType::Float2}, + "uint webgl_toUnorm16(in float x) {\n" + " return uint(round(clamp(x, 0.0, 1.0) * 65535.0));\n" + "}\n" + "uint packUnorm2x16_emu(in float2 v)\n" + "{\n" + " uint x = webgl_toUnorm16(v.x);\n" + " uint y = webgl_toUnorm16(v.y);\n" + " return (y << 16) | x;\n" + "}\n"}, + {{EOpPackHalf2x16, ParamType::Float2}, + "uint packHalf2x16_emu(in float2 v)\n" + "{\n" + " uint x = f32tof16(v.x);\n" + " uint y = f32tof16(v.y);\n" + " return (y << 16) | x;\n" + "}\n"}, + {{EOpUnpackSnorm2x16, ParamType::Uint1}, + "float webgl_fromSnorm16(in uint x) {\n" + " int xi = asint(x & 0x7fffu) - asint(x & 0x8000u);\n" + " return clamp(float(xi) / 32767.0, -1.0, 1.0);\n" + "}\n" + "float2 unpackSnorm2x16_emu(in uint u)\n" + "{\n" + " uint y = (u >> 16);\n" + " uint x = u;\n" + " return float2(webgl_fromSnorm16(x), webgl_fromSnorm16(y));\n" + "}\n"}, + {{EOpUnpackUnorm2x16, ParamType::Uint1}, + "float webgl_fromUnorm16(in uint x) {\n" + " return float(x) / 65535.0;\n" + "}\n" + "float2 unpackUnorm2x16_emu(in uint u)\n" + "{\n" + " uint y = (u >> 16);\n" + " uint x = u & 0xffffu;\n" + " return float2(webgl_fromUnorm16(x), webgl_fromUnorm16(y));\n" + "}\n"}, + {{EOpUnpackHalf2x16, ParamType::Uint1}, + "float2 unpackHalf2x16_emu(in uint u)\n" + "{\n" + " uint y = (u >> 16);\n" + " uint x = u & 0xffffu;\n" + " return float2(f16tof32(x), f16tof32(y));\n" + "}\n"}, + {{EOpPackSnorm4x8, ParamType::Float4}, + "int webgl_toSnorm8(in float x) {\n" + " return int(round(clamp(x, -1.0, 1.0) * 127.0));\n" + "}\n" + "uint packSnorm4x8_emu(in float4 v)\n" + "{\n" + " int x = webgl_toSnorm8(v.x);\n" + " int y = webgl_toSnorm8(v.y);\n" + " int z = webgl_toSnorm8(v.z);\n" + " int w = webgl_toSnorm8(v.w);\n" + " return ((asuint(w) & 0xffu) << 24) | ((asuint(z) & 0xffu) << 16) \n" + " | ((asuint(y) & 0xffu) << 8) | (asuint(x) & 0xffu);\n" + "}\n"}, + {{EOpPackUnorm4x8, ParamType::Float4}, + "uint webgl_toUnorm8(in float x) {\n" + " return uint(round(clamp(x, 0.0, 1.0) * 255.0));\n" + "}\n" + "uint packUnorm4x8_emu(in float4 v)\n" + "{\n" + " uint x = webgl_toUnorm8(v.x);\n" + " uint y = webgl_toUnorm8(v.y);\n" + " uint z = webgl_toUnorm8(v.z);\n" + " uint w = webgl_toUnorm8(v.w);\n" + " return (w << 24) | (z << 16) | (y << 8) | x;\n" + "}\n"}, + {{EOpUnpackSnorm4x8, ParamType::Uint1}, + "float webgl_fromSnorm8(in uint x) {\n" + " int xi = asint(x & 0x7fu) - asint(x & 0x80u);\n" + " return clamp(float(xi) / 127.0, -1.0, 1.0);\n" + "}\n" + "float4 unpackSnorm4x8_emu(in uint u)\n" + "{\n" + " uint w = (u >> 24);\n" + " uint z = (u >> 16);\n" + " uint y = (u >> 8);\n" + " uint x = u;\n" + " return float4(webgl_fromSnorm8(x), webgl_fromSnorm8(y), \n" + " webgl_fromSnorm8(z), webgl_fromSnorm8(w));\n" + "}\n"}, + {{EOpUnpackUnorm4x8, ParamType::Uint1}, + "float webgl_fromUnorm8(in uint x) {\n" + " return float(x) / 255.0;\n" + "}\n" + "float4 unpackUnorm4x8_emu(in uint u)\n" + "{\n" + " uint w = (u >> 24) & 0xffu;\n" + " uint z = (u >> 16) & 0xffu;\n" + " uint y = (u >> 8) & 0xffu;\n" + " uint x = u & 0xffu;\n" + " return float4(webgl_fromUnorm8(x), webgl_fromUnorm8(y), \n" + " webgl_fromUnorm8(z), webgl_fromUnorm8(w));\n" + "}\n"}, + // The matrix resulting from outer product needs to be transposed + // (matrices are stored as transposed to simplify element access in HLSL). + // So the function should return transpose(c * r) where c is a column vector + // and r is a row vector. This can be simplified by using the following + // formula: + // transpose(c * r) = transpose(r) * transpose(c) + // transpose(r) and transpose(c) are in a sense free, since to get the + // transpose of r, we simply can build a column matrix out of the original + // vector instead of a row matrix. + {{EOpOuterProduct, ParamType::Float2, ParamType::Float2}, + "float2x2 outerProduct_emu(in float2 c, in float2 r)\n" + "{\n" + " return mul(float2x1(r), float1x2(c));\n" + "}\n"}, + {{EOpOuterProduct, ParamType::Float3, ParamType::Float3}, + "float3x3 outerProduct_emu(in float3 c, in float3 r)\n" + "{\n" + " return mul(float3x1(r), float1x3(c));\n" + "}\n"}, + {{EOpOuterProduct, ParamType::Float4, ParamType::Float4}, + "float4x4 outerProduct_emu(in float4 c, in float4 r)\n" + "{\n" + " return mul(float4x1(r), float1x4(c));\n" + "}\n"}, + {{EOpOuterProduct, ParamType::Float3, ParamType::Float2}, + "float2x3 outerProduct_emu(in float3 c, in float2 r)\n" + "{\n" + " return mul(float2x1(r), float1x3(c));\n" + "}\n"}, + {{EOpOuterProduct, ParamType::Float2, ParamType::Float3}, + "float3x2 outerProduct_emu(in float2 c, in float3 r)\n" + "{\n" + " return mul(float3x1(r), float1x2(c));\n" + "}\n"}, + {{EOpOuterProduct, ParamType::Float4, ParamType::Float2}, + "float2x4 outerProduct_emu(in float4 c, in float2 r)\n" + "{\n" + " return mul(float2x1(r), float1x4(c));\n" + "}\n"}, + {{EOpOuterProduct, ParamType::Float2, ParamType::Float4}, + "float4x2 outerProduct_emu(in float2 c, in float4 r)\n" + "{\n" + " return mul(float4x1(r), float1x2(c));\n" + "}\n"}, + {{EOpOuterProduct, ParamType::Float4, ParamType::Float3}, + "float3x4 outerProduct_emu(in float4 c, in float3 r)\n" + "{\n" + " return mul(float3x1(r), float1x4(c));\n" + "}\n"}, + {{EOpOuterProduct, ParamType::Float3, ParamType::Float4}, + "float4x3 outerProduct_emu(in float3 c, in float4 r)\n" + "{\n" + " return mul(float4x1(r), float1x3(c));\n" + "}\n"}, + // Remember here that the parameter matrix is actually the transpose + // of the matrix that we're trying to invert, and the resulting matrix + // should also be the transpose of the inverse. + // When accessing the parameter matrix with m[a][b] it can be thought of so + // that a is the column and b is the row of the matrix that we're inverting. + // We calculate the inverse as the adjugate matrix divided by the + // determinant of the matrix being inverted. However, as the result needs + // to be transposed, we actually use of the transpose of the adjugate matrix + // which happens to be the cofactor matrix. That's stored in 'cof'. + // We don't need to care about divide-by-zero since results are undefined + // for singular or poorly-conditioned matrices. + {{EOpInverse, ParamType::Mat2}, + "float2x2 inverse_emu(in float2x2 m)\n" + "{\n" + " float2x2 cof = { m[1][1], -m[0][1], -m[1][0], m[0][0] };\n" + " return cof / determinant(transpose(m));\n" + "}\n"}, + // cofAB is the cofactor for column A and row B. + {{EOpInverse, ParamType::Mat3}, + "float3x3 inverse_emu(in float3x3 m)\n" + "{\n" + " float cof00 = m[1][1] * m[2][2] - m[2][1] * m[1][2];\n" + " float cof01 = -(m[1][0] * m[2][2] - m[2][0] * m[1][2]);\n" + " float cof02 = m[1][0] * m[2][1] - m[2][0] * m[1][1];\n" + " float cof10 = -(m[0][1] * m[2][2] - m[2][1] * m[0][2]);\n" + " float cof11 = m[0][0] * m[2][2] - m[2][0] * m[0][2];\n" + " float cof12 = -(m[0][0] * m[2][1] - m[2][0] * m[0][1]);\n" + " float cof20 = m[0][1] * m[1][2] - m[1][1] * m[0][2];\n" + " float cof21 = -(m[0][0] * m[1][2] - m[1][0] * m[0][2]);\n" + " float cof22 = m[0][0] * m[1][1] - m[1][0] * m[0][1];\n" + " float3x3 cof = { cof00, cof10, cof20, cof01, cof11, cof21, cof02, cof12, cof22 };\n" + " return cof / determinant(transpose(m));\n" + "}\n"}, + {{EOpInverse, ParamType::Mat4}, + "float4x4 inverse_emu(in float4x4 m)\n" + "{\n" + " float cof00 = m[1][1] * m[2][2] * m[3][3] + m[2][1] * m[3][2] * m[1][3] + m[3][1] * \n" + " m[1][2] * m[2][3]\n" + " - m[1][1] * m[3][2] * m[2][3] - m[2][1] * m[1][2] * m[3][3] - m[3][1] * m[2][2] * \n" + " m[1][3];\n" + " float cof01 = -(m[1][0] * m[2][2] * m[3][3] + m[2][0] * m[3][2] * m[1][3] + m[3][0] * \n" + " m[1][2] * m[2][3]\n" + " - m[1][0] * m[3][2] * m[2][3] - m[2][0] * m[1][2] * m[3][3] - m[3][0] * m[2][2] * \n" + " m[1][3]);\n" + " float cof02 = m[1][0] * m[2][1] * m[3][3] + m[2][0] * m[3][1] * m[1][3] + m[3][0] * \n" + " m[1][1] * m[2][3]\n" + " - m[1][0] * m[3][1] * m[2][3] - m[2][0] * m[1][1] * m[3][3] - m[3][0] * m[2][1] * \n" + " m[1][3];\n" + " float cof03 = -(m[1][0] * m[2][1] * m[3][2] + m[2][0] * m[3][1] * m[1][2] + m[3][0] * \n" + " m[1][1] * m[2][2]\n" + " - m[1][0] * m[3][1] * m[2][2] - m[2][0] * m[1][1] * m[3][2] - m[3][0] * m[2][1] * \n" + " m[1][2]);\n" + " float cof10 = -(m[0][1] * m[2][2] * m[3][3] + m[2][1] * m[3][2] * m[0][3] + m[3][1] * \n" + " m[0][2] * m[2][3]\n" + " - m[0][1] * m[3][2] * m[2][3] - m[2][1] * m[0][2] * m[3][3] - m[3][1] * m[2][2] * \n" + " m[0][3]);\n" + " float cof11 = m[0][0] * m[2][2] * m[3][3] + m[2][0] * m[3][2] * m[0][3] + m[3][0] * \n" + " m[0][2] * m[2][3]\n" + " - m[0][0] * m[3][2] * m[2][3] - m[2][0] * m[0][2] * m[3][3] - m[3][0] * m[2][2] * \n" + " m[0][3];\n" + " float cof12 = -(m[0][0] * m[2][1] * m[3][3] + m[2][0] * m[3][1] * m[0][3] + m[3][0] * \n" + " m[0][1] * m[2][3]\n" + " - m[0][0] * m[3][1] * m[2][3] - m[2][0] * m[0][1] * m[3][3] - m[3][0] * m[2][1] * \n" + " m[0][3]);\n" + " float cof13 = m[0][0] * m[2][1] * m[3][2] + m[2][0] * m[3][1] * m[0][2] + m[3][0] * \n" + " m[0][1] * m[2][2]\n" + " - m[0][0] * m[3][1] * m[2][2] - m[2][0] * m[0][1] * m[3][2] - m[3][0] * m[2][1] * \n" + " m[0][2];\n" + " float cof20 = m[0][1] * m[1][2] * m[3][3] + m[1][1] * m[3][2] * m[0][3] + m[3][1] * \n" + " m[0][2] * m[1][3]\n" + " - m[0][1] * m[3][2] * m[1][3] - m[1][1] * m[0][2] * m[3][3] - m[3][1] * m[1][2] * \n" + " m[0][3];\n" + " float cof21 = -(m[0][0] * m[1][2] * m[3][3] + m[1][0] * m[3][2] * m[0][3] + m[3][0] * \n" + " m[0][2] * m[1][3]\n" + " - m[0][0] * m[3][2] * m[1][3] - m[1][0] * m[0][2] * m[3][3] - m[3][0] * m[1][2] * \n" + " m[0][3]);\n" + " float cof22 = m[0][0] * m[1][1] * m[3][3] + m[1][0] * m[3][1] * m[0][3] + m[3][0] * \n" + " m[0][1] * m[1][3]\n" + " - m[0][0] * m[3][1] * m[1][3] - m[1][0] * m[0][1] * m[3][3] - m[3][0] * m[1][1] * \n" + " m[0][3];\n" + " float cof23 = -(m[0][0] * m[1][1] * m[3][2] + m[1][0] * m[3][1] * m[0][2] + m[3][0] * \n" + " m[0][1] * m[1][2]\n" + " - m[0][0] * m[3][1] * m[1][2] - m[1][0] * m[0][1] * m[3][2] - m[3][0] * m[1][1] * \n" + " m[0][2]);\n" + " float cof30 = -(m[0][1] * m[1][2] * m[2][3] + m[1][1] * m[2][2] * m[0][3] + m[2][1] * \n" + " m[0][2] * m[1][3]\n" + " - m[0][1] * m[2][2] * m[1][3] - m[1][1] * m[0][2] * m[2][3] - m[2][1] * m[1][2] * \n" + " m[0][3]);\n" + " float cof31 = m[0][0] * m[1][2] * m[2][3] + m[1][0] * m[2][2] * m[0][3] + m[2][0] * \n" + " m[0][2] * m[1][3]\n" + " - m[0][0] * m[2][2] * m[1][3] - m[1][0] * m[0][2] * m[2][3] - m[2][0] * m[1][2] * \n" + " m[0][3];\n" + " float cof32 = -(m[0][0] * m[1][1] * m[2][3] + m[1][0] * m[2][1] * m[0][3] + m[2][0] * \n" + " m[0][1] * m[1][3]\n" + " - m[0][0] * m[2][1] * m[1][3] - m[1][0] * m[0][1] * m[2][3] - m[2][0] * m[1][1] * \n" + " m[0][3]);\n" + " float cof33 = m[0][0] * m[1][1] * m[2][2] + m[1][0] * m[2][1] * m[0][2] + m[2][0] * \n" + " m[0][1] * m[1][2]\n" + " - m[0][0] * m[2][1] * m[1][2] - m[1][0] * m[0][1] * m[2][2] - m[2][0] * m[1][1] * \n" + " m[0][2];\n" + " float4x4 cof = { cof00, cof10, cof20, cof30, cof01, cof11, cof21, cof31,\n" + " cof02, cof12, cof22, cof32, cof03, cof13, cof23, cof33 };\n" + " return cof / determinant(transpose(m));\n" + "}\n"}, + // Emulate ESSL3 variant of mix that takes last argument as boolean vector. + // genType mix(genType x, genType y, genBType a): Selects which vector each returned component + // comes from. For a component of 'a' that is false, the corresponding component of 'x' is + // returned. For a component of 'a' that is true, the corresponding component of 'y' is + // returned. + {{EOpMix, ParamType::Float1, ParamType::Float1, ParamType::Bool1}, + "float mix_emu(float x, float y, bool a)\n" + "{\n" + " return a ? y : x;\n" + "}\n"}, + {{EOpMix, ParamType::Float2, ParamType::Float2, ParamType::Bool2}, + "float2 mix_emu(float2 x, float2 y, bool2 a)\n" + "{\n" + " return a ? y : x;\n" + "}\n"}, + {{EOpMix, ParamType::Float3, ParamType::Float3, ParamType::Bool3}, + "float3 mix_emu(float3 x, float3 y, bool3 a)\n" + "{\n" + " return a ? y : x;\n" + "}\n"}, + {{EOpMix, ParamType::Float4, ParamType::Float4, ParamType::Bool4}, + "float4 mix_emu(float4 x, float4 y, bool4 a)\n" + "{\n" + " return a ? y : x;\n" + "}\n"}, + {{EOpBitfieldExtract, ParamType::Uint1, ParamType::Int1, ParamType::Int1}, + "uint bitfieldExtract_emu(uint value, int offset, int bits)\n" + "{\n" + " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n" + " {\n" + " return 0u;\n" + " }\n" + " uint maskMsb = (1u << (bits - 1));\n" + " uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n" + " return (value & mask) >> offset;\n" + "}\n"}, + {{EOpBitfieldExtract, ParamType::Uint2, ParamType::Int1, ParamType::Int1}, + "uint2 bitfieldExtract_emu(uint2 value, int offset, int bits)\n" + "{\n" + " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n" + " {\n" + " return uint2(0u, 0u);\n" + " }\n" + " uint maskMsb = (1u << (bits - 1));\n" + " uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n" + " return (value & mask) >> offset;\n" + "}\n"}, + {{EOpBitfieldExtract, ParamType::Uint3, ParamType::Int1, ParamType::Int1}, + "uint3 bitfieldExtract_emu(uint3 value, int offset, int bits)\n" + "{\n" + " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n" + " {\n" + " return uint3(0u, 0u, 0u);\n" + " }\n" + " uint maskMsb = (1u << (bits - 1));\n" + " uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n" + " return (value & mask) >> offset;\n" + "}\n"}, + {{EOpBitfieldExtract, ParamType::Uint4, ParamType::Int1, ParamType::Int1}, + "uint4 bitfieldExtract_emu(uint4 value, int offset, int bits)\n" + "{\n" + " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n" + " {\n" + " return uint4(0u, 0u, 0u, 0u);\n" + " }\n" + " uint maskMsb = (1u << (bits - 1));\n" + " uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n" + " return (value & mask) >> offset;\n" + "}\n"}, + {{EOpBitfieldExtract, ParamType::Int1, ParamType::Int1, ParamType::Int1}, + "int bitfieldExtract_emu(int value, int offset, int bits)\n" + "{\n" + " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n" + " {\n" + " return 0;\n" + " }\n" + " uint maskMsb = (1u << (bits - 1));\n" + " uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n" + " uint resultUnsigned = (asuint(value) & mask) >> offset;\n" + " if (bits != 32 && (resultUnsigned & maskMsb) != 0)\n" + " {\n" + " uint higherBitsMask = ((1u << (32 - bits)) - 1u) << bits;\n" + " resultUnsigned |= higherBitsMask;\n" + " }\n" + " return asint(resultUnsigned);\n" + "}\n"}, + {{EOpBitfieldExtract, ParamType::Int2, ParamType::Int1, ParamType::Int1}, + "int2 bitfieldExtract_emu(int2 value, int offset, int bits)\n" + "{\n" + " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n" + " {\n" + " return int2(0, 0);\n" + " }\n" + " uint maskMsb = (1u << (bits - 1));\n" + " uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n" + " uint2 resultUnsigned = (asuint(value) & mask) >> offset;\n" + " if (bits != 32)\n" + " {\n" + " uint higherBitsMask = ((1u << (32 - bits)) - 1u) << bits;\n" + " resultUnsigned |= ((resultUnsigned & maskMsb) >> (bits - 1)) * higherBitsMask;\n" + " }\n" + " return asint(resultUnsigned);\n" + "}\n"}, + {{EOpBitfieldExtract, ParamType::Int3, ParamType::Int1, ParamType::Int1}, + "int3 bitfieldExtract_emu(int3 value, int offset, int bits)\n" + "{\n" + " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n" + " {\n" + " return int3(0, 0, 0);\n" + " }\n" + " uint maskMsb = (1u << (bits - 1));\n" + " uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n" + " uint3 resultUnsigned = (asuint(value) & mask) >> offset;\n" + " if (bits != 32)\n" + " {\n" + " uint higherBitsMask = ((1u << (32 - bits)) - 1u) << bits;\n" + " resultUnsigned |= ((resultUnsigned & maskMsb) >> (bits - 1)) * higherBitsMask;\n" + " }\n" + " return asint(resultUnsigned);\n" + "}\n"}, + {{EOpBitfieldExtract, ParamType::Int4, ParamType::Int1, ParamType::Int1}, + "int4 bitfieldExtract_emu(int4 value, int offset, int bits)\n" + "{\n" + " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n" + " {\n" + " return int4(0, 0, 0, 0);\n" + " }\n" + " uint maskMsb = (1u << (bits - 1));\n" + " uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n" + " uint4 resultUnsigned = (asuint(value) & mask) >> offset;\n" + " if (bits != 32)\n" + " {\n" + " uint higherBitsMask = ((1u << (32 - bits)) - 1u) << bits;\n" + " resultUnsigned |= ((resultUnsigned & maskMsb) >> (bits - 1)) * higherBitsMask;\n" + " }\n" + " return asint(resultUnsigned);\n" + "}\n"}, + {{EOpBitfieldInsert, ParamType::Uint1, ParamType::Uint1, ParamType::Int1, ParamType::Int1}, + "uint bitfieldInsert_emu(uint base, uint insert, int offset, int bits)\n" + "{\n" + " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n" + " {\n" + " return base;\n" + " }\n" + " uint maskMsb = (1u << (bits - 1));\n" + " uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n" + " uint baseMask = ~insertMask;\n" + " return (base & baseMask) | ((insert << offset) & insertMask);\n" + "}\n"}, + {{EOpBitfieldInsert, ParamType::Uint2, ParamType::Uint2, ParamType::Int1, ParamType::Int1}, + "uint2 bitfieldInsert_emu(uint2 base, uint2 insert, int offset, int bits)\n" + "{\n" + " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n" + " {\n" + " return base;\n" + " }\n" + " uint maskMsb = (1u << (bits - 1));\n" + " uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n" + " uint baseMask = ~insertMask;\n" + " return (base & baseMask) | ((insert << offset) & insertMask);\n" + "}\n"}, + {{EOpBitfieldInsert, ParamType::Uint3, ParamType::Uint3, ParamType::Int1, ParamType::Int1}, + "uint3 bitfieldInsert_emu(uint3 base, uint3 insert, int offset, int bits)\n" + "{\n" + " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n" + " {\n" + " return base;\n" + " }\n" + " uint maskMsb = (1u << (bits - 1));\n" + " uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n" + " uint baseMask = ~insertMask;\n" + " return (base & baseMask) | ((insert << offset) & insertMask);\n" + "}\n"}, + {{EOpBitfieldInsert, ParamType::Uint4, ParamType::Uint4, ParamType::Int1, ParamType::Int1}, + "uint4 bitfieldInsert_emu(uint4 base, uint4 insert, int offset, int bits)\n" + "{\n" + " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n" + " {\n" + " return base;\n" + " }\n" + " uint maskMsb = (1u << (bits - 1));\n" + " uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n" + " uint baseMask = ~insertMask;\n" + " return (base & baseMask) | ((insert << offset) & insertMask);\n" + "}\n"}, + {{EOpBitfieldInsert, ParamType::Int1, ParamType::Int1, ParamType::Int1, ParamType::Int1}, + "int bitfieldInsert_emu(int base, int insert, int offset, int bits)\n" + "{\n" + " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n" + " {\n" + " return base;\n" + " }\n" + " uint maskMsb = (1u << (bits - 1));\n" + " uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n" + " uint baseMask = ~insertMask;\n" + " uint resultUnsigned = (asuint(base) & baseMask) | ((asuint(insert) << offset) & \n" + " insertMask);\n" + " return asint(resultUnsigned);\n" + "}\n"}, + {{EOpBitfieldInsert, ParamType::Int2, ParamType::Int2, ParamType::Int1, ParamType::Int1}, + "int2 bitfieldInsert_emu(int2 base, int2 insert, int offset, int bits)\n" + "{\n" + " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n" + " {\n" + " return base;\n" + " }\n" + " uint maskMsb = (1u << (bits - 1));\n" + " uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n" + " uint baseMask = ~insertMask;\n" + " uint2 resultUnsigned = (asuint(base) & baseMask) | ((asuint(insert) << offset) & \n" + " insertMask);\n" + " return asint(resultUnsigned);\n" + "}\n"}, + {{EOpBitfieldInsert, ParamType::Int3, ParamType::Int3, ParamType::Int1, ParamType::Int1}, + "int3 bitfieldInsert_emu(int3 base, int3 insert, int offset, int bits)\n" + "{\n" + " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n" + " {\n" + " return base;\n" + " }\n" + " uint maskMsb = (1u << (bits - 1));\n" + " uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n" + " uint baseMask = ~insertMask;\n" + " uint3 resultUnsigned = (asuint(base) & baseMask) | ((asuint(insert) << offset) & \n" + " insertMask);\n" + " return asint(resultUnsigned);\n" + "}\n"}, + {{EOpBitfieldInsert, ParamType::Int4, ParamType::Int4, ParamType::Int1, ParamType::Int1}, + "int4 bitfieldInsert_emu(int4 base, int4 insert, int offset, int bits)\n" + "{\n" + " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n" + " {\n" + " return base;\n" + " }\n" + " uint maskMsb = (1u << (bits - 1));\n" + " uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n" + " uint baseMask = ~insertMask;\n" + " uint4 resultUnsigned = (asuint(base) & baseMask) | ((asuint(insert) << offset) & \n" + " insertMask);\n" + " return asint(resultUnsigned);\n" + "}\n"}, + {{EOpUaddCarry, ParamType::Uint1, ParamType::Uint1, ParamType::Uint1}, + "uint uaddCarry_emu(uint x, uint y, out uint carry)\n" + "{\n" + " carry = uint(x > (0xffffffffu - y));\n" + " return x + y;\n" + "}\n"}, + {{EOpUaddCarry, ParamType::Uint2, ParamType::Uint2, ParamType::Uint2}, + "uint2 uaddCarry_emu(uint2 x, uint2 y, out uint2 carry)\n" + "{\n" + " carry = uint2(x > (0xffffffffu - y));\n" + " return x + y;\n" + "}\n"}, + {{EOpUaddCarry, ParamType::Uint3, ParamType::Uint3, ParamType::Uint3}, + "uint3 uaddCarry_emu(uint3 x, uint3 y, out uint3 carry)\n" + "{\n" + " carry = uint3(x > (0xffffffffu - y));\n" + " return x + y;\n" + "}\n"}, + {{EOpUaddCarry, ParamType::Uint4, ParamType::Uint4, ParamType::Uint4}, + "uint4 uaddCarry_emu(uint4 x, uint4 y, out uint4 carry)\n" + "{\n" + " carry = uint4(x > (0xffffffffu - y));\n" + " return x + y;\n" + "}\n"}, + {{EOpUsubBorrow, ParamType::Uint1, ParamType::Uint1, ParamType::Uint1}, + "uint usubBorrow_emu(uint x, uint y, out uint borrow)\n" + "{\n" + " borrow = uint(x < y);\n" + " return x - y;\n" + "}\n"}, + {{EOpUsubBorrow, ParamType::Uint2, ParamType::Uint2, ParamType::Uint2}, + "uint2 usubBorrow_emu(uint2 x, uint2 y, out uint2 borrow)\n" + "{\n" + " borrow = uint2(x < y);\n" + " return x - y;\n" + "}\n"}, + {{EOpUsubBorrow, ParamType::Uint3, ParamType::Uint3, ParamType::Uint3}, + "uint3 usubBorrow_emu(uint3 x, uint3 y, out uint3 borrow)\n" + "{\n" + " borrow = uint3(x < y);\n" + " return x - y;\n" + "}\n"}, + {{EOpUsubBorrow, ParamType::Uint4, ParamType::Uint4, ParamType::Uint4}, + "uint4 usubBorrow_emu(uint4 x, uint4 y, out uint4 borrow)\n" + "{\n" + " borrow = uint4(x < y);\n" + " return x - y;\n" + "}\n"}, +}; +} // anonymous namespace + +const char *FindHLSLFunction(const FunctionId &functionID) +{ + for (size_t index = 0; index < ArraySize(g_hlslFunctions); ++index) + { + const auto &function = g_hlslFunctions[index]; + if (function.id == functionID) + { + return function.body; + } + } + + return nullptr; +} +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/glslang.h b/src/3rdparty/angle/src/compiler/translator/glslang.h index 0555e96d45..e54c31ba3e 100644 --- a/src/3rdparty/angle/src/compiler/translator/glslang.h +++ b/src/3rdparty/angle/src/compiler/translator/glslang.h @@ -7,14 +7,18 @@ #ifndef COMPILER_TRANSLATOR_GLSLANG_H_ #define COMPILER_TRANSLATOR_GLSLANG_H_ +namespace sh +{ class TParseContext; -extern int glslang_initialize(TParseContext* context); -extern int glslang_finalize(TParseContext* context); +} + +extern int glslang_initialize(sh::TParseContext *context); +extern int glslang_finalize(sh::TParseContext *context); extern int glslang_scan(size_t count, - const char* const string[], + const char *const string[], const int length[], - TParseContext* context); -extern int glslang_parse(TParseContext* context); + sh::TParseContext *context); +extern int glslang_parse(sh::TParseContext *context); -#endif // COMPILER_TRANSLATOR_GLSLANG_H_ +#endif // COMPILER_TRANSLATOR_GLSLANG_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/glslang.l b/src/3rdparty/angle/src/compiler/translator/glslang.l index d09358dd8a..858ffd96bb 100644 --- a/src/3rdparty/angle/src/compiler/translator/glslang.l +++ b/src/3rdparty/angle/src/compiler/translator/glslang.l @@ -22,6 +22,8 @@ WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp). // This file is auto-generated by generate_parser.sh. DO NOT EDIT! +/* clang-format off */ + // Ignore errors in auto-generated code. #if defined(__GNUC__) #pragma GCC diagnostic ignored "-Wunused-function" @@ -44,6 +46,9 @@ WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp). #include "compiler/preprocessor/Token.h" #include "compiler/translator/util.h" #include "compiler/translator/length_limits.h" + +using namespace sh; + #include "glslang_tab.h" /* windows only pragma */ @@ -71,10 +76,16 @@ static int reserved_word(yyscan_t yyscanner); static int ES2_reserved_ES3_keyword(TParseContext *context, int token); static int ES2_keyword_ES3_reserved(TParseContext *context, int token); static int ES2_ident_ES3_keyword(TParseContext *context, int token); +static int ES2_ident_ES3_keyword_multiview_keyword(TParseContext *context, int token); +static int ES2_ident_ES3_reserved_ES3_1_keyword(TParseContext *context, int token); +static int ES2_and_ES3_reserved_ES3_1_keyword(TParseContext *context, int token); +static int ES2_and_ES3_ident_ES3_1_keyword(TParseContext *context, int token); +static int ES3_extension_keyword_else_ident(TParseContext *context, TExtension extension, int token); static int uint_constant(TParseContext *context); static int int_constant(TParseContext *context); static int float_constant(yyscan_t yyscanner); static int floatsuffix_check(TParseContext* context); +static int yuvcscstandardext_constant(TParseContext *context); %} %option noyywrap nounput never-interactive @@ -103,6 +114,7 @@ O [0-7] "attribute" { return ES2_keyword_ES3_reserved(context, ATTRIBUTE); } "const" { return CONST_QUAL; } "uniform" { return UNIFORM; } +"buffer" { return ES2_and_ES3_ident_ES3_1_keyword(context, BUFFER); } "varying" { return ES2_keyword_ES3_reserved(context, VARYING); } "break" { return BREAK; } @@ -124,6 +136,7 @@ O [0-7] "in" { return IN_QUAL; } "out" { return OUT_QUAL; } "inout" { return INOUT_QUAL; } +"shared" { return ES2_and_ES3_ident_ES3_1_keyword(context, SHARED); } "float" { return FLOAT_TYPE; } "int" { return INT_TYPE; } @@ -171,29 +184,52 @@ O [0-7] "sampler3DRect" { return ES2_reserved_ES3_keyword(context, SAMPLER3DRECT); } "sampler2DRect" { return SAMPLER2DRECT; } "sampler2DArray" { return ES2_ident_ES3_keyword(context, SAMPLER2DARRAY); } +"sampler2DMS" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, SAMPLER2DMS); } "isampler2D" { return ES2_ident_ES3_keyword(context, ISAMPLER2D); } "isampler3D" { return ES2_ident_ES3_keyword(context, ISAMPLER3D); } "isamplerCube" { return ES2_ident_ES3_keyword(context, ISAMPLERCUBE); } "isampler2DArray" { return ES2_ident_ES3_keyword(context, ISAMPLER2DARRAY); } +"isampler2DMS" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, ISAMPLER2DMS); } "usampler2D" { return ES2_ident_ES3_keyword(context, USAMPLER2D); } "usampler3D" { return ES2_ident_ES3_keyword(context, USAMPLER3D); } "usamplerCube" { return ES2_ident_ES3_keyword(context, USAMPLERCUBE); } "usampler2DArray" { return ES2_ident_ES3_keyword(context, USAMPLER2DARRAY); } +"usampler2DMS" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, USAMPLER2DMS); } "sampler2DShadow" { return ES2_reserved_ES3_keyword(context, SAMPLER2DSHADOW); } "samplerCubeShadow" { return ES2_ident_ES3_keyword(context, SAMPLERCUBESHADOW); } "sampler2DArrayShadow" { return ES2_ident_ES3_keyword(context, SAMPLER2DARRAYSHADOW); } +"__samplerExternal2DY2YEXT" { return ES3_extension_keyword_else_ident(context, TExtension::EXT_YUV_target, SAMPLEREXTERNAL2DY2YEXT); } "struct" { return STRUCT; } -"layout" { return ES2_ident_ES3_keyword(context, LAYOUT); } +"layout" { return ES2_ident_ES3_keyword_multiview_keyword(context, LAYOUT); } + +"yuvCscStandardEXT" { return ES3_extension_keyword_else_ident(context, TExtension::EXT_YUV_target, YUVCSCSTANDARDEXT); } +"itu_601" { return yuvcscstandardext_constant(context); } +"itu_601_full_range" { return yuvcscstandardext_constant(context); } +"itu_709" { return yuvcscstandardext_constant(context); } + +"image2D" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IMAGE2D); } +"iimage2D" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IIMAGE2D); } +"uimage2D" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, UIMAGE2D); } +"image2DArray" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IMAGE2DARRAY); } +"iimage2DArray" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IIMAGE2DARRAY); } +"uimage2DArray" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, UIMAGE2DARRAY); } +"image3D" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IMAGE3D); } +"uimage3D" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, UIMAGE3D); } +"iimage3D" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IIMAGE3D); } +"iimageCube" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IIMAGECUBE); } +"uimageCube" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, UIMAGECUBE); } +"imageCube" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, IMAGECUBE); } +"readonly" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, READONLY); } +"writeonly" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, WRITEONLY); } +"coherent" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, COHERENT); } +"restrict" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, RESTRICT); } +"volatile" { return ES2_and_ES3_reserved_ES3_1_keyword(context, VOLATILE); } +"atomic_uint" { return ES2_ident_ES3_reserved_ES3_1_keyword(context, ATOMICUINT); } /* Reserved keywords for GLSL ES 3.00 that are not reserved for GLSL ES 1.00 */ -"coherent" | -"restrict" | -"readonly" | -"writeonly" | "resource" | -"atomic_uint" | "noperspective" | "patch" | "sample" | @@ -204,23 +240,11 @@ O [0-7] "filter" | "image1D" | -"image2D" | -"image3D" | -"imageCube" | "iimage1D" | -"iimage2D" | -"iimage3D" | -"iimageCube" | "uimage1D" | -"uimage2D" | -"uimage3D" | -"uimageCube" | "image1DArray" | -"image2DArray" | "iimage1DArray" | -"iimage2DArray" | "uimage1DArray" | -"uimage2DArray" | "image1DShadow" | "image2DShadow" | "image1DArrayShadow" | @@ -240,9 +264,6 @@ O [0-7] "samplerBuffer" | "isamplerBuffer" | "usamplerBuffer" | -"sampler2DMS" | -"isampler2DMS" | -"usampler2DMS" | "sampler2DMSArray" | "isampler2DMSArray" | "usampler2DMSArray" { @@ -278,7 +299,6 @@ O [0-7] "inline" | "noinline" | -"volatile" | "public" | "static" | "extern" | @@ -390,6 +410,10 @@ O [0-7] return FIELD_SELECTION; } [ \t\v\f\r] {} +. { + yyextra->error(*yylloc, "Illegal character at fieldname start", yytext); + return 0; +} [ \t\v\n\f\r] { } <*><> { yyterminate(); } @@ -431,8 +455,7 @@ int check_type(yyscan_t yyscanner) { int reserved_word(yyscan_t yyscanner) { struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; - yyextra->error(*yylloc, "Illegal use of reserved word", yytext, ""); - yyextra->recover(); + yyextra->error(*yylloc, "Illegal use of reserved word", yytext); return 0; } @@ -460,6 +483,24 @@ int ES2_keyword_ES3_reserved(TParseContext *context, int token) return token; } +int ES2_ident_ES3_reserved_ES3_1_keyword(TParseContext *context, int token) +{ + struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); + yyscan_t yyscanner = (yyscan_t) context->getScanner(); + + if (context->getShaderVersion() < 300) + { + yylval->lex.string = NewPoolTString(yytext); + return check_type(yyscanner); + } + else if (context->getShaderVersion() == 300) + { + return reserved_word(yyscanner); + } + + return token; +} + int ES2_ident_ES3_keyword(TParseContext *context, int token) { struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); @@ -475,19 +516,76 @@ int ES2_ident_ES3_keyword(TParseContext *context, int token) return token; } +int ES2_ident_ES3_keyword_multiview_keyword(TParseContext *context, int token) +{ + struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); + yyscan_t yyscanner = (yyscan_t) context->getScanner(); + + // not a reserved word in GLSL ES 1.00, so could be used as an identifier/type name + // except when multiview extension is enabled + if (context->getShaderVersion() < 300 && !context->isExtensionEnabled(TExtension::OVR_multiview)) + { + yylval->lex.string = NewPoolTString(yytext); + return check_type(yyscanner); + } + + return token; +} + +int ES2_and_ES3_reserved_ES3_1_keyword(TParseContext *context, int token) +{ + yyscan_t yyscanner = (yyscan_t) context->getScanner(); + + if (context->getShaderVersion() < 310) + { + return reserved_word(yyscanner); + } + + return token; +} + +int ES2_and_ES3_ident_ES3_1_keyword(TParseContext *context, int token) +{ + struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); + yyscan_t yyscanner = (yyscan_t) context->getScanner(); + + // not a reserved word in GLSL ES 1.00 and GLSL ES 3.00, so could be used as an identifier/type name + if (context->getShaderVersion() < 310) + { + yylval->lex.string = NewPoolTString(yytext); + return check_type(yyscanner); + } + + return token; +} + +int ES3_extension_keyword_else_ident(TParseContext *context, TExtension extension, int token) +{ + struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); + yyscan_t yyscanner = (yyscan_t) context->getScanner(); + + // a reserved word in GLSL ES 3.00 with enabled extension, otherwise could be used as an identifier/type name + if (context->getShaderVersion() >= 300 && context->isExtensionEnabled(extension)) + { + return token; + } + + yylval->lex.string = NewPoolTString(yytext); + return check_type(yyscanner); +} + int uint_constant(TParseContext *context) { struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); if (context->getShaderVersion() < 300) { - context->error(*yylloc, "Unsigned integers are unsupported prior to GLSL ES 3.00", yytext, ""); - context->recover(); + context->error(*yylloc, "Unsigned integers are unsupported prior to GLSL ES 3.00", yytext); return 0; } if (!atoi_clamp(yytext, &(yylval->lex.u))) - yyextra->error(*yylloc, "Integer overflow", yytext, ""); + yyextra->error(*yylloc, "Integer overflow", yytext); return UINTCONSTANT; } @@ -499,21 +597,19 @@ int floatsuffix_check(TParseContext* context) if (context->getShaderVersion() < 300) { context->error(*yylloc, "Floating-point suffix unsupported prior to GLSL ES 3.00", yytext); - context->recover(); return 0; } std::string text = yytext; text.resize(text.size() - 1); if (!strtof_clamp(text, &(yylval->lex.f))) - yyextra->warning(*yylloc, "Float overflow", yytext, ""); + yyextra->warning(*yylloc, "Float overflow", yytext); return(FLOATCONSTANT); } void yyerror(YYLTYPE* lloc, TParseContext* context, void *scanner, const char* reason) { context->error(*lloc, reason, yyget_text(scanner)); - context->recover(); } int int_constant(TParseContext *context) { @@ -523,9 +619,9 @@ int int_constant(TParseContext *context) { if (!atoi_clamp(yytext, &u)) { if (context->getShaderVersion() >= 300) - yyextra->error(*yylloc, "Integer overflow", yytext, ""); + yyextra->error(*yylloc, "Integer overflow", yytext); else - yyextra->warning(*yylloc, "Integer overflow", yytext, ""); + yyextra->warning(*yylloc, "Integer overflow", yytext); } yylval->lex.i = static_cast(u); return INTCONSTANT; @@ -535,10 +631,26 @@ int float_constant(yyscan_t yyscanner) { struct yyguts_t* yyg = (struct yyguts_t*) yyscanner; if (!strtof_clamp(yytext, &(yylval->lex.f))) - yyextra->warning(*yylloc, "Float overflow", yytext, ""); + yyextra->warning(*yylloc, "Float overflow", yytext); return FLOATCONSTANT; } +int yuvcscstandardext_constant(TParseContext *context) +{ + struct yyguts_t* yyg = (struct yyguts_t*) context->getScanner(); + yyscan_t yyscanner = (yyscan_t) context->getScanner(); + + // a reserved word in GLSL ES 3.00 with enabled extension, otherwise could be used as an identifier/type name + if (context->getShaderVersion() >= 300 && context->isExtensionEnabled(TExtension::EXT_YUV_target)) + { + yylval->lex.string = NewPoolTString(yytext); + return YUVCSCSTANDARDEXTCONSTANT; + } + + yylval->lex.string = NewPoolTString(yytext); + return check_type(yyscanner); +} + int glslang_initialize(TParseContext* context) { yyscan_t scanner = NULL; if (yylex_init_extra(context, &scanner)) @@ -574,13 +686,12 @@ int glslang_scan(size_t count, const char* const string[], const int length[], const TExtensionBehavior& extBehavior = context->extensionBehavior(); for (TExtensionBehavior::const_iterator iter = extBehavior.begin(); iter != extBehavior.end(); ++iter) { - preprocessor->predefineMacro(iter->first.c_str(), 1); + preprocessor->predefineMacro(GetExtensionNameString(iter->first), 1); } if (context->getFragmentPrecisionHigh()) preprocessor->predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1); - preprocessor->setMaxTokenSize(GetGlobalMaxTokenSize(context->getShaderSpec())); + preprocessor->setMaxTokenSize(sh::GetGlobalMaxTokenSize(context->getShaderSpec())); return 0; } - diff --git a/src/3rdparty/angle/src/compiler/translator/glslang.y b/src/3rdparty/angle/src/compiler/translator/glslang.y index aba2706311..3e506caac8 100644 --- a/src/3rdparty/angle/src/compiler/translator/glslang.y +++ b/src/3rdparty/angle/src/compiler/translator/glslang.y @@ -22,6 +22,8 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). // This file is auto-generated by generate_parser.sh. DO NOT EDIT! +// clang-format off + // Ignore errors in auto-generated code. #if defined(__GNUC__) #pragma GCC diagnostic ignored "-Wunused-function" @@ -44,6 +46,8 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). #define YYENABLE_NLS 0 +using namespace sh; + %} %expect 1 /* One shift reduce conflict because of if | else */ %parse-param {TParseContext* context} @@ -70,22 +74,30 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). struct { TOperator op; union { - TIntermNode* intermNode; + TIntermNode *intermNode; TIntermNodePair nodePair; - TIntermTyped* intermTypedNode; - TIntermAggregate* intermAggregate; - TIntermSwitch* intermSwitch; - TIntermCase* intermCase; + TIntermFunctionCallOrMethod callOrMethodPair; + TIntermTyped *intermTypedNode; + TIntermAggregate *intermAggregate; + TIntermBlock *intermBlock; + TIntermDeclaration *intermDeclaration; + TIntermFunctionPrototype *intermFunctionPrototype; + TIntermSwitch *intermSwitch; + TIntermCase *intermCase; }; union { + TVector *arraySizes; + TTypeSpecifierNonArray typeSpecifierNonArray; TPublicType type; TPrecision precision; TLayoutQualifier layoutQualifier; TQualifier qualifier; - TFunction* function; + TFunction *function; TParameter param; - TField* field; - TFieldList* fieldList; + TField *field; + TFieldList *fieldList; + TQualifierWrapperBase *qualifierWrapper; + TTypeQualifierBuilder *typeQualifierBuilder; }; } interm; } @@ -112,29 +124,37 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons #define VERTEX_ONLY(S, L) { \ if (context->getShaderType() != GL_VERTEX_SHADER) { \ - context->error(L, " supported in vertex shaders only ", S); \ - context->recover(); \ + context->error(L, " supported in vertex shaders only", S); \ } \ } -#define FRAG_ONLY(S, L) { \ - if (context->getShaderType() != GL_FRAGMENT_SHADER) { \ - context->error(L, " supported in fragment shaders only ", S); \ - context->recover(); \ +#define COMPUTE_ONLY(S, L) { \ + if (context->getShaderType() != GL_COMPUTE_SHADER) { \ + context->error(L, " supported in compute shaders only", S); \ } \ } #define ES2_ONLY(S, L) { \ if (context->getShaderVersion() != 100) { \ - context->error(L, " supported in GLSL ES 1.00 only ", S); \ - context->recover(); \ + context->error(L, " supported in GLSL ES 1.00 only", S); \ } \ } -#define ES3_ONLY(TOKEN, LINE, REASON) { \ - if (context->getShaderVersion() != 300) { \ - context->error(LINE, REASON " supported in GLSL ES 3.00 only ", TOKEN); \ - context->recover(); \ +#define ES3_OR_NEWER(TOKEN, LINE, REASON) { \ + if (context->getShaderVersion() < 300) { \ + context->error(LINE, REASON " supported in GLSL ES 3.00 and above only", TOKEN); \ + } \ +} + +#define ES3_OR_NEWER_OR_MULTIVIEW(TOKEN, LINE, REASON) { \ + if (context->getShaderVersion() < 300 && !context->isExtensionEnabled(TExtension::OVR_multiview)) { \ + context->error(LINE, REASON " supported in GLSL ES 3.00 and above only", TOKEN); \ + } \ +} + +#define ES3_1_ONLY(TOKEN, LINE, REASON) { \ + if (context->getShaderVersion() != 310) { \ + context->error(LINE, REASON " supported in GLSL ES 3.10 only", TOKEN); \ } \ } %} @@ -143,15 +163,22 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons %token ATTRIBUTE CONST_QUAL BOOL_TYPE FLOAT_TYPE INT_TYPE UINT_TYPE %token BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT %token BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4 UVEC2 UVEC3 UVEC4 -%token MATRIX2 MATRIX3 MATRIX4 IN_QUAL OUT_QUAL INOUT_QUAL UNIFORM VARYING +%token MATRIX2 MATRIX3 MATRIX4 IN_QUAL OUT_QUAL INOUT_QUAL UNIFORM BUFFER VARYING %token MATRIX2x3 MATRIX3x2 MATRIX2x4 MATRIX4x2 MATRIX3x4 MATRIX4x3 %token CENTROID FLAT SMOOTH +%token READONLY WRITEONLY COHERENT RESTRICT VOLATILE SHARED %token STRUCT VOID_TYPE WHILE %token SAMPLER2D SAMPLERCUBE SAMPLER_EXTERNAL_OES SAMPLER2DRECT SAMPLER2DARRAY %token ISAMPLER2D ISAMPLER3D ISAMPLERCUBE ISAMPLER2DARRAY %token USAMPLER2D USAMPLER3D USAMPLERCUBE USAMPLER2DARRAY +%token SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS %token SAMPLER3D SAMPLER3DRECT SAMPLER2DSHADOW SAMPLERCUBESHADOW SAMPLER2DARRAYSHADOW +%token SAMPLEREXTERNAL2DY2YEXT +%token IMAGE2D IIMAGE2D UIMAGE2D IMAGE3D IIMAGE3D UIMAGE3D IMAGE2DARRAY IIMAGE2DARRAY UIMAGE2DARRAY +%token IMAGECUBE IIMAGECUBE UIMAGECUBE +%token ATOMICUINT %token LAYOUT +%token YUVCSCSTANDARDEXT YUVCSCSTANDARDEXTCONSTANT %token IDENTIFIER TYPE_NAME FLOATCONSTANT INTCONSTANT UINTCONSTANT BOOLCONSTANT %token FIELD_SELECTION @@ -166,7 +193,7 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons %token LEFT_ANGLE RIGHT_ANGLE VERTICAL_BAR CARET AMPERSAND QUESTION %type identifier -%type assignment_operator unary_operator +%type assignment_operator unary_operator %type variable_identifier primary_expression postfix_expression %type expression integer_expression assignment_expression %type unary_expression multiplicative_expression additive_expression @@ -174,11 +201,12 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons %type conditional_expression constant_expression %type logical_or_expression logical_xor_expression logical_and_expression %type shift_expression and_expression exclusive_or_expression inclusive_or_expression -%type function_call initializer condition conditionopt +%type function_call initializer -%type translation_unit function_definition -%type statement simple_statement -%type statement_list compound_statement compound_statement_no_new_scope +%type condition conditionopt +%type translation_unit +%type function_definition statement simple_statement +%type statement_list compound_statement_with_scope compound_statement_no_new_scope %type declaration_statement selection_statement expression_statement %type declaration external_declaration %type for_init_statement @@ -188,14 +216,22 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons %type iteration_statement jump_statement statement_no_new_scope statement_with_scope %type single_declaration init_declarator_list -%type parameter_declaration parameter_declarator parameter_type_specifier -%type parameter_qualifier parameter_type_qualifier -%type layout_qualifier layout_qualifier_id_list layout_qualifier_id +%type parameter_declaration parameter_declarator parameter_type_specifier +%type layout_qualifier_id_list layout_qualifier_id + +// Note: array_specifier guaranteed to be non-null. +%type array_specifier + +%type fully_specified_type type_specifier %type precision_qualifier -%type type_qualifier fully_specified_type type_specifier storage_qualifier interpolation_qualifier -%type type_specifier_no_prec type_specifier_nonarray -%type struct_specifier +%type layout_qualifier +%type interpolation_qualifier +%type storage_qualifier single_type_qualifier invariant_qualifier +%type type_qualifier + +%type type_specifier_nonarray struct_specifier +%type type_specifier_no_prec %type struct_declarator %type struct_declarator_list struct_declaration struct_declaration_list %type function_header function_declarator function_identifier @@ -229,22 +265,31 @@ primary_expression | INTCONSTANT { TConstantUnion *unionArray = new TConstantUnion[1]; unionArray->setIConst($1.i); - $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), @1); + $$ = context->addScalarLiteral(unionArray, @1); } | UINTCONSTANT { TConstantUnion *unionArray = new TConstantUnion[1]; unionArray->setUConst($1.u); - $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtUInt, EbpUndefined, EvqConst), @1); + $$ = context->addScalarLiteral(unionArray, @1); } | FLOATCONSTANT { TConstantUnion *unionArray = new TConstantUnion[1]; unionArray->setFConst($1.f); - $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), @1); + $$ = context->addScalarLiteral(unionArray, @1); } | BOOLCONSTANT { TConstantUnion *unionArray = new TConstantUnion[1]; unionArray->setBConst($1.b); - $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @1); + $$ = context->addScalarLiteral(unionArray, @1); + } + | YUVCSCSTANDARDEXTCONSTANT { + if (!context->checkCanUseExtension(@1, TExtension::EXT_YUV_target)) + { + context->error(@1, "unsupported value", $1.string->c_str()); + } + TConstantUnion *unionArray = new TConstantUnion[1]; + unionArray->setYuvCscStandardEXTConst(getYuvCscStandardEXT($1.string->c_str())); + $$ = context->addScalarLiteral(unionArray, @1); } | LEFT_PAREN expression RIGHT_PAREN { $$ = $2; @@ -274,32 +319,26 @@ postfix_expression integer_expression : expression { - if (context->integerErrorCheck($1, "[]")) - context->recover(); + context->checkIsScalarInteger($1, "[]"); $$ = $1; } ; function_call : function_call_or_method { - bool fatalError = false; - $$ = context->addFunctionCallOrMethod($1.function, $1.nodePair.node1, $1.nodePair.node2, @1, &fatalError); - if (fatalError) - { - YYERROR; - } + $$ = context->addFunctionCallOrMethod($1.function, $1.callOrMethodPair.arguments, $1.callOrMethodPair.thisNode, @1); } ; function_call_or_method : function_call_generic { $$ = $1; - $$.nodePair.node2 = nullptr; + $$.callOrMethodPair.thisNode = nullptr; } | postfix_expression DOT function_call_generic { - ES3_ONLY("", @3, "methods"); + ES3_OR_NEWER("", @3, "methods"); $$ = $3; - $$.nodePair.node2 = $1; + $$.callOrMethodPair.thisNode = $1; } ; @@ -315,26 +354,23 @@ function_call_generic function_call_header_no_parameters : function_call_header VOID_TYPE { $$.function = $1; - $$.nodePair.node1 = nullptr; + $$.callOrMethodPair.arguments = context->createEmptyArgumentsList(); } | function_call_header { $$.function = $1; - $$.nodePair.node1 = nullptr; + $$.callOrMethodPair.arguments = context->createEmptyArgumentsList(); } ; function_call_header_with_parameters : function_call_header assignment_expression { - const TType *type = new TType($2->getType()); - $1->addParameter(TConstParameter(type)); + $$.callOrMethodPair.arguments = context->createEmptyArgumentsList(); $$.function = $1; - $$.nodePair.node1 = context->intermediate.makeAggregate($2, @2); + $$.callOrMethodPair.arguments->push_back($2); } | function_call_header_with_parameters COMMA assignment_expression { - const TType *type = new TType($3->getType()); - $1.function->addParameter(TConstParameter(type)); $$.function = $1.function; - $$.nodePair.node1 = context->intermediate.growAggregate($1.intermNode, $3, @2); + $$.callOrMethodPair.arguments->push_back($3); } ; @@ -348,24 +384,13 @@ function_call_header function_identifier : type_specifier_no_prec { - if ($1.array) { - ES3_ONLY("[]", @1, "array constructor"); - } $$ = context->addConstructorFunc($1); } | IDENTIFIER { - if (context->reservedErrorCheck(@1, *$1.string)) - context->recover(); - const TType *type = TCache::getType(EbtVoid, EbpUndefined); - TFunction *function = new TFunction($1.string, type); - $$ = function; + $$ = context->addNonConstructorFunc($1.string, @1); } | FIELD_SELECTION { - if (context->reservedErrorCheck(@1, *$1.string)) - context->recover(); - const TType *type = TCache::getType(EbtVoid, EbpUndefined); - TFunction *function = new TFunction($1.string, type); - $$ = function; + $$ = context->addNonConstructorFunc($1.string, @1); } ; @@ -380,21 +405,18 @@ unary_expression $$ = context->addUnaryMathLValue(EOpPreDecrement, $2, @1); } | unary_operator unary_expression { - if ($1.op != EOpNull) { - $$ = context->addUnaryMath($1.op, $2, @1); - } else - $$ = $2; + $$ = context->addUnaryMath($1, $2, @1); } ; // Grammar Note: No traditional style type casts. unary_operator - : PLUS { $$.op = EOpPositive; } - | DASH { $$.op = EOpNegative; } - | BANG { $$.op = EOpLogicalNot; } + : PLUS { $$ = EOpPositive; } + | DASH { $$ = EOpNegative; } + | BANG { $$ = EOpLogicalNot; } | TILDE { - ES3_ONLY("~", @$, "bit-wise operator"); - $$.op = EOpBitwiseNot; + ES3_OR_NEWER("~", @$, "bit-wise operator"); + $$ = EOpBitwiseNot; } ; // Grammar Note: No '*' or '&' unary ops. Pointers are not supported. @@ -408,7 +430,7 @@ multiplicative_expression $$ = context->addBinaryMath(EOpDiv, $1, $3, @2); } | multiplicative_expression PERCENT unary_expression { - ES3_ONLY("%", @2, "integer modulus operator"); + ES3_OR_NEWER("%", @2, "integer modulus operator"); $$ = context->addBinaryMath(EOpIMod, $1, $3, @2); } ; @@ -426,11 +448,11 @@ additive_expression shift_expression : additive_expression { $$ = $1; } | shift_expression LEFT_OP additive_expression { - ES3_ONLY("<<", @2, "bit-wise operator"); + ES3_OR_NEWER("<<", @2, "bit-wise operator"); $$ = context->addBinaryMath(EOpBitShiftLeft, $1, $3, @2); } | shift_expression RIGHT_OP additive_expression { - ES3_ONLY(">>", @2, "bit-wise operator"); + ES3_OR_NEWER(">>", @2, "bit-wise operator"); $$ = context->addBinaryMath(EOpBitShiftRight, $1, $3, @2); } ; @@ -464,7 +486,7 @@ equality_expression and_expression : equality_expression { $$ = $1; } | and_expression AMPERSAND equality_expression { - ES3_ONLY("&", @2, "bit-wise operator"); + ES3_OR_NEWER("&", @2, "bit-wise operator"); $$ = context->addBinaryMath(EOpBitwiseAnd, $1, $3, @2); } ; @@ -472,7 +494,7 @@ and_expression exclusive_or_expression : and_expression { $$ = $1; } | exclusive_or_expression CARET and_expression { - ES3_ONLY("^", @2, "bit-wise operator"); + ES3_OR_NEWER("^", @2, "bit-wise operator"); $$ = context->addBinaryMath(EOpBitwiseXor, $1, $3, @2); } ; @@ -480,7 +502,7 @@ exclusive_or_expression inclusive_or_expression : exclusive_or_expression { $$ = $1; } | inclusive_or_expression VERTICAL_BAR exclusive_or_expression { - ES3_ONLY("|", @2, "bit-wise operator"); + ES3_OR_NEWER("|", @2, "bit-wise operator"); $$ = context->addBinaryMath(EOpBitwiseOr, $1, $3, @2); } ; @@ -516,41 +538,39 @@ conditional_expression assignment_expression : conditional_expression { $$ = $1; } | unary_expression assignment_operator assignment_expression { - if (context->lValueErrorCheck(@2, "assign", $1)) - context->recover(); - $$ = context->addAssign($2.op, $1, $3, @2); + $$ = context->addAssign($2, $1, $3, @2); } ; assignment_operator - : EQUAL { $$.op = EOpAssign; } - | MUL_ASSIGN { $$.op = EOpMulAssign; } - | DIV_ASSIGN { $$.op = EOpDivAssign; } + : EQUAL { $$ = EOpAssign; } + | MUL_ASSIGN { $$ = EOpMulAssign; } + | DIV_ASSIGN { $$ = EOpDivAssign; } | MOD_ASSIGN { - ES3_ONLY("%=", @$, "integer modulus operator"); - $$.op = EOpIModAssign; + ES3_OR_NEWER("%=", @$, "integer modulus operator"); + $$ = EOpIModAssign; } - | ADD_ASSIGN { $$.op = EOpAddAssign; } - | SUB_ASSIGN { $$.op = EOpSubAssign; } + | ADD_ASSIGN { $$ = EOpAddAssign; } + | SUB_ASSIGN { $$ = EOpSubAssign; } | LEFT_ASSIGN { - ES3_ONLY("<<=", @$, "bit-wise operator"); - $$.op = EOpBitShiftLeftAssign; + ES3_OR_NEWER("<<=", @$, "bit-wise operator"); + $$ = EOpBitShiftLeftAssign; } | RIGHT_ASSIGN { - ES3_ONLY(">>=", @$, "bit-wise operator"); - $$.op = EOpBitShiftRightAssign; + ES3_OR_NEWER(">>=", @$, "bit-wise operator"); + $$ = EOpBitShiftRightAssign; } | AND_ASSIGN { - ES3_ONLY("&=", @$, "bit-wise operator"); - $$.op = EOpBitwiseAndAssign; + ES3_OR_NEWER("&=", @$, "bit-wise operator"); + $$ = EOpBitwiseAndAssign; } | XOR_ASSIGN { - ES3_ONLY("^=", @$, "bit-wise operator"); - $$.op = EOpBitwiseXorAssign; + ES3_OR_NEWER("^=", @$, "bit-wise operator"); + $$ = EOpBitwiseXorAssign; } | OR_ASSIGN { - ES3_ONLY("|=", @$, "bit-wise operator"); - $$.op = EOpBitwiseOrAssign; + ES3_OR_NEWER("|=", @$, "bit-wise operator"); + $$ = EOpBitwiseOrAssign; } ; @@ -565,16 +585,14 @@ expression constant_expression : conditional_expression { - if (context->constErrorCheck($1)) - context->recover(); + context->checkIsConst($1); $$ = $1; } ; enter_struct : IDENTIFIER LEFT_BRACE { - if (context->enterStructDeclaration(@1, *$1.string)) - context->recover(); + context->enterStructDeclaration(@1, *$1.string); $$ = $1; } ; @@ -584,43 +602,38 @@ declaration $$ = context->addFunctionPrototypeDeclaration(*($1.function), @1); } | init_declarator_list SEMICOLON { - TIntermAggregate *aggNode = $1.intermAggregate; - if (aggNode && aggNode->getOp() == EOpNull) - aggNode->setOp(EOpDeclaration); - $$ = aggNode; + $$ = $1.intermDeclaration; } | PRECISION precision_qualifier type_specifier_no_prec SEMICOLON { - if (($2 == EbpHigh) && (context->getShaderType() == GL_FRAGMENT_SHADER) && !context->getFragmentPrecisionHigh()) { - context->error(@1, "precision is not supported in fragment shader", "highp"); - context->recover(); - } - if (!context->symbolTable.setDefaultPrecision( $3, $2 )) { - context->error(@1, "illegal type argument for default precision qualifier", getBasicString($3.type)); - context->recover(); - } - $$ = 0; + context->parseDefaultPrecisionQualifier($2, $3, @1); + $$ = nullptr; } | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE SEMICOLON { - ES3_ONLY(getQualifierString($1.qualifier), @1, "interface blocks"); - $$ = context->addInterfaceBlock($1, @2, *$2.string, $3, NULL, @$, NULL, @$); + ES3_OR_NEWER($2.string->c_str(), @1, "interface blocks"); + $$ = context->addInterfaceBlock(*$1, @2, *$2.string, $3, NULL, @$, NULL, @$); } | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE IDENTIFIER SEMICOLON { - ES3_ONLY(getQualifierString($1.qualifier), @1, "interface blocks"); - $$ = context->addInterfaceBlock($1, @2, *$2.string, $3, $5.string, @5, NULL, @$); + ES3_OR_NEWER($2.string->c_str(), @1, "interface blocks"); + $$ = context->addInterfaceBlock(*$1, @2, *$2.string, $3, $5.string, @5, NULL, @$); } | type_qualifier enter_struct struct_declaration_list RIGHT_BRACE IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET SEMICOLON { - ES3_ONLY(getQualifierString($1.qualifier), @1, "interface blocks"); - $$ = context->addInterfaceBlock($1, @2, *$2.string, $3, $5.string, @5, $7, @6); + ES3_OR_NEWER($2.string->c_str(), @1, "interface blocks"); + $$ = context->addInterfaceBlock(*$1, @2, *$2.string, $3, $5.string, @5, $7, @6); } | type_qualifier SEMICOLON { - context->parseGlobalLayoutQualifier($1); - $$ = 0; + context->parseGlobalLayoutQualifier(*$1); + $$ = nullptr; + } + | type_qualifier IDENTIFIER SEMICOLON // e.g. to qualify an existing variable as invariant + { + $$ = context->parseInvariantDeclaration(*$1, @2, $2.string, $2.symbol); } ; function_prototype : function_declarator RIGHT_PAREN { $$.function = context->parseFunctionDeclarator(@2, $1); + context->exitFunctionDeclaration(); } ; @@ -638,145 +651,69 @@ function_header_with_parameters : function_header parameter_declaration { // Add the parameter $$ = $1; - if ($2.param.type->getBasicType() != EbtVoid) - $1->addParameter($2.param.turnToConst()); - else - delete $2.param.type; + if ($2.type->getBasicType() != EbtVoid) + { + $1->addParameter($2.turnToConst()); + } } | function_header_with_parameters COMMA parameter_declaration { - // + $$ = $1; // Only first parameter of one-parameter functions can be void // The check for named parameters not being void is done in parameter_declarator - // - if ($3.param.type->getBasicType() == EbtVoid) { - // + if ($3.type->getBasicType() == EbtVoid) + { // This parameter > first is void - // - context->error(@2, "cannot be an argument type except for '(void)'", "void"); - context->recover(); - delete $3.param.type; - } else { - // Add the parameter - $$ = $1; - $1->addParameter($3.param.turnToConst()); + context->error(@2, "cannot be a parameter type except for '(void)'", "void"); + } + else + { + $1->addParameter($3.turnToConst()); } } ; function_header : fully_specified_type IDENTIFIER LEFT_PAREN { - if ($1.qualifier != EvqGlobal && $1.qualifier != EvqTemporary) - { - context->error(@2, "no qualifiers allowed for function return", getQualifierString($1.qualifier)); - context->recover(); - } - if (!$1.layoutQualifier.isEmpty()) - { - context->error(@2, "no qualifiers allowed for function return", "layout"); - context->recover(); - } - // make sure a sampler is not involved as well... - if (context->samplerErrorCheck(@2, $1, "samplers can't be function return values")) - context->recover(); + $$ = context->parseFunctionHeader($1, $2.string, @2); - // Add the function as a prototype after parsing it (we do not support recursion) - TFunction *function; - const TType *type = new TType($1); - function = new TFunction($2.string, type); - $$ = function; - context->symbolTable.push(); + context->enterFunctionDeclaration(); } ; parameter_declarator // Type + name : type_specifier identifier { - if ($1.type == EbtVoid) { - context->error(@2, "illegal use of type 'void'", $2.string->c_str()); - context->recover(); - } - if (context->reservedErrorCheck(@2, *$2.string)) - context->recover(); - TParameter param = {$2.string, new TType($1)}; - $$.param = param; + $$ = context->parseParameterDeclarator($1, $2.string, @2); } - | type_specifier identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { - // Check that we can make an array out of this type - if (context->arrayTypeErrorCheck(@3, $1)) - context->recover(); - - if (context->reservedErrorCheck(@2, *$2.string)) - context->recover(); - - int size; - if (context->arraySizeErrorCheck(@3, $4, size)) - context->recover(); - $1.setArraySize(size); - - TType* type = new TType($1); - TParameter param = { $2.string, type }; - $$.param = param; + | type_specifier identifier array_specifier { + $$ = context->parseParameterArrayDeclarator($2.string, @2, *($3), @3, &$1); } ; parameter_declaration - // - // The only parameter qualifier a parameter can have are - // IN_QUAL, OUT_QUAL, INOUT_QUAL, or CONST. - // - - // - // Type + name - // - : parameter_type_qualifier parameter_qualifier parameter_declarator { - $$ = $3; - if (context->paramErrorCheck(@3, $1, $2, $$.param.type)) - context->recover(); - } - | parameter_qualifier parameter_declarator { + : type_qualifier parameter_declarator { $$ = $2; - if (context->parameterSamplerErrorCheck(@2, $1, *$2.param.type)) - context->recover(); - if (context->paramErrorCheck(@2, EvqTemporary, $1, $$.param.type)) - context->recover(); + context->checkIsParameterQualifierValid(@2, *$1, $2.type); } - // - // Only type - // - | parameter_type_qualifier parameter_qualifier parameter_type_specifier { - $$ = $3; - if (context->paramErrorCheck(@3, $1, $2, $$.param.type)) - context->recover(); + | parameter_declarator { + $$ = $1; + $$.type->setQualifier(EvqIn); } - | parameter_qualifier parameter_type_specifier { + | type_qualifier parameter_type_specifier { $$ = $2; - if (context->parameterSamplerErrorCheck(@2, $1, *$2.param.type)) - context->recover(); - if (context->paramErrorCheck(@2, EvqTemporary, $1, $$.param.type)) - context->recover(); + context->checkIsParameterQualifierValid(@2, *$1, $2.type); } - ; - -parameter_qualifier - : /* empty */ { - $$ = EvqIn; - } - | IN_QUAL { - $$ = EvqIn; - } - | OUT_QUAL { - $$ = EvqOut; - } - | INOUT_QUAL { - $$ = EvqInOut; + | parameter_type_specifier { + $$ = $1; + $$.type->setQualifier(EvqIn); } ; parameter_type_specifier : type_specifier { TParameter param = { 0, new TType($1) }; - $$.param = param; + $$ = param; } ; @@ -786,213 +723,164 @@ init_declarator_list } | init_declarator_list COMMA identifier { $$ = $1; - $$.intermAggregate = context->parseDeclarator($$.type, $1.intermAggregate, @3, *$3.string); + context->parseDeclarator($$.type, @3, *$3.string, $$.intermDeclaration); } - | init_declarator_list COMMA identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { + | init_declarator_list COMMA identifier array_specifier { $$ = $1; - $$.intermAggregate = context->parseArrayDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, $5); + context->parseArrayDeclarator($$.type, @3, *$3.string, @4, *($4), $$.intermDeclaration); } - | init_declarator_list COMMA identifier LEFT_BRACKET RIGHT_BRACKET EQUAL initializer { - ES3_ONLY("[]", @3, "implicitly sized array"); + | init_declarator_list COMMA identifier array_specifier EQUAL initializer { + ES3_OR_NEWER("=", @5, "first-class arrays (array initializer)"); $$ = $1; - $$.intermAggregate = context->parseArrayInitDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, nullptr, @6, $7); - } - | init_declarator_list COMMA identifier LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer { - ES3_ONLY("=", @7, "first-class arrays (array initializer)"); - $$ = $1; - $$.intermAggregate = context->parseArrayInitDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, $5, @7, $8); + context->parseArrayInitDeclarator($$.type, @3, *$3.string, @4, *($4), @5, $6, $$.intermDeclaration); } | init_declarator_list COMMA identifier EQUAL initializer { $$ = $1; - $$.intermAggregate = context->parseInitDeclarator($$.type, $1.intermAggregate, @3, *$3.string, @4, $5); + context->parseInitDeclarator($$.type, @3, *$3.string, @4, $5, $$.intermDeclaration); } ; single_declaration : fully_specified_type { $$.type = $1; - $$.intermAggregate = context->parseSingleDeclaration($$.type, @1, ""); + $$.intermDeclaration = context->parseSingleDeclaration($$.type, @1, ""); } | fully_specified_type identifier { $$.type = $1; - $$.intermAggregate = context->parseSingleDeclaration($$.type, @2, *$2.string); + $$.intermDeclaration = context->parseSingleDeclaration($$.type, @2, *$2.string); } - | fully_specified_type identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { + | fully_specified_type identifier array_specifier { $$.type = $1; - $$.intermAggregate = context->parseSingleArrayDeclaration($$.type, @2, *$2.string, @3, $4); + $$.intermDeclaration = context->parseSingleArrayDeclaration($$.type, @2, *$2.string, @3, *($3)); } - | fully_specified_type identifier LEFT_BRACKET RIGHT_BRACKET EQUAL initializer { - ES3_ONLY("[]", @3, "implicitly sized array"); + | fully_specified_type identifier array_specifier EQUAL initializer { + ES3_OR_NEWER("[]", @3, "first-class arrays (array initializer)"); $$.type = $1; - $$.intermAggregate = context->parseSingleArrayInitDeclaration($$.type, @2, *$2.string, @3, nullptr, @5, $6); - } - | fully_specified_type identifier LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer { - ES3_ONLY("=", @6, "first-class arrays (array initializer)"); - $$.type = $1; - $$.intermAggregate = context->parseSingleArrayInitDeclaration($$.type, @2, *$2.string, @3, $4, @6, $7); + $$.intermDeclaration = context->parseSingleArrayInitDeclaration($$.type, @2, *$2.string, @3, *($3), @4, $5); } | fully_specified_type identifier EQUAL initializer { $$.type = $1; - $$.intermAggregate = context->parseSingleInitDeclaration($$.type, @2, *$2.string, @3, $4); - } - | INVARIANT IDENTIFIER { - // $$.type is not used in invariant declarations. - $$.intermAggregate = context->parseInvariantDeclaration(@1, @2, $2.string, $2.symbol); + $$.intermDeclaration = context->parseSingleInitDeclaration($$.type, @2, *$2.string, @3, $4); } ; fully_specified_type : type_specifier { + context->addFullySpecifiedType(&$1); $$ = $1; - - if ($1.array) { - ES3_ONLY("[]", @1, "first-class-array"); - if (context->getShaderVersion() != 300) { - $1.clearArrayness(); - } - } } - | type_qualifier type_specifier { - $$ = context->addFullySpecifiedType($1.qualifier, $1.invariant, $1.layoutQualifier, $2); + | type_qualifier type_specifier { + $$ = context->addFullySpecifiedType(*$1, $2); } ; interpolation_qualifier : SMOOTH { - $$.qualifier = EvqSmooth; + $$ = EvqSmooth; } | FLAT { - $$.qualifier = EvqFlat; - } - ; - -parameter_type_qualifier - : CONST_QUAL { - $$ = EvqConst; + $$ = EvqFlat; } ; type_qualifier - : ATTRIBUTE { - VERTEX_ONLY("attribute", @1); - ES2_ONLY("attribute", @1); - if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "attribute")) - context->recover(); - $$.setBasic(EbtVoid, EvqAttribute, @1); + : single_type_qualifier { + $$ = context->createTypeQualifierBuilder(@1); + $$->appendQualifier($1); } - | VARYING { - ES2_ONLY("varying", @1); - if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "varying")) - context->recover(); - if (context->getShaderType() == GL_VERTEX_SHADER) - $$.setBasic(EbtVoid, EvqVaryingOut, @1); - else - $$.setBasic(EbtVoid, EvqVaryingIn, @1); - } - | INVARIANT VARYING { - ES2_ONLY("varying", @1); - if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "invariant varying")) - context->recover(); - if (context->getShaderType() == GL_VERTEX_SHADER) - $$.setBasic(EbtVoid, EvqVaryingOut, @1); - else - $$.setBasic(EbtVoid, EvqVaryingIn, @1); - $$.invariant = true; - } - | storage_qualifier { - if ($1.qualifier != EvqConst && !context->symbolTable.atGlobalLevel()) - { - context->error(@1, "Local variables can only use the const storage qualifier.", getQualifierString($1.qualifier)); - context->recover(); - } - $$.setBasic(EbtVoid, $1.qualifier, @1); - } - | interpolation_qualifier storage_qualifier { - $$ = context->joinInterpolationQualifiers(@1, $1.qualifier, @2, $2.qualifier); - } - | interpolation_qualifier { - context->error(@1, "interpolation qualifier requires a fragment 'in' or vertex 'out' storage qualifier", getInterpolationString($1.qualifier)); - context->recover(); - - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtVoid, qual, @1); - } - | layout_qualifier { - $$.qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.layoutQualifier = $1; - } - | layout_qualifier storage_qualifier { - $$.setBasic(EbtVoid, $2.qualifier, @2); - $$.layoutQualifier = $1; - } - | INVARIANT storage_qualifier { - context->es3InvariantErrorCheck($2.qualifier, @1); - $$.setBasic(EbtVoid, $2.qualifier, @2); - $$.invariant = true; - } - | INVARIANT interpolation_qualifier storage_qualifier { - context->es3InvariantErrorCheck($3.qualifier, @1); - $$ = context->joinInterpolationQualifiers(@2, $2.qualifier, @3, $3.qualifier); - $$.invariant = true; + | type_qualifier single_type_qualifier { + $$ = $1; + $$->appendQualifier($2); } ; +invariant_qualifier + : INVARIANT { + // empty + } + ; + +single_type_qualifier + : storage_qualifier { + context->checkLocalVariableConstStorageQualifier(*$1); + $$ = $1; + } + | layout_qualifier { + context->checkIsAtGlobalLevel(@1, "layout"); + $$ = new TLayoutQualifierWrapper($1, @1); + } + | precision_qualifier { + $$ = new TPrecisionQualifierWrapper($1, @1); + } + | interpolation_qualifier { + $$ = new TInterpolationQualifierWrapper($1, @1); + } + | invariant_qualifier { + context->checkIsAtGlobalLevel(@1, "invariant"); + $$ = new TInvariantQualifierWrapper(@1); + } + ; + + storage_qualifier - : CONST_QUAL { - $$.qualifier = EvqConst; + : + ATTRIBUTE { + VERTEX_ONLY("attribute", @1); + ES2_ONLY("attribute", @1); + $$ = context->parseGlobalStorageQualifier(EvqAttribute, @1); + } + | VARYING { + ES2_ONLY("varying", @1); + $$ = context->parseVaryingQualifier(@1); + } + | CONST_QUAL { + $$ = new TStorageQualifierWrapper(EvqConst, @1); } | IN_QUAL { - ES3_ONLY("in", @1, "storage qualifier"); - $$.qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentIn : EvqVertexIn; + $$ = context->parseInQualifier(@1); } | OUT_QUAL { - ES3_ONLY("out", @1, "storage qualifier"); - $$.qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqVertexOut; + $$ = context->parseOutQualifier(@1); } - | CENTROID IN_QUAL { - ES3_ONLY("centroid in", @1, "storage qualifier"); - if (context->getShaderType() == GL_VERTEX_SHADER) - { - context->error(@1, "invalid storage qualifier", "it is an error to use 'centroid in' in the vertex shader"); - context->recover(); - } - $$.qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqCentroidIn : EvqVertexIn; + | INOUT_QUAL { + $$ = context->parseInOutQualifier(@1); } - | CENTROID OUT_QUAL { - ES3_ONLY("centroid out", @1, "storage qualifier"); - if (context->getShaderType() == GL_FRAGMENT_SHADER) - { - context->error(@1, "invalid storage qualifier", "it is an error to use 'centroid out' in the fragment shader"); - context->recover(); - } - $$.qualifier = (context->getShaderType() == GL_FRAGMENT_SHADER) ? EvqFragmentOut : EvqCentroidOut; + | CENTROID { + ES3_OR_NEWER("centroid", @1, "storage qualifier"); + $$ = new TStorageQualifierWrapper(EvqCentroid, @1); } | UNIFORM { - if (context->globalErrorCheck(@1, context->symbolTable.atGlobalLevel(), "uniform")) - context->recover(); - $$.qualifier = EvqUniform; + $$ = context->parseGlobalStorageQualifier(EvqUniform, @1); + } + | BUFFER { + ES3_1_ONLY("buffer", @1, "storage qualifier"); + $$ = context->parseGlobalStorageQualifier(EvqBuffer, @1); + } + | READONLY { + $$ = new TMemoryQualifierWrapper(EvqReadOnly, @1); + } + | WRITEONLY { + $$ = new TMemoryQualifierWrapper(EvqWriteOnly, @1); + } + | COHERENT { + $$ = new TMemoryQualifierWrapper(EvqCoherent, @1); + } + | RESTRICT { + $$ = new TMemoryQualifierWrapper(EvqRestrict, @1); + } + | VOLATILE { + $$ = new TMemoryQualifierWrapper(EvqVolatile, @1); + } + | SHARED { + COMPUTE_ONLY("shared", @1); + $$ = context->parseGlobalStorageQualifier(EvqShared, @1); } ; type_specifier : type_specifier_no_prec { $$ = $1; - - if ($$.precision == EbpUndefined) { - $$.precision = context->symbolTable.getDefaultPrecision($1.type); - if (context->precisionErrorCheck(@1, $$.precision, $1.type)) { - context->recover(); - } - } - } - | precision_qualifier type_specifier_no_prec { - $$ = $2; - $$.precision = $1; - - if (!SupportsPrecision($2.type)) { - context->error(@1, "illegal type for precision qualifier", getBasicString($2.type)); - context->recover(); - } + $$.precision = context->symbolTable.getDefaultPrecision($1.getBasicType()); } ; @@ -1010,7 +898,7 @@ precision_qualifier layout_qualifier : LAYOUT LEFT_PAREN layout_qualifier_id_list RIGHT_PAREN { - ES3_ONLY("layout", @1, "qualifier"); + ES3_OR_NEWER_OR_MULTIVIEW("layout", @1, "qualifier"); $$ = $3; } ; @@ -1020,7 +908,7 @@ layout_qualifier_id_list $$ = $1; } | layout_qualifier_id_list COMMA layout_qualifier_id { - $$ = context->joinLayoutQualifiers($1, $3); + $$ = context->joinLayoutQualifiers($1, $3, @3); } ; @@ -1029,279 +917,303 @@ layout_qualifier_id $$ = context->parseLayoutQualifier(*$1.string, @1); } | IDENTIFIER EQUAL INTCONSTANT { - $$ = context->parseLayoutQualifier(*$1.string, @1, *$3.string, $3.i, @3); + $$ = context->parseLayoutQualifier(*$1.string, @1, $3.i, @3); } | IDENTIFIER EQUAL UINTCONSTANT { - $$ = context->parseLayoutQualifier(*$1.string, @1, *$3.string, $3.i, @3); + $$ = context->parseLayoutQualifier(*$1.string, @1, $3.i, @3); + } + | SHARED { + $$ = context->parseLayoutQualifier("shared", @1); } ; type_specifier_no_prec : type_specifier_nonarray { - $$ = $1; + $$.initialize($1, (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary)); } - | type_specifier_nonarray LEFT_BRACKET RIGHT_BRACKET { - ES3_ONLY("[]", @2, "implicitly sized array"); - $$ = $1; - $$.setArraySize(0); + | type_specifier_nonarray array_specifier { + $$.initialize($1, (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary)); + $$.setArraySizes($2); } - | type_specifier_nonarray LEFT_BRACKET constant_expression RIGHT_BRACKET { - $$ = $1; + ; - if (context->arrayTypeErrorCheck(@2, $1)) - context->recover(); - else { - int size; - if (context->arraySizeErrorCheck(@2, $3, size)) - context->recover(); - $$.setArraySize(size); - } +array_specifier + : LEFT_BRACKET RIGHT_BRACKET { + ES3_OR_NEWER("[]", @1, "implicitly sized array"); + $$ = new TVector(); + $$->push_back(0u); + } + | LEFT_BRACKET constant_expression RIGHT_BRACKET { + $$ = new TVector(); + unsigned int size = context->checkIsValidArraySize(@1, $2); + // Make the type an array even if size check failed. + // This ensures useless error messages regarding a variable's non-arrayness won't follow. + $$->push_back(size); + } + | array_specifier LEFT_BRACKET RIGHT_BRACKET { + ES3_1_ONLY("[]", @2, "arrays of arrays"); + $$ = $1; + $$->insert($$->begin(), 0u); + } + | array_specifier LEFT_BRACKET constant_expression RIGHT_BRACKET { + ES3_1_ONLY("[]", @2, "arrays of arrays"); + $$ = $1; + unsigned int size = context->checkIsValidArraySize(@2, $3); + // Make the type an array even if size check failed. + // This ensures useless error messages regarding a variable's non-arrayness won't follow. + $$->insert($$->begin(), size); } ; type_specifier_nonarray : VOID_TYPE { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtVoid, qual, @1); + $$.initialize(EbtVoid, @1); } | FLOAT_TYPE { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtFloat, qual, @1); + $$.initialize(EbtFloat, @1); } | INT_TYPE { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtInt, qual, @1); + $$.initialize(EbtInt, @1); } | UINT_TYPE { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtUInt, qual, @1); + $$.initialize(EbtUInt, @1); } | BOOL_TYPE { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtBool, qual, @1); + $$.initialize(EbtBool, @1); } | VEC2 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtFloat, qual, @1); + $$.initialize(EbtFloat, @1); $$.setAggregate(2); } | VEC3 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtFloat, qual, @1); + $$.initialize(EbtFloat, @1); $$.setAggregate(3); } | VEC4 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtFloat, qual, @1); + $$.initialize(EbtFloat, @1); $$.setAggregate(4); } | BVEC2 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtBool, qual, @1); + $$.initialize(EbtBool, @1); $$.setAggregate(2); } | BVEC3 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtBool, qual, @1); + $$.initialize(EbtBool, @1); $$.setAggregate(3); } | BVEC4 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtBool, qual, @1); + $$.initialize(EbtBool, @1); $$.setAggregate(4); } | IVEC2 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtInt, qual, @1); + $$.initialize(EbtInt, @1); $$.setAggregate(2); } | IVEC3 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtInt, qual, @1); + $$.initialize(EbtInt, @1); $$.setAggregate(3); } | IVEC4 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtInt, qual, @1); + $$.initialize(EbtInt, @1); $$.setAggregate(4); } | UVEC2 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtUInt, qual, @1); + $$.initialize(EbtUInt, @1); $$.setAggregate(2); } | UVEC3 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtUInt, qual, @1); + $$.initialize(EbtUInt, @1); $$.setAggregate(3); } | UVEC4 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtUInt, qual, @1); + $$.initialize(EbtUInt, @1); $$.setAggregate(4); } | MATRIX2 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtFloat, qual, @1); + $$.initialize(EbtFloat, @1); $$.setMatrix(2, 2); } | MATRIX3 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtFloat, qual, @1); + $$.initialize(EbtFloat, @1); $$.setMatrix(3, 3); } | MATRIX4 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtFloat, qual, @1); + $$.initialize(EbtFloat, @1); $$.setMatrix(4, 4); } | MATRIX2x3 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtFloat, qual, @1); + $$.initialize(EbtFloat, @1); $$.setMatrix(2, 3); } | MATRIX3x2 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtFloat, qual, @1); + $$.initialize(EbtFloat, @1); $$.setMatrix(3, 2); } | MATRIX2x4 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtFloat, qual, @1); + $$.initialize(EbtFloat, @1); $$.setMatrix(2, 4); } | MATRIX4x2 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtFloat, qual, @1); + $$.initialize(EbtFloat, @1); $$.setMatrix(4, 2); } | MATRIX3x4 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtFloat, qual, @1); + $$.initialize(EbtFloat, @1); $$.setMatrix(3, 4); } | MATRIX4x3 { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtFloat, qual, @1); + $$.initialize(EbtFloat, @1); $$.setMatrix(4, 3); } + | YUVCSCSTANDARDEXT { + if (!context->checkCanUseExtension(@1, TExtension::EXT_YUV_target)) + { + context->error(@1, "unsupported type", "yuvCscStandardEXT"); + } + $$.initialize(EbtYuvCscStandardEXT, @1); + } | SAMPLER2D { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtSampler2D, qual, @1); + $$.initialize(EbtSampler2D, @1); } | SAMPLER3D { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtSampler3D, qual, @1); + $$.initialize(EbtSampler3D, @1); } | SAMPLERCUBE { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtSamplerCube, qual, @1); + $$.initialize(EbtSamplerCube, @1); } | SAMPLER2DARRAY { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtSampler2DArray, qual, @1); + $$.initialize(EbtSampler2DArray, @1); + } + | SAMPLER2DMS { + $$.initialize(EbtSampler2DMS, @1); } | ISAMPLER2D { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtISampler2D, qual, @1); + $$.initialize(EbtISampler2D, @1); } | ISAMPLER3D { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtISampler3D, qual, @1); + $$.initialize(EbtISampler3D, @1); } | ISAMPLERCUBE { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtISamplerCube, qual, @1); + $$.initialize(EbtISamplerCube, @1); } | ISAMPLER2DARRAY { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtISampler2DArray, qual, @1); + $$.initialize(EbtISampler2DArray, @1); + } + | ISAMPLER2DMS { + $$.initialize(EbtISampler2DMS, @1); } | USAMPLER2D { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtUSampler2D, qual, @1); + $$.initialize(EbtUSampler2D, @1); } | USAMPLER3D { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtUSampler3D, qual, @1); + $$.initialize(EbtUSampler3D, @1); } | USAMPLERCUBE { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtUSamplerCube, qual, @1); + $$.initialize(EbtUSamplerCube, @1); } | USAMPLER2DARRAY { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtUSampler2DArray, qual, @1); + $$.initialize(EbtUSampler2DArray, @1); + } + | USAMPLER2DMS { + $$.initialize(EbtUSampler2DMS, @1); } | SAMPLER2DSHADOW { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtSampler2DShadow, qual, @1); + $$.initialize(EbtSampler2DShadow, @1); } | SAMPLERCUBESHADOW { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtSamplerCubeShadow, qual, @1); + $$.initialize(EbtSamplerCubeShadow, @1); } | SAMPLER2DARRAYSHADOW { - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtSampler2DArrayShadow, qual, @1); + $$.initialize(EbtSampler2DArrayShadow, @1); } | SAMPLER_EXTERNAL_OES { - if (!context->supportsExtension("GL_OES_EGL_image_external")) { + constexpr std::array extensions{ { TExtension::NV_EGL_stream_consumer_external, + TExtension::OES_EGL_image_external_essl3, + TExtension::OES_EGL_image_external } }; + if (!context->checkCanUseOneOfExtensions(@1, extensions)) + { context->error(@1, "unsupported type", "samplerExternalOES"); - context->recover(); } - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtSamplerExternalOES, qual, @1); + $$.initialize(EbtSamplerExternalOES, @1); + } + | SAMPLEREXTERNAL2DY2YEXT { + if (!context->checkCanUseExtension(@1, TExtension::EXT_YUV_target)) + { + context->error(@1, "unsupported type", "__samplerExternal2DY2YEXT"); + } + $$.initialize(EbtSamplerExternal2DY2YEXT, @1); } | SAMPLER2DRECT { - if (!context->supportsExtension("GL_ARB_texture_rectangle")) { + if (!context->checkCanUseExtension(@1, TExtension::ARB_texture_rectangle)) + { context->error(@1, "unsupported type", "sampler2DRect"); - context->recover(); } - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtSampler2DRect, qual, @1); + $$.initialize(EbtSampler2DRect, @1); } | struct_specifier { $$ = $1; - $$.qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + } + | IMAGE2D { + $$.initialize(EbtImage2D, @1); + } + | IIMAGE2D { + $$.initialize(EbtIImage2D, @1); + } + | UIMAGE2D { + $$.initialize(EbtUImage2D, @1); + } + | IMAGE3D { + $$.initialize(EbtImage3D, @1); + } + | IIMAGE3D { + $$.initialize(EbtIImage3D, @1); + } + | UIMAGE3D { + $$.initialize(EbtUImage3D, @1); + } + | IMAGE2DARRAY { + $$.initialize(EbtImage2DArray, @1); + } + | IIMAGE2DARRAY { + $$.initialize(EbtIImage2DArray, @1); + } + | UIMAGE2DARRAY { + $$.initialize(EbtUImage2DArray, @1); + } + | IMAGECUBE { + $$.initialize(EbtImageCube, @1); + } + | IIMAGECUBE { + $$.initialize(EbtIImageCube, @1); + } + | UIMAGECUBE { + $$.initialize(EbtUImageCube, @1); + } + | ATOMICUINT { + $$.initialize(EbtAtomicCounter, @1); } | TYPE_NAME { - // - // This is for user defined type names. The lexical phase looked up the - // type. - // + // This is for user defined type names. The lexical phase looked up the type. TType& structure = static_cast($1.symbol)->getType(); - TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - $$.setBasic(EbtStruct, qual, @1); - $$.userDef = &structure; + $$.initializeStruct(structure.getStruct(), false, @1); } ; struct_specifier - : STRUCT identifier LEFT_BRACE { if (context->enterStructDeclaration(@2, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE { + : STRUCT identifier LEFT_BRACE { context->enterStructDeclaration(@2, *$2.string); } struct_declaration_list RIGHT_BRACE { $$ = context->addStructure(@1, @2, $2.string, $5); } - | STRUCT LEFT_BRACE { if (context->enterStructDeclaration(@2, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE { + | STRUCT LEFT_BRACE { context->enterStructDeclaration(@2, *$2.string); } struct_declaration_list RIGHT_BRACE { $$ = context->addStructure(@1, @$, NewPoolTString(""), $4); } ; struct_declaration_list : struct_declaration { - $$ = $1; + $$ = context->addStructFieldList($1, @1); } | struct_declaration_list struct_declaration { - $$ = $1; - for (size_t i = 0; i < $2->size(); ++i) { - TField* field = (*$2)[i]; - for (size_t j = 0; j < $$->size(); ++j) { - if ((*$$)[j]->name() == field->name()) { - context->error(@2, "duplicate field name in structure:", "struct", field->name().c_str()); - context->recover(); - } - } - $$->push_back(field); - } + $$ = context->combineStructFieldLists($1, $2, @2); } ; @@ -1311,9 +1223,7 @@ struct_declaration } | type_qualifier type_specifier struct_declarator_list SEMICOLON { // ES3 Only, but errors should be handled elsewhere - $2.qualifier = $1.qualifier; - $2.layoutQualifier = $1.layoutQualifier; - $$ = context->addStructDeclaratorList($2, $3); + $$ = context->addStructDeclaratorListWithQualifiers(*$1, &$2, $3); } ; @@ -1329,23 +1239,10 @@ struct_declarator_list struct_declarator : identifier { - if (context->reservedErrorCheck(@1, *$1.string)) - context->recover(); - - TType* type = new TType(EbtVoid, EbpUndefined); - $$ = new TField(type, $1.string, @1); + $$ = context->parseStructDeclarator($1.string, @1); } - | identifier LEFT_BRACKET constant_expression RIGHT_BRACKET { - if (context->reservedErrorCheck(@1, *$1.string)) - context->recover(); - - TType* type = new TType(EbtVoid, EbpUndefined); - int size; - if (context->arraySizeErrorCheck(@3, $3, size)) - context->recover(); - type->setArraySize(size); - - $$ = new TField(type, $1.string, @1); + | identifier array_specifier { + $$ = context->parseStructArrayDeclarator($1.string, @1, *($2), @2); } ; @@ -1358,8 +1255,8 @@ declaration_statement ; statement - : compound_statement { $$ = $1; } - | simple_statement { $$ = $1; } + : compound_statement_with_scope { $$ = $1; } + | simple_statement { $$ = $1; } ; // Grammar Note: Labeled statements for SWITCH only; 'goto' is not supported. @@ -1374,13 +1271,13 @@ simple_statement | jump_statement { $$ = $1; } ; -compound_statement - : LEFT_BRACE RIGHT_BRACE { $$ = 0; } +compound_statement_with_scope + : LEFT_BRACE RIGHT_BRACE { + $$ = new TIntermBlock(); + $$->setLine(@$); + } | LEFT_BRACE { context->symbolTable.push(); } statement_list { context->symbolTable.pop(); } RIGHT_BRACE { - if ($3 != 0) { - $3->setOp(EOpSequence); - $3->setLine(@$); - } + $3->setLine(@$); $$ = $3; } ; @@ -1396,38 +1293,36 @@ statement_with_scope ; compound_statement_no_new_scope - // Statement that doesn't create a new scope, for selection_statement, iteration_statement + // Statement that doesn't create a new scope for iteration_statement, function definition (scope is created for parameters) : LEFT_BRACE RIGHT_BRACE { - $$ = 0; + $$ = new TIntermBlock(); + $$->setLine(@$); } | LEFT_BRACE statement_list RIGHT_BRACE { - if ($2) { - $2->setOp(EOpSequence); - $2->setLine(@$); - } + $2->setLine(@$); $$ = $2; } ; statement_list : statement { - $$ = context->intermediate.makeAggregate($1, @$); + $$ = new TIntermBlock(); + $$->appendStatement($1); } | statement_list statement { - $$ = context->intermediate.growAggregate($1, $2, @$); + $$ = $1; + $$->appendStatement($2); } ; expression_statement - : SEMICOLON { $$ = 0; } - | expression SEMICOLON { $$ = static_cast($1); } + : SEMICOLON { $$ = context->addEmptyStatement(@$); } + | expression SEMICOLON { $$ = $1; } ; selection_statement : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement { - if (context->boolErrorCheck(@1, $3)) - context->recover(); - $$ = context->intermediate.addSelection($3, $5, @1); + $$ = context->addIfElse($3, $5, @1); } ; @@ -1438,12 +1333,14 @@ selection_rest_statement } | statement_with_scope { $$.node1 = $1; - $$.node2 = 0; + $$.node2 = nullptr; } ; +// Note that we've diverged from the spec grammar here a bit for the sake of simplicity. +// We're reusing compound_statement_with_scope instead of having separate rules for switch. switch_statement - : SWITCH LEFT_PAREN expression RIGHT_PAREN { context->incrSwitchNestingLevel(); } compound_statement { + : SWITCH LEFT_PAREN expression RIGHT_PAREN { context->incrSwitchNestingLevel(); } compound_statement_with_scope { $$ = context->addSwitch($3, $6, @1); context->decrSwitchNestingLevel(); } @@ -1459,42 +1356,28 @@ case_label ; condition - // In 1996 c++ draft, conditions can include single declarations : expression { $$ = $1; - if (context->boolErrorCheck($1->getLine(), $1)) - context->recover(); + context->checkIsScalarBool($1->getLine(), $1); } | fully_specified_type identifier EQUAL initializer { - TIntermNode *intermNode; - if (context->boolErrorCheck(@2, $1)) - context->recover(); - - if (!context->executeInitializer(@2, *$2.string, $1, $4, &intermNode)) - $$ = $4; - else { - context->recover(); - $$ = 0; - } + $$ = context->addConditionInitializer($1, *$2.string, $4, @2); } ; iteration_statement : WHILE LEFT_PAREN { context->symbolTable.push(); context->incrLoopNestingLevel(); } condition RIGHT_PAREN statement_no_new_scope { context->symbolTable.pop(); - $$ = context->intermediate.addLoop(ELoopWhile, 0, $4, 0, $6, @1); + $$ = context->addLoop(ELoopWhile, 0, $4, 0, $6, @1); context->decrLoopNestingLevel(); } | DO { context->incrLoopNestingLevel(); } statement_with_scope WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON { - if (context->boolErrorCheck(@8, $6)) - context->recover(); - - $$ = context->intermediate.addLoop(ELoopDoWhile, 0, $6, 0, $3, @4); + $$ = context->addLoop(ELoopDoWhile, 0, $6, 0, $3, @4); context->decrLoopNestingLevel(); } | FOR LEFT_PAREN { context->symbolTable.push(); context->incrLoopNestingLevel(); } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope { context->symbolTable.pop(); - $$ = context->intermediate.addLoop(ELoopFor, $4, reinterpret_cast($5.node1), reinterpret_cast($5.node2), $7, @1); + $$ = context->addLoop(ELoopFor, $4, $5.node1, reinterpret_cast($5.node2), $7, @1); context->decrLoopNestingLevel(); } ; @@ -1513,7 +1396,7 @@ conditionopt $$ = $1; } | /* May be null */ { - $$ = 0; + $$ = nullptr; } ; @@ -1542,7 +1425,6 @@ jump_statement $$ = context->addBranch(EOpReturn, $2, @1); } | DISCARD SEMICOLON { - FRAG_ONLY("discard", @1); $$ = context->addBranch(EOpKill, @1); } ; @@ -1551,12 +1433,13 @@ jump_statement translation_unit : external_declaration { - $$ = $1; + $$ = new TIntermBlock(); + $$->setLine(@$); + $$->appendStatement($1); context->setTreeRoot($$); } | translation_unit external_declaration { - $$ = context->intermediate.growAggregate($1, $2, @$); - context->setTreeRoot($$); + $$->appendStatement($2); } ; @@ -1571,10 +1454,10 @@ external_declaration function_definition : function_prototype { - context->parseFunctionPrototype(@1, $1.function, &$1.intermAggregate); + context->parseFunctionDefinitionHeader(@1, &($1.function), &($1.intermFunctionPrototype)); } compound_statement_no_new_scope { - $$ = context->addFunctionDefinition(*($1.function), $1.intermAggregate, $3, @1); + $$ = context->addFunctionDefinition($1.intermFunctionPrototype, $3, @1); } ; diff --git a/src/3rdparty/angle/src/compiler/translator/intermOut.cpp b/src/3rdparty/angle/src/compiler/translator/intermOut.cpp deleted file mode 100644 index 6dca547f08..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/intermOut.cpp +++ /dev/null @@ -1,626 +0,0 @@ -// -// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/translator/Intermediate.h" -#include "compiler/translator/SymbolTable.h" - -namespace -{ - -void OutputFunction(TInfoSinkBase &out, const char *str, TIntermAggregate *node) -{ - const char *internal = node->getNameObj().isInternal() ? " (internal function)" : ""; - out << str << internal << ": " << node->getNameObj().getString(); -} - -// -// Two purposes: -// 1. Show an example of how to iterate tree. Functions can -// also directly call Traverse() on children themselves to -// have finer grained control over the process than shown here. -// See the last function for how to get started. -// 2. Print out a text based description of the tree. -// - -// -// Use this class to carry along data from node to node in -// the traversal -// -class TOutputTraverser : public TIntermTraverser -{ - public: - TOutputTraverser(TInfoSinkBase &i) - : TIntermTraverser(true, false, false), - sink(i) - { - } - TInfoSinkBase& sink; - - protected: - void visitSymbol(TIntermSymbol *) override; - void visitConstantUnion(TIntermConstantUnion *) override; - bool visitBinary(Visit visit, TIntermBinary *) override; - bool visitUnary(Visit visit, TIntermUnary *) override; - bool visitSelection(Visit visit, TIntermSelection *) override; - bool visitAggregate(Visit visit, TIntermAggregate *) override; - bool visitLoop(Visit visit, TIntermLoop *) override; - bool visitBranch(Visit visit, TIntermBranch *) override; -}; - -// -// Helper functions for printing, not part of traversing. -// -void OutputTreeText(TInfoSinkBase &sink, TIntermNode *node, const int depth) -{ - int i; - - sink.location(node->getLine()); - - for (i = 0; i < depth; ++i) - sink << " "; -} - -} // namespace anonymous - -// -// The rest of the file are the traversal functions. The last one -// is the one that starts the traversal. -// -// Return true from interior nodes to have the external traversal -// continue on to children. If you process children yourself, -// return false. -// - -void TOutputTraverser::visitSymbol(TIntermSymbol *node) -{ - OutputTreeText(sink, node, mDepth); - - sink << "'" << node->getSymbol() << "' "; - sink << "(" << node->getCompleteString() << ")\n"; -} - -bool TOutputTraverser::visitBinary(Visit visit, TIntermBinary *node) -{ - TInfoSinkBase& out = sink; - - OutputTreeText(out, node, mDepth); - - switch (node->getOp()) - { - case EOpAssign: - out << "move second child to first child"; - break; - case EOpInitialize: - out << "initialize first child with second child"; - break; - case EOpAddAssign: - out << "add second child into first child"; - break; - case EOpSubAssign: - out << "subtract second child into first child"; - break; - case EOpMulAssign: - out << "multiply second child into first child"; - break; - case EOpVectorTimesMatrixAssign: - out << "matrix mult second child into first child"; - break; - case EOpVectorTimesScalarAssign: - out << "vector scale second child into first child"; - break; - case EOpMatrixTimesScalarAssign: - out << "matrix scale second child into first child"; - break; - case EOpMatrixTimesMatrixAssign: - out << "matrix mult second child into first child"; - break; - case EOpDivAssign: - out << "divide second child into first child"; - break; - case EOpIModAssign: - out << "modulo second child into first child"; - break; - case EOpBitShiftLeftAssign: - out << "bit-wise shift first child left by second child"; - break; - case EOpBitShiftRightAssign: - out << "bit-wise shift first child right by second child"; - break; - case EOpBitwiseAndAssign: - out << "bit-wise and second child into first child"; - break; - case EOpBitwiseXorAssign: - out << "bit-wise xor second child into first child"; - break; - case EOpBitwiseOrAssign: - out << "bit-wise or second child into first child"; - break; - - case EOpIndexDirect: - out << "direct index"; - break; - case EOpIndexIndirect: - out << "indirect index"; - break; - case EOpIndexDirectStruct: - out << "direct index for structure"; - break; - case EOpIndexDirectInterfaceBlock: - out << "direct index for interface block"; - break; - case EOpVectorSwizzle: - out << "vector swizzle"; - break; - - case EOpAdd: - out << "add"; - break; - case EOpSub: - out << "subtract"; - break; - case EOpMul: - out << "component-wise multiply"; - break; - case EOpDiv: - out << "divide"; - break; - case EOpIMod: - out << "modulo"; - break; - case EOpBitShiftLeft: - out << "bit-wise shift left"; - break; - case EOpBitShiftRight: - out << "bit-wise shift right"; - break; - case EOpBitwiseAnd: - out << "bit-wise and"; - break; - case EOpBitwiseXor: - out << "bit-wise xor"; - break; - case EOpBitwiseOr: - out << "bit-wise or"; - break; - - case EOpEqual: - out << "Compare Equal"; - break; - case EOpNotEqual: - out << "Compare Not Equal"; - break; - case EOpLessThan: - out << "Compare Less Than"; - break; - case EOpGreaterThan: - out << "Compare Greater Than"; - break; - case EOpLessThanEqual: - out << "Compare Less Than or Equal"; - break; - case EOpGreaterThanEqual: - out << "Compare Greater Than or Equal"; - break; - - case EOpVectorTimesScalar: - out << "vector-scale"; - break; - case EOpVectorTimesMatrix: - out << "vector-times-matrix"; - break; - case EOpMatrixTimesVector: - out << "matrix-times-vector"; - break; - case EOpMatrixTimesScalar: - out << "matrix-scale"; - break; - case EOpMatrixTimesMatrix: - out << "matrix-multiply"; - break; - - case EOpLogicalOr: - out << "logical-or"; - break; - case EOpLogicalXor: - out << "logical-xor"; - break; - case EOpLogicalAnd: - out << "logical-and"; - break; - default: - out << ""; - } - - out << " (" << node->getCompleteString() << ")"; - - out << "\n"; - - // Special handling for direct indexes. Because constant - // unions are not aware they are struct indexes, treat them - // here where we have that contextual knowledge. - if (node->getOp() == EOpIndexDirectStruct || - node->getOp() == EOpIndexDirectInterfaceBlock) - { - mDepth++; - node->getLeft()->traverse(this); - mDepth--; - - TIntermConstantUnion *intermConstantUnion = node->getRight()->getAsConstantUnion(); - ASSERT(intermConstantUnion); - - OutputTreeText(out, intermConstantUnion, mDepth + 1); - - // The following code finds the field name from the constant union - const TConstantUnion *constantUnion = intermConstantUnion->getUnionArrayPointer(); - const TStructure *structure = node->getLeft()->getType().getStruct(); - const TInterfaceBlock *interfaceBlock = node->getLeft()->getType().getInterfaceBlock(); - ASSERT(structure || interfaceBlock); - - const TFieldList &fields = structure ? structure->fields() : interfaceBlock->fields(); - - const TField *field = fields[constantUnion->getIConst()]; - - out << constantUnion->getIConst() << " (field '" << field->name() << "')"; - - return false; - } - - return true; -} - -bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary *node) -{ - TInfoSinkBase& out = sink; - - OutputTreeText(out, node, mDepth); - - switch (node->getOp()) - { - case EOpNegative: out << "Negate value"; break; - case EOpPositive: out << "Positive sign"; break; - case EOpVectorLogicalNot: - case EOpLogicalNot: out << "Negate conditional"; break; - case EOpBitwiseNot: out << "bit-wise not"; break; - - case EOpPostIncrement: out << "Post-Increment"; break; - case EOpPostDecrement: out << "Post-Decrement"; break; - case EOpPreIncrement: out << "Pre-Increment"; break; - case EOpPreDecrement: out << "Pre-Decrement"; break; - - case EOpRadians: out << "radians"; break; - case EOpDegrees: out << "degrees"; break; - case EOpSin: out << "sine"; break; - case EOpCos: out << "cosine"; break; - case EOpTan: out << "tangent"; break; - case EOpAsin: out << "arc sine"; break; - case EOpAcos: out << "arc cosine"; break; - case EOpAtan: out << "arc tangent"; break; - - case EOpSinh: out << "hyperbolic sine"; break; - case EOpCosh: out << "hyperbolic cosine"; break; - case EOpTanh: out << "hyperbolic tangent"; break; - case EOpAsinh: out << "arc hyperbolic sine"; break; - case EOpAcosh: out << "arc hyperbolic cosine"; break; - case EOpAtanh: out << "arc hyperbolic tangent"; break; - - case EOpExp: out << "exp"; break; - case EOpLog: out << "log"; break; - case EOpExp2: out << "exp2"; break; - case EOpLog2: out << "log2"; break; - case EOpSqrt: out << "sqrt"; break; - case EOpInverseSqrt: out << "inverse sqrt"; break; - - case EOpAbs: out << "Absolute value"; break; - case EOpSign: out << "Sign"; break; - case EOpFloor: out << "Floor"; break; - case EOpTrunc: out << "Truncate"; break; - case EOpRound: out << "Round"; break; - case EOpRoundEven: out << "Round half even"; break; - case EOpCeil: out << "Ceiling"; break; - case EOpFract: out << "Fraction"; break; - case EOpIsNan: out << "Is not a number"; break; - case EOpIsInf: out << "Is infinity"; break; - - case EOpFloatBitsToInt: out << "float bits to int"; break; - case EOpFloatBitsToUint: out << "float bits to uint"; break; - case EOpIntBitsToFloat: out << "int bits to float"; break; - case EOpUintBitsToFloat: out << "uint bits to float"; break; - - case EOpPackSnorm2x16: out << "pack Snorm 2x16"; break; - case EOpPackUnorm2x16: out << "pack Unorm 2x16"; break; - case EOpPackHalf2x16: out << "pack half 2x16"; break; - - case EOpUnpackSnorm2x16: out << "unpack Snorm 2x16"; break; - case EOpUnpackUnorm2x16: out << "unpack Unorm 2x16"; break; - case EOpUnpackHalf2x16: out << "unpack half 2x16"; break; - - case EOpLength: out << "length"; break; - case EOpNormalize: out << "normalize"; break; - // case EOpDPdx: out << "dPdx"; break; - // case EOpDPdy: out << "dPdy"; break; - // case EOpFwidth: out << "fwidth"; break; - - case EOpDeterminant: out << "determinant"; break; - case EOpTranspose: out << "transpose"; break; - case EOpInverse: out << "inverse"; break; - - case EOpAny: out << "any"; break; - case EOpAll: out << "all"; break; - - default: - out.prefix(EPrefixError); - out << "Bad unary op"; - } - - out << " (" << node->getCompleteString() << ")"; - - out << "\n"; - - return true; -} - -bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate *node) -{ - TInfoSinkBase &out = sink; - - if (node->getOp() == EOpNull) - { - out.prefix(EPrefixError); - out << "node is still EOpNull!"; - return true; - } - - OutputTreeText(out, node, mDepth); - - switch (node->getOp()) - { - case EOpSequence: out << "Sequence\n"; return true; - case EOpComma: out << "Comma\n"; return true; - case EOpFunction: OutputFunction(out, "Function Definition", node); break; - case EOpFunctionCall: OutputFunction(out, "Function Call", node); break; - case EOpParameters: out << "Function Parameters: "; break; - case EOpPrototype: OutputFunction(out, "Function Prototype", node); break; - - case EOpConstructFloat: out << "Construct float"; break; - case EOpConstructVec2: out << "Construct vec2"; break; - case EOpConstructVec3: out << "Construct vec3"; break; - case EOpConstructVec4: out << "Construct vec4"; break; - case EOpConstructBool: out << "Construct bool"; break; - case EOpConstructBVec2: out << "Construct bvec2"; break; - case EOpConstructBVec3: out << "Construct bvec3"; break; - case EOpConstructBVec4: out << "Construct bvec4"; break; - case EOpConstructInt: out << "Construct int"; break; - case EOpConstructIVec2: out << "Construct ivec2"; break; - case EOpConstructIVec3: out << "Construct ivec3"; break; - case EOpConstructIVec4: out << "Construct ivec4"; break; - case EOpConstructUInt: out << "Construct uint"; break; - case EOpConstructUVec2: out << "Construct uvec2"; break; - case EOpConstructUVec3: out << "Construct uvec3"; break; - case EOpConstructUVec4: out << "Construct uvec4"; break; - case EOpConstructMat2: out << "Construct mat2"; break; - case EOpConstructMat2x3: out << "Construct mat2x3"; break; - case EOpConstructMat2x4: out << "Construct mat2x4"; break; - case EOpConstructMat3x2: out << "Construct mat3x2"; break; - case EOpConstructMat3: out << "Construct mat3"; break; - case EOpConstructMat3x4: out << "Construct mat3x4"; break; - case EOpConstructMat4x2: out << "Construct mat4x2"; break; - case EOpConstructMat4x3: out << "Construct mat4x3"; break; - case EOpConstructMat4: out << "Construct mat4"; break; - case EOpConstructStruct: out << "Construct structure"; break; - - case EOpLessThan: out << "Compare Less Than"; break; - case EOpGreaterThan: out << "Compare Greater Than"; break; - case EOpLessThanEqual: out << "Compare Less Than or Equal"; break; - case EOpGreaterThanEqual: out << "Compare Greater Than or Equal"; break; - case EOpVectorEqual: out << "Equal"; break; - case EOpVectorNotEqual: out << "NotEqual"; break; - - case EOpMod: out << "mod"; break; - case EOpModf: out << "modf"; break; - case EOpPow: out << "pow"; break; - - case EOpAtan: out << "arc tangent"; break; - - case EOpMin: out << "min"; break; - case EOpMax: out << "max"; break; - case EOpClamp: out << "clamp"; break; - case EOpMix: out << "mix"; break; - case EOpStep: out << "step"; break; - case EOpSmoothStep: out << "smoothstep"; break; - - case EOpDistance: out << "distance"; break; - case EOpDot: out << "dot-product"; break; - case EOpCross: out << "cross-product"; break; - case EOpFaceForward: out << "face-forward"; break; - case EOpReflect: out << "reflect"; break; - case EOpRefract: out << "refract"; break; - case EOpMul: out << "component-wise multiply"; break; - - case EOpOuterProduct: out << "outer product"; break; - - case EOpDeclaration: out << "Declaration: "; break; - case EOpInvariantDeclaration: out << "Invariant Declaration: "; break; - - default: - out.prefix(EPrefixError); - out << "Bad aggregation op"; - } - - if (node->getOp() != EOpSequence && node->getOp() != EOpParameters) - out << " (" << node->getCompleteString() << ")"; - - out << "\n"; - - return true; -} - -bool TOutputTraverser::visitSelection(Visit visit, TIntermSelection *node) -{ - TInfoSinkBase &out = sink; - - OutputTreeText(out, node, mDepth); - - out << "Test condition and select"; - out << " (" << node->getCompleteString() << ")\n"; - - ++mDepth; - - OutputTreeText(sink, node, mDepth); - out << "Condition\n"; - node->getCondition()->traverse(this); - - OutputTreeText(sink, node, mDepth); - if (node->getTrueBlock()) - { - out << "true case\n"; - node->getTrueBlock()->traverse(this); - } - else - { - out << "true case is null\n"; - } - - if (node->getFalseBlock()) - { - OutputTreeText(sink, node, mDepth); - out << "false case\n"; - node->getFalseBlock()->traverse(this); - } - - --mDepth; - - return false; -} - -void TOutputTraverser::visitConstantUnion(TIntermConstantUnion *node) -{ - TInfoSinkBase &out = sink; - - size_t size = node->getType().getObjectSize(); - - for (size_t i = 0; i < size; i++) - { - OutputTreeText(out, node, mDepth); - switch (node->getUnionArrayPointer()[i].getType()) - { - case EbtBool: - if (node->getUnionArrayPointer()[i].getBConst()) - out << "true"; - else - out << "false"; - - out << " (" << "const bool" << ")"; - out << "\n"; - break; - case EbtFloat: - out << node->getUnionArrayPointer()[i].getFConst(); - out << " (const float)\n"; - break; - case EbtInt: - out << node->getUnionArrayPointer()[i].getIConst(); - out << " (const int)\n"; - break; - case EbtUInt: - out << node->getUnionArrayPointer()[i].getUConst(); - out << " (const uint)\n"; - break; - default: - out.message(EPrefixInternalError, node->getLine(), "Unknown constant"); - break; - } - } -} - -bool TOutputTraverser::visitLoop(Visit visit, TIntermLoop *node) -{ - TInfoSinkBase &out = sink; - - OutputTreeText(out, node, mDepth); - - out << "Loop with condition "; - if (node->getType() == ELoopDoWhile) - out << "not "; - out << "tested first\n"; - - ++mDepth; - - OutputTreeText(sink, node, mDepth); - if (node->getCondition()) - { - out << "Loop Condition\n"; - node->getCondition()->traverse(this); - } - else - { - out << "No loop condition\n"; - } - - OutputTreeText(sink, node, mDepth); - if (node->getBody()) - { - out << "Loop Body\n"; - node->getBody()->traverse(this); - } - else - { - out << "No loop body\n"; - } - - if (node->getExpression()) - { - OutputTreeText(sink, node, mDepth); - out << "Loop Terminal Expression\n"; - node->getExpression()->traverse(this); - } - - --mDepth; - - return false; -} - -bool TOutputTraverser::visitBranch(Visit visit, TIntermBranch *node) -{ - TInfoSinkBase &out = sink; - - OutputTreeText(out, node, mDepth); - - switch (node->getFlowOp()) - { - case EOpKill: out << "Branch: Kill"; break; - case EOpBreak: out << "Branch: Break"; break; - case EOpContinue: out << "Branch: Continue"; break; - case EOpReturn: out << "Branch: Return"; break; - default: out << "Branch: Unknown Branch"; break; - } - - if (node->getExpression()) - { - out << " with expression\n"; - ++mDepth; - node->getExpression()->traverse(this); - --mDepth; - } - else - { - out << "\n"; - } - - return false; -} - -// -// This function is the one to call externally to start the traversal. -// Individual functions can be initialized to 0 to skip processing of that -// type of node. Its children will still be processed. -// -void TIntermediate::outputTree(TIntermNode *root, TInfoSinkBase &infoSink) -{ - TOutputTraverser it(infoSink); - - ASSERT(root); - - root->traverse(&it); -} diff --git a/src/3rdparty/angle/src/compiler/translator/length_limits.h b/src/3rdparty/angle/src/compiler/translator/length_limits.h index 88634381fa..fcda639d71 100644 --- a/src/3rdparty/angle/src/compiler/translator/length_limits.h +++ b/src/3rdparty/angle/src/compiler/translator/length_limits.h @@ -16,6 +16,11 @@ // These constants are factored out from the rest of the headers to // make it easier to reference them from the compiler sources. +namespace sh +{ + size_t GetGlobalMaxTokenSize(ShShaderSpec spec); -#endif // COMPILER_TRANSLATOR_LENGTHLIMITS_H_ +} // namespace sh + +#endif // COMPILER_TRANSLATOR_LENGTHLIMITS_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/parseConst.cpp b/src/3rdparty/angle/src/compiler/translator/parseConst.cpp deleted file mode 100644 index 1897ed151c..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/parseConst.cpp +++ /dev/null @@ -1,264 +0,0 @@ -// -// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/translator/ParseContext.h" - -// -// Use this class to carry along data from node to node in -// the traversal -// -class TConstTraverser : public TIntermTraverser -{ - public: - TConstTraverser(ConstantUnion *cUnion, bool singleConstParam, - TOperator constructType, TInfoSink &sink, TType &t) - : error(false), - mIndex(0), - mUnionArray(cUnion), - mType(t), - mConstructorType(constructType), - mSingleConstantParam(singleConstParam), - mInfoSink(sink), - mSize(0), - mIsDiagonalMatrixInit(false), - mMatrixCols(0), - mMatrixRows(0) - { - } - - bool error; - - protected: - void visitSymbol(TIntermSymbol *); - void visitConstantUnion(TIntermConstantUnion *); - bool visitBinary(Visit visit, TIntermBinary *); - bool visitUnary(Visit visit, TIntermUnary *); - bool visitSelection(Visit visit, TIntermSelection *); - bool visitAggregate(Visit visit, TIntermAggregate *); - bool visitLoop(Visit visit, TIntermLoop *); - bool visitBranch(Visit visit, TIntermBranch *); - - size_t mIndex; - ConstantUnion *mUnionArray; - TType mType; - TOperator mConstructorType; - bool mSingleConstantParam; - TInfoSink &mInfoSink; - size_t mSize; // size of the constructor ( 4 for vec4) - bool mIsDiagonalMatrixInit; - int mMatrixCols; // columns of the matrix - int mMatrixRows; // rows of the matrix -}; - -// -// The rest of the file are the traversal functions. The last one -// is the one that starts the traversal. -// -// Return true from interior nodes to have the external traversal -// continue on to children. If you process children yourself, -// return false. -// -void TConstTraverser::visitSymbol(TIntermSymbol *node) -{ - mInfoSink.info.message(EPrefixInternalError, node->getLine(), - "Symbol Node found in constant constructor"); - return; -} - -bool TConstTraverser::visitBinary(Visit visit, TIntermBinary *node) -{ - TQualifier qualifier = node->getType().getQualifier(); - - if (qualifier != EvqConst) - { - TString buf; - buf.append("'constructor' : assigning non-constant to "); - buf.append(mType.getCompleteString()); - mInfoSink.info.message(EPrefixError, node->getLine(), buf.c_str()); - error = true; - return false; - } - - mInfoSink.info.message(EPrefixInternalError, node->getLine(), - "Binary Node found in constant constructor"); - return false; -} - -bool TConstTraverser::visitUnary(Visit visit, TIntermUnary *node) -{ - TString buf; - buf.append("'constructor' : assigning non-constant to "); - buf.append(mType.getCompleteString()); - mInfoSink.info.message(EPrefixError, node->getLine(), buf.c_str()); - error = true; - return false; -} - -bool TConstTraverser::visitAggregate(Visit visit, TIntermAggregate *node) -{ - if (!node->isConstructor() && node->getOp() != EOpComma) - { - TString buf; - buf.append("'constructor' : assigning non-constant to "); - buf.append(mType.getCompleteString()); - mInfoSink.info.message(EPrefixError, node->getLine(), buf.c_str()); - error = true; - return false; - } - - if (node->getSequence()->size() == 0) - { - error = true; - return false; - } - - bool flag = node->getSequence()->size() == 1 && - (*node->getSequence())[0]->getAsTyped()->getAsConstantUnion(); - if (flag) - { - mSingleConstantParam = true; - mConstructorType = node->getOp(); - mSize = node->getType().getObjectSize(); - - if (node->getType().isMatrix()) - { - mIsDiagonalMatrixInit = true; - mMatrixCols = node->getType().getCols(); - mMatrixRows = node->getType().getRows(); - } - } - - for (TIntermSequence::iterator p = node->getSequence()->begin(); - p != node->getSequence()->end(); p++) - { - if (node->getOp() == EOpComma) - mIndex = 0; - (*p)->traverse(this); - } - if (flag) - { - mSingleConstantParam = false; - mConstructorType = EOpNull; - mSize = 0; - mIsDiagonalMatrixInit = false; - mMatrixCols = 0; - mMatrixRows = 0; - } - return false; -} - -bool TConstTraverser::visitSelection(Visit visit, TIntermSelection *node) -{ - mInfoSink.info.message(EPrefixInternalError, node->getLine(), - "Selection Node found in constant constructor"); - error = true; - return false; -} - -void TConstTraverser::visitConstantUnion(TIntermConstantUnion *node) -{ - if (!node->getUnionArrayPointer()) - { - // The constant was not initialized, this should already have been logged - ASSERT(mInfoSink.info.size() != 0); - return; - } - - ConstantUnion *leftUnionArray = mUnionArray; - size_t instanceSize = mType.getObjectSize(); - TBasicType basicType = mType.getBasicType(); - - if (mIndex >= instanceSize) - return; - - if (!mSingleConstantParam) - { - size_t objectSize = node->getType().getObjectSize(); - ConstantUnion *rightUnionArray = node->getUnionArrayPointer(); - for (size_t i=0; i < objectSize; i++) - { - if (mIndex >= instanceSize) - return; - leftUnionArray[mIndex].cast(basicType, rightUnionArray[i]); - mIndex++; - } - } - else - { - size_t totalSize = mIndex + mSize; - ConstantUnion *rightUnionArray = node->getUnionArrayPointer(); - if (!mIsDiagonalMatrixInit) - { - int count = 0; - for (size_t i = mIndex; i < totalSize; i++) - { - if (i >= instanceSize) - return; - leftUnionArray[i].cast(basicType, rightUnionArray[count]); - mIndex++; - if (node->getType().getObjectSize() > 1) - count++; - } - } - else - { - // for matrix diagonal constructors from a single scalar - for (int i = 0, col = 0; col < mMatrixCols; col++) - { - for (int row = 0; row < mMatrixRows; row++, i++) - { - if (col == row) - { - leftUnionArray[i].cast(basicType, rightUnionArray[0]); - } - else - { - leftUnionArray[i].setFConst(0.0f); - } - mIndex++; - } - } - } - } -} - -bool TConstTraverser::visitLoop(Visit visit, TIntermLoop *node) -{ - mInfoSink.info.message(EPrefixInternalError, node->getLine(), - "Loop Node found in constant constructor"); - error = true; - return false; -} - -bool TConstTraverser::visitBranch(Visit visit, TIntermBranch *node) -{ - mInfoSink.info.message(EPrefixInternalError, node->getLine(), - "Branch Node found in constant constructor"); - error = true; - return false; -} - -// -// This function is the one to call externally to start the traversal. -// Individual functions can be initialized to 0 to skip processing of that -// type of node. It's children will still be processed. -// -bool TIntermediate::parseConstTree( - const TSourceLoc &line, TIntermNode *root, ConstantUnion *unionArray, - TOperator constructorType, TType t, bool singleConstantParam) -{ - if (root == 0) - return false; - - TConstTraverser it(unionArray, singleConstantParam, constructorType, - mInfoSink, t); - - root->traverse(&it); - if (it.error) - return true; - else - return false; -} diff --git a/src/3rdparty/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp b/src/3rdparty/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp deleted file mode 100644 index 790974a2bf..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp +++ /dev/null @@ -1,130 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/translator/InfoSink.h" -#include "compiler/translator/ParseContext.h" -#include "compiler/translator/depgraph/DependencyGraphOutput.h" -#include "compiler/translator/timing/RestrictFragmentShaderTiming.h" - -RestrictFragmentShaderTiming::RestrictFragmentShaderTiming(TInfoSinkBase& sink) - : mSink(sink) - , mNumErrors(0) -{ - // Sampling ops found only in fragment shaders. - mSamplingOps.insert("texture2D(s21;vf2;f1;"); - mSamplingOps.insert("texture2DProj(s21;vf3;f1;"); - mSamplingOps.insert("texture2DProj(s21;vf4;f1;"); - mSamplingOps.insert("textureCube(sC1;vf3;f1;"); - // Sampling ops found in both vertex and fragment shaders. - mSamplingOps.insert("texture2D(s21;vf2;"); - mSamplingOps.insert("texture2DProj(s21;vf3;"); - mSamplingOps.insert("texture2DProj(s21;vf4;"); - mSamplingOps.insert("textureCube(sC1;vf3;"); - // Sampling ops provided by OES_EGL_image_external. - mSamplingOps.insert("texture2D(1;vf2;"); - mSamplingOps.insert("texture2DProj(1;vf3;"); - mSamplingOps.insert("texture2DProj(1;vf4;"); - // Sampling ops provided by ARB_texture_rectangle. - mSamplingOps.insert("texture2DRect(1;vf2;"); - mSamplingOps.insert("texture2DRectProj(1;vf3;"); - mSamplingOps.insert("texture2DRectProj(1;vf4;"); - // Sampling ops provided by EXT_shader_texture_lod. - mSamplingOps.insert("texture2DLodEXT(1;vf2;f1;"); - mSamplingOps.insert("texture2DProjLodEXT(1;vf3;f1;"); - mSamplingOps.insert("texture2DProjLodEXT(1;vf4;f1;"); - mSamplingOps.insert("textureCubeLodEXT(1;vf4;f1;"); - mSamplingOps.insert("texture2DGradEXT(1;vf2;vf2;vf2;"); - mSamplingOps.insert("texture2DProjGradEXT(1;vf3;vf2;vf2;"); - mSamplingOps.insert("texture2DProjGradEXT(1;vf4;vf2;vf2;"); - mSamplingOps.insert("textureCubeGradEXT(1;vf3;vf3;vf3;"); -} - -// FIXME(mvujovic): We do not know if the execution time of built-in operations like sin, pow, etc. -// can vary based on the value of the input arguments. If so, we should restrict those as well. -void RestrictFragmentShaderTiming::enforceRestrictions(const TDependencyGraph& graph) -{ - mNumErrors = 0; - - // FIXME(mvujovic): The dependency graph does not support user defined function calls right now, - // so we generate errors for them. - validateUserDefinedFunctionCallUsage(graph); - - // Starting from each sampler, traverse the dependency graph and generate an error each time we - // hit a node where sampler dependent values are not allowed. - for (auto samplerSymbol : graph.samplerSymbols()) - { - clearVisited(); - samplerSymbol->traverse(this); - } -} - -void RestrictFragmentShaderTiming::validateUserDefinedFunctionCallUsage(const TDependencyGraph& graph) -{ - for (const auto* functionCall : graph.userDefinedFunctionCalls()) - { - beginError(functionCall->getIntermFunctionCall()); - mSink << "A call to a user defined function is not permitted.\n"; - } -} - -void RestrictFragmentShaderTiming::beginError(const TIntermNode* node) -{ - ++mNumErrors; - mSink.prefix(EPrefixError); - mSink.location(node->getLine()); -} - -bool RestrictFragmentShaderTiming::isSamplingOp(const TIntermAggregate* intermFunctionCall) const -{ - return !intermFunctionCall->isUserDefined() && - mSamplingOps.find(intermFunctionCall->getName()) != mSamplingOps.end(); -} - -void RestrictFragmentShaderTiming::visitArgument(TGraphArgument* parameter) -{ - // Texture cache access time might leak sensitive information. - // Thus, we restrict sampler dependent values from affecting the coordinate or LOD bias of a - // sampling operation. - if (isSamplingOp(parameter->getIntermFunctionCall())) { - switch (parameter->getArgumentNumber()) { - case 1: - // Second argument (coord) - beginError(parameter->getIntermFunctionCall()); - mSink << "An expression dependent on a sampler is not permitted to be the" - << " coordinate argument of a sampling operation.\n"; - break; - case 2: - // Third argument (bias) - beginError(parameter->getIntermFunctionCall()); - mSink << "An expression dependent on a sampler is not permitted to be the" - << " bias argument of a sampling operation.\n"; - break; - default: - // First argument (sampler) - break; - } - } -} - -void RestrictFragmentShaderTiming::visitSelection(TGraphSelection* selection) -{ - beginError(selection->getIntermSelection()); - mSink << "An expression dependent on a sampler is not permitted in a conditional statement.\n"; -} - -void RestrictFragmentShaderTiming::visitLoop(TGraphLoop* loop) -{ - beginError(loop->getIntermLoop()); - mSink << "An expression dependent on a sampler is not permitted in a loop condition.\n"; -} - -void RestrictFragmentShaderTiming::visitLogicalOp(TGraphLogicalOp* logicalOp) -{ - beginError(logicalOp->getIntermLogicalOp()); - mSink << "An expression dependent on a sampler is not permitted on the left hand side of a logical " - << logicalOp->getOpString() - << " operator.\n"; -} diff --git a/src/3rdparty/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.h b/src/3rdparty/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.h deleted file mode 100644 index b8c7e82956..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/timing/RestrictFragmentShaderTiming.h +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_TRANSLATOR_TIMING_RESTRICTFRAGMENTSHADERTIMING_H_ -#define COMPILER_TRANSLATOR_TIMING_RESTRICTFRAGMENTSHADERTIMING_H_ - -#include "compiler/translator/IntermNode.h" -#include "compiler/translator/depgraph/DependencyGraph.h" - -class TInfoSinkBase; - -class RestrictFragmentShaderTiming : TDependencyGraphTraverser -{ - public: - RestrictFragmentShaderTiming(TInfoSinkBase &sink); - void enforceRestrictions(const TDependencyGraph &graph); - int numErrors() const { return mNumErrors; } - - void visitArgument(TGraphArgument *parameter) override; - void visitSelection(TGraphSelection *selection) override; - void visitLoop(TGraphLoop *loop) override; - void visitLogicalOp(TGraphLogicalOp *logicalOp) override; - - private: - void beginError(const TIntermNode *node); - void validateUserDefinedFunctionCallUsage(const TDependencyGraph &graph); - bool isSamplingOp(const TIntermAggregate *intermFunctionCall) const; - - TInfoSinkBase &mSink; - int mNumErrors; - - typedef std::set StringSet; - StringSet mSamplingOps; -}; - -#endif // COMPILER_TRANSLATOR_TIMING_RESTRICTFRAGMENTSHADERTIMING_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp b/src/3rdparty/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp deleted file mode 100644 index 7c1208a298..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#include "compiler/translator/timing/RestrictVertexShaderTiming.h" - -void RestrictVertexShaderTiming::visitSymbol(TIntermSymbol* node) -{ - if (IsSampler(node->getBasicType())) { - ++mNumErrors; - mSink.message(EPrefixError, - node->getLine(), - "Samplers are not permitted in vertex shaders.\n"); - } -} diff --git a/src/3rdparty/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.h b/src/3rdparty/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.h deleted file mode 100644 index 23a8217722..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/timing/RestrictVertexShaderTiming.h +++ /dev/null @@ -1,32 +0,0 @@ -// -// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -#ifndef COMPILER_TRANSLATOR_TIMING_RESTRICTVERTEXSHADERTIMING_H_ -#define COMPILER_TRANSLATOR_TIMING_RESTRICTVERTEXSHADERTIMING_H_ - -#include "compiler/translator/IntermNode.h" -#include "compiler/translator/InfoSink.h" - -class TInfoSinkBase; - -class RestrictVertexShaderTiming : public TIntermTraverser { -public: - RestrictVertexShaderTiming(TInfoSinkBase& sink) - : TIntermTraverser(true, false, false) - , mSink(sink) - , mNumErrors(0) {} - - void enforceRestrictions(TIntermNode* root) { root->traverse(this); } - int numErrors() { return mNumErrors; } - - void visitSymbol(TIntermSymbol *) override; - -private: - TInfoSinkBase& mSink; - int mNumErrors; -}; - -#endif // COMPILER_TRANSLATOR_TIMING_RESTRICTVERTEXSHADERTIMING_H_ diff --git a/src/3rdparty/angle/src/compiler/translator/util.cpp b/src/3rdparty/angle/src/compiler/translator/util.cpp index 0131137206..9738370c47 100644 --- a/src/3rdparty/angle/src/compiler/translator/util.cpp +++ b/src/3rdparty/angle/src/compiler/translator/util.cpp @@ -8,17 +8,9 @@ #include +#include "common/utilities.h" #include "compiler/preprocessor/numeric_lex.h" #include "compiler/translator/SymbolTable.h" -#include "common/utilities.h" - -bool strtof_clamp(const std::string &str, float *value) -{ - bool success = pp::numeric_lex_float(str, value); - if (!success) - *value = std::numeric_limits::max(); - return success; -} bool atoi_clamp(const char *str, unsigned int *value) { @@ -31,135 +23,392 @@ bool atoi_clamp(const char *str, unsigned int *value) namespace sh { +namespace +{ + +bool IsInterpolationIn(TQualifier qualifier) +{ + switch (qualifier) + { + case EvqSmoothIn: + case EvqFlatIn: + case EvqCentroidIn: + return true; + default: + return false; + } +} + +} // anonymous namespace + +float NumericLexFloat32OutOfRangeToInfinity(const std::string &str) +{ + // Parses a decimal string using scientific notation into a floating point number. + // Out-of-range values are converted to infinity. Values that are too small to be + // represented are converted to zero. + + // The mantissa in decimal scientific notation. The magnitude of the mantissa integer does not + // matter. + unsigned int decimalMantissa = 0; + size_t i = 0; + bool decimalPointSeen = false; + bool nonZeroSeenInMantissa = false; + + // The exponent offset reflects the position of the decimal point. + int exponentOffset = -1; + while (i < str.length()) + { + const char c = str[i]; + if (c == 'e' || c == 'E') + { + break; + } + if (c == '.') + { + decimalPointSeen = true; + ++i; + continue; + } + + unsigned int digit = static_cast(c - '0'); + ASSERT(digit < 10u); + if (digit != 0u) + { + nonZeroSeenInMantissa = true; + } + if (nonZeroSeenInMantissa) + { + // Add bits to the mantissa until space runs out in 32-bit int. This should be + // enough precision to make the resulting binary mantissa accurate to 1 ULP. + if (decimalMantissa <= (std::numeric_limits::max() - 9u) / 10u) + { + decimalMantissa = decimalMantissa * 10u + digit; + } + if (!decimalPointSeen) + { + ++exponentOffset; + } + } + else if (decimalPointSeen) + { + --exponentOffset; + } + ++i; + } + if (decimalMantissa == 0) + { + return 0.0f; + } + int exponent = 0; + if (i < str.length()) + { + ASSERT(str[i] == 'e' || str[i] == 'E'); + ++i; + bool exponentOutOfRange = false; + bool negativeExponent = false; + if (str[i] == '-') + { + negativeExponent = true; + ++i; + } + else if (str[i] == '+') + { + ++i; + } + while (i < str.length()) + { + const char c = str[i]; + unsigned int digit = static_cast(c - '0'); + ASSERT(digit < 10u); + if (exponent <= (std::numeric_limits::max() - 9) / 10) + { + exponent = exponent * 10 + digit; + } + else + { + exponentOutOfRange = true; + } + ++i; + } + if (negativeExponent) + { + exponent = -exponent; + } + if (exponentOutOfRange) + { + if (negativeExponent) + { + return 0.0f; + } + else + { + return std::numeric_limits::infinity(); + } + } + } + // Do the calculation in 64-bit to avoid overflow. + long long exponentLong = + static_cast(exponent) + static_cast(exponentOffset); + if (exponentLong > std::numeric_limits::max_exponent10) + { + return std::numeric_limits::infinity(); + } + else if (exponentLong < std::numeric_limits::min_exponent10) + { + return 0.0f; + } + // The exponent is in range, so we need to actually evaluate the float. + exponent = static_cast(exponentLong); + double value = decimalMantissa; + + // Calculate the exponent offset to normalize the mantissa. + int normalizationExponentOffset = 0; + while (decimalMantissa >= 10u) + { + --normalizationExponentOffset; + decimalMantissa /= 10u; + } + // Apply the exponent. + value *= std::pow(10.0, static_cast(exponent + normalizationExponentOffset)); + if (value > static_cast(std::numeric_limits::max())) + { + return std::numeric_limits::infinity(); + } + if (value < static_cast(std::numeric_limits::min())) + { + return 0.0f; + } + return static_cast(value); +} + +bool strtof_clamp(const std::string &str, float *value) +{ + // Try the standard float parsing path first. + bool success = pp::numeric_lex_float(str, value); + + // If the standard path doesn't succeed, take the path that can handle the following corner + // cases: + // 1. The decimal mantissa is very small but the exponent is very large, putting the resulting + // number inside the float range. + // 2. The decimal mantissa is very large but the exponent is very small, putting the resulting + // number inside the float range. + // 3. The value is out-of-range and should be evaluated as infinity. + // 4. The value is too small and should be evaluated as zero. + // See ESSL 3.00.6 section 4.1.4 for the relevant specification. + if (!success) + *value = NumericLexFloat32OutOfRangeToInfinity(str); + return !gl::isInf(*value); +} + GLenum GLVariableType(const TType &type) { if (type.getBasicType() == EbtFloat) { - if (type.isScalar()) - { - return GL_FLOAT; - } - else if (type.isVector()) + if (type.isVector()) { switch (type.getNominalSize()) { - case 2: return GL_FLOAT_VEC2; - case 3: return GL_FLOAT_VEC3; - case 4: return GL_FLOAT_VEC4; - default: UNREACHABLE(); + case 2: + return GL_FLOAT_VEC2; + case 3: + return GL_FLOAT_VEC3; + case 4: + return GL_FLOAT_VEC4; + default: + UNREACHABLE(); } } else if (type.isMatrix()) { switch (type.getCols()) { - case 2: - switch (type.getRows()) - { - case 2: return GL_FLOAT_MAT2; - case 3: return GL_FLOAT_MAT2x3; - case 4: return GL_FLOAT_MAT2x4; - default: UNREACHABLE(); - } + case 2: + switch (type.getRows()) + { + case 2: + return GL_FLOAT_MAT2; + case 3: + return GL_FLOAT_MAT2x3; + case 4: + return GL_FLOAT_MAT2x4; + default: + UNREACHABLE(); + } - case 3: - switch (type.getRows()) - { - case 2: return GL_FLOAT_MAT3x2; - case 3: return GL_FLOAT_MAT3; - case 4: return GL_FLOAT_MAT3x4; - default: UNREACHABLE(); - } + case 3: + switch (type.getRows()) + { + case 2: + return GL_FLOAT_MAT3x2; + case 3: + return GL_FLOAT_MAT3; + case 4: + return GL_FLOAT_MAT3x4; + default: + UNREACHABLE(); + } - case 4: - switch (type.getRows()) - { - case 2: return GL_FLOAT_MAT4x2; - case 3: return GL_FLOAT_MAT4x3; - case 4: return GL_FLOAT_MAT4; - default: UNREACHABLE(); - } + case 4: + switch (type.getRows()) + { + case 2: + return GL_FLOAT_MAT4x2; + case 3: + return GL_FLOAT_MAT4x3; + case 4: + return GL_FLOAT_MAT4; + default: + UNREACHABLE(); + } - default: UNREACHABLE(); + default: + UNREACHABLE(); } } - else UNREACHABLE(); + else + { + return GL_FLOAT; + } } else if (type.getBasicType() == EbtInt) { - if (type.isScalar()) - { - return GL_INT; - } - else if (type.isVector()) + if (type.isVector()) { switch (type.getNominalSize()) { - case 2: return GL_INT_VEC2; - case 3: return GL_INT_VEC3; - case 4: return GL_INT_VEC4; - default: UNREACHABLE(); + case 2: + return GL_INT_VEC2; + case 3: + return GL_INT_VEC3; + case 4: + return GL_INT_VEC4; + default: + UNREACHABLE(); } } - else UNREACHABLE(); + else + { + ASSERT(!type.isMatrix()); + return GL_INT; + } } else if (type.getBasicType() == EbtUInt) { - if (type.isScalar()) - { - return GL_UNSIGNED_INT; - } - else if (type.isVector()) + if (type.isVector()) { switch (type.getNominalSize()) { - case 2: return GL_UNSIGNED_INT_VEC2; - case 3: return GL_UNSIGNED_INT_VEC3; - case 4: return GL_UNSIGNED_INT_VEC4; - default: UNREACHABLE(); + case 2: + return GL_UNSIGNED_INT_VEC2; + case 3: + return GL_UNSIGNED_INT_VEC3; + case 4: + return GL_UNSIGNED_INT_VEC4; + default: + UNREACHABLE(); } } - else UNREACHABLE(); + else + { + ASSERT(!type.isMatrix()); + return GL_UNSIGNED_INT; + } } else if (type.getBasicType() == EbtBool) { - if (type.isScalar()) - { - return GL_BOOL; - } - else if (type.isVector()) + if (type.isVector()) { switch (type.getNominalSize()) { - case 2: return GL_BOOL_VEC2; - case 3: return GL_BOOL_VEC3; - case 4: return GL_BOOL_VEC4; - default: UNREACHABLE(); + case 2: + return GL_BOOL_VEC2; + case 3: + return GL_BOOL_VEC3; + case 4: + return GL_BOOL_VEC4; + default: + UNREACHABLE(); } } - else UNREACHABLE(); + else + { + ASSERT(!type.isMatrix()); + return GL_BOOL; + } } switch (type.getBasicType()) { - case EbtSampler2D: return GL_SAMPLER_2D; - case EbtSampler3D: return GL_SAMPLER_3D; - case EbtSamplerCube: return GL_SAMPLER_CUBE; - case EbtSamplerExternalOES: return GL_SAMPLER_EXTERNAL_OES; - case EbtSampler2DRect: return GL_SAMPLER_2D_RECT_ARB; - case EbtSampler2DArray: return GL_SAMPLER_2D_ARRAY; - case EbtISampler2D: return GL_INT_SAMPLER_2D; - case EbtISampler3D: return GL_INT_SAMPLER_3D; - case EbtISamplerCube: return GL_INT_SAMPLER_CUBE; - case EbtISampler2DArray: return GL_INT_SAMPLER_2D_ARRAY; - case EbtUSampler2D: return GL_UNSIGNED_INT_SAMPLER_2D; - case EbtUSampler3D: return GL_UNSIGNED_INT_SAMPLER_3D; - case EbtUSamplerCube: return GL_UNSIGNED_INT_SAMPLER_CUBE; - case EbtUSampler2DArray: return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY; - case EbtSampler2DShadow: return GL_SAMPLER_2D_SHADOW; - case EbtSamplerCubeShadow: return GL_SAMPLER_CUBE_SHADOW; - case EbtSampler2DArrayShadow: return GL_SAMPLER_2D_ARRAY_SHADOW; - default: UNREACHABLE(); + case EbtSampler2D: + return GL_SAMPLER_2D; + case EbtSampler3D: + return GL_SAMPLER_3D; + case EbtSamplerCube: + return GL_SAMPLER_CUBE; + case EbtSamplerExternalOES: + return GL_SAMPLER_EXTERNAL_OES; + case EbtSamplerExternal2DY2YEXT: + return GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT; + case EbtSampler2DRect: + return GL_SAMPLER_2D_RECT_ANGLE; + case EbtSampler2DArray: + return GL_SAMPLER_2D_ARRAY; + case EbtSampler2DMS: + return GL_SAMPLER_2D_MULTISAMPLE; + case EbtISampler2D: + return GL_INT_SAMPLER_2D; + case EbtISampler3D: + return GL_INT_SAMPLER_3D; + case EbtISamplerCube: + return GL_INT_SAMPLER_CUBE; + case EbtISampler2DArray: + return GL_INT_SAMPLER_2D_ARRAY; + case EbtISampler2DMS: + return GL_INT_SAMPLER_2D_MULTISAMPLE; + case EbtUSampler2D: + return GL_UNSIGNED_INT_SAMPLER_2D; + case EbtUSampler3D: + return GL_UNSIGNED_INT_SAMPLER_3D; + case EbtUSamplerCube: + return GL_UNSIGNED_INT_SAMPLER_CUBE; + case EbtUSampler2DArray: + return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY; + case EbtUSampler2DMS: + return GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE; + case EbtSampler2DShadow: + return GL_SAMPLER_2D_SHADOW; + case EbtSamplerCubeShadow: + return GL_SAMPLER_CUBE_SHADOW; + case EbtSampler2DArrayShadow: + return GL_SAMPLER_2D_ARRAY_SHADOW; + case EbtImage2D: + return GL_IMAGE_2D; + case EbtIImage2D: + return GL_INT_IMAGE_2D; + case EbtUImage2D: + return GL_UNSIGNED_INT_IMAGE_2D; + case EbtImage2DArray: + return GL_IMAGE_2D_ARRAY; + case EbtIImage2DArray: + return GL_INT_IMAGE_2D_ARRAY; + case EbtUImage2DArray: + return GL_UNSIGNED_INT_IMAGE_2D_ARRAY; + case EbtImage3D: + return GL_IMAGE_3D; + case EbtIImage3D: + return GL_INT_IMAGE_3D; + case EbtUImage3D: + return GL_UNSIGNED_INT_IMAGE_3D; + case EbtImageCube: + return GL_IMAGE_CUBE; + case EbtIImageCube: + return GL_INT_IMAGE_CUBE; + case EbtUImageCube: + return GL_UNSIGNED_INT_IMAGE_CUBE; + case EbtAtomicCounter: + return GL_UNSIGNED_INT_ATOMIC_COUNTER; + default: + UNREACHABLE(); } return GL_NONE; @@ -171,32 +420,32 @@ GLenum GLVariablePrecision(const TType &type) { switch (type.getPrecision()) { - case EbpHigh: - return GL_HIGH_FLOAT; - case EbpMedium: - return GL_MEDIUM_FLOAT; - case EbpLow: - return GL_LOW_FLOAT; - case EbpUndefined: - // Should be defined as the default precision by the parser - default: - UNREACHABLE(); + case EbpHigh: + return GL_HIGH_FLOAT; + case EbpMedium: + return GL_MEDIUM_FLOAT; + case EbpLow: + return GL_LOW_FLOAT; + case EbpUndefined: + // Should be defined as the default precision by the parser + default: + UNREACHABLE(); } } else if (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt) { switch (type.getPrecision()) { - case EbpHigh: - return GL_HIGH_INT; - case EbpMedium: - return GL_MEDIUM_INT; - case EbpLow: - return GL_LOW_INT; - case EbpUndefined: - // Should be defined as the default precision by the parser - default: - UNREACHABLE(); + case EbpHigh: + return GL_HIGH_INT; + case EbpMedium: + return GL_MEDIUM_INT; + case EbpLow: + return GL_LOW_INT; + case EbpUndefined: + // Should be defined as the default precision by the parser + default: + UNREACHABLE(); } } @@ -206,26 +455,46 @@ GLenum GLVariablePrecision(const TType &type) TString ArrayString(const TType &type) { + TStringStream arrayString; if (!type.isArray()) - { - return ""; - } + return arrayString.str(); - return "[" + str(type.getArraySize()) + "]"; + const TVector &arraySizes = *type.getArraySizes(); + for (auto arraySizeIter = arraySizes.rbegin(); arraySizeIter != arraySizes.rend(); + ++arraySizeIter) + { + arrayString << "["; + if (*arraySizeIter > 0) + { + arrayString << (*arraySizeIter); + } + arrayString << "]"; + } + return arrayString.str(); +} + +TString GetTypeName(const TType &type, ShHashFunction64 hashFunction, NameMap *nameMap) +{ + if (type.getBasicType() == EbtStruct) + return HashName(TName(type.getStruct()->name()), hashFunction, nameMap); + else + return type.getBuiltInTypeNameString(); } bool IsVaryingOut(TQualifier qualifier) { switch (qualifier) { - case EvqVaryingOut: - case EvqSmoothOut: - case EvqFlatOut: - case EvqCentroidOut: - case EvqVertexOut: - return true; + case EvqVaryingOut: + case EvqSmoothOut: + case EvqFlatOut: + case EvqCentroidOut: + case EvqVertexOut: + case EvqGeometryOut: + return true; - default: break; + default: + break; } return false; @@ -235,14 +504,16 @@ bool IsVaryingIn(TQualifier qualifier) { switch (qualifier) { - case EvqVaryingIn: - case EvqSmoothIn: - case EvqFlatIn: - case EvqCentroidIn: - case EvqFragmentIn: - return true; + case EvqVaryingIn: + case EvqSmoothIn: + case EvqFlatIn: + case EvqCentroidIn: + case EvqFragmentIn: + case EvqGeometryIn: + return true; - default: break; + default: + break; } return false; @@ -253,108 +524,191 @@ bool IsVarying(TQualifier qualifier) return IsVaryingIn(qualifier) || IsVaryingOut(qualifier); } +bool IsGeometryShaderInput(GLenum shaderType, TQualifier qualifier) +{ + return (qualifier == EvqGeometryIn) || + ((shaderType == GL_GEOMETRY_SHADER_OES) && IsInterpolationIn(qualifier)); +} + InterpolationType GetInterpolationType(TQualifier qualifier) { switch (qualifier) { - case EvqFlatIn: - case EvqFlatOut: - return INTERPOLATION_FLAT; + case EvqFlatIn: + case EvqFlatOut: + return INTERPOLATION_FLAT; - case EvqSmoothIn: - case EvqSmoothOut: - case EvqVertexOut: - case EvqFragmentIn: - case EvqVaryingIn: - case EvqVaryingOut: - return INTERPOLATION_SMOOTH; + case EvqSmoothIn: + case EvqSmoothOut: + case EvqVertexOut: + case EvqFragmentIn: + case EvqVaryingIn: + case EvqVaryingOut: + case EvqGeometryIn: + case EvqGeometryOut: + return INTERPOLATION_SMOOTH; - case EvqCentroidIn: - case EvqCentroidOut: - return INTERPOLATION_CENTROID; + case EvqCentroidIn: + case EvqCentroidOut: + return INTERPOLATION_CENTROID; - default: UNREACHABLE(); - return INTERPOLATION_SMOOTH; + default: + UNREACHABLE(); + return INTERPOLATION_SMOOTH; } } -GetVariableTraverser::GetVariableTraverser(const TSymbolTable &symbolTable) - : mSymbolTable(symbolTable) +TType GetShaderVariableBasicType(const sh::ShaderVariable &var) { + switch (var.type) + { + case GL_BOOL: + return TType(EbtBool); + case GL_BOOL_VEC2: + return TType(EbtBool, 2); + case GL_BOOL_VEC3: + return TType(EbtBool, 3); + case GL_BOOL_VEC4: + return TType(EbtBool, 4); + case GL_FLOAT: + return TType(EbtFloat); + case GL_FLOAT_VEC2: + return TType(EbtFloat, 2); + case GL_FLOAT_VEC3: + return TType(EbtFloat, 3); + case GL_FLOAT_VEC4: + return TType(EbtFloat, 4); + case GL_FLOAT_MAT2: + return TType(EbtFloat, 2, 2); + case GL_FLOAT_MAT3: + return TType(EbtFloat, 3, 3); + case GL_FLOAT_MAT4: + return TType(EbtFloat, 4, 4); + case GL_FLOAT_MAT2x3: + return TType(EbtFloat, 2, 3); + case GL_FLOAT_MAT2x4: + return TType(EbtFloat, 2, 4); + case GL_FLOAT_MAT3x2: + return TType(EbtFloat, 3, 2); + case GL_FLOAT_MAT3x4: + return TType(EbtFloat, 3, 4); + case GL_FLOAT_MAT4x2: + return TType(EbtFloat, 4, 2); + case GL_FLOAT_MAT4x3: + return TType(EbtFloat, 4, 3); + case GL_INT: + return TType(EbtInt); + case GL_INT_VEC2: + return TType(EbtInt, 2); + case GL_INT_VEC3: + return TType(EbtInt, 3); + case GL_INT_VEC4: + return TType(EbtInt, 4); + case GL_UNSIGNED_INT: + return TType(EbtUInt); + case GL_UNSIGNED_INT_VEC2: + return TType(EbtUInt, 2); + case GL_UNSIGNED_INT_VEC3: + return TType(EbtUInt, 3); + case GL_UNSIGNED_INT_VEC4: + return TType(EbtUInt, 4); + default: + UNREACHABLE(); + return TType(); + } } -template void GetVariableTraverser::setTypeSpecificInfo( - const TType &type, const TString& name, InterfaceBlockField *variable); -template void GetVariableTraverser::setTypeSpecificInfo( - const TType &type, const TString& name, ShaderVariable *variable); -template void GetVariableTraverser::setTypeSpecificInfo( - const TType &type, const TString& name, Uniform *variable); - -template<> -void GetVariableTraverser::setTypeSpecificInfo( - const TType &type, const TString& name, Varying *variable) +// GLSL ES 1.0.17 4.6.1 The Invariant Qualifier +bool CanBeInvariantESSL1(TQualifier qualifier) { - ASSERT(variable); - switch (type.getQualifier()) - { - case EvqVaryingIn: - case EvqVaryingOut: - case EvqVertexOut: - case EvqSmoothOut: - case EvqFlatOut: - case EvqCentroidOut: - if (mSymbolTable.isVaryingInvariant(std::string(name.c_str())) || type.isInvariant()) - { - variable->isInvariant = true; - } - break; - default: - break; - } - - variable->interpolation = GetInterpolationType(type.getQualifier()); + return IsVaryingIn(qualifier) || IsVaryingOut(qualifier) || + IsBuiltinOutputVariable(qualifier) || + (IsBuiltinFragmentInputVariable(qualifier) && qualifier != EvqFrontFacing); } -template -void GetVariableTraverser::traverse(const TType &type, - const TString &name, - std::vector *output) +// GLSL ES 3.00 Revision 6, 4.6.1 The Invariant Qualifier +// GLSL ES 3.10 Revision 4, 4.8.1 The Invariant Qualifier +bool CanBeInvariantESSL3OrGreater(TQualifier qualifier) { - const TStructure *structure = type.getStruct(); - - VarT variable; - variable.name = name.c_str(); - variable.arraySize = static_cast(type.getArraySize()); - - if (!structure) - { - variable.type = GLVariableType(type); - variable.precision = GLVariablePrecision(type); - } - else - { - // Note: this enum value is not exposed outside ANGLE - variable.type = GL_STRUCT_ANGLEX; - variable.structName = structure->name().c_str(); - - const TFieldList &fields = structure->fields(); - - for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) - { - TField *field = fields[fieldIndex]; - traverse(*field->type(), field->name(), &variable.fields); - } - } - setTypeSpecificInfo(type, name, &variable); - visitVariable(&variable); - - ASSERT(output); - output->push_back(variable); + return IsVaryingOut(qualifier) || qualifier == EvqFragmentOut || + IsBuiltinOutputVariable(qualifier); } -template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector *); -template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector *); -template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector *); -template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector *); - +bool IsBuiltinOutputVariable(TQualifier qualifier) +{ + switch (qualifier) + { + case EvqPosition: + case EvqPointSize: + case EvqFragDepth: + case EvqFragDepthEXT: + case EvqFragColor: + case EvqSecondaryFragColorEXT: + case EvqFragData: + case EvqSecondaryFragDataEXT: + return true; + default: + break; + } + return false; } + +bool IsBuiltinFragmentInputVariable(TQualifier qualifier) +{ + switch (qualifier) + { + case EvqFragCoord: + case EvqPointCoord: + case EvqFrontFacing: + return true; + default: + break; + } + return false; +} + +bool IsOutputESSL(ShShaderOutput output) +{ + return output == SH_ESSL_OUTPUT; +} + +bool IsOutputGLSL(ShShaderOutput output) +{ + switch (output) + { + case SH_GLSL_130_OUTPUT: + case SH_GLSL_140_OUTPUT: + case SH_GLSL_150_CORE_OUTPUT: + case SH_GLSL_330_CORE_OUTPUT: + case SH_GLSL_400_CORE_OUTPUT: + case SH_GLSL_410_CORE_OUTPUT: + case SH_GLSL_420_CORE_OUTPUT: + case SH_GLSL_430_CORE_OUTPUT: + case SH_GLSL_440_CORE_OUTPUT: + case SH_GLSL_450_CORE_OUTPUT: + case SH_GLSL_COMPATIBILITY_OUTPUT: + return true; + default: + break; + } + return false; +} +bool IsOutputHLSL(ShShaderOutput output) +{ + switch (output) + { + case SH_HLSL_3_0_OUTPUT: + case SH_HLSL_4_1_OUTPUT: + case SH_HLSL_4_0_FL9_3_OUTPUT: + return true; + default: + break; + } + return false; +} +bool IsOutputVulkan(ShShaderOutput output) +{ + return output == SH_GLSL_VULKAN_OUTPUT; +} + +} // namespace sh diff --git a/src/3rdparty/angle/src/compiler/translator/util.h b/src/3rdparty/angle/src/compiler/translator/util.h index ea7a35a352..6d6dc95b3b 100644 --- a/src/3rdparty/angle/src/compiler/translator/util.h +++ b/src/3rdparty/angle/src/compiler/translator/util.h @@ -12,54 +12,52 @@ #include "angle_gl.h" #include +#include "compiler/translator/HashNames.h" +#include "compiler/translator/Operator.h" #include "compiler/translator/Types.h" -// strtof_clamp is like strtof but -// 1. it forces C locale, i.e. forcing '.' as decimal point. -// 2. it clamps the value to -FLT_MAX or FLT_MAX if overflow happens. -// Return false if overflow happens. -bool strtof_clamp(const std::string &str, float *value); - // If overflow happens, clamp the value to UINT_MIN or UINT_MAX. // Return false if overflow happens. bool atoi_clamp(const char *str, unsigned int *value); -class TSymbolTable; - namespace sh { +class TSymbolTable; + +float NumericLexFloat32OutOfRangeToInfinity(const std::string &str); + +// strtof_clamp is like strtof but +// 1. it forces C locale, i.e. forcing '.' as decimal point. +// 2. it sets the value to infinity if overflow happens. +// 3. str should be guaranteed to be in the valid format for a floating point number as defined +// by the grammar in the ESSL 3.00.6 spec section 4.1.4. +// Return false if overflow happens. +bool strtof_clamp(const std::string &str, float *value); GLenum GLVariableType(const TType &type); GLenum GLVariablePrecision(const TType &type); bool IsVaryingIn(TQualifier qualifier); bool IsVaryingOut(TQualifier qualifier); bool IsVarying(TQualifier qualifier); +bool IsGeometryShaderInput(GLenum shaderType, TQualifier qualifier); InterpolationType GetInterpolationType(TQualifier qualifier); + +// Returns array brackets including size with outermost array size first, as specified in GLSL ES +// 3.10 section 4.1.9. TString ArrayString(const TType &type); -class GetVariableTraverser : angle::NonCopyable -{ - public: - GetVariableTraverser(const TSymbolTable &symbolTable); - virtual ~GetVariableTraverser() {} +TString GetTypeName(const TType &type, ShHashFunction64 hashFunction, NameMap *nameMap); - template - void traverse(const TType &type, const TString &name, std::vector *output); +TType GetShaderVariableBasicType(const sh::ShaderVariable &var); - protected: - // May be overloaded - virtual void visitVariable(ShaderVariable *newVar) {} +bool IsBuiltinOutputVariable(TQualifier qualifier); +bool IsBuiltinFragmentInputVariable(TQualifier qualifier); +bool CanBeInvariantESSL1(TQualifier qualifier); +bool CanBeInvariantESSL3OrGreater(TQualifier qualifier); +bool IsOutputESSL(ShShaderOutput output); +bool IsOutputGLSL(ShShaderOutput output); +bool IsOutputHLSL(ShShaderOutput output); +bool IsOutputVulkan(ShShaderOutput output); +} // namespace sh - private: - // Helper function called by traverse() to fill specific fields - // for attributes/varyings/uniforms. - template - void setTypeSpecificInfo( - const TType &type, const TString &name, VarT *variable) {} - - const TSymbolTable &mSymbolTable; -}; - -} - -#endif // COMPILER_TRANSLATOR_UTIL_H_ +#endif // COMPILER_TRANSLATOR_UTIL_H_ diff --git a/src/3rdparty/angle/src/gpu_info_util/SystemInfo.cpp b/src/3rdparty/angle/src/gpu_info_util/SystemInfo.cpp new file mode 100644 index 0000000000..f8d744342d --- /dev/null +++ b/src/3rdparty/angle/src/gpu_info_util/SystemInfo.cpp @@ -0,0 +1,171 @@ +// +// Copyright (c) 2013-2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// SystemInfo.cpp: implementation of the system-agnostic parts of SystemInfo.h + +#include "gpu_info_util/SystemInfo.h" + +#include +#include + +#include "common/debug.h" +#include "common/string_utils.h" + +namespace angle +{ + +GPUDeviceInfo::GPUDeviceInfo() = default; + +GPUDeviceInfo::~GPUDeviceInfo() = default; + +GPUDeviceInfo::GPUDeviceInfo(const GPUDeviceInfo &other) = default; + +SystemInfo::SystemInfo() = default; + +SystemInfo::~SystemInfo() = default; + +SystemInfo::SystemInfo(const SystemInfo &other) = default; + +bool IsAMD(VendorID vendorId) +{ + return vendorId == kVendorID_AMD; +} + +bool IsIntel(VendorID vendorId) +{ + return vendorId == kVendorID_Intel; +} + +bool IsNvidia(VendorID vendorId) +{ + return vendorId == kVendorID_Nvidia; +} + +bool IsQualcomm(VendorID vendorId) +{ + return vendorId == kVendorID_Qualcomm; +} + +bool ParseAMDBrahmaDriverVersion(const std::string &content, std::string *version) +{ + const size_t begin = content.find_first_of("0123456789"); + if (begin == std::string::npos) + { + return false; + } + + const size_t end = content.find_first_not_of("0123456789.", begin); + if (end == std::string::npos) + { + *version = content.substr(begin); + } + else + { + *version = content.substr(begin, end - begin); + } + return true; +} + +bool ParseAMDCatalystDriverVersion(const std::string &content, std::string *version) +{ + std::istringstream stream(content); + + std::string line; + while (std::getline(stream, line)) + { + static const char kReleaseVersion[] = "ReleaseVersion="; + if (line.compare(0, std::strlen(kReleaseVersion), kReleaseVersion) != 0) + { + continue; + } + + if (ParseAMDBrahmaDriverVersion(line, version)) + { + return true; + } + } + return false; +} + +bool ParseMacMachineModel(const std::string &identifier, + std::string *type, + int32_t *major, + int32_t *minor) +{ + size_t numberLoc = identifier.find_first_of("0123456789"); + if (numberLoc == std::string::npos) + { + return false; + } + + size_t commaLoc = identifier.find(',', numberLoc); + if (commaLoc == std::string::npos || commaLoc >= identifier.size()) + { + return false; + } + + const char *numberPtr = &identifier[numberLoc]; + const char *commaPtr = &identifier[commaLoc + 1]; + char *endPtr = nullptr; + + int32_t majorTmp = std::strtol(numberPtr, &endPtr, 10); + if (endPtr == numberPtr) + { + return false; + } + + int32_t minorTmp = std::strtol(commaPtr, &endPtr, 10); + if (endPtr == commaPtr) + { + return false; + } + + *major = majorTmp; + *minor = minorTmp; + *type = identifier.substr(0, numberLoc); + + return true; +} + +bool CMDeviceIDToDeviceAndVendorID(const std::string &id, uint32_t *vendorId, uint32_t *deviceId) +{ + unsigned int vendor = 0; + unsigned int device = 0; + + bool success = id.length() >= 21 && HexStringToUInt(id.substr(8, 4), &vendor) && + HexStringToUInt(id.substr(17, 4), &device); + + *vendorId = vendor; + *deviceId = device; + return success; +} + +void FindPrimaryGPU(SystemInfo *info) +{ + ASSERT(!info->gpus.empty()); + + // On dual-GPU systems we assume the non-Intel GPU is the primary one. + int primary = 0; + bool hasIntel = false; + for (size_t i = 0; i < info->gpus.size(); ++i) + { + if (IsIntel(info->gpus[i].vendorId)) + { + hasIntel = true; + } + if (IsIntel(info->gpus[primary].vendorId)) + { + primary = static_cast(i); + } + } + + // Assume that a combination of AMD or Nvidia with Intel means Optimus or AMD Switchable + info->primaryGPUIndex = primary; + info->isOptimus = hasIntel && IsNvidia(info->gpus[primary].vendorId); + info->isAMDSwitchable = hasIntel && IsAMD(info->gpus[primary].vendorId); +} + +} // namespace angle diff --git a/src/3rdparty/angle/src/gpu_info_util/SystemInfo.h b/src/3rdparty/angle/src/gpu_info_util/SystemInfo.h new file mode 100644 index 0000000000..ada43f0a15 --- /dev/null +++ b/src/3rdparty/angle/src/gpu_info_util/SystemInfo.h @@ -0,0 +1,73 @@ +// +// Copyright (c) 2013-2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// SystemInfo.h: gathers information available without starting a GPU driver. + +#ifndef GPU_INFO_UTIL_SYSTEM_INFO_H_ +#define GPU_INFO_UTIL_SYSTEM_INFO_H_ + +#include +#include +#include + +namespace angle +{ + +using VendorID = uint32_t; +using DeviceID = uint32_t; + +constexpr VendorID kVendorID_AMD = 0x1002; +constexpr VendorID kVendorID_Intel = 0x8086; +constexpr VendorID kVendorID_Nvidia = 0x10DE; +constexpr VendorID kVendorID_Qualcomm = 0x5143; + +struct GPUDeviceInfo +{ + GPUDeviceInfo(); + ~GPUDeviceInfo(); + + GPUDeviceInfo(const GPUDeviceInfo &other); + + VendorID vendorId = 0; + DeviceID deviceId = 0; + + std::string driverVendor; + std::string driverVersion; + std::string driverDate; +}; + +struct SystemInfo +{ + SystemInfo(); + ~SystemInfo(); + + SystemInfo(const SystemInfo &other); + + std::vector gpus; + int primaryGPUIndex = -1; + int activeGPUIndex = -1; + + bool isOptimus = false; + bool isAMDSwitchable = false; + + // Only available on macOS + std::string machineModelName; + std::string machineModelVersion; + + // Only available on Windows, set even on failure. + std::string primaryDisplayDeviceId; +}; + +bool GetSystemInfo(SystemInfo *info); + +bool IsAMD(VendorID vendorId); +bool IsIntel(VendorID vendorId); +bool IsNvidia(VendorID vendorId); +bool IsQualcomm(VendorID vendorId); + +} // namespace angle + +#endif // GPU_INFO_UTIL_SYSTEM_INFO_H_ diff --git a/src/3rdparty/angle/src/gpu_info_util/SystemInfo_internal.h b/src/3rdparty/angle/src/gpu_info_util/SystemInfo_internal.h new file mode 100644 index 0000000000..d2f6124662 --- /dev/null +++ b/src/3rdparty/angle/src/gpu_info_util/SystemInfo_internal.h @@ -0,0 +1,38 @@ +// +// Copyright (c) 2013-2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// SystemInfo_internal.h: Functions used by the SystemInfo_* files and unittests + +#ifndef GPU_INFO_UTIL_SYSTEM_INFO_INTERNAL_H_ +#define GPU_INFO_UTIL_SYSTEM_INFO_INTERNAL_H_ + +#include "gpu_info_util/SystemInfo.h" + +namespace angle +{ + +// Defined in SystemInfo_libpci when GPU_INFO_USE_LIBPCI is defined. +bool GetPCIDevicesWithLibPCI(std::vector *devices); +// Defined in SystemInfo_x11 when GPU_INFO_USE_X11 is defined. +bool GetNvidiaDriverVersionWithXNVCtrl(std::string *version); + +// Target specific helper functions that can be compiled on all targets +// Live in SystemInfo.cpp +bool ParseAMDBrahmaDriverVersion(const std::string &content, std::string *version); +bool ParseAMDCatalystDriverVersion(const std::string &content, std::string *version); +bool ParseMacMachineModel(const std::string &identifier, + std::string *type, + int32_t *major, + int32_t *minor); +bool CMDeviceIDToDeviceAndVendorID(const std::string &id, uint32_t *vendorId, uint32_t *deviceId); + +// In the case there are multiple GPUs, this finds the primary one and sets Optimus or AMD +// Switchable +void FindPrimaryGPU(SystemInfo *info); + +} // namespace angle + +#endif // GPU_INFO_UTIL_SYSTEM_INFO_INTERNAL_H_ diff --git a/src/3rdparty/angle/src/gpu_info_util/SystemInfo_libpci.cpp b/src/3rdparty/angle/src/gpu_info_util/SystemInfo_libpci.cpp new file mode 100644 index 0000000000..07c72872ad --- /dev/null +++ b/src/3rdparty/angle/src/gpu_info_util/SystemInfo_libpci.cpp @@ -0,0 +1,132 @@ +// +// Copyright (c) 2013-2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// SystemInfo_libpci.cpp: implementation of the libPCI-specific parts of SystemInfo.h + +#include "gpu_info_util/SystemInfo_internal.h" + +#include +#include +#include + +#include "common/angleutils.h" +#include "common/debug.h" + +#if !defined(GPU_INFO_USE_LIBPCI) +#error SystemInfo_libpci.cpp compiled without GPU_INFO_USE_LIBPCI +#endif + +namespace angle +{ + +namespace +{ + +struct LibPCI : private angle::NonCopyable +{ + LibPCI() + { + if (access("/sys/bus/pci/", F_OK) != 0 && access("/sys/bs/pci_express/", F_OK) != 0) + { + return; + } + + mHandle = dlopen("libpci.so.3", RTLD_LAZY); + + if (mHandle == nullptr) + { + mHandle = dlopen("libpci.so", RTLD_LAZY); + } + + if (mHandle == nullptr) + { + return; + } + + mValid = + (Alloc = reinterpret_cast(dlsym(mHandle, "pci_alloc"))) != nullptr && + (Init = reinterpret_cast(dlsym(mHandle, "pci_init"))) != nullptr && + (Cleanup = reinterpret_cast(dlsym(mHandle, "pci_cleanup"))) != + nullptr && + (ScanBus = reinterpret_cast(dlsym(mHandle, "pci_scan_bus"))) != + nullptr && + (FillInfo = reinterpret_cast(dlsym(mHandle, "pci_fill_info"))) != + nullptr && + (LookupName = reinterpret_cast( + dlsym(mHandle, "pci_lookup_name"))) != nullptr; + } + + bool IsValid() const { return mValid; } + + ~LibPCI() + { + if (mHandle != nullptr) + { + dlclose(mHandle); + } + } + + decltype(&::pci_alloc) Alloc = nullptr; + decltype(&::pci_init) Init = nullptr; + decltype(&::pci_cleanup) Cleanup = nullptr; + decltype(&::pci_scan_bus) ScanBus = nullptr; + decltype(&::pci_fill_info) FillInfo = nullptr; + decltype(&::pci_lookup_name) LookupName = nullptr; + + private: + void *mHandle = nullptr; + bool mValid = false; +}; + +} // anonymous namespace + +// Adds an entry per PCI GPU found and fills the device and vendor ID. +bool GetPCIDevicesWithLibPCI(std::vector *devices) +{ + LibPCI pci; + if (!pci.IsValid()) + { + return false; + } + + pci_access *access = pci.Alloc(); + ASSERT(access != nullptr); + pci.Init(access); + pci.ScanBus(access); + + for (pci_dev *device = access->devices; device != nullptr; device = device->next) + { + pci.FillInfo(device, PCI_FILL_IDENT | PCI_FILL_CLASS); + + // Skip non-GPU devices + switch (device->device_class) + { + case PCI_CLASS_DISPLAY_VGA: + case PCI_CLASS_DISPLAY_XGA: + case PCI_CLASS_DISPLAY_3D: + break; + default: + continue; + } + + // Skip unknown devices + if (device->vendor_id == 0 || device->device_id == 0) + { + continue; + } + + GPUDeviceInfo info; + info.vendorId = device->vendor_id; + info.deviceId = device->device_id; + + devices->push_back(info); + } + + pci.Cleanup(access); + + return true; +} +} diff --git a/src/3rdparty/angle/src/gpu_info_util/SystemInfo_linux.cpp b/src/3rdparty/angle/src/gpu_info_util/SystemInfo_linux.cpp new file mode 100644 index 0000000000..98f000b069 --- /dev/null +++ b/src/3rdparty/angle/src/gpu_info_util/SystemInfo_linux.cpp @@ -0,0 +1,144 @@ +// +// Copyright (c) 2013-2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// SystemInfo_linux.cpp: implementation of the Linux-specific parts of SystemInfo.h + +#include "gpu_info_util/SystemInfo_internal.h" + +#include +#include + +#include "common/angleutils.h" +#include "common/debug.h" + +namespace angle +{ + +namespace +{ + +bool ReadWholeFile(const char *filename, std::string *content) +{ + std::ifstream file(filename); + + if (!file) + { + return false; + } + + *content = std::string(std::istreambuf_iterator(file), std::istreambuf_iterator()); + return true; +} + +// Scan /sys/module/amdgpu/version. +bool GetAMDBrahmaDriverVersion(std::string *version) +{ + *version = ""; + std::string content; + + return ReadWholeFile("/sys/module/amdgpu/version", &content) && + ParseAMDBrahmaDriverVersion(content, version); +} + +// Scan /etc/ati/amdpcsdb.default for "ReleaseVersion". +bool GetAMDCatalystDriverVersion(std::string *version) +{ + *version = ""; + std::string content; + + return ReadWholeFile("/etc/ati/amdpcsdb.default", &content) && + ParseAMDCatalystDriverVersion(content, version); +} + +} // anonymous namespace + +#if !defined(GPU_INFO_USE_X11) +bool GetNvidiaDriverVersionWithXNVCtrl(std::string *version) +{ + return false; +} +#endif + +#if !defined(GPU_INFO_USE_LIBPCI) +bool GetPCIDevicesWithLibPCI(std::vector *devices) +{ + return false; +} +#endif + +bool GetSystemInfo(SystemInfo *info) +{ + if (!GetPCIDevicesWithLibPCI(&(info->gpus))) + { + return false; + } + + if (info->gpus.size() == 0) + { + return false; + } + + FindPrimaryGPU(info); + + for (size_t i = 0; i < info->gpus.size(); ++i) + { + GPUDeviceInfo *gpu = &info->gpus[i]; + + // New GPUs might be added inside this loop, don't query for their driver version again + if (!gpu->driverVendor.empty()) + { + continue; + } + + if (IsAMD(gpu->vendorId)) + { + std::string version; + if (GetAMDBrahmaDriverVersion(&version)) + { + gpu->driverVendor = "AMD (Brahma)"; + gpu->driverVersion = std::move(version); + } + else if (GetAMDCatalystDriverVersion(&version)) + { + gpu->driverVendor = "AMD (Catalyst)"; + gpu->driverVersion = std::move(version); + } + } + + if (IsNvidia(gpu->vendorId)) + { + std::string version; + if (GetNvidiaDriverVersionWithXNVCtrl(&version)) + { + gpu->driverVendor = "Nvidia"; + gpu->driverVersion = std::move(version); + } + } + + // In dual-GPU cases the PCI scan sometimes only gives us the Intel GPU. + // If we are able to query for the Nvidia driver version, it means there + // was hidden Nvidia GPU, so we add it to the list and make it primary. + if (IsIntel(gpu->vendorId) && info->gpus.size() == 1) + { + std::string version; + if (GetNvidiaDriverVersionWithXNVCtrl(&version)) + { + GPUDeviceInfo nvidiaInfo; + nvidiaInfo.vendorId = kVendorID_Nvidia; + nvidiaInfo.deviceId = 0; + gpu->driverVendor = "Nvidia"; + gpu->driverVersion = std::move(version); + + info->gpus.emplace_back(std::move(nvidiaInfo)); + info->isOptimus = true; + } + } + } + + return true; +} + +} // namespace angle diff --git a/src/3rdparty/angle/src/gpu_info_util/SystemInfo_mac.mm b/src/3rdparty/angle/src/gpu_info_util/SystemInfo_mac.mm new file mode 100644 index 0000000000..7a7a62d170 --- /dev/null +++ b/src/3rdparty/angle/src/gpu_info_util/SystemInfo_mac.mm @@ -0,0 +1,170 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// SystemInfo_mac.cpp: implementation of the Mac-specific parts of SystemInfo.h + +#include "gpu_info_util/SystemInfo_internal.h" + +#import +#import + +namespace angle +{ + +namespace +{ + +std::string GetMachineModel() +{ + io_service_t platformExpert = IOServiceGetMatchingService( + kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice")); + + if (platformExpert == IO_OBJECT_NULL) + { + return ""; + } + + CFDataRef modelData = static_cast( + IORegistryEntryCreateCFProperty(platformExpert, CFSTR("model"), kCFAllocatorDefault, 0)); + if (modelData == nullptr) + { + IOObjectRelease(platformExpert); + return ""; + } + + std::string result = reinterpret_cast(CFDataGetBytePtr(modelData)); + + IOObjectRelease(platformExpert); + CFRelease(modelData); + + return result; +} + +// Extracts one integer property from a registry entry. +bool GetEntryProperty(io_registry_entry_t entry, CFStringRef name, uint32_t *value) +{ + *value = 0; + + CFDataRef data = static_cast( + IORegistryEntrySearchCFProperty(entry, kIOServicePlane, name, kCFAllocatorDefault, + kIORegistryIterateRecursively | kIORegistryIterateParents)); + + if (data == nullptr) + { + return false; + } + + const uint32_t *valuePtr = reinterpret_cast(CFDataGetBytePtr(data)); + + if (valuePtr == nullptr) + { + CFRelease(data); + return false; + } + + *value = *valuePtr; + CFRelease(data); + return true; +} + +// CGDisplayIOServicePort is deprecated as of macOS 10.9, but has no replacement, see +// https://crbug.com/650837 +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +// Find the info of the current GPU. +bool GetActiveGPU(VendorID *vendorId, DeviceID *deviceId) +{ + io_registry_entry_t port = CGDisplayIOServicePort(kCGDirectMainDisplay); + + return GetEntryProperty(port, CFSTR("vendor-id"), vendorId) && + GetEntryProperty(port, CFSTR("device-id"), deviceId); +} + +#pragma clang diagnostic pop + +// Gathers the vendor and device IDs for the PCI GPUs +bool GetPCIDevices(std::vector *devices) +{ + // matchDictionary will be consumed by IOServiceGetMatchingServices, no need to release it. + CFMutableDictionaryRef matchDictionary = IOServiceMatching("IOPCIDevice"); + + io_iterator_t entryIterator; + if (IOServiceGetMatchingServices(kIOMasterPortDefault, matchDictionary, &entryIterator) != + kIOReturnSuccess) + { + return false; + } + + io_registry_entry_t entry = IO_OBJECT_NULL; + + while ((entry = IOIteratorNext(entryIterator)) != IO_OBJECT_NULL) + { + constexpr uint32_t kClassCodeDisplayVGA = 0x30000; + uint32_t classCode; + GPUDeviceInfo info; + + if (GetEntryProperty(entry, CFSTR("class-code"), &classCode) && + classCode == kClassCodeDisplayVGA && + GetEntryProperty(entry, CFSTR("vendor-id"), &info.vendorId) && + GetEntryProperty(entry, CFSTR("device-id"), &info.deviceId)) + { + devices->push_back(info); + } + + IOObjectRelease(entry); + } + IOObjectRelease(entryIterator); + + return true; +} + +} // anonymous namespace + +bool GetSystemInfo(SystemInfo *info) +{ + { + int32_t major = 0; + int32_t minor = 0; + ParseMacMachineModel(GetMachineModel(), &info->machineModelName, &major, &minor); + info->machineModelVersion = std::to_string(major) + "." + std::to_string(minor); + } + + if (!GetPCIDevices(&(info->gpus))) + { + return false; + } + + if (info->gpus.empty()) + { + return false; + } + + // Find the active GPU + { + VendorID activeVendor; + DeviceID activeDevice; + if (!GetActiveGPU(&activeVendor, &activeDevice)) + { + return false; + } + + for (size_t i = 0; i < info->gpus.size(); ++i) + { + if (info->gpus[i].vendorId == activeVendor && info->gpus[i].deviceId == activeDevice) + { + info->activeGPUIndex = i; + break; + } + } + } + + FindPrimaryGPU(info); + + return true; +} + +} // namespace angle diff --git a/src/3rdparty/angle/src/gpu_info_util/SystemInfo_win.cpp b/src/3rdparty/angle/src/gpu_info_util/SystemInfo_win.cpp new file mode 100644 index 0000000000..041fdad34d --- /dev/null +++ b/src/3rdparty/angle/src/gpu_info_util/SystemInfo_win.cpp @@ -0,0 +1,251 @@ +// +// Copyright (c) 2013-2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// SystemInfo_win.cpp: implementation of the Windows-specific parts of SystemInfo.h + +#include "gpu_info_util/SystemInfo_internal.h" + +#include "common/debug.h" +#include "common/string_utils.h" + +// Windows.h needs to be included first +#include + +#if defined(GPU_INFO_USE_SETUPAPI) +// Remove parts of commctrl.h that have compile errors +#define NOTOOLBAR +#define NOTOOLTIPS +#include +#include +#elif defined(GPU_INFO_USE_DXGI) +#include +#include +#else +#error "SystemInfo_win needs at least GPU_INFO_USE_SETUPAPI or GPU_INFO_USE_DXGI defined" +#endif + +#include +#include + +namespace angle +{ + +namespace +{ + +// Returns the CM device ID of the primary GPU. +std::string GetPrimaryDisplayDeviceId() +{ + DISPLAY_DEVICEA displayDevice; + displayDevice.cb = sizeof(DISPLAY_DEVICEA); + + for (int i = 0; EnumDisplayDevicesA(nullptr, i, &displayDevice, 0); ++i) + { + if (displayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) + { + return displayDevice.DeviceID; + } + } + + return ""; +} + +#if defined(GPU_INFO_USE_SETUPAPI) + +std::string GetRegistryStringValue(HKEY key, const char *valueName) +{ + std::array value; + DWORD valueSize = sizeof(value); + if (RegQueryValueExA(key, valueName, nullptr, nullptr, reinterpret_cast(value.data()), + &valueSize) == ERROR_SUCCESS) + { + return value.data(); + } + return ""; +} + +// Gathers information about the devices from the registry. The reason why we aren't using +// a dedicated API such as DXGI is that we need information like the driver vendor and date. +// DXGI doesn't provide a way to know the device registry key from an IDXGIAdapter. +bool GetDevicesFromRegistry(std::vector *devices) +{ + // Display adapter class GUID from + // https://msdn.microsoft.com/en-us/library/windows/hardware/ff553426%28v=vs.85%29.aspx + GUID displayClass = { + 0x4d36e968, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}}; + + HDEVINFO deviceInfo = SetupDiGetClassDevsW(&displayClass, nullptr, nullptr, DIGCF_PRESENT); + + if (deviceInfo == INVALID_HANDLE_VALUE) + { + return false; + } + + // This iterates over the devices of the "Display adapter" class + DWORD deviceIndex = 0; + SP_DEVINFO_DATA deviceData; + deviceData.cbSize = sizeof(deviceData); + while (SetupDiEnumDeviceInfo(deviceInfo, deviceIndex++, &deviceData)) + { + // The device and vendor IDs can be gathered directly, but information about the driver + // requires some registry digging + char fullDeviceID[MAX_DEVICE_ID_LEN]; + if (CM_Get_Device_IDA(deviceData.DevInst, fullDeviceID, MAX_DEVICE_ID_LEN, 0) != CR_SUCCESS) + { + continue; + } + + GPUDeviceInfo device; + + if (!CMDeviceIDToDeviceAndVendorID(fullDeviceID, &device.vendorId, &device.deviceId)) + { + continue; + } + + // The driver key will end with something like {}/<4 digit number>. + std::array value; + if (!SetupDiGetDeviceRegistryPropertyW(deviceInfo, &deviceData, SPDRP_DRIVER, nullptr, + reinterpret_cast(value.data()), sizeof(value), + nullptr)) + { + continue; + } + + std::wstring driverKey = L"System\\CurrentControlSet\\Control\\Class\\"; + driverKey += value.data(); + + HKEY key; + if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, driverKey.c_str(), 0, KEY_QUERY_VALUE, &key) != + ERROR_SUCCESS) + { + continue; + } + + device.driverVersion = GetRegistryStringValue(key, "DriverVersion"); + device.driverDate = GetRegistryStringValue(key, "DriverDate"); + device.driverVendor = GetRegistryStringValue(key, "ProviderName"); + + RegCloseKey(key); + + devices->push_back(device); + } + + SetupDiDestroyDeviceInfoList(deviceInfo); + + return true; +} + +#elif defined(GPU_INFO_USE_DXGI) + +bool GetDevicesFromDXGI(std::vector *devices) +{ + IDXGIFactory *factory; + if (!SUCCEEDED(CreateDXGIFactory(__uuidof(IDXGIFactory), reinterpret_cast(&factory)))) + { + return false; + } + + UINT i = 0; + IDXGIAdapter *adapter = nullptr; + while (factory->EnumAdapters(i++, &adapter) != DXGI_ERROR_NOT_FOUND) + { + DXGI_ADAPTER_DESC desc; + adapter->GetDesc(&desc); + + LARGE_INTEGER umdVersion; + if (adapter->CheckInterfaceSupport(__uuidof(ID3D10Device), &umdVersion) == + DXGI_ERROR_UNSUPPORTED) + { + adapter->Release(); + continue; + } + + // The UMD driver version here is the same as in the registry except for the last number. + uint64_t intVersion = umdVersion.QuadPart; + std::ostringstream o; + + const uint64_t kMask = 0xFF; + o << ((intVersion >> 48) & kMask) << "."; + o << ((intVersion >> 32) & kMask) << "."; + o << ((intVersion >> 16) & kMask) << "."; + o << (intVersion & kMask); + + GPUDeviceInfo device; + device.vendorId = desc.VendorId; + device.deviceId = desc.DeviceId; + device.driverVersion = o.str(); + + devices->push_back(device); + + adapter->Release(); + } + + factory->Release(); + + return true; +} + +#else +#error +#endif + +} // anonymous namespace + +bool GetSystemInfo(SystemInfo *info) +{ + // Get the CM device ID first so that it is returned even in error cases. + info->primaryDisplayDeviceId = GetPrimaryDisplayDeviceId(); + +#if defined(GPU_INFO_USE_SETUPAPI) + if (!GetDevicesFromRegistry(&info->gpus)) + { + return false; + } +#elif defined(GPU_INFO_USE_DXGI) + if (!GetDevicesFromDXGI(&info->gpus)) + { + return false; + } +#else +#error +#endif + + if (info->gpus.size() == 0) + { + return false; + } + + FindPrimaryGPU(info); + + // Override the primary GPU index with what we gathered from EnumDisplayDevices + uint32_t primaryVendorId = 0; + uint32_t primaryDeviceId = 0; + + if (!CMDeviceIDToDeviceAndVendorID(info->primaryDisplayDeviceId, &primaryVendorId, + &primaryDeviceId)) + { + return false; + } + + bool foundPrimary = false; + for (size_t i = 0; i < info->gpus.size(); ++i) + { + if (info->gpus[i].vendorId == primaryVendorId && info->gpus[i].deviceId == primaryDeviceId) + { + info->primaryGPUIndex = static_cast(i); + foundPrimary = true; + } + } + ASSERT(foundPrimary); + + // nvd3d9wrap.dll is loaded into all processes when Optimus is enabled. + HMODULE nvd3d9wrap = GetModuleHandleW(L"nvd3d9wrap.dll"); + info->isOptimus = nvd3d9wrap != nullptr; + + return true; +} + +} // namespace angle diff --git a/src/3rdparty/angle/src/gpu_info_util/SystemInfo_x11.cpp b/src/3rdparty/angle/src/gpu_info_util/SystemInfo_x11.cpp new file mode 100644 index 0000000000..3513309f36 --- /dev/null +++ b/src/3rdparty/angle/src/gpu_info_util/SystemInfo_x11.cpp @@ -0,0 +1,53 @@ +// +// Copyright (c) 2013-2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// SystemInfo_x11.cpp: implementation of the X11-specific parts of SystemInfo.h + +#include "gpu_info_util/SystemInfo_internal.h" + +#include + +#include "common/debug.h" +#include "third_party/libXNVCtrl/NVCtrl.h" +#include "third_party/libXNVCtrl/NVCtrlLib.h" + +#if !defined(GPU_INFO_USE_X11) +#error SystemInfo_x11.cpp compiled without GPU_INFO_USE_X11 +#endif + +namespace angle +{ + +bool GetNvidiaDriverVersionWithXNVCtrl(std::string *version) +{ + *version = ""; + + int eventBase = 0; + int errorBase = 0; + + Display *display = XOpenDisplay(nullptr); + + if (XNVCTRLQueryExtension(display, &eventBase, &errorBase)) + { + int screenCount = ScreenCount(display); + for (int screen = 0; screen < screenCount; ++screen) + { + char *buffer = nullptr; + if (XNVCTRLIsNvScreen(display, screen) && + XNVCTRLQueryStringAttribute(display, screen, 0, + NV_CTRL_STRING_NVIDIA_DRIVER_VERSION, &buffer)) + { + ASSERT(buffer != nullptr); + *version = buffer; + XFree(buffer); + return true; + } + } + } + + return false; +} +} diff --git a/src/3rdparty/angle/src/id/commit.h b/src/3rdparty/angle/src/id/commit.h deleted file mode 100644 index 0546412964..0000000000 --- a/src/3rdparty/angle/src/id/commit.h +++ /dev/null @@ -1,3 +0,0 @@ -#define ANGLE_COMMIT_HASH "8613f4946861" -#define ANGLE_COMMIT_HASH_SIZE 12 -#define ANGLE_COMMIT_DATE "2016-02-11 19:53:41 +0000" diff --git a/src/3rdparty/angle/src/image_util/copyimage.cpp b/src/3rdparty/angle/src/image_util/copyimage.cpp new file mode 100644 index 0000000000..cc07908158 --- /dev/null +++ b/src/3rdparty/angle/src/image_util/copyimage.cpp @@ -0,0 +1,22 @@ +// +// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// copyimage.cpp: Defines image copying functions + +#include "image_util/copyimage.h" + +namespace angle +{ + +void CopyBGRA8ToRGBA8(const uint8_t *source, uint8_t *dest) +{ + uint32_t argb = *reinterpret_cast(source); + *reinterpret_cast(dest) = (argb & 0xFF00FF00) | // Keep alpha and green + (argb & 0x00FF0000) >> 16 | // Move red to blue + (argb & 0x000000FF) << 16; // Move blue to red +} + +} // namespace angle diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/copyimage.h b/src/3rdparty/angle/src/image_util/copyimage.h similarity index 77% rename from src/3rdparty/angle/src/libANGLE/renderer/d3d/copyimage.h rename to src/3rdparty/angle/src/image_util/copyimage.h index 189654ca39..bc8c1390eb 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/copyimage.h +++ b/src/3rdparty/angle/src/image_util/copyimage.h @@ -6,15 +6,16 @@ // copyimage.h: Defines image copying functions -#ifndef LIBANGLE_RENDERER_D3D_COPYIMAGE_H_ -#define LIBANGLE_RENDERER_D3D_COPYIMAGE_H_ +#ifndef IMAGEUTIL_COPYIMAGE_H_ +#define IMAGEUTIL_COPYIMAGE_H_ -#include "common/mathutil.h" -#include "libANGLE/angletypes.h" +#include "common/Color.h" + +#include "image_util/imageformats.h" #include -namespace rx +namespace angle { template @@ -28,8 +29,8 @@ void CopyPixel(const uint8_t *source, uint8_t *dest); void CopyBGRA8ToRGBA8(const uint8_t *source, uint8_t *dest); -} +} // namespace angle #include "copyimage.inl" -#endif // LIBANGLE_RENDERER_D3D_COPYIMAGE_H_ +#endif // IMAGEUTIL_COPYIMAGE_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/copyimage.inl b/src/3rdparty/angle/src/image_util/copyimage.inl similarity index 69% rename from src/3rdparty/angle/src/libANGLE/renderer/d3d/copyimage.inl rename to src/3rdparty/angle/src/image_util/copyimage.inl index 0498cf7750..dbada81291 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/copyimage.inl +++ b/src/3rdparty/angle/src/image_util/copyimage.inl @@ -6,19 +6,21 @@ // copyimage.inl: Defines image copying functions -namespace rx +namespace angle { template inline void ReadColor(const uint8_t *source, uint8_t *dest) { - sourceType::readColor(reinterpret_cast*>(dest), reinterpret_cast(source)); + sourceType::readColor(reinterpret_cast*>(dest), + reinterpret_cast(source)); } template inline void WriteColor(const uint8_t *source, uint8_t *dest) { - destType::writeColor(reinterpret_cast(dest), reinterpret_cast*>(source)); + destType::writeColor(reinterpret_cast(dest), + reinterpret_cast*>(source)); } template @@ -29,4 +31,4 @@ inline void CopyPixel(const uint8_t *source, uint8_t *dest) WriteColor(&temp, dest); } -} +} // namespace angle diff --git a/src/3rdparty/angle/src/image_util/generatemip.h b/src/3rdparty/angle/src/image_util/generatemip.h new file mode 100644 index 0000000000..a89db823b0 --- /dev/null +++ b/src/3rdparty/angle/src/image_util/generatemip.h @@ -0,0 +1,34 @@ +// +// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// generatemip.h: Defines the GenerateMip function, templated on the format +// type of the image for which mip levels are being generated. + +#ifndef IMAGEUTIL_GENERATEMIP_H_ +#define IMAGEUTIL_GENERATEMIP_H_ + +#include +#include + +namespace angle +{ + +template +inline void GenerateMip(size_t sourceWidth, + size_t sourceHeight, + size_t sourceDepth, + const uint8_t *sourceData, + size_t sourceRowPitch, + size_t sourceDepthPitch, + uint8_t *destData, + size_t destRowPitch, + size_t destDepthPitch); + +} // namespace angle + +#include "generatemip.inl" + +#endif // IMAGEUTIL_GENERATEMIP_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/generatemip.inl b/src/3rdparty/angle/src/image_util/generatemip.inl similarity index 98% rename from src/3rdparty/angle/src/libANGLE/renderer/d3d/generatemip.inl rename to src/3rdparty/angle/src/image_util/generatemip.inl index 265783641e..ddf510c749 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/generatemip.inl +++ b/src/3rdparty/angle/src/image_util/generatemip.inl @@ -9,7 +9,9 @@ #include "common/mathutil.h" -namespace rx +#include "image_util/imageformats.h" + +namespace angle { namespace priv @@ -231,7 +233,7 @@ static MipGenerationFunction GetMipGenerationFunction(size_t sourceWidth, size_t switch (index) { - case 0: return NULL; + case 0: return nullptr; case 1: return GenerateMip_X; // W x 1 x 1 case 2: return GenerateMip_Y; // 1 x H x 1 case 3: return GenerateMip_XY; // W x H x 1 @@ -242,10 +244,10 @@ static MipGenerationFunction GetMipGenerationFunction(size_t sourceWidth, size_t } UNREACHABLE(); - return NULL; + return nullptr; } -} +} // namespace priv template inline void GenerateMip(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth, @@ -257,10 +259,10 @@ inline void GenerateMip(size_t sourceWidth, size_t sourceHeight, size_t sourceDe size_t mipDepth = std::max(1, sourceDepth >> 1); priv::MipGenerationFunction generationFunction = priv::GetMipGenerationFunction(sourceWidth, sourceHeight, sourceDepth); - ASSERT(generationFunction != NULL); + ASSERT(generationFunction != nullptr); generationFunction(sourceWidth, sourceHeight, sourceDepth, sourceData, sourceRowPitch, sourceDepthPitch, mipWidth, mipHeight, mipDepth, destData, destRowPitch, destDepthPitch); } -} +} // namespace angle diff --git a/src/3rdparty/angle/src/image_util/imageformats.cpp b/src/3rdparty/angle/src/image_util/imageformats.cpp new file mode 100644 index 0000000000..a4c86945b6 --- /dev/null +++ b/src/3rdparty/angle/src/image_util/imageformats.cpp @@ -0,0 +1,1722 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// imageformats.cpp: Defines image format types with functions for mip generation +// and copying. + +#include "image_util/imageformats.h" + +#include "common/mathutil.h" + +namespace angle +{ + +void L8::readColor(gl::ColorF *dst, const L8 *src) +{ + const float lum = gl::normalizedToFloat(src->L); + dst->red = lum; + dst->green = lum; + dst->blue = lum; + dst->alpha = 1.0f; +} + +void L8::writeColor(L8 *dst, const gl::ColorF *src) +{ + dst->L = gl::floatToNormalized(src->red); +} + +void L8::average(L8 *dst, const L8 *src1, const L8 *src2) +{ + dst->L = gl::average(src1->L, src2->L); +} + +void R8::readColor(gl::ColorUI *dst, const R8 *src) +{ + dst->red = src->R; + dst->green = 0; + dst->blue = 0; + dst->alpha = 1; +} + +void R8::readColor(gl::ColorF *dst, const R8 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R8::writeColor(R8 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast(src->red); +} + +void R8::writeColor(R8 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); +} + +void R8::average(R8 *dst, const R8 *src1, const R8 *src2) +{ + dst->R = gl::average(src1->R, src2->R); +} + +void A8::readColor(gl::ColorF *dst, const A8 *src) +{ + dst->red = 0.0f; + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = gl::normalizedToFloat(src->A); +} + +void A8::writeColor(A8 *dst, const gl::ColorF *src) +{ + dst->A = gl::floatToNormalized(src->alpha); +} + +void A8::average(A8 *dst, const A8 *src1, const A8 *src2) +{ + dst->A = gl::average(src1->A, src2->A); +} + +void L8A8::readColor(gl::ColorF *dst, const L8A8 *src) +{ + const float lum = gl::normalizedToFloat(src->L); + dst->red = lum; + dst->green = lum; + dst->blue = lum; + dst->alpha = gl::normalizedToFloat(src->A); +} + +void L8A8::writeColor(L8A8 *dst, const gl::ColorF *src) +{ + dst->L = gl::floatToNormalized(src->red); + dst->A = gl::floatToNormalized(src->alpha); +} + +void L8A8::average(L8A8 *dst, const L8A8 *src1, const L8A8 *src2) +{ + *(uint16_t *)dst = (((*(uint16_t *)src1 ^ *(uint16_t *)src2) & 0xFEFE) >> 1) + + (*(uint16_t *)src1 & *(uint16_t *)src2); +} + +void A8L8::readColor(gl::ColorF *dst, const A8L8 *src) +{ + const float lum = gl::normalizedToFloat(src->L); + dst->red = lum; + dst->green = lum; + dst->blue = lum; + dst->alpha = gl::normalizedToFloat(src->A); +} + +void A8L8::writeColor(A8L8 *dst, const gl::ColorF *src) +{ + dst->L = gl::floatToNormalized(src->red); + dst->A = gl::floatToNormalized(src->alpha); +} + +void A8L8::average(A8L8 *dst, const A8L8 *src1, const A8L8 *src2) +{ + *(uint16_t *)dst = (((*(uint16_t *)src1 ^ *(uint16_t *)src2) & 0xFEFE) >> 1) + + (*(uint16_t *)src1 & *(uint16_t *)src2); +} + +void R8G8::readColor(gl::ColorUI *dst, const R8G8 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = 0; + dst->alpha = 1; +} + +void R8G8::readColor(gl::ColorF *dst, const R8G8 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R8G8::writeColor(R8G8 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast(src->red); + dst->G = static_cast(src->green); +} + +void R8G8::writeColor(R8G8 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); + dst->G = gl::floatToNormalized(src->green); +} + +void R8G8::average(R8G8 *dst, const R8G8 *src1, const R8G8 *src2) +{ + *(uint16_t *)dst = (((*(uint16_t *)src1 ^ *(uint16_t *)src2) & 0xFEFE) >> 1) + + (*(uint16_t *)src1 & *(uint16_t *)src2); +} + +void R8G8B8::readColor(gl::ColorUI *dst, const R8G8B8 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->G; + dst->alpha = 1; +} + +void R8G8B8::readColor(gl::ColorF *dst, const R8G8B8 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = 1.0f; +} + +void R8G8B8::writeColor(R8G8B8 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast(src->red); + dst->G = static_cast(src->green); + dst->B = static_cast(src->blue); +} + +void R8G8B8::writeColor(R8G8B8 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); + dst->G = gl::floatToNormalized(src->green); + dst->B = gl::floatToNormalized(src->blue); +} + +void R8G8B8::average(R8G8B8 *dst, const R8G8B8 *src1, const R8G8B8 *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); +} + +void B8G8R8::readColor(gl::ColorUI *dst, const B8G8R8 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->G; + dst->alpha = 1; +} + +void B8G8R8::readColor(gl::ColorF *dst, const B8G8R8 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = 1.0f; +} + +void B8G8R8::writeColor(B8G8R8 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast(src->red); + dst->G = static_cast(src->green); + dst->B = static_cast(src->blue); +} + +void B8G8R8::writeColor(B8G8R8 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); + dst->G = gl::floatToNormalized(src->green); + dst->B = gl::floatToNormalized(src->blue); +} + +void B8G8R8::average(B8G8R8 *dst, const B8G8R8 *src1, const B8G8R8 *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); +} + +void R5G6B5::readColor(gl::ColorF *dst, const R5G6B5 *src) +{ + dst->red = gl::normalizedToFloat<5>(gl::getShiftedData<5, 11>(src->RGB)); + dst->green = gl::normalizedToFloat<6>(gl::getShiftedData<6, 5>(src->RGB)); + dst->blue = gl::normalizedToFloat<5>(gl::getShiftedData<5, 0>(src->RGB)); + dst->alpha = 1.0f; +} + +void R5G6B5::writeColor(R5G6B5 *dst, const gl::ColorF *src) +{ + dst->RGB = gl::shiftData<5, 11>(gl::floatToNormalized<5, uint16_t>(src->red)) | + gl::shiftData<6, 5>(gl::floatToNormalized<6, uint16_t>(src->green)) | + gl::shiftData<5, 0>(gl::floatToNormalized<5, uint16_t>(src->blue)); +} + +void R5G6B5::average(R5G6B5 *dst, const R5G6B5 *src1, const R5G6B5 *src2) +{ + dst->RGB = gl::shiftData<5, 11>(gl::average(gl::getShiftedData<5, 11>(src1->RGB), + gl::getShiftedData<5, 11>(src2->RGB))) | + gl::shiftData<6, 5>(gl::average(gl::getShiftedData<6, 5>(src1->RGB), + gl::getShiftedData<6, 5>(src2->RGB))) | + gl::shiftData<5, 0>(gl::average(gl::getShiftedData<5, 0>(src1->RGB), + gl::getShiftedData<5, 0>(src2->RGB))); +} + +void B5G6R5::readColor(gl::ColorF *dst, const B5G6R5 *src) +{ + dst->red = gl::normalizedToFloat<5>(gl::getShiftedData<5, 11>(src->BGR)); + dst->green = gl::normalizedToFloat<6>(gl::getShiftedData<6, 5>(src->BGR)); + dst->blue = gl::normalizedToFloat<5>(gl::getShiftedData<5, 0>(src->BGR)); + dst->alpha = 1.0f; +} + +void B5G6R5::writeColor(B5G6R5 *dst, const gl::ColorF *src) +{ + dst->BGR = gl::shiftData<5, 0>(gl::floatToNormalized<5, unsigned short>(src->blue)) | + gl::shiftData<6, 5>(gl::floatToNormalized<6, unsigned short>(src->green)) | + gl::shiftData<5, 11>(gl::floatToNormalized<5, unsigned short>(src->red)); +} + +void B5G6R5::average(B5G6R5 *dst, const B5G6R5 *src1, const B5G6R5 *src2) +{ + dst->BGR = gl::shiftData<5, 11>(gl::average(gl::getShiftedData<5, 11>(src1->BGR), + gl::getShiftedData<5, 11>(src2->BGR))) | + gl::shiftData<6, 5>(gl::average(gl::getShiftedData<6, 5>(src1->BGR), + gl::getShiftedData<6, 5>(src2->BGR))) | + gl::shiftData<5, 0>(gl::average(gl::getShiftedData<5, 0>(src1->BGR), + gl::getShiftedData<5, 0>(src2->BGR))); +} + +void A8R8G8B8::readColor(gl::ColorUI *dst, const A8R8G8B8 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; +} + +void A8R8G8B8::readColor(gl::ColorF *dst, const A8R8G8B8 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = gl::normalizedToFloat(src->A); +} + +void A8R8G8B8::writeColor(A8R8G8B8 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast(src->red); + dst->G = static_cast(src->green); + dst->B = static_cast(src->blue); + dst->A = static_cast(src->alpha); +} + +void A8R8G8B8::writeColor(A8R8G8B8 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); + dst->G = gl::floatToNormalized(src->green); + dst->B = gl::floatToNormalized(src->blue); + dst->A = gl::floatToNormalized(src->alpha); +} + +void A8R8G8B8::average(A8R8G8B8 *dst, const A8R8G8B8 *src1, const A8R8G8B8 *src2) +{ + *(uint32_t *)dst = (((*(uint32_t *)src1 ^ *(uint32_t *)src2) & 0xFEFEFEFE) >> 1) + + (*(uint32_t *)src1 & *(uint32_t *)src2); +} + +void R8G8B8A8::readColor(gl::ColorUI *dst, const R8G8B8A8 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; +} + +void R8G8B8A8::readColor(gl::ColorF *dst, const R8G8B8A8 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = gl::normalizedToFloat(src->A); +} + +void R8G8B8A8::writeColor(R8G8B8A8 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast(src->red); + dst->G = static_cast(src->green); + dst->B = static_cast(src->blue); + dst->A = static_cast(src->alpha); +} + +void R8G8B8A8::writeColor(R8G8B8A8 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); + dst->G = gl::floatToNormalized(src->green); + dst->B = gl::floatToNormalized(src->blue); + dst->A = gl::floatToNormalized(src->alpha); +} + +void R8G8B8A8::average(R8G8B8A8 *dst, const R8G8B8A8 *src1, const R8G8B8A8 *src2) +{ + *(uint32_t *)dst = (((*(uint32_t *)src1 ^ *(uint32_t *)src2) & 0xFEFEFEFE) >> 1) + + (*(uint32_t *)src1 & *(uint32_t *)src2); +} + +void R8G8B8A8SRGB::readColor(gl::ColorF *dst, const R8G8B8A8SRGB *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = gl::normalizedToFloat(src->A); +} + +void R8G8B8A8SRGB::writeColor(R8G8B8A8SRGB *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); + dst->G = gl::floatToNormalized(src->green); + dst->B = gl::floatToNormalized(src->blue); + dst->A = gl::floatToNormalized(src->alpha); +} + +void R8G8B8A8SRGB::average(R8G8B8A8SRGB *dst, const R8G8B8A8SRGB *src1, const R8G8B8A8SRGB *src2) +{ + dst->R = + gl::linearToSRGB(static_cast((static_cast(gl::sRGBToLinear(src1->R)) + + static_cast(gl::sRGBToLinear(src2->R))) >> + 1)); + dst->G = + gl::linearToSRGB(static_cast((static_cast(gl::sRGBToLinear(src1->G)) + + static_cast(gl::sRGBToLinear(src2->G))) >> + 1)); + dst->B = + gl::linearToSRGB(static_cast((static_cast(gl::sRGBToLinear(src1->B)) + + static_cast(gl::sRGBToLinear(src2->B))) >> + 1)); + dst->A = static_cast( + (static_cast(src1->A) + static_cast(src2->A)) >> 1); +} + +void B8G8R8A8::readColor(gl::ColorUI *dst, const B8G8R8A8 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; +} + +void B8G8R8A8::readColor(gl::ColorF *dst, const B8G8R8A8 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = gl::normalizedToFloat(src->A); +} + +void B8G8R8A8::writeColor(B8G8R8A8 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast(src->red); + dst->G = static_cast(src->green); + dst->B = static_cast(src->blue); + dst->A = static_cast(src->alpha); +} + +void B8G8R8A8::writeColor(B8G8R8A8 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); + dst->G = gl::floatToNormalized(src->green); + dst->B = gl::floatToNormalized(src->blue); + dst->A = gl::floatToNormalized(src->alpha); +} + +void B8G8R8A8::average(B8G8R8A8 *dst, const B8G8R8A8 *src1, const B8G8R8A8 *src2) +{ + *(uint32_t *)dst = (((*(uint32_t *)src1 ^ *(uint32_t *)src2) & 0xFEFEFEFE) >> 1) + + (*(uint32_t *)src1 & *(uint32_t *)src2); +} + +void B8G8R8X8::readColor(gl::ColorUI *dst, const B8G8R8X8 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = 1; +} + +void B8G8R8X8::readColor(gl::ColorF *dst, const B8G8R8X8 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = 1.0f; +} + +void B8G8R8X8::writeColor(B8G8R8X8 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast(src->red); + dst->G = static_cast(src->green); + dst->B = static_cast(src->blue); + dst->X = 255; +} + +void B8G8R8X8::writeColor(B8G8R8X8 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); + dst->G = gl::floatToNormalized(src->green); + dst->B = gl::floatToNormalized(src->blue); + dst->X = 255; +} + +void B8G8R8X8::average(B8G8R8X8 *dst, const B8G8R8X8 *src1, const B8G8R8X8 *src2) +{ + *(uint32_t *)dst = (((*(uint32_t *)src1 ^ *(uint32_t *)src2) & 0xFEFEFEFE) >> 1) + + (*(uint32_t *)src1 & *(uint32_t *)src2); + dst->X = 255; +} + +void A1R5G5B5::readColor(gl::ColorF *dst, const A1R5G5B5 *src) +{ + dst->alpha = gl::normalizedToFloat<1>(gl::getShiftedData<1, 15>(src->ARGB)); + dst->red = gl::normalizedToFloat<5>(gl::getShiftedData<5, 10>(src->ARGB)); + dst->green = gl::normalizedToFloat<5>(gl::getShiftedData<5, 5>(src->ARGB)); + dst->blue = gl::normalizedToFloat<5>(gl::getShiftedData<5, 0>(src->ARGB)); +} + +void A1R5G5B5::writeColor(A1R5G5B5 *dst, const gl::ColorF *src) +{ + dst->ARGB = gl::shiftData<1, 15>(gl::floatToNormalized<1, uint16_t>(src->alpha)) | + gl::shiftData<5, 10>(gl::floatToNormalized<5, uint16_t>(src->red)) | + gl::shiftData<5, 5>(gl::floatToNormalized<5, uint16_t>(src->green)) | + gl::shiftData<5, 0>(gl::floatToNormalized<5, uint16_t>(src->blue)); +} + +void A1R5G5B5::average(A1R5G5B5 *dst, const A1R5G5B5 *src1, const A1R5G5B5 *src2) +{ + dst->ARGB = gl::shiftData<1, 15>(gl::average(gl::getShiftedData<1, 15>(src1->ARGB), + gl::getShiftedData<1, 15>(src2->ARGB))) | + gl::shiftData<5, 10>(gl::average(gl::getShiftedData<5, 10>(src1->ARGB), + gl::getShiftedData<5, 10>(src2->ARGB))) | + gl::shiftData<5, 5>(gl::average(gl::getShiftedData<5, 5>(src1->ARGB), + gl::getShiftedData<5, 5>(src2->ARGB))) | + gl::shiftData<5, 0>(gl::average(gl::getShiftedData<5, 0>(src1->ARGB), + gl::getShiftedData<5, 0>(src2->ARGB))); +} + +void R5G5B5A1::readColor(gl::ColorF *dst, const R5G5B5A1 *src) +{ + dst->red = gl::normalizedToFloat<5>(gl::getShiftedData<5, 11>(src->RGBA)); + dst->green = gl::normalizedToFloat<5>(gl::getShiftedData<5, 6>(src->RGBA)); + dst->blue = gl::normalizedToFloat<5>(gl::getShiftedData<5, 1>(src->RGBA)); + dst->alpha = gl::normalizedToFloat<1>(gl::getShiftedData<1, 0>(src->RGBA)); +} + +void R5G5B5A1::writeColor(R5G5B5A1 *dst, const gl::ColorF *src) +{ + dst->RGBA = gl::shiftData<5, 11>(gl::floatToNormalized<5, uint16_t>(src->red)) | + gl::shiftData<5, 6>(gl::floatToNormalized<5, uint16_t>(src->green)) | + gl::shiftData<5, 1>(gl::floatToNormalized<5, uint16_t>(src->blue)) | + gl::shiftData<1, 0>(gl::floatToNormalized<1, uint16_t>(src->alpha)); +} + +void R5G5B5A1::average(R5G5B5A1 *dst, const R5G5B5A1 *src1, const R5G5B5A1 *src2) +{ + dst->RGBA = gl::shiftData<5, 11>(gl::average(gl::getShiftedData<5, 11>(src1->RGBA), + gl::getShiftedData<5, 11>(src2->RGBA))) | + gl::shiftData<5, 6>(gl::average(gl::getShiftedData<5, 6>(src1->RGBA), + gl::getShiftedData<5, 6>(src2->RGBA))) | + gl::shiftData<5, 1>(gl::average(gl::getShiftedData<5, 1>(src1->RGBA), + gl::getShiftedData<5, 1>(src2->RGBA))) | + gl::shiftData<1, 0>(gl::average(gl::getShiftedData<1, 0>(src1->RGBA), + gl::getShiftedData<1, 0>(src2->RGBA))); +} + +void R4G4B4A4::readColor(gl::ColorF *dst, const R4G4B4A4 *src) +{ + dst->red = gl::normalizedToFloat<4>(gl::getShiftedData<4, 12>(src->RGBA)); + dst->green = gl::normalizedToFloat<4>(gl::getShiftedData<4, 8>(src->RGBA)); + dst->blue = gl::normalizedToFloat<4>(gl::getShiftedData<4, 4>(src->RGBA)); + dst->alpha = gl::normalizedToFloat<4>(gl::getShiftedData<4, 0>(src->RGBA)); +} + +void R4G4B4A4::writeColor(R4G4B4A4 *dst, const gl::ColorF *src) +{ + dst->RGBA = gl::shiftData<4, 12>(gl::floatToNormalized<4, uint16_t>(src->red)) | + gl::shiftData<4, 8>(gl::floatToNormalized<4, uint16_t>(src->green)) | + gl::shiftData<4, 4>(gl::floatToNormalized<4, uint16_t>(src->blue)) | + gl::shiftData<4, 0>(gl::floatToNormalized<4, uint16_t>(src->alpha)); +} + +void R4G4B4A4::average(R4G4B4A4 *dst, const R4G4B4A4 *src1, const R4G4B4A4 *src2) +{ + dst->RGBA = gl::shiftData<4, 12>(gl::average(gl::getShiftedData<4, 12>(src1->RGBA), + gl::getShiftedData<4, 12>(src2->RGBA))) | + gl::shiftData<4, 8>(gl::average(gl::getShiftedData<4, 8>(src1->RGBA), + gl::getShiftedData<4, 8>(src2->RGBA))) | + gl::shiftData<4, 4>(gl::average(gl::getShiftedData<4, 4>(src1->RGBA), + gl::getShiftedData<4, 4>(src2->RGBA))) | + gl::shiftData<4, 0>(gl::average(gl::getShiftedData<4, 0>(src1->RGBA), + gl::getShiftedData<4, 0>(src2->RGBA))); +} + +void A4R4G4B4::readColor(gl::ColorF *dst, const A4R4G4B4 *src) +{ + dst->alpha = gl::normalizedToFloat<4>(gl::getShiftedData<4, 12>(src->ARGB)); + dst->red = gl::normalizedToFloat<4>(gl::getShiftedData<4, 8>(src->ARGB)); + dst->green = gl::normalizedToFloat<4>(gl::getShiftedData<4, 4>(src->ARGB)); + dst->blue = gl::normalizedToFloat<4>(gl::getShiftedData<4, 0>(src->ARGB)); +} + +void A4R4G4B4::writeColor(A4R4G4B4 *dst, const gl::ColorF *src) +{ + dst->ARGB = gl::shiftData<4, 12>(gl::floatToNormalized<4, uint16_t>(src->alpha)) | + gl::shiftData<4, 8>(gl::floatToNormalized<4, uint16_t>(src->red)) | + gl::shiftData<4, 4>(gl::floatToNormalized<4, uint16_t>(src->green)) | + gl::shiftData<4, 0>(gl::floatToNormalized<4, uint16_t>(src->blue)); +} + +void A4R4G4B4::average(A4R4G4B4 *dst, const A4R4G4B4 *src1, const A4R4G4B4 *src2) +{ + dst->ARGB = gl::shiftData<4, 12>(gl::average(gl::getShiftedData<4, 12>(src1->ARGB), + gl::getShiftedData<4, 12>(src2->ARGB))) | + gl::shiftData<4, 8>(gl::average(gl::getShiftedData<4, 8>(src1->ARGB), + gl::getShiftedData<4, 8>(src2->ARGB))) | + gl::shiftData<4, 4>(gl::average(gl::getShiftedData<4, 4>(src1->ARGB), + gl::getShiftedData<4, 4>(src2->ARGB))) | + gl::shiftData<4, 0>(gl::average(gl::getShiftedData<4, 0>(src1->ARGB), + gl::getShiftedData<4, 0>(src2->ARGB))); +} + +void R16::readColor(gl::ColorUI *dst, const R16 *src) +{ + dst->red = src->R; + dst->green = 0; + dst->blue = 0; + dst->alpha = 1; +} + +void R16::readColor(gl::ColorF *dst, const R16 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R16::writeColor(R16 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast(src->red); +} + +void R16::writeColor(R16 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); +} + +void R16::average(R16 *dst, const R16 *src1, const R16 *src2) +{ + dst->R = gl::average(src1->R, src2->R); +} + +void R16G16::readColor(gl::ColorUI *dst, const R16G16 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = 0; + dst->alpha = 1; +} + +void R16G16::readColor(gl::ColorF *dst, const R16G16 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R16G16::writeColor(R16G16 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast(src->red); + dst->G = static_cast(src->green); +} + +void R16G16::writeColor(R16G16 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); + dst->G = gl::floatToNormalized(src->green); +} + +void R16G16::average(R16G16 *dst, const R16G16 *src1, const R16G16 *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); +} + +void R16G16B16::readColor(gl::ColorUI *dst, const R16G16B16 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = 1; +} + +void R16G16B16::readColor(gl::ColorF *dst, const R16G16B16 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = 1.0f; +} + +void R16G16B16::writeColor(R16G16B16 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast(src->red); + dst->G = static_cast(src->green); + dst->B = static_cast(src->blue); +} + +void R16G16B16::writeColor(R16G16B16 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); + dst->G = gl::floatToNormalized(src->green); + dst->B = gl::floatToNormalized(src->blue); +} + +void R16G16B16::average(R16G16B16 *dst, const R16G16B16 *src1, const R16G16B16 *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); +} + +void R16G16B16A16::readColor(gl::ColorUI *dst, const R16G16B16A16 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; +} + +void R16G16B16A16::readColor(gl::ColorF *dst, const R16G16B16A16 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = gl::normalizedToFloat(src->A); +} + +void R16G16B16A16::writeColor(R16G16B16A16 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast(src->red); + dst->G = static_cast(src->green); + dst->B = static_cast(src->blue); + dst->A = static_cast(src->alpha); +} + +void R16G16B16A16::writeColor(R16G16B16A16 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); + dst->G = gl::floatToNormalized(src->green); + dst->B = gl::floatToNormalized(src->blue); + dst->A = gl::floatToNormalized(src->alpha); +} + +void R16G16B16A16::average(R16G16B16A16 *dst, const R16G16B16A16 *src1, const R16G16B16A16 *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + dst->A = gl::average(src1->A, src2->A); +} + +void R32::readColor(gl::ColorUI *dst, const R32 *src) +{ + dst->red = src->R; + dst->green = 0; + dst->blue = 0; + dst->alpha = 1; +} + +void R32::readColor(gl::ColorF *dst, const R32 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R32::writeColor(R32 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast(src->red); +} + +void R32::writeColor(R32 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); +} + +void R32::average(R32 *dst, const R32 *src1, const R32 *src2) +{ + dst->R = gl::average(src1->R, src2->R); +} + +void R32G32::readColor(gl::ColorUI *dst, const R32G32 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = 0; + dst->alpha = 1; +} + +void R32G32::readColor(gl::ColorF *dst, const R32G32 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R32G32::writeColor(R32G32 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast(src->red); + dst->G = static_cast(src->green); +} + +void R32G32::writeColor(R32G32 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); + dst->G = gl::floatToNormalized(src->green); +} + +void R32G32::average(R32G32 *dst, const R32G32 *src1, const R32G32 *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); +} + +void R32G32B32::readColor(gl::ColorUI *dst, const R32G32B32 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = 1; +} + +void R32G32B32::readColor(gl::ColorF *dst, const R32G32B32 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = 1.0f; +} + +void R32G32B32::writeColor(R32G32B32 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast(src->red); + dst->G = static_cast(src->green); + dst->B = static_cast(src->blue); +} + +void R32G32B32::writeColor(R32G32B32 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); + dst->G = gl::floatToNormalized(src->green); + dst->B = gl::floatToNormalized(src->blue); +} + +void R32G32B32::average(R32G32B32 *dst, const R32G32B32 *src1, const R32G32B32 *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); +} + +void R32G32B32A32::readColor(gl::ColorUI *dst, const R32G32B32A32 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; +} + +void R32G32B32A32::readColor(gl::ColorF *dst, const R32G32B32A32 *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = gl::normalizedToFloat(src->A); +} + +void R32G32B32A32::writeColor(R32G32B32A32 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast(src->red); + dst->G = static_cast(src->green); + dst->B = static_cast(src->blue); + dst->A = static_cast(src->alpha); +} + +void R32G32B32A32::writeColor(R32G32B32A32 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); + dst->G = gl::floatToNormalized(src->green); + dst->B = gl::floatToNormalized(src->blue); + dst->A = gl::floatToNormalized(src->alpha); +} + +void R32G32B32A32::average(R32G32B32A32 *dst, const R32G32B32A32 *src1, const R32G32B32A32 *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + dst->A = gl::average(src1->A, src2->A); +} + +void R8S::readColor(gl::ColorI *dst, const R8S *src) +{ + dst->red = src->R; + dst->green = 0; + dst->blue = 0; + dst->alpha = 1; +} + +void R8S::readColor(gl::ColorF *dst, const R8S *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R8S::writeColor(R8S *dst, const gl::ColorI *src) +{ + dst->R = static_cast(src->red); +} + +void R8S::writeColor(R8S *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); +} + +void R8S::average(R8S *dst, const R8S *src1, const R8S *src2) +{ + dst->R = static_cast(gl::average(src1->R, src2->R)); +} + +void R8G8S::readColor(gl::ColorI *dst, const R8G8S *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = 0; + dst->alpha = 1; +} + +void R8G8S::readColor(gl::ColorF *dst, const R8G8S *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R8G8S::writeColor(R8G8S *dst, const gl::ColorI *src) +{ + dst->R = static_cast(src->red); + dst->G = static_cast(src->green); +} + +void R8G8S::writeColor(R8G8S *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); + dst->G = gl::floatToNormalized(src->green); +} + +void R8G8S::average(R8G8S *dst, const R8G8S *src1, const R8G8S *src2) +{ + dst->R = static_cast(gl::average(src1->R, src2->R)); + dst->G = static_cast(gl::average(src1->G, src2->G)); +} + +void R8G8B8S::readColor(gl::ColorI *dst, const R8G8B8S *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = 1; +} + +void R8G8B8S::readColor(gl::ColorF *dst, const R8G8B8S *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = 1.0f; +} + +void R8G8B8S::writeColor(R8G8B8S *dst, const gl::ColorI *src) +{ + dst->R = static_cast(src->red); + dst->G = static_cast(src->green); + dst->B = static_cast(src->blue); +} + +void R8G8B8S::writeColor(R8G8B8S *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); + dst->G = gl::floatToNormalized(src->green); + dst->B = gl::floatToNormalized(src->blue); +} + +void R8G8B8S::average(R8G8B8S *dst, const R8G8B8S *src1, const R8G8B8S *src2) +{ + dst->R = static_cast(gl::average(src1->R, src2->R)); + dst->G = static_cast(gl::average(src1->G, src2->G)); + dst->B = static_cast(gl::average(src1->B, src2->B)); +} + +void R8G8B8A8S::readColor(gl::ColorI *dst, const R8G8B8A8S *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; +} + +void R8G8B8A8S::readColor(gl::ColorF *dst, const R8G8B8A8S *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = gl::normalizedToFloat(src->A); +} + +void R8G8B8A8S::writeColor(R8G8B8A8S *dst, const gl::ColorI *src) +{ + dst->R = static_cast(src->red); + dst->G = static_cast(src->green); + dst->B = static_cast(src->blue); + dst->A = static_cast(src->alpha); +} + +void R8G8B8A8S::writeColor(R8G8B8A8S *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); + dst->G = gl::floatToNormalized(src->green); + dst->B = gl::floatToNormalized(src->blue); + dst->A = gl::floatToNormalized(src->alpha); +} + +void R8G8B8A8S::average(R8G8B8A8S *dst, const R8G8B8A8S *src1, const R8G8B8A8S *src2) +{ + dst->R = static_cast(gl::average(src1->R, src2->R)); + dst->G = static_cast(gl::average(src1->G, src2->G)); + dst->B = static_cast(gl::average(src1->B, src2->B)); + dst->A = static_cast(gl::average(src1->A, src2->A)); +} + +void R16S::readColor(gl::ColorI *dst, const R16S *src) +{ + dst->red = src->R; + dst->green = 0; + dst->blue = 0; + dst->alpha = 1; +} + +void R16S::readColor(gl::ColorF *dst, const R16S *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R16S::writeColor(R16S *dst, const gl::ColorI *src) +{ + dst->R = static_cast(src->red); +} + +void R16S::writeColor(R16S *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); +} + +void R16S::average(R16S *dst, const R16S *src1, const R16S *src2) +{ + dst->R = gl::average(src1->R, src2->R); +} + +void R16G16S::readColor(gl::ColorI *dst, const R16G16S *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = 0; + dst->alpha = 1; +} + +void R16G16S::readColor(gl::ColorF *dst, const R16G16S *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R16G16S::writeColor(R16G16S *dst, const gl::ColorI *src) +{ + dst->R = static_cast(src->red); + dst->G = static_cast(src->green); +} + +void R16G16S::writeColor(R16G16S *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); + dst->G = gl::floatToNormalized(src->green); +} + +void R16G16S::average(R16G16S *dst, const R16G16S *src1, const R16G16S *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); +} + +void R16G16B16S::readColor(gl::ColorI *dst, const R16G16B16S *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = 1; +} + +void R16G16B16S::readColor(gl::ColorF *dst, const R16G16B16S *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = 1.0f; +} + +void R16G16B16S::writeColor(R16G16B16S *dst, const gl::ColorI *src) +{ + dst->R = static_cast(src->red); + dst->G = static_cast(src->green); + dst->B = static_cast(src->blue); +} + +void R16G16B16S::writeColor(R16G16B16S *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); + dst->G = gl::floatToNormalized(src->green); + dst->B = gl::floatToNormalized(src->blue); +} + +void R16G16B16S::average(R16G16B16S *dst, const R16G16B16S *src1, const R16G16B16S *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); +} + +void R16G16B16A16S::readColor(gl::ColorI *dst, const R16G16B16A16S *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; +} + +void R16G16B16A16S::readColor(gl::ColorF *dst, const R16G16B16A16S *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = gl::normalizedToFloat(src->A); +} + +void R16G16B16A16S::writeColor(R16G16B16A16S *dst, const gl::ColorI *src) +{ + dst->R = static_cast(src->red); + dst->G = static_cast(src->green); + dst->B = static_cast(src->blue); + dst->A = static_cast(src->alpha); +} + +void R16G16B16A16S::writeColor(R16G16B16A16S *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); + dst->G = gl::floatToNormalized(src->green); + dst->B = gl::floatToNormalized(src->blue); + dst->A = gl::floatToNormalized(src->alpha); +} + +void R16G16B16A16S::average(R16G16B16A16S *dst, + const R16G16B16A16S *src1, + const R16G16B16A16S *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + dst->A = gl::average(src1->A, src2->A); +} + +void R32S::readColor(gl::ColorI *dst, const R32S *src) +{ + dst->red = src->R; + dst->green = 0; + dst->blue = 0; + dst->alpha = 1; +} + +void R32S::readColor(gl::ColorF *dst, const R32S *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R32S::writeColor(R32S *dst, const gl::ColorI *src) +{ + dst->R = static_cast(src->red); +} + +void R32S::writeColor(R32S *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); +} + +void R32S::average(R32S *dst, const R32S *src1, const R32S *src2) +{ + dst->R = gl::average(src1->R, src2->R); +} + +void R32G32S::readColor(gl::ColorI *dst, const R32G32S *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = 0; + dst->alpha = 1; +} + +void R32G32S::readColor(gl::ColorF *dst, const R32G32S *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R32G32S::writeColor(R32G32S *dst, const gl::ColorI *src) +{ + dst->R = static_cast(src->red); + dst->G = static_cast(src->green); +} + +void R32G32S::writeColor(R32G32S *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); + dst->G = gl::floatToNormalized(src->green); +} + +void R32G32S::average(R32G32S *dst, const R32G32S *src1, const R32G32S *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); +} + +void R32G32B32S::readColor(gl::ColorI *dst, const R32G32B32S *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = 1; +} + +void R32G32B32S::readColor(gl::ColorF *dst, const R32G32B32S *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = 1.0f; +} + +void R32G32B32S::writeColor(R32G32B32S *dst, const gl::ColorI *src) +{ + dst->R = static_cast(src->red); + dst->G = static_cast(src->green); + dst->B = static_cast(src->blue); +} + +void R32G32B32S::writeColor(R32G32B32S *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); + dst->G = gl::floatToNormalized(src->green); + dst->B = gl::floatToNormalized(src->blue); +} + +void R32G32B32S::average(R32G32B32S *dst, const R32G32B32S *src1, const R32G32B32S *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); +} + +void R32G32B32A32S::readColor(gl::ColorI *dst, const R32G32B32A32S *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; +} + +void R32G32B32A32S::readColor(gl::ColorF *dst, const R32G32B32A32S *src) +{ + dst->red = gl::normalizedToFloat(src->R); + dst->green = gl::normalizedToFloat(src->G); + dst->blue = gl::normalizedToFloat(src->B); + dst->alpha = gl::normalizedToFloat(src->A); +} + +void R32G32B32A32S::writeColor(R32G32B32A32S *dst, const gl::ColorI *src) +{ + dst->R = static_cast(src->red); + dst->G = static_cast(src->green); + dst->B = static_cast(src->blue); + dst->A = static_cast(src->alpha); +} + +void R32G32B32A32S::writeColor(R32G32B32A32S *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized(src->red); + dst->G = gl::floatToNormalized(src->green); + dst->B = gl::floatToNormalized(src->blue); + dst->A = gl::floatToNormalized(src->alpha); +} + +void R32G32B32A32S::average(R32G32B32A32S *dst, + const R32G32B32A32S *src1, + const R32G32B32A32S *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + dst->A = gl::average(src1->A, src2->A); +} + +void A16B16G16R16F::readColor(gl::ColorF *dst, const A16B16G16R16F *src) +{ + dst->red = gl::float16ToFloat32(src->R); + dst->green = gl::float16ToFloat32(src->G); + dst->blue = gl::float16ToFloat32(src->B); + dst->alpha = gl::float16ToFloat32(src->A); +} + +void A16B16G16R16F::writeColor(A16B16G16R16F *dst, const gl::ColorF *src) +{ + dst->R = gl::float32ToFloat16(src->red); + dst->G = gl::float32ToFloat16(src->green); + dst->B = gl::float32ToFloat16(src->blue); + dst->A = gl::float32ToFloat16(src->alpha); +} + +void A16B16G16R16F::average(A16B16G16R16F *dst, + const A16B16G16R16F *src1, + const A16B16G16R16F *src2) +{ + dst->R = gl::averageHalfFloat(src1->R, src2->R); + dst->G = gl::averageHalfFloat(src1->G, src2->G); + dst->B = gl::averageHalfFloat(src1->B, src2->B); + dst->A = gl::averageHalfFloat(src1->A, src2->A); +} + +void R16G16B16A16F::readColor(gl::ColorF *dst, const R16G16B16A16F *src) +{ + dst->red = gl::float16ToFloat32(src->R); + dst->green = gl::float16ToFloat32(src->G); + dst->blue = gl::float16ToFloat32(src->B); + dst->alpha = gl::float16ToFloat32(src->A); +} + +void R16G16B16A16F::writeColor(R16G16B16A16F *dst, const gl::ColorF *src) +{ + dst->R = gl::float32ToFloat16(src->red); + dst->G = gl::float32ToFloat16(src->green); + dst->B = gl::float32ToFloat16(src->blue); + dst->A = gl::float32ToFloat16(src->alpha); +} + +void R16G16B16A16F::average(R16G16B16A16F *dst, + const R16G16B16A16F *src1, + const R16G16B16A16F *src2) +{ + dst->R = gl::averageHalfFloat(src1->R, src2->R); + dst->G = gl::averageHalfFloat(src1->G, src2->G); + dst->B = gl::averageHalfFloat(src1->B, src2->B); + dst->A = gl::averageHalfFloat(src1->A, src2->A); +} + +void R16F::readColor(gl::ColorF *dst, const R16F *src) +{ + dst->red = gl::float16ToFloat32(src->R); + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R16F::writeColor(R16F *dst, const gl::ColorF *src) +{ + dst->R = gl::float32ToFloat16(src->red); +} + +void R16F::average(R16F *dst, const R16F *src1, const R16F *src2) +{ + dst->R = gl::averageHalfFloat(src1->R, src2->R); +} + +void A16F::readColor(gl::ColorF *dst, const A16F *src) +{ + dst->red = 0.0f; + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = gl::float16ToFloat32(src->A); +} + +void A16F::writeColor(A16F *dst, const gl::ColorF *src) +{ + dst->A = gl::float32ToFloat16(src->alpha); +} + +void A16F::average(A16F *dst, const A16F *src1, const A16F *src2) +{ + dst->A = gl::averageHalfFloat(src1->A, src2->A); +} + +void L16F::readColor(gl::ColorF *dst, const L16F *src) +{ + float lum = gl::float16ToFloat32(src->L); + dst->red = lum; + dst->green = lum; + dst->blue = lum; + dst->alpha = 1.0f; +} + +void L16F::writeColor(L16F *dst, const gl::ColorF *src) +{ + dst->L = gl::float32ToFloat16(src->red); +} + +void L16F::average(L16F *dst, const L16F *src1, const L16F *src2) +{ + dst->L = gl::averageHalfFloat(src1->L, src2->L); +} + +void L16A16F::readColor(gl::ColorF *dst, const L16A16F *src) +{ + float lum = gl::float16ToFloat32(src->L); + dst->red = lum; + dst->green = lum; + dst->blue = lum; + dst->alpha = gl::float16ToFloat32(src->A); +} + +void L16A16F::writeColor(L16A16F *dst, const gl::ColorF *src) +{ + dst->L = gl::float32ToFloat16(src->red); + dst->A = gl::float32ToFloat16(src->alpha); +} + +void L16A16F::average(L16A16F *dst, const L16A16F *src1, const L16A16F *src2) +{ + dst->L = gl::averageHalfFloat(src1->L, src2->L); + dst->A = gl::averageHalfFloat(src1->A, src2->A); +} + +void R16G16F::readColor(gl::ColorF *dst, const R16G16F *src) +{ + dst->red = gl::float16ToFloat32(src->R); + dst->green = gl::float16ToFloat32(src->G); + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R16G16F::writeColor(R16G16F *dst, const gl::ColorF *src) +{ + dst->R = gl::float32ToFloat16(src->red); + dst->G = gl::float32ToFloat16(src->green); +} + +void R16G16F::average(R16G16F *dst, const R16G16F *src1, const R16G16F *src2) +{ + dst->R = gl::averageHalfFloat(src1->R, src2->R); + dst->G = gl::averageHalfFloat(src1->G, src2->G); +} + +void R16G16B16F::readColor(gl::ColorF *dst, const R16G16B16F *src) +{ + dst->red = gl::float16ToFloat32(src->R); + dst->green = gl::float16ToFloat32(src->G); + dst->blue = gl::float16ToFloat32(src->B); + dst->alpha = 1.0f; +} + +void R16G16B16F::writeColor(R16G16B16F *dst, const gl::ColorF *src) +{ + dst->R = gl::float32ToFloat16(src->red); + dst->G = gl::float32ToFloat16(src->green); + dst->B = gl::float32ToFloat16(src->blue); +} + +void R16G16B16F::average(R16G16B16F *dst, const R16G16B16F *src1, const R16G16B16F *src2) +{ + dst->R = gl::averageHalfFloat(src1->R, src2->R); + dst->G = gl::averageHalfFloat(src1->G, src2->G); + dst->B = gl::averageHalfFloat(src1->B, src2->B); +} + +void A32B32G32R32F::readColor(gl::ColorF *dst, const A32B32G32R32F *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; +} + +void A32B32G32R32F::writeColor(A32B32G32R32F *dst, const gl::ColorF *src) +{ + dst->R = src->red; + dst->G = src->green; + dst->B = src->blue; + dst->A = src->alpha; +} + +void A32B32G32R32F::average(A32B32G32R32F *dst, + const A32B32G32R32F *src1, + const A32B32G32R32F *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + dst->A = gl::average(src1->A, src2->A); +} + +void R32G32B32A32F::readColor(gl::ColorF *dst, const R32G32B32A32F *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; +} + +void R32G32B32A32F::writeColor(R32G32B32A32F *dst, const gl::ColorF *src) +{ + dst->R = src->red; + dst->G = src->green; + dst->B = src->blue; + dst->A = src->alpha; +} + +void R32G32B32A32F::average(R32G32B32A32F *dst, + const R32G32B32A32F *src1, + const R32G32B32A32F *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + dst->A = gl::average(src1->A, src2->A); +} + +void R32F::readColor(gl::ColorF *dst, const R32F *src) +{ + dst->red = src->R; + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R32F::writeColor(R32F *dst, const gl::ColorF *src) +{ + dst->R = src->red; +} + +void R32F::average(R32F *dst, const R32F *src1, const R32F *src2) +{ + dst->R = gl::average(src1->R, src2->R); +} + +void A32F::readColor(gl::ColorF *dst, const A32F *src) +{ + dst->red = 0.0f; + dst->green = 0.0f; + dst->blue = 0.0f; + dst->alpha = src->A; +} + +void A32F::writeColor(A32F *dst, const gl::ColorF *src) +{ + dst->A = src->alpha; +} + +void A32F::average(A32F *dst, const A32F *src1, const A32F *src2) +{ + dst->A = gl::average(src1->A, src2->A); +} + +void L32F::readColor(gl::ColorF *dst, const L32F *src) +{ + dst->red = src->L; + dst->green = src->L; + dst->blue = src->L; + dst->alpha = 1.0f; +} + +void L32F::writeColor(L32F *dst, const gl::ColorF *src) +{ + dst->L = src->red; +} + +void L32F::average(L32F *dst, const L32F *src1, const L32F *src2) +{ + dst->L = gl::average(src1->L, src2->L); +} + +void L32A32F::readColor(gl::ColorF *dst, const L32A32F *src) +{ + dst->red = src->L; + dst->green = src->L; + dst->blue = src->L; + dst->alpha = src->A; +} + +void L32A32F::writeColor(L32A32F *dst, const gl::ColorF *src) +{ + dst->L = src->red; + dst->A = src->alpha; +} + +void L32A32F::average(L32A32F *dst, const L32A32F *src1, const L32A32F *src2) +{ + dst->L = gl::average(src1->L, src2->L); + dst->A = gl::average(src1->A, src2->A); +} + +void R32G32F::readColor(gl::ColorF *dst, const R32G32F *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = 0.0f; + dst->alpha = 1.0f; +} + +void R32G32F::writeColor(R32G32F *dst, const gl::ColorF *src) +{ + dst->R = src->red; + dst->G = src->green; +} + +void R32G32F::average(R32G32F *dst, const R32G32F *src1, const R32G32F *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); +} + +void R32G32B32F::readColor(gl::ColorF *dst, const R32G32B32F *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = 1.0f; +} + +void R32G32B32F::writeColor(R32G32B32F *dst, const gl::ColorF *src) +{ + dst->R = src->red; + dst->G = src->green; + dst->B = src->blue; +} + +void R32G32B32F::average(R32G32B32F *dst, const R32G32B32F *src1, const R32G32B32F *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); +} + +void R10G10B10A2::readColor(gl::ColorUI *dst, const R10G10B10A2 *src) +{ + dst->red = src->R; + dst->green = src->G; + dst->blue = src->B; + dst->alpha = src->A; +} + +void R10G10B10A2::readColor(gl::ColorF *dst, const R10G10B10A2 *src) +{ + dst->red = gl::normalizedToFloat<10>(src->R); + dst->green = gl::normalizedToFloat<10>(src->G); + dst->blue = gl::normalizedToFloat<10>(src->B); + dst->alpha = gl::normalizedToFloat<2>(src->A); +} + +void R10G10B10A2::writeColor(R10G10B10A2 *dst, const gl::ColorUI *src) +{ + dst->R = static_cast(src->red); + dst->G = static_cast(src->green); + dst->B = static_cast(src->blue); + dst->A = static_cast(src->alpha); +} + +void R10G10B10A2::writeColor(R10G10B10A2 *dst, const gl::ColorF *src) +{ + dst->R = gl::floatToNormalized<10, uint32_t>(src->red); + dst->G = gl::floatToNormalized<10, uint32_t>(src->green); + dst->B = gl::floatToNormalized<10, uint32_t>(src->blue); + dst->A = gl::floatToNormalized<2, uint32_t>(src->alpha); +} + +void R10G10B10A2::average(R10G10B10A2 *dst, const R10G10B10A2 *src1, const R10G10B10A2 *src2) +{ + dst->R = gl::average(src1->R, src2->R); + dst->G = gl::average(src1->G, src2->G); + dst->B = gl::average(src1->B, src2->B); + dst->A = gl::average(src1->A, src2->A); +} + +void R9G9B9E5::readColor(gl::ColorF *dst, const R9G9B9E5 *src) +{ + gl::convert999E5toRGBFloats(gl::bitCast(*src), &dst->red, &dst->green, &dst->blue); + dst->alpha = 1.0f; +} + +void R9G9B9E5::writeColor(R9G9B9E5 *dst, const gl::ColorF *src) +{ + *reinterpret_cast(dst) = + gl::convertRGBFloatsTo999E5(src->red, src->green, src->blue); +} + +void R9G9B9E5::average(R9G9B9E5 *dst, const R9G9B9E5 *src1, const R9G9B9E5 *src2) +{ + float r1, g1, b1; + gl::convert999E5toRGBFloats(*reinterpret_cast(src1), &r1, &g1, &b1); + + float r2, g2, b2; + gl::convert999E5toRGBFloats(*reinterpret_cast(src2), &r2, &g2, &b2); + + *reinterpret_cast(dst) = + gl::convertRGBFloatsTo999E5(gl::average(r1, r2), gl::average(g1, g2), gl::average(b1, b2)); +} + +void R11G11B10F::readColor(gl::ColorF *dst, const R11G11B10F *src) +{ + dst->red = gl::float11ToFloat32(src->R); + dst->green = gl::float11ToFloat32(src->G); + dst->blue = gl::float10ToFloat32(src->B); + dst->alpha = 1.0f; +} + +void R11G11B10F::writeColor(R11G11B10F *dst, const gl::ColorF *src) +{ + dst->R = gl::float32ToFloat11(src->red); + dst->G = gl::float32ToFloat11(src->green); + dst->B = gl::float32ToFloat10(src->blue); +} + +void R11G11B10F::average(R11G11B10F *dst, const R11G11B10F *src1, const R11G11B10F *src2) +{ + dst->R = gl::averageFloat11(src1->R, src2->R); + dst->G = gl::averageFloat11(src1->G, src2->G); + dst->B = gl::averageFloat10(src1->B, src2->B); +} + +} // namespace angle diff --git a/src/3rdparty/angle/src/image_util/imageformats.h b/src/3rdparty/angle/src/image_util/imageformats.h new file mode 100644 index 0000000000..65644cd8d9 --- /dev/null +++ b/src/3rdparty/angle/src/image_util/imageformats.h @@ -0,0 +1,700 @@ +// +// Copyright (c) 2013-2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// imageformats.h: Defines image format types with functions for mip generation +// and copying. + +#ifndef IMAGEUTIL_IMAGEFORMATS_H_ +#define IMAGEUTIL_IMAGEFORMATS_H_ + +#include "common/Color.h" + +#include + +namespace angle +{ + +// Several structures share functionality for reading, writing or mipmapping but the layout +// must match the texture format which the structure represents. If collapsing or typedefing +// structs in this header, make sure the functionality and memory layout is exactly the same. + +struct L8 +{ + uint8_t L; + + static void readColor(gl::ColorF *dst, const L8 *src); + static void writeColor(L8 *dst, const gl::ColorF *src); + static void average(L8 *dst, const L8 *src1, const L8 *src2); +}; + +struct R8 +{ + uint8_t R; + + static void readColor(gl::ColorF *dst, const R8 *src); + static void readColor(gl::ColorUI *dst, const R8 *src); + static void writeColor(R8 *dst, const gl::ColorF *src); + static void writeColor(R8 *dst, const gl::ColorUI *src); + static void average(R8 *dst, const R8 *src1, const R8 *src2); +}; + +struct A8 +{ + uint8_t A; + + static void readColor(gl::ColorF *dst, const A8 *src); + static void writeColor(A8 *dst, const gl::ColorF *src); + static void average(A8 *dst, const A8 *src1, const A8 *src2); +}; + +struct L8A8 +{ + uint8_t L; + uint8_t A; + + static void readColor(gl::ColorF *dst, const L8A8 *src); + static void writeColor(L8A8 *dst, const gl::ColorF *src); + static void average(L8A8 *dst, const L8A8 *src1, const L8A8 *src2); +}; + +struct A8L8 +{ + uint8_t A; + uint8_t L; + + static void readColor(gl::ColorF *dst, const A8L8 *src); + static void writeColor(A8L8 *dst, const gl::ColorF *src); + static void average(A8L8 *dst, const A8L8 *src1, const A8L8 *src2); +}; + +struct R8G8 +{ + uint8_t R; + uint8_t G; + + static void readColor(gl::ColorF *dst, const R8G8 *src); + static void readColor(gl::ColorUI *dst, const R8G8 *src); + static void writeColor(R8G8 *dst, const gl::ColorF *src); + static void writeColor(R8G8 *dst, const gl::ColorUI *src); + static void average(R8G8 *dst, const R8G8 *src1, const R8G8 *src2); +}; + +struct R8G8B8 +{ + uint8_t R; + uint8_t G; + uint8_t B; + + static void readColor(gl::ColorF *dst, const R8G8B8 *src); + static void readColor(gl::ColorUI *dst, const R8G8B8 *src); + static void writeColor(R8G8B8 *dst, const gl::ColorF *src); + static void writeColor(R8G8B8 *dst, const gl::ColorUI *src); + static void average(R8G8B8 *dst, const R8G8B8 *src1, const R8G8B8 *src2); +}; + +struct B8G8R8 +{ + uint8_t B; + uint8_t G; + uint8_t R; + + static void readColor(gl::ColorF *dst, const B8G8R8 *src); + static void readColor(gl::ColorUI *dst, const B8G8R8 *src); + static void writeColor(B8G8R8 *dst, const gl::ColorF *src); + static void writeColor(B8G8R8 *dst, const gl::ColorUI *src); + static void average(B8G8R8 *dst, const B8G8R8 *src1, const B8G8R8 *src2); +}; + +struct R5G6B5 +{ + // OpenGL ES 2.0.25 spec Section 3.6.2: "Components are packed with the first component in the + // most significant bits of the bitfield, and successive component occupying progressively less + // significant locations" + uint16_t RGB; + + static void readColor(gl::ColorF *dst, const R5G6B5 *src); + static void writeColor(R5G6B5 *dst, const gl::ColorF *src); + static void average(R5G6B5 *dst, const R5G6B5 *src1, const R5G6B5 *src2); +}; + +struct B5G6R5 +{ + uint16_t BGR; + + static void readColor(gl::ColorF *dst, const B5G6R5 *src); + static void writeColor(B5G6R5 *dst, const gl::ColorF *src); + static void average(B5G6R5 *dst, const B5G6R5 *src1, const B5G6R5 *src2); +}; + +struct A8R8G8B8 +{ + uint8_t A; + uint8_t R; + uint8_t G; + uint8_t B; + + static void readColor(gl::ColorF *dst, const A8R8G8B8 *src); + static void readColor(gl::ColorUI *dst, const A8R8G8B8 *src); + static void writeColor(A8R8G8B8 *dst, const gl::ColorF *src); + static void writeColor(A8R8G8B8 *dst, const gl::ColorUI *src); + static void average(A8R8G8B8 *dst, const A8R8G8B8 *src1, const A8R8G8B8 *src2); +}; + +struct R8G8B8A8 +{ + uint8_t R; + uint8_t G; + uint8_t B; + uint8_t A; + + static void readColor(gl::ColorF *dst, const R8G8B8A8 *src); + static void readColor(gl::ColorUI *dst, const R8G8B8A8 *src); + static void writeColor(R8G8B8A8 *dst, const gl::ColorF *src); + static void writeColor(R8G8B8A8 *dst, const gl::ColorUI *src); + static void average(R8G8B8A8 *dst, const R8G8B8A8 *src1, const R8G8B8A8 *src2); +}; + +struct R8G8B8A8SRGB +{ + uint8_t R; + uint8_t G; + uint8_t B; + uint8_t A; + + static void readColor(gl::ColorF *dst, const R8G8B8A8SRGB *src); + static void writeColor(R8G8B8A8SRGB *dst, const gl::ColorF *src); + static void average(R8G8B8A8SRGB *dst, const R8G8B8A8SRGB *src1, const R8G8B8A8SRGB *src2); +}; + +struct B8G8R8A8 +{ + uint8_t B; + uint8_t G; + uint8_t R; + uint8_t A; + + static void readColor(gl::ColorF *dst, const B8G8R8A8 *src); + static void readColor(gl::ColorUI *dst, const B8G8R8A8 *src); + static void writeColor(B8G8R8A8 *dst, const gl::ColorF *src); + static void writeColor(B8G8R8A8 *dst, const gl::ColorUI *src); + static void average(B8G8R8A8 *dst, const B8G8R8A8 *src1, const B8G8R8A8 *src2); +}; + +struct B8G8R8X8 +{ + uint8_t B; + uint8_t G; + uint8_t R; + uint8_t X; + + static void readColor(gl::ColorF *dst, const B8G8R8X8 *src); + static void readColor(gl::ColorUI *dst, const B8G8R8X8 *src); + static void writeColor(B8G8R8X8 *dst, const gl::ColorF *src); + static void writeColor(B8G8R8X8 *dst, const gl::ColorUI *src); + static void average(B8G8R8X8 *dst, const B8G8R8X8 *src1, const B8G8R8X8 *src2); +}; + +struct A1R5G5B5 +{ + uint16_t ARGB; + + static void readColor(gl::ColorF *dst, const A1R5G5B5 *src); + static void writeColor(A1R5G5B5 *dst, const gl::ColorF *src); + static void average(A1R5G5B5 *dst, const A1R5G5B5 *src1, const A1R5G5B5 *src2); +}; + +struct R5G5B5A1 +{ + // OpenGL ES 2.0.25 spec Section 3.6.2: "Components are packed with the first component in the + // most significant + // bits of the bitfield, and successive component occupying progressively less significant + // locations" + uint16_t RGBA; + + static void readColor(gl::ColorF *dst, const R5G5B5A1 *src); + static void writeColor(R5G5B5A1 *dst, const gl::ColorF *src); + static void average(R5G5B5A1 *dst, const R5G5B5A1 *src1, const R5G5B5A1 *src2); +}; + +struct R4G4B4A4 +{ + // OpenGL ES 2.0.25 spec Section 3.6.2: "Components are packed with the first component in the + // most significant + // bits of the bitfield, and successive component occupying progressively less significant + // locations" + uint16_t RGBA; + + static void readColor(gl::ColorF *dst, const R4G4B4A4 *src); + static void writeColor(R4G4B4A4 *dst, const gl::ColorF *src); + static void average(R4G4B4A4 *dst, const R4G4B4A4 *src1, const R4G4B4A4 *src2); +}; + +struct A4R4G4B4 +{ + uint16_t ARGB; + + static void readColor(gl::ColorF *dst, const A4R4G4B4 *src); + static void writeColor(A4R4G4B4 *dst, const gl::ColorF *src); + static void average(A4R4G4B4 *dst, const A4R4G4B4 *src1, const A4R4G4B4 *src2); +}; + +struct R16 +{ + uint16_t R; + + static void readColor(gl::ColorF *dst, const R16 *src); + static void readColor(gl::ColorUI *dst, const R16 *src); + static void writeColor(R16 *dst, const gl::ColorF *src); + static void writeColor(R16 *dst, const gl::ColorUI *src); + static void average(R16 *dst, const R16 *src1, const R16 *src2); +}; + +struct R16G16 +{ + uint16_t R; + uint16_t G; + + static void readColor(gl::ColorF *dst, const R16G16 *src); + static void readColor(gl::ColorUI *dst, const R16G16 *src); + static void writeColor(R16G16 *dst, const gl::ColorF *src); + static void writeColor(R16G16 *dst, const gl::ColorUI *src); + static void average(R16G16 *dst, const R16G16 *src1, const R16G16 *src2); +}; + +struct R16G16B16 +{ + uint16_t R; + uint16_t G; + uint16_t B; + + static void readColor(gl::ColorF *dst, const R16G16B16 *src); + static void readColor(gl::ColorUI *dst, const R16G16B16 *src); + static void writeColor(R16G16B16 *dst, const gl::ColorF *src); + static void writeColor(R16G16B16 *dst, const gl::ColorUI *src); + static void average(R16G16B16 *dst, const R16G16B16 *src1, const R16G16B16 *src2); +}; + +struct R16G16B16A16 +{ + uint16_t R; + uint16_t G; + uint16_t B; + uint16_t A; + + static void readColor(gl::ColorF *dst, const R16G16B16A16 *src); + static void readColor(gl::ColorUI *dst, const R16G16B16A16 *src); + static void writeColor(R16G16B16A16 *dst, const gl::ColorF *src); + static void writeColor(R16G16B16A16 *dst, const gl::ColorUI *src); + static void average(R16G16B16A16 *dst, const R16G16B16A16 *src1, const R16G16B16A16 *src2); +}; + +struct R32 +{ + uint32_t R; + + static void readColor(gl::ColorF *dst, const R32 *src); + static void readColor(gl::ColorUI *dst, const R32 *src); + static void writeColor(R32 *dst, const gl::ColorF *src); + static void writeColor(R32 *dst, const gl::ColorUI *src); + static void average(R32 *dst, const R32 *src1, const R32 *src2); +}; + +struct R32G32 +{ + uint32_t R; + uint32_t G; + + static void readColor(gl::ColorF *dst, const R32G32 *src); + static void readColor(gl::ColorUI *dst, const R32G32 *src); + static void writeColor(R32G32 *dst, const gl::ColorF *src); + static void writeColor(R32G32 *dst, const gl::ColorUI *src); + static void average(R32G32 *dst, const R32G32 *src1, const R32G32 *src2); +}; + +struct R32G32B32 +{ + uint32_t R; + uint32_t G; + uint32_t B; + + static void readColor(gl::ColorF *dst, const R32G32B32 *src); + static void readColor(gl::ColorUI *dst, const R32G32B32 *src); + static void writeColor(R32G32B32 *dst, const gl::ColorF *src); + static void writeColor(R32G32B32 *dst, const gl::ColorUI *src); + static void average(R32G32B32 *dst, const R32G32B32 *src1, const R32G32B32 *src2); +}; + +struct R32G32B32A32 +{ + uint32_t R; + uint32_t G; + uint32_t B; + uint32_t A; + + static void readColor(gl::ColorF *dst, const R32G32B32A32 *src); + static void readColor(gl::ColorUI *dst, const R32G32B32A32 *src); + static void writeColor(R32G32B32A32 *dst, const gl::ColorF *src); + static void writeColor(R32G32B32A32 *dst, const gl::ColorUI *src); + static void average(R32G32B32A32 *dst, const R32G32B32A32 *src1, const R32G32B32A32 *src2); +}; + +struct R8S +{ + int8_t R; + + static void readColor(gl::ColorF *dst, const R8S *src); + static void readColor(gl::ColorI *dst, const R8S *src); + static void writeColor(R8S *dst, const gl::ColorF *src); + static void writeColor(R8S *dst, const gl::ColorI *src); + static void average(R8S *dst, const R8S *src1, const R8S *src2); +}; + +struct R8G8S +{ + int8_t R; + int8_t G; + + static void readColor(gl::ColorF *dst, const R8G8S *src); + static void readColor(gl::ColorI *dst, const R8G8S *src); + static void writeColor(R8G8S *dst, const gl::ColorF *src); + static void writeColor(R8G8S *dst, const gl::ColorI *src); + static void average(R8G8S *dst, const R8G8S *src1, const R8G8S *src2); +}; + +struct R8G8B8S +{ + int8_t R; + int8_t G; + int8_t B; + + static void readColor(gl::ColorF *dst, const R8G8B8S *src); + static void readColor(gl::ColorI *dst, const R8G8B8S *src); + static void writeColor(R8G8B8S *dst, const gl::ColorF *src); + static void writeColor(R8G8B8S *dst, const gl::ColorI *src); + static void average(R8G8B8S *dst, const R8G8B8S *src1, const R8G8B8S *src2); +}; + +struct R8G8B8A8S +{ + int8_t R; + int8_t G; + int8_t B; + int8_t A; + + static void readColor(gl::ColorF *dst, const R8G8B8A8S *src); + static void readColor(gl::ColorI *dst, const R8G8B8A8S *src); + static void writeColor(R8G8B8A8S *dst, const gl::ColorF *src); + static void writeColor(R8G8B8A8S *dst, const gl::ColorI *src); + static void average(R8G8B8A8S *dst, const R8G8B8A8S *src1, const R8G8B8A8S *src2); +}; + +struct R16S +{ + int16_t R; + + static void readColor(gl::ColorF *dst, const R16S *src); + static void readColor(gl::ColorI *dst, const R16S *src); + static void writeColor(R16S *dst, const gl::ColorF *src); + static void writeColor(R16S *dst, const gl::ColorI *src); + static void average(R16S *dst, const R16S *src1, const R16S *src2); +}; + +struct R16G16S +{ + int16_t R; + int16_t G; + + static void readColor(gl::ColorF *dst, const R16G16S *src); + static void readColor(gl::ColorI *dst, const R16G16S *src); + static void writeColor(R16G16S *dst, const gl::ColorF *src); + static void writeColor(R16G16S *dst, const gl::ColorI *src); + static void average(R16G16S *dst, const R16G16S *src1, const R16G16S *src2); +}; + +struct R16G16B16S +{ + int16_t R; + int16_t G; + int16_t B; + + static void readColor(gl::ColorF *dst, const R16G16B16S *src); + static void readColor(gl::ColorI *dst, const R16G16B16S *src); + static void writeColor(R16G16B16S *dst, const gl::ColorF *src); + static void writeColor(R16G16B16S *dst, const gl::ColorI *src); + static void average(R16G16B16S *dst, const R16G16B16S *src1, const R16G16B16S *src2); +}; + +struct R16G16B16A16S +{ + int16_t R; + int16_t G; + int16_t B; + int16_t A; + + static void readColor(gl::ColorF *dst, const R16G16B16A16S *src); + static void readColor(gl::ColorI *dst, const R16G16B16A16S *src); + static void writeColor(R16G16B16A16S *dst, const gl::ColorF *src); + static void writeColor(R16G16B16A16S *dst, const gl::ColorI *src); + static void average(R16G16B16A16S *dst, const R16G16B16A16S *src1, const R16G16B16A16S *src2); +}; + +struct R32S +{ + int32_t R; + + static void readColor(gl::ColorF *dst, const R32S *src); + static void readColor(gl::ColorI *dst, const R32S *src); + static void writeColor(R32S *dst, const gl::ColorF *src); + static void writeColor(R32S *dst, const gl::ColorI *src); + static void average(R32S *dst, const R32S *src1, const R32S *src2); +}; + +struct R32G32S +{ + int32_t R; + int32_t G; + + static void readColor(gl::ColorF *dst, const R32G32S *src); + static void readColor(gl::ColorI *dst, const R32G32S *src); + static void writeColor(R32G32S *dst, const gl::ColorF *src); + static void writeColor(R32G32S *dst, const gl::ColorI *src); + static void average(R32G32S *dst, const R32G32S *src1, const R32G32S *src2); +}; + +struct R32G32B32S +{ + int32_t R; + int32_t G; + int32_t B; + + static void readColor(gl::ColorF *dst, const R32G32B32S *src); + static void readColor(gl::ColorI *dst, const R32G32B32S *src); + static void writeColor(R32G32B32S *dst, const gl::ColorF *src); + static void writeColor(R32G32B32S *dst, const gl::ColorI *src); + static void average(R32G32B32S *dst, const R32G32B32S *src1, const R32G32B32S *src2); +}; + +struct R32G32B32A32S +{ + int32_t R; + int32_t G; + int32_t B; + int32_t A; + + static void readColor(gl::ColorF *dst, const R32G32B32A32S *src); + static void readColor(gl::ColorI *dst, const R32G32B32A32S *src); + static void writeColor(R32G32B32A32S *dst, const gl::ColorF *src); + static void writeColor(R32G32B32A32S *dst, const gl::ColorI *src); + static void average(R32G32B32A32S *dst, const R32G32B32A32S *src1, const R32G32B32A32S *src2); +}; + +struct A16B16G16R16F +{ + uint16_t A; + uint16_t R; + uint16_t G; + uint16_t B; + + static void readColor(gl::ColorF *dst, const A16B16G16R16F *src); + static void writeColor(A16B16G16R16F *dst, const gl::ColorF *src); + static void average(A16B16G16R16F *dst, const A16B16G16R16F *src1, const A16B16G16R16F *src2); +}; + +struct R16G16B16A16F +{ + uint16_t R; + uint16_t G; + uint16_t B; + uint16_t A; + + static void readColor(gl::ColorF *dst, const R16G16B16A16F *src); + static void writeColor(R16G16B16A16F *dst, const gl::ColorF *src); + static void average(R16G16B16A16F *dst, const R16G16B16A16F *src1, const R16G16B16A16F *src2); +}; + +struct R16F +{ + uint16_t R; + + static void readColor(gl::ColorF *dst, const R16F *src); + static void writeColor(R16F *dst, const gl::ColorF *src); + static void average(R16F *dst, const R16F *src1, const R16F *src2); +}; + +struct A16F +{ + uint16_t A; + + static void readColor(gl::ColorF *dst, const A16F *src); + static void writeColor(A16F *dst, const gl::ColorF *src); + static void average(A16F *dst, const A16F *src1, const A16F *src2); +}; + +struct L16F +{ + uint16_t L; + + static void readColor(gl::ColorF *dst, const L16F *src); + static void writeColor(L16F *dst, const gl::ColorF *src); + static void average(L16F *dst, const L16F *src1, const L16F *src2); +}; + +struct L16A16F +{ + uint16_t L; + uint16_t A; + + static void readColor(gl::ColorF *dst, const L16A16F *src); + static void writeColor(L16A16F *dst, const gl::ColorF *src); + static void average(L16A16F *dst, const L16A16F *src1, const L16A16F *src2); +}; + +struct R16G16F +{ + uint16_t R; + uint16_t G; + + static void readColor(gl::ColorF *dst, const R16G16F *src); + static void writeColor(R16G16F *dst, const gl::ColorF *src); + static void average(R16G16F *dst, const R16G16F *src1, const R16G16F *src2); +}; + +struct R16G16B16F +{ + uint16_t R; + uint16_t G; + uint16_t B; + + static void readColor(gl::ColorF *dst, const R16G16B16F *src); + static void writeColor(R16G16B16F *dst, const gl::ColorF *src); + static void average(R16G16B16F *dst, const R16G16B16F *src1, const R16G16B16F *src2); +}; + +struct A32B32G32R32F +{ + float A; + float R; + float G; + float B; + + static void readColor(gl::ColorF *dst, const A32B32G32R32F *src); + static void writeColor(A32B32G32R32F *dst, const gl::ColorF *src); + static void average(A32B32G32R32F *dst, const A32B32G32R32F *src1, const A32B32G32R32F *src2); +}; + +struct R32G32B32A32F +{ + float R; + float G; + float B; + float A; + + static void readColor(gl::ColorF *dst, const R32G32B32A32F *src); + static void writeColor(R32G32B32A32F *dst, const gl::ColorF *src); + static void average(R32G32B32A32F *dst, const R32G32B32A32F *src1, const R32G32B32A32F *src2); +}; + +struct R32F +{ + float R; + + static void readColor(gl::ColorF *dst, const R32F *src); + static void writeColor(R32F *dst, const gl::ColorF *src); + static void average(R32F *dst, const R32F *src1, const R32F *src2); +}; + +struct A32F +{ + float A; + + static void readColor(gl::ColorF *dst, const A32F *src); + static void writeColor(A32F *dst, const gl::ColorF *src); + static void average(A32F *dst, const A32F *src1, const A32F *src2); +}; + +struct L32F +{ + float L; + + static void readColor(gl::ColorF *dst, const L32F *src); + static void writeColor(L32F *dst, const gl::ColorF *src); + static void average(L32F *dst, const L32F *src1, const L32F *src2); +}; + +struct L32A32F +{ + float L; + float A; + + static void readColor(gl::ColorF *dst, const L32A32F *src); + static void writeColor(L32A32F *dst, const gl::ColorF *src); + static void average(L32A32F *dst, const L32A32F *src1, const L32A32F *src2); +}; + +struct R32G32F +{ + float R; + float G; + + static void readColor(gl::ColorF *dst, const R32G32F *src); + static void writeColor(R32G32F *dst, const gl::ColorF *src); + static void average(R32G32F *dst, const R32G32F *src1, const R32G32F *src2); +}; + +struct R32G32B32F +{ + float R; + float G; + float B; + + static void readColor(gl::ColorF *dst, const R32G32B32F *src); + static void writeColor(R32G32B32F *dst, const gl::ColorF *src); + static void average(R32G32B32F *dst, const R32G32B32F *src1, const R32G32B32F *src2); +}; + +struct R10G10B10A2 +{ + uint32_t R : 10; + uint32_t G : 10; + uint32_t B : 10; + uint32_t A : 2; + + static void readColor(gl::ColorF *dst, const R10G10B10A2 *src); + static void readColor(gl::ColorUI *dst, const R10G10B10A2 *src); + static void writeColor(R10G10B10A2 *dst, const gl::ColorF *src); + static void writeColor(R10G10B10A2 *dst, const gl::ColorUI *src); + static void average(R10G10B10A2 *dst, const R10G10B10A2 *src1, const R10G10B10A2 *src2); +}; +static_assert(sizeof(R10G10B10A2) == 4, "R10G10B10A2 struct not 32-bits."); + +struct R9G9B9E5 +{ + uint32_t R : 9; + uint32_t G : 9; + uint32_t B : 9; + uint32_t E : 5; + + static void readColor(gl::ColorF *dst, const R9G9B9E5 *src); + static void writeColor(R9G9B9E5 *dst, const gl::ColorF *src); + static void average(R9G9B9E5 *dst, const R9G9B9E5 *src1, const R9G9B9E5 *src2); +}; +static_assert(sizeof(R9G9B9E5) == 4, "R9G9B9E5 struct not 32-bits."); + +struct R11G11B10F +{ + uint32_t R : 11; + uint32_t G : 11; + uint32_t B : 10; + + static void readColor(gl::ColorF *dst, const R11G11B10F *src); + static void writeColor(R11G11B10F *dst, const gl::ColorF *src); + static void average(R11G11B10F *dst, const R11G11B10F *src1, const R11G11B10F *src2); +}; +static_assert(sizeof(R11G11B10F) == 4, "R11G11B10F struct not 32-bits."); + +} // namespace angle + +#endif // IMAGEUTIL_IMAGEFORMATS_H_ diff --git a/src/3rdparty/angle/src/image_util/loadimage.cpp b/src/3rdparty/angle/src/image_util/loadimage.cpp new file mode 100644 index 0000000000..56ad3b32e3 --- /dev/null +++ b/src/3rdparty/angle/src/image_util/loadimage.cpp @@ -0,0 +1,1323 @@ +// +// Copyright (c) 2013-2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// angle_loadimage.cpp: Defines image loading functions. + +#include "image_util/loadimage.h" + +#include "common/mathutil.h" +#include "common/platform.h" +#include "image_util/imageformats.h" + +namespace angle +{ + +void LoadA8ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ +#if defined(ANGLE_USE_SSE) + if (gl::supportsSSE2()) + { + __m128i zeroWide = _mm_setzero_si128(); + + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint8_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint32_t *dest = priv::OffsetDataPointer(output, y, z, outputRowPitch, + outputDepthPitch); + + size_t x = 0; + + // Make output writes aligned + for (; ((reinterpret_cast(&dest[x]) & 0xF) != 0 && x < width); x++) + { + dest[x] = static_cast(source[x]) << 24; + } + + for (; x + 7 < width; x += 8) + { + __m128i sourceData = + _mm_loadl_epi64(reinterpret_cast(&source[x])); + // Interleave each byte to 16bit, make the lower byte to zero + sourceData = _mm_unpacklo_epi8(zeroWide, sourceData); + // Interleave each 16bit to 32bit, make the lower 16bit to zero + __m128i lo = _mm_unpacklo_epi16(zeroWide, sourceData); + __m128i hi = _mm_unpackhi_epi16(zeroWide, sourceData); + + _mm_store_si128(reinterpret_cast<__m128i *>(&dest[x]), lo); + _mm_store_si128(reinterpret_cast<__m128i *>(&dest[x + 4]), hi); + } + + // Handle the remainder + for (; x < width; x++) + { + dest[x] = static_cast(source[x]) << 24; + } + } + } + + return; + } +#endif + + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint8_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint32_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[x] = static_cast(source[x]) << 24; + } + } + } +} + +void LoadA8ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + // Same as loading to RGBA + LoadA8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, + outputRowPitch, outputDepthPitch); +} + +void LoadA32FToRGBA32F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const float *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + float *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[4 * x + 0] = 0.0f; + dest[4 * x + 1] = 0.0f; + dest[4 * x + 2] = 0.0f; + dest[4 * x + 3] = source[x]; + } + } + } +} + +void LoadA16FToRGBA16F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[4 * x + 0] = 0; + dest[4 * x + 1] = 0; + dest[4 * x + 2] = 0; + dest[4 * x + 3] = source[x]; + } + } + } +} + +void LoadL8ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint8_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint8_t sourceVal = source[x]; + dest[4 * x + 0] = sourceVal; + dest[4 * x + 1] = sourceVal; + dest[4 * x + 2] = sourceVal; + dest[4 * x + 3] = 0xFF; + } + } + } +} + +void LoadL8ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + // Same as loading to RGBA + LoadL8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, + outputRowPitch, outputDepthPitch); +} + +void LoadL32FToRGBA32F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const float *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + float *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[4 * x + 0] = source[x]; + dest[4 * x + 1] = source[x]; + dest[4 * x + 2] = source[x]; + dest[4 * x + 3] = 1.0f; + } + } + } +} + +void LoadL16FToRGBA16F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[4 * x + 0] = source[x]; + dest[4 * x + 1] = source[x]; + dest[4 * x + 2] = source[x]; + dest[4 * x + 3] = gl::Float16One; + } + } + } +} + +void LoadLA8ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint8_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[4 * x + 0] = source[2 * x + 0]; + dest[4 * x + 1] = source[2 * x + 0]; + dest[4 * x + 2] = source[2 * x + 0]; + dest[4 * x + 3] = source[2 * x + 1]; + } + } + } +} + +void LoadLA8ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + // Same as loading to RGBA + LoadLA8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, + outputRowPitch, outputDepthPitch); +} + +void LoadLA32FToRGBA32F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const float *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + float *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[4 * x + 0] = source[2 * x + 0]; + dest[4 * x + 1] = source[2 * x + 0]; + dest[4 * x + 2] = source[2 * x + 0]; + dest[4 * x + 3] = source[2 * x + 1]; + } + } + } +} + +void LoadLA16FToRGBA16F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[4 * x + 0] = source[2 * x + 0]; + dest[4 * x + 1] = source[2 * x + 0]; + dest[4 * x + 2] = source[2 * x + 0]; + dest[4 * x + 3] = source[2 * x + 1]; + } + } + } +} + +void LoadRGB8ToBGR565(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint8_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint8_t r8 = source[x * 3 + 0]; + uint8_t g8 = source[x * 3 + 1]; + uint8_t b8 = source[x * 3 + 2]; + auto r5 = static_cast(r8 >> 3); + auto g6 = static_cast(g8 >> 2); + auto b5 = static_cast(b8 >> 3); + dest[x] = (r5 << 11) | (g6 << 5) | b5; + } + } + } +} + +void LoadRGB565ToBGR565(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + // The GL type RGB is packed with with red in the MSB, while the D3D11 type BGR + // is packed with red in the LSB + auto rgb = source[x]; + uint16_t r5 = gl::getShiftedData<5, 11>(rgb); + uint16_t g6 = gl::getShiftedData<6, 5>(rgb); + uint16_t b5 = gl::getShiftedData<5, 0>(rgb); + dest[x] = (r5 << 11) | (g6 << 5) | b5; + } + } + } +} + +void LoadRGB8ToBGRX8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint8_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[4 * x + 0] = source[x * 3 + 2]; + dest[4 * x + 1] = source[x * 3 + 1]; + dest[4 * x + 2] = source[x * 3 + 0]; + dest[4 * x + 3] = 0xFF; + } + } + } +} + +void LoadRG8ToBGRX8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint8_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[4 * x + 0] = 0x00; + dest[4 * x + 1] = source[x * 2 + 1]; + dest[4 * x + 2] = source[x * 2 + 0]; + dest[4 * x + 3] = 0xFF; + } + } + } +} + +void LoadR8ToBGRX8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint8_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[4 * x + 0] = 0x00; + dest[4 * x + 1] = 0x00; + dest[4 * x + 2] = source[x]; + dest[4 * x + 3] = 0xFF; + } + } + } +} + +void LoadR5G6B5ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint16_t rgb = source[x]; + dest[4 * x + 0] = + static_cast(((rgb & 0x001F) << 3) | ((rgb & 0x001F) >> 2)); + dest[4 * x + 1] = + static_cast(((rgb & 0x07E0) >> 3) | ((rgb & 0x07E0) >> 9)); + dest[4 * x + 2] = + static_cast(((rgb & 0xF800) >> 8) | ((rgb & 0xF800) >> 13)); + dest[4 * x + 3] = 0xFF; + } + } + } +} + +void LoadR5G6B5ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint16_t rgb = source[x]; + dest[4 * x + 0] = + static_cast(((rgb & 0xF800) >> 8) | ((rgb & 0xF800) >> 13)); + dest[4 * x + 1] = + static_cast(((rgb & 0x07E0) >> 3) | ((rgb & 0x07E0) >> 9)); + dest[4 * x + 2] = + static_cast(((rgb & 0x001F) << 3) | ((rgb & 0x001F) >> 2)); + dest[4 * x + 3] = 0xFF; + } + } + } +} + +void LoadRGBA8ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ +#if defined(ANGLE_USE_SSE) + if (gl::supportsSSE2()) + { + __m128i brMask = _mm_set1_epi32(0x00ff00ff); + + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint32_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint32_t *dest = priv::OffsetDataPointer(output, y, z, outputRowPitch, + outputDepthPitch); + + size_t x = 0; + + // Make output writes aligned + for (; ((reinterpret_cast(&dest[x]) & 15) != 0) && x < width; x++) + { + uint32_t rgba = source[x]; + dest[x] = (ANGLE_ROTL(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00); + } + + for (; x + 3 < width; x += 4) + { + __m128i sourceData = + _mm_loadu_si128(reinterpret_cast(&source[x])); + // Mask out g and a, which don't change + __m128i gaComponents = _mm_andnot_si128(brMask, sourceData); + // Mask out b and r + __m128i brComponents = _mm_and_si128(sourceData, brMask); + // Swap b and r + __m128i brSwapped = _mm_shufflehi_epi16( + _mm_shufflelo_epi16(brComponents, _MM_SHUFFLE(2, 3, 0, 1)), + _MM_SHUFFLE(2, 3, 0, 1)); + __m128i result = _mm_or_si128(gaComponents, brSwapped); + _mm_store_si128(reinterpret_cast<__m128i *>(&dest[x]), result); + } + + // Perform leftover writes + for (; x < width; x++) + { + uint32_t rgba = source[x]; + dest[x] = (ANGLE_ROTL(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00); + } + } + } + + return; + } +#endif + + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint32_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint32_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint32_t rgba = source[x]; + dest[x] = (ANGLE_ROTL(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00); + } + } + } +} + +void LoadRGBA8ToBGRA4(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint32_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint32_t rgba8 = source[x]; + auto r4 = static_cast((rgba8 & 0x000000FF) >> 4); + auto g4 = static_cast((rgba8 & 0x0000FF00) >> 12); + auto b4 = static_cast((rgba8 & 0x00FF0000) >> 20); + auto a4 = static_cast((rgba8 & 0xFF000000) >> 28); + dest[x] = (a4 << 12) | (r4 << 8) | (g4 << 4) | b4; + } + } + } +} + +void LoadRGBA4ToARGB4(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[x] = ANGLE_ROTR16(source[x], 4); + } + } + } +} + +void LoadRGBA4ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint16_t rgba = source[x]; + dest[4 * x + 0] = + static_cast(((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4)); + dest[4 * x + 1] = + static_cast(((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8)); + dest[4 * x + 2] = + static_cast(((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12)); + dest[4 * x + 3] = + static_cast(((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0)); + } + } + } +} + +void LoadRGBA4ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint16_t rgba = source[x]; + dest[4 * x + 0] = + static_cast(((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12)); + dest[4 * x + 1] = + static_cast(((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8)); + dest[4 * x + 2] = + static_cast(((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4)); + dest[4 * x + 3] = + static_cast(((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0)); + } + } + } +} + +void LoadBGRA4ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint16_t bgra = source[x]; + dest[4 * x + 0] = + static_cast(((bgra & 0xF000) >> 8) | ((bgra & 0xF000) >> 12)); + dest[4 * x + 1] = + static_cast(((bgra & 0x0F00) >> 4) | ((bgra & 0x0F00) >> 8)); + dest[4 * x + 2] = + static_cast(((bgra & 0x00F0) << 0) | ((bgra & 0x00F0) >> 4)); + dest[4 * x + 3] = + static_cast(((bgra & 0x000F) << 4) | ((bgra & 0x000F) >> 0)); + } + } + } +} + +void LoadRGBA8ToBGR5A1(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint32_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint32_t rgba8 = source[x]; + auto r5 = static_cast((rgba8 & 0x000000FF) >> 3); + auto g5 = static_cast((rgba8 & 0x0000FF00) >> 11); + auto b5 = static_cast((rgba8 & 0x00FF0000) >> 19); + auto a1 = static_cast((rgba8 & 0xFF000000) >> 31); + dest[x] = (a1 << 15) | (r5 << 10) | (g5 << 5) | b5; + } + } + } +} + +void LoadRGB10A2ToBGR5A1(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const R10G10B10A2 *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + R10G10B10A2 rgb10a2 = source[x]; + + uint16_t r5 = static_cast(rgb10a2.R >> 5u); + uint16_t g5 = static_cast(rgb10a2.G >> 5u); + uint16_t b5 = static_cast(rgb10a2.B >> 5u); + uint16_t a1 = static_cast(rgb10a2.A >> 1u); + + dest[x] = (a1 << 15) | (r5 << 10) | (g5 << 5) | b5; + } + } + } +} + +void LoadRGB5A1ToA1RGB5(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[x] = ANGLE_ROTR16(source[x], 1); + } + } + } +} + +void LoadRGB5A1ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint16_t rgba = source[x]; + dest[4 * x + 0] = + static_cast(((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3)); + dest[4 * x + 1] = + static_cast(((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8)); + dest[4 * x + 2] = + static_cast(((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13)); + dest[4 * x + 3] = static_cast((rgba & 0x0001) ? 0xFF : 0); + } + } + } +} + +void LoadRGB5A1ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint16_t rgba = source[x]; + dest[4 * x + 0] = + static_cast(((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13)); + dest[4 * x + 1] = + static_cast(((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8)); + dest[4 * x + 2] = + static_cast(((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3)); + dest[4 * x + 3] = static_cast((rgba & 0x0001) ? 0xFF : 0); + } + } + } +} + +void LoadBGR5A1ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint16_t bgra = source[x]; + dest[4 * x + 0] = + static_cast(((bgra & 0xF800) >> 8) | ((bgra & 0xF800) >> 13)); + dest[4 * x + 1] = + static_cast(((bgra & 0x07C0) >> 3) | ((bgra & 0x07C0) >> 8)); + dest[4 * x + 2] = + static_cast(((bgra & 0x003E) << 2) | ((bgra & 0x003E) >> 3)); + dest[4 * x + 3] = static_cast((bgra & 0x0001) ? 0xFF : 0); + } + } + } +} + +void LoadRGB10A2ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint32_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint32_t rgba = source[x]; + dest[4 * x + 0] = static_cast((rgba & 0x000003FF) >> 2); + dest[4 * x + 1] = static_cast((rgba & 0x000FFC00) >> 12); + dest[4 * x + 2] = static_cast((rgba & 0x3FF00000) >> 22); + dest[4 * x + 3] = static_cast(((rgba & 0xC0000000) >> 30) * 0x55); + } + } + } +} + +void LoadRGB16FToRGB9E5(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint32_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[x] = gl::convertRGBFloatsTo999E5(gl::float16ToFloat32(source[x * 3 + 0]), + gl::float16ToFloat32(source[x * 3 + 1]), + gl::float16ToFloat32(source[x * 3 + 2])); + } + } + } +} + +void LoadRGB32FToRGB9E5(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const float *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint32_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[x] = gl::convertRGBFloatsTo999E5(source[x * 3 + 0], source[x * 3 + 1], + source[x * 3 + 2]); + } + } + } +} + +void LoadRGB16FToRG11B10F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint16_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint32_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[x] = (gl::float32ToFloat11(gl::float16ToFloat32(source[x * 3 + 0])) << 0) | + (gl::float32ToFloat11(gl::float16ToFloat32(source[x * 3 + 1])) << 11) | + (gl::float32ToFloat10(gl::float16ToFloat32(source[x * 3 + 2])) << 22); + } + } + } +} + +void LoadRGB32FToRG11B10F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const float *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint32_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[x] = (gl::float32ToFloat11(source[x * 3 + 0]) << 0) | + (gl::float32ToFloat11(source[x * 3 + 1]) << 11) | + (gl::float32ToFloat10(source[x * 3 + 2]) << 22); + } + } + } +} + +void LoadG8R24ToR24G8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint32_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint32_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + uint32_t d = source[x] >> 8; + uint8_t s = source[x] & 0xFF; + dest[x] = d | (s << 24); + } + } + } +} + +void LoadD32FToD32F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const float *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + float *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[x] = gl::clamp01(source[x]); + } + } + } +} + +void LoadD32FS8X24ToD32FS8X24(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const float *sourceDepth = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + const uint32_t *sourceStencil = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch) + 1; + float *destDepth = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + uint32_t *destStencil = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch) + + 1; + for (size_t x = 0; x < width; x++) + { + destDepth[x * 2] = gl::clamp01(sourceDepth[x * 2]); + destStencil[x * 2] = sourceStencil[x * 2] & 0xFF000000; + } + } + } +} + +void LoadRGB32FToRGBA16F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const float *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[x * 4 + 0] = gl::float32ToFloat16(source[x * 3 + 0]); + dest[x * 4 + 1] = gl::float32ToFloat16(source[x * 3 + 1]); + dest[x * 4 + 2] = gl::float32ToFloat16(source[x * 3 + 2]); + dest[x * 4 + 3] = gl::Float16One; + } + } + } +} + +void LoadR32ToR16(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint32_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + for (size_t x = 0; x < width; x++) + { + dest[x] = source[x] >> 16; + } + } + } +} + +void LoadR32ToR24G8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + for (size_t z = 0; z < depth; z++) + { + for (size_t y = 0; y < height; y++) + { + const uint32_t *source = + priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint32_t *dest = + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + + for (size_t x = 0; x < width; x++) + { + dest[x] = source[x] >> 8; + } + } + } +} + +} // namespace angle diff --git a/src/3rdparty/angle/src/image_util/loadimage.h b/src/3rdparty/angle/src/image_util/loadimage.h new file mode 100644 index 0000000000..3e8aac79c2 --- /dev/null +++ b/src/3rdparty/angle/src/image_util/loadimage.h @@ -0,0 +1,658 @@ +// +// Copyright (c) 2013-2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// loadimage.h: Defines image loading functions + +#ifndef IMAGEUTIL_LOADIMAGE_H_ +#define IMAGEUTIL_LOADIMAGE_H_ + +#include +#include + +namespace angle +{ + +void LoadA8ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadA8ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadA32FToRGBA32F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadA16FToRGBA16F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadL8ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadL8ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadL32FToRGBA32F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadL16FToRGBA16F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadLA8ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadLA8ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadLA32FToRGBA32F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadLA16FToRGBA16F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGB8ToBGR565(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGB565ToBGR565(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGB8ToBGRX8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRG8ToBGRX8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadR8ToBGRX8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadR5G6B5ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadR5G6B5ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGBA8ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGBA8ToBGRA4(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGBA4ToARGB4(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGBA4ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGBA4ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadBGRA4ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGBA8ToBGR5A1(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGB10A2ToBGR5A1(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGB5A1ToA1RGB5(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGB5A1ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGB5A1ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadBGR5A1ToBGRA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGB10A2ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGB16FToRGB9E5(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGB32FToRGB9E5(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGB16FToRG11B10F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGB32FToRG11B10F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadG8R24ToR24G8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadD32FToD32F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadD32FS8X24ToD32FS8X24(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +template +inline void LoadToNative(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +template +inline void LoadToNative3To4(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +template +inline void Load32FTo16F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadRGB32FToRGBA16F(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +template +inline void LoadCompressedToNative(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadR32ToR16(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +template +inline void Initialize4ComponentData(size_t width, + size_t height, + size_t depth, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadR32ToR24G8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadETC1RGB8ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadETC1RGB8ToBC1(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadEACR11ToR8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadEACR11SToR8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadEACRG11ToRG8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadEACRG11SToRG8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadETC2RGB8ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadETC2RGB8ToBC1(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadETC2SRGB8ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadETC2SRGB8ToBC1(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadETC2RGB8A1ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadETC2RGB8A1ToBC1(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadETC2SRGB8A1ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadETC2SRGB8A1ToBC1(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadETC2RGBA8ToRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +void LoadETC2SRGBA8ToSRGBA8(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +} // namespace angle + +#include "loadimage.inl" + +#endif // IMAGEUTIL_LOADIMAGE_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage.inl b/src/3rdparty/angle/src/image_util/loadimage.inl similarity index 79% rename from src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage.inl rename to src/3rdparty/angle/src/image_util/loadimage.inl index 920e667db1..b8d590ca1b 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage.inl +++ b/src/3rdparty/angle/src/image_util/loadimage.inl @@ -6,7 +6,12 @@ #include "common/mathutil.h" -namespace rx +#include + +namespace angle +{ + +namespace priv { template @@ -21,6 +26,8 @@ inline const T *OffsetDataPointer(const uint8_t *data, size_t y, size_t z, size_ return reinterpret_cast(data + (y * rowPitch) + (z * depthPitch)); } +} // namespace priv + template inline void LoadToNative(size_t width, size_t height, size_t depth, const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, @@ -39,8 +46,8 @@ inline void LoadToNative(size_t width, size_t height, size_t depth, { for (size_t z = 0; z < depth; z++) { - const type *source = OffsetDataPointer(input, 0, z, inputRowPitch, inputDepthPitch); - type *dest = OffsetDataPointer(output, 0, z, outputRowPitch, outputDepthPitch); + const type *source = priv::OffsetDataPointer(input, 0, z, inputRowPitch, inputDepthPitch); + type *dest = priv::OffsetDataPointer(output, 0, z, outputRowPitch, outputDepthPitch); memcpy(dest, source, layerSize); } @@ -51,8 +58,8 @@ inline void LoadToNative(size_t width, size_t height, size_t depth, { for (size_t y = 0; y < height; y++) { - const type *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - type *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + const type *source = priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + type *dest = priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); memcpy(dest, source, width * sizeof(type) * componentCount); } } @@ -70,8 +77,8 @@ inline void LoadToNative3To4(size_t width, size_t height, size_t depth, { for (size_t y = 0; y < height; y++) { - const type *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - type *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + const type *source = priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + type *dest = priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); for (size_t x = 0; x < width; x++) { dest[x * 4 + 0] = source[x * 3 + 0]; @@ -94,8 +101,8 @@ inline void Load32FTo16F(size_t width, size_t height, size_t depth, { for (size_t y = 0; y < height; y++) { - const float *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint16_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + const float *source = priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint16_t *dest = priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); for (size_t x = 0; x < elementWidth; x++) { @@ -117,8 +124,8 @@ inline void LoadCompressedToNative(size_t width, size_t height, size_t depth, { for (size_t y = 0; y < rows; ++y) { - const uint8_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + const uint8_t *source = priv::OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); + uint8_t *dest = priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); memcpy(dest, source, columns * blockSize); } } @@ -140,7 +147,7 @@ inline void Initialize4ComponentData(size_t width, size_t height, size_t depth, { for (size_t y = 0; y < height; y++) { - type *destRow = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + type *destRow = priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); for (size_t x = 0; x < width; x++) { type* destPixel = destRow + x * 4; @@ -153,4 +160,4 @@ inline void Initialize4ComponentData(size_t width, size_t height, size_t depth, } } -} +} // namespace angle diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage_etc.cpp b/src/3rdparty/angle/src/image_util/loadimage_etc.cpp similarity index 69% rename from src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage_etc.cpp rename to src/3rdparty/angle/src/image_util/loadimage_etc.cpp index 26a3b32ce0..67f73837c0 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage_etc.cpp +++ b/src/3rdparty/angle/src/image_util/loadimage_etc.cpp @@ -6,18 +6,22 @@ // loadimage_etc.cpp: Decodes ETC and EAC encoded textures. -#include "libANGLE/renderer/d3d/loadimage_etc.h" +#include "image_util/loadimage.h" -#include "libANGLE/renderer/d3d/loadimage.h" -#include "libANGLE/renderer/d3d/imageformats.h" +#include "common/mathutil.h" -namespace rx +#include "image_util/imageformats.h" + +namespace angle { namespace { + +using IntensityModifier = const int[4]; + // Table 3.17.2 sorted according to table 3.17.3 // clang-format off -static const int intensityModifierDefault[][4] = +static IntensityModifier intensityModifierDefault[] = { { 2, 8, -2, -8 }, { 5, 17, -5, -17 }, @@ -32,7 +36,7 @@ static const int intensityModifierDefault[][4] = // Table C.12, intensity modifier for non opaque punchthrough alpha // clang-format off -static const int intensityModifierNonOpaque[][4] = +static IntensityModifier intensityModifierNonOpaque[] = { { 0, 8, 0, -8 }, { 0, 17, 0, -17 }, @@ -45,13 +49,7 @@ static const int intensityModifierNonOpaque[][4] = }; // clang-format on -// Table C.7, mapping from pixel index values to modifier value orders -// clang-format off -static const int valueMappingTable[] = -{ - 2, 3, 1, 0 -}; -// clang-format on +static const int kNumPixelsInBlock = 16; struct ETC2Block { @@ -101,7 +99,7 @@ struct ETC2Block const auto &block = u.idht.mode.idm.colors.diff; int r = (block.R + block.dR); int g = (block.G + block.dG); - int b = (block.B + block.dB); + int b = (block.B + block.dB); if (r < 0 || r > 31) { decodeTBlock(dest, x, y, w, h, destRowPitch, alphaValues, @@ -146,7 +144,7 @@ struct ETC2Block const auto &block = u.idht.mode.idm.colors.diff; int r = (block.R + block.dR); int g = (block.G + block.dG); - int b = (block.B + block.dB); + int b = (block.B + block.dB); if (r < 0 || r > 31) { transcodeTBlockToBC1(dest, x, y, w, h, alphaValues, nonOpaquePunchThroughAlpha); @@ -173,18 +171,15 @@ struct ETC2Block } private: - union - { + union { // Individual, differential, H and T modes struct { - union - { + union { // Individual and differential modes struct { - union - { + union { struct // Individual colors { unsigned char R2 : 4; @@ -294,8 +289,7 @@ struct ETC2Block // Single channel block struct { - union - { + union { unsigned char us; signed char s; } base_codeword; @@ -369,7 +363,7 @@ struct ETC2Block int b1 = extend_4to8bits(block.B1); int r2 = extend_4to8bits(block.R2); int g2 = extend_4to8bits(block.G2); - int b2 = extend_4to8bits(block.B2); + int b2 = extend_4to8bits(block.B2); decodeIndividualOrDifferentialBlock(dest, x, y, w, h, destRowPitch, r1, g1, b1, r2, g2, b2, alphaValues, nonOpaquePunchThroughAlpha); } @@ -389,7 +383,7 @@ struct ETC2Block int r1 = extend_5to8bits(block.R); int r2 = extend_5to8bits(block.R + block.dR); int g2 = extend_5to8bits(block.G + block.dG); - int b2 = extend_5to8bits(block.B + block.dB); + int b2 = extend_5to8bits(block.B + block.dB); decodeIndividualOrDifferentialBlock(dest, x, y, w, h, destRowPitch, r1, g1, b1, r2, g2, b2, alphaValues, nonOpaquePunchThroughAlpha); } @@ -409,7 +403,7 @@ struct ETC2Block const uint8_t alphaValues[4][4], bool nonOpaquePunchThroughAlpha) const { - const auto intensityModifier = + const IntensityModifier *intensityModifier = nonOpaquePunchThroughAlpha ? intensityModifierNonOpaque : intensityModifierDefault; R8G8B8A8 subblockColors0[4]; @@ -537,8 +531,9 @@ struct ETC2Block int b2 = extend_4to8bits(block.HB2); static const int distance[8] = {3, 6, 11, 16, 23, 32, 41, 64}; - const int d = distance[(block.Hda << 2) | (block.Hdb << 1) | - ((r1 << 16 | g1 << 8 | b1) >= (r2 << 16 | g2 << 8 | b2) ? 1 : 0)]; + const int orderingTrickBit = + ((r1 << 16 | g1 << 8 | b1) >= (r2 << 16 | g2 << 8 | b2) ? 1 : 0); + const int d = distance[(block.Hda << 2) | (block.Hdb << 1) | orderingTrickBit]; const R8G8B8A8 paintColors[4] = { createRGBA(r1 + d, g1 + d, b1 + d), createRGBA(r1 - d, g1 - d, b1 - d), @@ -607,7 +602,7 @@ struct ETC2Block size_t bitIndex = x * 4 + y; size_t bitOffset = bitIndex & 7; size_t lsb = (u.idht.pixelIndexLSB[1 - (bitIndex >> 3)] >> bitOffset) & 1; - size_t msb = (u.idht.pixelIndexMSB[1 - (bitIndex >> 3)] >> bitOffset) & 1; + size_t msb = (u.idht.pixelIndexMSB[1 - (bitIndex >> 3)] >> bitOffset) & 1; return (msb << 1) | lsb; } @@ -640,10 +635,13 @@ struct ETC2Block (static_cast(rgba.B >> 3) << 0); } - uint32_t matchBC1Bits(const R8G8B8A8 *rgba, + uint32_t matchBC1Bits(const int *pixelIndices, + const int *pixelIndexCounts, + const R8G8B8A8 *subblockColors, + size_t numColors, const R8G8B8A8 &minColor, const R8G8B8A8 &maxColor, - bool opaque) const + bool nonOpaquePunchThroughAlpha) const { // Project each pixel on the (maxColor, minColor) line to decide which // BC1 code to assign to it. @@ -664,102 +662,127 @@ struct ETC2Block decodedColors[i][2] * direction[2]; } - uint32_t bits = 0; - if (opaque) - { - for (int i = 15; i >= 0; i--) - { - // In opaque mode, the code is from 0 to 3. + ASSERT(numColors <= kNumPixelsInBlock); - bits <<= 2; - const int dot = - rgba[i].R * direction[0] + rgba[i].G * direction[1] + rgba[i].B * direction[2]; - const int factor = gl::clamp( - static_cast( - (static_cast(dot - stops[1]) / (stops[0] - stops[1])) * 3 + 0.5f), - 0, 3); - switch (factor) + int encodedColors[kNumPixelsInBlock]; + if (nonOpaquePunchThroughAlpha) + { + for (size_t i = 0; i < numColors; i++) + { + const int count = pixelIndexCounts[i]; + if (count > 0) { - case 0: - bits |= 1; - break; - case 1: - bits |= 3; - break; - case 2: - bits |= 2; - break; - case 3: - default: - bits |= 0; - break; + // In non-opaque mode, 3 is for tranparent pixels. + + if (0 == subblockColors[i].A) + { + encodedColors[i] = 3; + } + else + { + const R8G8B8A8 &pixel = subblockColors[i]; + const int dot = pixel.R * direction[0] + pixel.G * direction[1] + + pixel.B * direction[2]; + const int factor = gl::clamp( + static_cast( + (static_cast(dot - stops[1]) / (stops[0] - stops[1])) * 2 + + 0.5f), + 0, 2); + switch (factor) + { + case 0: + encodedColors[i] = 0; + break; + case 1: + encodedColors[i] = 2; + break; + case 2: + default: + encodedColors[i] = 1; + break; + } + } } } } else { - for (int i = 15; i >= 0; i--) + for (size_t i = 0; i < numColors; i++) { - // In non-opaque mode, 3 is for tranparent pixels. + const int count = pixelIndexCounts[i]; + if (count > 0) + { + // In opaque mode, the code is from 0 to 3. - bits <<= 2; - if (0 == rgba[i].A) - { - bits |= 3; - } - else - { - const int dot = rgba[i].R * direction[0] + rgba[i].G * direction[1] + - rgba[i].B * direction[2]; + const R8G8B8A8 &pixel = subblockColors[i]; + const int dot = + pixel.R * direction[0] + pixel.G * direction[1] + pixel.B * direction[2]; const int factor = gl::clamp( static_cast( - (static_cast(dot - stops[1]) / (stops[0] - stops[1])) * 2 + + (static_cast(dot - stops[1]) / (stops[0] - stops[1])) * 3 + 0.5f), - 0, 2); + 0, 3); switch (factor) { case 0: - bits |= 0; + encodedColors[i] = 1; break; case 1: - bits |= 2; + encodedColors[i] = 3; break; case 2: + encodedColors[i] = 2; + break; + case 3: default: - bits |= 1; + encodedColors[i] = 0; break; } } } } + uint32_t bits = 0; + for (int i = kNumPixelsInBlock - 1; i >= 0; i--) + { + bits <<= 2; + bits |= encodedColors[pixelIndices[i]]; + } + return bits; } void packBC1(void *bc1, - const R8G8B8A8 *rgba, - R8G8B8A8 &minColor, - R8G8B8A8 &maxColor, - bool opaque) const + const int *pixelIndices, + const int *pixelIndexCounts, + const R8G8B8A8 *subblockColors, + size_t numColors, + int minColorIndex, + int maxColorIndex, + bool nonOpaquePunchThroughAlpha) const { + const R8G8B8A8 &minColor = subblockColors[minColorIndex]; + const R8G8B8A8 &maxColor = subblockColors[maxColorIndex]; + uint32_t bits; uint16_t max16 = RGB8ToRGB565(maxColor); uint16_t min16 = RGB8ToRGB565(minColor); if (max16 != min16) { // Find the best BC1 code for each pixel - bits = matchBC1Bits(rgba, minColor, maxColor, opaque); + bits = matchBC1Bits(pixelIndices, pixelIndexCounts, subblockColors, numColors, minColor, + maxColor, nonOpaquePunchThroughAlpha); } else { // Same colors, BC1 index 0 is the color in both opaque and transparent mode bits = 0; // BC1 index 3 is transparent - if (!opaque) + if (nonOpaquePunchThroughAlpha) { - for (int i = 0; i < 16; i++) + for (int i = 0; i < kNumPixelsInBlock; i++) { - if (0 == rgba[i].A) + if (0 == subblockColors[pixelIndices[i]].A) { bits |= (3 << (i * 2)); } @@ -772,15 +795,7 @@ struct ETC2Block std::swap(max16, min16); uint32_t xorMask = 0; - if (opaque) - { - // In opaque mode switching the two colors is doing the - // following code swaps: 0 <-> 1 and 2 <-> 3. This is - // equivalent to flipping the first bit of each code - // (5 = 0b0101) - xorMask = 0x55555555; - } - else + if (nonOpaquePunchThroughAlpha) { // In transparent mode switching the colors is doing the // following code swap: 0 <-> 1. 0xA selects the second bit of @@ -790,6 +805,14 @@ struct ETC2Block // 0 or 1. xorMask = ~((bits >> 1) | 0xAAAAAAAA); } + else + { + // In opaque mode switching the two colors is doing the + // following code swaps: 0 <-> 1 and 2 <-> 3. This is + // equivalent to flipping the first bit of each code + // (5 = 0b0101) + xorMask = 0x55555555; + } bits ^= xorMask; } @@ -802,16 +825,16 @@ struct ETC2Block // Encode the opaqueness in the order of the two BC1 colors BC1Block *dest = reinterpret_cast(bc1); - if (opaque) - { - dest->color0 = max16; - dest->color1 = min16; - } - else + if (nonOpaquePunchThroughAlpha) { dest->color0 = min16; dest->color1 = max16; } + else + { + dest->color0 = max16; + dest->color1 = min16; + } dest->bits = bits; } @@ -829,7 +852,7 @@ struct ETC2Block int b1 = extend_4to8bits(block.B1); int r2 = extend_4to8bits(block.R2); int g2 = extend_4to8bits(block.G2); - int b2 = extend_4to8bits(block.B2); + int b2 = extend_4to8bits(block.B2); transcodeIndividualOrDifferentialBlockToBC1(dest, x, y, w, h, r1, g1, b1, r2, g2, b2, alphaValues, nonOpaquePunchThroughAlpha); } @@ -848,53 +871,184 @@ struct ETC2Block int r1 = extend_5to8bits(block.R); int r2 = extend_5to8bits(block.R + block.dR); int g2 = extend_5to8bits(block.G + block.dG); - int b2 = extend_5to8bits(block.B + block.dB); + int b2 = extend_5to8bits(block.B + block.dB); transcodeIndividualOrDifferentialBlockToBC1(dest, x, y, w, h, r1, g1, b1, r2, g2, b2, alphaValues, nonOpaquePunchThroughAlpha); } - void decodeSubblock(R8G8B8A8 *rgbaBlock, - size_t pixelRange[2][2], - size_t x, - size_t y, - size_t w, - size_t h, - const uint8_t alphaValues[4][4], - bool flipbit, - size_t subblockIdx, - const R8G8B8A8 subblockColors[2][4]) const + void extractPixelIndices(int *pixelIndices, + int *pixelIndicesCounts, + size_t x, + size_t y, + size_t w, + size_t h, + bool flipbit, + size_t subblockIdx) const { size_t dxBegin = 0; size_t dxEnd = 4; size_t dyBegin = subblockIdx * 2; - size_t dyEnd = dyBegin + 2; + size_t dyEnd = dyBegin + 2; if (!flipbit) { std::swap(dxBegin, dyBegin); std::swap(dxEnd, dyEnd); } - for (size_t j = dyBegin; j < dyEnd && (y + j) < h; j++) + for (size_t j = dyBegin; j < dyEnd; j++) { - R8G8B8A8 *row = &rgbaBlock[j * 4]; - for (size_t i = dxBegin; i < dxEnd && (x + i) < w; i++) + int *row = &pixelIndices[j * 4]; + for (size_t i = dxBegin; i < dxEnd; i++) { - const size_t pixelIndex = getIndex(i, j); - if (valueMappingTable[pixelIndex] < valueMappingTable[pixelRange[subblockIdx][0]]) - { - pixelRange[subblockIdx][0] = pixelIndex; - } - if (valueMappingTable[pixelIndex] > valueMappingTable[pixelRange[subblockIdx][1]]) - { - pixelRange[subblockIdx][1] = pixelIndex; - } - - row[i] = subblockColors[subblockIdx][pixelIndex]; - row[i].A = alphaValues[j][i]; + const size_t pixelIndex = subblockIdx * 4 + getIndex(i, j); + row[i] = static_cast(pixelIndex); + pixelIndicesCounts[pixelIndex]++; } } } + void selectEndPointPCA(const int *pixelIndexCounts, + const R8G8B8A8 *subblockColors, + size_t numColors, + int *minColorIndex, + int *maxColorIndex) const + { + // determine color distribution + int mu[3], min[3], max[3]; + for (int ch = 0; ch < 3; ch++) + { + int muv = 0; + int minv = 255; + int maxv = 0; + for (size_t i = 0; i < numColors; i++) + { + const int count = pixelIndexCounts[i]; + if (count > 0) + { + const auto &pixel = subblockColors[i]; + if (pixel.A > 0) + { + // Non-transparent pixels + muv += (&pixel.R)[ch] * count; + minv = std::min(minv, (&pixel.R)[ch]); + maxv = std::max(maxv, (&pixel.R)[ch]); + } + } + } + + mu[ch] = (muv + kNumPixelsInBlock / 2) / kNumPixelsInBlock; + min[ch] = minv; + max[ch] = maxv; + } + + // determine covariance matrix + int cov[6] = {0, 0, 0, 0, 0, 0}; + for (size_t i = 0; i < numColors; i++) + { + const int count = pixelIndexCounts[i]; + if (count > 0) + { + const auto &pixel = subblockColors[i]; + if (pixel.A > 0) + { + int r = pixel.R - mu[0]; + int g = pixel.G - mu[1]; + int b = pixel.B - mu[2]; + + cov[0] += r * r * count; + cov[1] += r * g * count; + cov[2] += r * b * count; + cov[3] += g * g * count; + cov[4] += g * b * count; + cov[5] += b * b * count; + } + } + } + + // Power iteration algorithm to get the eigenvalues and eigenvector + + // Starts with diagonal vector + float vfr = static_cast(max[0] - min[0]); + float vfg = static_cast(max[1] - min[1]); + float vfb = static_cast(max[2] - min[2]); + float eigenvalue; + + static const size_t kPowerIterations = 4; + for (size_t i = 0; i < kPowerIterations; i++) + { + float r = vfr * cov[0] + vfg * cov[1] + vfb * cov[2]; + float g = vfr * cov[1] + vfg * cov[3] + vfb * cov[4]; + float b = vfr * cov[2] + vfg * cov[4] + vfb * cov[5]; + + vfr = r; + vfg = g; + vfb = b; + + eigenvalue = sqrt(r * r + g * g + b * b); + if (eigenvalue > 0) + { + float invNorm = 1.0f / eigenvalue; + vfr *= invNorm; + vfg *= invNorm; + vfb *= invNorm; + } + } + + int vr, vg, vb; + + static const float kDefaultLuminanceThreshold = 4.0f * 255; + static const float kQuantizeRange = 512.0f; + if (eigenvalue < kDefaultLuminanceThreshold) // too small, default to luminance + { + // Luminance weights defined by ITU-R Recommendation BT.601, scaled by 1000 + vr = 299; + vg = 587; + vb = 114; + } + else + { + // From the eigenvalue and eigenvector, choose the axis to project + // colors on. When projecting colors we want to do integer computations + // for speed, so we normalize the eigenvector to the [0, 512] range. + float magn = std::max(std::max(std::abs(vfr), std::abs(vfg)), std::abs(vfb)); + magn = kQuantizeRange / magn; + vr = static_cast(vfr * magn); + vg = static_cast(vfg * magn); + vb = static_cast(vfb * magn); + } + + // Pick colors at extreme points + int minD = INT_MAX; + int maxD = 0; + size_t minIndex = 0; + size_t maxIndex = 0; + for (size_t i = 0; i < numColors; i++) + { + const int count = pixelIndexCounts[i]; + if (count > 0) + { + const auto &pixel = subblockColors[i]; + if (pixel.A > 0) + { + int dot = pixel.R * vr + pixel.G * vg + pixel.B * vb; + if (dot < minD) + { + minD = dot; + minIndex = i; + } + if (dot > maxD) + { + maxD = dot; + maxIndex = i; + } + } + } + } + + *minColorIndex = static_cast(minIndex); + *maxColorIndex = static_cast(maxIndex); + } + void transcodeIndividualOrDifferentialBlockToBC1(uint8_t *dest, size_t x, size_t y, @@ -912,76 +1066,63 @@ struct ETC2Block // A BC1 block has 2 endpoints, pixels is encoded as linear // interpolations of them. A ETC1/ETC2 individual or differential block // has 2 subblocks. Each subblock has one color and a modifier. We - // compute the max intensity and min intensity pixel values to use as + // select axis by principal component analysis (PCA) to use as // our two BC1 endpoints and then map pixels to BC1 by projecting on the // line between the two endpoints and choosing the right fraction. - // - // In the future, we have 2 potential improvements to this algorithm. - // 1. We don't actually need to decode ETC blocks to RGBs. Instead, - // the subblock colors and pixel indices alreay contains enough - // information for transcode. A direct mapping would be more - // efficient here. - // 2. Currently the BC1 endpoints come from the max and min intensity - // of ETC colors. A principal component analysis (PCA) on them might - // give us better quality results, with limited costs - const auto intensityModifier = + // The goal of this algorithm is make it faster than decode ETC to RGBs + // and then encode to BC. To achieve this, we only extract subblock + // colors, pixel indices, and counts of each pixel indices from ETC. + // With those information, we can only encode used subblock colors + // to BC1, and copy the bits to the right pixels. + // Fully decode and encode need to process 16 RGBA pixels. With this + // algorithm, it's 8 pixels at maximum for a individual or + // differential block. Saves us bandwidth and computations. + + static const size_t kNumColors = 8; + + const IntensityModifier *intensityModifier = nonOpaquePunchThroughAlpha ? intensityModifierNonOpaque : intensityModifierDefault; // Compute the colors that pixels can have in each subblock both for // the decoding of the RGBA data and BC1 encoding - R8G8B8A8 subblockColors[2][4]; + R8G8B8A8 subblockColors[kNumColors]; for (size_t modifierIdx = 0; modifierIdx < 4; modifierIdx++) { - const int i1 = intensityModifier[u.idht.mode.idm.cw1][modifierIdx]; - subblockColors[0][modifierIdx] = createRGBA(r1 + i1, g1 + i1, b1 + i1); + if (nonOpaquePunchThroughAlpha && (modifierIdx == 2)) + { + // In ETC opaque punch through formats, individual and + // differential blocks take index 2 as transparent pixel. + // Thus we don't need to compute its color, just assign it + // as black. + subblockColors[modifierIdx] = createRGBA(0, 0, 0, 0); + subblockColors[4 + modifierIdx] = createRGBA(0, 0, 0, 0); + } + else + { + const int i1 = intensityModifier[u.idht.mode.idm.cw1][modifierIdx]; + subblockColors[modifierIdx] = createRGBA(r1 + i1, g1 + i1, b1 + i1); - const int i2 = intensityModifier[u.idht.mode.idm.cw2][modifierIdx]; - subblockColors[1][modifierIdx] = createRGBA(r2 + i2, g2 + i2, b2 + i2); + const int i2 = intensityModifier[u.idht.mode.idm.cw2][modifierIdx]; + subblockColors[4 + modifierIdx] = createRGBA(r2 + i2, g2 + i2, b2 + i2); + } } - // 1 and 3 are the argmax and argmin of valueMappingTable - size_t pixelRange[2][2] = {{1, 3}, {1, 3}}; - R8G8B8A8 rgbaBlock[16]; - // Decode the block in rgbaBlock and store the inverse valueTableMapping - // of {min(modifier index), max(modifier index)} + int pixelIndices[kNumPixelsInBlock]; + int pixelIndexCounts[kNumColors] = {0}; + // Extract pixel indices from a ETC block. for (size_t blockIdx = 0; blockIdx < 2; blockIdx++) { - decodeSubblock(rgbaBlock, pixelRange, x, y, w, h, alphaValues, u.idht.mode.idm.flipbit, - blockIdx, subblockColors); - } - if (nonOpaquePunchThroughAlpha) - { - decodePunchThroughAlphaBlock(reinterpret_cast(rgbaBlock), x, y, w, h, - sizeof(R8G8B8A8) * 4); + extractPixelIndices(pixelIndices, pixelIndexCounts, x, y, w, h, u.idht.mode.idm.flipbit, + blockIdx); } - // Get the "min" and "max" pixel colors that have been used. - R8G8B8A8 minColor; - const R8G8B8A8 &minColor0 = subblockColors[0][pixelRange[0][0]]; - const R8G8B8A8 &minColor1 = subblockColors[1][pixelRange[1][0]]; - if (minColor0.R + minColor0.G + minColor0.B < minColor1.R + minColor1.G + minColor1.B) - { - minColor = minColor0; - } - else - { - minColor = minColor1; - } + int minColorIndex, maxColorIndex; + selectEndPointPCA(pixelIndexCounts, subblockColors, kNumColors, &minColorIndex, + &maxColorIndex); - R8G8B8A8 maxColor; - const R8G8B8A8 &maxColor0 = subblockColors[0][pixelRange[0][1]]; - const R8G8B8A8 &maxColor1 = subblockColors[1][pixelRange[1][1]]; - if (maxColor0.R + maxColor0.G + maxColor0.B < maxColor1.R + maxColor1.G + maxColor1.B) - { - maxColor = maxColor1; - } - else - { - maxColor = maxColor0; - } - - packBC1(dest, rgbaBlock, minColor, maxColor, !nonOpaquePunchThroughAlpha); + packBC1(dest, pixelIndices, pixelIndexCounts, subblockColors, kNumColors, minColorIndex, + maxColorIndex, nonOpaquePunchThroughAlpha); } void transcodeTBlockToBC1(uint8_t *dest, @@ -992,8 +1133,48 @@ struct ETC2Block const uint8_t alphaValues[4][4], bool nonOpaquePunchThroughAlpha) const { - // TODO (mgong): Will be implemented soon - UNIMPLEMENTED(); + static const size_t kNumColors = 4; + + // Table C.8, distance index for T and H modes + const auto &block = u.idht.mode.tm; + + int r1 = extend_4to8bits(block.TR1a << 2 | block.TR1b); + int g1 = extend_4to8bits(block.TG1); + int b1 = extend_4to8bits(block.TB1); + int r2 = extend_4to8bits(block.TR2); + int g2 = extend_4to8bits(block.TG2); + int b2 = extend_4to8bits(block.TB2); + + static int distance[8] = {3, 6, 11, 16, 23, 32, 41, 64}; + const int d = distance[block.Tda << 1 | block.Tdb]; + + // In ETC opaque punch through formats, index == 2 means transparent pixel. + // Thus we don't need to compute its color, just assign it as black. + const R8G8B8A8 paintColors[kNumColors] = { + createRGBA(r1, g1, b1), createRGBA(r2 + d, g2 + d, b2 + d), + nonOpaquePunchThroughAlpha ? createRGBA(0, 0, 0, 0) : createRGBA(r2, g2, b2), + createRGBA(r2 - d, g2 - d, b2 - d), + }; + + int pixelIndices[kNumPixelsInBlock]; + int pixelIndexCounts[kNumColors] = {0}; + for (size_t j = 0; j < 4; j++) + { + int *row = &pixelIndices[j * 4]; + for (size_t i = 0; i < 4; i++) + { + const size_t pixelIndex = getIndex(i, j); + row[i] = static_cast(pixelIndex); + pixelIndexCounts[pixelIndex]++; + } + } + + int minColorIndex, maxColorIndex; + selectEndPointPCA(pixelIndexCounts, paintColors, kNumColors, &minColorIndex, + &maxColorIndex); + + packBC1(dest, pixelIndices, pixelIndexCounts, paintColors, kNumColors, minColorIndex, + maxColorIndex, nonOpaquePunchThroughAlpha); } void transcodeHBlockToBC1(uint8_t *dest, @@ -1004,8 +1185,51 @@ struct ETC2Block const uint8_t alphaValues[4][4], bool nonOpaquePunchThroughAlpha) const { - // TODO (mgong): Will be implemented soon - UNIMPLEMENTED(); + static const size_t kNumColors = 4; + + // Table C.8, distance index for T and H modes + const auto &block = u.idht.mode.hm; + + int r1 = extend_4to8bits(block.HR1); + int g1 = extend_4to8bits(block.HG1a << 1 | block.HG1b); + int b1 = extend_4to8bits(block.HB1a << 3 | block.HB1b << 1 | block.HB1c); + int r2 = extend_4to8bits(block.HR2); + int g2 = extend_4to8bits(block.HG2a << 1 | block.HG2b); + int b2 = extend_4to8bits(block.HB2); + + static const int distance[8] = {3, 6, 11, 16, 23, 32, 41, 64}; + const int orderingTrickBit = + ((r1 << 16 | g1 << 8 | b1) >= (r2 << 16 | g2 << 8 | b2) ? 1 : 0); + const int d = distance[(block.Hda << 2) | (block.Hdb << 1) | orderingTrickBit]; + + // In ETC opaque punch through formats, index == 2 means transparent pixel. + // Thus we don't need to compute its color, just assign it as black. + const R8G8B8A8 paintColors[kNumColors] = { + createRGBA(r1 + d, g1 + d, b1 + d), createRGBA(r1 - d, g1 - d, b1 - d), + nonOpaquePunchThroughAlpha ? createRGBA(0, 0, 0, 0) + : createRGBA(r2 + d, g2 + d, b2 + d), + createRGBA(r2 - d, g2 - d, b2 - d), + }; + + int pixelIndices[kNumPixelsInBlock]; + int pixelIndexCounts[kNumColors] = {0}; + for (size_t j = 0; j < 4; j++) + { + int *row = &pixelIndices[j * 4]; + for (size_t i = 0; i < 4; i++) + { + const size_t pixelIndex = getIndex(i, j); + row[i] = static_cast(pixelIndex); + pixelIndexCounts[pixelIndex]++; + } + } + + int minColorIndex, maxColorIndex; + selectEndPointPCA(pixelIndexCounts, paintColors, kNumColors, &minColorIndex, + &maxColorIndex); + + packBC1(dest, pixelIndices, pixelIndexCounts, paintColors, kNumColors, minColorIndex, + maxColorIndex, nonOpaquePunchThroughAlpha); } void transcodePlanarBlockToBC1(uint8_t *dest, @@ -1015,8 +1239,22 @@ struct ETC2Block size_t h, const uint8_t alphaValues[4][4]) const { - // TODO (mgong): Will be implemented soon - UNIMPLEMENTED(); + static const size_t kNumColors = kNumPixelsInBlock; + + R8G8B8A8 rgbaBlock[kNumColors]; + decodePlanarBlock(reinterpret_cast(rgbaBlock), x, y, w, h, sizeof(R8G8B8A8) * 4, + alphaValues); + + // Planar block doesn't have a color table, fill indices as full + int pixelIndices[kNumPixelsInBlock] = {0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15}; + int pixelIndexCounts[kNumColors] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; + + int minColorIndex, maxColorIndex; + selectEndPointPCA(pixelIndexCounts, rgbaBlock, kNumColors, &minColorIndex, &maxColorIndex); + + packBC1(dest, pixelIndices, pixelIndexCounts, rgbaBlock, kNumColors, minColorIndex, + maxColorIndex, false); } // Single channel utility functions @@ -1108,9 +1346,9 @@ void LoadR11EACToR8(size_t width, for (size_t y = 0; y < height; y += 4) { const ETC2Block *sourceRow = - OffsetDataPointer(input, y / 4, z, inputRowPitch, inputDepthPitch); + priv::OffsetDataPointer(input, y / 4, z, inputRowPitch, inputDepthPitch); uint8_t *destRow = - OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); for (size_t x = 0; x < width; x += 4) { @@ -1140,9 +1378,9 @@ void LoadRG11EACToRG8(size_t width, for (size_t y = 0; y < height; y += 4) { const ETC2Block *sourceRow = - OffsetDataPointer(input, y / 4, z, inputRowPitch, inputDepthPitch); + priv::OffsetDataPointer(input, y / 4, z, inputRowPitch, inputDepthPitch); uint8_t *destRow = - OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); for (size_t x = 0; x < width; x += 4) { @@ -1176,9 +1414,9 @@ void LoadETC2RGB8ToRGBA8(size_t width, for (size_t y = 0; y < height; y += 4) { const ETC2Block *sourceRow = - OffsetDataPointer(input, y / 4, z, inputRowPitch, inputDepthPitch); + priv::OffsetDataPointer(input, y / 4, z, inputRowPitch, inputDepthPitch); uint8_t *destRow = - OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); for (size_t x = 0; x < width; x += 4) { @@ -1208,9 +1446,9 @@ void LoadETC2RGB8ToBC1(size_t width, for (size_t y = 0; y < height; y += 4) { const ETC2Block *sourceRow = - OffsetDataPointer(input, y / 4, z, inputRowPitch, inputDepthPitch); - uint8_t *destRow = - OffsetDataPointer(output, y / 4, z, outputRowPitch, outputDepthPitch); + priv::OffsetDataPointer(input, y / 4, z, inputRowPitch, inputDepthPitch); + uint8_t *destRow = priv::OffsetDataPointer(output, y / 4, z, outputRowPitch, + outputDepthPitch); for (size_t x = 0; x < width; x += 4) { @@ -1242,9 +1480,9 @@ void LoadETC2RGBA8ToRGBA8(size_t width, for (size_t y = 0; y < height; y += 4) { const ETC2Block *sourceRow = - OffsetDataPointer(input, y / 4, z, inputRowPitch, inputDepthPitch); + priv::OffsetDataPointer(input, y / 4, z, inputRowPitch, inputDepthPitch); uint8_t *destRow = - OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); + priv::OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); for (size_t x = 0; x < width; x += 4) { @@ -1362,6 +1600,20 @@ void LoadETC2RGB8ToRGBA8(size_t width, outputRowPitch, outputDepthPitch, false); } +void LoadETC2RGB8ToBC1(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + LoadETC2RGB8ToBC1(width, height, depth, input, inputRowPitch, inputDepthPitch, output, + outputRowPitch, outputDepthPitch, false); +} + void LoadETC2SRGB8ToRGBA8(size_t width, size_t height, size_t depth, @@ -1376,6 +1628,20 @@ void LoadETC2SRGB8ToRGBA8(size_t width, outputRowPitch, outputDepthPitch, false); } +void LoadETC2SRGB8ToBC1(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + LoadETC2RGB8ToBC1(width, height, depth, input, inputRowPitch, inputDepthPitch, output, + outputRowPitch, outputDepthPitch, false); +} + void LoadETC2RGB8A1ToRGBA8(size_t width, size_t height, size_t depth, @@ -1390,6 +1656,20 @@ void LoadETC2RGB8A1ToRGBA8(size_t width, outputRowPitch, outputDepthPitch, true); } +void LoadETC2RGB8A1ToBC1(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + LoadETC2RGB8ToBC1(width, height, depth, input, inputRowPitch, inputDepthPitch, output, + outputRowPitch, outputDepthPitch, true); +} + void LoadETC2SRGB8A1ToRGBA8(size_t width, size_t height, size_t depth, @@ -1404,6 +1684,20 @@ void LoadETC2SRGB8A1ToRGBA8(size_t width, outputRowPitch, outputDepthPitch, true); } +void LoadETC2SRGB8A1ToBC1(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + LoadETC2RGB8ToBC1(width, height, depth, input, inputRowPitch, inputDepthPitch, output, + outputRowPitch, outputDepthPitch, true); +} + void LoadETC2RGBA8ToRGBA8(size_t width, size_t height, size_t depth, @@ -1432,4 +1726,4 @@ void LoadETC2SRGBA8ToSRGBA8(size_t width, outputRowPitch, outputDepthPitch, true); } -} // namespace rx +} // namespace angle diff --git a/src/3rdparty/angle/src/libANGLE/AttributeMap.cpp b/src/3rdparty/angle/src/libANGLE/AttributeMap.cpp index 651a012037..e10d3add7c 100644 --- a/src/3rdparty/angle/src/libANGLE/AttributeMap.cpp +++ b/src/3rdparty/angle/src/libANGLE/AttributeMap.cpp @@ -6,6 +6,8 @@ #include "libANGLE/AttributeMap.h" +#include "common/debug.h" + namespace egl { @@ -13,33 +15,61 @@ AttributeMap::AttributeMap() { } -AttributeMap::AttributeMap(const EGLint *attributes) -{ - if (attributes) - { - for (const EGLint *curAttrib = attributes; curAttrib[0] != EGL_NONE; curAttrib += 2) - { - insert(curAttrib[0], curAttrib[1]); - } - } -} +AttributeMap::AttributeMap(const AttributeMap &other) = default; -void AttributeMap::insert(EGLint key, EGLint value) +AttributeMap::~AttributeMap() = default; + +void AttributeMap::insert(EGLAttrib key, EGLAttrib value) { mAttributes[key] = value; } -bool AttributeMap::contains(EGLint key) const +bool AttributeMap::contains(EGLAttrib key) const { return (mAttributes.find(key) != mAttributes.end()); } -EGLint AttributeMap::get(EGLint key, EGLint defaultValue) const +EGLAttrib AttributeMap::get(EGLAttrib key) const { - std::map::const_iterator iter = mAttributes.find(key); + auto iter = mAttributes.find(key); + ASSERT(iter != mAttributes.end()); + return iter->second; +} + +EGLAttrib AttributeMap::get(EGLAttrib key, EGLAttrib defaultValue) const +{ + auto iter = mAttributes.find(key); return (mAttributes.find(key) != mAttributes.end()) ? iter->second : defaultValue; } +EGLint AttributeMap::getAsInt(EGLAttrib key) const +{ + return static_cast(get(key)); +} + +EGLint AttributeMap::getAsInt(EGLAttrib key, EGLint defaultValue) const +{ + return static_cast(get(key, static_cast(defaultValue))); +} + +bool AttributeMap::isEmpty() const +{ + return mAttributes.empty(); +} + +std::vector AttributeMap::toIntVector() const +{ + std::vector ret; + for (const auto &pair : mAttributes) + { + ret.push_back(static_cast(pair.first)); + ret.push_back(static_cast(pair.second)); + } + ret.push_back(EGL_NONE); + + return ret; +} + AttributeMap::const_iterator AttributeMap::begin() const { return mAttributes.begin(); @@ -50,4 +80,31 @@ AttributeMap::const_iterator AttributeMap::end() const return mAttributes.end(); } +// static +AttributeMap AttributeMap::CreateFromIntArray(const EGLint *attributes) +{ + AttributeMap map; + if (attributes) + { + for (const EGLint *curAttrib = attributes; curAttrib[0] != EGL_NONE; curAttrib += 2) + { + map.insert(static_cast(curAttrib[0]), static_cast(curAttrib[1])); + } + } + return map; +} + +// static +AttributeMap AttributeMap::CreateFromAttribArray(const EGLAttrib *attributes) +{ + AttributeMap map; + if (attributes) + { + for (const EGLAttrib *curAttrib = attributes; curAttrib[0] != EGL_NONE; curAttrib += 2) + { + map.insert(curAttrib[0], curAttrib[1]); + } + } + return map; +} } diff --git a/src/3rdparty/angle/src/libANGLE/AttributeMap.h b/src/3rdparty/angle/src/libANGLE/AttributeMap.h index 56f1684415..eddc1b72d0 100644 --- a/src/3rdparty/angle/src/libANGLE/AttributeMap.h +++ b/src/3rdparty/angle/src/libANGLE/AttributeMap.h @@ -11,6 +11,7 @@ #include #include +#include namespace egl { @@ -19,19 +20,28 @@ class AttributeMap final { public: AttributeMap(); - explicit AttributeMap(const EGLint *attributes); + AttributeMap(const AttributeMap &other); + ~AttributeMap(); - void insert(EGLint key, EGLint value); - bool contains(EGLint key) const; - EGLint get(EGLint key, EGLint defaultValue) const; + void insert(EGLAttrib key, EGLAttrib value); + bool contains(EGLAttrib key) const; + EGLAttrib get(EGLAttrib key) const; + EGLAttrib get(EGLAttrib key, EGLAttrib defaultValue) const; + EGLint getAsInt(EGLAttrib key) const; + EGLint getAsInt(EGLAttrib key, EGLint defaultValue) const; + bool isEmpty() const; + std::vector toIntVector() const; - typedef std::map::const_iterator const_iterator; + typedef std::map::const_iterator const_iterator; const_iterator begin() const; const_iterator end() const; + static AttributeMap CreateFromIntArray(const EGLint *attributes); + static AttributeMap CreateFromAttribArray(const EGLAttrib *attributes); + private: - std::map mAttributes; + std::map mAttributes; }; } diff --git a/src/3rdparty/angle/src/libANGLE/BinaryStream.h b/src/3rdparty/angle/src/libANGLE/BinaryStream.h index 3e6ccc7446..3e4c0934cf 100644 --- a/src/3rdparty/angle/src/libANGLE/BinaryStream.h +++ b/src/3rdparty/angle/src/libANGLE/BinaryStream.h @@ -9,25 +9,13 @@ #ifndef LIBANGLE_BINARYSTREAM_H_ #define LIBANGLE_BINARYSTREAM_H_ -#include "common/angleutils.h" -#include "common/mathutil.h" - #include #include #include #include -template -void StaticAssertIsFundamental() -{ - // c++11 STL is not available on OSX or Android -#if !defined(ANGLE_PLATFORM_APPLE) && !defined(ANGLE_PLATFORM_ANDROID) - static_assert(std::is_fundamental::value, "T must be a fundamental type."); -#else - union { T dummy; } dummy; - static_cast(dummy); -#endif -} +#include "common/angleutils.h" +#include "common/mathutil.h" namespace gl { @@ -58,6 +46,16 @@ class BinaryInputStream : angle::NonCopyable *outValue = readInt(); } + template + void readIntVector(std::vector *param) + { + unsigned int size = readInt(); + for (unsigned int index = 0; index < size; ++index) + { + param->push_back(readInt()); + } + } + bool readBool() { int value = 0; @@ -92,25 +90,31 @@ class BinaryInputStream : angle::NonCopyable return; } - if (!rx::IsUnsignedAdditionSafe(mOffset, length) || mOffset + length > mLength) + angle::CheckedNumeric checkedOffset(mOffset); + checkedOffset += length; + + if (!checkedOffset.IsValid() || mOffset + length > mLength) { mError = true; return; } v->assign(reinterpret_cast(mData) + mOffset, length); - mOffset += length; + mOffset = checkedOffset.ValueOrDie(); } void skip(size_t length) { - if (!rx::IsUnsignedAdditionSafe(mOffset, length) || mOffset + length > mLength) + angle::CheckedNumeric checkedOffset(mOffset); + checkedOffset += length; + + if (!checkedOffset.IsValid() || mOffset + length > mLength) { mError = true; return; } - mOffset += length; + mOffset = checkedOffset.ValueOrDie(); } size_t offset() const @@ -142,24 +146,27 @@ class BinaryInputStream : angle::NonCopyable template void read(T *v, size_t num) { - StaticAssertIsFundamental(); + static_assert(std::is_fundamental::value, "T must be a fundamental type."); - if (!rx::IsUnsignedMultiplicationSafe(num, sizeof(T))) + angle::CheckedNumeric checkedLength(num); + checkedLength *= sizeof(T); + if (!checkedLength.IsValid()) { mError = true; return; } - size_t length = num * sizeof(T); + angle::CheckedNumeric checkedOffset(mOffset); + checkedOffset += checkedLength; - if (!rx::IsUnsignedAdditionSafe(mOffset, length) || mOffset + length > mLength) + if (!checkedOffset.IsValid() || checkedOffset.ValueOrDie() > mLength) { mError = true; return; } - memcpy(v, mData + mOffset, length); - mOffset += length; + memcpy(v, mData + mOffset, checkedLength.ValueOrDie()); + mOffset = checkedOffset.ValueOrDie(); } template @@ -173,19 +180,42 @@ class BinaryInputStream : angle::NonCopyable class BinaryOutputStream : angle::NonCopyable { public: - BinaryOutputStream() - { - } + BinaryOutputStream(); + ~BinaryOutputStream(); // writeInt also handles bool types template void writeInt(IntT param) { - ASSERT(rx::IsIntegerCastSafe(param)); + ASSERT(angle::IsValueInRangeForNumericType(param)); int intValue = static_cast(param); write(&intValue, 1); } + // Specialized writeInt for values that can also be exactly -1. + template + void writeIntOrNegOne(UintT param) + { + if (param == static_cast(-1)) + { + writeInt(-1); + } + else + { + writeInt(param); + } + } + + template + void writeIntVector(std::vector param) + { + writeInt(param.size()); + for (IntT element : param) + { + writeIntOrNegOne(element); + } + } + void writeString(const std::string &v) { writeInt(v.length()); @@ -204,7 +234,7 @@ class BinaryOutputStream : angle::NonCopyable const void* data() const { - return mData.size() ? &mData[0] : NULL; + return mData.size() ? &mData[0] : nullptr; } private: @@ -213,12 +243,19 @@ class BinaryOutputStream : angle::NonCopyable template void write(const T *v, size_t num) { - StaticAssertIsFundamental(); + static_assert(std::is_fundamental::value, "T must be a fundamental type."); const char *asBytes = reinterpret_cast(v); mData.insert(mData.end(), asBytes, asBytes + num * sizeof(T)); } }; + +inline BinaryOutputStream::BinaryOutputStream() +{ } +inline BinaryOutputStream::~BinaryOutputStream() = default; + +} // namespace gl + #endif // LIBANGLE_BINARYSTREAM_H_ diff --git a/src/3rdparty/angle/src/libANGLE/Buffer.cpp b/src/3rdparty/angle/src/libANGLE/Buffer.cpp index 589735c5a8..a1ebfc1acb 100644 --- a/src/3rdparty/angle/src/libANGLE/Buffer.cpp +++ b/src/3rdparty/angle/src/libANGLE/Buffer.cpp @@ -9,123 +9,148 @@ // [OpenGL ES 2.0.24] section 2.9 page 21. #include "libANGLE/Buffer.h" + +#include "libANGLE/Context.h" #include "libANGLE/renderer/BufferImpl.h" -#include "libANGLE/renderer/Renderer.h" +#include "libANGLE/renderer/GLImplFactory.h" namespace gl { -Buffer::Buffer(rx::BufferImpl *impl, GLuint id) - : RefCountObject(id), - mBuffer(impl), - mLabel(), - mUsage(GL_STATIC_DRAW), +BufferState::BufferState() + : mLabel(), + mUsage(BufferUsage::StaticDraw), mSize(0), mAccessFlags(0), mAccess(GL_WRITE_ONLY_OES), mMapped(GL_FALSE), - mMapPointer(NULL), + mMapPointer(nullptr), mMapOffset(0), mMapLength(0) { } +BufferState::~BufferState() +{ +} + +Buffer::Buffer(rx::GLImplFactory *factory, GLuint id) + : RefCountObject(id), mImpl(factory->createBuffer(mState)) +{ +} + Buffer::~Buffer() { - SafeDelete(mBuffer); + SafeDelete(mImpl); +} + +Error Buffer::onDestroy(const Context *context) +{ + // In tests, mImpl might be null. + if (mImpl) + mImpl->destroy(context); + return NoError(); } void Buffer::setLabel(const std::string &label) { - mLabel = label; + mState.mLabel = label; } const std::string &Buffer::getLabel() const { - return mLabel; + return mState.mLabel; } -Error Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage) +Error Buffer::bufferData(const Context *context, + BufferBinding target, + const void *data, + GLsizeiptr size, + BufferUsage usage) { - gl::Error error = mBuffer->setData(data, size, usage); - if (error.isError()) + const void *dataForImpl = data; + + // If we are using robust resource init, make sure the buffer starts cleared. + // Note: the Context is checked for nullptr because of some testing code. + // TODO(jmadill): Investigate lazier clearing. + if (context && context->getGLState().isRobustResourceInitEnabled() && !data && size > 0) { - return error; + angle::MemoryBuffer *scratchBuffer = nullptr; + ANGLE_TRY(context->getZeroFilledBuffer(static_cast(size), &scratchBuffer)); + dataForImpl = scratchBuffer->data(); } + ANGLE_TRY(mImpl->setData(context, target, dataForImpl, size, usage)); + mIndexRangeCache.clear(); - mUsage = usage; - mSize = size; + mState.mUsage = usage; + mState.mSize = size; - return error; + return NoError(); } -Error Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset) +Error Buffer::bufferSubData(const Context *context, + BufferBinding target, + const void *data, + GLsizeiptr size, + GLintptr offset) { - gl::Error error = mBuffer->setSubData(data, size, offset); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mImpl->setSubData(context, target, data, size, offset)); mIndexRangeCache.invalidateRange(static_cast(offset), static_cast(size)); - return error; + return NoError(); } -Error Buffer::copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) +Error Buffer::copyBufferSubData(const Context *context, + Buffer *source, + GLintptr sourceOffset, + GLintptr destOffset, + GLsizeiptr size) { - gl::Error error = mBuffer->copySubData(source->getImplementation(), sourceOffset, destOffset, size); - if (error.isError()) - { - return error; - } + ANGLE_TRY( + mImpl->copySubData(context, source->getImplementation(), sourceOffset, destOffset, size)); mIndexRangeCache.invalidateRange(static_cast(destOffset), static_cast(size)); - return error; + return NoError(); } -Error Buffer::map(GLenum access) +Error Buffer::map(const Context *context, GLenum access) { - ASSERT(!mMapped); + ASSERT(!mState.mMapped); - Error error = mBuffer->map(access, &mMapPointer); - if (error.isError()) - { - mMapPointer = NULL; - return error; - } + mState.mMapPointer = nullptr; + ANGLE_TRY(mImpl->map(context, access, &mState.mMapPointer)); ASSERT(access == GL_WRITE_ONLY_OES); - mMapped = GL_TRUE; - mMapOffset = 0; - mMapLength = mSize; - mAccess = access; - mAccessFlags = GL_MAP_WRITE_BIT; + mState.mMapped = GL_TRUE; + mState.mMapOffset = 0; + mState.mMapLength = mState.mSize; + mState.mAccess = access; + mState.mAccessFlags = GL_MAP_WRITE_BIT; mIndexRangeCache.clear(); - return error; + return NoError(); } -Error Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access) +Error Buffer::mapRange(const Context *context, + GLintptr offset, + GLsizeiptr length, + GLbitfield access) { - ASSERT(!mMapped); - ASSERT(offset + length <= mSize); + ASSERT(!mState.mMapped); + ASSERT(offset + length <= mState.mSize); - Error error = mBuffer->mapRange(offset, length, access, &mMapPointer); - if (error.isError()) - { - mMapPointer = NULL; - return error; - } + mState.mMapPointer = nullptr; + ANGLE_TRY(mImpl->mapRange(context, offset, length, access, &mState.mMapPointer)); - mMapped = GL_TRUE; - mMapOffset = static_cast(offset); - mMapLength = static_cast(length); - mAccess = GL_WRITE_ONLY_OES; - mAccessFlags = access; + mState.mMapped = GL_TRUE; + mState.mMapOffset = static_cast(offset); + mState.mMapLength = static_cast(length); + mState.mAccess = GL_WRITE_ONLY_OES; + mState.mAccessFlags = access; // The OES_mapbuffer extension states that GL_WRITE_ONLY_OES is the only valid // value for GL_BUFFER_ACCESS_OES because it was written against ES2. Since there is @@ -137,28 +162,24 @@ Error Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access) mIndexRangeCache.invalidateRange(static_cast(offset), static_cast(length)); } - return error; + return NoError(); } -Error Buffer::unmap(GLboolean *result) +Error Buffer::unmap(const Context *context, GLboolean *result) { - ASSERT(mMapped); + ASSERT(mState.mMapped); - Error error = mBuffer->unmap(result); - if (error.isError()) - { - *result = GL_FALSE; - return error; - } + *result = GL_FALSE; + ANGLE_TRY(mImpl->unmap(context, result)); - mMapped = GL_FALSE; - mMapPointer = NULL; - mMapOffset = 0; - mMapLength = 0; - mAccess = GL_WRITE_ONLY_OES; - mAccessFlags = 0; + mState.mMapped = GL_FALSE; + mState.mMapPointer = nullptr; + mState.mMapOffset = 0; + mState.mMapLength = 0; + mState.mAccess = GL_WRITE_ONLY_OES; + mState.mAccessFlags = 0; - return error; + return NoError(); } void Buffer::onTransformFeedback() @@ -171,7 +192,8 @@ void Buffer::onPixelUnpack() mIndexRangeCache.clear(); } -Error Buffer::getIndexRange(GLenum type, +Error Buffer::getIndexRange(const gl::Context *context, + GLenum type, size_t offset, size_t count, bool primitiveRestartEnabled, @@ -179,18 +201,15 @@ Error Buffer::getIndexRange(GLenum type, { if (mIndexRangeCache.findRange(type, offset, count, primitiveRestartEnabled, outRange)) { - return gl::Error(GL_NO_ERROR); + return NoError(); } - Error error = mBuffer->getIndexRange(type, offset, count, primitiveRestartEnabled, outRange); - if (error.isError()) - { - return error; - } + ANGLE_TRY( + mImpl->getIndexRange(context, type, offset, count, primitiveRestartEnabled, outRange)); mIndexRangeCache.addRange(type, offset, count, primitiveRestartEnabled, *outRange); - return Error(GL_NO_ERROR); + return NoError(); } -} +} // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/Buffer.h b/src/3rdparty/angle/src/libANGLE/Buffer.h index 6c951ef586..86d4a9fd6f 100644 --- a/src/3rdparty/angle/src/libANGLE/Buffer.h +++ b/src/3rdparty/angle/src/libANGLE/Buffer.h @@ -15,69 +15,109 @@ #include "libANGLE/Debug.h" #include "libANGLE/Error.h" #include "libANGLE/IndexRangeCache.h" +#include "libANGLE/PackedGLEnums.h" #include "libANGLE/RefCountObject.h" namespace rx { class BufferImpl; +class GLImplFactory; }; namespace gl { +class Buffer; +class Context; + +class BufferState final : angle::NonCopyable +{ + public: + BufferState(); + ~BufferState(); + + const std::string &getLabel(); + + BufferUsage getUsage() const { return mUsage; } + GLbitfield getAccessFlags() const { return mAccessFlags; } + GLenum getAccess() const { return mAccess; } + GLboolean isMapped() const { return mMapped; } + void *getMapPointer() const { return mMapPointer; } + GLint64 getMapOffset() const { return mMapOffset; } + GLint64 getMapLength() const { return mMapLength; } + GLint64 getSize() const { return mSize; } + + private: + friend class Buffer; + + std::string mLabel; + + BufferUsage mUsage; + GLint64 mSize; + GLbitfield mAccessFlags; + GLenum mAccess; + GLboolean mMapped; + void *mMapPointer; + GLint64 mMapOffset; + GLint64 mMapLength; +}; class Buffer final : public RefCountObject, public LabeledObject { public: - Buffer(rx::BufferImpl *impl, GLuint id); - virtual ~Buffer(); + Buffer(rx::GLImplFactory *factory, GLuint id); + ~Buffer() override; + Error onDestroy(const Context *context) override; void setLabel(const std::string &label) override; const std::string &getLabel() const override; - Error bufferData(const void *data, GLsizeiptr size, GLenum usage); - Error bufferSubData(const void *data, GLsizeiptr size, GLintptr offset); - Error copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); - Error map(GLenum access); - Error mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access); - Error unmap(GLboolean *result); + Error bufferData(const Context *context, + BufferBinding target, + const void *data, + GLsizeiptr size, + BufferUsage usage); + Error bufferSubData(const Context *context, + BufferBinding target, + const void *data, + GLsizeiptr size, + GLintptr offset); + Error copyBufferSubData(const Context *context, + Buffer *source, + GLintptr sourceOffset, + GLintptr destOffset, + GLsizeiptr size); + Error map(const Context *context, GLenum access); + Error mapRange(const Context *context, GLintptr offset, GLsizeiptr length, GLbitfield access); + Error unmap(const Context *context, GLboolean *result); void onTransformFeedback(); void onPixelUnpack(); - Error getIndexRange(GLenum type, + Error getIndexRange(const gl::Context *context, + GLenum type, size_t offset, size_t count, bool primitiveRestartEnabled, IndexRange *outRange) const; - GLenum getUsage() const { return mUsage; } - GLbitfield getAccessFlags() const { return mAccessFlags; } - GLenum getAccess() const { return mAccess; } - GLboolean isMapped() const { return mMapped; } - GLvoid *getMapPointer() const { return mMapPointer; } - GLint64 getMapOffset() const { return mMapOffset; } - GLint64 getMapLength() const { return mMapLength; } - GLint64 getSize() const { return mSize; } + BufferUsage getUsage() const { return mState.mUsage; } + GLbitfield getAccessFlags() const { return mState.mAccessFlags; } + GLenum getAccess() const { return mState.mAccess; } + GLboolean isMapped() const { return mState.mMapped; } + void *getMapPointer() const { return mState.mMapPointer; } + GLint64 getMapOffset() const { return mState.mMapOffset; } + GLint64 getMapLength() const { return mState.mMapLength; } + GLint64 getSize() const { return mState.mSize; } - rx::BufferImpl *getImplementation() const { return mBuffer; } + rx::BufferImpl *getImplementation() const { return mImpl; } private: - rx::BufferImpl *mBuffer; - - std::string mLabel; - - GLenum mUsage; - GLint64 mSize; - GLbitfield mAccessFlags; - GLenum mAccess; - GLboolean mMapped; - GLvoid *mMapPointer; - GLint64 mMapOffset; - GLint64 mMapLength; + BufferState mState; + rx::BufferImpl *mImpl; mutable IndexRangeCache mIndexRangeCache; }; -} +} // namespace gl -#endif // LIBANGLE_BUFFER_H_ +#endif // LIBANGLE_BUFFER_H_ diff --git a/src/3rdparty/angle/src/libANGLE/Caps.cpp b/src/3rdparty/angle/src/libANGLE/Caps.cpp index 1eb54a1589..44da2bbe27 100644 --- a/src/3rdparty/angle/src/libANGLE/Caps.cpp +++ b/src/3rdparty/angle/src/libANGLE/Caps.cpp @@ -5,9 +5,12 @@ // #include "libANGLE/Caps.h" + #include "common/debug.h" #include "common/angleutils.h" +#include "libANGLE/formatutils.h" + #include "angle_gl.h" #include @@ -32,6 +35,10 @@ TextureCaps::TextureCaps() { } +TextureCaps::TextureCaps(const TextureCaps &other) = default; + +TextureCaps::~TextureCaps() = default; + GLuint TextureCaps::getMaxSamples() const { return !sampleCounts.empty() ? *sampleCounts.rbegin() : 0; @@ -56,40 +63,80 @@ GLuint TextureCaps::getNearestSamples(GLuint requestedSamples) const return 0; } -void TextureCapsMap::insert(GLenum internalFormat, const TextureCaps &caps) +TextureCaps GenerateMinimumTextureCaps(GLenum sizedInternalFormat, + const Version &clientVersion, + const Extensions &extensions) { - mCapsMap[internalFormat] = caps; + TextureCaps caps; + + const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(sizedInternalFormat); + caps.texturable = internalFormatInfo.textureSupport(clientVersion, extensions); + caps.renderable = internalFormatInfo.renderSupport(clientVersion, extensions); + caps.filterable = internalFormatInfo.filterSupport(clientVersion, extensions); + + caps.sampleCounts.insert(0); + if (internalFormatInfo.isRequiredRenderbufferFormat(clientVersion)) + { + if ((clientVersion.major >= 3 && clientVersion.minor >= 1) || + (clientVersion.major >= 3 && internalFormatInfo.componentType != GL_UNSIGNED_INT && + internalFormatInfo.componentType != GL_INT)) + { + caps.sampleCounts.insert(4); + } + } + + return caps; } -void TextureCapsMap::remove(GLenum internalFormat) +TextureCapsMap::TextureCapsMap() { - InternalFormatToCapsMap::iterator i = mCapsMap.find(internalFormat); - if (i != mCapsMap.end()) - { - mCapsMap.erase(i); - } +} + +TextureCapsMap::~TextureCapsMap() +{ +} + +void TextureCapsMap::insert(GLenum internalFormat, const TextureCaps &caps) +{ + angle::Format::ID formatID = angle::Format::InternalFormatToID(internalFormat); + get(formatID) = caps; +} + +void TextureCapsMap::clear() +{ + mFormatData.fill(TextureCaps()); } const TextureCaps &TextureCapsMap::get(GLenum internalFormat) const { - static TextureCaps defaultUnsupportedTexture; - InternalFormatToCapsMap::const_iterator iter = mCapsMap.find(internalFormat); - return (iter != mCapsMap.end()) ? iter->second : defaultUnsupportedTexture; + angle::Format::ID formatID = angle::Format::InternalFormatToID(internalFormat); + return get(formatID); } -TextureCapsMap::const_iterator TextureCapsMap::begin() const +const TextureCaps &TextureCapsMap::get(angle::Format::ID formatID) const { - return mCapsMap.begin(); + return mFormatData[static_cast(formatID)]; } -TextureCapsMap::const_iterator TextureCapsMap::end() const +TextureCaps &TextureCapsMap::get(angle::Format::ID formatID) { - return mCapsMap.end(); + return mFormatData[static_cast(formatID)]; } -size_t TextureCapsMap::size() const +void TextureCapsMap::set(angle::Format::ID formatID, const TextureCaps &caps) { - return mCapsMap.size(); + get(formatID) = caps; +} + +void InitMinimumTextureCapsMap(const Version &clientVersion, + const Extensions &extensions, + TextureCapsMap *capsMap) +{ + for (GLenum internalFormat : GetAllSizedInternalFormats()) + { + capsMap->insert(internalFormat, + GenerateMinimumTextureCaps(internalFormat, clientVersion, extensions)); + } } Extensions::Extensions() @@ -111,23 +158,25 @@ Extensions::Extensions() textureCompressionDXT1(false), textureCompressionDXT3(false), textureCompressionDXT5(false), + textureCompressionS3TCsRGB(false), textureCompressionASTCHDR(false), textureCompressionASTCLDR(false), compressedETC1RGB8Texture(false), + sRGB(false), depthTextures(false), depth32(false), textureStorage(false), textureNPOT(false), drawBuffers(false), textureFilterAnisotropic(false), - maxTextureAnisotropy(false), + maxTextureAnisotropy(0.0f), occlusionQueryBoolean(false), fence(false), - timerQuery(false), disjointTimerQuery(false), queryCounterBitsTimeElapsed(0), queryCounterBitsTimestamp(0), robustness(false), + robustBufferAccessBehavior(false), blendMinMax(false), framebufferBlit(false), framebufferMultisample(false), @@ -135,10 +184,9 @@ Extensions::Extensions() packReverseRowOrder(false), standardDerivatives(false), shaderTextureLOD(false), - shaderFramebufferFetch(false), - ARMshaderFramebufferFetch(false), - NVshaderFramebufferFetch(false), fragDepth(false), + multiview(false), + maxViews(1u), textureUsage(false), translatedShaderSource(false), fboRenderMipmap(false), @@ -147,6 +195,7 @@ Extensions::Extensions() eglImage(false), eglImageExternal(false), eglImageExternalEssl3(false), + eglStreamConsumerExternal(false), unpackSubimage(false), packSubimage(false), vertexArrayObject(false), @@ -157,7 +206,31 @@ Extensions::Extensions() maxLabelLength(0), noError(false), lossyETCDecode(false), - colorBufferFloat(false) + bindUniformLocation(false), + syncQuery(false), + copyTexture(false), + copyCompressedTexture(false), + webglCompatibility(false), + requestExtension(false), + bindGeneratesResource(false), + robustClientMemory(false), + textureSRGBDecode(false), + sRGBWriteControl(false), + colorBufferFloatRGB(false), + colorBufferFloatRGBA(false), + colorBufferFloat(false), + multisampleCompatibility(false), + framebufferMixedSamples(false), + textureNorm16(false), + pathRendering(false), + surfacelessContext(false), + clientArrays(false), + robustResourceInitialization(false), + programCacheControl(false), + textureRectangle(false), + geometryShader(false), + maxGeometryOutputVertices(0), + maxGeometryShaderInvocations(0) { } @@ -165,70 +238,13 @@ std::vector Extensions::getStrings() const { std::vector extensionStrings; - // clang-format off - // | Extension name | Supported flag | Output vector | - InsertExtensionString("GL_OES_element_index_uint", elementIndexUint, &extensionStrings); - InsertExtensionString("GL_OES_packed_depth_stencil", packedDepthStencil, &extensionStrings); - InsertExtensionString("GL_OES_get_program_binary", getProgramBinary, &extensionStrings); - InsertExtensionString("GL_OES_rgb8_rgba8", rgb8rgba8, &extensionStrings); - InsertExtensionString("GL_EXT_texture_format_BGRA8888", textureFormatBGRA8888, &extensionStrings); - InsertExtensionString("GL_EXT_read_format_bgra", readFormatBGRA, &extensionStrings); - InsertExtensionString("GL_NV_pixel_buffer_object", pixelBufferObject, &extensionStrings); - InsertExtensionString("GL_OES_mapbuffer", mapBuffer, &extensionStrings); - InsertExtensionString("GL_EXT_map_buffer_range", mapBufferRange, &extensionStrings); - InsertExtensionString("GL_EXT_color_buffer_half_float", colorBufferHalfFloat, &extensionStrings); - InsertExtensionString("GL_OES_texture_half_float", textureHalfFloat, &extensionStrings); - InsertExtensionString("GL_OES_texture_half_float_linear", textureHalfFloatLinear, &extensionStrings); - InsertExtensionString("GL_OES_texture_float", textureFloat, &extensionStrings); - InsertExtensionString("GL_OES_texture_float_linear", textureFloatLinear, &extensionStrings); - InsertExtensionString("GL_EXT_texture_rg", textureRG, &extensionStrings); - InsertExtensionString("GL_EXT_texture_compression_dxt1", textureCompressionDXT1, &extensionStrings); - InsertExtensionString("GL_ANGLE_texture_compression_dxt3", textureCompressionDXT3, &extensionStrings); - InsertExtensionString("GL_ANGLE_texture_compression_dxt5", textureCompressionDXT5, &extensionStrings); - InsertExtensionString("GL_KHR_texture_compression_astc_hdr", textureCompressionASTCHDR, &extensionStrings); - InsertExtensionString("GL_KHR_texture_compression_astc_ldr", textureCompressionASTCLDR, &extensionStrings); - InsertExtensionString("GL_OES_compressed_ETC1_RGB8_texture", compressedETC1RGB8Texture, &extensionStrings); - InsertExtensionString("GL_EXT_sRGB", sRGB, &extensionStrings); - InsertExtensionString("GL_ANGLE_depth_texture", depthTextures, &extensionStrings); - InsertExtensionString("GL_OES_depth32", depth32, &extensionStrings); - InsertExtensionString("GL_EXT_texture_storage", textureStorage, &extensionStrings); - InsertExtensionString("GL_OES_texture_npot", textureNPOT, &extensionStrings); - InsertExtensionString("GL_EXT_draw_buffers", drawBuffers, &extensionStrings); - InsertExtensionString("GL_EXT_texture_filter_anisotropic", textureFilterAnisotropic, &extensionStrings); - InsertExtensionString("GL_EXT_occlusion_query_boolean", occlusionQueryBoolean, &extensionStrings); - InsertExtensionString("GL_NV_fence", fence, &extensionStrings); - InsertExtensionString("GL_ANGLE_timer_query", timerQuery, &extensionStrings); - InsertExtensionString("GL_EXT_disjoint_timer_query", disjointTimerQuery, &extensionStrings); - InsertExtensionString("GL_EXT_robustness", robustness, &extensionStrings); - InsertExtensionString("GL_EXT_blend_minmax", blendMinMax, &extensionStrings); - InsertExtensionString("GL_ANGLE_framebuffer_blit", framebufferBlit, &extensionStrings); - InsertExtensionString("GL_ANGLE_framebuffer_multisample", framebufferMultisample, &extensionStrings); - InsertExtensionString("GL_ANGLE_instanced_arrays", instancedArrays, &extensionStrings); - InsertExtensionString("GL_ANGLE_pack_reverse_row_order", packReverseRowOrder, &extensionStrings); - InsertExtensionString("GL_OES_standard_derivatives", standardDerivatives, &extensionStrings); - InsertExtensionString("GL_EXT_shader_texture_lod", shaderTextureLOD, &extensionStrings); - InsertExtensionString("GL_NV_shader_framebuffer_fetch", NVshaderFramebufferFetch, &extensionStrings); - InsertExtensionString("GL_ARM_shader_framebuffer_fetch", ARMshaderFramebufferFetch, &extensionStrings); - InsertExtensionString("GL_EXT_shader_framebuffer_fetch", shaderFramebufferFetch, &extensionStrings); - InsertExtensionString("GL_EXT_frag_depth", fragDepth, &extensionStrings); - InsertExtensionString("GL_ANGLE_texture_usage", textureUsage, &extensionStrings); - InsertExtensionString("GL_ANGLE_translated_shader_source", translatedShaderSource, &extensionStrings); - InsertExtensionString("GL_OES_fbo_render_mipmap", fboRenderMipmap, &extensionStrings); - InsertExtensionString("GL_EXT_discard_framebuffer", discardFramebuffer, &extensionStrings); - InsertExtensionString("GL_EXT_debug_marker", debugMarker, &extensionStrings); - InsertExtensionString("GL_OES_EGL_image", eglImage, &extensionStrings); - InsertExtensionString("GL_OES_EGL_image_external", eglImageExternal, &extensionStrings); - InsertExtensionString("GL_OES_EGL_image_external_essl3", eglImageExternalEssl3, &extensionStrings); - InsertExtensionString("GL_EXT_unpack_subimage", unpackSubimage, &extensionStrings); - InsertExtensionString("GL_NV_pack_subimage", packSubimage, &extensionStrings); - InsertExtensionString("GL_EXT_color_buffer_float", colorBufferFloat, &extensionStrings); - InsertExtensionString("GL_OES_vertex_array_object", vertexArrayObject, &extensionStrings); - InsertExtensionString("GL_KHR_debug", debug, &extensionStrings); - // TODO(jmadill): Enable this when complete. - //InsertExtensionString("GL_KHR_no_error", noError, &extensionStrings); - - InsertExtensionString("GL_ANGLE_lossy_etc_decode", lossyETCDecode, &extensionStrings); - // clang-format on + for (const auto &extensionInfo : GetExtensionInfoMap()) + { + if (this->*(extensionInfo.second.ExtensionsMember)) + { + extensionStrings.push_back(extensionInfo.first); + } + } return extensionStrings; } @@ -243,10 +259,14 @@ Limitations::Limitations() { } -static bool GetFormatSupport(const TextureCapsMap &textureCaps, const std::vector &requiredFormats, - bool requiresTexturing, bool requiresFiltering, bool requiresRendering) +static bool GetFormatSupportBase(const TextureCapsMap &textureCaps, + const GLenum *requiredFormats, + size_t requiredFormatsSize, + bool requiresTexturing, + bool requiresFiltering, + bool requiresRendering) { - for (size_t i = 0; i < requiredFormats.size(); i++) + for (size_t i = 0; i < requiredFormatsSize; i++) { const TextureCaps &cap = textureCaps.get(requiredFormats[i]); @@ -269,11 +289,23 @@ static bool GetFormatSupport(const TextureCapsMap &textureCaps, const std::vecto return true; } +template +static bool GetFormatSupport(const TextureCapsMap &textureCaps, + const GLenum (&requiredFormats)[N], + bool requiresTexturing, + bool requiresFiltering, + bool requiresRendering) +{ + return GetFormatSupportBase(textureCaps, requiredFormats, N, requiresTexturing, + requiresFiltering, requiresRendering); +} + // Check for GL_OES_packed_depth_stencil static bool DeterminePackedDepthStencilSupport(const TextureCapsMap &textureCaps) { - std::vector requiredFormats; - requiredFormats.push_back(GL_DEPTH24_STENCIL8); + constexpr GLenum requiredFormats[] = { + GL_DEPTH24_STENCIL8, + }; return GetFormatSupport(textureCaps, requiredFormats, false, false, true); } @@ -281,9 +313,9 @@ static bool DeterminePackedDepthStencilSupport(const TextureCapsMap &textureCaps // Checks for GL_OES_rgb8_rgba8 support static bool DetermineRGB8AndRGBA8TextureSupport(const TextureCapsMap &textureCaps) { - std::vector requiredFormats; - requiredFormats.push_back(GL_RGB8); - requiredFormats.push_back(GL_RGBA8); + constexpr GLenum requiredFormats[] = { + GL_RGB8, GL_RGBA8, + }; return GetFormatSupport(textureCaps, requiredFormats, true, true, true); } @@ -291,8 +323,9 @@ static bool DetermineRGB8AndRGBA8TextureSupport(const TextureCapsMap &textureCap // Checks for GL_EXT_texture_format_BGRA8888 support static bool DetermineBGRA8TextureSupport(const TextureCapsMap &textureCaps) { - std::vector requiredFormats; - requiredFormats.push_back(GL_BGRA8_EXT); + constexpr GLenum requiredFormats[] = { + GL_BGRA8_EXT, + }; return GetFormatSupport(textureCaps, requiredFormats, true, true, true); } @@ -300,11 +333,9 @@ static bool DetermineBGRA8TextureSupport(const TextureCapsMap &textureCaps) // Checks for GL_OES_color_buffer_half_float support static bool DetermineColorBufferHalfFloatSupport(const TextureCapsMap &textureCaps) { - std::vector requiredFormats; - requiredFormats.push_back(GL_RGBA16F); - requiredFormats.push_back(GL_RGB16F); - requiredFormats.push_back(GL_RG16F); - requiredFormats.push_back(GL_R16F); + constexpr GLenum requiredFormats[] = { + GL_RGBA16F, GL_RGB16F, GL_RG16F, GL_R16F, + }; return GetFormatSupport(textureCaps, requiredFormats, true, false, true); } @@ -312,19 +343,19 @@ static bool DetermineColorBufferHalfFloatSupport(const TextureCapsMap &textureCa // Checks for GL_OES_texture_half_float support static bool DetermineHalfFloatTextureSupport(const TextureCapsMap &textureCaps) { - std::vector requiredFormats; - requiredFormats.push_back(GL_RGB16F); - requiredFormats.push_back(GL_RGBA16F); + constexpr GLenum requiredFormats[] = { + GL_RGB16F, GL_RGBA16F, + }; - return GetFormatSupport(textureCaps, requiredFormats, true, false, true); + return GetFormatSupport(textureCaps, requiredFormats, true, false, false); } // Checks for GL_OES_texture_half_float_linear support static bool DetermineHalfFloatTextureFilteringSupport(const TextureCapsMap &textureCaps) { - std::vector requiredFormats; - requiredFormats.push_back(GL_RGB16F); - requiredFormats.push_back(GL_RGBA16F); + constexpr GLenum requiredFormats[] = { + GL_RGB16F, GL_RGBA16F, + }; return DetermineHalfFloatTextureSupport(textureCaps) && GetFormatSupport(textureCaps, requiredFormats, true, true, false); @@ -333,50 +364,65 @@ static bool DetermineHalfFloatTextureFilteringSupport(const TextureCapsMap &text // Checks for GL_OES_texture_float support static bool DetermineFloatTextureSupport(const TextureCapsMap &textureCaps) { - std::vector requiredFormats; - requiredFormats.push_back(GL_RGB32F); - requiredFormats.push_back(GL_RGBA32F); + constexpr GLenum requiredFormats[] = { + GL_RGB32F, GL_RGBA32F, + }; - return GetFormatSupport(textureCaps, requiredFormats, true, false, true); + return GetFormatSupport(textureCaps, requiredFormats, true, false, false); } // Checks for GL_OES_texture_float_linear support static bool DetermineFloatTextureFilteringSupport(const TextureCapsMap &textureCaps) { - std::vector requiredFormats; - requiredFormats.push_back(GL_RGB32F); - requiredFormats.push_back(GL_RGBA32F); + constexpr GLenum requiredFormats[] = { + GL_RGB32F, GL_RGBA32F, + }; return DetermineFloatTextureSupport(textureCaps) && GetFormatSupport(textureCaps, requiredFormats, true, true, false); } // Checks for GL_EXT_texture_rg support +static bool DetermineRGHalfFloatTextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_R16F, GL_RG16F, + }; + return GetFormatSupport(textureCaps, requiredFormats, true, true, false); +} + +static bool DetermineRGFloatTextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_R32F, GL_RG32F, + }; + return GetFormatSupport(textureCaps, requiredFormats, true, true, false); +} + static bool DetermineRGTextureSupport(const TextureCapsMap &textureCaps, bool checkHalfFloatFormats, bool checkFloatFormats) { - std::vector requiredFormats; - requiredFormats.push_back(GL_R8); - requiredFormats.push_back(GL_RG8); - if (checkHalfFloatFormats) + if (checkHalfFloatFormats && !DetermineRGHalfFloatTextureSupport(textureCaps)) { - requiredFormats.push_back(GL_R16F); - requiredFormats.push_back(GL_RG16F); - } - if (checkFloatFormats) - { - requiredFormats.push_back(GL_R32F); - requiredFormats.push_back(GL_RG32F); + return false; } + if (checkFloatFormats && !DetermineRGFloatTextureSupport(textureCaps)) + { + return false; + } + + constexpr GLenum requiredFormats[] = { + GL_R8, GL_RG8, + }; return GetFormatSupport(textureCaps, requiredFormats, true, true, false); } // Check for GL_EXT_texture_compression_dxt1 static bool DetermineDXT1TextureSupport(const TextureCapsMap &textureCaps) { - std::vector requiredFormats; - requiredFormats.push_back(GL_COMPRESSED_RGB_S3TC_DXT1_EXT); - requiredFormats.push_back(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT); + constexpr GLenum requiredFormats[] = { + GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, + }; return GetFormatSupport(textureCaps, requiredFormats, true, true, false); } @@ -384,8 +430,9 @@ static bool DetermineDXT1TextureSupport(const TextureCapsMap &textureCaps) // Check for GL_ANGLE_texture_compression_dxt3 static bool DetermineDXT3TextureSupport(const TextureCapsMap &textureCaps) { - std::vector requiredFormats; - requiredFormats.push_back(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE); + constexpr GLenum requiredFormats[] = { + GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, + }; return GetFormatSupport(textureCaps, requiredFormats, true, true, false); } @@ -393,8 +440,20 @@ static bool DetermineDXT3TextureSupport(const TextureCapsMap &textureCaps) // Check for GL_ANGLE_texture_compression_dxt5 static bool DetermineDXT5TextureSupport(const TextureCapsMap &textureCaps) { - std::vector requiredFormats; - requiredFormats.push_back(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE); + constexpr GLenum requiredFormats[] = { + GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, true, false); +} + +// Check for GL_EXT_texture_compression_s3tc_srgb +static bool DetermineS3TCsRGBTextureSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, + GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, + }; return GetFormatSupport(textureCaps, requiredFormats, true, true, false); } @@ -402,35 +461,22 @@ static bool DetermineDXT5TextureSupport(const TextureCapsMap &textureCaps) // Check for GL_KHR_texture_compression_astc_hdr and GL_KHR_texture_compression_astc_ldr static bool DetermineASTCTextureSupport(const TextureCapsMap &textureCaps) { - std::vector requiredFormats; - requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_4x4_KHR); - requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_5x4_KHR); - requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_5x5_KHR); - requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_6x5_KHR); - requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_6x6_KHR); - requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_8x5_KHR); - requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_8x6_KHR); - requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_8x8_KHR); - requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_10x5_KHR); - requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_10x6_KHR); - requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_10x8_KHR); - requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_10x10_KHR); - requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_12x10_KHR); - requiredFormats.push_back(GL_COMPRESSED_RGBA_ASTC_12x12_KHR); - requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR); - requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR); - requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR); - requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR); - requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR); - requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR); - requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR); - requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR); - requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR); - requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR); - requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR); - requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR); - requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR); - requiredFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR); + constexpr GLenum requiredFormats[] = { + GL_COMPRESSED_RGBA_ASTC_4x4_KHR, GL_COMPRESSED_RGBA_ASTC_5x4_KHR, + GL_COMPRESSED_RGBA_ASTC_5x5_KHR, GL_COMPRESSED_RGBA_ASTC_6x5_KHR, + GL_COMPRESSED_RGBA_ASTC_6x6_KHR, GL_COMPRESSED_RGBA_ASTC_8x5_KHR, + GL_COMPRESSED_RGBA_ASTC_8x6_KHR, GL_COMPRESSED_RGBA_ASTC_8x8_KHR, + GL_COMPRESSED_RGBA_ASTC_10x5_KHR, GL_COMPRESSED_RGBA_ASTC_10x6_KHR, + GL_COMPRESSED_RGBA_ASTC_10x8_KHR, GL_COMPRESSED_RGBA_ASTC_10x10_KHR, + GL_COMPRESSED_RGBA_ASTC_12x10_KHR, GL_COMPRESSED_RGBA_ASTC_12x12_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, + GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, + }; return GetFormatSupport(textureCaps, requiredFormats, true, true, false); } @@ -438,8 +484,9 @@ static bool DetermineASTCTextureSupport(const TextureCapsMap &textureCaps) // Check for GL_ETC1_RGB8_OES static bool DetermineETC1RGB8TextureSupport(const TextureCapsMap &textureCaps) { - std::vector requiredFormats; - requiredFormats.push_back(GL_ETC1_RGB8_OES); + constexpr GLenum requiredFormats[] = { + GL_ETC1_RGB8_OES, + }; return GetFormatSupport(textureCaps, requiredFormats, true, true, false); } @@ -447,12 +494,13 @@ static bool DetermineETC1RGB8TextureSupport(const TextureCapsMap &textureCaps) // Check for GL_ANGLE_texture_compression_dxt5 static bool DetermineSRGBTextureSupport(const TextureCapsMap &textureCaps) { - std::vector requiredFilterFormats; - requiredFilterFormats.push_back(GL_SRGB8); - requiredFilterFormats.push_back(GL_SRGB8_ALPHA8); + constexpr GLenum requiredFilterFormats[] = { + GL_SRGB8, GL_SRGB8_ALPHA8, + }; - std::vector requiredRenderFormats; - requiredRenderFormats.push_back(GL_SRGB8_ALPHA8); + constexpr GLenum requiredRenderFormats[] = { + GL_SRGB8_ALPHA8, + }; return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false) && GetFormatSupport(textureCaps, requiredRenderFormats, true, false, true); @@ -461,10 +509,9 @@ static bool DetermineSRGBTextureSupport(const TextureCapsMap &textureCaps) // Check for GL_ANGLE_depth_texture static bool DetermineDepthTextureSupport(const TextureCapsMap &textureCaps) { - std::vector requiredFormats; - requiredFormats.push_back(GL_DEPTH_COMPONENT16); - requiredFormats.push_back(GL_DEPTH_COMPONENT32_OES); - requiredFormats.push_back(GL_DEPTH24_STENCIL8_OES); + constexpr GLenum requiredFormats[] = { + GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT32_OES, GL_DEPTH24_STENCIL8_OES, + }; return GetFormatSupport(textureCaps, requiredFormats, true, true, true); } @@ -472,27 +519,59 @@ static bool DetermineDepthTextureSupport(const TextureCapsMap &textureCaps) // Check for GL_OES_depth32 static bool DetermineDepth32Support(const TextureCapsMap &textureCaps) { - std::vector requiredFormats; - requiredFormats.push_back(GL_DEPTH_COMPONENT32_OES); + constexpr GLenum requiredFormats[] = { + GL_DEPTH_COMPONENT32_OES, + }; return GetFormatSupport(textureCaps, requiredFormats, false, false, true); } +// Check for GL_CHROMIUM_color_buffer_float_rgb +static bool DetermineColorBufferFloatRGBSupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_RGB32F, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, false, true); +} + +// Check for GL_CHROMIUM_color_buffer_float_rgba +static bool DetermineColorBufferFloatRGBASupport(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFormats[] = { + GL_RGBA32F, + }; + + return GetFormatSupport(textureCaps, requiredFormats, true, false, true); +} + // Check for GL_EXT_color_buffer_float static bool DetermineColorBufferFloatSupport(const TextureCapsMap &textureCaps) { - std::vector requiredFormats; - requiredFormats.push_back(GL_R16F); - requiredFormats.push_back(GL_RG16F); - requiredFormats.push_back(GL_RGBA16F); - requiredFormats.push_back(GL_R32F); - requiredFormats.push_back(GL_RG32F); - requiredFormats.push_back(GL_RGBA32F); - requiredFormats.push_back(GL_R11F_G11F_B10F); + constexpr GLenum requiredFormats[] = { + GL_R16F, GL_RG16F, GL_RGBA16F, GL_R32F, GL_RG32F, GL_RGBA32F, GL_R11F_G11F_B10F, + }; return GetFormatSupport(textureCaps, requiredFormats, true, false, true); } +// Check for GL_EXT_texture_norm16 +static bool DetermineTextureNorm16Support(const TextureCapsMap &textureCaps) +{ + constexpr GLenum requiredFilterFormats[] = { + GL_R16_EXT, GL_RG16_EXT, GL_RGB16_EXT, GL_RGBA16_EXT, + GL_R16_SNORM_EXT, GL_RG16_SNORM_EXT, GL_RGB16_SNORM_EXT, GL_RGBA16_SNORM_EXT, + }; + + constexpr GLenum requiredRenderFormats[] = { + GL_R16_EXT, GL_RG16_EXT, GL_RGBA16_EXT, + }; + + return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false) && + GetFormatSupport(textureCaps, requiredRenderFormats, true, false, true); +} + void Extensions::setTextureExtensionSupport(const TextureCapsMap &textureCaps) { packedDepthStencil = DeterminePackedDepthStencilSupport(textureCaps); @@ -507,47 +586,161 @@ void Extensions::setTextureExtensionSupport(const TextureCapsMap &textureCaps) textureCompressionDXT1 = DetermineDXT1TextureSupport(textureCaps); textureCompressionDXT3 = DetermineDXT3TextureSupport(textureCaps); textureCompressionDXT5 = DetermineDXT5TextureSupport(textureCaps); + textureCompressionS3TCsRGB = DetermineS3TCsRGBTextureSupport(textureCaps); textureCompressionASTCHDR = DetermineASTCTextureSupport(textureCaps); textureCompressionASTCLDR = textureCompressionASTCHDR; compressedETC1RGB8Texture = DetermineETC1RGB8TextureSupport(textureCaps); sRGB = DetermineSRGBTextureSupport(textureCaps); depthTextures = DetermineDepthTextureSupport(textureCaps); depth32 = DetermineDepth32Support(textureCaps); + colorBufferFloatRGB = DetermineColorBufferFloatRGBSupport(textureCaps); + colorBufferFloatRGBA = DetermineColorBufferFloatRGBASupport(textureCaps); colorBufferFloat = DetermineColorBufferFloatSupport(textureCaps); + textureNorm16 = DetermineTextureNorm16Support(textureCaps); } -TypePrecision::TypePrecision() +const ExtensionInfoMap &GetExtensionInfoMap() { - range[0] = 0; - range[1] = 0; - precision = 0; + auto buildExtensionInfoMap = []() { + auto enableableExtension = [](ExtensionInfo::ExtensionBool member) { + ExtensionInfo info; + info.Requestable = true; + info.ExtensionsMember = member; + return info; + }; + + auto esOnlyExtension = [](ExtensionInfo::ExtensionBool member) { + ExtensionInfo info; + info.ExtensionsMember = member; + return info; + }; + + // clang-format off + ExtensionInfoMap map; + map["GL_OES_element_index_uint"] = enableableExtension(&Extensions::elementIndexUint); + map["GL_OES_packed_depth_stencil"] = esOnlyExtension(&Extensions::packedDepthStencil); + map["GL_OES_get_program_binary"] = enableableExtension(&Extensions::getProgramBinary); + map["GL_OES_rgb8_rgba8"] = enableableExtension(&Extensions::rgb8rgba8); + map["GL_EXT_texture_format_BGRA8888"] = enableableExtension(&Extensions::textureFormatBGRA8888); + map["GL_EXT_read_format_bgra"] = esOnlyExtension(&Extensions::readFormatBGRA); + map["GL_NV_pixel_buffer_object"] = enableableExtension(&Extensions::pixelBufferObject); + map["GL_OES_mapbuffer"] = enableableExtension(&Extensions::mapBuffer); + map["GL_EXT_map_buffer_range"] = enableableExtension(&Extensions::mapBufferRange); + map["GL_EXT_color_buffer_half_float"] = enableableExtension(&Extensions::colorBufferHalfFloat); + map["GL_OES_texture_half_float"] = enableableExtension(&Extensions::textureHalfFloat); + map["GL_OES_texture_half_float_linear"] = enableableExtension(&Extensions::textureHalfFloatLinear); + map["GL_OES_texture_float"] = enableableExtension(&Extensions::textureFloat); + map["GL_OES_texture_float_linear"] = enableableExtension(&Extensions::textureFloatLinear); + map["GL_EXT_texture_rg"] = enableableExtension(&Extensions::textureRG); + map["GL_EXT_texture_compression_dxt1"] = enableableExtension(&Extensions::textureCompressionDXT1); + map["GL_ANGLE_texture_compression_dxt3"] = enableableExtension(&Extensions::textureCompressionDXT3); + map["GL_ANGLE_texture_compression_dxt5"] = enableableExtension(&Extensions::textureCompressionDXT5); + map["GL_EXT_texture_compression_s3tc_srgb"] = enableableExtension(&Extensions::textureCompressionS3TCsRGB); + map["GL_KHR_texture_compression_astc_hdr"] = enableableExtension(&Extensions::textureCompressionASTCHDR); + map["GL_KHR_texture_compression_astc_ldr"] = enableableExtension(&Extensions::textureCompressionASTCLDR); + map["GL_OES_compressed_ETC1_RGB8_texture"] = enableableExtension(&Extensions::compressedETC1RGB8Texture); + map["GL_EXT_sRGB"] = enableableExtension(&Extensions::sRGB); + map["GL_ANGLE_depth_texture"] = esOnlyExtension(&Extensions::depthTextures); + map["GL_OES_depth32"] = esOnlyExtension(&Extensions::depth32); + map["GL_EXT_texture_storage"] = esOnlyExtension(&Extensions::textureStorage); + map["GL_OES_texture_npot"] = enableableExtension(&Extensions::textureNPOT); + map["GL_EXT_draw_buffers"] = enableableExtension(&Extensions::drawBuffers); + map["GL_EXT_texture_filter_anisotropic"] = enableableExtension(&Extensions::textureFilterAnisotropic); + map["GL_EXT_occlusion_query_boolean"] = enableableExtension(&Extensions::occlusionQueryBoolean); + map["GL_NV_fence"] = esOnlyExtension(&Extensions::fence); + map["GL_EXT_disjoint_timer_query"] = enableableExtension(&Extensions::disjointTimerQuery); + map["GL_EXT_robustness"] = esOnlyExtension(&Extensions::robustness); + map["GL_KHR_robust_buffer_access_behavior"] = esOnlyExtension(&Extensions::robustBufferAccessBehavior); + map["GL_EXT_blend_minmax"] = enableableExtension(&Extensions::blendMinMax); + map["GL_ANGLE_framebuffer_blit"] = enableableExtension(&Extensions::framebufferBlit); + map["GL_ANGLE_framebuffer_multisample"] = enableableExtension(&Extensions::framebufferMultisample); + map["GL_ANGLE_instanced_arrays"] = enableableExtension(&Extensions::instancedArrays); + map["GL_ANGLE_pack_reverse_row_order"] = enableableExtension(&Extensions::packReverseRowOrder); + map["GL_OES_standard_derivatives"] = enableableExtension(&Extensions::standardDerivatives); + map["GL_EXT_shader_texture_lod"] = enableableExtension(&Extensions::shaderTextureLOD); + map["GL_EXT_frag_depth"] = enableableExtension(&Extensions::fragDepth); + map["GL_ANGLE_multiview"] = enableableExtension(&Extensions::multiview); + map["GL_ANGLE_texture_usage"] = enableableExtension(&Extensions::textureUsage); + map["GL_ANGLE_translated_shader_source"] = esOnlyExtension(&Extensions::translatedShaderSource); + map["GL_OES_fbo_render_mipmap"] = enableableExtension(&Extensions::fboRenderMipmap); + map["GL_EXT_discard_framebuffer"] = esOnlyExtension(&Extensions::discardFramebuffer); + map["GL_EXT_debug_marker"] = esOnlyExtension(&Extensions::debugMarker); + map["GL_OES_EGL_image"] = esOnlyExtension(&Extensions::eglImage); + map["GL_OES_EGL_image_external"] = esOnlyExtension(&Extensions::eglImageExternal); + map["GL_OES_EGL_image_external_essl3"] = esOnlyExtension(&Extensions::eglImageExternalEssl3); + map["GL_NV_EGL_stream_consumer_external"] = esOnlyExtension(&Extensions::eglStreamConsumerExternal); + map["GL_EXT_unpack_subimage"] = enableableExtension(&Extensions::unpackSubimage); + map["GL_NV_pack_subimage"] = enableableExtension(&Extensions::packSubimage); + map["GL_EXT_color_buffer_float"] = enableableExtension(&Extensions::colorBufferFloat); + map["GL_OES_vertex_array_object"] = esOnlyExtension(&Extensions::vertexArrayObject); + map["GL_KHR_debug"] = esOnlyExtension(&Extensions::debug); + // TODO(jmadill): Enable this when complete. + //map["GL_KHR_no_error"] = esOnlyExtension(&Extensions::noError); + map["GL_ANGLE_lossy_etc_decode"] = enableableExtension(&Extensions::lossyETCDecode); + map["GL_CHROMIUM_bind_uniform_location"] = esOnlyExtension(&Extensions::bindUniformLocation); + map["GL_CHROMIUM_sync_query"] = enableableExtension(&Extensions::syncQuery); + map["GL_CHROMIUM_copy_texture"] = esOnlyExtension(&Extensions::copyTexture); + map["GL_CHROMIUM_copy_compressed_texture"] = esOnlyExtension(&Extensions::copyCompressedTexture); + map["GL_ANGLE_webgl_compatibility"] = esOnlyExtension(&Extensions::webglCompatibility); + map["GL_ANGLE_request_extension"] = esOnlyExtension(&Extensions::requestExtension); + map["GL_CHROMIUM_bind_generates_resource"] = esOnlyExtension(&Extensions::bindGeneratesResource); + map["GL_ANGLE_robust_client_memory"] = esOnlyExtension(&Extensions::robustClientMemory); + map["GL_EXT_texture_sRGB_decode"] = esOnlyExtension(&Extensions::textureSRGBDecode); + map["GL_EXT_sRGB_write_control"] = esOnlyExtension(&Extensions::sRGBWriteControl); + map["GL_CHROMIUM_color_buffer_float_rgb"] = enableableExtension(&Extensions::colorBufferFloatRGB); + map["GL_CHROMIUM_color_buffer_float_rgba"] = enableableExtension(&Extensions::colorBufferFloatRGBA); + map["GL_EXT_multisample_compatibility"] = esOnlyExtension(&Extensions::multisampleCompatibility); + map["GL_CHROMIUM_framebuffer_mixed_samples"] = esOnlyExtension(&Extensions::framebufferMixedSamples); + map["GL_EXT_texture_norm16"] = esOnlyExtension(&Extensions::textureNorm16); + map["GL_CHROMIUM_path_rendering"] = esOnlyExtension(&Extensions::pathRendering); + map["GL_OES_surfaceless_context"] = esOnlyExtension(&Extensions::surfacelessContext); + map["GL_ANGLE_client_arrays"] = esOnlyExtension(&Extensions::clientArrays); + map["GL_ANGLE_robust_resource_initialization"] = esOnlyExtension(&Extensions::robustResourceInitialization); + map["GL_ANGLE_program_cache_control"] = esOnlyExtension(&Extensions::programCacheControl); + map["GL_ANGLE_texture_rectangle"] = enableableExtension(&Extensions::textureRectangle); + map["GL_EXT_geometry_shader"] = enableableExtension(&Extensions::geometryShader); + // clang-format on + + return map; + }; + + static const ExtensionInfoMap extensionInfo = buildExtensionInfoMap(); + return extensionInfo; } +TypePrecision::TypePrecision() : range({{0, 0}}), precision(0) +{ +} + +TypePrecision::TypePrecision(const TypePrecision &other) = default; + void TypePrecision::setIEEEFloat() { - range[0] = 127; - range[1] = 127; + range = {{127, 127}}; precision = 23; } void TypePrecision::setTwosComplementInt(unsigned int bits) { - range[0] = GLint(bits) - 1; - range[1] = GLint(bits) - 2; + range = {{static_cast(bits) - 1, static_cast(bits) - 2}}; precision = 0; } +void TypePrecision::setSimulatedFloat(unsigned int r, unsigned int p) +{ + range = {{static_cast(r), static_cast(r)}}; + precision = static_cast(p); +} + void TypePrecision::setSimulatedInt(unsigned int r) { - range[0] = GLint(r); - range[1] = GLint(r); + range = {{static_cast(r), static_cast(r)}}; precision = 0; } void TypePrecision::get(GLint *returnRange, GLint *returnPrecision) const { - returnRange[0] = range[0]; - returnRange[1] = range[1]; + std::copy(range.begin(), range.end(), returnRange); *returnPrecision = precision; } @@ -555,37 +748,77 @@ Caps::Caps() : maxElementIndex(0), max3DTextureSize(0), max2DTextureSize(0), + maxRectangleTextureSize(0), maxArrayTextureLayers(0), maxLODBias(0), maxCubeMapTextureSize(0), maxRenderbufferSize(0), - maxDrawBuffers(0), - maxColorAttachments(0), - maxViewportWidth(0), - maxViewportHeight(0), minAliasedPointSize(0), maxAliasedPointSize(0), minAliasedLineWidth(0), - // Table 6.29 + maxAliasedLineWidth(0), + + // Table 20.40 + maxDrawBuffers(0), + maxFramebufferWidth(0), + maxFramebufferHeight(0), + maxFramebufferSamples(0), + maxColorAttachments(0), + maxViewportWidth(0), + maxViewportHeight(0), + maxSampleMaskWords(0), + maxColorTextureSamples(0), + maxDepthTextureSamples(0), + maxIntegerSamples(0), + maxServerWaitTimeout(0), + + // Table 20.41 + maxVertexAttribRelativeOffset(0), + maxVertexAttribBindings(0), + maxVertexAttribStride(0), maxElementsIndices(0), maxElementsVertices(0), - maxServerWaitTimeout(0), - // Table 6.31 + + // Table 20.43 maxVertexAttributes(0), maxVertexUniformComponents(0), maxVertexUniformVectors(0), maxVertexUniformBlocks(0), maxVertexOutputComponents(0), maxVertexTextureImageUnits(0), - // Table 6.32 + maxVertexAtomicCounterBuffers(0), + maxVertexAtomicCounters(0), + maxVertexImageUniforms(0), + maxVertexShaderStorageBlocks(0), + + // Table 20.44 maxFragmentUniformComponents(0), maxFragmentUniformVectors(0), maxFragmentUniformBlocks(0), maxFragmentInputComponents(0), maxTextureImageUnits(0), + maxFragmentAtomicCounterBuffers(0), + maxFragmentAtomicCounters(0), + maxFragmentImageUniforms(0), + maxFragmentShaderStorageBlocks(0), + minProgramTextureGatherOffset(0), + maxProgramTextureGatherOffset(0), minProgramTexelOffset(0), maxProgramTexelOffset(0), - // Table 6.33 + + // Table 20.45 + maxComputeWorkGroupInvocations(0), + maxComputeUniformBlocks(0), + maxComputeTextureImageUnits(0), + maxComputeSharedMemorySize(0), + maxComputeUniformComponents(0), + maxComputeAtomicCounterBuffers(0), + maxComputeAtomicCounters(0), + maxComputeImageUniforms(0), + maxCombinedComputeUniformComponents(0), + maxComputeShaderStorageBlocks(0), + + // Table 20.46 maxUniformBufferBindings(0), maxUniformBlockSize(0), uniformBufferOffsetAlignment(0), @@ -595,15 +828,233 @@ Caps::Caps() maxVaryingComponents(0), maxVaryingVectors(0), maxCombinedTextureImageUnits(0), - // Table 6.34 + maxCombinedShaderOutputResources(0), + + // Table 20.47 + maxUniformLocations(0), + maxAtomicCounterBufferBindings(0), + maxAtomicCounterBufferSize(0), + maxCombinedAtomicCounterBuffers(0), + maxCombinedAtomicCounters(0), + maxImageUnits(0), + maxCombinedImageUniforms(0), + maxShaderStorageBufferBindings(0), + maxShaderStorageBlockSize(0), + maxCombinedShaderStorageBlocks(0), + shaderStorageBufferOffsetAlignment(0), + + // Table 20.48 maxTransformFeedbackInterleavedComponents(0), maxTransformFeedbackSeparateAttributes(0), maxTransformFeedbackSeparateComponents(0), - // Table 6.35 + + // Table 20.49 maxSamples(0) { + for (size_t i = 0; i < 3; ++i) + { + maxComputeWorkGroupCount[i] = 0; + maxComputeWorkGroupSize[i] = 0; + } } +Caps::Caps(const Caps &other) = default; +Caps::~Caps() = default; + +Caps GenerateMinimumCaps(const Version &clientVersion, const Extensions &extensions) +{ + Caps caps; + + if (clientVersion >= Version(2, 0)) + { + // Table 6.18 + caps.max2DTextureSize = 64; + caps.maxCubeMapTextureSize = 16; + caps.maxViewportWidth = caps.max2DTextureSize; + caps.maxViewportHeight = caps.max2DTextureSize; + caps.minAliasedPointSize = 1; + caps.maxAliasedPointSize = 1; + caps.minAliasedLineWidth = 1; + caps.maxAliasedLineWidth = 1; + + // Table 6.19 + caps.vertexHighpFloat.setSimulatedFloat(62, 16); + caps.vertexMediumpFloat.setSimulatedFloat(14, 10); + caps.vertexLowpFloat.setSimulatedFloat(1, 8); + caps.vertexHighpInt.setSimulatedInt(16); + caps.vertexMediumpInt.setSimulatedInt(10); + caps.vertexLowpInt.setSimulatedInt(8); + caps.fragmentHighpFloat.setSimulatedFloat(62, 16); + caps.fragmentMediumpFloat.setSimulatedFloat(14, 10); + caps.fragmentLowpFloat.setSimulatedFloat(1, 8); + caps.fragmentHighpInt.setSimulatedInt(16); + caps.fragmentMediumpInt.setSimulatedInt(10); + caps.fragmentLowpInt.setSimulatedInt(8); + + // Table 6.20 + caps.maxVertexAttributes = 8; + caps.maxVertexUniformVectors = 128; + caps.maxVaryingVectors = 8; + caps.maxCombinedTextureImageUnits = 8; + caps.maxTextureImageUnits = 8; + caps.maxFragmentUniformVectors = 16; + caps.maxRenderbufferSize = 1; + } + + if (clientVersion >= Version(3, 0)) + { + // Table 6.28 + caps.maxElementIndex = (1 << 24) - 1; + caps.max3DTextureSize = 256; + caps.max2DTextureSize = 2048; + caps.maxArrayTextureLayers = 256; + caps.maxLODBias = 2.0f; + caps.maxCubeMapTextureSize = 2048; + caps.maxRenderbufferSize = 2048; + caps.maxDrawBuffers = 4; + caps.maxColorAttachments = 4; + caps.maxViewportWidth = caps.max2DTextureSize; + caps.maxViewportHeight = caps.max2DTextureSize; + + // Table 6.29 + caps.compressedTextureFormats.push_back(GL_COMPRESSED_R11_EAC); + caps.compressedTextureFormats.push_back(GL_COMPRESSED_SIGNED_R11_EAC); + caps.compressedTextureFormats.push_back(GL_COMPRESSED_RG11_EAC); + caps.compressedTextureFormats.push_back(GL_COMPRESSED_SIGNED_RG11_EAC); + caps.compressedTextureFormats.push_back(GL_COMPRESSED_RGB8_ETC2); + caps.compressedTextureFormats.push_back(GL_COMPRESSED_SRGB8_ETC2); + caps.compressedTextureFormats.push_back(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2); + caps.compressedTextureFormats.push_back(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2); + caps.compressedTextureFormats.push_back(GL_COMPRESSED_RGBA8_ETC2_EAC); + caps.compressedTextureFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC); + caps.vertexHighpFloat.setIEEEFloat(); + caps.vertexHighpInt.setTwosComplementInt(32); + caps.vertexMediumpInt.setTwosComplementInt(16); + caps.vertexLowpInt.setTwosComplementInt(8); + caps.fragmentHighpFloat.setIEEEFloat(); + caps.fragmentHighpInt.setSimulatedInt(32); + caps.fragmentMediumpInt.setTwosComplementInt(16); + caps.fragmentLowpInt.setTwosComplementInt(8); + caps.maxServerWaitTimeout = 0; + + // Table 6.31 + caps.maxVertexAttributes = 16; + caps.maxVertexUniformComponents = 1024; + caps.maxVertexUniformVectors = 256; + caps.maxVertexUniformBlocks = 12; + caps.maxVertexOutputComponents = 64; + caps.maxVertexTextureImageUnits = 16; + + // Table 6.32 + caps.maxFragmentUniformComponents = 896; + caps.maxFragmentUniformVectors = 224; + caps.maxFragmentUniformBlocks = 12; + caps.maxFragmentInputComponents = 60; + caps.maxTextureImageUnits = 16; + caps.minProgramTexelOffset = -8; + caps.maxProgramTexelOffset = 7; + + // Table 6.33 + caps.maxUniformBufferBindings = 24; + caps.maxUniformBlockSize = 16384; + caps.uniformBufferOffsetAlignment = 256; + caps.maxCombinedUniformBlocks = 24; + caps.maxCombinedVertexUniformComponents = + caps.maxVertexUniformBlocks * (caps.maxUniformBlockSize / 4) + + caps.maxVertexUniformComponents; + caps.maxCombinedFragmentUniformComponents = + caps.maxFragmentUniformBlocks * (caps.maxUniformBlockSize / 4) + + caps.maxFragmentUniformComponents; + caps.maxVaryingComponents = 60; + caps.maxVaryingVectors = 15; + caps.maxCombinedTextureImageUnits = 32; + + // Table 6.34 + caps.maxTransformFeedbackInterleavedComponents = 64; + caps.maxTransformFeedbackSeparateAttributes = 4; + caps.maxTransformFeedbackSeparateComponents = 4; + + // Table 3.35 + caps.maxSamples = 4; + } + + if (clientVersion >= Version(3, 1)) + { + // Table 20.40 + caps.maxFramebufferWidth = 2048; + caps.maxFramebufferHeight = 2048; + caps.maxFramebufferSamples = 4; + caps.maxSampleMaskWords = 1; + caps.maxColorTextureSamples = 1; + caps.maxDepthTextureSamples = 1; + caps.maxIntegerSamples = 1; + + // Table 20.41 + caps.maxVertexAttribRelativeOffset = 2047; + caps.maxVertexAttribBindings = 16; + caps.maxVertexAttribStride = 2048; + + // Table 20.43 + caps.maxVertexAtomicCounterBuffers = 0; + caps.maxVertexAtomicCounters = 0; + caps.maxVertexImageUniforms = 0; + caps.maxVertexShaderStorageBlocks = 0; + + // Table 20.44 + caps.maxFragmentUniformComponents = 1024; + caps.maxFragmentUniformVectors = 256; + caps.maxFragmentAtomicCounterBuffers = 0; + caps.maxFragmentAtomicCounters = 0; + caps.maxFragmentImageUniforms = 0; + caps.maxFragmentShaderStorageBlocks = 0; + caps.minProgramTextureGatherOffset = 0; + caps.maxProgramTextureGatherOffset = 0; + + // Table 20.45 + caps.maxComputeWorkGroupCount = {{65535, 65535, 65535}}; + caps.maxComputeWorkGroupSize = {{128, 128, 64}}; + caps.maxComputeWorkGroupInvocations = 12; + caps.maxComputeUniformBlocks = 12; + caps.maxComputeTextureImageUnits = 16; + caps.maxComputeSharedMemorySize = 16384; + caps.maxComputeUniformComponents = 1024; + caps.maxComputeAtomicCounterBuffers = 1; + caps.maxComputeAtomicCounters = 8; + caps.maxComputeImageUniforms = 4; + caps.maxCombinedComputeUniformComponents = + caps.maxComputeUniformBlocks * static_cast(caps.maxUniformBlockSize / 4) + + caps.maxComputeUniformComponents; + caps.maxComputeShaderStorageBlocks = 4; + + // Table 20.46 + caps.maxUniformBufferBindings = 36; + caps.maxCombinedFragmentUniformComponents = + caps.maxFragmentUniformBlocks * (caps.maxUniformBlockSize / 4) + + caps.maxFragmentUniformComponents; + caps.maxCombinedTextureImageUnits = 48; + caps.maxCombinedShaderOutputResources = 4; + + // Table 20.47 + caps.maxUniformLocations = 1024; + caps.maxAtomicCounterBufferBindings = 1; + caps.maxAtomicCounterBufferSize = 32; + caps.maxCombinedAtomicCounterBuffers = 1; + caps.maxCombinedAtomicCounters = 8; + caps.maxImageUnits = 4; + caps.maxCombinedImageUniforms = 4; + caps.maxShaderStorageBufferBindings = 4; + caps.maxShaderStorageBlockSize = 1 << 27; + caps.maxCombinedShaderStorageBlocks = 4; + caps.shaderStorageBufferOffsetAlignment = 256; + } + + if (extensions.textureRectangle) + { + caps.maxRectangleTextureSize = 64; + } + + return caps; +} } namespace egl @@ -617,6 +1068,7 @@ Caps::Caps() DisplayExtensions::DisplayExtensions() : createContextRobustness(false), d3dShareHandleClientBuffer(false), + d3dTextureClientBuffer(false), surfaceD3DTexture2DShareHandle(false), querySurfacePointer(false), windowFixedSize(false), @@ -635,7 +1087,21 @@ DisplayExtensions::DisplayExtensions() getAllProcAddresses(false), flexibleSurfaceCompatibility(false), directComposition(false), - createContextNoError(false) + createContextNoError(false), + stream(false), + streamConsumerGLTexture(false), + streamConsumerGLTextureYUV(false), + streamProducerD3DTextureNV12(false), + createContextWebGLCompatibility(false), + createContextBindGeneratesResource(false), + getSyncValues(false), + swapBuffersWithDamage(false), + pixelFormatFloat(false), + surfacelessContext(false), + displayTextureShareGroup(false), + createContextClientArrays(false), + programCacheControl(false), + robustResourceInitialization(false) { } @@ -644,29 +1110,44 @@ std::vector DisplayExtensions::getStrings() const std::vector extensionStrings; // clang-format off - // | Extension name | Supported flag | Output vector | - InsertExtensionString("EGL_EXT_create_context_robustness", createContextRobustness, &extensionStrings); - InsertExtensionString("EGL_ANGLE_d3d_share_handle_client_buffer", d3dShareHandleClientBuffer, &extensionStrings); - InsertExtensionString("EGL_ANGLE_surface_d3d_texture_2d_share_handle", surfaceD3DTexture2DShareHandle, &extensionStrings); - InsertExtensionString("EGL_ANGLE_query_surface_pointer", querySurfacePointer, &extensionStrings); - InsertExtensionString("EGL_ANGLE_window_fixed_size", windowFixedSize, &extensionStrings); - InsertExtensionString("EGL_ANGLE_keyed_mutex", keyedMutex, &extensionStrings); - InsertExtensionString("EGL_ANGLE_surface_orientation", surfaceOrientation, &extensionStrings); - InsertExtensionString("EGL_ANGLE_direct_composition", directComposition, &extensionStrings); - InsertExtensionString("EGL_NV_post_sub_buffer", postSubBuffer, &extensionStrings); - InsertExtensionString("EGL_KHR_create_context", createContext, &extensionStrings); - InsertExtensionString("EGL_EXT_device_query", deviceQuery, &extensionStrings); - InsertExtensionString("EGL_KHR_image", image, &extensionStrings); - InsertExtensionString("EGL_KHR_image_base", imageBase, &extensionStrings); - InsertExtensionString("EGL_KHR_image_pixmap", imagePixmap, &extensionStrings); - InsertExtensionString("EGL_KHR_gl_texture_2D_image", glTexture2DImage, &extensionStrings); - InsertExtensionString("EGL_KHR_gl_texture_cubemap_image", glTextureCubemapImage, &extensionStrings); - InsertExtensionString("EGL_KHR_gl_texture_3D_image", glTexture3DImage, &extensionStrings); - InsertExtensionString("EGL_KHR_gl_renderbuffer_image", glRenderbufferImage, &extensionStrings); - InsertExtensionString("EGL_KHR_get_all_proc_addresses", getAllProcAddresses, &extensionStrings); - InsertExtensionString("EGL_ANGLE_flexible_surface_compatibility", flexibleSurfaceCompatibility, &extensionStrings); + // | Extension name | Supported flag | Output vector | + InsertExtensionString("EGL_EXT_create_context_robustness", createContextRobustness, &extensionStrings); + InsertExtensionString("EGL_ANGLE_d3d_share_handle_client_buffer", d3dShareHandleClientBuffer, &extensionStrings); + InsertExtensionString("EGL_ANGLE_d3d_texture_client_buffer", d3dTextureClientBuffer, &extensionStrings); + InsertExtensionString("EGL_ANGLE_surface_d3d_texture_2d_share_handle", surfaceD3DTexture2DShareHandle, &extensionStrings); + InsertExtensionString("EGL_ANGLE_query_surface_pointer", querySurfacePointer, &extensionStrings); + InsertExtensionString("EGL_ANGLE_window_fixed_size", windowFixedSize, &extensionStrings); + InsertExtensionString("EGL_ANGLE_keyed_mutex", keyedMutex, &extensionStrings); + InsertExtensionString("EGL_ANGLE_surface_orientation", surfaceOrientation, &extensionStrings); + InsertExtensionString("EGL_ANGLE_direct_composition", directComposition, &extensionStrings); + InsertExtensionString("EGL_NV_post_sub_buffer", postSubBuffer, &extensionStrings); + InsertExtensionString("EGL_KHR_create_context", createContext, &extensionStrings); + InsertExtensionString("EGL_EXT_device_query", deviceQuery, &extensionStrings); + InsertExtensionString("EGL_KHR_image", image, &extensionStrings); + InsertExtensionString("EGL_KHR_image_base", imageBase, &extensionStrings); + InsertExtensionString("EGL_KHR_image_pixmap", imagePixmap, &extensionStrings); + InsertExtensionString("EGL_KHR_gl_texture_2D_image", glTexture2DImage, &extensionStrings); + InsertExtensionString("EGL_KHR_gl_texture_cubemap_image", glTextureCubemapImage, &extensionStrings); + InsertExtensionString("EGL_KHR_gl_texture_3D_image", glTexture3DImage, &extensionStrings); + InsertExtensionString("EGL_KHR_gl_renderbuffer_image", glRenderbufferImage, &extensionStrings); + InsertExtensionString("EGL_KHR_get_all_proc_addresses", getAllProcAddresses, &extensionStrings); + InsertExtensionString("EGL_KHR_stream", stream, &extensionStrings); + InsertExtensionString("EGL_KHR_stream_consumer_gltexture", streamConsumerGLTexture, &extensionStrings); + InsertExtensionString("EGL_NV_stream_consumer_gltexture_yuv", streamConsumerGLTextureYUV, &extensionStrings); + InsertExtensionString("EGL_ANGLE_flexible_surface_compatibility", flexibleSurfaceCompatibility, &extensionStrings); + InsertExtensionString("EGL_ANGLE_stream_producer_d3d_texture_nv12", streamProducerD3DTextureNV12, &extensionStrings); + InsertExtensionString("EGL_ANGLE_create_context_webgl_compatibility", createContextWebGLCompatibility, &extensionStrings); + InsertExtensionString("EGL_CHROMIUM_create_context_bind_generates_resource", createContextBindGeneratesResource, &extensionStrings); + InsertExtensionString("EGL_CHROMIUM_sync_control", getSyncValues, &extensionStrings); + InsertExtensionString("EGL_EXT_swap_buffers_with_damage", swapBuffersWithDamage, &extensionStrings); + InsertExtensionString("EGL_EXT_pixel_format_float", pixelFormatFloat, &extensionStrings); + InsertExtensionString("EGL_KHR_surfaceless_context", surfacelessContext, &extensionStrings); + InsertExtensionString("EGL_ANGLE_display_texture_share_group", displayTextureShareGroup, &extensionStrings); + InsertExtensionString("EGL_ANGLE_create_context_client_arrays", createContextClientArrays, &extensionStrings); + InsertExtensionString("EGL_ANGLE_program_cache_control", programCacheControl, &extensionStrings); + InsertExtensionString("EGL_ANGLE_robust_resource_initialization", robustResourceInitialization, &extensionStrings); // TODO(jmadill): Enable this when complete. - //InsertExtensionString("KHR_create_context_no_error", createContextNoError, &extensionStrings); + //InsertExtensionString("KHR_create_context_no_error", createContextNoError, &extensionStrings); // clang-format on return extensionStrings; @@ -694,6 +1175,7 @@ ClientExtensions::ClientExtensions() platformANGLE(false), platformANGLED3D(false), platformANGLEOpenGL(false), + platformANGLEVulkan(false), deviceCreation(false), deviceCreationD3D11(false), x11Visual(false), @@ -702,6 +1184,8 @@ ClientExtensions::ClientExtensions() { } +ClientExtensions::ClientExtensions(const ClientExtensions &other) = default; + std::vector ClientExtensions::getStrings() const { std::vector extensionStrings; @@ -714,6 +1198,8 @@ std::vector ClientExtensions::getStrings() const InsertExtensionString("EGL_ANGLE_platform_angle", platformANGLE, &extensionStrings); InsertExtensionString("EGL_ANGLE_platform_angle_d3d", platformANGLED3D, &extensionStrings); InsertExtensionString("EGL_ANGLE_platform_angle_opengl", platformANGLEOpenGL, &extensionStrings); + InsertExtensionString("EGL_ANGLE_platform_angle_null", platformANGLENULL, &extensionStrings); + InsertExtensionString("EGL_ANGLE_platform_angle_vulkan", platformANGLEVulkan, &extensionStrings); InsertExtensionString("EGL_ANGLE_device_creation", deviceCreation, &extensionStrings); InsertExtensionString("EGL_ANGLE_device_creation_d3d11", deviceCreationD3D11, &extensionStrings); InsertExtensionString("EGL_ANGLE_x11_visual", x11Visual, &extensionStrings); @@ -724,4 +1210,4 @@ std::vector ClientExtensions::getStrings() const return extensionStrings; } -} +} // namespace egl diff --git a/src/3rdparty/angle/src/libANGLE/Caps.h b/src/3rdparty/angle/src/libANGLE/Caps.h index d0e839a2ba..64bdf97112 100644 --- a/src/3rdparty/angle/src/libANGLE/Caps.h +++ b/src/3rdparty/angle/src/libANGLE/Caps.h @@ -8,21 +8,28 @@ #define LIBANGLE_CAPS_H_ #include "angle_gl.h" +#include "libANGLE/Version.h" #include "libANGLE/angletypes.h" +#include "libANGLE/renderer/Format.h" #include #include #include #include +#include namespace gl { +struct Extensions; + typedef std::set SupportedSampleSet; struct TextureCaps { TextureCaps(); + TextureCaps(const TextureCaps &other); + ~TextureCaps(); // Supports for basic texturing: glTexImage, glTexSubImage, etc bool texturable; @@ -44,26 +51,37 @@ struct TextureCaps GLuint getNearestSamples(GLuint requestedSamples) const; }; -class TextureCapsMap +TextureCaps GenerateMinimumTextureCaps(GLenum internalFormat, + const Version &clientVersion, + const Extensions &extensions); + +class TextureCapsMap final : angle::NonCopyable { public: - typedef std::map::const_iterator const_iterator; + TextureCapsMap(); + ~TextureCapsMap(); + // These methods are deprecated. Please use angle::Format for new features. void insert(GLenum internalFormat, const TextureCaps &caps); - void remove(GLenum internalFormat); - const TextureCaps &get(GLenum internalFormat) const; - const_iterator begin() const; - const_iterator end() const; + void clear(); - size_t size() const; + // Prefer using angle::Format methods. + const TextureCaps &get(angle::Format::ID formatID) const; + void set(angle::Format::ID formatID, const TextureCaps &caps); private: - typedef std::map InternalFormatToCapsMap; - InternalFormatToCapsMap mCapsMap; + TextureCaps &get(angle::Format::ID formatID); + + // Indexed by angle::Format::ID + std::array mFormatData; }; +void InitMinimumTextureCapsMap(const Version &clientVersion, + const Extensions &extensions, + TextureCapsMap *capsMap); + struct Extensions { Extensions(); @@ -87,6 +105,7 @@ struct Extensions // GL_EXT_sRGB // GL_ANGLE_depth_texture, GL_OES_depth32 // GL_EXT_color_buffer_float + // GL_EXT_texture_norm16 void setTextureExtensionSupport(const TextureCapsMap &textureCaps); // ES2 Extension support @@ -141,12 +160,18 @@ struct Extensions bool textureRG; // GL_EXT_texture_compression_dxt1, GL_ANGLE_texture_compression_dxt3 and GL_ANGLE_texture_compression_dxt5 - // Implies that TextureCaps for GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT + // Implies that TextureCaps exist for GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT // GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE and GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE bool textureCompressionDXT1; bool textureCompressionDXT3; bool textureCompressionDXT5; + // GL_EXT_texture_compression_s3tc_srgb + // Implies that TextureCaps exist for GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, + // GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, and + // GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT + bool textureCompressionS3TCsRGB; + // GL_KHR_texture_compression_astc_hdr bool textureCompressionASTCHDR; @@ -188,9 +213,6 @@ struct Extensions // GL_NV_fence bool fence; - // GL_ANGLE_timer_query - bool timerQuery; - // GL_EXT_disjoint_timer_query bool disjointTimerQuery; GLuint queryCounterBitsTimeElapsed; @@ -199,6 +221,9 @@ struct Extensions // GL_EXT_robustness bool robustness; + // GL_KHR_robust_buffer_access_behavior + bool robustBufferAccessBehavior; + // GL_EXT_blend_minmax bool blendMinMax; @@ -220,18 +245,13 @@ struct Extensions // GL_EXT_shader_texture_lod bool shaderTextureLOD; - // GL_EXT_shader_framebuffer_fetch - bool shaderFramebufferFetch; - - // GL_ARM_shader_framebuffer_fetch - bool ARMshaderFramebufferFetch; - - // GL_NV_shader_framebuffer_fetch - bool NVshaderFramebufferFetch; - // GL_EXT_frag_depth bool fragDepth; + // ANGLE_multiview + bool multiview; + GLuint maxViews; + // GL_ANGLE_texture_usage bool textureUsage; @@ -256,6 +276,9 @@ struct Extensions // GL_OES_EGL_image_external_essl3 bool eglImageExternalEssl3; + // NV_EGL_stream_consumer_external + bool eglStreamConsumerExternal; + // EXT_unpack_subimage bool unpackSubimage; @@ -278,12 +301,98 @@ struct Extensions // GL_ANGLE_lossy_etc_decode bool lossyETCDecode; + // GL_CHROMIUM_bind_uniform_location + bool bindUniformLocation; + + // GL_CHROMIUM_sync_query + bool syncQuery; + + // GL_CHROMIUM_copy_texture + bool copyTexture; + + // GL_CHROMIUM_copy_compressed_texture + bool copyCompressedTexture; + + // GL_ANGLE_webgl_compatibility + bool webglCompatibility; + + // GL_ANGLE_request_extension + bool requestExtension; + + // GL_CHROMIUM_bind_generates_resource + bool bindGeneratesResource; + + // GL_ANGLE_robust_client_memory + bool robustClientMemory; + + // GL_EXT_texture_sRGB_decode + bool textureSRGBDecode; + + // GL_EXT_sRGB_write_control + bool sRGBWriteControl; + + // GL_CHROMIUM_color_buffer_float_rgb + bool colorBufferFloatRGB; + + // GL_CHROMIUM_color_buffer_float_rgba + bool colorBufferFloatRGBA; + // ES3 Extension support // GL_EXT_color_buffer_float bool colorBufferFloat; + + // GL_EXT_multisample_compatibility. + // written against ES 3.1 but can apply to earlier versions. + bool multisampleCompatibility; + + // GL_CHROMIUM_framebuffer_mixed_samples + bool framebufferMixedSamples; + + // GL_EXT_texture_norm16 + // written against ES 3.1 but can apply to ES 3.0 as well. + bool textureNorm16; + + // GL_CHROMIUM_path_rendering + bool pathRendering; + + // GL_OES_surfaceless_context + bool surfacelessContext; + + // GL_ANGLE_client_arrays + bool clientArrays; + + // GL_ANGLE_robust_resource_initialization + bool robustResourceInitialization; + + // GL_ANGLE_program_cache_control + bool programCacheControl; + + // GL_ANGLE_texture_rectangle + bool textureRectangle; + + // GL_EXT_geometry_shader + bool geometryShader; + // GL_EXT_geometry_shader (May 31, 2016) Table 20.43gs: Implementation dependent geometry shader + // limits + // TODO(jiawei.shao@intel.com): add all implementation dependent geometry shader limits. + GLuint maxGeometryOutputVertices; + GLuint maxGeometryShaderInvocations; }; +struct ExtensionInfo +{ + // If this extension can be enabled with glRequestExtension (GL_ANGLE_request_extension) + bool Requestable = false; + + // Pointer to a boolean member of the Extensions struct + typedef bool(Extensions::*ExtensionBool); + ExtensionBool ExtensionsMember = nullptr; +}; + +using ExtensionInfoMap = std::map; +const ExtensionInfoMap &GetExtensionInfoMap(); + struct Limitations { Limitations(); @@ -311,39 +420,57 @@ struct Limitations struct TypePrecision { TypePrecision(); + TypePrecision(const TypePrecision &other); void setIEEEFloat(); void setTwosComplementInt(unsigned int bits); + void setSimulatedFloat(unsigned int range, unsigned int precision); void setSimulatedInt(unsigned int range); void get(GLint *returnRange, GLint *returnPrecision) const; - GLint range[2]; + std::array range; GLint precision; }; struct Caps { Caps(); + Caps(const Caps &other); + ~Caps(); - // Table 6.28, implementation dependent values + // ES 3.1 (April 29, 2015) 20.39: implementation dependent values GLuint64 maxElementIndex; GLuint max3DTextureSize; GLuint max2DTextureSize; + GLuint maxRectangleTextureSize; GLuint maxArrayTextureLayers; GLfloat maxLODBias; GLuint maxCubeMapTextureSize; GLuint maxRenderbufferSize; - GLuint maxDrawBuffers; - GLuint maxColorAttachments; - GLuint maxViewportWidth; - GLuint maxViewportHeight; GLfloat minAliasedPointSize; GLfloat maxAliasedPointSize; GLfloat minAliasedLineWidth; GLfloat maxAliasedLineWidth; - // Table 6.29, implementation dependent values (cont.) + // ES 3.1 (April 29, 2015) 20.40: implementation dependent values (cont.) + GLuint maxDrawBuffers; + GLuint maxFramebufferWidth; + GLuint maxFramebufferHeight; + GLuint maxFramebufferSamples; + GLuint maxColorAttachments; + GLuint maxViewportWidth; + GLuint maxViewportHeight; + GLuint maxSampleMaskWords; + GLuint maxColorTextureSamples; + GLuint maxDepthTextureSamples; + GLuint maxIntegerSamples; + GLuint64 maxServerWaitTimeout; + + // ES 3.1 (April 29, 2015) Table 20.41: Implementation dependent values (cont.) + GLint maxVertexAttribRelativeOffset; + GLuint maxVertexAttribBindings; + GLint maxVertexAttribStride; GLuint maxElementsIndices; GLuint maxElementsVertices; std::vector compressedTextureFormats; @@ -361,26 +488,49 @@ struct Caps TypePrecision fragmentHighpInt; TypePrecision fragmentMediumpInt; TypePrecision fragmentLowpInt; - GLuint64 maxServerWaitTimeout; - // Table 6.31, implementation dependent vertex shader limits + // ES 3.1 (April 29, 2015) Table 20.43: Implementation dependent Vertex shader limits GLuint maxVertexAttributes; GLuint maxVertexUniformComponents; GLuint maxVertexUniformVectors; GLuint maxVertexUniformBlocks; GLuint maxVertexOutputComponents; GLuint maxVertexTextureImageUnits; + GLuint maxVertexAtomicCounterBuffers; + GLuint maxVertexAtomicCounters; + GLuint maxVertexImageUniforms; + GLuint maxVertexShaderStorageBlocks; - // Table 6.32, implementation dependent fragment shader limits + // ES 3.1 (April 29, 2015) Table 20.44: Implementation dependent Fragment shader limits GLuint maxFragmentUniformComponents; GLuint maxFragmentUniformVectors; GLuint maxFragmentUniformBlocks; GLuint maxFragmentInputComponents; GLuint maxTextureImageUnits; + GLuint maxFragmentAtomicCounterBuffers; + GLuint maxFragmentAtomicCounters; + GLuint maxFragmentImageUniforms; + GLuint maxFragmentShaderStorageBlocks; + GLint minProgramTextureGatherOffset; + GLuint maxProgramTextureGatherOffset; GLint minProgramTexelOffset; GLint maxProgramTexelOffset; - // Table 6.33, implementation dependent aggregate shader limits + // ES 3.1 (April 29, 2015) Table 20.45: implementation dependent compute shader limits + std::array maxComputeWorkGroupCount; + std::array maxComputeWorkGroupSize; + GLuint maxComputeWorkGroupInvocations; + GLuint maxComputeUniformBlocks; + GLuint maxComputeTextureImageUnits; + GLuint maxComputeSharedMemorySize; + GLuint maxComputeUniformComponents; + GLuint maxComputeAtomicCounterBuffers; + GLuint maxComputeAtomicCounters; + GLuint maxComputeImageUniforms; + GLuint maxCombinedComputeUniformComponents; + GLuint maxComputeShaderStorageBlocks; + + // ES 3.1 (April 29, 2015) Table 20.46: implementation dependent aggregate shader limits GLuint maxUniformBufferBindings; GLuint64 maxUniformBlockSize; GLuint uniformBufferOffsetAlignment; @@ -390,16 +540,31 @@ struct Caps GLuint maxVaryingComponents; GLuint maxVaryingVectors; GLuint maxCombinedTextureImageUnits; + GLuint maxCombinedShaderOutputResources; - // Table 6.34, implementation dependent transform feedback limits + // ES 3.1 (April 29, 2015) Table 20.47: implementation dependent aggregate shader limits (cont.) + GLuint maxUniformLocations; + GLuint maxAtomicCounterBufferBindings; + GLuint maxAtomicCounterBufferSize; + GLuint maxCombinedAtomicCounterBuffers; + GLuint maxCombinedAtomicCounters; + GLuint maxImageUnits; + GLuint maxCombinedImageUniforms; + GLuint maxShaderStorageBufferBindings; + GLuint64 maxShaderStorageBlockSize; + GLuint maxCombinedShaderStorageBlocks; + GLuint shaderStorageBufferOffsetAlignment; + + // ES 3.1 (April 29, 2015) Table 20.48: implementation dependent transform feedback limits GLuint maxTransformFeedbackInterleavedComponents; GLuint maxTransformFeedbackSeparateAttributes; GLuint maxTransformFeedbackSeparateComponents; - // Table 6.35, Framebuffer Dependent Values + // ES 3.1 (April 29, 2015) Table 20.49: Framebuffer Dependent Values GLuint maxSamples; }; +Caps GenerateMinimumCaps(const Version &clientVersion, const Extensions &extensions); } namespace egl @@ -426,6 +591,9 @@ struct DisplayExtensions // EGL_ANGLE_d3d_share_handle_client_buffer bool d3dShareHandleClientBuffer; + // EGL_ANGLE_d3d_texture_client_buffer + bool d3dTextureClientBuffer; + // EGL_ANGLE_surface_d3d_texture_2d_share_handle bool surfaceD3DTexture2DShareHandle; @@ -482,6 +650,48 @@ struct DisplayExtensions // KHR_create_context_no_error bool createContextNoError; + + // EGL_KHR_stream + bool stream; + + // EGL_KHR_stream_consumer_gltexture + bool streamConsumerGLTexture; + + // EGL_NV_stream_consumer_gltexture_yuv + bool streamConsumerGLTextureYUV; + + // EGL_ANGLE_stream_producer_d3d_texture_nv12 + bool streamProducerD3DTextureNV12; + + // EGL_ANGLE_create_context_webgl_compatibility + bool createContextWebGLCompatibility; + + // EGL_CHROMIUM_create_context_bind_generates_resource + bool createContextBindGeneratesResource; + + // EGL_CHROMIUM_get_sync_values + bool getSyncValues; + + // EGL_EXT_swap_buffers_with_damage + bool swapBuffersWithDamage; + + // EGL_EXT_pixel_format_float + bool pixelFormatFloat; + + // EGL_KHR_surfaceless_context + bool surfacelessContext; + + // EGL_ANGLE_display_texture_share_group + bool displayTextureShareGroup; + + // EGL_ANGLE_create_context_client_arrays + bool createContextClientArrays; + + // EGL_ANGLE_program_cache_control + bool programCacheControl; + + // EGL_ANGLE_robust_resource_initialization + bool robustResourceInitialization; }; struct DeviceExtensions @@ -498,6 +708,7 @@ struct DeviceExtensions struct ClientExtensions { ClientExtensions(); + ClientExtensions(const ClientExtensions &other); // Generate a vector of supported extension strings std::vector getStrings() const; @@ -520,6 +731,12 @@ struct ClientExtensions // EGL_ANGLE_platform_angle_opengl bool platformANGLEOpenGL; + // EGL_ANGLE_platform_angle_null + bool platformANGLENULL; + + // EGL_ANGLE_platform_angle_vulkan + bool platformANGLEVulkan; + // EGL_ANGLE_device_creation bool deviceCreation; @@ -536,6 +753,6 @@ struct ClientExtensions bool clientGetAllProcAddresses; }; -} +} // namespace egl #endif // LIBANGLE_CAPS_H_ diff --git a/src/3rdparty/angle/src/libANGLE/Compiler.cpp b/src/3rdparty/angle/src/libANGLE/Compiler.cpp index 348c41bef3..236c7e1fc2 100644 --- a/src/3rdparty/angle/src/libANGLE/Compiler.cpp +++ b/src/3rdparty/angle/src/libANGLE/Compiler.cpp @@ -9,9 +9,9 @@ #include "libANGLE/Compiler.h" #include "common/debug.h" -#include "libANGLE/Data.h" +#include "libANGLE/ContextState.h" #include "libANGLE/renderer/CompilerImpl.h" -#include "libANGLE/renderer/ImplFactory.h" +#include "libANGLE/renderer/GLImplFactory.h" namespace gl { @@ -19,26 +19,46 @@ namespace gl namespace { -// Global count of active shader compiler handles. Needed to know when to call ShInitialize and -// ShFinalize. +// Global count of active shader compiler handles. Needed to know when to call sh::Initialize and +// sh::Finalize. size_t activeCompilerHandles = 0; +ShShaderSpec SelectShaderSpec(GLint majorVersion, GLint minorVersion, bool isWebGL) +{ + if (majorVersion >= 3) + { + if (minorVersion == 1) + { + return isWebGL ? SH_WEBGL3_SPEC : SH_GLES3_1_SPEC; + } + else + { + return isWebGL ? SH_WEBGL2_SPEC : SH_GLES3_SPEC; + } + } + return isWebGL ? SH_WEBGL_SPEC : SH_GLES2_SPEC; +} + } // anonymous namespace -Compiler::Compiler(rx::ImplFactory *implFactory, const gl::Data &data) +Compiler::Compiler(rx::GLImplFactory *implFactory, const ContextState &state) : mImplementation(implFactory->createCompiler()), - mSpec(data.clientVersion > 2 ? SH_GLES3_SPEC : SH_GLES2_SPEC), + mSpec(SelectShaderSpec(state.getClientMajorVersion(), + state.getClientMinorVersion(), + state.getExtensions().webglCompatibility)), mOutputType(mImplementation->getTranslatorOutputType()), mResources(), mFragmentCompiler(nullptr), - mVertexCompiler(nullptr) + mVertexCompiler(nullptr), + mComputeCompiler(nullptr), + mGeometryCompiler(nullptr) { - ASSERT(data.clientVersion == 2 || data.clientVersion == 3); + ASSERT(state.getClientMajorVersion() == 2 || state.getClientMajorVersion() == 3); - const gl::Caps &caps = *data.caps; - const gl::Extensions &extensions = *data.extensions; + const gl::Caps &caps = state.getCaps(); + const gl::Extensions &extensions = state.getExtensions(); - ShInitBuiltInResources(&mResources); + sh::InitBuiltInResources(&mResources); mResources.MaxVertexAttribs = caps.maxVertexAttributes; mResources.MaxVertexUniformVectors = caps.maxVertexUniformVectors; mResources.MaxVaryingVectors = caps.maxVaryingVectors; @@ -50,30 +70,79 @@ Compiler::Compiler(rx::ImplFactory *implFactory, const gl::Data &data) mResources.OES_standard_derivatives = extensions.standardDerivatives; mResources.EXT_draw_buffers = extensions.drawBuffers; mResources.EXT_shader_texture_lod = extensions.shaderTextureLOD; - // TODO: disabled until the extension is actually supported. - mResources.OES_EGL_image_external = 0; + mResources.OES_EGL_image_external = extensions.eglImageExternal; + mResources.OES_EGL_image_external_essl3 = extensions.eglImageExternalEssl3; + mResources.NV_EGL_stream_consumer_external = extensions.eglStreamConsumerExternal; + mResources.ARB_texture_rectangle = extensions.textureRectangle; // TODO: use shader precision caps to determine if high precision is supported? mResources.FragmentPrecisionHigh = 1; mResources.EXT_frag_depth = extensions.fragDepth; + // OVR_multiview state + mResources.OVR_multiview = extensions.multiview; + mResources.MaxViewsOVR = extensions.maxViews; + // GLSL ES 3.0 constants mResources.MaxVertexOutputVectors = caps.maxVertexOutputComponents / 4; mResources.MaxFragmentInputVectors = caps.maxFragmentInputComponents / 4; mResources.MinProgramTexelOffset = caps.minProgramTexelOffset; mResources.MaxProgramTexelOffset = caps.maxProgramTexelOffset; + + // GLSL ES 3.1 constants + mResources.MaxProgramTextureGatherOffset = caps.maxProgramTextureGatherOffset; + mResources.MinProgramTextureGatherOffset = caps.minProgramTextureGatherOffset; + mResources.MaxImageUnits = caps.maxImageUnits; + mResources.MaxVertexImageUniforms = caps.maxVertexImageUniforms; + mResources.MaxFragmentImageUniforms = caps.maxFragmentImageUniforms; + mResources.MaxComputeImageUniforms = caps.maxComputeImageUniforms; + mResources.MaxCombinedImageUniforms = caps.maxCombinedImageUniforms; + mResources.MaxCombinedShaderOutputResources = caps.maxCombinedShaderOutputResources; + mResources.MaxUniformLocations = caps.maxUniformLocations; + + for (size_t index = 0u; index < 3u; ++index) + { + mResources.MaxComputeWorkGroupCount[index] = caps.maxComputeWorkGroupCount[index]; + mResources.MaxComputeWorkGroupSize[index] = caps.maxComputeWorkGroupSize[index]; + } + + mResources.MaxComputeUniformComponents = caps.maxComputeUniformComponents; + mResources.MaxComputeTextureImageUnits = caps.maxComputeTextureImageUnits; + + mResources.MaxComputeAtomicCounters = caps.maxComputeAtomicCounters; + mResources.MaxComputeAtomicCounterBuffers = caps.maxComputeAtomicCounterBuffers; + + mResources.MaxVertexAtomicCounters = caps.maxVertexAtomicCounters; + mResources.MaxFragmentAtomicCounters = caps.maxFragmentAtomicCounters; + mResources.MaxCombinedAtomicCounters = caps.maxCombinedAtomicCounters; + mResources.MaxAtomicCounterBindings = caps.maxAtomicCounterBufferBindings; + mResources.MaxVertexAtomicCounterBuffers = caps.maxVertexAtomicCounterBuffers; + mResources.MaxFragmentAtomicCounterBuffers = caps.maxFragmentAtomicCounterBuffers; + mResources.MaxCombinedAtomicCounterBuffers = caps.maxCombinedAtomicCounterBuffers; + mResources.MaxAtomicCounterBufferSize = caps.maxAtomicCounterBufferSize; + + mResources.MaxUniformBufferBindings = caps.maxUniformBufferBindings; + mResources.MaxShaderStorageBufferBindings = caps.maxShaderStorageBufferBindings; + + // Needed by point size clamping workaround + mResources.MaxPointSize = caps.maxAliasedPointSize; + + if (state.getClientMajorVersion() == 2 && !extensions.drawBuffers) + { + mResources.MaxDrawBuffers = 1; + } + + // Geometry Shader constants + mResources.OES_geometry_shader = extensions.geometryShader; + // TODO(jiawei.shao@intel.com): initialize all implementation dependent geometry shader limits. + mResources.MaxGeometryOutputVertices = extensions.maxGeometryOutputVertices; + mResources.MaxGeometryShaderInvocations = extensions.maxGeometryShaderInvocations; } Compiler::~Compiler() -{ - release(); - SafeDelete(mImplementation); -} - -Error Compiler::release() { if (mFragmentCompiler) { - ShDestruct(mFragmentCompiler); + sh::Destruct(mFragmentCompiler); mFragmentCompiler = nullptr; ASSERT(activeCompilerHandles > 0); @@ -82,21 +151,28 @@ Error Compiler::release() if (mVertexCompiler) { - ShDestruct(mVertexCompiler); + sh::Destruct(mVertexCompiler); mVertexCompiler = nullptr; ASSERT(activeCompilerHandles > 0); activeCompilerHandles--; } + if (mComputeCompiler) + { + sh::Destruct(mComputeCompiler); + mComputeCompiler = nullptr; + + ASSERT(activeCompilerHandles > 0); + activeCompilerHandles--; + } + if (activeCompilerHandles == 0) { - ShFinalize(); + sh::Finalize(); } - mImplementation->release(); - - return gl::Error(GL_NO_ERROR); + ANGLE_SWALLOW_ERR(mImplementation->release()); } ShHandle Compiler::getCompilerHandle(GLenum type) @@ -111,7 +187,12 @@ ShHandle Compiler::getCompilerHandle(GLenum type) case GL_FRAGMENT_SHADER: compiler = &mFragmentCompiler; break; - + case GL_COMPUTE_SHADER: + compiler = &mComputeCompiler; + break; + case GL_GEOMETRY_SHADER_EXT: + compiler = &mGeometryCompiler; + break; default: UNREACHABLE(); return nullptr; @@ -121,14 +202,20 @@ ShHandle Compiler::getCompilerHandle(GLenum type) { if (activeCompilerHandles == 0) { - ShInitialize(); + sh::Initialize(); } - *compiler = ShConstructCompiler(type, mSpec, mOutputType, &mResources); + *compiler = sh::ConstructCompiler(type, mSpec, mOutputType, &mResources); + ASSERT(*compiler); activeCompilerHandles++; } return *compiler; } +const std::string &Compiler::getBuiltinResourcesString(GLenum type) +{ + return sh::GetBuiltInResourcesString(getCompilerHandle(type)); +} + } // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/Compiler.h b/src/3rdparty/angle/src/libANGLE/Compiler.h index 8634e39a45..b7f7e9f31b 100644 --- a/src/3rdparty/angle/src/libANGLE/Compiler.h +++ b/src/3rdparty/angle/src/libANGLE/Compiler.h @@ -10,38 +10,40 @@ #ifndef LIBANGLE_COMPILER_H_ #define LIBANGLE_COMPILER_H_ -#include "libANGLE/Error.h" #include "GLSLANG/ShaderLang.h" +#include "libANGLE/Error.h" +#include "libANGLE/RefCountObject.h" namespace rx { class CompilerImpl; -class ImplFactory; +class GLImplFactory; } namespace gl { -struct Data; +class ContextState; -class Compiler final : angle::NonCopyable +class Compiler final : public RefCountObjectNoID { public: - Compiler(rx::ImplFactory *implFactory, const Data &data); - ~Compiler(); - - Error release(); + Compiler(rx::GLImplFactory *implFactory, const ContextState &data); ShHandle getCompilerHandle(GLenum type); ShShaderOutput getShaderOutputType() const { return mOutputType; } + const std::string &getBuiltinResourcesString(GLenum type); private: - rx::CompilerImpl *mImplementation; + ~Compiler() override; + std::unique_ptr mImplementation; ShShaderSpec mSpec; ShShaderOutput mOutputType; ShBuiltInResources mResources; ShHandle mFragmentCompiler; ShHandle mVertexCompiler; + ShHandle mComputeCompiler; + ShHandle mGeometryCompiler; }; } // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/Config.cpp b/src/3rdparty/angle/src/libANGLE/Config.cpp index d511df3a69..172c312ae0 100644 --- a/src/3rdparty/angle/src/libANGLE/Config.cpp +++ b/src/3rdparty/angle/src/libANGLE/Config.cpp @@ -58,10 +58,27 @@ Config::Config() transparentRedValue(0), transparentGreenValue(0), transparentBlueValue(0), - optimalOrientation(0) + optimalOrientation(0), + colorComponentType(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT) { } +Config::~Config() +{ +} + +Config::Config(const Config &other) = default; + +Config &Config::operator=(const Config &other) = default; + +ConfigSet::ConfigSet() = default; + +ConfigSet::ConfigSet(const ConfigSet &other) = default; + +ConfigSet &ConfigSet::operator=(const ConfigSet &other) = default; + +ConfigSet::~ConfigSet() = default; + EGLint ConfigSet::add(const Config &config) { // Set the config's ID to a small number that starts at 1 ([EGL 1.5] section 3.4) @@ -134,6 +151,10 @@ class ConfigSorter static_assert(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG, "Unexpected EGL enum value."); SORT(configCaveat); + static_assert(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT < EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT, + "Unexpected order of EGL enums."); + SORT(colorComponentType); + static_assert(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER, "Unexpected EGL enum value."); SORT(colorBufferType); @@ -160,6 +181,7 @@ class ConfigSorter } private: + void scanForWantedComponents(const AttributeMap &attributeMap) { // [EGL 1.5] section 3.4.1.2 page 30 @@ -215,8 +237,13 @@ std::vector ConfigSet::filter(const AttributeMap &attributeMap) c for (auto attribIter = attributeMap.begin(); attribIter != attributeMap.end(); attribIter++) { - EGLint attributeKey = attribIter->first; - EGLint attributeValue = attribIter->second; + EGLAttrib attributeKey = attribIter->first; + EGLAttrib attributeValue = attribIter->second; + + if (attributeValue == EGL_DONT_CARE) + { + continue; + } switch (attributeKey) { @@ -255,6 +282,9 @@ std::vector ConfigSet::filter(const AttributeMap &attributeMap) c case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE: match = config.optimalOrientation == attributeValue; break; + case EGL_COLOR_COMPONENT_TYPE_EXT: + match = config.colorComponentType == static_cast(attributeValue); + break; default: UNREACHABLE(); } diff --git a/src/3rdparty/angle/src/libANGLE/Config.h b/src/3rdparty/angle/src/libANGLE/Config.h index 00f5673b59..f2fbe8b95a 100644 --- a/src/3rdparty/angle/src/libANGLE/Config.h +++ b/src/3rdparty/angle/src/libANGLE/Config.h @@ -27,6 +27,9 @@ namespace egl struct Config { Config(); + ~Config(); + Config(const Config &other); + Config &operator=(const Config &other); GLenum renderTargetFormat; // TODO(geofflang): remove this GLenum depthStencilFormat; // TODO(geofflang): remove this @@ -65,11 +68,17 @@ struct Config EGLint transparentGreenValue; // Transparent green value EGLint transparentBlueValue; // Transparent blue value EGLint optimalOrientation; // Optimal window surface orientation + EGLenum colorComponentType; // Color component type }; class ConfigSet { public: + ConfigSet(); + ConfigSet(const ConfigSet &other); + ~ConfigSet(); + ConfigSet &operator=(const ConfigSet &other); + EGLint add(const Config &config); const Config &get(EGLint id) const; @@ -83,7 +92,7 @@ class ConfigSet std::vector filter(const AttributeMap &attributeMap) const; private: - typedef std::map ConfigMap; + typedef std::map ConfigMap; ConfigMap mConfigs; }; diff --git a/src/3rdparty/angle/src/libANGLE/Constants.h b/src/3rdparty/angle/src/libANGLE/Constants.h index dc8f9555b8..2fe921af38 100644 --- a/src/3rdparty/angle/src/libANGLE/Constants.h +++ b/src/3rdparty/angle/src/libANGLE/Constants.h @@ -9,36 +9,54 @@ #ifndef LIBANGLE_CONSTANTS_H_ #define LIBANGLE_CONSTANTS_H_ +#include "common/platform.h" + namespace gl { +// The binary cache is currently left disable by default, and the application can enable it. +const size_t kDefaultMaxProgramCacheMemoryBytes = 0; + enum { - MAX_VERTEX_ATTRIBS = 16, + // Implementation upper limits, real maximums depend on the hardware + MAX_SAMPLE_MASK_WORDS = 2, + + MAX_VERTEX_ATTRIBS = 16, + MAX_VERTEX_ATTRIB_BINDINGS = 16, // Implementation upper limits, real maximums depend on the hardware IMPLEMENTATION_MAX_VARYING_VECTORS = 32, - IMPLEMENTATION_MAX_DRAW_BUFFERS = 8, - IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS = IMPLEMENTATION_MAX_DRAW_BUFFERS + 2, // 2 extra for depth and/or stencil buffers + IMPLEMENTATION_MAX_DRAW_BUFFERS = 8, + IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS = + IMPLEMENTATION_MAX_DRAW_BUFFERS + 2, // 2 extra for depth and/or stencil buffers - IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS = 16, + IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS = 16, IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS = 16, - IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS = IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS + - IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS, + IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS = + IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS + + IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS, IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS = 4, + // Maximum number of views which are supported by the implementation of ANGLE_multiview. + IMPLEMENTATION_ANGLE_MULTIVIEW_MAX_VIEWS = 4, + // These are the maximums the implementation can support // The actual GL caps are limited by the device caps // and should be queried from the Context - IMPLEMENTATION_MAX_2D_TEXTURE_SIZE = 16384, - IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 16384, - IMPLEMENTATION_MAX_3D_TEXTURE_SIZE = 2048, + IMPLEMENTATION_MAX_2D_TEXTURE_SIZE = 16384, + IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 16384, + IMPLEMENTATION_MAX_3D_TEXTURE_SIZE = 2048, IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS = 2048, - IMPLEMENTATION_MAX_TEXTURE_LEVELS = 15 // 1+log2 of MAX_TEXTURE_SIZE -}; + // 1+log2 of max of MAX_*_TEXTURE_SIZE + IMPLEMENTATION_MAX_TEXTURE_LEVELS = 15, + // Limit active textures so we can use fast bitsets. + IMPLEMENTATION_MAX_SHADER_TEXTURES = 32, + IMPLEMENTATION_MAX_ACTIVE_TEXTURES = IMPLEMENTATION_MAX_SHADER_TEXTURES * 2, +}; } #endif // LIBANGLE_CONSTANTS_H_ diff --git a/src/3rdparty/angle/src/libANGLE/Context.cpp b/src/3rdparty/angle/src/libANGLE/Context.cpp index 26f2970068..f638beda58 100644 --- a/src/3rdparty/angle/src/libANGLE/Context.cpp +++ b/src/3rdparty/angle/src/libANGLE/Context.cpp @@ -9,18 +9,24 @@ #include "libANGLE/Context.h" +#include #include #include +#include +#include "common/matrix_utils.h" #include "common/platform.h" #include "common/utilities.h" +#include "common/version.h" #include "libANGLE/Buffer.h" #include "libANGLE/Compiler.h" #include "libANGLE/Display.h" #include "libANGLE/Fence.h" #include "libANGLE/Framebuffer.h" #include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/Path.h" #include "libANGLE/Program.h" +#include "libANGLE/ProgramPipeline.h" #include "libANGLE/Query.h" #include "libANGLE/Renderbuffer.h" #include "libANGLE/ResourceManager.h" @@ -29,36 +35,97 @@ #include "libANGLE/Texture.h" #include "libANGLE/TransformFeedback.h" #include "libANGLE/VertexArray.h" +#include "libANGLE/Workarounds.h" #include "libANGLE/formatutils.h" +#include "libANGLE/queryconversions.h" +#include "libANGLE/queryutils.h" +#include "libANGLE/renderer/ContextImpl.h" +#include "libANGLE/renderer/EGLImplFactory.h" +#include "libANGLE/renderer/Format.h" #include "libANGLE/validationES.h" -#include "libANGLE/renderer/Renderer.h" namespace { +#define ANGLE_HANDLE_ERR(X) \ + handleError(X); \ + return; +#define ANGLE_CONTEXT_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_HANDLE_ERR); + template -gl::Error GetQueryObjectParameter(gl::Context *context, GLuint id, GLenum pname, T *params) +std::vector GatherPaths(gl::PathManager &resourceManager, + GLsizei numPaths, + const void *paths, + GLuint pathBase) { - gl::Query *queryObject = context->getQuery(id, false, GL_NONE); - ASSERT(queryObject != nullptr); + std::vector ret; + ret.reserve(numPaths); + + const auto *nameArray = static_cast(paths); + + for (GLsizei i = 0; i < numPaths; ++i) + { + const GLuint pathName = nameArray[i] + pathBase; + + ret.push_back(resourceManager.getPath(pathName)); + } + + return ret; +} + +std::vector GatherPaths(gl::PathManager &resourceManager, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase) +{ + switch (pathNameType) + { + case GL_UNSIGNED_BYTE: + return GatherPaths(resourceManager, numPaths, paths, pathBase); + + case GL_BYTE: + return GatherPaths(resourceManager, numPaths, paths, pathBase); + + case GL_UNSIGNED_SHORT: + return GatherPaths(resourceManager, numPaths, paths, pathBase); + + case GL_SHORT: + return GatherPaths(resourceManager, numPaths, paths, pathBase); + + case GL_UNSIGNED_INT: + return GatherPaths(resourceManager, numPaths, paths, pathBase); + + case GL_INT: + return GatherPaths(resourceManager, numPaths, paths, pathBase); + } + + UNREACHABLE(); + return std::vector(); +} + +template +gl::Error GetQueryObjectParameter(gl::Query *query, GLenum pname, T *params) +{ + ASSERT(query != nullptr); switch (pname) { case GL_QUERY_RESULT_EXT: - return queryObject->getResult(params); + return query->getResult(params); case GL_QUERY_RESULT_AVAILABLE_EXT: { bool available; - gl::Error error = queryObject->isResultAvailable(&available); + gl::Error error = query->isResultAvailable(&available); if (!error.isError()) { - *params = static_cast(available ? GL_TRUE : GL_FALSE); + *params = gl::CastFromStateValue(pname, static_cast(available)); } return error; } default: UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION, "Unreachable Error"); + return gl::InternalError() << "Unreachable Error"; } } @@ -69,7 +136,7 @@ void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback) for (size_t tfBufferIndex = 0; tfBufferIndex < transformFeedback->getIndexedBufferCount(); tfBufferIndex++) { - const OffsetBindingPointer &buffer = + const gl::OffsetBindingPointer &buffer = transformFeedback->getIndexedBuffer(tfBufferIndex); if (buffer.get() != nullptr) { @@ -80,15 +147,25 @@ void MarkTransformFeedbackBufferUsage(gl::TransformFeedback *transformFeedback) } // Attribute map queries. -EGLint GetClientVersion(const egl::AttributeMap &attribs) +EGLint GetClientMajorVersion(const egl::AttributeMap &attribs) { - return attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1); + return static_cast(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1)); +} + +EGLint GetClientMinorVersion(const egl::AttributeMap &attribs) +{ + return static_cast(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0)); +} + +gl::Version GetClientVersion(const egl::AttributeMap &attribs) +{ + return gl::Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs)); } GLenum GetResetStrategy(const egl::AttributeMap &attribs) { - EGLenum attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, - EGL_NO_RESET_NOTIFICATION_EXT); + EGLAttrib attrib = attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, + EGL_NO_RESET_NOTIFICATION); switch (attrib) { case EGL_NO_RESET_NOTIFICATION: @@ -103,12 +180,15 @@ GLenum GetResetStrategy(const egl::AttributeMap &attribs) bool GetRobustAccess(const egl::AttributeMap &attribs) { - return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE); + return (attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE) == EGL_TRUE) || + ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) != + 0); } bool GetDebug(const egl::AttributeMap &attribs) { - return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE); + return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) || + ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0); } bool GetNoError(const egl::AttributeMap &attribs) @@ -116,504 +196,657 @@ bool GetNoError(const egl::AttributeMap &attribs) return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE); } +bool GetWebGLContext(const egl::AttributeMap &attribs) +{ + return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE); +} + +bool GetBindGeneratesResource(const egl::AttributeMap &attribs) +{ + return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE); +} + +bool GetClientArraysEnabled(const egl::AttributeMap &attribs) +{ + return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE); +} + +bool GetRobustResourceInit(const egl::AttributeMap &attribs) +{ + return (attribs.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE); +} + +std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label) +{ + std::string labelName; + if (label != nullptr) + { + size_t labelLength = length < 0 ? strlen(label) : length; + labelName = std::string(label, labelLength); + } + return labelName; +} + +void GetObjectLabelBase(const std::string &objectLabel, + GLsizei bufSize, + GLsizei *length, + GLchar *label) +{ + size_t writeLength = objectLabel.length(); + if (label != nullptr && bufSize > 0) + { + writeLength = std::min(static_cast(bufSize) - 1, objectLabel.length()); + std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label); + label[writeLength] = '\0'; + } + + if (length != nullptr) + { + *length = static_cast(writeLength); + } +} + +template +void LimitCap(CapT *cap, MaxT maximum) +{ + *cap = std::min(*cap, static_cast(maximum)); +} + } // anonymous namespace namespace gl { -Context::Context(const egl::Config *config, +Context::Context(rx::EGLImplFactory *implFactory, + const egl::Config *config, const Context *shareContext, - rx::Renderer *renderer, - const egl::AttributeMap &attribs) - : ValidationContext(GetClientVersion(attribs), - mState, + TextureManager *shareTextures, + MemoryProgramCache *memoryProgramCache, + const egl::AttributeMap &attribs, + const egl::DisplayExtensions &displayExtensions) + + : ValidationContext(shareContext, + shareTextures, + GetClientVersion(attribs), + &mGLState, mCaps, mTextureCaps, mExtensions, - nullptr, mLimitations, GetNoError(attribs)), - mCompiler(nullptr), - mRenderer(renderer), - mClientVersion(GetClientVersion(attribs)), + mImplementation(implFactory->createContext(mState)), + mCompiler(), mConfig(config), mClientType(EGL_OPENGL_ES_API), mHasBeenCurrent(false), mContextLost(false), mResetStatus(GL_NO_ERROR), + mContextLostForced(false), mResetStrategy(GetResetStrategy(attribs)), mRobustAccess(GetRobustAccess(attribs)), - mCurrentSurface(nullptr), - mResourceManager(nullptr) + mCurrentSurface(static_cast(EGL_NO_SURFACE)), + mCurrentDisplay(static_cast(EGL_NO_DISPLAY)), + mSurfacelessFramebuffer(nullptr), + mWebGLContext(GetWebGLContext(attribs)), + mMemoryProgramCache(memoryProgramCache), + mScratchBuffer(1000u), + mZeroFilledBuffer(1000u) { - ASSERT(!mRobustAccess); // Unimplemented + mImplementation->setMemoryProgramCache(memoryProgramCache); - initCaps(mClientVersion); + bool robustResourceInit = GetRobustResourceInit(attribs); + initCaps(displayExtensions, robustResourceInit); + initWorkarounds(); - mState.initialize(mCaps, mExtensions, mClientVersion, GetDebug(attribs)); + mGLState.initialize(this, GetDebug(attribs), GetBindGeneratesResource(attribs), + GetClientArraysEnabled(attribs), robustResourceInit, + mMemoryProgramCache != nullptr); mFenceNVHandleAllocator.setBaseHandle(0); - if (shareContext != NULL) - { - mResourceManager = shareContext->mResourceManager; - mResourceManager->addRef(); - } - else - { - mResourceManager = new ResourceManager(mRenderer); - } - - mData.resourceManager = mResourceManager; - // [OpenGL ES 2.0.24] section 3.7 page 83: - // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional + // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have two-dimensional // and cube map texture state vectors respectively associated with them. // In order that access to these initial textures not be lost, they are treated as texture // objects all of whose names are 0. - Texture *zeroTexture2D = new Texture(mRenderer->createTexture(GL_TEXTURE_2D), 0, GL_TEXTURE_2D); - mZeroTextures[GL_TEXTURE_2D].set(zeroTexture2D); + Texture *zeroTexture2D = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D); + mZeroTextures[GL_TEXTURE_2D].set(this, zeroTexture2D); - Texture *zeroTextureCube = new Texture(mRenderer->createTexture(GL_TEXTURE_CUBE_MAP), 0, GL_TEXTURE_CUBE_MAP); - mZeroTextures[GL_TEXTURE_CUBE_MAP].set(zeroTextureCube); + Texture *zeroTextureCube = new Texture(mImplementation.get(), 0, GL_TEXTURE_CUBE_MAP); + mZeroTextures[GL_TEXTURE_CUBE_MAP].set(this, zeroTextureCube); - if (mClientVersion >= 3) + if (getClientVersion() >= Version(3, 0)) { // TODO: These could also be enabled via extension - Texture *zeroTexture3D = new Texture(mRenderer->createTexture(GL_TEXTURE_3D), 0, GL_TEXTURE_3D); - mZeroTextures[GL_TEXTURE_3D].set(zeroTexture3D); + Texture *zeroTexture3D = new Texture(mImplementation.get(), 0, GL_TEXTURE_3D); + mZeroTextures[GL_TEXTURE_3D].set(this, zeroTexture3D); - Texture *zeroTexture2DArray = new Texture(mRenderer->createTexture(GL_TEXTURE_2D_ARRAY), 0, GL_TEXTURE_2D_ARRAY); - mZeroTextures[GL_TEXTURE_2D_ARRAY].set(zeroTexture2DArray); + Texture *zeroTexture2DArray = new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_ARRAY); + mZeroTextures[GL_TEXTURE_2D_ARRAY].set(this, zeroTexture2DArray); + } + if (getClientVersion() >= Version(3, 1)) + { + Texture *zeroTexture2DMultisample = + new Texture(mImplementation.get(), 0, GL_TEXTURE_2D_MULTISAMPLE); + mZeroTextures[GL_TEXTURE_2D_MULTISAMPLE].set(this, zeroTexture2DMultisample); + + for (unsigned int i = 0; i < mCaps.maxAtomicCounterBufferBindings; i++) + { + bindBufferRange(BufferBinding::AtomicCounter, 0, i, 0, 0); + } + + for (unsigned int i = 0; i < mCaps.maxShaderStorageBufferBindings; i++) + { + bindBufferRange(BufferBinding::ShaderStorage, i, 0, 0, 0); + } } - mState.initializeZeroTextures(mZeroTextures); + const Extensions &nativeExtensions = mImplementation->getNativeExtensions(); + if (nativeExtensions.textureRectangle) + { + Texture *zeroTextureRectangle = + new Texture(mImplementation.get(), 0, GL_TEXTURE_RECTANGLE_ANGLE); + mZeroTextures[GL_TEXTURE_RECTANGLE_ANGLE].set(this, zeroTextureRectangle); + } + + if (nativeExtensions.eglImageExternal || nativeExtensions.eglStreamConsumerExternal) + { + Texture *zeroTextureExternal = + new Texture(mImplementation.get(), 0, GL_TEXTURE_EXTERNAL_OES); + mZeroTextures[GL_TEXTURE_EXTERNAL_OES].set(this, zeroTextureExternal); + } + + mGLState.initializeZeroTextures(this, mZeroTextures); bindVertexArray(0); - bindArrayBuffer(0); - bindElementArrayBuffer(0); - bindRenderbuffer(0); - - bindGenericUniformBuffer(0); - for (unsigned int i = 0; i < mCaps.maxCombinedUniformBlocks; i++) - { - bindIndexedUniformBuffer(0, i, 0, -1); - } - - bindCopyReadBuffer(0); - bindCopyWriteBuffer(0); - bindPixelPackBuffer(0); - bindPixelUnpackBuffer(0); - - if (mClientVersion >= 3) + if (getClientVersion() >= Version(3, 0)) { // [OpenGL ES 3.0.2] section 2.14.1 pg 85: // In the initial state, a default transform feedback object is bound and treated as // a transform feedback object with a name of zero. That object is bound any time // BindTransformFeedback is called with id of zero - bindTransformFeedback(0); + bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0); } - mCompiler = new Compiler(mRenderer, getData()); + for (auto type : angle::AllEnums()) + { + bindBuffer(type, 0); + } + + bindRenderbuffer(GL_RENDERBUFFER, 0); + + for (unsigned int i = 0; i < mCaps.maxUniformBufferBindings; i++) + { + bindBufferRange(BufferBinding::Uniform, i, 0, 0, -1); + } + + // Initialize dirty bit masks + mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_STATE); + mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING); + // No dirty objects. + + // Readpixels uses the pack state and read FBO + mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_STATE); + mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING); + mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER); + + mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED); + mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED); + mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR); + mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT); + mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR); + mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH); + mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL); + mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK); + mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK); + mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT); + mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK); + mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER); + + mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED); + mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR); + mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB); + mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER); + mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER); + + handleError(mImplementation->initialize()); } -Context::~Context() +egl::Error Context::onDestroy(const egl::Display *display) { - mState.reset(); - - for (auto framebuffer : mFramebufferMap) - { - // Default framebuffer are owned by their respective Surface - if (framebuffer.second != nullptr && framebuffer.second->id() != 0) - { - SafeDelete(framebuffer.second); - } - } - for (auto fence : mFenceNVMap) { SafeDelete(fence.second); } + mFenceNVMap.clear(); for (auto query : mQueryMap) { if (query.second != nullptr) { - query.second->release(); + query.second->release(this); } } + mQueryMap.clear(); for (auto vertexArray : mVertexArrayMap) { - SafeDelete(vertexArray.second); + if (vertexArray.second) + { + vertexArray.second->onDestroy(this); + } } + mVertexArrayMap.clear(); for (auto transformFeedback : mTransformFeedbackMap) { if (transformFeedback.second != nullptr) { - transformFeedback.second->release(); + transformFeedback.second->release(this); } } + mTransformFeedbackMap.clear(); for (auto &zeroTexture : mZeroTextures) { - zeroTexture.second.set(NULL); + ANGLE_TRY(zeroTexture.second->onDestroy(this)); + zeroTexture.second.set(this, nullptr); } mZeroTextures.clear(); - if (mCurrentSurface != nullptr) - { - releaseSurface(); - } + SafeDelete(mSurfacelessFramebuffer); - if (mResourceManager) - { - mResourceManager->release(); - } + ANGLE_TRY(releaseSurface(display)); + releaseShaderCompiler(); - SafeDelete(mCompiler); + mGLState.reset(this); + + mState.mBuffers->release(this); + mState.mShaderPrograms->release(this); + mState.mTextures->release(this); + mState.mRenderbuffers->release(this); + mState.mSamplers->release(this); + mState.mSyncs->release(this); + mState.mPaths->release(this); + mState.mFramebuffers->release(this); + mState.mPipelines->release(this); + + mImplementation->onDestroy(this); + + return egl::NoError(); } -void Context::makeCurrent(egl::Surface *surface) +Context::~Context() { - ASSERT(surface != nullptr); +} + +egl::Error Context::makeCurrent(egl::Display *display, egl::Surface *surface) +{ + mCurrentDisplay = display; if (!mHasBeenCurrent) { initRendererString(); + initVersionStrings(); initExtensionStrings(); - mState.setViewportParams(0, 0, surface->getWidth(), surface->getHeight()); - mState.setScissorParams(0, 0, surface->getWidth(), surface->getHeight()); + int width = 0; + int height = 0; + if (surface != nullptr) + { + width = surface->getWidth(); + height = surface->getHeight(); + } + + mGLState.setViewportParams(0, 0, width, height); + mGLState.setScissorParams(0, 0, width, height); mHasBeenCurrent = true; } // TODO(jmadill): Rework this when we support ContextImpl - mState.setAllDirtyBits(); + mGLState.setAllDirtyBits(); + mGLState.setAllDirtyObjects(); - if (mCurrentSurface) + ANGLE_TRY(releaseSurface(display)); + + Framebuffer *newDefault = nullptr; + if (surface != nullptr) { - releaseSurface(); + ANGLE_TRY(surface->setIsCurrent(this, true)); + mCurrentSurface = surface; + newDefault = surface->getDefaultFramebuffer(); + } + else + { + if (mSurfacelessFramebuffer == nullptr) + { + mSurfacelessFramebuffer = new Framebuffer(mImplementation.get()); + } + + newDefault = mSurfacelessFramebuffer; } - surface->setIsCurrent(true); - mCurrentSurface = surface; // Update default framebuffer, the binding of the previous default // framebuffer (or lack of) will have a nullptr. { - Framebuffer *newDefault = surface->getDefaultFramebuffer(); - if (mState.getReadFramebuffer() == nullptr) + if (mGLState.getReadFramebuffer() == nullptr) { - mState.setReadFramebufferBinding(newDefault); + mGLState.setReadFramebufferBinding(newDefault); } - if (mState.getDrawFramebuffer() == nullptr) + if (mGLState.getDrawFramebuffer() == nullptr) { - mState.setDrawFramebufferBinding(newDefault); + mGLState.setDrawFramebufferBinding(newDefault); } - mFramebufferMap[0] = newDefault; + mState.mFramebuffers->setDefaultFramebuffer(newDefault); } // Notify the renderer of a context switch - mRenderer->onMakeCurrent(getData()); + mImplementation->onMakeCurrent(this); + return egl::NoError(); } -void Context::releaseSurface() +egl::Error Context::releaseSurface(const egl::Display *display) { - ASSERT(mCurrentSurface != nullptr); - // Remove the default framebuffer + Framebuffer *currentDefault = nullptr; + if (mCurrentSurface != nullptr) { - Framebuffer *currentDefault = mCurrentSurface->getDefaultFramebuffer(); - if (mState.getReadFramebuffer() == currentDefault) - { - mState.setReadFramebufferBinding(nullptr); - } - if (mState.getDrawFramebuffer() == currentDefault) - { - mState.setDrawFramebufferBinding(nullptr); - } - mFramebufferMap.erase(0); + currentDefault = mCurrentSurface->getDefaultFramebuffer(); + } + else if (mSurfacelessFramebuffer != nullptr) + { + currentDefault = mSurfacelessFramebuffer; } - mCurrentSurface->setIsCurrent(false); - mCurrentSurface = nullptr; -} + if (mGLState.getReadFramebuffer() == currentDefault) + { + mGLState.setReadFramebufferBinding(nullptr); + } + if (mGLState.getDrawFramebuffer() == currentDefault) + { + mGLState.setDrawFramebufferBinding(nullptr); + } + mState.mFramebuffers->setDefaultFramebuffer(nullptr); -// NOTE: this function should not assume that this context is current! -void Context::markContextLost() -{ - if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT) - mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT; - mContextLost = true; -} + if (mCurrentSurface) + { + ANGLE_TRY(mCurrentSurface->setIsCurrent(this, false)); + mCurrentSurface = nullptr; + } -bool Context::isContextLost() -{ - return mContextLost; + return egl::NoError(); } GLuint Context::createBuffer() { - return mResourceManager->createBuffer(); + return mState.mBuffers->createBuffer(); } GLuint Context::createProgram() { - return mResourceManager->createProgram(); + return mState.mShaderPrograms->createProgram(mImplementation.get()); } GLuint Context::createShader(GLenum type) { - return mResourceManager->createShader(mRenderer->getRendererLimitations(), type); + return mState.mShaderPrograms->createShader(mImplementation.get(), mLimitations, type); } GLuint Context::createTexture() { - return mResourceManager->createTexture(); + return mState.mTextures->createTexture(); } GLuint Context::createRenderbuffer() { - return mResourceManager->createRenderbuffer(); + return mState.mRenderbuffers->createRenderbuffer(); } -GLsync Context::createFenceSync() +GLuint Context::createPaths(GLsizei range) { - GLuint handle = mResourceManager->createFenceSync(); - - return reinterpret_cast(static_cast(handle)); -} - -GLuint Context::createVertexArray() -{ - GLuint vertexArray = mVertexArrayHandleAllocator.allocate(); - mVertexArrayMap[vertexArray] = nullptr; - return vertexArray; -} - -GLuint Context::createSampler() -{ - return mResourceManager->createSampler(); -} - -GLuint Context::createTransformFeedback() -{ - GLuint transformFeedback = mTransformFeedbackAllocator.allocate(); - mTransformFeedbackMap[transformFeedback] = nullptr; - return transformFeedback; + auto resultOrError = mState.mPaths->createPaths(mImplementation.get(), range); + if (resultOrError.isError()) + { + handleError(resultOrError.getError()); + return 0; + } + return resultOrError.getResult(); } // Returns an unused framebuffer name GLuint Context::createFramebuffer() { - GLuint handle = mFramebufferHandleAllocator.allocate(); - - mFramebufferMap[handle] = NULL; - - return handle; + return mState.mFramebuffers->createFramebuffer(); } GLuint Context::createFenceNV() { GLuint handle = mFenceNVHandleAllocator.allocate(); - - mFenceNVMap[handle] = new FenceNV(mRenderer->createFenceNV()); - + mFenceNVMap.assign(handle, new FenceNV(mImplementation->createFenceNV())); return handle; } -// Returns an unused query name -GLuint Context::createQuery() +GLuint Context::createProgramPipeline() { - GLuint handle = mQueryHandleAllocator.allocate(); + return mState.mPipelines->createProgramPipeline(); +} - mQueryMap[handle] = NULL; - - return handle; +GLuint Context::createShaderProgramv(GLenum type, GLsizei count, const GLchar *const *strings) +{ + UNIMPLEMENTED(); + return 0u; } void Context::deleteBuffer(GLuint buffer) { - if (mResourceManager->getBuffer(buffer)) + if (mState.mBuffers->getBuffer(buffer)) { detachBuffer(buffer); } - mResourceManager->deleteBuffer(buffer); + mState.mBuffers->deleteObject(this, buffer); } void Context::deleteShader(GLuint shader) { - mResourceManager->deleteShader(shader); + mState.mShaderPrograms->deleteShader(this, shader); } void Context::deleteProgram(GLuint program) { - mResourceManager->deleteProgram(program); + mState.mShaderPrograms->deleteProgram(this, program); } void Context::deleteTexture(GLuint texture) { - if (mResourceManager->getTexture(texture)) + if (mState.mTextures->getTexture(texture)) { detachTexture(texture); } - mResourceManager->deleteTexture(texture); + mState.mTextures->deleteObject(this, texture); } void Context::deleteRenderbuffer(GLuint renderbuffer) { - if (mResourceManager->getRenderbuffer(renderbuffer)) + if (mState.mRenderbuffers->getRenderbuffer(renderbuffer)) { detachRenderbuffer(renderbuffer); } - mResourceManager->deleteRenderbuffer(renderbuffer); + mState.mRenderbuffers->deleteObject(this, renderbuffer); } -void Context::deleteFenceSync(GLsync fenceSync) +void Context::deleteSync(GLsync sync) { // The spec specifies the underlying Fence object is not deleted until all current // wait commands finish. However, since the name becomes invalid, we cannot query the fence, // and since our API is currently designed for being called from a single thread, we can delete // the fence immediately. - mResourceManager->deleteFenceSync(static_cast(reinterpret_cast(fenceSync))); + mState.mSyncs->deleteObject(this, static_cast(reinterpret_cast(sync))); } -void Context::deleteVertexArray(GLuint vertexArray) +void Context::deleteProgramPipeline(GLuint pipeline) { - auto iter = mVertexArrayMap.find(vertexArray); - if (iter != mVertexArrayMap.end()) + if (mState.mPipelines->getProgramPipeline(pipeline)) { - VertexArray *vertexArrayObject = iter->second; - if (vertexArrayObject != nullptr) - { - detachVertexArray(vertexArray); - delete vertexArrayObject; - } + detachProgramPipeline(pipeline); + } - mVertexArrayMap.erase(iter); - mVertexArrayHandleAllocator.release(vertexArray); + mState.mPipelines->deleteObject(this, pipeline); +} + +void Context::deletePaths(GLuint first, GLsizei range) +{ + mState.mPaths->deletePaths(first, range); +} + +bool Context::hasPathData(GLuint path) const +{ + const auto *pathObj = mState.mPaths->getPath(path); + if (pathObj == nullptr) + return false; + + return pathObj->hasPathData(); +} + +bool Context::hasPath(GLuint path) const +{ + return mState.mPaths->hasPath(path); +} + +void Context::setPathCommands(GLuint path, + GLsizei numCommands, + const GLubyte *commands, + GLsizei numCoords, + GLenum coordType, + const void *coords) +{ + auto *pathObject = mState.mPaths->getPath(path); + + handleError(pathObject->setCommands(numCommands, commands, numCoords, coordType, coords)); +} + +void Context::setPathParameterf(GLuint path, GLenum pname, GLfloat value) +{ + auto *pathObj = mState.mPaths->getPath(path); + + switch (pname) + { + case GL_PATH_STROKE_WIDTH_CHROMIUM: + pathObj->setStrokeWidth(value); + break; + case GL_PATH_END_CAPS_CHROMIUM: + pathObj->setEndCaps(static_cast(value)); + break; + case GL_PATH_JOIN_STYLE_CHROMIUM: + pathObj->setJoinStyle(static_cast(value)); + break; + case GL_PATH_MITER_LIMIT_CHROMIUM: + pathObj->setMiterLimit(value); + break; + case GL_PATH_STROKE_BOUND_CHROMIUM: + pathObj->setStrokeBound(value); + break; + default: + UNREACHABLE(); + break; } } -void Context::deleteSampler(GLuint sampler) +void Context::getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const { - if (mResourceManager->getSampler(sampler)) - { - detachSampler(sampler); - } + const auto *pathObj = mState.mPaths->getPath(path); - mResourceManager->deleteSampler(sampler); + switch (pname) + { + case GL_PATH_STROKE_WIDTH_CHROMIUM: + *value = pathObj->getStrokeWidth(); + break; + case GL_PATH_END_CAPS_CHROMIUM: + *value = static_cast(pathObj->getEndCaps()); + break; + case GL_PATH_JOIN_STYLE_CHROMIUM: + *value = static_cast(pathObj->getJoinStyle()); + break; + case GL_PATH_MITER_LIMIT_CHROMIUM: + *value = pathObj->getMiterLimit(); + break; + case GL_PATH_STROKE_BOUND_CHROMIUM: + *value = pathObj->getStrokeBound(); + break; + default: + UNREACHABLE(); + break; + } } -void Context::deleteTransformFeedback(GLuint transformFeedback) +void Context::setPathStencilFunc(GLenum func, GLint ref, GLuint mask) { - auto iter = mTransformFeedbackMap.find(transformFeedback); - if (iter != mTransformFeedbackMap.end()) - { - TransformFeedback *transformFeedbackObject = iter->second; - if (transformFeedbackObject != nullptr) - { - detachTransformFeedback(transformFeedback); - transformFeedbackObject->release(); - } - - mTransformFeedbackMap.erase(iter); - mTransformFeedbackAllocator.release(transformFeedback); - } + mGLState.setPathStencilFunc(func, ref, mask); } void Context::deleteFramebuffer(GLuint framebuffer) { - FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer); - - if (framebufferObject != mFramebufferMap.end()) + if (mState.mFramebuffers->getFramebuffer(framebuffer)) { detachFramebuffer(framebuffer); - - mFramebufferHandleAllocator.release(framebufferObject->first); - delete framebufferObject->second; - mFramebufferMap.erase(framebufferObject); } + + mState.mFramebuffers->deleteObject(this, framebuffer); } void Context::deleteFenceNV(GLuint fence) { - FenceNVMap::iterator fenceObject = mFenceNVMap.find(fence); - - if (fenceObject != mFenceNVMap.end()) + FenceNV *fenceObject = nullptr; + if (mFenceNVMap.erase(fence, &fenceObject)) { - mFenceNVHandleAllocator.release(fenceObject->first); - delete fenceObject->second; - mFenceNVMap.erase(fenceObject); - } -} - -void Context::deleteQuery(GLuint query) -{ - QueryMap::iterator queryObject = mQueryMap.find(query); - if (queryObject != mQueryMap.end()) - { - mQueryHandleAllocator.release(queryObject->first); - if (queryObject->second) - { - queryObject->second->release(); - } - mQueryMap.erase(queryObject); + mFenceNVHandleAllocator.release(fence); + delete fenceObject; } } Buffer *Context::getBuffer(GLuint handle) const { - return mResourceManager->getBuffer(handle); -} - -Shader *Context::getShader(GLuint handle) const -{ - return mResourceManager->getShader(handle); -} - -Program *Context::getProgram(GLuint handle) const -{ - return mResourceManager->getProgram(handle); + return mState.mBuffers->getBuffer(handle); } Texture *Context::getTexture(GLuint handle) const { - return mResourceManager->getTexture(handle); + return mState.mTextures->getTexture(handle); } Renderbuffer *Context::getRenderbuffer(GLuint handle) const { - return mResourceManager->getRenderbuffer(handle); + return mState.mRenderbuffers->getRenderbuffer(handle); } -FenceSync *Context::getFenceSync(GLsync handle) const +Sync *Context::getSync(GLsync handle) const { - return mResourceManager->getFenceSync(static_cast(reinterpret_cast(handle))); + return mState.mSyncs->getSync(static_cast(reinterpret_cast(handle))); } VertexArray *Context::getVertexArray(GLuint handle) const { - auto vertexArray = mVertexArrayMap.find(handle); - return (vertexArray != mVertexArrayMap.end()) ? vertexArray->second : nullptr; + return mVertexArrayMap.query(handle); } Sampler *Context::getSampler(GLuint handle) const { - return mResourceManager->getSampler(handle); + return mState.mSamplers->getSampler(handle); } TransformFeedback *Context::getTransformFeedback(GLuint handle) const { - auto iter = mTransformFeedbackMap.find(handle); - return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr; + return mTransformFeedbackMap.query(handle); +} + +ProgramPipeline *Context::getProgramPipeline(GLuint handle) const +{ + return mState.mPipelines->getProgramPipeline(handle); } LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const @@ -648,31 +881,64 @@ LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const { - return getFenceSync(reinterpret_cast(const_cast(ptr))); + return getSync(reinterpret_cast(const_cast(ptr))); +} + +void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label) +{ + LabeledObject *object = getLabeledObject(identifier, name); + ASSERT(object != nullptr); + + std::string labelName = GetObjectLabelFromPointer(length, label); + object->setLabel(labelName); + + // TODO(jmadill): Determine if the object is dirty based on 'name'. Conservatively assume the + // specified object is active until we do this. + mGLState.setObjectDirty(identifier); +} + +void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label) +{ + LabeledObject *object = getLabeledObjectFromPtr(ptr); + ASSERT(object != nullptr); + + std::string labelName = GetObjectLabelFromPointer(length, label); + object->setLabel(labelName); +} + +void Context::getObjectLabel(GLenum identifier, + GLuint name, + GLsizei bufSize, + GLsizei *length, + GLchar *label) const +{ + LabeledObject *object = getLabeledObject(identifier, name); + ASSERT(object != nullptr); + + const std::string &objectLabel = object->getLabel(); + GetObjectLabelBase(objectLabel, bufSize, length, label); +} + +void Context::getObjectPtrLabel(const void *ptr, + GLsizei bufSize, + GLsizei *length, + GLchar *label) const +{ + LabeledObject *object = getLabeledObjectFromPtr(ptr); + ASSERT(object != nullptr); + + const std::string &objectLabel = object->getLabel(); + GetObjectLabelBase(objectLabel, bufSize, length, label); } bool Context::isSampler(GLuint samplerName) const { - return mResourceManager->isSampler(samplerName); -} - -void Context::bindArrayBuffer(unsigned int buffer) -{ - mResourceManager->checkBufferAllocation(buffer); - - mState.setArrayBufferBinding(getBuffer(buffer)); -} - -void Context::bindElementArrayBuffer(unsigned int buffer) -{ - mResourceManager->checkBufferAllocation(buffer); - - mState.getVertexArray()->setElementArrayBuffer(getBuffer(buffer)); + return mState.mSamplers->isSampler(samplerName); } void Context::bindTexture(GLenum target, GLuint handle) { - Texture *texture = NULL; + Texture *texture = nullptr; if (handle == 0) { @@ -680,156 +946,118 @@ void Context::bindTexture(GLenum target, GLuint handle) } else { - mResourceManager->checkTextureAllocation(handle, target); - texture = getTexture(handle); + texture = mState.mTextures->checkTextureAllocation(mImplementation.get(), handle, target); } ASSERT(texture); - - mState.setSamplerTexture(target, texture); + mGLState.setSamplerTexture(this, target, texture); } void Context::bindReadFramebuffer(GLuint framebufferHandle) { - Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle); - mState.setReadFramebufferBinding(framebuffer); + Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation( + mImplementation.get(), mCaps, framebufferHandle); + mGLState.setReadFramebufferBinding(framebuffer); } void Context::bindDrawFramebuffer(GLuint framebufferHandle) { - Framebuffer *framebuffer = checkFramebufferAllocation(framebufferHandle); - mState.setDrawFramebufferBinding(framebuffer); + Framebuffer *framebuffer = mState.mFramebuffers->checkFramebufferAllocation( + mImplementation.get(), mCaps, framebufferHandle); + mGLState.setDrawFramebufferBinding(framebuffer); } -void Context::bindRenderbuffer(GLuint renderbuffer) +void Context::bindVertexArray(GLuint vertexArrayHandle) { - mResourceManager->checkRenderbufferAllocation(renderbuffer); - - mState.setRenderbufferBinding(getRenderbuffer(renderbuffer)); + VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle); + mGLState.setVertexArrayBinding(vertexArray); } -void Context::bindVertexArray(GLuint vertexArray) +void Context::bindVertexBuffer(GLuint bindingIndex, + GLuint bufferHandle, + GLintptr offset, + GLsizei stride) { - checkVertexArrayAllocation(vertexArray); - - mState.setVertexArrayBinding(getVertexArray(vertexArray)); + Buffer *buffer = mState.mBuffers->checkBufferAllocation(mImplementation.get(), bufferHandle); + mGLState.bindVertexBuffer(this, bindingIndex, buffer, offset, stride); } -void Context::bindSampler(GLuint textureUnit, GLuint sampler) +void Context::bindSampler(GLuint textureUnit, GLuint samplerHandle) { ASSERT(textureUnit < mCaps.maxCombinedTextureImageUnits); - mResourceManager->checkSamplerAllocation(sampler); - - mState.setSamplerBinding(textureUnit, getSampler(sampler)); + Sampler *sampler = + mState.mSamplers->checkSamplerAllocation(mImplementation.get(), samplerHandle); + mGLState.setSamplerBinding(this, textureUnit, sampler); } -void Context::bindGenericUniformBuffer(GLuint buffer) +void Context::bindImageTexture(GLuint unit, + GLuint texture, + GLint level, + GLboolean layered, + GLint layer, + GLenum access, + GLenum format) { - mResourceManager->checkBufferAllocation(buffer); - - mState.setGenericUniformBufferBinding(getBuffer(buffer)); -} - -void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size) -{ - mResourceManager->checkBufferAllocation(buffer); - - mState.setIndexedUniformBufferBinding(index, getBuffer(buffer), offset, size); -} - -void Context::bindGenericTransformFeedbackBuffer(GLuint buffer) -{ - mResourceManager->checkBufferAllocation(buffer); - - mState.getCurrentTransformFeedback()->bindGenericBuffer(getBuffer(buffer)); -} - -void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size) -{ - mResourceManager->checkBufferAllocation(buffer); - - mState.getCurrentTransformFeedback()->bindIndexedBuffer(index, getBuffer(buffer), offset, size); -} - -void Context::bindCopyReadBuffer(GLuint buffer) -{ - mResourceManager->checkBufferAllocation(buffer); - - mState.setCopyReadBufferBinding(getBuffer(buffer)); -} - -void Context::bindCopyWriteBuffer(GLuint buffer) -{ - mResourceManager->checkBufferAllocation(buffer); - - mState.setCopyWriteBufferBinding(getBuffer(buffer)); -} - -void Context::bindPixelPackBuffer(GLuint buffer) -{ - mResourceManager->checkBufferAllocation(buffer); - - mState.setPixelPackBufferBinding(getBuffer(buffer)); -} - -void Context::bindPixelUnpackBuffer(GLuint buffer) -{ - mResourceManager->checkBufferAllocation(buffer); - - mState.setPixelUnpackBufferBinding(getBuffer(buffer)); + Texture *tex = mState.mTextures->getTexture(texture); + mGLState.setImageUnit(this, unit, tex, level, layered, layer, access, format); } void Context::useProgram(GLuint program) { - mState.setProgram(getProgram(program)); + mGLState.setProgram(this, getProgram(program)); } -void Context::bindTransformFeedback(GLuint transformFeedback) +void Context::useProgramStages(GLuint pipeline, GLbitfield stages, GLuint program) { - checkTransformFeedbackAllocation(transformFeedback); - - mState.setTransformFeedbackBinding(getTransformFeedback(transformFeedback)); + UNIMPLEMENTED(); } -Error Context::beginQuery(GLenum target, GLuint query) +void Context::bindTransformFeedback(GLenum target, GLuint transformFeedbackHandle) +{ + ASSERT(target == GL_TRANSFORM_FEEDBACK); + TransformFeedback *transformFeedback = + checkTransformFeedbackAllocation(transformFeedbackHandle); + mGLState.setTransformFeedbackBinding(this, transformFeedback); +} + +void Context::bindProgramPipeline(GLuint pipelineHandle) +{ + ProgramPipeline *pipeline = + mState.mPipelines->checkProgramPipelineAllocation(mImplementation.get(), pipelineHandle); + mGLState.setProgramPipelineBinding(this, pipeline); +} + +void Context::beginQuery(GLenum target, GLuint query) { Query *queryObject = getQuery(query, true, target); ASSERT(queryObject); // begin query - Error error = queryObject->begin(); - if (error.isError()) - { - return error; - } + ANGLE_CONTEXT_TRY(queryObject->begin()); // set query as active for specified target only if begin succeeded - mState.setActiveQuery(target, queryObject); - - return Error(GL_NO_ERROR); + mGLState.setActiveQuery(this, target, queryObject); } -Error Context::endQuery(GLenum target) +void Context::endQuery(GLenum target) { - Query *queryObject = mState.getActiveQuery(target); + Query *queryObject = mGLState.getActiveQuery(target); ASSERT(queryObject); - gl::Error error = queryObject->end(); + handleError(queryObject->end()); // Always unbind the query, even if there was an error. This may delete the query object. - mState.setActiveQuery(target, NULL); - - return error; + mGLState.setActiveQuery(this, target, nullptr); } -Error Context::queryCounter(GLuint id, GLenum target) +void Context::queryCounter(GLuint id, GLenum target) { ASSERT(target == GL_TIMESTAMP_EXT); Query *queryObject = getQuery(id, true, target); ASSERT(queryObject); - return queryObject->queryCounter(); + handleError(queryObject->queryCounter()); } void Context::getQueryiv(GLenum target, GLenum pname, GLint *params) @@ -837,7 +1065,7 @@ void Context::getQueryiv(GLenum target, GLenum pname, GLint *params) switch (pname) { case GL_CURRENT_QUERY_EXT: - params[0] = getState().getActiveQueryId(target); + params[0] = mGLState.getActiveQueryId(target); break; case GL_QUERY_COUNTER_BITS_EXT: switch (target) @@ -860,763 +1088,992 @@ void Context::getQueryiv(GLenum target, GLenum pname, GLint *params) } } -Error Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params) +void Context::getQueryObjectiv(GLuint id, GLenum pname, GLint *params) { - return GetQueryObjectParameter(this, id, pname, params); + handleError(GetQueryObjectParameter(getQuery(id), pname, params)); } -Error Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params) +void Context::getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params) { - return GetQueryObjectParameter(this, id, pname, params); + handleError(GetQueryObjectParameter(getQuery(id), pname, params)); } -Error Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params) +void Context::getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params) { - return GetQueryObjectParameter(this, id, pname, params); + handleError(GetQueryObjectParameter(getQuery(id), pname, params)); } -Error Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params) +void Context::getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params) { - return GetQueryObjectParameter(this, id, pname, params); + handleError(GetQueryObjectParameter(getQuery(id), pname, params)); } -Framebuffer *Context::getFramebuffer(unsigned int handle) const +Framebuffer *Context::getFramebuffer(GLuint handle) const { - auto framebufferIt = mFramebufferMap.find(handle); - return ((framebufferIt == mFramebufferMap.end()) ? nullptr : framebufferIt->second); + return mState.mFramebuffers->getFramebuffer(handle); } -FenceNV *Context::getFenceNV(unsigned int handle) +FenceNV *Context::getFenceNV(GLuint handle) { - FenceNVMap::iterator fence = mFenceNVMap.find(handle); + return mFenceNVMap.query(handle); +} - if (fence == mFenceNVMap.end()) +Query *Context::getQuery(GLuint handle, bool create, GLenum type) +{ + if (!mQueryMap.contains(handle)) { - return NULL; + return nullptr; } - else - { - return fence->second; - } -} -Query *Context::getQuery(unsigned int handle, bool create, GLenum type) -{ - QueryMap::iterator query = mQueryMap.find(handle); - - if (query == mQueryMap.end()) + Query *query = mQueryMap.query(handle); + if (!query && create) { - return NULL; - } - else - { - if (!query->second && create) - { - query->second = new Query(mRenderer->createQuery(type), handle); - query->second->addRef(); - } - return query->second; + query = new Query(mImplementation->createQuery(type), handle); + query->addRef(); + mQueryMap.assign(handle, query); } + return query; } Query *Context::getQuery(GLuint handle) const { - auto iter = mQueryMap.find(handle); - return (iter != mQueryMap.end()) ? iter->second : nullptr; + return mQueryMap.query(handle); } Texture *Context::getTargetTexture(GLenum target) const { - ASSERT(ValidTextureTarget(this, target)); - return mState.getTargetTexture(target); + ASSERT(ValidTextureTarget(this, target) || ValidTextureExternalTarget(this, target)); + return mGLState.getTargetTexture(target); } Texture *Context::getSamplerTexture(unsigned int sampler, GLenum type) const { - return mState.getSamplerTexture(sampler, type); + return mGLState.getSamplerTexture(sampler, type); } Compiler *Context::getCompiler() const { - return mCompiler; + if (mCompiler.get() == nullptr) + { + mCompiler.set(this, new Compiler(mImplementation.get(), mState)); + } + return mCompiler.get(); } -void Context::getBooleanv(GLenum pname, GLboolean *params) +void Context::getBooleanvImpl(GLenum pname, GLboolean *params) { switch (pname) { - case GL_SHADER_COMPILER: *params = GL_TRUE; break; - case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break; - default: - mState.getBooleanv(pname, params); - break; + case GL_SHADER_COMPILER: + *params = GL_TRUE; + break; + case GL_CONTEXT_ROBUST_ACCESS_EXT: + *params = mRobustAccess ? GL_TRUE : GL_FALSE; + break; + default: + mGLState.getBooleanv(pname, params); + break; } } -void Context::getFloatv(GLenum pname, GLfloat *params) +void Context::getFloatvImpl(GLenum pname, GLfloat *params) { // Queries about context capabilities and maximums are answered by Context. // Queries about current GL state values are answered by State. switch (pname) { - case GL_ALIASED_LINE_WIDTH_RANGE: - params[0] = mCaps.minAliasedLineWidth; - params[1] = mCaps.maxAliasedLineWidth; - break; - case GL_ALIASED_POINT_SIZE_RANGE: - params[0] = mCaps.minAliasedPointSize; - params[1] = mCaps.maxAliasedPointSize; - break; - case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: - ASSERT(mExtensions.textureFilterAnisotropic); - *params = mExtensions.maxTextureAnisotropy; - break; - case GL_MAX_TEXTURE_LOD_BIAS: - *params = mCaps.maxLODBias; - break; - default: - mState.getFloatv(pname, params); + case GL_ALIASED_LINE_WIDTH_RANGE: + params[0] = mCaps.minAliasedLineWidth; + params[1] = mCaps.maxAliasedLineWidth; + break; + case GL_ALIASED_POINT_SIZE_RANGE: + params[0] = mCaps.minAliasedPointSize; + params[1] = mCaps.maxAliasedPointSize; + break; + case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: + ASSERT(mExtensions.textureFilterAnisotropic); + *params = mExtensions.maxTextureAnisotropy; + break; + case GL_MAX_TEXTURE_LOD_BIAS: + *params = mCaps.maxLODBias; + break; + + case GL_PATH_MODELVIEW_MATRIX_CHROMIUM: + case GL_PATH_PROJECTION_MATRIX_CHROMIUM: + { + ASSERT(mExtensions.pathRendering); + const GLfloat *m = mGLState.getPathRenderingMatrix(pname); + memcpy(params, m, 16 * sizeof(GLfloat)); + } break; + + default: + mGLState.getFloatv(pname, params); + break; } } -void Context::getIntegerv(GLenum pname, GLint *params) +void Context::getIntegervImpl(GLenum pname, GLint *params) { // Queries about context capabilities and maximums are answered by Context. // Queries about current GL state values are answered by State. switch (pname) { - case GL_MAX_VERTEX_ATTRIBS: *params = mCaps.maxVertexAttributes; break; - case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mCaps.maxVertexUniformVectors; break; - case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = mCaps.maxVertexUniformComponents; break; - case GL_MAX_VARYING_VECTORS: *params = mCaps.maxVaryingVectors; break; - case GL_MAX_VARYING_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break; - case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mCaps.maxCombinedTextureImageUnits; break; - case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxVertexTextureImageUnits; break; - case GL_MAX_TEXTURE_IMAGE_UNITS: *params = mCaps.maxTextureImageUnits; break; - case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mCaps.maxFragmentUniformVectors; break; - case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = mCaps.maxFragmentUniformComponents; break; - case GL_MAX_RENDERBUFFER_SIZE: *params = mCaps.maxRenderbufferSize; break; - case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mCaps.maxColorAttachments; break; - case GL_MAX_DRAW_BUFFERS_EXT: *params = mCaps.maxDrawBuffers; break; - //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE - case GL_SUBPIXEL_BITS: *params = 4; break; - case GL_MAX_TEXTURE_SIZE: *params = mCaps.max2DTextureSize; break; - case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = mCaps.maxCubeMapTextureSize; break; - case GL_MAX_3D_TEXTURE_SIZE: *params = mCaps.max3DTextureSize; break; - case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = mCaps.maxArrayTextureLayers; break; - case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: *params = mCaps.uniformBufferOffsetAlignment; break; - case GL_MAX_UNIFORM_BUFFER_BINDINGS: *params = mCaps.maxUniformBufferBindings; break; - case GL_MAX_VERTEX_UNIFORM_BLOCKS: *params = mCaps.maxVertexUniformBlocks; break; - case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: *params = mCaps.maxFragmentUniformBlocks; break; - case GL_MAX_COMBINED_UNIFORM_BLOCKS: *params = mCaps.maxCombinedTextureImageUnits; break; - case GL_MAX_VERTEX_OUTPUT_COMPONENTS: *params = mCaps.maxVertexOutputComponents; break; - case GL_MAX_FRAGMENT_INPUT_COMPONENTS: *params = mCaps.maxFragmentInputComponents; break; - case GL_MIN_PROGRAM_TEXEL_OFFSET: *params = mCaps.minProgramTexelOffset; break; - case GL_MAX_PROGRAM_TEXEL_OFFSET: *params = mCaps.maxProgramTexelOffset; break; - case GL_MAJOR_VERSION: *params = mClientVersion; break; - case GL_MINOR_VERSION: *params = 0; break; - case GL_MAX_ELEMENTS_INDICES: *params = mCaps.maxElementsIndices; break; - case GL_MAX_ELEMENTS_VERTICES: *params = mCaps.maxElementsVertices; break; - case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mCaps.maxTransformFeedbackInterleavedComponents; break; - case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: *params = mCaps.maxTransformFeedbackSeparateAttributes; break; - case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: *params = mCaps.maxTransformFeedbackSeparateComponents; break; - case GL_NUM_COMPRESSED_TEXTURE_FORMATS: - *params = static_cast(mCaps.compressedTextureFormats.size()); - break; - case GL_MAX_SAMPLES_ANGLE: *params = mCaps.maxSamples; break; - case GL_MAX_VIEWPORT_DIMS: + case GL_MAX_VERTEX_ATTRIBS: + *params = mCaps.maxVertexAttributes; + break; + case GL_MAX_VERTEX_UNIFORM_VECTORS: + *params = mCaps.maxVertexUniformVectors; + break; + case GL_MAX_VERTEX_UNIFORM_COMPONENTS: + *params = mCaps.maxVertexUniformComponents; + break; + case GL_MAX_VARYING_VECTORS: + *params = mCaps.maxVaryingVectors; + break; + case GL_MAX_VARYING_COMPONENTS: + *params = mCaps.maxVertexOutputComponents; + break; + case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: + *params = mCaps.maxCombinedTextureImageUnits; + break; + case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: + *params = mCaps.maxVertexTextureImageUnits; + break; + case GL_MAX_TEXTURE_IMAGE_UNITS: + *params = mCaps.maxTextureImageUnits; + break; + case GL_MAX_FRAGMENT_UNIFORM_VECTORS: + *params = mCaps.maxFragmentUniformVectors; + break; + case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: + *params = mCaps.maxFragmentUniformComponents; + break; + case GL_MAX_RENDERBUFFER_SIZE: + *params = mCaps.maxRenderbufferSize; + break; + case GL_MAX_COLOR_ATTACHMENTS_EXT: + *params = mCaps.maxColorAttachments; + break; + case GL_MAX_DRAW_BUFFERS_EXT: + *params = mCaps.maxDrawBuffers; + break; + // case GL_FRAMEBUFFER_BINDING: // now equivalent to + // GL_DRAW_FRAMEBUFFER_BINDING_ANGLE + case GL_SUBPIXEL_BITS: + *params = 4; + break; + case GL_MAX_TEXTURE_SIZE: + *params = mCaps.max2DTextureSize; + break; + case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE: + *params = mCaps.maxRectangleTextureSize; + break; + case GL_MAX_CUBE_MAP_TEXTURE_SIZE: + *params = mCaps.maxCubeMapTextureSize; + break; + case GL_MAX_3D_TEXTURE_SIZE: + *params = mCaps.max3DTextureSize; + break; + case GL_MAX_ARRAY_TEXTURE_LAYERS: + *params = mCaps.maxArrayTextureLayers; + break; + case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: + *params = mCaps.uniformBufferOffsetAlignment; + break; + case GL_MAX_UNIFORM_BUFFER_BINDINGS: + *params = mCaps.maxUniformBufferBindings; + break; + case GL_MAX_VERTEX_UNIFORM_BLOCKS: + *params = mCaps.maxVertexUniformBlocks; + break; + case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: + *params = mCaps.maxFragmentUniformBlocks; + break; + case GL_MAX_COMBINED_UNIFORM_BLOCKS: + *params = mCaps.maxCombinedTextureImageUnits; + break; + case GL_MAX_VERTEX_OUTPUT_COMPONENTS: + *params = mCaps.maxVertexOutputComponents; + break; + case GL_MAX_FRAGMENT_INPUT_COMPONENTS: + *params = mCaps.maxFragmentInputComponents; + break; + case GL_MIN_PROGRAM_TEXEL_OFFSET: + *params = mCaps.minProgramTexelOffset; + break; + case GL_MAX_PROGRAM_TEXEL_OFFSET: + *params = mCaps.maxProgramTexelOffset; + break; + case GL_MAJOR_VERSION: + *params = getClientVersion().major; + break; + case GL_MINOR_VERSION: + *params = getClientVersion().minor; + break; + case GL_MAX_ELEMENTS_INDICES: + *params = mCaps.maxElementsIndices; + break; + case GL_MAX_ELEMENTS_VERTICES: + *params = mCaps.maxElementsVertices; + break; + case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: + *params = mCaps.maxTransformFeedbackInterleavedComponents; + break; + case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: + *params = mCaps.maxTransformFeedbackSeparateAttributes; + break; + case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: + *params = mCaps.maxTransformFeedbackSeparateComponents; + break; + case GL_NUM_COMPRESSED_TEXTURE_FORMATS: + *params = static_cast(mCaps.compressedTextureFormats.size()); + break; + case GL_MAX_SAMPLES_ANGLE: + *params = mCaps.maxSamples; + break; + case GL_MAX_VIEWPORT_DIMS: { params[0] = mCaps.maxViewportWidth; params[1] = mCaps.maxViewportHeight; } break; - case GL_COMPRESSED_TEXTURE_FORMATS: - std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), params); - break; - case GL_RESET_NOTIFICATION_STRATEGY_EXT: - *params = mResetStrategy; - break; - case GL_NUM_SHADER_BINARY_FORMATS: - *params = static_cast(mCaps.shaderBinaryFormats.size()); - break; - case GL_SHADER_BINARY_FORMATS: - std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params); - break; - case GL_NUM_PROGRAM_BINARY_FORMATS: - *params = static_cast(mCaps.programBinaryFormats.size()); - break; - case GL_PROGRAM_BINARY_FORMATS: - std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params); - break; - case GL_NUM_EXTENSIONS: - *params = static_cast(mExtensionStrings.size()); - break; + case GL_COMPRESSED_TEXTURE_FORMATS: + std::copy(mCaps.compressedTextureFormats.begin(), mCaps.compressedTextureFormats.end(), + params); + break; + case GL_RESET_NOTIFICATION_STRATEGY_EXT: + *params = mResetStrategy; + break; + case GL_NUM_SHADER_BINARY_FORMATS: + *params = static_cast(mCaps.shaderBinaryFormats.size()); + break; + case GL_SHADER_BINARY_FORMATS: + std::copy(mCaps.shaderBinaryFormats.begin(), mCaps.shaderBinaryFormats.end(), params); + break; + case GL_NUM_PROGRAM_BINARY_FORMATS: + *params = static_cast(mCaps.programBinaryFormats.size()); + break; + case GL_PROGRAM_BINARY_FORMATS: + std::copy(mCaps.programBinaryFormats.begin(), mCaps.programBinaryFormats.end(), params); + break; + case GL_NUM_EXTENSIONS: + *params = static_cast(mExtensionStrings.size()); + break; - // GL_KHR_debug - case GL_MAX_DEBUG_MESSAGE_LENGTH: - *params = mExtensions.maxDebugMessageLength; - break; - case GL_MAX_DEBUG_LOGGED_MESSAGES: - *params = mExtensions.maxDebugLoggedMessages; - break; - case GL_MAX_DEBUG_GROUP_STACK_DEPTH: - *params = mExtensions.maxDebugGroupStackDepth; - break; - case GL_MAX_LABEL_LENGTH: - *params = mExtensions.maxLabelLength; - break; + // GL_KHR_debug + case GL_MAX_DEBUG_MESSAGE_LENGTH: + *params = mExtensions.maxDebugMessageLength; + break; + case GL_MAX_DEBUG_LOGGED_MESSAGES: + *params = mExtensions.maxDebugLoggedMessages; + break; + case GL_MAX_DEBUG_GROUP_STACK_DEPTH: + *params = mExtensions.maxDebugGroupStackDepth; + break; + case GL_MAX_LABEL_LENGTH: + *params = mExtensions.maxLabelLength; + break; - // GL_EXT_disjoint_timer_query - case GL_GPU_DISJOINT_EXT: - *params = mRenderer->getGPUDisjoint(); - break; + // GL_ANGLE_multiview + case GL_MAX_VIEWS_ANGLE: + *params = mExtensions.maxViews; + break; - default: - mState.getIntegerv(getData(), pname, params); - break; + // GL_EXT_disjoint_timer_query + case GL_GPU_DISJOINT_EXT: + *params = mImplementation->getGPUDisjoint(); + break; + case GL_MAX_FRAMEBUFFER_WIDTH: + *params = mCaps.maxFramebufferWidth; + break; + case GL_MAX_FRAMEBUFFER_HEIGHT: + *params = mCaps.maxFramebufferHeight; + break; + case GL_MAX_FRAMEBUFFER_SAMPLES: + *params = mCaps.maxFramebufferSamples; + break; + case GL_MAX_SAMPLE_MASK_WORDS: + *params = mCaps.maxSampleMaskWords; + break; + case GL_MAX_COLOR_TEXTURE_SAMPLES: + *params = mCaps.maxColorTextureSamples; + break; + case GL_MAX_DEPTH_TEXTURE_SAMPLES: + *params = mCaps.maxDepthTextureSamples; + break; + case GL_MAX_INTEGER_SAMPLES: + *params = mCaps.maxIntegerSamples; + break; + case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET: + *params = mCaps.maxVertexAttribRelativeOffset; + break; + case GL_MAX_VERTEX_ATTRIB_BINDINGS: + *params = mCaps.maxVertexAttribBindings; + break; + case GL_MAX_VERTEX_ATTRIB_STRIDE: + *params = mCaps.maxVertexAttribStride; + break; + case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS: + *params = mCaps.maxVertexAtomicCounterBuffers; + break; + case GL_MAX_VERTEX_ATOMIC_COUNTERS: + *params = mCaps.maxVertexAtomicCounters; + break; + case GL_MAX_VERTEX_IMAGE_UNIFORMS: + *params = mCaps.maxVertexImageUniforms; + break; + case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS: + *params = mCaps.maxVertexShaderStorageBlocks; + break; + case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS: + *params = mCaps.maxFragmentAtomicCounterBuffers; + break; + case GL_MAX_FRAGMENT_ATOMIC_COUNTERS: + *params = mCaps.maxFragmentAtomicCounters; + break; + case GL_MAX_FRAGMENT_IMAGE_UNIFORMS: + *params = mCaps.maxFragmentImageUniforms; + break; + case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS: + *params = mCaps.maxFragmentShaderStorageBlocks; + break; + case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET: + *params = mCaps.minProgramTextureGatherOffset; + break; + case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET: + *params = mCaps.maxProgramTextureGatherOffset; + break; + case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS: + *params = mCaps.maxComputeWorkGroupInvocations; + break; + case GL_MAX_COMPUTE_UNIFORM_BLOCKS: + *params = mCaps.maxComputeUniformBlocks; + break; + case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS: + *params = mCaps.maxComputeTextureImageUnits; + break; + case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE: + *params = mCaps.maxComputeSharedMemorySize; + break; + case GL_MAX_COMPUTE_UNIFORM_COMPONENTS: + *params = mCaps.maxComputeUniformComponents; + break; + case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS: + *params = mCaps.maxComputeAtomicCounterBuffers; + break; + case GL_MAX_COMPUTE_ATOMIC_COUNTERS: + *params = mCaps.maxComputeAtomicCounters; + break; + case GL_MAX_COMPUTE_IMAGE_UNIFORMS: + *params = mCaps.maxComputeImageUniforms; + break; + case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS: + *params = mCaps.maxCombinedComputeUniformComponents; + break; + case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS: + *params = mCaps.maxComputeShaderStorageBlocks; + break; + case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES: + *params = mCaps.maxCombinedShaderOutputResources; + break; + case GL_MAX_UNIFORM_LOCATIONS: + *params = mCaps.maxUniformLocations; + break; + case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS: + *params = mCaps.maxAtomicCounterBufferBindings; + break; + case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE: + *params = mCaps.maxAtomicCounterBufferSize; + break; + case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS: + *params = mCaps.maxCombinedAtomicCounterBuffers; + break; + case GL_MAX_COMBINED_ATOMIC_COUNTERS: + *params = mCaps.maxCombinedAtomicCounters; + break; + case GL_MAX_IMAGE_UNITS: + *params = mCaps.maxImageUnits; + break; + case GL_MAX_COMBINED_IMAGE_UNIFORMS: + *params = mCaps.maxCombinedImageUniforms; + break; + case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS: + *params = mCaps.maxShaderStorageBufferBindings; + break; + case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS: + *params = mCaps.maxCombinedShaderStorageBlocks; + break; + case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT: + *params = mCaps.shaderStorageBufferOffsetAlignment; + break; + default: + mGLState.getIntegerv(this, pname, params); + break; } } -void Context::getInteger64v(GLenum pname, GLint64 *params) +void Context::getInteger64vImpl(GLenum pname, GLint64 *params) { // Queries about context capabilities and maximums are answered by Context. // Queries about current GL state values are answered by State. switch (pname) { - case GL_MAX_ELEMENT_INDEX: - *params = mCaps.maxElementIndex; - break; - case GL_MAX_UNIFORM_BLOCK_SIZE: - *params = mCaps.maxUniformBlockSize; - break; - case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: - *params = mCaps.maxCombinedVertexUniformComponents; - break; - case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: - *params = mCaps.maxCombinedFragmentUniformComponents; - break; - case GL_MAX_SERVER_WAIT_TIMEOUT: - *params = mCaps.maxServerWaitTimeout; - break; + case GL_MAX_ELEMENT_INDEX: + *params = mCaps.maxElementIndex; + break; + case GL_MAX_UNIFORM_BLOCK_SIZE: + *params = mCaps.maxUniformBlockSize; + break; + case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: + *params = mCaps.maxCombinedVertexUniformComponents; + break; + case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: + *params = mCaps.maxCombinedFragmentUniformComponents; + break; + case GL_MAX_SERVER_WAIT_TIMEOUT: + *params = mCaps.maxServerWaitTimeout; + break; - // GL_EXT_disjoint_timer_query - case GL_TIMESTAMP_EXT: - *params = mRenderer->getTimestamp(); - break; - default: - UNREACHABLE(); - break; + // GL_EXT_disjoint_timer_query + case GL_TIMESTAMP_EXT: + *params = mImplementation->getTimestamp(); + break; + + case GL_MAX_SHADER_STORAGE_BLOCK_SIZE: + *params = mCaps.maxShaderStorageBlockSize; + break; + default: + UNREACHABLE(); + break; } } void Context::getPointerv(GLenum pname, void **params) const { - mState.getPointerv(pname, params); + mGLState.getPointerv(pname, params); } -bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data) +void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data) { // Queries about context capabilities and maximums are answered by Context. // Queries about current GL state values are answered by State. - // Indexed integer queries all refer to current state, so this function is a - // mere passthrough. - return mState.getIndexedIntegerv(target, index, data); + + GLenum nativeType; + unsigned int numParams; + bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams); + ASSERT(queryStatus); + + if (nativeType == GL_INT) + { + switch (target) + { + case GL_MAX_COMPUTE_WORK_GROUP_COUNT: + ASSERT(index < 3u); + *data = mCaps.maxComputeWorkGroupCount[index]; + break; + case GL_MAX_COMPUTE_WORK_GROUP_SIZE: + ASSERT(index < 3u); + *data = mCaps.maxComputeWorkGroupSize[index]; + break; + default: + mGLState.getIntegeri_v(target, index, data); + } + } + else + { + CastIndexedStateValues(this, nativeType, target, index, numParams, data); + } } -bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data) +void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data) { // Queries about context capabilities and maximums are answered by Context. // Queries about current GL state values are answered by State. - // Indexed integer queries all refer to current state, so this function is a - // mere passthrough. - return mState.getIndexedInteger64v(target, index, data); + + GLenum nativeType; + unsigned int numParams; + bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams); + ASSERT(queryStatus); + + if (nativeType == GL_INT_64_ANGLEX) + { + mGLState.getInteger64i_v(target, index, data); + } + else + { + CastIndexedStateValues(this, nativeType, target, index, numParams, data); + } } -bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) +void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data) { - if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT) + // Queries about context capabilities and maximums are answered by Context. + // Queries about current GL state values are answered by State. + + GLenum nativeType; + unsigned int numParams; + bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams); + ASSERT(queryStatus); + + if (nativeType == GL_BOOL) { - *type = GL_INT; - *numParams = 1; - return true; + mGLState.getBooleani_v(target, index, data); } - - // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation - // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due - // to the fact that it is stored internally as a float, and so would require conversion - // if returned from Context::getIntegerv. Since this conversion is already implemented - // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we - // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling - // application. - switch (pname) + else { - case GL_COMPRESSED_TEXTURE_FORMATS: - { - *type = GL_INT; - *numParams = static_cast(mCaps.compressedTextureFormats.size()); - } - return true; - case GL_PROGRAM_BINARY_FORMATS_OES: - { - *type = GL_INT; - *numParams = static_cast(mCaps.programBinaryFormats.size()); - } - return true; - case GL_SHADER_BINARY_FORMATS: - { - *type = GL_INT; - *numParams = static_cast(mCaps.shaderBinaryFormats.size()); - } - return true; - - case GL_MAX_VERTEX_ATTRIBS: - case GL_MAX_VERTEX_UNIFORM_VECTORS: - case GL_MAX_VARYING_VECTORS: - case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: - case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: - case GL_MAX_TEXTURE_IMAGE_UNITS: - case GL_MAX_FRAGMENT_UNIFORM_VECTORS: - case GL_MAX_RENDERBUFFER_SIZE: - case GL_MAX_COLOR_ATTACHMENTS_EXT: - case GL_MAX_DRAW_BUFFERS_EXT: - case GL_NUM_SHADER_BINARY_FORMATS: - case GL_NUM_COMPRESSED_TEXTURE_FORMATS: - case GL_ARRAY_BUFFER_BINDING: - //case GL_FRAMEBUFFER_BINDING: // equivalent to DRAW_FRAMEBUFFER_BINDING_ANGLE - case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: - case GL_READ_FRAMEBUFFER_BINDING_ANGLE: - case GL_RENDERBUFFER_BINDING: - case GL_CURRENT_PROGRAM: - case GL_PACK_ALIGNMENT: - case GL_PACK_REVERSE_ROW_ORDER_ANGLE: - case GL_UNPACK_ALIGNMENT: - case GL_GENERATE_MIPMAP_HINT: - case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: - case GL_RED_BITS: - case GL_GREEN_BITS: - case GL_BLUE_BITS: - case GL_ALPHA_BITS: - case GL_DEPTH_BITS: - case GL_STENCIL_BITS: - case GL_ELEMENT_ARRAY_BUFFER_BINDING: - case GL_CULL_FACE_MODE: - case GL_FRONT_FACE: - case GL_ACTIVE_TEXTURE: - case GL_STENCIL_FUNC: - case GL_STENCIL_VALUE_MASK: - case GL_STENCIL_REF: - case GL_STENCIL_FAIL: - case GL_STENCIL_PASS_DEPTH_FAIL: - case GL_STENCIL_PASS_DEPTH_PASS: - case GL_STENCIL_BACK_FUNC: - case GL_STENCIL_BACK_VALUE_MASK: - case GL_STENCIL_BACK_REF: - case GL_STENCIL_BACK_FAIL: - case GL_STENCIL_BACK_PASS_DEPTH_FAIL: - case GL_STENCIL_BACK_PASS_DEPTH_PASS: - case GL_DEPTH_FUNC: - case GL_BLEND_SRC_RGB: - case GL_BLEND_SRC_ALPHA: - case GL_BLEND_DST_RGB: - case GL_BLEND_DST_ALPHA: - case GL_BLEND_EQUATION_RGB: - case GL_BLEND_EQUATION_ALPHA: - case GL_STENCIL_WRITEMASK: - case GL_STENCIL_BACK_WRITEMASK: - case GL_STENCIL_CLEAR_VALUE: - case GL_SUBPIXEL_BITS: - case GL_MAX_TEXTURE_SIZE: - case GL_MAX_CUBE_MAP_TEXTURE_SIZE: - case GL_SAMPLE_BUFFERS: - case GL_SAMPLES: - case GL_IMPLEMENTATION_COLOR_READ_TYPE: - case GL_IMPLEMENTATION_COLOR_READ_FORMAT: - case GL_TEXTURE_BINDING_2D: - case GL_TEXTURE_BINDING_CUBE_MAP: - case GL_RESET_NOTIFICATION_STRATEGY_EXT: - case GL_NUM_PROGRAM_BINARY_FORMATS_OES: - { - *type = GL_INT; - *numParams = 1; - } - return true; - case GL_MAX_SAMPLES_ANGLE: - { - if (mExtensions.framebufferMultisample) - { - *type = GL_INT; - *numParams = 1; - } - else - { - return false; - } - } - return true; - case GL_MAX_VIEWPORT_DIMS: - { - *type = GL_INT; - *numParams = 2; - } - return true; - case GL_VIEWPORT: - case GL_SCISSOR_BOX: - { - *type = GL_INT; - *numParams = 4; - } - return true; - case GL_SHADER_COMPILER: - case GL_SAMPLE_COVERAGE_INVERT: - case GL_DEPTH_WRITEMASK: - case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled, - case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries. - case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural - case GL_SAMPLE_COVERAGE: - case GL_SCISSOR_TEST: - case GL_STENCIL_TEST: - case GL_DEPTH_TEST: - case GL_BLEND: - case GL_DITHER: - case GL_CONTEXT_ROBUST_ACCESS_EXT: - { - *type = GL_BOOL; - *numParams = 1; - } - return true; - case GL_COLOR_WRITEMASK: - { - *type = GL_BOOL; - *numParams = 4; - } - return true; - case GL_POLYGON_OFFSET_FACTOR: - case GL_POLYGON_OFFSET_UNITS: - case GL_SAMPLE_COVERAGE_VALUE: - case GL_DEPTH_CLEAR_VALUE: - case GL_LINE_WIDTH: - { - *type = GL_FLOAT; - *numParams = 1; - } - return true; - case GL_ALIASED_LINE_WIDTH_RANGE: - case GL_ALIASED_POINT_SIZE_RANGE: - case GL_DEPTH_RANGE: - { - *type = GL_FLOAT; - *numParams = 2; - } - return true; - case GL_COLOR_CLEAR_VALUE: - case GL_BLEND_COLOR: - { - *type = GL_FLOAT; - *numParams = 4; - } - return true; - case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: - if (!mExtensions.maxTextureAnisotropy) - { - return false; - } - *type = GL_FLOAT; - *numParams = 1; - return true; - case GL_TIMESTAMP_EXT: - if (!mExtensions.disjointTimerQuery) - { - return false; - } - *type = GL_INT_64_ANGLEX; - *numParams = 1; - return true; - case GL_GPU_DISJOINT_EXT: - if (!mExtensions.disjointTimerQuery) - { - return false; - } - *type = GL_INT; - *numParams = 1; - return true; + CastIndexedStateValues(this, nativeType, target, index, numParams, data); } - - if (mExtensions.debug) - { - switch (pname) - { - case GL_DEBUG_LOGGED_MESSAGES: - case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH: - case GL_DEBUG_GROUP_STACK_DEPTH: - case GL_MAX_DEBUG_MESSAGE_LENGTH: - case GL_MAX_DEBUG_LOGGED_MESSAGES: - case GL_MAX_DEBUG_GROUP_STACK_DEPTH: - case GL_MAX_LABEL_LENGTH: - *type = GL_INT; - *numParams = 1; - return true; - - case GL_DEBUG_OUTPUT_SYNCHRONOUS: - case GL_DEBUG_OUTPUT: - *type = GL_BOOL; - *numParams = 1; - return true; - } - } - - // Check for ES3.0+ parameter names which are also exposed as ES2 extensions - switch (pname) - { - case GL_PACK_ROW_LENGTH: - case GL_PACK_SKIP_ROWS: - case GL_PACK_SKIP_PIXELS: - if ((mClientVersion < 3) && !mExtensions.packSubimage) - { - return false; - } - *type = GL_INT; - *numParams = 1; - return true; - case GL_UNPACK_ROW_LENGTH: - case GL_UNPACK_SKIP_ROWS: - case GL_UNPACK_SKIP_PIXELS: - if ((mClientVersion < 3) && !mExtensions.unpackSubimage) - { - return false; - } - *type = GL_INT; - *numParams = 1; - return true; - case GL_VERTEX_ARRAY_BINDING: - if ((mClientVersion < 3) && !mExtensions.vertexArrayObject) - { - return false; - } - *type = GL_INT; - *numParams = 1; - return true; - case GL_PIXEL_PACK_BUFFER_BINDING: - case GL_PIXEL_UNPACK_BUFFER_BINDING: - if ((mClientVersion < 3) && !mExtensions.pixelBufferObject) - { - return false; - } - *type = GL_INT; - *numParams = 1; - return true; - } - - if (mClientVersion < 3) - { - return false; - } - - // Check for ES3.0+ parameter names - switch (pname) - { - case GL_MAX_UNIFORM_BUFFER_BINDINGS: - case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: - case GL_UNIFORM_BUFFER_BINDING: - case GL_TRANSFORM_FEEDBACK_BINDING: - case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: - case GL_COPY_READ_BUFFER_BINDING: - case GL_COPY_WRITE_BUFFER_BINDING: - case GL_TEXTURE_BINDING_3D: - case GL_TEXTURE_BINDING_2D_ARRAY: - case GL_MAX_3D_TEXTURE_SIZE: - case GL_MAX_ARRAY_TEXTURE_LAYERS: - case GL_MAX_VERTEX_UNIFORM_BLOCKS: - case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: - case GL_MAX_COMBINED_UNIFORM_BLOCKS: - case GL_MAX_VERTEX_OUTPUT_COMPONENTS: - case GL_MAX_FRAGMENT_INPUT_COMPONENTS: - case GL_MAX_VARYING_COMPONENTS: - case GL_MAX_VERTEX_UNIFORM_COMPONENTS: - case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: - case GL_MIN_PROGRAM_TEXEL_OFFSET: - case GL_MAX_PROGRAM_TEXEL_OFFSET: - case GL_NUM_EXTENSIONS: - case GL_MAJOR_VERSION: - case GL_MINOR_VERSION: - case GL_MAX_ELEMENTS_INDICES: - case GL_MAX_ELEMENTS_VERTICES: - case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: - case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: - case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: - case GL_UNPACK_IMAGE_HEIGHT: - case GL_UNPACK_SKIP_IMAGES: - { - *type = GL_INT; - *numParams = 1; - } - return true; - - case GL_MAX_ELEMENT_INDEX: - case GL_MAX_UNIFORM_BLOCK_SIZE: - case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: - case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: - case GL_MAX_SERVER_WAIT_TIMEOUT: - { - *type = GL_INT_64_ANGLEX; - *numParams = 1; - } - return true; - - case GL_TRANSFORM_FEEDBACK_ACTIVE: - case GL_TRANSFORM_FEEDBACK_PAUSED: - case GL_PRIMITIVE_RESTART_FIXED_INDEX: - case GL_RASTERIZER_DISCARD: - { - *type = GL_BOOL; - *numParams = 1; - } - return true; - - case GL_MAX_TEXTURE_LOD_BIAS: - { - *type = GL_FLOAT; - *numParams = 1; - } - return true; - } - - return false; } -bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams) +void Context::getBufferParameteriv(BufferBinding target, GLenum pname, GLint *params) { - if (mClientVersion < 3) - { - return false; - } - - switch (target) - { - case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: - case GL_UNIFORM_BUFFER_BINDING: - { - *type = GL_INT; - *numParams = 1; - } - return true; - case GL_TRANSFORM_FEEDBACK_BUFFER_START: - case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: - case GL_UNIFORM_BUFFER_START: - case GL_UNIFORM_BUFFER_SIZE: - { - *type = GL_INT_64_ANGLEX; - *numParams = 1; - } - } - - return false; + Buffer *buffer = mGLState.getTargetBuffer(target); + QueryBufferParameteriv(buffer, pname, params); } -Error Context::drawArrays(GLenum mode, GLint first, GLsizei count) +void Context::getFramebufferAttachmentParameteriv(GLenum target, + GLenum attachment, + GLenum pname, + GLint *params) { - syncRendererState(); - Error error = mRenderer->drawArrays(getData(), mode, first, count); - if (error.isError()) - { - return error; - } - - MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback()); - - return Error(GL_NO_ERROR); + const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target); + QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params); } -Error Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount) +void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params) { - syncRendererState(); - Error error = mRenderer->drawArraysInstanced(getData(), mode, first, count, instanceCount); - if (error.isError()) - { - return error; - } - - MarkTransformFeedbackBufferUsage(mState.getCurrentTransformFeedback()); - - return Error(GL_NO_ERROR); + Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer(); + QueryRenderbufferiv(this, renderbuffer, pname, params); } -Error Context::drawElements(GLenum mode, - GLsizei count, - GLenum type, - const GLvoid *indices, - const IndexRange &indexRange) +void Context::getTexParameterfv(GLenum target, GLenum pname, GLfloat *params) { - syncRendererState(); - return mRenderer->drawElements(getData(), mode, count, type, indices, indexRange); + Texture *texture = getTargetTexture(target); + QueryTexParameterfv(texture, pname, params); } -Error Context::drawElementsInstanced(GLenum mode, - GLsizei count, - GLenum type, - const GLvoid *indices, - GLsizei instances, - const IndexRange &indexRange) +void Context::getTexParameteriv(GLenum target, GLenum pname, GLint *params) { - syncRendererState(); - return mRenderer->drawElementsInstanced(getData(), mode, count, type, indices, instances, - indexRange); + Texture *texture = getTargetTexture(target); + QueryTexParameteriv(texture, pname, params); } -Error Context::drawRangeElements(GLenum mode, - GLuint start, - GLuint end, - GLsizei count, - GLenum type, - const GLvoid *indices, - const IndexRange &indexRange) +void Context::getTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) { - syncRendererState(); - return mRenderer->drawRangeElements(getData(), mode, start, end, count, type, indices, - indexRange); + Texture *texture = + getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); + QueryTexLevelParameteriv(texture, target, level, pname, params); } -Error Context::flush() +void Context::getTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params) { - return mRenderer->flush(); + Texture *texture = + getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); + QueryTexLevelParameterfv(texture, target, level, pname, params); } -Error Context::finish() +void Context::texParameterf(GLenum target, GLenum pname, GLfloat param) { - return mRenderer->finish(); + Texture *texture = getTargetTexture(target); + SetTexParameterf(this, texture, pname, param); + onTextureChange(texture); +} + +void Context::texParameterfv(GLenum target, GLenum pname, const GLfloat *params) +{ + Texture *texture = getTargetTexture(target); + SetTexParameterfv(this, texture, pname, params); + onTextureChange(texture); +} + +void Context::texParameteri(GLenum target, GLenum pname, GLint param) +{ + Texture *texture = getTargetTexture(target); + SetTexParameteri(this, texture, pname, param); + onTextureChange(texture); +} + +void Context::texParameteriv(GLenum target, GLenum pname, const GLint *params) +{ + Texture *texture = getTargetTexture(target); + SetTexParameteriv(this, texture, pname, params); + onTextureChange(texture); +} + +void Context::drawArrays(GLenum mode, GLint first, GLsizei count) +{ + ANGLE_CONTEXT_TRY(prepareForDraw()); + ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count)); + MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback()); +} + +void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount) +{ + ANGLE_CONTEXT_TRY(prepareForDraw()); + ANGLE_CONTEXT_TRY( + mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount)); + MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback()); +} + +void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) +{ + ANGLE_CONTEXT_TRY(prepareForDraw()); + ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices)); +} + +void Context::drawElementsInstanced(GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei instances) +{ + ANGLE_CONTEXT_TRY(prepareForDraw()); + ANGLE_CONTEXT_TRY( + mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances)); +} + +void Context::drawRangeElements(GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const void *indices) +{ + ANGLE_CONTEXT_TRY(prepareForDraw()); + ANGLE_CONTEXT_TRY( + mImplementation->drawRangeElements(this, mode, start, end, count, type, indices)); +} + +void Context::drawArraysIndirect(GLenum mode, const void *indirect) +{ + ANGLE_CONTEXT_TRY(prepareForDraw()); + ANGLE_CONTEXT_TRY(mImplementation->drawArraysIndirect(this, mode, indirect)); +} + +void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect) +{ + ANGLE_CONTEXT_TRY(prepareForDraw()); + ANGLE_CONTEXT_TRY(mImplementation->drawElementsIndirect(this, mode, type, indirect)); +} + +void Context::flush() +{ + handleError(mImplementation->flush(this)); +} + +void Context::finish() +{ + handleError(mImplementation->finish(this)); } void Context::insertEventMarker(GLsizei length, const char *marker) { - ASSERT(mRenderer); - mRenderer->insertEventMarker(length, marker); + ASSERT(mImplementation); + mImplementation->insertEventMarker(length, marker); } void Context::pushGroupMarker(GLsizei length, const char *marker) { - ASSERT(mRenderer); - mRenderer->pushGroupMarker(length, marker); + ASSERT(mImplementation); + mImplementation->pushGroupMarker(length, marker); } void Context::popGroupMarker() { - ASSERT(mRenderer); - mRenderer->popGroupMarker(); + ASSERT(mImplementation); + mImplementation->popGroupMarker(); } -void Context::recordError(const Error &error) +void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + + programObject->bindUniformLocation(location, name); +} + +void Context::setCoverageModulation(GLenum components) +{ + mGLState.setCoverageModulation(components); +} + +void Context::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix) +{ + mGLState.loadPathRenderingMatrix(matrixMode, matrix); +} + +void Context::loadPathRenderingIdentityMatrix(GLenum matrixMode) +{ + GLfloat I[16]; + angle::Matrix::setToIdentity(I); + + mGLState.loadPathRenderingMatrix(matrixMode, I); +} + +void Context::stencilFillPath(GLuint path, GLenum fillMode, GLuint mask) +{ + const auto *pathObj = mState.mPaths->getPath(path); + if (!pathObj) + return; + + // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering? + syncRendererState(); + + mImplementation->stencilFillPath(pathObj, fillMode, mask); +} + +void Context::stencilStrokePath(GLuint path, GLint reference, GLuint mask) +{ + const auto *pathObj = mState.mPaths->getPath(path); + if (!pathObj) + return; + + // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering? + syncRendererState(); + + mImplementation->stencilStrokePath(pathObj, reference, mask); +} + +void Context::coverFillPath(GLuint path, GLenum coverMode) +{ + const auto *pathObj = mState.mPaths->getPath(path); + if (!pathObj) + return; + + // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering? + syncRendererState(); + + mImplementation->coverFillPath(pathObj, coverMode); +} + +void Context::coverStrokePath(GLuint path, GLenum coverMode) +{ + const auto *pathObj = mState.mPaths->getPath(path); + if (!pathObj) + return; + + // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering? + syncRendererState(); + + mImplementation->coverStrokePath(pathObj, coverMode); +} + +void Context::stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode) +{ + const auto *pathObj = mState.mPaths->getPath(path); + if (!pathObj) + return; + + // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering? + syncRendererState(); + + mImplementation->stencilThenCoverFillPath(pathObj, fillMode, mask, coverMode); +} + +void Context::stencilThenCoverStrokePath(GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode) +{ + const auto *pathObj = mState.mPaths->getPath(path); + if (!pathObj) + return; + + // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering? + syncRendererState(); + + mImplementation->stencilThenCoverStrokePath(pathObj, reference, mask, coverMode); +} + +void Context::coverFillPathInstanced(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase); + + // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering? + syncRendererState(); + + mImplementation->coverFillPathInstanced(pathObjects, coverMode, transformType, transformValues); +} + +void Context::coverStrokePathInstanced(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase); + + // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering? + syncRendererState(); + + mImplementation->coverStrokePathInstanced(pathObjects, coverMode, transformType, + transformValues); +} + +void Context::stencilFillPathInstanced(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase); + + // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering? + syncRendererState(); + + mImplementation->stencilFillPathInstanced(pathObjects, fillMode, mask, transformType, + transformValues); +} + +void Context::stencilStrokePathInstanced(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase); + + // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering? + syncRendererState(); + + mImplementation->stencilStrokePathInstanced(pathObjects, reference, mask, transformType, + transformValues); +} + +void Context::stencilThenCoverFillPathInstanced(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase); + + // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering? + syncRendererState(); + + mImplementation->stencilThenCoverFillPathInstanced(pathObjects, coverMode, fillMode, mask, + transformType, transformValues); +} + +void Context::stencilThenCoverStrokePathInstanced(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + const auto &pathObjects = GatherPaths(*mState.mPaths, numPaths, pathNameType, paths, pathBase); + + // TODO(svaisanen@nvidia.com): maybe sync only state required for path rendering? + syncRendererState(); + + mImplementation->stencilThenCoverStrokePathInstanced(pathObjects, coverMode, reference, mask, + transformType, transformValues); +} + +void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name) +{ + auto *programObject = getProgram(program); + + programObject->bindFragmentInputLocation(location, name); +} + +void Context::programPathFragmentInputGen(GLuint program, + GLint location, + GLenum genMode, + GLint components, + const GLfloat *coeffs) +{ + auto *programObject = getProgram(program); + + programObject->pathFragmentInputGen(this, location, genMode, components, coeffs); +} + +GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name) +{ + const auto *programObject = getProgram(program); + return QueryProgramResourceIndex(programObject, programInterface, name); +} + +void Context::getProgramResourceName(GLuint program, + GLenum programInterface, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name) +{ + const auto *programObject = getProgram(program); + QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name); +} + +GLint Context::getProgramResourceLocation(GLuint program, + GLenum programInterface, + const GLchar *name) +{ + const auto *programObject = getProgram(program); + return QueryProgramResourceLocation(programObject, programInterface, name); +} + +void Context::getProgramResourceiv(GLuint program, + GLenum programInterface, + GLuint index, + GLsizei propCount, + const GLenum *props, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + const auto *programObject = getProgram(program); + QueryProgramResourceiv(programObject, programInterface, index, propCount, props, bufSize, + length, params); +} + +void Context::getProgramInterfaceiv(GLuint program, + GLenum programInterface, + GLenum pname, + GLint *params) +{ + const auto *programObject = getProgram(program); + QueryProgramInterfaceiv(programObject, programInterface, pname, params); +} + +void Context::handleError(const Error &error) { if (error.isError()) { - mErrors.insert(error.getCode()); - - if (!error.getMessage().empty()) + GLenum code = error.getCode(); + mErrors.insert(code); + if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory) { - auto &debug = mState.getDebug(); - debug.insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(), - GL_DEBUG_SEVERITY_HIGH, error.getMessage()); + markContextLost(); } + + ASSERT(!error.getMessage().empty()); + mGLState.getDebug().insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(), + GL_DEBUG_SEVERITY_HIGH, error.getMessage()); } } @@ -1636,32 +2093,61 @@ GLenum Context::getError() } } +// NOTE: this function should not assume that this context is current! +void Context::markContextLost() +{ + if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT) + { + mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT; + mContextLostForced = true; + } + mContextLost = true; +} + +bool Context::isContextLost() +{ + return mContextLost; +} + GLenum Context::getResetStatus() { - //TODO(jmadill): needs MANGLE reworking - if (mResetStatus == GL_NO_ERROR && !mContextLost) + // Even if the application doesn't want to know about resets, we want to know + // as it will allow us to skip all the calls. + if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT) { - // mResetStatus will be set by the markContextLost callback - // in the case a notification is sent - if (mRenderer->testDeviceLost()) + if (!mContextLost && mImplementation->getResetStatus() != GL_NO_ERROR) { - mRenderer->notifyDeviceLost(); + mContextLost = true; } + + // EXT_robustness, section 2.6: If the reset notification behavior is + // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of + // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR. + return GL_NO_ERROR; } - GLenum status = mResetStatus; - - if (mResetStatus != GL_NO_ERROR) + // The GL_EXT_robustness spec says that if a reset is encountered, a reset + // status should be returned at least once, and GL_NO_ERROR should be returned + // once the device has finished resetting. + if (!mContextLost) { - ASSERT(mContextLost); + ASSERT(mResetStatus == GL_NO_ERROR); + mResetStatus = mImplementation->getResetStatus(); - if (mRenderer->testDeviceResettable()) + if (mResetStatus != GL_NO_ERROR) { - mResetStatus = GL_NO_ERROR; + mContextLost = true; } } + else if (!mContextLostForced && mResetStatus != GL_NO_ERROR) + { + // If markContextLost was used to mark the context lost then + // assume that is not recoverable, and continue to report the + // lost reset status for the lifetime of this context. + mResetStatus = mImplementation->getResetStatus(); + } - return status; + return mResetStatus; } bool Context::isResetNotificationEnabled() @@ -1681,73 +2167,57 @@ EGLenum Context::getClientType() const EGLenum Context::getRenderBuffer() const { - auto framebufferIt = mFramebufferMap.find(0); - if (framebufferIt != mFramebufferMap.end()) - { - const Framebuffer *framebuffer = framebufferIt->second; - const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK); - - ASSERT(backAttachment != nullptr); - return backAttachment->getSurface()->getRenderBuffer(); - } - else + const Framebuffer *framebuffer = mState.mFramebuffers->getFramebuffer(0); + if (framebuffer == nullptr) { return EGL_NONE; } + + const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK); + ASSERT(backAttachment != nullptr); + return backAttachment->getSurface()->getRenderBuffer(); } -void Context::checkVertexArrayAllocation(GLuint vertexArray) +VertexArray *Context::checkVertexArrayAllocation(GLuint vertexArrayHandle) { // Only called after a prior call to Gen. - if (!getVertexArray(vertexArray)) + VertexArray *vertexArray = getVertexArray(vertexArrayHandle); + if (!vertexArray) { - VertexArray *vertexArrayObject = - new VertexArray(mRenderer, vertexArray, MAX_VERTEX_ATTRIBS); - mVertexArrayMap[vertexArray] = vertexArrayObject; + vertexArray = new VertexArray(mImplementation.get(), vertexArrayHandle, + mCaps.maxVertexAttributes, mCaps.maxVertexAttribBindings); + + mVertexArrayMap.assign(vertexArrayHandle, vertexArray); } + + return vertexArray; } -void Context::checkTransformFeedbackAllocation(GLuint transformFeedback) +TransformFeedback *Context::checkTransformFeedbackAllocation(GLuint transformFeedbackHandle) { // Only called after a prior call to Gen. - if (!getTransformFeedback(transformFeedback)) + TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle); + if (!transformFeedback) { - TransformFeedback *transformFeedbackObject = - new TransformFeedback(mRenderer->createTransformFeedback(), transformFeedback, mCaps); - transformFeedbackObject->addRef(); - mTransformFeedbackMap[transformFeedback] = transformFeedbackObject; - } -} - -Framebuffer *Context::checkFramebufferAllocation(GLuint framebuffer) -{ - // Can be called from Bind without a prior call to Gen. - auto framebufferIt = mFramebufferMap.find(framebuffer); - bool neverCreated = framebufferIt == mFramebufferMap.end(); - if (neverCreated || framebufferIt->second == nullptr) - { - Framebuffer *newFBO = new Framebuffer(mCaps, mRenderer, framebuffer); - if (neverCreated) - { - mFramebufferHandleAllocator.reserve(framebuffer); - mFramebufferMap[framebuffer] = newFBO; - return newFBO; - } - - framebufferIt->second = newFBO; + transformFeedback = + new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mCaps); + transformFeedback->addRef(); + mTransformFeedbackMap.assign(transformFeedbackHandle, transformFeedback); } - return framebufferIt->second; + return transformFeedback; } bool Context::isVertexArrayGenerated(GLuint vertexArray) { - return mVertexArrayMap.find(vertexArray) != mVertexArrayMap.end(); + ASSERT(mVertexArrayMap.contains(0)); + return mVertexArrayMap.contains(vertexArray); } bool Context::isTransformFeedbackGenerated(GLuint transformFeedback) { - return mTransformFeedbackMap.find(transformFeedback) != mTransformFeedbackMap.end(); + ASSERT(mTransformFeedbackMap.contains(0)); + return mTransformFeedbackMap.contains(transformFeedback); } void Context::detachTexture(GLuint texture) @@ -1756,7 +2226,7 @@ void Context::detachTexture(GLuint texture) // allocation map management either here or in the resource manager at detach time. // Zero textures are held by the Context, and we don't attempt to request them from // the State. - mState.detachTexture(mZeroTextures, texture); + mGLState.detachTexture(this, mZeroTextures, texture); } void Context::detachBuffer(GLuint buffer) @@ -1769,7 +2239,7 @@ void Context::detachBuffer(GLuint buffer) // Attachments to unbound container objects, such as // deletion of a buffer attached to a vertex array object which is not bound to the context, // are not affected and continue to act as references on the deleted object - mState.detachBuffer(buffer); + mGLState.detachBuffer(this, buffer); } void Context::detachFramebuffer(GLuint framebuffer) @@ -1779,15 +2249,16 @@ void Context::detachFramebuffer(GLuint framebuffer) // to State at binding time. // [OpenGL ES 2.0.24] section 4.4 page 107: - // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though - // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero. + // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as + // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of + // zero. - if (mState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0) + if (mGLState.removeReadFramebufferBinding(framebuffer) && framebuffer != 0) { bindReadFramebuffer(0); } - if (mState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0) + if (mGLState.removeDrawFramebufferBinding(framebuffer) && framebuffer != 0) { bindDrawFramebuffer(0); } @@ -1795,7 +2266,7 @@ void Context::detachFramebuffer(GLuint framebuffer) void Context::detachRenderbuffer(GLuint renderbuffer) { - mState.detachRenderbuffer(renderbuffer); + mGLState.detachRenderbuffer(this, renderbuffer); } void Context::detachVertexArray(GLuint vertexArray) @@ -1807,7 +2278,7 @@ void Context::detachVertexArray(GLuint vertexArray) // [OpenGL ES 3.0.2] section 2.10 page 43: // If a vertex array object that is currently bound is deleted, the binding // for that object reverts to zero and the default vertex array becomes current. - if (mState.removeVertexArrayBinding(vertexArray)) + if (mGLState.removeVertexArrayBinding(vertexArray)) { bindVertexArray(0); } @@ -1815,151 +2286,188 @@ void Context::detachVertexArray(GLuint vertexArray) void Context::detachTransformFeedback(GLuint transformFeedback) { - mState.detachTransformFeedback(transformFeedback); + // Transform feedback detachment is handled by Context, because 0 is a valid + // transform feedback, and a pointer to it must be passed from Context to State at + // binding time. + + // The OpenGL specification doesn't mention what should happen when the currently bound + // transform feedback object is deleted. Since it is a container object, we treat it like + // VAOs and FBOs and set the current bound transform feedback back to 0. + if (mGLState.removeTransformFeedbackBinding(this, transformFeedback)) + { + bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0); + } } void Context::detachSampler(GLuint sampler) { - mState.detachSampler(sampler); + mGLState.detachSampler(this, sampler); } -void Context::setVertexAttribDivisor(GLuint index, GLuint divisor) +void Context::detachProgramPipeline(GLuint pipeline) { - mState.setVertexAttribDivisor(index, divisor); + mGLState.detachProgramPipeline(this, pipeline); +} + +void Context::vertexAttribDivisor(GLuint index, GLuint divisor) +{ + mGLState.setVertexAttribDivisor(this, index, divisor); } void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param) { - mResourceManager->checkSamplerAllocation(sampler); + Sampler *samplerObject = + mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler); + SetSamplerParameteri(samplerObject, pname, param); + mGLState.setObjectDirty(GL_SAMPLER); +} - Sampler *samplerObject = getSampler(sampler); - ASSERT(samplerObject); - - // clang-format off - switch (pname) - { - case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(static_cast(param)); break; - case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(static_cast(param)); break; - case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(static_cast(param)); break; - case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(static_cast(param)); break; - case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(static_cast(param)); break; - case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(static_cast(param), getExtensions().maxTextureAnisotropy)); break; - case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(static_cast(param)); break; - case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(static_cast(param)); break; - case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(static_cast(param)); break; - case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(static_cast(param)); break; - default: UNREACHABLE(); break; - } - // clang-format on +void Context::samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param) +{ + Sampler *samplerObject = + mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler); + SetSamplerParameteriv(samplerObject, pname, param); + mGLState.setObjectDirty(GL_SAMPLER); } void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param) { - mResourceManager->checkSamplerAllocation(sampler); - - Sampler *samplerObject = getSampler(sampler); - ASSERT(samplerObject); - - // clang-format off - switch (pname) - { - case GL_TEXTURE_MIN_FILTER: samplerObject->setMinFilter(uiround(param)); break; - case GL_TEXTURE_MAG_FILTER: samplerObject->setMagFilter(uiround(param)); break; - case GL_TEXTURE_WRAP_S: samplerObject->setWrapS(uiround(param)); break; - case GL_TEXTURE_WRAP_T: samplerObject->setWrapT(uiround(param)); break; - case GL_TEXTURE_WRAP_R: samplerObject->setWrapR(uiround(param)); break; - case GL_TEXTURE_MAX_ANISOTROPY_EXT: samplerObject->setMaxAnisotropy(std::min(param, getExtensions().maxTextureAnisotropy)); break; - case GL_TEXTURE_MIN_LOD: samplerObject->setMinLod(param); break; - case GL_TEXTURE_MAX_LOD: samplerObject->setMaxLod(param); break; - case GL_TEXTURE_COMPARE_MODE: samplerObject->setCompareMode(uiround(param)); break; - case GL_TEXTURE_COMPARE_FUNC: samplerObject->setCompareFunc(uiround(param)); break; - default: UNREACHABLE(); break; - } - // clang-format on + Sampler *samplerObject = + mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler); + SetSamplerParameterf(samplerObject, pname, param); + mGLState.setObjectDirty(GL_SAMPLER); } -GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname) +void Context::samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param) { - mResourceManager->checkSamplerAllocation(sampler); - - Sampler *samplerObject = getSampler(sampler); - ASSERT(samplerObject); - - // clang-format off - switch (pname) - { - case GL_TEXTURE_MIN_FILTER: return static_cast(samplerObject->getMinFilter()); - case GL_TEXTURE_MAG_FILTER: return static_cast(samplerObject->getMagFilter()); - case GL_TEXTURE_WRAP_S: return static_cast(samplerObject->getWrapS()); - case GL_TEXTURE_WRAP_T: return static_cast(samplerObject->getWrapT()); - case GL_TEXTURE_WRAP_R: return static_cast(samplerObject->getWrapR()); - case GL_TEXTURE_MAX_ANISOTROPY_EXT: return static_cast(samplerObject->getMaxAnisotropy()); - case GL_TEXTURE_MIN_LOD: return uiround(samplerObject->getMinLod()); - case GL_TEXTURE_MAX_LOD: return uiround(samplerObject->getMaxLod()); - case GL_TEXTURE_COMPARE_MODE: return static_cast(samplerObject->getCompareMode()); - case GL_TEXTURE_COMPARE_FUNC: return static_cast(samplerObject->getCompareFunc()); - default: UNREACHABLE(); return 0; - } - // clang-format on + Sampler *samplerObject = + mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler); + SetSamplerParameterfv(samplerObject, pname, param); + mGLState.setObjectDirty(GL_SAMPLER); } -GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname) +void Context::getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params) { - mResourceManager->checkSamplerAllocation(sampler); + const Sampler *samplerObject = + mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler); + QuerySamplerParameteriv(samplerObject, pname, params); + mGLState.setObjectDirty(GL_SAMPLER); +} - Sampler *samplerObject = getSampler(sampler); - ASSERT(samplerObject); +void Context::getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params) +{ + const Sampler *samplerObject = + mState.mSamplers->checkSamplerAllocation(mImplementation.get(), sampler); + QuerySamplerParameterfv(samplerObject, pname, params); + mGLState.setObjectDirty(GL_SAMPLER); +} - // clang-format off - switch (pname) - { - case GL_TEXTURE_MIN_FILTER: return static_cast(samplerObject->getMinFilter()); - case GL_TEXTURE_MAG_FILTER: return static_cast(samplerObject->getMagFilter()); - case GL_TEXTURE_WRAP_S: return static_cast(samplerObject->getWrapS()); - case GL_TEXTURE_WRAP_T: return static_cast(samplerObject->getWrapT()); - case GL_TEXTURE_WRAP_R: return static_cast(samplerObject->getWrapR()); - case GL_TEXTURE_MAX_ANISOTROPY_EXT: return samplerObject->getMaxAnisotropy(); - case GL_TEXTURE_MIN_LOD: return samplerObject->getMinLod(); - case GL_TEXTURE_MAX_LOD: return samplerObject->getMaxLod(); - case GL_TEXTURE_COMPARE_MODE: return static_cast(samplerObject->getCompareMode()); - case GL_TEXTURE_COMPARE_FUNC: return static_cast(samplerObject->getCompareFunc()); - default: UNREACHABLE(); return 0; - } - // clang-format on +void Context::programParameteri(GLuint program, GLenum pname, GLint value) +{ + gl::Program *programObject = getProgram(program); + SetProgramParameteri(programObject, pname, value); } void Context::initRendererString() { std::ostringstream rendererString; rendererString << "ANGLE ("; - rendererString << mRenderer->getRendererDescription(); + rendererString << mImplementation->getRendererDescription(); rendererString << ")"; mRendererString = MakeStaticString(rendererString.str()); } -const std::string &Context::getRendererString() const +void Context::initVersionStrings() { - return mRendererString; + const Version &clientVersion = getClientVersion(); + + std::ostringstream versionString; + versionString << "OpenGL ES " << clientVersion.major << "." << clientVersion.minor << " (ANGLE " + << ANGLE_VERSION_STRING << ")"; + mVersionString = MakeStaticString(versionString.str()); + + std::ostringstream shadingLanguageVersionString; + shadingLanguageVersionString << "OpenGL ES GLSL ES " + << (clientVersion.major == 2 ? 1 : clientVersion.major) << "." + << clientVersion.minor << "0 (ANGLE " << ANGLE_VERSION_STRING + << ")"; + mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str()); } void Context::initExtensionStrings() { - mExtensionStrings = mExtensions.getStrings(); + auto mergeExtensionStrings = [](const std::vector &strings) { + std::ostringstream combinedStringStream; + std::copy(strings.begin(), strings.end(), + std::ostream_iterator(combinedStringStream, " ")); + return MakeStaticString(combinedStringStream.str()); + }; - std::ostringstream combinedStringStream; - std::copy(mExtensionStrings.begin(), mExtensionStrings.end(), std::ostream_iterator(combinedStringStream, " ")); - mExtensionString = combinedStringStream.str(); + mExtensionStrings.clear(); + for (const auto &extensionString : mExtensions.getStrings()) + { + mExtensionStrings.push_back(MakeStaticString(extensionString)); + } + mExtensionString = mergeExtensionStrings(mExtensionStrings); + + const gl::Extensions &nativeExtensions = mImplementation->getNativeExtensions(); + + mRequestableExtensionStrings.clear(); + for (const auto &extensionInfo : GetExtensionInfoMap()) + { + if (extensionInfo.second.Requestable && + !(mExtensions.*(extensionInfo.second.ExtensionsMember)) && + nativeExtensions.*(extensionInfo.second.ExtensionsMember)) + { + mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first)); + } + } + mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings); } -const std::string &Context::getExtensionString() const +const GLubyte *Context::getString(GLenum name) const { - return mExtensionString; + switch (name) + { + case GL_VENDOR: + return reinterpret_cast("Google Inc."); + + case GL_RENDERER: + return reinterpret_cast(mRendererString); + + case GL_VERSION: + return reinterpret_cast(mVersionString); + + case GL_SHADING_LANGUAGE_VERSION: + return reinterpret_cast(mShadingLanguageString); + + case GL_EXTENSIONS: + return reinterpret_cast(mExtensionString); + + case GL_REQUESTABLE_EXTENSIONS_ANGLE: + return reinterpret_cast(mRequestableExtensionString); + + default: + UNREACHABLE(); + return nullptr; + } } -const std::string &Context::getExtensionString(size_t idx) const +const GLubyte *Context::getStringi(GLenum name, GLuint index) const { - return mExtensionStrings[idx]; + switch (name) + { + case GL_EXTENSIONS: + return reinterpret_cast(mExtensionStrings[index]); + + case GL_REQUESTABLE_EXTENSIONS_ANGLE: + return reinterpret_cast(mRequestableExtensionStrings[index]); + + default: + UNREACHABLE(); + return nullptr; + } } size_t Context::getExtensionStringCount() const @@ -1967,26 +2475,117 @@ size_t Context::getExtensionStringCount() const return mExtensionStrings.size(); } -void Context::initCaps(GLuint clientVersion) +bool Context::isExtensionRequestable(const char *name) { - mCaps = mRenderer->getRendererCaps(); + const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap(); + auto extension = extensionInfos.find(name); - mExtensions = mRenderer->getRendererExtensions(); + const Extensions &nativeExtensions = mImplementation->getNativeExtensions(); + return extension != extensionInfos.end() && extension->second.Requestable && + nativeExtensions.*(extension->second.ExtensionsMember); +} - mLimitations = mRenderer->getRendererLimitations(); +void Context::requestExtension(const char *name) +{ + const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap(); + ASSERT(extensionInfos.find(name) != extensionInfos.end()); + const auto &extension = extensionInfos.at(name); + ASSERT(extension.Requestable); + ASSERT(mImplementation->getNativeExtensions().*(extension.ExtensionsMember)); - if (clientVersion < 3) + if (mExtensions.*(extension.ExtensionsMember)) + { + // Extension already enabled + return; + } + + mExtensions.*(extension.ExtensionsMember) = true; + updateCaps(); + initExtensionStrings(); + + // Release the shader compiler so it will be re-created with the requested extensions enabled. + releaseShaderCompiler(); + + // Invalidate all textures and framebuffer. Some extensions make new formats renderable or + // sampleable. + mState.mTextures->signalAllTexturesDirty(); + for (auto &zeroTexture : mZeroTextures) + { + zeroTexture.second->signalDirty(InitState::Initialized); + } + + mState.mFramebuffers->invalidateFramebufferComplenessCache(); +} + +size_t Context::getRequestableExtensionStringCount() const +{ + return mRequestableExtensionStrings.size(); +} + +void Context::beginTransformFeedback(GLenum primitiveMode) +{ + TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback(); + ASSERT(transformFeedback != nullptr); + ASSERT(!transformFeedback->isPaused()); + + transformFeedback->begin(this, primitiveMode, mGLState.getProgram()); +} + +bool Context::hasActiveTransformFeedback(GLuint program) const +{ + for (auto pair : mTransformFeedbackMap) + { + if (pair.second != nullptr && pair.second->hasBoundProgram(program)) + { + return true; + } + } + return false; +} + +void Context::initCaps(const egl::DisplayExtensions &displayExtensions, bool robustResourceInit) +{ + mCaps = mImplementation->getNativeCaps(); + + mExtensions = mImplementation->getNativeExtensions(); + + mLimitations = mImplementation->getNativeLimitations(); + + if (getClientVersion() < Version(3, 0)) { // Disable ES3+ extensions - mExtensions.colorBufferFloat = false; + mExtensions.colorBufferFloat = false; + mExtensions.eglImageExternalEssl3 = false; + mExtensions.textureNorm16 = false; + mExtensions.multiview = false; + mExtensions.maxViews = 1u; } - if (clientVersion > 2) + if (getClientVersion() < ES_3_1) + { + // Disable ES3.1+ extensions + mExtensions.geometryShader = false; + } + + if (getClientVersion() > Version(2, 0)) { // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts - //mExtensions.sRGB = false; + // mExtensions.sRGB = false; } + // Some extensions are always available because they are implemented in the GL layer. + mExtensions.bindUniformLocation = true; + mExtensions.vertexArrayObject = true; + mExtensions.bindGeneratesResource = true; + mExtensions.clientArrays = true; + mExtensions.requestExtension = true; + + // Enable the no error extension if the context was created with the flag. + mExtensions.noError = mSkipValidation; + + // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO + mExtensions.surfacelessContext = displayExtensions.surfacelessContext; + // Explicitly enable GL_KHR_debug mExtensions.debug = true; mExtensions.maxDebugMessageLength = 1024; @@ -1994,64 +2593,186 @@ void Context::initCaps(GLuint clientVersion) mExtensions.maxDebugGroupStackDepth = 1024; mExtensions.maxLabelLength = 1024; + // Explicitly enable GL_ANGLE_robust_client_memory + mExtensions.robustClientMemory = true; + + // Determine robust resource init availability from EGL. + mExtensions.robustResourceInitialization = robustResourceInit; + + // mExtensions.robustBufferAccessBehavior is true only if robust access is true and the backend + // supports it. + mExtensions.robustBufferAccessBehavior = + mRobustAccess && mExtensions.robustBufferAccessBehavior; + + // Enable the cache control query unconditionally. + mExtensions.programCacheControl = true; + // Apply implementation limits - mCaps.maxVertexAttributes = std::min(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS); - mCaps.maxVertexUniformBlocks = std::min(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS); - mCaps.maxVertexOutputComponents = std::min(mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4); + LimitCap(&mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS); - mCaps.maxFragmentInputComponents = std::min(mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4); - - mCaps.compressedTextureFormats.clear(); - - const TextureCapsMap &rendererFormats = mRenderer->getRendererTextureCaps(); - for (TextureCapsMap::const_iterator i = rendererFormats.begin(); i != rendererFormats.end(); i++) + if (getClientVersion() < ES_3_1) { - GLenum format = i->first; - TextureCaps formatCaps = i->second; + mCaps.maxVertexAttribBindings = mCaps.maxVertexAttributes; + } + else + { + LimitCap(&mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS); + } - const InternalFormat &formatInfo = GetInternalFormatInfo(format); + LimitCap(&mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS); + LimitCap(&mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4); + LimitCap(&mCaps.maxFragmentInputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4); + + // Limit textures as well, so we can use fast bitsets with texture bindings. + LimitCap(&mCaps.maxCombinedTextureImageUnits, IMPLEMENTATION_MAX_ACTIVE_TEXTURES); + LimitCap(&mCaps.maxVertexTextureImageUnits, IMPLEMENTATION_MAX_ACTIVE_TEXTURES / 2); + LimitCap(&mCaps.maxTextureImageUnits, IMPLEMENTATION_MAX_ACTIVE_TEXTURES / 2); + + mCaps.maxSampleMaskWords = std::min(mCaps.maxSampleMaskWords, MAX_SAMPLE_MASK_WORDS); + + // WebGL compatibility + mExtensions.webglCompatibility = mWebGLContext; + for (const auto &extensionInfo : GetExtensionInfoMap()) + { + // If this context is for WebGL, disable all enableable extensions + if (mWebGLContext && extensionInfo.second.Requestable) + { + mExtensions.*(extensionInfo.second.ExtensionsMember) = false; + } + } + + // Generate texture caps + updateCaps(); +} + +void Context::updateCaps() +{ + mCaps.compressedTextureFormats.clear(); + mTextureCaps.clear(); + + for (GLenum sizedInternalFormat : GetAllSizedInternalFormats()) + { + TextureCaps formatCaps = mImplementation->getNativeTextureCaps().get(sizedInternalFormat); + const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat); // Update the format caps based on the client version and extensions. // Caps are AND'd with the renderer caps because some core formats are still unsupported in // ES3. formatCaps.texturable = - formatCaps.texturable && formatInfo.textureSupport(clientVersion, mExtensions); + formatCaps.texturable && formatInfo.textureSupport(getClientVersion(), mExtensions); formatCaps.renderable = - formatCaps.renderable && formatInfo.renderSupport(clientVersion, mExtensions); + formatCaps.renderable && formatInfo.renderSupport(getClientVersion(), mExtensions); formatCaps.filterable = - formatCaps.filterable && formatInfo.filterSupport(clientVersion, mExtensions); + formatCaps.filterable && formatInfo.filterSupport(getClientVersion(), mExtensions); - // OpenGL ES does not support multisampling with integer formats - if (!formatInfo.renderSupport || formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT) + // OpenGL ES does not support multisampling with non-rendererable formats + // OpenGL ES 3.0 or prior does not support multisampling with integer formats + if (!formatCaps.renderable || + (getClientVersion() < ES_3_1 && + (formatInfo.componentType == GL_INT || formatInfo.componentType == GL_UNSIGNED_INT))) { formatCaps.sampleCounts.clear(); } + else + { + // We may have limited the max samples for some required renderbuffer formats due to + // non-conformant formats. In this case MAX_SAMPLES needs to be lowered accordingly. + GLuint formatMaxSamples = formatCaps.getMaxSamples(); + + // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers + // in these required formats with up to the value of MAX_SAMPLES multisamples, with the + // exception of signed and unsigned integer formats." + if (formatInfo.componentType != GL_INT && formatInfo.componentType != GL_UNSIGNED_INT && + formatInfo.isRequiredRenderbufferFormat(getClientVersion())) + { + ASSERT(getClientVersion() < ES_3_0 || formatMaxSamples >= 4); + mCaps.maxSamples = std::min(mCaps.maxSamples, formatMaxSamples); + } + + // Handle GLES 3.1 MAX_*_SAMPLES values similarly to MAX_SAMPLES. + if (getClientVersion() >= ES_3_1) + { + // GLES 3.1 section 9.2.5: "Implementations must support creation of renderbuffers + // in these required formats with up to the value of MAX_SAMPLES multisamples, with + // the exception that the signed and unsigned integer formats are required only to + // support creation of renderbuffers with up to the value of MAX_INTEGER_SAMPLES + // multisamples, which must be at least one." + if (formatInfo.componentType == GL_INT || + formatInfo.componentType == GL_UNSIGNED_INT) + { + mCaps.maxIntegerSamples = std::min(mCaps.maxIntegerSamples, formatMaxSamples); + } + + // GLES 3.1 section 19.3.1. + if (formatCaps.texturable) + { + if (formatInfo.depthBits > 0) + { + mCaps.maxDepthTextureSamples = + std::min(mCaps.maxDepthTextureSamples, formatMaxSamples); + } + else if (formatInfo.redBits > 0) + { + mCaps.maxColorTextureSamples = + std::min(mCaps.maxColorTextureSamples, formatMaxSamples); + } + } + } + } if (formatCaps.texturable && formatInfo.compressed) { - mCaps.compressedTextureFormats.push_back(format); + mCaps.compressedTextureFormats.push_back(sizedInternalFormat); } - mTextureCaps.insert(format, formatCaps); + mTextureCaps.insert(sizedInternalFormat, formatCaps); } + + // If program binary is disabled, blank out the memory cache pointer. + if (!mImplementation->getNativeExtensions().getProgramBinary) + { + mMemoryProgramCache = nullptr; + } +} + +void Context::initWorkarounds() +{ + // Apply back-end workarounds. + mImplementation->applyNativeWorkarounds(&mWorkarounds); + + // Lose the context upon out of memory error if the application is + // expecting to watch for those events. + mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT); +} + +Error Context::prepareForDraw() +{ + syncRendererState(); + + if (isRobustResourceInitEnabled()) + { + ANGLE_TRY(mGLState.clearUnclearedActiveTextures(this)); + ANGLE_TRY(mGLState.getDrawFramebuffer()->ensureDrawAttachmentsInitialized(this)); + } + + return NoError(); } void Context::syncRendererState() { - const State::DirtyBits &dirtyBits = mState.getDirtyBits(); - mRenderer->syncState(mState, dirtyBits); - mState.clearDirtyBits(); - mState.syncDirtyObjects(); + mGLState.syncDirtyObjects(this); + const State::DirtyBits &dirtyBits = mGLState.getDirtyBits(); + mImplementation->syncState(this, dirtyBits); + mGLState.clearDirtyBits(); } -void Context::syncRendererState(const State::DirtyBits &bitMask) +void Context::syncRendererState(const State::DirtyBits &bitMask, + const State::DirtyObjects &objectMask) { - const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask); - mRenderer->syncState(mState, dirtyBits); - mState.clearDirtyBits(dirtyBits); - - // TODO(jmadill): Filter objects by bitMask somehow? - mState.syncDirtyObjects(); + mGLState.syncDirtyObjects(this, objectMask); + const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask); + mImplementation->syncState(this, dirtyBits); + mGLState.clearDirtyBits(dirtyBits); } void Context::blitFramebuffer(GLint srcX0, @@ -2065,76 +2786,44 @@ void Context::blitFramebuffer(GLint srcX0, GLbitfield mask, GLenum filter) { - Framebuffer *readFramebuffer = mState.getReadFramebuffer(); - ASSERT(readFramebuffer); - - Framebuffer *drawFramebuffer = mState.getDrawFramebuffer(); + Framebuffer *drawFramebuffer = mGLState.getDrawFramebuffer(); ASSERT(drawFramebuffer); Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0); Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0); - syncRendererState(mState.blitStateBitMask()); + syncStateForBlit(); - Error error = drawFramebuffer->blit(mState, srcArea, dstArea, mask, filter, readFramebuffer); - if (error.isError()) - { - recordError(error); - return; - } + handleError(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter)); } void Context::clear(GLbitfield mask) { - // Sync the clear state - syncRendererState(mState.clearStateBitMask()); - - Error error = mState.getDrawFramebuffer()->clear(mData, mask); - if (error.isError()) - { - recordError(error); - } + syncStateForClear(); + handleError(mGLState.getDrawFramebuffer()->clear(this, mask)); } void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values) { - // Sync the clear state - syncRendererState(mState.clearStateBitMask()); - - Error error = mState.getDrawFramebuffer()->clearBufferfv(mData, buffer, drawbuffer, values); - if (error.isError()) - { - recordError(error); - } + syncStateForClear(); + handleError(mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values)); } void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values) { - // Sync the clear state - syncRendererState(mState.clearStateBitMask()); - - Error error = mState.getDrawFramebuffer()->clearBufferuiv(mData, buffer, drawbuffer, values); - if (error.isError()) - { - recordError(error); - } + syncStateForClear(); + handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values)); } void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values) { - // Sync the clear state - syncRendererState(mState.clearStateBitMask()); - - Error error = mState.getDrawFramebuffer()->clearBufferiv(mData, buffer, drawbuffer, values); - if (error.isError()) - { - recordError(error); - } + syncStateForClear(); + handleError(mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values)); } void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) { - Framebuffer *framebufferObject = mState.getDrawFramebuffer(); + Framebuffer *framebufferObject = mGLState.getDrawFramebuffer(); ASSERT(framebufferObject); // If a buffer is not present, the clear has no effect @@ -2144,14 +2833,8 @@ void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLin return; } - // Sync the clear state - syncRendererState(mState.clearStateBitMask()); - - Error error = framebufferObject->clearBufferfi(mData, buffer, drawbuffer, depth, stencil); - if (error.isError()) - { - recordError(error); - } + syncStateForClear(); + handleError(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil)); } void Context::readPixels(GLint x, @@ -2160,20 +2843,20 @@ void Context::readPixels(GLint x, GLsizei height, GLenum format, GLenum type, - GLvoid *pixels) + void *pixels) { - // Sync pack state - syncRendererState(mState.packStateBitMask()); + if (width == 0 || height == 0) + { + return; + } - Framebuffer *framebufferObject = mState.getReadFramebuffer(); - ASSERT(framebufferObject); + syncStateForReadPixels(); + + Framebuffer *readFBO = mGLState.getReadFramebuffer(); + ASSERT(readFBO); Rectangle area(x, y, width, height); - Error error = framebufferObject->readPixels(mState, area, format, type, pixels); - if (error.isError()) - { - recordError(error); - } + handleError(readFBO->readPixels(this, area, format, type, pixels)); } void Context::copyTexImage2D(GLenum target, @@ -2186,18 +2869,14 @@ void Context::copyTexImage2D(GLenum target, GLint border) { // Only sync the read FBO - mState.syncDirtyObject(GL_READ_FRAMEBUFFER); + mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER); Rectangle sourceArea(x, y, width, height); - const Framebuffer *framebuffer = mState.getReadFramebuffer(); + Framebuffer *framebuffer = mGLState.getReadFramebuffer(); Texture *texture = getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); - Error error = texture->copyImage(target, level, sourceArea, internalformat, framebuffer); - if (error.isError()) - { - recordError(error); - } + handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer)); } void Context::copyTexSubImage2D(GLenum target, @@ -2209,20 +2888,21 @@ void Context::copyTexSubImage2D(GLenum target, GLsizei width, GLsizei height) { + if (width == 0 || height == 0) + { + return; + } + // Only sync the read FBO - mState.syncDirtyObject(GL_READ_FRAMEBUFFER); + mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER); Offset destOffset(xoffset, yoffset, 0); Rectangle sourceArea(x, y, width, height); - const Framebuffer *framebuffer = mState.getReadFramebuffer(); + Framebuffer *framebuffer = mGLState.getReadFramebuffer(); Texture *texture = getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); - Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer); - if (error.isError()) - { - recordError(error); - } + handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer)); } void Context::copyTexSubImage3D(GLenum target, @@ -2235,19 +2915,20 @@ void Context::copyTexSubImage3D(GLenum target, GLsizei width, GLsizei height) { + if (width == 0 || height == 0) + { + return; + } + // Only sync the read FBO - mState.syncDirtyObject(GL_READ_FRAMEBUFFER); + mGLState.syncDirtyObject(this, GL_READ_FRAMEBUFFER); Offset destOffset(xoffset, yoffset, zoffset); Rectangle sourceArea(x, y, width, height); - const Framebuffer *framebuffer = mState.getReadFramebuffer(); - Texture *texture = getTargetTexture(target); - Error error = texture->copySubImage(target, level, destOffset, sourceArea, framebuffer); - if (error.isError()) - { - recordError(error); - } + Framebuffer *framebuffer = mGLState.getReadFramebuffer(); + Texture *texture = getTargetTexture(target); + handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer)); } void Context::framebufferTexture2D(GLenum target, @@ -2256,7 +2937,7 @@ void Context::framebufferTexture2D(GLenum target, GLuint texture, GLint level) { - Framebuffer *framebuffer = mState.getTargetFramebuffer(target); + Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target); ASSERT(framebuffer); if (texture != 0) @@ -2269,20 +2950,29 @@ void Context::framebufferTexture2D(GLenum target, { index = ImageIndex::Make2D(level); } + else if (textarget == GL_TEXTURE_RECTANGLE_ANGLE) + { + index = ImageIndex::MakeRectangle(level); + } + else if (textarget == GL_TEXTURE_2D_MULTISAMPLE) + { + ASSERT(level == 0); + index = ImageIndex::Make2DMultisample(); + } else { ASSERT(IsCubeMapTextureTarget(textarget)); index = ImageIndex::MakeCube(textarget, level); } - framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj); + framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj); } else { - framebuffer->resetAttachment(attachment); + framebuffer->resetAttachment(this, attachment); } - mState.setObjectDirty(target); + mGLState.setObjectDirty(target); } void Context::framebufferRenderbuffer(GLenum target, @@ -2290,21 +2980,22 @@ void Context::framebufferRenderbuffer(GLenum target, GLenum renderbuffertarget, GLuint renderbuffer) { - Framebuffer *framebuffer = mState.getTargetFramebuffer(target); + Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target); ASSERT(framebuffer); if (renderbuffer != 0) { Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer); - framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(), + + framebuffer->setAttachment(this, GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(), renderbufferObject); } else { - framebuffer->resetAttachment(attachment); + framebuffer->resetAttachment(this, attachment); } - mState.setObjectDirty(target); + mGLState.setObjectDirty(target); } void Context::framebufferTextureLayer(GLenum target, @@ -2313,7 +3004,7 @@ void Context::framebufferTextureLayer(GLenum target, GLint level, GLint layer) { - Framebuffer *framebuffer = mState.getTargetFramebuffer(target); + Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target); ASSERT(framebuffer); if (texture != 0) @@ -2332,46 +3023,94 @@ void Context::framebufferTextureLayer(GLenum target, index = ImageIndex::Make2DArray(level, layer); } - framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject); + framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject); } else { - framebuffer->resetAttachment(attachment); + framebuffer->resetAttachment(this, attachment); } - mState.setObjectDirty(target); + mGLState.setObjectDirty(target); +} + +void Context::framebufferTextureMultiviewLayeredANGLE(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint baseViewIndex, + GLsizei numViews) +{ + Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target); + ASSERT(framebuffer); + + if (texture != 0) + { + Texture *textureObj = getTexture(texture); + + ImageIndex index = ImageIndex::Make2DArrayRange(level, baseViewIndex, numViews); + framebuffer->setAttachmentMultiviewLayered(this, GL_TEXTURE, attachment, index, textureObj, + numViews, baseViewIndex); + } + else + { + framebuffer->resetAttachment(this, attachment); + } + + mGLState.setObjectDirty(target); +} + +void Context::framebufferTextureMultiviewSideBySideANGLE(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLsizei numViews, + const GLint *viewportOffsets) +{ + Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target); + ASSERT(framebuffer); + + if (texture != 0) + { + Texture *textureObj = getTexture(texture); + + ImageIndex index = ImageIndex::Make2D(level); + framebuffer->setAttachmentMultiviewSideBySide(this, GL_TEXTURE, attachment, index, + textureObj, numViews, viewportOffsets); + } + else + { + framebuffer->resetAttachment(this, attachment); + } + + mGLState.setObjectDirty(target); } void Context::drawBuffers(GLsizei n, const GLenum *bufs) { - Framebuffer *framebuffer = mState.getDrawFramebuffer(); + Framebuffer *framebuffer = mGLState.getDrawFramebuffer(); ASSERT(framebuffer); framebuffer->setDrawBuffers(n, bufs); - mState.setObjectDirty(GL_DRAW_FRAMEBUFFER); + mGLState.setObjectDirty(GL_DRAW_FRAMEBUFFER); } void Context::readBuffer(GLenum mode) { - Framebuffer *readFBO = mState.getReadFramebuffer(); + Framebuffer *readFBO = mGLState.getReadFramebuffer(); readFBO->setReadBuffer(mode); - mState.setObjectDirty(GL_READ_FRAMEBUFFER); + mGLState.setObjectDirty(GL_READ_FRAMEBUFFER); } void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments) { // Only sync the FBO - mState.syncDirtyObject(target); + mGLState.syncDirtyObject(this, target); - Framebuffer *framebuffer = mState.getTargetFramebuffer(target); + Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target); ASSERT(framebuffer); // The specification isn't clear what should be done when the framebuffer isn't complete. // We leave it up to the framebuffer implementation to decide what to do. - Error error = framebuffer->discard(numAttachments, attachments); - if (error.isError()) - { - recordError(error); - } + handleError(framebuffer->discard(this, numAttachments, attachments)); } void Context::invalidateFramebuffer(GLenum target, @@ -2379,20 +3118,17 @@ void Context::invalidateFramebuffer(GLenum target, const GLenum *attachments) { // Only sync the FBO - mState.syncDirtyObject(target); + mGLState.syncDirtyObject(this, target); - Framebuffer *framebuffer = mState.getTargetFramebuffer(target); + Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target); ASSERT(framebuffer); - if (framebuffer->checkStatus(mData) == GL_FRAMEBUFFER_COMPLETE) + if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE) { - Error error = framebuffer->invalidate(numAttachments, attachments); - if (error.isError()) - { - recordError(error); - return; - } + return; } + + handleError(framebuffer->invalidate(this, numAttachments, attachments)); } void Context::invalidateSubFramebuffer(GLenum target, @@ -2404,21 +3140,2419 @@ void Context::invalidateSubFramebuffer(GLenum target, GLsizei height) { // Only sync the FBO - mState.syncDirtyObject(target); + mGLState.syncDirtyObject(this, target); - Framebuffer *framebuffer = mState.getTargetFramebuffer(target); + Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target); ASSERT(framebuffer); - if (framebuffer->checkStatus(mData) == GL_FRAMEBUFFER_COMPLETE) + if (framebuffer->checkStatus(this) != GL_FRAMEBUFFER_COMPLETE) { - Rectangle area(x, y, width, height); - Error error = framebuffer->invalidateSub(numAttachments, attachments, area); - if (error.isError()) - { - recordError(error); + return; + } + + Rectangle area(x, y, width, height); + handleError(framebuffer->invalidateSub(this, numAttachments, attachments, area)); +} + +void Context::texImage2D(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + const void *pixels) +{ + syncStateForTexImage(); + + Extents size(width, height, 1); + Texture *texture = + getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); + handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat, + size, format, type, reinterpret_cast(pixels))); +} + +void Context::texImage3D(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const void *pixels) +{ + syncStateForTexImage(); + + Extents size(width, height, depth); + Texture *texture = getTargetTexture(target); + handleError(texture->setImage(this, mGLState.getUnpackState(), target, level, internalformat, + size, format, type, reinterpret_cast(pixels))); +} + +void Context::texSubImage2D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void *pixels) +{ + // Zero sized uploads are valid but no-ops + if (width == 0 || height == 0) + { + return; + } + + syncStateForTexImage(); + + Box area(xoffset, yoffset, 0, width, height, 1); + Texture *texture = + getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); + handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format, + type, reinterpret_cast(pixels))); +} + +void Context::texSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *pixels) +{ + // Zero sized uploads are valid but no-ops + if (width == 0 || height == 0 || depth == 0) + { + return; + } + + syncStateForTexImage(); + + Box area(xoffset, yoffset, zoffset, width, height, depth); + Texture *texture = getTargetTexture(target); + handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format, + type, reinterpret_cast(pixels))); +} + +void Context::compressedTexImage2D(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + const void *data) +{ + syncStateForTexImage(); + + Extents size(width, height, 1); + Texture *texture = + getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); + handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level, + internalformat, size, imageSize, + reinterpret_cast(data))); +} + +void Context::compressedTexImage3D(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const void *data) +{ + syncStateForTexImage(); + + Extents size(width, height, depth); + Texture *texture = getTargetTexture(target); + handleError(texture->setCompressedImage(this, mGLState.getUnpackState(), target, level, + internalformat, size, imageSize, + reinterpret_cast(data))); +} + +void Context::compressedTexSubImage2D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const void *data) +{ + syncStateForTexImage(); + + Box area(xoffset, yoffset, 0, width, height, 1); + Texture *texture = + getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); + handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area, + format, imageSize, + reinterpret_cast(data))); +} + +void Context::compressedTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void *data) +{ + // Zero sized uploads are valid but no-ops + if (width == 0 || height == 0) + { + return; + } + + syncStateForTexImage(); + + Box area(xoffset, yoffset, zoffset, width, height, depth); + Texture *texture = getTargetTexture(target); + handleError(texture->setCompressedSubImage(this, mGLState.getUnpackState(), target, level, area, + format, imageSize, + reinterpret_cast(data))); +} + +void Context::generateMipmap(GLenum target) +{ + Texture *texture = getTargetTexture(target); + handleError(texture->generateMipmap(this)); +} + +void Context::copyTextureCHROMIUM(GLuint sourceId, + GLint sourceLevel, + GLenum destTarget, + GLuint destId, + GLint destLevel, + GLint internalFormat, + GLenum destType, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha) +{ + syncStateForTexImage(); + + gl::Texture *sourceTexture = getTexture(sourceId); + gl::Texture *destTexture = getTexture(destId); + handleError(destTexture->copyTexture(this, destTarget, destLevel, internalFormat, destType, + sourceLevel, ConvertToBool(unpackFlipY), + ConvertToBool(unpackPremultiplyAlpha), + ConvertToBool(unpackUnmultiplyAlpha), sourceTexture)); +} + +void Context::copySubTextureCHROMIUM(GLuint sourceId, + GLint sourceLevel, + GLenum destTarget, + GLuint destId, + GLint destLevel, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha) +{ + // Zero sized copies are valid but no-ops + if (width == 0 || height == 0) + { + return; + } + + syncStateForTexImage(); + + gl::Texture *sourceTexture = getTexture(sourceId); + gl::Texture *destTexture = getTexture(destId); + Offset offset(xoffset, yoffset, 0); + Rectangle area(x, y, width, height); + handleError(destTexture->copySubTexture(this, destTarget, destLevel, offset, sourceLevel, area, + ConvertToBool(unpackFlipY), + ConvertToBool(unpackPremultiplyAlpha), + ConvertToBool(unpackUnmultiplyAlpha), sourceTexture)); +} + +void Context::compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId) +{ + syncStateForTexImage(); + + gl::Texture *sourceTexture = getTexture(sourceId); + gl::Texture *destTexture = getTexture(destId); + handleError(destTexture->copyCompressedTexture(this, sourceTexture)); +} + +void Context::getBufferPointerv(BufferBinding target, GLenum pname, void **params) +{ + Buffer *buffer = mGLState.getTargetBuffer(target); + ASSERT(buffer); + + QueryBufferPointerv(buffer, pname, params); +} + +void *Context::mapBuffer(BufferBinding target, GLenum access) +{ + Buffer *buffer = mGLState.getTargetBuffer(target); + ASSERT(buffer); + + Error error = buffer->map(this, access); + if (error.isError()) + { + handleError(error); + return nullptr; + } + + return buffer->getMapPointer(); +} + +GLboolean Context::unmapBuffer(BufferBinding target) +{ + Buffer *buffer = mGLState.getTargetBuffer(target); + ASSERT(buffer); + + GLboolean result; + Error error = buffer->unmap(this, &result); + if (error.isError()) + { + handleError(error); + return GL_FALSE; + } + + return result; +} + +void *Context::mapBufferRange(BufferBinding target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access) +{ + Buffer *buffer = mGLState.getTargetBuffer(target); + ASSERT(buffer); + + Error error = buffer->mapRange(this, offset, length, access); + if (error.isError()) + { + handleError(error); + return nullptr; + } + + return buffer->getMapPointer(); +} + +void Context::flushMappedBufferRange(BufferBinding /*target*/, + GLintptr /*offset*/, + GLsizeiptr /*length*/) +{ + // We do not currently support a non-trivial implementation of FlushMappedBufferRange +} + +void Context::syncStateForReadPixels() +{ + syncRendererState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects); +} + +void Context::syncStateForTexImage() +{ + syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects); +} + +void Context::syncStateForClear() +{ + syncRendererState(mClearDirtyBits, mClearDirtyObjects); +} + +void Context::syncStateForBlit() +{ + syncRendererState(mBlitDirtyBits, mBlitDirtyObjects); +} + +void Context::activeShaderProgram(GLuint pipeline, GLuint program) +{ + UNIMPLEMENTED(); +} + +void Context::activeTexture(GLenum texture) +{ + mGLState.setActiveSampler(texture - GL_TEXTURE0); +} + +void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) +{ + mGLState.setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha)); +} + +void Context::blendEquation(GLenum mode) +{ + mGLState.setBlendEquation(mode, mode); +} + +void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) +{ + mGLState.setBlendEquation(modeRGB, modeAlpha); +} + +void Context::blendFunc(GLenum sfactor, GLenum dfactor) +{ + mGLState.setBlendFactors(sfactor, dfactor, sfactor, dfactor); +} + +void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) +{ + mGLState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha); +} + +void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) +{ + mGLState.setColorClearValue(red, green, blue, alpha); +} + +void Context::clearDepthf(GLfloat depth) +{ + mGLState.setDepthClearValue(depth); +} + +void Context::clearStencil(GLint s) +{ + mGLState.setStencilClearValue(s); +} + +void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) +{ + mGLState.setColorMask(ConvertToBool(red), ConvertToBool(green), ConvertToBool(blue), + ConvertToBool(alpha)); +} + +void Context::cullFace(CullFaceMode mode) +{ + mGLState.setCullMode(mode); +} + +void Context::depthFunc(GLenum func) +{ + mGLState.setDepthFunc(func); +} + +void Context::depthMask(GLboolean flag) +{ + mGLState.setDepthMask(ConvertToBool(flag)); +} + +void Context::depthRangef(GLfloat zNear, GLfloat zFar) +{ + mGLState.setDepthRange(zNear, zFar); +} + +void Context::disable(GLenum cap) +{ + mGLState.setEnableFeature(cap, false); +} + +void Context::disableVertexAttribArray(GLuint index) +{ + mGLState.setEnableVertexAttribArray(index, false); +} + +void Context::enable(GLenum cap) +{ + mGLState.setEnableFeature(cap, true); +} + +void Context::enableVertexAttribArray(GLuint index) +{ + mGLState.setEnableVertexAttribArray(index, true); +} + +void Context::frontFace(GLenum mode) +{ + mGLState.setFrontFace(mode); +} + +void Context::hint(GLenum target, GLenum mode) +{ + switch (target) + { + case GL_GENERATE_MIPMAP_HINT: + mGLState.setGenerateMipmapHint(mode); + break; + + case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: + mGLState.setFragmentShaderDerivativeHint(mode); + break; + + default: + UNREACHABLE(); return; + } +} + +void Context::lineWidth(GLfloat width) +{ + mGLState.setLineWidth(width); +} + +void Context::pixelStorei(GLenum pname, GLint param) +{ + switch (pname) + { + case GL_UNPACK_ALIGNMENT: + mGLState.setUnpackAlignment(param); + break; + + case GL_PACK_ALIGNMENT: + mGLState.setPackAlignment(param); + break; + + case GL_PACK_REVERSE_ROW_ORDER_ANGLE: + mGLState.setPackReverseRowOrder(param != 0); + break; + + case GL_UNPACK_ROW_LENGTH: + ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage); + mGLState.setUnpackRowLength(param); + break; + + case GL_UNPACK_IMAGE_HEIGHT: + ASSERT(getClientMajorVersion() >= 3); + mGLState.setUnpackImageHeight(param); + break; + + case GL_UNPACK_SKIP_IMAGES: + ASSERT(getClientMajorVersion() >= 3); + mGLState.setUnpackSkipImages(param); + break; + + case GL_UNPACK_SKIP_ROWS: + ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage); + mGLState.setUnpackSkipRows(param); + break; + + case GL_UNPACK_SKIP_PIXELS: + ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimage); + mGLState.setUnpackSkipPixels(param); + break; + + case GL_PACK_ROW_LENGTH: + ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage); + mGLState.setPackRowLength(param); + break; + + case GL_PACK_SKIP_ROWS: + ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage); + mGLState.setPackSkipRows(param); + break; + + case GL_PACK_SKIP_PIXELS: + ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimage); + mGLState.setPackSkipPixels(param); + break; + + default: + UNREACHABLE(); + return; + } +} + +void Context::polygonOffset(GLfloat factor, GLfloat units) +{ + mGLState.setPolygonOffsetParams(factor, units); +} + +void Context::sampleCoverage(GLfloat value, GLboolean invert) +{ + mGLState.setSampleCoverageParams(clamp01(value), ConvertToBool(invert)); +} + +void Context::sampleMaski(GLuint maskNumber, GLbitfield mask) +{ + mGLState.setSampleMaskParams(maskNumber, mask); +} + +void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height) +{ + mGLState.setScissorParams(x, y, width, height); +} + +void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) +{ + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) + { + mGLState.setStencilParams(func, ref, mask); + } + + if (face == GL_BACK || face == GL_FRONT_AND_BACK) + { + mGLState.setStencilBackParams(func, ref, mask); + } +} + +void Context::stencilMaskSeparate(GLenum face, GLuint mask) +{ + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) + { + mGLState.setStencilWritemask(mask); + } + + if (face == GL_BACK || face == GL_FRONT_AND_BACK) + { + mGLState.setStencilBackWritemask(mask); + } +} + +void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) +{ + if (face == GL_FRONT || face == GL_FRONT_AND_BACK) + { + mGLState.setStencilOperations(fail, zfail, zpass); + } + + if (face == GL_BACK || face == GL_FRONT_AND_BACK) + { + mGLState.setStencilBackOperations(fail, zfail, zpass); + } +} + +void Context::vertexAttrib1f(GLuint index, GLfloat x) +{ + GLfloat vals[4] = {x, 0, 0, 1}; + mGLState.setVertexAttribf(index, vals); +} + +void Context::vertexAttrib1fv(GLuint index, const GLfloat *values) +{ + GLfloat vals[4] = {values[0], 0, 0, 1}; + mGLState.setVertexAttribf(index, vals); +} + +void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y) +{ + GLfloat vals[4] = {x, y, 0, 1}; + mGLState.setVertexAttribf(index, vals); +} + +void Context::vertexAttrib2fv(GLuint index, const GLfloat *values) +{ + GLfloat vals[4] = {values[0], values[1], 0, 1}; + mGLState.setVertexAttribf(index, vals); +} + +void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) +{ + GLfloat vals[4] = {x, y, z, 1}; + mGLState.setVertexAttribf(index, vals); +} + +void Context::vertexAttrib3fv(GLuint index, const GLfloat *values) +{ + GLfloat vals[4] = {values[0], values[1], values[2], 1}; + mGLState.setVertexAttribf(index, vals); +} + +void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + GLfloat vals[4] = {x, y, z, w}; + mGLState.setVertexAttribf(index, vals); +} + +void Context::vertexAttrib4fv(GLuint index, const GLfloat *values) +{ + mGLState.setVertexAttribf(index, values); +} + +void Context::vertexAttribPointer(GLuint index, + GLint size, + GLenum type, + GLboolean normalized, + GLsizei stride, + const void *ptr) +{ + mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(BufferBinding::Array), + size, type, ConvertToBool(normalized), false, stride, ptr); +} + +void Context::vertexAttribFormat(GLuint attribIndex, + GLint size, + GLenum type, + GLboolean normalized, + GLuint relativeOffset) +{ + mGLState.setVertexAttribFormat(attribIndex, size, type, ConvertToBool(normalized), false, + relativeOffset); +} + +void Context::vertexAttribIFormat(GLuint attribIndex, + GLint size, + GLenum type, + GLuint relativeOffset) +{ + mGLState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset); +} + +void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex) +{ + mGLState.setVertexAttribBinding(this, attribIndex, bindingIndex); +} + +void Context::vertexBindingDivisor(GLuint bindingIndex, GLuint divisor) +{ + mGLState.setVertexBindingDivisor(bindingIndex, divisor); +} + +void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height) +{ + mGLState.setViewportParams(x, y, width, height); +} + +void Context::vertexAttribIPointer(GLuint index, + GLint size, + GLenum type, + GLsizei stride, + const void *pointer) +{ + mGLState.setVertexAttribPointer(this, index, mGLState.getTargetBuffer(BufferBinding::Array), + size, type, false, true, stride, pointer); +} + +void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w) +{ + GLint vals[4] = {x, y, z, w}; + mGLState.setVertexAttribi(index, vals); +} + +void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) +{ + GLuint vals[4] = {x, y, z, w}; + mGLState.setVertexAttribu(index, vals); +} + +void Context::vertexAttribI4iv(GLuint index, const GLint *v) +{ + mGLState.setVertexAttribi(index, v); +} + +void Context::vertexAttribI4uiv(GLuint index, const GLuint *v) +{ + mGLState.setVertexAttribu(index, v); +} + +void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params) +{ + const VertexAttribCurrentValueData ¤tValues = + getGLState().getVertexAttribCurrentValue(index); + const VertexArray *vao = getGLState().getVertexArray(); + QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index), + currentValues, pname, params); +} + +void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params) +{ + const VertexAttribCurrentValueData ¤tValues = + getGLState().getVertexAttribCurrentValue(index); + const VertexArray *vao = getGLState().getVertexArray(); + QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index), + currentValues, pname, params); +} + +void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params) +{ + const VertexAttribCurrentValueData ¤tValues = + getGLState().getVertexAttribCurrentValue(index); + const VertexArray *vao = getGLState().getVertexArray(); + QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index), + currentValues, pname, params); +} + +void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params) +{ + const VertexAttribCurrentValueData ¤tValues = + getGLState().getVertexAttribCurrentValue(index); + const VertexArray *vao = getGLState().getVertexArray(); + QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index), + currentValues, pname, params); +} + +void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer) +{ + const VertexAttribute &attrib = getGLState().getVertexArray()->getVertexAttribute(index); + QueryVertexAttribPointerv(attrib, pname, pointer); +} + +void Context::debugMessageControl(GLenum source, + GLenum type, + GLenum severity, + GLsizei count, + const GLuint *ids, + GLboolean enabled) +{ + std::vector idVector(ids, ids + count); + mGLState.getDebug().setMessageControl(source, type, severity, std::move(idVector), + ConvertToBool(enabled)); +} + +void Context::debugMessageInsert(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar *buf) +{ + std::string msg(buf, (length > 0) ? static_cast(length) : strlen(buf)); + mGLState.getDebug().insertMessage(source, type, id, severity, std::move(msg)); +} + +void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam) +{ + mGLState.getDebug().setCallback(callback, userParam); +} + +GLuint Context::getDebugMessageLog(GLuint count, + GLsizei bufSize, + GLenum *sources, + GLenum *types, + GLuint *ids, + GLenum *severities, + GLsizei *lengths, + GLchar *messageLog) +{ + return static_cast(mGLState.getDebug().getMessages(count, bufSize, sources, types, ids, + severities, lengths, messageLog)); +} + +void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message) +{ + std::string msg(message, (length > 0) ? static_cast(length) : strlen(message)); + mGLState.getDebug().pushGroup(source, id, std::move(msg)); + mImplementation->pushDebugGroup(source, id, length, message); +} + +void Context::popDebugGroup() +{ + mGLState.getDebug().popGroup(); + mImplementation->popDebugGroup(); +} + +void Context::bufferData(BufferBinding target, GLsizeiptr size, const void *data, BufferUsage usage) +{ + Buffer *buffer = mGLState.getTargetBuffer(target); + ASSERT(buffer); + handleError(buffer->bufferData(this, target, data, size, usage)); +} + +void Context::bufferSubData(BufferBinding target, + GLintptr offset, + GLsizeiptr size, + const void *data) +{ + if (data == nullptr) + { + return; + } + + Buffer *buffer = mGLState.getTargetBuffer(target); + ASSERT(buffer); + handleError(buffer->bufferSubData(this, target, data, size, offset)); +} + +void Context::attachShader(GLuint program, GLuint shader) +{ + Program *programObject = mState.mShaderPrograms->getProgram(program); + Shader *shaderObject = mState.mShaderPrograms->getShader(shader); + ASSERT(programObject && shaderObject); + programObject->attachShader(shaderObject); +} + +const Workarounds &Context::getWorkarounds() const +{ + return mWorkarounds; +} + +void Context::copyBufferSubData(BufferBinding readTarget, + BufferBinding writeTarget, + GLintptr readOffset, + GLintptr writeOffset, + GLsizeiptr size) +{ + // if size is zero, the copy is a successful no-op + if (size == 0) + { + return; + } + + // TODO(jmadill): cache these. + Buffer *readBuffer = mGLState.getTargetBuffer(readTarget); + Buffer *writeBuffer = mGLState.getTargetBuffer(writeTarget); + + handleError(writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size)); +} + +void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name) +{ + Program *programObject = getProgram(program); + // TODO(jmadill): Re-use this from the validation if possible. + ASSERT(programObject); + programObject->bindAttributeLocation(index, name); +} + +void Context::bindBuffer(BufferBinding target, GLuint buffer) +{ + Buffer *bufferObject = mState.mBuffers->checkBufferAllocation(mImplementation.get(), buffer); + mGLState.setBufferBinding(this, target, bufferObject); +} + +void Context::bindBufferBase(BufferBinding target, GLuint index, GLuint buffer) +{ + bindBufferRange(target, index, buffer, 0, 0); +} + +void Context::bindBufferRange(BufferBinding target, + GLuint index, + GLuint buffer, + GLintptr offset, + GLsizeiptr size) +{ + Buffer *bufferObject = mState.mBuffers->checkBufferAllocation(mImplementation.get(), buffer); + mGLState.setIndexedBufferBinding(this, target, index, bufferObject, offset, size); +} + +void Context::bindFramebuffer(GLenum target, GLuint framebuffer) +{ + if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER) + { + bindReadFramebuffer(framebuffer); + } + + if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER) + { + bindDrawFramebuffer(framebuffer); + } +} + +void Context::bindRenderbuffer(GLenum target, GLuint renderbuffer) +{ + ASSERT(target == GL_RENDERBUFFER); + Renderbuffer *object = + mState.mRenderbuffers->checkRenderbufferAllocation(mImplementation.get(), renderbuffer); + mGLState.setRenderbufferBinding(this, object); +} + +void Context::texStorage2DMultisample(GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations) +{ + Extents size(width, height, 1); + Texture *texture = getTargetTexture(target); + handleError(texture->setStorageMultisample(this, target, samples, internalformat, size, + ConvertToBool(fixedsamplelocations))); +} + +void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val) +{ + // According to spec 3.1 Table 20.49: Framebuffer Dependent Values, + // the sample position should be queried by DRAW_FRAMEBUFFER. + mGLState.syncDirtyObject(this, GL_DRAW_FRAMEBUFFER); + const Framebuffer *framebuffer = mGLState.getDrawFramebuffer(); + + switch (pname) + { + case GL_SAMPLE_POSITION: + handleError(framebuffer->getSamplePosition(index, val)); + break; + default: + UNREACHABLE(); + } +} + +void Context::renderbufferStorage(GLenum target, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format. + GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat); + + Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer(); + handleError(renderbuffer->setStorage(this, convertedInternalFormat, width, height)); +} + +void Context::renderbufferStorageMultisample(GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format. + GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat); + + Renderbuffer *renderbuffer = mGLState.getCurrentRenderbuffer(); + handleError( + renderbuffer->setStorageMultisample(this, samples, convertedInternalFormat, width, height)); +} + +void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values) +{ + const Sync *syncObject = getSync(sync); + handleError(QuerySynciv(syncObject, pname, bufSize, length, values)); +} + +void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params) +{ + Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target); + QueryFramebufferParameteriv(framebuffer, pname, params); +} + +void Context::framebufferParameteri(GLenum target, GLenum pname, GLint param) +{ + Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target); + SetFramebufferParameteri(framebuffer, pname, param); +} + +Error Context::getScratchBuffer(size_t requstedSizeBytes, + angle::MemoryBuffer **scratchBufferOut) const +{ + if (!mScratchBuffer.get(requstedSizeBytes, scratchBufferOut)) + { + return OutOfMemory() << "Failed to allocate internal buffer."; + } + return NoError(); +} + +Error Context::getZeroFilledBuffer(size_t requstedSizeBytes, + angle::MemoryBuffer **zeroBufferOut) const +{ + if (!mZeroFilledBuffer.getInitialized(requstedSizeBytes, zeroBufferOut, 0)) + { + return OutOfMemory() << "Failed to allocate internal buffer."; + } + return NoError(); +} + +void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ) +{ + if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u) + { + return; + } + + // TODO(jmadill): Dirty bits for compute. + if (isRobustResourceInitEnabled()) + { + ANGLE_CONTEXT_TRY(mGLState.clearUnclearedActiveTextures(this)); + } + + handleError(mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ)); +} + +void Context::dispatchComputeIndirect(GLintptr indirect) +{ + UNIMPLEMENTED(); +} + +void Context::texStorage2D(GLenum target, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height) +{ + Extents size(width, height, 1); + Texture *texture = getTargetTexture(target); + handleError(texture->setStorage(this, target, levels, internalFormat, size)); +} + +void Context::texStorage3D(GLenum target, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth) +{ + Extents size(width, height, depth); + Texture *texture = getTargetTexture(target); + handleError(texture->setStorage(this, target, levels, internalFormat, size)); +} + +void Context::memoryBarrier(GLbitfield barriers) +{ + UNIMPLEMENTED(); +} + +void Context::memoryBarrierByRegion(GLbitfield barriers) +{ + UNIMPLEMENTED(); +} + +GLenum Context::checkFramebufferStatus(GLenum target) +{ + Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target); + ASSERT(framebuffer); + + return framebuffer->checkStatus(this); +} + +void Context::compileShader(GLuint shader) +{ + Shader *shaderObject = GetValidShader(this, shader); + if (!shaderObject) + { + return; + } + shaderObject->compile(this); +} + +void Context::deleteBuffers(GLsizei n, const GLuint *buffers) +{ + for (int i = 0; i < n; i++) + { + deleteBuffer(buffers[i]); + } +} + +void Context::deleteFramebuffers(GLsizei n, const GLuint *framebuffers) +{ + for (int i = 0; i < n; i++) + { + if (framebuffers[i] != 0) + { + deleteFramebuffer(framebuffers[i]); } } } +void Context::deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers) +{ + for (int i = 0; i < n; i++) + { + deleteRenderbuffer(renderbuffers[i]); + } +} + +void Context::deleteTextures(GLsizei n, const GLuint *textures) +{ + for (int i = 0; i < n; i++) + { + if (textures[i] != 0) + { + deleteTexture(textures[i]); + } + } +} + +void Context::detachShader(GLuint program, GLuint shader) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + + Shader *shaderObject = getShader(shader); + ASSERT(shaderObject); + + programObject->detachShader(this, shaderObject); +} + +void Context::genBuffers(GLsizei n, GLuint *buffers) +{ + for (int i = 0; i < n; i++) + { + buffers[i] = createBuffer(); + } +} + +void Context::genFramebuffers(GLsizei n, GLuint *framebuffers) +{ + for (int i = 0; i < n; i++) + { + framebuffers[i] = createFramebuffer(); + } +} + +void Context::genRenderbuffers(GLsizei n, GLuint *renderbuffers) +{ + for (int i = 0; i < n; i++) + { + renderbuffers[i] = createRenderbuffer(); + } +} + +void Context::genTextures(GLsizei n, GLuint *textures) +{ + for (int i = 0; i < n; i++) + { + textures[i] = createTexture(); + } +} + +void Context::getActiveAttrib(GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->getActiveAttribute(index, bufsize, length, size, type, name); +} + +void Context::getActiveUniform(GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->getActiveUniform(index, bufsize, length, size, type, name); +} + +void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->getAttachedShaders(maxcount, count, shaders); +} + +GLint Context::getAttribLocation(GLuint program, const GLchar *name) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + return programObject->getAttributeLocation(name); +} + +void Context::getBooleanv(GLenum pname, GLboolean *params) +{ + GLenum nativeType; + unsigned int numParams = 0; + getQueryParameterInfo(pname, &nativeType, &numParams); + + if (nativeType == GL_BOOL) + { + getBooleanvImpl(pname, params); + } + else + { + CastStateValues(this, nativeType, pname, numParams, params); + } +} + +void Context::getFloatv(GLenum pname, GLfloat *params) +{ + GLenum nativeType; + unsigned int numParams = 0; + getQueryParameterInfo(pname, &nativeType, &numParams); + + if (nativeType == GL_FLOAT) + { + getFloatvImpl(pname, params); + } + else + { + CastStateValues(this, nativeType, pname, numParams, params); + } +} + +void Context::getIntegerv(GLenum pname, GLint *params) +{ + GLenum nativeType; + unsigned int numParams = 0; + getQueryParameterInfo(pname, &nativeType, &numParams); + + if (nativeType == GL_INT) + { + getIntegervImpl(pname, params); + } + else + { + CastStateValues(this, nativeType, pname, numParams, params); + } +} + +void Context::getProgramiv(GLuint program, GLenum pname, GLint *params) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + QueryProgramiv(this, programObject, pname, params); +} + +void Context::getProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params) +{ + UNIMPLEMENTED(); +} + +void Context::getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->getInfoLog(bufsize, length, infolog); +} + +void Context::getProgramPipelineInfoLog(GLuint pipeline, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog) +{ + UNIMPLEMENTED(); +} + +void Context::getShaderiv(GLuint shader, GLenum pname, GLint *params) +{ + Shader *shaderObject = getShader(shader); + ASSERT(shaderObject); + QueryShaderiv(this, shaderObject, pname, params); +} + +void Context::getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog) +{ + Shader *shaderObject = getShader(shader); + ASSERT(shaderObject); + shaderObject->getInfoLog(this, bufsize, length, infolog); +} + +void Context::getShaderPrecisionFormat(GLenum shadertype, + GLenum precisiontype, + GLint *range, + GLint *precision) +{ + // TODO(jmadill): Compute shaders. + + switch (shadertype) + { + case GL_VERTEX_SHADER: + switch (precisiontype) + { + case GL_LOW_FLOAT: + mCaps.vertexLowpFloat.get(range, precision); + break; + case GL_MEDIUM_FLOAT: + mCaps.vertexMediumpFloat.get(range, precision); + break; + case GL_HIGH_FLOAT: + mCaps.vertexHighpFloat.get(range, precision); + break; + + case GL_LOW_INT: + mCaps.vertexLowpInt.get(range, precision); + break; + case GL_MEDIUM_INT: + mCaps.vertexMediumpInt.get(range, precision); + break; + case GL_HIGH_INT: + mCaps.vertexHighpInt.get(range, precision); + break; + + default: + UNREACHABLE(); + return; + } + break; + + case GL_FRAGMENT_SHADER: + switch (precisiontype) + { + case GL_LOW_FLOAT: + mCaps.fragmentLowpFloat.get(range, precision); + break; + case GL_MEDIUM_FLOAT: + mCaps.fragmentMediumpFloat.get(range, precision); + break; + case GL_HIGH_FLOAT: + mCaps.fragmentHighpFloat.get(range, precision); + break; + + case GL_LOW_INT: + mCaps.fragmentLowpInt.get(range, precision); + break; + case GL_MEDIUM_INT: + mCaps.fragmentMediumpInt.get(range, precision); + break; + case GL_HIGH_INT: + mCaps.fragmentHighpInt.get(range, precision); + break; + + default: + UNREACHABLE(); + return; + } + break; + + default: + UNREACHABLE(); + return; + } +} + +void Context::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source) +{ + Shader *shaderObject = getShader(shader); + ASSERT(shaderObject); + shaderObject->getSource(bufsize, length, source); +} + +void Context::getUniformfv(GLuint program, GLint location, GLfloat *params) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->getUniformfv(this, location, params); +} + +void Context::getUniformiv(GLuint program, GLint location, GLint *params) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->getUniformiv(this, location, params); +} + +GLint Context::getUniformLocation(GLuint program, const GLchar *name) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + return programObject->getUniformLocation(name); +} + +GLboolean Context::isBuffer(GLuint buffer) +{ + if (buffer == 0) + { + return GL_FALSE; + } + + return (getBuffer(buffer) ? GL_TRUE : GL_FALSE); +} + +GLboolean Context::isEnabled(GLenum cap) +{ + return mGLState.getEnableFeature(cap); +} + +GLboolean Context::isFramebuffer(GLuint framebuffer) +{ + if (framebuffer == 0) + { + return GL_FALSE; + } + + return (getFramebuffer(framebuffer) ? GL_TRUE : GL_FALSE); +} + +GLboolean Context::isProgram(GLuint program) +{ + if (program == 0) + { + return GL_FALSE; + } + + return (getProgram(program) ? GL_TRUE : GL_FALSE); +} + +GLboolean Context::isRenderbuffer(GLuint renderbuffer) +{ + if (renderbuffer == 0) + { + return GL_FALSE; + } + + return (getRenderbuffer(renderbuffer) ? GL_TRUE : GL_FALSE); +} + +GLboolean Context::isShader(GLuint shader) +{ + if (shader == 0) + { + return GL_FALSE; + } + + return (getShader(shader) ? GL_TRUE : GL_FALSE); +} + +GLboolean Context::isTexture(GLuint texture) +{ + if (texture == 0) + { + return GL_FALSE; + } + + return (getTexture(texture) ? GL_TRUE : GL_FALSE); +} + +void Context::linkProgram(GLuint program) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + handleError(programObject->link(this)); + mGLState.onProgramExecutableChange(programObject); +} + +void Context::releaseShaderCompiler() +{ + mCompiler.set(this, nullptr); +} + +void Context::shaderBinary(GLsizei n, + const GLuint *shaders, + GLenum binaryformat, + const void *binary, + GLsizei length) +{ + // No binary shader formats are supported. + UNIMPLEMENTED(); +} + +void Context::shaderSource(GLuint shader, + GLsizei count, + const GLchar *const *string, + const GLint *length) +{ + Shader *shaderObject = getShader(shader); + ASSERT(shaderObject); + shaderObject->setSource(count, string, length); +} + +void Context::stencilFunc(GLenum func, GLint ref, GLuint mask) +{ + stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask); +} + +void Context::stencilMask(GLuint mask) +{ + stencilMaskSeparate(GL_FRONT_AND_BACK, mask); +} + +void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass) +{ + stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass); +} + +void Context::uniform1f(GLint location, GLfloat x) +{ + Program *program = mGLState.getProgram(); + program->setUniform1fv(location, 1, &x); +} + +void Context::uniform1fv(GLint location, GLsizei count, const GLfloat *v) +{ + Program *program = mGLState.getProgram(); + program->setUniform1fv(location, count, v); +} + +void Context::uniform1i(GLint location, GLint x) +{ + Program *program = mGLState.getProgram(); + if (program->setUniform1iv(location, 1, &x) == Program::SetUniformResult::SamplerChanged) + { + mGLState.setObjectDirty(GL_PROGRAM); + } +} + +void Context::uniform1iv(GLint location, GLsizei count, const GLint *v) +{ + Program *program = mGLState.getProgram(); + if (program->setUniform1iv(location, count, v) == Program::SetUniformResult::SamplerChanged) + { + mGLState.setObjectDirty(GL_PROGRAM); + } +} + +void Context::uniform2f(GLint location, GLfloat x, GLfloat y) +{ + GLfloat xy[2] = {x, y}; + Program *program = mGLState.getProgram(); + program->setUniform2fv(location, 1, xy); +} + +void Context::uniform2fv(GLint location, GLsizei count, const GLfloat *v) +{ + Program *program = mGLState.getProgram(); + program->setUniform2fv(location, count, v); +} + +void Context::uniform2i(GLint location, GLint x, GLint y) +{ + GLint xy[2] = {x, y}; + Program *program = mGLState.getProgram(); + program->setUniform2iv(location, 1, xy); +} + +void Context::uniform2iv(GLint location, GLsizei count, const GLint *v) +{ + Program *program = mGLState.getProgram(); + program->setUniform2iv(location, count, v); +} + +void Context::uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) +{ + GLfloat xyz[3] = {x, y, z}; + Program *program = mGLState.getProgram(); + program->setUniform3fv(location, 1, xyz); +} + +void Context::uniform3fv(GLint location, GLsizei count, const GLfloat *v) +{ + Program *program = mGLState.getProgram(); + program->setUniform3fv(location, count, v); +} + +void Context::uniform3i(GLint location, GLint x, GLint y, GLint z) +{ + GLint xyz[3] = {x, y, z}; + Program *program = mGLState.getProgram(); + program->setUniform3iv(location, 1, xyz); +} + +void Context::uniform3iv(GLint location, GLsizei count, const GLint *v) +{ + Program *program = mGLState.getProgram(); + program->setUniform3iv(location, count, v); +} + +void Context::uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + GLfloat xyzw[4] = {x, y, z, w}; + Program *program = mGLState.getProgram(); + program->setUniform4fv(location, 1, xyzw); +} + +void Context::uniform4fv(GLint location, GLsizei count, const GLfloat *v) +{ + Program *program = mGLState.getProgram(); + program->setUniform4fv(location, count, v); +} + +void Context::uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) +{ + GLint xyzw[4] = {x, y, z, w}; + Program *program = mGLState.getProgram(); + program->setUniform4iv(location, 1, xyzw); +} + +void Context::uniform4iv(GLint location, GLsizei count, const GLint *v) +{ + Program *program = mGLState.getProgram(); + program->setUniform4iv(location, count, v); +} + +void Context::uniformMatrix2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *program = mGLState.getProgram(); + program->setUniformMatrix2fv(location, count, transpose, value); +} + +void Context::uniformMatrix3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *program = mGLState.getProgram(); + program->setUniformMatrix3fv(location, count, transpose, value); +} + +void Context::uniformMatrix4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *program = mGLState.getProgram(); + program->setUniformMatrix4fv(location, count, transpose, value); +} + +void Context::validateProgram(GLuint program) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->validate(mCaps); +} + +void Context::validateProgramPipeline(GLuint pipeline) +{ + UNIMPLEMENTED(); +} + +void Context::getProgramBinary(GLuint program, + GLsizei bufSize, + GLsizei *length, + GLenum *binaryFormat, + void *binary) +{ + Program *programObject = getProgram(program); + ASSERT(programObject != nullptr); + + handleError(programObject->saveBinary(this, binaryFormat, binary, bufSize, length)); +} + +void Context::programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length) +{ + Program *programObject = getProgram(program); + ASSERT(programObject != nullptr); + + handleError(programObject->loadBinary(this, binaryFormat, binary, length)); +} + +void Context::uniform1ui(GLint location, GLuint v0) +{ + Program *program = mGLState.getProgram(); + program->setUniform1uiv(location, 1, &v0); +} + +void Context::uniform2ui(GLint location, GLuint v0, GLuint v1) +{ + Program *program = mGLState.getProgram(); + const GLuint xy[] = {v0, v1}; + program->setUniform2uiv(location, 1, xy); +} + +void Context::uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) +{ + Program *program = mGLState.getProgram(); + const GLuint xyz[] = {v0, v1, v2}; + program->setUniform3uiv(location, 1, xyz); +} + +void Context::uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +{ + Program *program = mGLState.getProgram(); + const GLuint xyzw[] = {v0, v1, v2, v3}; + program->setUniform4uiv(location, 1, xyzw); +} + +void Context::uniform1uiv(GLint location, GLsizei count, const GLuint *value) +{ + Program *program = mGLState.getProgram(); + program->setUniform1uiv(location, count, value); +} +void Context::uniform2uiv(GLint location, GLsizei count, const GLuint *value) +{ + Program *program = mGLState.getProgram(); + program->setUniform2uiv(location, count, value); +} + +void Context::uniform3uiv(GLint location, GLsizei count, const GLuint *value) +{ + Program *program = mGLState.getProgram(); + program->setUniform3uiv(location, count, value); +} + +void Context::uniform4uiv(GLint location, GLsizei count, const GLuint *value) +{ + Program *program = mGLState.getProgram(); + program->setUniform4uiv(location, count, value); +} + +void Context::genQueries(GLsizei n, GLuint *ids) +{ + for (GLsizei i = 0; i < n; i++) + { + GLuint handle = mQueryHandleAllocator.allocate(); + mQueryMap.assign(handle, nullptr); + ids[i] = handle; + } +} + +void Context::deleteQueries(GLsizei n, const GLuint *ids) +{ + for (int i = 0; i < n; i++) + { + GLuint query = ids[i]; + + Query *queryObject = nullptr; + if (mQueryMap.erase(query, &queryObject)) + { + mQueryHandleAllocator.release(query); + if (queryObject) + { + queryObject->release(this); + } + } + } +} + +GLboolean Context::isQuery(GLuint id) +{ + return (getQuery(id, false, GL_NONE) != nullptr) ? GL_TRUE : GL_FALSE; +} + +void Context::uniformMatrix2x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *program = mGLState.getProgram(); + program->setUniformMatrix2x3fv(location, count, transpose, value); +} + +void Context::uniformMatrix3x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *program = mGLState.getProgram(); + program->setUniformMatrix3x2fv(location, count, transpose, value); +} + +void Context::uniformMatrix2x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *program = mGLState.getProgram(); + program->setUniformMatrix2x4fv(location, count, transpose, value); +} + +void Context::uniformMatrix4x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *program = mGLState.getProgram(); + program->setUniformMatrix4x2fv(location, count, transpose, value); +} + +void Context::uniformMatrix3x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *program = mGLState.getProgram(); + program->setUniformMatrix3x4fv(location, count, transpose, value); +} + +void Context::uniformMatrix4x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *program = mGLState.getProgram(); + program->setUniformMatrix4x3fv(location, count, transpose, value); +} + +void Context::deleteVertexArrays(GLsizei n, const GLuint *arrays) +{ + for (int arrayIndex = 0; arrayIndex < n; arrayIndex++) + { + GLuint vertexArray = arrays[arrayIndex]; + + if (arrays[arrayIndex] != 0) + { + VertexArray *vertexArrayObject = nullptr; + if (mVertexArrayMap.erase(vertexArray, &vertexArrayObject)) + { + if (vertexArrayObject != nullptr) + { + detachVertexArray(vertexArray); + vertexArrayObject->onDestroy(this); + } + + mVertexArrayHandleAllocator.release(vertexArray); + } + } + } +} + +void Context::genVertexArrays(GLsizei n, GLuint *arrays) +{ + for (int arrayIndex = 0; arrayIndex < n; arrayIndex++) + { + GLuint vertexArray = mVertexArrayHandleAllocator.allocate(); + mVertexArrayMap.assign(vertexArray, nullptr); + arrays[arrayIndex] = vertexArray; + } +} + +bool Context::isVertexArray(GLuint array) +{ + if (array == 0) + { + return GL_FALSE; + } + + VertexArray *vao = getVertexArray(array); + return (vao != nullptr ? GL_TRUE : GL_FALSE); +} + +void Context::endTransformFeedback() +{ + TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback(); + transformFeedback->end(this); +} + +void Context::transformFeedbackVaryings(GLuint program, + GLsizei count, + const GLchar *const *varyings, + GLenum bufferMode) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->setTransformFeedbackVaryings(count, varyings, bufferMode); +} + +void Context::getTransformFeedbackVarying(GLuint program, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLsizei *size, + GLenum *type, + GLchar *name) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name); +} + +void Context::deleteTransformFeedbacks(GLsizei n, const GLuint *ids) +{ + for (int i = 0; i < n; i++) + { + GLuint transformFeedback = ids[i]; + if (transformFeedback == 0) + { + continue; + } + + TransformFeedback *transformFeedbackObject = nullptr; + if (mTransformFeedbackMap.erase(transformFeedback, &transformFeedbackObject)) + { + if (transformFeedbackObject != nullptr) + { + detachTransformFeedback(transformFeedback); + transformFeedbackObject->release(this); + } + + mTransformFeedbackHandleAllocator.release(transformFeedback); + } + } +} + +void Context::genTransformFeedbacks(GLsizei n, GLuint *ids) +{ + for (int i = 0; i < n; i++) + { + GLuint transformFeedback = mTransformFeedbackHandleAllocator.allocate(); + mTransformFeedbackMap.assign(transformFeedback, nullptr); + ids[i] = transformFeedback; + } +} + +bool Context::isTransformFeedback(GLuint id) +{ + if (id == 0) + { + // The 3.0.4 spec [section 6.1.11] states that if ID is zero, IsTransformFeedback + // returns FALSE + return GL_FALSE; + } + + const TransformFeedback *transformFeedback = getTransformFeedback(id); + return ((transformFeedback != nullptr) ? GL_TRUE : GL_FALSE); +} + +void Context::pauseTransformFeedback() +{ + TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback(); + transformFeedback->pause(); +} + +void Context::resumeTransformFeedback() +{ + TransformFeedback *transformFeedback = mGLState.getCurrentTransformFeedback(); + transformFeedback->resume(); +} + +void Context::getUniformuiv(GLuint program, GLint location, GLuint *params) +{ + const Program *programObject = getProgram(program); + programObject->getUniformuiv(this, location, params); +} + +GLint Context::getFragDataLocation(GLuint program, const GLchar *name) +{ + const Program *programObject = getProgram(program); + return programObject->getFragDataLocation(name); +} + +void Context::getUniformIndices(GLuint program, + GLsizei uniformCount, + const GLchar *const *uniformNames, + GLuint *uniformIndices) +{ + const Program *programObject = getProgram(program); + if (!programObject->isLinked()) + { + for (int uniformId = 0; uniformId < uniformCount; uniformId++) + { + uniformIndices[uniformId] = GL_INVALID_INDEX; + } + } + else + { + for (int uniformId = 0; uniformId < uniformCount; uniformId++) + { + uniformIndices[uniformId] = programObject->getUniformIndex(uniformNames[uniformId]); + } + } +} + +void Context::getActiveUniformsiv(GLuint program, + GLsizei uniformCount, + const GLuint *uniformIndices, + GLenum pname, + GLint *params) +{ + const Program *programObject = getProgram(program); + for (int uniformId = 0; uniformId < uniformCount; uniformId++) + { + const GLuint index = uniformIndices[uniformId]; + params[uniformId] = GetUniformResourceProperty(programObject, index, pname); + } +} + +GLuint Context::getUniformBlockIndex(GLuint program, const GLchar *uniformBlockName) +{ + const Program *programObject = getProgram(program); + return programObject->getUniformBlockIndex(uniformBlockName); +} + +void Context::getActiveUniformBlockiv(GLuint program, + GLuint uniformBlockIndex, + GLenum pname, + GLint *params) +{ + const Program *programObject = getProgram(program); + QueryActiveUniformBlockiv(programObject, uniformBlockIndex, pname, params); +} + +void Context::getActiveUniformBlockName(GLuint program, + GLuint uniformBlockIndex, + GLsizei bufSize, + GLsizei *length, + GLchar *uniformBlockName) +{ + const Program *programObject = getProgram(program); + programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName); +} + +void Context::uniformBlockBinding(GLuint program, + GLuint uniformBlockIndex, + GLuint uniformBlockBinding) +{ + Program *programObject = getProgram(program); + programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding); +} + +GLsync Context::fenceSync(GLenum condition, GLbitfield flags) +{ + GLuint handle = mState.mSyncs->createSync(mImplementation.get()); + GLsync syncHandle = reinterpret_cast(static_cast(handle)); + + Sync *syncObject = getSync(syncHandle); + Error error = syncObject->set(condition, flags); + if (error.isError()) + { + deleteSync(syncHandle); + handleError(error); + return nullptr; + } + + return syncHandle; +} + +GLboolean Context::isSync(GLsync sync) +{ + return (getSync(sync) != nullptr); +} + +GLenum Context::clientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) +{ + Sync *syncObject = getSync(sync); + + GLenum result = GL_WAIT_FAILED; + handleError(syncObject->clientWait(flags, timeout, &result)); + return result; +} + +void Context::waitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) +{ + Sync *syncObject = getSync(sync); + handleError(syncObject->serverWait(flags, timeout)); +} + +void Context::getInteger64v(GLenum pname, GLint64 *params) +{ + GLenum nativeType = GL_NONE; + unsigned int numParams = 0; + getQueryParameterInfo(pname, &nativeType, &numParams); + + if (nativeType == GL_INT_64_ANGLEX) + { + getInteger64vImpl(pname, params); + } + else + { + CastStateValues(this, nativeType, pname, numParams, params); + } +} + +void Context::getBufferParameteri64v(BufferBinding target, GLenum pname, GLint64 *params) +{ + Buffer *buffer = mGLState.getTargetBuffer(target); + QueryBufferParameteri64v(buffer, pname, params); +} + +void Context::genSamplers(GLsizei count, GLuint *samplers) +{ + for (int i = 0; i < count; i++) + { + samplers[i] = mState.mSamplers->createSampler(); + } +} + +void Context::deleteSamplers(GLsizei count, const GLuint *samplers) +{ + for (int i = 0; i < count; i++) + { + GLuint sampler = samplers[i]; + + if (mState.mSamplers->getSampler(sampler)) + { + detachSampler(sampler); + } + + mState.mSamplers->deleteObject(this, sampler); + } +} + +void Context::getInternalformativ(GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei bufSize, + GLint *params) +{ + const TextureCaps &formatCaps = mTextureCaps.get(internalformat); + QueryInternalFormativ(formatCaps, pname, bufSize, params); +} + +void Context::programUniform1i(GLuint program, GLint location, GLint v0) +{ + programUniform1iv(program, location, 1, &v0); +} + +void Context::programUniform2i(GLuint program, GLint location, GLint v0, GLint v1) +{ + GLint xy[2] = {v0, v1}; + programUniform2iv(program, location, 1, xy); +} + +void Context::programUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2) +{ + GLint xyz[3] = {v0, v1, v2}; + programUniform3iv(program, location, 1, xyz); +} + +void Context::programUniform4i(GLuint program, + GLint location, + GLint v0, + GLint v1, + GLint v2, + GLint v3) +{ + GLint xyzw[4] = {v0, v1, v2, v3}; + programUniform4iv(program, location, 1, xyzw); +} + +void Context::programUniform1ui(GLuint program, GLint location, GLuint v0) +{ + programUniform1uiv(program, location, 1, &v0); +} + +void Context::programUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1) +{ + GLuint xy[2] = {v0, v1}; + programUniform2uiv(program, location, 1, xy); +} + +void Context::programUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2) +{ + GLuint xyz[3] = {v0, v1, v2}; + programUniform3uiv(program, location, 1, xyz); +} + +void Context::programUniform4ui(GLuint program, + GLint location, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3) +{ + GLuint xyzw[4] = {v0, v1, v2, v3}; + programUniform4uiv(program, location, 1, xyzw); +} + +void Context::programUniform1f(GLuint program, GLint location, GLfloat v0) +{ + programUniform1fv(program, location, 1, &v0); +} + +void Context::programUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1) +{ + GLfloat xy[2] = {v0, v1}; + programUniform2fv(program, location, 1, xy); +} + +void Context::programUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) +{ + GLfloat xyz[3] = {v0, v1, v2}; + programUniform3fv(program, location, 1, xyz); +} + +void Context::programUniform4f(GLuint program, + GLint location, + GLfloat v0, + GLfloat v1, + GLfloat v2, + GLfloat v3) +{ + GLfloat xyzw[4] = {v0, v1, v2, v3}; + programUniform4fv(program, location, 1, xyzw); +} + +void Context::programUniform1iv(GLuint program, GLint location, GLsizei count, const GLint *value) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + if (programObject->setUniform1iv(location, count, value) == + Program::SetUniformResult::SamplerChanged) + { + mGLState.setObjectDirty(GL_PROGRAM); + } +} + +void Context::programUniform2iv(GLuint program, GLint location, GLsizei count, const GLint *value) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->setUniform2iv(location, count, value); +} + +void Context::programUniform3iv(GLuint program, GLint location, GLsizei count, const GLint *value) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->setUniform3iv(location, count, value); +} + +void Context::programUniform4iv(GLuint program, GLint location, GLsizei count, const GLint *value) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->setUniform4iv(location, count, value); +} + +void Context::programUniform1uiv(GLuint program, GLint location, GLsizei count, const GLuint *value) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->setUniform1uiv(location, count, value); +} + +void Context::programUniform2uiv(GLuint program, GLint location, GLsizei count, const GLuint *value) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->setUniform2uiv(location, count, value); +} + +void Context::programUniform3uiv(GLuint program, GLint location, GLsizei count, const GLuint *value) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->setUniform3uiv(location, count, value); +} + +void Context::programUniform4uiv(GLuint program, GLint location, GLsizei count, const GLuint *value) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->setUniform4uiv(location, count, value); +} + +void Context::programUniform1fv(GLuint program, GLint location, GLsizei count, const GLfloat *value) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->setUniform1fv(location, count, value); +} + +void Context::programUniform2fv(GLuint program, GLint location, GLsizei count, const GLfloat *value) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->setUniform2fv(location, count, value); +} + +void Context::programUniform3fv(GLuint program, GLint location, GLsizei count, const GLfloat *value) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->setUniform3fv(location, count, value); +} + +void Context::programUniform4fv(GLuint program, GLint location, GLsizei count, const GLfloat *value) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->setUniform4fv(location, count, value); +} + +void Context::programUniformMatrix2fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->setUniformMatrix2fv(location, count, transpose, value); +} + +void Context::programUniformMatrix3fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->setUniformMatrix3fv(location, count, transpose, value); +} + +void Context::programUniformMatrix4fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->setUniformMatrix4fv(location, count, transpose, value); +} + +void Context::programUniformMatrix2x3fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->setUniformMatrix2x3fv(location, count, transpose, value); +} + +void Context::programUniformMatrix3x2fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->setUniformMatrix3x2fv(location, count, transpose, value); +} + +void Context::programUniformMatrix2x4fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->setUniformMatrix2x4fv(location, count, transpose, value); +} + +void Context::programUniformMatrix4x2fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->setUniformMatrix4x2fv(location, count, transpose, value); +} + +void Context::programUniformMatrix3x4fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->setUniformMatrix3x4fv(location, count, transpose, value); +} + +void Context::programUniformMatrix4x3fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + Program *programObject = getProgram(program); + ASSERT(programObject); + programObject->setUniformMatrix4x3fv(location, count, transpose, value); +} + +void Context::onTextureChange(const Texture *texture) +{ + // Conservatively assume all textures are dirty. + // TODO(jmadill): More fine-grained update. + mGLState.setObjectDirty(GL_TEXTURE); +} + +void Context::genProgramPipelines(GLsizei count, GLuint *pipelines) +{ + for (int i = 0; i < count; i++) + { + pipelines[i] = createProgramPipeline(); + } +} + +void Context::deleteProgramPipelines(GLsizei count, const GLuint *pipelines) +{ + for (int i = 0; i < count; i++) + { + if (pipelines[i] != 0) + { + deleteProgramPipeline(pipelines[i]); + } + } +} + +GLboolean Context::isProgramPipeline(GLuint pipeline) +{ + if (pipeline == 0) + { + return GL_FALSE; + } + + return (getProgramPipeline(pipeline) ? GL_TRUE : GL_FALSE); +} + } // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/Context.h b/src/3rdparty/angle/src/libANGLE/Context.h index 6b82eb7cb9..38c4e7b4d1 100644 --- a/src/3rdparty/angle/src/libANGLE/Context.h +++ b/src/3rdparty/angle/src/libANGLE/Context.h @@ -10,25 +10,28 @@ #ifndef LIBANGLE_CONTEXT_H_ #define LIBANGLE_CONTEXT_H_ -#include "common/angleutils.h" -#include "libANGLE/RefCountObject.h" -#include "libANGLE/Caps.h" -#include "libANGLE/Constants.h" -#include "libANGLE/Data.h" -#include "libANGLE/Error.h" -#include "libANGLE/HandleAllocator.h" -#include "libANGLE/VertexAttribute.h" -#include "libANGLE/angletypes.h" +#include +#include #include "angle_gl.h" - -#include -#include -#include +#include "common/MemoryBuffer.h" +#include "common/angleutils.h" +#include "libANGLE/Caps.h" +#include "libANGLE/Constants.h" +#include "libANGLE/ContextState.h" +#include "libANGLE/Error.h" +#include "libANGLE/HandleAllocator.h" +#include "libANGLE/PackedGLEnums.h" +#include "libANGLE/RefCountObject.h" +#include "libANGLE/ResourceMap.h" +#include "libANGLE/VertexAttribute.h" +#include "libANGLE/Workarounds.h" +#include "libANGLE/angletypes.h" namespace rx { -class Renderer; +class ContextImpl; +class EGLImplFactory; } namespace egl @@ -36,41 +39,44 @@ namespace egl class AttributeMap; class Surface; struct Config; +class Thread; } namespace gl { -class Compiler; -class Shader; -class Program; -class Texture; -class Framebuffer; -class Renderbuffer; -class FenceNV; -class FenceSync; -class Query; -class ResourceManager; class Buffer; -struct VertexAttribute; -class VertexArray; +class Compiler; +class FenceNV; +class Sync; +class Framebuffer; +class MemoryProgramCache; +class Program; +class Query; +class Renderbuffer; class Sampler; +class Shader; +class Texture; class TransformFeedback; +class VertexArray; +struct VertexAttribute; +class ProgramPipeline; class Context final : public ValidationContext { public: - Context(const egl::Config *config, + Context(rx::EGLImplFactory *implFactory, + const egl::Config *config, const Context *shareContext, - rx::Renderer *renderer, - const egl::AttributeMap &attribs); + TextureManager *shareTextures, + MemoryProgramCache *memoryProgramCache, + const egl::AttributeMap &attribs, + const egl::DisplayExtensions &displayExtensions); - virtual ~Context(); + egl::Error onDestroy(const egl::Display *display); + ~Context() override; - void makeCurrent(egl::Surface *surface); - void releaseSurface(); - - virtual void markContextLost(); - bool isContextLost(); + egl::Error makeCurrent(egl::Display *display, egl::Surface *surface); + egl::Error releaseSurface(const egl::Display *display); // These create and destroy methods are merely pass-throughs to // ResourceManager, which owns these object types @@ -79,18 +85,30 @@ class Context final : public ValidationContext GLuint createProgram(); GLuint createTexture(); GLuint createRenderbuffer(); - GLuint createSampler(); - GLuint createTransformFeedback(); - GLsync createFenceSync(); + GLuint createPaths(GLsizei range); + GLuint createProgramPipeline(); + GLuint createShaderProgramv(GLenum type, GLsizei count, const GLchar *const *strings); void deleteBuffer(GLuint buffer); void deleteShader(GLuint shader); void deleteProgram(GLuint program); void deleteTexture(GLuint texture); void deleteRenderbuffer(GLuint renderbuffer); - void deleteSampler(GLuint sampler); - void deleteTransformFeedback(GLuint transformFeedback); - void deleteFenceSync(GLsync fenceSync); + void deletePaths(GLuint first, GLsizei range); + void deleteProgramPipeline(GLuint pipeline); + + // CHROMIUM_path_rendering + bool hasPathData(GLuint path) const; + bool hasPath(GLuint path) const; + void setPathCommands(GLuint path, + GLsizei numCommands, + const GLubyte *commands, + GLsizei numCoords, + GLenum coordType, + const void *coords); + void setPathParameterf(GLuint path, GLenum pname, GLfloat value); + void getPathParameterfv(GLuint path, GLenum pname, GLfloat *value) const; + void setPathStencilFunc(GLenum func, GLint ref, GLuint mask); // Framebuffers are owned by the Context, so these methods do not pass through GLuint createFramebuffer(); @@ -100,54 +118,90 @@ class Context final : public ValidationContext GLuint createFenceNV(); void deleteFenceNV(GLuint fence); - // Queries are owned by the Context; - GLuint createQuery(); - void deleteQuery(GLuint query); - - // Vertex arrays are owned by the Context - GLuint createVertexArray(); - void deleteVertexArray(GLuint vertexArray); - - void bindArrayBuffer(GLuint buffer); - void bindElementArrayBuffer(GLuint buffer); void bindTexture(GLenum target, GLuint handle); void bindReadFramebuffer(GLuint framebufferHandle); void bindDrawFramebuffer(GLuint framebufferHandle); - void bindRenderbuffer(GLuint renderbuffer); - void bindVertexArray(GLuint vertexArray); - void bindSampler(GLuint textureUnit, GLuint sampler); - void bindGenericUniformBuffer(GLuint buffer); - void bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size); - void bindGenericTransformFeedbackBuffer(GLuint buffer); - void bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size); - void bindCopyReadBuffer(GLuint buffer); - void bindCopyWriteBuffer(GLuint buffer); - void bindPixelPackBuffer(GLuint buffer); - void bindPixelUnpackBuffer(GLuint buffer); + void bindVertexArray(GLuint vertexArrayHandle); + void bindVertexBuffer(GLuint bindingIndex, + GLuint bufferHandle, + GLintptr offset, + GLsizei stride); + void bindSampler(GLuint textureUnit, GLuint samplerHandle); + void bindImageTexture(GLuint unit, + GLuint texture, + GLint level, + GLboolean layered, + GLint layer, + GLenum access, + GLenum format); void useProgram(GLuint program); - void bindTransformFeedback(GLuint transformFeedback); + void useProgramStages(GLuint pipeline, GLbitfield stages, GLuint program); + void bindTransformFeedback(GLenum target, GLuint transformFeedbackHandle); + void bindProgramPipeline(GLuint pipelineHandle); - Error beginQuery(GLenum target, GLuint query); - Error endQuery(GLenum target); - Error queryCounter(GLuint id, GLenum target); + void beginQuery(GLenum target, GLuint query); + void endQuery(GLenum target); + void queryCounter(GLuint id, GLenum target); void getQueryiv(GLenum target, GLenum pname, GLint *params); - Error getQueryObjectiv(GLuint id, GLenum pname, GLint *params); - Error getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params); - Error getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params); - Error getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params); + void getQueryObjectiv(GLuint id, GLenum pname, GLint *params); + void getQueryObjectuiv(GLuint id, GLenum pname, GLuint *params); + void getQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params); + void getQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params); - void setVertexAttribDivisor(GLuint index, GLuint divisor); + void vertexAttribDivisor(GLuint index, GLuint divisor); + void vertexBindingDivisor(GLuint bindingIndex, GLuint divisor); + + void getBufferParameteriv(BufferBinding target, GLenum pname, GLint *params); + void getFramebufferAttachmentParameteriv(GLenum target, + GLenum attachment, + GLenum pname, + GLint *params); + void getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params); + + void getTexParameterfv(GLenum target, GLenum pname, GLfloat *params); + void getTexParameteriv(GLenum target, GLenum pname, GLint *params); + void getTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params); + void getTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params); + void texParameterf(GLenum target, GLenum pname, GLfloat param); + void texParameterfv(GLenum target, GLenum pname, const GLfloat *params); + void texParameteri(GLenum target, GLenum pname, GLint param); + void texParameteriv(GLenum target, GLenum pname, const GLint *params); void samplerParameteri(GLuint sampler, GLenum pname, GLint param); + void samplerParameteriv(GLuint sampler, GLenum pname, const GLint *param); void samplerParameterf(GLuint sampler, GLenum pname, GLfloat param); - GLint getSamplerParameteri(GLuint sampler, GLenum pname); - GLfloat getSamplerParameterf(GLuint sampler, GLenum pname); + void samplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param); + + void getSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params); + void getSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params); + + void programParameteri(GLuint program, GLenum pname, GLint value); + + GLuint getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name); + void getProgramResourceName(GLuint program, + GLenum programInterface, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name); + GLint getProgramResourceLocation(GLuint program, GLenum programInterface, const GLchar *name); + void getProgramResourceiv(GLuint program, + GLenum programInterface, + GLuint index, + GLsizei propCount, + const GLenum *props, + GLsizei bufSize, + GLsizei *length, + GLint *params); + + void getProgramInterfaceiv(GLuint program, + GLenum programInterface, + GLenum pname, + GLint *params); Buffer *getBuffer(GLuint handle) const; FenceNV *getFenceNV(GLuint handle); - FenceSync *getFenceSync(GLsync handle) const; - Shader *getShader(GLuint handle) const; - Program *getProgram(GLuint handle) const; + Sync *getSync(GLsync handle) const; Texture *getTexture(GLuint handle) const; Framebuffer *getFramebuffer(GLuint handle) const; Renderbuffer *getRenderbuffer(GLuint handle) const; @@ -156,8 +210,16 @@ class Context final : public ValidationContext Query *getQuery(GLuint handle, bool create, GLenum type); Query *getQuery(GLuint handle) const; TransformFeedback *getTransformFeedback(GLuint handle) const; - LabeledObject *getLabeledObject(GLenum identifier, GLuint name) const; - LabeledObject *getLabeledObjectFromPtr(const void *ptr) const; + ProgramPipeline *getProgramPipeline(GLuint handle) const; + + void objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label); + void objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label); + void getObjectLabel(GLenum identifier, + GLuint name, + GLsizei bufSize, + GLsizei *length, + GLchar *label) const; + void getObjectPtrLabel(const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label) const; Texture *getTargetTexture(GLenum target) const; Texture *getSamplerTexture(unsigned int sampler, GLenum type) const; @@ -170,16 +232,108 @@ class Context final : public ValidationContext bool isTransformFeedbackGenerated(GLuint vertexArray); void getBooleanv(GLenum pname, GLboolean *params); + void getBooleanvImpl(GLenum pname, GLboolean *params); void getFloatv(GLenum pname, GLfloat *params); + void getFloatvImpl(GLenum pname, GLfloat *params); void getIntegerv(GLenum pname, GLint *params); - void getInteger64v(GLenum pname, GLint64 *params); + void getIntegervImpl(GLenum pname, GLint *params); + void getInteger64vImpl(GLenum pname, GLint64 *params); void getPointerv(GLenum pname, void **params) const; + void getBooleani_v(GLenum target, GLuint index, GLboolean *data); + void getIntegeri_v(GLenum target, GLuint index, GLint *data); + void getInteger64i_v(GLenum target, GLuint index, GLint64 *data); - bool getIndexedIntegerv(GLenum target, GLuint index, GLint *data); - bool getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data); + void activeShaderProgram(GLuint pipeline, GLuint program); + void activeTexture(GLenum texture); + void blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); + void blendEquation(GLenum mode); + void blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha); + void blendFunc(GLenum sfactor, GLenum dfactor); + void blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); + void clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); + void clearDepthf(GLfloat depth); + void clearStencil(GLint s); + void colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); + void cullFace(CullFaceMode mode); + void depthFunc(GLenum func); + void depthMask(GLboolean flag); + void depthRangef(GLfloat zNear, GLfloat zFar); + void disable(GLenum cap); + void disableVertexAttribArray(GLuint index); + void enable(GLenum cap); + void enableVertexAttribArray(GLuint index); + void frontFace(GLenum mode); + void hint(GLenum target, GLenum mode); + void lineWidth(GLfloat width); + void pixelStorei(GLenum pname, GLint param); + void polygonOffset(GLfloat factor, GLfloat units); + void sampleCoverage(GLfloat value, GLboolean invert); + void sampleMaski(GLuint maskNumber, GLbitfield mask); + void scissor(GLint x, GLint y, GLsizei width, GLsizei height); + void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask); + void stencilMaskSeparate(GLenum face, GLuint mask); + void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass); + void vertexAttrib1f(GLuint index, GLfloat x); + void vertexAttrib1fv(GLuint index, const GLfloat *values); + void vertexAttrib2f(GLuint index, GLfloat x, GLfloat y); + void vertexAttrib2fv(GLuint index, const GLfloat *values); + void vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z); + void vertexAttrib3fv(GLuint index, const GLfloat *values); + void vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + void vertexAttrib4fv(GLuint index, const GLfloat *values); + void vertexAttribFormat(GLuint attribIndex, + GLint size, + GLenum type, + GLboolean normalized, + GLuint relativeOffset); + void vertexAttribIFormat(GLuint attribIndex, GLint size, GLenum type, GLuint relativeOffset); + void vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex); + void vertexAttribPointer(GLuint index, + GLint size, + GLenum type, + GLboolean normalized, + GLsizei stride, + const void *ptr); + void vertexAttribIPointer(GLuint index, + GLint size, + GLenum type, + GLsizei stride, + const void *pointer); + void viewport(GLint x, GLint y, GLsizei width, GLsizei height); - bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams); - bool getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams); + void vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w); + void vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); + void vertexAttribI4iv(GLuint index, const GLint *v); + void vertexAttribI4uiv(GLuint index, const GLuint *v); + void getVertexAttribiv(GLuint index, GLenum pname, GLint *params); + void getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params); + void getVertexAttribIiv(GLuint index, GLenum pname, GLint *params); + void getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params); + void getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer); + + void debugMessageControl(GLenum source, + GLenum type, + GLenum severity, + GLsizei count, + const GLuint *ids, + GLboolean enabled); + void debugMessageInsert(GLenum source, + GLenum type, + GLuint id, + GLenum severity, + GLsizei length, + const GLchar *buf); + void debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam); + GLuint getDebugMessageLog(GLuint count, + GLsizei bufSize, + GLenum *sources, + GLenum *types, + GLuint *ids, + GLenum *severities, + GLsizei *lengths, + GLchar *messageLog); + void pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message); + void popDebugGroup(); void clear(GLbitfield mask); void clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values); @@ -187,27 +341,23 @@ class Context final : public ValidationContext void clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values); void clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); - Error drawArrays(GLenum mode, GLint first, GLsizei count); - Error drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount); + void drawArrays(GLenum mode, GLint first, GLsizei count); + void drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount); - Error drawElements(GLenum mode, - GLsizei count, - GLenum type, - const GLvoid *indices, - const IndexRange &indexRange); - Error drawElementsInstanced(GLenum mode, - GLsizei count, - GLenum type, - const GLvoid *indices, - GLsizei instances, - const IndexRange &indexRange); - Error drawRangeElements(GLenum mode, - GLuint start, - GLuint end, - GLsizei count, - GLenum type, - const GLvoid *indices, - const IndexRange &indexRange); + void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices); + void drawElementsInstanced(GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei instances); + void drawRangeElements(GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const void *indices); + void drawArraysIndirect(GLenum mode, const void *indirect); + void drawElementsIndirect(GLenum mode, GLenum type, const void *indirect); void blitFramebuffer(GLint srcX0, GLint srcY0, @@ -226,7 +376,7 @@ class Context final : public ValidationContext GLsizei height, GLenum format, GLenum type, - GLvoid *pixels); + void *pixels); void copyTexImage2D(GLenum target, GLint level, @@ -272,6 +422,18 @@ class Context final : public ValidationContext GLuint texture, GLint level, GLint layer); + void framebufferTextureMultiviewLayeredANGLE(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint baseViewIndex, + GLsizei numViews); + void framebufferTextureMultiviewSideBySideANGLE(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLsizei numViews, + const GLint *viewportOffsets); void drawBuffers(GLsizei n, const GLenum *bufs); void readBuffer(GLenum mode); @@ -286,40 +448,596 @@ class Context final : public ValidationContext GLsizei width, GLsizei height); - Error flush(); - Error finish(); + void texImage2D(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + const void *pixels); + void texImage3D(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const void *pixels); + void texSubImage2D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void *pixels); + void texSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *pixels); + void compressedTexImage2D(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + const void *data); + void compressedTexImage3D(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const void *data); + void compressedTexSubImage2D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const void *data); + void compressedTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void *data); + void copyTextureCHROMIUM(GLuint sourceId, + GLint sourceLevel, + GLenum destTarget, + GLuint destId, + GLint destLevel, + GLint internalFormat, + GLenum destType, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha); + void copySubTextureCHROMIUM(GLuint sourceId, + GLint sourceLevel, + GLenum destTarget, + GLuint destId, + GLint destLevel, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha); + void compressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId); + + void generateMipmap(GLenum target); + + void flush(); + void finish(); + + void getBufferPointerv(BufferBinding target, GLenum pname, void **params); + void *mapBuffer(BufferBinding target, GLenum access); + GLboolean unmapBuffer(BufferBinding target); + void *mapBufferRange(BufferBinding target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access); + void flushMappedBufferRange(BufferBinding target, GLintptr offset, GLsizeiptr length); + + void beginTransformFeedback(GLenum primitiveMode); + + bool hasActiveTransformFeedback(GLuint program) const; void insertEventMarker(GLsizei length, const char *marker); void pushGroupMarker(GLsizei length, const char *marker); void popGroupMarker(); - void recordError(const Error &error) override; + void bindUniformLocation(GLuint program, GLint location, const GLchar *name); + void renderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); + void renderbufferStorageMultisample(GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height); + + void getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); + + // CHROMIUM_framebuffer_mixed_samples + void setCoverageModulation(GLenum components); + + // CHROMIUM_path_rendering + void loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix); + void loadPathRenderingIdentityMatrix(GLenum matrixMode); + void stencilFillPath(GLuint path, GLenum fillMode, GLuint mask); + void stencilStrokePath(GLuint path, GLint reference, GLuint mask); + void coverFillPath(GLuint path, GLenum coverMode); + void coverStrokePath(GLuint path, GLenum coverMode); + void stencilThenCoverFillPath(GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode); + void stencilThenCoverStrokePath(GLuint path, GLint reference, GLuint mask, GLenum coverMode); + void coverFillPathInstanced(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); + void coverStrokePathInstanced(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); + void stencilFillPathInstanced(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBAse, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); + void stencilStrokePathInstanced(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); + void stencilThenCoverFillPathInstanced(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); + void stencilThenCoverStrokePathInstanced(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); + void bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name); + void programPathFragmentInputGen(GLuint program, + GLint location, + GLenum genMode, + GLint components, + const GLfloat *coeffs); + + void bufferData(BufferBinding target, GLsizeiptr size, const void *data, BufferUsage usage); + void bufferSubData(BufferBinding target, GLintptr offset, GLsizeiptr size, const void *data); + void attachShader(GLuint program, GLuint shader); + void bindAttribLocation(GLuint program, GLuint index, const GLchar *name); + void bindBuffer(BufferBinding target, GLuint buffer); + void bindBufferBase(BufferBinding target, GLuint index, GLuint buffer); + void bindBufferRange(BufferBinding target, + GLuint index, + GLuint buffer, + GLintptr offset, + GLsizeiptr size); + void bindFramebuffer(GLenum target, GLuint framebuffer); + void bindRenderbuffer(GLenum target, GLuint renderbuffer); + + void texStorage2DMultisample(GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations); + + void getMultisamplefv(GLenum pname, GLuint index, GLfloat *val); + + void copyBufferSubData(BufferBinding readTarget, + BufferBinding writeTarget, + GLintptr readOffset, + GLintptr writeOffset, + GLsizeiptr size); + + GLenum checkFramebufferStatus(GLenum target); + void compileShader(GLuint shader); + void deleteBuffers(GLsizei n, const GLuint *buffers); + void deleteFramebuffers(GLsizei n, const GLuint *framebuffers); + void deleteRenderbuffers(GLsizei n, const GLuint *renderbuffers); + void deleteTextures(GLsizei n, const GLuint *textures); + void detachShader(GLuint program, GLuint shader); + void genBuffers(GLsizei n, GLuint *buffers); + void genFramebuffers(GLsizei n, GLuint *framebuffers); + void genRenderbuffers(GLsizei n, GLuint *renderbuffers); + void genTextures(GLsizei n, GLuint *textures); + void getActiveAttrib(GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name); + void getActiveUniform(GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name); + void getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders); + GLint getAttribLocation(GLuint program, const GLchar *name); + void getProgramiv(GLuint program, GLenum pname, GLint *params); + void getProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params); + void getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog); + void getProgramPipelineInfoLog(GLuint pipeline, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog); + void getShaderiv(GLuint shader, GLenum pname, GLint *params); + void getShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog); + void getShaderPrecisionFormat(GLenum shadertype, + GLenum precisiontype, + GLint *range, + GLint *precision); + void getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source); + void getUniformfv(GLuint program, GLint location, GLfloat *params); + void getUniformiv(GLuint program, GLint location, GLint *params); + GLint getUniformLocation(GLuint program, const GLchar *name); + GLboolean isBuffer(GLuint buffer); + GLboolean isEnabled(GLenum cap); + GLboolean isFramebuffer(GLuint framebuffer); + GLboolean isProgram(GLuint program); + GLboolean isRenderbuffer(GLuint renderbuffer); + GLboolean isShader(GLuint shader); + GLboolean isTexture(GLuint texture); + void linkProgram(GLuint program); + void releaseShaderCompiler(); + void shaderBinary(GLsizei n, + const GLuint *shaders, + GLenum binaryformat, + const void *binary, + GLsizei length); + void shaderSource(GLuint shader, + GLsizei count, + const GLchar *const *string, + const GLint *length); + void stencilFunc(GLenum func, GLint ref, GLuint mask); + void stencilMask(GLuint mask); + void stencilOp(GLenum fail, GLenum zfail, GLenum zpass); + void uniform1f(GLint location, GLfloat x); + void uniform1fv(GLint location, GLsizei count, const GLfloat *v); + void uniform1i(GLint location, GLint x); + void uniform1iv(GLint location, GLsizei count, const GLint *v); + void uniform2f(GLint location, GLfloat x, GLfloat y); + void uniform2fv(GLint location, GLsizei count, const GLfloat *v); + void uniform2i(GLint location, GLint x, GLint y); + void uniform2iv(GLint location, GLsizei count, const GLint *v); + void uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z); + void uniform3fv(GLint location, GLsizei count, const GLfloat *v); + void uniform3i(GLint location, GLint x, GLint y, GLint z); + void uniform3iv(GLint location, GLsizei count, const GLint *v); + void uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + void uniform4fv(GLint location, GLsizei count, const GLfloat *v); + void uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w); + void uniform4iv(GLint location, GLsizei count, const GLint *v); + void uniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void uniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void uniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void validateProgram(GLuint program); + void validateProgramPipeline(GLuint pipeline); + + void genQueries(GLsizei n, GLuint *ids); + void deleteQueries(GLsizei n, const GLuint *ids); + GLboolean isQuery(GLuint id); + + void uniform1ui(GLint location, GLuint v0); + void uniform2ui(GLint location, GLuint v0, GLuint v1); + void uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2); + void uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + void uniform1uiv(GLint location, GLsizei count, const GLuint *value); + void uniform2uiv(GLint location, GLsizei count, const GLuint *value); + void uniform3uiv(GLint location, GLsizei count, const GLuint *value); + void uniform4uiv(GLint location, GLsizei count, const GLuint *value); + + void uniformMatrix2x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + void uniformMatrix3x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + void uniformMatrix2x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + void uniformMatrix4x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + void uniformMatrix3x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + void uniformMatrix4x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + + void deleteVertexArrays(GLsizei n, const GLuint *arrays); + void genVertexArrays(GLsizei n, GLuint *arrays); + bool isVertexArray(GLuint array); + + void endTransformFeedback(); + void transformFeedbackVaryings(GLuint program, + GLsizei count, + const GLchar *const *varyings, + GLenum bufferMode); + void getTransformFeedbackVarying(GLuint program, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLsizei *size, + GLenum *type, + GLchar *name); + + void deleteTransformFeedbacks(GLsizei n, const GLuint *ids); + void genTransformFeedbacks(GLsizei n, GLuint *ids); + bool isTransformFeedback(GLuint id); + void pauseTransformFeedback(); + void resumeTransformFeedback(); + + void getProgramBinary(GLuint program, + GLsizei bufSize, + GLsizei *length, + GLenum *binaryFormat, + void *binary); + void programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); + + void getUniformuiv(GLuint program, GLint location, GLuint *params); + GLint getFragDataLocation(GLuint program, const GLchar *name); + void getUniformIndices(GLuint program, + GLsizei uniformCount, + const GLchar *const *uniformNames, + GLuint *uniformIndices); + void getActiveUniformsiv(GLuint program, + GLsizei uniformCount, + const GLuint *uniformIndices, + GLenum pname, + GLint *params); + GLuint getUniformBlockIndex(GLuint program, const GLchar *uniformBlockName); + void getActiveUniformBlockiv(GLuint program, + GLuint uniformBlockIndex, + GLenum pname, + GLint *params); + void getActiveUniformBlockName(GLuint program, + GLuint uniformBlockIndex, + GLsizei bufSize, + GLsizei *length, + GLchar *uniformBlockName); + void uniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); + + GLsync fenceSync(GLenum condition, GLbitfield flags); + GLboolean isSync(GLsync sync); + void deleteSync(GLsync sync); + GLenum clientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout); + void waitSync(GLsync sync, GLbitfield flags, GLuint64 timeout); + void getInteger64v(GLenum pname, GLint64 *params); + + void getBufferParameteri64v(BufferBinding target, GLenum pname, GLint64 *params); + void genSamplers(GLsizei count, GLuint *samplers); + void deleteSamplers(GLsizei count, const GLuint *samplers); + void getInternalformativ(GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei bufSize, + GLint *params); + + void programUniform1i(GLuint program, GLint location, GLint v0); + void programUniform2i(GLuint program, GLint location, GLint v0, GLint v1); + void programUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2); + void programUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); + void programUniform1ui(GLuint program, GLint location, GLuint v0); + void programUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1); + void programUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); + void programUniform4ui(GLuint program, + GLint location, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3); + void programUniform1f(GLuint program, GLint location, GLfloat v0); + void programUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1); + void programUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); + void programUniform4f(GLuint program, + GLint location, + GLfloat v0, + GLfloat v1, + GLfloat v2, + GLfloat v3); + void programUniform1iv(GLuint program, GLint location, GLsizei count, const GLint *value); + void programUniform2iv(GLuint program, GLint location, GLsizei count, const GLint *value); + void programUniform3iv(GLuint program, GLint location, GLsizei count, const GLint *value); + void programUniform4iv(GLuint program, GLint location, GLsizei count, const GLint *value); + void programUniform1uiv(GLuint program, GLint location, GLsizei count, const GLuint *value); + void programUniform2uiv(GLuint program, GLint location, GLsizei count, const GLuint *value); + void programUniform3uiv(GLuint program, GLint location, GLsizei count, const GLuint *value); + void programUniform4uiv(GLuint program, GLint location, GLsizei count, const GLuint *value); + void programUniform1fv(GLuint program, GLint location, GLsizei count, const GLfloat *value); + void programUniform2fv(GLuint program, GLint location, GLsizei count, const GLfloat *value); + void programUniform3fv(GLuint program, GLint location, GLsizei count, const GLfloat *value); + void programUniform4fv(GLuint program, GLint location, GLsizei count, const GLfloat *value); + + void programUniformMatrix2fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + + void programUniformMatrix3fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + + void programUniformMatrix4fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + + void programUniformMatrix2x3fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + + void programUniformMatrix3x2fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + + void programUniformMatrix2x4fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + + void programUniformMatrix4x2fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + + void programUniformMatrix3x4fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + + void programUniformMatrix4x3fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + + void deleteProgramPipelines(GLsizei n, const GLuint *pipelines); + void genProgramPipelines(GLsizei n, GLuint *pipelines); + GLboolean isProgramPipeline(GLuint pipeline); + + // Consumes the error. + void handleError(const Error &error) override; GLenum getError(); + void markContextLost(); + bool isContextLost(); GLenum getResetStatus(); - virtual bool isResetNotificationEnabled(); + bool isResetNotificationEnabled(); const egl::Config *getConfig() const; EGLenum getClientType() const; EGLenum getRenderBuffer() const; - const std::string &getRendererString() const; + const GLubyte *getString(GLenum name) const; + const GLubyte *getStringi(GLenum name, GLuint index) const; - const std::string &getExtensionString() const; - const std::string &getExtensionString(size_t idx) const; size_t getExtensionStringCount() const; - rx::Renderer *getRenderer() { return mRenderer; } + bool isExtensionRequestable(const char *name); + void requestExtension(const char *name); + size_t getRequestableExtensionStringCount() const; - State &getState() { return mState; } + rx::ContextImpl *getImplementation() const { return mImplementation.get(); } + const Workarounds &getWorkarounds() const; - void syncRendererState(); - void syncRendererState(const State::DirtyBits &bitMask); + void getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params); + void framebufferParameteri(GLenum target, GLenum pname, GLint param); + + Error getScratchBuffer(size_t requestedSizeBytes, angle::MemoryBuffer **scratchBufferOut) const; + Error getZeroFilledBuffer(size_t requstedSizeBytes, angle::MemoryBuffer **zeroBufferOut) const; + + void dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ); + void dispatchComputeIndirect(GLintptr indirect); + + MemoryProgramCache *getMemoryProgramCache() const { return mMemoryProgramCache; } + + template + void gatherParams(ParamsT &&... params); + + void texStorage2D(GLenum target, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height); + void texStorage3D(GLenum target, + GLsizei levels, + GLenum internalFormat, + GLsizei width, + GLsizei height, + GLsizei depth); + + void memoryBarrier(GLbitfield barriers); + void memoryBarrierByRegion(GLbitfield barriers); + + // Notification for a state change in a Texture. + void onTextureChange(const Texture *texture); + + egl::Display *getCurrentDisplay() const { return mCurrentDisplay; } + egl::Surface *getCurrentDrawSurface() const { return mCurrentSurface; } + egl::Surface *getCurrentReadSurface() const { return mCurrentSurface; } + + bool isRobustResourceInitEnabled() const { return mGLState.isRobustResourceInitEnabled(); } private: - void checkVertexArrayAllocation(GLuint vertexArray); - void checkTransformFeedbackAllocation(GLuint transformFeedback); - Framebuffer *checkFramebufferAllocation(GLuint framebufferHandle); + Error prepareForDraw(); + void syncRendererState(); + void syncRendererState(const State::DirtyBits &bitMask, const State::DirtyObjects &objectMask); + void syncStateForReadPixels(); + void syncStateForTexImage(); + void syncStateForClear(); + void syncStateForBlit(); + VertexArray *checkVertexArrayAllocation(GLuint vertexArrayHandle); + TransformFeedback *checkTransformFeedbackAllocation(GLuint transformFeedback); void detachBuffer(GLuint buffer); void detachTexture(GLuint texture); @@ -328,11 +1046,20 @@ class Context final : public ValidationContext void detachVertexArray(GLuint vertexArray); void detachTransformFeedback(GLuint transformFeedback); void detachSampler(GLuint sampler); + void detachProgramPipeline(GLuint pipeline); void initRendererString(); + void initVersionStrings(); void initExtensionStrings(); - void initCaps(GLuint clientVersion); + void initCaps(const egl::DisplayExtensions &displayExtensions, bool robustResourceInit); + void updateCaps(); + void initWorkarounds(); + + LabeledObject *getLabeledObject(GLenum identifier, GLuint name) const; + LabeledObject *getLabeledObjectFromPtr(const void *ptr) const; + + std::unique_ptr mImplementation; // Caps to use for validation Caps mCaps; @@ -340,42 +1067,35 @@ class Context final : public ValidationContext Extensions mExtensions; Limitations mLimitations; - // Shader compiler - Compiler *mCompiler; + // Shader compiler. Lazily initialized hence the mutable value. + mutable BindingPointer mCompiler; - rx::Renderer *const mRenderer; - State mState; - - int mClientVersion; + State mGLState; const egl::Config *mConfig; EGLenum mClientType; TextureMap mZeroTextures; - typedef std::map FramebufferMap; - FramebufferMap mFramebufferMap; - HandleAllocator mFramebufferHandleAllocator; - - typedef std::map FenceNVMap; - FenceNVMap mFenceNVMap; + ResourceMap mFenceNVMap; HandleAllocator mFenceNVHandleAllocator; - typedef std::map QueryMap; - QueryMap mQueryMap; + ResourceMap mQueryMap; HandleAllocator mQueryHandleAllocator; - typedef std::map VertexArrayMap; - VertexArrayMap mVertexArrayMap; + ResourceMap mVertexArrayMap; HandleAllocator mVertexArrayHandleAllocator; - typedef std::map TransformFeedbackMap; - TransformFeedbackMap mTransformFeedbackMap; - HandleAllocator mTransformFeedbackAllocator; + ResourceMap mTransformFeedbackMap; + HandleAllocator mTransformFeedbackHandleAllocator; - std::string mRendererString; - std::string mExtensionString; - std::vector mExtensionStrings; + const char *mVersionString; + const char *mShadingLanguageString; + const char *mRendererString; + const char *mExtensionString; + std::vector mExtensionStrings; + const char *mRequestableExtensionString; + std::vector mRequestableExtensionStrings; // Recorded errors typedef std::set ErrorSet; @@ -385,13 +1105,50 @@ class Context final : public ValidationContext bool mHasBeenCurrent; bool mContextLost; GLenum mResetStatus; + bool mContextLostForced; GLenum mResetStrategy; bool mRobustAccess; egl::Surface *mCurrentSurface; + egl::Display *mCurrentDisplay; + Framebuffer *mSurfacelessFramebuffer; + bool mWebGLContext; + MemoryProgramCache *mMemoryProgramCache; - ResourceManager *mResourceManager; + State::DirtyBits mTexImageDirtyBits; + State::DirtyObjects mTexImageDirtyObjects; + State::DirtyBits mReadPixelsDirtyBits; + State::DirtyObjects mReadPixelsDirtyObjects; + State::DirtyBits mClearDirtyBits; + State::DirtyObjects mClearDirtyObjects; + State::DirtyBits mBlitDirtyBits; + State::DirtyObjects mBlitDirtyObjects; + + Workarounds mWorkarounds; + + // Not really a property of context state. The size and contexts change per-api-call. + mutable angle::ScratchBuffer mScratchBuffer; + mutable angle::ScratchBuffer mZeroFilledBuffer; }; +template +ANGLE_INLINE void Context::gatherParams(ArgsT &&... args) +{ + static_assert(sizeof(EntryPointParamType) <= kParamsBufferSize, + "Params struct too large, please increase kParamsBufferSize."); + + mSavedArgsType = &EntryPointParamType::TypeInfo; + + // Skip doing any work for ParamsBase/Invalid type. + if (!EntryPointParamType::TypeInfo.isValid()) + { + return; + } + + EntryPointParamType *objBuffer = + reinterpret_cast *>(mParamsBuffer.data()); + EntryPointParamType::template Factory(objBuffer, this, std::forward(args)...); +} + } // namespace gl -#endif // LIBANGLE_CONTEXT_H_ +#endif // LIBANGLE_CONTEXT_H_ diff --git a/src/3rdparty/angle/src/libANGLE/ContextState.cpp b/src/3rdparty/angle/src/libANGLE/ContextState.cpp new file mode 100644 index 0000000000..d109cca76d --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/ContextState.cpp @@ -0,0 +1,839 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Data.cpp: Container class for all GL relevant state, caps and objects + +#include "libANGLE/ContextState.h" + +#include "libANGLE/Framebuffer.h" +#include "libANGLE/ResourceManager.h" + +namespace gl +{ + +namespace +{ + +template +using ContextStateMember = T *(ContextState::*); + +template +T *AllocateOrGetSharedResourceManager(const ContextState *shareContextState, + ContextStateMember member) +{ + if (shareContextState) + { + T *resourceManager = (*shareContextState).*member; + resourceManager->addRef(); + return resourceManager; + } + else + { + return new T(); + } +} + +TextureManager *AllocateOrGetSharedTextureManager(const ContextState *shareContextState, + TextureManager *shareTextures, + ContextStateMember member) +{ + if (shareContextState) + { + TextureManager *textureManager = (*shareContextState).*member; + ASSERT(shareTextures == nullptr || textureManager == shareTextures); + textureManager->addRef(); + return textureManager; + } + else if (shareTextures) + { + TextureManager *textureManager = shareTextures; + textureManager->addRef(); + return textureManager; + } + else + { + return new TextureManager(); + } +} + +} // anonymous namespace + +ContextState::ContextState(ContextID contextIn, + const ContextState *shareContextState, + TextureManager *shareTextures, + const Version &clientVersion, + State *stateIn, + const Caps &capsIn, + const TextureCapsMap &textureCapsIn, + const Extensions &extensionsIn, + const Limitations &limitationsIn) + : mClientVersion(clientVersion), + mContext(contextIn), + mState(stateIn), + mCaps(capsIn), + mTextureCaps(textureCapsIn), + mExtensions(extensionsIn), + mLimitations(limitationsIn), + mBuffers(AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mBuffers)), + mShaderPrograms( + AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mShaderPrograms)), + mTextures(AllocateOrGetSharedTextureManager(shareContextState, + shareTextures, + &ContextState::mTextures)), + mRenderbuffers( + AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mRenderbuffers)), + mSamplers(AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mSamplers)), + mSyncs(AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mSyncs)), + mPaths(AllocateOrGetSharedResourceManager(shareContextState, &ContextState::mPaths)), + mFramebuffers(new FramebufferManager()), + mPipelines(new ProgramPipelineManager()) +{ +} + +ContextState::~ContextState() +{ + // Handles are released by the Context. +} + +bool ContextState::isWebGL() const +{ + return mExtensions.webglCompatibility; +} + +bool ContextState::isWebGL1() const +{ + return (isWebGL() && mClientVersion.major == 2); +} + +const TextureCaps &ContextState::getTextureCap(GLenum internalFormat) const +{ + return mTextureCaps.get(internalFormat); +} + +ValidationContext::ValidationContext(const ValidationContext *shareContext, + TextureManager *shareTextures, + const Version &clientVersion, + State *state, + const Caps &caps, + const TextureCapsMap &textureCaps, + const Extensions &extensions, + const Limitations &limitations, + bool skipValidation) + : mState(reinterpret_cast(this), + shareContext ? &shareContext->mState : nullptr, + shareTextures, + clientVersion, + state, + caps, + textureCaps, + extensions, + limitations), + mSkipValidation(skipValidation), + mDisplayTextureShareGroup(shareTextures != nullptr) +{ +} + +ValidationContext::~ValidationContext() +{ +} + +bool ValidationContext::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) +{ + // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation + // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due + // to the fact that it is stored internally as a float, and so would require conversion + // if returned from Context::getIntegerv. Since this conversion is already implemented + // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we + // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling + // application. + switch (pname) + { + case GL_COMPRESSED_TEXTURE_FORMATS: + { + *type = GL_INT; + *numParams = static_cast(getCaps().compressedTextureFormats.size()); + return true; + } + case GL_SHADER_BINARY_FORMATS: + { + *type = GL_INT; + *numParams = static_cast(getCaps().shaderBinaryFormats.size()); + return true; + } + + case GL_MAX_VERTEX_ATTRIBS: + case GL_MAX_VERTEX_UNIFORM_VECTORS: + case GL_MAX_VARYING_VECTORS: + case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: + case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: + case GL_MAX_TEXTURE_IMAGE_UNITS: + case GL_MAX_FRAGMENT_UNIFORM_VECTORS: + case GL_MAX_RENDERBUFFER_SIZE: + case GL_NUM_SHADER_BINARY_FORMATS: + case GL_NUM_COMPRESSED_TEXTURE_FORMATS: + case GL_ARRAY_BUFFER_BINDING: + case GL_FRAMEBUFFER_BINDING: + case GL_RENDERBUFFER_BINDING: + case GL_CURRENT_PROGRAM: + case GL_PACK_ALIGNMENT: + case GL_UNPACK_ALIGNMENT: + case GL_GENERATE_MIPMAP_HINT: + case GL_RED_BITS: + case GL_GREEN_BITS: + case GL_BLUE_BITS: + case GL_ALPHA_BITS: + case GL_DEPTH_BITS: + case GL_STENCIL_BITS: + case GL_ELEMENT_ARRAY_BUFFER_BINDING: + case GL_CULL_FACE_MODE: + case GL_FRONT_FACE: + case GL_ACTIVE_TEXTURE: + case GL_STENCIL_FUNC: + case GL_STENCIL_VALUE_MASK: + case GL_STENCIL_REF: + case GL_STENCIL_FAIL: + case GL_STENCIL_PASS_DEPTH_FAIL: + case GL_STENCIL_PASS_DEPTH_PASS: + case GL_STENCIL_BACK_FUNC: + case GL_STENCIL_BACK_VALUE_MASK: + case GL_STENCIL_BACK_REF: + case GL_STENCIL_BACK_FAIL: + case GL_STENCIL_BACK_PASS_DEPTH_FAIL: + case GL_STENCIL_BACK_PASS_DEPTH_PASS: + case GL_DEPTH_FUNC: + case GL_BLEND_SRC_RGB: + case GL_BLEND_SRC_ALPHA: + case GL_BLEND_DST_RGB: + case GL_BLEND_DST_ALPHA: + case GL_BLEND_EQUATION_RGB: + case GL_BLEND_EQUATION_ALPHA: + case GL_STENCIL_WRITEMASK: + case GL_STENCIL_BACK_WRITEMASK: + case GL_STENCIL_CLEAR_VALUE: + case GL_SUBPIXEL_BITS: + case GL_MAX_TEXTURE_SIZE: + case GL_MAX_CUBE_MAP_TEXTURE_SIZE: + case GL_SAMPLE_BUFFERS: + case GL_SAMPLES: + case GL_IMPLEMENTATION_COLOR_READ_TYPE: + case GL_IMPLEMENTATION_COLOR_READ_FORMAT: + case GL_TEXTURE_BINDING_2D: + case GL_TEXTURE_BINDING_CUBE_MAP: + case GL_RESET_NOTIFICATION_STRATEGY_EXT: + { + *type = GL_INT; + *numParams = 1; + return true; + } + case GL_PACK_REVERSE_ROW_ORDER_ANGLE: + { + if (!getExtensions().packReverseRowOrder) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + } + case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE: + case GL_TEXTURE_BINDING_RECTANGLE_ANGLE: + { + if (!getExtensions().textureRectangle) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + } + case GL_MAX_DRAW_BUFFERS_EXT: + case GL_MAX_COLOR_ATTACHMENTS_EXT: + { + if ((getClientMajorVersion() < 3) && !getExtensions().drawBuffers) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + } + case GL_MAX_VIEWPORT_DIMS: + { + *type = GL_INT; + *numParams = 2; + return true; + } + case GL_VIEWPORT: + case GL_SCISSOR_BOX: + { + *type = GL_INT; + *numParams = 4; + return true; + } + case GL_SHADER_COMPILER: + case GL_SAMPLE_COVERAGE_INVERT: + case GL_DEPTH_WRITEMASK: + case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled, + case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries. + case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as + // bool-natural + case GL_SAMPLE_COVERAGE: + case GL_SCISSOR_TEST: + case GL_STENCIL_TEST: + case GL_DEPTH_TEST: + case GL_BLEND: + case GL_DITHER: + case GL_CONTEXT_ROBUST_ACCESS_EXT: + { + *type = GL_BOOL; + *numParams = 1; + return true; + } + case GL_COLOR_WRITEMASK: + { + *type = GL_BOOL; + *numParams = 4; + return true; + } + case GL_POLYGON_OFFSET_FACTOR: + case GL_POLYGON_OFFSET_UNITS: + case GL_SAMPLE_COVERAGE_VALUE: + case GL_DEPTH_CLEAR_VALUE: + case GL_LINE_WIDTH: + { + *type = GL_FLOAT; + *numParams = 1; + return true; + } + case GL_ALIASED_LINE_WIDTH_RANGE: + case GL_ALIASED_POINT_SIZE_RANGE: + case GL_DEPTH_RANGE: + { + *type = GL_FLOAT; + *numParams = 2; + return true; + } + case GL_COLOR_CLEAR_VALUE: + case GL_BLEND_COLOR: + { + *type = GL_FLOAT; + *numParams = 4; + return true; + } + case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: + if (!getExtensions().textureFilterAnisotropic) + { + return false; + } + *type = GL_FLOAT; + *numParams = 1; + return true; + case GL_TIMESTAMP_EXT: + if (!getExtensions().disjointTimerQuery) + { + return false; + } + *type = GL_INT_64_ANGLEX; + *numParams = 1; + return true; + case GL_GPU_DISJOINT_EXT: + if (!getExtensions().disjointTimerQuery) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + case GL_COVERAGE_MODULATION_CHROMIUM: + if (!getExtensions().framebufferMixedSamples) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + case GL_TEXTURE_BINDING_EXTERNAL_OES: + if (!getExtensions().eglStreamConsumerExternal && !getExtensions().eglImageExternal) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + } + + if (getExtensions().debug) + { + switch (pname) + { + case GL_DEBUG_LOGGED_MESSAGES: + case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH: + case GL_DEBUG_GROUP_STACK_DEPTH: + case GL_MAX_DEBUG_MESSAGE_LENGTH: + case GL_MAX_DEBUG_LOGGED_MESSAGES: + case GL_MAX_DEBUG_GROUP_STACK_DEPTH: + case GL_MAX_LABEL_LENGTH: + *type = GL_INT; + *numParams = 1; + return true; + + case GL_DEBUG_OUTPUT_SYNCHRONOUS: + case GL_DEBUG_OUTPUT: + *type = GL_BOOL; + *numParams = 1; + return true; + } + } + + if (getExtensions().multisampleCompatibility) + { + switch (pname) + { + case GL_MULTISAMPLE_EXT: + case GL_SAMPLE_ALPHA_TO_ONE_EXT: + *type = GL_BOOL; + *numParams = 1; + return true; + } + } + + if (getExtensions().pathRendering) + { + switch (pname) + { + case GL_PATH_MODELVIEW_MATRIX_CHROMIUM: + case GL_PATH_PROJECTION_MATRIX_CHROMIUM: + *type = GL_FLOAT; + *numParams = 16; + return true; + } + } + + if (getExtensions().bindGeneratesResource) + { + switch (pname) + { + case GL_BIND_GENERATES_RESOURCE_CHROMIUM: + *type = GL_BOOL; + *numParams = 1; + return true; + } + } + + if (getExtensions().clientArrays) + { + switch (pname) + { + case GL_CLIENT_ARRAYS_ANGLE: + *type = GL_BOOL; + *numParams = 1; + return true; + } + } + + if (getExtensions().sRGBWriteControl) + { + switch (pname) + { + case GL_FRAMEBUFFER_SRGB_EXT: + *type = GL_BOOL; + *numParams = 1; + return true; + } + } + + if (getExtensions().robustResourceInitialization && + pname == GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE) + { + *type = GL_BOOL; + *numParams = 1; + return true; + } + + if (getExtensions().programCacheControl && pname == GL_PROGRAM_CACHE_ENABLED_ANGLE) + { + *type = GL_BOOL; + *numParams = 1; + return true; + } + + // Check for ES3.0+ parameter names which are also exposed as ES2 extensions + switch (pname) + { + // case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE // equivalent to FRAMEBUFFER_BINDING + case GL_READ_FRAMEBUFFER_BINDING_ANGLE: + if ((getClientMajorVersion() < 3) && !getExtensions().framebufferBlit) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + + case GL_NUM_PROGRAM_BINARY_FORMATS_OES: + if ((getClientMajorVersion() < 3) && !getExtensions().getProgramBinary) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + + case GL_PROGRAM_BINARY_FORMATS_OES: + if ((getClientMajorVersion() < 3) && !getExtensions().getProgramBinary) + { + return false; + } + *type = GL_INT; + *numParams = static_cast(getCaps().programBinaryFormats.size()); + return true; + + case GL_PACK_ROW_LENGTH: + case GL_PACK_SKIP_ROWS: + case GL_PACK_SKIP_PIXELS: + if ((getClientMajorVersion() < 3) && !getExtensions().packSubimage) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + case GL_UNPACK_ROW_LENGTH: + case GL_UNPACK_SKIP_ROWS: + case GL_UNPACK_SKIP_PIXELS: + if ((getClientMajorVersion() < 3) && !getExtensions().unpackSubimage) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + case GL_VERTEX_ARRAY_BINDING: + if ((getClientMajorVersion() < 3) && !getExtensions().vertexArrayObject) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + case GL_PIXEL_PACK_BUFFER_BINDING: + case GL_PIXEL_UNPACK_BUFFER_BINDING: + if ((getClientMajorVersion() < 3) && !getExtensions().pixelBufferObject) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + case GL_MAX_SAMPLES: + { + static_assert(GL_MAX_SAMPLES_ANGLE == GL_MAX_SAMPLES, + "GL_MAX_SAMPLES_ANGLE not equal to GL_MAX_SAMPLES"); + if ((getClientMajorVersion() < 3) && !getExtensions().framebufferMultisample) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + + case GL_FRAGMENT_SHADER_DERIVATIVE_HINT: + if ((getClientMajorVersion() < 3) && !getExtensions().standardDerivatives) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + } + } + + if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT) + { + if ((getClientVersion() < Version(3, 0)) && !getExtensions().drawBuffers) + { + return false; + } + *type = GL_INT; + *numParams = 1; + return true; + } + + if (getExtensions().multiview && pname == GL_MAX_VIEWS_ANGLE) + { + *type = GL_INT; + *numParams = 1; + return true; + } + + if (getClientVersion() < Version(3, 0)) + { + return false; + } + + // Check for ES3.0+ parameter names + switch (pname) + { + case GL_MAX_UNIFORM_BUFFER_BINDINGS: + case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: + case GL_UNIFORM_BUFFER_BINDING: + case GL_TRANSFORM_FEEDBACK_BINDING: + case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: + case GL_COPY_READ_BUFFER_BINDING: + case GL_COPY_WRITE_BUFFER_BINDING: + case GL_SAMPLER_BINDING: + case GL_READ_BUFFER: + case GL_TEXTURE_BINDING_3D: + case GL_TEXTURE_BINDING_2D_ARRAY: + case GL_MAX_3D_TEXTURE_SIZE: + case GL_MAX_ARRAY_TEXTURE_LAYERS: + case GL_MAX_VERTEX_UNIFORM_BLOCKS: + case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: + case GL_MAX_COMBINED_UNIFORM_BLOCKS: + case GL_MAX_VERTEX_OUTPUT_COMPONENTS: + case GL_MAX_FRAGMENT_INPUT_COMPONENTS: + case GL_MAX_VARYING_COMPONENTS: + case GL_MAX_VERTEX_UNIFORM_COMPONENTS: + case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: + case GL_MIN_PROGRAM_TEXEL_OFFSET: + case GL_MAX_PROGRAM_TEXEL_OFFSET: + case GL_NUM_EXTENSIONS: + case GL_MAJOR_VERSION: + case GL_MINOR_VERSION: + case GL_MAX_ELEMENTS_INDICES: + case GL_MAX_ELEMENTS_VERTICES: + case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: + case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: + case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: + case GL_UNPACK_IMAGE_HEIGHT: + case GL_UNPACK_SKIP_IMAGES: + { + *type = GL_INT; + *numParams = 1; + return true; + } + + case GL_MAX_ELEMENT_INDEX: + case GL_MAX_UNIFORM_BLOCK_SIZE: + case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: + case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: + case GL_MAX_SERVER_WAIT_TIMEOUT: + { + *type = GL_INT_64_ANGLEX; + *numParams = 1; + return true; + } + + case GL_TRANSFORM_FEEDBACK_ACTIVE: + case GL_TRANSFORM_FEEDBACK_PAUSED: + case GL_PRIMITIVE_RESTART_FIXED_INDEX: + case GL_RASTERIZER_DISCARD: + { + *type = GL_BOOL; + *numParams = 1; + return true; + } + + case GL_MAX_TEXTURE_LOD_BIAS: + { + *type = GL_FLOAT; + *numParams = 1; + return true; + } + } + + if (getExtensions().requestExtension) + { + switch (pname) + { + case GL_NUM_REQUESTABLE_EXTENSIONS_ANGLE: + *type = GL_INT; + *numParams = 1; + return true; + } + } + + if (getClientVersion() < Version(3, 1)) + { + return false; + } + + switch (pname) + { + case GL_ATOMIC_COUNTER_BUFFER_BINDING: + case GL_DRAW_INDIRECT_BUFFER_BINDING: + case GL_MAX_FRAMEBUFFER_WIDTH: + case GL_MAX_FRAMEBUFFER_HEIGHT: + case GL_MAX_FRAMEBUFFER_SAMPLES: + case GL_MAX_SAMPLE_MASK_WORDS: + case GL_MAX_COLOR_TEXTURE_SAMPLES: + case GL_MAX_DEPTH_TEXTURE_SAMPLES: + case GL_MAX_INTEGER_SAMPLES: + case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET: + case GL_MAX_VERTEX_ATTRIB_BINDINGS: + case GL_MAX_VERTEX_ATTRIB_STRIDE: + case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS: + case GL_MAX_VERTEX_ATOMIC_COUNTERS: + case GL_MAX_VERTEX_IMAGE_UNIFORMS: + case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS: + case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS: + case GL_MAX_FRAGMENT_ATOMIC_COUNTERS: + case GL_MAX_FRAGMENT_IMAGE_UNIFORMS: + case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS: + case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET: + case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET: + case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS: + case GL_MAX_COMPUTE_UNIFORM_BLOCKS: + case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS: + case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE: + case GL_MAX_COMPUTE_UNIFORM_COMPONENTS: + case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS: + case GL_MAX_COMPUTE_ATOMIC_COUNTERS: + case GL_MAX_COMPUTE_IMAGE_UNIFORMS: + case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS: + case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS: + case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES: + case GL_MAX_UNIFORM_LOCATIONS: + case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS: + case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE: + case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS: + case GL_MAX_COMBINED_ATOMIC_COUNTERS: + case GL_MAX_IMAGE_UNITS: + case GL_MAX_COMBINED_IMAGE_UNIFORMS: + case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS: + case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS: + case GL_SHADER_STORAGE_BUFFER_BINDING: + case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT: + case GL_TEXTURE_BINDING_2D_MULTISAMPLE: + *type = GL_INT; + *numParams = 1; + return true; + case GL_MAX_SHADER_STORAGE_BLOCK_SIZE: + *type = GL_INT_64_ANGLEX; + *numParams = 1; + return true; + case GL_SAMPLE_MASK: + *type = GL_BOOL; + *numParams = 1; + return true; + } + + return false; +} + +bool ValidationContext::getIndexedQueryParameterInfo(GLenum target, + GLenum *type, + unsigned int *numParams) +{ + if (getClientVersion() < Version(3, 0)) + { + return false; + } + + switch (target) + { + case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: + case GL_UNIFORM_BUFFER_BINDING: + { + *type = GL_INT; + *numParams = 1; + return true; + } + case GL_TRANSFORM_FEEDBACK_BUFFER_START: + case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: + case GL_UNIFORM_BUFFER_START: + case GL_UNIFORM_BUFFER_SIZE: + { + *type = GL_INT_64_ANGLEX; + *numParams = 1; + return true; + } + } + + if (getClientVersion() < Version(3, 1)) + { + return false; + } + + switch (target) + { + case GL_MAX_COMPUTE_WORK_GROUP_COUNT: + case GL_MAX_COMPUTE_WORK_GROUP_SIZE: + case GL_ATOMIC_COUNTER_BUFFER_BINDING: + case GL_SHADER_STORAGE_BUFFER_BINDING: + case GL_VERTEX_BINDING_BUFFER: + case GL_VERTEX_BINDING_DIVISOR: + case GL_VERTEX_BINDING_OFFSET: + case GL_VERTEX_BINDING_STRIDE: + case GL_SAMPLE_MASK_VALUE: + { + *type = GL_INT; + *numParams = 1; + return true; + } + case GL_ATOMIC_COUNTER_BUFFER_START: + case GL_ATOMIC_COUNTER_BUFFER_SIZE: + case GL_SHADER_STORAGE_BUFFER_START: + case GL_SHADER_STORAGE_BUFFER_SIZE: + { + *type = GL_INT_64_ANGLEX; + *numParams = 1; + return true; + } + } + + return false; +} + +Program *ValidationContext::getProgram(GLuint handle) const +{ + return mState.mShaderPrograms->getProgram(handle); +} + +Shader *ValidationContext::getShader(GLuint handle) const +{ + return mState.mShaderPrograms->getShader(handle); +} + +bool ValidationContext::isTextureGenerated(GLuint texture) const +{ + return mState.mTextures->isHandleGenerated(texture); +} + +bool ValidationContext::isBufferGenerated(GLuint buffer) const +{ + return mState.mBuffers->isHandleGenerated(buffer); +} + +bool ValidationContext::isRenderbufferGenerated(GLuint renderbuffer) const +{ + return mState.mRenderbuffers->isHandleGenerated(renderbuffer); +} + +bool ValidationContext::isFramebufferGenerated(GLuint framebuffer) const +{ + return mState.mFramebuffers->isHandleGenerated(framebuffer); +} + +bool ValidationContext::isProgramPipelineGenerated(GLuint pipeline) const +{ + return mState.mPipelines->isHandleGenerated(pipeline); +} + +bool ValidationContext::usingDisplayTextureShareGroup() const +{ + return mDisplayTextureShareGroup; +} + +GLenum ValidationContext::getConvertedRenderbufferFormat(GLenum internalformat) const +{ + return mState.mExtensions.webglCompatibility && mState.mClientVersion.major == 2 && + internalformat == GL_DEPTH_STENCIL + ? GL_DEPTH24_STENCIL8 + : internalformat; +} + +} // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/ContextState.h b/src/3rdparty/angle/src/libANGLE/ContextState.h new file mode 100644 index 0000000000..e6e9f4c6b0 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/ContextState.h @@ -0,0 +1,164 @@ +// +// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ContextState: Container class for all GL context state, caps and objects. + +#ifndef LIBANGLE_CONTEXTSTATE_H_ +#define LIBANGLE_CONTEXTSTATE_H_ + +#include "common/MemoryBuffer.h" +#include "common/angleutils.h" +#include "libANGLE/State.h" +#include "libANGLE/Version.h" +#include "libANGLE/params.h" + +namespace gl +{ +class BufferManager; +class ContextState; +class FramebufferManager; +class PathManager; +class ProgramPipelineManager; +class RenderbufferManager; +class SamplerManager; +class ShaderProgramManager; +class SyncManager; +class TextureManager; +class ValidationContext; + +static constexpr Version ES_2_0 = Version(2, 0); +static constexpr Version ES_3_0 = Version(3, 0); +static constexpr Version ES_3_1 = Version(3, 1); + +using ContextID = uintptr_t; + +class ContextState final : angle::NonCopyable +{ + public: + ContextState(ContextID context, + const ContextState *shareContextState, + TextureManager *shareTextures, + const Version &clientVersion, + State *state, + const Caps &caps, + const TextureCapsMap &textureCaps, + const Extensions &extensions, + const Limitations &limitations); + ~ContextState(); + + ContextID getContextID() const { return mContext; } + GLint getClientMajorVersion() const { return mClientVersion.major; } + GLint getClientMinorVersion() const { return mClientVersion.minor; } + const Version &getClientVersion() const { return mClientVersion; } + const State &getState() const { return *mState; } + const Caps &getCaps() const { return mCaps; } + const TextureCapsMap &getTextureCaps() const { return mTextureCaps; } + const Extensions &getExtensions() const { return mExtensions; } + const Limitations &getLimitations() const { return mLimitations; } + + const TextureCaps &getTextureCap(GLenum internalFormat) const; + + bool usingDisplayTextureShareGroup() const; + + bool isWebGL() const; + bool isWebGL1() const; + + private: + friend class Context; + friend class ValidationContext; + + Version mClientVersion; + ContextID mContext; + State *mState; + const Caps &mCaps; + const TextureCapsMap &mTextureCaps; + const Extensions &mExtensions; + const Limitations &mLimitations; + + BufferManager *mBuffers; + ShaderProgramManager *mShaderPrograms; + TextureManager *mTextures; + RenderbufferManager *mRenderbuffers; + SamplerManager *mSamplers; + SyncManager *mSyncs; + PathManager *mPaths; + FramebufferManager *mFramebuffers; + ProgramPipelineManager *mPipelines; +}; + +class ValidationContext : angle::NonCopyable +{ + public: + ValidationContext(const ValidationContext *shareContext, + TextureManager *shareTextures, + const Version &clientVersion, + State *state, + const Caps &caps, + const TextureCapsMap &textureCaps, + const Extensions &extensions, + const Limitations &limitations, + bool skipValidation); + virtual ~ValidationContext(); + + virtual void handleError(const Error &error) = 0; + + const ContextState &getContextState() const { return mState; } + GLint getClientMajorVersion() const { return mState.getClientMajorVersion(); } + GLint getClientMinorVersion() const { return mState.getClientMinorVersion(); } + const Version &getClientVersion() const { return mState.getClientVersion(); } + const State &getGLState() const { return mState.getState(); } + const Caps &getCaps() const { return mState.getCaps(); } + const TextureCapsMap &getTextureCaps() const { return mState.getTextureCaps(); } + const Extensions &getExtensions() const { return mState.getExtensions(); } + const Limitations &getLimitations() const { return mState.getLimitations(); } + bool skipValidation() const { return mSkipValidation; } + + // Specific methods needed for validation. + bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams); + bool getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams); + + Program *getProgram(GLuint handle) const; + Shader *getShader(GLuint handle) const; + + bool isTextureGenerated(GLuint texture) const; + bool isBufferGenerated(GLuint buffer) const; + bool isRenderbufferGenerated(GLuint renderbuffer) const; + bool isFramebufferGenerated(GLuint framebuffer) const; + bool isProgramPipelineGenerated(GLuint pipeline) const; + + bool usingDisplayTextureShareGroup() const; + + // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format. + GLenum getConvertedRenderbufferFormat(GLenum internalformat) const; + + bool isWebGL() const { return mState.isWebGL(); } + bool isWebGL1() const { return mState.isWebGL1(); } + + template + const T &getParams() const; + + protected: + ContextState mState; + bool mSkipValidation; + bool mDisplayTextureShareGroup; + + // Caches entry point parameters and values re-used between layers. + mutable const ParamTypeInfo *mSavedArgsType; + static constexpr size_t kParamsBufferSize = 64u; + mutable std::array mParamsBuffer; +}; + +template +const T &ValidationContext::getParams() const +{ + const T *params = reinterpret_cast(mParamsBuffer.data()); + ASSERT(mSavedArgsType->hasDynamicType(T::TypeInfo)); + return *params; +} + +} // namespace gl + +#endif // LIBANGLE_CONTEXTSTATE_H_ diff --git a/src/3rdparty/angle/src/libANGLE/Data.cpp b/src/3rdparty/angle/src/libANGLE/Data.cpp deleted file mode 100644 index 83f04b5a0b..0000000000 --- a/src/3rdparty/angle/src/libANGLE/Data.cpp +++ /dev/null @@ -1,56 +0,0 @@ -// -// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// Data.cpp: Container class for all GL relevant state, caps and objects - -#include "libANGLE/Data.h" -#include "libANGLE/ResourceManager.h" - -namespace gl -{ - -Data::Data(uintptr_t contextIn, - GLint clientVersionIn, - const State &stateIn, - const Caps &capsIn, - const TextureCapsMap &textureCapsIn, - const Extensions &extensionsIn, - const ResourceManager *resourceManagerIn, - const Limitations &limitationsIn) - : context(contextIn), - clientVersion(clientVersionIn), - state(&stateIn), - caps(&capsIn), - textureCaps(&textureCapsIn), - extensions(&extensionsIn), - resourceManager(resourceManagerIn), - limitations(&limitationsIn) -{} - -Data::~Data() -{ -} - -ValidationContext::ValidationContext(GLint clientVersion, - const State &state, - const Caps &caps, - const TextureCapsMap &textureCaps, - const Extensions &extensions, - const ResourceManager *resourceManager, - const Limitations &limitations, - bool skipValidation) - : mData(reinterpret_cast(this), - clientVersion, - state, - caps, - textureCaps, - extensions, - resourceManager, - limitations), - mSkipValidation(skipValidation) -{ -} -} // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/Data.h b/src/3rdparty/angle/src/libANGLE/Data.h deleted file mode 100644 index f7230d74bc..0000000000 --- a/src/3rdparty/angle/src/libANGLE/Data.h +++ /dev/null @@ -1,72 +0,0 @@ -// -// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// Data.h: Container class for all GL relevant state, caps and objects - -#ifndef LIBANGLE_DATA_H_ -#define LIBANGLE_DATA_H_ - -#include "common/angleutils.h" -#include "libANGLE/State.h" - -namespace gl -{ - -struct Data final : public angle::NonCopyable -{ - public: - Data(uintptr_t context, - GLint clientVersion, - const State &state, - const Caps &caps, - const TextureCapsMap &textureCaps, - const Extensions &extensions, - const ResourceManager *resourceManager, - const Limitations &limitations); - ~Data(); - - uintptr_t context; - GLint clientVersion; - const State *state; - const Caps *caps; - const TextureCapsMap *textureCaps; - const Extensions *extensions; - const ResourceManager *resourceManager; - const Limitations *limitations; -}; - -class ValidationContext : angle::NonCopyable -{ - public: - ValidationContext(GLint clientVersion, - const State &state, - const Caps &caps, - const TextureCapsMap &textureCaps, - const Extensions &extensions, - const ResourceManager *resourceManager, - const Limitations &limitations, - bool skipValidation); - virtual ~ValidationContext() {} - - virtual void recordError(const Error &error) = 0; - - const Data &getData() const { return mData; } - int getClientVersion() const { return mData.clientVersion; } - const State &getState() const { return *mData.state; } - const Caps &getCaps() const { return *mData.caps; } - const TextureCapsMap &getTextureCaps() const { return *mData.textureCaps; } - const Extensions &getExtensions() const { return *mData.extensions; } - const Limitations &getLimitations() const { return *mData.limitations; } - bool skipValidation() const { return mSkipValidation; } - - protected: - Data mData; - bool mSkipValidation; -}; - -} - -#endif // LIBANGLE_DATA_H_ diff --git a/src/3rdparty/angle/src/libANGLE/Debug.cpp b/src/3rdparty/angle/src/libANGLE/Debug.cpp index 30321f4160..96f30df98c 100644 --- a/src/3rdparty/angle/src/libANGLE/Debug.cpp +++ b/src/3rdparty/angle/src/libANGLE/Debug.cpp @@ -16,6 +16,26 @@ namespace gl { +Debug::Control::Control() +{ +} + +Debug::Control::~Control() +{ +} + +Debug::Control::Control(const Control &other) = default; + +Debug::Group::Group() +{ +} + +Debug::Group::~Group() +{ +} + +Debug::Group::Group(const Group &other) = default; + Debug::Debug() : mOutputEnabled(false), mCallbackFunction(nullptr), @@ -28,6 +48,10 @@ Debug::Debug() pushDefaultGroup(); } +Debug::~Debug() +{ +} + void Debug::setMaxLoggedMessages(GLuint maxLoggedMessages) { mMaxLoggedMessages = maxLoggedMessages; diff --git a/src/3rdparty/angle/src/libANGLE/Debug.h b/src/3rdparty/angle/src/libANGLE/Debug.h index f545b815e4..2c15c25e9a 100644 --- a/src/3rdparty/angle/src/libANGLE/Debug.h +++ b/src/3rdparty/angle/src/libANGLE/Debug.h @@ -31,6 +31,7 @@ class Debug : angle::NonCopyable { public: Debug(); + ~Debug(); void setMaxLoggedMessages(GLuint maxLoggedMessages); @@ -91,6 +92,10 @@ class Debug : angle::NonCopyable struct Control { + Control(); + ~Control(); + Control(const Control &other); + GLenum source; GLenum type; GLenum severity; @@ -100,6 +105,10 @@ class Debug : angle::NonCopyable struct Group { + Group(); + ~Group(); + Group(const Group &other); + GLenum source; GLuint id; std::string message; diff --git a/src/3rdparty/angle/src/libANGLE/Device.cpp b/src/3rdparty/angle/src/libANGLE/Device.cpp index eb30b2023f..3ebf48b919 100644 --- a/src/3rdparty/angle/src/libANGLE/Device.cpp +++ b/src/3rdparty/angle/src/libANGLE/Device.cpp @@ -45,33 +45,28 @@ static DeviceSet *GetDeviceSet() // Static factory methods egl::Error Device::CreateDevice(void *devicePointer, EGLint deviceType, Device **outDevice) { + *outDevice = nullptr; + #if defined(ANGLE_ENABLE_D3D11) if (deviceType == EGL_D3D11_DEVICE_ANGLE) { - rx::DeviceD3D *deviceD3D = new rx::DeviceD3D(); - egl::Error error = deviceD3D->initialize(devicePointer, deviceType, EGL_TRUE); - if (error.isError()) - { - *outDevice = nullptr; - return error; - } - - *outDevice = new Device(nullptr, deviceD3D); + std::unique_ptr deviceD3D(new rx::DeviceD3D()); + ANGLE_TRY(deviceD3D->initialize(devicePointer, deviceType, EGL_TRUE)); + *outDevice = new Device(nullptr, deviceD3D.release()); GetDeviceSet()->insert(*outDevice); - return egl::Error(EGL_SUCCESS); + return NoError(); } #endif // Note that creating an EGL device from inputted D3D9 parameters isn't currently supported - *outDevice = nullptr; - return egl::Error(EGL_BAD_ATTRIBUTE); + return EglBadAttribute(); } egl::Error Device::CreateDevice(Display *owningDisplay, rx::DeviceImpl *impl, Device **outDevice) { *outDevice = new Device(owningDisplay, impl); GetDeviceSet()->insert(*outDevice); - return egl::Error(EGL_SUCCESS); + return NoError(); } bool Device::IsValidDevice(Device *device) diff --git a/src/3rdparty/angle/src/libANGLE/Display.cpp b/src/3rdparty/angle/src/libANGLE/Display.cpp index 486c74abc0..735b472787 100644 --- a/src/3rdparty/angle/src/libANGLE/Display.cpp +++ b/src/3rdparty/angle/src/libANGLE/Display.cpp @@ -28,6 +28,8 @@ #include "libANGLE/histogram_macros.h" #include "libANGLE/Image.h" #include "libANGLE/Surface.h" +#include "libANGLE/Stream.h" +#include "libANGLE/ResourceManager.h" #include "libANGLE/renderer/DisplayImpl.h" #include "libANGLE/renderer/ImageImpl.h" #include "third_party/trace_event/trace_event.h" @@ -43,39 +45,35 @@ # include "libANGLE/renderer/gl/glx/DisplayGLX.h" # elif defined(ANGLE_PLATFORM_APPLE) # include "libANGLE/renderer/gl/cgl/DisplayCGL.h" +# elif defined(ANGLE_USE_OZONE) +# include "libANGLE/renderer/gl/egl/ozone/DisplayOzone.h" +# elif defined(ANGLE_PLATFORM_ANDROID) +# include "libANGLE/renderer/gl/egl/android/DisplayAndroid.h" # else # error Unsupported OpenGL platform. # endif #endif +#if defined(ANGLE_ENABLE_NULL) +#include "libANGLE/renderer/null/DisplayNULL.h" +#endif // defined(ANGLE_ENABLE_NULL) + +#if defined(ANGLE_ENABLE_VULKAN) +#if defined(ANGLE_PLATFORM_WINDOWS) +#include "libANGLE/renderer/vulkan/win32/DisplayVkWin32.h" +#elif defined(ANGLE_PLATFORM_LINUX) +#include "libANGLE/renderer/vulkan/xcb/DisplayVkXcb.h" +#else +#error Unsupported Vulkan platform. +#endif +#endif // defined(ANGLE_ENABLE_VULKAN) + namespace egl { namespace { -class DefaultPlatform : public angle::Platform -{ -public: - DefaultPlatform() {} - ~DefaultPlatform() override {} -}; - -DefaultPlatform *defaultPlatform = nullptr; - -void InitDefaultPlatformImpl() -{ - if (ANGLEPlatformCurrent() == nullptr) - { - if (defaultPlatform == nullptr) - { - defaultPlatform = new DefaultPlatform(); - } - - ANGLEPlatformInitialize(defaultPlatform); - } -} - typedef std::map WindowSurfaceMap; // Get a map of all EGL window surfaces to validate that no window has more than one EGL surface // associated with it. @@ -99,7 +97,7 @@ static DevicePlatformDisplayMap *GetDevicePlatformDisplayMap() return &displays; } -rx::DisplayImpl *CreateDisplayFromDevice(Device *eglDevice) +rx::DisplayImpl *CreateDisplayFromDevice(Device *eglDevice, const DisplayState &state) { rx::DisplayImpl *impl = nullptr; @@ -107,7 +105,7 @@ rx::DisplayImpl *CreateDisplayFromDevice(Device *eglDevice) { #if defined(ANGLE_ENABLE_D3D11) case EGL_D3D11_DEVICE_ANGLE: - impl = new rx::DisplayD3D(); + impl = new rx::DisplayD3D(state); break; #endif #if defined(ANGLE_ENABLE_D3D9) @@ -130,86 +128,162 @@ rx::DisplayImpl *CreateDisplayFromDevice(Device *eglDevice) return impl; } -rx::DisplayImpl *CreateDisplayFromAttribs(const AttributeMap &attribMap) +rx::DisplayImpl *CreateDisplayFromAttribs(const AttributeMap &attribMap, const DisplayState &state) { rx::DisplayImpl *impl = nullptr; - EGLint displayType = attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE); + EGLAttrib displayType = + attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE); switch (displayType) { - case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE: + case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE: #if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11) - // Default to D3D displays - impl = new rx::DisplayD3D(); + // Default to D3D displays + impl = new rx::DisplayD3D(state); #elif defined(ANGLE_USE_X11) - impl = new rx::DisplayGLX(); + impl = new rx::DisplayGLX(state); #elif defined(ANGLE_PLATFORM_APPLE) - impl = new rx::DisplayCGL(); + impl = new rx::DisplayCGL(state); +#elif defined(ANGLE_USE_OZONE) + impl = new rx::DisplayOzone(state); +#elif defined(ANGLE_PLATFORM_ANDROID) + impl = new rx::DisplayAndroid(state); #else - // No display available - UNREACHABLE(); + // No display available + UNREACHABLE(); #endif - break; + break; - case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE: - case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE: + case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE: + case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE: #if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11) - impl = new rx::DisplayD3D(); + impl = new rx::DisplayD3D(state); #else - // A D3D display was requested on a platform that doesn't support it - UNREACHABLE(); + // A D3D display was requested on a platform that doesn't support it + UNREACHABLE(); #endif - break; + break; - case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE: + case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE: #if defined(ANGLE_ENABLE_OPENGL) #if defined(ANGLE_PLATFORM_WINDOWS) - impl = new rx::DisplayWGL(); + impl = new rx::DisplayWGL(state); #elif defined(ANGLE_USE_X11) - impl = new rx::DisplayGLX(); + impl = new rx::DisplayGLX(state); #elif defined(ANGLE_PLATFORM_APPLE) - impl = new rx::DisplayCGL(); + impl = new rx::DisplayCGL(state); +#elif defined(ANGLE_USE_OZONE) + // This might work but has never been tried, so disallow for now. + impl = nullptr; +#elif defined(ANGLE_PLATFORM_ANDROID) + // No GL support on this platform, fail display creation. + impl = nullptr; #else #error Unsupported OpenGL platform. #endif #else - UNREACHABLE(); -#endif - break; + // No display available + UNREACHABLE(); +#endif // defined(ANGLE_ENABLE_OPENGL) + break; + case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE: #if defined(ANGLE_ENABLE_OPENGL) - case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE: #if defined(ANGLE_PLATFORM_WINDOWS) - impl = new rx::DisplayWGL(); + impl = new rx::DisplayWGL(state); #elif defined(ANGLE_USE_X11) - impl = new rx::DisplayGLX(); + impl = new rx::DisplayGLX(state); +#elif defined(ANGLE_USE_OZONE) + impl = new rx::DisplayOzone(state); +#elif defined(ANGLE_PLATFORM_ANDROID) + impl = new rx::DisplayAndroid(state); #else - // No GLES support on this platform, fail display creation. - impl = nullptr; -#endif - break; + // No GLES support on this platform, fail display creation. + impl = nullptr; #endif +#endif // defined(ANGLE_ENABLE_OPENGL) + break; - default: - UNREACHABLE(); - break; + case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE: +#if defined(ANGLE_ENABLE_VULKAN) +#if defined(ANGLE_PLATFORM_WINDOWS) + impl = new rx::DisplayVkWin32(state); +#elif defined(ANGLE_PLATFORM_LINUX) + impl = new rx::DisplayVkXcb(state); +#else +#error Unsupported Vulkan platform. +#endif +#else + // No display available + UNREACHABLE(); +#endif // defined(ANGLE_ENABLE_VULKAN) + break; + + case EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE: +#if defined(ANGLE_ENABLE_NULL) + impl = new rx::DisplayNULL(state); +#else + // No display available + UNREACHABLE(); +#endif // defined(ANGLE_ENABLE_NULL) + break; + + default: + UNREACHABLE(); + break; } return impl; } +void Display_logError(angle::PlatformMethods *platform, const char *errorMessage) +{ + gl::Trace(gl::LOG_ERR, errorMessage); } -Display *Display::GetDisplayFromAttribs(void *native_display, const AttributeMap &attribMap) +void Display_logWarning(angle::PlatformMethods *platform, const char *warningMessage) { - // Initialize the global platform if not already - InitDefaultPlatformImpl(); + gl::Trace(gl::LOG_WARN, warningMessage); +} +void Display_logInfo(angle::PlatformMethods *platform, const char *infoMessage) +{ + // Uncomment to get info spam + // gl::Trace(gl::LOG_WARN, infoMessage); +} + +void ANGLESetDefaultDisplayPlatform(angle::EGLDisplayType display) +{ + angle::PlatformMethods *platformMethods = ANGLEPlatformCurrent(); + if (platformMethods->logError != angle::DefaultLogError) + { + // Don't reset pre-set Platform to Default + return; + } + + ANGLEResetDisplayPlatform(display); + platformMethods->logError = Display_logError; + platformMethods->logWarning = Display_logWarning; + platformMethods->logInfo = Display_logInfo; +} + +} // anonymous namespace + +DisplayState::DisplayState() +{ +} + +DisplayState::~DisplayState() +{ +} + +// static +Display *Display::GetDisplayFromNativeDisplay(EGLNativeDisplayType nativeDisplay, + const AttributeMap &attribMap) +{ Display *display = nullptr; - EGLNativeDisplayType displayId = reinterpret_cast(native_display); - - ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap(); - ANGLEPlatformDisplayMap::const_iterator iter = displays->find(displayId); + ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap(); + const auto &iter = displays->find(nativeDisplay); if (iter != displays->end()) { display = iter->second; @@ -218,19 +292,19 @@ Display *Display::GetDisplayFromAttribs(void *native_display, const AttributeMap if (display == nullptr) { // Validate the native display - if (!Display::isValidNativeDisplay(displayId)) + if (!Display::isValidNativeDisplay(nativeDisplay)) { - return NULL; + return nullptr; } - display = new Display(EGL_PLATFORM_ANGLE_ANGLE, displayId, nullptr); - displays->insert(std::make_pair(displayId, display)); + display = new Display(EGL_PLATFORM_ANGLE_ANGLE, nativeDisplay, nullptr); + displays->insert(std::make_pair(nativeDisplay, display)); } // Apply new attributes if the display is not initialized yet. if (!display->isInitialized()) { - rx::DisplayImpl *impl = CreateDisplayFromAttribs(attribMap); + rx::DisplayImpl *impl = CreateDisplayFromAttribs(attribMap, display->getState()); if (impl == nullptr) { // No valid display implementation for these attributes @@ -243,15 +317,12 @@ Display *Display::GetDisplayFromAttribs(void *native_display, const AttributeMap return display; } -Display *Display::GetDisplayFromDevice(void *native_display) +// static +Display *Display::GetDisplayFromDevice(Device *device, const AttributeMap &attribMap) { - // Initialize the global platform if not already - InitDefaultPlatformImpl(); - Display *display = nullptr; - Device *eglDevice = reinterpret_cast(native_display); - ASSERT(Device::IsValidDevice(eglDevice)); + ASSERT(Device::IsValidDevice(device)); ANGLEPlatformDisplayMap *anglePlatformDisplays = GetANGLEPlatformDisplayMap(); DevicePlatformDisplayMap *devicePlatformDisplays = GetDevicePlatformDisplayMap(); @@ -260,7 +331,7 @@ Display *Display::GetDisplayFromDevice(void *native_display) for (auto &displayMapEntry : *anglePlatformDisplays) { egl::Display *iterDisplay = displayMapEntry.second; - if (iterDisplay->getDevice() == eglDevice) + if (iterDisplay->getDevice() == device) { display = iterDisplay; } @@ -269,7 +340,7 @@ Display *Display::GetDisplayFromDevice(void *native_display) if (display == nullptr) { // See if the eglDevice is in use by a Display created using the DEVICE platform - DevicePlatformDisplayMap::const_iterator iter = devicePlatformDisplays->find(eglDevice); + const auto &iter = devicePlatformDisplays->find(device); if (iter != devicePlatformDisplays->end()) { display = iter->second; @@ -279,15 +350,15 @@ Display *Display::GetDisplayFromDevice(void *native_display) if (display == nullptr) { // Otherwise create a new Display - display = new Display(EGL_PLATFORM_DEVICE_EXT, 0, eglDevice); - devicePlatformDisplays->insert(std::make_pair(eglDevice, display)); + display = new Display(EGL_PLATFORM_DEVICE_EXT, 0, device); + devicePlatformDisplays->insert(std::make_pair(device, display)); } // Apply new attributes if the display is not initialized yet. if (!display->isInitialized()) { - rx::DisplayImpl *impl = CreateDisplayFromDevice(eglDevice); - display->setAttributes(impl, egl::AttributeMap()); + rx::DisplayImpl *impl = CreateDisplayFromDevice(device, display->getState()); + display->setAttributes(impl, attribMap); } return display; @@ -299,19 +370,26 @@ Display::Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDe mAttributeMap(), mConfigSet(), mContextSet(), + mStreamSet(), mInitialized(false), + mDeviceLost(false), mCaps(), mDisplayExtensions(), mDisplayExtensionString(), mVendorString(), mDevice(eglDevice), - mPlatform(platform) + mPlatform(platform), + mTextureManager(nullptr), + mMemoryProgramCache(gl::kDefaultMaxProgramCacheMemoryBytes), + mGlobalTextureShareGroupUsers(0), + mProxyContext(this) { } Display::~Display() { - terminate(); + // TODO(jmadill): When is this called? + // terminate(); if (mPlatform == EGL_PLATFORM_ANGLE_ANGLE) { @@ -336,6 +414,8 @@ Display::~Display() UNREACHABLE(); } + mProxyContext.reset(nullptr); + SafeDelete(mDevice); SafeDelete(mImplementation); } @@ -353,8 +433,20 @@ void Display::setAttributes(rx::DisplayImpl *impl, const AttributeMap &attribMap Error Display::initialize() { - // Re-initialize default platform if it's needed - InitDefaultPlatformImpl(); + // TODO(jmadill): Store Platform in Display and init here. + const angle::PlatformMethods *platformMethods = + reinterpret_cast( + mAttributeMap.get(EGL_PLATFORM_ANGLE_PLATFORM_METHODS_ANGLEX, 0)); + if (platformMethods != nullptr) + { + *ANGLEPlatformCurrent() = *platformMethods; + } + else + { + ANGLESetDefaultDisplayPlatform(this); + } + + gl::InitializeDebugAnnotations(&mAnnotator); SCOPED_ANGLE_HISTOGRAM_TIMER("GPU.ANGLE.DisplayInitializeMS"); TRACE_EVENT0("gpu.angle", "egl::Display::initialize"); @@ -363,17 +455,14 @@ Error Display::initialize() if (isInitialized()) { - return Error(EGL_SUCCESS); + return NoError(); } Error error = mImplementation->initialize(this); if (error.isError()) { // Log extended error message here - std::stringstream errorStream; - errorStream << "ANGLE Display::initialize error " << error.getID() << ": " - << error.getMessage(); - ANGLEPlatformCurrent()->logError(errorStream.str().c_str()); + ERR() << "ANGLE Display::initialize error " << error.getID() << ": " << error.getMessage(); return error; } @@ -383,7 +472,7 @@ Error Display::initialize() if (mConfigSet.size() == 0) { mImplementation->terminate(); - return Error(EGL_NOT_INITIALIZED); + return EglNotInitialized(); } initDisplayExtensions(); @@ -395,17 +484,8 @@ Error Display::initialize() if (mDisplayExtensions.deviceQuery) { rx::DeviceImpl *impl = nullptr; - error = mImplementation->getDevice(&impl); - if (error.isError()) - { - return error; - } - - error = Device::CreateDevice(this, impl, &mDevice); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mImplementation->getDevice(&impl)); + ANGLE_TRY(Device::CreateDevice(this, impl, &mDevice)); } else { @@ -419,28 +499,45 @@ Error Display::initialize() ASSERT(mDevice != nullptr); } + mProxyContext.reset(nullptr); + gl::Context *proxyContext = new gl::Context(mImplementation, nullptr, nullptr, nullptr, nullptr, + egl::AttributeMap(), mDisplayExtensions); + mProxyContext.reset(proxyContext); + mInitialized = true; - return Error(EGL_SUCCESS); + return NoError(); } -void Display::terminate() +Error Display::terminate() { - makeCurrent(nullptr, nullptr, nullptr); + ANGLE_TRY(makeCurrent(nullptr, nullptr, nullptr)); + + mMemoryProgramCache.clear(); + + mProxyContext.reset(nullptr); while (!mContextSet.empty()) { - destroyContext(*mContextSet.begin()); + ANGLE_TRY(destroyContext(*mContextSet.begin())); } + // The global texture manager should be deleted with the last context that uses it. + ASSERT(mGlobalTextureShareGroupUsers == 0 && mTextureManager == nullptr); + while (!mImageSet.empty()) { destroyImage(*mImageSet.begin()); } - while (!mImplementation->getSurfaceSet().empty()) + while (!mStreamSet.empty()) { - destroySurface(*mImplementation->getSurfaceSet().begin()); + destroyStream(*mStreamSet.begin()); + } + + while (!mState.surfaceSet.empty()) + { + ANGLE_TRY(destroySurface(*mState.surfaceSet.begin())); } mConfigSet.clear(); @@ -454,9 +551,16 @@ void Display::terminate() mImplementation->terminate(); + mDeviceLost = false; + mInitialized = false; - // Never de-init default platform.. terminate is not that final. + gl::UninitializeDebugAnnotations(); + + // TODO(jmadill): Store Platform in Display and deinit here. + ANGLEResetDisplayPlatform(this); + + return NoError(); } std::vector Display::getConfigs(const egl::AttributeMap &attribs) const @@ -464,189 +568,100 @@ std::vector Display::getConfigs(const egl::AttributeMap &attribs) return mConfigSet.filter(attribs); } -bool Display::getConfigAttrib(const Config *configuration, EGLint attribute, EGLint *value) -{ - switch (attribute) - { - case EGL_BUFFER_SIZE: *value = configuration->bufferSize; break; - case EGL_ALPHA_SIZE: *value = configuration->alphaSize; break; - case EGL_BLUE_SIZE: *value = configuration->blueSize; break; - case EGL_GREEN_SIZE: *value = configuration->greenSize; break; - case EGL_RED_SIZE: *value = configuration->redSize; break; - case EGL_DEPTH_SIZE: *value = configuration->depthSize; break; - case EGL_STENCIL_SIZE: *value = configuration->stencilSize; break; - case EGL_CONFIG_CAVEAT: *value = configuration->configCaveat; break; - case EGL_CONFIG_ID: *value = configuration->configID; break; - case EGL_LEVEL: *value = configuration->level; break; - case EGL_NATIVE_RENDERABLE: *value = configuration->nativeRenderable; break; - case EGL_NATIVE_VISUAL_ID: *value = configuration->nativeVisualID; break; - case EGL_NATIVE_VISUAL_TYPE: *value = configuration->nativeVisualType; break; - case EGL_SAMPLES: *value = configuration->samples; break; - case EGL_SAMPLE_BUFFERS: *value = configuration->sampleBuffers; break; - case EGL_SURFACE_TYPE: *value = configuration->surfaceType; break; - case EGL_TRANSPARENT_TYPE: *value = configuration->transparentType; break; - case EGL_TRANSPARENT_BLUE_VALUE: *value = configuration->transparentBlueValue; break; - case EGL_TRANSPARENT_GREEN_VALUE: *value = configuration->transparentGreenValue; break; - case EGL_TRANSPARENT_RED_VALUE: *value = configuration->transparentRedValue; break; - case EGL_BIND_TO_TEXTURE_RGB: *value = configuration->bindToTextureRGB; break; - case EGL_BIND_TO_TEXTURE_RGBA: *value = configuration->bindToTextureRGBA; break; - case EGL_MIN_SWAP_INTERVAL: *value = configuration->minSwapInterval; break; - case EGL_MAX_SWAP_INTERVAL: *value = configuration->maxSwapInterval; break; - case EGL_LUMINANCE_SIZE: *value = configuration->luminanceSize; break; - case EGL_ALPHA_MASK_SIZE: *value = configuration->alphaMaskSize; break; - case EGL_COLOR_BUFFER_TYPE: *value = configuration->colorBufferType; break; - case EGL_RENDERABLE_TYPE: *value = configuration->renderableType; break; - case EGL_MATCH_NATIVE_PIXMAP: *value = false; UNIMPLEMENTED(); break; - case EGL_CONFORMANT: *value = configuration->conformant; break; - case EGL_MAX_PBUFFER_WIDTH: *value = configuration->maxPBufferWidth; break; - case EGL_MAX_PBUFFER_HEIGHT: *value = configuration->maxPBufferHeight; break; - case EGL_MAX_PBUFFER_PIXELS: *value = configuration->maxPBufferPixels; break; - - case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE: - if (!getExtensions().surfaceOrientation) - { - return false; - } - *value = configuration->optimalOrientation; - break; - - default: - return false; - } - - return true; -} - -Error Display::createWindowSurface(const Config *configuration, EGLNativeWindowType window, const AttributeMap &attribs, +Error Display::createWindowSurface(const Config *configuration, + EGLNativeWindowType window, + const AttributeMap &attribs, Surface **outSurface) { if (mImplementation->testDeviceLost()) { - Error error = restoreLostDevice(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(restoreLostDevice()); } - rx::SurfaceImpl *surfaceImpl = mImplementation->createWindowSurface(configuration, window, attribs); - ASSERT(surfaceImpl != nullptr); + SurfacePointer surface(new WindowSurface(mImplementation, configuration, window, attribs), + this); + ANGLE_TRY(surface->initialize(this)); - Error error = surfaceImpl->initialize(); - if (error.isError()) - { - SafeDelete(surfaceImpl); - return error; - } - - Surface *surface = new Surface(surfaceImpl, EGL_WINDOW_BIT, configuration, attribs); - mImplementation->getSurfaceSet().insert(surface); + ASSERT(outSurface != nullptr); + *outSurface = surface.release(); + mState.surfaceSet.insert(*outSurface); WindowSurfaceMap *windowSurfaces = GetWindowSurfaces(); ASSERT(windowSurfaces && windowSurfaces->find(window) == windowSurfaces->end()); - windowSurfaces->insert(std::make_pair(window, surface)); + windowSurfaces->insert(std::make_pair(window, *outSurface)); - ASSERT(outSurface != nullptr); - *outSurface = surface; - return Error(EGL_SUCCESS); + return NoError(); } -Error Display::createPbufferSurface(const Config *configuration, const AttributeMap &attribs, Surface **outSurface) +Error Display::createPbufferSurface(const Config *configuration, + const AttributeMap &attribs, + Surface **outSurface) { ASSERT(isInitialized()); if (mImplementation->testDeviceLost()) { - Error error = restoreLostDevice(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(restoreLostDevice()); } - rx::SurfaceImpl *surfaceImpl = mImplementation->createPbufferSurface(configuration, attribs); - ASSERT(surfaceImpl != nullptr); - - Error error = surfaceImpl->initialize(); - if (error.isError()) - { - SafeDelete(surfaceImpl); - return error; - } - - Surface *surface = new Surface(surfaceImpl, EGL_PBUFFER_BIT, configuration, attribs); - mImplementation->getSurfaceSet().insert(surface); + SurfacePointer surface(new PbufferSurface(mImplementation, configuration, attribs), this); + ANGLE_TRY(surface->initialize(this)); ASSERT(outSurface != nullptr); - *outSurface = surface; - return Error(EGL_SUCCESS); + *outSurface = surface.release(); + mState.surfaceSet.insert(*outSurface); + + return NoError(); } -Error Display::createPbufferFromClientBuffer(const Config *configuration, EGLClientBuffer shareHandle, - const AttributeMap &attribs, Surface **outSurface) +Error Display::createPbufferFromClientBuffer(const Config *configuration, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const AttributeMap &attribs, + Surface **outSurface) { ASSERT(isInitialized()); if (mImplementation->testDeviceLost()) { - Error error = restoreLostDevice(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(restoreLostDevice()); } - rx::SurfaceImpl *surfaceImpl = mImplementation->createPbufferFromClientBuffer(configuration, shareHandle, attribs); - ASSERT(surfaceImpl != nullptr); - - Error error = surfaceImpl->initialize(); - if (error.isError()) - { - SafeDelete(surfaceImpl); - return error; - } - - Surface *surface = new Surface(surfaceImpl, EGL_PBUFFER_BIT, configuration, attribs); - mImplementation->getSurfaceSet().insert(surface); + SurfacePointer surface( + new PbufferSurface(mImplementation, configuration, buftype, clientBuffer, attribs), this); + ANGLE_TRY(surface->initialize(this)); ASSERT(outSurface != nullptr); - *outSurface = surface; - return Error(EGL_SUCCESS); + *outSurface = surface.release(); + mState.surfaceSet.insert(*outSurface); + + return NoError(); } -Error Display::createPixmapSurface(const Config *configuration, NativePixmapType nativePixmap, const AttributeMap &attribs, +Error Display::createPixmapSurface(const Config *configuration, + NativePixmapType nativePixmap, + const AttributeMap &attribs, Surface **outSurface) { ASSERT(isInitialized()); if (mImplementation->testDeviceLost()) { - Error error = restoreLostDevice(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(restoreLostDevice()); } - rx::SurfaceImpl *surfaceImpl = mImplementation->createPixmapSurface(configuration, nativePixmap, attribs); - ASSERT(surfaceImpl != nullptr); - - Error error = surfaceImpl->initialize(); - if (error.isError()) - { - SafeDelete(surfaceImpl); - return error; - } - - Surface *surface = new Surface(surfaceImpl, EGL_PIXMAP_BIT, configuration, attribs); - mImplementation->getSurfaceSet().insert(surface); + SurfacePointer surface(new PixmapSurface(mImplementation, configuration, nativePixmap, attribs), + this); + ANGLE_TRY(surface->initialize(this)); ASSERT(outSurface != nullptr); - *outSurface = surface; - return Error(EGL_SUCCESS); + *outSurface = surface.release(); + mState.surfaceSet.insert(*outSurface); + + return NoError(); } -Error Display::createImage(gl::Context *context, +Error Display::createImage(const gl::Context *context, EGLenum target, EGLClientBuffer buffer, const AttributeMap &attribs, @@ -656,11 +671,7 @@ Error Display::createImage(gl::Context *context, if (mImplementation->testDeviceLost()) { - Error error = restoreLostDevice(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(restoreLostDevice()); } egl::ImageSibling *sibling = nullptr; @@ -678,16 +689,11 @@ Error Display::createImage(gl::Context *context, } ASSERT(sibling != nullptr); - rx::ImageImpl *imageImpl = mImplementation->createImage(target, sibling, attribs); - ASSERT(imageImpl != nullptr); + angle::UniqueObjectPointer imagePtr( + new Image(mImplementation, target, sibling, attribs), context); + ANGLE_TRY(imagePtr->initialize()); - Error error = imageImpl->initialize(); - if (error.isError()) - { - return error; - } - - Image *image = new Image(imageImpl, target, sibling, attribs); + Image *image = imagePtr.release(); ASSERT(outImage != nullptr); *outImage = image; @@ -696,49 +702,92 @@ Error Display::createImage(gl::Context *context, image->addRef(); mImageSet.insert(image); - return Error(EGL_SUCCESS); + return NoError(); } -Error Display::createContext(const Config *configuration, gl::Context *shareContext, const AttributeMap &attribs, +Error Display::createStream(const AttributeMap &attribs, Stream **outStream) +{ + ASSERT(isInitialized()); + + Stream *stream = new Stream(this, attribs); + + ASSERT(stream != nullptr); + mStreamSet.insert(stream); + + ASSERT(outStream != nullptr); + *outStream = stream; + + return NoError(); +} + +Error Display::createContext(const Config *configuration, + gl::Context *shareContext, + const AttributeMap &attribs, gl::Context **outContext) { ASSERT(isInitialized()); if (mImplementation->testDeviceLost()) { - Error error = restoreLostDevice(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(restoreLostDevice()); } - gl::Context *context = *outContext = - mImplementation->createContext(configuration, shareContext, attribs); + // This display texture sharing will allow the first context to create the texture share group. + bool usingDisplayTextureShareGroup = + attribs.get(EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE, EGL_FALSE) == EGL_TRUE; + gl::TextureManager *shareTextures = nullptr; + + if (usingDisplayTextureShareGroup) + { + ASSERT((mTextureManager == nullptr) == (mGlobalTextureShareGroupUsers == 0)); + if (mTextureManager == nullptr) + { + mTextureManager = new gl::TextureManager(); + } + + mGlobalTextureShareGroupUsers++; + shareTextures = mTextureManager; + } + + gl::MemoryProgramCache *cachePointer = &mMemoryProgramCache; + + // Check context creation attributes to see if we should enable the cache. + if (mAttributeMap.get(EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE, EGL_TRUE) == EGL_FALSE) + { + cachePointer = nullptr; + } + + // A program cache size of zero indicates it should be disabled. + if (mMemoryProgramCache.maxSize() == 0) + { + cachePointer = nullptr; + } + + gl::Context *context = + new gl::Context(mImplementation, configuration, shareContext, shareTextures, cachePointer, + attribs, mDisplayExtensions); ASSERT(context != nullptr); mContextSet.insert(context); ASSERT(outContext != nullptr); *outContext = context; - return Error(EGL_SUCCESS); + return NoError(); } -Error Display::makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context) +Error Display::makeCurrent(egl::Surface *drawSurface, + egl::Surface *readSurface, + gl::Context *context) { - Error error = mImplementation->makeCurrent(drawSurface, readSurface, context); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mImplementation->makeCurrent(drawSurface, readSurface, context)); - if (context != nullptr && drawSurface != nullptr) + if (context != nullptr) { ASSERT(readSurface == drawSurface); - context->makeCurrent(drawSurface); + ANGLE_TRY(context->makeCurrent(this, drawSurface)); } - return egl::Error(EGL_SUCCESS); + return NoError(); } Error Display::restoreLostDevice() @@ -748,14 +797,14 @@ Error Display::restoreLostDevice() if ((*ctx)->isResetNotificationEnabled()) { // If reset notifications have been requested, application must delete all contexts first - return Error(EGL_CONTEXT_LOST); + return EglContextLost(); } } - return mImplementation->restoreLostDevice(); + return mImplementation->restoreLostDevice(this); } -void Display::destroySurface(Surface *surface) +Error Display::destroySurface(Surface *surface) { if (surface->getType() == EGL_WINDOW_BIT) { @@ -774,54 +823,89 @@ void Display::destroySurface(Surface *surface) } ASSERT(surfaceRemoved); - UNUSED_ASSERTION_VARIABLE(surfaceRemoved); } - mImplementation->destroySurface(surface); + mState.surfaceSet.erase(surface); + ANGLE_TRY(surface->onDestroy(this)); + return NoError(); } void Display::destroyImage(egl::Image *image) { auto iter = mImageSet.find(image); ASSERT(iter != mImageSet.end()); - (*iter)->release(); + (*iter)->release(mProxyContext.get()); mImageSet.erase(iter); } -void Display::destroyContext(gl::Context *context) +void Display::destroyStream(egl::Stream *stream) { + mStreamSet.erase(stream); + SafeDelete(stream); +} + +Error Display::destroyContext(gl::Context *context) +{ + if (context->usingDisplayTextureShareGroup()) + { + ASSERT(mGlobalTextureShareGroupUsers >= 1 && mTextureManager != nullptr); + if (mGlobalTextureShareGroupUsers == 1) + { + // If this is the last context using the global share group, destroy the global texture + // manager so that the textures can be destroyed while a context still exists + mTextureManager->release(context); + mTextureManager = nullptr; + } + mGlobalTextureShareGroupUsers--; + } + + ANGLE_TRY(context->onDestroy(this)); mContextSet.erase(context); SafeDelete(context); + return NoError(); } bool Display::isDeviceLost() const { ASSERT(isInitialized()); - return mImplementation->isDeviceLost(); + return mDeviceLost; } bool Display::testDeviceLost() { ASSERT(isInitialized()); - return mImplementation->testDeviceLost(); + + if (!mDeviceLost && mImplementation->testDeviceLost()) + { + notifyDeviceLost(); + } + + return mDeviceLost; } void Display::notifyDeviceLost() { + if (mDeviceLost) + { + return; + } + for (ContextSet::iterator context = mContextSet.begin(); context != mContextSet.end(); context++) { (*context)->markContextLost(); } + + mDeviceLost = true; } -Error Display::waitClient() const +Error Display::waitClient(const gl::Context *context) const { - return mImplementation->waitClient(); + return mImplementation->waitClient(context); } -Error Display::waitNative(EGLint engine, egl::Surface *drawSurface, egl::Surface *readSurface) const +Error Display::waitNative(const gl::Context *context, EGLint engine) const { - return mImplementation->waitNative(engine, drawSurface, readSurface); + return mImplementation->waitNative(context, engine); } const Caps &Display::getCaps() const @@ -839,14 +923,14 @@ bool Display::isValidConfig(const Config *config) const return mConfigSet.contains(config); } -bool Display::isValidContext(gl::Context *context) const +bool Display::isValidContext(const gl::Context *context) const { - return mContextSet.find(context) != mContextSet.end(); + return mContextSet.find(const_cast(context)) != mContextSet.end(); } -bool Display::isValidSurface(Surface *surface) const +bool Display::isValidSurface(const Surface *surface) const { - return mImplementation->getSurfaceSet().find(surface) != mImplementation->getSurfaceSet().end(); + return mState.surfaceSet.find(const_cast(surface)) != mState.surfaceSet.end(); } bool Display::isValidImage(const Image *image) const @@ -854,6 +938,11 @@ bool Display::isValidImage(const Image *image) const return mImageSet.find(const_cast(image)) != mImageSet.end(); } +bool Display::isValidStream(const Stream *stream) const +{ + return mStreamSet.find(const_cast(stream)) != mStreamSet.end(); +} + bool Display::hasExistingWindowSurface(EGLNativeWindowType window) { WindowSurfaceMap *windowSurfaces = GetWindowSurfaces(); @@ -879,12 +968,20 @@ static ClientExtensions GenerateClientExtensions() extensions.platformANGLEOpenGL = true; #endif +#if defined(ANGLE_ENABLE_NULL) + extensions.platformANGLENULL = true; +#endif + #if defined(ANGLE_ENABLE_D3D11) extensions.deviceCreation = true; extensions.deviceCreationD3D11 = true; extensions.experimentalPresentPath = true; #endif +#if defined(ANGLE_ENABLE_VULKAN) + extensions.platformANGLEVulkan = true; +#endif + #if defined(ANGLE_USE_X11) extensions.x11Visual = true; #endif @@ -904,15 +1001,18 @@ static std::string GenerateExtensionsString(const T &extensions) return stream.str(); } -const ClientExtensions &Display::getClientExtensions() +// static +const ClientExtensions &Display::GetClientExtensions() { static const ClientExtensions clientExtensions = GenerateClientExtensions(); return clientExtensions; } -const std::string &Display::getClientExtensionString() +// static +const std::string &Display::GetClientExtensionString() { - static const std::string clientExtensionsString = GenerateExtensionsString(getClientExtensions()); + static const std::string clientExtensionsString = + GenerateExtensionsString(GetClientExtensions()); return clientExtensionsString; } @@ -920,9 +1020,20 @@ void Display::initDisplayExtensions() { mDisplayExtensions = mImplementation->getExtensions(); + // Some extensions are always available because they are implemented in the EGL layer. + mDisplayExtensions.createContext = true; + mDisplayExtensions.createContextNoError = true; + mDisplayExtensions.createContextWebGLCompatibility = true; + mDisplayExtensions.createContextBindGeneratesResource = true; + mDisplayExtensions.createContextClientArrays = true; + mDisplayExtensions.pixelFormatFloat = true; + // Force EGL_KHR_get_all_proc_addresses on. mDisplayExtensions.getAllProcAddresses = true; + // Enable program cache control since it is not back-end dependent. + mDisplayExtensions.programCacheControl = true; + mDisplayExtensionString = GenerateExtensionsString(mDisplayExtensions); } @@ -931,6 +1042,14 @@ bool Display::isValidNativeWindow(EGLNativeWindowType window) const return mImplementation->isValidNativeWindow(window); } +Error Display::validateClientBuffer(const Config *configuration, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const AttributeMap &attribs) +{ + return mImplementation->validateClientBuffer(configuration, buftype, clientBuffer, attribs); +} + bool Display::isValidDisplay(const egl::Display *display) { const ANGLEPlatformDisplayMap *anglePlatformDisplayMap = GetANGLEPlatformDisplayMap(); @@ -969,7 +1088,7 @@ bool Display::isValidNativeDisplay(EGLNativeDisplayType display) { return true; } - return (WindowFromDC(display) != NULL); + return (WindowFromDC(display) != nullptr); #else return true; #endif @@ -1000,4 +1119,105 @@ Device *Display::getDevice() const return mDevice; } +gl::Version Display::getMaxSupportedESVersion() const +{ + return mImplementation->getMaxSupportedESVersion(); } + +EGLint Display::programCacheGetAttrib(EGLenum attrib) const +{ + switch (attrib) + { + case EGL_PROGRAM_CACHE_KEY_LENGTH_ANGLE: + return static_cast(gl::kProgramHashLength); + + case EGL_PROGRAM_CACHE_SIZE_ANGLE: + return static_cast(mMemoryProgramCache.entryCount()); + + default: + UNREACHABLE(); + return 0; + } +} + +Error Display::programCacheQuery(EGLint index, + void *key, + EGLint *keysize, + void *binary, + EGLint *binarysize) +{ + ASSERT(index >= 0 && index < static_cast(mMemoryProgramCache.entryCount())); + + const angle::MemoryBuffer *programBinary = nullptr; + gl::ProgramHash programHash; + // TODO(jmadill): Make this thread-safe. + bool result = + mMemoryProgramCache.getAt(static_cast(index), &programHash, &programBinary); + if (!result) + { + return EglBadAccess() << "Program binary not accessible."; + } + + ASSERT(keysize && binarysize); + + if (key) + { + ASSERT(*keysize == static_cast(gl::kProgramHashLength)); + memcpy(key, programHash.data(), gl::kProgramHashLength); + } + + if (binary) + { + // Note: we check the size here instead of in the validation code, since we need to + // access the cache as atomically as possible. It's possible that the cache contents + // could change between the validation size check and the retrieval. + if (programBinary->size() > static_cast(*binarysize)) + { + return EglBadAccess() << "Program binary too large or changed during access."; + } + + memcpy(binary, programBinary->data(), programBinary->size()); + } + + *binarysize = static_cast(programBinary->size()); + *keysize = static_cast(gl::kProgramHashLength); + + return NoError(); +} + +Error Display::programCachePopulate(const void *key, + EGLint keysize, + const void *binary, + EGLint binarysize) +{ + ASSERT(keysize == static_cast(gl::kProgramHashLength)); + + gl::ProgramHash programHash; + memcpy(programHash.data(), key, gl::kProgramHashLength); + + mMemoryProgramCache.putBinary(programHash, reinterpret_cast(binary), + static_cast(binarysize)); + return NoError(); +} + +EGLint Display::programCacheResize(EGLint limit, EGLenum mode) +{ + switch (mode) + { + case EGL_PROGRAM_CACHE_RESIZE_ANGLE: + { + size_t initialSize = mMemoryProgramCache.size(); + mMemoryProgramCache.resize(static_cast(limit)); + return static_cast(initialSize); + } + + case EGL_PROGRAM_CACHE_TRIM_ANGLE: + return static_cast(mMemoryProgramCache.trim(static_cast(limit))); + + default: + UNREACHABLE(); + return 0; + } +} + +} // namespace egl diff --git a/src/3rdparty/angle/src/libANGLE/Display.h b/src/3rdparty/angle/src/libANGLE/Display.h index f80e308347..aa1d1c3b37 100644 --- a/src/3rdparty/angle/src/libANGLE/Display.h +++ b/src/3rdparty/angle/src/libANGLE/Display.h @@ -14,15 +14,18 @@ #include #include -#include "libANGLE/Error.h" +#include "libANGLE/AttributeMap.h" #include "libANGLE/Caps.h" #include "libANGLE/Config.h" -#include "libANGLE/AttributeMap.h" -#include "libANGLE/renderer/Renderer.h" +#include "libANGLE/Error.h" +#include "libANGLE/LoggingAnnotator.h" +#include "libANGLE/MemoryProgramCache.h" +#include "libANGLE/Version.h" namespace gl { class Context; +class TextureManager; } namespace rx @@ -35,6 +38,21 @@ namespace egl class Device; class Image; class Surface; +class Stream; +class Thread; + +using SurfaceSet = std::set; + +struct DisplayState final : private angle::NonCopyable +{ + DisplayState(); + ~DisplayState(); + + SurfaceSet surfaceSet; +}; + +// Constant coded here as a sanity limit. +constexpr EGLAttrib kProgramCacheSizeAbsoluteMax = 0x4000000; class Display final : angle::NonCopyable { @@ -42,48 +60,68 @@ class Display final : angle::NonCopyable ~Display(); Error initialize(); - void terminate(); + Error terminate(); - static egl::Display *GetDisplayFromDevice(void *native_display); - static egl::Display *GetDisplayFromAttribs(void *native_display, const AttributeMap &attribMap); + static Display *GetDisplayFromDevice(Device *device, const AttributeMap &attribMap); + static Display *GetDisplayFromNativeDisplay(EGLNativeDisplayType nativeDisplay, + const AttributeMap &attribMap); - static const ClientExtensions &getClientExtensions(); - static const std::string &getClientExtensionString(); + static const ClientExtensions &GetClientExtensions(); + static const std::string &GetClientExtensionString(); - std::vector getConfigs(const egl::AttributeMap &attribs) const; - bool getConfigAttrib(const Config *configuration, EGLint attribute, EGLint *value); + std::vector getConfigs(const AttributeMap &attribs) const; - Error createWindowSurface(const Config *configuration, EGLNativeWindowType window, const AttributeMap &attribs, + Error createWindowSurface(const Config *configuration, + EGLNativeWindowType window, + const AttributeMap &attribs, Surface **outSurface); - Error createPbufferSurface(const Config *configuration, const AttributeMap &attribs, Surface **outSurface); - Error createPbufferFromClientBuffer(const Config *configuration, EGLClientBuffer shareHandle, const AttributeMap &attribs, + Error createPbufferSurface(const Config *configuration, + const AttributeMap &attribs, + Surface **outSurface); + Error createPbufferFromClientBuffer(const Config *configuration, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const AttributeMap &attribs, Surface **outSurface); - Error createPixmapSurface(const Config *configuration, NativePixmapType nativePixmap, const AttributeMap &attribs, + Error createPixmapSurface(const Config *configuration, + NativePixmapType nativePixmap, + const AttributeMap &attribs, Surface **outSurface); - Error createImage(gl::Context *context, + Error createImage(const gl::Context *context, EGLenum target, EGLClientBuffer buffer, const AttributeMap &attribs, Image **outImage); - Error createContext(const Config *configuration, gl::Context *shareContext, const AttributeMap &attribs, + Error createStream(const AttributeMap &attribs, Stream **outStream); + + Error createContext(const Config *configuration, + gl::Context *shareContext, + const AttributeMap &attribs, gl::Context **outContext); - Error makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context); + Error makeCurrent(Surface *drawSurface, Surface *readSurface, gl::Context *context); - void destroySurface(egl::Surface *surface); - void destroyImage(egl::Image *image); - void destroyContext(gl::Context *context); + Error destroySurface(Surface *surface); + void destroyImage(Image *image); + void destroyStream(Stream *stream); + Error destroyContext(gl::Context *context); bool isInitialized() const; bool isValidConfig(const Config *config) const; - bool isValidContext(gl::Context *context) const; - bool isValidSurface(egl::Surface *surface) const; + bool isValidContext(const gl::Context *context) const; + bool isValidSurface(const Surface *surface) const; bool isValidImage(const Image *image) const; + bool isValidStream(const Stream *stream) const; bool isValidNativeWindow(EGLNativeWindowType window) const; - static bool isValidDisplay(const egl::Display *display); + Error validateClientBuffer(const Config *configuration, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const AttributeMap &attribs); + + static bool isValidDisplay(const Display *display); static bool isValidNativeDisplay(EGLNativeDisplayType display); static bool hasExistingWindowSurface(EGLNativeWindowType window); @@ -91,8 +129,8 @@ class Display final : angle::NonCopyable bool testDeviceLost(); void notifyDeviceLost(); - Error waitClient() const; - Error waitNative(EGLint engine, egl::Surface *drawSurface, egl::Surface *readSurface) const; + Error waitClient(const gl::Context *context) const; + Error waitNative(const gl::Context *context, EGLint engine) const; const Caps &getCaps() const; @@ -100,13 +138,31 @@ class Display final : angle::NonCopyable const std::string &getExtensionString() const; const std::string &getVendorString() const; + EGLint programCacheGetAttrib(EGLenum attrib) const; + Error programCacheQuery(EGLint index, + void *key, + EGLint *keysize, + void *binary, + EGLint *binarysize); + Error programCachePopulate(const void *key, + EGLint keysize, + const void *binary, + EGLint binarysize); + EGLint programCacheResize(EGLint limit, EGLenum mode); + const AttributeMap &getAttributeMap() const { return mAttributeMap; } EGLNativeDisplayType getNativeDisplayId() const { return mDisplayId; } - rx::DisplayImpl *getImplementation() { return mImplementation; } + rx::DisplayImpl *getImplementation() const { return mImplementation; } Device *getDevice() const; EGLenum getPlatform() const { return mPlatform; } + gl::Version getMaxSupportedESVersion() const; + + const DisplayState &getState() const { return mState; } + + gl::Context *getProxyContext() const { return mProxyContext.get(); } + private: Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDevice); @@ -117,6 +173,7 @@ class Display final : angle::NonCopyable void initDisplayExtensions(); void initVendorString(); + DisplayState mState; rx::DisplayImpl *mImplementation; EGLNativeDisplayType mDisplayId; @@ -130,7 +187,11 @@ class Display final : angle::NonCopyable typedef std::set ImageSet; ImageSet mImageSet; + typedef std::set StreamSet; + StreamSet mStreamSet; + bool mInitialized; + bool mDeviceLost; Caps mCaps; @@ -141,8 +202,17 @@ class Display final : angle::NonCopyable Device *mDevice; EGLenum mPlatform; + angle::LoggingAnnotator mAnnotator; + + gl::TextureManager *mTextureManager; + gl::MemoryProgramCache mMemoryProgramCache; + size_t mGlobalTextureShareGroupUsers; + + // This gl::Context is a simple proxy to the Display for the GL back-end entry points + // that need access to implementation-specific data, like a Renderer object. + angle::UniqueObjectPointer mProxyContext; }; -} +} // namespace egl #endif // LIBANGLE_DISPLAY_H_ diff --git a/src/3rdparty/angle/src/libANGLE/Error.cpp b/src/3rdparty/angle/src/libANGLE/Error.cpp index fed1594972..388f0259fa 100644 --- a/src/3rdparty/angle/src/libANGLE/Error.cpp +++ b/src/3rdparty/angle/src/libANGLE/Error.cpp @@ -10,35 +10,38 @@ #include "libANGLE/Error.h" #include "common/angleutils.h" +#include "common/debug.h" +#include "common/utilities.h" #include +namespace +{ +std::unique_ptr EmplaceErrorString(std::string &&message) +{ + return message.empty() ? std::unique_ptr() + : std::unique_ptr(new std::string(std::move(message))); +} +} // anonymous namespace + namespace gl { -Error::Error(GLenum errorCode, const char *msg, ...) : mCode(errorCode), mID(errorCode) +Error::Error(GLenum errorCode, std::string &&message) + : mCode(errorCode), mID(errorCode), mMessage(EmplaceErrorString(std::move(message))) { - va_list vararg; - va_start(vararg, msg); - createMessageString(); - *mMessage = FormatString(msg, vararg); - va_end(vararg); } -Error::Error(GLenum errorCode, GLuint id, const char *msg, ...) : mCode(errorCode), mID(id) +Error::Error(GLenum errorCode, GLuint id, std::string &&message) + : mCode(errorCode), mID(id), mMessage(EmplaceErrorString(std::move(message))) { - va_list vararg; - va_start(vararg, msg); - createMessageString(); - *mMessage = FormatString(msg, vararg); - va_end(vararg); } void Error::createMessageString() const { if (!mMessage) { - mMessage.reset(new std::string); + mMessage.reset(new std::string(GetGenericErrorMessage(mCode))); } } @@ -64,34 +67,32 @@ bool Error::operator!=(const Error &other) const { return !(*this == other); } + +std::ostream &operator<<(std::ostream &os, const Error &err) +{ + return gl::FmtHexShort(os, err.getCode()); } +} // namespace gl + namespace egl { -Error::Error(EGLint errorCode, const char *msg, ...) : mCode(errorCode), mID(0) +Error::Error(EGLint errorCode, std::string &&message) + : mCode(errorCode), mID(errorCode), mMessage(EmplaceErrorString(std::move(message))) { - va_list vararg; - va_start(vararg, msg); - createMessageString(); - *mMessage = FormatString(msg, vararg); - va_end(vararg); } -Error::Error(EGLint errorCode, EGLint id, const char *msg, ...) : mCode(errorCode), mID(id) +Error::Error(EGLint errorCode, EGLint id, std::string &&message) + : mCode(errorCode), mID(id), mMessage(EmplaceErrorString(std::move(message))) { - va_list vararg; - va_start(vararg, msg); - createMessageString(); - *mMessage = FormatString(msg, vararg); - va_end(vararg); } void Error::createMessageString() const { if (!mMessage) { - mMessage.reset(new std::string); + mMessage.reset(new std::string(GetGenericErrorMessage(mCode))); } } @@ -101,4 +102,9 @@ const std::string &Error::getMessage() const return *mMessage; } +std::ostream &operator<<(std::ostream &os, const Error &err) +{ + return gl::FmtHexShort(os, err.getCode()); } + +} // namespace egl diff --git a/src/3rdparty/angle/src/libANGLE/Error.h b/src/3rdparty/angle/src/libANGLE/Error.h index a5f760956a..1d57bb8707 100644 --- a/src/3rdparty/angle/src/libANGLE/Error.h +++ b/src/3rdparty/angle/src/libANGLE/Error.h @@ -9,23 +9,89 @@ #ifndef LIBANGLE_ERROR_H_ #define LIBANGLE_ERROR_H_ -#include "angle_gl.h" #include +#include +#include "angle_gl.h" +#include "common/angleutils.h" +#include "common/debug.h" -#include #include +#include +#include + +namespace angle +{ +template +class ANGLE_NO_DISCARD ErrorOrResultBase +{ + public: + ErrorOrResultBase(const ErrorT &error) : mError(error) {} + ErrorOrResultBase(ErrorT &&error) : mError(std::move(error)) {} + + ErrorOrResultBase(ResultT &&result) : mError(NoErrorVal), mResult(std::forward(result)) + { + } + + ErrorOrResultBase(const ResultT &result) : mError(NoErrorVal), mResult(result) {} + + bool isError() const { return mError.isError(); } + const ErrorT &getError() const { return mError; } + ResultT &&getResult() { return std::move(mResult); } + + private: + ErrorT mError; + ResultT mResult; +}; + +template +class ErrorStreamBase : angle::NonCopyable +{ + public: + ErrorStreamBase() : mID(EnumT) {} + ErrorStreamBase(GLuint id) : mID(id) {} + + template + ErrorStreamBase &operator<<(T value) + { + mErrorStream << value; + return *this; + } + + operator ErrorT() { return ErrorT(EnumT, mID, mErrorStream.str()); } + + template + operator ErrorOrResultBase() + { + return static_cast(*this); + } + + private: + GLuint mID; + std::ostringstream mErrorStream; +}; +} // namespace angle + +namespace egl +{ +class Error; +} // namespace egl namespace gl { -class Error final +class ANGLE_NO_DISCARD Error final { public: explicit inline Error(GLenum errorCode); - Error(GLenum errorCode, const char *msg, ...); - Error(GLenum errorCode, GLuint id, const char *msg, ...); + Error(GLenum errorCode, std::string &&message); + Error(GLenum errorCode, GLuint id, std::string &&message); inline Error(const Error &other); inline Error(Error &&other); + inline ~Error() = default; + + // automatic error type conversion + inline Error(egl::Error &&eglErr); + inline Error(egl::Error eglErr); inline Error &operator=(const Error &other); inline Error &operator=(Error &&other); @@ -43,40 +109,60 @@ class Error final private: void createMessageString() const; + friend std::ostream &operator<<(std::ostream &os, const Error &err); + friend class egl::Error; + GLenum mCode; GLuint mID; mutable std::unique_ptr mMessage; }; -template -class ErrorOrResult +template +using ErrorOrResult = angle::ErrorOrResultBase; + +namespace priv { - public: - ErrorOrResult(const gl::Error &error) : mError(error) {} - ErrorOrResult(T &&result) : mError(GL_NO_ERROR), mResult(std::move(result)) {} - bool isError() const { return mError.isError(); } - const gl::Error &getError() const { return mError; } - T &&getResult() { return std::move(mResult); } +template +using ErrorStream = angle::ErrorStreamBase; - private: - Error mError; - T mResult; -}; +} // namespace priv + +using InternalError = priv::ErrorStream; + +using InvalidEnum = priv::ErrorStream; +using InvalidValue = priv::ErrorStream; +using InvalidOperation = priv::ErrorStream; +using StackOverflow = priv::ErrorStream; +using StackUnderflow = priv::ErrorStream; +using OutOfMemory = priv::ErrorStream; +using InvalidFramebufferOperation = priv::ErrorStream; + +inline Error NoError() +{ + return Error(GL_NO_ERROR); +} + +using LinkResult = ErrorOrResult; } // namespace gl namespace egl { -class Error final +class ANGLE_NO_DISCARD Error final { public: explicit inline Error(EGLint errorCode); - Error(EGLint errorCode, const char *msg, ...); - Error(EGLint errorCode, EGLint id, const char *msg, ...); + Error(EGLint errorCode, std::string &&message); + Error(EGLint errorCode, EGLint id, std::string &&message); inline Error(const Error &other); inline Error(Error &&other); + inline ~Error() = default; + + // automatic error type conversion + inline Error(gl::Error &&glErr); + inline Error(gl::Error glErr); inline Error &operator=(const Error &other); inline Error &operator=(Error &&other); @@ -90,13 +176,92 @@ class Error final private: void createMessageString() const; + friend std::ostream &operator<<(std::ostream &os, const Error &err); + friend class gl::Error; + EGLint mCode; EGLint mID; mutable std::unique_ptr mMessage; }; +template +using ErrorOrResult = angle::ErrorOrResultBase; + +namespace priv +{ + +template +using ErrorStream = angle::ErrorStreamBase; + +} // namespace priv + +using EglNotInitialized = priv::ErrorStream; +using EglBadAccess = priv::ErrorStream; +using EglBadAlloc = priv::ErrorStream; +using EglBadAttribute = priv::ErrorStream; +using EglBadConfig = priv::ErrorStream; +using EglBadContext = priv::ErrorStream; +using EglBadCurrentSurface = priv::ErrorStream; +using EglBadDisplay = priv::ErrorStream; +using EglBadMatch = priv::ErrorStream; +using EglBadNativeWindow = priv::ErrorStream; +using EglBadParameter = priv::ErrorStream; +using EglBadSurface = priv::ErrorStream; +using EglContextLost = priv::ErrorStream; +using EglBadStream = priv::ErrorStream; +using EglBadState = priv::ErrorStream; +using EglBadDevice = priv::ErrorStream; + +inline Error NoError() +{ + return Error(EGL_SUCCESS); +} + } // namespace egl +#define ANGLE_CONCAT1(x, y) x##y +#define ANGLE_CONCAT2(x, y) ANGLE_CONCAT1(x, y) +#define ANGLE_LOCAL_VAR ANGLE_CONCAT2(_localVar, __LINE__) + +#define ANGLE_TRY_TEMPLATE(EXPR, FUNC) \ + { \ + auto ANGLE_LOCAL_VAR = EXPR; \ + if (ANGLE_LOCAL_VAR.isError()) \ + { \ + FUNC(ANGLE_LOCAL_VAR); \ + } \ + } \ + ANGLE_EMPTY_STATEMENT + +#define ANGLE_RETURN(X) return X; +#define ANGLE_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_RETURN); + +#define ANGLE_TRY_RESULT(EXPR, RESULT) \ + { \ + auto ANGLE_LOCAL_VAR = EXPR; \ + if (ANGLE_LOCAL_VAR.isError()) \ + { \ + return ANGLE_LOCAL_VAR.getError(); \ + } \ + RESULT = ANGLE_LOCAL_VAR.getResult(); \ + } \ + ANGLE_EMPTY_STATEMENT + +// TODO(jmadill): Introduce way to store errors to a const Context. +#define ANGLE_SWALLOW_ERR(EXPR) \ + { \ + auto ANGLE_LOCAL_VAR = EXPR; \ + if (ANGLE_LOCAL_VAR.isError()) \ + { \ + ERR() << "Unhandled internal error: " << ANGLE_LOCAL_VAR; \ + } \ + } \ + ANGLE_EMPTY_STATEMENT + +#undef ANGLE_LOCAL_VAR +#undef ANGLE_CONCAT2 +#undef ANGLE_CONCAT1 + #include "Error.inl" #endif // LIBANGLE_ERROR_H_ diff --git a/src/3rdparty/angle/src/libANGLE/Error.inl b/src/3rdparty/angle/src/libANGLE/Error.inl index 900fc5fd03..4632830ce0 100644 --- a/src/3rdparty/angle/src/libANGLE/Error.inl +++ b/src/3rdparty/angle/src/libANGLE/Error.inl @@ -37,6 +37,21 @@ Error::Error(Error &&other) { } +// automatic error type conversion +Error::Error(egl::Error &&eglErr) + : mCode(GL_INVALID_OPERATION), + mID(0), + mMessage(std::move(eglErr.mMessage)) +{ +} + +Error::Error(egl::Error eglErr) + : mCode(GL_INVALID_OPERATION), + mID(0), + mMessage(std::move(eglErr.mMessage)) +{ +} + Error &Error::operator=(const Error &other) { mCode = other.mCode; @@ -82,7 +97,7 @@ bool Error::isError() const return (mCode != GL_NO_ERROR); } -} +} // namespace gl namespace egl { @@ -111,6 +126,21 @@ Error::Error(Error &&other) { } +// automatic error type conversion +Error::Error(gl::Error &&glErr) + : mCode(EGL_BAD_ACCESS), + mID(0), + mMessage(std::move(glErr.mMessage)) +{ +} + +Error::Error(gl::Error glErr) + : mCode(EGL_BAD_ACCESS), + mID(0), + mMessage(std::move(glErr.mMessage)) +{ +} + Error &Error::operator=(const Error &other) { mCode = other.mCode; diff --git a/src/3rdparty/angle/src/libANGLE/ErrorStrings.h b/src/3rdparty/angle/src/libANGLE/ErrorStrings.h new file mode 100644 index 0000000000..93d64482d9 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/ErrorStrings.h @@ -0,0 +1,173 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ErrorStrings.h: Contains mapping of commonly used error messages + +#ifndef LIBANGLE_ERRORSTRINGS_H_ +#define LIBANGLE_ERRORSTRINGS_H_ + +#define ERRMSG(name, message) \ + static const constexpr char *kError##name = static_cast(message); +#define ANGLE_VALIDATION_ERR(context, error, errorName) \ + context->handleError(error << kError##errorName) + +namespace gl +{ +ERRMSG(BufferNotBound, "A buffer must be bound."); +ERRMSG(CompressedTextureDimensionsMustMatchData, + "Compressed texture dimensions must exactly match the dimensions of the data passed in."); +ERRMSG(CompressedTexturesNotAttachable, "Compressed textures cannot be attached to a framebuffer."); +ERRMSG(CubemapFacesEqualDimensions, "Each cubemap face must have equal width and height."); +ERRMSG(CubemapIncomplete, + "Texture is not cubemap complete. All cubemaps faces must be defined and be the same size."); +ERRMSG(DefaultFramebufferInvalidAttachment, + "Invalid attachment when the default framebuffer is bound."); +ERRMSG(DefaultFramebufferTarget, "It is invalid to change default FBO's attachments"); +ERRMSG(EnumNotSupported, "Enum is not currently supported."); +ERRMSG(EnumRequiresGLES31, "Enum requires GLES 3.1"); +ERRMSG(ES31Required, "OpenGL ES 3.1 Required"); +ERRMSG(ES3Required, "OpenGL ES 3.0 Required."); +ERRMSG(ExceedsMaxElement, "Element value exceeds maximum element index."); +ERRMSG(ExpectedProgramName, "Expected a program name, but found a shader name."); +ERRMSG(ExpectedShaderName, "Expected a shader name, but found a program name."); +ERRMSG(ExtensionNotEnabled, "Extension is not enabled."); +ERRMSG(FeedbackLoop, "Feedback loop formed between Framebuffer and active Texture."); +ERRMSG(FramebufferIncompleteAttachment, + "Attachment type must be compatible with attachment object."); +ERRMSG(GenerateMipmapNotAllowed, "Texture format does not support mipmap generation."); +ERRMSG(IndexExceedsMaxActiveUniform, "Index exceeds program active uniform count."); +ERRMSG(IndexExceedsMaxDrawBuffer, "Index exceeds MAX_DRAW_BUFFERS."); +ERRMSG(IndexExceedsMaxVertexAttribute, "Index exceeds MAX_VERTEX_ATTRIBS."); +ERRMSG(InsufficientBufferSize, "Insufficient buffer size."); +ERRMSG(InsufficientVertexBufferSize, "Vertex buffer is not big enough for the draw call"); +ERRMSG(IntegerOverflow, "Integer overflow."); +ERRMSG(InvalidAttachment, "Invalid Attachment Type."); +ERRMSG(InvalidBlendEquation, "Invalid blend equation."); +ERRMSG(InvalidBlendFunction, "Invalid blend function."); +ERRMSG(InvalidBorder, "Border must be 0."); +ERRMSG(InvalidBufferTypes, "Invalid buffer target enum."); +ERRMSG(InvalidBufferUsage, "Invalid buffer usage enum."); +ERRMSG(InvalidClearMask, "Invalid mask bits."); +ERRMSG(InvalidConstantColor, + "CONSTANT_COLOR (or ONE_MINUS_CONSTANT_COLOR) and CONSTANT_ALPHA (or " + "ONE_MINUS_CONSTANT_ALPHA) cannot be used together as source and destination factors in the " + "blend function."); +ERRMSG(InvalidCoverMode, "Invalid cover mode."); +ERRMSG(InvalidCullMode, "Cull mode not recognized."); +ERRMSG(InvalidDebugSeverity, "Invalid debug severity."); +ERRMSG(InvalidDebugSource, "Invalid debug source."); +ERRMSG(InvalidDebugType, "Invalid debug type."); +ERRMSG(InvalidDepthRange, "Near value cannot be greater than far."); +ERRMSG(InvalidDrawMode, "Invalid draw mode."); +ERRMSG(InvalidDrawModeTransformFeedback, + "Draw mode must match current transform feedback object's draw mode."); +ERRMSG(InvalidFillMode, "Invalid fill mode."); +ERRMSG(InvalidFilterTexture, "Texture only supports NEAREST and LINEAR filtering."); +ERRMSG(InvalidFormat, "Invalid format."); +ERRMSG(InvalidFramebufferTarget, "Invalid framebuffer target."); +ERRMSG(InvalidFramebufferTextureLevel, "Mipmap level must be 0 when attaching a texture."); +ERRMSG(InvalidFramebufferAttachmentParameter, "Invalid parameter name for framebuffer attachment."); +ERRMSG(InvalidInternalFormat, "Invalid internal format."); +ERRMSG(InvalidMatrixMode, "Invalid matrix mode."); +ERRMSG(InvalidMipLevel, "Level of detail outside of range."); +ERRMSG(InvalidName, "Invalid name."); +ERRMSG(InvalidNameCharacters, "Name contains invalid characters."); +ERRMSG(InvalidPname, "Invalid pname."); +ERRMSG(InvalidPrecision, "Invalid or unsupported precision type."); +ERRMSG(InvalidProgramName, "Program object expected."); +ERRMSG(InvalidQueryId, "Invalid query Id."); +ERRMSG(InvalidQueryTarget, "Invalid query target."); +ERRMSG(InvalidQueryType, "Invalid query type."); +ERRMSG(InvalidRange, "Invalid range."); +ERRMSG(InvalidRenderbufferInternalFormat, "Invalid renderbuffer internalformat."); +ERRMSG(InvalidRenderbufferTarget, "Invalid renderbuffer target."); +ERRMSG(InvalidRenderbufferTextureParameter, "Invalid parameter name for renderbuffer attachment."); +ERRMSG(InvalidRenderbufferWidthHeight, + "Renderbuffer width and height cannot be negative and cannot exceed maximum texture size."); +ERRMSG(InvalidSampleMaskNumber, + "MaskNumber cannot be greater than or equal to the value of MAX_SAMPLE_MASK_WORDS."); +ERRMSG(InvalidSampler, "Sampler is not valid"); +ERRMSG(InvalidShaderName, "Shader object expected."); +ERRMSG(InvalidShaderType, "Invalid shader type."); +ERRMSG(InvalidStencil, "Invalid stencil."); +ERRMSG(InvalidStencilBitMask, "Invalid stencil bit mask."); +ERRMSG(InvalidTarget, "Invalid target."); +ERRMSG(InvalidTextureFilterParam, "Texture filter not recognized."); +ERRMSG(InvalidTextureRange, "Cannot be less than 0 or greater than maximum number of textures."); +ERRMSG(InvalidTextureTarget, "Invalid or unsupported texture target."); +ERRMSG(InvalidTextureWrap, "Texture wrap mode not recognized."); +ERRMSG(InvalidType, "Invalid type."); +ERRMSG(InvalidTypePureInt, "Invalid type, should be integer"); +ERRMSG(InvalidUnpackAlignment, "Unpack alignment must be 1, 2, 4, or 8."); +ERRMSG(InvalidVertexAttrSize, "Vertex attribute size must be 1, 2, 3, or 4."); +ERRMSG(InvalidWidth, "Invalid width."); +ERRMSG(InvalidWrapModeTexture, "Invalid wrap mode for texture type."); +ERRMSG(LevelNotZero, "Texture level must be zero."); +ERRMSG(MismatchedByteCountType, "Buffer size does not align with data type."); +ERRMSG(MismatchedFormat, "Format must match internal format."); +ERRMSG(MismatchedTargetAndFormat, "Invalid texture target and format combination."); +ERRMSG(MismatchedTypeAndFormat, "Invalid format and type combination."); +ERRMSG(MismatchedVariableProgram, "Variable is not part of the current program."); +ERRMSG(MissingReadAttachment, "Missing read attachment."); +ERRMSG(MustHaveElementArrayBinding, "Must have element array buffer binding."); +ERRMSG(NameBeginsWithGL, "Attributes that begin with 'gl_' are not allowed."); +ERRMSG(NegativeAttachments, "Negative number of attachments."); +ERRMSG(NegativeBufferSize, "Negative buffer size."); +ERRMSG(NegativeCount, "Negative count."); +ERRMSG(NegativeLength, "Negative length."); +ERRMSG(NegativeMaxCount, "Negative maxcount."); +ERRMSG(NegativeOffset, "Negative offset."); +ERRMSG(NegativePrimcount, "Primcount must be greater than or equal to zero."); +ERRMSG(NegativeSize, "Cannot have negative height or width."); +ERRMSG(NegativeStart, "Cannot have negative start."); +ERRMSG(NegativeStride, "Cannot have negative stride."); +ERRMSG(NoSuchPath, "No such path object."); +ERRMSG(NoTransformFeedbackOutputVariables, + "The active program has specified no output variables to record."); +ERRMSG(NoZeroDivisor, "At least one enabled attribute must have a divisor of zero."); +ERRMSG(ObjectNotGenerated, "Object cannot be used because it has not been generated."); +ERRMSG(OffsetMustBeMultipleOfType, "Offset must be a multiple of the passed in datatype."); +ERRMSG(OutsideOfBounds, "Parameter outside of bounds."); +ERRMSG(ParamOverflow, "The provided parameters overflow with the provided buffer."); +ERRMSG(PixelDataNotNull, "Pixel data must be null."); +ERRMSG(PixelDataNull, "Pixel data cannot be null."); +ERRMSG(ProgramDoesNotExist, "Program doesn't exist."); +ERRMSG(ProgramNotBound, "A program must be bound."); +ERRMSG(ProgramNotLinked, "Program not linked."); +ERRMSG(QueryActive, "Query is active."); +ERRMSG(QueryExtensionNotEnabled, "Query extension not enabled."); +ERRMSG(ReadBufferNone, "Read buffer is GL_NONE."); +ERRMSG(RenderbufferNotBound, "A renderbuffer must be bound."); +ERRMSG(ResourceMaxTextureSize, "Desired resource size is greater than max texture size."); +ERRMSG(ShaderAttachmentHasShader, "Shader attachment already has a shader."); +ERRMSG(ShaderSourceInvalidCharacters, "Shader source contains invalid characters."); +ERRMSG(ShaderToDetachMustBeAttached, + "Shader to be detached must be currently attached to the program."); +ERRMSG(SourceTextureTooSmall, "The specified dimensions are outside of the bounds of the texture."); +ERRMSG(StencilReferenceMaskOrMismatch, + "Stencil reference and mask values must be the same for front facing and back facing " + "triangles."); +ERRMSG(StrideMustBeMultipleOfType, "Stride must be a multiple of the passed in datatype."); +ERRMSG(TextureNotBound, "A texture must be bound."); +ERRMSG(TextureNotPow2, "The texture is a non-power-of-two texture."); +ERRMSG(TransformFeedbackDoesNotExist, "Transform feedback object that does not exist."); +ERRMSG(TypeMismatch, + "Passed in texture target and format must match the one originally used to define the " + "texture."); +ERRMSG(TypeNotUnsignedShortByte, "Only UNSIGNED_SHORT and UNSIGNED_BYTE types are supported."); +ERRMSG(UniformSizeMismatch, "Uniform size does not match uniform method."); +ERRMSG(UnknownParameter, "Unknown parameter value."); +ERRMSG(VertexArrayNoBuffer, "An enabled vertex array has no buffer."); +ERRMSG(VertexArrayNoBufferPointer, "An enabled vertex array has no buffer and no pointer."); +ERRMSG(ViewportNegativeSize, "Viewport size cannot be negative."); +ERRMSG(Webgl2NameLengthLimitExceeded, "Location lengths must not be greater than 1024 characters."); +ERRMSG(WebglBindAttribLocationReservedPrefix, + "Attributes that begin with 'webgl_', or '_webgl_' are not allowed."); +ERRMSG(WebglNameLengthLimitExceeded, + "Location name lengths must not be greater than 256 characters."); +} +#undef ERRMSG +#endif // LIBANGLE_ERRORSTRINGS_H_ diff --git a/src/3rdparty/angle/src/libANGLE/Fence.cpp b/src/3rdparty/angle/src/libANGLE/Fence.cpp index ff32f4bbe9..9c4d381673 100644 --- a/src/3rdparty/angle/src/libANGLE/Fence.cpp +++ b/src/3rdparty/angle/src/libANGLE/Fence.cpp @@ -4,18 +4,17 @@ // found in the LICENSE file. // -// Fence.cpp: Implements the gl::FenceNV and gl::FenceSync classes, which support the GL_NV_fence +// Fence.cpp: Implements the gl::FenceNV and gl::Sync classes, which support the GL_NV_fence // extension and GLES3 sync objects. #include "libANGLE/Fence.h" -#include "libANGLE/renderer/FenceNVImpl.h" -#include "libANGLE/renderer/FenceSyncImpl.h" -#include "libANGLE/renderer/Renderer.h" -#include "common/utilities.h" - #include "angle_gl.h" +#include "common/utilities.h" +#include "libANGLE/renderer/FenceNVImpl.h" +#include "libANGLE/renderer/SyncImpl.h" + namespace gl { @@ -44,7 +43,7 @@ Error FenceNV::set(GLenum condition) mStatus = GL_FALSE; mIsSet = true; - return Error(GL_NO_ERROR); + return NoError(); } Error FenceNV::test(GLboolean *outResult) @@ -57,7 +56,7 @@ Error FenceNV::test(GLboolean *outResult) } *outResult = mStatus; - return Error(GL_NO_ERROR); + return NoError(); } Error FenceNV::finish() @@ -72,30 +71,39 @@ Error FenceNV::finish() mStatus = GL_TRUE; - return Error(GL_NO_ERROR); + return NoError(); } -FenceSync::FenceSync(rx::FenceSyncImpl *impl, GLuint id) - : RefCountObject(id), mFence(impl), mLabel(), mCondition(GL_NONE), mFlags(0) +Sync::Sync(rx::SyncImpl *impl, GLuint id) + : RefCountObject(id), + mFence(impl), + mLabel(), + mCondition(GL_SYNC_GPU_COMMANDS_COMPLETE), + mFlags(0) { } -FenceSync::~FenceSync() +Error Sync::onDestroy(const Context *context) +{ + return NoError(); +} + +Sync::~Sync() { SafeDelete(mFence); } -void FenceSync::setLabel(const std::string &label) +void Sync::setLabel(const std::string &label) { mLabel = label; } -const std::string &FenceSync::getLabel() const +const std::string &Sync::getLabel() const { return mLabel; } -Error FenceSync::set(GLenum condition, GLbitfield flags) +Error Sync::set(GLenum condition, GLbitfield flags) { Error error = mFence->set(condition, flags); if (error.isError()) @@ -105,23 +113,23 @@ Error FenceSync::set(GLenum condition, GLbitfield flags) mCondition = condition; mFlags = flags; - return Error(GL_NO_ERROR); + return NoError(); } -Error FenceSync::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult) +Error Sync::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult) { ASSERT(mCondition != GL_NONE); return mFence->clientWait(flags, timeout, outResult); } -Error FenceSync::serverWait(GLbitfield flags, GLuint64 timeout) +Error Sync::serverWait(GLbitfield flags, GLuint64 timeout) { return mFence->serverWait(flags, timeout); } -Error FenceSync::getStatus(GLint *outResult) const +Error Sync::getStatus(GLint *outResult) const { return mFence->getStatus(outResult); } -} +} // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/Fence.h b/src/3rdparty/angle/src/libANGLE/Fence.h index b2daed6f0e..24bc689ca3 100644 --- a/src/3rdparty/angle/src/libANGLE/Fence.h +++ b/src/3rdparty/angle/src/libANGLE/Fence.h @@ -4,7 +4,7 @@ // found in the LICENSE file. // -// Fence.h: Defines the gl::FenceNV and gl::FenceSync classes, which support the GL_NV_fence +// Fence.h: Defines the gl::FenceNV and gl::Sync classes, which support the GL_NV_fence // extension and GLES3 sync objects. #ifndef LIBANGLE_FENCE_H_ @@ -19,7 +19,7 @@ namespace rx { class FenceNVImpl; -class FenceSyncImpl; +class SyncImpl; } namespace gl @@ -48,11 +48,13 @@ class FenceNV final : angle::NonCopyable GLenum mCondition; }; -class FenceSync final : public RefCountObject, public LabeledObject +class Sync final : public RefCountObject, public LabeledObject { public: - FenceSync(rx::FenceSyncImpl *impl, GLuint id); - virtual ~FenceSync(); + Sync(rx::SyncImpl *impl, GLuint id); + ~Sync() override; + + Error onDestroy(const Context *context) override; void setLabel(const std::string &label) override; const std::string &getLabel() const override; @@ -66,7 +68,7 @@ class FenceSync final : public RefCountObject, public LabeledObject GLbitfield getFlags() const { return mFlags; } private: - rx::FenceSyncImpl *mFence; + rx::SyncImpl *mFence; std::string mLabel; @@ -74,6 +76,6 @@ class FenceSync final : public RefCountObject, public LabeledObject GLbitfield mFlags; }; -} +} // namespace gl #endif // LIBANGLE_FENCE_H_ diff --git a/src/3rdparty/angle/src/libANGLE/Framebuffer.cpp b/src/3rdparty/angle/src/libANGLE/Framebuffer.cpp index 3def57b87e..48e71685b3 100644 --- a/src/3rdparty/angle/src/libANGLE/Framebuffer.cpp +++ b/src/3rdparty/angle/src/libANGLE/Framebuffer.cpp @@ -10,72 +10,349 @@ #include "libANGLE/Framebuffer.h" #include "common/Optional.h" +#include "common/bitset_utils.h" #include "common/utilities.h" #include "libANGLE/Config.h" #include "libANGLE/Context.h" +#include "libANGLE/Display.h" #include "libANGLE/FramebufferAttachment.h" #include "libANGLE/Renderbuffer.h" #include "libANGLE/Surface.h" #include "libANGLE/Texture.h" #include "libANGLE/formatutils.h" +#include "libANGLE/renderer/ContextImpl.h" #include "libANGLE/renderer/FramebufferImpl.h" -#include "libANGLE/renderer/ImplFactory.h" +#include "libANGLE/renderer/GLImplFactory.h" #include "libANGLE/renderer/RenderbufferImpl.h" #include "libANGLE/renderer/SurfaceImpl.h" +using namespace angle; + namespace gl { namespace { -void DetachMatchingAttachment(FramebufferAttachment *attachment, GLenum matchType, GLuint matchId) + +void BindResourceChannel(OnAttachmentDirtyBinding *binding, FramebufferAttachmentObject *resource) { - if (attachment->isAttached() && - attachment->type() == matchType && - attachment->id() == matchId) + binding->bind(resource ? resource->getDirtyChannel() : nullptr); +} + +bool CheckMultiviewStateMatchesForCompleteness(const FramebufferAttachment *firstAttachment, + const FramebufferAttachment *secondAttachment) +{ + ASSERT(firstAttachment && secondAttachment); + ASSERT(firstAttachment->isAttached() && secondAttachment->isAttached()); + + if (firstAttachment->getNumViews() != secondAttachment->getNumViews()) { - attachment->detach(); + return false; + } + if (firstAttachment->getBaseViewIndex() != secondAttachment->getBaseViewIndex()) + { + return false; + } + if (firstAttachment->getMultiviewLayout() != secondAttachment->getMultiviewLayout()) + { + return false; + } + if (firstAttachment->getMultiviewViewportOffsets() != + secondAttachment->getMultiviewViewportOffsets()) + { + return false; + } + return true; +} + +bool CheckAttachmentCompleteness(const Context *context, const FramebufferAttachment &attachment) +{ + ASSERT(attachment.isAttached()); + + const Extents &size = attachment.getSize(); + if (size.width == 0 || size.height == 0) + { + return false; + } + + const InternalFormat &format = *attachment.getFormat().info; + if (!format.renderSupport(context->getClientVersion(), context->getExtensions())) + { + return false; + } + + if (attachment.type() == GL_TEXTURE) + { + if (attachment.layer() >= size.depth) + { + return false; + } + + // ES3 specifies that cube map texture attachments must be cube complete. + // This language is missing from the ES2 spec, but we enforce it here because some + // desktop OpenGL drivers also enforce this validation. + // TODO(jmadill): Check if OpenGL ES2 drivers enforce cube completeness. + const Texture *texture = attachment.getTexture(); + ASSERT(texture); + if (texture->getTarget() == GL_TEXTURE_CUBE_MAP && + !texture->getTextureState().isCubeComplete()) + { + return false; + } + + if (!texture->getImmutableFormat()) + { + GLuint attachmentMipLevel = static_cast(attachment.mipLevel()); + + // From the ES 3.0 spec, pg 213: + // If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is TEXTURE and the value of + // FRAMEBUFFER_ATTACHMENT_OBJECT_NAME does not name an immutable-format texture, + // then the value of FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL must be in the + // range[levelbase, q], where levelbase is the value of TEXTURE_BASE_LEVEL and q is + // the effective maximum texture level defined in the Mipmapping discussion of + // section 3.8.10.4. + if (attachmentMipLevel < texture->getBaseLevel() || + attachmentMipLevel > texture->getMipmapMaxLevel()) + { + return false; + } + + // Form the ES 3.0 spec, pg 213/214: + // If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is TEXTURE and the value of + // FRAMEBUFFER_ATTACHMENT_OBJECT_NAME does not name an immutable-format texture and + // the value of FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL is not levelbase, then the + // texture must be mipmap complete, and if FRAMEBUFFER_ATTACHMENT_OBJECT_NAME names + // a cubemap texture, the texture must also be cube complete. + if (attachmentMipLevel != texture->getBaseLevel() && !texture->isMipmapComplete()) + { + return false; + } + } + } + + return true; +}; + +bool CheckAttachmentSampleCompleteness(const Context *context, + const FramebufferAttachment &attachment, + bool colorAttachment, + Optional *samples, + Optional *fixedSampleLocations) +{ + ASSERT(attachment.isAttached()); + + if (attachment.type() == GL_TEXTURE) + { + const Texture *texture = attachment.getTexture(); + ASSERT(texture); + + const ImageIndex &attachmentImageIndex = attachment.getTextureImageIndex(); + + // ES3.1 (section 9.4) requires that the value of TEXTURE_FIXED_SAMPLE_LOCATIONS should be + // the same for all attached textures. + bool fixedSampleloc = texture->getFixedSampleLocations(attachmentImageIndex.type, + attachmentImageIndex.mipIndex); + if (fixedSampleLocations->valid() && fixedSampleloc != fixedSampleLocations->value()) + { + return false; + } + else + { + *fixedSampleLocations = fixedSampleloc; + } + } + + if (samples->valid()) + { + if (attachment.getSamples() != samples->value()) + { + if (colorAttachment) + { + // APPLE_framebuffer_multisample, which EXT_draw_buffers refers to, requires that + // all color attachments have the same number of samples for the FBO to be complete. + return false; + } + else + { + // CHROMIUM_framebuffer_mixed_samples allows a framebuffer to be considered complete + // when its depth or stencil samples are a multiple of the number of color samples. + if (!context->getExtensions().framebufferMixedSamples) + { + return false; + } + + if ((attachment.getSamples() % std::max(samples->value(), 1)) != 0) + { + return false; + } + } + } + } + else + { + *samples = attachment.getSamples(); + } + + return true; +} + +// Needed to index into the attachment arrays/bitsets. +static_assert(static_cast(IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS) == + gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX, + "Framebuffer Dirty bit mismatch"); +static_assert(static_cast(IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS) == + gl::Framebuffer::DIRTY_BIT_DEPTH_ATTACHMENT, + "Framebuffer Dirty bit mismatch"); +static_assert(static_cast(IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS + 1) == + gl::Framebuffer::DIRTY_BIT_STENCIL_ATTACHMENT, + "Framebuffer Dirty bit mismatch"); + +Error InitAttachment(const Context *context, FramebufferAttachment *attachment) +{ + ASSERT(attachment->isAttached()); + if (attachment->initState() == InitState::MayNeedInit) + { + ANGLE_TRY(attachment->initializeContents(context)); + } + return NoError(); +} + +bool IsColorMaskedOut(const BlendState &blend) +{ + return (!blend.colorMaskRed && !blend.colorMaskGreen && !blend.colorMaskBlue && + !blend.colorMaskAlpha); +} + +bool IsDepthMaskedOut(const DepthStencilState &depthStencil) +{ + return !depthStencil.depthMask; +} + +bool IsStencilMaskedOut(const DepthStencilState &depthStencil) +{ + return ((depthStencil.stencilMask & depthStencil.stencilWritemask) == 0); +} + +bool IsClearBufferMaskedOut(const Context *context, GLenum buffer) +{ + switch (buffer) + { + case GL_COLOR: + return IsColorMaskedOut(context->getGLState().getBlendState()); + case GL_DEPTH: + return IsDepthMaskedOut(context->getGLState().getDepthStencilState()); + case GL_STENCIL: + return IsStencilMaskedOut(context->getGLState().getDepthStencilState()); + case GL_DEPTH_STENCIL: + return IsDepthMaskedOut(context->getGLState().getDepthStencilState()) && + IsStencilMaskedOut(context->getGLState().getDepthStencilState()); + default: + UNREACHABLE(); + return true; } } -} -Framebuffer::Data::Data() +} // anonymous namespace + +// This constructor is only used for default framebuffers. +FramebufferState::FramebufferState() : mLabel(), mColorAttachments(1), - mDrawBufferStates(1, GL_NONE), - mReadBufferState(GL_COLOR_ATTACHMENT0_EXT) + mDrawBufferStates(1, GL_BACK), + mReadBufferState(GL_BACK), + mDefaultWidth(0), + mDefaultHeight(0), + mDefaultSamples(0), + mDefaultFixedSampleLocations(GL_FALSE), + mWebGLDepthStencilConsistent(true) { - mDrawBufferStates[0] = GL_COLOR_ATTACHMENT0_EXT; + ASSERT(mDrawBufferStates.size() > 0); + mEnabledDrawBuffers.set(0); } -Framebuffer::Data::Data(const Caps &caps) +FramebufferState::FramebufferState(const Caps &caps) : mLabel(), mColorAttachments(caps.maxColorAttachments), mDrawBufferStates(caps.maxDrawBuffers, GL_NONE), - mReadBufferState(GL_COLOR_ATTACHMENT0_EXT) + mReadBufferState(GL_COLOR_ATTACHMENT0_EXT), + mDefaultWidth(0), + mDefaultHeight(0), + mDefaultSamples(0), + mDefaultFixedSampleLocations(GL_FALSE), + mWebGLDepthStencilConsistent(true) { ASSERT(mDrawBufferStates.size() > 0); mDrawBufferStates[0] = GL_COLOR_ATTACHMENT0_EXT; } -Framebuffer::Data::~Data() +FramebufferState::~FramebufferState() { } -const std::string &Framebuffer::Data::getLabel() +const std::string &FramebufferState::getLabel() { return mLabel; } -const FramebufferAttachment *Framebuffer::Data::getReadAttachment() const +const FramebufferAttachment *FramebufferState::getAttachment(GLenum attachment) const { - ASSERT(mReadBufferState == GL_BACK || (mReadBufferState >= GL_COLOR_ATTACHMENT0 && mReadBufferState <= GL_COLOR_ATTACHMENT15)); - size_t readIndex = (mReadBufferState == GL_BACK ? 0 : static_cast(mReadBufferState - GL_COLOR_ATTACHMENT0)); + if (attachment >= GL_COLOR_ATTACHMENT0 && attachment <= GL_COLOR_ATTACHMENT15) + { + return getColorAttachment(attachment - GL_COLOR_ATTACHMENT0); + } + + switch (attachment) + { + case GL_COLOR: + case GL_BACK: + return getColorAttachment(0); + case GL_DEPTH: + case GL_DEPTH_ATTACHMENT: + return getDepthAttachment(); + case GL_STENCIL: + case GL_STENCIL_ATTACHMENT: + return getStencilAttachment(); + case GL_DEPTH_STENCIL: + case GL_DEPTH_STENCIL_ATTACHMENT: + return getDepthStencilAttachment(); + default: + UNREACHABLE(); + return nullptr; + } +} + +size_t FramebufferState::getReadIndex() const +{ + ASSERT(mReadBufferState == GL_BACK || + (mReadBufferState >= GL_COLOR_ATTACHMENT0 && mReadBufferState <= GL_COLOR_ATTACHMENT15)); + size_t readIndex = (mReadBufferState == GL_BACK + ? 0 + : static_cast(mReadBufferState - GL_COLOR_ATTACHMENT0)); ASSERT(readIndex < mColorAttachments.size()); + return readIndex; +} + +const FramebufferAttachment *FramebufferState::getReadAttachment() const +{ + if (mReadBufferState == GL_NONE) + { + return nullptr; + } + size_t readIndex = getReadIndex(); return mColorAttachments[readIndex].isAttached() ? &mColorAttachments[readIndex] : nullptr; } -const FramebufferAttachment *Framebuffer::Data::getFirstColorAttachment() const +const FramebufferAttachment *FramebufferState::getFirstNonNullAttachment() const +{ + auto *colorAttachment = getFirstColorAttachment(); + if (colorAttachment) + { + return colorAttachment; + } + return getDepthOrStencilAttachment(); +} + +const FramebufferAttachment *FramebufferState::getFirstColorAttachment() const { for (const FramebufferAttachment &colorAttachment : mColorAttachments) { @@ -88,7 +365,7 @@ const FramebufferAttachment *Framebuffer::Data::getFirstColorAttachment() const return nullptr; } -const FramebufferAttachment *Framebuffer::Data::getDepthOrStencilAttachment() const +const FramebufferAttachment *FramebufferState::getDepthOrStencilAttachment() const { if (mDepthAttachment.isAttached()) { @@ -101,31 +378,38 @@ const FramebufferAttachment *Framebuffer::Data::getDepthOrStencilAttachment() co return nullptr; } -const FramebufferAttachment *Framebuffer::Data::getColorAttachment(size_t colorAttachment) const +const FramebufferAttachment *FramebufferState::getStencilOrDepthStencilAttachment() const { - ASSERT(colorAttachment < mColorAttachments.size()); - return mColorAttachments[colorAttachment].isAttached() ? - &mColorAttachments[colorAttachment] : - nullptr; + if (mStencilAttachment.isAttached()) + { + return &mStencilAttachment; + } + return getDepthStencilAttachment(); } -const FramebufferAttachment *Framebuffer::Data::getDepthAttachment() const +const FramebufferAttachment *FramebufferState::getColorAttachment(size_t colorAttachment) const +{ + ASSERT(colorAttachment < mColorAttachments.size()); + return mColorAttachments[colorAttachment].isAttached() ? &mColorAttachments[colorAttachment] + : nullptr; +} + +const FramebufferAttachment *FramebufferState::getDepthAttachment() const { return mDepthAttachment.isAttached() ? &mDepthAttachment : nullptr; } -const FramebufferAttachment *Framebuffer::Data::getStencilAttachment() const +const FramebufferAttachment *FramebufferState::getStencilAttachment() const { return mStencilAttachment.isAttached() ? &mStencilAttachment : nullptr; } -const FramebufferAttachment *Framebuffer::Data::getDepthStencilAttachment() const +const FramebufferAttachment *FramebufferState::getDepthStencilAttachment() const { // A valid depth-stencil attachment has the same resource bound to both the // depth and stencil attachment points. if (mDepthAttachment.isAttached() && mStencilAttachment.isAttached() && - mDepthAttachment.type() == mStencilAttachment.type() && - mDepthAttachment.id() == mStencilAttachment.id()) + mDepthAttachment == mStencilAttachment) { return &mDepthAttachment; } @@ -133,12 +417,11 @@ const FramebufferAttachment *Framebuffer::Data::getDepthStencilAttachment() cons return nullptr; } -bool Framebuffer::Data::attachmentsHaveSameDimensions() const +bool FramebufferState::attachmentsHaveSameDimensions() const { Optional attachmentSize; - auto hasMismatchedSize = [&attachmentSize](const FramebufferAttachment &attachment) - { + auto hasMismatchedSize = [&attachmentSize](const FramebufferAttachment &attachment) { if (!attachment.isAttached()) { return false; @@ -150,7 +433,9 @@ bool Framebuffer::Data::attachmentsHaveSameDimensions() const return false; } - return (attachment.getSize() != attachmentSize.value()); + const auto &prevSize = attachmentSize.value(); + const auto &curSize = attachment.getSize(); + return (curSize.width != prevSize.width || curSize.height != prevSize.height); }; for (const auto &attachment : mColorAttachments) @@ -169,156 +454,16 @@ bool Framebuffer::Data::attachmentsHaveSameDimensions() const return !hasMismatchedSize(mStencilAttachment); } -Framebuffer::Framebuffer(const Caps &caps, rx::ImplFactory *factory, GLuint id) - : mData(caps), mImpl(factory->createFramebuffer(mData)), mId(id) +const gl::FramebufferAttachment *FramebufferState::getDrawBuffer(size_t drawBufferIdx) const { - ASSERT(mId != 0); - ASSERT(mImpl != nullptr); -} - -Framebuffer::Framebuffer(rx::SurfaceImpl *surface) - : mData(), mImpl(surface->createDefaultFramebuffer(mData)), mId(0) -{ - ASSERT(mImpl != nullptr); -} - -Framebuffer::~Framebuffer() -{ - SafeDelete(mImpl); -} - -void Framebuffer::setLabel(const std::string &label) -{ - mData.mLabel = label; -} - -const std::string &Framebuffer::getLabel() const -{ - return mData.mLabel; -} - -void Framebuffer::detachTexture(GLuint textureId) -{ - detachResourceById(GL_TEXTURE, textureId); -} - -void Framebuffer::detachRenderbuffer(GLuint renderbufferId) -{ - detachResourceById(GL_RENDERBUFFER, renderbufferId); -} - -void Framebuffer::detachResourceById(GLenum resourceType, GLuint resourceId) -{ - for (auto &colorAttachment : mData.mColorAttachments) - { - DetachMatchingAttachment(&colorAttachment, resourceType, resourceId); - } - - DetachMatchingAttachment(&mData.mDepthAttachment, resourceType, resourceId); - DetachMatchingAttachment(&mData.mStencilAttachment, resourceType, resourceId); -} - -const FramebufferAttachment *Framebuffer::getColorbuffer(size_t colorAttachment) const -{ - return mData.getColorAttachment(colorAttachment); -} - -const FramebufferAttachment *Framebuffer::getDepthbuffer() const -{ - return mData.getDepthAttachment(); -} - -const FramebufferAttachment *Framebuffer::getStencilbuffer() const -{ - return mData.getStencilAttachment(); -} - -const FramebufferAttachment *Framebuffer::getDepthStencilBuffer() const -{ - return mData.getDepthStencilAttachment(); -} - -const FramebufferAttachment *Framebuffer::getDepthOrStencilbuffer() const -{ - return mData.getDepthOrStencilAttachment(); -} - -const FramebufferAttachment *Framebuffer::getReadColorbuffer() const -{ - return mData.getReadAttachment(); -} - -GLenum Framebuffer::getReadColorbufferType() const -{ - const FramebufferAttachment *readAttachment = mData.getReadAttachment(); - return (readAttachment != nullptr ? readAttachment->type() : GL_NONE); -} - -const FramebufferAttachment *Framebuffer::getFirstColorbuffer() const -{ - return mData.getFirstColorAttachment(); -} - -const FramebufferAttachment *Framebuffer::getAttachment(GLenum attachment) const -{ - if (attachment >= GL_COLOR_ATTACHMENT0 && attachment <= GL_COLOR_ATTACHMENT15) - { - return mData.getColorAttachment(attachment - GL_COLOR_ATTACHMENT0); - } - else - { - switch (attachment) - { - case GL_COLOR: - case GL_BACK: - return mData.getColorAttachment(0); - case GL_DEPTH: - case GL_DEPTH_ATTACHMENT: - return mData.getDepthAttachment(); - case GL_STENCIL: - case GL_STENCIL_ATTACHMENT: - return mData.getStencilAttachment(); - case GL_DEPTH_STENCIL: - case GL_DEPTH_STENCIL_ATTACHMENT: - return getDepthStencilBuffer(); - default: - UNREACHABLE(); - return nullptr; - } - } -} - -size_t Framebuffer::getDrawbufferStateCount() const -{ - return mData.mDrawBufferStates.size(); -} - -GLenum Framebuffer::getDrawBufferState(size_t drawBuffer) const -{ - ASSERT(drawBuffer < mData.mDrawBufferStates.size()); - return mData.mDrawBufferStates[drawBuffer]; -} - -void Framebuffer::setDrawBuffers(size_t count, const GLenum *buffers) -{ - auto &drawStates = mData.mDrawBufferStates; - - ASSERT(count <= drawStates.size()); - std::copy(buffers, buffers + count, drawStates.begin()); - std::fill(drawStates.begin() + count, drawStates.end(), GL_NONE); - mDirtyBits.set(DIRTY_BIT_DRAW_BUFFERS); -} - -const FramebufferAttachment *Framebuffer::getDrawBuffer(size_t drawBuffer) const -{ - ASSERT(drawBuffer < mData.mDrawBufferStates.size()); - if (mData.mDrawBufferStates[drawBuffer] != GL_NONE) + ASSERT(drawBufferIdx < mDrawBufferStates.size()); + if (mDrawBufferStates[drawBufferIdx] != GL_NONE) { // ES3 spec: "If the GL is bound to a draw framebuffer object, the ith buffer listed in bufs // must be COLOR_ATTACHMENTi or NONE" - ASSERT(mData.mDrawBufferStates[drawBuffer] == GL_COLOR_ATTACHMENT0 + drawBuffer || - (drawBuffer == 0 && mData.mDrawBufferStates[drawBuffer] == GL_BACK)); - return getAttachment(mData.mDrawBufferStates[drawBuffer]); + ASSERT(mDrawBufferStates[drawBufferIdx] == GL_COLOR_ATTACHMENT0 + drawBufferIdx || + (drawBufferIdx == 0 && mDrawBufferStates[drawBufferIdx] == GL_BACK)); + return getAttachment(mDrawBufferStates[drawBufferIdx]); } else { @@ -326,9 +471,395 @@ const FramebufferAttachment *Framebuffer::getDrawBuffer(size_t drawBuffer) const } } +size_t FramebufferState::getDrawBufferCount() const +{ + return mDrawBufferStates.size(); +} + +bool FramebufferState::colorAttachmentsAreUniqueImages() const +{ + for (size_t firstAttachmentIdx = 0; firstAttachmentIdx < mColorAttachments.size(); + firstAttachmentIdx++) + { + const gl::FramebufferAttachment &firstAttachment = mColorAttachments[firstAttachmentIdx]; + if (!firstAttachment.isAttached()) + { + continue; + } + + for (size_t secondAttachmentIdx = firstAttachmentIdx + 1; + secondAttachmentIdx < mColorAttachments.size(); secondAttachmentIdx++) + { + const gl::FramebufferAttachment &secondAttachment = + mColorAttachments[secondAttachmentIdx]; + if (!secondAttachment.isAttached()) + { + continue; + } + + if (firstAttachment == secondAttachment) + { + return false; + } + } + } + + return true; +} + +bool FramebufferState::hasDepth() const +{ + return (mDepthAttachment.isAttached() && mDepthAttachment.getDepthSize() > 0); +} + +bool FramebufferState::hasStencil() const +{ + return (mStencilAttachment.isAttached() && mStencilAttachment.getStencilSize() > 0); +} + +GLsizei FramebufferState::getNumViews() const +{ + const FramebufferAttachment *attachment = getFirstNonNullAttachment(); + if (attachment == nullptr) + { + return FramebufferAttachment::kDefaultNumViews; + } + return attachment->getNumViews(); +} + +const std::vector *FramebufferState::getViewportOffsets() const +{ + const FramebufferAttachment *attachment = getFirstNonNullAttachment(); + if (attachment == nullptr) + { + return nullptr; + } + return &attachment->getMultiviewViewportOffsets(); +} + +GLenum FramebufferState::getMultiviewLayout() const +{ + const FramebufferAttachment *attachment = getFirstNonNullAttachment(); + if (attachment == nullptr) + { + return GL_NONE; + } + return attachment->getMultiviewLayout(); +} + +int FramebufferState::getBaseViewIndex() const +{ + const FramebufferAttachment *attachment = getFirstNonNullAttachment(); + if (attachment == nullptr) + { + return GL_NONE; + } + return attachment->getBaseViewIndex(); +} + +Box FramebufferState::getDimensions() const +{ + ASSERT(attachmentsHaveSameDimensions()); + ASSERT(getFirstNonNullAttachment() != nullptr); + Extents extents = getFirstNonNullAttachment()->getSize(); + return Box(0, 0, 0, extents.width, extents.height, extents.depth); +} + +Framebuffer::Framebuffer(const Caps &caps, rx::GLImplFactory *factory, GLuint id) + : mState(caps), + mImpl(factory->createFramebuffer(mState)), + mId(id), + mCachedStatus(), + mDirtyDepthAttachmentBinding(this, DIRTY_BIT_DEPTH_ATTACHMENT), + mDirtyStencilAttachmentBinding(this, DIRTY_BIT_STENCIL_ATTACHMENT) +{ + ASSERT(mId != 0); + ASSERT(mImpl != nullptr); + ASSERT(mState.mColorAttachments.size() == static_cast(caps.maxColorAttachments)); + + for (uint32_t colorIndex = 0; + colorIndex < static_cast(mState.mColorAttachments.size()); ++colorIndex) + { + mDirtyColorAttachmentBindings.emplace_back(this, DIRTY_BIT_COLOR_ATTACHMENT_0 + colorIndex); + } +} + +Framebuffer::Framebuffer(const egl::Display *display, egl::Surface *surface) + : mState(), + mImpl(surface->getImplementation()->createDefaultFramebuffer(mState)), + mId(0), + mCachedStatus(GL_FRAMEBUFFER_COMPLETE), + mDirtyDepthAttachmentBinding(this, DIRTY_BIT_DEPTH_ATTACHMENT), + mDirtyStencilAttachmentBinding(this, DIRTY_BIT_STENCIL_ATTACHMENT) +{ + ASSERT(mImpl != nullptr); + mDirtyColorAttachmentBindings.emplace_back(this, DIRTY_BIT_COLOR_ATTACHMENT_0); + + const Context *proxyContext = display->getProxyContext(); + + setAttachmentImpl(proxyContext, GL_FRAMEBUFFER_DEFAULT, GL_BACK, gl::ImageIndex::MakeInvalid(), + surface, FramebufferAttachment::kDefaultNumViews, + FramebufferAttachment::kDefaultBaseViewIndex, + FramebufferAttachment::kDefaultMultiviewLayout, + FramebufferAttachment::kDefaultViewportOffsets); + + if (surface->getConfig()->depthSize > 0) + { + setAttachmentImpl( + proxyContext, GL_FRAMEBUFFER_DEFAULT, GL_DEPTH, gl::ImageIndex::MakeInvalid(), surface, + FramebufferAttachment::kDefaultNumViews, FramebufferAttachment::kDefaultBaseViewIndex, + FramebufferAttachment::kDefaultMultiviewLayout, + FramebufferAttachment::kDefaultViewportOffsets); + } + + if (surface->getConfig()->stencilSize > 0) + { + setAttachmentImpl(proxyContext, GL_FRAMEBUFFER_DEFAULT, GL_STENCIL, + gl::ImageIndex::MakeInvalid(), surface, + FramebufferAttachment::kDefaultNumViews, + FramebufferAttachment::kDefaultBaseViewIndex, + FramebufferAttachment::kDefaultMultiviewLayout, + FramebufferAttachment::kDefaultViewportOffsets); + } +} + +Framebuffer::Framebuffer(rx::GLImplFactory *factory) + : mState(), + mImpl(factory->createFramebuffer(mState)), + mId(0), + mCachedStatus(GL_FRAMEBUFFER_UNDEFINED_OES), + mDirtyDepthAttachmentBinding(this, DIRTY_BIT_DEPTH_ATTACHMENT), + mDirtyStencilAttachmentBinding(this, DIRTY_BIT_STENCIL_ATTACHMENT) +{ + mDirtyColorAttachmentBindings.emplace_back(this, DIRTY_BIT_COLOR_ATTACHMENT_0); +} + +Framebuffer::~Framebuffer() +{ + SafeDelete(mImpl); +} + +void Framebuffer::onDestroy(const Context *context) +{ + for (auto &attachment : mState.mColorAttachments) + { + attachment.detach(context); + } + mState.mDepthAttachment.detach(context); + mState.mStencilAttachment.detach(context); + mState.mWebGLDepthAttachment.detach(context); + mState.mWebGLStencilAttachment.detach(context); + mState.mWebGLDepthStencilAttachment.detach(context); + + mImpl->destroy(context); +} + +void Framebuffer::destroyDefault(const egl::Display *display) +{ + mImpl->destroyDefault(display); +} + +void Framebuffer::setLabel(const std::string &label) +{ + mState.mLabel = label; +} + +const std::string &Framebuffer::getLabel() const +{ + return mState.mLabel; +} + +bool Framebuffer::detachTexture(const Context *context, GLuint textureId) +{ + return detachResourceById(context, GL_TEXTURE, textureId); +} + +bool Framebuffer::detachRenderbuffer(const Context *context, GLuint renderbufferId) +{ + return detachResourceById(context, GL_RENDERBUFFER, renderbufferId); +} + +bool Framebuffer::detachResourceById(const Context *context, GLenum resourceType, GLuint resourceId) +{ + bool found = false; + + for (size_t colorIndex = 0; colorIndex < mState.mColorAttachments.size(); ++colorIndex) + { + if (detachMatchingAttachment(context, &mState.mColorAttachments[colorIndex], resourceType, + resourceId, DIRTY_BIT_COLOR_ATTACHMENT_0 + colorIndex)) + { + found = true; + } + } + + if (context->isWebGL1()) + { + const std::array attachments = { + {&mState.mWebGLDepthStencilAttachment, &mState.mWebGLDepthAttachment, + &mState.mWebGLStencilAttachment}}; + for (FramebufferAttachment *attachment : attachments) + { + if (attachment->isAttached() && attachment->type() == resourceType && + attachment->id() == resourceId) + { + resetAttachment(context, attachment->getBinding()); + found = true; + } + } + } + else + { + if (detachMatchingAttachment(context, &mState.mDepthAttachment, resourceType, resourceId, + DIRTY_BIT_DEPTH_ATTACHMENT)) + { + found = true; + } + if (detachMatchingAttachment(context, &mState.mStencilAttachment, resourceType, resourceId, + DIRTY_BIT_STENCIL_ATTACHMENT)) + { + found = true; + } + } + + return found; +} + +bool Framebuffer::detachMatchingAttachment(const Context *context, + FramebufferAttachment *attachment, + GLenum matchType, + GLuint matchId, + size_t dirtyBit) +{ + if (attachment->isAttached() && attachment->type() == matchType && attachment->id() == matchId) + { + attachment->detach(context); + mDirtyBits.set(dirtyBit); + mState.mResourceNeedsInit.set(dirtyBit, false); + return true; + } + + return false; +} + +const FramebufferAttachment *Framebuffer::getColorbuffer(size_t colorAttachment) const +{ + return mState.getColorAttachment(colorAttachment); +} + +const FramebufferAttachment *Framebuffer::getDepthbuffer() const +{ + return mState.getDepthAttachment(); +} + +const FramebufferAttachment *Framebuffer::getStencilbuffer() const +{ + return mState.getStencilAttachment(); +} + +const FramebufferAttachment *Framebuffer::getDepthStencilBuffer() const +{ + return mState.getDepthStencilAttachment(); +} + +const FramebufferAttachment *Framebuffer::getDepthOrStencilbuffer() const +{ + return mState.getDepthOrStencilAttachment(); +} + +const FramebufferAttachment *Framebuffer::getStencilOrDepthStencilAttachment() const +{ + return mState.getStencilOrDepthStencilAttachment(); +} + +const FramebufferAttachment *Framebuffer::getReadColorbuffer() const +{ + return mState.getReadAttachment(); +} + +GLenum Framebuffer::getReadColorbufferType() const +{ + const FramebufferAttachment *readAttachment = mState.getReadAttachment(); + return (readAttachment != nullptr ? readAttachment->type() : GL_NONE); +} + +const FramebufferAttachment *Framebuffer::getFirstColorbuffer() const +{ + return mState.getFirstColorAttachment(); +} + +const FramebufferAttachment *Framebuffer::getFirstNonNullAttachment() const +{ + return mState.getFirstNonNullAttachment(); +} + +const FramebufferAttachment *Framebuffer::getAttachment(GLenum attachment) const +{ + return mState.getAttachment(attachment); +} + +size_t Framebuffer::getDrawbufferStateCount() const +{ + return mState.mDrawBufferStates.size(); +} + +GLenum Framebuffer::getDrawBufferState(size_t drawBuffer) const +{ + ASSERT(drawBuffer < mState.mDrawBufferStates.size()); + return mState.mDrawBufferStates[drawBuffer]; +} + +const std::vector &Framebuffer::getDrawBufferStates() const +{ + return mState.getDrawBufferStates(); +} + +void Framebuffer::setDrawBuffers(size_t count, const GLenum *buffers) +{ + auto &drawStates = mState.mDrawBufferStates; + + ASSERT(count <= drawStates.size()); + std::copy(buffers, buffers + count, drawStates.begin()); + std::fill(drawStates.begin() + count, drawStates.end(), GL_NONE); + mDirtyBits.set(DIRTY_BIT_DRAW_BUFFERS); + + mState.mEnabledDrawBuffers.reset(); + for (size_t index = 0; index < count; ++index) + { + if (drawStates[index] != GL_NONE && mState.mColorAttachments[index].isAttached()) + { + mState.mEnabledDrawBuffers.set(index); + } + } +} + +const FramebufferAttachment *Framebuffer::getDrawBuffer(size_t drawBuffer) const +{ + return mState.getDrawBuffer(drawBuffer); +} + +GLenum Framebuffer::getDrawbufferWriteType(size_t drawBuffer) const +{ + const FramebufferAttachment *attachment = mState.getDrawBuffer(drawBuffer); + if (attachment == nullptr) + { + return GL_NONE; + } + + GLenum componentType = attachment->getFormat().info->componentType; + switch (componentType) + { + case GL_INT: + case GL_UNSIGNED_INT: + return componentType; + + default: + return GL_FLOAT; + } +} + bool Framebuffer::hasEnabledDrawBuffer() const { - for (size_t drawbufferIdx = 0; drawbufferIdx < mData.mDrawBufferStates.size(); ++drawbufferIdx) + for (size_t drawbufferIdx = 0; drawbufferIdx < mState.mDrawBufferStates.size(); ++drawbufferIdx) { if (getDrawBuffer(drawbufferIdx) != nullptr) { @@ -341,36 +872,36 @@ bool Framebuffer::hasEnabledDrawBuffer() const GLenum Framebuffer::getReadBufferState() const { - return mData.mReadBufferState; + return mState.mReadBufferState; } void Framebuffer::setReadBuffer(GLenum buffer) { ASSERT(buffer == GL_BACK || buffer == GL_NONE || (buffer >= GL_COLOR_ATTACHMENT0 && - (buffer - GL_COLOR_ATTACHMENT0) < mData.mColorAttachments.size())); - mData.mReadBufferState = buffer; + (buffer - GL_COLOR_ATTACHMENT0) < mState.mColorAttachments.size())); + mState.mReadBufferState = buffer; mDirtyBits.set(DIRTY_BIT_READ_BUFFER); } size_t Framebuffer::getNumColorBuffers() const { - return mData.mColorAttachments.size(); + return mState.mColorAttachments.size(); } bool Framebuffer::hasDepth() const { - return (mData.mDepthAttachment.isAttached() && mData.mDepthAttachment.getDepthSize() > 0); + return mState.hasDepth(); } bool Framebuffer::hasStencil() const { - return (mData.mStencilAttachment.isAttached() && mData.mStencilAttachment.getStencilSize() > 0); + return mState.hasStencil(); } bool Framebuffer::usingExtendedDrawBuffers() const { - for (size_t drawbufferIdx = 1; drawbufferIdx < mData.mDrawBufferStates.size(); ++drawbufferIdx) + for (size_t drawbufferIdx = 1; drawbufferIdx < mState.mDrawBufferStates.size(); ++drawbufferIdx) { if (getDrawBuffer(drawbufferIdx) != nullptr) { @@ -381,210 +912,234 @@ bool Framebuffer::usingExtendedDrawBuffers() const return false; } -GLenum Framebuffer::checkStatus(const gl::Data &data) const +void Framebuffer::invalidateCompletenessCache() { - // The default framebuffer *must* always be complete, though it may not be - // subject to the same rules as application FBOs. ie, it could have 0x0 size. + if (mId != 0) + { + mCachedStatus.reset(); + } +} + +GLenum Framebuffer::checkStatus(const Context *context) +{ + // The default framebuffer is always complete except when it is surfaceless in which + // case it is always unsupported. We return early because the default framebuffer may + // not be subject to the same rules as application FBOs. ie, it could have 0x0 size. if (mId == 0) { - return GL_FRAMEBUFFER_COMPLETE; + ASSERT(mCachedStatus.valid()); + ASSERT(mCachedStatus.value() == GL_FRAMEBUFFER_COMPLETE || + mCachedStatus.value() == GL_FRAMEBUFFER_UNDEFINED_OES); + return mCachedStatus.value(); } - unsigned int colorbufferSize = 0; - int samples = -1; - bool missingAttachment = true; + if (hasAnyDirtyBit() || !mCachedStatus.valid()) + { + mCachedStatus = checkStatusImpl(context); + } - for (const FramebufferAttachment &colorAttachment : mData.mColorAttachments) + return mCachedStatus.value(); +} + +GLenum Framebuffer::checkStatusImpl(const Context *context) +{ + const ContextState &state = context->getContextState(); + + ASSERT(mId != 0); + + bool hasAttachments = false; + Optional colorbufferSize; + Optional samples; + Optional fixedSampleLocations; + bool hasRenderbuffer = false; + + const FramebufferAttachment *firstAttachment = getFirstNonNullAttachment(); + + for (const FramebufferAttachment &colorAttachment : mState.mColorAttachments) { if (colorAttachment.isAttached()) { - const Extents &size = colorAttachment.getSize(); - if (size.width == 0 || size.height == 0) + if (!CheckAttachmentCompleteness(context, colorAttachment)) { return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } - GLenum internalformat = colorAttachment.getInternalFormat(); - const TextureCaps &formatCaps = data.textureCaps->get(internalformat); - const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat); - if (colorAttachment.type() == GL_TEXTURE) + const InternalFormat &format = *colorAttachment.getFormat().info; + if (format.depthBits > 0 || format.stencilBits > 0) { - if (!formatCaps.renderable) - { - return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; - } - - if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) - { - return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; - } - - if (colorAttachment.layer() >= size.depth) - { - return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; - } - - // ES3 specifies that cube map texture attachments must be cube complete. - // This language is missing from the ES2 spec, but we enforce it here because some - // desktop OpenGL drivers also enforce this validation. - // TODO(jmadill): Check if OpenGL ES2 drivers enforce cube completeness. - const Texture *texture = colorAttachment.getTexture(); - ASSERT(texture); - if (texture->getTarget() == GL_TEXTURE_CUBE_MAP && !texture->isCubeComplete()) - { - return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; - } - } - else if (colorAttachment.type() == GL_RENDERBUFFER) - { - if (!formatCaps.renderable || formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) - { - return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; - } + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } - if (!missingAttachment) + if (!CheckAttachmentSampleCompleteness(context, colorAttachment, true, &samples, + &fixedSampleLocations)) { - // APPLE_framebuffer_multisample, which EXT_draw_buffers refers to, requires that - // all color attachments have the same number of samples for the FBO to be complete. - if (colorAttachment.getSamples() != samples) - { - return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT; - } + return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE; + } - // in GLES 2.0, all color attachments attachments must have the same number of bitplanes - // in GLES 3.0, there is no such restriction - if (data.clientVersion < 3) + // in GLES 2.0, all color attachments attachments must have the same number of bitplanes + // in GLES 3.0, there is no such restriction + if (state.getClientMajorVersion() < 3) + { + if (colorbufferSize.valid()) { - if (formatInfo.pixelBytes != colorbufferSize) + if (format.pixelBytes != colorbufferSize.value()) { return GL_FRAMEBUFFER_UNSUPPORTED; } } + else + { + colorbufferSize = format.pixelBytes; + } } - else + + if (!CheckMultiviewStateMatchesForCompleteness(firstAttachment, &colorAttachment)) { - samples = colorAttachment.getSamples(); - colorbufferSize = formatInfo.pixelBytes; - missingAttachment = false; + return GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_ANGLE; } + + hasRenderbuffer = hasRenderbuffer || (colorAttachment.type() == GL_RENDERBUFFER); + hasAttachments = true; } } - const FramebufferAttachment &depthAttachment = mData.mDepthAttachment; + const FramebufferAttachment &depthAttachment = mState.mDepthAttachment; if (depthAttachment.isAttached()) { - const Extents &size = depthAttachment.getSize(); - if (size.width == 0 || size.height == 0) + if (!CheckAttachmentCompleteness(context, depthAttachment)) { return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } - GLenum internalformat = depthAttachment.getInternalFormat(); - const TextureCaps &formatCaps = data.textureCaps->get(internalformat); - const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat); - if (depthAttachment.type() == GL_TEXTURE) + const InternalFormat &format = *depthAttachment.getFormat().info; + if (format.depthBits == 0) { - // depth texture attachments require OES/ANGLE_depth_texture - if (!data.extensions->depthTextures) - { - return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; - } - - if (!formatCaps.renderable) - { - return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; - } - - if (formatInfo.depthBits == 0) - { - return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; - } - } - else if (depthAttachment.type() == GL_RENDERBUFFER) - { - if (!formatCaps.renderable || formatInfo.depthBits == 0) - { - return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; - } + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } - if (missingAttachment) + if (!CheckAttachmentSampleCompleteness(context, depthAttachment, false, &samples, + &fixedSampleLocations)) { - samples = depthAttachment.getSamples(); - missingAttachment = false; + return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE; } - else if (samples != depthAttachment.getSamples()) + + if (!CheckMultiviewStateMatchesForCompleteness(firstAttachment, &depthAttachment)) { - return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE; + return GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_ANGLE; } + + hasRenderbuffer = hasRenderbuffer || (depthAttachment.type() == GL_RENDERBUFFER); + hasAttachments = true; } - const FramebufferAttachment &stencilAttachment = mData.mStencilAttachment; + const FramebufferAttachment &stencilAttachment = mState.mStencilAttachment; if (stencilAttachment.isAttached()) { - const Extents &size = stencilAttachment.getSize(); - if (size.width == 0 || size.height == 0) + if (!CheckAttachmentCompleteness(context, stencilAttachment)) { return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } - GLenum internalformat = stencilAttachment.getInternalFormat(); - const TextureCaps &formatCaps = data.textureCaps->get(internalformat); - const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat); - if (stencilAttachment.type() == GL_TEXTURE) + const InternalFormat &format = *stencilAttachment.getFormat().info; + if (format.stencilBits == 0) { - // texture stencil attachments come along as part - // of OES_packed_depth_stencil + OES/ANGLE_depth_texture - if (!data.extensions->depthTextures) + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; + } + + if (!CheckAttachmentSampleCompleteness(context, stencilAttachment, false, &samples, + &fixedSampleLocations)) + { + return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE; + } + + if (!CheckMultiviewStateMatchesForCompleteness(firstAttachment, &stencilAttachment)) + { + return GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_ANGLE; + } + + hasRenderbuffer = hasRenderbuffer || (stencilAttachment.type() == GL_RENDERBUFFER); + hasAttachments = true; + } + + // Starting from ES 3.0 stencil and depth, if present, should be the same image + if (state.getClientMajorVersion() >= 3 && depthAttachment.isAttached() && + stencilAttachment.isAttached() && stencilAttachment != depthAttachment) + { + return GL_FRAMEBUFFER_UNSUPPORTED; + } + + // Special additional validation for WebGL 1 DEPTH/STENCIL/DEPTH_STENCIL. + if (state.isWebGL1()) + { + if (!mState.mWebGLDepthStencilConsistent) + { + return GL_FRAMEBUFFER_UNSUPPORTED; + } + + if (mState.mWebGLDepthStencilAttachment.isAttached()) + { + if (mState.mWebGLDepthStencilAttachment.getDepthSize() == 0 || + mState.mWebGLDepthStencilAttachment.getStencilSize() == 0) { return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } - if (!formatCaps.renderable) + if (!CheckMultiviewStateMatchesForCompleteness(firstAttachment, + &mState.mWebGLDepthStencilAttachment)) { - return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; - } - - if (formatInfo.stencilBits == 0) - { - return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; + return GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_ANGLE; } } - else if (stencilAttachment.type() == GL_RENDERBUFFER) + else if (mState.mStencilAttachment.isAttached() && + mState.mStencilAttachment.getDepthSize() > 0) { - if (!formatCaps.renderable || formatInfo.stencilBits == 0) - { - return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; - } + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } - - if (missingAttachment) + else if (mState.mDepthAttachment.isAttached() && + mState.mDepthAttachment.getStencilSize() > 0) { - samples = stencilAttachment.getSamples(); - missingAttachment = false; - } - else if (samples != stencilAttachment.getSamples()) - { - return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE; + return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } } - // we need to have at least one attachment to be complete - if (missingAttachment) + // ES3.1(section 9.4) requires that if no image is attached to the framebuffer, and either the + // value of the framebuffer's FRAMEBUFFER_DEFAULT_WIDTH or FRAMEBUFFER_DEFAULT_HEIGHT parameters + // is zero, the framebuffer is considered incomplete. + GLint defaultWidth = mState.getDefaultWidth(); + GLint defaultHeight = mState.getDefaultHeight(); + if (!hasAttachments && (defaultWidth == 0 || defaultHeight == 0)) { return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; } - // In ES 2.0, all color attachments must have the same width and height. + // In ES 2.0 and WebGL, all color attachments must have the same width and height. // In ES 3.0, there is no such restriction. - if (data.clientVersion < 3 && !mData.attachmentsHaveSameDimensions()) + if ((state.getClientMajorVersion() < 3 || state.getExtensions().webglCompatibility) && + !mState.attachmentsHaveSameDimensions()) { return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS; } - syncState(); - if (!mImpl->checkStatus()) + // ES3.1(section 9.4) requires that if the attached images are a mix of renderbuffers and + // textures, the value of TEXTURE_FIXED_SAMPLE_LOCATIONS must be TRUE for all attached textures. + if (fixedSampleLocations.valid() && hasRenderbuffer && !fixedSampleLocations.value()) + { + return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE; + } + + // The WebGL conformance tests implicitly define that all framebuffer + // attachments must be unique. For example, the same level of a texture can + // not be attached to two different color attachments. + if (state.getExtensions().webglCompatibility) + { + if (!mState.colorAttachmentsAreUniqueImages()) + { + return GL_FRAMEBUFFER_UNSUPPORTED; + } + } + + syncState(context); + if (!mImpl->checkStatus(context)) { return GL_FRAMEBUFFER_UNSUPPORTED; } @@ -592,216 +1147,1036 @@ GLenum Framebuffer::checkStatus(const gl::Data &data) const return GL_FRAMEBUFFER_COMPLETE; } -Error Framebuffer::discard(size_t count, const GLenum *attachments) +Error Framebuffer::discard(const Context *context, size_t count, const GLenum *attachments) { - return mImpl->discard(count, attachments); + // Back-ends might make the contents of the FBO undefined. In WebGL 2.0, invalidate operations + // can be no-ops, so we should probably do that to ensure consistency. + // TODO(jmadill): WebGL behaviour, and robust resource init behaviour without WebGL. + + return mImpl->discard(context, count, attachments); } -Error Framebuffer::invalidate(size_t count, const GLenum *attachments) +Error Framebuffer::invalidate(const Context *context, size_t count, const GLenum *attachments) { - return mImpl->invalidate(count, attachments); + // Back-ends might make the contents of the FBO undefined. In WebGL 2.0, invalidate operations + // can be no-ops, so we should probably do that to ensure consistency. + // TODO(jmadill): WebGL behaviour, and robust resource init behaviour without WebGL. + + return mImpl->invalidate(context, count, attachments); } -Error Framebuffer::invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) +bool Framebuffer::partialClearNeedsInit(const Context *context, + bool color, + bool depth, + bool stencil) { - return mImpl->invalidateSub(count, attachments, area); -} + const auto &glState = context->getGLState(); -Error Framebuffer::clear(const gl::Data &data, GLbitfield mask) -{ - if (data.state->isRasterizerDiscardEnabled()) + if (!glState.isRobustResourceInitEnabled()) { - return gl::Error(GL_NO_ERROR); + return false; } - return mImpl->clear(data, mask); + // Scissors can affect clearing. + // TODO(jmadill): Check for complete scissor overlap. + if (glState.isScissorTestEnabled()) + { + return true; + } + + // If colors masked, we must clear before we clear. Do a simple check. + // TODO(jmadill): Filter out unused color channels from the test. + if (color) + { + const auto &blend = glState.getBlendState(); + if (!(blend.colorMaskRed && blend.colorMaskGreen && blend.colorMaskBlue && + blend.colorMaskAlpha)) + { + return true; + } + } + + const auto &depthStencil = glState.getDepthStencilState(); + ASSERT(depthStencil.stencilBackMask == depthStencil.stencilMask); + if (stencil && depthStencil.stencilMask != depthStencil.stencilWritemask) + { + return true; + } + + return false; } -Error Framebuffer::clearBufferfv(const gl::Data &data, +Error Framebuffer::invalidateSub(const Context *context, + size_t count, + const GLenum *attachments, + const gl::Rectangle &area) +{ + // Back-ends might make the contents of the FBO undefined. In WebGL 2.0, invalidate operations + // can be no-ops, so we should probably do that to ensure consistency. + // TODO(jmadill): Make a invalidate no-op in WebGL 2.0. + + return mImpl->invalidateSub(context, count, attachments, area); +} + +Error Framebuffer::clear(const gl::Context *context, GLbitfield mask) +{ + const auto &glState = context->getGLState(); + if (glState.isRasterizerDiscardEnabled()) + { + return NoError(); + } + + const auto &blend = glState.getBlendState(); + const auto &depthStencil = glState.getDepthStencilState(); + + bool color = (mask & GL_COLOR_BUFFER_BIT) != 0 && !IsColorMaskedOut(blend); + bool depth = (mask & GL_DEPTH_BUFFER_BIT) != 0 && !IsDepthMaskedOut(depthStencil); + bool stencil = (mask & GL_STENCIL_BUFFER_BIT) != 0 && !IsStencilMaskedOut(depthStencil); + + if (partialClearNeedsInit(context, color, depth, stencil)) + { + ANGLE_TRY(ensureDrawAttachmentsInitialized(context)); + } + + ANGLE_TRY(mImpl->clear(context, mask)); + + if (glState.isRobustResourceInitEnabled()) + { + markDrawAttachmentsInitialized(color, depth, stencil); + } + + return NoError(); +} + +Error Framebuffer::clearBufferfv(const gl::Context *context, GLenum buffer, GLint drawbuffer, const GLfloat *values) { - if (data.state->isRasterizerDiscardEnabled()) + if (context->getGLState().isRasterizerDiscardEnabled() || + IsClearBufferMaskedOut(context, buffer)) { - return gl::Error(GL_NO_ERROR); + return NoError(); } - return mImpl->clearBufferfv(data, buffer, drawbuffer, values); + if (partialBufferClearNeedsInit(context, buffer)) + { + ANGLE_TRY(ensureBufferInitialized(context, buffer, drawbuffer)); + } + + ANGLE_TRY(mImpl->clearBufferfv(context, buffer, drawbuffer, values)); + + if (context->isRobustResourceInitEnabled()) + { + markBufferInitialized(buffer, drawbuffer); + } + return NoError(); } -Error Framebuffer::clearBufferuiv(const gl::Data &data, +Error Framebuffer::clearBufferuiv(const gl::Context *context, GLenum buffer, GLint drawbuffer, const GLuint *values) { - if (data.state->isRasterizerDiscardEnabled()) + if (context->getGLState().isRasterizerDiscardEnabled() || + IsClearBufferMaskedOut(context, buffer)) { - return gl::Error(GL_NO_ERROR); + return NoError(); } - return mImpl->clearBufferuiv(data, buffer, drawbuffer, values); + if (partialBufferClearNeedsInit(context, buffer)) + { + ANGLE_TRY(ensureBufferInitialized(context, buffer, drawbuffer)); + } + + ANGLE_TRY(mImpl->clearBufferuiv(context, buffer, drawbuffer, values)); + + if (context->isRobustResourceInitEnabled()) + { + markBufferInitialized(buffer, drawbuffer); + } + return NoError(); } -Error Framebuffer::clearBufferiv(const gl::Data &data, +Error Framebuffer::clearBufferiv(const gl::Context *context, GLenum buffer, GLint drawbuffer, const GLint *values) { - if (data.state->isRasterizerDiscardEnabled()) + if (context->getGLState().isRasterizerDiscardEnabled() || + IsClearBufferMaskedOut(context, buffer)) { - return gl::Error(GL_NO_ERROR); + return NoError(); } - return mImpl->clearBufferiv(data, buffer, drawbuffer, values); + if (partialBufferClearNeedsInit(context, buffer)) + { + ANGLE_TRY(ensureBufferInitialized(context, buffer, drawbuffer)); + } + + ANGLE_TRY(mImpl->clearBufferiv(context, buffer, drawbuffer, values)); + + if (context->isRobustResourceInitEnabled()) + { + markBufferInitialized(buffer, drawbuffer); + } + return NoError(); } -Error Framebuffer::clearBufferfi(const gl::Data &data, +Error Framebuffer::clearBufferfi(const gl::Context *context, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) { - if (data.state->isRasterizerDiscardEnabled()) + if (context->getGLState().isRasterizerDiscardEnabled() || + IsClearBufferMaskedOut(context, buffer)) { - return gl::Error(GL_NO_ERROR); + return NoError(); } - return mImpl->clearBufferfi(data, buffer, drawbuffer, depth, stencil); + if (partialBufferClearNeedsInit(context, buffer)) + { + ANGLE_TRY(ensureBufferInitialized(context, buffer, drawbuffer)); + } + + ANGLE_TRY(mImpl->clearBufferfi(context, buffer, drawbuffer, depth, stencil)); + + if (context->isRobustResourceInitEnabled()) + { + markBufferInitialized(buffer, drawbuffer); + } + return NoError(); } -GLenum Framebuffer::getImplementationColorReadFormat() const +GLenum Framebuffer::getImplementationColorReadFormat(const Context *context) const { - return mImpl->getImplementationColorReadFormat(); + return mImpl->getImplementationColorReadFormat(context); } -GLenum Framebuffer::getImplementationColorReadType() const +GLenum Framebuffer::getImplementationColorReadType(const Context *context) const { - return mImpl->getImplementationColorReadType(); + return mImpl->getImplementationColorReadType(context); } -Error Framebuffer::readPixels(const State &state, +Error Framebuffer::readPixels(const gl::Context *context, const Rectangle &area, GLenum format, GLenum type, - GLvoid *pixels) const + void *pixels) { - Error error = mImpl->readPixels(state, area, format, type, pixels); - if (error.isError()) - { - return error; - } + ANGLE_TRY(ensureReadAttachmentInitialized(context, GL_COLOR_BUFFER_BIT)); + ANGLE_TRY(mImpl->readPixels(context, area, format, type, pixels)); - Buffer *unpackBuffer = state.getUnpackState().pixelBuffer.get(); + Buffer *unpackBuffer = context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack); if (unpackBuffer) { unpackBuffer->onPixelUnpack(); } - return Error(GL_NO_ERROR); + return NoError(); } -Error Framebuffer::blit(const State &state, +Error Framebuffer::blit(const gl::Context *context, const Rectangle &sourceArea, const Rectangle &destArea, GLbitfield mask, - GLenum filter, - const Framebuffer *sourceFramebuffer) + GLenum filter) { - return mImpl->blit(state, sourceArea, destArea, mask, filter, sourceFramebuffer); + GLbitfield blitMask = mask; + + // Note that blitting is called against draw framebuffer. + // See the code in gl::Context::blitFramebuffer. + if ((mask & GL_COLOR_BUFFER_BIT) && !hasEnabledDrawBuffer()) + { + blitMask &= ~GL_COLOR_BUFFER_BIT; + } + + if ((mask & GL_STENCIL_BUFFER_BIT) && mState.getStencilAttachment() == nullptr) + { + blitMask &= ~GL_STENCIL_BUFFER_BIT; + } + + if ((mask & GL_DEPTH_BUFFER_BIT) && mState.getDepthAttachment() == nullptr) + { + blitMask &= ~GL_DEPTH_BUFFER_BIT; + } + + if (!blitMask) + { + return NoError(); + } + + auto *sourceFBO = context->getGLState().getReadFramebuffer(); + ANGLE_TRY(sourceFBO->ensureReadAttachmentInitialized(context, blitMask)); + + // TODO(jmadill): Only clear if not the full FBO dimensions, and only specified bitmask. + ANGLE_TRY(ensureDrawAttachmentsInitialized(context)); + + return mImpl->blit(context, sourceArea, destArea, blitMask, filter); } -int Framebuffer::getSamples(const gl::Data &data) const +int Framebuffer::getSamples(const Context *context) { - if (checkStatus(data) == GL_FRAMEBUFFER_COMPLETE) + if (complete(context)) { - // for a complete framebuffer, all attachments must have the same sample count - // in this case return the first nonzero sample size - for (const FramebufferAttachment &colorAttachment : mData.mColorAttachments) - { - if (colorAttachment.isAttached()) - { - return colorAttachment.getSamples(); - } - } + return getCachedSamples(context); } return 0; } -bool Framebuffer::hasValidDepthStencil() const +int Framebuffer::getCachedSamples(const Context *context) { - return mData.getDepthStencilAttachment() != nullptr; + // For a complete framebuffer, all attachments must have the same sample count. + // In this case return the first nonzero sample size. + const auto *firstNonNullAttachment = mState.getFirstNonNullAttachment(); + if (firstNonNullAttachment) + { + ASSERT(firstNonNullAttachment->isAttached()); + return firstNonNullAttachment->getSamples(); + } + + // No attachments found. + return 0; } -void Framebuffer::setAttachment(GLenum type, +Error Framebuffer::getSamplePosition(size_t index, GLfloat *xy) const +{ + ANGLE_TRY(mImpl->getSamplePosition(index, xy)); + return NoError(); +} + +bool Framebuffer::hasValidDepthStencil() const +{ + return mState.getDepthStencilAttachment() != nullptr; +} + +void Framebuffer::setAttachment(const Context *context, + GLenum type, GLenum binding, const ImageIndex &textureIndex, FramebufferAttachmentObject *resource) { - if (binding == GL_DEPTH_STENCIL || binding == GL_DEPTH_STENCIL_ATTACHMENT) - { - // ensure this is a legitimate depth+stencil format - FramebufferAttachmentObject *attachmentObj = resource; - if (resource) - { - FramebufferAttachment::Target target(binding, textureIndex); - GLenum internalFormat = resource->getAttachmentInternalFormat(target); - const InternalFormat &formatInfo = GetInternalFormatInfo(internalFormat); - if (formatInfo.depthBits == 0 || formatInfo.stencilBits == 0) - { - // Attaching nullptr detaches the current attachment. - attachmentObj = nullptr; - } - } + setAttachment(context, type, binding, textureIndex, resource, + FramebufferAttachment::kDefaultNumViews, + FramebufferAttachment::kDefaultBaseViewIndex, + FramebufferAttachment::kDefaultMultiviewLayout, + FramebufferAttachment::kDefaultViewportOffsets); +} - mData.mDepthAttachment.attach(type, binding, textureIndex, attachmentObj); - mData.mStencilAttachment.attach(type, binding, textureIndex, attachmentObj); - mDirtyBits.set(DIRTY_BIT_DEPTH_ATTACHMENT); - mDirtyBits.set(DIRTY_BIT_STENCIL_ATTACHMENT); +void Framebuffer::setAttachment(const Context *context, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei numViews, + GLuint baseViewIndex, + GLenum multiviewLayout, + const GLint *viewportOffsets) +{ + // Context may be null in unit tests. + if (!context || !context->isWebGL1()) + { + setAttachmentImpl(context, type, binding, textureIndex, resource, numViews, baseViewIndex, + multiviewLayout, viewportOffsets); + return; + } + + switch (binding) + { + case GL_DEPTH_STENCIL: + case GL_DEPTH_STENCIL_ATTACHMENT: + mState.mWebGLDepthStencilAttachment.attach(context, type, binding, textureIndex, + resource, numViews, baseViewIndex, + multiviewLayout, viewportOffsets); + break; + case GL_DEPTH: + case GL_DEPTH_ATTACHMENT: + mState.mWebGLDepthAttachment.attach(context, type, binding, textureIndex, resource, + numViews, baseViewIndex, multiviewLayout, + viewportOffsets); + break; + case GL_STENCIL: + case GL_STENCIL_ATTACHMENT: + mState.mWebGLStencilAttachment.attach(context, type, binding, textureIndex, resource, + numViews, baseViewIndex, multiviewLayout, + viewportOffsets); + break; + default: + setAttachmentImpl(context, type, binding, textureIndex, resource, numViews, + baseViewIndex, multiviewLayout, viewportOffsets); + return; + } + + commitWebGL1DepthStencilIfConsistent(context, numViews, baseViewIndex, multiviewLayout, + viewportOffsets); +} + +void Framebuffer::setAttachmentMultiviewLayered(const Context *context, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei numViews, + GLint baseViewIndex) +{ + setAttachment(context, type, binding, textureIndex, resource, numViews, baseViewIndex, + GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE, + FramebufferAttachment::kDefaultViewportOffsets); +} + +void Framebuffer::setAttachmentMultiviewSideBySide(const Context *context, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei numViews, + const GLint *viewportOffsets) +{ + setAttachment(context, type, binding, textureIndex, resource, numViews, + FramebufferAttachment::kDefaultBaseViewIndex, + GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE, viewportOffsets); +} + +void Framebuffer::commitWebGL1DepthStencilIfConsistent(const Context *context, + GLsizei numViews, + GLuint baseViewIndex, + GLenum multiviewLayout, + const GLint *viewportOffsets) +{ + int count = 0; + + std::array attachments = {{&mState.mWebGLDepthStencilAttachment, + &mState.mWebGLDepthAttachment, + &mState.mWebGLStencilAttachment}}; + for (FramebufferAttachment *attachment : attachments) + { + if (attachment->isAttached()) + { + count++; + } + } + + mState.mWebGLDepthStencilConsistent = (count <= 1); + if (!mState.mWebGLDepthStencilConsistent) + { + // Inconsistent. + return; + } + + auto getImageIndexIfTextureAttachment = [](const FramebufferAttachment &attachment) { + if (attachment.type() == GL_TEXTURE) + { + return attachment.getTextureImageIndex(); + } + else + { + return ImageIndex::MakeInvalid(); + } + }; + + if (mState.mWebGLDepthAttachment.isAttached()) + { + const auto &depth = mState.mWebGLDepthAttachment; + setAttachmentImpl(context, depth.type(), GL_DEPTH_ATTACHMENT, + getImageIndexIfTextureAttachment(depth), depth.getResource(), numViews, + baseViewIndex, multiviewLayout, viewportOffsets); + setAttachmentImpl(context, GL_NONE, GL_STENCIL_ATTACHMENT, ImageIndex::MakeInvalid(), + nullptr, numViews, baseViewIndex, multiviewLayout, viewportOffsets); + } + else if (mState.mWebGLStencilAttachment.isAttached()) + { + const auto &stencil = mState.mWebGLStencilAttachment; + setAttachmentImpl(context, GL_NONE, GL_DEPTH_ATTACHMENT, ImageIndex::MakeInvalid(), nullptr, + numViews, baseViewIndex, multiviewLayout, viewportOffsets); + setAttachmentImpl(context, stencil.type(), GL_STENCIL_ATTACHMENT, + getImageIndexIfTextureAttachment(stencil), stencil.getResource(), + numViews, baseViewIndex, multiviewLayout, viewportOffsets); + } + else if (mState.mWebGLDepthStencilAttachment.isAttached()) + { + const auto &depthStencil = mState.mWebGLDepthStencilAttachment; + setAttachmentImpl(context, depthStencil.type(), GL_DEPTH_ATTACHMENT, + getImageIndexIfTextureAttachment(depthStencil), + depthStencil.getResource(), numViews, baseViewIndex, multiviewLayout, + viewportOffsets); + setAttachmentImpl(context, depthStencil.type(), GL_STENCIL_ATTACHMENT, + getImageIndexIfTextureAttachment(depthStencil), + depthStencil.getResource(), numViews, baseViewIndex, multiviewLayout, + viewportOffsets); } else { - switch (binding) + setAttachmentImpl(context, GL_NONE, GL_DEPTH_ATTACHMENT, ImageIndex::MakeInvalid(), nullptr, + numViews, baseViewIndex, multiviewLayout, viewportOffsets); + setAttachmentImpl(context, GL_NONE, GL_STENCIL_ATTACHMENT, ImageIndex::MakeInvalid(), + nullptr, numViews, baseViewIndex, multiviewLayout, viewportOffsets); + } +} + +void Framebuffer::setAttachmentImpl(const Context *context, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei numViews, + GLuint baseViewIndex, + GLenum multiviewLayout, + const GLint *viewportOffsets) +{ + switch (binding) + { + case GL_DEPTH_STENCIL: + case GL_DEPTH_STENCIL_ATTACHMENT: { - case GL_DEPTH: - case GL_DEPTH_ATTACHMENT: - mData.mDepthAttachment.attach(type, binding, textureIndex, resource); - mDirtyBits.set(DIRTY_BIT_DEPTH_ATTACHMENT); - break; - case GL_STENCIL: - case GL_STENCIL_ATTACHMENT: - mData.mStencilAttachment.attach(type, binding, textureIndex, resource); - mDirtyBits.set(DIRTY_BIT_STENCIL_ATTACHMENT); - break; - case GL_BACK: - mData.mColorAttachments[0].attach(type, binding, textureIndex, resource); - mDirtyBits.set(DIRTY_BIT_COLOR_ATTACHMENT_0); - break; - default: + // ensure this is a legitimate depth+stencil format + FramebufferAttachmentObject *attachmentObj = resource; + if (resource) { - size_t colorIndex = binding - GL_COLOR_ATTACHMENT0; - ASSERT(colorIndex < mData.mColorAttachments.size()); - mData.mColorAttachments[colorIndex].attach(type, binding, textureIndex, resource); - mDirtyBits.set(DIRTY_BIT_COLOR_ATTACHMENT_0 + colorIndex); + const Format &format = resource->getAttachmentFormat(binding, textureIndex); + if (format.info->depthBits == 0 || format.info->stencilBits == 0) + { + // Attaching nullptr detaches the current attachment. + attachmentObj = nullptr; + } } + + updateAttachment(context, &mState.mDepthAttachment, DIRTY_BIT_DEPTH_ATTACHMENT, + &mDirtyDepthAttachmentBinding, type, binding, textureIndex, + attachmentObj, numViews, baseViewIndex, multiviewLayout, + viewportOffsets); + updateAttachment(context, &mState.mStencilAttachment, DIRTY_BIT_STENCIL_ATTACHMENT, + &mDirtyStencilAttachmentBinding, type, binding, textureIndex, + attachmentObj, numViews, baseViewIndex, multiviewLayout, + viewportOffsets); break; } + + case GL_DEPTH: + case GL_DEPTH_ATTACHMENT: + updateAttachment(context, &mState.mDepthAttachment, DIRTY_BIT_DEPTH_ATTACHMENT, + &mDirtyDepthAttachmentBinding, type, binding, textureIndex, resource, + numViews, baseViewIndex, multiviewLayout, viewportOffsets); + break; + + case GL_STENCIL: + case GL_STENCIL_ATTACHMENT: + updateAttachment(context, &mState.mStencilAttachment, DIRTY_BIT_STENCIL_ATTACHMENT, + &mDirtyStencilAttachmentBinding, type, binding, textureIndex, resource, + numViews, baseViewIndex, multiviewLayout, viewportOffsets); + break; + + case GL_BACK: + mState.mColorAttachments[0].attach(context, type, binding, textureIndex, resource, + numViews, baseViewIndex, multiviewLayout, + viewportOffsets); + mDirtyBits.set(DIRTY_BIT_COLOR_ATTACHMENT_0); + // No need for a resource binding for the default FBO, it's always complete. + break; + + default: + { + size_t colorIndex = binding - GL_COLOR_ATTACHMENT0; + ASSERT(colorIndex < mState.mColorAttachments.size()); + size_t dirtyBit = DIRTY_BIT_COLOR_ATTACHMENT_0 + colorIndex; + updateAttachment(context, &mState.mColorAttachments[colorIndex], dirtyBit, + &mDirtyColorAttachmentBindings[colorIndex], type, binding, + textureIndex, resource, numViews, baseViewIndex, multiviewLayout, + viewportOffsets); + + // TODO(jmadill): ASSERT instead of checking the attachment exists in + // formsRenderingFeedbackLoopWith + bool enabled = (type != GL_NONE && getDrawBufferState(colorIndex) != GL_NONE); + mState.mEnabledDrawBuffers.set(colorIndex, enabled); + } + break; + } + + mAttachedTextures.reset(); +} + +void Framebuffer::updateAttachment(const Context *context, + FramebufferAttachment *attachment, + size_t dirtyBit, + OnAttachmentDirtyBinding *onDirtyBinding, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei numViews, + GLuint baseViewIndex, + GLenum multiviewLayout, + const GLint *viewportOffsets) +{ + attachment->attach(context, type, binding, textureIndex, resource, numViews, baseViewIndex, + multiviewLayout, viewportOffsets); + mDirtyBits.set(dirtyBit); + mState.mResourceNeedsInit.set(dirtyBit, attachment->initState() == InitState::MayNeedInit); + BindResourceChannel(onDirtyBinding, resource); +} + +void Framebuffer::resetAttachment(const Context *context, GLenum binding) +{ + setAttachment(context, GL_NONE, binding, ImageIndex::MakeInvalid(), nullptr); +} + +void Framebuffer::syncState(const Context *context) +{ + if (mDirtyBits.any()) + { + mImpl->syncState(context, mDirtyBits); + mDirtyBits.reset(); + if (mId != 0) + { + mCachedStatus.reset(); + } } } -void Framebuffer::resetAttachment(GLenum binding) +void Framebuffer::signal(size_t dirtyBit, InitState state) { - setAttachment(GL_NONE, binding, ImageIndex::MakeInvalid(), nullptr); + // TOOD(jmadill): Make this only update individual attachments to do less work. + mCachedStatus.reset(); + + // Mark the appropriate init flag. + mState.mResourceNeedsInit.set(dirtyBit, state == InitState::MayNeedInit); } -void Framebuffer::syncState() const +bool Framebuffer::complete(const Context *context) { - if (mDirtyBits.any()) + return (checkStatus(context) == GL_FRAMEBUFFER_COMPLETE); +} + +bool Framebuffer::cachedComplete() const +{ + return (mCachedStatus.valid() && mCachedStatus == GL_FRAMEBUFFER_COMPLETE); +} + +bool Framebuffer::formsRenderingFeedbackLoopWith(const State &state) const +{ + const Program *program = state.getProgram(); + + // TODO(jmadill): Default framebuffer feedback loops. + if (mId == 0) { - mImpl->syncState(mDirtyBits); - mDirtyBits.reset(); + return false; + } + + // The bitset will skip inactive draw buffers. + for (size_t drawIndex : mState.mEnabledDrawBuffers) + { + const FramebufferAttachment &attachment = mState.mColorAttachments[drawIndex]; + ASSERT(attachment.isAttached()); + if (attachment.type() == GL_TEXTURE) + { + // Validate the feedback loop. + if (program->samplesFromTexture(state, attachment.id())) + { + return true; + } + } + } + + // Validate depth-stencil feedback loop. + const auto &dsState = state.getDepthStencilState(); + + // We can skip the feedback loop checks if depth/stencil is masked out or disabled. + const FramebufferAttachment *depth = getDepthbuffer(); + if (depth && depth->type() == GL_TEXTURE && dsState.depthTest && dsState.depthMask) + { + if (program->samplesFromTexture(state, depth->id())) + { + return true; + } + } + + // Note: we assume the front and back masks are the same for WebGL. + const FramebufferAttachment *stencil = getStencilbuffer(); + ASSERT(dsState.stencilBackWritemask == dsState.stencilWritemask); + if (stencil && stencil->type() == GL_TEXTURE && dsState.stencilTest && + dsState.stencilWritemask != 0) + { + // Skip the feedback loop check if depth/stencil point to the same resource. + if (!depth || *stencil != *depth) + { + if (program->samplesFromTexture(state, stencil->id())) + { + return true; + } + } + } + + return false; +} + +bool Framebuffer::formsCopyingFeedbackLoopWith(GLuint copyTextureID, + GLint copyTextureLevel, + GLint copyTextureLayer) const +{ + if (mId == 0) + { + // It seems impossible to form a texture copying feedback loop with the default FBO. + return false; + } + + const FramebufferAttachment *readAttachment = getReadColorbuffer(); + ASSERT(readAttachment); + + if (readAttachment->isTextureWithId(copyTextureID)) + { + const auto &imageIndex = readAttachment->getTextureImageIndex(); + if (imageIndex.mipIndex == copyTextureLevel) + { + // Check 3D/Array texture layers. + return imageIndex.layerIndex == ImageIndex::ENTIRE_LEVEL || + copyTextureLayer == ImageIndex::ENTIRE_LEVEL || + imageIndex.layerIndex == copyTextureLayer; + } + } + return false; +} + +GLint Framebuffer::getDefaultWidth() const +{ + return mState.getDefaultWidth(); +} + +GLint Framebuffer::getDefaultHeight() const +{ + return mState.getDefaultHeight(); +} + +GLint Framebuffer::getDefaultSamples() const +{ + return mState.getDefaultSamples(); +} + +bool Framebuffer::getDefaultFixedSampleLocations() const +{ + return mState.getDefaultFixedSampleLocations(); +} + +void Framebuffer::setDefaultWidth(GLint defaultWidth) +{ + mState.mDefaultWidth = defaultWidth; + mDirtyBits.set(DIRTY_BIT_DEFAULT_WIDTH); +} + +void Framebuffer::setDefaultHeight(GLint defaultHeight) +{ + mState.mDefaultHeight = defaultHeight; + mDirtyBits.set(DIRTY_BIT_DEFAULT_HEIGHT); +} + +void Framebuffer::setDefaultSamples(GLint defaultSamples) +{ + mState.mDefaultSamples = defaultSamples; + mDirtyBits.set(DIRTY_BIT_DEFAULT_SAMPLES); +} + +void Framebuffer::setDefaultFixedSampleLocations(bool defaultFixedSampleLocations) +{ + mState.mDefaultFixedSampleLocations = defaultFixedSampleLocations; + mDirtyBits.set(DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS); +} + +// TODO(jmadill): Remove this kludge. +GLenum Framebuffer::checkStatus(const ValidationContext *context) +{ + return checkStatus(static_cast(context)); +} + +int Framebuffer::getSamples(const ValidationContext *context) +{ + return getSamples(static_cast(context)); +} + +GLsizei Framebuffer::getNumViews() const +{ + return mState.getNumViews(); +} + +GLint Framebuffer::getBaseViewIndex() const +{ + return mState.getBaseViewIndex(); +} + +const std::vector *Framebuffer::getViewportOffsets() const +{ + return mState.getViewportOffsets(); +} + +GLenum Framebuffer::getMultiviewLayout() const +{ + return mState.getMultiviewLayout(); +} + +Error Framebuffer::ensureDrawAttachmentsInitialized(const Context *context) +{ + if (!context->isRobustResourceInitEnabled()) + { + return NoError(); + } + + // Note: we don't actually filter by the draw attachment enum. Just init everything. + for (size_t bit : mState.mResourceNeedsInit) + { + switch (bit) + { + case DIRTY_BIT_DEPTH_ATTACHMENT: + ANGLE_TRY(InitAttachment(context, &mState.mDepthAttachment)); + break; + case DIRTY_BIT_STENCIL_ATTACHMENT: + ANGLE_TRY(InitAttachment(context, &mState.mStencilAttachment)); + break; + default: + ANGLE_TRY(InitAttachment(context, &mState.mColorAttachments[bit])); + break; + } + } + + mState.mResourceNeedsInit.reset(); + return NoError(); +} + +Error Framebuffer::ensureReadAttachmentInitialized(const Context *context, GLbitfield blitMask) +{ + if (!context->isRobustResourceInitEnabled() || mState.mResourceNeedsInit.none()) + { + return NoError(); + } + + if ((blitMask & GL_COLOR_BUFFER_BIT) != 0 && mState.mReadBufferState != GL_NONE) + { + size_t readIndex = mState.getReadIndex(); + if (mState.mResourceNeedsInit[readIndex]) + { + ANGLE_TRY(InitAttachment(context, &mState.mColorAttachments[readIndex])); + mState.mResourceNeedsInit.reset(readIndex); + } + } + + if ((blitMask & GL_DEPTH_BUFFER_BIT) != 0 && hasDepth()) + { + if (mState.mResourceNeedsInit[DIRTY_BIT_DEPTH_ATTACHMENT]) + { + ANGLE_TRY(InitAttachment(context, &mState.mDepthAttachment)); + mState.mResourceNeedsInit.reset(DIRTY_BIT_DEPTH_ATTACHMENT); + } + } + + if ((blitMask & GL_STENCIL_BUFFER_BIT) != 0 && hasStencil()) + { + if (mState.mResourceNeedsInit[DIRTY_BIT_STENCIL_ATTACHMENT]) + { + ANGLE_TRY(InitAttachment(context, &mState.mStencilAttachment)); + mState.mResourceNeedsInit.reset(DIRTY_BIT_STENCIL_ATTACHMENT); + } + } + + return NoError(); +} + +void Framebuffer::markDrawAttachmentsInitialized(bool color, bool depth, bool stencil) +{ + // Mark attachments as initialized. + if (color) + { + for (auto colorIndex : mState.mEnabledDrawBuffers) + { + auto &colorAttachment = mState.mColorAttachments[colorIndex]; + ASSERT(colorAttachment.isAttached()); + colorAttachment.setInitState(InitState::Initialized); + mState.mResourceNeedsInit.reset(colorIndex); + } + } + + if (depth && mState.mDepthAttachment.isAttached()) + { + mState.mDepthAttachment.setInitState(InitState::Initialized); + mState.mResourceNeedsInit.reset(DIRTY_BIT_DEPTH_ATTACHMENT); + } + + if (stencil && mState.mStencilAttachment.isAttached()) + { + mState.mStencilAttachment.setInitState(InitState::Initialized); + mState.mResourceNeedsInit.reset(DIRTY_BIT_STENCIL_ATTACHMENT); } } +void Framebuffer::markBufferInitialized(GLenum bufferType, GLint bufferIndex) +{ + switch (bufferType) + { + case GL_COLOR: + { + ASSERT(bufferIndex < static_cast(mState.mColorAttachments.size())); + if (mState.mColorAttachments[bufferIndex].isAttached()) + { + mState.mColorAttachments[bufferIndex].setInitState(InitState::Initialized); + mState.mResourceNeedsInit.reset(bufferIndex); + } + break; + } + case GL_DEPTH: + { + if (mState.mDepthAttachment.isAttached()) + { + mState.mDepthAttachment.setInitState(InitState::Initialized); + mState.mResourceNeedsInit.reset(DIRTY_BIT_DEPTH_ATTACHMENT); + } + break; + } + case GL_STENCIL: + { + if (mState.mStencilAttachment.isAttached()) + { + mState.mStencilAttachment.setInitState(InitState::Initialized); + mState.mResourceNeedsInit.reset(DIRTY_BIT_STENCIL_ATTACHMENT); + } + break; + } + case GL_DEPTH_STENCIL: + { + if (mState.mDepthAttachment.isAttached()) + { + mState.mDepthAttachment.setInitState(InitState::Initialized); + mState.mResourceNeedsInit.reset(DIRTY_BIT_DEPTH_ATTACHMENT); + } + if (mState.mStencilAttachment.isAttached()) + { + mState.mStencilAttachment.setInitState(InitState::Initialized); + mState.mResourceNeedsInit.reset(DIRTY_BIT_STENCIL_ATTACHMENT); + } + break; + } + default: + UNREACHABLE(); + break; + } +} + +Box Framebuffer::getDimensions() const +{ + return mState.getDimensions(); +} + +Error Framebuffer::ensureBufferInitialized(const Context *context, + GLenum bufferType, + GLint bufferIndex) +{ + ASSERT(context->isRobustResourceInitEnabled()); + + if (mState.mResourceNeedsInit.none()) + { + return NoError(); + } + + switch (bufferType) + { + case GL_COLOR: + { + ASSERT(bufferIndex < static_cast(mState.mColorAttachments.size())); + if (mState.mResourceNeedsInit[bufferIndex]) + { + ANGLE_TRY(InitAttachment(context, &mState.mColorAttachments[bufferIndex])); + mState.mResourceNeedsInit.reset(bufferIndex); + } + break; + } + case GL_DEPTH: + { + if (mState.mResourceNeedsInit[DIRTY_BIT_DEPTH_ATTACHMENT]) + { + ANGLE_TRY(InitAttachment(context, &mState.mDepthAttachment)); + mState.mResourceNeedsInit.reset(DIRTY_BIT_DEPTH_ATTACHMENT); + } + break; + } + case GL_STENCIL: + { + if (mState.mResourceNeedsInit[DIRTY_BIT_STENCIL_ATTACHMENT]) + { + ANGLE_TRY(InitAttachment(context, &mState.mStencilAttachment)); + mState.mResourceNeedsInit.reset(DIRTY_BIT_STENCIL_ATTACHMENT); + } + break; + } + case GL_DEPTH_STENCIL: + { + if (mState.mResourceNeedsInit[DIRTY_BIT_DEPTH_ATTACHMENT]) + { + ANGLE_TRY(InitAttachment(context, &mState.mDepthAttachment)); + mState.mResourceNeedsInit.reset(DIRTY_BIT_DEPTH_ATTACHMENT); + } + if (mState.mResourceNeedsInit[DIRTY_BIT_STENCIL_ATTACHMENT]) + { + ANGLE_TRY(InitAttachment(context, &mState.mStencilAttachment)); + mState.mResourceNeedsInit.reset(DIRTY_BIT_STENCIL_ATTACHMENT); + } + break; + } + default: + UNREACHABLE(); + break; + } + + return NoError(); +} + +bool Framebuffer::partialBufferClearNeedsInit(const Context *context, GLenum bufferType) +{ + if (!context->isRobustResourceInitEnabled() || mState.mResourceNeedsInit.none()) + { + return false; + } + + switch (bufferType) + { + case GL_COLOR: + return partialClearNeedsInit(context, true, false, false); + case GL_DEPTH: + return partialClearNeedsInit(context, false, true, false); + case GL_STENCIL: + return partialClearNeedsInit(context, false, false, true); + case GL_DEPTH_STENCIL: + return partialClearNeedsInit(context, false, true, true); + default: + UNREACHABLE(); + return false; + } +} + +bool Framebuffer::hasTextureAttachment(const Texture *texture) const +{ + if (!mAttachedTextures.valid()) + { + std::set attachedTextures; + + for (const auto &colorAttachment : mState.mColorAttachments) + { + if (colorAttachment.isAttached() && colorAttachment.type() == GL_TEXTURE) + { + attachedTextures.insert(colorAttachment.getResource()); + } + } + + if (mState.mDepthAttachment.isAttached() && mState.mDepthAttachment.type() == GL_TEXTURE) + { + attachedTextures.insert(mState.mDepthAttachment.getResource()); + } + + if (mState.mStencilAttachment.isAttached() && + mState.mStencilAttachment.type() == GL_TEXTURE) + { + attachedTextures.insert(mState.mStencilAttachment.getResource()); + } + + mAttachedTextures = std::move(attachedTextures); + } + + return (mAttachedTextures.value().count(texture) > 0); +} + } // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/Framebuffer.h b/src/3rdparty/angle/src/libANGLE/Framebuffer.h index b07b59ac90..70223f0bc7 100644 --- a/src/3rdparty/angle/src/libANGLE/Framebuffer.h +++ b/src/3rdparty/angle/src/libANGLE/Framebuffer.h @@ -12,16 +12,18 @@ #include +#include "common/Optional.h" #include "common/angleutils.h" #include "libANGLE/Constants.h" #include "libANGLE/Debug.h" #include "libANGLE/Error.h" #include "libANGLE/FramebufferAttachment.h" #include "libANGLE/RefCountObject.h" +#include "libANGLE/signal_utils.h" namespace rx { -class ImplFactory; +class GLImplFactory; class FramebufferImpl; class RenderbufferImpl; class SurfaceImpl; @@ -29,98 +31,171 @@ class SurfaceImpl; namespace egl { +class Display; class Surface; } namespace gl { class Context; +class ContextState; +class Framebuffer; class Renderbuffer; class State; class Texture; class TextureCapsMap; +class ValidationContext; struct Caps; -struct Data; struct Extensions; struct ImageIndex; struct Rectangle; -class Framebuffer final : public LabeledObject +class FramebufferState final : angle::NonCopyable { public: + FramebufferState(); + explicit FramebufferState(const Caps &caps); + ~FramebufferState(); - class Data final : angle::NonCopyable + const std::string &getLabel(); + size_t getReadIndex() const; + + const FramebufferAttachment *getAttachment(GLenum attachment) const; + const FramebufferAttachment *getReadAttachment() const; + const FramebufferAttachment *getFirstNonNullAttachment() const; + const FramebufferAttachment *getFirstColorAttachment() const; + const FramebufferAttachment *getDepthOrStencilAttachment() const; + const FramebufferAttachment *getStencilOrDepthStencilAttachment() const; + const FramebufferAttachment *getColorAttachment(size_t colorAttachment) const; + const FramebufferAttachment *getDepthAttachment() const; + const FramebufferAttachment *getStencilAttachment() const; + const FramebufferAttachment *getDepthStencilAttachment() const; + + const std::vector &getDrawBufferStates() const { return mDrawBufferStates; } + DrawBufferMask getEnabledDrawBuffers() const { return mEnabledDrawBuffers; } + GLenum getReadBufferState() const { return mReadBufferState; } + const std::vector &getColorAttachments() const { - public: - explicit Data(); - explicit Data(const Caps &caps); - ~Data(); + return mColorAttachments; + } - const std::string &getLabel(); + bool attachmentsHaveSameDimensions() const; + bool colorAttachmentsAreUniqueImages() const; + Box getDimensions() const; - const FramebufferAttachment *getReadAttachment() const; - const FramebufferAttachment *getFirstColorAttachment() const; - const FramebufferAttachment *getDepthOrStencilAttachment() const; - const FramebufferAttachment *getColorAttachment(size_t colorAttachment) const; - const FramebufferAttachment *getDepthAttachment() const; - const FramebufferAttachment *getStencilAttachment() const; - const FramebufferAttachment *getDepthStencilAttachment() const; + const FramebufferAttachment *getDrawBuffer(size_t drawBufferIdx) const; + size_t getDrawBufferCount() const; - const std::vector &getDrawBufferStates() const { return mDrawBufferStates; } - GLenum getReadBufferState() const { return mReadBufferState; } - const std::vector &getColorAttachments() const { return mColorAttachments; } + GLint getDefaultWidth() const { return mDefaultWidth; }; + GLint getDefaultHeight() const { return mDefaultHeight; }; + GLint getDefaultSamples() const { return mDefaultSamples; }; + bool getDefaultFixedSampleLocations() const { return mDefaultFixedSampleLocations; }; - bool attachmentsHaveSameDimensions() const; + bool hasDepth() const; + bool hasStencil() const; - private: - friend class Framebuffer; + GLenum getMultiviewLayout() const; + GLsizei getNumViews() const; + const std::vector *getViewportOffsets() const; + GLint getBaseViewIndex() const; - std::string mLabel; + private: + friend class Framebuffer; - std::vector mColorAttachments; - FramebufferAttachment mDepthAttachment; - FramebufferAttachment mStencilAttachment; + std::string mLabel; - std::vector mDrawBufferStates; - GLenum mReadBufferState; - }; + std::vector mColorAttachments; + FramebufferAttachment mDepthAttachment; + FramebufferAttachment mStencilAttachment; - Framebuffer(const Caps &caps, rx::ImplFactory *factory, GLuint id); - Framebuffer(rx::SurfaceImpl *surface); - virtual ~Framebuffer(); + std::vector mDrawBufferStates; + GLenum mReadBufferState; + DrawBufferMask mEnabledDrawBuffers; + + GLint mDefaultWidth; + GLint mDefaultHeight; + GLint mDefaultSamples; + bool mDefaultFixedSampleLocations; + + // It's necessary to store all this extra state so we can restore attachments + // when DEPTH_STENCIL/DEPTH/STENCIL is unbound in WebGL 1. + FramebufferAttachment mWebGLDepthStencilAttachment; + FramebufferAttachment mWebGLDepthAttachment; + FramebufferAttachment mWebGLStencilAttachment; + bool mWebGLDepthStencilConsistent; + + // Tracks if we need to initialize the resources for each attachment. + angle::BitSet mResourceNeedsInit; +}; + +class Framebuffer final : public LabeledObject, public OnAttachmentDirtyReceiver +{ + public: + // Constructor to build application-defined framebuffers + Framebuffer(const Caps &caps, rx::GLImplFactory *factory, GLuint id); + // Constructor to build default framebuffers for a surface + Framebuffer(const egl::Display *display, egl::Surface *surface); + // Constructor to build a fake default framebuffer when surfaceless + Framebuffer(rx::GLImplFactory *factory); + + ~Framebuffer() override; + void onDestroy(const Context *context); + void destroyDefault(const egl::Display *display); void setLabel(const std::string &label) override; const std::string &getLabel() const override; - const rx::FramebufferImpl *getImplementation() const { return mImpl; } - rx::FramebufferImpl *getImplementation() { return mImpl; } + rx::FramebufferImpl *getImplementation() const { return mImpl; } GLuint id() const { return mId; } - void setAttachment(GLenum type, + void setAttachment(const Context *context, + GLenum type, GLenum binding, const ImageIndex &textureIndex, FramebufferAttachmentObject *resource); - void resetAttachment(GLenum binding); + void setAttachmentMultiviewLayered(const Context *context, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei numViews, + GLint baseViewIndex); + void setAttachmentMultiviewSideBySide(const Context *context, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei numViews, + const GLint *viewportOffsets); + void resetAttachment(const Context *context, GLenum binding); - void detachTexture(GLuint texture); - void detachRenderbuffer(GLuint renderbuffer); + bool detachTexture(const Context *context, GLuint texture); + bool detachRenderbuffer(const Context *context, GLuint renderbuffer); const FramebufferAttachment *getColorbuffer(size_t colorAttachment) const; const FramebufferAttachment *getDepthbuffer() const; const FramebufferAttachment *getStencilbuffer() const; const FramebufferAttachment *getDepthStencilBuffer() const; const FramebufferAttachment *getDepthOrStencilbuffer() const; + const FramebufferAttachment *getStencilOrDepthStencilAttachment() const; const FramebufferAttachment *getReadColorbuffer() const; GLenum getReadColorbufferType() const; const FramebufferAttachment *getFirstColorbuffer() const; + const FramebufferAttachment *getFirstNonNullAttachment() const; const FramebufferAttachment *getAttachment(GLenum attachment) const; + GLenum getMultiviewLayout() const; + GLsizei getNumViews() const; + GLint getBaseViewIndex() const; + const std::vector *getViewportOffsets() const; size_t getDrawbufferStateCount() const; GLenum getDrawBufferState(size_t drawBuffer) const; + const std::vector &getDrawBufferStates() const; void setDrawBuffers(size_t count, const GLenum *buffers); const FramebufferAttachment *getDrawBuffer(size_t drawBuffer) const; + GLenum getDrawbufferWriteType(size_t drawBuffer) const; bool hasEnabledDrawBuffer() const; GLenum getReadBufferState() const; @@ -129,48 +204,81 @@ class Framebuffer final : public LabeledObject size_t getNumColorBuffers() const; bool hasDepth() const; bool hasStencil() const; - int getSamples(const gl::Data &data) const; + bool usingExtendedDrawBuffers() const; - GLenum checkStatus(const gl::Data &data) const; + // This method calls checkStatus. + int getSamples(const Context *context); + + Error getSamplePosition(size_t index, GLfloat *xy) const; + + GLint getDefaultWidth() const; + GLint getDefaultHeight() const; + GLint getDefaultSamples() const; + bool getDefaultFixedSampleLocations() const; + void setDefaultWidth(GLint defaultWidth); + void setDefaultHeight(GLint defaultHeight); + void setDefaultSamples(GLint defaultSamples); + void setDefaultFixedSampleLocations(bool defaultFixedSampleLocations); + + void invalidateCompletenessCache(); + + GLenum checkStatus(const Context *context); + + // TODO(jmadill): Remove this kludge. + GLenum checkStatus(const ValidationContext *context); + int getSamples(const ValidationContext *context); + + // For when we don't want to check completeness in getSamples(). + int getCachedSamples(const Context *context); + + // Helper for checkStatus == GL_FRAMEBUFFER_COMPLETE. + bool complete(const Context *context); + bool cachedComplete() const; + bool hasValidDepthStencil() const; - Error discard(size_t count, const GLenum *attachments); - Error invalidate(size_t count, const GLenum *attachments); - Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area); + Error discard(const Context *context, size_t count, const GLenum *attachments); + Error invalidate(const Context *context, size_t count, const GLenum *attachments); + Error invalidateSub(const Context *context, + size_t count, + const GLenum *attachments, + const gl::Rectangle &area); - Error clear(const gl::Data &data, GLbitfield mask); - Error clearBufferfv(const gl::Data &data, + Error clear(const gl::Context *context, GLbitfield mask); + Error clearBufferfv(const gl::Context *context, GLenum buffer, GLint drawbuffer, const GLfloat *values); - Error clearBufferuiv(const gl::Data &data, + Error clearBufferuiv(const gl::Context *context, GLenum buffer, GLint drawbuffer, const GLuint *values); - Error clearBufferiv(const gl::Data &data, GLenum buffer, GLint drawbuffer, const GLint *values); - Error clearBufferfi(const gl::Data &data, + Error clearBufferiv(const gl::Context *context, + GLenum buffer, + GLint drawbuffer, + const GLint *values); + Error clearBufferfi(const gl::Context *context, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); - GLenum getImplementationColorReadFormat() const; - GLenum getImplementationColorReadType() const; - Error readPixels(const gl::State &state, + GLenum getImplementationColorReadFormat(const Context *context) const; + GLenum getImplementationColorReadType(const Context *context) const; + Error readPixels(const gl::Context *context, const gl::Rectangle &area, GLenum format, GLenum type, - GLvoid *pixels) const; + void *pixels); - Error blit(const State &state, + Error blit(const gl::Context *context, const Rectangle &sourceArea, const Rectangle &destArea, GLbitfield mask, - GLenum filter, - const Framebuffer *sourceFramebuffer); + GLenum filter); - enum DirtyBitType + enum DirtyBitType : size_t { DIRTY_BIT_COLOR_ATTACHMENT_0, DIRTY_BIT_COLOR_ATTACHMENT_MAX = @@ -179,26 +287,103 @@ class Framebuffer final : public LabeledObject DIRTY_BIT_STENCIL_ATTACHMENT, DIRTY_BIT_DRAW_BUFFERS, DIRTY_BIT_READ_BUFFER, + DIRTY_BIT_DEFAULT_WIDTH, + DIRTY_BIT_DEFAULT_HEIGHT, + DIRTY_BIT_DEFAULT_SAMPLES, + DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS, DIRTY_BIT_UNKNOWN, - DIRTY_BIT_MAX = DIRTY_BIT_UNKNOWN, + DIRTY_BIT_MAX = DIRTY_BIT_UNKNOWN }; - typedef std::bitset DirtyBits; + typedef angle::BitSet DirtyBits; bool hasAnyDirtyBit() const { return mDirtyBits.any(); } - void syncState() const; + void syncState(const Context *context); - protected: - void detachResourceById(GLenum resourceType, GLuint resourceId); + // OnAttachmentChangedReceiver implementation + void signal(size_t dirtyBit, InitState state) override; - Data mData; + bool formsRenderingFeedbackLoopWith(const State &state) const; + bool formsCopyingFeedbackLoopWith(GLuint copyTextureID, + GLint copyTextureLevel, + GLint copyTextureLayer) const; + + Error ensureDrawAttachmentsInitialized(const Context *context); + Error ensureReadAttachmentInitialized(const Context *context, GLbitfield blitMask); + Box getDimensions() const; + + bool hasTextureAttachment(const Texture *texture) const; + + private: + bool detachResourceById(const Context *context, GLenum resourceType, GLuint resourceId); + bool detachMatchingAttachment(const Context *context, + FramebufferAttachment *attachment, + GLenum matchType, + GLuint matchId, + size_t dirtyBit); + GLenum checkStatusImpl(const Context *context); + void setAttachment(const Context *context, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei numViews, + GLuint baseViewIndex, + GLenum multiviewLayout, + const GLint *viewportOffsets); + void commitWebGL1DepthStencilIfConsistent(const Context *context, + GLsizei numViews, + GLuint baseViewIndex, + GLenum multiviewLayout, + const GLint *viewportOffsets); + void setAttachmentImpl(const Context *context, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei numViews, + GLuint baseViewIndex, + GLenum multiviewLayout, + const GLint *viewportOffsets); + void updateAttachment(const Context *context, + FramebufferAttachment *attachment, + size_t dirtyBit, + OnAttachmentDirtyBinding *onDirtyBinding, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei numViews, + GLuint baseViewIndex, + GLenum multiviewLayout, + const GLint *viewportOffsets); + + void markDrawAttachmentsInitialized(bool color, bool depth, bool stencil); + void markBufferInitialized(GLenum bufferType, GLint bufferIndex); + Error ensureBufferInitialized(const Context *context, GLenum bufferType, GLint bufferIndex); + + // Checks that we have a partially masked clear: + // * some color channels are masked out + // * some stencil values are masked out + // * scissor test partially overlaps the framebuffer + bool partialClearNeedsInit(const Context *context, bool color, bool depth, bool stencil); + bool partialBufferClearNeedsInit(const Context *context, GLenum bufferType); + + FramebufferState mState; rx::FramebufferImpl *mImpl; GLuint mId; - // TODO(jmadill): See if we can make this non-mutable. - mutable DirtyBits mDirtyBits; + Optional mCachedStatus; + std::vector mDirtyColorAttachmentBindings; + OnAttachmentDirtyBinding mDirtyDepthAttachmentBinding; + OnAttachmentDirtyBinding mDirtyStencilAttachmentBinding; + + DirtyBits mDirtyBits; + + // A cache of attached textures for quick validation of feedback loops. + mutable Optional> mAttachedTextures; }; -} +} // namespace gl -#endif // LIBANGLE_FRAMEBUFFER_H_ +#endif // LIBANGLE_FRAMEBUFFER_H_ diff --git a/src/3rdparty/angle/src/libANGLE/FramebufferAttachment.cpp b/src/3rdparty/angle/src/libANGLE/FramebufferAttachment.cpp index 352a326c23..cf6bd9c264 100644 --- a/src/3rdparty/angle/src/libANGLE/FramebufferAttachment.cpp +++ b/src/3rdparty/angle/src/libANGLE/FramebufferAttachment.cpp @@ -11,17 +11,48 @@ #include "common/utilities.h" #include "libANGLE/Config.h" +#include "libANGLE/Context.h" #include "libANGLE/Renderbuffer.h" #include "libANGLE/Surface.h" #include "libANGLE/Texture.h" #include "libANGLE/formatutils.h" +#include "libANGLE/renderer/FramebufferAttachmentObjectImpl.h" #include "libANGLE/renderer/FramebufferImpl.h" namespace gl { +namespace +{ + +std::vector TransformViewportOffsetArrayToVectorOfOffsets(const GLint *viewportOffsets, + GLsizei numViews) +{ + const size_t numViewsAsSizeT = static_cast(numViews); + std::vector offsetVector; + offsetVector.reserve(numViewsAsSizeT); + for (size_t i = 0u; i < numViewsAsSizeT; ++i) + { + offsetVector.emplace_back(Offset(viewportOffsets[i * 2u], viewportOffsets[i * 2u + 1u], 0)); + } + return offsetVector; +} + +} // namespace + ////// FramebufferAttachment::Target Implementation ////// +const GLsizei FramebufferAttachment::kDefaultNumViews = 1; +const GLenum FramebufferAttachment::kDefaultMultiviewLayout = GL_NONE; +const GLint FramebufferAttachment::kDefaultBaseViewIndex = 0; +const GLint FramebufferAttachment::kDefaultViewportOffsets[2] = {0}; + +std::vector FramebufferAttachment::GetDefaultViewportOffsetVector() +{ + return TransformViewportOffsetArrayToVectorOfOffsets( + FramebufferAttachment::kDefaultViewportOffsets, FramebufferAttachment::kDefaultNumViews); +} + FramebufferAttachment::Target::Target() : mBinding(GL_NONE), mTextureIndex(ImageIndex::MakeInvalid()) @@ -50,106 +81,143 @@ FramebufferAttachment::Target &FramebufferAttachment::Target::operator=(const Ta ////// FramebufferAttachment Implementation ////// FramebufferAttachment::FramebufferAttachment() - : mType(GL_NONE), mResource(nullptr) + : mType(GL_NONE), + mResource(nullptr), + mNumViews(kDefaultNumViews), + mMultiviewLayout(kDefaultMultiviewLayout), + mBaseViewIndex(kDefaultBaseViewIndex), + mViewportOffsets(GetDefaultViewportOffsetVector()) { } -FramebufferAttachment::FramebufferAttachment(GLenum type, +FramebufferAttachment::FramebufferAttachment(const Context *context, + GLenum type, GLenum binding, const ImageIndex &textureIndex, FramebufferAttachmentObject *resource) : mResource(nullptr) { - attach(type, binding, textureIndex, resource); + attach(context, type, binding, textureIndex, resource, kDefaultNumViews, kDefaultBaseViewIndex, + kDefaultMultiviewLayout, kDefaultViewportOffsets); } -FramebufferAttachment::FramebufferAttachment(const FramebufferAttachment &other) - : mResource(nullptr) +FramebufferAttachment::FramebufferAttachment(FramebufferAttachment &&other) + : FramebufferAttachment() { - attach(other.mType, other.mTarget.binding(), other.mTarget.textureIndex(), other.mResource); + *this = std::move(other); } -FramebufferAttachment &FramebufferAttachment::operator=(const FramebufferAttachment &other) +FramebufferAttachment &FramebufferAttachment::operator=(FramebufferAttachment &&other) { - attach(other.mType, other.mTarget.binding(), other.mTarget.textureIndex(), other.mResource); + std::swap(mType, other.mType); + std::swap(mTarget, other.mTarget); + std::swap(mResource, other.mResource); + std::swap(mNumViews, other.mNumViews); + std::swap(mMultiviewLayout, other.mMultiviewLayout); + std::swap(mBaseViewIndex, other.mBaseViewIndex); + std::swap(mViewportOffsets, other.mViewportOffsets); return *this; } FramebufferAttachment::~FramebufferAttachment() { - detach(); + ASSERT(!isAttached()); } -void FramebufferAttachment::detach() +void FramebufferAttachment::detach(const Context *context) { mType = GL_NONE; if (mResource != nullptr) { - mResource->onDetach(); + mResource->onDetach(context); mResource = nullptr; } + mNumViews = kDefaultNumViews; + mMultiviewLayout = kDefaultMultiviewLayout; + mBaseViewIndex = kDefaultBaseViewIndex; + mViewportOffsets = GetDefaultViewportOffsetVector(); // not technically necessary, could omit for performance mTarget = Target(); } -void FramebufferAttachment::attach(GLenum type, +void FramebufferAttachment::attach(const Context *context, + GLenum type, GLenum binding, const ImageIndex &textureIndex, - FramebufferAttachmentObject *resource) + FramebufferAttachmentObject *resource, + GLsizei numViews, + GLuint baseViewIndex, + GLenum multiviewLayout, + const GLint *viewportOffsets) { + if (resource == nullptr) + { + detach(context); + return; + } + mType = type; mTarget = Target(binding, textureIndex); - - if (resource) + mNumViews = numViews; + mBaseViewIndex = baseViewIndex; + mMultiviewLayout = multiviewLayout; + if (multiviewLayout == GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE) { - resource->onAttach(); + mViewportOffsets = TransformViewportOffsetArrayToVectorOfOffsets(viewportOffsets, numViews); } + else + { + mViewportOffsets = GetDefaultViewportOffsetVector(); + } + resource->onAttach(context); + if (mResource != nullptr) { - mResource->onDetach(); + mResource->onDetach(context); } + mResource = resource; } GLuint FramebufferAttachment::getRedSize() const { - return GetInternalFormatInfo(getInternalFormat()).redBits; + return getFormat().info->redBits; } GLuint FramebufferAttachment::getGreenSize() const { - return GetInternalFormatInfo(getInternalFormat()).greenBits; + return getFormat().info->greenBits; } GLuint FramebufferAttachment::getBlueSize() const { - return GetInternalFormatInfo(getInternalFormat()).blueBits; + return getFormat().info->blueBits; } GLuint FramebufferAttachment::getAlphaSize() const { - return GetInternalFormatInfo(getInternalFormat()).alphaBits; + return getFormat().info->alphaBits; } GLuint FramebufferAttachment::getDepthSize() const { - return GetInternalFormatInfo(getInternalFormat()).depthBits; + return getFormat().info->depthBits; } GLuint FramebufferAttachment::getStencilSize() const { - return GetInternalFormatInfo(getInternalFormat()).stencilBits; + return getFormat().info->stencilBits; } GLenum FramebufferAttachment::getComponentType() const { - return GetInternalFormatInfo(getInternalFormat()).componentType; + return getFormat().info->componentType; } GLenum FramebufferAttachment::getColorEncoding() const { - return GetInternalFormatInfo(getInternalFormat()).colorEncoding; + return getFormat().info->colorEncoding; } GLuint FramebufferAttachment::id() const @@ -190,6 +258,26 @@ GLint FramebufferAttachment::layer() const return 0; } +GLsizei FramebufferAttachment::getNumViews() const +{ + return mNumViews; +} + +GLenum FramebufferAttachment::getMultiviewLayout() const +{ + return mMultiviewLayout; +} + +GLint FramebufferAttachment::getBaseViewIndex() const +{ + return mBaseViewIndex; +} + +const std::vector &FramebufferAttachment::getMultiviewViewportOffsets() const +{ + return mViewportOffsets; +} + Texture *FramebufferAttachment::getTexture() const { return rx::GetAs(mResource); @@ -205,4 +293,93 @@ const egl::Surface *FramebufferAttachment::getSurface() const return rx::GetAs(mResource); } +FramebufferAttachmentObject *FramebufferAttachment::getResource() const +{ + return mResource; } + +bool FramebufferAttachment::operator==(const FramebufferAttachment &other) const +{ + if (mResource != other.mResource || mType != other.mType || mNumViews != other.mNumViews || + mMultiviewLayout != other.mMultiviewLayout || mBaseViewIndex != other.mBaseViewIndex || + mViewportOffsets != other.mViewportOffsets) + { + return false; + } + + if (mType == GL_TEXTURE && getTextureImageIndex() != other.getTextureImageIndex()) + { + return false; + } + + return true; +} + +bool FramebufferAttachment::operator!=(const FramebufferAttachment &other) const +{ + return !(*this == other); +} + +InitState FramebufferAttachment::initState() const +{ + return mResource ? mResource->initState(mTarget.textureIndex()) : InitState::Initialized; +} + +Error FramebufferAttachment::initializeContents(const Context *context) +{ + ASSERT(mResource); + ANGLE_TRY(mResource->initializeContents(context, mTarget.textureIndex())); + setInitState(InitState::Initialized); + return NoError(); +} + +void FramebufferAttachment::setInitState(InitState initState) const +{ + ASSERT(mResource); + mResource->setInitState(mTarget.textureIndex(), initState); +} + +////// FramebufferAttachmentObject Implementation ////// + +FramebufferAttachmentObject::FramebufferAttachmentObject() +{ +} + +FramebufferAttachmentObject::~FramebufferAttachmentObject() +{ +} + +Error FramebufferAttachmentObject::getAttachmentRenderTarget( + const Context *context, + GLenum binding, + const ImageIndex &imageIndex, + rx::FramebufferAttachmentRenderTarget **rtOut) const +{ + return getAttachmentImpl()->getAttachmentRenderTarget(context, binding, imageIndex, rtOut); +} + +OnAttachmentDirtyChannel *FramebufferAttachmentObject::getDirtyChannel() +{ + return &mDirtyChannel; +} + +Error FramebufferAttachmentObject::initializeContents(const Context *context, + const ImageIndex &imageIndex) +{ + ASSERT(context->isRobustResourceInitEnabled()); + + // Because gl::Texture cannot support tracking individual layer dirtiness, we only handle + // initializing entire mip levels for 2D array textures. + if (imageIndex.type == GL_TEXTURE_2D_ARRAY && imageIndex.hasLayer()) + { + ImageIndex fullMipIndex = imageIndex; + fullMipIndex.layerIndex = ImageIndex::ENTIRE_LEVEL; + return getAttachmentImpl()->initializeContents(context, fullMipIndex); + } + else + { + return getAttachmentImpl()->initializeContents(context, imageIndex); + } +} + +} // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/FramebufferAttachment.h b/src/3rdparty/angle/src/libANGLE/FramebufferAttachment.h index 33196f5c61..5c0553a1d4 100644 --- a/src/3rdparty/angle/src/libANGLE/FramebufferAttachment.h +++ b/src/3rdparty/angle/src/libANGLE/FramebufferAttachment.h @@ -15,6 +15,7 @@ #include "libANGLE/angletypes.h" #include "libANGLE/Error.h" #include "libANGLE/ImageIndex.h" +#include "libANGLE/signal_utils.h" namespace egl { @@ -38,9 +39,20 @@ class FramebufferAttachmentObjectImpl; namespace gl { class FramebufferAttachmentObject; +struct Format; class Renderbuffer; class Texture; +enum class InitState +{ + MayNeedInit, + Initialized, +}; + +using OnAttachmentDirtyBinding = angle::ChannelBinding; +using OnAttachmentDirtyChannel = angle::BroadcastChannel; +using OnAttachmentDirtyReceiver = angle::SignalReceiver; + // FramebufferAttachment implements a GL framebuffer attachment. // Attachments are "light" containers, which store pointers to ref-counted GL objects. // We support GL texture (2D/3D/Cube/2D array) and renderbuffer object attachments. @@ -52,16 +64,94 @@ class FramebufferAttachment final public: FramebufferAttachment(); - FramebufferAttachment(GLenum type, + FramebufferAttachment(const Context *context, + GLenum type, GLenum binding, const ImageIndex &textureIndex, FramebufferAttachmentObject *resource); - FramebufferAttachment(const FramebufferAttachment &other); - FramebufferAttachment &operator=(const FramebufferAttachment &other); + FramebufferAttachment(FramebufferAttachment &&other); + FramebufferAttachment &operator=(FramebufferAttachment &&other); ~FramebufferAttachment(); + void detach(const Context *context); + void attach(const Context *context, + GLenum type, + GLenum binding, + const ImageIndex &textureIndex, + FramebufferAttachmentObject *resource, + GLsizei numViews, + GLuint baseViewIndex, + GLenum multiviewLayout, + const GLint *viewportOffsets); + + // Helper methods + GLuint getRedSize() const; + GLuint getGreenSize() const; + GLuint getBlueSize() const; + GLuint getAlphaSize() const; + GLuint getDepthSize() const; + GLuint getStencilSize() const; + GLenum getComponentType() const; + GLenum getColorEncoding() const; + + bool isTextureWithId(GLuint textureId) const { return mType == GL_TEXTURE && id() == textureId; } + bool isRenderbufferWithId(GLuint renderbufferId) const { return mType == GL_RENDERBUFFER && id() == renderbufferId; } + + GLenum getBinding() const { return mTarget.binding(); } + GLuint id() const; + + // These methods are only legal to call on Texture attachments + const ImageIndex &getTextureImageIndex() const; + GLenum cubeMapFace() const; + GLint mipLevel() const; + GLint layer() const; + GLsizei getNumViews() const; + GLenum getMultiviewLayout() const; + GLint getBaseViewIndex() const; + const std::vector &getMultiviewViewportOffsets() const; + + // The size of the underlying resource the attachment points to. The 'depth' value will + // correspond to a 3D texture depth or the layer count of a 2D array texture. For Surfaces and + // Renderbuffers, it will always be 1. + Extents getSize() const; + const Format &getFormat() const; + GLsizei getSamples() const; + GLenum type() const { return mType; } + bool isAttached() const { return mType != GL_NONE; } + + Renderbuffer *getRenderbuffer() const; + Texture *getTexture() const; + const egl::Surface *getSurface() const; + FramebufferAttachmentObject *getResource() const; + InitState initState() const; + Error initializeContents(const Context *context); + void setInitState(InitState initState) const; + + // "T" must be static_castable from FramebufferAttachmentRenderTarget + template + gl::Error getRenderTarget(const Context *context, T **rtOut) const + { + static_assert(std::is_base_of(), + "Invalid RenderTarget class."); + return getRenderTargetImpl( + context, reinterpret_cast(rtOut)); + } + + bool operator==(const FramebufferAttachment &other) const; + bool operator!=(const FramebufferAttachment &other) const; + + static std::vector GetDefaultViewportOffsetVector(); + static const GLsizei kDefaultNumViews; + static const GLenum kDefaultMultiviewLayout; + static const GLint kDefaultBaseViewIndex; + static const GLint kDefaultViewportOffsets[2]; + + private: + gl::Error getRenderTargetImpl(const Context *context, + rx::FramebufferAttachmentRenderTarget **rtOut) const; + // A framebuffer attachment points to one of three types of resources: Renderbuffers, // Textures and egl::Surface. The "Target" struct indicates which part of the // object an attachment references. For the three types: @@ -84,135 +174,77 @@ class FramebufferAttachment final ImageIndex mTextureIndex; }; - void detach(); - void attach(GLenum type, - GLenum binding, - const ImageIndex &textureIndex, - FramebufferAttachmentObject *resource); - - // Helper methods - GLuint getRedSize() const; - GLuint getGreenSize() const; - GLuint getBlueSize() const; - GLuint getAlphaSize() const; - GLuint getDepthSize() const; - GLuint getStencilSize() const; - GLenum getComponentType() const; - GLenum getColorEncoding() const; - - bool isTextureWithId(GLuint textureId) const { return mType == GL_TEXTURE && id() == textureId; } - bool isRenderbufferWithId(GLuint renderbufferId) const { return mType == GL_RENDERBUFFER && id() == renderbufferId; } - - GLenum getBinding() const { return mTarget.binding(); } - GLuint id() const; - - // These methods are only legal to call on Texture attachments - const ImageIndex &getTextureImageIndex() const; - GLenum cubeMapFace() const; - GLint mipLevel() const; - GLint layer() const; - - // The size of the underlying resource the attachment points to. The 'depth' value will - // correspond to a 3D texture depth or the layer count of a 2D array texture. For Surfaces and - // Renderbuffers, it will always be 1. - Extents getSize() const; - GLenum getInternalFormat() const; - GLsizei getSamples() const; - GLenum type() const { return mType; } - bool isAttached() const { return mType != GL_NONE; } - - Renderbuffer *getRenderbuffer() const; - Texture *getTexture() const; - const egl::Surface *getSurface() const; - - // "T" must be static_castable from FramebufferAttachmentRenderTarget - template - gl::Error getRenderTarget(T **rtOut) const - { - // Cast through the pointer-to-pointer type - rx::FramebufferAttachmentRenderTarget *rtPtr = nullptr; - gl::Error error = getRenderTarget(&rtPtr); - *rtOut = static_cast(rtPtr); - return error; - } - - private: - gl::Error getRenderTarget(rx::FramebufferAttachmentRenderTarget **rtOut) const; - GLenum mType; Target mTarget; FramebufferAttachmentObject *mResource; + GLsizei mNumViews; + GLenum mMultiviewLayout; + GLint mBaseViewIndex; + std::vector mViewportOffsets; }; // A base class for objects that FBO Attachments may point to. class FramebufferAttachmentObject { public: - FramebufferAttachmentObject() {} - virtual ~FramebufferAttachmentObject() {} + FramebufferAttachmentObject(); + virtual ~FramebufferAttachmentObject(); - virtual Extents getAttachmentSize(const FramebufferAttachment::Target &target) const = 0; - virtual GLenum getAttachmentInternalFormat(const FramebufferAttachment::Target &target) const = 0; - virtual GLsizei getAttachmentSamples(const FramebufferAttachment::Target &target) const = 0; + virtual Extents getAttachmentSize(const ImageIndex &imageIndex) const = 0; + virtual const Format &getAttachmentFormat(GLenum binding, + const ImageIndex &imageIndex) const = 0; + virtual GLsizei getAttachmentSamples(const ImageIndex &imageIndex) const = 0; - virtual void onAttach() = 0; - virtual void onDetach() = 0; + virtual void onAttach(const Context *context) = 0; + virtual void onDetach(const Context *context) = 0; virtual GLuint getId() const = 0; - Error getAttachmentRenderTarget(const FramebufferAttachment::Target &target, + // These are used for robust resource initialization. + virtual InitState initState(const ImageIndex &imageIndex) const = 0; + virtual void setInitState(const ImageIndex &imageIndex, InitState initState) = 0; + + Error getAttachmentRenderTarget(const Context *context, + GLenum binding, + const ImageIndex &imageIndex, rx::FramebufferAttachmentRenderTarget **rtOut) const; + Error initializeContents(const Context *context, const ImageIndex &imageIndex); + + OnAttachmentDirtyChannel *getDirtyChannel(); + protected: virtual rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const = 0; + + OnAttachmentDirtyChannel mDirtyChannel; }; inline Extents FramebufferAttachment::getSize() const { - return mResource->getAttachmentSize(mTarget); + ASSERT(mResource); + return mResource->getAttachmentSize(mTarget.textureIndex()); } -inline GLenum FramebufferAttachment::getInternalFormat() const +inline const Format &FramebufferAttachment::getFormat() const { - return mResource->getAttachmentInternalFormat(mTarget); + ASSERT(mResource); + return mResource->getAttachmentFormat(mTarget.binding(), mTarget.textureIndex()); } inline GLsizei FramebufferAttachment::getSamples() const { - return mResource->getAttachmentSamples(mTarget); + ASSERT(mResource); + return mResource->getAttachmentSamples(mTarget.textureIndex()); } -inline gl::Error FramebufferAttachment::getRenderTarget(rx::FramebufferAttachmentRenderTarget **rtOut) const +inline gl::Error FramebufferAttachment::getRenderTargetImpl( + const Context *context, + rx::FramebufferAttachmentRenderTarget **rtOut) const { - return mResource->getAttachmentRenderTarget(mTarget, rtOut); + ASSERT(mResource); + return mResource->getAttachmentRenderTarget(context, mTarget.binding(), mTarget.textureIndex(), + rtOut); } } // namespace gl -namespace rx -{ - -class FramebufferAttachmentObjectImpl : angle::NonCopyable -{ - public: - FramebufferAttachmentObjectImpl() {} - virtual ~FramebufferAttachmentObjectImpl() {} - - virtual gl::Error getAttachmentRenderTarget(const gl::FramebufferAttachment::Target &target, - FramebufferAttachmentRenderTarget **rtOut) = 0; -}; - -} // namespace rx - -namespace gl -{ - -inline Error FramebufferAttachmentObject::getAttachmentRenderTarget( - const FramebufferAttachment::Target &target, - rx::FramebufferAttachmentRenderTarget **rtOut) const -{ - return getAttachmentImpl()->getAttachmentRenderTarget(target, rtOut); -} - -} - #endif // LIBANGLE_FRAMEBUFFERATTACHMENT_H_ diff --git a/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp b/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp index 4815855d5a..c3c184258f 100644 --- a/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp +++ b/src/3rdparty/angle/src/libANGLE/HandleAllocator.cpp @@ -49,9 +49,10 @@ GLuint HandleAllocator::allocate() { ASSERT(!mUnallocatedList.empty() || !mReleasedList.empty()); - // Allocate from released list, constant time. + // Allocate from released list, logarithmic time for pop_heap. if (!mReleasedList.empty()) { + std::pop_heap(mReleasedList.begin(), mReleasedList.end()); GLuint reusedHandle = mReleasedList.back(); mReleasedList.pop_back(); return reusedHandle; @@ -63,19 +64,23 @@ GLuint HandleAllocator::allocate() GLuint freeListHandle = listIt->begin; ASSERT(freeListHandle > 0); - listIt->begin++; if (listIt->begin == listIt->end) { mUnallocatedList.erase(listIt); } + else + { + listIt->begin++; + } return freeListHandle; } void HandleAllocator::release(GLuint handle) { - // Add to released list, constant time. + // Add to released list, logarithmic time for push_heap. mReleasedList.push_back(handle); + std::push_heap(mReleasedList.begin(), mReleasedList.end()); } void HandleAllocator::reserve(GLuint handle) @@ -101,7 +106,7 @@ void HandleAllocator::reserve(GLuint handle) if (handle == begin || handle == end) { - if (begin + 1 == end) + if (begin == end) { mUnallocatedList.erase(boundIt); } @@ -117,18 +122,21 @@ void HandleAllocator::reserve(GLuint handle) return; } + ASSERT(begin < handle && handle < end); + // need to split the range auto placementIt = mUnallocatedList.erase(boundIt); + placementIt = mUnallocatedList.insert(placementIt, HandleRange(handle + 1, end)); + mUnallocatedList.insert(placementIt, HandleRange(begin, handle - 1)); +} - if (handle + 1 != end) - { - placementIt = mUnallocatedList.insert(placementIt, HandleRange(handle + 1, end)); - } - if (begin != handle) - { - ASSERT(begin < handle); - mUnallocatedList.insert(placementIt, HandleRange(begin, handle)); - } +void HandleAllocator::reset() +{ + mUnallocatedList.clear(); + mUnallocatedList.push_back(HandleRange(1, std::numeric_limits::max())); + mReleasedList.clear(); + mBaseValue = 1; + mNextValue = 1; } } // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/HandleAllocator.h b/src/3rdparty/angle/src/libANGLE/HandleAllocator.h index 1888d57cfa..cd21d687f4 100644 --- a/src/3rdparty/angle/src/libANGLE/HandleAllocator.h +++ b/src/3rdparty/angle/src/libANGLE/HandleAllocator.h @@ -14,8 +14,6 @@ #include "angle_gl.h" -#include - namespace gl { @@ -24,7 +22,7 @@ class HandleAllocator final : angle::NonCopyable public: // Maximum handle = MAX_UINT-1 HandleAllocator(); - // Specify maximum handle value + // Specify maximum handle value. Used for testing. HandleAllocator(GLuint maximumHandleValue); ~HandleAllocator(); @@ -34,6 +32,7 @@ class HandleAllocator final : angle::NonCopyable GLuint allocate(); void release(GLuint handle); void reserve(GLuint handle); + void reset(); private: GLuint mBaseValue; @@ -41,6 +40,7 @@ class HandleAllocator final : angle::NonCopyable typedef std::vector HandleList; HandleList mFreeValues; + // Represents an inclusive range [begin, end] struct HandleRange { HandleRange(GLuint beginIn, GLuint endIn) : begin(beginIn), end(endIn) {} @@ -53,7 +53,7 @@ class HandleAllocator final : angle::NonCopyable // The freelist consists of never-allocated handles, stored // as ranges, and handles that were previously allocated and - // released, stored in a stack. + // released, stored in a heap. std::vector mUnallocatedList; std::vector mReleasedList; }; diff --git a/src/3rdparty/angle/src/libANGLE/HandleRangeAllocator.cpp b/src/3rdparty/angle/src/libANGLE/HandleRangeAllocator.cpp new file mode 100644 index 0000000000..2a97ce939f --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/HandleRangeAllocator.cpp @@ -0,0 +1,229 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// HandleRangeAllocator.cpp : Implementation for HandleRangeAllocator.h + +#include "libANGLE/HandleRangeAllocator.h" + +#include +#include +#include + +#include "common/angleutils.h" +#include "common/debug.h" + +namespace gl +{ + +const GLuint HandleRangeAllocator::kInvalidHandle = 0; + +HandleRangeAllocator::HandleRangeAllocator() +{ + // Simplify the code by making sure that lower_bound(id) never + // returns the beginning of the map, if id is valid (eg != kInvalidHandle). + mUsed.insert(std::make_pair(0u, 0u)); +} + +HandleRangeAllocator::~HandleRangeAllocator() +{ +} + +GLuint HandleRangeAllocator::allocate() +{ + return allocateRange(1u); +} + +GLuint HandleRangeAllocator::allocateAtOrAbove(GLuint wanted) +{ + if (wanted == 0u || wanted == 1u) + return allocateRange(1u); + + auto current = mUsed.lower_bound(wanted); + auto next = current; + if (current == mUsed.end() || current->first > wanted) + { + current--; + } + else + { + next++; + } + + GLuint firstId = current->first; + GLuint lastId = current->second; + ASSERT(wanted >= firstId); + + if (wanted - 1u <= lastId) + { + // Append to current range. + lastId++; + if (lastId == 0) + { + // The increment overflowed. + return allocateRange(1u); + } + + current->second = lastId; + + if (next != mUsed.end() && next->first - 1u == lastId) + { + // Merge with next range. + current->second = next->second; + mUsed.erase(next); + } + return lastId; + } + else if (next != mUsed.end() && next->first - 1u == wanted) + { + // Prepend to next range. + GLuint lastExisting = next->second; + mUsed.erase(next); + mUsed.insert(std::make_pair(wanted, lastExisting)); + return wanted; + } + mUsed.insert(std::make_pair(wanted, wanted)); + return wanted; +} + +GLuint HandleRangeAllocator::allocateRange(GLuint range) +{ + ASSERT(range != 0); + + auto current = mUsed.begin(); + auto next = current; + + while (++next != mUsed.end()) + { + if (next->first - current->second > range) + break; + current = next; + } + const GLuint firstId = current->second + 1u; + const GLuint lastId = firstId + range - 1u; + + // deal with wraparound + if (firstId == 0u || lastId < firstId) + return kInvalidHandle; + + current->second = lastId; + + if (next != mUsed.end() && next->first - 1u == lastId) + { + // merge with next range + current->second = next->second; + mUsed.erase(next); + } + return firstId; +} + +bool HandleRangeAllocator::markAsUsed(GLuint handle) +{ + ASSERT(handle); + auto current = mUsed.lower_bound(handle); + if (current != mUsed.end() && current->first == handle) + return false; + + auto next = current; + --current; + + if (current->second >= handle) + return false; + + ASSERT(current->first < handle && current->second < handle); + + if (current->second + 1u == handle) + { + // Append to current range. + current->second = handle; + if (next != mUsed.end() && next->first - 1u == handle) + { + // Merge with next range. + current->second = next->second; + mUsed.erase(next); + } + return true; + } + else if (next != mUsed.end() && next->first - 1u == handle) + { + // Prepend to next range. + GLuint lastExisting = next->second; + mUsed.erase(next); + mUsed.insert(std::make_pair(handle, lastExisting)); + return true; + } + + mUsed.insert(std::make_pair(handle, handle)); + return true; +} + +void HandleRangeAllocator::release(GLuint handle) +{ + releaseRange(handle, 1u); +} + +void HandleRangeAllocator::releaseRange(GLuint first, GLuint range) +{ + if (range == 0u || (first == 0u && range == 1u)) + return; + + if (first == 0u) + { + first++; + range--; + } + + GLuint last = first + range - 1u; + if (last < first) + last = std::numeric_limits::max(); + + while (true) + { + auto current = mUsed.lower_bound(last); + if (current == mUsed.end() || current->first > last) + --current; + + if (current->second < first) + return; + + if (current->first >= first) + { + const GLuint lastExisting = current->second; + mUsed.erase(current); + if (last < lastExisting) + { + mUsed.insert(std::make_pair(last + 1u, lastExisting)); + } + } + else if (current->second <= last) + { + current->second = first - 1u; + } + else + { + ASSERT(current->first < first && current->second > last); + const GLuint lastExisting = current->second; + current->second = first - 1u; + mUsed.insert(std::make_pair(last + 1u, lastExisting)); + } + } +} + +bool HandleRangeAllocator::isUsed(GLuint handle) const +{ + if (handle == kInvalidHandle) + return false; + + auto current = mUsed.lower_bound(handle); + if (current != mUsed.end()) + { + if (current->first == handle) + return true; + } + --current; + return current->second >= handle; +} + +} // namespace gl \ No newline at end of file diff --git a/src/3rdparty/angle/src/libANGLE/HandleRangeAllocator.h b/src/3rdparty/angle/src/libANGLE/HandleRangeAllocator.h new file mode 100644 index 0000000000..4d4b6f4f69 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/HandleRangeAllocator.h @@ -0,0 +1,60 @@ +// +// Copyright (c) 2002-2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// HandleRangeAllocator.h: Defines the gl::HandleRangeAllocator class, which is used to +// allocate contiguous ranges of GL path handles. + +#ifndef LIBANGLE_HANDLERANGEALLOCATOR_H_ +#define LIBANGLE_HANDLERANGEALLOCATOR_H_ + +#include + +#include "angle_gl.h" +#include "common/angleutils.h" + +namespace gl +{ + +// Allocates contiguous ranges of path object handles. +class HandleRangeAllocator final : angle::NonCopyable +{ + public: + static const GLuint kInvalidHandle; + + HandleRangeAllocator(); + ~HandleRangeAllocator(); + + // Allocates a new path handle. + GLuint allocate(); + + // Allocates a handle starting at or above the value of |wanted|. + // Note: may wrap if it starts near limit. + GLuint allocateAtOrAbove(GLuint wanted); + + // Allocates |range| amount of contiguous paths. + // Returns the first id to |first_id| or |kInvalidHandle| if + // allocation failed. + GLuint allocateRange(GLuint range); + + // Marks an id as used. Returns false if handle was already used. + bool markAsUsed(GLuint handle); + + // Release handle. + void release(GLuint handle); + + // Release a |range| amount of contiguous handles, starting from |first| + void releaseRange(GLuint first, GLuint range); + + // Checks whether or not a resource ID is in use. + bool isUsed(GLuint handle) const; + + private: + std::map mUsed; +}; + +} // namespace gl + +#endif // LIBANGLE_HANDLERANGEALLOCATOR_H_ \ No newline at end of file diff --git a/src/3rdparty/angle/src/libANGLE/Image.cpp b/src/3rdparty/angle/src/libANGLE/Image.cpp index a9448e3f6c..04c757c2c4 100644 --- a/src/3rdparty/angle/src/libANGLE/Image.cpp +++ b/src/3rdparty/angle/src/libANGLE/Image.cpp @@ -11,13 +11,42 @@ #include "common/debug.h" #include "common/utilities.h" #include "libANGLE/angletypes.h" +#include "libANGLE/formatutils.h" #include "libANGLE/Texture.h" #include "libANGLE/Renderbuffer.h" +#include "libANGLE/renderer/EGLImplFactory.h" #include "libANGLE/renderer/ImageImpl.h" namespace egl { -ImageSibling::ImageSibling(GLuint id) : RefCountObject(id), mSourcesOf(), mTargetOf() + +namespace +{ +gl::ImageIndex GetImageIndex(EGLenum eglTarget, const egl::AttributeMap &attribs) +{ + if (eglTarget == EGL_GL_RENDERBUFFER) + { + return gl::ImageIndex::MakeInvalid(); + } + + GLenum target = egl_gl::EGLImageTargetToGLTextureTarget(eglTarget); + GLint mip = static_cast(attribs.get(EGL_GL_TEXTURE_LEVEL_KHR, 0)); + GLint layer = static_cast(attribs.get(EGL_GL_TEXTURE_ZOFFSET_KHR, 0)); + + if (target == GL_TEXTURE_3D) + { + return gl::ImageIndex::Make3D(mip, layer); + } + else + { + ASSERT(layer == 0); + return gl::ImageIndex::MakeGeneric(target, mip); + } +} +} // anonymous namespace + +ImageSibling::ImageSibling(GLuint id) + : RefCountObject(id), FramebufferAttachmentObject(), mSourcesOf(), mTargetOf() { } @@ -25,46 +54,38 @@ ImageSibling::~ImageSibling() { // EGL images should hold a ref to their targets and siblings, a Texture should not be deletable // while it is attached to an EGL image. + // Child class should orphan images before destruction. ASSERT(mSourcesOf.empty()); - orphanImages(); + ASSERT(mTargetOf.get() == nullptr); } -void ImageSibling::setTargetImage(egl::Image *imageTarget) +void ImageSibling::setTargetImage(const gl::Context *context, egl::Image *imageTarget) { ASSERT(imageTarget != nullptr); - mTargetOf.set(imageTarget); + mTargetOf.set(context, imageTarget); imageTarget->addTargetSibling(this); } -gl::Error ImageSibling::orphanImages() +gl::Error ImageSibling::orphanImages(const gl::Context *context) { if (mTargetOf.get() != nullptr) { // Can't be a target and have sources. ASSERT(mSourcesOf.empty()); - gl::Error error = mTargetOf->orphanSibling(this); - if (error.isError()) - { - return error; - } - - mTargetOf.set(nullptr); + ANGLE_TRY(mTargetOf->orphanSibling(context, this)); + mTargetOf.set(context, nullptr); } else { - for (auto &sourceImage : mSourcesOf) + for (egl::Image *sourceImage : mSourcesOf) { - gl::Error error = sourceImage->orphanSibling(this); - if (error.isError()) - { - return error; - } + ANGLE_TRY(sourceImage->orphanSibling(context, this)); } mSourcesOf.clear(); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } void ImageSibling::addImageSource(egl::Image *imageSource) @@ -79,114 +100,146 @@ void ImageSibling::removeImageSource(egl::Image *imageSource) mSourcesOf.erase(imageSource); } -Image::Image(rx::ImageImpl *impl, EGLenum target, ImageSibling *buffer, const AttributeMap &attribs) +bool ImageSibling::isEGLImageTarget() const +{ + return (mTargetOf.get() != nullptr); +} + +gl::InitState ImageSibling::sourceEGLImageInitState() const +{ + ASSERT(isEGLImageTarget()); + return mTargetOf->sourceInitState(); +} + +void ImageSibling::setSourceEGLImageInitState(gl::InitState initState) const +{ + ASSERT(isEGLImageTarget()); + mTargetOf->setInitState(initState); +} + +ImageState::ImageState(EGLenum target, ImageSibling *buffer, const AttributeMap &attribs) + : imageIndex(GetImageIndex(target, attribs)), source(buffer), targets() +{ +} + +ImageState::~ImageState() +{ +} + +Image::Image(rx::EGLImplFactory *factory, + EGLenum target, + ImageSibling *buffer, + const AttributeMap &attribs) : RefCountObject(0), - mImplementation(impl), - mInternalFormat(GL_NONE), - mWidth(0), - mHeight(0), - mSamples(0), - mSource(), - mTargets() + mState(target, buffer, attribs), + mImplementation(factory->createImage(mState, target, attribs)), + mOrphanedAndNeedsInit(false) { ASSERT(mImplementation != nullptr); ASSERT(buffer != nullptr); - mSource.set(buffer); - mSource->addImageSource(this); + mState.source->addImageSource(this); +} - if (IsTextureTarget(target)) +gl::Error Image::onDestroy(const gl::Context *context) +{ + // All targets should hold a ref to the egl image and it should not be deleted until there are + // no siblings left. + ASSERT(mState.targets.empty()); + + // Tell the source that it is no longer used by this image + if (mState.source.get() != nullptr) { - gl::Texture *texture = rx::GetAs(mSource.get()); - GLenum textureTarget = egl_gl::EGLImageTargetToGLTextureTarget(target); - size_t level = attribs.get(EGL_GL_TEXTURE_LEVEL_KHR, 0); - mInternalFormat = texture->getInternalFormat(textureTarget, level); - mWidth = texture->getWidth(textureTarget, level); - mHeight = texture->getHeight(textureTarget, level); - mSamples = 0; - } - else if (IsRenderbufferTarget(target)) - { - gl::Renderbuffer *renderbuffer = rx::GetAs(mSource.get()); - mInternalFormat = renderbuffer->getInternalFormat(); - mWidth = renderbuffer->getWidth(); - mHeight = renderbuffer->getHeight(); - mSamples = renderbuffer->getSamples(); - } - else - { - UNREACHABLE(); + mState.source->removeImageSource(this); + mState.source.set(context, nullptr); } + return gl::NoError(); } Image::~Image() { SafeDelete(mImplementation); - - // All targets should hold a ref to the egl image and it should not be deleted until there are - // no siblings left. - ASSERT(mTargets.empty()); - - // Tell the source that it is no longer used by this image - if (mSource.get() != nullptr) - { - mSource->removeImageSource(this); - mSource.set(nullptr); - } } void Image::addTargetSibling(ImageSibling *sibling) { - mTargets.insert(sibling); + mState.targets.insert(sibling); } -gl::Error Image::orphanSibling(ImageSibling *sibling) +gl::Error Image::orphanSibling(const gl::Context *context, ImageSibling *sibling) { // notify impl - gl::Error error = mImplementation->orphan(sibling); + ANGLE_TRY(mImplementation->orphan(context, sibling)); - if (mSource.get() == sibling) + if (mState.source.get() == sibling) { // If the sibling is the source, it cannot be a target. - ASSERT(mTargets.find(sibling) == mTargets.end()); - - mSource.set(nullptr); + ASSERT(mState.targets.find(sibling) == mState.targets.end()); + mState.source.set(context, nullptr); + mOrphanedAndNeedsInit = + (sibling->initState(mState.imageIndex) == gl::InitState::MayNeedInit); } else { - mTargets.erase(sibling); + mState.targets.erase(sibling); } - return error; + return gl::NoError(); } -GLenum Image::getInternalFormat() const +const gl::Format &Image::getFormat() const { - return mInternalFormat; + return mState.source->getAttachmentFormat(GL_NONE, mState.imageIndex); } size_t Image::getWidth() const { - return mWidth; + return mState.source->getAttachmentSize(mState.imageIndex).width; } size_t Image::getHeight() const { - return mHeight; + return mState.source->getAttachmentSize(mState.imageIndex).height; } size_t Image::getSamples() const { - return mSamples; + return mState.source->getAttachmentSamples(mState.imageIndex); } -rx::ImageImpl *Image::getImplementation() +rx::ImageImpl *Image::getImplementation() const { return mImplementation; } -const rx::ImageImpl *Image::getImplementation() const +Error Image::initialize() { - return mImplementation; + return mImplementation->initialize(); } + +bool Image::orphaned() const +{ + return (mState.source.get() == nullptr); } + +gl::InitState Image::sourceInitState() const +{ + if (orphaned()) + { + return mOrphanedAndNeedsInit ? gl::InitState::MayNeedInit : gl::InitState::Initialized; + } + + return mState.source->initState(mState.imageIndex); +} + +void Image::setInitState(gl::InitState initState) +{ + if (orphaned()) + { + mOrphanedAndNeedsInit = false; + } + + return mState.source->setInitState(mState.imageIndex, initState); +} + +} // namespace egl diff --git a/src/3rdparty/angle/src/libANGLE/Image.h b/src/3rdparty/angle/src/libANGLE/Image.h index 26c9df914c..d2f1b875c6 100644 --- a/src/3rdparty/angle/src/libANGLE/Image.h +++ b/src/3rdparty/angle/src/libANGLE/Image.h @@ -12,12 +12,15 @@ #include "common/angleutils.h" #include "libANGLE/AttributeMap.h" #include "libANGLE/Error.h" +#include "libANGLE/FramebufferAttachment.h" #include "libANGLE/RefCountObject.h" +#include "libANGLE/formatutils.h" #include namespace rx { +class EGLImplFactory; class ImageImpl; } @@ -25,18 +28,25 @@ namespace egl { class Image; -class ImageSibling : public RefCountObject +// Only currently Renderbuffers and Textures can be bound with images. This makes the relationship +// explicit, and also ensures that an image sibling can determine if it's been initialized or not, +// which is important for the robust resource init extension with Textures and EGLImages. +class ImageSibling : public gl::RefCountObject, public gl::FramebufferAttachmentObject { public: ImageSibling(GLuint id); - virtual ~ImageSibling(); + ~ImageSibling() override; + + bool isEGLImageTarget() const; + gl::InitState sourceEGLImageInitState() const; + void setSourceEGLImageInitState(gl::InitState initState) const; protected: // Set the image target of this sibling - void setTargetImage(egl::Image *imageTarget); + void setTargetImage(const gl::Context *context, egl::Image *imageTarget); // Orphan all EGL image sources and targets - gl::Error orphanImages(); + gl::Error orphanImages(const gl::Context *context); private: friend class Image; @@ -48,22 +58,42 @@ class ImageSibling : public RefCountObject void removeImageSource(egl::Image *imageSource); std::set mSourcesOf; - BindingPointer mTargetOf; + gl::BindingPointer mTargetOf; }; -class Image final : public RefCountObject +struct ImageState : private angle::NonCopyable +{ + ImageState(EGLenum target, ImageSibling *buffer, const AttributeMap &attribs); + ~ImageState(); + + gl::ImageIndex imageIndex; + gl::BindingPointer source; + std::set targets; +}; + +class Image final : public gl::RefCountObject { public: - Image(rx::ImageImpl *impl, EGLenum target, ImageSibling *buffer, const AttributeMap &attribs); - ~Image(); + Image(rx::EGLImplFactory *factory, + EGLenum target, + ImageSibling *buffer, + const AttributeMap &attribs); - GLenum getInternalFormat() const; + gl::Error onDestroy(const gl::Context *context) override; + ~Image() override; + + const gl::Format &getFormat() const; size_t getWidth() const; size_t getHeight() const; size_t getSamples() const; - rx::ImageImpl *getImplementation(); - const rx::ImageImpl *getImplementation() const; + Error initialize(); + + rx::ImageImpl *getImplementation() const; + + bool orphaned() const; + gl::InitState sourceInitState() const; + void setInitState(gl::InitState initState); private: friend class ImageSibling; @@ -74,18 +104,12 @@ class Image final : public RefCountObject // Called from ImageSibling only to notify the image that a sibling (source or target) has // been respecified and state tracking should be updated. - gl::Error orphanSibling(ImageSibling *sibling); + gl::Error orphanSibling(const gl::Context *context, ImageSibling *sibling); + ImageState mState; rx::ImageImpl *mImplementation; - - GLenum mInternalFormat; - size_t mWidth; - size_t mHeight; - size_t mSamples; - - BindingPointer mSource; - std::set mTargets; + bool mOrphanedAndNeedsInit; }; -} +} // namespace egl #endif // LIBANGLE_IMAGE_H_ diff --git a/src/3rdparty/angle/src/libANGLE/ImageIndex.cpp b/src/3rdparty/angle/src/libANGLE/ImageIndex.cpp index c84e7c5d65..6f99f8ab54 100644 --- a/src/3rdparty/angle/src/libANGLE/ImageIndex.cpp +++ b/src/3rdparty/angle/src/libANGLE/ImageIndex.cpp @@ -1,3 +1,4 @@ +#include "ImageIndex.h" // // Copyright 2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -16,7 +17,8 @@ namespace gl ImageIndex::ImageIndex(const ImageIndex &other) : type(other.type), mipIndex(other.mipIndex), - layerIndex(other.layerIndex) + layerIndex(other.layerIndex), + numLayers(other.numLayers) {} ImageIndex &ImageIndex::operator=(const ImageIndex &other) @@ -24,29 +26,45 @@ ImageIndex &ImageIndex::operator=(const ImageIndex &other) type = other.type; mipIndex = other.mipIndex; layerIndex = other.layerIndex; + numLayers = other.numLayers; return *this; } +bool ImageIndex::is3D() const +{ + return type == GL_TEXTURE_3D || type == GL_TEXTURE_2D_ARRAY; +} + ImageIndex ImageIndex::Make2D(GLint mipIndex) { - return ImageIndex(GL_TEXTURE_2D, mipIndex, ENTIRE_LEVEL); + return ImageIndex(GL_TEXTURE_2D, mipIndex, ENTIRE_LEVEL, 1); +} + +ImageIndex ImageIndex::MakeRectangle(GLint mipIndex) +{ + return ImageIndex(GL_TEXTURE_RECTANGLE_ANGLE, mipIndex, ENTIRE_LEVEL, 1); } ImageIndex ImageIndex::MakeCube(GLenum target, GLint mipIndex) { ASSERT(gl::IsCubeMapTextureTarget(target)); return ImageIndex(target, mipIndex, - static_cast(CubeMapTextureTargetToLayerIndex(target))); + static_cast(CubeMapTextureTargetToLayerIndex(target)), 1); } ImageIndex ImageIndex::Make2DArray(GLint mipIndex, GLint layerIndex) { - return ImageIndex(GL_TEXTURE_2D_ARRAY, mipIndex, layerIndex); + return ImageIndex(GL_TEXTURE_2D_ARRAY, mipIndex, layerIndex, 1); +} + +ImageIndex ImageIndex::Make2DArrayRange(GLint mipIndex, GLint layerIndex, GLint numLayers) +{ + return ImageIndex(GL_TEXTURE_2D_ARRAY, mipIndex, layerIndex, numLayers); } ImageIndex ImageIndex::Make3D(GLint mipIndex, GLint layerIndex) { - return ImageIndex(GL_TEXTURE_3D, mipIndex, layerIndex); + return ImageIndex(GL_TEXTURE_3D, mipIndex, layerIndex, 1); } ImageIndex ImageIndex::MakeGeneric(GLenum target, GLint mipIndex) @@ -54,12 +72,17 @@ ImageIndex ImageIndex::MakeGeneric(GLenum target, GLint mipIndex) GLint layerIndex = IsCubeMapTextureTarget(target) ? static_cast(CubeMapTextureTargetToLayerIndex(target)) : ENTIRE_LEVEL; - return ImageIndex(target, mipIndex, layerIndex); + return ImageIndex(target, mipIndex, layerIndex, 1); +} + +ImageIndex ImageIndex::Make2DMultisample() +{ + return ImageIndex(GL_TEXTURE_2D_MULTISAMPLE, 0, ENTIRE_LEVEL, 1); } ImageIndex ImageIndex::MakeInvalid() { - return ImageIndex(GL_NONE, -1, -1); + return ImageIndex(GL_NONE, -1, -1, -1); } bool ImageIndex::operator<(const ImageIndex &other) const @@ -72,33 +95,58 @@ bool ImageIndex::operator<(const ImageIndex &other) const { return mipIndex < other.mipIndex; } - else + else if (layerIndex != other.layerIndex) { return layerIndex < other.layerIndex; } + else + { + return numLayers < other.numLayers; + } } -ImageIndex::ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn) - : type(typeIn), - mipIndex(mipIndexIn), - layerIndex(layerIndexIn) +bool ImageIndex::operator==(const ImageIndex &other) const +{ + return (type == other.type) && (mipIndex == other.mipIndex) && + (layerIndex == other.layerIndex) && (numLayers == other.numLayers); +} + +bool ImageIndex::operator!=(const ImageIndex &other) const +{ + return !(*this == other); +} + +ImageIndex::ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn, GLint numLayersIn) + : type(typeIn), mipIndex(mipIndexIn), layerIndex(layerIndexIn), numLayers(numLayersIn) {} +ImageIndexIterator::ImageIndexIterator(const ImageIndexIterator &other) = default; + ImageIndexIterator ImageIndexIterator::Make2D(GLint minMip, GLint maxMip) { return ImageIndexIterator(GL_TEXTURE_2D, Range(minMip, maxMip), - Range(ImageIndex::ENTIRE_LEVEL, ImageIndex::ENTIRE_LEVEL), NULL); + Range(ImageIndex::ENTIRE_LEVEL, ImageIndex::ENTIRE_LEVEL), + nullptr); +} + +ImageIndexIterator ImageIndexIterator::MakeRectangle(GLint minMip, GLint maxMip) +{ + return ImageIndexIterator(GL_TEXTURE_RECTANGLE_ANGLE, Range(minMip, maxMip), + Range(ImageIndex::ENTIRE_LEVEL, ImageIndex::ENTIRE_LEVEL), + nullptr); } ImageIndexIterator ImageIndexIterator::MakeCube(GLint minMip, GLint maxMip) { - return ImageIndexIterator(GL_TEXTURE_CUBE_MAP, Range(minMip, maxMip), Range(0, 6), NULL); + return ImageIndexIterator(GL_TEXTURE_CUBE_MAP, Range(minMip, maxMip), Range(0, 6), + nullptr); } ImageIndexIterator ImageIndexIterator::Make3D(GLint minMip, GLint maxMip, GLint minLayer, GLint maxLayer) { - return ImageIndexIterator(GL_TEXTURE_3D, Range(minMip, maxMip), Range(minLayer, maxLayer), NULL); + return ImageIndexIterator(GL_TEXTURE_3D, Range(minMip, maxMip), + Range(minLayer, maxLayer), nullptr); } ImageIndexIterator ImageIndexIterator::Make2DArray(GLint minMip, GLint maxMip, @@ -108,19 +156,33 @@ ImageIndexIterator ImageIndexIterator::Make2DArray(GLint minMip, GLint maxMip, Range(0, IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS), layerCounts); } -ImageIndexIterator::ImageIndexIterator(GLenum type, const Range &mipRange, - const Range &layerRange, const GLsizei *layerCounts) +ImageIndexIterator ImageIndexIterator::Make2DMultisample() +{ + return ImageIndexIterator(GL_TEXTURE_2D_MULTISAMPLE, Range(0, 0), + Range(ImageIndex::ENTIRE_LEVEL, ImageIndex::ENTIRE_LEVEL), + nullptr); +} + +ImageIndexIterator::ImageIndexIterator(GLenum type, + const Range &mipRange, + const Range &layerRange, + const GLsizei *layerCounts) : mType(type), mMipRange(mipRange), mLayerRange(layerRange), mLayerCounts(layerCounts), - mCurrentMip(mipRange.start), - mCurrentLayer(layerRange.start) + mCurrentMip(mipRange.low()), + mCurrentLayer(layerRange.low()) {} GLint ImageIndexIterator::maxLayer() const { - return (mLayerCounts ? static_cast(mLayerCounts[mCurrentMip]) : mLayerRange.end); + if (mLayerCounts) + { + ASSERT(mCurrentMip >= 0); + return (mCurrentMip < mMipRange.high()) ? mLayerCounts[mCurrentMip] : 0; + } + return mLayerRange.high(); } ImageIndex ImageIndexIterator::next() @@ -134,20 +196,28 @@ ImageIndex ImageIndexIterator::next() if (mCurrentLayer != ImageIndex::ENTIRE_LEVEL) { - if (mCurrentLayer < maxLayer()-1) + if (mCurrentLayer < maxLayer() - 1) { mCurrentLayer++; } - else if (mCurrentMip < mMipRange.end-1) + else if (mCurrentMip < mMipRange.high() - 1) { mCurrentMip++; - mCurrentLayer = mLayerRange.start; + mCurrentLayer = mLayerRange.low(); + } + else + { + done(); } } - else if (mCurrentMip < mMipRange.end-1) + else if (mCurrentMip < mMipRange.high() - 1) { mCurrentMip++; - mCurrentLayer = mLayerRange.start; + mCurrentLayer = mLayerRange.low(); + } + else + { + done(); } return value; @@ -155,7 +225,7 @@ ImageIndex ImageIndexIterator::next() ImageIndex ImageIndexIterator::current() const { - ImageIndex value(mType, mCurrentMip, mCurrentLayer); + ImageIndex value(mType, mCurrentMip, mCurrentLayer, 1); if (mType == GL_TEXTURE_CUBE_MAP) { @@ -167,7 +237,13 @@ ImageIndex ImageIndexIterator::current() const bool ImageIndexIterator::hasNext() const { - return (mCurrentMip < mMipRange.end || mCurrentLayer < maxLayer()); + return (mCurrentMip < mMipRange.high() || mCurrentLayer < maxLayer()); } +void ImageIndexIterator::done() +{ + mCurrentMip = mMipRange.high(); + mCurrentLayer = maxLayer(); } + +} // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/ImageIndex.h b/src/3rdparty/angle/src/libANGLE/ImageIndex.h index b527c7c8ab..8e1b010325 100644 --- a/src/3rdparty/angle/src/libANGLE/ImageIndex.h +++ b/src/3rdparty/angle/src/libANGLE/ImageIndex.h @@ -23,37 +23,48 @@ struct ImageIndex GLenum type; GLint mipIndex; GLint layerIndex; + GLint numLayers; ImageIndex(const ImageIndex &other); ImageIndex &operator=(const ImageIndex &other); bool hasLayer() const { return layerIndex != ENTIRE_LEVEL; } + bool is3D() const; static ImageIndex Make2D(GLint mipIndex); + static ImageIndex MakeRectangle(GLint mipIndex); static ImageIndex MakeCube(GLenum target, GLint mipIndex); static ImageIndex Make2DArray(GLint mipIndex, GLint layerIndex); + static ImageIndex Make2DArrayRange(GLint mipIndex, GLint layerIndex, GLint numLayers); static ImageIndex Make3D(GLint mipIndex, GLint layerIndex = ENTIRE_LEVEL); static ImageIndex MakeGeneric(GLenum target, GLint mipIndex); + static ImageIndex Make2DMultisample(); static ImageIndex MakeInvalid(); static const GLint ENTIRE_LEVEL = static_cast(-1); bool operator<(const ImageIndex &other) const; + bool operator==(const ImageIndex &other) const; + bool operator!=(const ImageIndex &other) const; private: friend class ImageIndexIterator; - ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn); + ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn, GLint numLayersIn); }; class ImageIndexIterator { public: + ImageIndexIterator(const ImageIndexIterator &other); + static ImageIndexIterator Make2D(GLint minMip, GLint maxMip); + static ImageIndexIterator MakeRectangle(GLint minMip, GLint maxMip); static ImageIndexIterator MakeCube(GLint minMip, GLint maxMip); static ImageIndexIterator Make3D(GLint minMip, GLint maxMip, GLint minLayer, GLint maxLayer); static ImageIndexIterator Make2DArray(GLint minMip, GLint maxMip, const GLsizei *layerCounts); + static ImageIndexIterator Make2DMultisample(); ImageIndex next(); ImageIndex current() const; @@ -65,6 +76,7 @@ class ImageIndexIterator const Range &layerRange, const GLsizei *layerCounts); GLint maxLayer() const; + void done(); GLenum mType; Range mMipRange; diff --git a/src/3rdparty/angle/src/libANGLE/IndexRangeCache.cpp b/src/3rdparty/angle/src/libANGLE/IndexRangeCache.cpp index 4f165c1b28..71a1392b1b 100644 --- a/src/3rdparty/angle/src/libANGLE/IndexRangeCache.cpp +++ b/src/3rdparty/angle/src/libANGLE/IndexRangeCache.cpp @@ -15,6 +15,14 @@ namespace gl { +IndexRangeCache::IndexRangeCache() +{ +} + +IndexRangeCache::~IndexRangeCache() +{ +} + void IndexRangeCache::addRange(GLenum type, size_t offset, size_t count, diff --git a/src/3rdparty/angle/src/libANGLE/IndexRangeCache.h b/src/3rdparty/angle/src/libANGLE/IndexRangeCache.h index 69de421c13..3b183448e6 100644 --- a/src/3rdparty/angle/src/libANGLE/IndexRangeCache.h +++ b/src/3rdparty/angle/src/libANGLE/IndexRangeCache.h @@ -23,6 +23,9 @@ namespace gl class IndexRangeCache { public: + IndexRangeCache(); + ~IndexRangeCache(); + void addRange(GLenum type, size_t offset, size_t count, diff --git a/src/3rdparty/angle/src/libANGLE/LoggingAnnotator.cpp b/src/3rdparty/angle/src/libANGLE/LoggingAnnotator.cpp new file mode 100644 index 0000000000..799399e453 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/LoggingAnnotator.cpp @@ -0,0 +1,44 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// LoggingAnnotator.cpp: DebugAnnotator implementing logging +// + +#include "libANGLE/LoggingAnnotator.h" + +#include + +namespace angle +{ + +bool LoggingAnnotator::getStatus() +{ + return false; +} + +void LoggingAnnotator::logMessage(const gl::LogMessage &msg) const +{ + auto *plat = ANGLEPlatformCurrent(); + if (plat != nullptr) + { + switch (msg.getSeverity()) + { + case gl::LOG_ERR: + plat->logError(plat, msg.getMessage().c_str()); + break; + case gl::LOG_WARN: + plat->logWarning(plat, msg.getMessage().c_str()); + break; + default: + UNREACHABLE(); + } + } + else + { + gl::Trace(msg.getSeverity(), msg.getMessage().c_str()); + } +} + +} // namespace angle diff --git a/src/3rdparty/angle/src/libANGLE/LoggingAnnotator.h b/src/3rdparty/angle/src/libANGLE/LoggingAnnotator.h new file mode 100644 index 0000000000..5bec68e189 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/LoggingAnnotator.h @@ -0,0 +1,31 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// LoggingAnnotator.h: DebugAnnotator implementing logging +// + +#ifndef LIBANGLE_LOGGINGANNOTATOR_H_ +#define LIBANGLE_LOGGINGANNOTATOR_H_ + +#include "common/debug.h" + +namespace angle +{ + +class LoggingAnnotator : public gl::DebugAnnotator +{ + public: + LoggingAnnotator(){}; + ~LoggingAnnotator() override{}; + void beginEvent(const wchar_t *eventName) override {} + void endEvent() override {} + void setMarker(const wchar_t *markerName) override {} + bool getStatus() override; + void logMessage(const gl::LogMessage &msg) const override; +}; + +} // namespace angle + +#endif // LIBANGLE_LOGGINGANNOTATOR_H_ diff --git a/src/3rdparty/angle/src/libANGLE/MemoryProgramCache.cpp b/src/3rdparty/angle/src/libANGLE/MemoryProgramCache.cpp new file mode 100644 index 0000000000..9eec12e3ea --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/MemoryProgramCache.cpp @@ -0,0 +1,772 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// MemoryProgramCache: Stores compiled and linked programs in memory so they don't +// always have to be re-compiled. Can be used in conjunction with the platform +// layer to warm up the cache from disk. + +#include "libANGLE/MemoryProgramCache.h" + +#include +#include + +#include "common/utilities.h" +#include "common/version.h" +#include "libANGLE/BinaryStream.h" +#include "libANGLE/Context.h" +#include "libANGLE/Uniform.h" +#include "libANGLE/histogram_macros.h" +#include "libANGLE/renderer/ProgramImpl.h" +#include "platform/Platform.h" + +namespace gl +{ + +namespace +{ +enum CacheResult +{ + kCacheMiss, + kCacheHitMemory, + kCacheHitDisk, + kCacheResultMax, +}; + +constexpr unsigned int kWarningLimit = 3; + +void WriteShaderVar(BinaryOutputStream *stream, const sh::ShaderVariable &var) +{ + stream->writeInt(var.type); + stream->writeInt(var.precision); + stream->writeString(var.name); + stream->writeString(var.mappedName); + stream->writeIntVector(var.arraySizes); + stream->writeInt(var.staticUse); + stream->writeString(var.structName); + ASSERT(var.fields.empty()); +} + +void LoadShaderVar(BinaryInputStream *stream, sh::ShaderVariable *var) +{ + var->type = stream->readInt(); + var->precision = stream->readInt(); + var->name = stream->readString(); + var->mappedName = stream->readString(); + stream->readIntVector(&var->arraySizes); + var->staticUse = stream->readBool(); + var->structName = stream->readString(); +} + +void WriteShaderVariableBuffer(BinaryOutputStream *stream, const ShaderVariableBuffer &var) +{ + stream->writeInt(var.binding); + stream->writeInt(var.dataSize); + + stream->writeInt(var.vertexStaticUse); + stream->writeInt(var.fragmentStaticUse); + stream->writeInt(var.computeStaticUse); + + stream->writeInt(var.memberIndexes.size()); + for (unsigned int memberCounterIndex : var.memberIndexes) + { + stream->writeInt(memberCounterIndex); + } +} + +void LoadShaderVariableBuffer(BinaryInputStream *stream, ShaderVariableBuffer *var) +{ + var->binding = stream->readInt(); + var->dataSize = stream->readInt(); + var->vertexStaticUse = stream->readBool(); + var->fragmentStaticUse = stream->readBool(); + var->computeStaticUse = stream->readBool(); + + unsigned int numMembers = stream->readInt(); + for (unsigned int blockMemberIndex = 0; blockMemberIndex < numMembers; blockMemberIndex++) + { + var->memberIndexes.push_back(stream->readInt()); + } +} + +void WriteBufferVariable(BinaryOutputStream *stream, const BufferVariable &var) +{ + WriteShaderVar(stream, var); + + stream->writeInt(var.bufferIndex); + stream->writeInt(var.blockInfo.offset); + stream->writeInt(var.blockInfo.arrayStride); + stream->writeInt(var.blockInfo.matrixStride); + stream->writeInt(var.blockInfo.isRowMajorMatrix); + stream->writeInt(var.blockInfo.topLevelArrayStride); + stream->writeInt(var.topLevelArraySize); + stream->writeInt(var.vertexStaticUse); + stream->writeInt(var.fragmentStaticUse); + stream->writeInt(var.computeStaticUse); +} + +void LoadBufferVariable(BinaryInputStream *stream, BufferVariable *var) +{ + LoadShaderVar(stream, var); + + var->bufferIndex = stream->readInt(); + var->blockInfo.offset = stream->readInt(); + var->blockInfo.arrayStride = stream->readInt(); + var->blockInfo.matrixStride = stream->readInt(); + var->blockInfo.isRowMajorMatrix = stream->readBool(); + var->blockInfo.topLevelArrayStride = stream->readInt(); + var->topLevelArraySize = stream->readInt(); + var->vertexStaticUse = stream->readBool(); + var->fragmentStaticUse = stream->readBool(); + var->computeStaticUse = stream->readBool(); +} + +void WriteInterfaceBlock(BinaryOutputStream *stream, const InterfaceBlock &block) +{ + stream->writeString(block.name); + stream->writeString(block.mappedName); + stream->writeInt(block.isArray); + stream->writeInt(block.arrayElement); + + WriteShaderVariableBuffer(stream, block); +} + +void LoadInterfaceBlock(BinaryInputStream *stream, InterfaceBlock *block) +{ + block->name = stream->readString(); + block->mappedName = stream->readString(); + block->isArray = stream->readBool(); + block->arrayElement = stream->readInt(); + + LoadShaderVariableBuffer(stream, block); +} + +class HashStream final : angle::NonCopyable +{ + public: + std::string str() { return mStringStream.str(); } + + template + HashStream &operator<<(T value) + { + mStringStream << value << kSeparator; + return *this; + } + + private: + static constexpr char kSeparator = ':'; + std::ostringstream mStringStream; +}; + +HashStream &operator<<(HashStream &stream, const Shader *shader) +{ + if (shader) + { + stream << shader->getSourceString().c_str() << shader->getSourceString().length() + << shader->getCompilerResourcesString().c_str(); + } + return stream; +} + +HashStream &operator<<(HashStream &stream, const Program::Bindings &bindings) +{ + for (const auto &binding : bindings) + { + stream << binding.first << binding.second; + } + return stream; +} + +HashStream &operator<<(HashStream &stream, const std::vector &strings) +{ + for (const auto &str : strings) + { + stream << str; + } + return stream; +} + +} // anonymous namespace + +MemoryProgramCache::MemoryProgramCache(size_t maxCacheSizeBytes) + : mProgramBinaryCache(maxCacheSizeBytes), mIssuedWarnings(0) +{ +} + +MemoryProgramCache::~MemoryProgramCache() +{ +} + +// static +LinkResult MemoryProgramCache::Deserialize(const Context *context, + const Program *program, + ProgramState *state, + const uint8_t *binary, + size_t length, + InfoLog &infoLog) +{ + BinaryInputStream stream(binary, length); + + unsigned char commitString[ANGLE_COMMIT_HASH_SIZE]; + stream.readBytes(commitString, ANGLE_COMMIT_HASH_SIZE); + if (memcmp(commitString, ANGLE_COMMIT_HASH, sizeof(unsigned char) * ANGLE_COMMIT_HASH_SIZE) != + 0) + { + infoLog << "Invalid program binary version."; + return false; + } + + int majorVersion = stream.readInt(); + int minorVersion = stream.readInt(); + if (majorVersion != context->getClientMajorVersion() || + minorVersion != context->getClientMinorVersion()) + { + infoLog << "Cannot load program binaries across different ES context versions."; + return false; + } + + state->mComputeShaderLocalSize[0] = stream.readInt(); + state->mComputeShaderLocalSize[1] = stream.readInt(); + state->mComputeShaderLocalSize[2] = stream.readInt(); + + state->mNumViews = stream.readInt(); + + static_assert(MAX_VERTEX_ATTRIBS <= sizeof(unsigned long) * 8, + "Too many vertex attribs for mask"); + state->mActiveAttribLocationsMask = stream.readInt(); + + unsigned int attribCount = stream.readInt(); + ASSERT(state->mAttributes.empty()); + for (unsigned int attribIndex = 0; attribIndex < attribCount; ++attribIndex) + { + sh::Attribute attrib; + LoadShaderVar(&stream, &attrib); + attrib.location = stream.readInt(); + state->mAttributes.push_back(attrib); + } + + unsigned int uniformCount = stream.readInt(); + ASSERT(state->mUniforms.empty()); + for (unsigned int uniformIndex = 0; uniformIndex < uniformCount; ++uniformIndex) + { + LinkedUniform uniform; + LoadShaderVar(&stream, &uniform); + + uniform.bufferIndex = stream.readInt(); + uniform.blockInfo.offset = stream.readInt(); + uniform.blockInfo.arrayStride = stream.readInt(); + uniform.blockInfo.matrixStride = stream.readInt(); + uniform.blockInfo.isRowMajorMatrix = stream.readBool(); + + uniform.typeInfo = &GetUniformTypeInfo(uniform.type); + + state->mUniforms.push_back(uniform); + } + + const unsigned int uniformIndexCount = stream.readInt(); + ASSERT(state->mUniformLocations.empty()); + for (unsigned int uniformIndexIndex = 0; uniformIndexIndex < uniformIndexCount; + uniformIndexIndex++) + { + VariableLocation variable; + stream.readInt(&variable.arrayIndex); + stream.readInt(&variable.index); + stream.readBool(&variable.ignored); + + state->mUniformLocations.push_back(variable); + } + + unsigned int uniformBlockCount = stream.readInt(); + ASSERT(state->mUniformBlocks.empty()); + for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlockCount; + ++uniformBlockIndex) + { + InterfaceBlock uniformBlock; + LoadInterfaceBlock(&stream, &uniformBlock); + state->mUniformBlocks.push_back(uniformBlock); + + state->mActiveUniformBlockBindings.set(uniformBlockIndex, uniformBlock.binding != 0); + } + + unsigned int bufferVariableCount = stream.readInt(); + ASSERT(state->mBufferVariables.empty()); + for (unsigned int index = 0; index < bufferVariableCount; ++index) + { + BufferVariable bufferVariable; + LoadBufferVariable(&stream, &bufferVariable); + state->mBufferVariables.push_back(bufferVariable); + } + + unsigned int shaderStorageBlockCount = stream.readInt(); + ASSERT(state->mShaderStorageBlocks.empty()); + for (unsigned int shaderStorageBlockIndex = 0; + shaderStorageBlockIndex < shaderStorageBlockCount; ++shaderStorageBlockIndex) + { + InterfaceBlock shaderStorageBlock; + LoadInterfaceBlock(&stream, &shaderStorageBlock); + state->mShaderStorageBlocks.push_back(shaderStorageBlock); + } + + unsigned int atomicCounterBufferCount = stream.readInt(); + ASSERT(state->mAtomicCounterBuffers.empty()); + for (unsigned int bufferIndex = 0; bufferIndex < atomicCounterBufferCount; ++bufferIndex) + { + AtomicCounterBuffer atomicCounterBuffer; + LoadShaderVariableBuffer(&stream, &atomicCounterBuffer); + + state->mAtomicCounterBuffers.push_back(atomicCounterBuffer); + } + + unsigned int transformFeedbackVaryingCount = stream.readInt(); + + // Reject programs that use transform feedback varyings if the hardware cannot support them. + if (transformFeedbackVaryingCount > 0 && + context->getWorkarounds().disableProgramCachingForTransformFeedback) + { + infoLog << "Current driver does not support transform feedback in binary programs."; + return false; + } + + ASSERT(state->mLinkedTransformFeedbackVaryings.empty()); + for (unsigned int transformFeedbackVaryingIndex = 0; + transformFeedbackVaryingIndex < transformFeedbackVaryingCount; + ++transformFeedbackVaryingIndex) + { + sh::Varying varying; + stream.readIntVector(&varying.arraySizes); + stream.readInt(&varying.type); + stream.readString(&varying.name); + + GLuint arrayIndex = stream.readInt(); + + state->mLinkedTransformFeedbackVaryings.emplace_back(varying, arrayIndex); + } + + stream.readInt(&state->mTransformFeedbackBufferMode); + + unsigned int outputCount = stream.readInt(); + ASSERT(state->mOutputVariables.empty()); + for (unsigned int outputIndex = 0; outputIndex < outputCount; ++outputIndex) + { + sh::OutputVariable output; + LoadShaderVar(&stream, &output); + output.location = stream.readInt(); + state->mOutputVariables.push_back(output); + } + + unsigned int outputVarCount = stream.readInt(); + ASSERT(state->mOutputLocations.empty()); + for (unsigned int outputIndex = 0; outputIndex < outputVarCount; ++outputIndex) + { + VariableLocation locationData; + stream.readInt(&locationData.arrayIndex); + stream.readInt(&locationData.index); + stream.readBool(&locationData.ignored); + state->mOutputLocations.push_back(locationData); + } + + unsigned int outputTypeCount = stream.readInt(); + for (unsigned int outputIndex = 0; outputIndex < outputTypeCount; ++outputIndex) + { + state->mOutputVariableTypes.push_back(stream.readInt()); + } + static_assert(IMPLEMENTATION_MAX_DRAW_BUFFERS < 8 * sizeof(uint32_t), + "All bits of DrawBufferMask can be contained in an uint32_t"); + state->mActiveOutputVariables = stream.readInt(); + + unsigned int samplerRangeLow = stream.readInt(); + unsigned int samplerRangeHigh = stream.readInt(); + state->mSamplerUniformRange = RangeUI(samplerRangeLow, samplerRangeHigh); + unsigned int samplerCount = stream.readInt(); + for (unsigned int samplerIndex = 0; samplerIndex < samplerCount; ++samplerIndex) + { + GLenum textureType = stream.readInt(); + size_t bindingCount = stream.readInt(); + bool unreferenced = stream.readBool(); + state->mSamplerBindings.emplace_back( + SamplerBinding(textureType, bindingCount, unreferenced)); + } + + unsigned int imageRangeLow = stream.readInt(); + unsigned int imageRangeHigh = stream.readInt(); + state->mImageUniformRange = RangeUI(imageRangeLow, imageRangeHigh); + unsigned int imageBindingCount = stream.readInt(); + for (unsigned int imageIndex = 0; imageIndex < imageBindingCount; ++imageIndex) + { + unsigned int elementCount = stream.readInt(); + ImageBinding imageBinding(elementCount); + for (unsigned int i = 0; i < elementCount; ++i) + { + imageBinding.boundImageUnits[i] = stream.readInt(); + } + state->mImageBindings.emplace_back(imageBinding); + } + + unsigned int atomicCounterRangeLow = stream.readInt(); + unsigned int atomicCounterRangeHigh = stream.readInt(); + state->mAtomicCounterUniformRange = RangeUI(atomicCounterRangeLow, atomicCounterRangeHigh); + + static_assert(SHADER_TYPE_MAX <= sizeof(unsigned long) * 8, "Too many shader types"); + state->mLinkedShaderStages = stream.readInt(); + + return program->getImplementation()->load(context, infoLog, &stream); +} + +// static +void MemoryProgramCache::Serialize(const Context *context, + const gl::Program *program, + angle::MemoryBuffer *binaryOut) +{ + BinaryOutputStream stream; + + stream.writeBytes(reinterpret_cast(ANGLE_COMMIT_HASH), + ANGLE_COMMIT_HASH_SIZE); + + // nullptr context is supported when computing binary length. + if (context) + { + stream.writeInt(context->getClientVersion().major); + stream.writeInt(context->getClientVersion().minor); + } + else + { + stream.writeInt(2); + stream.writeInt(0); + } + + const auto &state = program->getState(); + + const auto &computeLocalSize = state.getComputeShaderLocalSize(); + + stream.writeInt(computeLocalSize[0]); + stream.writeInt(computeLocalSize[1]); + stream.writeInt(computeLocalSize[2]); + + stream.writeInt(state.mNumViews); + + stream.writeInt(state.getActiveAttribLocationsMask().to_ulong()); + + stream.writeInt(state.getAttributes().size()); + for (const sh::Attribute &attrib : state.getAttributes()) + { + WriteShaderVar(&stream, attrib); + stream.writeInt(attrib.location); + } + + stream.writeInt(state.getUniforms().size()); + for (const LinkedUniform &uniform : state.getUniforms()) + { + WriteShaderVar(&stream, uniform); + + // FIXME: referenced + + stream.writeInt(uniform.bufferIndex); + stream.writeInt(uniform.blockInfo.offset); + stream.writeInt(uniform.blockInfo.arrayStride); + stream.writeInt(uniform.blockInfo.matrixStride); + stream.writeInt(uniform.blockInfo.isRowMajorMatrix); + } + + stream.writeInt(state.getUniformLocations().size()); + for (const auto &variable : state.getUniformLocations()) + { + stream.writeInt(variable.arrayIndex); + stream.writeIntOrNegOne(variable.index); + stream.writeInt(variable.ignored); + } + + stream.writeInt(state.getUniformBlocks().size()); + for (const InterfaceBlock &uniformBlock : state.getUniformBlocks()) + { + WriteInterfaceBlock(&stream, uniformBlock); + } + + stream.writeInt(state.getBufferVariables().size()); + for (const BufferVariable &bufferVariable : state.getBufferVariables()) + { + WriteBufferVariable(&stream, bufferVariable); + } + + stream.writeInt(state.getShaderStorageBlocks().size()); + for (const InterfaceBlock &shaderStorageBlock : state.getShaderStorageBlocks()) + { + WriteInterfaceBlock(&stream, shaderStorageBlock); + } + + stream.writeInt(state.mAtomicCounterBuffers.size()); + for (const auto &atomicCounterBuffer : state.mAtomicCounterBuffers) + { + WriteShaderVariableBuffer(&stream, atomicCounterBuffer); + } + + // Warn the app layer if saving a binary with unsupported transform feedback. + if (!state.getLinkedTransformFeedbackVaryings().empty() && + context->getWorkarounds().disableProgramCachingForTransformFeedback) + { + WARN() << "Saving program binary with transform feedback, which is not supported on this " + "driver."; + } + + stream.writeInt(state.getLinkedTransformFeedbackVaryings().size()); + for (const auto &var : state.getLinkedTransformFeedbackVaryings()) + { + stream.writeIntVector(var.arraySizes); + stream.writeInt(var.type); + stream.writeString(var.name); + + stream.writeIntOrNegOne(var.arrayIndex); + } + + stream.writeInt(state.getTransformFeedbackBufferMode()); + + stream.writeInt(state.getOutputVariables().size()); + for (const sh::OutputVariable &output : state.getOutputVariables()) + { + WriteShaderVar(&stream, output); + stream.writeInt(output.location); + } + + stream.writeInt(state.getOutputLocations().size()); + for (const auto &outputVar : state.getOutputLocations()) + { + stream.writeInt(outputVar.arrayIndex); + stream.writeIntOrNegOne(outputVar.index); + stream.writeInt(outputVar.ignored); + } + + stream.writeInt(state.mOutputVariableTypes.size()); + for (const auto &outputVariableType : state.mOutputVariableTypes) + { + stream.writeInt(outputVariableType); + } + + static_assert(IMPLEMENTATION_MAX_DRAW_BUFFERS < 8 * sizeof(uint32_t), + "All bits of DrawBufferMask can be contained in an uint32_t"); + stream.writeInt(static_cast(state.mActiveOutputVariables.to_ulong())); + + stream.writeInt(state.getSamplerUniformRange().low()); + stream.writeInt(state.getSamplerUniformRange().high()); + + stream.writeInt(state.getSamplerBindings().size()); + for (const auto &samplerBinding : state.getSamplerBindings()) + { + stream.writeInt(samplerBinding.textureType); + stream.writeInt(samplerBinding.boundTextureUnits.size()); + stream.writeInt(samplerBinding.unreferenced); + } + + stream.writeInt(state.getImageUniformRange().low()); + stream.writeInt(state.getImageUniformRange().high()); + + stream.writeInt(state.getImageBindings().size()); + for (const auto &imageBinding : state.getImageBindings()) + { + stream.writeInt(imageBinding.boundImageUnits.size()); + for (size_t i = 0; i < imageBinding.boundImageUnits.size(); ++i) + { + stream.writeInt(imageBinding.boundImageUnits[i]); + } + } + + stream.writeInt(state.getAtomicCounterUniformRange().low()); + stream.writeInt(state.getAtomicCounterUniformRange().high()); + + stream.writeInt(state.getLinkedShaderStages().to_ulong()); + + program->getImplementation()->save(context, &stream); + + ASSERT(binaryOut); + binaryOut->resize(stream.length()); + memcpy(binaryOut->data(), stream.data(), stream.length()); +} + +// static +void MemoryProgramCache::ComputeHash(const Context *context, + const Program *program, + ProgramHash *hashOut) +{ + const Shader *vertexShader = program->getAttachedVertexShader(); + const Shader *fragmentShader = program->getAttachedFragmentShader(); + const Shader *computeShader = program->getAttachedComputeShader(); + + // Compute the program hash. Start with the shader hashes and resource strings. + HashStream hashStream; + hashStream << vertexShader << fragmentShader << computeShader; + + // Add some ANGLE metadata and Context properties, such as version and back-end. + hashStream << ANGLE_COMMIT_HASH << context->getClientMajorVersion() + << context->getClientMinorVersion() << context->getString(GL_RENDERER); + + // Hash pre-link program properties. + hashStream << program->getAttributeBindings() << program->getUniformLocationBindings() + << program->getFragmentInputBindings() + << program->getState().getTransformFeedbackVaryingNames() + << program->getState().getTransformFeedbackBufferMode(); + + // Call the secure SHA hashing function. + const std::string &programKey = hashStream.str(); + angle::base::SHA1HashBytes(reinterpret_cast(programKey.c_str()), + programKey.length(), hashOut->data()); +} + +LinkResult MemoryProgramCache::getProgram(const Context *context, + const Program *program, + ProgramState *state, + ProgramHash *hashOut) +{ + ComputeHash(context, program, hashOut); + const angle::MemoryBuffer *binaryProgram = nullptr; + LinkResult result(false); + if (get(*hashOut, &binaryProgram)) + { + InfoLog infoLog; + ANGLE_TRY_RESULT(Deserialize(context, program, state, binaryProgram->data(), + binaryProgram->size(), infoLog), + result); + ANGLE_HISTOGRAM_BOOLEAN("GPU.ANGLE.ProgramCache.LoadBinarySuccess", result.getResult()); + if (!result.getResult()) + { + // Cache load failed, evict. + if (mIssuedWarnings++ < kWarningLimit) + { + WARN() << "Failed to load binary from cache: " << infoLog.str(); + + if (mIssuedWarnings == kWarningLimit) + { + WARN() << "Reaching warning limit for cache load failures, silencing " + "subsequent warnings."; + } + } + remove(*hashOut); + } + } + return result; +} + +bool MemoryProgramCache::get(const ProgramHash &programHash, const angle::MemoryBuffer **programOut) +{ + const CacheEntry *entry = nullptr; + if (!mProgramBinaryCache.get(programHash, &entry)) + { + ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.ProgramCache.CacheResult", kCacheMiss, + kCacheResultMax); + return false; + } + + if (entry->second == CacheSource::PutProgram) + { + ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.ProgramCache.CacheResult", kCacheHitMemory, + kCacheResultMax); + } + else + { + ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.ProgramCache.CacheResult", kCacheHitDisk, + kCacheResultMax); + } + + *programOut = &entry->first; + return true; +} + +bool MemoryProgramCache::getAt(size_t index, + ProgramHash *hashOut, + const angle::MemoryBuffer **programOut) +{ + const CacheEntry *entry = nullptr; + if (!mProgramBinaryCache.getAt(index, hashOut, &entry)) + { + return false; + } + + *programOut = &entry->first; + return true; +} + +void MemoryProgramCache::remove(const ProgramHash &programHash) +{ + bool result = mProgramBinaryCache.eraseByKey(programHash); + ASSERT(result); +} + +void MemoryProgramCache::putProgram(const ProgramHash &programHash, + const Context *context, + const Program *program) +{ + CacheEntry newEntry; + Serialize(context, program, &newEntry.first); + newEntry.second = CacheSource::PutProgram; + + ANGLE_HISTOGRAM_COUNTS("GPU.ANGLE.ProgramCache.ProgramBinarySizeBytes", + static_cast(newEntry.first.size())); + + const CacheEntry *result = + mProgramBinaryCache.put(programHash, std::move(newEntry), newEntry.first.size()); + if (!result) + { + ERR() << "Failed to store binary program in memory cache, program is too large."; + } + else + { + auto *platform = ANGLEPlatformCurrent(); + platform->cacheProgram(platform, programHash, result->first.size(), result->first.data()); + } +} + +void MemoryProgramCache::updateProgram(const Context *context, const Program *program) +{ + gl::ProgramHash programHash; + ComputeHash(context, program, &programHash); + putProgram(programHash, context, program); +} + +void MemoryProgramCache::putBinary(const ProgramHash &programHash, + const uint8_t *binary, + size_t length) +{ + // Copy the binary. + CacheEntry newEntry; + newEntry.first.resize(length); + memcpy(newEntry.first.data(), binary, length); + newEntry.second = CacheSource::PutBinary; + + // Store the binary. + const CacheEntry *result = mProgramBinaryCache.put(programHash, std::move(newEntry), length); + if (!result) + { + ERR() << "Failed to store binary program in memory cache, program is too large."; + } +} + +void MemoryProgramCache::clear() +{ + mProgramBinaryCache.clear(); + mIssuedWarnings = 0; +} + +void MemoryProgramCache::resize(size_t maxCacheSizeBytes) +{ + mProgramBinaryCache.resize(maxCacheSizeBytes); +} + +size_t MemoryProgramCache::entryCount() const +{ + return mProgramBinaryCache.entryCount(); +} + +size_t MemoryProgramCache::trim(size_t limit) +{ + return mProgramBinaryCache.shrinkToSize(limit); +} + +size_t MemoryProgramCache::size() const +{ + return mProgramBinaryCache.size(); +} + +size_t MemoryProgramCache::maxSize() const +{ + return mProgramBinaryCache.maxSize(); +} + +} // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/MemoryProgramCache.h b/src/3rdparty/angle/src/libANGLE/MemoryProgramCache.h new file mode 100644 index 0000000000..044bd48ecc --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/MemoryProgramCache.h @@ -0,0 +1,130 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// MemoryProgramCache: Stores compiled and linked programs in memory so they don't +// always have to be re-compiled. Can be used in conjunction with the platform +// layer to warm up the cache from disk. + +#ifndef LIBANGLE_MEMORY_PROGRAM_CACHE_H_ +#define LIBANGLE_MEMORY_PROGRAM_CACHE_H_ + +#include + +#include "common/MemoryBuffer.h" +#include "libANGLE/Error.h" +#include "libANGLE/SizedMRUCache.h" + +namespace gl +{ +// 160-bit SHA-1 hash key. +constexpr size_t kProgramHashLength = 20; +using ProgramHash = std::array; +} // namespace gl + +namespace std +{ +template <> +struct hash +{ + // Simple routine to hash four ints. + size_t operator()(const gl::ProgramHash &programHash) const + { + unsigned int hash = 0; + for (uint32_t num : programHash) + { + hash *= 37; + hash += num; + } + return hash; + } +}; +} // namespace std + +namespace gl +{ +class Context; +class InfoLog; +class Program; +class ProgramState; + +class MemoryProgramCache final : angle::NonCopyable +{ + public: + MemoryProgramCache(size_t maxCacheSizeBytes); + ~MemoryProgramCache(); + + // Writes a program's binary to the output memory buffer. + static void Serialize(const Context *context, + const Program *program, + angle::MemoryBuffer *binaryOut); + + // Loads program state according to the specified binary blob. + static LinkResult Deserialize(const Context *context, + const Program *program, + ProgramState *state, + const uint8_t *binary, + size_t length, + InfoLog &infoLog); + + static void ComputeHash(const Context *context, const Program *program, ProgramHash *hashOut); + + // Check if the cache contains a binary matching the specified program. + bool get(const ProgramHash &programHash, const angle::MemoryBuffer **programOut); + + // For querying the contents of the cache. + bool getAt(size_t index, ProgramHash *hashOut, const angle::MemoryBuffer **programOut); + + // Evict a program from the binary cache. + void remove(const ProgramHash &programHash); + + // Helper method that serializes a program. + void putProgram(const ProgramHash &programHash, const Context *context, const Program *program); + + // Same as putProgram but computes the hash. + void updateProgram(const Context *context, const Program *program); + + // Store a binary directly. + void putBinary(const ProgramHash &programHash, const uint8_t *binary, size_t length); + + // Check the cache, and deserialize and load the program if found. Evict existing hash if load + // fails. + LinkResult getProgram(const Context *context, + const Program *program, + ProgramState *state, + ProgramHash *hashOut); + + // Empty the cache. + void clear(); + + // Resize the cache. Discards current contents. + void resize(size_t maxCacheSizeBytes); + + // Returns the number of entries in the cache. + size_t entryCount() const; + + // Reduces the current cache size and returns the number of bytes freed. + size_t trim(size_t limit); + + // Returns the current cache size in bytes. + size_t size() const; + + // Returns the maximum cache size in bytes. + size_t maxSize() const; + + private: + enum class CacheSource + { + PutProgram, + PutBinary, + }; + + using CacheEntry = std::pair; + angle::SizedMRUCache mProgramBinaryCache; + unsigned int mIssuedWarnings; +}; + +} // namespace gl + +#endif // LIBANGLE_MEMORY_PROGRAM_CACHE_H_ diff --git a/src/3rdparty/angle/src/libANGLE/PackedGLEnums.h b/src/3rdparty/angle/src/libANGLE/PackedGLEnums.h new file mode 100644 index 0000000000..70e32910fc --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/PackedGLEnums.h @@ -0,0 +1,111 @@ +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// PackedGLEnums_autogen.h: +// Declares ANGLE-specific enums classes for GLEnum and functions operating +// on them. + +#ifndef LIBANGLE_PACKEDGLENUMS_H_ +#define LIBANGLE_PACKEDGLENUMS_H_ + +#include "libANGLE/PackedGLEnums_autogen.h" + +#include +#include + +namespace angle +{ + +template +class EnumIterator final +{ + private: + using UnderlyingType = typename std::underlying_type::type; + + public: + EnumIterator(E value) : mValue(static_cast(value)) {} + EnumIterator &operator++() + { + mValue++; + return *this; + } + bool operator==(const EnumIterator &other) const { return mValue == other.mValue; } + bool operator!=(const EnumIterator &other) const { return mValue != other.mValue; } + E operator*() const { return static_cast(mValue); } + + private: + UnderlyingType mValue; +}; + +template +struct AllEnums +{ + EnumIterator begin() const { return {static_cast(0)}; } + EnumIterator end() const { return {E::InvalidEnum}; } +}; + +template +class PackedEnumMap +{ + private: + using UnderlyingType = typename std::underlying_type::type; + static constexpr size_t kSize = static_cast(E::EnumCount); + using Storage = std::array; + + Storage mData; + + public: + // types: + using value_type = T; + using pointer = T *; + using const_pointer = const T *; + using reference = T &; + using const_reference = const T &; + + using size_type = size_t; + using difference_type = ptrdiff_t; + + using iterator = typename Storage::iterator; + using const_iterator = typename Storage::const_iterator; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + // No explicit construct/copy/destroy for aggregate type + void fill(const T &u) { mData.fill(u); } + void swap(PackedEnumMap &a) noexcept { mData.swap(a.mData); } + + // iterators: + iterator begin() noexcept { return mData.begin(); } + const_iterator begin() const noexcept { return mData.begin(); } + iterator end() noexcept { return mData.end(); } + const_iterator end() const noexcept { return mData.end(); } + + reverse_iterator rbegin() noexcept { return mData.rbegin(); } + const_reverse_iterator rbegin() const noexcept { return mData.rbegin(); } + reverse_iterator rend() noexcept { return mData.rend(); } + const_reverse_iterator rend() const noexcept { return mData.rend(); } + + // capacity: + constexpr size_type size() const noexcept { return mData.size(); } + constexpr size_type max_size() const noexcept { return mData.max_size(); } + constexpr bool empty() const noexcept { return mData.empty(); } + + // element access: + reference operator[](E n) { return mData[static_cast(n)]; } + const_reference operator[](E n) const { return mData[static_cast(n)]; } + const_reference at(E n) const { return mData.at(static_cast(n)); } + reference at(E n) { return mData.at(static_cast(n)); } + + reference front() { return mData.front(); } + const_reference front() const { return mData.front(); } + reference back() { return mData.back(); } + const_reference back() const { return mData.back(); } + + T *data() noexcept { return mData.data(); } + const T *data() const noexcept { return mData.data(); } +}; + +} // namespace angle + +#endif // LIBANGLE_PACKEDGLENUMS_H_ diff --git a/src/3rdparty/angle/src/libANGLE/PackedGLEnums_autogen.cpp b/src/3rdparty/angle/src/libANGLE/PackedGLEnums_autogen.cpp new file mode 100644 index 0000000000..4959a8ff14 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/PackedGLEnums_autogen.cpp @@ -0,0 +1,174 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_packed_gl_enums.py using data from packed_gl_enums.json. +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// PackedGLEnums_autogen.cpp: +// Implements ANGLE-specific enums classes for GLEnum and functions operating +// on them. + +#include "libANGLE/PackedGLEnums_autogen.h" +#include "common/debug.h" + +namespace gl +{ + +template <> +BufferBinding FromGLenum(GLenum from) +{ + switch (from) + { + case GL_ARRAY_BUFFER: + return BufferBinding::Array; + case GL_ATOMIC_COUNTER_BUFFER: + return BufferBinding::AtomicCounter; + case GL_COPY_READ_BUFFER: + return BufferBinding::CopyRead; + case GL_COPY_WRITE_BUFFER: + return BufferBinding::CopyWrite; + case GL_DISPATCH_INDIRECT_BUFFER: + return BufferBinding::DispatchIndirect; + case GL_DRAW_INDIRECT_BUFFER: + return BufferBinding::DrawIndirect; + case GL_ELEMENT_ARRAY_BUFFER: + return BufferBinding::ElementArray; + case GL_PIXEL_PACK_BUFFER: + return BufferBinding::PixelPack; + case GL_PIXEL_UNPACK_BUFFER: + return BufferBinding::PixelUnpack; + case GL_SHADER_STORAGE_BUFFER: + return BufferBinding::ShaderStorage; + case GL_TRANSFORM_FEEDBACK_BUFFER: + return BufferBinding::TransformFeedback; + case GL_UNIFORM_BUFFER: + return BufferBinding::Uniform; + default: + return BufferBinding::InvalidEnum; + } +} + +GLenum ToGLenum(BufferBinding from) +{ + switch (from) + { + case BufferBinding::Array: + return GL_ARRAY_BUFFER; + case BufferBinding::AtomicCounter: + return GL_ATOMIC_COUNTER_BUFFER; + case BufferBinding::CopyRead: + return GL_COPY_READ_BUFFER; + case BufferBinding::CopyWrite: + return GL_COPY_WRITE_BUFFER; + case BufferBinding::DispatchIndirect: + return GL_DISPATCH_INDIRECT_BUFFER; + case BufferBinding::DrawIndirect: + return GL_DRAW_INDIRECT_BUFFER; + case BufferBinding::ElementArray: + return GL_ELEMENT_ARRAY_BUFFER; + case BufferBinding::PixelPack: + return GL_PIXEL_PACK_BUFFER; + case BufferBinding::PixelUnpack: + return GL_PIXEL_UNPACK_BUFFER; + case BufferBinding::ShaderStorage: + return GL_SHADER_STORAGE_BUFFER; + case BufferBinding::TransformFeedback: + return GL_TRANSFORM_FEEDBACK_BUFFER; + case BufferBinding::Uniform: + return GL_UNIFORM_BUFFER; + default: + UNREACHABLE(); + return GL_NONE; + } +} + +template <> +BufferUsage FromGLenum(GLenum from) +{ + switch (from) + { + case GL_DYNAMIC_COPY: + return BufferUsage::DynamicCopy; + case GL_DYNAMIC_DRAW: + return BufferUsage::DynamicDraw; + case GL_DYNAMIC_READ: + return BufferUsage::DynamicRead; + case GL_STATIC_COPY: + return BufferUsage::StaticCopy; + case GL_STATIC_DRAW: + return BufferUsage::StaticDraw; + case GL_STATIC_READ: + return BufferUsage::StaticRead; + case GL_STREAM_COPY: + return BufferUsage::StreamCopy; + case GL_STREAM_DRAW: + return BufferUsage::StreamDraw; + case GL_STREAM_READ: + return BufferUsage::StreamRead; + default: + return BufferUsage::InvalidEnum; + } +} + +GLenum ToGLenum(BufferUsage from) +{ + switch (from) + { + case BufferUsage::DynamicCopy: + return GL_DYNAMIC_COPY; + case BufferUsage::DynamicDraw: + return GL_DYNAMIC_DRAW; + case BufferUsage::DynamicRead: + return GL_DYNAMIC_READ; + case BufferUsage::StaticCopy: + return GL_STATIC_COPY; + case BufferUsage::StaticDraw: + return GL_STATIC_DRAW; + case BufferUsage::StaticRead: + return GL_STATIC_READ; + case BufferUsage::StreamCopy: + return GL_STREAM_COPY; + case BufferUsage::StreamDraw: + return GL_STREAM_DRAW; + case BufferUsage::StreamRead: + return GL_STREAM_READ; + default: + UNREACHABLE(); + return GL_NONE; + } +} + +template <> +CullFaceMode FromGLenum(GLenum from) +{ + switch (from) + { + case GL_BACK: + return CullFaceMode::Back; + case GL_FRONT: + return CullFaceMode::Front; + case GL_FRONT_AND_BACK: + return CullFaceMode::FrontAndBack; + default: + return CullFaceMode::InvalidEnum; + } +} + +GLenum ToGLenum(CullFaceMode from) +{ + switch (from) + { + case CullFaceMode::Back: + return GL_BACK; + case CullFaceMode::Front: + return GL_FRONT; + case CullFaceMode::FrontAndBack: + return GL_FRONT_AND_BACK; + default: + UNREACHABLE(); + return GL_NONE; + } +} + +} // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/PackedGLEnums_autogen.h b/src/3rdparty/angle/src/libANGLE/PackedGLEnums_autogen.h new file mode 100644 index 0000000000..f3f349ab68 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/PackedGLEnums_autogen.h @@ -0,0 +1,84 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_packed_gl_enums.py using data from packed_gl_enums.json. +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// PackedGLEnums_autogen.h: +// Declares ANGLE-specific enums classes for GLEnum and functions operating +// on them. + +#ifndef LIBANGLE_PACKEDGLENUMS_AUTOGEN_H_ +#define LIBANGLE_PACKEDGLENUMS_AUTOGEN_H_ + +#include + +#include + +namespace gl +{ + +template +Enum FromGLenum(GLenum from); + +enum class BufferBinding : uint8_t +{ + Array = 0, + AtomicCounter = 1, + CopyRead = 2, + CopyWrite = 3, + DispatchIndirect = 4, + DrawIndirect = 5, + ElementArray = 6, + PixelPack = 7, + PixelUnpack = 8, + ShaderStorage = 9, + TransformFeedback = 10, + Uniform = 11, + + InvalidEnum = 12, + EnumCount = 12, +}; + +template <> +BufferBinding FromGLenum(GLenum from); +GLenum ToGLenum(BufferBinding from); + +enum class BufferUsage : uint8_t +{ + DynamicCopy = 0, + DynamicDraw = 1, + DynamicRead = 2, + StaticCopy = 3, + StaticDraw = 4, + StaticRead = 5, + StreamCopy = 6, + StreamDraw = 7, + StreamRead = 8, + + InvalidEnum = 9, + EnumCount = 9, +}; + +template <> +BufferUsage FromGLenum(GLenum from); +GLenum ToGLenum(BufferUsage from); + +enum class CullFaceMode : uint8_t +{ + Back = 0, + Front = 1, + FrontAndBack = 2, + + InvalidEnum = 3, + EnumCount = 3, +}; + +template <> +CullFaceMode FromGLenum(GLenum from); +GLenum ToGLenum(CullFaceMode from); + +} // namespace gl + +#endif // LIBANGLE_PACKEDGLENUMS_AUTOGEN_H_ diff --git a/src/3rdparty/angle/src/libANGLE/Path.cpp b/src/3rdparty/angle/src/libANGLE/Path.cpp new file mode 100644 index 0000000000..8f2ce9ef92 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/Path.cpp @@ -0,0 +1,78 @@ +// +// Copyright (c) 2002-2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Path.h: Defines the gl::Path class, representing CHROMIUM_path_rendering +// path object. + +#include "libANGLE/Path.h" +#include "libANGLE/renderer/PathImpl.h" + +#include "common/mathutil.h" +#include "common/debug.h" + +namespace gl +{ + +Path::Path(rx::PathImpl *impl) + : mPath(impl), + mHasData(false), + mEndCaps(GL_FLAT_CHROMIUM), + mJoinStyle(GL_MITER_REVERT_CHROMIUM), + mStrokeWidth(1.0f), + mStrokeBound(0.2f), + mMiterLimit(4.0f) +{ +} + +Path::~Path() +{ + delete mPath; +} + +Error Path::setCommands(GLsizei numCommands, + const GLubyte *commands, + GLsizei numCoords, + GLenum coordType, + const void *coords) +{ + ANGLE_TRY(mPath->setCommands(numCommands, commands, numCoords, coordType, coords)); + + mHasData = true; + + return NoError(); +} + +void Path::setStrokeWidth(GLfloat width) +{ + mStrokeWidth = width; + mPath->setPathParameter(GL_PATH_STROKE_WIDTH_CHROMIUM, mStrokeWidth); +} + +void Path::setStrokeBound(GLfloat bound) +{ + mStrokeBound = clamp(bound, 0.0f, 1.0f); + mPath->setPathParameter(GL_PATH_STROKE_BOUND_CHROMIUM, mStrokeBound); +} + +void Path::setEndCaps(GLenum type) +{ + mEndCaps = type; + mPath->setPathParameter(GL_PATH_END_CAPS_CHROMIUM, static_cast(type)); +} + +void Path::setJoinStyle(GLenum type) +{ + mJoinStyle = type; + mPath->setPathParameter(GL_PATH_JOIN_STYLE_CHROMIUM, static_cast(type)); +} + +void Path::setMiterLimit(GLfloat value) +{ + mMiterLimit = value; + mPath->setPathParameter(GL_PATH_MITER_LIMIT_CHROMIUM, value); +} + +} // gl diff --git a/src/3rdparty/angle/src/libANGLE/Path.h b/src/3rdparty/angle/src/libANGLE/Path.h new file mode 100644 index 0000000000..b103c84607 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/Path.h @@ -0,0 +1,71 @@ +// +// Copyright (c) 2002-2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Path.h: Defines the gl::Path class, representing CHROMIUM_path_rendering +// path object. + +#ifndef LIBANGLE_PATH_H_ +#define LIBANGLE_PATH_H_ + +#include "angle_gl.h" +#include "common/angleutils.h" +#include "libANGLE/Error.h" +#include "libANGLE/RefCountObject.h" + +namespace rx +{ +class PathImpl; +} + +namespace gl +{ +class Path final : angle::NonCopyable +{ + public: + Path(rx::PathImpl *impl); + + ~Path(); + + Error setCommands(GLsizei numCommands, + const GLubyte *commands, + GLsizei numCoords, + GLenum coordType, + const void *coords); + + void setStrokeWidth(GLfloat width); + void setStrokeBound(GLfloat bound); + void setEndCaps(GLenum type); + void setJoinStyle(GLenum type); + void setMiterLimit(GLfloat value); + + GLfloat getStrokeWidth() const { return mStrokeWidth; } + GLfloat getStrokeBound() const { return mStrokeBound; } + GLfloat getMiterLimit() const { return mMiterLimit; } + GLenum getEndCaps() const { return mEndCaps; } + GLenum getJoinStyle() const { return mJoinStyle; } + + bool hasPathData() const { return mHasData; } + + rx::PathImpl *getImplementation() const { return mPath; } + + private: + rx::PathImpl *mPath; + + // a Path object is not actually considered "a path" + // untill it has been specified with data. So we'll + // keep this flag to support this semantics. + bool mHasData; + + GLenum mEndCaps; + GLenum mJoinStyle; + GLfloat mStrokeWidth; + GLfloat mStrokeBound; + GLfloat mMiterLimit; +}; + +} // namespace gl + +#endif // LIBANGLE_PATH_H_ \ No newline at end of file diff --git a/src/3rdparty/angle/src/libANGLE/Platform.cpp b/src/3rdparty/angle/src/libANGLE/Platform.cpp index bfcdb1494e..702091624f 100644 --- a/src/3rdparty/angle/src/libANGLE/Platform.cpp +++ b/src/3rdparty/angle/src/libANGLE/Platform.cpp @@ -8,28 +8,62 @@ #include +#include + #include "common/debug.h" namespace { -angle::Platform *currentPlatform = nullptr; +// TODO(jmadill): Make methods owned by egl::Display. +angle::PlatformMethods g_platformMethods; +} // anonymous namespace + +angle::PlatformMethods::PlatformMethods() +{ } -// static -angle::Platform *ANGLE_APIENTRY ANGLEPlatformCurrent() +angle::PlatformMethods *ANGLEPlatformCurrent() { - return currentPlatform; + return &g_platformMethods; } -// static -void ANGLE_APIENTRY ANGLEPlatformInitialize(angle::Platform *platformImpl) +bool ANGLE_APIENTRY ANGLEGetDisplayPlatform(angle::EGLDisplayType display, + const char *const methodNames[], + unsigned int methodNameCount, + void *context, + void *platformMethods) { - ASSERT(platformImpl != nullptr); - currentPlatform = platformImpl; + angle::PlatformMethods **platformMethodsOut = + reinterpret_cast(platformMethods); + + // We allow for a lower input count of impl platform methods if the subset is correct. + if (methodNameCount > angle::g_NumPlatformMethods) + { + ERR() << "Invalid platform method count: " << methodNameCount << ", expected " + << angle::g_NumPlatformMethods << "."; + return false; + } + + for (unsigned int nameIndex = 0; nameIndex < methodNameCount; ++nameIndex) + { + const char *expectedName = angle::g_PlatformMethodNames[nameIndex]; + const char *actualName = methodNames[nameIndex]; + if (strcmp(expectedName, actualName) != 0) + { + ERR() << "Invalid platform method name: " << actualName << ", expected " << expectedName + << "."; + return false; + } + } + + // TODO(jmadill): Store platform methods in display. + g_platformMethods.context = context; + *platformMethodsOut = &g_platformMethods; + return true; } -// static -void ANGLE_APIENTRY ANGLEPlatformShutdown() +void ANGLE_APIENTRY ANGLEResetDisplayPlatform(angle::EGLDisplayType display) { - currentPlatform = nullptr; + // TODO(jmadill): Store platform methods in display. + g_platformMethods = angle::PlatformMethods(); } diff --git a/src/3rdparty/angle/src/libANGLE/Program.cpp b/src/3rdparty/angle/src/libANGLE/Program.cpp index 69497c4436..795d326041 100644 --- a/src/3rdparty/angle/src/libANGLE/Program.cpp +++ b/src/3rdparty/angle/src/libANGLE/Program.cpp @@ -11,18 +11,24 @@ #include -#include "common/BitSetIterator.h" +#include "common/bitset_utils.h" #include "common/debug.h" #include "common/platform.h" +#include "common/string_utils.h" #include "common/utilities.h" -#include "common/version.h" #include "compiler/translator/blocklayout.h" -#include "libANGLE/Data.h" +#include "libANGLE/Context.h" +#include "libANGLE/MemoryProgramCache.h" +#include "libANGLE/ProgramLinkedResources.h" #include "libANGLE/ResourceManager.h" +#include "libANGLE/Uniform.h" +#include "libANGLE/VaryingPacking.h" #include "libANGLE/features.h" -#include "libANGLE/renderer/Renderer.h" -#include "libANGLE/renderer/ProgramImpl.h" +#include "libANGLE/histogram_macros.h" #include "libANGLE/queryconversions.h" +#include "libANGLE/renderer/GLImplFactory.h" +#include "libANGLE/renderer/ProgramImpl.h" +#include "platform/Platform.h" namespace gl { @@ -30,29 +36,6 @@ namespace gl namespace { -void WriteShaderVar(BinaryOutputStream *stream, const sh::ShaderVariable &var) -{ - stream->writeInt(var.type); - stream->writeInt(var.precision); - stream->writeString(var.name); - stream->writeString(var.mappedName); - stream->writeInt(var.arraySize); - stream->writeInt(var.staticUse); - stream->writeString(var.structName); - ASSERT(var.fields.empty()); -} - -void LoadShaderVar(BinaryInputStream *stream, sh::ShaderVariable *var) -{ - var->type = stream->readInt(); - var->precision = stream->readInt(); - var->name = stream->readString(); - var->mappedName = stream->readString(); - var->arraySize = stream->readInt(); - var->staticUse = stream->readBool(); - var->structName = stream->readString(); -} - // This simplified cast function doesn't need to worry about advanced concepts like // depth range values, or casting to bool. template @@ -88,19 +71,19 @@ GLuint UniformStateQueryCast(GLint value) template <> GLfloat UniformStateQueryCast(GLboolean value) { - return (value == GL_TRUE ? 1.0f : 0.0f); + return (ConvertToBool(value) ? 1.0f : 0.0f); } template <> GLint UniformStateQueryCast(GLboolean value) { - return (value == GL_TRUE ? 1 : 0); + return (ConvertToBool(value) ? 1 : 0); } template <> GLuint UniformStateQueryCast(GLboolean value) { - return (value == GL_TRUE ? 1u : 0u); + return (ConvertToBool(value) ? 1u : 0u); } // Default to static_cast @@ -123,29 +106,224 @@ void UniformStateQueryCastLoop(DestT *dataOut, const uint8_t *srcPointer, int co } } -bool UniformInList(const std::vector &list, const std::string &name) +template +GLuint GetResourceIndexFromName(const std::vector &list, const std::string &name) { - for (const LinkedUniform &uniform : list) + std::string nameAsArrayName = name + "[0]"; + for (size_t index = 0; index < list.size(); index++) { - if (uniform.name == name) - return true; + const VarT &resource = list[index]; + if (resource.name == name || (resource.isArray() && resource.name == nameAsArrayName)) + { + return static_cast(index); + } } + return GL_INVALID_INDEX; +} + +template +GLint GetVariableLocation(const std::vector &list, + const std::vector &locationList, + const std::string &name) +{ + size_t nameLengthWithoutArrayIndex; + unsigned int arrayIndex = ParseArrayIndex(name, &nameLengthWithoutArrayIndex); + + for (size_t location = 0u; location < locationList.size(); ++location) + { + const VariableLocation &variableLocation = locationList[location]; + if (!variableLocation.used()) + { + continue; + } + + const VarT &variable = list[variableLocation.index]; + + if (angle::BeginsWith(variable.name, name)) + { + if (name.length() == variable.name.length()) + { + ASSERT(name == variable.name); + // GLES 3.1 November 2016 page 87. + // The string exactly matches the name of the active variable. + return static_cast(location); + } + if (name.length() + 3u == variable.name.length() && variable.isArray()) + { + ASSERT(name + "[0]" == variable.name); + // The string identifies the base name of an active array, where the string would + // exactly match the name of the variable if the suffix "[0]" were appended to the + // string. + return static_cast(location); + } + } + if (variable.isArray() && variableLocation.arrayIndex == arrayIndex && + nameLengthWithoutArrayIndex + 3u == variable.name.length() && + angle::BeginsWith(variable.name, name, nameLengthWithoutArrayIndex)) + { + ASSERT(name.substr(0u, nameLengthWithoutArrayIndex) + "[0]" == variable.name); + // The string identifies an active element of the array, where the string ends with the + // concatenation of the "[" character, an integer (with no "+" sign, extra leading + // zeroes, or whitespace) identifying an array element, and the "]" character, the + // integer is less than the number of active elements of the array variable, and where + // the string would exactly match the enumerated name of the array if the decimal + // integer were replaced with zero. + return static_cast(location); + } + } + + return -1; +} + +void CopyStringToBuffer(GLchar *buffer, const std::string &string, GLsizei bufSize, GLsizei *length) +{ + ASSERT(bufSize > 0); + strncpy(buffer, string.c_str(), bufSize); + buffer[bufSize - 1] = '\0'; + + if (length) + { + *length = static_cast(strlen(buffer)); + } +} + +bool IncludeSameArrayElement(const std::set &nameSet, const std::string &name) +{ + std::vector subscripts; + std::string baseName = ParseResourceName(name, &subscripts); + for (auto nameInSet : nameSet) + { + std::vector arrayIndices; + std::string arrayName = ParseResourceName(nameInSet, &arrayIndices); + if (baseName == arrayName && + (subscripts.empty() || arrayIndices.empty() || subscripts == arrayIndices)) + { + return true; + } + } return false; } +bool validateInterfaceBlocksCount(GLuint maxInterfaceBlocks, + const std::vector &interfaceBlocks, + const std::string &errorMessage, + InfoLog &infoLog) +{ + GLuint blockCount = 0; + for (const sh::InterfaceBlock &block : interfaceBlocks) + { + if (block.staticUse || block.layout != sh::BLOCKLAYOUT_PACKED) + { + blockCount += (block.arraySize ? block.arraySize : 1); + if (blockCount > maxInterfaceBlocks) + { + infoLog << errorMessage << maxInterfaceBlocks << ")"; + return false; + } + } + } + return true; +} + +GLuint GetInterfaceBlockIndex(const std::vector &list, const std::string &name) +{ + std::vector subscripts; + std::string baseName = ParseResourceName(name, &subscripts); + + unsigned int numBlocks = static_cast(list.size()); + for (unsigned int blockIndex = 0; blockIndex < numBlocks; blockIndex++) + { + const auto &block = list[blockIndex]; + if (block.name == baseName) + { + const bool arrayElementZero = + (subscripts.empty() && (!block.isArray || block.arrayElement == 0)); + const bool arrayElementMatches = + (subscripts.size() == 1 && subscripts[0] == block.arrayElement); + if (arrayElementMatches || arrayElementZero) + { + return blockIndex; + } + } + } + + return GL_INVALID_INDEX; +} + +void GetInterfaceBlockName(const GLuint index, + const std::vector &list, + GLsizei bufSize, + GLsizei *length, + GLchar *name) +{ + ASSERT(index < list.size()); + + const auto &block = list[index]; + + if (bufSize > 0) + { + std::string blockName = block.name; + + if (block.isArray) + { + blockName += ArrayString(block.arrayElement); + } + CopyStringToBuffer(name, blockName, bufSize, length); + } +} + +void InitUniformBlockLinker(const gl::Context *context, + const ProgramState &state, + UniformBlockLinker *blockLinker) +{ + if (state.getAttachedVertexShader()) + { + blockLinker->addShaderBlocks(GL_VERTEX_SHADER, + &state.getAttachedVertexShader()->getUniformBlocks(context)); + } + + if (state.getAttachedFragmentShader()) + { + blockLinker->addShaderBlocks(GL_FRAGMENT_SHADER, + &state.getAttachedFragmentShader()->getUniformBlocks(context)); + } + + if (state.getAttachedComputeShader()) + { + blockLinker->addShaderBlocks(GL_COMPUTE_SHADER, + &state.getAttachedComputeShader()->getUniformBlocks(context)); + } +} + +void InitShaderStorageBlockLinker(const gl::Context *context, + const ProgramState &state, + ShaderStorageBlockLinker *blockLinker) +{ + if (state.getAttachedVertexShader()) + { + blockLinker->addShaderBlocks( + GL_VERTEX_SHADER, &state.getAttachedVertexShader()->getShaderStorageBlocks(context)); + } + + if (state.getAttachedFragmentShader()) + { + blockLinker->addShaderBlocks( + GL_FRAGMENT_SHADER, + &state.getAttachedFragmentShader()->getShaderStorageBlocks(context)); + } + + if (state.getAttachedComputeShader()) + { + blockLinker->addShaderBlocks( + GL_COMPUTE_SHADER, &state.getAttachedComputeShader()->getShaderStorageBlocks(context)); + } +} + } // anonymous namespace const char *const g_fakepath = "C:\\fakepath"; -AttributeBindings::AttributeBindings() -{ -} - -AttributeBindings::~AttributeBindings() -{ -} - InfoLog::InfoLog() { } @@ -156,7 +334,12 @@ InfoLog::~InfoLog() size_t InfoLog::getLength() const { - const std::string &logString = mStream.str(); + if (!mLazyStream) + { + return 0; + } + + const std::string &logString = mLazyStream->str(); return logString.empty() ? 0 : logString.length() + 1; } @@ -166,12 +349,12 @@ void InfoLog::getLog(GLsizei bufSize, GLsizei *length, char *infoLog) const if (bufSize > 0) { - const std::string str(mStream.str()); + const std::string logString(str()); - if (!str.empty()) + if (!logString.empty()) { - index = std::min(static_cast(bufSize) - 1, str.length()); - memcpy(infoLog, str.c_str(), index); + index = std::min(static_cast(bufSize) - 1, logString.length()); + memcpy(infoLog, logString.c_str(), index); } infoLog[index] = '\0'; @@ -184,10 +367,12 @@ void InfoLog::getLog(GLsizei bufSize, GLsizei *length, char *infoLog) const } // append a santized message to the program info log. -// The D3D compiler includes a fake file path in some of the warning or error +// The D3D compiler includes a fake file path in some of the warning or error // messages, so lets remove all occurrences of this fake file path from the log. void InfoLog::appendSanitized(const char *message) { + ensureInitialized(); + std::string msg(message); size_t found; @@ -201,328 +386,627 @@ void InfoLog::appendSanitized(const char *message) } while (found != std::string::npos); - mStream << message << std::endl; + *mLazyStream << message << std::endl; } void InfoLog::reset() { } -VariableLocation::VariableLocation() - : name(), - element(0), - index(0) +VariableLocation::VariableLocation() : arrayIndex(0), index(kUnused), ignored(false) { } -VariableLocation::VariableLocation(const std::string &name, unsigned int element, unsigned int index) - : name(name), - element(element), - index(index) +VariableLocation::VariableLocation(unsigned int arrayIndex, unsigned int index) + : arrayIndex(arrayIndex), index(index), ignored(false) +{ + ASSERT(arrayIndex != GL_INVALID_INDEX); +} + +SamplerBinding::SamplerBinding(GLenum textureTypeIn, size_t elementCount, bool unreferenced) + : textureType(textureTypeIn), boundTextureUnits(elementCount, 0), unreferenced(unreferenced) { } -Program::Data::Data() +SamplerBinding::SamplerBinding(const SamplerBinding &other) = default; + +SamplerBinding::~SamplerBinding() = default; + +Program::Bindings::Bindings() +{ +} + +Program::Bindings::~Bindings() +{ +} + +void Program::Bindings::bindLocation(GLuint index, const std::string &name) +{ + mBindings[name] = index; +} + +int Program::Bindings::getBinding(const std::string &name) const +{ + auto iter = mBindings.find(name); + return (iter != mBindings.end()) ? iter->second : -1; +} + +Program::Bindings::const_iterator Program::Bindings::begin() const +{ + return mBindings.begin(); +} + +Program::Bindings::const_iterator Program::Bindings::end() const +{ + return mBindings.end(); +} + +ImageBinding::ImageBinding(size_t count) : boundImageUnits(count, 0) +{ +} +ImageBinding::ImageBinding(GLuint imageUnit, size_t count) +{ + for (size_t index = 0; index < count; ++index) + { + boundImageUnits.push_back(imageUnit + static_cast(index)); + } +} + +ImageBinding::ImageBinding(const ImageBinding &other) = default; + +ImageBinding::~ImageBinding() = default; + +ProgramState::ProgramState() : mLabel(), mAttachedFragmentShader(nullptr), mAttachedVertexShader(nullptr), + mAttachedComputeShader(nullptr), + mAttachedGeometryShader(nullptr), mTransformFeedbackBufferMode(GL_INTERLEAVED_ATTRIBS), - mBinaryRetrieveableHint(false) + mMaxActiveAttribLocation(0), + mSamplerUniformRange(0, 0), + mImageUniformRange(0, 0), + mAtomicCounterUniformRange(0, 0), + mBinaryRetrieveableHint(false), + mNumViews(-1) { + mComputeShaderLocalSize.fill(1); } -Program::Data::~Data() +ProgramState::~ProgramState() { - if (mAttachedVertexShader != nullptr) - { - mAttachedVertexShader->release(); - } - - if (mAttachedFragmentShader != nullptr) - { - mAttachedFragmentShader->release(); - } + ASSERT(!mAttachedVertexShader && !mAttachedFragmentShader && !mAttachedComputeShader && + !mAttachedGeometryShader); } -const std::string &Program::Data::getLabel() +const std::string &ProgramState::getLabel() { return mLabel; } -const LinkedUniform *Program::Data::getUniformByName(const std::string &name) const +GLuint ProgramState::getUniformIndexFromName(const std::string &name) const { - for (const LinkedUniform &linkedUniform : mUniforms) + return GetResourceIndexFromName(mUniforms, name); +} + +GLuint ProgramState::getBufferVariableIndexFromName(const std::string &name) const +{ + return GetResourceIndexFromName(mBufferVariables, name); +} + +GLuint ProgramState::getUniformIndexFromLocation(GLint location) const +{ + ASSERT(location >= 0 && static_cast(location) < mUniformLocations.size()); + return mUniformLocations[location].index; +} + +Optional ProgramState::getSamplerIndex(GLint location) const +{ + GLuint index = getUniformIndexFromLocation(location); + if (!isSamplerUniformIndex(index)) { - if (linkedUniform.name == name) + return Optional::Invalid(); + } + + return getSamplerIndexFromUniformIndex(index); +} + +bool ProgramState::isSamplerUniformIndex(GLuint index) const +{ + return mSamplerUniformRange.contains(index); +} + +GLuint ProgramState::getSamplerIndexFromUniformIndex(GLuint uniformIndex) const +{ + ASSERT(isSamplerUniformIndex(uniformIndex)); + return uniformIndex - mSamplerUniformRange.low(); +} + +GLuint ProgramState::getAttributeLocation(const std::string &name) const +{ + for (const sh::Attribute &attribute : mAttributes) + { + if (attribute.name == name) { - return &linkedUniform; + return attribute.location; } } - return nullptr; + return static_cast(-1); } -GLint Program::Data::getUniformLocation(const std::string &name) const -{ - size_t subscript = GL_INVALID_INDEX; - std::string baseName = gl::ParseUniformName(name, &subscript); - - for (size_t location = 0; location < mUniformLocations.size(); ++location) - { - const VariableLocation &uniformLocation = mUniformLocations[location]; - const LinkedUniform &uniform = mUniforms[uniformLocation.index]; - - if (uniform.name == baseName) - { - if ((uniform.isArray() && uniformLocation.element == subscript) || - (subscript == GL_INVALID_INDEX)) - { - return static_cast(location); - } - } - } - - return -1; -} - -GLuint Program::Data::getUniformIndex(const std::string &name) const -{ - size_t subscript = GL_INVALID_INDEX; - std::string baseName = gl::ParseUniformName(name, &subscript); - - // The app is not allowed to specify array indices other than 0 for arrays of basic types - if (subscript != 0 && subscript != GL_INVALID_INDEX) - { - return GL_INVALID_INDEX; - } - - for (size_t index = 0; index < mUniforms.size(); index++) - { - const LinkedUniform &uniform = mUniforms[index]; - if (uniform.name == baseName) - { - if (uniform.isArray() || subscript == GL_INVALID_INDEX) - { - return static_cast(index); - } - } - } - - return GL_INVALID_INDEX; -} - -Program::Program(rx::ImplFactory *factory, ResourceManager *manager, GLuint handle) - : mProgram(factory->createProgram(mData)), +Program::Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, GLuint handle) + : mProgram(factory->createProgram(mState)), mValidated(false), mLinked(false), mDeleteStatus(false), mRefCount(0), mResourceManager(manager), - mHandle(handle), - mSamplerUniformRange(0, 0) + mHandle(handle) { ASSERT(mProgram); - resetUniformBlockBindings(); unlink(); } Program::~Program() { - unlink(true); + ASSERT(!mProgram); +} +void Program::onDestroy(const Context *context) +{ + if (mState.mAttachedVertexShader != nullptr) + { + mState.mAttachedVertexShader->release(context); + mState.mAttachedVertexShader = nullptr; + } + + if (mState.mAttachedFragmentShader != nullptr) + { + mState.mAttachedFragmentShader->release(context); + mState.mAttachedFragmentShader = nullptr; + } + + if (mState.mAttachedComputeShader != nullptr) + { + mState.mAttachedComputeShader->release(context); + mState.mAttachedComputeShader = nullptr; + } + + if (mState.mAttachedGeometryShader != nullptr) + { + mState.mAttachedGeometryShader->release(context); + mState.mAttachedGeometryShader = nullptr; + } + + mProgram->destroy(context); + + ASSERT(!mState.mAttachedVertexShader && !mState.mAttachedFragmentShader && + !mState.mAttachedComputeShader && !mState.mAttachedGeometryShader); SafeDelete(mProgram); + + delete this; } void Program::setLabel(const std::string &label) { - mData.mLabel = label; + mState.mLabel = label; } const std::string &Program::getLabel() const { - return mData.mLabel; + return mState.mLabel; } -bool Program::attachShader(Shader *shader) +void Program::attachShader(Shader *shader) { - if (shader->getType() == GL_VERTEX_SHADER) + switch (shader->getType()) { - if (mData.mAttachedVertexShader) + case GL_VERTEX_SHADER: { - return false; + ASSERT(!mState.mAttachedVertexShader); + mState.mAttachedVertexShader = shader; + mState.mAttachedVertexShader->addRef(); + break; } - - mData.mAttachedVertexShader = shader; - mData.mAttachedVertexShader->addRef(); - } - else if (shader->getType() == GL_FRAGMENT_SHADER) - { - if (mData.mAttachedFragmentShader) + case GL_FRAGMENT_SHADER: { - return false; + ASSERT(!mState.mAttachedFragmentShader); + mState.mAttachedFragmentShader = shader; + mState.mAttachedFragmentShader->addRef(); + break; } - - mData.mAttachedFragmentShader = shader; - mData.mAttachedFragmentShader->addRef(); + case GL_COMPUTE_SHADER: + { + ASSERT(!mState.mAttachedComputeShader); + mState.mAttachedComputeShader = shader; + mState.mAttachedComputeShader->addRef(); + break; + } + case GL_GEOMETRY_SHADER_EXT: + { + ASSERT(!mState.mAttachedGeometryShader); + mState.mAttachedGeometryShader = shader; + mState.mAttachedGeometryShader->addRef(); + break; + } + default: + UNREACHABLE(); } - else UNREACHABLE(); - - return true; } -bool Program::detachShader(Shader *shader) +void Program::detachShader(const Context *context, Shader *shader) { - if (shader->getType() == GL_VERTEX_SHADER) + switch (shader->getType()) { - if (mData.mAttachedVertexShader != shader) + case GL_VERTEX_SHADER: { - return false; + ASSERT(mState.mAttachedVertexShader == shader); + shader->release(context); + mState.mAttachedVertexShader = nullptr; + break; } - - shader->release(); - mData.mAttachedVertexShader = nullptr; - } - else if (shader->getType() == GL_FRAGMENT_SHADER) - { - if (mData.mAttachedFragmentShader != shader) + case GL_FRAGMENT_SHADER: { - return false; + ASSERT(mState.mAttachedFragmentShader == shader); + shader->release(context); + mState.mAttachedFragmentShader = nullptr; + break; } - - shader->release(); - mData.mAttachedFragmentShader = nullptr; + case GL_COMPUTE_SHADER: + { + ASSERT(mState.mAttachedComputeShader == shader); + shader->release(context); + mState.mAttachedComputeShader = nullptr; + break; + } + case GL_GEOMETRY_SHADER_EXT: + { + ASSERT(mState.mAttachedGeometryShader == shader); + shader->release(context); + mState.mAttachedGeometryShader = nullptr; + break; + } + default: + UNREACHABLE(); } - else UNREACHABLE(); - - return true; } int Program::getAttachedShadersCount() const { - return (mData.mAttachedVertexShader ? 1 : 0) + (mData.mAttachedFragmentShader ? 1 : 0); -} - -void AttributeBindings::bindAttributeLocation(GLuint index, const char *name) -{ - if (index < MAX_VERTEX_ATTRIBS) - { - for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) - { - mAttributeBinding[i].erase(name); - } - - mAttributeBinding[index].insert(name); - } + return (mState.mAttachedVertexShader ? 1 : 0) + (mState.mAttachedFragmentShader ? 1 : 0) + + (mState.mAttachedComputeShader ? 1 : 0) + (mState.mAttachedGeometryShader ? 1 : 0); } void Program::bindAttributeLocation(GLuint index, const char *name) { - mAttributeBindings.bindAttributeLocation(index, name); + mAttributeBindings.bindLocation(index, name); } -// Links the HLSL code of the vertex and pixel shader by matching up their varyings, -// compiling them into binaries, determining the attribute mappings, and collecting -// a list of uniforms -Error Program::link(const gl::Data &data) +void Program::bindUniformLocation(GLuint index, const char *name) { - unlink(false); - - mInfoLog.reset(); - resetUniformBlockBindings(); - - if (!mData.mAttachedFragmentShader || !mData.mAttachedFragmentShader->isCompiled()) - { - return Error(GL_NO_ERROR); - } - ASSERT(mData.mAttachedFragmentShader->getType() == GL_FRAGMENT_SHADER); - - if (!mData.mAttachedVertexShader || !mData.mAttachedVertexShader->isCompiled()) - { - return Error(GL_NO_ERROR); - } - ASSERT(mData.mAttachedVertexShader->getType() == GL_VERTEX_SHADER); - - if (!linkAttributes(data, mInfoLog, mAttributeBindings, mData.mAttachedVertexShader)) - { - return Error(GL_NO_ERROR); - } - - if (!linkVaryings(mInfoLog, mData.mAttachedVertexShader, mData.mAttachedFragmentShader)) - { - return Error(GL_NO_ERROR); - } - - if (!linkUniforms(mInfoLog, *data.caps)) - { - return Error(GL_NO_ERROR); - } - - if (!linkUniformBlocks(mInfoLog, *data.caps)) - { - return Error(GL_NO_ERROR); - } - - const auto &mergedVaryings = getMergedVaryings(); - - if (!linkValidateTransformFeedback(mInfoLog, mergedVaryings, *data.caps)) - { - return Error(GL_NO_ERROR); - } - - linkOutputVariables(); - - rx::LinkResult result = mProgram->link(data, mInfoLog); - if (result.error.isError() || !result.linkSuccess) - { - return result.error; - } - - gatherTransformFeedbackVaryings(mergedVaryings); - gatherInterfaceBlockInfo(); - - mLinked = true; - return gl::Error(GL_NO_ERROR); + mUniformLocationBindings.bindLocation(index, name); } -int AttributeBindings::getAttributeBinding(const std::string &name) const +void Program::bindFragmentInputLocation(GLint index, const char *name) { - for (int location = 0; location < MAX_VERTEX_ATTRIBS; location++) + mFragmentInputBindings.bindLocation(index, name); +} + +BindingInfo Program::getFragmentInputBindingInfo(const Context *context, GLint index) const +{ + BindingInfo ret; + ret.type = GL_NONE; + ret.valid = false; + + Shader *fragmentShader = mState.getAttachedFragmentShader(); + ASSERT(fragmentShader); + + // Find the actual fragment shader varying we're interested in + const std::vector &inputs = fragmentShader->getInputVaryings(context); + + for (const auto &binding : mFragmentInputBindings) { - if (mAttributeBinding[location].find(name) != mAttributeBinding[location].end()) + if (binding.second != static_cast(index)) + continue; + + ret.valid = true; + + size_t nameLengthWithoutArrayIndex; + unsigned int arrayIndex = ParseArrayIndex(binding.first, &nameLengthWithoutArrayIndex); + + for (const auto &in : inputs) { - return location; + if (in.name.length() == nameLengthWithoutArrayIndex && + angle::BeginsWith(in.name, binding.first, nameLengthWithoutArrayIndex)) + { + if (in.isArray()) + { + // The client wants to bind either "name" or "name[0]". + // GL ES 3.1 spec refers to active array names with language such as: + // "if the string identifies the base name of an active array, where the + // string would exactly match the name of the variable if the suffix "[0]" + // were appended to the string". + if (arrayIndex == GL_INVALID_INDEX) + arrayIndex = 0; + + ret.name = in.mappedName + "[" + ToString(arrayIndex) + "]"; + } + else + { + ret.name = in.mappedName; + } + ret.type = in.type; + return ret; + } } } - return -1; + return ret; +} + +void Program::pathFragmentInputGen(const Context *context, + GLint index, + GLenum genMode, + GLint components, + const GLfloat *coeffs) +{ + // If the location is -1 then the command is silently ignored + if (index == -1) + return; + + const auto &binding = getFragmentInputBindingInfo(context, index); + + // If the input doesn't exist then then the command is silently ignored + // This could happen through optimization for example, the shader translator + // decides that a variable is not actually being used and optimizes it away. + if (binding.name.empty()) + return; + + mProgram->setPathFragmentInputGen(binding.name, genMode, components, coeffs); +} + +// The attached shaders are checked for linking errors by matching up their variables. +// Uniform, input and output variables get collected. +// The code gets compiled into binaries. +Error Program::link(const gl::Context *context) +{ + const auto &data = context->getContextState(); + + auto *platform = ANGLEPlatformCurrent(); + double startTime = platform->currentTime(platform); + + unlink(); + + ProgramHash programHash; + auto *cache = context->getMemoryProgramCache(); + if (cache) + { + ANGLE_TRY_RESULT(cache->getProgram(context, this, &mState, &programHash), mLinked); + ANGLE_HISTOGRAM_BOOLEAN("GPU.ANGLE.ProgramCache.LoadBinarySuccess", mLinked); + } + + if (mLinked) + { + double delta = platform->currentTime(platform) - startTime; + int us = static_cast(delta * 1000000.0); + ANGLE_HISTOGRAM_COUNTS("GPU.ANGLE.ProgramCache.ProgramCacheHitTimeUS", us); + return NoError(); + } + + // Cache load failed, fall through to normal linking. + unlink(); + mInfoLog.reset(); + + const Caps &caps = data.getCaps(); + + Shader *vertexShader = mState.mAttachedVertexShader; + Shader *fragmentShader = mState.mAttachedFragmentShader; + Shader *computeShader = mState.mAttachedComputeShader; + + bool isComputeShaderAttached = (computeShader != nullptr); + bool nonComputeShadersAttached = (vertexShader != nullptr || fragmentShader != nullptr); + // Check whether we both have a compute and non-compute shaders attached. + // If there are of both types attached, then linking should fail. + // OpenGL ES 3.10, 7.3 Program Objects, under LinkProgram + if (isComputeShaderAttached == true && nonComputeShadersAttached == true) + { + mInfoLog << "Both a compute and non-compute shaders are attached to the same program."; + return NoError(); + } + + if (computeShader) + { + if (!computeShader->isCompiled(context)) + { + mInfoLog << "Attached compute shader is not compiled."; + return NoError(); + } + ASSERT(computeShader->getType() == GL_COMPUTE_SHADER); + + mState.mComputeShaderLocalSize = computeShader->getWorkGroupSize(context); + + // GLSL ES 3.10, 4.4.1.1 Compute Shader Inputs + // If the work group size is not specified, a link time error should occur. + if (!mState.mComputeShaderLocalSize.isDeclared()) + { + mInfoLog << "Work group size is not specified."; + return NoError(); + } + + if (!linkUniforms(context, mInfoLog, mUniformLocationBindings)) + { + return NoError(); + } + + if (!linkInterfaceBlocks(context, mInfoLog)) + { + return NoError(); + } + + ProgramLinkedResources resources = { + {0, PackMode::ANGLE_RELAXED}, + {&mState.mUniformBlocks, &mState.mUniforms}, + {&mState.mShaderStorageBlocks, &mState.mBufferVariables}}; + + InitUniformBlockLinker(context, mState, &resources.uniformBlockLinker); + InitShaderStorageBlockLinker(context, mState, &resources.shaderStorageBlockLinker); + + ANGLE_TRY_RESULT(mProgram->link(context, resources, mInfoLog), mLinked); + if (!mLinked) + { + return NoError(); + } + } + else + { + if (!fragmentShader || !fragmentShader->isCompiled(context)) + { + return NoError(); + } + ASSERT(fragmentShader->getType() == GL_FRAGMENT_SHADER); + + if (!vertexShader || !vertexShader->isCompiled(context)) + { + return NoError(); + } + ASSERT(vertexShader->getType() == GL_VERTEX_SHADER); + + if (fragmentShader->getShaderVersion(context) != vertexShader->getShaderVersion(context)) + { + mInfoLog << "Fragment shader version does not match vertex shader version."; + return NoError(); + } + + if (!linkAttributes(context, mInfoLog)) + { + return NoError(); + } + + if (!linkVaryings(context, mInfoLog)) + { + return NoError(); + } + + if (!linkUniforms(context, mInfoLog, mUniformLocationBindings)) + { + return NoError(); + } + + if (!linkInterfaceBlocks(context, mInfoLog)) + { + return NoError(); + } + + if (!linkValidateGlobalNames(context, mInfoLog)) + { + return NoError(); + } + + const auto &mergedVaryings = getMergedVaryings(context); + + mState.mNumViews = vertexShader->getNumViews(context); + + linkOutputVariables(context); + + // Map the varyings to the register file + // In WebGL, we use a slightly different handling for packing variables. + auto packMode = data.getExtensions().webglCompatibility ? PackMode::WEBGL_STRICT + : PackMode::ANGLE_RELAXED; + + ProgramLinkedResources resources = { + {data.getCaps().maxVaryingVectors, packMode}, + {&mState.mUniformBlocks, &mState.mUniforms}, + {&mState.mShaderStorageBlocks, &mState.mBufferVariables}}; + + InitUniformBlockLinker(context, mState, &resources.uniformBlockLinker); + InitShaderStorageBlockLinker(context, mState, &resources.shaderStorageBlockLinker); + + if (!linkValidateTransformFeedback(context, mInfoLog, mergedVaryings, caps)) + { + return NoError(); + } + + if (!resources.varyingPacking.collectAndPackUserVaryings( + mInfoLog, mergedVaryings, mState.getTransformFeedbackVaryingNames())) + { + return NoError(); + } + + ANGLE_TRY_RESULT(mProgram->link(context, resources, mInfoLog), mLinked); + if (!mLinked) + { + return NoError(); + } + + gatherTransformFeedbackVaryings(mergedVaryings); + } + + gatherAtomicCounterBuffers(); + initInterfaceBlockBindings(); + + setUniformValuesFromBindingQualifiers(); + + ASSERT(mLinked); + updateLinkedShaderStages(); + + // Mark implementation-specific unreferenced uniforms as ignored. + mProgram->markUnusedUniformLocations(&mState.mUniformLocations, &mState.mSamplerBindings); + + // Save to the program cache. + if (cache && (mState.mLinkedTransformFeedbackVaryings.empty() || + !context->getWorkarounds().disableProgramCachingForTransformFeedback)) + { + cache->putProgram(programHash, context, this); + } + + double delta = platform->currentTime(platform) - startTime; + int us = static_cast(delta * 1000000.0); + ANGLE_HISTOGRAM_COUNTS("GPU.ANGLE.ProgramCache.ProgramCacheMissTimeUS", us); + + return NoError(); +} + +void Program::updateLinkedShaderStages() +{ + if (mState.mAttachedVertexShader) + { + mState.mLinkedShaderStages.set(SHADER_VERTEX); + } + + if (mState.mAttachedFragmentShader) + { + mState.mLinkedShaderStages.set(SHADER_FRAGMENT); + } + + if (mState.mAttachedComputeShader) + { + mState.mLinkedShaderStages.set(SHADER_COMPUTE); + } } // Returns the program object to an unlinked state, before re-linking, or at destruction -void Program::unlink(bool destroy) +void Program::unlink() { - if (destroy) // Object being destructed - { - if (mData.mAttachedFragmentShader) - { - mData.mAttachedFragmentShader->release(); - mData.mAttachedFragmentShader = nullptr; - } - - if (mData.mAttachedVertexShader) - { - mData.mAttachedVertexShader->release(); - mData.mAttachedVertexShader = nullptr; - } - } - - mData.mAttributes.clear(); - mData.mActiveAttribLocationsMask.reset(); - mData.mTransformFeedbackVaryingVars.clear(); - mData.mUniforms.clear(); - mData.mUniformLocations.clear(); - mData.mUniformBlocks.clear(); - mData.mOutputVariables.clear(); + mState.mAttributes.clear(); + mState.mActiveAttribLocationsMask.reset(); + mState.mMaxActiveAttribLocation = 0; + mState.mLinkedTransformFeedbackVaryings.clear(); + mState.mUniforms.clear(); + mState.mUniformLocations.clear(); + mState.mUniformBlocks.clear(); + mState.mActiveUniformBlockBindings.reset(); + mState.mAtomicCounterBuffers.clear(); + mState.mOutputVariables.clear(); + mState.mOutputLocations.clear(); + mState.mOutputVariableTypes.clear(); + mState.mActiveOutputVariables.reset(); + mState.mComputeShaderLocalSize.fill(1); + mState.mSamplerBindings.clear(); + mState.mImageBindings.clear(); + mState.mNumViews = -1; + mState.mLinkedShaderStages.reset(); mValidated = false; @@ -534,236 +1018,50 @@ bool Program::isLinked() const return mLinked; } -Error Program::loadBinary(GLenum binaryFormat, const void *binary, GLsizei length) +Error Program::loadBinary(const Context *context, + GLenum binaryFormat, + const void *binary, + GLsizei length) { - unlink(false); + unlink(); #if ANGLE_PROGRAM_BINARY_LOAD != ANGLE_ENABLED - return Error(GL_NO_ERROR); + return NoError(); #else ASSERT(binaryFormat == GL_PROGRAM_BINARY_ANGLE); if (binaryFormat != GL_PROGRAM_BINARY_ANGLE) { mInfoLog << "Invalid program binary format."; - return Error(GL_NO_ERROR); + return NoError(); } - BinaryInputStream stream(binary, length); + const uint8_t *bytes = reinterpret_cast(binary); + ANGLE_TRY_RESULT( + MemoryProgramCache::Deserialize(context, this, &mState, bytes, length, mInfoLog), mLinked); - int majorVersion = stream.readInt(); - int minorVersion = stream.readInt(); - if (majorVersion != ANGLE_MAJOR_VERSION || minorVersion != ANGLE_MINOR_VERSION) - { - mInfoLog << "Invalid program binary version."; - return Error(GL_NO_ERROR); - } + // Currently we require the full shader text to compute the program hash. + // TODO(jmadill): Store the binary in the internal program cache. - unsigned char commitString[ANGLE_COMMIT_HASH_SIZE]; - stream.readBytes(commitString, ANGLE_COMMIT_HASH_SIZE); - if (memcmp(commitString, ANGLE_COMMIT_HASH, sizeof(unsigned char) * ANGLE_COMMIT_HASH_SIZE) != 0) - { - mInfoLog << "Invalid program binary version."; - return Error(GL_NO_ERROR); - } - - static_assert(MAX_VERTEX_ATTRIBS <= sizeof(unsigned long) * 8, - "Too many vertex attribs for mask"); - mData.mActiveAttribLocationsMask = stream.readInt(); - - unsigned int attribCount = stream.readInt(); - ASSERT(mData.mAttributes.empty()); - for (unsigned int attribIndex = 0; attribIndex < attribCount; ++attribIndex) - { - sh::Attribute attrib; - LoadShaderVar(&stream, &attrib); - attrib.location = stream.readInt(); - mData.mAttributes.push_back(attrib); - } - - unsigned int uniformCount = stream.readInt(); - ASSERT(mData.mUniforms.empty()); - for (unsigned int uniformIndex = 0; uniformIndex < uniformCount; ++uniformIndex) - { - LinkedUniform uniform; - LoadShaderVar(&stream, &uniform); - - uniform.blockIndex = stream.readInt(); - uniform.blockInfo.offset = stream.readInt(); - uniform.blockInfo.arrayStride = stream.readInt(); - uniform.blockInfo.matrixStride = stream.readInt(); - uniform.blockInfo.isRowMajorMatrix = stream.readBool(); - - mData.mUniforms.push_back(uniform); - } - - const unsigned int uniformIndexCount = stream.readInt(); - ASSERT(mData.mUniformLocations.empty()); - for (unsigned int uniformIndexIndex = 0; uniformIndexIndex < uniformIndexCount; - uniformIndexIndex++) - { - VariableLocation variable; - stream.readString(&variable.name); - stream.readInt(&variable.element); - stream.readInt(&variable.index); - - mData.mUniformLocations.push_back(variable); - } - - unsigned int uniformBlockCount = stream.readInt(); - ASSERT(mData.mUniformBlocks.empty()); - for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlockCount; - ++uniformBlockIndex) - { - UniformBlock uniformBlock; - stream.readString(&uniformBlock.name); - stream.readBool(&uniformBlock.isArray); - stream.readInt(&uniformBlock.arrayElement); - stream.readInt(&uniformBlock.dataSize); - stream.readBool(&uniformBlock.vertexStaticUse); - stream.readBool(&uniformBlock.fragmentStaticUse); - - unsigned int numMembers = stream.readInt(); - for (unsigned int blockMemberIndex = 0; blockMemberIndex < numMembers; blockMemberIndex++) - { - uniformBlock.memberUniformIndexes.push_back(stream.readInt()); - } - - mData.mUniformBlocks.push_back(uniformBlock); - } - - unsigned int transformFeedbackVaryingCount = stream.readInt(); - ASSERT(mData.mTransformFeedbackVaryingVars.empty()); - for (unsigned int transformFeedbackVaryingIndex = 0; - transformFeedbackVaryingIndex < transformFeedbackVaryingCount; - ++transformFeedbackVaryingIndex) - { - sh::Varying varying; - stream.readInt(&varying.arraySize); - stream.readInt(&varying.type); - stream.readString(&varying.name); - - mData.mTransformFeedbackVaryingVars.push_back(varying); - } - - stream.readInt(&mData.mTransformFeedbackBufferMode); - - unsigned int outputVarCount = stream.readInt(); - for (unsigned int outputIndex = 0; outputIndex < outputVarCount; ++outputIndex) - { - int locationIndex = stream.readInt(); - VariableLocation locationData; - stream.readInt(&locationData.element); - stream.readInt(&locationData.index); - stream.readString(&locationData.name); - mData.mOutputVariables[locationIndex] = locationData; - } - - stream.readInt(&mSamplerUniformRange.start); - stream.readInt(&mSamplerUniformRange.end); - - rx::LinkResult result = mProgram->load(mInfoLog, &stream); - if (result.error.isError() || !result.linkSuccess) - { - return result.error; - } - - mLinked = true; - return Error(GL_NO_ERROR); -#endif // #if ANGLE_PROGRAM_BINARY_LOAD == ANGLE_ENABLED + return NoError(); +#endif // #if ANGLE_PROGRAM_BINARY_LOAD == ANGLE_ENABLED } -Error Program::saveBinary(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length) const +Error Program::saveBinary(const Context *context, + GLenum *binaryFormat, + void *binary, + GLsizei bufSize, + GLsizei *length) const { if (binaryFormat) { *binaryFormat = GL_PROGRAM_BINARY_ANGLE; } - BinaryOutputStream stream; + angle::MemoryBuffer memoryBuf; + MemoryProgramCache::Serialize(context, this, &memoryBuf); - stream.writeInt(ANGLE_MAJOR_VERSION); - stream.writeInt(ANGLE_MINOR_VERSION); - stream.writeBytes(reinterpret_cast(ANGLE_COMMIT_HASH), ANGLE_COMMIT_HASH_SIZE); - - stream.writeInt(mData.mActiveAttribLocationsMask.to_ulong()); - - stream.writeInt(mData.mAttributes.size()); - for (const sh::Attribute &attrib : mData.mAttributes) - { - WriteShaderVar(&stream, attrib); - stream.writeInt(attrib.location); - } - - stream.writeInt(mData.mUniforms.size()); - for (const gl::LinkedUniform &uniform : mData.mUniforms) - { - WriteShaderVar(&stream, uniform); - - // FIXME: referenced - - stream.writeInt(uniform.blockIndex); - stream.writeInt(uniform.blockInfo.offset); - stream.writeInt(uniform.blockInfo.arrayStride); - stream.writeInt(uniform.blockInfo.matrixStride); - stream.writeInt(uniform.blockInfo.isRowMajorMatrix); - } - - stream.writeInt(mData.mUniformLocations.size()); - for (const auto &variable : mData.mUniformLocations) - { - stream.writeString(variable.name); - stream.writeInt(variable.element); - stream.writeInt(variable.index); - } - - stream.writeInt(mData.mUniformBlocks.size()); - for (const UniformBlock &uniformBlock : mData.mUniformBlocks) - { - stream.writeString(uniformBlock.name); - stream.writeInt(uniformBlock.isArray); - stream.writeInt(uniformBlock.arrayElement); - stream.writeInt(uniformBlock.dataSize); - - stream.writeInt(uniformBlock.vertexStaticUse); - stream.writeInt(uniformBlock.fragmentStaticUse); - - stream.writeInt(uniformBlock.memberUniformIndexes.size()); - for (unsigned int memberUniformIndex : uniformBlock.memberUniformIndexes) - { - stream.writeInt(memberUniformIndex); - } - } - - stream.writeInt(mData.mTransformFeedbackVaryingVars.size()); - for (const sh::Varying &varying : mData.mTransformFeedbackVaryingVars) - { - stream.writeInt(varying.arraySize); - stream.writeInt(varying.type); - stream.writeString(varying.name); - } - - stream.writeInt(mData.mTransformFeedbackBufferMode); - - stream.writeInt(mData.mOutputVariables.size()); - for (const auto &outputPair : mData.mOutputVariables) - { - stream.writeInt(outputPair.first); - stream.writeInt(outputPair.second.element); - stream.writeInt(outputPair.second.index); - stream.writeString(outputPair.second.name); - } - - stream.writeInt(mSamplerUniformRange.start); - stream.writeInt(mSamplerUniformRange.end); - - gl::Error error = mProgram->save(&stream); - if (error.isError()) - { - return error; - } - - GLsizei streamLength = static_cast(stream.length()); - const void *streamData = stream.data(); + GLsizei streamLength = static_cast(memoryBuf.size()); + const uint8_t *streamState = memoryBuf.data(); if (streamLength > bufSize) { @@ -775,14 +1073,14 @@ Error Program::saveBinary(GLenum *binaryFormat, void *binary, GLsizei bufSize, G // TODO: This should be moved to the validation layer but computing the size of the binary before saving // it causes the save to happen twice. It may be possible to write the binary to a separate buffer, validate // sizes and then copy it. - return Error(GL_INVALID_OPERATION); + return InternalError(); } if (binary) { char *ptr = reinterpret_cast(binary); - memcpy(ptr, streamData, streamLength); + memcpy(ptr, streamState, streamLength); ptr += streamLength; ASSERT(ptr - streamLength == binary); @@ -793,13 +1091,13 @@ Error Program::saveBinary(GLenum *binaryFormat, void *binary, GLsizei bufSize, G *length = streamLength; } - return Error(GL_NO_ERROR); + return NoError(); } -GLint Program::getBinaryLength() const +GLint Program::getBinaryLength(const Context *context) const { GLint length; - Error error = saveBinary(nullptr, nullptr, std::numeric_limits::max(), &length); + Error error = saveBinary(context, nullptr, nullptr, std::numeric_limits::max(), &length); if (error.isError()) { return 0; @@ -812,21 +1110,36 @@ void Program::setBinaryRetrievableHint(bool retrievable) { // TODO(jmadill) : replace with dirty bits mProgram->setBinaryRetrievableHint(retrievable); - mData.mBinaryRetrieveableHint = retrievable; + mState.mBinaryRetrieveableHint = retrievable; } bool Program::getBinaryRetrievableHint() const { - return mData.mBinaryRetrieveableHint; + return mState.mBinaryRetrieveableHint; } -void Program::release() +void Program::setSeparable(bool separable) +{ + // TODO(yunchao) : replace with dirty bits + if (mState.mSeparable != separable) + { + mProgram->setSeparable(separable); + mState.mSeparable = separable; + } +} + +bool Program::isSeparable() const +{ + return mState.mSeparable; +} + +void Program::release(const Context *context) { mRefCount--; if (mRefCount == 0 && mDeleteStatus) { - mResourceManager->deleteProgram(mHandle); + mResourceManager->deleteProgram(context, mHandle); } } @@ -854,24 +1167,40 @@ void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shade { int total = 0; - if (mData.mAttachedVertexShader) + if (mState.mAttachedComputeShader) { if (total < maxCount) { - shaders[total] = mData.mAttachedVertexShader->getHandle(); + shaders[total] = mState.mAttachedComputeShader->getHandle(); + total++; } - - total++; } - if (mData.mAttachedFragmentShader) + if (mState.mAttachedVertexShader) { if (total < maxCount) { - shaders[total] = mData.mAttachedFragmentShader->getHandle(); + shaders[total] = mState.mAttachedVertexShader->getHandle(); + total++; } + } - total++; + if (mState.mAttachedFragmentShader) + { + if (total < maxCount) + { + shaders[total] = mState.mAttachedFragmentShader->getHandle(); + total++; + } + } + + if (mState.mAttachedGeometryShader) + { + if (total < maxCount) + { + shaders[total] = mState.mAttachedGeometryShader->getHandle(); + total++; + } } if (count) @@ -882,24 +1211,21 @@ void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shade GLuint Program::getAttributeLocation(const std::string &name) const { - for (const sh::Attribute &attribute : mData.mAttributes) - { - if (attribute.name == name && attribute.staticUse) - { - return attribute.location; - } - } - - return static_cast(-1); + return mState.getAttributeLocation(name); } bool Program::isAttribLocationActive(size_t attribLocation) const { - ASSERT(attribLocation < mData.mActiveAttribLocationsMask.size()); - return mData.mActiveAttribLocationsMask[attribLocation]; + ASSERT(attribLocation < mState.mActiveAttribLocationsMask.size()); + return mState.mActiveAttribLocationsMask[attribLocation]; } -void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) +void Program::getActiveAttribute(GLuint index, + GLsizei bufsize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name) const { if (!mLinked) { @@ -918,35 +1244,12 @@ void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, return; } - size_t attributeIndex = 0; - - for (const sh::Attribute &attribute : mData.mAttributes) - { - // Skip over inactive attributes - if (attribute.staticUse) - { - if (static_cast(index) == attributeIndex) - { - break; - } - attributeIndex++; - } - } - - ASSERT(index == attributeIndex && attributeIndex < mData.mAttributes.size()); - const sh::Attribute &attrib = mData.mAttributes[attributeIndex]; + ASSERT(index < mState.mAttributes.size()); + const sh::Attribute &attrib = mState.mAttributes[index]; if (bufsize > 0) { - const char *string = attrib.name.c_str(); - - strncpy(name, string, bufsize); - name[bufsize - 1] = '\0'; - - if (length) - { - *length = static_cast(strlen(name)); - } + CopyStringToBuffer(name, attrib.name, bufsize, length); } // Always a single 'type' instance @@ -961,14 +1264,7 @@ GLint Program::getActiveAttributeCount() const return 0; } - GLint count = 0; - - for (const sh::Attribute &attrib : mData.mAttributes) - { - count += (attrib.staticUse ? 1 : 0); - } - - return count; + return static_cast(mState.mAttributes.size()); } GLint Program::getActiveAttributeMaxLength() const @@ -980,30 +1276,105 @@ GLint Program::getActiveAttributeMaxLength() const size_t maxLength = 0; - for (const sh::Attribute &attrib : mData.mAttributes) + for (const sh::Attribute &attrib : mState.mAttributes) { - if (attrib.staticUse) - { - maxLength = std::max(attrib.name.length() + 1, maxLength); - } + maxLength = std::max(attrib.name.length() + 1, maxLength); } return static_cast(maxLength); } +GLuint Program::getInputResourceIndex(const GLchar *name) const +{ + return GetResourceIndexFromName(mState.mAttributes, std::string(name)); +} + +GLuint Program::getOutputResourceIndex(const GLchar *name) const +{ + return GetResourceIndexFromName(mState.mOutputVariables, std::string(name)); +} + +size_t Program::getOutputResourceCount() const +{ + return (mLinked ? mState.mOutputVariables.size() : 0); +} + +template +void Program::getResourceName(GLuint index, + const std::vector &resources, + GLsizei bufSize, + GLsizei *length, + GLchar *name) const +{ + if (length) + { + *length = 0; + } + + if (!mLinked) + { + if (bufSize > 0) + { + name[0] = '\0'; + } + return; + } + ASSERT(index < resources.size()); + const auto &resource = resources[index]; + + if (bufSize > 0) + { + CopyStringToBuffer(name, resource.name, bufSize, length); + } +} + +void Program::getInputResourceName(GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name) const +{ + getResourceName(index, mState.mAttributes, bufSize, length, name); +} + +void Program::getOutputResourceName(GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name) const +{ + getResourceName(index, mState.mOutputVariables, bufSize, length, name); +} + +void Program::getUniformResourceName(GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name) const +{ + getResourceName(index, mState.mUniforms, bufSize, length, name); +} + +void Program::getBufferVariableResourceName(GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name) const +{ + getResourceName(index, mState.mBufferVariables, bufSize, length, name); +} + +const sh::Attribute &Program::getInputResource(GLuint index) const +{ + ASSERT(index < mState.mAttributes.size()); + return mState.mAttributes[index]; +} + +const sh::OutputVariable &Program::getOutputResource(GLuint index) const +{ + ASSERT(index < mState.mOutputVariables.size()); + return mState.mOutputVariables[index]; +} + GLint Program::getFragDataLocation(const std::string &name) const { - std::string baseName(name); - unsigned int arrayIndex = ParseAndStripArrayIndex(&baseName); - for (auto outputPair : mData.mOutputVariables) - { - const VariableLocation &outputVariable = outputPair.second; - if (outputVariable.name == baseName && (arrayIndex == GL_INVALID_INDEX || arrayIndex == outputVariable.element)) - { - return static_cast(outputPair.first); - } - } - return -1; + return GetVariableLocation(mState.mOutputVariables, mState.mOutputLocations, name); } void Program::getActiveUniform(GLuint index, @@ -1016,27 +1387,16 @@ void Program::getActiveUniform(GLuint index, if (mLinked) { // index must be smaller than getActiveUniformCount() - ASSERT(index < mData.mUniforms.size()); - const LinkedUniform &uniform = mData.mUniforms[index]; + ASSERT(index < mState.mUniforms.size()); + const LinkedUniform &uniform = mState.mUniforms[index]; if (bufsize > 0) { std::string string = uniform.name; - if (uniform.isArray()) - { - string += "[0]"; - } - - strncpy(name, string.c_str(), bufsize); - name[bufsize - 1] = '\0'; - - if (length) - { - *length = static_cast(strlen(name)); - } + CopyStringToBuffer(name, string, bufsize, length); } - *size = uniform.elementCount(); + *size = clampCast(uniform.getBasicTypeElementCount()); *type = uniform.type; } else @@ -1060,7 +1420,7 @@ GLint Program::getActiveUniformCount() const { if (mLinked) { - return static_cast(mData.mUniforms.size()); + return static_cast(mState.mUniforms.size()); } else { @@ -1068,13 +1428,18 @@ GLint Program::getActiveUniformCount() const } } +size_t Program::getActiveBufferVariableCount() const +{ + return mLinked ? mState.mBufferVariables.size() : 0; +} + GLint Program::getActiveUniformMaxLength() const { size_t maxLength = 0; if (mLinked) { - for (const LinkedUniform &uniform : mData.mUniforms) + for (const LinkedUniform &uniform : mState.mUniforms) { if (!uniform.name.empty()) { @@ -1091,188 +1456,248 @@ GLint Program::getActiveUniformMaxLength() const return static_cast(maxLength); } -GLint Program::getActiveUniformi(GLuint index, GLenum pname) const -{ - ASSERT(static_cast(index) < mData.mUniforms.size()); - const gl::LinkedUniform &uniform = mData.mUniforms[index]; - switch (pname) - { - case GL_UNIFORM_TYPE: return static_cast(uniform.type); - case GL_UNIFORM_SIZE: return static_cast(uniform.elementCount()); - case GL_UNIFORM_NAME_LENGTH: return static_cast(uniform.name.size() + 1 + (uniform.isArray() ? 3 : 0)); - case GL_UNIFORM_BLOCK_INDEX: return uniform.blockIndex; - case GL_UNIFORM_OFFSET: return uniform.blockInfo.offset; - case GL_UNIFORM_ARRAY_STRIDE: return uniform.blockInfo.arrayStride; - case GL_UNIFORM_MATRIX_STRIDE: return uniform.blockInfo.matrixStride; - case GL_UNIFORM_IS_ROW_MAJOR: return static_cast(uniform.blockInfo.isRowMajorMatrix); - default: - UNREACHABLE(); - break; - } - return 0; -} - bool Program::isValidUniformLocation(GLint location) const { - ASSERT(rx::IsIntegerCastSafe(mData.mUniformLocations.size())); - return (location >= 0 && static_cast(location) < mData.mUniformLocations.size()); + ASSERT(angle::IsValueInRangeForNumericType(mState.mUniformLocations.size())); + return (location >= 0 && static_cast(location) < mState.mUniformLocations.size() && + mState.mUniformLocations[static_cast(location)].used()); } const LinkedUniform &Program::getUniformByLocation(GLint location) const { - ASSERT(location >= 0 && static_cast(location) < mData.mUniformLocations.size()); - return mData.mUniforms[mData.mUniformLocations[location].index]; + ASSERT(location >= 0 && static_cast(location) < mState.mUniformLocations.size()); + return mState.mUniforms[mState.getUniformIndexFromLocation(location)]; +} + +const VariableLocation &Program::getUniformLocation(GLint location) const +{ + ASSERT(location >= 0 && static_cast(location) < mState.mUniformLocations.size()); + return mState.mUniformLocations[location]; +} + +const std::vector &Program::getUniformLocations() const +{ + return mState.mUniformLocations; +} + +const LinkedUniform &Program::getUniformByIndex(GLuint index) const +{ + ASSERT(index < static_cast(mState.mUniforms.size())); + return mState.mUniforms[index]; +} + +const BufferVariable &Program::getBufferVariableByIndex(GLuint index) const +{ + ASSERT(index < static_cast(mState.mBufferVariables.size())); + return mState.mBufferVariables[index]; } GLint Program::getUniformLocation(const std::string &name) const { - return mData.getUniformLocation(name); + return GetVariableLocation(mState.mUniforms, mState.mUniformLocations, name); } GLuint Program::getUniformIndex(const std::string &name) const { - return mData.getUniformIndex(name); + return mState.getUniformIndexFromName(name); } void Program::setUniform1fv(GLint location, GLsizei count, const GLfloat *v) { - setUniformInternal(location, count * 1, v); - mProgram->setUniform1fv(location, count, v); + const VariableLocation &locationInfo = mState.mUniformLocations[location]; + GLsizei clampedCount = clampUniformCount(locationInfo, count, 1, v); + mProgram->setUniform1fv(location, clampedCount, v); } void Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) { - setUniformInternal(location, count * 2, v); - mProgram->setUniform2fv(location, count, v); + const VariableLocation &locationInfo = mState.mUniformLocations[location]; + GLsizei clampedCount = clampUniformCount(locationInfo, count, 2, v); + mProgram->setUniform2fv(location, clampedCount, v); } void Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) { - setUniformInternal(location, count * 3, v); - mProgram->setUniform3fv(location, count, v); + const VariableLocation &locationInfo = mState.mUniformLocations[location]; + GLsizei clampedCount = clampUniformCount(locationInfo, count, 3, v); + mProgram->setUniform3fv(location, clampedCount, v); } void Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) { - setUniformInternal(location, count * 4, v); - mProgram->setUniform4fv(location, count, v); + const VariableLocation &locationInfo = mState.mUniformLocations[location]; + GLsizei clampedCount = clampUniformCount(locationInfo, count, 4, v); + mProgram->setUniform4fv(location, clampedCount, v); } -void Program::setUniform1iv(GLint location, GLsizei count, const GLint *v) +Program::SetUniformResult Program::setUniform1iv(GLint location, GLsizei count, const GLint *v) { - setUniformInternal(location, count * 1, v); - mProgram->setUniform1iv(location, count, v); + const VariableLocation &locationInfo = mState.mUniformLocations[location]; + GLsizei clampedCount = clampUniformCount(locationInfo, count, 1, v); + + mProgram->setUniform1iv(location, clampedCount, v); + + if (mState.isSamplerUniformIndex(locationInfo.index)) + { + updateSamplerUniform(locationInfo, clampedCount, v); + return SetUniformResult::SamplerChanged; + } + + return SetUniformResult::NoSamplerChange; } void Program::setUniform2iv(GLint location, GLsizei count, const GLint *v) { - setUniformInternal(location, count * 2, v); - mProgram->setUniform2iv(location, count, v); + const VariableLocation &locationInfo = mState.mUniformLocations[location]; + GLsizei clampedCount = clampUniformCount(locationInfo, count, 2, v); + mProgram->setUniform2iv(location, clampedCount, v); } void Program::setUniform3iv(GLint location, GLsizei count, const GLint *v) { - setUniformInternal(location, count * 3, v); - mProgram->setUniform3iv(location, count, v); + const VariableLocation &locationInfo = mState.mUniformLocations[location]; + GLsizei clampedCount = clampUniformCount(locationInfo, count, 3, v); + mProgram->setUniform3iv(location, clampedCount, v); } void Program::setUniform4iv(GLint location, GLsizei count, const GLint *v) { - setUniformInternal(location, count * 4, v); - mProgram->setUniform4iv(location, count, v); + const VariableLocation &locationInfo = mState.mUniformLocations[location]; + GLsizei clampedCount = clampUniformCount(locationInfo, count, 4, v); + mProgram->setUniform4iv(location, clampedCount, v); } void Program::setUniform1uiv(GLint location, GLsizei count, const GLuint *v) { - setUniformInternal(location, count * 1, v); - mProgram->setUniform1uiv(location, count, v); + const VariableLocation &locationInfo = mState.mUniformLocations[location]; + GLsizei clampedCount = clampUniformCount(locationInfo, count, 1, v); + mProgram->setUniform1uiv(location, clampedCount, v); } void Program::setUniform2uiv(GLint location, GLsizei count, const GLuint *v) { - setUniformInternal(location, count * 2, v); - mProgram->setUniform2uiv(location, count, v); + const VariableLocation &locationInfo = mState.mUniformLocations[location]; + GLsizei clampedCount = clampUniformCount(locationInfo, count, 2, v); + mProgram->setUniform2uiv(location, clampedCount, v); } void Program::setUniform3uiv(GLint location, GLsizei count, const GLuint *v) { - setUniformInternal(location, count * 3, v); - mProgram->setUniform3uiv(location, count, v); + const VariableLocation &locationInfo = mState.mUniformLocations[location]; + GLsizei clampedCount = clampUniformCount(locationInfo, count, 3, v); + mProgram->setUniform3uiv(location, clampedCount, v); } void Program::setUniform4uiv(GLint location, GLsizei count, const GLuint *v) { - setUniformInternal(location, count * 4, v); - mProgram->setUniform4uiv(location, count, v); + const VariableLocation &locationInfo = mState.mUniformLocations[location]; + GLsizei clampedCount = clampUniformCount(locationInfo, count, 4, v); + mProgram->setUniform4uiv(location, clampedCount, v); } void Program::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { - setMatrixUniformInternal<2, 2>(location, count, transpose, v); - mProgram->setUniformMatrix2fv(location, count, transpose, v); + GLsizei clampedCount = clampMatrixUniformCount<2, 2>(location, count, transpose, v); + mProgram->setUniformMatrix2fv(location, clampedCount, transpose, v); } void Program::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { - setMatrixUniformInternal<3, 3>(location, count, transpose, v); - mProgram->setUniformMatrix3fv(location, count, transpose, v); + GLsizei clampedCount = clampMatrixUniformCount<3, 3>(location, count, transpose, v); + mProgram->setUniformMatrix3fv(location, clampedCount, transpose, v); } void Program::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { - setMatrixUniformInternal<4, 4>(location, count, transpose, v); - mProgram->setUniformMatrix4fv(location, count, transpose, v); + GLsizei clampedCount = clampMatrixUniformCount<4, 4>(location, count, transpose, v); + mProgram->setUniformMatrix4fv(location, clampedCount, transpose, v); } void Program::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { - setMatrixUniformInternal<2, 3>(location, count, transpose, v); - mProgram->setUniformMatrix2x3fv(location, count, transpose, v); + GLsizei clampedCount = clampMatrixUniformCount<2, 3>(location, count, transpose, v); + mProgram->setUniformMatrix2x3fv(location, clampedCount, transpose, v); } void Program::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { - setMatrixUniformInternal<2, 4>(location, count, transpose, v); - mProgram->setUniformMatrix2x4fv(location, count, transpose, v); + GLsizei clampedCount = clampMatrixUniformCount<2, 4>(location, count, transpose, v); + mProgram->setUniformMatrix2x4fv(location, clampedCount, transpose, v); } void Program::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { - setMatrixUniformInternal<3, 2>(location, count, transpose, v); - mProgram->setUniformMatrix3x2fv(location, count, transpose, v); + GLsizei clampedCount = clampMatrixUniformCount<3, 2>(location, count, transpose, v); + mProgram->setUniformMatrix3x2fv(location, clampedCount, transpose, v); } void Program::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { - setMatrixUniformInternal<3, 4>(location, count, transpose, v); - mProgram->setUniformMatrix3x4fv(location, count, transpose, v); + GLsizei clampedCount = clampMatrixUniformCount<3, 4>(location, count, transpose, v); + mProgram->setUniformMatrix3x4fv(location, clampedCount, transpose, v); } void Program::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { - setMatrixUniformInternal<4, 2>(location, count, transpose, v); - mProgram->setUniformMatrix4x2fv(location, count, transpose, v); + GLsizei clampedCount = clampMatrixUniformCount<4, 2>(location, count, transpose, v); + mProgram->setUniformMatrix4x2fv(location, clampedCount, transpose, v); } void Program::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { - setMatrixUniformInternal<4, 3>(location, count, transpose, v); - mProgram->setUniformMatrix4x3fv(location, count, transpose, v); + GLsizei clampedCount = clampMatrixUniformCount<4, 3>(location, count, transpose, v); + mProgram->setUniformMatrix4x3fv(location, clampedCount, transpose, v); } -void Program::getUniformfv(GLint location, GLfloat *v) const +void Program::getUniformfv(const Context *context, GLint location, GLfloat *v) const { - getUniformInternal(location, v); + const auto &uniformLocation = mState.getUniformLocations()[location]; + const auto &uniform = mState.getUniforms()[uniformLocation.index]; + + GLenum nativeType = gl::VariableComponentType(uniform.type); + if (nativeType == GL_FLOAT) + { + mProgram->getUniformfv(context, location, v); + } + else + { + getUniformInternal(context, v, location, nativeType, + gl::VariableComponentCount(uniform.type)); + } } -void Program::getUniformiv(GLint location, GLint *v) const +void Program::getUniformiv(const Context *context, GLint location, GLint *v) const { - getUniformInternal(location, v); + const auto &uniformLocation = mState.getUniformLocations()[location]; + const auto &uniform = mState.getUniforms()[uniformLocation.index]; + + GLenum nativeType = gl::VariableComponentType(uniform.type); + if (nativeType == GL_INT || nativeType == GL_BOOL) + { + mProgram->getUniformiv(context, location, v); + } + else + { + getUniformInternal(context, v, location, nativeType, + gl::VariableComponentCount(uniform.type)); + } } -void Program::getUniformuiv(GLint location, GLuint *v) const +void Program::getUniformuiv(const Context *context, GLint location, GLuint *v) const { - getUniformInternal(location, v); + const auto &uniformLocation = mState.getUniformLocations()[location]; + const auto &uniform = mState.getUniforms()[uniformLocation.index]; + + GLenum nativeType = gl::VariableComponentType(uniform.type); + if (nativeType == GL_UNSIGNED_INT) + { + mProgram->getUniformuiv(context, location, v); + } + else + { + getUniformInternal(context, v, location, nativeType, + gl::VariableComponentCount(uniform.type)); + } } void Program::flagForDeletion() @@ -1291,7 +1716,7 @@ void Program::validate(const Caps &caps) if (mLinked) { - mValidated = (mProgram->validate(caps, &mInfoLog) == GL_TRUE); + mValidated = ConvertToBool(mProgram->validate(caps, &mInfoLog)); } else { @@ -1320,22 +1745,15 @@ bool Program::validateSamplers(InfoLog *infoLog, const Caps &caps) // if any two active samplers in a program are of different types, but refer to the same // texture image unit, and this is the current program, then ValidateProgram will fail, and // DrawArrays and DrawElements will issue the INVALID_OPERATION error. - for (unsigned int samplerIndex = mSamplerUniformRange.start; - samplerIndex < mSamplerUniformRange.end; ++samplerIndex) + for (const auto &samplerBinding : mState.mSamplerBindings) { - const LinkedUniform &uniform = mData.mUniforms[samplerIndex]; - ASSERT(uniform.isSampler()); - - if (!uniform.staticUse) + if (samplerBinding.unreferenced) continue; - const GLuint *dataPtr = reinterpret_cast(uniform.getDataPtrToElement(0)); - GLenum textureType = SamplerTypeToTextureType(uniform.type); + GLenum textureType = samplerBinding.textureType; - for (unsigned int arrayElement = 0; arrayElement < uniform.elementCount(); ++arrayElement) + for (GLuint textureUnit : samplerBinding.boundTextureUnits) { - GLuint textureUnit = dataPtr[arrayElement]; - if (textureUnit >= caps.maxCombinedTextureImageUnits) { if (infoLog) @@ -1382,70 +1800,34 @@ bool Program::isValidated() const GLuint Program::getActiveUniformBlockCount() const { - return static_cast(mData.mUniformBlocks.size()); + return static_cast(mState.mUniformBlocks.size()); } -void Program::getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const +GLuint Program::getActiveAtomicCounterBufferCount() const { - ASSERT(uniformBlockIndex < - mData.mUniformBlocks.size()); // index must be smaller than getActiveUniformBlockCount() - - const UniformBlock &uniformBlock = mData.mUniformBlocks[uniformBlockIndex]; - - if (bufSize > 0) - { - std::string string = uniformBlock.name; - - if (uniformBlock.isArray) - { - string += ArrayString(uniformBlock.arrayElement); - } - - strncpy(uniformBlockName, string.c_str(), bufSize); - uniformBlockName[bufSize - 1] = '\0'; - - if (length) - { - *length = static_cast(strlen(uniformBlockName)); - } - } + return static_cast(mState.mAtomicCounterBuffers.size()); } -void Program::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const +GLuint Program::getActiveShaderStorageBlockCount() const { - ASSERT(uniformBlockIndex < - mData.mUniformBlocks.size()); // index must be smaller than getActiveUniformBlockCount() + return static_cast(mState.mShaderStorageBlocks.size()); +} - const UniformBlock &uniformBlock = mData.mUniformBlocks[uniformBlockIndex]; +void Program::getActiveUniformBlockName(const GLuint blockIndex, + GLsizei bufSize, + GLsizei *length, + GLchar *blockName) const +{ + GetInterfaceBlockName(blockIndex, mState.mUniformBlocks, bufSize, length, blockName); +} - switch (pname) - { - case GL_UNIFORM_BLOCK_DATA_SIZE: - *params = static_cast(uniformBlock.dataSize); - break; - case GL_UNIFORM_BLOCK_NAME_LENGTH: - *params = - static_cast(uniformBlock.name.size() + 1 + (uniformBlock.isArray ? 3 : 0)); - break; - case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: - *params = static_cast(uniformBlock.memberUniformIndexes.size()); - break; - case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: - { - for (unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++) - { - params[blockMemberIndex] = static_cast(uniformBlock.memberUniformIndexes[blockMemberIndex]); - } - } - break; - case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: - *params = static_cast(uniformBlock.vertexStaticUse); - break; - case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: - *params = static_cast(uniformBlock.fragmentStaticUse); - break; - default: UNREACHABLE(); - } +void Program::getActiveShaderStorageBlockName(const GLuint blockIndex, + GLsizei bufSize, + GLsizei *length, + GLchar *blockName) const +{ + + GetInterfaceBlockName(blockIndex, mState.mShaderStorageBlocks, bufSize, length, blockName); } GLint Program::getActiveUniformBlockMaxLength() const @@ -1454,18 +1836,14 @@ GLint Program::getActiveUniformBlockMaxLength() const if (mLinked) { - unsigned int numUniformBlocks = static_cast(mData.mUniformBlocks.size()); + unsigned int numUniformBlocks = static_cast(mState.mUniformBlocks.size()); for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < numUniformBlocks; uniformBlockIndex++) { - const UniformBlock &uniformBlock = mData.mUniformBlocks[uniformBlockIndex]; + const InterfaceBlock &uniformBlock = mState.mUniformBlocks[uniformBlockIndex]; if (!uniformBlock.name.empty()) { - const int length = static_cast(uniformBlock.name.length()) + 1; - - // Counting in "[0]". - const int arrayLength = (uniformBlock.isArray ? 3 : 0); - - maxLength = std::max(length + arrayLength, maxLength); + int length = static_cast(uniformBlock.nameWithArrayIndex().length()); + maxLength = std::max(length + 1, maxLength); } } } @@ -1475,87 +1853,77 @@ GLint Program::getActiveUniformBlockMaxLength() const GLuint Program::getUniformBlockIndex(const std::string &name) const { - size_t subscript = GL_INVALID_INDEX; - std::string baseName = gl::ParseUniformName(name, &subscript); - - unsigned int numUniformBlocks = static_cast(mData.mUniformBlocks.size()); - for (unsigned int blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++) - { - const gl::UniformBlock &uniformBlock = mData.mUniformBlocks[blockIndex]; - if (uniformBlock.name == baseName) - { - const bool arrayElementZero = - (subscript == GL_INVALID_INDEX && - (!uniformBlock.isArray || uniformBlock.arrayElement == 0)); - if (subscript == uniformBlock.arrayElement || arrayElementZero) - { - return blockIndex; - } - } - } - - return GL_INVALID_INDEX; + return GetInterfaceBlockIndex(mState.mUniformBlocks, name); } -const UniformBlock &Program::getUniformBlockByIndex(GLuint index) const +GLuint Program::getShaderStorageBlockIndex(const std::string &name) const { - ASSERT(index < static_cast(mData.mUniformBlocks.size())); - return mData.mUniformBlocks[index]; + return GetInterfaceBlockIndex(mState.mShaderStorageBlocks, name); +} + +const InterfaceBlock &Program::getUniformBlockByIndex(GLuint index) const +{ + ASSERT(index < static_cast(mState.mUniformBlocks.size())); + return mState.mUniformBlocks[index]; +} + +const InterfaceBlock &Program::getShaderStorageBlockByIndex(GLuint index) const +{ + ASSERT(index < static_cast(mState.mShaderStorageBlocks.size())); + return mState.mShaderStorageBlocks[index]; } void Program::bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding) { - mData.mUniformBlockBindings[uniformBlockIndex] = uniformBlockBinding; + mState.mUniformBlocks[uniformBlockIndex].binding = uniformBlockBinding; + mState.mActiveUniformBlockBindings.set(uniformBlockIndex, uniformBlockBinding != 0); mProgram->setUniformBlockBinding(uniformBlockIndex, uniformBlockBinding); } GLuint Program::getUniformBlockBinding(GLuint uniformBlockIndex) const { - return mData.getUniformBlockBinding(uniformBlockIndex); + return mState.getUniformBlockBinding(uniformBlockIndex); } -void Program::resetUniformBlockBindings() +GLuint Program::getShaderStorageBlockBinding(GLuint shaderStorageBlockIndex) const { - for (unsigned int blockId = 0; blockId < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; blockId++) - { - mData.mUniformBlockBindings[blockId] = 0; - } - mData.mActiveUniformBlockBindings.reset(); + return mState.getShaderStorageBlockBinding(shaderStorageBlockIndex); } void Program::setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode) { - mData.mTransformFeedbackVaryingNames.resize(count); + mState.mTransformFeedbackVaryingNames.resize(count); for (GLsizei i = 0; i < count; i++) { - mData.mTransformFeedbackVaryingNames[i] = varyings[i]; + mState.mTransformFeedbackVaryingNames[i] = varyings[i]; } - mData.mTransformFeedbackBufferMode = bufferMode; + mState.mTransformFeedbackBufferMode = bufferMode; } void Program::getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const { if (mLinked) { - ASSERT(index < mData.mTransformFeedbackVaryingVars.size()); - const sh::Varying &varying = mData.mTransformFeedbackVaryingVars[index]; - GLsizei lastNameIdx = std::min(bufSize - 1, static_cast(varying.name.length())); + ASSERT(index < mState.mLinkedTransformFeedbackVaryings.size()); + const auto &var = mState.mLinkedTransformFeedbackVaryings[index]; + std::string varName = var.nameWithArrayIndex(); + GLsizei lastNameIdx = std::min(bufSize - 1, static_cast(varName.length())); if (length) { *length = lastNameIdx; } if (size) { - *size = varying.elementCount(); + *size = var.size(); } if (type) { - *type = varying.type; + *type = var.type; } if (name) { - memcpy(name, varying.name.c_str(), lastNameIdx); + memcpy(name, varName.c_str(), lastNameIdx); name[lastNameIdx] = '\0'; } } @@ -1565,7 +1933,7 @@ GLsizei Program::getTransformFeedbackVaryingCount() const { if (mLinked) { - return static_cast(mData.mTransformFeedbackVaryingVars.size()); + return static_cast(mState.mLinkedTransformFeedbackVaryings.size()); } else { @@ -1578,9 +1946,10 @@ GLsizei Program::getTransformFeedbackVaryingMaxLength() const if (mLinked) { GLsizei maxSize = 0; - for (const sh::Varying &varying : mData.mTransformFeedbackVaryingVars) + for (const auto &var : mState.mLinkedTransformFeedbackVaryings) { - maxSize = std::max(maxSize, static_cast(varying.name.length() + 1)); + maxSize = + std::max(maxSize, static_cast(var.nameWithArrayIndex().length() + 1)); } return maxSize; @@ -1593,16 +1962,20 @@ GLsizei Program::getTransformFeedbackVaryingMaxLength() const GLenum Program::getTransformFeedbackBufferMode() const { - return mData.mTransformFeedbackBufferMode; + return mState.mTransformFeedbackBufferMode; } -// static -bool Program::linkVaryings(InfoLog &infoLog, - const Shader *vertexShader, - const Shader *fragmentShader) +bool Program::linkVaryings(const Context *context, InfoLog &infoLog) const { - const std::vector &vertexVaryings = vertexShader->getVaryings(); - const std::vector &fragmentVaryings = fragmentShader->getVaryings(); + Shader *vertexShader = mState.mAttachedVertexShader; + Shader *fragmentShader = mState.mAttachedFragmentShader; + + ASSERT(vertexShader->getShaderVersion(context) == fragmentShader->getShaderVersion(context)); + + const std::vector &vertexVaryings = vertexShader->getOutputVaryings(context); + const std::vector &fragmentVaryings = fragmentShader->getInputVaryings(context); + + std::map staticFragmentInputLocations; for (const sh::Varying &output : fragmentVaryings) { @@ -1619,7 +1992,8 @@ bool Program::linkVaryings(InfoLog &infoLog, if (output.name == input.name) { ASSERT(!input.isBuiltIn()); - if (!linkValidateVaryings(infoLog, output.name, input, output)) + if (!linkValidateVaryings(infoLog, output.name, input, output, + vertexShader->getShaderVersion(context))) { return false; } @@ -1635,6 +2009,34 @@ bool Program::linkVaryings(InfoLog &infoLog, infoLog << "Fragment varying " << output.name << " does not match any vertex varying"; return false; } + + // Check for aliased path rendering input bindings (if any). + // If more than one binding refer statically to the same + // location the link must fail. + + if (!output.staticUse) + continue; + + const auto inputBinding = mFragmentInputBindings.getBinding(output.name); + if (inputBinding == -1) + continue; + + const auto it = staticFragmentInputLocations.find(inputBinding); + if (it == std::end(staticFragmentInputLocations)) + { + staticFragmentInputLocations.insert(std::make_pair(inputBinding, output.name)); + } + else + { + infoLog << "Binding for fragment input " << output.name << " conflicts with " + << it->second; + return false; + } + } + + if (!linkValidateBuiltInVaryings(context, infoLog)) + { + return false; } // TODO(jmadill): verify no unmatched vertex varyings? @@ -1642,67 +2044,135 @@ bool Program::linkVaryings(InfoLog &infoLog, return true; } -bool Program::linkUniforms(gl::InfoLog &infoLog, const gl::Caps &caps) +bool Program::linkUniforms(const Context *context, + InfoLog &infoLog, + const Bindings &uniformLocationBindings) { - const std::vector &vertexUniforms = mData.mAttachedVertexShader->getUniforms(); - const std::vector &fragmentUniforms = mData.mAttachedFragmentShader->getUniforms(); - - // Check that uniforms defined in the vertex and fragment shaders are identical - std::map linkedUniforms; - - for (const sh::Uniform &vertexUniform : vertexUniforms) - { - linkedUniforms[vertexUniform.name] = LinkedUniform(vertexUniform); - } - - for (const sh::Uniform &fragmentUniform : fragmentUniforms) - { - auto entry = linkedUniforms.find(fragmentUniform.name); - if (entry != linkedUniforms.end()) - { - LinkedUniform *vertexUniform = &entry->second; - const std::string &uniformName = "uniform '" + vertexUniform->name + "'"; - if (!linkValidateUniforms(infoLog, uniformName, *vertexUniform, fragmentUniform)) - { - return false; - } - } - } - - // Flatten the uniforms list (nested fields) into a simple list (no nesting). - // Also check the maximum uniform vector and sampler counts. - if (!flattenUniformsAndCheckCaps(caps, infoLog)) + UniformLinker linker(mState); + if (!linker.link(context, infoLog, uniformLocationBindings)) { return false; } - indexUniforms(); + linker.getResults(&mState.mUniforms, &mState.mUniformLocations); + + linkSamplerAndImageBindings(); + + if (!linkAtomicCounterBuffers()) + { + return false; + } return true; } -void Program::indexUniforms() +void Program::linkSamplerAndImageBindings() { - for (size_t uniformIndex = 0; uniformIndex < mData.mUniforms.size(); uniformIndex++) - { - const gl::LinkedUniform &uniform = mData.mUniforms[uniformIndex]; + unsigned int high = static_cast(mState.mUniforms.size()); + unsigned int low = high; - for (unsigned int arrayIndex = 0; arrayIndex < uniform.elementCount(); arrayIndex++) + for (auto counterIter = mState.mUniforms.rbegin(); + counterIter != mState.mUniforms.rend() && counterIter->isAtomicCounter(); ++counterIter) + { + --low; + } + + mState.mAtomicCounterUniformRange = RangeUI(low, high); + + high = low; + + for (auto imageIter = mState.mUniforms.rbegin(); + imageIter != mState.mUniforms.rend() && imageIter->isImage(); ++imageIter) + { + --low; + } + + mState.mImageUniformRange = RangeUI(low, high); + + // If uniform is a image type, insert it into the mImageBindings array. + for (unsigned int imageIndex : mState.mImageUniformRange) + { + // ES3.1 (section 7.6.1) and GLSL ES3.1 (section 4.4.5), Uniform*i{v} commands + // cannot load values into a uniform defined as an image. if declare without a + // binding qualifier, any uniform image variable (include all elements of + // unbound image array) shoud be bound to unit zero. + auto &imageUniform = mState.mUniforms[imageIndex]; + if (imageUniform.binding == -1) { - if (!uniform.isBuiltIn()) - { - // Assign in-order uniform locations - mData.mUniformLocations.push_back(gl::VariableLocation( - uniform.name, arrayIndex, static_cast(uniformIndex))); - } + mState.mImageBindings.emplace_back( + ImageBinding(imageUniform.getBasicTypeElementCount())); } + else + { + mState.mImageBindings.emplace_back( + ImageBinding(imageUniform.binding, imageUniform.getBasicTypeElementCount())); + } + } + + high = low; + + for (auto samplerIter = mState.mUniforms.rbegin() + mState.mImageUniformRange.length(); + samplerIter != mState.mUniforms.rend() && samplerIter->isSampler(); ++samplerIter) + { + --low; + } + + mState.mSamplerUniformRange = RangeUI(low, high); + + // If uniform is a sampler type, insert it into the mSamplerBindings array. + for (unsigned int samplerIndex : mState.mSamplerUniformRange) + { + const auto &samplerUniform = mState.mUniforms[samplerIndex]; + GLenum textureType = SamplerTypeToTextureType(samplerUniform.type); + mState.mSamplerBindings.emplace_back( + SamplerBinding(textureType, samplerUniform.getBasicTypeElementCount(), false)); } } -bool Program::linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform) +bool Program::linkAtomicCounterBuffers() { - // We don't validate precision on UBO fields. See resolution of Khronos bug 10287. - if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, false)) + for (unsigned int index : mState.mAtomicCounterUniformRange) + { + auto &uniform = mState.mUniforms[index]; + bool found = false; + for (unsigned int bufferIndex = 0; bufferIndex < mState.mAtomicCounterBuffers.size(); + ++bufferIndex) + { + auto &buffer = mState.mAtomicCounterBuffers[bufferIndex]; + if (buffer.binding == uniform.binding) + { + buffer.memberIndexes.push_back(index); + uniform.bufferIndex = bufferIndex; + found = true; + buffer.unionReferencesWith(uniform); + break; + } + } + if (!found) + { + AtomicCounterBuffer atomicCounterBuffer; + atomicCounterBuffer.binding = uniform.binding; + atomicCounterBuffer.memberIndexes.push_back(index); + atomicCounterBuffer.unionReferencesWith(uniform); + mState.mAtomicCounterBuffers.push_back(atomicCounterBuffer); + uniform.bufferIndex = static_cast(mState.mAtomicCounterBuffers.size() - 1); + } + } + // TODO(jie.a.chen@intel.com): Count each atomic counter buffer to validate against + // gl_Max[Vertex|Fragment|Compute|Combined]AtomicCounterBuffers. + + return true; +} + +bool Program::linkValidateInterfaceBlockFields(InfoLog &infoLog, + const std::string &uniformName, + const sh::InterfaceBlockField &vertexUniform, + const sh::InterfaceBlockField &fragmentUniform, + bool webglCompatibility) +{ + // If webgl, validate precision of UBO fields, otherwise don't. See Khronos bug 10287. + if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, + webglCompatibility)) { return false; } @@ -1716,32 +2186,34 @@ bool Program::linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::stri return true; } -// Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices -bool Program::linkAttributes(const gl::Data &data, - InfoLog &infoLog, - const AttributeBindings &attributeBindings, - const Shader *vertexShader) +// Assigns locations to all attributes from the bindings and program locations. +bool Program::linkAttributes(const Context *context, InfoLog &infoLog) { + const ContextState &data = context->getContextState(); + auto *vertexShader = mState.getAttachedVertexShader(); + unsigned int usedLocations = 0; - mData.mAttributes = vertexShader->getActiveAttributes(); - GLuint maxAttribs = data.caps->maxVertexAttributes; + mState.mAttributes = vertexShader->getActiveAttributes(context); + GLuint maxAttribs = data.getCaps().maxVertexAttributes; // TODO(jmadill): handle aliasing robustly - if (mData.mAttributes.size() > maxAttribs) + if (mState.mAttributes.size() > maxAttribs) { infoLog << "Too many vertex attributes."; return false; } - std::vector usedAttribMap(data.caps->maxVertexAttributes, nullptr); + std::vector usedAttribMap(maxAttribs, nullptr); // Link attributes that have a binding location - for (sh::Attribute &attribute : mData.mAttributes) + for (sh::Attribute &attribute : mState.mAttributes) { - // TODO(jmadill): do staticUse filtering step here, or not at all - ASSERT(attribute.staticUse); + // GLSL ES 3.10 January 2016 section 4.3.4: Vertex shader inputs can't be arrays or + // structures, so we don't need to worry about adjusting their names or generating entries + // for each member/element (unlike uniforms for example). + ASSERT(!attribute.isArray() && !attribute.isStruct()); - int bindingLocation = attributeBindings.getAttributeBinding(attribute.name); + int bindingLocation = mAttributeBindings.getBinding(attribute.name); if (attribute.location == -1 && bindingLocation != -1) { attribute.location = bindingLocation; @@ -1788,10 +2260,8 @@ bool Program::linkAttributes(const gl::Data &data, } // Link attributes that don't have a binding location - for (sh::Attribute &attribute : mData.mAttributes) + for (sh::Attribute &attribute : mState.mAttributes) { - ASSERT(attribute.staticUse); - // Not set by glBindAttribLocation or by location layout qualifier if (attribute.location == -1) { @@ -1808,82 +2278,150 @@ bool Program::linkAttributes(const gl::Data &data, } } - for (const sh::Attribute &attribute : mData.mAttributes) + for (const sh::Attribute &attribute : mState.mAttributes) { - ASSERT(attribute.staticUse); ASSERT(attribute.location != -1); - int regs = VariableRegisterCount(attribute.type); + unsigned int regs = static_cast(VariableRegisterCount(attribute.type)); - for (int r = 0; r < regs; r++) + for (unsigned int r = 0; r < regs; r++) { - mData.mActiveAttribLocationsMask.set(attribute.location + r); + unsigned int location = static_cast(attribute.location) + r; + mState.mActiveAttribLocationsMask.set(location); + mState.mMaxActiveAttribLocation = + std::max(mState.mMaxActiveAttribLocation, location + 1); } } return true; } -bool Program::linkUniformBlocks(InfoLog &infoLog, const Caps &caps) +bool Program::validateVertexAndFragmentInterfaceBlocks( + const std::vector &vertexInterfaceBlocks, + const std::vector &fragmentInterfaceBlocks, + InfoLog &infoLog, + bool webglCompatibility) const { - const Shader &vertexShader = *mData.mAttachedVertexShader; - const Shader &fragmentShader = *mData.mAttachedFragmentShader; - - const std::vector &vertexInterfaceBlocks = vertexShader.getInterfaceBlocks(); - const std::vector &fragmentInterfaceBlocks = fragmentShader.getInterfaceBlocks(); - // Check that interface blocks defined in the vertex and fragment shaders are identical - typedef std::map UniformBlockMap; - UniformBlockMap linkedUniformBlocks; + typedef std::map InterfaceBlockMap; + InterfaceBlockMap linkedInterfaceBlocks; - GLuint vertexBlockCount = 0; for (const sh::InterfaceBlock &vertexInterfaceBlock : vertexInterfaceBlocks) { - linkedUniformBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock; - - // Note: shared and std140 layouts are always considered active - if (vertexInterfaceBlock.staticUse || vertexInterfaceBlock.layout != sh::BLOCKLAYOUT_PACKED) - { - if (++vertexBlockCount > caps.maxVertexUniformBlocks) - { - infoLog << "Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS (" - << caps.maxVertexUniformBlocks << ")"; - return false; - } - } + linkedInterfaceBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock; } - GLuint fragmentBlockCount = 0; for (const sh::InterfaceBlock &fragmentInterfaceBlock : fragmentInterfaceBlocks) { - auto entry = linkedUniformBlocks.find(fragmentInterfaceBlock.name); - if (entry != linkedUniformBlocks.end()) + auto entry = linkedInterfaceBlocks.find(fragmentInterfaceBlock.name); + if (entry != linkedInterfaceBlocks.end()) { const sh::InterfaceBlock &vertexInterfaceBlock = *entry->second; - if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock)) + if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock, + webglCompatibility)) { return false; } } - - // Note: shared and std140 layouts are always considered active - if (fragmentInterfaceBlock.staticUse || - fragmentInterfaceBlock.layout != sh::BLOCKLAYOUT_PACKED) - { - if (++fragmentBlockCount > caps.maxFragmentUniformBlocks) - { - infoLog - << "Fragment shader uniform block count exceed GL_MAX_FRAGMENT_UNIFORM_BLOCKS (" - << caps.maxFragmentUniformBlocks << ")"; - return false; - } - } + // TODO(jiajia.qin@intel.com): Add + // MAX_COMBINED_UNIFORM_BLOCKS/MAX_COMBINED_SHADER_STORAGE_BLOCKS validation. } - return true; } -bool Program::areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, - const sh::InterfaceBlock &fragmentInterfaceBlock) +bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog) +{ + const auto &caps = context->getCaps(); + + if (mState.mAttachedComputeShader) + { + Shader &computeShader = *mState.mAttachedComputeShader; + const auto &computeUniformBlocks = computeShader.getUniformBlocks(context); + + if (!validateInterfaceBlocksCount( + caps.maxComputeUniformBlocks, computeUniformBlocks, + "Compute shader uniform block count exceeds GL_MAX_COMPUTE_UNIFORM_BLOCKS (", + infoLog)) + { + return false; + } + + const auto &computeShaderStorageBlocks = computeShader.getShaderStorageBlocks(context); + if (!validateInterfaceBlocksCount(caps.maxComputeShaderStorageBlocks, + computeShaderStorageBlocks, + "Compute shader shader storage block count exceeds " + "GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS (", + infoLog)) + { + return false; + } + return true; + } + + Shader &vertexShader = *mState.mAttachedVertexShader; + Shader &fragmentShader = *mState.mAttachedFragmentShader; + + const auto &vertexUniformBlocks = vertexShader.getUniformBlocks(context); + const auto &fragmentUniformBlocks = fragmentShader.getUniformBlocks(context); + + if (!validateInterfaceBlocksCount( + caps.maxVertexUniformBlocks, vertexUniformBlocks, + "Vertex shader uniform block count exceeds GL_MAX_VERTEX_UNIFORM_BLOCKS (", infoLog)) + { + return false; + } + if (!validateInterfaceBlocksCount( + caps.maxFragmentUniformBlocks, fragmentUniformBlocks, + "Fragment shader uniform block count exceeds GL_MAX_FRAGMENT_UNIFORM_BLOCKS (", + infoLog)) + { + + return false; + } + + bool webglCompatibility = context->getExtensions().webglCompatibility; + if (!validateVertexAndFragmentInterfaceBlocks(vertexUniformBlocks, fragmentUniformBlocks, + infoLog, webglCompatibility)) + { + return false; + } + + if (context->getClientVersion() >= Version(3, 1)) + { + const auto &vertexShaderStorageBlocks = vertexShader.getShaderStorageBlocks(context); + const auto &fragmentShaderStorageBlocks = fragmentShader.getShaderStorageBlocks(context); + + if (!validateInterfaceBlocksCount(caps.maxVertexShaderStorageBlocks, + vertexShaderStorageBlocks, + "Vertex shader shader storage block count exceeds " + "GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS (", + infoLog)) + { + return false; + } + if (!validateInterfaceBlocksCount(caps.maxFragmentShaderStorageBlocks, + fragmentShaderStorageBlocks, + "Fragment shader shader storage block count exceeds " + "GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS (", + infoLog)) + { + + return false; + } + + if (!validateVertexAndFragmentInterfaceBlocks(vertexShaderStorageBlocks, + fragmentShaderStorageBlocks, infoLog, + webglCompatibility)) + { + return false; + } + } + return true; +} + +bool Program::areMatchingInterfaceBlocks(InfoLog &infoLog, + const sh::InterfaceBlock &vertexInterfaceBlock, + const sh::InterfaceBlock &fragmentInterfaceBlock, + bool webglCompatibility) const { const char* blockName = vertexInterfaceBlock.name.c_str(); // validate blocks for the same member types @@ -1899,7 +2437,9 @@ bool Program::areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::Interfa << "' between vertex and fragment shaders"; return false; } - if (vertexInterfaceBlock.layout != fragmentInterfaceBlock.layout || vertexInterfaceBlock.isRowMajorLayout != fragmentInterfaceBlock.isRowMajorLayout) + if (vertexInterfaceBlock.layout != fragmentInterfaceBlock.layout || + vertexInterfaceBlock.isRowMajorLayout != fragmentInterfaceBlock.isRowMajorLayout || + vertexInterfaceBlock.binding != fragmentInterfaceBlock.binding) { infoLog << "Layout qualifiers differ for interface block '" << blockName << "' between vertex and fragment shaders"; @@ -1920,7 +2460,8 @@ bool Program::areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::Interfa return false; } std::string memberName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'"; - if (!linkValidateInterfaceBlockFields(infoLog, memberName, vertexMember, fragmentMember)) + if (!linkValidateInterfaceBlockFields(infoLog, memberName, vertexMember, fragmentMember, + webglCompatibility)) { return false; } @@ -1936,7 +2477,7 @@ bool Program::linkValidateVariablesBase(InfoLog &infoLog, const std::string &var infoLog << "Types for " << variableName << " differ between vertex and fragment shaders"; return false; } - if (vertexVariable.arraySize != fragmentVariable.arraySize) + if (vertexVariable.arraySizes != fragmentVariable.arraySizes) { infoLog << "Array sizes for " << variableName << " differ between vertex and fragment shaders"; return false; @@ -1946,6 +2487,12 @@ bool Program::linkValidateVariablesBase(InfoLog &infoLog, const std::string &var infoLog << "Precisions for " << variableName << " differ between vertex and fragment shaders"; return false; } + if (vertexVariable.structName != fragmentVariable.structName) + { + infoLog << "Structure names for " << variableName + << " differ between vertex and fragment shaders"; + return false; + } if (vertexVariable.fields.size() != fragmentVariable.fields.size()) { @@ -1979,23 +2526,11 @@ bool Program::linkValidateVariablesBase(InfoLog &infoLog, const std::string &var return true; } -bool Program::linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform) -{ -#if ANGLE_PROGRAM_LINK_VALIDATE_UNIFORM_PRECISION == ANGLE_ENABLED - const bool validatePrecision = true; -#else - const bool validatePrecision = false; -#endif - - if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, validatePrecision)) - { - return false; - } - - return true; -} - -bool Program::linkValidateVaryings(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying) +bool Program::linkValidateVaryings(InfoLog &infoLog, + const std::string &varyingName, + const sh::Varying &vertexVarying, + const sh::Varying &fragmentVarying, + int shaderVersion) { if (!linkValidateVariablesBase(infoLog, varyingName, vertexVarying, fragmentVarying, false)) { @@ -2004,27 +2539,112 @@ bool Program::linkValidateVaryings(InfoLog &infoLog, const std::string &varyingN if (!sh::InterpolationTypesMatch(vertexVarying.interpolation, fragmentVarying.interpolation)) { - infoLog << "Interpolation types for " << varyingName << " differ between vertex and fragment shaders"; + infoLog << "Interpolation types for " << varyingName + << " differ between vertex and fragment shaders."; + return false; + } + + if (shaderVersion == 100 && vertexVarying.isInvariant != fragmentVarying.isInvariant) + { + infoLog << "Invariance for " << varyingName + << " differs between vertex and fragment shaders."; return false; } return true; } -bool Program::linkValidateTransformFeedback(InfoLog &infoLog, - const std::vector &varyings, +bool Program::linkValidateBuiltInVaryings(const Context *context, InfoLog &infoLog) const +{ + Shader *vertexShader = mState.mAttachedVertexShader; + Shader *fragmentShader = mState.mAttachedFragmentShader; + const auto &vertexVaryings = vertexShader->getOutputVaryings(context); + const auto &fragmentVaryings = fragmentShader->getInputVaryings(context); + int shaderVersion = vertexShader->getShaderVersion(context); + + if (shaderVersion != 100) + { + // Only ESSL 1.0 has restrictions on matching input and output invariance + return true; + } + + bool glPositionIsInvariant = false; + bool glPointSizeIsInvariant = false; + bool glFragCoordIsInvariant = false; + bool glPointCoordIsInvariant = false; + + for (const sh::Varying &varying : vertexVaryings) + { + if (!varying.isBuiltIn()) + { + continue; + } + if (varying.name.compare("gl_Position") == 0) + { + glPositionIsInvariant = varying.isInvariant; + } + else if (varying.name.compare("gl_PointSize") == 0) + { + glPointSizeIsInvariant = varying.isInvariant; + } + } + + for (const sh::Varying &varying : fragmentVaryings) + { + if (!varying.isBuiltIn()) + { + continue; + } + if (varying.name.compare("gl_FragCoord") == 0) + { + glFragCoordIsInvariant = varying.isInvariant; + } + else if (varying.name.compare("gl_PointCoord") == 0) + { + glPointCoordIsInvariant = varying.isInvariant; + } + } + + // There is some ambiguity in ESSL 1.00.17 paragraph 4.6.4 interpretation, + // for example, https://cvs.khronos.org/bugzilla/show_bug.cgi?id=13842. + // Not requiring invariance to match is supported by: + // dEQP, WebGL CTS, Nexus 5X GLES + if (glFragCoordIsInvariant && !glPositionIsInvariant) + { + infoLog << "gl_FragCoord can only be declared invariant if and only if gl_Position is " + "declared invariant."; + return false; + } + if (glPointCoordIsInvariant && !glPointSizeIsInvariant) + { + infoLog << "gl_PointCoord can only be declared invariant if and only if gl_PointSize is " + "declared invariant."; + return false; + } + + return true; +} + +bool Program::linkValidateTransformFeedback(const gl::Context *context, + InfoLog &infoLog, + const Program::MergedVaryings &varyings, const Caps &caps) const { size_t totalComponents = 0; std::set uniqueNames; - for (const std::string &tfVaryingName : mData.mTransformFeedbackVaryingNames) + for (const std::string &tfVaryingName : mState.mTransformFeedbackVaryingNames) { bool found = false; - for (const sh::Varying *varying : varyings) + std::vector subscripts; + std::string baseName = ParseResourceName(tfVaryingName, &subscripts); + + for (const auto &ref : varyings) { - if (tfVaryingName == varying->name) + const sh::Varying *varying = ref.second.get(); + + if (baseName == varying->name) { if (uniqueNames.count(tfVaryingName) > 0) { @@ -2032,17 +2652,33 @@ bool Program::linkValidateTransformFeedback(InfoLog &infoLog, << tfVaryingName << ")."; return false; } - uniqueNames.insert(tfVaryingName); - - if (varying->isArray()) + if (context->getClientVersion() >= Version(3, 1)) + { + if (IncludeSameArrayElement(uniqueNames, tfVaryingName)) + { + infoLog + << "Two transform feedback varyings include the same array element (" + << tfVaryingName << ")."; + return false; + } + } + else if (varying->isArray()) { infoLog << "Capture of arrays is undefined and not supported."; return false; } + uniqueNames.insert(tfVaryingName); + // TODO(jmadill): Investigate implementation limits on D3D11 - size_t componentCount = gl::VariableComponentCount(varying->type); - if (mData.mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS && + + // GLSL ES 3.10 section 4.3.6: A vertex output can't be an array of arrays. + ASSERT(!varying->isArrayOfArrays()); + size_t elementCount = + ((varying->isArray() && subscripts.empty()) ? varying->getOutermostArraySize() + : 1); + size_t componentCount = VariableComponentCount(varying->type) * elementCount; + if (mState.mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS && componentCount > caps.maxTransformFeedbackSeparateComponents) { infoLog << "Transform feedback varying's " << varying->name << " components (" @@ -2056,19 +2692,21 @@ bool Program::linkValidateTransformFeedback(InfoLog &infoLog, break; } } - - if (tfVaryingName.find('[') != std::string::npos) + if (context->getClientVersion() < Version(3, 1) && + tfVaryingName.find('[') != std::string::npos) { infoLog << "Capture of array elements is undefined and not supported."; return false; } - - // All transform feedback varyings are expected to exist since packVaryings checks for them. - ASSERT(found); - UNUSED_ASSERTION_VARIABLE(found); + if (!found) + { + infoLog << "Transform feedback varying " << tfVaryingName + << " does not exist in the vertex shader."; + return false; + } } - if (mData.mTransformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS && + if (mState.mTransformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS && totalComponents > caps.maxTransformFeedbackInterleavedComponents) { infoLog << "Transform feedback varying total components (" << totalComponents @@ -2080,454 +2718,349 @@ bool Program::linkValidateTransformFeedback(InfoLog &infoLog, return true; } -void Program::gatherTransformFeedbackVaryings(const std::vector &varyings) +bool Program::linkValidateGlobalNames(const Context *context, InfoLog &infoLog) const +{ + const std::vector &vertexUniforms = + mState.mAttachedVertexShader->getUniforms(context); + const std::vector &fragmentUniforms = + mState.mAttachedFragmentShader->getUniforms(context); + const std::vector &attributes = + mState.mAttachedVertexShader->getActiveAttributes(context); + for (const auto &attrib : attributes) + { + for (const auto &uniform : vertexUniforms) + { + if (uniform.name == attrib.name) + { + infoLog << "Name conflicts between a uniform and an attribute: " << attrib.name; + return false; + } + } + for (const auto &uniform : fragmentUniforms) + { + if (uniform.name == attrib.name) + { + infoLog << "Name conflicts between a uniform and an attribute: " << attrib.name; + return false; + } + } + } + return true; +} + +void Program::gatherTransformFeedbackVaryings(const Program::MergedVaryings &varyings) { // Gather the linked varyings that are used for transform feedback, they should all exist. - mData.mTransformFeedbackVaryingVars.clear(); - for (const std::string &tfVaryingName : mData.mTransformFeedbackVaryingNames) + mState.mLinkedTransformFeedbackVaryings.clear(); + for (const std::string &tfVaryingName : mState.mTransformFeedbackVaryingNames) { - for (const sh::Varying *varying : varyings) + std::vector subscripts; + std::string baseName = ParseResourceName(tfVaryingName, &subscripts); + size_t subscript = GL_INVALID_INDEX; + if (!subscripts.empty()) { - if (tfVaryingName == varying->name) + subscript = subscripts.back(); + } + for (const auto &ref : varyings) + { + const sh::Varying *varying = ref.second.get(); + if (baseName == varying->name) { - mData.mTransformFeedbackVaryingVars.push_back(*varying); + mState.mLinkedTransformFeedbackVaryings.emplace_back( + *varying, static_cast(subscript)); break; } } } } -std::vector Program::getMergedVaryings() const +Program::MergedVaryings Program::getMergedVaryings(const Context *context) const { - std::set uniqueNames; - std::vector varyings; + MergedVaryings merged; - for (const sh::Varying &varying : mData.mAttachedVertexShader->getVaryings()) + for (const sh::Varying &varying : mState.mAttachedVertexShader->getOutputVaryings(context)) { - if (uniqueNames.count(varying.name) == 0) - { - uniqueNames.insert(varying.name); - varyings.push_back(&varying); - } + merged[varying.name].vertex = &varying; } - for (const sh::Varying &varying : mData.mAttachedFragmentShader->getVaryings()) + for (const sh::Varying &varying : mState.mAttachedFragmentShader->getInputVaryings(context)) { - if (uniqueNames.count(varying.name) == 0) - { - uniqueNames.insert(varying.name); - varyings.push_back(&varying); - } + merged[varying.name].fragment = &varying; } - return varyings; + return merged; } -void Program::linkOutputVariables() + +void Program::linkOutputVariables(const Context *context) { - const Shader *fragmentShader = mData.mAttachedFragmentShader; + Shader *fragmentShader = mState.mAttachedFragmentShader; ASSERT(fragmentShader != nullptr); + ASSERT(mState.mOutputVariableTypes.empty()); + ASSERT(mState.mActiveOutputVariables.none()); + + // Gather output variable types + for (const auto &outputVariable : fragmentShader->getActiveOutputVariables(context)) + { + if (outputVariable.isBuiltIn() && outputVariable.name != "gl_FragColor" && + outputVariable.name != "gl_FragData") + { + continue; + } + + unsigned int baseLocation = + (outputVariable.location == -1 ? 0u + : static_cast(outputVariable.location)); + + // GLSL ES 3.10 section 4.3.6: Output variables cannot be arrays of arrays or arrays of + // structures, so we may use getBasicTypeElementCount(). + unsigned int elementCount = outputVariable.getBasicTypeElementCount(); + for (unsigned int elementIndex = 0; elementIndex < elementCount; elementIndex++) + { + const unsigned int location = baseLocation + elementIndex; + if (location >= mState.mOutputVariableTypes.size()) + { + mState.mOutputVariableTypes.resize(location + 1, GL_NONE); + } + ASSERT(location < mState.mActiveOutputVariables.size()); + mState.mActiveOutputVariables.set(location); + mState.mOutputVariableTypes[location] = VariableComponentType(outputVariable.type); + } + } + // Skip this step for GLES2 shaders. - if (fragmentShader->getShaderVersion() == 100) + if (fragmentShader->getShaderVersion(context) == 100) return; - const auto &shaderOutputVars = fragmentShader->getActiveOutputVariables(); - + mState.mOutputVariables = fragmentShader->getActiveOutputVariables(context); // TODO(jmadill): any caps validation here? - for (unsigned int outputVariableIndex = 0; outputVariableIndex < shaderOutputVars.size(); + for (unsigned int outputVariableIndex = 0; outputVariableIndex < mState.mOutputVariables.size(); outputVariableIndex++) { - const sh::OutputVariable &outputVariable = shaderOutputVars[outputVariableIndex]; + const sh::OutputVariable &outputVariable = mState.mOutputVariables[outputVariableIndex]; + + if (outputVariable.isArray()) + { + // We're following the GLES 3.1 November 2016 spec section 7.3.1.1 Naming Active + // Resources and including [0] at the end of array variable names. + mState.mOutputVariables[outputVariableIndex].name += "[0]"; + mState.mOutputVariables[outputVariableIndex].mappedName += "[0]"; + } // Don't store outputs for gl_FragDepth, gl_FragColor, etc. if (outputVariable.isBuiltIn()) continue; // Since multiple output locations must be specified, use 0 for non-specified locations. - int baseLocation = (outputVariable.location == -1 ? 0 : outputVariable.location); + unsigned int baseLocation = + (outputVariable.location == -1 ? 0u + : static_cast(outputVariable.location)); - ASSERT(outputVariable.staticUse); - - for (unsigned int elementIndex = 0; elementIndex < outputVariable.elementCount(); - elementIndex++) + // GLSL ES 3.10 section 4.3.6: Output variables cannot be arrays of arrays or arrays of + // structures, so we may use getBasicTypeElementCount(). + unsigned int elementCount = outputVariable.getBasicTypeElementCount(); + for (unsigned int elementIndex = 0; elementIndex < elementCount; elementIndex++) { - const int location = baseLocation + elementIndex; - ASSERT(mData.mOutputVariables.count(location) == 0); - unsigned int element = outputVariable.isArray() ? elementIndex : GL_INVALID_INDEX; - mData.mOutputVariables[location] = - VariableLocation(outputVariable.name, element, outputVariableIndex); - } - } -} - -bool Program::flattenUniformsAndCheckCaps(const Caps &caps, InfoLog &infoLog) -{ - const gl::Shader *vertexShader = mData.getAttachedVertexShader(); - VectorAndSamplerCount vsCounts; - - std::vector samplerUniforms; - - for (const sh::Uniform &uniform : vertexShader->getUniforms()) - { - if (uniform.staticUse) - { - vsCounts += flattenUniform(uniform, uniform.name, &samplerUniforms); - } - } - - if (vsCounts.vectorCount > caps.maxVertexUniformVectors) - { - infoLog << "Vertex shader active uniforms exceed MAX_VERTEX_UNIFORM_VECTORS (" - << caps.maxVertexUniformVectors << ")."; - return false; - } - - if (vsCounts.samplerCount > caps.maxVertexTextureImageUnits) - { - infoLog << "Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (" - << caps.maxVertexTextureImageUnits << ")."; - return false; - } - - const gl::Shader *fragmentShader = mData.getAttachedFragmentShader(); - VectorAndSamplerCount fsCounts; - - for (const sh::Uniform &uniform : fragmentShader->getUniforms()) - { - if (uniform.staticUse) - { - fsCounts += flattenUniform(uniform, uniform.name, &samplerUniforms); - } - } - - if (fsCounts.vectorCount > caps.maxFragmentUniformVectors) - { - infoLog << "Fragment shader active uniforms exceed MAX_FRAGMENT_UNIFORM_VECTORS (" - << caps.maxFragmentUniformVectors << ")."; - return false; - } - - if (fsCounts.samplerCount > caps.maxTextureImageUnits) - { - infoLog << "Fragment shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (" - << caps.maxTextureImageUnits << ")."; - return false; - } - - mSamplerUniformRange.start = static_cast(mData.mUniforms.size()); - mSamplerUniformRange.end = - mSamplerUniformRange.start + static_cast(samplerUniforms.size()); - - mData.mUniforms.insert(mData.mUniforms.end(), samplerUniforms.begin(), samplerUniforms.end()); - - return true; -} - -Program::VectorAndSamplerCount Program::flattenUniform(const sh::ShaderVariable &uniform, - const std::string &fullName, - std::vector *samplerUniforms) -{ - VectorAndSamplerCount vectorAndSamplerCount; - - if (uniform.isStruct()) - { - for (unsigned int elementIndex = 0; elementIndex < uniform.elementCount(); elementIndex++) - { - const std::string &elementString = (uniform.isArray() ? ArrayString(elementIndex) : ""); - - for (size_t fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++) + const unsigned int location = baseLocation + elementIndex; + if (location >= mState.mOutputLocations.size()) { - const sh::ShaderVariable &field = uniform.fields[fieldIndex]; - const std::string &fieldFullName = (fullName + elementString + "." + field.name); - - vectorAndSamplerCount += flattenUniform(field, fieldFullName, samplerUniforms); + mState.mOutputLocations.resize(location + 1); } - } - - return vectorAndSamplerCount; - } - - // Not a struct - bool isSampler = IsSamplerType(uniform.type); - if (!UniformInList(mData.getUniforms(), fullName) && !UniformInList(*samplerUniforms, fullName)) - { - gl::LinkedUniform linkedUniform(uniform.type, uniform.precision, fullName, - uniform.arraySize, -1, - sh::BlockMemberInfo::getDefaultBlockInfo()); - linkedUniform.staticUse = true; - - // Store sampler uniforms separately, so we'll append them to the end of the list. - if (isSampler) - { - samplerUniforms->push_back(linkedUniform); - } - else - { - mData.mUniforms.push_back(linkedUniform); - } - } - - unsigned int elementCount = uniform.elementCount(); - - // Samplers aren't "real" uniforms, so they don't count towards register usage. - // Likewise, don't count "real" uniforms towards sampler count. - vectorAndSamplerCount.vectorCount = - (isSampler ? 0 : (VariableRegisterCount(uniform.type) * elementCount)); - vectorAndSamplerCount.samplerCount = (isSampler ? elementCount : 0); - - return vectorAndSamplerCount; -} - -void Program::gatherInterfaceBlockInfo() -{ - std::set visitedList; - - const gl::Shader *vertexShader = mData.getAttachedVertexShader(); - - ASSERT(mData.mUniformBlocks.empty()); - for (const sh::InterfaceBlock &vertexBlock : vertexShader->getInterfaceBlocks()) - { - // Only 'packed' blocks are allowed to be considered inacive. - if (!vertexBlock.staticUse && vertexBlock.layout == sh::BLOCKLAYOUT_PACKED) - continue; - - if (visitedList.count(vertexBlock.name) > 0) - continue; - - defineUniformBlock(vertexBlock, GL_VERTEX_SHADER); - visitedList.insert(vertexBlock.name); - } - - const gl::Shader *fragmentShader = mData.getAttachedFragmentShader(); - - for (const sh::InterfaceBlock &fragmentBlock : fragmentShader->getInterfaceBlocks()) - { - // Only 'packed' blocks are allowed to be considered inacive. - if (!fragmentBlock.staticUse && fragmentBlock.layout == sh::BLOCKLAYOUT_PACKED) - continue; - - if (visitedList.count(fragmentBlock.name) > 0) - { - for (gl::UniformBlock &block : mData.mUniformBlocks) + ASSERT(!mState.mOutputLocations.at(location).used()); + if (outputVariable.isArray()) { - if (block.name == fragmentBlock.name) - { - block.fragmentStaticUse = fragmentBlock.staticUse; - } - } - - continue; - } - - defineUniformBlock(fragmentBlock, GL_FRAGMENT_SHADER); - visitedList.insert(fragmentBlock.name); - } -} - -template -void Program::defineUniformBlockMembers(const std::vector &fields, - const std::string &prefix, - int blockIndex) -{ - for (const VarT &field : fields) - { - const std::string &fullName = (prefix.empty() ? field.name : prefix + "." + field.name); - - if (field.isStruct()) - { - for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++) - { - const std::string uniformElementName = - fullName + (field.isArray() ? ArrayString(arrayElement) : ""); - defineUniformBlockMembers(field.fields, uniformElementName, blockIndex); - } - } - else - { - // If getBlockMemberInfo returns false, the uniform is optimized out. - sh::BlockMemberInfo memberInfo; - if (!mProgram->getUniformBlockMemberInfo(fullName, &memberInfo)) - { - continue; - } - - LinkedUniform newUniform(field.type, field.precision, fullName, field.arraySize, - blockIndex, memberInfo); - - // Since block uniforms have no location, we don't need to store them in the uniform - // locations list. - mData.mUniforms.push_back(newUniform); - } - } -} - -void Program::defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, GLenum shaderType) -{ - int blockIndex = static_cast(mData.mUniformBlocks.size()); - size_t blockSize = 0; - - // Don't define this block at all if it's not active in the implementation. - if (!mProgram->getUniformBlockSize(interfaceBlock.name, &blockSize)) - { - return; - } - - // Track the first and last uniform index to determine the range of active uniforms in the - // block. - size_t firstBlockUniformIndex = mData.mUniforms.size(); - defineUniformBlockMembers(interfaceBlock.fields, interfaceBlock.fieldPrefix(), blockIndex); - size_t lastBlockUniformIndex = mData.mUniforms.size(); - - std::vector blockUniformIndexes; - for (size_t blockUniformIndex = firstBlockUniformIndex; - blockUniformIndex < lastBlockUniformIndex; ++blockUniformIndex) - { - blockUniformIndexes.push_back(static_cast(blockUniformIndex)); - } - - if (interfaceBlock.arraySize > 0) - { - for (unsigned int arrayElement = 0; arrayElement < interfaceBlock.arraySize; ++arrayElement) - { - UniformBlock block(interfaceBlock.name, true, arrayElement); - block.memberUniformIndexes = blockUniformIndexes; - - if (shaderType == GL_VERTEX_SHADER) - { - block.vertexStaticUse = interfaceBlock.staticUse; + mState.mOutputLocations[location] = + VariableLocation(elementIndex, outputVariableIndex); } else { - ASSERT(shaderType == GL_FRAGMENT_SHADER); - block.fragmentStaticUse = interfaceBlock.staticUse; + VariableLocation locationInfo; + locationInfo.index = outputVariableIndex; + mState.mOutputLocations[location] = locationInfo; } - - // TODO(jmadill): Determine if we can ever have an inactive array element block. - size_t blockElementSize = 0; - if (!mProgram->getUniformBlockSize(block.nameWithArrayIndex(), &blockElementSize)) - { - continue; - } - - ASSERT(blockElementSize == blockSize); - block.dataSize = static_cast(blockElementSize); - mData.mUniformBlocks.push_back(block); } } - else +} + +void Program::setUniformValuesFromBindingQualifiers() +{ + for (unsigned int samplerIndex : mState.mSamplerUniformRange) { - UniformBlock block(interfaceBlock.name, false, 0); - block.memberUniformIndexes = blockUniformIndexes; - - if (shaderType == GL_VERTEX_SHADER) + const auto &samplerUniform = mState.mUniforms[samplerIndex]; + if (samplerUniform.binding != -1) { - block.vertexStaticUse = interfaceBlock.staticUse; + GLint location = getUniformLocation(samplerUniform.name); + ASSERT(location != -1); + std::vector boundTextureUnits; + for (unsigned int elementIndex = 0; + elementIndex < samplerUniform.getBasicTypeElementCount(); ++elementIndex) + { + boundTextureUnits.push_back(samplerUniform.binding + elementIndex); + } + setUniform1iv(location, static_cast(boundTextureUnits.size()), + boundTextureUnits.data()); } - else - { - ASSERT(shaderType == GL_FRAGMENT_SHADER); - block.fragmentStaticUse = interfaceBlock.staticUse; - } - - block.dataSize = static_cast(blockSize); - mData.mUniformBlocks.push_back(block); } } +void Program::gatherAtomicCounterBuffers() +{ + for (unsigned int index : mState.mAtomicCounterUniformRange) + { + auto &uniform = mState.mUniforms[index]; + uniform.blockInfo.offset = uniform.offset; + uniform.blockInfo.arrayStride = (uniform.isArray() ? 4 : 0); + uniform.blockInfo.matrixStride = 0; + uniform.blockInfo.isRowMajorMatrix = false; + } + + // TODO(jie.a.chen@intel.com): Get the actual BUFFER_DATA_SIZE from backend for each buffer. +} + +void Program::initInterfaceBlockBindings() +{ + // Set initial bindings from shader. + for (unsigned int blockIndex = 0; blockIndex < mState.mUniformBlocks.size(); blockIndex++) + { + InterfaceBlock &uniformBlock = mState.mUniformBlocks[blockIndex]; + bindUniformBlock(blockIndex, uniformBlock.binding); + } +} + +void Program::updateSamplerUniform(const VariableLocation &locationInfo, + GLsizei clampedCount, + const GLint *v) +{ + ASSERT(mState.isSamplerUniformIndex(locationInfo.index)); + GLuint samplerIndex = mState.getSamplerIndexFromUniformIndex(locationInfo.index); + std::vector *boundTextureUnits = + &mState.mSamplerBindings[samplerIndex].boundTextureUnits; + + std::copy(v, v + clampedCount, boundTextureUnits->begin() + locationInfo.arrayIndex); + + // Invalidate the validation cache. + mCachedValidateSamplersResult.reset(); +} + template -void Program::setUniformInternal(GLint location, GLsizei count, const T *v) +GLsizei Program::clampUniformCount(const VariableLocation &locationInfo, + GLsizei count, + int vectorSize, + const T *v) { - const VariableLocation &locationInfo = mData.mUniformLocations[location]; - LinkedUniform *linkedUniform = &mData.mUniforms[locationInfo.index]; - uint8_t *destPointer = linkedUniform->getDataPtrToElement(locationInfo.element); + if (count == 1) + return 1; - if (VariableComponentType(linkedUniform->type) == GL_BOOL) - { - // Do a cast conversion for boolean types. From the spec: - // "The uniform is set to FALSE if the input value is 0 or 0.0f, and set to TRUE otherwise." - GLint *destAsInt = reinterpret_cast(destPointer); - for (GLsizei component = 0; component < count; ++component) - { - destAsInt[component] = (v[component] != static_cast(0) ? GL_TRUE : GL_FALSE); - } - } - else - { - // Invalide the validation cache if we modify the sampler data. - if (linkedUniform->isSampler() && memcmp(destPointer, v, sizeof(T) * count) != 0) - { - mCachedValidateSamplersResult.reset(); - } + const LinkedUniform &linkedUniform = mState.mUniforms[locationInfo.index]; - memcpy(destPointer, v, sizeof(T) * count); + // OpenGL ES 3.0.4 spec pg 67: "Values for any array element that exceeds the highest array + // element index used, as reported by GetActiveUniform, will be ignored by the GL." + unsigned int remainingElements = + linkedUniform.getBasicTypeElementCount() - locationInfo.arrayIndex; + GLsizei maxElementCount = + static_cast(remainingElements * linkedUniform.getElementComponents()); + + if (count * vectorSize > maxElementCount) + { + return maxElementCount / vectorSize; } + + return count; } template -void Program::setMatrixUniformInternal(GLint location, - GLsizei count, - GLboolean transpose, - const T *v) +GLsizei Program::clampMatrixUniformCount(GLint location, + GLsizei count, + GLboolean transpose, + const T *v) { + const VariableLocation &locationInfo = mState.mUniformLocations[location]; + if (!transpose) { - setUniformInternal(location, count * cols * rows, v); - return; + return clampUniformCount(locationInfo, count, cols * rows, v); } - // Perform a transposing copy. - const VariableLocation &locationInfo = mData.mUniformLocations[location]; - LinkedUniform *linkedUniform = &mData.mUniforms[locationInfo.index]; - T *destPtr = reinterpret_cast(linkedUniform->getDataPtrToElement(locationInfo.element)); - for (GLsizei element = 0; element < count; ++element) - { - size_t elementOffset = element * rows * cols; + const LinkedUniform &linkedUniform = mState.mUniforms[locationInfo.index]; - for (size_t row = 0; row < rows; ++row) + // OpenGL ES 3.0.4 spec pg 67: "Values for any array element that exceeds the highest array + // element index used, as reported by GetActiveUniform, will be ignored by the GL." + unsigned int remainingElements = + linkedUniform.getBasicTypeElementCount() - locationInfo.arrayIndex; + return std::min(count, static_cast(remainingElements)); +} + +// Driver differences mean that doing the uniform value cast ourselves gives consistent results. +// EG: on NVIDIA drivers, it was observed that getUniformi for MAX_INT+1 returned MIN_INT. +template +void Program::getUniformInternal(const Context *context, + DestT *dataOut, + GLint location, + GLenum nativeType, + int components) const +{ + switch (nativeType) + { + case GL_BOOL: { - for (size_t col = 0; col < cols; ++col) + GLint tempValue[16] = {0}; + mProgram->getUniformiv(context, location, tempValue); + UniformStateQueryCastLoop( + dataOut, reinterpret_cast(tempValue), components); + break; + } + case GL_INT: + { + GLint tempValue[16] = {0}; + mProgram->getUniformiv(context, location, tempValue); + UniformStateQueryCastLoop(dataOut, reinterpret_cast(tempValue), + components); + break; + } + case GL_UNSIGNED_INT: + { + GLuint tempValue[16] = {0}; + mProgram->getUniformuiv(context, location, tempValue); + UniformStateQueryCastLoop(dataOut, reinterpret_cast(tempValue), + components); + break; + } + case GL_FLOAT: + { + GLfloat tempValue[16] = {0}; + mProgram->getUniformfv(context, location, tempValue); + UniformStateQueryCastLoop( + dataOut, reinterpret_cast(tempValue), components); + break; + } + default: + UNREACHABLE(); + break; + } +} + +bool Program::samplesFromTexture(const gl::State &state, GLuint textureID) const +{ + // Must be called after samplers are validated. + ASSERT(mCachedValidateSamplersResult.valid() && mCachedValidateSamplersResult.value()); + + for (const auto &binding : mState.mSamplerBindings) + { + GLenum textureType = binding.textureType; + for (const auto &unit : binding.boundTextureUnits) + { + GLenum programTextureID = state.getSamplerTextureId(unit, textureType); + if (programTextureID == textureID) { - destPtr[col * rows + row + elementOffset] = v[row * cols + col + elementOffset]; + // TODO(jmadill): Check for appropriate overlap. + return true; } } } + + return false; } -template -void Program::getUniformInternal(GLint location, DestT *dataOut) const -{ - const VariableLocation &locationInfo = mData.mUniformLocations[location]; - const LinkedUniform &uniform = mData.mUniforms[locationInfo.index]; - - const uint8_t *srcPointer = uniform.getDataPtrToElement(locationInfo.element); - - GLenum componentType = VariableComponentType(uniform.type); - if (componentType == GLTypeToGLenum::value) - { - memcpy(dataOut, srcPointer, uniform.getElementSize()); - return; - } - - int components = VariableComponentCount(uniform.type); - - switch (componentType) - { - case GL_INT: - UniformStateQueryCastLoop(dataOut, srcPointer, components); - break; - case GL_UNSIGNED_INT: - UniformStateQueryCastLoop(dataOut, srcPointer, components); - break; - case GL_BOOL: - UniformStateQueryCastLoop(dataOut, srcPointer, components); - break; - case GL_FLOAT: - UniformStateQueryCastLoop(dataOut, srcPointer, components); - break; - default: - UNREACHABLE(); - } -} -} +} // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/Program.h b/src/3rdparty/angle/src/libANGLE/Program.h index f885ad1694..c242d84671 100644 --- a/src/3rdparty/angle/src/libANGLE/Program.h +++ b/src/3rdparty/angle/src/libANGLE/Program.h @@ -11,8 +11,10 @@ #define LIBANGLE_PROGRAM_H_ #include -#include +#include +#include +#include #include #include #include @@ -22,15 +24,16 @@ #include "common/mathutil.h" #include "common/Optional.h" -#include "libANGLE/angletypes.h" #include "libANGLE/Constants.h" #include "libANGLE/Debug.h" #include "libANGLE/Error.h" #include "libANGLE/RefCountObject.h" +#include "libANGLE/Uniform.h" +#include "libANGLE/angletypes.h" namespace rx { -class ImplFactory; +class GLImplFactory; class ProgramImpl; struct TranslatedAttribute; } @@ -38,31 +41,17 @@ struct TranslatedAttribute; namespace gl { struct Caps; -struct Data; -class ResourceManager; +class Context; +class ContextState; class Shader; +class ShaderProgramManager; +class State; class InfoLog; -class AttributeBindings; class Buffer; class Framebuffer; -struct UniformBlock; -struct LinkedUniform; extern const char * const g_fakepath; -class AttributeBindings -{ - public: - AttributeBindings(); - ~AttributeBindings(); - - void bindAttributeLocation(GLuint index, const char *name); - int getAttributeBinding(const std::string &name) const; - - private: - std::set mAttributeBinding[MAX_VERTEX_ATTRIBS]; -}; - class InfoLog : angle::NonCopyable { public: @@ -122,134 +111,330 @@ class InfoLog : angle::NonCopyable template StreamHelper operator<<(const T &value) { - StreamHelper helper(&mStream); + ensureInitialized(); + StreamHelper helper(mLazyStream.get()); helper << value; return helper; } - std::string str() const { return mStream.str(); } + std::string str() const { return mLazyStream ? mLazyStream->str() : ""; } private: - std::stringstream mStream; + void ensureInitialized() + { + if (!mLazyStream) + { + mLazyStream.reset(new std::stringstream()); + } + } + + std::unique_ptr mLazyStream; }; // Struct used for correlating uniforms/elements of uniform arrays to handles struct VariableLocation { - VariableLocation(); - VariableLocation(const std::string &name, unsigned int element, unsigned int index); + static constexpr unsigned int kUnused = GL_INVALID_INDEX; - std::string name; - unsigned int element; + VariableLocation(); + VariableLocation(unsigned int arrayIndex, unsigned int index); + + // If used is false, it means this location is only used to fill an empty space in an array, + // and there is no corresponding uniform variable for this location. It can also mean the + // uniform was optimized out by the implementation. + bool used() const { return (index != kUnused); } + void markUnused() { index = kUnused; } + void markIgnored() { ignored = true; } + + // "arrayIndex" stores the index of the innermost GLSL array. It's zero for non-arrays. + unsigned int arrayIndex; + // "index" is an index of the variable. The variable contains the indices for other than the + // innermost GLSL arrays. unsigned int index; + + // If this location was bound to an unreferenced uniform. Setting data on this uniform is a + // no-op. + bool ignored; +}; + +// Information about a variable binding. +// Currently used by CHROMIUM_path_rendering +struct BindingInfo +{ + // The type of binding, for example GL_FLOAT_VEC3. + // This can be GL_NONE if the variable is optimized away. + GLenum type; + + // This is the name of the variable in + // the translated shader program. Note that + // this can be empty in the case where the + // variable has been optimized away. + std::string name; + + // True if the binding is valid, otherwise false. + bool valid; +}; + +// This small structure encapsulates binding sampler uniforms to active GL textures. +struct SamplerBinding +{ + SamplerBinding(GLenum textureTypeIn, size_t elementCount, bool unreferenced); + SamplerBinding(const SamplerBinding &other); + ~SamplerBinding(); + + // Necessary for retrieving active textures from the GL state. + GLenum textureType; + + // List of all textures bound to this sampler, of type textureType. + std::vector boundTextureUnits; + + // A note if this sampler is an unreferenced uniform. + bool unreferenced; +}; + +// A varying with tranform feedback enabled. If it's an array, either the whole array or one of its +// elements specified by 'arrayIndex' can set to be enabled. +struct TransformFeedbackVarying : public sh::Varying +{ + TransformFeedbackVarying(const sh::Varying &varyingIn, GLuint index) + : sh::Varying(varyingIn), arrayIndex(index) + { + ASSERT(!isArrayOfArrays()); + } + std::string nameWithArrayIndex() const + { + std::stringstream fullNameStr; + fullNameStr << name; + if (arrayIndex != GL_INVALID_INDEX) + { + fullNameStr << "[" << arrayIndex << "]"; + } + return fullNameStr.str(); + } + GLsizei size() const + { + return (isArray() && arrayIndex == GL_INVALID_INDEX ? getOutermostArraySize() : 1); + } + + GLuint arrayIndex; +}; + +struct ImageBinding +{ + ImageBinding(size_t count); + ImageBinding(GLuint imageUnit, size_t count); + ImageBinding(const ImageBinding &other); + ~ImageBinding(); + + std::vector boundImageUnits; +}; + +using ShaderStagesMask = angle::BitSet; + +class ProgramState final : angle::NonCopyable +{ + public: + ProgramState(); + ~ProgramState(); + + const std::string &getLabel(); + + Shader *getAttachedVertexShader() const { return mAttachedVertexShader; } + Shader *getAttachedFragmentShader() const { return mAttachedFragmentShader; } + Shader *getAttachedComputeShader() const { return mAttachedComputeShader; } + Shader *getAttachedGeometryShader() const { return mAttachedGeometryShader; } + const std::vector &getTransformFeedbackVaryingNames() const + { + return mTransformFeedbackVaryingNames; + } + GLint getTransformFeedbackBufferMode() const { return mTransformFeedbackBufferMode; } + GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const + { + ASSERT(uniformBlockIndex < mUniformBlocks.size()); + return mUniformBlocks[uniformBlockIndex].binding; + } + GLuint getShaderStorageBlockBinding(GLuint blockIndex) const + { + ASSERT(blockIndex < mShaderStorageBlocks.size()); + return mShaderStorageBlocks[blockIndex].binding; + } + const UniformBlockBindingMask &getActiveUniformBlockBindingsMask() const + { + return mActiveUniformBlockBindings; + } + const std::vector &getAttributes() const { return mAttributes; } + const AttributesMask &getActiveAttribLocationsMask() const + { + return mActiveAttribLocationsMask; + } + unsigned int getMaxActiveAttribLocation() const { return mMaxActiveAttribLocation; } + DrawBufferMask getActiveOutputVariables() const { return mActiveOutputVariables; } + const std::vector &getOutputVariables() const { return mOutputVariables; } + const std::vector &getOutputLocations() const { return mOutputLocations; } + const std::vector &getUniforms() const { return mUniforms; } + const std::vector &getUniformLocations() const { return mUniformLocations; } + const std::vector &getUniformBlocks() const { return mUniformBlocks; } + const std::vector &getShaderStorageBlocks() const + { + return mShaderStorageBlocks; + } + const std::vector &getBufferVariables() const { return mBufferVariables; } + const std::vector &getSamplerBindings() const { return mSamplerBindings; } + const std::vector &getImageBindings() const { return mImageBindings; } + const sh::WorkGroupSize &getComputeShaderLocalSize() const { return mComputeShaderLocalSize; } + const RangeUI &getSamplerUniformRange() const { return mSamplerUniformRange; } + const RangeUI &getImageUniformRange() const { return mImageUniformRange; } + const RangeUI &getAtomicCounterUniformRange() const { return mAtomicCounterUniformRange; } + + const std::vector &getLinkedTransformFeedbackVaryings() const + { + return mLinkedTransformFeedbackVaryings; + } + const std::vector &getAtomicCounterBuffers() const + { + return mAtomicCounterBuffers; + } + + GLuint getUniformIndexFromName(const std::string &name) const; + GLuint getUniformIndexFromLocation(GLint location) const; + Optional getSamplerIndex(GLint location) const; + bool isSamplerUniformIndex(GLuint index) const; + GLuint getSamplerIndexFromUniformIndex(GLuint uniformIndex) const; + GLuint getAttributeLocation(const std::string &name) const; + + GLuint getBufferVariableIndexFromName(const std::string &name) const; + + int getNumViews() const { return mNumViews; } + bool usesMultiview() const { return mNumViews != -1; } + + const ShaderStagesMask &getLinkedShaderStages() const { return mLinkedShaderStages; } + + private: + friend class MemoryProgramCache; + friend class Program; + + std::string mLabel; + + sh::WorkGroupSize mComputeShaderLocalSize; + + Shader *mAttachedFragmentShader; + Shader *mAttachedVertexShader; + Shader *mAttachedComputeShader; + Shader *mAttachedGeometryShader; + + std::vector mTransformFeedbackVaryingNames; + std::vector mLinkedTransformFeedbackVaryings; + GLenum mTransformFeedbackBufferMode; + + // For faster iteration on the blocks currently being bound. + UniformBlockBindingMask mActiveUniformBlockBindings; + + std::vector mAttributes; + angle::BitSet mActiveAttribLocationsMask; + unsigned int mMaxActiveAttribLocation; + + // Uniforms are sorted in order: + // 1. Non-opaque uniforms + // 2. Sampler uniforms + // 3. Image uniforms + // 4. Atomic counter uniforms + // 5. Uniform block uniforms + // This makes opaque uniform validation easier, since we don't need a separate list. + // For generating the entries and naming them we follow the spec: GLES 3.1 November 2016 section + // 7.3.1.1 Naming Active Resources. There's a separate entry for each struct member and each + // inner array of an array of arrays. Names and mapped names of uniforms that are arrays include + // [0] in the end. This makes implementation of queries simpler. + std::vector mUniforms; + + std::vector mUniformLocations; + std::vector mUniformBlocks; + std::vector mBufferVariables; + std::vector mShaderStorageBlocks; + std::vector mAtomicCounterBuffers; + RangeUI mSamplerUniformRange; + RangeUI mImageUniformRange; + RangeUI mAtomicCounterUniformRange; + + // An array of the samplers that are used by the program + std::vector mSamplerBindings; + + // An array of the images that are used by the program + std::vector mImageBindings; + + // Names and mapped names of output variables that are arrays include [0] in the end, similarly + // to uniforms. + std::vector mOutputVariables; + std::vector mOutputLocations; + DrawBufferMask mActiveOutputVariables; + + // Fragment output variable base types: FLOAT, INT, or UINT. Ordered by location. + std::vector mOutputVariableTypes; + + bool mBinaryRetrieveableHint; + bool mSeparable; + ShaderStagesMask mLinkedShaderStages; + + // ANGLE_multiview. + int mNumViews; }; class Program final : angle::NonCopyable, public LabeledObject { public: - class Data final : angle::NonCopyable - { - public: - Data(); - ~Data(); - - const std::string &getLabel(); - - const Shader *getAttachedVertexShader() const { return mAttachedVertexShader; } - const Shader *getAttachedFragmentShader() const { return mAttachedFragmentShader; } - const std::vector &getTransformFeedbackVaryingNames() const - { - return mTransformFeedbackVaryingNames; - } - GLint getTransformFeedbackBufferMode() const { return mTransformFeedbackBufferMode; } - GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const - { - ASSERT(uniformBlockIndex < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS); - return mUniformBlockBindings[uniformBlockIndex]; - } - const UniformBlockBindingMask &getActiveUniformBlockBindingsMask() const - { - return mActiveUniformBlockBindings; - } - const std::vector &getAttributes() const { return mAttributes; } - const AttributesMask &getActiveAttribLocationsMask() const - { - return mActiveAttribLocationsMask; - } - const std::map &getOutputVariables() const - { - return mOutputVariables; - } - const std::vector &getUniforms() const { return mUniforms; } - const std::vector &getUniformLocations() const - { - return mUniformLocations; - } - const std::vector &getUniformBlocks() const { return mUniformBlocks; } - - const LinkedUniform *getUniformByName(const std::string &name) const; - GLint getUniformLocation(const std::string &name) const; - GLuint getUniformIndex(const std::string &name) const; - - private: - friend class Program; - - std::string mLabel; - - Shader *mAttachedFragmentShader; - Shader *mAttachedVertexShader; - - std::vector mTransformFeedbackVaryingNames; - std::vector mTransformFeedbackVaryingVars; - GLenum mTransformFeedbackBufferMode; - - GLuint mUniformBlockBindings[IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS]; - UniformBlockBindingMask mActiveUniformBlockBindings; - - std::vector mAttributes; - std::bitset mActiveAttribLocationsMask; - - // Uniforms are sorted in order: - // 1. Non-sampler uniforms - // 2. Sampler uniforms - // 3. Uniform block uniforms - // This makes sampler validation easier, since we don't need a separate list. - std::vector mUniforms; - std::vector mUniformLocations; - std::vector mUniformBlocks; - - // TODO(jmadill): use unordered/hash map when available - std::map mOutputVariables; - - bool mBinaryRetrieveableHint; - }; - - Program(rx::ImplFactory *factory, ResourceManager *manager, GLuint handle); - ~Program(); + Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, GLuint handle); + void onDestroy(const Context *context); GLuint id() const { return mHandle; } void setLabel(const std::string &label) override; const std::string &getLabel() const override; - rx::ProgramImpl *getImplementation() { return mProgram; } - const rx::ProgramImpl *getImplementation() const { return mProgram; } + rx::ProgramImpl *getImplementation() const { return mProgram; } - bool attachShader(Shader *shader); - bool detachShader(Shader *shader); + void attachShader(Shader *shader); + void detachShader(const Context *context, Shader *shader); int getAttachedShadersCount() const; - void bindAttributeLocation(GLuint index, const char *name); + const Shader *getAttachedVertexShader() const { return mState.mAttachedVertexShader; } + const Shader *getAttachedFragmentShader() const { return mState.mAttachedFragmentShader; } + const Shader *getAttachedComputeShader() const { return mState.mAttachedComputeShader; } + const Shader *getAttachedGeometryShader() const { return mState.mAttachedGeometryShader; } - Error link(const gl::Data &data); + void bindAttributeLocation(GLuint index, const char *name); + void bindUniformLocation(GLuint index, const char *name); + + // CHROMIUM_path_rendering + BindingInfo getFragmentInputBindingInfo(const Context *context, GLint index) const; + void bindFragmentInputLocation(GLint index, const char *name); + void pathFragmentInputGen(const Context *context, + GLint index, + GLenum genMode, + GLint components, + const GLfloat *coeffs); + + Error link(const gl::Context *context); bool isLinked() const; - Error loadBinary(GLenum binaryFormat, const void *binary, GLsizei length); - Error saveBinary(GLenum *binaryFormat, void *binary, GLsizei bufSize, GLsizei *length) const; - GLint getBinaryLength() const; + bool hasLinkedVertexShader() const { return mState.mLinkedShaderStages[SHADER_VERTEX]; } + bool hasLinkedFragmentShader() const { return mState.mLinkedShaderStages[SHADER_FRAGMENT]; } + bool hasLinkedComputeShader() const { return mState.mLinkedShaderStages[SHADER_COMPUTE]; } + + Error loadBinary(const Context *context, + GLenum binaryFormat, + const void *binary, + GLsizei length); + Error saveBinary(const Context *context, + GLenum *binaryFormat, + void *binary, + GLsizei bufSize, + GLsizei *length) const; + GLint getBinaryLength(const Context *context) const; void setBinaryRetrievableHint(bool retrievable); bool getBinaryRetrievableHint() const; + void setSeparable(bool separable); + bool isSeparable() const; + int getInfoLogLength() const; void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const; void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders) const; @@ -257,12 +442,23 @@ class Program final : angle::NonCopyable, public LabeledObject GLuint getAttributeLocation(const std::string &name) const; bool isAttribLocationActive(size_t attribLocation) const; - void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); + void getActiveAttribute(GLuint index, + GLsizei bufsize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name) const; GLint getActiveAttributeCount() const; GLint getActiveAttributeMaxLength() const; - const std::vector &getAttributes() const { return mData.mAttributes; } + const std::vector &getAttributes() const { return mState.mAttributes; } GLint getFragDataLocation(const std::string &name) const; + size_t getOutputResourceCount() const; + const std::vector &getOutputVariableTypes() const + { + return mState.mOutputVariableTypes; + } + DrawBufferMask getActiveOutputVariables() const { return mState.mActiveOutputVariables; } void getActiveUniform(GLuint index, GLsizei bufsize, @@ -271,10 +467,21 @@ class Program final : angle::NonCopyable, public LabeledObject GLenum *type, GLchar *name) const; GLint getActiveUniformCount() const; + size_t getActiveBufferVariableCount() const; GLint getActiveUniformMaxLength() const; - GLint getActiveUniformi(GLuint index, GLenum pname) const; bool isValidUniformLocation(GLint location) const; const LinkedUniform &getUniformByLocation(GLint location) const; + const VariableLocation &getUniformLocation(GLint location) const; + const std::vector &getUniformLocations() const; + const LinkedUniform &getUniformByIndex(GLuint index) const; + + const BufferVariable &getBufferVariableByIndex(GLuint index) const; + + enum SetUniformResult + { + SamplerChanged, + NoSamplerChange, + }; GLint getUniformLocation(const std::string &name) const; GLuint getUniformIndex(const std::string &name) const; @@ -282,7 +489,7 @@ class Program final : angle::NonCopyable, public LabeledObject void setUniform2fv(GLint location, GLsizei count, const GLfloat *v); void setUniform3fv(GLint location, GLsizei count, const GLfloat *v); void setUniform4fv(GLint location, GLsizei count, const GLfloat *v); - void setUniform1iv(GLint location, GLsizei count, const GLint *v); + SetUniformResult setUniform1iv(GLint location, GLsizei count, const GLint *v); void setUniform2iv(GLint location, GLsizei count, const GLint *v); void setUniform3iv(GLint location, GLsizei count, const GLint *v); void setUniform4iv(GLint location, GLsizei count, const GLint *v); @@ -300,21 +507,32 @@ class Program final : angle::NonCopyable, public LabeledObject void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void getUniformfv(GLint location, GLfloat *params) const; - void getUniformiv(GLint location, GLint *params) const; - void getUniformuiv(GLint location, GLuint *params) const; + void getUniformfv(const Context *context, GLint location, GLfloat *params) const; + void getUniformiv(const Context *context, GLint location, GLint *params) const; + void getUniformuiv(const Context *context, GLint location, GLuint *params) const; - void getActiveUniformBlockName(GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName) const; - void getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const; + void getActiveUniformBlockName(const GLuint blockIndex, + GLsizei bufSize, + GLsizei *length, + GLchar *blockName) const; + void getActiveShaderStorageBlockName(const GLuint blockIndex, + GLsizei bufSize, + GLsizei *length, + GLchar *blockName) const; GLuint getActiveUniformBlockCount() const; + GLuint getActiveAtomicCounterBufferCount() const; + GLuint getActiveShaderStorageBlockCount() const; GLint getActiveUniformBlockMaxLength() const; GLuint getUniformBlockIndex(const std::string &name) const; + GLuint getShaderStorageBlockIndex(const std::string &name) const; void bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding); GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const; + GLuint getShaderStorageBlockBinding(GLuint shaderStorageBlockIndex) const; - const UniformBlock &getUniformBlockByIndex(GLuint index) const; + const InterfaceBlock &getUniformBlockByIndex(GLuint index) const; + const InterfaceBlock &getShaderStorageBlockByIndex(GLuint index) const; void setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode); void getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const; @@ -322,11 +540,14 @@ class Program final : angle::NonCopyable, public LabeledObject GLsizei getTransformFeedbackVaryingMaxLength() const; GLenum getTransformFeedbackBufferMode() const; - static bool linkValidateUniforms(InfoLog &infoLog, const std::string &uniformName, const sh::Uniform &vertexUniform, const sh::Uniform &fragmentUniform); - static bool linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform); + static bool linkValidateInterfaceBlockFields(InfoLog &infoLog, + const std::string &uniformName, + const sh::InterfaceBlockField &vertexUniform, + const sh::InterfaceBlockField &fragmentUniform, + bool webglCompatibility); void addRef(); - void release(); + void release(const Context *context); unsigned int getRefCount() const; void flagForDeletion(); bool isFlaggedForDeletion() const; @@ -334,28 +555,25 @@ class Program final : angle::NonCopyable, public LabeledObject void validate(const Caps &caps); bool validateSamplers(InfoLog *infoLog, const Caps &caps); bool isValidated() const; + bool samplesFromTexture(const gl::State &state, GLuint textureID) const; const AttributesMask &getActiveAttribLocationsMask() const { - return mData.mActiveAttribLocationsMask; + return mState.mActiveAttribLocationsMask; } - private: - void unlink(bool destroy = false); - void resetUniformBlockBindings(); + const std::vector &getSamplerBindings() const + { + return mState.mSamplerBindings; + } - bool linkAttributes(const gl::Data &data, - InfoLog &infoLog, - const AttributeBindings &attributeBindings, - const Shader *vertexShader); - bool linkUniformBlocks(InfoLog &infoLog, const Caps &caps); - static bool linkVaryings(InfoLog &infoLog, - const Shader *vertexShader, - const Shader *fragmentShader); - bool linkUniforms(gl::InfoLog &infoLog, const gl::Caps &caps); - void indexUniforms(); - bool areMatchingInterfaceBlocks(gl::InfoLog &infoLog, const sh::InterfaceBlock &vertexInterfaceBlock, - const sh::InterfaceBlock &fragmentInterfaceBlock); + const std::vector &getImageBindings() const { return mState.mImageBindings; } + const sh::WorkGroupSize &getComputeShaderLocalSize() const + { + return mState.mComputeShaderLocalSize; + } + + const ProgramState &getState() const { return mState; } static bool linkValidateVariablesBase(InfoLog &infoLog, const std::string &variableName, @@ -363,71 +581,147 @@ class Program final : angle::NonCopyable, public LabeledObject const sh::ShaderVariable &fragmentVariable, bool validatePrecision); - static bool linkValidateVaryings(InfoLog &infoLog, const std::string &varyingName, const sh::Varying &vertexVarying, const sh::Varying &fragmentVarying); - bool linkValidateTransformFeedback(InfoLog &infoLog, - const std::vector &linkedVaryings, - const Caps &caps) const; + GLuint getInputResourceIndex(const GLchar *name) const; + GLuint getOutputResourceIndex(const GLchar *name) const; + void getInputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const; + void getOutputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const; + void getUniformResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const; + void getBufferVariableResourceName(GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name) const; + const sh::Attribute &getInputResource(GLuint index) const; + const sh::OutputVariable &getOutputResource(GLuint index) const; - void gatherTransformFeedbackVaryings(const std::vector &varyings); - bool assignUniformBlockRegister(InfoLog &infoLog, UniformBlock *uniformBlock, GLenum shader, unsigned int registerIndex, const Caps &caps); - void defineOutputVariables(Shader *fragmentShader); - - std::vector getMergedVaryings() const; - void linkOutputVariables(); - - bool flattenUniformsAndCheckCaps(const Caps &caps, InfoLog &infoLog); - - struct VectorAndSamplerCount + class Bindings final : angle::NonCopyable { - VectorAndSamplerCount() : vectorCount(0), samplerCount(0) {} - VectorAndSamplerCount(const VectorAndSamplerCount &other) = default; - VectorAndSamplerCount &operator=(const VectorAndSamplerCount &other) = default; + public: + Bindings(); + ~Bindings(); + void bindLocation(GLuint index, const std::string &name); + int getBinding(const std::string &name) const; - VectorAndSamplerCount &operator+=(const VectorAndSamplerCount &other) - { - vectorCount += other.vectorCount; - samplerCount += other.samplerCount; - return *this; - } + typedef std::unordered_map::const_iterator const_iterator; + const_iterator begin() const; + const_iterator end() const; - unsigned int vectorCount; - unsigned int samplerCount; + private: + std::unordered_map mBindings; }; - VectorAndSamplerCount flattenUniform(const sh::ShaderVariable &uniform, - const std::string &fullName, - std::vector *samplerUniforms); + const Bindings &getAttributeBindings() const { return mAttributeBindings; } + const Bindings &getUniformLocationBindings() const { return mUniformLocationBindings; } + const Bindings &getFragmentInputBindings() const { return mFragmentInputBindings; } - void gatherInterfaceBlockInfo(); - template - void defineUniformBlockMembers(const std::vector &fields, - const std::string &prefix, - int blockIndex); + int getNumViews() const { return mState.getNumViews(); } + bool usesMultiview() const { return mState.usesMultiview(); } - void defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, GLenum shaderType); + struct VaryingRef + { + const sh::Varying *get() const { return vertex ? vertex : fragment; } + const sh::Varying *vertex = nullptr; + const sh::Varying *fragment = nullptr; + }; + using MergedVaryings = std::map; + + private: + ~Program() override; + + void unlink(); + + bool linkAttributes(const Context *context, InfoLog &infoLog); + bool validateVertexAndFragmentInterfaceBlocks( + const std::vector &vertexInterfaceBlocks, + const std::vector &fragmentInterfaceBlocks, + InfoLog &infoLog, + bool webglCompatibility) const; + bool linkInterfaceBlocks(const Context *context, InfoLog &infoLog); + bool linkVaryings(const Context *context, InfoLog &infoLog) const; + + bool linkUniforms(const Context *context, + InfoLog &infoLog, + const Bindings &uniformLocationBindings); + void linkSamplerAndImageBindings(); + bool linkAtomicCounterBuffers(); + + void updateLinkedShaderStages(); + + bool areMatchingInterfaceBlocks(InfoLog &infoLog, + const sh::InterfaceBlock &vertexInterfaceBlock, + const sh::InterfaceBlock &fragmentInterfaceBlock, + bool webglCompatibility) const; + + static bool linkValidateVaryings(InfoLog &infoLog, + const std::string &varyingName, + const sh::Varying &vertexVarying, + const sh::Varying &fragmentVarying, + int shaderVersion); + bool linkValidateBuiltInVaryings(const Context *context, InfoLog &infoLog) const; + bool linkValidateTransformFeedback(const gl::Context *context, + InfoLog &infoLog, + const MergedVaryings &linkedVaryings, + const Caps &caps) const; + bool linkValidateGlobalNames(const Context *context, InfoLog &infoLog) const; + + void gatherTransformFeedbackVaryings(const MergedVaryings &varyings); + + MergedVaryings getMergedVaryings(const Context *context) const; + void linkOutputVariables(const Context *context); + + void setUniformValuesFromBindingQualifiers(); + + void gatherAtomicCounterBuffers(); + void initInterfaceBlockBindings(); + + // Both these function update the cached uniform values and return a modified "count" + // so that the uniform update doesn't overflow the uniform. template - void setUniformInternal(GLint location, GLsizei count, const T *v); - + GLsizei clampUniformCount(const VariableLocation &locationInfo, + GLsizei count, + int vectorSize, + const T *v); template - void setMatrixUniformInternal(GLint location, GLsizei count, GLboolean transpose, const T *v); + GLsizei clampMatrixUniformCount(GLint location, GLsizei count, GLboolean transpose, const T *v); + + void updateSamplerUniform(const VariableLocation &locationInfo, + GLsizei clampedCount, + const GLint *v); template - void getUniformInternal(GLint location, DestT *dataOut) const; + void getUniformInternal(const Context *context, + DestT *dataOut, + GLint location, + GLenum nativeType, + int components) const; - Data mData; + template + void getResourceName(GLuint index, + const std::vector &resources, + GLsizei bufSize, + GLsizei *length, + GLchar *name) const; + + ProgramState mState; rx::ProgramImpl *mProgram; bool mValidated; - AttributeBindings mAttributeBindings; + Bindings mAttributeBindings; + + // Note that this has nothing to do with binding layout qualifiers that can be set for some + // uniforms in GLES3.1+. It is used to pre-set the location of uniforms. + Bindings mUniformLocationBindings; + + // CHROMIUM_path_rendering + Bindings mFragmentInputBindings; bool mLinked; bool mDeleteStatus; // Flag to indicate that the program can be deleted when no longer in use unsigned int mRefCount; - ResourceManager *mResourceManager; + ShaderProgramManager *mResourceManager; const GLuint mHandle; InfoLog mInfoLog; @@ -435,8 +729,7 @@ class Program final : angle::NonCopyable, public LabeledObject // Cache for sampler validation Optional mCachedValidateSamplersResult; std::vector mTextureUnitTypesCache; - RangeUI mSamplerUniformRange; }; -} +} // namespace gl #endif // LIBANGLE_PROGRAM_H_ diff --git a/src/3rdparty/angle/src/libANGLE/ProgramLinkedResources.cpp b/src/3rdparty/angle/src/libANGLE/ProgramLinkedResources.cpp new file mode 100644 index 0000000000..a33f751525 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/ProgramLinkedResources.cpp @@ -0,0 +1,1040 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// UniformLinker.cpp: implements link-time checks for default block uniforms, and generates uniform +// locations. Populates data structures related to uniforms so that they can be stored in program +// state. + +#include "libANGLE/ProgramLinkedResources.h" + +#include "common/string_utils.h" +#include "common/utilities.h" +#include "libANGLE/Caps.h" +#include "libANGLE/Context.h" +#include "libANGLE/Shader.h" +#include "libANGLE/features.h" + +namespace gl +{ + +namespace +{ + +LinkedUniform *FindUniform(std::vector &list, const std::string &name) +{ + for (LinkedUniform &uniform : list) + { + if (uniform.name == name) + return &uniform; + } + + return nullptr; +} + +int GetUniformLocationBinding(const Program::Bindings &uniformLocationBindings, + const sh::Uniform &uniform) +{ + int binding = uniformLocationBindings.getBinding(uniform.name); + if (uniform.isArray() && binding == -1) + { + // Bindings for array uniforms can be set either with or without [0] in the end. + ASSERT(angle::EndsWith(uniform.name, "[0]")); + std::string nameWithoutIndex = uniform.name.substr(0u, uniform.name.length() - 3u); + return uniformLocationBindings.getBinding(nameWithoutIndex); + } + return binding; +} + +} // anonymous namespace + +UniformLinker::UniformLinker(const ProgramState &state) : mState(state) +{ +} + +UniformLinker::~UniformLinker() = default; + +void UniformLinker::getResults(std::vector *uniforms, + std::vector *uniformLocations) +{ + uniforms->swap(mUniforms); + uniformLocations->swap(mUniformLocations); +} + +bool UniformLinker::link(const Context *context, + InfoLog &infoLog, + const Program::Bindings &uniformLocationBindings) +{ + if (mState.getAttachedVertexShader() && mState.getAttachedFragmentShader()) + { + ASSERT(mState.getAttachedComputeShader() == nullptr); + if (!validateVertexAndFragmentUniforms(context, infoLog)) + { + return false; + } + } + + // Flatten the uniforms list (nested fields) into a simple list (no nesting). + // Also check the maximum uniform vector and sampler counts. + if (!flattenUniformsAndCheckCaps(context, infoLog)) + { + return false; + } + + if (!checkMaxCombinedAtomicCounters(context->getCaps(), infoLog)) + { + return false; + } + + if (!indexUniforms(infoLog, uniformLocationBindings)) + { + return false; + } + + return true; +} + +bool UniformLinker::validateVertexAndFragmentUniforms(const Context *context, + InfoLog &infoLog) const +{ + // Check that uniforms defined in the vertex and fragment shaders are identical + std::map linkedUniforms; + const std::vector &vertexUniforms = + mState.getAttachedVertexShader()->getUniforms(context); + const std::vector &fragmentUniforms = + mState.getAttachedFragmentShader()->getUniforms(context); + + for (const sh::Uniform &vertexUniform : vertexUniforms) + { + linkedUniforms[vertexUniform.name] = vertexUniform; + } + + for (const sh::Uniform &fragmentUniform : fragmentUniforms) + { + auto entry = linkedUniforms.find(fragmentUniform.name); + if (entry != linkedUniforms.end()) + { + const sh::Uniform &linkedUniform = entry->second; + const std::string &uniformName = "uniform '" + linkedUniform.name + "'"; + if (!linkValidateUniforms(infoLog, uniformName, linkedUniform, fragmentUniform)) + { + return false; + } + } + } + return true; +} + +// GLSL ES Spec 3.00.3, section 4.3.5. +bool UniformLinker::linkValidateUniforms(InfoLog &infoLog, + const std::string &uniformName, + const sh::Uniform &vertexUniform, + const sh::Uniform &fragmentUniform) +{ +#if ANGLE_PROGRAM_LINK_VALIDATE_UNIFORM_PRECISION == ANGLE_ENABLED + const bool validatePrecision = true; +#else + const bool validatePrecision = false; +#endif + + if (!Program::linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, + validatePrecision)) + { + return false; + } + + // GLSL ES Spec 3.10.4, section 4.4.5. + if (vertexUniform.binding != -1 && fragmentUniform.binding != -1 && + vertexUniform.binding != fragmentUniform.binding) + { + infoLog << "Binding layout qualifiers for " << uniformName + << " differ between vertex and fragment shaders."; + return false; + } + + // GLSL ES Spec 3.10.4, section 9.2.1. + if (vertexUniform.location != -1 && fragmentUniform.location != -1 && + vertexUniform.location != fragmentUniform.location) + { + infoLog << "Location layout qualifiers for " << uniformName + << " differ between vertex and fragment shaders."; + return false; + } + if (vertexUniform.offset != fragmentUniform.offset) + { + infoLog << "Offset layout qualifiers for " << uniformName + << " differ between vertex and fragment shaders."; + return false; + } + + return true; +} + +bool UniformLinker::indexUniforms(InfoLog &infoLog, + const Program::Bindings &uniformLocationBindings) +{ + // All the locations where another uniform can't be located. + std::set reservedLocations; + // Locations which have been allocated for an unused uniform. + std::set ignoredLocations; + + int maxUniformLocation = -1; + + // Gather uniform locations that have been set either using the bindUniformLocation API or by + // using a location layout qualifier and check conflicts between them. + if (!gatherUniformLocationsAndCheckConflicts(infoLog, uniformLocationBindings, + &reservedLocations, &ignoredLocations, + &maxUniformLocation)) + { + return false; + } + + // Conflicts have been checked, now we can prune non-statically used uniforms. Code further down + // the line relies on only having statically used uniforms in mUniforms. + pruneUnusedUniforms(); + + // Gather uniforms that have their location pre-set and uniforms that don't yet have a location. + std::vector unlocatedUniforms; + std::map preLocatedUniforms; + + for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) + { + const LinkedUniform &uniform = mUniforms[uniformIndex]; + + if (uniform.isBuiltIn() || IsAtomicCounterType(uniform.type)) + { + continue; + } + + int preSetLocation = GetUniformLocationBinding(uniformLocationBindings, uniform); + int shaderLocation = uniform.location; + + if (shaderLocation != -1) + { + preSetLocation = shaderLocation; + } + + unsigned int elementCount = uniform.getBasicTypeElementCount(); + for (unsigned int arrayIndex = 0; arrayIndex < elementCount; arrayIndex++) + { + VariableLocation location(arrayIndex, static_cast(uniformIndex)); + + if ((arrayIndex == 0 && preSetLocation != -1) || shaderLocation != -1) + { + int elementLocation = preSetLocation + arrayIndex; + preLocatedUniforms[elementLocation] = location; + } + else + { + unlocatedUniforms.push_back(location); + } + } + } + + // Make enough space for all uniforms, with pre-set locations or not. + mUniformLocations.resize( + std::max(unlocatedUniforms.size() + preLocatedUniforms.size() + ignoredLocations.size(), + static_cast(maxUniformLocation + 1))); + + // Assign uniforms with pre-set locations + for (const auto &uniform : preLocatedUniforms) + { + mUniformLocations[uniform.first] = uniform.second; + } + + // Assign ignored uniforms + for (const auto &ignoredLocation : ignoredLocations) + { + mUniformLocations[ignoredLocation].markIgnored(); + } + + // Automatically assign locations for the rest of the uniforms + size_t nextUniformLocation = 0; + for (const auto &unlocatedUniform : unlocatedUniforms) + { + while (mUniformLocations[nextUniformLocation].used() || + mUniformLocations[nextUniformLocation].ignored) + { + nextUniformLocation++; + } + + ASSERT(nextUniformLocation < mUniformLocations.size()); + mUniformLocations[nextUniformLocation] = unlocatedUniform; + nextUniformLocation++; + } + + return true; +} + +bool UniformLinker::gatherUniformLocationsAndCheckConflicts( + InfoLog &infoLog, + const Program::Bindings &uniformLocationBindings, + std::set *reservedLocations, + std::set *ignoredLocations, + int *maxUniformLocation) +{ + for (const LinkedUniform &uniform : mUniforms) + { + if (uniform.isBuiltIn()) + { + continue; + } + + int apiBoundLocation = GetUniformLocationBinding(uniformLocationBindings, uniform); + int shaderLocation = uniform.location; + + if (shaderLocation != -1) + { + unsigned int elementCount = uniform.getBasicTypeElementCount(); + + for (unsigned int arrayIndex = 0; arrayIndex < elementCount; arrayIndex++) + { + // GLSL ES 3.10 section 4.4.3 + int elementLocation = shaderLocation + arrayIndex; + *maxUniformLocation = std::max(*maxUniformLocation, elementLocation); + if (reservedLocations->find(elementLocation) != reservedLocations->end()) + { + infoLog << "Multiple uniforms bound to location " << elementLocation << "."; + return false; + } + reservedLocations->insert(elementLocation); + if (!uniform.staticUse) + { + ignoredLocations->insert(elementLocation); + } + } + } + else if (apiBoundLocation != -1 && uniform.staticUse) + { + // Only the first location is reserved even if the uniform is an array. + *maxUniformLocation = std::max(*maxUniformLocation, apiBoundLocation); + if (reservedLocations->find(apiBoundLocation) != reservedLocations->end()) + { + infoLog << "Multiple uniforms bound to location " << apiBoundLocation << "."; + return false; + } + reservedLocations->insert(apiBoundLocation); + } + } + + // Record the uniform locations that were bound using the API for uniforms that were not found + // from the shader. Other uniforms should not be assigned to those locations. + for (const auto &locationBinding : uniformLocationBindings) + { + GLuint location = locationBinding.second; + if (reservedLocations->find(location) == reservedLocations->end()) + { + ignoredLocations->insert(location); + *maxUniformLocation = std::max(*maxUniformLocation, static_cast(location)); + } + } + + return true; +} + +void UniformLinker::pruneUnusedUniforms() +{ + auto uniformIter = mUniforms.begin(); + while (uniformIter != mUniforms.end()) + { + if (uniformIter->staticUse) + { + ++uniformIter; + } + else + { + uniformIter = mUniforms.erase(uniformIter); + } + } +} + +bool UniformLinker::flattenUniformsAndCheckCapsForShader( + const Context *context, + Shader *shader, + GLuint maxUniformComponents, + GLuint maxTextureImageUnits, + GLuint maxImageUnits, + GLuint maxAtomicCounters, + const std::string &componentsErrorMessage, + const std::string &samplerErrorMessage, + const std::string &imageErrorMessage, + const std::string &atomicCounterErrorMessage, + std::vector &samplerUniforms, + std::vector &imageUniforms, + std::vector &atomicCounterUniforms, + InfoLog &infoLog) +{ + ShaderUniformCount shaderUniformCount; + for (const sh::Uniform &uniform : shader->getUniforms(context)) + { + shaderUniformCount += flattenUniform(uniform, &samplerUniforms, &imageUniforms, + &atomicCounterUniforms, shader->getType()); + } + + if (shaderUniformCount.vectorCount > maxUniformComponents) + { + infoLog << componentsErrorMessage << maxUniformComponents << ")."; + return false; + } + + if (shaderUniformCount.samplerCount > maxTextureImageUnits) + { + infoLog << samplerErrorMessage << maxTextureImageUnits << ")."; + return false; + } + + if (shaderUniformCount.imageCount > maxImageUnits) + { + infoLog << imageErrorMessage << maxImageUnits << ")."; + return false; + } + + if (shaderUniformCount.atomicCounterCount > maxAtomicCounters) + { + infoLog << atomicCounterErrorMessage << maxAtomicCounters << ")."; + return false; + } + + return true; +} + +bool UniformLinker::flattenUniformsAndCheckCaps(const Context *context, InfoLog &infoLog) +{ + std::vector samplerUniforms; + std::vector imageUniforms; + std::vector atomicCounterUniforms; + + const Caps &caps = context->getCaps(); + + if (mState.getAttachedComputeShader()) + { + Shader *computeShader = mState.getAttachedComputeShader(); + + // TODO (mradev): check whether we need finer-grained component counting + if (!flattenUniformsAndCheckCapsForShader( + context, computeShader, caps.maxComputeUniformComponents / 4, + caps.maxComputeTextureImageUnits, caps.maxComputeImageUniforms, + caps.maxComputeAtomicCounters, + "Compute shader active uniforms exceed MAX_COMPUTE_UNIFORM_COMPONENTS (", + "Compute shader sampler count exceeds MAX_COMPUTE_TEXTURE_IMAGE_UNITS (", + "Compute shader image count exceeds MAX_COMPUTE_IMAGE_UNIFORMS (", + "Compute shader atomic counter count exceeds MAX_COMPUTE_ATOMIC_COUNTERS (", + samplerUniforms, imageUniforms, atomicCounterUniforms, infoLog)) + { + return false; + } + } + else + { + Shader *vertexShader = mState.getAttachedVertexShader(); + + if (!flattenUniformsAndCheckCapsForShader( + context, vertexShader, caps.maxVertexUniformVectors, + caps.maxVertexTextureImageUnits, caps.maxVertexImageUniforms, + caps.maxVertexAtomicCounters, + "Vertex shader active uniforms exceed MAX_VERTEX_UNIFORM_VECTORS (", + "Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (", + "Vertex shader image count exceeds MAX_VERTEX_IMAGE_UNIFORMS (", + "Vertex shader atomic counter count exceeds MAX_VERTEX_ATOMIC_COUNTERS (", + samplerUniforms, imageUniforms, atomicCounterUniforms, infoLog)) + { + return false; + } + + Shader *fragmentShader = mState.getAttachedFragmentShader(); + + if (!flattenUniformsAndCheckCapsForShader( + context, fragmentShader, caps.maxFragmentUniformVectors, caps.maxTextureImageUnits, + caps.maxFragmentImageUniforms, caps.maxFragmentAtomicCounters, + "Fragment shader active uniforms exceed MAX_FRAGMENT_UNIFORM_VECTORS (", + "Fragment shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (", + "Fragment shader image count exceeds MAX_FRAGMENT_IMAGE_UNIFORMS (", + "Fragment shader atomic counter count exceeds MAX_FRAGMENT_ATOMIC_COUNTERS (", + samplerUniforms, imageUniforms, atomicCounterUniforms, infoLog)) + { + return false; + } + } + + mUniforms.insert(mUniforms.end(), samplerUniforms.begin(), samplerUniforms.end()); + mUniforms.insert(mUniforms.end(), imageUniforms.begin(), imageUniforms.end()); + mUniforms.insert(mUniforms.end(), atomicCounterUniforms.begin(), atomicCounterUniforms.end()); + return true; +} + +UniformLinker::ShaderUniformCount UniformLinker::flattenUniform( + const sh::Uniform &uniform, + std::vector *samplerUniforms, + std::vector *imageUniforms, + std::vector *atomicCounterUniforms, + GLenum shaderType) +{ + int location = uniform.location; + ShaderUniformCount shaderUniformCount = + flattenUniformImpl(uniform, uniform.name, uniform.mappedName, samplerUniforms, + imageUniforms, atomicCounterUniforms, shaderType, uniform.staticUse, + uniform.binding, uniform.offset, &location); + if (uniform.staticUse) + { + return shaderUniformCount; + } + return ShaderUniformCount(); +} + +UniformLinker::ShaderUniformCount UniformLinker::flattenArrayOfStructsUniform( + const sh::ShaderVariable &uniform, + unsigned int arrayNestingIndex, + const std::string &namePrefix, + const std::string &mappedNamePrefix, + std::vector *samplerUniforms, + std::vector *imageUniforms, + std::vector *atomicCounterUniforms, + GLenum shaderType, + bool markStaticUse, + int binding, + int offset, + int *location) +{ + // Nested arrays are processed starting from outermost (arrayNestingIndex 0u) and ending at the + // innermost. + ShaderUniformCount shaderUniformCount; + const unsigned int currentArraySize = uniform.getNestedArraySize(arrayNestingIndex); + for (unsigned int arrayElement = 0u; arrayElement < currentArraySize; ++arrayElement) + { + const std::string elementName = namePrefix + ArrayString(arrayElement); + const std::string elementMappedName = mappedNamePrefix + ArrayString(arrayElement); + if (arrayNestingIndex + 1u < uniform.arraySizes.size()) + { + shaderUniformCount += flattenArrayOfStructsUniform( + uniform, arrayNestingIndex + 1u, elementName, elementMappedName, samplerUniforms, + imageUniforms, atomicCounterUniforms, shaderType, markStaticUse, binding, offset, + location); + } + else + { + shaderUniformCount += flattenStructUniform( + uniform.fields, elementName, elementMappedName, samplerUniforms, imageUniforms, + atomicCounterUniforms, shaderType, markStaticUse, binding, offset, location); + } + } + return shaderUniformCount; +} + +UniformLinker::ShaderUniformCount UniformLinker::flattenStructUniform( + const std::vector &fields, + const std::string &namePrefix, + const std::string &mappedNamePrefix, + std::vector *samplerUniforms, + std::vector *imageUniforms, + std::vector *atomicCounterUniforms, + GLenum shaderType, + bool markStaticUse, + int binding, + int offset, + int *location) +{ + ShaderUniformCount shaderUniformCount; + for (const sh::ShaderVariable &field : fields) + { + const std::string &fieldName = namePrefix + "." + field.name; + const std::string &fieldMappedName = mappedNamePrefix + "." + field.mappedName; + + shaderUniformCount += + flattenUniformImpl(field, fieldName, fieldMappedName, samplerUniforms, imageUniforms, + atomicCounterUniforms, shaderType, markStaticUse, -1, -1, location); + } + return shaderUniformCount; +} + +UniformLinker::ShaderUniformCount UniformLinker::flattenArrayUniform( + const sh::ShaderVariable &uniform, + const std::string &namePrefix, + const std::string &mappedNamePrefix, + std::vector *samplerUniforms, + std::vector *imageUniforms, + std::vector *atomicCounterUniforms, + GLenum shaderType, + bool markStaticUse, + int binding, + int offset, + int *location) +{ + ShaderUniformCount shaderUniformCount; + + ASSERT(uniform.isArray()); + for (unsigned int arrayElement = 0u; arrayElement < uniform.getOutermostArraySize(); + ++arrayElement) + { + sh::ShaderVariable uniformElement = uniform; + uniformElement.indexIntoArray(arrayElement); + const std::string elementName = namePrefix + ArrayString(arrayElement); + const std::string elementMappedName = mappedNamePrefix + ArrayString(arrayElement); + + shaderUniformCount += flattenUniformImpl( + uniformElement, elementName, elementMappedName, samplerUniforms, imageUniforms, + atomicCounterUniforms, shaderType, markStaticUse, binding, offset, location); + } + return shaderUniformCount; +} + +UniformLinker::ShaderUniformCount UniformLinker::flattenUniformImpl( + const sh::ShaderVariable &uniform, + const std::string &fullName, + const std::string &fullMappedName, + std::vector *samplerUniforms, + std::vector *imageUniforms, + std::vector *atomicCounterUniforms, + GLenum shaderType, + bool markStaticUse, + int binding, + int offset, + int *location) +{ + ASSERT(location); + ShaderUniformCount shaderUniformCount; + + if (uniform.isStruct()) + { + if (uniform.isArray()) + { + shaderUniformCount += flattenArrayOfStructsUniform( + uniform, 0u, fullName, fullMappedName, samplerUniforms, imageUniforms, + atomicCounterUniforms, shaderType, markStaticUse, binding, offset, location); + } + else + { + shaderUniformCount += flattenStructUniform( + uniform.fields, fullName, fullMappedName, samplerUniforms, imageUniforms, + atomicCounterUniforms, shaderType, markStaticUse, binding, offset, location); + } + return shaderUniformCount; + } + if (uniform.isArrayOfArrays()) + { + // GLES 3.1 November 2016 section 7.3.1 page 77: + // "For an active variable declared as an array of an aggregate data type (structures or + // arrays), a separate entry will be generated for each active array element" + return flattenArrayUniform(uniform, fullName, fullMappedName, samplerUniforms, + imageUniforms, atomicCounterUniforms, shaderType, markStaticUse, + binding, offset, location); + } + + // Not a struct + bool isSampler = IsSamplerType(uniform.type); + bool isImage = IsImageType(uniform.type); + bool isAtomicCounter = IsAtomicCounterType(uniform.type); + std::vector *uniformList = &mUniforms; + if (isSampler) + { + uniformList = samplerUniforms; + } + else if (isImage) + { + uniformList = imageUniforms; + } + else if (isAtomicCounter) + { + uniformList = atomicCounterUniforms; + } + + std::string fullNameWithArrayIndex(fullName); + std::string fullMappedNameWithArrayIndex(fullMappedName); + + if (uniform.isArray()) + { + // We're following the GLES 3.1 November 2016 spec section 7.3.1.1 Naming Active Resources + // and including [0] at the end of array variable names. + fullNameWithArrayIndex += "[0]"; + fullMappedNameWithArrayIndex += "[0]"; + } + + LinkedUniform *existingUniform = FindUniform(*uniformList, fullNameWithArrayIndex); + if (existingUniform) + { + if (binding != -1) + { + existingUniform->binding = binding; + } + if (offset != -1) + { + existingUniform->offset = offset; + } + if (*location != -1) + { + existingUniform->location = *location; + } + if (markStaticUse) + { + existingUniform->staticUse = true; + existingUniform->setStaticUse(shaderType, true); + } + } + else + { + ASSERT(uniform.arraySizes.size() <= 1u); + LinkedUniform linkedUniform(uniform.type, uniform.precision, fullNameWithArrayIndex, + uniform.arraySizes, binding, offset, *location, -1, + sh::BlockMemberInfo::getDefaultBlockInfo()); + linkedUniform.mappedName = fullMappedNameWithArrayIndex; + linkedUniform.staticUse = markStaticUse; + linkedUniform.flattenedOffsetInParentArrays = uniform.flattenedOffsetInParentArrays; + if (markStaticUse) + { + linkedUniform.setStaticUse(shaderType, true); + } + + uniformList->push_back(linkedUniform); + } + + // Struct and array of arrays uniforms get flattened so we can use getBasicTypeElementCount(). + unsigned int elementCount = uniform.getBasicTypeElementCount(); + + // Samplers and images aren't "real" uniforms, so they don't count towards register usage. + // Likewise, don't count "real" uniforms towards opaque count. + shaderUniformCount.vectorCount = + (IsOpaqueType(uniform.type) ? 0 : (VariableRegisterCount(uniform.type) * elementCount)); + shaderUniformCount.samplerCount = (isSampler ? elementCount : 0); + shaderUniformCount.imageCount = (isImage ? elementCount : 0); + shaderUniformCount.atomicCounterCount = (isAtomicCounter ? elementCount : 0); + + if (*location != -1) + { + *location += elementCount; + } + + return shaderUniformCount; +} + +bool UniformLinker::checkMaxCombinedAtomicCounters(const Caps &caps, InfoLog &infoLog) +{ + unsigned int atomicCounterCount = 0; + for (const auto &uniform : mUniforms) + { + if (IsAtomicCounterType(uniform.type) && uniform.staticUse) + { + atomicCounterCount += uniform.getBasicTypeElementCount(); + if (atomicCounterCount > caps.maxCombinedAtomicCounters) + { + infoLog << "atomic counter count exceeds MAX_COMBINED_ATOMIC_COUNTERS" + << caps.maxCombinedAtomicCounters << ")."; + return false; + } + } + } + return true; +} + +// InterfaceBlockLinker implementation. +InterfaceBlockLinker::InterfaceBlockLinker(std::vector *blocksOut) + : mBlocksOut(blocksOut) +{ +} + +InterfaceBlockLinker::~InterfaceBlockLinker() +{ +} + +void InterfaceBlockLinker::addShaderBlocks(GLenum shader, + const std::vector *blocks) +{ + mShaderBlocks.push_back(std::make_pair(shader, blocks)); +} + +void InterfaceBlockLinker::linkBlocks(const GetBlockSize &getBlockSize, + const GetBlockMemberInfo &getMemberInfo) const +{ + ASSERT(mBlocksOut->empty()); + + std::set visitedList; + + for (const auto &shaderBlocks : mShaderBlocks) + { + const GLenum shaderType = shaderBlocks.first; + + for (const auto &block : *shaderBlocks.second) + { + // Only 'packed' blocks are allowed to be considered inactive. + if (!block.staticUse && block.layout == sh::BLOCKLAYOUT_PACKED) + continue; + + if (visitedList.count(block.name) > 0) + { + if (block.staticUse) + { + for (InterfaceBlock &priorBlock : *mBlocksOut) + { + if (block.name == priorBlock.name) + { + priorBlock.setStaticUse(shaderType, true); + // TODO(jiajia.qin@intel.com): update the block members static use. + } + } + } + } + else + { + defineInterfaceBlock(getBlockSize, getMemberInfo, block, shaderType); + visitedList.insert(block.name); + } + } + } +} + +template +void InterfaceBlockLinker::defineArrayOfStructsBlockMembers(const GetBlockMemberInfo &getMemberInfo, + const VarT &field, + unsigned int arrayNestingIndex, + const std::string &prefix, + const std::string &mappedPrefix, + int blockIndex, + bool singleEntryForTopLevelArray, + int topLevelArraySize) const +{ + // Nested arrays are processed starting from outermost (arrayNestingIndex 0u) and ending at the + // innermost. + unsigned int entryGenerationArraySize = field.getNestedArraySize(arrayNestingIndex); + if (singleEntryForTopLevelArray) + { + entryGenerationArraySize = 1; + } + for (unsigned int arrayElement = 0u; arrayElement < entryGenerationArraySize; ++arrayElement) + { + const std::string elementName = prefix + ArrayString(arrayElement); + const std::string elementMappedName = mappedPrefix + ArrayString(arrayElement); + if (arrayNestingIndex + 1u < field.arraySizes.size()) + { + defineArrayOfStructsBlockMembers(getMemberInfo, field, arrayNestingIndex + 1u, + elementName, elementMappedName, blockIndex, false, + topLevelArraySize); + } + else + { + defineBlockMembers(getMemberInfo, field.fields, elementName, elementMappedName, + blockIndex, false, topLevelArraySize); + } + } +} + +template +void InterfaceBlockLinker::defineBlockMembers(const GetBlockMemberInfo &getMemberInfo, + const std::vector &fields, + const std::string &prefix, + const std::string &mappedPrefix, + int blockIndex, + bool singleEntryForTopLevelArray, + int topLevelArraySize) const +{ + for (const VarT &field : fields) + { + std::string fullName = (prefix.empty() ? field.name : prefix + "." + field.name); + std::string fullMappedName = + (mappedPrefix.empty() ? field.mappedName : mappedPrefix + "." + field.mappedName); + + defineBlockMember(getMemberInfo, field, fullName, fullMappedName, blockIndex, + singleEntryForTopLevelArray, topLevelArraySize); + } +} + +template +void InterfaceBlockLinker::defineBlockMember(const GetBlockMemberInfo &getMemberInfo, + const VarT &field, + const std::string &fullName, + const std::string &fullMappedName, + int blockIndex, + bool singleEntryForTopLevelArray, + int topLevelArraySize) const +{ + int nextArraySize = topLevelArraySize; + if (((field.isArray() && field.isStruct()) || field.isArrayOfArrays()) && + singleEntryForTopLevelArray) + { + // In OpenGL ES 3.10 spec, session 7.3.1.1 'For an active shader storage block + // member declared as an array of an aggregate type, an entry will be generated only + // for the first array element, regardless of its type.' + nextArraySize = field.getOutermostArraySize(); + } + + if (field.isStruct()) + { + if (field.isArray()) + { + defineArrayOfStructsBlockMembers(getMemberInfo, field, 0u, fullName, fullMappedName, + blockIndex, singleEntryForTopLevelArray, + nextArraySize); + } + else + { + ASSERT(nextArraySize == topLevelArraySize); + defineBlockMembers(getMemberInfo, field.fields, fullName, fullMappedName, blockIndex, + false, nextArraySize); + } + return; + } + if (field.isArrayOfArrays()) + { + unsigned int entryGenerationArraySize = field.getOutermostArraySize(); + if (singleEntryForTopLevelArray) + { + entryGenerationArraySize = 1u; + } + for (unsigned int arrayElement = 0u; arrayElement < entryGenerationArraySize; + ++arrayElement) + { + VarT fieldElement = field; + fieldElement.indexIntoArray(arrayElement); + const std::string elementName = fullName + ArrayString(arrayElement); + const std::string elementMappedName = fullMappedName + ArrayString(arrayElement); + + defineBlockMember(getMemberInfo, fieldElement, elementName, elementMappedName, + blockIndex, false, nextArraySize); + } + return; + } + + // If getBlockMemberInfo returns false, the variable is optimized out. + sh::BlockMemberInfo memberInfo; + if (!getMemberInfo(fullName, fullMappedName, &memberInfo)) + { + return; + } + + std::string fullNameWithArrayIndex = fullName; + std::string fullMappedNameWithArrayIndex = fullMappedName; + + if (field.isArray()) + { + fullNameWithArrayIndex += "[0]"; + fullMappedNameWithArrayIndex += "[0]"; + } + + ASSERT(nextArraySize == topLevelArraySize); + defineBlockMemberImpl(field, fullNameWithArrayIndex, fullMappedNameWithArrayIndex, blockIndex, + memberInfo, nextArraySize); +} + +void InterfaceBlockLinker::defineInterfaceBlock(const GetBlockSize &getBlockSize, + const GetBlockMemberInfo &getMemberInfo, + const sh::InterfaceBlock &interfaceBlock, + GLenum shaderType) const +{ + size_t blockSize = 0; + std::vector blockIndexes; + + int blockIndex = static_cast(mBlocksOut->size()); + // Track the first and last block member index to determine the range of active block members in + // the block. + size_t firstBlockMemberIndex = getCurrentBlockMemberIndex(); + defineBlockMembers(getMemberInfo, interfaceBlock.fields, interfaceBlock.fieldPrefix(), + interfaceBlock.fieldMappedPrefix(), blockIndex, + interfaceBlock.blockType == sh::BlockType::BLOCK_BUFFER, 1); + size_t lastBlockMemberIndex = getCurrentBlockMemberIndex(); + + for (size_t blockMemberIndex = firstBlockMemberIndex; blockMemberIndex < lastBlockMemberIndex; + ++blockMemberIndex) + { + blockIndexes.push_back(static_cast(blockMemberIndex)); + } + + // ESSL 3.10 section 4.4.4 page 58: + // Any uniform or shader storage block declared without a binding qualifier is initially + // assigned to block binding point zero. + int blockBinding = (interfaceBlock.binding == -1 ? 0 : interfaceBlock.binding); + for (unsigned int arrayElement = 0; arrayElement < interfaceBlock.elementCount(); + ++arrayElement) + { + std::string blockArrayName = interfaceBlock.name; + std::string blockMappedArrayName = interfaceBlock.mappedName; + if (interfaceBlock.isArray()) + { + blockArrayName += ArrayString(arrayElement); + blockMappedArrayName += ArrayString(arrayElement); + } + + // Don't define this block at all if it's not active in the implementation. + if (!getBlockSize(blockArrayName, blockMappedArrayName, &blockSize)) + { + continue; + } + + InterfaceBlock block(interfaceBlock.name, interfaceBlock.mappedName, + interfaceBlock.isArray(), arrayElement, blockBinding + arrayElement); + block.memberIndexes = blockIndexes; + block.setStaticUse(shaderType, interfaceBlock.staticUse); + + // Since all block elements in an array share the same active interface blocks, they + // will all be active once any block member is used. So, since interfaceBlock.name[0] + // was active, here we will add every block element in the array. + block.dataSize = static_cast(blockSize); + mBlocksOut->push_back(block); + } +} + +// UniformBlockLinker implementation. +UniformBlockLinker::UniformBlockLinker(std::vector *blocksOut, + std::vector *uniformsOut) + : InterfaceBlockLinker(blocksOut), mUniformsOut(uniformsOut) +{ +} + +UniformBlockLinker::~UniformBlockLinker() +{ +} + +void UniformBlockLinker::defineBlockMemberImpl(const sh::ShaderVariable &field, + const std::string &fullName, + const std::string &fullMappedName, + int blockIndex, + const sh::BlockMemberInfo &memberInfo, + int /*topLevelArraySize*/) const +{ + LinkedUniform newUniform(field.type, field.precision, fullName, field.arraySizes, -1, -1, -1, + blockIndex, memberInfo); + newUniform.mappedName = fullMappedName; + // TODO(jiajia.qin@intel.com): update the block memeber static use. + + // Since block uniforms have no location, we don't need to store them in the uniform locations + // list. + mUniformsOut->push_back(newUniform); +} + +size_t UniformBlockLinker::getCurrentBlockMemberIndex() const +{ + return mUniformsOut->size(); +} + +// ShaderStorageBlockLinker implementation. +ShaderStorageBlockLinker::ShaderStorageBlockLinker(std::vector *blocksOut, + std::vector *bufferVariablesOut) + : InterfaceBlockLinker(blocksOut), mBufferVariablesOut(bufferVariablesOut) +{ +} + +ShaderStorageBlockLinker::~ShaderStorageBlockLinker() +{ +} + +void ShaderStorageBlockLinker::defineBlockMemberImpl(const sh::ShaderVariable &field, + const std::string &fullName, + const std::string &fullMappedName, + int blockIndex, + const sh::BlockMemberInfo &memberInfo, + int topLevelArraySize) const +{ + BufferVariable newBufferVariable(field.type, field.precision, fullName, field.arraySizes, + blockIndex, memberInfo); + newBufferVariable.mappedName = fullMappedName; + // TODO(jiajia.qin@intel.com): update the block memeber static use. + + newBufferVariable.topLevelArraySize = topLevelArraySize; + + mBufferVariablesOut->push_back(newBufferVariable); +} + +size_t ShaderStorageBlockLinker::getCurrentBlockMemberIndex() const +{ + return mBufferVariablesOut->size(); +} + +} // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/ProgramLinkedResources.h b/src/3rdparty/angle/src/libANGLE/ProgramLinkedResources.h new file mode 100644 index 0000000000..1bf91b7f3b --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/ProgramLinkedResources.h @@ -0,0 +1,274 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// UniformLinker.h: implements link-time checks for default block uniforms, and generates uniform +// locations. Populates data structures related to uniforms so that they can be stored in program +// state. + +#ifndef LIBANGLE_UNIFORMLINKER_H_ +#define LIBANGLE_UNIFORMLINKER_H_ + +#include "libANGLE/Program.h" +#include "libANGLE/Uniform.h" +#include "libANGLE/VaryingPacking.h" + +#include + +namespace gl +{ + +class UniformLinker +{ + public: + UniformLinker(const ProgramState &state); + ~UniformLinker(); + + bool link(const Context *context, + InfoLog &infoLog, + const Program::Bindings &uniformLocationBindings); + + void getResults(std::vector *uniforms, + std::vector *uniformLocations); + + private: + struct ShaderUniformCount + { + ShaderUniformCount() : vectorCount(0), samplerCount(0), imageCount(0), atomicCounterCount(0) + { + } + ShaderUniformCount(const ShaderUniformCount &other) = default; + ShaderUniformCount &operator=(const ShaderUniformCount &other) = default; + + ShaderUniformCount &operator+=(const ShaderUniformCount &other) + { + vectorCount += other.vectorCount; + samplerCount += other.samplerCount; + imageCount += other.imageCount; + atomicCounterCount += other.atomicCounterCount; + return *this; + } + + unsigned int vectorCount; + unsigned int samplerCount; + unsigned int imageCount; + unsigned int atomicCounterCount; + }; + + bool validateVertexAndFragmentUniforms(const Context *context, InfoLog &infoLog) const; + + static bool linkValidateUniforms(InfoLog &infoLog, + const std::string &uniformName, + const sh::Uniform &vertexUniform, + const sh::Uniform &fragmentUniform); + + bool flattenUniformsAndCheckCapsForShader(const Context *context, + Shader *shader, + GLuint maxUniformComponents, + GLuint maxTextureImageUnits, + GLuint maxImageUnits, + GLuint maxAtomicCounters, + const std::string &componentsErrorMessage, + const std::string &samplerErrorMessage, + const std::string &imageErrorMessage, + const std::string &atomicCounterErrorMessage, + std::vector &samplerUniforms, + std::vector &imageUniforms, + std::vector &atomicCounterUniforms, + InfoLog &infoLog); + + bool flattenUniformsAndCheckCaps(const Context *context, InfoLog &infoLog); + bool checkMaxCombinedAtomicCounters(const Caps &caps, InfoLog &infoLog); + + ShaderUniformCount flattenUniform(const sh::Uniform &uniform, + std::vector *samplerUniforms, + std::vector *imageUniforms, + std::vector *atomicCounterUniforms, + GLenum shaderType); + + ShaderUniformCount flattenArrayOfStructsUniform( + const sh::ShaderVariable &uniform, + unsigned int arrayNestingIndex, + const std::string &namePrefix, + const std::string &mappedNamePrefix, + std::vector *samplerUniforms, + std::vector *imageUniforms, + std::vector *atomicCounterUniforms, + GLenum shaderType, + bool markStaticUse, + int binding, + int offset, + int *location); + + ShaderUniformCount flattenStructUniform(const std::vector &fields, + const std::string &namePrefix, + const std::string &mappedNamePrefix, + std::vector *samplerUniforms, + std::vector *imageUniforms, + std::vector *atomicCounterUniforms, + GLenum shaderType, + bool markStaticUse, + int binding, + int offset, + int *location); + + ShaderUniformCount flattenArrayUniform(const sh::ShaderVariable &uniform, + const std::string &fullName, + const std::string &fullMappedName, + std::vector *samplerUniforms, + std::vector *imageUniforms, + std::vector *atomicCounterUniforms, + GLenum shaderType, + bool markStaticUse, + int binding, + int offset, + int *location); + + // markStaticUse is given as a separate parameter because it is tracked here at struct + // granularity. + ShaderUniformCount flattenUniformImpl(const sh::ShaderVariable &uniform, + const std::string &fullName, + const std::string &fullMappedName, + std::vector *samplerUniforms, + std::vector *imageUniforms, + std::vector *atomicCounterUniforms, + GLenum shaderType, + bool markStaticUse, + int binding, + int offset, + int *location); + + bool indexUniforms(InfoLog &infoLog, const Program::Bindings &uniformLocationBindings); + bool gatherUniformLocationsAndCheckConflicts(InfoLog &infoLog, + const Program::Bindings &uniformLocationBindings, + std::set *reservedLocations, + std::set *ignoredLocations, + int *maxUniformLocation); + void pruneUnusedUniforms(); + + const ProgramState &mState; + std::vector mUniforms; + std::vector mUniformLocations; +}; + +// This class is intended to be used during the link step to store interface block information. +// It is called by the Impl class during ProgramImpl::link so that it has access to the +// real block size and layout. +class InterfaceBlockLinker : angle::NonCopyable +{ + public: + virtual ~InterfaceBlockLinker(); + + using GetBlockSize = std::function< + bool(const std::string &blockName, const std::string &blockMappedName, size_t *sizeOut)>; + using GetBlockMemberInfo = std::function< + bool(const std::string &name, const std::string &mappedName, sh::BlockMemberInfo *infoOut)>; + + // This is called once per shader stage. It stores a pointer to the block vector, so it's + // important that this class does not persist longer than the duration of Program::link. + void addShaderBlocks(GLenum shader, const std::vector *blocks); + + // This is called once during a link operation, after all shader blocks are added. + void linkBlocks(const GetBlockSize &getBlockSize, + const GetBlockMemberInfo &getMemberInfo) const; + + protected: + InterfaceBlockLinker(std::vector *blocksOut); + void defineInterfaceBlock(const GetBlockSize &getBlockSize, + const GetBlockMemberInfo &getMemberInfo, + const sh::InterfaceBlock &interfaceBlock, + GLenum shaderType) const; + + template + void defineBlockMembers(const GetBlockMemberInfo &getMemberInfo, + const std::vector &fields, + const std::string &prefix, + const std::string &mappedPrefix, + int blockIndex, + bool singleEntryForTopLevelArray, + int topLevelArraySize) const; + template + void defineBlockMember(const GetBlockMemberInfo &getMemberInfo, + const VarT &field, + const std::string &fullName, + const std::string &fullMappedName, + int blockIndex, + bool singleEntryForTopLevelArray, + int topLevelArraySize) const; + + virtual void defineBlockMemberImpl(const sh::ShaderVariable &field, + const std::string &fullName, + const std::string &fullMappedName, + int blockIndex, + const sh::BlockMemberInfo &memberInfo, + int topLevelArraySize) const = 0; + virtual size_t getCurrentBlockMemberIndex() const = 0; + + using ShaderBlocks = std::pair *>; + std::vector mShaderBlocks; + + std::vector *mBlocksOut; + + private: + template + void defineArrayOfStructsBlockMembers(const GetBlockMemberInfo &getMemberInfo, + const VarT &field, + unsigned int arrayNestingIndex, + const std::string &prefix, + const std::string &mappedPrefix, + int blockIndex, + bool singleEntryForTopLevelArray, + int topLevelArraySize) const; +}; + +class UniformBlockLinker final : public InterfaceBlockLinker +{ + public: + UniformBlockLinker(std::vector *blocksOut, + std::vector *uniformsOut); + ~UniformBlockLinker() override; + + private: + void defineBlockMemberImpl(const sh::ShaderVariable &field, + const std::string &fullName, + const std::string &fullMappedName, + int blockIndex, + const sh::BlockMemberInfo &memberInfo, + int topLevelArraySize) const override; + size_t getCurrentBlockMemberIndex() const override; + std::vector *mUniformsOut; +}; + +class ShaderStorageBlockLinker final : public InterfaceBlockLinker +{ + public: + ShaderStorageBlockLinker(std::vector *blocksOut, + std::vector *bufferVariablesOut); + ~ShaderStorageBlockLinker() override; + + private: + void defineBlockMemberImpl(const sh::ShaderVariable &field, + const std::string &fullName, + const std::string &fullMappedName, + int blockIndex, + const sh::BlockMemberInfo &memberInfo, + int topLevelArraySize) const override; + size_t getCurrentBlockMemberIndex() const override; + std::vector *mBufferVariablesOut; +}; + +// The link operation is responsible for finishing the link of uniform and interface blocks. +// This way it can filter out unreferenced resources and still have access to the info. +// TODO(jmadill): Integrate uniform linking/filtering as well as interface blocks. +struct ProgramLinkedResources +{ + VaryingPacking varyingPacking; + UniformBlockLinker uniformBlockLinker; + ShaderStorageBlockLinker shaderStorageBlockLinker; +}; + +} // namespace gl + +#endif // LIBANGLE_UNIFORMLINKER_H_ diff --git a/src/3rdparty/angle/src/libANGLE/ProgramPipeline.cpp b/src/3rdparty/angle/src/libANGLE/ProgramPipeline.cpp new file mode 100644 index 0000000000..0445512090 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/ProgramPipeline.cpp @@ -0,0 +1,65 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ProgramPipeline.cpp: Implements the gl::ProgramPipeline class. +// Implements GL program pipeline objects and related functionality. +// [OpenGL ES 3.1] section 7.4 page 105. + +#include "libANGLE/ProgramPipeline.h" + +#include "libANGLE/angletypes.h" +#include "libANGLE/renderer/GLImplFactory.h" +#include "libANGLE/renderer/ProgramPipelineImpl.h" + +namespace gl +{ + +ProgramPipelineState::ProgramPipelineState() : mLabel() +{ +} + +ProgramPipelineState::~ProgramPipelineState() +{ +} + +const std::string &ProgramPipelineState::getLabel() const +{ + return mLabel; +} + +ProgramPipeline::ProgramPipeline(rx::GLImplFactory *factory, GLuint handle) + : RefCountObject(handle), + mProgramPipeline(factory->createProgramPipeline(mState)) +{ + ASSERT(mProgramPipeline); +} + +ProgramPipeline::~ProgramPipeline() +{ + mProgramPipeline.release(); +} + +Error ProgramPipeline::onDestroy(const Context *context) +{ + return NoError(); +} + +void ProgramPipeline::setLabel(const std::string &label) +{ + mState.mLabel = label; +} + +const std::string &ProgramPipeline::getLabel() const +{ + return mState.mLabel; +} + +rx::ProgramPipelineImpl *ProgramPipeline::getImplementation() const +{ + return mProgramPipeline.get(); +} + +} // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/ProgramPipeline.h b/src/3rdparty/angle/src/libANGLE/ProgramPipeline.h new file mode 100644 index 0000000000..2aac87c7b8 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/ProgramPipeline.h @@ -0,0 +1,65 @@ +// +// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ProgramPipeline.h: Defines the gl::ProgramPipeline class. +// Implements GL program pipeline objects and related functionality. +// [OpenGL ES 3.1] section 7.4 page 105. + +#ifndef LIBANGLE_PROGRAMPIPELINE_H_ +#define LIBANGLE_PROGRAMPIPELINE_H_ + +#include + +#include "common/angleutils.h" +#include "libANGLE/Debug.h" +#include "libANGLE/RefCountObject.h" + +namespace rx +{ +class GLImplFactory; +class ProgramPipelineImpl; +}; + +namespace gl +{ +class Context; +class ProgramPipeline; + +class ProgramPipelineState final : angle::NonCopyable +{ + public: + ProgramPipelineState(); + ~ProgramPipelineState(); + + const std::string &getLabel() const; + + private: + friend class ProgramPipeline; + + std::string mLabel; +}; + +class ProgramPipeline final : public RefCountObject, public LabeledObject +{ + public: + ProgramPipeline(rx::GLImplFactory *factory, GLuint handle); + ~ProgramPipeline() override; + + Error onDestroy(const Context *context) override; + + void setLabel(const std::string &label) override; + const std::string &getLabel() const override; + + rx::ProgramPipelineImpl *getImplementation() const; + + private: + std::unique_ptr mProgramPipeline; + + ProgramPipelineState mState; +}; +} + +#endif // LIBANGLE_PROGRAMPIPELINE_H_ diff --git a/src/3rdparty/angle/src/libANGLE/Query.h b/src/3rdparty/angle/src/libANGLE/Query.h index 5486f983e7..c307eaaf08 100644 --- a/src/3rdparty/angle/src/libANGLE/Query.h +++ b/src/3rdparty/angle/src/libANGLE/Query.h @@ -29,7 +29,8 @@ class Query final : public RefCountObject, public LabeledObject { public: Query(rx::QueryImpl *impl, GLuint id); - virtual ~Query(); + void destroy(const gl::Context *context) {} + ~Query() override; void setLabel(const std::string &label) override; const std::string &getLabel() const override; diff --git a/src/3rdparty/angle/src/libANGLE/RefCountObject.cpp b/src/3rdparty/angle/src/libANGLE/RefCountObject.cpp deleted file mode 100644 index b1210200cf..0000000000 --- a/src/3rdparty/angle/src/libANGLE/RefCountObject.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// RefCountObject.cpp: Defines the gl::RefCountObject base class that provides -// lifecycle support for GL objects using the traditional BindObject scheme, but -// that need to be reference counted for correct cross-context deletion. -// (Concretely, textures, buffers and renderbuffers.) - -#include "RefCountObject.h" - -RefCountObject::RefCountObject(GLuint id) - : mId(id), - mRefCount(0) -{ -} - -RefCountObject::~RefCountObject() -{ - ASSERT(mRefCount == 0); -} - -void RefCountObject::addRef() const -{ - mRefCount++; -} - -void RefCountObject::release() const -{ - ASSERT(mRefCount > 0); - - if (--mRefCount == 0) - { - delete this; - } -} - diff --git a/src/3rdparty/angle/src/libANGLE/RefCountObject.h b/src/3rdparty/angle/src/libANGLE/RefCountObject.h index 86e6d788b5..cb41cc27f4 100644 --- a/src/3rdparty/angle/src/libANGLE/RefCountObject.h +++ b/src/3rdparty/angle/src/libANGLE/RefCountObject.h @@ -12,16 +12,21 @@ #ifndef LIBANGLE_REFCOUNTOBJECT_H_ #define LIBANGLE_REFCOUNTOBJECT_H_ -#include "common/debug.h" - #include "angle_gl.h" +#include "common/debug.h" +#include "libANGLE/Error.h" #include -class RefCountObject : angle::NonCopyable +namespace gl +{ +class Context; + +class RefCountObjectNoID : angle::NonCopyable { public: - explicit RefCountObject(GLuint id) : mId(id), mRefCount(0) {} + RefCountObjectNoID() : mRefCount(0) {} + virtual Error onDestroy(const Context *context); void addRef() const { ++mRefCount; } @@ -35,17 +40,56 @@ class RefCountObject : angle::NonCopyable } } - GLuint id() const { return mId; } - size_t getRefCount() const { return mRefCount; } protected: - virtual ~RefCountObject() { ASSERT(mRefCount == 0); } + virtual ~RefCountObjectNoID(); + + // A specialized release method for objects which need a destroy context. + void release(const gl::Context *context) + { + ASSERT(mRefCount > 0); + if (--mRefCount == 0) + { + ANGLE_SWALLOW_ERR(onDestroy(context)); + delete this; + } + } + + template + friend class BindingPointer; + mutable std::size_t mRefCount; +}; + +inline RefCountObjectNoID::~RefCountObjectNoID() +{ + ASSERT(mRefCount == 0); +} + +inline Error RefCountObjectNoID::onDestroy(const Context *context) +{ + return NoError(); +} + +template +class BindingPointer; + +class RefCountObject : RefCountObjectNoID +{ + public: + explicit RefCountObject(GLuint id) : mId(id) {} + + GLuint id() const { return mId; } + + using RefCountObjectNoID::release; + using RefCountObjectNoID::addRef; + using RefCountObjectNoID::getRefCount; + + protected: + ~RefCountObject() override {} private: GLuint mId; - - mutable std::size_t mRefCount; }; template @@ -57,15 +101,17 @@ class BindingPointer { } - BindingPointer(const BindingPointer &other) - : mObject(nullptr) + BindingPointer(ObjectType *object) : mObject(object) { mObject->addRef(); } + + BindingPointer(const BindingPointer &other) : mObject(other.mObject) { - set(other.mObject); + mObject->addRef(); } - void operator=(const BindingPointer &other) + BindingPointer &operator=(BindingPointer &&other) { - set(other.mObject); + std::swap(mObject, other.mObject); + return *this; } virtual ~BindingPointer() @@ -74,11 +120,12 @@ class BindingPointer ASSERT(mObject == nullptr); } - virtual void set(ObjectType *newObject) + virtual void set(const Context *context, ObjectType *newObject) { // addRef first in case newObject == mObject and this is the last reference to it. - if (newObject != nullptr) reinterpret_cast(newObject)->addRef(); - if (mObject != nullptr) reinterpret_cast(mObject)->release(); + if (newObject != nullptr) reinterpret_cast(newObject)->addRef(); + if (mObject != nullptr) + reinterpret_cast(mObject)->release(context); mObject = newObject; } @@ -104,16 +151,16 @@ class OffsetBindingPointer : public BindingPointer public: OffsetBindingPointer() : mOffset(0), mSize(0) { } - void set(ObjectType *newObject) override + void set(const Context *context, ObjectType *newObject) override { - BindingPointer::set(newObject); + BindingPointer::set(context, newObject); mOffset = 0; mSize = 0; } - void set(ObjectType *newObject, GLintptr offset, GLsizeiptr size) + void set(const Context *context, ObjectType *newObject, GLintptr offset, GLsizeiptr size) { - BindingPointer::set(newObject); + BindingPointer::set(context, newObject); mOffset = offset; mSize = size; } @@ -135,5 +182,6 @@ class OffsetBindingPointer : public BindingPointer GLintptr mOffset; GLsizeiptr mSize; }; +} // namespace gl #endif // LIBANGLE_REFCOUNTOBJECT_H_ diff --git a/src/3rdparty/angle/src/libANGLE/Renderbuffer.cpp b/src/3rdparty/angle/src/libANGLE/Renderbuffer.cpp index 161fbea797..8310f1abda 100644 --- a/src/3rdparty/angle/src/libANGLE/Renderbuffer.cpp +++ b/src/3rdparty/angle/src/libANGLE/Renderbuffer.cpp @@ -25,11 +25,24 @@ Renderbuffer::Renderbuffer(rx::RenderbufferImpl *impl, GLuint id) mLabel(), mWidth(0), mHeight(0), - mInternalFormat(GL_RGBA4), - mSamples(0) + mFormat(GL_RGBA4), + mSamples(0), + mInitState(InitState::MayNeedInit) { } +Error Renderbuffer::onDestroy(const Context *context) +{ + ANGLE_TRY(orphanImages(context)); + + if (mRenderbuffer) + { + ANGLE_TRY(mRenderbuffer->onDestroy(context)); + } + + return NoError(); +} + Renderbuffer::~Renderbuffer() { SafeDelete(mRenderbuffer); @@ -45,73 +58,73 @@ const std::string &Renderbuffer::getLabel() const return mLabel; } -Error Renderbuffer::setStorage(GLenum internalformat, size_t width, size_t height) +Error Renderbuffer::setStorage(const Context *context, + GLenum internalformat, + size_t width, + size_t height) { - orphanImages(); + ANGLE_TRY(orphanImages(context)); - Error error = mRenderbuffer->setStorage(internalformat, width, height); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mRenderbuffer->setStorage(context, internalformat, width, height)); mWidth = static_cast(width); mHeight = static_cast(height); - mInternalFormat = internalformat; + mFormat = Format(internalformat); mSamples = 0; - return Error(GL_NO_ERROR); + mInitState = InitState::MayNeedInit; + mDirtyChannel.signal(mInitState); + + return NoError(); } -Error Renderbuffer::setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height) +Error Renderbuffer::setStorageMultisample(const Context *context, + size_t samples, + GLenum internalformat, + size_t width, + size_t height) { - orphanImages(); + ANGLE_TRY(orphanImages(context)); - Error error = mRenderbuffer->setStorageMultisample(samples, internalformat, width, height); - if (error.isError()) - { - return error; - } + ANGLE_TRY( + mRenderbuffer->setStorageMultisample(context, samples, internalformat, width, height)); mWidth = static_cast(width); mHeight = static_cast(height); - mInternalFormat = internalformat; + mFormat = Format(internalformat); mSamples = static_cast(samples); - return Error(GL_NO_ERROR); + mInitState = InitState::MayNeedInit; + mDirtyChannel.signal(mInitState); + + return NoError(); } -Error Renderbuffer::setStorageEGLImageTarget(egl::Image *image) +Error Renderbuffer::setStorageEGLImageTarget(const Context *context, egl::Image *image) { - orphanImages(); + ANGLE_TRY(orphanImages(context)); - Error error = mRenderbuffer->setStorageEGLImageTarget(image); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mRenderbuffer->setStorageEGLImageTarget(context, image)); - setTargetImage(image); + setTargetImage(context, image); mWidth = static_cast(image->getWidth()); mHeight = static_cast(image->getHeight()); - mInternalFormat = image->getInternalFormat(); + mFormat = Format(image->getFormat()); mSamples = 0; - return Error(GL_NO_ERROR); + mInitState = image->sourceInitState(); + mDirtyChannel.signal(mInitState); + + return NoError(); } -rx::RenderbufferImpl *Renderbuffer::getImplementation() +rx::RenderbufferImpl *Renderbuffer::getImplementation() const { ASSERT(mRenderbuffer); return mRenderbuffer; } -const rx::RenderbufferImpl *Renderbuffer::getImplementation() const -{ - return mRenderbuffer; -} - GLsizei Renderbuffer::getWidth() const { return mWidth; @@ -122,9 +135,9 @@ GLsizei Renderbuffer::getHeight() const return mHeight; } -GLenum Renderbuffer::getInternalFormat() const +const Format &Renderbuffer::getFormat() const { - return mInternalFormat; + return mFormat; } GLsizei Renderbuffer::getSamples() const @@ -134,42 +147,42 @@ GLsizei Renderbuffer::getSamples() const GLuint Renderbuffer::getRedSize() const { - return GetInternalFormatInfo(mInternalFormat).redBits; + return mFormat.info->redBits; } GLuint Renderbuffer::getGreenSize() const { - return GetInternalFormatInfo(mInternalFormat).greenBits; + return mFormat.info->greenBits; } GLuint Renderbuffer::getBlueSize() const { - return GetInternalFormatInfo(mInternalFormat).blueBits; + return mFormat.info->blueBits; } GLuint Renderbuffer::getAlphaSize() const { - return GetInternalFormatInfo(mInternalFormat).alphaBits; + return mFormat.info->alphaBits; } GLuint Renderbuffer::getDepthSize() const { - return GetInternalFormatInfo(mInternalFormat).depthBits; + return mFormat.info->depthBits; } GLuint Renderbuffer::getStencilSize() const { - return GetInternalFormatInfo(mInternalFormat).stencilBits; + return mFormat.info->stencilBits; } -void Renderbuffer::onAttach() +void Renderbuffer::onAttach(const Context *context) { addRef(); } -void Renderbuffer::onDetach() +void Renderbuffer::onDetach(const Context *context) { - release(); + release(context); } GLuint Renderbuffer::getId() const @@ -177,8 +190,46 @@ GLuint Renderbuffer::getId() const return id(); } -Extents Renderbuffer::getAttachmentSize(const FramebufferAttachment::Target & /*target*/) const +Extents Renderbuffer::getAttachmentSize(const gl::ImageIndex & /*imageIndex*/) const { return Extents(mWidth, mHeight, 1); } + +const Format &Renderbuffer::getAttachmentFormat(GLenum /*binding*/, + const ImageIndex & /*imageIndex*/) const +{ + return getFormat(); } +GLsizei Renderbuffer::getAttachmentSamples(const ImageIndex & /*imageIndex*/) const +{ + return getSamples(); +} + +InitState Renderbuffer::initState(const gl::ImageIndex & /*imageIndex*/) const +{ + if (isEGLImageTarget()) + { + return sourceEGLImageInitState(); + } + + return mInitState; +} + +void Renderbuffer::setInitState(const gl::ImageIndex & /*imageIndex*/, InitState initState) +{ + if (isEGLImageTarget()) + { + setSourceEGLImageInitState(initState); + } + else + { + mInitState = initState; + } +} + +rx::FramebufferAttachmentObjectImpl *Renderbuffer::getAttachmentImpl() const +{ + return mRenderbuffer; +} + +} // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/Renderbuffer.h b/src/3rdparty/angle/src/libANGLE/Renderbuffer.h index 04af03e879..def18e6ff7 100644 --- a/src/3rdparty/angle/src/libANGLE/Renderbuffer.h +++ b/src/3rdparty/angle/src/libANGLE/Renderbuffer.h @@ -17,6 +17,7 @@ #include "libANGLE/Error.h" #include "libANGLE/FramebufferAttachment.h" #include "libANGLE/Image.h" +#include "libANGLE/formatutils.h" #include "libANGLE/renderer/RenderbufferImpl.h" namespace gl @@ -27,26 +28,30 @@ namespace gl // attachment point. class Renderbuffer final : public egl::ImageSibling, - public gl::FramebufferAttachmentObject, public LabeledObject { public: Renderbuffer(rx::RenderbufferImpl *impl, GLuint id); - virtual ~Renderbuffer(); + ~Renderbuffer() override; + + Error onDestroy(const Context *context) override; void setLabel(const std::string &label) override; const std::string &getLabel() const override; - Error setStorage(GLenum internalformat, size_t width, size_t height); - Error setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height); - Error setStorageEGLImageTarget(egl::Image *imageTarget); + Error setStorage(const Context *context, GLenum internalformat, size_t width, size_t height); + Error setStorageMultisample(const Context *context, + size_t samples, + GLenum internalformat, + size_t width, + size_t height); + Error setStorageEGLImageTarget(const Context *context, egl::Image *imageTarget); - rx::RenderbufferImpl *getImplementation(); - const rx::RenderbufferImpl *getImplementation() const; + rx::RenderbufferImpl *getImplementation() const; GLsizei getWidth() const; GLsizei getHeight() const; - GLenum getInternalFormat() const; + const Format &getFormat() const; GLsizei getSamples() const; GLuint getRedSize() const; GLuint getGreenSize() const; @@ -56,16 +61,19 @@ class Renderbuffer final : public egl::ImageSibling, GLuint getStencilSize() const; // FramebufferAttachmentObject Impl - Extents getAttachmentSize(const FramebufferAttachment::Target &target) const override; - GLenum getAttachmentInternalFormat(const FramebufferAttachment::Target &/*target*/) const override { return getInternalFormat(); } - GLsizei getAttachmentSamples(const FramebufferAttachment::Target &/*target*/) const override { return getSamples(); } + Extents getAttachmentSize(const ImageIndex &imageIndex) const override; + const Format &getAttachmentFormat(GLenum binding, const ImageIndex &imageIndex) const override; + GLsizei getAttachmentSamples(const ImageIndex &imageIndex) const override; - void onAttach() override; - void onDetach() override; + void onAttach(const Context *context) override; + void onDetach(const Context *context) override; GLuint getId() const override; + InitState initState(const ImageIndex &imageIndex) const override; + void setInitState(const ImageIndex &imageIndex, InitState initState) override; + private: - rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override { return mRenderbuffer; } + rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override; rx::RenderbufferImpl *mRenderbuffer; @@ -73,10 +81,13 @@ class Renderbuffer final : public egl::ImageSibling, GLsizei mWidth; GLsizei mHeight; - GLenum mInternalFormat; + Format mFormat; GLsizei mSamples; + + // For robust resource init. + InitState mInitState; }; -} +} // namespace gl #endif // LIBANGLE_RENDERBUFFER_H_ diff --git a/src/3rdparty/angle/src/libANGLE/ResourceManager.cpp b/src/3rdparty/angle/src/libANGLE/ResourceManager.cpp index dc9dad1e9f..79eb7e5f42 100644 --- a/src/3rdparty/angle/src/libANGLE/ResourceManager.cpp +++ b/src/3rdparty/angle/src/libANGLE/ResourceManager.cpp @@ -1,456 +1,483 @@ // -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2016 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// ResourceManager.cpp: Implements the gl::ResourceManager class, which tracks and -// retrieves objects which may be shared by multiple Contexts. +// ResourceManager.cpp: Implements the the ResourceManager classes, which handle allocation and +// lifetime of GL objects. #include "libANGLE/ResourceManager.h" #include "libANGLE/Buffer.h" +#include "libANGLE/Fence.h" +#include "libANGLE/Path.h" #include "libANGLE/Program.h" +#include "libANGLE/ProgramPipeline.h" #include "libANGLE/Renderbuffer.h" +#include "libANGLE/Sampler.h" #include "libANGLE/Shader.h" #include "libANGLE/Texture.h" -#include "libANGLE/Sampler.h" -#include "libANGLE/Fence.h" -#include "libANGLE/renderer/Renderer.h" +#include "libANGLE/renderer/GLImplFactory.h" namespace gl { -ResourceManager::ResourceManager(rx::ImplFactory *factory) - : mFactory(factory), - mRefCount(1) + +namespace +{ + +template +GLuint AllocateEmptyObject(HandleAllocator *handleAllocator, ResourceMap *objectMap) +{ + GLuint handle = handleAllocator->allocate(); + objectMap->assign(handle, nullptr); + return handle; +} + +} // anonymous namespace + +template +ResourceManagerBase::ResourceManagerBase() : mRefCount(1) { } -ResourceManager::~ResourceManager() -{ - while (!mBufferMap.empty()) - { - deleteBuffer(mBufferMap.begin()->first); - } - - while (!mProgramMap.empty()) - { - deleteProgram(mProgramMap.begin()->first); - } - - while (!mShaderMap.empty()) - { - deleteShader(mShaderMap.begin()->first); - } - - while (!mRenderbufferMap.empty()) - { - deleteRenderbuffer(mRenderbufferMap.begin()->first); - } - - while (!mTextureMap.empty()) - { - deleteTexture(mTextureMap.begin()->first); - } - - while (!mSamplerMap.empty()) - { - deleteSampler(mSamplerMap.begin()->first); - } - - while (!mFenceSyncMap.empty()) - { - deleteFenceSync(mFenceSyncMap.begin()->first); - } -} - -void ResourceManager::addRef() +template +void ResourceManagerBase::addRef() { mRefCount++; } -void ResourceManager::release() +template +void ResourceManagerBase::release(const Context *context) { if (--mRefCount == 0) { + reset(context); delete this; } } -// Returns an unused buffer name -GLuint ResourceManager::createBuffer() +template +TypedResourceManager::~TypedResourceManager() { - GLuint handle = mBufferHandleAllocator.allocate(); + ASSERT(mObjectMap.empty()); +} - mBufferMap[handle] = NULL; +template +void TypedResourceManager::reset(const Context *context) +{ + this->mHandleAllocator.reset(); + for (const auto &resource : mObjectMap) + { + if (resource.second) + { + ImplT::DeleteObject(context, resource.second); + } + } + mObjectMap.clear(); +} +template +void TypedResourceManager::deleteObject( + const Context *context, + GLuint handle) +{ + ResourceType *resource = nullptr; + if (!mObjectMap.erase(handle, &resource)) + { + return; + } + + // Requires an explicit this-> because of C++ template rules. + this->mHandleAllocator.release(handle); + + if (resource) + { + ImplT::DeleteObject(context, resource); + } +} + +template class ResourceManagerBase; +template class ResourceManagerBase; +template class TypedResourceManager; +template class TypedResourceManager; +template class TypedResourceManager; +template class TypedResourceManager; +template class TypedResourceManager; +template class TypedResourceManager; +template class TypedResourceManager; + +// BufferManager Implementation. + +// static +Buffer *BufferManager::AllocateNewObject(rx::GLImplFactory *factory, GLuint handle) +{ + Buffer *buffer = new Buffer(factory, handle); + buffer->addRef(); + return buffer; +} + +// static +void BufferManager::DeleteObject(const Context *context, Buffer *buffer) +{ + buffer->release(context); +} + +GLuint BufferManager::createBuffer() +{ + return AllocateEmptyObject(&mHandleAllocator, &mObjectMap); +} + +Buffer *BufferManager::getBuffer(GLuint handle) const +{ + return mObjectMap.query(handle); +} + +// ShaderProgramManager Implementation. + +ShaderProgramManager::ShaderProgramManager() +{ +} + +ShaderProgramManager::~ShaderProgramManager() +{ + ASSERT(mPrograms.empty()); + ASSERT(mShaders.empty()); +} + +void ShaderProgramManager::reset(const Context *context) +{ + while (!mPrograms.empty()) + { + deleteProgram(context, mPrograms.begin()->first); + } + mPrograms.clear(); + while (!mShaders.empty()) + { + deleteShader(context, mShaders.begin()->first); + } + mShaders.clear(); +} + +GLuint ShaderProgramManager::createShader(rx::GLImplFactory *factory, + const gl::Limitations &rendererLimitations, + GLenum type) +{ + ASSERT(type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER || type == GL_COMPUTE_SHADER || + type == GL_GEOMETRY_SHADER_EXT); + GLuint handle = mHandleAllocator.allocate(); + mShaders.assign(handle, new Shader(this, factory, rendererLimitations, type, handle)); return handle; } -// Returns an unused shader/program name -GLuint ResourceManager::createShader(const gl::Limitations &rendererLimitations, GLenum type) +void ShaderProgramManager::deleteShader(const Context *context, GLuint shader) { - GLuint handle = mProgramShaderHandleAllocator.allocate(); + deleteObject(context, &mShaders, shader); +} - if (type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER) - { - mShaderMap[handle] = new Shader(this, mFactory, rendererLimitations, type, handle); - } - else UNREACHABLE(); +Shader *ShaderProgramManager::getShader(GLuint handle) const +{ + return mShaders.query(handle); +} +GLuint ShaderProgramManager::createProgram(rx::GLImplFactory *factory) +{ + GLuint handle = mHandleAllocator.allocate(); + mPrograms.assign(handle, new Program(factory, this, handle)); return handle; } -// Returns an unused program/shader name -GLuint ResourceManager::createProgram() +void ShaderProgramManager::deleteProgram(const gl::Context *context, GLuint program) { - GLuint handle = mProgramShaderHandleAllocator.allocate(); + deleteObject(context, &mPrograms, program); +} - mProgramMap[handle] = new Program(mFactory, this, handle); +Program *ShaderProgramManager::getProgram(GLuint handle) const +{ + return mPrograms.query(handle); +} +template +void ShaderProgramManager::deleteObject(const Context *context, + ResourceMap *objectMap, + GLuint id) +{ + ObjectType *object = objectMap->query(id); + if (!object) + { + return; + } + + if (object->getRefCount() == 0) + { + mHandleAllocator.release(id); + object->onDestroy(context); + objectMap->erase(id, &object); + } + else + { + object->flagForDeletion(); + } +} + +// TextureManager Implementation. + +// static +Texture *TextureManager::AllocateNewObject(rx::GLImplFactory *factory, GLuint handle, GLenum target) +{ + Texture *texture = new Texture(factory, handle, target); + texture->addRef(); + return texture; +} + +// static +void TextureManager::DeleteObject(const Context *context, Texture *texture) +{ + texture->release(context); +} + +GLuint TextureManager::createTexture() +{ + return AllocateEmptyObject(&mHandleAllocator, &mObjectMap); +} + +Texture *TextureManager::getTexture(GLuint handle) const +{ + ASSERT(mObjectMap.query(0) == nullptr); + return mObjectMap.query(handle); +} + +void TextureManager::signalAllTexturesDirty() const +{ + for (const auto &texture : mObjectMap) + { + if (texture.second) + { + // We don't know if the Texture needs init, but that's ok, since it will only force + // a re-check, and will not initialize the pixels if it's not needed. + texture.second->signalDirty(InitState::MayNeedInit); + } + } +} + +// RenderbufferManager Implementation. + +// static +Renderbuffer *RenderbufferManager::AllocateNewObject(rx::GLImplFactory *factory, GLuint handle) +{ + Renderbuffer *renderbuffer = new Renderbuffer(factory->createRenderbuffer(), handle); + renderbuffer->addRef(); + return renderbuffer; +} + +// static +void RenderbufferManager::DeleteObject(const Context *context, Renderbuffer *renderbuffer) +{ + renderbuffer->release(context); +} + +GLuint RenderbufferManager::createRenderbuffer() +{ + return AllocateEmptyObject(&mHandleAllocator, &mObjectMap); +} + +Renderbuffer *RenderbufferManager::getRenderbuffer(GLuint handle) const +{ + return mObjectMap.query(handle); +} + +// SamplerManager Implementation. + +// static +Sampler *SamplerManager::AllocateNewObject(rx::GLImplFactory *factory, GLuint handle) +{ + Sampler *sampler = new Sampler(factory, handle); + sampler->addRef(); + return sampler; +} + +// static +void SamplerManager::DeleteObject(const Context *context, Sampler *sampler) +{ + sampler->release(context); +} + +GLuint SamplerManager::createSampler() +{ + return AllocateEmptyObject(&mHandleAllocator, &mObjectMap); +} + +Sampler *SamplerManager::getSampler(GLuint handle) const +{ + return mObjectMap.query(handle); +} + +bool SamplerManager::isSampler(GLuint sampler) const +{ + return mObjectMap.contains(sampler); +} + +// SyncManager Implementation. + +// static +void SyncManager::DeleteObject(const Context *context, Sync *sync) +{ + sync->release(context); +} + +GLuint SyncManager::createSync(rx::GLImplFactory *factory) +{ + GLuint handle = mHandleAllocator.allocate(); + Sync *sync = new Sync(factory->createSync(), handle); + sync->addRef(); + mObjectMap.assign(handle, sync); return handle; } -// Returns an unused texture name -GLuint ResourceManager::createTexture() +Sync *SyncManager::getSync(GLuint handle) const { - GLuint handle = mTextureHandleAllocator.allocate(); - - mTextureMap[handle] = NULL; - - return handle; + return mObjectMap.query(handle); } -// Returns an unused renderbuffer name -GLuint ResourceManager::createRenderbuffer() +// PathManager Implementation. + +PathManager::PathManager() { - GLuint handle = mRenderbufferHandleAllocator.allocate(); - - mRenderbufferMap[handle] = NULL; - - return handle; } -// Returns an unused sampler name -GLuint ResourceManager::createSampler() +ErrorOrResult PathManager::createPaths(rx::GLImplFactory *factory, GLsizei range) { - GLuint handle = mSamplerHandleAllocator.allocate(); + // Allocate client side handles. + const GLuint client = mHandleAllocator.allocateRange(static_cast(range)); + if (client == HandleRangeAllocator::kInvalidHandle) + return OutOfMemory() << "Failed to allocate path handle range."; - mSamplerMap[handle] = NULL; - - return handle; -} - -// Returns the next unused fence name, and allocates the fence -GLuint ResourceManager::createFenceSync() -{ - GLuint handle = mFenceSyncHandleAllocator.allocate(); - - FenceSync *fenceSync = new FenceSync(mFactory->createFenceSync(), handle); - fenceSync->addRef(); - mFenceSyncMap[handle] = fenceSync; - - return handle; -} - -void ResourceManager::deleteBuffer(GLuint buffer) -{ - BufferMap::iterator bufferObject = mBufferMap.find(buffer); - - if (bufferObject != mBufferMap.end()) + const auto &paths = factory->createPaths(range); + if (paths.empty()) { - mBufferHandleAllocator.release(bufferObject->first); - if (bufferObject->second) bufferObject->second->release(); - mBufferMap.erase(bufferObject); + mHandleAllocator.releaseRange(client, range); + return OutOfMemory() << "Failed to allocate path objects."; + } + + for (GLsizei i = 0; i < range; ++i) + { + rx::PathImpl *impl = paths[static_cast(i)]; + const auto id = client + i; + mPaths.assign(id, new Path(impl)); + } + return client; +} + +void PathManager::deletePaths(GLuint first, GLsizei range) +{ + for (GLsizei i = 0; i < range; ++i) + { + const auto id = first + i; + Path *p = nullptr; + if (!mPaths.erase(id, &p)) + continue; + delete p; + } + mHandleAllocator.releaseRange(first, static_cast(range)); +} + +Path *PathManager::getPath(GLuint handle) const +{ + return mPaths.query(handle); +} + +bool PathManager::hasPath(GLuint handle) const +{ + return mHandleAllocator.isUsed(handle); +} + +PathManager::~PathManager() +{ + ASSERT(mPaths.empty()); +} + +void PathManager::reset(const Context *context) +{ + for (auto path : mPaths) + { + SafeDelete(path.second); + } + mPaths.clear(); +} + +// FramebufferManager Implementation. + +// static +Framebuffer *FramebufferManager::AllocateNewObject(rx::GLImplFactory *factory, + GLuint handle, + const Caps &caps) +{ + return new Framebuffer(caps, factory, handle); +} + +// static +void FramebufferManager::DeleteObject(const Context *context, Framebuffer *framebuffer) +{ + // Default framebuffer are owned by their respective Surface + if (framebuffer->id() != 0) + { + framebuffer->onDestroy(context); + delete framebuffer; } } -void ResourceManager::deleteShader(GLuint shader) +GLuint FramebufferManager::createFramebuffer() { - ShaderMap::iterator shaderObject = mShaderMap.find(shader); + return AllocateEmptyObject(&mHandleAllocator, &mObjectMap); +} - if (shaderObject != mShaderMap.end()) +Framebuffer *FramebufferManager::getFramebuffer(GLuint handle) const +{ + return mObjectMap.query(handle); +} + +void FramebufferManager::setDefaultFramebuffer(Framebuffer *framebuffer) +{ + ASSERT(framebuffer == nullptr || framebuffer->id() == 0); + mObjectMap.assign(0, framebuffer); +} + +void FramebufferManager::invalidateFramebufferComplenessCache() const +{ + for (const auto &framebuffer : mObjectMap) { - if (shaderObject->second->getRefCount() == 0) + if (framebuffer.second) { - mProgramShaderHandleAllocator.release(shaderObject->first); - delete shaderObject->second; - mShaderMap.erase(shaderObject); - } - else - { - shaderObject->second->flagForDeletion(); + framebuffer.second->invalidateCompletenessCache(); } } } -void ResourceManager::deleteProgram(GLuint program) +// ProgramPipelineManager Implementation. + +// static +ProgramPipeline *ProgramPipelineManager::AllocateNewObject(rx::GLImplFactory *factory, + GLuint handle) { - ProgramMap::iterator programObject = mProgramMap.find(program); - - if (programObject != mProgramMap.end()) - { - if (programObject->second->getRefCount() == 0) - { - mProgramShaderHandleAllocator.release(programObject->first); - delete programObject->second; - mProgramMap.erase(programObject); - } - else - { - programObject->second->flagForDeletion(); - } - } + ProgramPipeline *pipeline = new ProgramPipeline(factory, handle); + pipeline->addRef(); + return pipeline; } -void ResourceManager::deleteTexture(GLuint texture) +// static +void ProgramPipelineManager::DeleteObject(const Context *context, ProgramPipeline *pipeline) { - TextureMap::iterator textureObject = mTextureMap.find(texture); - - if (textureObject != mTextureMap.end()) - { - mTextureHandleAllocator.release(textureObject->first); - if (textureObject->second) textureObject->second->release(); - mTextureMap.erase(textureObject); - } + pipeline->release(context); } -void ResourceManager::deleteRenderbuffer(GLuint renderbuffer) +GLuint ProgramPipelineManager::createProgramPipeline() { - RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer); - - if (renderbufferObject != mRenderbufferMap.end()) - { - mRenderbufferHandleAllocator.release(renderbufferObject->first); - if (renderbufferObject->second) renderbufferObject->second->release(); - mRenderbufferMap.erase(renderbufferObject); - } + return AllocateEmptyObject(&mHandleAllocator, &mObjectMap); } -void ResourceManager::deleteSampler(GLuint sampler) +ProgramPipeline *ProgramPipelineManager::getProgramPipeline(GLuint handle) const { - auto samplerObject = mSamplerMap.find(sampler); - - if (samplerObject != mSamplerMap.end()) - { - mSamplerHandleAllocator.release(samplerObject->first); - if (samplerObject->second) samplerObject->second->release(); - mSamplerMap.erase(samplerObject); - } + return mObjectMap.query(handle); } -void ResourceManager::deleteFenceSync(GLuint fenceSync) -{ - auto fenceObjectIt = mFenceSyncMap.find(fenceSync); - - if (fenceObjectIt != mFenceSyncMap.end()) - { - mFenceSyncHandleAllocator.release(fenceObjectIt->first); - if (fenceObjectIt->second) fenceObjectIt->second->release(); - mFenceSyncMap.erase(fenceObjectIt); - } -} - -Buffer *ResourceManager::getBuffer(unsigned int handle) -{ - BufferMap::iterator buffer = mBufferMap.find(handle); - - if (buffer == mBufferMap.end()) - { - return NULL; - } - else - { - return buffer->second; - } -} - -Shader *ResourceManager::getShader(unsigned int handle) -{ - ShaderMap::iterator shader = mShaderMap.find(handle); - - if (shader == mShaderMap.end()) - { - return NULL; - } - else - { - return shader->second; - } -} - -Texture *ResourceManager::getTexture(unsigned int handle) -{ - if (handle == 0) return NULL; - - TextureMap::iterator texture = mTextureMap.find(handle); - - if (texture == mTextureMap.end()) - { - return NULL; - } - else - { - return texture->second; - } -} - -Program *ResourceManager::getProgram(unsigned int handle) const -{ - ProgramMap::const_iterator program = mProgramMap.find(handle); - - if (program == mProgramMap.end()) - { - return NULL; - } - else - { - return program->second; - } -} - -Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle) -{ - RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle); - - if (renderbuffer == mRenderbufferMap.end()) - { - return NULL; - } - else - { - return renderbuffer->second; - } -} - -Sampler *ResourceManager::getSampler(unsigned int handle) -{ - auto sampler = mSamplerMap.find(handle); - - if (sampler == mSamplerMap.end()) - { - return NULL; - } - else - { - return sampler->second; - } -} - -FenceSync *ResourceManager::getFenceSync(unsigned int handle) -{ - auto fenceObjectIt = mFenceSyncMap.find(handle); - - if (fenceObjectIt == mFenceSyncMap.end()) - { - return NULL; - } - else - { - return fenceObjectIt->second; - } -} - -void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer) -{ - mRenderbufferMap[handle] = buffer; -} - -void ResourceManager::checkBufferAllocation(GLuint handle) -{ - if (handle != 0) - { - auto bufferMapIt = mBufferMap.find(handle); - bool handleAllocated = (bufferMapIt != mBufferMap.end()); - - if (handleAllocated && bufferMapIt->second != nullptr) - { - return; - } - - Buffer *buffer = new Buffer(mFactory->createBuffer(), handle); - buffer->addRef(); - - if (handleAllocated) - { - bufferMapIt->second = buffer; - } - else - { - mBufferHandleAllocator.reserve(handle); - mBufferMap[handle] = buffer; - } - } -} - -void ResourceManager::checkTextureAllocation(GLuint handle, GLenum type) -{ - if (handle != 0) - { - auto textureMapIt = mTextureMap.find(handle); - bool handleAllocated = (textureMapIt != mTextureMap.end()); - - if (handleAllocated && textureMapIt->second != nullptr) - { - return; - } - - Texture *texture = new Texture(mFactory->createTexture(type), handle, type); - texture->addRef(); - - if (handleAllocated) - { - textureMapIt->second = texture; - } - else - { - mTextureHandleAllocator.reserve(handle); - mTextureMap[handle] = texture; - } - } -} - -void ResourceManager::checkRenderbufferAllocation(GLuint handle) -{ - if (handle != 0) - { - auto renderbufferMapIt = mRenderbufferMap.find(handle); - bool handleAllocated = (renderbufferMapIt != mRenderbufferMap.end()); - - if (handleAllocated && renderbufferMapIt->second != nullptr) - { - return; - } - - Renderbuffer *renderbuffer = new Renderbuffer(mFactory->createRenderbuffer(), handle); - renderbuffer->addRef(); - - if (handleAllocated) - { - renderbufferMapIt->second = renderbuffer; - } - else - { - mRenderbufferHandleAllocator.reserve(handle); - mRenderbufferMap[handle] = renderbuffer; - } - } -} - -void ResourceManager::checkSamplerAllocation(GLuint sampler) -{ - if (sampler != 0 && !getSampler(sampler)) - { - Sampler *samplerObject = new Sampler(mFactory, sampler); - mSamplerMap[sampler] = samplerObject; - samplerObject->addRef(); - // Samplers cannot be created via Bind - } -} - -bool ResourceManager::isSampler(GLuint sampler) -{ - return mSamplerMap.find(sampler) != mSamplerMap.end(); -} - -} +} // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/ResourceManager.h b/src/3rdparty/angle/src/libANGLE/ResourceManager.h index 2073e9d728..2dfeff5234 100644 --- a/src/3rdparty/angle/src/libANGLE/ResourceManager.h +++ b/src/3rdparty/angle/src/libANGLE/ResourceManager.h @@ -1,115 +1,289 @@ // -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2016 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// ResourceManager.h : Defines the ResourceManager class, which tracks objects -// shared by multiple GL contexts. +// ResourceManager.h : Defines the ResourceManager classes, which handle allocation and lifetime of +// GL objects. #ifndef LIBANGLE_RESOURCEMANAGER_H_ #define LIBANGLE_RESOURCEMANAGER_H_ #include "angle_gl.h" #include "common/angleutils.h" -#include "libANGLE/angletypes.h" +#include "libANGLE/Error.h" #include "libANGLE/HandleAllocator.h" - -#include +#include "libANGLE/HandleRangeAllocator.h" +#include "libANGLE/ResourceMap.h" namespace rx { -class ImplFactory; +class GLImplFactory; } namespace gl { class Buffer; -struct Data; -class FenceSync; +struct Caps; +class Context; +class Sync; +class Framebuffer; struct Limitations; +class Path; class Program; +class ProgramPipeline; class Renderbuffer; class Sampler; class Shader; class Texture; -class ResourceManager : angle::NonCopyable +template +class ResourceManagerBase : angle::NonCopyable { public: - explicit ResourceManager(rx::ImplFactory *factory); - ~ResourceManager(); + ResourceManagerBase(); void addRef(); - void release(); + void release(const Context *context); - GLuint createBuffer(); - GLuint createShader(const gl::Limitations &rendererLimitations, GLenum type); - GLuint createProgram(); - GLuint createTexture(); - GLuint createRenderbuffer(); - GLuint createSampler(); - GLuint createFenceSync(); + protected: + virtual void reset(const Context *context) = 0; + virtual ~ResourceManagerBase() {} - void deleteBuffer(GLuint buffer); - void deleteShader(GLuint shader); - void deleteProgram(GLuint program); - void deleteTexture(GLuint texture); - void deleteRenderbuffer(GLuint renderbuffer); - void deleteSampler(GLuint sampler); - void deleteFenceSync(GLuint fenceSync); - - Buffer *getBuffer(GLuint handle); - Shader *getShader(GLuint handle); - Program *getProgram(GLuint handle) const; - Texture *getTexture(GLuint handle); - Renderbuffer *getRenderbuffer(GLuint handle); - Sampler *getSampler(GLuint handle); - FenceSync *getFenceSync(GLuint handle); - - void setRenderbuffer(GLuint handle, Renderbuffer *renderbuffer); - - void checkBufferAllocation(GLuint handle); - void checkTextureAllocation(GLuint handle, GLenum type); - void checkRenderbufferAllocation(GLuint handle); - void checkSamplerAllocation(GLuint sampler); - - bool isSampler(GLuint sampler); + HandleAllocatorType mHandleAllocator; private: - void createTextureInternal(GLuint handle); - - rx::ImplFactory *mFactory; - std::size_t mRefCount; - - typedef std::map BufferMap; - BufferMap mBufferMap; - HandleAllocator mBufferHandleAllocator; - - typedef std::map ShaderMap; - ShaderMap mShaderMap; - - typedef std::map ProgramMap; - ProgramMap mProgramMap; - HandleAllocator mProgramShaderHandleAllocator; - - typedef std::map TextureMap; - TextureMap mTextureMap; - HandleAllocator mTextureHandleAllocator; - - typedef std::map RenderbufferMap; - RenderbufferMap mRenderbufferMap; - HandleAllocator mRenderbufferHandleAllocator; - - typedef std::map SamplerMap; - SamplerMap mSamplerMap; - HandleAllocator mSamplerHandleAllocator; - - typedef std::map FenceMap; - FenceMap mFenceSyncMap; - HandleAllocator mFenceSyncHandleAllocator; + size_t mRefCount; }; -} +template +class TypedResourceManager : public ResourceManagerBase +{ + public: + TypedResourceManager() {} + + void deleteObject(const Context *context, GLuint handle); + bool isHandleGenerated(GLuint handle) const + { + // Zero is always assumed to have been generated implicitly. + return handle == 0 || mObjectMap.contains(handle); + } + + protected: + ~TypedResourceManager() override; + + // Inlined in the header for performance. + template + ResourceType *checkObjectAllocation(rx::GLImplFactory *factory, GLuint handle, ArgTypes... args) + { + ResourceType *value = mObjectMap.query(handle); + if (value) + { + return value; + } + + if (handle == 0) + { + return nullptr; + } + + ResourceType *object = ImplT::AllocateNewObject(factory, handle, args...); + + if (!mObjectMap.contains(handle)) + { + this->mHandleAllocator.reserve(handle); + } + mObjectMap.assign(handle, object); + + return object; + } + + void reset(const Context *context) override; + + ResourceMap mObjectMap; +}; + +class BufferManager : public TypedResourceManager +{ + public: + GLuint createBuffer(); + Buffer *getBuffer(GLuint handle) const; + + Buffer *checkBufferAllocation(rx::GLImplFactory *factory, GLuint handle) + { + return checkObjectAllocation(factory, handle); + } + + // TODO(jmadill): Investigate design which doesn't expose these methods publicly. + static Buffer *AllocateNewObject(rx::GLImplFactory *factory, GLuint handle); + static void DeleteObject(const Context *context, Buffer *buffer); + + protected: + ~BufferManager() override {} +}; + +class ShaderProgramManager : public ResourceManagerBase +{ + public: + ShaderProgramManager(); + + GLuint createShader(rx::GLImplFactory *factory, + const Limitations &rendererLimitations, + GLenum type); + void deleteShader(const Context *context, GLuint shader); + Shader *getShader(GLuint handle) const; + + GLuint createProgram(rx::GLImplFactory *factory); + void deleteProgram(const Context *context, GLuint program); + Program *getProgram(GLuint handle) const; + + protected: + ~ShaderProgramManager() override; + + private: + template + void deleteObject(const Context *context, ResourceMap *objectMap, GLuint id); + + void reset(const Context *context) override; + + ResourceMap mShaders; + ResourceMap mPrograms; +}; + +class TextureManager : public TypedResourceManager +{ + public: + GLuint createTexture(); + Texture *getTexture(GLuint handle) const; + + void signalAllTexturesDirty() const; + + Texture *checkTextureAllocation(rx::GLImplFactory *factory, GLuint handle, GLenum target) + { + return checkObjectAllocation(factory, handle, target); + } + + static Texture *AllocateNewObject(rx::GLImplFactory *factory, GLuint handle, GLenum target); + static void DeleteObject(const Context *context, Texture *texture); + + protected: + ~TextureManager() override {} +}; + +class RenderbufferManager + : public TypedResourceManager +{ + public: + GLuint createRenderbuffer(); + Renderbuffer *getRenderbuffer(GLuint handle) const; + + Renderbuffer *checkRenderbufferAllocation(rx::GLImplFactory *factory, GLuint handle) + { + return checkObjectAllocation(factory, handle); + } + + static Renderbuffer *AllocateNewObject(rx::GLImplFactory *factory, GLuint handle); + static void DeleteObject(const Context *context, Renderbuffer *renderbuffer); + + protected: + ~RenderbufferManager() override {} +}; + +class SamplerManager : public TypedResourceManager +{ + public: + GLuint createSampler(); + Sampler *getSampler(GLuint handle) const; + bool isSampler(GLuint sampler) const; + + Sampler *checkSamplerAllocation(rx::GLImplFactory *factory, GLuint handle) + { + return checkObjectAllocation(factory, handle); + } + + static Sampler *AllocateNewObject(rx::GLImplFactory *factory, GLuint handle); + static void DeleteObject(const Context *context, Sampler *sampler); + + protected: + ~SamplerManager() override {} +}; + +class SyncManager : public TypedResourceManager +{ + public: + GLuint createSync(rx::GLImplFactory *factory); + Sync *getSync(GLuint handle) const; + + static void DeleteObject(const Context *context, Sync *sync); + + protected: + ~SyncManager() override {} +}; + +class PathManager : public ResourceManagerBase +{ + public: + PathManager(); + + ErrorOrResult createPaths(rx::GLImplFactory *factory, GLsizei range); + void deletePaths(GLuint first, GLsizei range); + Path *getPath(GLuint handle) const; + bool hasPath(GLuint handle) const; + + protected: + ~PathManager() override; + void reset(const Context *context) override; + + private: + ResourceMap mPaths; +}; + +class FramebufferManager + : public TypedResourceManager +{ + public: + GLuint createFramebuffer(); + Framebuffer *getFramebuffer(GLuint handle) const; + void setDefaultFramebuffer(Framebuffer *framebuffer); + + void invalidateFramebufferComplenessCache() const; + + Framebuffer *checkFramebufferAllocation(rx::GLImplFactory *factory, + const Caps &caps, + GLuint handle) + { + return checkObjectAllocation(factory, handle, caps); + } + + static Framebuffer *AllocateNewObject(rx::GLImplFactory *factory, + GLuint handle, + const Caps &caps); + static void DeleteObject(const Context *context, Framebuffer *framebuffer); + + protected: + ~FramebufferManager() override {} +}; + +class ProgramPipelineManager + : public TypedResourceManager +{ + public: + GLuint createProgramPipeline(); + ProgramPipeline *getProgramPipeline(GLuint handle) const; + + ProgramPipeline *checkProgramPipelineAllocation(rx::GLImplFactory *factory, GLuint handle) + { + return checkObjectAllocation(factory, handle); + } + + static ProgramPipeline *AllocateNewObject(rx::GLImplFactory *factory, GLuint handle); + static void DeleteObject(const Context *context, ProgramPipeline *pipeline); + + protected: + ~ProgramPipelineManager() override {} +}; + +} // namespace gl #endif // LIBANGLE_RESOURCEMANAGER_H_ diff --git a/src/3rdparty/angle/src/libANGLE/ResourceMap.h b/src/3rdparty/angle/src/libANGLE/ResourceMap.h new file mode 100644 index 0000000000..b00da68612 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/ResourceMap.h @@ -0,0 +1,305 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ResourceMap: +// An optimized resource map which packs the first set of allocated objects into a +// flat array, and then falls back to an unordered map for the higher handle values. +// + +#ifndef LIBANGLE_RESOURCE_MAP_H_ +#define LIBANGLE_RESOURCE_MAP_H_ + +#include "libANGLE/angletypes.h" + +namespace gl +{ + +template +class ResourceMap final : angle::NonCopyable +{ + public: + ResourceMap(); + ~ResourceMap(); + + ResourceType *query(GLuint handle) const; + + // Returns true if the handle was reserved. Not necessarily if the resource is created. + bool contains(GLuint handle) const; + + // Returns the element that was at this location. + bool erase(GLuint handle, ResourceType **resourceOut); + + void assign(GLuint handle, ResourceType *resource); + + // Clears the map. + void clear(); + + using IndexAndResource = std::pair; + using HashMap = std::unordered_map; + + class Iterator final + { + public: + bool operator==(const Iterator &other) const; + bool operator!=(const Iterator &other) const; + Iterator &operator++(); + const IndexAndResource *operator->() const; + const IndexAndResource &operator*() const; + + private: + friend class ResourceMap; + Iterator(const ResourceMap &origin, + GLuint flatIndex, + typename HashMap::const_iterator hashIndex); + void updateValue(); + + const ResourceMap &mOrigin; + GLuint mFlatIndex; + typename HashMap::const_iterator mHashIndex; + IndexAndResource mValue; + }; + + // null values represent reserved handles. + Iterator begin() const; + Iterator end() const; + Iterator find(GLuint handle) const; + + // Not a constant-time operation, should only be used for verification. + bool empty() const; + + private: + friend class Iterator; + + GLuint nextNonNullResource(size_t flatIndex) const; + + // constexpr methods cannot contain reinterpret_cast, so we need a static method. + static ResourceType *InvalidPointer(); + static constexpr intptr_t kInvalidPointer = static_cast(-1); + + // Start with 32 maximum elements in the map, which can grow. + static constexpr size_t kInitialFlatResourcesSize = 0x20; + + // Experimental testing suggests that 16k is a reasonable upper limit. + static constexpr size_t kFlatResourcesLimit = 0x4000; + + std::vector mFlatResources; + + // A map of GL objects indexed by object ID. + HashMap mHashedResources; +}; + +template +ResourceMap::ResourceMap() + : mFlatResources(kInitialFlatResourcesSize, InvalidPointer()), mHashedResources() +{ +} + +template +ResourceMap::~ResourceMap() +{ + ASSERT(empty()); +} + +template +ResourceType *ResourceMap::query(GLuint handle) const +{ + if (handle < mFlatResources.size()) + { + auto value = mFlatResources[handle]; + return (value == InvalidPointer() ? nullptr : value); + } + auto it = mHashedResources.find(handle); + return (it == mHashedResources.end() ? nullptr : it->second); +} + +template +bool ResourceMap::contains(GLuint handle) const +{ + if (handle < mFlatResources.size()) + { + return (mFlatResources[handle] != InvalidPointer()); + } + return (mHashedResources.find(handle) != mHashedResources.end()); +} + +template +bool ResourceMap::erase(GLuint handle, ResourceType **resourceOut) +{ + if (handle < mFlatResources.size()) + { + auto &value = mFlatResources[handle]; + if (value == InvalidPointer()) + { + return false; + } + *resourceOut = value; + value = InvalidPointer(); + } + else + { + auto it = mHashedResources.find(handle); + if (it == mHashedResources.end()) + { + return false; + } + *resourceOut = it->second; + mHashedResources.erase(it); + } + return true; +} + +template +void ResourceMap::assign(GLuint handle, ResourceType *resource) +{ + if (handle < kFlatResourcesLimit) + { + if (handle >= mFlatResources.size()) + { + // Use power-of-two. + size_t newSize = mFlatResources.size(); + while (newSize <= handle) + { + newSize *= 2; + } + mFlatResources.resize(newSize, nullptr); + } + ASSERT(mFlatResources.size() > handle); + mFlatResources[handle] = resource; + } + else + { + mHashedResources[handle] = resource; + } +} + +template +typename ResourceMap::Iterator ResourceMap::begin() const +{ + return Iterator(*this, nextNonNullResource(0), mHashedResources.begin()); +} + +template +typename ResourceMap::Iterator ResourceMap::end() const +{ + return Iterator(*this, static_cast(mFlatResources.size()), mHashedResources.end()); +} + +template +typename ResourceMap::Iterator ResourceMap::find(GLuint handle) const +{ + if (handle < mFlatResources.size()) + { + return (mFlatResources[handle] != InvalidPointer() + ? Iterator(handle, mHashedResources.begin()) + : end()); + } + else + { + return mHashedResources.find(handle); + } +} + +template +bool ResourceMap::empty() const +{ + return (begin() == end()); +} + +template +void ResourceMap::clear() +{ + mFlatResources.assign(kInitialFlatResourcesSize, InvalidPointer()); + mHashedResources.clear(); +} + +template +GLuint ResourceMap::nextNonNullResource(size_t flatIndex) const +{ + for (size_t index = flatIndex; index < mFlatResources.size(); index++) + { + if (mFlatResources[index] != nullptr && mFlatResources[index] != InvalidPointer()) + { + return static_cast(index); + } + } + return static_cast(mFlatResources.size()); +} + +template +// static +ResourceType *ResourceMap::InvalidPointer() +{ + return reinterpret_cast(kInvalidPointer); +} + +template +ResourceMap::Iterator::Iterator( + const ResourceMap &origin, + GLuint flatIndex, + typename ResourceMap::HashMap::const_iterator hashIndex) + : mOrigin(origin), mFlatIndex(flatIndex), mHashIndex(hashIndex), mValue() +{ + updateValue(); +} + +template +bool ResourceMap::Iterator::operator==(const Iterator &other) const +{ + return (mFlatIndex == other.mFlatIndex && mHashIndex == other.mHashIndex); +} + +template +bool ResourceMap::Iterator::operator!=(const Iterator &other) const +{ + return !(*this == other); +} + +template +typename ResourceMap::Iterator &ResourceMap::Iterator::operator++() +{ + if (mFlatIndex < static_cast(mOrigin.mFlatResources.size())) + { + mFlatIndex = mOrigin.nextNonNullResource(mFlatIndex + 1); + } + else + { + mHashIndex++; + } + updateValue(); + return *this; +} + +template +const typename ResourceMap::IndexAndResource + *ResourceMap::Iterator::operator->() const +{ + return &mValue; +} + +template +const typename ResourceMap::IndexAndResource + &ResourceMap::Iterator::operator*() const +{ + return mValue; +} + +template +void ResourceMap::Iterator::updateValue() +{ + if (mFlatIndex < static_cast(mOrigin.mFlatResources.size())) + { + mValue.first = mFlatIndex; + mValue.second = mOrigin.mFlatResources[mFlatIndex]; + } + else if (mHashIndex != mOrigin.mHashedResources.end()) + { + mValue.first = mHashIndex->first; + mValue.second = mHashIndex->second; + } +} + +} // namespace gl + +#endif // LIBANGLE_RESOURCE_MAP_H_ diff --git a/src/3rdparty/angle/src/libANGLE/Sampler.cpp b/src/3rdparty/angle/src/libANGLE/Sampler.cpp index d8d606a46f..0f05b697a2 100644 --- a/src/3rdparty/angle/src/libANGLE/Sampler.cpp +++ b/src/3rdparty/angle/src/libANGLE/Sampler.cpp @@ -9,14 +9,14 @@ #include "libANGLE/Sampler.h" #include "libANGLE/angletypes.h" -#include "libANGLE/renderer/ImplFactory.h" +#include "libANGLE/renderer/GLImplFactory.h" #include "libANGLE/renderer/SamplerImpl.h" namespace gl { -Sampler::Sampler(rx::ImplFactory *factory, GLuint id) - : RefCountObject(id), mImpl(factory->createSampler()), mLabel(), mSamplerState() +Sampler::Sampler(rx::GLImplFactory *factory, GLuint id) + : RefCountObject(id), mState(), mImpl(factory->createSampler(mState)), mLabel() { } @@ -25,6 +25,11 @@ Sampler::~Sampler() SafeDelete(mImpl); } +Error Sampler::onDestroy(const Context *context) +{ + return NoError(); +} + void Sampler::setLabel(const std::string &label) { mLabel = label; @@ -37,116 +42,128 @@ const std::string &Sampler::getLabel() const void Sampler::setMinFilter(GLenum minFilter) { - mSamplerState.minFilter = minFilter; + mState.minFilter = minFilter; } GLenum Sampler::getMinFilter() const { - return mSamplerState.minFilter; + return mState.minFilter; } void Sampler::setMagFilter(GLenum magFilter) { - mSamplerState.magFilter = magFilter; + mState.magFilter = magFilter; } GLenum Sampler::getMagFilter() const { - return mSamplerState.magFilter; + return mState.magFilter; } void Sampler::setWrapS(GLenum wrapS) { - mSamplerState.wrapS = wrapS; + mState.wrapS = wrapS; } GLenum Sampler::getWrapS() const { - return mSamplerState.wrapS; + return mState.wrapS; } void Sampler::setWrapT(GLenum wrapT) { - mSamplerState.wrapT = wrapT; + mState.wrapT = wrapT; } GLenum Sampler::getWrapT() const { - return mSamplerState.wrapT; + return mState.wrapT; } void Sampler::setWrapR(GLenum wrapR) { - mSamplerState.wrapR = wrapR; + mState.wrapR = wrapR; } GLenum Sampler::getWrapR() const { - return mSamplerState.wrapR; + return mState.wrapR; } void Sampler::setMaxAnisotropy(float maxAnisotropy) { - mSamplerState.maxAnisotropy = maxAnisotropy; + mState.maxAnisotropy = maxAnisotropy; } float Sampler::getMaxAnisotropy() const { - return mSamplerState.maxAnisotropy; + return mState.maxAnisotropy; } void Sampler::setMinLod(GLfloat minLod) { - mSamplerState.minLod = minLod; + mState.minLod = minLod; } GLfloat Sampler::getMinLod() const { - return mSamplerState.minLod; + return mState.minLod; } void Sampler::setMaxLod(GLfloat maxLod) { - mSamplerState.maxLod = maxLod; + mState.maxLod = maxLod; } GLfloat Sampler::getMaxLod() const { - return mSamplerState.maxLod; + return mState.maxLod; } void Sampler::setCompareMode(GLenum compareMode) { - mSamplerState.compareMode = compareMode; + mState.compareMode = compareMode; } GLenum Sampler::getCompareMode() const { - return mSamplerState.compareMode; + return mState.compareMode; } void Sampler::setCompareFunc(GLenum compareFunc) { - mSamplerState.compareFunc = compareFunc; + mState.compareFunc = compareFunc; } GLenum Sampler::getCompareFunc() const { - return mSamplerState.compareFunc; + return mState.compareFunc; +} + +void Sampler::setSRGBDecode(GLenum sRGBDecode) +{ + mState.sRGBDecode = sRGBDecode; +} + +GLenum Sampler::getSRGBDecode() const +{ + return mState.sRGBDecode; } const SamplerState &Sampler::getSamplerState() const { - return mSamplerState; + return mState; } -const rx::SamplerImpl *Sampler::getImplementation() const +rx::SamplerImpl *Sampler::getImplementation() const { return mImpl; } -rx::SamplerImpl *Sampler::getImplementation() +void Sampler::syncState(const Context *context) { - return mImpl; -} + // TODO(jmadill): Use actual dirty bits for sampler. + mImpl->syncState(context); } + +} // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/Sampler.h b/src/3rdparty/angle/src/libANGLE/Sampler.h index a40b1655fc..cd34273b44 100644 --- a/src/3rdparty/angle/src/libANGLE/Sampler.h +++ b/src/3rdparty/angle/src/libANGLE/Sampler.h @@ -16,7 +16,7 @@ namespace rx { -class ImplFactory; +class GLImplFactory; class SamplerImpl; } @@ -26,9 +26,11 @@ namespace gl class Sampler final : public RefCountObject, public LabeledObject { public: - Sampler(rx::ImplFactory *factory, GLuint id); + Sampler(rx::GLImplFactory *factory, GLuint id); ~Sampler() override; + Error onDestroy(const Context *context) override; + void setLabel(const std::string &label) override; const std::string &getLabel() const override; @@ -62,19 +64,22 @@ class Sampler final : public RefCountObject, public LabeledObject void setCompareFunc(GLenum compareFunc); GLenum getCompareFunc() const; + void setSRGBDecode(GLenum sRGBDecode); + GLenum getSRGBDecode() const; + const SamplerState &getSamplerState() const; - const rx::SamplerImpl *getImplementation() const; - rx::SamplerImpl *getImplementation(); + rx::SamplerImpl *getImplementation() const; + + void syncState(const Context *context); private: + SamplerState mState; rx::SamplerImpl *mImpl; std::string mLabel; - - SamplerState mSamplerState; }; -} +} // namespace gl #endif // LIBANGLE_SAMPLER_H_ diff --git a/src/3rdparty/angle/src/libANGLE/Shader.cpp b/src/3rdparty/angle/src/libANGLE/Shader.cpp index bbe9077fc9..94c4f3c705 100644 --- a/src/3rdparty/angle/src/libANGLE/Shader.cpp +++ b/src/3rdparty/angle/src/libANGLE/Shader.cpp @@ -14,11 +14,13 @@ #include "common/utilities.h" #include "GLSLANG/ShaderLang.h" +#include "libANGLE/Caps.h" #include "libANGLE/Compiler.h" #include "libANGLE/Constants.h" -#include "libANGLE/renderer/Renderer.h" +#include "libANGLE/renderer/GLImplFactory.h" #include "libANGLE/renderer/ShaderImpl.h" #include "libANGLE/ResourceManager.h" +#include "libANGLE/Context.h" namespace gl { @@ -55,16 +57,16 @@ bool CompareShaderVar(const sh::ShaderVariable &x, const sh::ShaderVariable &y) { if (x.type == y.type) { - return x.arraySize > y.arraySize; + return x.getArraySizeProduct() > y.getArraySizeProduct(); } // Special case for handling structs: we sort these to the end of the list - if (x.type == GL_STRUCT_ANGLEX) + if (x.type == GL_NONE) { return false; } - if (y.type == GL_STRUCT_ANGLEX) + if (y.type == GL_NONE) { return true; } @@ -72,45 +74,61 @@ bool CompareShaderVar(const sh::ShaderVariable &x, const sh::ShaderVariable &y) return gl::VariableSortOrder(x.type) < gl::VariableSortOrder(y.type); } -Shader::Data::Data(GLenum shaderType) : mLabel(), mShaderType(shaderType), mShaderVersion(100) +ShaderState::ShaderState(GLenum shaderType) + : mLabel(), + mShaderType(shaderType), + mShaderVersion(100), + mNumViews(-1), + mGeometryShaderInputPrimitiveType(GL_INVALID_VALUE), + mGeometryShaderOutputPrimitiveType(GL_INVALID_VALUE), + mGeometryShaderInvocations(1), + mGeometryShaderMaxVertices(-1), + mCompileStatus(CompileStatus::NOT_COMPILED) +{ + mLocalSize.fill(-1); +} + +ShaderState::~ShaderState() { } -Shader::Data::~Data() -{ -} - -Shader::Shader(ResourceManager *manager, - rx::ImplFactory *implFactory, +Shader::Shader(ShaderProgramManager *manager, + rx::GLImplFactory *implFactory, const gl::Limitations &rendererLimitations, GLenum type, GLuint handle) - : mData(type), - mImplementation(implFactory->createShader(mData)), + : mState(type), + mImplementation(implFactory->createShader(mState)), mRendererLimitations(rendererLimitations), mHandle(handle), mType(type), mRefCount(0), mDeleteStatus(false), - mCompiled(false), mResourceManager(manager) { ASSERT(mImplementation); } +void Shader::onDestroy(const gl::Context *context) +{ + mBoundCompiler.set(context, nullptr); + mImplementation.reset(nullptr); + delete this; +} + Shader::~Shader() { - SafeDelete(mImplementation); + ASSERT(!mImplementation); } void Shader::setLabel(const std::string &label) { - mData.mLabel = label; + mState.mLabel = label; } const std::string &Shader::getLabel() const { - return mData.mLabel; + return mState.mLabel; } GLuint Shader::getHandle() const @@ -134,11 +152,12 @@ void Shader::setSource(GLsizei count, const char *const *string, const GLint *le } } - mData.mSource = stream.str(); + mState.mSource = stream.str(); } -int Shader::getInfoLogLength() const +int Shader::getInfoLogLength(const Context *context) { + resolveCompile(context); if (mInfoLog.empty()) { return 0; @@ -147,8 +166,10 @@ int Shader::getInfoLogLength() const return (static_cast(mInfoLog.length()) + 1); } -void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const +void Shader::getInfoLog(const Context *context, GLsizei bufSize, GLsizei *length, char *infoLog) { + resolveCompile(context); + int index = 0; if (bufSize > 0) @@ -167,21 +188,25 @@ void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const int Shader::getSourceLength() const { - return mData.mSource.empty() ? 0 : (static_cast(mData.mSource.length()) + 1); + return mState.mSource.empty() ? 0 : (static_cast(mState.mSource.length()) + 1); } -int Shader::getTranslatedSourceLength() const +int Shader::getTranslatedSourceLength(const Context *context) { - if (mData.mTranslatedSource.empty()) + resolveCompile(context); + + if (mState.mTranslatedSource.empty()) { return 0; } - return (static_cast(mData.mTranslatedSource.length()) + 1); + return (static_cast(mState.mTranslatedSource.length()) + 1); } -int Shader::getTranslatedSourceWithDebugInfoLength() const +int Shader::getTranslatedSourceWithDebugInfoLength(const Context *context) { + resolveCompile(context); + const std::string &debugInfo = mImplementation->getDebugInfo(); if (debugInfo.empty()) { @@ -191,7 +216,11 @@ int Shader::getTranslatedSourceWithDebugInfoLength() const return (static_cast(debugInfo.length()) + 1); } -void Shader::getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *length, char *buffer) +// static +void Shader::GetSourceImpl(const std::string &source, + GLsizei bufSize, + GLsizei *length, + char *buffer) { int index = 0; @@ -211,117 +240,186 @@ void Shader::getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei * void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer) const { - getSourceImpl(mData.mSource, bufSize, length, buffer); + GetSourceImpl(mState.mSource, bufSize, length, buffer); } -void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const +void Shader::getTranslatedSource(const Context *context, + GLsizei bufSize, + GLsizei *length, + char *buffer) { - getSourceImpl(mData.mTranslatedSource, bufSize, length, buffer); + GetSourceImpl(getTranslatedSource(context), bufSize, length, buffer); } -void Shader::getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer) const +const std::string &Shader::getTranslatedSource(const Context *context) { + resolveCompile(context); + return mState.mTranslatedSource; +} + +void Shader::getTranslatedSourceWithDebugInfo(const Context *context, + GLsizei bufSize, + GLsizei *length, + char *buffer) +{ + resolveCompile(context); const std::string &debugInfo = mImplementation->getDebugInfo(); - getSourceImpl(debugInfo, bufSize, length, buffer); + GetSourceImpl(debugInfo, bufSize, length, buffer); } -void Shader::compile(Compiler *compiler) +void Shader::compile(const Context *context) { - mData.mTranslatedSource.clear(); + mState.mTranslatedSource.clear(); mInfoLog.clear(); - mData.mShaderVersion = 100; - mData.mVaryings.clear(); - mData.mUniforms.clear(); - mData.mInterfaceBlocks.clear(); - mData.mActiveAttributes.clear(); - mData.mActiveOutputVariables.clear(); + mState.mShaderVersion = 100; + mState.mInputVaryings.clear(); + mState.mOutputVaryings.clear(); + mState.mUniforms.clear(); + mState.mUniformBlocks.clear(); + mState.mShaderStorageBlocks.clear(); + mState.mActiveAttributes.clear(); + mState.mActiveOutputVariables.clear(); + mState.mNumViews = -1; + mState.mGeometryShaderInputPrimitiveType = GL_INVALID_VALUE; + mState.mGeometryShaderOutputPrimitiveType = GL_INVALID_VALUE; + mState.mGeometryShaderInvocations = 1; + mState.mGeometryShaderMaxVertices = -1; - ShHandle compilerHandle = compiler->getCompilerHandle(mData.mShaderType); + mState.mCompileStatus = CompileStatus::COMPILE_REQUESTED; + mBoundCompiler.set(context, context->getCompiler()); + + // Cache the compile source and options for compilation. Must be done now, since the source + // can change before the link call or another call that resolves the compile. std::stringstream sourceStream; - std::string sourcePath; - int additionalOptions = - mImplementation->prepareSourceAndReturnOptions(&sourceStream, &sourcePath); - int compileOptions = (SH_OBJECT_CODE | SH_VARIABLES | additionalOptions); + mLastCompileOptions = + mImplementation->prepareSourceAndReturnOptions(&sourceStream, &mLastCompiledSourcePath); + mLastCompileOptions |= (SH_OBJECT_CODE | SH_VARIABLES); + mLastCompiledSource = sourceStream.str(); + + // Add default options to WebGL shaders to prevent unexpected behavior during compilation. + if (context->getExtensions().webglCompatibility) + { + mLastCompileOptions |= SH_INIT_GL_POSITION; + mLastCompileOptions |= SH_LIMIT_CALL_STACK_DEPTH; + mLastCompileOptions |= SH_LIMIT_EXPRESSION_COMPLEXITY; + mLastCompileOptions |= SH_ENFORCE_PACKING_RESTRICTIONS; + } // Some targets (eg D3D11 Feature Level 9_3 and below) do not support non-constant loop indexes // in fragment shaders. Shader compilation will fail. To provide a better error message we can // instruct the compiler to pre-validate. if (mRendererLimitations.shadersRequireIndexedLoopValidation) { - compileOptions |= SH_VALIDATE_LOOP_INDEXING; + mLastCompileOptions |= SH_VALIDATE_LOOP_INDEXING; } +} - std::string sourceString = sourceStream.str(); - std::vector sourceCStrings; - - if (!sourcePath.empty()) +void Shader::resolveCompile(const Context *context) +{ + if (!mState.compilePending()) { - sourceCStrings.push_back(sourcePath.c_str()); - } - - sourceCStrings.push_back(sourceString.c_str()); - - bool result = - ShCompile(compilerHandle, &sourceCStrings[0], sourceCStrings.size(), compileOptions); - - if (!result) - { - mInfoLog = ShGetInfoLog(compilerHandle); - TRACE("\n%s", mInfoLog.c_str()); - mCompiled = false; return; } - mData.mTranslatedSource = ShGetObjectCode(compilerHandle); + ASSERT(mBoundCompiler.get()); + ShHandle compilerHandle = mBoundCompiler->getCompilerHandle(mState.mShaderType); -#ifndef NDEBUG + std::vector srcStrings; + + if (!mLastCompiledSourcePath.empty()) + { + srcStrings.push_back(mLastCompiledSourcePath.c_str()); + } + + srcStrings.push_back(mLastCompiledSource.c_str()); + + if (!sh::Compile(compilerHandle, &srcStrings[0], srcStrings.size(), mLastCompileOptions)) + { + mInfoLog = sh::GetInfoLog(compilerHandle); + WARN() << std::endl << mInfoLog; + mState.mCompileStatus = CompileStatus::NOT_COMPILED; + return; + } + + mState.mTranslatedSource = sh::GetObjectCode(compilerHandle); + +#if !defined(NDEBUG) // Prefix translated shader with commented out un-translated shader. // Useful in diagnostics tools which capture the shader source. std::ostringstream shaderStream; shaderStream << "// GLSL\n"; shaderStream << "//\n"; - size_t curPos = 0; - while (curPos != std::string::npos) + std::istringstream inputSourceStream(mState.mSource); + std::string line; + while (std::getline(inputSourceStream, line)) { - size_t nextLine = mData.mSource.find("\n", curPos); - size_t len = (nextLine == std::string::npos) ? std::string::npos : (nextLine - curPos + 1); + // Remove null characters from the source line + line.erase(std::remove(line.begin(), line.end(), '\0'), line.end()); - shaderStream << "// " << mData.mSource.substr(curPos, len); - - curPos = (nextLine == std::string::npos) ? std::string::npos : (nextLine + 1); + shaderStream << "// " << line << std::endl; } shaderStream << "\n\n"; - shaderStream << mData.mTranslatedSource; - mData.mTranslatedSource = shaderStream.str(); -#endif + shaderStream << mState.mTranslatedSource; + mState.mTranslatedSource = shaderStream.str(); +#endif // !defined(NDEBUG) // Gather the shader information - mData.mShaderVersion = ShGetShaderVersion(compilerHandle); + mState.mShaderVersion = sh::GetShaderVersion(compilerHandle); - mData.mVaryings = GetShaderVariables(ShGetVaryings(compilerHandle)); - mData.mUniforms = GetShaderVariables(ShGetUniforms(compilerHandle)); - mData.mInterfaceBlocks = GetShaderVariables(ShGetInterfaceBlocks(compilerHandle)); + mState.mUniforms = GetShaderVariables(sh::GetUniforms(compilerHandle)); + mState.mUniformBlocks = GetShaderVariables(sh::GetUniformBlocks(compilerHandle)); + mState.mShaderStorageBlocks = GetShaderVariables(sh::GetShaderStorageBlocks(compilerHandle)); - if (mData.mShaderType == GL_VERTEX_SHADER) + switch (mState.mShaderType) { - mData.mActiveAttributes = GetActiveShaderVariables(ShGetAttributes(compilerHandle)); - } - else - { - ASSERT(mData.mShaderType == GL_FRAGMENT_SHADER); + case GL_COMPUTE_SHADER: + { + mState.mLocalSize = sh::GetComputeShaderLocalGroupSize(compilerHandle); + break; + } + case GL_VERTEX_SHADER: + { + { + mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle)); + mState.mActiveAttributes = + GetActiveShaderVariables(sh::GetAttributes(compilerHandle)); + mState.mNumViews = sh::GetVertexShaderNumViews(compilerHandle); + } + break; + } + case GL_FRAGMENT_SHADER: + { + mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle)); + // TODO(jmadill): Figure out why we only sort in the FS, and if we need to. + std::sort(mState.mInputVaryings.begin(), mState.mInputVaryings.end(), CompareShaderVar); + mState.mActiveOutputVariables = + GetActiveShaderVariables(sh::GetOutputVariables(compilerHandle)); + break; + } + case GL_GEOMETRY_SHADER_EXT: + { + mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle)); + mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle)); - // TODO(jmadill): Figure out why we only sort in the FS, and if we need to. - std::sort(mData.mVaryings.begin(), mData.mVaryings.end(), CompareShaderVar); - mData.mActiveOutputVariables = - GetActiveShaderVariables(ShGetOutputVariables(compilerHandle)); + mState.mGeometryShaderInputPrimitiveType = + sh::GetGeometryShaderInputPrimitiveType(compilerHandle); + mState.mGeometryShaderOutputPrimitiveType = + sh::GetGeometryShaderOutputPrimitiveType(compilerHandle); + mState.mGeometryShaderInvocations = sh::GetGeometryShaderInvocations(compilerHandle); + mState.mGeometryShaderMaxVertices = sh::GetGeometryShaderMaxVertices(compilerHandle); + break; + } + default: + UNREACHABLE(); } - ASSERT(!mData.mTranslatedSource.empty()); + ASSERT(!mState.mTranslatedSource.empty()); - mCompiled = mImplementation->postTranslateCompile(compiler, &mInfoLog); + bool success = mImplementation->postTranslateCompile(mBoundCompiler.get(), &mInfoLog); + mState.mCompileStatus = success ? CompileStatus::COMPILED : CompileStatus::NOT_COMPILED; } void Shader::addRef() @@ -329,13 +427,13 @@ void Shader::addRef() mRefCount++; } -void Shader::release() +void Shader::release(const Context *context) { mRefCount--; if (mRefCount == 0 && mDeleteStatus) { - mResourceManager->deleteShader(mHandle); + mResourceManager->deleteShader(context, mHandle); } } @@ -354,57 +452,110 @@ void Shader::flagForDeletion() mDeleteStatus = true; } -int Shader::getShaderVersion() const +bool Shader::isCompiled(const Context *context) { - return mData.mShaderVersion; + resolveCompile(context); + return mState.mCompileStatus == CompileStatus::COMPILED; } -const std::vector &Shader::getVaryings() const +int Shader::getShaderVersion(const Context *context) { - return mData.getVaryings(); + resolveCompile(context); + return mState.mShaderVersion; } -const std::vector &Shader::getUniforms() const +const std::vector &Shader::getInputVaryings(const Context *context) { - return mData.getUniforms(); + resolveCompile(context); + return mState.getInputVaryings(); } -const std::vector &Shader::getInterfaceBlocks() const +const std::vector &Shader::getOutputVaryings(const Context *context) { - return mData.getInterfaceBlocks(); + resolveCompile(context); + return mState.getOutputVaryings(); } -const std::vector &Shader::getActiveAttributes() const +const std::vector &Shader::getUniforms(const Context *context) { - return mData.getActiveAttributes(); + resolveCompile(context); + return mState.getUniforms(); } -const std::vector &Shader::getActiveOutputVariables() const +const std::vector &Shader::getUniformBlocks(const Context *context) { - return mData.getActiveOutputVariables(); + resolveCompile(context); + return mState.getUniformBlocks(); } -int Shader::getSemanticIndex(const std::string &attributeName) const +const std::vector &Shader::getShaderStorageBlocks(const Context *context) { - if (!attributeName.empty()) + resolveCompile(context); + return mState.getShaderStorageBlocks(); +} + +const std::vector &Shader::getActiveAttributes(const Context *context) +{ + resolveCompile(context); + return mState.getActiveAttributes(); +} + +const std::vector &Shader::getActiveOutputVariables(const Context *context) +{ + resolveCompile(context); + return mState.getActiveOutputVariables(); +} + +std::string Shader::getTransformFeedbackVaryingMappedName(const std::string &tfVaryingName, + const Context *context) +{ + // TODO(jiawei.shao@intel.com): support transform feedback on geometry shader. + ASSERT(mState.getShaderType() == GL_VERTEX_SHADER); + const auto &varyings = getOutputVaryings(context); + auto bracketPos = tfVaryingName.find("["); + if (bracketPos != std::string::npos) { - const auto &activeAttributes = mData.getActiveAttributes(); - - int semanticIndex = 0; - for (size_t attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++) + auto tfVaryingBaseName = tfVaryingName.substr(0, bracketPos); + for (const auto &varying : varyings) { - const sh::ShaderVariable &attribute = activeAttributes[attributeIndex]; - - if (attribute.name == attributeName) + if (varying.name == tfVaryingBaseName) { - return semanticIndex; + std::string mappedNameWithArrayIndex = + varying.mappedName + tfVaryingName.substr(bracketPos); + return mappedNameWithArrayIndex; } - - semanticIndex += gl::VariableRegisterCount(attribute.type); } } - - return -1; + else + { + for (const auto &varying : varyings) + { + if (varying.name == tfVaryingName) + { + return varying.mappedName; + } + } + } + UNREACHABLE(); + return std::string(); } +const sh::WorkGroupSize &Shader::getWorkGroupSize(const Context *context) +{ + resolveCompile(context); + return mState.mLocalSize; } + +int Shader::getNumViews(const Context *context) +{ + resolveCompile(context); + return mState.mNumViews; +} + +const std::string &Shader::getCompilerResourcesString() const +{ + ASSERT(mBoundCompiler.get()); + return mBoundCompiler->getBuiltinResourcesString(mState.mShaderType); +} + +} // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/Shader.h b/src/3rdparty/angle/src/libANGLE/Shader.h index 997977c87b..4b6be4696d 100644 --- a/src/3rdparty/angle/src/libANGLE/Shader.h +++ b/src/3rdparty/angle/src/libANGLE/Shader.h @@ -12,20 +12,22 @@ #ifndef LIBANGLE_SHADER_H_ #define LIBANGLE_SHADER_H_ -#include #include +#include +#include #include #include "angle_gl.h" #include +#include "common/Optional.h" #include "common/angleutils.h" -#include "libANGLE/angletypes.h" #include "libANGLE/Debug.h" +#include "libANGLE/angletypes.h" namespace rx { -class ImplFactory; +class GLImplFactory; class ShaderImpl; class ShaderSh; } @@ -33,63 +35,92 @@ class ShaderSh; namespace gl { class Compiler; +class ContextState; struct Limitations; -class ResourceManager; -struct Data; +class ShaderProgramManager; +class Context; + +// We defer the compile until link time, or until properties are queried. +enum class CompileStatus +{ + NOT_COMPILED, + COMPILE_REQUESTED, + COMPILED, +}; + +class ShaderState final : angle::NonCopyable +{ + public: + ShaderState(GLenum shaderType); + ~ShaderState(); + + const std::string &getLabel() const { return mLabel; } + + const std::string &getSource() const { return mSource; } + const std::string &getTranslatedSource() const { return mTranslatedSource; } + + GLenum getShaderType() const { return mShaderType; } + int getShaderVersion() const { return mShaderVersion; } + + const std::vector &getInputVaryings() const { return mInputVaryings; } + const std::vector &getOutputVaryings() const { return mOutputVaryings; } + const std::vector &getUniforms() const { return mUniforms; } + const std::vector &getUniformBlocks() const { return mUniformBlocks; } + const std::vector &getShaderStorageBlocks() const + { + return mShaderStorageBlocks; + } + const std::vector &getActiveAttributes() const { return mActiveAttributes; } + const std::vector &getActiveOutputVariables() const + { + return mActiveOutputVariables; + } + + bool compilePending() const { return mCompileStatus == CompileStatus::COMPILE_REQUESTED; } + + private: + friend class Shader; + + std::string mLabel; + + GLenum mShaderType; + int mShaderVersion; + std::string mTranslatedSource; + std::string mSource; + + sh::WorkGroupSize mLocalSize; + + std::vector mInputVaryings; + std::vector mOutputVaryings; + std::vector mUniforms; + std::vector mUniformBlocks; + std::vector mShaderStorageBlocks; + std::vector mActiveAttributes; + std::vector mActiveOutputVariables; + + // ANGLE_multiview. + int mNumViews; + + // Geometry Shader. + GLenum mGeometryShaderInputPrimitiveType; + GLenum mGeometryShaderOutputPrimitiveType; + int mGeometryShaderInvocations; + int mGeometryShaderMaxVertices; + + // Indicates if this shader has been successfully compiled + CompileStatus mCompileStatus; +}; class Shader final : angle::NonCopyable, public LabeledObject { public: - class Data final : angle::NonCopyable - { - public: - Data(GLenum shaderType); - ~Data(); - - const std::string &getLabel() const { return mLabel; } - - const std::string &getSource() const { return mSource; } - const std::string &getTranslatedSource() const { return mTranslatedSource; } - - GLenum getShaderType() const { return mShaderType; } - int getShaderVersion() const { return mShaderVersion; } - - const std::vector &getVaryings() const { return mVaryings; } - const std::vector &getUniforms() const { return mUniforms; } - const std::vector &getInterfaceBlocks() const - { - return mInterfaceBlocks; - } - const std::vector &getActiveAttributes() const { return mActiveAttributes; } - const std::vector &getActiveOutputVariables() const - { - return mActiveOutputVariables; - } - - private: - friend class Shader; - - std::string mLabel; - - GLenum mShaderType; - int mShaderVersion; - std::string mTranslatedSource; - std::string mSource; - - std::vector mVaryings; - std::vector mUniforms; - std::vector mInterfaceBlocks; - std::vector mActiveAttributes; - std::vector mActiveOutputVariables; - }; - - Shader(ResourceManager *manager, - rx::ImplFactory *implFactory, + Shader(ShaderProgramManager *manager, + rx::GLImplFactory *implFactory, const gl::Limitations &rendererLimitations, GLenum type, GLuint handle); - virtual ~Shader(); + void onDestroy(const Context *context); void setLabel(const std::string &label) override; const std::string &getLabel() const override; @@ -97,56 +128,85 @@ class Shader final : angle::NonCopyable, public LabeledObject GLenum getType() const { return mType; } GLuint getHandle() const; - const rx::ShaderImpl *getImplementation() const { return mImplementation; } + rx::ShaderImpl *getImplementation() const { return mImplementation.get(); } - void deleteSource(); void setSource(GLsizei count, const char *const *string, const GLint *length); - int getInfoLogLength() const; - void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const; + int getInfoLogLength(const Context *context); + void getInfoLog(const Context *context, GLsizei bufSize, GLsizei *length, char *infoLog); int getSourceLength() const; + const std::string &getSourceString() const { return mState.getSource(); } void getSource(GLsizei bufSize, GLsizei *length, char *buffer) const; - int getTranslatedSourceLength() const; - int getTranslatedSourceWithDebugInfoLength() const; - const std::string &getTranslatedSource() const { return mData.getTranslatedSource(); } - void getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const; - void getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer) const; + int getTranslatedSourceLength(const Context *context); + int getTranslatedSourceWithDebugInfoLength(const Context *context); + const std::string &getTranslatedSource(const Context *context); + void getTranslatedSource(const Context *context, + GLsizei bufSize, + GLsizei *length, + char *buffer); + void getTranslatedSourceWithDebugInfo(const Context *context, + GLsizei bufSize, + GLsizei *length, + char *buffer); - void compile(Compiler *compiler); - bool isCompiled() const { return mCompiled; } + void compile(const Context *context); + bool isCompiled(const Context *context); void addRef(); - void release(); + void release(const Context *context); unsigned int getRefCount() const; bool isFlaggedForDeletion() const; void flagForDeletion(); - int getShaderVersion() const; + int getShaderVersion(const Context *context); - const std::vector &getVaryings() const; - const std::vector &getUniforms() const; - const std::vector &getInterfaceBlocks() const; - const std::vector &getActiveAttributes() const; - const std::vector &getActiveOutputVariables() const; + const std::vector &getInputVaryings(const Context *context); + const std::vector &getOutputVaryings(const Context *context); + const std::vector &getUniforms(const Context *context); + const std::vector &getUniformBlocks(const Context *context); + const std::vector &getShaderStorageBlocks(const Context *context); + const std::vector &getActiveAttributes(const Context *context); + const std::vector &getActiveOutputVariables(const Context *context); - int getSemanticIndex(const std::string &attributeName) const; + // Returns mapped name of a transform feedback varying. The original name may contain array + // brackets with an index inside, which will get copied to the mapped name. The varying must be + // known to be declared in the shader. + std::string getTransformFeedbackVaryingMappedName(const std::string &tfVaryingName, + const Context *context); + + const sh::WorkGroupSize &getWorkGroupSize(const Context *context); + + int getNumViews(const Context *context); + + const std::string &getCompilerResourcesString() const; private: - static void getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *length, char *buffer); + ~Shader() override; + static void GetSourceImpl(const std::string &source, + GLsizei bufSize, + GLsizei *length, + char *buffer); - Data mData; - rx::ShaderImpl *mImplementation; + void resolveCompile(const Context *context); + + ShaderState mState; + std::string mLastCompiledSource; + std::string mLastCompiledSourcePath; + ShCompileOptions mLastCompileOptions; + std::unique_ptr mImplementation; const gl::Limitations &mRendererLimitations; const GLuint mHandle; const GLenum mType; unsigned int mRefCount; // Number of program objects this shader is attached to bool mDeleteStatus; // Flag to indicate that the shader can be deleted when no longer in use - bool mCompiled; // Indicates if this shader has been successfully compiled std::string mInfoLog; - ResourceManager *mResourceManager; + // We keep a reference to the translator in order to defer compiles while preserving settings. + BindingPointer mBoundCompiler; + + ShaderProgramManager *mResourceManager; }; bool CompareShaderVar(const sh::ShaderVariable &x, const sh::ShaderVariable &y); -} +} // namespace gl #endif // LIBANGLE_SHADER_H_ diff --git a/src/3rdparty/angle/src/libANGLE/SizedMRUCache.h b/src/3rdparty/angle/src/libANGLE/SizedMRUCache.h new file mode 100644 index 0000000000..6a608a697e --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/SizedMRUCache.h @@ -0,0 +1,174 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// SizedMRUCache.h: A hashing map that stores blobs of sized, untyped data. + +#ifndef LIBANGLE_SIZED_MRU_CACHE_H_ +#define LIBANGLE_SIZED_MRU_CACHE_H_ + +#include +#include "common/third_party/smhasher/src/PMurHash.h" + +namespace angle +{ + +template +class SizedMRUCache final : angle::NonCopyable +{ + public: + SizedMRUCache(size_t maximumTotalSize) + : mMaximumTotalSize(maximumTotalSize), + mCurrentSize(0), + mStore(SizedMRUCacheStore::NO_AUTO_EVICT) + { + } + + // Returns nullptr on failure. + const Value *put(const Key &key, Value &&value, size_t size) + { + if (size > mMaximumTotalSize) + { + return nullptr; + } + + // Check for existing key. + eraseByKey(key); + + auto retVal = mStore.Put(key, ValueAndSize(std::move(value), size)); + mCurrentSize += size; + + shrinkToSize(mMaximumTotalSize); + + return &retVal->second.value; + } + + bool get(const Key &key, const Value **valueOut) + { + const auto &iter = mStore.Get(key); + if (iter == mStore.end()) + { + return false; + } + *valueOut = &iter->second.value; + return true; + } + + bool getAt(size_t index, Key *keyOut, const Value **valueOut) + { + if (index < mStore.size()) + { + auto it = mStore.begin(); + std::advance(it, index); + *keyOut = it->first; + *valueOut = &it->second.value; + return true; + } + *valueOut = nullptr; + return false; + } + + bool empty() const { return mStore.empty(); } + + void clear() + { + mStore.Clear(); + mCurrentSize = 0; + } + + bool eraseByKey(const Key &key) + { + // Check for existing key. + auto existing = mStore.Peek(key); + if (existing != mStore.end()) + { + mCurrentSize -= existing->second.size; + mStore.Erase(existing); + return true; + } + + return false; + } + + size_t entryCount() const { return mStore.size(); } + + size_t size() const { return mCurrentSize; } + + // Also discards the cache contents. + void resize(size_t maximumTotalSize) + { + clear(); + mMaximumTotalSize = maximumTotalSize; + } + + // Reduce current memory usage. + size_t shrinkToSize(size_t limit) + { + size_t initialSize = mCurrentSize; + + while (mCurrentSize > limit) + { + ASSERT(!mStore.empty()); + auto iter = mStore.rbegin(); + mCurrentSize -= iter->second.size; + mStore.Erase(iter); + } + + return (initialSize - mCurrentSize); + } + + size_t maxSize() const { return mMaximumTotalSize; } + + private: + struct ValueAndSize + { + ValueAndSize() : value(), size(0) {} + ValueAndSize(Value &&value, size_t size) : value(std::move(value)), size(size) {} + ValueAndSize(ValueAndSize &&other) : ValueAndSize() { *this = std::move(other); } + ValueAndSize &operator=(ValueAndSize &&other) + { + std::swap(value, other.value); + std::swap(size, other.size); + return *this; + } + + Value value; + size_t size; + }; + + using SizedMRUCacheStore = base::HashingMRUCache; + + size_t mMaximumTotalSize; + size_t mCurrentSize; + SizedMRUCacheStore mStore; +}; + +// Helper function used in a few places. +template +void TrimCache(size_t maxStates, size_t gcLimit, const char *name, T *cache) +{ + const size_t kGarbageCollectionLimit = maxStates / 2 + gcLimit; + + if (cache->size() >= kGarbageCollectionLimit) + { + WARN() << "Overflowed the " << name << " cache limit of " << (maxStates / 2) + << " elements, removing the least recently used to make room."; + cache->ShrinkToSize(maxStates / 2); + } +} + +// Computes a hash of struct "key". Any structs passed to this function must be multiples of +// 4 bytes, since the PMurhHas32 method can only operate increments of 4-byte words. +template +std::size_t ComputeGenericHash(const T &key) +{ + static const unsigned int seed = 0xABCDEF98; + + // We can't support "odd" alignments. + static_assert(sizeof(key) % 4 == 0, "ComputeGenericHash requires aligned types"); + return PMurHash32(seed, &key, sizeof(T)); +} + +} // namespace angle +#endif // LIBANGLE_SIZED_MRU_CACHE_H_ diff --git a/src/3rdparty/angle/src/libANGLE/State.cpp b/src/3rdparty/angle/src/libANGLE/State.cpp index a1437b838b..f87e963710 100644 --- a/src/3rdparty/angle/src/libANGLE/State.cpp +++ b/src/3rdparty/angle/src/libANGLE/State.cpp @@ -8,15 +8,32 @@ #include "libANGLE/State.h" -#include "common/BitSetIterator.h" -#include "libANGLE/Context.h" +#include +#include + +#include "common/bitset_utils.h" +#include "common/mathutil.h" +#include "common/matrix_utils.h" #include "libANGLE/Caps.h" +#include "libANGLE/Context.h" #include "libANGLE/Debug.h" #include "libANGLE/Framebuffer.h" #include "libANGLE/FramebufferAttachment.h" #include "libANGLE/Query.h" #include "libANGLE/VertexArray.h" #include "libANGLE/formatutils.h" +#include "libANGLE/queryconversions.h" +#include "libANGLE/renderer/ContextImpl.h" + +namespace +{ + +GLenum ActiveQueryType(const GLenum type) +{ + return (type == GL_ANY_SAMPLES_PASSED_CONSERVATIVE) ? GL_ANY_SAMPLES_PASSED : type; +} + +} // anonymous namepace namespace gl { @@ -30,11 +47,15 @@ State::State() mSampleCoverage(false), mSampleCoverageValue(0), mSampleCoverageInvert(false), + mSampleMask(false), + mMaxSampleMaskWords(0), mStencilRef(0), mStencilBackRef(0), mLineWidth(0), mGenerateMipmapHint(GL_NONE), mFragmentShaderDerivativeHint(GL_NONE), + mBindGeneratesResource(true), + mClientArraysEnabled(true), mNearZ(0), mFarZ(0), mReadFramebuffer(nullptr), @@ -42,49 +63,31 @@ State::State() mProgram(nullptr), mVertexArray(nullptr), mActiveSampler(0), - mPrimitiveRestart(false) + mPrimitiveRestart(false), + mMultiSampling(false), + mSampleAlphaToOne(false), + mFramebufferSRGB(true), + mRobustResourceInit(false), + mProgramBinaryCacheEnabled(false) { - // Initialize dirty bit masks - // TODO(jmadill): additional ES3 state - mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_ALIGNMENT); - mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_ROW_LENGTH); - mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_IMAGE_HEIGHT); - mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_SKIP_IMAGES); - mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_SKIP_ROWS); - mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_SKIP_PIXELS); - - mPackStateBitMask.set(DIRTY_BIT_PACK_ALIGNMENT); - mPackStateBitMask.set(DIRTY_BIT_PACK_REVERSE_ROW_ORDER); - mPackStateBitMask.set(DIRTY_BIT_PACK_ROW_LENGTH); - mPackStateBitMask.set(DIRTY_BIT_PACK_SKIP_ROWS); - mPackStateBitMask.set(DIRTY_BIT_PACK_SKIP_PIXELS); - - mClearStateBitMask.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED); - mClearStateBitMask.set(DIRTY_BIT_SCISSOR_TEST_ENABLED); - mClearStateBitMask.set(DIRTY_BIT_SCISSOR); - mClearStateBitMask.set(DIRTY_BIT_VIEWPORT); - mClearStateBitMask.set(DIRTY_BIT_CLEAR_COLOR); - mClearStateBitMask.set(DIRTY_BIT_CLEAR_DEPTH); - mClearStateBitMask.set(DIRTY_BIT_CLEAR_STENCIL); - mClearStateBitMask.set(DIRTY_BIT_COLOR_MASK); - mClearStateBitMask.set(DIRTY_BIT_DEPTH_MASK); - mClearStateBitMask.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT); - mClearStateBitMask.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK); - - mBlitStateBitMask.set(DIRTY_BIT_SCISSOR_TEST_ENABLED); - mBlitStateBitMask.set(DIRTY_BIT_SCISSOR); } State::~State() { - reset(); } -void State::initialize(const Caps &caps, - const Extensions &extensions, - GLuint clientVersion, - bool debug) +void State::initialize(const Context *context, + bool debug, + bool bindGeneratesResource, + bool clientArraysEnabled, + bool robustResourceInit, + bool programBinaryCacheEnabled) { + const Caps &caps = context->getCaps(); + const Extensions &extensions = context->getExtensions(); + const Extensions &nativeExtensions = context->getImplementation()->getNativeExtensions(); + const Version &clientVersion = context->getClientVersion(); + mMaxDrawBuffers = caps.maxDrawBuffers; mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits; @@ -93,62 +96,34 @@ void State::initialize(const Caps &caps, mDepthClearValue = 1.0f; mStencilClearValue = 0; - mRasterizer.rasterizerDiscard = false; - mRasterizer.cullFace = false; - mRasterizer.cullMode = GL_BACK; - mRasterizer.frontFace = GL_CCW; - mRasterizer.polygonOffsetFill = false; - mRasterizer.polygonOffsetFactor = 0.0f; - mRasterizer.polygonOffsetUnits = 0.0f; - mRasterizer.pointDrawMode = false; - mRasterizer.multiSample = false; mScissorTest = false; mScissor.x = 0; mScissor.y = 0; mScissor.width = 0; mScissor.height = 0; - mBlend.blend = false; - mBlend.sourceBlendRGB = GL_ONE; - mBlend.sourceBlendAlpha = GL_ONE; - mBlend.destBlendRGB = GL_ZERO; - mBlend.destBlendAlpha = GL_ZERO; - mBlend.blendEquationRGB = GL_FUNC_ADD; - mBlend.blendEquationAlpha = GL_FUNC_ADD; - mBlend.sampleAlphaToCoverage = false; - mBlend.dither = true; - mBlendColor.red = 0; mBlendColor.green = 0; mBlendColor.blue = 0; mBlendColor.alpha = 0; - mDepthStencil.depthTest = false; - mDepthStencil.depthFunc = GL_LESS; - mDepthStencil.depthMask = true; - mDepthStencil.stencilTest = false; - mDepthStencil.stencilFunc = GL_ALWAYS; - mDepthStencil.stencilMask = static_cast(-1); - mDepthStencil.stencilWritemask = static_cast(-1); - mDepthStencil.stencilBackFunc = GL_ALWAYS; - mDepthStencil.stencilBackMask = static_cast(-1); - mDepthStencil.stencilBackWritemask = static_cast(-1); - mDepthStencil.stencilFail = GL_KEEP; - mDepthStencil.stencilPassDepthFail = GL_KEEP; - mDepthStencil.stencilPassDepthPass = GL_KEEP; - mDepthStencil.stencilBackFail = GL_KEEP; - mDepthStencil.stencilBackPassDepthFail = GL_KEEP; - mDepthStencil.stencilBackPassDepthPass = GL_KEEP; - mStencilRef = 0; mStencilBackRef = 0; mSampleCoverage = false; mSampleCoverageValue = 1.0f; mSampleCoverageInvert = false; + + mMaxSampleMaskWords = caps.maxSampleMaskWords; + mSampleMask = false; + mSampleMaskValues.fill(~GLbitfield(0)); + mGenerateMipmapHint = GL_DONT_CARE; mFragmentShaderDerivativeHint = GL_DONT_CARE; + mBindGeneratesResource = bindGeneratesResource; + mClientArraysEnabled = clientArraysEnabled; + mLineWidth = 1.0f; mViewport.x = 0; @@ -167,23 +142,48 @@ void State::initialize(const Caps &caps, mVertexAttribCurrentValues.resize(caps.maxVertexAttributes); - mUniformBuffers.resize(caps.maxCombinedUniformBlocks); + mUniformBuffers.resize(caps.maxUniformBufferBindings); mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits); mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits); - if (clientVersion >= 3) + if (clientVersion >= Version(3, 0)) { // TODO: These could also be enabled via extension mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits); mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits); } + if (clientVersion >= Version(3, 1)) + { + mSamplerTextures[GL_TEXTURE_2D_MULTISAMPLE].resize(caps.maxCombinedTextureImageUnits); + + mAtomicCounterBuffers.resize(caps.maxAtomicCounterBufferBindings); + mShaderStorageBuffers.resize(caps.maxShaderStorageBufferBindings); + mImageUnits.resize(caps.maxImageUnits); + } + if (nativeExtensions.textureRectangle) + { + mSamplerTextures[GL_TEXTURE_RECTANGLE_ANGLE].resize(caps.maxCombinedTextureImageUnits); + } + if (nativeExtensions.eglImageExternal || nativeExtensions.eglStreamConsumerExternal) + { + mSamplerTextures[GL_TEXTURE_EXTERNAL_OES].resize(caps.maxCombinedTextureImageUnits); + } + mCompleteTextureCache.resize(caps.maxCombinedTextureImageUnits, nullptr); + mCompleteTextureBindings.reserve(caps.maxCombinedTextureImageUnits); + mCachedTexturesInitState = InitState::MayNeedInit; + for (uint32_t textureIndex = 0; textureIndex < caps.maxCombinedTextureImageUnits; + ++textureIndex) + { + mCompleteTextureBindings.emplace_back(OnAttachmentDirtyBinding(this, textureIndex)); + } mSamplers.resize(caps.maxCombinedTextureImageUnits); - mActiveQueries[GL_ANY_SAMPLES_PASSED].set(nullptr); - mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(nullptr); - mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(nullptr); - mActiveQueries[GL_TIME_ELAPSED_EXT].set(nullptr); + mActiveQueries[GL_ANY_SAMPLES_PASSED].set(context, nullptr); + mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(context, nullptr); + mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(context, nullptr); + mActiveQueries[GL_TIME_ELAPSED_EXT].set(context, nullptr); + mActiveQueries[GL_COMMANDS_COMPLETED_CHROMIUM].set(context, nullptr); mProgram = nullptr; @@ -194,52 +194,89 @@ void State::initialize(const Caps &caps, mDebug.setOutputEnabled(debug); mDebug.setMaxLoggedMessages(extensions.maxDebugLoggedMessages); + + mMultiSampling = true; + mSampleAlphaToOne = false; + + mCoverageModulation = GL_NONE; + + angle::Matrix::setToIdentity(mPathMatrixProj); + angle::Matrix::setToIdentity(mPathMatrixMV); + mPathStencilFunc = GL_ALWAYS; + mPathStencilRef = 0; + mPathStencilMask = std::numeric_limits::max(); + + mRobustResourceInit = robustResourceInit; + mProgramBinaryCacheEnabled = programBinaryCacheEnabled; } -void State::reset() +void State::reset(const Context *context) { - for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++) + for (auto &bindingVec : mSamplerTextures) { - TextureBindingVector &textureVector = bindingVec->second; + TextureBindingVector &textureVector = bindingVec.second; for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++) { - textureVector[textureIdx].set(NULL); + textureVector[textureIdx].set(context, nullptr); } } for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++) { - mSamplers[samplerIdx].set(NULL); + mSamplers[samplerIdx].set(context, nullptr); } - mArrayBuffer.set(NULL); - mRenderbuffer.set(NULL); + for (auto &imageUnit : mImageUnits) + { + imageUnit.texture.set(context, nullptr); + imageUnit.level = 0; + imageUnit.layered = false; + imageUnit.layer = 0; + imageUnit.access = GL_READ_ONLY; + imageUnit.format = GL_R32UI; + } + + mRenderbuffer.set(context, nullptr); + + for (auto type : angle::AllEnums()) + { + mBoundBuffers[type].set(context, nullptr); + } if (mProgram) { - mProgram->release(); + mProgram->release(context); } - mProgram = NULL; + mProgram = nullptr; - mTransformFeedback.set(NULL); + mProgramPipeline.set(context, nullptr); + + mTransformFeedback.set(context, nullptr); for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++) { - i->second.set(NULL); + i->second.set(context, nullptr); } - mGenericUniformBuffer.set(NULL); - for (BufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr) + for (auto &buf : mUniformBuffers) { - bufItr->set(NULL); + buf.set(context, nullptr); } - mCopyReadBuffer.set(NULL); - mCopyWriteBuffer.set(NULL); + for (auto &buf : mAtomicCounterBuffers) + { + buf.set(context, nullptr); + } - mPack.pixelBuffer.set(NULL); - mUnpack.pixelBuffer.set(NULL); + for (auto &buf : mShaderStorageBuffers) + { + buf.set(context, nullptr); + } - mProgram = NULL; + angle::Matrix::setToIdentity(mPathMatrixProj); + angle::Matrix::setToIdentity(mPathMatrixMV); + mPathStencilFunc = GL_ALWAYS; + mPathStencilRef = 0; + mPathStencilMask = std::numeric_limits::max(); // TODO(jmadill): Is this necessary? setAllDirtyBits(); @@ -318,7 +355,7 @@ void State::setCullFace(bool enabled) mDirtyBits.set(DIRTY_BIT_CULL_FACE_ENABLED); } -void State::setCullMode(GLenum mode) +void State::setCullMode(CullFaceMode mode) { mRasterizer.cullMode = mode; mDirtyBits.set(DIRTY_BIT_CULL_FACE); @@ -528,6 +565,58 @@ bool State::getSampleCoverageInvert() const return mSampleCoverageInvert; } +bool State::isSampleMaskEnabled() const +{ + return mSampleMask; +} + +void State::setSampleMaskEnabled(bool enabled) +{ + mSampleMask = enabled; + mDirtyBits.set(DIRTY_BIT_SAMPLE_MASK_ENABLED); +} + +void State::setSampleMaskParams(GLuint maskNumber, GLbitfield mask) +{ + ASSERT(maskNumber < mMaxSampleMaskWords); + mSampleMaskValues[maskNumber] = mask; + // TODO(jmadill): Use a child dirty bit if we ever use more than two words. + mDirtyBits.set(DIRTY_BIT_SAMPLE_MASK); +} + +GLbitfield State::getSampleMaskWord(GLuint maskNumber) const +{ + ASSERT(maskNumber < mMaxSampleMaskWords); + return mSampleMaskValues[maskNumber]; +} + +GLuint State::getMaxSampleMaskWords() const +{ + return mMaxSampleMaskWords; +} + +void State::setSampleAlphaToOne(bool enabled) +{ + mSampleAlphaToOne = enabled; + mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_ONE); +} + +bool State::isSampleAlphaToOneEnabled() const +{ + return mSampleAlphaToOne; +} + +void State::setMultisampling(bool enabled) +{ + mMultiSampling = enabled; + mDirtyBits.set(DIRTY_BIT_MULTISAMPLING); +} + +bool State::isMultisamplingEnabled() const +{ + return mMultiSampling; +} + bool State::isScissorTestEnabled() const { return mScissorTest; @@ -579,6 +668,8 @@ void State::setEnableFeature(GLenum feature, bool enabled) { switch (feature) { + case GL_MULTISAMPLE_EXT: setMultisampling(enabled); break; + case GL_SAMPLE_ALPHA_TO_ONE_EXT: setSampleAlphaToOne(enabled); break; case GL_CULL_FACE: setCullFace(enabled); break; case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break; case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break; @@ -590,20 +681,28 @@ void State::setEnableFeature(GLenum feature, bool enabled) case GL_DITHER: setDither(enabled); break; case GL_PRIMITIVE_RESTART_FIXED_INDEX: setPrimitiveRestart(enabled); break; case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break; + case GL_SAMPLE_MASK: + setSampleMaskEnabled(enabled); + break; case GL_DEBUG_OUTPUT_SYNCHRONOUS: mDebug.setOutputSynchronous(enabled); break; case GL_DEBUG_OUTPUT: mDebug.setOutputEnabled(enabled); break; + case GL_FRAMEBUFFER_SRGB_EXT: + setFramebufferSRGB(enabled); + break; default: UNREACHABLE(); } } -bool State::getEnableFeature(GLenum feature) +bool State::getEnableFeature(GLenum feature) const { switch (feature) { + case GL_MULTISAMPLE_EXT: return isMultisamplingEnabled(); + case GL_SAMPLE_ALPHA_TO_ONE_EXT: return isSampleAlphaToOneEnabled(); case GL_CULL_FACE: return isCullFaceEnabled(); case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled(); case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled(); @@ -615,11 +714,26 @@ bool State::getEnableFeature(GLenum feature) case GL_DITHER: return isDitherEnabled(); case GL_PRIMITIVE_RESTART_FIXED_INDEX: return isPrimitiveRestartEnabled(); case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled(); + case GL_SAMPLE_MASK: + return isSampleMaskEnabled(); case GL_DEBUG_OUTPUT_SYNCHRONOUS: return mDebug.isOutputSynchronous(); case GL_DEBUG_OUTPUT: return mDebug.isOutputEnabled(); - default: UNREACHABLE(); return false; + case GL_BIND_GENERATES_RESOURCE_CHROMIUM: + return isBindGeneratesResourceEnabled(); + case GL_CLIENT_ARRAYS_ANGLE: + return areClientArraysEnabled(); + case GL_FRAMEBUFFER_SRGB_EXT: + return getFramebufferSRGB(); + case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: + return mRobustResourceInit; + case GL_PROGRAM_CACHE_ENABLED_ANGLE: + return mProgramBinaryCacheEnabled; + + default: + UNREACHABLE(); + return false; } } @@ -649,6 +763,16 @@ void State::setFragmentShaderDerivativeHint(GLenum hint) // Ignore for now. It is valid for implementations to ignore hint. } +bool State::isBindGeneratesResourceEnabled() const +{ + return mBindGeneratesResource; +} + +bool State::areClientArraysEnabled() const +{ + return mClientArraysEnabled; +} + void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height) { mViewport.x = x; @@ -673,9 +797,11 @@ unsigned int State::getActiveSampler() const return static_cast(mActiveSampler); } -void State::setSamplerTexture(GLenum type, Texture *texture) +void State::setSamplerTexture(const Context *context, GLenum type, Texture *texture) { - mSamplerTextures[type][mActiveSampler].set(texture); + mSamplerTextures[type][mActiveSampler].set(context, texture); + mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS); + mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES); } Texture *State::getTargetTexture(GLenum target) const @@ -699,7 +825,7 @@ GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const return it->second[sampler].id(); } -void State::detachTexture(const TextureMap &zeroTextures, GLuint texture) +void State::detachTexture(const Context *context, const TextureMap &zeroTextures, GLuint texture) { // Textures have a detach method on State rather than a simple // removeBinding, because the zero/null texture objects are managed @@ -710,40 +836,54 @@ void State::detachTexture(const TextureMap &zeroTextures, GLuint texture) // If a texture object is deleted, it is as if all texture units which are bound to that texture object are // rebound to texture object zero - for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++) + for (auto &bindingVec : mSamplerTextures) { - GLenum textureType = bindingVec->first; - TextureBindingVector &textureVector = bindingVec->second; - for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++) + GLenum textureType = bindingVec.first; + TextureBindingVector &textureVector = bindingVec.second; + for (BindingPointer &binding : textureVector) { - BindingPointer &binding = textureVector[textureIdx]; if (binding.id() == texture) { auto it = zeroTextures.find(textureType); ASSERT(it != zeroTextures.end()); // Zero textures are the "default" textures instead of NULL - binding.set(it->second.get()); + binding.set(context, it->second.get()); + mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS); } } } + for (auto &bindingImageUnit : mImageUnits) + { + if (bindingImageUnit.texture.id() == texture) + { + bindingImageUnit.texture.set(context, nullptr); + bindingImageUnit.level = 0; + bindingImageUnit.layered = false; + bindingImageUnit.layer = 0; + bindingImageUnit.access = GL_READ_ONLY; + bindingImageUnit.format = GL_R32UI; + break; + } + } + // [OpenGL ES 2.0.24] section 4.4 page 112: // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this // image was attached in the currently bound framebuffer. - if (mReadFramebuffer) + if (mReadFramebuffer && mReadFramebuffer->detachTexture(context, texture)) { - mReadFramebuffer->detachTexture(texture); + mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER); } - if (mDrawFramebuffer) + if (mDrawFramebuffer && mDrawFramebuffer->detachTexture(context, texture)) { - mDrawFramebuffer->detachTexture(texture); + mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER); } } -void State::initializeZeroTextures(const TextureMap &zeroTextures) +void State::initializeZeroTextures(const Context *context, const TextureMap &zeroTextures) { for (const auto &zeroTexture : zeroTextures) { @@ -751,14 +891,16 @@ void State::initializeZeroTextures(const TextureMap &zeroTextures) for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit) { - samplerTextureArray[textureUnit].set(zeroTexture.second.get()); + samplerTextureArray[textureUnit].set(context, zeroTexture.second.get()); } } } -void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler) +void State::setSamplerBinding(const Context *context, GLuint textureUnit, Sampler *sampler) { - mSamplers[textureUnit].set(sampler); + mSamplers[textureUnit].set(context, sampler); + mDirtyBits.set(DIRTY_BIT_SAMPLER_BINDINGS); + mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES); } GLuint State::getSamplerId(GLuint textureUnit) const @@ -772,25 +914,26 @@ Sampler *State::getSampler(GLuint textureUnit) const return mSamplers[textureUnit].get(); } -void State::detachSampler(GLuint sampler) +void State::detachSampler(const Context *context, GLuint sampler) { // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124: // If a sampler object that is currently bound to one or more texture units is // deleted, it is as though BindSampler is called once for each texture unit to // which the sampler is bound, with unit set to the texture unit and sampler set to zero. - for (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++) + for (BindingPointer &samplerBinding : mSamplers) { - BindingPointer &samplerBinding = mSamplers[textureUnit]; if (samplerBinding.id() == sampler) { - samplerBinding.set(NULL); + samplerBinding.set(context, nullptr); + mDirtyBits.set(DIRTY_BIT_SAMPLER_BINDINGS); } } } -void State::setRenderbufferBinding(Renderbuffer *renderbuffer) +void State::setRenderbufferBinding(const Context *context, Renderbuffer *renderbuffer) { - mRenderbuffer.set(renderbuffer); + mRenderbuffer.set(context, renderbuffer); + mDirtyBits.set(DIRTY_BIT_RENDERBUFFER_BINDING); } GLuint State::getRenderbufferId() const @@ -798,12 +941,12 @@ GLuint State::getRenderbufferId() const return mRenderbuffer.id(); } -Renderbuffer *State::getCurrentRenderbuffer() +Renderbuffer *State::getCurrentRenderbuffer() const { return mRenderbuffer.get(); } -void State::detachRenderbuffer(GLuint renderbuffer) +void State::detachRenderbuffer(const Context *context, GLuint renderbuffer) { // [OpenGL ES 2.0.24] section 4.4 page 109: // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer @@ -811,7 +954,7 @@ void State::detachRenderbuffer(GLuint renderbuffer) if (mRenderbuffer.id() == renderbuffer) { - mRenderbuffer.set(NULL); + setRenderbufferBinding(context, nullptr); } // [OpenGL ES 2.0.24] section 4.4 page 111: @@ -822,14 +965,17 @@ void State::detachRenderbuffer(GLuint renderbuffer) Framebuffer *readFramebuffer = mReadFramebuffer; Framebuffer *drawFramebuffer = mDrawFramebuffer; - if (readFramebuffer) + if (readFramebuffer && readFramebuffer->detachRenderbuffer(context, renderbuffer)) { - readFramebuffer->detachRenderbuffer(renderbuffer); + mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER); } if (drawFramebuffer && drawFramebuffer != readFramebuffer) { - drawFramebuffer->detachRenderbuffer(renderbuffer); + if (drawFramebuffer->detachRenderbuffer(context, renderbuffer)) + { + mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER); + } } } @@ -873,26 +1019,16 @@ Framebuffer *State::getTargetFramebuffer(GLenum target) const return mDrawFramebuffer; default: UNREACHABLE(); - return NULL; + return nullptr; } } -Framebuffer *State::getReadFramebuffer() +Framebuffer *State::getReadFramebuffer() const { return mReadFramebuffer; } -Framebuffer *State::getDrawFramebuffer() -{ - return mDrawFramebuffer; -} - -const Framebuffer *State::getReadFramebuffer() const -{ - return mReadFramebuffer; -} - -const Framebuffer *State::getDrawFramebuffer() const +Framebuffer *State::getDrawFramebuffer() const { return mDrawFramebuffer; } @@ -934,13 +1070,13 @@ void State::setVertexArrayBinding(VertexArray *vertexArray) GLuint State::getVertexArrayId() const { - ASSERT(mVertexArray != NULL); + ASSERT(mVertexArray != nullptr); return mVertexArray->id(); } VertexArray *State::getVertexArray() const { - ASSERT(mVertexArray != NULL); + ASSERT(mVertexArray != nullptr); return mVertexArray; } @@ -948,7 +1084,7 @@ bool State::removeVertexArrayBinding(GLuint vertexArray) { if (mVertexArray->id() == vertexArray) { - mVertexArray = NULL; + mVertexArray = nullptr; mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING); mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); return true; @@ -957,13 +1093,47 @@ bool State::removeVertexArrayBinding(GLuint vertexArray) return false; } -void State::setProgram(Program *newProgram) +void State::bindVertexBuffer(const Context *context, + GLuint bindingIndex, + Buffer *boundBuffer, + GLintptr offset, + GLsizei stride) +{ + getVertexArray()->bindVertexBuffer(context, bindingIndex, boundBuffer, offset, stride); + mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); +} + +void State::setVertexAttribBinding(const Context *context, GLuint attribIndex, GLuint bindingIndex) +{ + getVertexArray()->setVertexAttribBinding(context, attribIndex, bindingIndex); + mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); +} + +void State::setVertexAttribFormat(GLuint attribIndex, + GLint size, + GLenum type, + bool normalized, + bool pureInteger, + GLuint relativeOffset) +{ + getVertexArray()->setVertexAttribFormat(attribIndex, size, type, normalized, pureInteger, + relativeOffset); + mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); +} + +void State::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor) +{ + getVertexArray()->setVertexBindingDivisor(bindingIndex, divisor); + mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); +} + +void State::setProgram(const Context *context, Program *newProgram) { if (mProgram != newProgram) { if (mProgram) { - mProgram->release(); + mProgram->release(context); } mProgram = newProgram; @@ -971,7 +1141,10 @@ void State::setProgram(Program *newProgram) if (mProgram) { newProgram->addRef(); + mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES); } + mDirtyBits.set(DIRTY_BIT_PROGRAM_EXECUTABLE); + mDirtyBits.set(DIRTY_BIT_PROGRAM_BINDING); } } @@ -980,9 +1153,10 @@ Program *State::getProgram() const return mProgram; } -void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback) +void State::setTransformFeedbackBinding(const Context *context, + TransformFeedback *transformFeedback) { - mTransformFeedback.set(transformFeedback); + mTransformFeedback.set(context, transformFeedback); } TransformFeedback *State::getCurrentTransformFeedback() const @@ -992,23 +1166,37 @@ TransformFeedback *State::getCurrentTransformFeedback() const bool State::isTransformFeedbackActiveUnpaused() const { - gl::TransformFeedback *curTransformFeedback = getCurrentTransformFeedback(); + TransformFeedback *curTransformFeedback = getCurrentTransformFeedback(); return curTransformFeedback && curTransformFeedback->isActive() && !curTransformFeedback->isPaused(); } -void State::detachTransformFeedback(GLuint transformFeedback) +bool State::removeTransformFeedbackBinding(const Context *context, GLuint transformFeedback) { if (mTransformFeedback.id() == transformFeedback) { - mTransformFeedback.set(NULL); + mTransformFeedback.set(context, nullptr); + return true; } + + return false; } -bool State::isQueryActive() const +void State::setProgramPipelineBinding(const Context *context, ProgramPipeline *pipeline) +{ + mProgramPipeline.set(context, pipeline); +} + +void State::detachProgramPipeline(const Context *context, GLuint pipeline) +{ + mProgramPipeline.set(context, nullptr); +} + +bool State::isQueryActive(const GLenum type) const { for (auto &iter : mActiveQueries) { - if (iter.second.get() != NULL) + const Query *query = iter.second.get(); + if (query != nullptr && ActiveQueryType(query->getType()) == ActiveQueryType(type)) { return true; } @@ -1030,9 +1218,9 @@ bool State::isQueryActive(Query *query) const return false; } -void State::setActiveQuery(GLenum target, Query *query) +void State::setActiveQuery(const Context *context, GLenum target, Query *query) { - mActiveQueries[target].set(query); + mActiveQueries[target].set(context, query); } GLuint State::getActiveQueryId(GLenum target) const @@ -1051,24 +1239,64 @@ Query *State::getActiveQuery(GLenum target) const return it->second.get(); } -void State::setArrayBufferBinding(Buffer *buffer) +void State::setBufferBinding(const Context *context, BufferBinding target, Buffer *buffer) { - mArrayBuffer.set(buffer); + switch (target) + { + case BufferBinding::PixelPack: + mBoundBuffers[target].set(context, buffer); + mDirtyBits.set(DIRTY_BIT_PACK_BUFFER_BINDING); + break; + case BufferBinding::PixelUnpack: + mBoundBuffers[target].set(context, buffer); + mDirtyBits.set(DIRTY_BIT_UNPACK_BUFFER_BINDING); + break; + case BufferBinding::DrawIndirect: + mBoundBuffers[target].set(context, buffer); + mDirtyBits.set(DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING); + break; + case BufferBinding::TransformFeedback: + if (mTransformFeedback.get() != nullptr) + { + mTransformFeedback->bindGenericBuffer(context, buffer); + } + break; + case BufferBinding::ElementArray: + getVertexArray()->setElementArrayBuffer(context, buffer); + mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); + break; + default: + mBoundBuffers[target].set(context, buffer); + break; + } } - -GLuint State::getArrayBufferId() const +void State::setIndexedBufferBinding(const Context *context, + BufferBinding target, + GLuint index, + Buffer *buffer, + GLintptr offset, + GLsizeiptr size) { - return mArrayBuffer.id(); -} + setBufferBinding(context, target, buffer); -void State::setGenericUniformBufferBinding(Buffer *buffer) -{ - mGenericUniformBuffer.set(buffer); -} - -void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size) -{ - mUniformBuffers[index].set(buffer, offset, size); + switch (target) + { + case BufferBinding::TransformFeedback: + mTransformFeedback->bindIndexedBuffer(context, index, buffer, offset, size); + break; + case BufferBinding::Uniform: + mUniformBuffers[index].set(context, buffer, offset, size); + break; + case BufferBinding::AtomicCounter: + mAtomicCounterBuffers[index].set(context, buffer, offset, size); + break; + case BufferBinding::ShaderStorage: + mShaderStorageBuffers[index].set(context, buffer, offset, size); + break; + default: + UNREACHABLE(); + break; + } } const OffsetBindingPointer &State::getIndexedUniformBuffer(size_t index) const @@ -1077,62 +1305,48 @@ const OffsetBindingPointer &State::getIndexedUniformBuffer(size_t index) return mUniformBuffers[index]; } -void State::setCopyReadBufferBinding(Buffer *buffer) +const OffsetBindingPointer &State::getIndexedAtomicCounterBuffer(size_t index) const { - mCopyReadBuffer.set(buffer); + ASSERT(static_cast(index) < mAtomicCounterBuffers.size()); + return mAtomicCounterBuffers[index]; } -void State::setCopyWriteBufferBinding(Buffer *buffer) +const OffsetBindingPointer &State::getIndexedShaderStorageBuffer(size_t index) const { - mCopyWriteBuffer.set(buffer); + ASSERT(static_cast(index) < mShaderStorageBuffers.size()); + return mShaderStorageBuffers[index]; } -void State::setPixelPackBufferBinding(Buffer *buffer) -{ - mPack.pixelBuffer.set(buffer); -} - -void State::setPixelUnpackBufferBinding(Buffer *buffer) -{ - mUnpack.pixelBuffer.set(buffer); -} - -Buffer *State::getTargetBuffer(GLenum target) const +Buffer *State::getTargetBuffer(BufferBinding target) const { switch (target) { - case GL_ARRAY_BUFFER: return mArrayBuffer.get(); - case GL_COPY_READ_BUFFER: return mCopyReadBuffer.get(); - case GL_COPY_WRITE_BUFFER: return mCopyWriteBuffer.get(); - case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer().get(); - case GL_PIXEL_PACK_BUFFER: return mPack.pixelBuffer.get(); - case GL_PIXEL_UNPACK_BUFFER: return mUnpack.pixelBuffer.get(); - case GL_TRANSFORM_FEEDBACK_BUFFER: return mTransformFeedback->getGenericBuffer().get(); - case GL_UNIFORM_BUFFER: return mGenericUniformBuffer.get(); - default: UNREACHABLE(); return NULL; + case BufferBinding::ElementArray: + return getVertexArray()->getElementArrayBuffer().get(); + case BufferBinding::TransformFeedback: + return mTransformFeedback->getGenericBuffer().get(); + default: + return mBoundBuffers[target].get(); } } -void State::detachBuffer(GLuint bufferName) +void State::detachBuffer(const Context *context, GLuint bufferName) { - BindingPointer *buffers[] = {&mArrayBuffer, &mCopyReadBuffer, - &mCopyWriteBuffer, &mPack.pixelBuffer, - &mUnpack.pixelBuffer, &mGenericUniformBuffer}; - for (auto buffer : buffers) + for (auto &buffer : mBoundBuffers) { - if (buffer->id() == bufferName) + if (buffer.id() == bufferName) { - buffer->set(nullptr); + buffer.set(context, nullptr); } } TransformFeedback *curTransformFeedback = getCurrentTransformFeedback(); if (curTransformFeedback) { - curTransformFeedback->detachBuffer(bufferName); + curTransformFeedback->detachBuffer(context, bufferName); } - getVertexArray()->detachBuffer(bufferName); + getVertexArray()->detachBuffer(context, bufferName); } void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled) @@ -1145,48 +1359,58 @@ void State::setVertexAttribf(GLuint index, const GLfloat values[4]) { ASSERT(static_cast(index) < mVertexAttribCurrentValues.size()); mVertexAttribCurrentValues[index].setFloatValues(values); - mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index); + mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES); + mDirtyCurrentValues.set(index); } void State::setVertexAttribu(GLuint index, const GLuint values[4]) { ASSERT(static_cast(index) < mVertexAttribCurrentValues.size()); mVertexAttribCurrentValues[index].setUnsignedIntValues(values); - mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index); + mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES); + mDirtyCurrentValues.set(index); } void State::setVertexAttribi(GLuint index, const GLint values[4]) { ASSERT(static_cast(index) < mVertexAttribCurrentValues.size()); mVertexAttribCurrentValues[index].setIntValues(values); - mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index); + mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES); + mDirtyCurrentValues.set(index); } -void State::setVertexAttribState(unsigned int attribNum, - Buffer *boundBuffer, - GLint size, - GLenum type, - bool normalized, - bool pureInteger, - GLsizei stride, - const void *pointer) +void State::setVertexAttribPointer(const Context *context, + unsigned int attribNum, + Buffer *boundBuffer, + GLint size, + GLenum type, + bool normalized, + bool pureInteger, + GLsizei stride, + const void *pointer) { - getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer); + getVertexArray()->setVertexAttribPointer(context, attribNum, boundBuffer, size, type, + normalized, pureInteger, stride, pointer); mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); } -void State::setVertexAttribDivisor(GLuint index, GLuint divisor) +void State::setVertexAttribDivisor(const Context *context, GLuint index, GLuint divisor) { - getVertexArray()->setVertexAttribDivisor(index, divisor); + getVertexArray()->setVertexAttribDivisor(context, index, divisor); mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); } -const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const +const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(size_t attribNum) const { - ASSERT(static_cast(attribNum) < mVertexAttribCurrentValues.size()); + ASSERT(attribNum < mVertexAttribCurrentValues.size()); return mVertexAttribCurrentValues[attribNum]; } +const std::vector &State::getVertexAttribCurrentValues() const +{ + return mVertexAttribCurrentValues; +} + const void *State::getVertexAttribPointer(unsigned int attribNum) const { return getVertexArray()->getVertexAttribute(attribNum).pointer; @@ -1195,7 +1419,7 @@ const void *State::getVertexAttribPointer(unsigned int attribNum) const void State::setPackAlignment(GLint alignment) { mPack.alignment = alignment; - mDirtyBits.set(DIRTY_BIT_PACK_ALIGNMENT); + mDirtyBits.set(DIRTY_BIT_PACK_STATE); } GLint State::getPackAlignment() const @@ -1206,7 +1430,7 @@ GLint State::getPackAlignment() const void State::setPackReverseRowOrder(bool reverseRowOrder) { mPack.reverseRowOrder = reverseRowOrder; - mDirtyBits.set(DIRTY_BIT_PACK_REVERSE_ROW_ORDER); + mDirtyBits.set(DIRTY_BIT_PACK_STATE); } bool State::getPackReverseRowOrder() const @@ -1217,7 +1441,7 @@ bool State::getPackReverseRowOrder() const void State::setPackRowLength(GLint rowLength) { mPack.rowLength = rowLength; - mDirtyBits.set(DIRTY_BIT_PACK_ROW_LENGTH); + mDirtyBits.set(DIRTY_BIT_PACK_STATE); } GLint State::getPackRowLength() const @@ -1228,7 +1452,7 @@ GLint State::getPackRowLength() const void State::setPackSkipRows(GLint skipRows) { mPack.skipRows = skipRows; - mDirtyBits.set(DIRTY_BIT_PACK_SKIP_ROWS); + mDirtyBits.set(DIRTY_BIT_PACK_STATE); } GLint State::getPackSkipRows() const @@ -1239,7 +1463,7 @@ GLint State::getPackSkipRows() const void State::setPackSkipPixels(GLint skipPixels) { mPack.skipPixels = skipPixels; - mDirtyBits.set(DIRTY_BIT_PACK_SKIP_PIXELS); + mDirtyBits.set(DIRTY_BIT_PACK_STATE); } GLint State::getPackSkipPixels() const @@ -1260,7 +1484,7 @@ PixelPackState &State::getPackState() void State::setUnpackAlignment(GLint alignment) { mUnpack.alignment = alignment; - mDirtyBits.set(DIRTY_BIT_UNPACK_ALIGNMENT); + mDirtyBits.set(DIRTY_BIT_UNPACK_STATE); } GLint State::getUnpackAlignment() const @@ -1271,7 +1495,7 @@ GLint State::getUnpackAlignment() const void State::setUnpackRowLength(GLint rowLength) { mUnpack.rowLength = rowLength; - mDirtyBits.set(DIRTY_BIT_UNPACK_ROW_LENGTH); + mDirtyBits.set(DIRTY_BIT_UNPACK_STATE); } GLint State::getUnpackRowLength() const @@ -1282,7 +1506,7 @@ GLint State::getUnpackRowLength() const void State::setUnpackImageHeight(GLint imageHeight) { mUnpack.imageHeight = imageHeight; - mDirtyBits.set(DIRTY_BIT_UNPACK_IMAGE_HEIGHT); + mDirtyBits.set(DIRTY_BIT_UNPACK_STATE); } GLint State::getUnpackImageHeight() const @@ -1293,7 +1517,7 @@ GLint State::getUnpackImageHeight() const void State::setUnpackSkipImages(GLint skipImages) { mUnpack.skipImages = skipImages; - mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_IMAGES); + mDirtyBits.set(DIRTY_BIT_UNPACK_STATE); } GLint State::getUnpackSkipImages() const @@ -1304,7 +1528,7 @@ GLint State::getUnpackSkipImages() const void State::setUnpackSkipRows(GLint skipRows) { mUnpack.skipRows = skipRows; - mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_ROWS); + mDirtyBits.set(DIRTY_BIT_UNPACK_STATE); } GLint State::getUnpackSkipRows() const @@ -1315,7 +1539,7 @@ GLint State::getUnpackSkipRows() const void State::setUnpackSkipPixels(GLint skipPixels) { mUnpack.skipPixels = skipPixels; - mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_PIXELS); + mDirtyBits.set(DIRTY_BIT_UNPACK_STATE); } GLint State::getUnpackSkipPixels() const @@ -1343,6 +1567,84 @@ Debug &State::getDebug() return mDebug; } +void State::setCoverageModulation(GLenum components) +{ + mCoverageModulation = components; + mDirtyBits.set(DIRTY_BIT_COVERAGE_MODULATION); +} + +GLenum State::getCoverageModulation() const +{ + return mCoverageModulation; +} + +void State::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix) +{ + if (matrixMode == GL_PATH_MODELVIEW_CHROMIUM) + { + memcpy(mPathMatrixMV, matrix, 16 * sizeof(GLfloat)); + mDirtyBits.set(DIRTY_BIT_PATH_RENDERING_MATRIX_MV); + } + else if (matrixMode == GL_PATH_PROJECTION_CHROMIUM) + { + memcpy(mPathMatrixProj, matrix, 16 * sizeof(GLfloat)); + mDirtyBits.set(DIRTY_BIT_PATH_RENDERING_MATRIX_PROJ); + } + else + { + UNREACHABLE(); + } +} + +const GLfloat *State::getPathRenderingMatrix(GLenum which) const +{ + if (which == GL_PATH_MODELVIEW_MATRIX_CHROMIUM) + { + return mPathMatrixMV; + } + else if (which == GL_PATH_PROJECTION_MATRIX_CHROMIUM) + { + return mPathMatrixProj; + } + + UNREACHABLE(); + return nullptr; +} + +void State::setPathStencilFunc(GLenum func, GLint ref, GLuint mask) +{ + mPathStencilFunc = func; + mPathStencilRef = ref; + mPathStencilMask = mask; + mDirtyBits.set(DIRTY_BIT_PATH_RENDERING_STENCIL_STATE); +} + +GLenum State::getPathStencilFunc() const +{ + return mPathStencilFunc; +} + +GLint State::getPathStencilRef() const +{ + return mPathStencilRef; +} + +GLuint State::getPathStencilMask() const +{ + return mPathStencilMask; +} + +void State::setFramebufferSRGB(bool sRGB) +{ + mFramebufferSRGB = sRGB; + mDirtyBits.set(DIRTY_BIT_FRAMEBUFFER_SRGB); +} + +bool State::getFramebufferSRGB() const +{ + return mFramebufferSRGB; +} + void State::getBooleanv(GLenum pname, GLboolean *params) { switch (pname) @@ -1355,10 +1657,15 @@ void State::getBooleanv(GLenum pname, GLboolean *params) params[2] = mBlend.colorMaskBlue; params[3] = mBlend.colorMaskAlpha; break; - case GL_CULL_FACE: *params = mRasterizer.cullFace; break; + case GL_CULL_FACE: + *params = mRasterizer.cullFace; + break; case GL_POLYGON_OFFSET_FILL: *params = mRasterizer.polygonOffsetFill; break; case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mBlend.sampleAlphaToCoverage; break; case GL_SAMPLE_COVERAGE: *params = mSampleCoverage; break; + case GL_SAMPLE_MASK: + *params = mSampleMask; + break; case GL_SCISSOR_TEST: *params = mScissorTest; break; case GL_STENCIL_TEST: *params = mDepthStencil.stencilTest; break; case GL_DEPTH_TEST: *params = mDepthStencil.depthTest; break; @@ -1378,6 +1685,28 @@ void State::getBooleanv(GLenum pname, GLboolean *params) case GL_DEBUG_OUTPUT: *params = mDebug.isOutputEnabled() ? GL_TRUE : GL_FALSE; break; + case GL_MULTISAMPLE_EXT: + *params = mMultiSampling; + break; + case GL_SAMPLE_ALPHA_TO_ONE_EXT: + *params = mSampleAlphaToOne; + break; + case GL_BIND_GENERATES_RESOURCE_CHROMIUM: + *params = isBindGeneratesResourceEnabled() ? GL_TRUE : GL_FALSE; + break; + case GL_CLIENT_ARRAYS_ANGLE: + *params = areClientArraysEnabled() ? GL_TRUE : GL_FALSE; + break; + case GL_FRAMEBUFFER_SRGB_EXT: + *params = getFramebufferSRGB() ? GL_TRUE : GL_FALSE; + break; + case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: + *params = mRobustResourceInit ? GL_TRUE : GL_FALSE; + break; + case GL_PROGRAM_CACHE_ENABLED_ANGLE: + *params = mProgramBinaryCacheEnabled ? GL_TRUE : GL_FALSE; + break; + default: UNREACHABLE(); break; @@ -1413,13 +1742,21 @@ void State::getFloatv(GLenum pname, GLfloat *params) params[2] = mBlendColor.blue; params[3] = mBlendColor.alpha; break; + case GL_MULTISAMPLE_EXT: + *params = static_cast(mMultiSampling); + break; + case GL_SAMPLE_ALPHA_TO_ONE_EXT: + *params = static_cast(mSampleAlphaToOne); + case GL_COVERAGE_MODULATION_CHROMIUM: + params[0] = static_cast(mCoverageModulation); + break; default: UNREACHABLE(); break; } } -void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params) +void State::getIntegerv(const Context *context, GLenum pname, GLint *params) { if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT) { @@ -1437,8 +1774,15 @@ void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params) // State::getFloatv. switch (pname) { - case GL_ARRAY_BUFFER_BINDING: *params = mArrayBuffer.id(); break; - case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getVertexArray()->getElementArrayBuffer().id(); break; + case GL_ARRAY_BUFFER_BINDING: + *params = mBoundBuffers[BufferBinding::Array].id(); + break; + case GL_DRAW_INDIRECT_BUFFER_BINDING: + *params = mBoundBuffers[BufferBinding::DrawIndirect].id(); + break; + case GL_ELEMENT_ARRAY_BUFFER_BINDING: + *params = getVertexArray()->getElementArrayBuffer().id(); + break; //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mDrawFramebuffer->id(); break; case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break; @@ -1477,10 +1821,14 @@ void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params) break; case GL_STENCIL_FUNC: *params = mDepthStencil.stencilFunc; break; case GL_STENCIL_REF: *params = mStencilRef; break; - case GL_STENCIL_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilMask); break; + case GL_STENCIL_VALUE_MASK: + *params = CastMaskValue(context, mDepthStencil.stencilMask); + break; case GL_STENCIL_BACK_FUNC: *params = mDepthStencil.stencilBackFunc; break; case GL_STENCIL_BACK_REF: *params = mStencilBackRef; break; - case GL_STENCIL_BACK_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilBackMask); break; + case GL_STENCIL_BACK_VALUE_MASK: + *params = CastMaskValue(context, mDepthStencil.stencilBackMask); + break; case GL_STENCIL_FAIL: *params = mDepthStencil.stencilFail; break; case GL_STENCIL_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilPassDepthFail; break; case GL_STENCIL_PASS_DEPTH_PASS: *params = mDepthStencil.stencilPassDepthPass; break; @@ -1494,32 +1842,40 @@ void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params) case GL_BLEND_DST_ALPHA: *params = mBlend.destBlendAlpha; break; case GL_BLEND_EQUATION_RGB: *params = mBlend.blendEquationRGB; break; case GL_BLEND_EQUATION_ALPHA: *params = mBlend.blendEquationAlpha; break; - case GL_STENCIL_WRITEMASK: *params = clampToInt(mDepthStencil.stencilWritemask); break; - case GL_STENCIL_BACK_WRITEMASK: *params = clampToInt(mDepthStencil.stencilBackWritemask); break; + case GL_STENCIL_WRITEMASK: + *params = CastMaskValue(context, mDepthStencil.stencilWritemask); + break; + case GL_STENCIL_BACK_WRITEMASK: + *params = CastMaskValue(context, mDepthStencil.stencilBackWritemask); + break; case GL_STENCIL_CLEAR_VALUE: *params = mStencilClearValue; break; - case GL_IMPLEMENTATION_COLOR_READ_TYPE: *params = mReadFramebuffer->getImplementationColorReadType(); break; - case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = mReadFramebuffer->getImplementationColorReadFormat(); break; + case GL_IMPLEMENTATION_COLOR_READ_TYPE: + *params = mReadFramebuffer->getImplementationColorReadType(context); + break; + case GL_IMPLEMENTATION_COLOR_READ_FORMAT: + *params = mReadFramebuffer->getImplementationColorReadFormat(context); + break; case GL_SAMPLE_BUFFERS: case GL_SAMPLES: { - gl::Framebuffer *framebuffer = mDrawFramebuffer; - if (framebuffer->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE) + Framebuffer *framebuffer = mDrawFramebuffer; + if (framebuffer->checkStatus(context) == GL_FRAMEBUFFER_COMPLETE) { switch (pname) { - case GL_SAMPLE_BUFFERS: - if (framebuffer->getSamples(data) != 0) - { - *params = 1; - } - else - { - *params = 0; - } - break; - case GL_SAMPLES: - *params = framebuffer->getSamples(data); - break; + case GL_SAMPLE_BUFFERS: + if (framebuffer->getSamples(context) != 0) + { + *params = 1; + } + else + { + *params = 0; + } + break; + case GL_SAMPLES: + *params = framebuffer->getSamples(context); + break; } } else @@ -1540,15 +1896,19 @@ void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params) params[2] = mScissor.width; params[3] = mScissor.height; break; - case GL_CULL_FACE_MODE: *params = mRasterizer.cullMode; break; - case GL_FRONT_FACE: *params = mRasterizer.frontFace; break; + case GL_CULL_FACE_MODE: + *params = ToGLenum(mRasterizer.cullMode); + break; + case GL_FRONT_FACE: + *params = mRasterizer.frontFace; + break; case GL_RED_BITS: case GL_GREEN_BITS: case GL_BLUE_BITS: case GL_ALPHA_BITS: { - gl::Framebuffer *framebuffer = getDrawFramebuffer(); - const gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer(); + Framebuffer *framebuffer = getDrawFramebuffer(); + const FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer(); if (colorbuffer) { @@ -1568,8 +1928,8 @@ void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params) break; case GL_DEPTH_BITS: { - const gl::Framebuffer *framebuffer = getDrawFramebuffer(); - const gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer(); + const Framebuffer *framebuffer = getDrawFramebuffer(); + const FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer(); if (depthbuffer) { @@ -1583,8 +1943,8 @@ void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params) break; case GL_STENCIL_BITS: { - const gl::Framebuffer *framebuffer = getDrawFramebuffer(); - const gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer(); + const Framebuffer *framebuffer = getDrawFramebuffer(); + const FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer(); if (stencilbuffer) { @@ -1600,6 +1960,11 @@ void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params) ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits); *params = getSamplerTextureId(static_cast(mActiveSampler), GL_TEXTURE_2D); break; + case GL_TEXTURE_BINDING_RECTANGLE_ANGLE: + ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits); + *params = getSamplerTextureId(static_cast(mActiveSampler), + GL_TEXTURE_RECTANGLE_ANGLE); + break; case GL_TEXTURE_BINDING_CUBE_MAP: ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits); *params = @@ -1614,27 +1979,45 @@ void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params) *params = getSamplerTextureId(static_cast(mActiveSampler), GL_TEXTURE_2D_ARRAY); break; + case GL_TEXTURE_BINDING_2D_MULTISAMPLE: + ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits); + *params = getSamplerTextureId(static_cast(mActiveSampler), + GL_TEXTURE_2D_MULTISAMPLE); + break; + case GL_TEXTURE_BINDING_EXTERNAL_OES: + ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits); + *params = getSamplerTextureId(static_cast(mActiveSampler), + GL_TEXTURE_EXTERNAL_OES); + break; case GL_UNIFORM_BUFFER_BINDING: - *params = mGenericUniformBuffer.id(); - break; + *params = mBoundBuffers[BufferBinding::Uniform].id(); + break; case GL_TRANSFORM_FEEDBACK_BINDING: *params = mTransformFeedback.id(); break; case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: - *params = mTransformFeedback->getGenericBuffer().id(); - break; + ASSERT(mTransformFeedback.get() != nullptr); + *params = mTransformFeedback->getGenericBuffer().id(); + break; case GL_COPY_READ_BUFFER_BINDING: - *params = mCopyReadBuffer.id(); - break; + *params = mBoundBuffers[BufferBinding::CopyRead].id(); + break; case GL_COPY_WRITE_BUFFER_BINDING: - *params = mCopyWriteBuffer.id(); - break; + *params = mBoundBuffers[BufferBinding::CopyWrite].id(); + break; case GL_PIXEL_PACK_BUFFER_BINDING: - *params = mPack.pixelBuffer.id(); - break; + *params = mBoundBuffers[BufferBinding::PixelPack].id(); + break; case GL_PIXEL_UNPACK_BUFFER_BINDING: - *params = mUnpack.pixelBuffer.id(); - break; + *params = mBoundBuffers[BufferBinding::PixelUnpack].id(); + break; + case GL_READ_BUFFER: + *params = mReadFramebuffer->getReadBufferState(); + break; + case GL_SAMPLER_BINDING: + ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits); + *params = getSamplerId(static_cast(mActiveSampler)); + break; case GL_DEBUG_LOGGED_MESSAGES: *params = static_cast(mDebug.getMessageCount()); break; @@ -1644,6 +2027,20 @@ void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params) case GL_DEBUG_GROUP_STACK_DEPTH: *params = static_cast(mDebug.getGroupStackDepth()); break; + case GL_MULTISAMPLE_EXT: + *params = static_cast(mMultiSampling); + break; + case GL_SAMPLE_ALPHA_TO_ONE_EXT: + *params = static_cast(mSampleAlphaToOne); + case GL_COVERAGE_MODULATION_CHROMIUM: + *params = static_cast(mCoverageModulation); + break; + case GL_ATOMIC_COUNTER_BUFFER_BINDING: + *params = mBoundBuffers[BufferBinding::AtomicCounter].id(); + break; + case GL_SHADER_STORAGE_BUFFER_BINDING: + *params = mBoundBuffers[BufferBinding::ShaderStorage].id(); + break; default: UNREACHABLE(); break; @@ -1666,75 +2063,111 @@ void State::getPointerv(GLenum pname, void **params) const } } -bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data) +void State::getIntegeri_v(GLenum target, GLuint index, GLint *data) { switch (target) { case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: - if (static_cast(index) < mTransformFeedback->getIndexedBufferCount()) - { - *data = mTransformFeedback->getIndexedBuffer(index).id(); - } - break; + ASSERT(static_cast(index) < mTransformFeedback->getIndexedBufferCount()); + *data = mTransformFeedback->getIndexedBuffer(index).id(); + break; case GL_UNIFORM_BUFFER_BINDING: - if (static_cast(index) < mUniformBuffers.size()) - { - *data = mUniformBuffers[index].id(); - } - break; + ASSERT(static_cast(index) < mUniformBuffers.size()); + *data = mUniformBuffers[index].id(); + break; + case GL_ATOMIC_COUNTER_BUFFER_BINDING: + ASSERT(static_cast(index) < mAtomicCounterBuffers.size()); + *data = mAtomicCounterBuffers[index].id(); + break; + case GL_SHADER_STORAGE_BUFFER_BINDING: + ASSERT(static_cast(index) < mShaderStorageBuffers.size()); + *data = mShaderStorageBuffers[index].id(); + break; + case GL_VERTEX_BINDING_BUFFER: + ASSERT(static_cast(index) < mVertexArray->getMaxBindings()); + *data = mVertexArray->getVertexBinding(index).getBuffer().id(); + break; + case GL_VERTEX_BINDING_DIVISOR: + ASSERT(static_cast(index) < mVertexArray->getMaxBindings()); + *data = mVertexArray->getVertexBinding(index).getDivisor(); + break; + case GL_VERTEX_BINDING_OFFSET: + ASSERT(static_cast(index) < mVertexArray->getMaxBindings()); + *data = static_cast(mVertexArray->getVertexBinding(index).getOffset()); + break; + case GL_VERTEX_BINDING_STRIDE: + ASSERT(static_cast(index) < mVertexArray->getMaxBindings()); + *data = mVertexArray->getVertexBinding(index).getStride(); + break; + case GL_SAMPLE_MASK_VALUE: + ASSERT(static_cast(index) < mSampleMaskValues.size()); + *data = mSampleMaskValues[index]; + break; default: - return false; + UNREACHABLE(); + break; } - - return true; } -bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data) +void State::getInteger64i_v(GLenum target, GLuint index, GLint64 *data) { switch (target) { case GL_TRANSFORM_FEEDBACK_BUFFER_START: - if (static_cast(index) < mTransformFeedback->getIndexedBufferCount()) - { - *data = mTransformFeedback->getIndexedBuffer(index).getOffset(); - } - break; + ASSERT(static_cast(index) < mTransformFeedback->getIndexedBufferCount()); + *data = mTransformFeedback->getIndexedBuffer(index).getOffset(); + break; case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: - if (static_cast(index) < mTransformFeedback->getIndexedBufferCount()) - { - *data = mTransformFeedback->getIndexedBuffer(index).getSize(); - } - break; + ASSERT(static_cast(index) < mTransformFeedback->getIndexedBufferCount()); + *data = mTransformFeedback->getIndexedBuffer(index).getSize(); + break; case GL_UNIFORM_BUFFER_START: - if (static_cast(index) < mUniformBuffers.size()) - { - *data = mUniformBuffers[index].getOffset(); - } - break; + ASSERT(static_cast(index) < mUniformBuffers.size()); + *data = mUniformBuffers[index].getOffset(); + break; case GL_UNIFORM_BUFFER_SIZE: - if (static_cast(index) < mUniformBuffers.size()) - { - *data = mUniformBuffers[index].getSize(); - } - break; + ASSERT(static_cast(index) < mUniformBuffers.size()); + *data = mUniformBuffers[index].getSize(); + break; + case GL_ATOMIC_COUNTER_BUFFER_START: + ASSERT(static_cast(index) < mAtomicCounterBuffers.size()); + *data = mAtomicCounterBuffers[index].getOffset(); + break; + case GL_ATOMIC_COUNTER_BUFFER_SIZE: + ASSERT(static_cast(index) < mAtomicCounterBuffers.size()); + *data = mAtomicCounterBuffers[index].getSize(); + break; + case GL_SHADER_STORAGE_BUFFER_START: + ASSERT(static_cast(index) < mShaderStorageBuffers.size()); + *data = mShaderStorageBuffers[index].getOffset(); + break; + case GL_SHADER_STORAGE_BUFFER_SIZE: + ASSERT(static_cast(index) < mShaderStorageBuffers.size()); + *data = mShaderStorageBuffers[index].getSize(); + break; default: - return false; + UNREACHABLE(); + break; } - - return true; } -bool State::hasMappedBuffer(GLenum target) const +void State::getBooleani_v(GLenum target, GLuint index, GLboolean *data) { - if (target == GL_ARRAY_BUFFER) + UNREACHABLE(); +} + +bool State::hasMappedBuffer(BufferBinding target) const +{ + if (target == BufferBinding::Array) { - const VertexArray *vao = getVertexArray(); + const VertexArray *vao = getVertexArray(); const auto &vertexAttribs = vao->getVertexAttributes(); + const auto &vertexBindings = vao->getVertexBindings(); size_t maxEnabledAttrib = vao->getMaxEnabledAttribute(); for (size_t attribIndex = 0; attribIndex < maxEnabledAttrib; attribIndex++) { - const gl::VertexAttribute &vertexAttrib = vertexAttribs[attribIndex]; - gl::Buffer *boundBuffer = vertexAttrib.buffer.get(); + const VertexAttribute &vertexAttrib = vertexAttribs[attribIndex]; + auto *boundBuffer = vertexBindings[vertexAttrib.bindingIndex].getBuffer().get(); if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped()) { return true; @@ -1750,35 +2183,36 @@ bool State::hasMappedBuffer(GLenum target) const } } -void State::syncDirtyObjects() +void State::syncDirtyObjects(const Context *context) { if (!mDirtyObjects.any()) return; - syncDirtyObjects(mDirtyObjects); + syncDirtyObjects(context, mDirtyObjects); } -void State::syncDirtyObjects(const DirtyObjects &bitset) +void State::syncDirtyObjects(const Context *context, const DirtyObjects &bitset) { - for (auto dirtyObject : angle::IterateBitSet(bitset)) + for (auto dirtyObject : bitset) { switch (dirtyObject) { case DIRTY_OBJECT_READ_FRAMEBUFFER: ASSERT(mReadFramebuffer); - mReadFramebuffer->syncState(); + mReadFramebuffer->syncState(context); break; case DIRTY_OBJECT_DRAW_FRAMEBUFFER: ASSERT(mDrawFramebuffer); - mDrawFramebuffer->syncState(); + mDrawFramebuffer->syncState(context); break; case DIRTY_OBJECT_VERTEX_ARRAY: ASSERT(mVertexArray); - mVertexArray->syncImplState(); + mVertexArray->syncState(context); break; - case DIRTY_OBJECT_PROGRAM: - // TODO(jmadill): implement this + case DIRTY_OBJECT_PROGRAM_TEXTURES: + syncProgramTextures(context); break; + default: UNREACHABLE(); break; @@ -1788,7 +2222,82 @@ void State::syncDirtyObjects(const DirtyObjects &bitset) mDirtyObjects &= ~bitset; } -void State::syncDirtyObject(GLenum target) +void State::syncProgramTextures(const Context *context) +{ + // TODO(jmadill): Fine-grained updates. + if (!mProgram) + { + return; + } + + ASSERT(mDirtyObjects[DIRTY_OBJECT_PROGRAM_TEXTURES]); + mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS); + + ActiveTextureMask newActiveTextures; + + // Initialize to the 'Initialized' state and set to 'MayNeedInit' if any texture is not + // initialized. + mCachedTexturesInitState = InitState::Initialized; + + for (const SamplerBinding &samplerBinding : mProgram->getSamplerBindings()) + { + if (samplerBinding.unreferenced) + continue; + + GLenum textureType = samplerBinding.textureType; + for (GLuint textureUnitIndex : samplerBinding.boundTextureUnits) + { + Texture *texture = getSamplerTexture(textureUnitIndex, textureType); + Sampler *sampler = getSampler(textureUnitIndex); + ASSERT(static_cast(textureUnitIndex) < mCompleteTextureCache.size()); + ASSERT(static_cast(textureUnitIndex) < newActiveTextures.size()); + + ASSERT(texture); + + // Mark the texture binding bit as dirty if the texture completeness changes. + // TODO(jmadill): Use specific dirty bit for completeness change. + if (texture->isSamplerComplete(context, sampler) && + !mDrawFramebuffer->hasTextureAttachment(texture)) + { + texture->syncState(); + mCompleteTextureCache[textureUnitIndex] = texture; + } + else + { + mCompleteTextureCache[textureUnitIndex] = nullptr; + } + + // Bind the texture unconditionally, to recieve completeness change notifications. + mCompleteTextureBindings[textureUnitIndex].bind(texture->getDirtyChannel()); + mActiveTexturesMask.set(textureUnitIndex); + newActiveTextures.set(textureUnitIndex); + + if (sampler != nullptr) + { + sampler->syncState(context); + } + + if (texture->initState() == InitState::MayNeedInit) + { + mCachedTexturesInitState = InitState::MayNeedInit; + } + } + } + + // Unset now missing textures. + ActiveTextureMask negativeMask = mActiveTexturesMask & ~newActiveTextures; + if (negativeMask.any()) + { + for (auto textureIndex : negativeMask) + { + mCompleteTextureBindings[textureIndex].reset(); + mCompleteTextureCache[textureIndex] = nullptr; + mActiveTexturesMask.reset(textureIndex); + } + } +} + +void State::syncDirtyObject(const Context *context, GLenum target) { DirtyObjects localSet; @@ -1807,12 +2316,14 @@ void State::syncDirtyObject(GLenum target) case GL_VERTEX_ARRAY: localSet.set(DIRTY_OBJECT_VERTEX_ARRAY); break; + case GL_TEXTURE: + case GL_SAMPLER: case GL_PROGRAM: - localSet.set(DIRTY_OBJECT_PROGRAM); + localSet.set(DIRTY_OBJECT_PROGRAM_TEXTURES); break; } - syncDirtyObjects(localSet); + syncDirtyObjects(context, localSet); } void State::setObjectDirty(GLenum target) @@ -1832,10 +2343,91 @@ void State::setObjectDirty(GLenum target) case GL_VERTEX_ARRAY: mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY); break; + case GL_TEXTURE: + case GL_SAMPLER: case GL_PROGRAM: - mDirtyObjects.set(DIRTY_OBJECT_PROGRAM); + mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES); + mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS); break; } } +void State::onProgramExecutableChange(Program *program) +{ + // OpenGL Spec: + // "If LinkProgram or ProgramBinary successfully re-links a program object + // that was already in use as a result of a previous call to UseProgram, then the + // generated executable code will be installed as part of the current rendering state." + if (program->isLinked() && mProgram == program) + { + mDirtyBits.set(DIRTY_BIT_PROGRAM_EXECUTABLE); + mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES); + } +} + +void State::setImageUnit(const Context *context, + GLuint unit, + Texture *texture, + GLint level, + GLboolean layered, + GLint layer, + GLenum access, + GLenum format) +{ + mImageUnits[unit].texture.set(context, texture); + mImageUnits[unit].level = level; + mImageUnits[unit].layered = layered; + mImageUnits[unit].layer = layer; + mImageUnits[unit].access = access; + mImageUnits[unit].format = format; +} + +const ImageUnit &State::getImageUnit(GLuint unit) const +{ + return mImageUnits[unit]; +} + +// Handle a dirty texture event. +void State::signal(size_t textureIndex, InitState initState) +{ + // Conservatively assume all textures are dirty. + // TODO(jmadill): More fine-grained update. + mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES); + + if (initState == InitState::MayNeedInit) + { + mCachedTexturesInitState = InitState::MayNeedInit; + } +} + +Error State::clearUnclearedActiveTextures(const Context *context) +{ + ASSERT(mRobustResourceInit); + + if (mCachedTexturesInitState == InitState::Initialized) + { + return NoError(); + } + + for (auto textureIndex : mActiveTexturesMask) + { + Texture *texture = mCompleteTextureCache[textureIndex]; + if (texture) + { + ANGLE_TRY(texture->ensureInitialized(context)); + } + } + + mCachedTexturesInitState = InitState::Initialized; + + return NoError(); +} + +AttributesMask State::getAndResetDirtyCurrentValues() const +{ + AttributesMask retVal = mDirtyCurrentValues; + mDirtyCurrentValues.reset(); + return retVal; +} + } // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/State.h b/src/3rdparty/angle/src/libANGLE/State.h index e822d7e679..52e1d78382 100644 --- a/src/3rdparty/angle/src/libANGLE/State.h +++ b/src/3rdparty/angle/src/libANGLE/State.h @@ -12,14 +12,18 @@ #include #include +#include "common/Color.h" #include "common/angleutils.h" +#include "common/bitset_utils.h" #include "libANGLE/Debug.h" #include "libANGLE/Program.h" +#include "libANGLE/ProgramPipeline.h" #include "libANGLE/RefCountObject.h" #include "libANGLE/Renderbuffer.h" #include "libANGLE/Sampler.h" #include "libANGLE/Texture.h" #include "libANGLE/TransformFeedback.h" +#include "libANGLE/Version.h" #include "libANGLE/VertexAttribute.h" #include "libANGLE/angletypes.h" @@ -29,21 +33,20 @@ class Query; class VertexArray; class Context; struct Caps; -struct Data; -typedef std::map> TextureMap; - -class State : angle::NonCopyable +class State : public OnAttachmentDirtyReceiver, angle::NonCopyable { public: State(); - ~State(); + ~State() override; - void initialize(const Caps &caps, - const Extensions &extensions, - GLuint clientVersion, - bool debug); - void reset(); + void initialize(const Context *context, + bool debug, + bool bindGeneratesResource, + bool clientArraysEnabled, + bool robustResourceInit, + bool programBinaryCacheEnabled); + void reset(const Context *context); // State chunk getters const RasterizerState &getRasterizerState() const; @@ -74,7 +77,7 @@ class State : angle::NonCopyable // Face culling state manipulation bool isCullFaceEnabled() const; void setCullFace(bool enabled); - void setCullMode(GLenum mode); + void setCullMode(CullFaceMode mode); void setFrontFace(GLenum front); // Depth test state manipulation @@ -100,8 +103,12 @@ class State : angle::NonCopyable void setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask); void setStencilWritemask(GLuint stencilWritemask); void setStencilBackWritemask(GLuint stencilBackWritemask); - void setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass); - void setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass); + void setStencilOperations(GLenum stencilFail, + GLenum stencilPassDepthFail, + GLenum stencilPassDepthPass); + void setStencilBackOperations(GLenum stencilBackFail, + GLenum stencilBackPassDepthFail, + GLenum stencilBackPassDepthPass); GLint getStencilRef() const; GLint getStencilBackRef() const; @@ -116,9 +123,22 @@ class State : angle::NonCopyable bool isSampleCoverageEnabled() const; void setSampleCoverage(bool enabled); void setSampleCoverageParams(GLclampf value, bool invert); - GLclampf getSampleCoverageValue() const; + GLfloat getSampleCoverageValue() const; bool getSampleCoverageInvert() const; + // Multisample mask state manipulation. + bool isSampleMaskEnabled() const; + void setSampleMaskEnabled(bool enabled); + void setSampleMaskParams(GLuint maskNumber, GLbitfield mask); + GLbitfield getSampleMaskWord(GLuint maskNumber) const; + GLuint getMaxSampleMaskWords() const; + + // Multisampling/alpha to one manipulation. + void setSampleAlphaToOne(bool enabled); + bool isSampleAlphaToOneEnabled() const; + void setMultisampling(bool enabled); + bool isMultisamplingEnabled() const; + // Scissor test state toggle & query bool isScissorTestEnabled() const; void setScissorTest(bool enabled); @@ -131,7 +151,7 @@ class State : angle::NonCopyable // Generic state toggle & query void setEnableFeature(GLenum feature, bool enabled); - bool getEnableFeature(GLenum feature); + bool getEnableFeature(GLenum feature) const; // Line width state setter void setLineWidth(GLfloat width); @@ -141,6 +161,12 @@ class State : angle::NonCopyable void setGenerateMipmapHint(GLenum hint); void setFragmentShaderDerivativeHint(GLenum hint); + // GL_CHROMIUM_bind_generates_resource + bool isBindGeneratesResourceEnabled() const; + + // GL_ANGLE_client_arrays + bool areClientArraysEnabled() const; + // Viewport state setter/getter void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height); const Rectangle &getViewport() const; @@ -148,33 +174,31 @@ class State : angle::NonCopyable // Texture binding & active texture unit manipulation void setActiveSampler(unsigned int active); unsigned int getActiveSampler() const; - void setSamplerTexture(GLenum type, Texture *texture); + void setSamplerTexture(const Context *context, GLenum type, Texture *texture); Texture *getTargetTexture(GLenum target) const; Texture *getSamplerTexture(unsigned int sampler, GLenum type) const; GLuint getSamplerTextureId(unsigned int sampler, GLenum type) const; - void detachTexture(const TextureMap &zeroTextures, GLuint texture); - void initializeZeroTextures(const TextureMap &zeroTextures); + void detachTexture(const Context *context, const TextureMap &zeroTextures, GLuint texture); + void initializeZeroTextures(const Context *context, const TextureMap &zeroTextures); // Sampler object binding manipulation - void setSamplerBinding(GLuint textureUnit, Sampler *sampler); + void setSamplerBinding(const Context *context, GLuint textureUnit, Sampler *sampler); GLuint getSamplerId(GLuint textureUnit) const; Sampler *getSampler(GLuint textureUnit) const; - void detachSampler(GLuint sampler); + void detachSampler(const Context *context, GLuint sampler); // Renderbuffer binding manipulation - void setRenderbufferBinding(Renderbuffer *renderbuffer); + void setRenderbufferBinding(const Context *context, Renderbuffer *renderbuffer); GLuint getRenderbufferId() const; - Renderbuffer *getCurrentRenderbuffer(); - void detachRenderbuffer(GLuint renderbuffer); + Renderbuffer *getCurrentRenderbuffer() const; + void detachRenderbuffer(const Context *context, GLuint renderbuffer); // Framebuffer binding manipulation void setReadFramebufferBinding(Framebuffer *framebuffer); void setDrawFramebufferBinding(Framebuffer *framebuffer); Framebuffer *getTargetFramebuffer(GLenum target) const; - Framebuffer *getReadFramebuffer(); - Framebuffer *getDrawFramebuffer(); - const Framebuffer *getReadFramebuffer() const; - const Framebuffer *getDrawFramebuffer() const; + Framebuffer *getReadFramebuffer() const; + Framebuffer *getDrawFramebuffer() const; bool removeReadFramebufferBinding(GLuint framebuffer); bool removeDrawFramebufferBinding(GLuint framebuffer); @@ -185,55 +209,75 @@ class State : angle::NonCopyable bool removeVertexArrayBinding(GLuint vertexArray); // Program binding manipulation - void setProgram(Program *newProgram); + void setProgram(const Context *context, Program *newProgram); Program *getProgram() const; // Transform feedback object (not buffer) binding manipulation - void setTransformFeedbackBinding(TransformFeedback *transformFeedback); + void setTransformFeedbackBinding(const Context *context, TransformFeedback *transformFeedback); TransformFeedback *getCurrentTransformFeedback() const; bool isTransformFeedbackActiveUnpaused() const; - void detachTransformFeedback(GLuint transformFeedback); + bool removeTransformFeedbackBinding(const Context *context, GLuint transformFeedback); // Query binding manipulation - bool isQueryActive() const; + bool isQueryActive(const GLenum type) const; bool isQueryActive(Query *query) const; - void setActiveQuery(GLenum target, Query *query); + void setActiveQuery(const Context *context, GLenum target, Query *query); GLuint getActiveQueryId(GLenum target) const; Query *getActiveQuery(GLenum target) const; + // Program Pipeline binding manipulation + void setProgramPipelineBinding(const Context *context, ProgramPipeline *pipeline); + void detachProgramPipeline(const Context *context, GLuint pipeline); + //// Typed buffer binding point manipulation //// - // GL_ARRAY_BUFFER - void setArrayBufferBinding(Buffer *buffer); - GLuint getArrayBufferId() const; + void setBufferBinding(const Context *context, BufferBinding target, Buffer *buffer); + Buffer *getTargetBuffer(BufferBinding target) const; + void setIndexedBufferBinding(const Context *context, + BufferBinding target, + GLuint index, + Buffer *buffer, + GLintptr offset, + GLsizeiptr size); - // GL_UNIFORM_BUFFER - Both indexed and generic targets - void setGenericUniformBufferBinding(Buffer *buffer); - void setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size); const OffsetBindingPointer &getIndexedUniformBuffer(size_t index) const; + const OffsetBindingPointer &getIndexedAtomicCounterBuffer(size_t index) const; + const OffsetBindingPointer &getIndexedShaderStorageBuffer(size_t index) const; - // GL_COPY_[READ/WRITE]_BUFFER - void setCopyReadBufferBinding(Buffer *buffer); - void setCopyWriteBufferBinding(Buffer *buffer); - - // GL_PIXEL[PACK/UNPACK]_BUFFER - void setPixelPackBufferBinding(Buffer *buffer); - void setPixelUnpackBufferBinding(Buffer *buffer); - - // Retrieve typed buffer by target (non-indexed) - Buffer *getTargetBuffer(GLenum target) const; // Detach a buffer from all bindings - void detachBuffer(GLuint bufferName); + void detachBuffer(const Context *context, GLuint bufferName); // Vertex attrib manipulation void setEnableVertexAttribArray(unsigned int attribNum, bool enabled); + void setElementArrayBuffer(const Context *context, Buffer *buffer); void setVertexAttribf(GLuint index, const GLfloat values[4]); void setVertexAttribu(GLuint index, const GLuint values[4]); void setVertexAttribi(GLuint index, const GLint values[4]); - void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, - bool normalized, bool pureInteger, GLsizei stride, const void *pointer); - void setVertexAttribDivisor(GLuint index, GLuint divisor); - const VertexAttribCurrentValueData &getVertexAttribCurrentValue(unsigned int attribNum) const; + void setVertexAttribPointer(const Context *context, + unsigned int attribNum, + Buffer *boundBuffer, + GLint size, + GLenum type, + bool normalized, + bool pureInteger, + GLsizei stride, + const void *pointer); + void setVertexAttribDivisor(const Context *context, GLuint index, GLuint divisor); + const VertexAttribCurrentValueData &getVertexAttribCurrentValue(size_t attribNum) const; + const std::vector &getVertexAttribCurrentValues() const; const void *getVertexAttribPointer(unsigned int attribNum) const; + void bindVertexBuffer(const Context *context, + GLuint bindingIndex, + Buffer *boundBuffer, + GLintptr offset, + GLsizei stride); + void setVertexAttribFormat(GLuint attribIndex, + GLint size, + GLenum type, + bool normalized, + bool pureInteger, + GLuint relativeOffset); + void setVertexAttribBinding(const Context *context, GLuint attribIndex, GLuint bindingIndex); + void setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor); // Pixel pack state manipulation void setPackAlignment(GLint alignment); @@ -269,15 +313,37 @@ class State : angle::NonCopyable const Debug &getDebug() const; Debug &getDebug(); + // CHROMIUM_framebuffer_mixed_samples coverage modulation + void setCoverageModulation(GLenum components); + GLenum getCoverageModulation() const; + + // CHROMIUM_path_rendering + void loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix); + const GLfloat *getPathRenderingMatrix(GLenum which) const; + void setPathStencilFunc(GLenum func, GLint ref, GLuint mask); + + GLenum getPathStencilFunc() const; + GLint getPathStencilRef() const; + GLuint getPathStencilMask() const; + + // GL_EXT_sRGB_write_control + void setFramebufferSRGB(bool sRGB); + bool getFramebufferSRGB() const; + // State query functions void getBooleanv(GLenum pname, GLboolean *params); void getFloatv(GLenum pname, GLfloat *params); - void getIntegerv(const gl::Data &data, GLenum pname, GLint *params); + void getIntegerv(const Context *context, GLenum pname, GLint *params); void getPointerv(GLenum pname, void **params) const; - bool getIndexedIntegerv(GLenum target, GLuint index, GLint *data); - bool getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data); + void getIntegeri_v(GLenum target, GLuint index, GLint *data); + void getInteger64i_v(GLenum target, GLuint index, GLint64 *data); + void getBooleani_v(GLenum target, GLuint index, GLboolean *data); - bool hasMappedBuffer(GLenum target) const; + bool hasMappedBuffer(BufferBinding target) const; + bool isRobustResourceInitEnabled() const { return mRobustResourceInit; } + + // Sets the dirty bit for the program executable. + void onProgramExecutableChange(Program *program); enum DirtyBitType { @@ -293,6 +359,8 @@ class State : angle::NonCopyable DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED, DIRTY_BIT_SAMPLE_COVERAGE_ENABLED, DIRTY_BIT_SAMPLE_COVERAGE, + DIRTY_BIT_SAMPLE_MASK_ENABLED, + DIRTY_BIT_SAMPLE_MASK, DIRTY_BIT_DEPTH_TEST_ENABLED, DIRTY_BIT_DEPTH_FUNC, DIRTY_BIT_DEPTH_MASK, @@ -314,17 +382,10 @@ class State : angle::NonCopyable DIRTY_BIT_CLEAR_COLOR, DIRTY_BIT_CLEAR_DEPTH, DIRTY_BIT_CLEAR_STENCIL, - DIRTY_BIT_UNPACK_ALIGNMENT, - DIRTY_BIT_UNPACK_ROW_LENGTH, - DIRTY_BIT_UNPACK_IMAGE_HEIGHT, - DIRTY_BIT_UNPACK_SKIP_IMAGES, - DIRTY_BIT_UNPACK_SKIP_ROWS, - DIRTY_BIT_UNPACK_SKIP_PIXELS, - DIRTY_BIT_PACK_ALIGNMENT, - DIRTY_BIT_PACK_REVERSE_ROW_ORDER, - DIRTY_BIT_PACK_ROW_LENGTH, - DIRTY_BIT_PACK_SKIP_ROWS, - DIRTY_BIT_PACK_SKIP_PIXELS, + DIRTY_BIT_UNPACK_STATE, + DIRTY_BIT_UNPACK_BUFFER_BINDING, + DIRTY_BIT_PACK_STATE, + DIRTY_BIT_PACK_BUFFER_BINDING, DIRTY_BIT_DITHER_ENABLED, DIRTY_BIT_GENERATE_MIPMAP_HINT, DIRTY_BIT_SHADER_DERIVATIVE_HINT, @@ -332,51 +393,83 @@ class State : angle::NonCopyable DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING, DIRTY_BIT_RENDERBUFFER_BINDING, DIRTY_BIT_VERTEX_ARRAY_BINDING, + DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING, DIRTY_BIT_PROGRAM_BINDING, - DIRTY_BIT_CURRENT_VALUE_0, - DIRTY_BIT_CURRENT_VALUE_MAX = DIRTY_BIT_CURRENT_VALUE_0 + MAX_VERTEX_ATTRIBS, - DIRTY_BIT_INVALID = DIRTY_BIT_CURRENT_VALUE_MAX, - DIRTY_BIT_MAX = DIRTY_BIT_INVALID, + DIRTY_BIT_PROGRAM_EXECUTABLE, + // TODO(jmadill): Fine-grained dirty bits for each texture/sampler. + DIRTY_BIT_TEXTURE_BINDINGS, + DIRTY_BIT_SAMPLER_BINDINGS, + DIRTY_BIT_MULTISAMPLING, + DIRTY_BIT_SAMPLE_ALPHA_TO_ONE, + DIRTY_BIT_COVERAGE_MODULATION, // CHROMIUM_framebuffer_mixed_samples + DIRTY_BIT_PATH_RENDERING_MATRIX_MV, // CHROMIUM_path_rendering path model view matrix + DIRTY_BIT_PATH_RENDERING_MATRIX_PROJ, // CHROMIUM_path_rendering path projection matrix + DIRTY_BIT_PATH_RENDERING_STENCIL_STATE, + DIRTY_BIT_FRAMEBUFFER_SRGB, // GL_EXT_sRGB_write_control + DIRTY_BIT_CURRENT_VALUES, + DIRTY_BIT_INVALID, + DIRTY_BIT_MAX = DIRTY_BIT_INVALID, }; + static_assert(DIRTY_BIT_MAX <= 64, "State dirty bits must be capped at 64"); + // TODO(jmadill): Consider storing dirty objects in a list instead of by binding. enum DirtyObjectType { DIRTY_OBJECT_READ_FRAMEBUFFER, DIRTY_OBJECT_DRAW_FRAMEBUFFER, DIRTY_OBJECT_VERTEX_ARRAY, - DIRTY_OBJECT_PROGRAM, + // Use a very coarse bit for any program or texture change. + // TODO(jmadill): Fine-grained dirty bits for each texture/sampler. + DIRTY_OBJECT_PROGRAM_TEXTURES, DIRTY_OBJECT_UNKNOWN, DIRTY_OBJECT_MAX = DIRTY_OBJECT_UNKNOWN, }; - typedef std::bitset DirtyBits; + typedef angle::BitSet DirtyBits; const DirtyBits &getDirtyBits() const { return mDirtyBits; } void clearDirtyBits() { mDirtyBits.reset(); } void clearDirtyBits(const DirtyBits &bitset) { mDirtyBits &= ~bitset; } void setAllDirtyBits() { mDirtyBits.set(); } - typedef std::bitset DirtyObjects; + typedef angle::BitSet DirtyObjects; void clearDirtyObjects() { mDirtyObjects.reset(); } void setAllDirtyObjects() { mDirtyObjects.set(); } - void syncDirtyObjects(); - void syncDirtyObjects(const DirtyObjects &bitset); - void syncDirtyObject(GLenum target); + void syncDirtyObjects(const Context *context); + void syncDirtyObjects(const Context *context, const DirtyObjects &bitset); + void syncDirtyObject(const Context *context, GLenum target); void setObjectDirty(GLenum target); - // Dirty bit masks - const DirtyBits &unpackStateBitMask() const { return mUnpackStateBitMask; } - const DirtyBits &packStateBitMask() const { return mPackStateBitMask; } - const DirtyBits &clearStateBitMask() const { return mClearStateBitMask; } - const DirtyBits &blitStateBitMask() const { return mBlitStateBitMask; } + // This actually clears the current value dirty bits. + // TODO(jmadill): Pass mutable dirty bits into Impl. + AttributesMask getAndResetDirtyCurrentValues() const; + + void setImageUnit(const Context *context, + GLuint unit, + Texture *texture, + GLint level, + GLboolean layered, + GLint layer, + GLenum access, + GLenum format); + + const ImageUnit &getImageUnit(GLuint unit) const; + const std::vector &getCompleteTextureCache() const { return mCompleteTextureCache; } + + // Handle a dirty texture event. + void signal(size_t textureIndex, InitState initState) override; + + Error clearUnclearedActiveTextures(const Context *context); private: + void syncProgramTextures(const Context *context); + // Cached values from Context's caps GLuint mMaxDrawBuffers; GLuint mMaxCombinedTextureImageUnits; ColorF mColorClearValue; - GLclampf mDepthClearValue; + GLfloat mDepthClearValue; int mStencilClearValue; RasterizerState mRasterizer; @@ -386,8 +479,11 @@ class State : angle::NonCopyable BlendState mBlend; ColorF mBlendColor; bool mSampleCoverage; - GLclampf mSampleCoverageValue; + GLfloat mSampleCoverageValue; bool mSampleCoverageInvert; + bool mSampleMask; + GLuint mMaxSampleMaskWords; + std::array mSampleMaskValues; DepthStencilState mDepthStencil; GLint mStencilRef; @@ -398,59 +494,109 @@ class State : angle::NonCopyable GLenum mGenerateMipmapHint; GLenum mFragmentShaderDerivativeHint; + bool mBindGeneratesResource; + bool mClientArraysEnabled; + Rectangle mViewport; float mNearZ; float mFarZ; - BindingPointer mArrayBuffer; Framebuffer *mReadFramebuffer; Framebuffer *mDrawFramebuffer; BindingPointer mRenderbuffer; Program *mProgram; + BindingPointer mProgramPipeline; typedef std::vector VertexAttribVector; - VertexAttribVector mVertexAttribCurrentValues; // From glVertexAttrib + VertexAttribVector mVertexAttribCurrentValues; // From glVertexAttrib VertexArray *mVertexArray; // Texture and sampler bindings - size_t mActiveSampler; // Active texture unit selector - GL_TEXTURE0 + size_t mActiveSampler; // Active texture unit selector - GL_TEXTURE0 typedef std::vector> TextureBindingVector; typedef std::map TextureBindingMap; TextureBindingMap mSamplerTextures; + // Texture Completeness Caching + // ---------------------------- + // The texture completeness cache uses dirty bits to avoid having to scan the list + // of textures each draw call. This gl::State class implements OnAttachmentDirtyReceiver, + // and keeps an array of bindings to the Texture class. When the Textures are marked dirty, + // they send messages to the State class (and any Framebuffers they're attached to) via the + // State::signal method (see above). Internally this then invalidates the completeness cache. + // + // Note this requires that we also invalidate the completeness cache manually on events like + // re-binding textures/samplers or a change in the program. For more information see the + // signal_utils.h header and the design doc linked there. + + // A cache of complete textures. nullptr indicates unbound or incomplete. + // Don't use BindingPointer because this cache is only valid within a draw call. + // Also stores a notification channel to the texture itself to handle texture change events. + std::vector mCompleteTextureCache; + std::vector mCompleteTextureBindings; + InitState mCachedTexturesInitState; + using ActiveTextureMask = angle::BitSet; + ActiveTextureMask mActiveTexturesMask; + typedef std::vector> SamplerBindingVector; SamplerBindingVector mSamplers; + typedef std::vector ImageUnitVector; + ImageUnitVector mImageUnits; + typedef std::map> ActiveQueryMap; ActiveQueryMap mActiveQueries; - BindingPointer mGenericUniformBuffer; - typedef std::vector> BufferVector; + // Stores the currently bound buffer for each binding point. It has entries for the element + // array buffer and the transform feedback buffer but these should not be used. Instead these + // bind points are respectively owned by current the vertex array object and the current + // transform feedback object. + using BoundBufferMap = angle::PackedEnumMap>; + BoundBufferMap mBoundBuffers; + + using BufferVector = std::vector>; BufferVector mUniformBuffers; + BufferVector mAtomicCounterBuffers; + BufferVector mShaderStorageBuffers; BindingPointer mTransformFeedback; - BindingPointer mCopyReadBuffer; - BindingPointer mCopyWriteBuffer; - + BindingPointer mPixelUnpackBuffer; PixelUnpackState mUnpack; + BindingPointer mPixelPackBuffer; PixelPackState mPack; bool mPrimitiveRestart; Debug mDebug; - DirtyBits mDirtyBits; - DirtyBits mUnpackStateBitMask; - DirtyBits mPackStateBitMask; - DirtyBits mClearStateBitMask; - DirtyBits mBlitStateBitMask; + bool mMultiSampling; + bool mSampleAlphaToOne; + GLenum mCoverageModulation; + + // CHROMIUM_path_rendering + GLfloat mPathMatrixMV[16]; + GLfloat mPathMatrixProj[16]; + GLenum mPathStencilFunc; + GLint mPathStencilRef; + GLuint mPathStencilMask; + + // GL_EXT_sRGB_write_control + bool mFramebufferSRGB; + + // GL_ANGLE_robust_resource_intialization + bool mRobustResourceInit; + + // GL_ANGLE_program_cache_control + bool mProgramBinaryCacheEnabled; + + DirtyBits mDirtyBits; DirtyObjects mDirtyObjects; + mutable AttributesMask mDirtyCurrentValues; }; -} - -#endif // LIBANGLE_STATE_H_ +} // namespace gl +#endif // LIBANGLE_STATE_H_ diff --git a/src/3rdparty/angle/src/libANGLE/Stream.cpp b/src/3rdparty/angle/src/libANGLE/Stream.cpp new file mode 100644 index 0000000000..68279976b7 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/Stream.cpp @@ -0,0 +1,271 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Stream.cpp: Implements the egl::Stream class, representing the stream +// where frames are streamed in. Implements EGLStreanKHR. + +#include "libANGLE/Stream.h" + +#include +#include + +#include "common/debug.h" +#include "common/mathutil.h" +#include "common/platform.h" +#include "common/utilities.h" +#include "libANGLE/Context.h" +#include "libANGLE/Display.h" +#include "libANGLE/renderer/DisplayImpl.h" +#include "libANGLE/renderer/StreamProducerImpl.h" + +namespace egl +{ + +Stream::Stream(Display *display, const AttributeMap &attribs) + : mDisplay(display), + mProducerImplementation(nullptr), + mState(EGL_STREAM_STATE_CREATED_KHR), + mProducerFrame(0), + mConsumerFrame(0), + mConsumerLatency(attribs.getAsInt(EGL_CONSUMER_LATENCY_USEC_KHR, 0)), + mConsumerAcquireTimeout(attribs.getAsInt(EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR, 0)), + mPlaneCount(0), + mConsumerType(ConsumerType::NoConsumer), + mProducerType(ProducerType::NoProducer) +{ + for (auto &plane : mPlanes) + { + plane.textureUnit = -1; + plane.texture = nullptr; + } +} + +Stream::~Stream() +{ + SafeDelete(mProducerImplementation); + for (auto &plane : mPlanes) + { + if (plane.texture != nullptr) + { + plane.texture->releaseStream(); + } + } +} + +void Stream::setConsumerLatency(EGLint latency) +{ + mConsumerLatency = latency; +} + +EGLint Stream::getConsumerLatency() const +{ + return mConsumerLatency; +} + +EGLuint64KHR Stream::getProducerFrame() const +{ + return mProducerFrame; +} + +EGLuint64KHR Stream::getConsumerFrame() const +{ + return mConsumerFrame; +} + +EGLenum Stream::getState() const +{ + return mState; +} + +void Stream::setConsumerAcquireTimeout(EGLint timeout) +{ + mConsumerAcquireTimeout = timeout; +} + +EGLint Stream::getConsumerAcquireTimeout() const +{ + return mConsumerAcquireTimeout; +} + +Stream::ProducerType Stream::getProducerType() const +{ + return mProducerType; +} + +Stream::ConsumerType Stream::getConsumerType() const +{ + return mConsumerType; +} + +EGLint Stream::getPlaneCount() const +{ + return mPlaneCount; +} + +rx::StreamProducerImpl *Stream::getImplementation() +{ + return mProducerImplementation; +} + +Error Stream::createConsumerGLTextureExternal(const AttributeMap &attributes, gl::Context *context) +{ + ASSERT(mState == EGL_STREAM_STATE_CREATED_KHR); + ASSERT(mConsumerType == ConsumerType::NoConsumer); + ASSERT(mProducerType == ProducerType::NoProducer); + ASSERT(context != nullptr); + + const auto &glState = context->getGLState(); + EGLenum bufferType = attributes.getAsInt(EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER); + if (bufferType == EGL_RGB_BUFFER) + { + mPlanes[0].texture = glState.getTargetTexture(GL_TEXTURE_EXTERNAL_OES); + ASSERT(mPlanes[0].texture != nullptr); + mPlanes[0].texture->bindStream(this); + mConsumerType = ConsumerType::GLTextureRGB; + mPlaneCount = 1; + } + else + { + mPlaneCount = attributes.getAsInt(EGL_YUV_NUMBER_OF_PLANES_EXT, 2); + ASSERT(mPlaneCount <= 3); + for (EGLint i = 0; i < mPlaneCount; i++) + { + // Fetch all the textures + mPlanes[i].textureUnit = attributes.getAsInt(EGL_YUV_PLANE0_TEXTURE_UNIT_NV + i, -1); + if (mPlanes[i].textureUnit != EGL_NONE) + { + mPlanes[i].texture = + glState.getSamplerTexture(mPlanes[i].textureUnit, GL_TEXTURE_EXTERNAL_OES); + ASSERT(mPlanes[i].texture != nullptr); + } + } + + // Bind them to the stream + for (EGLint i = 0; i < mPlaneCount; i++) + { + if (mPlanes[i].textureUnit != EGL_NONE) + { + mPlanes[i].texture->bindStream(this); + } + } + mConsumerType = ConsumerType::GLTextureYUV; + } + + mContext = context; + mState = EGL_STREAM_STATE_CONNECTING_KHR; + + return NoError(); +} + +Error Stream::createProducerD3D11TextureNV12(const AttributeMap &attributes) +{ + ASSERT(mState == EGL_STREAM_STATE_CONNECTING_KHR); + ASSERT(mConsumerType == ConsumerType::GLTextureYUV); + ASSERT(mProducerType == ProducerType::NoProducer); + ASSERT(mPlaneCount == 2); + + mProducerImplementation = mDisplay->getImplementation()->createStreamProducerD3DTextureNV12( + mConsumerType, attributes); + mProducerType = ProducerType::D3D11TextureNV12; + mState = EGL_STREAM_STATE_EMPTY_KHR; + + return NoError(); +} + +// Called when the consumer of this stream starts using the stream +Error Stream::consumerAcquire(const gl::Context *context) +{ + ASSERT(mState == EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR || + mState == EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR); + ASSERT(mConsumerType == ConsumerType::GLTextureRGB || + mConsumerType == ConsumerType::GLTextureYUV); + ASSERT(mProducerType == ProducerType::D3D11TextureNV12); + + mState = EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR; + mConsumerFrame++; + + // Bind the planes to the gl textures + for (int i = 0; i < mPlaneCount; i++) + { + if (mPlanes[i].texture != nullptr) + { + ANGLE_TRY(mPlanes[i].texture->acquireImageFromStream( + context, mProducerImplementation->getGLFrameDescription(i))); + } + } + + return NoError(); +} + +Error Stream::consumerRelease(const gl::Context *context) +{ + ASSERT(mState == EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR || + mState == EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR); + ASSERT(mConsumerType == ConsumerType::GLTextureRGB || + mConsumerType == ConsumerType::GLTextureYUV); + ASSERT(mProducerType == ProducerType::D3D11TextureNV12); + + // Release the images + for (int i = 0; i < mPlaneCount; i++) + { + if (mPlanes[i].texture != nullptr) + { + ANGLE_TRY(mPlanes[i].texture->releaseImageFromStream(context)); + } + } + + return NoError(); +} + +bool Stream::isConsumerBoundToContext(const gl::Context *context) const +{ + ASSERT(context != nullptr); + return (context == mContext); +} + +Error Stream::validateD3D11NV12Texture(void *texture) const +{ + ASSERT(mConsumerType == ConsumerType::GLTextureRGB || + mConsumerType == ConsumerType::GLTextureYUV); + ASSERT(mProducerType == ProducerType::D3D11TextureNV12); + ASSERT(mProducerImplementation != nullptr); + + return mProducerImplementation->validateD3DNV12Texture(texture); +} + +Error Stream::postD3D11NV12Texture(void *texture, const AttributeMap &attributes) +{ + ASSERT(mConsumerType == ConsumerType::GLTextureRGB || + mConsumerType == ConsumerType::GLTextureYUV); + ASSERT(mProducerType == ProducerType::D3D11TextureNV12); + + mProducerImplementation->postD3DNV12Texture(texture, attributes); + mProducerFrame++; + + mState = EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR; + + return NoError(); +} + +// This is called when a texture object associated with this stream is destroyed. Even if multiple +// textures are bound, one being destroyed invalidates the stream, so all the remaining textures +// will be released and the stream will be invalidated. +void Stream::releaseTextures() +{ + for (auto &plane : mPlanes) + { + if (plane.texture != nullptr) + { + plane.texture->releaseStream(); + plane.texture = nullptr; + } + } + mConsumerType = ConsumerType::NoConsumer; + mProducerType = ProducerType::NoProducer; + mState = EGL_STREAM_STATE_DISCONNECTED_KHR; +} + +} // namespace egl diff --git a/src/3rdparty/angle/src/libANGLE/Stream.h b/src/3rdparty/angle/src/libANGLE/Stream.h new file mode 100644 index 0000000000..b674c44008 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/Stream.h @@ -0,0 +1,143 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Stream.h: Defines the egl::Stream class, representing the stream +// where frames are streamed in. Implements EGLStreanKHR. + +#ifndef LIBANGLE_STREAM_H_ +#define LIBANGLE_STREAM_H_ + +#include + +#include +#include + +#include "common/angleutils.h" +#include "libANGLE/AttributeMap.h" + +namespace rx +{ +class StreamProducerImpl; +} + +namespace gl +{ +class Context; +class Texture; +} + +namespace egl +{ +class Display; +class Error; +class Thread; + +class Stream final : angle::NonCopyable +{ + public: + Stream(Display *display, const AttributeMap &attribs); + ~Stream(); + + enum class ConsumerType + { + NoConsumer, + GLTextureRGB, + GLTextureYUV, + }; + + enum class ProducerType + { + NoProducer, + D3D11TextureNV12, + }; + + // A GL texture interpretation of a part of a producer frame. For use with GL texture consumers + struct GLTextureDescription + { + unsigned int width; + unsigned int height; + unsigned int internalFormat; + unsigned int mipLevels; + }; + + EGLenum getState() const; + + void setConsumerLatency(EGLint latency); + EGLint getConsumerLatency() const; + + EGLuint64KHR getProducerFrame() const; + EGLuint64KHR getConsumerFrame() const; + + void setConsumerAcquireTimeout(EGLint timeout); + EGLint getConsumerAcquireTimeout() const; + + ConsumerType getConsumerType() const; + ProducerType getProducerType() const; + + EGLint getPlaneCount() const; + + rx::StreamProducerImpl *getImplementation(); + + // Consumer creation methods + Error createConsumerGLTextureExternal(const AttributeMap &attributes, gl::Context *context); + + // Producer creation methods + Error createProducerD3D11TextureNV12(const AttributeMap &attributes); + + // Consumer methods + Error consumerAcquire(const gl::Context *context); + Error consumerRelease(const gl::Context *context); + + // Some consumers are bound to GL contexts. This validates that a given context is bound to the + // stream's consumer + bool isConsumerBoundToContext(const gl::Context *context) const; + + // Producer methods + Error validateD3D11NV12Texture(void *texture) const; + Error postD3D11NV12Texture(void *texture, const AttributeMap &attributes); + + private: + // Associated display + Display *mDisplay; + + // Producer Implementation + rx::StreamProducerImpl *mProducerImplementation; + + // Associated GL context. Note that this is a weak pointer used for validation purposes only, + // and should never be arbitrarily dereferenced without knowing the context still exists as it + // can become dangling at any time. + gl::Context *mContext; + + // EGL defined attributes + EGLint mState; + EGLuint64KHR mProducerFrame; + EGLuint64KHR mConsumerFrame; + EGLint mConsumerLatency; + + // EGL gltexture consumer attributes + EGLint mConsumerAcquireTimeout; + + // EGL gltexture yuv consumer attributes + EGLint mPlaneCount; + struct PlaneTexture + { + EGLint textureUnit; + gl::Texture *texture; + }; + // Texture units and textures for all the planes + std::array mPlanes; + + // Consumer and producer types + ConsumerType mConsumerType; + ProducerType mProducerType; + + // ANGLE-only method, used internally + friend class gl::Texture; + void releaseTextures(); +}; +} // namespace egl + +#endif // LIBANGLE_STREAM_H_ diff --git a/src/3rdparty/angle/src/libANGLE/Surface.cpp b/src/3rdparty/angle/src/libANGLE/Surface.cpp index b5ed0ff5a6..746da03778 100644 --- a/src/3rdparty/angle/src/libANGLE/Surface.cpp +++ b/src/3rdparty/angle/src/libANGLE/Surface.cpp @@ -10,29 +10,44 @@ #include "libANGLE/Surface.h" -#include "libANGLE/Config.h" -#include "libANGLE/Framebuffer.h" -#include "libANGLE/Texture.h" - #include #include +#include "libANGLE/Config.h" +#include "libANGLE/Context.h" +#include "libANGLE/Display.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/Texture.h" +#include "libANGLE/Thread.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/EGLImplFactory.h" + namespace egl { -Surface::Surface(rx::SurfaceImpl *impl, - EGLint surfaceType, - const egl::Config *config, - const AttributeMap &attributes) +SurfaceState::SurfaceState(const egl::Config *configIn, const AttributeMap &attributesIn) + : defaultFramebuffer(nullptr), config(configIn), attributes(attributesIn) +{ +} + +Surface::Surface(EGLint surfaceType, const egl::Config *config, const AttributeMap &attributes) : FramebufferAttachmentObject(), - mImplementation(impl), - mDefaultFramebuffer(nullptr), + mState(config, attributes), + mImplementation(nullptr), mCurrentCount(0), mDestroyed(false), mType(surfaceType), - mConfig(config), mPostSubBufferRequested(false), + mLargestPbuffer(false), + mGLColorspace(EGL_GL_COLORSPACE_LINEAR), + mVGAlphaFormat(EGL_VG_ALPHA_FORMAT_NONPRE), + mVGColorspace(EGL_VG_COLORSPACE_sRGB), + mMipmapTexture(false), + mMipmapLevel(0), + mHorizontalResolution(EGL_UNKNOWN), + mVerticalResolution(EGL_UNKNOWN), + mMultisampleResolve(EGL_MULTISAMPLE_RESOLVE_DEFAULT), mFixedSize(false), mFixedWidth(0), mFixedHeight(0), @@ -41,75 +56,135 @@ Surface::Surface(rx::SurfaceImpl *impl, // FIXME: Determine actual pixel aspect ratio mPixelAspectRatio(static_cast(1.0 * EGL_DISPLAY_SCALING)), mRenderBuffer(EGL_BACK_BUFFER), - mSwapBehavior(impl->getSwapBehavior()), + mSwapBehavior(EGL_NONE), mOrientation(0), - mTexture() + mTexture(), + mBackFormat(config->renderTargetFormat), + mDSFormat(config->depthStencilFormat) { mPostSubBufferRequested = (attributes.get(EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_FALSE) == EGL_TRUE); mFlexibleSurfaceCompatibilityRequested = (attributes.get(EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE, EGL_FALSE) == EGL_TRUE); + if (mType == EGL_PBUFFER_BIT) + { + mLargestPbuffer = (attributes.get(EGL_LARGEST_PBUFFER, EGL_FALSE) == EGL_TRUE); + } + + mGLColorspace = + static_cast(attributes.get(EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_LINEAR)); + mVGAlphaFormat = + static_cast(attributes.get(EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_NONPRE)); + mVGColorspace = static_cast(attributes.get(EGL_VG_COLORSPACE, EGL_VG_COLORSPACE_sRGB)); + mMipmapTexture = (attributes.get(EGL_MIPMAP_TEXTURE, EGL_FALSE) == EGL_TRUE); + mDirectComposition = (attributes.get(EGL_DIRECT_COMPOSITION_ANGLE, EGL_FALSE) == EGL_TRUE); + mRobustResourceInitialization = + (attributes.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE); + mFixedSize = (attributes.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE) == EGL_TRUE); if (mFixedSize) { - mFixedWidth = attributes.get(EGL_WIDTH, 0); - mFixedHeight = attributes.get(EGL_HEIGHT, 0); + mFixedWidth = static_cast(attributes.get(EGL_WIDTH, 0)); + mFixedHeight = static_cast(attributes.get(EGL_HEIGHT, 0)); } if (mType != EGL_WINDOW_BIT) { - mTextureFormat = attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE); - mTextureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE); + mTextureFormat = static_cast(attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE)); + mTextureTarget = static_cast(attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE)); } - mOrientation = attributes.get(EGL_SURFACE_ORIENTATION_ANGLE, 0); - - mDefaultFramebuffer = createDefaultFramebuffer(); - ASSERT(mDefaultFramebuffer != nullptr); + mOrientation = static_cast(attributes.get(EGL_SURFACE_ORIENTATION_ANGLE, 0)); } Surface::~Surface() { +} + +rx::FramebufferAttachmentObjectImpl *Surface::getAttachmentImpl() const +{ + return mImplementation; +} + +Error Surface::destroyImpl(const Display *display) +{ + if (mState.defaultFramebuffer) + { + mState.defaultFramebuffer->destroyDefault(display); + } + if (mImplementation) + { + mImplementation->destroy(display); + } + if (mTexture.get()) { if (mImplementation) { - mImplementation->releaseTexImage(EGL_BACK_BUFFER); + ANGLE_TRY(mImplementation->releaseTexImage(EGL_BACK_BUFFER)); } - mTexture->releaseTexImageFromSurface(); - mTexture.set(nullptr); + auto glErr = mTexture->releaseTexImageFromSurface(display->getProxyContext()); + if (glErr.isError()) + { + return Error(EGL_BAD_SURFACE); + } + mTexture.set(nullptr, nullptr); } - SafeDelete(mDefaultFramebuffer); + if (mState.defaultFramebuffer) + { + mState.defaultFramebuffer->onDestroy(display->getProxyContext()); + } + SafeDelete(mState.defaultFramebuffer); SafeDelete(mImplementation); + + delete this; + return NoError(); } -void Surface::setIsCurrent(bool isCurrent) +Error Surface::initialize(const Display *display) +{ + ANGLE_TRY(mImplementation->initialize(display)); + + // Initialized here since impl is nullptr in the constructor. + // Must happen after implementation initialize for Android. + mSwapBehavior = mImplementation->getSwapBehavior(); + + // Must happen after implementation initialize for OSX. + mState.defaultFramebuffer = createDefaultFramebuffer(display); + ASSERT(mState.defaultFramebuffer != nullptr); + + return NoError(); +} + +Error Surface::setIsCurrent(const gl::Context *context, bool isCurrent) { if (isCurrent) { mCurrentCount++; + return NoError(); } - else + + ASSERT(mCurrentCount > 0); + mCurrentCount--; + if (mCurrentCount == 0 && mDestroyed) { - ASSERT(mCurrentCount > 0); - mCurrentCount--; - if (mCurrentCount == 0 && mDestroyed) - { - delete this; - } + ASSERT(context); + return destroyImpl(context->getCurrentDisplay()); } + return NoError(); } -void Surface::onDestroy() +Error Surface::onDestroy(const Display *display) { mDestroyed = true; if (mCurrentCount == 0) { - delete this; + return destroyImpl(display); } + return NoError(); } EGLint Surface::getType() const @@ -117,14 +192,23 @@ EGLint Surface::getType() const return mType; } -Error Surface::swap() +Error Surface::swap(const gl::Context *context) { - return mImplementation->swap(); + return mImplementation->swap(context); } -Error Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) +Error Surface::swapWithDamage(const gl::Context *context, EGLint *rects, EGLint n_rects) { - return mImplementation->postSubBuffer(x, y, width, height); + return mImplementation->swapWithDamage(context, rects, n_rects); +} + +Error Surface::postSubBuffer(const gl::Context *context, + EGLint x, + EGLint y, + EGLint width, + EGLint height) +{ + return mImplementation->postSubBuffer(context, x, y, width, height); } Error Surface::querySurfacePointerANGLE(EGLint attribute, void **value) @@ -142,9 +226,30 @@ void Surface::setSwapInterval(EGLint interval) mImplementation->setSwapInterval(interval); } +void Surface::setMipmapLevel(EGLint level) +{ + // Level is set but ignored + UNIMPLEMENTED(); + mMipmapLevel = level; +} + +void Surface::setMultisampleResolve(EGLenum resolve) +{ + // Behaviour is set but ignored + UNIMPLEMENTED(); + mMultisampleResolve = resolve; +} + +void Surface::setSwapBehavior(EGLenum behavior) +{ + // Behaviour is set but ignored + UNIMPLEMENTED(); + mSwapBehavior = behavior; +} + const Config *Surface::getConfig() const { - return mConfig; + return mState.config; } EGLint Surface::getPixelAspectRatio() const @@ -172,6 +277,51 @@ EGLenum Surface::getTextureTarget() const return mTextureTarget; } +bool Surface::getLargestPbuffer() const +{ + return mLargestPbuffer; +} + +EGLenum Surface::getGLColorspace() const +{ + return mGLColorspace; +} + +EGLenum Surface::getVGAlphaFormat() const +{ + return mVGAlphaFormat; +} + +EGLenum Surface::getVGColorspace() const +{ + return mVGColorspace; +} + +bool Surface::getMipmapTexture() const +{ + return mMipmapTexture; +} + +EGLint Surface::getMipmapLevel() const +{ + return mMipmapLevel; +} + +EGLint Surface::getHorizontalResolution() const +{ + return mHorizontalResolution; +} + +EGLint Surface::getVerticalResolution() const +{ + return mVerticalResolution; +} + +EGLenum Surface::getMultisampleResolve() const +{ + return mMultisampleResolve; +} + EGLint Surface::isFixedSize() const { return mFixedSize; @@ -187,42 +337,60 @@ EGLint Surface::getHeight() const return mFixedSize ? static_cast(mFixedHeight) : mImplementation->getHeight(); } -Error Surface::bindTexImage(gl::Texture *texture, EGLint buffer) +Error Surface::bindTexImage(const gl::Context *context, gl::Texture *texture, EGLint buffer) { ASSERT(!mTexture.get()); + ANGLE_TRY(mImplementation->bindTexImage(texture, buffer)); - texture->bindTexImageFromSurface(this); - mTexture.set(texture); - return mImplementation->bindTexImage(texture, buffer); + auto glErr = texture->bindTexImageFromSurface(context, this); + if (glErr.isError()) + { + return Error(EGL_BAD_SURFACE); + } + mTexture.set(context, texture); + + return NoError(); } -Error Surface::releaseTexImage(EGLint buffer) +Error Surface::releaseTexImage(const gl::Context *context, EGLint buffer) +{ + ASSERT(context); + + ANGLE_TRY(mImplementation->releaseTexImage(buffer)); + + ASSERT(mTexture.get()); + auto glErr = mTexture->releaseTexImageFromSurface(context); + if (glErr.isError()) + { + return Error(EGL_BAD_SURFACE); + } + mTexture.set(context, nullptr); + + return NoError(); +} + +Error Surface::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) +{ + return mImplementation->getSyncValues(ust, msc, sbc); +} + +void Surface::releaseTexImageFromTexture(const gl::Context *context) { ASSERT(mTexture.get()); - mTexture->releaseTexImageFromSurface(); - mTexture.set(nullptr); - - return mImplementation->releaseTexImage(buffer); + mTexture.set(context, nullptr); } -void Surface::releaseTexImageFromTexture() -{ - ASSERT(mTexture.get()); - mTexture.set(nullptr); -} - -gl::Extents Surface::getAttachmentSize(const gl::FramebufferAttachment::Target & /*target*/) const +gl::Extents Surface::getAttachmentSize(const gl::ImageIndex & /*target*/) const { return gl::Extents(getWidth(), getHeight(), 1); } -GLenum Surface::getAttachmentInternalFormat(const gl::FramebufferAttachment::Target &target) const +const gl::Format &Surface::getAttachmentFormat(GLenum binding, const gl::ImageIndex &target) const { - const egl::Config *config = getConfig(); - return (target.binding() == GL_BACK ? config->renderTargetFormat : config->depthStencilFormat); + return (binding == GL_BACK ? mBackFormat : mDSFormat); } -GLsizei Surface::getAttachmentSamples(const gl::FramebufferAttachment::Target &target) const +GLsizei Surface::getAttachmentSamples(const gl::ImageIndex &target) const { return getConfig()->samples; } @@ -233,29 +401,84 @@ GLuint Surface::getId() const return 0; } -gl::Framebuffer *Surface::createDefaultFramebuffer() +gl::Framebuffer *Surface::createDefaultFramebuffer(const Display *display) { - gl::Framebuffer *framebuffer = new gl::Framebuffer(mImplementation); - - GLenum drawBufferState = GL_BACK; - framebuffer->setDrawBuffers(1, &drawBufferState); - framebuffer->setReadBuffer(GL_BACK); - - framebuffer->setAttachment(GL_FRAMEBUFFER_DEFAULT, GL_BACK, gl::ImageIndex::MakeInvalid(), - this); - - if (mConfig->depthSize > 0) - { - framebuffer->setAttachment(GL_FRAMEBUFFER_DEFAULT, GL_DEPTH, gl::ImageIndex::MakeInvalid(), - this); - } - - if (mConfig->stencilSize > 0) - { - framebuffer->setAttachment(GL_FRAMEBUFFER_DEFAULT, GL_STENCIL, - gl::ImageIndex::MakeInvalid(), this); - } - - return framebuffer; + return new gl::Framebuffer(display, this); } + +gl::InitState Surface::initState(const gl::ImageIndex & /*imageIndex*/) const +{ + // TODO(jmadill): Lazy surface init. + return gl::InitState::Initialized; } + +void Surface::setInitState(const gl::ImageIndex & /*imageIndex*/, gl::InitState /*initState*/) +{ + // No-op. +} + +WindowSurface::WindowSurface(rx::EGLImplFactory *implFactory, + const egl::Config *config, + EGLNativeWindowType window, + const AttributeMap &attribs) + : Surface(EGL_WINDOW_BIT, config, attribs) +{ + mImplementation = implFactory->createWindowSurface(mState, window, attribs); +} + +WindowSurface::~WindowSurface() +{ +} + +PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory, + const Config *config, + const AttributeMap &attribs) + : Surface(EGL_PBUFFER_BIT, config, attribs) +{ + mImplementation = implFactory->createPbufferSurface(mState, attribs); +} + +PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory, + const Config *config, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const AttributeMap &attribs) + : Surface(EGL_PBUFFER_BIT, config, attribs) +{ + mImplementation = + implFactory->createPbufferFromClientBuffer(mState, buftype, clientBuffer, attribs); +} + +PbufferSurface::~PbufferSurface() +{ +} + +PixmapSurface::PixmapSurface(rx::EGLImplFactory *implFactory, + const Config *config, + NativePixmapType nativePixmap, + const AttributeMap &attribs) + : Surface(EGL_PIXMAP_BIT, config, attribs) +{ + mImplementation = implFactory->createPixmapSurface(mState, nativePixmap, attribs); +} + +PixmapSurface::~PixmapSurface() +{ +} + +// SurfaceDeleter implementation. + +SurfaceDeleter::SurfaceDeleter(const Display *display) : mDisplay(display) +{ +} + +SurfaceDeleter::~SurfaceDeleter() +{ +} + +void SurfaceDeleter::operator()(Surface *surface) +{ + ANGLE_SWALLOW_ERR(surface->onDestroy(mDisplay)); +} + +} // namespace egl diff --git a/src/3rdparty/angle/src/libANGLE/Surface.h b/src/3rdparty/angle/src/libANGLE/Surface.h index e110f5da7b..b3188ff909 100644 --- a/src/3rdparty/angle/src/libANGLE/Surface.h +++ b/src/3rdparty/angle/src/libANGLE/Surface.h @@ -14,9 +14,11 @@ #include #include "common/angleutils.h" +#include "libANGLE/AttributeMap.h" #include "libANGLE/Error.h" #include "libANGLE/FramebufferAttachment.h" #include "libANGLE/RefCountObject.h" +#include "libANGLE/formatutils.h" #include "libANGLE/renderer/SurfaceImpl.h" namespace gl @@ -25,33 +27,55 @@ class Framebuffer; class Texture; } +namespace rx +{ +class EGLImplFactory; +} + namespace egl { -class AttributeMap; class Display; struct Config; -class Surface final : public gl::FramebufferAttachmentObject +struct SurfaceState final : private angle::NonCopyable +{ + SurfaceState(const egl::Config *configIn, const AttributeMap &attributesIn); + + gl::Framebuffer *defaultFramebuffer; + const egl::Config *config; + AttributeMap attributes; +}; + +class Surface : public gl::FramebufferAttachmentObject { public: - Surface(rx::SurfaceImpl *impl, EGLint surfaceType, const egl::Config *config, const AttributeMap &attributes); - - rx::SurfaceImpl *getImplementation() { return mImplementation; } - const rx::SurfaceImpl *getImplementation() const { return mImplementation; } + rx::SurfaceImpl *getImplementation() const { return mImplementation; } EGLint getType() const; - Error swap(); - Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height); + Error initialize(const Display *display); + Error swap(const gl::Context *context); + Error swapWithDamage(const gl::Context *context, EGLint *rects, EGLint n_rects); + Error postSubBuffer(const gl::Context *context, + EGLint x, + EGLint y, + EGLint width, + EGLint height); Error querySurfacePointerANGLE(EGLint attribute, void **value); - Error bindTexImage(gl::Texture *texture, EGLint buffer); - Error releaseTexImage(EGLint buffer); + Error bindTexImage(const gl::Context *context, gl::Texture *texture, EGLint buffer); + Error releaseTexImage(const gl::Context *context, EGLint buffer); + + Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc); EGLint isPostSubBufferSupported() const; void setSwapInterval(EGLint interval); - void setIsCurrent(bool isCurrent); - void onDestroy(); + Error setIsCurrent(const gl::Context *context, bool isCurrent); + Error onDestroy(const Display *display); + + void setMipmapLevel(EGLint level); + void setMultisampleResolve(EGLenum resolve); + void setSwapBehavior(EGLenum behavior); const Config *getConfig() const; @@ -63,19 +87,29 @@ class Surface final : public gl::FramebufferAttachmentObject EGLenum getSwapBehavior() const; EGLenum getTextureFormat() const; EGLenum getTextureTarget() const; + bool getLargestPbuffer() const; + EGLenum getGLColorspace() const; + EGLenum getVGAlphaFormat() const; + EGLenum getVGColorspace() const; + bool getMipmapTexture() const; + EGLint getMipmapLevel() const; + EGLint getHorizontalResolution() const; + EGLint getVerticalResolution() const; + EGLenum getMultisampleResolve() const; gl::Texture *getBoundTexture() const { return mTexture.get(); } - gl::Framebuffer *getDefaultFramebuffer() { return mDefaultFramebuffer; } + gl::Framebuffer *getDefaultFramebuffer() { return mState.defaultFramebuffer; } EGLint isFixedSize() const; // FramebufferAttachmentObject implementation - gl::Extents getAttachmentSize(const gl::FramebufferAttachment::Target &target) const override; - GLenum getAttachmentInternalFormat(const gl::FramebufferAttachment::Target &target) const override; - GLsizei getAttachmentSamples(const gl::FramebufferAttachment::Target &target) const override; + gl::Extents getAttachmentSize(const gl::ImageIndex &imageIndex) const override; + const gl::Format &getAttachmentFormat(GLenum binding, + const gl::ImageIndex &imageIndex) const override; + GLsizei getAttachmentSamples(const gl::ImageIndex &imageIndex) const override; - void onAttach() override {} - void onDetach() override {} + void onAttach(const gl::Context *context) override {} + void onDetach(const gl::Context *context) override {} GLuint getId() const override; bool flexibleSurfaceCompatibilityRequested() const @@ -86,34 +120,50 @@ class Surface final : public gl::FramebufferAttachmentObject bool directComposition() const { return mDirectComposition; } - private: - virtual ~Surface(); - rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override { return mImplementation; } + gl::InitState initState(const gl::ImageIndex &imageIndex) const override; + void setInitState(const gl::ImageIndex &imageIndex, gl::InitState initState) override; - gl::Framebuffer *createDefaultFramebuffer(); + bool isRobustResourceInitEnabled() const { return mRobustResourceInitialization; } + + protected: + Surface(EGLint surfaceType, const egl::Config *config, const AttributeMap &attributes); + ~Surface() override; + rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override; + + gl::Framebuffer *createDefaultFramebuffer(const Display *display); // ANGLE-only method, used internally friend class gl::Texture; - void releaseTexImageFromTexture(); + void releaseTexImageFromTexture(const gl::Context *context); + SurfaceState mState; rx::SurfaceImpl *mImplementation; - gl::Framebuffer *mDefaultFramebuffer; int mCurrentCount; bool mDestroyed; EGLint mType; - const egl::Config *mConfig; - bool mPostSubBufferRequested; bool mFlexibleSurfaceCompatibilityRequested; + bool mLargestPbuffer; + EGLenum mGLColorspace; + EGLenum mVGAlphaFormat; + EGLenum mVGColorspace; + bool mMipmapTexture; + EGLint mMipmapLevel; + EGLint mHorizontalResolution; + EGLint mVerticalResolution; + EGLenum mMultisampleResolve; + bool mFixedSize; size_t mFixedWidth; size_t mFixedHeight; bool mDirectComposition; + bool mRobustResourceInitialization; + EGLenum mTextureFormat; EGLenum mTextureTarget; @@ -123,9 +173,66 @@ class Surface final : public gl::FramebufferAttachmentObject EGLint mOrientation; - BindingPointer mTexture; + gl::BindingPointer mTexture; + + gl::Format mBackFormat; + gl::Format mDSFormat; + + private: + Error destroyImpl(const Display *display); }; -} +class WindowSurface final : public Surface +{ + public: + WindowSurface(rx::EGLImplFactory *implFactory, + const Config *config, + EGLNativeWindowType window, + const AttributeMap &attribs); + ~WindowSurface() override; +}; + +class PbufferSurface final : public Surface +{ + public: + PbufferSurface(rx::EGLImplFactory *implFactory, + const Config *config, + const AttributeMap &attribs); + PbufferSurface(rx::EGLImplFactory *implFactory, + const Config *config, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const AttributeMap &attribs); + + protected: + ~PbufferSurface() override; +}; + +class PixmapSurface final : public Surface +{ + public: + PixmapSurface(rx::EGLImplFactory *implFactory, + const Config *config, + NativePixmapType nativePixmap, + const AttributeMap &attribs); + + protected: + ~PixmapSurface() override; +}; + +class SurfaceDeleter final +{ + public: + SurfaceDeleter(const Display *display); + ~SurfaceDeleter(); + void operator()(Surface *surface); + + private: + const Display *mDisplay; +}; + +using SurfacePointer = angle::UniqueObjectPointerBase; + +} // namespace egl #endif // LIBANGLE_SURFACE_H_ diff --git a/src/3rdparty/angle/src/libANGLE/Texture.cpp b/src/3rdparty/angle/src/libANGLE/Texture.cpp index 5ef6762d3d..da92e65916 100644 --- a/src/3rdparty/angle/src/libANGLE/Texture.cpp +++ b/src/3rdparty/angle/src/libANGLE/Texture.cpp @@ -12,324 +12,207 @@ #include "common/utilities.h" #include "libANGLE/Config.h" #include "libANGLE/Context.h" -#include "libANGLE/Data.h" +#include "libANGLE/ContextState.h" #include "libANGLE/Image.h" #include "libANGLE/Surface.h" #include "libANGLE/formatutils.h" +#include "libANGLE/renderer/GLImplFactory.h" +#include "libANGLE/renderer/TextureImpl.h" namespace gl { -bool IsMipmapFiltered(const gl::SamplerState &samplerState) +namespace +{ +bool IsPointSampled(const SamplerState &samplerState) +{ + return (samplerState.magFilter == GL_NEAREST && + (samplerState.minFilter == GL_NEAREST || + samplerState.minFilter == GL_NEAREST_MIPMAP_NEAREST)); +} + +size_t GetImageDescIndex(GLenum target, size_t level) +{ + return IsCubeMapTextureTarget(target) ? ((level * 6) + CubeMapTextureTargetToLayerIndex(target)) + : level; +} + +ImageIndex GetImageIndexFromDescIndex(GLenum target, size_t descIndex) +{ + if (target == GL_TEXTURE_CUBE_MAP) + { + size_t faceIndex = descIndex % 6; + size_t mipIndex = descIndex / 6; + return ImageIndex::MakeCube(LayerIndexToCubeMapTextureTarget(faceIndex), + static_cast(mipIndex)); + } + + return ImageIndex::MakeGeneric(target, static_cast(descIndex)); +} + +InitState DetermineInitState(const Context *context, const uint8_t *pixels) +{ + // Can happen in tests. + if (!context || !context->isRobustResourceInitEnabled()) + return InitState::Initialized; + + const auto &glState = context->getGLState(); + return (pixels == nullptr && glState.getTargetBuffer(gl::BufferBinding::PixelUnpack) == nullptr) + ? InitState::MayNeedInit + : InitState::Initialized; +} + +} // namespace + +bool IsMipmapFiltered(const SamplerState &samplerState) { switch (samplerState.minFilter) { - case GL_NEAREST: - case GL_LINEAR: - return false; - case GL_NEAREST_MIPMAP_NEAREST: - case GL_LINEAR_MIPMAP_NEAREST: - case GL_NEAREST_MIPMAP_LINEAR: - case GL_LINEAR_MIPMAP_LINEAR: + case GL_NEAREST: + case GL_LINEAR: + return false; + case GL_NEAREST_MIPMAP_NEAREST: + case GL_LINEAR_MIPMAP_NEAREST: + case GL_NEAREST_MIPMAP_LINEAR: + case GL_LINEAR_MIPMAP_LINEAR: + return true; + default: + UNREACHABLE(); + return false; + } +} + +SwizzleState::SwizzleState() + : swizzleRed(GL_INVALID_INDEX), + swizzleGreen(GL_INVALID_INDEX), + swizzleBlue(GL_INVALID_INDEX), + swizzleAlpha(GL_INVALID_INDEX) +{ +} + +SwizzleState::SwizzleState(GLenum red, GLenum green, GLenum blue, GLenum alpha) + : swizzleRed(red), swizzleGreen(green), swizzleBlue(blue), swizzleAlpha(alpha) +{ +} + +bool SwizzleState::swizzleRequired() const +{ + return swizzleRed != GL_RED || swizzleGreen != GL_GREEN || swizzleBlue != GL_BLUE || + swizzleAlpha != GL_ALPHA; +} + +bool SwizzleState::operator==(const SwizzleState &other) const +{ + return swizzleRed == other.swizzleRed && swizzleGreen == other.swizzleGreen && + swizzleBlue == other.swizzleBlue && swizzleAlpha == other.swizzleAlpha; +} + +bool SwizzleState::operator!=(const SwizzleState &other) const +{ + return !(*this == other); +} + +TextureState::TextureState(GLenum target) + : mTarget(target), + mSwizzleState(GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA), + mSamplerState(SamplerState::CreateDefaultForTarget(target)), + mBaseLevel(0), + mMaxLevel(1000), + mDepthStencilTextureMode(GL_DEPTH_COMPONENT), + mImmutableFormat(false), + mImmutableLevels(0), + mUsage(GL_NONE), + mImageDescs((IMPLEMENTATION_MAX_TEXTURE_LEVELS + 1) * + (target == GL_TEXTURE_CUBE_MAP ? 6 : 1)), + mInitState(InitState::MayNeedInit) +{ +} + +TextureState::~TextureState() +{ +} + +bool TextureState::swizzleRequired() const +{ + return mSwizzleState.swizzleRequired(); +} + +GLuint TextureState::getEffectiveBaseLevel() const +{ + if (mImmutableFormat) + { + // GLES 3.0.4 section 3.8.10 + return std::min(mBaseLevel, mImmutableLevels - 1); + } + // Some classes use the effective base level to index arrays with level data. By clamping the + // effective base level to max levels these arrays need just one extra item to store properties + // that should be returned for all out-of-range base level values, instead of needing special + // handling for out-of-range base levels. + return std::min(mBaseLevel, static_cast(IMPLEMENTATION_MAX_TEXTURE_LEVELS)); +} + +GLuint TextureState::getEffectiveMaxLevel() const +{ + if (mImmutableFormat) + { + // GLES 3.0.4 section 3.8.10 + GLuint clampedMaxLevel = std::max(mMaxLevel, getEffectiveBaseLevel()); + clampedMaxLevel = std::min(clampedMaxLevel, mImmutableLevels - 1); + return clampedMaxLevel; + } + return mMaxLevel; +} + +GLuint TextureState::getMipmapMaxLevel() const +{ + const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel()); + GLuint expectedMipLevels = 0; + if (mTarget == GL_TEXTURE_3D) + { + const int maxDim = std::max(std::max(baseImageDesc.size.width, baseImageDesc.size.height), + baseImageDesc.size.depth); + expectedMipLevels = static_cast(log2(maxDim)); + } + else + { + expectedMipLevels = static_cast( + log2(std::max(baseImageDesc.size.width, baseImageDesc.size.height))); + } + + return std::min(getEffectiveBaseLevel() + expectedMipLevels, getEffectiveMaxLevel()); +} + +bool TextureState::setBaseLevel(GLuint baseLevel) +{ + if (mBaseLevel != baseLevel) + { + mBaseLevel = baseLevel; return true; - default: UNREACHABLE(); - return false; } + return false; } -bool IsPointSampled(const gl::SamplerState &samplerState) +bool TextureState::setMaxLevel(GLuint maxLevel) { - return (samplerState.magFilter == GL_NEAREST && (samplerState.minFilter == GL_NEAREST || samplerState.minFilter == GL_NEAREST_MIPMAP_NEAREST)); -} - -static size_t GetImageDescIndex(GLenum target, size_t level) -{ - return IsCubeMapTextureTarget(target) ? ((level * 6) + CubeMapTextureTargetToLayerIndex(target)) : level; -} - -Texture::Texture(rx::TextureImpl *impl, GLuint id, GLenum target) - : egl::ImageSibling(id), - mTexture(impl), - mLabel(), - mTextureState(), - mTarget(target), - mImageDescs(IMPLEMENTATION_MAX_TEXTURE_LEVELS * (target == GL_TEXTURE_CUBE_MAP ? 6 : 1)), - mCompletenessCache(), - mBoundSurface(NULL) -{ -} - -Texture::~Texture() -{ - if (mBoundSurface) + if (mMaxLevel != maxLevel) { - mBoundSurface->releaseTexImage(EGL_BACK_BUFFER); - mBoundSurface = NULL; + mMaxLevel = maxLevel; + return true; } - SafeDelete(mTexture); -} -void Texture::setLabel(const std::string &label) -{ - mLabel = label; -} - -const std::string &Texture::getLabel() const -{ - return mLabel; -} - -GLenum Texture::getTarget() const -{ - return mTarget; -} - -void Texture::setSwizzleRed(GLenum swizzleRed) -{ - mTextureState.swizzleRed = swizzleRed; -} - -GLenum Texture::getSwizzleRed() const -{ - return mTextureState.swizzleRed; -} - -void Texture::setSwizzleGreen(GLenum swizzleGreen) -{ - mTextureState.swizzleGreen = swizzleGreen; -} - -GLenum Texture::getSwizzleGreen() const -{ - return mTextureState.swizzleGreen; -} - -void Texture::setSwizzleBlue(GLenum swizzleBlue) -{ - mTextureState.swizzleBlue = swizzleBlue; -} - -GLenum Texture::getSwizzleBlue() const -{ - return mTextureState.swizzleBlue; -} - -void Texture::setSwizzleAlpha(GLenum swizzleAlpha) -{ - mTextureState.swizzleAlpha = swizzleAlpha; -} - -GLenum Texture::getSwizzleAlpha() const -{ - return mTextureState.swizzleAlpha; -} - -void Texture::setMinFilter(GLenum minFilter) -{ - mTextureState.samplerState.minFilter = minFilter; -} - -GLenum Texture::getMinFilter() const -{ - return mTextureState.samplerState.minFilter; -} - -void Texture::setMagFilter(GLenum magFilter) -{ - mTextureState.samplerState.magFilter = magFilter; -} - -GLenum Texture::getMagFilter() const -{ - return mTextureState.samplerState.magFilter; -} - -void Texture::setWrapS(GLenum wrapS) -{ - mTextureState.samplerState.wrapS = wrapS; -} - -GLenum Texture::getWrapS() const -{ - return mTextureState.samplerState.wrapS; -} - -void Texture::setWrapT(GLenum wrapT) -{ - mTextureState.samplerState.wrapT = wrapT; -} - -GLenum Texture::getWrapT() const -{ - return mTextureState.samplerState.wrapT; -} - -void Texture::setWrapR(GLenum wrapR) -{ - mTextureState.samplerState.wrapR = wrapR; -} - -GLenum Texture::getWrapR() const -{ - return mTextureState.samplerState.wrapR; -} - -void Texture::setMaxAnisotropy(float maxAnisotropy) -{ - mTextureState.samplerState.maxAnisotropy = maxAnisotropy; -} - -float Texture::getMaxAnisotropy() const -{ - return mTextureState.samplerState.maxAnisotropy; -} - -void Texture::setMinLod(GLfloat minLod) -{ - mTextureState.samplerState.minLod = minLod; -} - -GLfloat Texture::getMinLod() const -{ - return mTextureState.samplerState.minLod; -} - -void Texture::setMaxLod(GLfloat maxLod) -{ - mTextureState.samplerState.maxLod = maxLod; -} - -GLfloat Texture::getMaxLod() const -{ - return mTextureState.samplerState.maxLod; -} - -void Texture::setCompareMode(GLenum compareMode) -{ - mTextureState.samplerState.compareMode = compareMode; -} - -GLenum Texture::getCompareMode() const -{ - return mTextureState.samplerState.compareMode; -} - -void Texture::setCompareFunc(GLenum compareFunc) -{ - mTextureState.samplerState.compareFunc = compareFunc; -} - -GLenum Texture::getCompareFunc() const -{ - return mTextureState.samplerState.compareFunc; -} - -const SamplerState &Texture::getSamplerState() const -{ - return mTextureState.samplerState; -} - -void Texture::setBaseLevel(GLuint baseLevel) -{ - mTextureState.baseLevel = baseLevel; -} - -GLuint Texture::getBaseLevel() const -{ - return mTextureState.baseLevel; -} - -void Texture::setMaxLevel(GLuint maxLevel) -{ - mTextureState.maxLevel = maxLevel; -} - -GLuint Texture::getMaxLevel() const -{ - return mTextureState.maxLevel; -} - -bool Texture::getImmutableFormat() const -{ - return mTextureState.immutableFormat; -} - -GLuint Texture::getImmutableLevels() const -{ - return mTextureState.immutableLevels; -} - -void Texture::setUsage(GLenum usage) -{ - mTextureState.usage = usage; - getImplementation()->setUsage(usage); -} - -GLenum Texture::getUsage() const -{ - return mTextureState.usage; -} - -const TextureState &Texture::getTextureState() const -{ - return mTextureState; -} - -size_t Texture::getWidth(GLenum target, size_t level) const -{ - ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); - return getImageDesc(target, level).size.width; -} - -size_t Texture::getHeight(GLenum target, size_t level) const -{ - ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); - return getImageDesc(target, level).size.height; -} - -size_t Texture::getDepth(GLenum target, size_t level) const -{ - ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); - return getImageDesc(target, level).size.depth; -} - -GLenum Texture::getInternalFormat(GLenum target, size_t level) const -{ - ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); - return getImageDesc(target, level).internalFormat; -} - -bool Texture::isSamplerComplete(const SamplerState &samplerState, const Data &data) const -{ - const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), mTextureState.baseLevel); - const TextureCaps &textureCaps = data.textureCaps->get(baseImageDesc.internalFormat); - if (!mCompletenessCache.cacheValid || - mCompletenessCache.samplerState != samplerState || - mCompletenessCache.filterable != textureCaps.filterable || - mCompletenessCache.clientVersion != data.clientVersion || - mCompletenessCache.supportsNPOT != data.extensions->textureNPOT) - { - mCompletenessCache.cacheValid = true; - mCompletenessCache.samplerState = samplerState; - mCompletenessCache.filterable = textureCaps.filterable; - mCompletenessCache.clientVersion = data.clientVersion; - mCompletenessCache.supportsNPOT = data.extensions->textureNPOT; - mCompletenessCache.samplerComplete = computeSamplerCompleteness(samplerState, data); - } - return mCompletenessCache.samplerComplete; -} - -bool Texture::isMipmapComplete() const -{ - return computeMipmapCompleteness(); + return false; } // Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81. -bool Texture::isCubeComplete() const +// According to [OpenGL ES 3.0.5] section 3.8.13 Texture Completeness page 160 any +// per-level checks begin at the base-level. +// For OpenGL ES2 the base level is always zero. +bool TextureState::isCubeComplete() const { ASSERT(mTarget == GL_TEXTURE_CUBE_MAP); - const ImageDesc &baseImageDesc = getImageDesc(FirstCubeMapTextureTarget, 0); + const ImageDesc &baseImageDesc = + getImageDesc(FirstCubeMapTextureTarget, getEffectiveBaseLevel()); if (baseImageDesc.size.width == 0 || baseImageDesc.size.width != baseImageDesc.size.height) { return false; @@ -337,10 +220,10 @@ bool Texture::isCubeComplete() const for (GLenum face = FirstCubeMapTextureTarget + 1; face <= LastCubeMapTextureTarget; face++) { - const ImageDesc &faceImageDesc = getImageDesc(face, 0); + const ImageDesc &faceImageDesc = getImageDesc(face, getEffectiveBaseLevel()); if (faceImageDesc.size.width != baseImageDesc.size.width || faceImageDesc.size.height != baseImageDesc.size.height || - faceImageDesc.internalFormat != baseImageDesc.internalFormat) + !Format::SameSized(faceImageDesc.format, baseImageDesc.format)) { return false; } @@ -349,373 +232,54 @@ bool Texture::isCubeComplete() const return true; } -size_t Texture::getMipCompleteLevels() const +bool TextureState::computeSamplerCompleteness(const SamplerState &samplerState, + const ContextState &data) const { - const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), 0); - if (mTarget == GL_TEXTURE_3D) - { - const int maxDim = std::max(std::max(baseImageDesc.size.width, baseImageDesc.size.height), - baseImageDesc.size.depth); - return log2(maxDim) + 1; - } - else - { - return log2(std::max(baseImageDesc.size.width, baseImageDesc.size.height)) + 1; - } -} - -egl::Surface *Texture::getBoundSurface() const -{ - return mBoundSurface; -} - -Error Texture::setImage(Context *context, - GLenum target, - size_t level, - GLenum internalFormat, - const Extents &size, - GLenum format, - GLenum type, - const uint8_t *pixels) -{ - ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); - - // Release from previous calls to eglBindTexImage, to avoid calling the Impl after - releaseTexImageInternal(); - orphanImages(); - - // Hack: allow nullptr for testing - if (context != nullptr) - { - // Sync the unpack state - context->syncRendererState(context->getState().unpackStateBitMask()); - } - - const PixelUnpackState defaultUnpack; - const PixelUnpackState &unpack = context ? context->getState().getUnpackState() : defaultUnpack; - Error error = mTexture->setImage(target, level, internalFormat, size, format, type, unpack, pixels); - if (error.isError()) - { - return error; - } - - setImageDesc(target, level, ImageDesc(size, GetSizedInternalFormat(internalFormat, type))); - - return Error(GL_NO_ERROR); -} - -Error Texture::setSubImage(Context *context, - GLenum target, - size_t level, - const Box &area, - GLenum format, - GLenum type, - const uint8_t *pixels) -{ - ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); - - // Sync the unpack state - context->syncRendererState(context->getState().unpackStateBitMask()); - - const PixelUnpackState &unpack = context->getState().getUnpackState(); - return mTexture->setSubImage(target, level, area, format, type, unpack, pixels); -} - -Error Texture::setCompressedImage(Context *context, - GLenum target, - size_t level, - GLenum internalFormat, - const Extents &size, - size_t imageSize, - const uint8_t *pixels) -{ - ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); - - // Release from previous calls to eglBindTexImage, to avoid calling the Impl after - releaseTexImageInternal(); - orphanImages(); - - // Sync the unpack state - context->syncRendererState(context->getState().unpackStateBitMask()); - - const PixelUnpackState &unpack = context->getState().getUnpackState(); - Error error = mTexture->setCompressedImage(target, level, internalFormat, size, unpack, imageSize, pixels); - if (error.isError()) - { - return error; - } - - setImageDesc(target, level, ImageDesc(size, GetSizedInternalFormat(internalFormat, GL_UNSIGNED_BYTE))); - - return Error(GL_NO_ERROR); -} - -Error Texture::setCompressedSubImage(Context *context, - GLenum target, - size_t level, - const Box &area, - GLenum format, - size_t imageSize, - const uint8_t *pixels) -{ - ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); - - // Sync the unpack state - context->syncRendererState(context->getState().unpackStateBitMask()); - - const PixelUnpackState &unpack = context->getState().getUnpackState(); - return mTexture->setCompressedSubImage(target, level, area, format, unpack, imageSize, pixels); -} - -Error Texture::copyImage(GLenum target, size_t level, const Rectangle &sourceArea, GLenum internalFormat, - const Framebuffer *source) -{ - ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); - - // Release from previous calls to eglBindTexImage, to avoid calling the Impl after - releaseTexImageInternal(); - orphanImages(); - - Error error = mTexture->copyImage(target, level, sourceArea, internalFormat, source); - if (error.isError()) - { - return error; - } - - setImageDesc(target, level, ImageDesc(Extents(sourceArea.width, sourceArea.height, 1), - GetSizedInternalFormat(internalFormat, GL_UNSIGNED_BYTE))); - - return Error(GL_NO_ERROR); -} - -Error Texture::copySubImage(GLenum target, size_t level, const Offset &destOffset, const Rectangle &sourceArea, - const Framebuffer *source) -{ - ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); - - return mTexture->copySubImage(target, level, destOffset, sourceArea, source); -} - -Error Texture::setStorage(GLenum target, size_t levels, GLenum internalFormat, const Extents &size) -{ - ASSERT(target == mTarget); - - // Release from previous calls to eglBindTexImage, to avoid calling the Impl after - releaseTexImageInternal(); - orphanImages(); - - Error error = mTexture->setStorage(target, levels, internalFormat, size); - if (error.isError()) - { - return error; - } - - mTextureState.immutableFormat = true; - mTextureState.immutableLevels = static_cast(levels); - clearImageDescs(); - setImageDescChain(levels, size, internalFormat); - - return Error(GL_NO_ERROR); -} - -Error Texture::generateMipmaps() -{ - // Release from previous calls to eglBindTexImage, to avoid calling the Impl after - releaseTexImageInternal(); - - // EGL_KHR_gl_image states that images are only orphaned when generating mipmaps if the texture - // is not mip complete. - if (!isMipmapComplete()) - { - orphanImages(); - } - - Error error = mTexture->generateMipmaps(mTextureState); - if (error.isError()) - { - return error; - } - - const ImageDesc &baseImageInfo = getImageDesc(getBaseImageTarget(), 0); - size_t mipLevels = log2(std::max(std::max(baseImageInfo.size.width, baseImageInfo.size.height), baseImageInfo.size.depth)) + 1; - setImageDescChain(mipLevels, baseImageInfo.size, baseImageInfo.internalFormat); - - return Error(GL_NO_ERROR); -} - -void Texture::setImageDescChain(size_t levels, Extents baseSize, GLenum sizedInternalFormat) -{ - for (int level = 0; level < static_cast(levels); level++) - { - Extents levelSize( - std::max(baseSize.width >> level, 1), std::max(baseSize.height >> level, 1), - (mTarget == GL_TEXTURE_2D_ARRAY) ? baseSize.depth - : std::max(baseSize.depth >> level, 1)); - ImageDesc levelInfo(levelSize, sizedInternalFormat); - - if (mTarget == GL_TEXTURE_CUBE_MAP) - { - for (GLenum face = FirstCubeMapTextureTarget; face <= LastCubeMapTextureTarget; face++) - { - setImageDesc(face, level, levelInfo); - } - } - else - { - setImageDesc(mTarget, level, levelInfo); - } - } -} - -Texture::ImageDesc::ImageDesc() - : ImageDesc(Extents(0, 0, 0), GL_NONE) -{ -} - -Texture::ImageDesc::ImageDesc(const Extents &size, GLenum internalFormat) - : size(size), - internalFormat(internalFormat) -{ -} - -const Texture::ImageDesc &Texture::getImageDesc(GLenum target, size_t level) const -{ - size_t descIndex = GetImageDescIndex(target, level); - ASSERT(descIndex < mImageDescs.size()); - return mImageDescs[descIndex]; -} - -void Texture::setImageDesc(GLenum target, size_t level, const ImageDesc &desc) -{ - size_t descIndex = GetImageDescIndex(target, level); - ASSERT(descIndex < mImageDescs.size()); - mImageDescs[descIndex] = desc; - mCompletenessCache.cacheValid = false; -} - -void Texture::clearImageDesc(GLenum target, size_t level) -{ - setImageDesc(target, level, ImageDesc()); -} - -void Texture::clearImageDescs() -{ - for (size_t descIndex = 0; descIndex < mImageDescs.size(); descIndex++) - { - mImageDescs[descIndex] = ImageDesc(); - } - mCompletenessCache.cacheValid = false; -} - -void Texture::bindTexImageFromSurface(egl::Surface *surface) -{ - ASSERT(surface); - - if (mBoundSurface) - { - releaseTexImageFromSurface(); - } - - mTexture->bindTexImage(surface); - mBoundSurface = surface; - - // Set the image info to the size and format of the surface - ASSERT(mTarget == GL_TEXTURE_2D); - Extents size(surface->getWidth(), surface->getHeight(), 1); - ImageDesc desc(size, surface->getConfig()->renderTargetFormat); - setImageDesc(mTarget, 0, desc); -} - -void Texture::releaseTexImageFromSurface() -{ - ASSERT(mBoundSurface); - mBoundSurface = nullptr; - mTexture->releaseTexImage(); - - // Erase the image info for level 0 - ASSERT(mTarget == GL_TEXTURE_2D); - clearImageDesc(mTarget, 0); -} - -void Texture::releaseTexImageInternal() -{ - if (mBoundSurface) - { - // Notify the surface - mBoundSurface->releaseTexImageFromTexture(); - - // Then, call the same method as from the surface - releaseTexImageFromSurface(); - } -} - -Error Texture::setEGLImageTarget(GLenum target, egl::Image *imageTarget) -{ - ASSERT(target == mTarget); - ASSERT(target == GL_TEXTURE_2D); - - // Release from previous calls to eglBindTexImage, to avoid calling the Impl after - releaseTexImageInternal(); - orphanImages(); - - Error error = mTexture->setEGLImageTarget(target, imageTarget); - if (error.isError()) - { - return error; - } - - setTargetImage(imageTarget); - - Extents size(static_cast(imageTarget->getWidth()), - static_cast(imageTarget->getHeight()), 1); - GLenum internalFormat = imageTarget->getInternalFormat(); - GLenum type = GetInternalFormatInfo(internalFormat).type; - - clearImageDescs(); - setImageDesc(target, 0, ImageDesc(size, GetSizedInternalFormat(internalFormat, type))); - - return Error(GL_NO_ERROR); -} - -GLenum Texture::getBaseImageTarget() const -{ - return mTarget == GL_TEXTURE_CUBE_MAP ? FirstCubeMapTextureTarget : mTarget; -} - -bool Texture::computeSamplerCompleteness(const SamplerState &samplerState, const Data &data) const -{ - const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), mTextureState.baseLevel); - if (baseImageDesc.size.width == 0 || baseImageDesc.size.height == 0 || baseImageDesc.size.depth == 0) + if (mBaseLevel > mMaxLevel) { return false; } + const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel()); + if (baseImageDesc.size.width == 0 || baseImageDesc.size.height == 0 || + baseImageDesc.size.depth == 0) + { + return false; + } + // The cases where the texture is incomplete because base level is out of range should be + // handled by the above condition. + ASSERT(mBaseLevel < IMPLEMENTATION_MAX_TEXTURE_LEVELS || mImmutableFormat); if (mTarget == GL_TEXTURE_CUBE_MAP && baseImageDesc.size.width != baseImageDesc.size.height) { return false; } - const TextureCaps &textureCaps = data.textureCaps->get(baseImageDesc.internalFormat); - if (!textureCaps.filterable && !IsPointSampled(samplerState)) + // According to es 3.1 spec, texture is justified as incomplete if sized internalformat is + // unfilterable(table 20.11) and filter is not GL_NEAREST(8.16). The default value of minFilter + // is NEAREST_MIPMAP_LINEAR and magFilter is LINEAR(table 20.11,). For multismaple texture, + // filter state of multisample texture is ignored(11.1.3.3). So it shouldn't be judged as + // incomplete texture. So, we ignore filtering for multisample texture completeness here. + if (mTarget != GL_TEXTURE_2D_MULTISAMPLE && + !baseImageDesc.format.info->filterSupport(data.getClientVersion(), data.getExtensions()) && + !IsPointSampled(samplerState)) { return false; } - - bool npotSupport = data.extensions->textureNPOT || data.clientVersion >= 3; + bool npotSupport = data.getExtensions().textureNPOT || data.getClientMajorVersion() >= 3; if (!npotSupport) { - if ((samplerState.wrapS != GL_CLAMP_TO_EDGE && !gl::isPow2(baseImageDesc.size.width)) || - (samplerState.wrapT != GL_CLAMP_TO_EDGE && !gl::isPow2(baseImageDesc.size.height))) + if ((samplerState.wrapS != GL_CLAMP_TO_EDGE && !isPow2(baseImageDesc.size.width)) || + (samplerState.wrapT != GL_CLAMP_TO_EDGE && !isPow2(baseImageDesc.size.height))) { return false; } } - if (IsMipmapFiltered(samplerState)) + if (mTarget != GL_TEXTURE_2D_MULTISAMPLE && IsMipmapFiltered(samplerState)) { if (!npotSupport) { - if (!gl::isPow2(baseImageDesc.size.width) || !gl::isPow2(baseImageDesc.size.height)) + if (!isPow2(baseImageDesc.size.width) || !isPow2(baseImageDesc.size.height)) { return false; } @@ -734,17 +298,43 @@ bool Texture::computeSamplerCompleteness(const SamplerState &samplerState, const } } + // From GL_OES_EGL_image_external_essl3: If state is present in a sampler object bound to a + // texture unit that would have been rejected by a call to TexParameter* for the texture bound + // to that unit, the behavior of the implementation is as if the texture were incomplete. For + // example, if TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to anything but CLAMP_TO_EDGE on the + // sampler object bound to a texture unit and the texture bound to that unit is an external + // texture, the texture will be considered incomplete. + // Sampler object state which does not affect sampling for the type of texture bound to a + // texture unit, such as TEXTURE_WRAP_R for an external texture, does not affect completeness. + if (mTarget == GL_TEXTURE_EXTERNAL_OES) + { + if (samplerState.wrapS != GL_CLAMP_TO_EDGE || samplerState.wrapT != GL_CLAMP_TO_EDGE) + { + return false; + } + + if (samplerState.minFilter != GL_LINEAR && samplerState.minFilter != GL_NEAREST) + { + return false; + } + } + // OpenGLES 3.0.2 spec section 3.8.13 states that a texture is not mipmap complete if: // The internalformat specified for the texture arrays is a sized internal depth or // depth and stencil format (see table 3.13), the value of TEXTURE_COMPARE_- // MODE is NONE, and either the magnification filter is not NEAREST or the mini- // fication filter is neither NEAREST nor NEAREST_MIPMAP_NEAREST. - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(baseImageDesc.internalFormat); - if (formatInfo.depthBits > 0 && data.clientVersion > 2) + if (mTarget != GL_TEXTURE_2D_MULTISAMPLE && baseImageDesc.format.info->depthBits > 0 && + data.getClientMajorVersion() >= 3) { - if (samplerState.compareMode == GL_NONE) + // Note: we restrict this validation to sized types. For the OES_depth_textures + // extension, due to some underspecification problems, we must allow linear filtering + // for legacy compatibility with WebGL 1. + // See http://crbug.com/649200 + if (samplerState.compareMode == GL_NONE && baseImageDesc.format.info->sized) { - if ((samplerState.minFilter != GL_NEAREST && samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST) || + if ((samplerState.minFilter != GL_NEAREST && + samplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST) || samplerState.magFilter != GL_NEAREST) { return false; @@ -755,13 +345,11 @@ bool Texture::computeSamplerCompleteness(const SamplerState &samplerState, const return true; } -bool Texture::computeMipmapCompleteness() const +bool TextureState::computeMipmapCompleteness() const { - size_t expectedMipLevels = getMipCompleteLevels(); + const GLuint maxLevel = getMipmapMaxLevel(); - size_t maxLevel = std::min(expectedMipLevels, mTextureState.maxLevel + 1); - - for (size_t level = mTextureState.baseLevel; level < maxLevel; level++) + for (GLuint level = getEffectiveBaseLevel(); level <= maxLevel; level++) { if (mTarget == GL_TEXTURE_CUBE_MAP) { @@ -785,17 +373,18 @@ bool Texture::computeMipmapCompleteness() const return true; } -bool Texture::computeLevelCompleteness(GLenum target, size_t level) const +bool TextureState::computeLevelCompleteness(GLenum target, size_t level) const { ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS); - if (mTextureState.immutableFormat) + if (mImmutableFormat) { return true; } - const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), mTextureState.baseLevel); - if (baseImageDesc.size.width == 0 || baseImageDesc.size.height == 0 || baseImageDesc.size.depth == 0) + const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel()); + if (baseImageDesc.size.width == 0 || baseImageDesc.size.height == 0 || + baseImageDesc.size.depth == 0) { return false; } @@ -807,13 +396,13 @@ bool Texture::computeLevelCompleteness(GLenum target, size_t level) const return false; } - if (levelImageDesc.internalFormat != baseImageDesc.internalFormat) + if (!Format::SameSized(levelImageDesc.format, baseImageDesc.format)) { return false; } - ASSERT(level >= mTextureState.baseLevel); - const size_t relativeLevel = level - mTextureState.baseLevel; + ASSERT(level >= getEffectiveBaseLevel()); + const size_t relativeLevel = level - getEffectiveBaseLevel(); if (levelImageDesc.size.width != std::max(1, baseImageDesc.size.width >> relativeLevel)) { return false; @@ -842,44 +431,1054 @@ bool Texture::computeLevelCompleteness(GLenum target, size_t level) const return true; } -Texture::SamplerCompletenessCache::SamplerCompletenessCache() - : cacheValid(false), - samplerState(), - filterable(false), - clientVersion(0), - supportsNPOT(false), - samplerComplete(false) +GLenum TextureState::getBaseImageTarget() const +{ + return mTarget == GL_TEXTURE_CUBE_MAP ? FirstCubeMapTextureTarget : mTarget; +} + +ImageDesc::ImageDesc() + : ImageDesc(Extents(0, 0, 0), Format::Invalid(), 0, GL_TRUE, InitState::Initialized) { } -Extents Texture::getAttachmentSize(const gl::FramebufferAttachment::Target &target) const +ImageDesc::ImageDesc(const Extents &size, const Format &format, const InitState initState) + : size(size), format(format), samples(0), fixedSampleLocations(GL_TRUE), initState(initState) { - return getImageDesc(target.textureIndex().type, target.textureIndex().mipIndex).size; } -GLenum Texture::getAttachmentInternalFormat(const gl::FramebufferAttachment::Target &target) const +ImageDesc::ImageDesc(const Extents &size, + const Format &format, + const GLsizei samples, + const bool fixedSampleLocations, + const InitState initState) + : size(size), + format(format), + samples(samples), + fixedSampleLocations(fixedSampleLocations), + initState(initState) { - return getInternalFormat(target.textureIndex().type, target.textureIndex().mipIndex); } -GLsizei Texture::getAttachmentSamples(const gl::FramebufferAttachment::Target &/*target*/) const +const ImageDesc &TextureState::getImageDesc(GLenum target, size_t level) const { - // Multisample textures not currently supported - return 0; + size_t descIndex = GetImageDescIndex(target, level); + ASSERT(descIndex < mImageDescs.size()); + return mImageDescs[descIndex]; } -void Texture::onAttach() +void TextureState::setImageDesc(GLenum target, size_t level, const ImageDesc &desc) +{ + size_t descIndex = GetImageDescIndex(target, level); + ASSERT(descIndex < mImageDescs.size()); + mImageDescs[descIndex] = desc; + if (desc.initState == InitState::MayNeedInit) + { + mInitState = InitState::MayNeedInit; + } +} + +const ImageDesc &TextureState::getImageDesc(const ImageIndex &imageIndex) const +{ + return getImageDesc(imageIndex.type, imageIndex.mipIndex); +} + +void TextureState::setImageDescChain(GLuint baseLevel, + GLuint maxLevel, + Extents baseSize, + const Format &format, + InitState initState) +{ + for (GLuint level = baseLevel; level <= maxLevel; level++) + { + int relativeLevel = (level - baseLevel); + Extents levelSize(std::max(baseSize.width >> relativeLevel, 1), + std::max(baseSize.height >> relativeLevel, 1), + (mTarget == GL_TEXTURE_2D_ARRAY) + ? baseSize.depth + : std::max(baseSize.depth >> relativeLevel, 1)); + ImageDesc levelInfo(levelSize, format, initState); + + if (mTarget == GL_TEXTURE_CUBE_MAP) + { + for (GLenum face = FirstCubeMapTextureTarget; face <= LastCubeMapTextureTarget; face++) + { + setImageDesc(face, level, levelInfo); + } + } + else + { + setImageDesc(mTarget, level, levelInfo); + } + } +} + +void TextureState::setImageDescChainMultisample(Extents baseSize, + const Format &format, + GLsizei samples, + bool fixedSampleLocations, + InitState initState) +{ + ASSERT(mTarget == GL_TEXTURE_2D_MULTISAMPLE); + ImageDesc levelInfo(baseSize, format, samples, fixedSampleLocations, initState); + setImageDesc(mTarget, 0, levelInfo); +} + +void TextureState::clearImageDesc(GLenum target, size_t level) +{ + setImageDesc(target, level, ImageDesc()); +} + +void TextureState::clearImageDescs() +{ + for (size_t descIndex = 0; descIndex < mImageDescs.size(); descIndex++) + { + mImageDescs[descIndex] = ImageDesc(); + } +} + +Texture::Texture(rx::GLImplFactory *factory, GLuint id, GLenum target) + : egl::ImageSibling(id), + mState(target), + mTexture(factory->createTexture(mState)), + mLabel(), + mBoundSurface(nullptr), + mBoundStream(nullptr) +{ +} + +Error Texture::onDestroy(const Context *context) +{ + if (mBoundSurface) + { + ANGLE_TRY(mBoundSurface->releaseTexImage(context, EGL_BACK_BUFFER)); + mBoundSurface = nullptr; + } + if (mBoundStream) + { + mBoundStream->releaseTextures(); + mBoundStream = nullptr; + } + + ANGLE_TRY(orphanImages(context)); + + if (mTexture) + { + ANGLE_TRY(mTexture->onDestroy(context)); + } + return NoError(); +} + +Texture::~Texture() +{ + SafeDelete(mTexture); +} + +void Texture::setLabel(const std::string &label) +{ + mLabel = label; + mDirtyBits.set(DIRTY_BIT_LABEL); +} + +const std::string &Texture::getLabel() const +{ + return mLabel; +} + +GLenum Texture::getTarget() const +{ + return mState.mTarget; +} + +void Texture::setSwizzleRed(GLenum swizzleRed) +{ + mState.mSwizzleState.swizzleRed = swizzleRed; + mDirtyBits.set(DIRTY_BIT_SWIZZLE_RED); +} + +GLenum Texture::getSwizzleRed() const +{ + return mState.mSwizzleState.swizzleRed; +} + +void Texture::setSwizzleGreen(GLenum swizzleGreen) +{ + mState.mSwizzleState.swizzleGreen = swizzleGreen; + mDirtyBits.set(DIRTY_BIT_SWIZZLE_GREEN); +} + +GLenum Texture::getSwizzleGreen() const +{ + return mState.mSwizzleState.swizzleGreen; +} + +void Texture::setSwizzleBlue(GLenum swizzleBlue) +{ + mState.mSwizzleState.swizzleBlue = swizzleBlue; + mDirtyBits.set(DIRTY_BIT_SWIZZLE_BLUE); +} + +GLenum Texture::getSwizzleBlue() const +{ + return mState.mSwizzleState.swizzleBlue; +} + +void Texture::setSwizzleAlpha(GLenum swizzleAlpha) +{ + mState.mSwizzleState.swizzleAlpha = swizzleAlpha; + mDirtyBits.set(DIRTY_BIT_SWIZZLE_ALPHA); +} + +GLenum Texture::getSwizzleAlpha() const +{ + return mState.mSwizzleState.swizzleAlpha; +} + +void Texture::setMinFilter(GLenum minFilter) +{ + mState.mSamplerState.minFilter = minFilter; + mDirtyBits.set(DIRTY_BIT_MIN_FILTER); +} + +GLenum Texture::getMinFilter() const +{ + return mState.mSamplerState.minFilter; +} + +void Texture::setMagFilter(GLenum magFilter) +{ + mState.mSamplerState.magFilter = magFilter; + mDirtyBits.set(DIRTY_BIT_MAG_FILTER); +} + +GLenum Texture::getMagFilter() const +{ + return mState.mSamplerState.magFilter; +} + +void Texture::setWrapS(GLenum wrapS) +{ + mState.mSamplerState.wrapS = wrapS; + mDirtyBits.set(DIRTY_BIT_WRAP_S); +} + +GLenum Texture::getWrapS() const +{ + return mState.mSamplerState.wrapS; +} + +void Texture::setWrapT(GLenum wrapT) +{ + mState.mSamplerState.wrapT = wrapT; + mDirtyBits.set(DIRTY_BIT_WRAP_T); +} + +GLenum Texture::getWrapT() const +{ + return mState.mSamplerState.wrapT; +} + +void Texture::setWrapR(GLenum wrapR) +{ + mState.mSamplerState.wrapR = wrapR; + mDirtyBits.set(DIRTY_BIT_WRAP_R); +} + +GLenum Texture::getWrapR() const +{ + return mState.mSamplerState.wrapR; +} + +void Texture::setMaxAnisotropy(float maxAnisotropy) +{ + mState.mSamplerState.maxAnisotropy = maxAnisotropy; + mDirtyBits.set(DIRTY_BIT_MAX_ANISOTROPY); +} + +float Texture::getMaxAnisotropy() const +{ + return mState.mSamplerState.maxAnisotropy; +} + +void Texture::setMinLod(GLfloat minLod) +{ + mState.mSamplerState.minLod = minLod; + mDirtyBits.set(DIRTY_BIT_MIN_LOD); +} + +GLfloat Texture::getMinLod() const +{ + return mState.mSamplerState.minLod; +} + +void Texture::setMaxLod(GLfloat maxLod) +{ + mState.mSamplerState.maxLod = maxLod; + mDirtyBits.set(DIRTY_BIT_MAX_LOD); +} + +GLfloat Texture::getMaxLod() const +{ + return mState.mSamplerState.maxLod; +} + +void Texture::setCompareMode(GLenum compareMode) +{ + mState.mSamplerState.compareMode = compareMode; + mDirtyBits.set(DIRTY_BIT_COMPARE_MODE); +} + +GLenum Texture::getCompareMode() const +{ + return mState.mSamplerState.compareMode; +} + +void Texture::setCompareFunc(GLenum compareFunc) +{ + mState.mSamplerState.compareFunc = compareFunc; + mDirtyBits.set(DIRTY_BIT_COMPARE_FUNC); +} + +GLenum Texture::getCompareFunc() const +{ + return mState.mSamplerState.compareFunc; +} + +void Texture::setSRGBDecode(GLenum sRGBDecode) +{ + mState.mSamplerState.sRGBDecode = sRGBDecode; + mDirtyBits.set(DIRTY_BIT_SRGB_DECODE); +} + +GLenum Texture::getSRGBDecode() const +{ + return mState.mSamplerState.sRGBDecode; +} + +const SamplerState &Texture::getSamplerState() const +{ + return mState.mSamplerState; +} + +Error Texture::setBaseLevel(const Context *context, GLuint baseLevel) +{ + if (mState.setBaseLevel(baseLevel)) + { + ANGLE_TRY(mTexture->setBaseLevel(context, mState.getEffectiveBaseLevel())); + mDirtyBits.set(DIRTY_BIT_BASE_LEVEL); + invalidateCompletenessCache(); + } + + return NoError(); +} + +GLuint Texture::getBaseLevel() const +{ + return mState.mBaseLevel; +} + +void Texture::setMaxLevel(GLuint maxLevel) +{ + if (mState.setMaxLevel(maxLevel)) + { + mDirtyBits.set(DIRTY_BIT_MAX_LEVEL); + invalidateCompletenessCache(); + } +} + +GLuint Texture::getMaxLevel() const +{ + return mState.mMaxLevel; +} + +void Texture::setDepthStencilTextureMode(GLenum mode) +{ + if (mode != mState.mDepthStencilTextureMode) + { + // Changing the mode from the default state (GL_DEPTH_COMPONENT) is not implemented yet + UNIMPLEMENTED(); + } + + // TODO(geofflang): add dirty bits + mState.mDepthStencilTextureMode = mode; +} + +GLenum Texture::getDepthStencilTextureMode() const +{ + return mState.mDepthStencilTextureMode; +} + +bool Texture::getImmutableFormat() const +{ + return mState.mImmutableFormat; +} + +GLuint Texture::getImmutableLevels() const +{ + return mState.mImmutableLevels; +} + +void Texture::setUsage(GLenum usage) +{ + mState.mUsage = usage; + mDirtyBits.set(DIRTY_BIT_USAGE); +} + +GLenum Texture::getUsage() const +{ + return mState.mUsage; +} + +const TextureState &Texture::getTextureState() const +{ + return mState; +} + +size_t Texture::getWidth(GLenum target, size_t level) const +{ + ASSERT(target == mState.mTarget || + (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); + return mState.getImageDesc(target, level).size.width; +} + +size_t Texture::getHeight(GLenum target, size_t level) const +{ + ASSERT(target == mState.mTarget || + (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); + return mState.getImageDesc(target, level).size.height; +} + +size_t Texture::getDepth(GLenum target, size_t level) const +{ + ASSERT(target == mState.mTarget || + (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); + return mState.getImageDesc(target, level).size.depth; +} + +const Format &Texture::getFormat(GLenum target, size_t level) const +{ + ASSERT(target == mState.mTarget || + (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); + return mState.getImageDesc(target, level).format; +} + +GLsizei Texture::getSamples(GLenum target, size_t level) const +{ + ASSERT(target == mState.mTarget || + (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); + return mState.getImageDesc(target, level).samples; +} + +bool Texture::getFixedSampleLocations(GLenum target, size_t level) const +{ + ASSERT(target == mState.mTarget || + (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); + return mState.getImageDesc(target, level).fixedSampleLocations; +} + +GLuint Texture::getMipmapMaxLevel() const +{ + return mState.getMipmapMaxLevel(); +} + +bool Texture::isMipmapComplete() const +{ + return mState.computeMipmapCompleteness(); +} + +egl::Surface *Texture::getBoundSurface() const +{ + return mBoundSurface; +} + +egl::Stream *Texture::getBoundStream() const +{ + return mBoundStream; +} + +void Texture::signalDirty(InitState initState) const +{ + mDirtyChannel.signal(initState); + invalidateCompletenessCache(); +} + +Error Texture::setImage(const Context *context, + const PixelUnpackState &unpackState, + GLenum target, + size_t level, + GLenum internalFormat, + const Extents &size, + GLenum format, + GLenum type, + const uint8_t *pixels) +{ + ASSERT(target == mState.mTarget || + (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); + + // Release from previous calls to eglBindTexImage, to avoid calling the Impl after + ANGLE_TRY(releaseTexImageInternal(context)); + ANGLE_TRY(orphanImages(context)); + + ANGLE_TRY(mTexture->setImage(context, target, level, internalFormat, size, format, type, + unpackState, pixels)); + + InitState initState = DetermineInitState(context, pixels); + mState.setImageDesc(target, level, ImageDesc(size, Format(internalFormat, type), initState)); + signalDirty(initState); + + return NoError(); +} + +Error Texture::setSubImage(const Context *context, + const PixelUnpackState &unpackState, + GLenum target, + size_t level, + const Box &area, + GLenum format, + GLenum type, + const uint8_t *pixels) +{ + ASSERT(target == mState.mTarget || + (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); + + ANGLE_TRY(ensureSubImageInitialized(context, target, level, area)); + + return mTexture->setSubImage(context, target, level, area, format, type, unpackState, pixels); +} + +Error Texture::setCompressedImage(const Context *context, + const PixelUnpackState &unpackState, + GLenum target, + size_t level, + GLenum internalFormat, + const Extents &size, + size_t imageSize, + const uint8_t *pixels) +{ + ASSERT(target == mState.mTarget || + (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); + + // Release from previous calls to eglBindTexImage, to avoid calling the Impl after + ANGLE_TRY(releaseTexImageInternal(context)); + ANGLE_TRY(orphanImages(context)); + + ANGLE_TRY(mTexture->setCompressedImage(context, target, level, internalFormat, size, + unpackState, imageSize, pixels)); + + InitState initState = DetermineInitState(context, pixels); + mState.setImageDesc(target, level, ImageDesc(size, Format(internalFormat), initState)); + signalDirty(initState); + + return NoError(); +} + +Error Texture::setCompressedSubImage(const Context *context, + const PixelUnpackState &unpackState, + GLenum target, + size_t level, + const Box &area, + GLenum format, + size_t imageSize, + const uint8_t *pixels) +{ + ASSERT(target == mState.mTarget || + (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); + + ANGLE_TRY(ensureSubImageInitialized(context, target, level, area)); + + return mTexture->setCompressedSubImage(context, target, level, area, format, unpackState, + imageSize, pixels); +} + +Error Texture::copyImage(const Context *context, + GLenum target, + size_t level, + const Rectangle &sourceArea, + GLenum internalFormat, + Framebuffer *source) +{ + ASSERT(target == mState.mTarget || + (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); + + // Release from previous calls to eglBindTexImage, to avoid calling the Impl after + ANGLE_TRY(releaseTexImageInternal(context)); + ANGLE_TRY(orphanImages(context)); + + // Ensure source FBO is initialized. + ANGLE_TRY(source->ensureReadAttachmentInitialized(context, GL_COLOR_BUFFER_BIT)); + + // Use the source FBO size as the init image area. + Box destBox(0, 0, 0, sourceArea.width, sourceArea.height, 1); + ANGLE_TRY(ensureSubImageInitialized(context, target, level, destBox)); + + ANGLE_TRY(mTexture->copyImage(context, target, level, sourceArea, internalFormat, source)); + + const InternalFormat &internalFormatInfo = + GetInternalFormatInfo(internalFormat, GL_UNSIGNED_BYTE); + + mState.setImageDesc(target, level, + ImageDesc(Extents(sourceArea.width, sourceArea.height, 1), + Format(internalFormatInfo), InitState::Initialized)); + + // We need to initialize this texture only if the source attachment is not initialized. + signalDirty(InitState::Initialized); + + return NoError(); +} + +Error Texture::copySubImage(const Context *context, + GLenum target, + size_t level, + const Offset &destOffset, + const Rectangle &sourceArea, + Framebuffer *source) +{ + ASSERT(target == mState.mTarget || + (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); + + // Ensure source FBO is initialized. + ANGLE_TRY(source->ensureReadAttachmentInitialized(context, GL_COLOR_BUFFER_BIT)); + + Box destBox(destOffset.x, destOffset.y, destOffset.y, sourceArea.width, sourceArea.height, 1); + ANGLE_TRY(ensureSubImageInitialized(context, target, level, destBox)); + + return mTexture->copySubImage(context, target, level, destOffset, sourceArea, source); +} + +Error Texture::copyTexture(const Context *context, + GLenum target, + size_t level, + GLenum internalFormat, + GLenum type, + size_t sourceLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + Texture *source) +{ + ASSERT(target == mState.mTarget || + (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); + + // Release from previous calls to eglBindTexImage, to avoid calling the Impl after + ANGLE_TRY(releaseTexImageInternal(context)); + ANGLE_TRY(orphanImages(context)); + + // Initialize source texture. + // Note: we don't have a way to notify which portions of the image changed currently. + ANGLE_TRY(source->ensureInitialized(context)); + + ANGLE_TRY(mTexture->copyTexture(context, target, level, internalFormat, type, sourceLevel, + unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha, + source)); + + const auto &sourceDesc = source->mState.getImageDesc(source->getTarget(), 0); + const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type); + mState.setImageDesc( + target, level, + ImageDesc(sourceDesc.size, Format(internalFormatInfo), InitState::Initialized)); + + signalDirty(InitState::Initialized); + + return NoError(); +} + +Error Texture::copySubTexture(const Context *context, + GLenum target, + size_t level, + const Offset &destOffset, + size_t sourceLevel, + const Rectangle &sourceArea, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + Texture *source) +{ + ASSERT(target == mState.mTarget || + (mState.mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target))); + + // Ensure source is initialized. + ANGLE_TRY(source->ensureInitialized(context)); + + Box destBox(destOffset.x, destOffset.y, destOffset.y, sourceArea.width, sourceArea.height, 1); + ANGLE_TRY(ensureSubImageInitialized(context, target, level, destBox)); + + return mTexture->copySubTexture(context, target, level, destOffset, sourceLevel, sourceArea, + unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha, + source); +} + +Error Texture::copyCompressedTexture(const Context *context, const Texture *source) +{ + // Release from previous calls to eglBindTexImage, to avoid calling the Impl after + ANGLE_TRY(releaseTexImageInternal(context)); + ANGLE_TRY(orphanImages(context)); + + ANGLE_TRY(mTexture->copyCompressedTexture(context, source)); + + ASSERT(source->getTarget() != GL_TEXTURE_CUBE_MAP && getTarget() != GL_TEXTURE_CUBE_MAP); + const auto &sourceDesc = source->mState.getImageDesc(source->getTarget(), 0); + mState.setImageDesc(getTarget(), 0, sourceDesc); + + return NoError(); +} + +Error Texture::setStorage(const Context *context, + GLenum target, + GLsizei levels, + GLenum internalFormat, + const Extents &size) +{ + ASSERT(target == mState.mTarget); + + // Release from previous calls to eglBindTexImage, to avoid calling the Impl after + ANGLE_TRY(releaseTexImageInternal(context)); + ANGLE_TRY(orphanImages(context)); + + ANGLE_TRY(mTexture->setStorage(context, target, levels, internalFormat, size)); + + mState.mImmutableFormat = true; + mState.mImmutableLevels = static_cast(levels); + mState.clearImageDescs(); + mState.setImageDescChain(0, static_cast(levels - 1), size, Format(internalFormat), + InitState::MayNeedInit); + + // Changing the texture to immutable can trigger a change in the base and max levels: + // GLES 3.0.4 section 3.8.10 pg 158: + // "For immutable-format textures, levelbase is clamped to the range[0;levels],levelmax is then + // clamped to the range[levelbase;levels]. + mDirtyBits.set(DIRTY_BIT_BASE_LEVEL); + mDirtyBits.set(DIRTY_BIT_MAX_LEVEL); + + signalDirty(InitState::MayNeedInit); + + return NoError(); +} + +Error Texture::setStorageMultisample(const Context *context, + GLenum target, + GLsizei samples, + GLint internalFormat, + const Extents &size, + bool fixedSampleLocations) +{ + ASSERT(target == mState.mTarget); + + // Release from previous calls to eglBindTexImage, to avoid calling the Impl after + ANGLE_TRY(releaseTexImageInternal(context)); + ANGLE_TRY(orphanImages(context)); + + ANGLE_TRY(mTexture->setStorageMultisample(context, target, samples, internalFormat, size, + fixedSampleLocations)); + + mState.mImmutableFormat = true; + mState.mImmutableLevels = static_cast(1); + mState.clearImageDescs(); + mState.setImageDescChainMultisample(size, Format(internalFormat), samples, fixedSampleLocations, + InitState::MayNeedInit); + + signalDirty(InitState::MayNeedInit); + + return NoError(); +} + +Error Texture::generateMipmap(const Context *context) +{ + // Release from previous calls to eglBindTexImage, to avoid calling the Impl after + ANGLE_TRY(releaseTexImageInternal(context)); + + // EGL_KHR_gl_image states that images are only orphaned when generating mipmaps if the texture + // is not mip complete. + if (!isMipmapComplete()) + { + ANGLE_TRY(orphanImages(context)); + } + + const GLuint baseLevel = mState.getEffectiveBaseLevel(); + const GLuint maxLevel = mState.getMipmapMaxLevel(); + + if (maxLevel > baseLevel) + { + syncState(); + const ImageDesc &baseImageInfo = + mState.getImageDesc(mState.getBaseImageTarget(), baseLevel); + + // Clear the base image immediately if necessary. + if (context->isRobustResourceInitEnabled() && + baseImageInfo.initState == InitState::MayNeedInit) + { + ANGLE_TRY(initializeContents( + context, GetImageIndexFromDescIndex(mState.getBaseImageTarget(), baseLevel))); + } + + ANGLE_TRY(mTexture->generateMipmap(context)); + + mState.setImageDescChain(baseLevel, maxLevel, baseImageInfo.size, baseImageInfo.format, + InitState::Initialized); + } + + signalDirty(InitState::Initialized); + + return NoError(); +} + +Error Texture::bindTexImageFromSurface(const Context *context, egl::Surface *surface) +{ + ASSERT(surface); + + if (mBoundSurface) + { + ANGLE_TRY(releaseTexImageFromSurface(context)); + } + + ANGLE_TRY(mTexture->bindTexImage(context, surface)); + mBoundSurface = surface; + + // Set the image info to the size and format of the surface + ASSERT(mState.mTarget == GL_TEXTURE_2D || mState.mTarget == GL_TEXTURE_RECTANGLE_ANGLE); + Extents size(surface->getWidth(), surface->getHeight(), 1); + ImageDesc desc(size, Format(surface->getConfig()->renderTargetFormat), InitState::Initialized); + mState.setImageDesc(mState.mTarget, 0, desc); + signalDirty(InitState::Initialized); + return NoError(); +} + +Error Texture::releaseTexImageFromSurface(const Context *context) +{ + ASSERT(mBoundSurface); + mBoundSurface = nullptr; + ANGLE_TRY(mTexture->releaseTexImage(context)); + + // Erase the image info for level 0 + ASSERT(mState.mTarget == GL_TEXTURE_2D || mState.mTarget == GL_TEXTURE_RECTANGLE_ANGLE); + mState.clearImageDesc(mState.mTarget, 0); + signalDirty(InitState::Initialized); + return NoError(); +} + +void Texture::bindStream(egl::Stream *stream) +{ + ASSERT(stream); + + // It should not be possible to bind a texture already bound to another stream + ASSERT(mBoundStream == nullptr); + + mBoundStream = stream; + + ASSERT(mState.mTarget == GL_TEXTURE_EXTERNAL_OES); +} + +void Texture::releaseStream() +{ + ASSERT(mBoundStream); + mBoundStream = nullptr; +} + +Error Texture::acquireImageFromStream(const Context *context, + const egl::Stream::GLTextureDescription &desc) +{ + ASSERT(mBoundStream != nullptr); + ANGLE_TRY(mTexture->setImageExternal(context, mState.mTarget, mBoundStream, desc)); + + Extents size(desc.width, desc.height, 1); + mState.setImageDesc(mState.mTarget, 0, + ImageDesc(size, Format(desc.internalFormat), InitState::Initialized)); + signalDirty(InitState::Initialized); + return NoError(); +} + +Error Texture::releaseImageFromStream(const Context *context) +{ + ASSERT(mBoundStream != nullptr); + ANGLE_TRY(mTexture->setImageExternal(context, mState.mTarget, nullptr, + egl::Stream::GLTextureDescription())); + + // Set to incomplete + mState.clearImageDesc(mState.mTarget, 0); + signalDirty(InitState::Initialized); + return NoError(); +} + +Error Texture::releaseTexImageInternal(const Context *context) +{ + if (mBoundSurface) + { + // Notify the surface + mBoundSurface->releaseTexImageFromTexture(context); + + // Then, call the same method as from the surface + ANGLE_TRY(releaseTexImageFromSurface(context)); + } + return NoError(); +} + +Error Texture::setEGLImageTarget(const Context *context, GLenum target, egl::Image *imageTarget) +{ + ASSERT(target == mState.mTarget); + ASSERT(target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES); + + // Release from previous calls to eglBindTexImage, to avoid calling the Impl after + ANGLE_TRY(releaseTexImageInternal(context)); + ANGLE_TRY(orphanImages(context)); + + ANGLE_TRY(mTexture->setEGLImageTarget(context, target, imageTarget)); + + setTargetImage(context, imageTarget); + + Extents size(static_cast(imageTarget->getWidth()), + static_cast(imageTarget->getHeight()), 1); + + auto initState = imageTarget->sourceInitState(); + + mState.clearImageDescs(); + mState.setImageDesc(target, 0, ImageDesc(size, imageTarget->getFormat(), initState)); + signalDirty(initState); + + return NoError(); +} + +Extents Texture::getAttachmentSize(const ImageIndex &imageIndex) const +{ + return mState.getImageDesc(imageIndex).size; +} + +const Format &Texture::getAttachmentFormat(GLenum /*binding*/, const ImageIndex &imageIndex) const +{ + return mState.getImageDesc(imageIndex).format; +} + +GLsizei Texture::getAttachmentSamples(const ImageIndex &imageIndex) const +{ + return getSamples(imageIndex.type, 0); +} + +void Texture::onAttach(const Context *context) { addRef(); } -void Texture::onDetach() +void Texture::onDetach(const Context *context) { - release(); + release(context); } GLuint Texture::getId() const { return id(); } + +void Texture::syncState() +{ + mTexture->syncState(mDirtyBits); + mDirtyBits.reset(); } + +rx::FramebufferAttachmentObjectImpl *Texture::getAttachmentImpl() const +{ + return mTexture; +} + +bool Texture::isSamplerComplete(const Context *context, const Sampler *optionalSampler) +{ + const auto &samplerState = + optionalSampler ? optionalSampler->getSamplerState() : mState.mSamplerState; + const auto &contextState = context->getContextState(); + + if (contextState.getContextID() != mCompletenessCache.context || + mCompletenessCache.samplerState != samplerState) + { + mCompletenessCache.context = context->getContextState().getContextID(); + mCompletenessCache.samplerState = samplerState; + mCompletenessCache.samplerComplete = + mState.computeSamplerCompleteness(samplerState, contextState); + } + + return mCompletenessCache.samplerComplete; +} + +Texture::SamplerCompletenessCache::SamplerCompletenessCache() + : context(0), samplerState(), samplerComplete(false) +{ +} + +void Texture::invalidateCompletenessCache() const +{ + mCompletenessCache.context = 0; +} + +Error Texture::ensureInitialized(const Context *context) +{ + if (!context->isRobustResourceInitEnabled() || mState.mInitState == InitState::Initialized) + { + return NoError(); + } + + bool anyDirty = false; + + for (size_t descIndex = 0; descIndex < mState.mImageDescs.size(); ++descIndex) + { + auto &imageDesc = mState.mImageDescs[descIndex]; + if (imageDesc.initState == InitState::MayNeedInit) + { + ASSERT(mState.mInitState == InitState::MayNeedInit); + const auto &imageIndex = GetImageIndexFromDescIndex(mState.mTarget, descIndex); + ANGLE_TRY(initializeContents(context, imageIndex)); + imageDesc.initState = InitState::Initialized; + anyDirty = true; + } + } + if (anyDirty) + { + signalDirty(InitState::Initialized); + } + mState.mInitState = InitState::Initialized; + + return NoError(); +} + +InitState Texture::initState(const ImageIndex &imageIndex) const +{ + return mState.getImageDesc(imageIndex).initState; +} + +InitState Texture::initState() const +{ + return mState.mInitState; +} + +void Texture::setInitState(const ImageIndex &imageIndex, InitState initState) +{ + ImageDesc newDesc = mState.getImageDesc(imageIndex); + newDesc.initState = initState; + mState.setImageDesc(imageIndex.type, imageIndex.mipIndex, newDesc); +} + +Error Texture::ensureSubImageInitialized(const Context *context, + GLenum target, + size_t level, + const gl::Box &area) +{ + if (!context->isRobustResourceInitEnabled() || mState.mInitState == InitState::Initialized) + { + return NoError(); + } + + // Pre-initialize the texture contents if necessary. + // TODO(jmadill): Check if area overlaps the entire texture. + const auto &imageIndex = GetImageIndexFromDescIndex(target, level); + const auto &desc = mState.getImageDesc(imageIndex); + if (desc.initState == InitState::MayNeedInit) + { + ASSERT(mState.mInitState == InitState::MayNeedInit); + bool coversWholeImage = area.x == 0 && area.y == 0 && area.z == 0 && + area.width == desc.size.width && area.height == desc.size.height && + area.depth == desc.size.depth; + if (!coversWholeImage) + { + ANGLE_TRY(initializeContents(context, imageIndex)); + } + setInitState(imageIndex, InitState::Initialized); + } + + return NoError(); +} + +} // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/Texture.h b/src/3rdparty/angle/src/libANGLE/Texture.h index 7ca8a456fc..7525da2b2f 100644 --- a/src/3rdparty/angle/src/libANGLE/Texture.h +++ b/src/3rdparty/angle/src/libANGLE/Texture.h @@ -13,37 +13,169 @@ #include #include "angle_gl.h" +#include "common/Optional.h" #include "common/debug.h" #include "libANGLE/Caps.h" -#include "libANGLE/Debug.h" #include "libANGLE/Constants.h" +#include "libANGLE/Debug.h" #include "libANGLE/Error.h" #include "libANGLE/FramebufferAttachment.h" #include "libANGLE/Image.h" +#include "libANGLE/Stream.h" #include "libANGLE/angletypes.h" -#include "libANGLE/renderer/TextureImpl.h" +#include "libANGLE/formatutils.h" namespace egl { class Surface; +class Stream; +} + +namespace rx +{ +class GLImplFactory; +class TextureImpl; +class TextureGL; } namespace gl { -class Context; +class ContextState; class Framebuffer; -struct Data; +class Sampler; +class Texture; bool IsMipmapFiltered(const SamplerState &samplerState); +struct ImageDesc final +{ + ImageDesc(); + ImageDesc(const Extents &size, const Format &format, const InitState initState); + ImageDesc(const Extents &size, + const Format &format, + const GLsizei samples, + const bool fixedSampleLocations, + const InitState initState); + + ImageDesc(const ImageDesc &other) = default; + ImageDesc &operator=(const ImageDesc &other) = default; + + Extents size; + Format format; + GLsizei samples; + bool fixedSampleLocations; + + // Needed for robust resource initialization. + InitState initState; +}; + +struct SwizzleState final +{ + SwizzleState(); + SwizzleState(GLenum red, GLenum green, GLenum blue, GLenum alpha); + SwizzleState(const SwizzleState &other) = default; + SwizzleState &operator=(const SwizzleState &other) = default; + + bool swizzleRequired() const; + + bool operator==(const SwizzleState &other) const; + bool operator!=(const SwizzleState &other) const; + + GLenum swizzleRed; + GLenum swizzleGreen; + GLenum swizzleBlue; + GLenum swizzleAlpha; +}; + +// State from Table 6.9 (state per texture object) in the OpenGL ES 3.0.2 spec. +struct TextureState final : private angle::NonCopyable +{ + TextureState(GLenum target); + ~TextureState(); + + bool swizzleRequired() const; + GLuint getEffectiveBaseLevel() const; + GLuint getEffectiveMaxLevel() const; + + // Returns the value called "q" in the GLES 3.0.4 spec section 3.8.10. + GLuint getMipmapMaxLevel() const; + + // Returns true if base level changed. + bool setBaseLevel(GLuint baseLevel); + bool setMaxLevel(GLuint maxLevel); + + bool isCubeComplete() const; + + const ImageDesc &getImageDesc(GLenum target, size_t level) const; + const ImageDesc &getImageDesc(const ImageIndex &imageIndex) const; + + GLenum getTarget() const { return mTarget; } + const SwizzleState &getSwizzleState() const { return mSwizzleState; } + const SamplerState &getSamplerState() const { return mSamplerState; } + GLenum getUsage() const { return mUsage; } + + private: + // Texture needs access to the ImageDesc functions. + friend class Texture; + // TODO(jmadill): Remove TextureGL from friends. + friend class rx::TextureGL; + friend bool operator==(const TextureState &a, const TextureState &b); + + bool computeSamplerCompleteness(const SamplerState &samplerState, + const ContextState &data) const; + bool computeMipmapCompleteness() const; + bool computeLevelCompleteness(GLenum target, size_t level) const; + + GLenum getBaseImageTarget() const; + + void setImageDesc(GLenum target, size_t level, const ImageDesc &desc); + void setImageDescChain(GLuint baselevel, + GLuint maxLevel, + Extents baseSize, + const Format &format, + InitState initState); + void setImageDescChainMultisample(Extents baseSize, + const Format &format, + GLsizei samples, + bool fixedSampleLocations, + InitState initState); + + void clearImageDesc(GLenum target, size_t level); + void clearImageDescs(); + + const GLenum mTarget; + + SwizzleState mSwizzleState; + + SamplerState mSamplerState; + + GLuint mBaseLevel; + GLuint mMaxLevel; + + GLenum mDepthStencilTextureMode; + + bool mImmutableFormat; + GLuint mImmutableLevels; + + // From GL_ANGLE_texture_usage + GLenum mUsage; + + std::vector mImageDescs; + InitState mInitState; +}; + +bool operator==(const TextureState &a, const TextureState &b); +bool operator!=(const TextureState &a, const TextureState &b); + class Texture final : public egl::ImageSibling, - public FramebufferAttachmentObject, public LabeledObject { public: - Texture(rx::TextureImpl *impl, GLuint id, GLenum target); + Texture(rx::GLImplFactory *factory, GLuint id, GLenum target); ~Texture() override; + Error onDestroy(const Context *context) override; + void setLabel(const std::string &label) override; const std::string &getLabel() const override; @@ -91,14 +223,20 @@ class Texture final : public egl::ImageSibling, void setCompareFunc(GLenum compareFunc); GLenum getCompareFunc() const; + void setSRGBDecode(GLenum sRGBDecode); + GLenum getSRGBDecode() const; + const SamplerState &getSamplerState() const; - void setBaseLevel(GLuint baseLevel); + gl::Error setBaseLevel(const Context *context, GLuint baseLevel); GLuint getBaseLevel() const; void setMaxLevel(GLuint maxLevel); GLuint getMaxLevel() const; + void setDepthStencilTextureMode(GLenum mode); + GLenum getDepthStencilTextureMode() const; + bool getImmutableFormat() const; GLuint getImmutableLevels() const; @@ -111,14 +249,17 @@ class Texture final : public egl::ImageSibling, size_t getWidth(GLenum target, size_t level) const; size_t getHeight(GLenum target, size_t level) const; size_t getDepth(GLenum target, size_t level) const; - GLenum getInternalFormat(GLenum target, size_t level) const; + GLsizei getSamples(GLenum target, size_t level) const; + bool getFixedSampleLocations(GLenum target, size_t level) const; + const Format &getFormat(GLenum target, size_t level) const; + + // Returns the value called "q" in the GLES 3.0.4 spec section 3.8.10. + GLuint getMipmapMaxLevel() const; - bool isSamplerComplete(const SamplerState &samplerState, const Data &data) const; bool isMipmapComplete() const; - bool isCubeComplete() const; - size_t getMipCompleteLevels() const; - Error setImage(Context *context, + Error setImage(const Context *context, + const PixelUnpackState &unpackState, GLenum target, size_t level, GLenum internalFormat, @@ -126,7 +267,8 @@ class Texture final : public egl::ImageSibling, GLenum format, GLenum type, const uint8_t *pixels); - Error setSubImage(Context *context, + Error setSubImage(const Context *context, + const PixelUnpackState &unpackState, GLenum target, size_t level, const Box &area, @@ -134,14 +276,16 @@ class Texture final : public egl::ImageSibling, GLenum type, const uint8_t *pixels); - Error setCompressedImage(Context *context, + Error setCompressedImage(const Context *context, + const PixelUnpackState &unpackState, GLenum target, size_t level, GLenum internalFormat, const Extents &size, size_t imageSize, const uint8_t *pixels); - Error setCompressedSubImage(Context *context, + Error setCompressedSubImage(const Context *context, + const PixelUnpackState &unpackState, GLenum target, size_t level, const Box &area, @@ -149,98 +293,179 @@ class Texture final : public egl::ImageSibling, size_t imageSize, const uint8_t *pixels); - Error copyImage(GLenum target, + Error copyImage(const Context *context, + GLenum target, size_t level, const Rectangle &sourceArea, GLenum internalFormat, - const Framebuffer *source); - Error copySubImage(GLenum target, + Framebuffer *source); + Error copySubImage(const Context *context, + GLenum target, size_t level, const Offset &destOffset, const Rectangle &sourceArea, - const Framebuffer *source); + Framebuffer *source); - Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const Extents &size); + Error copyTexture(const Context *context, + GLenum target, + size_t level, + GLenum internalFormat, + GLenum type, + size_t sourceLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + Texture *source); + Error copySubTexture(const Context *context, + GLenum target, + size_t level, + const Offset &destOffset, + size_t sourceLevel, + const Rectangle &sourceArea, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + Texture *source); + Error copyCompressedTexture(const Context *context, const Texture *source); - Error setEGLImageTarget(GLenum target, egl::Image *imageTarget); + Error setStorage(const Context *context, + GLenum target, + GLsizei levels, + GLenum internalFormat, + const Extents &size); - Error generateMipmaps(); + Error setStorageMultisample(const Context *context, + GLenum target, + GLsizei samples, + GLint internalformat, + const Extents &size, + bool fixedSampleLocations); + + Error setEGLImageTarget(const Context *context, GLenum target, egl::Image *imageTarget); + + Error generateMipmap(const Context *context); egl::Surface *getBoundSurface() const; + egl::Stream *getBoundStream() const; - rx::TextureImpl *getImplementation() { return mTexture; } - const rx::TextureImpl *getImplementation() const { return mTexture; } + void signalDirty(InitState initState) const; + + bool isSamplerComplete(const Context *context, const Sampler *optionalSampler); + + rx::TextureImpl *getImplementation() const { return mTexture; } // FramebufferAttachmentObject implementation - Extents getAttachmentSize(const FramebufferAttachment::Target &target) const override; - GLenum getAttachmentInternalFormat(const FramebufferAttachment::Target &target) const override; - GLsizei getAttachmentSamples(const FramebufferAttachment::Target &target) const override; + Extents getAttachmentSize(const ImageIndex &imageIndex) const override; + const Format &getAttachmentFormat(GLenum binding, const ImageIndex &imageIndex) const override; + GLsizei getAttachmentSamples(const ImageIndex &imageIndex) const override; - void onAttach() override; - void onDetach() override; + void onAttach(const Context *context) override; + void onDetach(const Context *context) override; GLuint getId() const override; + // Needed for robust resource init. + Error ensureInitialized(const Context *context); + InitState initState(const ImageIndex &imageIndex) const override; + InitState initState() const; + void setInitState(const ImageIndex &imageIndex, InitState initState) override; + + enum DirtyBitType + { + // Sampler state + DIRTY_BIT_MIN_FILTER, + DIRTY_BIT_MAG_FILTER, + DIRTY_BIT_WRAP_S, + DIRTY_BIT_WRAP_T, + DIRTY_BIT_WRAP_R, + DIRTY_BIT_MAX_ANISOTROPY, + DIRTY_BIT_MIN_LOD, + DIRTY_BIT_MAX_LOD, + DIRTY_BIT_COMPARE_MODE, + DIRTY_BIT_COMPARE_FUNC, + DIRTY_BIT_SRGB_DECODE, + + // Texture state + DIRTY_BIT_SWIZZLE_RED, + DIRTY_BIT_SWIZZLE_GREEN, + DIRTY_BIT_SWIZZLE_BLUE, + DIRTY_BIT_SWIZZLE_ALPHA, + DIRTY_BIT_BASE_LEVEL, + DIRTY_BIT_MAX_LEVEL, + + // Misc + DIRTY_BIT_LABEL, + DIRTY_BIT_USAGE, + + DIRTY_BIT_COUNT, + }; + using DirtyBits = angle::BitSet; + + void syncState(); + bool hasAnyDirtyBit() const { return mDirtyBits.any(); } + private: - rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override { return mTexture; } + rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override; // ANGLE-only method, used internally friend class egl::Surface; - void bindTexImageFromSurface(egl::Surface *surface); - void releaseTexImageFromSurface(); + Error bindTexImageFromSurface(const Context *context, egl::Surface *surface); + Error releaseTexImageFromSurface(const Context *context); + // ANGLE-only methods, used internally + friend class egl::Stream; + void bindStream(egl::Stream *stream); + void releaseStream(); + Error acquireImageFromStream(const Context *context, + const egl::Stream::GLTextureDescription &desc); + Error releaseImageFromStream(const Context *context); + + void invalidateCompletenessCache() const; + Error releaseTexImageInternal(const Context *context); + + Error ensureSubImageInitialized(const Context *context, + GLenum target, + size_t level, + const gl::Box &area); + + TextureState mState; + DirtyBits mDirtyBits; rx::TextureImpl *mTexture; std::string mLabel; - TextureState mTextureState; - - GLenum mTarget; - - struct ImageDesc - { - Extents size; - GLenum internalFormat; - - ImageDesc(); - ImageDesc(const Extents &size, GLenum internalFormat); - }; - - GLenum getBaseImageTarget() const; - - bool computeSamplerCompleteness(const SamplerState &samplerState, const Data &data) const; - bool computeMipmapCompleteness() const; - bool computeLevelCompleteness(GLenum target, size_t level) const; - - const ImageDesc &getImageDesc(GLenum target, size_t level) const; - void setImageDesc(GLenum target, size_t level, const ImageDesc &desc); - void setImageDescChain(size_t levels, Extents baseSize, GLenum sizedInternalFormat); - void clearImageDesc(GLenum target, size_t level); - void clearImageDescs(); - void releaseTexImageInternal(); - - std::vector mImageDescs; + egl::Surface *mBoundSurface; + egl::Stream *mBoundStream; struct SamplerCompletenessCache { SamplerCompletenessCache(); - bool cacheValid; + // Context used to generate this cache entry + ContextID context; // All values that affect sampler completeness that are not stored within // the texture itself SamplerState samplerState; - bool filterable; - GLint clientVersion; - bool supportsNPOT; // Result of the sampler completeness with the above parameters bool samplerComplete; }; - mutable SamplerCompletenessCache mCompletenessCache; - egl::Surface *mBoundSurface; + mutable SamplerCompletenessCache mCompletenessCache; }; +inline bool operator==(const TextureState &a, const TextureState &b) +{ + return a.mSwizzleState == b.mSwizzleState && a.mSamplerState == b.mSamplerState && + a.mBaseLevel == b.mBaseLevel && a.mMaxLevel == b.mMaxLevel && + a.mImmutableFormat == b.mImmutableFormat && a.mImmutableLevels == b.mImmutableLevels && + a.mUsage == b.mUsage; } -#endif // LIBANGLE_TEXTURE_H_ +inline bool operator!=(const TextureState &a, const TextureState &b) +{ + return !(a == b); +} +} // namespace gl + +#endif // LIBANGLE_TEXTURE_H_ diff --git a/src/3rdparty/angle/src/libANGLE/Thread.cpp b/src/3rdparty/angle/src/libANGLE/Thread.cpp new file mode 100644 index 0000000000..d346db1fa2 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/Thread.cpp @@ -0,0 +1,91 @@ +// +// Copyright(c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Thread.cpp : Defines the Thread class which represents a global EGL thread. + +#include "libANGLE/Thread.h" + +#include "libANGLE/Context.h" +#include "libANGLE/Error.h" + +namespace egl +{ +Thread::Thread() + : mError(EGL_SUCCESS), + mAPI(EGL_OPENGL_ES_API), + mContext(static_cast(EGL_NO_CONTEXT)) +{ +} + +void Thread::setError(const Error &error) +{ + mError = error.getCode(); +} + +EGLint Thread::getError() const +{ + return mError; +} + +void Thread::setAPI(EGLenum api) +{ + mAPI = api; +} + +EGLenum Thread::getAPI() const +{ + return mAPI; +} + +void Thread::setCurrent(gl::Context *context) +{ + mContext = context; +} + +Surface *Thread::getCurrentDrawSurface() const +{ + if (mContext) + { + return mContext->getCurrentDrawSurface(); + } + return nullptr; +} + +Surface *Thread::getCurrentReadSurface() const +{ + if (mContext) + { + return mContext->getCurrentReadSurface(); + } + return nullptr; +} + +gl::Context *Thread::getContext() const +{ + return mContext; +} + +gl::Context *Thread::getValidContext() const +{ + if (mContext && mContext->isContextLost()) + { + mContext->handleError(gl::OutOfMemory() << "Context has been lost."); + return nullptr; + } + + return mContext; +} + +Display *Thread::getCurrentDisplay() const +{ + if (mContext) + { + return mContext->getCurrentDisplay(); + } + return nullptr; +} + +} // namespace egl diff --git a/src/3rdparty/angle/src/libANGLE/Thread.h b/src/3rdparty/angle/src/libANGLE/Thread.h new file mode 100644 index 0000000000..6406dad9e0 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/Thread.h @@ -0,0 +1,51 @@ +// +// Copyright(c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Thread.h : Defines the Thread class which represents a global EGL thread. + +#ifndef LIBANGLE_THREAD_H_ +#define LIBANGLE_THREAD_H_ + +#include + +namespace gl +{ +class Context; +} // namespace gl + +namespace egl +{ +class Error; +class Display; +class Surface; + +class Thread +{ + public: + Thread(); + + void setError(const Error &error); + EGLint getError() const; + + void setAPI(EGLenum api); + EGLenum getAPI() const; + + void setCurrent(gl::Context *context); + Surface *getCurrentDrawSurface() const; + Surface *getCurrentReadSurface() const; + gl::Context *getContext() const; + gl::Context *getValidContext() const; + Display *getCurrentDisplay() const; + + private: + EGLint mError; + EGLenum mAPI; + gl::Context *mContext; +}; + +} // namespace egl + +#endif // LIBANGLE_THREAD_H_ diff --git a/src/3rdparty/angle/src/libANGLE/TransformFeedback.cpp b/src/3rdparty/angle/src/libANGLE/TransformFeedback.cpp index b7961971d0..99235debd4 100644 --- a/src/3rdparty/angle/src/libANGLE/TransformFeedback.cpp +++ b/src/3rdparty/angle/src/libANGLE/TransformFeedback.cpp @@ -8,133 +8,204 @@ #include "libANGLE/Buffer.h" #include "libANGLE/Caps.h" +#include "libANGLE/ContextState.h" +#include "libANGLE/Program.h" +#include "libANGLE/renderer/GLImplFactory.h" #include "libANGLE/renderer/TransformFeedbackImpl.h" namespace gl { -TransformFeedback::TransformFeedback(rx::TransformFeedbackImpl *impl, GLuint id, const Caps &caps) - : RefCountObject(id), - mImplementation(impl), - mLabel(), +TransformFeedbackState::TransformFeedbackState(size_t maxIndexedBuffers) + : mLabel(), mActive(false), mPrimitiveMode(GL_NONE), mPaused(false), + mProgram(nullptr), mGenericBuffer(), - mIndexedBuffers(caps.maxTransformFeedbackSeparateAttributes) + mIndexedBuffers(maxIndexedBuffers) { - ASSERT(impl != NULL); +} + +TransformFeedbackState::~TransformFeedbackState() +{ +} + +const BindingPointer &TransformFeedbackState::getGenericBuffer() const +{ + return mGenericBuffer; +} + +const OffsetBindingPointer &TransformFeedbackState::getIndexedBuffer(size_t idx) const +{ + return mIndexedBuffers[idx]; +} + +const std::vector> &TransformFeedbackState::getIndexedBuffers() const +{ + return mIndexedBuffers; +} + +TransformFeedback::TransformFeedback(rx::GLImplFactory *implFactory, GLuint id, const Caps &caps) + : RefCountObject(id), + mState(caps.maxTransformFeedbackSeparateAttributes), + mImplementation(implFactory->createTransformFeedback(mState)) +{ + ASSERT(mImplementation != nullptr); +} + +Error TransformFeedback::onDestroy(const Context *context) +{ + if (mState.mProgram) + { + mState.mProgram->release(context); + mState.mProgram = nullptr; + } + + ASSERT(!mState.mProgram); + mState.mGenericBuffer.set(context, nullptr); + for (size_t i = 0; i < mState.mIndexedBuffers.size(); i++) + { + mState.mIndexedBuffers[i].set(context, nullptr); + } + + return NoError(); } TransformFeedback::~TransformFeedback() { - mGenericBuffer.set(nullptr); - for (size_t i = 0; i < mIndexedBuffers.size(); i++) - { - mIndexedBuffers[i].set(nullptr); - } - SafeDelete(mImplementation); } void TransformFeedback::setLabel(const std::string &label) { - mLabel = label; + mState.mLabel = label; } const std::string &TransformFeedback::getLabel() const { - return mLabel; + return mState.mLabel; } -void TransformFeedback::begin(GLenum primitiveMode) +void TransformFeedback::begin(const Context *context, GLenum primitiveMode, Program *program) { - mActive = true; - mPrimitiveMode = primitiveMode; - mPaused = false; + mState.mActive = true; + mState.mPrimitiveMode = primitiveMode; + mState.mPaused = false; mImplementation->begin(primitiveMode); + bindProgram(context, program); } -void TransformFeedback::end() +void TransformFeedback::end(const Context *context) { - mActive = false; - mPrimitiveMode = GL_NONE; - mPaused = false; + mState.mActive = false; + mState.mPrimitiveMode = GL_NONE; + mState.mPaused = false; mImplementation->end(); + if (mState.mProgram) + { + mState.mProgram->release(context); + mState.mProgram = nullptr; + } } void TransformFeedback::pause() { - mPaused = true; + mState.mPaused = true; mImplementation->pause(); } void TransformFeedback::resume() { - mPaused = false; + mState.mPaused = false; mImplementation->resume(); } bool TransformFeedback::isActive() const { - return mActive; + return mState.mActive; } bool TransformFeedback::isPaused() const { - return mPaused; + return mState.mPaused; } GLenum TransformFeedback::getPrimitiveMode() const { - return mPrimitiveMode; + return mState.mPrimitiveMode; } -void TransformFeedback::bindGenericBuffer(Buffer *buffer) +void TransformFeedback::bindProgram(const Context *context, Program *program) { - mGenericBuffer.set(buffer); - mImplementation->bindGenericBuffer(mGenericBuffer); -} - -void TransformFeedback::detachBuffer(GLuint bufferName) -{ - for (size_t index = 0; index < mIndexedBuffers.size(); index++) + if (mState.mProgram != program) { - if (mIndexedBuffers[index].id() == bufferName) + if (mState.mProgram != nullptr) { - mIndexedBuffers[index].set(nullptr); - mImplementation->bindIndexedBuffer(index, mIndexedBuffers[index]); + mState.mProgram->release(context); + } + mState.mProgram = program; + if (mState.mProgram != nullptr) + { + mState.mProgram->addRef(); + } + } +} + +bool TransformFeedback::hasBoundProgram(GLuint program) const +{ + return mState.mProgram != nullptr && mState.mProgram->id() == program; +} + +void TransformFeedback::bindGenericBuffer(const Context *context, Buffer *buffer) +{ + mState.mGenericBuffer.set(context, buffer); + mImplementation->bindGenericBuffer(mState.mGenericBuffer); +} + +void TransformFeedback::detachBuffer(const Context *context, GLuint bufferName) +{ + for (size_t index = 0; index < mState.mIndexedBuffers.size(); index++) + { + if (mState.mIndexedBuffers[index].id() == bufferName) + { + mState.mIndexedBuffers[index].set(context, nullptr); + mImplementation->bindIndexedBuffer(index, mState.mIndexedBuffers[index]); } } - if (mGenericBuffer.id() == bufferName) + if (mState.mGenericBuffer.id() == bufferName) { - mGenericBuffer.set(nullptr); - mImplementation->bindGenericBuffer(mGenericBuffer); + mState.mGenericBuffer.set(context, nullptr); + mImplementation->bindGenericBuffer(mState.mGenericBuffer); } } const BindingPointer &TransformFeedback::getGenericBuffer() const { - return mGenericBuffer; + return mState.mGenericBuffer; } -void TransformFeedback::bindIndexedBuffer(size_t index, Buffer *buffer, size_t offset, size_t size) +void TransformFeedback::bindIndexedBuffer(const Context *context, + size_t index, + Buffer *buffer, + size_t offset, + size_t size) { - ASSERT(index < mIndexedBuffers.size()); - mIndexedBuffers[index].set(buffer, offset, size); - mImplementation->bindIndexedBuffer(index, mIndexedBuffers[index]); + ASSERT(index < mState.mIndexedBuffers.size()); + mState.mIndexedBuffers[index].set(context, buffer, offset, size); + mImplementation->bindIndexedBuffer(index, mState.mIndexedBuffers[index]); } const OffsetBindingPointer &TransformFeedback::getIndexedBuffer(size_t index) const { - ASSERT(index < mIndexedBuffers.size()); - return mIndexedBuffers[index]; + ASSERT(index < mState.mIndexedBuffers.size()); + return mState.mIndexedBuffers[index]; } size_t TransformFeedback::getIndexedBufferCount() const { - return mIndexedBuffers.size(); + return mState.mIndexedBuffers.size(); } rx::TransformFeedbackImpl *TransformFeedback::getImplementation() diff --git a/src/3rdparty/angle/src/libANGLE/TransformFeedback.h b/src/3rdparty/angle/src/libANGLE/TransformFeedback.h index 098e4ea4d6..2b35d43f9a 100644 --- a/src/3rdparty/angle/src/libANGLE/TransformFeedback.h +++ b/src/3rdparty/angle/src/libANGLE/TransformFeedback.h @@ -16,6 +16,7 @@ namespace rx { +class GLImplFactory; class TransformFeedbackImpl; } @@ -23,39 +24,21 @@ namespace gl { class Buffer; struct Caps; +class Context; +class Program; -class TransformFeedback final : public RefCountObject, public LabeledObject +class TransformFeedbackState final : angle::NonCopyable { public: - TransformFeedback(rx::TransformFeedbackImpl* impl, GLuint id, const Caps &caps); - virtual ~TransformFeedback(); + TransformFeedbackState(size_t maxIndexedBuffers); + ~TransformFeedbackState(); - void setLabel(const std::string &label) override; - const std::string &getLabel() const override; - - void begin(GLenum primitiveMode); - void end(); - void pause(); - void resume(); - - bool isActive() const; - bool isPaused() const; - GLenum getPrimitiveMode() const; - - void bindGenericBuffer(Buffer *buffer); const BindingPointer &getGenericBuffer() const; - - void bindIndexedBuffer(size_t index, Buffer *buffer, size_t offset, size_t size); - const OffsetBindingPointer &getIndexedBuffer(size_t index) const; - size_t getIndexedBufferCount() const; - - void detachBuffer(GLuint bufferName); - - rx::TransformFeedbackImpl *getImplementation(); - const rx::TransformFeedbackImpl *getImplementation() const; + const OffsetBindingPointer &getIndexedBuffer(size_t idx) const; + const std::vector> &getIndexedBuffers() const; private: - rx::TransformFeedbackImpl* mImplementation; + friend class TransformFeedback; std::string mLabel; @@ -63,10 +46,56 @@ class TransformFeedback final : public RefCountObject, public LabeledObject GLenum mPrimitiveMode; bool mPaused; + Program *mProgram; + BindingPointer mGenericBuffer; std::vector> mIndexedBuffers; }; +class TransformFeedback final : public RefCountObject, public LabeledObject +{ + public: + TransformFeedback(rx::GLImplFactory *implFactory, GLuint id, const Caps &caps); + ~TransformFeedback() override; + Error onDestroy(const Context *context) override; + + void setLabel(const std::string &label) override; + const std::string &getLabel() const override; + + void begin(const Context *context, GLenum primitiveMode, Program *program); + void end(const Context *context); + void pause(); + void resume(); + + bool isActive() const; + bool isPaused() const; + GLenum getPrimitiveMode() const; + + bool hasBoundProgram(GLuint program) const; + + void bindGenericBuffer(const Context *context, Buffer *buffer); + const BindingPointer &getGenericBuffer() const; + + void bindIndexedBuffer(const Context *context, + size_t index, + Buffer *buffer, + size_t offset, + size_t size); + const OffsetBindingPointer &getIndexedBuffer(size_t index) const; + size_t getIndexedBufferCount() const; + + void detachBuffer(const Context *context, GLuint bufferName); + + rx::TransformFeedbackImpl *getImplementation(); + const rx::TransformFeedbackImpl *getImplementation() const; + + private: + void bindProgram(const Context *context, Program *program); + + TransformFeedbackState mState; + rx::TransformFeedbackImpl* mImplementation; +}; + } #endif // LIBANGLE_TRANSFORM_FEEDBACK_H_ diff --git a/src/3rdparty/angle/src/libANGLE/Uniform.cpp b/src/3rdparty/angle/src/libANGLE/Uniform.cpp index bfae3c014f..dee8eee915 100644 --- a/src/3rdparty/angle/src/libANGLE/Uniform.cpp +++ b/src/3rdparty/angle/src/libANGLE/Uniform.cpp @@ -13,46 +13,99 @@ namespace gl { +StaticallyUsed::StaticallyUsed() + : vertexStaticUse(false), fragmentStaticUse(false), computeStaticUse(false) +{ +} + +StaticallyUsed::~StaticallyUsed() +{ +} + +StaticallyUsed::StaticallyUsed(const StaticallyUsed &rhs) = default; +StaticallyUsed &StaticallyUsed::operator=(const StaticallyUsed &rhs) = default; + +void StaticallyUsed::setStaticUse(GLenum shaderType, bool used) +{ + switch (shaderType) + { + case GL_VERTEX_SHADER: + vertexStaticUse = used; + break; + + case GL_FRAGMENT_SHADER: + fragmentStaticUse = used; + break; + + case GL_COMPUTE_SHADER: + computeStaticUse = used; + break; + + default: + UNREACHABLE(); + } +} + +void StaticallyUsed::unionReferencesWith(const StaticallyUsed &other) +{ + vertexStaticUse |= other.vertexStaticUse; + fragmentStaticUse |= other.fragmentStaticUse; + computeStaticUse |= other.computeStaticUse; +} + LinkedUniform::LinkedUniform() - : blockIndex(-1), blockInfo(sh::BlockMemberInfo::getDefaultBlockInfo()) + : typeInfo(nullptr), bufferIndex(-1), blockInfo(sh::BlockMemberInfo::getDefaultBlockInfo()) { } LinkedUniform::LinkedUniform(GLenum typeIn, GLenum precisionIn, const std::string &nameIn, - unsigned int arraySizeIn, - const int blockIndexIn, + const std::vector &arraySizesIn, + const int bindingIn, + const int offsetIn, + const int locationIn, + const int bufferIndexIn, const sh::BlockMemberInfo &blockInfoIn) - : blockIndex(blockIndexIn), blockInfo(blockInfoIn) + : typeInfo(&GetUniformTypeInfo(typeIn)), bufferIndex(bufferIndexIn), blockInfo(blockInfoIn) { type = typeIn; precision = precisionIn; name = nameIn; - arraySize = arraySizeIn; + arraySizes = arraySizesIn; + binding = bindingIn; + offset = offsetIn; + location = locationIn; + ASSERT(!isArrayOfArrays()); + ASSERT(!isArray() || !isStruct()); } LinkedUniform::LinkedUniform(const sh::Uniform &uniform) - : sh::Uniform(uniform), blockIndex(-1), blockInfo(sh::BlockMemberInfo::getDefaultBlockInfo()) + : sh::Uniform(uniform), + typeInfo(&GetUniformTypeInfo(type)), + bufferIndex(-1), + blockInfo(sh::BlockMemberInfo::getDefaultBlockInfo()) { + ASSERT(!isArrayOfArrays()); + ASSERT(!isArray() || !isStruct()); } LinkedUniform::LinkedUniform(const LinkedUniform &uniform) - : sh::Uniform(uniform), blockIndex(uniform.blockIndex), blockInfo(uniform.blockInfo) + : sh::Uniform(uniform), + StaticallyUsed(uniform), + typeInfo(uniform.typeInfo), + bufferIndex(uniform.bufferIndex), + blockInfo(uniform.blockInfo) { - // This function is not intended to be called during runtime. - ASSERT(uniform.mLazyData.empty()); } LinkedUniform &LinkedUniform::operator=(const LinkedUniform &uniform) { - // This function is not intended to be called during runtime. - ASSERT(uniform.mLazyData.empty()); - sh::Uniform::operator=(uniform); - blockIndex = uniform.blockIndex; + StaticallyUsed::operator=(uniform); + typeInfo = uniform.typeInfo; + bufferIndex = uniform.bufferIndex; blockInfo = uniform.blockInfo; - return *this; } @@ -62,41 +115,22 @@ LinkedUniform::~LinkedUniform() bool LinkedUniform::isInDefaultBlock() const { - return blockIndex == -1; -} - -size_t LinkedUniform::dataSize() const -{ - ASSERT(type != GL_STRUCT_ANGLEX); - if (mLazyData.empty()) - { - mLazyData.resize(VariableExternalSize(type) * elementCount()); - ASSERT(!mLazyData.empty()); - } - - return mLazyData.size(); -} - -uint8_t *LinkedUniform::data() -{ - if (mLazyData.empty()) - { - // dataSize() will init the data store. - size_t size = dataSize(); - memset(mLazyData.data(), 0, size); - } - - return mLazyData.data(); -} - -const uint8_t *LinkedUniform::data() const -{ - return const_cast(this)->data(); + return bufferIndex == -1; } bool LinkedUniform::isSampler() const { - return IsSamplerType(type); + return typeInfo->isSampler; +} + +bool LinkedUniform::isImage() const +{ + return typeInfo->isImageType; +} + +bool LinkedUniform::isAtomicCounter() const +{ + return IsAtomicCounterType(type); } bool LinkedUniform::isField() const @@ -106,36 +140,67 @@ bool LinkedUniform::isField() const size_t LinkedUniform::getElementSize() const { - return VariableExternalSize(type); + return typeInfo->externalSize; } -uint8_t *LinkedUniform::getDataPtrToElement(size_t elementIndex) +size_t LinkedUniform::getElementComponents() const { - ASSERT((!isArray() && elementIndex == 0) || (isArray() && elementIndex < arraySize)); - return data() + getElementSize() * elementIndex; + return typeInfo->componentCount; } -const uint8_t *LinkedUniform::getDataPtrToElement(size_t elementIndex) const -{ - return const_cast(this)->getDataPtrToElement(elementIndex); -} - -UniformBlock::UniformBlock() - : isArray(false), arrayElement(0), dataSize(0), vertexStaticUse(false), fragmentStaticUse(false) +BufferVariable::BufferVariable() + : bufferIndex(-1), blockInfo(sh::BlockMemberInfo::getDefaultBlockInfo()), topLevelArraySize(-1) { } -UniformBlock::UniformBlock(const std::string &nameIn, bool isArrayIn, unsigned int arrayElementIn) - : name(nameIn), - isArray(isArrayIn), - arrayElement(arrayElementIn), - dataSize(0), - vertexStaticUse(false), - fragmentStaticUse(false) +BufferVariable::BufferVariable(GLenum typeIn, + GLenum precisionIn, + const std::string &nameIn, + const std::vector &arraySizesIn, + const int bufferIndexIn, + const sh::BlockMemberInfo &blockInfoIn) + : bufferIndex(bufferIndexIn), blockInfo(blockInfoIn), topLevelArraySize(-1) +{ + type = typeIn; + precision = precisionIn; + name = nameIn; + arraySizes = arraySizesIn; +} + +BufferVariable::~BufferVariable() { } -std::string UniformBlock::nameWithArrayIndex() const +ShaderVariableBuffer::ShaderVariableBuffer() : binding(0), dataSize(0) +{ +} + +ShaderVariableBuffer::ShaderVariableBuffer(const ShaderVariableBuffer &other) = default; + +ShaderVariableBuffer::~ShaderVariableBuffer() +{ +} + +int ShaderVariableBuffer::numActiveVariables() const +{ + return static_cast(memberIndexes.size()); +} + +InterfaceBlock::InterfaceBlock() : isArray(false), arrayElement(0) +{ +} + +InterfaceBlock::InterfaceBlock(const std::string &nameIn, + const std::string &mappedNameIn, + bool isArrayIn, + unsigned int arrayElementIn, + int bindingIn) + : name(nameIn), mappedName(mappedNameIn), isArray(isArrayIn), arrayElement(arrayElementIn) +{ + binding = bindingIn; +} + +std::string InterfaceBlock::nameWithArrayIndex() const { std::stringstream fullNameStr; fullNameStr << name; @@ -146,4 +211,16 @@ std::string UniformBlock::nameWithArrayIndex() const return fullNameStr.str(); } + +std::string InterfaceBlock::mappedNameWithArrayIndex() const +{ + std::stringstream fullNameStr; + fullNameStr << mappedName; + if (isArray) + { + fullNameStr << "[" << arrayElement << "]"; + } + + return fullNameStr.str(); +} } diff --git a/src/3rdparty/angle/src/libANGLE/Uniform.h b/src/3rdparty/angle/src/libANGLE/Uniform.h index e62a583f3d..14c39387a6 100644 --- a/src/3rdparty/angle/src/libANGLE/Uniform.h +++ b/src/3rdparty/angle/src/libANGLE/Uniform.h @@ -18,53 +18,107 @@ namespace gl { +struct UniformTypeInfo; -// Helper struct representing a single shader uniform -struct LinkedUniform : public sh::Uniform +struct StaticallyUsed { - LinkedUniform(); - LinkedUniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, const int blockIndex, const sh::BlockMemberInfo &blockInfo); - LinkedUniform(const sh::Uniform &uniform); - LinkedUniform(const LinkedUniform &uniform); - LinkedUniform &operator=(const LinkedUniform &uniform); - ~LinkedUniform(); + StaticallyUsed(); + StaticallyUsed(const StaticallyUsed &rhs); + virtual ~StaticallyUsed(); - size_t dataSize() const; - uint8_t *data(); - const uint8_t *data() const; - bool isSampler() const; - bool isInDefaultBlock() const; - bool isField() const; - size_t getElementSize() const; - uint8_t *getDataPtrToElement(size_t elementIndex); - const uint8_t *getDataPtrToElement(size_t elementIndex) const; + StaticallyUsed &operator=(const StaticallyUsed &rhs); - int blockIndex; - sh::BlockMemberInfo blockInfo; - - private: - mutable rx::MemoryBuffer mLazyData; -}; - -// Helper struct representing a single shader uniform block -struct UniformBlock -{ - UniformBlock(); - UniformBlock(const std::string &nameIn, bool isArrayIn, unsigned int arrayElementIn); - UniformBlock(const UniformBlock &other) = default; - UniformBlock &operator=(const UniformBlock &other) = default; - - std::string nameWithArrayIndex() const; - - std::string name; - bool isArray; - unsigned int arrayElement; - unsigned int dataSize; + void setStaticUse(GLenum shaderType, bool used); + void unionReferencesWith(const StaticallyUsed &other); bool vertexStaticUse; bool fragmentStaticUse; + bool computeStaticUse; +}; - std::vector memberUniformIndexes; +// Helper struct representing a single shader uniform +struct LinkedUniform : public sh::Uniform, public StaticallyUsed +{ + LinkedUniform(); + LinkedUniform(GLenum type, + GLenum precision, + const std::string &name, + const std::vector &arraySizes, + const int binding, + const int offset, + const int location, + const int bufferIndex, + const sh::BlockMemberInfo &blockInfo); + LinkedUniform(const sh::Uniform &uniform); + LinkedUniform(const LinkedUniform &uniform); + LinkedUniform &operator=(const LinkedUniform &uniform); + ~LinkedUniform() override; + + bool isSampler() const; + bool isImage() const; + bool isAtomicCounter() const; + bool isInDefaultBlock() const; + bool isField() const; + size_t getElementSize() const; + size_t getElementComponents() const; + + const UniformTypeInfo *typeInfo; + + // Identifies the containing buffer backed resource -- interface block or atomic counter buffer. + int bufferIndex; + sh::BlockMemberInfo blockInfo; +}; + +struct BufferVariable : public sh::ShaderVariable, public StaticallyUsed +{ + BufferVariable(); + BufferVariable(GLenum type, + GLenum precision, + const std::string &name, + const std::vector &arraySizes, + const int bufferIndex, + const sh::BlockMemberInfo &blockInfo); + ~BufferVariable() override; + + int bufferIndex; + sh::BlockMemberInfo blockInfo; + + int topLevelArraySize; +}; + +// Parent struct for atomic counter, uniform block, and shader storage block buffer, which all +// contain a group of shader variables, and have a GL buffer backed. +struct ShaderVariableBuffer : public StaticallyUsed +{ + ShaderVariableBuffer(); + ShaderVariableBuffer(const ShaderVariableBuffer &other); + ~ShaderVariableBuffer() override; + int numActiveVariables() const; + + int binding; + unsigned int dataSize; + std::vector memberIndexes; +}; + +using AtomicCounterBuffer = ShaderVariableBuffer; + +// Helper struct representing a single shader interface block +struct InterfaceBlock : public ShaderVariableBuffer +{ + InterfaceBlock(); + InterfaceBlock(const std::string &nameIn, + const std::string &mappedNameIn, + bool isArrayIn, + unsigned int arrayElementIn, + int bindingIn); + + std::string nameWithArrayIndex() const; + std::string mappedNameWithArrayIndex() const; + + std::string name; + std::string mappedName; + bool isArray; + unsigned int arrayElement; }; } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/VaryingPacking.cpp b/src/3rdparty/angle/src/libANGLE/VaryingPacking.cpp similarity index 51% rename from src/3rdparty/angle/src/libANGLE/renderer/d3d/VaryingPacking.cpp rename to src/3rdparty/angle/src/libANGLE/VaryingPacking.cpp index f2654d34e3..6fc707b549 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/VaryingPacking.cpp +++ b/src/3rdparty/angle/src/libANGLE/VaryingPacking.cpp @@ -4,75 +4,103 @@ // found in the LICENSE file. // // VaryingPacking: -// Class which describes a mapping from varyings to registers in D3D -// for linking between shader stages. +// Class which describes a mapping from varyings to registers, according +// to the spec, or using custom packing algorithms. We also keep a register +// allocation list for the D3D renderer. // -#include "libANGLE/renderer/d3d/VaryingPacking.h" +#include "libANGLE/VaryingPacking.h" #include "common/utilities.h" -#include "compiler/translator/blocklayoutHLSL.h" -#include "libANGLE/renderer/d3d/DynamicHLSL.h" -#include "libANGLE/renderer/d3d/ProgramD3D.h" +#include "libANGLE/Program.h" +#include "libANGLE/Shader.h" -namespace rx +namespace gl { -// Implementation of VaryingPacking::BuiltinVarying -VaryingPacking::BuiltinVarying::BuiltinVarying() : enabled(false), index(0), systemValue(false) +namespace { + +// true if varying x has a higher priority in packing than y +bool ComparePackedVarying(const PackedVarying &x, const PackedVarying &y) +{ + // If the PackedVarying 'x' or 'y' to be compared is an array element, this clones an equivalent + // non-array shader variable 'vx' or 'vy' for actual comparison instead. + sh::ShaderVariable vx, vy; + const sh::ShaderVariable *px, *py; + if (x.isArrayElement()) + { + vx = *x.varying; + vx.arraySizes.clear(); + px = &vx; + } + else + { + px = x.varying; + } + + if (y.isArrayElement()) + { + vy = *y.varying; + vy.arraySizes.clear(); + py = &vy; + } + else + { + py = y.varying; + } + + return gl::CompareShaderVar(*px, *py); } -std::string VaryingPacking::BuiltinVarying::str() const -{ - return (systemValue ? semantic : (semantic + Str(index))); -} - -void VaryingPacking::BuiltinVarying::enableSystem(const std::string &systemValueSemantic) -{ - enabled = true; - semantic = systemValueSemantic; - systemValue = true; -} - -void VaryingPacking::BuiltinVarying::enable(const std::string &semanticVal, unsigned int indexVal) -{ - enabled = true; - semantic = semanticVal; - index = indexVal; -} +} // anonymous namespace // Implementation of VaryingPacking -VaryingPacking::VaryingPacking(GLuint maxVaryingVectors) - : mRegisterMap(maxVaryingVectors), mBuiltinInfo(SHADER_TYPE_MAX) +VaryingPacking::VaryingPacking(GLuint maxVaryingVectors, PackMode packMode) + : mRegisterMap(maxVaryingVectors), mPackMode(packMode) { } +VaryingPacking::~VaryingPacking() = default; + // Packs varyings into generic varying registers, using the algorithm from // See [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111 // Also [OpenGL ES Shading Language 3.00 rev. 4] Section 11 page 119 // Returns false if unsuccessful. bool VaryingPacking::packVarying(const PackedVarying &packedVarying) { - unsigned int varyingRows = 0; - unsigned int varyingColumns = 0; - const auto &varying = *packedVarying.varying; // "Non - square matrices of type matCxR consume the same space as a square matrix of type matN - // where N is the greater of C and R.Variables of type mat2 occupies 2 complete rows." + // where N is the greater of C and R." // Here we are a bit more conservative and allow packing non-square matrices more tightly. // Make sure we use transposed matrix types to count registers correctly. ASSERT(!varying.isStruct()); - GLenum transposedType = gl::TransposeMatrixType(varying.type); - varyingRows = gl::VariableRowCount(transposedType); - varyingColumns = gl::VariableColumnCount(transposedType); + GLenum transposedType = gl::TransposeMatrixType(varying.type); + unsigned int varyingRows = gl::VariableRowCount(transposedType); + unsigned int varyingColumns = gl::VariableColumnCount(transposedType); + + // "Variables of type mat2 occupies 2 complete rows." + // For non-WebGL contexts, we allow mat2 to occupy only two columns per row. + if (mPackMode == PackMode::WEBGL_STRICT && varying.type == GL_FLOAT_MAT2) + { + varyingColumns = 4; + } // "Arrays of size N are assumed to take N times the size of the base type" - varyingRows *= varying.elementCount(); + // GLSL ES 3.10 section 4.3.6: Output variables cannot be arrays of arrays or arrays of + // structures, so we may use getBasicTypeElementCount(). + const unsigned int elementCount = varying.getBasicTypeElementCount(); + varyingRows *= (packedVarying.isArrayElement() ? 1 : elementCount); unsigned int maxVaryingVectors = static_cast(mRegisterMap.size()); + // Fail if we are packing a single over-large varying. + if (varyingRows > maxVaryingVectors) + { + return false; + } + // "For 2, 3 and 4 component variables packing is started using the 1st column of the 1st row. // Variables are then allocated to successive rows, aligning them to the 1st column." if (varyingColumns >= 2 && varyingColumns <= 4) @@ -157,9 +185,15 @@ bool VaryingPacking::packVarying(const PackedVarying &packedVarying) registerInfo.packedVarying = &packedVarying; registerInfo.registerRow = row + arrayIndex; registerInfo.registerColumn = bestColumn; - registerInfo.varyingArrayIndex = arrayIndex; - registerInfo.varyingRowIndex = 0; - mRegisterList.push_back(registerInfo); + registerInfo.varyingArrayIndex = + (packedVarying.isArrayElement() ? packedVarying.arrayIndex : arrayIndex); + registerInfo.varyingRowIndex = 0; + // Do not record register info for builtins. + // TODO(jmadill): Clean this up. + if (!packedVarying.varying->isBuiltIn()) + { + mRegisterList.push_back(registerInfo); + } mRegisterMap[row + arrayIndex][bestColumn] = true; } break; @@ -209,14 +243,26 @@ void VaryingPacking::insert(unsigned int registerRow, registerInfo.packedVarying = &packedVarying; registerInfo.registerColumn = registerColumn; - for (unsigned int arrayElement = 0; arrayElement < varying.elementCount(); ++arrayElement) + // GLSL ES 3.10 section 4.3.6: Output variables cannot be arrays of arrays or arrays of + // structures, so we may use getBasicTypeElementCount(). + const unsigned int arrayElementCount = varying.getBasicTypeElementCount(); + for (unsigned int arrayElement = 0; arrayElement < arrayElementCount; ++arrayElement) { + if (packedVarying.isArrayElement() && arrayElement != packedVarying.arrayIndex) + { + continue; + } for (unsigned int varyingRow = 0; varyingRow < varyingRows; ++varyingRow) { - registerInfo.registerRow = registerRow + (arrayElement * varyingRows) + varyingRow; - registerInfo.varyingRowIndex = varyingRow; + registerInfo.registerRow = registerRow + (arrayElement * varyingRows) + varyingRow; + registerInfo.varyingRowIndex = varyingRow; registerInfo.varyingArrayIndex = arrayElement; - mRegisterList.push_back(registerInfo); + // Do not record register info for builtins. + // TODO(jmadill): Clean this up. + if (!packedVarying.varying->isBuiltIn()) + { + mRegisterList.push_back(registerInfo); + } for (unsigned int columnIndex = 0; columnIndex < varyingColumns; ++columnIndex) { @@ -226,76 +272,111 @@ void VaryingPacking::insert(unsigned int registerRow, } } -// See comment on packVarying. -bool VaryingPacking::packVaryings(gl::InfoLog &infoLog, - const std::vector &packedVaryings, - const std::vector &transformFeedbackVaryings) +bool VaryingPacking::collectAndPackUserVaryings(gl::InfoLog &infoLog, + const Program::MergedVaryings &mergedVaryings, + const std::vector &tfVaryings) +{ + std::set uniqueFullNames; + mPackedVaryings.clear(); + + for (const auto &ref : mergedVaryings) + { + const sh::Varying *input = ref.second.vertex; + const sh::Varying *output = ref.second.fragment; + + // Only pack statically used varyings that have a matched input or output, plus special + // builtins. + if (((input && output) || (output && output->isBuiltIn())) && output->staticUse) + { + // Will get the vertex shader interpolation by default. + auto interpolation = ref.second.get()->interpolation; + + // Note that we lose the vertex shader static use information here. The data for the + // variable is taken from the fragment shader. + if (output->isStruct()) + { + ASSERT(!output->isArray()); + for (const auto &field : output->fields) + { + ASSERT(!field.isStruct() && !field.isArray()); + mPackedVaryings.push_back(PackedVarying(field, interpolation, output->name)); + uniqueFullNames.insert(mPackedVaryings.back().nameWithArrayIndex()); + } + } + else + { + mPackedVaryings.push_back(PackedVarying(*output, interpolation)); + uniqueFullNames.insert(mPackedVaryings.back().nameWithArrayIndex()); + } + continue; + } + + // Keep Transform FB varyings in the merged list always. + if (!input) + { + continue; + } + + for (const std::string &tfVarying : tfVaryings) + { + std::vector subscripts; + std::string baseName = ParseResourceName(tfVarying, &subscripts); + size_t subscript = GL_INVALID_INDEX; + if (!subscripts.empty()) + { + subscript = subscripts.back(); + } + // Already packed for fragment shader. + if (uniqueFullNames.count(tfVarying) > 0 || uniqueFullNames.count(baseName) > 0) + { + continue; + } + // Array as a whole and array element conflict has already been checked in + // linkValidateTransformFeedback. + if (baseName == input->name) + { + // Transform feedback for varying structs is underspecified. + // See Khronos bug 9856. + // TODO(jmadill): Figure out how to be spec-compliant here. + if (!input->isStruct() && tfVarying.compare(0, 3, "gl_") != 0) + { + mPackedVaryings.push_back(PackedVarying(*input, input->interpolation)); + mPackedVaryings.back().vertexOnly = true; + mPackedVaryings.back().arrayIndex = static_cast(subscript); + uniqueFullNames.insert(tfVarying); + } + // Continue to match next array element for 'input' if the current match is array + // element. + if (subscript == GL_INVALID_INDEX) + { + break; + } + } + } + } + + std::sort(mPackedVaryings.begin(), mPackedVaryings.end(), ComparePackedVarying); + + return packUserVaryings(infoLog, mPackedVaryings, tfVaryings); +} + +// See comment on packVarying. +bool VaryingPacking::packUserVaryings(gl::InfoLog &infoLog, + const std::vector &packedVaryings, + const std::vector &transformFeedbackVaryings) { - std::set uniqueVaryingNames; // "Variables are packed into the registers one at a time so that they each occupy a contiguous // subrectangle. No splitting of variables is permitted." for (const PackedVarying &packedVarying : packedVaryings) { - const auto &varying = *packedVarying.varying; - - // Do not assign registers to built-in or unreferenced varyings - if (varying.isBuiltIn() || (!varying.staticUse && !packedVarying.isStructField())) + if (!packVarying(packedVarying)) { - continue; - } - - ASSERT(!varying.isStruct()); - ASSERT(uniqueVaryingNames.count(varying.name) == 0); - - if (packVarying(packedVarying)) - { - uniqueVaryingNames.insert(varying.name); - } - else - { - infoLog << "Could not pack varying " << varying.name; + infoLog << "Could not pack varying " << packedVarying.nameWithArrayIndex(); return false; } } - for (const std::string &transformFeedbackVaryingName : transformFeedbackVaryings) - { - if (transformFeedbackVaryingName.compare(0, 3, "gl_") == 0) - { - // do not pack builtin XFB varyings - continue; - } - - for (const PackedVarying &packedVarying : packedVaryings) - { - const auto &varying = *packedVarying.varying; - - // Make sure transform feedback varyings aren't optimized out. - if (uniqueVaryingNames.count(transformFeedbackVaryingName) == 0) - { - bool found = false; - if (transformFeedbackVaryingName == varying.name) - { - if (!packVarying(packedVarying)) - { - infoLog << "Could not pack varying " << varying.name; - return false; - } - - found = true; - break; - } - if (!found) - { - infoLog << "Transform feedback varying " << transformFeedbackVaryingName - << " does not exist in the vertex shader."; - return false; - } - } - } - } - // Sort the packed register list std::sort(mRegisterList.begin(), mRegisterList.end()); @@ -321,77 +402,7 @@ unsigned int VaryingPacking::getRegisterCount() const } } - if (mBuiltinInfo[SHADER_PIXEL].glFragCoord.enabled) - { - ++count; - } - - if (mBuiltinInfo[SHADER_PIXEL].glPointCoord.enabled) - { - ++count; - } - return count; } -void VaryingPacking::enableBuiltins(ShaderType shaderType, - const ProgramD3DMetadata &programMetadata) -{ - int majorShaderModel = programMetadata.getRendererMajorShaderModel(); - bool position = programMetadata.usesTransformFeedbackGLPosition(); - bool fragCoord = programMetadata.usesFragCoord(); - bool pointCoord = shaderType == SHADER_VERTEX ? programMetadata.addsPointCoordToVertexShader() - : programMetadata.usesPointCoord(); - bool pointSize = programMetadata.usesSystemValuePointSize(); - bool hlsl4 = (majorShaderModel >= 4); - const std::string &userSemantic = GetVaryingSemantic(majorShaderModel, pointSize); - - unsigned int reservedSemanticIndex = getMaxSemanticIndex(); - - BuiltinInfo *builtins = &mBuiltinInfo[shaderType]; - - if (hlsl4) - { - builtins->dxPosition.enableSystem("SV_Position"); - } - else if (shaderType == SHADER_PIXEL) - { - builtins->dxPosition.enableSystem("VPOS"); - } - else - { - builtins->dxPosition.enableSystem("POSITION"); - } - - if (position) - { - builtins->glPosition.enable(userSemantic, reservedSemanticIndex++); - } - - if (fragCoord) - { - builtins->glFragCoord.enable(userSemantic, reservedSemanticIndex++); - } - - if (pointCoord) - { - // SM3 reserves the TEXCOORD semantic for point sprite texcoords (gl_PointCoord) - // In D3D11 we manually compute gl_PointCoord in the GS. - if (hlsl4) - { - builtins->glPointCoord.enable(userSemantic, reservedSemanticIndex++); - } - else - { - builtins->glPointCoord.enable("TEXCOORD", 0); - } - } - - // Special case: do not include PSIZE semantic in HLSL 3 pixel shaders - if (pointSize && (shaderType != SHADER_PIXEL || hlsl4)) - { - builtins->glPointSize.enableSystem("PSIZE"); - } -} - } // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/VaryingPacking.h b/src/3rdparty/angle/src/libANGLE/VaryingPacking.h similarity index 66% rename from src/3rdparty/angle/src/libANGLE/renderer/d3d/VaryingPacking.h rename to src/3rdparty/angle/src/libANGLE/VaryingPacking.h index ca4640b000..14b25f929e 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/VaryingPacking.h +++ b/src/3rdparty/angle/src/libANGLE/VaryingPacking.h @@ -4,23 +4,28 @@ // found in the LICENSE file. // // VaryingPacking: -// Class which describes a mapping from varyings to registers in D3D -// for linking between shader stages. +// Class which describes a mapping from varyings to registers, according +// to the spec, or using custom packing algorithms. We also keep a register +// allocation list for the D3D renderer. // -#ifndef LIBANGLE_RENDERER_D3D_VARYINGPACKING_H_ -#define LIBANGLE_RENDERER_D3D_VARYINGPACKING_H_ +#ifndef LIBANGLE_VARYINGPACKING_H_ +#define LIBANGLE_VARYINGPACKING_H_ -#include "libANGLE/renderer/d3d/RendererD3D.h" +#include -namespace rx +#include "angle_gl.h" +#include "common/angleutils.h" +#include "libANGLE/Program.h" + +namespace gl { -class ProgramD3DMetadata; +class InfoLog; struct PackedVarying { PackedVarying(const sh::ShaderVariable &varyingIn, sh::InterpolationType interpolationIn) - : varying(&varyingIn), vertexOnly(false), interpolation(interpolationIn) + : PackedVarying(varyingIn, interpolationIn, "") { } PackedVarying(const sh::ShaderVariable &varyingIn, @@ -29,12 +34,26 @@ struct PackedVarying : varying(&varyingIn), vertexOnly(false), interpolation(interpolationIn), - parentStructName(parentStructNameIn) + parentStructName(parentStructNameIn), + arrayIndex(GL_INVALID_INDEX) { } bool isStructField() const { return !parentStructName.empty(); } + bool isArrayElement() const { return arrayIndex != GL_INVALID_INDEX; } + + std::string nameWithArrayIndex() const + { + std::stringstream fullNameStr; + fullNameStr << varying->name; + if (arrayIndex != GL_INVALID_INDEX) + { + fullNameStr << "[" << arrayIndex << "]"; + } + return fullNameStr.str(); + } + const sh::ShaderVariable *varying; // Transform feedback varyings can be only referenced in the VS. @@ -45,6 +64,8 @@ struct PackedVarying // Struct name std::string parentStructName; + + GLuint arrayIndex; }; struct PackedVaryingRegister final @@ -96,14 +117,29 @@ struct PackedVaryingRegister final std::string structFieldName; }; +// Supported packing modes: +enum class PackMode +{ + // We treat mat2 arrays as taking two full rows. + WEBGL_STRICT, + + // We allow mat2 to take a 2x2 chunk. + ANGLE_RELAXED, +}; + class VaryingPacking final : angle::NonCopyable { public: - VaryingPacking(GLuint maxVaryingVectors); + VaryingPacking(GLuint maxVaryingVectors, PackMode packMode); + ~VaryingPacking(); - bool packVaryings(gl::InfoLog &infoLog, - const std::vector &packedVaryings, - const std::vector &transformFeedbackVaryings); + bool packUserVaryings(gl::InfoLog &infoLog, + const std::vector &packedVaryings, + const std::vector &tfVaryings); + + bool collectAndPackUserVaryings(gl::InfoLog &infoLog, + const Program::MergedVaryings &mergedVaryings, + const std::vector &tfVaryings); struct Register { @@ -124,35 +160,7 @@ class VaryingPacking final : angle::NonCopyable return static_cast(mRegisterList.size()); } unsigned int getRegisterCount() const; - - void enableBuiltins(ShaderType shaderType, const ProgramD3DMetadata &programMetadata); - - struct BuiltinVarying final : angle::NonCopyable - { - BuiltinVarying(); - - std::string str() const; - void enableSystem(const std::string &systemValueSemantic); - void enable(const std::string &semanticVal, unsigned int indexVal); - - bool enabled; - std::string semantic; - unsigned int index; - bool systemValue; - }; - - struct BuiltinInfo - { - BuiltinVarying dxPosition; - BuiltinVarying glPosition; - BuiltinVarying glFragCoord; - BuiltinVarying glPointCoord; - BuiltinVarying glPointSize; - }; - - const BuiltinInfo &builtins(ShaderType shaderType) const { return mBuiltinInfo[shaderType]; } - - bool usesPointSize() const { return mBuiltinInfo[SHADER_VERTEX].glPointSize.enabled; } + size_t getRegisterMapSize() const { return mRegisterMap.size(); } private: bool packVarying(const PackedVarying &packedVarying); @@ -166,10 +174,11 @@ class VaryingPacking final : angle::NonCopyable std::vector mRegisterMap; std::vector mRegisterList; + std::vector mPackedVaryings; - std::vector mBuiltinInfo; + PackMode mPackMode; }; -} // namespace rx +} // namespace gl -#endif // LIBANGLE_RENDERER_D3D_VARYINGPACKING_H_ +#endif // LIBANGLE_VARYINGPACKING_H_ diff --git a/src/3rdparty/angle/src/libANGLE/Version.h b/src/3rdparty/angle/src/libANGLE/Version.h index 72dfbb6b8d..7bd41846c8 100644 --- a/src/3rdparty/angle/src/libANGLE/Version.h +++ b/src/3rdparty/angle/src/libANGLE/Version.h @@ -9,23 +9,24 @@ #ifndef LIBANGLE_VERSION_H_ #define LIBANGLE_VERSION_H_ -#include - namespace gl { struct Version { - Version(); - Version(GLuint major, GLuint minor); + constexpr Version(); + constexpr Version(unsigned int major, unsigned int minor); - GLuint major; - GLuint minor; + unsigned int major; + unsigned int minor; }; +bool operator==(const Version &a, const Version &b); +bool operator!=(const Version &a, const Version &b); bool operator>=(const Version &a, const Version &b); +bool operator<=(const Version &a, const Version &b); bool operator<(const Version &a, const Version &b); - +bool operator>(const Version &a, const Version &b); } #include "Version.inl" diff --git a/src/3rdparty/angle/src/libANGLE/Version.inl b/src/3rdparty/angle/src/libANGLE/Version.inl index f64f7cae77..c98054829e 100644 --- a/src/3rdparty/angle/src/libANGLE/Version.inl +++ b/src/3rdparty/angle/src/libANGLE/Version.inl @@ -6,28 +6,54 @@ // Version.inl: Encapsulation of a GL version. +#include + namespace gl { -inline Version::Version() +constexpr Version::Version() : Version(0, 0) { } -inline Version::Version(GLuint major_, GLuint minor_) +// Avoid conflicts with linux system defines +#undef major +#undef minor + +constexpr Version::Version(unsigned int major_, unsigned int minor_) + : major(major_), + minor(minor_) { - major = major_; - minor = minor_; +} + +inline bool operator==(const Version &a, const Version &b) +{ + return std::tie(a.major, a.minor) == std::tie(b.major, b.minor); +} + +inline bool operator!=(const Version &a, const Version &b) +{ + return std::tie(a.major, a.minor) != std::tie(b.major, b.minor); } inline bool operator>=(const Version &a, const Version &b) { - return a.major > b.major || (a.major == b.major && a.minor >= b.minor); + return std::tie(a.major, a.minor) >= std::tie(b.major, b.minor); +} + +inline bool operator<=(const Version &a, const Version &b) +{ + return std::tie(a.major, a.minor) <= std::tie(b.major, b.minor); } inline bool operator<(const Version &a, const Version &b) { - return !(a >= b); + return std::tie(a.major, a.minor) < std::tie(b.major, b.minor); } +inline bool operator>(const Version &a, const Version &b) +{ + return std::tie(a.major, a.minor) > std::tie(b.major, b.minor); } + +} // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/VertexArray.cpp b/src/3rdparty/angle/src/libANGLE/VertexArray.cpp index 8d51e9b469..a8c2fce155 100644 --- a/src/3rdparty/angle/src/libANGLE/VertexArray.cpp +++ b/src/3rdparty/angle/src/libANGLE/VertexArray.cpp @@ -8,36 +8,53 @@ #include "libANGLE/VertexArray.h" #include "libANGLE/Buffer.h" -#include "libANGLE/renderer/ImplFactory.h" +#include "libANGLE/Context.h" +#include "libANGLE/renderer/GLImplFactory.h" #include "libANGLE/renderer/VertexArrayImpl.h" namespace gl { -VertexArray::Data::Data(size_t maxAttribs) - : mLabel(), mVertexAttributes(maxAttribs), mMaxEnabledAttribute(0) +VertexArrayState::VertexArrayState(size_t maxAttribs, size_t maxAttribBindings) + : mLabel(), mVertexBindings(maxAttribBindings), mMaxEnabledAttribute(0) { -} + ASSERT(maxAttribs <= maxAttribBindings); -VertexArray::Data::~Data() -{ - for (size_t i = 0; i < getMaxAttribs(); i++) + for (size_t i = 0; i < maxAttribs; i++) { - mVertexAttributes[i].buffer.set(nullptr); + mVertexAttributes.emplace_back(static_cast(i)); } - mElementArrayBuffer.set(nullptr); } -VertexArray::VertexArray(rx::ImplFactory *factory, GLuint id, size_t maxAttribs) - : mId(id), - mVertexArray(factory->createVertexArray(mData)), - mData(maxAttribs) +VertexArrayState::~VertexArrayState() { } +VertexArray::VertexArray(rx::GLImplFactory *factory, + GLuint id, + size_t maxAttribs, + size_t maxAttribBindings) + : mId(id), + mState(maxAttribs, maxAttribBindings), + mVertexArray(factory->createVertexArray(mState)) +{ +} + +void VertexArray::onDestroy(const Context *context) +{ + for (auto &binding : mState.mVertexBindings) + { + binding.setBuffer(context, nullptr); + } + mState.mElementArrayBuffer.set(context, nullptr); + mVertexArray->destroy(context); + SafeDelete(mVertexArray); + delete this; +} + VertexArray::~VertexArray() { - SafeDelete(mVertexArray); + ASSERT(!mVertexArray); } GLuint VertexArray::id() const @@ -47,94 +64,204 @@ GLuint VertexArray::id() const void VertexArray::setLabel(const std::string &label) { - mData.mLabel = label; + mState.mLabel = label; } const std::string &VertexArray::getLabel() const { - return mData.mLabel; + return mState.mLabel; } -void VertexArray::detachBuffer(GLuint bufferName) +void VertexArray::detachBuffer(const Context *context, GLuint bufferName) { - for (size_t attribute = 0; attribute < getMaxAttribs(); attribute++) + for (auto &binding : mState.mVertexBindings) { - if (mData.mVertexAttributes[attribute].buffer.id() == bufferName) + if (binding.getBuffer().id() == bufferName) { - mData.mVertexAttributes[attribute].buffer.set(nullptr); + binding.setBuffer(context, nullptr); } } - if (mData.mElementArrayBuffer.id() == bufferName) + if (mState.mElementArrayBuffer.id() == bufferName) { - mData.mElementArrayBuffer.set(nullptr); + mState.mElementArrayBuffer.set(context, nullptr); } } -const VertexAttribute &VertexArray::getVertexAttribute(size_t attributeIndex) const +const VertexAttribute &VertexArray::getVertexAttribute(size_t attribIndex) const { - ASSERT(attributeIndex < getMaxAttribs()); - return mData.mVertexAttributes[attributeIndex]; + ASSERT(attribIndex < getMaxAttribs()); + return mState.mVertexAttributes[attribIndex]; } -void VertexArray::setVertexAttribDivisor(size_t index, GLuint divisor) +const VertexBinding &VertexArray::getVertexBinding(size_t bindingIndex) const { - ASSERT(index < getMaxAttribs()); - mData.mVertexAttributes[index].divisor = divisor; - mDirtyBits.set(DIRTY_BIT_ATTRIB_0_DIVISOR + index); + ASSERT(bindingIndex < getMaxBindings()); + return mState.mVertexBindings[bindingIndex]; } -void VertexArray::enableAttribute(size_t attributeIndex, bool enabledState) +size_t VertexArray::GetVertexIndexFromDirtyBit(size_t dirtyBit) { - ASSERT(attributeIndex < getMaxAttribs()); - mData.mVertexAttributes[attributeIndex].enabled = enabledState; - mDirtyBits.set(DIRTY_BIT_ATTRIB_0_ENABLED + attributeIndex); + static_assert(gl::MAX_VERTEX_ATTRIBS == gl::MAX_VERTEX_ATTRIB_BINDINGS, + "The stride of vertex attributes should equal to that of vertex bindings."); + ASSERT(dirtyBit > DIRTY_BIT_ELEMENT_ARRAY_BUFFER); + return (dirtyBit - DIRTY_BIT_ATTRIB_0_ENABLED) % gl::MAX_VERTEX_ATTRIBS; +} + +void VertexArray::bindVertexBufferImpl(const Context *context, + size_t bindingIndex, + Buffer *boundBuffer, + GLintptr offset, + GLsizei stride) +{ + ASSERT(bindingIndex < getMaxBindings()); + + VertexBinding *binding = &mState.mVertexBindings[bindingIndex]; + + binding->setBuffer(context, boundBuffer); + binding->setOffset(offset); + binding->setStride(stride); +} + +void VertexArray::bindVertexBuffer(const Context *context, + size_t bindingIndex, + Buffer *boundBuffer, + GLintptr offset, + GLsizei stride) +{ + bindVertexBufferImpl(context, bindingIndex, boundBuffer, offset, stride); + + mDirtyBits.set(DIRTY_BIT_BINDING_0_BUFFER + bindingIndex); +} + +void VertexArray::setVertexAttribBinding(const Context *context, + size_t attribIndex, + GLuint bindingIndex) +{ + ASSERT(attribIndex < getMaxAttribs() && bindingIndex < getMaxBindings()); + + if (mState.mVertexAttributes[attribIndex].bindingIndex != bindingIndex) + { + // In ES 3.0 contexts, the binding cannot change, hence the code below is unreachable. + ASSERT(context->getClientVersion() >= ES_3_1); + mState.mVertexAttributes[attribIndex].bindingIndex = bindingIndex; + + mDirtyBits.set(DIRTY_BIT_ATTRIB_0_BINDING + attribIndex); + } +} + +void VertexArray::setVertexBindingDivisor(size_t bindingIndex, GLuint divisor) +{ + ASSERT(bindingIndex < getMaxBindings()); + + mState.mVertexBindings[bindingIndex].setDivisor(divisor); + + mDirtyBits.set(DIRTY_BIT_BINDING_0_DIVISOR + bindingIndex); +} + +void VertexArray::setVertexAttribFormatImpl(size_t attribIndex, + GLint size, + GLenum type, + bool normalized, + bool pureInteger, + GLuint relativeOffset) +{ + ASSERT(attribIndex < getMaxAttribs()); + + VertexAttribute *attrib = &mState.mVertexAttributes[attribIndex]; + + attrib->size = size; + attrib->type = type; + attrib->normalized = normalized; + attrib->pureInteger = pureInteger; + attrib->relativeOffset = relativeOffset; +} + +void VertexArray::setVertexAttribFormat(size_t attribIndex, + GLint size, + GLenum type, + bool normalized, + bool pureInteger, + GLuint relativeOffset) +{ + setVertexAttribFormatImpl(attribIndex, size, type, normalized, pureInteger, relativeOffset); + + mDirtyBits.set(DIRTY_BIT_ATTRIB_0_FORMAT + attribIndex); +} + +void VertexArray::setVertexAttribDivisor(const Context *context, size_t attribIndex, GLuint divisor) +{ + ASSERT(attribIndex < getMaxAttribs()); + + setVertexAttribBinding(context, attribIndex, static_cast(attribIndex)); + setVertexBindingDivisor(attribIndex, divisor); +} + +void VertexArray::enableAttribute(size_t attribIndex, bool enabledState) +{ + ASSERT(attribIndex < getMaxAttribs()); + + mState.mVertexAttributes[attribIndex].enabled = enabledState; + + mDirtyBits.set(DIRTY_BIT_ATTRIB_0_ENABLED + attribIndex); // Update state cache if (enabledState) { - mData.mMaxEnabledAttribute = std::max(attributeIndex + 1, mData.mMaxEnabledAttribute); + mState.mMaxEnabledAttribute = std::max(attribIndex + 1, mState.mMaxEnabledAttribute); } - else if (mData.mMaxEnabledAttribute == attributeIndex + 1) + else if (mState.mMaxEnabledAttribute == attribIndex + 1) { - while (mData.mMaxEnabledAttribute > 0 && - !mData.mVertexAttributes[mData.mMaxEnabledAttribute - 1].enabled) + while (mState.mMaxEnabledAttribute > 0 && + !mState.mVertexAttributes[mState.mMaxEnabledAttribute - 1].enabled) { - --mData.mMaxEnabledAttribute; + --mState.mMaxEnabledAttribute; } } } -void VertexArray::setAttributeState(size_t attributeIndex, gl::Buffer *boundBuffer, GLint size, GLenum type, - bool normalized, bool pureInteger, GLsizei stride, const void *pointer) +void VertexArray::setVertexAttribPointer(const Context *context, + size_t attribIndex, + gl::Buffer *boundBuffer, + GLint size, + GLenum type, + bool normalized, + bool pureInteger, + GLsizei stride, + const void *pointer) { - ASSERT(attributeIndex < getMaxAttribs()); + ASSERT(attribIndex < getMaxAttribs()); - VertexAttribute *attrib = &mData.mVertexAttributes[attributeIndex]; + GLintptr offset = boundBuffer ? reinterpret_cast(pointer) : 0; - attrib->buffer.set(boundBuffer); - attrib->size = size; - attrib->type = type; - attrib->normalized = normalized; - attrib->pureInteger = pureInteger; - attrib->stride = stride; - attrib->pointer = pointer; - mDirtyBits.set(DIRTY_BIT_ATTRIB_0_POINTER + attributeIndex); + setVertexAttribFormatImpl(attribIndex, size, type, normalized, pureInteger, 0); + setVertexAttribBinding(context, attribIndex, static_cast(attribIndex)); + + VertexAttribute &attrib = mState.mVertexAttributes[attribIndex]; + + GLsizei effectiveStride = + stride != 0 ? stride : static_cast(ComputeVertexAttributeTypeSize(attrib)); + attrib.pointer = pointer; + attrib.vertexAttribArrayStride = stride; + + bindVertexBufferImpl(context, attribIndex, boundBuffer, offset, effectiveStride); + + mDirtyBits.set(DIRTY_BIT_ATTRIB_0_POINTER + attribIndex); } -void VertexArray::setElementArrayBuffer(Buffer *buffer) +void VertexArray::setElementArrayBuffer(const Context *context, Buffer *buffer) { - mData.mElementArrayBuffer.set(buffer); + mState.mElementArrayBuffer.set(context, buffer); mDirtyBits.set(DIRTY_BIT_ELEMENT_ARRAY_BUFFER); } -void VertexArray::syncImplState() +void VertexArray::syncState(const Context *context) { if (mDirtyBits.any()) { - mVertexArray->syncState(mDirtyBits); + mVertexArray->syncState(context, mDirtyBits); mDirtyBits.reset(); } } -} +} // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/VertexArray.h b/src/3rdparty/angle/src/libANGLE/VertexArray.h index 6bc267d399..f82ec789f0 100644 --- a/src/3rdparty/angle/src/libANGLE/VertexArray.h +++ b/src/3rdparty/angle/src/libANGLE/VertexArray.h @@ -23,68 +23,131 @@ namespace rx { -class ImplFactory; +class GLImplFactory; class VertexArrayImpl; -} +} // namespace rx namespace gl { class Buffer; +class VertexArrayState final : angle::NonCopyable +{ + public: + VertexArrayState(size_t maxAttribs, size_t maxBindings); + ~VertexArrayState(); + + const std::string &getLabel() const { return mLabel; } + + const BindingPointer &getElementArrayBuffer() const { return mElementArrayBuffer; } + size_t getMaxAttribs() const { return mVertexAttributes.size(); } + size_t getMaxBindings() const { return mVertexBindings.size(); } + size_t getMaxEnabledAttribute() const { return mMaxEnabledAttribute; } + const std::vector &getVertexAttributes() const { return mVertexAttributes; } + const VertexAttribute &getVertexAttribute(size_t attribIndex) const + { + return mVertexAttributes[attribIndex]; + } + const std::vector &getVertexBindings() const { return mVertexBindings; } + const VertexBinding &getVertexBinding(size_t bindingIndex) const + { + return mVertexBindings[bindingIndex]; + } + const VertexBinding &getBindingFromAttribIndex(size_t attribIndex) const + { + return mVertexBindings[mVertexAttributes[attribIndex].bindingIndex]; + } + size_t getBindingIndexFromAttribIndex(size_t attribIndex) const + { + return mVertexAttributes[attribIndex].bindingIndex; + } + + private: + friend class VertexArray; + std::string mLabel; + std::vector mVertexAttributes; + BindingPointer mElementArrayBuffer; + std::vector mVertexBindings; + size_t mMaxEnabledAttribute; +}; + class VertexArray final : public LabeledObject { public: - VertexArray(rx::ImplFactory *factory, GLuint id, size_t maxAttribs); - ~VertexArray(); + VertexArray(rx::GLImplFactory *factory, GLuint id, size_t maxAttribs, size_t maxAttribBindings); + + void onDestroy(const Context *context); GLuint id() const; void setLabel(const std::string &label) override; const std::string &getLabel() const override; - const VertexAttribute &getVertexAttribute(size_t attributeIndex) const; - - void detachBuffer(GLuint bufferName); - void setVertexAttribDivisor(size_t index, GLuint divisor); - void enableAttribute(size_t attributeIndex, bool enabledState); - void setAttributeState(size_t attributeIndex, gl::Buffer *boundBuffer, GLint size, GLenum type, - bool normalized, bool pureInteger, GLsizei stride, const void *pointer); - - void setElementArrayBuffer(Buffer *buffer); - - const BindingPointer &getElementArrayBuffer() const { return mData.getElementArrayBuffer(); } - size_t getMaxAttribs() const { return mData.getVertexAttributes().size(); } - const std::vector &getVertexAttributes() const { return mData.getVertexAttributes(); } - - rx::VertexArrayImpl *getImplementation() { return mVertexArray; } - const rx::VertexArrayImpl *getImplementation() const { return mVertexArray; } - - size_t getMaxEnabledAttribute() const { return mData.getMaxEnabledAttribute(); } - - class Data final : public angle::NonCopyable + const VertexBinding &getVertexBinding(size_t bindingIndex) const; + const VertexAttribute &getVertexAttribute(size_t attribIndex) const; + const VertexBinding &getBindingFromAttribIndex(size_t attribIndex) const { - public: - explicit Data(size_t maxAttribs); - ~Data(); + return mState.getBindingFromAttribIndex(attribIndex); + } - const std::string &getLabel() const { return mLabel; } + void detachBuffer(const Context *context, GLuint bufferName); + void setVertexAttribDivisor(const Context *context, size_t index, GLuint divisor); + void enableAttribute(size_t attribIndex, bool enabledState); + void setVertexAttribPointer(const Context *context, + size_t attribIndex, + Buffer *boundBuffer, + GLint size, + GLenum type, + bool normalized, + bool pureInteger, + GLsizei stride, + const void *pointer); + void setVertexAttribFormat(size_t attribIndex, + GLint size, + GLenum type, + bool normalized, + bool pureInteger, + GLuint relativeOffset); + void bindVertexBuffer(const Context *context, + size_t bindingIndex, + Buffer *boundBuffer, + GLintptr offset, + GLsizei stride); + void setVertexAttribBinding(const Context *context, size_t attribIndex, GLuint bindingIndex); + void setVertexBindingDivisor(size_t bindingIndex, GLuint divisor); + void setVertexAttribFormatImpl(size_t attribIndex, + GLint size, + GLenum type, + bool normalized, + bool pureInteger, + GLuint relativeOffset); + void bindVertexBufferImpl(const Context *context, + size_t bindingIndex, + Buffer *boundBuffer, + GLintptr offset, + GLsizei stride); - const BindingPointer &getElementArrayBuffer() const { return mElementArrayBuffer; } - size_t getMaxAttribs() const { return mVertexAttributes.size(); } - size_t getMaxEnabledAttribute() const { return mMaxEnabledAttribute; } - const std::vector &getVertexAttributes() const { return mVertexAttributes; } - const VertexAttribute &getVertexAttribute(size_t index) const - { - return mVertexAttributes[index]; - } + void setElementArrayBuffer(const Context *context, Buffer *buffer); - private: - friend class VertexArray; - std::string mLabel; - std::vector mVertexAttributes; - BindingPointer mElementArrayBuffer; - size_t mMaxEnabledAttribute; - }; + const BindingPointer &getElementArrayBuffer() const + { + return mState.getElementArrayBuffer(); + } + size_t getMaxAttribs() const { return mState.getMaxAttribs(); } + size_t getMaxBindings() const { return mState.getMaxBindings(); } + + const std::vector &getVertexAttributes() const + { + return mState.getVertexAttributes(); + } + const std::vector &getVertexBindings() const + { + return mState.getVertexBindings(); + } + + rx::VertexArrayImpl *getImplementation() const { return mVertexArray; } + + size_t getMaxEnabledAttribute() const { return mState.getMaxEnabledAttribute(); } enum DirtyBitType { @@ -98,28 +161,45 @@ class VertexArray final : public LabeledObject DIRTY_BIT_ATTRIB_0_POINTER = DIRTY_BIT_ATTRIB_MAX_ENABLED, DIRTY_BIT_ATTRIB_MAX_POINTER = DIRTY_BIT_ATTRIB_0_POINTER + gl::MAX_VERTEX_ATTRIBS, - // Reserve bits for divisors - DIRTY_BIT_ATTRIB_0_DIVISOR = DIRTY_BIT_ATTRIB_MAX_POINTER, - DIRTY_BIT_ATTRIB_MAX_DIVISOR = DIRTY_BIT_ATTRIB_0_DIVISOR + gl::MAX_VERTEX_ATTRIBS, + // Reserve bits for changes to VertexAttribFormat + DIRTY_BIT_ATTRIB_0_FORMAT = DIRTY_BIT_ATTRIB_MAX_POINTER, + DIRTY_BIT_ATTRIB_MAX_FORMAT = DIRTY_BIT_ATTRIB_0_FORMAT + gl::MAX_VERTEX_ATTRIBS, - DIRTY_BIT_UNKNOWN = DIRTY_BIT_ATTRIB_MAX_DIVISOR, + // Reserve bits for changes to VertexAttribBinding + DIRTY_BIT_ATTRIB_0_BINDING = DIRTY_BIT_ATTRIB_MAX_FORMAT, + DIRTY_BIT_ATTRIB_MAX_BINDING = DIRTY_BIT_ATTRIB_0_BINDING + gl::MAX_VERTEX_ATTRIBS, + + // Reserve bits for changes to BindVertexBuffer + DIRTY_BIT_BINDING_0_BUFFER = DIRTY_BIT_ATTRIB_MAX_BINDING, + DIRTY_BIT_BINDING_MAX_BUFFER = DIRTY_BIT_BINDING_0_BUFFER + gl::MAX_VERTEX_ATTRIB_BINDINGS, + + // Reserve bits for binding divisors + DIRTY_BIT_BINDING_0_DIVISOR = DIRTY_BIT_BINDING_MAX_BUFFER, + DIRTY_BIT_BINDING_MAX_DIVISOR = + DIRTY_BIT_BINDING_0_DIVISOR + gl::MAX_VERTEX_ATTRIB_BINDINGS, + + DIRTY_BIT_UNKNOWN = DIRTY_BIT_BINDING_MAX_DIVISOR, DIRTY_BIT_MAX = DIRTY_BIT_UNKNOWN, }; - typedef std::bitset DirtyBits; + using DirtyBits = angle::BitSet; - void syncImplState(); + static size_t GetVertexIndexFromDirtyBit(size_t dirtyBit); + + void syncState(const Context *context); bool hasAnyDirtyBit() const { return mDirtyBits.any(); } private: + ~VertexArray() override; + GLuint mId; - rx::VertexArrayImpl *mVertexArray; - - Data mData; + VertexArrayState mState; DirtyBits mDirtyBits; + + rx::VertexArrayImpl *mVertexArray; }; -} +} // namespace gl #endif // LIBANGLE_VERTEXARRAY_H_ diff --git a/src/3rdparty/angle/src/libANGLE/VertexAttribute.cpp b/src/3rdparty/angle/src/libANGLE/VertexAttribute.cpp index 13d78fd13c..20f7452fa5 100644 --- a/src/3rdparty/angle/src/libANGLE/VertexAttribute.cpp +++ b/src/3rdparty/angle/src/libANGLE/VertexAttribute.cpp @@ -3,7 +3,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Implementation of the state class for mananging GLES 3 Vertex Array Objects. +// Implementation of the state classes for mananging GLES 3.1 Vertex Array Objects. // #include "libANGLE/VertexAttribute.h" @@ -11,18 +11,76 @@ namespace gl { -VertexAttribute::VertexAttribute() +// [OpenGL ES 3.1] (November 3, 2016) Section 20 Page 361 +// Table 20.2: Vertex Array Object State +VertexBinding::VertexBinding() : mStride(16u), mDivisor(0), mOffset(0) +{ +} + +VertexBinding::VertexBinding(VertexBinding &&binding) +{ + *this = std::move(binding); +} + +VertexBinding::~VertexBinding() +{ +} + +VertexBinding &VertexBinding::operator=(VertexBinding &&binding) +{ + if (this != &binding) + { + mStride = binding.mStride; + mDivisor = binding.mDivisor; + mOffset = binding.mOffset; + std::swap(binding.mBuffer, mBuffer); + } + return *this; +} + +VertexAttribute::VertexAttribute(GLuint bindingIndex) : enabled(false), type(GL_FLOAT), - size(4), + size(4u), normalized(false), pureInteger(false), - stride(0), - pointer(NULL), - divisor(0) + pointer(nullptr), + relativeOffset(0), + vertexAttribArrayStride(0), + bindingIndex(bindingIndex) { } +VertexAttribute::VertexAttribute(VertexAttribute &&attrib) + : enabled(attrib.enabled), + type(attrib.type), + size(attrib.size), + normalized(attrib.normalized), + pureInteger(attrib.pureInteger), + pointer(attrib.pointer), + relativeOffset(attrib.relativeOffset), + vertexAttribArrayStride(attrib.vertexAttribArrayStride), + bindingIndex(attrib.bindingIndex) +{ +} + +VertexAttribute &VertexAttribute::operator=(VertexAttribute &&attrib) +{ + if (this != &attrib) + { + enabled = attrib.enabled; + type = attrib.type; + size = attrib.size; + normalized = attrib.normalized; + pureInteger = attrib.pureInteger; + pointer = attrib.pointer; + relativeOffset = attrib.relativeOffset; + vertexAttribArrayStride = attrib.vertexAttribArrayStride; + bindingIndex = attrib.bindingIndex; + } + return *this; +} + size_t ComputeVertexAttributeTypeSize(const VertexAttribute& attrib) { GLuint size = attrib.size; @@ -43,32 +101,62 @@ size_t ComputeVertexAttributeTypeSize(const VertexAttribute& attrib) } } -size_t ComputeVertexAttributeStride(const VertexAttribute& attrib) +size_t ComputeVertexAttributeStride(const VertexAttribute &attrib, const VertexBinding &binding) { - if (!attrib.enabled) - { - return 16; - } - return attrib.stride ? attrib.stride : ComputeVertexAttributeTypeSize(attrib); + // In ES 3.1, VertexAttribPointer will store the type size in the binding stride. + // Hence, rendering always uses the binding's stride. + return attrib.enabled ? binding.getStride() : 16u; } -size_t ComputeVertexAttributeElementCount(const VertexAttribute &attrib, - size_t drawCount, - size_t instanceCount) +// Warning: you should ensure binding really matches attrib.bindingIndex before using this function. +GLintptr ComputeVertexAttributeOffset(const VertexAttribute &attrib, const VertexBinding &binding) +{ + return attrib.relativeOffset + binding.getOffset(); +} + +size_t ComputeVertexBindingElementCount(GLuint divisor, size_t drawCount, size_t instanceCount) { // For instanced rendering, we draw "instanceDrawCount" sets of "vertexDrawCount" vertices. // // A vertex attribute with a positive divisor loads one instanced vertex for every set of // non-instanced vertices, and the instanced vertex index advances once every "mDivisor" // instances. - if (instanceCount > 0 && attrib.divisor > 0) + if (instanceCount > 0 && divisor > 0) { // When instanceDrawCount is not a multiple attrib.divisor, the division must round up. // For instance, with 5 non-instanced vertices and a divisor equal to 3, we need 2 instanced // vertices. - return (instanceCount + attrib.divisor - 1u) / attrib.divisor; + return (instanceCount + divisor - 1u) / divisor; } return drawCount; } + +GLenum GetVertexAttributeBaseType(const VertexAttribute &attrib) +{ + if (attrib.pureInteger) + { + switch (attrib.type) + { + case GL_BYTE: + case GL_SHORT: + case GL_INT: + return GL_INT; + + case GL_UNSIGNED_BYTE: + case GL_UNSIGNED_SHORT: + case GL_UNSIGNED_INT: + return GL_UNSIGNED_INT; + + default: + UNREACHABLE(); + return GL_NONE; + } + } + else + { + return GL_FLOAT; + } } + +} // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/VertexAttribute.h b/src/3rdparty/angle/src/libANGLE/VertexAttribute.h index d1ee1b47a2..c531bece7c 100644 --- a/src/3rdparty/angle/src/libANGLE/VertexAttribute.h +++ b/src/3rdparty/angle/src/libANGLE/VertexAttribute.h @@ -3,7 +3,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Helper structure describing a single vertex attribute +// Helper structures about Generic Vertex Attribute. // #ifndef LIBANGLE_VERTEXATTRIBUTE_H_ @@ -13,45 +13,77 @@ namespace gl { +class VertexArray; -struct VertexAttribute +// +// Implementation of Generic Vertex Attribute Bindings for ES3.1. The members are intentionally made +// private in order to hide implementation details. +// +class VertexBinding final : angle::NonCopyable { - bool enabled; // From glEnable/DisableVertexAttribArray + public: + VertexBinding(); + VertexBinding(VertexBinding &&binding); + ~VertexBinding(); + VertexBinding &operator=(VertexBinding &&binding); + GLuint getStride() const { return mStride; } + void setStride(GLuint strideIn) { mStride = strideIn; } + + GLuint getDivisor() const { return mDivisor; } + void setDivisor(GLuint divisorIn) { mDivisor = divisorIn; } + + GLintptr getOffset() const { return mOffset; } + void setOffset(GLintptr offsetIn) { mOffset = offsetIn; } + + const BindingPointer &getBuffer() const { return mBuffer; } + void setBuffer(const gl::Context *context, Buffer *bufferIn) { mBuffer.set(context, bufferIn); } + + private: + GLuint mStride; + GLuint mDivisor; + GLintptr mOffset; + + BindingPointer mBuffer; +}; + +// +// Implementation of Generic Vertex Attributes for ES3.1 +// +struct VertexAttribute final : private angle::NonCopyable +{ + explicit VertexAttribute(GLuint bindingIndex); + explicit VertexAttribute(VertexAttribute &&attrib); + VertexAttribute &operator=(VertexAttribute &&attrib); + + bool enabled; // For glEnable/DisableVertexAttribArray GLenum type; GLuint size; bool normalized; bool pureInteger; - GLuint stride; // 0 means natural stride - union - { - const GLvoid *pointer; - GLintptr offset; - }; - BindingPointer buffer; // Captured when glVertexAttribPointer is called. + const void *pointer; + GLuint relativeOffset; - GLuint divisor; - - VertexAttribute(); + GLuint vertexAttribArrayStride; // ONLY for queries of VERTEX_ATTRIB_ARRAY_STRIDE + GLuint bindingIndex; }; -bool operator==(const VertexAttribute &a, const VertexAttribute &b); -bool operator!=(const VertexAttribute &a, const VertexAttribute &b); +size_t ComputeVertexAttributeTypeSize(const VertexAttribute &attrib); -template -T QuerySingleVertexAttributeParameter(const VertexAttribute& attrib, GLenum pname); +// Warning: you should ensure binding really matches attrib.bindingIndex before using this function. +size_t ComputeVertexAttributeStride(const VertexAttribute &attrib, const VertexBinding &binding); -size_t ComputeVertexAttributeTypeSize(const VertexAttribute& attrib); -size_t ComputeVertexAttributeStride(const VertexAttribute& attrib); -size_t ComputeVertexAttributeElementCount(const VertexAttribute &attrib, - size_t drawCount, - size_t instanceCount); +// Warning: you should ensure binding really matches attrib.bindingIndex before using this function. +GLintptr ComputeVertexAttributeOffset(const VertexAttribute &attrib, const VertexBinding &binding); + +size_t ComputeVertexBindingElementCount(GLuint divisor, size_t drawCount, size_t instanceCount); + +GLenum GetVertexAttributeBaseType(const VertexAttribute &attrib); struct VertexAttribCurrentValueData { - union - { + union { GLfloat FloatValues[4]; GLint IntValues[4]; GLuint UnsignedIntValues[4]; @@ -68,8 +100,8 @@ struct VertexAttribCurrentValueData bool operator==(const VertexAttribCurrentValueData &a, const VertexAttribCurrentValueData &b); bool operator!=(const VertexAttribCurrentValueData &a, const VertexAttribCurrentValueData &b); -} +} // namespace gl #include "VertexAttribute.inl" -#endif // LIBANGLE_VERTEXATTRIBUTE_H_ +#endif // LIBANGLE_VERTEXATTRIBUTE_H_ diff --git a/src/3rdparty/angle/src/libANGLE/VertexAttribute.inl b/src/3rdparty/angle/src/libANGLE/VertexAttribute.inl index 0cd31f6762..1c1843e46f 100644 --- a/src/3rdparty/angle/src/libANGLE/VertexAttribute.inl +++ b/src/3rdparty/angle/src/libANGLE/VertexAttribute.inl @@ -9,51 +9,6 @@ namespace gl { -inline bool operator==(const VertexAttribute &a, const VertexAttribute &b) -{ - return a.enabled == b.enabled && - a.type == b.type && - a.size == b.size && - a.normalized == b.normalized && - a.pureInteger == b.pureInteger && - a.stride == b.stride && - a.pointer == b.pointer && - a.buffer.get() == b.buffer.get() && - a.divisor == b.divisor; -} - -inline bool operator!=(const VertexAttribute &a, const VertexAttribute &b) -{ - return !(a == b); -} - -template -T QuerySingleVertexAttributeParameter(const VertexAttribute& attrib, GLenum pname) -{ - switch (pname) - { - case GL_VERTEX_ATTRIB_ARRAY_ENABLED: - return static_cast(attrib.enabled ? GL_TRUE : GL_FALSE); - case GL_VERTEX_ATTRIB_ARRAY_SIZE: - return static_cast(attrib.size); - case GL_VERTEX_ATTRIB_ARRAY_STRIDE: - return static_cast(attrib.stride); - case GL_VERTEX_ATTRIB_ARRAY_TYPE: - return static_cast(attrib.type); - case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: - return static_cast(attrib.normalized ? GL_TRUE : GL_FALSE); - case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: - return static_cast(attrib.buffer.id()); - case GL_VERTEX_ATTRIB_ARRAY_DIVISOR: - return static_cast(attrib.divisor); - case GL_VERTEX_ATTRIB_ARRAY_INTEGER: - return static_cast(attrib.pureInteger ? GL_TRUE : GL_FALSE); - default: - UNREACHABLE(); - return static_cast(0); - } -} - inline VertexAttribCurrentValueData::VertexAttribCurrentValueData() : Type(GL_FLOAT) { @@ -100,4 +55,4 @@ inline bool operator!=(const VertexAttribCurrentValueData &a, const VertexAttrib return !(a == b); } -} +} // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/Workarounds.h b/src/3rdparty/angle/src/libANGLE/Workarounds.h new file mode 100644 index 0000000000..898031d78d --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/Workarounds.h @@ -0,0 +1,29 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Workarounds.h: Workarounds for driver bugs and other behaviors seen +// on all platforms. + +#ifndef LIBANGLE_WORKAROUNDS_H_ +#define LIBANGLE_WORKAROUNDS_H_ + +namespace gl +{ + +struct Workarounds +{ + // Force the context to be lost (via KHR_robustness) if a GL_OUT_OF_MEMORY error occurs. The + // driver may be in an inconsistent state if this happens, and some users of ANGLE rely on this + // notification to prevent further execution. + bool loseContextOnOutOfMemory = false; + + // Program binaries don't contain transform feedback varyings on Qualcomm GPUs. + // Work around this by disabling the program cache for programs with transform feedback. + bool disableProgramCachingForTransformFeedback = false; +}; +} // namespace gl + +#endif // LIBANGLE_WORKAROUNDS_H_ diff --git a/src/3rdparty/angle/src/libANGLE/WorkerThread.cpp b/src/3rdparty/angle/src/libANGLE/WorkerThread.cpp new file mode 100644 index 0000000000..b5d789ef93 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/WorkerThread.cpp @@ -0,0 +1,157 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// WorkerThread: +// Task running thread for ANGLE, similar to a TaskRunner in Chromium. +// Might be implemented differently depending on platform. +// + +#include "libANGLE/WorkerThread.h" + +namespace angle +{ + +namespace priv +{ +// SingleThreadedWorkerPool implementation. +SingleThreadedWorkerPool::SingleThreadedWorkerPool(size_t maxThreads) + : WorkerThreadPoolBase(maxThreads) +{ +} + +SingleThreadedWorkerPool::~SingleThreadedWorkerPool() +{ +} + +SingleThreadedWaitableEvent SingleThreadedWorkerPool::postWorkerTaskImpl(Closure *task) +{ + (*task)(); + return SingleThreadedWaitableEvent(EventResetPolicy::Automatic, EventInitialState::Signaled); +} + +// SingleThreadedWaitableEvent implementation. +SingleThreadedWaitableEvent::SingleThreadedWaitableEvent() + : SingleThreadedWaitableEvent(EventResetPolicy::Automatic, EventInitialState::NonSignaled) +{ +} + +SingleThreadedWaitableEvent::SingleThreadedWaitableEvent(EventResetPolicy resetPolicy, + EventInitialState initialState) + : WaitableEventBase(resetPolicy, initialState) +{ +} + +SingleThreadedWaitableEvent::~SingleThreadedWaitableEvent() +{ +} + +SingleThreadedWaitableEvent::SingleThreadedWaitableEvent(SingleThreadedWaitableEvent &&other) + : WaitableEventBase(std::move(other)) +{ +} + +SingleThreadedWaitableEvent &SingleThreadedWaitableEvent::operator=( + SingleThreadedWaitableEvent &&other) +{ + return copyBase(std::move(other)); +} + +void SingleThreadedWaitableEvent::resetImpl() +{ + mSignaled = false; +} + +void SingleThreadedWaitableEvent::waitImpl() +{ +} + +void SingleThreadedWaitableEvent::signalImpl() +{ + mSignaled = true; +} + +#if (ANGLE_STD_ASYNC_WORKERS == ANGLE_ENABLED) +// AsyncWorkerPool implementation. +AsyncWorkerPool::AsyncWorkerPool(size_t maxThreads) : WorkerThreadPoolBase(maxThreads) +{ +} + +AsyncWorkerPool::~AsyncWorkerPool() +{ +} + +AsyncWaitableEvent AsyncWorkerPool::postWorkerTaskImpl(Closure *task) +{ + auto future = std::async(std::launch::async, [task] { (*task)(); }); + + AsyncWaitableEvent waitable(EventResetPolicy::Automatic, EventInitialState::NonSignaled); + + waitable.setFuture(std::move(future)); + + return waitable; +} + +// AsyncWaitableEvent implementation. +AsyncWaitableEvent::AsyncWaitableEvent() + : AsyncWaitableEvent(EventResetPolicy::Automatic, EventInitialState::NonSignaled) +{ +} + +AsyncWaitableEvent::AsyncWaitableEvent(EventResetPolicy resetPolicy, EventInitialState initialState) + : WaitableEventBase(resetPolicy, initialState) +{ +} + +AsyncWaitableEvent::~AsyncWaitableEvent() +{ +} + +AsyncWaitableEvent::AsyncWaitableEvent(AsyncWaitableEvent &&other) + : WaitableEventBase(std::move(other)), mFuture(std::move(other.mFuture)) +{ +} + +AsyncWaitableEvent &AsyncWaitableEvent::operator=(AsyncWaitableEvent &&other) +{ + std::swap(mFuture, other.mFuture); + return copyBase(std::move(other)); +} + +void AsyncWaitableEvent::setFuture(std::future &&future) +{ + mFuture = std::move(future); +} + +void AsyncWaitableEvent::resetImpl() +{ + mSignaled = false; + mFuture = std::future(); +} + +void AsyncWaitableEvent::waitImpl() +{ + if (mSignaled || !mFuture.valid()) + { + return; + } + + mFuture.wait(); + signal(); +} + +void AsyncWaitableEvent::signalImpl() +{ + mSignaled = true; + + if (mResetPolicy == EventResetPolicy::Automatic) + { + reset(); + } +} +#endif // (ANGLE_STD_ASYNC_WORKERS == ANGLE_ENABLED) + +} // namespace priv + +} // namespace angle diff --git a/src/3rdparty/angle/src/libANGLE/WorkerThread.h b/src/3rdparty/angle/src/libANGLE/WorkerThread.h new file mode 100644 index 0000000000..f6b81dce21 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/WorkerThread.h @@ -0,0 +1,284 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// WorkerThread: +// Asychronous tasks/threads for ANGLE, similar to a TaskRunner in Chromium. +// Can be implemented as different targets, depending on platform. +// + +#ifndef LIBANGLE_WORKER_THREAD_H_ +#define LIBANGLE_WORKER_THREAD_H_ + +#include +#include + +#include "common/debug.h" +#include "libANGLE/features.h" + +#if (ANGLE_STD_ASYNC_WORKERS == ANGLE_ENABLED) +#include +#endif // (ANGLE_STD_ASYNC_WORKERS == ANGLE_ENABLED) + +namespace angle +{ +// Indicates whether a WaitableEvent should automatically reset the event state after a single +// waiting thread has been released or remain signaled until reset() is manually invoked. +enum class EventResetPolicy +{ + Manual, + Automatic +}; + +// Specify the initial state on creation. +enum class EventInitialState +{ + NonSignaled, + Signaled +}; + +// A callback function with no return value and no arguments. +class Closure +{ + public: + virtual ~Closure() = default; + virtual void operator()() = 0; +}; + +namespace priv +{ +// An event that we can wait on, useful for joining worker threads. +template +class WaitableEventBase : angle::NonCopyable +{ + public: + WaitableEventBase(EventResetPolicy resetPolicy, EventInitialState initialState); + + WaitableEventBase(WaitableEventBase &&other); + + // Puts the event in the un-signaled state. + void reset(); + + // Waits indefinitely for the event to be signaled. + void wait(); + + // Puts the event in the signaled state, causing any thread blocked on Wait to be woken up. + // The event state is reset to non-signaled after a waiting thread has been released. + void signal(); + + protected: + Impl ©Base(Impl &&other); + + template + static size_t WaitManyBase(std::array *waitables); + + EventResetPolicy mResetPolicy; + bool mSignaled; +}; + +template +WaitableEventBase::WaitableEventBase(EventResetPolicy resetPolicy, + EventInitialState initialState) + : mResetPolicy(resetPolicy), mSignaled(initialState == EventInitialState::Signaled) +{ +} + +template +WaitableEventBase::WaitableEventBase(WaitableEventBase &&other) + : mResetPolicy(other.mResetPolicy), mSignaled(other.mSignaled) +{ +} + +template +void WaitableEventBase::reset() +{ + static_cast(this)->resetImpl(); +} + +template +void WaitableEventBase::wait() +{ + static_cast(this)->waitImpl(); +} + +template +void WaitableEventBase::signal() +{ + static_cast(this)->signalImpl(); +} + +template +template +// static +size_t WaitableEventBase::WaitManyBase(std::array *waitables) +{ + ASSERT(Count > 0); + + for (size_t index = 0; index < Count; ++index) + { + (*waitables)[index].wait(); + } + + return 0; +} + +template +Impl &WaitableEventBase::copyBase(Impl &&other) +{ + std::swap(mSignaled, other.mSignaled); + std::swap(mResetPolicy, other.mResetPolicy); + return *static_cast(this); +} + +class SingleThreadedWaitableEvent : public WaitableEventBase +{ + public: + SingleThreadedWaitableEvent(); + SingleThreadedWaitableEvent(EventResetPolicy resetPolicy, EventInitialState initialState); + ~SingleThreadedWaitableEvent(); + + SingleThreadedWaitableEvent(SingleThreadedWaitableEvent &&other); + SingleThreadedWaitableEvent &operator=(SingleThreadedWaitableEvent &&other); + + void resetImpl(); + void waitImpl(); + void signalImpl(); + + // Wait, synchronously, on multiple events. + // returns the index of a WaitableEvent which has been signaled. + template + static size_t WaitMany(std::array *waitables); +}; + +template +// static +size_t SingleThreadedWaitableEvent::WaitMany( + std::array *waitables) +{ + return WaitableEventBase::WaitManyBase(waitables); +} + +#if (ANGLE_STD_ASYNC_WORKERS == ANGLE_ENABLED) +class AsyncWaitableEvent : public WaitableEventBase +{ + public: + AsyncWaitableEvent(); + AsyncWaitableEvent(EventResetPolicy resetPolicy, EventInitialState initialState); + ~AsyncWaitableEvent(); + + AsyncWaitableEvent(AsyncWaitableEvent &&other); + AsyncWaitableEvent &operator=(AsyncWaitableEvent &&other); + + void resetImpl(); + void waitImpl(); + void signalImpl(); + + // Wait, synchronously, on multiple events. + // returns the index of a WaitableEvent which has been signaled. + template + static size_t WaitMany(std::array *waitables); + + private: + friend class AsyncWorkerPool; + void setFuture(std::future &&future); + + std::future mFuture; +}; + +template +// static +size_t AsyncWaitableEvent::WaitMany(std::array *waitables) +{ + return WaitableEventBase::WaitManyBase(waitables); +} +#endif // (ANGLE_STD_ASYNC_WORKERS == ANGLE_ENABLED) + +// The traits class allows the the thread pool to return the "Typed" waitable event from postTask. +// Otherwise postTask would always think it returns the current active type, so the unit tests +// could not run on multiple worker types in the same compilation. +template +struct WorkerThreadPoolTraits; + +class SingleThreadedWorkerPool; +template <> +struct WorkerThreadPoolTraits +{ + using WaitableEventType = SingleThreadedWaitableEvent; +}; + +#if (ANGLE_STD_ASYNC_WORKERS == ANGLE_ENABLED) +class AsyncWorkerPool; +template <> +struct WorkerThreadPoolTraits +{ + using WaitableEventType = AsyncWaitableEvent; +}; +#endif // (ANGLE_STD_ASYNC_WORKERS == ANGLE_ENABLED) + +// Request WorkerThreads from the WorkerThreadPool. Each pool can keep worker threads around so +// we avoid the costly spin up and spin down time. +template +class WorkerThreadPoolBase : angle::NonCopyable +{ + public: + WorkerThreadPoolBase(size_t maxThreads); + ~WorkerThreadPoolBase(); + + using WaitableEventType = typename WorkerThreadPoolTraits::WaitableEventType; + + // Returns an event to wait on for the task to finish. + // If the pool fails to create the task, returns null. + WaitableEventType postWorkerTask(Closure *task); +}; + +template +WorkerThreadPoolBase::WorkerThreadPoolBase(size_t maxThreads) +{ +} + +template +WorkerThreadPoolBase::~WorkerThreadPoolBase() +{ +} + +template +typename WorkerThreadPoolBase::WaitableEventType WorkerThreadPoolBase::postWorkerTask( + Closure *task) +{ + return static_cast(this)->postWorkerTaskImpl(task); +} + +class SingleThreadedWorkerPool : public WorkerThreadPoolBase +{ + public: + SingleThreadedWorkerPool(size_t maxThreads); + ~SingleThreadedWorkerPool(); + + SingleThreadedWaitableEvent postWorkerTaskImpl(Closure *task); +}; + +#if (ANGLE_STD_ASYNC_WORKERS == ANGLE_ENABLED) +class AsyncWorkerPool : public WorkerThreadPoolBase +{ + public: + AsyncWorkerPool(size_t maxThreads); + ~AsyncWorkerPool(); + + AsyncWaitableEvent postWorkerTaskImpl(Closure *task); +}; +#endif // (ANGLE_STD_ASYNC_WORKERS == ANGLE_ENABLED) + +} // namespace priv + +#if (ANGLE_STD_ASYNC_WORKERS == ANGLE_ENABLED) +using WaitableEvent = priv::AsyncWaitableEvent; +using WorkerThreadPool = priv::AsyncWorkerPool; +#else +using WaitableEvent = priv::SingleThreadedWaitableEvent; +using WorkerThreadPool = priv::SingleThreadedWorkerPool; +#endif // (ANGLE_STD_ASYNC_WORKERS == ANGLE_ENABLED) + +} // namespace angle + +#endif // LIBANGLE_WORKER_THREAD_H_ diff --git a/src/3rdparty/angle/src/libANGLE/angletypes.cpp b/src/3rdparty/angle/src/libANGLE/angletypes.cpp index fa5b157906..702d391e46 100644 --- a/src/3rdparty/angle/src/libANGLE/angletypes.cpp +++ b/src/3rdparty/angle/src/libANGLE/angletypes.cpp @@ -39,38 +39,142 @@ PrimitiveType GetPrimitiveType(GLenum drawMode) } } +RasterizerState::RasterizerState() +{ + memset(this, 0, sizeof(RasterizerState)); + + rasterizerDiscard = false; + cullFace = false; + cullMode = CullFaceMode::Back; + frontFace = GL_CCW; + polygonOffsetFill = false; + polygonOffsetFactor = 0.0f; + polygonOffsetUnits = 0.0f; + pointDrawMode = false; + multiSample = false; +} + +bool operator==(const RasterizerState &a, const RasterizerState &b) +{ + return memcmp(&a, &b, sizeof(RasterizerState)) == 0; +} + +bool operator!=(const RasterizerState &a, const RasterizerState &b) +{ + return !(a == b); +} + +BlendState::BlendState() +{ + memset(this, 0, sizeof(BlendState)); + + blend = false; + sourceBlendRGB = GL_ONE; + sourceBlendAlpha = GL_ONE; + destBlendRGB = GL_ZERO; + destBlendAlpha = GL_ZERO; + blendEquationRGB = GL_FUNC_ADD; + blendEquationAlpha = GL_FUNC_ADD; + sampleAlphaToCoverage = false; + dither = true; +} + +BlendState::BlendState(const BlendState &other) +{ + memcpy(this, &other, sizeof(BlendState)); +} + +bool operator==(const BlendState &a, const BlendState &b) +{ + return memcmp(&a, &b, sizeof(BlendState)) == 0; +} + +bool operator!=(const BlendState &a, const BlendState &b) +{ + return !(a == b); +} + +DepthStencilState::DepthStencilState() +{ + memset(this, 0, sizeof(DepthStencilState)); + + depthTest = false; + depthFunc = GL_LESS; + depthMask = true; + stencilTest = false; + stencilFunc = GL_ALWAYS; + stencilMask = static_cast(-1); + stencilWritemask = static_cast(-1); + stencilBackFunc = GL_ALWAYS; + stencilBackMask = static_cast(-1); + stencilBackWritemask = static_cast(-1); + stencilFail = GL_KEEP; + stencilPassDepthFail = GL_KEEP; + stencilPassDepthPass = GL_KEEP; + stencilBackFail = GL_KEEP; + stencilBackPassDepthFail = GL_KEEP; + stencilBackPassDepthPass = GL_KEEP; +} + +DepthStencilState::DepthStencilState(const DepthStencilState &other) +{ + memcpy(this, &other, sizeof(DepthStencilState)); +} + +bool operator==(const DepthStencilState &a, const DepthStencilState &b) +{ + return memcmp(&a, &b, sizeof(DepthStencilState)) == 0; +} + +bool operator!=(const DepthStencilState &a, const DepthStencilState &b) +{ + return !(a == b); +} + SamplerState::SamplerState() - : minFilter(GL_NEAREST_MIPMAP_LINEAR), - magFilter(GL_LINEAR), - wrapS(GL_REPEAT), - wrapT(GL_REPEAT), - wrapR(GL_REPEAT), - maxAnisotropy(1.0f), - minLod(-1000.0f), - maxLod(1000.0f), - compareMode(GL_NONE), - compareFunc(GL_LEQUAL) +{ + memset(this, 0, sizeof(SamplerState)); + + minFilter = GL_NEAREST_MIPMAP_LINEAR; + magFilter = GL_LINEAR; + wrapS = GL_REPEAT; + wrapT = GL_REPEAT; + wrapR = GL_REPEAT; + maxAnisotropy = 1.0f; + minLod = -1000.0f; + maxLod = 1000.0f; + compareMode = GL_NONE; + compareFunc = GL_LEQUAL; + sRGBDecode = GL_DECODE_EXT; +} + +SamplerState::SamplerState(const SamplerState &other) = default; + +// static +SamplerState SamplerState::CreateDefaultForTarget(GLenum target) +{ + SamplerState state; + + // According to OES_EGL_image_external and ARB_texture_rectangle: For external textures, the + // default min filter is GL_LINEAR and the default s and t wrap modes are GL_CLAMP_TO_EDGE. + if (target == GL_TEXTURE_EXTERNAL_OES || target == GL_TEXTURE_RECTANGLE_ANGLE) + { + state.minFilter = GL_LINEAR; + state.wrapS = GL_CLAMP_TO_EDGE; + state.wrapT = GL_CLAMP_TO_EDGE; + } + + return state; +} + +ImageUnit::ImageUnit() + : texture(), level(0), layered(false), layer(0), access(GL_READ_ONLY), format(GL_R32UI) { } -TextureState::TextureState() - : swizzleRed(GL_RED), - swizzleGreen(GL_GREEN), - swizzleBlue(GL_BLUE), - swizzleAlpha(GL_ALPHA), - samplerState(), - baseLevel(0), - maxLevel(1000), - immutableFormat(false), - immutableLevels(0) -{ -} +ImageUnit::ImageUnit(const ImageUnit &other) = default; -bool TextureState::swizzleRequired() const -{ - return swizzleRed != GL_RED || swizzleGreen != GL_GREEN || - swizzleBlue != GL_BLUE || swizzleAlpha != GL_ALPHA; -} +ImageUnit::~ImageUnit() = default; static void MinMax(int a, int b, int *minimum, int *maximum) { @@ -133,6 +237,16 @@ bool Box::operator!=(const Box &other) const return !(*this == other); } +bool operator==(const Offset &a, const Offset &b) +{ + return a.x == b.x && a.y == b.y && a.z == b.z; +} + +bool operator!=(const Offset &a, const Offset &b) +{ + return !(a == b); +} + bool operator==(const Extents &lhs, const Extents &rhs) { return lhs.width == rhs.width && lhs.height == rhs.height && lhs.depth == rhs.depth; @@ -142,4 +256,4 @@ bool operator!=(const Extents &lhs, const Extents &rhs) { return !(lhs == rhs); } -} +} // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/angletypes.h b/src/3rdparty/angle/src/libANGLE/angletypes.h index c29ad06bd2..4f364b090a 100644 --- a/src/3rdparty/angle/src/libANGLE/angletypes.h +++ b/src/3rdparty/angle/src/libANGLE/angletypes.h @@ -9,20 +9,22 @@ #ifndef LIBANGLE_ANGLETYPES_H_ #define LIBANGLE_ANGLETYPES_H_ +#include "common/bitset_utils.h" #include "libANGLE/Constants.h" +#include "libANGLE/Error.h" +#include "libANGLE/PackedGLEnums.h" #include "libANGLE/RefCountObject.h" #include #include +#include +#include namespace gl { class Buffer; -class State; -class Program; -struct VertexAttribute; -struct VertexAttribCurrentValueData; +class Texture; enum PrimitiveType { @@ -41,31 +43,19 @@ PrimitiveType GetPrimitiveType(GLenum drawMode); enum SamplerType { SAMPLER_PIXEL, - SAMPLER_VERTEX + SAMPLER_VERTEX, + SAMPLER_COMPUTE }; -template -struct Color +enum ShaderType { - T red; - T green; - T blue; - T alpha; - - Color() : red(0), green(0), blue(0), alpha(0) { } - Color(T r, T g, T b, T a) : red(r), green(g), blue(b), alpha(a) { } + SHADER_VERTEX, + SHADER_FRAGMENT, + SHADER_GEOMETRY, + SHADER_COMPUTE, + SHADER_TYPE_MAX }; -template -bool operator==(const Color &a, const Color &b); - -template -bool operator!=(const Color &a, const Color &b); - -typedef Color ColorF; -typedef Color ColorI; -typedef Color ColorUI; - struct Rectangle { Rectangle() : x(0), y(0), width(0), height(0) {} @@ -100,6 +90,9 @@ struct Offset Offset(int x_in, int y_in, int z_in) : x(x_in), y(y_in), z(z_in) { } }; +bool operator==(const Offset &a, const Offset &b); +bool operator!=(const Offset &a, const Offset &b); + struct Extents { int width; @@ -109,6 +102,9 @@ struct Extents Extents() : width(0), height(0), depth(0) { } Extents(int width_, int height_, int depth_) : width(width_), height(height_), depth(depth_) { } + Extents(const Extents &other) = default; + Extents &operator=(const Extents &other) = default; + bool empty() const { return (width * height * depth) == 0; } }; @@ -131,11 +127,13 @@ struct Box bool operator!=(const Box &other) const; }; - -struct RasterizerState +struct RasterizerState final { + // This will zero-initialize the struct, including padding. + RasterizerState(); + bool cullFace; - GLenum cullMode; + CullFaceMode cullMode; GLenum frontFace; bool polygonOffsetFill; @@ -148,8 +146,15 @@ struct RasterizerState bool rasterizerDiscard; }; -struct BlendState +bool operator==(const RasterizerState &a, const RasterizerState &b); +bool operator!=(const RasterizerState &a, const RasterizerState &b); + +struct BlendState final { + // This will zero-initialize the struct, including padding. + BlendState(); + BlendState(const BlendState &other); + bool blend; GLenum sourceBlendRGB; GLenum destBlendRGB; @@ -168,8 +173,15 @@ struct BlendState bool dither; }; -struct DepthStencilState +bool operator==(const BlendState &a, const BlendState &b); +bool operator!=(const BlendState &a, const BlendState &b); + +struct DepthStencilState final { + // This will zero-initialize the struct, including padding. + DepthStencilState(); + DepthStencilState(const DepthStencilState &other); + bool depthTest; GLenum depthFunc; bool depthMask; @@ -189,10 +201,17 @@ struct DepthStencilState GLuint stencilBackWritemask; }; +bool operator==(const DepthStencilState &a, const DepthStencilState &b); +bool operator!=(const DepthStencilState &a, const DepthStencilState &b); + // State from Table 6.10 (state per sampler object) -struct SamplerState +struct SamplerState final { + // This will zero-initialize the struct, including padding. SamplerState(); + SamplerState(const SamplerState &other); + + static SamplerState CreateDefaultForTarget(GLenum target); GLenum minFilter; GLenum magFilter; @@ -209,110 +228,92 @@ struct SamplerState GLenum compareMode; GLenum compareFunc; + + GLenum sRGBDecode; }; bool operator==(const SamplerState &a, const SamplerState &b); bool operator!=(const SamplerState &a, const SamplerState &b); -// State from Table 6.9 (state per texture object) in the OpenGL ES 3.0.2 spec. -struct TextureState +struct DrawArraysIndirectCommand { - TextureState(); + GLuint count; + GLuint instanceCount; + GLuint first; + GLuint baseInstance; +}; +static_assert(sizeof(DrawArraysIndirectCommand) == 16, + "Unexpected size of DrawArraysIndirectCommand"); - GLenum swizzleRed; - GLenum swizzleGreen; - GLenum swizzleBlue; - GLenum swizzleAlpha; +struct DrawElementsIndirectCommand +{ + GLuint count; + GLuint primCount; + GLuint firstIndex; + GLint baseVertex; + GLuint baseInstance; +}; +static_assert(sizeof(DrawElementsIndirectCommand) == 20, + "Unexpected size of DrawElementsIndirectCommand"); - SamplerState samplerState; +struct ImageUnit +{ + ImageUnit(); + ImageUnit(const ImageUnit &other); + ~ImageUnit(); - GLuint baseLevel; - GLuint maxLevel; - - bool immutableFormat; - GLuint immutableLevels; - - // From GL_ANGLE_texture_usage - GLenum usage; - - bool swizzleRequired() const; + BindingPointer texture; + GLint level; + GLboolean layered; + GLint layer; + GLenum access; + GLenum format; }; -bool operator==(const TextureState &a, const TextureState &b); -bool operator!=(const TextureState &a, const TextureState &b); - -struct PixelUnpackState +struct PixelStoreStateBase { - BindingPointer pixelBuffer; - GLint alignment; - GLint rowLength; - GLint skipRows; - GLint skipPixels; - GLint imageHeight; - GLint skipImages; - - PixelUnpackState() - : alignment(4), - rowLength(0), - skipRows(0), - skipPixels(0), - imageHeight(0), - skipImages(0) - {} - - PixelUnpackState(GLint alignmentIn, GLint rowLengthIn) - : alignment(alignmentIn), - rowLength(rowLengthIn), - skipRows(0), - skipPixels(0), - imageHeight(0), - skipImages(0) - {} + GLint alignment = 4; + GLint rowLength = 0; + GLint skipRows = 0; + GLint skipPixels = 0; + GLint imageHeight = 0; + GLint skipImages = 0; }; -struct PixelPackState +struct PixelUnpackState : PixelStoreStateBase { - BindingPointer pixelBuffer; - GLint alignment; - bool reverseRowOrder; - GLint rowLength; - GLint skipRows; - GLint skipPixels; +}; - PixelPackState() - : alignment(4), - reverseRowOrder(false), - rowLength(0), - skipRows(0), - skipPixels(0) - {} - - explicit PixelPackState(GLint alignmentIn, bool reverseRowOrderIn) - : alignment(alignmentIn), - reverseRowOrder(reverseRowOrderIn), - rowLength(0), - skipRows(0), - skipPixels(0) - {} +struct PixelPackState : PixelStoreStateBase +{ + bool reverseRowOrder = false; }; // Used in Program and VertexArray. -typedef std::bitset AttributesMask; +using AttributesMask = angle::BitSet; -// Use in Program -typedef std::bitset UniformBlockBindingMask; -} +// Used in Program +using UniformBlockBindingMask = angle::BitSet; + +// Used in Framebuffer +using DrawBufferMask = angle::BitSet; + +using ContextID = uintptr_t; + +constexpr size_t CUBE_FACE_COUNT = 6; + +using TextureMap = std::map>; + +template +using AttachmentArray = std::array; + +template +using DrawBuffersArray = std::array; + +} // namespace gl namespace rx { -enum VendorID : uint32_t -{ - VENDOR_ID_UNKNOWN = 0x0, - VENDOR_ID_AMD = 0x1002, - VENDOR_ID_INTEL = 0x8086, - VENDOR_ID_NVIDIA = 0x10DE, -}; - // A macro that determines whether an object has a given runtime type. #if defined(__clang__) #if __has_feature(cxx_rtti) @@ -354,12 +355,12 @@ inline DestT *GetImplAs(SrcT *src) } template -inline const DestT *GetImplAs(const SrcT *src) +inline DestT *SafeGetImplAs(SrcT *src) { - return GetAs(src->getImplementation()); + return src != nullptr ? GetAs(src->getImplementation()) : nullptr; } -} +} // namespace rx #include "angletypes.inl" @@ -407,6 +408,80 @@ inline GLenum FramebufferBindingToEnum(FramebufferBinding binding) return GL_NONE; } } -} + +template +class DestroyThenDelete +{ + public: + DestroyThenDelete(const ContextT *context) : mContext(context) {} + + void operator()(ObjT *obj) + { + ANGLE_SWALLOW_ERR(obj->onDestroy(mContext)); + delete obj; + } + + private: + const ContextT *mContext; +}; + +// Helper class for wrapping an onDestroy function. +template +class UniqueObjectPointerBase : angle::NonCopyable +{ + public: + template + UniqueObjectPointerBase(const ContextT *context) : mObject(nullptr), mDeleter(context) + { + } + + template + UniqueObjectPointerBase(ObjT *obj, const ContextT *context) : mObject(obj), mDeleter(context) + { + } + + ~UniqueObjectPointerBase() + { + if (mObject) + { + mDeleter(mObject); + } + } + + ObjT *operator->() const { return mObject; } + + ObjT *release() + { + auto obj = mObject; + mObject = nullptr; + return obj; + } + + ObjT *get() const { return mObject; } + + void reset(ObjT *obj) + { + if (mObject) + { + mDeleter(mObject); + } + mObject = obj; + } + + private: + ObjT *mObject; + DeleterT mDeleter; +}; + +template +using UniqueObjectPointer = UniqueObjectPointerBase>; + +} // namespace angle + +namespace gl +{ +class ContextState; + +} // namespace gl #endif // LIBANGLE_ANGLETYPES_H_ diff --git a/src/3rdparty/angle/src/libANGLE/angletypes.inl b/src/3rdparty/angle/src/libANGLE/angletypes.inl index d51bcaaa78..3fbe0747d2 100644 --- a/src/3rdparty/angle/src/libANGLE/angletypes.inl +++ b/src/3rdparty/angle/src/libANGLE/angletypes.inl @@ -9,21 +9,6 @@ namespace gl { -template -bool operator==(const Color &a, const Color &b) -{ - return a.red == b.red && - a.green == b.green && - a.blue == b.blue && - a.alpha == b.alpha; -} - -template -bool operator!=(const Color &a, const Color &b) -{ - return !(a == b); -} - inline bool operator==(const Rectangle &a, const Rectangle &b) { return a.x == b.x && @@ -39,16 +24,7 @@ inline bool operator!=(const Rectangle &a, const Rectangle &b) inline bool operator==(const SamplerState &a, const SamplerState &b) { - return a.minFilter == b.minFilter && - a.magFilter == b.magFilter && - a.wrapS == b.wrapS && - a.wrapT == b.wrapT && - a.wrapR == b.wrapR && - a.maxAnisotropy == b.maxAnisotropy && - a.minLod == b.minLod && - a.maxLod == b.maxLod && - a.compareMode == b.compareMode && - a.compareFunc == b.compareFunc; + return memcmp(&a, &b, sizeof(SamplerState)) == 0; } inline bool operator!=(const SamplerState &a, const SamplerState &b) @@ -56,23 +32,4 @@ inline bool operator!=(const SamplerState &a, const SamplerState &b) return !(a == b); } -inline bool operator==(const TextureState &a, const TextureState &b) -{ - return a.swizzleRed == b.swizzleRed && - a.swizzleGreen == b.swizzleGreen && - a.swizzleBlue == b.swizzleBlue && - a.swizzleAlpha == b.swizzleAlpha && - a.samplerState == b.samplerState && - a.baseLevel == b.baseLevel && - a.maxLevel == b.maxLevel && - a.immutableFormat == b.immutableFormat && - a.immutableLevels == b.immutableLevels && - a.usage == b.usage; -} - -inline bool operator!=(const TextureState &a, const TextureState &b) -{ - return !(a == b); -} - -} +} // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/entry_points_enum_autogen.h b/src/3rdparty/angle/src/libANGLE/entry_points_enum_autogen.h new file mode 100644 index 0000000000..14b5e3c1b0 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/entry_points_enum_autogen.h @@ -0,0 +1,336 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml. +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// entry_points_enum_autogen.h: +// Defines the GLES entry points enumeration. + +#ifndef LIBGLESV2_ENTRYPOINTSENUM_AUTOGEN_H_ +#define LIBGLESV2_ENTRYPOINTSENUM_AUTOGEN_H_ + +namespace gl +{ +enum class EntryPoint +{ + Invalid, + ActiveTexture, + AttachShader, + BindAttribLocation, + BindBuffer, + BindFramebuffer, + BindRenderbuffer, + BindTexture, + BlendColor, + BlendEquation, + BlendEquationSeparate, + BlendFunc, + BlendFuncSeparate, + BufferData, + BufferSubData, + CheckFramebufferStatus, + Clear, + ClearColor, + ClearDepthf, + ClearStencil, + ColorMask, + CompileShader, + CompressedTexImage2D, + CompressedTexSubImage2D, + CopyTexImage2D, + CopyTexSubImage2D, + CreateProgram, + CreateShader, + CullFace, + DeleteBuffers, + DeleteFramebuffers, + DeleteProgram, + DeleteRenderbuffers, + DeleteShader, + DeleteTextures, + DepthFunc, + DepthMask, + DepthRangef, + DetachShader, + Disable, + DisableVertexAttribArray, + DrawArrays, + DrawElements, + Enable, + EnableVertexAttribArray, + Finish, + Flush, + FramebufferRenderbuffer, + FramebufferTexture2D, + FrontFace, + GenBuffers, + GenerateMipmap, + GenFramebuffers, + GenRenderbuffers, + GenTextures, + GetActiveAttrib, + GetActiveUniform, + GetAttachedShaders, + GetAttribLocation, + GetBooleanv, + GetBufferParameteriv, + GetError, + GetFloatv, + GetFramebufferAttachmentParameteriv, + GetIntegerv, + GetProgramiv, + GetProgramInfoLog, + GetRenderbufferParameteriv, + GetShaderiv, + GetShaderInfoLog, + GetShaderPrecisionFormat, + GetShaderSource, + GetString, + GetTexParameterfv, + GetTexParameteriv, + GetUniformfv, + GetUniformiv, + GetUniformLocation, + GetVertexAttribfv, + GetVertexAttribiv, + GetVertexAttribPointerv, + Hint, + IsBuffer, + IsEnabled, + IsFramebuffer, + IsProgram, + IsRenderbuffer, + IsShader, + IsTexture, + LineWidth, + LinkProgram, + PixelStorei, + PolygonOffset, + ReadPixels, + ReleaseShaderCompiler, + RenderbufferStorage, + SampleCoverage, + Scissor, + ShaderBinary, + ShaderSource, + StencilFunc, + StencilFuncSeparate, + StencilMask, + StencilMaskSeparate, + StencilOp, + StencilOpSeparate, + TexImage2D, + TexParameterf, + TexParameterfv, + TexParameteri, + TexParameteriv, + TexSubImage2D, + Uniform1f, + Uniform1fv, + Uniform1i, + Uniform1iv, + Uniform2f, + Uniform2fv, + Uniform2i, + Uniform2iv, + Uniform3f, + Uniform3fv, + Uniform3i, + Uniform3iv, + Uniform4f, + Uniform4fv, + Uniform4i, + Uniform4iv, + UniformMatrix2fv, + UniformMatrix3fv, + UniformMatrix4fv, + UseProgram, + ValidateProgram, + VertexAttrib1f, + VertexAttrib1fv, + VertexAttrib2f, + VertexAttrib2fv, + VertexAttrib3f, + VertexAttrib3fv, + VertexAttrib4f, + VertexAttrib4fv, + VertexAttribPointer, + Viewport, + ReadBuffer, + DrawRangeElements, + TexImage3D, + TexSubImage3D, + CopyTexSubImage3D, + CompressedTexImage3D, + CompressedTexSubImage3D, + GenQueries, + DeleteQueries, + IsQuery, + BeginQuery, + EndQuery, + GetQueryiv, + GetQueryObjectuiv, + UnmapBuffer, + GetBufferPointerv, + DrawBuffers, + UniformMatrix2x3fv, + UniformMatrix3x2fv, + UniformMatrix2x4fv, + UniformMatrix4x2fv, + UniformMatrix3x4fv, + UniformMatrix4x3fv, + BlitFramebuffer, + RenderbufferStorageMultisample, + FramebufferTextureLayer, + MapBufferRange, + FlushMappedBufferRange, + BindVertexArray, + DeleteVertexArrays, + GenVertexArrays, + IsVertexArray, + GetIntegeri_v, + BeginTransformFeedback, + EndTransformFeedback, + BindBufferRange, + BindBufferBase, + TransformFeedbackVaryings, + GetTransformFeedbackVarying, + VertexAttribIPointer, + GetVertexAttribIiv, + GetVertexAttribIuiv, + VertexAttribI4i, + VertexAttribI4ui, + VertexAttribI4iv, + VertexAttribI4uiv, + GetUniformuiv, + GetFragDataLocation, + Uniform1ui, + Uniform2ui, + Uniform3ui, + Uniform4ui, + Uniform1uiv, + Uniform2uiv, + Uniform3uiv, + Uniform4uiv, + ClearBufferiv, + ClearBufferuiv, + ClearBufferfv, + ClearBufferfi, + GetStringi, + CopyBufferSubData, + GetUniformIndices, + GetActiveUniformsiv, + GetUniformBlockIndex, + GetActiveUniformBlockiv, + GetActiveUniformBlockName, + UniformBlockBinding, + DrawArraysInstanced, + DrawElementsInstanced, + FenceSync, + IsSync, + DeleteSync, + ClientWaitSync, + WaitSync, + GetInteger64v, + GetSynciv, + GetInteger64i_v, + GetBufferParameteri64v, + GenSamplers, + DeleteSamplers, + IsSampler, + BindSampler, + SamplerParameteri, + SamplerParameteriv, + SamplerParameterf, + SamplerParameterfv, + GetSamplerParameteriv, + GetSamplerParameterfv, + VertexAttribDivisor, + BindTransformFeedback, + DeleteTransformFeedbacks, + GenTransformFeedbacks, + IsTransformFeedback, + PauseTransformFeedback, + ResumeTransformFeedback, + GetProgramBinary, + ProgramBinary, + ProgramParameteri, + InvalidateFramebuffer, + InvalidateSubFramebuffer, + TexStorage2D, + TexStorage3D, + GetInternalformativ, + DispatchCompute, + DispatchComputeIndirect, + DrawArraysIndirect, + DrawElementsIndirect, + FramebufferParameteri, + GetFramebufferParameteriv, + GetProgramInterfaceiv, + GetProgramResourceIndex, + GetProgramResourceName, + GetProgramResourceiv, + GetProgramResourceLocation, + UseProgramStages, + ActiveShaderProgram, + CreateShaderProgramv, + BindProgramPipeline, + DeleteProgramPipelines, + GenProgramPipelines, + IsProgramPipeline, + GetProgramPipelineiv, + ProgramUniform1i, + ProgramUniform2i, + ProgramUniform3i, + ProgramUniform4i, + ProgramUniform1ui, + ProgramUniform2ui, + ProgramUniform3ui, + ProgramUniform4ui, + ProgramUniform1f, + ProgramUniform2f, + ProgramUniform3f, + ProgramUniform4f, + ProgramUniform1iv, + ProgramUniform2iv, + ProgramUniform3iv, + ProgramUniform4iv, + ProgramUniform1uiv, + ProgramUniform2uiv, + ProgramUniform3uiv, + ProgramUniform4uiv, + ProgramUniform1fv, + ProgramUniform2fv, + ProgramUniform3fv, + ProgramUniform4fv, + ProgramUniformMatrix2fv, + ProgramUniformMatrix3fv, + ProgramUniformMatrix4fv, + ProgramUniformMatrix2x3fv, + ProgramUniformMatrix3x2fv, + ProgramUniformMatrix2x4fv, + ProgramUniformMatrix4x2fv, + ProgramUniformMatrix3x4fv, + ProgramUniformMatrix4x3fv, + ValidateProgramPipeline, + GetProgramPipelineInfoLog, + BindImageTexture, + GetBooleani_v, + MemoryBarrier, + MemoryBarrierByRegion, + TexStorage2DMultisample, + GetMultisamplefv, + SampleMaski, + GetTexLevelParameteriv, + GetTexLevelParameterfv, + BindVertexBuffer, + VertexAttribFormat, + VertexAttribIFormat, + VertexAttribBinding, + VertexBindingDivisor, + DrawElementsInstancedANGLE +}; +} // namespace gl +#endif // LIBGLESV2_ENTRY_POINTS_ENUM_AUTOGEN_H_ diff --git a/src/3rdparty/angle/src/libANGLE/es3_copy_conversion_formats.json b/src/3rdparty/angle/src/libANGLE/es3_copy_conversion_formats.json new file mode 100644 index 0000000000..39b71fd93a --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/es3_copy_conversion_formats.json @@ -0,0 +1,44 @@ +{ + "From ES 3.0.1 spec, table 3.15": + [ + [ "GL_ALPHA", "GL_RGBA" ], + [ "GL_LUMINANCE", "GL_RED" ], + [ "GL_LUMINANCE", "GL_RG" ], + [ "GL_LUMINANCE", "GL_RGB" ], + [ "GL_LUMINANCE", "GL_RGBA" ], + [ "GL_LUMINANCE_ALPHA", "GL_RGBA" ], + [ "GL_RED", "GL_RED" ], + [ "GL_RED", "GL_RG" ], + [ "GL_RED", "GL_RGB" ], + [ "GL_RED", "GL_RGBA" ], + [ "GL_RG", "GL_RG" ], + [ "GL_RG", "GL_RGB" ], + [ "GL_RG", "GL_RGBA" ], + [ "GL_RGB", "GL_RGB" ], + [ "GL_RGB", "GL_RGBA" ], + [ "GL_RGBA", "GL_RGBA" ] + ], + + "Necessary for ANGLE back-buffers": + [ + [ "GL_ALPHA", "GL_BGRA_EXT" ], + [ "GL_LUMINANCE", "GL_BGRA_EXT" ], + [ "GL_LUMINANCE_ALPHA", "GL_BGRA_EXT" ], + [ "GL_RED", "GL_BGRA_EXT" ], + [ "GL_RG", "GL_BGRA_EXT" ], + [ "GL_RGB", "GL_BGRA_EXT" ], + [ "GL_RGBA", "GL_BGRA_EXT" ], + [ "GL_BGRA_EXT", "GL_BGRA_EXT" ], + + [ "GL_RED_INTEGER", "GL_RED_INTEGER" ], + [ "GL_RED_INTEGER", "GL_RG_INTEGER" ], + [ "GL_RED_INTEGER", "GL_RGB_INTEGER" ], + [ "GL_RED_INTEGER", "GL_RGBA_INTEGER" ], + [ "GL_RG_INTEGER", "GL_RG_INTEGER" ], + [ "GL_RG_INTEGER", "GL_RGB_INTEGER" ], + [ "GL_RG_INTEGER", "GL_RGBA_INTEGER" ], + [ "GL_RGB_INTEGER", "GL_RGB_INTEGER" ], + [ "GL_RGB_INTEGER", "GL_RGBA_INTEGER" ], + [ "GL_RGBA_INTEGER", "GL_RGBA_INTEGER" ] + ] +} diff --git a/src/3rdparty/angle/src/libANGLE/es3_copy_conversion_table_autogen.cpp b/src/3rdparty/angle/src/libANGLE/es3_copy_conversion_table_autogen.cpp new file mode 100644 index 0000000000..149f79f458 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/es3_copy_conversion_table_autogen.cpp @@ -0,0 +1,171 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_copy_conversion_table.py using data from es3_copy_conversion_formats.json. +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// format_map: +// Determining the sized internal format from a (format,type) pair. +// Also check es3 format combinations for validity. + +#include "angle_gl.h" +#include "common/debug.h" + +namespace gl +{ + +bool ValidES3CopyConversion(GLenum textureFormat, GLenum framebufferFormat) +{ + switch (textureFormat) + { + case GL_ALPHA: + switch (framebufferFormat) + { + case GL_BGRA_EXT: + case GL_RGBA: + return true; + default: + break; + } + break; + + case GL_BGRA_EXT: + switch (framebufferFormat) + { + case GL_BGRA_EXT: + return true; + default: + break; + } + break; + + case GL_LUMINANCE: + switch (framebufferFormat) + { + case GL_BGRA_EXT: + case GL_RED: + case GL_RG: + case GL_RGB: + case GL_RGBA: + return true; + default: + break; + } + break; + + case GL_LUMINANCE_ALPHA: + switch (framebufferFormat) + { + case GL_BGRA_EXT: + case GL_RGBA: + return true; + default: + break; + } + break; + + case GL_RED: + switch (framebufferFormat) + { + case GL_BGRA_EXT: + case GL_RED: + case GL_RG: + case GL_RGB: + case GL_RGBA: + return true; + default: + break; + } + break; + + case GL_RED_INTEGER: + switch (framebufferFormat) + { + case GL_RED_INTEGER: + case GL_RGBA_INTEGER: + case GL_RGB_INTEGER: + case GL_RG_INTEGER: + return true; + default: + break; + } + break; + + case GL_RG: + switch (framebufferFormat) + { + case GL_BGRA_EXT: + case GL_RG: + case GL_RGB: + case GL_RGBA: + return true; + default: + break; + } + break; + + case GL_RGB: + switch (framebufferFormat) + { + case GL_BGRA_EXT: + case GL_RGB: + case GL_RGBA: + return true; + default: + break; + } + break; + + case GL_RGBA: + switch (framebufferFormat) + { + case GL_BGRA_EXT: + case GL_RGBA: + return true; + default: + break; + } + break; + + case GL_RGBA_INTEGER: + switch (framebufferFormat) + { + case GL_RGBA_INTEGER: + return true; + default: + break; + } + break; + + case GL_RGB_INTEGER: + switch (framebufferFormat) + { + case GL_RGBA_INTEGER: + case GL_RGB_INTEGER: + return true; + default: + break; + } + break; + + case GL_RG_INTEGER: + switch (framebufferFormat) + { + case GL_RGBA_INTEGER: + case GL_RGB_INTEGER: + case GL_RG_INTEGER: + return true; + default: + break; + } + break; + + default: + break; + } + + return false; +} + +} // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/es3_format_type_combinations.json b/src/3rdparty/angle/src/libANGLE/es3_format_type_combinations.json new file mode 100644 index 0000000000..fb12242e75 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/es3_format_type_combinations.json @@ -0,0 +1,171 @@ +{ + "Format combinations from ES 3.0.1 spec, table 3.2": + [ + [ "GL_RGBA8", "GL_RGBA", "GL_UNSIGNED_BYTE" ], + [ "GL_RGB5_A1", "GL_RGBA", "GL_UNSIGNED_BYTE" ], + [ "GL_RGBA4", "GL_RGBA", "GL_UNSIGNED_BYTE" ], + [ "GL_SRGB8_ALPHA8", "GL_RGBA", "GL_UNSIGNED_BYTE" ], + [ "GL_RGBA8_SNORM", "GL_RGBA", "GL_BYTE" ], + [ "GL_RGBA4", "GL_RGBA", "GL_UNSIGNED_SHORT_4_4_4_4" ], + [ "GL_RGB10_A2", "GL_RGBA", "GL_UNSIGNED_INT_2_10_10_10_REV" ], + [ "GL_RGB5_A1", "GL_RGBA", "GL_UNSIGNED_INT_2_10_10_10_REV" ], + [ "GL_RGB5_A1", "GL_RGBA", "GL_UNSIGNED_SHORT_5_5_5_1" ], + [ "GL_RGBA16F", "GL_RGBA", "GL_HALF_FLOAT" ], + [ "GL_RGBA16F", "GL_RGBA", "GL_HALF_FLOAT_OES" ], + [ "GL_RGBA32F", "GL_RGBA", "GL_FLOAT" ], + [ "GL_RGBA16F", "GL_RGBA", "GL_FLOAT" ], + [ "GL_RGBA8UI", "GL_RGBA_INTEGER", "GL_UNSIGNED_BYTE" ], + [ "GL_RGBA8I", "GL_RGBA_INTEGER", "GL_BYTE" ], + [ "GL_RGBA16UI", "GL_RGBA_INTEGER", "GL_UNSIGNED_SHORT" ], + [ "GL_RGBA16I", "GL_RGBA_INTEGER", "GL_SHORT" ], + [ "GL_RGBA32UI", "GL_RGBA_INTEGER", "GL_UNSIGNED_INT" ], + [ "GL_RGBA32I", "GL_RGBA_INTEGER", "GL_INT" ], + [ "GL_RGB10_A2UI", "GL_RGBA_INTEGER", "GL_UNSIGNED_INT_2_10_10_10_REV" ], + [ "GL_RGB8", "GL_RGB", "GL_UNSIGNED_BYTE" ], + [ "GL_RGB565", "GL_RGB", "GL_UNSIGNED_BYTE" ], + [ "GL_SRGB8", "GL_RGB", "GL_UNSIGNED_BYTE" ], + [ "GL_RGB8_SNORM", "GL_RGB", "GL_BYTE" ], + [ "GL_RGB565", "GL_RGB", "GL_UNSIGNED_SHORT_5_6_5" ], + [ "GL_R11F_G11F_B10F", "GL_RGB", "GL_UNSIGNED_INT_10F_11F_11F_REV" ], + [ "GL_RGB9_E5", "GL_RGB", "GL_UNSIGNED_INT_5_9_9_9_REV" ], + [ "GL_RGB16F", "GL_RGB", "GL_HALF_FLOAT" ], + [ "GL_RGB16F", "GL_RGB", "GL_HALF_FLOAT_OES" ], + [ "GL_R11F_G11F_B10F", "GL_RGB", "GL_HALF_FLOAT" ], + [ "GL_R11F_G11F_B10F", "GL_RGB", "GL_HALF_FLOAT_OES" ], + [ "GL_RGB9_E5", "GL_RGB", "GL_HALF_FLOAT" ], + [ "GL_RGB9_E5", "GL_RGB", "GL_HALF_FLOAT_OES" ], + [ "GL_RGB32F", "GL_RGB", "GL_FLOAT" ], + [ "GL_RGB16F", "GL_RGB", "GL_FLOAT" ], + [ "GL_R11F_G11F_B10F", "GL_RGB", "GL_FLOAT" ], + [ "GL_RGB9_E5", "GL_RGB", "GL_FLOAT" ], + [ "GL_RGB8UI", "GL_RGB_INTEGER", "GL_UNSIGNED_BYTE" ], + [ "GL_RGB8I", "GL_RGB_INTEGER", "GL_BYTE" ], + [ "GL_RGB16UI", "GL_RGB_INTEGER", "GL_UNSIGNED_SHORT" ], + [ "GL_RGB16I", "GL_RGB_INTEGER", "GL_SHORT" ], + [ "GL_RGB32UI", "GL_RGB_INTEGER", "GL_UNSIGNED_INT" ], + [ "GL_RGB32I", "GL_RGB_INTEGER", "GL_INT" ], + [ "GL_RG8", "GL_RG", "GL_UNSIGNED_BYTE" ], + [ "GL_RG8_SNORM", "GL_RG", "GL_BYTE" ], + [ "GL_RG16F", "GL_RG", "GL_HALF_FLOAT" ], + [ "GL_RG16F", "GL_RG", "GL_HALF_FLOAT_OES" ], + [ "GL_RG32F", "GL_RG", "GL_FLOAT" ], + [ "GL_RG16F", "GL_RG", "GL_FLOAT" ], + [ "GL_RG8UI", "GL_RG_INTEGER", "GL_UNSIGNED_BYTE" ], + [ "GL_RG8I", "GL_RG_INTEGER", "GL_BYTE" ], + [ "GL_RG16UI", "GL_RG_INTEGER", "GL_UNSIGNED_SHORT" ], + [ "GL_RG16I", "GL_RG_INTEGER", "GL_SHORT" ], + [ "GL_RG32UI", "GL_RG_INTEGER", "GL_UNSIGNED_INT" ], + [ "GL_RG32I", "GL_RG_INTEGER", "GL_INT" ], + [ "GL_R8", "GL_RED", "GL_UNSIGNED_BYTE" ], + [ "GL_R8_SNORM", "GL_RED", "GL_BYTE" ], + [ "GL_R16F", "GL_RED", "GL_HALF_FLOAT" ], + [ "GL_R16F", "GL_RED", "GL_HALF_FLOAT_OES" ], + [ "GL_R32F", "GL_RED", "GL_FLOAT" ], + [ "GL_R16F", "GL_RED", "GL_FLOAT" ], + [ "GL_R8UI", "GL_RED_INTEGER", "GL_UNSIGNED_BYTE" ], + [ "GL_R8I", "GL_RED_INTEGER", "GL_BYTE" ], + [ "GL_R16UI", "GL_RED_INTEGER", "GL_UNSIGNED_SHORT" ], + [ "GL_R16I", "GL_RED_INTEGER", "GL_SHORT" ], + [ "GL_R32UI", "GL_RED_INTEGER", "GL_UNSIGNED_INT" ], + [ "GL_R32I", "GL_RED_INTEGER", "GL_INT" ] + ], + "Unsized formats": + [ + [ "GL_RGBA", "GL_RGBA", "GL_UNSIGNED_BYTE" ], + [ "GL_RGBA", "GL_RGBA", "GL_UNSIGNED_SHORT_4_4_4_4" ], + [ "GL_RGBA", "GL_RGBA", "GL_UNSIGNED_SHORT_5_5_5_1" ], + [ "GL_RGB", "GL_RGB", "GL_UNSIGNED_BYTE" ], + [ "GL_RGB", "GL_RGB", "GL_UNSIGNED_SHORT_5_6_5" ], + [ "GL_LUMINANCE_ALPHA", "GL_LUMINANCE_ALPHA", "GL_UNSIGNED_BYTE" ], + [ "GL_LUMINANCE", "GL_LUMINANCE", "GL_UNSIGNED_BYTE" ], + [ "GL_ALPHA", "GL_ALPHA", "GL_UNSIGNED_BYTE" ], + [ "GL_SRGB_ALPHA_EXT", "GL_SRGB_ALPHA_EXT", "GL_UNSIGNED_BYTE" ], + [ "GL_SRGB_EXT", "GL_SRGB_EXT", "GL_UNSIGNED_BYTE" ], + [ "GL_RG", "GL_RG", "GL_UNSIGNED_BYTE" ], + [ "GL_RG", "GL_RG", "GL_FLOAT" ], + [ "GL_RG", "GL_RG", "GL_HALF_FLOAT" ], + [ "GL_RG", "GL_RG", "GL_HALF_FLOAT_OES" ], + [ "GL_RED", "GL_RED", "GL_UNSIGNED_BYTE" ], + [ "GL_RED", "GL_RED", "GL_FLOAT" ], + [ "GL_RED", "GL_RED", "GL_HALF_FLOAT" ], + [ "GL_RED", "GL_RED", "GL_HALF_FLOAT_OES" ], + [ "GL_DEPTH_STENCIL", "GL_DEPTH_STENCIL", "GL_UNSIGNED_INT_24_8" ] + ], + "Depth stencil formats": + [ + [ "GL_DEPTH_COMPONENT16", "GL_DEPTH_COMPONENT", "GL_UNSIGNED_SHORT" ], + [ "GL_DEPTH_COMPONENT24", "GL_DEPTH_COMPONENT", "GL_UNSIGNED_INT" ], + [ "GL_DEPTH_COMPONENT16", "GL_DEPTH_COMPONENT", "GL_UNSIGNED_INT" ], + [ "GL_DEPTH_COMPONENT32F", "GL_DEPTH_COMPONENT", "GL_FLOAT" ], + [ "GL_DEPTH24_STENCIL8", "GL_DEPTH_STENCIL", "GL_UNSIGNED_INT_24_8" ], + [ "GL_DEPTH32F_STENCIL8", "GL_DEPTH_STENCIL", "GL_FLOAT_32_UNSIGNED_INT_24_8_REV" ] + ], + "From GL_EXT_sRGB": + [ + [ "GL_SRGB8_ALPHA8_EXT", "GL_SRGB_ALPHA_EXT", "GL_UNSIGNED_BYTE" ], + [ "GL_SRGB8", "GL_SRGB_EXT", "GL_UNSIGNED_BYTE" ] + ], + "From GL_OES_texture_float": + [ + [ "GL_RGBA", "GL_RGBA", "GL_FLOAT" ], + [ "GL_RGB", "GL_RGB", "GL_FLOAT" ], + [ "GL_LUMINANCE_ALPHA", "GL_LUMINANCE_ALPHA", "GL_FLOAT" ], + [ "GL_LUMINANCE", "GL_LUMINANCE", "GL_FLOAT" ], + [ "GL_ALPHA", "GL_ALPHA", "GL_FLOAT" ] + ], + "From GL_OES_texture_half_float": + [ + [ "GL_RGBA", "GL_RGBA", "GL_HALF_FLOAT_OES" ], + [ "GL_RGB", "GL_RGB", "GL_HALF_FLOAT_OES" ], + [ "GL_LUMINANCE_ALPHA", "GL_LUMINANCE_ALPHA", "GL_HALF_FLOAT" ], + [ "GL_LUMINANCE_ALPHA", "GL_LUMINANCE_ALPHA", "GL_HALF_FLOAT_OES" ], + [ "GL_LUMINANCE", "GL_LUMINANCE", "GL_HALF_FLOAT" ], + [ "GL_LUMINANCE", "GL_LUMINANCE", "GL_HALF_FLOAT_OES" ], + [ "GL_ALPHA", "GL_ALPHA", "GL_HALF_FLOAT" ], + [ "GL_ALPHA", "GL_ALPHA", "GL_HALF_FLOAT_OES" ] + ], + "From GL_EXT_texture_format_BGRA8888": + [ + [ "GL_BGRA_EXT", "GL_BGRA_EXT", "GL_UNSIGNED_BYTE" ] + ], + "From GL_EXT_texture_storage": + [ + [ "GL_ALPHA8_EXT", "GL_ALPHA", "GL_UNSIGNED_BYTE" ], + [ "GL_LUMINANCE8_EXT", "GL_LUMINANCE", "GL_UNSIGNED_BYTE" ], + [ "GL_LUMINANCE8_ALPHA8_EXT", "GL_LUMINANCE_ALPHA", "GL_UNSIGNED_BYTE" ], + [ "GL_ALPHA32F_EXT", "GL_ALPHA", "GL_FLOAT" ], + [ "GL_LUMINANCE32F_EXT", "GL_LUMINANCE", "GL_FLOAT" ], + [ "GL_LUMINANCE_ALPHA32F_EXT", "GL_LUMINANCE_ALPHA", "GL_FLOAT" ], + [ "GL_ALPHA16F_EXT", "GL_ALPHA", "GL_HALF_FLOAT" ], + [ "GL_ALPHA16F_EXT", "GL_ALPHA", "GL_HALF_FLOAT_OES" ], + [ "GL_LUMINANCE16F_EXT", "GL_LUMINANCE", "GL_HALF_FLOAT" ], + [ "GL_LUMINANCE16F_EXT", "GL_LUMINANCE", "GL_HALF_FLOAT_OES" ], + [ "GL_LUMINANCE_ALPHA16F_EXT", "GL_LUMINANCE_ALPHA", "GL_HALF_FLOAT" ], + [ "GL_LUMINANCE_ALPHA16F_EXT", "GL_LUMINANCE_ALPHA", "GL_HALF_FLOAT_OES" ] + ], + "From GL_EXT_texture_storage and GL_EXT_texture_format_BGRA8888": + [ + [ "GL_BGRA8_EXT", "GL_BGRA_EXT", "GL_UNSIGNED_BYTE" ], + [ "GL_BGRA4_ANGLEX", "GL_BGRA_EXT", "GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT" ], + [ "GL_BGRA4_ANGLEX", "GL_BGRA_EXT", "GL_UNSIGNED_BYTE" ], + [ "GL_BGR5_A1_ANGLEX", "GL_BGRA_EXT", "GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT" ], + [ "GL_BGR5_A1_ANGLEX", "GL_BGRA_EXT", "GL_UNSIGNED_BYTE" ] + ], + "From GL_ANGLE_depth_texture and OES_depth_texture": + [ + [ "GL_DEPTH_COMPONENT32_OES", "GL_DEPTH_COMPONENT", "GL_UNSIGNED_INT_24_8" ], + [ "GL_DEPTH_COMPONENT", "GL_DEPTH_COMPONENT", "GL_UNSIGNED_SHORT" ], + [ "GL_DEPTH_COMPONENT", "GL_DEPTH_COMPONENT", "GL_UNSIGNED_INT" ] + ], + "From GL_EXT_texture_norm16": + [ + [ "GL_R16_EXT", "GL_RED", "GL_UNSIGNED_SHORT" ], + [ "GL_RG16_EXT", "GL_RG", "GL_UNSIGNED_SHORT" ], + [ "GL_RGB16_EXT", "GL_RGB", "GL_UNSIGNED_SHORT" ], + [ "GL_RGBA16_EXT", "GL_RGBA", "GL_UNSIGNED_SHORT" ], + [ "GL_R16_SNORM_EXT", "GL_RED", "GL_SHORT" ], + [ "GL_RG16_SNORM_EXT", "GL_RG", "GL_SHORT" ], + [ "GL_RGB16_SNORM_EXT", "GL_RGB", "GL_SHORT" ], + [ "GL_RGBA16_SNORM_EXT", "GL_RGBA", "GL_SHORT" ] + ] +} diff --git a/src/3rdparty/angle/src/libANGLE/features.h b/src/3rdparty/angle/src/libANGLE/features.h index ecf486dcf7..48a194ff0b 100644 --- a/src/3rdparty/angle/src/libANGLE/features.h +++ b/src/3rdparty/angle/src/libANGLE/features.h @@ -7,6 +7,8 @@ #ifndef LIBANGLE_FEATURES_H_ #define LIBANGLE_FEATURES_H_ +#include "common/platform.h" + #define ANGLE_DISABLED 0 #define ANGLE_ENABLED 1 @@ -50,4 +52,14 @@ #define ANGLE_PROGRAM_LINK_VALIDATE_UNIFORM_PRECISION ANGLE_ENABLED #endif +// Controls if our threading code uses std::async or falls back to single-threaded operations. +// TODO(jmadill): Enable on Linux once STL chrono headers are updated. +#if !defined(ANGLE_STD_ASYNC_WORKERS) +#if defined(ANGLE_PLATFORM_WINDOWS) +#define ANGLE_STD_ASYNC_WORKERS ANGLE_ENABLED +#else +#define ANGLE_STD_ASYNC_WORKERS ANGLE_DISABLED +#endif // defined(ANGLE_PLATFORM_WINDOWS) +#endif // !defined(ANGLE_STD_ASYNC_WORKERS) + #endif // LIBANGLE_FEATURES_H_ diff --git a/src/3rdparty/angle/src/libANGLE/format_map_autogen.cpp b/src/3rdparty/angle/src/libANGLE/format_map_autogen.cpp new file mode 100644 index 0000000000..a7f3ebafc8 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/format_map_autogen.cpp @@ -0,0 +1,1570 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_format_map.py using data from format_map_data.json. +// ES3 format info from es3_format_type_combinations.json. +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// format_map: +// Determining the sized internal format from a (format,type) pair. +// Also check es3 format combinations for validity. + +#include "angle_gl.h" +#include "common/debug.h" + +namespace gl +{ + +GLenum GetSizedFormatInternal(GLenum format, GLenum type) +{ + switch (format) + { + case GL_ALPHA: + switch (type) + { + case GL_FLOAT: + return GL_ALPHA32F_EXT; + case GL_HALF_FLOAT: + return GL_ALPHA16F_EXT; + case GL_HALF_FLOAT_OES: + return GL_ALPHA16F_EXT; + case GL_UNSIGNED_BYTE: + return GL_ALPHA8_EXT; + default: + break; + } + break; + + case GL_BGRA_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_BGRA8_EXT; + case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: + return GL_BGR5_A1_ANGLEX; + case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: + return GL_BGRA4_ANGLEX; + case GL_UNSIGNED_SHORT_5_6_5: + return GL_BGR565_ANGLEX; + default: + break; + } + break; + + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + default: + break; + } + break; + + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE; + default: + break; + } + break; + + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE; + default: + break; + } + break; + + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + default: + break; + } + break; + + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT; + default: + break; + } + break; + + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; + default: + break; + } + break; + + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; + default: + break; + } + break; + + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT; + default: + break; + } + break; + + case GL_DEPTH_COMPONENT: + switch (type) + { + case GL_FLOAT: + return GL_DEPTH_COMPONENT32F; + case GL_UNSIGNED_INT: + return GL_DEPTH_COMPONENT32_OES; + case GL_UNSIGNED_SHORT: + return GL_DEPTH_COMPONENT16; + default: + break; + } + break; + + case GL_DEPTH_STENCIL: + switch (type) + { + case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: + return GL_DEPTH32F_STENCIL8; + case GL_UNSIGNED_INT_24_8: + return GL_DEPTH24_STENCIL8; + default: + break; + } + break; + + case GL_LUMINANCE: + switch (type) + { + case GL_FLOAT: + return GL_LUMINANCE32F_EXT; + case GL_HALF_FLOAT: + return GL_LUMINANCE16F_EXT; + case GL_HALF_FLOAT_OES: + return GL_LUMINANCE16F_EXT; + case GL_UNSIGNED_BYTE: + return GL_LUMINANCE8_EXT; + default: + break; + } + break; + + case GL_LUMINANCE_ALPHA: + switch (type) + { + case GL_FLOAT: + return GL_LUMINANCE_ALPHA32F_EXT; + case GL_HALF_FLOAT: + return GL_LUMINANCE_ALPHA16F_EXT; + case GL_HALF_FLOAT_OES: + return GL_LUMINANCE_ALPHA16F_EXT; + case GL_UNSIGNED_BYTE: + return GL_LUMINANCE8_ALPHA8_EXT; + default: + break; + } + break; + + case GL_RED: + switch (type) + { + case GL_BYTE: + return GL_R8_SNORM; + case GL_FLOAT: + return GL_R32F; + case GL_HALF_FLOAT: + return GL_R16F; + case GL_HALF_FLOAT_OES: + return GL_R16F; + case GL_SHORT: + return GL_R16_SNORM_EXT; + case GL_UNSIGNED_BYTE: + return GL_R8; + case GL_UNSIGNED_SHORT: + return GL_R16_EXT; + default: + break; + } + break; + + case GL_RED_INTEGER: + switch (type) + { + case GL_BYTE: + return GL_R8I; + case GL_INT: + return GL_R32I; + case GL_SHORT: + return GL_R16I; + case GL_UNSIGNED_BYTE: + return GL_R8UI; + case GL_UNSIGNED_INT: + return GL_R32UI; + case GL_UNSIGNED_SHORT: + return GL_R16UI; + default: + break; + } + break; + + case GL_RG: + switch (type) + { + case GL_BYTE: + return GL_RG8_SNORM; + case GL_FLOAT: + return GL_RG32F; + case GL_HALF_FLOAT: + return GL_RG16F; + case GL_HALF_FLOAT_OES: + return GL_RG16F; + case GL_SHORT: + return GL_RG16_SNORM_EXT; + case GL_UNSIGNED_BYTE: + return GL_RG8; + case GL_UNSIGNED_SHORT: + return GL_RG16_EXT; + default: + break; + } + break; + + case GL_RGB: + switch (type) + { + case GL_BYTE: + return GL_RGB8_SNORM; + case GL_FLOAT: + return GL_RGB32F; + case GL_HALF_FLOAT: + return GL_RGB16F; + case GL_HALF_FLOAT_OES: + return GL_RGB16F; + case GL_SHORT: + return GL_RGB16_SNORM_EXT; + case GL_UNSIGNED_BYTE: + return GL_RGB8; + case GL_UNSIGNED_INT_10F_11F_11F_REV: + return GL_R11F_G11F_B10F; + case GL_UNSIGNED_INT_5_9_9_9_REV: + return GL_RGB9_E5; + case GL_UNSIGNED_SHORT: + return GL_RGB16_EXT; + case GL_UNSIGNED_SHORT_5_6_5: + return GL_RGB565; + default: + break; + } + break; + + case GL_RGBA: + switch (type) + { + case GL_BYTE: + return GL_RGBA8_SNORM; + case GL_FLOAT: + return GL_RGBA32F; + case GL_HALF_FLOAT: + return GL_RGBA16F; + case GL_HALF_FLOAT_OES: + return GL_RGBA16F; + case GL_SHORT: + return GL_RGBA16_SNORM_EXT; + case GL_UNSIGNED_BYTE: + return GL_RGBA8; + case GL_UNSIGNED_INT_2_10_10_10_REV: + return GL_RGB10_A2; + case GL_UNSIGNED_SHORT: + return GL_RGBA16_EXT; + case GL_UNSIGNED_SHORT_4_4_4_4: + return GL_RGBA4; + case GL_UNSIGNED_SHORT_5_5_5_1: + return GL_RGB5_A1; + default: + break; + } + break; + + case GL_RGBA_INTEGER: + switch (type) + { + case GL_BYTE: + return GL_RGBA8I; + case GL_INT: + return GL_RGBA32I; + case GL_SHORT: + return GL_RGBA16I; + case GL_UNSIGNED_BYTE: + return GL_RGBA8UI; + case GL_UNSIGNED_INT: + return GL_RGBA32UI; + case GL_UNSIGNED_INT_2_10_10_10_REV: + return GL_RGB10_A2UI; + case GL_UNSIGNED_SHORT: + return GL_RGBA16UI; + default: + break; + } + break; + + case GL_RGB_INTEGER: + switch (type) + { + case GL_BYTE: + return GL_RGB8I; + case GL_INT: + return GL_RGB32I; + case GL_SHORT: + return GL_RGB16I; + case GL_UNSIGNED_BYTE: + return GL_RGB8UI; + case GL_UNSIGNED_INT: + return GL_RGB32UI; + case GL_UNSIGNED_SHORT: + return GL_RGB16UI; + default: + break; + } + break; + + case GL_RG_INTEGER: + switch (type) + { + case GL_BYTE: + return GL_RG8I; + case GL_INT: + return GL_RG32I; + case GL_SHORT: + return GL_RG16I; + case GL_UNSIGNED_BYTE: + return GL_RG8UI; + case GL_UNSIGNED_INT: + return GL_RG32UI; + case GL_UNSIGNED_SHORT: + return GL_RG16UI; + default: + break; + } + break; + + case GL_SRGB_ALPHA_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_SRGB8_ALPHA8; + default: + break; + } + break; + + case GL_SRGB_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_SRGB8; + default: + break; + } + break; + + case GL_STENCIL: + switch (type) + { + case GL_UNSIGNED_BYTE: + return GL_STENCIL_INDEX8; + default: + break; + } + break; + + case GL_NONE: + return GL_NONE; + + default: + break; + } + + return GL_NONE; +} + +bool ValidES3Format(GLenum format) +{ + switch (format) + { + case GL_ALPHA: + case GL_BGRA_EXT: + case GL_DEPTH_COMPONENT: + case GL_DEPTH_STENCIL: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_RED: + case GL_RED_INTEGER: + case GL_RG: + case GL_RGB: + case GL_RGBA: + case GL_RGBA_INTEGER: + case GL_RGB_INTEGER: + case GL_RG_INTEGER: + case GL_SRGB_ALPHA_EXT: + case GL_SRGB_EXT: + return true; + + default: + return false; + } +} + +bool ValidES3Type(GLenum type) +{ + switch (type) + { + case GL_BYTE: + case GL_FLOAT: + case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: + case GL_HALF_FLOAT: + case GL_HALF_FLOAT_OES: + case GL_INT: + case GL_SHORT: + case GL_UNSIGNED_BYTE: + case GL_UNSIGNED_INT: + case GL_UNSIGNED_INT_10F_11F_11F_REV: + case GL_UNSIGNED_INT_24_8: + case GL_UNSIGNED_INT_2_10_10_10_REV: + case GL_UNSIGNED_INT_5_9_9_9_REV: + case GL_UNSIGNED_SHORT: + case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_5_6_5: + return true; + + default: + return false; + } +} + +bool ValidES3FormatCombination(GLenum format, GLenum type, GLenum internalFormat) +{ + ASSERT(ValidES3Format(format) && ValidES3Type(type)); + + switch (format) + { + case GL_RGB_INTEGER: + switch (type) + { + case GL_INT: + { + switch (internalFormat) + { + case GL_RGB32I: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_SHORT: + { + switch (internalFormat) + { + case GL_RGB16UI: + return true; + default: + break; + } + break; + } + case GL_SHORT: + { + switch (internalFormat) + { + case GL_RGB16I: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_RGB8UI: + return true; + default: + break; + } + break; + } + case GL_BYTE: + { + switch (internalFormat) + { + case GL_RGB8I: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_INT: + { + switch (internalFormat) + { + case GL_RGB32UI: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_RGBA_INTEGER: + switch (type) + { + case GL_INT: + { + switch (internalFormat) + { + case GL_RGBA32I: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_SHORT: + { + switch (internalFormat) + { + case GL_RGBA16UI: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_INT_2_10_10_10_REV: + { + switch (internalFormat) + { + case GL_RGB10_A2UI: + return true; + default: + break; + } + break; + } + case GL_SHORT: + { + switch (internalFormat) + { + case GL_RGBA16I: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_RGBA8UI: + return true; + default: + break; + } + break; + } + case GL_BYTE: + { + switch (internalFormat) + { + case GL_RGBA8I: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_INT: + { + switch (internalFormat) + { + case GL_RGBA32UI: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_RGB: + switch (type) + { + case GL_UNSIGNED_INT_10F_11F_11F_REV: + { + switch (internalFormat) + { + case GL_R11F_G11F_B10F: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_SHORT: + { + switch (internalFormat) + { + case GL_RGB16_EXT: + return true; + default: + break; + } + break; + } + case GL_SHORT: + { + switch (internalFormat) + { + case GL_RGB16_SNORM_EXT: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_RGB: + case GL_RGB8: + case GL_RGB565: + case GL_SRGB8: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_SHORT_5_6_5: + { + switch (internalFormat) + { + case GL_RGB: + case GL_RGB565: + return true; + default: + break; + } + break; + } + case GL_HALF_FLOAT_OES: + { + switch (internalFormat) + { + case GL_RGB: + case GL_RGB16F: + case GL_R11F_G11F_B10F: + case GL_RGB9_E5: + return true; + default: + break; + } + break; + } + case GL_HALF_FLOAT: + { + switch (internalFormat) + { + case GL_RGB16F: + case GL_R11F_G11F_B10F: + case GL_RGB9_E5: + return true; + default: + break; + } + break; + } + case GL_FLOAT: + { + switch (internalFormat) + { + case GL_RGB: + case GL_RGB32F: + case GL_RGB16F: + case GL_R11F_G11F_B10F: + case GL_RGB9_E5: + return true; + default: + break; + } + break; + } + case GL_BYTE: + { + switch (internalFormat) + { + case GL_RGB8_SNORM: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_INT_5_9_9_9_REV: + { + switch (internalFormat) + { + case GL_RGB9_E5: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_LUMINANCE_ALPHA: + switch (type) + { + case GL_HALF_FLOAT: + { + switch (internalFormat) + { + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE_ALPHA16F_EXT: + return true; + default: + break; + } + break; + } + case GL_FLOAT: + { + switch (internalFormat) + { + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE_ALPHA32F_EXT: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE8_ALPHA8_EXT: + return true; + default: + break; + } + break; + } + case GL_HALF_FLOAT_OES: + { + switch (internalFormat) + { + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE_ALPHA16F_EXT: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_ALPHA: + switch (type) + { + case GL_HALF_FLOAT: + { + switch (internalFormat) + { + case GL_ALPHA: + case GL_ALPHA16F_EXT: + return true; + default: + break; + } + break; + } + case GL_FLOAT: + { + switch (internalFormat) + { + case GL_ALPHA: + case GL_ALPHA32F_EXT: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_ALPHA: + case GL_ALPHA8_EXT: + return true; + default: + break; + } + break; + } + case GL_HALF_FLOAT_OES: + { + switch (internalFormat) + { + case GL_ALPHA: + case GL_ALPHA16F_EXT: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_RGBA: + switch (type) + { + case GL_UNSIGNED_SHORT: + { + switch (internalFormat) + { + case GL_RGBA16_EXT: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_INT_2_10_10_10_REV: + { + switch (internalFormat) + { + case GL_RGB10_A2: + case GL_RGB5_A1: + return true; + default: + break; + } + break; + } + case GL_SHORT: + { + switch (internalFormat) + { + case GL_RGBA16_SNORM_EXT: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_SHORT_4_4_4_4: + { + switch (internalFormat) + { + case GL_RGBA: + case GL_RGBA4: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_RGBA: + case GL_RGBA8: + case GL_RGB5_A1: + case GL_RGBA4: + case GL_SRGB8_ALPHA8: + return true; + default: + break; + } + break; + } + case GL_HALF_FLOAT_OES: + { + switch (internalFormat) + { + case GL_RGBA: + case GL_RGBA16F: + return true; + default: + break; + } + break; + } + case GL_HALF_FLOAT: + { + switch (internalFormat) + { + case GL_RGBA16F: + return true; + default: + break; + } + break; + } + case GL_FLOAT: + { + switch (internalFormat) + { + case GL_RGBA: + case GL_RGBA32F: + case GL_RGBA16F: + return true; + default: + break; + } + break; + } + case GL_BYTE: + { + switch (internalFormat) + { + case GL_RGBA8_SNORM: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_SHORT_5_5_5_1: + { + switch (internalFormat) + { + case GL_RGBA: + case GL_RGB5_A1: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_LUMINANCE: + switch (type) + { + case GL_HALF_FLOAT: + { + switch (internalFormat) + { + case GL_LUMINANCE: + case GL_LUMINANCE16F_EXT: + return true; + default: + break; + } + break; + } + case GL_FLOAT: + { + switch (internalFormat) + { + case GL_LUMINANCE: + case GL_LUMINANCE32F_EXT: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_LUMINANCE: + case GL_LUMINANCE8_EXT: + return true; + default: + break; + } + break; + } + case GL_HALF_FLOAT_OES: + { + switch (internalFormat) + { + case GL_LUMINANCE: + case GL_LUMINANCE16F_EXT: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_RG_INTEGER: + switch (type) + { + case GL_INT: + { + switch (internalFormat) + { + case GL_RG32I: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_SHORT: + { + switch (internalFormat) + { + case GL_RG16UI: + return true; + default: + break; + } + break; + } + case GL_SHORT: + { + switch (internalFormat) + { + case GL_RG16I: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_RG8UI: + return true; + default: + break; + } + break; + } + case GL_BYTE: + { + switch (internalFormat) + { + case GL_RG8I: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_INT: + { + switch (internalFormat) + { + case GL_RG32UI: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_RED_INTEGER: + switch (type) + { + case GL_INT: + { + switch (internalFormat) + { + case GL_R32I: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_SHORT: + { + switch (internalFormat) + { + case GL_R16UI: + return true; + default: + break; + } + break; + } + case GL_SHORT: + { + switch (internalFormat) + { + case GL_R16I: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_R8UI: + return true; + default: + break; + } + break; + } + case GL_BYTE: + { + switch (internalFormat) + { + case GL_R8I: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_INT: + { + switch (internalFormat) + { + case GL_R32UI: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_RED: + switch (type) + { + case GL_UNSIGNED_SHORT: + { + switch (internalFormat) + { + case GL_R16_EXT: + return true; + default: + break; + } + break; + } + case GL_SHORT: + { + switch (internalFormat) + { + case GL_R16_SNORM_EXT: + return true; + default: + break; + } + break; + } + case GL_FLOAT: + { + switch (internalFormat) + { + case GL_RED: + case GL_R32F: + case GL_R16F: + return true; + default: + break; + } + break; + } + case GL_HALF_FLOAT_OES: + { + switch (internalFormat) + { + case GL_RED: + case GL_R16F: + return true; + default: + break; + } + break; + } + case GL_HALF_FLOAT: + { + switch (internalFormat) + { + case GL_RED: + case GL_R16F: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_RED: + case GL_R8: + return true; + default: + break; + } + break; + } + case GL_BYTE: + { + switch (internalFormat) + { + case GL_R8_SNORM: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_DEPTH_COMPONENT: + switch (type) + { + case GL_UNSIGNED_INT: + { + switch (internalFormat) + { + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT16: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_INT_24_8: + { + switch (internalFormat) + { + case GL_DEPTH_COMPONENT32_OES: + return true; + default: + break; + } + break; + } + case GL_FLOAT: + { + switch (internalFormat) + { + case GL_DEPTH_COMPONENT32F: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_SHORT: + { + switch (internalFormat) + { + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_DEPTH_STENCIL: + switch (type) + { + case GL_UNSIGNED_INT_24_8: + { + switch (internalFormat) + { + case GL_DEPTH_STENCIL: + case GL_DEPTH24_STENCIL8: + return true; + default: + break; + } + break; + } + case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: + { + switch (internalFormat) + { + case GL_DEPTH32F_STENCIL8: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_SRGB_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_SRGB_EXT: + case GL_SRGB8: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_SRGB_ALPHA_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_SRGB_ALPHA_EXT: + case GL_SRGB8_ALPHA8_EXT: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_RG: + switch (type) + { + case GL_UNSIGNED_SHORT: + { + switch (internalFormat) + { + case GL_RG16_EXT: + return true; + default: + break; + } + break; + } + case GL_SHORT: + { + switch (internalFormat) + { + case GL_RG16_SNORM_EXT: + return true; + default: + break; + } + break; + } + case GL_FLOAT: + { + switch (internalFormat) + { + case GL_RG: + case GL_RG32F: + case GL_RG16F: + return true; + default: + break; + } + break; + } + case GL_HALF_FLOAT_OES: + { + switch (internalFormat) + { + case GL_RG: + case GL_RG16F: + return true; + default: + break; + } + break; + } + case GL_HALF_FLOAT: + { + switch (internalFormat) + { + case GL_RG: + case GL_RG16F: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_RG: + case GL_RG8: + return true; + default: + break; + } + break; + } + case GL_BYTE: + { + switch (internalFormat) + { + case GL_RG8_SNORM: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + case GL_BGRA_EXT: + switch (type) + { + case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: + { + switch (internalFormat) + { + case GL_BGRA4_ANGLEX: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_BYTE: + { + switch (internalFormat) + { + case GL_BGRA8_EXT: + case GL_BGRA4_ANGLEX: + case GL_BGR5_A1_ANGLEX: + case GL_BGRA_EXT: + return true; + default: + break; + } + break; + } + case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: + { + switch (internalFormat) + { + case GL_BGR5_A1_ANGLEX: + return true; + default: + break; + } + break; + } + default: + break; + } + break; + + default: + UNREACHABLE(); + break; + } + + return false; +} + +} // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/format_map_data.json b/src/3rdparty/angle/src/libANGLE/format_map_data.json new file mode 100644 index 0000000000..a4f1c98b4d --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/format_map_data.json @@ -0,0 +1,142 @@ +{ + "GL_RGBA": { + "GL_UNSIGNED_BYTE": "GL_RGBA8", + "GL_UNSIGNED_SHORT": "GL_RGBA16_EXT", + "GL_BYTE": "GL_RGBA8_SNORM", + "GL_SHORT": "GL_RGBA16_SNORM_EXT", + "GL_UNSIGNED_SHORT_4_4_4_4": "GL_RGBA4", + "GL_UNSIGNED_SHORT_5_5_5_1": "GL_RGB5_A1", + "GL_UNSIGNED_INT_2_10_10_10_REV": "GL_RGB10_A2", + "GL_FLOAT": "GL_RGBA32F", + "GL_HALF_FLOAT": "GL_RGBA16F", + "GL_HALF_FLOAT_OES": "GL_RGBA16F" + }, + "GL_RGBA_INTEGER": { + "GL_UNSIGNED_BYTE": "GL_RGBA8UI", + "GL_BYTE": "GL_RGBA8I", + "GL_UNSIGNED_SHORT": "GL_RGBA16UI", + "GL_SHORT": "GL_RGBA16I", + "GL_UNSIGNED_INT": "GL_RGBA32UI", + "GL_INT": "GL_RGBA32I", + "GL_UNSIGNED_INT_2_10_10_10_REV": "GL_RGB10_A2UI" + }, + "GL_RGB": { + "GL_UNSIGNED_BYTE": "GL_RGB8", + "GL_UNSIGNED_SHORT": "GL_RGB16_EXT", + "GL_BYTE": "GL_RGB8_SNORM", + "GL_SHORT": "GL_RGB16_SNORM_EXT", + "GL_UNSIGNED_SHORT_5_6_5": "GL_RGB565", + "GL_UNSIGNED_INT_10F_11F_11F_REV": "GL_R11F_G11F_B10F", + "GL_UNSIGNED_INT_5_9_9_9_REV": "GL_RGB9_E5", + "GL_FLOAT": "GL_RGB32F", + "GL_HALF_FLOAT": "GL_RGB16F", + "GL_HALF_FLOAT_OES": "GL_RGB16F" + }, + "GL_RGB_INTEGER": { + "GL_UNSIGNED_BYTE": "GL_RGB8UI", + "GL_BYTE": "GL_RGB8I", "GL_UNSIGNED_SHORT": "GL_RGB16UI", + "GL_SHORT": "GL_RGB16I", + "GL_UNSIGNED_INT": "GL_RGB32UI", + "GL_INT": "GL_RGB32I" + }, + "GL_RG": { + "GL_UNSIGNED_BYTE": "GL_RG8", + "GL_UNSIGNED_SHORT": "GL_RG16_EXT", + "GL_BYTE": "GL_RG8_SNORM", + "GL_SHORT": "GL_RG16_SNORM_EXT", + "GL_FLOAT": "GL_RG32F", + "GL_HALF_FLOAT": "GL_RG16F", + "GL_HALF_FLOAT_OES": "GL_RG16F" + }, + "GL_RG_INTEGER": { + "GL_UNSIGNED_BYTE": "GL_RG8UI", + "GL_BYTE": "GL_RG8I", + "GL_UNSIGNED_SHORT": "GL_RG16UI", + "GL_SHORT": "GL_RG16I", + "GL_UNSIGNED_INT": "GL_RG32UI", + "GL_INT": "GL_RG32I" + }, + "GL_RED": { + "GL_UNSIGNED_BYTE": "GL_R8", + "GL_UNSIGNED_SHORT": "GL_R16_EXT", + "GL_BYTE": "GL_R8_SNORM", + "GL_SHORT": "GL_R16_SNORM_EXT", + "GL_FLOAT": "GL_R32F", + "GL_HALF_FLOAT": "GL_R16F", + "GL_HALF_FLOAT_OES": "GL_R16F" + }, + "GL_RED_INTEGER": { + "GL_UNSIGNED_BYTE": "GL_R8UI", + "GL_BYTE": "GL_R8I", + "GL_UNSIGNED_SHORT": "GL_R16UI", + "GL_SHORT": "GL_R16I", + "GL_UNSIGNED_INT": "GL_R32UI", + "GL_INT": "GL_R32I" + }, + "GL_LUMINANCE_ALPHA": { + "GL_UNSIGNED_BYTE": "GL_LUMINANCE8_ALPHA8_EXT", + "GL_FLOAT": "GL_LUMINANCE_ALPHA32F_EXT", + "GL_HALF_FLOAT": "GL_LUMINANCE_ALPHA16F_EXT", + "GL_HALF_FLOAT_OES": "GL_LUMINANCE_ALPHA16F_EXT" + }, + "GL_LUMINANCE": { + "GL_UNSIGNED_BYTE": "GL_LUMINANCE8_EXT", + "GL_FLOAT": "GL_LUMINANCE32F_EXT", + "GL_HALF_FLOAT": "GL_LUMINANCE16F_EXT", + "GL_HALF_FLOAT_OES": "GL_LUMINANCE16F_EXT" + }, + "GL_ALPHA": { + "GL_UNSIGNED_BYTE": "GL_ALPHA8_EXT", + "GL_FLOAT": "GL_ALPHA32F_EXT", + "GL_HALF_FLOAT": "GL_ALPHA16F_EXT", + "GL_HALF_FLOAT_OES": "GL_ALPHA16F_EXT" + }, + "GL_BGRA_EXT": { + "GL_UNSIGNED_BYTE": "GL_BGRA8_EXT", + "GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT": "GL_BGRA4_ANGLEX", + "GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT": "GL_BGR5_A1_ANGLEX", + "GL_UNSIGNED_SHORT_5_6_5": "GL_BGR565_ANGLEX" + }, + "GL_SRGB_EXT": { + "GL_UNSIGNED_BYTE": "GL_SRGB8" + }, + "GL_SRGB_ALPHA_EXT": { + "GL_UNSIGNED_BYTE": "GL_SRGB8_ALPHA8" + }, + "GL_COMPRESSED_RGB_S3TC_DXT1_EXT": { + "GL_UNSIGNED_BYTE": "GL_COMPRESSED_RGB_S3TC_DXT1_EXT" + }, + "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT": { + "GL_UNSIGNED_BYTE": "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT" + }, + "GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE": { + "GL_UNSIGNED_BYTE": "GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE" + }, + "GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE": { + "GL_UNSIGNED_BYTE": "GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE" + }, + "GL_COMPRESSED_SRGB_S3TC_DXT1_EXT": { + "GL_UNSIGNED_BYTE": "GL_COMPRESSED_SRGB_S3TC_DXT1_EXT" + }, + "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT": { + "GL_UNSIGNED_BYTE": "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT" + }, + "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT": { + "GL_UNSIGNED_BYTE": "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT" + }, + "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT": { + "GL_UNSIGNED_BYTE": "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT" + }, + "GL_DEPTH_COMPONENT": { + "GL_UNSIGNED_SHORT": "GL_DEPTH_COMPONENT16", + "GL_UNSIGNED_INT": "GL_DEPTH_COMPONENT32_OES", + "GL_FLOAT": "GL_DEPTH_COMPONENT32F" + }, + "GL_STENCIL": { + "GL_UNSIGNED_BYTE": "GL_STENCIL_INDEX8" + }, + "GL_DEPTH_STENCIL": { + "GL_UNSIGNED_INT_24_8": "GL_DEPTH24_STENCIL8", + "GL_FLOAT_32_UNSIGNED_INT_24_8_REV": "GL_DEPTH32F_STENCIL8" + } +} diff --git a/src/3rdparty/angle/src/libANGLE/formatutils.cpp b/src/3rdparty/angle/src/libANGLE/formatutils.cpp index f8b9a8bab8..67bb2efdea 100644 --- a/src/3rdparty/angle/src/libANGLE/formatutils.cpp +++ b/src/3rdparty/angle/src/libANGLE/formatutils.cpp @@ -6,11 +6,13 @@ // formatutils.cpp: Queries for GL image formats. -#include "common/mathutil.h" #include "libANGLE/formatutils.h" + +#include "common/mathutil.h" #include "libANGLE/Context.h" #include "libANGLE/Framebuffer.h" -#include "libANGLE/renderer/Renderer.h" + +using namespace angle; namespace gl { @@ -18,116 +20,28 @@ namespace gl // ES2 requires that format is equal to internal format at all glTex*Image2D entry points and the implementation // can decide the true, sized, internal format. The ES2FormatMap determines the internal format for all valid // format and type combinations. +GLenum GetSizedFormatInternal(GLenum format, GLenum type); -typedef std::pair FormatTypePair; -typedef std::pair FormatPair; -typedef std::map FormatMap; - -// A helper function to insert data into the format map with fewer characters. -static inline void InsertFormatMapping(FormatMap *map, GLenum format, GLenum type, GLenum internalFormat) +namespace +{ +using InternalFormatInfoMap = + std::unordered_map>; + +} // anonymous namespace + +FormatType::FormatType() : format(GL_NONE), type(GL_NONE) { - map->insert(FormatPair(FormatTypePair(format, type), internalFormat)); } -FormatMap BuildFormatMap() +FormatType::FormatType(GLenum format_, GLenum type_) : format(format_), type(type_) { - FormatMap map; +} - // | Format | Type | Internal format | - InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA8); - InsertFormatMapping(&map, GL_RGBA, GL_BYTE, GL_RGBA8_SNORM); - InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_RGBA4); - InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_RGB5_A1); - InsertFormatMapping(&map, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2); - InsertFormatMapping(&map, GL_RGBA, GL_FLOAT, GL_RGBA32F); - InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT, GL_RGBA16F); - InsertFormatMapping(&map, GL_RGBA, GL_HALF_FLOAT_OES, GL_RGBA16F); - - InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_RGBA8UI); - InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_BYTE, GL_RGBA8I); - InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_RGBA16UI); - InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_SHORT, GL_RGBA16I); - InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_RGBA32UI); - InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_INT, GL_RGBA32I); - InsertFormatMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_RGB10_A2UI); - - InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_BYTE, GL_RGB8); - InsertFormatMapping(&map, GL_RGB, GL_BYTE, GL_RGB8_SNORM); - InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB565); - InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_R11F_G11F_B10F); - InsertFormatMapping(&map, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_RGB9_E5); - InsertFormatMapping(&map, GL_RGB, GL_FLOAT, GL_RGB32F); - InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT, GL_RGB16F); - InsertFormatMapping(&map, GL_RGB, GL_HALF_FLOAT_OES, GL_RGB16F); - - InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_RGB8UI); - InsertFormatMapping(&map, GL_RGB_INTEGER, GL_BYTE, GL_RGB8I); - InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_RGB16UI); - InsertFormatMapping(&map, GL_RGB_INTEGER, GL_SHORT, GL_RGB16I); - InsertFormatMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_RGB32UI); - InsertFormatMapping(&map, GL_RGB_INTEGER, GL_INT, GL_RGB32I); - - InsertFormatMapping(&map, GL_RG, GL_UNSIGNED_BYTE, GL_RG8); - InsertFormatMapping(&map, GL_RG, GL_BYTE, GL_RG8_SNORM); - InsertFormatMapping(&map, GL_RG, GL_FLOAT, GL_RG32F); - InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT, GL_RG16F); - InsertFormatMapping(&map, GL_RG, GL_HALF_FLOAT_OES, GL_RG16F); - - InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_RG8UI); - InsertFormatMapping(&map, GL_RG_INTEGER, GL_BYTE, GL_RG8I); - InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_RG16UI); - InsertFormatMapping(&map, GL_RG_INTEGER, GL_SHORT, GL_RG16I); - InsertFormatMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_RG32UI); - InsertFormatMapping(&map, GL_RG_INTEGER, GL_INT, GL_RG32I); - - InsertFormatMapping(&map, GL_RED, GL_UNSIGNED_BYTE, GL_R8); - InsertFormatMapping(&map, GL_RED, GL_BYTE, GL_R8_SNORM); - InsertFormatMapping(&map, GL_RED, GL_FLOAT, GL_R32F); - InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT, GL_R16F); - InsertFormatMapping(&map, GL_RED, GL_HALF_FLOAT_OES, GL_R16F); - - InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_R8UI); - InsertFormatMapping(&map, GL_RED_INTEGER, GL_BYTE, GL_R8I); - InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_R16UI); - InsertFormatMapping(&map, GL_RED_INTEGER, GL_SHORT, GL_R16I); - InsertFormatMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_R32UI); - InsertFormatMapping(&map, GL_RED_INTEGER, GL_INT, GL_R32I); - - InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE8_ALPHA8_EXT); - InsertFormatMapping(&map, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE8_EXT); - InsertFormatMapping(&map, GL_ALPHA, GL_UNSIGNED_BYTE, GL_ALPHA8_EXT); - InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_LUMINANCE_ALPHA32F_EXT); - InsertFormatMapping(&map, GL_LUMINANCE, GL_FLOAT, GL_LUMINANCE32F_EXT); - InsertFormatMapping(&map, GL_ALPHA, GL_FLOAT, GL_ALPHA32F_EXT); - InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, GL_LUMINANCE_ALPHA16F_EXT); - InsertFormatMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, GL_LUMINANCE_ALPHA16F_EXT); - InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT, GL_LUMINANCE16F_EXT); - InsertFormatMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT_OES, GL_LUMINANCE16F_EXT); - InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT, GL_ALPHA16F_EXT); - InsertFormatMapping(&map, GL_ALPHA, GL_HALF_FLOAT_OES, GL_ALPHA16F_EXT); - - InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_BGRA8_EXT); - InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_BGRA4_ANGLEX); - InsertFormatMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_BGR5_A1_ANGLEX); - - InsertFormatMapping(&map, GL_SRGB_EXT, GL_UNSIGNED_BYTE, GL_SRGB8); - InsertFormatMapping(&map, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, GL_SRGB8_ALPHA8); - - InsertFormatMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGB_S3TC_DXT1_EXT); - InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT); - InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE); - InsertFormatMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE); - - InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_DEPTH_COMPONENT16); - InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_DEPTH_COMPONENT32_OES); - InsertFormatMapping(&map, GL_DEPTH_COMPONENT, GL_FLOAT, GL_DEPTH_COMPONENT32F); - - InsertFormatMapping(&map, GL_STENCIL, GL_UNSIGNED_BYTE, GL_STENCIL_INDEX8); - - InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_DEPTH24_STENCIL8); - InsertFormatMapping(&map, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_DEPTH32F_STENCIL8); - - return map; +bool FormatType::operator<(const FormatType &other) const +{ + if (format != other.format) + return format < other.format; + return type < other.type; } Type::Type() @@ -158,20 +72,20 @@ bool operator<(const Type& a, const Type& b) } // Information about internal formats -static bool AlwaysSupported(GLuint, const Extensions &) +static bool AlwaysSupported(const Version &, const Extensions &) { return true; } -static bool NeverSupported(GLuint, const Extensions &) +static bool NeverSupported(const Version &, const Extensions &) { return false; } -template -static bool RequireES(GLuint clientVersion, const Extensions &) +template +static bool RequireES(const Version &clientVersion, const Extensions &) { - return clientVersion >= minCoreGLVersion; + return clientVersion >= Version(minCoreGLMajorVersion, minCoreGLMinorVersion); } // Pointer to a boolean memeber of the Extensions struct @@ -179,96 +93,192 @@ typedef bool(Extensions::*ExtensionBool); // Check support for a single extension template -static bool RequireExt(GLuint, const Extensions & extensions) +static bool RequireExt(const Version &, const Extensions &extensions) { return extensions.*bool1; } // Check for a minimum client version or a single extension -template -static bool RequireESOrExt(GLuint clientVersion, const Extensions &extensions) +template +static bool RequireESOrExt(const Version &clientVersion, const Extensions &extensions) { - return clientVersion >= minCoreGLVersion || extensions.*bool1; + return clientVersion >= Version(minCoreGLMajorVersion, minCoreGLMinorVersion) || + extensions.*bool1; } // Check for a minimum client version or two extensions -template -static bool RequireESOrExtAndExt(GLuint clientVersion, const Extensions &extensions) +template +static bool RequireESOrExtAndExt(const Version &clientVersion, const Extensions &extensions) { - return clientVersion >= minCoreGLVersion || (extensions.*bool1 && extensions.*bool2); + return clientVersion >= Version(minCoreGLMajorVersion, minCoreGLMinorVersion) || + (extensions.*bool1 && extensions.*bool2); } // Check for a minimum client version or at least one of two extensions -template -static bool RequireESOrExtOrExt(GLuint clientVersion, const Extensions &extensions) +template +static bool RequireESOrExtOrExt(const Version &clientVersion, const Extensions &extensions) { - return clientVersion >= minCoreGLVersion || extensions.*bool1 || extensions.*bool2; + return clientVersion >= Version(minCoreGLMajorVersion, minCoreGLMinorVersion) || + extensions.*bool1 || extensions.*bool2; } // Check support for two extensions template -static bool RequireExtAndExt(GLuint, const Extensions &extensions) +static bool RequireExtAndExt(const Version &, const Extensions &extensions) { return extensions.*bool1 && extensions.*bool2; } // Check support for either of two extensions template -static bool RequireExtOrExt(GLuint, const Extensions &extensions) +static bool RequireExtOrExt(const Version &, const Extensions &extensions) { return extensions.*bool1 || extensions.*bool2; } // Special function for half float formats with three or four channels. -static bool HalfFloatSupport(GLuint clientVersion, const Extensions &extensions) +static bool HalfFloatSupport(const Version &clientVersion, const Extensions &extensions) { - return clientVersion >= 3 || extensions.textureHalfFloat; + return clientVersion >= Version(3, 0) || extensions.textureHalfFloat; } -static bool HalfFloatRenderableSupport(GLuint clientVersion, const Extensions &extensions) +static bool HalfFloatRGBRenderableSupport(const Version &clientVersion, + const Extensions &extensions) { return HalfFloatSupport(clientVersion, extensions) && extensions.colorBufferHalfFloat; } -// Special function for half float formats with one or two channels. -static bool HalfFloatSupportRG(GLuint clientVersion, const Extensions &extensions) +static bool HalfFloatRGBARenderableSupport(const Version &clientVersion, + const Extensions &extensions) { - return clientVersion >= 3 || (extensions.textureHalfFloat && extensions.textureRG); + return HalfFloatSupport(clientVersion, extensions) && + (extensions.colorBufferHalfFloat || extensions.colorBufferFloat); } -static bool HalfFloatRenderableSupportRG(GLuint clientVersion, const Extensions &extensions) +// Special function for half float formats with one or two channels. + +// R16F, RG16F +static bool HalfFloatRGSupport(const Version &clientVersion, const Extensions &extensions) { - return HalfFloatSupportRG(clientVersion, extensions) && extensions.colorBufferHalfFloat; + return clientVersion >= Version(3, 0) || (extensions.textureHalfFloat && extensions.textureRG); +} + +// R16F, RG16F +static bool HalfFloatRGRenderableSupport(const Version &clientVersion, const Extensions &extensions) +{ + // It's unclear if EXT_color_buffer_half_float gives renderability to non-OES half float + // textures + return HalfFloatRGSupport(clientVersion, extensions) && + (extensions.colorBufferHalfFloat || extensions.colorBufferFloat); +} + +// RED + HALF_FLOAT_OES, RG + HALF_FLOAT_OES +static bool UnsizedHalfFloatOESRGSupport(const Version &, const Extensions &extensions) +{ + return extensions.textureHalfFloat && extensions.textureRG; +} + +// RED + HALF_FLOAT_OES, RG + HALF_FLOAT_OES +static bool UnsizedHalfFloatOESRGRenderableSupport(const Version &clientVersion, + const Extensions &extensions) +{ + return UnsizedHalfFloatOESRGSupport(clientVersion, extensions) && + extensions.colorBufferHalfFloat; +} + +// RGB + HALF_FLOAT_OES, RGBA + HALF_FLOAT_OES +static bool UnsizedHalfFloatOESSupport(const Version &clientVersion, const Extensions &extensions) +{ + return extensions.textureHalfFloat; +} + +// RGB + HALF_FLOAT_OES, RGBA + HALF_FLOAT_OES +static bool UnsizedHalfFloatOESRenderableSupport(const Version &clientVersion, + const Extensions &extensions) +{ + return UnsizedHalfFloatOESSupport(clientVersion, extensions) && extensions.colorBufferHalfFloat; } // Special function for float formats with three or four channels. -static bool FloatSupport(GLuint clientVersion, const Extensions &extensions) + +// RGB32F, RGBA32F +static bool FloatSupport(const Version &clientVersion, const Extensions &extensions) { - return clientVersion >= 3 || extensions.textureFloat; + return clientVersion >= Version(3, 0) || extensions.textureFloat; } -static bool FloatRenderableSupport(GLuint clientVersion, const Extensions &extensions) +// RGB32F +static bool FloatRGBRenderableSupport(const Version &clientVersion, const Extensions &extensions) +{ + return FloatSupport(clientVersion, extensions) && extensions.colorBufferFloatRGB; +} + +// RGBA32F +static bool FloatRGBARenderableSupport(const Version &clientVersion, const Extensions &extensions) { - // We don't expose colorBufferFloat in ES2, but we silently support rendering to float. return FloatSupport(clientVersion, extensions) && - (extensions.colorBufferFloat || clientVersion == 2); + (extensions.colorBufferFloat || extensions.colorBufferFloatRGBA); +} + +// RGB + FLOAT, RGBA + FLOAT +static bool UnsizedFloatSupport(const Version &clientVersion, const Extensions &extensions) +{ + return extensions.textureFloat; +} + +// RGB + FLOAT +static bool UnsizedFloatRGBRenderableSupport(const Version &clientVersion, + const Extensions &extensions) +{ + return UnsizedFloatSupport(clientVersion, extensions) && extensions.colorBufferFloatRGB; +} + +// RGBA + FLOAT +static bool UnsizedFloatRGBARenderableSupport(const Version &clientVersion, + const Extensions &extensions) +{ + return UnsizedFloatSupport(clientVersion, extensions) && + (extensions.colorBufferFloatRGBA || extensions.colorBufferFloat); } // Special function for float formats with one or two channels. -static bool FloatSupportRG(GLuint clientVersion, const Extensions &extensions) + +// R32F, RG32F +static bool FloatRGSupport(const Version &clientVersion, const Extensions &extensions) { - return clientVersion >= 3 || (extensions.textureFloat && extensions.textureRG); + return clientVersion >= Version(3, 0) || (extensions.textureFloat && extensions.textureRG); } -static bool FloatRenderableSupportRG(GLuint clientVersion, const Extensions &extensions) +// R32F, RG32F +static bool FloatRGRenderableSupport(const Version &clientVersion, const Extensions &extensions) { - // We don't expose colorBufferFloat in ES2, but we silently support rendering to float. - return FloatSupportRG(clientVersion, extensions) && - (extensions.colorBufferFloat || clientVersion == 2); + return FloatRGSupport(clientVersion, extensions) && extensions.colorBufferFloat; +} + +// RED + FLOAT, RG + FLOAT +static bool UnsizedFloatRGSupport(const Version &clientVersion, const Extensions &extensions) +{ + return extensions.textureFloat && extensions.textureRG; +} + +// RED + FLOAT, RG + FLOAT +static bool UnsizedFloatRGRenderableSupport(const Version &clientVersion, + const Extensions &extensions) +{ + return FloatRGSupport(clientVersion, extensions) && extensions.colorBufferFloat; } InternalFormat::InternalFormat() - : redBits(0), + : internalFormat(GL_NONE), + sized(false), + sizedInternalFormat(GL_NONE), + redBits(0), greenBits(0), blueBits(0), luminanceBits(0), @@ -291,32 +301,252 @@ InternalFormat::InternalFormat() { } -static InternalFormat UnsizedFormat(GLenum format, InternalFormat::SupportCheckFunction textureSupport, - InternalFormat::SupportCheckFunction renderSupport, - InternalFormat::SupportCheckFunction filterSupport) +InternalFormat::InternalFormat(const InternalFormat &other) = default; + +bool InternalFormat::isLUMA() const { - InternalFormat formatInfo; - formatInfo.format = format; - formatInfo.textureSupport = textureSupport; - formatInfo.renderSupport = renderSupport; - formatInfo.filterSupport = filterSupport; - return formatInfo; + return ((redBits + greenBits + blueBits + depthBits + stencilBits) == 0 && + (luminanceBits + alphaBits) > 0); } -static InternalFormat RGBAFormat(GLuint red, GLuint green, GLuint blue, GLuint alpha, GLuint shared, - GLenum format, GLenum type, GLenum componentType, bool srgb, - InternalFormat::SupportCheckFunction textureSupport, - InternalFormat::SupportCheckFunction renderSupport, - InternalFormat::SupportCheckFunction filterSupport) +GLenum InternalFormat::getReadPixelsFormat() const +{ + return format; +} + +GLenum InternalFormat::getReadPixelsType(const Version &version) const +{ + switch (type) + { + case GL_HALF_FLOAT: + case GL_HALF_FLOAT_OES: + if (version < Version(3, 0)) + { + // The internal format may have a type of GL_HALF_FLOAT but when exposing this type + // as the IMPLEMENTATION_READ_TYPE, only HALF_FLOAT_OES is allowed by + // OES_texture_half_float. HALF_FLOAT becomes core in ES3 and is acceptable to use + // as an IMPLEMENTATION_READ_TYPE. + return GL_HALF_FLOAT_OES; + } + else + { + return GL_HALF_FLOAT; + } + + default: + return type; + } +} + +bool InternalFormat::isRequiredRenderbufferFormat(const Version &version) const +{ + // GLES 3.0.5 section 4.4.2.2: + // "Implementations are required to support the same internal formats for renderbuffers as the + // required formats for textures enumerated in section 3.8.3.1, with the exception of the color + // formats labelled "texture-only"." + if (!sized || compressed) + { + return false; + } + + // Luma formats. + if (isLUMA()) + { + return false; + } + + // Depth/stencil formats. + if (depthBits > 0 || stencilBits > 0) + { + // GLES 2.0.25 table 4.5. + // GLES 3.0.5 section 3.8.3.1. + // GLES 3.1 table 8.14. + + // Required formats in all versions. + switch (internalFormat) + { + case GL_DEPTH_COMPONENT16: + case GL_STENCIL_INDEX8: + // Note that STENCIL_INDEX8 is not mentioned in GLES 3.0.5 section 3.8.3.1, but it + // is in section 4.4.2.2. + return true; + default: + break; + } + if (version.major < 3) + { + return false; + } + // Required formats in GLES 3.0 and up. + switch (internalFormat) + { + case GL_DEPTH_COMPONENT32F: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH32F_STENCIL8: + case GL_DEPTH24_STENCIL8: + return true; + default: + return false; + } + } + + // RGBA formats. + // GLES 2.0.25 table 4.5. + // GLES 3.0.5 section 3.8.3.1. + // GLES 3.1 table 8.13. + + // Required formats in all versions. + switch (internalFormat) + { + case GL_RGBA4: + case GL_RGB5_A1: + case GL_RGB565: + return true; + default: + break; + } + if (version.major < 3) + { + return false; + } + + if (format == GL_BGRA_EXT) + { + return false; + } + + switch (componentType) + { + case GL_SIGNED_NORMALIZED: + case GL_FLOAT: + return false; + case GL_UNSIGNED_INT: + case GL_INT: + // Integer RGB formats are not required renderbuffer formats. + if (alphaBits == 0 && blueBits != 0) + { + return false; + } + // All integer R and RG formats are required. + // Integer RGBA formats including RGB10_A2_UI are required. + return true; + case GL_UNSIGNED_NORMALIZED: + if (internalFormat == GL_SRGB8) + { + return false; + } + return true; + default: + UNREACHABLE(); + return false; + } +} + +Format::Format(GLenum internalFormat) : Format(GetSizedInternalFormatInfo(internalFormat)) +{ +} + +Format::Format(const InternalFormat &internalFormat) : info(&internalFormat) +{ +} + +Format::Format(GLenum internalFormat, GLenum type) + : info(&GetInternalFormatInfo(internalFormat, type)) +{ +} + +Format::Format(const Format &other) = default; +Format &Format::operator=(const Format &other) = default; + +bool Format::valid() const +{ + return info->internalFormat != GL_NONE; +} + +// static +bool Format::SameSized(const Format &a, const Format &b) +{ + return a.info->sizedInternalFormat == b.info->sizedInternalFormat; +} + +static GLenum EquivalentBlitInternalFormat(GLenum internalformat) +{ + // BlitFramebuffer works if the color channels are identically + // sized, even if there is a swizzle (for example, blitting from a + // multisampled RGBA8 renderbuffer to a BGRA8 texture). This could + // be expanded and/or autogenerated if that is found necessary. + if (internalformat == GL_BGRA8_EXT) + return GL_RGBA8; + return internalformat; +} + +// static +bool Format::EquivalentForBlit(const Format &a, const Format &b) +{ + return (EquivalentBlitInternalFormat(a.info->sizedInternalFormat) == + EquivalentBlitInternalFormat(b.info->sizedInternalFormat)); +} + +// static +Format Format::Invalid() +{ + static Format invalid(GL_NONE, GL_NONE); + return invalid; +} + +std::ostream &operator<<(std::ostream &os, const Format &fmt) +{ + // TODO(ynovikov): return string representation when available + return FmtHexShort(os, fmt.info->sizedInternalFormat); +} + +bool InternalFormat::operator==(const InternalFormat &other) const +{ + // We assume all internal formats are unique if they have the same internal format and type + return internalFormat == other.internalFormat && type == other.type; +} + +bool InternalFormat::operator!=(const InternalFormat &other) const +{ + return !(*this == other); +} + +void InsertFormatInfo(InternalFormatInfoMap *map, const InternalFormat &formatInfo) +{ + ASSERT(!formatInfo.sized || (*map).count(formatInfo.internalFormat) == 0); + ASSERT((*map)[formatInfo.internalFormat].count(formatInfo.type) == 0); + (*map)[formatInfo.internalFormat][formatInfo.type] = formatInfo; +} + +void AddRGBAFormat(InternalFormatInfoMap *map, + GLenum internalFormat, + bool sized, + GLuint red, + GLuint green, + GLuint blue, + GLuint alpha, + GLuint shared, + GLenum format, + GLenum type, + GLenum componentType, + bool srgb, + InternalFormat::SupportCheckFunction textureSupport, + InternalFormat::SupportCheckFunction renderSupport, + InternalFormat::SupportCheckFunction filterSupport) { InternalFormat formatInfo; + formatInfo.internalFormat = internalFormat; + formatInfo.sized = sized; + formatInfo.sizedInternalFormat = + sized ? internalFormat : GetSizedFormatInternal(internalFormat, type); formatInfo.redBits = red; formatInfo.greenBits = green; formatInfo.blueBits = blue; formatInfo.alphaBits = alpha; formatInfo.sharedBits = shared; formatInfo.pixelBytes = (red + green + blue + alpha + shared) / 8; - formatInfo.componentCount = ((red > 0) ? 1 : 0) + ((green > 0) ? 1 : 0) + ((blue > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0); + formatInfo.componentCount = + ((red > 0) ? 1 : 0) + ((green > 0) ? 1 : 0) + ((blue > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0); formatInfo.format = format; formatInfo.type = type; formatInfo.componentType = componentType; @@ -324,15 +554,27 @@ static InternalFormat RGBAFormat(GLuint red, GLuint green, GLuint blue, GLuint a formatInfo.textureSupport = textureSupport; formatInfo.renderSupport = renderSupport; formatInfo.filterSupport = filterSupport; - return formatInfo; + + InsertFormatInfo(map, formatInfo); } -static InternalFormat LUMAFormat(GLuint luminance, GLuint alpha, GLenum format, GLenum type, GLenum componentType, - InternalFormat::SupportCheckFunction textureSupport, - InternalFormat::SupportCheckFunction renderSupport, - InternalFormat::SupportCheckFunction filterSupport) +static void AddLUMAFormat(InternalFormatInfoMap *map, + GLenum internalFormat, + bool sized, + GLuint luminance, + GLuint alpha, + GLenum format, + GLenum type, + GLenum componentType, + InternalFormat::SupportCheckFunction textureSupport, + InternalFormat::SupportCheckFunction renderSupport, + InternalFormat::SupportCheckFunction filterSupport) { InternalFormat formatInfo; + formatInfo.internalFormat = internalFormat; + formatInfo.sized = sized; + formatInfo.sizedInternalFormat = + sized ? internalFormat : GetSizedFormatInternal(internalFormat, type); formatInfo.luminanceBits = luminance; formatInfo.alphaBits = alpha; formatInfo.pixelBytes = (luminance + alpha) / 8; @@ -344,15 +586,28 @@ static InternalFormat LUMAFormat(GLuint luminance, GLuint alpha, GLenum format, formatInfo.textureSupport = textureSupport; formatInfo.renderSupport = renderSupport; formatInfo.filterSupport = filterSupport; - return formatInfo; + + InsertFormatInfo(map, formatInfo); } -static InternalFormat DepthStencilFormat(GLuint depthBits, GLuint stencilBits, GLuint unusedBits, GLenum format, - GLenum type, GLenum componentType, InternalFormat::SupportCheckFunction textureSupport, - InternalFormat::SupportCheckFunction renderSupport, - InternalFormat::SupportCheckFunction filterSupport) +void AddDepthStencilFormat(InternalFormatInfoMap *map, + GLenum internalFormat, + bool sized, + GLuint depthBits, + GLuint stencilBits, + GLuint unusedBits, + GLenum format, + GLenum type, + GLenum componentType, + InternalFormat::SupportCheckFunction textureSupport, + InternalFormat::SupportCheckFunction renderSupport, + InternalFormat::SupportCheckFunction filterSupport) { InternalFormat formatInfo; + formatInfo.internalFormat = internalFormat; + formatInfo.sized = sized; + formatInfo.sizedInternalFormat = + sized ? internalFormat : GetSizedFormatInternal(internalFormat, type); formatInfo.depthBits = depthBits; formatInfo.stencilBits = stencilBits; formatInfo.pixelBytes = (depthBits + stencilBits + unusedBits) / 8; @@ -364,16 +619,27 @@ static InternalFormat DepthStencilFormat(GLuint depthBits, GLuint stencilBits, G formatInfo.textureSupport = textureSupport; formatInfo.renderSupport = renderSupport; formatInfo.filterSupport = filterSupport; - return formatInfo; + + InsertFormatInfo(map, formatInfo); } -static InternalFormat CompressedFormat(GLuint compressedBlockWidth, GLuint compressedBlockHeight, GLuint compressedBlockSize, - GLuint componentCount, GLenum format, GLenum type, bool srgb, - InternalFormat::SupportCheckFunction textureSupport, - InternalFormat::SupportCheckFunction renderSupport, - InternalFormat::SupportCheckFunction filterSupport) +void AddCompressedFormat(InternalFormatInfoMap *map, + GLenum internalFormat, + GLuint compressedBlockWidth, + GLuint compressedBlockHeight, + GLuint compressedBlockSize, + GLuint componentCount, + GLenum format, + GLenum type, + bool srgb, + InternalFormat::SupportCheckFunction textureSupport, + InternalFormat::SupportCheckFunction renderSupport, + InternalFormat::SupportCheckFunction filterSupport) { InternalFormat formatInfo; + formatInfo.internalFormat = internalFormat; + formatInfo.sized = true; + formatInfo.sizedInternalFormat = internalFormat; formatInfo.compressedBlockWidth = compressedBlockWidth; formatInfo.compressedBlockHeight = compressedBlockHeight; formatInfo.pixelBytes = compressedBlockSize / 8; @@ -386,189 +652,279 @@ static InternalFormat CompressedFormat(GLuint compressedBlockWidth, GLuint compr formatInfo.textureSupport = textureSupport; formatInfo.renderSupport = renderSupport; formatInfo.filterSupport = filterSupport; - return formatInfo; -} -typedef std::pair InternalFormatInfoPair; -typedef std::map InternalFormatInfoMap; + InsertFormatInfo(map, formatInfo); +} static InternalFormatInfoMap BuildInternalFormatInfoMap() { InternalFormatInfoMap map; - // clang-format off // From ES 3.0.1 spec, table 3.12 - map.insert(InternalFormatInfoPair(GL_NONE, InternalFormat())); + map[GL_NONE][GL_NONE] = InternalFormat(); - // | Internal format | | R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Renderable | Filterable | - map.insert(InternalFormatInfoPair(GL_R8, RGBAFormat( 8, 0, 0, 0, 0, GL_RED, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, &Extensions::textureRG>, RequireESOrExt<3, &Extensions::textureRG>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_R8_SNORM, RGBAFormat( 8, 0, 0, 0, 0, GL_RED, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RG8, RGBAFormat( 8, 8, 0, 0, 0, GL_RG, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, &Extensions::textureRG>, RequireESOrExt<3, &Extensions::textureRG>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RG8_SNORM, RGBAFormat( 8, 8, 0, 0, 0, GL_RG, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGB8, RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, &Extensions::rgb8rgba8>, RequireESOrExt<3, &Extensions::rgb8rgba8>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGB8_SNORM, RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGB565, RGBAFormat( 5, 6, 5, 0, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_NORMALIZED, false, RequireES<2>, RequireES<2>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGBA4, RGBAFormat( 4, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_NORMALIZED, false, RequireES<2>, RequireES<2>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGB5_A1, RGBAFormat( 5, 5, 5, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_NORMALIZED, false, RequireES<2>, RequireES<2>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGBA8, RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, &Extensions::rgb8rgba8>, RequireESOrExt<3, &Extensions::rgb8rgba8>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGBA8_SNORM, RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGB10_A2, RGBAFormat(10, 10, 10, 2, 0, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, RequireES<3>, RequireES<3>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGB10_A2UI, RGBAFormat(10, 10, 10, 2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_SRGB8, RGBAFormat( 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireESOrExt<3, &Extensions::sRGB>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_SRGB8_ALPHA8, RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireESOrExt<3, &Extensions::sRGB>, RequireESOrExt<3, &Extensions::sRGB>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_R11F_G11F_B10F, RGBAFormat(11, 11, 10, 0, 0, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_FLOAT, false, RequireES<3>, RequireExt<&Extensions::colorBufferFloat>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGB9_E5, RGBAFormat( 9, 9, 9, 0, 5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT, false, RequireES<3>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_R8I, RGBAFormat( 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_BYTE, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_R8UI, RGBAFormat( 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_R16I, RGBAFormat(16, 0, 0, 0, 0, GL_RED_INTEGER, GL_SHORT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_R16UI, RGBAFormat(16, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_R32I, RGBAFormat(32, 0, 0, 0, 0, GL_RED_INTEGER, GL_INT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_R32UI, RGBAFormat(32, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RG8I, RGBAFormat( 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_BYTE, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RG8UI, RGBAFormat( 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RG16I, RGBAFormat(16, 16, 0, 0, 0, GL_RG_INTEGER, GL_SHORT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RG16UI, RGBAFormat(16, 16, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RG32I, RGBAFormat(32, 32, 0, 0, 0, GL_RG_INTEGER, GL_INT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RG32UI, RGBAFormat(32, 32, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RGB8I, RGBAFormat( 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_BYTE, GL_INT, false, RequireES<3>, NeverSupported, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RGB8UI, RGBAFormat( 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3>, NeverSupported, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RGB16I, RGBAFormat(16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_SHORT, GL_INT, false, RequireES<3>, NeverSupported, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RGB16UI, RGBAFormat(16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3>, NeverSupported, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RGB32I, RGBAFormat(32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_INT, GL_INT, false, RequireES<3>, NeverSupported, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RGB32UI, RGBAFormat(32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3>, NeverSupported, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RGBA8I, RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_BYTE, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RGBA8UI, RGBAFormat( 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RGBA16I, RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_SHORT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RGBA16UI, RGBAFormat(16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RGBA32I, RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_INT, GL_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); - map.insert(InternalFormatInfoPair(GL_RGBA32UI, RGBAFormat(32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3>, RequireES<3>, NeverSupported))); + // clang-format off - map.insert(InternalFormatInfoPair(GL_BGRA8_EXT, RGBAFormat( 8, 8, 8, 8, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888>, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_BGRA4_ANGLEX, RGBAFormat( 4, 4, 4, 4, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888>, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_BGR5_A1_ANGLEX, RGBAFormat( 5, 5, 5, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888>, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported))); + // | Internal format |sized| R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Renderable | Filterable | + AddRGBAFormat(&map, GL_R8, true, 8, 0, 0, 0, 0, GL_RED, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, 0, &Extensions::textureRG>, RequireESOrExt<3, 0, &Extensions::textureRG>, AlwaysSupported); + AddRGBAFormat(&map, GL_R8_SNORM, true, 8, 0, 0, 0, 0, GL_RED, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3, 0>, NeverSupported, AlwaysSupported); + AddRGBAFormat(&map, GL_RG8, true, 8, 8, 0, 0, 0, GL_RG, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, 0, &Extensions::textureRG>, RequireESOrExt<3, 0, &Extensions::textureRG>, AlwaysSupported); + AddRGBAFormat(&map, GL_RG8_SNORM, true, 8, 8, 0, 0, 0, GL_RG, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3, 0>, NeverSupported, AlwaysSupported); + AddRGBAFormat(&map, GL_RGB8, true, 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, 0, &Extensions::rgb8rgba8>, RequireESOrExt<3, 0, &Extensions::rgb8rgba8>, AlwaysSupported); + AddRGBAFormat(&map, GL_RGB8_SNORM, true, 8, 8, 8, 0, 0, GL_RGB, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3, 0>, NeverSupported, AlwaysSupported); + AddRGBAFormat(&map, GL_RGB565, true, 5, 6, 5, 0, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_NORMALIZED, false, RequireES<2, 0>, RequireES<2, 0>, AlwaysSupported); + AddRGBAFormat(&map, GL_RGBA4, true, 4, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_NORMALIZED, false, RequireES<2, 0>, RequireES<2, 0>, AlwaysSupported); + AddRGBAFormat(&map, GL_RGB5_A1, true, 5, 5, 5, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_NORMALIZED, false, RequireES<2, 0>, RequireES<2, 0>, AlwaysSupported); + AddRGBAFormat(&map, GL_RGBA8, true, 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, 0, &Extensions::rgb8rgba8>, RequireESOrExt<3, 0, &Extensions::rgb8rgba8>, AlwaysSupported); + AddRGBAFormat(&map, GL_RGBA8_SNORM, true, 8, 8, 8, 8, 0, GL_RGBA, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3, 0>, NeverSupported, AlwaysSupported); + AddRGBAFormat(&map, GL_RGB10_A2, true, 10, 10, 10, 2, 0, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, RequireES<3, 0>, RequireES<3, 0>, AlwaysSupported); + AddRGBAFormat(&map, GL_RGB10_A2UI, true, 10, 10, 10, 2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT, false, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_SRGB8, true, 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireESOrExt<3, 0, &Extensions::sRGB>, NeverSupported, AlwaysSupported); + AddRGBAFormat(&map, GL_SRGB8_ALPHA8, true, 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireESOrExt<3, 0, &Extensions::sRGB>, RequireESOrExt<3, 0, &Extensions::sRGB>, AlwaysSupported); + AddRGBAFormat(&map, GL_RGB9_E5, true, 9, 9, 9, 0, 5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT, false, RequireES<3, 0>, NeverSupported, AlwaysSupported); + AddRGBAFormat(&map, GL_R8I, true, 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_BYTE, GL_INT, false, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_R8UI, true, 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_R16I, true, 16, 0, 0, 0, 0, GL_RED_INTEGER, GL_SHORT, GL_INT, false, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_R16UI, true, 16, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_R32I, true, 32, 0, 0, 0, 0, GL_RED_INTEGER, GL_INT, GL_INT, false, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_R32UI, true, 32, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_RG8I, true, 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_BYTE, GL_INT, false, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_RG8UI, true, 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_RG16I, true, 16, 16, 0, 0, 0, GL_RG_INTEGER, GL_SHORT, GL_INT, false, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_RG16UI, true, 16, 16, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_RG32I, true, 32, 32, 0, 0, 0, GL_RG_INTEGER, GL_INT, GL_INT, false, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_R11F_G11F_B10F, true, 11, 11, 10, 0, 0, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_FLOAT, false, RequireES<3, 0>, RequireExt<&Extensions::colorBufferFloat>, AlwaysSupported); + AddRGBAFormat(&map, GL_RG32UI, true, 32, 32, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_RGB8I, true, 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_BYTE, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB8UI, true, 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB16I, true, 16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_SHORT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB16UI, true, 16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB32I, true, 32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_INT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB32UI, true, 32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGBA8I, true, 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_BYTE, GL_INT, false, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_RGBA8UI, true, 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_RGBA16I, true, 16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_SHORT, GL_INT, false, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_RGBA16UI, true, 16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_RGBA32I, true, 32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_INT, GL_INT, false, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + AddRGBAFormat(&map, GL_RGBA32UI, true, 32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3, 0>, RequireES<3, 0>, NeverSupported); + + AddRGBAFormat(&map, GL_BGRA8_EXT, true, 8, 8, 8, 8, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888>, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported); + AddRGBAFormat(&map, GL_BGRA4_ANGLEX, true, 4, 4, 4, 4, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888>, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported); + AddRGBAFormat(&map, GL_BGR5_A1_ANGLEX, true, 5, 5, 5, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888>, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported); + + // Special format which is not really supported, so always false for all supports. + AddRGBAFormat(&map, GL_BGR565_ANGLEX, true, 5, 6, 5, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_NORMALIZED, false, NeverSupported, NeverSupported, NeverSupported); // Floating point renderability and filtering is provided by OES_texture_float and OES_texture_half_float - // | Internal format | | D |S | Format | Type | Comp | SRGB | Texture supported | Renderable | Filterable | - // | | | | | | | type | | | | | - map.insert(InternalFormatInfoPair(GL_R16F, RGBAFormat(16, 0, 0, 0, 0, GL_RED, GL_HALF_FLOAT, GL_FLOAT, false, HalfFloatSupportRG, HalfFloatRenderableSupportRG, RequireExt<&Extensions::textureHalfFloatLinear>))); - map.insert(InternalFormatInfoPair(GL_RG16F, RGBAFormat(16, 16, 0, 0, 0, GL_RG, GL_HALF_FLOAT, GL_FLOAT, false, HalfFloatSupportRG, HalfFloatRenderableSupportRG, RequireExt<&Extensions::textureHalfFloatLinear>))); - map.insert(InternalFormatInfoPair(GL_RGB16F, RGBAFormat(16, 16, 16, 0, 0, GL_RGB, GL_HALF_FLOAT, GL_FLOAT, false, HalfFloatSupport, HalfFloatRenderableSupport, RequireExt<&Extensions::textureHalfFloatLinear>))); - map.insert(InternalFormatInfoPair(GL_RGBA16F, RGBAFormat(16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT, GL_FLOAT, false, HalfFloatSupport, HalfFloatRenderableSupport, RequireExt<&Extensions::textureHalfFloatLinear>))); - map.insert(InternalFormatInfoPair(GL_R32F, RGBAFormat(32, 0, 0, 0, 0, GL_RED, GL_FLOAT, GL_FLOAT, false, FloatSupportRG, FloatRenderableSupportRG, RequireExt<&Extensions::textureFloatLinear> ))); - map.insert(InternalFormatInfoPair(GL_RG32F, RGBAFormat(32, 32, 0, 0, 0, GL_RG, GL_FLOAT, GL_FLOAT, false, FloatSupportRG, FloatRenderableSupportRG, RequireExt<&Extensions::textureFloatLinear> ))); - map.insert(InternalFormatInfoPair(GL_RGB32F, RGBAFormat(32, 32, 32, 0, 0, GL_RGB, GL_FLOAT, GL_FLOAT, false, FloatSupport, FloatRenderableSupport, RequireExt<&Extensions::textureFloatLinear> ))); - map.insert(InternalFormatInfoPair(GL_RGBA32F, RGBAFormat(32, 32, 32, 32, 0, GL_RGBA, GL_FLOAT, GL_FLOAT, false, FloatSupport, FloatRenderableSupport, RequireExt<&Extensions::textureFloatLinear> ))); + // | Internal format |sized| D |S | Format | Type | Comp | SRGB | Texture supported | Renderable | Filterable | + // | | | | | | | type | | | | | + AddRGBAFormat(&map, GL_R16F, true, 16, 0, 0, 0, 0, GL_RED, GL_HALF_FLOAT, GL_FLOAT, false, HalfFloatRGSupport, HalfFloatRGRenderableSupport, RequireESOrExt<3, 0, &Extensions::textureHalfFloatLinear>); + AddRGBAFormat(&map, GL_RG16F, true, 16, 16, 0, 0, 0, GL_RG, GL_HALF_FLOAT, GL_FLOAT, false, HalfFloatRGSupport, HalfFloatRGRenderableSupport, RequireESOrExt<3, 0, &Extensions::textureHalfFloatLinear>); + AddRGBAFormat(&map, GL_RGB16F, true, 16, 16, 16, 0, 0, GL_RGB, GL_HALF_FLOAT, GL_FLOAT, false, HalfFloatSupport, HalfFloatRGBRenderableSupport, RequireESOrExt<3, 0, &Extensions::textureHalfFloatLinear>); + AddRGBAFormat(&map, GL_RGBA16F, true, 16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT, GL_FLOAT, false, HalfFloatSupport, HalfFloatRGBARenderableSupport, RequireESOrExt<3, 0, &Extensions::textureHalfFloatLinear>); + AddRGBAFormat(&map, GL_R32F, true, 32, 0, 0, 0, 0, GL_RED, GL_FLOAT, GL_FLOAT, false, FloatRGSupport, FloatRGRenderableSupport, RequireExt<&Extensions::textureFloatLinear> ); + AddRGBAFormat(&map, GL_RG32F, true, 32, 32, 0, 0, 0, GL_RG, GL_FLOAT, GL_FLOAT, false, FloatRGSupport, FloatRGRenderableSupport, RequireExt<&Extensions::textureFloatLinear> ); + AddRGBAFormat(&map, GL_RGB32F, true, 32, 32, 32, 0, 0, GL_RGB, GL_FLOAT, GL_FLOAT, false, FloatSupport, FloatRGBRenderableSupport, RequireExt<&Extensions::textureFloatLinear> ); + AddRGBAFormat(&map, GL_RGBA32F, true, 32, 32, 32, 32, 0, GL_RGBA, GL_FLOAT, GL_FLOAT, false, FloatSupport, FloatRGBARenderableSupport, RequireExt<&Extensions::textureFloatLinear> ); // Depth stencil formats - // | Internal format | | D |S | X | Format | Type | Component type | Supported | Renderable | Filterable | - map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT16, DepthStencilFormat(16, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, RequireES<2>, RequireES<2>, RequireESOrExt<3, &Extensions::depthTextures>))); - map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT24, DepthStencilFormat(24, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireES<3>, RequireES<3>, RequireESOrExt<3, &Extensions::depthTextures>))); - map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32F, DepthStencilFormat(32, 0, 0, GL_DEPTH_COMPONENT, GL_FLOAT, GL_FLOAT, RequireES<3>, RequireES<3>, RequireESOrExt<3, &Extensions::depthTextures>))); - map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT32_OES, DepthStencilFormat(32, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireExtOrExt<&Extensions::depthTextures, &Extensions::depth32>, RequireExtOrExt<&Extensions::depthTextures, &Extensions::depth32>, AlwaysSupported ))); - map.insert(InternalFormatInfoPair(GL_DEPTH24_STENCIL8, DepthStencilFormat(24, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_NORMALIZED, RequireESOrExt<3, &Extensions::depthTextures>, RequireESOrExtOrExt<3, &Extensions::depthTextures, &Extensions::packedDepthStencil>, AlwaysSupported ))); - map.insert(InternalFormatInfoPair(GL_DEPTH32F_STENCIL8, DepthStencilFormat(32, 8, 24, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT, RequireES<3>, RequireES<3>, AlwaysSupported ))); + // | Internal format |sized| D |S | X | Format | Type | Component type | Supported | Renderable | Filterable | + AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT16, true, 16, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, RequireES<2, 0>, RequireES<2, 0>, RequireESOrExt<3, 0, &Extensions::depthTextures>); + AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT24, true, 24, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireES<3, 0>, RequireES<3, 0>, RequireESOrExt<3, 0, &Extensions::depthTextures>); + AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT32F, true, 32, 0, 0, GL_DEPTH_COMPONENT, GL_FLOAT, GL_FLOAT, RequireES<3, 0>, RequireES<3, 0>, RequireESOrExt<3, 0, &Extensions::depthTextures>); + AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT32_OES, true, 32, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireExtOrExt<&Extensions::depthTextures, &Extensions::depth32>, RequireExtOrExt<&Extensions::depthTextures, &Extensions::depth32>, AlwaysSupported ); + AddDepthStencilFormat(&map, GL_DEPTH24_STENCIL8, true, 24, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_NORMALIZED, RequireESOrExt<3, 0, &Extensions::depthTextures>, RequireESOrExtOrExt<3, 0, &Extensions::depthTextures, &Extensions::packedDepthStencil>, AlwaysSupported ); + AddDepthStencilFormat(&map, GL_DEPTH32F_STENCIL8, true, 32, 8, 24, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT, RequireES<3, 0>, RequireES<3, 0>, AlwaysSupported ); // STENCIL_INDEX8 is special-cased, see around the bottom of the list. // Luminance alpha formats - // | Internal format | | L | A | Format | Type | Component type | Supported | Renderable | Filterable | - map.insert(InternalFormatInfoPair(GL_ALPHA8_EXT, LUMAFormat( 0, 8, GL_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExt<&Extensions::textureStorage>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_LUMINANCE8_EXT, LUMAFormat( 8, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExt<&Extensions::textureStorage>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_ALPHA32F_EXT, LUMAFormat( 0, 32, GL_ALPHA, GL_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureFloat>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_LUMINANCE32F_EXT, LUMAFormat(32, 0, GL_LUMINANCE, GL_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureFloat>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_ALPHA16F_EXT, LUMAFormat( 0, 16, GL_ALPHA, GL_HALF_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_LUMINANCE16F_EXT, LUMAFormat(16, 0, GL_LUMINANCE, GL_HALF_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_LUMINANCE8_ALPHA8_EXT, LUMAFormat( 8, 8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExt<&Extensions::textureStorage>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA32F_EXT, LUMAFormat(32, 32, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureFloat>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA16F_EXT, LUMAFormat(16, 16, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, AlwaysSupported))); - - // Unsized formats - // | Internal format | | Format | Supported | Renderable | Filterable | - map.insert(InternalFormatInfoPair(GL_ALPHA, UnsizedFormat(GL_ALPHA, RequireES<2>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_LUMINANCE, UnsizedFormat(GL_LUMINANCE, RequireES<2>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_LUMINANCE_ALPHA, UnsizedFormat(GL_LUMINANCE_ALPHA, RequireES<2>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RED, UnsizedFormat(GL_RED, RequireESOrExt<3, &Extensions::textureRG>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RG, UnsizedFormat(GL_RG, RequireESOrExt<3, &Extensions::textureRG>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGB, UnsizedFormat(GL_RGB, RequireES<2>, RequireES<2>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RGBA, UnsizedFormat(GL_RGBA, RequireES<2>, RequireES<2>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_RED_INTEGER, UnsizedFormat(GL_RED_INTEGER, RequireES<3>, NeverSupported, NeverSupported ))); - map.insert(InternalFormatInfoPair(GL_RG_INTEGER, UnsizedFormat(GL_RG_INTEGER, RequireES<3>, NeverSupported, NeverSupported ))); - map.insert(InternalFormatInfoPair(GL_RGB_INTEGER, UnsizedFormat(GL_RGB_INTEGER, RequireES<3>, NeverSupported, NeverSupported ))); - map.insert(InternalFormatInfoPair(GL_RGBA_INTEGER, UnsizedFormat(GL_RGBA_INTEGER, RequireES<3>, NeverSupported, NeverSupported ))); - map.insert(InternalFormatInfoPair(GL_BGRA_EXT, UnsizedFormat(GL_BGRA_EXT, RequireExt<&Extensions::textureFormatBGRA8888>, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_DEPTH_COMPONENT, UnsizedFormat(GL_DEPTH_COMPONENT, RequireES<2>, RequireES<2>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_DEPTH_STENCIL, UnsizedFormat(GL_DEPTH_STENCIL, RequireESOrExt<3, &Extensions::packedDepthStencil>, RequireESOrExt<3, &Extensions::packedDepthStencil>, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_SRGB_EXT, UnsizedFormat(GL_RGB, RequireESOrExt<3, &Extensions::sRGB>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_SRGB_ALPHA_EXT, UnsizedFormat(GL_RGBA, RequireESOrExt<3, &Extensions::sRGB>, RequireESOrExt<3, &Extensions::sRGB>, AlwaysSupported))); + // | Internal format |sized| L | A | Format | Type | Component type | Supported | Renderable | Filterable | + AddLUMAFormat(&map, GL_ALPHA8_EXT, true, 0, 8, GL_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExt<&Extensions::textureStorage>, NeverSupported, AlwaysSupported); + AddLUMAFormat(&map, GL_LUMINANCE8_EXT, true, 8, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExt<&Extensions::textureStorage>, NeverSupported, AlwaysSupported); + AddLUMAFormat(&map, GL_LUMINANCE8_ALPHA8_EXT, true, 8, 8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExt<&Extensions::textureStorage>, NeverSupported, AlwaysSupported); + AddLUMAFormat(&map, GL_ALPHA16F_EXT, true, 0, 16, GL_ALPHA, GL_HALF_FLOAT_OES, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, RequireESOrExt<3, 0, &Extensions::textureHalfFloatLinear>); + AddLUMAFormat(&map, GL_LUMINANCE16F_EXT, true, 16, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, RequireESOrExt<3, 0, &Extensions::textureHalfFloatLinear>); + AddLUMAFormat(&map, GL_LUMINANCE_ALPHA16F_EXT, true, 16, 16, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureHalfFloat>, NeverSupported, RequireESOrExt<3, 0, &Extensions::textureHalfFloatLinear>); + AddLUMAFormat(&map, GL_ALPHA32F_EXT, true, 0, 32, GL_ALPHA, GL_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureFloat>, NeverSupported, RequireExt<&Extensions::textureFloatLinear>); + AddLUMAFormat(&map, GL_LUMINANCE32F_EXT, true, 32, 0, GL_LUMINANCE, GL_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureFloat>, NeverSupported, RequireExt<&Extensions::textureFloatLinear>); + AddLUMAFormat(&map, GL_LUMINANCE_ALPHA32F_EXT, true, 32, 32, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorage, &Extensions::textureFloat>, NeverSupported, RequireExt<&Extensions::textureFloatLinear>); // Compressed formats, From ES 3.0.1 spec, table 3.16 - // | Internal format | |W |H | BS |CC| Format | Type | SRGB | Supported | Renderable | Filterable | - map.insert(InternalFormatInfoPair(GL_COMPRESSED_R11_EAC, CompressedFormat(4, 4, 64, 1, GL_COMPRESSED_R11_EAC, GL_UNSIGNED_BYTE, false, RequireES<3>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_R11_EAC, CompressedFormat(4, 4, 64, 1, GL_COMPRESSED_SIGNED_R11_EAC, GL_UNSIGNED_BYTE, false, RequireES<3>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RG11_EAC, CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_RG11_EAC, GL_UNSIGNED_BYTE, false, RequireES<3>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_SIGNED_RG11_EAC, CompressedFormat(4, 4, 128, 2, GL_COMPRESSED_SIGNED_RG11_EAC, GL_UNSIGNED_BYTE, false, RequireES<3>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_ETC2, CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB8_ETC2, GL_UNSIGNED_BYTE, false, RequireES<3>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ETC2, CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_SRGB8_ETC2, GL_UNSIGNED_BYTE, true, RequireES<3>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, false, RequireES<3>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_UNSIGNED_BYTE, true, RequireES<3>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA8_ETC2_EAC, CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_UNSIGNED_BYTE, false, RequireES<3>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_UNSIGNED_BYTE, true, RequireES<3>, NeverSupported, AlwaysSupported))); + // | Internal format |W |H | BS |CC| Format | Type | SRGB | Supported | Renderable | Filterable | + AddCompressedFormat(&map, GL_COMPRESSED_R11_EAC, 4, 4, 64, 1, GL_RED, GL_UNSIGNED_BYTE, false, RequireES<3, 0>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SIGNED_R11_EAC, 4, 4, 64, 1, GL_RED, GL_UNSIGNED_BYTE, false, RequireES<3, 0>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RG11_EAC, 4, 4, 128, 2, GL_RG, GL_UNSIGNED_BYTE, false, RequireES<3, 0>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SIGNED_RG11_EAC, 4, 4, 128, 2, GL_RG, GL_UNSIGNED_BYTE, false, RequireES<3, 0>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGB8_ETC2, 4, 4, 64, 3, GL_RGB, GL_UNSIGNED_BYTE, false, RequireES<3, 0>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ETC2, 4, 4, 64, 3, GL_RGB, GL_UNSIGNED_BYTE, true, RequireES<3, 0>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, 4, 4, 64, 3, GL_RGB, GL_UNSIGNED_BYTE, false, RequireES<3, 0>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, 4, 4, 64, 3, GL_RGB, GL_UNSIGNED_BYTE, true, RequireES<3, 0>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA8_ETC2_EAC, 4, 4, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, false, RequireES<3, 0>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, 4, 4, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, true, RequireES<3, 0>, NeverSupported, AlwaysSupported); // From GL_EXT_texture_compression_dxt1 - // | Internal format | |W |H | BS |CC| Format | Type | SRGB | Supported | Renderable | Filterable | - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, CompressedFormat(4, 4, 64, 3, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT1>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, CompressedFormat(4, 4, 64, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT1>, NeverSupported, AlwaysSupported))); + // | Internal format |W |H | BS |CC| Format | Type | SRGB | Supported | Renderable | Filterable | + AddCompressedFormat(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 64, 3, GL_RGB, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT1>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 4, 4, 64, 4, GL_RGBA, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT1>, NeverSupported, AlwaysSupported); // From GL_ANGLE_texture_compression_dxt3 - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT5>, NeverSupported, AlwaysSupported))); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, 4, 4, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT3>, NeverSupported, AlwaysSupported); // From GL_ANGLE_texture_compression_dxt5 - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, CompressedFormat(4, 4, 128, 4, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT5>, NeverSupported, AlwaysSupported))); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, 4, 4, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::textureCompressionDXT5>, NeverSupported, AlwaysSupported); // From GL_OES_compressed_ETC1_RGB8_texture - map.insert(InternalFormatInfoPair(GL_ETC1_RGB8_OES, CompressedFormat(4, 4, 64, 3, GL_ETC1_RGB8_OES, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::compressedETC1RGB8Texture>, NeverSupported, AlwaysSupported))); + AddCompressedFormat(&map, GL_ETC1_RGB8_OES, 4, 4, 64, 3, GL_RGB, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::compressedETC1RGB8Texture>, NeverSupported, AlwaysSupported); + + // From GL_EXT_texture_compression_s3tc_srgb + // | Internal format |W |H | BS |CC| Format | Type | SRGB | Supported | Renderable | Filterable | + AddCompressedFormat(&map, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, 4, 4, 64, 3, GL_RGB, GL_UNSIGNED_BYTE, true, RequireExt<&Extensions::textureCompressionS3TCsRGB>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 4, 4, 64, 4, GL_RGBA, GL_UNSIGNED_BYTE, true, RequireExt<&Extensions::textureCompressionS3TCsRGB>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 4, 4, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, true, RequireExt<&Extensions::textureCompressionS3TCsRGB>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 4, 4, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, true, RequireExt<&Extensions::textureCompressionS3TCsRGB>, NeverSupported, AlwaysSupported); // From KHR_texture_compression_astc_hdr - // | Internal format | | W | H | BS |CC| Format | Type | SRGB | Supported | Renderable | Filterable | - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_4x4_KHR, CompressedFormat( 4, 4, 128, 4, GL_COMPRESSED_RGBA_ASTC_4x4_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_5x4_KHR, CompressedFormat( 5, 4, 128, 4, GL_COMPRESSED_RGBA_ASTC_5x4_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_5x5_KHR, CompressedFormat( 5, 5, 128, 4, GL_COMPRESSED_RGBA_ASTC_5x5_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_6x5_KHR, CompressedFormat( 6, 5, 128, 4, GL_COMPRESSED_RGBA_ASTC_6x5_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_6x6_KHR, CompressedFormat( 6, 6, 128, 4, GL_COMPRESSED_RGBA_ASTC_6x6_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_8x5_KHR, CompressedFormat( 8, 5, 128, 4, GL_COMPRESSED_RGBA_ASTC_8x5_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_8x6_KHR, CompressedFormat( 8, 6, 128, 4, GL_COMPRESSED_RGBA_ASTC_8x6_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_8x8_KHR, CompressedFormat( 8, 8, 128, 4, GL_COMPRESSED_RGBA_ASTC_8x8_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_10x5_KHR, CompressedFormat(10, 5, 128, 4, GL_COMPRESSED_RGBA_ASTC_10x5_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_10x6_KHR, CompressedFormat(10, 6, 128, 4, GL_COMPRESSED_RGBA_ASTC_10x6_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_10x8_KHR, CompressedFormat(10, 8, 128, 4, GL_COMPRESSED_RGBA_ASTC_10x8_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_10x10_KHR, CompressedFormat(10, 10, 128, 4, GL_COMPRESSED_RGBA_ASTC_10x10_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_12x10_KHR, CompressedFormat(12, 10, 128, 4, GL_COMPRESSED_RGBA_ASTC_12x10_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_RGBA_ASTC_12x12_KHR, CompressedFormat(12, 12, 128, 4, GL_COMPRESSED_RGBA_ASTC_12x12_KHR, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + // | Internal format | W | H | BS |CC| Format | Type | SRGB | Supported | Renderable | Filterable | + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_4x4_KHR, 4, 4, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_5x4_KHR, 5, 4, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_5x5_KHR, 5, 5, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_6x5_KHR, 6, 5, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_6x6_KHR, 6, 6, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_8x5_KHR, 8, 5, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_8x6_KHR, 8, 6, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_8x8_KHR, 8, 8, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_10x5_KHR, 10, 5, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_10x6_KHR, 10, 6, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_10x8_KHR, 10, 8, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_10x10_KHR, 10, 10, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_12x10_KHR, 12, 10, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_12x12_KHR, 12, 12, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, false, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, CompressedFormat( 4, 4, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, CompressedFormat( 5, 4, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, CompressedFormat( 5, 5, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, CompressedFormat( 6, 5, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, CompressedFormat( 6, 6, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, CompressedFormat( 8, 5, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, CompressedFormat( 8, 6, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, CompressedFormat( 8, 8, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, CompressedFormat(10, 5, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, CompressedFormat(10, 6, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, CompressedFormat(10, 8, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, CompressedFormat(10, 10, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, CompressedFormat(12, 10, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); - map.insert(InternalFormatInfoPair(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, CompressedFormat(12, 12, 128, 4, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported))); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, 4, 4, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, 5, 4, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, 5, 5, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, 6, 5, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, 6, 6, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, 8, 5, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, 8, 6, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, 8, 8, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, 10, 5, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, 10, 6, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, 10, 8, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, 10, 10, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, 12, 10, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, 12, 12, 128, 4, GL_RGBA, GL_UNSIGNED_BYTE, true, RequireExtOrExt<&Extensions::textureCompressionASTCHDR, &Extensions::textureCompressionASTCLDR>, NeverSupported, AlwaysSupported); // For STENCIL_INDEX8 we chose a normalized component type for the following reasons: // - Multisampled buffer are disallowed for non-normalized integer component types and we want to support it for STENCIL_INDEX8 // - All other stencil formats (all depth-stencil) are either float or normalized // - It affects only validation of internalformat in RenderbufferStorageMultisample. - // | Internal format | |D |S |X | Format | Type | Component type | Supported | Renderable | Filterable | - map.insert(InternalFormatInfoPair(GL_STENCIL_INDEX8, DepthStencilFormat(0, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireES<2>, RequireES<2>, NeverSupported))); + // | Internal format |sized|D |S |X | Format | Type | Component type | Supported | Renderable | Filterable | + AddDepthStencilFormat(&map, GL_STENCIL_INDEX8, true, 0, 8, 0, GL_STENCIL, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireES<2, 0>, RequireES<2, 0>, NeverSupported); // From GL_ANGLE_lossy_etc_decode - map.insert(InternalFormatInfoPair(GL_ETC1_RGB8_LOSSY_DECODE_ANGLE, CompressedFormat(4, 4, 64, 3, GL_ETC1_RGB8_OES, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::lossyETCDecode>, NeverSupported, AlwaysSupported))); + // | Internal format |W |H |BS |CC| Format | Type | SRGB | Supported | Renderable | Filterable | + AddCompressedFormat(&map, GL_ETC1_RGB8_LOSSY_DECODE_ANGLE, 4, 4, 64, 3, GL_RGB, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::lossyETCDecode>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE, 4, 4, 64, 3, GL_RGB, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::lossyETCDecode>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE, 4, 4, 64, 3, GL_RGB, GL_UNSIGNED_BYTE, true, RequireExt<&Extensions::lossyETCDecode>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE, 4, 4, 64, 3, GL_RGBA, GL_UNSIGNED_BYTE, false, RequireExt<&Extensions::lossyETCDecode>, NeverSupported, AlwaysSupported); + AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE, 4, 4, 64, 3, GL_RGBA, GL_UNSIGNED_BYTE, true, RequireExt<&Extensions::lossyETCDecode>, NeverSupported, AlwaysSupported); + // From GL_EXT_texture_norm16 + // | Internal format |sized| R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Renderable | Filterable | + AddRGBAFormat(&map, GL_R16_EXT, true, 16, 0, 0, 0, 0, GL_RED, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, RequireExt<&Extensions::textureNorm16>, AlwaysSupported); + AddRGBAFormat(&map, GL_R16_SNORM_EXT, true, 16, 0, 0, 0, 0, GL_RED, GL_SHORT, GL_SIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, NeverSupported, AlwaysSupported); + AddRGBAFormat(&map, GL_RG16_EXT, true, 16, 16, 0, 0, 0, GL_RG, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, RequireExt<&Extensions::textureNorm16>, AlwaysSupported); + AddRGBAFormat(&map, GL_RG16_SNORM_EXT, true, 16, 16, 0, 0, 0, GL_RG, GL_SHORT, GL_SIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, NeverSupported, AlwaysSupported); + AddRGBAFormat(&map, GL_RGB16_EXT, true, 16, 16, 16, 0, 0, GL_RGB, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, NeverSupported, AlwaysSupported); + AddRGBAFormat(&map, GL_RGB16_SNORM_EXT, true, 16, 16, 16, 0, 0, GL_RGB, GL_SHORT, GL_SIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, NeverSupported, AlwaysSupported); + AddRGBAFormat(&map, GL_RGBA16_EXT, true, 16, 16, 16, 16, 0, GL_RGBA, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, RequireExt<&Extensions::textureNorm16>, AlwaysSupported); + AddRGBAFormat(&map, GL_RGBA16_SNORM_EXT, true, 16, 16, 16, 16, 0, GL_RGBA, GL_SHORT, GL_SIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16>, NeverSupported, AlwaysSupported); + + // Unsized formats + // | Internal format |sized | R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Renderable | Filterable | + AddRGBAFormat(&map, GL_RED, false, 8, 0, 0, 0, 0, GL_RED, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureRG>, AlwaysSupported, AlwaysSupported); + AddRGBAFormat(&map, GL_RED, false, 8, 0, 0, 0, 0, GL_RED, GL_BYTE, GL_SIGNED_NORMALIZED, false, NeverSupported, NeverSupported, NeverSupported ); + AddRGBAFormat(&map, GL_RG, false, 8, 8, 0, 0, 0, GL_RG, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureRG>, AlwaysSupported, AlwaysSupported); + AddRGBAFormat(&map, GL_RG, false, 8, 8, 0, 0, 0, GL_RG, GL_BYTE, GL_SIGNED_NORMALIZED, false, NeverSupported, NeverSupported, NeverSupported ); + AddRGBAFormat(&map, GL_RGB, false, 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireES<2, 0>, AlwaysSupported, AlwaysSupported); + AddRGBAFormat(&map, GL_RGB, false, 5, 6, 5, 0, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_NORMALIZED, false, RequireES<2, 0>, RequireES<2, 0>, AlwaysSupported); + AddRGBAFormat(&map, GL_RGB, false, 8, 8, 8, 0, 0, GL_RGB, GL_BYTE, GL_SIGNED_NORMALIZED, false, NeverSupported, NeverSupported, NeverSupported ); + AddRGBAFormat(&map, GL_RGBA, false, 4, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_NORMALIZED, false, RequireES<2, 0>, RequireES<2, 0>, AlwaysSupported); + AddRGBAFormat(&map, GL_RGBA, false, 5, 5, 5, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_NORMALIZED, false, RequireES<2, 0>, RequireES<2, 0>, AlwaysSupported); + AddRGBAFormat(&map, GL_RGBA, false, 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireES<2, 0>, RequireES<2, 0>, AlwaysSupported); + AddRGBAFormat(&map, GL_RGBA, false, 10, 10, 10, 2, 0, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, RequireES<2, 0>, RequireES<2, 0>, AlwaysSupported); + AddRGBAFormat(&map, GL_RGBA, false, 8, 8, 8, 8, 0, GL_RGBA, GL_BYTE, GL_SIGNED_NORMALIZED, false, NeverSupported, NeverSupported, NeverSupported ); + AddRGBAFormat(&map, GL_SRGB, false, 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireExt<&Extensions::sRGB>, NeverSupported, AlwaysSupported); + AddRGBAFormat(&map, GL_SRGB_ALPHA_EXT, false, 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireExt<&Extensions::sRGB>, RequireExt<&Extensions::sRGB>, AlwaysSupported); + + AddRGBAFormat(&map, GL_BGRA_EXT, false, 8, 8, 8, 8, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888>, RequireExt<&Extensions::textureFormatBGRA8888>, AlwaysSupported); + + // Unsized integer formats + // |Internal format |sized | R | G | B | A |S | Format | Type | Component type | SRGB | Texture | Renderable | Filterable | + AddRGBAFormat(&map, GL_RED_INTEGER, false, 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_BYTE, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RED_INTEGER, false, 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RED_INTEGER, false, 16, 0, 0, 0, 0, GL_RED_INTEGER, GL_SHORT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RED_INTEGER, false, 16, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RED_INTEGER, false, 32, 0, 0, 0, 0, GL_RED_INTEGER, GL_INT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RED_INTEGER, false, 32, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RG_INTEGER, false, 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_BYTE, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RG_INTEGER, false, 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RG_INTEGER, false, 16, 16, 0, 0, 0, GL_RG_INTEGER, GL_SHORT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RG_INTEGER, false, 16, 16, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RG_INTEGER, false, 32, 32, 0, 0, 0, GL_RG_INTEGER, GL_INT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RG_INTEGER, false, 32, 32, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB_INTEGER, false, 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_BYTE, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB_INTEGER, false, 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB_INTEGER, false, 16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_SHORT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB_INTEGER, false, 16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB_INTEGER, false, 32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_INT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGB_INTEGER, false, 32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGBA_INTEGER, false, 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_BYTE, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGBA_INTEGER, false, 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGBA_INTEGER, false, 16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_SHORT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGBA_INTEGER, false, 16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGBA_INTEGER, false, 32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_INT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGBA_INTEGER, false, 32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + AddRGBAFormat(&map, GL_RGBA_INTEGER, false, 10, 10, 10, 2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported); + + // Unsized floating point formats + // |Internal format |sized | R | G | B | A |S | Format | Type | Comp | SRGB | Texture supported | Renderable | Filterable | + AddRGBAFormat(&map, GL_RED, false, 16, 0, 0, 0, 0, GL_RED, GL_HALF_FLOAT, GL_FLOAT, false, NeverSupported, NeverSupported, NeverSupported ); + AddRGBAFormat(&map, GL_RG, false, 16, 16, 0, 0, 0, GL_RG, GL_HALF_FLOAT, GL_FLOAT, false, NeverSupported, NeverSupported, NeverSupported ); + AddRGBAFormat(&map, GL_RGB, false, 16, 16, 16, 0, 0, GL_RGB, GL_HALF_FLOAT, GL_FLOAT, false, NeverSupported, NeverSupported, NeverSupported ); + AddRGBAFormat(&map, GL_RGBA, false, 16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT, GL_FLOAT, false, NeverSupported, NeverSupported, NeverSupported ); + AddRGBAFormat(&map, GL_RED, false, 16, 0, 0, 0, 0, GL_RED, GL_HALF_FLOAT_OES, GL_FLOAT, false, UnsizedHalfFloatOESRGSupport, UnsizedHalfFloatOESRGRenderableSupport, RequireESOrExt<3, 0, &Extensions::textureHalfFloatLinear>); + AddRGBAFormat(&map, GL_RG, false, 16, 16, 0, 0, 0, GL_RG, GL_HALF_FLOAT_OES, GL_FLOAT, false, UnsizedHalfFloatOESRGSupport, UnsizedHalfFloatOESRGRenderableSupport, RequireESOrExt<3, 0, &Extensions::textureHalfFloatLinear>); + AddRGBAFormat(&map, GL_RGB, false, 16, 16, 16, 0, 0, GL_RGB, GL_HALF_FLOAT_OES, GL_FLOAT, false, UnsizedHalfFloatOESSupport, UnsizedHalfFloatOESRenderableSupport, RequireESOrExt<3, 0, &Extensions::textureHalfFloatLinear>); + AddRGBAFormat(&map, GL_RGBA, false, 16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT_OES, GL_FLOAT, false, UnsizedHalfFloatOESSupport, UnsizedHalfFloatOESRenderableSupport, RequireESOrExt<3, 0, &Extensions::textureHalfFloatLinear>); + AddRGBAFormat(&map, GL_RED, false, 32, 0, 0, 0, 0, GL_RED, GL_FLOAT, GL_FLOAT, false, UnsizedFloatRGSupport, UnsizedFloatRGRenderableSupport, RequireExt<&Extensions::textureFloatLinear> ); + AddRGBAFormat(&map, GL_RG, false, 32, 32, 0, 0, 0, GL_RG, GL_FLOAT, GL_FLOAT, false, UnsizedFloatRGSupport, UnsizedFloatRGRenderableSupport, RequireExt<&Extensions::textureFloatLinear> ); + AddRGBAFormat(&map, GL_RGB, false, 32, 32, 32, 0, 0, GL_RGB, GL_FLOAT, GL_FLOAT, false, UnsizedFloatSupport, UnsizedFloatRGBRenderableSupport, RequireExt<&Extensions::textureFloatLinear> ); + AddRGBAFormat(&map, GL_RGB, false, 9, 9, 9, 0, 5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT, false, NeverSupported, NeverSupported, NeverSupported ); + AddRGBAFormat(&map, GL_RGB, false, 11, 11, 10, 0, 0, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_FLOAT, false, NeverSupported, NeverSupported, NeverSupported ); + AddRGBAFormat(&map, GL_RGBA, false, 32, 32, 32, 32, 0, GL_RGBA, GL_FLOAT, GL_FLOAT, false, UnsizedFloatSupport, UnsizedFloatRGBARenderableSupport, RequireExt<&Extensions::textureFloatLinear> ); + + // Unsized luminance alpha formats + // | Internal format |sized | L | A | Format | Type | Component type | Supported | Renderable | Filterable | + AddLUMAFormat(&map, GL_ALPHA, false, 0, 8, GL_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireES<2, 0>, NeverSupported, AlwaysSupported ); + AddLUMAFormat(&map, GL_LUMINANCE, false, 8, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireES<2, 0>, NeverSupported, AlwaysSupported ); + AddLUMAFormat(&map, GL_LUMINANCE_ALPHA, false, 8, 8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireES<2, 0>, NeverSupported, AlwaysSupported ); + AddLUMAFormat(&map, GL_ALPHA, false, 0, 16, GL_ALPHA, GL_HALF_FLOAT_OES, GL_FLOAT, RequireExt<&Extensions::textureHalfFloat>, NeverSupported, RequireExt<&Extensions::textureHalfFloatLinear>); + AddLUMAFormat(&map, GL_LUMINANCE, false, 16, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES, GL_FLOAT, RequireExt<&Extensions::textureHalfFloat>, NeverSupported, RequireExt<&Extensions::textureHalfFloatLinear>); + AddLUMAFormat(&map, GL_LUMINANCE_ALPHA ,false, 16, 16, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, GL_FLOAT, RequireExt<&Extensions::textureHalfFloat>, NeverSupported, RequireExt<&Extensions::textureHalfFloatLinear>); + AddLUMAFormat(&map, GL_ALPHA, false, 0, 32, GL_ALPHA, GL_FLOAT, GL_FLOAT, RequireExt<&Extensions::textureFloat>, NeverSupported, RequireExt<&Extensions::textureFloatLinear> ); + AddLUMAFormat(&map, GL_LUMINANCE, false, 32, 0, GL_LUMINANCE, GL_FLOAT, GL_FLOAT, RequireExt<&Extensions::textureFloat>, NeverSupported, RequireExt<&Extensions::textureFloatLinear> ); + AddLUMAFormat(&map, GL_LUMINANCE_ALPHA, false, 32, 32, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_FLOAT, RequireExt<&Extensions::textureFloat>, NeverSupported, RequireExt<&Extensions::textureFloatLinear> ); + + // Unsized depth stencil formats + // | Internal format |sized | D |S | X | Format | Type | Component type | Supported | Renderable | Filterable | + AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT, false, 16, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, RequireES<2, 0>, RequireES<2, 0>, AlwaysSupported); + AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT, false, 24, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireES<2, 0>, RequireES<2, 0>, AlwaysSupported); + AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT, false, 32, 0, 0, GL_DEPTH_COMPONENT, GL_FLOAT, GL_FLOAT, RequireES<2, 0>, RequireES<2, 0>, AlwaysSupported); + AddDepthStencilFormat(&map, GL_DEPTH_STENCIL, false, 24, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_NORMALIZED, RequireESOrExt<3, 0, &Extensions::packedDepthStencil>, RequireESOrExt<3, 0, &Extensions::packedDepthStencil>, AlwaysSupported); + AddDepthStencilFormat(&map, GL_DEPTH_STENCIL, false, 32, 8, 24, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT, RequireESOrExt<3, 0, &Extensions::packedDepthStencil>, RequireESOrExt<3, 0, &Extensions::packedDepthStencil>, AlwaysSupported); + AddDepthStencilFormat(&map, GL_STENCIL, false, 0, 8, 0, GL_STENCIL, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireES<2, 0>, RequireES<2, 0>, NeverSupported); // clang-format on return map; @@ -584,12 +940,18 @@ static FormatSet BuildAllSizedInternalFormatSet() { FormatSet result; - const InternalFormatInfoMap &formats = GetInternalFormatMap(); - for (InternalFormatInfoMap::const_iterator i = formats.begin(); i != formats.end(); i++) + for (const auto &internalFormat : GetInternalFormatMap()) { - if (i->second.pixelBytes > 0) + for (const auto &type : internalFormat.second) { - result.insert(i->first); + if (type.second.sized) + { + // TODO(jmadill): Fix this hack. + if (internalFormat.first == GL_BGR565_ANGLEX) + continue; + + result.insert(internalFormat.first); + } } } @@ -652,107 +1014,199 @@ const Type &GetTypeInfo(GLenum type) } } -const InternalFormat GetInternalFormatInfo(GLenum internalFormat) +const InternalFormat &GetSizedInternalFormatInfo(GLenum internalFormat) { + static const InternalFormat defaultInternalFormat; const InternalFormatInfoMap &formatMap = GetInternalFormatMap(); - InternalFormatInfoMap::const_iterator iter = formatMap.find(internalFormat); - if (iter != formatMap.end()) + auto iter = formatMap.find(internalFormat); + + // Sized internal formats only have one type per entry + if (iter == formatMap.end() || iter->second.size() != 1) { - return iter->second; - } - else - { - static const InternalFormat defaultInternalFormat; return defaultInternalFormat; } + + const InternalFormat &internalFormatInfo = iter->second.begin()->second; + if (!internalFormatInfo.sized) + { + return defaultInternalFormat; + } + + return internalFormatInfo; } -GLuint InternalFormat::computeRowPitch(GLenum formatType, GLsizei width, GLint alignment, GLint rowLength) const +const InternalFormat &GetInternalFormatInfo(GLenum internalFormat, GLenum type) { - ASSERT(alignment > 0 && isPow2(alignment)); - GLuint rowBytes; - if (rowLength > 0) + static const InternalFormat defaultInternalFormat; + const InternalFormatInfoMap &formatMap = GetInternalFormatMap(); + + auto internalFormatIter = formatMap.find(internalFormat); + if (internalFormatIter == formatMap.end()) { - ASSERT(!compressed); - rowBytes = pixelBytes * rowLength; + return defaultInternalFormat; } - else + + // If the internal format is sized, simply return it without the type check. + if (internalFormatIter->second.size() == 1 && internalFormatIter->second.begin()->second.sized) { - rowBytes = computeBlockSize(formatType, width, 1); + return internalFormatIter->second.begin()->second; } - return rx::roundUp(rowBytes, static_cast(alignment)); + + auto typeIter = internalFormatIter->second.find(type); + if (typeIter == internalFormatIter->second.end()) + { + return defaultInternalFormat; + } + + return typeIter->second; } -GLuint InternalFormat::computeDepthPitch(GLenum formatType, - GLsizei width, - GLsizei height, - GLint alignment, - GLint rowLength, - GLint imageHeight) const +GLuint InternalFormat::computePixelBytes(GLenum formatType) const { - GLuint rows; - if (imageHeight > 0) - { - rows = imageHeight; - } - else - { - rows = height; - } - return computeRowPitch(formatType, width, alignment, rowLength) * rows; + const auto &typeInfo = GetTypeInfo(formatType); + GLuint components = typeInfo.specialInterpretation ? 1u : componentCount; + return components * typeInfo.bytes; } -GLuint InternalFormat::computeBlockSize(GLenum formatType, GLsizei width, GLsizei height) const +ErrorOrResult InternalFormat::computeRowPitch(GLenum formatType, + GLsizei width, + GLint alignment, + GLint rowLength) const { + // Compressed images do not use pack/unpack parameters. if (compressed) { - GLsizei numBlocksWide = (width + compressedBlockWidth - 1) / compressedBlockWidth; - GLsizei numBlocksHight = (height + compressedBlockHeight - 1) / compressedBlockHeight; - return (pixelBytes * numBlocksWide * numBlocksHight); - } - else - { - const Type &typeInfo = GetTypeInfo(formatType); - if (typeInfo.specialInterpretation) - { - return typeInfo.bytes * width * height; - } - else - { - return componentCount * typeInfo.bytes * width * height; - } + ASSERT(rowLength == 0); + return computeCompressedImageSize(Extents(width, 1, 1)); } + + CheckedNumeric checkedWidth(rowLength > 0 ? rowLength : width); + CheckedNumeric checkedRowBytes = checkedWidth * computePixelBytes(formatType); + + ASSERT(alignment > 0 && isPow2(alignment)); + CheckedNumeric checkedAlignment(alignment); + auto aligned = rx::roundUp(checkedRowBytes, checkedAlignment); + ANGLE_TRY_CHECKED_MATH(aligned); + return aligned.ValueOrDie(); } -GLuint InternalFormat::computeSkipPixels(GLint rowPitch, - GLint depthPitch, - GLint skipImages, - GLint skipRows, - GLint skipPixels) const +ErrorOrResult InternalFormat::computeDepthPitch(GLsizei height, + GLint imageHeight, + GLuint rowPitch) const { - return skipImages * depthPitch + skipRows * rowPitch + skipPixels * pixelBytes; + GLuint rows = + (imageHeight > 0 ? static_cast(imageHeight) : static_cast(height)); + CheckedNumeric checkedRowPitch(rowPitch); + + auto depthPitch = checkedRowPitch * rows; + ANGLE_TRY_CHECKED_MATH(depthPitch); + return depthPitch.ValueOrDie(); } -GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type) +ErrorOrResult InternalFormat::computeDepthPitch(GLenum formatType, + GLsizei width, + GLsizei height, + GLint alignment, + GLint rowLength, + GLint imageHeight) const { - const InternalFormat& formatInfo = GetInternalFormatInfo(internalFormat); - if (formatInfo.pixelBytes > 0) + GLuint rowPitch = 0; + ANGLE_TRY_RESULT(computeRowPitch(formatType, width, alignment, rowLength), rowPitch); + return computeDepthPitch(height, imageHeight, rowPitch); +} + +ErrorOrResult InternalFormat::computeCompressedImageSize(const Extents &size) const +{ + CheckedNumeric checkedWidth(size.width); + CheckedNumeric checkedHeight(size.height); + CheckedNumeric checkedDepth(size.depth); + CheckedNumeric checkedBlockWidth(compressedBlockWidth); + CheckedNumeric checkedBlockHeight(compressedBlockHeight); + + ASSERT(compressed); + auto numBlocksWide = (checkedWidth + checkedBlockWidth - 1u) / checkedBlockWidth; + auto numBlocksHigh = (checkedHeight + checkedBlockHeight - 1u) / checkedBlockHeight; + auto bytes = numBlocksWide * numBlocksHigh * pixelBytes * checkedDepth; + ANGLE_TRY_CHECKED_MATH(bytes); + return bytes.ValueOrDie(); +} + +ErrorOrResult InternalFormat::computeSkipBytes(GLuint rowPitch, + GLuint depthPitch, + const PixelStoreStateBase &state, + bool is3D) const +{ + CheckedNumeric checkedRowPitch(rowPitch); + CheckedNumeric checkedDepthPitch(depthPitch); + CheckedNumeric checkedSkipImages(static_cast(state.skipImages)); + CheckedNumeric checkedSkipRows(static_cast(state.skipRows)); + CheckedNumeric checkedSkipPixels(static_cast(state.skipPixels)); + CheckedNumeric checkedPixelBytes(pixelBytes); + auto checkedSkipImagesBytes = checkedSkipImages * checkedDepthPitch; + if (!is3D) { - return internalFormat; + checkedSkipImagesBytes = 0; } - else + auto skipBytes = checkedSkipImagesBytes + checkedSkipRows * checkedRowPitch + + checkedSkipPixels * checkedPixelBytes; + ANGLE_TRY_CHECKED_MATH(skipBytes); + return skipBytes.ValueOrDie(); +} + +ErrorOrResult InternalFormat::computePackUnpackEndByte( + GLenum formatType, + const Extents &size, + const PixelStoreStateBase &state, + bool is3D) const +{ + GLuint rowPitch = 0; + ANGLE_TRY_RESULT(computeRowPitch(formatType, size.width, state.alignment, state.rowLength), + rowPitch); + + GLuint depthPitch = 0; + if (is3D) { - static const FormatMap formatMap = BuildFormatMap(); - FormatMap::const_iterator iter = formatMap.find(FormatTypePair(internalFormat, type)); - if (iter != formatMap.end()) + ANGLE_TRY_RESULT(computeDepthPitch(size.height, state.imageHeight, rowPitch), depthPitch); + } + + CheckedNumeric checkedCopyBytes = 0; + if (compressed) + { + ANGLE_TRY_RESULT(computeCompressedImageSize(size), checkedCopyBytes); + } + else if (size.height != 0 && (!is3D || size.depth != 0)) + { + CheckedNumeric bytes = computePixelBytes(formatType); + checkedCopyBytes += size.width * bytes; + + CheckedNumeric heightMinusOne = size.height - 1; + checkedCopyBytes += heightMinusOne * rowPitch; + + if (is3D) { - return iter->second; - } - else - { - return GL_NONE; + CheckedNumeric depthMinusOne = size.depth - 1; + checkedCopyBytes += depthMinusOne * depthPitch; } } + + CheckedNumeric checkedSkipBytes = 0; + ANGLE_TRY_RESULT(computeSkipBytes(rowPitch, depthPitch, state, is3D), checkedSkipBytes); + + CheckedNumeric endByte = checkedCopyBytes + checkedSkipBytes; + + ANGLE_TRY_CHECKED_MATH(endByte); + return endByte.ValueOrDie(); +} + +GLenum GetUnsizedFormat(GLenum internalFormat) +{ + auto sizedFormatInfo = GetSizedInternalFormatInfo(internalFormat); + if (sizedFormatInfo.internalFormat != GL_NONE) + { + return sizedFormatInfo.format; + } + + return internalFormat; } const FormatSet &GetAllSizedInternalFormats() @@ -1543,6 +1997,129 @@ const VertexFormat &GetVertexFormatFromType(VertexFormatType vertexFormatType) } } +size_t GetVertexFormatTypeSize(VertexFormatType vertexFormatType) +{ + switch (vertexFormatType) + { + case VERTEX_FORMAT_SBYTE1: + case VERTEX_FORMAT_SBYTE1_NORM: + case VERTEX_FORMAT_UBYTE1: + case VERTEX_FORMAT_UBYTE1_NORM: + case VERTEX_FORMAT_SBYTE1_INT: + case VERTEX_FORMAT_UBYTE1_INT: + return 1; + + case VERTEX_FORMAT_SBYTE2: + case VERTEX_FORMAT_SBYTE2_NORM: + case VERTEX_FORMAT_UBYTE2: + case VERTEX_FORMAT_UBYTE2_NORM: + case VERTEX_FORMAT_SBYTE2_INT: + case VERTEX_FORMAT_UBYTE2_INT: + case VERTEX_FORMAT_SSHORT1: + case VERTEX_FORMAT_SSHORT1_NORM: + case VERTEX_FORMAT_USHORT1: + case VERTEX_FORMAT_USHORT1_NORM: + case VERTEX_FORMAT_SSHORT1_INT: + case VERTEX_FORMAT_USHORT1_INT: + case VERTEX_FORMAT_HALF1: + return 2; + + case VERTEX_FORMAT_SBYTE3: + case VERTEX_FORMAT_SBYTE3_NORM: + case VERTEX_FORMAT_UBYTE3: + case VERTEX_FORMAT_UBYTE3_NORM: + case VERTEX_FORMAT_SBYTE3_INT: + case VERTEX_FORMAT_UBYTE3_INT: + return 3; + + case VERTEX_FORMAT_SBYTE4: + case VERTEX_FORMAT_SBYTE4_NORM: + case VERTEX_FORMAT_UBYTE4: + case VERTEX_FORMAT_UBYTE4_NORM: + case VERTEX_FORMAT_SBYTE4_INT: + case VERTEX_FORMAT_UBYTE4_INT: + case VERTEX_FORMAT_SSHORT2: + case VERTEX_FORMAT_SSHORT2_NORM: + case VERTEX_FORMAT_USHORT2: + case VERTEX_FORMAT_USHORT2_NORM: + case VERTEX_FORMAT_SSHORT2_INT: + case VERTEX_FORMAT_USHORT2_INT: + case VERTEX_FORMAT_SINT1: + case VERTEX_FORMAT_SINT1_NORM: + case VERTEX_FORMAT_UINT1: + case VERTEX_FORMAT_UINT1_NORM: + case VERTEX_FORMAT_SINT1_INT: + case VERTEX_FORMAT_UINT1_INT: + case VERTEX_FORMAT_HALF2: + case VERTEX_FORMAT_FIXED1: + case VERTEX_FORMAT_FLOAT1: + case VERTEX_FORMAT_SINT210: + case VERTEX_FORMAT_UINT210: + case VERTEX_FORMAT_SINT210_NORM: + case VERTEX_FORMAT_UINT210_NORM: + case VERTEX_FORMAT_SINT210_INT: + case VERTEX_FORMAT_UINT210_INT: + return 4; + + case VERTEX_FORMAT_SSHORT3: + case VERTEX_FORMAT_SSHORT3_NORM: + case VERTEX_FORMAT_USHORT3: + case VERTEX_FORMAT_USHORT3_NORM: + case VERTEX_FORMAT_SSHORT3_INT: + case VERTEX_FORMAT_USHORT3_INT: + case VERTEX_FORMAT_HALF3: + return 6; + + case VERTEX_FORMAT_SSHORT4: + case VERTEX_FORMAT_SSHORT4_NORM: + case VERTEX_FORMAT_USHORT4: + case VERTEX_FORMAT_USHORT4_NORM: + case VERTEX_FORMAT_SSHORT4_INT: + case VERTEX_FORMAT_USHORT4_INT: + case VERTEX_FORMAT_SINT2: + case VERTEX_FORMAT_SINT2_NORM: + case VERTEX_FORMAT_UINT2: + case VERTEX_FORMAT_UINT2_NORM: + case VERTEX_FORMAT_SINT2_INT: + case VERTEX_FORMAT_UINT2_INT: + case VERTEX_FORMAT_HALF4: + case VERTEX_FORMAT_FIXED2: + case VERTEX_FORMAT_FLOAT2: + return 8; + + case VERTEX_FORMAT_SINT3: + case VERTEX_FORMAT_SINT3_NORM: + case VERTEX_FORMAT_UINT3: + case VERTEX_FORMAT_UINT3_NORM: + case VERTEX_FORMAT_SINT3_INT: + case VERTEX_FORMAT_UINT3_INT: + case VERTEX_FORMAT_FIXED3: + case VERTEX_FORMAT_FLOAT3: + return 12; + + case VERTEX_FORMAT_SINT4: + case VERTEX_FORMAT_SINT4_NORM: + case VERTEX_FORMAT_UINT4: + case VERTEX_FORMAT_UINT4_NORM: + case VERTEX_FORMAT_SINT4_INT: + case VERTEX_FORMAT_UINT4_INT: + case VERTEX_FORMAT_FIXED4: + case VERTEX_FORMAT_FLOAT4: + return 16; + + case VERTEX_FORMAT_INVALID: + default: + UNREACHABLE(); + return 0; + } +} + +bool ValidES3InternalFormat(GLenum internalFormat) +{ + const InternalFormatInfoMap &formatMap = GetInternalFormatMap(); + return internalFormat != GL_NONE && formatMap.find(internalFormat) != formatMap.end(); +} + VertexFormat::VertexFormat(GLenum typeIn, GLboolean normalizedIn, GLuint componentsIn, bool pureIntegerIn) : type(typeIn), normalized(normalizedIn), diff --git a/src/3rdparty/angle/src/libANGLE/formatutils.h b/src/3rdparty/angle/src/libANGLE/formatutils.h index 2165e6badd..dbfe590846 100644 --- a/src/3rdparty/angle/src/libANGLE/formatutils.h +++ b/src/3rdparty/angle/src/libANGLE/formatutils.h @@ -9,16 +9,32 @@ #ifndef LIBANGLE_FORMATUTILS_H_ #define LIBANGLE_FORMATUTILS_H_ -#include "libANGLE/Caps.h" -#include "libANGLE/angletypes.h" +#include +#include +#include #include "angle_gl.h" - -#include -#include +#include "libANGLE/Caps.h" +#include "libANGLE/Error.h" +#include "libANGLE/Version.h" +#include "libANGLE/angletypes.h" namespace gl { +struct VertexAttribute; + +struct FormatType final +{ + FormatType(); + FormatType(GLenum format_, GLenum type_); + FormatType(const FormatType &other) = default; + FormatType &operator=(const FormatType &other) = default; + + bool operator<(const FormatType &other) const; + + GLenum format; + GLenum type; +}; struct Type { @@ -30,9 +46,58 @@ struct Type }; const Type &GetTypeInfo(GLenum type); +// Information about an OpenGL internal format. Can be keyed on the internalFormat and type +// members. struct InternalFormat { InternalFormat(); + InternalFormat(const InternalFormat &other); + + GLuint computePixelBytes(GLenum formatType) const; + + ErrorOrResult computeRowPitch(GLenum formatType, + GLsizei width, + GLint alignment, + GLint rowLength) const; + ErrorOrResult computeDepthPitch(GLsizei height, + GLint imageHeight, + GLuint rowPitch) const; + ErrorOrResult computeDepthPitch(GLenum formatType, + GLsizei width, + GLsizei height, + GLint alignment, + GLint rowLength, + GLint imageHeight) const; + + ErrorOrResult computeCompressedImageSize(const Extents &size) const; + + ErrorOrResult computeSkipBytes(GLuint rowPitch, + GLuint depthPitch, + const PixelStoreStateBase &state, + bool is3D) const; + + ErrorOrResult computePackUnpackEndByte(GLenum formatType, + const Extents &size, + const PixelStoreStateBase &state, + bool is3D) const; + + bool isLUMA() const; + GLenum getReadPixelsFormat() const; + GLenum getReadPixelsType(const Version &version) const; + + // Return true if the format is a required renderbuffer format in the given version of the core + // spec. Note that it isn't always clear whether all the rules that apply to core required + // renderbuffer formats also apply to additional formats added by extensions. Because of this + // extension formats are conservatively not included. + bool isRequiredRenderbufferFormat(const Version &version) const; + + bool operator==(const InternalFormat &other) const; + bool operator!=(const InternalFormat &other) const; + + GLenum internalFormat; + + bool sized; + GLenum sizedInternalFormat; GLuint redBits; GLuint greenBits; @@ -60,28 +125,45 @@ struct InternalFormat GLenum componentType; GLenum colorEncoding; - typedef bool (*SupportCheckFunction)(GLuint, const Extensions &); + typedef bool (*SupportCheckFunction)(const Version &, const Extensions &); SupportCheckFunction textureSupport; SupportCheckFunction renderSupport; SupportCheckFunction filterSupport; - - GLuint computeRowPitch(GLenum formatType, GLsizei width, GLint alignment, GLint rowLength) const; - GLuint computeDepthPitch(GLenum formatType, - GLsizei width, - GLsizei height, - GLint alignment, - GLint rowLength, - GLint imageHeight) const; - GLuint computeBlockSize(GLenum formatType, GLsizei width, GLsizei height) const; - GLuint computeSkipPixels(GLint rowPitch, - GLint depthPitch, - GLint skipImages, - GLint skipRows, - GLint skipPixels) const; }; -const InternalFormat GetInternalFormatInfo(GLenum internalFormat); -GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type); +// A "Format" wraps an InternalFormat struct, querying it from either a sized internal format or +// unsized internal format and type. +// TODO(geofflang): Remove this, it doesn't add any more information than the InternalFormat object. +struct Format +{ + // Sized types only. + explicit Format(GLenum internalFormat); + + // Sized or unsized types. + explicit Format(const InternalFormat &internalFormat); + Format(GLenum internalFormat, GLenum type); + + Format(const Format &other); + Format &operator=(const Format &other); + + bool valid() const; + + static Format Invalid(); + static bool SameSized(const Format &a, const Format &b); + static bool EquivalentForBlit(const Format &a, const Format &b); + + friend std::ostream &operator<<(std::ostream &os, const Format &fmt); + + // This is the sized info. + const InternalFormat *info; +}; + +const InternalFormat &GetSizedInternalFormatInfo(GLenum internalFormat); +const InternalFormat &GetInternalFormatInfo(GLenum internalFormat, GLenum type); + +// Strip sizing information from an internal format. Doesn't necessarily validate that the internal +// format is valid. +GLenum GetUnsizedFormat(GLenum internalFormat); typedef std::set FormatSet; const FormatSet &GetAllSizedInternalFormats(); @@ -212,9 +294,9 @@ enum VertexFormatType VERTEX_FORMAT_UINT210_INT, }; -typedef std::vector InputLayout; +typedef std::vector InputLayout; -struct VertexFormat : angle::NonCopyable +struct VertexFormat : private angle::NonCopyable { VertexFormat(GLenum typeIn, GLboolean normalizedIn, GLuint componentsIn, bool pureIntegerIn); @@ -228,6 +310,19 @@ VertexFormatType GetVertexFormatType(GLenum type, GLboolean normalized, GLuint c VertexFormatType GetVertexFormatType(const VertexAttribute &attrib); VertexFormatType GetVertexFormatType(const VertexAttribute &attrib, GLenum currentValueType); const VertexFormat &GetVertexFormatFromType(VertexFormatType vertexFormatType); +size_t GetVertexFormatTypeSize(VertexFormatType vertexFormatType); + +// Check if an internal format is ever valid in ES3. Makes no checks about support for a specific +// context. +bool ValidES3InternalFormat(GLenum internalFormat); + +// Implemented in format_map_autogen.cpp +bool ValidES3Format(GLenum format); +bool ValidES3Type(GLenum type); +bool ValidES3FormatCombination(GLenum format, GLenum type, GLenum internalFormat); + +// Implemented in es3_copy_conversion_table_autogen.cpp +bool ValidES3CopyConversion(GLenum textureFormat, GLenum framebufferFormat); } // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/histogram_macros.h b/src/3rdparty/angle/src/libANGLE/histogram_macros.h index d1c952a6bd..fb428b46d2 100644 --- a/src/3rdparty/angle/src/libANGLE/histogram_macros.h +++ b/src/3rdparty/angle/src/libANGLE/histogram_macros.h @@ -41,18 +41,19 @@ #define ANGLE_HISTOGRAM_COUNTS_10000(name, sample) \ ANGLE_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 10000, 50) -#define ANGLE_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) \ - ANGLEPlatformCurrent()->histogramCustomCounts(\ - name, sample, min, max, bucket_count) +#define ANGLE_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) \ + ANGLEPlatformCurrent()->histogramCustomCounts(ANGLEPlatformCurrent(), name, sample, min, max, \ + bucket_count) #define ANGLE_HISTOGRAM_PERCENTAGE(name, under_one_hundred) \ ANGLE_HISTOGRAM_ENUMERATION(name, under_one_hundred, 101) #define ANGLE_HISTOGRAM_BOOLEAN(name, sample) \ - ANGLEPlatformCurrent()->histogramBoolean(name, sample) + ANGLEPlatformCurrent()->histogramBoolean(ANGLEPlatformCurrent(), name, sample) -#define ANGLE_HISTOGRAM_ENUMERATION(name, sample, boundary_value) \ - ANGLEPlatformCurrent()->histogramEnumeration(name, sample, boundary_value) +#define ANGLE_HISTOGRAM_ENUMERATION(name, sample, boundary_value) \ + ANGLEPlatformCurrent()->histogramEnumeration(ANGLEPlatformCurrent(), name, sample, \ + boundary_value) #define ANGLE_HISTOGRAM_MEMORY_KB(name, sample) ANGLE_HISTOGRAM_CUSTOM_COUNTS( \ name, sample, 1000, 500000, 50) @@ -61,7 +62,7 @@ name, sample, 1, 1000, 50) #define ANGLE_HISTOGRAM_SPARSE_SLOWLY(name, sample) \ - ANGLEPlatformCurrent()->histogramSparse(name, sample) + ANGLEPlatformCurrent()->histogramSparse(ANGLEPlatformCurrent(), name, sample) // Scoped class which logs its time on this earth as a UMA statistic. This is // recommended for when you want a histogram which measures the time it takes @@ -79,29 +80,33 @@ #define SCOPED_ANGLE_HISTOGRAM_TIMER_EXPANDER(name, is_long, key) \ SCOPED_ANGLE_HISTOGRAM_TIMER_UNIQUE(name, is_long, key) -#define SCOPED_ANGLE_HISTOGRAM_TIMER_UNIQUE(name, is_long, key) \ - class ScopedHistogramTimer##key \ - { \ - public: \ - ScopedHistogramTimer##key() : constructed_(ANGLEPlatformCurrent()->currentTime()) {} \ - ~ScopedHistogramTimer##key() \ - { \ - if (constructed_ == 0) \ - return; \ - double elapsed = ANGLEPlatformCurrent()->currentTime() - constructed_; \ - int elapsedMS = static_cast(elapsed * 1000.0); \ - if (is_long) \ - { \ - ANGLE_HISTOGRAM_LONG_TIMES_100(name, elapsedMS); \ - } \ - else \ - { \ - ANGLE_HISTOGRAM_TIMES(name, elapsedMS); \ - } \ - } \ - \ - private: \ - double constructed_; \ +#define SCOPED_ANGLE_HISTOGRAM_TIMER_UNIQUE(name, is_long, key) \ + class ScopedHistogramTimer##key \ + { \ + public: \ + ScopedHistogramTimer##key() \ + : constructed_(ANGLEPlatformCurrent()->currentTime(ANGLEPlatformCurrent())) \ + { \ + } \ + ~ScopedHistogramTimer##key() \ + { \ + if (constructed_ == 0) \ + return; \ + auto *platform = ANGLEPlatformCurrent(); \ + double elapsed = platform->currentTime(platform) - constructed_; \ + int elapsedMS = static_cast(elapsed * 1000.0); \ + if (is_long) \ + { \ + ANGLE_HISTOGRAM_LONG_TIMES_100(name, elapsedMS); \ + } \ + else \ + { \ + ANGLE_HISTOGRAM_TIMES(name, elapsedMS); \ + } \ + } \ + \ + private: \ + double constructed_; \ } scoped_histogram_timer_##key -#endif // BASE_METRICS_HISTOGRAM_MACROS_H_ +#endif // LIBANGLE_HISTOGRAM_MACROS_H_ diff --git a/src/3rdparty/angle/src/libANGLE/packed_gl_enums.json b/src/3rdparty/angle/src/libANGLE/packed_gl_enums.json new file mode 100644 index 0000000000..7e77de2f36 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/packed_gl_enums.json @@ -0,0 +1,35 @@ +{ + "BufferBinding": + { + "Array": "GL_ARRAY_BUFFER", + "AtomicCounter": "GL_ATOMIC_COUNTER_BUFFER", + "CopyRead": "GL_COPY_READ_BUFFER", + "CopyWrite": "GL_COPY_WRITE_BUFFER", + "DispatchIndirect": "GL_DISPATCH_INDIRECT_BUFFER", + "DrawIndirect": "GL_DRAW_INDIRECT_BUFFER", + "ElementArray": "GL_ELEMENT_ARRAY_BUFFER", + "PixelPack": "GL_PIXEL_PACK_BUFFER", + "PixelUnpack": "GL_PIXEL_UNPACK_BUFFER", + "ShaderStorage": "GL_SHADER_STORAGE_BUFFER", + "TransformFeedback": "GL_TRANSFORM_FEEDBACK_BUFFER", + "Uniform": "GL_UNIFORM_BUFFER" + }, + "BufferUsage": + { + "DynamicCopy": "GL_DYNAMIC_COPY", + "DynamicDraw": "GL_DYNAMIC_DRAW", + "DynamicRead": "GL_DYNAMIC_READ", + "StaticCopy": "GL_STATIC_COPY", + "StaticDraw": "GL_STATIC_DRAW", + "StaticRead": "GL_STATIC_READ", + "StreamCopy": "GL_STREAM_COPY", + "StreamDraw": "GL_STREAM_DRAW", + "StreamRead": "GL_STREAM_READ" + }, + "CullFaceMode": + { + "Back": "GL_BACK", + "Front": "GL_FRONT", + "FrontAndBack": "GL_FRONT_AND_BACK" + } +} diff --git a/src/3rdparty/angle/src/libANGLE/params.cpp b/src/3rdparty/angle/src/libANGLE/params.cpp new file mode 100644 index 0000000000..a89d87e0a9 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/params.cpp @@ -0,0 +1,68 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// params: +// Parameter wrapper structs for OpenGL ES. These helpers cache re-used values +// in entry point routines. + +#include "libANGLE/params.h" + +#include "common/utilities.h" +#include "libANGLE/Context.h" +#include "libANGLE/VertexArray.h" + +namespace gl +{ + +// static +constexpr ParamTypeInfo ParamsBase::TypeInfo; +constexpr ParamTypeInfo HasIndexRange::TypeInfo; + +HasIndexRange::HasIndexRange() + : ParamsBase(nullptr), mContext(nullptr), mCount(0), mType(GL_NONE), mIndices(nullptr) +{ +} + +HasIndexRange::HasIndexRange(Context *context, GLsizei count, GLenum type, const void *indices) + : ParamsBase(context), mContext(context), mCount(count), mType(type), mIndices(indices) +{ +} + +const Optional &HasIndexRange::getIndexRange() const +{ + if (mIndexRange.valid() || !mContext) + { + return mIndexRange; + } + + const State &state = mContext->getGLState(); + + const gl::VertexArray *vao = state.getVertexArray(); + gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get(); + + if (elementArrayBuffer) + { + uintptr_t offset = reinterpret_cast(mIndices); + IndexRange indexRange; + Error error = + elementArrayBuffer->getIndexRange(mContext, mType, static_cast(offset), mCount, + state.isPrimitiveRestartEnabled(), &indexRange); + if (error.isError()) + { + mContext->handleError(error); + return mIndexRange; + } + + mIndexRange = indexRange; + } + else + { + mIndexRange = ComputeIndexRange(mType, mIndices, mCount, state.isPrimitiveRestartEnabled()); + } + + return mIndexRange; +} + +} // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/params.h b/src/3rdparty/angle/src/libANGLE/params.h new file mode 100644 index 0000000000..27dba640ff --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/params.h @@ -0,0 +1,228 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// params: +// Parameter wrapper structs for OpenGL ES. These helpers cache re-used values +// in entry point routines. + +#ifndef LIBANGLE_PARAMS_H_ +#define LIBANGLE_PARAMS_H_ + +#include "angle_gl.h" +#include "common/Optional.h" +#include "common/angleutils.h" +#include "common/mathutil.h" +#include "libANGLE/entry_points_enum_autogen.h" + +namespace gl +{ +class Context; + +template +struct EntryPointParam; + +template +using EntryPointParamType = typename EntryPointParam::Type; + +class ParamTypeInfo +{ + public: + constexpr ParamTypeInfo(const char *selfClass, const ParamTypeInfo *parentType) + : mSelfClass(selfClass), mParentTypeInfo(parentType) + { + } + + constexpr bool hasDynamicType(const ParamTypeInfo &typeInfo) const + { + return mSelfClass == typeInfo.mSelfClass || + (mParentTypeInfo && mParentTypeInfo->hasDynamicType(typeInfo)); + } + + constexpr bool isValid() const { return mSelfClass != nullptr; } + + private: + const char *mSelfClass; + const ParamTypeInfo *mParentTypeInfo; +}; + +#define ANGLE_PARAM_TYPE_INFO(NAME, BASENAME) \ + static constexpr ParamTypeInfo TypeInfo = {#NAME, &BASENAME::TypeInfo} + +class ParamsBase : angle::NonCopyable +{ + public: + ParamsBase(Context *context, ...){}; + + template + static void Factory(EntryPointParamType *objBuffer, ArgsT... args); + + static constexpr ParamTypeInfo TypeInfo = {nullptr, nullptr}; +}; + +// static +template +ANGLE_INLINE void ParamsBase::Factory(EntryPointParamType *objBuffer, ArgsT... args) +{ + new (objBuffer) EntryPointParamType(args...); +} + +class HasIndexRange : public ParamsBase +{ + public: + // Dummy placeholder that can't generate an index range. + HasIndexRange(); + HasIndexRange(Context *context, GLsizei count, GLenum type, const void *indices); + + template + static void Factory(HasIndexRange *objBuffer, ArgsT... args); + + const Optional &getIndexRange() const; + + ANGLE_PARAM_TYPE_INFO(HasIndexRange, ParamsBase); + + private: + Context *mContext; + GLsizei mCount; + GLenum mType; + const GLvoid *mIndices; + mutable Optional mIndexRange; +}; + +// Entry point funcs essentially re-map different entry point parameter arrays into +// the format the parameter type class expects. For example, for HasIndexRange, for the +// various indexed draw calls, they drop parameters that aren't useful and re-arrange +// the rest. +#define ANGLE_ENTRY_POINT_FUNC(NAME, CLASS, ...) \ + \ +template<> struct EntryPointParam \ + { \ + using Type = CLASS; \ + }; \ + \ +template<> inline void CLASS::Factory(__VA_ARGS__) + +ANGLE_ENTRY_POINT_FUNC(DrawElements, + HasIndexRange, + HasIndexRange *objBuffer, + Context *context, + GLenum /*mode*/, + GLsizei count, + GLenum type, + const void *indices) +{ + return ParamsBase::Factory(objBuffer, context, count, type, indices); +} + +ANGLE_ENTRY_POINT_FUNC(DrawElementsInstanced, + HasIndexRange, + HasIndexRange *objBuffer, + Context *context, + GLenum /*mode*/, + GLsizei count, + GLenum type, + const void *indices, + GLsizei /*instanceCount*/) +{ + return ParamsBase::Factory(objBuffer, context, count, type, + indices); +} + +ANGLE_ENTRY_POINT_FUNC(DrawElementsInstancedANGLE, + HasIndexRange, + HasIndexRange *objBuffer, + Context *context, + GLenum /*mode*/, + GLsizei count, + GLenum type, + const void *indices, + GLsizei /*instanceCount*/) +{ + return ParamsBase::Factory(objBuffer, context, count, + type, indices); +} + +ANGLE_ENTRY_POINT_FUNC(DrawRangeElements, + HasIndexRange, + HasIndexRange *objBuffer, + Context *context, + GLenum /*mode*/, + GLuint /*start*/, + GLuint /*end*/, + GLsizei count, + GLenum type, + const void *indices) +{ + return ParamsBase::Factory(objBuffer, context, count, type, + indices); +} + +#undef ANGLE_ENTRY_POINT_FUNC + +template +struct EntryPointParam +{ + using Type = ParamsBase; +}; + +// A template struct for determining the default value to return for each entry point. +template +struct DefaultReturnValue; + +// Default return values for each basic return type. +template +struct DefaultReturnValue +{ + static constexpr GLint kValue = -1; +}; + +// This doubles as the GLenum return value. +template +struct DefaultReturnValue +{ + static constexpr GLuint kValue = 0; +}; + +template +struct DefaultReturnValue +{ + static constexpr GLboolean kValue = GL_FALSE; +}; + +// Catch-all rules for pointer types. +template +struct DefaultReturnValue +{ + static constexpr const PointerType *kValue = nullptr; +}; + +template +struct DefaultReturnValue +{ + static constexpr PointerType *kValue = nullptr; +}; + +// Overloaded to return invalid index +template <> +struct DefaultReturnValue +{ + static constexpr GLuint kValue = GL_INVALID_INDEX; +}; + +// Specialized enum error value. +template <> +struct DefaultReturnValue +{ + static constexpr GLenum kValue = GL_WAIT_FAILED; +}; + +template +constexpr ANGLE_INLINE ReturnType GetDefaultReturnValue() +{ + return DefaultReturnValue::kValue; +} + +} // namespace gl + +#endif // LIBANGLE_PARAMS_H_ diff --git a/src/3rdparty/angle/src/libANGLE/queryconversions.cpp b/src/3rdparty/angle/src/libANGLE/queryconversions.cpp index 3a6059a89c..78d219365e 100644 --- a/src/3rdparty/angle/src/libANGLE/queryconversions.cpp +++ b/src/3rdparty/angle/src/libANGLE/queryconversions.cpp @@ -24,18 +24,9 @@ GLint64 ExpandFloatToInteger(GLfloat value) return static_cast((static_cast(0xFFFFFFFFULL) * value - 1.0) / 2.0); } -template -QueryT ClampToQueryRange(GLint64 value) -{ - const GLint64 min = static_cast(std::numeric_limits::min()); - const GLint64 max = static_cast(std::numeric_limits::max()); - return static_cast(clamp(value, min, max)); -} - template -QueryT CastStateValueToInt(GLenum pname, NativeT value) +QueryT CastFromStateValueToInt(GLenum pname, NativeT value) { - GLenum queryType = GLTypeToGLenum::value; GLenum nativeType = GLTypeToGLenum::value; if (nativeType == GL_FLOAT) @@ -43,37 +34,68 @@ QueryT CastStateValueToInt(GLenum pname, NativeT value) // RGBA color values and DepthRangeF values are converted to integer using Equation 2.4 from Table 4.5 if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR) { - return ClampToQueryRange(ExpandFloatToInteger(static_cast(value))); + return clampCast(ExpandFloatToInteger(static_cast(value))); } else { - return gl::iround(static_cast(value)); + return clampCast(std::round(value)); } } - // Clamp 64-bit int values when casting to int - if (nativeType == GL_INT_64_ANGLEX && queryType == GL_INT) - { - GLint64 minIntValue = static_cast(std::numeric_limits::min()); - GLint64 maxIntValue = static_cast(std::numeric_limits::max()); - GLint64 clampedValue = std::max(std::min(static_cast(value), maxIntValue), minIntValue); - return static_cast(clampedValue); - } - - return static_cast(value); + return clampCast(value); } +template +NativeT CastQueryValueToInt(GLenum pname, QueryT value) +{ + GLenum queryType = GLTypeToGLenum::value; + + if (queryType == GL_FLOAT) + { + return static_cast(std::round(value)); + } + + return static_cast(value); +} + +} // anonymous namespace + +// ES 3.10 Section 2.2.2 +// When querying bitmasks(such as SAMPLE_MASK_VALUE or STENCIL_WRITEMASK) with GetIntegerv, the +// mask value is treated as a signed integer, so that mask values with the high bit set will not be +// clamped when returned as signed integers. +GLint CastMaskValue(const Context *context, GLuint value) +{ + return (context->getClientVersion() >= Version(3, 1) ? static_cast(value) + : clampCast(value)); +} + +template +QueryT CastFromGLintStateValue(GLenum pname, InternalT value) +{ + return CastFromStateValue(pname, clampCast(value)); +} + +template GLfloat CastFromGLintStateValue(GLenum pname, GLenum value); +template GLint CastFromGLintStateValue(GLenum pname, GLenum value); +template GLint64 CastFromGLintStateValue(GLenum pname, GLenum value); +template GLuint CastFromGLintStateValue(GLenum pname, GLenum value); +template GLfloat CastFromGLintStateValue(GLenum pname, bool value); +template GLuint CastFromGLintStateValue(GLenum pname, bool value); +template GLint CastFromGLintStateValue(GLenum pname, bool value); + template -QueryT CastStateValue(GLenum pname, NativeT value) +QueryT CastFromStateValue(GLenum pname, NativeT value) { GLenum queryType = GLTypeToGLenum::value; switch (queryType) { case GL_INT: - return CastStateValueToInt(pname, value); case GL_INT_64_ANGLEX: - return CastStateValueToInt(pname, value); + case GL_UNSIGNED_INT: + case GL_UINT_64_ANGLEX: + return CastFromStateValueToInt(pname, value); case GL_FLOAT: return static_cast(value); case GL_BOOL: @@ -83,19 +105,50 @@ QueryT CastStateValue(GLenum pname, NativeT value) return 0; } } +template GLint CastFromStateValue(GLenum pname, GLint value); +template GLint CastFromStateValue(GLenum pname, GLint64 value); +template GLint64 CastFromStateValue(GLenum pname, GLint value); +template GLint64 CastFromStateValue(GLenum pname, GLint64 value); +template GLfloat CastFromStateValue(GLenum pname, GLint value); +template GLfloat CastFromStateValue(GLenum pname, GLfloat value); +template GLint CastFromStateValue(GLenum pname, GLfloat value); +template GLuint CastFromStateValue(GLenum pname, GLint value); +template GLuint CastFromStateValue(GLenum pname, GLuint value); +template GLint CastFromStateValue(GLenum pname, GLboolean value); +template GLint64 CastFromStateValue(GLenum pname, GLboolean value); +template GLint CastFromStateValue(GLenum pname, GLuint value); +template GLint64 CastFromStateValue(GLenum pname, GLuint value); +template GLuint64 CastFromStateValue(GLenum pname, GLuint value); -} // anonymous namespace +template +NativeT CastQueryValueTo(GLenum pname, QueryT value) +{ + GLenum nativeType = GLTypeToGLenum::value; -template <> -GLenum GLTypeToGLenum::value = GL_INT; -template <> -GLenum GLTypeToGLenum::value = GL_UNSIGNED_INT; -template <> -GLenum GLTypeToGLenum::value = GL_BOOL; -template <> -GLenum GLTypeToGLenum::value = GL_INT_64_ANGLEX; -template <> -GLenum GLTypeToGLenum::value = GL_FLOAT; + switch (nativeType) + { + case GL_INT: + case GL_INT_64_ANGLEX: + case GL_UNSIGNED_INT: + case GL_UINT_64_ANGLEX: + return CastQueryValueToInt(pname, value); + case GL_FLOAT: + return static_cast(value); + case GL_BOOL: + return static_cast(value == static_cast(0) ? GL_FALSE : GL_TRUE); + default: + UNREACHABLE(); + return 0; + } +} + +template GLint CastQueryValueTo(GLenum pname, GLfloat value); +template GLboolean CastQueryValueTo(GLenum pname, GLint value); +template GLint CastQueryValueTo(GLenum pname, GLint value); +template GLfloat CastQueryValueTo(GLenum pname, GLint value); +template GLfloat CastQueryValueTo(GLenum pname, GLfloat value); +template GLuint CastQueryValueTo(GLenum pname, GLint value); +template GLuint CastQueryValueTo(GLenum pname, GLfloat value); template void CastStateValues(Context *context, GLenum nativeType, GLenum pname, @@ -104,17 +157,17 @@ void CastStateValues(Context *context, GLenum nativeType, GLenum pname, if (nativeType == GL_INT) { std::vector intParams(numParams, 0); - context->getIntegerv(pname, intParams.data()); + context->getIntegervImpl(pname, intParams.data()); for (unsigned int i = 0; i < numParams; ++i) { - outParams[i] = CastStateValue(pname, intParams[i]); + outParams[i] = CastFromStateValue(pname, intParams[i]); } } else if (nativeType == GL_BOOL) { std::vector boolParams(numParams, GL_FALSE); - context->getBooleanv(pname, boolParams.data()); + context->getBooleanvImpl(pname, boolParams.data()); for (unsigned int i = 0; i < numParams; ++i) { @@ -124,11 +177,11 @@ void CastStateValues(Context *context, GLenum nativeType, GLenum pname, else if (nativeType == GL_FLOAT) { std::vector floatParams(numParams, 0.0f); - context->getFloatv(pname, floatParams.data()); + context->getFloatvImpl(pname, floatParams.data()); for (unsigned int i = 0; i < numParams; ++i) { - outParams[i] = CastStateValue(pname, floatParams[i]); + outParams[i] = CastFromStateValue(pname, floatParams[i]); } } else if (nativeType == GL_INT_64_ANGLEX) @@ -138,7 +191,7 @@ void CastStateValues(Context *context, GLenum nativeType, GLenum pname, for (unsigned int i = 0; i < numParams; ++i) { - outParams[i] = CastStateValue(pname, int64Params[i]); + outParams[i] = CastFromStateValue(pname, int64Params[i]); } } else UNREACHABLE(); @@ -146,7 +199,7 @@ void CastStateValues(Context *context, GLenum nativeType, GLenum pname, // Explicit template instantiation (how we export template functions in different files) // The calls below will make CastStateValues successfully link with the GL state query types -// The GL state query API types are: bool, int, uint, float, int64 +// The GL state query API types are: bool, int, uint, float, int64, uint64 template void CastStateValues(Context *, GLenum, GLenum, unsigned int, GLboolean *); template void CastStateValues(Context *, GLenum, GLenum, unsigned int, GLint *); @@ -154,4 +207,77 @@ template void CastStateValues(Context *, GLenum, GLenum, unsigned int, G template void CastStateValues(Context *, GLenum, GLenum, unsigned int, GLfloat *); template void CastStateValues(Context *, GLenum, GLenum, unsigned int, GLint64 *); +template +void CastIndexedStateValues(Context *context, + GLenum nativeType, + GLenum pname, + GLuint index, + unsigned int numParams, + QueryT *outParams) +{ + if (nativeType == GL_INT) + { + std::vector intParams(numParams, 0); + context->getIntegeri_v(pname, index, intParams.data()); + + for (unsigned int i = 0; i < numParams; ++i) + { + outParams[i] = CastFromStateValue(pname, intParams[i]); + } + } + else if (nativeType == GL_BOOL) + { + std::vector boolParams(numParams, GL_FALSE); + context->getBooleani_v(pname, index, boolParams.data()); + + for (unsigned int i = 0; i < numParams; ++i) + { + outParams[i] = + (boolParams[i] == GL_FALSE ? static_cast(0) : static_cast(1)); + } + } + else if (nativeType == GL_INT_64_ANGLEX) + { + std::vector int64Params(numParams, 0); + context->getInteger64i_v(pname, index, int64Params.data()); + + for (unsigned int i = 0; i < numParams; ++i) + { + outParams[i] = CastFromStateValue(pname, int64Params[i]); + } + } + else + UNREACHABLE(); +} + +template void CastIndexedStateValues(Context *, + GLenum, + GLenum, + GLuint index, + unsigned int, + GLboolean *); +template void CastIndexedStateValues(Context *, + GLenum, + GLenum, + GLuint index, + unsigned int, + GLint *); +template void CastIndexedStateValues(Context *, + GLenum, + GLenum, + GLuint index, + unsigned int, + GLuint *); +template void CastIndexedStateValues(Context *, + GLenum, + GLenum, + GLuint index, + unsigned int, + GLfloat *); +template void CastIndexedStateValues(Context *, + GLenum, + GLenum, + GLuint index, + unsigned int, + GLint64 *); } diff --git a/src/3rdparty/angle/src/libANGLE/queryconversions.h b/src/3rdparty/angle/src/libANGLE/queryconversions.h index e0fdbe17e0..805f36cf02 100644 --- a/src/3rdparty/angle/src/libANGLE/queryconversions.h +++ b/src/3rdparty/angle/src/libANGLE/queryconversions.h @@ -18,19 +18,100 @@ class Context; // Helper class for converting a GL type to a GLenum: // We can't use CastStateValueEnum generally, because of GLboolean + GLubyte overlap. -// We restrict our use to CastStateValue, where it eliminates duplicate parameters. +// We restrict our use to CastFromStateValue and CastQueryValueTo, where it eliminates +// duplicate parameters. template struct GLTypeToGLenum { - static GLenum value; + // static constexpr GLenum value; }; -// The GL state query API types are: bool, int, uint, float, int64 +template <> +struct GLTypeToGLenum +{ + static constexpr GLenum value = GL_INT; +}; +template <> +struct GLTypeToGLenum +{ + static constexpr GLenum value = GL_UNSIGNED_INT; +}; +template <> +struct GLTypeToGLenum +{ + static constexpr GLenum value = GL_BOOL; +}; +template <> +struct GLTypeToGLenum +{ + static constexpr GLenum value = GL_INT_64_ANGLEX; +}; +template <> +struct GLTypeToGLenum +{ + static constexpr GLenum value = GL_UINT_64_ANGLEX; +}; +template <> +struct GLTypeToGLenum +{ + static constexpr GLenum value = GL_FLOAT; +}; + +GLint CastMaskValue(const Context *context, GLuint value); + +template +QueryT CastFromGLintStateValue(GLenum pname, InternalT value); + +template +QueryT CastFromStateValue(GLenum pname, NativeT value); + +template +NativeT CastQueryValueTo(GLenum pname, QueryT value); + +template +GLenum ConvertToGLenum(GLenum pname, ParamType param) +{ + return static_cast(CastQueryValueTo(pname, param)); +} + +template +GLenum ConvertToGLenum(ParamType param) +{ + return ConvertToGLenum(GL_NONE, param); +} + +template +GLenum ConvertToGLint(ParamType param) +{ + return CastQueryValueTo(GL_NONE, param); +} + +template +bool ConvertToBool(ParamType param) +{ + return param != GL_FALSE; +} + +template +GLboolean ConvertToGLBoolean(ParamType param) +{ + return param ? GL_TRUE : GL_FALSE; +} + +// The GL state query API types are: bool, int, uint, float, int64, uint64 template void CastStateValues(Context *context, GLenum nativeType, GLenum pname, unsigned int numParams, QueryT *outParams); +// The GL state query API types are: bool, int, uint, float, int64, uint64 +template +void CastIndexedStateValues(Context *context, + GLenum nativeType, + GLenum pname, + GLuint index, + unsigned int numParams, + QueryT *outParams); } #endif // LIBANGLE_QUERY_CONVERSIONS_H_ diff --git a/src/3rdparty/angle/src/libANGLE/queryutils.cpp b/src/3rdparty/angle/src/libANGLE/queryutils.cpp new file mode 100644 index 0000000000..16a989c688 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/queryutils.cpp @@ -0,0 +1,1916 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// queryutils.cpp: Utilities for querying values from GL objects + +#include "libANGLE/queryutils.h" + +#include "common/utilities.h" + +#include "libANGLE/Buffer.h" +#include "libANGLE/Config.h" +#include "libANGLE/Context.h" +#include "libANGLE/Fence.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/Program.h" +#include "libANGLE/Renderbuffer.h" +#include "libANGLE/Sampler.h" +#include "libANGLE/Shader.h" +#include "libANGLE/Surface.h" +#include "libANGLE/Texture.h" +#include "libANGLE/Uniform.h" +#include "libANGLE/VertexAttribute.h" +#include "libANGLE/queryconversions.h" + +namespace gl +{ + +namespace +{ + +template +void QueryTexLevelParameterBase(const Texture *texture, + GLenum target, + GLint level, + GLenum pname, + ParamType *params) +{ + ASSERT(texture != nullptr); + const InternalFormat *info = texture->getTextureState().getImageDesc(target, level).format.info; + + switch (pname) + { + case GL_TEXTURE_RED_TYPE: + *params = CastFromGLintStateValue( + pname, info->redBits ? info->componentType : GL_NONE); + break; + case GL_TEXTURE_GREEN_TYPE: + *params = CastFromGLintStateValue( + pname, info->greenBits ? info->componentType : GL_NONE); + break; + case GL_TEXTURE_BLUE_TYPE: + *params = CastFromGLintStateValue( + pname, info->blueBits ? info->componentType : GL_NONE); + break; + case GL_TEXTURE_ALPHA_TYPE: + *params = CastFromGLintStateValue( + pname, info->alphaBits ? info->componentType : GL_NONE); + break; + case GL_TEXTURE_DEPTH_TYPE: + *params = CastFromGLintStateValue( + pname, info->depthBits ? info->componentType : GL_NONE); + break; + case GL_TEXTURE_RED_SIZE: + *params = CastFromGLintStateValue(pname, info->redBits); + break; + case GL_TEXTURE_GREEN_SIZE: + *params = CastFromGLintStateValue(pname, info->greenBits); + break; + case GL_TEXTURE_BLUE_SIZE: + *params = CastFromGLintStateValue(pname, info->blueBits); + break; + case GL_TEXTURE_ALPHA_SIZE: + *params = CastFromGLintStateValue(pname, info->alphaBits); + break; + case GL_TEXTURE_DEPTH_SIZE: + *params = CastFromGLintStateValue(pname, info->depthBits); + break; + case GL_TEXTURE_STENCIL_SIZE: + *params = CastFromGLintStateValue(pname, info->stencilBits); + break; + case GL_TEXTURE_SHARED_SIZE: + *params = CastFromGLintStateValue(pname, info->sharedBits); + break; + case GL_TEXTURE_INTERNAL_FORMAT: + *params = CastFromGLintStateValue( + pname, info->internalFormat ? info->internalFormat : GL_RGBA); + break; + case GL_TEXTURE_WIDTH: + *params = CastFromGLintStateValue( + pname, static_cast(texture->getWidth(target, level))); + break; + case GL_TEXTURE_HEIGHT: + *params = CastFromGLintStateValue( + pname, static_cast(texture->getHeight(target, level))); + break; + case GL_TEXTURE_DEPTH: + *params = CastFromGLintStateValue( + pname, static_cast(texture->getDepth(target, level))); + break; + case GL_TEXTURE_SAMPLES: + *params = CastFromStateValue(pname, texture->getSamples(target, level)); + break; + case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS: + *params = CastFromStateValue( + pname, static_cast(texture->getFixedSampleLocations(target, level))); + break; + case GL_TEXTURE_COMPRESSED: + *params = CastFromStateValue(pname, static_cast(info->compressed)); + break; + default: + UNREACHABLE(); + break; + } +} + +template +void QueryTexParameterBase(const Texture *texture, GLenum pname, ParamType *params) +{ + ASSERT(texture != nullptr); + + switch (pname) + { + case GL_TEXTURE_MAG_FILTER: + *params = CastFromGLintStateValue(pname, texture->getMagFilter()); + break; + case GL_TEXTURE_MIN_FILTER: + *params = CastFromGLintStateValue(pname, texture->getMinFilter()); + break; + case GL_TEXTURE_WRAP_S: + *params = CastFromGLintStateValue(pname, texture->getWrapS()); + break; + case GL_TEXTURE_WRAP_T: + *params = CastFromGLintStateValue(pname, texture->getWrapT()); + break; + case GL_TEXTURE_WRAP_R: + *params = CastFromGLintStateValue(pname, texture->getWrapR()); + break; + case GL_TEXTURE_IMMUTABLE_FORMAT: + *params = CastFromGLintStateValue(pname, texture->getImmutableFormat()); + break; + case GL_TEXTURE_IMMUTABLE_LEVELS: + *params = CastFromGLintStateValue(pname, texture->getImmutableLevels()); + break; + case GL_TEXTURE_USAGE_ANGLE: + *params = CastFromGLintStateValue(pname, texture->getUsage()); + break; + case GL_TEXTURE_MAX_ANISOTROPY_EXT: + *params = CastFromStateValue(pname, texture->getMaxAnisotropy()); + break; + case GL_TEXTURE_SWIZZLE_R: + *params = CastFromGLintStateValue(pname, texture->getSwizzleRed()); + break; + case GL_TEXTURE_SWIZZLE_G: + *params = CastFromGLintStateValue(pname, texture->getSwizzleGreen()); + break; + case GL_TEXTURE_SWIZZLE_B: + *params = CastFromGLintStateValue(pname, texture->getSwizzleBlue()); + break; + case GL_TEXTURE_SWIZZLE_A: + *params = CastFromGLintStateValue(pname, texture->getSwizzleAlpha()); + break; + case GL_TEXTURE_BASE_LEVEL: + *params = CastFromGLintStateValue(pname, texture->getBaseLevel()); + break; + case GL_TEXTURE_MAX_LEVEL: + *params = CastFromGLintStateValue(pname, texture->getMaxLevel()); + break; + case GL_TEXTURE_MIN_LOD: + *params = CastFromStateValue(pname, texture->getSamplerState().minLod); + break; + case GL_TEXTURE_MAX_LOD: + *params = CastFromStateValue(pname, texture->getSamplerState().maxLod); + break; + case GL_TEXTURE_COMPARE_MODE: + *params = CastFromGLintStateValue(pname, texture->getCompareMode()); + break; + case GL_TEXTURE_COMPARE_FUNC: + *params = CastFromGLintStateValue(pname, texture->getCompareFunc()); + break; + case GL_TEXTURE_SRGB_DECODE_EXT: + *params = CastFromGLintStateValue(pname, texture->getSRGBDecode()); + break; + default: + UNREACHABLE(); + break; + } +} + +template +void SetTexParameterBase(Context *context, Texture *texture, GLenum pname, const ParamType *params) +{ + ASSERT(texture != nullptr); + + switch (pname) + { + case GL_TEXTURE_WRAP_S: + texture->setWrapS(ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_WRAP_T: + texture->setWrapT(ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_WRAP_R: + texture->setWrapR(ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_MIN_FILTER: + texture->setMinFilter(ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_MAG_FILTER: + texture->setMagFilter(ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_USAGE_ANGLE: + texture->setUsage(ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_MAX_ANISOTROPY_EXT: + texture->setMaxAnisotropy(CastQueryValueTo(pname, params[0])); + break; + case GL_TEXTURE_COMPARE_MODE: + texture->setCompareMode(ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_COMPARE_FUNC: + texture->setCompareFunc(ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_SWIZZLE_R: + texture->setSwizzleRed(ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_SWIZZLE_G: + texture->setSwizzleGreen(ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_SWIZZLE_B: + texture->setSwizzleBlue(ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_SWIZZLE_A: + texture->setSwizzleAlpha(ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_BASE_LEVEL: + { + context->handleError(texture->setBaseLevel( + context, clampCast(CastQueryValueTo(pname, params[0])))); + break; + } + case GL_TEXTURE_MAX_LEVEL: + texture->setMaxLevel(clampCast(CastQueryValueTo(pname, params[0]))); + break; + case GL_TEXTURE_MIN_LOD: + texture->setMinLod(CastQueryValueTo(pname, params[0])); + break; + case GL_TEXTURE_MAX_LOD: + texture->setMaxLod(CastQueryValueTo(pname, params[0])); + break; + case GL_DEPTH_STENCIL_TEXTURE_MODE: + texture->setDepthStencilTextureMode(ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_SRGB_DECODE_EXT: + texture->setSRGBDecode(ConvertToGLenum(pname, params[0])); + break; + default: + UNREACHABLE(); + break; + } +} + +template +void QuerySamplerParameterBase(const Sampler *sampler, GLenum pname, ParamType *params) +{ + switch (pname) + { + case GL_TEXTURE_MIN_FILTER: + *params = CastFromGLintStateValue(pname, sampler->getMinFilter()); + break; + case GL_TEXTURE_MAG_FILTER: + *params = CastFromGLintStateValue(pname, sampler->getMagFilter()); + break; + case GL_TEXTURE_WRAP_S: + *params = CastFromGLintStateValue(pname, sampler->getWrapS()); + break; + case GL_TEXTURE_WRAP_T: + *params = CastFromGLintStateValue(pname, sampler->getWrapT()); + break; + case GL_TEXTURE_WRAP_R: + *params = CastFromGLintStateValue(pname, sampler->getWrapR()); + break; + case GL_TEXTURE_MAX_ANISOTROPY_EXT: + *params = CastFromStateValue(pname, sampler->getMaxAnisotropy()); + break; + case GL_TEXTURE_MIN_LOD: + *params = CastFromStateValue(pname, sampler->getMinLod()); + break; + case GL_TEXTURE_MAX_LOD: + *params = CastFromStateValue(pname, sampler->getMaxLod()); + break; + case GL_TEXTURE_COMPARE_MODE: + *params = CastFromGLintStateValue(pname, sampler->getCompareMode()); + break; + case GL_TEXTURE_COMPARE_FUNC: + *params = CastFromGLintStateValue(pname, sampler->getCompareFunc()); + break; + case GL_TEXTURE_SRGB_DECODE_EXT: + *params = CastFromGLintStateValue(pname, sampler->getSRGBDecode()); + break; + default: + UNREACHABLE(); + break; + } +} + +template +void SetSamplerParameterBase(Sampler *sampler, GLenum pname, const ParamType *params) +{ + switch (pname) + { + case GL_TEXTURE_WRAP_S: + sampler->setWrapS(ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_WRAP_T: + sampler->setWrapT(ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_WRAP_R: + sampler->setWrapR(ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_MIN_FILTER: + sampler->setMinFilter(ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_MAG_FILTER: + sampler->setMagFilter(ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_MAX_ANISOTROPY_EXT: + sampler->setMaxAnisotropy(CastQueryValueTo(pname, params[0])); + break; + case GL_TEXTURE_COMPARE_MODE: + sampler->setCompareMode(ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_COMPARE_FUNC: + sampler->setCompareFunc(ConvertToGLenum(pname, params[0])); + break; + case GL_TEXTURE_MIN_LOD: + sampler->setMinLod(CastQueryValueTo(pname, params[0])); + break; + case GL_TEXTURE_MAX_LOD: + sampler->setMaxLod(CastQueryValueTo(pname, params[0])); + break; + case GL_TEXTURE_SRGB_DECODE_EXT: + sampler->setSRGBDecode(ConvertToGLenum(pname, params[0])); + break; + default: + UNREACHABLE(); + break; + } +} + +// Warning: you should ensure binding really matches attrib.bindingIndex before using this function. +template +void QueryVertexAttribBase(const VertexAttribute &attrib, + const VertexBinding &binding, + const CurrentDataType (¤tValueData)[CurrentValueCount], + GLenum pname, + ParamType *params) +{ + switch (pname) + { + case GL_CURRENT_VERTEX_ATTRIB: + for (size_t i = 0; i < CurrentValueCount; ++i) + { + params[i] = CastFromStateValue(pname, currentValueData[i]); + } + break; + case GL_VERTEX_ATTRIB_ARRAY_ENABLED: + *params = CastFromStateValue(pname, static_cast(attrib.enabled)); + break; + case GL_VERTEX_ATTRIB_ARRAY_SIZE: + *params = CastFromGLintStateValue(pname, attrib.size); + break; + case GL_VERTEX_ATTRIB_ARRAY_STRIDE: + *params = CastFromGLintStateValue(pname, attrib.vertexAttribArrayStride); + break; + case GL_VERTEX_ATTRIB_ARRAY_TYPE: + *params = CastFromGLintStateValue(pname, attrib.type); + break; + case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: + *params = CastFromStateValue(pname, static_cast(attrib.normalized)); + break; + case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: + *params = CastFromGLintStateValue(pname, binding.getBuffer().id()); + break; + case GL_VERTEX_ATTRIB_ARRAY_DIVISOR: + *params = CastFromGLintStateValue(pname, binding.getDivisor()); + break; + case GL_VERTEX_ATTRIB_ARRAY_INTEGER: + *params = CastFromGLintStateValue(pname, attrib.pureInteger); + break; + case GL_VERTEX_ATTRIB_BINDING: + *params = CastFromGLintStateValue(pname, attrib.bindingIndex); + break; + case GL_VERTEX_ATTRIB_RELATIVE_OFFSET: + *params = CastFromGLintStateValue(pname, attrib.relativeOffset); + break; + default: + UNREACHABLE(); + break; + } +} + +template +void QueryBufferParameterBase(const Buffer *buffer, GLenum pname, ParamType *params) +{ + ASSERT(buffer != nullptr); + + switch (pname) + { + case GL_BUFFER_USAGE: + *params = CastFromGLintStateValue(pname, ToGLenum(buffer->getUsage())); + break; + case GL_BUFFER_SIZE: + *params = CastFromStateValue(pname, buffer->getSize()); + break; + case GL_BUFFER_ACCESS_FLAGS: + *params = CastFromGLintStateValue(pname, buffer->getAccessFlags()); + break; + case GL_BUFFER_ACCESS_OES: + *params = CastFromGLintStateValue(pname, buffer->getAccess()); + break; + case GL_BUFFER_MAPPED: + *params = CastFromStateValue(pname, buffer->isMapped()); + break; + case GL_BUFFER_MAP_OFFSET: + *params = CastFromStateValue(pname, buffer->getMapOffset()); + break; + case GL_BUFFER_MAP_LENGTH: + *params = CastFromStateValue(pname, buffer->getMapLength()); + break; + default: + UNREACHABLE(); + break; + } +} + +GLint GetCommonVariableProperty(const sh::ShaderVariable &var, GLenum prop) +{ + switch (prop) + { + case GL_TYPE: + return clampCast(var.type); + + case GL_ARRAY_SIZE: + // Queryable variables are guaranteed not to be arrays of arrays or arrays of structs, + // see GLES 3.1 spec section 7.3.1.1 page 77. + return clampCast(var.getBasicTypeElementCount()); + + case GL_NAME_LENGTH: + // ES31 spec p84: This counts the terminating null char. + return clampCast(var.name.size() + 1u); + + default: + UNREACHABLE(); + return GL_INVALID_VALUE; + } +} + +GLint GetInputResourceProperty(const Program *program, GLuint index, GLenum prop) +{ + const auto &attribute = program->getInputResource(index); + switch (prop) + { + case GL_TYPE: + case GL_ARRAY_SIZE: + case GL_NAME_LENGTH: + return GetCommonVariableProperty(attribute, prop); + + case GL_LOCATION: + return program->getAttributeLocation(attribute.name); + + case GL_REFERENCED_BY_VERTEX_SHADER: + return 1; + + case GL_REFERENCED_BY_FRAGMENT_SHADER: + case GL_REFERENCED_BY_COMPUTE_SHADER: + return 0; + + default: + UNREACHABLE(); + return GL_INVALID_VALUE; + } +} + +GLint GetOutputResourceProperty(const Program *program, GLuint index, const GLenum prop) +{ + const auto &outputVariable = program->getOutputResource(index); + switch (prop) + { + case GL_TYPE: + case GL_ARRAY_SIZE: + case GL_NAME_LENGTH: + return GetCommonVariableProperty(outputVariable, prop); + + case GL_LOCATION: + return program->getFragDataLocation(outputVariable.name); + + case GL_REFERENCED_BY_VERTEX_SHADER: + return 0; + + case GL_REFERENCED_BY_FRAGMENT_SHADER: + return 1; + + case GL_REFERENCED_BY_COMPUTE_SHADER: + return 0; + + default: + UNREACHABLE(); + return GL_INVALID_VALUE; + } +} + +GLint QueryProgramInterfaceActiveResources(const Program *program, GLenum programInterface) +{ + switch (programInterface) + { + case GL_PROGRAM_INPUT: + return clampCast(program->getAttributes().size()); + + case GL_PROGRAM_OUTPUT: + return clampCast(program->getState().getOutputVariables().size()); + + case GL_UNIFORM: + return clampCast(program->getState().getUniforms().size()); + + case GL_UNIFORM_BLOCK: + return clampCast(program->getState().getUniformBlocks().size()); + + case GL_ATOMIC_COUNTER_BUFFER: + return clampCast(program->getState().getAtomicCounterBuffers().size()); + + case GL_BUFFER_VARIABLE: + return clampCast(program->getState().getBufferVariables().size()); + + case GL_SHADER_STORAGE_BLOCK: + return clampCast(program->getState().getShaderStorageBlocks().size()); + + // TODO(jie.a.chen@intel.com): more interfaces. + case GL_TRANSFORM_FEEDBACK_VARYING: + UNIMPLEMENTED(); + return 0; + + default: + UNREACHABLE(); + return 0; + } +} + +template +GLint FindMaxSize(const std::vector &resources, M member) +{ + GLint max = 0; + for (const T &resource : resources) + { + max = std::max(max, clampCast((resource.*member).size())); + } + return max; +} + +GLint QueryProgramInterfaceMaxNameLength(const Program *program, GLenum programInterface) +{ + GLint maxNameLength = 0; + switch (programInterface) + { + case GL_PROGRAM_INPUT: + maxNameLength = FindMaxSize(program->getAttributes(), &sh::Attribute::name); + break; + + case GL_PROGRAM_OUTPUT: + maxNameLength = + FindMaxSize(program->getState().getOutputVariables(), &sh::OutputVariable::name); + break; + + case GL_UNIFORM: + maxNameLength = FindMaxSize(program->getState().getUniforms(), &LinkedUniform::name); + break; + + case GL_UNIFORM_BLOCK: + maxNameLength = + FindMaxSize(program->getState().getUniformBlocks(), &InterfaceBlock::name); + break; + + case GL_BUFFER_VARIABLE: + maxNameLength = + FindMaxSize(program->getState().getBufferVariables(), &BufferVariable::name); + break; + + case GL_SHADER_STORAGE_BLOCK: + maxNameLength = + FindMaxSize(program->getState().getShaderStorageBlocks(), &InterfaceBlock::name); + break; + + // TODO(jie.a.chen@intel.com): more interfaces. + case GL_TRANSFORM_FEEDBACK_VARYING: + UNIMPLEMENTED(); + return 0; + + default: + UNREACHABLE(); + return 0; + } + // This length includes an extra character for the null terminator. + return (maxNameLength == 0 ? 0 : maxNameLength + 1); +} + +GLint QueryProgramInterfaceMaxNumActiveVariables(const Program *program, GLenum programInterface) +{ + switch (programInterface) + { + case GL_UNIFORM_BLOCK: + return FindMaxSize(program->getState().getUniformBlocks(), + &InterfaceBlock::memberIndexes); + case GL_ATOMIC_COUNTER_BUFFER: + return FindMaxSize(program->getState().getAtomicCounterBuffers(), + &AtomicCounterBuffer::memberIndexes); + + case GL_SHADER_STORAGE_BLOCK: + return FindMaxSize(program->getState().getShaderStorageBlocks(), + &InterfaceBlock::memberIndexes); + + default: + UNREACHABLE(); + return 0; + } +} + +GLenum GetUniformPropertyEnum(GLenum prop) +{ + switch (prop) + { + case GL_UNIFORM_TYPE: + return GL_TYPE; + case GL_UNIFORM_SIZE: + return GL_ARRAY_SIZE; + case GL_UNIFORM_NAME_LENGTH: + return GL_NAME_LENGTH; + case GL_UNIFORM_BLOCK_INDEX: + return GL_BLOCK_INDEX; + case GL_UNIFORM_OFFSET: + return GL_OFFSET; + case GL_UNIFORM_ARRAY_STRIDE: + return GL_ARRAY_STRIDE; + case GL_UNIFORM_MATRIX_STRIDE: + return GL_MATRIX_STRIDE; + case GL_UNIFORM_IS_ROW_MAJOR: + return GL_IS_ROW_MAJOR; + + default: + return prop; + } +} + +GLenum GetUniformBlockPropertyEnum(GLenum prop) +{ + switch (prop) + { + case GL_UNIFORM_BLOCK_BINDING: + return GL_BUFFER_BINDING; + + case GL_UNIFORM_BLOCK_DATA_SIZE: + return GL_BUFFER_DATA_SIZE; + + case GL_UNIFORM_BLOCK_NAME_LENGTH: + return GL_NAME_LENGTH; + + case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: + return GL_NUM_ACTIVE_VARIABLES; + + case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: + return GL_ACTIVE_VARIABLES; + + case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: + return GL_REFERENCED_BY_VERTEX_SHADER; + + case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: + return GL_REFERENCED_BY_FRAGMENT_SHADER; + + default: + return prop; + } +} + +void GetShaderVariableBufferResourceProperty(const ShaderVariableBuffer &buffer, + GLenum pname, + GLint *params, + GLsizei bufSize, + GLsizei *outputPosition) + +{ + switch (pname) + { + case GL_BUFFER_BINDING: + params[(*outputPosition)++] = buffer.binding; + break; + case GL_BUFFER_DATA_SIZE: + params[(*outputPosition)++] = clampCast(buffer.dataSize); + break; + case GL_NUM_ACTIVE_VARIABLES: + params[(*outputPosition)++] = buffer.numActiveVariables(); + break; + case GL_ACTIVE_VARIABLES: + for (size_t memberIndex = 0; + memberIndex < buffer.memberIndexes.size() && *outputPosition < bufSize; + ++memberIndex) + { + params[(*outputPosition)++] = clampCast(buffer.memberIndexes[memberIndex]); + } + break; + case GL_REFERENCED_BY_VERTEX_SHADER: + params[(*outputPosition)++] = static_cast(buffer.vertexStaticUse); + break; + case GL_REFERENCED_BY_FRAGMENT_SHADER: + params[(*outputPosition)++] = static_cast(buffer.fragmentStaticUse); + break; + case GL_REFERENCED_BY_COMPUTE_SHADER: + params[(*outputPosition)++] = static_cast(buffer.computeStaticUse); + break; + default: + UNREACHABLE(); + break; + } +} + +void GetInterfaceBlockResourceProperty(const InterfaceBlock &block, + GLenum pname, + GLint *params, + GLsizei bufSize, + GLsizei *outputPosition) +{ + if (pname == GL_NAME_LENGTH) + { + params[(*outputPosition)++] = clampCast(block.nameWithArrayIndex().size() + 1); + return; + } + GetShaderVariableBufferResourceProperty(block, pname, params, bufSize, outputPosition); +} + +void GetUniformBlockResourceProperty(const Program *program, + GLuint blockIndex, + GLenum pname, + GLint *params, + GLsizei bufSize, + GLsizei *outputPosition) + +{ + ASSERT(*outputPosition < bufSize); + const auto &block = program->getUniformBlockByIndex(blockIndex); + GetInterfaceBlockResourceProperty(block, pname, params, bufSize, outputPosition); +} + +void GetShaderStorageBlockResourceProperty(const Program *program, + GLuint blockIndex, + GLenum pname, + GLint *params, + GLsizei bufSize, + GLsizei *outputPosition) + +{ + ASSERT(*outputPosition < bufSize); + const auto &block = program->getShaderStorageBlockByIndex(blockIndex); + GetInterfaceBlockResourceProperty(block, pname, params, bufSize, outputPosition); +} + +void GetAtomicCounterBufferResourceProperty(const Program *program, + GLuint index, + GLenum pname, + GLint *params, + GLsizei bufSize, + GLsizei *outputPosition) + +{ + ASSERT(*outputPosition < bufSize); + const auto &buffer = program->getState().getAtomicCounterBuffers()[index]; + GetShaderVariableBufferResourceProperty(buffer, pname, params, bufSize, outputPosition); +} + +} // anonymous namespace + +void QueryFramebufferAttachmentParameteriv(const Framebuffer *framebuffer, + GLenum attachment, + GLenum pname, + GLint *params) +{ + ASSERT(framebuffer); + + const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(attachment); + if (attachmentObject == nullptr) + { + // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE + // is NONE, then querying any other pname will generate INVALID_ENUM. + + // ES 3.0.2 spec pg 235 states that if the attachment type is none, + // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an + // INVALID_OPERATION for all other pnames + + switch (pname) + { + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: + *params = GL_NONE; + break; + + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: + *params = 0; + break; + + default: + UNREACHABLE(); + break; + } + + return; + } + + switch (pname) + { + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: + *params = attachmentObject->type(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: + *params = attachmentObject->id(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: + *params = attachmentObject->mipLevel(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: + *params = attachmentObject->cubeMapFace(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE: + *params = attachmentObject->getRedSize(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: + *params = attachmentObject->getGreenSize(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE: + *params = attachmentObject->getBlueSize(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE: + *params = attachmentObject->getAlphaSize(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE: + *params = attachmentObject->getDepthSize(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: + *params = attachmentObject->getStencilSize(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: + *params = attachmentObject->getComponentType(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: + *params = attachmentObject->getColorEncoding(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER: + *params = attachmentObject->layer(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE: + *params = attachmentObject->getNumViews(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE: + *params = static_cast(attachmentObject->getMultiviewLayout()); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE: + *params = attachmentObject->getBaseViewIndex(); + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE: + { + const std::vector &offsets = attachmentObject->getMultiviewViewportOffsets(); + for (size_t i = 0u; i < offsets.size(); ++i) + { + params[i * 2u] = offsets[i].x; + params[i * 2u + 1u] = offsets[i].y; + } + } + break; + + default: + UNREACHABLE(); + break; + } +} + +void QueryBufferParameteriv(const Buffer *buffer, GLenum pname, GLint *params) +{ + QueryBufferParameterBase(buffer, pname, params); +} + +void QueryBufferParameteri64v(const Buffer *buffer, GLenum pname, GLint64 *params) +{ + QueryBufferParameterBase(buffer, pname, params); +} + +void QueryBufferPointerv(const Buffer *buffer, GLenum pname, void **params) +{ + switch (pname) + { + case GL_BUFFER_MAP_POINTER: + *params = buffer->getMapPointer(); + break; + + default: + UNREACHABLE(); + break; + } +} + +void QueryProgramiv(const Context *context, const Program *program, GLenum pname, GLint *params) +{ + ASSERT(program != nullptr); + + switch (pname) + { + case GL_DELETE_STATUS: + *params = program->isFlaggedForDeletion(); + return; + case GL_LINK_STATUS: + *params = program->isLinked(); + return; + case GL_VALIDATE_STATUS: + *params = program->isValidated(); + return; + case GL_INFO_LOG_LENGTH: + *params = program->getInfoLogLength(); + return; + case GL_ATTACHED_SHADERS: + *params = program->getAttachedShadersCount(); + return; + case GL_ACTIVE_ATTRIBUTES: + *params = program->getActiveAttributeCount(); + return; + case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: + *params = program->getActiveAttributeMaxLength(); + return; + case GL_ACTIVE_UNIFORMS: + *params = program->getActiveUniformCount(); + return; + case GL_ACTIVE_UNIFORM_MAX_LENGTH: + *params = program->getActiveUniformMaxLength(); + return; + case GL_PROGRAM_BINARY_LENGTH_OES: + *params = program->getBinaryLength(context); + return; + case GL_ACTIVE_UNIFORM_BLOCKS: + *params = program->getActiveUniformBlockCount(); + return; + case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: + *params = program->getActiveUniformBlockMaxLength(); + break; + case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: + *params = program->getTransformFeedbackBufferMode(); + break; + case GL_TRANSFORM_FEEDBACK_VARYINGS: + *params = program->getTransformFeedbackVaryingCount(); + break; + case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: + *params = program->getTransformFeedbackVaryingMaxLength(); + break; + case GL_PROGRAM_BINARY_RETRIEVABLE_HINT: + *params = program->getBinaryRetrievableHint(); + break; + case GL_PROGRAM_SEPARABLE: + *params = program->isSeparable(); + break; + case GL_COMPUTE_WORK_GROUP_SIZE: + { + const sh::WorkGroupSize &localSize = program->getComputeShaderLocalSize(); + params[0] = localSize[0]; + params[1] = localSize[1]; + params[2] = localSize[2]; + } + break; + case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS: + *params = program->getActiveAtomicCounterBufferCount(); + break; + default: + UNREACHABLE(); + break; + } +} + +void QueryRenderbufferiv(const Context *context, + const Renderbuffer *renderbuffer, + GLenum pname, + GLint *params) +{ + ASSERT(renderbuffer != nullptr); + + switch (pname) + { + case GL_RENDERBUFFER_WIDTH: + *params = renderbuffer->getWidth(); + break; + case GL_RENDERBUFFER_HEIGHT: + *params = renderbuffer->getHeight(); + break; + case GL_RENDERBUFFER_INTERNAL_FORMAT: + // Special case the WebGL 1 DEPTH_STENCIL format. + if (context->isWebGL1() && + renderbuffer->getFormat().info->internalFormat == GL_DEPTH24_STENCIL8) + { + *params = GL_DEPTH_STENCIL; + } + else + { + *params = renderbuffer->getFormat().info->internalFormat; + } + break; + case GL_RENDERBUFFER_RED_SIZE: + *params = renderbuffer->getRedSize(); + break; + case GL_RENDERBUFFER_GREEN_SIZE: + *params = renderbuffer->getGreenSize(); + break; + case GL_RENDERBUFFER_BLUE_SIZE: + *params = renderbuffer->getBlueSize(); + break; + case GL_RENDERBUFFER_ALPHA_SIZE: + *params = renderbuffer->getAlphaSize(); + break; + case GL_RENDERBUFFER_DEPTH_SIZE: + *params = renderbuffer->getDepthSize(); + break; + case GL_RENDERBUFFER_STENCIL_SIZE: + *params = renderbuffer->getStencilSize(); + break; + case GL_RENDERBUFFER_SAMPLES_ANGLE: + *params = renderbuffer->getSamples(); + break; + default: + UNREACHABLE(); + break; + } +} + +void QueryShaderiv(const Context *context, Shader *shader, GLenum pname, GLint *params) +{ + ASSERT(shader != nullptr); + + switch (pname) + { + case GL_SHADER_TYPE: + *params = shader->getType(); + return; + case GL_DELETE_STATUS: + *params = shader->isFlaggedForDeletion(); + return; + case GL_COMPILE_STATUS: + *params = shader->isCompiled(context) ? GL_TRUE : GL_FALSE; + return; + case GL_INFO_LOG_LENGTH: + *params = shader->getInfoLogLength(context); + return; + case GL_SHADER_SOURCE_LENGTH: + *params = shader->getSourceLength(); + return; + case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE: + *params = shader->getTranslatedSourceWithDebugInfoLength(context); + return; + default: + UNREACHABLE(); + break; + } +} + +void QueryTexLevelParameterfv(const Texture *texture, + GLenum target, + GLint level, + GLenum pname, + GLfloat *params) +{ + QueryTexLevelParameterBase(texture, target, level, pname, params); +} + +void QueryTexLevelParameteriv(const Texture *texture, + GLenum target, + GLint level, + GLenum pname, + GLint *params) +{ + QueryTexLevelParameterBase(texture, target, level, pname, params); +} + +void QueryTexParameterfv(const Texture *texture, GLenum pname, GLfloat *params) +{ + QueryTexParameterBase(texture, pname, params); +} + +void QueryTexParameteriv(const Texture *texture, GLenum pname, GLint *params) +{ + QueryTexParameterBase(texture, pname, params); +} + +void QuerySamplerParameterfv(const Sampler *sampler, GLenum pname, GLfloat *params) +{ + QuerySamplerParameterBase(sampler, pname, params); +} + +void QuerySamplerParameteriv(const Sampler *sampler, GLenum pname, GLint *params) +{ + QuerySamplerParameterBase(sampler, pname, params); +} + +void QueryVertexAttribfv(const VertexAttribute &attrib, + const VertexBinding &binding, + const VertexAttribCurrentValueData ¤tValueData, + GLenum pname, + GLfloat *params) +{ + QueryVertexAttribBase(attrib, binding, currentValueData.FloatValues, pname, params); +} + +void QueryVertexAttribiv(const VertexAttribute &attrib, + const VertexBinding &binding, + const VertexAttribCurrentValueData ¤tValueData, + GLenum pname, + GLint *params) +{ + QueryVertexAttribBase(attrib, binding, currentValueData.FloatValues, pname, params); +} + +void QueryVertexAttribPointerv(const VertexAttribute &attrib, GLenum pname, void **pointer) +{ + switch (pname) + { + case GL_VERTEX_ATTRIB_ARRAY_POINTER: + *pointer = const_cast(attrib.pointer); + break; + + default: + UNREACHABLE(); + break; + } +} + +void QueryVertexAttribIiv(const VertexAttribute &attrib, + const VertexBinding &binding, + const VertexAttribCurrentValueData ¤tValueData, + GLenum pname, + GLint *params) +{ + QueryVertexAttribBase(attrib, binding, currentValueData.IntValues, pname, params); +} + +void QueryVertexAttribIuiv(const VertexAttribute &attrib, + const VertexBinding &binding, + const VertexAttribCurrentValueData ¤tValueData, + GLenum pname, + GLuint *params) +{ + QueryVertexAttribBase(attrib, binding, currentValueData.UnsignedIntValues, pname, params); +} + +void QueryActiveUniformBlockiv(const Program *program, + GLuint uniformBlockIndex, + GLenum pname, + GLint *params) +{ + GLenum prop = GetUniformBlockPropertyEnum(pname); + QueryProgramResourceiv(program, GL_UNIFORM_BLOCK, uniformBlockIndex, 1, &prop, + std::numeric_limits::max(), nullptr, params); +} + +void QueryInternalFormativ(const TextureCaps &format, GLenum pname, GLsizei bufSize, GLint *params) +{ + switch (pname) + { + case GL_NUM_SAMPLE_COUNTS: + if (bufSize != 0) + { + *params = clampCast(format.sampleCounts.size()); + } + break; + + case GL_SAMPLES: + { + size_t returnCount = std::min(bufSize, format.sampleCounts.size()); + auto sampleReverseIt = format.sampleCounts.rbegin(); + for (size_t sampleIndex = 0; sampleIndex < returnCount; ++sampleIndex) + { + params[sampleIndex] = *sampleReverseIt++; + } + } + break; + + default: + UNREACHABLE(); + break; + } +} + +void QueryFramebufferParameteriv(const Framebuffer *framebuffer, GLenum pname, GLint *params) +{ + ASSERT(framebuffer); + + switch (pname) + { + case GL_FRAMEBUFFER_DEFAULT_WIDTH: + *params = framebuffer->getDefaultWidth(); + break; + case GL_FRAMEBUFFER_DEFAULT_HEIGHT: + *params = framebuffer->getDefaultHeight(); + break; + case GL_FRAMEBUFFER_DEFAULT_SAMPLES: + *params = framebuffer->getDefaultSamples(); + break; + case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS: + *params = ConvertToGLBoolean(framebuffer->getDefaultFixedSampleLocations()); + break; + default: + UNREACHABLE(); + break; + } +} + +Error QuerySynciv(const Sync *sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values) +{ + ASSERT(sync); + + // All queries return one value, exit early if the buffer can't fit anything. + if (bufSize < 1) + { + if (length != nullptr) + { + *length = 0; + } + return NoError(); + } + + switch (pname) + { + case GL_OBJECT_TYPE: + *values = clampCast(GL_SYNC_FENCE); + break; + case GL_SYNC_CONDITION: + *values = clampCast(sync->getCondition()); + break; + case GL_SYNC_FLAGS: + *values = clampCast(sync->getFlags()); + break; + case GL_SYNC_STATUS: + ANGLE_TRY(sync->getStatus(values)); + break; + + default: + UNREACHABLE(); + break; + } + + if (length != nullptr) + { + *length = 1; + } + + return NoError(); +} + +void SetTexParameterf(Context *context, Texture *texture, GLenum pname, GLfloat param) +{ + SetTexParameterBase(context, texture, pname, ¶m); +} + +void SetTexParameterfv(Context *context, Texture *texture, GLenum pname, const GLfloat *params) +{ + SetTexParameterBase(context, texture, pname, params); +} + +void SetTexParameteri(Context *context, Texture *texture, GLenum pname, GLint param) +{ + SetTexParameterBase(context, texture, pname, ¶m); +} + +void SetTexParameteriv(Context *context, Texture *texture, GLenum pname, const GLint *params) +{ + SetTexParameterBase(context, texture, pname, params); +} + +void SetSamplerParameterf(Sampler *sampler, GLenum pname, GLfloat param) +{ + SetSamplerParameterBase(sampler, pname, ¶m); +} + +void SetSamplerParameterfv(Sampler *sampler, GLenum pname, const GLfloat *params) +{ + SetSamplerParameterBase(sampler, pname, params); +} + +void SetSamplerParameteri(Sampler *sampler, GLenum pname, GLint param) +{ + SetSamplerParameterBase(sampler, pname, ¶m); +} + +void SetSamplerParameteriv(Sampler *sampler, GLenum pname, const GLint *params) +{ + SetSamplerParameterBase(sampler, pname, params); +} + +void SetFramebufferParameteri(Framebuffer *framebuffer, GLenum pname, GLint param) +{ + ASSERT(framebuffer); + + switch (pname) + { + case GL_FRAMEBUFFER_DEFAULT_WIDTH: + framebuffer->setDefaultWidth(param); + break; + case GL_FRAMEBUFFER_DEFAULT_HEIGHT: + framebuffer->setDefaultHeight(param); + break; + case GL_FRAMEBUFFER_DEFAULT_SAMPLES: + framebuffer->setDefaultSamples(param); + break; + case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS: + framebuffer->setDefaultFixedSampleLocations(ConvertToBool(param)); + break; + default: + UNREACHABLE(); + break; + } +} + +void SetProgramParameteri(Program *program, GLenum pname, GLint value) +{ + ASSERT(program); + + switch (pname) + { + case GL_PROGRAM_BINARY_RETRIEVABLE_HINT: + program->setBinaryRetrievableHint(ConvertToBool(value)); + break; + case GL_PROGRAM_SEPARABLE: + program->setSeparable(ConvertToBool(value)); + break; + default: + UNREACHABLE(); + break; + } +} + +GLint GetUniformResourceProperty(const Program *program, GLuint index, const GLenum prop) +{ + const auto &uniform = program->getUniformByIndex(index); + GLenum resourceProp = GetUniformPropertyEnum(prop); + switch (resourceProp) + { + case GL_TYPE: + case GL_ARRAY_SIZE: + case GL_NAME_LENGTH: + return GetCommonVariableProperty(uniform, resourceProp); + + case GL_LOCATION: + return program->getUniformLocation(uniform.name); + + case GL_BLOCK_INDEX: + return (uniform.isAtomicCounter() ? -1 : uniform.bufferIndex); + + case GL_OFFSET: + return uniform.blockInfo.offset; + + case GL_ARRAY_STRIDE: + return uniform.blockInfo.arrayStride; + + case GL_MATRIX_STRIDE: + return uniform.blockInfo.matrixStride; + + case GL_IS_ROW_MAJOR: + return static_cast(uniform.blockInfo.isRowMajorMatrix); + + case GL_REFERENCED_BY_VERTEX_SHADER: + return uniform.vertexStaticUse; + + case GL_REFERENCED_BY_FRAGMENT_SHADER: + return uniform.fragmentStaticUse; + + case GL_REFERENCED_BY_COMPUTE_SHADER: + return uniform.computeStaticUse; + + case GL_ATOMIC_COUNTER_BUFFER_INDEX: + return (uniform.isAtomicCounter() ? uniform.bufferIndex : -1); + + default: + UNREACHABLE(); + return 0; + } +} + +GLint GetBufferVariableResourceProperty(const Program *program, GLuint index, const GLenum prop) +{ + const auto &bufferVariable = program->getBufferVariableByIndex(index); + switch (prop) + { + case GL_TYPE: + case GL_ARRAY_SIZE: + case GL_NAME_LENGTH: + return GetCommonVariableProperty(bufferVariable, prop); + + case GL_BLOCK_INDEX: + return bufferVariable.bufferIndex; + + case GL_OFFSET: + return bufferVariable.blockInfo.offset; + + case GL_ARRAY_STRIDE: + return bufferVariable.blockInfo.arrayStride; + + case GL_MATRIX_STRIDE: + return bufferVariable.blockInfo.matrixStride; + + case GL_IS_ROW_MAJOR: + return static_cast(bufferVariable.blockInfo.isRowMajorMatrix); + + case GL_REFERENCED_BY_VERTEX_SHADER: + return bufferVariable.vertexStaticUse; + + case GL_REFERENCED_BY_FRAGMENT_SHADER: + return bufferVariable.fragmentStaticUse; + + case GL_REFERENCED_BY_COMPUTE_SHADER: + return bufferVariable.computeStaticUse; + + case GL_TOP_LEVEL_ARRAY_SIZE: + return bufferVariable.topLevelArraySize; + + case GL_TOP_LEVEL_ARRAY_STRIDE: + return bufferVariable.blockInfo.topLevelArrayStride; + + default: + UNREACHABLE(); + return 0; + } +} + +GLuint QueryProgramResourceIndex(const Program *program, + GLenum programInterface, + const GLchar *name) +{ + switch (programInterface) + { + case GL_PROGRAM_INPUT: + return program->getInputResourceIndex(name); + + case GL_PROGRAM_OUTPUT: + return program->getOutputResourceIndex(name); + + case GL_UNIFORM: + return program->getState().getUniformIndexFromName(name); + + case GL_BUFFER_VARIABLE: + return program->getState().getBufferVariableIndexFromName(name); + + case GL_SHADER_STORAGE_BLOCK: + return program->getShaderStorageBlockIndex(name); + + case GL_UNIFORM_BLOCK: + return program->getUniformBlockIndex(name); + + // TODO(jie.a.chen@intel.com): more interfaces. + case GL_TRANSFORM_FEEDBACK_VARYING: + UNIMPLEMENTED(); + return GL_INVALID_INDEX; + + default: + UNREACHABLE(); + return GL_INVALID_INDEX; + } +} + +void QueryProgramResourceName(const Program *program, + GLenum programInterface, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name) +{ + switch (programInterface) + { + case GL_PROGRAM_INPUT: + program->getInputResourceName(index, bufSize, length, name); + break; + + case GL_PROGRAM_OUTPUT: + program->getOutputResourceName(index, bufSize, length, name); + break; + + case GL_UNIFORM: + program->getUniformResourceName(index, bufSize, length, name); + break; + + case GL_BUFFER_VARIABLE: + program->getBufferVariableResourceName(index, bufSize, length, name); + break; + + case GL_SHADER_STORAGE_BLOCK: + program->getActiveShaderStorageBlockName(index, bufSize, length, name); + break; + + case GL_UNIFORM_BLOCK: + program->getActiveUniformBlockName(index, bufSize, length, name); + break; + + // TODO(jie.a.chen@intel.com): more interfaces. + case GL_TRANSFORM_FEEDBACK_VARYING: + UNIMPLEMENTED(); + break; + + default: + UNREACHABLE(); + } +} + +GLint QueryProgramResourceLocation(const Program *program, + GLenum programInterface, + const GLchar *name) +{ + switch (programInterface) + { + case GL_PROGRAM_INPUT: + return program->getAttributeLocation(name); + + case GL_PROGRAM_OUTPUT: + return program->getFragDataLocation(name); + + case GL_UNIFORM: + return program->getUniformLocation(name); + + default: + UNREACHABLE(); + return -1; + } +} + +void QueryProgramResourceiv(const Program *program, + GLenum programInterface, + GLuint index, + GLsizei propCount, + const GLenum *props, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + if (!program->isLinked()) + { + if (length != nullptr) + { + *length = 0; + } + return; + } + + GLsizei pos = 0; + for (GLsizei i = 0; i < propCount; i++) + { + switch (programInterface) + { + case GL_PROGRAM_INPUT: + params[i] = GetInputResourceProperty(program, index, props[i]); + ++pos; + break; + + case GL_PROGRAM_OUTPUT: + params[i] = GetOutputResourceProperty(program, index, props[i]); + ++pos; + break; + + case GL_UNIFORM: + params[i] = GetUniformResourceProperty(program, index, props[i]); + ++pos; + break; + + case GL_BUFFER_VARIABLE: + params[i] = GetBufferVariableResourceProperty(program, index, props[i]); + ++pos; + break; + + case GL_UNIFORM_BLOCK: + GetUniformBlockResourceProperty(program, index, props[i], params, bufSize, &pos); + break; + + case GL_SHADER_STORAGE_BLOCK: + GetShaderStorageBlockResourceProperty(program, index, props[i], params, bufSize, + &pos); + break; + + case GL_ATOMIC_COUNTER_BUFFER: + GetAtomicCounterBufferResourceProperty(program, index, props[i], params, bufSize, + &pos); + break; + // TODO(jie.a.chen@intel.com): more interfaces. + case GL_TRANSFORM_FEEDBACK_VARYING: + UNIMPLEMENTED(); + params[i] = GL_INVALID_VALUE; + break; + + default: + UNREACHABLE(); + params[i] = GL_INVALID_VALUE; + } + if (pos == bufSize) + { + // Most properties return one value, but GL_ACTIVE_VARIABLES returns an array of values. + // This checks not to break buffer bounds for such case. + break; + } + } + + if (length != nullptr) + { + *length = pos; + } +} + +void QueryProgramInterfaceiv(const Program *program, + GLenum programInterface, + GLenum pname, + GLint *params) +{ + switch (pname) + { + case GL_ACTIVE_RESOURCES: + *params = QueryProgramInterfaceActiveResources(program, programInterface); + break; + + case GL_MAX_NAME_LENGTH: + *params = QueryProgramInterfaceMaxNameLength(program, programInterface); + break; + + case GL_MAX_NUM_ACTIVE_VARIABLES: + *params = QueryProgramInterfaceMaxNumActiveVariables(program, programInterface); + break; + + default: + UNREACHABLE(); + } +} + +} // namespace gl + +namespace egl +{ + +void QueryConfigAttrib(const Config *config, EGLint attribute, EGLint *value) +{ + ASSERT(config != nullptr); + switch (attribute) + { + case EGL_BUFFER_SIZE: + *value = config->bufferSize; + break; + case EGL_ALPHA_SIZE: + *value = config->alphaSize; + break; + case EGL_BLUE_SIZE: + *value = config->blueSize; + break; + case EGL_GREEN_SIZE: + *value = config->greenSize; + break; + case EGL_RED_SIZE: + *value = config->redSize; + break; + case EGL_DEPTH_SIZE: + *value = config->depthSize; + break; + case EGL_STENCIL_SIZE: + *value = config->stencilSize; + break; + case EGL_CONFIG_CAVEAT: + *value = config->configCaveat; + break; + case EGL_CONFIG_ID: + *value = config->configID; + break; + case EGL_LEVEL: + *value = config->level; + break; + case EGL_NATIVE_RENDERABLE: + *value = config->nativeRenderable; + break; + case EGL_NATIVE_VISUAL_ID: + *value = config->nativeVisualID; + break; + case EGL_NATIVE_VISUAL_TYPE: + *value = config->nativeVisualType; + break; + case EGL_SAMPLES: + *value = config->samples; + break; + case EGL_SAMPLE_BUFFERS: + *value = config->sampleBuffers; + break; + case EGL_SURFACE_TYPE: + *value = config->surfaceType; + break; + case EGL_TRANSPARENT_TYPE: + *value = config->transparentType; + break; + case EGL_TRANSPARENT_BLUE_VALUE: + *value = config->transparentBlueValue; + break; + case EGL_TRANSPARENT_GREEN_VALUE: + *value = config->transparentGreenValue; + break; + case EGL_TRANSPARENT_RED_VALUE: + *value = config->transparentRedValue; + break; + case EGL_BIND_TO_TEXTURE_RGB: + *value = config->bindToTextureRGB; + break; + case EGL_BIND_TO_TEXTURE_RGBA: + *value = config->bindToTextureRGBA; + break; + case EGL_MIN_SWAP_INTERVAL: + *value = config->minSwapInterval; + break; + case EGL_MAX_SWAP_INTERVAL: + *value = config->maxSwapInterval; + break; + case EGL_LUMINANCE_SIZE: + *value = config->luminanceSize; + break; + case EGL_ALPHA_MASK_SIZE: + *value = config->alphaMaskSize; + break; + case EGL_COLOR_BUFFER_TYPE: + *value = config->colorBufferType; + break; + case EGL_RENDERABLE_TYPE: + *value = config->renderableType; + break; + case EGL_MATCH_NATIVE_PIXMAP: + *value = false; + UNIMPLEMENTED(); + break; + case EGL_CONFORMANT: + *value = config->conformant; + break; + case EGL_MAX_PBUFFER_WIDTH: + *value = config->maxPBufferWidth; + break; + case EGL_MAX_PBUFFER_HEIGHT: + *value = config->maxPBufferHeight; + break; + case EGL_MAX_PBUFFER_PIXELS: + *value = config->maxPBufferPixels; + break; + case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE: + *value = config->optimalOrientation; + break; + case EGL_COLOR_COMPONENT_TYPE_EXT: + *value = config->colorComponentType; + break; + default: + UNREACHABLE(); + break; + } +} + +void QueryContextAttrib(const gl::Context *context, EGLint attribute, EGLint *value) +{ + switch (attribute) + { + case EGL_CONFIG_ID: + *value = context->getConfig()->configID; + break; + case EGL_CONTEXT_CLIENT_TYPE: + *value = context->getClientType(); + break; + case EGL_CONTEXT_CLIENT_VERSION: + *value = context->getClientMajorVersion(); + break; + case EGL_RENDER_BUFFER: + *value = context->getRenderBuffer(); + break; + case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: + *value = context->isRobustResourceInitEnabled(); + break; + default: + UNREACHABLE(); + break; + } +} + +void QuerySurfaceAttrib(const Surface *surface, EGLint attribute, EGLint *value) +{ + switch (attribute) + { + case EGL_GL_COLORSPACE: + *value = surface->getGLColorspace(); + break; + case EGL_VG_ALPHA_FORMAT: + *value = surface->getVGAlphaFormat(); + break; + case EGL_VG_COLORSPACE: + *value = surface->getVGColorspace(); + break; + case EGL_CONFIG_ID: + *value = surface->getConfig()->configID; + break; + case EGL_HEIGHT: + *value = surface->getHeight(); + break; + case EGL_HORIZONTAL_RESOLUTION: + *value = surface->getHorizontalResolution(); + break; + case EGL_LARGEST_PBUFFER: + // The EGL spec states that value is not written if the surface is not a pbuffer + if (surface->getType() == EGL_PBUFFER_BIT) + { + *value = surface->getLargestPbuffer(); + } + break; + case EGL_MIPMAP_TEXTURE: + // The EGL spec states that value is not written if the surface is not a pbuffer + if (surface->getType() == EGL_PBUFFER_BIT) + { + *value = surface->getMipmapTexture(); + } + break; + case EGL_MIPMAP_LEVEL: + // The EGL spec states that value is not written if the surface is not a pbuffer + if (surface->getType() == EGL_PBUFFER_BIT) + { + *value = surface->getMipmapLevel(); + } + break; + case EGL_MULTISAMPLE_RESOLVE: + *value = surface->getMultisampleResolve(); + break; + case EGL_PIXEL_ASPECT_RATIO: + *value = surface->getPixelAspectRatio(); + break; + case EGL_RENDER_BUFFER: + *value = surface->getRenderBuffer(); + break; + case EGL_SWAP_BEHAVIOR: + *value = surface->getSwapBehavior(); + break; + case EGL_TEXTURE_FORMAT: + // The EGL spec states that value is not written if the surface is not a pbuffer + if (surface->getType() == EGL_PBUFFER_BIT) + { + *value = surface->getTextureFormat(); + } + break; + case EGL_TEXTURE_TARGET: + // The EGL spec states that value is not written if the surface is not a pbuffer + if (surface->getType() == EGL_PBUFFER_BIT) + { + *value = surface->getTextureTarget(); + } + break; + case EGL_VERTICAL_RESOLUTION: + *value = surface->getVerticalResolution(); + break; + case EGL_WIDTH: + *value = surface->getWidth(); + break; + case EGL_POST_SUB_BUFFER_SUPPORTED_NV: + *value = surface->isPostSubBufferSupported(); + break; + case EGL_FIXED_SIZE_ANGLE: + *value = surface->isFixedSize(); + break; + case EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE: + *value = surface->flexibleSurfaceCompatibilityRequested(); + break; + case EGL_SURFACE_ORIENTATION_ANGLE: + *value = surface->getOrientation(); + break; + case EGL_DIRECT_COMPOSITION_ANGLE: + *value = surface->directComposition(); + break; + case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: + *value = surface->isRobustResourceInitEnabled(); + break; + default: + UNREACHABLE(); + break; + } +} + +void SetSurfaceAttrib(Surface *surface, EGLint attribute, EGLint value) +{ + switch (attribute) + { + case EGL_MIPMAP_LEVEL: + surface->setMipmapLevel(value); + break; + case EGL_MULTISAMPLE_RESOLVE: + surface->setMultisampleResolve(value); + break; + case EGL_SWAP_BEHAVIOR: + surface->setSwapBehavior(value); + break; + default: + UNREACHABLE(); + break; + } +} + +} // namespace egl diff --git a/src/3rdparty/angle/src/libANGLE/queryutils.h b/src/3rdparty/angle/src/libANGLE/queryutils.h new file mode 100644 index 0000000000..990cbc169e --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/queryutils.h @@ -0,0 +1,162 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// queryutils.h: Utilities for querying values from GL objects + +#ifndef LIBANGLE_QUERYUTILS_H_ +#define LIBANGLE_QUERYUTILS_H_ + +#include "angle_gl.h" +#include "common/angleutils.h" + +#include + +namespace gl +{ +class Buffer; +class Context; +class Error; +class Sync; +class Framebuffer; +class Program; +class Renderbuffer; +class Sampler; +class Shader; +class Texture; +struct TextureCaps; +struct UniformBlock; +struct VertexAttribute; +class VertexBinding; +struct VertexAttribCurrentValueData; + +void QueryFramebufferAttachmentParameteriv(const Framebuffer *framebuffer, + GLenum attachment, + GLenum pname, + GLint *params); +void QueryBufferParameteriv(const Buffer *buffer, GLenum pname, GLint *params); +void QueryBufferParameteri64v(const Buffer *buffer, GLenum pname, GLint64 *params); +void QueryBufferPointerv(const Buffer *buffer, GLenum pname, void **params); +void QueryProgramiv(const Context *context, const Program *program, GLenum pname, GLint *params); +void QueryRenderbufferiv(const Context *context, + const Renderbuffer *renderbuffer, + GLenum pname, + GLint *params); +void QueryShaderiv(const Context *context, Shader *shader, GLenum pname, GLint *params); +void QueryTexLevelParameterfv(const Texture *texture, + GLenum target, + GLint level, + GLenum pname, + GLfloat *params); +void QueryTexLevelParameteriv(const Texture *texture, + GLenum target, + GLint level, + GLenum pname, + GLint *params); +void QueryTexParameterfv(const Texture *texture, GLenum pname, GLfloat *params); +void QueryTexParameteriv(const Texture *texture, GLenum pname, GLint *params); +void QuerySamplerParameterfv(const Sampler *sampler, GLenum pname, GLfloat *params); +void QuerySamplerParameteriv(const Sampler *sampler, GLenum pname, GLint *params); + +// Warning: you should ensure binding really matches attrib.bindingIndex before using the following +// functions. +void QueryVertexAttribfv(const VertexAttribute &attrib, + const VertexBinding &binding, + const VertexAttribCurrentValueData ¤tValueData, + GLenum pname, + GLfloat *params); + +void QueryVertexAttribiv(const VertexAttribute &attrib, + const VertexBinding &binding, + const VertexAttribCurrentValueData ¤tValueData, + GLenum pname, + GLint *params); + +void QueryVertexAttribPointerv(const VertexAttribute &attrib, GLenum pname, void **pointer); + +void QueryVertexAttribIiv(const VertexAttribute &attrib, + const VertexBinding &binding, + const VertexAttribCurrentValueData ¤tValueData, + GLenum pname, + GLint *params); + +void QueryVertexAttribIuiv(const VertexAttribute &attrib, + const VertexBinding &binding, + const VertexAttribCurrentValueData ¤tValueData, + GLenum pname, + GLuint *params); + +void QueryActiveUniformBlockiv(const Program *program, + GLuint uniformBlockIndex, + GLenum pname, + GLint *params); + +void QueryInternalFormativ(const TextureCaps &format, GLenum pname, GLsizei bufSize, GLint *params); + +void QueryFramebufferParameteriv(const Framebuffer *framebuffer, GLenum pname, GLint *params); + +Error QuerySynciv(const Sync *sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); + +void SetTexParameterf(Context *context, Texture *texture, GLenum pname, GLfloat param); +void SetTexParameterfv(Context *context, Texture *texture, GLenum pname, const GLfloat *params); +void SetTexParameteri(Context *context, Texture *texture, GLenum pname, GLint param); +void SetTexParameteriv(Context *context, Texture *texture, GLenum pname, const GLint *params); + +void SetSamplerParameterf(Sampler *sampler, GLenum pname, GLfloat param); +void SetSamplerParameterfv(Sampler *sampler, GLenum pname, const GLfloat *params); +void SetSamplerParameteri(Sampler *sampler, GLenum pname, GLint param); +void SetSamplerParameteriv(Sampler *sampler, GLenum pname, const GLint *params); + +void SetFramebufferParameteri(Framebuffer *framebuffer, GLenum pname, GLint param); + +void SetProgramParameteri(Program *program, GLenum pname, GLint value); + +GLint GetUniformResourceProperty(const Program *program, GLuint index, const GLenum prop); + +GLuint QueryProgramResourceIndex(const Program *program, + GLenum programInterface, + const GLchar *name); + +void QueryProgramResourceName(const Program *program, + GLenum programInterface, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name); + +GLint QueryProgramResourceLocation(const Program *program, + GLenum programInterface, + const GLchar *name); +void QueryProgramResourceiv(const Program *program, + GLenum programInterface, + GLuint index, + GLsizei propCount, + const GLenum *props, + GLsizei bufSize, + GLsizei *length, + GLint *params); + +void QueryProgramInterfaceiv(const Program *program, + GLenum programInterface, + GLenum pname, + GLint *params); + +} // namespace gl + +namespace egl +{ +struct Config; +class Surface; + +void QueryConfigAttrib(const Config *config, EGLint attribute, EGLint *value); + +void QueryContextAttrib(const gl::Context *context, EGLint attribute, EGLint *value); + +void QuerySurfaceAttrib(const Surface *surface, EGLint attribute, EGLint *value); +void SetSurfaceAttrib(Surface *surface, EGLint attribute, EGLint value); + +} // namespace egl + +#endif // LIBANGLE_QUERYUTILS_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/BufferImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/BufferImpl.h index d77f06cf09..f76fcdc8d7 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/BufferImpl.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/BufferImpl.h @@ -12,31 +12,58 @@ #include "common/angleutils.h" #include "common/mathutil.h" #include "libANGLE/Error.h" +#include "libANGLE/PackedGLEnums.h" #include +namespace gl +{ +class BufferState; +class Context; +} + namespace rx { - class BufferImpl : angle::NonCopyable { public: - virtual ~BufferImpl() { } + BufferImpl(const gl::BufferState &state) : mState(state) {} + virtual ~BufferImpl() {} + virtual void destroy(const gl::Context *context) {} - virtual gl::Error setData(const void* data, size_t size, GLenum usage) = 0; - virtual gl::Error setSubData(const void* data, size_t size, size_t offset) = 0; - virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) = 0; - virtual gl::Error map(GLenum access, GLvoid **mapPtr) = 0; - virtual gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) = 0; - virtual gl::Error unmap(GLboolean *result) = 0; + virtual gl::Error setData(const gl::Context *context, + gl::BufferBinding target, + const void *data, + size_t size, + gl::BufferUsage usage) = 0; + virtual gl::Error setSubData(const gl::Context *context, + gl::BufferBinding target, + const void *data, + size_t size, + size_t offset) = 0; + virtual gl::Error copySubData(const gl::Context *context, + BufferImpl *source, + GLintptr sourceOffset, + GLintptr destOffset, + GLsizeiptr size) = 0; + virtual gl::Error map(const gl::Context *context, GLenum access, void **mapPtr) = 0; + virtual gl::Error mapRange(const gl::Context *context, + size_t offset, + size_t length, + GLbitfield access, + void **mapPtr) = 0; + virtual gl::Error unmap(const gl::Context *context, GLboolean *result) = 0; - virtual gl::Error getIndexRange(GLenum type, + virtual gl::Error getIndexRange(const gl::Context *context, + GLenum type, size_t offset, size_t count, bool primitiveRestartEnabled, gl::IndexRange *outRange) = 0; -}; + protected: + const gl::BufferState &mState; +}; } -#endif // LIBANGLE_RENDERER_BUFFERIMPL_H_ +#endif // LIBANGLE_RENDERER_BUFFERIMPL_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/BufferImpl_mock.h b/src/3rdparty/angle/src/libANGLE/renderer/BufferImpl_mock.h index a6387661ce..5a4e21003c 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/BufferImpl_mock.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/BufferImpl_mock.h @@ -11,28 +11,38 @@ #include "gmock/gmock.h" +#include "libANGLE/Buffer.h" #include "libANGLE/renderer/BufferImpl.h" namespace rx { - class MockBufferImpl : public BufferImpl { public: + MockBufferImpl() : BufferImpl(mMockState) {} ~MockBufferImpl() { destructor(); } - MOCK_METHOD3(setData, gl::Error(const void*, size_t, GLenum)); - MOCK_METHOD3(setSubData, gl::Error(const void*, size_t, size_t)); - MOCK_METHOD4(copySubData, gl::Error(BufferImpl *, GLintptr, GLintptr, GLsizeiptr)); - MOCK_METHOD2(map, gl::Error(GLenum, GLvoid **)); - MOCK_METHOD4(mapRange, gl::Error(size_t, size_t, GLbitfield, GLvoid **)); - MOCK_METHOD1(unmap, gl::Error(GLboolean *result)); + MOCK_METHOD5( + setData, + gl::Error(const gl::Context *, gl::BufferBinding, const void *, size_t, gl::BufferUsage)); + MOCK_METHOD5(setSubData, + gl::Error(const gl::Context *, gl::BufferBinding, const void *, size_t, size_t)); + MOCK_METHOD5( + copySubData, + gl::Error(const gl::Context *contextImpl, BufferImpl *, GLintptr, GLintptr, GLsizeiptr)); + MOCK_METHOD3(map, gl::Error(const gl::Context *contextImpl, GLenum, void **)); + MOCK_METHOD5(mapRange, + gl::Error(const gl::Context *contextImpl, size_t, size_t, GLbitfield, void **)); + MOCK_METHOD2(unmap, gl::Error(const gl::Context *contextImpl, GLboolean *result)); - MOCK_METHOD5(getIndexRange, gl::Error(GLenum, size_t, size_t, bool, gl::IndexRange *)); + MOCK_METHOD6(getIndexRange, + gl::Error(const gl::Context *, GLenum, size_t, size_t, bool, gl::IndexRange *)); MOCK_METHOD0(destructor, void()); -}; + protected: + gl::BufferState mMockState; +}; } -#endif // LIBANGLE_RENDERER_BUFFERIMPLMOCK_H_ +#endif // LIBANGLE_RENDERER_BUFFERIMPLMOCK_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/ContextImpl.cpp b/src/3rdparty/angle/src/libANGLE/renderer/ContextImpl.cpp new file mode 100644 index 0000000000..8d3df291d3 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/ContextImpl.cpp @@ -0,0 +1,119 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ContextImpl: +// Implementation-specific functionality associated with a GL Context. +// + +#include "libANGLE/renderer/ContextImpl.h" + +namespace rx +{ + +ContextImpl::ContextImpl(const gl::ContextState &state) + : mState(state), mMemoryProgramCache(nullptr) +{ +} + +ContextImpl::~ContextImpl() +{ +} + +void ContextImpl::stencilFillPath(const gl::Path *path, GLenum fillMode, GLuint mask) +{ + UNREACHABLE(); +} + +void ContextImpl::stencilStrokePath(const gl::Path *path, GLint reference, GLuint mask) +{ + UNREACHABLE(); +} + +void ContextImpl::coverFillPath(const gl::Path *path, GLenum coverMode) +{ + UNREACHABLE(); +} + +void ContextImpl::coverStrokePath(const gl::Path *path, GLenum coverMode) +{ + UNREACHABLE(); +} + +void ContextImpl::stencilThenCoverFillPath(const gl::Path *path, + GLenum fillMode, + GLuint mask, + GLenum coverMode) +{ + UNREACHABLE(); +} + +void ContextImpl::stencilThenCoverStrokePath(const gl::Path *path, + GLint reference, + GLuint mask, + GLenum coverMode) +{ + UNREACHABLE(); +} + +void ContextImpl::coverFillPathInstanced(const std::vector &paths, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + UNREACHABLE(); +} + +void ContextImpl::coverStrokePathInstanced(const std::vector &paths, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + UNREACHABLE(); +} + +void ContextImpl::stencilFillPathInstanced(const std::vector &paths, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + UNREACHABLE(); +} + +void ContextImpl::stencilStrokePathInstanced(const std::vector &paths, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + UNREACHABLE(); +} + +void ContextImpl::stencilThenCoverFillPathInstanced(const std::vector &paths, + GLenum coverMode, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + UNREACHABLE(); +} + +void ContextImpl::stencilThenCoverStrokePathInstanced(const std::vector &paths, + GLenum coverMode, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + UNREACHABLE(); +} + +void ContextImpl::setMemoryProgramCache(gl::MemoryProgramCache *memoryProgramCache) +{ + mMemoryProgramCache = memoryProgramCache; +} + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/ContextImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/ContextImpl.h new file mode 100644 index 0000000000..7ba4b5ad2d --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/ContextImpl.h @@ -0,0 +1,186 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ContextImpl: +// Implementation-specific functionality associated with a GL Context. +// + +#ifndef LIBANGLE_RENDERER_CONTEXTIMPL_H_ +#define LIBANGLE_RENDERER_CONTEXTIMPL_H_ + +#include + +#include "common/angleutils.h" +#include "libANGLE/ContextState.h" +#include "libANGLE/renderer/GLImplFactory.h" + +namespace gl +{ +class MemoryProgramCache; +class Path; +struct Workarounds; +} + +namespace rx +{ +class ContextImpl : public GLImplFactory +{ + public: + ContextImpl(const gl::ContextState &state); + ~ContextImpl() override; + + virtual void onDestroy(const gl::Context *context) {} + + virtual gl::Error initialize() = 0; + + // Flush and finish. + virtual gl::Error flush(const gl::Context *context) = 0; + virtual gl::Error finish(const gl::Context *context) = 0; + + // Drawing methods. + virtual gl::Error drawArrays(const gl::Context *context, + GLenum mode, + GLint first, + GLsizei count) = 0; + virtual gl::Error drawArraysInstanced(const gl::Context *context, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instanceCount) = 0; + + virtual gl::Error drawElements(const gl::Context *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices) = 0; + virtual gl::Error drawElementsInstanced(const gl::Context *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei instances) = 0; + virtual gl::Error drawRangeElements(const gl::Context *context, + GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const void *indices) = 0; + + virtual gl::Error drawArraysIndirect(const gl::Context *context, + GLenum mode, + const void *indirect) = 0; + virtual gl::Error drawElementsIndirect(const gl::Context *context, + GLenum mode, + GLenum type, + const void *indirect) = 0; + + // CHROMIUM_path_rendering path drawing methods. + virtual void stencilFillPath(const gl::Path *path, GLenum fillMode, GLuint mask); + virtual void stencilStrokePath(const gl::Path *path, GLint reference, GLuint mask); + virtual void coverFillPath(const gl::Path *path, GLenum coverMode); + virtual void coverStrokePath(const gl::Path *path, GLenum coverMode); + virtual void stencilThenCoverFillPath(const gl::Path *path, + GLenum fillMode, + GLuint mask, + GLenum coverMode); + + virtual void stencilThenCoverStrokePath(const gl::Path *path, + GLint reference, + GLuint mask, + GLenum coverMode); + + virtual void coverFillPathInstanced(const std::vector &paths, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); + virtual void coverStrokePathInstanced(const std::vector &paths, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); + virtual void stencilFillPathInstanced(const std::vector &paths, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); + virtual void stencilStrokePathInstanced(const std::vector &paths, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); + virtual void stencilThenCoverFillPathInstanced(const std::vector &paths, + GLenum coverMode, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); + virtual void stencilThenCoverStrokePathInstanced(const std::vector &paths, + GLenum coverMode, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); + + // Device loss + virtual GLenum getResetStatus() = 0; + + // Vendor and description strings. + virtual std::string getVendorString() const = 0; + virtual std::string getRendererDescription() const = 0; + + // EXT_debug_marker + virtual void insertEventMarker(GLsizei length, const char *marker) = 0; + virtual void pushGroupMarker(GLsizei length, const char *marker) = 0; + virtual void popGroupMarker() = 0; + + // KHR_debug + virtual void pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message) = 0; + virtual void popDebugGroup() = 0; + + // State sync with dirty bits. + virtual void syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits) = 0; + + // Disjoint timer queries + virtual GLint getGPUDisjoint() = 0; + virtual GLint64 getTimestamp() = 0; + + // Context switching + virtual void onMakeCurrent(const gl::Context *context) = 0; + + // Native capabilities, unmodified by gl::Context. + virtual const gl::Caps &getNativeCaps() const = 0; + virtual const gl::TextureCapsMap &getNativeTextureCaps() const = 0; + virtual const gl::Extensions &getNativeExtensions() const = 0; + virtual const gl::Limitations &getNativeLimitations() const = 0; + + virtual void applyNativeWorkarounds(gl::Workarounds *workarounds) const {} + + virtual gl::Error dispatchCompute(const gl::Context *context, + GLuint numGroupsX, + GLuint numGroupsY, + GLuint numGroupsZ) = 0; + + const gl::ContextState &getContextState() { return mState; } + int getClientMajorVersion() const { return mState.getClientMajorVersion(); } + int getClientMinorVersion() const { return mState.getClientMinorVersion(); } + const gl::State &getGLState() const { return mState.getState(); } + const gl::Caps &getCaps() const { return mState.getCaps(); } + const gl::TextureCapsMap &getTextureCaps() const { return mState.getTextureCaps(); } + const gl::Extensions &getExtensions() const { return mState.getExtensions(); } + const gl::Limitations &getLimitations() const { return mState.getLimitations(); } + + // A common GL driver behaviour is to trigger dynamic shader recompilation on a draw call, + // based on the current render states. We store a mutable pointer to the program cache so + // on draw calls we can store the refreshed shaders in the cache. + void setMemoryProgramCache(gl::MemoryProgramCache *memoryProgramCache); + + protected: + const gl::ContextState &mState; + gl::MemoryProgramCache *mMemoryProgramCache; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_CONTEXTIMPL_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/DisplayImpl.cpp b/src/3rdparty/angle/src/libANGLE/renderer/DisplayImpl.cpp index 8061189f0a..5cc9da96dc 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/DisplayImpl.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/DisplayImpl.cpp @@ -8,26 +8,20 @@ #include "libANGLE/renderer/DisplayImpl.h" +#include "libANGLE/Display.h" #include "libANGLE/Surface.h" namespace rx { -DisplayImpl::DisplayImpl() - : mExtensionsInitialized(false), - mCapsInitialized(false) +DisplayImpl::DisplayImpl(const egl::DisplayState &state) + : mState(state), mExtensionsInitialized(false), mCapsInitialized(false) { } DisplayImpl::~DisplayImpl() { - ASSERT(mSurfaceSet.empty()); -} - -void DisplayImpl::destroySurface(egl::Surface *surface) -{ - mSurfaceSet.erase(surface); - surface->onDestroy(); + ASSERT(mState.surfaceSet.empty()); } const egl::DisplayExtensions &DisplayImpl::getExtensions() const @@ -41,6 +35,15 @@ const egl::DisplayExtensions &DisplayImpl::getExtensions() const return mExtensions; } +egl::Error DisplayImpl::validateClientBuffer(const egl::Config *configuration, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const egl::AttributeMap &attribs) const +{ + UNREACHABLE(); + return egl::EglBadDisplay() << "DisplayImpl::validateClientBuffer unimplemented."; +} + const egl::Caps &DisplayImpl::getCaps() const { if (!mCapsInitialized) @@ -52,4 +55,4 @@ const egl::Caps &DisplayImpl::getCaps() const return mCaps; } -} +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/DisplayImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/DisplayImpl.h index 9e38f63370..b1c49d9bc8 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/DisplayImpl.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/DisplayImpl.h @@ -13,7 +13,9 @@ #include "libANGLE/Caps.h" #include "libANGLE/Config.h" #include "libANGLE/Error.h" -#include "libANGLE/renderer/Renderer.h" +#include "libANGLE/renderer/EGLImplFactory.h" +#include "libANGLE/Stream.h" +#include "libANGLE/Version.h" #include #include @@ -22,9 +24,11 @@ namespace egl { class AttributeMap; class Display; +struct DisplayState; struct Config; class Surface; class ImageSibling; +class Thread; } namespace gl @@ -38,69 +42,43 @@ class SurfaceImpl; class ImageImpl; struct ConfigDesc; class DeviceImpl; +class StreamProducerImpl; -class DisplayImpl : angle::NonCopyable +class DisplayImpl : public EGLImplFactory { public: - DisplayImpl(); - virtual ~DisplayImpl(); + DisplayImpl(const egl::DisplayState &state); + ~DisplayImpl() override; virtual egl::Error initialize(egl::Display *display) = 0; virtual void terminate() = 0; - virtual SurfaceImpl *createWindowSurface(const egl::Config *configuration, - EGLNativeWindowType window, - const egl::AttributeMap &attribs) = 0; - virtual SurfaceImpl *createPbufferSurface(const egl::Config *configuration, - const egl::AttributeMap &attribs) = 0; - virtual SurfaceImpl *createPbufferFromClientBuffer(const egl::Config *configuration, - EGLClientBuffer shareHandle, - const egl::AttributeMap &attribs) = 0; - virtual SurfaceImpl *createPixmapSurface(const egl::Config *configuration, - NativePixmapType nativePixmap, - const egl::AttributeMap &attribs) = 0; - - virtual ImageImpl *createImage(EGLenum target, - egl::ImageSibling *buffer, - const egl::AttributeMap &attribs) = 0; - - virtual gl::Context *createContext(const egl::Config *config, - const gl::Context *shareContext, - const egl::AttributeMap &attribs) = 0; - virtual egl::Error makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context) = 0; - virtual egl::ConfigSet generateConfigs() const = 0; + virtual egl::ConfigSet generateConfigs() = 0; - virtual bool isDeviceLost() const = 0; virtual bool testDeviceLost() = 0; - virtual egl::Error restoreLostDevice() = 0; + virtual egl::Error restoreLostDevice(const egl::Display *display) = 0; virtual bool isValidNativeWindow(EGLNativeWindowType window) const = 0; + virtual egl::Error validateClientBuffer(const egl::Config *configuration, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const egl::AttributeMap &attribs) const; virtual std::string getVendorString() const = 0; virtual egl::Error getDevice(DeviceImpl **device) = 0; - virtual egl::Error waitClient() const = 0; - virtual egl::Error waitNative(EGLint engine, - egl::Surface *drawSurface, - egl::Surface *readSurface) const = 0; - + virtual egl::Error waitClient(const gl::Context *context) const = 0; + virtual egl::Error waitNative(const gl::Context *context, EGLint engine) const = 0; + virtual gl::Version getMaxSupportedESVersion() const = 0; const egl::Caps &getCaps() const; - typedef std::set SurfaceSet; - const SurfaceSet &getSurfaceSet() const { return mSurfaceSet; } - SurfaceSet &getSurfaceSet() { return mSurfaceSet; } - - void destroySurface(egl::Surface *surface); - const egl::DisplayExtensions &getExtensions() const; protected: - // Place the surface set here so it can be accessible for handling - // context loss events. (It is shared between the Display and Impl.) - SurfaceSet mSurfaceSet; + const egl::DisplayState &mState; private: virtual void generateExtensions(egl::DisplayExtensions *outExtensions) const = 0; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/EGLImplFactory.h b/src/3rdparty/angle/src/libANGLE/renderer/EGLImplFactory.h new file mode 100644 index 0000000000..0433364cd3 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/EGLImplFactory.h @@ -0,0 +1,68 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// EGLImplFactory.h: +// Factory interface for EGL Impl objects. +// + +#ifndef LIBANGLE_RENDERER_EGLIMPLFACTORY_H_ +#define LIBANGLE_RENDERER_EGLIMPLFACTORY_H_ + +#include "libANGLE/Stream.h" + +namespace egl +{ +class AttributeMap; +struct Config; +class ImageSibling; +struct ImageState; +struct SurfaceState; +} + +namespace gl +{ +class Context; +class ContextState; +} + +namespace rx +{ +class ContextImpl; +class ImageImpl; +class SurfaceImpl; + +class EGLImplFactory : angle::NonCopyable +{ + public: + EGLImplFactory() {} + virtual ~EGLImplFactory() {} + + virtual SurfaceImpl *createWindowSurface(const egl::SurfaceState &state, + EGLNativeWindowType window, + const egl::AttributeMap &attribs) = 0; + virtual SurfaceImpl *createPbufferSurface(const egl::SurfaceState &state, + const egl::AttributeMap &attribs) = 0; + virtual SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const egl::AttributeMap &attribs) = 0; + virtual SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state, + NativePixmapType nativePixmap, + const egl::AttributeMap &attribs) = 0; + + virtual ImageImpl *createImage(const egl::ImageState &state, + EGLenum target, + const egl::AttributeMap &attribs) = 0; + + virtual ContextImpl *createContext(const gl::ContextState &state) = 0; + + virtual StreamProducerImpl *createStreamProducerD3DTextureNV12( + egl::Stream::ConsumerType consumerType, + const egl::AttributeMap &attribs) = 0; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_EGLIMPLFACTORY_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/Format.h b/src/3rdparty/angle/src/libANGLE/renderer/Format.h new file mode 100644 index 0000000000..66bdace3e9 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/Format.h @@ -0,0 +1,105 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Format: +// A universal description of typed GPU storage. Across multiple +// renderer back-ends, there are common formats and some distinct +// permutations, this enum encapsulates them all. Formats apply to +// textures, but could also apply to any typed data. + +#ifndef LIBANGLE_RENDERER_FORMAT_H_ +#define LIBANGLE_RENDERER_FORMAT_H_ + +#include "libANGLE/renderer/renderer_utils.h" + +namespace angle +{ + +struct Format final : private angle::NonCopyable +{ + enum class ID; + + constexpr Format(ID id, + GLenum glFormat, + GLenum fboFormat, + rx::MipGenerationFunction mipGen, + const rx::FastCopyFunctionMap &fastCopyFunctions, + rx::ColorReadFunction colorRead, + rx::ColorWriteFunction colorWrite, + GLenum componentType, + GLuint redBits, + GLuint greenBits, + GLuint blueBits, + GLuint alphaBits, + GLuint depthBits, + GLuint stencilBits); + + static const Format &Get(ID id); + static ID InternalFormatToID(GLenum internalFormat); + + ID id; + + // The closest matching GL internal format for the storage this format uses. Note that this + // may be a different internal format than the one this ANGLE format is used for. + GLenum glInternalFormat; + + // The format we should report to the GL layer when querying implementation formats from a FBO. + // This might not be the same as the glInternalFormat, since some DXGI formats don't have + // matching GL format enums, like BGRA4, BGR5A1 and B5G6R6. + GLenum fboImplementationInternalFormat; + + rx::MipGenerationFunction mipGenerationFunction; + rx::ColorReadFunction colorReadFunction; + rx::ColorWriteFunction colorWriteFunction; + + // A map from a gl::FormatType to a fast pixel copy function for this format. + const rx::FastCopyFunctionMap &fastCopyFunctions; + + GLenum componentType; + + GLuint redBits; + GLuint greenBits; + GLuint blueBits; + GLuint alphaBits; + GLuint depthBits; + GLuint stencilBits; +}; + +constexpr Format::Format(ID id, + GLenum glFormat, + GLenum fboFormat, + rx::MipGenerationFunction mipGen, + const rx::FastCopyFunctionMap &fastCopyFunctions, + rx::ColorReadFunction colorRead, + rx::ColorWriteFunction colorWrite, + GLenum componentType, + GLuint redBits, + GLuint greenBits, + GLuint blueBits, + GLuint alphaBits, + GLuint depthBits, + GLuint stencilBits) + : id(id), + glInternalFormat(glFormat), + fboImplementationInternalFormat(fboFormat), + mipGenerationFunction(mipGen), + colorReadFunction(colorRead), + colorWriteFunction(colorWrite), + fastCopyFunctions(fastCopyFunctions), + componentType(componentType), + redBits(redBits), + greenBits(greenBits), + blueBits(blueBits), + alphaBits(alphaBits), + depthBits(depthBits), + stencilBits(stencilBits) +{ +} + +} // namespace angle + +#include "libANGLE/renderer/Format_ID_autogen.inl" + +#endif // LIBANGLE_RENDERER_FORMAT_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/Format_ID_autogen.inl b/src/3rdparty/angle/src/libANGLE/renderer/Format_ID_autogen.inl new file mode 100644 index 0000000000..b2cbfb0410 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/Format_ID_autogen.inl @@ -0,0 +1,147 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_angle_format_table.py using data from angle_format_data.json +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ANGLE format enumeration. + +namespace angle +{ + +enum class Format::ID +{ + NONE, + A16_FLOAT, + A32_FLOAT, + A8_UNORM, + ASTC_10x10_SRGB_BLOCK, + ASTC_10x10_UNORM_BLOCK, + ASTC_10x5_SRGB_BLOCK, + ASTC_10x5_UNORM_BLOCK, + ASTC_10x6_SRGB_BLOCK, + ASTC_10x6_UNORM_BLOCK, + ASTC_10x8_SRGB_BLOCK, + ASTC_10x8_UNORM_BLOCK, + ASTC_12x10_SRGB_BLOCK, + ASTC_12x10_UNORM_BLOCK, + ASTC_12x12_SRGB_BLOCK, + ASTC_12x12_UNORM_BLOCK, + ASTC_4x4_SRGB_BLOCK, + ASTC_4x4_UNORM_BLOCK, + ASTC_5x4_SRGB_BLOCK, + ASTC_5x4_UNORM_BLOCK, + ASTC_5x5_SRGB_BLOCK, + ASTC_5x5_UNORM_BLOCK, + ASTC_6x5_SRGB_BLOCK, + ASTC_6x5_UNORM_BLOCK, + ASTC_6x6_SRGB_BLOCK, + ASTC_6x6_UNORM_BLOCK, + ASTC_8x5_SRGB_BLOCK, + ASTC_8x5_UNORM_BLOCK, + ASTC_8x6_SRGB_BLOCK, + ASTC_8x6_UNORM_BLOCK, + ASTC_8x8_SRGB_BLOCK, + ASTC_8x8_UNORM_BLOCK, + B4G4R4A4_UNORM, + B5G5R5A1_UNORM, + B5G6R5_UNORM, + B8G8R8A8_UNORM, + B8G8R8A8_UNORM_SRGB, + B8G8R8X8_UNORM, + BC1_RGBA_UNORM_BLOCK, + BC1_RGBA_UNORM_SRGB_BLOCK, + BC1_RGB_UNORM_BLOCK, + BC1_RGB_UNORM_SRGB_BLOCK, + BC2_RGBA_UNORM_BLOCK, + BC2_RGBA_UNORM_SRGB_BLOCK, + BC3_RGBA_UNORM_BLOCK, + BC3_RGBA_UNORM_SRGB_BLOCK, + D16_UNORM, + D24_UNORM, + D24_UNORM_S8_UINT, + D32_FLOAT, + D32_FLOAT_S8X24_UINT, + D32_UNORM, + EAC_R11G11_SNORM_BLOCK, + EAC_R11G11_UNORM_BLOCK, + EAC_R11_SNORM_BLOCK, + EAC_R11_UNORM_BLOCK, + ETC1_LOSSY_DECODE_R8G8B8_UNORM_BLOCK, + ETC1_R8G8B8_UNORM_BLOCK, + ETC2_R8G8B8A1_SRGB_BLOCK, + ETC2_R8G8B8A1_UNORM_BLOCK, + ETC2_R8G8B8A8_SRGB_BLOCK, + ETC2_R8G8B8A8_UNORM_BLOCK, + ETC2_R8G8B8_SRGB_BLOCK, + ETC2_R8G8B8_UNORM_BLOCK, + L16A16_FLOAT, + L16_FLOAT, + L32A32_FLOAT, + L32_FLOAT, + L8A8_UNORM, + L8_UNORM, + R10G10B10A2_UINT, + R10G10B10A2_UNORM, + R11G11B10_FLOAT, + R16G16B16A16_FLOAT, + R16G16B16A16_SINT, + R16G16B16A16_SNORM, + R16G16B16A16_UINT, + R16G16B16A16_UNORM, + R16G16B16_FLOAT, + R16G16B16_SINT, + R16G16B16_SNORM, + R16G16B16_UINT, + R16G16B16_UNORM, + R16G16_FLOAT, + R16G16_SINT, + R16G16_SNORM, + R16G16_UINT, + R16G16_UNORM, + R16_FLOAT, + R16_SINT, + R16_SNORM, + R16_UINT, + R16_UNORM, + R32G32B32A32_FLOAT, + R32G32B32A32_SINT, + R32G32B32A32_UINT, + R32G32B32_FLOAT, + R32G32B32_SINT, + R32G32B32_UINT, + R32G32_FLOAT, + R32G32_SINT, + R32G32_UINT, + R32_FLOAT, + R32_SINT, + R32_UINT, + R4G4B4A4_UNORM, + R5G5B5A1_UNORM, + R5G6B5_UNORM, + R8G8B8A8_SINT, + R8G8B8A8_SNORM, + R8G8B8A8_UINT, + R8G8B8A8_UNORM, + R8G8B8A8_UNORM_SRGB, + R8G8B8_SINT, + R8G8B8_SNORM, + R8G8B8_UINT, + R8G8B8_UNORM, + R8G8B8_UNORM_SRGB, + R8G8_SINT, + R8G8_SNORM, + R8G8_UINT, + R8G8_UNORM, + R8_SINT, + R8_SNORM, + R8_UINT, + R8_UNORM, + R9G9B9E5_SHAREDEXP, + S8_UINT +}; + +constexpr uint32_t kNumANGLEFormats = 128; + +} // namespace angle diff --git a/src/3rdparty/angle/src/libANGLE/renderer/Format_table_autogen.cpp b/src/3rdparty/angle/src/libANGLE/renderer/Format_table_autogen.cpp new file mode 100644 index 0000000000..ecb3ad231a --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/Format_table_autogen.cpp @@ -0,0 +1,434 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_angle_format_table.py using data from angle_format_data.json +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ANGLE Format table: +// Queries for typed format information from the ANGLE format enum. + +#include "libANGLE/renderer/Format.h" + +#include "image_util/copyimage.h" +#include "image_util/generatemip.h" +#include "image_util/loadimage.h" + +namespace angle +{ + +static constexpr rx::FastCopyFunctionMap::Entry BGRAEntry = {GL_RGBA, GL_UNSIGNED_BYTE, + CopyBGRA8ToRGBA8}; +static constexpr rx::FastCopyFunctionMap BGRACopyFunctions = {&BGRAEntry, 1}; +static constexpr rx::FastCopyFunctionMap NoCopyFunctions; + +constexpr Format g_formatInfoTable[] = { + // clang-format off + { Format::ID::NONE, GL_NONE, GL_NONE, nullptr, NoCopyFunctions, nullptr, nullptr, GL_NONE, 0, 0, 0, 0, 0, 0 }, + { Format::ID::A16_FLOAT, GL_ALPHA16F_EXT, GL_ALPHA16F_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 0, 0, 0, 16, 0, 0 }, + { Format::ID::A32_FLOAT, GL_ALPHA32F_EXT, GL_ALPHA32F_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 0, 0, 0, 32, 0, 0 }, + { Format::ID::A8_UNORM, GL_ALPHA8_EXT, GL_ALPHA8_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 8, 0, 0 }, + { Format::ID::ASTC_10x10_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::ASTC_10x10_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_10x10_KHR, GL_COMPRESSED_RGBA_ASTC_10x10_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::ASTC_10x5_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::ASTC_10x5_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_10x5_KHR, GL_COMPRESSED_RGBA_ASTC_10x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::ASTC_10x6_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::ASTC_10x6_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_10x6_KHR, GL_COMPRESSED_RGBA_ASTC_10x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::ASTC_10x8_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::ASTC_10x8_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_10x8_KHR, GL_COMPRESSED_RGBA_ASTC_10x8_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::ASTC_12x10_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::ASTC_12x10_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_12x10_KHR, GL_COMPRESSED_RGBA_ASTC_12x10_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::ASTC_12x12_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::ASTC_12x12_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_12x12_KHR, GL_COMPRESSED_RGBA_ASTC_12x12_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::ASTC_4x4_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::ASTC_4x4_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_4x4_KHR, GL_COMPRESSED_RGBA_ASTC_4x4_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::ASTC_5x4_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::ASTC_5x4_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_5x4_KHR, GL_COMPRESSED_RGBA_ASTC_5x4_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::ASTC_5x5_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::ASTC_5x5_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_5x5_KHR, GL_COMPRESSED_RGBA_ASTC_5x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::ASTC_6x5_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::ASTC_6x5_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_6x5_KHR, GL_COMPRESSED_RGBA_ASTC_6x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::ASTC_6x6_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::ASTC_6x6_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_6x6_KHR, GL_COMPRESSED_RGBA_ASTC_6x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::ASTC_8x5_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::ASTC_8x5_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_8x5_KHR, GL_COMPRESSED_RGBA_ASTC_8x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::ASTC_8x6_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::ASTC_8x6_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_8x6_KHR, GL_COMPRESSED_RGBA_ASTC_8x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::ASTC_8x8_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::ASTC_8x8_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_8x8_KHR, GL_COMPRESSED_RGBA_ASTC_8x8_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::B4G4R4A4_UNORM, GL_BGRA4_ANGLEX, GL_RGBA4, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 4, 4, 4, 4, 0, 0 }, + { Format::ID::B5G5R5A1_UNORM, GL_BGR5_A1_ANGLEX, GL_RGB5_A1, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 5, 5, 5, 1, 0, 0 }, + { Format::ID::B5G6R5_UNORM, GL_BGR565_ANGLEX, GL_RGB565, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 5, 6, 5, 0, 0, 0 }, + { Format::ID::B8G8R8A8_UNORM, GL_BGRA8_EXT, GL_BGRA8_EXT, GenerateMip, BGRACopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0 }, + { Format::ID::B8G8R8A8_UNORM_SRGB, GL_BGRA8_SRGB_ANGLEX, GL_BGRA8_SRGB_ANGLEX, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0 }, + { Format::ID::B8G8R8X8_UNORM, GL_BGRA8_EXT, GL_BGRA8_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0 }, + { Format::ID::BC1_RGBA_UNORM_BLOCK, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::BC1_RGBA_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::BC1_RGB_UNORM_BLOCK, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::BC1_RGB_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::BC2_RGBA_UNORM_BLOCK, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::BC2_RGBA_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::BC3_RGBA_UNORM_BLOCK, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::BC3_RGBA_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::D16_UNORM, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT16, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 16, 0 }, + { Format::ID::D24_UNORM, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT24, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 24, 0 }, + { Format::ID::D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 24, 8 }, + { Format::ID::D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, nullptr, NoCopyFunctions, nullptr, nullptr, GL_FLOAT, 0, 0, 0, 0, 32, 0 }, + { Format::ID::D32_FLOAT_S8X24_UINT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, nullptr, NoCopyFunctions, nullptr, nullptr, GL_FLOAT, 0, 0, 0, 0, 32, 8 }, + { Format::ID::D32_UNORM, GL_DEPTH_COMPONENT32_OES, GL_DEPTH_COMPONENT32_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 32, 0 }, + { Format::ID::EAC_R11G11_SNORM_BLOCK, GL_COMPRESSED_SIGNED_RG11_EAC, GL_COMPRESSED_SIGNED_RG11_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_SIGNED_NORMALIZED, 11, 11, 0, 0, 0, 0 }, + { Format::ID::EAC_R11G11_UNORM_BLOCK, GL_COMPRESSED_RG11_EAC, GL_COMPRESSED_RG11_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 11, 11, 0, 0, 0, 0 }, + { Format::ID::EAC_R11_SNORM_BLOCK, GL_COMPRESSED_SIGNED_R11_EAC, GL_COMPRESSED_SIGNED_R11_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_SIGNED_NORMALIZED, 11, 0, 0, 0, 0, 0 }, + { Format::ID::EAC_R11_UNORM_BLOCK, GL_COMPRESSED_R11_EAC, GL_COMPRESSED_R11_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 11, 0, 0, 0, 0, 0 }, + { Format::ID::ETC1_LOSSY_DECODE_R8G8B8_UNORM_BLOCK, GL_ETC1_RGB8_LOSSY_DECODE_ANGLE, GL_ETC1_RGB8_LOSSY_DECODE_ANGLE, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0 }, + { Format::ID::ETC1_R8G8B8_UNORM_BLOCK, GL_ETC1_RGB8_OES, GL_ETC1_RGB8_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0 }, + { Format::ID::ETC2_R8G8B8A1_SRGB_BLOCK, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 1, 0, 0 }, + { Format::ID::ETC2_R8G8B8A1_UNORM_BLOCK, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 1, 0, 0 }, + { Format::ID::ETC2_R8G8B8A8_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0 }, + { Format::ID::ETC2_R8G8B8A8_UNORM_BLOCK, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_COMPRESSED_RGBA8_ETC2_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0 }, + { Format::ID::ETC2_R8G8B8_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ETC2, GL_COMPRESSED_SRGB8_ETC2, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0 }, + { Format::ID::ETC2_R8G8B8_UNORM_BLOCK, GL_COMPRESSED_RGB8_ETC2, GL_COMPRESSED_RGB8_ETC2, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0 }, + { Format::ID::L16A16_FLOAT, GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA16F_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 0, 0, 0, 16, 0, 0 }, + { Format::ID::L16_FLOAT, GL_LUMINANCE16F_EXT, GL_LUMINANCE16F_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 0, 0, 0, 0, 0, 0 }, + { Format::ID::L32A32_FLOAT, GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA32F_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 0, 0, 0, 32, 0, 0 }, + { Format::ID::L32_FLOAT, GL_LUMINANCE32F_EXT, GL_LUMINANCE32F_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 0, 0, 0, 0, 0, 0 }, + { Format::ID::L8A8_UNORM, GL_LUMINANCE8_ALPHA8_EXT, GL_LUMINANCE8_ALPHA8_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 8, 0, 0 }, + { Format::ID::L8_UNORM, GL_LUMINANCE8_EXT, GL_LUMINANCE8_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0 }, + { Format::ID::R10G10B10A2_UINT, GL_RGB10_A2UI, GL_RGB10_A2UI, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 10, 10, 10, 2, 0, 0 }, + { Format::ID::R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 10, 10, 10, 2, 0, 0 }, + { Format::ID::R11G11B10_FLOAT, GL_R11F_G11F_B10F, GL_R11F_G11F_B10F, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 11, 11, 10, 0, 0, 0 }, + { Format::ID::R16G16B16A16_FLOAT, GL_RGBA16F, GL_RGBA16F, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 16, 16, 16, 16, 0, 0 }, + { Format::ID::R16G16B16A16_SINT, GL_RGBA16I, GL_RGBA16I, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 16, 16, 16, 16, 0, 0 }, + { Format::ID::R16G16B16A16_SNORM, GL_RGBA16_SNORM_EXT, GL_RGBA16_SNORM_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_SIGNED_NORMALIZED, 16, 16, 16, 16, 0, 0 }, + { Format::ID::R16G16B16A16_UINT, GL_RGBA16UI, GL_RGBA16UI, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 16, 16, 16, 16, 0, 0 }, + { Format::ID::R16G16B16A16_UNORM, GL_RGBA16_EXT, GL_RGBA16_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 16, 16, 16, 16, 0, 0 }, + { Format::ID::R16G16B16_FLOAT, GL_RGB16F, GL_RGB16F, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 16, 16, 16, 0, 0, 0 }, + { Format::ID::R16G16B16_SINT, GL_RGB16I, GL_RGB16I, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 16, 16, 16, 0, 0, 0 }, + { Format::ID::R16G16B16_SNORM, GL_RGB16_SNORM_EXT, GL_RGB16_SNORM_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_SIGNED_NORMALIZED, 16, 16, 16, 0, 0, 0 }, + { Format::ID::R16G16B16_UINT, GL_RGB16UI, GL_RGB16UI, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 16, 16, 16, 0, 0, 0 }, + { Format::ID::R16G16B16_UNORM, GL_RGB16_EXT, GL_RGB16_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 16, 16, 16, 0, 0, 0 }, + { Format::ID::R16G16_FLOAT, GL_RG16F, GL_RG16F, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 16, 16, 0, 0, 0, 0 }, + { Format::ID::R16G16_SINT, GL_RG16I, GL_RG16I, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 16, 16, 0, 0, 0, 0 }, + { Format::ID::R16G16_SNORM, GL_RG16_SNORM_EXT, GL_RG16_SNORM_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_SIGNED_NORMALIZED, 16, 16, 0, 0, 0, 0 }, + { Format::ID::R16G16_UINT, GL_RG16UI, GL_RG16UI, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 16, 16, 0, 0, 0, 0 }, + { Format::ID::R16G16_UNORM, GL_RG16_EXT, GL_RG16_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 16, 16, 0, 0, 0, 0 }, + { Format::ID::R16_FLOAT, GL_R16F, GL_R16F, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 16, 0, 0, 0, 0, 0 }, + { Format::ID::R16_SINT, GL_R16I, GL_R16I, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 16, 0, 0, 0, 0, 0 }, + { Format::ID::R16_SNORM, GL_R16_SNORM_EXT, GL_R16_SNORM_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_SIGNED_NORMALIZED, 16, 0, 0, 0, 0, 0 }, + { Format::ID::R16_UINT, GL_R16UI, GL_R16UI, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 16, 0, 0, 0, 0, 0 }, + { Format::ID::R16_UNORM, GL_R16_EXT, GL_R16_EXT, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 16, 0, 0, 0, 0, 0 }, + { Format::ID::R32G32B32A32_FLOAT, GL_RGBA32F, GL_RGBA32F, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 32, 32, 32, 32, 0, 0 }, + { Format::ID::R32G32B32A32_SINT, GL_RGBA32I, GL_RGBA32I, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 32, 32, 32, 32, 0, 0 }, + { Format::ID::R32G32B32A32_UINT, GL_RGBA32UI, GL_RGBA32UI, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 32, 32, 32, 32, 0, 0 }, + { Format::ID::R32G32B32_FLOAT, GL_RGB32F, GL_RGB32F, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 32, 32, 32, 0, 0, 0 }, + { Format::ID::R32G32B32_SINT, GL_RGB32I, GL_RGB32I, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 32, 32, 32, 0, 0, 0 }, + { Format::ID::R32G32B32_UINT, GL_RGB32UI, GL_RGB32UI, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 32, 32, 32, 0, 0, 0 }, + { Format::ID::R32G32_FLOAT, GL_RG32F, GL_RG32F, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 32, 32, 0, 0, 0, 0 }, + { Format::ID::R32G32_SINT, GL_RG32I, GL_RG32I, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 32, 32, 0, 0, 0, 0 }, + { Format::ID::R32G32_UINT, GL_RG32UI, GL_RG32UI, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 32, 32, 0, 0, 0, 0 }, + { Format::ID::R32_FLOAT, GL_R32F, GL_R32F, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 32, 0, 0, 0, 0, 0 }, + { Format::ID::R32_SINT, GL_R32I, GL_R32I, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 32, 0, 0, 0, 0, 0 }, + { Format::ID::R32_UINT, GL_R32UI, GL_R32UI, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 32, 0, 0, 0, 0, 0 }, + { Format::ID::R4G4B4A4_UNORM, GL_RGBA4, GL_RGBA4, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 4, 4, 4, 4, 0, 0 }, + { Format::ID::R5G5B5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 5, 5, 5, 1, 0, 0 }, + { Format::ID::R5G6B5_UNORM, GL_RGB565, GL_RGB565, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 5, 6, 5, 0, 0, 0 }, + { Format::ID::R8G8B8A8_SINT, GL_RGBA8I, GL_RGBA8I, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 8, 8, 8, 8, 0, 0 }, + { Format::ID::R8G8B8A8_SNORM, GL_RGBA8_SNORM, GL_RGBA8_SNORM, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_SIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0 }, + { Format::ID::R8G8B8A8_UINT, GL_RGBA8UI, GL_RGBA8UI, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 8, 8, 8, 8, 0, 0 }, + { Format::ID::R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0 }, + { Format::ID::R8G8B8A8_UNORM_SRGB, GL_SRGB8_ALPHA8, GL_SRGB8_ALPHA8, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0 }, + { Format::ID::R8G8B8_SINT, GL_RGB8I, GL_RGB8I, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 8, 8, 8, 0, 0, 0 }, + { Format::ID::R8G8B8_SNORM, GL_RGB8_SNORM, GL_RGB8_SNORM, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_SIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0 }, + { Format::ID::R8G8B8_UINT, GL_RGB8UI, GL_RGB8UI, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 8, 8, 8, 0, 0, 0 }, + { Format::ID::R8G8B8_UNORM, GL_RGB8, GL_RGB8, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0 }, + { Format::ID::R8G8B8_UNORM_SRGB, GL_SRGB8, GL_SRGB8, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0 }, + { Format::ID::R8G8_SINT, GL_RG8I, GL_RG8I, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 8, 8, 0, 0, 0, 0 }, + { Format::ID::R8G8_SNORM, GL_RG8_SNORM, GL_RG8_SNORM, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_SIGNED_NORMALIZED, 8, 8, 0, 0, 0, 0 }, + { Format::ID::R8G8_UINT, GL_RG8UI, GL_RG8UI, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 8, 8, 0, 0, 0, 0 }, + { Format::ID::R8G8_UNORM, GL_RG8, GL_RG8, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 8, 0, 0, 0, 0 }, + { Format::ID::R8_SINT, GL_R8I, GL_R8I, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_INT, 8, 0, 0, 0, 0, 0 }, + { Format::ID::R8_SNORM, GL_R8_SNORM, GL_R8_SNORM, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_SIGNED_NORMALIZED, 8, 0, 0, 0, 0, 0 }, + { Format::ID::R8_UINT, GL_R8UI, GL_R8UI, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_INT, 8, 0, 0, 0, 0, 0 }, + { Format::ID::R8_UNORM, GL_R8, GL_R8, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_UNSIGNED_NORMALIZED, 8, 0, 0, 0, 0, 0 }, + { Format::ID::R9G9B9E5_SHAREDEXP, GL_RGB9_E5, GL_RGB9_E5, GenerateMip, NoCopyFunctions, ReadColor, WriteColor, GL_FLOAT, 9, 9, 9, 0, 0, 0 }, + { Format::ID::S8_UINT, GL_STENCIL_INDEX8, GL_STENCIL_INDEX8, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_INT, 0, 0, 0, 0, 0, 8 }, + // clang-format on +}; + +// static +Format::ID Format::InternalFormatToID(GLenum internalFormat) +{ + switch (internalFormat) + { + case GL_RGBA16_EXT: + return Format::ID::R16G16B16A16_UNORM; + case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: + return Format::ID::ETC1_LOSSY_DECODE_R8G8B8_UNORM_BLOCK; + case GL_RG8I: + return Format::ID::R8G8_SINT; + case GL_R16F: + return Format::ID::R16_FLOAT; + case GL_RGBA8I: + return Format::ID::R8G8B8A8_SINT; + case GL_RG8UI: + return Format::ID::R8G8_UINT; + case GL_RGBA8_SNORM: + return Format::ID::R8G8B8A8_SNORM; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: + return Format::ID::ASTC_12x10_SRGB_BLOCK; + case GL_RG8_SNORM: + return Format::ID::R8G8_SNORM; + case GL_BGR565_ANGLEX: + return Format::ID::B5G6R5_UNORM; + case GL_DEPTH_COMPONENT24: + return Format::ID::D24_UNORM; + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + return Format::ID::ETC2_R8G8B8A1_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_10x10_KHR: + return Format::ID::ASTC_10x10_UNORM_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: + return Format::ID::ASTC_8x6_SRGB_BLOCK; + case GL_RGB32UI: + return Format::ID::R32G32B32_UINT; + case GL_COMPRESSED_RGBA_ASTC_6x5_KHR: + return Format::ID::ASTC_6x5_UNORM_BLOCK; + case GL_ALPHA32F_EXT: + return Format::ID::A32_FLOAT; + case GL_R16UI: + return Format::ID::R16_UINT; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: + return Format::ID::ASTC_5x4_SRGB_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: + return Format::ID::ASTC_5x5_SRGB_BLOCK; + case GL_COMPRESSED_R11_EAC: + return Format::ID::EAC_R11_UNORM_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: + return Format::ID::ASTC_10x10_SRGB_BLOCK; + case GL_RGBA32UI: + return Format::ID::R32G32B32A32_UINT; + case GL_R8_SNORM: + return Format::ID::R8_SNORM; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + return Format::ID::BC1_RGBA_UNORM_SRGB_BLOCK; + case GL_LUMINANCE32F_EXT: + return Format::ID::L32_FLOAT; + case GL_RG16_EXT: + return Format::ID::R16G16_UNORM; + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + return Format::ID::ETC2_R8G8B8A1_SRGB_BLOCK; + case GL_SRGB8: + return Format::ID::R8G8B8_UNORM_SRGB; + case GL_LUMINANCE8_ALPHA8_EXT: + return Format::ID::L8A8_UNORM; + case GL_BGRX8_ANGLEX: + return Format::ID::B8G8R8X8_UNORM; + case GL_RGB16_SNORM_EXT: + return Format::ID::R16G16B16_SNORM; + case GL_RGBA8UI: + return Format::ID::R8G8B8A8_UINT; + case GL_BGRA4_ANGLEX: + return Format::ID::B4G4R4A4_UNORM; + case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + return Format::ID::ETC2_R8G8B8A8_SRGB_BLOCK; + case GL_LUMINANCE8_EXT: + return Format::ID::L8_UNORM; + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + return Format::ID::BC3_RGBA_UNORM_BLOCK; + case GL_R16I: + return Format::ID::R16_SINT; + case GL_RGB5_A1: + return Format::ID::R5G5B5A1_UNORM; + case GL_RGB16UI: + return Format::ID::R16G16B16_UINT; + case GL_COMPRESSED_RGBA_ASTC_4x4_KHR: + return Format::ID::ASTC_4x4_UNORM_BLOCK; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + return Format::ID::BC2_RGBA_UNORM_SRGB_BLOCK; + case GL_R16_SNORM_EXT: + return Format::ID::R16_SNORM; + case GL_COMPRESSED_RGB8_ETC2: + return Format::ID::ETC2_R8G8B8_UNORM_BLOCK; + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + return Format::ID::BC1_RGB_UNORM_SRGB_BLOCK; + case GL_RGBA32F: + return Format::ID::R32G32B32A32_FLOAT; + case GL_RGBA32I: + return Format::ID::R32G32B32A32_SINT; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + return Format::ID::BC3_RGBA_UNORM_SRGB_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_8x5_KHR: + return Format::ID::ASTC_8x5_UNORM_BLOCK; + case GL_RG8: + return Format::ID::R8G8_UNORM; + case GL_COMPRESSED_RGBA_ASTC_8x8_KHR: + return Format::ID::ASTC_8x8_UNORM_BLOCK; + case GL_RGB10_A2: + return Format::ID::R10G10B10A2_UNORM; + case GL_COMPRESSED_SIGNED_RG11_EAC: + return Format::ID::EAC_R11G11_SNORM_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: + return Format::ID::ASTC_6x6_SRGB_BLOCK; + case GL_DEPTH_COMPONENT16: + return Format::ID::D16_UNORM; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: + return Format::ID::ASTC_10x5_SRGB_BLOCK; + case GL_RGB32I: + return Format::ID::R32G32B32_SINT; + case GL_R8: + return Format::ID::R8_UNORM; + case GL_RGB32F: + return Format::ID::R32G32B32_FLOAT; + case GL_R16_EXT: + return Format::ID::R16_UNORM; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: + return Format::ID::ASTC_8x8_SRGB_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_10x5_KHR: + return Format::ID::ASTC_10x5_UNORM_BLOCK; + case GL_R11F_G11F_B10F: + return Format::ID::R11G11B10_FLOAT; + case GL_RGB8: + return Format::ID::R8G8B8_UNORM; + case GL_COMPRESSED_RGBA_ASTC_5x5_KHR: + return Format::ID::ASTC_5x5_UNORM_BLOCK; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: + return Format::ID::ASTC_8x5_SRGB_BLOCK; + case GL_RGBA16I: + return Format::ID::R16G16B16A16_SINT; + case GL_R8I: + return Format::ID::R8_SINT; + case GL_RGB8_SNORM: + return Format::ID::R8G8B8_SNORM; + case GL_RG32F: + return Format::ID::R32G32_FLOAT; + case GL_DEPTH_COMPONENT32F: + return Format::ID::D32_FLOAT; + case GL_RG32I: + return Format::ID::R32G32_SINT; + case GL_ALPHA8_EXT: + return Format::ID::A8_UNORM; + case GL_RGB16_EXT: + return Format::ID::R16G16B16_UNORM; + case GL_BGRA8_EXT: + return Format::ID::B8G8R8A8_UNORM; + case GL_RG32UI: + return Format::ID::R32G32_UINT; + case GL_RGBA16UI: + return Format::ID::R16G16B16A16_UINT; + case GL_COMPRESSED_RGBA8_ETC2_EAC: + return Format::ID::ETC2_R8G8B8A8_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return Format::ID::BC1_RGBA_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_10x6_KHR: + return Format::ID::ASTC_10x6_UNORM_BLOCK; + case GL_COMPRESSED_SRGB8_ETC2: + return Format::ID::ETC2_R8G8B8_SRGB_BLOCK; + case GL_BGRA8_SRGB_ANGLEX: + return Format::ID::B8G8R8A8_UNORM_SRGB; + case GL_DEPTH32F_STENCIL8: + return Format::ID::D32_FLOAT_S8X24_UINT; + case GL_COMPRESSED_RGBA_ASTC_6x6_KHR: + return Format::ID::ASTC_6x6_UNORM_BLOCK; + case GL_R32UI: + return Format::ID::R32_UINT; + case GL_BGR5_A1_ANGLEX: + return Format::ID::B5G5R5A1_UNORM; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: + return Format::ID::ASTC_12x12_SRGB_BLOCK; + case GL_COMPRESSED_RG11_EAC: + return Format::ID::EAC_R11G11_UNORM_BLOCK; + case GL_SRGB8_ALPHA8: + return Format::ID::R8G8B8A8_UNORM_SRGB; + case GL_LUMINANCE_ALPHA16F_EXT: + return Format::ID::L16A16_FLOAT; + case GL_RGBA: + return Format::ID::R8G8B8A8_UNORM; + case GL_ETC1_RGB8_OES: + return Format::ID::ETC1_R8G8B8_UNORM_BLOCK; + case GL_DEPTH24_STENCIL8: + return Format::ID::D24_UNORM_S8_UINT; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: + return Format::ID::ASTC_4x4_SRGB_BLOCK; + case GL_RGB16I: + return Format::ID::R16G16B16_SINT; + case GL_R8UI: + return Format::ID::R8_UINT; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: + return Format::ID::ASTC_10x6_SRGB_BLOCK; + case GL_RGBA16F: + return Format::ID::R16G16B16A16_FLOAT; + case GL_COMPRESSED_SIGNED_R11_EAC: + return Format::ID::EAC_R11_SNORM_BLOCK; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + return Format::ID::BC1_RGB_UNORM_BLOCK; + case GL_RGB8I: + return Format::ID::R8G8B8_SINT; + case GL_COMPRESSED_RGBA_ASTC_8x6_KHR: + return Format::ID::ASTC_8x6_UNORM_BLOCK; + case GL_STENCIL_INDEX8: + return Format::ID::S8_UINT; + case GL_LUMINANCE_ALPHA32F_EXT: + return Format::ID::L32A32_FLOAT; + case GL_ALPHA16F_EXT: + return Format::ID::A16_FLOAT; + case GL_RGB8UI: + return Format::ID::R8G8B8_UINT; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: + return Format::ID::ASTC_10x8_SRGB_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_12x10_KHR: + return Format::ID::ASTC_12x10_UNORM_BLOCK; + case GL_RGB9_E5: + return Format::ID::R9G9B9E5_SHAREDEXP; + case GL_RGBA16_SNORM_EXT: + return Format::ID::R16G16B16A16_SNORM; + case GL_R32I: + return Format::ID::R32_SINT; + case GL_DEPTH_COMPONENT32_OES: + return Format::ID::D32_UNORM; + case GL_R32F: + return Format::ID::R32_FLOAT; + case GL_NONE: + return Format::ID::NONE; + case GL_RG16F: + return Format::ID::R16G16_FLOAT; + case GL_RGB: + return Format::ID::R8G8B8_UNORM; + case GL_RGB565: + return Format::ID::R5G6B5_UNORM; + case GL_LUMINANCE16F_EXT: + return Format::ID::L16_FLOAT; + case GL_RG16UI: + return Format::ID::R16G16_UINT; + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + return Format::ID::BC2_RGBA_UNORM_BLOCK; + case GL_RG16I: + return Format::ID::R16G16_SINT; + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: + return Format::ID::ASTC_6x5_SRGB_BLOCK; + case GL_RG16_SNORM_EXT: + return Format::ID::R16G16_SNORM; + case GL_COMPRESSED_RGBA_ASTC_12x12_KHR: + return Format::ID::ASTC_12x12_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_5x4_KHR: + return Format::ID::ASTC_5x4_UNORM_BLOCK; + case GL_COMPRESSED_RGBA_ASTC_10x8_KHR: + return Format::ID::ASTC_10x8_UNORM_BLOCK; + case GL_RGBA4: + return Format::ID::R4G4B4A4_UNORM; + case GL_RGBA8: + return Format::ID::R8G8B8A8_UNORM; + case GL_RGB16F: + return Format::ID::R16G16B16_FLOAT; + case GL_RGB10_A2UI: + return Format::ID::R10G10B10A2_UINT; + default: + return Format::ID::NONE; + } +} + +// static +const Format &Format::Get(ID id) +{ + return g_formatInfoTable[static_cast(id)]; +} + +} // namespace angle diff --git a/src/3rdparty/angle/src/libANGLE/renderer/FramebufferAttachmentObjectImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/FramebufferAttachmentObjectImpl.h new file mode 100644 index 0000000000..056ddc833a --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/FramebufferAttachmentObjectImpl.h @@ -0,0 +1,54 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// FramebufferAttachmentObjectImpl.h: +// Common ancenstor for all implementations of FBO attachable-objects. +// This means Surfaces, Textures and Renderbuffers. +// + +#ifndef LIBANGLE_RENDERER_FRAMEBUFFER_ATTACHMENT_OBJECT_IMPL_H_ +#define LIBANGLE_RENDERER_FRAMEBUFFER_ATTACHMENT_OBJECT_IMPL_H_ + +#include "libANGLE/FramebufferAttachment.h" + +namespace rx +{ + +class FramebufferAttachmentObjectImpl : angle::NonCopyable +{ + public: + FramebufferAttachmentObjectImpl() {} + virtual ~FramebufferAttachmentObjectImpl() {} + + virtual gl::Error getAttachmentRenderTarget(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex, + FramebufferAttachmentRenderTarget **rtOut); + + virtual gl::Error initializeContents(const gl::Context *context, + const gl::ImageIndex &imageIndex); +}; + +inline gl::Error FramebufferAttachmentObjectImpl::getAttachmentRenderTarget( + const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex, + FramebufferAttachmentRenderTarget **rtOut) +{ + UNIMPLEMENTED(); + return gl::OutOfMemory() << "getAttachmentRenderTarget not supported."; +} + +inline gl::Error FramebufferAttachmentObjectImpl::initializeContents( + const gl::Context *context, + const gl::ImageIndex &imageIndex) +{ + UNIMPLEMENTED(); + return gl::OutOfMemory() << "initialize not supported."; +} + +} // namespace rx + +#endif // LIBANGLE_RENDERER_FRAMEBUFFER_ATTACHMENT_OBJECT_IMPL_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/FramebufferImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/FramebufferImpl.h index 680122d0ed..ebb166ca80 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/FramebufferImpl.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/FramebufferImpl.h @@ -24,53 +24,72 @@ struct Rectangle; namespace rx { +class DisplayImpl; class FramebufferImpl : angle::NonCopyable { public: - explicit FramebufferImpl(const gl::Framebuffer::Data &data) : mData(data) { } - virtual ~FramebufferImpl() { } + explicit FramebufferImpl(const gl::FramebufferState &state) : mState(state) {} + virtual ~FramebufferImpl() {} + virtual void destroy(const gl::Context *context) {} + virtual void destroyDefault(const egl::Display *display) {} - virtual gl::Error discard(size_t count, const GLenum *attachments) = 0; - virtual gl::Error invalidate(size_t count, const GLenum *attachments) = 0; - virtual gl::Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) = 0; + virtual gl::Error discard(const gl::Context *context, + size_t count, + const GLenum *attachments) = 0; + virtual gl::Error invalidate(const gl::Context *context, + size_t count, + const GLenum *attachments) = 0; + virtual gl::Error invalidateSub(const gl::Context *context, + size_t count, + const GLenum *attachments, + const gl::Rectangle &area) = 0; - virtual gl::Error clear(const gl::Data &data, GLbitfield mask) = 0; - virtual gl::Error clearBufferfv(const gl::Data &data, + virtual gl::Error clear(const gl::Context *context, GLbitfield mask) = 0; + virtual gl::Error clearBufferfv(const gl::Context *context, GLenum buffer, GLint drawbuffer, const GLfloat *values) = 0; - virtual gl::Error clearBufferuiv(const gl::Data &data, + virtual gl::Error clearBufferuiv(const gl::Context *context, GLenum buffer, GLint drawbuffer, const GLuint *values) = 0; - virtual gl::Error clearBufferiv(const gl::Data &data, + virtual gl::Error clearBufferiv(const gl::Context *context, GLenum buffer, GLint drawbuffer, const GLint *values) = 0; - virtual gl::Error clearBufferfi(const gl::Data &data, + virtual gl::Error clearBufferfi(const gl::Context *context, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) = 0; - virtual GLenum getImplementationColorReadFormat() const = 0; - virtual GLenum getImplementationColorReadType() const = 0; - virtual gl::Error readPixels(const gl::State &state, const gl::Rectangle &area, GLenum format, GLenum type, GLvoid *pixels) const = 0; + virtual GLenum getImplementationColorReadFormat(const gl::Context *context) const = 0; + virtual GLenum getImplementationColorReadType(const gl::Context *context) const = 0; + virtual gl::Error readPixels(const gl::Context *context, + const gl::Rectangle &area, + GLenum format, + GLenum type, + void *pixels) = 0; - virtual gl::Error blit(const gl::State &state, const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, - GLbitfield mask, GLenum filter, const gl::Framebuffer *sourceFramebuffer) = 0; + virtual gl::Error blit(const gl::Context *context, + const gl::Rectangle &sourceArea, + const gl::Rectangle &destArea, + GLbitfield mask, + GLenum filter) = 0; - virtual bool checkStatus() const = 0; + virtual bool checkStatus(const gl::Context *context) const = 0; - virtual void syncState(const gl::Framebuffer::DirtyBits &dirtyBits) = 0; + virtual void syncState(const gl::Context *context, + const gl::Framebuffer::DirtyBits &dirtyBits) = 0; - const gl::Framebuffer::Data &getData() const { return mData; } + virtual gl::Error getSamplePosition(size_t index, GLfloat *xy) const = 0; + + const gl::FramebufferState &getState() const { return mState; } protected: - const gl::Framebuffer::Data &mData; + const gl::FramebufferState &mState; }; - } -#endif // LIBANGLE_RENDERER_FRAMEBUFFERIMPL_H_ +#endif // LIBANGLE_RENDERER_FRAMEBUFFERIMPL_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/FramebufferImpl_mock.h b/src/3rdparty/angle/src/libANGLE/renderer/FramebufferImpl_mock.h index 57c95342d7..c2d069676e 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/FramebufferImpl_mock.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/FramebufferImpl_mock.h @@ -20,38 +20,39 @@ namespace rx class MockFramebufferImpl : public rx::FramebufferImpl { public: - MockFramebufferImpl() : rx::FramebufferImpl(gl::Framebuffer::Data()) {} - virtual ~MockFramebufferImpl() { destroy(); } + MockFramebufferImpl() : rx::FramebufferImpl(gl::FramebufferState()) {} + virtual ~MockFramebufferImpl() { destructor(); } - MOCK_METHOD2(discard, gl::Error(size_t, const GLenum *)); - MOCK_METHOD2(invalidate, gl::Error(size_t, const GLenum *)); - MOCK_METHOD3(invalidateSub, gl::Error(size_t, const GLenum *, const gl::Rectangle &)); + MOCK_METHOD3(discard, gl::Error(const gl::Context *, size_t, const GLenum *)); + MOCK_METHOD3(invalidate, gl::Error(const gl::Context *, size_t, const GLenum *)); + MOCK_METHOD4(invalidateSub, + gl::Error(const gl::Context *, size_t, const GLenum *, const gl::Rectangle &)); - MOCK_METHOD2(clear, gl::Error(const gl::Data &, GLbitfield)); - MOCK_METHOD4(clearBufferfv, gl::Error(const gl::Data &, GLenum, GLint, const GLfloat *)); - MOCK_METHOD4(clearBufferuiv, gl::Error(const gl::Data &, GLenum, GLint, const GLuint *)); - MOCK_METHOD4(clearBufferiv, gl::Error(const gl::Data &, GLenum, GLint, const GLint *)); - MOCK_METHOD5(clearBufferfi, gl::Error(const gl::Data &, GLenum, GLint, GLfloat, GLint)); + MOCK_METHOD2(clear, gl::Error(const gl::Context *, GLbitfield)); + MOCK_METHOD4(clearBufferfv, gl::Error(const gl::Context *, GLenum, GLint, const GLfloat *)); + MOCK_METHOD4(clearBufferuiv, gl::Error(const gl::Context *, GLenum, GLint, const GLuint *)); + MOCK_METHOD4(clearBufferiv, gl::Error(const gl::Context *, GLenum, GLint, const GLint *)); + MOCK_METHOD5(clearBufferfi, gl::Error(const gl::Context *, GLenum, GLint, GLfloat, GLint)); - MOCK_CONST_METHOD0(getImplementationColorReadFormat, GLenum()); - MOCK_CONST_METHOD0(getImplementationColorReadType, GLenum()); - MOCK_CONST_METHOD5( - readPixels, - gl::Error(const gl::State &, const gl::Rectangle &, GLenum, GLenum, GLvoid *)); + MOCK_CONST_METHOD1(getImplementationColorReadFormat, GLenum(const gl::Context *)); + MOCK_CONST_METHOD1(getImplementationColorReadType, GLenum(const gl::Context *)); + MOCK_METHOD5(readPixels, + gl::Error(const gl::Context *, const gl::Rectangle &, GLenum, GLenum, void *)); - MOCK_METHOD6(blit, - gl::Error(const gl::State &, + MOCK_CONST_METHOD2(getSamplePosition, gl::Error(size_t, GLfloat *)); + + MOCK_METHOD5(blit, + gl::Error(const gl::Context *, const gl::Rectangle &, const gl::Rectangle &, GLbitfield, - GLenum, - const gl::Framebuffer *)); + GLenum)); - MOCK_CONST_METHOD0(checkStatus, bool()); + MOCK_CONST_METHOD1(checkStatus, bool(const gl::Context *)); - MOCK_METHOD1(syncState, void(const gl::Framebuffer::DirtyBits &)); + MOCK_METHOD2(syncState, void(const gl::Context *, const gl::Framebuffer::DirtyBits &)); - MOCK_METHOD0(destroy, void()); + MOCK_METHOD0(destructor, void()); }; inline ::testing::NiceMock *MakeFramebufferMock() @@ -59,10 +60,10 @@ inline ::testing::NiceMock *MakeFramebufferMock() ::testing::NiceMock *framebufferImpl = new ::testing::NiceMock(); // TODO(jmadill): add ON_CALLS for other returning methods - ON_CALL(*framebufferImpl, checkStatus()).WillByDefault(::testing::Return(true)); + ON_CALL(*framebufferImpl, checkStatus(testing::_)).WillByDefault(::testing::Return(true)); // We must mock the destructor since NiceMock doesn't work for destructors. - EXPECT_CALL(*framebufferImpl, destroy()).Times(1).RetiresOnSaturation(); + EXPECT_CALL(*framebufferImpl, destructor()).Times(1).RetiresOnSaturation(); return framebufferImpl; } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/GLImplFactory.h b/src/3rdparty/angle/src/libANGLE/renderer/GLImplFactory.h new file mode 100644 index 0000000000..b9a135f596 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/GLImplFactory.h @@ -0,0 +1,93 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// GLImplFactory.h: +// Factory interface for OpenGL ES Impl objects. +// + +#ifndef LIBANGLE_RENDERER_GLIMPLFACTORY_H_ +#define LIBANGLE_RENDERER_GLIMPLFACTORY_H_ + +#include + +#include "angle_gl.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/Program.h" +#include "libANGLE/ProgramPipeline.h" +#include "libANGLE/Shader.h" +#include "libANGLE/TransformFeedback.h" +#include "libANGLE/VertexArray.h" + +namespace gl +{ +class ContextState; +} + +namespace rx +{ +class BufferImpl; +class CompilerImpl; +class ContextImpl; +class FenceNVImpl; +class SyncImpl; +class FramebufferImpl; +class PathImpl; +class ProgramImpl; +class ProgramPipelineImpl; +class QueryImpl; +class RenderbufferImpl; +class SamplerImpl; +class ShaderImpl; +class TextureImpl; +class TransformFeedbackImpl; +class VertexArrayImpl; + +class GLImplFactory : angle::NonCopyable +{ + public: + GLImplFactory() {} + virtual ~GLImplFactory() {} + + // Shader creation + virtual CompilerImpl *createCompiler() = 0; + virtual ShaderImpl *createShader(const gl::ShaderState &data) = 0; + virtual ProgramImpl *createProgram(const gl::ProgramState &data) = 0; + + // Framebuffer creation + virtual FramebufferImpl *createFramebuffer(const gl::FramebufferState &data) = 0; + + // Texture creation + virtual TextureImpl *createTexture(const gl::TextureState &state) = 0; + + // Renderbuffer creation + virtual RenderbufferImpl *createRenderbuffer() = 0; + + // Buffer creation + virtual BufferImpl *createBuffer(const gl::BufferState &state) = 0; + + // Vertex Array creation + virtual VertexArrayImpl *createVertexArray(const gl::VertexArrayState &data) = 0; + + // Query and Fence creation + virtual QueryImpl *createQuery(GLenum type) = 0; + virtual FenceNVImpl *createFenceNV() = 0; + virtual SyncImpl *createSync() = 0; + + // Transform Feedback creation + virtual TransformFeedbackImpl *createTransformFeedback( + const gl::TransformFeedbackState &state) = 0; + + // Sampler object creation + virtual SamplerImpl *createSampler(const gl::SamplerState &state) = 0; + + // Program Pipeline object creation + virtual ProgramPipelineImpl *createProgramPipeline(const gl::ProgramPipelineState &data) = 0; + + virtual std::vector createPaths(GLsizei range) = 0; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_GLIMPLFACTORY_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/Image.h b/src/3rdparty/angle/src/libANGLE/renderer/Image.h deleted file mode 100644 index 62d854c9b6..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/Image.h +++ /dev/null @@ -1,77 +0,0 @@ -// -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// Image.h: Defines the rx::Image class, an abstract base class for the -// renderer-specific classes which will define the interface to the underlying -// surfaces or resources. - -#ifndef LIBANGLE_RENDERER_IMAGE_H_ -#define LIBANGLE_RENDERER_IMAGE_H_ - -#include "common/debug.h" -#include "libANGLE/Error.h" - -#include - -namespace gl -{ -class Framebuffer; -struct Rectangle; -struct Extents; -struct Box; -struct Offset; -struct ImageIndex; -} - -namespace rx -{ -class RendererD3D; -class RenderTarget; -class TextureStorage; - -class Image -{ - public: - Image(); - virtual ~Image() {}; - - GLsizei getWidth() const { return mWidth; } - GLsizei getHeight() const { return mHeight; } - GLsizei getDepth() const { return mDepth; } - GLenum getInternalFormat() const { return mInternalFormat; } - GLenum getTarget() const { return mTarget; } - bool isRenderableFormat() const { return mRenderable; } - - void markDirty() {mDirty = true;} - void markClean() {mDirty = false;} - virtual bool isDirty() const = 0; - - virtual bool redefine(GLenum target, GLenum internalformat, const gl::Extents &size, bool forceRelease) = 0; - - virtual gl::Error loadData(const gl::Box &area, GLint unpackAlignment, GLenum type, const void *input) = 0; - virtual gl::Error loadCompressedData(const gl::Box &area, const void *input) = 0; - - virtual gl::Error copy(const gl::Offset &destOffset, const gl::Rectangle &sourceArea, const gl::Framebuffer *source) = 0; - virtual gl::Error copy(const gl::Offset &destOffset, const gl::Box &sourceArea, - const gl::ImageIndex &sourceIndex, TextureStorage *source) = 0; - - protected: - GLsizei mWidth; - GLsizei mHeight; - GLsizei mDepth; - GLenum mInternalFormat; - bool mRenderable; - GLenum mTarget; - - bool mDirty; - - private: - DISALLOW_COPY_AND_ASSIGN(Image); -}; - -} - -#endif // LIBANGLE_RENDERER_IMAGE_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/ImageImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/ImageImpl.h index e48f1946a8..79694eaebf 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/ImageImpl.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/ImageImpl.h @@ -12,21 +12,31 @@ #include "common/angleutils.h" #include "libANGLE/Error.h" +namespace gl +{ +class Context; +} // namespace gl + namespace egl { class ImageSibling; -} +struct ImageState; +} // namespace egl namespace rx { class ImageImpl : angle::NonCopyable { public: + ImageImpl(const egl::ImageState &state) : mState(state) {} virtual ~ImageImpl() {} virtual egl::Error initialize() = 0; - virtual gl::Error orphan(egl::ImageSibling *sibling) = 0; + virtual gl::Error orphan(const gl::Context *context, egl::ImageSibling *sibling) = 0; + + protected: + const egl::ImageState &mState; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_IMAGEIMPL_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/ImageImpl_mock.h b/src/3rdparty/angle/src/libANGLE/renderer/ImageImpl_mock.h index 27fe6a3947..30c0cc2594 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/ImageImpl_mock.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/ImageImpl_mock.h @@ -18,11 +18,17 @@ namespace rx class MockImageImpl : public ImageImpl { public: + MockImageImpl(const egl::ImageState &state, + EGLenum /*target*/, + const egl::AttributeMap & /*attribs*/) + : ImageImpl(state) + { + } virtual ~MockImageImpl() { destructor(); } MOCK_METHOD0(initialize, egl::Error(void)); - MOCK_METHOD1(orphan, gl::Error(egl::ImageSibling *)); + MOCK_METHOD2(orphan, gl::Error(const gl::Context *, egl::ImageSibling *)); MOCK_METHOD0(destructor, void()); }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_IMAGEIMPLMOCK_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/ImplFactory.h b/src/3rdparty/angle/src/libANGLE/renderer/ImplFactory.h deleted file mode 100644 index b988fcf97f..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/ImplFactory.h +++ /dev/null @@ -1,74 +0,0 @@ -// -// Copyright 2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// ImplFactory.h: -// Factory interface for Impl objects. -// - -#ifndef LIBANGLE_RENDERER_IMPLFACTORY_H_ -#define LIBANGLE_RENDERER_IMPLFACTORY_H_ - -#include "libANGLE/Framebuffer.h" -#include "libANGLE/Program.h" -#include "libANGLE/Shader.h" -#include "libANGLE/VertexArray.h" - -namespace rx -{ -class BufferImpl; -class CompilerImpl; -class FenceNVImpl; -class FenceSyncImpl; -class FramebufferImpl; -class ProgramImpl; -class QueryImpl; -class RenderbufferImpl; -class SamplerImpl; -class ShaderImpl; -class TextureImpl; -class TransformFeedbackImpl; -class VertexArrayImpl; - -class ImplFactory : angle::NonCopyable -{ - public: - ImplFactory() {} - virtual ~ImplFactory() {} - - // Shader creation - virtual CompilerImpl *createCompiler() = 0; - virtual ShaderImpl *createShader(const gl::Shader::Data &data) = 0; - virtual ProgramImpl *createProgram(const gl::Program::Data &data) = 0; - - // Framebuffer creation - virtual FramebufferImpl *createFramebuffer(const gl::Framebuffer::Data &data) = 0; - - // Texture creation - virtual TextureImpl *createTexture(GLenum target) = 0; - - // Renderbuffer creation - virtual RenderbufferImpl *createRenderbuffer() = 0; - - // Buffer creation - virtual BufferImpl *createBuffer() = 0; - - // Vertex Array creation - virtual VertexArrayImpl *createVertexArray(const gl::VertexArray::Data &data) = 0; - - // Query and Fence creation - virtual QueryImpl *createQuery(GLenum type) = 0; - virtual FenceNVImpl *createFenceNV() = 0; - virtual FenceSyncImpl *createFenceSync() = 0; - - // Transform Feedback creation - virtual TransformFeedbackImpl *createTransformFeedback() = 0; - - // Sampler object creation - virtual SamplerImpl *createSampler() = 0; -}; - -} - -#endif // LIBANGLE_RENDERER_IMPLFACTORY_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/PathImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/PathImpl.h new file mode 100644 index 0000000000..3607f69a2b --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/PathImpl.h @@ -0,0 +1,36 @@ +// +// Copyright (c) 2002-2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// PathImpl.h: Defines the Path implementation interface for +// CHROMIUM_path_rendering path objects. + +#ifndef LIBANGLE_RENDERER_PATHIMPL_H_ +#define LIBANGLE_RENDERER_PATHIMPL_H_ + +#include "angle_gl.h" +#include "common/angleutils.h" +#include "libANGLE/Error.h" + +namespace rx +{ + +class PathImpl : angle::NonCopyable +{ + public: + virtual ~PathImpl() {} + + virtual gl::Error setCommands(GLsizei numCommands, + const GLubyte *commands, + GLsizei numCoords, + GLenum coordType, + const void *coords) = 0; + + virtual void setPathParameter(GLenum pname, GLfloat value) = 0; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_PATHIMPL_H_ \ No newline at end of file diff --git a/src/3rdparty/angle/src/libANGLE/renderer/ProgramImpl.cpp b/src/3rdparty/angle/src/libANGLE/renderer/ProgramImpl.cpp deleted file mode 100644 index 8fbc53768f..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/ProgramImpl.cpp +++ /dev/null @@ -1,152 +0,0 @@ -// -// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// ProgramD3D.cpp: Defines the rx::ProgramD3D class which implements rx::ProgramImpl. - -#include "libANGLE/renderer/ProgramImpl.h" - -#include "common/utilities.h" - -namespace rx -{ - -namespace -{ - -unsigned int ParseAndStripArrayIndex(std::string* name) -{ - unsigned int subscript = GL_INVALID_INDEX; - - // Strip any trailing array operator and retrieve the subscript - size_t open = name->find_last_of('['); - size_t close = name->find_last_of(']'); - if (open != std::string::npos && close == name->length() - 1) - { - subscript = atoi(name->substr(open + 1).c_str()); - name->erase(open); - } - - return subscript; -} - -} - -LinkResult::LinkResult(bool linkSuccess, const gl::Error &error) - : linkSuccess(linkSuccess), - error(error) -{ -} - -ProgramImpl::~ProgramImpl() -{ - // Ensure that reset was called by the inherited class during destruction - ASSERT(mUniformIndex.size() == 0); -} - -gl::LinkedUniform *ProgramImpl::getUniformByLocation(GLint location) const -{ - ASSERT(location >= 0 && static_cast(location) < mUniformIndex.size()); - return mUniforms[mUniformIndex[location].index]; -} - -gl::LinkedUniform *ProgramImpl::getUniformByName(const std::string &name) const -{ - for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++) - { - if (mUniforms[uniformIndex]->name == name) - { - return mUniforms[uniformIndex]; - } - } - - return NULL; -} - -gl::UniformBlock *ProgramImpl::getUniformBlockByIndex(GLuint blockIndex) const -{ - ASSERT(blockIndex < mUniformBlocks.size()); - return mUniformBlocks[blockIndex]; -} - -GLint ProgramImpl::getUniformLocation(std::string name) -{ - unsigned int subscript = ParseAndStripArrayIndex(&name); - - unsigned int numUniforms = mUniformIndex.size(); - for (unsigned int location = 0; location < numUniforms; location++) - { - if (mUniformIndex[location].name == name) - { - const int index = mUniformIndex[location].index; - const bool isArray = mUniforms[index]->isArray(); - - if ((isArray && mUniformIndex[location].element == subscript) || - (subscript == GL_INVALID_INDEX)) - { - return location; - } - } - } - - return -1; -} - -GLuint ProgramImpl::getUniformIndex(std::string name) -{ - unsigned int subscript = ParseAndStripArrayIndex(&name); - - // The app is not allowed to specify array indices other than 0 for arrays of basic types - if (subscript != 0 && subscript != GL_INVALID_INDEX) - { - return GL_INVALID_INDEX; - } - - unsigned int numUniforms = mUniforms.size(); - for (unsigned int index = 0; index < numUniforms; index++) - { - if (mUniforms[index]->name == name) - { - if (mUniforms[index]->isArray() || subscript == GL_INVALID_INDEX) - { - return index; - } - } - } - - return GL_INVALID_INDEX; -} - -GLuint ProgramImpl::getUniformBlockIndex(std::string name) const -{ - unsigned int subscript = ParseAndStripArrayIndex(&name); - - unsigned int numUniformBlocks = mUniformBlocks.size(); - for (unsigned int blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++) - { - const gl::UniformBlock &uniformBlock = *mUniformBlocks[blockIndex]; - if (uniformBlock.name == name) - { - const bool arrayElementZero = (subscript == GL_INVALID_INDEX && uniformBlock.elementIndex == 0); - if (subscript == uniformBlock.elementIndex || arrayElementZero) - { - return blockIndex; - } - } - } - - return GL_INVALID_INDEX; -} - -void ProgramImpl::reset() -{ - std::fill(mSemanticIndex, mSemanticIndex + ArraySize(mSemanticIndex), -1); - SafeDeleteContainer(mUniforms); - mUniformIndex.clear(); - SafeDeleteContainer(mUniformBlocks); - mTransformFeedbackLinkedVaryings.clear(); -} - -} diff --git a/src/3rdparty/angle/src/libANGLE/renderer/ProgramImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/ProgramImpl.h index 1e688045a1..2371b2759c 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/ProgramImpl.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/ProgramImpl.h @@ -14,32 +14,39 @@ #include "libANGLE/Constants.h" #include "libANGLE/Program.h" #include "libANGLE/Shader.h" -#include "libANGLE/renderer/Renderer.h" #include +namespace gl +{ +class Context; +struct ProgramLinkedResources; +} + +namespace sh +{ +struct BlockMemberInfo; +} + namespace rx { - -struct LinkResult -{ - LinkResult(bool linkSuccess, const gl::Error &error) : linkSuccess(linkSuccess), error(error) {} - - bool linkSuccess; - gl::Error error; -}; - class ProgramImpl : angle::NonCopyable { public: - ProgramImpl(const gl::Program::Data &data) : mData(data) {} + ProgramImpl(const gl::ProgramState &state) : mState(state) {} virtual ~ProgramImpl() {} + virtual void destroy(const gl::Context *context) {} - virtual LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) = 0; - virtual gl::Error save(gl::BinaryOutputStream *stream) = 0; + virtual gl::LinkResult load(const gl::Context *context, + gl::InfoLog &infoLog, + gl::BinaryInputStream *stream) = 0; + virtual void save(const gl::Context *context, gl::BinaryOutputStream *stream) = 0; virtual void setBinaryRetrievableHint(bool retrievable) = 0; + virtual void setSeparable(bool separable) = 0; - virtual LinkResult link(const gl::Data &data, gl::InfoLog &infoLog) = 0; + virtual gl::LinkResult link(const gl::Context *context, + const gl::ProgramLinkedResources &resources, + gl::InfoLog &infoLog) = 0; virtual GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) = 0; virtual void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) = 0; @@ -64,22 +71,37 @@ class ProgramImpl : angle::NonCopyable virtual void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0; virtual void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) = 0; + // Done in the back-end to avoid having to keep a system copy of uniform data. + virtual void getUniformfv(const gl::Context *context, + GLint location, + GLfloat *params) const = 0; + virtual void getUniformiv(const gl::Context *context, GLint location, GLint *params) const = 0; + virtual void getUniformuiv(const gl::Context *context, + GLint location, + GLuint *params) const = 0; + // TODO: synchronize in syncState when dirty bits exist. virtual void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) = 0; - // May only be called after a successful link operation. - // Return false for inactive blocks. - virtual bool getUniformBlockSize(const std::string &blockName, size_t *sizeOut) const = 0; + // CHROMIUM_path_rendering + // Set parameters to control fragment shader input variable interpolation + virtual void setPathFragmentInputGen(const std::string &inputName, + GLenum genMode, + GLint components, + const GLfloat *coeffs) = 0; - // May only be called after a successful link operation. - // Returns false for inactive members. - virtual bool getUniformBlockMemberInfo(const std::string &memberUniformName, - sh::BlockMemberInfo *memberInfoOut) const = 0; + // Implementation-specific method for ignoring unreferenced uniforms. Some implementations may + // perform more extensive analysis and ignore some locations that ANGLE doesn't detect as + // unreferenced. This method is not required to be overriden by a back-end. + virtual void markUnusedUniformLocations(std::vector *uniformLocations, + std::vector *samplerBindings) + { + } protected: - const gl::Program::Data &mData; + const gl::ProgramState &mState; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_PROGRAMIMPL_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/ProgramImpl_mock.h b/src/3rdparty/angle/src/libANGLE/renderer/ProgramImpl_mock.h index d6aa238f64..4717ab8843 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/ProgramImpl_mock.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/ProgramImpl_mock.h @@ -12,6 +12,7 @@ #include "gmock/gmock.h" +#include "libANGLE/ProgramLinkedResources.h" #include "libANGLE/renderer/ProgramImpl.h" namespace rx @@ -20,14 +21,18 @@ namespace rx class MockProgramImpl : public rx::ProgramImpl { public: - MockProgramImpl() : ProgramImpl(gl::Program::Data()) {} - virtual ~MockProgramImpl() { destroy(); } + MockProgramImpl() : ProgramImpl(gl::ProgramState()) {} + virtual ~MockProgramImpl() { destructor(); } - MOCK_METHOD2(load, LinkResult(gl::InfoLog &, gl::BinaryInputStream *)); - MOCK_METHOD1(save, gl::Error(gl::BinaryOutputStream *)); + MOCK_METHOD3(load, gl::LinkResult(const gl::Context *, gl::InfoLog &, gl::BinaryInputStream *)); + MOCK_METHOD2(save, void(const gl::Context *, gl::BinaryOutputStream *)); MOCK_METHOD1(setBinaryRetrievableHint, void(bool)); + MOCK_METHOD1(setSeparable, void(bool)); - MOCK_METHOD2(link, LinkResult(const gl::Data &, gl::InfoLog &)); + MOCK_METHOD3(link, + gl::LinkResult(const gl::Context *, + const gl::ProgramLinkedResources &, + gl::InfoLog &)); MOCK_METHOD2(validate, GLboolean(const gl::Caps &, gl::InfoLog *)); MOCK_METHOD3(setUniform1fv, void(GLint, GLsizei, const GLfloat *)); @@ -53,11 +58,15 @@ class MockProgramImpl : public rx::ProgramImpl MOCK_METHOD4(setUniformMatrix3x4fv, void(GLint, GLsizei, GLboolean, const GLfloat *)); MOCK_METHOD4(setUniformMatrix4x3fv, void(GLint, GLsizei, GLboolean, const GLfloat *)); - MOCK_METHOD2(setUniformBlockBinding, void(GLuint, GLuint)); - MOCK_CONST_METHOD2(getUniformBlockSize, bool(const std::string &, size_t *)); - MOCK_CONST_METHOD2(getUniformBlockMemberInfo, bool(const std::string &, sh::BlockMemberInfo *)); + MOCK_CONST_METHOD3(getUniformfv, void(const gl::Context *, GLint, GLfloat *)); + MOCK_CONST_METHOD3(getUniformiv, void(const gl::Context *, GLint, GLint *)); + MOCK_CONST_METHOD3(getUniformuiv, void(const gl::Context *, GLint, GLuint *)); - MOCK_METHOD0(destroy, void()); + MOCK_METHOD2(setUniformBlockBinding, void(GLuint, GLuint)); + MOCK_METHOD4(setPathFragmentInputGen, + void(const std::string &, GLenum, GLint, const GLfloat *)); + + MOCK_METHOD0(destructor, void()); }; inline ::testing::NiceMock *MakeProgramMock() @@ -65,7 +74,7 @@ inline ::testing::NiceMock *MakeProgramMock() ::testing::NiceMock *programImpl = new ::testing::NiceMock(); // TODO(jmadill): add ON_CALLS for returning methods // We must mock the destructor since NiceMock doesn't work for destructors. - EXPECT_CALL(*programImpl, destroy()).Times(1).RetiresOnSaturation(); + EXPECT_CALL(*programImpl, destructor()).Times(1).RetiresOnSaturation(); return programImpl; } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/ProgramPipelineImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/ProgramPipelineImpl.h new file mode 100644 index 0000000000..242e9260f1 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/ProgramPipelineImpl.h @@ -0,0 +1,32 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// ProgramPipelineImpl.h: Defines the abstract rx::ProgramPipelineImpl class. + +#ifndef LIBANGLE_RENDERER_PROGRAMPIPELINEIMPL_H_ +#define LIBANGLE_RENDERER_PROGRAMPIPELINEIMPL_H_ + +#include "common/angleutils.h" +#include "libANGLE/ProgramPipeline.h" + +namespace rx +{ +class ContextImpl; + +class ProgramPipelineImpl : public angle::NonCopyable +{ + public: + ProgramPipelineImpl(const gl::ProgramPipelineState &state) : mState(state) {} + virtual ~ProgramPipelineImpl() {} + virtual void destroy(const ContextImpl *contextImpl) {} + + protected: + const gl::ProgramPipelineState &mState; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_PROGRAMPIPELINEIMPL_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/RenderbufferImpl.cpp b/src/3rdparty/angle/src/libANGLE/renderer/RenderbufferImpl.cpp deleted file mode 100644 index ea5a40a21a..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/RenderbufferImpl.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// -// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// RenderbufferImpl.h: Implements the shared methods of the abstract class gl::RenderbufferImpl - -#include "libANGLE/renderer/RenderbufferImpl.h" - -namespace rx -{ -RenderbufferImpl::RenderbufferImpl() -{ -} - -RenderbufferImpl::~RenderbufferImpl() -{ -} - -} diff --git a/src/3rdparty/angle/src/libANGLE/renderer/RenderbufferImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/RenderbufferImpl.h index 75b4cdcfee..a70ab1d0f0 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/RenderbufferImpl.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/RenderbufferImpl.h @@ -12,7 +12,7 @@ #include "angle_gl.h" #include "common/angleutils.h" #include "libANGLE/Error.h" -#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/renderer/FramebufferAttachmentObjectImpl.h" namespace egl { @@ -26,13 +26,25 @@ class RenderbufferImpl : public FramebufferAttachmentObjectImpl { public: RenderbufferImpl() {} - virtual ~RenderbufferImpl() {} + ~RenderbufferImpl() override {} + virtual gl::Error onDestroy(const gl::Context *context); - virtual gl::Error setStorage(GLenum internalformat, size_t width, size_t height) = 0; - virtual gl::Error setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height) = 0; - virtual gl::Error setStorageEGLImageTarget(egl::Image *image) = 0; + virtual gl::Error setStorage(const gl::Context *context, + GLenum internalformat, + size_t width, + size_t height) = 0; + virtual gl::Error setStorageMultisample(const gl::Context *context, + size_t samples, + GLenum internalformat, + size_t width, + size_t height) = 0; + virtual gl::Error setStorageEGLImageTarget(const gl::Context *context, egl::Image *image) = 0; }; +inline gl::Error RenderbufferImpl::onDestroy(const gl::Context *context) +{ + return gl::NoError(); +} } #endif // LIBANGLE_RENDERER_RENDERBUFFERIMPL_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/RenderbufferImpl_mock.h b/src/3rdparty/angle/src/libANGLE/renderer/RenderbufferImpl_mock.h index c2c67cc76a..408b9a5fe9 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/RenderbufferImpl_mock.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/RenderbufferImpl_mock.h @@ -21,11 +21,16 @@ class MockRenderbufferImpl : public RenderbufferImpl { public: virtual ~MockRenderbufferImpl() { destructor(); } - MOCK_METHOD3(setStorage, gl::Error(GLenum, size_t, size_t)); - MOCK_METHOD4(setStorageMultisample, gl::Error(size_t, GLenum, size_t, size_t)); - MOCK_METHOD1(setStorageEGLImageTarget, gl::Error(egl::Image *)); + MOCK_METHOD4(setStorage, gl::Error(const gl::Context *, GLenum, size_t, size_t)); + MOCK_METHOD5(setStorageMultisample, + gl::Error(const gl::Context *, size_t, GLenum, size_t, size_t)); + MOCK_METHOD2(setStorageEGLImageTarget, gl::Error(const gl::Context *, egl::Image *)); - MOCK_METHOD2(getAttachmentRenderTarget, gl::Error(const gl::FramebufferAttachment::Target &, FramebufferAttachmentRenderTarget **)); + MOCK_METHOD4(getAttachmentRenderTarget, + gl::Error(const gl::Context *, + GLenum, + const gl::ImageIndex &, + FramebufferAttachmentRenderTarget **)); MOCK_METHOD0(destructor, void()); }; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/Renderer.cpp b/src/3rdparty/angle/src/libANGLE/renderer/Renderer.cpp deleted file mode 100644 index f3f7f55bb9..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/Renderer.cpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// Renderer.cpp: Implements EGL dependencies for creating and destroying Renderer instances. - -#include "common/utilities.h" -#include "libANGLE/AttributeMap.h" -#include "libANGLE/renderer/Renderer.h" - -#include - -namespace rx -{ -Renderer::Renderer() : mCapsInitialized(false) -{ -} - -Renderer::~Renderer() -{ -} - -void Renderer::ensureCapsInitialized() const -{ - if (!mCapsInitialized) - { - generateCaps(&mCaps, &mTextureCaps, &mExtensions, &mLimitations); - mCapsInitialized = true; - } -} - -const gl::Caps &Renderer::getRendererCaps() const -{ - ensureCapsInitialized(); - - return mCaps; -} - -const gl::TextureCapsMap &Renderer::getRendererTextureCaps() const -{ - ensureCapsInitialized(); - - return mTextureCaps; -} - -const gl::Extensions &Renderer::getRendererExtensions() const -{ - ensureCapsInitialized(); - - return mExtensions; -} - -const gl::Limitations &Renderer::getRendererLimitations() const -{ - ensureCapsInitialized(); - - return mLimitations; -} - -} diff --git a/src/3rdparty/angle/src/libANGLE/renderer/Renderer.h b/src/3rdparty/angle/src/libANGLE/renderer/Renderer.h deleted file mode 100644 index d0da2b140c..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/Renderer.h +++ /dev/null @@ -1,121 +0,0 @@ -// -// Copyright (c) 2012-2014 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// Renderer.h: Defines a back-end specific class that hides the details of the -// implementation-specific renderer. - -#ifndef LIBANGLE_RENDERER_RENDERER_H_ -#define LIBANGLE_RENDERER_RENDERER_H_ - -#include "libANGLE/Caps.h" -#include "libANGLE/Error.h" -#include "libANGLE/Framebuffer.h" -#include "libANGLE/State.h" -#include "libANGLE/Uniform.h" -#include "libANGLE/angletypes.h" -#include "libANGLE/renderer/ImplFactory.h" -#include "common/mathutil.h" - -#include - -#include - -namespace egl -{ -class AttributeMap; -class Display; -class Surface; -} - -namespace rx -{ -struct TranslatedIndexData; -struct SourceIndexData; -struct WorkaroundsD3D; -class DisplayImpl; - -class Renderer : public ImplFactory -{ - public: - Renderer(); - virtual ~Renderer(); - - virtual gl::Error flush() = 0; - virtual gl::Error finish() = 0; - - virtual gl::Error drawArrays(const gl::Data &data, GLenum mode, GLint first, GLsizei count) = 0; - virtual gl::Error drawArraysInstanced(const gl::Data &data, - GLenum mode, - GLint first, - GLsizei count, - GLsizei instanceCount) = 0; - - virtual gl::Error drawElements(const gl::Data &data, - GLenum mode, - GLsizei count, - GLenum type, - const GLvoid *indices, - const gl::IndexRange &indexRange) = 0; - virtual gl::Error drawElementsInstanced(const gl::Data &data, - GLenum mode, - GLsizei count, - GLenum type, - const GLvoid *indices, - GLsizei instances, - const gl::IndexRange &indexRange) = 0; - virtual gl::Error drawRangeElements(const gl::Data &data, - GLenum mode, - GLuint start, - GLuint end, - GLsizei count, - GLenum type, - const GLvoid *indices, - const gl::IndexRange &indexRange) = 0; - - // lost device - //TODO(jmadill): investigate if this stuff is necessary in GL - virtual void notifyDeviceLost() = 0; - virtual bool isDeviceLost() const = 0; - virtual bool testDeviceLost() = 0; - virtual bool testDeviceResettable() = 0; - - virtual std::string getVendorString() const = 0; - virtual std::string getRendererDescription() const = 0; - - virtual void insertEventMarker(GLsizei length, const char *marker) = 0; - virtual void pushGroupMarker(GLsizei length, const char *marker) = 0; - virtual void popGroupMarker() = 0; - - virtual void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits) = 0; - - // Disjoint timer queries - virtual GLint getGPUDisjoint() = 0; - virtual GLint64 getTimestamp() = 0; - - // Context switching - virtual void onMakeCurrent(const gl::Data &data) = 0; - - // Renderer capabilities - const gl::Caps &getRendererCaps() const; - const gl::TextureCapsMap &getRendererTextureCaps() const; - const gl::Extensions &getRendererExtensions() const; - const gl::Limitations &getRendererLimitations() const; - - private: - void ensureCapsInitialized() const; - virtual void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap* outTextureCaps, - gl::Extensions *outExtensions, - gl::Limitations *outLimitations) const = 0; - - mutable bool mCapsInitialized; - mutable gl::Caps mCaps; - mutable gl::TextureCapsMap mTextureCaps; - mutable gl::Extensions mExtensions; - mutable gl::Limitations mLimitations; -}; - -} -#endif // LIBANGLE_RENDERER_RENDERER_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/SamplerImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/SamplerImpl.h index 85383cf8e5..66e1079b64 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/SamplerImpl.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/SamplerImpl.h @@ -11,15 +11,29 @@ #include "common/angleutils.h" +namespace gl +{ +class Context; +struct SamplerState; +} // namespace gl + namespace rx { -class SamplerImpl : public angle::NonCopyable +class SamplerImpl : angle::NonCopyable { public: - SamplerImpl() {} + SamplerImpl(const gl::SamplerState &state) : mState(state) {} virtual ~SamplerImpl() {} + + virtual void syncState(const gl::Context *context) + { + // Default implementation: no-op. + } + + protected: + const gl::SamplerState &mState; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_SAMPLERIMPL_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/ShaderImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/ShaderImpl.h index 5a466377a5..77e02d0237 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/ShaderImpl.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/ShaderImpl.h @@ -18,21 +18,21 @@ namespace rx class ShaderImpl : angle::NonCopyable { public: - ShaderImpl(const gl::Shader::Data &data) : mData(data) {} + ShaderImpl(const gl::ShaderState &data) : mData(data) {} virtual ~ShaderImpl() { } - // Returns additional ShCompile options. - virtual int prepareSourceAndReturnOptions(std::stringstream *sourceStream, - std::string *sourcePath) = 0; + // Returns additional sh::Compile options. + virtual ShCompileOptions prepareSourceAndReturnOptions(std::stringstream *sourceStream, + std::string *sourcePath) = 0; // Returns success for compiling on the driver. Returns success. virtual bool postTranslateCompile(gl::Compiler *compiler, std::string *infoLog) = 0; virtual std::string getDebugInfo() const = 0; - const gl::Shader::Data &getData() const { return mData; } + const gl::ShaderState &getData() const { return mData; } protected: - const gl::Shader::Data &mData; + const gl::ShaderState &mData; }; } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/StreamProducerImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/StreamProducerImpl.h new file mode 100644 index 0000000000..1915bf75d3 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/StreamProducerImpl.h @@ -0,0 +1,39 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// StreamProducerImpl.h: Defines the abstract rx::StreamProducerImpl class. + +#ifndef LIBANGLE_RENDERER_STREAMPRODUCERIMPL_H_ +#define LIBANGLE_RENDERER_STREAMPRODUCERIMPL_H_ + +#include "common/angleutils.h" +#include "libANGLE/Stream.h" + +namespace rx +{ + +class StreamProducerImpl : angle::NonCopyable +{ + public: + explicit StreamProducerImpl() {} + virtual ~StreamProducerImpl() {} + + // Validates the ability for the producer to accept an arbitrary pointer to a frame. All + // pointers should be validated through this function before being used to produce a frame. + virtual egl::Error validateD3DNV12Texture(void *pointer) const = 0; + + // Constructs a frame from an arbitrary external pointer that points to producer specific frame + // data. Replaces the internal frame with the new one. + virtual void postD3DNV12Texture(void *pointer, const egl::AttributeMap &attributes) = 0; + + // Returns an OpenGL texture interpretation of some frame attributes for the purpose of + // constructing an OpenGL texture from a frame. Depending on the producer and consumer, some + // frames may have multiple "planes" with different OpenGL texture representations. + virtual egl::Stream::GLTextureDescription getGLFrameDescription(int planeIndex) = 0; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_STREAMPRODUCERIMPL_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/SurfaceImpl.cpp b/src/3rdparty/angle/src/libANGLE/renderer/SurfaceImpl.cpp index 36f5fdca3f..cd2fa3dde6 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/SurfaceImpl.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/SurfaceImpl.cpp @@ -11,7 +11,7 @@ namespace rx { -SurfaceImpl::SurfaceImpl() +SurfaceImpl::SurfaceImpl(const egl::SurfaceState &state) : mState(state) { } @@ -19,4 +19,10 @@ SurfaceImpl::~SurfaceImpl() { } +egl::Error SurfaceImpl::swapWithDamage(const gl::Context *context, EGLint *rects, EGLint n_rects) +{ + UNREACHABLE(); + return egl::EglBadSurface() << "swapWithDamage implementation missing."; } + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/SurfaceImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/SurfaceImpl.h index 32125d542c..eaa27de281 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/SurfaceImpl.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/SurfaceImpl.h @@ -9,35 +9,51 @@ #ifndef LIBANGLE_RENDERER_SURFACEIMPL_H_ #define LIBANGLE_RENDERER_SURFACEIMPL_H_ +#include +#include + #include "common/angleutils.h" #include "libANGLE/Error.h" -#include "libANGLE/Framebuffer.h" #include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/renderer/FramebufferAttachmentObjectImpl.h" + +namespace gl +{ +class FramebufferState; +} namespace egl { class Display; struct Config; +struct SurfaceState; +class Thread; } namespace rx { - class FramebufferImpl; class SurfaceImpl : public FramebufferAttachmentObjectImpl { public: - SurfaceImpl(); - virtual ~SurfaceImpl(); + SurfaceImpl(const egl::SurfaceState &surfaceState); + ~SurfaceImpl() override; + virtual void destroy(const egl::Display *display) {} - virtual egl::Error initialize() = 0; - virtual FramebufferImpl *createDefaultFramebuffer(const gl::Framebuffer::Data &data) = 0; - virtual egl::Error swap() = 0; - virtual egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) = 0; + virtual egl::Error initialize(const egl::Display *display) = 0; + virtual FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) = 0; + virtual egl::Error swap(const gl::Context *context) = 0; + virtual egl::Error swapWithDamage(const gl::Context *context, EGLint *rects, EGLint n_rects); + virtual egl::Error postSubBuffer(const gl::Context *context, + EGLint x, + EGLint y, + EGLint width, + EGLint height) = 0; virtual egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) = 0; virtual egl::Error bindTexImage(gl::Texture *texture, EGLint buffer) = 0; virtual egl::Error releaseTexImage(EGLint buffer) = 0; + virtual egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) = 0; virtual void setSwapInterval(EGLint interval) = 0; // width and height can change with client window resizing @@ -46,6 +62,9 @@ class SurfaceImpl : public FramebufferAttachmentObjectImpl virtual EGLint isPostSubBufferSupported() const = 0; virtual EGLint getSwapBehavior() const = 0; + + protected: + const egl::SurfaceState &mState; }; } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/FenceSyncImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/SyncImpl.h similarity index 76% rename from src/3rdparty/angle/src/libANGLE/renderer/FenceSyncImpl.h rename to src/3rdparty/angle/src/libANGLE/renderer/SyncImpl.h index 6b78e69d47..22c92c3729 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/FenceSyncImpl.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/SyncImpl.h @@ -4,7 +4,7 @@ // found in the LICENSE file. // -// FenceSyncImpl.h: Defines the rx::FenceSyncImpl class. +// SyncImpl.h: Defines the rx::SyncImpl class. #ifndef LIBANGLE_RENDERER_FENCESYNCIMPL_H_ #define LIBANGLE_RENDERER_FENCESYNCIMPL_H_ @@ -18,18 +18,17 @@ namespace rx { -class FenceSyncImpl : angle::NonCopyable +class SyncImpl : angle::NonCopyable { public: - FenceSyncImpl() { }; - virtual ~FenceSyncImpl() { }; + SyncImpl(){}; + virtual ~SyncImpl(){}; virtual gl::Error set(GLenum condition, GLbitfield flags) = 0; virtual gl::Error clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult) = 0; virtual gl::Error serverWait(GLbitfield flags, GLuint64 timeout) = 0; virtual gl::Error getStatus(GLint *outResult) = 0; }; - } -#endif // LIBANGLE_RENDERER_FENCESYNCIMPL_H_ +#endif // LIBANGLE_RENDERER_FENCESYNCIMPL_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/TextureImpl.cpp b/src/3rdparty/angle/src/libANGLE/renderer/TextureImpl.cpp new file mode 100644 index 0000000000..830d30e6d1 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/TextureImpl.cpp @@ -0,0 +1,63 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// TextureImpl.cpp: Defines the abstract rx::TextureImpl classes. + +#include "libANGLE/renderer/TextureImpl.h" + +namespace rx +{ + +TextureImpl::TextureImpl(const gl::TextureState &state) : mState(state) +{ +} + +TextureImpl::~TextureImpl() +{ +} + +gl::Error TextureImpl::onDestroy(const gl::Context *context) +{ + return gl::NoError(); +} + +gl::Error TextureImpl::copyTexture(const gl::Context *context, + GLenum target, + size_t level, + GLenum internalFormat, + GLenum type, + size_t sourceLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) +{ + UNREACHABLE(); + return gl::InternalError() << "CHROMIUM_copy_texture exposed but not implemented."; +} + +gl::Error TextureImpl::copySubTexture(const gl::Context *context, + GLenum target, + size_t level, + const gl::Offset &destOffset, + size_t sourceLevel, + const gl::Rectangle &sourceArea, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) +{ + UNREACHABLE(); + return gl::InternalError() << "CHROMIUM_copy_texture exposed but not implemented."; +} + +gl::Error TextureImpl::copyCompressedTexture(const gl::Context *context, const gl::Texture *source) +{ + UNREACHABLE(); + return gl::InternalError() << "CHROMIUM_copy_compressed_texture exposed but not implemented."; +} + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/TextureImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/TextureImpl.h index ad4ec8d830..3b4f28f5f7 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/TextureImpl.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/TextureImpl.h @@ -14,8 +14,10 @@ #include "angle_gl.h" #include "common/angleutils.h" #include "libANGLE/Error.h" -#include "libANGLE/FramebufferAttachment.h" #include "libANGLE/ImageIndex.h" +#include "libANGLE/Stream.h" +#include "libANGLE/Texture.h" +#include "libANGLE/renderer/FramebufferAttachmentObjectImpl.h" namespace egl { @@ -36,38 +38,120 @@ struct TextureState; namespace rx { +class ContextImpl; class TextureImpl : public FramebufferAttachmentObjectImpl { public: - TextureImpl() {} - virtual ~TextureImpl() {} + TextureImpl(const gl::TextureState &state); + ~TextureImpl() override; - virtual void setUsage(GLenum usage) = 0; + virtual gl::Error onDestroy(const gl::Context *context); - virtual gl::Error setImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, GLenum format, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) = 0; - virtual gl::Error setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) = 0; + virtual gl::Error setImage(const gl::Context *context, + GLenum target, + size_t level, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) = 0; + virtual gl::Error setSubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) = 0; - virtual gl::Error setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, - const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) = 0; - virtual gl::Error setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, - const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) = 0; + virtual gl::Error setCompressedImage(const gl::Context *context, + GLenum target, + size_t level, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) = 0; + virtual gl::Error setCompressedSubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) = 0; - virtual gl::Error copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat, + virtual gl::Error copyImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Rectangle &sourceArea, + GLenum internalFormat, const gl::Framebuffer *source) = 0; - virtual gl::Error copySubImage(GLenum target, size_t level, const gl::Offset &destOffset, const gl::Rectangle &sourceArea, + virtual gl::Error copySubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, const gl::Framebuffer *source) = 0; - virtual gl::Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) = 0; + virtual gl::Error copyTexture(const gl::Context *context, + GLenum target, + size_t level, + GLenum internalFormat, + GLenum type, + size_t sourceLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source); + virtual gl::Error copySubTexture(const gl::Context *context, + GLenum target, + size_t level, + const gl::Offset &destOffset, + size_t sourceLevel, + const gl::Rectangle &sourceArea, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source); - virtual gl::Error setEGLImageTarget(GLenum target, egl::Image *image) = 0; + virtual gl::Error copyCompressedTexture(const gl::Context *context, const gl::Texture *source); - virtual gl::Error generateMipmaps(const gl::TextureState &textureState) = 0; + virtual gl::Error setStorage(const gl::Context *context, + GLenum target, + size_t levels, + GLenum internalFormat, + const gl::Extents &size) = 0; - virtual void bindTexImage(egl::Surface *surface) = 0; - virtual void releaseTexImage() = 0; + virtual gl::Error setStorageMultisample(const gl::Context *context, + GLenum target, + GLsizei samples, + GLint internalformat, + const gl::Extents &size, + bool fixedSampleLocations) = 0; + + virtual gl::Error setEGLImageTarget(const gl::Context *context, + GLenum target, + egl::Image *image) = 0; + + virtual gl::Error setImageExternal(const gl::Context *context, + GLenum target, + egl::Stream *stream, + const egl::Stream::GLTextureDescription &desc) = 0; + + virtual gl::Error generateMipmap(const gl::Context *context) = 0; + + virtual gl::Error setBaseLevel(const gl::Context *context, GLuint baseLevel) = 0; + + virtual gl::Error bindTexImage(const gl::Context *context, egl::Surface *surface) = 0; + virtual gl::Error releaseTexImage(const gl::Context *context) = 0; + + virtual void syncState(const gl::Texture::DirtyBits &dirtyBits) = 0; + + protected: + const gl::TextureState &mState; }; } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/TextureImpl_mock.h b/src/3rdparty/angle/src/libANGLE/renderer/TextureImpl_mock.h index 3eb43f0033..e7fa441781 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/TextureImpl_mock.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/TextureImpl_mock.h @@ -19,23 +19,111 @@ namespace rx class MockTextureImpl : public TextureImpl { public: + MockTextureImpl() : TextureImpl(mMockState), mMockState(GL_TEXTURE_2D) {} virtual ~MockTextureImpl() { destructor(); } - MOCK_METHOD1(setUsage, void(GLenum)); - MOCK_METHOD8(setImage, gl::Error(GLenum, size_t, GLenum, const gl::Extents &, GLenum, GLenum, const gl::PixelUnpackState &, const uint8_t *)); - MOCK_METHOD7(setSubImage, gl::Error(GLenum, size_t, const gl::Box &, GLenum, GLenum, const gl::PixelUnpackState &, const uint8_t *)); - MOCK_METHOD7(setCompressedImage, gl::Error(GLenum, size_t, GLenum, const gl::Extents &, const gl::PixelUnpackState &, size_t, const uint8_t *)); - MOCK_METHOD7(setCompressedSubImage, gl::Error(GLenum, size_t, const gl::Box &, GLenum, const gl::PixelUnpackState &, size_t, const uint8_t *)); - MOCK_METHOD5(copyImage, gl::Error(GLenum, size_t, const gl::Rectangle &, GLenum, const gl::Framebuffer *)); - MOCK_METHOD5(copySubImage, gl::Error(GLenum, size_t, const gl::Offset &, const gl::Rectangle &, const gl::Framebuffer *)); - MOCK_METHOD4(setStorage, gl::Error(GLenum, size_t, GLenum, const gl::Extents &)); - MOCK_METHOD2(setEGLImageTarget, gl::Error(GLenum, egl::Image *)); - MOCK_METHOD1(generateMipmaps, gl::Error(const gl::TextureState &)); - MOCK_METHOD1(bindTexImage, void(egl::Surface *)); - MOCK_METHOD0(releaseTexImage, void(void)); + MOCK_METHOD9(setImage, + gl::Error(const gl::Context *, + GLenum, + size_t, + GLenum, + const gl::Extents &, + GLenum, + GLenum, + const gl::PixelUnpackState &, + const uint8_t *)); + MOCK_METHOD8(setSubImage, + gl::Error(const gl::Context *, + GLenum, + size_t, + const gl::Box &, + GLenum, + GLenum, + const gl::PixelUnpackState &, + const uint8_t *)); + MOCK_METHOD8(setCompressedImage, + gl::Error(const gl::Context *, + GLenum, + size_t, + GLenum, + const gl::Extents &, + const gl::PixelUnpackState &, + size_t, + const uint8_t *)); + MOCK_METHOD8(setCompressedSubImage, + gl::Error(const gl::Context *, + GLenum, + size_t, + const gl::Box &, + GLenum, + const gl::PixelUnpackState &, + size_t, + const uint8_t *)); + MOCK_METHOD6(copyImage, + gl::Error(const gl::Context *, + GLenum, + size_t, + const gl::Rectangle &, + GLenum, + const gl::Framebuffer *)); + MOCK_METHOD6(copySubImage, + gl::Error(const gl::Context *, + GLenum, + size_t, + const gl::Offset &, + const gl::Rectangle &, + const gl::Framebuffer *)); + MOCK_METHOD10(copyTexture, + gl::Error(const gl::Context *, + GLenum, + size_t, + GLenum, + GLenum, + size_t, + bool, + bool, + bool, + const gl::Texture *)); + MOCK_METHOD10(copySubTexture, + gl::Error(const gl::Context *, + GLenum, + size_t, + const gl::Offset &, + size_t, + const gl::Rectangle &, + bool, + bool, + bool, + const gl::Texture *)); + MOCK_METHOD2(copyCompressedTexture, gl::Error(const gl::Context *, const gl::Texture *source)); + MOCK_METHOD5(setStorage, + gl::Error(const gl::Context *, GLenum, size_t, GLenum, const gl::Extents &)); + MOCK_METHOD4(setImageExternal, + gl::Error(const gl::Context *, + GLenum, + egl::Stream *, + const egl::Stream::GLTextureDescription &)); + MOCK_METHOD3(setEGLImageTarget, gl::Error(const gl::Context *, GLenum, egl::Image *)); + MOCK_METHOD1(generateMipmap, gl::Error(const gl::Context *)); + MOCK_METHOD2(bindTexImage, gl::Error(const gl::Context *, egl::Surface *)); + MOCK_METHOD1(releaseTexImage, gl::Error(const gl::Context *)); - MOCK_METHOD2(getAttachmentRenderTarget, gl::Error(const gl::FramebufferAttachment::Target &, FramebufferAttachmentRenderTarget **)); + MOCK_METHOD4(getAttachmentRenderTarget, + gl::Error(const gl::Context *, + GLenum, + const gl::ImageIndex &, + FramebufferAttachmentRenderTarget **)); + + MOCK_METHOD6(setStorageMultisample, + gl::Error(const gl::Context *, GLenum, GLsizei, GLint, const gl::Extents &, bool)); + + MOCK_METHOD2(setBaseLevel, gl::Error(const gl::Context *, GLuint)); + + MOCK_METHOD1(syncState, void(const gl::Texture::DirtyBits &)); MOCK_METHOD0(destructor, void()); + + protected: + gl::TextureState mMockState; }; } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/TransformFeedbackImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/TransformFeedbackImpl.h index 5df7cad87b..ad371e9b36 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/TransformFeedbackImpl.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/TransformFeedbackImpl.h @@ -18,6 +18,7 @@ namespace rx class TransformFeedbackImpl : angle::NonCopyable { public: + TransformFeedbackImpl(const gl::TransformFeedbackState &state) : mState(state) {} virtual ~TransformFeedbackImpl() { } virtual void begin(GLenum primitiveMode) = 0; @@ -25,8 +26,12 @@ class TransformFeedbackImpl : angle::NonCopyable virtual void pause() = 0; virtual void resume() = 0; - virtual void bindGenericBuffer(const BindingPointer &binding) = 0; - virtual void bindIndexedBuffer(size_t index, const OffsetBindingPointer &binding) = 0; + virtual void bindGenericBuffer(const gl::BindingPointer &binding) = 0; + virtual void bindIndexedBuffer(size_t index, + const gl::OffsetBindingPointer &binding) = 0; + + protected: + const gl::TransformFeedbackState &mState; }; } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/TransformFeedbackImpl_mock.h b/src/3rdparty/angle/src/libANGLE/renderer/TransformFeedbackImpl_mock.h index c7d2fc620d..2de3ad79a9 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/TransformFeedbackImpl_mock.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/TransformFeedbackImpl_mock.h @@ -19,6 +19,10 @@ namespace rx class MockTransformFeedbackImpl : public TransformFeedbackImpl { public: + MockTransformFeedbackImpl(const gl::TransformFeedbackState &state) + : TransformFeedbackImpl(state) + { + } ~MockTransformFeedbackImpl() { destructor(); } MOCK_METHOD1(begin, void(GLenum primitiveMode)); @@ -26,8 +30,8 @@ class MockTransformFeedbackImpl : public TransformFeedbackImpl MOCK_METHOD0(pause, void()); MOCK_METHOD0(resume, void()); - MOCK_METHOD1(bindGenericBuffer, void(const BindingPointer &)); - MOCK_METHOD2(bindIndexedBuffer, void(size_t, const OffsetBindingPointer &)); + MOCK_METHOD1(bindGenericBuffer, void(const gl::BindingPointer &)); + MOCK_METHOD2(bindIndexedBuffer, void(size_t, const gl::OffsetBindingPointer &)); MOCK_METHOD0(destructor, void()); }; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/VertexArrayImpl.h b/src/3rdparty/angle/src/libANGLE/renderer/VertexArrayImpl.h index 13617c7ecb..e48cc53d6c 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/VertexArrayImpl.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/VertexArrayImpl.h @@ -15,15 +15,21 @@ namespace rx { +class ContextImpl; class VertexArrayImpl : angle::NonCopyable { public: - VertexArrayImpl(const gl::VertexArray::Data &data) : mData(data) { } - virtual ~VertexArrayImpl() { } - virtual void syncState(const gl::VertexArray::DirtyBits &dirtyBits) {} + VertexArrayImpl(const gl::VertexArrayState &state) : mState(state) {} + virtual void syncState(const gl::Context *context, const gl::VertexArray::DirtyBits &dirtyBits) + { + } + + virtual void destroy(const gl::Context *context) {} + virtual ~VertexArrayImpl() {} + protected: - const gl::VertexArray::Data &mData; + const gl::VertexArrayState &mState; }; } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/Workarounds.h b/src/3rdparty/angle/src/libANGLE/renderer/Workarounds.h deleted file mode 100644 index b73f4a5472..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/Workarounds.h +++ /dev/null @@ -1,74 +0,0 @@ -// -// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// angletypes.h: Workarounds for driver bugs and other issues. - -#ifndef LIBANGLE_RENDERER_WORKAROUNDS_H_ -#define LIBANGLE_RENDERER_WORKAROUNDS_H_ - -// TODO(jmadill,zmo,geofflang): make a workarounds library that can operate -// independent of ANGLE's renderer. Workarounds should also be accessible -// outside of the Renderer. - -namespace rx -{ - -struct D3DCompilerWorkarounds : angle::NonCopyable -{ - D3DCompilerWorkarounds() - : skipOptimization(false), - useMaxOptimization(false), - enableIEEEStrictness(false) - {} - - void reset() - { - skipOptimization = false; - useMaxOptimization = false; - enableIEEEStrictness = false; - } - - bool skipOptimization; - bool useMaxOptimization; - - // IEEE strictness needs to be enabled for NANs to work. - bool enableIEEEStrictness; -}; - -struct Workarounds -{ - Workarounds() - : mrtPerfWorkaround(false), - setDataFasterThanImageUpload(false), - zeroMaxLodWorkaround(false), - useInstancedPointSpriteEmulation(false) - {} - - // On some systems, having extra rendertargets than necessary slows down the shader. - // We can fix this by optimizing those out of the shader. At the same time, we can - // work around a bug on some nVidia drivers that they ignore "null" render targets - // in D3D11, by compacting the active color attachments list to omit null entries. - bool mrtPerfWorkaround; - - bool setDataFasterThanImageUpload; - - // Some renderers can't disable mipmaps on a mipmapped texture (i.e. solely sample from level zero, and ignore the other levels). - // D3D11 Feature Level 10+ does this by setting MaxLOD to 0.0f in the Sampler state. D3D9 sets D3DSAMP_MIPFILTER to D3DTEXF_NONE. - // There is no equivalent to this in D3D11 Feature Level 9_3. - // This causes problems when (for example) an application creates a mipmapped texture2D, but sets GL_TEXTURE_MIN_FILTER to GL_NEAREST (i.e disables mipmaps). - // To work around this, D3D11 FL9_3 has to create two copies of the texture. The textures' level zeros are identical, but only one texture has mips. - bool zeroMaxLodWorkaround; - - // Some renderers do not support Geometry Shaders so the Geometry Shader-based - // PointSprite emulation will not work. - // To work around this, D3D11 FL9_3 has to use a different pointsprite - // emulation that is implemented using instanced quads. - bool useInstancedPointSpriteEmulation; -}; - -} - -#endif // LIBANGLE_RENDERER_WORKAROUNDS_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/angle_format_data.json b/src/3rdparty/angle/src/libANGLE/renderer/angle_format_data.json new file mode 100644 index 0000000000..5b3a226e2e --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/angle_format_data.json @@ -0,0 +1,24 @@ +{ + "B5G6R5_UNORM": { + "fboImplementationInternalFormat": "GL_RGB565" + }, + "B5G5R5A1_UNORM": { + "fboImplementationInternalFormat": "GL_RGB5_A1", + "channelStruct": "A1R5G5B5" + }, + "B8G8R8X8_UNORM": { + "glInternalFormat": "GL_BGRA8_EXT", + "channelStruct": "B8G8R8X8" + }, + "R9G9B9E5_SHAREDEXP": { + "componentType": "float", + "channelStruct": "R9G9B9E5" + }, + "B4G4R4A4_UNORM": { + "fboImplementationInternalFormat": "GL_RGBA4", + "channelStruct": "A4R4G4B4" + }, + "R8G8B8A8_UNORM_SRGB": { + "channelStruct": "R8G8B8A8SRGB" + } +} diff --git a/src/3rdparty/angle/src/libANGLE/renderer/angle_format_map.json b/src/3rdparty/angle/src/libANGLE/renderer/angle_format_map.json new file mode 100644 index 0000000000..5a4e487cbd --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/angle_format_map.json @@ -0,0 +1,132 @@ +[ + [ "GL_ALPHA16F_EXT", "A16_FLOAT" ], + [ "GL_ALPHA32F_EXT", "A32_FLOAT" ], + [ "GL_ALPHA8_EXT", "A8_UNORM" ], + [ "GL_BGR565_ANGLEX", "B5G6R5_UNORM" ], + [ "GL_BGR5_A1_ANGLEX", "B5G5R5A1_UNORM" ], + [ "GL_BGRA4_ANGLEX", "B4G4R4A4_UNORM" ], + [ "GL_BGRA8_EXT", "B8G8R8A8_UNORM" ], + [ "GL_BGRA8_SRGB_ANGLEX", "B8G8R8A8_UNORM_SRGB"], + [ "GL_BGRX8_ANGLEX", "B8G8R8X8_UNORM" ], + [ "GL_COMPRESSED_R11_EAC", "EAC_R11_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RG11_EAC", "EAC_R11G11_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGB8_ETC2", "ETC2_R8G8B8_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2", "ETC2_R8G8B8A1_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA8_ETC2_EAC", "ETC2_R8G8B8A8_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT", "BC1_RGBA_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE", "BC2_RGBA_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE", "BC3_RGBA_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_4x4_KHR", "ASTC_4x4_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_5x4_KHR", "ASTC_5x4_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_5x5_KHR", "ASTC_5x5_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_6x5_KHR", "ASTC_6x5_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_6x6_KHR", "ASTC_6x6_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_8x5_KHR", "ASTC_8x5_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_8x6_KHR", "ASTC_8x6_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_8x8_KHR", "ASTC_8x8_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_10x5_KHR", "ASTC_10x5_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_10x6_KHR", "ASTC_10x6_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_10x8_KHR", "ASTC_10x8_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_10x10_KHR", "ASTC_10x10_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_12x10_KHR", "ASTC_12x10_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGBA_ASTC_12x12_KHR", "ASTC_12x12_UNORM_BLOCK" ], + [ "GL_COMPRESSED_RGB_S3TC_DXT1_EXT", "BC1_RGB_UNORM_BLOCK" ], + [ "GL_COMPRESSED_SIGNED_R11_EAC", "EAC_R11_SNORM_BLOCK" ], + [ "GL_COMPRESSED_SIGNED_RG11_EAC", "EAC_R11G11_SNORM_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR", "ASTC_4x4_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR", "ASTC_5x4_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR", "ASTC_5x5_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR", "ASTC_6x5_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR", "ASTC_6x6_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR", "ASTC_8x5_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR", "ASTC_8x6_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR", "ASTC_8x8_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR", "ASTC_10x5_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR", "ASTC_10x6_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR", "ASTC_10x8_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR", "ASTC_10x10_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR", "ASTC_12x10_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR", "ASTC_12x12_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC", "ETC2_R8G8B8A8_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_ETC2", "ETC2_R8G8B8_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2", "ETC2_R8G8B8A1_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT", "BC1_RGBA_UNORM_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT", "BC2_RGBA_UNORM_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT", "BC3_RGBA_UNORM_SRGB_BLOCK" ], + [ "GL_COMPRESSED_SRGB_S3TC_DXT1_EXT", "BC1_RGB_UNORM_SRGB_BLOCK" ], + [ "GL_DEPTH24_STENCIL8", "D24_UNORM_S8_UINT" ], + [ "GL_DEPTH32F_STENCIL8", "D32_FLOAT_S8X24_UINT" ], + [ "GL_DEPTH_COMPONENT16", "D16_UNORM" ], + [ "GL_DEPTH_COMPONENT24", "D24_UNORM" ], + [ "GL_DEPTH_COMPONENT32F", "D32_FLOAT" ], + [ "GL_DEPTH_COMPONENT32_OES", "D32_UNORM" ], + [ "GL_ETC1_RGB8_OES", "ETC1_R8G8B8_UNORM_BLOCK" ], + [ "GL_ETC1_RGB8_LOSSY_DECODE_ANGLE", "ETC1_LOSSY_DECODE_R8G8B8_UNORM_BLOCK" ], + [ "GL_LUMINANCE16F_EXT", "L16_FLOAT" ], + [ "GL_LUMINANCE32F_EXT", "L32_FLOAT" ], + [ "GL_LUMINANCE8_ALPHA8_EXT", "L8A8_UNORM" ], + [ "GL_LUMINANCE8_EXT", "L8_UNORM" ], + [ "GL_LUMINANCE_ALPHA16F_EXT", "L16A16_FLOAT" ], + [ "GL_LUMINANCE_ALPHA32F_EXT", "L32A32_FLOAT" ], + [ "GL_NONE", "NONE" ], + [ "GL_R11F_G11F_B10F", "R11G11B10_FLOAT" ], + [ "GL_R16F", "R16_FLOAT" ], + [ "GL_R16I", "R16_SINT" ], + [ "GL_R16UI", "R16_UINT" ], + [ "GL_R32F", "R32_FLOAT" ], + [ "GL_R32I", "R32_SINT" ], + [ "GL_R32UI", "R32_UINT" ], + [ "GL_R8", "R8_UNORM" ], + [ "GL_R8I", "R8_SINT" ], + [ "GL_R8UI", "R8_UINT" ], + [ "GL_R8_SNORM", "R8_SNORM" ], + [ "GL_RG16F", "R16G16_FLOAT" ], + [ "GL_RG16I", "R16G16_SINT" ], + [ "GL_RG16UI", "R16G16_UINT" ], + [ "GL_RG32F", "R32G32_FLOAT" ], + [ "GL_RG32I", "R32G32_SINT" ], + [ "GL_RG32UI", "R32G32_UINT" ], + [ "GL_RG8", "R8G8_UNORM" ], + [ "GL_RG8I", "R8G8_SINT" ], + [ "GL_RG8UI", "R8G8_UINT" ], + [ "GL_RG8_SNORM", "R8G8_SNORM" ], + [ "GL_RGB", "R8G8B8_UNORM" ], + [ "GL_RGB10_A2", "R10G10B10A2_UNORM" ], + [ "GL_RGB10_A2UI", "R10G10B10A2_UINT" ], + [ "GL_RGB16F", "R16G16B16_FLOAT" ], + [ "GL_RGB16I", "R16G16B16_SINT" ], + [ "GL_RGB16UI", "R16G16B16_UINT" ], + [ "GL_RGB32F", "R32G32B32_FLOAT" ], + [ "GL_RGB32I", "R32G32B32_SINT" ], + [ "GL_RGB32UI", "R32G32B32_UINT" ], + [ "GL_RGB565", "R5G6B5_UNORM" ], + [ "GL_RGB5_A1", "R5G5B5A1_UNORM" ], + [ "GL_RGB8", "R8G8B8_UNORM" ], + [ "GL_RGB8I", "R8G8B8_SINT" ], + [ "GL_RGB8UI", "R8G8B8_UINT" ], + [ "GL_RGB8_SNORM", "R8G8B8_SNORM" ], + [ "GL_RGB9_E5", "R9G9B9E5_SHAREDEXP" ], + [ "GL_RGBA", "R8G8B8A8_UNORM" ], + [ "GL_RGBA16F", "R16G16B16A16_FLOAT" ], + [ "GL_RGBA16I", "R16G16B16A16_SINT" ], + [ "GL_RGBA16UI", "R16G16B16A16_UINT" ], + [ "GL_RGBA32F", "R32G32B32A32_FLOAT" ], + [ "GL_RGBA32I", "R32G32B32A32_SINT" ], + [ "GL_RGBA32UI", "R32G32B32A32_UINT" ], + [ "GL_RGBA4", "R4G4B4A4_UNORM" ], + [ "GL_RGBA8", "R8G8B8A8_UNORM" ], + [ "GL_RGBA8I", "R8G8B8A8_SINT" ], + [ "GL_RGBA8UI", "R8G8B8A8_UINT" ], + [ "GL_RGBA8_SNORM", "R8G8B8A8_SNORM" ], + [ "GL_SRGB8", "R8G8B8_UNORM_SRGB" ], + [ "GL_SRGB8_ALPHA8", "R8G8B8A8_UNORM_SRGB" ], + [ "GL_STENCIL_INDEX8", "S8_UINT" ], + [ "GL_R16_EXT", "R16_UNORM" ], + [ "GL_RG16_EXT", "R16G16_UNORM" ], + [ "GL_RGB16_EXT", "R16G16B16_UNORM" ], + [ "GL_RGBA16_EXT", "R16G16B16A16_UNORM" ], + [ "GL_R16_SNORM_EXT", "R16_SNORM" ], + [ "GL_RG16_SNORM_EXT", "R16G16_SNORM" ], + [ "GL_RGB16_SNORM_EXT", "R16G16B16_SNORM" ], + [ "GL_RGBA16_SNORM_EXT", "R16G16B16A16_SNORM" ] +] diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/BufferD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/BufferD3D.cpp index ffca99c3ac..7769ab2b75 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/BufferD3D.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/BufferD3D.cpp @@ -12,42 +12,33 @@ #include "common/utilities.h" #include "libANGLE/renderer/d3d/IndexBuffer.h" #include "libANGLE/renderer/d3d/VertexBuffer.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" namespace rx { unsigned int BufferD3D::mNextSerial = 1; -BufferD3D::BufferD3D(BufferFactoryD3D *factory) - : BufferImpl(), +BufferD3D::BufferD3D(const gl::BufferState &state, BufferFactoryD3D *factory) + : BufferImpl(state), mFactory(factory), - mStaticVertexBuffer(nullptr), mStaticIndexBuffer(nullptr), - mStaticBufferCache(nullptr), mStaticBufferCacheTotalSize(0), mStaticVertexBufferOutOfDate(false), mUnmodifiedDataUse(0), - mUsage(D3D_BUFFER_USAGE_STATIC) + mUsage(D3DBufferUsage::STATIC) { updateSerial(); } BufferD3D::~BufferD3D() { - SafeDelete(mStaticVertexBuffer); SafeDelete(mStaticIndexBuffer); - - emptyStaticBufferCache(); } void BufferD3D::emptyStaticBufferCache() { - if (mStaticBufferCache != nullptr) - { - SafeDeleteContainer(*mStaticBufferCache); - SafeDelete(mStaticBufferCache); - } - + mStaticVertexBuffers.clear(); mStaticBufferCacheTotalSize = 0; } @@ -56,35 +47,37 @@ void BufferD3D::updateSerial() mSerial = mNextSerial++; } -void BufferD3D::updateD3DBufferUsage(GLenum usage) +void BufferD3D::updateD3DBufferUsage(const gl::Context *context, gl::BufferUsage usage) { switch (usage) { - case GL_STATIC_DRAW: - case GL_STATIC_READ: - case GL_STATIC_COPY: - mUsage = D3D_BUFFER_USAGE_STATIC; - initializeStaticData(); + case gl::BufferUsage::StaticCopy: + case gl::BufferUsage::StaticDraw: + case gl::BufferUsage::StaticRead: + mUsage = D3DBufferUsage::STATIC; + initializeStaticData(context); break; - case GL_STREAM_DRAW: - case GL_STREAM_READ: - case GL_STREAM_COPY: - case GL_DYNAMIC_READ: - case GL_DYNAMIC_COPY: - case GL_DYNAMIC_DRAW: - mUsage = D3D_BUFFER_USAGE_DYNAMIC; + case gl::BufferUsage::DynamicCopy: + case gl::BufferUsage::DynamicDraw: + case gl::BufferUsage::DynamicRead: + case gl::BufferUsage::StreamCopy: + case gl::BufferUsage::StreamDraw: + case gl::BufferUsage::StreamRead: + mUsage = D3DBufferUsage::DYNAMIC; break; default: UNREACHABLE(); } } -void BufferD3D::initializeStaticData() +void BufferD3D::initializeStaticData(const gl::Context *context) { - if (!mStaticVertexBuffer) + if (mStaticVertexBuffers.empty()) { - mStaticVertexBuffer = new StaticVertexBufferInterface(mFactory); + StaticVertexBufferInterface *newStaticBuffer = new StaticVertexBufferInterface(mFactory); + mStaticVertexBuffers.push_back( + std::unique_ptr(newStaticBuffer)); } if (!mStaticIndexBuffer) { @@ -97,168 +90,101 @@ StaticIndexBufferInterface *BufferD3D::getStaticIndexBuffer() return mStaticIndexBuffer; } -StaticVertexBufferInterface *BufferD3D::getStaticVertexBuffer( - const gl::VertexAttribute &attribute, - D3DStaticBufferCreationType creationType) +StaticVertexBufferInterface *BufferD3D::getStaticVertexBuffer(const gl::VertexAttribute &attribute, + const gl::VertexBinding &binding) { - if (!mStaticVertexBuffer) + if (mStaticVertexBuffers.empty()) { // Early out if there aren't any static buffers at all - ASSERT(mStaticBufferCache == nullptr); return nullptr; } - if (mStaticBufferCache == nullptr && !mStaticVertexBuffer->isCommitted()) + // Early out, the attribute can be added to mStaticVertexBuffer. + if (mStaticVertexBuffers.size() == 1 && mStaticVertexBuffers[0]->empty()) { - // Early out, the attribute can be added to mStaticVertexBuffer or is already in there - return mStaticVertexBuffer; + return mStaticVertexBuffers[0].get(); } + // Cache size limiting: track the total allocated buffer sizes. + size_t currentTotalSize = 0; + // At this point, see if any of the existing static buffers contains the attribute data - - // If the default static vertex buffer contains the attribute, then return it - if (mStaticVertexBuffer->lookupAttribute(attribute, nullptr)) + // If there is a cached static buffer that already contains the attribute, then return it + for (const auto &staticBuffer : mStaticVertexBuffers) { - return mStaticVertexBuffer; - } - - if (mStaticBufferCache != nullptr) - { - // If there is a cached static buffer that already contains the attribute, then return it - for (StaticVertexBufferInterface *staticBuffer : *mStaticBufferCache) + if (staticBuffer->matchesAttribute(attribute, binding)) { - if (staticBuffer->lookupAttribute(attribute, nullptr)) - { - return staticBuffer; - } + return staticBuffer.get(); } + + currentTotalSize += staticBuffer->getBufferSize(); } - if (!mStaticVertexBuffer->isCommitted()) - { - // None of the existing static buffers contain the attribute data and we are able to add - // the data to mStaticVertexBuffer, so we should just do so - return mStaticVertexBuffer; - } + // Cache size limiting: Clean-up threshold is four times the base buffer size, with a minimum. + ASSERT(getSize() < std::numeric_limits::max() / 4u); + size_t sizeThreshold = std::max(getSize() * 4u, static_cast(0x1000u)); - // At this point, we must create a new static buffer for the attribute data - if (creationType != D3D_BUFFER_CREATE_IF_NECESSARY) - { - return nullptr; - } - - ASSERT(mStaticVertexBuffer); - ASSERT(mStaticVertexBuffer->isCommitted()); - unsigned int staticVertexBufferSize = mStaticVertexBuffer->getBufferSize(); - if (IsUnsignedAdditionSafe(staticVertexBufferSize, mStaticBufferCacheTotalSize)) - { - // Ensure that the total size of the static buffer cache remains less than 4x the - // size of the original buffer - unsigned int maxStaticCacheSize = - IsUnsignedMultiplicationSafe(static_cast(getSize()), 4u) - ? 4u * static_cast(getSize()) - : std::numeric_limits::max(); - - // We can't reuse the default static vertex buffer, so we add it to the cache - if (staticVertexBufferSize + mStaticBufferCacheTotalSize <= maxStaticCacheSize) - { - if (mStaticBufferCache == nullptr) - { - mStaticBufferCache = new std::vector(); - } - - mStaticBufferCacheTotalSize += staticVertexBufferSize; - (*mStaticBufferCache).push_back(mStaticVertexBuffer); - mStaticVertexBuffer = nullptr; - - // Then reinitialize the static buffers to create a new static vertex buffer - initializeStaticData(); - - // Return the default static vertex buffer - return mStaticVertexBuffer; - } - } - - // At this point: - // - mStaticVertexBuffer is committed and can't be altered - // - mStaticBufferCache is full (or nearly overflowing) - // The inputted attribute should be put in some static buffer at some point, but it can't - // go in one right now, since mStaticBufferCache is full and we can't delete mStaticVertexBuffer - // in case another attribute is relying upon it for the current draw. - // We therefore mark mStaticVertexBuffer for deletion at the next possible time. - mStaticVertexBufferOutOfDate = true; - return nullptr; -} - -void BufferD3D::reinitOutOfDateStaticData() -{ - if (mStaticVertexBufferOutOfDate) - { - // During the last draw the caller tried to use some attribute with static data, but neither - // the static buffer cache nor mStaticVertexBuffer contained that data. - // Therefore, invalidate mStaticVertexBuffer so that if the caller tries to use that - // attribute in the next draw, it'll successfully get put into mStaticVertexBuffer. - invalidateStaticData(D3D_BUFFER_INVALIDATE_DEFAULT_BUFFER_ONLY); - mStaticVertexBufferOutOfDate = false; - } -} - -void BufferD3D::invalidateStaticData(D3DBufferInvalidationType invalidationType) -{ - if (invalidationType == D3D_BUFFER_INVALIDATE_WHOLE_CACHE && mStaticBufferCache != nullptr) + // If we're past the threshold, clear the buffer cache. Note that this will release buffers + // that are currenly bound, and in an edge case can even translate the same attribute twice + // in the same draw call. It will not delete currently bound buffers, however, because they + // are ref counted. + if (currentTotalSize > sizeThreshold) { emptyStaticBufferCache(); } - if ((mStaticVertexBuffer && mStaticVertexBuffer->getBufferSize() != 0) || (mStaticIndexBuffer && mStaticIndexBuffer->getBufferSize() != 0)) - { - SafeDelete(mStaticVertexBuffer); - SafeDelete(mStaticIndexBuffer); + // At this point, we must create a new static buffer for the attribute data. + StaticVertexBufferInterface *newStaticBuffer = new StaticVertexBufferInterface(mFactory); + newStaticBuffer->setAttribute(attribute, binding); + mStaticVertexBuffers.push_back(std::unique_ptr(newStaticBuffer)); + return newStaticBuffer; +} - // If the buffer was created with a static usage then we recreate the static - // buffers so that they are populated the next time we use this buffer. - if (mUsage == D3D_BUFFER_USAGE_STATIC) - { - initializeStaticData(); - } +void BufferD3D::invalidateStaticData(const gl::Context *context) +{ + emptyStaticBufferCache(); + + if (mStaticIndexBuffer && mStaticIndexBuffer->getBufferSize() != 0) + { + SafeDelete(mStaticIndexBuffer); + } + + // If the buffer was created with a static usage then we recreate the static + // buffers so that they are populated the next time we use this buffer. + if (mUsage == D3DBufferUsage::STATIC) + { + initializeStaticData(context); } mUnmodifiedDataUse = 0; } // Creates static buffers if sufficient used data has been left unmodified -void BufferD3D::promoteStaticUsage(int dataSize) +void BufferD3D::promoteStaticUsage(const gl::Context *context, int dataSize) { - if (!mStaticVertexBuffer && !mStaticIndexBuffer) + if (mUsage == D3DBufferUsage::DYNAMIC) { - // There isn't any scenario that involves promoting static usage and the static buffer cache - // being non-empty - ASSERT(mStaticBufferCache == nullptr); - mUnmodifiedDataUse += dataSize; if (mUnmodifiedDataUse > 3 * getSize()) { - initializeStaticData(); + updateD3DBufferUsage(context, gl::BufferUsage::StaticDraw); } } } -gl::Error BufferD3D::getIndexRange(GLenum type, +gl::Error BufferD3D::getIndexRange(const gl::Context *context, + GLenum type, size_t offset, size_t count, bool primitiveRestartEnabled, gl::IndexRange *outRange) { const uint8_t *data = nullptr; - gl::Error error = getData(&data); - if (error.isError()) - { - return error; - } + ANGLE_TRY(getData(context, &data)); *outRange = gl::ComputeIndexRange(type, data + offset, count, primitiveRestartEnabled); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -} +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/BufferD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/BufferD3D.h index a27ca9857a..60153748e6 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/BufferD3D.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/BufferD3D.h @@ -15,71 +15,69 @@ #include #include +namespace gl +{ +struct VertexAttribute; +class VertexBinding; +} + namespace rx { class BufferFactoryD3D; class StaticIndexBufferInterface; class StaticVertexBufferInterface; -enum D3DBufferUsage +enum class D3DBufferUsage { - D3D_BUFFER_USAGE_STATIC, - D3D_BUFFER_USAGE_DYNAMIC, -}; - -enum D3DBufferInvalidationType -{ - D3D_BUFFER_INVALIDATE_WHOLE_CACHE, - D3D_BUFFER_INVALIDATE_DEFAULT_BUFFER_ONLY, -}; - -enum D3DStaticBufferCreationType -{ - D3D_BUFFER_CREATE_IF_NECESSARY, - D3D_BUFFER_DO_NOT_CREATE, + STATIC, + DYNAMIC, }; class BufferD3D : public BufferImpl { public: - BufferD3D(BufferFactoryD3D *factory); - virtual ~BufferD3D(); + BufferD3D(const gl::BufferState &state, BufferFactoryD3D *factory); + ~BufferD3D() override; unsigned int getSerial() const { return mSerial; } virtual size_t getSize() const = 0; virtual bool supportsDirectBinding() const = 0; - virtual void markTransformFeedbackUsage() = 0; - virtual gl::Error getData(const uint8_t **outData) = 0; + virtual gl::Error markTransformFeedbackUsage(const gl::Context *context) = 0; + virtual gl::Error getData(const gl::Context *context, const uint8_t **outData) = 0; + // Warning: you should ensure binding really matches attrib.bindingIndex before using this + // function. StaticVertexBufferInterface *getStaticVertexBuffer(const gl::VertexAttribute &attribute, - D3DStaticBufferCreationType creationType); + const gl::VertexBinding &binding); StaticIndexBufferInterface *getStaticIndexBuffer(); - void initializeStaticData(); - void invalidateStaticData(D3DBufferInvalidationType invalidationType); - void reinitOutOfDateStaticData(); + virtual void initializeStaticData(const gl::Context *context); + virtual void invalidateStaticData(const gl::Context *context); - void promoteStaticUsage(int dataSize); + void promoteStaticUsage(const gl::Context *context, int dataSize); - gl::Error getIndexRange(GLenum type, + gl::Error getIndexRange(const gl::Context *context, + GLenum type, size_t offset, size_t count, bool primitiveRestartEnabled, gl::IndexRange *outRange) override; + BufferFactoryD3D *getFactory() const { return mFactory; } + D3DBufferUsage getUsage() const { return mUsage; } + protected: void updateSerial(); - void updateD3DBufferUsage(GLenum usage); + void updateD3DBufferUsage(const gl::Context *context, gl::BufferUsage usage); void emptyStaticBufferCache(); BufferFactoryD3D *mFactory; unsigned int mSerial; static unsigned int mNextSerial; - StaticVertexBufferInterface *mStaticVertexBuffer; + std::vector> mStaticVertexBuffers; StaticIndexBufferInterface *mStaticIndexBuffer; - std::vector *mStaticBufferCache; unsigned int mStaticBufferCacheTotalSize; unsigned int mStaticVertexBufferOutOfDate; unsigned int mUnmodifiedDataUse; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/CompilerD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/CompilerD3D.cpp index 6f8d1717cd..8ceeec3c39 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/CompilerD3D.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/CompilerD3D.cpp @@ -17,4 +17,14 @@ CompilerD3D::CompilerD3D(ShShaderOutput translatorOutputType) { } +gl::Error CompilerD3D::release() +{ + return gl::NoError(); +} + +ShShaderOutput CompilerD3D::getTranslatorOutputType() const +{ + return mTranslatorOutputType; +} + } // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/CompilerD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/CompilerD3D.h index 8f4334963d..bcfe810d04 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/CompilerD3D.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/CompilerD3D.h @@ -21,8 +21,8 @@ class CompilerD3D : public CompilerImpl CompilerD3D(ShShaderOutput translatorOutputType); ~CompilerD3D() override {} - gl::Error release() override { return gl::Error(GL_NO_ERROR); } - ShShaderOutput getTranslatorOutputType() const override { return mTranslatorOutputType; } + gl::Error release() override; + ShShaderOutput getTranslatorOutputType() const override; private: ShShaderOutput mTranslatorOutputType; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/DeviceD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/DeviceD3D.cpp index f40e6e6cab..5a06b15279 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/DeviceD3D.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/DeviceD3D.cpp @@ -39,11 +39,11 @@ egl::Error DeviceD3D::getDevice(void **outValue) if (!mIsInitialized) { *outValue = nullptr; - return egl::Error(EGL_BAD_DEVICE_EXT); + return egl::EglBadDevice(); } *outValue = mDevice; - return egl::Error(EGL_SUCCESS); + return egl::NoError(); } egl::Error DeviceD3D::initialize(void *device, @@ -53,15 +53,11 @@ egl::Error DeviceD3D::initialize(void *device, ASSERT(!mIsInitialized); if (mIsInitialized) { - return egl::Error(EGL_BAD_DEVICE_EXT); + return egl::EglBadDevice(); } - mDevice = device; - mDeviceType = deviceType; - mDeviceExternallySourced = !!deviceExternallySourced; - #if defined(ANGLE_ENABLE_D3D11) - if (mDeviceType == EGL_D3D11_DEVICE_ANGLE) + if (deviceType == EGL_D3D11_DEVICE_ANGLE) { // Validate the device IUnknown *iunknown = reinterpret_cast(device); @@ -71,7 +67,7 @@ egl::Error DeviceD3D::initialize(void *device, iunknown->QueryInterface(__uuidof(ID3D11Device), reinterpret_cast(&d3dDevice)); if (FAILED(hr)) { - return egl::Error(EGL_BAD_ATTRIBUTE, "Invalid D3D device passed into EGLDeviceEXT"); + return egl::EglBadAttribute() << "Invalid D3D device passed into EGLDeviceEXT"; } // The QI to ID3D11Device adds a ref to the D3D11 device. @@ -81,12 +77,15 @@ egl::Error DeviceD3D::initialize(void *device, else #endif { - ASSERT(!mDeviceExternallySourced); + ASSERT(deviceExternallySourced == EGL_FALSE); } - mIsInitialized = true; + mDevice = device; + mDeviceType = deviceType; + mDeviceExternallySourced = !!deviceExternallySourced; + mIsInitialized = true; - return egl::Error(EGL_SUCCESS); + return egl::NoError(); } EGLint DeviceD3D::getType() @@ -99,4 +98,8 @@ void DeviceD3D::generateExtensions(egl::DeviceExtensions *outExtensions) const outExtensions->deviceD3D = true; } +bool DeviceD3D::deviceExternallySourced() +{ + return mDeviceExternallySourced; +} } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/DeviceD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/DeviceD3D.h index 1dd9979708..15eaf9210a 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/DeviceD3D.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/DeviceD3D.h @@ -25,7 +25,7 @@ class DeviceD3D : public DeviceImpl egl::Error getDevice(void **outValue) override; EGLint getType() override; void generateExtensions(egl::DeviceExtensions *outExtensions) const override; - bool deviceExternallySourced() override { return mDeviceExternallySourced; } + bool deviceExternallySourced() override; private: void *mDevice; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp index d4dc702582..0edda9c584 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.cpp @@ -8,18 +8,19 @@ #include "libANGLE/renderer/d3d/DisplayD3D.h" -#include "libANGLE/Context.h" +#include + #include "libANGLE/Config.h" +#include "libANGLE/Context.h" #include "libANGLE/Display.h" #include "libANGLE/Surface.h" +#include "libANGLE/Thread.h" #include "libANGLE/histogram_macros.h" +#include "libANGLE/renderer/d3d/DeviceD3D.h" #include "libANGLE/renderer/d3d/EGLImageD3D.h" #include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/SurfaceD3D.h" #include "libANGLE/renderer/d3d/SwapChainD3D.h" -#include "libANGLE/renderer/d3d/DeviceD3D.h" - -#include #if defined (ANGLE_ENABLE_D3D9) # include "libANGLE/renderer/d3d/d3d9/Renderer9.h" @@ -29,10 +30,6 @@ # include "libANGLE/renderer/d3d/d3d11/Renderer11.h" #endif // ANGLE_ENABLE_D3D11 -#if defined (ANGLE_TEST_CONFIG) -# define ANGLE_DEFAULT_D3D11 1 -#endif - #if !defined(ANGLE_DEFAULT_D3D11) // Enables use of the Direct3D 11 API for a default display, when available # define ANGLE_DEFAULT_D3D11 1 @@ -60,8 +57,8 @@ egl::Error CreateRendererD3D(egl::Display *display, RendererD3D **outRenderer) const auto &attribMap = display->getAttributeMap(); EGLNativeDisplayType nativeDisplay = display->getNativeDisplayId(); - EGLint requestedDisplayType = - attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE); + EGLint requestedDisplayType = static_cast( + attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE)); # if defined(ANGLE_ENABLE_D3D11) if (nativeDisplay == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE || @@ -117,11 +114,10 @@ egl::Error CreateRendererD3D(egl::Display *display, RendererD3D **outRenderer) UNIMPLEMENTED(); } - egl::Error result(EGL_NOT_INITIALIZED, "No available renderers."); for (size_t i = 0; i < rendererCreationFunctions.size(); i++) { RendererD3D *renderer = rendererCreationFunctions[i](display); - result = renderer->initialize(); + egl::Error result = renderer->initialize(); # if defined(ANGLE_ENABLE_D3D11) if (renderer->getRendererClass() == RENDERER_D3D11) @@ -146,70 +142,45 @@ egl::Error CreateRendererD3D(egl::Display *display, RendererD3D **outRenderer) if (!result.isError()) { *outRenderer = renderer; - break; - } - else - { - // Failed to create the renderer, try the next - SafeDelete(renderer); + return result; } + + // Failed to create the renderer, try the next + SafeDelete(renderer); } - return result; + return egl::EglNotInitialized() << "No available renderers."; } -DisplayD3D::DisplayD3D() : mRenderer(nullptr) +DisplayD3D::DisplayD3D(const egl::DisplayState &state) : DisplayImpl(state), mRenderer(nullptr) { } - -SurfaceImpl *DisplayD3D::createWindowSurface(const egl::Config *configuration, +SurfaceImpl *DisplayD3D::createWindowSurface(const egl::SurfaceState &state, EGLNativeWindowType window, const egl::AttributeMap &attribs) { ASSERT(mRenderer != nullptr); - - EGLint width = attribs.get(EGL_WIDTH, 0); - EGLint height = attribs.get(EGL_HEIGHT, 0); - EGLint fixedSize = attribs.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE); - EGLint orientation = attribs.get(EGL_SURFACE_ORIENTATION_ANGLE, 0); - EGLint directComposition = attribs.get(EGL_DIRECT_COMPOSITION_ANGLE, EGL_FALSE); - - if (!fixedSize) - { - width = -1; - height = -1; - } - - return SurfaceD3D::createFromWindow(mRenderer, mDisplay, configuration, window, fixedSize, - directComposition, width, height, orientation); + return new WindowSurfaceD3D(state, mRenderer, mDisplay, window, attribs); } -SurfaceImpl *DisplayD3D::createPbufferSurface(const egl::Config *configuration, +SurfaceImpl *DisplayD3D::createPbufferSurface(const egl::SurfaceState &state, const egl::AttributeMap &attribs) { ASSERT(mRenderer != nullptr); - - EGLint width = attribs.get(EGL_WIDTH, 0); - EGLint height = attribs.get(EGL_HEIGHT, 0); - - return SurfaceD3D::createOffscreen(mRenderer, mDisplay, configuration, nullptr, width, height); + return new PbufferSurfaceD3D(state, mRenderer, mDisplay, 0, nullptr, attribs); } -SurfaceImpl *DisplayD3D::createPbufferFromClientBuffer(const egl::Config *configuration, - EGLClientBuffer shareHandle, +SurfaceImpl *DisplayD3D::createPbufferFromClientBuffer(const egl::SurfaceState &state, + EGLenum buftype, + EGLClientBuffer clientBuffer, const egl::AttributeMap &attribs) { ASSERT(mRenderer != nullptr); - - EGLint width = attribs.get(EGL_WIDTH, 0); - EGLint height = attribs.get(EGL_HEIGHT, 0); - - return SurfaceD3D::createOffscreen( - mRenderer, mDisplay, configuration, shareHandle, width, height); + return new PbufferSurfaceD3D(state, mRenderer, mDisplay, buftype, clientBuffer, attribs); } -SurfaceImpl *DisplayD3D::createPixmapSurface(const egl::Config *configuration, +SurfaceImpl *DisplayD3D::createPixmapSurface(const egl::SurfaceState &state, NativePixmapType nativePixmap, const egl::AttributeMap &attribs) { @@ -217,11 +188,11 @@ SurfaceImpl *DisplayD3D::createPixmapSurface(const egl::Config *configuration, return nullptr; } -ImageImpl *DisplayD3D::createImage(EGLenum target, - egl::ImageSibling *buffer, +ImageImpl *DisplayD3D::createImage(const egl::ImageState &state, + EGLenum target, const egl::AttributeMap &attribs) { - return new EGLImageD3D(mRenderer, target, buffer, attribs); + return new EGLImageD3D(state, target, attribs, mRenderer); } egl::Error DisplayD3D::getDevice(DeviceImpl **device) @@ -229,30 +200,31 @@ egl::Error DisplayD3D::getDevice(DeviceImpl **device) return mRenderer->getEGLDevice(device); } -gl::Context *DisplayD3D::createContext(const egl::Config *config, - const gl::Context *shareContext, - const egl::AttributeMap &attribs) +ContextImpl *DisplayD3D::createContext(const gl::ContextState &state) { ASSERT(mRenderer != nullptr); - return new gl::Context(config, shareContext, mRenderer, attribs); + return mRenderer->createContext(state); +} + +StreamProducerImpl *DisplayD3D::createStreamProducerD3DTextureNV12( + egl::Stream::ConsumerType consumerType, + const egl::AttributeMap &attribs) +{ + ASSERT(mRenderer != nullptr); + return mRenderer->createStreamProducerD3DTextureNV12(consumerType, attribs); } egl::Error DisplayD3D::makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context) { - return egl::Error(EGL_SUCCESS); + return egl::NoError(); } egl::Error DisplayD3D::initialize(egl::Display *display) { ASSERT(mRenderer == nullptr && display != nullptr); mDisplay = display; - egl::Error error = CreateRendererD3D(display, &mRenderer); - if (error.isError()) - { - return error; - } - - return egl::Error(EGL_SUCCESS); + ANGLE_TRY(CreateRendererD3D(display, &mRenderer)); + return egl::NoError(); } void DisplayD3D::terminate() @@ -260,32 +232,26 @@ void DisplayD3D::terminate() SafeDelete(mRenderer); } -egl::ConfigSet DisplayD3D::generateConfigs() const +egl::ConfigSet DisplayD3D::generateConfigs() { ASSERT(mRenderer != nullptr); return mRenderer->generateConfigs(); } -bool DisplayD3D::isDeviceLost() const -{ - ASSERT(mRenderer != nullptr); - return mRenderer->isDeviceLost(); -} - bool DisplayD3D::testDeviceLost() { ASSERT(mRenderer != nullptr); return mRenderer->testDeviceLost(); } -egl::Error DisplayD3D::restoreLostDevice() +egl::Error DisplayD3D::restoreLostDevice(const egl::Display *display) { // Release surface resources to make the Reset() succeed - for (auto &surface : mSurfaceSet) + for (egl::Surface *surface : mState.surfaceSet) { if (surface->getBoundTexture()) { - surface->releaseTexImage(EGL_BACK_BUFFER); + ANGLE_TRY(surface->releaseTexImage(display->getProxyContext(), EGL_BACK_BUFFER)); } SurfaceD3D *surfaceD3D = GetImplAs(surface); surfaceD3D->releaseSwapChain(); @@ -293,27 +259,43 @@ egl::Error DisplayD3D::restoreLostDevice() if (!mRenderer->resetDevice()) { - return egl::Error(EGL_BAD_ALLOC); + return egl::EglBadAlloc(); } // Restore any surfaces that may have been lost - for (const auto &surface : mSurfaceSet) + for (const egl::Surface *surface : mState.surfaceSet) { SurfaceD3D *surfaceD3D = GetImplAs(surface); - egl::Error error = surfaceD3D->resetSwapChain(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(surfaceD3D->resetSwapChain(display)); } - return egl::Error(EGL_SUCCESS); + return egl::NoError(); } bool DisplayD3D::isValidNativeWindow(EGLNativeWindowType window) const { - return NativeWindow::isValidNativeWindow(window); + return mRenderer->isValidNativeWindow(window); +} + +egl::Error DisplayD3D::validateClientBuffer(const egl::Config *configuration, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const egl::AttributeMap &attribs) const +{ + switch (buftype) + { + case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE: + return mRenderer->validateShareHandle(configuration, static_cast(clientBuffer), + attribs); + + case EGL_D3D_TEXTURE_ANGLE: + return mRenderer->getD3DTextureInfo( + configuration, static_cast(clientBuffer), nullptr, nullptr, nullptr); + + default: + return DisplayImpl::validateClientBuffer(configuration, buftype, clientBuffer, attribs); + } } void DisplayD3D::generateExtensions(egl::DisplayExtensions *outExtensions) const @@ -337,20 +319,43 @@ void DisplayD3D::generateCaps(egl::Caps *outCaps) const // Display must be initialized to generate caps ASSERT(mRenderer != nullptr); - outCaps->textureNPOT = mRenderer->getRendererExtensions().textureNPOT; + outCaps->textureNPOT = mRenderer->getNativeExtensions().textureNPOT; } -egl::Error DisplayD3D::waitClient() const +egl::Error DisplayD3D::waitClient(const gl::Context *context) const { - // Unimplemented as it is a noop on D3D - return egl::Error(EGL_SUCCESS); + for (egl::Surface *surface : mState.surfaceSet) + { + SurfaceD3D *surfaceD3D = GetImplAs(surface); + ANGLE_TRY(surfaceD3D->checkForOutOfDateSwapChain(context)); + } + + return egl::NoError(); } -egl::Error DisplayD3D::waitNative(EGLint engine, - egl::Surface *drawSurface, - egl::Surface *readSurface) const +egl::Error DisplayD3D::waitNative(const gl::Context *context, EGLint engine) const { - // Unimplemented as it is a noop on D3D - return egl::Error(EGL_SUCCESS); + egl::Surface *drawSurface = context->getCurrentDrawSurface(); + egl::Surface *readSurface = context->getCurrentReadSurface(); + + if (drawSurface != nullptr) + { + SurfaceD3D *drawSurfaceD3D = GetImplAs(drawSurface); + ANGLE_TRY(drawSurfaceD3D->checkForOutOfDateSwapChain(context)); + } + + if (readSurface != nullptr) + { + SurfaceD3D *readSurfaceD3D = GetImplAs(readSurface); + ANGLE_TRY(readSurfaceD3D->checkForOutOfDateSwapChain(context)); + } + + return egl::NoError(); } + +gl::Version DisplayD3D::getMaxSupportedESVersion() const +{ + return mRenderer->getMaxSupportedESVersion(); } + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.h index 0ce196dea2..7090522312 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/DisplayD3D.h @@ -19,50 +19,55 @@ class RendererD3D; class DisplayD3D : public DisplayImpl { public: - DisplayD3D(); + DisplayD3D(const egl::DisplayState &state); egl::Error initialize(egl::Display *display) override; - virtual void terminate() override; + void terminate() override; // Surface creation - SurfaceImpl *createWindowSurface(const egl::Config *configuration, + SurfaceImpl *createWindowSurface(const egl::SurfaceState &state, EGLNativeWindowType window, const egl::AttributeMap &attribs) override; - SurfaceImpl *createPbufferSurface(const egl::Config *configuration, + SurfaceImpl *createPbufferSurface(const egl::SurfaceState &state, const egl::AttributeMap &attribs) override; - SurfaceImpl *createPbufferFromClientBuffer(const egl::Config *configuration, - EGLClientBuffer shareHandle, + SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state, + EGLenum buftype, + EGLClientBuffer clientBuffer, const egl::AttributeMap &attribs) override; - SurfaceImpl *createPixmapSurface(const egl::Config *configuration, + SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state, NativePixmapType nativePixmap, const egl::AttributeMap &attribs) override; - ImageImpl *createImage(EGLenum target, - egl::ImageSibling *buffer, + ImageImpl *createImage(const egl::ImageState &state, + EGLenum target, const egl::AttributeMap &attribs) override; - gl::Context *createContext(const egl::Config *config, - const gl::Context *shareContext, - const egl::AttributeMap &attribs) override; + ContextImpl *createContext(const gl::ContextState &state) override; + + StreamProducerImpl *createStreamProducerD3DTextureNV12( + egl::Stream::ConsumerType consumerType, + const egl::AttributeMap &attribs) override; egl::Error makeCurrent(egl::Surface *drawSurface, egl::Surface *readSurface, gl::Context *context) override; - egl::ConfigSet generateConfigs() const override; + egl::ConfigSet generateConfigs() override; - bool isDeviceLost() const override; bool testDeviceLost() override; - egl::Error restoreLostDevice() override; + egl::Error restoreLostDevice(const egl::Display *display) override; bool isValidNativeWindow(EGLNativeWindowType window) const override; + egl::Error validateClientBuffer(const egl::Config *configuration, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const egl::AttributeMap &attribs) const override; egl::Error getDevice(DeviceImpl **device) override; std::string getVendorString() const override; - egl::Error waitClient() const override; - egl::Error waitNative(EGLint engine, - egl::Surface *drawSurface, - egl::Surface *readSurface) const override; + egl::Error waitClient(const gl::Context *context) const override; + egl::Error waitNative(const gl::Context *context, EGLint engine) const override; + gl::Version getMaxSupportedESVersion() const override; private: void generateExtensions(egl::DisplayExtensions *outExtensions) const override; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/DynamicHLSL.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/DynamicHLSL.cpp index 42a534f573..b4143a3f5f 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/DynamicHLSL.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/DynamicHLSL.cpp @@ -8,15 +8,17 @@ #include "libANGLE/renderer/d3d/DynamicHLSL.h" +#include "common/string_utils.h" #include "common/utilities.h" #include "compiler/translator/blocklayoutHLSL.h" +#include "libANGLE/Context.h" #include "libANGLE/Program.h" #include "libANGLE/Shader.h" +#include "libANGLE/VaryingPacking.h" #include "libANGLE/formatutils.h" #include "libANGLE/renderer/d3d/ProgramD3D.h" #include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/ShaderD3D.h" -#include "libANGLE/renderer/d3d/VaryingPacking.h" using namespace gl; @@ -26,7 +28,28 @@ namespace rx namespace { -std::string HLSLComponentTypeString(GLenum componentType) +// This class needs to match OutputHLSL::decorate +class DecorateVariable final : angle::NonCopyable +{ + public: + explicit DecorateVariable(const std::string &str) : mName(str) {} + const std::string &getName() const { return mName; } + + private: + const std::string &mName; +}; + +std::ostream &operator<<(std::ostream &o, const DecorateVariable &dv) +{ + if (dv.getName().compare(0, 3, "gl_") != 0) + { + o << "_"; + } + o << dv.getName(); + return o; +} + +const char *HLSLComponentTypeString(GLenum componentType) { switch (componentType) { @@ -44,12 +67,16 @@ std::string HLSLComponentTypeString(GLenum componentType) } } -std::string HLSLComponentTypeString(GLenum componentType, int componentCount) +void HLSLComponentTypeString(std::ostringstream &ostream, GLenum componentType, int componentCount) { - return HLSLComponentTypeString(componentType) + (componentCount > 1 ? Str(componentCount) : ""); + ostream << HLSLComponentTypeString(componentType); + if (componentCount > 1) + { + ostream << componentCount; + } } -std::string HLSLMatrixTypeString(GLenum type) +const char *HLSLMatrixTypeString(GLenum type) { switch (type) { @@ -77,15 +104,16 @@ std::string HLSLMatrixTypeString(GLenum type) } } -std::string HLSLTypeString(GLenum type) +void HLSLTypeString(std::ostringstream &ostream, GLenum type) { if (gl::IsMatrixType(type)) { - return HLSLMatrixTypeString(type); + ostream << HLSLMatrixTypeString(type); + return; } - return HLSLComponentTypeString(gl::VariableComponentType(type), - gl::VariableComponentCount(type)); + HLSLComponentTypeString(ostream, gl::VariableComponentType(type), + gl::VariableComponentCount(type)); } const PixelShaderOutputVariable *FindOutputAtLocation( @@ -103,7 +131,7 @@ const PixelShaderOutputVariable *FindOutputAtLocation( return nullptr; } -void WriteArrayString(std::stringstream &strstr, unsigned int i) +void WriteArrayString(std::ostringstream &strstr, unsigned int i) { static_assert(GL_INVALID_INDEX == UINT_MAX, "GL_INVALID_INDEX must be equal to the max unsigned int."); @@ -117,16 +145,14 @@ void WriteArrayString(std::stringstream &strstr, unsigned int i) strstr << "]"; } -const std::string VERTEX_ATTRIBUTE_STUB_STRING = "@@ VERTEX ATTRIBUTES @@"; -const std::string PIXEL_OUTPUT_STUB_STRING = "@@ PIXEL OUTPUT @@"; +constexpr const char *VERTEX_ATTRIBUTE_STUB_STRING = "@@ VERTEX ATTRIBUTES @@"; +constexpr const char *PIXEL_OUTPUT_STUB_STRING = "@@ PIXEL OUTPUT @@"; } // anonymous namespace -std::string GetVaryingSemantic(int majorShaderModel, bool programUsesPointSize) -{ - // SM3 reserves the TEXCOORD semantic for point sprite texcoords (gl_PointCoord) - // In D3D11 we manually compute gl_PointCoord in the GS. - return ((programUsesPointSize && majorShaderModel < 4) ? "COLOR" : "TEXCOORD"); -} +// BuiltinInfo implementation + +BuiltinInfo::BuiltinInfo() = default; +BuiltinInfo::~BuiltinInfo() = default; // DynamicHLSL implementation @@ -134,55 +160,13 @@ DynamicHLSL::DynamicHLSL(RendererD3D *const renderer) : mRenderer(renderer) { } -void DynamicHLSL::generateVaryingHLSL(const VaryingPacking &varyingPacking, - std::stringstream &hlslStream) const -{ - std::string varyingSemantic = - GetVaryingSemantic(mRenderer->getMajorShaderModel(), varyingPacking.usesPointSize()); - - for (const PackedVaryingRegister ®isterInfo : varyingPacking.getRegisterList()) - { - const auto &varying = *registerInfo.packedVarying->varying; - ASSERT(!varying.isStruct()); - - // TODO: Add checks to ensure D3D interpolation modifiers don't result in too many - // registers being used. - // For example, if there are N registers, and we have N vec3 varyings and 1 float - // varying, then D3D will pack them into N registers. - // If the float varying has the 'nointerpolation' modifier on it then we would need - // N + 1 registers, and D3D compilation will fail. - - switch (registerInfo.packedVarying->interpolation) - { - case sh::INTERPOLATION_SMOOTH: - hlslStream << " "; - break; - case sh::INTERPOLATION_FLAT: - hlslStream << " nointerpolation "; - break; - case sh::INTERPOLATION_CENTROID: - hlslStream << " centroid "; - break; - default: - UNREACHABLE(); - } - - GLenum transposedType = gl::TransposeMatrixType(varying.type); - GLenum componentType = gl::VariableComponentType(transposedType); - int columnCount = gl::VariableColumnCount(transposedType); - hlslStream << HLSLComponentTypeString(componentType, columnCount); - unsigned int semanticIndex = registerInfo.semanticIndex; - hlslStream << " v" << semanticIndex << " : " << varyingSemantic << semanticIndex << ";\n"; - } -} - std::string DynamicHLSL::generateVertexShaderForInputLayout( const std::string &sourceShader, const InputLayout &inputLayout, const std::vector &shaderAttributes) const { - std::stringstream structStream; - std::stringstream initStream; + std::ostringstream structStream; + std::ostringstream initStream; structStream << "struct VS_INPUT\n" << "{\n"; @@ -231,26 +215,31 @@ std::string DynamicHLSL::generateVertexShaderForInputLayout( { GLenum componentType = mRenderer->getVertexComponentType(vertexFormatType); - if (shaderAttribute.name == "gl_InstanceID") + if (shaderAttribute.name == "gl_InstanceID" || + shaderAttribute.name == "gl_VertexID") { - // The input type of the instance ID in HLSL (uint) differs from the one in ESSL - // (int). + // The input types of the instance ID and vertex ID in HLSL (uint) differs from + // the ones in ESSL (int). structStream << " uint"; } else { - structStream << " " << HLSLComponentTypeString( - componentType, - VariableComponentCount(shaderAttribute.type)); + structStream << " "; + HLSLComponentTypeString(structStream, componentType, + VariableComponentCount(shaderAttribute.type)); } } - structStream << " " << decorateVariable(shaderAttribute.name) << " : "; + structStream << " " << DecorateVariable(shaderAttribute.name) << " : "; if (shaderAttribute.name == "gl_InstanceID") { structStream << "SV_InstanceID"; } + else if (shaderAttribute.name == "gl_VertexID") + { + structStream << "SV_VertexID"; + } else { structStream << "TEXCOORD" << semanticIndex; @@ -260,7 +249,7 @@ std::string DynamicHLSL::generateVertexShaderForInputLayout( structStream << ";\n"; // HLSL code for initialization - initStream << " " << decorateVariable(shaderAttribute.name) << " = "; + initStream << " " << DecorateVariable(shaderAttribute.name) << " = "; // Mismatched vertex attribute to vertex input may result in an undefined // data reinterpretation (eg for pure integer->float, float->pure integer) @@ -268,11 +257,11 @@ std::string DynamicHLSL::generateVertexShaderForInputLayout( if (IsMatrixType(shaderAttribute.type) || (mRenderer->getVertexConversionType(vertexFormatType) & VERTEX_CONVERT_GPU) != 0) { - initStream << generateAttributeConversionHLSL(vertexFormatType, shaderAttribute); + GenerateAttributeConversionHLSL(vertexFormatType, shaderAttribute, initStream); } else { - initStream << "input." << decorateVariable(shaderAttribute.name); + initStream << "input." << DecorateVariable(shaderAttribute.name); } initStream << ";\n"; @@ -289,8 +278,9 @@ std::string DynamicHLSL::generateVertexShaderForInputLayout( std::string vertexHLSL(sourceShader); - size_t copyInsertionPos = vertexHLSL.find(VERTEX_ATTRIBUTE_STUB_STRING); - vertexHLSL.replace(copyInsertionPos, VERTEX_ATTRIBUTE_STUB_STRING.length(), structStream.str()); + bool success = + angle::ReplaceSubstring(&vertexHLSL, VERTEX_ATTRIBUTE_STUB_STRING, structStream.str()); + ASSERT(success); return vertexHLSL; } @@ -305,22 +295,32 @@ std::string DynamicHLSL::generatePixelShaderForOutputSignature( std::string targetSemantic = (shaderModel >= 4) ? "SV_TARGET" : "COLOR"; std::string depthSemantic = (shaderModel >= 4) ? "SV_Depth" : "DEPTH"; - std::stringstream declarationStream; - std::stringstream copyStream; + std::ostringstream declarationStream; + std::ostringstream copyStream; declarationStream << "struct PS_OUTPUT\n" "{\n"; - for (size_t layoutIndex = 0; layoutIndex < outputLayout.size(); ++layoutIndex) + size_t numOutputs = outputLayout.size(); + + // Workaround for HLSL 3.x: We can't do a depth/stencil only render, the runtime will complain. + if (numOutputs == 0 && (shaderModel == 3 || !mRenderer->getShaderModelSuffix().empty())) { - GLenum binding = outputLayout[layoutIndex]; + numOutputs = 1u; + } + const PixelShaderOutputVariable defaultOutput(GL_FLOAT_VEC4, "dummy", "float4(0, 0, 0, 1)", 0); + + for (size_t layoutIndex = 0; layoutIndex < numOutputs; ++layoutIndex) + { + GLenum binding = outputLayout.empty() ? GL_COLOR_ATTACHMENT0 : outputLayout[layoutIndex]; if (binding != GL_NONE) { unsigned int location = (binding - GL_COLOR_ATTACHMENT0); const PixelShaderOutputVariable *outputVariable = - FindOutputAtLocation(outputVariables, location); + outputLayout.empty() ? &defaultOutput + : FindOutputAtLocation(outputVariables, location); // OpenGL ES 3.0 spec $4.2.1 // If [...] not all user-defined output variables are written, the values of fragment @@ -328,8 +328,9 @@ std::string DynamicHLSL::generatePixelShaderForOutputSignature( // corresponding to unwritten variables are similarly undefined. if (outputVariable) { - declarationStream << " " + HLSLTypeString(outputVariable->type) << " " - << outputVariable->name << " : " << targetSemantic + declarationStream << " "; + HLSLTypeString(declarationStream, outputVariable->type); + declarationStream << " " << outputVariable->name << " : " << targetSemantic << static_cast(layoutIndex) << ";\n"; copyStream << " output." << outputVariable->name << " = " @@ -354,61 +355,113 @@ std::string DynamicHLSL::generatePixelShaderForOutputSignature( std::string pixelHLSL(sourceShader); - size_t outputInsertionPos = pixelHLSL.find(PIXEL_OUTPUT_STUB_STRING); - pixelHLSL.replace(outputInsertionPos, PIXEL_OUTPUT_STUB_STRING.length(), - declarationStream.str()); + bool success = + angle::ReplaceSubstring(&pixelHLSL, PIXEL_OUTPUT_STUB_STRING, declarationStream.str()); + ASSERT(success); return pixelHLSL; } -void DynamicHLSL::generateVaryingLinkHLSL(ShaderType shaderType, - const VaryingPacking &varyingPacking, - std::stringstream &linkStream) const +void DynamicHLSL::generateVaryingLinkHLSL(const VaryingPacking &varyingPacking, + const BuiltinInfo &builtins, + bool programUsesPointSize, + std::ostringstream &hlslStream) const { - const auto &builtins = varyingPacking.builtins(shaderType); ASSERT(builtins.dxPosition.enabled); - linkStream << "{\n" + hlslStream << "{\n" << " float4 dx_Position : " << builtins.dxPosition.str() << ";\n"; if (builtins.glPosition.enabled) { - linkStream << " float4 gl_Position : " << builtins.glPosition.str() << ";\n"; + hlslStream << " float4 gl_Position : " << builtins.glPosition.str() << ";\n"; } if (builtins.glFragCoord.enabled) { - linkStream << " float4 gl_FragCoord : " << builtins.glFragCoord.str() << ";\n"; + hlslStream << " float4 gl_FragCoord : " << builtins.glFragCoord.str() << ";\n"; } if (builtins.glPointCoord.enabled) { - linkStream << " float2 gl_PointCoord : " << builtins.glPointCoord.str() << ";\n"; + hlslStream << " float2 gl_PointCoord : " << builtins.glPointCoord.str() << ";\n"; } if (builtins.glPointSize.enabled) { - linkStream << " float gl_PointSize : " << builtins.glPointSize.str() << ";\n"; + hlslStream << " float gl_PointSize : " << builtins.glPointSize.str() << ";\n"; } - // Do this after glPointSize, to potentially combine gl_PointCoord and gl_PointSize into the - // same register. - generateVaryingHLSL(varyingPacking, linkStream); + if (builtins.glViewIDOVR.enabled) + { + hlslStream << " nointerpolation uint gl_ViewID_OVR : " << builtins.glViewIDOVR.str() + << ";\n"; + } - linkStream << "};\n"; + if (builtins.glViewportIndex.enabled) + { + hlslStream << " nointerpolation uint gl_ViewportIndex : " + << builtins.glViewportIndex.str() << ";\n"; + } + + if (builtins.glLayer.enabled) + { + hlslStream << " nointerpolation uint gl_Layer : " << builtins.glLayer.str() << ";\n"; + } + + std::string varyingSemantic = + GetVaryingSemantic(mRenderer->getMajorShaderModel(), programUsesPointSize); + + for (const PackedVaryingRegister ®isterInfo : varyingPacking.getRegisterList()) + { + const auto &varying = *registerInfo.packedVarying->varying; + ASSERT(!varying.isStruct()); + + // TODO: Add checks to ensure D3D interpolation modifiers don't result in too many + // registers being used. + // For example, if there are N registers, and we have N vec3 varyings and 1 float + // varying, then D3D will pack them into N registers. + // If the float varying has the 'nointerpolation' modifier on it then we would need + // N + 1 registers, and D3D compilation will fail. + + switch (registerInfo.packedVarying->interpolation) + { + case sh::INTERPOLATION_SMOOTH: + hlslStream << " "; + break; + case sh::INTERPOLATION_FLAT: + hlslStream << " nointerpolation "; + break; + case sh::INTERPOLATION_CENTROID: + hlslStream << " centroid "; + break; + default: + UNREACHABLE(); + } + + GLenum transposedType = gl::TransposeMatrixType(varying.type); + GLenum componentType = gl::VariableComponentType(transposedType); + int columnCount = gl::VariableColumnCount(transposedType); + HLSLComponentTypeString(hlslStream, componentType, columnCount); + unsigned int semanticIndex = registerInfo.semanticIndex; + hlslStream << " v" << semanticIndex << " : " << varyingSemantic << semanticIndex << ";\n"; + } + + hlslStream << "};\n"; } -bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, - const gl::Program::Data &programData, +void DynamicHLSL::generateShaderLinkHLSL(const gl::Context *context, + const gl::ProgramState &programData, const ProgramD3DMetadata &programMetadata, const VaryingPacking &varyingPacking, + const BuiltinVaryingsD3D &builtinsD3D, std::string *pixelHLSL, std::string *vertexHLSL) const { ASSERT(pixelHLSL->empty() && vertexHLSL->empty()); - const gl::Shader *vertexShaderGL = programData.getAttachedVertexShader(); - const ShaderD3D *vertexShader = GetImplAs(vertexShaderGL); - const gl::Shader *fragmentShaderGL = programData.getAttachedFragmentShader(); + const auto &data = context->getContextState(); + gl::Shader *vertexShaderGL = programData.getAttachedVertexShader(); + gl::Shader *fragmentShaderGL = programData.getAttachedFragmentShader(); const ShaderD3D *fragmentShader = GetImplAs(fragmentShaderGL); const int shaderModel = mRenderer->getMajorShaderModel(); @@ -422,48 +475,59 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, // Validation done in the compiler ASSERT(!fragmentShader->usesFragColor() || !fragmentShader->usesFragData()); - std::stringstream vertexStream; - vertexStream << vertexShaderGL->getTranslatedSource(); + std::ostringstream vertexStream; + vertexStream << vertexShaderGL->getTranslatedSource(context); // Instanced PointSprite emulation requires additional entries originally generated in the // GeometryShader HLSL. These include pointsize clamp values. if (useInstancedPointSpriteEmulation) { vertexStream << "static float minPointSize = " - << static_cast(data.caps->minAliasedPointSize) << ".0f;\n" + << static_cast(data.getCaps().minAliasedPointSize) << ".0f;\n" << "static float maxPointSize = " - << static_cast(data.caps->maxAliasedPointSize) << ".0f;\n"; + << static_cast(data.getCaps().maxAliasedPointSize) << ".0f;\n"; } // Add stub string to be replaced when shader is dynamically defined by its layout - vertexStream << "\n" << VERTEX_ATTRIBUTE_STUB_STRING + "\n"; + vertexStream << "\n" << std::string(VERTEX_ATTRIBUTE_STUB_STRING) << "\n"; + + const auto &vertexBuiltins = builtinsD3D[gl::SHADER_VERTEX]; // Write the HLSL input/output declarations vertexStream << "struct VS_OUTPUT\n"; - generateVaryingLinkHLSL(SHADER_VERTEX, varyingPacking, vertexStream); + generateVaryingLinkHLSL(varyingPacking, vertexBuiltins, builtinsD3D.usesPointSize(), + vertexStream); vertexStream << "\n" << "VS_OUTPUT main(VS_INPUT input)\n" << "{\n" << " initAttributes(input);\n"; - if (vertexShader->usesDeferredInit()) - { - vertexStream << "\n" - << " initializeDeferredGlobals();\n"; - } - vertexStream << "\n" << " gl_main();\n" << "\n" << " VS_OUTPUT output;\n"; - const auto &vertexBuiltins = varyingPacking.builtins(SHADER_VERTEX); - if (vertexBuiltins.glPosition.enabled) { vertexStream << " output.gl_Position = gl_Position;\n"; } + if (vertexBuiltins.glViewIDOVR.enabled) + { + vertexStream << " output.gl_ViewID_OVR = _ViewID_OVR;\n"; + } + if (programMetadata.hasANGLEMultiviewEnabled() && programMetadata.canSelectViewInVertexShader()) + { + ASSERT(vertexBuiltins.glViewportIndex.enabled && vertexBuiltins.glLayer.enabled); + vertexStream << " if (multiviewSelectViewportIndex)\n" + << " {\n" + << " output.gl_ViewportIndex = _ViewID_OVR;\n" + << " } else {\n" + << " output.gl_ViewportIndex = 0;\n" + << " output.gl_Layer = _ViewID_OVR;\n" + << " }\n"; + } + // On D3D9 or D3D11 Feature Level 9, we need to emulate large viewports using dx_ViewAdjust. if (shaderModel >= 4 && mRenderer->getShaderModelSuffix() == "") { @@ -528,10 +592,10 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, if (packedVarying.isStructField()) { - vertexStream << decorateVariable(packedVarying.parentStructName) << "."; + vertexStream << DecorateVariable(packedVarying.parentStructName) << "."; } - vertexStream << decorateVariable(varying.name); + vertexStream << DecorateVariable(varying.name); if (varying.isArray()) { @@ -593,13 +657,16 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, << " return output;\n" << "}\n"; - std::stringstream pixelStream; - pixelStream << fragmentShaderGL->getTranslatedSource(); + const auto &pixelBuiltins = builtinsD3D[gl::SHADER_FRAGMENT]; + + std::ostringstream pixelStream; + pixelStream << fragmentShaderGL->getTranslatedSource(context); pixelStream << "struct PS_INPUT\n"; - generateVaryingLinkHLSL(SHADER_PIXEL, varyingPacking, pixelStream); + generateVaryingLinkHLSL(varyingPacking, pixelBuiltins, builtinsD3D.usesPointSize(), + pixelStream); pixelStream << "\n"; - pixelStream << PIXEL_OUTPUT_STUB_STRING + "\n"; + pixelStream << std::string(PIXEL_OUTPUT_STUB_STRING) << "\n"; if (fragmentShader->usesFrontFacing()) { @@ -620,7 +687,11 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, << "{\n"; } - const auto &pixelBuiltins = varyingPacking.builtins(SHADER_PIXEL); + if (fragmentShader->usesViewID()) + { + ASSERT(pixelBuiltins.glViewIDOVR.enabled); + pixelStream << " _ViewID_OVR = input.gl_ViewID_OVR;\n"; + } if (pixelBuiltins.glFragCoord.enabled) { @@ -721,18 +792,19 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, const auto &varying = *packedVarying.varying; ASSERT(!varying.isBuiltIn() && !varying.isStruct()); - // Don't reference VS-only transform feedback varyings in the PS. - if (registerInfo.packedVarying->vertexOnly) + // Don't reference VS-only transform feedback varyings in the PS. Note that we're relying on + // that the staticUse flag is set according to usage in the fragment shader. + if (packedVarying.vertexOnly || !varying.staticUse) continue; pixelStream << " "; if (packedVarying.isStructField()) { - pixelStream << decorateVariable(packedVarying.parentStructName) << "."; + pixelStream << DecorateVariable(packedVarying.parentStructName) << "."; } - pixelStream << decorateVariable(varying.name); + pixelStream << DecorateVariable(varying.name); if (varying.isArray()) { @@ -766,12 +838,6 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, pixelStream << ";\n"; } - if (fragmentShader->usesDeferredInit()) - { - pixelStream << "\n" - << " initializeDeferredGlobals();\n"; - } - pixelStream << "\n" << " gl_main();\n" << "\n" @@ -780,34 +846,126 @@ bool DynamicHLSL::generateShaderLinkHLSL(const gl::Data &data, *vertexHLSL = vertexStream.str(); *pixelHLSL = pixelStream.str(); - - return true; } -std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &varyingPacking) const +std::string DynamicHLSL::generateComputeShaderLinkHLSL(const gl::Context *context, + const gl::ProgramState &programData) const +{ + gl::Shader *computeShaderGL = programData.getAttachedComputeShader(); + std::stringstream computeStream; + std::string translatedSource = computeShaderGL->getTranslatedSource(context); + computeStream << translatedSource; + + bool usesWorkGroupID = translatedSource.find("GL_USES_WORK_GROUP_ID") != std::string::npos; + bool usesLocalInvocationID = + translatedSource.find("GL_USES_LOCAL_INVOCATION_ID") != std::string::npos; + bool usesGlobalInvocationID = + translatedSource.find("GL_USES_GLOBAL_INVOCATION_ID") != std::string::npos; + bool usesLocalInvocationIndex = + translatedSource.find("GL_USES_LOCAL_INVOCATION_INDEX") != std::string::npos; + + computeStream << "\nstruct CS_INPUT\n{\n"; + if (usesWorkGroupID) + { + computeStream << " uint3 dx_WorkGroupID : " + << "SV_GroupID;\n"; + } + + if (usesLocalInvocationID) + { + computeStream << " uint3 dx_LocalInvocationID : " + << "SV_GroupThreadID;\n"; + } + + if (usesGlobalInvocationID) + { + computeStream << " uint3 dx_GlobalInvocationID : " + << "SV_DispatchThreadID;\n"; + } + + if (usesLocalInvocationIndex) + { + computeStream << " uint dx_LocalInvocationIndex : " + << "SV_GroupIndex;\n"; + } + + computeStream << "};\n\n"; + + const sh::WorkGroupSize &localSize = computeShaderGL->getWorkGroupSize(context); + computeStream << "[numthreads(" << localSize[0] << ", " << localSize[1] << ", " << localSize[2] + << ")]\n"; + + computeStream << "void main(CS_INPUT input)\n" + << "{\n"; + + if (usesWorkGroupID) + { + computeStream << " gl_WorkGroupID = input.dx_WorkGroupID;\n"; + } + if (usesLocalInvocationID) + { + computeStream << " gl_LocalInvocationID = input.dx_LocalInvocationID;\n"; + } + if (usesGlobalInvocationID) + { + computeStream << " gl_GlobalInvocationID = input.dx_GlobalInvocationID;\n"; + } + if (usesLocalInvocationIndex) + { + computeStream << " gl_LocalInvocationIndex = input.dx_LocalInvocationIndex;\n"; + } + + computeStream << "\n" + << " gl_main();\n" + << "}\n"; + + return computeStream.str(); +} + +std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &varyingPacking, + const BuiltinVaryingsD3D &builtinsD3D, + const bool hasANGLEMultiviewEnabled, + const bool selectViewInVS) const { ASSERT(mRenderer->getMajorShaderModel() >= 4); - std::stringstream preambleStream; + std::ostringstream preambleStream; - const auto &builtins = varyingPacking.builtins(SHADER_VERTEX); + const auto &vertexBuiltins = builtinsD3D[gl::SHADER_VERTEX]; preambleStream << "struct GS_INPUT\n"; - generateVaryingLinkHLSL(SHADER_VERTEX, varyingPacking, preambleStream); + generateVaryingLinkHLSL(varyingPacking, vertexBuiltins, builtinsD3D.usesPointSize(), + preambleStream); preambleStream << "\n" << "struct GS_OUTPUT\n"; - generateVaryingLinkHLSL(SHADER_GEOMETRY, varyingPacking, preambleStream); + generateVaryingLinkHLSL(varyingPacking, builtinsD3D[gl::SHADER_GEOMETRY], + builtinsD3D.usesPointSize(), preambleStream); preambleStream << "\n" << "void copyVertex(inout GS_OUTPUT output, GS_INPUT input, GS_INPUT flatinput)\n" << "{\n" << " output.gl_Position = input.gl_Position;\n"; - if (builtins.glPointSize.enabled) + if (vertexBuiltins.glPointSize.enabled) { preambleStream << " output.gl_PointSize = input.gl_PointSize;\n"; } + if (hasANGLEMultiviewEnabled) + { + preambleStream << " output.gl_ViewID_OVR = input.gl_ViewID_OVR;\n"; + if (selectViewInVS) + { + ASSERT(builtinsD3D[gl::SHADER_GEOMETRY].glViewportIndex.enabled && + builtinsD3D[gl::SHADER_GEOMETRY].glLayer.enabled); + + // If the view is already selected in the VS, then we just pass the gl_ViewportIndex and + // gl_Layer to the output. + preambleStream << " output.gl_ViewportIndex = input.gl_ViewportIndex;\n" + << " output.gl_Layer = input.gl_Layer;\n"; + } + } + for (const PackedVaryingRegister &varyingRegister : varyingPacking.getRegisterList()) { preambleStream << " output.v" << varyingRegister.semanticIndex << " = "; @@ -818,7 +976,7 @@ std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &va preambleStream << "input.v" << varyingRegister.semanticIndex << "; \n"; } - if (builtins.glFragCoord.enabled) + if (vertexBuiltins.glFragCoord.enabled) { preambleStream << " output.gl_FragCoord = input.gl_FragCoord;\n"; } @@ -829,20 +987,46 @@ std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &va << "#endif // ANGLE_POINT_SPRITE_SHADER\n" << "}\n"; + if (hasANGLEMultiviewEnabled && !selectViewInVS) + { + ASSERT(builtinsD3D[gl::SHADER_GEOMETRY].glViewportIndex.enabled && + builtinsD3D[gl::SHADER_GEOMETRY].glLayer.enabled); + + // According to the HLSL reference, using SV_RenderTargetArrayIndex is only valid if the + // render target is an array resource. Because of this we do not write to gl_Layer if we are + // taking the side-by-side code path. We still select the viewport index in the layered code + // path as that is always valid. See: + // https://msdn.microsoft.com/en-us/library/windows/desktop/bb509647(v=vs.85).aspx + preambleStream << "\n" + << "void selectView(inout GS_OUTPUT output, GS_INPUT input)\n" + << "{\n" + << " if (multiviewSelectViewportIndex)\n" + << " {\n" + << " output.gl_ViewportIndex = input.gl_ViewID_OVR;\n" + << " } else {\n" + << " output.gl_ViewportIndex = 0;\n" + << " output.gl_Layer = input.gl_ViewID_OVR;\n" + << " }\n" + << "}\n"; + } + return preambleStream.str(); } -std::string DynamicHLSL::generateGeometryShaderHLSL(gl::PrimitiveType primitiveType, - const gl::Data &data, - const gl::Program::Data &programData, +std::string DynamicHLSL::generateGeometryShaderHLSL(const gl::Context *context, + gl::PrimitiveType primitiveType, + const gl::ProgramState &programData, const bool useViewScale, + const bool hasANGLEMultiviewEnabled, + const bool selectViewInVS, + const bool pointSpriteEmulation, const std::string &preambleString) const { ASSERT(mRenderer->getMajorShaderModel() >= 4); std::stringstream shaderStream; - const bool pointSprites = (primitiveType == PRIMITIVE_POINTS); + const bool pointSprites = (primitiveType == PRIMITIVE_POINTS) && pointSpriteEmulation; const bool usesPointCoord = preambleString.find("gl_PointCoord") != std::string::npos; const char *inputPT = nullptr; @@ -854,9 +1038,19 @@ std::string DynamicHLSL::generateGeometryShaderHLSL(gl::PrimitiveType primitiveT { case PRIMITIVE_POINTS: inputPT = "point"; - outputPT = "Triangle"; inputSize = 1; - maxVertexOutput = 4; + + if (pointSprites) + { + outputPT = "Triangle"; + maxVertexOutput = 4; + } + else + { + outputPT = "Point"; + maxVertexOutput = 1; + } + break; case PRIMITIVE_LINES: @@ -882,18 +1076,34 @@ std::string DynamicHLSL::generateGeometryShaderHLSL(gl::PrimitiveType primitiveT break; } + if (pointSprites || hasANGLEMultiviewEnabled) + { + shaderStream << "cbuffer DriverConstants : register(b0)\n" + "{\n"; + + if (pointSprites) + { + shaderStream << " float4 dx_ViewCoords : packoffset(c1);\n"; + if (useViewScale) + { + shaderStream << " float2 dx_ViewScale : packoffset(c3);\n"; + } + } + + if (hasANGLEMultiviewEnabled) + { + // We have to add a value which we can use to keep track of which multi-view code path + // is to be selected in the GS. + shaderStream << " float multiviewSelectViewportIndex : packoffset(c3.z);\n"; + } + + shaderStream << "};\n\n"; + } + if (pointSprites) { shaderStream << "#define ANGLE_POINT_SPRITE_SHADER\n" "\n" - "uniform float4 dx_ViewCoords : register(c1);\n"; - - if (useViewScale) - { - shaderStream << "uniform float2 dx_ViewScale : register(c3);\n"; - } - - shaderStream << "\n" "static float2 pointSpriteCorners[] = \n" "{\n" " float2( 0.5f, -0.5f),\n" @@ -911,10 +1121,10 @@ std::string DynamicHLSL::generateGeometryShaderHLSL(gl::PrimitiveType primitiveT "};\n" "\n" "static float minPointSize = " - << static_cast(data.caps->minAliasedPointSize) + << static_cast(context->getCaps().minAliasedPointSize) << ".0f;\n" "static float maxPointSize = " - << static_cast(data.caps->maxAliasedPointSize) << ".0f;\n" + << static_cast(context->getCaps().maxAliasedPointSize) << ".0f;\n" << "\n"; } @@ -944,7 +1154,10 @@ std::string DynamicHLSL::generateGeometryShaderHLSL(gl::PrimitiveType primitiveT { shaderStream << " copyVertex(output, input[" << vertexIndex << "], input[lastVertexIndex]);\n"; - + if (hasANGLEMultiviewEnabled && !selectViewInVS) + { + shaderStream << " selectView(output, input[" << vertexIndex << "]);\n"; + } if (!pointSprites) { ASSERT(inputSize == maxVertexOutput); @@ -995,50 +1208,38 @@ std::string DynamicHLSL::generateGeometryShaderHLSL(gl::PrimitiveType primitiveT return shaderStream.str(); } -// This method needs to match OutputHLSL::decorate -std::string DynamicHLSL::decorateVariable(const std::string &name) +// static +void DynamicHLSL::GenerateAttributeConversionHLSL(gl::VertexFormatType vertexFormatType, + const sh::ShaderVariable &shaderAttrib, + std::ostringstream &outStream) { - if (name.compare(0, 3, "gl_") != 0) - { - return "_" + name; - } - - return name; -} - -std::string DynamicHLSL::generateAttributeConversionHLSL( - gl::VertexFormatType vertexFormatType, - const sh::ShaderVariable &shaderAttrib) const -{ - const gl::VertexFormat &vertexFormat = gl::GetVertexFormatFromType(vertexFormatType); - std::string attribString = "input." + decorateVariable(shaderAttrib.name); - // Matrix if (IsMatrixType(shaderAttrib.type)) { - return "transpose(" + attribString + ")"; + outStream << "transpose(input." << DecorateVariable(shaderAttrib.name) << ")"; + return; } GLenum shaderComponentType = VariableComponentType(shaderAttrib.type); int shaderComponentCount = VariableComponentCount(shaderAttrib.type); + const gl::VertexFormat &vertexFormat = gl::GetVertexFormatFromType(vertexFormatType); // Perform integer to float conversion (if necessary) - bool requiresTypeConversion = - (shaderComponentType == GL_FLOAT && vertexFormat.type != GL_FLOAT); - - if (requiresTypeConversion) + if (shaderComponentType == GL_FLOAT && vertexFormat.type != GL_FLOAT) { // TODO: normalization for 32-bit integer formats ASSERT(!vertexFormat.normalized && !vertexFormat.pureInteger); - return "float" + Str(shaderComponentCount) + "(" + attribString + ")"; + outStream << "float" << shaderComponentCount << "(input." + << DecorateVariable(shaderAttrib.name) << ")"; + return; } // No conversion necessary - return attribString; + outStream << "input." << DecorateVariable(shaderAttrib.name); } -void DynamicHLSL::getPixelShaderOutputKey(const gl::Data &data, - const gl::Program::Data &programData, +void DynamicHLSL::getPixelShaderOutputKey(const gl::ContextState &data, + const gl::ProgramState &programData, const ProgramD3DMetadata &metadata, std::vector *outPixelShaderKey) { @@ -1047,7 +1248,7 @@ void DynamicHLSL::getPixelShaderOutputKey(const gl::Data &data, // - with a 2.0 context, the output color is broadcast to all channels bool broadcast = metadata.usesBroadcast(data); const unsigned int numRenderTargets = - (broadcast || metadata.usesMultipleFragmentOuts() ? data.caps->maxDrawBuffers : 1); + (broadcast || metadata.usesMultipleFragmentOuts() ? data.getCaps().maxDrawBuffers : 1); if (metadata.getMajorShaderVersion() < 300) { @@ -1069,25 +1270,158 @@ void DynamicHLSL::getPixelShaderOutputKey(const gl::Data &data, const auto &shaderOutputVars = metadata.getFragmentShader()->getData().getActiveOutputVariables(); - for (auto outputPair : programData.getOutputVariables()) + for (size_t outputLocationIndex = 0u; + outputLocationIndex < programData.getOutputLocations().size(); ++outputLocationIndex) { - const VariableLocation &outputLocation = outputPair.second; + const VariableLocation &outputLocation = + programData.getOutputLocations().at(outputLocationIndex); + if (!outputLocation.used()) + { + continue; + } const sh::ShaderVariable &outputVariable = shaderOutputVars[outputLocation.index]; - const std::string &variableName = "out_" + outputLocation.name; + const std::string &variableName = "out_" + outputVariable.name; + + // Fragment outputs can't be arrays of arrays. ESSL 3.10 section 4.3.6. const std::string &elementString = - (outputLocation.element == GL_INVALID_INDEX ? "" : Str(outputLocation.element)); + (outputVariable.isArray() ? Str(outputLocation.arrayIndex) : ""); ASSERT(outputVariable.staticUse); PixelShaderOutputVariable outputKeyVariable; outputKeyVariable.type = outputVariable.type; outputKeyVariable.name = variableName + elementString; - outputKeyVariable.source = variableName + ArrayString(outputLocation.element); - outputKeyVariable.outputIndex = outputPair.first; + outputKeyVariable.source = + variableName + + (outputVariable.isArray() ? ArrayString(outputLocation.arrayIndex) : ""); + outputKeyVariable.outputIndex = outputLocationIndex; outPixelShaderKey->push_back(outputKeyVariable); } } } +// BuiltinVarying Implementation. +BuiltinVarying::BuiltinVarying() : enabled(false), index(0), systemValue(false) +{ +} + +std::string BuiltinVarying::str() const +{ + return (systemValue ? semantic : (semantic + Str(index))); +} + +void BuiltinVarying::enableSystem(const std::string &systemValueSemantic) +{ + enabled = true; + semantic = systemValueSemantic; + systemValue = true; +} + +void BuiltinVarying::enable(const std::string &semanticVal, unsigned int indexVal) +{ + enabled = true; + semantic = semanticVal; + index = indexVal; +} + +// BuiltinVaryingsD3D Implementation. +BuiltinVaryingsD3D::BuiltinVaryingsD3D(const ProgramD3DMetadata &metadata, + const VaryingPacking &packing) +{ + updateBuiltins(gl::SHADER_VERTEX, metadata, packing); + updateBuiltins(gl::SHADER_FRAGMENT, metadata, packing); + if (metadata.getRendererMajorShaderModel() >= 4) + { + updateBuiltins(gl::SHADER_GEOMETRY, metadata, packing); + } +} + +BuiltinVaryingsD3D::~BuiltinVaryingsD3D() = default; + +void BuiltinVaryingsD3D::updateBuiltins(gl::ShaderType shaderType, + const ProgramD3DMetadata &metadata, + const VaryingPacking &packing) +{ + const std::string &userSemantic = GetVaryingSemantic(metadata.getRendererMajorShaderModel(), + metadata.usesSystemValuePointSize()); + + unsigned int reservedSemanticIndex = packing.getMaxSemanticIndex(); + + BuiltinInfo *builtins = &mBuiltinInfo[shaderType]; + + if (metadata.getRendererMajorShaderModel() >= 4) + { + builtins->dxPosition.enableSystem("SV_Position"); + } + else if (shaderType == gl::SHADER_FRAGMENT) + { + builtins->dxPosition.enableSystem("VPOS"); + } + else + { + builtins->dxPosition.enableSystem("POSITION"); + } + + if (metadata.usesTransformFeedbackGLPosition()) + { + builtins->glPosition.enable(userSemantic, reservedSemanticIndex++); + } + + if (metadata.usesFragCoord()) + { + builtins->glFragCoord.enable(userSemantic, reservedSemanticIndex++); + } + + if (shaderType == gl::SHADER_VERTEX ? metadata.addsPointCoordToVertexShader() + : metadata.usesPointCoord()) + { + // SM3 reserves the TEXCOORD semantic for point sprite texcoords (gl_PointCoord) + // In D3D11 we manually compute gl_PointCoord in the GS. + if (metadata.getRendererMajorShaderModel() >= 4) + { + builtins->glPointCoord.enable(userSemantic, reservedSemanticIndex++); + } + else + { + builtins->glPointCoord.enable("TEXCOORD", 0); + } + } + + if (shaderType == gl::SHADER_VERTEX && metadata.hasANGLEMultiviewEnabled()) + { + builtins->glViewIDOVR.enable(userSemantic, reservedSemanticIndex++); + if (metadata.canSelectViewInVertexShader()) + { + builtins->glViewportIndex.enableSystem("SV_ViewportArrayIndex"); + builtins->glLayer.enableSystem("SV_RenderTargetArrayIndex"); + } + } + + if (shaderType == gl::SHADER_FRAGMENT && metadata.hasANGLEMultiviewEnabled()) + { + builtins->glViewIDOVR.enable(userSemantic, reservedSemanticIndex++); + } + + if (shaderType == gl::SHADER_GEOMETRY && metadata.hasANGLEMultiviewEnabled()) + { + // Although it is possible to retrieve gl_ViewID_OVR from the value of + // SV_ViewportArrayIndex or SV_RenderTargetArrayIndex based on the multi-view state in the + // driver constant buffer, it is easier and cleaner to pass it as a varying. + builtins->glViewIDOVR.enable(userSemantic, reservedSemanticIndex++); + + // gl_Layer and gl_ViewportIndex are necessary so that we can write to either based on the + // multiview state in the driver constant buffer. + builtins->glViewportIndex.enableSystem("SV_ViewportArrayIndex"); + builtins->glLayer.enableSystem("SV_RenderTargetArrayIndex"); + } + + // Special case: do not include PSIZE semantic in HLSL 3 pixel shaders + if (metadata.usesSystemValuePointSize() && + (shaderType != gl::SHADER_FRAGMENT || metadata.getRendererMajorShaderModel() >= 4)) + { + builtins->glPointSize.enableSystem("PSIZE"); + } +} + } // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/DynamicHLSL.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/DynamicHLSL.h index 69d941c06a..fe8d9cb0a3 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/DynamicHLSL.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/DynamicHLSL.h @@ -16,6 +16,7 @@ #include "common/angleutils.h" #include "libANGLE/Constants.h" #include "libANGLE/Program.h" +#include "libANGLE/angletypes.h" #include "libANGLE/formatutils.h" #include "libANGLE/renderer/d3d/RendererD3D.h" @@ -29,23 +30,88 @@ namespace gl { class InfoLog; struct VariableLocation; +class VaryingPacking; struct VertexAttribute; -struct Data; } namespace rx { -struct PackedVarying; class ProgramD3DMetadata; class ShaderD3D; -class VaryingPacking; struct PixelShaderOutputVariable { - GLenum type; + PixelShaderOutputVariable() {} + PixelShaderOutputVariable(GLenum typeIn, + const std::string &nameIn, + const std::string &sourceIn, + size_t outputIndexIn) + : type(typeIn), name(nameIn), source(sourceIn), outputIndex(outputIndexIn) + { + } + + GLenum type = GL_NONE; std::string name; std::string source; - size_t outputIndex; + size_t outputIndex = 0; +}; + +struct BuiltinVarying final : private angle::NonCopyable +{ + BuiltinVarying(); + + std::string str() const; + void enableSystem(const std::string &systemValueSemantic); + void enable(const std::string &semanticVal, unsigned int indexVal); + + bool enabled; + std::string semantic; + unsigned int index; + bool systemValue; +}; + +struct BuiltinInfo +{ + BuiltinInfo(); + ~BuiltinInfo(); + + BuiltinVarying dxPosition; + BuiltinVarying glPosition; + BuiltinVarying glFragCoord; + BuiltinVarying glPointCoord; + BuiltinVarying glPointSize; + BuiltinVarying glViewIDOVR; + BuiltinVarying glViewportIndex; + BuiltinVarying glLayer; +}; + +inline std::string GetVaryingSemantic(int majorShaderModel, bool programUsesPointSize) +{ + // SM3 reserves the TEXCOORD semantic for point sprite texcoords (gl_PointCoord) + // In D3D11 we manually compute gl_PointCoord in the GS. + return ((programUsesPointSize && majorShaderModel < 4) ? "COLOR" : "TEXCOORD"); +} + +class BuiltinVaryingsD3D +{ + public: + BuiltinVaryingsD3D(const ProgramD3DMetadata &metadata, const gl::VaryingPacking &packing); + ~BuiltinVaryingsD3D(); + + bool usesPointSize() const { return mBuiltinInfo[gl::SHADER_VERTEX].glPointSize.enabled; } + + const BuiltinInfo &operator[](gl::ShaderType shaderType) const + { + return mBuiltinInfo[shaderType]; + } + BuiltinInfo &operator[](gl::ShaderType shaderType) { return mBuiltinInfo[shaderType]; } + + private: + void updateBuiltins(gl::ShaderType shaderType, + const ProgramD3DMetadata &metadata, + const gl::VaryingPacking &packing); + + std::array mBuiltinInfo; }; class DynamicHLSL : angle::NonCopyable @@ -62,43 +128,48 @@ class DynamicHLSL : angle::NonCopyable const std::vector &outputVariables, bool usesFragDepth, const std::vector &outputLayout) const; - bool generateShaderLinkHLSL(const gl::Data &data, - const gl::Program::Data &programData, + void generateShaderLinkHLSL(const gl::Context *context, + const gl::ProgramState &programData, const ProgramD3DMetadata &programMetadata, - const VaryingPacking &varyingPacking, + const gl::VaryingPacking &varyingPacking, + const BuiltinVaryingsD3D &builtinsD3D, std::string *pixelHLSL, std::string *vertexHLSL) const; + std::string generateComputeShaderLinkHLSL(const gl::Context *context, + const gl::ProgramState &programData) const; - std::string generateGeometryShaderPreamble(const VaryingPacking &varyingPacking) const; + std::string generateGeometryShaderPreamble(const gl::VaryingPacking &varyingPacking, + const BuiltinVaryingsD3D &builtinsD3D, + const bool hasANGLEMultiviewEnabled, + const bool selectViewInVS) const; - std::string generateGeometryShaderHLSL(gl::PrimitiveType primitiveType, - const gl::Data &data, - const gl::Program::Data &programData, + std::string generateGeometryShaderHLSL(const gl::Context *context, + gl::PrimitiveType primitiveType, + const gl::ProgramState &programData, const bool useViewScale, + const bool hasANGLEMultiviewEnabled, + const bool selectViewInVS, + const bool pointSpriteEmulation, const std::string &preambleString) const; - void getPixelShaderOutputKey(const gl::Data &data, - const gl::Program::Data &programData, + void getPixelShaderOutputKey(const gl::ContextState &data, + const gl::ProgramState &programData, const ProgramD3DMetadata &metadata, std::vector *outPixelShaderKey); private: RendererD3D *const mRenderer; - void generateVaryingLinkHLSL(ShaderType shaderType, - const VaryingPacking &varyingPacking, - std::stringstream &linkStream) const; - void generateVaryingHLSL(const VaryingPacking &varyingPacking, - std::stringstream &hlslStream) const; + void generateVaryingLinkHLSL(const gl::VaryingPacking &varyingPacking, + const BuiltinInfo &builtins, + bool programUsesPointSize, + std::ostringstream &hlslStream) const; - // Prepend an underscore - static std::string decorateVariable(const std::string &name); - - std::string generateAttributeConversionHLSL(gl::VertexFormatType vertexFormatType, - const sh::ShaderVariable &shaderAttrib) const; + static void GenerateAttributeConversionHLSL(gl::VertexFormatType vertexFormatType, + const sh::ShaderVariable &shaderAttrib, + std::ostringstream &outStream); }; -std::string GetVaryingSemantic(int majorShaderModel, bool programUsesPointSize); -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_DYNAMICHLSL_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/EGLImageD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/EGLImageD3D.cpp index ca4b16987f..fcc2456bd6 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/EGLImageD3D.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/EGLImageD3D.cpp @@ -22,46 +22,14 @@ namespace rx { -static gl::ImageIndex GetImageIndex(GLenum target, size_t mip, size_t layer) -{ - if (target == GL_TEXTURE_3D) - { - return gl::ImageIndex::Make3D(static_cast(mip), static_cast(layer)); - } - else - { - ASSERT(layer == 0); - return gl::ImageIndex::MakeGeneric(target, static_cast(mip)); - } -} -EGLImageD3D::EGLImageD3D(RendererD3D *renderer, +EGLImageD3D::EGLImageD3D(const egl::ImageState &state, EGLenum target, - egl::ImageSibling *buffer, - const egl::AttributeMap &attribs) - : mRenderer(renderer), mBuffer(buffer), mAttachmentBuffer(nullptr), mRenderTarget(nullptr) + const egl::AttributeMap &attribs, + RendererD3D *renderer) + : ImageImpl(state), mRenderer(renderer), mRenderTarget(nullptr) { ASSERT(renderer != nullptr); - ASSERT(buffer != nullptr); - - if (egl::IsTextureTarget(target)) - { - mAttachmentBuffer = GetImplAs(GetAs(buffer)); - mAttachmentTarget = gl::FramebufferAttachment::Target( - GL_NONE, GetImageIndex(egl_gl::EGLImageTargetToGLTextureTarget(target), - attribs.get(EGL_GL_TEXTURE_LEVEL_KHR, 0), - attribs.get(EGL_GL_TEXTURE_ZOFFSET_KHR, 0))); - } - else if (egl::IsRenderbufferTarget(target)) - { - mAttachmentBuffer = GetImplAs(GetAs(buffer)); - mAttachmentTarget = - gl::FramebufferAttachment::Target(GL_NONE, gl::ImageIndex::MakeInvalid()); - } - else - { - UNREACHABLE(); - } } EGLImageD3D::~EGLImageD3D() @@ -71,62 +39,49 @@ EGLImageD3D::~EGLImageD3D() egl::Error EGLImageD3D::initialize() { - return egl::Error(EGL_SUCCESS); + return egl::NoError(); } -gl::Error EGLImageD3D::orphan(egl::ImageSibling *sibling) +gl::Error EGLImageD3D::orphan(const gl::Context *context, egl::ImageSibling *sibling) { - if (sibling == mBuffer) + if (sibling == mState.source.get()) { - gl::Error error = copyToLocalRendertarget(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(copyToLocalRendertarget(context)); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error EGLImageD3D::getRenderTarget(RenderTargetD3D **outRT) const +gl::Error EGLImageD3D::getRenderTarget(const gl::Context *context, RenderTargetD3D **outRT) const { - if (mAttachmentBuffer) + if (mState.source.get()) { + ASSERT(!mRenderTarget); FramebufferAttachmentRenderTarget *rt = nullptr; - gl::Error error = mAttachmentBuffer->getAttachmentRenderTarget(mAttachmentTarget, &rt); - if (error.isError()) - { - return error; - } - + ANGLE_TRY( + mState.source->getAttachmentRenderTarget(context, GL_NONE, mState.imageIndex, &rt)); *outRT = static_cast(rt); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } else { ASSERT(mRenderTarget); *outRT = mRenderTarget; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } } -gl::Error EGLImageD3D::copyToLocalRendertarget() +gl::Error EGLImageD3D::copyToLocalRendertarget(const gl::Context *context) { - ASSERT(mBuffer != nullptr); - ASSERT(mAttachmentBuffer != nullptr); + ASSERT(mState.source.get() != nullptr); ASSERT(mRenderTarget == nullptr); RenderTargetD3D *curRenderTarget = nullptr; - gl::Error error = getRenderTarget(&curRenderTarget); - if (error.isError()) - { - return error; - } + ANGLE_TRY(getRenderTarget(context, &curRenderTarget)); - // Clear the source image buffers - mBuffer = nullptr; - mAttachmentBuffer = nullptr; + // This only currently applies do D3D11, where it invalidates FBOs with this Image attached. + curRenderTarget->signalDirty(context); return mRenderer->createRenderTargetCopy(curRenderTarget, &mRenderTarget); } -} +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/EGLImageD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/EGLImageD3D.h index 6ec33e08f2..1ee7984426 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/EGLImageD3D.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/EGLImageD3D.h @@ -9,9 +9,13 @@ #ifndef LIBANGLE_RENDERER_D3D_EGLIMAGED3D_H_ #define LIBANGLE_RENDERER_D3D_EGLIMAGED3D_H_ -#include "libANGLE/FramebufferAttachment.h" #include "libANGLE/renderer/ImageImpl.h" +namespace gl +{ +class Context; +} + namespace egl { class AttributeMap; @@ -19,6 +23,7 @@ class AttributeMap; namespace rx { +class FramebufferAttachmentObjectImpl; class TextureD3D; class RenderbufferD3D; class RendererD3D; @@ -27,30 +32,24 @@ class RenderTargetD3D; class EGLImageD3D final : public ImageImpl { public: - EGLImageD3D(RendererD3D *renderer, + EGLImageD3D(const egl::ImageState &state, EGLenum target, - egl::ImageSibling *buffer, - const egl::AttributeMap &attribs); + const egl::AttributeMap &attribs, + RendererD3D *renderer); ~EGLImageD3D() override; egl::Error initialize() override; - gl::Error orphan(egl::ImageSibling *sibling) override; + gl::Error orphan(const gl::Context *context, egl::ImageSibling *sibling) override; - gl::Error getRenderTarget(RenderTargetD3D **outRT) const; + gl::Error getRenderTarget(const gl::Context *context, RenderTargetD3D **outRT) const; private: - gl::Error copyToLocalRendertarget(); + gl::Error copyToLocalRendertarget(const gl::Context *context); RendererD3D *mRenderer; - - egl::ImageSibling *mBuffer; - - gl::FramebufferAttachment::Target mAttachmentTarget; - FramebufferAttachmentObjectImpl *mAttachmentBuffer; - RenderTargetD3D *mRenderTarget; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_EGLIMAGED3D_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp index 82967aced0..3d73b2c840 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp @@ -8,14 +8,16 @@ #include "libANGLE/renderer/d3d/FramebufferD3D.h" -#include "common/BitSetIterator.h" -#include "libANGLE/formatutils.h" +#include "common/bitset_utils.h" +#include "libANGLE/Context.h" #include "libANGLE/Framebuffer.h" #include "libANGLE/FramebufferAttachment.h" #include "libANGLE/Surface.h" -#include "libANGLE/renderer/d3d/RendererD3D.h" -#include "libANGLE/renderer/d3d/RenderbufferD3D.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/ContextImpl.h" #include "libANGLE/renderer/d3d/RenderTargetD3D.h" +#include "libANGLE/renderer/d3d/RenderbufferD3D.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/SurfaceD3D.h" #include "libANGLE/renderer/d3d/SwapChainD3D.h" #include "libANGLE/renderer/d3d/TextureD3D.h" @@ -37,19 +39,19 @@ ClearParameters GetClearParameters(const gl::State &state, GLbitfield mask) { clearParams.clearColor[i] = false; } - clearParams.colorFClearValue = state.getColorClearValue(); - clearParams.colorClearType = GL_FLOAT; - clearParams.colorMaskRed = blendState.colorMaskRed; - clearParams.colorMaskGreen = blendState.colorMaskGreen; - clearParams.colorMaskBlue = blendState.colorMaskBlue; - clearParams.colorMaskAlpha = blendState.colorMaskAlpha; - clearParams.clearDepth = false; - clearParams.depthClearValue = state.getDepthClearValue(); - clearParams.clearStencil = false; - clearParams.stencilClearValue = state.getStencilClearValue(); + clearParams.colorF = state.getColorClearValue(); + clearParams.colorType = GL_FLOAT; + clearParams.colorMaskRed = blendState.colorMaskRed; + clearParams.colorMaskGreen = blendState.colorMaskGreen; + clearParams.colorMaskBlue = blendState.colorMaskBlue; + clearParams.colorMaskAlpha = blendState.colorMaskAlpha; + clearParams.clearDepth = false; + clearParams.depthValue = state.getDepthClearValue(); + clearParams.clearStencil = false; + clearParams.stencilValue = state.getStencilClearValue(); clearParams.stencilWriteMask = state.getDepthStencilState().stencilWritemask; - clearParams.scissorEnabled = state.isScissorTestEnabled(); - clearParams.scissor = state.getScissor(); + clearParams.scissorEnabled = state.isScissorTestEnabled(); + clearParams.scissor = state.getScissor(); const gl::Framebuffer *framebufferObject = state.getDrawFramebuffer(); if (mask & GL_COLOR_BUFFER_BIT) @@ -65,7 +67,8 @@ ClearParameters GetClearParameters(const gl::State &state, GLbitfield mask) if (mask & GL_DEPTH_BUFFER_BIT) { - if (state.getDepthStencilState().depthMask && framebufferObject->getDepthbuffer() != NULL) + if (state.getDepthStencilState().depthMask && + framebufferObject->getDepthbuffer() != nullptr) { clearParams.clearDepth = true; } @@ -73,7 +76,7 @@ ClearParameters GetClearParameters(const gl::State &state, GLbitfield mask) if (mask & GL_STENCIL_BUFFER_BIT) { - if (framebufferObject->getStencilbuffer() != NULL && + if (framebufferObject->getStencilbuffer() != nullptr && framebufferObject->getStencilbuffer()->getStencilSize() > 0) { clearParams.clearStencil = true; @@ -82,10 +85,13 @@ ClearParameters GetClearParameters(const gl::State &state, GLbitfield mask) return clearParams; } - } -FramebufferD3D::FramebufferD3D(const gl::Framebuffer::Data &data, RendererD3D *renderer) +ClearParameters::ClearParameters() = default; + +ClearParameters::ClearParameters(const ClearParameters &other) = default; + +FramebufferD3D::FramebufferD3D(const gl::FramebufferState &data, RendererD3D *renderer) : FramebufferImpl(data), mRenderer(renderer) { } @@ -94,20 +100,19 @@ FramebufferD3D::~FramebufferD3D() { } -gl::Error FramebufferD3D::clear(const gl::Data &data, GLbitfield mask) +gl::Error FramebufferD3D::clear(const gl::Context *context, GLbitfield mask) { - const gl::State &state = *data.state; - ClearParameters clearParams = GetClearParameters(state, mask); - return clear(data, clearParams); + ClearParameters clearParams = GetClearParameters(context->getGLState(), mask); + return clearImpl(context, clearParams); } -gl::Error FramebufferD3D::clearBufferfv(const gl::Data &data, +gl::Error FramebufferD3D::clearBufferfv(const gl::Context *context, GLenum buffer, GLint drawbuffer, const GLfloat *values) { // glClearBufferfv can be called to clear the color buffer or depth buffer - ClearParameters clearParams = GetClearParameters(*data.state, 0); + ClearParameters clearParams = GetClearParameters(context->getGLState(), 0); if (buffer == GL_COLOR) { @@ -115,43 +120,43 @@ gl::Error FramebufferD3D::clearBufferfv(const gl::Data &data, { clearParams.clearColor[i] = (drawbuffer == static_cast(i)); } - clearParams.colorFClearValue = gl::ColorF(values[0], values[1], values[2], values[3]); - clearParams.colorClearType = GL_FLOAT; + clearParams.colorF = gl::ColorF(values[0], values[1], values[2], values[3]); + clearParams.colorType = GL_FLOAT; } if (buffer == GL_DEPTH) { clearParams.clearDepth = true; - clearParams.depthClearValue = values[0]; + clearParams.depthValue = values[0]; } - return clear(data, clearParams); + return clearImpl(context, clearParams); } -gl::Error FramebufferD3D::clearBufferuiv(const gl::Data &data, +gl::Error FramebufferD3D::clearBufferuiv(const gl::Context *context, GLenum buffer, GLint drawbuffer, const GLuint *values) { // glClearBufferuiv can only be called to clear a color buffer - ClearParameters clearParams = GetClearParameters(*data.state, 0); + ClearParameters clearParams = GetClearParameters(context->getGLState(), 0); for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++) { clearParams.clearColor[i] = (drawbuffer == static_cast(i)); } - clearParams.colorUIClearValue = gl::ColorUI(values[0], values[1], values[2], values[3]); - clearParams.colorClearType = GL_UNSIGNED_INT; + clearParams.colorUI = gl::ColorUI(values[0], values[1], values[2], values[3]); + clearParams.colorType = GL_UNSIGNED_INT; - return clear(data, clearParams); + return clearImpl(context, clearParams); } -gl::Error FramebufferD3D::clearBufferiv(const gl::Data &data, +gl::Error FramebufferD3D::clearBufferiv(const gl::Context *context, GLenum buffer, GLint drawbuffer, const GLint *values) { // glClearBufferiv can be called to clear the color buffer or stencil buffer - ClearParameters clearParams = GetClearParameters(*data.state, 0); + ClearParameters clearParams = GetClearParameters(context->getGLState(), 0); if (buffer == GL_COLOR) { @@ -159,167 +164,154 @@ gl::Error FramebufferD3D::clearBufferiv(const gl::Data &data, { clearParams.clearColor[i] = (drawbuffer == static_cast(i)); } - clearParams.colorIClearValue = gl::ColorI(values[0], values[1], values[2], values[3]); - clearParams.colorClearType = GL_INT; + clearParams.colorI = gl::ColorI(values[0], values[1], values[2], values[3]); + clearParams.colorType = GL_INT; } if (buffer == GL_STENCIL) { clearParams.clearStencil = true; - clearParams.stencilClearValue = values[1]; + clearParams.stencilValue = values[0]; } - return clear(data, clearParams); + return clearImpl(context, clearParams); } -gl::Error FramebufferD3D::clearBufferfi(const gl::Data &data, +gl::Error FramebufferD3D::clearBufferfi(const gl::Context *context, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) { // glClearBufferfi can only be called to clear a depth stencil buffer - ClearParameters clearParams = GetClearParameters(*data.state, 0); - clearParams.clearDepth = true; - clearParams.depthClearValue = depth; - clearParams.clearStencil = true; - clearParams.stencilClearValue = stencil; + ClearParameters clearParams = GetClearParameters(context->getGLState(), 0); + clearParams.clearDepth = true; + clearParams.depthValue = depth; + clearParams.clearStencil = true; + clearParams.stencilValue = stencil; - return clear(data, clearParams); + return clearImpl(context, clearParams); } -GLenum FramebufferD3D::getImplementationColorReadFormat() const +GLenum FramebufferD3D::getImplementationColorReadFormat(const gl::Context *context) const { - const gl::FramebufferAttachment *readAttachment = mData.getReadAttachment(); + const gl::FramebufferAttachment *readAttachment = mState.getReadAttachment(); if (readAttachment == nullptr) { return GL_NONE; } - RenderTargetD3D *attachmentRenderTarget = NULL; - gl::Error error = readAttachment->getRenderTarget(&attachmentRenderTarget); + RenderTargetD3D *attachmentRenderTarget = nullptr; + gl::Error error = readAttachment->getRenderTarget(context, &attachmentRenderTarget); if (error.isError()) { return GL_NONE; } GLenum implementationFormat = getRenderTargetImplementationFormat(attachmentRenderTarget); - const gl::InternalFormat &implementationFormatInfo = gl::GetInternalFormatInfo(implementationFormat); + const gl::InternalFormat &implementationFormatInfo = + gl::GetSizedInternalFormatInfo(implementationFormat); - return implementationFormatInfo.format; + return implementationFormatInfo.getReadPixelsFormat(); } -GLenum FramebufferD3D::getImplementationColorReadType() const +GLenum FramebufferD3D::getImplementationColorReadType(const gl::Context *context) const { - const gl::FramebufferAttachment *readAttachment = mData.getReadAttachment(); + const gl::FramebufferAttachment *readAttachment = mState.getReadAttachment(); if (readAttachment == nullptr) { return GL_NONE; } - RenderTargetD3D *attachmentRenderTarget = NULL; - gl::Error error = readAttachment->getRenderTarget(&attachmentRenderTarget); + RenderTargetD3D *attachmentRenderTarget = nullptr; + gl::Error error = readAttachment->getRenderTarget(context, &attachmentRenderTarget); if (error.isError()) { return GL_NONE; } GLenum implementationFormat = getRenderTargetImplementationFormat(attachmentRenderTarget); - const gl::InternalFormat &implementationFormatInfo = gl::GetInternalFormatInfo(implementationFormat); + const gl::InternalFormat &implementationFormatInfo = + gl::GetSizedInternalFormatInfo(implementationFormat); - return implementationFormatInfo.type; + return implementationFormatInfo.getReadPixelsType(context->getClientVersion()); } -gl::Error FramebufferD3D::readPixels(const gl::State &state, const gl::Rectangle &area, GLenum format, GLenum type, GLvoid *pixels) const +gl::Error FramebufferD3D::readPixels(const gl::Context *context, + const gl::Rectangle &origArea, + GLenum format, + GLenum type, + void *pixels) { - const gl::PixelPackState &packState = state.getPackState(); + // Clip read area to framebuffer. + const gl::Extents fbSize = getState().getReadAttachment()->getSize(); + const gl::Rectangle fbRect(0, 0, fbSize.width, fbSize.height); + gl::Rectangle area; + if (!ClipRectangle(origArea, fbRect, &area)) + { + // nothing to read + return gl::NoError(); + } - GLenum sizedInternalFormat = gl::GetSizedInternalFormat(format, type); - const gl::InternalFormat &sizedFormatInfo = gl::GetInternalFormatInfo(sizedInternalFormat); - GLuint outputPitch = - sizedFormatInfo.computeRowPitch(type, area.width, packState.alignment, packState.rowLength); - GLsizei outputSkipBytes = sizedFormatInfo.computeSkipPixels( - outputPitch, 0, 0, packState.skipRows, packState.skipPixels); + const gl::PixelPackState &packState = context->getGLState().getPackState(); - return readPixelsImpl(area, format, type, outputPitch, packState, + const gl::InternalFormat &sizedFormatInfo = gl::GetInternalFormatInfo(format, type); + + GLuint outputPitch = 0; + ANGLE_TRY_RESULT(sizedFormatInfo.computeRowPitch(type, origArea.width, packState.alignment, + packState.rowLength), + outputPitch); + GLuint outputSkipBytes = 0; + ANGLE_TRY_RESULT(sizedFormatInfo.computeSkipBytes(outputPitch, 0, packState, false), + outputSkipBytes); + outputSkipBytes += + (area.x - origArea.x) * sizedFormatInfo.pixelBytes + (area.y - origArea.y) * outputPitch; + + return readPixelsImpl(context, area, format, type, outputPitch, packState, reinterpret_cast(pixels) + outputSkipBytes); } -gl::Error FramebufferD3D::blit(const gl::State &state, const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, - GLbitfield mask, GLenum filter, const gl::Framebuffer *sourceFramebuffer) +gl::Error FramebufferD3D::blit(const gl::Context *context, + const gl::Rectangle &sourceArea, + const gl::Rectangle &destArea, + GLbitfield mask, + GLenum filter) { - bool blitRenderTarget = false; - if ((mask & GL_COLOR_BUFFER_BIT) && - sourceFramebuffer->getReadColorbuffer() != nullptr && - mData.getFirstColorAttachment() != nullptr) - { - blitRenderTarget = true; - } + const auto &glState = context->getGLState(); + const gl::Framebuffer *sourceFramebuffer = glState.getReadFramebuffer(); + const gl::Rectangle *scissor = glState.isScissorTestEnabled() ? &glState.getScissor() : nullptr; + ANGLE_TRY(blitImpl(context, sourceArea, destArea, scissor, (mask & GL_COLOR_BUFFER_BIT) != 0, + (mask & GL_DEPTH_BUFFER_BIT) != 0, (mask & GL_STENCIL_BUFFER_BIT) != 0, + filter, sourceFramebuffer)); - bool blitStencil = false; - if ((mask & GL_STENCIL_BUFFER_BIT) && - sourceFramebuffer->getStencilbuffer() != nullptr && - mData.getStencilAttachment() != nullptr) - { - blitStencil = true; - } - - bool blitDepth = false; - if ((mask & GL_DEPTH_BUFFER_BIT) && - sourceFramebuffer->getDepthbuffer() != nullptr && - mData.getDepthAttachment() != nullptr) - { - blitDepth = true; - } - - if (blitRenderTarget || blitDepth || blitStencil) - { - const gl::Rectangle *scissor = state.isScissorTestEnabled() ? &state.getScissor() : NULL; - gl::Error error = blit(sourceArea, destArea, scissor, blitRenderTarget, blitDepth, blitStencil, - filter, sourceFramebuffer); - if (error.isError()) - { - return error; - } - } - - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -bool FramebufferD3D::checkStatus() const +bool FramebufferD3D::checkStatus(const gl::Context *context) const { // if we have both a depth and stencil buffer, they must refer to the same object // since we only support packed_depth_stencil and not separate depth and stencil - if (mData.getDepthAttachment() != nullptr && mData.getStencilAttachment() != nullptr && - mData.getDepthStencilAttachment() == nullptr) + if (mState.getDepthAttachment() != nullptr && mState.getStencilAttachment() != nullptr && + mState.getDepthStencilAttachment() == nullptr) { return false; } - // D3D11 does not allow for overlapping RenderTargetViews, so ensure uniqueness - const auto &colorAttachments = mData.getColorAttachments(); - for (size_t colorAttachment = 0; colorAttachment < colorAttachments.size(); colorAttachment++) + // D3D11 does not allow for overlapping RenderTargetViews. + // If WebGL compatibility is enabled, this has already been checked at a higher level. + ASSERT(!context->getExtensions().webglCompatibility || mState.colorAttachmentsAreUniqueImages()); + if (!context->getExtensions().webglCompatibility) { - const gl::FramebufferAttachment &attachment = colorAttachments[colorAttachment]; - if (attachment.isAttached()) + if (!mState.colorAttachmentsAreUniqueImages()) { - for (size_t prevColorAttachment = 0; prevColorAttachment < colorAttachment; prevColorAttachment++) - { - const gl::FramebufferAttachment &prevAttachment = colorAttachments[prevColorAttachment]; - if (prevAttachment.isAttached() && - (attachment.id() == prevAttachment.id() && - attachment.type() == prevAttachment.type())) - { - return false; - } - } + return false; } } // D3D requires all render targets to have the same dimensions. - if (!mData.attachmentsHaveSameDimensions()) + if (!mState.attachmentsHaveSameDimensions()) { return false; } @@ -327,45 +319,52 @@ bool FramebufferD3D::checkStatus() const return true; } -void FramebufferD3D::syncState(const gl::Framebuffer::DirtyBits &dirtyBits) +void FramebufferD3D::syncState(const gl::Context *context, + const gl::Framebuffer::DirtyBits &dirtyBits) { - bool invalidateColorAttachmentCache = false; - if (!mColorAttachmentsForRender.valid()) { - invalidateColorAttachmentCache = true; + return; } - for (auto dirtyBit : angle::IterateBitSet(dirtyBits)) + for (auto dirtyBit : dirtyBits) { if ((dirtyBit >= gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 && dirtyBit < gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX) || dirtyBit == gl::Framebuffer::DIRTY_BIT_DRAW_BUFFERS) { - invalidateColorAttachmentCache = true; + mColorAttachmentsForRender.reset(); } } +} - if (!invalidateColorAttachmentCache) +const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender(const gl::Context *context) +{ + gl::DrawBufferMask activeProgramOutputs = + context->getContextState().getState().getProgram()->getActiveOutputVariables(); + + if (mColorAttachmentsForRender.valid() && mCurrentActiveProgramOutputs == activeProgramOutputs) { - return; + return mColorAttachmentsForRender.value(); } // Does not actually free memory gl::AttachmentList colorAttachmentsForRender; - const auto &colorAttachments = mData.getColorAttachments(); - const auto &drawBufferStates = mData.getDrawBufferStates(); + const auto &colorAttachments = mState.getColorAttachments(); + const auto &drawBufferStates = mState.getDrawBufferStates(); const auto &workarounds = mRenderer->getWorkarounds(); for (size_t attachmentIndex = 0; attachmentIndex < colorAttachments.size(); ++attachmentIndex) { - GLenum drawBufferState = drawBufferStates[attachmentIndex]; + GLenum drawBufferState = drawBufferStates[attachmentIndex]; const gl::FramebufferAttachment &colorAttachment = colorAttachments[attachmentIndex]; - if (colorAttachment.isAttached() && drawBufferState != GL_NONE) + if (colorAttachment.isAttached() && drawBufferState != GL_NONE && + activeProgramOutputs[attachmentIndex]) { - ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + attachmentIndex)); + ASSERT(drawBufferState == GL_BACK || + drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + attachmentIndex)); colorAttachmentsForRender.push_back(&colorAttachment); } else if (!workarounds.mrtPerfWorkaround) @@ -374,12 +373,32 @@ void FramebufferD3D::syncState(const gl::Framebuffer::DirtyBits &dirtyBits) } } - mColorAttachmentsForRender = std::move(colorAttachmentsForRender); -} + // When rendering with no render target on D3D, two bugs lead to incorrect behavior on Intel + // drivers < 4815. The rendering samples always pass neglecting discard statements in pixel + // shader. We add a dummy texture as render target in such case. + if (mRenderer->getWorkarounds().addDummyTextureNoRenderTarget && + colorAttachmentsForRender.empty()) + { + static_assert(static_cast(activeProgramOutputs.size()) <= 32, + "Size of active program outputs should less or equal than 32."); + GLenum i = static_cast( + gl::ScanForward(static_cast(activeProgramOutputs.bits()))); + + gl::Texture *dummyTex = nullptr; + // TODO(Jamie): Handle error if dummy texture can't be created. + ANGLE_SWALLOW_ERR(mRenderer->getIncompleteTexture(context, GL_TEXTURE_2D, &dummyTex)); + if (dummyTex) + { + gl::ImageIndex index = gl::ImageIndex::Make2D(0); + gl::FramebufferAttachment *dummyAttach = new gl::FramebufferAttachment( + context, GL_TEXTURE, GL_COLOR_ATTACHMENT0_EXT + i, index, dummyTex); + colorAttachmentsForRender.push_back(dummyAttach); + } + } + + mColorAttachmentsForRender = std::move(colorAttachmentsForRender); + mCurrentActiveProgramOutputs = activeProgramOutputs; -const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender() const -{ - ASSERT(mColorAttachmentsForRender.valid()); return mColorAttachmentsForRender.value(); } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.h index eb839c4364..a7312fdef4 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.h @@ -9,9 +9,10 @@ #ifndef LIBANGLE_RENDERER_D3D_FRAMBUFFERD3D_H_ #define LIBANGLE_RENDERER_D3D_FRAMBUFFERD3D_H_ -#include #include +#include +#include "common/Color.h" #include "common/Optional.h" #include "libANGLE/angletypes.h" #include "libANGLE/renderer/FramebufferImpl.h" @@ -22,32 +23,33 @@ class FramebufferAttachment; struct PixelPackState; typedef std::vector AttachmentList; - } namespace rx { class RendererD3D; class RenderTargetD3D; -struct WorkaroundsD3D; struct ClearParameters { + ClearParameters(); + ClearParameters(const ClearParameters &other); + bool clearColor[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS]; - gl::ColorF colorFClearValue; - gl::ColorI colorIClearValue; - gl::ColorUI colorUIClearValue; - GLenum colorClearType; + gl::ColorF colorF; + gl::ColorI colorI; + gl::ColorUI colorUI; + GLenum colorType; bool colorMaskRed; bool colorMaskGreen; bool colorMaskBlue; bool colorMaskAlpha; bool clearDepth; - float depthClearValue; + float depthValue; bool clearStencil; - GLint stencilClearValue; + GLint stencilValue; GLuint stencilWriteMask; bool scissorEnabled; @@ -57,61 +59,76 @@ struct ClearParameters class FramebufferD3D : public FramebufferImpl { public: - FramebufferD3D(const gl::Framebuffer::Data &data, RendererD3D *renderer); - virtual ~FramebufferD3D(); + FramebufferD3D(const gl::FramebufferState &data, RendererD3D *renderer); + ~FramebufferD3D() override; - gl::Error clear(const gl::Data &data, GLbitfield mask) override; - gl::Error clearBufferfv(const gl::Data &data, + gl::Error clear(const gl::Context *context, GLbitfield mask) override; + gl::Error clearBufferfv(const gl::Context *context, GLenum buffer, GLint drawbuffer, const GLfloat *values) override; - gl::Error clearBufferuiv(const gl::Data &data, + gl::Error clearBufferuiv(const gl::Context *context, GLenum buffer, GLint drawbuffer, const GLuint *values) override; - gl::Error clearBufferiv(const gl::Data &data, + gl::Error clearBufferiv(const gl::Context *context, GLenum buffer, GLint drawbuffer, const GLint *values) override; - gl::Error clearBufferfi(const gl::Data &data, + gl::Error clearBufferfi(const gl::Context *context, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) override; - GLenum getImplementationColorReadFormat() const override; - GLenum getImplementationColorReadType() const override; - gl::Error readPixels(const gl::State &state, const gl::Rectangle &area, GLenum format, GLenum type, GLvoid *pixels) const override; + GLenum getImplementationColorReadFormat(const gl::Context *context) const override; + GLenum getImplementationColorReadType(const gl::Context *context) const override; + gl::Error readPixels(const gl::Context *context, + const gl::Rectangle &area, + GLenum format, + GLenum type, + void *pixels) override; - gl::Error blit(const gl::State &state, const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, - GLbitfield mask, GLenum filter, const gl::Framebuffer *sourceFramebuffer) override; + gl::Error blit(const gl::Context *context, + const gl::Rectangle &sourceArea, + const gl::Rectangle &destArea, + GLbitfield mask, + GLenum filter) override; - bool checkStatus() const override; + bool checkStatus(const gl::Context *context) const override; - void syncState(const gl::Framebuffer::DirtyBits &dirtyBits) override; + void syncState(const gl::Context *context, + const gl::Framebuffer::DirtyBits &dirtyBits) override; - const gl::AttachmentList &getColorAttachmentsForRender() const; + const gl::AttachmentList &getColorAttachmentsForRender(const gl::Context *context); private: - virtual gl::Error clear(const gl::Data &data, const ClearParameters &clearParams) = 0; + virtual gl::Error clearImpl(const gl::Context *context, const ClearParameters &clearParams) = 0; - virtual gl::Error readPixelsImpl(const gl::Rectangle &area, + virtual gl::Error readPixelsImpl(const gl::Context *context, + const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch, const gl::PixelPackState &pack, - uint8_t *pixels) const = 0; + uint8_t *pixels) = 0; - virtual gl::Error blit(const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, const gl::Rectangle *scissor, - bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter, - const gl::Framebuffer *sourceFramebuffer) = 0; + virtual gl::Error blitImpl(const gl::Context *context, + const gl::Rectangle &sourceArea, + const gl::Rectangle &destArea, + const gl::Rectangle *scissor, + bool blitRenderTarget, + bool blitDepth, + bool blitStencil, + GLenum filter, + const gl::Framebuffer *sourceFramebuffer) = 0; virtual GLenum getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const = 0; RendererD3D *mRenderer; Optional mColorAttachmentsForRender; + gl::DrawBufferMask mCurrentActiveProgramOutputs; }; - } -#endif // LIBANGLE_RENDERER_D3D_FRAMBUFFERD3D_H_ +#endif // LIBANGLE_RENDERER_D3D_FRAMBUFFERD3D_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp index df0257e370..b38765070b 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp @@ -6,16 +6,14 @@ #include "libANGLE/renderer/d3d/HLSLCompiler.h" +#include + #include "common/utilities.h" #include "libANGLE/Program.h" #include "libANGLE/features.h" #include "libANGLE/histogram_macros.h" #include "third_party/trace_event/trace_event.h" -#ifndef QT_D3DCOMPILER_DLL -#define QT_D3DCOMPILER_DLL D3DCOMPILER_DLL -#endif - #if ANGLE_APPEND_ASSEMBLY_TO_SHADER_DEBUG_INFO == ANGLE_ENABLED namespace { @@ -25,15 +23,6 @@ namespace #define CREATE_COMPILER_FLAG_INFO(flag) { flag, #flag } -#if defined(ANGLE_MINGW32_COMPAT) -#ifndef D3DCOMPILE_RESERVED16 -#define D3DCOMPILE_RESERVED16 0x10000 -#endif -#ifndef D3DCOMPILE_RESERVED17 -#define D3DCOMPILE_RESERVED17 0x20000 -#endif -#endif - struct CompilerFlagInfo { UINT mFlag; @@ -119,11 +108,11 @@ HLSLCompiler::~HLSLCompiler() release(); } -gl::Error HLSLCompiler::initialize() +gl::Error HLSLCompiler::ensureInitialized() { if (mInitialized) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } TRACE_EVENT0("gpu.angle", "HLSLCompiler::initialize"); @@ -141,28 +130,6 @@ gl::Error HLSLCompiler::initialize() } #endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES - // Load the compiler DLL specified by the environment, or default to QT_D3DCOMPILER_DLL - const wchar_t *defaultCompiler = _wgetenv(L"QT_D3DCOMPILER_DLL"); - if (!defaultCompiler) - defaultCompiler = QT_D3DCOMPILER_DLL; - - const wchar_t *compilerDlls[] = { - defaultCompiler, - L"d3dcompiler_47.dll", - L"d3dcompiler_46.dll", - L"d3dcompiler_43.dll", - 0 - }; - - // Load the first available known compiler DLL - for (int i = 0; compilerDlls[i]; ++i) - { - mD3DCompilerModule = LoadLibrary(compilerDlls[i]); - if (mD3DCompilerModule) - break; - } - - if (!mD3DCompilerModule) { // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with. @@ -171,7 +138,8 @@ gl::Error HLSLCompiler::initialize() if (!mD3DCompilerModule) { - return gl::Error(GL_INVALID_OPERATION, "No D3D compiler module found - aborting!\n"); + ERR() << "D3D compiler module not found."; + return gl::OutOfMemory() << "D3D compiler module not found."; } mD3DCompileFunc = reinterpret_cast(GetProcAddress(mD3DCompilerModule, "D3DCompile")); @@ -190,11 +158,11 @@ gl::Error HLSLCompiler::initialize() if (mD3DCompileFunc == nullptr) { - return gl::Error(GL_INVALID_OPERATION, "Error finding D3DCompile entry point"); + return gl::OutOfMemory() << "Error finding D3DCompile entry point."; } mInitialized = true; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } void HLSLCompiler::release() @@ -213,11 +181,7 @@ gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string const std::vector &configs, const D3D_SHADER_MACRO *overrideMacros, ID3DBlob **outCompiledBlob, std::string *outDebugInfo) { - gl::Error error = initialize(); - if (error.isError()) - { - return error; - } + ASSERT(mInitialized); #if !defined(ANGLE_ENABLE_WINDOWS_STORE) ASSERT(mD3DCompilerModule); @@ -228,7 +192,9 @@ gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string if (gl::DebugAnnotationsActive()) { std::string sourcePath = getTempPath(); - std::string sourceText = FormatString("#line 2 \"%s\"\n\n%s", sourcePath.c_str(), hlsl.c_str()); + std::ostringstream stream; + stream << "#line 2 \"" << sourcePath << "\"\n\n" << hlsl; + std::string sourceText = stream.str(); writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size()); } #endif @@ -255,8 +221,11 @@ gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string SafeRelease(errorMessage); infoLog.appendSanitized(message.c_str()); - TRACE("\n%s", hlsl.c_str()); - TRACE("\n%s", message.c_str()); + + // This produces unbelievable amounts of spam in about:gpu. + // WARN() << std::endl << hlsl; + + WARN() << std::endl << message; if ((message.find("error X3531:") != std::string::npos || // "can't unroll loops marked with loop attribute" message.find("error X4014:") != std::string::npos) && // "cannot have gradient operations inside loops with divergent flow control", @@ -304,20 +273,17 @@ gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string } std::string disassembly; - error = disassembleBinary(binary, &disassembly); - if (error.isError()) - { - return error; - } + ANGLE_TRY(disassembleBinary(binary, &disassembly)); (*outDebugInfo) += "\n" + disassembly + "\n// ASSEMBLY END\n"; #endif // ANGLE_APPEND_ASSEMBLY_TO_SHADER_DEBUG_INFO == ANGLE_ENABLED - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } if (result == E_OUTOFMEMORY) { *outCompiledBlob = nullptr; - return gl::Error(GL_OUT_OF_MEMORY, "HLSL compiler had an unexpected failure, result: 0x%X.", result); + return gl::OutOfMemory() + << "HLSL compiler had an unexpected failure, " << gl::FmtHR(result); } infoLog << "Warning: D3D shader compilation failed with " << configs[i].name << " flags. (" @@ -331,16 +297,12 @@ gl::Error HLSLCompiler::compileToBinary(gl::InfoLog &infoLog, const std::string // None of the configurations succeeded in compiling this shader but the compiler is still intact *outCompiledBlob = nullptr; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error HLSLCompiler::disassembleBinary(ID3DBlob *shaderBinary, std::string *disassemblyOut) { - gl::Error error = initialize(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(ensureInitialized()); // Retrieve disassembly UINT flags = D3D_DISASM_ENABLE_DEFAULT_VALUE_PRINTS | D3D_DISASM_ENABLE_INSTRUCTION_NUMBERING; @@ -361,7 +323,7 @@ gl::Error HLSLCompiler::disassembleBinary(ID3DBlob *shaderBinary, std::string *d SafeRelease(disassembly); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } } // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.h index 3c0d2adcac..c8f9eac290 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.h @@ -1,3 +1,11 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// HLSLCompiler: Wrapper for the D3DCompiler DLL. +// + #ifndef LIBANGLE_RENDERER_D3D_HLSLCOMPILER_H_ #define LIBANGLE_RENDERER_D3D_HLSLCOMPILER_H_ @@ -41,9 +49,9 @@ class HLSLCompiler : angle::NonCopyable ID3DBlob **outCompiledBlob, std::string *outDebugInfo); gl::Error disassembleBinary(ID3DBlob *shaderBinary, std::string *disassemblyOut); + gl::Error ensureInitialized(); private: - gl::Error initialize(); bool mInitialized; HMODULE mD3DCompilerModule; @@ -53,4 +61,4 @@ class HLSLCompiler : angle::NonCopyable } -#endif // LIBANGLE_RENDERER_D3D_HLSLCOMPILER_H_ +#endif // LIBANGLE_RENDERER_D3D_HLSLCOMPILER_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/ImageD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ImageD3D.cpp index ead5db6453..dbbcbbed2a 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/ImageD3D.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ImageD3D.cpp @@ -29,4 +29,34 @@ ImageD3D::ImageD3D() { } +gl::Error ImageD3D::setManagedSurface2D(const gl::Context *context, + TextureStorage *storage, + int level) +{ + return gl::NoError(); +} + +gl::Error ImageD3D::setManagedSurfaceCube(const gl::Context *context, + TextureStorage *storage, + int face, + int level) +{ + return gl::NoError(); +} + +gl::Error ImageD3D::setManagedSurface3D(const gl::Context *context, + TextureStorage *storage, + int level) +{ + return gl::NoError(); +} + +gl::Error ImageD3D::setManagedSurface2DArray(const gl::Context *context, + TextureStorage *storage, + int layer, + int level) +{ + return gl::NoError(); +} + } // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/ImageD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ImageD3D.h index 2afe1cfabf..1b7235fbaa 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/ImageD3D.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ImageD3D.h @@ -17,6 +17,7 @@ namespace gl { +class Context; class Framebuffer; struct ImageIndex; struct Box; @@ -51,18 +52,40 @@ class ImageD3D : angle::NonCopyable virtual bool redefine(GLenum target, GLenum internalformat, const gl::Extents &size, bool forceRelease) = 0; - virtual gl::Error loadData(const gl::Box &area, const gl::PixelUnpackState &unpack, GLenum type, const void *input) = 0; - virtual gl::Error loadCompressedData(const gl::Box &area, const void *input) = 0; + virtual gl::Error loadData(const gl::Context *context, + const gl::Box &area, + const gl::PixelUnpackState &unpack, + GLenum type, + const void *input, + bool applySkipImages) = 0; + virtual gl::Error loadCompressedData(const gl::Context *context, + const gl::Box &area, + const void *input) = 0; - virtual gl::Error setManagedSurface2D(TextureStorage *storage, int level) { return gl::Error(GL_NO_ERROR); }; - virtual gl::Error setManagedSurfaceCube(TextureStorage *storage, int face, int level) { return gl::Error(GL_NO_ERROR); }; - virtual gl::Error setManagedSurface3D(TextureStorage *storage, int level) { return gl::Error(GL_NO_ERROR); }; - virtual gl::Error setManagedSurface2DArray(TextureStorage *storage, int layer, int level) { return gl::Error(GL_NO_ERROR); }; - virtual gl::Error copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box ®ion) = 0; + virtual gl::Error setManagedSurface2D(const gl::Context *context, + TextureStorage *storage, + int level); + virtual gl::Error setManagedSurfaceCube(const gl::Context *context, + TextureStorage *storage, + int face, + int level); + virtual gl::Error setManagedSurface3D(const gl::Context *context, + TextureStorage *storage, + int level); + virtual gl::Error setManagedSurface2DArray(const gl::Context *context, + TextureStorage *storage, + int layer, + int level); + virtual gl::Error copyToStorage(const gl::Context *context, + TextureStorage *storage, + const gl::ImageIndex &index, + const gl::Box ®ion) = 0; - virtual gl::Error copyFromTexStorage(const gl::ImageIndex &imageIndex, + virtual gl::Error copyFromTexStorage(const gl::Context *context, + const gl::ImageIndex &imageIndex, TextureStorage *source) = 0; - virtual gl::Error copyFromFramebuffer(const gl::Offset &destOffset, + virtual gl::Error copyFromFramebuffer(const gl::Context *context, + const gl::Offset &destOffset, const gl::Rectangle &sourceArea, const gl::Framebuffer *source) = 0; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexBuffer.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexBuffer.cpp index 677b8bb240..937512a96a 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexBuffer.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexBuffer.cpp @@ -71,7 +71,8 @@ gl::Error IndexBufferInterface::mapBuffer(unsigned int size, void **outMappedMem // Protect against integer overflow if (mWritePosition + size < mWritePosition) { - return gl::Error(GL_OUT_OF_MEMORY, "Mapping of internal index buffer would cause an integer overflow."); + return gl::OutOfMemory() + << "Mapping of internal index buffer would cause an integer overflow."; } gl::Error error = mIndexBuffer->mapBuffer(mWritePosition, size, outMappedMemory); @@ -79,7 +80,7 @@ gl::Error IndexBufferInterface::mapBuffer(unsigned int size, void **outMappedMem { if (outMappedMemory) { - *outMappedMemory = NULL; + *outMappedMemory = nullptr; } return error; } @@ -90,7 +91,7 @@ gl::Error IndexBufferInterface::mapBuffer(unsigned int size, void **outMappedMem } mWritePosition += size; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error IndexBufferInterface::unmapBuffer() @@ -145,24 +146,16 @@ gl::Error StreamingIndexBufferInterface::reserveBufferSpace(unsigned int size, G unsigned int writePos = getWritePosition(); if (size > curBufferSize) { - gl::Error error = setBufferSize(std::max(size, 2 * curBufferSize), indexType); - if (error.isError()) - { - return error; - } + ANGLE_TRY(setBufferSize(std::max(size, 2 * curBufferSize), indexType)); setWritePosition(0); } else if (writePos + size > curBufferSize || writePos + size < writePos) { - gl::Error error = discard(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(discard()); setWritePosition(0); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } @@ -184,13 +177,13 @@ gl::Error StaticIndexBufferInterface::reserveBufferSpace(unsigned int size, GLen } else if (curSize >= size && indexType == getIndexType()) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } else { UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION, "Internal static index buffers can't be resized"); + return gl::InternalError() << "Internal static index buffers can't be resized"; } } -} +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexBuffer.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexBuffer.h index 0b7b28ddf0..969cf6ae63 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexBuffer.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexBuffer.h @@ -81,7 +81,7 @@ class StreamingIndexBufferInterface : public IndexBufferInterface { public: explicit StreamingIndexBufferInterface(BufferFactoryD3D *factory); - ~StreamingIndexBufferInterface(); + ~StreamingIndexBufferInterface() override; gl::Error reserveBufferSpace(unsigned int size, GLenum indexType) override; }; @@ -90,7 +90,7 @@ class StaticIndexBufferInterface : public IndexBufferInterface { public: explicit StaticIndexBufferInterface(BufferFactoryD3D *factory); - ~StaticIndexBufferInterface(); + ~StaticIndexBufferInterface() override; gl::Error reserveBufferSpace(unsigned int size, GLenum indexType) override; }; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexDataManager.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexDataManager.cpp index f1ba3d3db0..e974097b45 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexDataManager.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexDataManager.cpp @@ -10,10 +10,12 @@ #include "libANGLE/renderer/d3d/IndexDataManager.h" #include "common/utilities.h" +#include "libANGLE/Buffer.h" +#include "libANGLE/Context.h" +#include "libANGLE/VertexArray.h" +#include "libANGLE/formatutils.h" #include "libANGLE/renderer/d3d/BufferD3D.h" #include "libANGLE/renderer/d3d/IndexBuffer.h" -#include "libANGLE/Buffer.h" -#include "libANGLE/formatutils.h" namespace rx { @@ -76,11 +78,12 @@ void ConvertIndices(GLenum sourceType, ConvertIndexArray(input, sourceType, output, destinationType, count, usePrimitiveRestartFixedIndex); } - else UNREACHABLE(); + else + UNREACHABLE(); } gl::Error StreamInIndexBuffer(IndexBufferInterface *buffer, - const GLvoid *data, + const void *data, unsigned int count, GLenum srcType, GLenum dstType, @@ -91,50 +94,59 @@ gl::Error StreamInIndexBuffer(IndexBufferInterface *buffer, if (count > (std::numeric_limits::max() >> dstTypeInfo.bytesShift)) { - return gl::Error(GL_OUT_OF_MEMORY, - "Reserving %u indices of %u bytes each exceeds the maximum buffer size.", - count, dstTypeInfo.bytes); + return gl::OutOfMemory() << "Reserving " << count << " indices of " << dstTypeInfo.bytes + << " bytes each exceeds the maximum buffer size."; } unsigned int bufferSizeRequired = count << dstTypeInfo.bytesShift; - gl::Error error = buffer->reserveBufferSpace(bufferSizeRequired, dstType); - if (error.isError()) - { - return error; - } + ANGLE_TRY(buffer->reserveBufferSpace(bufferSizeRequired, dstType)); void *output = nullptr; - error = buffer->mapBuffer(bufferSizeRequired, &output, offset); - if (error.isError()) - { - return error; - } + ANGLE_TRY(buffer->mapBuffer(bufferSizeRequired, &output, offset)); ConvertIndices(srcType, dstType, data, count, output, usePrimitiveRestartFixedIndex); - error = buffer->unmapBuffer(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(buffer->unmapBuffer()); + return gl::NoError(); +} - return gl::Error(GL_NO_ERROR); +unsigned int ElementTypeSize(GLenum elementType) +{ + switch (elementType) + { + case GL_UNSIGNED_BYTE: + return sizeof(GLubyte); + case GL_UNSIGNED_SHORT: + return sizeof(GLushort); + case GL_UNSIGNED_INT: + return sizeof(GLuint); + default: + UNREACHABLE(); + return 0; + } } } // anonymous namespace -IndexDataManager::IndexDataManager(BufferFactoryD3D *factory, RendererClass rendererClass) - : mFactory(factory), - mRendererClass(rendererClass), - mStreamingBufferShort(nullptr), - mStreamingBufferInt(nullptr) +bool IsOffsetAligned(GLenum elementType, unsigned int offset) +{ + return (offset % ElementTypeSize(elementType) == 0); +} + +// IndexDataManager implementation. +IndexDataManager::IndexDataManager(BufferFactoryD3D *factory) + : mFactory(factory), mStreamingBufferShort(), mStreamingBufferInt() { } IndexDataManager::~IndexDataManager() { - SafeDelete(mStreamingBufferShort); - SafeDelete(mStreamingBufferInt); +} + +void IndexDataManager::deinitialize() +{ + mStreamingBufferShort.reset(); + mStreamingBufferInt.reset(); } // This function translates a GL-style indices into DX-style indices, with their description @@ -143,43 +155,31 @@ IndexDataManager::~IndexDataManager() // possible in DX and requires streaming (Case 1). If the GL indices are specified with a buffer // (Case 2), in a format supported by DX (subcase a) then all is good. // When we have a buffer with an unsupported format (subcase b) then we need to do some translation: -// we will start by falling back to streaming, and after a while will start using a static translated -// copy of the index buffer. -gl::Error IndexDataManager::prepareIndexData(GLenum srcType, +// we will start by falling back to streaming, and after a while will start using a static +// translated copy of the index buffer. +gl::Error IndexDataManager::prepareIndexData(const gl::Context *context, + GLenum srcType, + GLenum dstType, GLsizei count, gl::Buffer *glBuffer, - const GLvoid *indices, - TranslatedIndexData *translated, - bool primitiveRestartFixedIndexEnabled) + const void *indices, + TranslatedIndexData *translated) { - // Avoid D3D11's primitive restart index value - // see http://msdn.microsoft.com/en-us/library/windows/desktop/bb205124(v=vs.85).aspx - bool hasPrimitiveRestartIndex = - translated->indexRange.vertexIndexCount < static_cast(count) || - translated->indexRange.end == gl::GetPrimitiveRestartIndex(srcType); - bool primitiveRestartWorkaround = mRendererClass == RENDERER_D3D11 && - !primitiveRestartFixedIndexEnabled && - hasPrimitiveRestartIndex && srcType == GL_UNSIGNED_SHORT; - - // We should never have to deal with MAX_UINT indices, since we restrict it via - // MAX_ELEMENT_INDEX. - ASSERT(!(mRendererClass == RENDERER_D3D11 && !primitiveRestartFixedIndexEnabled && - hasPrimitiveRestartIndex && srcType == GL_UNSIGNED_INT)); - - const GLenum dstType = (srcType == GL_UNSIGNED_INT || primitiveRestartWorkaround) ? - GL_UNSIGNED_INT : GL_UNSIGNED_SHORT; - const gl::Type &srcTypeInfo = gl::GetTypeInfo(srcType); const gl::Type &dstTypeInfo = gl::GetTypeInfo(dstType); BufferD3D *buffer = glBuffer ? GetImplAs(glBuffer) : nullptr; - translated->indexType = dstType; + translated->indexType = dstType; translated->srcIndexData.srcBuffer = buffer; translated->srcIndexData.srcIndices = indices; translated->srcIndexData.srcIndexType = srcType; translated->srcIndexData.srcCount = count; + // Context can be nullptr in perf tests. + bool primitiveRestartFixedIndexEnabled = + context ? context->getGLState().isPrimitiveRestartEnabled() : false; + // Case 1: the indices are passed by pointer, which forces the streaming of index data if (glBuffer == nullptr) { @@ -192,95 +192,69 @@ gl::Error IndexDataManager::prepareIndexData(GLenum srcType, unsigned int offset = static_cast(reinterpret_cast(indices)); ASSERT(srcTypeInfo.bytes * static_cast(count) + offset <= buffer->getSize()); - bool offsetAligned; - switch (srcType) - { - case GL_UNSIGNED_BYTE: offsetAligned = (offset % sizeof(GLubyte) == 0); break; - case GL_UNSIGNED_SHORT: offsetAligned = (offset % sizeof(GLushort) == 0); break; - case GL_UNSIGNED_INT: offsetAligned = (offset % sizeof(GLuint) == 0); break; - default: UNREACHABLE(); offsetAligned = false; - } + bool offsetAligned = IsOffsetAligned(srcType, offset); // Case 2a: the buffer can be used directly - if (offsetAligned && buffer->supportsDirectBinding() && - dstType == srcType && !primitiveRestartWorkaround) + if (offsetAligned && buffer->supportsDirectBinding() && dstType == srcType) { - translated->storage = buffer; + translated->storage = buffer; translated->indexBuffer = nullptr; - translated->serial = buffer->getSerial(); - translated->startIndex = (offset >> srcTypeInfo.bytesShift); + translated->serial = buffer->getSerial(); + translated->startIndex = (offset >> srcTypeInfo.bytesShift); translated->startOffset = offset; - buffer->promoteStaticUsage(count << srcTypeInfo.bytesShift); - return gl::Error(GL_NO_ERROR); - } - else - { - translated->storage = nullptr; + return gl::NoError(); } + translated->storage = nullptr; + // Case 2b: use a static translated copy or fall back to streaming StaticIndexBufferInterface *staticBuffer = buffer->getStaticIndexBuffer(); bool staticBufferInitialized = staticBuffer && staticBuffer->getBufferSize() != 0; - bool staticBufferUsable = staticBuffer && - offsetAligned && staticBuffer->getIndexType() == dstType; + bool staticBufferUsable = + staticBuffer && offsetAligned && staticBuffer->getIndexType() == dstType; if (staticBufferInitialized && !staticBufferUsable) { - buffer->invalidateStaticData(D3D_BUFFER_INVALIDATE_WHOLE_CACHE); + buffer->invalidateStaticData(context); staticBuffer = nullptr; } if (staticBuffer == nullptr || !offsetAligned) { const uint8_t *bufferData = nullptr; - gl::Error error = buffer->getData(&bufferData); - if (error.isError()) - { - return error; - } + ANGLE_TRY(buffer->getData(context, &bufferData)); ASSERT(bufferData != nullptr); - error = streamIndexData(bufferData + offset, count, srcType, dstType, - primitiveRestartFixedIndexEnabled, translated); - if (error.isError()) - { - return error; - } + ANGLE_TRY(streamIndexData(bufferData + offset, count, srcType, dstType, + primitiveRestartFixedIndexEnabled, translated)); + buffer->promoteStaticUsage(context, count << srcTypeInfo.bytesShift); } else { if (!staticBufferInitialized) { const uint8_t *bufferData = nullptr; - gl::Error error = buffer->getData(&bufferData); - if (error.isError()) - { - return error; - } + ANGLE_TRY(buffer->getData(context, &bufferData)); ASSERT(bufferData != nullptr); unsigned int convertCount = static_cast(buffer->getSize()) >> srcTypeInfo.bytesShift; - error = StreamInIndexBuffer(staticBuffer, bufferData, convertCount, srcType, dstType, - primitiveRestartFixedIndexEnabled, nullptr); - if (error.isError()) - { - return error; - } + ANGLE_TRY(StreamInIndexBuffer(staticBuffer, bufferData, convertCount, srcType, dstType, + primitiveRestartFixedIndexEnabled, nullptr)); } ASSERT(offsetAligned && staticBuffer->getIndexType() == dstType); translated->indexBuffer = staticBuffer->getIndexBuffer(); - translated->serial = staticBuffer->getSerial(); - translated->startIndex = (offset >> srcTypeInfo.bytesShift); + translated->serial = staticBuffer->getSerial(); + translated->startIndex = (offset >> srcTypeInfo.bytesShift); translated->startOffset = (offset >> srcTypeInfo.bytesShift) << dstTypeInfo.bytesShift; } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error IndexDataManager::streamIndexData(const GLvoid *data, +gl::Error IndexDataManager::streamIndexData(const void *data, unsigned int count, GLenum srcType, GLenum dstType, @@ -290,65 +264,57 @@ gl::Error IndexDataManager::streamIndexData(const GLvoid *data, const gl::Type &dstTypeInfo = gl::GetTypeInfo(dstType); IndexBufferInterface *indexBuffer = nullptr; - gl::Error error = getStreamingIndexBuffer(dstType, &indexBuffer); - if (error.isError()) - { - return error; - } + ANGLE_TRY(getStreamingIndexBuffer(dstType, &indexBuffer)); ASSERT(indexBuffer != nullptr); unsigned int offset; - StreamInIndexBuffer(indexBuffer, data, count, srcType, dstType, usePrimitiveRestartFixedIndex, - &offset); + ANGLE_TRY(StreamInIndexBuffer(indexBuffer, data, count, srcType, dstType, + usePrimitiveRestartFixedIndex, &offset)); translated->indexBuffer = indexBuffer->getIndexBuffer(); - translated->serial = indexBuffer->getSerial(); - translated->startIndex = (offset >> dstTypeInfo.bytesShift); + translated->serial = indexBuffer->getSerial(); + translated->startIndex = (offset >> dstTypeInfo.bytesShift); translated->startOffset = offset; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error IndexDataManager::getStreamingIndexBuffer(GLenum destinationIndexType, IndexBufferInterface **outBuffer) { ASSERT(outBuffer); - if (destinationIndexType == GL_UNSIGNED_INT) + ASSERT(destinationIndexType == GL_UNSIGNED_SHORT || destinationIndexType == GL_UNSIGNED_INT); + + auto &streamingBuffer = + (destinationIndexType == GL_UNSIGNED_INT) ? mStreamingBufferInt : mStreamingBufferShort; + + if (!streamingBuffer) { - if (!mStreamingBufferInt) - { - mStreamingBufferInt = new StreamingIndexBufferInterface(mFactory); - gl::Error error = mStreamingBufferInt->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, - GL_UNSIGNED_INT); - if (error.isError()) - { - SafeDelete(mStreamingBufferInt); - return error; - } - } - - *outBuffer = mStreamingBufferInt; - return gl::Error(GL_NO_ERROR); + StreamingBuffer newBuffer(new StreamingIndexBufferInterface(mFactory)); + ANGLE_TRY(newBuffer->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, destinationIndexType)); + streamingBuffer = std::move(newBuffer); } - else - { - ASSERT(destinationIndexType == GL_UNSIGNED_SHORT); - if (!mStreamingBufferShort) - { - mStreamingBufferShort = new StreamingIndexBufferInterface(mFactory); - gl::Error error = mStreamingBufferShort->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, - GL_UNSIGNED_SHORT); - if (error.isError()) - { - SafeDelete(mStreamingBufferShort); - return error; - } - } - - *outBuffer = mStreamingBufferShort; - return gl::Error(GL_NO_ERROR); - } + *outBuffer = streamingBuffer.get(); + return gl::NoError(); } +GLenum GetIndexTranslationDestType(GLenum srcType, + const gl::HasIndexRange &lazyIndexRange, + bool usePrimitiveRestartWorkaround) +{ + // Avoid D3D11's primitive restart index value + // see http://msdn.microsoft.com/en-us/library/windows/desktop/bb205124(v=vs.85).aspx + if (usePrimitiveRestartWorkaround) + { + const gl::IndexRange &indexRange = lazyIndexRange.getIndexRange().value(); + if (indexRange.end == gl::GetPrimitiveRestartIndex(srcType)) + { + return GL_UNSIGNED_INT; + } + } + + return (srcType == GL_UNSIGNED_INT) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT; } + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexDataManager.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexDataManager.h index 44eb68c071..77f05df92d 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexDataManager.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/IndexDataManager.h @@ -19,7 +19,10 @@ namespace { - enum { INITIAL_INDEX_BUFFER_SIZE = 4096 * sizeof(GLuint) }; +enum +{ + INITIAL_INDEX_BUFFER_SIZE = 4096 * sizeof(GLuint) +}; } namespace gl @@ -39,7 +42,7 @@ class RendererD3D; struct SourceIndexData { BufferD3D *srcBuffer; - const GLvoid *srcIndices; + const void *srcIndices; unsigned int srcCount; GLenum srcIndexType; bool srcIndicesChanged; @@ -47,9 +50,8 @@ struct SourceIndexData struct TranslatedIndexData { - gl::IndexRange indexRange; unsigned int startIndex; - unsigned int startOffset; // In bytes + unsigned int startOffset; // In bytes IndexBuffer *indexBuffer; BufferD3D *storage; @@ -62,18 +64,21 @@ struct TranslatedIndexData class IndexDataManager : angle::NonCopyable { public: - explicit IndexDataManager(BufferFactoryD3D *factory, RendererClass rendererClass); + explicit IndexDataManager(BufferFactoryD3D *factory); virtual ~IndexDataManager(); - gl::Error prepareIndexData(GLenum srcType, + void deinitialize(); + + gl::Error prepareIndexData(const gl::Context *context, + GLenum srcType, + GLenum dstType, GLsizei count, gl::Buffer *glBuffer, - const GLvoid *indices, - TranslatedIndexData *translated, - bool primitiveRestartFixedIndexEnabled); + const void *indices, + TranslatedIndexData *translated); private: - gl::Error streamIndexData(const GLvoid *data, + gl::Error streamIndexData(const void *data, unsigned int count, GLenum srcType, GLenum dstType, @@ -82,12 +87,19 @@ class IndexDataManager : angle::NonCopyable gl::Error getStreamingIndexBuffer(GLenum destinationIndexType, IndexBufferInterface **outBuffer); + using StreamingBuffer = std::unique_ptr; + BufferFactoryD3D *const mFactory; - RendererClass mRendererClass; - StreamingIndexBufferInterface *mStreamingBufferShort; - StreamingIndexBufferInterface *mStreamingBufferInt; + std::unique_ptr mStreamingBufferShort; + std::unique_ptr mStreamingBufferInt; }; -} +GLenum GetIndexTranslationDestType(GLenum srcType, + const gl::HasIndexRange &lazyIndexRange, + bool usePrimitiveRestartWorkaround); -#endif // LIBANGLE_INDEXDATAMANAGER_H_ +bool IsOffsetAligned(GLenum elementType, unsigned int offset); + +} // namespace rx + +#endif // LIBANGLE_INDEXDATAMANAGER_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/NativeWindowD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/NativeWindowD3D.cpp new file mode 100644 index 0000000000..113bad647c --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/NativeWindowD3D.cpp @@ -0,0 +1,23 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// NativeWindowD3D.cpp: Defines NativeWindowD3D, a class for managing and performing operations on +// an EGLNativeWindowType for the D3D renderers. + +#include "libANGLE/renderer/d3d/NativeWindowD3D.h" + +namespace rx +{ + +NativeWindowD3D::NativeWindowD3D(EGLNativeWindowType window) : mWindow(window) +{ +} + +NativeWindowD3D::~NativeWindowD3D() +{ +} + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/NativeWindowD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/NativeWindowD3D.h new file mode 100644 index 0000000000..365448488d --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/NativeWindowD3D.h @@ -0,0 +1,38 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// NativeWindowD3D.h: Defines NativeWindowD3D, a class for managing and performing operations on an +// EGLNativeWindowType for the D3D renderers. + +#ifndef LIBANGLE_RENDERER_D3D_NATIVEWINDOWD3D_H_ +#define LIBANGLE_RENDERER_D3D_NATIVEWINDOWD3D_H_ + +#include "common/debug.h" +#include "common/platform.h" + +#include +#include "libANGLE/Config.h" + +namespace rx +{ +class NativeWindowD3D : angle::NonCopyable +{ + public: + NativeWindowD3D(EGLNativeWindowType window); + virtual ~NativeWindowD3D(); + + virtual bool initialize() = 0; + virtual bool getClientRect(LPRECT rect) const = 0; + virtual bool isIconic() const = 0; + + inline EGLNativeWindowType getNativeWindow() const { return mWindow; } + + private: + EGLNativeWindowType mWindow; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_NATIVEWINDOWD3D_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ProgramD3D.cpp index 72c6f1a1a9..afc318d9fa 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/ProgramD3D.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ProgramD3D.cpp @@ -8,31 +8,41 @@ #include "libANGLE/renderer/d3d/ProgramD3D.h" -#include "common/BitSetIterator.h" +#include "common/bitset_utils.h" +#include "common/string_utils.h" #include "common/utilities.h" +#include "libANGLE/Context.h" #include "libANGLE/Framebuffer.h" #include "libANGLE/FramebufferAttachment.h" #include "libANGLE/Program.h" +#include "libANGLE/ProgramLinkedResources.h" +#include "libANGLE/Uniform.h" #include "libANGLE/VertexArray.h" #include "libANGLE/features.h" +#include "libANGLE/queryconversions.h" +#include "libANGLE/renderer/ContextImpl.h" #include "libANGLE/renderer/d3d/DynamicHLSL.h" #include "libANGLE/renderer/d3d/FramebufferD3D.h" #include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/ShaderD3D.h" #include "libANGLE/renderer/d3d/ShaderExecutableD3D.h" -#include "libANGLE/renderer/d3d/VaryingPacking.h" #include "libANGLE/renderer/d3d/VertexDataManager.h" +using namespace angle; + namespace rx { namespace { -gl::InputLayout GetDefaultInputLayoutFromShader(const gl::Shader *vertexShader) +void GetDefaultInputLayoutFromShader(const gl::Context *context, + gl::Shader *vertexShader, + gl::InputLayout *inputLayoutOut) { - gl::InputLayout defaultLayout; - for (const sh::Attribute &shaderAttr : vertexShader->getActiveAttributes()) + inputLayoutOut->clear(); + + for (const sh::Attribute &shaderAttr : vertexShader->getActiveAttributes(context)) { if (shaderAttr.type != GL_NONE) { @@ -47,255 +57,83 @@ gl::InputLayout GetDefaultInputLayoutFromShader(const gl::Shader *vertexShader) gl::VertexFormatType defaultType = gl::GetVertexFormatType(componentType, GL_FALSE, components, pureInt); - defaultLayout.push_back(defaultType); + inputLayoutOut->push_back(defaultType); } } } - - return defaultLayout; } -std::vector GetDefaultOutputLayoutFromShader( - const std::vector &shaderOutputVars) +void GetDefaultOutputLayoutFromShader( + const std::vector &shaderOutputVars, + std::vector *outputLayoutOut) { - std::vector defaultPixelOutput; + outputLayoutOut->clear(); if (!shaderOutputVars.empty()) { - defaultPixelOutput.push_back(GL_COLOR_ATTACHMENT0 + - static_cast(shaderOutputVars[0].outputIndex)); - } - - return defaultPixelOutput; -} - -bool IsRowMajorLayout(const sh::InterfaceBlockField &var) -{ - return var.isRowMajorLayout; -} - -bool IsRowMajorLayout(const sh::ShaderVariable &var) -{ - return false; -} - -struct AttributeSorter -{ - AttributeSorter(const ProgramD3D::SemanticIndexArray &semanticIndices) - : originalIndices(&semanticIndices) - { - } - - bool operator()(int a, int b) - { - int indexA = (*originalIndices)[a]; - int indexB = (*originalIndices)[b]; - - if (indexA == -1) - return false; - if (indexB == -1) - return true; - return (indexA < indexB); - } - - const ProgramD3D::SemanticIndexArray *originalIndices; -}; - -// true if varying x has a higher priority in packing than y -bool ComparePackedVarying(const PackedVarying &x, const PackedVarying &y) -{ - return gl::CompareShaderVar(*x.varying, *y.varying); -} - -std::vector MergeVaryings(const gl::Shader &vertexShader, - const gl::Shader &fragmentShader, - const std::vector &tfVaryings) -{ - std::vector packedVaryings; - - for (const sh::Varying &output : vertexShader.getVaryings()) - { - bool packed = false; - - // Built-in varyings obey special rules - if (output.isBuiltIn()) - { - continue; - } - - for (const sh::Varying &input : fragmentShader.getVaryings()) - { - if (output.name == input.name) - { - if (output.isStruct()) - { - ASSERT(!output.isArray()); - for (const auto &field : output.fields) - { - ASSERT(!field.isStruct() && !field.isArray()); - packedVaryings.push_back( - PackedVarying(field, input.interpolation, input.name)); - } - } - else - { - packedVaryings.push_back(PackedVarying(input, input.interpolation)); - } - packed = true; - break; - } - } - - // Keep Transform FB varyings in the merged list always. - if (!packed) - { - for (const std::string &tfVarying : tfVaryings) - { - if (tfVarying == output.name) - { - // Transform feedback for varying structs is underspecified. - // See Khronos bug 9856. - // TODO(jmadill): Figure out how to be spec-compliant here. - if (!output.isStruct()) - { - packedVaryings.push_back(PackedVarying(output, output.interpolation)); - packedVaryings.back().vertexOnly = true; - } - break; - } - } - } - } - - std::sort(packedVaryings.begin(), packedVaryings.end(), ComparePackedVarying); - - return packedVaryings; -} - -template -void GetUniformBlockInfo(const std::vector &fields, - const std::string &prefix, - sh::BlockLayoutEncoder *encoder, - bool inRowMajorLayout, - std::map *blockInfoOut) -{ - for (const VarT &field : fields) - { - const std::string &fieldName = (prefix.empty() ? field.name : prefix + "." + field.name); - - if (field.isStruct()) - { - bool rowMajorLayout = (inRowMajorLayout || IsRowMajorLayout(field)); - - for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++) - { - encoder->enterAggregateType(); - - const std::string uniformElementName = - fieldName + (field.isArray() ? ArrayString(arrayElement) : ""); - GetUniformBlockInfo(field.fields, uniformElementName, encoder, rowMajorLayout, - blockInfoOut); - - encoder->exitAggregateType(); - } - } - else - { - bool isRowMajorMatrix = (gl::IsMatrixType(field.type) && inRowMajorLayout); - (*blockInfoOut)[fieldName] = - encoder->encodeType(field.type, field.arraySize, isRowMajorMatrix); - } + outputLayoutOut->push_back(GL_COLOR_ATTACHMENT0 + + static_cast(shaderOutputVars[0].outputIndex)); } } -template -static inline void SetIfDirty(T *dest, const T &source, bool *dirtyFlag) +template +bool TransposeExpandMatrix(T *target, const GLfloat *value) { - ASSERT(dest != NULL); - ASSERT(dirtyFlag != NULL); + constexpr int targetWidth = 4; + constexpr int targetHeight = rows; + constexpr int srcWidth = rows; + constexpr int srcHeight = cols; - *dirtyFlag = *dirtyFlag || (memcmp(dest, &source, sizeof(T)) != 0); - *dest = source; -} + constexpr int copyWidth = std::min(targetHeight, srcWidth); + constexpr int copyHeight = std::min(targetWidth, srcHeight); -template -bool TransposeMatrix(T *target, - const GLfloat *value, - int targetWidth, - int targetHeight, - int srcWidth, - int srcHeight) -{ - bool dirty = false; - int copyWidth = std::min(targetHeight, srcWidth); - int copyHeight = std::min(targetWidth, srcHeight); + T staging[targetWidth * targetHeight] = {0}; for (int x = 0; x < copyWidth; x++) { for (int y = 0; y < copyHeight; y++) { - SetIfDirty(target + (x * targetWidth + y), static_cast(value[y * srcWidth + x]), - &dirty); - } - } - // clear unfilled right side - for (int y = 0; y < copyWidth; y++) - { - for (int x = copyHeight; x < targetWidth; x++) - { - SetIfDirty(target + (y * targetWidth + x), static_cast(0), &dirty); - } - } - // clear unfilled bottom. - for (int y = copyWidth; y < targetHeight; y++) - { - for (int x = 0; x < targetWidth; x++) - { - SetIfDirty(target + (y * targetWidth + x), static_cast(0), &dirty); + staging[x * targetWidth + y] = static_cast(value[y * srcWidth + x]); } } - return dirty; + if (memcmp(target, staging, targetWidth * targetHeight * sizeof(T)) == 0) + { + return false; + } + + memcpy(target, staging, targetWidth * targetHeight * sizeof(T)); + return true; } -template -bool ExpandMatrix(T *target, - const GLfloat *value, - int targetWidth, - int targetHeight, - int srcWidth, - int srcHeight) +template +bool ExpandMatrix(T *target, const GLfloat *value) { - bool dirty = false; - int copyWidth = std::min(targetWidth, srcWidth); - int copyHeight = std::min(targetHeight, srcHeight); + constexpr int targetWidth = 4; + constexpr int targetHeight = rows; + constexpr int srcWidth = cols; + constexpr int srcHeight = rows; + + constexpr int copyWidth = std::min(targetWidth, srcWidth); + constexpr int copyHeight = std::min(targetHeight, srcHeight); + + T staging[targetWidth * targetHeight] = {0}; for (int y = 0; y < copyHeight; y++) { for (int x = 0; x < copyWidth; x++) { - SetIfDirty(target + (y * targetWidth + x), static_cast(value[y * srcWidth + x]), - &dirty); - } - } - // clear unfilled right side - for (int y = 0; y < copyHeight; y++) - { - for (int x = copyWidth; x < targetWidth; x++) - { - SetIfDirty(target + (y * targetWidth + x), static_cast(0), &dirty); - } - } - // clear unfilled bottom. - for (int y = copyHeight; y < targetHeight; y++) - { - for (int x = 0; x < targetWidth; x++) - { - SetIfDirty(target + (y * targetWidth + x), static_cast(0), &dirty); + staging[y * targetWidth + x] = static_cast(value[y * srcWidth + x]); } } - return dirty; + if (memcmp(target, staging, targetWidth * targetHeight * sizeof(T)) == 0) + { + return false; + } + + memcpy(target, staging, targetWidth * targetHeight * sizeof(T)); + return true; } gl::PrimitiveType GetGeometryShaderTypeFromDrawMode(GLenum drawMode) @@ -327,21 +165,148 @@ gl::PrimitiveType GetGeometryShaderTypeFromDrawMode(GLenum drawMode) } } +bool FindFlatInterpolationVarying(const std::vector &varyings) +{ + // Note: this assumes nested structs can only be packed with one interpolation. + for (const auto &varying : varyings) + { + if (varying.interpolation == sh::INTERPOLATION_FLAT) + { + return true; + } + } + + return false; +} + +// Helper method to de-tranpose a matrix uniform for an API query. +void GetMatrixUniform(GLint columns, GLint rows, GLfloat *dataOut, const GLfloat *source) +{ + for (GLint col = 0; col < columns; ++col) + { + for (GLint row = 0; row < rows; ++row) + { + GLfloat *outptr = dataOut + ((col * rows) + row); + const GLfloat *inptr = source + ((row * 4) + col); + *outptr = *inptr; + } + } +} + +template +void GetMatrixUniform(GLint columns, GLint rows, NonFloatT *dataOut, const NonFloatT *source) +{ + UNREACHABLE(); +} + +class UniformBlockInfo final : angle::NonCopyable +{ + public: + UniformBlockInfo() {} + + void getShaderBlockInfo(const gl::Context *context, gl::Shader *shader); + + bool getBlockSize(const std::string &name, const std::string &mappedName, size_t *sizeOut); + bool getBlockMemberInfo(const std::string &name, + const std::string &mappedName, + sh::BlockMemberInfo *infoOut); + + private: + size_t getBlockInfo(const sh::InterfaceBlock &interfaceBlock); + + std::map mBlockSizes; + sh::BlockLayoutMap mBlockLayout; +}; + +void UniformBlockInfo::getShaderBlockInfo(const gl::Context *context, gl::Shader *shader) +{ + for (const sh::InterfaceBlock &interfaceBlock : shader->getUniformBlocks(context)) + { + if (!interfaceBlock.staticUse && interfaceBlock.layout == sh::BLOCKLAYOUT_PACKED) + continue; + + if (mBlockSizes.count(interfaceBlock.name) > 0) + continue; + + size_t dataSize = getBlockInfo(interfaceBlock); + mBlockSizes[interfaceBlock.name] = dataSize; + } +} + +size_t UniformBlockInfo::getBlockInfo(const sh::InterfaceBlock &interfaceBlock) +{ + ASSERT(interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED); + + // define member uniforms + sh::Std140BlockEncoder std140Encoder; + sh::HLSLBlockEncoder hlslEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED, false); + sh::BlockLayoutEncoder *encoder = nullptr; + + if (interfaceBlock.layout == sh::BLOCKLAYOUT_STD140) + { + encoder = &std140Encoder; + } + else + { + encoder = &hlslEncoder; + } + + sh::GetUniformBlockInfo(interfaceBlock.fields, interfaceBlock.fieldPrefix(), encoder, + interfaceBlock.isRowMajorLayout, &mBlockLayout); + + return encoder->getBlockSize(); +} + +bool UniformBlockInfo::getBlockSize(const std::string &name, + const std::string &mappedName, + size_t *sizeOut) +{ + size_t nameLengthWithoutArrayIndex; + gl::ParseArrayIndex(name, &nameLengthWithoutArrayIndex); + std::string baseName = name.substr(0u, nameLengthWithoutArrayIndex); + auto sizeIter = mBlockSizes.find(baseName); + if (sizeIter == mBlockSizes.end()) + { + *sizeOut = 0; + return false; + } + + *sizeOut = sizeIter->second; + return true; +}; + +bool UniformBlockInfo::getBlockMemberInfo(const std::string &name, + const std::string &mappedName, + sh::BlockMemberInfo *infoOut) +{ + auto infoIter = mBlockLayout.find(name); + if (infoIter == mBlockLayout.end()) + { + *infoOut = sh::BlockMemberInfo::getDefaultBlockInfo(); + return false; + } + + *infoOut = infoIter->second; + return true; +}; + } // anonymous namespace // D3DUniform Implementation -D3DUniform::D3DUniform(GLenum typeIn, +D3DUniform::D3DUniform(GLenum type, const std::string &nameIn, - unsigned int arraySizeIn, + const std::vector &arraySizesIn, bool defaultBlock) - : type(typeIn), + : typeInfo(gl::GetUniformTypeInfo(type)), name(nameIn), - arraySize(arraySizeIn), - data(nullptr), - dirty(true), + arraySizes(arraySizesIn), + vsData(nullptr), + psData(nullptr), + csData(nullptr), vsRegisterIndex(GL_INVALID_INDEX), psRegisterIndex(GL_INVALID_INDEX), + csRegisterIndex(GL_INVALID_INDEX), registerCount(0), registerElement(0) { @@ -350,23 +315,36 @@ D3DUniform::D3DUniform(GLenum typeIn, // Uniform blocks/buffers are treated separately by the Renderer (ES3 path only) if (defaultBlock) { - size_t bytes = gl::VariableInternalSize(type) * elementCount(); - data = new uint8_t[bytes]; - memset(data, 0, bytes); - - // TODO(jmadill): is this correct with non-square matrices? - registerCount = gl::VariableRowCount(type) * elementCount(); + // Use the row count as register count, will work for non-square matrices. + registerCount = typeInfo.rowCount * getArraySizeProduct(); } } D3DUniform::~D3DUniform() { - SafeDeleteArray(data); +} + +unsigned int D3DUniform::getArraySizeProduct() const +{ + return gl::ArraySizeProduct(arraySizes); +} + +const uint8_t *D3DUniform::getDataPtrToElement(size_t elementIndex) const +{ + ASSERT((!isArray() && elementIndex == 0) || + (isArray() && elementIndex < getArraySizeProduct())); + + if (isSampler()) + { + return reinterpret_cast(&mSamplerData[elementIndex]); + } + + return firstNonNullData() + (elementIndex > 0 ? (typeInfo.internalSize * elementIndex) : 0u); } bool D3DUniform::isSampler() const { - return gl::IsSamplerType(type); + return typeInfo.isSampler; } bool D3DUniform::isReferencedByVertexShader() const @@ -379,6 +357,23 @@ bool D3DUniform::isReferencedByFragmentShader() const return psRegisterIndex != GL_INVALID_INDEX; } +bool D3DUniform::isReferencedByComputeShader() const +{ + return csRegisterIndex != GL_INVALID_INDEX; +} + +const uint8_t *D3DUniform::firstNonNullData() const +{ + ASSERT(vsData || psData || csData || !mSamplerData.empty()); + + if (!mSamplerData.empty()) + { + return reinterpret_cast(mSamplerData.data()); + } + + return vsData ? vsData : (psData ? psData : csData); +} + // D3DVarying Implementation D3DVarying::D3DVarying() : semanticIndex(0), componentCount(0), outputSlot(0) @@ -398,16 +393,17 @@ D3DVarying::D3DVarying(const std::string &semanticNameIn, // ProgramD3DMetadata Implementation -ProgramD3DMetadata::ProgramD3DMetadata(int rendererMajorShaderModel, - const std::string &shaderModelSuffix, - bool usesInstancedPointSpriteEmulation, - bool usesViewScale, +ProgramD3DMetadata::ProgramD3DMetadata(RendererD3D *renderer, const ShaderD3D *vertexShader, const ShaderD3D *fragmentShader) - : mRendererMajorShaderModel(rendererMajorShaderModel), - mShaderModelSuffix(shaderModelSuffix), - mUsesInstancedPointSpriteEmulation(usesInstancedPointSpriteEmulation), - mUsesViewScale(usesViewScale), + : mRendererMajorShaderModel(renderer->getMajorShaderModel()), + mShaderModelSuffix(renderer->getShaderModelSuffix()), + mUsesInstancedPointSpriteEmulation( + renderer->getWorkarounds().useInstancedPointSpriteEmulation), + mUsesViewScale(renderer->presentPathFastEnabled()), + mHasANGLEMultiviewEnabled(vertexShader->hasANGLEMultiviewEnabled()), + mUsesViewID(fragmentShader->usesViewID()), + mCanSelectViewInVertexShader(renderer->canSelectViewInVertexShader()), mVertexShader(vertexShader), mFragmentShader(fragmentShader) { @@ -418,12 +414,13 @@ int ProgramD3DMetadata::getRendererMajorShaderModel() const return mRendererMajorShaderModel; } -bool ProgramD3DMetadata::usesBroadcast(const gl::Data &data) const +bool ProgramD3DMetadata::usesBroadcast(const gl::ContextState &data) const { - return (mFragmentShader->usesFragColor() && data.clientVersion < 3); + return (mFragmentShader->usesFragColor() && mFragmentShader->usesMultipleRenderTargets() && + data.getClientMajorVersion() < 3); } -bool ProgramD3DMetadata::usesFragDepth(const gl::Program::Data &programData) const +bool ProgramD3DMetadata::usesFragDepth() const { return mFragmentShader->usesFragDepth(); } @@ -445,7 +442,8 @@ bool ProgramD3DMetadata::usesPointSize() const bool ProgramD3DMetadata::usesInsertedPointCoordValue() const { - return !usesPointSize() && usesPointCoord() && mRendererMajorShaderModel >= 4; + return (!usesPointSize() || !mUsesInstancedPointSpriteEmulation) && usesPointCoord() && + mRendererMajorShaderModel >= 4; } bool ProgramD3DMetadata::usesViewScale() const @@ -453,15 +451,29 @@ bool ProgramD3DMetadata::usesViewScale() const return mUsesViewScale; } +bool ProgramD3DMetadata::hasANGLEMultiviewEnabled() const +{ + return mHasANGLEMultiviewEnabled; +} + +bool ProgramD3DMetadata::usesViewID() const +{ + return mUsesViewID; +} + +bool ProgramD3DMetadata::canSelectViewInVertexShader() const +{ + return mCanSelectViewInVertexShader; +} + bool ProgramD3DMetadata::addsPointCoordToVertexShader() const { - // Instanced PointSprite emulation requires that gl_PointCoord is present in the vertex shader + // PointSprite emulation requiress that gl_PointCoord is present in the vertex shader // VS_OUTPUT structure to ensure compatibility with the generated PS_INPUT of the pixel shader. - // GeometryShader PointSprite emulation does not require this additional entry because the - // GS_OUTPUT of the Geometry shader contains the pointCoord value and already matches the - // PS_INPUT of the generated pixel shader. The Geometry Shader point sprite implementation needs - // gl_PointSize to be in VS_OUTPUT and GS_INPUT. Instanced point sprites doesn't need - // gl_PointSize in VS_OUTPUT. + // Even with a geometry shader, the app can render triangles or lines and reference + // gl_PointCoord in the fragment shader, requiring us to provide a dummy value. For + // simplicity, we always add this to the vertex shader when the fragment shader + // references gl_PointCoord, even if we could skip it in the geometry shader. return (mUsesInstancedPointSpriteEmulation && usesPointCoord()) || usesInsertedPointCoordValue(); } @@ -508,25 +520,45 @@ ProgramD3D::VertexExecutable::~VertexExecutable() SafeDelete(mShaderExecutable); } +// static +ProgramD3D::VertexExecutable::HLSLAttribType ProgramD3D::VertexExecutable::GetAttribType( + GLenum type) +{ + switch (type) + { + case GL_INT: + return HLSLAttribType::SIGNED_INT; + case GL_UNSIGNED_INT: + return HLSLAttribType::UNSIGNED_INT; + case GL_SIGNED_NORMALIZED: + case GL_UNSIGNED_NORMALIZED: + case GL_FLOAT: + return HLSLAttribType::FLOAT; + default: + UNREACHABLE(); + return HLSLAttribType::FLOAT; + } +} + // static void ProgramD3D::VertexExecutable::getSignature(RendererD3D *renderer, const gl::InputLayout &inputLayout, Signature *signatureOut) { - signatureOut->resize(inputLayout.size()); + signatureOut->assign(inputLayout.size(), HLSLAttribType::FLOAT); for (size_t index = 0; index < inputLayout.size(); ++index) { gl::VertexFormatType vertexFormatType = inputLayout[index]; - bool converted = false; - if (vertexFormatType != gl::VERTEX_FORMAT_INVALID) - { - VertexConversionType conversionType = - renderer->getVertexConversionType(vertexFormatType); - converted = ((conversionType & VERTEX_CONVERT_GPU) != 0); - } + if (vertexFormatType == gl::VERTEX_FORMAT_INVALID) + continue; - (*signatureOut)[index] = converted; + VertexConversionType conversionType = renderer->getVertexConversionType(vertexFormatType); + if ((conversionType & VERTEX_CONVERT_GPU) == 0) + continue; + + GLenum componentType = renderer->getVertexComponentType(vertexFormatType); + (*signatureOut)[index] = GetAttribType(componentType); } } @@ -535,9 +567,9 @@ bool ProgramD3D::VertexExecutable::matchesSignature(const Signature &signature) size_t limit = std::max(mSignature.size(), signature.size()); for (size_t index = 0; index < limit; ++index) { - // treat undefined indexes as 'not converted' - bool a = index < signature.size() ? signature[index] : false; - bool b = index < mSignature.size() ? mSignature[index] : false; + // treat undefined indexes as FLOAT + auto a = index < signature.size() ? signature[index] : HLSLAttribType::FLOAT; + auto b = index < mSignature.size() ? mSignature[index] : HLSLAttribType::FLOAT; if (a != b) return false; } @@ -562,19 +594,25 @@ ProgramD3D::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureTy unsigned int ProgramD3D::mCurrentSerial = 1; -ProgramD3D::ProgramD3D(const gl::Program::Data &data, RendererD3D *renderer) - : ProgramImpl(data), +ProgramD3D::ProgramD3D(const gl::ProgramState &state, RendererD3D *renderer) + : ProgramImpl(state), mRenderer(renderer), - mDynamicHLSL(NULL), - mGeometryExecutables(gl::PRIMITIVE_TYPE_MAX, nullptr), + mDynamicHLSL(nullptr), + mGeometryExecutables(gl::PRIMITIVE_TYPE_MAX), + mComputeExecutable(nullptr), mUsesPointSize(false), mUsesFlatInterpolation(false), - mVertexUniformStorage(NULL), - mFragmentUniformStorage(NULL), + mVertexUniformStorage(nullptr), + mFragmentUniformStorage(nullptr), + mComputeUniformStorage(nullptr), mUsedVertexSamplerRange(0), mUsedPixelSamplerRange(0), + mUsedComputeSamplerRange(0), mDirtySamplerMapping(true), - mSerial(issueSerial()) + mSerial(issueSerial()), + mVertexUniformsDirty(true), + mFragmentUniformsDirty(true), + mComputeUniformsDirty(true) { mDynamicHLSL = new DynamicHLSL(renderer); } @@ -590,14 +628,22 @@ bool ProgramD3D::usesPointSpriteEmulation() const return mUsesPointSize && mRenderer->getMajorShaderModel() >= 4; } +bool ProgramD3D::usesGeometryShaderForPointSpriteEmulation() const +{ + return usesPointSpriteEmulation() && !usesInstancedPointSpriteEmulation(); +} + bool ProgramD3D::usesGeometryShader(GLenum drawMode) const { + if (mHasANGLEMultiviewEnabled && !mRenderer->canSelectViewInVertexShader()) + { + return true; + } if (drawMode != GL_POINTS) { return mUsesFlatInterpolation; } - - return usesPointSpriteEmulation() && !usesInstancedPointSpriteEmulation(); + return usesGeometryShaderForPointSpriteEmulation(); } bool ProgramD3D::usesInstancedPointSpriteEmulation() const @@ -627,6 +673,13 @@ GLint ProgramD3D::getSamplerMapping(gl::SamplerType type, logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit; } break; + case gl::SAMPLER_COMPUTE: + ASSERT(samplerIndex < caps.maxComputeTextureImageUnits); + if (samplerIndex < mSamplersCS.size() && mSamplersCS[samplerIndex].active) + { + logicalTextureUnit = mSamplersCS[samplerIndex].logicalTextureUnit; + } + break; default: UNREACHABLE(); } @@ -654,6 +707,10 @@ GLenum ProgramD3D::getSamplerTextureType(gl::SamplerType type, unsigned int samp ASSERT(samplerIndex < mSamplersVS.size()); ASSERT(mSamplersVS[samplerIndex].active); return mSamplersVS[samplerIndex].textureType; + case gl::SAMPLER_COMPUTE: + ASSERT(samplerIndex < mSamplersCS.size()); + ASSERT(mSamplersCS[samplerIndex].active); + return mSamplersCS[samplerIndex].textureType; default: UNREACHABLE(); } @@ -661,7 +718,7 @@ GLenum ProgramD3D::getSamplerTextureType(gl::SamplerType type, unsigned int samp return GL_TEXTURE_2D; } -GLint ProgramD3D::getUsedSamplerRange(gl::SamplerType type) const +GLuint ProgramD3D::getUsedSamplerRange(gl::SamplerType type) const { switch (type) { @@ -669,17 +726,19 @@ GLint ProgramD3D::getUsedSamplerRange(gl::SamplerType type) const return mUsedPixelSamplerRange; case gl::SAMPLER_VERTEX: return mUsedVertexSamplerRange; + case gl::SAMPLER_COMPUTE: + return mUsedComputeSamplerRange; default: UNREACHABLE(); - return 0; + return 0u; } } -void ProgramD3D::updateSamplerMapping() +ProgramD3D::SamplerMapping ProgramD3D::updateSamplerMapping() { if (!mDirtySamplerMapping) { - return; + return SamplerMapping::WasClean; } mDirtySamplerMapping = false; @@ -687,14 +746,10 @@ void ProgramD3D::updateSamplerMapping() // Retrieve sampler uniform values for (const D3DUniform *d3dUniform : mD3DUniforms) { - if (!d3dUniform->dirty) - continue; - if (!d3dUniform->isSampler()) continue; - int count = d3dUniform->elementCount(); - const GLint(*v)[4] = reinterpret_cast(d3dUniform->data); + int count = d3dUniform->getArraySizeProduct(); if (d3dUniform->isReferencedByFragmentShader()) { @@ -707,7 +762,7 @@ void ProgramD3D::updateSamplerMapping() if (samplerIndex < mSamplersPS.size()) { ASSERT(mSamplersPS[samplerIndex].active); - mSamplersPS[samplerIndex].logicalTextureUnit = v[i][0]; + mSamplersPS[samplerIndex].logicalTextureUnit = d3dUniform->mSamplerData[i]; } } } @@ -723,15 +778,37 @@ void ProgramD3D::updateSamplerMapping() if (samplerIndex < mSamplersVS.size()) { ASSERT(mSamplersVS[samplerIndex].active); - mSamplersVS[samplerIndex].logicalTextureUnit = v[i][0]; + mSamplersVS[samplerIndex].logicalTextureUnit = d3dUniform->mSamplerData[i]; + } + } + } + + if (d3dUniform->isReferencedByComputeShader()) + { + unsigned int firstIndex = d3dUniform->csRegisterIndex; + + for (int i = 0; i < count; i++) + { + unsigned int samplerIndex = firstIndex + i; + + if (samplerIndex < mSamplersCS.size()) + { + ASSERT(mSamplersCS[samplerIndex].active); + mSamplersCS[samplerIndex].logicalTextureUnit = d3dUniform->mSamplerData[i]; } } } } + + return SamplerMapping::WasDirty; } -LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) +gl::LinkResult ProgramD3D::load(const gl::Context *context, + gl::InfoLog &infoLog, + gl::BinaryInputStream *stream) { + // TODO(jmadill): Use Renderer from contextImpl. + reset(); DeviceIdentifier binaryDeviceIdentifier = {0}; @@ -742,20 +819,19 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) if (memcmp(&identifier, &binaryDeviceIdentifier, sizeof(DeviceIdentifier)) != 0) { infoLog << "Invalid program binary, device configuration has changed."; - return LinkResult(false, gl::Error(GL_NO_ERROR)); + return false; } int compileFlags = stream->readInt(); if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL) { infoLog << "Mismatched compilation flags."; - return LinkResult(false, gl::Error(GL_NO_ERROR)); + return false; } - // TODO(jmadill): replace MAX_VERTEX_ATTRIBS - for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; ++i) + for (int &index : mAttribLocationToD3DSemantic) { - stream->readInt(&mSemanticIndexes[i]); + stream->readInt(&index); } const unsigned int psSamplerCount = stream->readInt(); @@ -777,27 +853,39 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) mSamplersVS.push_back(sampler); } + const unsigned int csSamplerCount = stream->readInt(); + for (unsigned int i = 0; i < csSamplerCount; ++i) + { + Sampler sampler; + stream->readBool(&sampler.active); + stream->readInt(&sampler.logicalTextureUnit); + stream->readInt(&sampler.textureType); + mSamplersCS.push_back(sampler); + } + stream->readInt(&mUsedVertexSamplerRange); stream->readInt(&mUsedPixelSamplerRange); + stream->readInt(&mUsedComputeSamplerRange); const unsigned int uniformCount = stream->readInt(); if (stream->error()) { infoLog << "Invalid program binary."; - return LinkResult(false, gl::Error(GL_NO_ERROR)); + return false; } - const auto &linkedUniforms = mData.getUniforms(); + const auto &linkedUniforms = mState.getUniforms(); ASSERT(mD3DUniforms.empty()); for (unsigned int uniformIndex = 0; uniformIndex < uniformCount; uniformIndex++) { const gl::LinkedUniform &linkedUniform = linkedUniforms[uniformIndex]; D3DUniform *d3dUniform = - new D3DUniform(linkedUniform.type, linkedUniform.name, linkedUniform.arraySize, + new D3DUniform(linkedUniform.type, linkedUniform.name, linkedUniform.arraySizes, linkedUniform.isInDefaultBlock()); stream->readInt(&d3dUniform->psRegisterIndex); stream->readInt(&d3dUniform->vsRegisterIndex); + stream->readInt(&d3dUniform->csRegisterIndex); stream->readInt(&d3dUniform->registerCount); stream->readInt(&d3dUniform->registerElement); @@ -808,7 +896,7 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) if (stream->error()) { infoLog << "Invalid program binary."; - return LinkResult(false, gl::Error(GL_NO_ERROR)); + return false; } ASSERT(mD3DUniformBlocks.empty()); @@ -817,6 +905,7 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) D3DUniformBlock uniformBlock; stream->readInt(&uniformBlock.psRegisterIndex); stream->readInt(&uniformBlock.vsRegisterIndex); + stream->readInt(&uniformBlock.csRegisterIndex); mD3DUniformBlocks.push_back(uniformBlock); } @@ -834,11 +923,13 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) stream->readString(&mVertexHLSL); stream->readBytes(reinterpret_cast(&mVertexWorkarounds), - sizeof(D3DCompilerWorkarounds)); + sizeof(angle::CompilerWorkaroundsD3D)); stream->readString(&mPixelHLSL); stream->readBytes(reinterpret_cast(&mPixelWorkarounds), - sizeof(D3DCompilerWorkarounds)); + sizeof(angle::CompilerWorkaroundsD3D)); stream->readBool(&mUsesFragDepth); + stream->readBool(&mHasANGLEMultiviewEnabled); + stream->readBool(&mUsesViewID); stream->readBool(&mUsesPointSize); stream->readBool(&mUsesFlatInterpolation); @@ -857,6 +948,8 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) const unsigned char *binary = reinterpret_cast(stream->data()); + bool separateAttribs = (mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS); + const unsigned int vertexShaderCount = stream->readInt(); for (unsigned int vertexShaderIndex = 0; vertexShaderIndex < vertexShaderCount; vertexShaderIndex++) @@ -874,18 +967,14 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) ShaderExecutableD3D *shaderExecutable = nullptr; - gl::Error error = mRenderer->loadExecutable( - vertexShaderFunction, vertexShaderSize, SHADER_VERTEX, mStreamOutVaryings, - (mData.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), &shaderExecutable); - if (error.isError()) - { - return LinkResult(false, error); - } + ANGLE_TRY(mRenderer->loadExecutable(vertexShaderFunction, vertexShaderSize, + gl::SHADER_VERTEX, mStreamOutVaryings, separateAttribs, + &shaderExecutable)); if (!shaderExecutable) { infoLog << "Could not create vertex shader."; - return LinkResult(false, gl::Error(GL_NO_ERROR)); + return false; } // generated converted input layout @@ -893,8 +982,8 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) VertexExecutable::getSignature(mRenderer, inputLayout, &signature); // add new binary - mVertexExecutables.push_back( - new VertexExecutable(inputLayout, signature, shaderExecutable)); + mVertexExecutables.push_back(std::unique_ptr( + new VertexExecutable(inputLayout, signature, shaderExecutable))); stream->skip(vertexShaderSize); } @@ -913,22 +1002,19 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) const unsigned char *pixelShaderFunction = binary + stream->offset(); ShaderExecutableD3D *shaderExecutable = nullptr; - gl::Error error = mRenderer->loadExecutable( - pixelShaderFunction, pixelShaderSize, SHADER_PIXEL, mStreamOutVaryings, - (mData.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), &shaderExecutable); - if (error.isError()) - { - return LinkResult(false, error); - } + ANGLE_TRY(mRenderer->loadExecutable(pixelShaderFunction, pixelShaderSize, + gl::SHADER_FRAGMENT, mStreamOutVaryings, + separateAttribs, &shaderExecutable)); if (!shaderExecutable) { infoLog << "Could not create pixel shader."; - return LinkResult(false, gl::Error(GL_NO_ERROR)); + return false; } // add new binary - mPixelExecutables.push_back(new PixelExecutable(outputs, shaderExecutable)); + mPixelExecutables.push_back( + std::unique_ptr(new PixelExecutable(outputs, shaderExecutable))); stream->skip(pixelShaderSize); } @@ -939,36 +1025,52 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) unsigned int geometryShaderSize = stream->readInt(); if (geometryShaderSize == 0) { - mGeometryExecutables[geometryExeIndex] = nullptr; continue; } const unsigned char *geometryShaderFunction = binary + stream->offset(); - bool splitAttribs = (mData.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS); - gl::Error error = mRenderer->loadExecutable( - geometryShaderFunction, geometryShaderSize, SHADER_GEOMETRY, mStreamOutVaryings, - splitAttribs, &mGeometryExecutables[geometryExeIndex]); - if (error.isError()) - { - return LinkResult(false, error); - } + ShaderExecutableD3D *geometryExecutable = nullptr; + ANGLE_TRY(mRenderer->loadExecutable(geometryShaderFunction, geometryShaderSize, + gl::SHADER_GEOMETRY, mStreamOutVaryings, + separateAttribs, &geometryExecutable)); - if (!mGeometryExecutables[geometryExeIndex]) + if (!geometryExecutable) { infoLog << "Could not create geometry shader."; - return LinkResult(false, gl::Error(GL_NO_ERROR)); + return false; } + + mGeometryExecutables[geometryExeIndex].reset(geometryExecutable); + stream->skip(geometryShaderSize); } - initializeUniformStorage(); - initAttributesByLayout(); + unsigned int computeShaderSize = stream->readInt(); + if (computeShaderSize > 0) + { + const unsigned char *computeShaderFunction = binary + stream->offset(); - return LinkResult(true, gl::Error(GL_NO_ERROR)); + ShaderExecutableD3D *computeExecutable = nullptr; + ANGLE_TRY(mRenderer->loadExecutable(computeShaderFunction, computeShaderSize, + gl::SHADER_COMPUTE, std::vector(), false, + &computeExecutable)); + + if (!computeExecutable) + { + infoLog << "Could not create compute shader."; + return false; + } + + mComputeExecutable.reset(computeExecutable); + } + + initializeUniformStorage(); + + return true; } -gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream) +void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream) { // Output the DeviceIdentifier before we output any shader code // When we load the binary again later, we can validate the device identifier before trying to @@ -979,10 +1081,9 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream) stream->writeInt(ANGLE_COMPILE_OPTIMIZATION_LEVEL); - // TODO(jmadill): replace MAX_VERTEX_ATTRIBS - for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; ++i) + for (int d3dSemantic : mAttribLocationToD3DSemantic) { - stream->writeInt(mSemanticIndexes[i]); + stream->writeInt(d3dSemantic); } stream->writeInt(mSamplersPS.size()); @@ -1001,15 +1102,25 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream) stream->writeInt(mSamplersVS[i].textureType); } + stream->writeInt(mSamplersCS.size()); + for (unsigned int i = 0; i < mSamplersCS.size(); ++i) + { + stream->writeInt(mSamplersCS[i].active); + stream->writeInt(mSamplersCS[i].logicalTextureUnit); + stream->writeInt(mSamplersCS[i].textureType); + } + stream->writeInt(mUsedVertexSamplerRange); stream->writeInt(mUsedPixelSamplerRange); + stream->writeInt(mUsedComputeSamplerRange); stream->writeInt(mD3DUniforms.size()); for (const D3DUniform *uniform : mD3DUniforms) { // Type, name and arraySize are redundant, so aren't stored in the binary. - stream->writeInt(uniform->psRegisterIndex); - stream->writeInt(uniform->vsRegisterIndex); + stream->writeIntOrNegOne(uniform->psRegisterIndex); + stream->writeIntOrNegOne(uniform->vsRegisterIndex); + stream->writeIntOrNegOne(uniform->csRegisterIndex); stream->writeInt(uniform->registerCount); stream->writeInt(uniform->registerElement); } @@ -1017,8 +1128,9 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream) stream->writeInt(mD3DUniformBlocks.size()); for (const D3DUniformBlock &uniformBlock : mD3DUniformBlocks) { - stream->writeInt(uniformBlock.psRegisterIndex); - stream->writeInt(uniformBlock.vsRegisterIndex); + stream->writeIntOrNegOne(uniformBlock.psRegisterIndex); + stream->writeIntOrNegOne(uniformBlock.vsRegisterIndex); + stream->writeIntOrNegOne(uniformBlock.csRegisterIndex); } stream->writeInt(mStreamOutVaryings.size()); @@ -1032,11 +1144,13 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream) stream->writeString(mVertexHLSL); stream->writeBytes(reinterpret_cast(&mVertexWorkarounds), - sizeof(D3DCompilerWorkarounds)); + sizeof(angle::CompilerWorkaroundsD3D)); stream->writeString(mPixelHLSL); stream->writeBytes(reinterpret_cast(&mPixelWorkarounds), - sizeof(D3DCompilerWorkarounds)); + sizeof(angle::CompilerWorkaroundsD3D)); stream->writeInt(mUsesFragDepth); + stream->writeInt(mHasANGLEMultiviewEnabled); + stream->writeInt(mUsesViewID); stream->writeInt(mUsesPointSize); stream->writeInt(mUsesFlatInterpolation); @@ -1058,14 +1172,14 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream) for (size_t vertexExecutableIndex = 0; vertexExecutableIndex < mVertexExecutables.size(); vertexExecutableIndex++) { - VertexExecutable *vertexExecutable = mVertexExecutables[vertexExecutableIndex]; + VertexExecutable *vertexExecutable = mVertexExecutables[vertexExecutableIndex].get(); const auto &inputLayout = vertexExecutable->inputs(); stream->writeInt(inputLayout.size()); for (size_t inputIndex = 0; inputIndex < inputLayout.size(); inputIndex++) { - stream->writeInt(inputLayout[inputIndex]); + stream->writeInt(static_cast(inputLayout[inputIndex])); } size_t vertexShaderSize = vertexExecutable->shaderExecutable()->getLength(); @@ -1079,7 +1193,7 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream) for (size_t pixelExecutableIndex = 0; pixelExecutableIndex < mPixelExecutables.size(); pixelExecutableIndex++) { - PixelExecutable *pixelExecutable = mPixelExecutables[pixelExecutableIndex]; + PixelExecutable *pixelExecutable = mPixelExecutables[pixelExecutableIndex].get(); const std::vector outputs = pixelExecutable->outputSignature(); stream->writeInt(outputs.size()); @@ -1095,150 +1209,120 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream) stream->writeBytes(pixelBlob, pixelShaderSize); } - for (const ShaderExecutableD3D *geometryExe : mGeometryExecutables) + for (auto const &geometryExecutable : mGeometryExecutables) { - if (geometryExe == nullptr) + if (!geometryExecutable) { stream->writeInt(0); continue; } - size_t geometryShaderSize = geometryExe->getLength(); + size_t geometryShaderSize = geometryExecutable->getLength(); stream->writeInt(geometryShaderSize); - stream->writeBytes(geometryExe->getFunction(), geometryShaderSize); + stream->writeBytes(geometryExecutable->getFunction(), geometryShaderSize); } - return gl::Error(GL_NO_ERROR); + if (mComputeExecutable) + { + size_t computeShaderSize = mComputeExecutable->getLength(); + stream->writeInt(computeShaderSize); + stream->writeBytes(mComputeExecutable->getFunction(), computeShaderSize); + } + else + { + stream->writeInt(0); + } } void ProgramD3D::setBinaryRetrievableHint(bool /* retrievable */) { } -gl::Error ProgramD3D::getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo, - ShaderExecutableD3D **outExecutable) +void ProgramD3D::setSeparable(bool /* separable */) { - mPixelShaderOutputFormatCache.clear(); - - const FramebufferD3D *fboD3D = GetImplAs(fbo); - const gl::AttachmentList &colorbuffers = fboD3D->getColorAttachmentsForRender(); - - for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment) - { - const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment]; - - if (colorbuffer) - { - mPixelShaderOutputFormatCache.push_back(colorbuffer->getBinding() == GL_BACK - ? GL_COLOR_ATTACHMENT0 - : colorbuffer->getBinding()); - } - else - { - mPixelShaderOutputFormatCache.push_back(GL_NONE); - } - } - - return getPixelExecutableForOutputLayout(mPixelShaderOutputFormatCache, outExecutable, nullptr); } -gl::Error ProgramD3D::getPixelExecutableForOutputLayout(const std::vector &outputSignature, - ShaderExecutableD3D **outExectuable, - gl::InfoLog *infoLog) +gl::Error ProgramD3D::getPixelExecutableForCachedOutputLayout(ShaderExecutableD3D **outExecutable, + gl::InfoLog *infoLog) { - for (size_t executableIndex = 0; executableIndex < mPixelExecutables.size(); executableIndex++) + if (mCachedPixelExecutableIndex.valid()) { - if (mPixelExecutables[executableIndex]->matchesSignature(outputSignature)) - { - *outExectuable = mPixelExecutables[executableIndex]->shaderExecutable(); - return gl::Error(GL_NO_ERROR); - } + *outExecutable = mPixelExecutables[mCachedPixelExecutableIndex.value()]->shaderExecutable(); + return gl::NoError(); } std::string finalPixelHLSL = mDynamicHLSL->generatePixelShaderForOutputSignature( - mPixelHLSL, mPixelShaderKey, mUsesFragDepth, outputSignature); + mPixelHLSL, mPixelShaderKey, mUsesFragDepth, mPixelShaderOutputLayoutCache); // Generate new pixel executable - ShaderExecutableD3D *pixelExecutable = NULL; + ShaderExecutableD3D *pixelExecutable = nullptr; gl::InfoLog tempInfoLog; gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog; - gl::Error error = mRenderer->compileToExecutable( - *currentInfoLog, finalPixelHLSL, SHADER_PIXEL, mStreamOutVaryings, - (mData.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), mPixelWorkarounds, - &pixelExecutable); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mRenderer->compileToExecutable( + *currentInfoLog, finalPixelHLSL, gl::SHADER_FRAGMENT, mStreamOutVaryings, + (mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), mPixelWorkarounds, + &pixelExecutable)); if (pixelExecutable) { - mPixelExecutables.push_back(new PixelExecutable(outputSignature, pixelExecutable)); + mPixelExecutables.push_back(std::unique_ptr( + new PixelExecutable(mPixelShaderOutputLayoutCache, pixelExecutable))); + mCachedPixelExecutableIndex = mPixelExecutables.size() - 1; } else if (!infoLog) { - std::vector tempCharBuffer(tempInfoLog.getLength() + 3); - tempInfoLog.getLog(static_cast(tempInfoLog.getLength()), NULL, &tempCharBuffer[0]); - ERR("Error compiling dynamic pixel executable:\n%s\n", &tempCharBuffer[0]); + ERR() << "Error compiling dynamic pixel executable:" << std::endl + << tempInfoLog.str() << std::endl; } - *outExectuable = pixelExecutable; - return gl::Error(GL_NO_ERROR); + *outExecutable = pixelExecutable; + return gl::NoError(); } -gl::Error ProgramD3D::getVertexExecutableForInputLayout(const gl::InputLayout &inputLayout, - ShaderExecutableD3D **outExectuable, - gl::InfoLog *infoLog) +gl::Error ProgramD3D::getVertexExecutableForCachedInputLayout(ShaderExecutableD3D **outExectuable, + gl::InfoLog *infoLog) { - VertexExecutable::getSignature(mRenderer, inputLayout, &mCachedVertexSignature); - - for (size_t executableIndex = 0; executableIndex < mVertexExecutables.size(); executableIndex++) + if (mCachedVertexExecutableIndex.valid()) { - if (mVertexExecutables[executableIndex]->matchesSignature(mCachedVertexSignature)) - { - *outExectuable = mVertexExecutables[executableIndex]->shaderExecutable(); - return gl::Error(GL_NO_ERROR); - } + *outExectuable = + mVertexExecutables[mCachedVertexExecutableIndex.value()]->shaderExecutable(); + return gl::NoError(); } // Generate new dynamic layout with attribute conversions std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout( - mVertexHLSL, inputLayout, mData.getAttributes()); + mVertexHLSL, mCachedInputLayout, mState.getAttributes()); // Generate new vertex executable - ShaderExecutableD3D *vertexExecutable = NULL; + ShaderExecutableD3D *vertexExecutable = nullptr; gl::InfoLog tempInfoLog; gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog; - gl::Error error = mRenderer->compileToExecutable( - *currentInfoLog, finalVertexHLSL, SHADER_VERTEX, mStreamOutVaryings, - (mData.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), mVertexWorkarounds, - &vertexExecutable); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mRenderer->compileToExecutable( + *currentInfoLog, finalVertexHLSL, gl::SHADER_VERTEX, mStreamOutVaryings, + (mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), mVertexWorkarounds, + &vertexExecutable)); if (vertexExecutable) { - mVertexExecutables.push_back( - new VertexExecutable(inputLayout, mCachedVertexSignature, vertexExecutable)); + mVertexExecutables.push_back(std::unique_ptr( + new VertexExecutable(mCachedInputLayout, mCachedVertexSignature, vertexExecutable))); + mCachedVertexExecutableIndex = mVertexExecutables.size() - 1; } else if (!infoLog) { - std::vector tempCharBuffer(tempInfoLog.getLength() + 3); - tempInfoLog.getLog(static_cast(tempInfoLog.getLength()), NULL, &tempCharBuffer[0]); - ERR("Error compiling dynamic vertex executable:\n%s\n", &tempCharBuffer[0]); + ERR() << "Error compiling dynamic vertex executable:" << std::endl + << tempInfoLog.str() << std::endl; } *outExectuable = vertexExecutable; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error ProgramD3D::getGeometryExecutableForPrimitiveType(const gl::Data &data, +gl::Error ProgramD3D::getGeometryExecutableForPrimitiveType(const gl::Context *context, GLenum drawMode, ShaderExecutableD3D **outExecutable, gl::InfoLog *infoLog) @@ -1251,75 +1335,188 @@ gl::Error ProgramD3D::getGeometryExecutableForPrimitiveType(const gl::Data &data // Return a null shader if the current rendering doesn't use a geometry shader if (!usesGeometryShader(drawMode)) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::PrimitiveType geometryShaderType = GetGeometryShaderTypeFromDrawMode(drawMode); - if (mGeometryExecutables[geometryShaderType] != nullptr) + if (mGeometryExecutables[geometryShaderType]) { if (outExecutable) { - *outExecutable = mGeometryExecutables[geometryShaderType]; + *outExecutable = mGeometryExecutables[geometryShaderType].get(); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL( - geometryShaderType, data, mData, mRenderer->presentPathFastEnabled(), - mGeometryShaderPreamble); + context, geometryShaderType, mState, mRenderer->presentPathFastEnabled(), + mHasANGLEMultiviewEnabled, mRenderer->canSelectViewInVertexShader(), + usesGeometryShaderForPointSpriteEmulation(), mGeometryShaderPreamble); gl::InfoLog tempInfoLog; gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog; - gl::Error error = mRenderer->compileToExecutable( - *currentInfoLog, geometryHLSL, SHADER_GEOMETRY, mStreamOutVaryings, - (mData.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), D3DCompilerWorkarounds(), - &mGeometryExecutables[geometryShaderType]); + ShaderExecutableD3D *geometryExecutable = nullptr; + gl::Error error = mRenderer->compileToExecutable( + *currentInfoLog, geometryHLSL, gl::SHADER_GEOMETRY, mStreamOutVaryings, + (mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), + angle::CompilerWorkaroundsD3D(), &geometryExecutable); if (!infoLog && error.isError()) { - std::vector tempCharBuffer(tempInfoLog.getLength() + 3); - tempInfoLog.getLog(static_cast(tempInfoLog.getLength()), NULL, &tempCharBuffer[0]); - ERR("Error compiling dynamic geometry executable:\n%s\n", &tempCharBuffer[0]); + ERR() << "Error compiling dynamic geometry executable:" << std::endl + << tempInfoLog.str() << std::endl; + } + + if (geometryExecutable != nullptr) + { + mGeometryExecutables[geometryShaderType].reset(geometryExecutable); } if (outExecutable) { - *outExecutable = mGeometryExecutables[geometryShaderType]; + *outExecutable = mGeometryExecutables[geometryShaderType].get(); } return error; } -LinkResult ProgramD3D::compileProgramExecutables(const gl::Data &data, gl::InfoLog &infoLog) +class ProgramD3D::GetExecutableTask : public Closure { - const gl::InputLayout &defaultInputLayout = - GetDefaultInputLayoutFromShader(mData.getAttachedVertexShader()); - ShaderExecutableD3D *defaultVertexExecutable = NULL; - gl::Error error = - getVertexExecutableForInputLayout(defaultInputLayout, &defaultVertexExecutable, &infoLog); - if (error.isError()) + public: + GetExecutableTask(ProgramD3D *program) + : mProgram(program), mError(gl::NoError()), mInfoLog(), mResult(nullptr) { - return LinkResult(false, error); } - std::vector defaultPixelOutput = GetDefaultOutputLayoutFromShader(getPixelShaderKey()); - ShaderExecutableD3D *defaultPixelExecutable = NULL; - error = - getPixelExecutableForOutputLayout(defaultPixelOutput, &defaultPixelExecutable, &infoLog); - if (error.isError()) + virtual gl::Error run() = 0; + + void operator()() override { mError = run(); } + + const gl::Error &getError() const { return mError; } + const gl::InfoLog &getInfoLog() const { return mInfoLog; } + ShaderExecutableD3D *getResult() { return mResult; } + + protected: + ProgramD3D *mProgram; + gl::Error mError; + gl::InfoLog mInfoLog; + ShaderExecutableD3D *mResult; +}; + +class ProgramD3D::GetVertexExecutableTask : public ProgramD3D::GetExecutableTask +{ + public: + GetVertexExecutableTask(ProgramD3D *program, const gl::Context *context) + : GetExecutableTask(program), mContext(context) { - return LinkResult(false, error); + } + gl::Error run() override + { + mProgram->updateCachedInputLayoutFromShader(mContext); + + ANGLE_TRY(mProgram->getVertexExecutableForCachedInputLayout(&mResult, &mInfoLog)); + + return gl::NoError(); } - // Auto-generate the geometry shader here, if we expect to be using point rendering in D3D11. - ShaderExecutableD3D *pointGS = nullptr; - if (usesGeometryShader(GL_POINTS)) + private: + const gl::Context *mContext; +}; + +void ProgramD3D::updateCachedInputLayoutFromShader(const gl::Context *context) +{ + GetDefaultInputLayoutFromShader(context, mState.getAttachedVertexShader(), &mCachedInputLayout); + VertexExecutable::getSignature(mRenderer, mCachedInputLayout, &mCachedVertexSignature); + updateCachedVertexExecutableIndex(); +} + +class ProgramD3D::GetPixelExecutableTask : public ProgramD3D::GetExecutableTask +{ + public: + GetPixelExecutableTask(ProgramD3D *program) : GetExecutableTask(program) {} + gl::Error run() override + { + mProgram->updateCachedOutputLayoutFromShader(); + + ANGLE_TRY(mProgram->getPixelExecutableForCachedOutputLayout(&mResult, &mInfoLog)); + + return gl::NoError(); + } +}; + +void ProgramD3D::updateCachedOutputLayoutFromShader() +{ + GetDefaultOutputLayoutFromShader(mPixelShaderKey, &mPixelShaderOutputLayoutCache); + updateCachedPixelExecutableIndex(); +} + +class ProgramD3D::GetGeometryExecutableTask : public ProgramD3D::GetExecutableTask +{ + public: + GetGeometryExecutableTask(ProgramD3D *program, const gl::Context *context) + : GetExecutableTask(program), mContext(context) { - getGeometryExecutableForPrimitiveType(data, GL_POINTS, &pointGS, &infoLog); } - const ShaderD3D *vertexShaderD3D = GetImplAs(mData.getAttachedVertexShader()); + gl::Error run() override + { + // Auto-generate the geometry shader here, if we expect to be using point rendering in + // D3D11. + if (mProgram->usesGeometryShader(GL_POINTS)) + { + ANGLE_TRY(mProgram->getGeometryExecutableForPrimitiveType(mContext, GL_POINTS, &mResult, + &mInfoLog)); + } + + return gl::NoError(); + } + + private: + const gl::Context *mContext; +}; + +gl::Error ProgramD3D::getComputeExecutable(ShaderExecutableD3D **outExecutable) +{ + if (outExecutable) + { + *outExecutable = mComputeExecutable.get(); + } + + return gl::NoError(); +} + +gl::LinkResult ProgramD3D::compileProgramExecutables(const gl::Context *context, + gl::InfoLog &infoLog) +{ + // Ensure the compiler is initialized to avoid race conditions. + ANGLE_TRY(mRenderer->ensureHLSLCompilerInitialized()); + + WorkerThreadPool *workerPool = mRenderer->getWorkerThreadPool(); + + GetVertexExecutableTask vertexTask(this, context); + GetPixelExecutableTask pixelTask(this); + GetGeometryExecutableTask geometryTask(this, context); + + std::array waitEvents = {{workerPool->postWorkerTask(&vertexTask), + workerPool->postWorkerTask(&pixelTask), + workerPool->postWorkerTask(&geometryTask)}}; + + WaitableEvent::WaitMany(&waitEvents); + + infoLog << vertexTask.getInfoLog().str(); + infoLog << pixelTask.getInfoLog().str(); + infoLog << geometryTask.getInfoLog().str(); + + ANGLE_TRY(vertexTask.getError()); + ANGLE_TRY(pixelTask.getError()); + ANGLE_TRY(geometryTask.getError()); + + ShaderExecutableD3D *defaultVertexExecutable = vertexTask.getResult(); + ShaderExecutableD3D *defaultPixelExecutable = pixelTask.getResult(); + ShaderExecutableD3D *pointGS = geometryTask.getResult(); + + const ShaderD3D *vertexShaderD3D = GetImplAs(mState.getAttachedVertexShader()); if (usesGeometryShader(GL_POINTS) && pointGS) { @@ -1339,128 +1536,148 @@ LinkResult ProgramD3D::compileProgramExecutables(const gl::Data &data, gl::InfoL if (defaultPixelExecutable) { const ShaderD3D *fragmentShaderD3D = - GetImplAs(mData.getAttachedFragmentShader()); + GetImplAs(mState.getAttachedFragmentShader()); fragmentShaderD3D->appendDebugInfo(defaultPixelExecutable->getDebugInfo()); } - bool linkSuccess = (defaultVertexExecutable && defaultPixelExecutable && - (!usesGeometryShader(GL_POINTS) || pointGS)); - return LinkResult(linkSuccess, gl::Error(GL_NO_ERROR)); + return (defaultVertexExecutable && defaultPixelExecutable && + (!usesGeometryShader(GL_POINTS) || pointGS)); } -LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog) +gl::LinkResult ProgramD3D::compileComputeExecutable(const gl::Context *context, + gl::InfoLog &infoLog) { + // Ensure the compiler is initialized to avoid race conditions. + ANGLE_TRY(mRenderer->ensureHLSLCompilerInitialized()); + + std::string computeShader = mDynamicHLSL->generateComputeShaderLinkHLSL(context, mState); + + ShaderExecutableD3D *computeExecutable = nullptr; + ANGLE_TRY(mRenderer->compileToExecutable(infoLog, computeShader, gl::SHADER_COMPUTE, + std::vector(), false, + angle::CompilerWorkaroundsD3D(), &computeExecutable)); + + if (computeExecutable == nullptr) + { + ERR() << "Error compiling dynamic compute executable:" << std::endl + << infoLog.str() << std::endl; + } + else + { + const ShaderD3D *computeShaderD3D = GetImplAs(mState.getAttachedComputeShader()); + computeShaderD3D->appendDebugInfo(computeExecutable->getDebugInfo()); + mComputeExecutable.reset(computeExecutable); + } + + return mComputeExecutable.get() != nullptr; +} + +gl::LinkResult ProgramD3D::link(const gl::Context *context, + const gl::ProgramLinkedResources &resources, + gl::InfoLog &infoLog) +{ + const auto &data = context->getContextState(); + reset(); - // TODO(jmadill): structures containing samplers - for (const gl::LinkedUniform &linkedUniform : mData.getUniforms()) + gl::Shader *computeShader = mState.getAttachedComputeShader(); + if (computeShader) { - if (linkedUniform.isSampler() && linkedUniform.isField()) + mSamplersCS.resize(data.getCaps().maxComputeTextureImageUnits); + + defineUniformsAndAssignRegisters(context); + + gl::LinkResult result = compileComputeExecutable(context, infoLog); + if (result.isError()) { - infoLog << "Structures containing samplers not currently supported in D3D."; - return LinkResult(false, gl::Error(GL_NO_ERROR)); + infoLog << result.getError().getMessage(); + return result; + } + else if (!result.getResult()) + { + infoLog << "Failed to create D3D compute shader."; + return result; + } + } + else + { + gl::Shader *vertexShader = mState.getAttachedVertexShader(); + gl::Shader *fragmentShader = mState.getAttachedFragmentShader(); + + const ShaderD3D *vertexShaderD3D = GetImplAs(vertexShader); + const ShaderD3D *fragmentShaderD3D = GetImplAs(fragmentShader); + + mSamplersVS.resize(data.getCaps().maxVertexTextureImageUnits); + mSamplersPS.resize(data.getCaps().maxTextureImageUnits); + + vertexShaderD3D->generateWorkarounds(&mVertexWorkarounds); + fragmentShaderD3D->generateWorkarounds(&mPixelWorkarounds); + + if (mRenderer->getNativeLimitations().noFrontFacingSupport) + { + if (fragmentShaderD3D->usesFrontFacing()) + { + infoLog << "The current renderer doesn't support gl_FrontFacing"; + return false; + } + } + + // TODO(jmadill): Implement more sophisticated component packing in D3D9. + // We can fail here because we use one semantic per GLSL varying. D3D11 can pack varyings + // intelligently, but D3D9 assumes one semantic per register. + if (mRenderer->getRendererClass() == RENDERER_D3D9 && + resources.varyingPacking.getMaxSemanticIndex() > data.getCaps().maxVaryingVectors) + { + infoLog << "Cannot pack these varyings on D3D9."; + return false; + } + + ProgramD3DMetadata metadata(mRenderer, vertexShaderD3D, fragmentShaderD3D); + BuiltinVaryingsD3D builtins(metadata, resources.varyingPacking); + + mDynamicHLSL->generateShaderLinkHLSL(context, mState, metadata, resources.varyingPacking, + builtins, &mPixelHLSL, &mVertexHLSL); + + mUsesPointSize = vertexShaderD3D->usesPointSize(); + mDynamicHLSL->getPixelShaderOutputKey(data, mState, metadata, &mPixelShaderKey); + mUsesFragDepth = metadata.usesFragDepth(); + mUsesViewID = metadata.usesViewID(); + mHasANGLEMultiviewEnabled = metadata.hasANGLEMultiviewEnabled(); + + // Cache if we use flat shading + mUsesFlatInterpolation = + (FindFlatInterpolationVarying(fragmentShader->getInputVaryings(context)) || + FindFlatInterpolationVarying(vertexShader->getOutputVaryings(context))); + + if (mRenderer->getMajorShaderModel() >= 4) + { + mGeometryShaderPreamble = mDynamicHLSL->generateGeometryShaderPreamble( + resources.varyingPacking, builtins, mHasANGLEMultiviewEnabled, + metadata.canSelectViewInVertexShader()); + } + + initAttribLocationsToD3DSemantic(context); + + defineUniformsAndAssignRegisters(context); + + gatherTransformFeedbackVaryings(resources.varyingPacking, builtins[gl::SHADER_VERTEX]); + + gl::LinkResult result = compileProgramExecutables(context, infoLog); + if (result.isError()) + { + infoLog << result.getError().getMessage(); + return result; + } + else if (!result.getResult()) + { + infoLog << "Failed to create D3D shaders."; + return result; } } - const gl::Shader *vertexShader = mData.getAttachedVertexShader(); - const gl::Shader *fragmentShader = mData.getAttachedFragmentShader(); + linkResources(context, resources); - const ShaderD3D *vertexShaderD3D = GetImplAs(vertexShader); - const ShaderD3D *fragmentShaderD3D = GetImplAs(fragmentShader); - - mSamplersVS.resize(data.caps->maxVertexTextureImageUnits); - mSamplersPS.resize(data.caps->maxTextureImageUnits); - - vertexShaderD3D->generateWorkarounds(&mVertexWorkarounds); - fragmentShaderD3D->generateWorkarounds(&mPixelWorkarounds); - - if (mRenderer->getRendererLimitations().noFrontFacingSupport) - { - if (fragmentShaderD3D->usesFrontFacing()) - { - infoLog << "The current renderer doesn't support gl_FrontFacing"; - return LinkResult(false, gl::Error(GL_NO_ERROR)); - } - } - - std::vector packedVaryings = - MergeVaryings(*vertexShader, *fragmentShader, mData.getTransformFeedbackVaryingNames()); - - // Map the varyings to the register file - VaryingPacking varyingPacking(data.caps->maxVaryingVectors); - if (!varyingPacking.packVaryings(infoLog, packedVaryings, - mData.getTransformFeedbackVaryingNames())) - { - return LinkResult(false, gl::Error(GL_NO_ERROR)); - } - - ProgramD3DMetadata metadata(mRenderer->getMajorShaderModel(), mRenderer->getShaderModelSuffix(), - usesInstancedPointSpriteEmulation(), - mRenderer->presentPathFastEnabled(), vertexShaderD3D, - fragmentShaderD3D); - - varyingPacking.enableBuiltins(SHADER_VERTEX, metadata); - varyingPacking.enableBuiltins(SHADER_PIXEL, metadata); - - if (static_cast(varyingPacking.getRegisterCount()) > data.caps->maxVaryingVectors) - { - infoLog << "No varying registers left to support gl_FragCoord/gl_PointCoord"; - return LinkResult(false, gl::Error(GL_NO_ERROR)); - } - - // TODO(jmadill): Implement more sophisticated component packing in D3D9. - // We can fail here because we use one semantic per GLSL varying. D3D11 can pack varyings - // intelligently, but D3D9 assumes one semantic per register. - if (mRenderer->getRendererClass() == RENDERER_D3D9 && - varyingPacking.getMaxSemanticIndex() > data.caps->maxVaryingVectors) - { - infoLog << "Cannot pack these varyings on D3D9."; - return LinkResult(false, gl::Error(GL_NO_ERROR)); - } - - if (!mDynamicHLSL->generateShaderLinkHLSL(data, mData, metadata, varyingPacking, &mPixelHLSL, - &mVertexHLSL)) - { - return LinkResult(false, gl::Error(GL_NO_ERROR)); - } - - mUsesPointSize = vertexShaderD3D->usesPointSize(); - mDynamicHLSL->getPixelShaderOutputKey(data, mData, metadata, &mPixelShaderKey); - mUsesFragDepth = metadata.usesFragDepth(mData); - - // Cache if we use flat shading - mUsesFlatInterpolation = false; - for (const auto &varying : packedVaryings) - { - if (varying.interpolation == sh::INTERPOLATION_FLAT) - { - mUsesFlatInterpolation = true; - break; - } - } - - if (mRenderer->getMajorShaderModel() >= 4) - { - varyingPacking.enableBuiltins(SHADER_GEOMETRY, metadata); - mGeometryShaderPreamble = mDynamicHLSL->generateGeometryShaderPreamble(varyingPacking); - } - - initSemanticIndex(); - - defineUniformsAndAssignRegisters(); - - gatherTransformFeedbackVaryings(varyingPacking); - - LinkResult result = compileProgramExecutables(data, infoLog); - if (result.error.isError() || !result.linkSuccess) - { - infoLog << "Failed to create D3D shaders."; - return result; - } - - initUniformBlockInfo(); - - return LinkResult(true, gl::Error(GL_NO_ERROR)); + return true; } GLboolean ProgramD3D::validate(const gl::Caps & /*caps*/, gl::InfoLog * /*infoLog*/) @@ -1469,46 +1686,22 @@ GLboolean ProgramD3D::validate(const gl::Caps & /*caps*/, gl::InfoLog * /*infoLo return GL_TRUE; } -void ProgramD3D::initUniformBlockInfo() +void ProgramD3D::initializeUniformBlocks() { - const gl::Shader *vertexShader = mData.getAttachedVertexShader(); - - for (const sh::InterfaceBlock &vertexBlock : vertexShader->getInterfaceBlocks()) + if (mState.getUniformBlocks().empty()) { - if (!vertexBlock.staticUse && vertexBlock.layout == sh::BLOCKLAYOUT_PACKED) - continue; - - if (mBlockDataSizes.count(vertexBlock.name) > 0) - continue; - - size_t dataSize = getUniformBlockInfo(vertexBlock); - mBlockDataSizes[vertexBlock.name] = dataSize; + return; } - const gl::Shader *fragmentShader = mData.getAttachedFragmentShader(); - - for (const sh::InterfaceBlock &fragmentBlock : fragmentShader->getInterfaceBlocks()) - { - if (!fragmentBlock.staticUse && fragmentBlock.layout == sh::BLOCKLAYOUT_PACKED) - continue; - - if (mBlockDataSizes.count(fragmentBlock.name) > 0) - continue; - - size_t dataSize = getUniformBlockInfo(fragmentBlock); - mBlockDataSizes[fragmentBlock.name] = dataSize; - } -} - -void ProgramD3D::assignUniformBlockRegisters() -{ - mD3DUniformBlocks.clear(); + ASSERT(mD3DUniformBlocks.empty()); // Assign registers and update sizes. - const ShaderD3D *vertexShaderD3D = GetImplAs(mData.getAttachedVertexShader()); - const ShaderD3D *fragmentShaderD3D = GetImplAs(mData.getAttachedFragmentShader()); + const ShaderD3D *vertexShaderD3D = SafeGetImplAs(mState.getAttachedVertexShader()); + const ShaderD3D *fragmentShaderD3D = + SafeGetImplAs(mState.getAttachedFragmentShader()); + const ShaderD3D *computeShaderD3D = SafeGetImplAs(mState.getAttachedComputeShader()); - for (const gl::UniformBlock &uniformBlock : mData.getUniformBlocks()) + for (const gl::InterfaceBlock &uniformBlock : mState.getUniformBlocks()) { unsigned int uniformBlockElement = uniformBlock.isArray ? uniformBlock.arrayElement : 0; @@ -1516,18 +1709,27 @@ void ProgramD3D::assignUniformBlockRegisters() if (uniformBlock.vertexStaticUse) { - unsigned int baseRegister = - vertexShaderD3D->getInterfaceBlockRegister(uniformBlock.name); + ASSERT(vertexShaderD3D != nullptr); + unsigned int baseRegister = vertexShaderD3D->getUniformBlockRegister(uniformBlock.name); d3dUniformBlock.vsRegisterIndex = baseRegister + uniformBlockElement; } if (uniformBlock.fragmentStaticUse) { + ASSERT(fragmentShaderD3D != nullptr); unsigned int baseRegister = - fragmentShaderD3D->getInterfaceBlockRegister(uniformBlock.name); + fragmentShaderD3D->getUniformBlockRegister(uniformBlock.name); d3dUniformBlock.psRegisterIndex = baseRegister + uniformBlockElement; } + if (uniformBlock.computeStaticUse) + { + ASSERT(computeShaderD3D != nullptr); + unsigned int baseRegister = + computeShaderD3D->getUniformBlockRegister(uniformBlock.name); + d3dUniformBlock.csRegisterIndex = baseRegister + uniformBlockElement; + } + mD3DUniformBlocks.push_back(d3dUniformBlock); } } @@ -1537,6 +1739,7 @@ void ProgramD3D::initializeUniformStorage() // Compute total default block size unsigned int vertexRegisters = 0; unsigned int fragmentRegisters = 0; + unsigned int computeRegisters = 0; for (const D3DUniform *d3dUniform : mD3DUniforms) { if (!d3dUniform->isSampler()) @@ -1551,55 +1754,67 @@ void ProgramD3D::initializeUniformStorage() fragmentRegisters = std::max( fragmentRegisters, d3dUniform->psRegisterIndex + d3dUniform->registerCount); } + if (d3dUniform->isReferencedByComputeShader()) + { + computeRegisters = std::max( + computeRegisters, d3dUniform->csRegisterIndex + d3dUniform->registerCount); + } } } - mVertexUniformStorage = mRenderer->createUniformStorage(vertexRegisters * 16u); - mFragmentUniformStorage = mRenderer->createUniformStorage(fragmentRegisters * 16u); -} - -gl::Error ProgramD3D::applyUniforms(GLenum drawMode) -{ - ASSERT(!mDirtySamplerMapping); - - gl::Error error = mRenderer->applyUniforms(*this, drawMode, mD3DUniforms); - if (error.isError()) - { - return error; - } + mVertexUniformStorage = + std::unique_ptr(mRenderer->createUniformStorage(vertexRegisters * 16u)); + mFragmentUniformStorage = std::unique_ptr( + mRenderer->createUniformStorage(fragmentRegisters * 16u)); + mComputeUniformStorage = + std::unique_ptr(mRenderer->createUniformStorage(computeRegisters * 16u)); + // Iterate the uniforms again to assign data pointers to default block uniforms. for (D3DUniform *d3dUniform : mD3DUniforms) { - d3dUniform->dirty = false; - } + if (d3dUniform->isSampler()) + { + d3dUniform->mSamplerData.resize(d3dUniform->getArraySizeProduct(), 0); + continue; + } - return gl::Error(GL_NO_ERROR); + if (d3dUniform->isReferencedByVertexShader()) + { + d3dUniform->vsData = mVertexUniformStorage->getDataPointer(d3dUniform->vsRegisterIndex, + d3dUniform->registerElement); + } + + if (d3dUniform->isReferencedByFragmentShader()) + { + d3dUniform->psData = mFragmentUniformStorage->getDataPointer( + d3dUniform->psRegisterIndex, d3dUniform->registerElement); + } + + if (d3dUniform->isReferencedByComputeShader()) + { + d3dUniform->csData = mComputeUniformStorage->getDataPointer( + d3dUniform->csRegisterIndex, d3dUniform->registerElement); + } + } } -gl::Error ProgramD3D::applyUniformBuffers(const gl::Data &data) +void ProgramD3D::updateUniformBufferCache(const gl::Caps &caps, + unsigned int reservedVertex, + unsigned int reservedFragment) { - if (mData.getUniformBlocks().empty()) + if (mState.getUniformBlocks().empty()) { - return gl::Error(GL_NO_ERROR); - } - - // Lazy init. - if (mD3DUniformBlocks.empty()) - { - assignUniformBlockRegisters(); + return; } mVertexUBOCache.clear(); mFragmentUBOCache.clear(); - const unsigned int reservedBuffersInVS = mRenderer->getReservedVertexUniformBuffers(); - const unsigned int reservedBuffersInFS = mRenderer->getReservedFragmentUniformBuffers(); - for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mD3DUniformBlocks.size(); uniformBlockIndex++) { const D3DUniformBlock &uniformBlock = mD3DUniformBlocks[uniformBlockIndex]; - GLuint blockBinding = mData.getUniformBlockBinding(uniformBlockIndex); + GLuint blockBinding = mState.getUniformBlockBinding(uniformBlockIndex); // Unnecessary to apply an unreferenced standard or shared UBO if (!uniformBlock.vertexStaticUse() && !uniformBlock.fragmentStaticUse()) @@ -1609,8 +1824,8 @@ gl::Error ProgramD3D::applyUniformBuffers(const gl::Data &data) if (uniformBlock.vertexStaticUse()) { - unsigned int registerIndex = uniformBlock.vsRegisterIndex - reservedBuffersInVS; - ASSERT(registerIndex < data.caps->maxVertexUniformBlocks); + unsigned int registerIndex = uniformBlock.vsRegisterIndex - reservedVertex; + ASSERT(registerIndex < caps.maxVertexUniformBlocks); if (mVertexUBOCache.size() <= registerIndex) { @@ -1623,8 +1838,8 @@ gl::Error ProgramD3D::applyUniformBuffers(const gl::Data &data) if (uniformBlock.fragmentStaticUse()) { - unsigned int registerIndex = uniformBlock.psRegisterIndex - reservedBuffersInFS; - ASSERT(registerIndex < data.caps->maxFragmentUniformBlocks); + unsigned int registerIndex = uniformBlock.psRegisterIndex - reservedFragment; + ASSERT(registerIndex < caps.maxFragmentUniformBlocks); if (mFragmentUBOCache.size() <= registerIndex) { @@ -1635,36 +1850,50 @@ gl::Error ProgramD3D::applyUniformBuffers(const gl::Data &data) mFragmentUBOCache[registerIndex] = blockBinding; } } +} - return mRenderer->setUniformBuffers(data, mVertexUBOCache, mFragmentUBOCache); +const std::vector &ProgramD3D::getVertexUniformBufferCache() const +{ + return mVertexUBOCache; +} + +const std::vector &ProgramD3D::getFragmentUniformBufferCache() const +{ + return mFragmentUBOCache; } void ProgramD3D::dirtyAllUniforms() { - for (D3DUniform *d3dUniform : mD3DUniforms) - { - d3dUniform->dirty = true; - } + mVertexUniformsDirty = true; + mFragmentUniformsDirty = true; + mComputeUniformsDirty = true; +} + +void ProgramD3D::markUniformsClean() +{ + mVertexUniformsDirty = false; + mFragmentUniformsDirty = false; + mComputeUniformsDirty = false; } void ProgramD3D::setUniform1fv(GLint location, GLsizei count, const GLfloat *v) { - setUniform(location, count, v, GL_FLOAT); + setUniformInternal(location, count, v, GL_FLOAT); } void ProgramD3D::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) { - setUniform(location, count, v, GL_FLOAT_VEC2); + setUniformInternal(location, count, v, GL_FLOAT_VEC2); } void ProgramD3D::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) { - setUniform(location, count, v, GL_FLOAT_VEC3); + setUniformInternal(location, count, v, GL_FLOAT_VEC3); } void ProgramD3D::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) { - setUniform(location, count, v, GL_FLOAT_VEC4); + setUniformInternal(location, count, v, GL_FLOAT_VEC4); } void ProgramD3D::setUniformMatrix2fv(GLint location, @@ -1672,7 +1901,7 @@ void ProgramD3D::setUniformMatrix2fv(GLint location, GLboolean transpose, const GLfloat *value) { - setUniformMatrixfv<2, 2>(location, count, transpose, value, GL_FLOAT_MAT2); + setUniformMatrixfvInternal<2, 2>(location, count, transpose, value, GL_FLOAT_MAT2); } void ProgramD3D::setUniformMatrix3fv(GLint location, @@ -1680,7 +1909,7 @@ void ProgramD3D::setUniformMatrix3fv(GLint location, GLboolean transpose, const GLfloat *value) { - setUniformMatrixfv<3, 3>(location, count, transpose, value, GL_FLOAT_MAT3); + setUniformMatrixfvInternal<3, 3>(location, count, transpose, value, GL_FLOAT_MAT3); } void ProgramD3D::setUniformMatrix4fv(GLint location, @@ -1688,7 +1917,7 @@ void ProgramD3D::setUniformMatrix4fv(GLint location, GLboolean transpose, const GLfloat *value) { - setUniformMatrixfv<4, 4>(location, count, transpose, value, GL_FLOAT_MAT4); + setUniformMatrixfvInternal<4, 4>(location, count, transpose, value, GL_FLOAT_MAT4); } void ProgramD3D::setUniformMatrix2x3fv(GLint location, @@ -1696,7 +1925,7 @@ void ProgramD3D::setUniformMatrix2x3fv(GLint location, GLboolean transpose, const GLfloat *value) { - setUniformMatrixfv<2, 3>(location, count, transpose, value, GL_FLOAT_MAT2x3); + setUniformMatrixfvInternal<2, 3>(location, count, transpose, value, GL_FLOAT_MAT2x3); } void ProgramD3D::setUniformMatrix3x2fv(GLint location, @@ -1704,7 +1933,7 @@ void ProgramD3D::setUniformMatrix3x2fv(GLint location, GLboolean transpose, const GLfloat *value) { - setUniformMatrixfv<3, 2>(location, count, transpose, value, GL_FLOAT_MAT3x2); + setUniformMatrixfvInternal<3, 2>(location, count, transpose, value, GL_FLOAT_MAT3x2); } void ProgramD3D::setUniformMatrix2x4fv(GLint location, @@ -1712,7 +1941,7 @@ void ProgramD3D::setUniformMatrix2x4fv(GLint location, GLboolean transpose, const GLfloat *value) { - setUniformMatrixfv<2, 4>(location, count, transpose, value, GL_FLOAT_MAT2x4); + setUniformMatrixfvInternal<2, 4>(location, count, transpose, value, GL_FLOAT_MAT2x4); } void ProgramD3D::setUniformMatrix4x2fv(GLint location, @@ -1720,7 +1949,7 @@ void ProgramD3D::setUniformMatrix4x2fv(GLint location, GLboolean transpose, const GLfloat *value) { - setUniformMatrixfv<4, 2>(location, count, transpose, value, GL_FLOAT_MAT4x2); + setUniformMatrixfvInternal<4, 2>(location, count, transpose, value, GL_FLOAT_MAT4x2); } void ProgramD3D::setUniformMatrix3x4fv(GLint location, @@ -1728,7 +1957,7 @@ void ProgramD3D::setUniformMatrix3x4fv(GLint location, GLboolean transpose, const GLfloat *value) { - setUniformMatrixfv<3, 4>(location, count, transpose, value, GL_FLOAT_MAT3x4); + setUniformMatrixfvInternal<3, 4>(location, count, transpose, value, GL_FLOAT_MAT3x4); } void ProgramD3D::setUniformMatrix4x3fv(GLint location, @@ -1736,47 +1965,47 @@ void ProgramD3D::setUniformMatrix4x3fv(GLint location, GLboolean transpose, const GLfloat *value) { - setUniformMatrixfv<4, 3>(location, count, transpose, value, GL_FLOAT_MAT4x3); + setUniformMatrixfvInternal<4, 3>(location, count, transpose, value, GL_FLOAT_MAT4x3); } void ProgramD3D::setUniform1iv(GLint location, GLsizei count, const GLint *v) { - setUniform(location, count, v, GL_INT); + setUniformInternal(location, count, v, GL_INT); } void ProgramD3D::setUniform2iv(GLint location, GLsizei count, const GLint *v) { - setUniform(location, count, v, GL_INT_VEC2); + setUniformInternal(location, count, v, GL_INT_VEC2); } void ProgramD3D::setUniform3iv(GLint location, GLsizei count, const GLint *v) { - setUniform(location, count, v, GL_INT_VEC3); + setUniformInternal(location, count, v, GL_INT_VEC3); } void ProgramD3D::setUniform4iv(GLint location, GLsizei count, const GLint *v) { - setUniform(location, count, v, GL_INT_VEC4); + setUniformInternal(location, count, v, GL_INT_VEC4); } void ProgramD3D::setUniform1uiv(GLint location, GLsizei count, const GLuint *v) { - setUniform(location, count, v, GL_UNSIGNED_INT); + setUniformInternal(location, count, v, GL_UNSIGNED_INT); } void ProgramD3D::setUniform2uiv(GLint location, GLsizei count, const GLuint *v) { - setUniform(location, count, v, GL_UNSIGNED_INT_VEC2); + setUniformInternal(location, count, v, GL_UNSIGNED_INT_VEC2); } void ProgramD3D::setUniform3uiv(GLint location, GLsizei count, const GLuint *v) { - setUniform(location, count, v, GL_UNSIGNED_INT_VEC3); + setUniformInternal(location, count, v, GL_UNSIGNED_INT_VEC3); } void ProgramD3D::setUniform4uiv(GLint location, GLsizei count, const GLuint *v) { - setUniform(location, count, v, GL_UNSIGNED_INT_VEC4); + setUniformInternal(location, count, v, GL_UNSIGNED_INT_VEC4); } void ProgramD3D::setUniformBlockBinding(GLuint /*uniformBlockIndex*/, @@ -1784,35 +2013,58 @@ void ProgramD3D::setUniformBlockBinding(GLuint /*uniformBlockIndex*/, { } -void ProgramD3D::defineUniformsAndAssignRegisters() +void ProgramD3D::defineUniformsAndAssignRegisters(const gl::Context *context) { D3DUniformMap uniformMap; - const gl::Shader *vertexShader = mData.getAttachedVertexShader(); - for (const sh::Uniform &vertexUniform : vertexShader->getUniforms()) - + gl::Shader *computeShader = mState.getAttachedComputeShader(); + if (computeShader) { - if (vertexUniform.staticUse) + for (const sh::Uniform &computeUniform : computeShader->getUniforms(context)) { - defineUniformBase(vertexShader, vertexUniform, &uniformMap); + if (computeUniform.staticUse) + { + defineUniformBase(computeShader, computeUniform, &uniformMap); + } } } - - const gl::Shader *fragmentShader = mData.getAttachedFragmentShader(); - for (const sh::Uniform &fragmentUniform : fragmentShader->getUniforms()) + else { - if (fragmentUniform.staticUse) + gl::Shader *vertexShader = mState.getAttachedVertexShader(); + for (const sh::Uniform &vertexUniform : vertexShader->getUniforms(context)) { - defineUniformBase(fragmentShader, fragmentUniform, &uniformMap); + if (vertexUniform.staticUse) + { + defineUniformBase(vertexShader, vertexUniform, &uniformMap); + } + } + + gl::Shader *fragmentShader = mState.getAttachedFragmentShader(); + for (const sh::Uniform &fragmentUniform : fragmentShader->getUniforms(context)) + { + if (fragmentUniform.staticUse) + { + defineUniformBase(fragmentShader, fragmentUniform, &uniformMap); + } } } // Initialize the D3DUniform list to mirror the indexing of the GL layer. - for (const gl::LinkedUniform &glUniform : mData.getUniforms()) + for (const gl::LinkedUniform &glUniform : mState.getUniforms()) { if (!glUniform.isInDefaultBlock()) continue; - auto mapEntry = uniformMap.find(glUniform.name); + std::string name = glUniform.name; + if (glUniform.isArray()) + { + // In the program state, array uniform names include [0] as in the program resource + // spec. Here we don't include it. + // TODO(oetuaho@nvidia.com): consider using the same uniform naming here as in the GL + // layer. + ASSERT(angle::EndsWith(name, "[0]")); + name.resize(name.length() - 3); + } + auto mapEntry = uniformMap.find(name); ASSERT(mapEntry != uniformMap.end()); mD3DUniforms.push_back(mapEntry->second); } @@ -1825,7 +2077,8 @@ void ProgramD3D::defineUniformBase(const gl::Shader *shader, const sh::Uniform &uniform, D3DUniformMap *uniformMap) { - if (uniform.isBuiltIn()) + // Samplers get their registers assigned in assignAllSamplerRegisters. + if (uniform.isBuiltIn() || gl::IsSamplerType(uniform.type)) { defineUniform(shader->getType(), uniform, uniform.name, nullptr, uniformMap); return; @@ -1835,7 +2088,7 @@ void ProgramD3D::defineUniformBase(const gl::Shader *shader, unsigned int startRegister = shaderD3D->getUniformRegister(uniform.name); ShShaderOutput outputType = shaderD3D->getCompilerOutputType(); - sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType)); + sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType), true); encoder.skipRegisters(startRegister); defineUniform(shader->getType(), uniform, uniform.name, &encoder, uniformMap); @@ -1854,6 +2107,84 @@ D3DUniform *ProgramD3D::getD3DUniformByName(const std::string &name) return nullptr; } +void ProgramD3D::defineStructUniformFields(GLenum shaderType, + const std::vector &fields, + const std::string &namePrefix, + sh::HLSLBlockEncoder *encoder, + D3DUniformMap *uniformMap) +{ + if (encoder) + encoder->enterAggregateType(); + + for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) + { + const sh::ShaderVariable &field = fields[fieldIndex]; + const std::string &fieldFullName = (namePrefix + "." + field.name); + + // Samplers get their registers assigned in assignAllSamplerRegisters. + // Also they couldn't use the same encoder as the rest of the struct, since they are + // extracted out of the struct by the shader translator. + if (gl::IsSamplerType(field.type)) + { + defineUniform(shaderType, field, fieldFullName, nullptr, uniformMap); + } + else + { + defineUniform(shaderType, field, fieldFullName, encoder, uniformMap); + } + } + + if (encoder) + encoder->exitAggregateType(); +} + +void ProgramD3D::defineArrayOfStructsUniformFields(GLenum shaderType, + const sh::ShaderVariable &uniform, + unsigned int arrayNestingIndex, + const std::string &prefix, + sh::HLSLBlockEncoder *encoder, + D3DUniformMap *uniformMap) +{ + // Nested arrays are processed starting from outermost (arrayNestingIndex 0u) and ending at the + // innermost. + const unsigned int currentArraySize = uniform.getNestedArraySize(arrayNestingIndex); + for (unsigned int arrayElement = 0u; arrayElement < currentArraySize; ++arrayElement) + { + const std::string &elementString = prefix + ArrayString(arrayElement); + if (arrayNestingIndex + 1u < uniform.arraySizes.size()) + { + defineArrayOfStructsUniformFields(shaderType, uniform, arrayNestingIndex + 1u, + elementString, encoder, uniformMap); + } + else + { + defineStructUniformFields(shaderType, uniform.fields, elementString, encoder, + uniformMap); + } + } +} + +void ProgramD3D::defineArrayUniformElements(GLenum shaderType, + const sh::ShaderVariable &uniform, + const std::string &fullName, + sh::HLSLBlockEncoder *encoder, + D3DUniformMap *uniformMap) +{ + if (encoder) + encoder->enterAggregateType(); + + sh::ShaderVariable uniformElement = uniform; + uniformElement.arraySizes.pop_back(); + for (unsigned int arrayIndex = 0u; arrayIndex < uniform.getOutermostArraySize(); ++arrayIndex) + { + std::string elementFullName = fullName + ArrayString(arrayIndex); + defineUniform(shaderType, uniformElement, elementFullName, encoder, uniformMap); + } + + if (encoder) + encoder->exitAggregateType(); +} + void ProgramD3D::defineUniform(GLenum shaderType, const sh::ShaderVariable &uniform, const std::string &fullName, @@ -1862,24 +2193,20 @@ void ProgramD3D::defineUniform(GLenum shaderType, { if (uniform.isStruct()) { - for (unsigned int elementIndex = 0; elementIndex < uniform.elementCount(); elementIndex++) + if (uniform.isArray()) { - const std::string &elementString = (uniform.isArray() ? ArrayString(elementIndex) : ""); - - if (encoder) - encoder->enterAggregateType(); - - for (size_t fieldIndex = 0; fieldIndex < uniform.fields.size(); fieldIndex++) - { - const sh::ShaderVariable &field = uniform.fields[fieldIndex]; - const std::string &fieldFullName = (fullName + elementString + "." + field.name); - - defineUniform(shaderType, field, fieldFullName, encoder, uniformMap); - } - - if (encoder) - encoder->exitAggregateType(); + defineArrayOfStructsUniformFields(shaderType, uniform, 0u, fullName, encoder, + uniformMap); } + else + { + defineStructUniformFields(shaderType, uniform.fields, fullName, encoder, uniformMap); + } + return; + } + if (uniform.isArrayOfArrays()) + { + defineArrayUniformElements(shaderType, uniform, fullName, encoder, uniformMap); return; } @@ -1891,7 +2218,7 @@ void ProgramD3D::defineUniform(GLenum shaderType, // Advance the uniform offset, to track registers allocation for structs sh::BlockMemberInfo blockInfo = - encoder ? encoder->encodeType(uniform.type, uniform.arraySize, false) + encoder ? encoder->encodeType(uniform.type, uniform.arraySizes, false) : sh::BlockMemberInfo::getDefaultBlockInfo(); auto uniformMapEntry = uniformMap->find(fullName); @@ -1903,7 +2230,7 @@ void ProgramD3D::defineUniform(GLenum shaderType, } else { - d3dUniform = new D3DUniform(uniform.type, fullName, uniform.arraySize, true); + d3dUniform = new D3DUniform(uniform.type, fullName, uniform.arraySizes, true); (*uniformMap)[fullName] = d3dUniform; } @@ -1917,10 +2244,14 @@ void ProgramD3D::defineUniform(GLenum shaderType, { d3dUniform->psRegisterIndex = reg; } + else if (shaderType == GL_VERTEX_SHADER) + { + d3dUniform->vsRegisterIndex = reg; + } else { - ASSERT(shaderType == GL_VERTEX_SHADER); - d3dUniform->vsRegisterIndex = reg; + ASSERT(shaderType == GL_COMPUTE_SHADER); + d3dUniform->csRegisterIndex = reg; } // Arrays are treated as aggregate types @@ -1931,177 +2262,223 @@ void ProgramD3D::defineUniform(GLenum shaderType, } } +// Assume count is already clamped. template -void ProgramD3D::setUniform(GLint location, GLsizei countIn, const T *v, GLenum targetUniformType) +void ProgramD3D::setUniformImpl(const gl::VariableLocation &locationInfo, + GLsizei count, + const T *v, + uint8_t *targetData, + GLenum uniformType) { - const int components = gl::VariableComponentCount(targetUniformType); - const GLenum targetBoolType = gl::VariableBoolVectorType(targetUniformType); + D3DUniform *targetUniform = mD3DUniforms[locationInfo.index]; + const int components = targetUniform->typeInfo.componentCount; + const unsigned int arrayElementOffset = locationInfo.arrayIndex; - D3DUniform *targetUniform = getD3DUniformFromLocation(location); - - unsigned int elementCount = targetUniform->elementCount(); - unsigned int arrayElement = mData.getUniformLocations()[location].element; - unsigned int count = std::min(elementCount - arrayElement, static_cast(countIn)); - - if (targetUniform->type == targetUniformType) + if (targetUniform->typeInfo.type == uniformType) { - T *target = reinterpret_cast(targetUniform->data) + arrayElement * 4; + T *dest = reinterpret_cast(targetData) + arrayElementOffset * 4; + const T *source = v; - for (unsigned int i = 0; i < count; i++) + for (GLint i = 0; i < count; i++, dest += 4, source += components) { - T *dest = target + (i * 4); - const T *source = v + (i * components); - - for (int c = 0; c < components; c++) - { - SetIfDirty(dest + c, source[c], &targetUniform->dirty); - } - for (int c = components; c < 4; c++) - { - SetIfDirty(dest + c, T(0), &targetUniform->dirty); - } + memcpy(dest, source, components * sizeof(T)); } } - else if (targetUniform->type == targetBoolType) + else { - GLint *boolParams = reinterpret_cast(targetUniform->data) + arrayElement * 4; + ASSERT(targetUniform->typeInfo.type == gl::VariableBoolVectorType(uniformType)); + GLint *boolParams = reinterpret_cast(targetData) + arrayElementOffset * 4; - for (unsigned int i = 0; i < count; i++) + for (GLint i = 0; i < count; i++) { GLint *dest = boolParams + (i * 4); const T *source = v + (i * components); for (int c = 0; c < components; c++) { - SetIfDirty(dest + c, (source[c] == static_cast(0)) ? GL_FALSE : GL_TRUE, - &targetUniform->dirty); - } - for (int c = components; c < 4; c++) - { - SetIfDirty(dest + c, GL_FALSE, &targetUniform->dirty); + dest[c] = (source[c] == static_cast(0)) ? GL_FALSE : GL_TRUE; } } } - else if (targetUniform->isSampler()) +} + +template +void ProgramD3D::setUniformInternal(GLint location, GLsizei count, const T *v, GLenum uniformType) +{ + const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location]; + D3DUniform *targetUniform = mD3DUniforms[locationInfo.index]; + + if (targetUniform->typeInfo.isSampler) { - ASSERT(targetUniformType == GL_INT); - - GLint *target = reinterpret_cast(targetUniform->data) + arrayElement * 4; - - bool wasDirty = targetUniform->dirty; - - for (unsigned int i = 0; i < count; i++) - { - GLint *dest = target + (i * 4); - const GLint *source = reinterpret_cast(v) + (i * components); - - SetIfDirty(dest + 0, source[0], &targetUniform->dirty); - SetIfDirty(dest + 1, 0, &targetUniform->dirty); - SetIfDirty(dest + 2, 0, &targetUniform->dirty); - SetIfDirty(dest + 3, 0, &targetUniform->dirty); - } - - if (!wasDirty && targetUniform->dirty) + ASSERT(uniformType == GL_INT); + size_t size = count * sizeof(T); + GLint *dest = &targetUniform->mSamplerData[locationInfo.arrayIndex]; + if (memcmp(dest, v, size) != 0) { + memcpy(dest, v, size); mDirtySamplerMapping = true; } + return; + } + + if (targetUniform->vsData) + { + setUniformImpl(locationInfo, count, v, targetUniform->vsData, uniformType); + mVertexUniformsDirty = true; + } + + if (targetUniform->psData) + { + setUniformImpl(locationInfo, count, v, targetUniform->psData, uniformType); + mFragmentUniformsDirty = true; + } + + if (targetUniform->csData) + { + setUniformImpl(locationInfo, count, v, targetUniform->csData, uniformType); + mComputeUniformsDirty = true; } - else - UNREACHABLE(); } template -void ProgramD3D::setUniformMatrixfv(GLint location, - GLsizei countIn, - GLboolean transpose, - const GLfloat *value, - GLenum targetUniformType) +bool ProgramD3D::setUniformMatrixfvImpl(GLint location, + GLsizei countIn, + GLboolean transpose, + const GLfloat *value, + uint8_t *targetData, + GLenum targetUniformType) { D3DUniform *targetUniform = getD3DUniformFromLocation(location); - unsigned int elementCount = targetUniform->elementCount(); - unsigned int arrayElement = mData.getUniformLocations()[location].element; - unsigned int count = std::min(elementCount - arrayElement, static_cast(countIn)); + unsigned int elementCount = targetUniform->getArraySizeProduct(); + unsigned int arrayElementOffset = mState.getUniformLocations()[location].arrayIndex; + unsigned int count = + std::min(elementCount - arrayElementOffset, static_cast(countIn)); const unsigned int targetMatrixStride = (4 * rows); - GLfloat *target = - (GLfloat *)(targetUniform->data + arrayElement * sizeof(GLfloat) * targetMatrixStride); + GLfloat *target = reinterpret_cast( + targetData + arrayElementOffset * sizeof(GLfloat) * targetMatrixStride); + + bool dirty = false; for (unsigned int i = 0; i < count; i++) { // Internally store matrices as transposed versions to accomodate HLSL matrix indexing if (transpose == GL_FALSE) { - targetUniform->dirty = TransposeMatrix(target, value, 4, rows, rows, cols) || - targetUniform->dirty; + dirty = TransposeExpandMatrix(target, value) || dirty; } else { - targetUniform->dirty = - ExpandMatrix(target, value, 4, rows, cols, rows) || targetUniform->dirty; + dirty = ExpandMatrix(target, value) || dirty; } target += targetMatrixStride; value += cols * rows; } + + return dirty; } -size_t ProgramD3D::getUniformBlockInfo(const sh::InterfaceBlock &interfaceBlock) +template +void ProgramD3D::setUniformMatrixfvInternal(GLint location, + GLsizei countIn, + GLboolean transpose, + const GLfloat *value, + GLenum targetUniformType) { - ASSERT(interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED); + D3DUniform *targetUniform = getD3DUniformFromLocation(location); - // define member uniforms - sh::Std140BlockEncoder std140Encoder; - sh::HLSLBlockEncoder hlslEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED); - sh::BlockLayoutEncoder *encoder = nullptr; - - if (interfaceBlock.layout == sh::BLOCKLAYOUT_STANDARD) + if (targetUniform->vsData) { - encoder = &std140Encoder; - } - else - { - encoder = &hlslEncoder; - } - - GetUniformBlockInfo(interfaceBlock.fields, interfaceBlock.fieldPrefix(), encoder, - interfaceBlock.isRowMajorLayout, &mBlockInfo); - - return encoder->getBlockSize(); -} - -void ProgramD3D::assignAllSamplerRegisters() -{ - for (const D3DUniform *d3dUniform : mD3DUniforms) - { - if (d3dUniform->isSampler()) + if (setUniformMatrixfvImpl(location, countIn, transpose, value, + targetUniform->vsData, targetUniformType)) { - assignSamplerRegisters(d3dUniform); + mVertexUniformsDirty = true; + } + } + + if (targetUniform->psData) + { + if (setUniformMatrixfvImpl(location, countIn, transpose, value, + targetUniform->psData, targetUniformType)) + { + mFragmentUniformsDirty = true; + } + } + + if (targetUniform->csData) + { + if (setUniformMatrixfvImpl(location, countIn, transpose, value, + targetUniform->csData, targetUniformType)) + { + mComputeUniformsDirty = true; } } } -void ProgramD3D::assignSamplerRegisters(const D3DUniform *d3dUniform) +void ProgramD3D::assignAllSamplerRegisters() { - ASSERT(d3dUniform->isSampler()); - ASSERT(d3dUniform->vsRegisterIndex != GL_INVALID_INDEX || - d3dUniform->psRegisterIndex != GL_INVALID_INDEX); - - if (d3dUniform->vsRegisterIndex != GL_INVALID_INDEX) + for (size_t uniformIndex = 0; uniformIndex < mD3DUniforms.size(); ++uniformIndex) { - AssignSamplers(d3dUniform->vsRegisterIndex, d3dUniform->type, d3dUniform->arraySize, - mSamplersVS, &mUsedVertexSamplerRange); + if (mD3DUniforms[uniformIndex]->isSampler()) + { + assignSamplerRegisters(uniformIndex); + } } +} - if (d3dUniform->psRegisterIndex != GL_INVALID_INDEX) +void ProgramD3D::assignSamplerRegisters(size_t uniformIndex) +{ + D3DUniform *d3dUniform = mD3DUniforms[uniformIndex]; + ASSERT(d3dUniform->isSampler()); + // If the uniform is an array of arrays, then we have separate entries for each inner array in + // mD3DUniforms. However, the sampler register info is stored in the shader only for the + // outermost array. + std::vector subscripts; + const std::string baseName = gl::ParseResourceName(d3dUniform->name, &subscripts); + unsigned int registerOffset = mState.getUniforms()[uniformIndex].flattenedOffsetInParentArrays * + d3dUniform->getArraySizeProduct(); + + const gl::Shader *computeShader = mState.getAttachedComputeShader(); + if (computeShader) { - AssignSamplers(d3dUniform->psRegisterIndex, d3dUniform->type, d3dUniform->arraySize, - mSamplersPS, &mUsedPixelSamplerRange); + const ShaderD3D *computeShaderD3D = GetImplAs(mState.getAttachedComputeShader()); + ASSERT(computeShaderD3D->hasUniform(baseName)); + d3dUniform->csRegisterIndex = + computeShaderD3D->getUniformRegister(baseName) + registerOffset; + ASSERT(d3dUniform->csRegisterIndex != GL_INVALID_INDEX); + AssignSamplers(d3dUniform->csRegisterIndex, d3dUniform->typeInfo, + d3dUniform->getArraySizeProduct(), mSamplersCS, &mUsedComputeSamplerRange); + } + else + { + const ShaderD3D *vertexShaderD3D = GetImplAs(mState.getAttachedVertexShader()); + const ShaderD3D *fragmentShaderD3D = + GetImplAs(mState.getAttachedFragmentShader()); + ASSERT(vertexShaderD3D->hasUniform(baseName) || fragmentShaderD3D->hasUniform(baseName)); + if (vertexShaderD3D->hasUniform(baseName)) + { + d3dUniform->vsRegisterIndex = + vertexShaderD3D->getUniformRegister(baseName) + registerOffset; + ASSERT(d3dUniform->vsRegisterIndex != GL_INVALID_INDEX); + AssignSamplers(d3dUniform->vsRegisterIndex, d3dUniform->typeInfo, + d3dUniform->getArraySizeProduct(), mSamplersVS, + &mUsedVertexSamplerRange); + } + if (fragmentShaderD3D->hasUniform(baseName)) + { + d3dUniform->psRegisterIndex = + fragmentShaderD3D->getUniformRegister(baseName) + registerOffset; + ASSERT(d3dUniform->psRegisterIndex != GL_INVALID_INDEX); + AssignSamplers(d3dUniform->psRegisterIndex, d3dUniform->typeInfo, + d3dUniform->getArraySizeProduct(), mSamplersPS, &mUsedPixelSamplerRange); + } } } // static void ProgramD3D::AssignSamplers(unsigned int startSamplerIndex, - GLenum samplerType, + const gl::UniformTypeInfo &typeInfo, unsigned int samplerCount, std::vector &outSamplers, GLuint *outUsedRange) @@ -2113,7 +2490,7 @@ void ProgramD3D::AssignSamplers(unsigned int startSamplerIndex, ASSERT(samplerIndex < outSamplers.size()); Sampler *sampler = &outSamplers[samplerIndex]; sampler->active = true; - sampler->textureType = gl::SamplerTypeToTextureType(samplerType); + sampler->textureType = typeInfo.samplerTextureType; sampler->logicalTextureUnit = 0; *outUsedRange = std::max(samplerIndex + 1, *outUsedRange); samplerIndex++; @@ -2122,20 +2499,24 @@ void ProgramD3D::AssignSamplers(unsigned int startSamplerIndex, void ProgramD3D::reset() { - SafeDeleteContainer(mVertexExecutables); - SafeDeleteContainer(mPixelExecutables); + mVertexExecutables.clear(); + mPixelExecutables.clear(); - for (auto &element : mGeometryExecutables) + for (auto &geometryExecutable : mGeometryExecutables) { - SafeDelete(element); + geometryExecutable.reset(nullptr); } + mComputeExecutable.reset(nullptr); + mVertexHLSL.clear(); - mVertexWorkarounds = D3DCompilerWorkarounds(); + mVertexWorkarounds = angle::CompilerWorkaroundsD3D(); mPixelHLSL.clear(); - mPixelWorkarounds = D3DCompilerWorkarounds(); + mPixelWorkarounds = angle::CompilerWorkaroundsD3D(); mUsesFragDepth = false; + mHasANGLEMultiviewEnabled = false; + mUsesViewID = false; mPixelShaderKey.clear(); mUsesPointSize = false; mUsesFlatInterpolation = false; @@ -2143,22 +2524,29 @@ void ProgramD3D::reset() SafeDeleteContainer(mD3DUniforms); mD3DUniformBlocks.clear(); - SafeDelete(mVertexUniformStorage); - SafeDelete(mFragmentUniformStorage); + mVertexUniformStorage.reset(nullptr); + mFragmentUniformStorage.reset(nullptr); + mComputeUniformStorage.reset(nullptr); mSamplersPS.clear(); mSamplersVS.clear(); + mSamplersCS.clear(); mUsedVertexSamplerRange = 0; mUsedPixelSamplerRange = 0; + mUsedComputeSamplerRange = 0; mDirtySamplerMapping = true; - std::fill(mSemanticIndexes, mSemanticIndexes + ArraySize(mSemanticIndexes), -1); - std::fill(mAttributesByLayout, mAttributesByLayout + ArraySize(mAttributesByLayout), -1); + mAttribLocationToD3DSemantic.fill(-1); mStreamOutVaryings.clear(); mGeometryShaderPreamble.clear(); + + dirtyAllUniforms(); + + mCachedPixelExecutableIndex.reset(); + mCachedVertexExecutableIndex.reset(); } unsigned int ProgramD3D::getSerial() const @@ -2171,84 +2559,96 @@ unsigned int ProgramD3D::issueSerial() return mCurrentSerial++; } -void ProgramD3D::initSemanticIndex() +void ProgramD3D::initAttribLocationsToD3DSemantic(const gl::Context *context) { - const gl::Shader *vertexShader = mData.getAttachedVertexShader(); + gl::Shader *vertexShader = mState.getAttachedVertexShader(); ASSERT(vertexShader != nullptr); // Init semantic index - for (const sh::Attribute &attribute : mData.getAttributes()) + int semanticIndex = 0; + for (const sh::Attribute &attribute : vertexShader->getActiveAttributes(context)) { - int attributeIndex = attribute.location; - int index = vertexShader->getSemanticIndex(attribute.name); - int regs = gl::VariableRegisterCount(attribute.type); + int regCount = gl::VariableRegisterCount(attribute.type); + GLuint location = mState.getAttributeLocation(attribute.name); + ASSERT(location != std::numeric_limits::max()); - for (int reg = 0; reg < regs; ++reg) + for (int reg = 0; reg < regCount; ++reg) { - mSemanticIndexes[attributeIndex + reg] = index + reg; + mAttribLocationToD3DSemantic[location + reg] = semanticIndex++; } } - - initAttributesByLayout(); } -void ProgramD3D::initAttributesByLayout() +void ProgramD3D::updateCachedInputLayout(Serial associatedSerial, const gl::State &state) { - for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + if (mCurrentVertexArrayStateSerial == associatedSerial) { - mAttributesByLayout[i] = i; + return; } - std::sort(&mAttributesByLayout[0], &mAttributesByLayout[gl::MAX_VERTEX_ATTRIBS], - AttributeSorter(mSemanticIndexes)); -} - -void ProgramD3D::sortAttributesByLayout( - const std::vector &unsortedAttributes, - int sortedSemanticIndicesOut[gl::MAX_VERTEX_ATTRIBS], - const rx::TranslatedAttribute *sortedAttributesOut[gl::MAX_VERTEX_ATTRIBS]) const -{ - for (size_t attribIndex = 0; attribIndex < unsortedAttributes.size(); ++attribIndex) - { - int oldIndex = mAttributesByLayout[attribIndex]; - sortedSemanticIndicesOut[attribIndex] = mSemanticIndexes[oldIndex]; - sortedAttributesOut[attribIndex] = &unsortedAttributes[oldIndex]; - } -} - -void ProgramD3D::updateCachedInputLayout(const gl::State &state) -{ + mCurrentVertexArrayStateSerial = associatedSerial; mCachedInputLayout.clear(); + const auto &vertexAttributes = state.getVertexArray()->getVertexAttributes(); - for (unsigned int attributeIndex : angle::IterateBitSet(mData.getActiveAttribLocationsMask())) + for (size_t locationIndex : mState.getActiveAttribLocationsMask()) { - int semanticIndex = mSemanticIndexes[attributeIndex]; + int d3dSemantic = mAttribLocationToD3DSemantic[locationIndex]; - if (semanticIndex != -1) + if (d3dSemantic != -1) { - if (mCachedInputLayout.size() < static_cast(semanticIndex + 1)) + if (mCachedInputLayout.size() < static_cast(d3dSemantic + 1)) { - mCachedInputLayout.resize(semanticIndex + 1, gl::VERTEX_FORMAT_INVALID); + mCachedInputLayout.resize(d3dSemantic + 1, gl::VERTEX_FORMAT_INVALID); } - mCachedInputLayout[semanticIndex] = - GetVertexFormatType(vertexAttributes[attributeIndex], - state.getVertexAttribCurrentValue(attributeIndex).Type); + mCachedInputLayout[d3dSemantic] = + GetVertexFormatType(vertexAttributes[locationIndex], + state.getVertexAttribCurrentValue(locationIndex).Type); } } + + VertexExecutable::getSignature(mRenderer, mCachedInputLayout, &mCachedVertexSignature); + + updateCachedVertexExecutableIndex(); } -void ProgramD3D::gatherTransformFeedbackVaryings(const VaryingPacking &varyingPacking) +void ProgramD3D::updateCachedOutputLayout(const gl::Context *context, + const gl::Framebuffer *framebuffer) { - const auto &builtins = varyingPacking.builtins(SHADER_VERTEX); + mPixelShaderOutputLayoutCache.clear(); + FramebufferD3D *fboD3D = GetImplAs(framebuffer); + const auto &colorbuffers = fboD3D->getColorAttachmentsForRender(context); + + for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment) + { + const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment]; + + if (colorbuffer) + { + auto binding = colorbuffer->getBinding() == GL_BACK ? GL_COLOR_ATTACHMENT0 + : colorbuffer->getBinding(); + mPixelShaderOutputLayoutCache.push_back(binding); + } + else + { + mPixelShaderOutputLayoutCache.push_back(GL_NONE); + } + } + + updateCachedPixelExecutableIndex(); +} + +void ProgramD3D::gatherTransformFeedbackVaryings(const gl::VaryingPacking &varyingPacking, + const BuiltinInfo &builtins) +{ const std::string &varyingSemantic = GetVaryingSemantic(mRenderer->getMajorShaderModel(), usesPointSize()); // Gather the linked varyings that are used for transform feedback, they should all exist. mStreamOutVaryings.clear(); - const auto &tfVaryingNames = mData.getTransformFeedbackVaryingNames(); + const auto &tfVaryingNames = mState.getTransformFeedbackVaryingNames(); for (unsigned int outputSlot = 0; outputSlot < static_cast(tfVaryingNames.size()); ++outputSlot) { @@ -2278,7 +2678,14 @@ void ProgramD3D::gatherTransformFeedbackVaryings(const VaryingPacking &varyingPa } else { - for (const PackedVaryingRegister ®isterInfo : varyingPacking.getRegisterList()) + std::vector subscripts; + std::string baseName = gl::ParseResourceName(tfVaryingName, &subscripts); + size_t subscript = GL_INVALID_INDEX; + if (!subscripts.empty()) + { + subscript = subscripts.back(); + } + for (const auto ®isterInfo : varyingPacking.getRegisterList()) { const auto &varying = *registerInfo.packedVarying->varying; GLenum transposedType = gl::TransposeMatrixType(varying.type); @@ -2293,7 +2700,8 @@ void ProgramD3D::gatherTransformFeedbackVaryings(const VaryingPacking &varyingPa // There can be more than one register assigned to a particular varying, and each // register needs its own stream out entry. - if (tfVaryingName == varying.name) + if (baseName == registerInfo.packedVarying->varying->name && + (subscript == GL_INVALID_INDEX || subscript == registerInfo.varyingArrayIndex)) { mStreamOutVaryings.push_back(D3DVarying( varyingSemantic, registerInfo.semanticIndex, componentCount, outputSlot)); @@ -2305,36 +2713,155 @@ void ProgramD3D::gatherTransformFeedbackVaryings(const VaryingPacking &varyingPa D3DUniform *ProgramD3D::getD3DUniformFromLocation(GLint location) { - return mD3DUniforms[mData.getUniformLocations()[location].index]; + return mD3DUniforms[mState.getUniformLocations()[location].index]; } -bool ProgramD3D::getUniformBlockSize(const std::string &blockName, size_t *sizeOut) const +const D3DUniform *ProgramD3D::getD3DUniformFromLocation(GLint location) const { - std::string baseName = blockName; - gl::ParseAndStripArrayIndex(&baseName); + return mD3DUniforms[mState.getUniformLocations()[location].index]; +} - auto sizeIter = mBlockDataSizes.find(baseName); - if (sizeIter == mBlockDataSizes.end()) +void ProgramD3D::setPathFragmentInputGen(const std::string &inputName, + GLenum genMode, + GLint components, + const GLfloat *coeffs) +{ + UNREACHABLE(); +} + +bool ProgramD3D::hasVertexExecutableForCachedInputLayout() +{ + return mCachedVertexExecutableIndex.valid(); +} + +bool ProgramD3D::hasGeometryExecutableForPrimitiveType(GLenum drawMode) +{ + if (!usesGeometryShader(drawMode)) { + // No shader necessary mean we have the required (null) executable. + return true; + } + + gl::PrimitiveType geometryShaderType = GetGeometryShaderTypeFromDrawMode(drawMode); + return mGeometryExecutables[geometryShaderType].get() != nullptr; +} + +bool ProgramD3D::hasPixelExecutableForCachedOutputLayout() +{ + return mCachedPixelExecutableIndex.valid(); +} + +template +void ProgramD3D::getUniformInternal(GLint location, DestT *dataOut) const +{ + const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location]; + const gl::LinkedUniform &uniform = mState.getUniforms()[locationInfo.index]; + + const D3DUniform *targetUniform = getD3DUniformFromLocation(location); + const uint8_t *srcPointer = targetUniform->getDataPtrToElement(locationInfo.arrayIndex); + + if (gl::IsMatrixType(uniform.type)) + { + GetMatrixUniform(gl::VariableColumnCount(uniform.type), gl::VariableRowCount(uniform.type), + dataOut, reinterpret_cast(srcPointer)); + } + else + { + memcpy(dataOut, srcPointer, uniform.getElementSize()); + } +} + +void ProgramD3D::getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const +{ + getUniformInternal(location, params); +} + +void ProgramD3D::getUniformiv(const gl::Context *context, GLint location, GLint *params) const +{ + getUniformInternal(location, params); +} + +void ProgramD3D::getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const +{ + getUniformInternal(location, params); +} + +void ProgramD3D::updateCachedVertexExecutableIndex() +{ + mCachedVertexExecutableIndex.reset(); + for (size_t executableIndex = 0; executableIndex < mVertexExecutables.size(); executableIndex++) + { + if (mVertexExecutables[executableIndex]->matchesSignature(mCachedVertexSignature)) + { + mCachedVertexExecutableIndex = executableIndex; + break; + } + } +} + +void ProgramD3D::updateCachedPixelExecutableIndex() +{ + mCachedPixelExecutableIndex.reset(); + for (size_t executableIndex = 0; executableIndex < mPixelExecutables.size(); executableIndex++) + { + if (mPixelExecutables[executableIndex]->matchesSignature(mPixelShaderOutputLayoutCache)) + { + mCachedPixelExecutableIndex = executableIndex; + break; + } + } +} + +void ProgramD3D::linkResources(const gl::Context *context, + const gl::ProgramLinkedResources &resources) +{ + UniformBlockInfo uniformBlockInfo; + + if (mState.getAttachedVertexShader()) + { + uniformBlockInfo.getShaderBlockInfo(context, mState.getAttachedVertexShader()); + } + + if (mState.getAttachedFragmentShader()) + { + uniformBlockInfo.getShaderBlockInfo(context, mState.getAttachedFragmentShader()); + } + + if (mState.getAttachedComputeShader()) + { + uniformBlockInfo.getShaderBlockInfo(context, mState.getAttachedComputeShader()); + } + + // Gather interface block info. + auto getUniformBlockSize = [&uniformBlockInfo](const std::string &name, + const std::string &mappedName, size_t *sizeOut) { + return uniformBlockInfo.getBlockSize(name, mappedName, sizeOut); + }; + + auto getUniformBlockMemberInfo = [&uniformBlockInfo](const std::string &name, + const std::string &mappedName, + sh::BlockMemberInfo *infoOut) { + return uniformBlockInfo.getBlockMemberInfo(name, mappedName, infoOut); + }; + + resources.uniformBlockLinker.linkBlocks(getUniformBlockSize, getUniformBlockMemberInfo); + initializeUniformBlocks(); + + // TODO(jiajia.qin@intel.com): Determine correct shader storage block info. + auto getShaderStorageBlockSize = [](const std::string &name, const std::string &mappedName, + size_t *sizeOut) { *sizeOut = 0; - return false; - } + return true; + }; - *sizeOut = sizeIter->second; - return true; + auto getShaderStorageBlockMemberInfo = + [](const std::string &name, const std::string &mappedName, sh::BlockMemberInfo *infoOut) { + *infoOut = sh::BlockMemberInfo::getDefaultBlockInfo(); + return true; + }; + + resources.shaderStorageBlockLinker.linkBlocks(getShaderStorageBlockSize, + getShaderStorageBlockMemberInfo); } -bool ProgramD3D::getUniformBlockMemberInfo(const std::string &memberUniformName, - sh::BlockMemberInfo *memberInfoOut) const -{ - auto infoIter = mBlockInfo.find(memberUniformName); - if (infoIter == mBlockInfo.end()) - { - *memberInfoOut = sh::BlockMemberInfo::getDefaultBlockInfo(); - return false; - } - - *memberInfoOut = infoIter->second; - return true; -} -} +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/ProgramD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ProgramD3D.h index 3dfe52db1c..829757a73e 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/ProgramD3D.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ProgramD3D.h @@ -17,7 +17,7 @@ #include "libANGLE/formatutils.h" #include "libANGLE/renderer/ProgramImpl.h" #include "libANGLE/renderer/d3d/DynamicHLSL.h" -#include "libANGLE/renderer/d3d/WorkaroundsD3D.h" +#include "platform/WorkaroundsD3D.h" namespace rx { @@ -32,52 +32,71 @@ class ShaderExecutableD3D; #endif // Helper struct representing a single shader uniform -struct D3DUniform : angle::NonCopyable +// TODO(jmadill): Make uniform blocks shared between all programs, so we don't need separate +// register indices. +struct D3DUniform : private angle::NonCopyable { - D3DUniform(GLenum typeIn, + D3DUniform(GLenum type, const std::string &nameIn, - unsigned int arraySizeIn, + const std::vector &arraySizesIn, bool defaultBlock); ~D3DUniform(); bool isSampler() const; - unsigned int elementCount() const { return std::max(1u, arraySize); } + + bool isArray() const { return !arraySizes.empty(); } + unsigned int getArraySizeProduct() const; + bool isReferencedByVertexShader() const; bool isReferencedByFragmentShader() const; + bool isReferencedByComputeShader() const; + + const uint8_t *firstNonNullData() const; + const uint8_t *getDataPtrToElement(size_t elementIndex) const; // Duplicated from the GL layer - GLenum type; - std::string name; - unsigned int arraySize; + const gl::UniformTypeInfo &typeInfo; + std::string name; // Names of arrays don't include [0], unlike at the GL layer. + std::vector arraySizes; - // Pointer to a system copy of the data. - // TODO(jmadill): remove this in favor of gl::LinkedUniform::data(). - uint8_t *data; - - // Has the data been updated since the last sync? - bool dirty; + // Pointer to a system copies of the data. Separate pointers for each uniform storage type. + uint8_t *vsData; + uint8_t *psData; + uint8_t *csData; // Register information. unsigned int vsRegisterIndex; unsigned int psRegisterIndex; + unsigned int csRegisterIndex; unsigned int registerCount; // Register "elements" are used for uniform structs in ES3, to appropriately identify single // uniforms // inside aggregate types, which are packed according C-like structure rules. unsigned int registerElement; + + // Special buffer for sampler values. + std::vector mSamplerData; }; struct D3DUniformBlock { - D3DUniformBlock() : vsRegisterIndex(GL_INVALID_INDEX), psRegisterIndex(GL_INVALID_INDEX) {} + D3DUniformBlock() + : vsRegisterIndex(GL_INVALID_INDEX), + psRegisterIndex(GL_INVALID_INDEX), + csRegisterIndex(GL_INVALID_INDEX) + { + } bool vertexStaticUse() const { return vsRegisterIndex != GL_INVALID_INDEX; } bool fragmentStaticUse() const { return psRegisterIndex != GL_INVALID_INDEX; } + bool computeStaticUse() const { return csRegisterIndex != GL_INVALID_INDEX; } + unsigned int vsRegisterIndex; unsigned int psRegisterIndex; + unsigned int csRegisterIndex; }; struct D3DVarying final @@ -97,24 +116,24 @@ struct D3DVarying final unsigned int outputSlot; }; -class ProgramD3DMetadata : angle::NonCopyable +class ProgramD3DMetadata final : angle::NonCopyable { public: - ProgramD3DMetadata(int rendererMajorShaderModel, - const std::string &shaderModelSuffix, - bool usesInstancedPointSpriteEmulation, - bool usesViewScale, + ProgramD3DMetadata(RendererD3D *renderer, const ShaderD3D *vertexShader, const ShaderD3D *fragmentShader); int getRendererMajorShaderModel() const; - bool usesBroadcast(const gl::Data &data) const; - bool usesFragDepth(const gl::Program::Data &programData) const; + bool usesBroadcast(const gl::ContextState &data) const; + bool usesFragDepth() const; bool usesPointCoord() const; bool usesFragCoord() const; bool usesPointSize() const; bool usesInsertedPointCoordValue() const; bool usesViewScale() const; + bool hasANGLEMultiviewEnabled() const; + bool usesViewID() const; + bool canSelectViewInVertexShader() const; bool addsPointCoordToVertexShader() const; bool usesTransformFeedbackGLPosition() const; bool usesSystemValuePointSize() const; @@ -127,6 +146,9 @@ class ProgramD3DMetadata : angle::NonCopyable const std::string mShaderModelSuffix; const bool mUsesInstancedPointSpriteEmulation; const bool mUsesViewScale; + const bool mHasANGLEMultiviewEnabled; + const bool mUsesViewID; + const bool mCanSelectViewInVertexShader; const ShaderD3D *mVertexShader; const ShaderD3D *mFragmentShader; }; @@ -134,10 +156,8 @@ class ProgramD3DMetadata : angle::NonCopyable class ProgramD3D : public ProgramImpl { public: - typedef int SemanticIndexArray[gl::MAX_VERTEX_ATTRIBS]; - - ProgramD3D(const gl::Program::Data &data, RendererD3D *renderer); - virtual ~ProgramD3D(); + ProgramD3D(const gl::ProgramState &data, RendererD3D *renderer); + ~ProgramD3D() override; const std::vector &getPixelShaderKey() { return mPixelShaderKey; } @@ -145,116 +165,157 @@ class ProgramD3D : public ProgramImpl unsigned int samplerIndex, const gl::Caps &caps) const; GLenum getSamplerTextureType(gl::SamplerType type, unsigned int samplerIndex) const; - GLint getUsedSamplerRange(gl::SamplerType type) const; - void updateSamplerMapping(); + GLuint getUsedSamplerRange(gl::SamplerType type) const; + + enum SamplerMapping + { + WasDirty, + WasClean, + }; + + SamplerMapping updateSamplerMapping(); bool usesPointSize() const { return mUsesPointSize; } bool usesPointSpriteEmulation() const; bool usesGeometryShader(GLenum drawMode) const; + bool usesGeometryShaderForPointSpriteEmulation() const; bool usesInstancedPointSpriteEmulation() const; - LinkResult load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) override; - gl::Error save(gl::BinaryOutputStream *stream) override; + gl::LinkResult load(const gl::Context *context, + gl::InfoLog &infoLog, + gl::BinaryInputStream *stream) override; + void save(const gl::Context *context, gl::BinaryOutputStream *stream) override; void setBinaryRetrievableHint(bool retrievable) override; + void setSeparable(bool separable) override; - gl::Error getPixelExecutableForFramebuffer(const gl::Framebuffer *fbo, - ShaderExecutableD3D **outExectuable); - gl::Error getPixelExecutableForOutputLayout(const std::vector &outputLayout, - ShaderExecutableD3D **outExectuable, - gl::InfoLog *infoLog); - gl::Error getVertexExecutableForInputLayout(const gl::InputLayout &inputLayout, - ShaderExecutableD3D **outExectuable, - gl::InfoLog *infoLog); - gl::Error getGeometryExecutableForPrimitiveType(const gl::Data &data, + gl::Error getVertexExecutableForCachedInputLayout(ShaderExecutableD3D **outExectuable, + gl::InfoLog *infoLog); + gl::Error getGeometryExecutableForPrimitiveType(const gl::Context *context, GLenum drawMode, ShaderExecutableD3D **outExecutable, gl::InfoLog *infoLog); - - LinkResult link(const gl::Data &data, gl::InfoLog &infoLog) override; + gl::Error getPixelExecutableForCachedOutputLayout(ShaderExecutableD3D **outExectuable, + gl::InfoLog *infoLog); + gl::Error getComputeExecutable(ShaderExecutableD3D **outExecutable); + gl::LinkResult link(const gl::Context *context, + const gl::ProgramLinkedResources &resources, + gl::InfoLog &infoLog) override; GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override; - bool getUniformBlockSize(const std::string &blockName, size_t *sizeOut) const override; - bool getUniformBlockMemberInfo(const std::string &memberUniformName, - sh::BlockMemberInfo *memberInfoOut) const override; + void setPathFragmentInputGen(const std::string &inputName, + GLenum genMode, + GLint components, + const GLfloat *coeffs) override; void initializeUniformStorage(); - gl::Error applyUniforms(GLenum drawMode); - gl::Error applyUniformBuffers(const gl::Data &data); + void updateUniformBufferCache(const gl::Caps &caps, + unsigned int reservedVertex, + unsigned int reservedFragment); + const std::vector &getVertexUniformBufferCache() const; + const std::vector &getFragmentUniformBufferCache() const; + void dirtyAllUniforms(); - void setUniform1fv(GLint location, GLsizei count, const GLfloat *v); - void setUniform2fv(GLint location, GLsizei count, const GLfloat *v); - void setUniform3fv(GLint location, GLsizei count, const GLfloat *v); - void setUniform4fv(GLint location, GLsizei count, const GLfloat *v); - void setUniform1iv(GLint location, GLsizei count, const GLint *v); - void setUniform2iv(GLint location, GLsizei count, const GLint *v); - void setUniform3iv(GLint location, GLsizei count, const GLint *v); - void setUniform4iv(GLint location, GLsizei count, const GLint *v); - void setUniform1uiv(GLint location, GLsizei count, const GLuint *v); - void setUniform2uiv(GLint location, GLsizei count, const GLuint *v); - void setUniform3uiv(GLint location, GLsizei count, const GLuint *v); - void setUniform4uiv(GLint location, GLsizei count, const GLuint *v); + void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) override; + void setUniform2fv(GLint location, GLsizei count, const GLfloat *v) override; + void setUniform3fv(GLint location, GLsizei count, const GLfloat *v) override; + void setUniform4fv(GLint location, GLsizei count, const GLfloat *v) override; + void setUniform1iv(GLint location, GLsizei count, const GLint *v) override; + void setUniform2iv(GLint location, GLsizei count, const GLint *v) override; + void setUniform3iv(GLint location, GLsizei count, const GLint *v) override; + void setUniform4iv(GLint location, GLsizei count, const GLint *v) override; + void setUniform1uiv(GLint location, GLsizei count, const GLuint *v) override; + void setUniform2uiv(GLint location, GLsizei count, const GLuint *v) override; + void setUniform3uiv(GLint location, GLsizei count, const GLuint *v) override; + void setUniform4uiv(GLint location, GLsizei count, const GLuint *v) override; void setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value); + const GLfloat *value) override; void setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value); + const GLfloat *value) override; void setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value); + const GLfloat *value) override; void setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value); + const GLfloat *value) override; void setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value); + const GLfloat *value) override; void setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value); + const GLfloat *value) override; void setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value); + const GLfloat *value) override; void setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value); + const GLfloat *value) override; void setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value); + const GLfloat *value) override; + + void getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const override; + void getUniformiv(const gl::Context *context, GLint location, GLint *params) const override; + void getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const override; void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override; - const UniformStorageD3D &getVertexUniformStorage() const { return *mVertexUniformStorage; } - const UniformStorageD3D &getFragmentUniformStorage() const { return *mFragmentUniformStorage; } + UniformStorageD3D &getVertexUniformStorage() const { return *mVertexUniformStorage.get(); } + UniformStorageD3D &getFragmentUniformStorage() const { return *mFragmentUniformStorage.get(); } + UniformStorageD3D &getComputeUniformStorage() const { return *mComputeUniformStorage.get(); } unsigned int getSerial() const; - void sortAttributesByLayout( - const std::vector &unsortedAttributes, - int sortedSemanticIndicesOut[gl::MAX_VERTEX_ATTRIBS], - const rx::TranslatedAttribute *sortedAttributesOut[gl::MAX_VERTEX_ATTRIBS]) const; - const SemanticIndexArray &getSemanticIndexes() const { return mSemanticIndexes; } - const SemanticIndexArray &getAttributesByLayout() const { return mAttributesByLayout; } + const AttribIndexArray &getAttribLocationToD3DSemantics() const + { + return mAttribLocationToD3DSemantic; + } - void updateCachedInputLayout(const gl::State &state); - const gl::InputLayout &getCachedInputLayout() const { return mCachedInputLayout; } + void updateCachedInputLayout(Serial associatedSerial, const gl::State &state); + void updateCachedOutputLayout(const gl::Context *context, const gl::Framebuffer *framebuffer); bool isSamplerMappingDirty() { return mDirtySamplerMapping; } + // Checks if we need to recompile certain shaders. + bool hasVertexExecutableForCachedInputLayout(); + bool hasGeometryExecutableForPrimitiveType(GLenum drawMode); + bool hasPixelExecutableForCachedOutputLayout(); + + bool areVertexUniformsDirty() const { return mVertexUniformsDirty; } + bool areFragmentUniformsDirty() const { return mFragmentUniformsDirty; } + bool areComputeUniformsDirty() const { return mComputeUniformsDirty; } + const std::vector &getD3DUniforms() const { return mD3DUniforms; } + void markUniformsClean(); + private: + // These forward-declared tasks are used for multi-thread shader compiles. + class GetExecutableTask; + class GetVertexExecutableTask; + class GetPixelExecutableTask; + class GetGeometryExecutableTask; + class VertexExecutable { public: - typedef std::vector Signature; + enum HLSLAttribType + { + FLOAT, + UNSIGNED_INT, + SIGNED_INT, + }; + + typedef std::vector Signature; VertexExecutable(const gl::InputLayout &inputLayout, const Signature &signature, @@ -271,6 +332,8 @@ class ProgramD3D : public ProgramImpl ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable; } private: + static HLSLAttribType GetAttribType(GLenum type); + gl::InputLayout mInputs; Signature mSignature; ShaderExecutableD3D *mShaderExecutable; @@ -307,62 +370,105 @@ class ProgramD3D : public ProgramImpl typedef std::map D3DUniformMap; - void defineUniformsAndAssignRegisters(); + void defineUniformsAndAssignRegisters(const gl::Context *context); void defineUniformBase(const gl::Shader *shader, const sh::Uniform &uniform, D3DUniformMap *uniformMap); + void defineStructUniformFields(GLenum shaderType, + const std::vector &fields, + const std::string &namePrefix, + sh::HLSLBlockEncoder *encoder, + D3DUniformMap *uniformMap); + void defineArrayOfStructsUniformFields(GLenum shaderType, + const sh::ShaderVariable &uniform, + unsigned int arrayNestingIndex, + const std::string &prefix, + sh::HLSLBlockEncoder *encoder, + D3DUniformMap *uniformMap); + void defineArrayUniformElements(GLenum shaderType, + const sh::ShaderVariable &uniform, + const std::string &fullName, + sh::HLSLBlockEncoder *encoder, + D3DUniformMap *uniformMap); void defineUniform(GLenum shaderType, const sh::ShaderVariable &uniform, const std::string &fullName, sh::HLSLBlockEncoder *encoder, D3DUniformMap *uniformMap); void assignAllSamplerRegisters(); - void assignSamplerRegisters(const D3DUniform *d3dUniform); + void assignSamplerRegisters(size_t uniformIndex); static void AssignSamplers(unsigned int startSamplerIndex, - GLenum samplerType, + const gl::UniformTypeInfo &typeInfo, unsigned int samplerCount, std::vector &outSamplers, GLuint *outUsedRange); + template + void getUniformInternal(GLint location, DestT *dataOut) const; + template - void setUniform(GLint location, GLsizei count, const T *v, GLenum targetUniformType); + void setUniformImpl(const gl::VariableLocation &locationInfo, + GLsizei count, + const T *v, + uint8_t *targetData, + GLenum uniformType); + + template + void setUniformInternal(GLint location, GLsizei count, const T *v, GLenum uniformType); template - void setUniformMatrixfv(GLint location, - GLsizei count, - GLboolean transpose, - const GLfloat *value, - GLenum targetUniformType); + bool setUniformMatrixfvImpl(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + uint8_t *targetData, + GLenum targetUniformType); - LinkResult compileProgramExecutables(const gl::Data &data, gl::InfoLog &infoLog); + template + void setUniformMatrixfvInternal(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value, + GLenum targetUniformType); - void gatherTransformFeedbackVaryings(const VaryingPacking &varyings); + gl::LinkResult compileProgramExecutables(const gl::Context *context, gl::InfoLog &infoLog); + gl::LinkResult compileComputeExecutable(const gl::Context *context, gl::InfoLog &infoLog); + + void gatherTransformFeedbackVaryings(const gl::VaryingPacking &varyings, + const BuiltinInfo &builtins); D3DUniform *getD3DUniformByName(const std::string &name); D3DUniform *getD3DUniformFromLocation(GLint location); + const D3DUniform *getD3DUniformFromLocation(GLint location) const; - void initSemanticIndex(); - void initAttributesByLayout(); + void initAttribLocationsToD3DSemantic(const gl::Context *context); void reset(); - void assignUniformBlockRegisters(); + void initializeUniformBlocks(); - void initUniformBlockInfo(); - size_t getUniformBlockInfo(const sh::InterfaceBlock &interfaceBlock); + void updateCachedInputLayoutFromShader(const gl::Context *context); + void updateCachedOutputLayoutFromShader(); + void updateCachedVertexExecutableIndex(); + void updateCachedPixelExecutableIndex(); + + void linkResources(const gl::Context *context, const gl::ProgramLinkedResources &resources); RendererD3D *mRenderer; DynamicHLSL *mDynamicHLSL; - std::vector mVertexExecutables; - std::vector mPixelExecutables; - std::vector mGeometryExecutables; + std::vector> mVertexExecutables; + std::vector> mPixelExecutables; + std::vector> mGeometryExecutables; + std::unique_ptr mComputeExecutable; std::string mVertexHLSL; - D3DCompilerWorkarounds mVertexWorkarounds; + angle::CompilerWorkaroundsD3D mVertexWorkarounds; std::string mPixelHLSL; - D3DCompilerWorkarounds mPixelWorkarounds; + angle::CompilerWorkaroundsD3D mPixelWorkarounds; bool mUsesFragDepth; + bool mHasANGLEMultiviewEnabled; + bool mUsesViewID; std::vector mPixelShaderKey; // Common code for all dynamic geometry shaders. Consists mainly of the GS input and output @@ -373,20 +479,23 @@ class ProgramD3D : public ProgramImpl bool mUsesPointSize; bool mUsesFlatInterpolation; - UniformStorageD3D *mVertexUniformStorage; - UniformStorageD3D *mFragmentUniformStorage; + std::unique_ptr mVertexUniformStorage; + std::unique_ptr mFragmentUniformStorage; + std::unique_ptr mComputeUniformStorage; std::vector mSamplersPS; std::vector mSamplersVS; + std::vector mSamplersCS; GLuint mUsedVertexSamplerRange; GLuint mUsedPixelSamplerRange; + GLuint mUsedComputeSamplerRange; bool mDirtySamplerMapping; - // Cache for getPixelExecutableForFramebuffer - std::vector mPixelShaderOutputFormatCache; + // Cache for pixel shader output layout to save reallocations. + std::vector mPixelShaderOutputLayoutCache; + Optional mCachedPixelExecutableIndex; - SemanticIndexArray mSemanticIndexes; - SemanticIndexArray mAttributesByLayout; + AttribIndexArray mAttribLocationToD3DSemantic; unsigned int mSerial; @@ -394,17 +503,21 @@ class ProgramD3D : public ProgramImpl std::vector mFragmentUBOCache; VertexExecutable::Signature mCachedVertexSignature; gl::InputLayout mCachedInputLayout; + Optional mCachedVertexExecutableIndex; std::vector mStreamOutVaryings; std::vector mD3DUniforms; std::vector mD3DUniformBlocks; - std::map mBlockInfo; - std::map mBlockDataSizes; + bool mVertexUniformsDirty; + bool mFragmentUniformsDirty; + bool mComputeUniformsDirty; static unsigned int issueSerial(); static unsigned int mCurrentSerial; + + Serial mCurrentVertexArrayStateSerial; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderTargetD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderTargetD3D.h index b2d895d9c6..fde96133b0 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderTargetD3D.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderTargetD3D.h @@ -21,7 +21,7 @@ class RenderTargetD3D : public FramebufferAttachmentRenderTarget { public: RenderTargetD3D(); - virtual ~RenderTargetD3D(); + ~RenderTargetD3D() override; virtual GLsizei getWidth() const = 0; virtual GLsizei getHeight() const = 0; @@ -29,10 +29,14 @@ class RenderTargetD3D : public FramebufferAttachmentRenderTarget virtual GLenum getInternalFormat() const = 0; virtual GLsizei getSamples() const = 0; gl::Extents getExtents() const { return gl::Extents(getWidth(), getHeight(), getDepth()); } + bool isMultisampled() const { return getSamples() > 0; } virtual unsigned int getSerial() const; static unsigned int issueSerials(unsigned int count); + // Only currently applies to D3D11. + virtual void signalDirty(const gl::Context *context) {} + private: const unsigned int mSerial; static unsigned int mCurrentSerial; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp index 991801a091..d799e0b992 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp @@ -27,12 +27,25 @@ RenderbufferD3D::~RenderbufferD3D() mImage = nullptr; } -gl::Error RenderbufferD3D::setStorage(GLenum internalformat, size_t width, size_t height) +gl::Error RenderbufferD3D::onDestroy(const gl::Context *context) { - return setStorageMultisample(0, internalformat, width, height); + deleteRenderTarget(context); + return gl::NoError(); } -gl::Error RenderbufferD3D::setStorageMultisample(size_t samples, GLenum internalformat, size_t width, size_t height) +gl::Error RenderbufferD3D::setStorage(const gl::Context *context, + GLenum internalformat, + size_t width, + size_t height) +{ + return setStorageMultisample(context, 0, internalformat, width, height); +} + +gl::Error RenderbufferD3D::setStorageMultisample(const gl::Context *context, + size_t samples, + GLenum internalformat, + size_t width, + size_t height) { // If the renderbuffer parameters are queried, the calling function // will expect one of the valid renderbuffer formats for use in @@ -48,54 +61,70 @@ gl::Error RenderbufferD3D::setStorageMultisample(size_t samples, GLenum internal // the specified storage. // Because ES 3.0 already knows the exact number of supported samples, it would already have been // validated and generated GL_INVALID_VALUE. - const gl::TextureCaps &formatCaps = mRenderer->getRendererTextureCaps().get(creationFormat); + const gl::TextureCaps &formatCaps = mRenderer->getNativeTextureCaps().get(creationFormat); if (samples > formatCaps.getMaxSamples()) { - return gl::Error(GL_OUT_OF_MEMORY, "Renderbuffer format does not support %u samples, %u is the maximum.", - samples, formatCaps.getMaxSamples()); + return gl::OutOfMemory() << "Renderbuffer format does not support " << samples + << " samples, " << formatCaps.getMaxSamples() + << " is the maximum."; } - RenderTargetD3D *newRT = NULL; - gl::Error error = - mRenderer->createRenderTarget(static_cast(width), static_cast(height), - creationFormat, static_cast(samples), &newRT); - if (error.isError()) - { - return error; - } + RenderTargetD3D *newRT = nullptr; + ANGLE_TRY(mRenderer->createRenderTarget(static_cast(width), static_cast(height), + creationFormat, static_cast(samples), &newRT)); - SafeDelete(mRenderTarget); + deleteRenderTarget(context); mImage = nullptr; mRenderTarget = newRT; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error RenderbufferD3D::setStorageEGLImageTarget(egl::Image *image) +gl::Error RenderbufferD3D::setStorageEGLImageTarget(const gl::Context *context, egl::Image *image) { mImage = GetImplAs(image); - SafeDelete(mRenderTarget); + deleteRenderTarget(context); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error RenderbufferD3D::getRenderTarget(RenderTargetD3D **outRenderTarget) +gl::Error RenderbufferD3D::getRenderTarget(const gl::Context *context, + RenderTargetD3D **outRenderTarget) { if (mImage) { - return mImage->getRenderTarget(outRenderTarget); + return mImage->getRenderTarget(context, outRenderTarget); } else { *outRenderTarget = mRenderTarget; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } } -gl::Error RenderbufferD3D::getAttachmentRenderTarget(const gl::FramebufferAttachment::Target &target, +gl::Error RenderbufferD3D::getAttachmentRenderTarget(const gl::Context *context, + GLenum /*binding*/, + const gl::ImageIndex & /*imageIndex*/, FramebufferAttachmentRenderTarget **rtOut) { - return getRenderTarget(reinterpret_cast(rtOut)); + return getRenderTarget(context, reinterpret_cast(rtOut)); } +void RenderbufferD3D::deleteRenderTarget(const gl::Context *context) +{ + if (mRenderTarget) + { + mRenderTarget->signalDirty(context); + SafeDelete(mRenderTarget); + } } + +gl::Error RenderbufferD3D::initializeContents(const gl::Context *context, + const gl::ImageIndex &imageIndex) +{ + RenderTargetD3D *renderTarget = nullptr; + ANGLE_TRY(getRenderTarget(context, &renderTarget)); + return mRenderer->initRenderTarget(renderTarget); +} + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderbufferD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderbufferD3D.h index 20f6a10b2d..b50eff7db7 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderbufferD3D.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/RenderbufferD3D.h @@ -25,20 +25,33 @@ class RenderbufferD3D : public RenderbufferImpl { public: RenderbufferD3D(RendererD3D *renderer); - virtual ~RenderbufferD3D(); + ~RenderbufferD3D() override; - gl::Error setStorage(GLenum internalformat, size_t width, size_t height) override; - gl::Error setStorageMultisample(size_t samples, + gl::Error onDestroy(const gl::Context *context) override; + + gl::Error setStorage(const gl::Context *context, + GLenum internalformat, + size_t width, + size_t height) override; + gl::Error setStorageMultisample(const gl::Context *context, + size_t samples, GLenum internalformat, size_t width, size_t height) override; - gl::Error setStorageEGLImageTarget(egl::Image *image) override; + gl::Error setStorageEGLImageTarget(const gl::Context *context, egl::Image *image) override; - gl::Error getRenderTarget(RenderTargetD3D **outRenderTarget); - gl::Error getAttachmentRenderTarget(const gl::FramebufferAttachment::Target &target, + gl::Error getRenderTarget(const gl::Context *context, RenderTargetD3D **outRenderTarget); + gl::Error getAttachmentRenderTarget(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex, FramebufferAttachmentRenderTarget **rtOut) override; + gl::Error initializeContents(const gl::Context *context, + const gl::ImageIndex &imageIndex) override; + private: + void deleteRenderTarget(const gl::Context *context); + RendererD3D *mRenderer; RenderTargetD3D *mRenderTarget; EGLImageD3D *mImage; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/RendererD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/RendererD3D.cpp index 105587f62c..2167200a91 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/RendererD3D.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/RendererD3D.cpp @@ -8,43 +8,39 @@ #include "libANGLE/renderer/d3d/RendererD3D.h" -#include "common/debug.h" #include "common/MemoryBuffer.h" +#include "common/debug.h" #include "common/utilities.h" +#include "libANGLE/Context.h" #include "libANGLE/Display.h" -#include "libANGLE/formatutils.h" #include "libANGLE/Framebuffer.h" #include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/ImageIndex.h" +#include "libANGLE/ResourceManager.h" +#include "libANGLE/State.h" +#include "libANGLE/VertexArray.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/ContextImpl.h" +#include "libANGLE/renderer/TextureImpl.h" #include "libANGLE/renderer/d3d/BufferD3D.h" #include "libANGLE/renderer/d3d/DeviceD3D.h" #include "libANGLE/renderer/d3d/DisplayD3D.h" #include "libANGLE/renderer/d3d/IndexDataManager.h" #include "libANGLE/renderer/d3d/ProgramD3D.h" #include "libANGLE/renderer/d3d/SamplerD3D.h" -#include "libANGLE/ResourceManager.h" -#include "libANGLE/State.h" -#include "libANGLE/VertexArray.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" namespace rx { -namespace -{ -// If we request a scratch buffer requesting a smaller size this many times, -// release and recreate the scratch buffer. This ensures we don't have a -// degenerate case where we are stuck hogging memory. -const int ScratchMemoryBufferLifetime = 1000; - -} // anonymous namespace - RendererD3D::RendererD3D(egl::Display *display) : mDisplay(display), - mDeviceLost(false), - mAnnotator(nullptr), mPresentPathFastEnabled(false), - mScratchMemoryBufferResetCounter(0), + mCapsInitialized(false), mWorkaroundsInitialized(false), - mDisjoint(false) + mDisjoint(false), + mDeviceLost(false), + mWorkerThreadPool(4) { } @@ -55,451 +51,29 @@ RendererD3D::~RendererD3D() void RendererD3D::cleanup() { - mScratchMemoryBuffer.resize(0); - for (auto &incompleteTexture : mIncompleteTextures) - { - incompleteTexture.second.set(NULL); - } - mIncompleteTextures.clear(); - - if (mAnnotator != nullptr) - { - gl::UninitializeDebugAnnotations(); - SafeDelete(mAnnotator); - } + mIncompleteTextures.onDestroy(mDisplay->getProxyContext()); } -SamplerImpl *RendererD3D::createSampler() +bool RendererD3D::skipDraw(const gl::State &glState, GLenum drawMode) { - return new SamplerD3D(); -} - -gl::Error RendererD3D::drawArrays(const gl::Data &data, GLenum mode, GLint first, GLsizei count) -{ - return genericDrawArrays(data, mode, first, count, 0); -} - -gl::Error RendererD3D::drawArraysInstanced(const gl::Data &data, - GLenum mode, - GLint first, - GLsizei count, - GLsizei instanceCount) -{ - return genericDrawArrays(data, mode, first, count, instanceCount); -} - -gl::Error RendererD3D::drawElements(const gl::Data &data, - GLenum mode, - GLsizei count, - GLenum type, - const GLvoid *indices, - const gl::IndexRange &indexRange) -{ - return genericDrawElements(data, mode, count, type, indices, 0, indexRange); -} - -gl::Error RendererD3D::drawElementsInstanced(const gl::Data &data, - GLenum mode, - GLsizei count, - GLenum type, - const GLvoid *indices, - GLsizei instances, - const gl::IndexRange &indexRange) -{ - return genericDrawElements(data, mode, count, type, indices, instances, indexRange); -} - -gl::Error RendererD3D::drawRangeElements(const gl::Data &data, - GLenum mode, - GLuint start, - GLuint end, - GLsizei count, - GLenum type, - const GLvoid *indices, - const gl::IndexRange &indexRange) -{ - return genericDrawElements(data, mode, count, type, indices, 0, indexRange); -} - -gl::Error RendererD3D::genericDrawElements(const gl::Data &data, - GLenum mode, - GLsizei count, - GLenum type, - const GLvoid *indices, - GLsizei instances, - const gl::IndexRange &indexRange) -{ - gl::Program *program = data.state->getProgram(); - ASSERT(program != nullptr); - ProgramD3D *programD3D = GetImplAs(program); - bool usesPointSize = programD3D->usesPointSize(); - - programD3D->updateSamplerMapping(); - - gl::Error error = generateSwizzles(data); - if (error.isError()) - { - return error; - } - - if (!applyPrimitiveType(mode, count, usesPointSize)) - { - return gl::Error(GL_NO_ERROR); - } - - error = updateState(data, mode); - if (error.isError()) - { - return error; - } - - TranslatedIndexData indexInfo; - indexInfo.indexRange = indexRange; - - error = applyIndexBuffer(data, indices, count, mode, type, &indexInfo); - if (error.isError()) - { - return error; - } - - applyTransformFeedbackBuffers(*data.state); - // Transform feedback is not allowed for DrawElements, this error should have been caught at the API validation - // layer. - ASSERT(!data.state->isTransformFeedbackActiveUnpaused()); - - size_t vertexCount = indexInfo.indexRange.vertexCount(); - error = applyVertexBuffer(*data.state, mode, static_cast(indexInfo.indexRange.start), - static_cast(vertexCount), instances, &indexInfo); - if (error.isError()) - { - return error; - } - - error = applyTextures(data); - if (error.isError()) - { - return error; - } - - error = applyShaders(data, mode); - if (error.isError()) - { - return error; - } - - error = programD3D->applyUniformBuffers(data); - if (error.isError()) - { - return error; - } - - if (!skipDraw(data, mode)) - { - error = drawElementsImpl(data, indexInfo, mode, count, type, indices, instances); - if (error.isError()) - { - return error; - } - } - - return gl::Error(GL_NO_ERROR); -} - -gl::Error RendererD3D::genericDrawArrays(const gl::Data &data, - GLenum mode, - GLint first, - GLsizei count, - GLsizei instances) -{ - gl::Program *program = data.state->getProgram(); - ASSERT(program != nullptr); - ProgramD3D *programD3D = GetImplAs(program); - bool usesPointSize = programD3D->usesPointSize(); - - programD3D->updateSamplerMapping(); - - gl::Error error = generateSwizzles(data); - if (error.isError()) - { - return error; - } - - if (!applyPrimitiveType(mode, count, usesPointSize)) - { - return gl::Error(GL_NO_ERROR); - } - - error = updateState(data, mode); - if (error.isError()) - { - return error; - } - - applyTransformFeedbackBuffers(*data.state); - - error = applyVertexBuffer(*data.state, mode, first, count, instances, nullptr); - if (error.isError()) - { - return error; - } - - error = applyTextures(data); - if (error.isError()) - { - return error; - } - - error = applyShaders(data, mode); - if (error.isError()) - { - return error; - } - - error = programD3D->applyUniformBuffers(data); - if (error.isError()) - { - return error; - } - - if (!skipDraw(data, mode)) - { - error = drawArraysImpl(data, mode, count, instances); - if (error.isError()) - { - return error; - } - - if (data.state->isTransformFeedbackActiveUnpaused()) - { - markTransformFeedbackUsage(data); - } - } - - return gl::Error(GL_NO_ERROR); -} - -gl::Error RendererD3D::generateSwizzles(const gl::Data &data, gl::SamplerType type) -{ - ProgramD3D *programD3D = GetImplAs(data.state->getProgram()); - - unsigned int samplerRange = static_cast(programD3D->getUsedSamplerRange(type)); - - for (unsigned int i = 0; i < samplerRange; i++) - { - GLenum textureType = programD3D->getSamplerTextureType(type, i); - GLint textureUnit = programD3D->getSamplerMapping(type, i, *data.caps); - if (textureUnit != -1) - { - gl::Texture *texture = data.state->getSamplerTexture(textureUnit, textureType); - ASSERT(texture); - if (texture->getTextureState().swizzleRequired()) - { - gl::Error error = generateSwizzle(texture); - if (error.isError()) - { - return error; - } - } - } - } - - return gl::Error(GL_NO_ERROR); -} - -gl::Error RendererD3D::generateSwizzles(const gl::Data &data) -{ - gl::Error error = generateSwizzles(data, gl::SAMPLER_VERTEX); - if (error.isError()) - { - return error; - } - - error = generateSwizzles(data, gl::SAMPLER_PIXEL); - if (error.isError()) - { - return error; - } - - return gl::Error(GL_NO_ERROR); -} - -unsigned int RendererD3D::GetBlendSampleMask(const gl::Data &data, int samples) -{ - unsigned int mask = 0; - if (data.state->isSampleCoverageEnabled()) - { - GLclampf coverageValue = data.state->getSampleCoverageValue(); - if (coverageValue != 0) - { - float threshold = 0.5f; - - for (int i = 0; i < samples; ++i) - { - mask <<= 1; - - if ((i + 1) * coverageValue >= threshold) - { - threshold += 1.0f; - mask |= 1; - } - } - } - - bool coverageInvert = data.state->getSampleCoverageInvert(); - if (coverageInvert) - { - mask = ~mask; - } - } - else - { - mask = 0xFFFFFFFF; - } - - return mask; -} - -// Applies the shaders and shader constants to the Direct3D device -gl::Error RendererD3D::applyShaders(const gl::Data &data, GLenum drawMode) -{ - gl::Program *program = data.state->getProgram(); - ProgramD3D *programD3D = GetImplAs(program); - programD3D->updateCachedInputLayout(*data.state); - - gl::Error error = applyShadersImpl(data, drawMode); - if (error.isError()) - { - return error; - } - - return programD3D->applyUniforms(drawMode); -} - -// For each Direct3D sampler of either the pixel or vertex stage, -// looks up the corresponding OpenGL texture image unit and texture type, -// and sets the texture and its addressing/filtering state (or NULL when inactive). -// Sampler mapping needs to be up-to-date on the program object before this is called. -gl::Error RendererD3D::applyTextures(const gl::Data &data, gl::SamplerType shaderType, - const FramebufferTextureArray &framebufferTextures, size_t framebufferTextureCount) -{ - ProgramD3D *programD3D = GetImplAs(data.state->getProgram()); - - ASSERT(!programD3D->isSamplerMappingDirty()); - - unsigned int samplerRange = programD3D->getUsedSamplerRange(shaderType); - for (unsigned int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++) - { - GLenum textureType = programD3D->getSamplerTextureType(shaderType, samplerIndex); - GLint textureUnit = programD3D->getSamplerMapping(shaderType, samplerIndex, *data.caps); - if (textureUnit != -1) - { - gl::Texture *texture = data.state->getSamplerTexture(textureUnit, textureType); - ASSERT(texture); - - gl::Sampler *samplerObject = data.state->getSampler(textureUnit); - - const gl::SamplerState &samplerState = - samplerObject ? samplerObject->getSamplerState() : texture->getSamplerState(); - - // TODO: std::binary_search may become unavailable using older versions of GCC - if (texture->isSamplerComplete(samplerState, data) && - !std::binary_search(framebufferTextures.begin(), - framebufferTextures.begin() + framebufferTextureCount, texture)) - { - gl::Error error = setSamplerState(shaderType, samplerIndex, texture, samplerState); - if (error.isError()) - { - return error; - } - - error = setTexture(shaderType, samplerIndex, texture); - if (error.isError()) - { - return error; - } - } - else - { - // Texture is not sampler complete or it is in use by the framebuffer. Bind the incomplete texture. - gl::Texture *incompleteTexture = getIncompleteTexture(textureType); - - gl::Error error = setSamplerState(shaderType, samplerIndex, incompleteTexture, - incompleteTexture->getSamplerState()); - if (error.isError()) - { - return error; - } - - error = setTexture(shaderType, samplerIndex, incompleteTexture); - if (error.isError()) - { - return error; - } - } - } - else - { - // No texture bound to this slot even though it is used by the shader, bind a NULL texture - gl::Error error = setTexture(shaderType, samplerIndex, NULL); - if (error.isError()) - { - return error; - } - } - } - - // Set all the remaining textures to NULL - size_t samplerCount = (shaderType == gl::SAMPLER_PIXEL) ? data.caps->maxTextureImageUnits - : data.caps->maxVertexTextureImageUnits; - clearTextures(shaderType, samplerRange, samplerCount); - - return gl::Error(GL_NO_ERROR); -} - -gl::Error RendererD3D::applyTextures(const gl::Data &data) -{ - FramebufferTextureArray framebufferTextures; - size_t framebufferSerialCount = getBoundFramebufferTextures(data, &framebufferTextures); - - gl::Error error = applyTextures(data, gl::SAMPLER_VERTEX, framebufferTextures, framebufferSerialCount); - if (error.isError()) - { - return error; - } - - error = applyTextures(data, gl::SAMPLER_PIXEL, framebufferTextures, framebufferSerialCount); - if (error.isError()) - { - return error; - } - - return gl::Error(GL_NO_ERROR); -} - -bool RendererD3D::skipDraw(const gl::Data &data, GLenum drawMode) -{ - const gl::State &state = *data.state; - if (drawMode == GL_POINTS) { - bool usesPointSize = GetImplAs(state.getProgram())->usesPointSize(); + bool usesPointSize = GetImplAs(glState.getProgram())->usesPointSize(); // ProgramBinary assumes non-point rendering if gl_PointSize isn't written, // which affects varying interpolation. Since the value of gl_PointSize is // undefined when not written, just skip drawing to avoid unexpected results. - if (!usesPointSize && !state.isTransformFeedbackActiveUnpaused()) + if (!usesPointSize && !glState.isTransformFeedbackActiveUnpaused()) { - // This is stictly speaking not an error, but developers should be - // notified of risking undefined behavior. - ERR("Point rendering without writing to gl_PointSize."); - + // Notify developers of risking undefined behavior. + WARN() << "Point rendering without writing to gl_PointSize."; return true; } } else if (gl::IsTriangleMode(drawMode)) { - if (state.getRasterizerState().cullFace && - state.getRasterizerState().cullMode == GL_FRONT_AND_BACK) + if (glState.getRasterizerState().cullFace && + glState.getRasterizerState().cullMode == gl::CullFaceMode::FrontAndBack) { return true; } @@ -508,161 +82,54 @@ bool RendererD3D::skipDraw(const gl::Data &data, GLenum drawMode) return false; } -void RendererD3D::markTransformFeedbackUsage(const gl::Data &data) +gl::Error RendererD3D::getIncompleteTexture(const gl::Context *context, + GLenum type, + gl::Texture **textureOut) { - const gl::TransformFeedback *transformFeedback = data.state->getCurrentTransformFeedback(); - for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++) - { - const OffsetBindingPointer &binding = transformFeedback->getIndexedBuffer(i); - if (binding.get() != nullptr) - { - BufferD3D *bufferD3D = GetImplAs(binding.get()); - bufferD3D->markTransformFeedbackUsage(); - } - } + return mIncompleteTextures.getIncompleteTexture(context, type, this, textureOut); } -size_t RendererD3D::getBoundFramebufferTextures(const gl::Data &data, FramebufferTextureArray *outTextureArray) +GLenum RendererD3D::getResetStatus() { - size_t textureCount = 0; - - const gl::Framebuffer *drawFramebuffer = data.state->getDrawFramebuffer(); - for (size_t i = 0; i < drawFramebuffer->getNumColorBuffers(); i++) + if (!mDeviceLost) { - const gl::FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(i); - if (attachment && attachment->type() == GL_TEXTURE) + if (testDeviceLost()) { - (*outTextureArray)[textureCount++] = attachment->getTexture(); + mDeviceLost = true; + notifyDeviceLost(); + return GL_UNKNOWN_CONTEXT_RESET_EXT; } + return GL_NO_ERROR; } - const gl::FramebufferAttachment *depthStencilAttachment = drawFramebuffer->getDepthOrStencilbuffer(); - if (depthStencilAttachment && depthStencilAttachment->type() == GL_TEXTURE) + if (testDeviceResettable()) { - (*outTextureArray)[textureCount++] = depthStencilAttachment->getTexture(); + return GL_NO_ERROR; } - std::sort(outTextureArray->begin(), outTextureArray->begin() + textureCount); - - return textureCount; -} - -gl::Texture *RendererD3D::getIncompleteTexture(GLenum type) -{ - if (mIncompleteTextures.find(type) == mIncompleteTextures.end()) - { - const GLubyte color[] = { 0, 0, 0, 255 }; - const gl::Extents colorSize(1, 1, 1); - const gl::PixelUnpackState unpack(1, 0); - const gl::Box area(0, 0, 0, 1, 1, 1); - - // Skip the API layer to avoid needing to pass the Context and mess with dirty bits. - gl::Texture *t = - new gl::Texture(createTexture(type), std::numeric_limits::max(), type); - t->setStorage(type, 1, GL_RGBA8, colorSize); - - if (type == GL_TEXTURE_CUBE_MAP) - { - for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; face++) - { - t->getImplementation()->setSubImage(face, 0, area, GL_RGBA8, GL_UNSIGNED_BYTE, - unpack, color); - } - } - else - { - t->getImplementation()->setSubImage(type, 0, area, GL_RGBA8, GL_UNSIGNED_BYTE, unpack, - color); - } - - mIncompleteTextures[type].set(t); - } - - return mIncompleteTextures[type].get(); -} - -bool RendererD3D::isDeviceLost() const -{ - return mDeviceLost; + return GL_UNKNOWN_CONTEXT_RESET_EXT; } void RendererD3D::notifyDeviceLost() { - mDeviceLost = true; mDisplay->notifyDeviceLost(); } std::string RendererD3D::getVendorString() const { - LUID adapterLuid = { 0 }; + LUID adapterLuid = {0}; if (getLUID(&adapterLuid)) { char adapterLuidString[64]; - sprintf_s(adapterLuidString, sizeof(adapterLuidString), "(adapter LUID: %08x%08x)", adapterLuid.HighPart, adapterLuid.LowPart); + sprintf_s(adapterLuidString, sizeof(adapterLuidString), "(adapter LUID: %08x%08x)", + adapterLuid.HighPart, adapterLuid.LowPart); return std::string(adapterLuidString); } return std::string(""); } -gl::Error RendererD3D::getScratchMemoryBuffer(size_t requestedSize, MemoryBuffer **bufferOut) -{ - if (mScratchMemoryBuffer.size() == requestedSize) - { - mScratchMemoryBufferResetCounter = ScratchMemoryBufferLifetime; - *bufferOut = &mScratchMemoryBuffer; - return gl::Error(GL_NO_ERROR); - } - - if (mScratchMemoryBuffer.size() > requestedSize) - { - mScratchMemoryBufferResetCounter--; - } - - if (mScratchMemoryBufferResetCounter <= 0 || mScratchMemoryBuffer.size() < requestedSize) - { - mScratchMemoryBuffer.resize(0); - if (!mScratchMemoryBuffer.resize(requestedSize)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal buffer."); - } - mScratchMemoryBufferResetCounter = ScratchMemoryBufferLifetime; - } - - ASSERT(mScratchMemoryBuffer.size() >= requestedSize); - - *bufferOut = &mScratchMemoryBuffer; - return gl::Error(GL_NO_ERROR); -} - -void RendererD3D::insertEventMarker(GLsizei length, const char *marker) -{ - std::vector wcstring (length + 1); - size_t convertedChars = 0; - errno_t err = mbstowcs_s(&convertedChars, wcstring.data(), length + 1, marker, _TRUNCATE); - if (err == 0) - { - getAnnotator()->setMarker(wcstring.data()); - } -} - -void RendererD3D::pushGroupMarker(GLsizei length, const char *marker) -{ - std::vector wcstring(length + 1); - size_t convertedChars = 0; - errno_t err = mbstowcs_s(&convertedChars, wcstring.data(), length + 1, marker, _TRUNCATE); - if (err == 0) - { - getAnnotator()->beginEvent(wcstring.data()); - } -} - -void RendererD3D::popGroupMarker() -{ - getAnnotator()->endEvent(); -} - void RendererD3D::setGPUDisjoint() { mDisjoint = true; @@ -684,20 +151,110 @@ GLint64 RendererD3D::getTimestamp() return 0; } -void RendererD3D::onMakeCurrent(const gl::Data &data) +void RendererD3D::ensureCapsInitialized() const { + if (!mCapsInitialized) + { + generateCaps(&mNativeCaps, &mNativeTextureCaps, &mNativeExtensions, &mNativeLimitations); + mCapsInitialized = true; + } } -void RendererD3D::initializeDebugAnnotator() +const gl::Caps &RendererD3D::getNativeCaps() const { - createAnnotator(); - ASSERT(mAnnotator); - gl::InitializeDebugAnnotations(mAnnotator); + ensureCapsInitialized(); + return mNativeCaps; } -gl::DebugAnnotator *RendererD3D::getAnnotator() +const gl::TextureCapsMap &RendererD3D::getNativeTextureCaps() const { - ASSERT(mAnnotator); - return mAnnotator; + ensureCapsInitialized(); + return mNativeTextureCaps; } + +const gl::Extensions &RendererD3D::getNativeExtensions() const +{ + ensureCapsInitialized(); + return mNativeExtensions; } + +const gl::Limitations &RendererD3D::getNativeLimitations() const +{ + ensureCapsInitialized(); + return mNativeLimitations; +} + +angle::WorkerThreadPool *RendererD3D::getWorkerThreadPool() +{ + return &mWorkerThreadPool; +} + +Serial RendererD3D::generateSerial() +{ + return mSerialFactory.generate(); +} + +bool InstancedPointSpritesActive(ProgramD3D *programD3D, GLenum mode) +{ + return programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation() && + mode == GL_POINTS; +} + +gl::Error RendererD3D::initRenderTarget(RenderTargetD3D *renderTarget) +{ + return clearRenderTarget(renderTarget, gl::ColorF(0, 0, 0, 0), 1, 0); +} + +gl::Error RendererD3D::initializeMultisampleTextureToBlack(const gl::Context *context, + gl::Texture *glTexture) +{ + ASSERT(glTexture->getTarget() == GL_TEXTURE_2D_MULTISAMPLE); + TextureD3D *textureD3D = GetImplAs(glTexture); + gl::ImageIndex index = gl::ImageIndex::Make2DMultisample(); + RenderTargetD3D *renderTarget = nullptr; + ANGLE_TRY(textureD3D->getRenderTarget(context, index, &renderTarget)); + return clearRenderTarget(renderTarget, gl::ColorF(0.0f, 0.0f, 0.0f, 1.0f), 1.0f, 0); +} + +unsigned int GetBlendSampleMask(const gl::State &glState, int samples) +{ + unsigned int mask = 0; + if (glState.isSampleCoverageEnabled()) + { + GLfloat coverageValue = glState.getSampleCoverageValue(); + if (coverageValue != 0) + { + float threshold = 0.5f; + + for (int i = 0; i < samples; ++i) + { + mask <<= 1; + + if ((i + 1) * coverageValue >= threshold) + { + threshold += 1.0f; + mask |= 1; + } + } + } + + bool coverageInvert = glState.getSampleCoverageInvert(); + if (coverageInvert) + { + mask = ~mask; + } + } + else + { + mask = 0xFFFFFFFF; + } + + if (glState.isSampleMaskEnabled()) + { + mask &= glState.getSampleMaskWord(0); + } + + return mask; +} + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/RendererD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/RendererD3D.h index f956f037e2..dcc98f2ec6 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/RendererD3D.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/RendererD3D.h @@ -9,19 +9,21 @@ #ifndef LIBANGLE_RENDERER_D3D_RENDERERD3D_H_ #define LIBANGLE_RENDERER_D3D_RENDERERD3D_H_ -#include "common/debug.h" +#include + +#include "common/Color.h" #include "common/MemoryBuffer.h" -#include "libANGLE/Data.h" +#include "common/debug.h" +#include "libANGLE/ContextState.h" #include "libANGLE/Device.h" +#include "libANGLE/Version.h" +#include "libANGLE/WorkerThread.h" +#include "libANGLE/angletypes.h" #include "libANGLE/formatutils.h" -#include "libANGLE/renderer/Renderer.h" #include "libANGLE/renderer/d3d/VertexDataManager.h" #include "libANGLE/renderer/d3d/formatutilsD3D.h" -#include "libANGLE/renderer/d3d/WorkaroundsD3D.h" -#include "libANGLE/renderer/d3d/d3d11/NativeWindow.h" - -//FIXME(jmadill): std::array is currently prohibited by Chromium style guide -#include +#include "libANGLE/renderer/renderer_utils.h" +#include "platform/WorkaroundsD3D.h" namespace egl { @@ -30,7 +32,7 @@ class ConfigSet; namespace gl { -class DebugAnnotator; +class FramebufferState; class InfoLog; class Texture; struct LinkedVarying; @@ -38,28 +40,24 @@ struct LinkedVarying; namespace rx { +class ContextImpl; struct D3DUniform; struct D3DVarying; class DeviceD3D; class EGLImageD3D; +class FramebufferImpl; class ImageD3D; class IndexBuffer; +class NativeWindowD3D; class ProgramD3D; class RenderTargetD3D; class ShaderExecutableD3D; class SwapChainD3D; class TextureStorage; +struct TranslatedIndexData; class UniformStorageD3D; class VertexBuffer; -enum ShaderType -{ - SHADER_VERTEX, - SHADER_PIXEL, - SHADER_GEOMETRY, - SHADER_TYPE_MAX -}; - struct DeviceIdentifier { UINT VendorId; @@ -76,7 +74,7 @@ enum RendererClass }; // Useful for unit testing -class BufferFactoryD3D +class BufferFactoryD3D : angle::NonCopyable { public: BufferFactoryD3D() {} @@ -88,52 +86,32 @@ class BufferFactoryD3D // TODO(jmadill): add VertexFormatCaps virtual VertexConversionType getVertexConversionType(gl::VertexFormatType vertexFormatType) const = 0; virtual GLenum getVertexComponentType(gl::VertexFormatType vertexFormatType) const = 0; + + // Warning: you should ensure binding really matches attrib.bindingIndex before using this + // function. + virtual gl::ErrorOrResult getVertexSpaceRequired( + const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + GLsizei count, + GLsizei instances) const = 0; }; -class RendererD3D : public Renderer, public BufferFactoryD3D +using AttribIndexArray = std::array; + +class RendererD3D : public BufferFactoryD3D, public MultisampleTextureInitializer { public: explicit RendererD3D(egl::Display *display); - virtual ~RendererD3D(); + ~RendererD3D() override; virtual egl::Error initialize() = 0; - virtual egl::ConfigSet generateConfigs() const = 0; + virtual egl::ConfigSet generateConfigs() = 0; virtual void generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const = 0; - gl::Error drawArrays(const gl::Data &data, GLenum mode, GLint first, GLsizei count) override; - gl::Error drawArraysInstanced(const gl::Data &data, - GLenum mode, - GLint first, - GLsizei count, - GLsizei instanceCount) override; + virtual ContextImpl *createContext(const gl::ContextState &state) = 0; - gl::Error drawElements(const gl::Data &data, - GLenum mode, - GLsizei count, - GLenum type, - const GLvoid *indices, - const gl::IndexRange &indexRange) override; - gl::Error drawElementsInstanced(const gl::Data &data, - GLenum mode, - GLsizei count, - GLenum type, - const GLvoid *indices, - GLsizei instances, - const gl::IndexRange &indexRange) override; - gl::Error drawRangeElements(const gl::Data &data, - GLenum mode, - GLuint start, - GLuint end, - GLsizei count, - GLenum type, - const GLvoid *indices, - const gl::IndexRange &indexRange) override; - - bool isDeviceLost() const override; - std::string getVendorString() const override; - - SamplerImpl *createSampler() override; + std::string getVendorString() const; virtual int getMinorShaderModel() const = 0; virtual std::string getShaderModelSuffix() const = 0; @@ -141,204 +119,241 @@ class RendererD3D : public Renderer, public BufferFactoryD3D // Direct3D Specific methods virtual DeviceIdentifier getAdapterIdentifier() const = 0; - virtual SwapChainD3D *createSwapChain(NativeWindow nativeWindow, + virtual bool isValidNativeWindow(EGLNativeWindowType window) const = 0; + virtual NativeWindowD3D *createNativeWindow(EGLNativeWindowType window, + const egl::Config *config, + const egl::AttributeMap &attribs) const = 0; + + virtual SwapChainD3D *createSwapChain(NativeWindowD3D *nativeWindow, HANDLE shareHandle, + IUnknown *d3dTexture, GLenum backBufferFormat, GLenum depthBufferFormat, - EGLint orientation) = 0; - - virtual gl::Error generateSwizzle(gl::Texture *texture) = 0; - virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler) = 0; - virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture) = 0; - - virtual gl::Error setUniformBuffers(const gl::Data &data, - const std::vector &vertexUniformBuffers, - const std::vector &fragmentUniformBuffers) = 0; - - virtual gl::Error updateState(const gl::Data &data, GLenum drawMode) = 0; - - virtual gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) = 0; - virtual gl::Error applyUniforms(const ProgramD3D &programD3D, - GLenum drawMode, - const std::vector &uniformArray) = 0; - virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize) = 0; - virtual gl::Error applyVertexBuffer(const gl::State &state, - GLenum mode, - GLint first, - GLsizei count, - GLsizei instances, - TranslatedIndexData *indexInfo) = 0; - virtual gl::Error applyIndexBuffer(const gl::Data &data, - const GLvoid *indices, - GLsizei count, - GLenum mode, - GLenum type, - TranslatedIndexData *indexInfo) = 0; - virtual void applyTransformFeedbackBuffers(const gl::State& state) = 0; - - virtual unsigned int getReservedVertexUniformVectors() const = 0; - virtual unsigned int getReservedFragmentUniformVectors() const = 0; - virtual unsigned int getReservedVertexUniformBuffers() const = 0; - virtual unsigned int getReservedFragmentUniformBuffers() const = 0; + EGLint orientation, + EGLint samples) = 0; + virtual egl::Error getD3DTextureInfo(const egl::Config *configuration, + IUnknown *d3dTexture, + EGLint *width, + EGLint *height, + GLenum *fboFormat) const = 0; + virtual egl::Error validateShareHandle(const egl::Config *config, + HANDLE shareHandle, + const egl::AttributeMap &attribs) const = 0; virtual int getMajorShaderModel() const = 0; - const WorkaroundsD3D &getWorkarounds() const; + const angle::WorkaroundsD3D &getWorkarounds() const; // Pixel operations - virtual gl::Error copyImage2D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLint level) = 0; - virtual gl::Error copyImageCube(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLenum target, GLint level) = 0; - virtual gl::Error copyImage3D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLint level) = 0; - virtual gl::Error copyImage2DArray(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLint level) = 0; + virtual gl::Error copyImage2D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) = 0; + virtual gl::Error copyImageCube(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLenum target, + GLint level) = 0; + virtual gl::Error copyImage3D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) = 0; + virtual gl::Error copyImage2DArray(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) = 0; + + virtual gl::Error copyTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLenum destTarget, + GLint destLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) = 0; + virtual gl::Error copyCompressedTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + TextureStorage *storage, + GLint destLevel) = 0; // RenderTarget creation virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT) = 0; virtual gl::Error createRenderTargetCopy(RenderTargetD3D *source, RenderTargetD3D **outRT) = 0; // Shader operations - virtual gl::Error loadExecutable(const void *function, + virtual gl::Error loadExecutable(const uint8_t *function, size_t length, - ShaderType type, + gl::ShaderType type, const std::vector &streamOutVaryings, bool separatedOutputBuffers, - ShaderExecutableD3D **outExecutable) = 0; + ShaderExecutableD3D **outExecutable) = 0; virtual gl::Error compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, - ShaderType type, + gl::ShaderType type, const std::vector &streamOutVaryings, bool separatedOutputBuffers, - const D3DCompilerWorkarounds &workarounds, + const angle::CompilerWorkaroundsD3D &workarounds, ShaderExecutableD3D **outExectuable) = 0; + virtual gl::Error ensureHLSLCompilerInitialized() = 0; + virtual UniformStorageD3D *createUniformStorage(size_t storageSize) = 0; // Image operations virtual ImageD3D *createImage() = 0; - virtual gl::Error generateMipmap(ImageD3D *dest, ImageD3D *source) = 0; - virtual gl::Error generateMipmapsUsingD3D(TextureStorage *storage, - const gl::TextureState &textureState) = 0; + virtual gl::Error generateMipmap(const gl::Context *context, + ImageD3D *dest, + ImageD3D *source) = 0; + virtual gl::Error generateMipmapUsingD3D(const gl::Context *context, + TextureStorage *storage, + const gl::TextureState &textureState) = 0; + virtual gl::Error copyImage(const gl::Context *context, + ImageD3D *dest, + ImageD3D *source, + const gl::Rectangle &sourceRect, + const gl::Offset &destOffset, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) = 0; virtual TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain) = 0; - virtual TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage) = 0; + virtual TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage, + RenderTargetD3D *renderTargetD3D) = 0; + virtual TextureStorage *createTextureStorageExternal( + egl::Stream *stream, + const egl::Stream::GLTextureDescription &desc) = 0; virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly) = 0; virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly) = 0; virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0; virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) = 0; + virtual TextureStorage *createTextureStorage2DMultisample(GLenum internalformat, + GLsizei width, + GLsizei height, + int levels, + int samples, + bool fixedSampleLocations) = 0; // Buffer-to-texture and Texture-to-buffer copies virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const = 0; - virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget, - GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) = 0; + virtual gl::Error fastCopyBufferToTexture(const gl::Context *context, + const gl::PixelUnpackState &unpack, + unsigned int offset, + RenderTargetD3D *destRenderTarget, + GLenum destinationFormat, + GLenum sourcePixelsType, + const gl::Box &destArea) = 0; // Device lost - void notifyDeviceLost() override; + GLenum getResetStatus(); + void notifyDeviceLost(); virtual bool resetDevice() = 0; + virtual bool testDeviceLost() = 0; + virtual bool testDeviceResettable() = 0; + virtual RendererClass getRendererClass() const = 0; virtual void *getD3DDevice() = 0; - gl::Error getScratchMemoryBuffer(size_t requestedSize, MemoryBuffer **bufferOut); - - // EXT_debug_marker - void insertEventMarker(GLsizei length, const char *marker) override; - void pushGroupMarker(GLsizei length, const char *marker) override; - void popGroupMarker() override; - void setGPUDisjoint(); - GLint getGPUDisjoint() override; - GLint64 getTimestamp() override; + GLint getGPUDisjoint(); + GLint64 getTimestamp(); - void onMakeCurrent(const gl::Data &data) override; - - // In D3D11, faster than calling setTexture a jillion times - virtual gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) = 0; + virtual gl::Error clearRenderTarget(RenderTargetD3D *renderTarget, + const gl::ColorF &clearColorValue, + const float clearDepthValue, + const unsigned int clearStencilValue) = 0; virtual egl::Error getEGLDevice(DeviceImpl **device) = 0; bool presentPathFastEnabled() const { return mPresentPathFastEnabled; } + // Stream creation + virtual StreamProducerImpl *createStreamProducerD3DTextureNV12( + egl::Stream::ConsumerType consumerType, + const egl::AttributeMap &attribs) = 0; + + const gl::Caps &getNativeCaps() const; + const gl::TextureCapsMap &getNativeTextureCaps() const; + const gl::Extensions &getNativeExtensions() const; + const gl::Limitations &getNativeLimitations() const; + + // Necessary hack for default framebuffers in D3D. + virtual FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) = 0; + + virtual gl::Version getMaxSupportedESVersion() const = 0; + + gl::Error initRenderTarget(RenderTargetD3D *renderTarget); + + angle::WorkerThreadPool *getWorkerThreadPool(); + + gl::Error getIncompleteTexture(const gl::Context *context, + GLenum type, + gl::Texture **textureOut); + + Serial generateSerial(); + + virtual bool canSelectViewInVertexShader() const = 0; + + gl::Error initializeMultisampleTextureToBlack(const gl::Context *context, + gl::Texture *glTexture) override; + protected: virtual bool getLUID(LUID *adapterLuid) const = 0; - virtual gl::Error applyShadersImpl(const gl::Data &data, GLenum drawMode) = 0; + virtual void generateCaps(gl::Caps *outCaps, + gl::TextureCapsMap *outTextureCaps, + gl::Extensions *outExtensions, + gl::Limitations *outLimitations) const = 0; void cleanup(); - virtual void createAnnotator() = 0; - - static unsigned int GetBlendSampleMask(const gl::Data &data, int samples); - // dirtyPointer is a special value that will make the comparison with any valid pointer fail and force the renderer to re-apply the state. + bool skipDraw(const gl::State &glState, GLenum drawMode); egl::Display *mDisplay; - bool mDeviceLost; - - void initializeDebugAnnotator(); - gl::DebugAnnotator *mAnnotator; - - std::vector mTranslatedAttribCache; bool mPresentPathFastEnabled; private: - gl::Error genericDrawArrays(const gl::Data &data, - GLenum mode, - GLint first, - GLsizei count, - GLsizei instances); + void ensureCapsInitialized() const; - gl::Error genericDrawElements(const gl::Data &data, - GLenum mode, - GLsizei count, - GLenum type, - const GLvoid *indices, - GLsizei instances, - const gl::IndexRange &indexRange); + virtual angle::WorkaroundsD3D generateWorkarounds() const = 0; - virtual gl::Error drawArraysImpl(const gl::Data &data, - GLenum mode, - GLsizei count, - GLsizei instances) = 0; - virtual gl::Error drawElementsImpl(const gl::Data &data, - const TranslatedIndexData &indexInfo, - GLenum mode, - GLsizei count, - GLenum type, - const GLvoid *indices, - GLsizei instances) = 0; + mutable bool mCapsInitialized; + mutable gl::Caps mNativeCaps; + mutable gl::TextureCapsMap mNativeTextureCaps; + mutable gl::Extensions mNativeExtensions; + mutable gl::Limitations mNativeLimitations; - //FIXME(jmadill): std::array is currently prohibited by Chromium style guide - typedef std::array FramebufferTextureArray; - - gl::Error generateSwizzles(const gl::Data &data, gl::SamplerType type); - gl::Error generateSwizzles(const gl::Data &data); - - gl::Error applyState(const gl::Data &data, GLenum drawMode); - gl::Error applyShaders(const gl::Data &data, GLenum drawMode); - gl::Error applyTextures(const gl::Data &data, gl::SamplerType shaderType, - const FramebufferTextureArray &framebufferTextures, size_t framebufferTextureCount); - gl::Error applyTextures(const gl::Data &data); - - bool skipDraw(const gl::Data &data, GLenum drawMode); - void markTransformFeedbackUsage(const gl::Data &data); - - size_t getBoundFramebufferTextures(const gl::Data &data, FramebufferTextureArray *outTextureArray); - gl::Texture *getIncompleteTexture(GLenum type); - - gl::DebugAnnotator *getAnnotator(); - - virtual WorkaroundsD3D generateWorkarounds() const = 0; - - gl::TextureMap mIncompleteTextures; - MemoryBuffer mScratchMemoryBuffer; - unsigned int mScratchMemoryBufferResetCounter; + IncompleteTextureSet mIncompleteTextures; mutable bool mWorkaroundsInitialized; - mutable WorkaroundsD3D mWorkarounds; + mutable angle::WorkaroundsD3D mWorkarounds; bool mDisjoint; + bool mDeviceLost; + + angle::WorkerThreadPool mWorkerThreadPool; + + SerialFactory mSerialFactory; }; -} +unsigned int GetBlendSampleMask(const gl::State &glState, int samples); +bool InstancedPointSpritesActive(ProgramD3D *programD3D, GLenum mode); + +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_RENDERERD3D_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SamplerD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SamplerD3D.h index 7aabdc8132..3f8f5b9d8d 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SamplerD3D.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SamplerD3D.h @@ -17,7 +17,7 @@ namespace rx class SamplerD3D : public SamplerImpl { public: - SamplerD3D() {} + SamplerD3D(const gl::SamplerState &state) : SamplerImpl(state) {} ~SamplerD3D() override {} }; } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderD3D.cpp index 1ecbfb7410..2a8f1fb11c 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderD3D.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderD3D.cpp @@ -9,9 +9,11 @@ #include "libANGLE/renderer/d3d/ShaderD3D.h" #include "common/utilities.h" +#include "libANGLE/Caps.h" #include "libANGLE/Compiler.h" #include "libANGLE/Shader.h" #include "libANGLE/features.h" +#include "libANGLE/renderer/d3d/ProgramD3D.h" #include "libANGLE/renderer/d3d/RendererD3D.h" // Definitions local to the translation unit @@ -28,6 +30,9 @@ const char *GetShaderTypeString(GLenum type) case GL_FRAGMENT_SHADER: return "FRAGMENT"; + case GL_COMPUTE_SHADER: + return "COMPUTE"; + default: UNREACHABLE(); return ""; @@ -39,9 +44,39 @@ const char *GetShaderTypeString(GLenum type) namespace rx { -ShaderD3D::ShaderD3D(const gl::Shader::Data &data) : ShaderImpl(data) +ShaderD3D::ShaderD3D(const gl::ShaderState &data, + const angle::WorkaroundsD3D &workarounds, + const gl::Extensions &extensions) + : ShaderImpl(data), mAdditionalOptions(0) { uncompile(); + + if (workarounds.expandIntegerPowExpressions) + { + mAdditionalOptions |= SH_EXPAND_SELECT_HLSL_INTEGER_POW_EXPRESSIONS; + } + + if (workarounds.getDimensionsIgnoresBaseLevel) + { + mAdditionalOptions |= SH_HLSL_GET_DIMENSIONS_IGNORES_BASE_LEVEL; + } + + if (workarounds.preAddTexelFetchOffsets) + { + mAdditionalOptions |= SH_REWRITE_TEXELFETCHOFFSET_TO_TEXELFETCH; + } + if (workarounds.rewriteUnaryMinusOperator) + { + mAdditionalOptions |= SH_REWRITE_INTEGER_UNARY_MINUS_OPERATOR; + } + if (workarounds.emulateIsnanFloat) + { + mAdditionalOptions |= SH_EMULATE_ISNAN_FLOAT_FUNCTION; + } + if (extensions.multiview) + { + mAdditionalOptions |= SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW; + } } ShaderD3D::~ShaderD3D() @@ -50,6 +85,11 @@ ShaderD3D::~ShaderD3D() std::string ShaderD3D::getDebugInfo() const { + if (mDebugInfo.empty()) + { + return ""; + } + return mDebugInfo + std::string("\n// ") + GetShaderTypeString(mData.getShaderType()) + " SHADER END\n"; } @@ -69,15 +109,16 @@ void ShaderD3D::uncompile() mUsesPointCoord = false; mUsesDepthRange = false; mUsesFragDepth = false; + mHasANGLEMultiviewEnabled = false; + mUsesViewID = false; mUsesDiscardRewriting = false; mUsesNestedBreak = false; - mUsesDeferredInit = false; mRequiresIEEEStrictCompiling = false; mDebugInfo.clear(); } -void ShaderD3D::generateWorkarounds(D3DCompilerWorkarounds *workarounds) const +void ShaderD3D::generateWorkarounds(angle::CompilerWorkaroundsD3D *workarounds) const { if (mUsesDiscardRewriting) { @@ -106,10 +147,10 @@ unsigned int ShaderD3D::getUniformRegister(const std::string &uniformName) const return mUniformRegisterMap.find(uniformName)->second; } -unsigned int ShaderD3D::getInterfaceBlockRegister(const std::string &blockName) const +unsigned int ShaderD3D::getUniformBlockRegister(const std::string &blockName) const { - ASSERT(mInterfaceBlockRegisterMap.count(blockName) > 0); - return mInterfaceBlockRegisterMap.find(blockName)->second; + ASSERT(mUniformBlockRegisterMap.count(blockName) > 0); + return mUniformBlockRegisterMap.find(blockName)->second; } ShShaderOutput ShaderD3D::getCompilerOutputType() const @@ -117,12 +158,12 @@ ShShaderOutput ShaderD3D::getCompilerOutputType() const return mCompilerOutputType; } -int ShaderD3D::prepareSourceAndReturnOptions(std::stringstream *shaderSourceStream, - std::string *sourcePath) +ShCompileOptions ShaderD3D::prepareSourceAndReturnOptions(std::stringstream *shaderSourceStream, + std::string *sourcePath) { uncompile(); - int additionalOptions = 0; + ShCompileOptions additionalOptions = 0; const std::string &source = mData.getSource(); @@ -135,10 +176,24 @@ int ShaderD3D::prepareSourceAndReturnOptions(std::stringstream *shaderSourceStre } #endif + additionalOptions |= mAdditionalOptions; + *shaderSourceStream << source; return additionalOptions; } +bool ShaderD3D::hasUniform(const std::string &name) const +{ + return mUniformRegisterMap.find(name) != mUniformRegisterMap.end(); +} + +const std::map &GetUniformRegisterMap( + const std::map *uniformRegisterMap) +{ + ASSERT(uniformRegisterMap); + return *uniformRegisterMap; +} + bool ShaderD3D::postTranslateCompile(gl::Compiler *compiler, std::string *infoLog) { // TODO(jmadill): We shouldn't need to cache this. @@ -154,41 +209,30 @@ bool ShaderD3D::postTranslateCompile(gl::Compiler *compiler, std::string *infoLo mUsesPointSize = translatedSource.find("GL_USES_POINT_SIZE") != std::string::npos; mUsesPointCoord = translatedSource.find("GL_USES_POINT_COORD") != std::string::npos; mUsesDepthRange = translatedSource.find("GL_USES_DEPTH_RANGE") != std::string::npos; - mUsesFragDepth = translatedSource.find("GL_USES_FRAG_DEPTH") != std::string::npos; + mUsesFragDepth = translatedSource.find("GL_USES_FRAG_DEPTH") != std::string::npos; + mHasANGLEMultiviewEnabled = + translatedSource.find("GL_ANGLE_MULTIVIEW_ENABLED") != std::string::npos; + mUsesViewID = translatedSource.find("GL_USES_VIEW_ID") != std::string::npos; mUsesDiscardRewriting = translatedSource.find("ANGLE_USES_DISCARD_REWRITING") != std::string::npos; mUsesNestedBreak = translatedSource.find("ANGLE_USES_NESTED_BREAK") != std::string::npos; - mUsesDeferredInit = translatedSource.find("ANGLE_USES_DEFERRED_INIT") != std::string::npos; mRequiresIEEEStrictCompiling = translatedSource.find("ANGLE_REQUIRES_IEEE_STRICT_COMPILING") != std::string::npos; ShHandle compilerHandle = compiler->getCompilerHandle(mData.getShaderType()); - for (const sh::Uniform &uniform : mData.getUniforms()) - { - if (uniform.staticUse && !uniform.isBuiltIn()) - { - unsigned int index = static_cast(-1); - bool getUniformRegisterResult = - ShGetUniformRegister(compilerHandle, uniform.name, &index); - UNUSED_ASSERTION_VARIABLE(getUniformRegisterResult); - ASSERT(getUniformRegisterResult); + mUniformRegisterMap = GetUniformRegisterMap(sh::GetUniformRegisterMap(compilerHandle)); - mUniformRegisterMap[uniform.name] = index; - } - } - - for (const sh::InterfaceBlock &interfaceBlock : mData.getInterfaceBlocks()) + for (const sh::InterfaceBlock &interfaceBlock : mData.getUniformBlocks()) { if (interfaceBlock.staticUse) { unsigned int index = static_cast(-1); bool blockRegisterResult = - ShGetInterfaceBlockRegister(compilerHandle, interfaceBlock.name, &index); - UNUSED_ASSERTION_VARIABLE(blockRegisterResult); + sh::GetUniformBlockRegister(compilerHandle, interfaceBlock.name, &index); ASSERT(blockRegisterResult); - mInterfaceBlockRegisterMap[interfaceBlock.name] = index; + mUniformBlockRegisterMap[interfaceBlock.name] = index; } } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderD3D.h index 47a73dc27b..f7b0b20db4 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderD3D.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderD3D.h @@ -13,31 +13,50 @@ #include +namespace angle +{ +struct CompilerWorkaroundsD3D; +struct WorkaroundsD3D; +} + +namespace gl +{ +struct Extensions; +} + namespace rx { class DynamicHLSL; class RendererD3D; -struct D3DCompilerWorkarounds; +struct D3DUniform; class ShaderD3D : public ShaderImpl { public: - ShaderD3D(const gl::Shader::Data &data); - virtual ~ShaderD3D(); + ShaderD3D(const gl::ShaderState &data, + const angle::WorkaroundsD3D &workarounds, + const gl::Extensions &extensions); + ~ShaderD3D() override; // ShaderImpl implementation - int prepareSourceAndReturnOptions(std::stringstream *sourceStream, - std::string *sourcePath) override; + ShCompileOptions prepareSourceAndReturnOptions(std::stringstream *sourceStream, + std::string *sourcePath) override; bool postTranslateCompile(gl::Compiler *compiler, std::string *infoLog) override; std::string getDebugInfo() const override; // D3D-specific methods void uncompile(); + + bool hasUniform(const std::string &name) const; + + // Query regular uniforms with their name. Query sampler fields of structs with field selection + // using dot (.) operator. unsigned int getUniformRegister(const std::string &uniformName) const; - unsigned int getInterfaceBlockRegister(const std::string &blockName) const; + + unsigned int getUniformBlockRegister(const std::string &blockName) const; void appendDebugInfo(const std::string &info) const { mDebugInfo += info; } - void generateWorkarounds(D3DCompilerWorkarounds *workarounds) const; + void generateWorkarounds(angle::CompilerWorkaroundsD3D *workarounds) const; bool usesMultipleRenderTargets() const { return mUsesMultipleRenderTargets; } bool usesFragColor() const { return mUsesFragColor; } @@ -48,7 +67,8 @@ class ShaderD3D : public ShaderImpl bool usesPointCoord() const { return mUsesPointCoord; } bool usesDepthRange() const { return mUsesDepthRange; } bool usesFragDepth() const { return mUsesFragDepth; } - bool usesDeferredInit() const { return mUsesDeferredInit; } + bool usesViewID() const { return mUsesViewID; } + bool hasANGLEMultiviewEnabled() const { return mHasANGLEMultiviewEnabled; } ShShaderOutput getCompilerOutputType() const; @@ -62,16 +82,18 @@ class ShaderD3D : public ShaderImpl bool mUsesPointCoord; bool mUsesDepthRange; bool mUsesFragDepth; + bool mHasANGLEMultiviewEnabled; + bool mUsesViewID; bool mUsesDiscardRewriting; bool mUsesNestedBreak; - bool mUsesDeferredInit; bool mRequiresIEEEStrictCompiling; ShShaderOutput mCompilerOutputType; mutable std::string mDebugInfo; std::map mUniformRegisterMap; - std::map mInterfaceBlockRegisterMap; + std::map mUniformBlockRegisterMap; + ShCompileOptions mAdditionalOptions; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_SHADERD3D_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderExecutableD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderExecutableD3D.cpp index 97ffdf5094..83a66bd1a5 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderExecutableD3D.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderExecutableD3D.cpp @@ -44,9 +44,13 @@ void ShaderExecutableD3D::appendDebugInfo(const std::string &info) mDebugInfo += info; } - -UniformStorageD3D::UniformStorageD3D(size_t initialSize) : mSize(initialSize) +UniformStorageD3D::UniformStorageD3D(size_t initialSize) : mUniformData() { + bool result = mUniformData.resize(initialSize); + ASSERT(result); + + // Uniform data is zero-initialized by default. + mUniformData.fill(0); } UniformStorageD3D::~UniformStorageD3D() @@ -55,7 +59,13 @@ UniformStorageD3D::~UniformStorageD3D() size_t UniformStorageD3D::size() const { - return mSize; + return mUniformData.size(); } +uint8_t *UniformStorageD3D::getDataPointer(unsigned int registerIndex, unsigned int registerElement) +{ + size_t offset = ((registerIndex * 4 + registerElement) * sizeof(float)); + return mUniformData.data() + offset; } + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderExecutableD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderExecutableD3D.h index 71b83b7954..b8097710e2 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderExecutableD3D.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/ShaderExecutableD3D.h @@ -10,6 +10,7 @@ #ifndef LIBANGLE_RENDERER_D3D_SHADEREXECUTABLED3D_H_ #define LIBANGLE_RENDERER_D3D_SHADEREXECUTABLED3D_H_ +#include "common/MemoryBuffer.h" #include "common/debug.h" #include @@ -45,10 +46,12 @@ class UniformStorageD3D : angle::NonCopyable size_t size() const; + uint8_t *getDataPointer(unsigned int registerIndex, unsigned int registerElement); + private: - size_t mSize; + angle::MemoryBuffer mUniformData; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_SHADEREXECUTABLED3D_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp index f567f47525..7657aef79e 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp @@ -8,10 +8,11 @@ #include "libANGLE/renderer/d3d/SurfaceD3D.h" +#include "libANGLE/Context.h" #include "libANGLE/Display.h" #include "libANGLE/Surface.h" -#include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/RenderTargetD3D.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/SwapChainD3D.h" #include @@ -21,60 +22,62 @@ namespace rx { -SurfaceD3D *SurfaceD3D::createOffscreen(RendererD3D *renderer, egl::Display *display, const egl::Config *config, EGLClientBuffer shareHandle, - EGLint width, EGLint height) -{ - return new SurfaceD3D(renderer, display, config, width, height, EGL_TRUE, 0, EGL_FALSE, - shareHandle, NULL); -} - -SurfaceD3D *SurfaceD3D::createFromWindow(RendererD3D *renderer, - egl::Display *display, - const egl::Config *config, - EGLNativeWindowType window, - EGLint fixedSize, - EGLint directComposition, - EGLint width, - EGLint height, - EGLint orientation) -{ - return new SurfaceD3D(renderer, display, config, width, height, fixedSize, orientation, - directComposition, static_cast(0), window); -} - -SurfaceD3D::SurfaceD3D(RendererD3D *renderer, +SurfaceD3D::SurfaceD3D(const egl::SurfaceState &state, + RendererD3D *renderer, egl::Display *display, - const egl::Config *config, - EGLint width, - EGLint height, - EGLint fixedSize, - EGLint orientation, - EGLint directComposition, - EGLClientBuffer shareHandle, - EGLNativeWindowType window) - : SurfaceImpl(), + EGLNativeWindowType window, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const egl::AttributeMap &attribs) + : SurfaceImpl(state), mRenderer(renderer), mDisplay(display), - mFixedSize(fixedSize == EGL_TRUE), - mOrientation(orientation), - mRenderTargetFormat(config->renderTargetFormat), - mDepthStencilFormat(config->depthStencilFormat), + mFixedSize(window == nullptr || attribs.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE) == EGL_TRUE), + mOrientation(static_cast(attribs.get(EGL_SURFACE_ORIENTATION_ANGLE, 0))), + mRenderTargetFormat(state.config->renderTargetFormat), + mDepthStencilFormat(state.config->depthStencilFormat), mSwapChain(nullptr), mSwapIntervalDirty(true), mWindowSubclassed(false), - mNativeWindow(window, config, directComposition == EGL_TRUE), - mWidth(width), - mHeight(height), + mNativeWindow(renderer->createNativeWindow(window, state.config, attribs)), + mWidth(static_cast(attribs.get(EGL_WIDTH, 0))), + mHeight(static_cast(attribs.get(EGL_HEIGHT, 0))), mSwapInterval(1), - mShareHandle(reinterpret_cast(shareHandle)) + mShareHandle(0), + mD3DTexture(nullptr) { subclassWindow(); + if (window != nullptr && !mFixedSize) + { + mWidth = -1; + mHeight = -1; + } + + switch (buftype) + { + case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE: + mShareHandle = static_cast(clientBuffer); + break; + + case EGL_D3D_TEXTURE_ANGLE: + mD3DTexture = static_cast(clientBuffer); + ASSERT(mD3DTexture != nullptr); + mD3DTexture->AddRef(); + ANGLE_SWALLOW_ERR(mRenderer->getD3DTextureInfo(state.config, mD3DTexture, &mWidth, + &mHeight, &mRenderTargetFormat)); + break; + + default: + break; + } } SurfaceD3D::~SurfaceD3D() { unsubclassWindow(); releaseSwapChain(); + SafeDelete(mNativeWindow); + SafeRelease(mD3DTexture); } void SurfaceD3D::releaseSwapChain() @@ -82,41 +85,41 @@ void SurfaceD3D::releaseSwapChain() SafeDelete(mSwapChain); } -egl::Error SurfaceD3D::initialize() +egl::Error SurfaceD3D::initialize(const egl::Display *display) { - if (mNativeWindow.getNativeWindow()) + if (mNativeWindow->getNativeWindow()) { - if (!mNativeWindow.initialize()) + if (!mNativeWindow->initialize()) { - return egl::Error(EGL_BAD_SURFACE); + return egl::EglBadSurface(); } } - egl::Error error = resetSwapChain(); - if (error.isError()) - { - return error; - } - - return egl::Error(EGL_SUCCESS); + ANGLE_TRY(resetSwapChain(display)); + return egl::NoError(); } -FramebufferImpl *SurfaceD3D::createDefaultFramebuffer(const gl::Framebuffer::Data &data) +FramebufferImpl *SurfaceD3D::createDefaultFramebuffer(const gl::FramebufferState &data) { - return mRenderer->createFramebuffer(data); + return mRenderer->createDefaultFramebuffer(data); } egl::Error SurfaceD3D::bindTexImage(gl::Texture *, EGLint) { - return egl::Error(EGL_SUCCESS); + return egl::NoError(); } egl::Error SurfaceD3D::releaseTexImage(EGLint) { - return egl::Error(EGL_SUCCESS); + return egl::NoError(); } -egl::Error SurfaceD3D::resetSwapChain() +egl::Error SurfaceD3D::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) +{ + return mSwapChain->getSyncValues(ust, msc, sbc); +} + +egl::Error SurfaceD3D::resetSwapChain(const egl::Display *display) { ASSERT(!mSwapChain); @@ -126,11 +129,11 @@ egl::Error SurfaceD3D::resetSwapChain() if (!mFixedSize) { RECT windowRect; - if (!mNativeWindow.getClientRect(&windowRect)) + if (!mNativeWindow->getClientRect(&windowRect)) { ASSERT(false); - return egl::Error(EGL_BAD_SURFACE, "Could not retrieve the window dimensions"); + return egl::EglBadSurface() << "Could not retrieve the window dimensions"; } width = windowRect.right - windowRect.left; @@ -143,29 +146,34 @@ egl::Error SurfaceD3D::resetSwapChain() height = mHeight; } - mSwapChain = mRenderer->createSwapChain(mNativeWindow, mShareHandle, mRenderTargetFormat, - mDepthStencilFormat, mOrientation); + mSwapChain = + mRenderer->createSwapChain(mNativeWindow, mShareHandle, mD3DTexture, mRenderTargetFormat, + mDepthStencilFormat, mOrientation, mState.config->samples); if (!mSwapChain) { - return egl::Error(EGL_BAD_ALLOC); + return egl::EglBadAlloc(); } - egl::Error error = resetSwapChain(width, height); + // This is a bit risky to pass the proxy context here, but it can happen at almost any time. + egl::Error error = resetSwapChain(display->getProxyContext(), width, height); if (error.isError()) { SafeDelete(mSwapChain); return error; } - return egl::Error(EGL_SUCCESS); + return egl::NoError(); } -egl::Error SurfaceD3D::resizeSwapChain(int backbufferWidth, int backbufferHeight) +egl::Error SurfaceD3D::resizeSwapChain(const gl::Context *context, + int backbufferWidth, + int backbufferHeight) { ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0); ASSERT(mSwapChain); - EGLint status = mSwapChain->resize(std::max(1, backbufferWidth), std::max(1, backbufferHeight)); + EGLint status = + mSwapChain->resize(context, std::max(1, backbufferWidth), std::max(1, backbufferHeight)); if (status == EGL_CONTEXT_LOST) { @@ -180,15 +188,18 @@ egl::Error SurfaceD3D::resizeSwapChain(int backbufferWidth, int backbufferHeight mWidth = backbufferWidth; mHeight = backbufferHeight; - return egl::Error(EGL_SUCCESS); + return egl::NoError(); } -egl::Error SurfaceD3D::resetSwapChain(int backbufferWidth, int backbufferHeight) +egl::Error SurfaceD3D::resetSwapChain(const gl::Context *context, + int backbufferWidth, + int backbufferHeight) { ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0); ASSERT(mSwapChain); - EGLint status = mSwapChain->reset(std::max(1, backbufferWidth), std::max(1, backbufferHeight), mSwapInterval); + EGLint status = mSwapChain->reset(context, std::max(1, backbufferWidth), + std::max(1, backbufferHeight), mSwapInterval); if (status == EGL_CONTEXT_LOST) { @@ -204,17 +215,20 @@ egl::Error SurfaceD3D::resetSwapChain(int backbufferWidth, int backbufferHeight) mHeight = backbufferHeight; mSwapIntervalDirty = false; - return egl::Error(EGL_SUCCESS); + return egl::NoError(); } -egl::Error SurfaceD3D::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) +egl::Error SurfaceD3D::swapRect(const gl::Context *context, + EGLint x, + EGLint y, + EGLint width, + EGLint height) { if (!mSwapChain) { - return egl::Error(EGL_SUCCESS); + return egl::NoError(); } -#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (defined(ANGLE_ENABLE_WINDOWS_STORE) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) // Qt WP: eglPostSubBufferNV comes here if (x + width > mWidth) { width = mWidth - x; @@ -224,11 +238,10 @@ egl::Error SurfaceD3D::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) { height = mHeight - y; } -#endif if (width != 0 && height != 0) { - EGLint status = mSwapChain->swapRect(x, y, width, height); + EGLint status = mSwapChain->swapRect(context, x, y, width, height); if (status == EGL_CONTEXT_LOST) { @@ -241,34 +254,36 @@ egl::Error SurfaceD3D::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) } } - checkForOutOfDateSwapChain(); + ANGLE_TRY(checkForOutOfDateSwapChain(context)); - return egl::Error(EGL_SUCCESS); + return egl::NoError(); } #if !defined(ANGLE_ENABLE_WINDOWS_STORE) #define kSurfaceProperty _TEXT("Egl::SurfaceOwner") #define kParentWndProc _TEXT("Egl::SurfaceParentWndProc") +#define kDisplayProperty _TEXT("Egl::Display") static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { - if (message == WM_SIZE) - { - SurfaceD3D* surf = reinterpret_cast(GetProp(hwnd, kSurfaceProperty)); - if(surf) - { - surf->checkForOutOfDateSwapChain(); - } - } - WNDPROC prevWndFunc = reinterpret_cast(GetProp(hwnd, kParentWndProc)); - return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam); + if (message == WM_SIZE) + { + SurfaceD3D* surf = reinterpret_cast(GetProp(hwnd, kSurfaceProperty)); + if(surf) + { + egl::Display *display = reinterpret_cast(GetProp(hwnd, kDisplayProperty)); + surf->checkForOutOfDateSwapChain(display->getProxyContext()); + } + } + WNDPROC prevWndFunc = reinterpret_cast(GetProp(hwnd, kParentWndProc)); + return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam); } #endif void SurfaceD3D::subclassWindow() { #if !defined(ANGLE_ENABLE_WINDOWS_STORE) - HWND window = mNativeWindow.getNativeWindow(); + HWND window = mNativeWindow->getNativeWindow(); if (!window) { return; @@ -291,6 +306,7 @@ void SurfaceD3D::subclassWindow() SetProp(window, kSurfaceProperty, reinterpret_cast(this)); SetProp(window, kParentWndProc, reinterpret_cast(oldWndProc)); + SetProp(window, kDisplayProperty, reinterpret_cast(mDisplay)); mWindowSubclassed = true; #endif } @@ -303,7 +319,7 @@ void SurfaceD3D::unsubclassWindow() } #if !defined(ANGLE_ENABLE_WINDOWS_STORE) - HWND window = mNativeWindow.getNativeWindow(); + HWND window = mNativeWindow->getNativeWindow(); if (!window) { return; @@ -320,30 +336,31 @@ void SurfaceD3D::unsubclassWindow() if(parentWndFunc) { LONG_PTR prevWndFunc = SetWindowLongPtr(window, GWLP_WNDPROC, parentWndFunc); - UNUSED_ASSERTION_VARIABLE(prevWndFunc); ASSERT(prevWndFunc == reinterpret_cast(SurfaceWindowProc)); } RemoveProp(window, kSurfaceProperty); RemoveProp(window, kParentWndProc); + RemoveProp(window, kDisplayProperty); #endif mWindowSubclassed = false; } -bool SurfaceD3D::checkForOutOfDateSwapChain() + +egl::Error SurfaceD3D::checkForOutOfDateSwapChain(const gl::Context *context) { RECT client; int clientWidth = getWidth(); int clientHeight = getHeight(); bool sizeDirty = false; - if (!mFixedSize && !mNativeWindow.isIconic()) + if (!mFixedSize && !mNativeWindow->isIconic()) { // The window is automatically resized to 150x22 when it's minimized, but the swapchain shouldn't be resized // because that's not a useful size to render to. - if (!mNativeWindow.getClientRect(&client)) + if (!mNativeWindow->getClientRect(&client)) { - ASSERT(false); - return false; + UNREACHABLE(); + return egl::NoError(); } // Grow the buffer now, if the window has grown. We need to grow now to avoid losing information. @@ -352,28 +369,30 @@ bool SurfaceD3D::checkForOutOfDateSwapChain() sizeDirty = clientWidth != getWidth() || clientHeight != getHeight(); } - bool wasDirty = (mSwapIntervalDirty || sizeDirty); - if (mSwapIntervalDirty) { - resetSwapChain(clientWidth, clientHeight); + ANGLE_TRY(resetSwapChain(context, clientWidth, clientHeight)); } else if (sizeDirty) { - resizeSwapChain(clientWidth, clientHeight); + ANGLE_TRY(resizeSwapChain(context, clientWidth, clientHeight)); } - return wasDirty; + return egl::NoError(); } -egl::Error SurfaceD3D::swap() +egl::Error SurfaceD3D::swap(const gl::Context *context) { - return swapRect(0, 0, mWidth, mHeight); + return swapRect(context, 0, 0, mWidth, mHeight); } -egl::Error SurfaceD3D::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) +egl::Error SurfaceD3D::postSubBuffer(const gl::Context *context, + EGLint x, + EGLint y, + EGLint width, + EGLint height) { - return swapRect(x, y, width, height); + return swapRect(context, x, y, width, height); } rx::SwapChainD3D *SurfaceD3D::getSwapChain() const @@ -429,13 +448,15 @@ egl::Error SurfaceD3D::querySurfacePointerANGLE(EGLint attribute, void **value) } else UNREACHABLE(); - return egl::Error(EGL_SUCCESS); + return egl::NoError(); } -gl::Error SurfaceD3D::getAttachmentRenderTarget(const gl::FramebufferAttachment::Target &target, +gl::Error SurfaceD3D::getAttachmentRenderTarget(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex, FramebufferAttachmentRenderTarget **rtOut) { - if (target.binding() == GL_BACK) + if (binding == GL_BACK) { *rtOut = mSwapChain->getColorRenderTarget(); } @@ -443,7 +464,46 @@ gl::Error SurfaceD3D::getAttachmentRenderTarget(const gl::FramebufferAttachment: { *rtOut = mSwapChain->getDepthStencilRenderTarget(); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } +WindowSurfaceD3D::WindowSurfaceD3D(const egl::SurfaceState &state, + RendererD3D *renderer, + egl::Display *display, + EGLNativeWindowType window, + const egl::AttributeMap &attribs) + : SurfaceD3D(state, + renderer, + display, + window, + 0, + static_cast(0), + attribs) +{ } + +WindowSurfaceD3D::~WindowSurfaceD3D() +{ +} + +PbufferSurfaceD3D::PbufferSurfaceD3D(const egl::SurfaceState &state, + RendererD3D *renderer, + egl::Display *display, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const egl::AttributeMap &attribs) + : SurfaceD3D(state, + renderer, + display, + static_cast(0), + buftype, + clientBuffer, + attribs) +{ +} + +PbufferSurfaceD3D::~PbufferSurfaceD3D() +{ +} + +} // namespace rc diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.h index 67d408ddd9..01d2573244 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.h @@ -10,7 +10,7 @@ #define LIBANGLE_RENDERER_D3D_SURFACED3D_H_ #include "libANGLE/renderer/SurfaceImpl.h" -#include "libANGLE/renderer/d3d/d3d11/NativeWindow.h" +#include "libANGLE/renderer/d3d/NativeWindowD3D.h" namespace egl { @@ -25,28 +25,22 @@ class RendererD3D; class SurfaceD3D : public SurfaceImpl { public: - static SurfaceD3D *createFromWindow(RendererD3D *renderer, - egl::Display *display, - const egl::Config *config, - EGLNativeWindowType window, - EGLint fixedSize, - EGLint directComposition, - EGLint width, - EGLint height, - EGLint orientation); - static SurfaceD3D *createOffscreen(RendererD3D *renderer, egl::Display *display, const egl::Config *config, - EGLClientBuffer shareHandle, EGLint width, EGLint height); ~SurfaceD3D() override; void releaseSwapChain(); - egl::Error initialize() override; - FramebufferImpl *createDefaultFramebuffer(const gl::Framebuffer::Data &data) override; + egl::Error initialize(const egl::Display *display) override; + FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override; - egl::Error swap() override; - egl::Error postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) override; + egl::Error swap(const gl::Context *context) override; + egl::Error postSubBuffer(const gl::Context *context, + EGLint x, + EGLint y, + EGLint width, + EGLint height) override; egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override; egl::Error bindTexImage(gl::Texture *texture, EGLint buffer) override; egl::Error releaseTexImage(EGLint buffer) override; + egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override; void setSwapInterval(EGLint interval) override; EGLint getWidth() const override; @@ -58,29 +52,35 @@ class SurfaceD3D : public SurfaceImpl // D3D implementations SwapChainD3D *getSwapChain() const; - egl::Error resetSwapChain(); + egl::Error resetSwapChain(const egl::Display *display); - // Returns true if swapchain changed due to resize or interval update - bool checkForOutOfDateSwapChain(); + egl::Error checkForOutOfDateSwapChain(const gl::Context *context); - gl::Error getAttachmentRenderTarget(const gl::FramebufferAttachment::Target &target, + gl::Error getAttachmentRenderTarget(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex, FramebufferAttachmentRenderTarget **rtOut) override; - private: - SurfaceD3D(RendererD3D *renderer, + protected: + SurfaceD3D(const egl::SurfaceState &state, + RendererD3D *renderer, egl::Display *display, - const egl::Config *config, - EGLint width, - EGLint height, - EGLint fixedSize, - EGLint orientation, - EGLint directComposition, - EGLClientBuffer shareHandle, - EGLNativeWindowType window); + EGLNativeWindowType window, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const egl::AttributeMap &attribs); - egl::Error swapRect(EGLint x, EGLint y, EGLint width, EGLint height); - egl::Error resetSwapChain(int backbufferWidth, int backbufferHeight); - egl::Error resizeSwapChain(int backbufferWidth, int backbufferHeight); + egl::Error swapRect(const gl::Context *context, + EGLint x, + EGLint y, + EGLint width, + EGLint height); + egl::Error resetSwapChain(const gl::Context *context, + int backbufferWidth, + int backbufferHeight); + egl::Error resizeSwapChain(const gl::Context *context, + int backbufferWidth, + int backbufferHeight); void subclassWindow(); void unsubclassWindow(); @@ -96,18 +96,41 @@ class SurfaceD3D : public SurfaceImpl SwapChainD3D *mSwapChain; bool mSwapIntervalDirty; - bool mWindowSubclassed; // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking + bool mWindowSubclassed; // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking - NativeWindow mNativeWindow; // Handler for the Window that the surface is created for. + NativeWindowD3D *mNativeWindow; // Handler for the Window that the surface is created for. EGLint mWidth; EGLint mHeight; EGLint mSwapInterval; HANDLE mShareHandle; + IUnknown *mD3DTexture; }; +class WindowSurfaceD3D : public SurfaceD3D +{ + public: + WindowSurfaceD3D(const egl::SurfaceState &state, + RendererD3D *renderer, + egl::Display *display, + EGLNativeWindowType window, + const egl::AttributeMap &attribs); + ~WindowSurfaceD3D() override; +}; -} +class PbufferSurfaceD3D : public SurfaceD3D +{ + public: + PbufferSurfaceD3D(const egl::SurfaceState &state, + RendererD3D *renderer, + egl::Display *display, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const egl::AttributeMap &attribs); + ~PbufferSurfaceD3D() override; +}; + +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_SURFACED3D_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SwapChainD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SwapChainD3D.cpp new file mode 100644 index 0000000000..de8534c3da --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SwapChainD3D.cpp @@ -0,0 +1,34 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// SwapChainD3D.cpp: Defines a back-end specific class that hides the details of the +// implementation-specific swapchain. + +#include "libANGLE/renderer/d3d/SwapChainD3D.h" + +namespace rx +{ + +SwapChainD3D::SwapChainD3D(HANDLE shareHandle, + IUnknown *d3dTexture, + GLenum backBufferFormat, + GLenum depthBufferFormat) + : mOffscreenRenderTargetFormat(backBufferFormat), + mDepthBufferFormat(depthBufferFormat), + mShareHandle(shareHandle), + mD3DTexture(d3dTexture) +{ + if (mD3DTexture) + { + mD3DTexture->AddRef(); + } +} + +SwapChainD3D::~SwapChainD3D() +{ + SafeRelease(mD3DTexture); +} +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SwapChainD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SwapChainD3D.h index 171cab54dd..017737b878 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SwapChainD3D.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SwapChainD3D.h @@ -12,17 +12,26 @@ #include #include +#include #include "common/angleutils.h" #include "common/platform.h" - -// TODO: move out of D3D11 -#include "libANGLE/renderer/d3d/d3d11/NativeWindow.h" +#include "libANGLE/Error.h" #if !defined(ANGLE_FORCE_VSYNC_OFF) #define ANGLE_FORCE_VSYNC_OFF 0 #endif +namespace gl +{ +class Context; +} // namespace gl + +namespace egl +{ +class Display; +} // namespace egl + namespace rx { class RenderTargetD3D; @@ -30,35 +39,45 @@ class RenderTargetD3D; class SwapChainD3D : angle::NonCopyable { public: - SwapChainD3D(rx::NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) - : mNativeWindow(nativeWindow), mOffscreenRenderTargetFormat(backBufferFormat), mDepthBufferFormat(depthBufferFormat), mShareHandle(shareHandle) - { - } + SwapChainD3D(HANDLE shareHandle, + IUnknown *d3dTexture, + GLenum backBufferFormat, + GLenum depthBufferFormat); + virtual ~SwapChainD3D(); - virtual ~SwapChainD3D() {}; - - virtual EGLint resize(EGLint backbufferWidth, EGLint backbufferSize) = 0; - virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval) = 0; - virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height) = 0; + virtual EGLint resize(const gl::Context *context, + EGLint backbufferWidth, + EGLint backbufferSize) = 0; + virtual EGLint reset(const gl::Context *context, + EGLint backbufferWidth, + EGLint backbufferHeight, + EGLint swapInterval) = 0; + virtual EGLint swapRect(const gl::Context *context, + EGLint x, + EGLint y, + EGLint width, + EGLint height) = 0; virtual void recreate() = 0; - virtual void *getDevice() { return NULL; } + virtual void *getDevice() { return nullptr; } virtual RenderTargetD3D *getColorRenderTarget() = 0; virtual RenderTargetD3D *getDepthStencilRenderTarget() = 0; - GLenum GetRenderTargetInternalFormat() const { return mOffscreenRenderTargetFormat; } - GLenum GetDepthBufferInternalFormat() const { return mDepthBufferFormat; } + GLenum getRenderTargetInternalFormat() const { return mOffscreenRenderTargetFormat; } + GLenum getDepthBufferInternalFormat() const { return mDepthBufferFormat; } HANDLE getShareHandle() { return mShareHandle; } virtual void *getKeyedMutex() = 0; + virtual egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) = 0; + protected: - rx::NativeWindow mNativeWindow; // Handler for the Window that the surface is created for. const GLenum mOffscreenRenderTargetFormat; const GLenum mDepthBufferFormat; HANDLE mShareHandle; + IUnknown *mD3DTexture; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_SWAPCHAIND3D_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureD3D.cpp index 430576b318..bf44cbb5d2 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureD3D.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureD3D.cpp @@ -12,6 +12,7 @@ #include "common/utilities.h" #include "libANGLE/Buffer.h" #include "libANGLE/Config.h" +#include "libANGLE/Context.h" #include "libANGLE/Framebuffer.h" #include "libANGLE/Image.h" #include "libANGLE/Surface.h" @@ -21,8 +22,8 @@ #include "libANGLE/renderer/d3d/BufferD3D.h" #include "libANGLE/renderer/d3d/EGLImageD3D.h" #include "libANGLE/renderer/d3d/ImageD3D.h" -#include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/RenderTargetD3D.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/SurfaceD3D.h" #include "libANGLE/renderer/d3d/TextureStorage.h" @@ -32,26 +33,24 @@ namespace rx namespace { -gl::Error GetUnpackPointer(const gl::PixelUnpackState &unpack, const uint8_t *pixels, - ptrdiff_t layerOffset, const uint8_t **pointerOut) +gl::Error GetUnpackPointer(const gl::Context *context, + const gl::PixelUnpackState &unpack, + gl::Buffer *unpackBuffer, + const uint8_t *pixels, + ptrdiff_t layerOffset, + const uint8_t **pointerOut) { - if (unpack.pixelBuffer.id() != 0) + if (unpackBuffer) { // Do a CPU readback here, if we have an unpack buffer bound and the fast GPU path is not supported - gl::Buffer *pixelBuffer = unpack.pixelBuffer.get(); ptrdiff_t offset = reinterpret_cast(pixels); // TODO: this is the only place outside of renderer that asks for a buffers raw data. // This functionality should be moved into renderer and the getData method of BufferImpl removed. - BufferD3D *bufferD3D = GetImplAs(pixelBuffer); + BufferD3D *bufferD3D = GetImplAs(unpackBuffer); ASSERT(bufferD3D); - const uint8_t *bufferData = NULL; - gl::Error error = bufferD3D->getData(&bufferData); - if (error.isError()) - { - return error; - } - + const uint8_t *bufferData = nullptr; + ANGLE_TRY(bufferD3D->getData(context, &bufferData)); *pointerOut = bufferData + offset; } else @@ -65,7 +64,7 @@ gl::Error GetUnpackPointer(const gl::PixelUnpackState &unpack, const uint8_t *pi *pointerOut += layerOffset; } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } bool IsRenderTargetUsage(GLenum usage) @@ -75,41 +74,66 @@ bool IsRenderTargetUsage(GLenum usage) } -TextureD3D::TextureD3D(RendererD3D *renderer) - : mRenderer(renderer), - mUsage(GL_NONE), +TextureD3D::TextureD3D(const gl::TextureState &state, RendererD3D *renderer) + : TextureImpl(state), + mRenderer(renderer), mDirtyImages(true), mImmutable(false), - mTexStorage(NULL) + mTexStorage(nullptr), + mBaseLevel(0) { } TextureD3D::~TextureD3D() { + ASSERT(!mTexStorage); } -gl::Error TextureD3D::getNativeTexture(TextureStorage **outStorage) +gl::Error TextureD3D::getNativeTexture(const gl::Context *context, TextureStorage **outStorage) { // ensure the underlying texture is created - gl::Error error = initializeStorage(false); - if (error.isError()) - { - return error; - } + ANGLE_TRY(initializeStorage(context, false)); if (mTexStorage) { - error = updateStorage(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(updateStorage(context)); } ASSERT(outStorage); *outStorage = mTexStorage; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); +} + +gl::Error TextureD3D::getImageAndSyncFromStorage(const gl::Context *context, + const gl::ImageIndex &index, + ImageD3D **outImage) +{ + ImageD3D *image = getImage(index); + if (mTexStorage && mTexStorage->isRenderTarget()) + { + ANGLE_TRY(image->copyFromTexStorage(context, index, mTexStorage)); + mDirtyImages = true; + } + *outImage = image; + return gl::NoError(); +} + +GLint TextureD3D::getLevelZeroWidth() const +{ + ASSERT(gl::CountLeadingZeros(static_cast(getBaseLevelWidth())) > getBaseLevel()); + return getBaseLevelWidth() << mBaseLevel; +} + +GLint TextureD3D::getLevelZeroHeight() const +{ + ASSERT(gl::CountLeadingZeros(static_cast(getBaseLevelHeight())) > getBaseLevel()); + return getBaseLevelHeight() << mBaseLevel; +} + +GLint TextureD3D::getLevelZeroDepth() const +{ + return getBaseLevelDepth(); } GLint TextureD3D::getBaseLevelWidth() const @@ -139,6 +163,27 @@ GLenum TextureD3D::getBaseLevelInternalFormat() const return (baseImage ? baseImage->getInternalFormat() : GL_NONE); } +gl::Error TextureD3D::setStorage(const gl::Context *context, + GLenum target, + size_t levels, + GLenum internalFormat, + const gl::Extents &size) +{ + UNREACHABLE(); + return gl::InternalError(); +} + +gl::Error TextureD3D::setStorageMultisample(const gl::Context *context, + GLenum target, + GLsizei samples, + GLint internalFormat, + const gl::Extents &size, + bool fixedSampleLocations) +{ + UNREACHABLE(); + return gl::InternalError(); +} + bool TextureD3D::shouldUseSetData(const ImageD3D *image) const { if (!mRenderer->getWorkarounds().setDataFasterThanImageUpload) @@ -146,7 +191,12 @@ bool TextureD3D::shouldUseSetData(const ImageD3D *image) const return false; } - gl::InternalFormat internalFormat = gl::GetInternalFormatInfo(image->getInternalFormat()); + if (image->isDirty()) + { + return false; + } + + gl::InternalFormat internalFormat = gl::GetSizedInternalFormatInfo(image->getInternalFormat()); // We can only handle full updates for depth-stencil textures, so to avoid complications // disable them entirely. @@ -159,173 +209,166 @@ bool TextureD3D::shouldUseSetData(const ImageD3D *image) const return (mTexStorage && !internalFormat.compressed); } -gl::Error TextureD3D::setImageImpl(const gl::ImageIndex &index, +gl::Error TextureD3D::setImageImpl(const gl::Context *context, + const gl::ImageIndex &index, GLenum type, const gl::PixelUnpackState &unpack, const uint8_t *pixels, ptrdiff_t layerOffset) { ImageD3D *image = getImage(index); + gl::Buffer *unpackBuffer = + context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack); ASSERT(image); // No-op if (image->getWidth() == 0 || image->getHeight() == 0 || image->getDepth() == 0) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } // We no longer need the "GLenum format" parameter to TexImage to determine what data format "pixels" contains. // From our image internal format we know how many channels to expect, and "type" gives the format of pixel's components. - const uint8_t *pixelData = NULL; - gl::Error error = GetUnpackPointer(unpack, pixels, layerOffset, &pixelData); - if (error.isError()) - { - return error; - } + const uint8_t *pixelData = nullptr; + ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData)); if (pixelData != nullptr) { if (shouldUseSetData(image)) { - error = mTexStorage->setData(index, image, NULL, type, unpack, pixelData); + ANGLE_TRY( + mTexStorage->setData(context, index, image, nullptr, type, unpack, pixelData)); } else { gl::Box fullImageArea(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth()); - error = image->loadData(fullImageArea, unpack, type, pixelData); - } - - if (error.isError()) - { - return error; + ANGLE_TRY( + image->loadData(context, fullImageArea, unpack, type, pixelData, index.is3D())); } mDirtyImages = true; } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D::subImage(const gl::ImageIndex &index, const gl::Box &area, GLenum format, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixels, ptrdiff_t layerOffset) +gl::Error TextureD3D::subImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels, + ptrdiff_t layerOffset) { // CPU readback & copy where direct GPU copy is not supported - const uint8_t *pixelData = NULL; - gl::Error error = GetUnpackPointer(unpack, pixels, layerOffset, &pixelData); - if (error.isError()) - { - return error; - } + const uint8_t *pixelData = nullptr; + gl::Buffer *unpackBuffer = + context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack); + ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData)); - if (pixelData != NULL) + if (pixelData != nullptr) { ImageD3D *image = getImage(index); ASSERT(image); if (shouldUseSetData(image)) { - return mTexStorage->setData(index, image, &area, type, unpack, pixelData); - } - - error = image->loadData(area, unpack, type, pixelData); - if (error.isError()) - { - return error; - } - - error = commitRegion(index, area); - if (error.isError()) - { - return error; + return mTexStorage->setData(context, index, image, &area, type, unpack, pixelData); } + ANGLE_TRY(image->loadData(context, area, unpack, type, pixelData, index.is3D())); + ANGLE_TRY(commitRegion(context, index, area)); mDirtyImages = true; } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D::setCompressedImageImpl(const gl::ImageIndex &index, +gl::Error TextureD3D::setCompressedImageImpl(const gl::Context *context, + const gl::ImageIndex &index, const gl::PixelUnpackState &unpack, const uint8_t *pixels, ptrdiff_t layerOffset) { + ImageD3D *image = getImage(index); + ASSERT(image); + + if (image->getWidth() == 0 || image->getHeight() == 0 || image->getDepth() == 0) + { + return gl::NoError(); + } + // We no longer need the "GLenum format" parameter to TexImage to determine what data format "pixels" contains. // From our image internal format we know how many channels to expect, and "type" gives the format of pixel's components. - const uint8_t *pixelData = NULL; - gl::Error error = GetUnpackPointer(unpack, pixels, layerOffset, &pixelData); - if (error.isError()) - { - return error; - } + const uint8_t *pixelData = nullptr; + gl::Buffer *unpackBuffer = + context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack); + ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData)); - if (pixelData != NULL) + if (pixelData != nullptr) { - ImageD3D *image = getImage(index); - ASSERT(image); - gl::Box fullImageArea(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth()); - error = image->loadCompressedData(fullImageArea, pixelData); - if (error.isError()) - { - return error; - } + ANGLE_TRY(image->loadCompressedData(context, fullImageArea, pixelData)); mDirtyImages = true; } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D::subImageCompressed(const gl::ImageIndex &index, const gl::Box &area, GLenum format, - const gl::PixelUnpackState &unpack, const uint8_t *pixels, +gl::Error TextureD3D::subImageCompressed(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels, ptrdiff_t layerOffset) { - const uint8_t *pixelData = NULL; - gl::Error error = GetUnpackPointer(unpack, pixels, layerOffset, &pixelData); - if (error.isError()) - { - return error; - } + const uint8_t *pixelData = nullptr; + gl::Buffer *unpackBuffer = + context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack); + ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData)); - if (pixelData != NULL) + if (pixelData != nullptr) { ImageD3D *image = getImage(index); ASSERT(image); - error = image->loadCompressedData(area, pixelData); - if (error.isError()) - { - return error; - } + ANGLE_TRY(image->loadCompressedData(context, area, pixelData)); mDirtyImages = true; } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -bool TextureD3D::isFastUnpackable(const gl::PixelUnpackState &unpack, GLenum sizedInternalFormat) +bool TextureD3D::isFastUnpackable(const gl::Buffer *unpackBuffer, GLenum sizedInternalFormat) { - return unpack.pixelBuffer.id() != 0 && mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat); + return unpackBuffer != nullptr && + mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat); } -gl::Error TextureD3D::fastUnpackPixels(const gl::PixelUnpackState &unpack, const uint8_t *pixels, const gl::Box &destArea, - GLenum sizedInternalFormat, GLenum type, RenderTargetD3D *destRenderTarget) +gl::Error TextureD3D::fastUnpackPixels(const gl::Context *context, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels, + const gl::Box &destArea, + GLenum sizedInternalFormat, + GLenum type, + RenderTargetD3D *destRenderTarget) { if (unpack.skipRows != 0 || unpack.skipPixels != 0 || unpack.imageHeight != 0 || unpack.skipImages != 0) { // TODO(jmadill): additional unpack parameters UNIMPLEMENTED(); - return gl::Error(GL_INVALID_OPERATION, - "Unimplemented pixel store parameters in fastUnpackPixels"); + return gl::InternalError() << "Unimplemented pixel store parameters in fastUnpackPixels"; } // No-op if (destArea.width <= 0 && destArea.height <= 0 && destArea.depth <= 0) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } // In order to perform the fast copy through the shader, we must have the right format, and be able @@ -334,18 +377,17 @@ gl::Error TextureD3D::fastUnpackPixels(const gl::PixelUnpackState &unpack, const uintptr_t offset = reinterpret_cast(pixels); - gl::Error error = mRenderer->fastCopyBufferToTexture(unpack, static_cast(offset), destRenderTarget, sizedInternalFormat, type, destArea); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mRenderer->fastCopyBufferToTexture(context, unpack, static_cast(offset), + destRenderTarget, sizedInternalFormat, type, + destArea)); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } GLint TextureD3D::creationLevels(GLsizei width, GLsizei height, GLsizei depth) const { - if ((gl::isPow2(width) && gl::isPow2(height) && gl::isPow2(depth)) || mRenderer->getRendererExtensions().textureNPOT) + if ((gl::isPow2(width) && gl::isPow2(height) && gl::isPow2(depth)) || + mRenderer->getNativeExtensions().textureNPOT) { // Maximum number of levels return gl::log2(std::max(std::max(width, height), depth)) + 1; @@ -357,11 +399,6 @@ GLint TextureD3D::creationLevels(GLsizei width, GLsizei height, GLsizei depth) c } } -int TextureD3D::mipLevels() const -{ - return gl::log2(std::max(std::max(getBaseLevelWidth(), getBaseLevelHeight()), getBaseLevelDepth())) + 1; -} - TextureStorage *TextureD3D::getStorage() { ASSERT(mTexStorage); @@ -370,72 +407,60 @@ TextureStorage *TextureD3D::getStorage() ImageD3D *TextureD3D::getBaseLevelImage() const { - return getImage(getImageIndex(0, 0)); + if (mBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + return nullptr; + } + return getImage(getImageIndex(mBaseLevel, 0)); } -gl::Error TextureD3D::generateMipmaps(const gl::TextureState &textureState) +gl::Error TextureD3D::setImageExternal(const gl::Context *context, + GLenum target, + egl::Stream *stream, + const egl::Stream::GLTextureDescription &desc) { - GLint mipCount = mipLevels(); + // Only external images can accept external textures + UNREACHABLE(); + return gl::InternalError(); +} - if (mipCount == 1) - { - return gl::Error(GL_NO_ERROR); // no-op - } +gl::Error TextureD3D::generateMipmap(const gl::Context *context) +{ + const GLuint baseLevel = mState.getEffectiveBaseLevel(); + const GLuint maxLevel = mState.getMipmapMaxLevel(); + ASSERT(maxLevel > baseLevel); // Should be checked before calling this. if (mTexStorage && mRenderer->getWorkarounds().zeroMaxLodWorkaround) { // Switch to using the mipmapped texture. - TextureStorage *textureStorage = NULL; - gl::Error error = getNativeTexture(&textureStorage); - if (error.isError()) - { - return error; - } - - error = textureStorage->useLevelZeroWorkaroundTexture(false); - if (error.isError()) - { - return error; - } + TextureStorage *textureStorage = nullptr; + ANGLE_TRY(getNativeTexture(context, &textureStorage)); + ANGLE_TRY(textureStorage->useLevelZeroWorkaroundTexture(context, false)); } // Set up proper mipmap chain in our Image array. - initMipmapsImages(); + ANGLE_TRY(initMipmapImages(context)); if (mTexStorage && mTexStorage->supportsNativeMipmapFunction()) { - gl::Error error = updateStorage(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(updateStorage(context)); // Generate the mipmap chain using the ad-hoc DirectX function. - error = mRenderer->generateMipmapsUsingD3D(mTexStorage, textureState); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mRenderer->generateMipmapUsingD3D(context, mTexStorage, mState)); } else { // Generate the mipmap chain, one level at a time. - gl::Error error = generateMipmapsUsingImages(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(generateMipmapUsingImages(context, maxLevel)); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D::generateMipmapsUsingImages() +gl::Error TextureD3D::generateMipmapUsingImages(const gl::Context *context, const GLuint maxLevel) { - GLint mipCount = mipLevels(); - // We know that all layers have the same dimension, for the texture to be complete - GLint layerCount = static_cast(getLayerCount(0)); + GLint layerCount = static_cast(getLayerCount(mBaseLevel)); // When making mipmaps with the setData workaround enabled, the texture storage has // the image data already. For non-render-target storage, we have to pull it out into @@ -447,23 +472,15 @@ gl::Error TextureD3D::generateMipmapsUsingImages() // Copy from the storage mip 0 to Image mip 0 for (GLint layer = 0; layer < layerCount; ++layer) { - gl::ImageIndex srcIndex = getImageIndex(0, layer); + gl::ImageIndex srcIndex = getImageIndex(mBaseLevel, layer); ImageD3D *image = getImage(srcIndex); - gl::Error error = image->copyFromTexStorage(srcIndex, mTexStorage); - if (error.isError()) - { - return error; - } + ANGLE_TRY(image->copyFromTexStorage(context, srcIndex, mTexStorage)); } } else { - gl::Error error = updateStorage(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(updateStorage(context)); } } @@ -476,7 +493,7 @@ gl::Error TextureD3D::generateMipmapsUsingImages() for (GLint layer = 0; layer < layerCount; ++layer) { - for (GLint mip = 1; mip < mipCount; ++mip) + for (GLuint mip = mBaseLevel + 1; mip <= maxLevel; ++mip) { ASSERT(getLayerCount(mip) == layerCount); @@ -486,30 +503,25 @@ gl::Error TextureD3D::generateMipmapsUsingImages() if (renderableStorage) { // GPU-side mipmapping - gl::Error error = mTexStorage->generateMipmap(sourceIndex, destIndex); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mTexStorage->generateMipmap(context, sourceIndex, destIndex)); } else { // CPU-side mipmapping - gl::Error error = mRenderer->generateMipmap(getImage(destIndex), getImage(sourceIndex)); - if (error.isError()) - { - return error; - } + ANGLE_TRY( + mRenderer->generateMipmap(context, getImage(destIndex), getImage(sourceIndex))); } } } + mDirtyImages = true; + if (mTexStorage) { - updateStorage(); + ANGLE_TRY(updateStorage(context)); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } bool TextureD3D::isBaseImageZeroSize() const @@ -531,7 +543,7 @@ bool TextureD3D::isBaseImageZeroSize() const return true; } - if (baseImage->getTarget() == GL_TEXTURE_2D_ARRAY && getLayerCount(0) <= 0) + if (baseImage->getTarget() == GL_TEXTURE_2D_ARRAY && getLayerCount(getBaseLevel()) <= 0) { return true; } @@ -539,12 +551,16 @@ bool TextureD3D::isBaseImageZeroSize() const return false; } -gl::Error TextureD3D::ensureRenderTarget() +gl::Error TextureD3D::ensureRenderTarget(const gl::Context *context) { - gl::Error error = initializeStorage(true); - if (error.isError()) + ANGLE_TRY(initializeStorage(context, true)); + + // initializeStorage can fail with NoError if the texture is not complete. This is not + // an error for incomplete sampling, but it is a big problem for rendering. + if (!mTexStorage) { - return error; + UNREACHABLE(); + return gl::InternalError() << "Cannot render to incomplete texture."; } if (!isBaseImageZeroSize()) @@ -552,94 +568,210 @@ gl::Error TextureD3D::ensureRenderTarget() ASSERT(mTexStorage); if (!mTexStorage->isRenderTarget()) { - TextureStorage *newRenderTargetStorage = NULL; - error = createCompleteStorage(true, &newRenderTargetStorage); - if (error.isError()) - { - return error; - } + TexStoragePointer newRenderTargetStorage(context); + ANGLE_TRY(createCompleteStorage(true, &newRenderTargetStorage)); - error = mTexStorage->copyToStorage(newRenderTargetStorage); - if (error.isError()) - { - SafeDelete(newRenderTargetStorage); - return error; - } - - error = setCompleteTexStorage(newRenderTargetStorage); - if (error.isError()) - { - SafeDelete(newRenderTargetStorage); - return error; - } + ANGLE_TRY(mTexStorage->copyToStorage(context, newRenderTargetStorage.get())); + ANGLE_TRY(setCompleteTexStorage(context, newRenderTargetStorage.get())); + newRenderTargetStorage.release(); } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } bool TextureD3D::canCreateRenderTargetForImage(const gl::ImageIndex &index) const { + if (index.type == GL_TEXTURE_2D_MULTISAMPLE) + return true; + ImageD3D *image = getImage(index); + ASSERT(image); bool levelsComplete = (isImageComplete(index) && isImageComplete(getImageIndex(0, 0))); return (image->isRenderableFormat() && levelsComplete); } -gl::Error TextureD3D::commitRegion(const gl::ImageIndex &index, const gl::Box ®ion) +gl::Error TextureD3D::commitRegion(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box ®ion) { if (mTexStorage) { ASSERT(isValidIndex(index)); ImageD3D *image = getImage(index); - gl::Error error = image->copyToStorage(mTexStorage, index, region); - if (error.isError()) - { - return error; - } - + ANGLE_TRY(image->copyToStorage(context, mTexStorage, index, region)); image->markClean(); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D::getAttachmentRenderTarget(const gl::FramebufferAttachment::Target &target, +gl::Error TextureD3D::getAttachmentRenderTarget(const gl::Context *context, + GLenum /*binding*/, + const gl::ImageIndex &imageIndex, FramebufferAttachmentRenderTarget **rtOut) { RenderTargetD3D *rtD3D = nullptr; - gl::Error error = getRenderTarget(target.textureIndex(), &rtD3D); + gl::Error error = getRenderTarget(context, imageIndex, &rtD3D); *rtOut = static_cast(rtD3D); return error; } -TextureD3D_2D::TextureD3D_2D(RendererD3D *renderer) - : TextureD3D(renderer) +gl::Error TextureD3D::setBaseLevel(const gl::Context *context, GLuint baseLevel) +{ + const int oldStorageWidth = std::max(1, getLevelZeroWidth()); + const int oldStorageHeight = std::max(1, getLevelZeroHeight()); + const int oldStorageDepth = std::max(1, getLevelZeroDepth()); + const int oldStorageFormat = getBaseLevelInternalFormat(); + mBaseLevel = baseLevel; + + // When the base level changes, the texture storage might not be valid anymore, since it could + // have been created based on the dimensions of the previous specified level range. + const int newStorageWidth = std::max(1, getLevelZeroWidth()); + const int newStorageHeight = std::max(1, getLevelZeroHeight()); + const int newStorageDepth = std::max(1, getLevelZeroDepth()); + const int newStorageFormat = getBaseLevelInternalFormat(); + if (mTexStorage && + (newStorageWidth != oldStorageWidth || newStorageHeight != oldStorageHeight || + newStorageDepth != oldStorageDepth || newStorageFormat != oldStorageFormat)) + { + markAllImagesDirty(); + ANGLE_TRY(releaseTexStorage(context)); + } + + return gl::NoError(); +} + +void TextureD3D::syncState(const gl::Texture::DirtyBits &dirtyBits) +{ + // TODO(geofflang): Use dirty bits +} + +gl::Error TextureD3D::releaseTexStorage(const gl::Context *context) +{ + if (!mTexStorage) + { + return gl::NoError(); + } + auto err = mTexStorage->onDestroy(context); + SafeDelete(mTexStorage); + return err; +} + +gl::Error TextureD3D::onDestroy(const gl::Context *context) +{ + return releaseTexStorage(context); +} + +gl::Error TextureD3D::initializeContents(const gl::Context *context, + const gl::ImageIndex &imageIndexIn) +{ + gl::ImageIndex imageIndex = imageIndexIn; + + // Special case for D3D11 3D textures. We can't create render targets for individual layers of a + // 3D texture, so force the clear to the entire mip. There shouldn't ever be a case where we + // would lose existing data. + if (imageIndex.type == GL_TEXTURE_3D) + { + imageIndex.layerIndex = gl::ImageIndex::ENTIRE_LEVEL; + } + else if (imageIndex.type == GL_TEXTURE_2D_ARRAY && + imageIndex.layerIndex == gl::ImageIndex::ENTIRE_LEVEL) + { + GLsizei layerCount = getLayerCount(imageIndex.mipIndex); + for (imageIndex.layerIndex = 0; imageIndex.layerIndex < layerCount; ++imageIndex.layerIndex) + { + ANGLE_TRY(initializeContents(context, imageIndex)); + } + return gl::NoError(); + } + + // Force image clean. + ImageD3D *image = getImage(imageIndex); + if (image) + { + image->markClean(); + } + + // Fast path: can use a render target clear. + if (canCreateRenderTargetForImage(imageIndex)) + { + ANGLE_TRY(ensureRenderTarget(context)); + ASSERT(mTexStorage); + RenderTargetD3D *renderTarget = nullptr; + ANGLE_TRY(mTexStorage->getRenderTarget(context, imageIndex, &renderTarget)); + ANGLE_TRY(mRenderer->initRenderTarget(renderTarget)); + return gl::NoError(); + } + + // Slow path: non-renderable texture or the texture levels aren't set up. + const auto &formatInfo = gl::GetSizedInternalFormatInfo(image->getInternalFormat()); + + size_t imageBytes = 0; + ANGLE_TRY_RESULT(formatInfo.computeRowPitch(formatInfo.type, image->getWidth(), 1, 0), + imageBytes); + imageBytes *= image->getHeight() * image->getDepth(); + + gl::PixelUnpackState defaultUnpackState; + + angle::MemoryBuffer *zeroBuffer = nullptr; + ANGLE_TRY(context->getZeroFilledBuffer(imageBytes, &zeroBuffer)); + if (shouldUseSetData(image)) + { + ANGLE_TRY(mTexStorage->setData(context, imageIndex, image, nullptr, formatInfo.type, + defaultUnpackState, zeroBuffer->data())); + } + else + { + gl::Box fullImageArea(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth()); + ANGLE_TRY(image->loadData(context, fullImageArea, defaultUnpackState, formatInfo.type, + zeroBuffer->data(), false)); + + // Force an update to the tex storage so we avoid problems with subImage and dirty regions. + if (mTexStorage) + { + ANGLE_TRY(commitRegion(context, imageIndex, fullImageArea)); + image->markClean(); + } + else + { + mDirtyImages = true; + } + } + return gl::NoError(); +} + +TextureD3D_2D::TextureD3D_2D(const gl::TextureState &state, RendererD3D *renderer) + : TextureD3D(state, renderer) { mEGLImageTarget = false; - for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i) + for (auto &image : mImageArray) { - mImageArray[i] = renderer->createImage(); + image.reset(renderer->createImage()); } } +gl::Error TextureD3D_2D::onDestroy(const gl::Context *context) +{ + // Delete the Images before the TextureStorage. Images might be relying on the TextureStorage + // for some of their data. If TextureStorage is deleted before the Images, then their data will + // be wastefully copied back from the GPU before we delete the Images. + for (auto &image : mImageArray) + { + image.reset(); + } + return TextureD3D::onDestroy(context); +} + TextureD3D_2D::~TextureD3D_2D() { - // Delete the Images before the TextureStorage. - // Images might be relying on the TextureStorage for some of their data. - // If TextureStorage is deleted before the Images, then their data will be wastefully copied back from the GPU before we delete the Images. - for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i) - { - delete mImageArray[i]; - } - - SafeDelete(mTexStorage); } ImageD3D *TextureD3D_2D::getImage(int level, int layer) const { ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); ASSERT(layer == 0); - return mImageArray[level]; + return mImageArray[level].get(); } ImageD3D *TextureD3D_2D::getImage(const gl::ImageIndex &index) const @@ -647,7 +779,7 @@ ImageD3D *TextureD3D_2D::getImage(const gl::ImageIndex &index) const ASSERT(index.mipIndex < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); ASSERT(!index.hasLayer()); ASSERT(index.type == GL_TEXTURE_2D); - return mImageArray[index.mipIndex]; + return mImageArray[index.mipIndex].get(); } GLsizei TextureD3D_2D::getLayerCount(int level) const @@ -682,10 +814,16 @@ GLenum TextureD3D_2D::getInternalFormat(GLint level) const bool TextureD3D_2D::isDepth(GLint level) const { - return gl::GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0; + return gl::GetSizedInternalFormatInfo(getInternalFormat(level)).depthBits > 0; } -gl::Error TextureD3D_2D::setImage(GLenum target, +bool TextureD3D_2D::isSRGB(GLint level) const +{ + return gl::GetSizedInternalFormatInfo(getInternalFormat(level)).colorEncoding == GL_SRGB; +} + +gl::Error TextureD3D_2D::setImage(const gl::Context *context, + GLenum target, size_t imageLevel, GLenum internalFormat, const gl::Extents &size, @@ -696,33 +834,29 @@ gl::Error TextureD3D_2D::setImage(GLenum target, { ASSERT(target == GL_TEXTURE_2D && size.depth == 1); - GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, type); + const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type); bool fastUnpacked = false; GLint level = static_cast(imageLevel); - redefineImage(level, sizedInternalFormat, size, false); + ANGLE_TRY(redefineImage(context, level, internalFormatInfo.sizedInternalFormat, size, false)); gl::ImageIndex index = gl::ImageIndex::Make2D(level); // Attempt a fast gpu copy of the pixel data to the surface - if (isFastUnpackable(unpack, sizedInternalFormat) && isLevelComplete(level)) + gl::Buffer *unpackBuffer = + context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack); + if (isFastUnpackable(unpackBuffer, internalFormatInfo.sizedInternalFormat) && + isLevelComplete(level)) { // Will try to create RT storage if it does not exist - RenderTargetD3D *destRenderTarget = NULL; - gl::Error error = getRenderTarget(index, &destRenderTarget); - if (error.isError()) - { - return error; - } + RenderTargetD3D *destRenderTarget = nullptr; + ANGLE_TRY(getRenderTarget(context, index, &destRenderTarget)); gl::Box destArea(0, 0, 0, getWidth(level), getHeight(level), 1); - error = fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget); - if (error.isError()) - { - return error; - } + ANGLE_TRY(fastUnpackPixels(context, unpack, pixels, destArea, + internalFormatInfo.sizedInternalFormat, type, destRenderTarget)); // Ensure we don't overwrite our newly initialized data mImageArray[level]->markClean(); @@ -732,17 +866,14 @@ gl::Error TextureD3D_2D::setImage(GLenum target, if (!fastUnpacked) { - gl::Error error = setImageImpl(index, type, unpack, pixels, 0); - if (error.isError()) - { - return error; - } + ANGLE_TRY(setImageImpl(context, index, type, unpack, pixels, 0)); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D_2D::setSubImage(GLenum target, +gl::Error TextureD3D_2D::setSubImage(const gl::Context *context, + GLenum target, size_t imageLevel, const gl::Box &area, GLenum format, @@ -754,26 +885,26 @@ gl::Error TextureD3D_2D::setSubImage(GLenum target, GLint level = static_cast(imageLevel); gl::ImageIndex index = gl::ImageIndex::Make2D(level); - if (isFastUnpackable(unpack, getInternalFormat(level)) && isLevelComplete(level)) - { - RenderTargetD3D *renderTarget = NULL; - gl::Error error = getRenderTarget(index, &renderTarget); - if (error.isError()) - { - return error; - } + gl::Buffer *unpackBuffer = + context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack); + if (isFastUnpackable(unpackBuffer, getInternalFormat(level)) && isLevelComplete(level)) + { + RenderTargetD3D *renderTarget = nullptr; + ANGLE_TRY(getRenderTarget(context, index, &renderTarget)); ASSERT(!mImageArray[level]->isDirty()); - return fastUnpackPixels(unpack, pixels, area, getInternalFormat(level), type, renderTarget); + return fastUnpackPixels(context, unpack, pixels, area, getInternalFormat(level), type, + renderTarget); } else { - return TextureD3D::subImage(index, area, format, type, unpack, pixels, 0); + return TextureD3D::subImage(context, index, area, format, type, unpack, pixels, 0); } } -gl::Error TextureD3D_2D::setCompressedImage(GLenum target, +gl::Error TextureD3D_2D::setCompressedImage(const gl::Context *context, + GLenum target, size_t imageLevel, GLenum internalFormat, const gl::Extents &size, @@ -785,84 +916,120 @@ gl::Error TextureD3D_2D::setCompressedImage(GLenum target, GLint level = static_cast(imageLevel); // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly - redefineImage(level, internalFormat, size, false); + ANGLE_TRY(redefineImage(context, level, internalFormat, size, false)); - return setCompressedImageImpl(gl::ImageIndex::Make2D(level), unpack, pixels, 0); + return setCompressedImageImpl(context, gl::ImageIndex::Make2D(level), unpack, pixels, 0); } -gl::Error TextureD3D_2D::setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, - const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) +gl::Error TextureD3D_2D::setCompressedSubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) { ASSERT(target == GL_TEXTURE_2D && area.depth == 1 && area.z == 0); gl::ImageIndex index = gl::ImageIndex::Make2D(static_cast(level)); - gl::Error error = TextureD3D::subImageCompressed(index, area, format, unpack, pixels, 0); - if (error.isError()) - { - return error; - } + ANGLE_TRY(TextureD3D::subImageCompressed(context, index, area, format, unpack, pixels, 0)); - return commitRegion(index, area); + return commitRegion(context, index, area); } -gl::Error TextureD3D_2D::copyImage(GLenum target, +gl::Error TextureD3D_2D::copyImage(const gl::Context *context, + GLenum target, size_t imageLevel, - const gl::Rectangle &sourceArea, + const gl::Rectangle &origSourceArea, GLenum internalFormat, const gl::Framebuffer *source) { ASSERT(target == GL_TEXTURE_2D); - GLint level = static_cast(imageLevel); - GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, GL_UNSIGNED_BYTE); - redefineImage(level, sizedInternalFormat, gl::Extents(sourceArea.width, sourceArea.height, 1), - false); + GLint level = static_cast(imageLevel); + const gl::InternalFormat &internalFormatInfo = + gl::GetInternalFormatInfo(internalFormat, GL_UNSIGNED_BYTE); + gl::Extents sourceExtents(origSourceArea.width, origSourceArea.height, 1); + ANGLE_TRY(redefineImage(context, level, internalFormatInfo.sizedInternalFormat, sourceExtents, + false)); + + gl::Extents fbSize = source->getReadColorbuffer()->getSize(); + + // Does the read area extend beyond the framebuffer? + bool outside = origSourceArea.x < 0 || origSourceArea.y < 0 || + origSourceArea.x + origSourceArea.width > fbSize.width || + origSourceArea.y + origSourceArea.height > fbSize.height; + + // In WebGL mode we need to zero the texture outside the framebuffer. + // If we have robust resource init, it was already zeroed by redefineImage() above, otherwise + // zero it explicitly. + // TODO(fjhenigman): When robust resource is fully implemented look into making it a + // prerequisite for WebGL and deleting this code. + if (outside && + (context->getExtensions().webglCompatibility || context->isRobustResourceInitEnabled())) + { + angle::MemoryBuffer *zero; + ANGLE_TRY(context->getZeroFilledBuffer( + origSourceArea.width * origSourceArea.height * internalFormatInfo.pixelBytes, &zero)); + gl::PixelUnpackState unpack; + unpack.alignment = 1; + ANGLE_TRY(setImage(context, target, imageLevel, internalFormat, sourceExtents, + internalFormatInfo.format, internalFormatInfo.type, unpack, + zero->data())); + } + + gl::Rectangle sourceArea; + if (!ClipRectangle(origSourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height), + &sourceArea)) + { + // Empty source area, nothing to do. + return gl::NoError(); + } gl::ImageIndex index = gl::ImageIndex::Make2D(level); - gl::Offset destOffset(0, 0, 0); + gl::Offset destOffset(sourceArea.x - origSourceArea.x, sourceArea.y - origSourceArea.y, 0); // If the zero max LOD workaround is active, then we can't sample from individual layers of the framebuffer in shaders, // so we should use the non-rendering copy path. if (!canCreateRenderTargetForImage(index) || mRenderer->getWorkarounds().zeroMaxLodWorkaround) { - gl::Error error = mImageArray[level]->copyFromFramebuffer(destOffset, sourceArea, source); - if (error.isError()) - { - return error; - } - + ANGLE_TRY(mImageArray[level]->copyFromFramebuffer(context, destOffset, sourceArea, source)); mDirtyImages = true; } else { - gl::Error error = ensureRenderTarget(); - if (error.isError()) - { - return error; - } - - mImageArray[level]->markClean(); + ANGLE_TRY(ensureRenderTarget(context)); if (sourceArea.width != 0 && sourceArea.height != 0 && isValidLevel(level)) { - error = mRenderer->copyImage2D(source, sourceArea, internalFormat, destOffset, mTexStorage, level); - if (error.isError()) - { - return error; - } + ANGLE_TRY(updateStorageLevel(context, level)); + ANGLE_TRY(mRenderer->copyImage2D(context, source, sourceArea, internalFormat, + destOffset, mTexStorage, level)); } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D_2D::copySubImage(GLenum target, +gl::Error TextureD3D_2D::copySubImage(const gl::Context *context, + GLenum target, size_t imageLevel, - const gl::Offset &destOffset, - const gl::Rectangle &sourceArea, + const gl::Offset &origDestOffset, + const gl::Rectangle &origSourceArea, const gl::Framebuffer *source) { - ASSERT(target == GL_TEXTURE_2D && destOffset.z == 0); + ASSERT(target == GL_TEXTURE_2D && origDestOffset.z == 0); + + gl::Extents fbSize = source->getReadColorbuffer()->getSize(); + gl::Rectangle sourceArea; + if (!ClipRectangle(origSourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height), + &sourceArea)) + { + return gl::NoError(); + } + const gl::Offset destOffset(origDestOffset.x + sourceArea.x - origSourceArea.x, + origDestOffset.y + sourceArea.y - origSourceArea.y, 0); // can only make our texture storage to a render target if level 0 is defined (with a width & height) and // the current level we're copying to is defined (with appropriate format, width & height) @@ -874,44 +1041,162 @@ gl::Error TextureD3D_2D::copySubImage(GLenum target, // so we should use the non-rendering copy path. if (!canCreateRenderTargetForImage(index) || mRenderer->getWorkarounds().zeroMaxLodWorkaround) { - gl::Error error = mImageArray[level]->copyFromFramebuffer(destOffset, sourceArea, source); - if (error.isError()) - { - return error; - } - + ANGLE_TRY(mImageArray[level]->copyFromFramebuffer(context, destOffset, sourceArea, source)); mDirtyImages = true; } else { - gl::Error error = ensureRenderTarget(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(ensureRenderTarget(context)); if (isValidLevel(level)) { - error = updateStorageLevel(level); - if (error.isError()) - { - return error; - } - - error = mRenderer->copyImage2D(source, sourceArea, - gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format, - destOffset, mTexStorage, level); - if (error.isError()) - { - return error; - } + ANGLE_TRY(updateStorageLevel(context, level)); + ANGLE_TRY(mRenderer->copyImage2D(context, source, sourceArea, + gl::GetUnsizedFormat(getBaseLevelInternalFormat()), + destOffset, mTexStorage, level)); } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D_2D::setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) +gl::Error TextureD3D_2D::copyTexture(const gl::Context *context, + GLenum target, + size_t level, + GLenum internalFormat, + GLenum type, + size_t sourceLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) +{ + ASSERT(target == GL_TEXTURE_2D); + + GLenum sourceTarget = source->getTarget(); + + GLint destLevel = static_cast(level); + + const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type); + gl::Extents size(static_cast(source->getWidth(sourceTarget, sourceLevel)), + static_cast(source->getHeight(sourceTarget, sourceLevel)), 1); + ANGLE_TRY( + redefineImage(context, destLevel, internalFormatInfo.sizedInternalFormat, size, false)); + + gl::Rectangle sourceRect(0, 0, size.width, size.height); + gl::Offset destOffset(0, 0, 0); + + if (!isSRGB(destLevel) && canCreateRenderTargetForImage(gl::ImageIndex::Make2D(destLevel))) + { + ANGLE_TRY(ensureRenderTarget(context)); + ASSERT(isValidLevel(destLevel)); + ANGLE_TRY(updateStorageLevel(context, destLevel)); + + ANGLE_TRY(mRenderer->copyTexture(context, source, static_cast(sourceLevel), + sourceRect, internalFormatInfo.format, destOffset, + mTexStorage, target, destLevel, unpackFlipY, + unpackPremultiplyAlpha, unpackUnmultiplyAlpha)); + } + else + { + gl::ImageIndex sourceImageIndex = gl::ImageIndex::Make2D(static_cast(sourceLevel)); + TextureD3D *sourceD3D = GetImplAs(source); + ImageD3D *sourceImage = nullptr; + ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, sourceImageIndex, &sourceImage)); + + gl::ImageIndex destImageIndex = gl::ImageIndex::Make2D(static_cast(destLevel)); + ImageD3D *destImage = nullptr; + ANGLE_TRY(getImageAndSyncFromStorage(context, destImageIndex, &destImage)); + + ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, sourceRect, destOffset, + unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha)); + + mDirtyImages = true; + + gl::Box destRegion(destOffset, size); + ANGLE_TRY(commitRegion(context, destImageIndex, destRegion)); + } + + return gl::NoError(); +} + +gl::Error TextureD3D_2D::copySubTexture(const gl::Context *context, + GLenum target, + size_t level, + const gl::Offset &destOffset, + size_t sourceLevel, + const gl::Rectangle &sourceArea, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) +{ + ASSERT(target == GL_TEXTURE_2D); + + GLint destLevel = static_cast(level); + + if (!isSRGB(destLevel) && canCreateRenderTargetForImage(gl::ImageIndex::Make2D(destLevel))) + { + ANGLE_TRY(ensureRenderTarget(context)); + ASSERT(isValidLevel(destLevel)); + ANGLE_TRY(updateStorageLevel(context, destLevel)); + + ANGLE_TRY(mRenderer->copyTexture( + context, source, static_cast(sourceLevel), sourceArea, + gl::GetUnsizedFormat(getInternalFormat(destLevel)), destOffset, mTexStorage, target, + destLevel, unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha)); + } + else + { + gl::ImageIndex sourceImageIndex = gl::ImageIndex::Make2D(static_cast(sourceLevel)); + TextureD3D *sourceD3D = GetImplAs(source); + ImageD3D *sourceImage = nullptr; + ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, sourceImageIndex, &sourceImage)); + + gl::ImageIndex destImageIndex = gl::ImageIndex::Make2D(static_cast(destLevel)); + ImageD3D *destImage = nullptr; + ANGLE_TRY(getImageAndSyncFromStorage(context, destImageIndex, &destImage)); + + ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, sourceArea, destOffset, + unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha)); + + mDirtyImages = true; + + gl::Box destRegion(destOffset.x, destOffset.y, 0, sourceArea.width, sourceArea.height, 1); + ANGLE_TRY(commitRegion(context, destImageIndex, destRegion)); + } + + return gl::NoError(); +} + +gl::Error TextureD3D_2D::copyCompressedTexture(const gl::Context *context, + const gl::Texture *source) +{ + GLenum sourceTarget = source->getTarget(); + GLint sourceLevel = 0; + + GLint destLevel = 0; + + GLenum sizedInternalFormat = + source->getFormat(sourceTarget, sourceLevel).info->sizedInternalFormat; + gl::Extents size(static_cast(source->getWidth(sourceTarget, sourceLevel)), + static_cast(source->getHeight(sourceTarget, sourceLevel)), 1); + ANGLE_TRY(redefineImage(context, destLevel, sizedInternalFormat, size, false)); + + ANGLE_TRY(initializeStorage(context, false)); + ASSERT(mTexStorage); + + ANGLE_TRY( + mRenderer->copyCompressedTexture(context, source, sourceLevel, mTexStorage, destLevel)); + + return gl::NoError(); +} + +gl::Error TextureD3D_2D::setStorage(const gl::Context *context, + GLenum target, + size_t levels, + GLenum internalFormat, + const gl::Extents &size) { ASSERT(GL_TEXTURE_2D && size.depth == 1); @@ -920,49 +1205,38 @@ gl::Error TextureD3D_2D::setStorage(GLenum target, size_t levels, GLenum interna gl::Extents levelSize(std::max(1, size.width >> level), std::max(1, size.height >> level), 1); - redefineImage(level, internalFormat, levelSize, true); + ANGLE_TRY(redefineImage(context, level, internalFormat, levelSize, true)); } for (size_t level = levels; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) { - redefineImage(level, GL_NONE, gl::Extents(0, 0, 1), true); + ANGLE_TRY(redefineImage(context, level, GL_NONE, gl::Extents(0, 0, 1), true)); } // TODO(geofflang): Verify storage creation had no errors - bool renderTarget = IsRenderTargetUsage(mUsage); - TextureStorage *storage = mRenderer->createTextureStorage2D( - internalFormat, renderTarget, size.width, size.height, static_cast(levels), false); + bool renderTarget = IsRenderTargetUsage(mState.getUsage()); + TexStoragePointer storage(context); + storage.reset(mRenderer->createTextureStorage2D(internalFormat, renderTarget, size.width, + size.height, static_cast(levels), false)); - gl::Error error = setCompleteTexStorage(storage); - if (error.isError()) - { - SafeDelete(storage); - return error; - } + ANGLE_TRY(setCompleteTexStorage(context, storage.get())); + storage.release(); - error = updateStorage(); - - if (error.isError()) - { - return error; - } + ANGLE_TRY(updateStorage(context)); mImmutable = true; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -void TextureD3D_2D::bindTexImage(egl::Surface *surface) +gl::Error TextureD3D_2D::bindTexImage(const gl::Context *context, egl::Surface *surface) { GLenum internalformat = surface->getConfig()->renderTargetFormat; gl::Extents size(surface->getWidth(), surface->getHeight(), 1); - redefineImage(0, internalformat, size, true); + ANGLE_TRY(redefineImage(context, 0, internalformat, size, true)); - if (mTexStorage) - { - SafeDelete(mTexStorage); - } + ANGLE_TRY(releaseTexStorage(context)); SurfaceD3D *surfaceD3D = GetImplAs(surface); ASSERT(surfaceD3D); @@ -970,78 +1244,84 @@ void TextureD3D_2D::bindTexImage(egl::Surface *surface) mTexStorage = mRenderer->createTextureStorage2D(surfaceD3D->getSwapChain()); mEGLImageTarget = false; - mDirtyImages = true; + mDirtyImages = false; + mImageArray[0]->markClean(); + + return gl::NoError(); } -void TextureD3D_2D::releaseTexImage() +gl::Error TextureD3D_2D::releaseTexImage(const gl::Context *context) { if (mTexStorage) { - SafeDelete(mTexStorage); + ANGLE_TRY(releaseTexStorage(context)); } for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) { - redefineImage(i, GL_NONE, gl::Extents(0, 0, 1), true); + ANGLE_TRY(redefineImage(context, i, GL_NONE, gl::Extents(0, 0, 1), true)); } + + return gl::NoError(); } -gl::Error TextureD3D_2D::setEGLImageTarget(GLenum target, egl::Image *image) +gl::Error TextureD3D_2D::setEGLImageTarget(const gl::Context *context, + GLenum target, + egl::Image *image) { EGLImageD3D *eglImaged3d = GetImplAs(image); // Set the properties of the base mip level from the EGL image - GLenum internalformat = image->getInternalFormat(); + const auto &format = image->getFormat(); gl::Extents size(static_cast(image->getWidth()), static_cast(image->getHeight()), 1); - redefineImage(0, internalformat, size, true); + ANGLE_TRY(redefineImage(context, 0, format.info->sizedInternalFormat, size, true)); // Clear all other images. - for (size_t level = 1; level < ArraySize(mImageArray); level++) + for (size_t level = 1; level < mImageArray.size(); level++) { - redefineImage(level, GL_NONE, gl::Extents(0, 0, 1), true); + ANGLE_TRY(redefineImage(context, level, GL_NONE, gl::Extents(0, 0, 1), true)); } - SafeDelete(mTexStorage); + ANGLE_TRY(releaseTexStorage(context)); mImageArray[0]->markClean(); - mTexStorage = mRenderer->createTextureStorageEGLImage(eglImaged3d); + // Pass in the RenderTargetD3D here: createTextureStorage can't generate an error. + RenderTargetD3D *renderTargetD3D = nullptr; + ANGLE_TRY(eglImaged3d->getRenderTarget(context, &renderTargetD3D)); + + mTexStorage = mRenderer->createTextureStorageEGLImage(eglImaged3d, renderTargetD3D); mEGLImageTarget = true; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -void TextureD3D_2D::initMipmapsImages() +gl::Error TextureD3D_2D::initMipmapImages(const gl::Context *context) { - // Purge array levels 1 through q and reset them to represent the generated mipmap levels. - int levelCount = mipLevels(); - for (int level = 1; level < levelCount; level++) + const GLuint baseLevel = mState.getEffectiveBaseLevel(); + const GLuint maxLevel = mState.getMipmapMaxLevel(); + // Purge array levels baseLevel + 1 through q and reset them to represent the generated mipmap + // levels. + for (GLuint level = baseLevel + 1; level <= maxLevel; level++) { - gl::Extents levelSize(std::max(getBaseLevelWidth() >> level, 1), - std::max(getBaseLevelHeight() >> level, 1), - 1); + gl::Extents levelSize(std::max(getLevelZeroWidth() >> level, 1), + std::max(getLevelZeroHeight() >> level, 1), 1); - redefineImage(level, getBaseLevelInternalFormat(), levelSize, false); + ANGLE_TRY(redefineImage(context, level, getBaseLevelInternalFormat(), levelSize, false)); } + return gl::NoError(); } -gl::Error TextureD3D_2D::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) +gl::Error TextureD3D_2D::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) { ASSERT(!index.hasLayer()); // ensure the underlying texture is created - gl::Error error = ensureRenderTarget(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(ensureRenderTarget(context)); + ANGLE_TRY(updateStorageLevel(context, index.mipIndex)); - error = updateStorageLevel(index.mipIndex); - if (error.isError()) - { - return error; - } - - return mTexStorage->getRenderTarget(index, outRT); + return mTexStorage->getRenderTarget(context, index, outRT); } bool TextureD3D_2D::isValidLevel(int level) const @@ -1056,10 +1336,8 @@ bool TextureD3D_2D::isLevelComplete(int level) const return true; } - const ImageD3D *baseImage = getBaseLevelImage(); - - GLsizei width = baseImage->getWidth(); - GLsizei height = baseImage->getHeight(); + GLsizei width = getLevelZeroWidth(); + GLsizei height = getLevelZeroHeight(); if (width <= 0 || height <= 0) { @@ -1067,15 +1345,16 @@ bool TextureD3D_2D::isLevelComplete(int level) const } // The base image level is complete if the width and height are positive - if (level == 0) + if (level == static_cast(getBaseLevel())) { return true; } - ASSERT(level >= 1 && level <= (int)ArraySize(mImageArray) && mImageArray[level] != NULL); - ImageD3D *image = mImageArray[level]; + ASSERT(level >= 0 && level <= static_cast(mImageArray.size()) && + mImageArray[level] != nullptr); + ImageD3D *image = mImageArray[level].get(); - if (image->getInternalFormat() != baseImage->getInternalFormat()) + if (image->getInternalFormat() != getBaseLevelInternalFormat()) { return false; } @@ -1099,52 +1378,41 @@ bool TextureD3D_2D::isImageComplete(const gl::ImageIndex &index) const } // Constructs a native texture resource from the texture images -gl::Error TextureD3D_2D::initializeStorage(bool renderTarget) +gl::Error TextureD3D_2D::initializeStorage(const gl::Context *context, bool renderTarget) { // Only initialize the first time this texture is used as a render target or shader resource if (mTexStorage) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } // do not attempt to create storage for nonexistant data - if (!isLevelComplete(0)) + if (!isLevelComplete(getBaseLevel())) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } - bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mUsage)); + bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mState.getUsage())); - TextureStorage *storage = NULL; - gl::Error error = createCompleteStorage(createRenderTarget, &storage); - if (error.isError()) - { - return error; - } + TexStoragePointer storage(context); + ANGLE_TRY(createCompleteStorage(createRenderTarget, &storage)); - error = setCompleteTexStorage(storage); - if (error.isError()) - { - SafeDelete(storage); - return error; - } + ANGLE_TRY(setCompleteTexStorage(context, storage.get())); + storage.release(); ASSERT(mTexStorage); // flush image data to the storage - error = updateStorage(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(updateStorage(context)); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D_2D::createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const +gl::Error TextureD3D_2D::createCompleteStorage(bool renderTarget, + TexStoragePointer *outStorage) const { - GLsizei width = getBaseLevelWidth(); - GLsizei height = getBaseLevelHeight(); + GLsizei width = getLevelZeroWidth(); + GLsizei height = getLevelZeroHeight(); GLenum internalFormat = getBaseLevelInternalFormat(); ASSERT(width > 0 && height > 0); @@ -1165,84 +1433,83 @@ gl::Error TextureD3D_2D::createCompleteStorage(bool renderTarget, TextureStorage } // TODO(geofflang): Determine if the texture creation succeeded - *outTexStorage = mRenderer->createTextureStorage2D(internalFormat, renderTarget, width, height, levels, hintLevelZeroOnly); + outStorage->reset(mRenderer->createTextureStorage2D(internalFormat, renderTarget, width, height, + levels, hintLevelZeroOnly)); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D_2D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage) +gl::Error TextureD3D_2D::setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) { if (newCompleteTexStorage && newCompleteTexStorage->isManaged()) { for (int level = 0; level < newCompleteTexStorage->getLevelCount(); level++) { - gl::Error error = mImageArray[level]->setManagedSurface2D(newCompleteTexStorage, level); - if (error.isError()) - { - return error; - } + ANGLE_TRY( + mImageArray[level]->setManagedSurface2D(context, newCompleteTexStorage, level)); } } - SafeDelete(mTexStorage); + ANGLE_TRY(releaseTexStorage(context)); mTexStorage = newCompleteTexStorage; mDirtyImages = true; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D_2D::updateStorage() +gl::Error TextureD3D_2D::updateStorage(const gl::Context *context) { - ASSERT(mTexStorage != NULL); + if (!mDirtyImages) + { + return gl::NoError(); + } + + ASSERT(mTexStorage != nullptr); GLint storageLevels = mTexStorage->getLevelCount(); for (int level = 0; level < storageLevels; level++) { if (mImageArray[level]->isDirty() && isLevelComplete(level)) { - gl::Error error = updateStorageLevel(level); - if (error.isError()) - { - return error; - } + ANGLE_TRY(updateStorageLevel(context, level)); } } - return gl::Error(GL_NO_ERROR); + mDirtyImages = false; + return gl::NoError(); } -gl::Error TextureD3D_2D::updateStorageLevel(int level) +gl::Error TextureD3D_2D::updateStorageLevel(const gl::Context *context, int level) { - ASSERT(level <= (int)ArraySize(mImageArray) && mImageArray[level] != NULL); + ASSERT(level <= static_cast(mImageArray.size()) && mImageArray[level] != nullptr); ASSERT(isLevelComplete(level)); if (mImageArray[level]->isDirty()) { gl::ImageIndex index = gl::ImageIndex::Make2D(level); gl::Box region(0, 0, 0, getWidth(level), getHeight(level), 1); - gl::Error error = commitRegion(index, region); - if (error.isError()) - { - return error; - } + ANGLE_TRY(commitRegion(context, index, region)); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -void TextureD3D_2D::redefineImage(size_t level, - GLenum internalformat, - const gl::Extents &size, - bool forceRelease) +gl::Error TextureD3D_2D::redefineImage(const gl::Context *context, + size_t level, + GLenum internalformat, + const gl::Extents &size, + bool forceRelease) { ASSERT(size.depth == 1); // If there currently is a corresponding storage texture image, it has these parameters - const int storageWidth = std::max(1, getBaseLevelWidth() >> level); - const int storageHeight = std::max(1, getBaseLevelHeight() >> level); + const int storageWidth = std::max(1, getLevelZeroWidth() >> level); + const int storageHeight = std::max(1, getLevelZeroHeight() >> level); const GLenum storageFormat = getBaseLevelInternalFormat(); mImageArray[level]->redefine(GL_TEXTURE_2D, internalformat, size, forceRelease); + mDirtyImages = mDirtyImages || mImageArray[level]->isDirty(); if (mTexStorage) { @@ -1252,27 +1519,23 @@ void TextureD3D_2D::redefineImage(size_t level, // while orphaning if (level != 0 && mEGLImageTarget) { - // TODO(jmadill): Don't discard error. - mImageArray[0]->copyFromTexStorage(gl::ImageIndex::Make2D(0), mTexStorage); + ANGLE_TRY(mImageArray[0]->copyFromTexStorage(context, gl::ImageIndex::Make2D(0), + mTexStorage)); } - if ((level >= storageLevels && storageLevels != 0) || - size.width != storageWidth || + if ((level >= storageLevels && storageLevels != 0) || size.width != storageWidth || size.height != storageHeight || - internalformat != storageFormat) // Discard mismatched storage + internalformat != storageFormat) // Discard mismatched storage { - for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) - { - mImageArray[i]->markDirty(); - } - - SafeDelete(mTexStorage); - mDirtyImages = true; + ANGLE_TRY(releaseTexStorage(context)); + markAllImagesDirty(); } } // Can't be an EGL image target after being redefined mEGLImageTarget = false; + + return gl::NoError(); } gl::ImageIndexIterator TextureD3D_2D::imageIterator() const @@ -1292,46 +1555,58 @@ bool TextureD3D_2D::isValidIndex(const gl::ImageIndex &index) const index.mipIndex >= 0 && index.mipIndex < mTexStorage->getLevelCount()); } -TextureD3D_Cube::TextureD3D_Cube(RendererD3D *renderer) - : TextureD3D(renderer) +void TextureD3D_2D::markAllImagesDirty() { - for (int i = 0; i < 6; i++) + for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) { - for (int j = 0; j < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++j) + mImageArray[i]->markDirty(); + } + mDirtyImages = true; +} + +TextureD3D_Cube::TextureD3D_Cube(const gl::TextureState &state, RendererD3D *renderer) + : TextureD3D(state, renderer) +{ + for (auto &face : mImageArray) + { + for (auto &image : face) { - mImageArray[i][j] = renderer->createImage(); + image.reset(renderer->createImage()); } } } -TextureD3D_Cube::~TextureD3D_Cube() +gl::Error TextureD3D_Cube::onDestroy(const gl::Context *context) { - // Delete the Images before the TextureStorage. - // Images might be relying on the TextureStorage for some of their data. - // If TextureStorage is deleted before the Images, then their data will be wastefully copied back from the GPU before we delete the Images. - for (int i = 0; i < 6; i++) + // Delete the Images before the TextureStorage. Images might be relying on the TextureStorage + // for some of their data. If TextureStorage is deleted before the Images, then their data will + // be wastefully copied back from the GPU before we delete the Images. + for (auto &face : mImageArray) { - for (int j = 0; j < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++j) + for (auto &image : face) { - SafeDelete(mImageArray[i][j]); + image.reset(); } } + return TextureD3D::onDestroy(context); +} - SafeDelete(mTexStorage); +TextureD3D_Cube::~TextureD3D_Cube() +{ } ImageD3D *TextureD3D_Cube::getImage(int level, int layer) const { ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); ASSERT(layer >= 0 && layer < 6); - return mImageArray[layer][level]; + return mImageArray[layer][level].get(); } ImageD3D *TextureD3D_Cube::getImage(const gl::ImageIndex &index) const { ASSERT(index.mipIndex < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); ASSERT(index.layerIndex >= 0 && index.layerIndex < 6); - return mImageArray[index.layerIndex][index.mipIndex]; + return mImageArray[index.layerIndex][index.mipIndex].get(); } GLsizei TextureD3D_Cube::getLayerCount(int level) const @@ -1350,128 +1625,191 @@ GLenum TextureD3D_Cube::getInternalFormat(GLint level, GLint layer) const bool TextureD3D_Cube::isDepth(GLint level, GLint layer) const { - return gl::GetInternalFormatInfo(getInternalFormat(level, layer)).depthBits > 0; + return gl::GetSizedInternalFormatInfo(getInternalFormat(level, layer)).depthBits > 0; } -gl::Error TextureD3D_Cube::setEGLImageTarget(GLenum target, egl::Image *image) +bool TextureD3D_Cube::isSRGB(GLint level, GLint layer) const +{ + return gl::GetSizedInternalFormatInfo(getInternalFormat(level, layer)).colorEncoding == GL_SRGB; +} + +gl::Error TextureD3D_Cube::setEGLImageTarget(const gl::Context *context, + GLenum target, + egl::Image *image) { UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + return gl::InternalError(); } -gl::Error TextureD3D_Cube::setImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, GLenum format, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) +gl::Error TextureD3D_Cube::setImage(const gl::Context *context, + GLenum target, + size_t level, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) { ASSERT(size.depth == 1); - GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, type); + const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type); gl::ImageIndex index = gl::ImageIndex::MakeCube(target, static_cast(level)); - redefineImage(index.layerIndex, static_cast(level), sizedInternalFormat, size); + ANGLE_TRY(redefineImage(context, index.layerIndex, static_cast(level), + internalFormatInfo.sizedInternalFormat, size, false)); - return setImageImpl(index, type, unpack, pixels, 0); + return setImageImpl(context, index, type, unpack, pixels, 0); } -gl::Error TextureD3D_Cube::setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) +gl::Error TextureD3D_Cube::setSubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) { ASSERT(area.depth == 1 && area.z == 0); gl::ImageIndex index = gl::ImageIndex::MakeCube(target, static_cast(level)); - return TextureD3D::subImage(index, area, format, type, unpack, pixels, 0); + return TextureD3D::subImage(context, index, area, format, type, unpack, pixels, 0); } -gl::Error TextureD3D_Cube::setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, - const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) +gl::Error TextureD3D_Cube::setCompressedImage(const gl::Context *context, + GLenum target, + size_t level, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) { ASSERT(size.depth == 1); // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly size_t faceIndex = gl::CubeMapTextureTargetToLayerIndex(target); - redefineImage(static_cast(faceIndex), static_cast(level), internalFormat, size); + ANGLE_TRY(redefineImage(context, static_cast(faceIndex), static_cast(level), + internalFormat, size, false)); gl::ImageIndex index = gl::ImageIndex::MakeCube(target, static_cast(level)); - return setCompressedImageImpl(index, unpack, pixels, 0); + return setCompressedImageImpl(context, index, unpack, pixels, 0); } -gl::Error TextureD3D_Cube::setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, - const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) +gl::Error TextureD3D_Cube::setCompressedSubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) { ASSERT(area.depth == 1 && area.z == 0); gl::ImageIndex index = gl::ImageIndex::MakeCube(target, static_cast(level)); - gl::Error error = TextureD3D::subImageCompressed(index, area, format, unpack, pixels, 0); - if (error.isError()) - { - return error; - } - - return commitRegion(index, area); + ANGLE_TRY(TextureD3D::subImageCompressed(context, index, area, format, unpack, pixels, 0)); + return commitRegion(context, index, area); } -gl::Error TextureD3D_Cube::copyImage(GLenum target, +gl::Error TextureD3D_Cube::copyImage(const gl::Context *context, + GLenum target, size_t imageLevel, - const gl::Rectangle &sourceArea, + const gl::Rectangle &origSourceArea, GLenum internalFormat, const gl::Framebuffer *source) { int faceIndex = static_cast(gl::CubeMapTextureTargetToLayerIndex(target)); - GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, GL_UNSIGNED_BYTE); + const gl::InternalFormat &internalFormatInfo = + gl::GetInternalFormatInfo(internalFormat, GL_UNSIGNED_BYTE); GLint level = static_cast(imageLevel); - gl::Extents size(sourceArea.width, sourceArea.height, 1); - redefineImage(static_cast(faceIndex), level, sizedInternalFormat, size); + gl::Extents size(origSourceArea.width, origSourceArea.height, 1); + ANGLE_TRY(redefineImage(context, static_cast(faceIndex), level, + internalFormatInfo.sizedInternalFormat, size, false)); + + gl::Extents fbSize = source->getReadColorbuffer()->getSize(); + + // Does the read area extend beyond the framebuffer? + bool outside = origSourceArea.x < 0 || origSourceArea.y < 0 || + origSourceArea.x + origSourceArea.width > fbSize.width || + origSourceArea.y + origSourceArea.height > fbSize.height; + + // In WebGL mode we need to zero the texture outside the framebuffer. + // If we have robust resource init, it was already zeroed by redefineImage() above, otherwise + // zero it explicitly. + // TODO(fjhenigman): When robust resource is fully implemented look into making it a + // prerequisite for WebGL and deleting this code. + if (outside && context->getExtensions().webglCompatibility && + !context->isRobustResourceInitEnabled()) + { + angle::MemoryBuffer *zero; + ANGLE_TRY(context->getZeroFilledBuffer( + origSourceArea.width * origSourceArea.height * internalFormatInfo.pixelBytes, &zero)); + gl::PixelUnpackState unpack; + unpack.alignment = 1; + ANGLE_TRY(setImage(context, target, imageLevel, internalFormat, size, + internalFormatInfo.format, internalFormatInfo.type, unpack, + zero->data())); + } + + gl::Rectangle sourceArea; + if (!ClipRectangle(origSourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height), + &sourceArea)) + { + // Empty source area, nothing to do. + return gl::NoError(); + } gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level); - gl::Offset destOffset(0, 0, 0); + gl::Offset destOffset(sourceArea.x - origSourceArea.x, sourceArea.y - origSourceArea.y, 0); // If the zero max LOD workaround is active, then we can't sample from individual layers of the framebuffer in shaders, // so we should use the non-rendering copy path. if (!canCreateRenderTargetForImage(index) || mRenderer->getWorkarounds().zeroMaxLodWorkaround) { - gl::Error error = - mImageArray[faceIndex][level]->copyFromFramebuffer(destOffset, sourceArea, source); - if (error.isError()) - { - return error; - } - + ANGLE_TRY(mImageArray[faceIndex][level]->copyFromFramebuffer(context, destOffset, + sourceArea, source)); mDirtyImages = true; } else { - gl::Error error = ensureRenderTarget(); - if (error.isError()) - { - return error; - } - - mImageArray[faceIndex][level]->markClean(); + ANGLE_TRY(ensureRenderTarget(context)); ASSERT(size.width == size.height); if (size.width > 0 && isValidFaceLevel(faceIndex, level)) { - error = mRenderer->copyImageCube(source, sourceArea, internalFormat, destOffset, mTexStorage, target, level); - if (error.isError()) - { - return error; - } + ANGLE_TRY(updateStorageFaceLevel(context, faceIndex, level)); + ANGLE_TRY(mRenderer->copyImageCube(context, source, sourceArea, internalFormat, + destOffset, mTexStorage, target, level)); } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D_Cube::copySubImage(GLenum target, +gl::Error TextureD3D_Cube::copySubImage(const gl::Context *context, + GLenum target, size_t imageLevel, - const gl::Offset &destOffset, - const gl::Rectangle &sourceArea, + const gl::Offset &origDestOffset, + const gl::Rectangle &origSourceArea, const gl::Framebuffer *source) { + gl::Extents fbSize = source->getReadColorbuffer()->getSize(); + gl::Rectangle sourceArea; + if (!ClipRectangle(origSourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height), + &sourceArea)) + { + return gl::NoError(); + } + const gl::Offset destOffset(origDestOffset.x + sourceArea.x - origSourceArea.x, + origDestOffset.y + sourceArea.y - origSourceArea.y, 0); + int faceIndex = static_cast(gl::CubeMapTextureTargetToLayerIndex(target)); GLint level = static_cast(imageLevel); @@ -1481,44 +1819,145 @@ gl::Error TextureD3D_Cube::copySubImage(GLenum target, // so we should use the non-rendering copy path. if (!canCreateRenderTargetForImage(index) || mRenderer->getWorkarounds().zeroMaxLodWorkaround) { - gl::Error error = - mImageArray[faceIndex][level]->copyFromFramebuffer(destOffset, sourceArea, source); - if (error.isError()) - { - return error; - } - + ANGLE_TRY(mImageArray[faceIndex][level]->copyFromFramebuffer(context, destOffset, + sourceArea, source)); mDirtyImages = true; } else { - gl::Error error = ensureRenderTarget(); - if (error.isError()) - { - return error; - } - + ANGLE_TRY(ensureRenderTarget(context)); if (isValidFaceLevel(faceIndex, level)) { - error = updateStorageFaceLevel(faceIndex, level); - if (error.isError()) - { - return error; - } - - error = mRenderer->copyImageCube(source, sourceArea, gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format, - destOffset, mTexStorage, target, level); - if (error.isError()) - { - return error; - } + ANGLE_TRY(updateStorageFaceLevel(context, faceIndex, level)); + ANGLE_TRY(mRenderer->copyImageCube(context, source, sourceArea, + gl::GetUnsizedFormat(getBaseLevelInternalFormat()), + destOffset, mTexStorage, target, level)); } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D_Cube::setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) +gl::Error TextureD3D_Cube::copyTexture(const gl::Context *context, + GLenum target, + size_t level, + GLenum internalFormat, + GLenum type, + size_t sourceLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) +{ + ASSERT(gl::IsCubeMapTextureTarget(target)); + + GLenum sourceTarget = source->getTarget(); + + GLint destLevel = static_cast(level); + int faceIndex = static_cast(gl::CubeMapTextureTargetToLayerIndex(target)); + + const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type); + gl::Extents size(static_cast(source->getWidth(sourceTarget, sourceLevel)), + static_cast(source->getHeight(sourceTarget, sourceLevel)), 1); + ANGLE_TRY(redefineImage(context, faceIndex, destLevel, internalFormatInfo.sizedInternalFormat, + size, false)); + + gl::Rectangle sourceRect(0, 0, size.width, size.height); + gl::Offset destOffset(0, 0, 0); + + if (!isSRGB(destLevel, faceIndex) && + canCreateRenderTargetForImage(gl::ImageIndex::MakeCube(target, destLevel))) + { + ANGLE_TRY(ensureRenderTarget(context)); + ASSERT(isValidFaceLevel(faceIndex, destLevel)); + ANGLE_TRY(updateStorageFaceLevel(context, faceIndex, destLevel)); + + ANGLE_TRY(mRenderer->copyTexture(context, source, static_cast(sourceLevel), + sourceRect, internalFormatInfo.format, destOffset, + mTexStorage, target, destLevel, unpackFlipY, + unpackPremultiplyAlpha, unpackUnmultiplyAlpha)); + } + else + { + gl::ImageIndex sourceImageIndex = gl::ImageIndex::Make2D(static_cast(sourceLevel)); + TextureD3D *sourceD3D = GetImplAs(source); + ImageD3D *sourceImage = nullptr; + ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, sourceImageIndex, &sourceImage)); + + gl::ImageIndex destImageIndex = + gl::ImageIndex::MakeCube(target, static_cast(destLevel)); + ImageD3D *destImage = nullptr; + ANGLE_TRY(getImageAndSyncFromStorage(context, destImageIndex, &destImage)); + + ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, sourceRect, destOffset, + unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha)); + + mDirtyImages = true; + + gl::Box destRegion(destOffset, size); + ANGLE_TRY(commitRegion(context, destImageIndex, destRegion)); + } + + return gl::NoError(); +} + +gl::Error TextureD3D_Cube::copySubTexture(const gl::Context *context, + GLenum target, + size_t level, + const gl::Offset &destOffset, + size_t sourceLevel, + const gl::Rectangle &sourceArea, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) +{ + ASSERT(gl::IsCubeMapTextureTarget(target)); + + GLint destLevel = static_cast(level); + int faceIndex = static_cast(gl::CubeMapTextureTargetToLayerIndex(target)); + + if (!isSRGB(destLevel, faceIndex) && + canCreateRenderTargetForImage(gl::ImageIndex::MakeCube(target, destLevel))) + { + ANGLE_TRY(ensureRenderTarget(context)); + ASSERT(isValidFaceLevel(faceIndex, destLevel)); + ANGLE_TRY(updateStorageFaceLevel(context, faceIndex, destLevel)); + + ANGLE_TRY(mRenderer->copyTexture( + context, source, static_cast(sourceLevel), sourceArea, + gl::GetUnsizedFormat(getInternalFormat(destLevel, faceIndex)), destOffset, mTexStorage, + target, destLevel, unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha)); + } + else + { + gl::ImageIndex sourceImageIndex = gl::ImageIndex::Make2D(static_cast(sourceLevel)); + TextureD3D *sourceD3D = GetImplAs(source); + ImageD3D *sourceImage = nullptr; + ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, sourceImageIndex, &sourceImage)); + + gl::ImageIndex destImageIndex = + gl::ImageIndex::MakeCube(target, static_cast(destLevel)); + ImageD3D *destImage = nullptr; + ANGLE_TRY(getImageAndSyncFromStorage(context, destImageIndex, &destImage)); + + ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, sourceArea, destOffset, + unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha)); + + mDirtyImages = true; + + gl::Box destRegion(destOffset.x, destOffset.y, 0, sourceArea.width, sourceArea.height, 1); + ANGLE_TRY(commitRegion(context, destImageIndex, destRegion)); + } + + return gl::NoError(); +} + +gl::Error TextureD3D_Cube::setStorage(const gl::Context *context, + GLenum target, + size_t levels, + GLenum internalFormat, + const gl::Extents &size) { ASSERT(size.width == size.height); ASSERT(size.depth == 1); @@ -1541,28 +1980,20 @@ gl::Error TextureD3D_Cube::setStorage(GLenum target, size_t levels, GLenum inter } // TODO(geofflang): Verify storage creation had no errors - bool renderTarget = IsRenderTargetUsage(mUsage); + bool renderTarget = IsRenderTargetUsage(mState.getUsage()); - TextureStorage *storage = mRenderer->createTextureStorageCube( - internalFormat, renderTarget, size.width, static_cast(levels), false); + TexStoragePointer storage(context); + storage.reset(mRenderer->createTextureStorageCube(internalFormat, renderTarget, size.width, + static_cast(levels), false)); - gl::Error error = setCompleteTexStorage(storage); - if (error.isError()) - { - SafeDelete(storage); - return error; - } + ANGLE_TRY(setCompleteTexStorage(context, storage.get())); + storage.release(); - error = updateStorage(); - - if (error.isError()) - { - return error; - } + ANGLE_TRY(updateStorage(context)); mImmutable = true; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } // Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81. @@ -1579,7 +2010,7 @@ bool TextureD3D_Cube::isCubeComplete() const for (int faceIndex = 1; faceIndex < 6; faceIndex++) { - const ImageD3D &faceBaseImage = *mImageArray[faceIndex][0]; + const ImageD3D &faceBaseImage = *mImageArray[faceIndex][getBaseLevel()]; if (faceBaseImage.getWidth() != baseWidth || faceBaseImage.getHeight() != baseHeight || @@ -1592,97 +2023,85 @@ bool TextureD3D_Cube::isCubeComplete() const return true; } -void TextureD3D_Cube::bindTexImage(egl::Surface *surface) +gl::Error TextureD3D_Cube::bindTexImage(const gl::Context *context, egl::Surface *surface) { UNREACHABLE(); + return gl::InternalError(); } -void TextureD3D_Cube::releaseTexImage() +gl::Error TextureD3D_Cube::releaseTexImage(const gl::Context *context) { UNREACHABLE(); + return gl::InternalError(); } - -void TextureD3D_Cube::initMipmapsImages() +gl::Error TextureD3D_Cube::initMipmapImages(const gl::Context *context) { - // Purge array levels 1 through q and reset them to represent the generated mipmap levels. - int levelCount = mipLevels(); + const GLuint baseLevel = mState.getEffectiveBaseLevel(); + const GLuint maxLevel = mState.getMipmapMaxLevel(); + // Purge array levels baseLevel + 1 through q and reset them to represent the generated mipmap + // levels. for (int faceIndex = 0; faceIndex < 6; faceIndex++) { - for (int level = 1; level < levelCount; level++) + for (GLuint level = baseLevel + 1; level <= maxLevel; level++) { - int faceLevelSize = (std::max(mImageArray[faceIndex][0]->getWidth() >> level, 1)); - redefineImage(faceIndex, level, mImageArray[faceIndex][0]->getInternalFormat(), - gl::Extents(faceLevelSize, faceLevelSize, 1)); + int faceLevelSize = + (std::max(mImageArray[faceIndex][baseLevel]->getWidth() >> (level - baseLevel), 1)); + ANGLE_TRY(redefineImage(context, faceIndex, level, + mImageArray[faceIndex][baseLevel]->getInternalFormat(), + gl::Extents(faceLevelSize, faceLevelSize, 1), false)); } } + return gl::NoError(); } -gl::Error TextureD3D_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) +gl::Error TextureD3D_Cube::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) { ASSERT(gl::IsCubeMapTextureTarget(index.type)); // ensure the underlying texture is created - gl::Error error = ensureRenderTarget(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(ensureRenderTarget(context)); + ANGLE_TRY(updateStorageFaceLevel(context, index.layerIndex, index.mipIndex)); - error = updateStorageFaceLevel(index.layerIndex, index.mipIndex); - if (error.isError()) - { - return error; - } - - return mTexStorage->getRenderTarget(index, outRT); + return mTexStorage->getRenderTarget(context, index, outRT); } -gl::Error TextureD3D_Cube::initializeStorage(bool renderTarget) +gl::Error TextureD3D_Cube::initializeStorage(const gl::Context *context, bool renderTarget) { // Only initialize the first time this texture is used as a render target or shader resource if (mTexStorage) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } // do not attempt to create storage for nonexistant data - if (!isFaceLevelComplete(0, 0)) + if (!isFaceLevelComplete(0, getBaseLevel())) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } - bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mUsage)); + bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mState.getUsage())); - TextureStorage *storage = NULL; - gl::Error error = createCompleteStorage(createRenderTarget, &storage); - if (error.isError()) - { - return error; - } + TexStoragePointer storage(context); + ANGLE_TRY(createCompleteStorage(createRenderTarget, &storage)); - error = setCompleteTexStorage(storage); - if (error.isError()) - { - SafeDelete(storage); - return error; - } + ANGLE_TRY(setCompleteTexStorage(context, storage.get())); + storage.release(); ASSERT(mTexStorage); // flush image data to the storage - error = updateStorage(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(updateStorage(context)); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D_Cube::createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const +gl::Error TextureD3D_Cube::createCompleteStorage(bool renderTarget, + TexStoragePointer *outStorage) const { - GLsizei size = getBaseLevelWidth(); + GLsizei size = getLevelZeroWidth(); ASSERT(size > 0); @@ -1705,12 +2124,14 @@ gl::Error TextureD3D_Cube::createCompleteStorage(bool renderTarget, TextureStora } // TODO (geofflang): detect if storage creation succeeded - *outTexStorage = mRenderer->createTextureStorageCube(getBaseLevelInternalFormat(), renderTarget, size, levels, hintLevelZeroOnly); + outStorage->reset(mRenderer->createTextureStorageCube( + getBaseLevelInternalFormat(), renderTarget, size, levels, hintLevelZeroOnly)); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D_Cube::setCompleteTexStorage(TextureStorage *newCompleteTexStorage) +gl::Error TextureD3D_Cube::setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) { if (newCompleteTexStorage && newCompleteTexStorage->isManaged()) { @@ -1718,25 +2139,27 @@ gl::Error TextureD3D_Cube::setCompleteTexStorage(TextureStorage *newCompleteTexS { for (int level = 0; level < newCompleteTexStorage->getLevelCount(); level++) { - gl::Error error = mImageArray[faceIndex][level]->setManagedSurfaceCube(newCompleteTexStorage, faceIndex, level); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mImageArray[faceIndex][level]->setManagedSurfaceCube( + context, newCompleteTexStorage, faceIndex, level)); } } } - SafeDelete(mTexStorage); + ANGLE_TRY(releaseTexStorage(context)); mTexStorage = newCompleteTexStorage; mDirtyImages = true; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D_Cube::updateStorage() +gl::Error TextureD3D_Cube::updateStorage(const gl::Context *context) { - ASSERT(mTexStorage != NULL); + if (!mDirtyImages) + { + return gl::NoError(); + } + + ASSERT(mTexStorage != nullptr); GLint storageLevels = mTexStorage->getLevelCount(); for (int face = 0; face < 6; face++) { @@ -1744,16 +2167,13 @@ gl::Error TextureD3D_Cube::updateStorage() { if (mImageArray[face][level]->isDirty() && isFaceLevelComplete(face, level)) { - gl::Error error = updateStorageFaceLevel(face, level); - if (error.isError()) - { - return error; - } + ANGLE_TRY(updateStorageFaceLevel(context, face, level)); } } } - return gl::Error(GL_NO_ERROR); + mDirtyImages = false; + return gl::NoError(); } bool TextureD3D_Cube::isValidFaceLevel(int faceIndex, int level) const @@ -1763,16 +2183,21 @@ bool TextureD3D_Cube::isValidFaceLevel(int faceIndex, int level) const bool TextureD3D_Cube::isFaceLevelComplete(int faceIndex, int level) const { - ASSERT(level >= 0 && faceIndex < 6 && level < (int)ArraySize(mImageArray[faceIndex]) && mImageArray[faceIndex][level] != NULL); + if (getBaseLevel() >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + return false; + } + ASSERT(level >= 0 && faceIndex < 6 && level < static_cast(mImageArray[faceIndex].size()) && + mImageArray[faceIndex][level] != nullptr); if (isImmutable()) { return true; } - int baseSize = getBaseLevelWidth(); + int levelZeroSize = getLevelZeroWidth(); - if (baseSize <= 0) + if (levelZeroSize <= 0) { return false; } @@ -1786,14 +2211,14 @@ bool TextureD3D_Cube::isFaceLevelComplete(int faceIndex, int level) const } // Check that non-zero levels are consistent with the base level. - const ImageD3D *faceLevelImage = mImageArray[faceIndex][level]; + const ImageD3D *faceLevelImage = mImageArray[faceIndex][level].get(); if (faceLevelImage->getInternalFormat() != getBaseLevelInternalFormat()) { return false; } - if (faceLevelImage->getWidth() != std::max(1, baseSize >> level)) + if (faceLevelImage->getWidth() != std::max(1, levelZeroSize >> level)) { return false; } @@ -1806,57 +2231,55 @@ bool TextureD3D_Cube::isImageComplete(const gl::ImageIndex &index) const return isFaceLevelComplete(index.layerIndex, index.mipIndex); } -gl::Error TextureD3D_Cube::updateStorageFaceLevel(int faceIndex, int level) +gl::Error TextureD3D_Cube::updateStorageFaceLevel(const gl::Context *context, + int faceIndex, + int level) { - ASSERT(level >= 0 && faceIndex < 6 && level < (int)ArraySize(mImageArray[faceIndex]) && mImageArray[faceIndex][level] != NULL); - ImageD3D *image = mImageArray[faceIndex][level]; + ASSERT(level >= 0 && faceIndex < 6 && level < static_cast(mImageArray[faceIndex].size()) && + mImageArray[faceIndex][level] != nullptr); + ImageD3D *image = mImageArray[faceIndex][level].get(); if (image->isDirty()) { GLenum faceTarget = gl::LayerIndexToCubeMapTextureTarget(faceIndex); gl::ImageIndex index = gl::ImageIndex::MakeCube(faceTarget, level); gl::Box region(0, 0, 0, image->getWidth(), image->getHeight(), 1); - gl::Error error = commitRegion(index, region); - if (error.isError()) - { - return error; - } + ANGLE_TRY(commitRegion(context, index, region)); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -void TextureD3D_Cube::redefineImage(int faceIndex, GLint level, GLenum internalformat, const gl::Extents &size) +gl::Error TextureD3D_Cube::redefineImage(const gl::Context *context, + int faceIndex, + GLint level, + GLenum internalformat, + const gl::Extents &size, + bool forceRelease) { // If there currently is a corresponding storage texture image, it has these parameters - const int storageWidth = std::max(1, getBaseLevelWidth() >> level); - const int storageHeight = std::max(1, getBaseLevelHeight() >> level); + const int storageWidth = std::max(1, getLevelZeroWidth() >> level); + const int storageHeight = std::max(1, getLevelZeroHeight() >> level); const GLenum storageFormat = getBaseLevelInternalFormat(); - mImageArray[faceIndex][level]->redefine(GL_TEXTURE_CUBE_MAP, internalformat, size, false); + mImageArray[faceIndex][level]->redefine(GL_TEXTURE_CUBE_MAP, internalformat, size, + forceRelease); + mDirtyImages = mDirtyImages || mImageArray[faceIndex][level]->isDirty(); if (mTexStorage) { const int storageLevels = mTexStorage->getLevelCount(); - if ((level >= storageLevels && storageLevels != 0) || - size.width != storageWidth || + if ((level >= storageLevels && storageLevels != 0) || size.width != storageWidth || size.height != storageHeight || - internalformat != storageFormat) // Discard mismatched storage + internalformat != storageFormat) // Discard mismatched storage { - for (int dirtyLevel = 0; dirtyLevel < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; dirtyLevel++) - { - for (int dirtyFace = 0; dirtyFace < 6; dirtyFace++) - { - mImageArray[dirtyFace][dirtyLevel]->markDirty(); - } - } - - SafeDelete(mTexStorage); - - mDirtyImages = true; + markAllImagesDirty(); + ANGLE_TRY(releaseTexStorage(context)); } } + + return gl::NoError(); } gl::ImageIndexIterator TextureD3D_Cube::imageIterator() const @@ -1876,33 +2299,48 @@ bool TextureD3D_Cube::isValidIndex(const gl::ImageIndex &index) const index.mipIndex >= 0 && index.mipIndex < mTexStorage->getLevelCount()); } -TextureD3D_3D::TextureD3D_3D(RendererD3D *renderer) - : TextureD3D(renderer) +void TextureD3D_Cube::markAllImagesDirty() +{ + for (int dirtyLevel = 0; dirtyLevel < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; dirtyLevel++) + { + for (int dirtyFace = 0; dirtyFace < 6; dirtyFace++) + { + mImageArray[dirtyFace][dirtyLevel]->markDirty(); + } + } + mDirtyImages = true; +} + +TextureD3D_3D::TextureD3D_3D(const gl::TextureState &state, RendererD3D *renderer) + : TextureD3D(state, renderer) { for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i) { - mImageArray[i] = renderer->createImage(); + mImageArray[i].reset(renderer->createImage()); } } +gl::Error TextureD3D_3D::onDestroy(const gl::Context *context) +{ + // Delete the Images before the TextureStorage. Images might be relying on the TextureStorage + // for some of their data. If TextureStorage is deleted before the Images, then their data will + // be wastefully copied back from the GPU before we delete the Images. + for (auto &image : mImageArray) + { + image.reset(); + } + return TextureD3D::onDestroy(context); +} + TextureD3D_3D::~TextureD3D_3D() { - // Delete the Images before the TextureStorage. - // Images might be relying on the TextureStorage for some of their data. - // If TextureStorage is deleted before the Images, then their data will be wastefully copied back from the GPU before we delete the Images. - for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i) - { - delete mImageArray[i]; - } - - SafeDelete(mTexStorage); } ImageD3D *TextureD3D_3D::getImage(int level, int layer) const { ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); ASSERT(layer == 0); - return mImageArray[level]; + return mImageArray[level].get(); } ImageD3D *TextureD3D_3D::getImage(const gl::ImageIndex &index) const @@ -1910,7 +2348,7 @@ ImageD3D *TextureD3D_3D::getImage(const gl::ImageIndex &index) const ASSERT(index.mipIndex < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); ASSERT(!index.hasLayer()); ASSERT(index.type == GL_TEXTURE_3D); - return mImageArray[index.mipIndex]; + return mImageArray[index.mipIndex].get(); } GLsizei TextureD3D_3D::getLayerCount(int level) const @@ -1953,16 +2391,19 @@ GLenum TextureD3D_3D::getInternalFormat(GLint level) const bool TextureD3D_3D::isDepth(GLint level) const { - return gl::GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0; + return gl::GetSizedInternalFormatInfo(getInternalFormat(level)).depthBits > 0; } -gl::Error TextureD3D_3D::setEGLImageTarget(GLenum target, egl::Image *image) +gl::Error TextureD3D_3D::setEGLImageTarget(const gl::Context *context, + GLenum target, + egl::Image *image) { UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + return gl::InternalError(); } -gl::Error TextureD3D_3D::setImage(GLenum target, +gl::Error TextureD3D_3D::setImage(const gl::Context *context, + GLenum target, size_t imageLevel, GLenum internalFormat, const gl::Extents &size, @@ -1972,33 +2413,29 @@ gl::Error TextureD3D_3D::setImage(GLenum target, const uint8_t *pixels) { ASSERT(target == GL_TEXTURE_3D); - GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, type); + const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type); GLint level = static_cast(imageLevel); - redefineImage(level, sizedInternalFormat, size); + ANGLE_TRY(redefineImage(context, level, internalFormatInfo.sizedInternalFormat, size, false)); bool fastUnpacked = false; gl::ImageIndex index = gl::ImageIndex::Make3D(level); // Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer - if (isFastUnpackable(unpack, sizedInternalFormat) && !size.empty()) + gl::Buffer *unpackBuffer = + context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack); + if (isFastUnpackable(unpackBuffer, internalFormatInfo.sizedInternalFormat) && !size.empty() && + isLevelComplete(level)) { // Will try to create RT storage if it does not exist - RenderTargetD3D *destRenderTarget = NULL; - gl::Error error = getRenderTarget(index, &destRenderTarget); - if (error.isError()) - { - return error; - } + RenderTargetD3D *destRenderTarget = nullptr; + ANGLE_TRY(getRenderTarget(context, index, &destRenderTarget)); gl::Box destArea(0, 0, 0, getWidth(level), getHeight(level), getDepth(level)); - error = fastUnpackPixels(unpack, pixels, destArea, sizedInternalFormat, type, destRenderTarget); - if (error.isError()) - { - return error; - } + ANGLE_TRY(fastUnpackPixels(context, unpack, pixels, destArea, + internalFormatInfo.sizedInternalFormat, type, destRenderTarget)); // Ensure we don't overwrite our newly initialized data mImageArray[level]->markClean(); @@ -2008,17 +2445,14 @@ gl::Error TextureD3D_3D::setImage(GLenum target, if (!fastUnpacked) { - gl::Error error = setImageImpl(index, type, unpack, pixels, 0); - if (error.isError()) - { - return error; - } + ANGLE_TRY(setImageImpl(context, index, type, unpack, pixels, 0)); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D_3D::setSubImage(GLenum target, +gl::Error TextureD3D_3D::setSubImage(const gl::Context *context, + GLenum target, size_t imageLevel, const gl::Box &area, GLenum format, @@ -2032,26 +2466,25 @@ gl::Error TextureD3D_3D::setSubImage(GLenum target, gl::ImageIndex index = gl::ImageIndex::Make3D(level); // Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer - if (isFastUnpackable(unpack, getInternalFormat(level))) + gl::Buffer *unpackBuffer = + context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack); + if (isFastUnpackable(unpackBuffer, getInternalFormat(level)) && isLevelComplete(level)) { - RenderTargetD3D *destRenderTarget = NULL; - gl::Error error = getRenderTarget(index, &destRenderTarget); - if (error.isError()) - { - return error; - } - + RenderTargetD3D *destRenderTarget = nullptr; + ANGLE_TRY(getRenderTarget(context, index, &destRenderTarget)); ASSERT(!mImageArray[level]->isDirty()); - return fastUnpackPixels(unpack, pixels, area, getInternalFormat(level), type, destRenderTarget); + return fastUnpackPixels(context, unpack, pixels, area, getInternalFormat(level), type, + destRenderTarget); } else { - return TextureD3D::subImage(index, area, format, type, unpack, pixels, 0); + return TextureD3D::subImage(context, index, area, format, type, unpack, pixels, 0); } } -gl::Error TextureD3D_3D::setCompressedImage(GLenum target, +gl::Error TextureD3D_3D::setCompressedImage(const gl::Context *context, + GLenum target, size_t imageLevel, GLenum internalFormat, const gl::Extents &size, @@ -2063,35 +2496,41 @@ gl::Error TextureD3D_3D::setCompressedImage(GLenum target, GLint level = static_cast(imageLevel); // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly - redefineImage(level, internalFormat, size); + ANGLE_TRY(redefineImage(context, level, internalFormat, size, false)); gl::ImageIndex index = gl::ImageIndex::Make3D(level); - return setCompressedImageImpl(index, unpack, pixels, 0); + return setCompressedImageImpl(context, index, unpack, pixels, 0); } -gl::Error TextureD3D_3D::setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, - const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) +gl::Error TextureD3D_3D::setCompressedSubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) { ASSERT(target == GL_TEXTURE_3D); gl::ImageIndex index = gl::ImageIndex::Make3D(static_cast(level)); - gl::Error error = TextureD3D::subImageCompressed(index, area, format, unpack, pixels, 0); - if (error.isError()) - { - return error; - } - - return commitRegion(index, area); + ANGLE_TRY(TextureD3D::subImageCompressed(context, index, area, format, unpack, pixels, 0)); + return commitRegion(context, index, area); } -gl::Error TextureD3D_3D::copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat, +gl::Error TextureD3D_3D::copyImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Rectangle &sourceArea, + GLenum internalFormat, const gl::Framebuffer *source) { UNIMPLEMENTED(); - return gl::Error(GL_INVALID_OPERATION, "Copying 3D textures is unimplemented."); + return gl::InternalError() << "Copying 3D textures is unimplemented."; } -gl::Error TextureD3D_3D::copySubImage(GLenum target, +gl::Error TextureD3D_3D::copySubImage(const gl::Context *context, + GLenum target, size_t imageLevel, const gl::Offset &destOffset, const gl::Rectangle &sourceArea, @@ -2099,49 +2538,47 @@ gl::Error TextureD3D_3D::copySubImage(GLenum target, { ASSERT(target == GL_TEXTURE_3D); - GLint level = static_cast(imageLevel); - gl::ImageIndex index = gl::ImageIndex::Make3D(level); + GLint level = static_cast(imageLevel); - if (canCreateRenderTargetForImage(index)) + gl::Extents fbSize = source->getReadColorbuffer()->getSize(); + gl::Rectangle clippedSourceArea; + if (!ClipRectangle(sourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height), + &clippedSourceArea)) { - gl::Error error = mImageArray[level]->copyFromFramebuffer(destOffset, sourceArea, source); - if (error.isError()) - { - return error; - } - - mDirtyImages = true; + return gl::NoError(); } - else + const gl::Offset clippedDestOffset(destOffset.x + clippedSourceArea.x - sourceArea.x, + destOffset.y + clippedSourceArea.y - sourceArea.y, + destOffset.z); + + // Currently, copying directly to the storage is not possible because it's not possible to + // create an SRV from a single layer of a 3D texture. Instead, make sure the image is up to + // date before the copy and then copy back to the storage afterwards if needed. + // TODO: Investigate 3D blits in D3D11. + + bool syncTexStorage = mTexStorage && isLevelComplete(level); + if (syncTexStorage) { - gl::Error error = ensureRenderTarget(); - if (error.isError()) - { - return error; - } + gl::ImageIndex index = gl::ImageIndex::Make3D(level); + ANGLE_TRY(mImageArray[level]->copyFromTexStorage(context, index, mTexStorage)); + } + ANGLE_TRY(mImageArray[level]->copyFromFramebuffer(context, clippedDestOffset, clippedSourceArea, + source)); + mDirtyImages = true; - if (isValidLevel(level)) - { - error = updateStorageLevel(level); - if (error.isError()) - { - return error; - } - - error = mRenderer->copyImage3D(source, sourceArea, - gl::GetInternalFormatInfo(getBaseLevelInternalFormat()).format, - destOffset, mTexStorage, level); - if (error.isError()) - { - return error; - } - } + if (syncTexStorage) + { + ANGLE_TRY(updateStorageLevel(context, level)); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D_3D::setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) +gl::Error TextureD3D_3D::setStorage(const gl::Context *context, + GLenum target, + size_t levels, + GLenum internalFormat, + const gl::Extents &size) { ASSERT(target == GL_TEXTURE_3D); @@ -2159,130 +2596,106 @@ gl::Error TextureD3D_3D::setStorage(GLenum target, size_t levels, GLenum interna } // TODO(geofflang): Verify storage creation had no errors - bool renderTarget = IsRenderTargetUsage(mUsage); - TextureStorage *storage = - mRenderer->createTextureStorage3D(internalFormat, renderTarget, size.width, size.height, - size.depth, static_cast(levels)); + bool renderTarget = IsRenderTargetUsage(mState.getUsage()); + TexStoragePointer storage(context); + storage.reset(mRenderer->createTextureStorage3D(internalFormat, renderTarget, size.width, + size.height, size.depth, + static_cast(levels))); - gl::Error error = setCompleteTexStorage(storage); - if (error.isError()) - { - SafeDelete(storage); - return error; - } + ANGLE_TRY(setCompleteTexStorage(context, storage.get())); + storage.release(); - error = updateStorage(); - - if (error.isError()) - { - return error; - } + ANGLE_TRY(updateStorage(context)); mImmutable = true; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -void TextureD3D_3D::bindTexImage(egl::Surface *surface) +gl::Error TextureD3D_3D::bindTexImage(const gl::Context *context, egl::Surface *surface) { UNREACHABLE(); + return gl::InternalError(); } -void TextureD3D_3D::releaseTexImage() +gl::Error TextureD3D_3D::releaseTexImage(const gl::Context *context) { UNREACHABLE(); + return gl::InternalError(); } - -void TextureD3D_3D::initMipmapsImages() +gl::Error TextureD3D_3D::initMipmapImages(const gl::Context *context) { - // Purge array levels 1 through q and reset them to represent the generated mipmap levels. - int levelCount = mipLevels(); - for (int level = 1; level < levelCount; level++) + const GLuint baseLevel = mState.getEffectiveBaseLevel(); + const GLuint maxLevel = mState.getMipmapMaxLevel(); + // Purge array levels baseLevel + 1 through q and reset them to represent the generated mipmap + // levels. + for (GLuint level = baseLevel + 1; level <= maxLevel; level++) { - gl::Extents levelSize(std::max(getBaseLevelWidth() >> level, 1), - std::max(getBaseLevelHeight() >> level, 1), - std::max(getBaseLevelDepth() >> level, 1)); - redefineImage(level, getBaseLevelInternalFormat(), levelSize); + gl::Extents levelSize(std::max(getLevelZeroWidth() >> level, 1), + std::max(getLevelZeroHeight() >> level, 1), + std::max(getLevelZeroDepth() >> level, 1)); + ANGLE_TRY(redefineImage(context, level, getBaseLevelInternalFormat(), levelSize, false)); } + + return gl::NoError(); } -gl::Error TextureD3D_3D::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) +gl::Error TextureD3D_3D::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) { // ensure the underlying texture is created - gl::Error error = ensureRenderTarget(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(ensureRenderTarget(context)); if (index.hasLayer()) { - error = updateStorage(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(updateStorage(context)); } else { - error = updateStorageLevel(index.mipIndex); - if (error.isError()) - { - return error; - } + ANGLE_TRY(updateStorageLevel(context, index.mipIndex)); } - return mTexStorage->getRenderTarget(index, outRT); + return mTexStorage->getRenderTarget(context, index, outRT); } -gl::Error TextureD3D_3D::initializeStorage(bool renderTarget) +gl::Error TextureD3D_3D::initializeStorage(const gl::Context *context, bool renderTarget) { // Only initialize the first time this texture is used as a render target or shader resource if (mTexStorage) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } // do not attempt to create storage for nonexistant data - if (!isLevelComplete(0)) + if (!isLevelComplete(getBaseLevel())) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } - bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mUsage)); + bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mState.getUsage())); - TextureStorage *storage = NULL; - gl::Error error = createCompleteStorage(createRenderTarget, &storage); - if (error.isError()) - { - return error; - } + TexStoragePointer storage(context); + ANGLE_TRY(createCompleteStorage(createRenderTarget, &storage)); - error = setCompleteTexStorage(storage); - if (error.isError()) - { - SafeDelete(storage); - return error; - } + ANGLE_TRY(setCompleteTexStorage(context, storage.get())); + storage.release(); ASSERT(mTexStorage); // flush image data to the storage - error = updateStorage(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(updateStorage(context)); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D_3D::createCompleteStorage(bool renderTarget, TextureStorage **outStorage) const +gl::Error TextureD3D_3D::createCompleteStorage(bool renderTarget, + TexStoragePointer *outStorage) const { - GLsizei width = getBaseLevelWidth(); - GLsizei height = getBaseLevelHeight(); - GLsizei depth = getBaseLevelDepth(); + GLsizei width = getLevelZeroWidth(); + GLsizei height = getLevelZeroHeight(); + GLsizei depth = getLevelZeroDepth(); GLenum internalFormat = getBaseLevelInternalFormat(); ASSERT(width > 0 && height > 0 && depth > 0); @@ -2291,40 +2704,44 @@ gl::Error TextureD3D_3D::createCompleteStorage(bool renderTarget, TextureStorage GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, depth)); // TODO: Verify creation of the storage succeeded - *outStorage = mRenderer->createTextureStorage3D(internalFormat, renderTarget, width, height, depth, levels); + outStorage->reset(mRenderer->createTextureStorage3D(internalFormat, renderTarget, width, height, + depth, levels)); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D_3D::setCompleteTexStorage(TextureStorage *newCompleteTexStorage) +gl::Error TextureD3D_3D::setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) { - SafeDelete(mTexStorage); + ANGLE_TRY(releaseTexStorage(context)); mTexStorage = newCompleteTexStorage; mDirtyImages = true; // We do not support managed 3D storage, as that is D3D9/ES2-only ASSERT(!mTexStorage->isManaged()); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D_3D::updateStorage() +gl::Error TextureD3D_3D::updateStorage(const gl::Context *context) { - ASSERT(mTexStorage != NULL); + if (!mDirtyImages) + { + return gl::NoError(); + } + + ASSERT(mTexStorage != nullptr); GLint storageLevels = mTexStorage->getLevelCount(); for (int level = 0; level < storageLevels; level++) { if (mImageArray[level]->isDirty() && isLevelComplete(level)) { - gl::Error error = updateStorageLevel(level); - if (error.isError()) - { - return error; - } + ANGLE_TRY(updateStorageLevel(context, level)); } } - return gl::Error(GL_NO_ERROR); + mDirtyImages = false; + return gl::NoError(); } bool TextureD3D_3D::isValidLevel(int level) const @@ -2334,28 +2751,29 @@ bool TextureD3D_3D::isValidLevel(int level) const bool TextureD3D_3D::isLevelComplete(int level) const { - ASSERT(level >= 0 && level < (int)ArraySize(mImageArray) && mImageArray[level] != NULL); + ASSERT(level >= 0 && level < static_cast(mImageArray.size()) && + mImageArray[level] != nullptr); if (isImmutable()) { return true; } - GLsizei width = getBaseLevelWidth(); - GLsizei height = getBaseLevelHeight(); - GLsizei depth = getBaseLevelDepth(); + GLsizei width = getLevelZeroWidth(); + GLsizei height = getLevelZeroHeight(); + GLsizei depth = getLevelZeroDepth(); if (width <= 0 || height <= 0 || depth <= 0) { return false; } - if (level == 0) + if (level == static_cast(getBaseLevel())) { return true; } - ImageD3D *levelImage = mImageArray[level]; + ImageD3D *levelImage = mImageArray[level].get(); if (levelImage->getInternalFormat() != getBaseLevelInternalFormat()) { @@ -2385,54 +2803,51 @@ bool TextureD3D_3D::isImageComplete(const gl::ImageIndex &index) const return isLevelComplete(index.mipIndex); } -gl::Error TextureD3D_3D::updateStorageLevel(int level) +gl::Error TextureD3D_3D::updateStorageLevel(const gl::Context *context, int level) { - ASSERT(level >= 0 && level < (int)ArraySize(mImageArray) && mImageArray[level] != NULL); + ASSERT(level >= 0 && level < static_cast(mImageArray.size()) && + mImageArray[level] != nullptr); ASSERT(isLevelComplete(level)); if (mImageArray[level]->isDirty()) { gl::ImageIndex index = gl::ImageIndex::Make3D(level); gl::Box region(0, 0, 0, getWidth(level), getHeight(level), getDepth(level)); - gl::Error error = commitRegion(index, region); - if (error.isError()) - { - return error; - } + ANGLE_TRY(commitRegion(context, index, region)); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -void TextureD3D_3D::redefineImage(GLint level, GLenum internalformat, const gl::Extents &size) +gl::Error TextureD3D_3D::redefineImage(const gl::Context *context, + GLint level, + GLenum internalformat, + const gl::Extents &size, + bool forceRelease) { // If there currently is a corresponding storage texture image, it has these parameters - const int storageWidth = std::max(1, getBaseLevelWidth() >> level); - const int storageHeight = std::max(1, getBaseLevelHeight() >> level); - const int storageDepth = std::max(1, getBaseLevelDepth() >> level); + const int storageWidth = std::max(1, getLevelZeroWidth() >> level); + const int storageHeight = std::max(1, getLevelZeroHeight() >> level); + const int storageDepth = std::max(1, getLevelZeroDepth() >> level); const GLenum storageFormat = getBaseLevelInternalFormat(); - mImageArray[level]->redefine(GL_TEXTURE_3D, internalformat, size, false); + mImageArray[level]->redefine(GL_TEXTURE_3D, internalformat, size, forceRelease); + mDirtyImages = mDirtyImages || mImageArray[level]->isDirty(); if (mTexStorage) { const int storageLevels = mTexStorage->getLevelCount(); - if ((level >= storageLevels && storageLevels != 0) || - size.width != storageWidth || - size.height != storageHeight || - size.depth != storageDepth || - internalformat != storageFormat) // Discard mismatched storage + if ((level >= storageLevels && storageLevels != 0) || size.width != storageWidth || + size.height != storageHeight || size.depth != storageDepth || + internalformat != storageFormat) // Discard mismatched storage { - for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) - { - mImageArray[i]->markDirty(); - } - - SafeDelete(mTexStorage); - mDirtyImages = true; + markAllImagesDirty(); + ANGLE_TRY(releaseTexStorage(context)); } } + + return gl::NoError(); } gl::ImageIndexIterator TextureD3D_3D::imageIterator() const @@ -2453,23 +2868,42 @@ bool TextureD3D_3D::isValidIndex(const gl::ImageIndex &index) const index.mipIndex >= 0 && index.mipIndex < mTexStorage->getLevelCount()); } -TextureD3D_2DArray::TextureD3D_2DArray(RendererD3D *renderer) - : TextureD3D(renderer) +void TextureD3D_3D::markAllImagesDirty() +{ + for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + { + mImageArray[i]->markDirty(); + } + mDirtyImages = true; +} + +GLint TextureD3D_3D::getLevelZeroDepth() const +{ + ASSERT(gl::CountLeadingZeros(static_cast(getBaseLevelDepth())) > getBaseLevel()); + return getBaseLevelDepth() << getBaseLevel(); +} + +TextureD3D_2DArray::TextureD3D_2DArray(const gl::TextureState &state, RendererD3D *renderer) + : TextureD3D(state, renderer) { for (int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level) { mLayerCounts[level] = 0; - mImageArray[level] = NULL; + mImageArray[level] = nullptr; } } +gl::Error TextureD3D_2DArray::onDestroy(const gl::Context *context) +{ + // Delete the Images before the TextureStorage. Images might be relying on the TextureStorage + // for some of their data. If TextureStorage is deleted before the Images, then their data will + // be wastefully copied back from the GPU before we delete the Images. + deleteImages(); + return TextureD3D::onDestroy(context); +} + TextureD3D_2DArray::~TextureD3D_2DArray() { - // Delete the Images before the TextureStorage. - // Images might be relying on the TextureStorage for some of their data. - // If TextureStorage is deleted before the Images, then their data will be wastefully copied back from the GPU before we delete the Images. - deleteImages(); - SafeDelete(mTexStorage); } ImageD3D *TextureD3D_2DArray::getImage(int level, int layer) const @@ -2477,16 +2911,17 @@ ImageD3D *TextureD3D_2DArray::getImage(int level, int layer) const ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); ASSERT((layer == 0 && mLayerCounts[level] == 0) || layer < mLayerCounts[level]); - return (mImageArray[level] ? mImageArray[level][layer] : NULL); + return (mImageArray[level] ? mImageArray[level][layer] : nullptr); } ImageD3D *TextureD3D_2DArray::getImage(const gl::ImageIndex &index) const { ASSERT(index.mipIndex < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT(index.layerIndex != gl::ImageIndex::ENTIRE_LEVEL); ASSERT((index.layerIndex == 0 && mLayerCounts[index.mipIndex] == 0) || index.layerIndex < mLayerCounts[index.mipIndex]); ASSERT(index.type == GL_TEXTURE_2D_ARRAY); - return (mImageArray[index.mipIndex] ? mImageArray[index.mipIndex][index.layerIndex] : NULL); + return (mImageArray[index.mipIndex] ? mImageArray[index.mipIndex][index.layerIndex] : nullptr); } GLsizei TextureD3D_2DArray::getLayerCount(int level) const @@ -2512,16 +2947,19 @@ GLenum TextureD3D_2DArray::getInternalFormat(GLint level) const bool TextureD3D_2DArray::isDepth(GLint level) const { - return gl::GetInternalFormatInfo(getInternalFormat(level)).depthBits > 0; + return gl::GetSizedInternalFormatInfo(getInternalFormat(level)).depthBits > 0; } -gl::Error TextureD3D_2DArray::setEGLImageTarget(GLenum target, egl::Image *image) +gl::Error TextureD3D_2DArray::setEGLImageTarget(const gl::Context *context, + GLenum target, + egl::Image *image) { UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + return gl::InternalError(); } -gl::Error TextureD3D_2DArray::setImage(GLenum target, +gl::Error TextureD3D_2DArray::setImage(const gl::Context *context, + GLenum target, size_t imageLevel, GLenum internalFormat, const gl::Extents &size, @@ -2532,30 +2970,28 @@ gl::Error TextureD3D_2DArray::setImage(GLenum target, { ASSERT(target == GL_TEXTURE_2D_ARRAY); - GLenum sizedInternalFormat = gl::GetSizedInternalFormat(internalFormat, type); + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat, type); GLint level = static_cast(imageLevel); - redefineImage(level, sizedInternalFormat, size); + ANGLE_TRY(redefineImage(context, level, formatInfo.sizedInternalFormat, size, false)); - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(sizedInternalFormat); - GLsizei inputDepthPitch = formatInfo.computeDepthPitch( - type, size.width, size.height, unpack.alignment, unpack.rowLength, unpack.imageHeight); + GLsizei inputDepthPitch = 0; + ANGLE_TRY_RESULT(formatInfo.computeDepthPitch(type, size.width, size.height, unpack.alignment, + unpack.rowLength, unpack.imageHeight), + inputDepthPitch); for (int i = 0; i < size.depth; i++) { const ptrdiff_t layerOffset = (inputDepthPitch * i); gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, i); - gl::Error error = setImageImpl(index, type, unpack, pixels, layerOffset); - if (error.isError()) - { - return error; - } + ANGLE_TRY(setImageImpl(context, index, type, unpack, pixels, layerOffset)); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D_2DArray::setSubImage(GLenum target, +gl::Error TextureD3D_2DArray::setSubImage(const gl::Context *context, + GLenum target, size_t imageLevel, const gl::Box &area, GLenum format, @@ -2565,9 +3001,12 @@ gl::Error TextureD3D_2DArray::setSubImage(GLenum target, { ASSERT(target == GL_TEXTURE_2D_ARRAY); GLint level = static_cast(imageLevel); - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(getInternalFormat(level)); - GLsizei inputDepthPitch = formatInfo.computeDepthPitch( - type, area.width, area.height, unpack.alignment, unpack.rowLength, unpack.imageHeight); + const gl::InternalFormat &formatInfo = + gl::GetInternalFormatInfo(getInternalFormat(level), type); + GLsizei inputDepthPitch = 0; + ANGLE_TRY_RESULT(formatInfo.computeDepthPitch(type, area.width, area.height, unpack.alignment, + unpack.rowLength, unpack.imageHeight), + inputDepthPitch); for (int i = 0; i < area.depth; i++) { @@ -2577,17 +3016,15 @@ gl::Error TextureD3D_2DArray::setSubImage(GLenum target, gl::Box layerArea(area.x, area.y, 0, area.width, area.height, 1); gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, layer); - gl::Error error = TextureD3D::subImage(index, layerArea, format, type, unpack, pixels, layerOffset); - if (error.isError()) - { - return error; - } + ANGLE_TRY(TextureD3D::subImage(context, index, layerArea, format, type, unpack, pixels, + layerOffset)); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D_2DArray::setCompressedImage(GLenum target, +gl::Error TextureD3D_2DArray::setCompressedImage(const gl::Context *context, + GLenum target, size_t imageLevel, GLenum internalFormat, const gl::Extents &size, @@ -2599,35 +3036,41 @@ gl::Error TextureD3D_2DArray::setCompressedImage(GLenum target, GLint level = static_cast(imageLevel); // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly - redefineImage(level, internalFormat, size); + ANGLE_TRY(redefineImage(context, level, internalFormat, size, false)); - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); - GLsizei inputDepthPitch = - formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, size.width, size.height, 1, 0, 0); + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalFormat); + GLsizei inputDepthPitch = 0; + ANGLE_TRY_RESULT( + formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, size.width, size.height, 1, 0, 0), + inputDepthPitch); for (int i = 0; i < size.depth; i++) { const ptrdiff_t layerOffset = (inputDepthPitch * i); gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, i); - gl::Error error = setCompressedImageImpl(index, unpack, pixels, layerOffset); - if (error.isError()) - { - return error; - } + ANGLE_TRY(setCompressedImageImpl(context, index, unpack, pixels, layerOffset)); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D_2DArray::setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, - const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) +gl::Error TextureD3D_2DArray::setCompressedSubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) { ASSERT(target == GL_TEXTURE_2D_ARRAY); - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format); - GLsizei inputDepthPitch = - formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0, 0); + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(format); + GLsizei inputDepthPitch = 0; + ANGLE_TRY_RESULT( + formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0, 0), + inputDepthPitch); for (int i = 0; i < area.depth; i++) { @@ -2637,30 +3080,27 @@ gl::Error TextureD3D_2DArray::setCompressedSubImage(GLenum target, size_t level, gl::Box layerArea(area.x, area.y, 0, area.width, area.height, 1); gl::ImageIndex index = gl::ImageIndex::Make2DArray(static_cast(level), layer); - gl::Error error = TextureD3D::subImageCompressed(index, layerArea, format, unpack, pixels, layerOffset); - if (error.isError()) - { - return error; - } - - error = commitRegion(index, layerArea); - if (error.isError()) - { - return error; - } + ANGLE_TRY(TextureD3D::subImageCompressed(context, index, layerArea, format, unpack, pixels, + layerOffset)); + ANGLE_TRY(commitRegion(context, index, layerArea)); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D_2DArray::copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat, +gl::Error TextureD3D_2DArray::copyImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Rectangle &sourceArea, + GLenum internalFormat, const gl::Framebuffer *source) { UNIMPLEMENTED(); - return gl::Error(GL_INVALID_OPERATION, "Copying 2D array textures is unimplemented."); + return gl::InternalError() << "Copying 2D array textures is unimplemented."; } -gl::Error TextureD3D_2DArray::copySubImage(GLenum target, +gl::Error TextureD3D_2DArray::copySubImage(const gl::Context *context, + GLenum target, size_t imageLevel, const gl::Offset &destOffset, const gl::Rectangle &sourceArea, @@ -2671,46 +3111,45 @@ gl::Error TextureD3D_2DArray::copySubImage(GLenum target, GLint level = static_cast(imageLevel); gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, destOffset.z); - if (canCreateRenderTargetForImage(index)) + gl::Extents fbSize = source->getReadColorbuffer()->getSize(); + gl::Rectangle clippedSourceArea; + if (!ClipRectangle(sourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height), + &clippedSourceArea)) { - gl::Offset destLayerOffset(destOffset.x, destOffset.y, 0); - gl::Error error = mImageArray[level][destOffset.z]->copyFromFramebuffer(destLayerOffset, - sourceArea, source); - if (error.isError()) - { - return error; - } + return gl::NoError(); + } + const gl::Offset clippedDestOffset(destOffset.x + clippedSourceArea.x - sourceArea.x, + destOffset.y + clippedSourceArea.y - sourceArea.y, + destOffset.z); + if (!canCreateRenderTargetForImage(index)) + { + gl::Offset destLayerOffset(clippedDestOffset.x, clippedDestOffset.y, 0); + ANGLE_TRY(mImageArray[level][clippedDestOffset.z]->copyFromFramebuffer( + context, destLayerOffset, clippedSourceArea, source)); mDirtyImages = true; } else { - gl::Error error = ensureRenderTarget(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(ensureRenderTarget(context)); if (isValidLevel(level)) { - error = updateStorageLevel(level); - if (error.isError()) - { - return error; - } - - error = mRenderer->copyImage2DArray(source, sourceArea, gl::GetInternalFormatInfo(getInternalFormat(0)).format, - destOffset, mTexStorage, level); - if (error.isError()) - { - return error; - } + ANGLE_TRY(updateStorageLevel(context, level)); + ANGLE_TRY( + mRenderer->copyImage2DArray(context, source, clippedSourceArea, + gl::GetUnsizedFormat(getInternalFormat(getBaseLevel())), + clippedDestOffset, mTexStorage, level)); } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D_2DArray::setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) +gl::Error TextureD3D_2DArray::setStorage(const gl::Context *context, + GLenum target, + size_t levels, + GLenum internalFormat, + const gl::Extents &size) { ASSERT(target == GL_TEXTURE_2D_ARRAY); @@ -2738,124 +3177,103 @@ gl::Error TextureD3D_2DArray::setStorage(GLenum target, size_t levels, GLenum in } // TODO(geofflang): Verify storage creation had no errors - bool renderTarget = IsRenderTargetUsage(mUsage); - TextureStorage *storage = - mRenderer->createTextureStorage2DArray(internalFormat, renderTarget, size.width, - size.height, size.depth, static_cast(levels)); + bool renderTarget = IsRenderTargetUsage(mState.getUsage()); + TexStoragePointer storage(context); + storage.reset(mRenderer->createTextureStorage2DArray(internalFormat, renderTarget, size.width, + size.height, size.depth, + static_cast(levels))); - gl::Error error = setCompleteTexStorage(storage); - if (error.isError()) - { - SafeDelete(storage); - return error; - } + ANGLE_TRY(setCompleteTexStorage(context, storage.get())); + storage.release(); - error = updateStorage(); - - if (error.isError()) - { - return error; - } + ANGLE_TRY(updateStorage(context)); mImmutable = true; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -void TextureD3D_2DArray::bindTexImage(egl::Surface *surface) +gl::Error TextureD3D_2DArray::bindTexImage(const gl::Context *context, egl::Surface *surface) { UNREACHABLE(); + return gl::InternalError(); } -void TextureD3D_2DArray::releaseTexImage() +gl::Error TextureD3D_2DArray::releaseTexImage(const gl::Context *context) { UNREACHABLE(); + return gl::InternalError(); } - -void TextureD3D_2DArray::initMipmapsImages() +gl::Error TextureD3D_2DArray::initMipmapImages(const gl::Context *context) { - int baseWidth = getBaseLevelWidth(); - int baseHeight = getBaseLevelHeight(); - int baseDepth = getLayerCount(0); + const GLuint baseLevel = mState.getEffectiveBaseLevel(); + const GLuint maxLevel = mState.getMipmapMaxLevel(); + int baseWidth = getLevelZeroWidth(); + int baseHeight = getLevelZeroHeight(); + int baseDepth = getLayerCount(getBaseLevel()); GLenum baseFormat = getBaseLevelInternalFormat(); - // Purge array levels 1 through q and reset them to represent the generated mipmap levels. - int levelCount = mipLevels(); - for (int level = 1; level < levelCount; level++) + // Purge array levels baseLevel + 1 through q and reset them to represent the generated mipmap + // levels. + for (GLuint level = baseLevel + 1u; level <= maxLevel; level++) { + ASSERT((baseWidth >> level) > 0 || (baseHeight >> level) > 0); gl::Extents levelLayerSize(std::max(baseWidth >> level, 1), std::max(baseHeight >> level, 1), baseDepth); - redefineImage(level, baseFormat, levelLayerSize); + ANGLE_TRY(redefineImage(context, level, baseFormat, levelLayerSize, false)); } + + return gl::NoError(); } -gl::Error TextureD3D_2DArray::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) +gl::Error TextureD3D_2DArray::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) { // ensure the underlying texture is created - gl::Error error = ensureRenderTarget(); - if (error.isError()) - { - return error; - } - - error = updateStorageLevel(index.mipIndex); - if (error.isError()) - { - return error; - } - - return mTexStorage->getRenderTarget(index, outRT); + ANGLE_TRY(ensureRenderTarget(context)); + ANGLE_TRY(updateStorageLevel(context, index.mipIndex)); + return mTexStorage->getRenderTarget(context, index, outRT); } -gl::Error TextureD3D_2DArray::initializeStorage(bool renderTarget) +gl::Error TextureD3D_2DArray::initializeStorage(const gl::Context *context, bool renderTarget) { // Only initialize the first time this texture is used as a render target or shader resource if (mTexStorage) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } // do not attempt to create storage for nonexistant data - if (!isLevelComplete(0)) + if (!isLevelComplete(getBaseLevel())) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } - bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mUsage)); + bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mState.getUsage())); - TextureStorage *storage = NULL; - gl::Error error = createCompleteStorage(createRenderTarget, &storage); - if (error.isError()) - { - return error; - } + TexStoragePointer storage(context); + ANGLE_TRY(createCompleteStorage(createRenderTarget, &storage)); - error = setCompleteTexStorage(storage); - if (error.isError()) - { - SafeDelete(storage); - return error; - } + ANGLE_TRY(setCompleteTexStorage(context, storage.get())); + storage.release(); ASSERT(mTexStorage); // flush image data to the storage - error = updateStorage(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(updateStorage(context)); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D_2DArray::createCompleteStorage(bool renderTarget, TextureStorage **outStorage) const +gl::Error TextureD3D_2DArray::createCompleteStorage(bool renderTarget, + TexStoragePointer *outStorage) const { - GLsizei width = getBaseLevelWidth(); - GLsizei height = getBaseLevelHeight(); - GLsizei depth = getLayerCount(0); + GLsizei width = getLevelZeroWidth(); + GLsizei height = getLevelZeroHeight(); + GLsizei depth = getLayerCount(getBaseLevel()); GLenum internalFormat = getBaseLevelInternalFormat(); ASSERT(width > 0 && height > 0 && depth > 0); @@ -2864,40 +3282,44 @@ gl::Error TextureD3D_2DArray::createCompleteStorage(bool renderTarget, TextureSt GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, 1)); // TODO(geofflang): Verify storage creation succeeds - *outStorage = mRenderer->createTextureStorage2DArray(internalFormat, renderTarget, width, height, depth, levels); + outStorage->reset(mRenderer->createTextureStorage2DArray(internalFormat, renderTarget, width, + height, depth, levels)); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D_2DArray::setCompleteTexStorage(TextureStorage *newCompleteTexStorage) +gl::Error TextureD3D_2DArray::setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) { - SafeDelete(mTexStorage); + ANGLE_TRY(releaseTexStorage(context)); mTexStorage = newCompleteTexStorage; mDirtyImages = true; // We do not support managed 2D array storage, as managed storage is ES2/D3D9 only ASSERT(!mTexStorage->isManaged()); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureD3D_2DArray::updateStorage() +gl::Error TextureD3D_2DArray::updateStorage(const gl::Context *context) { - ASSERT(mTexStorage != NULL); + if (!mDirtyImages) + { + return gl::NoError(); + } + + ASSERT(mTexStorage != nullptr); GLint storageLevels = mTexStorage->getLevelCount(); for (int level = 0; level < storageLevels; level++) { if (isLevelComplete(level)) { - gl::Error error = updateStorageLevel(level); - if (error.isError()) - { - return error; - } + ANGLE_TRY(updateStorageLevel(context, level)); } } - return gl::Error(GL_NO_ERROR); + mDirtyImages = false; + return gl::NoError(); } bool TextureD3D_2DArray::isValidLevel(int level) const @@ -2914,21 +3336,29 @@ bool TextureD3D_2DArray::isLevelComplete(int level) const return true; } - GLsizei width = getBaseLevelWidth(); - GLsizei height = getBaseLevelHeight(); - GLsizei layers = getLayerCount(0); + GLsizei width = getLevelZeroWidth(); + GLsizei height = getLevelZeroHeight(); - if (width <= 0 || height <= 0 || layers <= 0) + if (width <= 0 || height <= 0) { return false; } - if (level == 0) + // Layers check needs to happen after the above checks, otherwise out-of-range base level may be + // queried. + GLsizei layers = getLayerCount(getBaseLevel()); + + if (layers <= 0) + { + return false; + } + + if (level == static_cast(getBaseLevel())) { return true; } - if (getInternalFormat(level) != getInternalFormat(0)) + if (getInternalFormat(level) != getInternalFormat(getBaseLevel())) { return false; } @@ -2956,27 +3386,23 @@ bool TextureD3D_2DArray::isImageComplete(const gl::ImageIndex &index) const return isLevelComplete(index.mipIndex); } -gl::Error TextureD3D_2DArray::updateStorageLevel(int level) +gl::Error TextureD3D_2DArray::updateStorageLevel(const gl::Context *context, int level) { - ASSERT(level >= 0 && level < (int)ArraySize(mLayerCounts)); + ASSERT(level >= 0 && level < static_cast(ArraySize(mLayerCounts))); ASSERT(isLevelComplete(level)); for (int layer = 0; layer < mLayerCounts[level]; layer++) { - ASSERT(mImageArray[level] != NULL && mImageArray[level][layer] != NULL); + ASSERT(mImageArray[level] != nullptr && mImageArray[level][layer] != nullptr); if (mImageArray[level][layer]->isDirty()) { gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, layer); gl::Box region(0, 0, 0, getWidth(level), getHeight(level), 1); - gl::Error error = commitRegion(index, region); - if (error.isError()) - { - return error; - } + ANGLE_TRY(commitRegion(context, index, region)); } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } void TextureD3D_2DArray::deleteImages() @@ -2988,18 +3414,26 @@ void TextureD3D_2DArray::deleteImages() delete mImageArray[level][layer]; } delete[] mImageArray[level]; - mImageArray[level] = NULL; + mImageArray[level] = nullptr; mLayerCounts[level] = 0; } } -void TextureD3D_2DArray::redefineImage(GLint level, GLenum internalformat, const gl::Extents &size) +gl::Error TextureD3D_2DArray::redefineImage(const gl::Context *context, + GLint level, + GLenum internalformat, + const gl::Extents &size, + bool forceRelease) { // If there currently is a corresponding storage texture image, it has these parameters - const int storageWidth = std::max(1, getBaseLevelWidth() >> level); - const int storageHeight = std::max(1, getBaseLevelHeight() >> level); - const int storageDepth = getLayerCount(0); - const GLenum storageFormat = getBaseLevelInternalFormat(); + const int storageWidth = std::max(1, getLevelZeroWidth() >> level); + const int storageHeight = std::max(1, getLevelZeroHeight() >> level); + const GLuint baseLevel = getBaseLevel(); + int storageDepth = 0; + if (baseLevel < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + storageDepth = getLayerCount(baseLevel); + } // Only reallocate the layers if the size doesn't match if (size.depth != mLayerCounts[level]) @@ -3026,33 +3460,27 @@ void TextureD3D_2DArray::redefineImage(GLint level, GLenum internalformat, const for (int layer = 0; layer < mLayerCounts[level]; layer++) { mImageArray[level][layer]->redefine(GL_TEXTURE_2D_ARRAY, internalformat, - gl::Extents(size.width, size.height, 1), false); + gl::Extents(size.width, size.height, 1), + forceRelease); + mDirtyImages = mDirtyImages || mImageArray[level][layer]->isDirty(); } } if (mTexStorage) { + const GLenum storageFormat = getBaseLevelInternalFormat(); const int storageLevels = mTexStorage->getLevelCount(); - if ((level >= storageLevels && storageLevels != 0) || - size.width != storageWidth || - size.height != storageHeight || - size.depth != storageDepth || - internalformat != storageFormat) // Discard mismatched storage + if ((level >= storageLevels && storageLevels != 0) || size.width != storageWidth || + size.height != storageHeight || size.depth != storageDepth || + internalformat != storageFormat) // Discard mismatched storage { - for (int dirtyLevel = 0; dirtyLevel < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; dirtyLevel++) - { - for (int dirtyLayer = 0; dirtyLayer < mLayerCounts[dirtyLevel]; dirtyLayer++) - { - mImageArray[dirtyLevel][dirtyLayer]->markDirty(); - } - } - - delete mTexStorage; - mTexStorage = NULL; - mDirtyImages = true; + markAllImagesDirty(); + ANGLE_TRY(releaseTexStorage(context)); } } + + return gl::NoError(); } gl::ImageIndexIterator TextureD3D_2DArray::imageIterator() const @@ -3083,4 +3511,464 @@ bool TextureD3D_2DArray::isValidIndex(const gl::ImageIndex &index) const return (!index.hasLayer() || (index.layerIndex >= 0 && index.layerIndex < mLayerCounts[index.mipIndex])); } +void TextureD3D_2DArray::markAllImagesDirty() +{ + for (int dirtyLevel = 0; dirtyLevel < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; dirtyLevel++) + { + for (int dirtyLayer = 0; dirtyLayer < mLayerCounts[dirtyLevel]; dirtyLayer++) + { + mImageArray[dirtyLevel][dirtyLayer]->markDirty(); + } + } + mDirtyImages = true; } + +TextureD3D_External::TextureD3D_External(const gl::TextureState &state, RendererD3D *renderer) + : TextureD3D(state, renderer) +{ +} + +TextureD3D_External::~TextureD3D_External() +{ +} + +ImageD3D *TextureD3D_External::getImage(const gl::ImageIndex &index) const +{ + UNREACHABLE(); + return nullptr; +} + +GLsizei TextureD3D_External::getLayerCount(int level) const +{ + return 1; +} + +gl::Error TextureD3D_External::setImage(const gl::Context *context, + GLenum target, + size_t imageLevel, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) +{ + // Image setting is not supported for external images + UNREACHABLE(); + return gl::InternalError(); +} + +gl::Error TextureD3D_External::setSubImage(const gl::Context *context, + GLenum target, + size_t imageLevel, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) +{ + UNREACHABLE(); + return gl::InternalError(); +} + +gl::Error TextureD3D_External::setCompressedImage(const gl::Context *context, + GLenum target, + size_t imageLevel, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) +{ + UNREACHABLE(); + return gl::InternalError(); +} + +gl::Error TextureD3D_External::setCompressedSubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) +{ + UNREACHABLE(); + return gl::InternalError(); +} + +gl::Error TextureD3D_External::copyImage(const gl::Context *context, + GLenum target, + size_t imageLevel, + const gl::Rectangle &sourceArea, + GLenum internalFormat, + const gl::Framebuffer *source) +{ + UNREACHABLE(); + return gl::InternalError(); +} + +gl::Error TextureD3D_External::copySubImage(const gl::Context *context, + GLenum target, + size_t imageLevel, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + const gl::Framebuffer *source) +{ + UNREACHABLE(); + return gl::InternalError(); +} + +gl::Error TextureD3D_External::setStorage(const gl::Context *context, + GLenum target, + size_t levels, + GLenum internalFormat, + const gl::Extents &size) +{ + UNREACHABLE(); + return gl::InternalError(); +} + +gl::Error TextureD3D_External::setImageExternal(const gl::Context *context, + GLenum target, + egl::Stream *stream, + const egl::Stream::GLTextureDescription &desc) +{ + ASSERT(target == GL_TEXTURE_EXTERNAL_OES); + + ANGLE_TRY(releaseTexStorage(context)); + + // If the stream is null, the external image is unbound and we release the storage + if (stream != nullptr) + { + mTexStorage = mRenderer->createTextureStorageExternal(stream, desc); + } + + return gl::NoError(); +} + +gl::Error TextureD3D_External::bindTexImage(const gl::Context *context, egl::Surface *surface) +{ + UNREACHABLE(); + return gl::InternalError(); +} + +gl::Error TextureD3D_External::releaseTexImage(const gl::Context *context) +{ + UNREACHABLE(); + return gl::InternalError(); +} + +gl::Error TextureD3D_External::setEGLImageTarget(const gl::Context *context, + GLenum target, + egl::Image *image) +{ + EGLImageD3D *eglImaged3d = GetImplAs(image); + + // Pass in the RenderTargetD3D here: createTextureStorage can't generate an error. + RenderTargetD3D *renderTargetD3D = nullptr; + ANGLE_TRY(eglImaged3d->getRenderTarget(context, &renderTargetD3D)); + + ANGLE_TRY(releaseTexStorage(context)); + mTexStorage = mRenderer->createTextureStorageEGLImage(eglImaged3d, renderTargetD3D); + + return gl::NoError(); +} + +gl::Error TextureD3D_External::initMipmapImages(const gl::Context *context) +{ + UNREACHABLE(); + return gl::InternalError(); +} + +gl::Error TextureD3D_External::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) +{ + UNREACHABLE(); + return gl::InternalError(); +} + +bool TextureD3D_External::isImageComplete(const gl::ImageIndex &index) const +{ + return (index.mipIndex == 0) ? (mTexStorage != nullptr) : false; +} + +gl::Error TextureD3D_External::initializeStorage(const gl::Context *context, bool renderTarget) +{ + // Texture storage is created when an external image is bound + ASSERT(mTexStorage); + return gl::NoError(); +} + +gl::Error TextureD3D_External::createCompleteStorage(bool renderTarget, + TexStoragePointer *outStorage) const +{ + UNREACHABLE(); + return gl::NoError(); +} + +gl::Error TextureD3D_External::setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) +{ + UNREACHABLE(); + return gl::NoError(); +} + +gl::Error TextureD3D_External::updateStorage(const gl::Context *context) +{ + // Texture storage does not need to be updated since it is already loaded with the latest + // external image + ASSERT(mTexStorage); + return gl::NoError(); +} + +gl::ImageIndexIterator TextureD3D_External::imageIterator() const +{ + return gl::ImageIndexIterator::Make2D(0, mTexStorage->getLevelCount()); +} + +gl::ImageIndex TextureD3D_External::getImageIndex(GLint mip, GLint /*layer*/) const +{ + // "layer" does not apply to 2D Textures. + return gl::ImageIndex::Make2D(mip); +} + +bool TextureD3D_External::isValidIndex(const gl::ImageIndex &index) const +{ + return (mTexStorage && index.type == GL_TEXTURE_EXTERNAL_OES && index.mipIndex == 0); +} + +void TextureD3D_External::markAllImagesDirty() +{ + UNREACHABLE(); +} + +TextureD3D_2DMultisample::TextureD3D_2DMultisample(const gl::TextureState &state, + RendererD3D *renderer) + : TextureD3D(state, renderer) +{ +} + +TextureD3D_2DMultisample::~TextureD3D_2DMultisample() +{ +} + +ImageD3D *TextureD3D_2DMultisample::getImage(const gl::ImageIndex &index) const +{ + return nullptr; +} + +gl::Error TextureD3D_2DMultisample::setImage(const gl::Context *context, + GLenum target, + size_t level, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) +{ + UNREACHABLE(); + return gl::InternalError(); +} + +gl::Error TextureD3D_2DMultisample::setSubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) +{ + UNREACHABLE(); + return gl::InternalError(); +} + +gl::Error TextureD3D_2DMultisample::setCompressedImage(const gl::Context *context, + GLenum target, + size_t level, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) +{ + UNREACHABLE(); + return gl::InternalError(); +} + +gl::Error TextureD3D_2DMultisample::setCompressedSubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) +{ + UNREACHABLE(); + return gl::InternalError(); +} + +gl::Error TextureD3D_2DMultisample::copyImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Rectangle &sourceArea, + GLenum internalFormat, + const gl::Framebuffer *source) +{ + UNREACHABLE(); + return gl::InternalError(); +} + +gl::Error TextureD3D_2DMultisample::copySubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + const gl::Framebuffer *source) +{ + UNREACHABLE(); + return gl::InternalError(); +} + +gl::Error TextureD3D_2DMultisample::setStorageMultisample(const gl::Context *context, + GLenum target, + GLsizei samples, + GLint internalFormat, + const gl::Extents &size, + bool fixedSampleLocations) +{ + ASSERT(target == GL_TEXTURE_2D_MULTISAMPLE && size.depth == 1); + + TexStoragePointer storage(context); + storage.reset(mRenderer->createTextureStorage2DMultisample(internalFormat, size.width, + size.height, static_cast(0), + samples, fixedSampleLocations)); + + ANGLE_TRY(setCompleteTexStorage(context, storage.get())); + storage.release(); + + ANGLE_TRY(updateStorage(context)); + + mImmutable = false; + + return gl::NoError(); +} + +gl::Error TextureD3D_2DMultisample::bindTexImage(const gl::Context *context, egl::Surface *surface) +{ + UNREACHABLE(); + return gl::NoError(); +} + +gl::Error TextureD3D_2DMultisample::releaseTexImage(const gl::Context *context) +{ + UNREACHABLE(); + return gl::NoError(); +} + +gl::Error TextureD3D_2DMultisample::setEGLImageTarget(const gl::Context *context, + GLenum target, + egl::Image *image) +{ + UNREACHABLE(); + return gl::InternalError(); +} + +gl::Error TextureD3D_2DMultisample::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) +{ + ASSERT(!index.hasLayer()); + + // ensure the underlying texture is created + ANGLE_TRY(ensureRenderTarget(context)); + + return mTexStorage->getRenderTarget(context, index, outRT); +} + +gl::ImageIndexIterator TextureD3D_2DMultisample::imageIterator() const +{ + return gl::ImageIndexIterator::Make2DMultisample(); +} + +gl::ImageIndex TextureD3D_2DMultisample::getImageIndex(GLint mip, GLint layer) const +{ + return gl::ImageIndex::Make2DMultisample(); +} + +bool TextureD3D_2DMultisample::isValidIndex(const gl::ImageIndex &index) const +{ + return (mTexStorage && index.type == GL_TEXTURE_2D_MULTISAMPLE && index.mipIndex == 0); +} + +GLsizei TextureD3D_2DMultisample::getLayerCount(int level) const +{ + return 1; +} + +void TextureD3D_2DMultisample::markAllImagesDirty() +{ +} + +gl::Error TextureD3D_2DMultisample::initializeStorage(const gl::Context *context, bool renderTarget) +{ + // Only initialize the first time this texture is used as a render target or shader resource + if (mTexStorage) + { + return gl::NoError(); + } + + bool createRenderTarget = (renderTarget || IsRenderTargetUsage(mState.getUsage())); + + TexStoragePointer storage(context); + ANGLE_TRY(createCompleteStorage(createRenderTarget, &storage)); + + ANGLE_TRY(setCompleteTexStorage(context, storage.get())); + storage.release(); + + ASSERT(mTexStorage); + + // flush image data to the storage + ANGLE_TRY(updateStorage(context)); + + return gl::NoError(); +} + +gl::Error TextureD3D_2DMultisample::createCompleteStorage(bool renderTarget, + TexStoragePointer *outStorage) const +{ + outStorage->reset(mTexStorage); + + return gl::NoError(); +} + +gl::Error TextureD3D_2DMultisample::setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) +{ + ANGLE_TRY(releaseTexStorage(context)); + mTexStorage = newCompleteTexStorage; + + return gl::NoError(); +} + +gl::Error TextureD3D_2DMultisample::updateStorage(const gl::Context *context) +{ + return gl::NoError(); +} + +gl::Error TextureD3D_2DMultisample::initMipmapImages(const gl::Context *context) +{ + UNIMPLEMENTED(); + return gl::NoError(); +} + +bool TextureD3D_2DMultisample::isImageComplete(const gl::ImageIndex &index) const +{ + return true; +} + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureD3D.h index 1d5faee703..eb206a6ccc 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureD3D.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureD3D.h @@ -9,9 +9,12 @@ #ifndef LIBANGLE_RENDERER_D3D_TEXTURED3D_H_ #define LIBANGLE_RENDERER_D3D_TEXTURED3D_H_ -#include "libANGLE/renderer/TextureImpl.h" -#include "libANGLE/angletypes.h" +#include "common/Color.h" #include "libANGLE/Constants.h" +#include "libANGLE/Stream.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/renderer/TextureImpl.h" +#include "libANGLE/renderer/d3d/TextureStorage.h" namespace gl { @@ -26,29 +29,51 @@ class RendererD3D; class RenderTargetD3D; class TextureStorage; +template +using TexLevelsArray = std::array; + class TextureD3D : public TextureImpl { public: - TextureD3D(RendererD3D *renderer); - virtual ~TextureD3D(); + TextureD3D(const gl::TextureState &data, RendererD3D *renderer); + ~TextureD3D() override; - gl::Error getNativeTexture(TextureStorage **outStorage); + gl::Error onDestroy(const gl::Context *context) override; + + gl::Error getNativeTexture(const gl::Context *context, TextureStorage **outStorage); - virtual void setUsage(GLenum usage) { mUsage = usage; } bool hasDirtyImages() const { return mDirtyImages; } void resetDirty() { mDirtyImages = false; } virtual ImageD3D *getImage(const gl::ImageIndex &index) const = 0; virtual GLsizei getLayerCount(int level) const = 0; + gl::Error getImageAndSyncFromStorage(const gl::Context *context, + const gl::ImageIndex &index, + ImageD3D **outImage); + GLint getBaseLevelWidth() const; GLint getBaseLevelHeight() const; - GLint getBaseLevelDepth() const; GLenum getBaseLevelInternalFormat() const; + gl::Error setStorage(const gl::Context *context, + GLenum target, + size_t levels, + GLenum internalFormat, + const gl::Extents &size) override; + + gl::Error setStorageMultisample(const gl::Context *context, + GLenum target, + GLsizei samples, + GLint internalFormat, + const gl::Extents &size, + bool fixedSampleLocations) override; + bool isImmutable() const { return mImmutable; } - virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) = 0; + virtual gl::Error getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) = 0; // Returns an iterator over all "Images" for this particular Texture. virtual gl::ImageIndexIterator imageIterator() const = 0; @@ -58,202 +83,393 @@ class TextureD3D : public TextureImpl virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const = 0; virtual bool isValidIndex(const gl::ImageIndex &index) const = 0; - gl::Error generateMipmaps(const gl::TextureState &textureState) override; + gl::Error setImageExternal(const gl::Context *context, + GLenum target, + egl::Stream *stream, + const egl::Stream::GLTextureDescription &desc) override; + gl::Error generateMipmap(const gl::Context *context) override; TextureStorage *getStorage(); ImageD3D *getBaseLevelImage() const; - gl::Error getAttachmentRenderTarget(const gl::FramebufferAttachment::Target &target, + gl::Error getAttachmentRenderTarget(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex, FramebufferAttachmentRenderTarget **rtOut) override; + gl::Error setBaseLevel(const gl::Context *context, GLuint baseLevel) override; + + void syncState(const gl::Texture::DirtyBits &dirtyBits) override; + + gl::Error initializeContents(const gl::Context *context, + const gl::ImageIndex &imageIndex) override; + protected: - gl::Error setImageImpl(const gl::ImageIndex &index, + gl::Error setImageImpl(const gl::Context *context, + const gl::ImageIndex &index, GLenum type, const gl::PixelUnpackState &unpack, const uint8_t *pixels, ptrdiff_t layerOffset); - gl::Error subImage(const gl::ImageIndex &index, const gl::Box &area, GLenum format, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixels, ptrdiff_t layerOffset); - gl::Error setCompressedImageImpl(const gl::ImageIndex &index, + gl::Error subImage(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels, + ptrdiff_t layerOffset); + gl::Error setCompressedImageImpl(const gl::Context *context, + const gl::ImageIndex &index, const gl::PixelUnpackState &unpack, const uint8_t *pixels, ptrdiff_t layerOffset); - gl::Error subImageCompressed(const gl::ImageIndex &index, const gl::Box &area, GLenum format, - const gl::PixelUnpackState &unpack, const uint8_t *pixels, ptrdiff_t layerOffset); - bool isFastUnpackable(const gl::PixelUnpackState &unpack, GLenum sizedInternalFormat); - gl::Error fastUnpackPixels(const gl::PixelUnpackState &unpack, const uint8_t *pixels, const gl::Box &destArea, - GLenum sizedInternalFormat, GLenum type, RenderTargetD3D *destRenderTarget); + gl::Error subImageCompressed(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels, + ptrdiff_t layerOffset); + bool isFastUnpackable(const gl::Buffer *unpackBuffer, GLenum sizedInternalFormat); + gl::Error fastUnpackPixels(const gl::Context *context, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels, + const gl::Box &destArea, + GLenum sizedInternalFormat, + GLenum type, + RenderTargetD3D *destRenderTarget); + + GLint getLevelZeroWidth() const; + GLint getLevelZeroHeight() const; + virtual GLint getLevelZeroDepth() const; GLint creationLevels(GLsizei width, GLsizei height, GLsizei depth) const; - int mipLevels() const; - virtual void initMipmapsImages() = 0; + virtual gl::Error initMipmapImages(const gl::Context *context) = 0; bool isBaseImageZeroSize() const; virtual bool isImageComplete(const gl::ImageIndex &index) const = 0; bool canCreateRenderTargetForImage(const gl::ImageIndex &index) const; - virtual gl::Error ensureRenderTarget(); + gl::Error ensureRenderTarget(const gl::Context *context); - virtual gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const = 0; - virtual gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage) = 0; - gl::Error commitRegion(const gl::ImageIndex &index, const gl::Box ®ion); + virtual gl::Error createCompleteStorage(bool renderTarget, + TexStoragePointer *outTexStorage) const = 0; + virtual gl::Error setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) = 0; + gl::Error commitRegion(const gl::Context *context, + const gl::ImageIndex &index, + const gl::Box ®ion); + + gl::Error releaseTexStorage(const gl::Context *context); + + GLuint getBaseLevel() const { return mBaseLevel; }; + + virtual void markAllImagesDirty() = 0; + + GLint getBaseLevelDepth() const; RendererD3D *mRenderer; - GLenum mUsage; - bool mDirtyImages; bool mImmutable; TextureStorage *mTexStorage; private: - virtual gl::Error initializeStorage(bool renderTarget) = 0; + virtual gl::Error initializeStorage(const gl::Context *context, bool renderTarget) = 0; - virtual gl::Error updateStorage() = 0; + virtual gl::Error updateStorage(const gl::Context *context) = 0; bool shouldUseSetData(const ImageD3D *image) const; - gl::Error generateMipmapsUsingImages(); + gl::Error generateMipmapUsingImages(const gl::Context *context, const GLuint maxLevel); + + GLuint mBaseLevel; }; class TextureD3D_2D : public TextureD3D { public: - TextureD3D_2D(RendererD3D *renderer); - virtual ~TextureD3D_2D(); + TextureD3D_2D(const gl::TextureState &data, RendererD3D *renderer); + ~TextureD3D_2D() override; - virtual ImageD3D *getImage(int level, int layer) const; - virtual ImageD3D *getImage(const gl::ImageIndex &index) const; - virtual GLsizei getLayerCount(int level) const; + gl::Error onDestroy(const gl::Context *context) override; + + ImageD3D *getImage(int level, int layer) const; + ImageD3D *getImage(const gl::ImageIndex &index) const override; + GLsizei getLayerCount(int level) const override; GLsizei getWidth(GLint level) const; GLsizei getHeight(GLint level) const; GLenum getInternalFormat(GLint level) const; bool isDepth(GLint level) const; + bool isSRGB(GLint level) const; - gl::Error setImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, GLenum format, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) override; - gl::Error setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) override; + gl::Error setImage(const gl::Context *context, + GLenum target, + size_t level, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) override; + gl::Error setSubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) override; - gl::Error setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, - const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) override; - gl::Error setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, - const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) override; + gl::Error setCompressedImage(const gl::Context *context, + GLenum target, + size_t level, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) override; + gl::Error setCompressedSubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) override; - gl::Error copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat, + gl::Error copyImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Rectangle &sourceArea, + GLenum internalFormat, const gl::Framebuffer *source) override; - gl::Error copySubImage(GLenum target, size_t level, const gl::Offset &destOffset, const gl::Rectangle &sourceArea, + gl::Error copySubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, const gl::Framebuffer *source) override; - gl::Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) override; + gl::Error copyTexture(const gl::Context *context, + GLenum target, + size_t level, + GLenum internalFormat, + GLenum type, + size_t sourceLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) override; + gl::Error copySubTexture(const gl::Context *context, + GLenum target, + size_t level, + const gl::Offset &destOffset, + size_t sourceLevel, + const gl::Rectangle &sourceArea, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) override; + gl::Error copyCompressedTexture(const gl::Context *context, const gl::Texture *source) override; - virtual void bindTexImage(egl::Surface *surface); - virtual void releaseTexImage(); + gl::Error setStorage(const gl::Context *context, + GLenum target, + size_t levels, + GLenum internalFormat, + const gl::Extents &size) override; - gl::Error setEGLImageTarget(GLenum target, egl::Image *image) override; + gl::Error bindTexImage(const gl::Context *context, egl::Surface *surface) override; + gl::Error releaseTexImage(const gl::Context *context) override; - virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT); + gl::Error setEGLImageTarget(const gl::Context *context, + GLenum target, + egl::Image *image) override; - virtual gl::ImageIndexIterator imageIterator() const; - virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const; - virtual bool isValidIndex(const gl::ImageIndex &index) const; + gl::Error getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) override; + + gl::ImageIndexIterator imageIterator() const override; + gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override; + bool isValidIndex(const gl::ImageIndex &index) const override; + + protected: + void markAllImagesDirty() override; private: - virtual gl::Error initializeStorage(bool renderTarget); - virtual gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const; - virtual gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage); + gl::Error initializeStorage(const gl::Context *context, bool renderTarget) override; + gl::Error createCompleteStorage(bool renderTarget, + TexStoragePointer *outTexStorage) const override; + gl::Error setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) override; - virtual gl::Error updateStorage(); - virtual void initMipmapsImages(); + gl::Error updateStorage(const gl::Context *context) override; + gl::Error initMipmapImages(const gl::Context *context) override; bool isValidLevel(int level) const; bool isLevelComplete(int level) const; - virtual bool isImageComplete(const gl::ImageIndex &index) const; + bool isImageComplete(const gl::ImageIndex &index) const override; - gl::Error updateStorageLevel(int level); + gl::Error updateStorageLevel(const gl::Context *context, int level); - void redefineImage(size_t level, - GLenum internalformat, - const gl::Extents &size, - bool forceRelease); + gl::Error redefineImage(const gl::Context *context, + size_t level, + GLenum internalformat, + const gl::Extents &size, + bool forceRelease); bool mEGLImageTarget; - ImageD3D *mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + TexLevelsArray> mImageArray; }; class TextureD3D_Cube : public TextureD3D { public: - TextureD3D_Cube(RendererD3D *renderer); - virtual ~TextureD3D_Cube(); + TextureD3D_Cube(const gl::TextureState &data, RendererD3D *renderer); + ~TextureD3D_Cube() override; - virtual ImageD3D *getImage(int level, int layer) const; - virtual ImageD3D *getImage(const gl::ImageIndex &index) const; - virtual GLsizei getLayerCount(int level) const; + gl::Error onDestroy(const gl::Context *context) override; - virtual bool hasDirtyImages() const { return mDirtyImages; } - virtual void resetDirty() { mDirtyImages = false; } - virtual void setUsage(GLenum usage) { mUsage = usage; } + ImageD3D *getImage(int level, int layer) const; + ImageD3D *getImage(const gl::ImageIndex &index) const override; + GLsizei getLayerCount(int level) const override; GLenum getInternalFormat(GLint level, GLint layer) const; bool isDepth(GLint level, GLint layer) const; + bool isSRGB(GLint level, GLint layer) const; - gl::Error setImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, GLenum format, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) override; - gl::Error setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) override; + gl::Error setImage(const gl::Context *context, + GLenum target, + size_t level, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) override; + gl::Error setSubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) override; - gl::Error setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, - const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) override; - gl::Error setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, - const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) override; + gl::Error setCompressedImage(const gl::Context *context, + GLenum target, + size_t level, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) override; + gl::Error setCompressedSubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) override; - gl::Error copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat, + gl::Error copyImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Rectangle &sourceArea, + GLenum internalFormat, const gl::Framebuffer *source) override; - gl::Error copySubImage(GLenum target, size_t level, const gl::Offset &destOffset, const gl::Rectangle &sourceArea, + gl::Error copySubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, const gl::Framebuffer *source) override; - gl::Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) override; + gl::Error copyTexture(const gl::Context *context, + GLenum target, + size_t level, + GLenum internalFormat, + GLenum type, + size_t sourceLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) override; + gl::Error copySubTexture(const gl::Context *context, + GLenum target, + size_t level, + const gl::Offset &destOffset, + size_t sourceLevel, + const gl::Rectangle &sourceArea, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const gl::Texture *source) override; - virtual void bindTexImage(egl::Surface *surface); - virtual void releaseTexImage(); + gl::Error setStorage(const gl::Context *context, + GLenum target, + size_t levels, + GLenum internalFormat, + const gl::Extents &size) override; - gl::Error setEGLImageTarget(GLenum target, egl::Image *image) override; + gl::Error bindTexImage(const gl::Context *context, egl::Surface *surface) override; + gl::Error releaseTexImage(const gl::Context *context) override; - virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT); + gl::Error setEGLImageTarget(const gl::Context *context, + GLenum target, + egl::Image *image) override; - virtual gl::ImageIndexIterator imageIterator() const; - virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const; - virtual bool isValidIndex(const gl::ImageIndex &index) const; + gl::Error getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) override; + + gl::ImageIndexIterator imageIterator() const override; + gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override; + bool isValidIndex(const gl::ImageIndex &index) const override; + + protected: + void markAllImagesDirty() override; private: - virtual gl::Error initializeStorage(bool renderTarget); - virtual gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const; - virtual gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage); + gl::Error initializeStorage(const gl::Context *context, bool renderTarget) override; + gl::Error createCompleteStorage(bool renderTarget, + TexStoragePointer *outTexStorage) const override; + gl::Error setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) override; - virtual gl::Error updateStorage(); - virtual void initMipmapsImages(); + gl::Error updateStorage(const gl::Context *context) override; + gl::Error initMipmapImages(const gl::Context *context) override; bool isValidFaceLevel(int faceIndex, int level) const; bool isFaceLevelComplete(int faceIndex, int level) const; bool isCubeComplete() const; - virtual bool isImageComplete(const gl::ImageIndex &index) const; - gl::Error updateStorageFaceLevel(int faceIndex, int level); + bool isImageComplete(const gl::ImageIndex &index) const override; + gl::Error updateStorageFaceLevel(const gl::Context *context, int faceIndex, int level); - void redefineImage(int faceIndex, GLint level, GLenum internalformat, const gl::Extents &size); + gl::Error redefineImage(const gl::Context *context, + int faceIndex, + GLint level, + GLenum internalformat, + const gl::Extents &size, + bool forceRelease); - ImageD3D *mImageArray[6][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + std::array>, 6> mImageArray; }; class TextureD3D_3D : public TextureD3D { public: - TextureD3D_3D(RendererD3D *renderer); - virtual ~TextureD3D_3D(); + TextureD3D_3D(const gl::TextureState &data, RendererD3D *renderer); + ~TextureD3D_3D() override; - virtual ImageD3D *getImage(int level, int layer) const; - virtual ImageD3D *getImage(const gl::ImageIndex &index) const; - virtual GLsizei getLayerCount(int level) const; + gl::Error onDestroy(const gl::Context *context) override; + + ImageD3D *getImage(int level, int layer) const; + ImageD3D *getImage(const gl::ImageIndex &index) const override; + GLsizei getLayerCount(int level) const override; GLsizei getWidth(GLint level) const; GLsizei getHeight(GLint level) const; @@ -261,110 +477,213 @@ class TextureD3D_3D : public TextureD3D GLenum getInternalFormat(GLint level) const; bool isDepth(GLint level) const; - gl::Error setImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, GLenum format, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) override; - gl::Error setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) override; + gl::Error setImage(const gl::Context *context, + GLenum target, + size_t level, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) override; + gl::Error setSubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) override; - gl::Error setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, - const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) override; - gl::Error setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, - const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) override; + gl::Error setCompressedImage(const gl::Context *context, + GLenum target, + size_t level, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) override; + gl::Error setCompressedSubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) override; - gl::Error copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat, + gl::Error copyImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Rectangle &sourceArea, + GLenum internalFormat, const gl::Framebuffer *source) override; - gl::Error copySubImage(GLenum target, size_t level, const gl::Offset &destOffset, const gl::Rectangle &sourceArea, + gl::Error copySubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, const gl::Framebuffer *source) override; - gl::Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) override; + gl::Error setStorage(const gl::Context *context, + GLenum target, + size_t levels, + GLenum internalFormat, + const gl::Extents &size) override; - virtual void bindTexImage(egl::Surface *surface); - virtual void releaseTexImage(); + gl::Error bindTexImage(const gl::Context *context, egl::Surface *surface) override; + gl::Error releaseTexImage(const gl::Context *context) override; - gl::Error setEGLImageTarget(GLenum target, egl::Image *image) override; + gl::Error setEGLImageTarget(const gl::Context *context, + GLenum target, + egl::Image *image) override; - virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT); + gl::Error getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) override; - virtual gl::ImageIndexIterator imageIterator() const; - virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const; - virtual bool isValidIndex(const gl::ImageIndex &index) const; + gl::ImageIndexIterator imageIterator() const override; + gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override; + bool isValidIndex(const gl::ImageIndex &index) const override; + + protected: + void markAllImagesDirty() override; + GLint getLevelZeroDepth() const override; private: - virtual gl::Error initializeStorage(bool renderTarget); - virtual gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outStorage) const; - virtual gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage); + gl::Error initializeStorage(const gl::Context *context, bool renderTarget) override; + gl::Error createCompleteStorage(bool renderTarget, + TexStoragePointer *outStorage) const override; + gl::Error setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) override; - virtual gl::Error updateStorage(); - virtual void initMipmapsImages(); + gl::Error updateStorage(const gl::Context *context) override; + gl::Error initMipmapImages(const gl::Context *context) override; bool isValidLevel(int level) const; bool isLevelComplete(int level) const; - virtual bool isImageComplete(const gl::ImageIndex &index) const; - gl::Error updateStorageLevel(int level); + bool isImageComplete(const gl::ImageIndex &index) const override; + gl::Error updateStorageLevel(const gl::Context *context, int level); - void redefineImage(GLint level, GLenum internalformat, const gl::Extents &size); + gl::Error redefineImage(const gl::Context *context, + GLint level, + GLenum internalformat, + const gl::Extents &size, + bool forceRelease); - ImageD3D *mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + TexLevelsArray> mImageArray; }; class TextureD3D_2DArray : public TextureD3D { public: - TextureD3D_2DArray(RendererD3D *renderer); - virtual ~TextureD3D_2DArray(); + TextureD3D_2DArray(const gl::TextureState &data, RendererD3D *renderer); + ~TextureD3D_2DArray() override; + + gl::Error onDestroy(const gl::Context *context) override; virtual ImageD3D *getImage(int level, int layer) const; - virtual ImageD3D *getImage(const gl::ImageIndex &index) const; - virtual GLsizei getLayerCount(int level) const; + ImageD3D *getImage(const gl::ImageIndex &index) const override; + GLsizei getLayerCount(int level) const override; GLsizei getWidth(GLint level) const; GLsizei getHeight(GLint level) const; GLenum getInternalFormat(GLint level) const; bool isDepth(GLint level) const; - gl::Error setImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, GLenum format, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) override; - gl::Error setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixels) override; + gl::Error setImage(const gl::Context *context, + GLenum target, + size_t level, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) override; + gl::Error setSubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) override; - gl::Error setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, - const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) override; - gl::Error setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, - const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) override; + gl::Error setCompressedImage(const gl::Context *context, + GLenum target, + size_t level, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) override; + gl::Error setCompressedSubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) override; - gl::Error copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat, + gl::Error copyImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Rectangle &sourceArea, + GLenum internalFormat, const gl::Framebuffer *source) override; - gl::Error copySubImage(GLenum target, size_t level, const gl::Offset &destOffset, const gl::Rectangle &sourceArea, + gl::Error copySubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, const gl::Framebuffer *source) override; - gl::Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const gl::Extents &size) override; + gl::Error setStorage(const gl::Context *context, + GLenum target, + size_t levels, + GLenum internalFormat, + const gl::Extents &size) override; - virtual void bindTexImage(egl::Surface *surface); - virtual void releaseTexImage(); + gl::Error bindTexImage(const gl::Context *context, egl::Surface *surface) override; + gl::Error releaseTexImage(const gl::Context *context) override; - gl::Error setEGLImageTarget(GLenum target, egl::Image *image) override; + gl::Error setEGLImageTarget(const gl::Context *context, + GLenum target, + egl::Image *image) override; - virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT); + gl::Error getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) override; - virtual gl::ImageIndexIterator imageIterator() const; - virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const; - virtual bool isValidIndex(const gl::ImageIndex &index) const; + gl::ImageIndexIterator imageIterator() const override; + gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override; + bool isValidIndex(const gl::ImageIndex &index) const override; + + protected: + void markAllImagesDirty() override; private: - virtual gl::Error initializeStorage(bool renderTarget); - virtual gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outStorage) const; - virtual gl::Error setCompleteTexStorage(TextureStorage *newCompleteTexStorage); + gl::Error initializeStorage(const gl::Context *context, bool renderTarget) override; + gl::Error createCompleteStorage(bool renderTarget, + TexStoragePointer *outStorage) const override; + gl::Error setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) override; - virtual gl::Error updateStorage(); - virtual void initMipmapsImages(); + gl::Error updateStorage(const gl::Context *context) override; + gl::Error initMipmapImages(const gl::Context *context) override; bool isValidLevel(int level) const; bool isLevelComplete(int level) const; - virtual bool isImageComplete(const gl::ImageIndex &index) const; - gl::Error updateStorageLevel(int level); + bool isImageComplete(const gl::ImageIndex &index) const override; + gl::Error updateStorageLevel(const gl::Context *context, int level); void deleteImages(); - void redefineImage(GLint level, GLenum internalformat, const gl::Extents &size); + gl::Error redefineImage(const gl::Context *context, + GLint level, + GLenum internalformat, + const gl::Extents &size, + bool forceRelease); // Storing images as an array of single depth textures since D3D11 treats each array level of a // Texture2D object as a separate subresource. Each layer would have to be looped over @@ -374,6 +693,199 @@ class TextureD3D_2DArray : public TextureD3D ImageD3D **mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; }; +class TextureD3D_External : public TextureD3D +{ + public: + TextureD3D_External(const gl::TextureState &data, RendererD3D *renderer); + ~TextureD3D_External() override; + + ImageD3D *getImage(const gl::ImageIndex &index) const override; + GLsizei getLayerCount(int level) const override; + + gl::Error setImage(const gl::Context *context, + GLenum target, + size_t level, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) override; + gl::Error setSubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) override; + + gl::Error setCompressedImage(const gl::Context *context, + GLenum target, + size_t level, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) override; + gl::Error setCompressedSubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) override; + + gl::Error copyImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Rectangle &sourceArea, + GLenum internalFormat, + const gl::Framebuffer *source) override; + gl::Error copySubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + const gl::Framebuffer *source) override; + + gl::Error setStorage(const gl::Context *context, + GLenum target, + size_t levels, + GLenum internalFormat, + const gl::Extents &size) override; + + gl::Error setImageExternal(const gl::Context *context, + GLenum target, + egl::Stream *stream, + const egl::Stream::GLTextureDescription &desc) override; + + gl::Error bindTexImage(const gl::Context *context, egl::Surface *surface) override; + gl::Error releaseTexImage(const gl::Context *context) override; + + gl::Error setEGLImageTarget(const gl::Context *context, + GLenum target, + egl::Image *image) override; + + gl::Error getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) override; + + gl::ImageIndexIterator imageIterator() const override; + gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override; + bool isValidIndex(const gl::ImageIndex &index) const override; + + protected: + void markAllImagesDirty() override; + + private: + gl::Error initializeStorage(const gl::Context *context, bool renderTarget) override; + gl::Error createCompleteStorage(bool renderTarget, + TexStoragePointer *outTexStorage) const override; + gl::Error setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) override; + + gl::Error updateStorage(const gl::Context *context) override; + gl::Error initMipmapImages(const gl::Context *context) override; + + bool isImageComplete(const gl::ImageIndex &index) const override; +}; + +class TextureD3D_2DMultisample : public TextureD3D +{ + public: + TextureD3D_2DMultisample(const gl::TextureState &data, RendererD3D *renderer); + ~TextureD3D_2DMultisample() override; + + ImageD3D *getImage(const gl::ImageIndex &index) const override; + gl::Error setImage(const gl::Context *context, + GLenum target, + size_t level, + GLenum internalFormat, + const gl::Extents &size, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) override; + gl::Error setSubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixels) override; + + gl::Error setCompressedImage(const gl::Context *context, + GLenum target, + size_t level, + GLenum internalFormat, + const gl::Extents &size, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) override; + gl::Error setCompressedSubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Box &area, + GLenum format, + const gl::PixelUnpackState &unpack, + size_t imageSize, + const uint8_t *pixels) override; + + gl::Error copyImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Rectangle &sourceArea, + GLenum internalFormat, + const gl::Framebuffer *source) override; + gl::Error copySubImage(const gl::Context *context, + GLenum target, + size_t level, + const gl::Offset &destOffset, + const gl::Rectangle &sourceArea, + const gl::Framebuffer *source) override; + + gl::Error setStorageMultisample(const gl::Context *context, + GLenum target, + GLsizei samples, + GLint internalFormat, + const gl::Extents &size, + bool fixedSampleLocations) override; + + gl::Error bindTexImage(const gl::Context *context, egl::Surface *surface) override; + gl::Error releaseTexImage(const gl::Context *context) override; + + gl::Error setEGLImageTarget(const gl::Context *context, + GLenum target, + egl::Image *image) override; + + gl::Error getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) override; + + gl::ImageIndexIterator imageIterator() const override; + gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override; + bool isValidIndex(const gl::ImageIndex &index) const override; + + GLsizei getLayerCount(int level) const override; + + protected: + void markAllImagesDirty() override; + + private: + gl::Error initializeStorage(const gl::Context *context, bool renderTarget) override; + gl::Error createCompleteStorage(bool renderTarget, + TexStoragePointer *outTexStorage) const override; + gl::Error setCompleteTexStorage(const gl::Context *context, + TextureStorage *newCompleteTexStorage) override; + + gl::Error updateStorage(const gl::Context *context) override; + gl::Error initMipmapImages(const gl::Context *context) override; + + bool isImageComplete(const gl::ImageIndex &index) const override; +}; } #endif // LIBANGLE_RENDERER_D3D_TEXTURED3D_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureStorage.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureStorage.cpp deleted file mode 100644 index abb83a14d5..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureStorage.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// TextureStorage.cpp: Shared members of abstract rx::TextureStorage class. - -#include "libANGLE/renderer/d3d/TextureStorage.h" -#include "libANGLE/renderer/d3d/TextureD3D.h" -#include "libANGLE/renderer/d3d/RenderTargetD3D.h" -#include "libANGLE/renderer/Renderer.h" -#include "libANGLE/Renderbuffer.h" -#include "libANGLE/Texture.h" - -#include "common/debug.h" -#include "common/mathutil.h" - -namespace rx -{ - -TextureStorage::TextureStorage() - : mFirstRenderTargetSerial(0), - mRenderTargetSerialsLayerStride(0) -{} - -void TextureStorage::initializeSerials(unsigned int rtSerialsToReserve, unsigned int rtSerialsLayerStride) -{ - mFirstRenderTargetSerial = RenderTargetD3D::issueSerials(rtSerialsToReserve); - mRenderTargetSerialsLayerStride = rtSerialsLayerStride; -} - -unsigned int TextureStorage::getRenderTargetSerial(const gl::ImageIndex &index) const -{ - unsigned int layerOffset = (index.hasLayer() ? (static_cast(index.layerIndex) * mRenderTargetSerialsLayerStride) : 0); - return mFirstRenderTargetSerial + static_cast(index.mipIndex) + layerOffset; -} - -} diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureStorage.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureStorage.h index 417237495d..383fbc2141 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureStorage.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/TextureStorage.h @@ -9,20 +9,19 @@ #ifndef LIBANGLE_RENDERER_D3D_TEXTURESTORAGE_H_ #define LIBANGLE_RENDERER_D3D_TEXTURESTORAGE_H_ -#include "libANGLE/Error.h" - #include "common/debug.h" -#include "libANGLE/Error.h" +#include "libANGLE/angletypes.h" #include #include namespace gl { +class Context; struct ImageIndex; struct Box; struct PixelUnpackState; -} +} // namespace gl namespace rx { @@ -36,23 +35,48 @@ class TextureStorage : angle::NonCopyable TextureStorage() {} virtual ~TextureStorage() {} + virtual gl::Error onDestroy(const gl::Context *context); + virtual int getTopLevel() const = 0; virtual bool isRenderTarget() const = 0; virtual bool isManaged() const = 0; virtual bool supportsNativeMipmapFunction() const = 0; virtual int getLevelCount() const = 0; - virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) = 0; - virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) = 0; + virtual gl::Error getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) = 0; + virtual gl::Error generateMipmap(const gl::Context *context, + const gl::ImageIndex &sourceIndex, + const gl::ImageIndex &destIndex) = 0; - virtual gl::Error copyToStorage(TextureStorage *destStorage) = 0; - virtual gl::Error setData(const gl::ImageIndex &index, ImageD3D *image, const gl::Box *destBox, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixelData) = 0; + virtual gl::Error copyToStorage(const gl::Context *context, TextureStorage *destStorage) = 0; + virtual gl::Error setData(const gl::Context *context, + const gl::ImageIndex &index, + ImageD3D *image, + const gl::Box *destBox, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixelData) = 0; // This is a no-op for most implementations of TextureStorage. Some (e.g. TextureStorage11_2D) might override it. - virtual gl::Error useLevelZeroWorkaroundTexture(bool useLevelZeroTexture) { return gl::Error(GL_NO_ERROR); } + virtual gl::Error useLevelZeroWorkaroundTexture(const gl::Context *context, + bool useLevelZeroTexture); }; +inline gl::Error TextureStorage::onDestroy(const gl::Context *context) +{ + return gl::NoError(); } +inline gl::Error TextureStorage::useLevelZeroWorkaroundTexture(const gl::Context *context, + bool useLevelZeroTexture) +{ + return gl::NoError(); +} + +using TexStoragePointer = angle::UniqueObjectPointer; + +} // namespace rx + #endif // LIBANGLE_RENDERER_D3D_TEXTURESTORAGE_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/TransformFeedbackD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/TransformFeedbackD3D.cpp deleted file mode 100644 index 80a4ec3ae1..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/TransformFeedbackD3D.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// -// Copyright 2014 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// TransformFeedbackD3D.cpp is a no-op implementation for both the D3D9 and D3D11 renderers. - -#include "libANGLE/renderer/d3d/TransformFeedbackD3D.h" - -namespace rx -{ - -TransformFeedbackD3D::TransformFeedbackD3D() -{ -} - -TransformFeedbackD3D::~TransformFeedbackD3D() -{ -} - -void TransformFeedbackD3D::begin(GLenum primitiveMode) -{ -} - -void TransformFeedbackD3D::end() -{ -} - -void TransformFeedbackD3D::pause() -{ -} - -void TransformFeedbackD3D::resume() -{ -} - -void TransformFeedbackD3D::bindGenericBuffer(const BindingPointer &binding) -{ -} - -void TransformFeedbackD3D::bindIndexedBuffer(size_t index, const OffsetBindingPointer &binding) -{ -} - -} diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/TransformFeedbackD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/TransformFeedbackD3D.h deleted file mode 100644 index 6925966153..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/TransformFeedbackD3D.h +++ /dev/null @@ -1,35 +0,0 @@ -// -// Copyright 2014 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// TransformFeedbackD3D.h: Implements the abstract rx::TransformFeedbackImpl class. - -#ifndef LIBANGLE_RENDERER_D3D_TRANSFORMFEEDBACKD3D_H_ -#define LIBANGLE_RENDERER_D3D_TRANSFORMFEEDBACKD3D_H_ - -#include "libANGLE/renderer/TransformFeedbackImpl.h" -#include "libANGLE/angletypes.h" - -namespace rx -{ - -class TransformFeedbackD3D : public TransformFeedbackImpl -{ - public: - TransformFeedbackD3D(); - virtual ~TransformFeedbackD3D(); - - void begin(GLenum primitiveMode) override; - void end() override; - void pause() override; - void resume() override; - - void bindGenericBuffer(const BindingPointer &binding) override; - void bindIndexedBuffer(size_t index, const OffsetBindingPointer &binding) override; -}; - -} - -#endif // LIBANGLE_RENDERER_D3D_TRANSFORMFEEDBACKD3D_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexBuffer.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexBuffer.cpp index 9efee9db7c..7c2d5aec70 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexBuffer.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexBuffer.cpp @@ -8,18 +8,19 @@ // class with derivations, classes that perform graphics API agnostic vertex buffer operations. #include "libANGLE/renderer/d3d/VertexBuffer.h" + +#include "common/mathutil.h" #include "libANGLE/renderer/d3d/BufferD3D.h" #include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/VertexAttribute.h" -#include "common/mathutil.h" - namespace rx { +// VertexBuffer Implementation unsigned int VertexBuffer::mNextSerial = 1; -VertexBuffer::VertexBuffer() +VertexBuffer::VertexBuffer() : mRefCount(1) { updateSerial(); } @@ -38,19 +39,34 @@ unsigned int VertexBuffer::getSerial() const return mSerial; } -VertexBufferInterface::VertexBufferInterface(BufferFactoryD3D *factory, bool dynamic) - : mFactory(factory) +void VertexBuffer::addRef() { - mDynamic = dynamic; - mWritePosition = 0; - mReservedSpace = 0; + mRefCount++; +} - mVertexBuffer = factory->createVertexBuffer(); +void VertexBuffer::release() +{ + ASSERT(mRefCount > 0); + mRefCount--; + + if (mRefCount == 0) + { + delete this; + } +} + +// VertexBufferInterface Implementation +VertexBufferInterface::VertexBufferInterface(BufferFactoryD3D *factory, bool dynamic) + : mFactory(factory), mVertexBuffer(factory->createVertexBuffer()), mDynamic(dynamic) +{ } VertexBufferInterface::~VertexBufferInterface() { - delete mVertexBuffer; + if (mVertexBuffer) + { + mVertexBuffer->release(); + } } unsigned int VertexBufferInterface::getSerial() const @@ -69,20 +85,30 @@ gl::Error VertexBufferInterface::setBufferSize(unsigned int size) { return mVertexBuffer->initialize(size, mDynamic); } - else + + return mVertexBuffer->setBufferSize(size); +} + +gl::ErrorOrResult VertexBufferInterface::getSpaceRequired( + const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + GLsizei count, + GLsizei instances) const +{ + unsigned int spaceRequired = 0; + ANGLE_TRY_RESULT(mFactory->getVertexSpaceRequired(attrib, binding, count, instances), + spaceRequired); + + // Align to 16-byte boundary + unsigned int alignedSpaceRequired = roundUp(spaceRequired, 16u); + + if (alignedSpaceRequired < spaceRequired) { - return mVertexBuffer->setBufferSize(size); + return gl::OutOfMemory() + << "Vertex buffer overflow in VertexBufferInterface::getSpaceRequired."; } -} -unsigned int VertexBufferInterface::getWritePosition() const -{ - return mWritePosition; -} - -void VertexBufferInterface::setWritePosition(unsigned int writePosition) -{ - mWritePosition = writePosition; + return alignedSpaceRequired; } gl::Error VertexBufferInterface::discard() @@ -90,127 +116,18 @@ gl::Error VertexBufferInterface::discard() return mVertexBuffer->discard(); } -gl::Error VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, - GLenum currentValueType, - GLint start, - GLsizei count, - GLsizei instances, - unsigned int *outStreamOffset, - const uint8_t *sourceData) -{ - gl::Error error(GL_NO_ERROR); - - unsigned int spaceRequired; - error = mVertexBuffer->getSpaceRequired(attrib, count, instances, &spaceRequired); - if (error.isError()) - { - return error; - } - - // Align to 16-byte boundary - unsigned int alignedSpaceRequired = roundUp(spaceRequired, 16u); - - // Protect against integer overflow - if (!IsUnsignedAdditionSafe(mWritePosition, alignedSpaceRequired) || - alignedSpaceRequired < spaceRequired) - { - return gl::Error(GL_OUT_OF_MEMORY, "Internal error, new vertex buffer write position would overflow."); - } - - error = reserveSpace(mReservedSpace); - if (error.isError()) - { - return error; - } - mReservedSpace = 0; - - error = mVertexBuffer->storeVertexAttributes(attrib, currentValueType, start, count, instances, mWritePosition, sourceData); - if (error.isError()) - { - return error; - } - - if (outStreamOffset) - { - *outStreamOffset = mWritePosition; - } - - mWritePosition += alignedSpaceRequired; - - return gl::Error(GL_NO_ERROR); -} - -gl::Error VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances) -{ - gl::Error error(GL_NO_ERROR); - - unsigned int requiredSpace; - error = mVertexBuffer->getSpaceRequired(attrib, count, instances, &requiredSpace); - if (error.isError()) - { - return error; - } - - // Align to 16-byte boundary - unsigned int alignedRequiredSpace = roundUp(requiredSpace, 16u); - - // Protect against integer overflow - if (!IsUnsignedAdditionSafe(mReservedSpace, alignedRequiredSpace) || - alignedRequiredSpace < requiredSpace) - { - return gl::Error(GL_OUT_OF_MEMORY, "Unable to reserve %u extra bytes in internal vertex buffer, " - "it would result in an overflow.", requiredSpace); - } - - mReservedSpace += alignedRequiredSpace; - - return gl::Error(GL_NO_ERROR); -} - -VertexBuffer* VertexBufferInterface::getVertexBuffer() const +VertexBuffer *VertexBufferInterface::getVertexBuffer() const { return mVertexBuffer; } -bool VertexBufferInterface::directStoragePossible(const gl::VertexAttribute &attrib, - GLenum currentValueType) const +// StreamingVertexBufferInterface Implementation +StreamingVertexBufferInterface::StreamingVertexBufferInterface(BufferFactoryD3D *factory, + std::size_t initialSize) + : VertexBufferInterface(factory, true), mWritePosition(0), mReservedSpace(0) { - gl::Buffer *buffer = attrib.buffer.get(); - BufferD3D *storage = buffer ? GetImplAs(buffer) : NULL; - - if (!storage || !storage->supportsDirectBinding()) - { - return false; - } - - // Alignment restrictions: In D3D, vertex data must be aligned to - // the format stride, or to a 4-byte boundary, whichever is smaller. - // (Undocumented, and experimentally confirmed) - size_t alignment = 4; - bool requiresConversion = false; - - if (attrib.type != GL_FLOAT) - { - gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib, currentValueType); - - unsigned int outputElementSize; - getVertexBuffer()->getSpaceRequired(attrib, 1, 0, &outputElementSize); - alignment = std::min(outputElementSize, 4); - - // TODO(jmadill): add VertexFormatCaps - requiresConversion = (mFactory->getVertexConversionType(vertexFormatType) & VERTEX_CONVERT_CPU) != 0; - } - - bool isAligned = (static_cast(ComputeVertexAttributeStride(attrib)) % alignment == 0) && - (static_cast(attrib.offset) % alignment == 0); - - return !requiresConversion && isAligned; -} - -StreamingVertexBufferInterface::StreamingVertexBufferInterface(BufferFactoryD3D *factory, std::size_t initialSize) - : VertexBufferInterface(factory, true) -{ - setBufferSize(static_cast(initialSize)); + // TODO(jmadill): Make an initialize method that can return an error. + ANGLE_SWALLOW_ERR(setBufferSize(static_cast(initialSize))); } StreamingVertexBufferInterface::~StreamingVertexBufferInterface() @@ -222,28 +139,118 @@ gl::Error StreamingVertexBufferInterface::reserveSpace(unsigned int size) unsigned int curBufferSize = getBufferSize(); if (size > curBufferSize) { - gl::Error error = setBufferSize(std::max(size, 3 * curBufferSize / 2)); - if (error.isError()) - { - return error; - } - setWritePosition(0); + ANGLE_TRY(setBufferSize(std::max(size, 3 * curBufferSize / 2))); + mWritePosition = 0; } - else if (getWritePosition() + size > curBufferSize) + else if (mWritePosition + size > curBufferSize) { - gl::Error error = discard(); - if (error.isError()) - { - return error; - } - setWritePosition(0); + ANGLE_TRY(discard()); + mWritePosition = 0; } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); +} + +gl::Error StreamingVertexBufferInterface::storeDynamicAttribute(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + GLenum currentValueType, + GLint start, + GLsizei count, + GLsizei instances, + unsigned int *outStreamOffset, + const uint8_t *sourceData) +{ + unsigned int spaceRequired = 0; + ANGLE_TRY_RESULT(getSpaceRequired(attrib, binding, count, instances), spaceRequired); + + // Protect against integer overflow + angle::CheckedNumeric checkedPosition(mWritePosition); + checkedPosition += spaceRequired; + if (!checkedPosition.IsValid()) + { + return gl::OutOfMemory() + << "Internal error, new vertex buffer write position would overflow."; + } + + ANGLE_TRY(reserveSpace(mReservedSpace)); + mReservedSpace = 0; + + ANGLE_TRY(mVertexBuffer->storeVertexAttributes(attrib, binding, currentValueType, start, count, + instances, mWritePosition, sourceData)); + + if (outStreamOffset) + { + *outStreamOffset = mWritePosition; + } + + mWritePosition += spaceRequired; + + return gl::NoError(); +} + +gl::Error StreamingVertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + GLsizei count, + GLsizei instances) +{ + unsigned int requiredSpace = 0; + ANGLE_TRY_RESULT(mFactory->getVertexSpaceRequired(attrib, binding, count, instances), + requiredSpace); + + // Align to 16-byte boundary + auto alignedRequiredSpace = rx::CheckedRoundUp(requiredSpace, 16u); + alignedRequiredSpace += mReservedSpace; + + // Protect against integer overflow + if (!alignedRequiredSpace.IsValid()) + { + return gl::OutOfMemory() + << "Unable to reserve " << requiredSpace + << " extra bytes in internal vertex buffer, it would result in an overflow."; + } + + mReservedSpace = alignedRequiredSpace.ValueOrDie(); + + return gl::NoError(); +} + +// StaticVertexBufferInterface Implementation +StaticVertexBufferInterface::AttributeSignature::AttributeSignature() + : type(GL_NONE), size(0), stride(0), normalized(false), pureInteger(false), offset(0) +{ +} + +bool StaticVertexBufferInterface::AttributeSignature::matchesAttribute( + const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding) const +{ + size_t attribStride = ComputeVertexAttributeStride(attrib, binding); + + if (type != attrib.type || size != attrib.size || static_cast(stride) != attribStride || + normalized != attrib.normalized || pureInteger != attrib.pureInteger) + { + return false; + } + + size_t attribOffset = + (static_cast(ComputeVertexAttributeOffset(attrib, binding)) % attribStride); + return (offset == attribOffset); +} + +void StaticVertexBufferInterface::AttributeSignature::set(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding) +{ + type = attrib.type; + size = attrib.size; + normalized = attrib.normalized; + pureInteger = attrib.pureInteger; + offset = stride = static_cast(ComputeVertexAttributeStride(attrib, binding)); + offset = static_cast(ComputeVertexAttributeOffset(attrib, binding)) % + ComputeVertexAttributeStride(attrib, binding); } StaticVertexBufferInterface::StaticVertexBufferInterface(BufferFactoryD3D *factory) - : VertexBufferInterface(factory, false), mIsCommitted(false) + : VertexBufferInterface(factory, false) { } @@ -251,82 +258,36 @@ StaticVertexBufferInterface::~StaticVertexBufferInterface() { } -bool StaticVertexBufferInterface::lookupAttribute(const gl::VertexAttribute &attrib, unsigned int *outStreamOffset) +bool StaticVertexBufferInterface::matchesAttribute(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding) const { - for (unsigned int element = 0; element < mCache.size(); element++) - { - size_t attribStride = ComputeVertexAttributeStride(attrib); - - if (mCache[element].type == attrib.type && mCache[element].size == attrib.size && - mCache[element].stride == attribStride && - mCache[element].normalized == attrib.normalized && - mCache[element].pureInteger == attrib.pureInteger) - { - size_t offset = (static_cast(attrib.offset) % attribStride); - if (mCache[element].attributeOffset == offset) - { - if (outStreamOffset) - { - *outStreamOffset = mCache[element].streamOffset; - } - return true; - } - } - } - - return false; + return mSignature.matchesAttribute(attrib, binding); } -gl::Error StaticVertexBufferInterface::reserveSpace(unsigned int size) +void StaticVertexBufferInterface::setAttribute(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding) { - unsigned int curSize = getBufferSize(); - if (curSize == 0) - { - return setBufferSize(size); - } - else if (curSize >= size) - { - return gl::Error(GL_NO_ERROR); - } - else - { - UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION, "Internal error, Static vertex buffers can't be resized."); - } + return mSignature.set(attrib, binding); } -gl::Error StaticVertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, - GLenum currentValueType, - GLint start, - GLsizei count, - GLsizei instances, - unsigned int *outStreamOffset, - const uint8_t *sourceData) +gl::Error StaticVertexBufferInterface::storeStaticAttribute(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + GLint start, + GLsizei count, + GLsizei instances, + const uint8_t *sourceData) { - unsigned int streamOffset; - gl::Error error = VertexBufferInterface::storeVertexAttributes(attrib, currentValueType, start, count, instances, &streamOffset, sourceData); - if (error.isError()) - { - return error; - } + unsigned int spaceRequired = 0; + ANGLE_TRY_RESULT(getSpaceRequired(attrib, binding, count, instances), spaceRequired); + ANGLE_TRY(setBufferSize(spaceRequired)); - size_t attributeOffset = static_cast(attrib.offset) % ComputeVertexAttributeStride(attrib); - VertexElement element = { attrib.type, attrib.size, static_cast(ComputeVertexAttributeStride(attrib)), attrib.normalized, attrib.pureInteger, attributeOffset, streamOffset }; - mCache.push_back(element); + ASSERT(attrib.enabled); + ANGLE_TRY(mVertexBuffer->storeVertexAttributes(attrib, binding, GL_NONE, start, count, + instances, 0, sourceData)); - if (outStreamOffset) - { - *outStreamOffset = streamOffset; - } - - return gl::Error(GL_NO_ERROR); + mSignature.set(attrib, binding); + mVertexBuffer->hintUnmapResource(); + return gl::NoError(); } -void StaticVertexBufferInterface::commit() -{ - if (getBufferSize() > 0) - { - mIsCommitted = true; - } -} -} +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexBuffer.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexBuffer.h index 692b6ac506..df8085d3cb 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexBuffer.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexBuffer.h @@ -22,6 +22,7 @@ namespace gl { struct VertexAttribute; +class VertexBinding; struct VertexAttribCurrentValueData; } @@ -29,23 +30,25 @@ namespace rx { class BufferFactoryD3D; +// Use a ref-counting scheme with self-deletion on release. We do this so that we can more +// easily manage the static buffer cache, without deleting currently bound buffers. class VertexBuffer : angle::NonCopyable { public: VertexBuffer(); - virtual ~VertexBuffer(); virtual gl::Error initialize(unsigned int size, bool dynamicUsage) = 0; + // Warning: you should ensure binding really matches attrib.bindingIndex before using this + // function. virtual gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, GLenum currentValueType, GLint start, GLsizei count, GLsizei instances, unsigned int offset, const uint8_t *sourceData) = 0; - virtual gl::Error getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, - unsigned int *outSpaceRequired) const = 0; virtual unsigned int getBufferSize() const = 0; virtual gl::Error setBufferSize(unsigned int size) = 0; @@ -56,12 +59,18 @@ class VertexBuffer : angle::NonCopyable // This may be overridden (e.g. by VertexBuffer11) if necessary. virtual void hintUnmapResource() { }; + // Reference counting. + void addRef(); + void release(); + protected: void updateSerial(); + virtual ~VertexBuffer(); private: unsigned int mSerial; static unsigned int mNextSerial; + unsigned int mRefCount; }; class VertexBufferInterface : angle::NonCopyable @@ -70,42 +79,24 @@ class VertexBufferInterface : angle::NonCopyable VertexBufferInterface(BufferFactoryD3D *factory, bool dynamic); virtual ~VertexBufferInterface(); - gl::Error reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances); - unsigned int getBufferSize() const; + bool empty() const { return getBufferSize() == 0; } unsigned int getSerial() const; - virtual gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, - GLenum currentValueType, - GLint start, - GLsizei count, - GLsizei instances, - unsigned int *outStreamOffset, - const uint8_t *sourceData); - - bool directStoragePossible(const gl::VertexAttribute &attrib, - GLenum currentValueType) const; - - VertexBuffer* getVertexBuffer() const; + VertexBuffer *getVertexBuffer() const; protected: - virtual gl::Error reserveSpace(unsigned int size) = 0; - - unsigned int getWritePosition() const; - void setWritePosition(unsigned int writePosition); - gl::Error discard(); gl::Error setBufferSize(unsigned int size); - private: + gl::ErrorOrResult getSpaceRequired(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + GLsizei count, + GLsizei instances) const; BufferFactoryD3D *const mFactory; - - VertexBuffer* mVertexBuffer; - - unsigned int mWritePosition; - unsigned int mReservedSpace; + VertexBuffer *mVertexBuffer; bool mDynamic; }; @@ -113,53 +104,72 @@ class StreamingVertexBufferInterface : public VertexBufferInterface { public: StreamingVertexBufferInterface(BufferFactoryD3D *factory, std::size_t initialSize); - ~StreamingVertexBufferInterface(); + ~StreamingVertexBufferInterface() override; - protected: + gl::Error storeDynamicAttribute(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + GLenum currentValueType, + GLint start, + GLsizei count, + GLsizei instances, + unsigned int *outStreamOffset, + const uint8_t *sourceData); + + gl::Error reserveVertexSpace(const gl::VertexAttribute &attribute, + const gl::VertexBinding &binding, + GLsizei count, + GLsizei instances); + + private: gl::Error reserveSpace(unsigned int size); + + unsigned int mWritePosition; + unsigned int mReservedSpace; }; class StaticVertexBufferInterface : public VertexBufferInterface { public: explicit StaticVertexBufferInterface(BufferFactoryD3D *factory); - ~StaticVertexBufferInterface(); + ~StaticVertexBufferInterface() override; - gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, - GLenum currentValueType, - GLint start, - GLsizei count, - GLsizei instances, - unsigned int *outStreamOffset, - const uint8_t *sourceData) override; + // Warning: you should ensure binding really matches attrib.bindingIndex before using these + // functions. + gl::Error storeStaticAttribute(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + GLint start, + GLsizei count, + GLsizei instances, + const uint8_t *sourceData); - bool lookupAttribute(const gl::VertexAttribute &attribute, unsigned int* outStreamFffset); + bool matchesAttribute(const gl::VertexAttribute &attribute, + const gl::VertexBinding &binding) const; - // If a static vertex buffer is committed then no more attribute data can be added to it - // A new static vertex buffer should be created instead - void commit(); - bool isCommitted() { return mIsCommitted; } - - protected: - gl::Error reserveSpace(unsigned int size); + void setAttribute(const gl::VertexAttribute &attribute, const gl::VertexBinding &binding); private: - struct VertexElement + class AttributeSignature final : angle::NonCopyable { + public: + AttributeSignature(); + + bool matchesAttribute(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding) const; + + void set(const gl::VertexAttribute &attrib, const gl::VertexBinding &binding); + + private: GLenum type; GLuint size; GLuint stride; bool normalized; bool pureInteger; - size_t attributeOffset; - - unsigned int streamOffset; + size_t offset; }; - bool mIsCommitted; - std::vector mCache; + AttributeSignature mSignature; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_VERTEXBUFFER_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexDataManager.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexDataManager.cpp index b392d0f4da..54ad5e54f5 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexDataManager.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexDataManager.cpp @@ -9,25 +9,38 @@ #include "libANGLE/renderer/d3d/VertexDataManager.h" +#include "common/bitset_utils.h" #include "libANGLE/Buffer.h" +#include "libANGLE/Context.h" #include "libANGLE/Program.h" #include "libANGLE/State.h" -#include "libANGLE/VertexAttribute.h" #include "libANGLE/VertexArray.h" +#include "libANGLE/VertexAttribute.h" +#include "libANGLE/formatutils.h" #include "libANGLE/renderer/d3d/BufferD3D.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/VertexBuffer.h" -namespace -{ - enum { INITIAL_STREAM_BUFFER_SIZE = 1024*1024 }; - // This has to be at least 4k or else it fails on ATI cards. - enum { CONSTANT_VERTEX_BUFFER_SIZE = 4096 }; -} +using namespace angle; namespace rx { +namespace +{ +enum +{ + INITIAL_STREAM_BUFFER_SIZE = 1024 * 1024 +}; +// This has to be at least 4k or else it fails on ATI cards. +enum +{ + CONSTANT_VERTEX_BUFFER_SIZE = 4096 +}; -static int ElementsInBuffer(const gl::VertexAttribute &attrib, unsigned int size) +// Warning: you should ensure binding really matches attrib.bindingIndex before using this function. +int ElementsInBuffer(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + unsigned int size) { // Size cannot be larger than a GLsizei if (size > static_cast(std::numeric_limits::max())) @@ -35,15 +48,139 @@ static int ElementsInBuffer(const gl::VertexAttribute &attrib, unsigned int size size = static_cast(std::numeric_limits::max()); } - GLsizei stride = static_cast(ComputeVertexAttributeStride(attrib)); - return (size - attrib.offset % stride + + GLsizei stride = static_cast(ComputeVertexAttributeStride(attrib, binding)); + GLsizei offset = static_cast(ComputeVertexAttributeOffset(attrib, binding)); + return (size - offset % stride + (stride - static_cast(ComputeVertexAttributeTypeSize(attrib)))) / stride; } -VertexDataManager::CurrentValueState::CurrentValueState() - : buffer(nullptr), - offset(0) +// Warning: you should ensure binding really matches attrib.bindingIndex before using this function. +bool DirectStoragePossible(const gl::VertexAttribute &attrib, const gl::VertexBinding &binding) +{ + // Current value attribs may not use direct storage. + if (!attrib.enabled) + { + return false; + } + + gl::Buffer *buffer = binding.getBuffer().get(); + if (!buffer) + { + return false; + } + + BufferD3D *bufferD3D = GetImplAs(buffer); + ASSERT(bufferD3D); + if (!bufferD3D->supportsDirectBinding()) + { + return false; + } + + // Alignment restrictions: In D3D, vertex data must be aligned to the format stride, or to a + // 4-byte boundary, whichever is smaller. (Undocumented, and experimentally confirmed) + size_t alignment = 4; + + // TODO(jmadill): add VertexFormatCaps + BufferFactoryD3D *factory = bufferD3D->getFactory(); + + gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib); + + // CPU-converted vertex data must be converted (naturally). + if ((factory->getVertexConversionType(vertexFormatType) & VERTEX_CONVERT_CPU) != 0) + { + return false; + } + + if (attrib.type != GL_FLOAT) + { + auto errorOrElementSize = factory->getVertexSpaceRequired(attrib, binding, 1, 0); + if (errorOrElementSize.isError()) + { + ERR() << "Unlogged error in DirectStoragePossible."; + return false; + } + + alignment = std::min(errorOrElementSize.getResult(), 4); + } + + GLintptr offset = ComputeVertexAttributeOffset(attrib, binding); + // Final alignment check - unaligned data must be converted. + return (static_cast(ComputeVertexAttributeStride(attrib, binding)) % alignment == 0) && + (static_cast(offset) % alignment == 0); +} +} // anonymous namespace + +TranslatedAttribute::TranslatedAttribute() + : active(false), + attribute(nullptr), + binding(nullptr), + currentValueType(GL_NONE), + baseOffset(0), + usesFirstVertexOffset(false), + stride(0), + vertexBuffer(), + storage(nullptr), + serial(0), + divisor(0) +{ +} + +TranslatedAttribute::TranslatedAttribute(const TranslatedAttribute &other) = default; + +gl::ErrorOrResult TranslatedAttribute::computeOffset(GLint startVertex) const +{ + if (!usesFirstVertexOffset) + { + return baseOffset; + } + + CheckedNumeric offset; + + offset = baseOffset + stride * static_cast(startVertex); + ANGLE_TRY_CHECKED_MATH(offset); + return offset.ValueOrDie(); +} + +// Warning: you should ensure binding really matches attrib.bindingIndex before using this function. +VertexStorageType ClassifyAttributeStorage(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding) +{ + // If attribute is disabled, we use the current value. + if (!attrib.enabled) + { + return VertexStorageType::CURRENT_VALUE; + } + + // If specified with immediate data, we must use dynamic storage. + auto *buffer = binding.getBuffer().get(); + if (!buffer) + { + return VertexStorageType::DYNAMIC; + } + + // Check if the buffer supports direct storage. + if (DirectStoragePossible(attrib, binding)) + { + return VertexStorageType::DIRECT; + } + + // Otherwise the storage is static or dynamic. + BufferD3D *bufferD3D = GetImplAs(buffer); + ASSERT(bufferD3D); + switch (bufferD3D->getUsage()) + { + case D3DBufferUsage::DYNAMIC: + return VertexStorageType::DYNAMIC; + case D3DBufferUsage::STATIC: + return VertexStorageType::STATIC; + default: + UNREACHABLE(); + return VertexStorageType::UNKNOWN; + } +} + +VertexDataManager::CurrentValueState::CurrentValueState() : buffer(), offset(0) { data.FloatValues[0] = std::numeric_limits::quiet_NaN(); data.FloatValues[1] = std::numeric_limits::quiet_NaN(); @@ -54,379 +191,456 @@ VertexDataManager::CurrentValueState::CurrentValueState() VertexDataManager::CurrentValueState::~CurrentValueState() { - SafeDelete(buffer); } VertexDataManager::VertexDataManager(BufferFactoryD3D *factory) - : mFactory(factory), - mStreamingBuffer(nullptr), - // TODO(jmadill): use context caps - mCurrentValueCache(gl::MAX_VERTEX_ATTRIBS) + : mFactory(factory), mStreamingBuffer(), mCurrentValueCache(gl::MAX_VERTEX_ATTRIBS) { - mStreamingBuffer = new StreamingVertexBufferInterface(factory, INITIAL_STREAM_BUFFER_SIZE); - - if (!mStreamingBuffer) - { - ERR("Failed to allocate the streaming vertex buffer."); - } - - // TODO(jmadill): use context caps - mActiveEnabledAttributes.reserve(gl::MAX_VERTEX_ATTRIBS); - mActiveDisabledAttributes.reserve(gl::MAX_VERTEX_ATTRIBS); } VertexDataManager::~VertexDataManager() { - SafeDelete(mStreamingBuffer); } -void VertexDataManager::hintUnmapAllResources(const std::vector &vertexAttributes) +gl::Error VertexDataManager::initialize() { - mStreamingBuffer->getVertexBuffer()->hintUnmapResource(); - - for (const TranslatedAttribute *translated : mActiveEnabledAttributes) + mStreamingBuffer.reset( + new StreamingVertexBufferInterface(mFactory, INITIAL_STREAM_BUFFER_SIZE)); + if (!mStreamingBuffer) { - gl::Buffer *buffer = translated->attribute->buffer.get(); - BufferD3D *storage = buffer ? GetImplAs(buffer) : nullptr; - StaticVertexBufferInterface *staticBuffer = - storage - ? storage->getStaticVertexBuffer(*translated->attribute, D3D_BUFFER_DO_NOT_CREATE) - : nullptr; - - if (staticBuffer) - { - // Commit all the static vertex buffers. This fixes them in size/contents, and forces - // ANGLE to use a new static buffer (or recreate the static buffers) next time - staticBuffer->commit(); - - staticBuffer->getVertexBuffer()->hintUnmapResource(); - } + return gl::OutOfMemory() << "Failed to allocate the streaming vertex buffer."; } - for (auto ¤tValue : mCurrentValueCache) - { - if (currentValue.buffer != nullptr) - { - currentValue.buffer->getVertexBuffer()->hintUnmapResource(); - } - } + return gl::NoError(); } -gl::Error VertexDataManager::prepareVertexData(const gl::State &state, +void VertexDataManager::deinitialize() +{ + mStreamingBuffer.reset(); + mCurrentValueCache.clear(); +} + +gl::Error VertexDataManager::prepareVertexData(const gl::Context *context, GLint start, GLsizei count, std::vector *translatedAttribs, GLsizei instances) { - if (!mStreamingBuffer) - { - return gl::Error(GL_OUT_OF_MEMORY, "Internal streaming vertex buffer is unexpectedly NULL."); - } + ASSERT(mStreamingBuffer); - // Compute active enabled and active disable attributes, for speed. - // TODO(jmadill): don't recompute if there was no state change + const gl::State &state = context->getGLState(); const gl::VertexArray *vertexArray = state.getVertexArray(); - const gl::Program *program = state.getProgram(); const auto &vertexAttributes = vertexArray->getVertexAttributes(); + const auto &vertexBindings = vertexArray->getVertexBindings(); + + mDynamicAttribsMaskCache.reset(); + const gl::Program *program = state.getProgram(); - mActiveEnabledAttributes.clear(); - mActiveDisabledAttributes.clear(); translatedAttribs->clear(); for (size_t attribIndex = 0; attribIndex < vertexAttributes.size(); ++attribIndex) { - if (program->isAttribLocationActive(attribIndex)) + // Skip attrib locations the program doesn't use. + if (!program->isAttribLocationActive(attribIndex)) + continue; + + const auto &attrib = vertexAttributes[attribIndex]; + const auto &binding = vertexBindings[attrib.bindingIndex]; + + // Resize automatically puts in empty attribs + translatedAttribs->resize(attribIndex + 1); + + TranslatedAttribute *translated = &(*translatedAttribs)[attribIndex]; + auto currentValueData = state.getVertexAttribCurrentValue(attribIndex); + + // Record the attribute now + translated->active = true; + translated->attribute = &attrib; + translated->binding = &binding; + translated->currentValueType = currentValueData.Type; + translated->divisor = binding.getDivisor(); + + switch (ClassifyAttributeStorage(attrib, binding)) { - // Resize automatically puts in empty attribs - translatedAttribs->resize(attribIndex + 1); - - TranslatedAttribute *translated = &(*translatedAttribs)[attribIndex]; - - // Record the attribute now - translated->active = true; - translated->attribute = &vertexAttributes[attribIndex]; - translated->currentValueType = - state.getVertexAttribCurrentValue(static_cast(attribIndex)).Type; - translated->divisor = vertexAttributes[attribIndex].divisor; - - if (vertexAttributes[attribIndex].enabled) + case VertexStorageType::STATIC: { - mActiveEnabledAttributes.push_back(translated); - - gl::Buffer *buffer = vertexAttributes[attribIndex].buffer.get(); - if (buffer) - { - // Also reinitialize static buffers which didn't contain matching data - // last time they were used - BufferD3D *bufferImpl = GetImplAs(buffer); - bufferImpl->reinitOutOfDateStaticData(); - } + // Store static attribute. + ANGLE_TRY(StoreStaticAttrib(context, translated)); + break; } - else + case VertexStorageType::DYNAMIC: + // Dynamic attributes must be handled together. + mDynamicAttribsMaskCache.set(attribIndex); + break; + case VertexStorageType::DIRECT: + // Update translated data for direct attributes. + StoreDirectAttrib(translated); + break; + case VertexStorageType::CURRENT_VALUE: { - mActiveDisabledAttributes.push_back(attribIndex); + ANGLE_TRY(storeCurrentValue(currentValueData, translated, attribIndex)); + break; } + default: + UNREACHABLE(); + break; } } - // Reserve the required space in the buffers - for (const TranslatedAttribute *activeAttrib : mActiveEnabledAttributes) + if (mDynamicAttribsMaskCache.none()) { - gl::Error error = reserveSpaceForAttrib(*activeAttrib, count, instances); - if (error.isError()) - { - return error; - } + return gl::NoError(); } - // Perform the vertex data translations - for (TranslatedAttribute *activeAttrib : mActiveEnabledAttributes) - { - gl::Error error = storeAttribute(activeAttrib, start, count, instances); + ANGLE_TRY(storeDynamicAttribs(context, translatedAttribs, mDynamicAttribsMaskCache, start, + count, instances)); - if (error.isError()) - { - hintUnmapAllResources(vertexAttributes); - return error; - } + PromoteDynamicAttribs(context, *translatedAttribs, mDynamicAttribsMaskCache, count); + + return gl::NoError(); +} + +// static +void VertexDataManager::StoreDirectAttrib(TranslatedAttribute *directAttrib) +{ + ASSERT(directAttrib->attribute && directAttrib->binding); + const auto &attrib = *directAttrib->attribute; + const auto &binding = *directAttrib->binding; + + gl::Buffer *buffer = binding.getBuffer().get(); + ASSERT(buffer); + BufferD3D *bufferD3D = GetImplAs(buffer); + + ASSERT(DirectStoragePossible(attrib, binding)); + directAttrib->vertexBuffer.set(nullptr); + directAttrib->storage = bufferD3D; + directAttrib->serial = bufferD3D->getSerial(); + directAttrib->stride = static_cast(ComputeVertexAttributeStride(attrib, binding)); + directAttrib->baseOffset = + static_cast(ComputeVertexAttributeOffset(attrib, binding)); + + // Instanced vertices do not apply the 'start' offset + directAttrib->usesFirstVertexOffset = (binding.getDivisor() == 0); +} + +// static +gl::Error VertexDataManager::StoreStaticAttrib(const gl::Context *context, + TranslatedAttribute *translated) +{ + ASSERT(translated->attribute && translated->binding); + const auto &attrib = *translated->attribute; + const auto &binding = *translated->binding; + + gl::Buffer *buffer = binding.getBuffer().get(); + ASSERT(buffer && attrib.enabled && !DirectStoragePossible(attrib, binding)); + BufferD3D *bufferD3D = GetImplAs(buffer); + + // Compute source data pointer + const uint8_t *sourceData = nullptr; + const int offset = static_cast(ComputeVertexAttributeOffset(attrib, binding)); + + ANGLE_TRY(bufferD3D->getData(context, &sourceData)); + sourceData += offset; + + unsigned int streamOffset = 0; + + translated->storage = nullptr; + ANGLE_TRY_RESULT(bufferD3D->getFactory()->getVertexSpaceRequired(attrib, binding, 1, 0), + translated->stride); + + auto *staticBuffer = bufferD3D->getStaticVertexBuffer(attrib, binding); + ASSERT(staticBuffer); + + if (staticBuffer->empty()) + { + // Convert the entire buffer + int totalCount = + ElementsInBuffer(attrib, binding, static_cast(bufferD3D->getSize())); + int startIndex = offset / static_cast(ComputeVertexAttributeStride(attrib, binding)); + + ANGLE_TRY(staticBuffer->storeStaticAttribute(attrib, binding, -startIndex, totalCount, 0, + sourceData)); } - for (size_t attribIndex : mActiveDisabledAttributes) - { - if (mCurrentValueCache[attribIndex].buffer == nullptr) - { - mCurrentValueCache[attribIndex].buffer = new StreamingVertexBufferInterface(mFactory, CONSTANT_VERTEX_BUFFER_SIZE); - } + unsigned int firstElementOffset = + (static_cast(offset) / + static_cast(ComputeVertexAttributeStride(attrib, binding))) * + translated->stride; - gl::Error error = storeCurrentValue( - state.getVertexAttribCurrentValue(static_cast(attribIndex)), - &(*translatedAttribs)[attribIndex], &mCurrentValueCache[attribIndex]); - if (error.isError()) - { - hintUnmapAllResources(vertexAttributes); - return error; - } + VertexBuffer *vertexBuffer = staticBuffer->getVertexBuffer(); + + CheckedNumeric checkedOffset(streamOffset); + checkedOffset += firstElementOffset; + + if (!checkedOffset.IsValid()) + { + return gl::InternalError() << "Integer overflow in VertexDataManager::StoreStaticAttrib"; } - // Hint to unmap all the resources - hintUnmapAllResources(vertexAttributes); + translated->vertexBuffer.set(vertexBuffer); + translated->serial = vertexBuffer->getSerial(); + translated->baseOffset = streamOffset + firstElementOffset; - for (const TranslatedAttribute *activeAttrib : mActiveEnabledAttributes) + // Instanced vertices do not apply the 'start' offset + translated->usesFirstVertexOffset = (binding.getDivisor() == 0); + + return gl::NoError(); +} + +gl::Error VertexDataManager::storeDynamicAttribs( + const gl::Context *context, + std::vector *translatedAttribs, + const gl::AttributesMask &dynamicAttribsMask, + GLint start, + GLsizei count, + GLsizei instances) +{ + // Instantiating this class will ensure the streaming buffer is never left mapped. + class StreamingBufferUnmapper final : NonCopyable { - gl::Buffer *buffer = activeAttrib->attribute->buffer.get(); + public: + StreamingBufferUnmapper(StreamingVertexBufferInterface *streamingBuffer) + : mStreamingBuffer(streamingBuffer) + { + ASSERT(mStreamingBuffer); + } + ~StreamingBufferUnmapper() { mStreamingBuffer->getVertexBuffer()->hintUnmapResource(); } + private: + StreamingVertexBufferInterface *mStreamingBuffer; + }; + + // Will trigger unmapping on return. + StreamingBufferUnmapper localUnmapper(mStreamingBuffer.get()); + + // Reserve the required space for the dynamic buffers. + for (auto attribIndex : dynamicAttribsMask) + { + const auto &dynamicAttrib = (*translatedAttribs)[attribIndex]; + ANGLE_TRY(reserveSpaceForAttrib(dynamicAttrib, start, count, instances)); + } + + // Store dynamic attributes + for (auto attribIndex : dynamicAttribsMask) + { + auto *dynamicAttrib = &(*translatedAttribs)[attribIndex]; + ANGLE_TRY(storeDynamicAttrib(context, dynamicAttrib, start, count, instances)); + } + + return gl::NoError(); +} + +void VertexDataManager::PromoteDynamicAttribs( + const gl::Context *context, + const std::vector &translatedAttribs, + const gl::AttributesMask &dynamicAttribsMask, + GLsizei count) +{ + for (auto attribIndex : dynamicAttribsMask) + { + const auto &dynamicAttrib = translatedAttribs[attribIndex]; + ASSERT(dynamicAttrib.attribute && dynamicAttrib.binding); + const auto &binding = *dynamicAttrib.binding; + + gl::Buffer *buffer = binding.getBuffer().get(); if (buffer) { BufferD3D *bufferD3D = GetImplAs(buffer); - size_t typeSize = ComputeVertexAttributeTypeSize(*activeAttrib->attribute); - bufferD3D->promoteStaticUsage(count * static_cast(typeSize)); + size_t typeSize = ComputeVertexAttributeTypeSize(*dynamicAttrib.attribute); + bufferD3D->promoteStaticUsage(context, count * static_cast(typeSize)); } } - - return gl::Error(GL_NO_ERROR); } gl::Error VertexDataManager::reserveSpaceForAttrib(const TranslatedAttribute &translatedAttrib, + GLint start, GLsizei count, GLsizei instances) const { - const gl::VertexAttribute &attrib = *translatedAttrib.attribute; - gl::Buffer *buffer = attrib.buffer.get(); - BufferD3D *bufferImpl = buffer ? GetImplAs(buffer) : NULL; - StaticVertexBufferInterface *staticBuffer = - bufferImpl ? bufferImpl->getStaticVertexBuffer(attrib, D3D_BUFFER_CREATE_IF_NECESSARY) - : NULL; - VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast(mStreamingBuffer); + ASSERT(translatedAttrib.attribute && translatedAttrib.binding); + const auto &attrib = *translatedAttrib.attribute; + const auto &binding = *translatedAttrib.binding; - if (!vertexBuffer->directStoragePossible(attrib, translatedAttrib.currentValueType)) + ASSERT(!DirectStoragePossible(attrib, binding)); + + gl::Buffer *buffer = binding.getBuffer().get(); + BufferD3D *bufferD3D = buffer ? GetImplAs(buffer) : nullptr; + ASSERT(!bufferD3D || bufferD3D->getStaticVertexBuffer(attrib, binding) == nullptr); + + size_t totalCount = gl::ComputeVertexBindingElementCount( + binding.getDivisor(), static_cast(count), static_cast(instances)); + // TODO(jiajia.qin@intel.com): force the index buffer to clamp any out of range indices instead + // of invalid operation here. + if (bufferD3D) { - if (staticBuffer) - { - if (staticBuffer->getBufferSize() == 0) - { - int totalCount = - ElementsInBuffer(attrib, static_cast(bufferImpl->getSize())); - gl::Error error = staticBuffer->reserveVertexSpace(attrib, totalCount, 0); - if (error.isError()) - { - return error; - } - } - } - else - { - size_t totalCount = ComputeVertexAttributeElementCount(attrib, count, instances); - ASSERT(!bufferImpl || - ElementsInBuffer(attrib, static_cast(bufferImpl->getSize())) >= - static_cast(totalCount)); + // Vertices do not apply the 'start' offset when the divisor is non-zero even when doing + // a non-instanced draw call + GLint firstVertexIndex = binding.getDivisor() > 0 ? 0 : start; + int64_t maxVertexCount = + static_cast(firstVertexIndex) + static_cast(totalCount); + int elementsInBuffer = + ElementsInBuffer(attrib, binding, static_cast(bufferD3D->getSize())); - gl::Error error = mStreamingBuffer->reserveVertexSpace( - attrib, static_cast(totalCount), instances); - if (error.isError()) - { - return error; - } + if (maxVertexCount > elementsInBuffer) + { + return gl::InvalidOperation() << "Vertex buffer is not big enough for the draw call."; } } - - return gl::Error(GL_NO_ERROR); + return mStreamingBuffer->reserveVertexSpace(attrib, binding, static_cast(totalCount), + instances); } -gl::Error VertexDataManager::storeAttribute(TranslatedAttribute *translated, - GLint start, - GLsizei count, - GLsizei instances) +gl::Error VertexDataManager::storeDynamicAttrib(const gl::Context *context, + TranslatedAttribute *translated, + GLint start, + GLsizei count, + GLsizei instances) { - const gl::VertexAttribute &attrib = *translated->attribute; + ASSERT(translated->attribute && translated->binding); + const auto &attrib = *translated->attribute; + const auto &binding = *translated->binding; - gl::Buffer *buffer = attrib.buffer.get(); + gl::Buffer *buffer = binding.getBuffer().get(); ASSERT(buffer || attrib.pointer); ASSERT(attrib.enabled); - BufferD3D *storage = buffer ? GetImplAs(buffer) : NULL; - StaticVertexBufferInterface *staticBuffer = - storage ? storage->getStaticVertexBuffer(attrib, D3D_BUFFER_DO_NOT_CREATE) : NULL; - VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast(mStreamingBuffer); - bool directStorage = vertexBuffer->directStoragePossible(attrib, translated->currentValueType); + BufferD3D *storage = buffer ? GetImplAs(buffer) : nullptr; // Instanced vertices do not apply the 'start' offset - GLint firstVertexIndex = (attrib.divisor > 0 ? 0 : start); - - translated->vertexBuffer = vertexBuffer->getVertexBuffer(); - - if (directStorage) - { - translated->storage = storage; - translated->serial = storage->getSerial(); - translated->stride = static_cast(ComputeVertexAttributeStride(attrib)); - translated->offset = static_cast(attrib.offset + translated->stride * firstVertexIndex); - - return gl::Error(GL_NO_ERROR); - } + GLint firstVertexIndex = (binding.getDivisor() > 0 ? 0 : start); // Compute source data pointer const uint8_t *sourceData = nullptr; if (buffer) { - gl::Error error = storage->getData(&sourceData); - if (error.isError()) - { - return error; - } - sourceData += static_cast(attrib.offset); + ANGLE_TRY(storage->getData(context, &sourceData)); + sourceData += static_cast(ComputeVertexAttributeOffset(attrib, binding)); } else { + // Attributes using client memory ignore the VERTEX_ATTRIB_BINDING state. + // https://www.opengl.org/registry/specs/ARB/vertex_attrib_binding.txt sourceData = static_cast(attrib.pointer); } unsigned int streamOffset = 0; - unsigned int outputElementSize = 0; - - if (staticBuffer) - { - gl::Error error = staticBuffer->getVertexBuffer()->getSpaceRequired(attrib, 1, 0, &outputElementSize); - if (error.isError()) - { - return error; - } - - if (!staticBuffer->lookupAttribute(attrib, &streamOffset)) - { - // Convert the entire buffer - int totalCount = - ElementsInBuffer(attrib, static_cast(storage->getSize())); - int startIndex = static_cast(attrib.offset) / - static_cast(ComputeVertexAttributeStride(attrib)); - - error = staticBuffer->storeVertexAttributes(attrib, - translated->currentValueType, - -startIndex, - totalCount, - 0, - &streamOffset, - sourceData); - if (error.isError()) - { - return error; - } - } - - unsigned int firstElementOffset = - (static_cast(attrib.offset) / - static_cast(ComputeVertexAttributeStride(attrib))) * - outputElementSize; - ASSERT(attrib.divisor == 0 || firstVertexIndex == 0); - unsigned int startOffset = firstVertexIndex * outputElementSize; - if (streamOffset + firstElementOffset + startOffset < streamOffset) - { - return gl::Error(GL_OUT_OF_MEMORY); - } - - streamOffset += firstElementOffset + startOffset; - } - else - { - size_t totalCount = ComputeVertexAttributeElementCount(attrib, count, instances); - gl::Error error = mStreamingBuffer->getVertexBuffer()->getSpaceRequired(attrib, 1, 0, &outputElementSize); - if (error.isError()) - { - return error; - } - - error = mStreamingBuffer->storeVertexAttributes( - attrib, translated->currentValueType, firstVertexIndex, - static_cast(totalCount), instances, &streamOffset, sourceData); - if (error.isError()) - { - return error; - } - } translated->storage = nullptr; - translated->serial = vertexBuffer->getSerial(); - translated->stride = outputElementSize; - translated->offset = streamOffset; + ANGLE_TRY_RESULT(mFactory->getVertexSpaceRequired(attrib, binding, 1, 0), translated->stride); - return gl::Error(GL_NO_ERROR); + size_t totalCount = gl::ComputeVertexBindingElementCount( + binding.getDivisor(), static_cast(count), static_cast(instances)); + + ANGLE_TRY(mStreamingBuffer->storeDynamicAttribute( + attrib, binding, translated->currentValueType, firstVertexIndex, + static_cast(totalCount), instances, &streamOffset, sourceData)); + + VertexBuffer *vertexBuffer = mStreamingBuffer->getVertexBuffer(); + + translated->vertexBuffer.set(vertexBuffer); + translated->serial = vertexBuffer->getSerial(); + translated->baseOffset = streamOffset; + translated->usesFirstVertexOffset = false; + + return gl::NoError(); } gl::Error VertexDataManager::storeCurrentValue(const gl::VertexAttribCurrentValueData ¤tValue, TranslatedAttribute *translated, - CurrentValueState *cachedState) + size_t attribIndex) { + CurrentValueState *cachedState = &mCurrentValueCache[attribIndex]; + auto &buffer = cachedState->buffer; + + if (!buffer) + { + buffer.reset(new StreamingVertexBufferInterface(mFactory, CONSTANT_VERTEX_BUFFER_SIZE)); + } + if (cachedState->data != currentValue) { - const gl::VertexAttribute &attrib = *translated->attribute; + ASSERT(translated->attribute && translated->binding); + const auto &attrib = *translated->attribute; + const auto &binding = *translated->binding; - gl::Error error = cachedState->buffer->reserveVertexSpace(attrib, 1, 0); - if (error.isError()) - { - return error; - } + ANGLE_TRY(buffer->reserveVertexSpace(attrib, binding, 1, 0)); const uint8_t *sourceData = reinterpret_cast(currentValue.FloatValues); unsigned int streamOffset; - error = cachedState->buffer->storeVertexAttributes(attrib, currentValue.Type, 0, 1, 0, &streamOffset, sourceData); - if (error.isError()) - { - return error; - } + ANGLE_TRY(buffer->storeDynamicAttribute(attrib, binding, currentValue.Type, 0, 1, 0, + &streamOffset, sourceData)); + + buffer->getVertexBuffer()->hintUnmapResource(); cachedState->data = currentValue; cachedState->offset = streamOffset; } - translated->storage = NULL; - translated->vertexBuffer = cachedState->buffer->getVertexBuffer(); - translated->serial = cachedState->buffer->getSerial(); + translated->vertexBuffer.set(buffer->getVertexBuffer()); + + translated->storage = nullptr; + translated->serial = buffer->getSerial(); translated->divisor = 0; + translated->stride = 0; + translated->baseOffset = static_cast(cachedState->offset); + translated->usesFirstVertexOffset = false; - translated->stride = 0; - translated->offset = static_cast(cachedState->offset); - - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } +// VertexBufferBinding implementation +VertexBufferBinding::VertexBufferBinding() : mBoundVertexBuffer(nullptr) +{ } + +VertexBufferBinding::VertexBufferBinding(const VertexBufferBinding &other) + : mBoundVertexBuffer(other.mBoundVertexBuffer) +{ + if (mBoundVertexBuffer) + { + mBoundVertexBuffer->addRef(); + } +} + +VertexBufferBinding::~VertexBufferBinding() +{ + if (mBoundVertexBuffer) + { + mBoundVertexBuffer->release(); + } +} + +VertexBufferBinding &VertexBufferBinding::operator=(const VertexBufferBinding &other) +{ + mBoundVertexBuffer = other.mBoundVertexBuffer; + if (mBoundVertexBuffer) + { + mBoundVertexBuffer->addRef(); + } + return *this; +} + +void VertexBufferBinding::set(VertexBuffer *vertexBuffer) +{ + if (mBoundVertexBuffer == vertexBuffer) + return; + + if (mBoundVertexBuffer) + { + mBoundVertexBuffer->release(); + } + if (vertexBuffer) + { + vertexBuffer->addRef(); + } + + mBoundVertexBuffer = vertexBuffer; +} + +VertexBuffer *VertexBufferBinding::get() const +{ + return mBoundVertexBuffer; +} + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexDataManager.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexDataManager.h index fb349c4cc2..694366deb7 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexDataManager.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/VertexDataManager.h @@ -10,14 +10,16 @@ #ifndef LIBANGLE_RENDERER_D3D_VERTEXDATAMANAGER_H_ #define LIBANGLE_RENDERER_D3D_VERTEXDATAMANAGER_H_ +#include "common/angleutils.h" +#include "libANGLE/angletypes.h" #include "libANGLE/Constants.h" #include "libANGLE/VertexAttribute.h" -#include "common/angleutils.h" namespace gl { class State; struct VertexAttribute; +class VertexBinding; struct VertexAttribCurrentValueData; } @@ -28,81 +30,123 @@ class BufferFactoryD3D; class StreamingVertexBufferInterface; class VertexBuffer; +class VertexBufferBinding final +{ + public: + VertexBufferBinding(); + VertexBufferBinding(const VertexBufferBinding &other); + ~VertexBufferBinding(); + + void set(VertexBuffer *vertexBuffer); + VertexBuffer *get() const; + VertexBufferBinding &operator=(const VertexBufferBinding &other); + + private: + VertexBuffer *mBoundVertexBuffer; +}; + struct TranslatedAttribute { - TranslatedAttribute() - : active(false), - attribute(NULL), - currentValueType(GL_NONE), - offset(0), - stride(0), - vertexBuffer(NULL), - storage(NULL), - serial(0), - divisor(0) - {} + TranslatedAttribute(); + TranslatedAttribute(const TranslatedAttribute &other); + + // Computes the correct offset from baseOffset, usesFirstVertexOffset, stride and startVertex. + // Can throw an error on integer overflow. + gl::ErrorOrResult computeOffset(GLint startVertex) const; bool active; const gl::VertexAttribute *attribute; + const gl::VertexBinding *binding; GLenum currentValueType; - unsigned int offset; + unsigned int baseOffset; + bool usesFirstVertexOffset; unsigned int stride; // 0 means not to advance the read pointer at all - VertexBuffer *vertexBuffer; + VertexBufferBinding vertexBuffer; BufferD3D *storage; unsigned int serial; unsigned int divisor; }; +enum class VertexStorageType +{ + UNKNOWN, + STATIC, // Translate the vertex data once and re-use it. + DYNAMIC, // Translate the data every frame into a ring buffer. + DIRECT, // Bind a D3D buffer directly without any translation. + CURRENT_VALUE, // Use a single value for the attribute. +}; + +// Given a vertex attribute, return the type of storage it will use. +VertexStorageType ClassifyAttributeStorage(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding); + class VertexDataManager : angle::NonCopyable { public: VertexDataManager(BufferFactoryD3D *factory); virtual ~VertexDataManager(); - gl::Error prepareVertexData(const gl::State &state, + gl::Error initialize(); + void deinitialize(); + + gl::Error prepareVertexData(const gl::Context *context, GLint start, GLsizei count, std::vector *translatedAttribs, GLsizei instances); + static void StoreDirectAttrib(TranslatedAttribute *directAttrib); + + static gl::Error StoreStaticAttrib(const gl::Context *context, TranslatedAttribute *translated); + + gl::Error storeDynamicAttribs(const gl::Context *context, + std::vector *translatedAttribs, + const gl::AttributesMask &dynamicAttribsMask, + GLint start, + GLsizei count, + GLsizei instances); + + // Promote static usage of dynamic buffers. + static void PromoteDynamicAttribs(const gl::Context *context, + const std::vector &translatedAttribs, + const gl::AttributesMask &dynamicAttribsMask, + GLsizei count); + + gl::Error storeCurrentValue(const gl::VertexAttribCurrentValueData ¤tValue, + TranslatedAttribute *translated, + size_t attribIndex); + private: struct CurrentValueState { CurrentValueState(); ~CurrentValueState(); - StreamingVertexBufferInterface *buffer; + std::unique_ptr buffer; gl::VertexAttribCurrentValueData data; size_t offset; }; gl::Error reserveSpaceForAttrib(const TranslatedAttribute &translatedAttrib, GLsizei count, + GLint start, GLsizei instances) const; - gl::Error storeAttribute(TranslatedAttribute *translated, - GLint start, - GLsizei count, - GLsizei instances); - - gl::Error storeCurrentValue(const gl::VertexAttribCurrentValueData ¤tValue, - TranslatedAttribute *translated, - CurrentValueState *cachedState); - - void hintUnmapAllResources(const std::vector &vertexAttributes); + gl::Error storeDynamicAttrib(const gl::Context *context, + TranslatedAttribute *translated, + GLint start, + GLsizei count, + GLsizei instances); BufferFactoryD3D *const mFactory; - StreamingVertexBufferInterface *mStreamingBuffer; + std::unique_ptr mStreamingBuffer; std::vector mCurrentValueCache; - - // Cache variables - std::vector mActiveEnabledAttributes; - std::vector mActiveDisabledAttributes; + gl::AttributesMask mDynamicAttribsMaskCache; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_VERTEXDATAMANAGER_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/WorkaroundsD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/WorkaroundsD3D.h deleted file mode 100644 index 58f65f6496..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/WorkaroundsD3D.h +++ /dev/null @@ -1,66 +0,0 @@ -// -// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// WorkaroundsD3D.h: Workarounds for D3D driver bugs and other issues. - -#ifndef LIBANGLE_RENDERER_D3D_WORKAROUNDSD3D_H_ -#define LIBANGLE_RENDERER_D3D_WORKAROUNDSD3D_H_ - -// TODO(jmadill,zmo,geofflang): make a workarounds library that can operate -// independent of ANGLE's renderer. Workarounds should also be accessible -// outside of the Renderer. - -namespace rx -{ -struct D3DCompilerWorkarounds -{ - D3DCompilerWorkarounds() - : skipOptimization(false), useMaxOptimization(false), enableIEEEStrictness(false) - { - } - - bool skipOptimization; - bool useMaxOptimization; - - // IEEE strictness needs to be enabled for NANs to work. - bool enableIEEEStrictness; -}; - -struct WorkaroundsD3D -{ - WorkaroundsD3D() - : mrtPerfWorkaround(false), - setDataFasterThanImageUpload(false), - zeroMaxLodWorkaround(false), - useInstancedPointSpriteEmulation(false) - { - } - - // On some systems, having extra rendertargets than necessary slows down the shader. - // We can fix this by optimizing those out of the shader. At the same time, we can - // work around a bug on some nVidia drivers that they ignore "null" render targets - // in D3D11, by compacting the active color attachments list to omit null entries. - bool mrtPerfWorkaround; - - bool setDataFasterThanImageUpload; - - // Some renderers can't disable mipmaps on a mipmapped texture (i.e. solely sample from level - // zero, and ignore the other levels). D3D11 Feature Level 10+ does this by setting MaxLOD to - // 0.0f in the Sampler state. D3D9 sets D3DSAMP_MIPFILTER to D3DTEXF_NONE. There is no - // equivalent to this in D3D11 Feature Level 9_3. This causes problems when (for example) an - // application creates a mipmapped texture2D, but sets GL_TEXTURE_MIN_FILTER to GL_NEAREST - // (i.e disables mipmaps). To work around this, D3D11 FL9_3 has to create two copies of the - // texture. The textures' level zeros are identical, but only one texture has mips. - bool zeroMaxLodWorkaround; - - // Some renderers do not support Geometry Shaders so the Geometry Shader-based PointSprite - // emulation will not work. To work around this, D3D11 FL9_3 has to use a different pointsprite - // emulation that is implemented using instanced quads. - bool useInstancedPointSpriteEmulation; -}; -} - -#endif // LIBANGLE_RENDERER_D3D_WORKAROUNDSD3D_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/copyimage.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/copyimage.cpp deleted file mode 100644 index b1798454ca..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/copyimage.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// -// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// copyimage.cpp: Defines image copying functions - -#include "libANGLE/renderer/d3d/copyimage.h" - -namespace rx -{ - -void CopyBGRA8ToRGBA8(const uint8_t *source, uint8_t *dest) -{ - uint32_t argb = *reinterpret_cast(source); - *reinterpret_cast(dest) = (argb & 0xFF00FF00) | // Keep alpha and green - (argb & 0x00FF0000) >> 16 | // Move red to blue - (argb & 0x000000FF) << 16; // Move blue to red -} - -} diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp index e951e13408..f032e888f1 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp @@ -10,112 +10,404 @@ #include +#include "common/utilities.h" #include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" #include "libANGLE/renderer/d3d/d3d11/Renderer11.h" -#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" #include "third_party/trace_event/trace_event.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dui11ps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2di11ps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dui11ps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dui11ps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2di11ps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2d11ps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2dui11ps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2di11ps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2d11ps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h" - -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11vs.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11gs.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dui11ps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3di11ps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d11ps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dui11ps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3di11ps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3d11ps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dui11ps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3di11ps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3d11ps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3dui11ps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3di11ps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum3d11ps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h" - -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef3dps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2darrayps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h" - namespace rx { namespace { -DXGI_FORMAT GetTextureFormat(ID3D11Resource *resource) +// Include inline shaders in the anonymous namespace to make sure no symbols are exported +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrougha2d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2di11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2dui11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2di11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dui11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dui11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2di11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dui11ps.h" + +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_ps.h" + +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11gs.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11vs.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum3d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3di11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3dui11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3di11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dui11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3di11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dui11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3di11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dui11ps.h" + +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepth11_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_vs.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvestencil11_ps.h" + +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2darrayps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef3dps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h" + +void StretchedBlitNearest_RowByRow(const gl::Box &sourceArea, + const gl::Box &destArea, + const gl::Rectangle &clippedDestArea, + const gl::Extents &sourceSize, + unsigned int sourceRowPitch, + unsigned int destRowPitch, + size_t pixelSize, + const uint8_t *sourceData, + uint8_t *destData) { - ID3D11Texture2D *texture = d3d11::DynamicCastComObject(resource); - if (!texture) + int srcHeightSubOne = (sourceArea.height - 1); + size_t copySize = pixelSize * destArea.width; + size_t srcOffset = sourceArea.x * pixelSize; + size_t destOffset = destArea.x * pixelSize; + + for (int y = clippedDestArea.y; y < clippedDestArea.y + clippedDestArea.height; y++) { - return DXGI_FORMAT_UNKNOWN; + float yPerc = static_cast(y - destArea.y) / (destArea.height - 1); + + // Interpolate using the original source rectangle to determine which row to sample from + // while clamping to the edges + unsigned int readRow = static_cast( + gl::clamp(sourceArea.y + floor(yPerc * srcHeightSubOne + 0.5f), 0, srcHeightSubOne)); + unsigned int writeRow = y; + + const uint8_t *sourceRow = sourceData + readRow * sourceRowPitch + srcOffset; + uint8_t *destRow = destData + writeRow * destRowPitch + destOffset; + memcpy(destRow, sourceRow, copySize); } - - D3D11_TEXTURE2D_DESC desc; - texture->GetDesc(&desc); - - SafeRelease(texture); - - return desc.Format; } -ID3D11Resource *CreateStagingTexture(ID3D11Device *device, ID3D11DeviceContext *context, - ID3D11Resource *source, unsigned int subresource, - const gl::Extents &size, unsigned int cpuAccessFlags) +void StretchedBlitNearest_PixelByPixel(const gl::Box &sourceArea, + const gl::Box &destArea, + const gl::Rectangle &clippedDestArea, + const gl::Extents &sourceSize, + unsigned int sourceRowPitch, + unsigned int destRowPitch, + ptrdiff_t readOffset, + ptrdiff_t writeOffset, + size_t copySize, + size_t srcPixelStride, + size_t destPixelStride, + const uint8_t *sourceData, + uint8_t *destData) { - D3D11_TEXTURE2D_DESC stagingDesc; - stagingDesc.Width = size.width; - stagingDesc.Height = size.height; - stagingDesc.MipLevels = 1; - stagingDesc.ArraySize = 1; - stagingDesc.Format = GetTextureFormat(source); - stagingDesc.SampleDesc.Count = 1; - stagingDesc.SampleDesc.Quality = 0; - stagingDesc.Usage = D3D11_USAGE_STAGING; - stagingDesc.CPUAccessFlags = cpuAccessFlags; - stagingDesc.MiscFlags = 0; - stagingDesc.BindFlags = 0; + auto xMax = clippedDestArea.x + clippedDestArea.width; + auto yMax = clippedDestArea.y + clippedDestArea.height; - ID3D11Texture2D *stagingTexture = nullptr; - HRESULT result = device->CreateTexture2D(&stagingDesc, nullptr, &stagingTexture); - if (FAILED(result)) + for (int writeRow = clippedDestArea.y; writeRow < yMax; writeRow++) { - ERR("Failed to create staging texture for depth stencil blit. HRESULT: 0x%X.", result); - return nullptr; + // Interpolate using the original source rectangle to determine which row to sample from + // while clamping to the edges + float yPerc = static_cast(writeRow - destArea.y) / (destArea.height - 1); + float yRounded = floor(yPerc * (sourceArea.height - 1) + 0.5f); + unsigned int readRow = + static_cast(gl::clamp(sourceArea.y + yRounded, 0, sourceSize.height - 1)); + + for (int writeColumn = clippedDestArea.x; writeColumn < xMax; writeColumn++) + { + // Interpolate the original source rectangle to determine which column to sample + // from while clamping to the edges + float xPerc = static_cast(writeColumn - destArea.x) / (destArea.width - 1); + float xRounded = floor(xPerc * (sourceArea.width - 1) + 0.5f); + unsigned int readColumn = static_cast( + gl::clamp(sourceArea.x + xRounded, 0, sourceSize.height - 1)); + + const uint8_t *sourcePixel = + sourceData + readRow * sourceRowPitch + readColumn * srcPixelStride + readOffset; + + uint8_t *destPixel = + destData + writeRow * destRowPitch + writeColumn * destPixelStride + writeOffset; + + memcpy(destPixel, sourcePixel, copySize); + } } - - context->CopySubresourceRegion(stagingTexture, 0, 0, 0, 0, source, subresource, nullptr); - - return stagingTexture; } -inline void GenerateVertexCoords(const gl::Box &sourceArea, const gl::Extents &sourceSize, - const gl::Box &destArea, const gl::Extents &destSize, - float *x1, float *y1, float *x2, float *y2, - float *u1, float *v1, float *u2, float *v2) +void StretchedBlitNearest(const gl::Box &sourceArea, + const gl::Box &destArea, + const gl::Rectangle &clipRect, + const gl::Extents &sourceSize, + unsigned int sourceRowPitch, + unsigned int destRowPitch, + ptrdiff_t readOffset, + ptrdiff_t writeOffset, + size_t copySize, + size_t srcPixelStride, + size_t destPixelStride, + const uint8_t *sourceData, + uint8_t *destData) +{ + gl::Rectangle clippedDestArea(destArea.x, destArea.y, destArea.width, destArea.height); + gl::ClipRectangle(clippedDestArea, clipRect, &clippedDestArea); + + // Determine if entire rows can be copied at once instead of each individual pixel. There + // must be no out of bounds lookups, whole rows copies, and no scale. + if (sourceArea.width == clippedDestArea.width && sourceArea.x >= 0 && + sourceArea.x + sourceArea.width <= sourceSize.width && copySize == srcPixelStride && + copySize == destPixelStride) + { + StretchedBlitNearest_RowByRow(sourceArea, destArea, clippedDestArea, sourceSize, + sourceRowPitch, destRowPitch, srcPixelStride, sourceData, + destData); + } + else + { + StretchedBlitNearest_PixelByPixel(sourceArea, destArea, clippedDestArea, sourceSize, + sourceRowPitch, destRowPitch, readOffset, writeOffset, + copySize, srcPixelStride, destPixelStride, sourceData, + destData); + } +} + +using DepthStencilLoader = void(const float *, uint8_t *); + +void LoadDepth16(const float *source, uint8_t *dest) +{ + uint32_t convertedDepth = gl::floatToNormalized<16, uint32_t>(source[0]); + memcpy(dest, &convertedDepth, 2u); +} + +void LoadDepth24(const float *source, uint8_t *dest) +{ + uint32_t convertedDepth = gl::floatToNormalized<24, uint32_t>(source[0]); + memcpy(dest, &convertedDepth, 3u); +} + +void LoadStencilHelper(const float *source, uint8_t *dest) +{ + uint32_t convertedStencil = gl::getShiftedData<8, 0>(static_cast(source[1])); + memcpy(dest, &convertedStencil, 1u); +} + +void LoadStencil8(const float *source, uint8_t *dest) +{ + // STENCIL_INDEX8 is implemented with D24S8, with the depth bits unused. Writes zero for safety. + float zero = 0.0f; + LoadDepth24(&zero, &dest[0]); + LoadStencilHelper(source, &dest[3]); +} + +void LoadDepth24Stencil8(const float *source, uint8_t *dest) +{ + LoadDepth24(source, &dest[0]); + LoadStencilHelper(source, &dest[3]); +} + +void LoadDepth32F(const float *source, uint8_t *dest) +{ + memcpy(dest, source, sizeof(float)); +} + +void LoadDepth32FStencil8(const float *source, uint8_t *dest) +{ + LoadDepth32F(source, &dest[0]); + LoadStencilHelper(source, &dest[4]); +} + +template +void CopyDepthStencil(const gl::Box &sourceArea, + const gl::Box &destArea, + const gl::Rectangle &clippedDestArea, + const gl::Extents &sourceSize, + unsigned int sourceRowPitch, + unsigned int destRowPitch, + ptrdiff_t readOffset, + ptrdiff_t writeOffset, + size_t copySize, + size_t srcPixelStride, + size_t destPixelStride, + const uint8_t *sourceData, + uint8_t *destData) +{ + // No stretching or subregions are supported, only full blits. + ASSERT(sourceArea == destArea); + ASSERT(sourceSize.width == sourceArea.width && sourceSize.height == sourceArea.height && + sourceSize.depth == 1); + ASSERT(clippedDestArea.width == sourceSize.width && + clippedDestArea.height == sourceSize.height); + ASSERT(readOffset == 0 && writeOffset == 0); + ASSERT(destArea.x == 0 && destArea.y == 0); + + for (int row = 0; row < destArea.height; ++row) + { + for (int column = 0; column < destArea.width; ++column) + { + ptrdiff_t offset = row * sourceRowPitch + column * srcPixelStride; + const float *sourcePixel = reinterpret_cast(sourceData + offset); + + uint8_t *destPixel = destData + row * destRowPitch + column * destPixelStride; + + loader(sourcePixel, destPixel); + } + } +} + +void Depth32FStencil8ToDepth32F(const float *source, float *dest) +{ + *dest = *source; +} + +void Depth24Stencil8ToDepth32F(const uint32_t *source, float *dest) +{ + uint32_t normDepth = source[0] & 0x00FFFFFF; + float floatDepth = gl::normalizedToFloat<24>(normDepth); + *dest = floatDepth; +} + +void BlitD24S8ToD32F(const gl::Box &sourceArea, + const gl::Box &destArea, + const gl::Rectangle &clippedDestArea, + const gl::Extents &sourceSize, + unsigned int sourceRowPitch, + unsigned int destRowPitch, + ptrdiff_t readOffset, + ptrdiff_t writeOffset, + size_t copySize, + size_t srcPixelStride, + size_t destPixelStride, + const uint8_t *sourceData, + uint8_t *destData) +{ + // No stretching or subregions are supported, only full blits. + ASSERT(sourceArea == destArea); + ASSERT(sourceSize.width == sourceArea.width && sourceSize.height == sourceArea.height && + sourceSize.depth == 1); + ASSERT(clippedDestArea.width == sourceSize.width && + clippedDestArea.height == sourceSize.height); + ASSERT(readOffset == 0 && writeOffset == 0); + ASSERT(destArea.x == 0 && destArea.y == 0); + + for (int row = 0; row < destArea.height; ++row) + { + for (int column = 0; column < destArea.width; ++column) + { + ptrdiff_t offset = row * sourceRowPitch + column * srcPixelStride; + const uint32_t *sourcePixel = reinterpret_cast(sourceData + offset); + + float *destPixel = + reinterpret_cast(destData + row * destRowPitch + column * destPixelStride); + + Depth24Stencil8ToDepth32F(sourcePixel, destPixel); + } + } +} + +void BlitD32FS8ToD32F(const gl::Box &sourceArea, + const gl::Box &destArea, + const gl::Rectangle &clippedDestArea, + const gl::Extents &sourceSize, + unsigned int sourceRowPitch, + unsigned int destRowPitch, + ptrdiff_t readOffset, + ptrdiff_t writeOffset, + size_t copySize, + size_t srcPixelStride, + size_t destPixelStride, + const uint8_t *sourceData, + uint8_t *destData) +{ + // No stretching or subregions are supported, only full blits. + ASSERT(sourceArea == destArea); + ASSERT(sourceSize.width == sourceArea.width && sourceSize.height == sourceArea.height && + sourceSize.depth == 1); + ASSERT(clippedDestArea.width == sourceSize.width && + clippedDestArea.height == sourceSize.height); + ASSERT(readOffset == 0 && writeOffset == 0); + ASSERT(destArea.x == 0 && destArea.y == 0); + + for (int row = 0; row < destArea.height; ++row) + { + for (int column = 0; column < destArea.width; ++column) + { + ptrdiff_t offset = row * sourceRowPitch + column * srcPixelStride; + const float *sourcePixel = reinterpret_cast(sourceData + offset); + float *destPixel = + reinterpret_cast(destData + row * destRowPitch + column * destPixelStride); + + Depth32FStencil8ToDepth32F(sourcePixel, destPixel); + } + } +} + +Blit11::BlitConvertFunction *GetCopyDepthStencilFunction(GLenum internalFormat) +{ + switch (internalFormat) + { + case GL_DEPTH_COMPONENT16: + return &CopyDepthStencil; + case GL_DEPTH_COMPONENT24: + return &CopyDepthStencil; + case GL_DEPTH_COMPONENT32F: + return &CopyDepthStencil; + case GL_STENCIL_INDEX8: + return &CopyDepthStencil; + case GL_DEPTH24_STENCIL8: + return &CopyDepthStencil; + case GL_DEPTH32F_STENCIL8: + return &CopyDepthStencil; + default: + UNREACHABLE(); + return nullptr; + } +} + +inline void GenerateVertexCoords(const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const gl::Box &destArea, + const gl::Extents &destSize, + float *x1, + float *y1, + float *x2, + float *y2, + float *u1, + float *v1, + float *u2, + float *v2) { *x1 = (destArea.x / float(destSize.width)) * 2.0f - 1.0f; *y1 = ((destSize.height - destArea.y - destArea.height) / float(destSize.height)) * 2.0f - 1.0f; @@ -128,37 +420,49 @@ inline void GenerateVertexCoords(const gl::Box &sourceArea, const gl::Extents &s *v2 = (sourceArea.y + sourceArea.height) / float(sourceSize.height); } -void Write2DVertices(const gl::Box &sourceArea, const gl::Extents &sourceSize, - const gl::Box &destArea, const gl::Extents &destSize, - void *outVertices, unsigned int *outStride, unsigned int *outVertexCount, +void Write2DVertices(const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const gl::Box &destArea, + const gl::Extents &destSize, + void *outVertices, + unsigned int *outStride, + unsigned int *outVertexCount, D3D11_PRIMITIVE_TOPOLOGY *outTopology) { float x1, y1, x2, y2, u1, v1, u2, v2; - GenerateVertexCoords(sourceArea, sourceSize, destArea, destSize, &x1, &y1, &x2, &y2, &u1, &v1, &u2, &v2); + GenerateVertexCoords(sourceArea, sourceSize, destArea, destSize, &x1, &y1, &x2, &y2, &u1, &v1, + &u2, &v2); - d3d11::PositionTexCoordVertex *vertices = static_cast(outVertices); + d3d11::PositionTexCoordVertex *vertices = + static_cast(outVertices); d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v2); d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v1); d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v2); d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v1); - *outStride = sizeof(d3d11::PositionTexCoordVertex); + *outStride = sizeof(d3d11::PositionTexCoordVertex); *outVertexCount = 4; - *outTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; + *outTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; } -void Write3DVertices(const gl::Box &sourceArea, const gl::Extents &sourceSize, - const gl::Box &destArea, const gl::Extents &destSize, - void *outVertices, unsigned int *outStride, unsigned int *outVertexCount, +void Write3DVertices(const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const gl::Box &destArea, + const gl::Extents &destSize, + void *outVertices, + unsigned int *outStride, + unsigned int *outVertexCount, D3D11_PRIMITIVE_TOPOLOGY *outTopology) { ASSERT(sourceSize.depth > 0 && destSize.depth > 0); float x1, y1, x2, y2, u1, v1, u2, v2; - GenerateVertexCoords(sourceArea, sourceSize, destArea, destSize, &x1, &y1, &x2, &y2, &u1, &v1, &u2, &v2); + GenerateVertexCoords(sourceArea, sourceSize, destArea, destSize, &x1, &y1, &x2, &y2, &u1, &v1, + &u2, &v2); - d3d11::PositionLayerTexCoord3DVertex *vertices = static_cast(outVertices); + d3d11::PositionLayerTexCoord3DVertex *vertices = + static_cast(outVertices); for (int i = 0; i < destSize.depth; i++) { @@ -173,24 +477,38 @@ void Write3DVertices(const gl::Box &sourceArea, const gl::Extents &sourceSize, d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 5], x2, y1, i, u2, v2, readDepth); } - *outStride = sizeof(d3d11::PositionLayerTexCoord3DVertex); + *outStride = sizeof(d3d11::PositionLayerTexCoord3DVertex); *outVertexCount = destSize.depth * 6; - *outTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + *outTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; } -inline unsigned int GetSwizzleIndex(GLenum swizzle) +unsigned int GetSwizzleIndex(GLenum swizzle) { unsigned int colorIndex = 0; switch (swizzle) { - case GL_RED: colorIndex = 0; break; - case GL_GREEN: colorIndex = 1; break; - case GL_BLUE: colorIndex = 2; break; - case GL_ALPHA: colorIndex = 3; break; - case GL_ZERO: colorIndex = 4; break; - case GL_ONE: colorIndex = 5; break; - default: UNREACHABLE(); break; + case GL_RED: + colorIndex = 0; + break; + case GL_GREEN: + colorIndex = 1; + break; + case GL_BLUE: + colorIndex = 2; + break; + case GL_ALPHA: + colorIndex = 3; + break; + case GL_ZERO: + colorIndex = 4; + break; + case GL_ONE: + colorIndex = 5; + break; + default: + UNREACHABLE(); + break; } return colorIndex; @@ -213,30 +531,50 @@ D3D11_BLEND_DESC GetAlphaMaskBlendStateDesc() return desc; } -D3D11_INPUT_ELEMENT_DESC quad2DLayout[] = -{ - { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 }, +D3D11_INPUT_ELEMENT_DESC quad2DLayout[] = { + {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0}, }; -D3D11_INPUT_ELEMENT_DESC quad3DLayout[] = -{ - { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "LAYER", 0, DXGI_FORMAT_R32_UINT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, +D3D11_INPUT_ELEMENT_DESC quad3DLayout[] = { + {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"LAYER", 0, DXGI_FORMAT_R32_UINT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0}, + {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}, }; -} // namespace +DXGI_FORMAT GetStencilSRVFormat(const d3d11::Format &formatSet) +{ + switch (formatSet.texFormat) + { + case DXGI_FORMAT_R32G8X24_TYPELESS: + return DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; + case DXGI_FORMAT_R24G8_TYPELESS: + return DXGI_FORMAT_X24_TYPELESS_G8_UINT; + default: + UNREACHABLE(); + return DXGI_FORMAT_UNKNOWN; + } +} + +} // namespace + +Blit11::Shader::Shader() = default; + +Blit11::Shader::Shader(Shader &&other) = default; + +Blit11::Shader::~Shader() = default; + +Blit11::Shader &Blit11::Shader::operator=(Blit11::Shader &&other) = default; Blit11::Blit11(Renderer11 *renderer) : mRenderer(renderer), mResourcesInitialized(false), - mVertexBuffer(nullptr), - mPointSampler(nullptr), - mLinearSampler(nullptr), - mScissorEnabledRasterizerState(nullptr), - mScissorDisabledRasterizerState(nullptr), - mDepthStencilState(nullptr), + mVertexBuffer(), + mPointSampler(), + mLinearSampler(), + mScissorEnabledRasterizerState(), + mScissorDisabledRasterizerState(), + mDepthStencilState(), mQuad2DIL(quad2DLayout, ArraySize(quad2DLayout), g_VS_Passthrough2D, @@ -254,516 +592,552 @@ Blit11::Blit11(Renderer11 *renderer) mQuad3DVS(g_VS_Passthrough3D, ArraySize(g_VS_Passthrough3D), "Blit11 3D vertex shader"), mQuad3DGS(g_GS_Passthrough3D, ArraySize(g_GS_Passthrough3D), "Blit11 3D geometry shader"), mAlphaMaskBlendState(GetAlphaMaskBlendStateDesc(), "Blit11 Alpha Mask Blend"), - mSwizzleCB(nullptr) + mSwizzleCB(), + mResolveDepthStencilVS(g_VS_ResolveDepthStencil, + ArraySize(g_VS_ResolveDepthStencil), + "Blit11::mResolveDepthStencilVS"), + mResolveDepthPS(g_PS_ResolveDepth, ArraySize(g_PS_ResolveDepth), "Blit11::mResolveDepthPS"), + mResolveDepthStencilPS(g_PS_ResolveDepthStencil, + ArraySize(g_PS_ResolveDepthStencil), + "Blit11::mResolveDepthStencilPS"), + mResolveStencilPS(g_PS_ResolveStencil, + ArraySize(g_PS_ResolveStencil), + "Blit11::mResolveStencilPS"), + mStencilSRV(), + mResolvedDepthStencilRTView() { } Blit11::~Blit11() { - freeResources(); - - mQuad2DIL.release(); - mQuad2DVS.release(); - mDepthPS.release(); - - mQuad3DIL.release(); - mQuad3DVS.release(); - mQuad3DGS.release(); - - clearShaderMap(); } gl::Error Blit11::initResources() { if (mResourcesInitialized) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } TRACE_EVENT0("gpu.angle", "Blit11::initResources"); - HRESULT result; - ID3D11Device *device = mRenderer->getDevice(); - D3D11_BUFFER_DESC vbDesc; vbDesc.ByteWidth = static_cast(std::max(sizeof(d3d11::PositionLayerTexCoord3DVertex), sizeof(d3d11::PositionTexCoordVertex)) * - 6 * mRenderer->getRendererCaps().max3DTextureSize); - vbDesc.Usage = D3D11_USAGE_DYNAMIC; - vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - vbDesc.MiscFlags = 0; + 6 * mRenderer->getNativeCaps().max3DTextureSize); + vbDesc.Usage = D3D11_USAGE_DYNAMIC; + vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + vbDesc.MiscFlags = 0; vbDesc.StructureByteStride = 0; - result = device->CreateBuffer(&vbDesc, nullptr, &mVertexBuffer); - ASSERT(SUCCEEDED(result)); - if (FAILED(result)) - { - freeResources(); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create blit vertex buffer, HRESULT: 0x%X", - result); - } - d3d11::SetDebugName(mVertexBuffer, "Blit11 vertex buffer"); + ANGLE_TRY(mRenderer->allocateResource(vbDesc, &mVertexBuffer)); + mVertexBuffer.setDebugName("Blit11 vertex buffer"); D3D11_SAMPLER_DESC pointSamplerDesc; - pointSamplerDesc.Filter = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR; - pointSamplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; - pointSamplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; - pointSamplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; - pointSamplerDesc.MipLODBias = 0.0f; - pointSamplerDesc.MaxAnisotropy = 0; + pointSamplerDesc.Filter = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR; + pointSamplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; + pointSamplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; + pointSamplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + pointSamplerDesc.MipLODBias = 0.0f; + pointSamplerDesc.MaxAnisotropy = 0; pointSamplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; pointSamplerDesc.BorderColor[0] = 0.0f; pointSamplerDesc.BorderColor[1] = 0.0f; pointSamplerDesc.BorderColor[2] = 0.0f; pointSamplerDesc.BorderColor[3] = 0.0f; - pointSamplerDesc.MinLOD = 0.0f; - pointSamplerDesc.MaxLOD = FLT_MAX; + pointSamplerDesc.MinLOD = 0.0f; + pointSamplerDesc.MaxLOD = FLT_MAX; - result = device->CreateSamplerState(&pointSamplerDesc, &mPointSampler); - ASSERT(SUCCEEDED(result)); - if (FAILED(result)) - { - freeResources(); - return gl::Error(GL_OUT_OF_MEMORY, - "Failed to create blit point sampler state, HRESULT: 0x%X", result); - } - d3d11::SetDebugName(mPointSampler, "Blit11 point sampler"); + ANGLE_TRY(mRenderer->allocateResource(pointSamplerDesc, &mPointSampler)); + mPointSampler.setDebugName("Blit11 point sampler"); D3D11_SAMPLER_DESC linearSamplerDesc; - linearSamplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; - linearSamplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; - linearSamplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; - linearSamplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; - linearSamplerDesc.MipLODBias = 0.0f; - linearSamplerDesc.MaxAnisotropy = 0; + linearSamplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + linearSamplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; + linearSamplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; + linearSamplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + linearSamplerDesc.MipLODBias = 0.0f; + linearSamplerDesc.MaxAnisotropy = 0; linearSamplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; linearSamplerDesc.BorderColor[0] = 0.0f; linearSamplerDesc.BorderColor[1] = 0.0f; linearSamplerDesc.BorderColor[2] = 0.0f; linearSamplerDesc.BorderColor[3] = 0.0f; - linearSamplerDesc.MinLOD = 0.0f; - linearSamplerDesc.MaxLOD = FLT_MAX; + linearSamplerDesc.MinLOD = 0.0f; + linearSamplerDesc.MaxLOD = FLT_MAX; - result = device->CreateSamplerState(&linearSamplerDesc, &mLinearSampler); - ASSERT(SUCCEEDED(result)); - if (FAILED(result)) - { - freeResources(); - return gl::Error(GL_OUT_OF_MEMORY, - "Failed to create blit linear sampler state, HRESULT: 0x%X", result); - } - d3d11::SetDebugName(mLinearSampler, "Blit11 linear sampler"); + ANGLE_TRY(mRenderer->allocateResource(linearSamplerDesc, &mLinearSampler)); + mLinearSampler.setDebugName("Blit11 linear sampler"); // Use a rasterizer state that will not cull so that inverted quads will not be culled D3D11_RASTERIZER_DESC rasterDesc; - rasterDesc.FillMode = D3D11_FILL_SOLID; - rasterDesc.CullMode = D3D11_CULL_NONE; + rasterDesc.FillMode = D3D11_FILL_SOLID; + rasterDesc.CullMode = D3D11_CULL_NONE; rasterDesc.FrontCounterClockwise = FALSE; - rasterDesc.DepthBias = 0; - rasterDesc.SlopeScaledDepthBias = 0.0f; - rasterDesc.DepthBiasClamp = 0.0f; - rasterDesc.DepthClipEnable = TRUE; - rasterDesc.MultisampleEnable = FALSE; + rasterDesc.DepthBias = 0; + rasterDesc.SlopeScaledDepthBias = 0.0f; + rasterDesc.DepthBiasClamp = 0.0f; + rasterDesc.DepthClipEnable = TRUE; + rasterDesc.MultisampleEnable = FALSE; rasterDesc.AntialiasedLineEnable = FALSE; rasterDesc.ScissorEnable = TRUE; - result = device->CreateRasterizerState(&rasterDesc, &mScissorEnabledRasterizerState); - ASSERT(SUCCEEDED(result)); - if (FAILED(result)) - { - freeResources(); - return gl::Error(GL_OUT_OF_MEMORY, - "Failed to create blit scissoring rasterizer state, HRESULT: 0x%X", - result); - } - d3d11::SetDebugName(mScissorEnabledRasterizerState, "Blit11 scissoring rasterizer state"); + ANGLE_TRY(mRenderer->allocateResource(rasterDesc, &mScissorEnabledRasterizerState)); + mScissorEnabledRasterizerState.setDebugName("Blit11 scissoring rasterizer state"); rasterDesc.ScissorEnable = FALSE; - result = device->CreateRasterizerState(&rasterDesc, &mScissorDisabledRasterizerState); - ASSERT(SUCCEEDED(result)); - if (FAILED(result)) - { - freeResources(); - return gl::Error(GL_OUT_OF_MEMORY, - "Failed to create blit no scissoring rasterizer state, HRESULT: 0x%X", - result); - } - d3d11::SetDebugName(mScissorDisabledRasterizerState, "Blit11 no scissoring rasterizer state"); + ANGLE_TRY(mRenderer->allocateResource(rasterDesc, &mScissorDisabledRasterizerState)); + mScissorDisabledRasterizerState.setDebugName("Blit11 no scissoring rasterizer state"); D3D11_DEPTH_STENCIL_DESC depthStencilDesc; - depthStencilDesc.DepthEnable = true; - depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; - depthStencilDesc.DepthFunc = D3D11_COMPARISON_ALWAYS; - depthStencilDesc.StencilEnable = FALSE; - depthStencilDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; - depthStencilDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; - depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.DepthEnable = TRUE; + depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + depthStencilDesc.DepthFunc = D3D11_COMPARISON_ALWAYS; + depthStencilDesc.StencilEnable = FALSE; + depthStencilDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; + depthStencilDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; + depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; - depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; - depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; - depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; - depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; - depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - result = device->CreateDepthStencilState(&depthStencilDesc, &mDepthStencilState); - ASSERT(SUCCEEDED(result)); - if (FAILED(result)) - { - freeResources(); - return gl::Error(GL_OUT_OF_MEMORY, - "Failed to create blit depth stencil state, HRESULT: 0x%X", result); - } - d3d11::SetDebugName(mDepthStencilState, "Blit11 depth stencil state"); + ANGLE_TRY(mRenderer->allocateResource(depthStencilDesc, &mDepthStencilState)); + mDepthStencilState.setDebugName("Blit11 depth stencil state"); D3D11_BUFFER_DESC swizzleBufferDesc; - swizzleBufferDesc.ByteWidth = sizeof(unsigned int) * 4; - swizzleBufferDesc.Usage = D3D11_USAGE_DYNAMIC; - swizzleBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - swizzleBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - swizzleBufferDesc.MiscFlags = 0; + swizzleBufferDesc.ByteWidth = sizeof(unsigned int) * 4; + swizzleBufferDesc.Usage = D3D11_USAGE_DYNAMIC; + swizzleBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + swizzleBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + swizzleBufferDesc.MiscFlags = 0; swizzleBufferDesc.StructureByteStride = 0; - result = device->CreateBuffer(&swizzleBufferDesc, nullptr, &mSwizzleCB); - ASSERT(SUCCEEDED(result)); - if (FAILED(result)) - { - freeResources(); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create blit swizzle buffer, HRESULT: 0x%X", - result); - } - d3d11::SetDebugName(mSwizzleCB, "Blit11 swizzle constant buffer"); + ANGLE_TRY(mRenderer->allocateResource(swizzleBufferDesc, &mSwizzleCB)); + mSwizzleCB.setDebugName("Blit11 swizzle constant buffer"); mResourcesInitialized = true; - return gl::Error(GL_NO_ERROR); -} - -void Blit11::freeResources() -{ - SafeRelease(mVertexBuffer); - SafeRelease(mPointSampler); - SafeRelease(mLinearSampler); - SafeRelease(mScissorEnabledRasterizerState); - SafeRelease(mScissorDisabledRasterizerState); - SafeRelease(mDepthStencilState); - SafeRelease(mSwizzleCB); - - mResourcesInitialized = false; + return gl::NoError(); } // static -Blit11::BlitShaderType Blit11::GetBlitShaderType(GLenum destinationFormat, bool isSigned, ShaderDimension dimension) +Blit11::BlitShaderType Blit11::GetBlitShaderType(GLenum destinationFormat, + GLenum sourceFormat, + bool isSigned, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + ShaderDimension dimension) { if (dimension == SHADER_3D) { + ASSERT(!unpackPremultiplyAlpha && !unpackUnmultiplyAlpha); + if (isSigned) { switch (destinationFormat) { - case GL_RGBA_INTEGER: return BLITSHADER_3D_RGBAI; - case GL_RGB_INTEGER: return BLITSHADER_3D_RGBI; - case GL_RG_INTEGER: return BLITSHADER_3D_RGI; - case GL_RED_INTEGER: return BLITSHADER_3D_RI; - default: - UNREACHABLE(); - return BLITSHADER_INVALID; + case GL_RGBA_INTEGER: + return BLITSHADER_3D_RGBAI; + case GL_RGB_INTEGER: + return BLITSHADER_3D_RGBI; + case GL_RG_INTEGER: + return BLITSHADER_3D_RGI; + case GL_RED_INTEGER: + return BLITSHADER_3D_RI; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; } } else { switch (destinationFormat) { - case GL_RGBA: return BLITSHADER_3D_RGBAF; - case GL_RGBA_INTEGER: return BLITSHADER_3D_RGBAUI; - case GL_BGRA_EXT: return BLITSHADER_3D_BGRAF; - case GL_RGB: return BLITSHADER_3D_RGBF; - case GL_RGB_INTEGER: return BLITSHADER_3D_RGBUI; - case GL_RG: return BLITSHADER_3D_RGF; - case GL_RG_INTEGER: return BLITSHADER_3D_RGUI; - case GL_RED: return BLITSHADER_3D_RF; - case GL_RED_INTEGER: return BLITSHADER_3D_RUI; - case GL_ALPHA: return BLITSHADER_3D_ALPHA; - case GL_LUMINANCE: return BLITSHADER_3D_LUMA; - case GL_LUMINANCE_ALPHA: return BLITSHADER_3D_LUMAALPHA; - default: - UNREACHABLE(); - return BLITSHADER_INVALID; + case GL_RGBA: + return BLITSHADER_3D_RGBAF; + case GL_RGBA_INTEGER: + return BLITSHADER_3D_RGBAUI; + case GL_BGRA_EXT: + return BLITSHADER_3D_BGRAF; + case GL_RGB: + return BLITSHADER_3D_RGBF; + case GL_RGB_INTEGER: + return BLITSHADER_3D_RGBUI; + case GL_RG: + return BLITSHADER_3D_RGF; + case GL_RG_INTEGER: + return BLITSHADER_3D_RGUI; + case GL_RED: + return BLITSHADER_3D_RF; + case GL_RED_INTEGER: + return BLITSHADER_3D_RUI; + case GL_ALPHA: + return BLITSHADER_3D_ALPHA; + case GL_LUMINANCE: + return BLITSHADER_3D_LUMA; + case GL_LUMINANCE_ALPHA: + return BLITSHADER_3D_LUMAALPHA; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; } } } else if (isSigned) { + ASSERT(!unpackPremultiplyAlpha && !unpackUnmultiplyAlpha); + switch (destinationFormat) { - case GL_RGBA_INTEGER: return BLITSHADER_2D_RGBAI; - case GL_RGB_INTEGER: return BLITSHADER_2D_RGBI; - case GL_RG_INTEGER: return BLITSHADER_2D_RGI; - case GL_RED_INTEGER: return BLITSHADER_2D_RI; - default: - UNREACHABLE(); - return BLITSHADER_INVALID; + case GL_RGBA_INTEGER: + return BLITSHADER_2D_RGBAI; + case GL_RGB_INTEGER: + return BLITSHADER_2D_RGBI; + case GL_RG_INTEGER: + return BLITSHADER_2D_RGI; + case GL_RED_INTEGER: + return BLITSHADER_2D_RI; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; } } else { - switch (destinationFormat) + bool floatToIntBlit = + !gl::IsIntegerFormat(sourceFormat) && gl::IsIntegerFormat(destinationFormat); + if (unpackPremultiplyAlpha != unpackUnmultiplyAlpha || floatToIntBlit) { - case GL_RGBA: return BLITSHADER_2D_RGBAF; - case GL_RGBA_INTEGER: return BLITSHADER_2D_RGBAUI; - case GL_BGRA_EXT: return BLITSHADER_2D_BGRAF; - case GL_RGB: return BLITSHADER_2D_RGBF; - case GL_RGB_INTEGER: return BLITSHADER_2D_RGBUI; - case GL_RG: return BLITSHADER_2D_RGF; - case GL_RG_INTEGER: return BLITSHADER_2D_RGUI; - case GL_RED: return BLITSHADER_2D_RF; - case GL_RED_INTEGER: return BLITSHADER_2D_RUI; - case GL_ALPHA: return BLITSHADER_2D_ALPHA; - case GL_LUMINANCE: return BLITSHADER_2D_LUMA; - case GL_LUMINANCE_ALPHA: return BLITSHADER_2D_LUMAALPHA; - default: - UNREACHABLE(); - return BLITSHADER_INVALID; + switch (destinationFormat) + { + case GL_RGBA: + case GL_BGRA_EXT: + ASSERT(!floatToIntBlit); + return unpackPremultiplyAlpha ? BLITSHADER_2D_RGBAF_PREMULTIPLY + : BLITSHADER_2D_RGBAF_UNMULTIPLY; + + case GL_RGB: + case GL_RG: + case GL_RED: + ASSERT(!floatToIntBlit); + return unpackPremultiplyAlpha ? BLITSHADER_2D_RGBF_PREMULTIPLY + : BLITSHADER_2D_RGBF_UNMULTIPLY; + + case GL_RGBA_INTEGER: + if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha) + { + return BLITSHADER_2D_RGBAF_TOUI; + } + else + { + return unpackPremultiplyAlpha ? BLITSHADER_2D_RGBAF_TOUI_PREMULTIPLY + : BLITSHADER_2D_RGBAF_TOUI_UNMULTIPLY; + } + + case GL_RGB_INTEGER: + case GL_RG_INTEGER: + case GL_RED_INTEGER: + if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha) + { + return BLITSHADER_2D_RGBF_TOUI; + } + else + { + return unpackPremultiplyAlpha ? BLITSHADER_2D_RGBF_TOUI_PREMULTIPLY + : BLITSHADER_2D_RGBF_TOUI_UNMULTIPLY; + } + case GL_LUMINANCE: + ASSERT(!floatToIntBlit); + return unpackPremultiplyAlpha ? BLITSHADER_2D_LUMAF_PREMULTIPLY + : BLITSHADER_2D_LUMAF_UNMULTIPLY; + case GL_LUMINANCE_ALPHA: + ASSERT(!floatToIntBlit); + return unpackPremultiplyAlpha ? BLITSHADER_2D_LUMAALPHAF_PREMULTIPLY + : BLITSHADER_2D_LUMAALPHAF_UNMULTIPLY; + case GL_ALPHA: + ASSERT(!floatToIntBlit); + return BLITSHADER_2D_ALPHA; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } + } + else + { + switch (destinationFormat) + { + case GL_RGBA: + return BLITSHADER_2D_RGBAF; + case GL_RGBA_INTEGER: + return BLITSHADER_2D_RGBAUI; + case GL_BGRA_EXT: + return BLITSHADER_2D_BGRAF; + case GL_RGB: + return BLITSHADER_2D_RGBF; + case GL_RGB_INTEGER: + return BLITSHADER_2D_RGBUI; + case GL_RG: + return BLITSHADER_2D_RGF; + case GL_RG_INTEGER: + return BLITSHADER_2D_RGUI; + case GL_RED: + return BLITSHADER_2D_RF; + case GL_RED_INTEGER: + return BLITSHADER_2D_RUI; + case GL_ALPHA: + return BLITSHADER_2D_ALPHA; + case GL_LUMINANCE: + return BLITSHADER_2D_LUMA; + case GL_LUMINANCE_ALPHA: + return BLITSHADER_2D_LUMAALPHA; + default: + UNREACHABLE(); + return BLITSHADER_INVALID; + } } } } // static -Blit11::SwizzleShaderType Blit11::GetSwizzleShaderType(GLenum type, D3D11_SRV_DIMENSION dimensionality) +Blit11::SwizzleShaderType Blit11::GetSwizzleShaderType(GLenum type, + D3D11_SRV_DIMENSION dimensionality) { switch (dimensionality) { - case D3D11_SRV_DIMENSION_TEXTURE2D: - switch (type) - { - case GL_FLOAT: return SWIZZLESHADER_2D_FLOAT; - case GL_UNSIGNED_INT: return SWIZZLESHADER_2D_UINT; - case GL_INT: return SWIZZLESHADER_2D_INT; - default: + case D3D11_SRV_DIMENSION_TEXTURE2D: + switch (type) + { + case GL_FLOAT: + return SWIZZLESHADER_2D_FLOAT; + case GL_UNSIGNED_INT: + return SWIZZLESHADER_2D_UINT; + case GL_INT: + return SWIZZLESHADER_2D_INT; + default: + UNREACHABLE(); + return SWIZZLESHADER_INVALID; + } + case D3D11_SRV_DIMENSION_TEXTURECUBE: + switch (type) + { + case GL_FLOAT: + return SWIZZLESHADER_CUBE_FLOAT; + case GL_UNSIGNED_INT: + return SWIZZLESHADER_CUBE_UINT; + case GL_INT: + return SWIZZLESHADER_CUBE_INT; + default: + UNREACHABLE(); + return SWIZZLESHADER_INVALID; + } + case D3D11_SRV_DIMENSION_TEXTURE3D: + switch (type) + { + case GL_FLOAT: + return SWIZZLESHADER_3D_FLOAT; + case GL_UNSIGNED_INT: + return SWIZZLESHADER_3D_UINT; + case GL_INT: + return SWIZZLESHADER_3D_INT; + default: + UNREACHABLE(); + return SWIZZLESHADER_INVALID; + } + case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: + switch (type) + { + case GL_FLOAT: + return SWIZZLESHADER_ARRAY_FLOAT; + case GL_UNSIGNED_INT: + return SWIZZLESHADER_ARRAY_UINT; + case GL_INT: + return SWIZZLESHADER_ARRAY_INT; + default: + UNREACHABLE(); + return SWIZZLESHADER_INVALID; + } + default: UNREACHABLE(); return SWIZZLESHADER_INVALID; - } - case D3D11_SRV_DIMENSION_TEXTURECUBE: - switch (type) - { - case GL_FLOAT: return SWIZZLESHADER_CUBE_FLOAT; - case GL_UNSIGNED_INT: return SWIZZLESHADER_CUBE_UINT; - case GL_INT: return SWIZZLESHADER_CUBE_INT; - default: - UNREACHABLE(); - return SWIZZLESHADER_INVALID; - } - case D3D11_SRV_DIMENSION_TEXTURE3D: - switch (type) - { - case GL_FLOAT: return SWIZZLESHADER_3D_FLOAT; - case GL_UNSIGNED_INT: return SWIZZLESHADER_3D_UINT; - case GL_INT: return SWIZZLESHADER_3D_INT; - default: - UNREACHABLE(); - return SWIZZLESHADER_INVALID; - } - case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: - switch (type) - { - case GL_FLOAT: return SWIZZLESHADER_ARRAY_FLOAT; - case GL_UNSIGNED_INT: return SWIZZLESHADER_ARRAY_UINT; - case GL_INT: return SWIZZLESHADER_ARRAY_INT; - default: - UNREACHABLE(); - return SWIZZLESHADER_INVALID; - } - default: - UNREACHABLE(); - return SWIZZLESHADER_INVALID; } } -Blit11::ShaderSupport Blit11::getShaderSupport(const Shader &shader) +gl::Error Blit11::getShaderSupport(const Shader &shader, Blit11::ShaderSupport *supportOut) { - ID3D11Device *device = mRenderer->getDevice(); - ShaderSupport support; - if (shader.dimension == SHADER_2D) { - support.inputLayout = mQuad2DIL.resolve(device); - support.vertexShader = mQuad2DVS.resolve(device); - support.geometryShader = nullptr; - support.vertexWriteFunction = Write2DVertices; + ANGLE_TRY(mQuad2DIL.resolve(mRenderer)); + ANGLE_TRY(mQuad2DVS.resolve(mRenderer)); + supportOut->inputLayout = &mQuad2DIL.getObj(); + supportOut->vertexShader = &mQuad2DVS.getObj(); + supportOut->geometryShader = nullptr; + supportOut->vertexWriteFunction = Write2DVertices; } else { ASSERT(shader.dimension == SHADER_3D); - support.inputLayout = mQuad3DIL.resolve(device); - support.vertexShader = mQuad3DVS.resolve(device); - support.geometryShader = mQuad3DGS.resolve(device); - support.vertexWriteFunction = Write3DVertices; + ANGLE_TRY(mQuad3DIL.resolve(mRenderer)); + ANGLE_TRY(mQuad3DVS.resolve(mRenderer)); + ANGLE_TRY(mQuad3DGS.resolve(mRenderer)); + supportOut->inputLayout = &mQuad2DIL.getObj(); + supportOut->vertexShader = &mQuad3DVS.getObj(); + supportOut->geometryShader = &mQuad3DGS.getObj(); + supportOut->vertexWriteFunction = Write3DVertices; } - return support; + return gl::NoError(); } -gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, - ID3D11RenderTargetView *dest, +gl::Error Blit11::swizzleTexture(const gl::Context *context, + const d3d11::SharedSRV &source, + const d3d11::RenderTargetView &dest, const gl::Extents &size, - GLenum swizzleRed, - GLenum swizzleGreen, - GLenum swizzleBlue, - GLenum swizzleAlpha) + const gl::SwizzleState &swizzleTarget) { - gl::Error error = initResources(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(initResources()); HRESULT result; ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); D3D11_SHADER_RESOURCE_VIEW_DESC sourceSRVDesc; - source->GetDesc(&sourceSRVDesc); + source.get()->GetDesc(&sourceSRVDesc); - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(sourceSRVDesc.Format); - const gl::InternalFormat &sourceFormatInfo = gl::GetInternalFormatInfo(dxgiFormatInfo.internalFormat); + GLenum componentType = d3d11::GetComponentType(sourceSRVDesc.Format); + if (componentType == GL_NONE) + { + // We're swizzling the depth component of a depth-stencil texture. + switch (sourceSRVDesc.Format) + { + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + componentType = GL_UNSIGNED_NORMALIZED; + break; + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + componentType = GL_FLOAT; + break; + default: + UNREACHABLE(); + break; + } + } GLenum shaderType = GL_NONE; - switch (sourceFormatInfo.componentType) + switch (componentType) { - case GL_UNSIGNED_NORMALIZED: - case GL_SIGNED_NORMALIZED: - case GL_FLOAT: - shaderType = GL_FLOAT; - break; - case GL_INT: - shaderType = GL_INT; - break; - case GL_UNSIGNED_INT: - shaderType = GL_UNSIGNED_INT; - break; - default: - UNREACHABLE(); - break; + case GL_UNSIGNED_NORMALIZED: + case GL_SIGNED_NORMALIZED: + case GL_FLOAT: + shaderType = GL_FLOAT; + break; + case GL_INT: + shaderType = GL_INT; + break; + case GL_UNSIGNED_INT: + shaderType = GL_UNSIGNED_INT; + break; + default: + UNREACHABLE(); + break; } const Shader *shader = nullptr; - error = getSwizzleShader(shaderType, sourceSRVDesc.ViewDimension, &shader); - if (error.isError()) - { - return error; - } + ANGLE_TRY(getSwizzleShader(shaderType, sourceSRVDesc.ViewDimension, &shader)); // Set vertices D3D11_MAPPED_SUBRESOURCE mappedResource; - result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + result = + deviceContext->Map(mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer for swizzle, HRESULT: 0x%X.", result); + return gl::OutOfMemory() << "Failed to map internal vertex buffer for swizzle, " + << gl::FmtHR(result); } - const ShaderSupport &support = getShaderSupport(*shader); + ShaderSupport support; + ANGLE_TRY(getShaderSupport(*shader, &support)); - UINT stride = 0; - UINT startIdx = 0; + UINT stride = 0; UINT drawCount = 0; D3D11_PRIMITIVE_TOPOLOGY topology; gl::Box area(0, 0, 0, size.width, size.height, size.depth); - support.vertexWriteFunction(area, size, area, size, mappedResource.pData, &stride, &drawCount, &topology); + support.vertexWriteFunction(area, size, area, size, mappedResource.pData, &stride, &drawCount, + &topology); - deviceContext->Unmap(mVertexBuffer, 0); + deviceContext->Unmap(mVertexBuffer.get(), 0); // Set constant buffer - result = deviceContext->Map(mSwizzleCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + result = deviceContext->Map(mSwizzleCB.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal constant buffer for swizzle, HRESULT: 0x%X.", result); + return gl::OutOfMemory() << "Failed to map internal constant buffer for swizzle, " + << gl::FmtHR(result); } - unsigned int *swizzleIndices = reinterpret_cast(mappedResource.pData); - swizzleIndices[0] = GetSwizzleIndex(swizzleRed); - swizzleIndices[1] = GetSwizzleIndex(swizzleGreen); - swizzleIndices[2] = GetSwizzleIndex(swizzleBlue); - swizzleIndices[3] = GetSwizzleIndex(swizzleAlpha); + unsigned int *swizzleIndices = reinterpret_cast(mappedResource.pData); + swizzleIndices[0] = GetSwizzleIndex(swizzleTarget.swizzleRed); + swizzleIndices[1] = GetSwizzleIndex(swizzleTarget.swizzleGreen); + swizzleIndices[2] = GetSwizzleIndex(swizzleTarget.swizzleBlue); + swizzleIndices[3] = GetSwizzleIndex(swizzleTarget.swizzleAlpha); - deviceContext->Unmap(mSwizzleCB, 0); + deviceContext->Unmap(mSwizzleCB.get(), 0); + + StateManager11 *stateManager = mRenderer->getStateManager(); // Apply vertex buffer - deviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &stride, &startIdx); + stateManager->setSingleVertexBuffer(&mVertexBuffer, stride, 0); // Apply constant buffer - deviceContext->PSSetConstantBuffers(0, 1, &mSwizzleCB); + stateManager->setPixelConstantBuffer(0, &mSwizzleCB); // Apply state - deviceContext->OMSetBlendState(nullptr, nullptr, 0xFFFFFFF); - deviceContext->OMSetDepthStencilState(nullptr, 0xFFFFFFFF); - deviceContext->RSSetState(mScissorDisabledRasterizerState); + stateManager->setSimpleBlendState(nullptr); + stateManager->setDepthStencilState(nullptr, 0xFFFFFFFF); + stateManager->setRasterizerState(&mScissorDisabledRasterizerState); // Apply shaders - deviceContext->IASetInputLayout(support.inputLayout); - deviceContext->IASetPrimitiveTopology(topology); - deviceContext->VSSetShader(support.vertexShader, nullptr, 0); + stateManager->setInputLayout(support.inputLayout); + stateManager->setPrimitiveTopology(topology); - deviceContext->PSSetShader(shader->pixelShader, nullptr, 0); - deviceContext->GSSetShader(support.geometryShader, nullptr, 0); - - // Unset the currently bound shader resource to avoid conflicts - auto stateManager = mRenderer->getStateManager(); - stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr); + stateManager->setDrawShaders(support.vertexShader, support.geometryShader, + &shader->pixelShader); // Apply render target - mRenderer->setOneTimeRenderTarget(dest); + stateManager->setRenderTarget(dest.get(), nullptr); // Set the viewport - D3D11_VIEWPORT viewport; - viewport.TopLeftX = 0; - viewport.TopLeftY = 0; - viewport.Width = static_cast(size.width); - viewport.Height = static_cast(size.height); - viewport.MinDepth = 0.0f; - viewport.MaxDepth = 1.0f; - deviceContext->RSSetViewports(1, &viewport); + stateManager->setSimpleViewport(size); - // Apply textures - stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, source); - - // Apply samplers - deviceContext->PSSetSamplers(0, 1, &mPointSampler); + // Apply textures and sampler + stateManager->setSimplePixelTextureAndSampler(source, mPointSampler); // Draw the quad deviceContext->Draw(drawCount, 0); - // Unbind textures and render targets and vertex buffer - stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr); - - mRenderer->unapplyRenderTargets(); - - UINT zero = 0; - ID3D11Buffer *const nullBuffer = nullptr; - deviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero); - - mRenderer->markAllStateDirty(); - - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, +gl::Error Blit11::copyTexture(const gl::Context *context, + const d3d11::SharedSRV &source, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11RenderTargetView *dest, + GLenum sourceFormat, + const d3d11::RenderTargetView &dest, const gl::Box &destArea, const gl::Extents &destSize, const gl::Rectangle *scissor, GLenum destFormat, GLenum filter, - bool maskOffAlpha) + bool maskOffAlpha, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) { - gl::Error error = initResources(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(initResources()); HRESULT result; ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); @@ -771,635 +1145,1009 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, // Determine if the source format is a signed integer format, the destFormat will already // be GL_XXXX_INTEGER but it does not tell us if it is signed or unsigned. D3D11_SHADER_RESOURCE_VIEW_DESC sourceSRVDesc; - source->GetDesc(&sourceSRVDesc); + source.get()->GetDesc(&sourceSRVDesc); - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(sourceSRVDesc.Format); - const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(dxgiFormatInfo.internalFormat); + GLenum componentType = d3d11::GetComponentType(sourceSRVDesc.Format); - bool isSigned = (internalFormatInfo.componentType == GL_INT); - ShaderDimension dimension = (sourceSRVDesc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE3D) ? SHADER_3D : SHADER_2D; + ASSERT(componentType != GL_NONE); + ASSERT(componentType != GL_SIGNED_NORMALIZED); + bool isSigned = (componentType == GL_INT); + + ShaderDimension dimension = + (sourceSRVDesc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE3D) ? SHADER_3D : SHADER_2D; const Shader *shader = nullptr; - error = getBlitShader(destFormat, isSigned, dimension, &shader); - if (error.isError()) - { - return error; - } + ANGLE_TRY(getBlitShader(destFormat, sourceFormat, isSigned, unpackPremultiplyAlpha, + unpackUnmultiplyAlpha, dimension, &shader)); - const ShaderSupport &support = getShaderSupport(*shader); + ShaderSupport support; + ANGLE_TRY(getShaderSupport(*shader, &support)); // Set vertices D3D11_MAPPED_SUBRESOURCE mappedResource; - result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + result = + deviceContext->Map(mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer for texture copy, HRESULT: 0x%X.", result); + return gl::OutOfMemory() << "Failed to map internal vertex buffer for texture copy, " + << gl::FmtHR(result); } - UINT stride = 0; - UINT startIdx = 0; + UINT stride = 0; UINT drawCount = 0; D3D11_PRIMITIVE_TOPOLOGY topology; support.vertexWriteFunction(sourceArea, sourceSize, destArea, destSize, mappedResource.pData, &stride, &drawCount, &topology); - deviceContext->Unmap(mVertexBuffer, 0); + deviceContext->Unmap(mVertexBuffer.get(), 0); + + StateManager11 *stateManager = mRenderer->getStateManager(); // Apply vertex buffer - deviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &stride, &startIdx); + stateManager->setSingleVertexBuffer(&mVertexBuffer, stride, 0); // Apply state if (maskOffAlpha) { - ID3D11BlendState *blendState = mAlphaMaskBlendState.resolve(mRenderer->getDevice()); - ASSERT(blendState); - deviceContext->OMSetBlendState(blendState, nullptr, 0xFFFFFFF); + ANGLE_TRY(mAlphaMaskBlendState.resolve(mRenderer)); + stateManager->setSimpleBlendState(&mAlphaMaskBlendState.getObj()); } else { - deviceContext->OMSetBlendState(nullptr, nullptr, 0xFFFFFFF); + stateManager->setSimpleBlendState(nullptr); } - deviceContext->OMSetDepthStencilState(nullptr, 0xFFFFFFFF); + stateManager->setDepthStencilState(nullptr, 0xFFFFFFFF); if (scissor) { - D3D11_RECT scissorRect; - scissorRect.left = scissor->x; - scissorRect.right = scissor->x + scissor->width; - scissorRect.top = scissor->y; - scissorRect.bottom = scissor->y + scissor->height; - - deviceContext->RSSetScissorRects(1, &scissorRect); - deviceContext->RSSetState(mScissorEnabledRasterizerState); + stateManager->setSimpleScissorRect(*scissor); + stateManager->setRasterizerState(&mScissorEnabledRasterizerState); } else { - deviceContext->RSSetState(mScissorDisabledRasterizerState); + stateManager->setRasterizerState(&mScissorDisabledRasterizerState); } // Apply shaders - deviceContext->IASetInputLayout(support.inputLayout); - deviceContext->IASetPrimitiveTopology(topology); - deviceContext->VSSetShader(support.vertexShader, nullptr, 0); + stateManager->setInputLayout(support.inputLayout); + stateManager->setPrimitiveTopology(topology); - deviceContext->PSSetShader(shader->pixelShader, nullptr, 0); - deviceContext->GSSetShader(support.geometryShader, nullptr, 0); - - // Unset the currently bound shader resource to avoid conflicts - auto stateManager = mRenderer->getStateManager(); - stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr); + stateManager->setDrawShaders(support.vertexShader, support.geometryShader, + &shader->pixelShader); // Apply render target - mRenderer->setOneTimeRenderTarget(dest); + stateManager->setRenderTarget(dest.get(), nullptr); // Set the viewport - D3D11_VIEWPORT viewport; - viewport.TopLeftX = 0; - viewport.TopLeftY = 0; - viewport.Width = static_cast(destSize.width); - viewport.Height = static_cast(destSize.height); - viewport.MinDepth = 0.0f; - viewport.MaxDepth = 1.0f; - deviceContext->RSSetViewports(1, &viewport); + stateManager->setSimpleViewport(destSize); - // Apply textures - stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, source); - - // Apply samplers - ID3D11SamplerState *sampler = nullptr; + // Apply texture and sampler switch (filter) { - case GL_NEAREST: sampler = mPointSampler; break; - case GL_LINEAR: sampler = mLinearSampler; break; + case GL_NEAREST: + stateManager->setSimplePixelTextureAndSampler(source, mPointSampler); + break; + case GL_LINEAR: + stateManager->setSimplePixelTextureAndSampler(source, mLinearSampler); + break; - default: - UNREACHABLE(); - return gl::Error(GL_OUT_OF_MEMORY, "Internal error, unknown blit filter mode."); + default: + UNREACHABLE(); + return gl::InternalError() << "Internal error, unknown blit filter mode."; } - deviceContext->PSSetSamplers(0, 1, &sampler); // Draw the quad deviceContext->Draw(drawCount, 0); - // Unbind textures and render targets and vertex buffer - stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr); - - mRenderer->unapplyRenderTargets(); - - UINT zero = 0; - ID3D11Buffer *const nullBuffer = nullptr; - deviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero); - - mRenderer->markAllStateDirty(); - - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Blit11::copyStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, +gl::Error Blit11::copyStencil(const gl::Context *context, + const TextureHelper11 &source, + unsigned int sourceSubresource, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const TextureHelper11 &dest, + unsigned int destSubresource, + const gl::Box &destArea, + const gl::Extents &destSize, const gl::Rectangle *scissor) { - return copyDepthStencil(source, sourceSubresource, sourceArea, sourceSize, - dest, destSubresource, destArea, destSize, - scissor, true); + return copyDepthStencilImpl(source, sourceSubresource, sourceArea, sourceSize, dest, + destSubresource, destArea, destSize, scissor, true); } -gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11DepthStencilView *dest, const gl::Box &destArea, const gl::Extents &destSize, +gl::Error Blit11::copyDepth(const gl::Context *context, + const d3d11::SharedSRV &source, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const d3d11::DepthStencilView &dest, + const gl::Box &destArea, + const gl::Extents &destSize, const gl::Rectangle *scissor) { - gl::Error error = initResources(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(initResources()); HRESULT result; ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); // Set vertices D3D11_MAPPED_SUBRESOURCE mappedResource; - result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + result = + deviceContext->Map(mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer for texture copy, HRESULT: 0x%X.", result); + return gl::OutOfMemory() << "Failed to map internal vertex buffer for texture copy, " + << gl::FmtHR(result); } - UINT stride = 0; - UINT startIdx = 0; + UINT stride = 0; UINT drawCount = 0; D3D11_PRIMITIVE_TOPOLOGY topology; - Write2DVertices(sourceArea, sourceSize, destArea, destSize, mappedResource.pData, - &stride, &drawCount, &topology); + Write2DVertices(sourceArea, sourceSize, destArea, destSize, mappedResource.pData, &stride, + &drawCount, &topology); - deviceContext->Unmap(mVertexBuffer, 0); + deviceContext->Unmap(mVertexBuffer.get(), 0); + + StateManager11 *stateManager = mRenderer->getStateManager(); // Apply vertex buffer - deviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &stride, &startIdx); + stateManager->setSingleVertexBuffer(&mVertexBuffer, stride, 0); // Apply state - deviceContext->OMSetBlendState(nullptr, nullptr, 0xFFFFFFF); - deviceContext->OMSetDepthStencilState(mDepthStencilState, 0xFFFFFFFF); + stateManager->setSimpleBlendState(nullptr); + stateManager->setDepthStencilState(&mDepthStencilState, 0xFFFFFFFF); if (scissor) { - D3D11_RECT scissorRect; - scissorRect.left = scissor->x; - scissorRect.right = scissor->x + scissor->width; - scissorRect.top = scissor->y; - scissorRect.bottom = scissor->y + scissor->height; - - deviceContext->RSSetScissorRects(1, &scissorRect); - deviceContext->RSSetState(mScissorEnabledRasterizerState); + stateManager->setSimpleScissorRect(*scissor); + stateManager->setRasterizerState(&mScissorEnabledRasterizerState); } else { - deviceContext->RSSetState(mScissorDisabledRasterizerState); + stateManager->setRasterizerState(&mScissorDisabledRasterizerState); } - ID3D11Device *device = mRenderer->getDevice(); - ID3D11VertexShader *quad2DVS = mQuad2DVS.resolve(device); - if (quad2DVS == nullptr) - { - return gl::Error(GL_INVALID_OPERATION, "Error compiling internal 2D blit vertex shader"); - } + ANGLE_TRY(mQuad2DIL.resolve(mRenderer)); + ANGLE_TRY(mQuad2DVS.resolve(mRenderer)); + ANGLE_TRY(mDepthPS.resolve(mRenderer)); // Apply shaders - deviceContext->IASetInputLayout(mQuad2DIL.resolve(device)); - deviceContext->IASetPrimitiveTopology(topology); - deviceContext->VSSetShader(quad2DVS, nullptr, 0); + stateManager->setInputLayout(&mQuad2DIL.getObj()); + stateManager->setPrimitiveTopology(topology); - deviceContext->PSSetShader(mDepthPS.resolve(device), nullptr, 0); - deviceContext->GSSetShader(nullptr, nullptr, 0); - - // Unset the currently bound shader resource to avoid conflicts - auto stateManager = mRenderer->getStateManager(); - stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr); + stateManager->setDrawShaders(&mQuad2DVS.getObj(), nullptr, &mDepthPS.getObj()); // Apply render target - deviceContext->OMSetRenderTargets(0, nullptr, dest); + stateManager->setRenderTarget(nullptr, dest.get()); // Set the viewport - D3D11_VIEWPORT viewport; - viewport.TopLeftX = 0; - viewport.TopLeftY = 0; - viewport.Width = static_cast(destSize.width); - viewport.Height = static_cast(destSize.height); - viewport.MinDepth = 0.0f; - viewport.MaxDepth = 1.0f; - deviceContext->RSSetViewports(1, &viewport); + stateManager->setSimpleViewport(destSize); - // Apply textures - stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, source); - - // Apply samplers - deviceContext->PSSetSamplers(0, 1, &mPointSampler); + // Apply texture and sampler + stateManager->setSimplePixelTextureAndSampler(source, mPointSampler); // Draw the quad deviceContext->Draw(drawCount, 0); - // Unbind textures and render targets and vertex buffer - stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, nullptr); - - mRenderer->unapplyRenderTargets(); - - UINT zero = 0; - ID3D11Buffer *const nullBuffer = nullptr; - deviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero); - - mRenderer->markAllStateDirty(); - - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, +gl::Error Blit11::copyDepthStencil(const TextureHelper11 &source, + unsigned int sourceSubresource, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const TextureHelper11 &dest, + unsigned int destSubresource, + const gl::Box &destArea, + const gl::Extents &destSize, const gl::Rectangle *scissor) { - return copyDepthStencil(source, sourceSubresource, sourceArea, sourceSize, - dest, destSubresource, destArea, destSize, - scissor, false); + return copyDepthStencilImpl(source, sourceSubresource, sourceArea, sourceSize, dest, + destSubresource, destArea, destSize, scissor, false); } -gl::Error Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, - const gl::Rectangle *scissor, bool stencilOnly) +gl::Error Blit11::copyDepthStencilImpl(const TextureHelper11 &source, + unsigned int sourceSubresource, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const TextureHelper11 &dest, + unsigned int destSubresource, + const gl::Box &destArea, + const gl::Extents &destSize, + const gl::Rectangle *scissor, + bool stencilOnly) { - gl::Error error = initResources(); - if (error.isError()) - { - return error; - } + auto srcDXGIFormat = source.getFormat(); + const auto &srcSizeInfo = d3d11::GetDXGIFormatSizeInfo(srcDXGIFormat); + unsigned int srcPixelSize = srcSizeInfo.pixelBytes; + unsigned int copyOffset = 0; + unsigned int copySize = srcPixelSize; + auto destDXGIFormat = dest.getFormat(); + const auto &destSizeInfo = d3d11::GetDXGIFormatSizeInfo(destDXGIFormat); + unsigned int destPixelSize = destSizeInfo.pixelBytes; - ID3D11Device *device = mRenderer->getDevice(); - ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + ASSERT(srcDXGIFormat == destDXGIFormat || destDXGIFormat == DXGI_FORMAT_R32_TYPELESS); - ID3D11Resource *sourceStaging = CreateStagingTexture(device, deviceContext, source, sourceSubresource, sourceSize, D3D11_CPU_ACCESS_READ); - // HACK: Create the destination staging buffer as a read/write texture so ID3D11DevicContext::UpdateSubresource can be called - // using it's mapped data as a source - ID3D11Resource *destStaging = CreateStagingTexture(device, deviceContext, dest, destSubresource, destSize, D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE); - - if (!sourceStaging || !destStaging) - { - SafeRelease(sourceStaging); - SafeRelease(destStaging); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal staging textures for depth stencil blit."); - } - - DXGI_FORMAT format = GetTextureFormat(source); - ASSERT(format == GetTextureFormat(dest)); - - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(format); - unsigned int pixelSize = dxgiFormatInfo.pixelBytes; - unsigned int copyOffset = 0; - unsigned int copySize = pixelSize; if (stencilOnly) { - copyOffset = dxgiFormatInfo.depthBits / 8; - copySize = dxgiFormatInfo.stencilBits / 8; + const auto &srcFormat = source.getFormatSet().format(); - // It would be expensive to have non-byte sized stencil sizes since it would - // require reading from the destination, currently there aren't any though. - ASSERT(dxgiFormatInfo.stencilBits % 8 == 0 && - dxgiFormatInfo.depthBits % 8 == 0); + // Stencil channel should be right after the depth channel. Some views to depth/stencil + // resources have red channel for depth, in which case the depth channel bit width is in + // redBits. + ASSERT((srcFormat.redBits != 0) != (srcFormat.depthBits != 0)); + GLuint depthBits = srcFormat.redBits + srcFormat.depthBits; + // Known formats have either 24 or 32 bits of depth. + ASSERT(depthBits == 24 || depthBits == 32); + copyOffset = depthBits / 8; + + // Stencil is assumed to be 8-bit - currently this is true for all possible formats. + copySize = 1; } + if (srcDXGIFormat != destDXGIFormat) + { + if (srcDXGIFormat == DXGI_FORMAT_R24G8_TYPELESS) + { + ASSERT(sourceArea == destArea && sourceSize == destSize && scissor == nullptr); + return copyAndConvert(source, sourceSubresource, sourceArea, sourceSize, dest, + destSubresource, destArea, destSize, scissor, copyOffset, + copyOffset, copySize, srcPixelSize, destPixelSize, + BlitD24S8ToD32F); + } + ASSERT(srcDXGIFormat == DXGI_FORMAT_R32G8X24_TYPELESS); + return copyAndConvert(source, sourceSubresource, sourceArea, sourceSize, dest, + destSubresource, destArea, destSize, scissor, copyOffset, copyOffset, + copySize, srcPixelSize, destPixelSize, BlitD32FS8ToD32F); + } + + return copyAndConvert(source, sourceSubresource, sourceArea, sourceSize, dest, destSubresource, + destArea, destSize, scissor, copyOffset, copyOffset, copySize, + srcPixelSize, destPixelSize, StretchedBlitNearest); +} + +gl::Error Blit11::copyAndConvertImpl(const TextureHelper11 &source, + unsigned int sourceSubresource, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const TextureHelper11 &destStaging, + const gl::Box &destArea, + const gl::Extents &destSize, + const gl::Rectangle *scissor, + size_t readOffset, + size_t writeOffset, + size_t copySize, + size_t srcPixelStride, + size_t destPixelStride, + BlitConvertFunction *convertFunction) +{ + ANGLE_TRY(initResources()); + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + TextureHelper11 sourceStaging; + ANGLE_TRY_RESULT(mRenderer->createStagingTexture(ResourceType::Texture2D, source.getFormatSet(), + sourceSize, StagingAccess::READ), + sourceStaging); + + deviceContext->CopySubresourceRegion(sourceStaging.get(), 0, 0, 0, 0, source.get(), + sourceSubresource, nullptr); + D3D11_MAPPED_SUBRESOURCE sourceMapping; - HRESULT result = deviceContext->Map(sourceStaging, 0, D3D11_MAP_READ, 0, &sourceMapping); + HRESULT result = deviceContext->Map(sourceStaging.get(), 0, D3D11_MAP_READ, 0, &sourceMapping); if (FAILED(result)) { - SafeRelease(sourceStaging); - SafeRelease(destStaging); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal source staging texture for depth stencil blit, HRESULT: 0x%X.", result); + return gl::OutOfMemory() + << "Failed to map internal source staging texture for depth stencil blit, " + << gl::FmtHR(result); } D3D11_MAPPED_SUBRESOURCE destMapping; - result = deviceContext->Map(destStaging, 0, D3D11_MAP_WRITE, 0, &destMapping); + result = deviceContext->Map(destStaging.get(), 0, D3D11_MAP_WRITE, 0, &destMapping); if (FAILED(result)) { - deviceContext->Unmap(sourceStaging, 0); - SafeRelease(sourceStaging); - SafeRelease(destStaging); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal destination staging texture for depth stencil blit, HRESULT: 0x%X.", result); + deviceContext->Unmap(sourceStaging.get(), 0); + return gl::OutOfMemory() + << "Failed to map internal destination staging texture for depth stencil blit, " + << gl::FmtHR(result); } - gl::Rectangle clippedDestArea(destArea.x, destArea.y, destArea.width, destArea.height); - // Clip dest area to the destination size - gl::ClipRectangle(clippedDestArea, gl::Rectangle(0, 0, destSize.width, destSize.height), &clippedDestArea); + gl::Rectangle clipRect = gl::Rectangle(0, 0, destSize.width, destSize.height); // Clip dest area to the scissor if (scissor) { - gl::ClipRectangle(clippedDestArea, *scissor, &clippedDestArea); + gl::ClipRectangle(clipRect, *scissor, &clipRect); } - // Determine if entire rows can be copied at once instead of each individual pixel, requires that there is - // no out of bounds lookups required, the entire pixel is copied and no stretching - bool wholeRowCopy = sourceArea.width == clippedDestArea.width && - sourceArea.x >= 0 && sourceArea.x + sourceArea.width <= sourceSize.width && - copySize == pixelSize; + convertFunction(sourceArea, destArea, clipRect, sourceSize, sourceMapping.RowPitch, + destMapping.RowPitch, readOffset, writeOffset, copySize, srcPixelStride, + destPixelStride, static_cast(sourceMapping.pData), + static_cast(destMapping.pData)); - for (int y = clippedDestArea.y; y < clippedDestArea.y + clippedDestArea.height; y++) - { - float yPerc = static_cast(y - destArea.y) / (destArea.height - 1); + deviceContext->Unmap(sourceStaging.get(), 0); + deviceContext->Unmap(destStaging.get(), 0); - // Interpolate using the original source rectangle to determine which row to sample from while clamping to the edges - unsigned int readRow = static_cast(gl::clamp(sourceArea.y + floor(yPerc * (sourceArea.height - 1) + 0.5f), 0, sourceSize.height - 1)); - unsigned int writeRow = y; - - if (wholeRowCopy) - { - void *sourceRow = reinterpret_cast(sourceMapping.pData) + - readRow * sourceMapping.RowPitch + - sourceArea.x * pixelSize; - - void *destRow = reinterpret_cast(destMapping.pData) + - writeRow * destMapping.RowPitch + - destArea.x * pixelSize; - - memcpy(destRow, sourceRow, pixelSize * destArea.width); - } - else - { - for (int x = clippedDestArea.x; x < clippedDestArea.x + clippedDestArea.width; x++) - { - float xPerc = static_cast(x - destArea.x) / (destArea.width - 1); - - // Interpolate the original source rectangle to determine which column to sample from while clamping to the edges - unsigned int readColumn = static_cast(gl::clamp(sourceArea.x + floor(xPerc * (sourceArea.width - 1) + 0.5f), 0, sourceSize.width - 1)); - unsigned int writeColumn = x; - - void *sourcePixel = reinterpret_cast(sourceMapping.pData) + - readRow * sourceMapping.RowPitch + - readColumn * pixelSize + - copyOffset; - - void *destPixel = reinterpret_cast(destMapping.pData) + - writeRow * destMapping.RowPitch + - writeColumn * pixelSize + - copyOffset; - - memcpy(destPixel, sourcePixel, copySize); - } - } - } - - // HACK: Use ID3D11DevicContext::UpdateSubresource which causes an extra copy compared to ID3D11DevicContext::CopySubresourceRegion - // according to MSDN. - deviceContext->UpdateSubresource(dest, destSubresource, nullptr, destMapping.pData, destMapping.RowPitch, destMapping.DepthPitch); - - deviceContext->Unmap(sourceStaging, 0); - deviceContext->Unmap(destStaging, 0); - - // TODO: Determine why this call to ID3D11DevicContext::CopySubresourceRegion causes a TDR timeout on some - // systems when called repeatedly. - // deviceContext->CopySubresourceRegion(dest, destSubresource, 0, 0, 0, destStaging, 0, nullptr); - - SafeRelease(sourceStaging); - SafeRelease(destStaging); - - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -void Blit11::addBlitShaderToMap(BlitShaderType blitShaderType, ShaderDimension dimension, ID3D11PixelShader *ps) +gl::Error Blit11::copyAndConvert(const TextureHelper11 &source, + unsigned int sourceSubresource, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const TextureHelper11 &dest, + unsigned int destSubresource, + const gl::Box &destArea, + const gl::Extents &destSize, + const gl::Rectangle *scissor, + size_t readOffset, + size_t writeOffset, + size_t copySize, + size_t srcPixelStride, + size_t destPixelStride, + BlitConvertFunction *convertFunction) +{ + ANGLE_TRY(initResources()); + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + // HACK: Create the destination staging buffer as a read/write texture so + // ID3D11DevicContext::UpdateSubresource can be called + // using it's mapped data as a source + TextureHelper11 destStaging; + ANGLE_TRY_RESULT(mRenderer->createStagingTexture(ResourceType::Texture2D, dest.getFormatSet(), + destSize, StagingAccess::READ_WRITE), + destStaging); + + deviceContext->CopySubresourceRegion(destStaging.get(), 0, 0, 0, 0, dest.get(), destSubresource, + nullptr); + + ANGLE_TRY(copyAndConvertImpl(source, sourceSubresource, sourceArea, sourceSize, destStaging, + destArea, destSize, scissor, readOffset, writeOffset, copySize, + srcPixelStride, destPixelStride, convertFunction)); + + // Work around timeouts/TDRs in older NVIDIA drivers. + if (mRenderer->getWorkarounds().depthStencilBlitExtraCopy) + { + D3D11_MAPPED_SUBRESOURCE mapped; + deviceContext->Map(destStaging.get(), 0, D3D11_MAP_READ, 0, &mapped); + deviceContext->UpdateSubresource(dest.get(), destSubresource, nullptr, mapped.pData, + mapped.RowPitch, mapped.DepthPitch); + deviceContext->Unmap(destStaging.get(), 0); + } + else + { + deviceContext->CopySubresourceRegion(dest.get(), destSubresource, 0, 0, 0, + destStaging.get(), 0, nullptr); + } + + return gl::NoError(); +} + +gl::Error Blit11::addBlitShaderToMap(BlitShaderType blitShaderType, + ShaderDimension dimension, + const ShaderData &shaderData, + const char *name) { ASSERT(mBlitShaderMap.find(blitShaderType) == mBlitShaderMap.end()); - ASSERT(ps); + + d3d11::PixelShader ps; + ANGLE_TRY(mRenderer->allocateResource(shaderData, &ps)); + ps.setDebugName(name); Shader shader; - shader.dimension = dimension; - shader.pixelShader = ps; + shader.dimension = dimension; + shader.pixelShader = std::move(ps); - mBlitShaderMap[blitShaderType] = shader; + mBlitShaderMap[blitShaderType] = std::move(shader); + return gl::NoError(); } -void Blit11::addSwizzleShaderToMap(SwizzleShaderType swizzleShaderType, ShaderDimension dimension, ID3D11PixelShader *ps) +gl::Error Blit11::addSwizzleShaderToMap(SwizzleShaderType swizzleShaderType, + ShaderDimension dimension, + const ShaderData &shaderData, + const char *name) { ASSERT(mSwizzleShaderMap.find(swizzleShaderType) == mSwizzleShaderMap.end()); - ASSERT(ps); + + d3d11::PixelShader ps; + ANGLE_TRY(mRenderer->allocateResource(shaderData, &ps)); + ps.setDebugName(name); Shader shader; - shader.dimension = dimension; - shader.pixelShader = ps; + shader.dimension = dimension; + shader.pixelShader = std::move(ps); - mSwizzleShaderMap[swizzleShaderType] = shader; + mSwizzleShaderMap[swizzleShaderType] = std::move(shader); + return gl::NoError(); } void Blit11::clearShaderMap() { - for (auto &blitShader : mBlitShaderMap) - { - SafeRelease(blitShader.second.pixelShader); - } mBlitShaderMap.clear(); - - for (auto &swizzleShader : mSwizzleShaderMap) - { - SafeRelease(swizzleShader.second.pixelShader); - } mSwizzleShaderMap.clear(); } -gl::Error Blit11::getBlitShader(GLenum destFormat, bool isSigned, ShaderDimension dimension, const Shader **shader) +gl::Error Blit11::getBlitShader(GLenum destFormat, + GLenum sourceFormat, + bool isSigned, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + ShaderDimension dimension, + const Shader **shader) { - BlitShaderType blitShaderType = GetBlitShaderType(destFormat, isSigned, dimension); + BlitShaderType blitShaderType = + GetBlitShaderType(destFormat, sourceFormat, isSigned, unpackPremultiplyAlpha, + unpackUnmultiplyAlpha, dimension); if (blitShaderType == BLITSHADER_INVALID) { - return gl::Error(GL_INVALID_OPERATION, "Internal blit shader type mismatch"); + return gl::InternalError() << "Internal blit shader type mismatch"; } auto blitShaderIt = mBlitShaderMap.find(blitShaderType); if (blitShaderIt != mBlitShaderMap.end()) { *shader = &blitShaderIt->second; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } ASSERT(dimension == SHADER_2D || mRenderer->isES3Capable()); - ID3D11Device *device = mRenderer->getDevice(); - switch (blitShaderType) { - case BLITSHADER_2D_RGBAF: - addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D RGBA pixel shader")); - break; - case BLITSHADER_2D_BGRAF: - addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D BGRA pixel shader")); - break; - case BLITSHADER_2D_RGBF: - addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGB2D, "Blit11 2D RGB pixel shader")); - break; - case BLITSHADER_2D_RGF: - addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRG2D, "Blit11 2D RG pixel shader")); - break; - case BLITSHADER_2D_RF: - addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughR2D, "Blit11 2D R pixel shader")); - break; - case BLITSHADER_2D_ALPHA: - addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D alpha pixel shader")); - break; - case BLITSHADER_2D_LUMA: - addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughLum2D, "Blit11 2D lum pixel shader")); - break; - case BLITSHADER_2D_LUMAALPHA: - addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughLumAlpha2D, "Blit11 2D luminance alpha pixel shader")); - break; - case BLITSHADER_2D_RGBAUI: - addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGBA2DUI, "Blit11 2D RGBA UI pixel shader")); - break; - case BLITSHADER_2D_RGBAI: - addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGBA2DI, "Blit11 2D RGBA I pixel shader")); - break; - case BLITSHADER_2D_RGBUI: - addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGB2DUI, "Blit11 2D RGB UI pixel shader")); - break; - case BLITSHADER_2D_RGBI: - addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGB2DI, "Blit11 2D RGB I pixel shader")); - break; - case BLITSHADER_2D_RGUI: - addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRG2DUI, "Blit11 2D RG UI pixel shader")); - break; - case BLITSHADER_2D_RGI: - addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRG2DI, "Blit11 2D RG I pixel shader")); - break; - case BLITSHADER_2D_RUI: - addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughR2DUI, "Blit11 2D R UI pixel shader")); - break; - case BLITSHADER_2D_RI: - addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughR2DI, "Blit11 2D R I pixel shader")); - break; - case BLITSHADER_3D_RGBAF: - addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D RGBA pixel shader")); - break; - case BLITSHADER_3D_RGBAUI: - addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DUI, "Blit11 3D UI RGBA pixel shader")); - break; - case BLITSHADER_3D_RGBAI: - addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DI, "Blit11 3D I RGBA pixel shader")); - break; - case BLITSHADER_3D_BGRAF: - addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D BGRA pixel shader")); - break; - case BLITSHADER_3D_RGBF: - addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGB3D, "Blit11 3D RGB pixel shader")); - break; - case BLITSHADER_3D_RGBUI: - addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGB3DUI, "Blit11 3D RGB UI pixel shader")); - break; - case BLITSHADER_3D_RGBI: - addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGB3DI, "Blit11 3D RGB I pixel shader")); - break; - case BLITSHADER_3D_RGF: - addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRG3D, "Blit11 3D RG pixel shader")); - break; - case BLITSHADER_3D_RGUI: - addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRG3DUI, "Blit11 3D RG UI pixel shader")); - break; - case BLITSHADER_3D_RGI: - addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRG3DI, "Blit11 3D RG I pixel shader")); - break; - case BLITSHADER_3D_RF: - addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughR3D, "Blit11 3D R pixel shader")); - break; - case BLITSHADER_3D_RUI: - addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughR3DUI, "Blit11 3D R UI pixel shader")); - break; - case BLITSHADER_3D_RI: - addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughR3DI, "Blit11 3D R I pixel shader")); - break; - case BLITSHADER_3D_ALPHA: - addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D alpha pixel shader")); - break; - case BLITSHADER_3D_LUMA: - addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughLum3D, "Blit11 3D luminance pixel shader")); - break; - case BLITSHADER_3D_LUMAALPHA: - addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughLumAlpha3D, "Blit11 3D luminance alpha pixel shader")); - break; - default: - UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION, "Internal error"); + case BLITSHADER_2D_RGBAF: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughRGBA2D), + "Blit11 2D RGBA pixel shader")); + break; + case BLITSHADER_2D_BGRAF: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughRGBA2D), + "Blit11 2D BGRA pixel shader")); + break; + case BLITSHADER_2D_RGBF: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughRGB2D), + "Blit11 2D RGB pixel shader")); + break; + case BLITSHADER_2D_RGF: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughRG2D), + "Blit11 2D RG pixel shader")); + break; + case BLITSHADER_2D_RF: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_PassthroughR2D), + "Blit11 2D R pixel shader")); + break; + case BLITSHADER_2D_ALPHA: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_PassthroughA2D), + "Blit11 2D alpha pixel shader")); + break; + case BLITSHADER_2D_LUMA: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughLum2D), + "Blit11 2D lum pixel shader")); + break; + case BLITSHADER_2D_LUMAALPHA: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughLumAlpha2D), + "Blit11 2D luminance alpha pixel shader")); + break; + case BLITSHADER_2D_RGBAUI: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughRGBA2DUI), + "Blit11 2D RGBA UI pixel shader")); + break; + case BLITSHADER_2D_RGBAI: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughRGBA2DI), + "Blit11 2D RGBA I pixel shader")); + break; + case BLITSHADER_2D_RGBUI: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughRGB2DUI), + "Blit11 2D RGB UI pixel shader")); + break; + case BLITSHADER_2D_RGBI: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughRGB2DI), + "Blit11 2D RGB I pixel shader")); + break; + case BLITSHADER_2D_RGUI: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughRG2DUI), + "Blit11 2D RG UI pixel shader")); + break; + case BLITSHADER_2D_RGI: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughRG2DI), + "Blit11 2D RG I pixel shader")); + break; + case BLITSHADER_2D_RUI: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughR2DUI), + "Blit11 2D R UI pixel shader")); + break; + case BLITSHADER_2D_RI: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, + ShaderData(g_PS_PassthroughR2DI), + "Blit11 2D R I pixel shader")); + break; + case BLITSHADER_3D_RGBAF: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughRGBA3D), + "Blit11 3D RGBA pixel shader")); + break; + case BLITSHADER_3D_RGBAUI: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughRGBA3DUI), + "Blit11 3D UI RGBA pixel shader")); + break; + case BLITSHADER_3D_RGBAI: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughRGBA3DI), + "Blit11 3D I RGBA pixel shader")); + break; + case BLITSHADER_3D_BGRAF: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughRGBA3D), + "Blit11 3D BGRA pixel shader")); + break; + case BLITSHADER_3D_RGBF: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughRGB3D), + "Blit11 3D RGB pixel shader")); + break; + case BLITSHADER_3D_RGBUI: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughRGB3DUI), + "Blit11 3D RGB UI pixel shader")); + break; + case BLITSHADER_3D_RGBI: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughRGB3DI), + "Blit11 3D RGB I pixel shader")); + break; + case BLITSHADER_3D_RGF: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughRG3D), + "Blit11 3D RG pixel shader")); + break; + case BLITSHADER_3D_RGUI: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughRG3DUI), + "Blit11 3D RG UI pixel shader")); + break; + case BLITSHADER_3D_RGI: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughRG3DI), + "Blit11 3D RG I pixel shader")); + break; + case BLITSHADER_3D_RF: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D, ShaderData(g_PS_PassthroughR3D), + "Blit11 3D R pixel shader")); + break; + case BLITSHADER_3D_RUI: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughR3DUI), + "Blit11 3D R UI pixel shader")); + break; + case BLITSHADER_3D_RI: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughR3DI), + "Blit11 3D R I pixel shader")); + break; + case BLITSHADER_3D_ALPHA: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughRGBA3D), + "Blit11 3D alpha pixel shader")); + break; + case BLITSHADER_3D_LUMA: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughLum3D), + "Blit11 3D luminance pixel shader")); + break; + case BLITSHADER_3D_LUMAALPHA: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_3D, + ShaderData(g_PS_PassthroughLumAlpha3D), + "Blit11 3D luminance alpha pixel shader")); + break; + + case BLITSHADER_2D_RGBAF_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_FtoF_PM_RGBA), + "Blit11 2D RGBA premultiply pixel shader")); + break; + + case BLITSHADER_2D_RGBAF_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_FtoF_UM_RGBA), + "Blit11 2D RGBA unmultiply pixel shader")); + break; + + case BLITSHADER_2D_RGBF_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_FtoF_PM_RGB), + "Blit11 2D RGB premultiply pixel shader")); + break; + + case BLITSHADER_2D_RGBF_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_FtoF_UM_RGB), + "Blit11 2D RGB unmultiply pixel shader")); + break; + + case BLITSHADER_2D_RGBAF_TOUI: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_FtoU_PT_RGBA), + "Blit11 2D RGBA to uint pixel shader")); + break; + + case BLITSHADER_2D_RGBAF_TOUI_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_FtoU_PM_RGBA), + "Blit11 2D RGBA to uint premultiply pixel shader")); + break; + + case BLITSHADER_2D_RGBAF_TOUI_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_FtoU_UM_RGBA), + "Blit11 2D RGBA to uint unmultiply pixel shader")); + break; + + case BLITSHADER_2D_RGBF_TOUI: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_FtoU_PT_RGB), + "Blit11 2D RGB to uint pixel shader")); + break; + + case BLITSHADER_2D_RGBF_TOUI_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_FtoU_PM_RGB), + "Blit11 2D RGB to uint premultiply pixel shader")); + break; + + case BLITSHADER_2D_RGBF_TOUI_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_FtoU_UM_RGB), + "Blit11 2D RGB to uint unmultiply pixel shader")); + break; + case BLITSHADER_2D_LUMAF_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_FtoF_PM_LUMA), + "Blit11 2D LUMA premultiply pixel shader")); + break; + case BLITSHADER_2D_LUMAF_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, ShaderData(g_PS_FtoF_UM_LUMA), + "Blit11 2D LUMA unmultiply pixel shader")); + break; + case BLITSHADER_2D_LUMAALPHAF_PREMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, + ShaderData(g_PS_FtoF_PM_LUMAALPHA), + "Blit11 2D LUMAALPHA premultiply pixel shader")); + break; + case BLITSHADER_2D_LUMAALPHAF_UNMULTIPLY: + ANGLE_TRY(addBlitShaderToMap(blitShaderType, SHADER_2D, + ShaderData(g_PS_FtoF_UM_LUMAALPHA), + "Blit11 2D LUMAALPHA unmultiply pixel shader")); + break; + + default: + UNREACHABLE(); + return gl::InternalError() << "Internal error"; } blitShaderIt = mBlitShaderMap.find(blitShaderType); ASSERT(blitShaderIt != mBlitShaderMap.end()); *shader = &blitShaderIt->second; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Blit11::getSwizzleShader(GLenum type, D3D11_SRV_DIMENSION viewDimension, const Shader **shader) +gl::Error Blit11::getSwizzleShader(GLenum type, + D3D11_SRV_DIMENSION viewDimension, + const Shader **shader) { SwizzleShaderType swizzleShaderType = GetSwizzleShaderType(type, viewDimension); if (swizzleShaderType == SWIZZLESHADER_INVALID) { - return gl::Error(GL_INVALID_OPERATION, "Swizzle shader type not found"); + return gl::InternalError() << "Swizzle shader type not found"; } auto swizzleShaderIt = mSwizzleShaderMap.find(swizzleShaderType); if (swizzleShaderIt != mSwizzleShaderMap.end()) { *shader = &swizzleShaderIt->second; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } // Swizzling shaders (OpenGL ES 3+) ASSERT(mRenderer->isES3Capable()); - ID3D11Device *device = mRenderer->getDevice(); - switch (swizzleShaderType) { - case SWIZZLESHADER_2D_FLOAT: - addSwizzleShaderToMap(swizzleShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_SwizzleF2D, "Blit11 2D F swizzle pixel shader")); - break; - case SWIZZLESHADER_2D_UINT: - addSwizzleShaderToMap(swizzleShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_SwizzleUI2D, "Blit11 2D UI swizzle pixel shader")); - break; - case SWIZZLESHADER_2D_INT: - addSwizzleShaderToMap(swizzleShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_SwizzleI2D, "Blit11 2D I swizzle pixel shader")); - break; - case SWIZZLESHADER_CUBE_FLOAT: - addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleF2DArray, "Blit11 2D Cube F swizzle pixel shader")); - break; - case SWIZZLESHADER_CUBE_UINT: - addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleUI2DArray, "Blit11 2D Cube UI swizzle pixel shader")); - break; - case SWIZZLESHADER_CUBE_INT: - addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleI2DArray, "Blit11 2D Cube I swizzle pixel shader")); - break; - case SWIZZLESHADER_3D_FLOAT: - addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleF3D, "Blit11 3D F swizzle pixel shader")); - break; - case SWIZZLESHADER_3D_UINT: - addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleUI3D, "Blit11 3D UI swizzle pixel shader")); - break; - case SWIZZLESHADER_3D_INT: - addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleI3D, "Blit11 3D I swizzle pixel shader")); - break; - case SWIZZLESHADER_ARRAY_FLOAT: - addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleF2DArray, "Blit11 2D Array F swizzle pixel shader")); - break; - case SWIZZLESHADER_ARRAY_UINT: - addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleUI2DArray, "Blit11 2D Array UI swizzle pixel shader")); - break; - case SWIZZLESHADER_ARRAY_INT: - addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleI2DArray, "Blit11 2D Array I swizzle pixel shader")); - break; - default: - UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION, "Internal error"); + case SWIZZLESHADER_2D_FLOAT: + ANGLE_TRY(addSwizzleShaderToMap(swizzleShaderType, SHADER_2D, + ShaderData(g_PS_SwizzleF2D), + "Blit11 2D F swizzle pixel shader")); + break; + case SWIZZLESHADER_2D_UINT: + ANGLE_TRY(addSwizzleShaderToMap(swizzleShaderType, SHADER_2D, + ShaderData(g_PS_SwizzleUI2D), + "Blit11 2D UI swizzle pixel shader")); + break; + case SWIZZLESHADER_2D_INT: + ANGLE_TRY(addSwizzleShaderToMap(swizzleShaderType, SHADER_2D, + ShaderData(g_PS_SwizzleI2D), + "Blit11 2D I swizzle pixel shader")); + break; + case SWIZZLESHADER_CUBE_FLOAT: + ANGLE_TRY(addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, + ShaderData(g_PS_SwizzleF2DArray), + "Blit11 2D Cube F swizzle pixel shader")); + break; + case SWIZZLESHADER_CUBE_UINT: + ANGLE_TRY(addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, + ShaderData(g_PS_SwizzleUI2DArray), + "Blit11 2D Cube UI swizzle pixel shader")); + break; + case SWIZZLESHADER_CUBE_INT: + ANGLE_TRY(addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, + ShaderData(g_PS_SwizzleI2DArray), + "Blit11 2D Cube I swizzle pixel shader")); + break; + case SWIZZLESHADER_3D_FLOAT: + ANGLE_TRY(addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, + ShaderData(g_PS_SwizzleF3D), + "Blit11 3D F swizzle pixel shader")); + break; + case SWIZZLESHADER_3D_UINT: + ANGLE_TRY(addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, + ShaderData(g_PS_SwizzleUI3D), + "Blit11 3D UI swizzle pixel shader")); + break; + case SWIZZLESHADER_3D_INT: + ANGLE_TRY(addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, + ShaderData(g_PS_SwizzleI3D), + "Blit11 3D I swizzle pixel shader")); + break; + case SWIZZLESHADER_ARRAY_FLOAT: + ANGLE_TRY(addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, + ShaderData(g_PS_SwizzleF2DArray), + "Blit11 2D Array F swizzle pixel shader")); + break; + case SWIZZLESHADER_ARRAY_UINT: + ANGLE_TRY(addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, + ShaderData(g_PS_SwizzleUI2DArray), + "Blit11 2D Array UI swizzle pixel shader")); + break; + case SWIZZLESHADER_ARRAY_INT: + ANGLE_TRY(addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, + ShaderData(g_PS_SwizzleI2DArray), + "Blit11 2D Array I swizzle pixel shader")); + break; + default: + UNREACHABLE(); + return gl::InternalError() << "Internal error"; } swizzleShaderIt = mSwizzleShaderMap.find(swizzleShaderType); ASSERT(swizzleShaderIt != mSwizzleShaderMap.end()); *shader = &swizzleShaderIt->second; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } +gl::ErrorOrResult Blit11::resolveDepth(const gl::Context *context, + RenderTarget11 *depth) +{ + ANGLE_TRY(initResources()); + + // Multisampled depth stencil SRVs are not available in feature level 10.0 + ASSERT(mRenderer->getRenderer11DeviceCaps().featureLevel > D3D_FEATURE_LEVEL_10_0); + + const auto &extents = depth->getExtents(); + auto *deviceContext = mRenderer->getDeviceContext(); + auto *stateManager = mRenderer->getStateManager(); + + ANGLE_TRY(initResolveDepthOnly(depth->getFormatSet(), extents)); + + ANGLE_TRY(mResolveDepthStencilVS.resolve(mRenderer)); + ANGLE_TRY(mResolveDepthPS.resolve(mRenderer)); + + // Apply the necessary state changes to the D3D11 immediate device context. + stateManager->setInputLayout(nullptr); + stateManager->setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + stateManager->setDrawShaders(&mResolveDepthStencilVS.getObj(), nullptr, + &mResolveDepthPS.getObj()); + stateManager->setRasterizerState(nullptr); + stateManager->setDepthStencilState(&mDepthStencilState, 0xFFFFFFFF); + stateManager->setRenderTargets(nullptr, 0, mResolvedDepthDSView.get()); + stateManager->setSimpleBlendState(nullptr); + stateManager->setSimpleViewport(extents); + + // Set the viewport + stateManager->setShaderResourceShared(gl::SAMPLER_PIXEL, 0, &depth->getShaderResourceView()); + + // Trigger the blit on the GPU. + deviceContext->Draw(6, 0); + + return mResolvedDepth; } + +gl::Error Blit11::initResolveDepthOnly(const d3d11::Format &format, const gl::Extents &extents) +{ + if (mResolvedDepth.valid() && extents == mResolvedDepth.getExtents() && + format.texFormat == mResolvedDepth.getFormat()) + { + return gl::NoError(); + } + + D3D11_TEXTURE2D_DESC textureDesc; + textureDesc.Width = extents.width; + textureDesc.Height = extents.height; + textureDesc.MipLevels = 1; + textureDesc.ArraySize = 1; + textureDesc.Format = format.texFormat; + textureDesc.SampleDesc.Count = 1; + textureDesc.SampleDesc.Quality = 0; + textureDesc.Usage = D3D11_USAGE_DEFAULT; + textureDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE; + textureDesc.CPUAccessFlags = 0; + textureDesc.MiscFlags = 0; + + ANGLE_TRY(mRenderer->allocateTexture(textureDesc, format, &mResolvedDepth)); + mResolvedDepth.setDebugName("Blit11::mResolvedDepth"); + + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Flags = 0; + dsvDesc.Format = format.dsvFormat; + dsvDesc.Texture2D.MipSlice = 0; + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + + ANGLE_TRY(mRenderer->allocateResource(dsvDesc, mResolvedDepth.get(), &mResolvedDepthDSView)); + mResolvedDepthDSView.setDebugName("Blit11::mResolvedDepthDSView"); + + // Possibly D3D11 bug or undefined behaviour: Clear the DSV so that our first render + // works as expected. Otherwise the results of the first use seem to be incorrect. + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + context->ClearDepthStencilView(mResolvedDepthDSView.get(), D3D11_CLEAR_DEPTH, 1.0f, 0); + + return gl::NoError(); +} + +gl::Error Blit11::initResolveDepthStencil(const gl::Extents &extents) +{ + // Check if we need to recreate depth stencil view + if (mResolvedDepthStencil.valid() && extents == mResolvedDepthStencil.getExtents()) + { + ASSERT(mResolvedDepthStencil.getFormat() == DXGI_FORMAT_R32G32_FLOAT); + return gl::NoError(); + } + + if (mResolvedDepthStencil.valid()) + { + releaseResolveDepthStencilResources(); + } + + const auto &formatSet = d3d11::Format::Get(GL_RG32F, mRenderer->getRenderer11DeviceCaps()); + + D3D11_TEXTURE2D_DESC textureDesc; + textureDesc.Width = extents.width; + textureDesc.Height = extents.height; + textureDesc.MipLevels = 1; + textureDesc.ArraySize = 1; + textureDesc.Format = formatSet.texFormat; + textureDesc.SampleDesc.Count = 1; + textureDesc.SampleDesc.Quality = 0; + textureDesc.Usage = D3D11_USAGE_DEFAULT; + textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET; + textureDesc.CPUAccessFlags = 0; + textureDesc.MiscFlags = 0; + + ANGLE_TRY(mRenderer->allocateTexture(textureDesc, formatSet, &mResolvedDepthStencil)); + mResolvedDepthStencil.setDebugName("Blit11::mResolvedDepthStencil"); + + ANGLE_TRY(mRenderer->allocateResourceNoDesc(mResolvedDepthStencil.get(), + &mResolvedDepthStencilRTView)); + mResolvedDepthStencilRTView.setDebugName("Blit11::mResolvedDepthStencilRTView"); + + return gl::NoError(); +} + +gl::ErrorOrResult Blit11::resolveStencil(const gl::Context *context, + RenderTarget11 *depthStencil, + bool alsoDepth) +{ + ANGLE_TRY(initResources()); + + // Multisampled depth stencil SRVs are not available in feature level 10.0 + ASSERT(mRenderer->getRenderer11DeviceCaps().featureLevel > D3D_FEATURE_LEVEL_10_0); + + const auto &extents = depthStencil->getExtents(); + + ANGLE_TRY(initResolveDepthStencil(extents)); + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + auto *stateManager = mRenderer->getStateManager(); + ID3D11Resource *stencilResource = depthStencil->getTexture().get(); + + // Check if we need to re-create the stencil SRV. + if (mStencilSRV.valid()) + { + ID3D11Resource *priorResource = nullptr; + mStencilSRV.get()->GetResource(&priorResource); + + if (stencilResource != priorResource) + { + mStencilSRV.reset(); + } + + SafeRelease(priorResource); + } + + if (!mStencilSRV.valid()) + { + D3D11_SHADER_RESOURCE_VIEW_DESC srViewDesc; + srViewDesc.Format = GetStencilSRVFormat(depthStencil->getFormatSet()); + srViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; + + ANGLE_TRY(mRenderer->allocateResource(srViewDesc, stencilResource, &mStencilSRV)); + mStencilSRV.setDebugName("Blit11::mStencilSRV"); + } + + // Notify the Renderer that all state should be invalidated. + ANGLE_TRY(mResolveDepthStencilVS.resolve(mRenderer)); + + // Resolving the depth buffer works by sampling the depth in the shader using a SRV, then + // writing to the resolved depth buffer using SV_Depth. We can't use this method for stencil + // because SV_StencilRef isn't supported until HLSL 5.1/D3D11.3. + const d3d11::PixelShader *pixelShader = nullptr; + if (alsoDepth) + { + ANGLE_TRY(mResolveDepthStencilPS.resolve(mRenderer)); + pixelShader = &mResolveDepthStencilPS.getObj(); + } + else + { + ANGLE_TRY(mResolveStencilPS.resolve(mRenderer)); + pixelShader = &mResolveStencilPS.getObj(); + } + + // Apply the necessary state changes to the D3D11 immediate device context. + stateManager->setInputLayout(nullptr); + stateManager->setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + stateManager->setDrawShaders(&mResolveDepthStencilVS.getObj(), nullptr, pixelShader); + stateManager->setRasterizerState(nullptr); + stateManager->setDepthStencilState(nullptr, 0xFFFFFFFF); + stateManager->setRenderTarget(mResolvedDepthStencilRTView.get(), nullptr); + stateManager->setSimpleBlendState(nullptr); + + // Set the viewport + stateManager->setSimpleViewport(extents); + stateManager->setShaderResourceShared(gl::SAMPLER_PIXEL, 0, + &depthStencil->getShaderResourceView()); + stateManager->setShaderResource(gl::SAMPLER_PIXEL, 1, &mStencilSRV); + + // Trigger the blit on the GPU. + deviceContext->Draw(6, 0); + + gl::Box copyBox(0, 0, 0, extents.width, extents.height, 1); + + TextureHelper11 dest; + ANGLE_TRY_RESULT( + mRenderer->createStagingTexture(ResourceType::Texture2D, depthStencil->getFormatSet(), + extents, StagingAccess::READ_WRITE), + dest); + + const auto ©Function = GetCopyDepthStencilFunction(depthStencil->getInternalFormat()); + const auto &dsFormatSet = depthStencil->getFormatSet(); + const auto &dsDxgiInfo = d3d11::GetDXGIFormatSizeInfo(dsFormatSet.texFormat); + + ANGLE_TRY(copyAndConvertImpl(mResolvedDepthStencil, 0, copyBox, extents, dest, copyBox, extents, + nullptr, 0, 0, 0, 8u, dsDxgiInfo.pixelBytes, copyFunction)); + + // Return the resolved depth texture, which the caller must Release. + return dest; +} + +void Blit11::releaseResolveDepthStencilResources() +{ + mStencilSRV.reset(); + mResolvedDepthStencilRTView.reset(); +} + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.h index 906616131e..14078f9db8 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Blit11.h @@ -10,8 +10,9 @@ #define LIBANGLE_RENDERER_D3D_D3D11_BLIT11_H_ #include "common/angleutils.h" -#include "libANGLE/angletypes.h" #include "libANGLE/Error.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h" #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #include @@ -26,36 +27,84 @@ class Blit11 : angle::NonCopyable explicit Blit11(Renderer11 *renderer); ~Blit11(); - gl::Error swizzleTexture(ID3D11ShaderResourceView *source, ID3D11RenderTargetView *dest, const gl::Extents &size, - GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha); + gl::Error swizzleTexture(const gl::Context *context, + const d3d11::SharedSRV &source, + const d3d11::RenderTargetView &dest, + const gl::Extents &size, + const gl::SwizzleState &swizzleTarget); - gl::Error copyTexture(ID3D11ShaderResourceView *source, + gl::Error copyTexture(const gl::Context *context, + const d3d11::SharedSRV &source, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11RenderTargetView *dest, + GLenum sourceFormat, + const d3d11::RenderTargetView &dest, const gl::Box &destArea, const gl::Extents &destSize, const gl::Rectangle *scissor, GLenum destFormat, GLenum filter, - bool maskOffAlpha); + bool maskOffAlpha, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha); - gl::Error copyStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, + gl::Error copyStencil(const gl::Context *context, + const TextureHelper11 &source, + unsigned int sourceSubresource, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const TextureHelper11 &dest, + unsigned int destSubresource, + const gl::Box &destArea, + const gl::Extents &destSize, const gl::Rectangle *scissor); - gl::Error copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11DepthStencilView *dest, const gl::Box &destArea, const gl::Extents &destSize, + gl::Error copyDepth(const gl::Context *context, + const d3d11::SharedSRV &source, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const d3d11::DepthStencilView &dest, + const gl::Box &destArea, + const gl::Extents &destSize, const gl::Rectangle *scissor); - gl::Error copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, + gl::Error copyDepthStencil(const TextureHelper11 &source, + unsigned int sourceSubresource, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const TextureHelper11 &dest, + unsigned int destSubresource, + const gl::Box &destArea, + const gl::Extents &destSize, const gl::Rectangle *scissor); + gl::ErrorOrResult resolveDepth(const gl::Context *context, + RenderTarget11 *depth); + + gl::ErrorOrResult resolveStencil(const gl::Context *context, + RenderTarget11 *depthStencil, + bool alsoDepth); + + using BlitConvertFunction = void(const gl::Box &sourceArea, + const gl::Box &destArea, + const gl::Rectangle &clipRect, + const gl::Extents &sourceSize, + unsigned int sourceRowPitch, + unsigned int destRowPitch, + ptrdiff_t readOffset, + ptrdiff_t writeOffset, + size_t copySize, + size_t srcPixelStride, + size_t destPixelStride, + const uint8_t *sourceData, + uint8_t *destData); + private: enum BlitShaderType { BLITSHADER_INVALID, + + // Passthrough shaders BLITSHADER_2D_RGBAF, BLITSHADER_2D_BGRAF, BLITSHADER_2D_RGBF, @@ -88,6 +137,27 @@ class Blit11 : angle::NonCopyable BLITSHADER_3D_ALPHA, BLITSHADER_3D_LUMA, BLITSHADER_3D_LUMAALPHA, + + // Multiply alpha shaders + BLITSHADER_2D_RGBAF_PREMULTIPLY, + BLITSHADER_2D_RGBAF_UNMULTIPLY, + + BLITSHADER_2D_RGBF_PREMULTIPLY, + BLITSHADER_2D_RGBF_UNMULTIPLY, + + BLITSHADER_2D_RGBAF_TOUI, + BLITSHADER_2D_RGBAF_TOUI_PREMULTIPLY, + BLITSHADER_2D_RGBAF_TOUI_UNMULTIPLY, + + BLITSHADER_2D_RGBF_TOUI, + BLITSHADER_2D_RGBF_TOUI_PREMULTIPLY, + BLITSHADER_2D_RGBF_TOUI_UNMULTIPLY, + + BLITSHADER_2D_LUMAF_PREMULTIPLY, + BLITSHADER_2D_LUMAF_UNMULTIPLY, + + BLITSHADER_2D_LUMAALPHAF_PREMULTIPLY, + BLITSHADER_2D_LUMAALPHAF_UNMULTIPLY }; enum SwizzleShaderType @@ -107,9 +177,13 @@ class Blit11 : angle::NonCopyable SWIZZLESHADER_ARRAY_INT, }; - typedef void (*WriteVertexFunction)(const gl::Box &sourceArea, const gl::Extents &sourceSize, - const gl::Box &destArea, const gl::Extents &destSize, - void *outVertices, unsigned int *outStride, unsigned int *outVertexCount, + typedef void (*WriteVertexFunction)(const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const gl::Box &destArea, + const gl::Extents &destSize, + void *outVertices, + unsigned int *outStride, + unsigned int *outVertexCount, D3D11_PRIMITIVE_TOPOLOGY *outTopology); enum ShaderDimension @@ -120,38 +194,102 @@ class Blit11 : angle::NonCopyable struct Shader { + Shader(); + Shader(Shader &&other); + ~Shader(); + Shader &operator=(Shader &&other); + ShaderDimension dimension; - ID3D11PixelShader *pixelShader; + d3d11::PixelShader pixelShader; }; struct ShaderSupport { - ID3D11InputLayout *inputLayout; - ID3D11VertexShader *vertexShader; - ID3D11GeometryShader *geometryShader; + const d3d11::InputLayout *inputLayout; + const d3d11::VertexShader *vertexShader; + const d3d11::GeometryShader *geometryShader; WriteVertexFunction vertexWriteFunction; }; gl::Error initResources(); - void freeResources(); - ShaderSupport getShaderSupport(const Shader &shader); + gl::Error getShaderSupport(const Shader &shader, ShaderSupport *supportOut); - static BlitShaderType GetBlitShaderType(GLenum destinationFormat, bool isSigned, ShaderDimension dimension); + static BlitShaderType GetBlitShaderType(GLenum destinationFormat, + GLenum sourceFormat, + bool isSigned, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + ShaderDimension dimension); static SwizzleShaderType GetSwizzleShaderType(GLenum type, D3D11_SRV_DIMENSION dimensionality); - gl::Error copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, - ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, - const gl::Rectangle *scissor, bool stencilOnly); + gl::Error copyDepthStencilImpl(const TextureHelper11 &source, + unsigned int sourceSubresource, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const TextureHelper11 &dest, + unsigned int destSubresource, + const gl::Box &destArea, + const gl::Extents &destSize, + const gl::Rectangle *scissor, + bool stencilOnly); - void addBlitShaderToMap(BlitShaderType blitShaderType, ShaderDimension dimension, ID3D11PixelShader *ps); + gl::Error copyAndConvertImpl(const TextureHelper11 &source, + unsigned int sourceSubresource, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const TextureHelper11 &destStaging, + const gl::Box &destArea, + const gl::Extents &destSize, + const gl::Rectangle *scissor, + size_t readOffset, + size_t writeOffset, + size_t copySize, + size_t srcPixelStride, + size_t destPixelStride, + BlitConvertFunction *convertFunction); - gl::Error getBlitShader(GLenum destFormat, bool isSigned, ShaderDimension dimension, const Shader **shaderOut); - gl::Error getSwizzleShader(GLenum type, D3D11_SRV_DIMENSION viewDimension, const Shader **shaderOut); + gl::Error copyAndConvert(const TextureHelper11 &source, + unsigned int sourceSubresource, + const gl::Box &sourceArea, + const gl::Extents &sourceSize, + const TextureHelper11 &dest, + unsigned int destSubresource, + const gl::Box &destArea, + const gl::Extents &destSize, + const gl::Rectangle *scissor, + size_t readOffset, + size_t writeOffset, + size_t copySize, + size_t srcPixelStride, + size_t destPixelStride, + BlitConvertFunction *convertFunction); - void addSwizzleShaderToMap(SwizzleShaderType swizzleShaderType, ShaderDimension dimension, ID3D11PixelShader *ps); + gl::Error addBlitShaderToMap(BlitShaderType blitShaderType, + ShaderDimension dimension, + const ShaderData &shaderData, + const char *name); + + gl::Error getBlitShader(GLenum destFormat, + GLenum sourceFormat, + bool isSigned, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + ShaderDimension dimension, + const Shader **shaderOut); + gl::Error getSwizzleShader(GLenum type, + D3D11_SRV_DIMENSION viewDimension, + const Shader **shaderOut); + + gl::Error addSwizzleShaderToMap(SwizzleShaderType swizzleShaderType, + ShaderDimension dimension, + const ShaderData &shaderData, + const char *name); void clearShaderMap(); + void releaseResolveDepthStencilResources(); + gl::Error initResolveDepthOnly(const d3d11::Format &format, const gl::Extents &extents); + gl::Error initResolveDepthStencil(const gl::Extents &extents); Renderer11 *mRenderer; @@ -159,12 +297,12 @@ class Blit11 : angle::NonCopyable std::map mSwizzleShaderMap; bool mResourcesInitialized; - ID3D11Buffer *mVertexBuffer; - ID3D11SamplerState *mPointSampler; - ID3D11SamplerState *mLinearSampler; - ID3D11RasterizerState *mScissorEnabledRasterizerState; - ID3D11RasterizerState *mScissorDisabledRasterizerState; - ID3D11DepthStencilState *mDepthStencilState; + d3d11::Buffer mVertexBuffer; + d3d11::SamplerState mPointSampler; + d3d11::SamplerState mLinearSampler; + d3d11::RasterizerState mScissorEnabledRasterizerState; + d3d11::RasterizerState mScissorDisabledRasterizerState; + d3d11::DepthStencilState mDepthStencilState; d3d11::LazyInputLayout mQuad2DIL; d3d11::LazyShader mQuad2DVS; @@ -176,9 +314,19 @@ class Blit11 : angle::NonCopyable d3d11::LazyBlendState mAlphaMaskBlendState; - ID3D11Buffer *mSwizzleCB; + d3d11::Buffer mSwizzleCB; + + d3d11::LazyShader mResolveDepthStencilVS; + d3d11::LazyShader mResolveDepthPS; + d3d11::LazyShader mResolveDepthStencilPS; + d3d11::LazyShader mResolveStencilPS; + d3d11::ShaderResourceView mStencilSRV; + TextureHelper11 mResolvedDepthStencil; + d3d11::RenderTargetView mResolvedDepthStencilRTView; + TextureHelper11 mResolvedDepth; + d3d11::DepthStencilView mResolvedDepthDSView; }; -} +} // namespace rx -#endif // LIBANGLE_RENDERER_D3D_D3D11_BLIT11_H_ +#endif // LIBANGLE_RENDERER_D3D_D3D11_BLIT11_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp index 0d5dc08b03..2317c9abdb 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp @@ -13,10 +13,14 @@ #include "common/MemoryBuffer.h" #include "libANGLE/renderer/d3d/IndexDataManager.h" #include "libANGLE/renderer/d3d/VertexDataManager.h" -#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" -#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" #include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/renderer/renderer_utils.h" + +namespace rx +{ namespace { @@ -27,41 +31,41 @@ GLuint ReadIndexValueFromIndices(const uint8_t *data, size_t index) return reinterpret_cast(data)[index]; } typedef GLuint (*ReadIndexValueFunction)(const uint8_t *data, size_t index); + +enum class CopyResult +{ + RECREATED, + NOT_RECREATED, +}; + +void CalculateConstantBufferParams(GLintptr offset, + GLsizeiptr size, + UINT *outFirstConstant, + UINT *outNumConstants) +{ + // The offset must be aligned to 256 bytes (should have been enforced by glBindBufferRange). + ASSERT(offset % 256 == 0); + + // firstConstant and numConstants are expressed in constants of 16-bytes. Furthermore they must + // be a multiple of 16 constants. + *outFirstConstant = static_cast(offset / 16); + + // The GL size is not required to be aligned to a 256 bytes boundary. + // Round the size up to a 256 bytes boundary then express the results in constants of 16-bytes. + *outNumConstants = static_cast(rx::roundUp(size, static_cast(256)) / 16); + + // Since the size is rounded up, firstConstant + numConstants may be bigger than the actual size + // of the buffer. This behaviour is explictly allowed according to the documentation on + // ID3D11DeviceContext1::PSSetConstantBuffers1 + // https://msdn.microsoft.com/en-us/library/windows/desktop/hh404649%28v=vs.85%29.aspx } -#if defined(ANGLE_MINGW32_COMPAT) -typedef enum D3D11_MAP_FLAG { - D3D11_MAP_FLAG_DO_NOT_WAIT = 0x100000 -} D3D11_MAP_FLAG; -#endif - -namespace rx -{ -PackPixelsParams::PackPixelsParams() - : format(GL_NONE), type(GL_NONE), outputPitch(0), packBuffer(nullptr), offset(0) -{ -} - -PackPixelsParams::PackPixelsParams(const gl::Rectangle &areaIn, - GLenum formatIn, - GLenum typeIn, - GLuint outputPitchIn, - const gl::PixelPackState &packIn, - ptrdiff_t offsetIn) - : area(areaIn), - format(formatIn), - type(typeIn), - outputPitch(outputPitchIn), - packBuffer(packIn.pixelBuffer.get()), - pack(packIn.alignment, packIn.reverseRowOrder), - offset(offsetIn) -{ -} +} // anonymous namespace namespace gl_d3d11 { -D3D11_MAP GetD3DMapTypeFromBits(GLbitfield access) +D3D11_MAP GetD3DMapTypeFromBits(BufferUsage usage, GLbitfield access) { bool readBit = ((access & GL_MAP_READ_BIT) != 0); bool writeBit = ((access & GL_MAP_WRITE_BIT) != 0); @@ -77,7 +81,8 @@ D3D11_MAP GetD3DMapTypeFromBits(GLbitfield access) } else if (writeBit && !readBit) { - return D3D11_MAP_WRITE; + // Special case for uniform storage - we only allow full buffer updates. + return usage == BUFFER_USAGE_UNIFORM ? D3D11_MAP_WRITE_DISCARD : D3D11_MAP_WRITE; } else if (writeBit && readBit) { @@ -89,7 +94,7 @@ D3D11_MAP GetD3DMapTypeFromBits(GLbitfield access) return D3D11_MAP_READ; } } -} +} // namespace gl_d3d11 // Each instance of Buffer11::BufferStorage is specialized for a class of D3D binding points // - vertex/transform feedback buffers @@ -106,16 +111,22 @@ class Buffer11::BufferStorage : angle::NonCopyable size_t getSize() const { return mBufferSize; } void setDataRevision(DataRevision rev) { mRevision = rev; } - virtual bool isMappable() const = 0; + virtual bool isCPUAccessible(GLbitfield access) const = 0; - virtual bool copyFromStorage(BufferStorage *source, - size_t sourceOffset, - size_t size, - size_t destOffset) = 0; - virtual gl::Error resize(size_t size, bool preserveData) = 0; + virtual bool isGPUAccessible() const = 0; - virtual uint8_t *map(size_t offset, size_t length, GLbitfield access) = 0; - virtual void unmap() = 0; + virtual gl::ErrorOrResult copyFromStorage(const gl::Context *context, + BufferStorage *source, + size_t sourceOffset, + size_t size, + size_t destOffset) = 0; + virtual gl::Error resize(const gl::Context *context, size_t size, bool preserveData) = 0; + + virtual gl::Error map(size_t offset, + size_t length, + GLbitfield access, + uint8_t **mapPointerOut) = 0; + virtual void unmap() = 0; gl::Error setData(const uint8_t *data, size_t offset, size_t size); @@ -133,28 +144,41 @@ class Buffer11::BufferStorage : angle::NonCopyable class Buffer11::NativeStorage : public Buffer11::BufferStorage { public: - NativeStorage(Renderer11 *renderer, BufferUsage usage); + NativeStorage(Renderer11 *renderer, + BufferUsage usage, + const OnBufferDataDirtyChannel *onStorageChanged); ~NativeStorage() override; - bool isMappable() const override { return mUsage == BUFFER_USAGE_STAGING; } + bool isCPUAccessible(GLbitfield access) const override; - ID3D11Buffer *getNativeStorage() const { return mNativeStorage; } - bool copyFromStorage(BufferStorage *source, - size_t sourceOffset, - size_t size, - size_t destOffset) override; - gl::Error resize(size_t size, bool preserveData) override; + bool isGPUAccessible() const override { return true; } - uint8_t *map(size_t offset, size_t length, GLbitfield access) override; + const d3d11::Buffer &getBuffer() const { return mBuffer; } + gl::ErrorOrResult copyFromStorage(const gl::Context *context, + BufferStorage *source, + size_t sourceOffset, + size_t size, + size_t destOffset) override; + gl::Error resize(const gl::Context *context, size_t size, bool preserveData) override; + + gl::Error map(size_t offset, + size_t length, + GLbitfield access, + uint8_t **mapPointerOut) override; void unmap() override; + gl::ErrorOrResult getSRVForFormat(DXGI_FORMAT srvFormat); + private: - static void fillBufferDesc(D3D11_BUFFER_DESC *bufferDesc, + static void FillBufferDesc(D3D11_BUFFER_DESC *bufferDesc, Renderer11 *renderer, BufferUsage usage, unsigned int bufferSize); + void clearSRVs(); - ID3D11Buffer *mNativeStorage; + d3d11::Buffer mBuffer; + const OnBufferDataDirtyChannel *mOnStorageChanged; + std::map mBufferResourceViews; }; // A emulated indexed buffer storage represents an underlying D3D11 buffer for data @@ -166,28 +190,32 @@ class Buffer11::EmulatedIndexedStorage : public Buffer11::BufferStorage EmulatedIndexedStorage(Renderer11 *renderer); ~EmulatedIndexedStorage() override; - bool isMappable() const override { return true; } + bool isCPUAccessible(GLbitfield access) const override { return true; } - ID3D11Buffer *getNativeStorage(); + bool isGPUAccessible() const override { return false; } - bool copyFromStorage(BufferStorage *source, - size_t sourceOffset, - size_t size, - size_t destOffset) override; + gl::ErrorOrResult getBuffer(SourceIndexData *indexInfo, + const TranslatedAttribute &attribute, + GLint startVertex); - gl::Error resize(size_t size, bool preserveData) override; + gl::ErrorOrResult copyFromStorage(const gl::Context *context, + BufferStorage *source, + size_t sourceOffset, + size_t size, + size_t destOffset) override; - uint8_t *map(size_t offset, size_t length, GLbitfield access) override; + gl::Error resize(const gl::Context *context, size_t size, bool preserveData) override; + + gl::Error map(size_t offset, + size_t length, + GLbitfield access, + uint8_t **mapPointerOut) override; void unmap() override; - bool update(SourceIndexData *indexInfo, const TranslatedAttribute *attribute); private: - ID3D11Buffer *mNativeStorage; // contains expanded data for use by D3D - MemoryBuffer mMemoryBuffer; // original data (not expanded) - MemoryBuffer mIndicesMemoryBuffer; // indices data - SourceIndexData mIndexInfo; // indices information - size_t mAttributeStride; // per element stride in bytes - size_t mAttributeOffset; // starting offset + d3d11::Buffer mBuffer; // contains expanded data for use by D3D + angle::MemoryBuffer mMemoryBuffer; // original data (not expanded) + angle::MemoryBuffer mIndicesMemoryBuffer; // indices data }; // Pack storage represents internal storage for pack buffers. We implement pack buffers @@ -198,24 +226,32 @@ class Buffer11::PackStorage : public Buffer11::BufferStorage explicit PackStorage(Renderer11 *renderer); ~PackStorage() override; - bool isMappable() const override { return true; } - bool copyFromStorage(BufferStorage *source, - size_t sourceOffset, - size_t size, - size_t destOffset) override; - gl::Error resize(size_t size, bool preserveData) override; + bool isCPUAccessible(GLbitfield access) const override { return true; } - uint8_t *map(size_t offset, size_t length, GLbitfield access) override; + bool isGPUAccessible() const override { return false; } + + gl::ErrorOrResult copyFromStorage(const gl::Context *context, + BufferStorage *source, + size_t sourceOffset, + size_t size, + size_t destOffset) override; + gl::Error resize(const gl::Context *context, size_t size, bool preserveData) override; + + gl::Error map(size_t offset, + size_t length, + GLbitfield access, + uint8_t **mapPointerOut) override; void unmap() override; - gl::Error packPixels(const gl::FramebufferAttachment &readAttachment, + gl::Error packPixels(const gl::Context *context, + const gl::FramebufferAttachment &readAttachment, const PackPixelsParams ¶ms); private: gl::Error flushQueuedPackCommand(); TextureHelper11 mStagingTexture; - MemoryBuffer mMemoryBuffer; + angle::MemoryBuffer mMemoryBuffer; std::unique_ptr mQueuedPackCommand; PackPixelsParams mPackParams; bool mDataModified; @@ -230,37 +266,46 @@ class Buffer11::SystemMemoryStorage : public Buffer11::BufferStorage explicit SystemMemoryStorage(Renderer11 *renderer); ~SystemMemoryStorage() override {} - bool isMappable() const override { return true; } - bool copyFromStorage(BufferStorage *source, - size_t sourceOffset, - size_t size, - size_t destOffset) override; - gl::Error resize(size_t size, bool preserveData) override; + bool isCPUAccessible(GLbitfield access) const override { return true; } - uint8_t *map(size_t offset, size_t length, GLbitfield access) override; + bool isGPUAccessible() const override { return false; } + + gl::ErrorOrResult copyFromStorage(const gl::Context *context, + BufferStorage *source, + size_t sourceOffset, + size_t size, + size_t destOffset) override; + gl::Error resize(const gl::Context *context, size_t size, bool preserveData) override; + + gl::Error map(size_t offset, + size_t length, + GLbitfield access, + uint8_t **mapPointerOut) override; void unmap() override; - MemoryBuffer *getSystemCopy() { return &mSystemCopy; } + angle::MemoryBuffer *getSystemCopy() { return &mSystemCopy; } protected: - MemoryBuffer mSystemCopy; + angle::MemoryBuffer mSystemCopy; }; -Buffer11::Buffer11(Renderer11 *renderer) - : BufferD3D(renderer), +Buffer11::Buffer11(const gl::BufferState &state, Renderer11 *renderer) + : BufferD3D(state, renderer), mRenderer(renderer), mSize(0), mMappedStorage(nullptr), - mBufferStorages(BUFFER_USAGE_COUNT, nullptr), + mBufferStorages({}), + mLatestBufferStorage(nullptr), + mDeallocThresholds({}), + mIdleness({}), mConstantBufferStorageAdditionalSize(0), - mMaxConstantBufferLruCount(0), - mReadUsageCount(0) + mMaxConstantBufferLruCount(0) { } Buffer11::~Buffer11() { - for (auto &storage : mBufferStorages) + for (BufferStorage *&storage : mBufferStorages) { SafeDelete(storage); } @@ -273,79 +318,74 @@ Buffer11::~Buffer11() mRenderer->onBufferDelete(this); } -gl::Error Buffer11::setData(const void *data, size_t size, GLenum usage) +gl::Error Buffer11::setData(const gl::Context *context, + gl::BufferBinding target, + const void *data, + size_t size, + gl::BufferUsage usage) { - gl::Error error = setSubData(data, size, 0); - if (error.isError()) - { - return error; - } - - updateD3DBufferUsage(usage); - return error; + updateD3DBufferUsage(context, usage); + ANGLE_TRY(setSubData(context, target, data, size, 0)); + return gl::NoError(); } -gl::Error Buffer11::getData(const uint8_t **outData) +gl::Error Buffer11::getData(const gl::Context *context, const uint8_t **outData) { SystemMemoryStorage *systemMemoryStorage = nullptr; - gl::Error error = getSystemMemoryStorage(&systemMemoryStorage); - - if (error.isError()) - { - *outData = nullptr; - return error; - } - - mReadUsageCount = 0; + ANGLE_TRY_RESULT(getSystemMemoryStorage(context), systemMemoryStorage); ASSERT(systemMemoryStorage->getSize() >= mSize); *outData = systemMemoryStorage->getSystemCopy()->data(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Buffer11::getSystemMemoryStorage(SystemMemoryStorage **storageOut) +gl::ErrorOrResult Buffer11::getSystemMemoryStorage( + const gl::Context *context) { - BufferStorage *memStorageUntyped = getBufferStorage(BUFFER_USAGE_SYSTEM_MEMORY); - - if (memStorageUntyped == nullptr) - { - // TODO(jmadill): convert all to errors - return gl::Error(GL_OUT_OF_MEMORY); - } - - *storageOut = GetAs(memStorageUntyped); - return gl::Error(GL_NO_ERROR); + BufferStorage *storage = nullptr; + ANGLE_TRY_RESULT(getBufferStorage(context, BUFFER_USAGE_SYSTEM_MEMORY), storage); + return GetAs(storage); } -gl::Error Buffer11::setSubData(const void *data, size_t size, size_t offset) +gl::Error Buffer11::setSubData(const gl::Context *context, + gl::BufferBinding target, + const void *data, + size_t size, + size_t offset) { size_t requiredSize = size + offset; if (data && size > 0) { // Use system memory storage for dynamic buffers. - + // Try using a constant storage for constant buffers BufferStorage *writeBuffer = nullptr; - if (supportsDirectBinding()) + if (target == gl::BufferBinding::Uniform) { - writeBuffer = getStagingStorage(); - - if (!writeBuffer) + // If we are a very large uniform buffer, keep system memory storage around so that we + // aren't forced to read back from a constant buffer. We also check the workaround for + // Intel - this requires us to use system memory so we don't end up having to copy from + // a constant buffer to a staging buffer. + // TODO(jmadill): Use Context caps. + if (offset == 0 && size >= mSize && + size <= static_cast(mRenderer->getNativeCaps().maxUniformBlockSize) && + !mRenderer->getWorkarounds().useSystemMemoryForConstantBuffers) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal buffer."); + ANGLE_TRY_RESULT(getBufferStorage(context, BUFFER_USAGE_UNIFORM), writeBuffer); } + else + { + ANGLE_TRY_RESULT(getSystemMemoryStorage(context), writeBuffer); + } + } + else if (supportsDirectBinding()) + { + ANGLE_TRY_RESULT(getStagingStorage(context), writeBuffer); } else { - SystemMemoryStorage *systemMemoryStorage = nullptr; - gl::Error error = getSystemMemoryStorage(&systemMemoryStorage); - if (error.isError()) - { - return error; - } - - writeBuffer = systemMemoryStorage; + ANGLE_TRY_RESULT(getSystemMemoryStorage(context), writeBuffer); } ASSERT(writeBuffer); @@ -355,24 +395,25 @@ gl::Error Buffer11::setSubData(const void *data, size_t size, size_t offset) if (writeBuffer->getSize() < requiredSize) { bool preserveData = (offset > 0); - gl::Error error = writeBuffer->resize(requiredSize, preserveData); - if (error.isError()) - { - return error; - } + ANGLE_TRY(writeBuffer->resize(context, requiredSize, preserveData)); } - writeBuffer->setData(static_cast(data), offset, size); - writeBuffer->setDataRevision(writeBuffer->getDataRevision() + 1); + ANGLE_TRY(writeBuffer->setData(static_cast(data), offset, size)); + onStorageUpdate(writeBuffer); + + // Notify any vertex arrays that we have dirty data. + // TODO(jmadill): Use a more fine grained notification for data updates. + mDirectBroadcastChannel.signal(context); } mSize = std::max(mSize, requiredSize); - invalidateStaticData(D3D_BUFFER_INVALIDATE_WHOLE_CACHE); + invalidateStaticData(context); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Buffer11::copySubData(BufferImpl *source, +gl::Error Buffer11::copySubData(const gl::Context *context, + BufferImpl *source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) @@ -380,28 +421,32 @@ gl::Error Buffer11::copySubData(BufferImpl *source, Buffer11 *sourceBuffer = GetAs(source); ASSERT(sourceBuffer != nullptr); - BufferStorage *copyDest = getLatestBufferStorage(); + BufferStorage *copyDest = nullptr; + ANGLE_TRY_RESULT(getLatestBufferStorage(context), copyDest); + if (!copyDest) { - copyDest = getStagingStorage(); + ANGLE_TRY_RESULT(getStagingStorage(context), copyDest); } - BufferStorage *copySource = sourceBuffer->getLatestBufferStorage(); + BufferStorage *copySource = nullptr; + ANGLE_TRY_RESULT(sourceBuffer->getLatestBufferStorage(context), copySource); - if (!copySource || !copyDest) + if (!copySource) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal staging buffer."); + ANGLE_TRY_RESULT(sourceBuffer->getStagingStorage(context), copySource); } - // If copying to/from a pixel pack buffer, we must have a staging or - // pack buffer partner, because other native buffers can't be mapped - if (copyDest->getUsage() == BUFFER_USAGE_PIXEL_PACK && !copySource->isMappable()) + ASSERT(copySource && copyDest); + + // A staging buffer is needed if there is no cpu-cpu or gpu-gpu copy path avaiable. + if (!copyDest->isGPUAccessible() && !copySource->isCPUAccessible(GL_MAP_READ_BIT)) { - copySource = sourceBuffer->getStagingStorage(); + ANGLE_TRY_RESULT(sourceBuffer->getStagingStorage(context), copySource); } - else if (copySource->getUsage() == BUFFER_USAGE_PIXEL_PACK && !copyDest->isMappable()) + else if (!copySource->isGPUAccessible() && !copyDest->isCPUAccessible(GL_MAP_WRITE_BIT)) { - copyDest = getStagingStorage(); + ANGLE_TRY_RESULT(getStagingStorage(context), copyDest); } // D3D11 does not allow overlapped copies until 11.1, and only if the @@ -411,36 +456,48 @@ gl::Error Buffer11::copySubData(BufferImpl *source, { if (copySource->getUsage() == BUFFER_USAGE_STAGING) { - copySource = getBufferStorage(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); + ANGLE_TRY_RESULT(getBufferStorage(context, BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK), + copySource); } else { - copySource = getStagingStorage(); + ANGLE_TRY_RESULT(getStagingStorage(context), copySource); } } - copyDest->copyFromStorage(copySource, sourceOffset, size, destOffset); - copyDest->setDataRevision(copyDest->getDataRevision() + 1); + CopyResult copyResult = CopyResult::NOT_RECREATED; + ANGLE_TRY_RESULT(copyDest->copyFromStorage(context, copySource, sourceOffset, size, destOffset), + copyResult); + onStorageUpdate(copyDest); mSize = std::max(mSize, destOffset + size); - invalidateStaticData(D3D_BUFFER_INVALIDATE_WHOLE_CACHE); + invalidateStaticData(context); - return gl::Error(GL_NO_ERROR); + // Also notify that direct buffers are dirty. + mDirectBroadcastChannel.signal(context); + + return gl::NoError(); } -gl::Error Buffer11::map(GLenum access, GLvoid **mapPtr) +gl::Error Buffer11::map(const gl::Context *context, GLenum access, void **mapPtr) { // GL_OES_mapbuffer uses an enum instead of a bitfield for it's access, convert to a bitfield // and call mapRange. ASSERT(access == GL_WRITE_ONLY_OES); - return mapRange(0, mSize, GL_MAP_WRITE_BIT, mapPtr); + return mapRange(context, 0, mSize, GL_MAP_WRITE_BIT, mapPtr); } -gl::Error Buffer11::mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) +gl::Error Buffer11::mapRange(const gl::Context *context, + size_t offset, + size_t length, + GLbitfield access, + void **mapPtr) { ASSERT(!mMappedStorage); - BufferStorage *latestStorage = getLatestBufferStorage(); + BufferStorage *latestStorage = nullptr; + ANGLE_TRY_RESULT(getLatestBufferStorage(context), latestStorage); + if (latestStorage && (latestStorage->getUsage() == BUFFER_USAGE_PIXEL_PACK || latestStorage->getUsage() == BUFFER_USAGE_STAGING)) { @@ -449,34 +506,32 @@ gl::Error Buffer11::mapRange(size_t offset, size_t length, GLbitfield access, GL } else { - // Fall back to using the staging buffer if the latest storage does - // not exist or is not CPU-accessible. - mMappedStorage = getStagingStorage(); + // Fall back to using the staging buffer if the latest storage does not exist or is not + // CPU-accessible. + ANGLE_TRY_RESULT(getStagingStorage(context), mMappedStorage); } if (!mMappedStorage) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate mappable internal buffer."); + return gl::OutOfMemory() << "Failed to allocate mappable internal buffer."; } if ((access & GL_MAP_WRITE_BIT) > 0) { // Update the data revision immediately, since the data might be changed at any time - mMappedStorage->setDataRevision(mMappedStorage->getDataRevision() + 1); - invalidateStaticData(D3D_BUFFER_INVALIDATE_WHOLE_CACHE); + onStorageUpdate(mMappedStorage); + invalidateStaticData(context); } - uint8_t *mappedBuffer = mMappedStorage->map(offset, length, access); - if (!mappedBuffer) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer."); - } + uint8_t *mappedBuffer = nullptr; + ANGLE_TRY(mMappedStorage->map(offset, length, access, &mappedBuffer)); + ASSERT(mappedBuffer); - *mapPtr = static_cast(mappedBuffer); - return gl::Error(GL_NO_ERROR); + *mapPtr = static_cast(mappedBuffer); + return gl::NoError(); } -gl::Error Buffer11::unmap(GLboolean *result) +gl::Error Buffer11::unmap(const gl::Context *context, GLboolean *result) { ASSERT(mMappedStorage); mMappedStorage->unmap(); @@ -485,168 +540,171 @@ gl::Error Buffer11::unmap(GLboolean *result) // TODO: detect if we had corruption. if so, return false. *result = GL_TRUE; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -void Buffer11::markTransformFeedbackUsage() +gl::Error Buffer11::markTransformFeedbackUsage(const gl::Context *context) { - BufferStorage *transformFeedbackStorage = - getBufferStorage(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); + BufferStorage *transformFeedbackStorage = nullptr; + ANGLE_TRY_RESULT(getBufferStorage(context, BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK), + transformFeedbackStorage); if (transformFeedbackStorage) { - transformFeedbackStorage->setDataRevision(transformFeedbackStorage->getDataRevision() + 1); + onStorageUpdate(transformFeedbackStorage); } - invalidateStaticData(D3D_BUFFER_INVALIDATE_WHOLE_CACHE); + invalidateStaticData(context); + return gl::NoError(); } -void Buffer11::markBufferUsage() +void Buffer11::updateDeallocThreshold(BufferUsage usage) { - mReadUsageCount++; + // The following strategy was tuned on the Oort online benchmark (http://oortonline.gl/) + // as well as a custom microbenchmark (IndexConversionPerfTest.Run/index_range_d3d11) - // Free the system memory storage if we decide it isn't being used very often. - const unsigned int usageLimit = 5; - - BufferStorage *&sysMemUsage = mBufferStorages[BUFFER_USAGE_SYSTEM_MEMORY]; - if (mReadUsageCount > usageLimit && sysMemUsage != nullptr) + // First readback: 8 unmodified uses before we free buffer memory. + // After that, double the threshold each time until we reach the max. + if (mDeallocThresholds[usage] == 0) { - if (getLatestBufferStorage() != sysMemUsage) - { - SafeDelete(sysMemUsage); - } + mDeallocThresholds[usage] = 8; } -} - -ID3D11Buffer *Buffer11::getBuffer(BufferUsage usage) -{ - markBufferUsage(); - - BufferStorage *bufferStorage = getBufferStorage(usage); - - if (!bufferStorage) + else if (mDeallocThresholds[usage] < std::numeric_limits::max() / 2u) { - // Storage out-of-memory - return nullptr; - } - - return GetAs(bufferStorage)->getNativeStorage(); -} - -ID3D11Buffer *Buffer11::getEmulatedIndexedBuffer(SourceIndexData *indexInfo, - const TranslatedAttribute *attribute) -{ - markBufferUsage(); - - assert(indexInfo != nullptr); - assert(attribute != nullptr); - - BufferStorage *bufferStorage = getBufferStorage(BUFFER_USAGE_EMULATED_INDEXED_VERTEX); - if (!bufferStorage) - { - // Storage out-of-memory - return nullptr; - } - - EmulatedIndexedStorage *emulatedStorage = GetAs(bufferStorage); - if (!emulatedStorage->update(indexInfo, attribute)) - { - // Storage out-of-memory - return nullptr; - } - - return emulatedStorage->getNativeStorage(); -} - -ID3D11Buffer *Buffer11::getConstantBufferRange(GLintptr offset, GLsizeiptr size) -{ - markBufferUsage(); - - BufferStorage *bufferStorage; - - if (offset == 0) - { - bufferStorage = getBufferStorage(BUFFER_USAGE_UNIFORM); + mDeallocThresholds[usage] *= 2u; } else { - bufferStorage = getConstantBufferRangeStorage(offset, size); + mDeallocThresholds[usage] = std::numeric_limits::max(); } - - if (!bufferStorage) - { - // Storage out-of-memory - return nullptr; - } - - return GetAs(bufferStorage)->getNativeStorage(); } -ID3D11ShaderResourceView *Buffer11::getSRV(DXGI_FORMAT srvFormat) +// Free the storage if we decide it isn't being used very often. +gl::Error Buffer11::checkForDeallocation(const gl::Context *context, BufferUsage usage) { - BufferStorage *storage = getBufferStorage(BUFFER_USAGE_PIXEL_UNPACK); + mIdleness[usage]++; - if (!storage) + BufferStorage *&storage = mBufferStorages[usage]; + if (storage != nullptr && mIdleness[usage] > mDeallocThresholds[usage]) { - // Storage out-of-memory - return nullptr; - } - - ID3D11Buffer *buffer = GetAs(storage)->getNativeStorage(); - - auto bufferSRVIt = mBufferResourceViews.find(srvFormat); - - if (bufferSRVIt != mBufferResourceViews.end()) - { - if (bufferSRVIt->second.first == buffer) + BufferStorage *latestStorage = nullptr; + ANGLE_TRY_RESULT(getLatestBufferStorage(context), latestStorage); + if (latestStorage != storage) { - return bufferSRVIt->second.second; - } - else - { - // The underlying buffer has changed since the SRV was created: recreate the SRV. - SafeRelease(bufferSRVIt->second.second); + SafeDelete(storage); } } - ID3D11Device *device = mRenderer->getDevice(); - ID3D11ShaderResourceView *bufferSRV = nullptr; - - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(srvFormat); - - D3D11_SHADER_RESOURCE_VIEW_DESC bufferSRVDesc; - bufferSRVDesc.Buffer.ElementOffset = 0; - bufferSRVDesc.Buffer.ElementWidth = - static_cast(mSize) / dxgiFormatInfo.pixelBytes; - bufferSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; - bufferSRVDesc.Format = srvFormat; - - HRESULT result = device->CreateShaderResourceView(buffer, &bufferSRVDesc, &bufferSRV); - UNUSED_ASSERTION_VARIABLE(result); - ASSERT(SUCCEEDED(result)); - - mBufferResourceViews[srvFormat] = BufferSRVPair(buffer, bufferSRV); - - return bufferSRV; + return gl::NoError(); } -gl::Error Buffer11::packPixels(const gl::FramebufferAttachment &readAttachment, +// Keep system memory when we are using it for the canonical version of data. +bool Buffer11::canDeallocateSystemMemory() const +{ + // Must keep system memory on Intel. + if (mRenderer->getWorkarounds().useSystemMemoryForConstantBuffers) + { + return false; + } + + return (!mBufferStorages[BUFFER_USAGE_UNIFORM] || + mSize <= mRenderer->getNativeCaps().maxUniformBlockSize); +} + +void Buffer11::markBufferUsage(BufferUsage usage) +{ + mIdleness[usage] = 0; +} + +gl::Error Buffer11::garbageCollection(const gl::Context *context, BufferUsage currentUsage) +{ + if (currentUsage != BUFFER_USAGE_SYSTEM_MEMORY && canDeallocateSystemMemory()) + { + ANGLE_TRY(checkForDeallocation(context, BUFFER_USAGE_SYSTEM_MEMORY)); + } + + if (currentUsage != BUFFER_USAGE_STAGING) + { + ANGLE_TRY(checkForDeallocation(context, BUFFER_USAGE_STAGING)); + } + + return gl::NoError(); +} + +gl::ErrorOrResult Buffer11::getBuffer(const gl::Context *context, BufferUsage usage) +{ + BufferStorage *storage = nullptr; + ANGLE_TRY_RESULT(getBufferStorage(context, usage), storage); + return GetAs(storage)->getBuffer().get(); +} + +gl::ErrorOrResult Buffer11::getEmulatedIndexedBuffer( + const gl::Context *context, + SourceIndexData *indexInfo, + const TranslatedAttribute &attribute, + GLint startVertex) +{ + ASSERT(indexInfo); + + BufferStorage *untypedStorage = nullptr; + ANGLE_TRY_RESULT(getBufferStorage(context, BUFFER_USAGE_EMULATED_INDEXED_VERTEX), + untypedStorage); + + EmulatedIndexedStorage *emulatedStorage = GetAs(untypedStorage); + + const d3d11::Buffer *nativeStorage = nullptr; + ANGLE_TRY_RESULT(emulatedStorage->getBuffer(indexInfo, attribute, startVertex), nativeStorage); + + return nativeStorage->get(); +} + +gl::Error Buffer11::getConstantBufferRange(const gl::Context *context, + GLintptr offset, + GLsizeiptr size, + const d3d11::Buffer **bufferOut, + UINT *firstConstantOut, + UINT *numConstantsOut) +{ + BufferStorage *bufferStorage = nullptr; + + if (offset == 0 || mRenderer->getRenderer11DeviceCaps().supportsConstantBufferOffsets) + { + ANGLE_TRY_RESULT(getBufferStorage(context, BUFFER_USAGE_UNIFORM), bufferStorage); + CalculateConstantBufferParams(offset, size, firstConstantOut, numConstantsOut); + } + else + { + ANGLE_TRY_RESULT(getConstantBufferRangeStorage(context, offset, size), bufferStorage); + *firstConstantOut = 0; + *numConstantsOut = 0; + } + + *bufferOut = &GetAs(bufferStorage)->getBuffer(); + + return gl::NoError(); +} + +gl::ErrorOrResult Buffer11::getSRV(const gl::Context *context, + DXGI_FORMAT srvFormat) +{ + BufferStorage *storage = nullptr; + ANGLE_TRY_RESULT(getBufferStorage(context, BUFFER_USAGE_PIXEL_UNPACK), storage); + NativeStorage *nativeStorage = GetAs(storage); + return nativeStorage->getSRVForFormat(srvFormat); +} + +gl::Error Buffer11::packPixels(const gl::Context *context, + const gl::FramebufferAttachment &readAttachment, const PackPixelsParams ¶ms) { - PackStorage *packStorage = getPackStorage(); - BufferStorage *latestStorage = getLatestBufferStorage(); + PackStorage *packStorage = nullptr; + ANGLE_TRY_RESULT(getPackStorage(context), packStorage); - if (packStorage) - { - gl::Error error = packStorage->packPixels(readAttachment, params); - if (error.isError()) - { - return error; - } - packStorage->setDataRevision(latestStorage ? latestStorage->getDataRevision() + 1 : 1); - } + ASSERT(packStorage); + ANGLE_TRY(packStorage->packPixels(context, readAttachment, params)); + onStorageUpdate(packStorage); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } size_t Buffer11::getTotalCPUBufferMemoryBytes() const @@ -662,48 +720,56 @@ size_t Buffer11::getTotalCPUBufferMemoryBytes() const return allocationSize; } -Buffer11::BufferStorage *Buffer11::getBufferStorage(BufferUsage usage) +gl::ErrorOrResult Buffer11::getBufferStorage(const gl::Context *context, + BufferUsage usage) { ASSERT(0 <= usage && usage < BUFFER_USAGE_COUNT); BufferStorage *&newStorage = mBufferStorages[usage]; if (!newStorage) { - if (usage == BUFFER_USAGE_PIXEL_PACK) - { - newStorage = new PackStorage(mRenderer); - } - else if (usage == BUFFER_USAGE_SYSTEM_MEMORY) - { - newStorage = new SystemMemoryStorage(mRenderer); - } - else if (usage == BUFFER_USAGE_EMULATED_INDEXED_VERTEX) - { - newStorage = new EmulatedIndexedStorage(mRenderer); - } - else - { - // buffer is not allocated, create it - newStorage = new NativeStorage(mRenderer, usage); - } + newStorage = allocateStorage(usage); } + markBufferUsage(usage); + // resize buffer if (newStorage->getSize() < mSize) { - if (newStorage->resize(mSize, true).isError()) - { - // Out of memory error - return nullptr; - } + ANGLE_TRY(newStorage->resize(context, mSize, true)); } - updateBufferStorage(newStorage, 0, mSize); + ASSERT(newStorage); + + ANGLE_TRY(updateBufferStorage(context, newStorage, 0, mSize)); + ANGLE_TRY(garbageCollection(context, usage)); return newStorage; } -Buffer11::BufferStorage *Buffer11::getConstantBufferRangeStorage(GLintptr offset, GLsizeiptr size) +Buffer11::BufferStorage *Buffer11::allocateStorage(BufferUsage usage) +{ + updateDeallocThreshold(usage); + switch (usage) + { + case BUFFER_USAGE_PIXEL_PACK: + return new PackStorage(mRenderer); + case BUFFER_USAGE_SYSTEM_MEMORY: + return new SystemMemoryStorage(mRenderer); + case BUFFER_USAGE_EMULATED_INDEXED_VERTEX: + return new EmulatedIndexedStorage(mRenderer); + case BUFFER_USAGE_INDEX: + case BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK: + return new NativeStorage(mRenderer, usage, &mDirectBroadcastChannel); + default: + return new NativeStorage(mRenderer, usage, nullptr); + } +} + +gl::ErrorOrResult Buffer11::getConstantBufferRangeStorage( + const gl::Context *context, + GLintptr offset, + GLsizeiptr size) { BufferStorage *newStorage; @@ -714,7 +780,7 @@ Buffer11::BufferStorage *Buffer11::getConstantBufferRangeStorage(GLintptr offset if (!cacheEntry->storage) { - cacheEntry->storage = new NativeStorage(mRenderer, BUFFER_USAGE_UNIFORM); + cacheEntry->storage = allocateStorage(BUFFER_USAGE_UNIFORM); cacheEntry->lruCount = ++mMaxConstantBufferLruCount; } @@ -722,6 +788,8 @@ Buffer11::BufferStorage *Buffer11::getConstantBufferRangeStorage(GLintptr offset newStorage = cacheEntry->storage; } + markBufferUsage(BUFFER_USAGE_UNIFORM); + if (newStorage->getSize() < static_cast(size)) { size_t maximumAllowedAdditionalSize = 2 * getSize(); @@ -733,8 +801,7 @@ Buffer11::BufferStorage *Buffer11::getConstantBufferRangeStorage(GLintptr offset auto iter = std::min_element(std::begin(mConstantBufferRangeStoragesCache), std::end(mConstantBufferRangeStoragesCache), [](const ConstantBufferCache::value_type &a, - const ConstantBufferCache::value_type &b) - { + const ConstantBufferCache::value_type &b) { return a.second.lruCount < b.second.lruCount; }); @@ -746,12 +813,7 @@ Buffer11::BufferStorage *Buffer11::getConstantBufferRangeStorage(GLintptr offset mConstantBufferRangeStoragesCache.erase(iter); } - if (newStorage->resize(size, false).isError()) - { - // Out of memory error - return nullptr; - } - + ANGLE_TRY(newStorage->resize(context, size, false)); mConstantBufferStorageAdditionalSize += sizeDelta; // We don't copy the old data when resizing the constant buffer because the data may be @@ -760,103 +822,148 @@ Buffer11::BufferStorage *Buffer11::getConstantBufferRangeStorage(GLintptr offset newStorage->setDataRevision(0); } - updateBufferStorage(newStorage, offset, size); - + ANGLE_TRY(updateBufferStorage(context, newStorage, offset, size)); + ANGLE_TRY(garbageCollection(context, BUFFER_USAGE_UNIFORM)); return newStorage; } -void Buffer11::updateBufferStorage(BufferStorage *storage, size_t sourceOffset, size_t storageSize) +gl::Error Buffer11::updateBufferStorage(const gl::Context *context, + BufferStorage *storage, + size_t sourceOffset, + size_t storageSize) { - BufferStorage *latestBuffer = getLatestBufferStorage(); - if (latestBuffer && latestBuffer->getDataRevision() > storage->getDataRevision()) + BufferStorage *latestBuffer = nullptr; + ANGLE_TRY_RESULT(getLatestBufferStorage(context), latestBuffer); + + ASSERT(storage); + + if (!latestBuffer) { - // Copy through a staging buffer if we're copying from or to a non-staging, mappable - // buffer storage. This is because we can't map a GPU buffer, and copy CPU - // data directly. If we're already using a staging buffer we're fine. - if (latestBuffer->getUsage() != BUFFER_USAGE_STAGING && - storage->getUsage() != BUFFER_USAGE_STAGING && - (!latestBuffer->isMappable() || !storage->isMappable())) - { - NativeStorage *stagingBuffer = getStagingStorage(); - - stagingBuffer->copyFromStorage(latestBuffer, 0, latestBuffer->getSize(), 0); - stagingBuffer->setDataRevision(latestBuffer->getDataRevision()); - - latestBuffer = stagingBuffer; - } - - // if copyFromStorage returns true, the D3D buffer has been recreated - // and we should update our serial - if (storage->copyFromStorage(latestBuffer, sourceOffset, storageSize, 0)) - { - updateSerial(); - } - storage->setDataRevision(latestBuffer->getDataRevision()); + onStorageUpdate(storage); + return gl::NoError(); } + + if (latestBuffer->getDataRevision() <= storage->getDataRevision()) + { + return gl::NoError(); + } + + // Copy through a staging buffer if we're copying from or to a non-staging, mappable + // buffer storage. This is because we can't map a GPU buffer, and copy CPU + // data directly. If we're already using a staging buffer we're fine. + if (latestBuffer->getUsage() != BUFFER_USAGE_STAGING && + storage->getUsage() != BUFFER_USAGE_STAGING && + (!latestBuffer->isCPUAccessible(GL_MAP_READ_BIT) || + !storage->isCPUAccessible(GL_MAP_WRITE_BIT))) + { + NativeStorage *stagingBuffer = nullptr; + ANGLE_TRY_RESULT(getStagingStorage(context), stagingBuffer); + + CopyResult copyResult = CopyResult::NOT_RECREATED; + ANGLE_TRY_RESULT( + stagingBuffer->copyFromStorage(context, latestBuffer, 0, latestBuffer->getSize(), 0), + copyResult); + onCopyStorage(stagingBuffer, latestBuffer); + + latestBuffer = stagingBuffer; + } + + CopyResult copyResult = CopyResult::NOT_RECREATED; + ANGLE_TRY_RESULT(storage->copyFromStorage(context, latestBuffer, sourceOffset, storageSize, 0), + copyResult); + // If the D3D buffer has been recreated, we should update our serial. + if (copyResult == CopyResult::RECREATED) + { + updateSerial(); + } + onCopyStorage(storage, latestBuffer); + return gl::NoError(); } -Buffer11::BufferStorage *Buffer11::getLatestBufferStorage() const +gl::ErrorOrResult Buffer11::getLatestBufferStorage( + const gl::Context *context) const { - // Even though we iterate over all the direct buffers, it is expected that only - // 1 or 2 will be present. - BufferStorage *latestStorage = nullptr; - DataRevision latestRevision = 0; - for (auto &storage : mBufferStorages) - { - if (storage && (!latestStorage || storage->getDataRevision() > latestRevision)) - { - latestStorage = storage; - latestRevision = storage->getDataRevision(); - } - } - // resize buffer - if (latestStorage && latestStorage->getSize() < mSize) + if (mLatestBufferStorage && mLatestBufferStorage->getSize() < mSize) { - if (latestStorage->resize(mSize, true).isError()) - { - // Out of memory error - return nullptr; - } + ANGLE_TRY(mLatestBufferStorage->resize(context, mSize, true)); } - return latestStorage; + return mLatestBufferStorage; } -Buffer11::NativeStorage *Buffer11::getStagingStorage() +gl::ErrorOrResult Buffer11::getStagingStorage(const gl::Context *context) { - BufferStorage *stagingStorage = getBufferStorage(BUFFER_USAGE_STAGING); - - if (!stagingStorage) - { - // Out-of-memory - return nullptr; - } - + BufferStorage *stagingStorage = nullptr; + ANGLE_TRY_RESULT(getBufferStorage(context, BUFFER_USAGE_STAGING), stagingStorage); return GetAs(stagingStorage); } -Buffer11::PackStorage *Buffer11::getPackStorage() +gl::ErrorOrResult Buffer11::getPackStorage(const gl::Context *context) { - BufferStorage *packStorage = getBufferStorage(BUFFER_USAGE_PIXEL_PACK); - - if (!packStorage) - { - // Out-of-memory - return nullptr; - } - + BufferStorage *packStorage = nullptr; + ANGLE_TRY_RESULT(getBufferStorage(context, BUFFER_USAGE_PIXEL_PACK), packStorage); return GetAs(packStorage); } +size_t Buffer11::getSize() const +{ + return mSize; +} + bool Buffer11::supportsDirectBinding() const { // Do not support direct buffers for dynamic data. The streaming buffer // offers better performance for data which changes every frame. - // Check for absence of static buffer interfaces to detect dynamic data. - return (mStaticVertexBuffer && mStaticIndexBuffer); + return (mUsage == D3DBufferUsage::STATIC); } +void Buffer11::initializeStaticData(const gl::Context *context) +{ + BufferD3D::initializeStaticData(context); + + // Notify when static data changes. + mStaticBroadcastChannel.signal(context); +} + +void Buffer11::invalidateStaticData(const gl::Context *context) +{ + BufferD3D::invalidateStaticData(context); + + // Notify when static data changes. + mStaticBroadcastChannel.signal(context); +} + +OnBufferDataDirtyChannel *Buffer11::getStaticBroadcastChannel() +{ + return &mStaticBroadcastChannel; +} + +OnBufferDataDirtyChannel *Buffer11::getDirectBroadcastChannel() +{ + return &mDirectBroadcastChannel; +} + +void Buffer11::onCopyStorage(BufferStorage *dest, BufferStorage *source) +{ + ASSERT(source && mLatestBufferStorage); + dest->setDataRevision(source->getDataRevision()); + + // Only update the latest buffer storage if our usage index is lower. See comment in header. + if (dest->getUsage() < mLatestBufferStorage->getUsage()) + { + mLatestBufferStorage = dest; + } +} + +void Buffer11::onStorageUpdate(BufferStorage *updatedStorage) +{ + updatedStorage->setDataRevision(updatedStorage->getDataRevision() + 1); + mLatestBufferStorage = updatedStorage; +} + +// Buffer11::BufferStorage implementation + Buffer11::BufferStorage::BufferStorage(Renderer11 *renderer, BufferUsage usage) : mRenderer(renderer), mRevision(0), mUsage(usage), mBufferSize(0) { @@ -864,113 +971,118 @@ Buffer11::BufferStorage::BufferStorage(Renderer11 *renderer, BufferUsage usage) gl::Error Buffer11::BufferStorage::setData(const uint8_t *data, size_t offset, size_t size) { - ASSERT(isMappable()); + ASSERT(isCPUAccessible(GL_MAP_WRITE_BIT)); - uint8_t *writePointer = map(offset, size, GL_MAP_WRITE_BIT); - if (!writePointer) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer."); - } + // Uniform storage can have a different internal size than the buffer size. Ensure we don't + // overflow. + size_t mapSize = std::min(size, mBufferSize - offset); - memcpy(writePointer, data, size); + uint8_t *writePointer = nullptr; + ANGLE_TRY(map(offset, mapSize, GL_MAP_WRITE_BIT, &writePointer)); + + memcpy(writePointer, data, mapSize); unmap(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -Buffer11::NativeStorage::NativeStorage(Renderer11 *renderer, BufferUsage usage) - : BufferStorage(renderer, usage), mNativeStorage(nullptr) +// Buffer11::NativeStorage implementation + +Buffer11::NativeStorage::NativeStorage(Renderer11 *renderer, + BufferUsage usage, + const OnBufferDataDirtyChannel *onStorageChanged) + : BufferStorage(renderer, usage), mBuffer(), mOnStorageChanged(onStorageChanged) { } Buffer11::NativeStorage::~NativeStorage() { - SafeRelease(mNativeStorage); + clearSRVs(); +} + +bool Buffer11::NativeStorage::isCPUAccessible(GLbitfield access) const +{ + if ((access & GL_MAP_READ_BIT) != 0) + { + // Read is more exclusive than write mappability. + return (mUsage == BUFFER_USAGE_STAGING); + } + ASSERT((access & GL_MAP_WRITE_BIT) != 0); + return (mUsage == BUFFER_USAGE_STAGING || mUsage == BUFFER_USAGE_UNIFORM); } // Returns true if it recreates the direct buffer -bool Buffer11::NativeStorage::copyFromStorage(BufferStorage *source, - size_t sourceOffset, - size_t size, - size_t destOffset) +gl::ErrorOrResult Buffer11::NativeStorage::copyFromStorage(const gl::Context *context, + BufferStorage *source, + size_t sourceOffset, + size_t size, + size_t destOffset) { - ID3D11DeviceContext *context = mRenderer->getDeviceContext(); - size_t requiredSize = destOffset + size; - bool createBuffer = !mNativeStorage || mBufferSize < requiredSize; + bool createBuffer = !mBuffer.valid() || mBufferSize < requiredSize; // (Re)initialize D3D buffer if needed + bool preserveData = (destOffset > 0); if (createBuffer) { - bool preserveData = (destOffset > 0); - resize(requiredSize, preserveData); + ANGLE_TRY(resize(context, requiredSize, preserveData)); + } + + size_t clampedSize = size; + if (mUsage == BUFFER_USAGE_UNIFORM) + { + clampedSize = std::min(clampedSize, mBufferSize - destOffset); } if (source->getUsage() == BUFFER_USAGE_PIXEL_PACK || source->getUsage() == BUFFER_USAGE_SYSTEM_MEMORY) { - ASSERT(source->isMappable()); + ASSERT(source->isCPUAccessible(GL_MAP_READ_BIT) && isCPUAccessible(GL_MAP_WRITE_BIT)); - uint8_t *sourcePointer = source->map(sourceOffset, size, GL_MAP_READ_BIT); + // Uniform buffers must be mapped with write/discard. + ASSERT(!(preserveData && mUsage == BUFFER_USAGE_UNIFORM)); - D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT hr = context->Map(mNativeStorage, 0, D3D11_MAP_WRITE, 0, &mappedResource); - ASSERT(SUCCEEDED(hr)); - if (FAILED(hr)) - { - source->unmap(); - return false; - } + uint8_t *sourcePointer = nullptr; + ANGLE_TRY(source->map(sourceOffset, clampedSize, GL_MAP_READ_BIT, &sourcePointer)); - uint8_t *destPointer = static_cast(mappedResource.pData) + destOffset; - - // Offset bounds are validated at the API layer - ASSERT(sourceOffset + size <= destOffset + mBufferSize); - memcpy(destPointer, sourcePointer, size); - - context->Unmap(mNativeStorage, 0); + auto err = setData(sourcePointer, destOffset, clampedSize); source->unmap(); + ANGLE_TRY(err); } else { D3D11_BOX srcBox; srcBox.left = static_cast(sourceOffset); - srcBox.right = static_cast(sourceOffset + size); + srcBox.right = static_cast(sourceOffset + clampedSize); srcBox.top = 0; srcBox.bottom = 1; srcBox.front = 0; srcBox.back = 1; - ID3D11Buffer *sourceBuffer = GetAs(source)->getNativeStorage(); + const d3d11::Buffer *sourceBuffer = &GetAs(source)->getBuffer(); - context->CopySubresourceRegion(mNativeStorage, 0, static_cast(destOffset), 0, - 0, sourceBuffer, 0, &srcBox); + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + deviceContext->CopySubresourceRegion(mBuffer.get(), 0, + static_cast(destOffset), 0, 0, + sourceBuffer->get(), 0, &srcBox); } - return createBuffer; + return createBuffer ? CopyResult::RECREATED : CopyResult::NOT_RECREATED; } -gl::Error Buffer11::NativeStorage::resize(size_t size, bool preserveData) +gl::Error Buffer11::NativeStorage::resize(const gl::Context *context, + size_t size, + bool preserveData) { - ID3D11Device *device = mRenderer->getDevice(); - ID3D11DeviceContext *context = mRenderer->getDeviceContext(); - D3D11_BUFFER_DESC bufferDesc; - fillBufferDesc(&bufferDesc, mRenderer, mUsage, static_cast(size)); + FillBufferDesc(&bufferDesc, mRenderer, mUsage, static_cast(size)); - ID3D11Buffer *newBuffer; - HRESULT result = device->CreateBuffer(&bufferDesc, nullptr, &newBuffer); + d3d11::Buffer newBuffer; + ANGLE_TRY(mRenderer->allocateResource(bufferDesc, &newBuffer)); + newBuffer.setDebugName("Buffer11::NativeStorage"); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer, result: 0x%X.", - result); - } - - d3d11::SetDebugName(newBuffer, "Buffer11::NativeStorage"); - - if (mNativeStorage && preserveData) + if (mBuffer.valid() && preserveData) { // We don't call resize if the buffer is big enough already. ASSERT(mBufferSize <= size); @@ -983,19 +1095,30 @@ gl::Error Buffer11::NativeStorage::resize(size_t size, bool preserveData) srcBox.front = 0; srcBox.back = 1; - context->CopySubresourceRegion(newBuffer, 0, 0, 0, 0, mNativeStorage, 0, &srcBox); + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + deviceContext->CopySubresourceRegion(newBuffer.get(), 0, 0, 0, 0, mBuffer.get(), 0, + &srcBox); } // No longer need the old buffer - SafeRelease(mNativeStorage); - mNativeStorage = newBuffer; + mBuffer = std::move(newBuffer); mBufferSize = bufferDesc.ByteWidth; - return gl::Error(GL_NO_ERROR); + // Free the SRVs. + clearSRVs(); + + // Notify that the storage has changed. + if (mOnStorageChanged) + { + mOnStorageChanged->signal(context); + } + + return gl::NoError(); } -void Buffer11::NativeStorage::fillBufferDesc(D3D11_BUFFER_DESC *bufferDesc, +// static +void Buffer11::NativeStorage::FillBufferDesc(D3D11_BUFFER_DESC *bufferDesc, Renderer11 *renderer, BufferUsage usage, unsigned int bufferSize) @@ -1030,6 +1153,13 @@ void Buffer11::NativeStorage::fillBufferDesc(D3D11_BUFFER_DESC *bufferDesc, bufferDesc->CPUAccessFlags = 0; break; + case BUFFER_USAGE_INDIRECT: + bufferDesc->MiscFlags = D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS; + bufferDesc->Usage = D3D11_USAGE_DEFAULT; + bufferDesc->BindFlags = 0; + bufferDesc->CPUAccessFlags = 0; + break; + case BUFFER_USAGE_PIXEL_UNPACK: bufferDesc->Usage = D3D11_USAGE_DEFAULT; bufferDesc->BindFlags = D3D11_BIND_SHADER_RESOURCE; @@ -1044,9 +1174,12 @@ void Buffer11::NativeStorage::fillBufferDesc(D3D11_BUFFER_DESC *bufferDesc, // Constant buffers must be of a limited size, and aligned to 16 byte boundaries // For our purposes we ignore any buffer data past the maximum constant buffer size bufferDesc->ByteWidth = roundUp(bufferDesc->ByteWidth, 16u); + + // Note: it seems that D3D11 allows larger buffers on some platforms, but not all. + // (Windows 10 seems to allow larger constant buffers, but not Windows 7) bufferDesc->ByteWidth = std::min(bufferDesc->ByteWidth, - static_cast(renderer->getRendererCaps().maxUniformBlockSize)); + static_cast(renderer->getNativeCaps().maxUniformBlockSize)); break; default: @@ -1054,126 +1187,87 @@ void Buffer11::NativeStorage::fillBufferDesc(D3D11_BUFFER_DESC *bufferDesc, } } -uint8_t *Buffer11::NativeStorage::map(size_t offset, size_t length, GLbitfield access) +gl::Error Buffer11::NativeStorage::map(size_t offset, + size_t length, + GLbitfield access, + uint8_t **mapPointerOut) { - ASSERT(mUsage == BUFFER_USAGE_STAGING); + ASSERT(isCPUAccessible(access)); D3D11_MAPPED_SUBRESOURCE mappedResource; ID3D11DeviceContext *context = mRenderer->getDeviceContext(); - D3D11_MAP d3dMapType = gl_d3d11::GetD3DMapTypeFromBits(access); - UINT d3dMapFlag = ((access & GL_MAP_UNSYNCHRONIZED_BIT) != 0 ? D3D11_MAP_FLAG_DO_NOT_WAIT : 0); + D3D11_MAP d3dMapType = gl_d3d11::GetD3DMapTypeFromBits(mUsage, access); + UINT d3dMapFlag = ((access & GL_MAP_UNSYNCHRONIZED_BIT) != 0 ? D3D11_MAP_FLAG_DO_NOT_WAIT : 0); - HRESULT result = context->Map(mNativeStorage, 0, d3dMapType, d3dMapFlag, &mappedResource); + HRESULT result = context->Map(mBuffer.get(), 0, d3dMapType, d3dMapFlag, &mappedResource); ASSERT(SUCCEEDED(result)); if (FAILED(result)) { - return nullptr; + return gl::OutOfMemory() << "Failed to map native storage in Buffer11::NativeStorage::map"; } - return static_cast(mappedResource.pData) + offset; + ASSERT(mappedResource.pData); + *mapPointerOut = static_cast(mappedResource.pData) + offset; + return gl::NoError(); } void Buffer11::NativeStorage::unmap() { - ASSERT(mUsage == BUFFER_USAGE_STAGING); + ASSERT(isCPUAccessible(GL_MAP_WRITE_BIT) || isCPUAccessible(GL_MAP_READ_BIT)); ID3D11DeviceContext *context = mRenderer->getDeviceContext(); - context->Unmap(mNativeStorage, 0); + context->Unmap(mBuffer.get(), 0); } +gl::ErrorOrResult Buffer11::NativeStorage::getSRVForFormat( + DXGI_FORMAT srvFormat) +{ + auto bufferSRVIt = mBufferResourceViews.find(srvFormat); + + if (bufferSRVIt != mBufferResourceViews.end()) + { + return &bufferSRVIt->second; + } + + const d3d11::DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(srvFormat); + + D3D11_SHADER_RESOURCE_VIEW_DESC bufferSRVDesc; + bufferSRVDesc.Buffer.ElementOffset = 0; + bufferSRVDesc.Buffer.ElementWidth = static_cast(mBufferSize) / dxgiFormatInfo.pixelBytes; + bufferSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; + bufferSRVDesc.Format = srvFormat; + + ANGLE_TRY(mRenderer->allocateResource(bufferSRVDesc, mBuffer.get(), + &mBufferResourceViews[srvFormat])); + + return &mBufferResourceViews[srvFormat]; +} + +void Buffer11::NativeStorage::clearSRVs() +{ + mBufferResourceViews.clear(); +} + +// Buffer11::EmulatedIndexStorage implementation + Buffer11::EmulatedIndexedStorage::EmulatedIndexedStorage(Renderer11 *renderer) - : BufferStorage(renderer, BUFFER_USAGE_EMULATED_INDEXED_VERTEX), mNativeStorage(nullptr) + : BufferStorage(renderer, BUFFER_USAGE_EMULATED_INDEXED_VERTEX), mBuffer() { } Buffer11::EmulatedIndexedStorage::~EmulatedIndexedStorage() { - SafeRelease(mNativeStorage); } -ID3D11Buffer *Buffer11::EmulatedIndexedStorage::getNativeStorage() -{ - if (!mNativeStorage) - { - // Expand the memory storage upon request and cache the results. - unsigned int expandedDataSize = - static_cast((mIndexInfo.srcCount * mAttributeStride) + mAttributeOffset); - MemoryBuffer expandedData; - if (!expandedData.resize(expandedDataSize)) - { - return nullptr; - } - - // Clear the contents of the allocated buffer - ZeroMemory(expandedData.data(), expandedDataSize); - - uint8_t *curr = expandedData.data(); - const uint8_t *ptr = static_cast(mIndexInfo.srcIndices); - - // Ensure that we start in the correct place for the emulated data copy operation to - // maintain offset behaviors. - curr += mAttributeOffset; - - ReadIndexValueFunction readIndexValue = ReadIndexValueFromIndices; - - switch (mIndexInfo.srcIndexType) - { - case GL_UNSIGNED_INT: - readIndexValue = ReadIndexValueFromIndices; - break; - case GL_UNSIGNED_SHORT: - readIndexValue = ReadIndexValueFromIndices; - break; - case GL_UNSIGNED_BYTE: - readIndexValue = ReadIndexValueFromIndices; - break; - } - - // Iterate over the cached index data and copy entries indicated into the emulated buffer. - for (GLuint i = 0; i < mIndexInfo.srcCount; i++) - { - GLuint idx = readIndexValue(ptr, i); - memcpy(curr, mMemoryBuffer.data() + (mAttributeStride * idx), mAttributeStride); - curr += mAttributeStride; - } - - // Finally, initialize the emulated indexed native storage object with the newly copied data - // and free the temporary buffers used. - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_BUFFER_DESC bufferDesc; - bufferDesc.ByteWidth = expandedDataSize; - bufferDesc.MiscFlags = 0; - bufferDesc.StructureByteStride = 0; - bufferDesc.Usage = D3D11_USAGE_DEFAULT; - bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - bufferDesc.CPUAccessFlags = 0; - - D3D11_SUBRESOURCE_DATA subResourceData = {expandedData.data(), 0, 0}; - - HRESULT result = device->CreateBuffer(&bufferDesc, &subResourceData, &mNativeStorage); - if (FAILED(result)) - { - ERR("Could not create emulated index data buffer: %08lX", result); - return nullptr; - } - d3d11::SetDebugName(mNativeStorage, "Buffer11::EmulatedIndexedStorage"); - } - - return mNativeStorage; -} - -bool Buffer11::EmulatedIndexedStorage::update(SourceIndexData *indexInfo, - const TranslatedAttribute *attribute) +gl::ErrorOrResult Buffer11::EmulatedIndexedStorage::getBuffer( + SourceIndexData *indexInfo, + const TranslatedAttribute &attribute, + GLint startVertex) { // If a change in the indices applied from the last draw call is detected, then the emulated // indexed buffer needs to be invalidated. After invalidation, the change detected flag should // be cleared to avoid unnecessary recreation of the buffer. - if (mNativeStorage == nullptr || indexInfo->srcIndicesChanged) + if (!mBuffer.valid() || indexInfo->srcIndicesChanged) { - SafeRelease(mNativeStorage); - - // Copy attribute offset and stride information - mAttributeStride = attribute->stride; - mAttributeOffset = attribute->offset; + mBuffer.reset(); // Copy the source index data. This ensures that the lifetime of the indices pointer // stays with this storage until the next time we invalidate. @@ -1196,52 +1290,122 @@ bool Buffer11::EmulatedIndexedStorage::update(SourceIndexData *indexInfo, if (!mIndicesMemoryBuffer.resize(indicesDataSize)) { - return false; + return gl::OutOfMemory() << "Error resizing index memory buffer in " + "Buffer11::EmulatedIndexedStorage::getBuffer"; } memcpy(mIndicesMemoryBuffer.data(), indexInfo->srcIndices, indicesDataSize); - // Copy the source index data description and update the srcIndices pointer to point - // to our cached index data. - mIndexInfo = *indexInfo; - mIndexInfo.srcIndices = mIndicesMemoryBuffer.data(); - indexInfo->srcIndicesChanged = false; } - return true; + + if (!mBuffer.valid()) + { + unsigned int offset = 0; + ANGLE_TRY_RESULT(attribute.computeOffset(startVertex), offset); + + // Expand the memory storage upon request and cache the results. + unsigned int expandedDataSize = + static_cast((indexInfo->srcCount * attribute.stride) + offset); + angle::MemoryBuffer expandedData; + if (!expandedData.resize(expandedDataSize)) + { + return gl::OutOfMemory() + << "Error resizing buffer in Buffer11::EmulatedIndexedStorage::getBuffer"; + } + + // Clear the contents of the allocated buffer + ZeroMemory(expandedData.data(), expandedDataSize); + + uint8_t *curr = expandedData.data(); + const uint8_t *ptr = static_cast(indexInfo->srcIndices); + + // Ensure that we start in the correct place for the emulated data copy operation to + // maintain offset behaviors. + curr += offset; + + ReadIndexValueFunction readIndexValue = ReadIndexValueFromIndices; + + switch (indexInfo->srcIndexType) + { + case GL_UNSIGNED_INT: + readIndexValue = ReadIndexValueFromIndices; + break; + case GL_UNSIGNED_SHORT: + readIndexValue = ReadIndexValueFromIndices; + break; + case GL_UNSIGNED_BYTE: + readIndexValue = ReadIndexValueFromIndices; + break; + } + + // Iterate over the cached index data and copy entries indicated into the emulated buffer. + for (GLuint i = 0; i < indexInfo->srcCount; i++) + { + GLuint idx = readIndexValue(ptr, i); + memcpy(curr, mMemoryBuffer.data() + (attribute.stride * idx), attribute.stride); + curr += attribute.stride; + } + + // Finally, initialize the emulated indexed native storage object with the newly copied data + // and free the temporary buffers used. + D3D11_BUFFER_DESC bufferDesc; + bufferDesc.ByteWidth = expandedDataSize; + bufferDesc.MiscFlags = 0; + bufferDesc.StructureByteStride = 0; + bufferDesc.Usage = D3D11_USAGE_DEFAULT; + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.CPUAccessFlags = 0; + + D3D11_SUBRESOURCE_DATA subResourceData = {expandedData.data(), 0, 0}; + + ANGLE_TRY(mRenderer->allocateResource(bufferDesc, &subResourceData, &mBuffer)); + mBuffer.setDebugName("Buffer11::EmulatedIndexedStorage"); + } + + return &mBuffer; } -bool Buffer11::EmulatedIndexedStorage::copyFromStorage(BufferStorage *source, - size_t sourceOffset, - size_t size, - size_t destOffset) +gl::ErrorOrResult Buffer11::EmulatedIndexedStorage::copyFromStorage( + const gl::Context *context, + BufferStorage *source, + size_t sourceOffset, + size_t size, + size_t destOffset) { - ASSERT(source->isMappable()); - const uint8_t *sourceData = source->map(sourceOffset, size, GL_MAP_READ_BIT); + ASSERT(source->isCPUAccessible(GL_MAP_READ_BIT)); + uint8_t *sourceData = nullptr; + ANGLE_TRY(source->map(sourceOffset, size, GL_MAP_READ_BIT, &sourceData)); ASSERT(destOffset + size <= mMemoryBuffer.size()); memcpy(mMemoryBuffer.data() + destOffset, sourceData, size); source->unmap(); - return true; + return CopyResult::RECREATED; } -gl::Error Buffer11::EmulatedIndexedStorage::resize(size_t size, bool preserveData) +gl::Error Buffer11::EmulatedIndexedStorage::resize(const gl::Context *context, + size_t size, + bool preserveData) { if (mMemoryBuffer.size() < size) { if (!mMemoryBuffer.resize(size)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize EmulatedIndexedStorage"); + return gl::OutOfMemory() << "Failed to resize EmulatedIndexedStorage"; } mBufferSize = size; } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -uint8_t *Buffer11::EmulatedIndexedStorage::map(size_t offset, size_t length, GLbitfield access) +gl::Error Buffer11::EmulatedIndexedStorage::map(size_t offset, + size_t length, + GLbitfield access, + uint8_t **mapPointerOut) { ASSERT(!mMemoryBuffer.empty() && offset + length <= mMemoryBuffer.size()); - return mMemoryBuffer.data() + offset; + *mapPointerOut = mMemoryBuffer.data() + offset; + return gl::NoError(); } void Buffer11::EmulatedIndexedStorage::unmap() @@ -1249,6 +1413,8 @@ void Buffer11::EmulatedIndexedStorage::unmap() // No-op } +// Buffer11::PackStorage implementation + Buffer11::PackStorage::PackStorage(Renderer11 *renderer) : BufferStorage(renderer, BUFFER_USAGE_PIXEL_PACK), mStagingTexture(), mDataModified(false) { @@ -1258,32 +1424,42 @@ Buffer11::PackStorage::~PackStorage() { } -bool Buffer11::PackStorage::copyFromStorage(BufferStorage *source, - size_t sourceOffset, - size_t size, - size_t destOffset) +gl::ErrorOrResult Buffer11::PackStorage::copyFromStorage(const gl::Context *context, + BufferStorage *source, + size_t sourceOffset, + size_t size, + size_t destOffset) { - // We copy through a staging buffer when drawing with a pack buffer, - // or for other cases where we access the pack buffer - UNREACHABLE(); - return false; + ANGLE_TRY(flushQueuedPackCommand()); + + // For all use cases of pack buffers, we must copy through a readable buffer. + ASSERT(source->isCPUAccessible(GL_MAP_READ_BIT)); + uint8_t *sourceData = nullptr; + ANGLE_TRY(source->map(sourceOffset, size, GL_MAP_READ_BIT, &sourceData)); + ASSERT(destOffset + size <= mMemoryBuffer.size()); + memcpy(mMemoryBuffer.data() + destOffset, sourceData, size); + source->unmap(); + return CopyResult::NOT_RECREATED; } -gl::Error Buffer11::PackStorage::resize(size_t size, bool preserveData) +gl::Error Buffer11::PackStorage::resize(const gl::Context *context, size_t size, bool preserveData) { if (size != mBufferSize) { if (!mMemoryBuffer.resize(size)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal buffer storage."); + return gl::OutOfMemory() << "Failed to resize internal buffer storage."; } mBufferSize = size; } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -uint8_t *Buffer11::PackStorage::map(size_t offset, size_t length, GLbitfield access) +gl::Error Buffer11::PackStorage::map(size_t offset, + size_t length, + GLbitfield access, + uint8_t **mapPointerOut) { ASSERT(offset + length <= getSize()); // TODO: fast path @@ -1291,15 +1467,12 @@ uint8_t *Buffer11::PackStorage::map(size_t offset, size_t length, GLbitfield acc // and if D3D packs the staging texture memory identically to how we would fill // the pack buffer according to the current pack state. - gl::Error error = flushQueuedPackCommand(); - if (error.isError()) - { - return nullptr; - } + ANGLE_TRY(flushQueuedPackCommand()); mDataModified = (mDataModified || (access & GL_MAP_WRITE_BIT) != 0); - return mMemoryBuffer.data() + offset; + *mapPointerOut = mMemoryBuffer.data() + offset; + return gl::NoError(); } void Buffer11::PackStorage::unmap() @@ -1307,42 +1480,29 @@ void Buffer11::PackStorage::unmap() // No-op } -gl::Error Buffer11::PackStorage::packPixels(const gl::FramebufferAttachment &readAttachment, +gl::Error Buffer11::PackStorage::packPixels(const gl::Context *context, + const gl::FramebufferAttachment &readAttachment, const PackPixelsParams ¶ms) { - gl::Error error = flushQueuedPackCommand(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(flushQueuedPackCommand()); RenderTarget11 *renderTarget = nullptr; - error = readAttachment.getRenderTarget(&renderTarget); - if (error.isError()) - { - return error; - } - - ID3D11Resource *renderTargetResource = renderTarget->getTexture(); - ASSERT(renderTargetResource); + ANGLE_TRY(readAttachment.getRenderTarget(context, &renderTarget)); + const TextureHelper11 &srcTexture = renderTarget->getTexture(); + ASSERT(srcTexture.valid()); unsigned int srcSubresource = renderTarget->getSubresourceIndex(); - TextureHelper11 srcTexture = TextureHelper11::MakeAndReference(renderTargetResource); mQueuedPackCommand.reset(new PackPixelsParams(params)); gl::Extents srcTextureSize(params.area.width, params.area.height, 1); - if (!mStagingTexture.getResource() || mStagingTexture.getFormat() != srcTexture.getFormat() || + if (!mStagingTexture.get() || mStagingTexture.getFormat() != srcTexture.getFormat() || mStagingTexture.getExtents() != srcTextureSize) { - auto textureOrError = - CreateStagingTexture(srcTexture.getTextureType(), srcTexture.getFormat(), - srcTextureSize, mRenderer->getDevice()); - if (textureOrError.isError()) - { - return textureOrError.getError(); - } - mStagingTexture = std::move(textureOrError.getResult()); + ANGLE_TRY_RESULT( + mRenderer->createStagingTexture(srcTexture.getTextureType(), srcTexture.getFormatSet(), + srcTextureSize, StagingAccess::READ), + mStagingTexture); } // ReadPixels from multisampled FBOs isn't supported in current GL @@ -1357,17 +1517,17 @@ gl::Error Buffer11::PackStorage::packPixels(const gl::FramebufferAttachment &rea // Select the correct layer from a 3D attachment srcBox.front = 0; - if (mStagingTexture.getTextureType() == GL_TEXTURE_3D) + if (mStagingTexture.is3D()) { srcBox.front = static_cast(readAttachment.layer()); } srcBox.back = srcBox.front + 1; // Asynchronous copy - immediateContext->CopySubresourceRegion(mStagingTexture.getResource(), 0, 0, 0, 0, - srcTexture.getResource(), srcSubresource, &srcBox); + immediateContext->CopySubresourceRegion(mStagingTexture.get(), 0, 0, 0, 0, srcTexture.get(), + srcSubresource, &srcBox); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Buffer11::PackStorage::flushQueuedPackCommand() @@ -1376,58 +1536,65 @@ gl::Error Buffer11::PackStorage::flushQueuedPackCommand() if (mQueuedPackCommand) { - gl::Error error = - mRenderer->packPixels(mStagingTexture, *mQueuedPackCommand, mMemoryBuffer.data()); + ANGLE_TRY( + mRenderer->packPixels(mStagingTexture, *mQueuedPackCommand, mMemoryBuffer.data())); mQueuedPackCommand.reset(nullptr); - if (error.isError()) - { - return error; - } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } +// Buffer11::SystemMemoryStorage implementation + Buffer11::SystemMemoryStorage::SystemMemoryStorage(Renderer11 *renderer) : Buffer11::BufferStorage(renderer, BUFFER_USAGE_SYSTEM_MEMORY) { } -bool Buffer11::SystemMemoryStorage::copyFromStorage(BufferStorage *source, - size_t sourceOffset, - size_t size, - size_t destOffset) +gl::ErrorOrResult Buffer11::SystemMemoryStorage::copyFromStorage( + const gl::Context *context, + BufferStorage *source, + size_t sourceOffset, + size_t size, + size_t destOffset) { - ASSERT(source->isMappable()); - const uint8_t *sourceData = source->map(sourceOffset, size, GL_MAP_READ_BIT); + ASSERT(source->isCPUAccessible(GL_MAP_READ_BIT)); + uint8_t *sourceData = nullptr; + ANGLE_TRY(source->map(sourceOffset, size, GL_MAP_READ_BIT, &sourceData)); ASSERT(destOffset + size <= mSystemCopy.size()); memcpy(mSystemCopy.data() + destOffset, sourceData, size); source->unmap(); - return true; + return CopyResult::RECREATED; } -gl::Error Buffer11::SystemMemoryStorage::resize(size_t size, bool preserveData) +gl::Error Buffer11::SystemMemoryStorage::resize(const gl::Context *context, + size_t size, + bool preserveData) { if (mSystemCopy.size() < size) { if (!mSystemCopy.resize(size)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize SystemMemoryStorage"); + return gl::OutOfMemory() << "Failed to resize SystemMemoryStorage"; } mBufferSize = size; } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -uint8_t *Buffer11::SystemMemoryStorage::map(size_t offset, size_t length, GLbitfield access) +gl::Error Buffer11::SystemMemoryStorage::map(size_t offset, + size_t length, + GLbitfield access, + uint8_t **mapPointerOut) { ASSERT(!mSystemCopy.empty() && offset + length <= mSystemCopy.size()); - return mSystemCopy.data() + offset; + *mapPointerOut = mSystemCopy.data() + offset; + return gl::NoError(); } void Buffer11::SystemMemoryStorage::unmap() { // No-op } -} +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h index a748db57ae..ddbeeb90d2 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.h @@ -9,10 +9,12 @@ #ifndef LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_ #define LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_ +#include #include #include "libANGLE/angletypes.h" #include "libANGLE/renderer/d3d/BufferD3D.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" namespace gl { @@ -21,69 +23,92 @@ class FramebufferAttachment; namespace rx { +struct PackPixelsParams; class Renderer11; struct SourceIndexData; struct TranslatedAttribute; +// The order of this enum governs priority of 'getLatestBufferStorage'. enum BufferUsage { + BUFFER_USAGE_SYSTEM_MEMORY, BUFFER_USAGE_STAGING, BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK, BUFFER_USAGE_INDEX, + // TODO: possibly share this buffer type with shader storage buffers. + BUFFER_USAGE_INDIRECT, BUFFER_USAGE_PIXEL_UNPACK, BUFFER_USAGE_PIXEL_PACK, BUFFER_USAGE_UNIFORM, - BUFFER_USAGE_SYSTEM_MEMORY, BUFFER_USAGE_EMULATED_INDEXED_VERTEX, BUFFER_USAGE_COUNT, }; -struct PackPixelsParams -{ - PackPixelsParams(); - PackPixelsParams(const gl::Rectangle &area, GLenum format, GLenum type, GLuint outputPitch, - const gl::PixelPackState &pack, ptrdiff_t offset); - - gl::Rectangle area; - GLenum format; - GLenum type; - GLuint outputPitch; - gl::Buffer *packBuffer; - gl::PixelPackState pack; - ptrdiff_t offset; -}; - typedef size_t DataRevision; class Buffer11 : public BufferD3D { public: - Buffer11(Renderer11 *renderer); - virtual ~Buffer11(); + Buffer11(const gl::BufferState &state, Renderer11 *renderer); + ~Buffer11() override; - ID3D11Buffer *getBuffer(BufferUsage usage); - ID3D11Buffer *getEmulatedIndexedBuffer(SourceIndexData *indexInfo, const TranslatedAttribute *attribute); - ID3D11Buffer *getConstantBufferRange(GLintptr offset, GLsizeiptr size); - ID3D11ShaderResourceView *getSRV(DXGI_FORMAT srvFormat); - bool isMapped() const { return mMappedStorage != NULL; } - gl::Error packPixels(const gl::FramebufferAttachment &readAttachment, + gl::ErrorOrResult getBuffer(const gl::Context *context, BufferUsage usage); + gl::ErrorOrResult getEmulatedIndexedBuffer(const gl::Context *context, + SourceIndexData *indexInfo, + const TranslatedAttribute &attribute, + GLint startVertex); + gl::Error getConstantBufferRange(const gl::Context *context, + GLintptr offset, + GLsizeiptr size, + const d3d11::Buffer **bufferOut, + UINT *firstConstantOut, + UINT *numConstantsOut); + gl::ErrorOrResult getSRV(const gl::Context *context, + DXGI_FORMAT srvFormat); + bool isMapped() const { return mMappedStorage != nullptr; } + gl::Error packPixels(const gl::Context *context, + const gl::FramebufferAttachment &readAttachment, const PackPixelsParams ¶ms); size_t getTotalCPUBufferMemoryBytes() const; // BufferD3D implementation - virtual size_t getSize() const { return mSize; } - virtual bool supportsDirectBinding() const; - gl::Error getData(const uint8_t **outData) override; + size_t getSize() const override; + bool supportsDirectBinding() const override; + gl::Error getData(const gl::Context *context, const uint8_t **outData) override; + void initializeStaticData(const gl::Context *context) override; + void invalidateStaticData(const gl::Context *context) override; // BufferImpl implementation - virtual gl::Error setData(const void* data, size_t size, GLenum usage); - virtual gl::Error setSubData(const void* data, size_t size, size_t offset); - virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); - virtual gl::Error map(GLenum access, GLvoid **mapPtr); - virtual gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr); - virtual gl::Error unmap(GLboolean *result); - virtual void markTransformFeedbackUsage(); + gl::Error setData(const gl::Context *context, + gl::BufferBinding target, + const void *data, + size_t size, + gl::BufferUsage usage) override; + gl::Error setSubData(const gl::Context *context, + gl::BufferBinding target, + const void *data, + size_t size, + size_t offset) override; + gl::Error copySubData(const gl::Context *context, + BufferImpl *source, + GLintptr sourceOffset, + GLintptr destOffset, + GLsizeiptr size) override; + gl::Error map(const gl::Context *context, GLenum access, void **mapPtr) override; + gl::Error mapRange(const gl::Context *context, + size_t offset, + size_t length, + GLbitfield access, + void **mapPtr) override; + gl::Error unmap(const gl::Context *context, GLboolean *result) override; + gl::Error markTransformFeedbackUsage(const gl::Context *context) override; + + // We use two set of dirty events. Static buffers are marked dirty whenever + // data changes, because they must be re-translated. Direct buffers only need to be + // updated when the underlying ID3D11Buffer pointer changes - hopefully far less often. + OnBufferDataDirtyChannel *getStaticBroadcastChannel(); + OnBufferDataDirtyChannel *getDirectBroadcastChannel(); private: class BufferStorage; @@ -92,20 +117,60 @@ class Buffer11 : public BufferD3D class PackStorage; class SystemMemoryStorage; + struct ConstantBufferCacheEntry + { + ConstantBufferCacheEntry() : storage(nullptr), lruCount(0) {} + + BufferStorage *storage; + unsigned int lruCount; + }; + + void markBufferUsage(BufferUsage usage); + gl::Error garbageCollection(const gl::Context *context, BufferUsage currentUsage); + gl::ErrorOrResult getStagingStorage(const gl::Context *context); + gl::ErrorOrResult getPackStorage(const gl::Context *context); + gl::ErrorOrResult getSystemMemoryStorage(const gl::Context *context); + + gl::Error updateBufferStorage(const gl::Context *context, + BufferStorage *storage, + size_t sourceOffset, + size_t storageSize); + gl::ErrorOrResult getBufferStorage(const gl::Context *context, + BufferUsage usage); + gl::ErrorOrResult getLatestBufferStorage(const gl::Context *context) const; + + gl::ErrorOrResult getConstantBufferRangeStorage(const gl::Context *context, + GLintptr offset, + GLsizeiptr size); + + BufferStorage *allocateStorage(BufferUsage usage); + void updateDeallocThreshold(BufferUsage usage); + + // Free the storage if we decide it isn't being used very often. + gl::Error checkForDeallocation(const gl::Context *context, BufferUsage usage); + + // For some cases of uniform buffer storage, we can't deallocate system memory storage. + bool canDeallocateSystemMemory() const; + + // Updates data revisions and latest storage. + void onCopyStorage(BufferStorage *dest, BufferStorage *source); + void onStorageUpdate(BufferStorage *updatedStorage); + Renderer11 *mRenderer; size_t mSize; BufferStorage *mMappedStorage; - std::vector mBufferStorages; + // Buffer storages are sorted by usage. It's important that the latest buffer storage picks + // the lowest usage in the case where two storages are tied on data revision - this ensures + // we never do anything dangerous like map a uniform buffer over a staging or system memory + // copy. + std::array mBufferStorages; + BufferStorage *mLatestBufferStorage; - struct ConstantBufferCacheEntry - { - ConstantBufferCacheEntry() : storage(nullptr), lruCount(0) { } - - BufferStorage *storage; - unsigned int lruCount; - }; + // These two arrays are used to track when to free unused storage. + std::array mDeallocThresholds; + std::array mIdleness; // Cache of D3D11 constant buffer for specific ranges of buffer data. // This is used to emulate UBO ranges on 11.0 devices. @@ -115,25 +180,10 @@ class Buffer11 : public BufferD3D size_t mConstantBufferStorageAdditionalSize; unsigned int mMaxConstantBufferLruCount; - typedef std::pair BufferSRVPair; - std::map mBufferResourceViews; - - unsigned int mReadUsageCount; - - void markBufferUsage(); - NativeStorage *getStagingStorage(); - PackStorage *getPackStorage(); - gl::Error getSystemMemoryStorage(SystemMemoryStorage **storageOut); - - void updateBufferStorage(BufferStorage *storage, size_t sourceOffset, size_t storageSize); - BufferStorage *getBufferStorage(BufferUsage usage); - BufferStorage *getLatestBufferStorage() const; - - BufferStorage *getConstantBufferRangeStorage(GLintptr offset, GLsizeiptr size); - - void invalidateEmulatedIndexedBuffer(); + OnBufferDataDirtyChannel mStaticBroadcastChannel; + OnBufferDataDirtyChannel mDirectBroadcastChannel; }; -} +} // namespace rx -#endif // LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_ +#endif // LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp index cd95c65d1c..f9dda0aeb4 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp @@ -1,4 +1,4 @@ -// + // Copyright (c) 2013 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -20,624 +20,814 @@ #include "third_party/trace_event/trace_event.h" // Precompiled shaders -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11vs.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11_fl9vs.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewgs.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewvs.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11vs.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/cleardepth11ps.h" #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11_fl9ps.h" - -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11vs.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps.h" - -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11vs.h" -#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps1.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps2.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps3.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps4.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps5.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps6.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps7.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps8.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps1.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps2.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps3.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps4.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps5.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps6.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps7.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps8.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps1.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps2.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps3.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps4.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps5.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps6.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps7.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps8.h" namespace rx { -template -static void ApplyVertices(const gl::Extents &framebufferSize, const gl::Rectangle *scissor, const gl::Color &color, float depth, void *buffer) +namespace { - d3d11::PositionDepthColorVertex *vertices = reinterpret_cast*>(buffer); +constexpr uint32_t g_ConstantBufferSize = sizeof(RtvDsvClearInfo); +constexpr uint32_t g_VertexSize = sizeof(d3d11::PositionVertex); - float depthClear = gl::clamp01(depth); - float left = -1.0f; - float right = 1.0f; - float top = -1.0f; - float bottom = 1.0f; +// Updates color, depth and alpha components of cached CB if necessary. +// Returns true if any constants are updated, false otherwise. +template +bool UpdateDataCache(RtvDsvClearInfo *dataCache, + const gl::Color &color, + const float *zValue, + const uint32_t numRtvs, + const uint8_t writeMask) +{ + bool cacheDirty = false; - // Clip the quad coordinates to the scissor if needed - if (scissor != nullptr) + if (numRtvs > 0) { - left = std::max(left, (scissor->x / float(framebufferSize.width)) * 2.0f - 1.0f); - right = std::min(right, ((scissor->x + scissor->width) / float(framebufferSize.width)) * 2.0f - 1.0f); - top = std::max(top, ((framebufferSize.height - scissor->y - scissor->height) / float(framebufferSize.height)) * 2.0f - 1.0f); - bottom = std::min(bottom, ((framebufferSize.height - scissor->y) / float(framebufferSize.height)) * 2.0f - 1.0f); + const bool writeRGB = (writeMask & ~D3D11_COLOR_WRITE_ENABLE_ALPHA) != 0; + if (writeRGB && memcmp(&dataCache->r, &color.red, sizeof(T) * 3) != 0) + { + dataCache->r = color.red; + dataCache->g = color.green; + dataCache->b = color.blue; + cacheDirty = true; + } + + const bool writeAlpha = (writeMask & D3D11_COLOR_WRITE_ENABLE_ALPHA) != 0; + if (writeAlpha && (dataCache->a != color.alpha)) + { + dataCache->a = color.alpha; + cacheDirty = true; + } } - d3d11::SetPositionDepthColorVertex(vertices + 0, left, bottom, depthClear, color); - d3d11::SetPositionDepthColorVertex(vertices + 1, left, top, depthClear, color); - d3d11::SetPositionDepthColorVertex(vertices + 2, right, bottom, depthClear, color); - d3d11::SetPositionDepthColorVertex(vertices + 3, right, top, depthClear, color); -} - -Clear11::ClearShader::ClearShader(DXGI_FORMAT colorType, - const char *inputLayoutName, - const BYTE *vsByteCode, - size_t vsSize, - const char *vsDebugName, - const BYTE *psByteCode, - size_t psSize, - const char *psDebugName) - : inputLayout(nullptr), - vertexShader(vsByteCode, vsSize, vsDebugName), - pixelShader(psByteCode, psSize, psDebugName) -{ - D3D11_INPUT_ELEMENT_DESC quadLayout[] = + if (zValue) { - { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "COLOR", 0, colorType, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - }; + const float clampedZValue = gl::clamp01(*zValue); - inputLayout = new d3d11::LazyInputLayout(quadLayout, 2, vsByteCode, vsSize, inputLayoutName); + if (clampedZValue != dataCache->z) + { + dataCache->z = clampedZValue; + cacheDirty = true; + } + } + + return cacheDirty; } -Clear11::ClearShader::~ClearShader() +bool AllOffsetsAreNonNegative(const std::vector &viewportOffsets) { - SafeDelete(inputLayout); - vertexShader.release(); - pixelShader.release(); + for (size_t i = 0u; i < viewportOffsets.size(); ++i) + { + const auto &offset = viewportOffsets[i]; + if (offset.x < 0 || offset.y < 0) + { + return false; + } + } + return true; +} +} // anonymous namespace + +#define CLEARPS(Index) \ + d3d11::LazyShader(g_PS_Clear##Index, ArraySize(g_PS_Clear##Index), \ + "Clear11 PS " ANGLE_STRINGIFY(Index)) + +Clear11::ShaderManager::ShaderManager() + : mIl9(), + mVs9(g_VS_Clear_FL9, ArraySize(g_VS_Clear_FL9), "Clear11 VS FL9"), + mPsFloat9(g_PS_ClearFloat_FL9, ArraySize(g_PS_ClearFloat_FL9), "Clear11 PS FloatFL9"), + mVs(g_VS_Clear, ArraySize(g_VS_Clear), "Clear11 VS"), + mVsMultiview(g_VS_Multiview_Clear, ArraySize(g_VS_Multiview_Clear), "Clear11 VS Multiview"), + mGsMultiview(g_GS_Multiview_Clear, ArraySize(g_GS_Multiview_Clear), "Clear11 GS Multiview"), + mPsDepth(g_PS_ClearDepth, ArraySize(g_PS_ClearDepth), "Clear11 PS Depth"), + mPsFloat{{CLEARPS(Float1), CLEARPS(Float2), CLEARPS(Float3), CLEARPS(Float4), CLEARPS(Float5), + CLEARPS(Float6), CLEARPS(Float7), CLEARPS(Float8)}}, + mPsUInt{{CLEARPS(Uint1), CLEARPS(Uint2), CLEARPS(Uint3), CLEARPS(Uint4), CLEARPS(Uint5), + CLEARPS(Uint6), CLEARPS(Uint7), CLEARPS(Uint8)}}, + mPsSInt{{CLEARPS(Sint1), CLEARPS(Sint2), CLEARPS(Sint3), CLEARPS(Sint4), CLEARPS(Sint5), + CLEARPS(Sint6), CLEARPS(Sint7), CLEARPS(Sint8)}} +{ +} + +#undef CLEARPS + +Clear11::ShaderManager::~ShaderManager() +{ +} + +gl::Error Clear11::ShaderManager::getShadersAndLayout(Renderer11 *renderer, + const INT clearType, + const uint32_t numRTs, + const bool hasLayeredLayout, + const d3d11::InputLayout **il, + const d3d11::VertexShader **vs, + const d3d11::GeometryShader **gs, + const d3d11::PixelShader **ps) +{ + if (renderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) + { + ASSERT(clearType == GL_FLOAT); + + ANGLE_TRY(mVs9.resolve(renderer)); + ANGLE_TRY(mPsFloat9.resolve(renderer)); + + if (!mIl9.valid()) + { + const D3D11_INPUT_ELEMENT_DESC ilDesc[] = { + {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}}; + + InputElementArray ilDescArray(ilDesc); + ShaderData vertexShader(g_VS_Clear_FL9); + + ANGLE_TRY(renderer->allocateResource(ilDescArray, &vertexShader, &mIl9)); + } + + *vs = &mVs9.getObj(); + *gs = nullptr; + *il = &mIl9; + *ps = &mPsFloat9.getObj(); + return gl::NoError(); + } + if (!hasLayeredLayout) + { + ANGLE_TRY(mVs.resolve(renderer)); + *vs = &mVs.getObj(); + *gs = nullptr; + } + else + { + // For layered framebuffers we have to use the multi-view versions of the VS and GS. + ANGLE_TRY(mVsMultiview.resolve(renderer)); + ANGLE_TRY(mGsMultiview.resolve(renderer)); + *vs = &mVsMultiview.getObj(); + *gs = &mGsMultiview.getObj(); + } + + *il = nullptr; + + if (numRTs == 0) + { + ANGLE_TRY(mPsDepth.resolve(renderer)); + *ps = &mPsDepth.getObj(); + return gl::NoError(); + } + + switch (clearType) + { + case GL_FLOAT: + ANGLE_TRY(mPsFloat[numRTs - 1].resolve(renderer)); + *ps = &mPsFloat[numRTs - 1].getObj(); + break; + case GL_UNSIGNED_INT: + ANGLE_TRY(mPsUInt[numRTs - 1].resolve(renderer)); + *ps = &mPsUInt[numRTs - 1].getObj(); + break; + case GL_INT: + ANGLE_TRY(mPsSInt[numRTs - 1].resolve(renderer)); + *ps = &mPsSInt[numRTs - 1].getObj(); + break; + default: + UNREACHABLE(); + break; + } + + return gl::NoError(); } Clear11::Clear11(Renderer11 *renderer) : mRenderer(renderer), - mClearBlendStates(StructLessThan), - mFloatClearShader(nullptr), - mUintClearShader(nullptr), - mIntClearShader(nullptr), - mClearDepthStencilStates(StructLessThan), - mVertexBuffer(nullptr), - mRasterizerState(nullptr) + mResourcesInitialized(false), + mScissorEnabledRasterizerState(), + mScissorDisabledRasterizerState(), + mShaderManager(), + mConstantBuffer(), + mVertexBuffer(), + mShaderData({}) { - TRACE_EVENT0("gpu.angle", "Clear11::Clear11"); - - HRESULT result; - ID3D11Device *device = renderer->getDevice(); - - D3D11_BUFFER_DESC vbDesc; - vbDesc.ByteWidth = sizeof(d3d11::PositionDepthColorVertex) * 4; - vbDesc.Usage = D3D11_USAGE_DYNAMIC; - vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - vbDesc.MiscFlags = 0; - vbDesc.StructureByteStride = 0; - - result = device->CreateBuffer(&vbDesc, nullptr, &mVertexBuffer); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mVertexBuffer, "Clear11 masked clear vertex buffer"); - - D3D11_RASTERIZER_DESC rsDesc; - rsDesc.FillMode = D3D11_FILL_SOLID; - rsDesc.CullMode = D3D11_CULL_NONE; - rsDesc.FrontCounterClockwise = FALSE; - rsDesc.DepthBias = 0; - rsDesc.DepthBiasClamp = 0.0f; - rsDesc.SlopeScaledDepthBias = 0.0f; - rsDesc.DepthClipEnable = TRUE; - rsDesc.ScissorEnable = FALSE; - rsDesc.MultisampleEnable = FALSE; - rsDesc.AntialiasedLineEnable = FALSE; - - result = device->CreateRasterizerState(&rsDesc, &mRasterizerState); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mRasterizerState, "Clear11 masked clear rasterizer state"); - - if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) - { - mFloatClearShader = new ClearShader(DXGI_FORMAT_R32G32B32A32_FLOAT, - "Clear11 Float IL", - g_VS_ClearFloat, - ArraySize(g_VS_ClearFloat), - "Clear11 Float VS", - g_PS_ClearFloat_FL9, - ArraySize(g_PS_ClearFloat_FL9), - "Clear11 Float PS"); - } - else - { - mFloatClearShader = new ClearShader(DXGI_FORMAT_R32G32B32A32_FLOAT, - "Clear11 Float IL", - g_VS_ClearFloat, - ArraySize(g_VS_ClearFloat), - "Clear11 Float VS", - g_PS_ClearFloat, - ArraySize(g_PS_ClearFloat), - "Clear11 Float PS"); - } - - if (renderer->isES3Capable()) - { - mUintClearShader = new ClearShader(DXGI_FORMAT_R32G32B32A32_UINT, - "Clear11 UINT IL", - g_VS_ClearUint, - ArraySize(g_VS_ClearUint), - "Clear11 UINT VS", - g_PS_ClearUint, - ArraySize(g_PS_ClearUint), - "Clear11 UINT PS"); - mIntClearShader = new ClearShader(DXGI_FORMAT_R32G32B32A32_UINT, - "Clear11 SINT IL", - g_VS_ClearSint, - ArraySize(g_VS_ClearSint), - "Clear11 SINT VS", - g_PS_ClearSint, - ArraySize(g_PS_ClearSint), - "Clear11 SINT PS"); - } } Clear11::~Clear11() { - for (ClearBlendStateMap::iterator i = mClearBlendStates.begin(); i != mClearBlendStates.end(); i++) - { - SafeRelease(i->second); - } - mClearBlendStates.clear(); - - SafeDelete(mFloatClearShader); - SafeDelete(mUintClearShader); - SafeDelete(mIntClearShader); - - for (ClearDepthStencilStateMap::iterator i = mClearDepthStencilStates.begin(); i != mClearDepthStencilStates.end(); i++) - { - SafeRelease(i->second); - } - mClearDepthStencilStates.clear(); - - SafeRelease(mVertexBuffer); - SafeRelease(mRasterizerState); } -gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl::Framebuffer::Data &fboData) +gl::Error Clear11::ensureResourcesInitialized() { - const auto &colorAttachments = fboData.getColorAttachments(); - const auto &drawBufferStates = fboData.getDrawBufferStates(); - const auto *depthAttachment = fboData.getDepthAttachment(); - const auto *stencilAttachment = fboData.getStencilAttachment(); + if (mResourcesInitialized) + { + return gl::NoError(); + } - ASSERT(colorAttachments.size() == drawBufferStates.size()); + TRACE_EVENT0("gpu.angle", "Clear11::ensureResourcesInitialized"); + + static_assert((sizeof(RtvDsvClearInfo) == sizeof(RtvDsvClearInfo)), + "Size of rx::RtvDsvClearInfo is not equal to rx::RtvDsvClearInfo"); + + static_assert( + (sizeof(RtvDsvClearInfo) == sizeof(RtvDsvClearInfo)), + "Size of rx::RtvDsvClearInfo is not equal to rx::RtvDsvClearInfo"); + + static_assert((sizeof(RtvDsvClearInfo) % 16 == 0), + "The size of RtvDsvClearInfo should be a multiple of 16bytes."); + + // Create Rasterizer States + D3D11_RASTERIZER_DESC rsDesc; + rsDesc.FillMode = D3D11_FILL_SOLID; + rsDesc.CullMode = D3D11_CULL_NONE; + rsDesc.FrontCounterClockwise = FALSE; + rsDesc.DepthBias = 0; + rsDesc.DepthBiasClamp = 0.0f; + rsDesc.SlopeScaledDepthBias = 0.0f; + rsDesc.DepthClipEnable = TRUE; + rsDesc.ScissorEnable = FALSE; + rsDesc.MultisampleEnable = FALSE; + rsDesc.AntialiasedLineEnable = FALSE; + + ANGLE_TRY(mRenderer->allocateResource(rsDesc, &mScissorDisabledRasterizerState)); + mScissorDisabledRasterizerState.setDebugName("Clear11 Rasterizer State with scissor disabled"); + + rsDesc.ScissorEnable = TRUE; + ANGLE_TRY(mRenderer->allocateResource(rsDesc, &mScissorEnabledRasterizerState)); + mScissorEnabledRasterizerState.setDebugName("Clear11 Rasterizer State with scissor enabled"); + + // Initialize Depthstencil state with defaults + mDepthStencilStateKey.depthTest = false; + mDepthStencilStateKey.depthMask = false; + mDepthStencilStateKey.depthFunc = GL_ALWAYS; + mDepthStencilStateKey.stencilWritemask = static_cast(-1); + mDepthStencilStateKey.stencilBackWritemask = static_cast(-1); + mDepthStencilStateKey.stencilBackMask = 0; + mDepthStencilStateKey.stencilTest = false; + mDepthStencilStateKey.stencilMask = 0; + mDepthStencilStateKey.stencilFail = GL_REPLACE; + mDepthStencilStateKey.stencilPassDepthFail = GL_REPLACE; + mDepthStencilStateKey.stencilPassDepthPass = GL_REPLACE; + mDepthStencilStateKey.stencilFunc = GL_ALWAYS; + mDepthStencilStateKey.stencilBackFail = GL_REPLACE; + mDepthStencilStateKey.stencilBackPassDepthFail = GL_REPLACE; + mDepthStencilStateKey.stencilBackPassDepthPass = GL_REPLACE; + mDepthStencilStateKey.stencilBackFunc = GL_ALWAYS; + + // Initialize BlendStateKey with defaults + mBlendStateKey.blendState.blend = false; + mBlendStateKey.blendState.sourceBlendRGB = GL_ONE; + mBlendStateKey.blendState.sourceBlendAlpha = GL_ONE; + mBlendStateKey.blendState.destBlendRGB = GL_ZERO; + mBlendStateKey.blendState.destBlendAlpha = GL_ZERO; + mBlendStateKey.blendState.blendEquationRGB = GL_FUNC_ADD; + mBlendStateKey.blendState.blendEquationAlpha = GL_FUNC_ADD; + mBlendStateKey.blendState.sampleAlphaToCoverage = false; + mBlendStateKey.blendState.dither = true; + + mResourcesInitialized = true; + return gl::NoError(); +} + +bool Clear11::useVertexBuffer() const +{ + return (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3); +} + +gl::Error Clear11::ensureConstantBufferCreated() +{ + if (mConstantBuffer.valid()) + { + return gl::NoError(); + } + + // Create constant buffer for color & depth data + + D3D11_BUFFER_DESC bufferDesc; + bufferDesc.ByteWidth = g_ConstantBufferSize; + bufferDesc.Usage = D3D11_USAGE_DYNAMIC; + bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bufferDesc.MiscFlags = 0; + bufferDesc.StructureByteStride = 0; + + D3D11_SUBRESOURCE_DATA initialData; + initialData.pSysMem = &mShaderData; + initialData.SysMemPitch = g_ConstantBufferSize; + initialData.SysMemSlicePitch = g_ConstantBufferSize; + + ANGLE_TRY(mRenderer->allocateResource(bufferDesc, &initialData, &mConstantBuffer)); + mConstantBuffer.setDebugName("Clear11 Constant Buffer"); + return gl::NoError(); +} + +gl::Error Clear11::ensureVertexBufferCreated() +{ + ASSERT(useVertexBuffer()); + + if (mVertexBuffer.valid()) + { + return gl::NoError(); + } + + // Create vertex buffer with vertices for a quad covering the entire surface + + static_assert((sizeof(d3d11::PositionVertex) % 16) == 0, + "d3d11::PositionVertex should be a multiple of 16 bytes"); + const d3d11::PositionVertex vbData[6] = {{-1.0f, 1.0f, 0.0f, 1.0f}, {1.0f, -1.0f, 0.0f, 1.0f}, + {-1.0f, -1.0f, 0.0f, 1.0f}, {-1.0f, 1.0f, 0.0f, 1.0f}, + {1.0f, 1.0f, 0.0f, 1.0f}, {1.0f, -1.0f, 0.0f, 1.0f}}; + + const UINT vbSize = sizeof(vbData); + + D3D11_BUFFER_DESC bufferDesc; + bufferDesc.ByteWidth = vbSize; + bufferDesc.Usage = D3D11_USAGE_IMMUTABLE; + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.CPUAccessFlags = 0; + bufferDesc.MiscFlags = 0; + bufferDesc.StructureByteStride = 0; + + D3D11_SUBRESOURCE_DATA initialData; + initialData.pSysMem = vbData; + initialData.SysMemPitch = vbSize; + initialData.SysMemSlicePitch = initialData.SysMemPitch; + + ANGLE_TRY(mRenderer->allocateResource(bufferDesc, &initialData, &mVertexBuffer)); + mVertexBuffer.setDebugName("Clear11 Vertex Buffer"); + return gl::NoError(); +} + +gl::Error Clear11::clearFramebuffer(const gl::Context *context, + const ClearParameters &clearParams, + const gl::FramebufferState &fboData) +{ + ANGLE_TRY(ensureResourcesInitialized()); // Iterate over the color buffers which require clearing and determine if they can be // cleared with ID3D11DeviceContext::ClearRenderTargetView or ID3D11DeviceContext1::ClearView. // This requires: - // 1) The render target is being cleared to a float value (will be cast to integer when clearing integer - // render targets as expected but does not work the other way around) + // 1) The render target is being cleared to a float value (will be cast to integer when clearing + // integer render targets as expected but does not work the other way around) // 2) The format of the render target has no color channels that are currently masked out. - // Clear the easy-to-clear buffers on the spot and accumulate the ones that require special work. + // Clear the easy-to-clear buffers on the spot and accumulate the ones that require special + // work. // // If these conditions are met, and: // - No scissored clear is needed, then clear using ID3D11DeviceContext::ClearRenderTargetView. // - A scissored clear is needed then clear using ID3D11DeviceContext1::ClearView if available. - // Otherwise draw a quad. + // Otherwise perform a shader based clear. // - // Also determine if the depth stencil can be cleared with ID3D11DeviceContext::ClearDepthStencilView - // by checking if the stencil write mask covers the entire stencil. + // Also determine if the DSV can be cleared withID3D11DeviceContext::ClearDepthStencilView by + // checking if the stencil write mask covers the entire stencil. // - // To clear the remaining buffers, quads must be drawn containing an int, uint or float vertex color - // attribute. + // To clear the remaining buffers, a shader based clear is performed: + // - The appropriate ShaderManagers (VS & PS) for the clearType is set + // - A CB containing the clear color and Z values is bound + // - An IL and VB are bound (for FL93 and below) + // - ScissorRect/Raststate/Viewport set as required + // - Blendstate set containing appropriate colorMasks + // - DepthStencilState set with appropriate parameters for a z or stencil clear if required + // - Color and/or Z buffers to be cleared are bound + // - Primitive covering entire clear area is drawn gl::Extents framebufferSize; - const gl::FramebufferAttachment *colorAttachment = fboData.getFirstColorAttachment(); - if (colorAttachment != nullptr) + const auto *depthStencilAttachment = fboData.getDepthOrStencilAttachment(); + if (depthStencilAttachment != nullptr) { - framebufferSize = colorAttachment->getSize(); - } - else if (depthAttachment != nullptr) - { - framebufferSize = depthAttachment->getSize(); - } - else if (stencilAttachment != nullptr) - { - framebufferSize = stencilAttachment->getSize(); + framebufferSize = depthStencilAttachment->getSize(); } else { - UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + const gl::FramebufferAttachment *colorAttachment = fboData.getFirstColorAttachment(); + + if (!colorAttachment) + { + UNREACHABLE(); + return gl::InternalError(); + } + + framebufferSize = colorAttachment->getSize(); } - if (clearParams.scissorEnabled && (clearParams.scissor.x >= framebufferSize.width || - clearParams.scissor.y >= framebufferSize.height || - clearParams.scissor.x + clearParams.scissor.width <= 0 || - clearParams.scissor.y + clearParams.scissor.height <= 0)) + const bool isSideBySideFBO = + (fboData.getMultiviewLayout() == GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE); + bool needScissoredClear = false; + std::vector scissorRects; + if (clearParams.scissorEnabled) { - // Scissor is enabled and the scissor rectangle is outside the renderbuffer - return gl::Error(GL_NO_ERROR); + const std::vector *viewportOffsets = fboData.getViewportOffsets(); + ASSERT(viewportOffsets != nullptr); + ASSERT(AllOffsetsAreNonNegative(*fboData.getViewportOffsets())); + + if (clearParams.scissor.x >= framebufferSize.width || + clearParams.scissor.y >= framebufferSize.height || clearParams.scissor.width == 0 || + clearParams.scissor.height == 0) + { + // The check assumes that the viewport offsets are not negative as according to the + // ANGLE_multiview spec. + // Scissor rect is outside the renderbuffer or is an empty rect. + return gl::NoError(); + } + + if (isSideBySideFBO) + { + // We always have to do a scissor clear for side-by-side framebuffers. + needScissoredClear = true; + } + else + { + // Because the viewport offsets can generate scissor rectangles within the framebuffer's + // bounds, we can do this check only for non-side-by-side framebuffers. + if (clearParams.scissor.x + clearParams.scissor.width <= 0 || + clearParams.scissor.y + clearParams.scissor.height <= 0) + { + // Scissor rect is outside the renderbuffer. + return gl::NoError(); + } + needScissoredClear = + clearParams.scissor.x > 0 || clearParams.scissor.y > 0 || + clearParams.scissor.x + clearParams.scissor.width < framebufferSize.width || + clearParams.scissor.y + clearParams.scissor.height < framebufferSize.height; + } + + if (needScissoredClear) + { + // Apply viewport offsets to compute the final scissor rectangles. This is valid also + // for non-side-by-side framebuffers, because the default viewport offset is {0,0}. + const size_t numViews = viewportOffsets->size(); + scissorRects.reserve(numViews); + for (size_t i = 0u; i < numViews; ++i) + { + const gl::Offset &offset = (*viewportOffsets)[i]; + D3D11_RECT rect; + int x = clearParams.scissor.x + offset.x; + int y = clearParams.scissor.y + offset.y; + rect.left = x; + rect.right = x + clearParams.scissor.width; + rect.top = y; + rect.bottom = y + clearParams.scissor.height; + scissorRects.emplace_back(rect); + } + } } - bool needScissoredClear = clearParams.scissorEnabled && (clearParams.scissor.x > 0 || clearParams.scissor.y > 0 || - clearParams.scissor.x + clearParams.scissor.width < framebufferSize.width || - clearParams.scissor.y + clearParams.scissor.height < framebufferSize.height); - - std::vector maskedClearRenderTargets; - RenderTarget11* maskedClearDepthStencil = nullptr; - - ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); -#if defined(ANGLE_ENABLE_D3D11_1) + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported(); -#endif - ID3D11Device *device = mRenderer->getDevice(); - for (size_t colorAttachmentIndex = 0; colorAttachmentIndex < colorAttachments.size(); - colorAttachmentIndex++) + std::array rtvs; + std::array rtvMasks = {}; + + uint32_t numRtvs = 0; + const uint8_t colorMask = + gl_d3d11::ConvertColorMask(clearParams.colorMaskRed, clearParams.colorMaskGreen, + clearParams.colorMaskBlue, clearParams.colorMaskAlpha); + + const auto &colorAttachments = fboData.getColorAttachments(); + for (auto colorAttachmentIndex : fboData.getEnabledDrawBuffers()) { const gl::FramebufferAttachment &attachment = colorAttachments[colorAttachmentIndex]; - if (clearParams.clearColor[colorAttachmentIndex] && attachment.isAttached() && - drawBufferStates[colorAttachmentIndex] != GL_NONE) + if (!clearParams.clearColor[colorAttachmentIndex]) { - RenderTarget11 *renderTarget = nullptr; - gl::Error error = attachment.getRenderTarget(&renderTarget); - if (error.isError()) + continue; + } + + RenderTarget11 *renderTarget = nullptr; + ANGLE_TRY(attachment.getRenderTarget(context, &renderTarget)); + + const gl::InternalFormat &formatInfo = *attachment.getFormat().info; + + if (clearParams.colorType == GL_FLOAT && + !(formatInfo.componentType == GL_FLOAT || + formatInfo.componentType == GL_UNSIGNED_NORMALIZED || + formatInfo.componentType == GL_SIGNED_NORMALIZED)) + { + ERR() << "It is undefined behaviour to clear a render buffer which is not " + "normalized fixed point or floating-point to floating point values (color " + "attachment " + << colorAttachmentIndex << " has internal format " << attachment.getFormat() + << ")."; + } + + if ((formatInfo.redBits == 0 || !clearParams.colorMaskRed) && + (formatInfo.greenBits == 0 || !clearParams.colorMaskGreen) && + (formatInfo.blueBits == 0 || !clearParams.colorMaskBlue) && + (formatInfo.alphaBits == 0 || !clearParams.colorMaskAlpha)) + { + // Every channel either does not exist in the render target or is masked out + continue; + } + + const auto &framebufferRTV = renderTarget->getRenderTargetView(); + ASSERT(framebufferRTV.valid()); + + if ((!(mRenderer->getRenderer11DeviceCaps().supportsClearView) && needScissoredClear) || + clearParams.colorType != GL_FLOAT || + (formatInfo.redBits > 0 && !clearParams.colorMaskRed) || + (formatInfo.greenBits > 0 && !clearParams.colorMaskGreen) || + (formatInfo.blueBits > 0 && !clearParams.colorMaskBlue) || + (formatInfo.alphaBits > 0 && !clearParams.colorMaskAlpha)) + { + rtvs[numRtvs] = framebufferRTV.get(); + rtvMasks[numRtvs] = gl_d3d11::GetColorMask(formatInfo) & colorMask; + numRtvs++; + } + else + { + // ID3D11DeviceContext::ClearRenderTargetView or ID3D11DeviceContext1::ClearView is + // possible + + const auto &nativeFormat = renderTarget->getFormatSet().format(); + + // Check if the actual format has a channel that the internal format does not and + // set them to the default values + float clearValues[4] = { + ((formatInfo.redBits == 0 && nativeFormat.redBits > 0) ? 0.0f + : clearParams.colorF.red), + ((formatInfo.greenBits == 0 && nativeFormat.greenBits > 0) + ? 0.0f + : clearParams.colorF.green), + ((formatInfo.blueBits == 0 && nativeFormat.blueBits > 0) ? 0.0f + : clearParams.colorF.blue), + ((formatInfo.alphaBits == 0 && nativeFormat.alphaBits > 0) + ? 1.0f + : clearParams.colorF.alpha), + }; + + if (formatInfo.alphaBits == 1) { - return error; + // Some drivers do not correctly handle calling Clear() on a format with 1-bit + // alpha. They can incorrectly round all non-zero values up to 1.0f. Note that + // WARP does not do this. We should handle the rounding for them instead. + clearValues[3] = (clearParams.colorF.alpha >= 0.5f) ? 1.0f : 0.0f; } - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(attachment.getInternalFormat()); - - if (clearParams.colorClearType == GL_FLOAT && - !(formatInfo.componentType == GL_FLOAT || formatInfo.componentType == GL_UNSIGNED_NORMALIZED || formatInfo.componentType == GL_SIGNED_NORMALIZED)) + if (needScissoredClear) { - ERR( - "It is undefined behaviour to clear a render buffer which is not normalized " - "fixed point or floating-" - "point to floating point values (color attachment %u has internal format " - "0x%X).", - colorAttachmentIndex, attachment.getInternalFormat()); - } - - if ((formatInfo.redBits == 0 || !clearParams.colorMaskRed) && - (formatInfo.greenBits == 0 || !clearParams.colorMaskGreen) && - (formatInfo.blueBits == 0 || !clearParams.colorMaskBlue) && - (formatInfo.alphaBits == 0 || !clearParams.colorMaskAlpha)) - { - // Every channel either does not exist in the render target or is masked out - continue; - } - else if ((!(mRenderer->getRenderer11DeviceCaps().supportsClearView) && needScissoredClear) || clearParams.colorClearType != GL_FLOAT || - (formatInfo.redBits > 0 && !clearParams.colorMaskRed) || - (formatInfo.greenBits > 0 && !clearParams.colorMaskGreen) || - (formatInfo.blueBits > 0 && !clearParams.colorMaskBlue) || - (formatInfo.alphaBits > 0 && !clearParams.colorMaskAlpha)) - { - // A masked clear is required, or a scissored clear is required and ID3D11DeviceContext1::ClearView is unavailable - MaskedRenderTarget maskAndRt; - bool clearColor = clearParams.clearColor[colorAttachmentIndex]; - maskAndRt.colorMask[0] = (clearColor && clearParams.colorMaskRed); - maskAndRt.colorMask[1] = (clearColor && clearParams.colorMaskGreen); - maskAndRt.colorMask[2] = (clearColor && clearParams.colorMaskBlue); - maskAndRt.colorMask[3] = (clearColor && clearParams.colorMaskAlpha); - maskAndRt.renderTarget = renderTarget; - maskedClearRenderTargets.push_back(maskAndRt); + // We shouldn't reach here if deviceContext1 is unavailable. + ASSERT(deviceContext1); + // There must be at least one scissor rectangle. + ASSERT(!scissorRects.empty()); + deviceContext1->ClearView(framebufferRTV.get(), clearValues, scissorRects.data(), + static_cast(scissorRects.size())); + if (mRenderer->getWorkarounds().callClearTwice) + { + deviceContext1->ClearView(framebufferRTV.get(), clearValues, + scissorRects.data(), + static_cast(scissorRects.size())); + } } else { - // ID3D11DeviceContext::ClearRenderTargetView or ID3D11DeviceContext1::ClearView is possible - - ID3D11RenderTargetView *framebufferRTV = renderTarget->getRenderTargetView(); - if (!framebufferRTV) + deviceContext->ClearRenderTargetView(framebufferRTV.get(), clearValues); + if (mRenderer->getWorkarounds().callClearTwice) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null."); - } - - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(renderTarget->getDXGIFormat()); - - // Check if the actual format has a channel that the internal format does not and set them to the - // default values - float clearValues[4] = - { - ((formatInfo.redBits == 0 && dxgiFormatInfo.redBits > 0) ? 0.0f : clearParams.colorFClearValue.red), - ((formatInfo.greenBits == 0 && dxgiFormatInfo.greenBits > 0) ? 0.0f : clearParams.colorFClearValue.green), - ((formatInfo.blueBits == 0 && dxgiFormatInfo.blueBits > 0) ? 0.0f : clearParams.colorFClearValue.blue), - ((formatInfo.alphaBits == 0 && dxgiFormatInfo.alphaBits > 0) ? 1.0f : clearParams.colorFClearValue.alpha), - }; - - if (dxgiFormatInfo.alphaBits == 1) - { - // Some drivers do not correctly handle calling Clear() on a format with 1-bit alpha. - // They can incorrectly round all non-zero values up to 1.0f. Note that WARP does not do this. - // We should handle the rounding for them instead. - clearValues[3] = (clearParams.colorFClearValue.alpha >= 0.5f) ? 1.0f : 0.0f; - } - -#if defined(ANGLE_ENABLE_D3D11_1) - if (needScissoredClear) - { - // We shouldn't reach here if deviceContext1 is unavailable. - ASSERT(deviceContext1); - - D3D11_RECT rect; - rect.left = clearParams.scissor.x; - rect.right = clearParams.scissor.x + clearParams.scissor.width; - rect.top = clearParams.scissor.y; - rect.bottom = clearParams.scissor.y + clearParams.scissor.height; - - deviceContext1->ClearView(framebufferRTV, clearValues, &rect, 1); - } - else -#endif - { - deviceContext->ClearRenderTargetView(framebufferRTV, clearValues); + deviceContext->ClearRenderTargetView(framebufferRTV.get(), clearValues); } } } } + ID3D11DepthStencilView *dsv = nullptr; + if (clearParams.clearDepth || clearParams.clearStencil) { - const gl::FramebufferAttachment *attachment = (depthAttachment != nullptr) ? depthAttachment : stencilAttachment; - ASSERT(attachment != nullptr); + RenderTarget11 *depthStencilRenderTarget = nullptr; - RenderTarget11 *renderTarget = nullptr; - gl::Error error = attachment->getRenderTarget(&renderTarget); - if (error.isError()) + ASSERT(depthStencilAttachment != nullptr); + ANGLE_TRY(depthStencilAttachment->getRenderTarget(context, &depthStencilRenderTarget)); + + dsv = depthStencilRenderTarget->getDepthStencilView().get(); + ASSERT(dsv != nullptr); + + const auto &nativeFormat = depthStencilRenderTarget->getFormatSet().format(); + const auto *stencilAttachment = fboData.getStencilAttachment(); + + uint32_t stencilUnmasked = + (stencilAttachment != nullptr) ? (1 << nativeFormat.stencilBits) - 1 : 0; + bool needMaskedStencilClear = + clearParams.clearStencil && + (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked; + + if (!needScissoredClear && !needMaskedStencilClear) { - return error; - } + const UINT clearFlags = (clearParams.clearDepth ? D3D11_CLEAR_DEPTH : 0) | + (clearParams.clearStencil ? D3D11_CLEAR_STENCIL : 0); + const FLOAT depthClear = gl::clamp01(clearParams.depthValue); + const UINT8 stencilClear = clearParams.stencilValue & 0xFF; - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(renderTarget->getDXGIFormat()); + deviceContext->ClearDepthStencilView(dsv, clearFlags, depthClear, stencilClear); - unsigned int stencilUnmasked = (stencilAttachment != nullptr) ? (1 << dxgiFormatInfo.stencilBits) - 1 : 0; - bool needMaskedStencilClear = clearParams.clearStencil && (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked; - - if (needScissoredClear || needMaskedStencilClear) - { - maskedClearDepthStencil = renderTarget; - } - else - { - ID3D11DepthStencilView *framebufferDSV = renderTarget->getDepthStencilView(); - if (!framebufferDSV) - { - return gl::Error(GL_OUT_OF_MEMORY, "Internal depth stencil view pointer unexpectedly null."); - } - - UINT clearFlags = (clearParams.clearDepth ? D3D11_CLEAR_DEPTH : 0) | - (clearParams.clearStencil ? D3D11_CLEAR_STENCIL : 0); - FLOAT depthClear = gl::clamp01(clearParams.depthClearValue); - UINT8 stencilClear = clearParams.stencilClearValue & 0xFF; - - deviceContext->ClearDepthStencilView(framebufferDSV, clearFlags, depthClear, stencilClear); + dsv = nullptr; } } - if (maskedClearRenderTargets.size() > 0 || maskedClearDepthStencil) + if (numRtvs == 0 && dsv == nullptr) { - // To clear the render targets and depth stencil in one pass: - // - // Render a quad clipped to the scissor rectangle which draws the clear color and a blend - // state that will perform the required color masking. - // - // The quad's depth is equal to the depth clear value with a depth stencil state that - // will enable or disable depth test/writes if the depth buffer should be cleared or not. - // - // The rasterizer state's stencil is set to always pass or fail based on if the stencil - // should be cleared or not with a stencil write mask of the stencil clear value. - // - // ====================================================================================== - // - // Luckily, the gl spec (ES 3.0.2 pg 183) states that the results of clearing a render- - // buffer that is not normalized fixed point or floating point with floating point values - // are undefined so we can just write floats to them and D3D11 will bit cast them to - // integers. - // - // Also, we don't have to worry about attempting to clear a normalized fixed/floating point - // buffer with integer values because there is no gl API call which would allow it, - // glClearBuffer* calls only clear a single renderbuffer at a time which is verified to - // be a compatible clear type. + return gl::NoError(); + } - // Bind all the render targets which need clearing - ASSERT(maskedClearRenderTargets.size() <= mRenderer->getRendererCaps().maxDrawBuffers); - std::vector rtvs(maskedClearRenderTargets.size()); - for (unsigned int i = 0; i < maskedClearRenderTargets.size(); i++) - { - RenderTarget11 *renderTarget = maskedClearRenderTargets[i].renderTarget; - ID3D11RenderTargetView *rtv = renderTarget->getRenderTargetView(); - if (!rtv) - { - return gl::Error(GL_OUT_OF_MEMORY, "Internal render target view pointer unexpectedly null."); - } + // Clear the remaining render targets and depth stencil in one pass by rendering a quad: + // + // IA/VS: Vertices containing position and color members are passed through to the next stage. + // The vertex position has XY coordinates equal to clip extents and a Z component equal to the + // Z clear value. The vertex color contains the clear color. + // + // Rasterizer: Viewport scales the VS output over the entire surface and depending on whether + // or not scissoring is enabled the appropriate scissor rect and rasterizerState with or without + // the scissor test enabled is set as well. + // + // DepthStencilTest: DepthTesting, DepthWrites, StencilMask and StencilWrites will be enabled or + // disabled or set depending on what the input depthStencil clear parameters are. Since the PS + // is not writing out depth or rejecting pixels, this should happen prior to the PS stage. + // + // PS: Will write out the color values passed through from the previous stage to all outputs. + // + // OM: BlendState will perform the required color masking and output to RTV(s). - rtvs[i] = rtv; - } - ID3D11DepthStencilView *dsv = maskedClearDepthStencil ? maskedClearDepthStencil->getDepthStencilView() : nullptr; + // + // ====================================================================================== + // + // Luckily, the gl spec (ES 3.0.2 pg 183) states that the results of clearing a render- + // buffer that is not normalized fixed point or floating point with floating point values + // are undefined so we can just write floats to them and D3D11 will bit cast them to + // integers. + // + // Also, we don't have to worry about attempting to clear a normalized fixed/floating point + // buffer with integer values because there is no gl API call which would allow it, + // glClearBuffer* calls only clear a single renderbuffer at a time which is verified to + // be a compatible clear type. - ID3D11BlendState *blendState = getBlendState(maskedClearRenderTargets); - const FLOAT blendFactors[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; - const UINT sampleMask = 0xFFFFFFFF; + ASSERT(numRtvs <= mRenderer->getNativeCaps().maxDrawBuffers); - ID3D11DepthStencilState *dsState = getDepthStencilState(clearParams); - const UINT stencilClear = clearParams.stencilClearValue & 0xFF; + // Setup BlendStateKey parameters + mBlendStateKey.blendState.colorMaskRed = clearParams.colorMaskRed; + mBlendStateKey.blendState.colorMaskGreen = clearParams.colorMaskGreen; + mBlendStateKey.blendState.colorMaskBlue = clearParams.colorMaskBlue; + mBlendStateKey.blendState.colorMaskAlpha = clearParams.colorMaskAlpha; + mBlendStateKey.rtvMax = numRtvs; + memcpy(mBlendStateKey.rtvMasks, &rtvMasks[0], sizeof(mBlendStateKey.rtvMasks)); - // Set the vertices - UINT vertexStride = 0; - const UINT startIdx = 0; - ClearShader *shader = nullptr; - D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal masked clear vertex buffer, HRESULT: 0x%X.", result); - } + // Get BlendState + const d3d11::BlendState *blendState = nullptr; + ANGLE_TRY(mRenderer->getBlendState(mBlendStateKey, &blendState)); - const gl::Rectangle *scissorPtr = clearParams.scissorEnabled ? &clearParams.scissor : nullptr; - switch (clearParams.colorClearType) - { - case GL_FLOAT: - ApplyVertices(framebufferSize, scissorPtr, clearParams.colorFClearValue, clearParams.depthClearValue, mappedResource.pData); - vertexStride = sizeof(d3d11::PositionDepthColorVertex); - shader = mFloatClearShader; + const d3d11::DepthStencilState *dsState = nullptr; + const float *zValue = nullptr; + + if (dsv) + { + // Setup DepthStencilStateKey + mDepthStencilStateKey.depthTest = clearParams.clearDepth; + mDepthStencilStateKey.depthMask = clearParams.clearDepth; + mDepthStencilStateKey.stencilWritemask = clearParams.stencilWriteMask; + mDepthStencilStateKey.stencilTest = clearParams.clearStencil; + + // Get DepthStencilState + ANGLE_TRY(mRenderer->getDepthStencilState(mDepthStencilStateKey, &dsState)); + zValue = clearParams.clearDepth ? &clearParams.depthValue : nullptr; + } + + bool dirtyCb = false; + + // Compare the input color/z values against the CB cache and update it if necessary + switch (clearParams.colorType) + { + case GL_FLOAT: + dirtyCb = UpdateDataCache(reinterpret_cast *>(&mShaderData), + clearParams.colorF, zValue, numRtvs, colorMask); break; - - case GL_UNSIGNED_INT: - ApplyVertices(framebufferSize, scissorPtr, clearParams.colorUIClearValue, clearParams.depthClearValue, mappedResource.pData); - vertexStride = sizeof(d3d11::PositionDepthColorVertex); - shader = mUintClearShader; + case GL_UNSIGNED_INT: + dirtyCb = UpdateDataCache(reinterpret_cast *>(&mShaderData), + clearParams.colorUI, zValue, numRtvs, colorMask); break; - - case GL_INT: - ApplyVertices(framebufferSize, scissorPtr, clearParams.colorIClearValue, clearParams.depthClearValue, mappedResource.pData); - vertexStride = sizeof(d3d11::PositionDepthColorVertex); - shader = mIntClearShader; + case GL_INT: + dirtyCb = UpdateDataCache(reinterpret_cast *>(&mShaderData), + clearParams.colorI, zValue, numRtvs, colorMask); break; - - default: + default: UNREACHABLE(); break; - } - - deviceContext->Unmap(mVertexBuffer, 0); - - // Set the viewport to be the same size as the framebuffer - D3D11_VIEWPORT viewport; - viewport.TopLeftX = 0; - viewport.TopLeftY = 0; - viewport.Width = static_cast(framebufferSize.width); - viewport.Height = static_cast(framebufferSize.height); - viewport.MinDepth = 0; - viewport.MaxDepth = 1; - deviceContext->RSSetViewports(1, &viewport); - - // Apply state - deviceContext->OMSetBlendState(blendState, blendFactors, sampleMask); - deviceContext->OMSetDepthStencilState(dsState, stencilClear); - deviceContext->RSSetState(mRasterizerState); - - // Apply shaders - deviceContext->IASetInputLayout(shader->inputLayout->resolve(device)); - deviceContext->VSSetShader(shader->vertexShader.resolve(device), nullptr, 0); - deviceContext->PSSetShader(shader->pixelShader.resolve(device), nullptr, 0); - deviceContext->GSSetShader(nullptr, nullptr, 0); - - // Apply vertex buffer - deviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &vertexStride, &startIdx); - deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - - // Apply render targets - deviceContext->OMSetRenderTargets(static_cast(rtvs.size()), - (rtvs.empty() ? nullptr : &rtvs[0]), dsv); - - // Draw the clear quad - deviceContext->Draw(4, 0); - - // Clean up - mRenderer->markAllStateDirty(); } - return gl::Error(GL_NO_ERROR); -} + ANGLE_TRY(ensureConstantBufferCreated()); -ID3D11BlendState *Clear11::getBlendState(const std::vector& rts) -{ - ClearBlendInfo blendKey = {}; - for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + if (dirtyCb) { - if (i < rts.size()) + // Update the constant buffer with the updated cache contents + // TODO(Shahmeer): Consider using UpdateSubresource1 D3D11_COPY_DISCARD where possible. + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT result = deviceContext->Map(mConstantBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, + &mappedResource); + if (FAILED(result)) { - RenderTarget11 *rt = rts[i].renderTarget; - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(rt->getInternalFormat()); + return gl::OutOfMemory() << "Clear11: Failed to map CB, " << gl::FmtHR(result); + } - blendKey.maskChannels[i][0] = (rts[i].colorMask[0] && formatInfo.redBits > 0); - blendKey.maskChannels[i][1] = (rts[i].colorMask[1] && formatInfo.greenBits > 0); - blendKey.maskChannels[i][2] = (rts[i].colorMask[2] && formatInfo.blueBits > 0); - blendKey.maskChannels[i][3] = (rts[i].colorMask[3] && formatInfo.alphaBits > 0); + memcpy(mappedResource.pData, &mShaderData, g_ConstantBufferSize); + deviceContext->Unmap(mConstantBuffer.get(), 0); + } + + auto *stateManager = mRenderer->getStateManager(); + + // Set the viewport to be the same size as the framebuffer. + stateManager->setSimpleViewport(framebufferSize); + + // Apply state + stateManager->setSimpleBlendState(blendState); + + const UINT stencilValue = clearParams.stencilValue & 0xFF; + stateManager->setDepthStencilState(dsState, stencilValue); + + if (needScissoredClear) + { + stateManager->setRasterizerState(&mScissorEnabledRasterizerState); + } + else + { + stateManager->setRasterizerState(&mScissorDisabledRasterizerState); + } + + // Get Shaders + const d3d11::VertexShader *vs = nullptr; + const d3d11::GeometryShader *gs = nullptr; + const d3d11::InputLayout *il = nullptr; + const d3d11::PixelShader *ps = nullptr; + const bool hasLayeredLayout = + (fboData.getMultiviewLayout() == GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE); + ANGLE_TRY(mShaderManager.getShadersAndLayout(mRenderer, clearParams.colorType, numRtvs, + hasLayeredLayout, &il, &vs, &gs, &ps)); + + // Apply Shaders + stateManager->setDrawShaders(vs, gs, ps); + stateManager->setPixelConstantBuffer(0, &mConstantBuffer); + + // Bind IL & VB if needed + stateManager->setIndexBuffer(nullptr, DXGI_FORMAT_UNKNOWN, 0); + stateManager->setInputLayout(il); + + if (useVertexBuffer()) + { + ANGLE_TRY(ensureVertexBufferCreated()); + stateManager->setSingleVertexBuffer(&mVertexBuffer, g_VertexSize, 0); + } + else + { + stateManager->setSingleVertexBuffer(nullptr, 0, 0); + } + + stateManager->setPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + + // Apply render targets + stateManager->setRenderTargets(&rtvs[0], numRtvs, dsv); + + // If scissors are necessary to be applied, then the number of clears is the number of scissor + // rects. If no scissors are necessary, then a single full-size clear is enough. + size_t necessaryNumClears = needScissoredClear ? scissorRects.size() : 1u; + for (size_t i = 0u; i < necessaryNumClears; ++i) + { + if (needScissoredClear) + { + ASSERT(i < scissorRects.size()); + stateManager->setScissorRectD3D(scissorRects[i]); + } + // Draw the fullscreen quad. + if (!hasLayeredLayout || isSideBySideFBO) + { + deviceContext->Draw(6, 0); } else { - blendKey.maskChannels[i][0] = false; - blendKey.maskChannels[i][1] = false; - blendKey.maskChannels[i][2] = false; - blendKey.maskChannels[i][3] = false; + ASSERT(hasLayeredLayout); + deviceContext->DrawInstanced(6, static_cast(fboData.getNumViews()), 0, 0); } } - ClearBlendStateMap::const_iterator i = mClearBlendStates.find(blendKey); - if (i != mClearBlendStates.end()) - { - return i->second; - } - else - { - D3D11_BLEND_DESC blendDesc = { 0 }; - blendDesc.AlphaToCoverageEnable = FALSE; - blendDesc.IndependentBlendEnable = (rts.size() > 1) ? TRUE : FALSE; - - for (unsigned int j = 0; j < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; j++) - { - blendDesc.RenderTarget[j].BlendEnable = FALSE; - blendDesc.RenderTarget[j].RenderTargetWriteMask = gl_d3d11::ConvertColorMask(blendKey.maskChannels[j][0], - blendKey.maskChannels[j][1], - blendKey.maskChannels[j][2], - blendKey.maskChannels[j][3]); - } - - ID3D11Device *device = mRenderer->getDevice(); - ID3D11BlendState* blendState = nullptr; - HRESULT result = device->CreateBlendState(&blendDesc, &blendState); - if (FAILED(result) || !blendState) - { - ERR("Unable to create a ID3D11BlendState, HRESULT: 0x%X.", result); - return nullptr; - } - - mClearBlendStates[blendKey] = blendState; - - return blendState; - } + return gl::NoError(); } -ID3D11DepthStencilState *Clear11::getDepthStencilState(const ClearParameters &clearParams) -{ - ClearDepthStencilInfo dsKey = { 0 }; - dsKey.clearDepth = clearParams.clearDepth; - dsKey.clearStencil = clearParams.clearStencil; - dsKey.stencilWriteMask = clearParams.stencilWriteMask & 0xFF; - - ClearDepthStencilStateMap::const_iterator i = mClearDepthStencilStates.find(dsKey); - if (i != mClearDepthStencilStates.end()) - { - return i->second; - } - else - { - D3D11_DEPTH_STENCIL_DESC dsDesc = { 0 }; - dsDesc.DepthEnable = dsKey.clearDepth ? TRUE : FALSE; - dsDesc.DepthWriteMask = dsKey.clearDepth ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; - dsDesc.DepthFunc = D3D11_COMPARISON_ALWAYS; - dsDesc.StencilEnable = dsKey.clearStencil ? TRUE : FALSE; - dsDesc.StencilReadMask = 0; - dsDesc.StencilWriteMask = dsKey.stencilWriteMask; - dsDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_REPLACE; - dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_REPLACE; - dsDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE; - dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - dsDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_REPLACE; - dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_REPLACE; - dsDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE; - dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - - ID3D11Device *device = mRenderer->getDevice(); - ID3D11DepthStencilState* dsState = nullptr; - HRESULT result = device->CreateDepthStencilState(&dsDesc, &dsState); - if (FAILED(result) || !dsState) - { - ERR("Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result); - return nullptr; - } - - mClearDepthStencilStates[dsKey] = dsState; - - return dsState; - } -} - -} +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.h index 3ff73c85d1..a09812c42b 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.h @@ -23,6 +23,14 @@ class Renderer11; class RenderTarget11; struct ClearParameters; +template +struct RtvDsvClearInfo +{ + T r, g, b, a; + float z; + float c1padding[3]; +}; + class Clear11 : angle::NonCopyable { public: @@ -30,68 +38,63 @@ class Clear11 : angle::NonCopyable ~Clear11(); // Clears the framebuffer with the supplied clear parameters, assumes that the framebuffer is currently applied. - gl::Error clearFramebuffer(const ClearParameters &clearParams, const gl::Framebuffer::Data &fboData); + gl::Error clearFramebuffer(const gl::Context *context, + const ClearParameters &clearParams, + const gl::FramebufferState &fboData); private: - struct MaskedRenderTarget + class ShaderManager final : angle::NonCopyable { - bool colorMask[4]; - RenderTarget11 *renderTarget; + public: + ShaderManager(); + ~ShaderManager(); + gl::Error getShadersAndLayout(Renderer11 *renderer, + const INT clearType, + const uint32_t numRTs, + const bool hasLayeredLayout, + const d3d11::InputLayout **il, + const d3d11::VertexShader **vs, + const d3d11::GeometryShader **gs, + const d3d11::PixelShader **ps); + + private: + constexpr static size_t kNumShaders = D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; + + d3d11::InputLayout mIl9; + d3d11::LazyShader mVs9; + d3d11::LazyShader mPsFloat9; + d3d11::LazyShader mVs; + d3d11::LazyShader mVsMultiview; + d3d11::LazyShader mGsMultiview; + d3d11::LazyShader mPsDepth; + std::array, kNumShaders> mPsFloat; + std::array, kNumShaders> mPsUInt; + std::array, kNumShaders> mPsSInt; }; - ID3D11BlendState *getBlendState(const std::vector &rts); - ID3D11DepthStencilState *getDepthStencilState(const ClearParameters &clearParams); - - struct ClearShader final : public angle::NonCopyable - { - ClearShader(DXGI_FORMAT colorType, - const char *inputLayoutName, - const BYTE *vsByteCode, - size_t vsSize, - const char *vsDebugName, - const BYTE *psByteCode, - size_t psSize, - const char *psDebugName); - ~ClearShader(); - - d3d11::LazyInputLayout *inputLayout; - d3d11::LazyShader vertexShader; - d3d11::LazyShader pixelShader; - }; - - template - static ClearShader CreateClearShader(ID3D11Device *device, DXGI_FORMAT colorType, const BYTE(&vsByteCode)[vsSize], const BYTE(&psByteCode)[psSize]); - - struct ClearBlendInfo - { - bool maskChannels[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT][4]; - }; - typedef bool(*ClearBlendInfoComparisonFunction)(const ClearBlendInfo&, const ClearBlendInfo &); - typedef std::map ClearBlendStateMap; - - struct ClearDepthStencilInfo - { - bool clearDepth; - bool clearStencil; - UINT8 stencilWriteMask; - }; - typedef bool(*ClearDepthStencilInfoComparisonFunction)(const ClearDepthStencilInfo&, const ClearDepthStencilInfo &); - typedef std::map ClearDepthStencilStateMap; + bool useVertexBuffer() const; + gl::Error ensureConstantBufferCreated(); + gl::Error ensureVertexBufferCreated(); + gl::Error ensureResourcesInitialized(); Renderer11 *mRenderer; + bool mResourcesInitialized; - ClearBlendStateMap mClearBlendStates; + // States + d3d11::RasterizerState mScissorEnabledRasterizerState; + d3d11::RasterizerState mScissorDisabledRasterizerState; + gl::DepthStencilState mDepthStencilStateKey; + d3d11::BlendStateKey mBlendStateKey; - ClearShader *mFloatClearShader; - ClearShader *mUintClearShader; - ClearShader *mIntClearShader; + // Shaders and shader resources + ShaderManager mShaderManager; + d3d11::Buffer mConstantBuffer; + d3d11::Buffer mVertexBuffer; - ClearDepthStencilStateMap mClearDepthStencilStates; - - ID3D11Buffer *mVertexBuffer; - ID3D11RasterizerState *mRasterizerState; + // Buffer data and draw parameters + RtvDsvClearInfo mShaderData; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_D3D11_CLEAR11_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Context11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Context11.cpp new file mode 100644 index 0000000000..b79dd3603a --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Context11.cpp @@ -0,0 +1,405 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Context11: +// D3D11-specific functionality associated with a GL Context. +// + +#include "libANGLE/renderer/d3d/d3d11/Context11.h" + +#include "common/string_utils.h" +#include "libANGLE/Context.h" +#include "libANGLE/MemoryProgramCache.h" +#include "libANGLE/renderer/d3d/CompilerD3D.h" +#include "libANGLE/renderer/d3d/ProgramD3D.h" +#include "libANGLE/renderer/d3d/RenderbufferD3D.h" +#include "libANGLE/renderer/d3d/SamplerD3D.h" +#include "libANGLE/renderer/d3d/ShaderD3D.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" +#include "libANGLE/renderer/d3d/d3d11/Buffer11.h" +#include "libANGLE/renderer/d3d/d3d11/Fence11.h" +#include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h" +#include "libANGLE/renderer/d3d/d3d11/ProgramPipeline11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/StateManager11.h" +#include "libANGLE/renderer/d3d/d3d11/TransformFeedback11.h" +#include "libANGLE/renderer/d3d/d3d11/VertexArray11.h" + +namespace rx +{ + +Context11::Context11(const gl::ContextState &state, Renderer11 *renderer) + : ContextImpl(state), mRenderer(renderer) +{ +} + +Context11::~Context11() +{ +} + +gl::Error Context11::initialize() +{ + return gl::NoError(); +} + +CompilerImpl *Context11::createCompiler() +{ + if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) + { + return new CompilerD3D(SH_HLSL_4_0_FL9_3_OUTPUT); + } + else + { + return new CompilerD3D(SH_HLSL_4_1_OUTPUT); + } +} + +ShaderImpl *Context11::createShader(const gl::ShaderState &data) +{ + return new ShaderD3D(data, mRenderer->getWorkarounds(), mRenderer->getNativeExtensions()); +} + +ProgramImpl *Context11::createProgram(const gl::ProgramState &data) +{ + return new ProgramD3D(data, mRenderer); +} + +FramebufferImpl *Context11::createFramebuffer(const gl::FramebufferState &data) +{ + return new Framebuffer11(data, mRenderer); +} + +TextureImpl *Context11::createTexture(const gl::TextureState &state) +{ + switch (state.getTarget()) + { + case GL_TEXTURE_2D: + return new TextureD3D_2D(state, mRenderer); + case GL_TEXTURE_CUBE_MAP: + return new TextureD3D_Cube(state, mRenderer); + case GL_TEXTURE_3D: + return new TextureD3D_3D(state, mRenderer); + case GL_TEXTURE_2D_ARRAY: + return new TextureD3D_2DArray(state, mRenderer); + case GL_TEXTURE_EXTERNAL_OES: + return new TextureD3D_External(state, mRenderer); + case GL_TEXTURE_2D_MULTISAMPLE: + return new TextureD3D_2DMultisample(state, mRenderer); + break; + default: + UNREACHABLE(); + } + + return nullptr; +} + +RenderbufferImpl *Context11::createRenderbuffer() +{ + return new RenderbufferD3D(mRenderer); +} + +BufferImpl *Context11::createBuffer(const gl::BufferState &state) +{ + Buffer11 *buffer = new Buffer11(state, mRenderer); + mRenderer->onBufferCreate(buffer); + return buffer; +} + +VertexArrayImpl *Context11::createVertexArray(const gl::VertexArrayState &data) +{ + return new VertexArray11(data); +} + +QueryImpl *Context11::createQuery(GLenum type) +{ + return new Query11(mRenderer, type); +} + +FenceNVImpl *Context11::createFenceNV() +{ + return new FenceNV11(mRenderer); +} + +SyncImpl *Context11::createSync() +{ + return new Sync11(mRenderer); +} + +TransformFeedbackImpl *Context11::createTransformFeedback(const gl::TransformFeedbackState &state) +{ + return new TransformFeedback11(state, mRenderer); +} + +SamplerImpl *Context11::createSampler(const gl::SamplerState &state) +{ + return new SamplerD3D(state); +} + +ProgramPipelineImpl *Context11::createProgramPipeline(const gl::ProgramPipelineState &data) +{ + return new ProgramPipeline11(data); +} + +std::vector Context11::createPaths(GLsizei) +{ + return std::vector(); +} + +gl::Error Context11::flush(const gl::Context *context) +{ + return mRenderer->flush(); +} + +gl::Error Context11::finish(const gl::Context *context) +{ + return mRenderer->finish(); +} + +gl::Error Context11::drawArrays(const gl::Context *context, GLenum mode, GLint first, GLsizei count) +{ + ANGLE_TRY(prepareForDrawCall(context, mode)); + return mRenderer->drawArrays(context, mode, first, count, 0); +} + +gl::Error Context11::drawArraysInstanced(const gl::Context *context, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instanceCount) +{ + ANGLE_TRY(prepareForDrawCall(context, mode)); + return mRenderer->drawArrays(context, mode, first, count, instanceCount); +} + +gl::Error Context11::drawElements(const gl::Context *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices) +{ + ANGLE_TRY(prepareForDrawCall(context, mode)); + return mRenderer->drawElements(context, mode, count, type, indices, 0); +} + +gl::Error Context11::drawElementsInstanced(const gl::Context *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei instances) +{ + ANGLE_TRY(prepareForDrawCall(context, mode)); + return mRenderer->drawElements(context, mode, count, type, indices, instances); +} + +gl::Error Context11::drawRangeElements(const gl::Context *context, + GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const void *indices) +{ + ANGLE_TRY(prepareForDrawCall(context, mode)); + return mRenderer->drawElements(context, mode, count, type, indices, 0); +} + +gl::Error Context11::drawArraysIndirect(const gl::Context *context, + GLenum mode, + const void *indirect) +{ + ANGLE_TRY(prepareForDrawCall(context, mode)); + return mRenderer->drawArraysIndirect(context, mode, indirect); +} + +gl::Error Context11::drawElementsIndirect(const gl::Context *context, + GLenum mode, + GLenum type, + const void *indirect) +{ + ANGLE_TRY(prepareForDrawCall(context, mode)); + return mRenderer->drawElementsIndirect(context, mode, type, indirect); +} + +GLenum Context11::getResetStatus() +{ + return mRenderer->getResetStatus(); +} + +std::string Context11::getVendorString() const +{ + return mRenderer->getVendorString(); +} + +std::string Context11::getRendererDescription() const +{ + return mRenderer->getRendererDescription(); +} + +void Context11::insertEventMarker(GLsizei length, const char *marker) +{ + auto optionalString = angle::WidenString(static_cast(length), marker); + if (optionalString.valid()) + { + mRenderer->getAnnotator()->setMarker(optionalString.value().data()); + } +} + +void Context11::pushGroupMarker(GLsizei length, const char *marker) +{ + auto optionalString = angle::WidenString(static_cast(length), marker); + if (optionalString.valid()) + { + mRenderer->getAnnotator()->beginEvent(optionalString.value().data()); + } +} + +void Context11::popGroupMarker() +{ + mRenderer->getAnnotator()->endEvent(); +} + +void Context11::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message) +{ + // Fall through to the EXT_debug_marker functions + pushGroupMarker(length, message); +} + +void Context11::popDebugGroup() +{ + // Fall through to the EXT_debug_marker functions + popGroupMarker(); +} + +void Context11::syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits) +{ + mRenderer->getStateManager()->syncState(context, dirtyBits); +} + +GLint Context11::getGPUDisjoint() +{ + return mRenderer->getGPUDisjoint(); +} + +GLint64 Context11::getTimestamp() +{ + return mRenderer->getTimestamp(); +} + +void Context11::onMakeCurrent(const gl::Context *context) +{ + ANGLE_SWALLOW_ERR(mRenderer->getStateManager()->onMakeCurrent(context)); +} + +const gl::Caps &Context11::getNativeCaps() const +{ + return mRenderer->getNativeCaps(); +} + +const gl::TextureCapsMap &Context11::getNativeTextureCaps() const +{ + return mRenderer->getNativeTextureCaps(); +} + +const gl::Extensions &Context11::getNativeExtensions() const +{ + return mRenderer->getNativeExtensions(); +} + +const gl::Limitations &Context11::getNativeLimitations() const +{ + return mRenderer->getNativeLimitations(); +} + +gl::Error Context11::dispatchCompute(const gl::Context *context, + GLuint numGroupsX, + GLuint numGroupsY, + GLuint numGroupsZ) +{ + return mRenderer->dispatchCompute(context, numGroupsX, numGroupsY, numGroupsZ); +} + +gl::Error Context11::triggerDrawCallProgramRecompilation(const gl::Context *context, + GLenum drawMode) +{ + const auto &glState = context->getGLState(); + const auto *va11 = GetImplAs(glState.getVertexArray()); + const auto *drawFBO = glState.getDrawFramebuffer(); + gl::Program *program = glState.getProgram(); + ProgramD3D *programD3D = GetImplAs(program); + + programD3D->updateCachedInputLayout(va11->getCurrentStateSerial(), glState); + programD3D->updateCachedOutputLayout(context, drawFBO); + + bool recompileVS = !programD3D->hasVertexExecutableForCachedInputLayout(); + bool recompileGS = !programD3D->hasGeometryExecutableForPrimitiveType(drawMode); + bool recompilePS = !programD3D->hasPixelExecutableForCachedOutputLayout(); + + if (!recompileVS && !recompileGS && !recompilePS) + { + return gl::NoError(); + } + + // Load the compiler if necessary and recompile the programs. + ANGLE_TRY(mRenderer->ensureHLSLCompilerInitialized()); + + gl::InfoLog infoLog; + + if (recompileVS) + { + ShaderExecutableD3D *vertexExe = nullptr; + ANGLE_TRY(programD3D->getVertexExecutableForCachedInputLayout(&vertexExe, &infoLog)); + if (!programD3D->hasVertexExecutableForCachedInputLayout()) + { + ASSERT(infoLog.getLength() > 0); + ERR() << "Dynamic recompilation error log: " << infoLog.str(); + return gl::InternalError() + << "Error compiling dynamic vertex executable:" << infoLog.str(); + } + } + + if (recompileGS) + { + ShaderExecutableD3D *geometryExe = nullptr; + ANGLE_TRY(programD3D->getGeometryExecutableForPrimitiveType(context, drawMode, &geometryExe, + &infoLog)); + if (!programD3D->hasGeometryExecutableForPrimitiveType(drawMode)) + { + ASSERT(infoLog.getLength() > 0); + ERR() << "Dynamic recompilation error log: " << infoLog.str(); + return gl::InternalError() + << "Error compiling dynamic geometry executable:" << infoLog.str(); + } + } + + if (recompilePS) + { + ShaderExecutableD3D *pixelExe = nullptr; + ANGLE_TRY(programD3D->getPixelExecutableForCachedOutputLayout(&pixelExe, &infoLog)); + if (!programD3D->hasPixelExecutableForCachedOutputLayout()) + { + ASSERT(infoLog.getLength() > 0); + ERR() << "Dynamic recompilation error log: " << infoLog.str(); + return gl::InternalError() + << "Error compiling dynamic pixel executable:" << infoLog.str(); + } + } + + // Refresh the program cache entry. + if (mMemoryProgramCache) + { + mMemoryProgramCache->updateProgram(context, program); + } + + return gl::NoError(); +} + +gl::Error Context11::prepareForDrawCall(const gl::Context *context, GLenum drawMode) +{ + ANGLE_TRY(mRenderer->getStateManager()->updateState(context, drawMode)); + return gl::NoError(); +} + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Context11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Context11.h new file mode 100644 index 0000000000..dd99111b19 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Context11.h @@ -0,0 +1,155 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Context11: +// D3D11-specific functionality associated with a GL Context. +// + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_CONTEXT11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_CONTEXT11_H_ + +#include "libANGLE/renderer/ContextImpl.h" + +namespace rx +{ +class Renderer11; + +class Context11 : public ContextImpl +{ + public: + Context11(const gl::ContextState &state, Renderer11 *renderer); + ~Context11() override; + + gl::Error initialize() override; + + // Shader creation + CompilerImpl *createCompiler() override; + ShaderImpl *createShader(const gl::ShaderState &data) override; + ProgramImpl *createProgram(const gl::ProgramState &data) override; + + // Framebuffer creation + FramebufferImpl *createFramebuffer(const gl::FramebufferState &data) override; + + // Texture creation + TextureImpl *createTexture(const gl::TextureState &state) override; + + // Renderbuffer creation + RenderbufferImpl *createRenderbuffer() override; + + // Buffer creation + BufferImpl *createBuffer(const gl::BufferState &state) override; + + // Vertex Array creation + VertexArrayImpl *createVertexArray(const gl::VertexArrayState &data) override; + + // Query and Fence creation + QueryImpl *createQuery(GLenum type) override; + FenceNVImpl *createFenceNV() override; + SyncImpl *createSync() override; + + // Transform Feedback creation + TransformFeedbackImpl *createTransformFeedback( + const gl::TransformFeedbackState &state) override; + + // Sampler object creation + SamplerImpl *createSampler(const gl::SamplerState &state) override; + + // Program Pipeline object creation + ProgramPipelineImpl *createProgramPipeline(const gl::ProgramPipelineState &data) override; + + // Path object creation. + std::vector createPaths(GLsizei) override; + + // Flush and finish. + gl::Error flush(const gl::Context *context) override; + gl::Error finish(const gl::Context *context) override; + + // Drawing methods. + gl::Error drawArrays(const gl::Context *context, + GLenum mode, + GLint first, + GLsizei count) override; + gl::Error drawArraysInstanced(const gl::Context *context, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instanceCount) override; + + gl::Error drawElements(const gl::Context *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices) override; + gl::Error drawElementsInstanced(const gl::Context *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei instances) override; + gl::Error drawRangeElements(const gl::Context *context, + GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const void *indices) override; + gl::Error drawArraysIndirect(const gl::Context *context, + GLenum mode, + const void *indirect) override; + gl::Error drawElementsIndirect(const gl::Context *context, + GLenum mode, + GLenum type, + const void *indirect) override; + + // Device loss + GLenum getResetStatus() override; + + // Vendor and description strings. + std::string getVendorString() const override; + std::string getRendererDescription() const override; + + // EXT_debug_marker + void insertEventMarker(GLsizei length, const char *marker) override; + void pushGroupMarker(GLsizei length, const char *marker) override; + void popGroupMarker() override; + + // KHR_debug + void pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message) override; + void popDebugGroup() override; + + // State sync with dirty bits. + void syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits) override; + + // Disjoint timer queries + GLint getGPUDisjoint() override; + GLint64 getTimestamp() override; + + // Context switching + void onMakeCurrent(const gl::Context *context) override; + + // Caps queries + const gl::Caps &getNativeCaps() const override; + const gl::TextureCapsMap &getNativeTextureCaps() const override; + const gl::Extensions &getNativeExtensions() const override; + const gl::Limitations &getNativeLimitations() const override; + + Renderer11 *getRenderer() const { return mRenderer; } + + gl::Error dispatchCompute(const gl::Context *context, + GLuint numGroupsX, + GLuint numGroupsY, + GLuint numGroupsZ) override; + + gl::Error triggerDrawCallProgramRecompilation(const gl::Context *context, GLenum drawMode); + + private: + gl::Error prepareForDrawCall(const gl::Context *context, GLenum drawMode); + + Renderer11 *mRenderer; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_CONTEXT11_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp index 1c35ab45cc..1e70363e11 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp @@ -27,9 +27,7 @@ DebugAnnotator11::~DebugAnnotator11() { if (mInitialized) { -#if defined(ANGLE_ENABLE_D3D11_1) SafeRelease(mUserDefinedAnnotation); -#endif #if !defined(ANGLE_ENABLE_WINDOWS_STORE) FreeLibrary(mD3d11Module); @@ -43,9 +41,7 @@ void DebugAnnotator11::beginEvent(const wchar_t *eventName) if (mUserDefinedAnnotation != nullptr) { -#if defined(ANGLE_ENABLE_D3D11_1) mUserDefinedAnnotation->BeginEvent(eventName); -#endif } } @@ -55,9 +51,7 @@ void DebugAnnotator11::endEvent() if (mUserDefinedAnnotation != nullptr) { -#if defined(ANGLE_ENABLE_D3D11_1) mUserDefinedAnnotation->EndEvent(); -#endif } } @@ -67,16 +61,14 @@ void DebugAnnotator11::setMarker(const wchar_t *markerName) if (mUserDefinedAnnotation != nullptr) { -#if defined(ANGLE_ENABLE_D3D11_1) mUserDefinedAnnotation->SetMarker(markerName); -#endif } } bool DebugAnnotator11::getStatus() { #if defined(ANGLE_ENABLE_WINDOWS_STORE) -#if (NTDDI_VERSION == NTDDI_WIN10) + static_assert(NTDDI_VERSION >= NTDDI_WIN10, "GetStatus only works on Win10 and above"); initializeDevice(); if (mUserDefinedAnnotation != nullptr) @@ -85,38 +77,6 @@ bool DebugAnnotator11::getStatus() } return true; // Default if initializeDevice() failed -#elif defined(_DEBUG) && (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) - static bool underCapture = true; - - // ID3DUserDefinedAnnotation::GetStatus doesn't work with the Graphics Diagnostics tools in - // Windows 8.1/Visual Studio 2013. We can use IDXGraphicsAnalysis, though. - // The call to GetDebugInterface1 only succeeds if the app is under capture. - // This should only be called in DEBUG mode. - // If an app links against DXGIGetDebugInterface1 in release mode then it will fail Windows - // Store ingestion checks. - - // Cache the result to reduce the number of calls to DXGIGetDebugInterface1 - static bool triedIDXGraphicsAnalysis = false; - - if (!triedIDXGraphicsAnalysis) - { - IDXGraphicsAnalysis *graphicsAnalysis = nullptr; - - HRESULT result = DXGIGetDebugInterface1(0, IID_PPV_ARGS(&graphicsAnalysis)); - if (SUCCEEDED(result)) - { - underCapture = (graphicsAnalysis != nullptr); - } - - SafeRelease(graphicsAnalysis); - triedIDXGraphicsAnalysis = true; - } - - return underCapture; -#else - // We can't detect GetStatus() on release WinRT 8.1 builds, so always return true. - return true; -#endif // (NTDDI_VERSION == NTDDI_WIN10) or _DEBUG #else // We can't detect GetStatus() on desktop ANGLE builds so always return true. return true; @@ -141,14 +101,13 @@ void DebugAnnotator11::initializeDevice() HRESULT hr = E_FAIL; // Create a D3D_DRIVER_TYPE_NULL device, which is much cheaper than other types of device. - hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_NULL, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &device, nullptr, &context); + hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_NULL, nullptr, 0, nullptr, 0, + D3D11_SDK_VERSION, &device, nullptr, &context); ASSERT(SUCCEEDED(hr)); if (SUCCEEDED(hr)) { -#if defined(ANGLE_ENABLE_D3D11_1) mUserDefinedAnnotation = d3d11::DynamicCastComObject(context); ASSERT(mUserDefinedAnnotation != nullptr); -#endif mInitialized = true; } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h index d1a0f7fd2e..62662c49ae 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h @@ -9,14 +9,12 @@ #ifndef LIBANGLE_RENDERER_D3D_D3D11_DEBUGANNOTATOR11_H_ #define LIBANGLE_RENDERER_D3D_D3D11_DEBUGANNOTATOR11_H_ -#include "common/debug.h" - -struct ID3DUserDefinedAnnotation; +#include "libANGLE/LoggingAnnotator.h" namespace rx { -class DebugAnnotator11 : public gl::DebugAnnotator +class DebugAnnotator11 : public angle::LoggingAnnotator { public: DebugAnnotator11(); diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp index 53fac65f2a..082f28d794 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp @@ -4,7 +4,8 @@ // found in the LICENSE file. // -// Fence11.cpp: Defines the rx::FenceNV11 and rx::FenceSync11 classes which implement rx::FenceNVImpl and rx::FenceSyncImpl. +// Fence11.cpp: Defines the rx::FenceNV11 and rx::Sync11 classes which implement +// rx::FenceNVImpl and rx::SyncImpl. #include "libANGLE/renderer/d3d/d3d11/Fence11.h" #include "libANGLE/renderer/d3d/d3d11/Renderer11.h" @@ -14,28 +15,30 @@ namespace rx { +static const int kDeviceLostCheckPeriod = 64; + // // Template helpers for set and test operations. // -template +template gl::Error FenceSetHelper(FenceClass *fence) { if (!fence->mQuery) { D3D11_QUERY_DESC queryDesc; - queryDesc.Query = D3D11_QUERY_EVENT; + queryDesc.Query = D3D11_QUERY_EVENT; queryDesc.MiscFlags = 0; HRESULT result = fence->mRenderer->getDevice()->CreateQuery(&queryDesc, &fence->mQuery); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create event query, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to create event query, " << gl::FmtHR(result); } } fence->mRenderer->getDeviceContext()->End(fence->mQuery); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } template @@ -44,30 +47,24 @@ gl::Error FenceTestHelper(FenceClass *fence, bool flushCommandBuffer, GLboolean ASSERT(fence->mQuery); UINT getDataFlags = (flushCommandBuffer ? 0 : D3D11_ASYNC_GETDATA_DONOTFLUSH); - HRESULT result = fence->mRenderer->getDeviceContext()->GetData(fence->mQuery, NULL, 0, getDataFlags); + HRESULT result = + fence->mRenderer->getDeviceContext()->GetData(fence->mQuery, nullptr, 0, getDataFlags); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to get query data, result: 0x%X.", result); - } - else if (fence->mRenderer->isDeviceLost()) - { - return gl::Error(GL_OUT_OF_MEMORY, "Device was lost while querying result of an event query."); + return gl::OutOfMemory() << "Failed to get query data, " << gl::FmtHR(result); } ASSERT(result == S_OK || result == S_FALSE); *outFinished = ((result == S_OK) ? GL_TRUE : GL_FALSE); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } // // FenceNV11 // -FenceNV11::FenceNV11(Renderer11 *renderer) - : FenceNVImpl(), - mRenderer(renderer), - mQuery(NULL) +FenceNV11::FenceNV11(Renderer11 *renderer) : FenceNVImpl(), mRenderer(renderer), mQuery(nullptr) { } @@ -89,22 +86,26 @@ gl::Error FenceNV11::test(GLboolean *outFinished) gl::Error FenceNV11::finish() { GLboolean finished = GL_FALSE; + + int loopCount = 0; while (finished != GL_TRUE) { - gl::Error error = FenceTestHelper(this, true, &finished); - if (error.isError()) + loopCount++; + ANGLE_TRY(FenceTestHelper(this, true, &finished)); + + if (loopCount % kDeviceLostCheckPeriod == 0 && mRenderer->testDeviceLost()) { - return error; + return gl::OutOfMemory() << "Device was lost while querying result of an event query."; } ScheduleYield(); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } // -// FenceSync11 +// Sync11 // // Important note on accurate timers in Windows: @@ -118,38 +119,34 @@ gl::Error FenceNV11::finish() // We still opt to use QPC. In the present and moving forward, most newer systems will not suffer // from buggy implementations. -FenceSync11::FenceSync11(Renderer11 *renderer) - : FenceSyncImpl(), - mRenderer(renderer), - mQuery(NULL) +Sync11::Sync11(Renderer11 *renderer) : SyncImpl(), mRenderer(renderer), mQuery(nullptr) { LARGE_INTEGER counterFreqency = {}; - BOOL success = QueryPerformanceFrequency(&counterFreqency); - UNUSED_ASSERTION_VARIABLE(success); + BOOL success = QueryPerformanceFrequency(&counterFreqency); ASSERT(success); mCounterFrequency = counterFreqency.QuadPart; } -FenceSync11::~FenceSync11() +Sync11::~Sync11() { SafeRelease(mQuery); } -gl::Error FenceSync11::set(GLenum condition, GLbitfield flags) +gl::Error Sync11::set(GLenum condition, GLbitfield flags) { ASSERT(condition == GL_SYNC_GPU_COMMANDS_COMPLETE && flags == 0); return FenceSetHelper(this); } -gl::Error FenceSync11::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult) +gl::Error Sync11::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult) { ASSERT(outResult); bool flushCommandBuffer = ((flags & GL_SYNC_FLUSH_COMMANDS_BIT) != 0); GLboolean result = GL_FALSE; - gl::Error error = FenceTestHelper(this, flushCommandBuffer, &result); + gl::Error error = FenceTestHelper(this, flushCommandBuffer, &result); if (error.isError()) { *outResult = GL_WAIT_FAILED; @@ -159,28 +156,34 @@ gl::Error FenceSync11::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *ou if (result == GL_TRUE) { *outResult = GL_ALREADY_SIGNALED; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } if (timeout == 0) { *outResult = GL_TIMEOUT_EXPIRED; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } LARGE_INTEGER currentCounter = {}; - BOOL success = QueryPerformanceCounter(¤tCounter); - UNUSED_ASSERTION_VARIABLE(success); + BOOL success = QueryPerformanceCounter(¤tCounter); ASSERT(success); - LONGLONG timeoutInSeconds = static_cast(timeout) * static_cast(1000000ll); - LONGLONG endCounter = currentCounter.QuadPart + mCounterFrequency * timeoutInSeconds; + LONGLONG timeoutInSeconds = static_cast(timeout / 1000000000ull); + LONGLONG endCounter = currentCounter.QuadPart + mCounterFrequency * timeoutInSeconds; + // Extremely unlikely, but if mCounterFrequency is large enough, endCounter can wrap + if (endCounter < currentCounter.QuadPart) + { + endCounter = MAXLONGLONG; + } + + int loopCount = 0; while (currentCounter.QuadPart < endCounter && !result) { + loopCount++; ScheduleYield(); success = QueryPerformanceCounter(¤tCounter); - UNUSED_ASSERTION_VARIABLE(success); ASSERT(success); error = FenceTestHelper(this, flushCommandBuffer, &result); @@ -189,6 +192,12 @@ gl::Error FenceSync11::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *ou *outResult = GL_WAIT_FAILED; return error; } + + if ((loopCount % kDeviceLostCheckPeriod) == 0 && mRenderer->testDeviceLost()) + { + *outResult = GL_WAIT_FAILED; + return gl::OutOfMemory() << "Device was lost while querying result of an event query."; + } } if (currentCounter.QuadPart >= endCounter) @@ -200,32 +209,32 @@ gl::Error FenceSync11::clientWait(GLbitfield flags, GLuint64 timeout, GLenum *ou *outResult = GL_CONDITION_SATISFIED; } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error FenceSync11::serverWait(GLbitfield flags, GLuint64 timeout) +gl::Error Sync11::serverWait(GLbitfield flags, GLuint64 timeout) { // Because our API is currently designed to be called from a single thread, we don't need to do - // extra work for a server-side fence. GPU commands issued after the fence is created will always - // be processed after the fence is signaled. - return gl::Error(GL_NO_ERROR); + // extra work for a server-side fence. GPU commands issued after the fence is created will + // always be processed after the fence is signaled. + return gl::NoError(); } -gl::Error FenceSync11::getStatus(GLint *outResult) +gl::Error Sync11::getStatus(GLint *outResult) { GLboolean result = GL_FALSE; - gl::Error error = FenceTestHelper(this, false, &result); + gl::Error error = FenceTestHelper(this, false, &result); if (error.isError()) { - // The spec does not specify any way to report errors during the status test (e.g. device lost) - // so we report the fence is unblocked in case of error or signaled. + // The spec does not specify any way to report errors during the status test (e.g. device + // lost) so we report the fence is unblocked in case of error or signaled. *outResult = GL_SIGNALED; return error; } *outResult = (result ? GL_SIGNALED : GL_UNSIGNALED); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -} // namespace rx +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.h index 595978885b..4168df5365 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Fence11.h @@ -4,13 +4,14 @@ // found in the LICENSE file. // -// Fence11.h: Defines the rx::FenceNV11 and rx::FenceSync11 classes which implement rx::FenceNVImpl and rx::FenceSyncImpl. +// Fence11.h: Defines the rx::FenceNV11 and rx::Sync11 classes which implement rx::FenceNVImpl +// and rx::SyncImpl. #ifndef LIBANGLE_RENDERER_D3D_D3D11_FENCE11_H_ #define LIBANGLE_RENDERER_D3D_D3D11_FENCE11_H_ #include "libANGLE/renderer/FenceNVImpl.h" -#include "libANGLE/renderer/FenceSyncImpl.h" +#include "libANGLE/renderer/SyncImpl.h" namespace rx { @@ -34,11 +35,11 @@ class FenceNV11 : public FenceNVImpl ID3D11Query *mQuery; }; -class FenceSync11 : public FenceSyncImpl +class Sync11 : public SyncImpl { public: - explicit FenceSync11(Renderer11 *renderer); - ~FenceSync11() override; + explicit Sync11(Renderer11 *renderer); + ~Sync11() override; gl::Error set(GLenum condition, GLbitfield flags) override; gl::Error clientWait(GLbitfield flags, GLuint64 timeout, GLenum *outResult) override; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp index 186a035902..02326d7b50 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp @@ -8,94 +8,119 @@ #include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h" +#include "common/bitset_utils.h" #include "common/debug.h" -#include "libANGLE/renderer/d3d/d3d11/Buffer11.h" -#include "libANGLE/renderer/d3d/d3d11/Clear11.h" -#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h" -#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" -#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" -#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" -#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" -#include "libANGLE/renderer/d3d/TextureD3D.h" +#include "libANGLE/Context.h" #include "libANGLE/Framebuffer.h" #include "libANGLE/FramebufferAttachment.h" #include "libANGLE/Texture.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" +#include "libANGLE/renderer/d3d/d3d11/Buffer11.h" +#include "libANGLE/renderer/d3d/d3d11/Clear11.h" +#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h" +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" + +using namespace angle; namespace rx { -Framebuffer11::Framebuffer11(const gl::Framebuffer::Data &data, Renderer11 *renderer) - : FramebufferD3D(data, renderer), mRenderer(renderer) +namespace { - ASSERT(mRenderer != nullptr); -} - -Framebuffer11::~Framebuffer11() +gl::Error MarkAttachmentsDirty(const gl::Context *context, + const gl::FramebufferAttachment *attachment) { -} - -static gl::Error InvalidateAttachmentSwizzles(const gl::FramebufferAttachment *attachment) -{ - if (attachment && attachment->type() == GL_TEXTURE) + if (attachment->type() == GL_TEXTURE) { gl::Texture *texture = attachment->getTexture(); TextureD3D *textureD3D = GetImplAs(texture); TextureStorage *texStorage = nullptr; - gl::Error error = textureD3D->getNativeTexture(&texStorage); - if (error.isError()) - { - return error; - } + ANGLE_TRY(textureD3D->getNativeTexture(context, &texStorage)); if (texStorage) { TextureStorage11 *texStorage11 = GetAs(texStorage); ASSERT(texStorage11); - texStorage11->invalidateSwizzleCacheLevel(attachment->mipLevel()); + texStorage11->markLevelDirty(attachment->mipLevel()); } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Framebuffer11::invalidateSwizzles() const +void UpdateCachedRenderTarget(const gl::Context *context, + const gl::FramebufferAttachment *attachment, + RenderTarget11 *&cachedRenderTarget, + OnRenderTargetDirtyBinding *channelBinding) { - for (const auto &colorAttachment : mData.getColorAttachments()) + RenderTarget11 *newRenderTarget = nullptr; + if (attachment) { - if (colorAttachment.isAttached()) + // TODO(jmadill): Don't swallow this error. + gl::Error error = attachment->getRenderTarget(context, &newRenderTarget); + if (error.isError()) { - gl::Error error = InvalidateAttachmentSwizzles(&colorAttachment); - if (error.isError()) - { - return error; - } + ERR() << "Internal rendertarget error: " << error; } } - - gl::Error error = InvalidateAttachmentSwizzles(mData.getDepthAttachment()); - if (error.isError()) + if (newRenderTarget != cachedRenderTarget) { - return error; + OnRenderTargetDirtyChannel *channel = + (newRenderTarget ? newRenderTarget->getBroadcastChannel() : nullptr); + channelBinding->bind(channel); + cachedRenderTarget = newRenderTarget; } +} +} // anonymous namespace - error = InvalidateAttachmentSwizzles(mData.getStencilAttachment()); - if (error.isError()) +Framebuffer11::Framebuffer11(const gl::FramebufferState &data, Renderer11 *renderer) + : FramebufferD3D(data, renderer), + mRenderer(renderer), + mCachedDepthStencilRenderTarget(nullptr), + mDepthStencilRenderTargetDirty(this, gl::IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS) +{ + ASSERT(mRenderer != nullptr); + mCachedColorRenderTargets.fill(nullptr); + for (size_t colorIndex = 0; colorIndex < data.getColorAttachments().size(); ++colorIndex) { - return error; + mColorRenderTargetsDirty.emplace_back(this, colorIndex); } - - return gl::Error(GL_NO_ERROR); } -gl::Error Framebuffer11::clear(const gl::Data &data, const ClearParameters &clearParams) +Framebuffer11::~Framebuffer11() +{ +} + +gl::Error Framebuffer11::markAttachmentsDirty(const gl::Context *context) const +{ + const auto &colorAttachments = mState.getColorAttachments(); + for (size_t drawBuffer : mState.getEnabledDrawBuffers()) + { + const gl::FramebufferAttachment &colorAttachment = colorAttachments[drawBuffer]; + ASSERT(colorAttachment.isAttached()); + ANGLE_TRY(MarkAttachmentsDirty(context, &colorAttachment)); + } + + const gl::FramebufferAttachment *dsAttachment = mState.getDepthOrStencilAttachment(); + if (dsAttachment) + { + ANGLE_TRY(MarkAttachmentsDirty(context, dsAttachment)); + } + + return gl::NoError(); +} + +gl::Error Framebuffer11::clearImpl(const gl::Context *context, const ClearParameters &clearParams) { Clear11 *clearer = mRenderer->getClearer(); - gl::Error error(GL_NO_ERROR); - const gl::FramebufferAttachment *colorAttachment = mData.getFirstColorAttachment(); + const gl::FramebufferAttachment *colorAttachment = mState.getFirstColorAttachment(); if (clearParams.scissorEnabled == true && colorAttachment != nullptr && UsePresentPathFast(mRenderer, colorAttachment)) { @@ -107,46 +132,43 @@ gl::Error Framebuffer11::clear(const gl::Data &data, const ClearParameters &clea presentPathFastClearParams.scissor.y = framebufferSize.height - presentPathFastClearParams.scissor.y - presentPathFastClearParams.scissor.height; - error = clearer->clearFramebuffer(presentPathFastClearParams, mData); + ANGLE_TRY(clearer->clearFramebuffer(context, presentPathFastClearParams, mState)); } else { - error = clearer->clearFramebuffer(clearParams, mData); + ANGLE_TRY(clearer->clearFramebuffer(context, clearParams, mState)); } - if (error.isError()) - { - return error; - } + ANGLE_TRY(markAttachmentsDirty(context)); - error = invalidateSwizzles(); - if (error.isError()) - { - return error; - } - - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Framebuffer11::invalidate(size_t count, const GLenum *attachments) +gl::Error Framebuffer11::invalidate(const gl::Context *context, + size_t count, + const GLenum *attachments) { - return invalidateBase(count, attachments, false); + return invalidateBase(context, count, attachments, false); } -gl::Error Framebuffer11::discard(size_t count, const GLenum *attachments) +gl::Error Framebuffer11::discard(const gl::Context *context, + size_t count, + const GLenum *attachments) { - return invalidateBase(count, attachments, true); + return invalidateBase(context, count, attachments, true); } -gl::Error Framebuffer11::invalidateBase(size_t count, const GLenum *attachments, bool useEXTBehavior) const +gl::Error Framebuffer11::invalidateBase(const gl::Context *context, + size_t count, + const GLenum *attachments, + bool useEXTBehavior) const { -#if defined(ANGLE_ENABLE_D3D11_1) ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported(); if (!deviceContext1) { // DiscardView() is only supported on ID3D11DeviceContext1 - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } bool foundDepth = false; @@ -175,37 +197,14 @@ gl::Error Framebuffer11::invalidateBase(size_t count, const GLenum *attachments, ASSERT((attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT15) || (attachments[i] == GL_COLOR)); - RenderTarget11 *renderTarget = nullptr; - ID3D11View *colorView = nullptr; - gl::Error error(GL_NO_ERROR); - size_t colorAttachmentID = 0; - - if (attachments[i] == GL_COLOR) + size_t colorIndex = + (attachments[i] == GL_COLOR ? 0u : (attachments[i] - GL_COLOR_ATTACHMENT0)); + const gl::FramebufferAttachment *colorAttachment = + mState.getColorAttachment(colorIndex); + if (colorAttachment) { - colorAttachmentID = 0; + ANGLE_TRY(invalidateAttachment(context, colorAttachment)); } - else - { - colorAttachmentID = attachments[i] - GL_COLOR_ATTACHMENT0; - } - - if (mData.getColorAttachment(static_cast(colorAttachmentID))) - { - error = mData.getColorAttachment(static_cast(colorAttachmentID)) - ->getRenderTarget(&renderTarget); - if (error.isError()) - { - return error; - } - - colorView = renderTarget->getRenderTargetView(); - - if (colorView != nullptr) - { - deviceContext1->DiscardView(colorView); - } - } - break; } } @@ -222,7 +221,7 @@ gl::Error Framebuffer11::invalidateBase(size_t count, const GLenum *attachments, discardDepth = foundDepth; // Don't bother discarding the stencil buffer if the depth buffer will already do it - discardStencil = foundStencil && (!discardDepth || mData.getDepthAttachment() == nullptr); + discardStencil = foundStencil && (!discardDepth || mState.getDepthAttachment() == nullptr); } else { @@ -230,94 +229,86 @@ gl::Error Framebuffer11::invalidateBase(size_t count, const GLenum *attachments, // attachments list does not include DEPTH_STENCIL_ATTACHMENT or both DEPTH_ATTACHMENT and // STENCIL_ATTACHMENT, then only the specified portion of every pixel in the subregion of pixels // of the DEPTH_STENCIL buffer may be invalidated, and the other portion must be preserved. - discardDepth = (foundDepth && foundStencil) || (foundDepth && (mData.getStencilAttachment() == nullptr)); - discardStencil = (foundStencil && (mData.getDepthAttachment() == nullptr)); + discardDepth = (foundDepth && foundStencil) || + (foundDepth && (mState.getStencilAttachment() == nullptr)); + discardStencil = (foundStencil && (mState.getDepthAttachment() == nullptr)); } - if (discardDepth && mData.getDepthAttachment()) + if (discardDepth && mState.getDepthAttachment()) { - RenderTarget11 *renderTarget = nullptr; - ID3D11View *depthView = nullptr; - gl::Error error(GL_NO_ERROR); - - error = mData.getDepthAttachment()->getRenderTarget(&renderTarget); - if (error.isError()) - { - return error; - } - - depthView = renderTarget->getDepthStencilView(); - - if (depthView != nullptr) - { - deviceContext1->DiscardView(depthView); - } + ANGLE_TRY(invalidateAttachment(context, mState.getDepthAttachment())); } - if (discardStencil && mData.getStencilAttachment()) + if (discardStencil && mState.getStencilAttachment()) { - RenderTarget11 *renderTarget = nullptr; - ID3D11View *stencilView = nullptr; - gl::Error error(GL_NO_ERROR); - - error = mData.getStencilAttachment()->getRenderTarget(&renderTarget); - if (error.isError()) - { - return error; - } - - stencilView = renderTarget->getDepthStencilView(); - - if (stencilView != nullptr) - { - deviceContext1->DiscardView(stencilView); - } + ANGLE_TRY(invalidateAttachment(context, mState.getStencilAttachment())); } -#endif // ANGLE_ENABLE_D3D11_1 - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Framebuffer11::invalidateSub(size_t, const GLenum *, const gl::Rectangle &) +gl::Error Framebuffer11::invalidateSub(const gl::Context *context, + size_t, + const GLenum *, + const gl::Rectangle &) { // A no-op implementation conforms to the spec, so don't call UNIMPLEMENTED() - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Framebuffer11::readPixelsImpl(const gl::Rectangle &area, +gl::Error Framebuffer11::invalidateAttachment(const gl::Context *context, + const gl::FramebufferAttachment *attachment) const +{ + ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported(); + ASSERT(deviceContext1); + ASSERT(attachment && attachment->isAttached()); + + RenderTarget11 *renderTarget = nullptr; + ANGLE_TRY(attachment->getRenderTarget(context, &renderTarget)); + const auto &rtv = renderTarget->getRenderTargetView(); + + if (rtv.valid()) + { + deviceContext1->DiscardView(rtv.get()); + } + + return gl::NoError(); +} + +gl::Error Framebuffer11::readPixelsImpl(const gl::Context *context, + const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch, const gl::PixelPackState &pack, - uint8_t *pixels) const + uint8_t *pixels) { - const gl::FramebufferAttachment *readAttachment = mData.getReadAttachment(); + const gl::FramebufferAttachment *readAttachment = mState.getReadAttachment(); ASSERT(readAttachment); - gl::Buffer *packBuffer = pack.pixelBuffer.get(); + gl::Buffer *packBuffer = context->getGLState().getTargetBuffer(gl::BufferBinding::PixelPack); if (packBuffer != nullptr) { - if (pack.rowLength != 0 || pack.skipRows != 0 || pack.skipPixels != 0) - { - UNIMPLEMENTED(); - return gl::Error(GL_INVALID_OPERATION, - "Unimplemented pixel store parameters in readPixelsImpl"); - } - Buffer11 *packBufferStorage = GetImplAs(packBuffer); PackPixelsParams packParams(area, format, type, static_cast(outputPitch), pack, - reinterpret_cast(pixels)); + packBuffer, reinterpret_cast(pixels)); - return packBufferStorage->packPixels(*readAttachment, packParams); + return packBufferStorage->packPixels(context, *readAttachment, packParams); } - return mRenderer->readFromAttachment(*readAttachment, area, format, type, + return mRenderer->readFromAttachment(context, *readAttachment, area, format, type, static_cast(outputPitch), pack, pixels); } -gl::Error Framebuffer11::blit(const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, const gl::Rectangle *scissor, - bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter, - const gl::Framebuffer *sourceFramebuffer) +gl::Error Framebuffer11::blitImpl(const gl::Context *context, + const gl::Rectangle &sourceArea, + const gl::Rectangle &destArea, + const gl::Rectangle *scissor, + bool blitRenderTarget, + bool blitDepth, + bool blitStencil, + GLenum filter, + const gl::Framebuffer *sourceFramebuffer) { if (blitRenderTarget) { @@ -325,15 +316,11 @@ gl::Error Framebuffer11::blit(const gl::Rectangle &sourceArea, const gl::Rectang ASSERT(readBuffer); RenderTargetD3D *readRenderTarget = nullptr; - gl::Error error = readBuffer->getRenderTarget(&readRenderTarget); - if (error.isError()) - { - return error; - } + ANGLE_TRY(readBuffer->getRenderTarget(context, &readRenderTarget)); ASSERT(readRenderTarget); - const auto &colorAttachments = mData.getColorAttachments(); - const auto &drawBufferStates = mData.getDrawBufferStates(); + const auto &colorAttachments = mState.getColorAttachments(); + const auto &drawBufferStates = mState.getDrawBufferStates(); for (size_t colorAttachment = 0; colorAttachment < colorAttachments.size(); colorAttachment++) { @@ -343,11 +330,7 @@ gl::Error Framebuffer11::blit(const gl::Rectangle &sourceArea, const gl::Rectang drawBufferStates[colorAttachment] != GL_NONE) { RenderTargetD3D *drawRenderTarget = nullptr; - error = drawBuffer.getRenderTarget(&drawRenderTarget); - if (error.isError()) - { - return error; - } + ANGLE_TRY(drawBuffer.getRenderTarget(context, &drawRenderTarget)); ASSERT(drawRenderTarget); const bool invertColorSource = UsePresentPathFast(mRenderer, readBuffer); @@ -368,13 +351,9 @@ gl::Error Framebuffer11::blit(const gl::Rectangle &sourceArea, const gl::Rectang actualDestArea.height = -destArea.height; } - error = mRenderer->blitRenderbufferRect(actualSourceArea, actualDestArea, - readRenderTarget, drawRenderTarget, filter, - scissor, blitRenderTarget, false, false); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mRenderer->blitRenderbufferRect( + context, actualSourceArea, actualDestArea, readRenderTarget, drawRenderTarget, + filter, scissor, blitRenderTarget, false, false)); } } } @@ -385,46 +364,144 @@ gl::Error Framebuffer11::blit(const gl::Rectangle &sourceArea, const gl::Rectang ASSERT(readBuffer); RenderTargetD3D *readRenderTarget = nullptr; - gl::Error error = readBuffer->getRenderTarget(&readRenderTarget); - if (error.isError()) - { - return error; - } + ANGLE_TRY(readBuffer->getRenderTarget(context, &readRenderTarget)); ASSERT(readRenderTarget); - const gl::FramebufferAttachment *drawBuffer = mData.getDepthOrStencilAttachment(); + const gl::FramebufferAttachment *drawBuffer = mState.getDepthOrStencilAttachment(); ASSERT(drawBuffer); RenderTargetD3D *drawRenderTarget = nullptr; - error = drawBuffer->getRenderTarget(&drawRenderTarget); - if (error.isError()) - { - return error; - } + ANGLE_TRY(drawBuffer->getRenderTarget(context, &drawRenderTarget)); ASSERT(drawRenderTarget); - error = mRenderer->blitRenderbufferRect(sourceArea, destArea, readRenderTarget, drawRenderTarget, filter, scissor, - false, blitDepth, blitStencil); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mRenderer->blitRenderbufferRect(context, sourceArea, destArea, readRenderTarget, + drawRenderTarget, filter, scissor, false, + blitDepth, blitStencil)); } - gl::Error error = invalidateSwizzles(); - if (error.isError()) - { - return error; - } - - return gl::Error(GL_NO_ERROR); + ANGLE_TRY(markAttachmentsDirty(context)); + return gl::NoError(); } GLenum Framebuffer11::getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const { RenderTarget11 *renderTarget11 = GetAs(renderTarget); - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(renderTarget11->getDXGIFormat()); - return dxgiFormatInfo.internalFormat; + return renderTarget11->getFormatSet().format().fboImplementationInternalFormat; } +void Framebuffer11::updateColorRenderTarget(const gl::Context *context, size_t colorIndex) +{ + UpdateCachedRenderTarget(context, mState.getColorAttachment(colorIndex), + mCachedColorRenderTargets[colorIndex], + &mColorRenderTargetsDirty[colorIndex]); } + +void Framebuffer11::updateDepthStencilRenderTarget(const gl::Context *context) +{ + UpdateCachedRenderTarget(context, mState.getDepthOrStencilAttachment(), + mCachedDepthStencilRenderTarget, &mDepthStencilRenderTargetDirty); +} + +void Framebuffer11::syncState(const gl::Context *context, + const gl::Framebuffer::DirtyBits &dirtyBits) +{ + const auto &mergedDirtyBits = dirtyBits | mInternalDirtyBits; + mInternalDirtyBits.reset(); + + for (auto dirtyBit : mergedDirtyBits) + { + switch (dirtyBit) + { + case gl::Framebuffer::DIRTY_BIT_DEPTH_ATTACHMENT: + case gl::Framebuffer::DIRTY_BIT_STENCIL_ATTACHMENT: + updateDepthStencilRenderTarget(context); + break; + case gl::Framebuffer::DIRTY_BIT_DRAW_BUFFERS: + case gl::Framebuffer::DIRTY_BIT_READ_BUFFER: + break; + case gl::Framebuffer::DIRTY_BIT_DEFAULT_WIDTH: + case gl::Framebuffer::DIRTY_BIT_DEFAULT_HEIGHT: + case gl::Framebuffer::DIRTY_BIT_DEFAULT_SAMPLES: + case gl::Framebuffer::DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS: + break; + default: + { + ASSERT(gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 == 0 && + dirtyBit < gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX); + size_t colorIndex = + static_cast(dirtyBit - gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0); + updateColorRenderTarget(context, colorIndex); + break; + } + } + } + + // We should not have dirtied any additional state during our sync. + ASSERT(!mInternalDirtyBits.any()); + + FramebufferD3D::syncState(context, dirtyBits); + + // Call this last to allow the state manager to take advantage of the cached render targets. + mRenderer->getStateManager()->invalidateRenderTarget(); + + // Call this to syncViewport for framebuffer default parameters. + if (mState.getDefaultWidth() != 0 || mState.getDefaultHeight() != 0) + { + mRenderer->getStateManager()->invalidateViewport(context); + } +} + +void Framebuffer11::signal(size_t channelID, const gl::Context *context) +{ + if (channelID == gl::IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS) + { + // Stencil is redundant in this case. + mInternalDirtyBits.set(gl::Framebuffer::DIRTY_BIT_DEPTH_ATTACHMENT); + mCachedDepthStencilRenderTarget = nullptr; + } + else + { + mInternalDirtyBits.set(gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 + channelID); + mCachedColorRenderTargets[channelID] = nullptr; + } + + // Notify the context we need to re-validate the RenderTarget. + // TODO(jmadill): Check that we're the active draw framebuffer. + mRenderer->getStateManager()->invalidateRenderTarget(); +} + +gl::Error Framebuffer11::getSamplePosition(size_t index, GLfloat *xy) const +{ + const gl::FramebufferAttachment *attachment = mState.getFirstNonNullAttachment(); + ASSERT(attachment); + GLsizei sampleCount = attachment->getSamples(); + + d3d11_gl::GetSamplePosition(sampleCount, index, xy); + return gl::NoError(); +} + +bool Framebuffer11::hasAnyInternalDirtyBit() const +{ + return mInternalDirtyBits.any(); +} + +void Framebuffer11::syncInternalState(const gl::Context *context) +{ + syncState(context, gl::Framebuffer::DirtyBits()); +} + +RenderTarget11 *Framebuffer11::getFirstRenderTarget() const +{ + ASSERT(mInternalDirtyBits.none()); + for (auto *renderTarget : mCachedColorRenderTargets) + { + if (renderTarget) + { + return renderTarget; + } + } + + return mCachedDepthStencilRenderTarget; +} + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h index c8a33ec7e5..afdda299b9 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h @@ -10,43 +10,93 @@ #define LIBANGLE_RENDERER_D3D_D3D11_FRAMBUFFER11_H_ #include "libANGLE/renderer/d3d/FramebufferD3D.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/signal_utils.h" namespace rx { class Renderer11; -class Framebuffer11 : public FramebufferD3D +class Framebuffer11 : public FramebufferD3D, public OnRenderTargetDirtyReceiver { public: - Framebuffer11(const gl::Framebuffer::Data &data, Renderer11 *renderer); - virtual ~Framebuffer11(); + Framebuffer11(const gl::FramebufferState &data, Renderer11 *renderer); + ~Framebuffer11() override; - gl::Error discard(size_t count, const GLenum *attachments) override; - gl::Error invalidate(size_t count, const GLenum *attachments) override; - gl::Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) override; + gl::Error discard(const gl::Context *context, size_t count, const GLenum *attachments) override; + gl::Error invalidate(const gl::Context *context, + size_t count, + const GLenum *attachments) override; + gl::Error invalidateSub(const gl::Context *context, + size_t count, + const GLenum *attachments, + const gl::Rectangle &area) override; // Invalidate the cached swizzles of all bound texture attachments. - gl::Error invalidateSwizzles() const; + gl::Error markAttachmentsDirty(const gl::Context *context) const; + + void syncState(const gl::Context *context, + const gl::Framebuffer::DirtyBits &dirtyBits) override; + + const RenderTargetArray &getCachedColorRenderTargets() const + { + return mCachedColorRenderTargets; + } + const RenderTarget11 *getCachedDepthStencilRenderTarget() const + { + return mCachedDepthStencilRenderTarget; + } + + RenderTarget11 *getFirstRenderTarget() const; + + bool hasAnyInternalDirtyBit() const; + void syncInternalState(const gl::Context *context); + + void signal(size_t channelID, const gl::Context *context) override; + + gl::Error getSamplePosition(size_t index, GLfloat *xy) const override; private: - gl::Error clear(const gl::Data &data, const ClearParameters &clearParams) override; + gl::Error clearImpl(const gl::Context *context, const ClearParameters &clearParams) override; - gl::Error readPixelsImpl(const gl::Rectangle &area, + gl::Error readPixelsImpl(const gl::Context *context, + const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch, const gl::PixelPackState &pack, - uint8_t *pixels) const override; + uint8_t *pixels) override; - gl::Error blit(const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, const gl::Rectangle *scissor, - bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter, - const gl::Framebuffer *sourceFramebuffer) override; + gl::Error blitImpl(const gl::Context *context, + const gl::Rectangle &sourceArea, + const gl::Rectangle &destArea, + const gl::Rectangle *scissor, + bool blitRenderTarget, + bool blitDepth, + bool blitStencil, + GLenum filter, + const gl::Framebuffer *sourceFramebuffer) override; - gl::Error invalidateBase(size_t count, const GLenum *attachments, bool useEXTBehavior) const; + gl::Error invalidateBase(const gl::Context *context, + size_t count, + const GLenum *attachments, + bool useEXTBehavior) const; + gl::Error invalidateAttachment(const gl::Context *context, + const gl::FramebufferAttachment *attachment) const; GLenum getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const override; + void updateColorRenderTarget(const gl::Context *context, size_t colorIndex); + void updateDepthStencilRenderTarget(const gl::Context *context); + Renderer11 *const mRenderer; + RenderTargetArray mCachedColorRenderTargets; + RenderTarget11 *mCachedDepthStencilRenderTarget; + + std::vector mColorRenderTargetsDirty; + OnRenderTargetDirtyBinding mDepthStencilRenderTargetDirty; + + gl::Framebuffer::DirtyBits mInternalDirtyBits; }; } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Image11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Image11.cpp index c52092d81e..bd921f1935 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Image11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Image11.cpp @@ -26,10 +26,10 @@ namespace rx Image11::Image11(Renderer11 *renderer) : mRenderer(renderer), mDXGIFormat(DXGI_FORMAT_UNKNOWN), - mStagingTexture(NULL), + mStagingTexture(), mStagingSubresource(0), mRecoverFromStorage(false), - mAssociatedStorage(NULL), + mAssociatedStorage(nullptr), mAssociatedImageIndex(gl::ImageIndex::MakeInvalid()), mRecoveredFromStorageCount(0) { @@ -41,55 +41,106 @@ Image11::~Image11() releaseStagingTexture(); } -gl::Error Image11::generateMipmap(Image11 *dest, Image11 *src) +// static +gl::Error Image11::GenerateMipmap(const gl::Context *context, + Image11 *dest, + Image11 *src, + const Renderer11DeviceCaps &rendererCaps) { ASSERT(src->getDXGIFormat() == dest->getDXGIFormat()); ASSERT(src->getWidth() == 1 || src->getWidth() / 2 == dest->getWidth()); ASSERT(src->getHeight() == 1 || src->getHeight() / 2 == dest->getHeight()); - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(src->getDXGIFormat()); - ASSERT(dxgiFormatInfo.mipGenerationFunction != NULL); - D3D11_MAPPED_SUBRESOURCE destMapped; - gl::Error error = dest->map(D3D11_MAP_WRITE, &destMapped); - if (error.isError()) - { - return error; - } + ANGLE_TRY(dest->map(context, D3D11_MAP_WRITE, &destMapped)); D3D11_MAPPED_SUBRESOURCE srcMapped; - error = src->map(D3D11_MAP_READ, &srcMapped); + gl::Error error = src->map(context, D3D11_MAP_READ, &srcMapped); if (error.isError()) { dest->unmap(); return error; } - const uint8_t *sourceData = reinterpret_cast(srcMapped.pData); - uint8_t *destData = reinterpret_cast(destMapped.pData); + const uint8_t *sourceData = reinterpret_cast(srcMapped.pData); + uint8_t *destData = reinterpret_cast(destMapped.pData); - dxgiFormatInfo.mipGenerationFunction(src->getWidth(), src->getHeight(), src->getDepth(), - sourceData, srcMapped.RowPitch, srcMapped.DepthPitch, - destData, destMapped.RowPitch, destMapped.DepthPitch); + auto mipGenerationFunction = + d3d11::Format::Get(src->getInternalFormat(), rendererCaps).format().mipGenerationFunction; + mipGenerationFunction(src->getWidth(), src->getHeight(), src->getDepth(), sourceData, + srcMapped.RowPitch, srcMapped.DepthPitch, destData, destMapped.RowPitch, + destMapped.DepthPitch); dest->unmap(); src->unmap(); dest->markDirty(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); +} + +// static +gl::Error Image11::CopyImage(const gl::Context *context, + Image11 *dest, + Image11 *source, + const gl::Rectangle &sourceRect, + const gl::Offset &destOffset, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const Renderer11DeviceCaps &rendererCaps) +{ + D3D11_MAPPED_SUBRESOURCE destMapped; + ANGLE_TRY(dest->map(context, D3D11_MAP_WRITE, &destMapped)); + + D3D11_MAPPED_SUBRESOURCE srcMapped; + gl::Error error = source->map(context, D3D11_MAP_READ, &srcMapped); + if (error.isError()) + { + dest->unmap(); + return error; + } + + const auto &sourceFormat = + d3d11::Format::Get(source->getInternalFormat(), rendererCaps).format(); + GLuint sourcePixelBytes = + gl::GetSizedInternalFormatInfo(sourceFormat.fboImplementationInternalFormat).pixelBytes; + + GLenum destUnsizedFormat = gl::GetUnsizedFormat(dest->getInternalFormat()); + const auto &destFormat = d3d11::Format::Get(dest->getInternalFormat(), rendererCaps).format(); + const auto &destFormatInfo = + gl::GetSizedInternalFormatInfo(destFormat.fboImplementationInternalFormat); + GLuint destPixelBytes = destFormatInfo.pixelBytes; + + const uint8_t *sourceData = reinterpret_cast(srcMapped.pData) + + sourceRect.x * sourcePixelBytes + sourceRect.y * srcMapped.RowPitch; + uint8_t *destData = reinterpret_cast(destMapped.pData) + + destOffset.x * destPixelBytes + destOffset.y * destMapped.RowPitch; + + CopyImageCHROMIUM(sourceData, srcMapped.RowPitch, sourcePixelBytes, + sourceFormat.colorReadFunction, destData, destMapped.RowPitch, destPixelBytes, + destFormat.colorWriteFunction, destUnsizedFormat, + destFormatInfo.componentType, sourceRect.width, sourceRect.height, + unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha); + + dest->unmap(); + source->unmap(); + + dest->markDirty(); + + return gl::NoError(); } bool Image11::isDirty() const { - // If mDirty is true - // AND mStagingTexture doesn't exist AND mStagingTexture doesn't need to be recovered from TextureStorage - // AND the texture doesn't require init data (i.e. a blank new texture will suffice) - // then isDirty should still return false. - if (mDirty && !mStagingTexture && !mRecoverFromStorage) + // If mDirty is true AND mStagingTexture doesn't exist AND mStagingTexture doesn't need to be + // recovered from TextureStorage AND the texture doesn't require init data (i.e. a blank new + // texture will suffice) AND robust resource initialization is not enabled then isDirty should + // still return false. + if (mDirty && !mStagingTexture.valid() && !mRecoverFromStorage) { const Renderer11DeviceCaps &deviceCaps = mRenderer->getRenderer11DeviceCaps(); - const d3d11::TextureFormat formatInfo = d3d11::GetTextureFormatInfo(mInternalFormat, deviceCaps); + const auto &formatInfo = d3d11::Format::Get(mInternalFormat, deviceCaps); if (formatInfo.dataInitializerFunction == nullptr) { return false; @@ -99,92 +150,69 @@ bool Image11::isDirty() const return mDirty; } -gl::Error Image11::copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box ®ion) +gl::Error Image11::copyToStorage(const gl::Context *context, + TextureStorage *storage, + const gl::ImageIndex &index, + const gl::Box ®ion) { TextureStorage11 *storage11 = GetAs(storage); - // If an app's behavior results in an Image11 copying its data to/from to a TextureStorage multiple times, - // then we should just keep the staging texture around to prevent the copying from impacting perf. - // We allow the Image11 to copy its data to/from TextureStorage once. - // This accounts for an app making a late call to glGenerateMipmap. + // If an app's behavior results in an Image11 copying its data to/from to a TextureStorage + // multiple times, then we should just keep the staging texture around to prevent the copying + // from impacting perf. We allow the Image11 to copy its data to/from TextureStorage once. This + // accounts for an app making a late call to glGenerateMipmap. bool attemptToReleaseStagingTexture = (mRecoveredFromStorageCount < 2); if (attemptToReleaseStagingTexture) { - // If another image is relying on this Storage for its data, then we must let it recover its data before we overwrite it. - gl::Error error = storage11->releaseAssociatedImage(index, this); - if (error.isError()) - { - return error; - } + // If another image is relying on this Storage for its data, then we must let it recover its + // data before we overwrite it. + ANGLE_TRY(storage11->releaseAssociatedImage(context, index, this)); } - ID3D11Resource *stagingTexture = NULL; + const TextureHelper11 *stagingTexture = nullptr; unsigned int stagingSubresourceIndex = 0; - gl::Error error = getStagingTexture(&stagingTexture, &stagingSubresourceIndex); - if (error.isError()) - { - return error; - } - - error = storage11->updateSubresourceLevel(stagingTexture, stagingSubresourceIndex, index, region); - if (error.isError()) - { - return error; - } + ANGLE_TRY(getStagingTexture(&stagingTexture, &stagingSubresourceIndex)); + ANGLE_TRY(storage11->updateSubresourceLevel(context, *stagingTexture, stagingSubresourceIndex, + index, region)); // Once the image data has been copied into the Storage, we can release it locally. if (attemptToReleaseStagingTexture) { storage11->associateImage(this, index); releaseStagingTexture(); - mRecoverFromStorage = true; - mAssociatedStorage = storage11; + mRecoverFromStorage = true; + mAssociatedStorage = storage11; mAssociatedImageIndex = index; } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -bool Image11::isAssociatedStorageValid(TextureStorage11* textureStorage) const +void Image11::verifyAssociatedStorageValid(TextureStorage11 *textureStorage) const { - return (mAssociatedStorage == textureStorage); + ASSERT(mAssociatedStorage == textureStorage); } -gl::Error Image11::recoverFromAssociatedStorage() +gl::Error Image11::recoverFromAssociatedStorage(const gl::Context *context) { if (mRecoverFromStorage) { - gl::Error error = createStagingTexture(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(createStagingTexture()); - bool textureStorageCorrect = mAssociatedStorage->isAssociatedImageValid(mAssociatedImageIndex, this); + mAssociatedStorage->verifyAssociatedImageValid(mAssociatedImageIndex, this); - // This means that the cached TextureStorage has been modified after this Image11 released its copy of its data. - // This should not have happened. The TextureStorage should have told this Image11 to recover its data before it was overwritten. - ASSERT(textureStorageCorrect); - - if (textureStorageCorrect) - { - // CopySubResource from the Storage to the Staging texture - gl::Box region(0, 0, 0, mWidth, mHeight, mDepth); - error = mAssociatedStorage->copySubresourceLevel(mStagingTexture, mStagingSubresource, mAssociatedImageIndex, region); - if (error.isError()) - { - return error; - } - - mRecoveredFromStorageCount += 1; - } + // CopySubResource from the Storage to the Staging texture + gl::Box region(0, 0, 0, mWidth, mHeight, mDepth); + ANGLE_TRY(mAssociatedStorage->copySubresourceLevel( + context, mStagingTexture, mStagingSubresource, mAssociatedImageIndex, region)); + mRecoveredFromStorageCount += 1; // Reset all the recovery parameters, even if the texture storage association is broken. disassociateStorage(); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } void Image11::disassociateStorage() @@ -194,17 +222,18 @@ void Image11::disassociateStorage() // Make the texturestorage release the Image11 too mAssociatedStorage->disassociateImage(mAssociatedImageIndex, this); - mRecoverFromStorage = false; - mAssociatedStorage = NULL; + mRecoverFromStorage = false; + mAssociatedStorage = nullptr; mAssociatedImageIndex = gl::ImageIndex::MakeInvalid(); } } -bool Image11::redefine(GLenum target, GLenum internalformat, const gl::Extents &size, bool forceRelease) +bool Image11::redefine(GLenum target, + GLenum internalformat, + const gl::Extents &size, + bool forceRelease) { - if (mWidth != size.width || - mHeight != size.height || - mInternalFormat != internalformat || + if (mWidth != size.width || mHeight != size.height || mInternalFormat != internalformat || forceRelease) { // End the association with the TextureStorage, since that data will be out of date. @@ -212,19 +241,20 @@ bool Image11::redefine(GLenum target, GLenum internalformat, const gl::Extents & disassociateStorage(); mRecoveredFromStorageCount = 0; - mWidth = size.width; - mHeight = size.height; - mDepth = size.depth; + mWidth = size.width; + mHeight = size.height; + mDepth = size.depth; mInternalFormat = internalformat; - mTarget = target; + mTarget = target; // compute the d3d format that will be used - const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat, mRenderer->getRenderer11DeviceCaps()); + const d3d11::Format &formatInfo = + d3d11::Format::Get(internalformat, mRenderer->getRenderer11DeviceCaps()); mDXGIFormat = formatInfo.texFormat; mRenderable = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN); releaseStagingTexture(); - mDirty = (formatInfo.dataInitializerFunction != NULL); + mDirty = (formatInfo.dataInitializerFunction != nullptr); return true; } @@ -241,119 +271,125 @@ DXGI_FORMAT Image11::getDXGIFormat() const return mDXGIFormat; } -// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input +// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as +// format/type at input // into the target pixel rectangle. -gl::Error Image11::loadData(const gl::Box &area, const gl::PixelUnpackState &unpack, GLenum type, const void *input) +gl::Error Image11::loadData(const gl::Context *context, + const gl::Box &area, + const gl::PixelUnpackState &unpack, + GLenum type, + const void *input, + bool applySkipImages) { - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); - GLsizei inputRowPitch = formatInfo.computeRowPitch(type, area.width, unpack.alignment, unpack.rowLength); - GLsizei inputDepthPitch = formatInfo.computeDepthPitch( - type, area.width, area.height, unpack.alignment, unpack.rowLength, unpack.imageHeight); - GLsizei inputSkipBytes = formatInfo.computeSkipPixels( - inputRowPitch, inputDepthPitch, unpack.skipImages, unpack.skipRows, unpack.skipPixels); + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(mInternalFormat); + GLuint inputRowPitch = 0; + ANGLE_TRY_RESULT( + formatInfo.computeRowPitch(type, area.width, unpack.alignment, unpack.rowLength), + inputRowPitch); + GLuint inputDepthPitch = 0; + ANGLE_TRY_RESULT(formatInfo.computeDepthPitch(area.height, unpack.imageHeight, inputRowPitch), + inputDepthPitch); + GLuint inputSkipBytes = 0; + ANGLE_TRY_RESULT( + formatInfo.computeSkipBytes(inputRowPitch, inputDepthPitch, unpack, applySkipImages), + inputSkipBytes); - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mDXGIFormat); - GLuint outputPixelSize = dxgiFormatInfo.pixelBytes; + const d3d11::DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(mDXGIFormat); + GLuint outputPixelSize = dxgiFormatInfo.pixelBytes; - const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat, mRenderer->getRenderer11DeviceCaps()); - LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(type).loadFunction; + const d3d11::Format &d3dFormatInfo = + d3d11::Format::Get(mInternalFormat, mRenderer->getRenderer11DeviceCaps()); + LoadImageFunction loadFunction = d3dFormatInfo.getLoadFunctions()(type).loadFunction; D3D11_MAPPED_SUBRESOURCE mappedImage; - gl::Error error = map(D3D11_MAP_WRITE, &mappedImage); - if (error.isError()) - { - return error; - } + ANGLE_TRY(map(context, D3D11_MAP_WRITE, &mappedImage)); - uint8_t *offsetMappedData = (reinterpret_cast(mappedImage.pData) + (area.y * mappedImage.RowPitch + area.x * outputPixelSize + area.z * mappedImage.DepthPitch)); + uint8_t *offsetMappedData = (reinterpret_cast(mappedImage.pData) + + (area.y * mappedImage.RowPitch + area.x * outputPixelSize + + area.z * mappedImage.DepthPitch)); loadFunction(area.width, area.height, area.depth, reinterpret_cast(input) + inputSkipBytes, inputRowPitch, inputDepthPitch, offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch); unmap(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Image11::loadCompressedData(const gl::Box &area, const void *input) +gl::Error Image11::loadCompressedData(const gl::Context *context, + const gl::Box &area, + const void *input) { - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); - GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, area.width, 1, 0); - GLsizei inputDepthPitch = - formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0, 0); + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(mInternalFormat); + GLsizei inputRowPitch = 0; + ANGLE_TRY_RESULT(formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, area.width, 1, 0), inputRowPitch); + GLsizei inputDepthPitch = 0; + ANGLE_TRY_RESULT(formatInfo.computeDepthPitch(area.height, 0, inputRowPitch), inputDepthPitch); - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mDXGIFormat); - GLuint outputPixelSize = dxgiFormatInfo.pixelBytes; - GLuint outputBlockWidth = dxgiFormatInfo.blockWidth; - GLuint outputBlockHeight = dxgiFormatInfo.blockHeight; + const d3d11::DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(mDXGIFormat); + GLuint outputPixelSize = dxgiFormatInfo.pixelBytes; + GLuint outputBlockWidth = dxgiFormatInfo.blockWidth; + GLuint outputBlockHeight = dxgiFormatInfo.blockHeight; ASSERT(area.x % outputBlockWidth == 0); ASSERT(area.y % outputBlockHeight == 0); - const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(mInternalFormat, mRenderer->getRenderer11DeviceCaps()); - LoadImageFunction loadFunction = d3dFormatInfo.loadFunctions.at(GL_UNSIGNED_BYTE).loadFunction; + const d3d11::Format &d3dFormatInfo = + d3d11::Format::Get(mInternalFormat, mRenderer->getRenderer11DeviceCaps()); + LoadImageFunction loadFunction = + d3dFormatInfo.getLoadFunctions()(GL_UNSIGNED_BYTE).loadFunction; D3D11_MAPPED_SUBRESOURCE mappedImage; - gl::Error error = map(D3D11_MAP_WRITE, &mappedImage); - if (error.isError()) - { - return error; - } + ANGLE_TRY(map(context, D3D11_MAP_WRITE, &mappedImage)); - uint8_t* offsetMappedData = reinterpret_cast(mappedImage.pData) + ((area.y / outputBlockHeight) * mappedImage.RowPitch + - (area.x / outputBlockWidth) * outputPixelSize + - area.z * mappedImage.DepthPitch); + uint8_t *offsetMappedData = + reinterpret_cast(mappedImage.pData) + + ((area.y / outputBlockHeight) * mappedImage.RowPitch + + (area.x / outputBlockWidth) * outputPixelSize + area.z * mappedImage.DepthPitch); - loadFunction(area.width, area.height, area.depth, - reinterpret_cast(input), inputRowPitch, inputDepthPitch, - offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch); + loadFunction(area.width, area.height, area.depth, reinterpret_cast(input), + inputRowPitch, inputDepthPitch, offsetMappedData, mappedImage.RowPitch, + mappedImage.DepthPitch); unmap(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Image11::copyFromTexStorage(const gl::ImageIndex &imageIndex, TextureStorage *source) +gl::Error Image11::copyFromTexStorage(const gl::Context *context, + const gl::ImageIndex &imageIndex, + TextureStorage *source) { TextureStorage11 *storage11 = GetAs(source); - ID3D11Resource *resource = nullptr; - gl::Error error = storage11->getResource(&resource); - if (error.isError()) - { - return error; - } + const TextureHelper11 *textureHelper = nullptr; + ANGLE_TRY(storage11->getResource(context, &textureHelper)); - UINT subresourceIndex = storage11->getSubresourceIndex(imageIndex); - TextureHelper11 textureHelper = TextureHelper11::MakeAndReference(resource); + UINT subresourceIndex = storage11->getSubresourceIndex(imageIndex); gl::Box sourceBox(0, 0, 0, mWidth, mHeight, mDepth); - return copyWithoutConversion(gl::Offset(), sourceBox, textureHelper, subresourceIndex); + return copyWithoutConversion(gl::Offset(), sourceBox, *textureHelper, subresourceIndex); } -gl::Error Image11::copyFromFramebuffer(const gl::Offset &destOffset, +gl::Error Image11::copyFromFramebuffer(const gl::Context *context, + const gl::Offset &destOffset, const gl::Rectangle &sourceArea, const gl::Framebuffer *sourceFBO) { const gl::FramebufferAttachment *srcAttachment = sourceFBO->getReadColorbuffer(); ASSERT(srcAttachment); - const auto &d3d11Format = d3d11::GetTextureFormatInfo(srcAttachment->getInternalFormat(), - mRenderer->getRenderer11DeviceCaps()); + GLenum sourceInternalFormat = srcAttachment->getFormat().info->sizedInternalFormat; + const auto &d3d11Format = + d3d11::Format::Get(sourceInternalFormat, mRenderer->getRenderer11DeviceCaps()); - if (d3d11Format.texFormat == mDXGIFormat) + if (d3d11Format.texFormat == mDXGIFormat && sourceInternalFormat == mInternalFormat) { - RenderTargetD3D *renderTarget = nullptr; - gl::Error error = srcAttachment->getRenderTarget(&renderTarget); - if (error.isError()) - { - return error; - } + RenderTarget11 *rt11 = nullptr; + ANGLE_TRY(srcAttachment->getRenderTarget(context, &rt11)); + ASSERT(rt11->getTexture().get()); - RenderTarget11 *rt11 = GetAs(renderTarget); - ASSERT(rt11->getTexture()); - - TextureHelper11 textureHelper = TextureHelper11::MakeAndReference(rt11->getTexture()); + TextureHelper11 textureHelper = rt11->getTexture(); unsigned int sourceSubResource = rt11->getSubresourceIndex(); gl::Box sourceBox(sourceArea.x, sourceArea.y, 0, sourceArea.width, sourceArea.height, 1); @@ -363,25 +399,47 @@ gl::Error Image11::copyFromFramebuffer(const gl::Offset &destOffset, // This format requires conversion, so we must copy the texture to staging and manually convert // via readPixels D3D11_MAPPED_SUBRESOURCE mappedImage; - gl::Error error = map(D3D11_MAP_WRITE, &mappedImage); - if (error.isError()) - { - return error; - } + ANGLE_TRY(map(context, D3D11_MAP_WRITE, &mappedImage)); // determine the offset coordinate into the destination buffer - const auto &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mDXGIFormat); + const auto &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(mDXGIFormat); GLsizei rowOffset = dxgiFormatInfo.pixelBytes * destOffset.x; uint8_t *dataOffset = static_cast(mappedImage.pData) + mappedImage.RowPitch * destOffset.y + rowOffset + destOffset.z * mappedImage.DepthPitch; - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); + const gl::InternalFormat &destFormatInfo = gl::GetSizedInternalFormatInfo(mInternalFormat); + const auto &destD3D11Format = + d3d11::Format::Get(mInternalFormat, mRenderer->getRenderer11DeviceCaps()); - error = mRenderer->readFromAttachment(*srcAttachment, sourceArea, formatInfo.format, - formatInfo.type, mappedImage.RowPitch, - gl::PixelPackState(), dataOffset); + auto loadFunction = destD3D11Format.getLoadFunctions()(destFormatInfo.type); + gl::Error error = gl::NoError(); + if (loadFunction.requiresConversion) + { + size_t bufferSize = destFormatInfo.pixelBytes * sourceArea.width * sourceArea.height; + angle::MemoryBuffer *memoryBuffer = nullptr; + error = mRenderer->getScratchMemoryBuffer(bufferSize, &memoryBuffer); + + if (!error.isError()) + { + GLuint memoryBufferRowPitch = destFormatInfo.pixelBytes * sourceArea.width; + + error = mRenderer->readFromAttachment( + context, *srcAttachment, sourceArea, destFormatInfo.format, destFormatInfo.type, + memoryBufferRowPitch, gl::PixelPackState(), memoryBuffer->data()); + + loadFunction.loadFunction(sourceArea.width, sourceArea.height, 1, memoryBuffer->data(), + memoryBufferRowPitch, 0, dataOffset, mappedImage.RowPitch, + mappedImage.DepthPitch); + } + } + else + { + error = mRenderer->readFromAttachment( + context, *srcAttachment, sourceArea, destFormatInfo.format, destFormatInfo.type, + mappedImage.RowPitch, gl::PixelPackState(), dataOffset); + } unmap(); mDirty = true; @@ -395,26 +453,23 @@ gl::Error Image11::copyWithoutConversion(const gl::Offset &destOffset, UINT sourceSubResource) { // No conversion needed-- use copyback fastpath - ID3D11Resource *stagingTexture = nullptr; + const TextureHelper11 *stagingTexture = nullptr; unsigned int stagingSubresourceIndex = 0; - gl::Error error = getStagingTexture(&stagingTexture, &stagingSubresourceIndex); - if (error.isError()) - { - return error; - } + ANGLE_TRY(getStagingTexture(&stagingTexture, &stagingSubresourceIndex)); - ID3D11Device *device = mRenderer->getDevice(); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); - UINT subresourceAfterResolve = sourceSubResource; - - ID3D11Resource *srcTex = nullptr; const gl::Extents &extents = textureHelper.getExtents(); - bool needResolve = - (textureHelper.getTextureType() == GL_TEXTURE_2D && textureHelper.getSampleCount() > 1); + D3D11_BOX srcBox; + srcBox.left = sourceArea.x; + srcBox.right = sourceArea.x + sourceArea.width; + srcBox.top = sourceArea.y; + srcBox.bottom = sourceArea.y + sourceArea.height; + srcBox.front = sourceArea.z; + srcBox.back = sourceArea.z + sourceArea.depth; - if (needResolve) + if (textureHelper.is2D() && textureHelper.getSampleCount() > 1) { D3D11_TEXTURE2D_DESC resolveDesc; resolveDesc.Width = extents.width; @@ -429,80 +484,57 @@ gl::Error Image11::copyWithoutConversion(const gl::Offset &destOffset, resolveDesc.CPUAccessFlags = 0; resolveDesc.MiscFlags = 0; - ID3D11Texture2D *srcTex2D = NULL; - HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex2D); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, - "Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", - result); - } - srcTex = srcTex2D; + d3d11::Texture2D resolveTex; + ANGLE_TRY(mRenderer->allocateResource(resolveDesc, &resolveTex)); - deviceContext->ResolveSubresource(srcTex, 0, textureHelper.getTexture2D(), + deviceContext->ResolveSubresource(resolveTex.get(), 0, textureHelper.get(), sourceSubResource, textureHelper.getFormat()); - subresourceAfterResolve = 0; + + deviceContext->CopySubresourceRegion(stagingTexture->get(), stagingSubresourceIndex, + destOffset.x, destOffset.y, destOffset.z, + resolveTex.get(), 0, &srcBox); } else { - srcTex = textureHelper.getResource(); - } - - D3D11_BOX srcBox; - srcBox.left = sourceArea.x; - srcBox.right = sourceArea.x + sourceArea.width; - srcBox.top = sourceArea.y; - srcBox.bottom = sourceArea.y + sourceArea.height; - srcBox.front = sourceArea.z; - srcBox.back = sourceArea.z + sourceArea.depth; - - deviceContext->CopySubresourceRegion(stagingTexture, stagingSubresourceIndex, destOffset.x, - destOffset.y, destOffset.z, srcTex, - subresourceAfterResolve, &srcBox); - - if (needResolve) - { - SafeRelease(srcTex); + deviceContext->CopySubresourceRegion(stagingTexture->get(), stagingSubresourceIndex, + destOffset.x, destOffset.y, destOffset.z, + textureHelper.get(), sourceSubResource, &srcBox); } mDirty = true; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Image11::getStagingTexture(ID3D11Resource **outStagingTexture, unsigned int *outSubresourceIndex) +gl::Error Image11::getStagingTexture(const TextureHelper11 **outStagingTexture, + unsigned int *outSubresourceIndex) { - gl::Error error = createStagingTexture(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(createStagingTexture()); - *outStagingTexture = mStagingTexture; + *outStagingTexture = &mStagingTexture; *outSubresourceIndex = mStagingSubresource; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } void Image11::releaseStagingTexture() { - SafeRelease(mStagingTexture); + mStagingTexture.reset(); } gl::Error Image11::createStagingTexture() { - if (mStagingTexture) + if (mStagingTexture.valid()) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } ASSERT(mWidth > 0 && mHeight > 0 && mDepth > 0); const DXGI_FORMAT dxgiFormat = getDXGIFormat(); + const auto &formatInfo = + d3d11::Format::Get(mInternalFormat, mRenderer->getRenderer11DeviceCaps()); - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result; - - int lodOffset = 1; - GLsizei width = mWidth; + int lodOffset = 1; + GLsizei width = mWidth; GLsizei height = mHeight; // adjust size if needed for compressed textures @@ -510,80 +542,69 @@ gl::Error Image11::createStagingTexture() if (mTarget == GL_TEXTURE_3D) { - ID3D11Texture3D *newTexture = NULL; - D3D11_TEXTURE3D_DESC desc; - desc.Width = width; - desc.Height = height; - desc.Depth = mDepth; - desc.MipLevels = lodOffset + 1; - desc.Format = dxgiFormat; - desc.Usage = D3D11_USAGE_STAGING; - desc.BindFlags = 0; + desc.Width = width; + desc.Height = height; + desc.Depth = mDepth; + desc.MipLevels = lodOffset + 1; + desc.Format = dxgiFormat; + desc.Usage = D3D11_USAGE_STAGING; + desc.BindFlags = 0; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; - desc.MiscFlags = 0; + desc.MiscFlags = 0; - if (d3d11::GetTextureFormatInfo(mInternalFormat, mRenderer->getRenderer11DeviceCaps()).dataInitializerFunction != NULL) + if (formatInfo.dataInitializerFunction != nullptr) { std::vector initialData; std::vector> textureData; - d3d11::GenerateInitialTextureData(mInternalFormat, mRenderer->getRenderer11DeviceCaps(), width, height, mDepth, - lodOffset + 1, &initialData, &textureData); + d3d11::GenerateInitialTextureData(mInternalFormat, mRenderer->getRenderer11DeviceCaps(), + width, height, mDepth, lodOffset + 1, &initialData, + &textureData); - result = device->CreateTexture3D(&desc, initialData.data(), &newTexture); + ANGLE_TRY( + mRenderer->allocateTexture(desc, formatInfo, initialData.data(), &mStagingTexture)); } else { - result = device->CreateTexture3D(&desc, NULL, &newTexture); + ANGLE_TRY(mRenderer->allocateTexture(desc, formatInfo, &mStagingTexture)); } - if (FAILED(result)) - { - ASSERT(result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create staging texture, result: 0x%X.", result); - } - - mStagingTexture = newTexture; + mStagingTexture.setDebugName("Image11::StagingTexture3D"); mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1); } - else if (mTarget == GL_TEXTURE_2D || mTarget == GL_TEXTURE_2D_ARRAY || mTarget == GL_TEXTURE_CUBE_MAP) + else if (mTarget == GL_TEXTURE_2D || mTarget == GL_TEXTURE_2D_ARRAY || + mTarget == GL_TEXTURE_CUBE_MAP) { - ID3D11Texture2D *newTexture = NULL; - D3D11_TEXTURE2D_DESC desc; - desc.Width = width; - desc.Height = height; - desc.MipLevels = lodOffset + 1; - desc.ArraySize = 1; - desc.Format = dxgiFormat; - desc.SampleDesc.Count = 1; + desc.Width = width; + desc.Height = height; + desc.MipLevels = lodOffset + 1; + desc.ArraySize = 1; + desc.Format = dxgiFormat; + desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_STAGING; - desc.BindFlags = 0; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; - desc.MiscFlags = 0; + desc.Usage = D3D11_USAGE_STAGING; + desc.BindFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + desc.MiscFlags = 0; - if (d3d11::GetTextureFormatInfo(mInternalFormat, mRenderer->getRenderer11DeviceCaps()).dataInitializerFunction != NULL) + if (formatInfo.dataInitializerFunction != nullptr) { std::vector initialData; std::vector> textureData; - d3d11::GenerateInitialTextureData(mInternalFormat, mRenderer->getRenderer11DeviceCaps(), width, height, 1, - lodOffset + 1, &initialData, &textureData); + d3d11::GenerateInitialTextureData(mInternalFormat, mRenderer->getRenderer11DeviceCaps(), + width, height, 1, lodOffset + 1, &initialData, + &textureData); - result = device->CreateTexture2D(&desc, initialData.data(), &newTexture); + ANGLE_TRY( + mRenderer->allocateTexture(desc, formatInfo, initialData.data(), &mStagingTexture)); } else { - result = device->CreateTexture2D(&desc, NULL, &newTexture); + ANGLE_TRY(mRenderer->allocateTexture(desc, formatInfo, &mStagingTexture)); } - if (FAILED(result)) - { - ASSERT(result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create staging texture, result: 0x%X.", result); - } - - mStagingTexture = newTexture; + mStagingTexture.setDebugName("Image11::StagingTexture2D"); mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1); } else @@ -592,30 +613,22 @@ gl::Error Image11::createStagingTexture() } mDirty = false; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Image11::map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map) +gl::Error Image11::map(const gl::Context *context, D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map) { // We must recover from the TextureStorage if necessary, even for D3D11_MAP_WRITE. - gl::Error error = recoverFromAssociatedStorage(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(recoverFromAssociatedStorage(context)); - ID3D11Resource *stagingTexture = NULL; - unsigned int subresourceIndex = 0; - error = getStagingTexture(&stagingTexture, &subresourceIndex); - if (error.isError()) - { - return error; - } + const TextureHelper11 *stagingTexture = nullptr; + unsigned int subresourceIndex = 0; + ANGLE_TRY(getStagingTexture(&stagingTexture, &subresourceIndex)); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); - ASSERT(mStagingTexture); - HRESULT result = deviceContext->Map(stagingTexture, subresourceIndex, mapType, 0, map); + ASSERT(stagingTexture && stagingTexture->valid()); + HRESULT result = deviceContext->Map(stagingTexture->get(), subresourceIndex, mapType, 0, map); if (FAILED(result)) { @@ -624,20 +637,20 @@ gl::Error Image11::map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map) { mRenderer->notifyDeviceLost(); } - return gl::Error(GL_OUT_OF_MEMORY, "Failed to map staging texture, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to map staging texture, " << gl::FmtHR(result); } mDirty = true; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } void Image11::unmap() { - if (mStagingTexture) + if (mStagingTexture.valid()) { ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); - deviceContext->Unmap(mStagingTexture, mStagingSubresource); + deviceContext->Unmap(mStagingTexture.get(), mStagingSubresource); } } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Image11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Image11.h index a5fcec84f8..584d231b37 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Image11.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Image11.h @@ -10,10 +10,10 @@ #ifndef LIBANGLE_RENDERER_D3D_D3D11_IMAGE11_H_ #define LIBANGLE_RENDERER_D3D_D3D11_IMAGE11_H_ -#include "libANGLE/renderer/d3d/ImageD3D.h" -#include "libANGLE/ImageIndex.h" - #include "common/debug.h" +#include "libANGLE/ImageIndex.h" +#include "libANGLE/renderer/d3d/ImageD3D.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" namespace gl { @@ -25,37 +25,63 @@ namespace rx class Renderer11; class TextureHelper11; class TextureStorage11; +struct Renderer11DeviceCaps; class Image11 : public ImageD3D { public: Image11(Renderer11 *renderer); - virtual ~Image11(); + ~Image11() override; - static gl::Error generateMipmap(Image11 *dest, Image11 *src); + static gl::Error GenerateMipmap(const gl::Context *context, + Image11 *dest, + Image11 *src, + const Renderer11DeviceCaps &rendererCaps); + static gl::Error CopyImage(const gl::Context *context, + Image11 *dest, + Image11 *source, + const gl::Rectangle &sourceRect, + const gl::Offset &destOffset, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha, + const Renderer11DeviceCaps &rendererCaps); - virtual bool isDirty() const; + bool isDirty() const override; - virtual gl::Error copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box ®ion); + gl::Error copyToStorage(const gl::Context *context, + TextureStorage *storage, + const gl::ImageIndex &index, + const gl::Box ®ion) override; bool redefine(GLenum target, GLenum internalformat, const gl::Extents &size, bool forceRelease) override; DXGI_FORMAT getDXGIFormat() const; - virtual gl::Error loadData(const gl::Box &area, const gl::PixelUnpackState &unpack, GLenum type, const void *input); - virtual gl::Error loadCompressedData(const gl::Box &area, const void *input); + gl::Error loadData(const gl::Context *context, + const gl::Box &area, + const gl::PixelUnpackState &unpack, + GLenum type, + const void *input, + bool applySkipImages) override; + gl::Error loadCompressedData(const gl::Context *context, + const gl::Box &area, + const void *input) override; - gl::Error copyFromTexStorage(const gl::ImageIndex &imageIndex, TextureStorage *source) override; - gl::Error copyFromFramebuffer(const gl::Offset &destOffset, + gl::Error copyFromTexStorage(const gl::Context *context, + const gl::ImageIndex &imageIndex, + TextureStorage *source) override; + gl::Error copyFromFramebuffer(const gl::Context *context, + const gl::Offset &destOffset, const gl::Rectangle &sourceArea, const gl::Framebuffer *source) override; - gl::Error recoverFromAssociatedStorage(); - bool isAssociatedStorageValid(TextureStorage11* textureStorage) const; + gl::Error recoverFromAssociatedStorage(const gl::Context *context); + void verifyAssociatedStorageValid(TextureStorage11 *textureStorage) const; void disassociateStorage(); protected: - gl::Error map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map); + gl::Error map(const gl::Context *context, D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map); void unmap(); private: @@ -64,14 +90,15 @@ class Image11 : public ImageD3D const TextureHelper11 &textureHelper, UINT sourceSubResource); - gl::Error getStagingTexture(ID3D11Resource **outStagingTexture, unsigned int *outSubresourceIndex); + gl::Error getStagingTexture(const TextureHelper11 **outStagingTexture, + unsigned int *outSubresourceIndex); gl::Error createStagingTexture(); void releaseStagingTexture(); Renderer11 *mRenderer; DXGI_FORMAT mDXGIFormat; - ID3D11Resource *mStagingTexture; + TextureHelper11 mStagingTexture; unsigned int mStagingSubresource; bool mRecoverFromStorage; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.cpp index a5e78a245d..a79fb71f71 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.cpp @@ -14,28 +14,23 @@ namespace rx { -IndexBuffer11::IndexBuffer11(Renderer11 *const renderer) : mRenderer(renderer) +IndexBuffer11::IndexBuffer11(Renderer11 *const renderer) + : mRenderer(renderer), mBuffer(), mBufferSize(0), mIndexType(GL_NONE), mDynamicUsage(false) { - mBuffer = NULL; - mBufferSize = 0; - mDynamicUsage = false; } IndexBuffer11::~IndexBuffer11() { - SafeRelease(mBuffer); } gl::Error IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic) { - SafeRelease(mBuffer); + mBuffer.reset(); updateSerial(); if (bufferSize > 0) { - ID3D11Device* dxDevice = mRenderer->getDevice(); - D3D11_BUFFER_DESC bufferDesc; bufferDesc.ByteWidth = bufferSize; bufferDesc.Usage = D3D11_USAGE_DYNAMIC; @@ -44,19 +39,15 @@ gl::Error IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, b bufferDesc.MiscFlags = 0; bufferDesc.StructureByteStride = 0; - HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal index buffer of size, %lu.", bufferSize); - } + ANGLE_TRY(mRenderer->allocateResource(bufferDesc, &mBuffer)); if (dynamic) { - d3d11::SetDebugName(mBuffer, "IndexBuffer11 (dynamic)"); + mBuffer.setDebugName("IndexBuffer11 (dynamic)"); } else { - d3d11::SetDebugName(mBuffer, "IndexBuffer11 (static)"); + mBuffer.setDebugName("IndexBuffer11 (static)"); } } @@ -64,45 +55,46 @@ gl::Error IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, b mIndexType = indexType; mDynamicUsage = dynamic; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error IndexBuffer11::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory) { - if (!mBuffer) + if (!mBuffer.valid()) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized."); + return gl::OutOfMemory() << "Internal index buffer is not initialized."; } // Check for integer overflows and out-out-bounds map requests if (offset + size < offset || offset + size > mBufferSize) { - return gl::Error(GL_OUT_OF_MEMORY, "Index buffer map range is not inside the buffer."); + return gl::OutOfMemory() << "Index buffer map range is not inside the buffer."; } ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); + HRESULT result = + dxContext->Map(mBuffer.get(), 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal index buffer, HRESULT: 0x%08x.", result); + return gl::OutOfMemory() << "Failed to map internal index buffer, " << gl::FmtHR(result); } *outMappedMemory = reinterpret_cast(mappedResource.pData) + offset; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error IndexBuffer11::unmapBuffer() { - if (!mBuffer) + if (!mBuffer.valid()) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized."); + return gl::OutOfMemory() << "Internal index buffer is not initialized."; } ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); - dxContext->Unmap(mBuffer, 0); - return gl::Error(GL_NO_ERROR); + dxContext->Unmap(mBuffer.get(), 0); + return gl::NoError(); } GLenum IndexBuffer11::getIndexType() const @@ -123,29 +115,29 @@ gl::Error IndexBuffer11::setSize(unsigned int bufferSize, GLenum indexType) } else { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } } gl::Error IndexBuffer11::discard() { - if (!mBuffer) + if (!mBuffer.valid()) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized."); + return gl::OutOfMemory() << "Internal index buffer is not initialized."; } ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + HRESULT result = dxContext->Map(mBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal index buffer, HRESULT: 0x%08x.", result); + return gl::OutOfMemory() << "Failed to map internal index buffer, " << gl::FmtHR(result); } - dxContext->Unmap(mBuffer, 0); + dxContext->Unmap(mBuffer.get(), 0); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } DXGI_FORMAT IndexBuffer11::getIndexFormat() const @@ -159,9 +151,9 @@ DXGI_FORMAT IndexBuffer11::getIndexFormat() const } } -ID3D11Buffer *IndexBuffer11::getBuffer() const +const d3d11::Buffer &IndexBuffer11::getBuffer() const { return mBuffer; } -} +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.h index e730377e00..7b5d744c02 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.h @@ -10,6 +10,7 @@ #define LIBANGLE_RENDERER_D3D_D3D11_INDEXBUFFER11_H_ #include "libANGLE/renderer/d3d/IndexBuffer.h" +#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h" namespace rx { @@ -19,31 +20,31 @@ class IndexBuffer11 : public IndexBuffer { public: explicit IndexBuffer11(Renderer11 *const renderer); - virtual ~IndexBuffer11(); + ~IndexBuffer11() override; - virtual gl::Error initialize(unsigned int bufferSize, GLenum indexType, bool dynamic); + gl::Error initialize(unsigned int bufferSize, GLenum indexType, bool dynamic) override; - virtual gl::Error mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory); - virtual gl::Error unmapBuffer(); + gl::Error mapBuffer(unsigned int offset, unsigned int size, void **outMappedMemory) override; + gl::Error unmapBuffer() override; - virtual GLenum getIndexType() const; - virtual unsigned int getBufferSize() const; - virtual gl::Error setSize(unsigned int bufferSize, GLenum indexType); + GLenum getIndexType() const override; + unsigned int getBufferSize() const override; + gl::Error setSize(unsigned int bufferSize, GLenum indexType) override; - virtual gl::Error discard(); + gl::Error discard() override; DXGI_FORMAT getIndexFormat() const; - ID3D11Buffer *getBuffer() const; + const d3d11::Buffer &getBuffer() const; private: Renderer11 *const mRenderer; - ID3D11Buffer *mBuffer; + d3d11::Buffer mBuffer; unsigned int mBufferSize; GLenum mIndexType; bool mDynamicUsage; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_D3D11_INDEXBUFFER11_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp index 3a6d797ea6..a238f97b08 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp @@ -9,17 +9,22 @@ #include "libANGLE/renderer/d3d/d3d11/InputLayoutCache.h" +#include "common/bitset_utils.h" #include "common/utilities.h" +#include "libANGLE/Context.h" #include "libANGLE/Program.h" +#include "libANGLE/VertexArray.h" #include "libANGLE/VertexAttribute.h" #include "libANGLE/renderer/d3d/IndexDataManager.h" #include "libANGLE/renderer/d3d/ProgramD3D.h" #include "libANGLE/renderer/d3d/VertexDataManager.h" #include "libANGLE/renderer/d3d/d3d11/Buffer11.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" #include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h" +#include "libANGLE/renderer/d3d/d3d11/VertexArray11.h" #include "libANGLE/renderer/d3d/d3d11/VertexBuffer11.h" #include "libANGLE/renderer/d3d/d3d11/formatutils11.h" -#include "third_party/murmurhash/MurmurHash3.h" namespace rx { @@ -32,24 +37,7 @@ size_t GetReservedBufferCount(bool usesPointSpriteEmulation) return usesPointSpriteEmulation ? 1 : 0; } -gl::InputLayout GetInputLayout(const SortedAttribArray &translatedAttributes, size_t attributeCount) -{ - gl::InputLayout inputLayout(attributeCount, gl::VERTEX_FORMAT_INVALID); - - for (size_t attributeIndex = 0; attributeIndex < attributeCount; ++attributeIndex) - { - const TranslatedAttribute *translatedAttribute = translatedAttributes[attributeIndex]; - - if (translatedAttribute->active) - { - inputLayout[attributeIndex] = gl::GetVertexFormatType( - *translatedAttribute->attribute, translatedAttribute->currentValueType); - } - } - return inputLayout; -} - -GLenum GetGLSLAttributeType(const std::vector &shaderAttributes, int index) +GLenum GetGLSLAttributeType(const std::vector &shaderAttributes, size_t index) { // Count matrices differently for (const sh::Attribute &attrib : shaderAttributes) @@ -61,8 +49,9 @@ GLenum GetGLSLAttributeType(const std::vector &shaderAttributes, GLenum transposedType = gl::TransposeMatrixType(attrib.type); int rows = gl::VariableRowCount(transposedType); + int intIndex = static_cast(index); - if (index >= attrib.location && index < attrib.location + rows) + if (intIndex >= attrib.location && intIndex < attrib.location + rows) { return transposedType; } @@ -72,8 +61,6 @@ GLenum GetGLSLAttributeType(const std::vector &shaderAttributes, return GL_NONE; } -const unsigned int kDefaultCacheSize = 1024; - struct PackedAttribute { uint8_t attribType; @@ -82,26 +69,18 @@ struct PackedAttribute uint8_t divisor; }; -Optional FindFirstNonInstanced(const SortedAttribArray &sortedAttributes, size_t maxIndex) -{ - for (size_t index = 0; index < maxIndex; ++index) - { - if (sortedAttributes[index]->divisor == 0) - { - return Optional(index); - } - } - - return Optional::Invalid(); -} - } // anonymous namespace -void InputLayoutCache::PackedAttributeLayout::addAttributeData( - GLenum glType, - UINT semanticIndex, - gl::VertexFormatType vertexFormatType, - unsigned int divisor) +PackedAttributeLayout::PackedAttributeLayout() : numAttributes(0), flags(0), attributeData({}) +{ +} + +PackedAttributeLayout::PackedAttributeLayout(const PackedAttributeLayout &other) = default; + +void PackedAttributeLayout::addAttributeData(GLenum glType, + UINT semanticIndex, + gl::VertexFormatType vertexFormatType, + unsigned int divisor) { gl::AttributeType attribType = gl::GetAttributeType(glType); @@ -121,139 +100,58 @@ void InputLayoutCache::PackedAttributeLayout::addAttributeData( attributeData[numAttributes++] = gl::bitCast(packedAttrib); } -bool InputLayoutCache::PackedAttributeLayout::operator<(const PackedAttributeLayout &other) const +bool PackedAttributeLayout::operator==(const PackedAttributeLayout &other) const { - if (numAttributes != other.numAttributes) - { - return numAttributes < other.numAttributes; - } - - if (flags != other.flags) - { - return flags < other.flags; - } - - return memcmp(attributeData, other.attributeData, sizeof(uint32_t) * numAttributes) < 0; + return (numAttributes == other.numAttributes) && (flags == other.flags) && + (attributeData == other.attributeData); } -InputLayoutCache::InputLayoutCache() : mUnsortedAttributesCount(0), mCacheSize(kDefaultCacheSize) +InputLayoutCache::InputLayoutCache() + : mLayoutCache(kDefaultCacheSize * 2), mPointSpriteVertexBuffer(), mPointSpriteIndexBuffer() { - mCounter = 0; - mDevice = NULL; - mDeviceContext = NULL; - mCurrentIL = NULL; - - for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) - { - mCurrentBuffers[i] = NULL; - mCurrentVertexStrides[i] = static_cast(-1); - mCurrentVertexOffsets[i] = static_cast(-1); - } - mPointSpriteVertexBuffer = NULL; - mPointSpriteIndexBuffer = NULL; } InputLayoutCache::~InputLayoutCache() { - clear(); -} - -void InputLayoutCache::initialize(ID3D11Device *device, ID3D11DeviceContext *context) -{ - clear(); - mDevice = device; - mDeviceContext = context; - mFeatureLevel = device->GetFeatureLevel(); } void InputLayoutCache::clear() { - for (auto &layout : mLayoutMap) - { - SafeRelease(layout.second); - } - mLayoutMap.clear(); - SafeRelease(mPointSpriteVertexBuffer); - SafeRelease(mPointSpriteIndexBuffer); - markDirty(); -} - -void InputLayoutCache::markDirty() -{ - mCurrentIL = NULL; - for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) - { - mCurrentBuffers[i] = NULL; - mCurrentVertexStrides[i] = static_cast(-1); - mCurrentVertexOffsets[i] = static_cast(-1); - } - mUnsortedAttributesCount = 0; + mLayoutCache.Clear(); + mPointSpriteVertexBuffer.reset(); + mPointSpriteIndexBuffer.reset(); } gl::Error InputLayoutCache::applyVertexBuffers( - const std::vector &unsortedAttributes, + const gl::Context *context, + const std::vector ¤tAttributes, GLenum mode, - gl::Program *program, - TranslatedIndexData *indexInfo, - GLsizei numIndicesPerInstance) + GLint start, + bool isIndexedRendering) { - ASSERT(mDevice && mDeviceContext); - + Renderer11 *renderer = GetImplAs(context)->getRenderer(); + const gl::State &state = context->getGLState(); + auto *stateManager = renderer->getStateManager(); + gl::Program *program = state.getProgram(); ProgramD3D *programD3D = GetImplAs(program); bool programUsesInstancedPointSprites = programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation(); bool instancedPointSpritesActive = programUsesInstancedPointSprites && (mode == GL_POINTS); - SortedIndexArray sortedSemanticIndices; - mSortedAttributes.fill(nullptr); - mUnsortedAttributesCount = unsortedAttributes.size(); - - programD3D->sortAttributesByLayout(unsortedAttributes, sortedSemanticIndices.data(), - mSortedAttributes.data()); - - // If we are using FL 9_3, make sure the first attribute is not instanced - if (mFeatureLevel <= D3D_FEATURE_LEVEL_9_3 && !unsortedAttributes.empty()) - { - if (mSortedAttributes[0]->divisor > 0) - { - Optional firstNonInstancedIndex = - FindFirstNonInstanced(mSortedAttributes, unsortedAttributes.size()); - if (firstNonInstancedIndex.valid()) - { - size_t index = firstNonInstancedIndex.value(); - std::swap(mSortedAttributes[0], mSortedAttributes[index]); - std::swap(sortedSemanticIndices[0], sortedSemanticIndices[index]); - } - } - } - - gl::Error error = updateInputLayout(program, mode, mSortedAttributes, sortedSemanticIndices, - unsortedAttributes.size(), numIndicesPerInstance); - if (error.isError()) - { - return error; - } - - bool dirtyBuffers = false; - size_t minDiff = gl::MAX_VERTEX_ATTRIBS; - size_t maxDiff = 0; - // Note that if we use instance emulation, we reserve the first buffer slot. size_t reservedBuffers = GetReservedBufferCount(programUsesInstancedPointSprites); for (size_t attribIndex = 0; attribIndex < (gl::MAX_VERTEX_ATTRIBS - reservedBuffers); ++attribIndex) { - ID3D11Buffer *buffer = NULL; - UINT vertexStride = 0; - UINT vertexOffset = 0; + ID3D11Buffer *buffer = nullptr; + UINT vertexStride = 0; + UINT vertexOffset = 0; - const auto &attrib = *mSortedAttributes[attribIndex]; - - if (attribIndex < unsortedAttributes.size() && attrib.active) + if (attribIndex < currentAttributes.size()) { - VertexBuffer11 *vertexBuffer = GetAs(attrib.vertexBuffer); - Buffer11 *bufferStorage = attrib.storage ? GetAs(attrib.storage) : nullptr; + const auto &attrib = *currentAttributes[attribIndex]; + Buffer11 *bufferStorage = attrib.storage ? GetAs(attrib.storage) : nullptr; // If indexed pointsprite emulation is active, then we need to take a less efficent code path. // Emulated indexed pointsprite rendering requires that the vertex buffers match exactly to @@ -261,18 +159,18 @@ gl::Error InputLayoutCache::applyVertexBuffers( // on the number of points indicated by the index list or how many duplicates are found on the index list. if (bufferStorage == nullptr) { - buffer = vertexBuffer->getBuffer(); + ASSERT(attrib.vertexBuffer.get()); + buffer = GetAs(attrib.vertexBuffer.get())->getBuffer().get(); } - else if (instancedPointSpritesActive && (indexInfo != nullptr)) + else if (instancedPointSpritesActive && isIndexedRendering) { + VertexArray11 *vao11 = GetImplAs(state.getVertexArray()); + ASSERT(vao11->isCachedIndexInfoValid()); + TranslatedIndexData *indexInfo = vao11->getCachedIndexInfo(); if (indexInfo->srcIndexData.srcBuffer != nullptr) { const uint8_t *bufferData = nullptr; - error = indexInfo->srcIndexData.srcBuffer->getData(&bufferData); - if (error.isError()) - { - return error; - } + ANGLE_TRY(indexInfo->srcIndexData.srcBuffer->getData(context, &bufferData)); ASSERT(bufferData != nullptr); ptrdiff_t offset = @@ -281,31 +179,24 @@ gl::Error InputLayoutCache::applyVertexBuffers( indexInfo->srcIndexData.srcIndices = bufferData + offset; } - buffer = bufferStorage->getEmulatedIndexedBuffer(&indexInfo->srcIndexData, &attrib); + ANGLE_TRY_RESULT(bufferStorage->getEmulatedIndexedBuffer( + context, &indexInfo->srcIndexData, attrib, start), + buffer); } else { - buffer = bufferStorage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); + ANGLE_TRY_RESULT( + bufferStorage->getBuffer(context, BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK), + buffer); } vertexStride = attrib.stride; - vertexOffset = attrib.offset; + ANGLE_TRY_RESULT(attrib.computeOffset(start), vertexOffset); } size_t bufferIndex = reservedBuffers + attribIndex; - if (buffer != mCurrentBuffers[bufferIndex] || - vertexStride != mCurrentVertexStrides[bufferIndex] || - vertexOffset != mCurrentVertexOffsets[bufferIndex]) - { - dirtyBuffers = true; - minDiff = std::min(minDiff, bufferIndex); - maxDiff = std::max(maxDiff, bufferIndex); - - mCurrentBuffers[bufferIndex] = buffer; - mCurrentVertexStrides[bufferIndex] = vertexStride; - mCurrentVertexOffsets[bufferIndex] = vertexOffset; - } + stateManager->queueVertexBufferChange(bufferIndex, buffer, vertexStride, vertexOffset); } // Instanced PointSprite emulation requires two additional ID3D11Buffers. A vertex buffer needs @@ -317,10 +208,9 @@ gl::Error InputLayoutCache::applyVertexBuffers( // handle missing vertex data and will TDR the system. if (programUsesInstancedPointSprites) { - HRESULT result = S_OK; const UINT pointSpriteVertexStride = sizeof(float) * 5; - if (!mPointSpriteVertexBuffer) + if (!mPointSpriteVertexBuffer.valid()) { static const float pointSpriteVertices[] = { @@ -342,25 +232,16 @@ gl::Error InputLayoutCache::applyVertexBuffers( vertexBufferDesc.MiscFlags = 0; vertexBufferDesc.StructureByteStride = 0; - result = mDevice->CreateBuffer(&vertexBufferDesc, &vertexBufferData, &mPointSpriteVertexBuffer); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create instanced pointsprite emulation vertex buffer, HRESULT: 0x%08x", result); - } + ANGLE_TRY(renderer->allocateResource(vertexBufferDesc, &vertexBufferData, + &mPointSpriteVertexBuffer)); } - mCurrentBuffers[0] = mPointSpriteVertexBuffer; // Set the stride to 0 if GL_POINTS mode is not being used to instruct the driver to avoid // indexing into the vertex buffer. - mCurrentVertexStrides[0] = instancedPointSpritesActive ? pointSpriteVertexStride : 0; - mCurrentVertexOffsets[0] = 0; + UINT stride = instancedPointSpritesActive ? pointSpriteVertexStride : 0; + stateManager->queueVertexBufferChange(0, mPointSpriteVertexBuffer.get(), stride, 0); - // Update maxDiff to include the additional point sprite vertex buffer - // to ensure that IASetVertexBuffers uses the correct buffer count. - minDiff = 0; - maxDiff = std::max(maxDiff, static_cast(0)); - - if (!mPointSpriteIndexBuffer) + if (!mPointSpriteIndexBuffer.valid()) { // Create an index buffer and set it for pointsprite rendering static const unsigned short pointSpriteIndices[] = @@ -377,12 +258,8 @@ gl::Error InputLayoutCache::applyVertexBuffers( indexBufferDesc.MiscFlags = 0; indexBufferDesc.StructureByteStride = 0; - result = mDevice->CreateBuffer(&indexBufferDesc, &indexBufferData, &mPointSpriteIndexBuffer); - if (FAILED(result)) - { - SafeRelease(mPointSpriteVertexBuffer); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create instanced pointsprite emulation index buffer, HRESULT: 0x%08x", result); - } + ANGLE_TRY(renderer->allocateResource(indexBufferDesc, &indexBufferData, + &mPointSpriteIndexBuffer)); } if (instancedPointSpritesActive) @@ -391,51 +268,51 @@ gl::Error InputLayoutCache::applyVertexBuffers( // non-indexed rendering path in ANGLE (DrawArrays). This means that applyIndexBuffer() // on the renderer will not be called and setting this buffer here ensures that the // rendering path will contain the correct index buffers. - mDeviceContext->IASetIndexBuffer(mPointSpriteIndexBuffer, DXGI_FORMAT_R16_UINT, 0); + stateManager->setIndexBuffer(mPointSpriteIndexBuffer.get(), DXGI_FORMAT_R16_UINT, 0); } } - if (dirtyBuffers) - { - ASSERT(minDiff <= maxDiff && maxDiff < gl::MAX_VERTEX_ATTRIBS); - mDeviceContext->IASetVertexBuffers( - static_cast(minDiff), static_cast(maxDiff - minDiff + 1), - mCurrentBuffers + minDiff, mCurrentVertexStrides + minDiff, - mCurrentVertexOffsets + minDiff); - } - - return gl::Error(GL_NO_ERROR); + stateManager->applyVertexBufferChanges(); + return gl::NoError(); } -gl::Error InputLayoutCache::updateVertexOffsetsForPointSpritesEmulation(GLsizei emulatedInstanceId) +gl::Error InputLayoutCache::updateVertexOffsetsForPointSpritesEmulation( + Renderer11 *renderer, + const std::vector ¤tAttributes, + GLint startVertex, + GLsizei emulatedInstanceId) { + auto *stateManager = renderer->getStateManager(); + size_t reservedBuffers = GetReservedBufferCount(true); - for (size_t attribIndex = 0; attribIndex < mUnsortedAttributesCount; ++attribIndex) + for (size_t attribIndex = 0; attribIndex < currentAttributes.size(); ++attribIndex) { - const auto &attrib = *mSortedAttributes[attribIndex]; + const auto &attrib = *currentAttributes[attribIndex]; size_t bufferIndex = reservedBuffers + attribIndex; - if (attrib.active && attrib.divisor > 0) + if (attrib.divisor > 0) { - mCurrentVertexOffsets[bufferIndex] = - attrib.offset + (attrib.stride * (emulatedInstanceId / attrib.divisor)); + unsigned int offset = 0; + ANGLE_TRY_RESULT(attrib.computeOffset(startVertex), offset); + offset += (attrib.stride * (emulatedInstanceId / attrib.divisor)); + stateManager->queueVertexOffsetChange(bufferIndex, offset); } } - mDeviceContext->IASetVertexBuffers(0, gl::MAX_VERTEX_ATTRIBS, mCurrentBuffers, - mCurrentVertexStrides, mCurrentVertexOffsets); - - return gl::Error(GL_NO_ERROR); + stateManager->applyVertexBufferChanges(); + return gl::NoError(); } -gl::Error InputLayoutCache::updateInputLayout(gl::Program *program, - GLenum mode, - const SortedAttribArray &sortedAttributes, - const SortedIndexArray &sortedSemanticIndices, - size_t attribCount, - GLsizei numIndicesPerInstance) +gl::Error InputLayoutCache::updateInputLayout( + Renderer11 *renderer, + const gl::State &state, + const std::vector ¤tAttributes, + GLenum mode, + const AttribIndexArray &sortedSemanticIndices, + const DrawCallVertexParams &vertexParams) { - const std::vector &shaderAttributes = program->getAttributes(); + gl::Program *program = state.getProgram(); + const auto &shaderAttributes = program->getAttributes(); PackedAttributeLayout layout; ProgramD3D *programD3D = GetImplAs(program); @@ -453,90 +330,70 @@ gl::Error InputLayoutCache::updateInputLayout(gl::Program *program, layout.flags |= PackedAttributeLayout::FLAG_INSTANCED_SPRITES_ACTIVE; } - if (numIndicesPerInstance > 0) + if (vertexParams.instances() > 0) { layout.flags |= PackedAttributeLayout::FLAG_INSTANCED_RENDERING_ACTIVE; } - const auto &semanticToLocation = programD3D->getAttributesByLayout(); + const auto &attribs = state.getVertexArray()->getVertexAttributes(); + const auto &bindings = state.getVertexArray()->getVertexBindings(); + const auto &locationToSemantic = programD3D->getAttribLocationToD3DSemantics(); + int divisorMultiplier = program->usesMultiview() ? program->getNumViews() : 1; - for (size_t attribIndex = 0; attribIndex < attribCount; ++attribIndex) + for (size_t attribIndex : program->getActiveAttribLocationsMask()) { - const auto &attrib = *sortedAttributes[attribIndex]; - int sortedIndex = sortedSemanticIndices[attribIndex]; - - if (!attrib.active) - continue; - - gl::VertexFormatType vertexFormatType = - gl::GetVertexFormatType(*attrib.attribute, attrib.currentValueType); - // Record the type of the associated vertex shader vector in our key // This will prevent mismatched vertex shaders from using the same input layout - GLenum glslElementType = - GetGLSLAttributeType(shaderAttributes, semanticToLocation[sortedIndex]); + GLenum glslElementType = GetGLSLAttributeType(shaderAttributes, attribIndex); - layout.addAttributeData(glslElementType, sortedIndex, vertexFormatType, attrib.divisor); + const auto &attrib = attribs[attribIndex]; + const auto &binding = bindings[attrib.bindingIndex]; + int d3dSemantic = locationToSemantic[attribIndex]; + + const auto ¤tValue = + state.getVertexAttribCurrentValue(static_cast(attribIndex)); + gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib, currentValue.Type); + + layout.addAttributeData(glslElementType, d3dSemantic, vertexFormatType, + binding.getDivisor() * divisorMultiplier); } - ID3D11InputLayout *inputLayout = nullptr; + const d3d11::InputLayout *inputLayout = nullptr; if (layout.numAttributes > 0 || layout.flags != 0) { - auto layoutMapIt = mLayoutMap.find(layout); - if (layoutMapIt != mLayoutMap.end()) + auto it = mLayoutCache.Get(layout); + if (it != mLayoutCache.end()) { - inputLayout = layoutMapIt->second; + inputLayout = &it->second; } else { - gl::Error error = - createInputLayout(sortedAttributes, sortedSemanticIndices, attribCount, mode, - program, numIndicesPerInstance, &inputLayout); - if (error.isError()) - { - return error; - } - if (mLayoutMap.size() >= mCacheSize) - { - TRACE("Overflowed the limit of %u input layouts, purging half the cache.", - mCacheSize); + angle::TrimCache(mLayoutCache.max_size() / 2, kGCLimit, "input layout", &mLayoutCache); - // Randomly release every second element - auto it = mLayoutMap.begin(); - while (it != mLayoutMap.end()) - { - it++; - if (it != mLayoutMap.end()) - { - // c++11 erase allows us to easily delete the current iterator. - SafeRelease(it->second); - it = mLayoutMap.erase(it); - } - } - } + d3d11::InputLayout newInputLayout; + ANGLE_TRY(createInputLayout(renderer, sortedSemanticIndices, currentAttributes, mode, + program, vertexParams, &newInputLayout)); - mLayoutMap[layout] = inputLayout; + auto insertIt = mLayoutCache.Put(layout, std::move(newInputLayout)); + inputLayout = &insertIt->second; } } - if (inputLayout != mCurrentIL) - { - mDeviceContext->IASetInputLayout(inputLayout); - mCurrentIL = inputLayout; - } - - return gl::Error(GL_NO_ERROR); + renderer->getStateManager()->setInputLayout(inputLayout); + return gl::NoError(); } -gl::Error InputLayoutCache::createInputLayout(const SortedAttribArray &sortedAttributes, - const SortedIndexArray &sortedSemanticIndices, - size_t attribCount, - GLenum mode, - gl::Program *program, - GLsizei numIndicesPerInstance, - ID3D11InputLayout **inputLayoutOut) +gl::Error InputLayoutCache::createInputLayout( + Renderer11 *renderer, + const AttribIndexArray &sortedSemanticIndices, + const std::vector ¤tAttributes, + GLenum mode, + gl::Program *program, + const DrawCallVertexParams &vertexParams, + d3d11::InputLayout *inputLayoutOut) { ProgramD3D *programD3D = GetImplAs(program); + auto featureLevel = renderer->getRenderer11DeviceCaps().featureLevel; bool programUsesInstancedPointSprites = programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation(); @@ -544,20 +401,17 @@ gl::Error InputLayoutCache::createInputLayout(const SortedAttribArray &sortedAtt unsigned int inputElementCount = 0; std::array inputElements; - for (size_t attribIndex = 0; attribIndex < attribCount; ++attribIndex) + for (size_t attribIndex = 0; attribIndex < currentAttributes.size(); ++attribIndex) { - const auto &attrib = *sortedAttributes[attribIndex]; + const auto &attrib = *currentAttributes[attribIndex]; const int sortedIndex = sortedSemanticIndices[attribIndex]; - if (!attrib.active) - continue; - D3D11_INPUT_CLASSIFICATION inputClass = attrib.divisor > 0 ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA; const auto &vertexFormatType = gl::GetVertexFormatType(*attrib.attribute, attrib.currentValueType); - const auto &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormatType, mFeatureLevel); + const auto &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormatType, featureLevel); auto *inputElement = &inputElements[inputElementCount]; @@ -584,23 +438,28 @@ gl::Error InputLayoutCache::createInputLayout(const SortedAttribArray &sortedAtt // doesn't support OpenGL ES 3.0. // As per the spec for ANGLE_instanced_arrays, not all attributes can be instanced // simultaneously, so a non-instanced element must exist. + + GLsizei numIndicesPerInstance = 0; + if (vertexParams.instances() > 0) + { + // This may trigger an evaluation of the index range. + numIndicesPerInstance = vertexParams.vertexCount(); + } + for (size_t elementIndex = 0; elementIndex < inputElementCount; ++elementIndex) { - if (sortedAttributes[elementIndex]->active) + // If rendering points and instanced pointsprite emulation is being used, the + // inputClass is required to be configured as per instance data + if (mode == GL_POINTS) { - // If rendering points and instanced pointsprite emulation is being used, the - // inputClass is required to be configured as per instance data - if (mode == GL_POINTS) + inputElements[elementIndex].InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA; + inputElements[elementIndex].InstanceDataStepRate = 1; + if (numIndicesPerInstance > 0 && currentAttributes[elementIndex]->divisor > 0) { - inputElements[elementIndex].InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA; - inputElements[elementIndex].InstanceDataStepRate = 1; - if (numIndicesPerInstance > 0 && sortedAttributes[elementIndex]->divisor > 0) - { - inputElements[elementIndex].InstanceDataStepRate = numIndicesPerInstance; - } + inputElements[elementIndex].InstanceDataStepRate = numIndicesPerInstance; } - inputElements[elementIndex].InputSlot++; } + inputElements[elementIndex].InputSlot++; } inputElements[inputElementCount].SemanticName = "SPRITEPOSITION"; @@ -622,28 +481,23 @@ gl::Error InputLayoutCache::createInputLayout(const SortedAttribArray &sortedAtt inputElementCount++; } - const gl::InputLayout &shaderInputLayout = GetInputLayout(sortedAttributes, attribCount); - ShaderExecutableD3D *shader = nullptr; - gl::Error error = - programD3D->getVertexExecutableForInputLayout(shaderInputLayout, &shader, nullptr); - if (error.isError()) - { - return error; - } + ANGLE_TRY(programD3D->getVertexExecutableForCachedInputLayout(&shader, nullptr)); ShaderExecutableD3D *shader11 = GetAs(shader); - HRESULT result = - mDevice->CreateInputLayout(inputElements.data(), inputElementCount, shader11->getFunction(), - shader11->getLength(), inputLayoutOut); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, - "Failed to create internal input layout, HRESULT: 0x%08x", result); - } + InputElementArray inputElementArray(inputElements.data(), inputElementCount); + ShaderData vertexShaderData(shader11->getFunction(), shader11->getLength()); - return gl::Error(GL_NO_ERROR); + ANGLE_TRY(renderer->allocateResource(inputElementArray, &vertexShaderData, inputLayoutOut)); + return gl::NoError(); +} + +void InputLayoutCache::setCacheSize(size_t newCacheSize) +{ + // Forces a reset of the cache. + LayoutCache newCache(newCacheSize); + mLayoutCache.Swap(newCache); } } // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h index e208ae3c64..8d7c7dd0f0 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h @@ -20,12 +20,55 @@ #include "common/angleutils.h" #include "libANGLE/Constants.h" #include "libANGLE/Error.h" +#include "libANGLE/SizedMRUCache.h" #include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" +#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h" + +namespace rx +{ +class DrawCallVertexParams; +struct PackedAttributeLayout +{ + PackedAttributeLayout(); + PackedAttributeLayout(const PackedAttributeLayout &other); + + void addAttributeData(GLenum glType, + UINT semanticIndex, + gl::VertexFormatType vertexFormatType, + unsigned int divisor); + + bool operator==(const PackedAttributeLayout &other) const; + + enum Flags + { + FLAG_USES_INSTANCED_SPRITES = 0x1, + FLAG_INSTANCED_SPRITES_ACTIVE = 0x2, + FLAG_INSTANCED_RENDERING_ACTIVE = 0x4, + }; + + uint32_t numAttributes; + uint32_t flags; + std::array attributeData; +}; +} // namespace rx + +namespace std +{ +template <> +struct hash +{ + size_t operator()(const rx::PackedAttributeLayout &value) const + { + return angle::ComputeGenericHash(value); + } +}; +} // namespace std namespace gl { class Program; -} +} // namespace gl namespace rx { @@ -33,91 +76,58 @@ struct TranslatedAttribute; struct TranslatedIndexData; struct SourceIndexData; class ProgramD3D; - -using SortedAttribArray = std::array; -using SortedIndexArray = std::array; +class Renderer11; class InputLayoutCache : angle::NonCopyable { public: InputLayoutCache(); - virtual ~InputLayoutCache(); + ~InputLayoutCache(); - void initialize(ID3D11Device *device, ID3D11DeviceContext *context); void clear(); - void markDirty(); - gl::Error applyVertexBuffers(const std::vector &attributes, + gl::Error applyVertexBuffers(const gl::Context *context, + const std::vector ¤tAttributes, GLenum mode, - gl::Program *program, - TranslatedIndexData *indexInfo, - GLsizei numIndicesPerInstance); + GLint start, + bool isIndexedRendering); - gl::Error updateVertexOffsetsForPointSpritesEmulation(GLsizei emulatedInstanceId); + gl::Error updateVertexOffsetsForPointSpritesEmulation( + Renderer11 *renderer, + const std::vector ¤tAttributes, + GLint startVertex, + GLsizei emulatedInstanceId); // Useful for testing - void setCacheSize(unsigned int cacheSize) { mCacheSize = cacheSize; } + void setCacheSize(size_t newCacheSize); + + gl::Error updateInputLayout(Renderer11 *renderer, + const gl::State &state, + const std::vector ¤tAttributes, + GLenum mode, + const AttribIndexArray &sortedSemanticIndices, + const DrawCallVertexParams &vertexParams); private: - struct PackedAttributeLayout - { - PackedAttributeLayout() - : numAttributes(0), - flags(0) - { - } - - void addAttributeData(GLenum glType, - UINT semanticIndex, - gl::VertexFormatType vertexFormatType, - unsigned int divisor); - - bool operator<(const PackedAttributeLayout &other) const; - - enum Flags - { - FLAG_USES_INSTANCED_SPRITES = 0x1, - FLAG_INSTANCED_SPRITES_ACTIVE = 0x2, - FLAG_INSTANCED_RENDERING_ACTIVE = 0x4, - }; - - size_t numAttributes; - unsigned int flags; - uint32_t attributeData[gl::MAX_VERTEX_ATTRIBS]; - }; - - gl::Error updateInputLayout(gl::Program *program, - GLenum mode, - const SortedAttribArray &sortedAttributes, - const SortedIndexArray &sortedSemanticIndices, - size_t attribCount, - GLsizei numIndicesPerInstance); - gl::Error createInputLayout(const SortedAttribArray &sortedAttributes, - const SortedIndexArray &sortedSemanticIndices, - size_t attribCount, + gl::Error createInputLayout(Renderer11 *renderer, + const AttribIndexArray &sortedSemanticIndices, + const std::vector ¤tAttributes, GLenum mode, gl::Program *program, - GLsizei numIndicesPerInstance, - ID3D11InputLayout **inputLayoutOut); + const DrawCallVertexParams &vertexParams, + d3d11::InputLayout *inputLayoutOut); - std::map mLayoutMap; + // Starting cache size. + static constexpr size_t kDefaultCacheSize = 1024; - ID3D11InputLayout *mCurrentIL; - ID3D11Buffer *mCurrentBuffers[gl::MAX_VERTEX_ATTRIBS]; - UINT mCurrentVertexStrides[gl::MAX_VERTEX_ATTRIBS]; - UINT mCurrentVertexOffsets[gl::MAX_VERTEX_ATTRIBS]; - SortedAttribArray mSortedAttributes; - size_t mUnsortedAttributesCount; + // The cache tries to clean up this many states at once. + static constexpr size_t kGCLimit = 128; - ID3D11Buffer *mPointSpriteVertexBuffer; - ID3D11Buffer *mPointSpriteIndexBuffer; + using LayoutCache = angle::base::HashingMRUCache; + LayoutCache mLayoutCache; - unsigned int mCacheSize; - unsigned long long mCounter; - - ID3D11Device *mDevice; - ID3D11DeviceContext *mDeviceContext; - D3D_FEATURE_LEVEL mFeatureLevel; + d3d11::Buffer mPointSpriteVertexBuffer; + d3d11::Buffer mPointSpriteIndexBuffer; }; } // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h deleted file mode 100644 index 612b06bb10..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h +++ /dev/null @@ -1,97 +0,0 @@ -// -// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// NativeWindow.h: Defines NativeWindow, a class for managing and -// performing operations on an EGLNativeWindowType. -// It is used for HWND (Desktop Windows) and IInspectable objects -//(Windows Store Applications). - -#ifndef LIBANGLE_RENDERER_D3D_D3D11_NATIVEWINDOW_H_ -#define LIBANGLE_RENDERER_D3D_D3D11_NATIVEWINDOW_H_ - -#include "common/debug.h" -#include "common/platform.h" - -#include -#include "libANGLE/Config.h" - -// DXGISwapChain and DXGIFactory are typedef'd to specific required -// types. The HWND NativeWindow implementation requires IDXGISwapChain -// and IDXGIFactory and the Windows Store NativeWindow -// implementation requires IDXGISwapChain1 and IDXGIFactory2. -#if defined(ANGLE_ENABLE_WINDOWS_STORE) -typedef IDXGISwapChain1 DXGISwapChain; -typedef IDXGIFactory2 DXGIFactory; - -#include -#include -#include -#include - -namespace rx -{ -class InspectableNativeWindow; -} - -using namespace Microsoft::WRL; -using namespace Microsoft::WRL::Wrappers; - -#elif defined(ANGLE_ENABLE_D3D11) -typedef IDXGISwapChain DXGISwapChain; -typedef IDXGIFactory DXGIFactory; -#endif - -typedef interface IDCompositionDevice IDCompositionDevice; -typedef interface IDCompositionTarget IDCompositionTarget; -typedef interface IDCompositionVisual IDCompositionVisual; - -namespace rx -{ - -class NativeWindow -{ - public: - enum RotationFlags { RotateNone = 0, RotateLeft = 1, RotateRight = 2 }; - explicit NativeWindow(EGLNativeWindowType window, - const egl::Config *config, - bool directComposition); - - ~NativeWindow(); - bool initialize(); - bool getClientRect(LPRECT rect); - bool isIconic(); -#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) - RotationFlags rotationFlags() const; -#endif - static bool isValidNativeWindow(EGLNativeWindowType window); - -#if defined(ANGLE_ENABLE_D3D11) - HRESULT createSwapChain(ID3D11Device* device, DXGIFactory* factory, - DXGI_FORMAT format, UINT width, UINT height, - DXGISwapChain** swapChain); -#endif - - inline EGLNativeWindowType getNativeWindow() const { return mWindow; } - - void commitChange(); - - private: - EGLNativeWindowType mWindow; - - bool mDirectComposition; - IDCompositionDevice *mDevice; - IDCompositionTarget *mCompositionTarget; - IDCompositionVisual *mVisual; - const egl::Config *mConfig; -#if defined(ANGLE_ENABLE_WINDOWS_STORE) - std::shared_ptr mImpl; -#endif - -}; - -} - -#endif // LIBANGLE_RENDERER_D3D_D3D11_NATIVEWINDOW_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow11.h new file mode 100644 index 0000000000..ab234d4450 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow11.h @@ -0,0 +1,38 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// NativeWindow11.h: Defines NativeWindow11, a class for managing and performing operations on an +// EGLNativeWindowType for the D3D11 renderer. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_NATIVEWINDOW11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_NATIVEWINDOW11_H_ + +#include "common/debug.h" +#include "common/platform.h" + +#include "libANGLE/Config.h" +#include "libANGLE/renderer/d3d/NativeWindowD3D.h" + +namespace rx +{ + +class NativeWindow11 : public NativeWindowD3D +{ + public: + NativeWindow11(EGLNativeWindowType window) : NativeWindowD3D(window) {} + + virtual HRESULT createSwapChain(ID3D11Device *device, + IDXGIFactory *factory, + DXGI_FORMAT format, + UINT width, + UINT height, + UINT samples, + IDXGISwapChain **swapChain) = 0; + virtual void commitChange() = 0; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_NATIVEWINDOW11_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp index dfc521f14f..7d7ecb0976 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp @@ -36,40 +36,25 @@ namespace rx PixelTransfer11::PixelTransfer11(Renderer11 *renderer) : mRenderer(renderer), mResourcesLoaded(false), - mBufferToTextureVS(NULL), - mBufferToTextureGS(NULL), - mParamsConstantBuffer(NULL), - mCopyRasterizerState(NULL), - mCopyDepthStencilState(NULL) + mBufferToTextureVS(), + mBufferToTextureGS(), + mParamsConstantBuffer(), + mCopyRasterizerState(), + mCopyDepthStencilState() { } PixelTransfer11::~PixelTransfer11() { - for (auto shaderMapIt = mBufferToTexturePSMap.begin(); shaderMapIt != mBufferToTexturePSMap.end(); shaderMapIt++) - { - SafeRelease(shaderMapIt->second); - } - - mBufferToTexturePSMap.clear(); - - SafeRelease(mBufferToTextureVS); - SafeRelease(mBufferToTextureGS); - SafeRelease(mParamsConstantBuffer); - SafeRelease(mCopyRasterizerState); - SafeRelease(mCopyDepthStencilState); } gl::Error PixelTransfer11::loadResources() { if (mResourcesLoaded) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } - HRESULT result = S_OK; - ID3D11Device *device = mRenderer->getDevice(); - D3D11_RASTERIZER_DESC rasterDesc; rasterDesc.FillMode = D3D11_FILL_SOLID; rasterDesc.CullMode = D3D11_CULL_NONE; @@ -82,12 +67,7 @@ gl::Error PixelTransfer11::loadResources() rasterDesc.MultisampleEnable = FALSE; rasterDesc.AntialiasedLineEnable = FALSE; - result = device->CreateRasterizerState(&rasterDesc, &mCopyRasterizerState); - ASSERT(SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal pixel transfer rasterizer state, result: 0x%X.", result); - } + ANGLE_TRY(mRenderer->allocateResource(rasterDesc, &mCopyRasterizerState)); D3D11_DEPTH_STENCIL_DESC depthStencilDesc; depthStencilDesc.DepthEnable = true; @@ -105,12 +85,7 @@ gl::Error PixelTransfer11::loadResources() depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; - result = device->CreateDepthStencilState(&depthStencilDesc, &mCopyDepthStencilState); - ASSERT(SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal pixel transfer depth stencil state, result: 0x%X.", result); - } + ANGLE_TRY(mRenderer->allocateResource(depthStencilDesc, &mCopyDepthStencilState)); D3D11_BUFFER_DESC constantBufferDesc = { 0 }; constantBufferDesc.ByteWidth = roundUp(sizeof(CopyShaderParams), 32u); @@ -120,38 +95,23 @@ gl::Error PixelTransfer11::loadResources() constantBufferDesc.MiscFlags = 0; constantBufferDesc.StructureByteStride = 0; - result = device->CreateBuffer(&constantBufferDesc, NULL, &mParamsConstantBuffer); - ASSERT(SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal pixel transfer constant buffer, result: 0x%X.", result); - } - d3d11::SetDebugName(mParamsConstantBuffer, "PixelTransfer11 constant buffer"); + ANGLE_TRY(mRenderer->allocateResource(constantBufferDesc, &mParamsConstantBuffer)); + mParamsConstantBuffer.setDebugName("PixelTransfer11 constant buffer"); // init shaders - mBufferToTextureVS = d3d11::CompileVS(device, g_VS_BufferToTexture, "BufferToTexture VS"); - if (!mBufferToTextureVS) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture vertex shader."); - } + ANGLE_TRY(mRenderer->allocateResource(ShaderData(g_VS_BufferToTexture), &mBufferToTextureVS)); + mBufferToTextureVS.setDebugName("BufferToTexture VS"); - mBufferToTextureGS = d3d11::CompileGS(device, g_GS_BufferToTexture, "BufferToTexture GS"); - if (!mBufferToTextureGS) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture geometry shader."); - } + ANGLE_TRY(mRenderer->allocateResource(ShaderData(g_GS_BufferToTexture), &mBufferToTextureGS)); + mBufferToTextureGS.setDebugName("BufferToTexture GS"); - gl::Error error = buildShaderMap(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(buildShaderMap()); StructZero(&mParamsData); mResourcesLoaded = true; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } void PixelTransfer11::setBufferToTextureCopyParams(const gl::Box &destArea, const gl::Extents &destSize, GLenum internalFormat, @@ -162,7 +122,7 @@ void PixelTransfer11::setBufferToTextureCopyParams(const gl::Box &destArea, cons float texelCenterX = 0.5f / static_cast(destSize.width - 1); float texelCenterY = 0.5f / static_cast(destSize.height - 1); - unsigned int bytesPerPixel = gl::GetInternalFormatInfo(internalFormat).pixelBytes; + unsigned int bytesPerPixel = gl::GetSizedInternalFormatInfo(internalFormat).pixelBytes; unsigned int alignmentBytes = static_cast(unpack.alignment); unsigned int alignmentPixels = (alignmentBytes <= bytesPerPixel ? 1 : alignmentBytes / bytesPerPixel); @@ -177,14 +137,15 @@ void PixelTransfer11::setBufferToTextureCopyParams(const gl::Box &destArea, cons parametersOut->FirstSlice = destArea.z; } -gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget, - GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) +gl::Error PixelTransfer11::copyBufferToTexture(const gl::Context *context, + const gl::PixelUnpackState &unpack, + unsigned int offset, + RenderTargetD3D *destRenderTarget, + GLenum destinationFormat, + GLenum sourcePixelsType, + const gl::Box &destArea) { - gl::Error error = loadResources(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(loadResources()); gl::Extents destSize = destRenderTarget->getExtents(); @@ -192,114 +153,106 @@ gl::Error PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpac destArea.y >= 0 && destArea.y + destArea.height <= destSize.height && destArea.z >= 0 && destArea.z + destArea.depth <= destSize.depth ); - const gl::Buffer &sourceBuffer = *unpack.pixelBuffer.get(); + const gl::Buffer &sourceBuffer = + *context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack); ASSERT(mRenderer->supportsFastCopyBufferToTexture(destinationFormat)); - ID3D11PixelShader *pixelShader = findBufferToTexturePS(destinationFormat); + const d3d11::PixelShader *pixelShader = findBufferToTexturePS(destinationFormat); ASSERT(pixelShader); // The SRV must be in the proper read format, which may be different from the destination format // EG: for half float data, we can load full precision floats with implicit conversion - GLenum unsizedFormat = gl::GetInternalFormatInfo(destinationFormat).format; - GLenum sourceFormat = gl::GetSizedInternalFormat(unsizedFormat, sourcePixelsType); + GLenum unsizedFormat = gl::GetUnsizedFormat(destinationFormat); + const gl::InternalFormat &sourceglFormatInfo = + gl::GetInternalFormatInfo(unsizedFormat, sourcePixelsType); - const d3d11::TextureFormat &sourceFormatInfo = d3d11::GetTextureFormatInfo(sourceFormat, mRenderer->getRenderer11DeviceCaps()); + const d3d11::Format &sourceFormatInfo = d3d11::Format::Get( + sourceglFormatInfo.sizedInternalFormat, mRenderer->getRenderer11DeviceCaps()); DXGI_FORMAT srvFormat = sourceFormatInfo.srvFormat; ASSERT(srvFormat != DXGI_FORMAT_UNKNOWN); Buffer11 *bufferStorage11 = GetAs(sourceBuffer.getImplementation()); - ID3D11ShaderResourceView *bufferSRV = bufferStorage11->getSRV(srvFormat); - ASSERT(bufferSRV != NULL); + const d3d11::ShaderResourceView *bufferSRV = nullptr; + ANGLE_TRY_RESULT(bufferStorage11->getSRV(context, srvFormat), bufferSRV); + ASSERT(bufferSRV != nullptr); - ID3D11RenderTargetView *textureRTV = GetAs(destRenderTarget)->getRenderTargetView(); - ASSERT(textureRTV != NULL); + const d3d11::RenderTargetView &textureRTV = + GetAs(destRenderTarget)->getRenderTargetView(); + ASSERT(textureRTV.valid()); CopyShaderParams shaderParams; - setBufferToTextureCopyParams(destArea, destSize, sourceFormat, unpack, offset, &shaderParams); + setBufferToTextureCopyParams(destArea, destSize, sourceglFormatInfo.sizedInternalFormat, unpack, + offset, &shaderParams); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); - ID3D11Buffer *nullBuffer = NULL; - UINT zero = 0; - // Are we doing a 2D or 3D copy? - ID3D11GeometryShader *geometryShader = ((destSize.depth > 1) ? mBufferToTextureGS : NULL); - auto stateManager = mRenderer->getStateManager(); + const auto *geometryShader = ((destSize.depth > 1) ? &mBufferToTextureGS : nullptr); + StateManager11 *stateManager = mRenderer->getStateManager(); - deviceContext->VSSetShader(mBufferToTextureVS, NULL, 0); - deviceContext->GSSetShader(geometryShader, NULL, 0); - deviceContext->PSSetShader(pixelShader, NULL, 0); + stateManager->setDrawShaders(&mBufferToTextureVS, geometryShader, pixelShader); stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, bufferSRV); - deviceContext->IASetInputLayout(NULL); - deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); + stateManager->setInputLayout(nullptr); + stateManager->setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); - deviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero); - deviceContext->OMSetBlendState(NULL, NULL, 0xFFFFFFF); - deviceContext->OMSetDepthStencilState(mCopyDepthStencilState, 0xFFFFFFFF); - deviceContext->RSSetState(mCopyRasterizerState); + stateManager->setSingleVertexBuffer(nullptr, 0, 0); + stateManager->setSimpleBlendState(nullptr); + stateManager->setDepthStencilState(&mCopyDepthStencilState, 0xFFFFFFFF); + stateManager->setRasterizerState(&mCopyRasterizerState); - mRenderer->setOneTimeRenderTarget(textureRTV); + stateManager->setRenderTarget(textureRTV.get(), nullptr); if (!StructEquals(mParamsData, shaderParams)) { - d3d11::SetBufferData(deviceContext, mParamsConstantBuffer, shaderParams); + d3d11::SetBufferData(deviceContext, mParamsConstantBuffer.get(), shaderParams); mParamsData = shaderParams; } - deviceContext->VSSetConstantBuffers(0, 1, &mParamsConstantBuffer); + stateManager->setVertexConstantBuffer(0, &mParamsConstantBuffer); // Set the viewport - D3D11_VIEWPORT viewport; - viewport.TopLeftX = 0; - viewport.TopLeftY = 0; - viewport.Width = static_cast(destSize.width); - viewport.Height = static_cast(destSize.height); - viewport.MinDepth = 0.0f; - viewport.MaxDepth = 1.0f; - deviceContext->RSSetViewports(1, &viewport); + stateManager->setSimpleViewport(destSize); UINT numPixels = (destArea.width * destArea.height * destArea.depth); deviceContext->Draw(numPixels, 0); - // Unbind textures and render targets and vertex buffer - stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); - deviceContext->VSSetConstantBuffers(0, 1, &nullBuffer); - - mRenderer->markAllStateDirty(); - - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error PixelTransfer11::buildShaderMap() { - ID3D11Device *device = mRenderer->getDevice(); + d3d11::PixelShader bufferToTextureFloat; + d3d11::PixelShader bufferToTextureInt; + d3d11::PixelShader bufferToTextureUint; - mBufferToTexturePSMap[GL_FLOAT] = d3d11::CompilePS(device, g_PS_BufferToTexture_4F, "BufferToTexture RGBA ps"); - mBufferToTexturePSMap[GL_INT] = d3d11::CompilePS(device, g_PS_BufferToTexture_4I, "BufferToTexture RGBA-I ps"); - mBufferToTexturePSMap[GL_UNSIGNED_INT] = d3d11::CompilePS(device, g_PS_BufferToTexture_4UI, "BufferToTexture RGBA-UI ps"); + ANGLE_TRY( + mRenderer->allocateResource(ShaderData(g_PS_BufferToTexture_4F), &bufferToTextureFloat)); + ANGLE_TRY( + mRenderer->allocateResource(ShaderData(g_PS_BufferToTexture_4I), &bufferToTextureInt)); + ANGLE_TRY( + mRenderer->allocateResource(ShaderData(g_PS_BufferToTexture_4UI), &bufferToTextureUint)); - // Check that all the shaders were created successfully - for (auto shaderMapIt = mBufferToTexturePSMap.begin(); shaderMapIt != mBufferToTexturePSMap.end(); shaderMapIt++) - { - if (shaderMapIt->second == NULL) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal buffer to texture pixel shader."); - } - } + bufferToTextureFloat.setDebugName("BufferToTexture RGBA ps"); + bufferToTextureInt.setDebugName("BufferToTexture RGBA-I ps"); + bufferToTextureUint.setDebugName("BufferToTexture RGBA-UI ps"); - return gl::Error(GL_NO_ERROR); + mBufferToTexturePSMap[GL_FLOAT] = std::move(bufferToTextureFloat); + mBufferToTexturePSMap[GL_INT] = std::move(bufferToTextureInt); + mBufferToTexturePSMap[GL_UNSIGNED_INT] = std::move(bufferToTextureUint); + + return gl::NoError(); } -ID3D11PixelShader *PixelTransfer11::findBufferToTexturePS(GLenum internalFormat) const +const d3d11::PixelShader *PixelTransfer11::findBufferToTexturePS(GLenum internalFormat) const { - GLenum componentType = gl::GetInternalFormatInfo(internalFormat).componentType; + GLenum componentType = gl::GetSizedInternalFormatInfo(internalFormat).componentType; if (componentType == GL_SIGNED_NORMALIZED || componentType == GL_UNSIGNED_NORMALIZED) { componentType = GL_FLOAT; } auto shaderMapIt = mBufferToTexturePSMap.find(componentType); - return (shaderMapIt == mBufferToTexturePSMap.end() ? NULL : shaderMapIt->second); + return (shaderMapIt == mBufferToTexturePSMap.end() ? nullptr : &shaderMapIt->second); } -} +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.h index 1672121ec7..a93544247e 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.h @@ -11,14 +11,14 @@ #ifndef LIBANGLE_RENDERER_D3D_D3D11_PIXELTRANSFER11_H_ #define LIBANGLE_RENDERER_D3D_D3D11_PIXELTRANSFER11_H_ -#include "libANGLE/Error.h" - -#include "common/platform.h" - #include #include +#include "common/platform.h" +#include "libANGLE/Error.h" +#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h" + namespace gl { @@ -45,8 +45,13 @@ class PixelTransfer11 // destRenderTarget: individual slice/layer of a target texture // destinationFormat/sourcePixelsType: determines shaders + shader parameters // destArea: the sub-section of destRenderTarget to copy to - gl::Error copyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget, - GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea); + gl::Error copyBufferToTexture(const gl::Context *context, + const gl::PixelUnpackState &unpack, + unsigned int offset, + RenderTargetD3D *destRenderTarget, + GLenum destinationFormat, + GLenum sourcePixelsType, + const gl::Box &destArea); private: @@ -68,22 +73,21 @@ class PixelTransfer11 gl::Error loadResources(); gl::Error buildShaderMap(); - ID3D11PixelShader *findBufferToTexturePS(GLenum internalFormat) const; + const d3d11::PixelShader *findBufferToTexturePS(GLenum internalFormat) const; Renderer11 *mRenderer; bool mResourcesLoaded; - std::map mBufferToTexturePSMap; - ID3D11VertexShader *mBufferToTextureVS; - ID3D11GeometryShader *mBufferToTextureGS; - ID3D11Buffer *mParamsConstantBuffer; + std::map mBufferToTexturePSMap; + d3d11::VertexShader mBufferToTextureVS; + d3d11::GeometryShader mBufferToTextureGS; + d3d11::Buffer mParamsConstantBuffer; CopyShaderParams mParamsData; - ID3D11RasterizerState *mCopyRasterizerState; - ID3D11DepthStencilState *mCopyDepthStencilState; - + d3d11::RasterizerState mCopyRasterizerState; + d3d11::DepthStencilState mCopyDepthStencilState; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_D3D11_PIXELTRANSFER11_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ProgramPipeline11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ProgramPipeline11.cpp new file mode 100644 index 0000000000..c9554431e5 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ProgramPipeline11.cpp @@ -0,0 +1,24 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ProgramPipelineNULL.cpp: +// Implements the class methods for ProgramPipeline11. +// + +#include "libANGLE/renderer/d3d/d3d11/ProgramPipeline11.h" + +namespace rx +{ + +ProgramPipeline11::ProgramPipeline11(const gl::ProgramPipelineState &state) + : ProgramPipelineImpl(state) +{ +} + +ProgramPipeline11::~ProgramPipeline11() +{ +} + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ProgramPipeline11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ProgramPipeline11.h new file mode 100644 index 0000000000..cf838eec05 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ProgramPipeline11.h @@ -0,0 +1,27 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ProgramPipeline11.h: +// Defines the class interface for ProgramPipeline11, implementing ProgramPipelineImpl. +// + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_PROGRAMPIPELINE11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_PROGRAMPIPELINE11_H_ + +#include "libANGLE/renderer/ProgramPipelineImpl.h" + +namespace rx +{ + +class ProgramPipeline11 : public ProgramPipelineImpl +{ + public: + ProgramPipeline11(const gl::ProgramPipelineState &state); + ~ProgramPipeline11() override; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_PROGRAMPIPELINE11_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp index 0a79b26df0..66b9476e7f 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp @@ -7,146 +7,96 @@ // Query11.cpp: Defines the rx::Query11 class which implements rx::QueryImpl. #include "libANGLE/renderer/d3d/d3d11/Query11.h" -#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" -#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" -#include "common/utilities.h" #include -#if defined(ANGLE_MINGW32_COMPAT) -typedef struct D3D11_QUERY_DATA_SO_STATISTICS { - UINT64 NumPrimitivesWritten; - UINT64 PrimitivesStorageNeeded; -} D3D11_QUERY_DATA_SO_STATISTICS; -#endif // ANGLE_MINGW32_COMPAT +#include "common/utilities.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" -#ifndef ANGLE_D3D11_QDTD_AVAILABLE -typedef struct D3D11_QUERY_DATA_TIMESTAMP_DISJOINT { - UINT64 Frequency; - BOOL Disjoint; -} D3D11_QUERY_DATA_TIMESTAMP_DISJOINT; -#endif // MINGW32 +namespace +{ + +GLuint64 MergeQueryResults(GLenum type, GLuint64 currentResult, GLuint64 newResult) +{ + switch (type) + { + case GL_ANY_SAMPLES_PASSED: + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE: + return (currentResult == GL_TRUE || newResult == GL_TRUE) ? GL_TRUE : GL_FALSE; + + case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: + return currentResult + newResult; + + case GL_TIME_ELAPSED_EXT: + return currentResult + newResult; + + case GL_TIMESTAMP_EXT: + return newResult; + + case GL_COMMANDS_COMPLETED_CHROMIUM: + return newResult; + + default: + UNREACHABLE(); + return 0; + } +} + +} // anonymous namespace namespace rx { -Query11::Query11(Renderer11 *renderer, GLenum type) - : QueryImpl(type), - mResult(0), - mQueryFinished(false), - mRenderer(renderer), - mQuery(nullptr), - mTimestampBeginQuery(nullptr), - mTimestampEndQuery(nullptr) +Query11::QueryState::QueryState() : query(), beginTimestamp(), endTimestamp(), finished(false) { } +Query11::QueryState::~QueryState() +{ +} + +Query11::Query11(Renderer11 *renderer, GLenum type) + : QueryImpl(type), mResult(0), mResultSum(0), mRenderer(renderer) +{ + mActiveQuery = std::unique_ptr(new QueryState()); +} + Query11::~Query11() { - SafeRelease(mQuery); - SafeRelease(mTimestampBeginQuery); - SafeRelease(mTimestampEndQuery); + mRenderer->getStateManager()->onDeleteQueryObject(this); } gl::Error Query11::begin() { - if (mQuery == nullptr) - { - D3D11_QUERY_DESC queryDesc; - queryDesc.Query = gl_d3d11::ConvertQueryType(getType()); - queryDesc.MiscFlags = 0; - - ID3D11Device *device = mRenderer->getDevice(); - - HRESULT result = device->CreateQuery(&queryDesc, &mQuery); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Internal query creation failed, result: 0x%X.", result); - } - - // If we are doing time elapsed we also need a query to actually query the timestamp - if (getType() == GL_TIME_ELAPSED_EXT) - { - D3D11_QUERY_DESC desc; - desc.Query = D3D11_QUERY_TIMESTAMP; - desc.MiscFlags = 0; - result = device->CreateQuery(&desc, &mTimestampBeginQuery); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Internal query creation failed, result: 0x%X.", - result); - } - result = device->CreateQuery(&desc, &mTimestampEndQuery); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Internal query creation failed, result: 0x%X.", - result); - } - } - } - - ID3D11DeviceContext *context = mRenderer->getDeviceContext(); - - context->Begin(mQuery); - - // If we are doing time elapsed query the begin timestamp - if (getType() == GL_TIME_ELAPSED_EXT) - { - context->End(mTimestampBeginQuery); - } - return gl::Error(GL_NO_ERROR); + mResultSum = 0; + mRenderer->getStateManager()->onBeginQuery(this); + return resume(); } gl::Error Query11::end() { - ASSERT(mQuery); - - ID3D11DeviceContext *context = mRenderer->getDeviceContext(); - - // If we are doing time elapsed query the end timestamp - if (getType() == GL_TIME_ELAPSED_EXT) - { - context->End(mTimestampEndQuery); - } - - context->End(mQuery); - - mQueryFinished = false; - mResult = GL_FALSE; - - return gl::Error(GL_NO_ERROR); + return pause(); } gl::Error Query11::queryCounter() { // This doesn't do anything for D3D11 as we don't support timestamps ASSERT(getType() == GL_TIMESTAMP_EXT); - mQueryFinished = true; - mResult = 0; - return gl::Error(GL_NO_ERROR); + mResultSum = 0; + mPendingQueries.push_back(std::unique_ptr(new QueryState())); + return gl::NoError(); } template gl::Error Query11::getResultBase(T *params) { - while (!mQueryFinished) - { - gl::Error error = testQuery(); - if (error.isError()) - { - return error; - } + ASSERT(!mActiveQuery->query.valid()); + ANGLE_TRY(flush(true)); + ASSERT(mPendingQueries.empty()); + *params = static_cast(mResultSum); - if (!mQueryFinished) - { - ScheduleYield(); - } - } - - ASSERT(mQueryFinished); - *params = static_cast(mResult); - - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Query11::getResult(GLint *params) @@ -171,105 +121,197 @@ gl::Error Query11::getResult(GLuint64 *params) gl::Error Query11::isResultAvailable(bool *available) { - gl::Error error = testQuery(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(flush(false)); - *available = mQueryFinished; - - return gl::Error(GL_NO_ERROR); + *available = mPendingQueries.empty(); + return gl::NoError(); } -gl::Error Query11::testQuery() +gl::Error Query11::pause() { - if (!mQueryFinished) + if (mActiveQuery->query.valid()) { - ASSERT(mQuery); + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + GLenum queryType = getType(); + // If we are doing time elapsed query the end timestamp + if (queryType == GL_TIME_ELAPSED_EXT) + { + context->End(mActiveQuery->endTimestamp.get()); + } + + context->End(mActiveQuery->query.get()); + + mPendingQueries.push_back(std::move(mActiveQuery)); + mActiveQuery = std::unique_ptr(new QueryState()); + } + + return flush(false); +} + +gl::Error Query11::resume() +{ + if (!mActiveQuery->query.valid()) + { + ANGLE_TRY(flush(false)); + + GLenum queryType = getType(); + D3D11_QUERY d3dQueryType = gl_d3d11::ConvertQueryType(queryType); + + D3D11_QUERY_DESC queryDesc; + queryDesc.Query = d3dQueryType; + queryDesc.MiscFlags = 0; + + ANGLE_TRY(mRenderer->allocateResource(queryDesc, &mActiveQuery->query)); + + // If we are doing time elapsed we also need a query to actually query the timestamp + if (queryType == GL_TIME_ELAPSED_EXT) + { + D3D11_QUERY_DESC desc; + desc.Query = D3D11_QUERY_TIMESTAMP; + desc.MiscFlags = 0; + + ANGLE_TRY(mRenderer->allocateResource(desc, &mActiveQuery->beginTimestamp)); + ANGLE_TRY(mRenderer->allocateResource(desc, &mActiveQuery->endTimestamp)); + } + + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + + if (d3dQueryType != D3D11_QUERY_EVENT) + { + context->Begin(mActiveQuery->query.get()); + } + + // If we are doing time elapsed, query the begin timestamp + if (queryType == GL_TIME_ELAPSED_EXT) + { + context->End(mActiveQuery->beginTimestamp.get()); + } + } + + return gl::NoError(); +} + +gl::Error Query11::flush(bool force) +{ + while (!mPendingQueries.empty()) + { + QueryState *query = mPendingQueries.front().get(); + + do + { + ANGLE_TRY(testQuery(query)); + if (!query->finished && !force) + { + return gl::NoError(); + } + } while (!query->finished); + + mResultSum = MergeQueryResults(getType(), mResultSum, mResult); + mPendingQueries.pop_front(); + } + + return gl::NoError(); +} + +gl::Error Query11::testQuery(QueryState *queryState) +{ + if (!queryState->finished) + { ID3D11DeviceContext *context = mRenderer->getDeviceContext(); switch (getType()) { - case GL_ANY_SAMPLES_PASSED_EXT: - case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: + case GL_ANY_SAMPLES_PASSED_EXT: + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: { + ASSERT(queryState->query.valid()); UINT64 numPixels = 0; - HRESULT result = context->GetData(mQuery, &numPixels, sizeof(numPixels), 0); + HRESULT result = + context->GetData(queryState->query.get(), &numPixels, sizeof(numPixels), 0); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to get the data of an internal query, result: 0x%X.", result); + return gl::OutOfMemory() + << "Failed to get the data of an internal query, " << gl::FmtHR(result); } if (result == S_OK) { - mQueryFinished = true; - mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE; + queryState->finished = true; + mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE; } } break; - case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: + case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: { - D3D11_QUERY_DATA_SO_STATISTICS soStats = { 0 }; - HRESULT result = context->GetData(mQuery, &soStats, sizeof(soStats), 0); + ASSERT(queryState->query.valid()); + D3D11_QUERY_DATA_SO_STATISTICS soStats = {0}; + HRESULT result = + context->GetData(queryState->query.get(), &soStats, sizeof(soStats), 0); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to get the data of an internal query, result: 0x%X.", result); + return gl::OutOfMemory() + << "Failed to get the data of an internal query, " << gl::FmtHR(result); } if (result == S_OK) { - mQueryFinished = true; - mResult = static_cast(soStats.NumPrimitivesWritten); + queryState->finished = true; + mResult = static_cast(soStats.NumPrimitivesWritten); } } break; case GL_TIME_ELAPSED_EXT: { + ASSERT(queryState->query.valid()); + ASSERT(queryState->beginTimestamp.valid()); + ASSERT(queryState->endTimestamp.valid()); D3D11_QUERY_DATA_TIMESTAMP_DISJOINT timeStats = {0}; - HRESULT result = context->GetData(mQuery, &timeStats, sizeof(timeStats), 0); + HRESULT result = + context->GetData(queryState->query.get(), &timeStats, sizeof(timeStats), 0); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, - "Failed to get the data of an internal query, result: 0x%X.", - result); + return gl::OutOfMemory() + << "Failed to get the data of an internal query, " << gl::FmtHR(result); } if (result == S_OK) { UINT64 beginTime = 0; - HRESULT beginRes = - context->GetData(mTimestampBeginQuery, &beginTime, sizeof(UINT64), 0); + HRESULT beginRes = context->GetData(queryState->beginTimestamp.get(), + &beginTime, sizeof(UINT64), 0); if (FAILED(beginRes)) { - return gl::Error( - GL_OUT_OF_MEMORY, - "Failed to get the data of an internal query, result: 0x%X.", beginRes); + return gl::OutOfMemory() << "Failed to get the data of an internal query, " + << gl::FmtHR(beginRes); } UINT64 endTime = 0; - HRESULT endRes = - context->GetData(mTimestampEndQuery, &endTime, sizeof(UINT64), 0); + HRESULT endRes = context->GetData(queryState->endTimestamp.get(), &endTime, + sizeof(UINT64), 0); if (FAILED(endRes)) { - return gl::Error( - GL_OUT_OF_MEMORY, - "Failed to get the data of an internal query, result: 0x%X.", endRes); + return gl::OutOfMemory() << "Failed to get the data of an internal query, " + << gl::FmtHR(endRes); } if (beginRes == S_OK && endRes == S_OK) { - mQueryFinished = true; + queryState->finished = true; if (timeStats.Disjoint) { mRenderer->setGPUDisjoint(); } static_assert(sizeof(UINT64) == sizeof(unsigned long long), "D3D UINT64 isn't 64 bits"); - if (rx::IsUnsignedMultiplicationSafe(endTime - beginTime, 1000000000ull)) + + angle::CheckedNumeric checkedTime(endTime); + checkedTime -= beginTime; + checkedTime *= 1000000000ull; + checkedTime /= timeStats.Frequency; + if (checkedTime.IsValid()) { - mResult = ((endTime - beginTime) * 1000000000ull) / timeStats.Frequency; + mResult = checkedTime.ValueOrDie(); } else { @@ -288,23 +330,46 @@ gl::Error Query11::testQuery() // D3D11 doesn't support GL timestamp queries as D3D timestamps are not guaranteed // to have any sort of continuity outside of a disjoint timestamp query block, which // GL depends on - mResult = 0; + ASSERT(!queryState->query.valid()); + mResult = 0; + queryState->finished = true; } break; - default: - UNREACHABLE(); + case GL_COMMANDS_COMPLETED_CHROMIUM: + { + ASSERT(queryState->query.valid()); + BOOL completed = 0; + HRESULT result = + context->GetData(queryState->query.get(), &completed, sizeof(completed), 0); + if (FAILED(result)) + { + return gl::OutOfMemory() + << "Failed to get the data of an internal query, " << gl::FmtHR(result); + } + + if (result == S_OK) + { + queryState->finished = true; + ASSERT(completed == TRUE); + mResult = (completed == TRUE) ? GL_TRUE : GL_FALSE; + } + } break; + + default: + UNREACHABLE(); + break; } - if (!mQueryFinished && mRenderer->testDeviceLost()) + if (!queryState->finished && mRenderer->testDeviceLost()) { mRenderer->notifyDeviceLost(); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to test get query result, device is lost."); + return gl::OutOfMemory() << "Failed to test get query result, device is lost."; } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -} +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.h index 29a6e6f85d..a88a8892aa 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.h @@ -9,7 +9,10 @@ #ifndef LIBANGLE_RENDERER_D3D_D3D11_QUERY11_H_ #define LIBANGLE_RENDERER_D3D_D3D11_QUERY11_H_ +#include + #include "libANGLE/renderer/QueryImpl.h" +#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h" namespace rx { @@ -19,31 +22,45 @@ class Query11 : public QueryImpl { public: Query11(Renderer11 *renderer, GLenum type); - virtual ~Query11(); + ~Query11() override; - virtual gl::Error begin(); - virtual gl::Error end(); - virtual gl::Error queryCounter(); - virtual gl::Error getResult(GLint *params); - virtual gl::Error getResult(GLuint *params); - virtual gl::Error getResult(GLint64 *params); - virtual gl::Error getResult(GLuint64 *params); - virtual gl::Error isResultAvailable(bool *available); + gl::Error begin() override; + gl::Error end() override; + gl::Error queryCounter() override; + gl::Error getResult(GLint *params) override; + gl::Error getResult(GLuint *params) override; + gl::Error getResult(GLint64 *params) override; + gl::Error getResult(GLuint64 *params) override; + gl::Error isResultAvailable(bool *available) override; + + gl::Error pause(); + gl::Error resume(); private: - gl::Error testQuery(); + struct QueryState final : private angle::NonCopyable + { + QueryState(); + ~QueryState(); + + d3d11::Query query; + d3d11::Query beginTimestamp; + d3d11::Query endTimestamp; + bool finished; + }; + + gl::Error flush(bool force); + gl::Error testQuery(QueryState *queryState); template gl::Error getResultBase(T *params); GLuint64 mResult; - - bool mQueryFinished; + GLuint64 mResultSum; Renderer11 *mRenderer; - ID3D11Query *mQuery; - ID3D11Query *mTimestampBeginQuery; - ID3D11Query *mTimestampEndQuery; + + std::unique_ptr mActiveQuery; + std::deque> mPendingQueries; }; } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp index 2ee25cfb6c..5b85196c2e 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp @@ -17,338 +17,180 @@ #include "libANGLE/renderer/d3d/FramebufferD3D.h" #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #include "libANGLE/renderer/d3d/d3d11/Renderer11.h" -#include "third_party/murmurhash/MurmurHash3.h" namespace rx { using namespace gl_d3d11; -template -static void ClearStateMap(mapType &map) -{ - for (typename mapType::iterator i = map.begin(); i != map.end(); i++) - { - SafeRelease(i->second.first); - } - map.clear(); -} - -// MSDN's documentation of ID3D11Device::CreateBlendState, ID3D11Device::CreateRasterizerState, -// ID3D11Device::CreateDepthStencilState and ID3D11Device::CreateSamplerState claims the maximum -// number of unique states of each type an application can create is 4096 -const unsigned int RenderStateCache::kMaxBlendStates = 4096; -const unsigned int RenderStateCache::kMaxRasterizerStates = 4096; -const unsigned int RenderStateCache::kMaxDepthStencilStates = 4096; -const unsigned int RenderStateCache::kMaxSamplerStates = 4096; - -RenderStateCache::RenderStateCache(Renderer11 *renderer) - : mRenderer(renderer), - mCounter(0), - mBlendStateCache(kMaxBlendStates, hashBlendState, compareBlendStates), - mRasterizerStateCache(kMaxRasterizerStates, hashRasterizerState, compareRasterizerStates), - mDepthStencilStateCache(kMaxDepthStencilStates, hashDepthStencilState, compareDepthStencilStates), - mSamplerStateCache(kMaxSamplerStates, hashSamplerState, compareSamplerStates), - mDevice(NULL) +RenderStateCache::RenderStateCache() + : mBlendStateCache(kMaxStates), + mRasterizerStateCache(kMaxStates), + mDepthStencilStateCache(kMaxStates), + mSamplerStateCache(kMaxStates) { } RenderStateCache::~RenderStateCache() { - clear(); -} - -void RenderStateCache::initialize(ID3D11Device *device) -{ - clear(); - mDevice = device; } void RenderStateCache::clear() { - ClearStateMap(mBlendStateCache); - ClearStateMap(mRasterizerStateCache); - ClearStateMap(mDepthStencilStateCache); - ClearStateMap(mSamplerStateCache); + mBlendStateCache.Clear(); + mRasterizerStateCache.Clear(); + mDepthStencilStateCache.Clear(); + mSamplerStateCache.Clear(); } -std::size_t RenderStateCache::hashBlendState(const BlendStateKey &blendState) +// static +d3d11::BlendStateKey RenderStateCache::GetBlendStateKey(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::BlendState &blendState) { - static const unsigned int seed = 0xABCDEF98; + d3d11::BlendStateKey key; + FramebufferD3D *framebufferD3D = GetImplAs(framebuffer); + const gl::AttachmentList &colorbuffers = framebufferD3D->getColorAttachmentsForRender(context); + const UINT8 blendStateMask = + gl_d3d11::ConvertColorMask(blendState.colorMaskRed, blendState.colorMaskGreen, + blendState.colorMaskBlue, blendState.colorMaskAlpha); - std::size_t hash = 0; - MurmurHash3_x86_32(&blendState, sizeof(gl::BlendState), seed, &hash); - return hash; -} - -bool RenderStateCache::compareBlendStates(const BlendStateKey &a, const BlendStateKey &b) -{ - return memcmp(&a, &b, sizeof(BlendStateKey)) == 0; -} - -gl::Error RenderStateCache::getBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, - ID3D11BlendState **outBlendState) -{ - if (!mDevice) - { - return gl::Error(GL_OUT_OF_MEMORY, "Internal error, RenderStateCache is not initialized."); - } - - bool mrt = false; - - const FramebufferD3D *framebufferD3D = GetImplAs(framebuffer); - const gl::AttachmentList &colorbuffers = framebufferD3D->getColorAttachmentsForRender(); - - BlendStateKey key = {}; key.blendState = blendState; - for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment) - { - const gl::FramebufferAttachment *attachment = colorbuffers[colorAttachment]; - auto rtChannels = key.rtChannels[colorAttachment]; + for (size_t i = 0; i < colorbuffers.size(); i++) + { + const gl::FramebufferAttachment *attachment = colorbuffers[i]; if (attachment) { - if (colorAttachment > 0) - { - mrt = true; - } - - rtChannels[0] = attachment->getRedSize() > 0; - rtChannels[1] = attachment->getGreenSize() > 0; - rtChannels[2] = attachment->getBlueSize() > 0; - rtChannels[3] = attachment->getAlphaSize() > 0; + key.rtvMax = static_cast(i) + 1; + key.rtvMasks[i] = + (gl_d3d11::GetColorMask(*attachment->getFormat().info)) & blendStateMask; } } - BlendStateMap::iterator keyIter = mBlendStateCache.find(key); + return key; +} + +gl::Error RenderStateCache::getBlendState(Renderer11 *renderer, + const d3d11::BlendStateKey &key, + const d3d11::BlendState **outBlendState) +{ + auto keyIter = mBlendStateCache.Get(key); if (keyIter != mBlendStateCache.end()) { - BlendStateCounterPair &state = keyIter->second; - state.second = mCounter++; - *outBlendState = state.first; - return gl::Error(GL_NO_ERROR); + *outBlendState = &keyIter->second; + return gl::NoError(); } - else + + TrimCache(kMaxStates, kGCLimit, "blend state", &mBlendStateCache); + + // Create a new blend state and insert it into the cache + D3D11_BLEND_DESC blendDesc; + D3D11_RENDER_TARGET_BLEND_DESC &rtDesc0 = blendDesc.RenderTarget[0]; + const gl::BlendState &blendState = key.blendState; + + blendDesc.AlphaToCoverageEnable = blendState.sampleAlphaToCoverage; + blendDesc.IndependentBlendEnable = key.rtvMax > 1 ? TRUE : FALSE; + + rtDesc0 = {}; + + if (blendState.blend) { - if (mBlendStateCache.size() >= kMaxBlendStates) - { - TRACE("Overflowed the limit of %u blend states, removing the least recently used " - "to make room.", kMaxBlendStates); - - BlendStateMap::iterator leastRecentlyUsed = mBlendStateCache.begin(); - for (BlendStateMap::iterator i = mBlendStateCache.begin(); i != mBlendStateCache.end(); i++) - { - if (i->second.second < leastRecentlyUsed->second.second) - { - leastRecentlyUsed = i; - } - } - SafeRelease(leastRecentlyUsed->second.first); - mBlendStateCache.erase(leastRecentlyUsed); - } - - // Create a new blend state and insert it into the cache - D3D11_BLEND_DESC blendDesc = { 0 }; - blendDesc.AlphaToCoverageEnable = blendState.sampleAlphaToCoverage; - blendDesc.IndependentBlendEnable = mrt ? TRUE : FALSE; - - for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - { - D3D11_RENDER_TARGET_BLEND_DESC &rtBlend = blendDesc.RenderTarget[i]; - - rtBlend.BlendEnable = blendState.blend; - if (blendState.blend) - { - rtBlend.SrcBlend = gl_d3d11::ConvertBlendFunc(blendState.sourceBlendRGB, false); - rtBlend.DestBlend = gl_d3d11::ConvertBlendFunc(blendState.destBlendRGB, false); - rtBlend.BlendOp = gl_d3d11::ConvertBlendOp(blendState.blendEquationRGB); - - rtBlend.SrcBlendAlpha = gl_d3d11::ConvertBlendFunc(blendState.sourceBlendAlpha, true); - rtBlend.DestBlendAlpha = gl_d3d11::ConvertBlendFunc(blendState.destBlendAlpha, true); - rtBlend.BlendOpAlpha = gl_d3d11::ConvertBlendOp(blendState.blendEquationAlpha); - } - - rtBlend.RenderTargetWriteMask = gl_d3d11::ConvertColorMask(key.rtChannels[i][0] && blendState.colorMaskRed, - key.rtChannels[i][1] && blendState.colorMaskGreen, - key.rtChannels[i][2] && blendState.colorMaskBlue, - key.rtChannels[i][3] && blendState.colorMaskAlpha); - } - - ID3D11BlendState *dx11BlendState = NULL; - HRESULT result = mDevice->CreateBlendState(&blendDesc, &dx11BlendState); - if (FAILED(result) || !dx11BlendState) - { - return gl::Error(GL_OUT_OF_MEMORY, "Unable to create a ID3D11BlendState, HRESULT: 0x%X.", result); - } - - mBlendStateCache.insert(std::make_pair(key, std::make_pair(dx11BlendState, mCounter++))); - - *outBlendState = dx11BlendState; - return gl::Error(GL_NO_ERROR); + rtDesc0.BlendEnable = true; + rtDesc0.SrcBlend = gl_d3d11::ConvertBlendFunc(blendState.sourceBlendRGB, false); + rtDesc0.DestBlend = gl_d3d11::ConvertBlendFunc(blendState.destBlendRGB, false); + rtDesc0.BlendOp = gl_d3d11::ConvertBlendOp(blendState.blendEquationRGB); + rtDesc0.SrcBlendAlpha = gl_d3d11::ConvertBlendFunc(blendState.sourceBlendAlpha, true); + rtDesc0.DestBlendAlpha = gl_d3d11::ConvertBlendFunc(blendState.destBlendAlpha, true); + rtDesc0.BlendOpAlpha = gl_d3d11::ConvertBlendOp(blendState.blendEquationAlpha); } + + rtDesc0.RenderTargetWriteMask = key.rtvMasks[0]; + + for (unsigned int i = 1; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + { + blendDesc.RenderTarget[i] = rtDesc0; + blendDesc.RenderTarget[i].RenderTargetWriteMask = key.rtvMasks[i]; + } + + d3d11::BlendState d3dBlendState; + ANGLE_TRY(renderer->allocateResource(blendDesc, &d3dBlendState)); + const auto &iter = mBlendStateCache.Put(key, std::move(d3dBlendState)); + + *outBlendState = &iter->second; + + return gl::NoError(); } -std::size_t RenderStateCache::hashRasterizerState(const RasterizerStateKey &rasterState) -{ - static const unsigned int seed = 0xABCDEF98; - - std::size_t hash = 0; - MurmurHash3_x86_32(&rasterState, sizeof(RasterizerStateKey), seed, &hash); - return hash; -} - -bool RenderStateCache::compareRasterizerStates(const RasterizerStateKey &a, const RasterizerStateKey &b) -{ - return memcmp(&a, &b, sizeof(RasterizerStateKey)) == 0; -} - -gl::Error RenderStateCache::getRasterizerState(const gl::RasterizerState &rasterState, bool scissorEnabled, +gl::Error RenderStateCache::getRasterizerState(Renderer11 *renderer, + const gl::RasterizerState &rasterState, + bool scissorEnabled, ID3D11RasterizerState **outRasterizerState) { - if (!mDevice) - { - return gl::Error(GL_OUT_OF_MEMORY, "Internal error, RenderStateCache is not initialized."); - } - - RasterizerStateKey key = {}; + d3d11::RasterizerStateKey key; key.rasterizerState = rasterState; - key.scissorEnabled = scissorEnabled; + key.scissorEnabled = scissorEnabled ? 1 : 0; - RasterizerStateMap::iterator keyIter = mRasterizerStateCache.find(key); + auto keyIter = mRasterizerStateCache.Get(key); if (keyIter != mRasterizerStateCache.end()) { - RasterizerStateCounterPair &state = keyIter->second; - state.second = mCounter++; - *outRasterizerState = state.first; - return gl::Error(GL_NO_ERROR); + *outRasterizerState = keyIter->second.get(); + return gl::NoError(); + } + + TrimCache(kMaxStates, kGCLimit, "rasterizer state", &mRasterizerStateCache); + + D3D11_CULL_MODE cullMode = + gl_d3d11::ConvertCullMode(rasterState.cullFace, rasterState.cullMode); + + // Disable culling if drawing points + if (rasterState.pointDrawMode) + { + cullMode = D3D11_CULL_NONE; + } + + D3D11_RASTERIZER_DESC rasterDesc; + rasterDesc.FillMode = D3D11_FILL_SOLID; + rasterDesc.CullMode = cullMode; + rasterDesc.FrontCounterClockwise = (rasterState.frontFace == GL_CCW) ? FALSE : TRUE; + rasterDesc.DepthBiasClamp = 0.0f; // MSDN documentation of DepthBiasClamp implies a value of + // zero will preform no clamping, must be tested though. + rasterDesc.DepthClipEnable = TRUE; + rasterDesc.ScissorEnable = scissorEnabled ? TRUE : FALSE; + rasterDesc.MultisampleEnable = rasterState.multiSample; + rasterDesc.AntialiasedLineEnable = FALSE; + + if (rasterState.polygonOffsetFill) + { + rasterDesc.SlopeScaledDepthBias = rasterState.polygonOffsetFactor; + rasterDesc.DepthBias = (INT)rasterState.polygonOffsetUnits; } else { - if (mRasterizerStateCache.size() >= kMaxRasterizerStates) - { - TRACE("Overflowed the limit of %u rasterizer states, removing the least recently used " - "to make room.", kMaxRasterizerStates); - - RasterizerStateMap::iterator leastRecentlyUsed = mRasterizerStateCache.begin(); - for (RasterizerStateMap::iterator i = mRasterizerStateCache.begin(); i != mRasterizerStateCache.end(); i++) - { - if (i->second.second < leastRecentlyUsed->second.second) - { - leastRecentlyUsed = i; - } - } - SafeRelease(leastRecentlyUsed->second.first); - mRasterizerStateCache.erase(leastRecentlyUsed); - } - - D3D11_CULL_MODE cullMode = gl_d3d11::ConvertCullMode(rasterState.cullFace, rasterState.cullMode); - - // Disable culling if drawing points - if (rasterState.pointDrawMode) - { - cullMode = D3D11_CULL_NONE; - } - - D3D11_RASTERIZER_DESC rasterDesc; - rasterDesc.FillMode = D3D11_FILL_SOLID; - rasterDesc.CullMode = cullMode; - rasterDesc.FrontCounterClockwise = (rasterState.frontFace == GL_CCW) ? FALSE: TRUE; - rasterDesc.DepthBiasClamp = 0.0f; // MSDN documentation of DepthBiasClamp implies a value of zero will preform no clamping, must be tested though. - rasterDesc.DepthClipEnable = TRUE; - rasterDesc.ScissorEnable = scissorEnabled ? TRUE : FALSE; - rasterDesc.MultisampleEnable = rasterState.multiSample; - rasterDesc.AntialiasedLineEnable = FALSE; - - if (rasterState.polygonOffsetFill) - { - rasterDesc.SlopeScaledDepthBias = rasterState.polygonOffsetFactor; - rasterDesc.DepthBias = (INT)rasterState.polygonOffsetUnits; - } - else - { - rasterDesc.SlopeScaledDepthBias = 0.0f; - rasterDesc.DepthBias = 0; - } - - ID3D11RasterizerState *dx11RasterizerState = NULL; - HRESULT result = mDevice->CreateRasterizerState(&rasterDesc, &dx11RasterizerState); - if (FAILED(result) || !dx11RasterizerState) - { - return gl::Error(GL_OUT_OF_MEMORY, "Unable to create a ID3D11RasterizerState, HRESULT: 0x%X.", result); - } - - mRasterizerStateCache.insert(std::make_pair(key, std::make_pair(dx11RasterizerState, mCounter++))); - - *outRasterizerState = dx11RasterizerState; - return gl::Error(GL_NO_ERROR); + rasterDesc.SlopeScaledDepthBias = 0.0f; + rasterDesc.DepthBias = 0; } + + d3d11::RasterizerState dx11RasterizerState; + ANGLE_TRY(renderer->allocateResource(rasterDesc, &dx11RasterizerState)); + *outRasterizerState = dx11RasterizerState.get(); + mRasterizerStateCache.Put(key, std::move(dx11RasterizerState)); + + return gl::NoError(); } -std::size_t RenderStateCache::hashDepthStencilState(const gl::DepthStencilState &dsState) +gl::Error RenderStateCache::getDepthStencilState(Renderer11 *renderer, + const gl::DepthStencilState &glState, + const d3d11::DepthStencilState **outDSState) { - static const unsigned int seed = 0xABCDEF98; - - std::size_t hash = 0; - MurmurHash3_x86_32(&dsState, sizeof(gl::DepthStencilState), seed, &hash); - return hash; -} - -bool RenderStateCache::compareDepthStencilStates(const gl::DepthStencilState &a, const gl::DepthStencilState &b) -{ - return memcmp(&a, &b, sizeof(gl::DepthStencilState)) == 0; -} - -gl::Error RenderStateCache::getDepthStencilState(const gl::DepthStencilState &originalState, - bool disableDepth, - bool disableStencil, - ID3D11DepthStencilState **outDSState) -{ - if (!mDevice) - { - return gl::Error(GL_OUT_OF_MEMORY, "Internal error, RenderStateCache is not initialized."); - } - - gl::DepthStencilState glState = originalState; - if (disableDepth) - { - glState.depthTest = false; - glState.depthMask = false; - } - - if (disableStencil) - { - glState.stencilWritemask = 0; - glState.stencilBackWritemask = 0; - glState.stencilTest = false; - } - - auto keyIter = mDepthStencilStateCache.find(glState); + auto keyIter = mDepthStencilStateCache.Get(glState); if (keyIter != mDepthStencilStateCache.end()) { - DepthStencilStateCounterPair &state = keyIter->second; - state.second = mCounter++; - *outDSState = state.first; - return gl::Error(GL_NO_ERROR); + *outDSState = &keyIter->second; + return gl::NoError(); } - if (mDepthStencilStateCache.size() >= kMaxDepthStencilStates) - { - TRACE( - "Overflowed the limit of %u depth stencil states, removing the least recently used " - "to make room.", - kMaxDepthStencilStates); - - auto leastRecentlyUsed = mDepthStencilStateCache.begin(); - for (auto i = mDepthStencilStateCache.begin(); i != mDepthStencilStateCache.end(); i++) - { - if (i->second.second < leastRecentlyUsed->second.second) - { - leastRecentlyUsed = i; - } - } - SafeRelease(leastRecentlyUsed->second.first); - mDepthStencilStateCache.erase(leastRecentlyUsed); - } + TrimCache(kMaxStates, kGCLimit, "depth stencil state", &mDepthStencilStateCache); D3D11_DEPTH_STENCIL_DESC dsDesc = {0}; dsDesc.DepthEnable = glState.depthTest ? TRUE : FALSE; @@ -366,107 +208,66 @@ gl::Error RenderStateCache::getDepthStencilState(const gl::DepthStencilState &or dsDesc.BackFace.StencilPassOp = ConvertStencilOp(glState.stencilBackPassDepthPass); dsDesc.BackFace.StencilFunc = ConvertComparison(glState.stencilBackFunc); - ID3D11DepthStencilState *dx11DepthStencilState = NULL; - HRESULT result = mDevice->CreateDepthStencilState(&dsDesc, &dx11DepthStencilState); - if (FAILED(result) || !dx11DepthStencilState) - { - return gl::Error(GL_OUT_OF_MEMORY, - "Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result); - } + d3d11::DepthStencilState dx11DepthStencilState; + ANGLE_TRY(renderer->allocateResource(dsDesc, &dx11DepthStencilState)); + const auto &iter = mDepthStencilStateCache.Put(glState, std::move(dx11DepthStencilState)); - mDepthStencilStateCache.insert( - std::make_pair(glState, std::make_pair(dx11DepthStencilState, mCounter++))); + *outDSState = &iter->second; - *outDSState = dx11DepthStencilState; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -std::size_t RenderStateCache::hashSamplerState(const gl::SamplerState &samplerState) +gl::Error RenderStateCache::getSamplerState(Renderer11 *renderer, + const gl::SamplerState &samplerState, + ID3D11SamplerState **outSamplerState) { - static const unsigned int seed = 0xABCDEF98; - - std::size_t hash = 0; - MurmurHash3_x86_32(&samplerState, sizeof(gl::SamplerState), seed, &hash); - return hash; -} - -bool RenderStateCache::compareSamplerStates(const gl::SamplerState &a, const gl::SamplerState &b) -{ - return memcmp(&a, &b, sizeof(gl::SamplerState)) == 0; -} - -gl::Error RenderStateCache::getSamplerState(const gl::SamplerState &samplerState, ID3D11SamplerState **outSamplerState) -{ - if (!mDevice) - { - return gl::Error(GL_OUT_OF_MEMORY, "Internal error, RenderStateCache is not initialized."); - } - - SamplerStateMap::iterator keyIter = mSamplerStateCache.find(samplerState); + auto keyIter = mSamplerStateCache.Get(samplerState); if (keyIter != mSamplerStateCache.end()) { - SamplerStateCounterPair &state = keyIter->second; - state.second = mCounter++; - *outSamplerState = state.first; - return gl::Error(GL_NO_ERROR); + *outSamplerState = keyIter->second.get(); + return gl::NoError(); } - else + + TrimCache(kMaxStates, kGCLimit, "sampler state", &mSamplerStateCache); + + const auto &featureLevel = renderer->getRenderer11DeviceCaps().featureLevel; + + D3D11_SAMPLER_DESC samplerDesc; + samplerDesc.Filter = + gl_d3d11::ConvertFilter(samplerState.minFilter, samplerState.magFilter, + samplerState.maxAnisotropy, samplerState.compareMode); + samplerDesc.AddressU = gl_d3d11::ConvertTextureWrap(samplerState.wrapS); + samplerDesc.AddressV = gl_d3d11::ConvertTextureWrap(samplerState.wrapT); + samplerDesc.AddressW = gl_d3d11::ConvertTextureWrap(samplerState.wrapR); + samplerDesc.MipLODBias = 0; + samplerDesc.MaxAnisotropy = + gl_d3d11::ConvertMaxAnisotropy(samplerState.maxAnisotropy, featureLevel); + samplerDesc.ComparisonFunc = gl_d3d11::ConvertComparison(samplerState.compareFunc); + samplerDesc.BorderColor[0] = 0.0f; + samplerDesc.BorderColor[1] = 0.0f; + samplerDesc.BorderColor[2] = 0.0f; + samplerDesc.BorderColor[3] = 0.0f; + samplerDesc.MinLOD = samplerState.minLod; + samplerDesc.MaxLOD = samplerState.maxLod; + + if (featureLevel <= D3D_FEATURE_LEVEL_9_3) { - if (mSamplerStateCache.size() >= kMaxSamplerStates) - { - TRACE("Overflowed the limit of %u sampler states, removing the least recently used " - "to make room.", kMaxSamplerStates); + // Check that maxLOD is nearly FLT_MAX (1000.0f is the default), since 9_3 doesn't support + // anything other than FLT_MAX. Note that Feature Level 9_* only supports GL ES 2.0, so the + // consumer of ANGLE can't modify the Max LOD themselves. + ASSERT(samplerState.maxLod >= 999.9f); - SamplerStateMap::iterator leastRecentlyUsed = mSamplerStateCache.begin(); - for (SamplerStateMap::iterator i = mSamplerStateCache.begin(); i != mSamplerStateCache.end(); i++) - { - if (i->second.second < leastRecentlyUsed->second.second) - { - leastRecentlyUsed = i; - } - } - SafeRelease(leastRecentlyUsed->second.first); - mSamplerStateCache.erase(leastRecentlyUsed); - } - - D3D11_SAMPLER_DESC samplerDesc; - samplerDesc.Filter = gl_d3d11::ConvertFilter(samplerState.minFilter, samplerState.magFilter, - samplerState.maxAnisotropy, samplerState.compareMode); - samplerDesc.AddressU = gl_d3d11::ConvertTextureWrap(samplerState.wrapS); - samplerDesc.AddressV = gl_d3d11::ConvertTextureWrap(samplerState.wrapT); - samplerDesc.AddressW = gl_d3d11::ConvertTextureWrap(samplerState.wrapR); - samplerDesc.MipLODBias = 0; - samplerDesc.MaxAnisotropy = static_cast(samplerState.maxAnisotropy); - samplerDesc.ComparisonFunc = gl_d3d11::ConvertComparison(samplerState.compareFunc); - samplerDesc.BorderColor[0] = 0.0f; - samplerDesc.BorderColor[1] = 0.0f; - samplerDesc.BorderColor[2] = 0.0f; - samplerDesc.BorderColor[3] = 0.0f; - samplerDesc.MinLOD = samplerState.minLod; - samplerDesc.MaxLOD = samplerState.maxLod; - - if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) - { - // Check that maxLOD is nearly FLT_MAX (1000.0f is the default), since 9_3 doesn't support anything other than FLT_MAX. - // Note that Feature Level 9_* only supports GL ES 2.0, so the consumer of ANGLE can't modify the Max LOD themselves. - ASSERT(samplerState.maxLod >= 999.9f); - - // Now just set MaxLOD to FLT_MAX. Other parts of the renderer (e.g. the non-zero max LOD workaround) should take account of this. - samplerDesc.MaxLOD = FLT_MAX; - } - - ID3D11SamplerState *dx11SamplerState = NULL; - HRESULT result = mDevice->CreateSamplerState(&samplerDesc, &dx11SamplerState); - if (FAILED(result) || !dx11SamplerState) - { - return gl::Error(GL_OUT_OF_MEMORY, "Unable to create a ID3D11SamplerState, HRESULT: 0x%X.", result); - } - - mSamplerStateCache.insert(std::make_pair(samplerState, std::make_pair(dx11SamplerState, mCounter++))); - - *outSamplerState = dx11SamplerState; - return gl::Error(GL_NO_ERROR); + // Now just set MaxLOD to FLT_MAX. Other parts of the renderer (e.g. the non-zero max LOD + // workaround) should take account of this. + samplerDesc.MaxLOD = FLT_MAX; } + + d3d11::SamplerState dx11SamplerState; + ANGLE_TRY(renderer->allocateResource(samplerDesc, &dx11SamplerState)); + *outSamplerState = dx11SamplerState.get(); + mSamplerStateCache.Put(samplerState, std::move(dx11SamplerState)); + + return gl::NoError(); } -} +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.h index 82cb13903c..7501e83fc4 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.h @@ -10,9 +10,11 @@ #ifndef LIBANGLE_RENDERER_D3D_D3D11_RENDERSTATECACHE_H_ #define LIBANGLE_RENDERER_D3D_D3D11_RENDERSTATECACHE_H_ -#include "libANGLE/angletypes.h" -#include "libANGLE/Error.h" #include "common/angleutils.h" +#include "libANGLE/Error.h" +#include "libANGLE/SizedMRUCache.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #include @@ -21,6 +23,42 @@ namespace gl class Framebuffer; } +namespace std +{ +template <> +struct hash +{ + size_t operator()(const rx::d3d11::BlendStateKey &key) const + { + return angle::ComputeGenericHash(key); + } +}; + +template <> +struct hash +{ + size_t operator()(const rx::d3d11::RasterizerStateKey &key) const + { + return angle::ComputeGenericHash(key); + } +}; + +template <> +struct hash +{ + size_t operator()(const gl::DepthStencilState &key) const + { + return angle::ComputeGenericHash(key); + } +}; + +template <> +struct hash +{ + size_t operator()(const gl::SamplerState &key) const { return angle::ComputeGenericHash(key); } +}; +} // namespace std + namespace rx { class Renderer11; @@ -28,87 +66,58 @@ class Renderer11; class RenderStateCache : angle::NonCopyable { public: - RenderStateCache(Renderer11 *renderer); + RenderStateCache(); virtual ~RenderStateCache(); - void initialize(ID3D11Device *device); void clear(); - gl::Error getBlendState(const gl::Framebuffer *framebuffer, const gl::BlendState &blendState, ID3D11BlendState **outBlendState); - gl::Error getRasterizerState(const gl::RasterizerState &rasterState, bool scissorEnabled, ID3D11RasterizerState **outRasterizerState); - gl::Error getDepthStencilState(const gl::DepthStencilState &dsState, - bool disableDepth, - bool disableStencil, - ID3D11DepthStencilState **outDSState); - gl::Error getSamplerState(const gl::SamplerState &samplerState, ID3D11SamplerState **outSamplerState); + static d3d11::BlendStateKey GetBlendStateKey(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::BlendState &blendState); + gl::Error getBlendState(Renderer11 *renderer, + const d3d11::BlendStateKey &key, + const d3d11::BlendState **outBlendState); + gl::Error getRasterizerState(Renderer11 *renderer, + const gl::RasterizerState &rasterState, + bool scissorEnabled, + ID3D11RasterizerState **outRasterizerState); + gl::Error getDepthStencilState(Renderer11 *renderer, + const gl::DepthStencilState &dsState, + const d3d11::DepthStencilState **outDSState); + gl::Error getSamplerState(Renderer11 *renderer, + const gl::SamplerState &samplerState, + ID3D11SamplerState **outSamplerState); private: - Renderer11 *mRenderer; - unsigned long long mCounter; + // MSDN's documentation of ID3D11Device::CreateBlendState, ID3D11Device::CreateRasterizerState, + // ID3D11Device::CreateDepthStencilState and ID3D11Device::CreateSamplerState claims the maximum + // number of unique states of each type an application can create is 4096 + // TODO(ShahmeerEsmail): Revisit the cache sizes to make sure they are appropriate for most + // scenarios. + static constexpr unsigned int kMaxStates = 4096; + + // The cache tries to clean up this many states at once. + static constexpr unsigned int kGCLimit = 128; // Blend state cache - struct BlendStateKey - { - gl::BlendState blendState; - bool rtChannels[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT][4]; - }; - static std::size_t hashBlendState(const BlendStateKey &blendState); - static bool compareBlendStates(const BlendStateKey &a, const BlendStateKey &b); - static const unsigned int kMaxBlendStates; - - typedef std::size_t (*BlendStateHashFunction)(const BlendStateKey &); - typedef bool (*BlendStateEqualityFunction)(const BlendStateKey &, const BlendStateKey &); - typedef std::pair BlendStateCounterPair; - typedef std::unordered_map BlendStateMap; + using BlendStateMap = angle::base::HashingMRUCache; BlendStateMap mBlendStateCache; // Rasterizer state cache - struct RasterizerStateKey - { - gl::RasterizerState rasterizerState; - bool scissorEnabled; - }; - static std::size_t hashRasterizerState(const RasterizerStateKey &rasterState); - static bool compareRasterizerStates(const RasterizerStateKey &a, const RasterizerStateKey &b); - static const unsigned int kMaxRasterizerStates; - - typedef std::size_t (*RasterizerStateHashFunction)(const RasterizerStateKey &); - typedef bool (*RasterizerStateEqualityFunction)(const RasterizerStateKey &, const RasterizerStateKey &); - typedef std::pair RasterizerStateCounterPair; - typedef std::unordered_map RasterizerStateMap; + using RasterizerStateMap = + angle::base::HashingMRUCache; RasterizerStateMap mRasterizerStateCache; // Depth stencil state cache - static std::size_t hashDepthStencilState(const gl::DepthStencilState &dsState); - static bool compareDepthStencilStates(const gl::DepthStencilState &a, const gl::DepthStencilState &b); - static const unsigned int kMaxDepthStencilStates; - - typedef std::size_t (*DepthStencilStateHashFunction)(const gl::DepthStencilState &); - typedef bool (*DepthStencilStateEqualityFunction)(const gl::DepthStencilState &, const gl::DepthStencilState &); - typedef std::pair DepthStencilStateCounterPair; - typedef std::unordered_map DepthStencilStateMap; + using DepthStencilStateMap = + angle::base::HashingMRUCache; DepthStencilStateMap mDepthStencilStateCache; // Sample state cache - static std::size_t hashSamplerState(const gl::SamplerState &samplerState); - static bool compareSamplerStates(const gl::SamplerState &a, const gl::SamplerState &b); - static const unsigned int kMaxSamplerStates; - - typedef std::size_t (*SamplerStateHashFunction)(const gl::SamplerState &); - typedef bool (*SamplerStateEqualityFunction)(const gl::SamplerState &, const gl::SamplerState &); - typedef std::pair SamplerStateCounterPair; - typedef std::unordered_map SamplerStateMap; + using SamplerStateMap = angle::base::HashingMRUCache; SamplerStateMap mSamplerStateCache; - - ID3D11Device *mDevice; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_D3D11_RENDERSTATECACHE_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp index cdfcacc287..594a382a72 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp @@ -18,7 +18,9 @@ namespace rx { -static bool getTextureProperties(ID3D11Resource *resource, unsigned int *mipLevels, unsigned int *samples) +namespace +{ +bool GetTextureProperties(ID3D11Resource *resource, unsigned int *mipLevels, unsigned int *samples) { ID3D11Texture1D *texture1D = d3d11::DynamicCastComObject(resource); if (texture1D) @@ -62,7 +64,7 @@ static bool getTextureProperties(ID3D11Resource *resource, unsigned int *mipLeve return false; } -static unsigned int getRTVSubresourceIndex(ID3D11Resource *resource, ID3D11RenderTargetView *view) +unsigned int GetRTVSubresourceIndex(ID3D11Resource *resource, ID3D11RenderTargetView *view) { D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; view->GetDesc(&rtvDesc); @@ -72,58 +74,58 @@ static unsigned int getRTVSubresourceIndex(ID3D11Resource *resource, ID3D11Rende switch (rtvDesc.ViewDimension) { - case D3D11_RTV_DIMENSION_TEXTURE1D: - mipSlice = rtvDesc.Texture1D.MipSlice; - arraySlice = 0; - break; + case D3D11_RTV_DIMENSION_TEXTURE1D: + mipSlice = rtvDesc.Texture1D.MipSlice; + arraySlice = 0; + break; - case D3D11_RTV_DIMENSION_TEXTURE1DARRAY: - mipSlice = rtvDesc.Texture1DArray.MipSlice; - arraySlice = rtvDesc.Texture1DArray.FirstArraySlice; - break; + case D3D11_RTV_DIMENSION_TEXTURE1DARRAY: + mipSlice = rtvDesc.Texture1DArray.MipSlice; + arraySlice = rtvDesc.Texture1DArray.FirstArraySlice; + break; - case D3D11_RTV_DIMENSION_TEXTURE2D: - mipSlice = rtvDesc.Texture2D.MipSlice; - arraySlice = 0; - break; + case D3D11_RTV_DIMENSION_TEXTURE2D: + mipSlice = rtvDesc.Texture2D.MipSlice; + arraySlice = 0; + break; - case D3D11_RTV_DIMENSION_TEXTURE2DARRAY: - mipSlice = rtvDesc.Texture2DArray.MipSlice; - arraySlice = rtvDesc.Texture2DArray.FirstArraySlice; - break; + case D3D11_RTV_DIMENSION_TEXTURE2DARRAY: + mipSlice = rtvDesc.Texture2DArray.MipSlice; + arraySlice = rtvDesc.Texture2DArray.FirstArraySlice; + break; - case D3D11_RTV_DIMENSION_TEXTURE2DMS: - mipSlice = 0; - arraySlice = 0; - break; + case D3D11_RTV_DIMENSION_TEXTURE2DMS: + mipSlice = 0; + arraySlice = 0; + break; - case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY: - mipSlice = 0; - arraySlice = rtvDesc.Texture2DMSArray.FirstArraySlice; - break; + case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY: + mipSlice = 0; + arraySlice = rtvDesc.Texture2DMSArray.FirstArraySlice; + break; - case D3D11_RTV_DIMENSION_TEXTURE3D: - mipSlice = rtvDesc.Texture3D.MipSlice; - arraySlice = 0; - break; + case D3D11_RTV_DIMENSION_TEXTURE3D: + mipSlice = rtvDesc.Texture3D.MipSlice; + arraySlice = 0; + break; - case D3D11_RTV_DIMENSION_UNKNOWN: - case D3D11_RTV_DIMENSION_BUFFER: - UNIMPLEMENTED(); - break; + case D3D11_RTV_DIMENSION_UNKNOWN: + case D3D11_RTV_DIMENSION_BUFFER: + UNIMPLEMENTED(); + break; - default: - UNREACHABLE(); - break; + default: + UNREACHABLE(); + break; } unsigned int mipLevels, samples; - getTextureProperties(resource, &mipLevels, &samples); + GetTextureProperties(resource, &mipLevels, &samples); return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels); } -static unsigned int getDSVSubresourceIndex(ID3D11Resource *resource, ID3D11DepthStencilView *view) +unsigned int GetDSVSubresourceIndex(ID3D11Resource *resource, ID3D11DepthStencilView *view) { D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; view->GetDesc(&dsvDesc); @@ -133,157 +135,170 @@ static unsigned int getDSVSubresourceIndex(ID3D11Resource *resource, ID3D11Depth switch (dsvDesc.ViewDimension) { - case D3D11_DSV_DIMENSION_TEXTURE1D: - mipSlice = dsvDesc.Texture1D.MipSlice; - arraySlice = 0; - break; + case D3D11_DSV_DIMENSION_TEXTURE1D: + mipSlice = dsvDesc.Texture1D.MipSlice; + arraySlice = 0; + break; - case D3D11_DSV_DIMENSION_TEXTURE1DARRAY: - mipSlice = dsvDesc.Texture1DArray.MipSlice; - arraySlice = dsvDesc.Texture1DArray.FirstArraySlice; - break; + case D3D11_DSV_DIMENSION_TEXTURE1DARRAY: + mipSlice = dsvDesc.Texture1DArray.MipSlice; + arraySlice = dsvDesc.Texture1DArray.FirstArraySlice; + break; - case D3D11_DSV_DIMENSION_TEXTURE2D: - mipSlice = dsvDesc.Texture2D.MipSlice; - arraySlice = 0; - break; + case D3D11_DSV_DIMENSION_TEXTURE2D: + mipSlice = dsvDesc.Texture2D.MipSlice; + arraySlice = 0; + break; - case D3D11_DSV_DIMENSION_TEXTURE2DARRAY: - mipSlice = dsvDesc.Texture2DArray.MipSlice; - arraySlice = dsvDesc.Texture2DArray.FirstArraySlice; - break; + case D3D11_DSV_DIMENSION_TEXTURE2DARRAY: + mipSlice = dsvDesc.Texture2DArray.MipSlice; + arraySlice = dsvDesc.Texture2DArray.FirstArraySlice; + break; - case D3D11_DSV_DIMENSION_TEXTURE2DMS: - mipSlice = 0; - arraySlice = 0; - break; + case D3D11_DSV_DIMENSION_TEXTURE2DMS: + mipSlice = 0; + arraySlice = 0; + break; - case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY: - mipSlice = 0; - arraySlice = dsvDesc.Texture2DMSArray.FirstArraySlice; - break; + case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY: + mipSlice = 0; + arraySlice = dsvDesc.Texture2DMSArray.FirstArraySlice; + break; - case D3D11_DSV_DIMENSION_UNKNOWN: - UNIMPLEMENTED(); - break; + case D3D11_DSV_DIMENSION_UNKNOWN: + UNIMPLEMENTED(); + break; - default: - UNREACHABLE(); - break; + default: + UNREACHABLE(); + break; } unsigned int mipLevels, samples; - getTextureProperties(resource, &mipLevels, &samples); + GetTextureProperties(resource, &mipLevels, &samples); return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels); } -TextureRenderTarget11::TextureRenderTarget11(ID3D11RenderTargetView *rtv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, - GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples) - : mWidth(width), - mHeight(height), - mDepth(depth), - mInternalFormat(internalFormat), - mDXGIFormat(DXGI_FORMAT_UNKNOWN), - mSamples(samples), - mSubresourceIndex(0), - mTexture(resource), - mRenderTarget(rtv), - mDepthStencil(NULL), - mShaderResource(srv) +GLenum GetSurfaceRTFormat(bool depth, SwapChain11 *swapChain) { - if (mTexture) - { - mTexture->AddRef(); - } - - if (mRenderTarget) - { - mRenderTarget->AddRef(); - } - - if (mShaderResource) - { - mShaderResource->AddRef(); - } - - if (mRenderTarget && mTexture) - { - mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget); - - D3D11_RENDER_TARGET_VIEW_DESC desc; - mRenderTarget->GetDesc(&desc); - mDXGIFormat = desc.Format; - } + return (depth ? swapChain->getDepthBufferInternalFormat() + : swapChain->getRenderTargetInternalFormat()); } -TextureRenderTarget11::TextureRenderTarget11(ID3D11DepthStencilView *dsv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, - GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples) - : mWidth(width), +const d3d11::Format &GetSurfaceFormatSet(bool depth, SwapChain11 *swapChain, Renderer11 *renderer) +{ + return d3d11::Format::Get(GetSurfaceRTFormat(depth, swapChain), + renderer->getRenderer11DeviceCaps()); +} + +} // anonymous namespace + +RenderTarget11::RenderTarget11(const d3d11::Format &formatSet) : mFormatSet(formatSet) +{ +} + +RenderTarget11::~RenderTarget11() +{ + ASSERT(mBroadcastChannel.empty()); +} + +void RenderTarget11::signalDirty(const gl::Context *context) +{ + mBroadcastChannel.signal(context); + + // Clear the list. We can't do this in the receiver because it would mutate during iteration. + mBroadcastChannel.reset(); +} + +TextureRenderTarget11::TextureRenderTarget11(d3d11::RenderTargetView &&rtv, + const TextureHelper11 &resource, + const d3d11::SharedSRV &srv, + const d3d11::SharedSRV &blitSRV, + GLenum internalFormat, + const d3d11::Format &formatSet, + GLsizei width, + GLsizei height, + GLsizei depth, + GLsizei samples) + : RenderTarget11(formatSet), + mWidth(width), mHeight(height), mDepth(depth), mInternalFormat(internalFormat), - mDXGIFormat(DXGI_FORMAT_UNKNOWN), mSamples(samples), mSubresourceIndex(0), mTexture(resource), - mRenderTarget(NULL), - mDepthStencil(dsv), - mShaderResource(srv) + mRenderTarget(std::move(rtv)), + mDepthStencil(), + mShaderResource(srv.makeCopy()), + mBlitShaderResource(blitSRV.makeCopy()) { - if (mTexture) + if (mRenderTarget.valid() && mTexture.valid()) { - mTexture->AddRef(); + mSubresourceIndex = GetRTVSubresourceIndex(mTexture.get(), mRenderTarget.get()); } + ASSERT(mFormatSet.formatID != angle::Format::ID::NONE || mWidth == 0 || mHeight == 0); +} - if (mDepthStencil) +TextureRenderTarget11::TextureRenderTarget11(d3d11::DepthStencilView &&dsv, + const TextureHelper11 &resource, + const d3d11::SharedSRV &srv, + GLenum internalFormat, + const d3d11::Format &formatSet, + GLsizei width, + GLsizei height, + GLsizei depth, + GLsizei samples) + : RenderTarget11(formatSet), + mWidth(width), + mHeight(height), + mDepth(depth), + mInternalFormat(internalFormat), + mSamples(samples), + mSubresourceIndex(0), + mTexture(resource), + mRenderTarget(), + mDepthStencil(std::move(dsv)), + mShaderResource(srv.makeCopy()), + mBlitShaderResource() +{ + if (mDepthStencil.valid() && mTexture.valid()) { - mDepthStencil->AddRef(); - } - - if (mShaderResource) - { - mShaderResource->AddRef(); - } - - if (mDepthStencil && mTexture) - { - mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil); - - D3D11_DEPTH_STENCIL_VIEW_DESC desc; - mDepthStencil->GetDesc(&desc); - mDXGIFormat = desc.Format; + mSubresourceIndex = GetDSVSubresourceIndex(mTexture.get(), mDepthStencil.get()); } + ASSERT(mFormatSet.formatID != angle::Format::ID::NONE || mWidth == 0 || mHeight == 0); } TextureRenderTarget11::~TextureRenderTarget11() { - SafeRelease(mTexture); - SafeRelease(mRenderTarget); - SafeRelease(mDepthStencil); - SafeRelease(mShaderResource); } -ID3D11Resource *TextureRenderTarget11::getTexture() const +const TextureHelper11 &TextureRenderTarget11::getTexture() const { return mTexture; } -ID3D11RenderTargetView *TextureRenderTarget11::getRenderTargetView() const +const d3d11::RenderTargetView &TextureRenderTarget11::getRenderTargetView() const { return mRenderTarget; } -ID3D11DepthStencilView *TextureRenderTarget11::getDepthStencilView() const +const d3d11::DepthStencilView &TextureRenderTarget11::getDepthStencilView() const { return mDepthStencil; } -ID3D11ShaderResourceView *TextureRenderTarget11::getShaderResourceView() const +const d3d11::SharedSRV &TextureRenderTarget11::getShaderResourceView() const { return mShaderResource; } +const d3d11::SharedSRV &TextureRenderTarget11::getBlitShaderResourceView() const +{ + return mBlitShaderResource; +} + GLsizei TextureRenderTarget11::getWidth() const { return mWidth; @@ -314,14 +329,11 @@ unsigned int TextureRenderTarget11::getSubresourceIndex() const return mSubresourceIndex; } -DXGI_FORMAT TextureRenderTarget11::getDXGIFormat() const -{ - return mDXGIFormat; -} - -SurfaceRenderTarget11::SurfaceRenderTarget11(SwapChain11 *swapChain, Renderer11 *renderer, bool depth) - : mSwapChain(swapChain), - mRenderer(renderer), +SurfaceRenderTarget11::SurfaceRenderTarget11(SwapChain11 *swapChain, + Renderer11 *renderer, + bool depth) + : RenderTarget11(GetSurfaceFormatSet(depth, swapChain, renderer)), + mSwapChain(swapChain), mDepth(depth) { ASSERT(mSwapChain); @@ -348,33 +360,41 @@ GLsizei SurfaceRenderTarget11::getDepth() const GLenum SurfaceRenderTarget11::getInternalFormat() const { - return (mDepth ? mSwapChain->GetDepthBufferInternalFormat() : mSwapChain->GetRenderTargetInternalFormat()); + return GetSurfaceRTFormat(mDepth, mSwapChain); } GLsizei SurfaceRenderTarget11::getSamples() const { - // Our EGL surfaces do not support multisampling. - return 0; + return mSwapChain->getSamples(); } -ID3D11Resource *SurfaceRenderTarget11::getTexture() const +const TextureHelper11 &SurfaceRenderTarget11::getTexture() const { return (mDepth ? mSwapChain->getDepthStencilTexture() : mSwapChain->getOffscreenTexture()); } -ID3D11RenderTargetView *SurfaceRenderTarget11::getRenderTargetView() const +const d3d11::RenderTargetView &SurfaceRenderTarget11::getRenderTargetView() const { - return (mDepth ? NULL : mSwapChain->getRenderTarget()); + ASSERT(!mDepth); + return mSwapChain->getRenderTarget(); } -ID3D11DepthStencilView *SurfaceRenderTarget11::getDepthStencilView() const +const d3d11::DepthStencilView &SurfaceRenderTarget11::getDepthStencilView() const { - return (mDepth ? mSwapChain->getDepthStencil() : NULL); + ASSERT(mDepth); + return mSwapChain->getDepthStencil(); } -ID3D11ShaderResourceView *SurfaceRenderTarget11::getShaderResourceView() const +const d3d11::SharedSRV &SurfaceRenderTarget11::getShaderResourceView() const { - return (mDepth ? mSwapChain->getDepthStencilShaderResource() : mSwapChain->getRenderTargetShaderResource()); + return (mDepth ? mSwapChain->getDepthStencilShaderResource() + : mSwapChain->getRenderTargetShaderResource()); +} + +const d3d11::SharedSRV &SurfaceRenderTarget11::getBlitShaderResourceView() const +{ + // The SurfaceRenderTargetView format should always be such that the normal SRV works for blits. + return getShaderResourceView(); } unsigned int SurfaceRenderTarget11::getSubresourceIndex() const @@ -382,9 +402,4 @@ unsigned int SurfaceRenderTarget11::getSubresourceIndex() const return 0; } -DXGI_FORMAT SurfaceRenderTarget11::getDXGIFormat() const -{ - return d3d11::GetTextureFormatInfo(getInternalFormat(), mRenderer->getRenderer11DeviceCaps()).texFormat; -} - -} +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h index d47b237c09..db49cac9f5 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h @@ -11,6 +11,9 @@ #define LIBANGLE_RENDERER_D3D_D3D11_RENDERTARGET11_H_ #include "libANGLE/renderer/d3d/RenderTargetD3D.h" +#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" namespace rx { @@ -20,28 +23,51 @@ class Renderer11; class RenderTarget11 : public RenderTargetD3D { public: - RenderTarget11() { } - virtual ~RenderTarget11() { } + RenderTarget11(const d3d11::Format &formatSet); + ~RenderTarget11() override; - virtual ID3D11Resource *getTexture() const = 0; - virtual ID3D11RenderTargetView *getRenderTargetView() const = 0; - virtual ID3D11DepthStencilView *getDepthStencilView() const = 0; - virtual ID3D11ShaderResourceView *getShaderResourceView() const = 0; + virtual const TextureHelper11 &getTexture() const = 0; + virtual const d3d11::RenderTargetView &getRenderTargetView() const = 0; + virtual const d3d11::DepthStencilView &getDepthStencilView() const = 0; + virtual const d3d11::SharedSRV &getShaderResourceView() const = 0; + virtual const d3d11::SharedSRV &getBlitShaderResourceView() const = 0; virtual unsigned int getSubresourceIndex() const = 0; - virtual DXGI_FORMAT getDXGIFormat() const = 0; + void signalDirty(const gl::Context *context) override; + OnRenderTargetDirtyChannel *getBroadcastChannel() { return &mBroadcastChannel; } + + const d3d11::Format &getFormatSet() const { return mFormatSet; } + + protected: + OnRenderTargetDirtyChannel mBroadcastChannel; + const d3d11::Format &mFormatSet; }; class TextureRenderTarget11 : public RenderTarget11 { public: // TextureRenderTarget11 takes ownership of any D3D11 resources it is given and will AddRef them - TextureRenderTarget11(ID3D11RenderTargetView *rtv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, - GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples); - TextureRenderTarget11(ID3D11DepthStencilView *dsv, ID3D11Resource *resource, ID3D11ShaderResourceView *srv, - GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei samples); - virtual ~TextureRenderTarget11(); + TextureRenderTarget11(d3d11::RenderTargetView &&rtv, + const TextureHelper11 &resource, + const d3d11::SharedSRV &srv, + const d3d11::SharedSRV &blitSRV, + GLenum internalFormat, + const d3d11::Format &formatSet, + GLsizei width, + GLsizei height, + GLsizei depth, + GLsizei samples); + TextureRenderTarget11(d3d11::DepthStencilView &&dsv, + const TextureHelper11 &resource, + const d3d11::SharedSRV &srv, + GLenum internalFormat, + const d3d11::Format &formatSet, + GLsizei width, + GLsizei height, + GLsizei depth, + GLsizei samples); + ~TextureRenderTarget11() override; GLsizei getWidth() const override; GLsizei getHeight() const override; @@ -49,35 +75,37 @@ class TextureRenderTarget11 : public RenderTarget11 GLenum getInternalFormat() const override; GLsizei getSamples() const override; - ID3D11Resource *getTexture() const override; - ID3D11RenderTargetView *getRenderTargetView() const override; - ID3D11DepthStencilView *getDepthStencilView() const override; - ID3D11ShaderResourceView *getShaderResourceView() const override; + const TextureHelper11 &getTexture() const override; + const d3d11::RenderTargetView &getRenderTargetView() const override; + const d3d11::DepthStencilView &getDepthStencilView() const override; + const d3d11::SharedSRV &getShaderResourceView() const override; + const d3d11::SharedSRV &getBlitShaderResourceView() const override; unsigned int getSubresourceIndex() const override; - DXGI_FORMAT getDXGIFormat() const override; - private: GLsizei mWidth; GLsizei mHeight; GLsizei mDepth; GLenum mInternalFormat; - DXGI_FORMAT mDXGIFormat; GLsizei mSamples; unsigned int mSubresourceIndex; - ID3D11Resource *mTexture; - ID3D11RenderTargetView *mRenderTarget; - ID3D11DepthStencilView *mDepthStencil; - ID3D11ShaderResourceView *mShaderResource; + TextureHelper11 mTexture; + d3d11::RenderTargetView mRenderTarget; + d3d11::DepthStencilView mDepthStencil; + d3d11::SharedSRV mShaderResource; + + // Shader resource view to use with internal blit shaders. Not set for depth/stencil render + // targets. + d3d11::SharedSRV mBlitShaderResource; }; class SurfaceRenderTarget11 : public RenderTarget11 { public: SurfaceRenderTarget11(SwapChain11 *swapChain, Renderer11 *renderer, bool depth); - virtual ~SurfaceRenderTarget11(); + ~SurfaceRenderTarget11() override; GLsizei getWidth() const override; GLsizei getHeight() const override; @@ -85,21 +113,19 @@ class SurfaceRenderTarget11 : public RenderTarget11 GLenum getInternalFormat() const override; GLsizei getSamples() const override; - ID3D11Resource *getTexture() const override; - ID3D11RenderTargetView *getRenderTargetView() const override; - ID3D11DepthStencilView *getDepthStencilView() const override; - ID3D11ShaderResourceView *getShaderResourceView() const override; + const TextureHelper11 &getTexture() const override; + const d3d11::RenderTargetView &getRenderTargetView() const override; + const d3d11::DepthStencilView &getDepthStencilView() const override; + const d3d11::SharedSRV &getShaderResourceView() const override; + const d3d11::SharedSRV &getBlitShaderResourceView() const override; unsigned int getSubresourceIndex() const override; - DXGI_FORMAT getDXGIFormat() const override; - private: SwapChain11 *mSwapChain; - Renderer11 *mRenderer; bool mDepth; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_D3D11_RENDERTARGET11_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp index 5118bdbe9c..b0ef9abddc 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp @@ -9,43 +9,24 @@ #include "libANGLE/renderer/d3d/d3d11/Renderer11.h" #include +#include #include -#if !defined(ANGLE_MINGW32_COMPAT) && WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP -#include -#endif #include "common/tls.h" #include "common/utilities.h" #include "libANGLE/Buffer.h" +#include "libANGLE/Context.h" #include "libANGLE/Display.h" -#include "libANGLE/formatutils.h" #include "libANGLE/Framebuffer.h" #include "libANGLE/FramebufferAttachment.h" -#include "libANGLE/histogram_macros.h" #include "libANGLE/Program.h" -#include "libANGLE/renderer/d3d/CompilerD3D.h" -#include "libANGLE/renderer/d3d/d3d11/Blit11.h" -#include "libANGLE/renderer/d3d/d3d11/Buffer11.h" -#include "libANGLE/renderer/d3d/d3d11/Clear11.h" -#include "libANGLE/renderer/d3d/d3d11/dxgi_support_table.h" -#include "libANGLE/renderer/d3d/d3d11/Fence11.h" -#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" -#include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h" -#include "libANGLE/renderer/d3d/d3d11/Image11.h" -#include "libANGLE/renderer/d3d/d3d11/IndexBuffer11.h" -#include "libANGLE/renderer/d3d/d3d11/PixelTransfer11.h" -#include "libANGLE/renderer/d3d/d3d11/Query11.h" -#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" -#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" -#include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h" -#include "libANGLE/renderer/d3d/d3d11/SwapChain11.h" -#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" -#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h" -#include "libANGLE/renderer/d3d/d3d11/Trim11.h" -#include "libANGLE/renderer/d3d/d3d11/VertexArray11.h" -#include "libANGLE/renderer/d3d/d3d11/VertexBuffer11.h" +#include "libANGLE/State.h" +#include "libANGLE/Surface.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/histogram_macros.h" #include "libANGLE/renderer/d3d/CompilerD3D.h" #include "libANGLE/renderer/d3d/DeviceD3D.h" +#include "libANGLE/renderer/d3d/DisplayD3D.h" #include "libANGLE/renderer/d3d/FramebufferD3D.h" #include "libANGLE/renderer/d3d/IndexDataManager.h" #include "libANGLE/renderer/d3d/ProgramD3D.h" @@ -53,12 +34,39 @@ #include "libANGLE/renderer/d3d/ShaderD3D.h" #include "libANGLE/renderer/d3d/SurfaceD3D.h" #include "libANGLE/renderer/d3d/TextureD3D.h" -#include "libANGLE/renderer/d3d/TransformFeedbackD3D.h" #include "libANGLE/renderer/d3d/VertexDataManager.h" -#include "libANGLE/State.h" -#include "libANGLE/Surface.h" +#include "libANGLE/renderer/d3d/d3d11/Blit11.h" +#include "libANGLE/renderer/d3d/d3d11/Buffer11.h" +#include "libANGLE/renderer/d3d/d3d11/Clear11.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" +#include "libANGLE/renderer/d3d/d3d11/Fence11.h" +#include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h" +#include "libANGLE/renderer/d3d/d3d11/Image11.h" +#include "libANGLE/renderer/d3d/d3d11/IndexBuffer11.h" +#include "libANGLE/renderer/d3d/d3d11/PixelTransfer11.h" +#include "libANGLE/renderer/d3d/d3d11/Query11.h" +#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" +#include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h" +#include "libANGLE/renderer/d3d/d3d11/StreamProducerNV12.h" +#include "libANGLE/renderer/d3d/d3d11/SwapChain11.h" +#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h" +#include "libANGLE/renderer/d3d/d3d11/TransformFeedback11.h" +#include "libANGLE/renderer/d3d/d3d11/Trim11.h" +#include "libANGLE/renderer/d3d/d3d11/VertexArray11.h" +#include "libANGLE/renderer/d3d/d3d11/VertexBuffer11.h" +#include "libANGLE/renderer/d3d/d3d11/dxgi_support_table.h" +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" +#include "libANGLE/renderer/renderer_utils.h" #include "third_party/trace_event/trace_event.h" +#ifdef ANGLE_ENABLE_WINDOWS_STORE +#include "libANGLE/renderer/d3d/d3d11/winrt/NativeWindow11WinRT.h" +#else +#include "libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.h" +#endif + // Include the D3D9 debug annotator header for use by the desktop D3D11 renderer // because the D3D11 interface method ID3DUserDefinedAnnotation::GetStatus // doesn't work with the Graphics Diagnostics tools in Visual Studio 2013. @@ -72,12 +80,6 @@ #define ANGLE_SKIP_DXGI_1_2_CHECK 0 #endif -#ifdef _DEBUG -// this flag enables suppressing some spurious warnings that pop up in certain WebGL samples -// and conformance tests. to enable all warnings, remove this define. -#define ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS 1 -#endif - namespace rx { @@ -89,25 +91,6 @@ enum MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 = 16 }; -#if defined(ANGLE_ENABLE_D3D11_1) -void CalculateConstantBufferParams(GLintptr offset, GLsizeiptr size, UINT *outFirstConstant, UINT *outNumConstants) -{ - // The offset must be aligned to 256 bytes (should have been enforced by glBindBufferRange). - ASSERT(offset % 256 == 0); - - // firstConstant and numConstants are expressed in constants of 16-bytes. Furthermore they must be a multiple of 16 constants. - *outFirstConstant = static_cast(offset / 16); - - // The GL size is not required to be aligned to a 256 bytes boundary. - // Round the size up to a 256 bytes boundary then express the results in constants of 16-bytes. - *outNumConstants = static_cast(rx::roundUp(size, static_cast(256)) / 16); - - // Since the size is rounded up, firstConstant + numConstants may be bigger than the actual size of the buffer. - // This behaviour is explictly allowed according to the documentation on ID3D11DeviceContext1::PSSetConstantBuffers1 - // https://msdn.microsoft.com/en-us/library/windows/desktop/hh404649%28v=vs.85%29.aspx -} -#endif - enum ANGLEFeatureLevel { ANGLE_FEATURE_LEVEL_INVALID, @@ -123,14 +106,18 @@ ANGLEFeatureLevel GetANGLEFeatureLevel(D3D_FEATURE_LEVEL d3dFeatureLevel) { switch (d3dFeatureLevel) { - case D3D_FEATURE_LEVEL_9_3: return ANGLE_FEATURE_LEVEL_9_3; - case D3D_FEATURE_LEVEL_10_0: return ANGLE_FEATURE_LEVEL_10_0; - case D3D_FEATURE_LEVEL_10_1: return ANGLE_FEATURE_LEVEL_10_1; - case D3D_FEATURE_LEVEL_11_0: return ANGLE_FEATURE_LEVEL_11_0; - // Note: we don't ever request a 11_1 device, because this gives - // an E_INVALIDARG error on systems that don't have the platform update. - case D3D_FEATURE_LEVEL_11_1: return ANGLE_FEATURE_LEVEL_11_1; - default: return ANGLE_FEATURE_LEVEL_INVALID; + case D3D_FEATURE_LEVEL_9_3: + return ANGLE_FEATURE_LEVEL_9_3; + case D3D_FEATURE_LEVEL_10_0: + return ANGLE_FEATURE_LEVEL_10_0; + case D3D_FEATURE_LEVEL_10_1: + return ANGLE_FEATURE_LEVEL_10_1; + case D3D_FEATURE_LEVEL_11_0: + return ANGLE_FEATURE_LEVEL_11_0; + case D3D_FEATURE_LEVEL_11_1: + return ANGLE_FEATURE_LEVEL_11_1; + default: + return ANGLE_FEATURE_LEVEL_INVALID; } } @@ -144,7 +131,7 @@ void SetLineLoopIndices(GLuint *dest, size_t count) } template -void CopyLineLoopIndices(const GLvoid *indices, GLuint *dest, size_t count) +void CopyLineLoopIndices(const void *indices, GLuint *dest, size_t count) { const T *srcPtr = static_cast(indices); for (size_t i = 0; i < count; ++i) @@ -165,7 +152,7 @@ void SetTriangleFanIndices(GLuint *destPtr, size_t numTris) } template -void CopyLineLoopIndicesWithRestart(const GLvoid *indices, +void CopyLineLoopIndicesWithRestart(const void *indices, size_t count, GLenum indexType, std::vector *bufferOut) @@ -206,7 +193,7 @@ void CopyLineLoopIndicesWithRestart(const GLvoid *indices, } } -void GetLineLoopIndices(const GLvoid *indices, +void GetLineLoopIndices(const void *indices, GLenum indexType, GLuint count, bool usePrimitiveRestartFixedIndex, @@ -257,7 +244,7 @@ void GetLineLoopIndices(const GLvoid *indices, } template -void CopyTriangleFanIndices(const GLvoid *indices, GLuint *destPtr, size_t numTris) +void CopyTriangleFanIndices(const void *indices, GLuint *destPtr, size_t numTris) { const T *srcPtr = static_cast(indices); @@ -270,7 +257,7 @@ void CopyTriangleFanIndices(const GLvoid *indices, GLuint *destPtr, size_t numTr } template -void CopyTriangleFanIndicesWithRestart(const GLvoid *indices, +void CopyTriangleFanIndicesWithRestart(const void *indices, GLuint indexCount, GLenum indexType, std::vector *bufferOut) @@ -314,7 +301,7 @@ void CopyTriangleFanIndicesWithRestart(const GLvoid *indices, } } -void GetTriFanIndices(const GLvoid *indices, +void GetTriFanIndices(const void *indices, GLenum indexType, GLuint count, bool usePrimitiveRestartFixedIndex, @@ -365,60 +352,135 @@ void GetTriFanIndices(const GLvoid *indices, } } +bool DrawCallNeedsTranslation(const gl::Context *context, GLenum mode) +{ + const auto &glState = context->getGLState(); + const gl::VertexArray *vertexArray = glState.getVertexArray(); + VertexArray11 *vertexArray11 = GetImplAs(vertexArray); + // Direct drawing doesn't support dynamic attribute storage since it needs the first and count + // to translate when applyVertexBuffer. GL_LINE_LOOP and GL_TRIANGLE_FAN are not supported + // either since we need to simulate them in D3D. + if (vertexArray11->hasActiveDynamicAttrib(context) || mode == GL_LINE_LOOP || + mode == GL_TRIANGLE_FAN) + { + return true; + } + + ProgramD3D *programD3D = GetImplAs(glState.getProgram()); + if (InstancedPointSpritesActive(programD3D, mode)) + { + return true; + } + + return false; +} + +bool IsArrayRTV(ID3D11RenderTargetView *rtv) +{ + D3D11_RENDER_TARGET_VIEW_DESC desc; + rtv->GetDesc(&desc); + if (desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE1DARRAY && + desc.Texture1DArray.ArraySize > 1) + return true; + if (desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2DARRAY && + desc.Texture2DArray.ArraySize > 1) + return true; + if (desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY && + desc.Texture2DMSArray.ArraySize > 1) + return true; + return false; +} + +int GetAdjustedInstanceCount(const gl::Program *program, int instanceCount) +{ + if (!program->usesMultiview()) + { + return instanceCount; + } + if (instanceCount == 0) + { + return program->getNumViews(); + } + return program->getNumViews() * instanceCount; +} + +const uint32_t ScratchMemoryBufferLifetime = 1000; + +void PopulateFormatDeviceCaps(ID3D11Device *device, + DXGI_FORMAT format, + UINT *outSupport, + UINT *outMaxSamples) +{ + if (FAILED(device->CheckFormatSupport(format, outSupport))) + { + *outSupport = 0; + } + + *outMaxSamples = 0; + for (UINT sampleCount = 2; sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; sampleCount *= 2) + { + UINT qualityCount = 0; + if (FAILED(device->CheckMultisampleQualityLevels(format, sampleCount, &qualityCount)) || + qualityCount == 0) + { + break; + } + + *outMaxSamples = sampleCount; + } +} + +bool CullsEverything(const gl::State &glState) +{ + return (glState.getRasterizerState().cullFace && + glState.getRasterizerState().cullMode == gl::CullFaceMode::FrontAndBack); +} + } // anonymous namespace +Renderer11DeviceCaps::Renderer11DeviceCaps() = default; + Renderer11::Renderer11(egl::Display *display) : RendererD3D(display), - mStateCache(this), + mCreateDebugDevice(false), + mStateCache(), mStateManager(this), - mLastHistogramUpdateTime(ANGLEPlatformCurrent()->monotonicallyIncreasingTime()) -#if !defined(ANGLE_MINGW32_COMPAT) - ,mDebug(nullptr) -#endif + mLastHistogramUpdateTime( + ANGLEPlatformCurrent()->monotonicallyIncreasingTime(ANGLEPlatformCurrent())), + mDebug(nullptr), + mScratchMemoryBuffer(ScratchMemoryBufferLifetime), + mAnnotator(nullptr) { - mVertexDataManager = NULL; - mIndexDataManager = NULL; + mLineLoopIB = nullptr; + mTriangleFanIB = nullptr; - mLineLoopIB = NULL; - mTriangleFanIB = NULL; - mAppliedIBChanged = false; + mBlit = nullptr; + mPixelTransfer = nullptr; - mBlit = NULL; - mPixelTransfer = NULL; + mClear = nullptr; - mClear = NULL; + mTrim = nullptr; - mTrim = NULL; - - mSyncQuery = NULL; - - mRenderer11DeviceCaps.supportsClearView = false; + mRenderer11DeviceCaps.supportsClearView = false; mRenderer11DeviceCaps.supportsConstantBufferOffsets = false; - mRenderer11DeviceCaps.supportsDXGI1_2 = false; - mRenderer11DeviceCaps.B5G6R5support = 0; - mRenderer11DeviceCaps.B4G4R4A4support = 0; - mRenderer11DeviceCaps.B5G5R5A1support = 0; + mRenderer11DeviceCaps.supportsVpRtIndexWriteFromVertexShader = false; + mRenderer11DeviceCaps.supportsDXGI1_2 = false; + mRenderer11DeviceCaps.B5G6R5support = 0; + mRenderer11DeviceCaps.B4G4R4A4support = 0; + mRenderer11DeviceCaps.B5G5R5A1support = 0; - mD3d11Module = NULL; - mDxgiModule = NULL; - mDCompModule = NULL; + mD3d11Module = nullptr; + mDxgiModule = nullptr; + mDCompModule = nullptr; mCreatedWithDeviceEXT = false; mEGLDevice = nullptr; - mDevice = NULL; - mDeviceContext = NULL; - mDeviceContext1 = NULL; - mDxgiAdapter = NULL; - mDxgiFactory = NULL; - - mDriverConstantBufferVS = NULL; - mDriverConstantBufferPS = NULL; - - mAppliedVertexShader = NULL; - mAppliedGeometryShader = NULL; - mAppliedPixelShader = NULL; - - mAppliedNumXFBBindings = static_cast(-1); + mDevice = nullptr; + mDeviceContext = nullptr; + mDeviceContext1 = nullptr; + mDeviceContext3 = nullptr; + mDxgiAdapter = nullptr; + mDxgiFactory = nullptr; ZeroMemory(&mAdapterDescription, sizeof(mAdapterDescription)); @@ -426,13 +488,21 @@ Renderer11::Renderer11(egl::Display *display) { const auto &attributes = mDisplay->getAttributeMap(); - EGLint requestedMajorVersion = - attributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, EGL_DONT_CARE); - EGLint requestedMinorVersion = - attributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, EGL_DONT_CARE); + EGLint requestedMajorVersion = static_cast( + attributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, EGL_DONT_CARE)); + EGLint requestedMinorVersion = static_cast( + attributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, EGL_DONT_CARE)); if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 11) { + if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 1) + { + // This could potentially lead to failed context creation if done on a system + // without the platform update which installs DXGI 1.2. Currently, for Chrome users + // D3D11 contexts are only created if the platform update is available, so this + // should not cause any issues. + mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_11_1); + } if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 0) { mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_11_0); @@ -451,11 +521,7 @@ Renderer11::Renderer11(egl::Display *display) } } -#if defined(ANGLE_ENABLE_WINDOWS_STORE) - if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 9) -#else if (requestedMajorVersion == 9 && requestedMinorVersion == 3) -#endif { if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 3) { @@ -473,8 +539,8 @@ Renderer11::Renderer11(egl::Display *display) #endif } - EGLint requestedDeviceType = attributes.get(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, - EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE); + EGLint requestedDeviceType = static_cast(attributes.get( + EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE)); switch (requestedDeviceType) { case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE: @@ -497,9 +563,11 @@ Renderer11::Renderer11(egl::Display *display) UNREACHABLE(); } - const EGLenum presentPath = attributes.get(EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE, - EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE); + const EGLenum presentPath = static_cast(attributes.get( + EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE, EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE)); mPresentPathFastEnabled = (presentPath == EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE); + + mCreateDebugDevice = ShouldUseDebugLayers(attributes); } else if (display->getPlatform() == EGL_PLATFORM_DEVICE_EXT) { @@ -509,11 +577,22 @@ Renderer11::Renderer11(egl::Display *display) // Also set EGL_PLATFORM_ANGLE_ANGLE variables, in case they're used elsewhere in ANGLE // mAvailableFeatureLevels defaults to empty - mRequestedDriverType = D3D_DRIVER_TYPE_UNKNOWN; + mRequestedDriverType = D3D_DRIVER_TYPE_UNKNOWN; mPresentPathFastEnabled = false; } - initializeDebugAnnotator(); +// The D3D11 renderer must choose the D3D9 debug annotator because the D3D11 interface +// method ID3DUserDefinedAnnotation::GetStatus on desktop builds doesn't work with the Graphics +// Diagnostics tools in Visual Studio 2013. +// The D3D9 annotator works properly for both D3D11 and D3D9. +// Incorrect status reporting can cause ANGLE to log unnecessary debug events. +#ifdef ANGLE_ENABLE_D3D9 + mAnnotator = new DebugAnnotator9(); +#else + mAnnotator = new DebugAnnotator11(); +#endif + ASSERT(mAnnotator); + gl::InitializeDebugAnnotations(mAnnotator); } Renderer11::~Renderer11() @@ -529,20 +608,17 @@ egl::Error Renderer11::initialize() { HRESULT result = S_OK; - egl::Error error = initializeD3DDevice(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(initializeD3DDevice()); #if !defined(ANGLE_ENABLE_WINDOWS_STORE) #if !ANGLE_SKIP_DXGI_1_2_CHECK { TRACE_EVENT0("gpu.angle", "Renderer11::initialize (DXGICheck)"); - // In order to create a swap chain for an HWND owned by another process, DXGI 1.2 is required. + // In order to create a swap chain for an HWND owned by another process, DXGI 1.2 is + // required. // The easiest way to check is to query for a IDXGIDevice2. bool requireDXGI1_2 = false; - HWND hwnd = WindowFromDC(mDisplay->getNativeDisplayId()); + HWND hwnd = WindowFromDC(mDisplay->getNativeDisplayId()); if (hwnd) { DWORD currentProcessId = GetCurrentProcessId(); @@ -557,13 +633,12 @@ egl::Error Renderer11::initialize() if (requireDXGI1_2) { - IDXGIDevice2 *dxgiDevice2 = NULL; - result = mDevice->QueryInterface(__uuidof(IDXGIDevice2), (void**)&dxgiDevice2); + IDXGIDevice2 *dxgiDevice2 = nullptr; + result = mDevice->QueryInterface(__uuidof(IDXGIDevice2), (void **)&dxgiDevice2); if (FAILED(result)) { - return egl::Error(EGL_NOT_INITIALIZED, - D3D11_INIT_INCOMPATIBLE_DXGI, - "DXGI 1.2 required to present to HWNDs owned by another process."); + return egl::EglNotInitialized(D3D11_INIT_INCOMPATIBLE_DXGI) + << "DXGI 1.2 required to present to HWNDs owned by another process."; } SafeRelease(dxgiDevice2); } @@ -573,90 +648,83 @@ egl::Error Renderer11::initialize() { TRACE_EVENT0("gpu.angle", "Renderer11::initialize (ComQueries)"); - // Cast the DeviceContext to a DeviceContext1. + // Cast the DeviceContext to a DeviceContext1 and DeviceContext3. // This could fail on Windows 7 without the Platform Update. - // Don't error in this case- just don't use mDeviceContext1. -#if defined(ANGLE_ENABLE_D3D11_1) + // Don't error in this case- just don't use mDeviceContext1 or mDeviceContext3. mDeviceContext1 = d3d11::DynamicCastComObject(mDeviceContext); -#endif + mDeviceContext3 = d3d11::DynamicCastComObject(mDeviceContext); - IDXGIDevice *dxgiDevice = NULL; - result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); + IDXGIDevice *dxgiDevice = nullptr; + result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void **)&dxgiDevice); if (FAILED(result)) { - return egl::Error(EGL_NOT_INITIALIZED, - D3D11_INIT_OTHER_ERROR, - "Could not query DXGI device."); + return egl::EglNotInitialized(D3D11_INIT_OTHER_ERROR) << "Could not query DXGI device."; } - result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&mDxgiAdapter); + result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&mDxgiAdapter); if (FAILED(result)) { - return egl::Error(EGL_NOT_INITIALIZED, - D3D11_INIT_OTHER_ERROR, - "Could not retrieve DXGI adapter"); + return egl::EglNotInitialized(D3D11_INIT_OTHER_ERROR) + << "Could not retrieve DXGI adapter"; } SafeRelease(dxgiDevice); -#if defined(ANGLE_ENABLE_D3D11_1) IDXGIAdapter2 *dxgiAdapter2 = d3d11::DynamicCastComObject(mDxgiAdapter); - // On D3D_FEATURE_LEVEL_9_*, IDXGIAdapter::GetDesc returns "Software Adapter" for the description string. - // If DXGI1.2 is available then IDXGIAdapter2::GetDesc2 can be used to get the actual hardware values. - if (mRenderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3 && dxgiAdapter2 != NULL) + // On D3D_FEATURE_LEVEL_9_*, IDXGIAdapter::GetDesc returns "Software Adapter" for the + // description string. + // If DXGI1.2 is available then IDXGIAdapter2::GetDesc2 can be used to get the actual + // hardware values. + if (mRenderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3 && dxgiAdapter2 != nullptr) { DXGI_ADAPTER_DESC2 adapterDesc2 = {}; - result = dxgiAdapter2->GetDesc2(&adapterDesc2); + result = dxgiAdapter2->GetDesc2(&adapterDesc2); if (SUCCEEDED(result)) { - // Copy the contents of the DXGI_ADAPTER_DESC2 into mAdapterDescription (a DXGI_ADAPTER_DESC). - memcpy(mAdapterDescription.Description, adapterDesc2.Description, sizeof(mAdapterDescription.Description)); - mAdapterDescription.VendorId = adapterDesc2.VendorId; - mAdapterDescription.DeviceId = adapterDesc2.DeviceId; - mAdapterDescription.SubSysId = adapterDesc2.SubSysId; - mAdapterDescription.Revision = adapterDesc2.Revision; - mAdapterDescription.DedicatedVideoMemory = adapterDesc2.DedicatedVideoMemory; + // Copy the contents of the DXGI_ADAPTER_DESC2 into mAdapterDescription (a + // DXGI_ADAPTER_DESC). + memcpy(mAdapterDescription.Description, adapterDesc2.Description, + sizeof(mAdapterDescription.Description)); + mAdapterDescription.VendorId = adapterDesc2.VendorId; + mAdapterDescription.DeviceId = adapterDesc2.DeviceId; + mAdapterDescription.SubSysId = adapterDesc2.SubSysId; + mAdapterDescription.Revision = adapterDesc2.Revision; + mAdapterDescription.DedicatedVideoMemory = adapterDesc2.DedicatedVideoMemory; mAdapterDescription.DedicatedSystemMemory = adapterDesc2.DedicatedSystemMemory; - mAdapterDescription.SharedSystemMemory = adapterDesc2.SharedSystemMemory; - mAdapterDescription.AdapterLuid = adapterDesc2.AdapterLuid; + mAdapterDescription.SharedSystemMemory = adapterDesc2.SharedSystemMemory; + mAdapterDescription.AdapterLuid = adapterDesc2.AdapterLuid; } } else -#endif { result = mDxgiAdapter->GetDesc(&mAdapterDescription); } -#if defined(ANGLE_ENABLE_D3D11_1) SafeRelease(dxgiAdapter2); -#endif if (FAILED(result)) { - return egl::Error(EGL_NOT_INITIALIZED, - D3D11_INIT_OTHER_ERROR, - "Could not read DXGI adaptor description."); + return egl::EglNotInitialized(D3D11_INIT_OTHER_ERROR) + << "Could not read DXGI adaptor description."; } memset(mDescription, 0, sizeof(mDescription)); wcstombs(mDescription, mAdapterDescription.Description, sizeof(mDescription) - 1); - result = mDxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&mDxgiFactory); + result = mDxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void **)&mDxgiFactory); if (!mDxgiFactory || FAILED(result)) { - return egl::Error(EGL_NOT_INITIALIZED, - D3D11_INIT_OTHER_ERROR, - "Could not create DXGI factory."); + return egl::EglNotInitialized(D3D11_INIT_OTHER_ERROR) + << "Could not create DXGI factory."; } } -#if !defined(ANGLE_MINGW32_COMPAT) // Disable some spurious D3D11 debug warnings to prevent them from flooding the output log -#if defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG) + if (mCreateDebugDevice) { TRACE_EVENT0("gpu.angle", "Renderer11::initialize (HideWarnings)"); ID3D11InfoQueue *infoQueue; @@ -664,29 +732,33 @@ egl::Error Renderer11::initialize() if (SUCCEEDED(result)) { - D3D11_MESSAGE_ID hideMessages[] = - { - D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET - }; + D3D11_MESSAGE_ID hideMessages[] = { + D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET}; D3D11_INFO_QUEUE_FILTER filter = {}; filter.DenyList.NumIDs = static_cast(ArraySize(hideMessages)); - filter.DenyList.pIDList = hideMessages; + filter.DenyList.pIDList = hideMessages; infoQueue->AddStorageFilterEntries(&filter); SafeRelease(infoQueue); } } -#endif #if !defined(NDEBUG) mDebug = d3d11::DynamicCastComObject(mDevice); #endif -#endif // !ANGLE_MINGW32_COMPAT - initializeDevice(); + ANGLE_TRY(initializeDevice()); - return egl::Error(EGL_SUCCESS); + return egl::NoError(); +} + +HRESULT Renderer11::callD3D11CreateDevice(PFN_D3D11_CREATE_DEVICE createDevice, bool debug) +{ + return createDevice( + nullptr, mRequestedDriverType, nullptr, debug ? D3D11_CREATE_DEVICE_DEBUG : 0, + mAvailableFeatureLevels.data(), static_cast(mAvailableFeatureLevels.size()), + D3D11_SDK_VERSION, &mDevice, &(mRenderer11DeviceCaps.featureLevel), &mDeviceContext); } egl::Error Renderer11::initializeD3DDevice() @@ -706,8 +778,8 @@ egl::Error Renderer11::initializeD3DDevice() if (mD3d11Module == nullptr || mDxgiModule == nullptr) { - return egl::Error(EGL_NOT_INITIALIZED, D3D11_INIT_MISSING_DEP, - "Could not load D3D11 or DXGI library."); + return egl::EglNotInitialized(D3D11_INIT_MISSING_DEP) + << "Could not load D3D11 or DXGI library."; } // create the D3D11 device @@ -717,68 +789,76 @@ egl::Error Renderer11::initializeD3DDevice() if (D3D11CreateDevice == nullptr) { - return egl::Error(EGL_NOT_INITIALIZED, D3D11_INIT_MISSING_DEP, - "Could not retrieve D3D11CreateDevice address."); + return egl::EglNotInitialized(D3D11_INIT_MISSING_DEP) + << "Could not retrieve D3D11CreateDevice address."; } } #endif -#ifdef _DEBUG + if (mCreateDebugDevice) { TRACE_EVENT0("gpu.angle", "D3D11CreateDevice (Debug)"); - result = D3D11CreateDevice(nullptr, mRequestedDriverType, nullptr, - D3D11_CREATE_DEVICE_DEBUG, mAvailableFeatureLevels.data(), - static_cast(mAvailableFeatureLevels.size()), - D3D11_SDK_VERSION, &mDevice, - &(mRenderer11DeviceCaps.featureLevel), &mDeviceContext); + result = callD3D11CreateDevice(D3D11CreateDevice, true); + + if (result == E_INVALIDARG && mAvailableFeatureLevels.size() > 1u && + mAvailableFeatureLevels[0] == D3D_FEATURE_LEVEL_11_1) + { + // On older Windows platforms, D3D11.1 is not supported which returns E_INVALIDARG. + // Try again without passing D3D_FEATURE_LEVEL_11_1 in case we have other feature + // levels to fall back on. + mAvailableFeatureLevels.erase(mAvailableFeatureLevels.begin()); + result = callD3D11CreateDevice(D3D11CreateDevice, true); + } + + if (!mDevice || FAILED(result)) + { + WARN() << "Failed creating Debug D3D11 device - falling back to release runtime."; + } } if (!mDevice || FAILED(result)) - { - ERR("Failed creating Debug D3D11 device - falling back to release runtime.\n"); - } - - if (!mDevice || FAILED(result)) -#endif { SCOPED_ANGLE_HISTOGRAM_TIMER("GPU.ANGLE.D3D11CreateDeviceMS"); TRACE_EVENT0("gpu.angle", "D3D11CreateDevice"); - result = D3D11CreateDevice( - nullptr, mRequestedDriverType, nullptr, 0, mAvailableFeatureLevels.data(), - static_cast(mAvailableFeatureLevels.size()), D3D11_SDK_VERSION, - &mDevice, &(mRenderer11DeviceCaps.featureLevel), &mDeviceContext); + result = callD3D11CreateDevice(D3D11CreateDevice, false); + + if (result == E_INVALIDARG && mAvailableFeatureLevels.size() > 1u && + mAvailableFeatureLevels[0] == D3D_FEATURE_LEVEL_11_1) + { + // On older Windows platforms, D3D11.1 is not supported which returns E_INVALIDARG. + // Try again without passing D3D_FEATURE_LEVEL_11_1 in case we have other feature + // levels to fall back on. + mAvailableFeatureLevels.erase(mAvailableFeatureLevels.begin()); + result = callD3D11CreateDevice(D3D11CreateDevice, false); + } // Cleanup done by destructor if (!mDevice || FAILED(result)) { ANGLE_HISTOGRAM_SPARSE_SLOWLY("GPU.ANGLE.D3D11CreateDeviceError", static_cast(result)); - return egl::Error(EGL_NOT_INITIALIZED, D3D11_INIT_CREATEDEVICE_ERROR, - "Could not create D3D11 device."); + return egl::EglNotInitialized(D3D11_INIT_CREATEDEVICE_ERROR) + << "Could not create D3D11 device."; } } } else { // We should use the inputted D3D11 device instead - void *device = nullptr; - egl::Error error = mEGLDevice->getDevice(&device); - if (error.isError()) - { - return error; - } + void *device = nullptr; + ANGLE_TRY(mEGLDevice->getDevice(&device)); ID3D11Device *d3dDevice = reinterpret_cast(device); if (FAILED(d3dDevice->GetDeviceRemovedReason())) { - return egl::Error(EGL_NOT_INITIALIZED, "Inputted D3D11 device has been lost."); + return egl::EglNotInitialized() << "Inputted D3D11 device has been lost."; } if (d3dDevice->GetFeatureLevel() < D3D_FEATURE_LEVEL_9_3) { - return egl::Error(EGL_NOT_INITIALIZED, - "Inputted D3D11 device must be Feature Level 9_3 or greater."); + return egl::EglNotInitialized() + << "Inputted D3D11 device must be Feature Level 9_3 or greater."; } // The Renderer11 adds a ref to the inputted D3D11 device, like D3D11CreateDevice does. @@ -788,27 +868,24 @@ egl::Error Renderer11::initializeD3DDevice() mRenderer11DeviceCaps.featureLevel = mDevice->GetFeatureLevel(); } + mResourceManager11.setAllocationsInitialized(mCreateDebugDevice); + d3d11::SetDebugName(mDeviceContext, "DeviceContext"); - return egl::Error(EGL_SUCCESS); + return egl::NoError(); } // do any one-time device initialization // NOTE: this is also needed after a device lost/reset // to reset the scene status and ensure the default states are reset. -void Renderer11::initializeDevice() +egl::Error Renderer11::initializeDevice() { SCOPED_ANGLE_HISTOGRAM_TIMER("GPU.ANGLE.Renderer11InitializeDeviceMS"); TRACE_EVENT0("gpu.angle", "Renderer11::initializeDevice"); populateRenderer11DeviceCaps(); - mStateCache.initialize(mDevice); - mInputLayoutCache.initialize(mDevice, mDeviceContext); - - ASSERT(!mVertexDataManager && !mIndexDataManager); - mVertexDataManager = new VertexDataManager(this); - mIndexDataManager = new IndexDataManager(this, getRendererClass()); + mStateCache.clear(); ASSERT(!mBlit); mBlit = new Blit11(this); @@ -820,7 +897,8 @@ void Renderer11::initializeDevice() // If automatic trim is enabled, DXGIDevice3::Trim( ) is called for the application // automatically when an application is suspended by the OS. This feature is currently // only supported for Windows Store applications. - EGLint enableAutoTrim = attributes.get(EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_FALSE); + EGLint enableAutoTrim = static_cast( + attributes.get(EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_FALSE)); if (enableAutoTrim == EGL_TRUE) { @@ -831,19 +909,12 @@ void Renderer11::initializeDevice() ASSERT(!mPixelTransfer); mPixelTransfer = new PixelTransfer11(this); - const gl::Caps &rendererCaps = getRendererCaps(); + const gl::Caps &rendererCaps = getNativeCaps(); - mStateManager.initialize(rendererCaps); - - mForceSetVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits); - mCurVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits); - - mForceSetPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits); - mCurPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits); - - mStateManager.initialize(rendererCaps); - - markAllStateDirty(); + if (mStateManager.initialize(rendererCaps, getNativeExtensions()).isError()) + { + return egl::EglBadAlloc() << "Error initializing state manager."; + } // Gather stats on DXGI and D3D feature level ANGLE_HISTOGRAM_BOOLEAN("GPU.ANGLE.SupportsDXGI1_2", mRenderer11DeviceCaps.supportsDXGI1_2); @@ -859,57 +930,117 @@ void Renderer11::initializeDevice() angleFeatureLevel = ANGLE_FEATURE_LEVEL_11_1; } - ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.D3D11FeatureLevel", - angleFeatureLevel, + ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.D3D11FeatureLevel", angleFeatureLevel, NUM_ANGLE_FEATURE_LEVELS); - // TODO(jmadill): use context caps, and place in common D3D location - mTranslatedAttribCache.resize(getRendererCaps().maxVertexAttributes); + return egl::NoError(); } void Renderer11::populateRenderer11DeviceCaps() { HRESULT hr = S_OK; -#if defined(ANGLE_ENABLE_D3D11_1) + LARGE_INTEGER version; + hr = mDxgiAdapter->CheckInterfaceSupport(__uuidof(IDXGIDevice), &version); + if (FAILED(hr)) + { + mRenderer11DeviceCaps.driverVersion.reset(); + ERR() << "Error querying driver version from DXGI Adapter."; + } + else + { + mRenderer11DeviceCaps.driverVersion = version; + } + if (mDeviceContext1) { D3D11_FEATURE_DATA_D3D11_OPTIONS d3d11Options; - HRESULT result = mDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &d3d11Options, sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS)); + HRESULT result = mDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &d3d11Options, + sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS)); if (SUCCEEDED(result)) { mRenderer11DeviceCaps.supportsClearView = (d3d11Options.ClearView != FALSE); - mRenderer11DeviceCaps.supportsConstantBufferOffsets = (d3d11Options.ConstantBufferOffsetting != FALSE); + mRenderer11DeviceCaps.supportsConstantBufferOffsets = + (d3d11Options.ConstantBufferOffsetting != FALSE); } } -#endif - hr = mDevice->CheckFormatSupport(DXGI_FORMAT_B5G6R5_UNORM, &(mRenderer11DeviceCaps.B5G6R5support)); - if (FAILED(hr)) + if (mDeviceContext3) + { + D3D11_FEATURE_DATA_D3D11_OPTIONS3 d3d11Options3; + HRESULT result = mDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS3, &d3d11Options3, + sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS3)); + if (SUCCEEDED(result)) + { + mRenderer11DeviceCaps.supportsVpRtIndexWriteFromVertexShader = + (d3d11Options3.VPAndRTArrayIndexFromAnyShaderFeedingRasterizer == TRUE); + } + } + + mRenderer11DeviceCaps.supportsMultisampledDepthStencilSRVs = + mRenderer11DeviceCaps.featureLevel > D3D_FEATURE_LEVEL_10_0; + + if (getWorkarounds().disableB5G6R5Support) { mRenderer11DeviceCaps.B5G6R5support = 0; + mRenderer11DeviceCaps.B5G6R5maxSamples = 0; } - - hr = mDevice->CheckFormatSupport(DXGI_FORMAT_B4G4R4A4_UNORM, &(mRenderer11DeviceCaps.B4G4R4A4support)); - if (FAILED(hr)) + else { - mRenderer11DeviceCaps.B4G4R4A4support = 0; + PopulateFormatDeviceCaps(mDevice, DXGI_FORMAT_B5G6R5_UNORM, + &mRenderer11DeviceCaps.B5G6R5support, + &mRenderer11DeviceCaps.B5G6R5maxSamples); } - hr = mDevice->CheckFormatSupport(DXGI_FORMAT_B5G5R5A1_UNORM, &(mRenderer11DeviceCaps.B5G5R5A1support)); - if (FAILED(hr)) - { - mRenderer11DeviceCaps.B5G5R5A1support = 0; - } + PopulateFormatDeviceCaps(mDevice, DXGI_FORMAT_B4G4R4A4_UNORM, + &mRenderer11DeviceCaps.B4G4R4A4support, + &mRenderer11DeviceCaps.B4G4R4A4maxSamples); + PopulateFormatDeviceCaps(mDevice, DXGI_FORMAT_B5G5R5A1_UNORM, + &mRenderer11DeviceCaps.B5G5R5A1support, + &mRenderer11DeviceCaps.B5G5R5A1maxSamples); -#if defined(ANGLE_ENABLE_D3D11_1) IDXGIAdapter2 *dxgiAdapter2 = d3d11::DynamicCastComObject(mDxgiAdapter); mRenderer11DeviceCaps.supportsDXGI1_2 = (dxgiAdapter2 != nullptr); SafeRelease(dxgiAdapter2); -#endif } -egl::ConfigSet Renderer11::generateConfigs() const +gl::SupportedSampleSet Renderer11::generateSampleSetForEGLConfig( + const gl::TextureCaps &colorBufferFormatCaps, + const gl::TextureCaps &depthStencilBufferFormatCaps) const +{ + gl::SupportedSampleSet sampleCounts; + +#if 0 // Disabling support for multisampling with Qt5 as it's causing a crash in the D3D11 shaders. + + // Generate a new set from the set intersection of sample counts between the color and depth + // format caps. + std::set_intersection(colorBufferFormatCaps.sampleCounts.begin(), + colorBufferFormatCaps.sampleCounts.end(), + depthStencilBufferFormatCaps.sampleCounts.begin(), + depthStencilBufferFormatCaps.sampleCounts.end(), + std::inserter(sampleCounts, sampleCounts.begin())); + + // Format of GL_NONE results in no supported sample counts. + // Add back the color sample counts to the supported sample set. + if (depthStencilBufferFormatCaps.sampleCounts.empty()) + { + sampleCounts = colorBufferFormatCaps.sampleCounts; + } + else if (colorBufferFormatCaps.sampleCounts.empty()) + { + // Likewise, add back the depth sample counts to the supported sample set. + sampleCounts = depthStencilBufferFormatCaps.sampleCounts; + } + +#endif + + // Always support 0 samples + sampleCounts.insert(0); + + return sampleCounts; +} + +egl::ConfigSet Renderer11::generateConfigs() { std::vector colorBufferFormats; @@ -920,6 +1051,14 @@ egl::ConfigSet Renderer11::generateConfigs() const // 24-bit supported formats colorBufferFormats.push_back(GL_RGB8_OES); + if (mRenderer11DeviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_0) + { + // Additional high bit depth formats added in D3D 10.0 + // https://msdn.microsoft.com/en-us/library/windows/desktop/bb173064.aspx + colorBufferFormats.push_back(GL_RGBA16F); + colorBufferFormats.push_back(GL_RGB10_A2); + } + if (!mPresentPathFastEnabled) { // 16-bit supported formats @@ -930,15 +1069,13 @@ egl::ConfigSet Renderer11::generateConfigs() const colorBufferFormats.push_back(GL_RGB565); } - static const GLenum depthStencilBufferFormats[] = - { - GL_NONE, - GL_DEPTH24_STENCIL8_OES, - GL_DEPTH_COMPONENT16, + static const GLenum depthStencilBufferFormats[] = { + GL_NONE, GL_DEPTH24_STENCIL8_OES, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16, + GL_STENCIL_INDEX8, }; - const gl::Caps &rendererCaps = getRendererCaps(); - const gl::TextureCapsMap &rendererTextureCaps = getRendererTextureCaps(); + const gl::Caps &rendererCaps = getNativeCaps(); + const gl::TextureCapsMap &rendererTextureCaps = getNativeTextureCaps(); const EGLint optimalSurfaceOrientation = mPresentPathFastEnabled ? 0 : EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE; @@ -946,7 +1083,8 @@ egl::ConfigSet Renderer11::generateConfigs() const egl::ConfigSet configs; for (GLenum colorBufferInternalFormat : colorBufferFormats) { - const gl::TextureCaps &colorBufferFormatCaps = rendererTextureCaps.get(colorBufferInternalFormat); + const gl::TextureCaps &colorBufferFormatCaps = + rendererTextureCaps.get(colorBufferInternalFormat); if (!colorBufferFormatCaps.renderable) { continue; @@ -963,64 +1101,87 @@ egl::ConfigSet Renderer11::generateConfigs() const } const gl::InternalFormat &colorBufferFormatInfo = - gl::GetInternalFormatInfo(colorBufferInternalFormat); + gl::GetSizedInternalFormatInfo(colorBufferInternalFormat); const gl::InternalFormat &depthStencilBufferFormatInfo = - gl::GetInternalFormatInfo(depthStencilBufferInternalFormat); + gl::GetSizedInternalFormatInfo(depthStencilBufferInternalFormat); + const gl::Version &maxVersion = getMaxSupportedESVersion(); - egl::Config config; - config.renderTargetFormat = colorBufferInternalFormat; - config.depthStencilFormat = depthStencilBufferInternalFormat; - config.bufferSize = colorBufferFormatInfo.pixelBytes * 8; - config.redSize = colorBufferFormatInfo.redBits; - config.greenSize = colorBufferFormatInfo.greenBits; - config.blueSize = colorBufferFormatInfo.blueBits; - config.luminanceSize = colorBufferFormatInfo.luminanceBits; - config.alphaSize = colorBufferFormatInfo.alphaBits; - config.alphaMaskSize = 0; - config.bindToTextureRGB = (colorBufferFormatInfo.format == GL_RGB); - config.bindToTextureRGBA = (colorBufferFormatInfo.format == GL_RGBA || - colorBufferFormatInfo.format == GL_BGRA_EXT); - config.colorBufferType = EGL_RGB_BUFFER; - config.configID = static_cast(configs.size() + 1); - // Can only support a conformant ES2 with feature level greater than 10.0. - config.conformant = (mRenderer11DeviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_0) - ? (EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT_KHR) - : 0; - config.configCaveat = config.conformant == EGL_NONE ? EGL_NON_CONFORMANT_CONFIG : EGL_NONE; + const gl::SupportedSampleSet sampleCounts = + generateSampleSetForEGLConfig(colorBufferFormatCaps, depthStencilBufferFormatCaps); - // PresentPathFast may not be conformant - if (mPresentPathFastEnabled) + for (GLuint sampleCount : sampleCounts) { + egl::Config config; + config.renderTargetFormat = colorBufferInternalFormat; + config.depthStencilFormat = depthStencilBufferInternalFormat; + config.bufferSize = colorBufferFormatInfo.pixelBytes * 8; + config.redSize = colorBufferFormatInfo.redBits; + config.greenSize = colorBufferFormatInfo.greenBits; + config.blueSize = colorBufferFormatInfo.blueBits; + config.luminanceSize = colorBufferFormatInfo.luminanceBits; + config.alphaSize = colorBufferFormatInfo.alphaBits; + config.alphaMaskSize = 0; + config.bindToTextureRGB = + ((colorBufferFormatInfo.format == GL_RGB) && (sampleCount <= 1)); + config.bindToTextureRGBA = (((colorBufferFormatInfo.format == GL_RGBA) || + (colorBufferFormatInfo.format == GL_BGRA_EXT)) && + (sampleCount <= 1)); + config.colorBufferType = EGL_RGB_BUFFER; + config.configCaveat = EGL_NONE; + config.configID = static_cast(configs.size() + 1); + + // PresentPathFast may not be conformant config.conformant = 0; + if (!mPresentPathFastEnabled) + { + // Can only support a conformant ES2 with feature level greater than 10.0. + if (mRenderer11DeviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_0) + { + config.conformant |= EGL_OPENGL_ES2_BIT; + } + + // We can only support conformant ES3 on FL 10.1+ + if (maxVersion.major >= 3) + { + config.conformant |= EGL_OPENGL_ES3_BIT_KHR; + } + } + + config.depthSize = depthStencilBufferFormatInfo.depthBits; + config.level = 0; + config.matchNativePixmap = EGL_NONE; + config.maxPBufferWidth = rendererCaps.max2DTextureSize; + config.maxPBufferHeight = rendererCaps.max2DTextureSize; + config.maxPBufferPixels = + rendererCaps.max2DTextureSize * rendererCaps.max2DTextureSize; + config.maxSwapInterval = 4; + config.minSwapInterval = 0; + config.nativeRenderable = EGL_FALSE; + config.nativeVisualID = 0; + config.nativeVisualType = EGL_NONE; + + // Can't support ES3 at all without feature level 10.1 + config.renderableType = EGL_OPENGL_ES2_BIT; + if (maxVersion.major >= 3) + { + config.renderableType |= EGL_OPENGL_ES3_BIT_KHR; + } + + config.sampleBuffers = (sampleCount == 0) ? 0 : 1; + config.samples = sampleCount; + config.stencilSize = depthStencilBufferFormatInfo.stencilBits; + config.surfaceType = + EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT; + config.transparentType = EGL_NONE; + config.transparentRedValue = 0; + config.transparentGreenValue = 0; + config.transparentBlueValue = 0; + config.optimalOrientation = optimalSurfaceOrientation; + config.colorComponentType = gl_egl::GLComponentTypeToEGLColorComponentType( + colorBufferFormatInfo.componentType); + + configs.add(config); } - - config.depthSize = depthStencilBufferFormatInfo.depthBits; - config.level = 0; - config.matchNativePixmap = EGL_NONE; - config.maxPBufferWidth = rendererCaps.max2DTextureSize; - config.maxPBufferHeight = rendererCaps.max2DTextureSize; - config.maxPBufferPixels = rendererCaps.max2DTextureSize * rendererCaps.max2DTextureSize; - config.maxSwapInterval = 4; - config.minSwapInterval = 0; - config.nativeRenderable = EGL_FALSE; - config.nativeVisualID = 0; - config.nativeVisualType = EGL_NONE; - // Can't support ES3 at all without feature level 10.0 - config.renderableType = - EGL_OPENGL_ES2_BIT | ((mRenderer11DeviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_0) - ? EGL_OPENGL_ES3_BIT_KHR - : 0); - config.sampleBuffers = 0; // FIXME: enumerate multi-sampling - config.samples = 0; - config.stencilSize = depthStencilBufferFormatInfo.stencilBits; - config.surfaceType = EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT; - config.transparentType = EGL_NONE; - config.transparentRedValue = 0; - config.transparentGreenValue = 0; - config.transparentBlueValue = 0; - config.optimalOrientation = optimalSurfaceOrientation; - - configs.add(config); } } @@ -1037,8 +1198,9 @@ void Renderer11::generateDisplayExtensions(egl::DisplayExtensions *outExtensions outExtensions->d3dShareHandleClientBuffer = true; outExtensions->surfaceD3DTexture2DShareHandle = true; } + outExtensions->d3dTextureClientBuffer = true; - outExtensions->keyedMutex = true; + outExtensions->keyedMutex = true; outExtensions->querySurfacePointer = true; outExtensions->windowFixedSize = true; @@ -1048,431 +1210,244 @@ void Renderer11::generateDisplayExtensions(egl::DisplayExtensions *outExtensions // D3D11 does not support present with dirty rectangles until DXGI 1.2. outExtensions->postSubBuffer = mRenderer11DeviceCaps.supportsDXGI1_2; - outExtensions->createContext = true; - outExtensions->deviceQuery = true; - outExtensions->createContextNoError = true; - outExtensions->image = true; outExtensions->imageBase = true; outExtensions->glTexture2DImage = true; outExtensions->glTextureCubemapImage = true; outExtensions->glRenderbufferImage = true; + outExtensions->stream = true; + outExtensions->streamConsumerGLTexture = true; + outExtensions->streamConsumerGLTextureYUV = true; + // Not all D3D11 devices support NV12 textures + if (getNV12TextureSupport()) + { + outExtensions->streamProducerD3DTextureNV12 = true; + } + outExtensions->flexibleSurfaceCompatibility = true; outExtensions->directComposition = !!mDCompModule; + + // Contexts are virtualized so textures can be shared globally + outExtensions->displayTextureShareGroup = true; + + // getSyncValues requires direct composition. + outExtensions->getSyncValues = outExtensions->directComposition; + + // D3D11 can be used without a swap chain + outExtensions->surfacelessContext = true; + + // All D3D feature levels support robust resource init + outExtensions->robustResourceInitialization = true; } gl::Error Renderer11::flush() { mDeviceContext->Flush(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Renderer11::finish() { - HRESULT result; - - if (!mSyncQuery) + if (!mSyncQuery.valid()) { D3D11_QUERY_DESC queryDesc; - queryDesc.Query = D3D11_QUERY_EVENT; + queryDesc.Query = D3D11_QUERY_EVENT; queryDesc.MiscFlags = 0; - result = mDevice->CreateQuery(&queryDesc, &mSyncQuery); - ASSERT(SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create event query, result: 0x%X.", result); - } + ANGLE_TRY(allocateResource(queryDesc, &mSyncQuery)); } - mDeviceContext->End(mSyncQuery); - mDeviceContext->Flush(); + mDeviceContext->End(mSyncQuery.get()); + HRESULT result = S_OK; + unsigned int attempt = 0; do { - result = mDeviceContext->GetData(mSyncQuery, NULL, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH); + unsigned int flushFrequency = 100; + UINT flags = (attempt % flushFrequency == 0) ? 0 : D3D11_ASYNC_GETDATA_DONOTFLUSH; + attempt++; + + result = mDeviceContext->GetData(mSyncQuery.get(), nullptr, 0, flags); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to get event query data, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to get event query data, " << gl::FmtHR(result); } - // Keep polling, but allow other threads to do something useful first - ScheduleYield(); + if (result == S_FALSE) + { + // Keep polling, but allow other threads to do something useful first + ScheduleYield(); + } if (testDeviceLost()) { mDisplay->notifyDeviceLost(); - return gl::Error(GL_OUT_OF_MEMORY, "Device was lost while waiting for sync."); + return gl::OutOfMemory() << "Device was lost while waiting for sync."; + } + } while (result == S_FALSE); + + return gl::NoError(); +} + +bool Renderer11::isValidNativeWindow(EGLNativeWindowType window) const +{ +#ifdef ANGLE_ENABLE_WINDOWS_STORE + return NativeWindow11WinRT::IsValidNativeWindow(window); +#else + return NativeWindow11Win32::IsValidNativeWindow(window); +#endif +} + +NativeWindowD3D *Renderer11::createNativeWindow(EGLNativeWindowType window, + const egl::Config *config, + const egl::AttributeMap &attribs) const +{ +#ifdef ANGLE_ENABLE_WINDOWS_STORE + UNUSED_VARIABLE(attribs); + return new NativeWindow11WinRT(window, config->alphaSize > 0); +#else + return new NativeWindow11Win32( + window, config->alphaSize > 0, + attribs.get(EGL_DIRECT_COMPOSITION_ANGLE, EGL_FALSE) == EGL_TRUE); +#endif +} + +egl::Error Renderer11::getD3DTextureInfo(const egl::Config *configuration, + IUnknown *d3dTexture, + EGLint *width, + EGLint *height, + GLenum *fboFormat) const +{ + ID3D11Texture2D *texture = d3d11::DynamicCastComObject(d3dTexture); + if (texture == nullptr) + { + return egl::EglBadParameter() << "client buffer is not a ID3D11Texture2D"; + } + + ID3D11Device *textureDevice = nullptr; + texture->GetDevice(&textureDevice); + if (textureDevice != mDevice) + { + SafeRelease(texture); + return egl::EglBadParameter() << "Texture's device does not match."; + } + SafeRelease(textureDevice); + + D3D11_TEXTURE2D_DESC desc = {0}; + texture->GetDesc(&desc); + SafeRelease(texture); + + if (width) + { + *width = static_cast(desc.Width); + } + if (height) + { + *height = static_cast(desc.Height); + } + if (static_cast(desc.SampleDesc.Count) != configuration->samples) + { + // Both the texture and EGL config sample count may not be the same when multi-sampling + // is disabled. The EGL sample count can be 0 but a D3D texture is always 1. Therefore, + // we must only check for a invalid match when the EGL config is non-zero or the texture is + // not one. + if (configuration->samples != 0 || desc.SampleDesc.Count != 1) + { + return egl::EglBadParameter() << "Texture's sample count does not match."; } } - while (result == S_FALSE); + // From table egl.restrictions in EGL_ANGLE_d3d_texture_client_buffer. + switch (desc.Format) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_R32G32B32A32_FLOAT: + break; - return gl::Error(GL_NO_ERROR); + default: + return egl::EglBadParameter() + << "Unknown client buffer texture format: " << desc.Format; + } + + if (fboFormat) + { + const angle::Format &angleFormat = d3d11_angle::GetFormat(desc.Format); + *fboFormat = angleFormat.fboImplementationInternalFormat; + } + + return egl::NoError(); } -SwapChainD3D *Renderer11::createSwapChain(NativeWindow nativeWindow, +egl::Error Renderer11::validateShareHandle(const egl::Config *config, + HANDLE shareHandle, + const egl::AttributeMap &attribs) const +{ + if (shareHandle == nullptr) + { + return egl::EglBadParameter() << "NULL share handle."; + } + + ID3D11Resource *tempResource11 = nullptr; + HRESULT result = mDevice->OpenSharedResource(shareHandle, __uuidof(ID3D11Resource), + (void **)&tempResource11); + if (FAILED(result)) + { + return egl::EglBadParameter() << "Failed to open share handle, " << gl::FmtHR(result); + } + + ID3D11Texture2D *texture2D = d3d11::DynamicCastComObject(tempResource11); + SafeRelease(tempResource11); + + if (texture2D == nullptr) + { + return egl::EglBadParameter() + << "Failed to query ID3D11Texture2D object from share handle."; + } + + D3D11_TEXTURE2D_DESC desc = {0}; + texture2D->GetDesc(&desc); + SafeRelease(texture2D); + + EGLint width = attribs.getAsInt(EGL_WIDTH, 0); + EGLint height = attribs.getAsInt(EGL_HEIGHT, 0); + ASSERT(width != 0 && height != 0); + + const d3d11::Format &backbufferFormatInfo = + d3d11::Format::Get(config->renderTargetFormat, getRenderer11DeviceCaps()); + + if (desc.Width != static_cast(width) || desc.Height != static_cast(height) || + desc.Format != backbufferFormatInfo.texFormat || desc.MipLevels != 1 || desc.ArraySize != 1) + { + return egl::EglBadParameter() << "Invalid texture parameters in share handle texture."; + } + + return egl::NoError(); +} + +SwapChainD3D *Renderer11::createSwapChain(NativeWindowD3D *nativeWindow, HANDLE shareHandle, + IUnknown *d3dTexture, GLenum backBufferFormat, GLenum depthBufferFormat, - EGLint orientation) + EGLint orientation, + EGLint samples) { - return new SwapChain11(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat, - orientation); -} - -CompilerImpl *Renderer11::createCompiler() -{ - if (mRenderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3) - { - return new CompilerD3D(SH_HLSL_4_0_FL9_3_OUTPUT); - } - else - { - return new CompilerD3D(SH_HLSL_4_1_OUTPUT); - } + return new SwapChain11(this, GetAs(nativeWindow), shareHandle, d3dTexture, + backBufferFormat, depthBufferFormat, orientation, samples); } void *Renderer11::getD3DDevice() { - return reinterpret_cast(mDevice); + return reinterpret_cast(mDevice); } -gl::Error Renderer11::generateSwizzle(gl::Texture *texture) -{ - if (texture) - { - TextureD3D *textureD3D = GetImplAs(texture); - ASSERT(textureD3D); - - TextureStorage *texStorage = nullptr; - gl::Error error = textureD3D->getNativeTexture(&texStorage); - if (error.isError()) - { - return error; - } - - if (texStorage) - { - TextureStorage11 *storage11 = GetAs(texStorage); - const gl::TextureState &textureState = texture->getTextureState(); - error = - storage11->generateSwizzles(textureState.swizzleRed, textureState.swizzleGreen, - textureState.swizzleBlue, textureState.swizzleAlpha); - if (error.isError()) - { - return error; - } - } - } - - return gl::Error(GL_NO_ERROR); -} - -gl::Error Renderer11::setSamplerState(gl::SamplerType type, - int index, - gl::Texture *texture, - const gl::SamplerState &samplerState) -{ - // Make sure to add the level offset for our tiny compressed texture workaround - TextureD3D *textureD3D = GetImplAs(texture); - - TextureStorage *storage = nullptr; - gl::Error error = textureD3D->getNativeTexture(&storage); - if (error.isError()) - { - return error; - } - - // Storage should exist, texture should be complete - ASSERT(storage); - - if (type == gl::SAMPLER_PIXEL) - { - ASSERT(static_cast(index) < getRendererCaps().maxTextureImageUnits); - - if (mForceSetPixelSamplerStates[index] || - memcmp(&samplerState, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0) - { - ID3D11SamplerState *dxSamplerState = NULL; - error = mStateCache.getSamplerState(samplerState, &dxSamplerState); - if (error.isError()) - { - return error; - } - - ASSERT(dxSamplerState != NULL); - mDeviceContext->PSSetSamplers(index, 1, &dxSamplerState); - - mCurPixelSamplerStates[index] = samplerState; - } - - mForceSetPixelSamplerStates[index] = false; - } - else if (type == gl::SAMPLER_VERTEX) - { - ASSERT(static_cast(index) < getRendererCaps().maxVertexTextureImageUnits); - - if (mForceSetVertexSamplerStates[index] || - memcmp(&samplerState, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0) - { - ID3D11SamplerState *dxSamplerState = NULL; - error = mStateCache.getSamplerState(samplerState, &dxSamplerState); - if (error.isError()) - { - return error; - } - - ASSERT(dxSamplerState != NULL); - mDeviceContext->VSSetSamplers(index, 1, &dxSamplerState); - - mCurVertexSamplerStates[index] = samplerState; - } - - mForceSetVertexSamplerStates[index] = false; - } - else UNREACHABLE(); - - return gl::Error(GL_NO_ERROR); -} - -gl::Error Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture) -{ - ID3D11ShaderResourceView *textureSRV = NULL; - - if (texture) - { - TextureD3D *textureImpl = GetImplAs(texture); - - TextureStorage *texStorage = nullptr; - gl::Error error = textureImpl->getNativeTexture(&texStorage); - if (error.isError()) - { - return error; - } - - // Texture should be complete and have a storage - ASSERT(texStorage); - - TextureStorage11 *storage11 = GetAs(texStorage); - - // Make sure to add the level offset for our tiny compressed texture workaround - gl::TextureState textureState = texture->getTextureState(); - textureState.baseLevel += storage11->getTopLevel(); - - error = storage11->getSRV(textureState, &textureSRV); - if (error.isError()) - { - return error; - } - - // If we get NULL back from getSRV here, something went wrong in the texture class and we're unexpectedly - // missing the shader resource view - ASSERT(textureSRV != NULL); - - textureImpl->resetDirty(); - } - - ASSERT((type == gl::SAMPLER_PIXEL && static_cast(index) < getRendererCaps().maxTextureImageUnits) || - (type == gl::SAMPLER_VERTEX && static_cast(index) < getRendererCaps().maxVertexTextureImageUnits)); - - mStateManager.setShaderResource(type, index, textureSRV); - - return gl::Error(GL_NO_ERROR); -} - -gl::Error Renderer11::setUniformBuffers(const gl::Data &data, - const std::vector &vertexUniformBuffers, - const std::vector &fragmentUniformBuffers) -{ - for (size_t uniformBufferIndex = 0; uniformBufferIndex < vertexUniformBuffers.size(); uniformBufferIndex++) - { - GLint binding = vertexUniformBuffers[uniformBufferIndex]; - - if (binding == -1) - { - continue; - } - - const OffsetBindingPointer &uniformBuffer = - data.state->getIndexedUniformBuffer(binding); - GLintptr uniformBufferOffset = uniformBuffer.getOffset(); - GLsizeiptr uniformBufferSize = uniformBuffer.getSize(); - - if (uniformBuffer.get() != nullptr) - { - Buffer11 *bufferStorage = GetImplAs(uniformBuffer.get()); - ID3D11Buffer *constantBuffer; - - if (mRenderer11DeviceCaps.supportsConstantBufferOffsets) - { - constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM); - } - else - { - constantBuffer = bufferStorage->getConstantBufferRange(uniformBufferOffset, uniformBufferSize); - } - - if (!constantBuffer) - { - return gl::Error(GL_OUT_OF_MEMORY); - } - - if (mCurrentConstantBufferVS[uniformBufferIndex] != bufferStorage->getSerial() || - mCurrentConstantBufferVSOffset[uniformBufferIndex] != uniformBufferOffset || - mCurrentConstantBufferVSSize[uniformBufferIndex] != uniformBufferSize) - { -#if defined(ANGLE_ENABLE_D3D11_1) - if (mRenderer11DeviceCaps.supportsConstantBufferOffsets && uniformBufferSize != 0) - { - UINT firstConstant = 0, numConstants = 0; - CalculateConstantBufferParams(uniformBufferOffset, uniformBufferSize, &firstConstant, &numConstants); - mDeviceContext1->VSSetConstantBuffers1( - getReservedVertexUniformBuffers() + - static_cast(uniformBufferIndex), - 1, &constantBuffer, &firstConstant, &numConstants); - } - else -#endif - { - mDeviceContext->VSSetConstantBuffers( - getReservedVertexUniformBuffers() + - static_cast(uniformBufferIndex), - 1, &constantBuffer); - } - - mCurrentConstantBufferVS[uniformBufferIndex] = bufferStorage->getSerial(); - mCurrentConstantBufferVSOffset[uniformBufferIndex] = uniformBufferOffset; - mCurrentConstantBufferVSSize[uniformBufferIndex] = uniformBufferSize; - } - } - } - - for (size_t uniformBufferIndex = 0; uniformBufferIndex < fragmentUniformBuffers.size(); uniformBufferIndex++) - { - GLint binding = fragmentUniformBuffers[uniformBufferIndex]; - - if (binding == -1) - { - continue; - } - - const OffsetBindingPointer &uniformBuffer = - data.state->getIndexedUniformBuffer(binding); - GLintptr uniformBufferOffset = uniformBuffer.getOffset(); - GLsizeiptr uniformBufferSize = uniformBuffer.getSize(); - - if (uniformBuffer.get() != nullptr) - { - Buffer11 *bufferStorage = GetImplAs(uniformBuffer.get()); - ID3D11Buffer *constantBuffer; - - if (mRenderer11DeviceCaps.supportsConstantBufferOffsets) - { - constantBuffer = bufferStorage->getBuffer(BUFFER_USAGE_UNIFORM); - } - else - { - constantBuffer = bufferStorage->getConstantBufferRange(uniformBufferOffset, uniformBufferSize); - } - - if (!constantBuffer) - { - return gl::Error(GL_OUT_OF_MEMORY); - } - - if (mCurrentConstantBufferPS[uniformBufferIndex] != bufferStorage->getSerial() || - mCurrentConstantBufferPSOffset[uniformBufferIndex] != uniformBufferOffset || - mCurrentConstantBufferPSSize[uniformBufferIndex] != uniformBufferSize) - { -#if defined(ANGLE_ENABLE_D3D11_1) - if (mRenderer11DeviceCaps.supportsConstantBufferOffsets && uniformBufferSize != 0) - { - UINT firstConstant = 0, numConstants = 0; - CalculateConstantBufferParams(uniformBufferOffset, uniformBufferSize, &firstConstant, &numConstants); - mDeviceContext1->PSSetConstantBuffers1( - getReservedFragmentUniformBuffers() + - static_cast(uniformBufferIndex), - 1, &constantBuffer, &firstConstant, &numConstants); - } - else -#endif - { - mDeviceContext->PSSetConstantBuffers( - getReservedFragmentUniformBuffers() + - static_cast(uniformBufferIndex), - 1, &constantBuffer); - } - - mCurrentConstantBufferPS[uniformBufferIndex] = bufferStorage->getSerial(); - mCurrentConstantBufferPSOffset[uniformBufferIndex] = uniformBufferOffset; - mCurrentConstantBufferPSSize[uniformBufferIndex] = uniformBufferSize; - } - } - } - - return gl::Error(GL_NO_ERROR); -} - -gl::Error Renderer11::updateState(const gl::Data &data, GLenum drawMode) -{ - // Applies the render target surface, depth stencil surface, viewport rectangle and - // scissor rectangle to the renderer - const gl::Framebuffer *framebufferObject = data.state->getDrawFramebuffer(); - ASSERT(framebufferObject && framebufferObject->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE); - gl::Error error = applyRenderTarget(framebufferObject); - if (error.isError()) - { - return error; - } - - // Set the present path state - const bool presentPathFastActive = - UsePresentPathFast(this, framebufferObject->getFirstColorbuffer()); - mStateManager.updatePresentPath(presentPathFastActive, - framebufferObject->getFirstColorbuffer()); - - // Setting viewport state - mStateManager.setViewport(data.caps, data.state->getViewport(), data.state->getNearPlane(), - data.state->getFarPlane()); - - // Setting scissor state - mStateManager.setScissorRectangle(data.state->getScissor(), data.state->isScissorTestEnabled()); - - // Applying rasterizer state to D3D11 device - int samples = framebufferObject->getSamples(data); - gl::RasterizerState rasterizer = data.state->getRasterizerState(); - rasterizer.pointDrawMode = (drawMode == GL_POINTS); - rasterizer.multiSample = (samples != 0); - - error = mStateManager.setRasterizerState(rasterizer); - if (error.isError()) - { - return error; - } - - // Setting blend state - unsigned int mask = GetBlendSampleMask(data, samples); - error = mStateManager.setBlendState(framebufferObject, data.state->getBlendState(), - data.state->getBlendColor(), mask); - if (error.isError()) - { - return error; - } - - // Setting depth stencil state - error = mStateManager.setDepthStencilState(*data.state); - return error; -} - -void Renderer11::syncState(const gl::State &state, const gl::State::DirtyBits &bitmask) -{ - mStateManager.syncState(state, bitmask); -} - -bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize) +bool Renderer11::applyPrimitiveType(const gl::State &glState, GLenum mode, GLsizei count) { D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; @@ -1480,192 +1455,105 @@ bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSi switch (mode) { - case GL_POINTS: primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; minCount = 1; break; - case GL_LINES: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINELIST; minCount = 2; break; - case GL_LINE_LOOP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; minCount = 2; break; - case GL_LINE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; minCount = 2; break; - case GL_TRIANGLES: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; minCount = 3; break; - case GL_TRIANGLE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; minCount = 3; break; - // emulate fans via rewriting index buffer - case GL_TRIANGLE_FAN: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; minCount = 3; break; - default: - UNREACHABLE(); - return false; + case GL_POINTS: + { + bool usesPointSize = GetImplAs(glState.getProgram())->usesPointSize(); + + // ProgramBinary assumes non-point rendering if gl_PointSize isn't written, + // which affects varying interpolation. Since the value of gl_PointSize is + // undefined when not written, just skip drawing to avoid unexpected results. + if (!usesPointSize && !glState.isTransformFeedbackActiveUnpaused()) + { + // Notify developers of risking undefined behavior. + WARN() << "Point rendering without writing to gl_PointSize."; + return false; + } + + // If instanced pointsprites are enabled and the shader uses gl_PointSize, the topology + // must be D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST. + if (usesPointSize && getWorkarounds().useInstancedPointSpriteEmulation) + { + primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + } + else + { + primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; + } + minCount = 1; + break; + } + case GL_LINES: + primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINELIST; + minCount = 2; + break; + case GL_LINE_LOOP: + primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; + minCount = 2; + break; + case GL_LINE_STRIP: + primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; + minCount = 2; + break; + case GL_TRIANGLES: + primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + minCount = CullsEverything(glState) ? std::numeric_limits::max() : 3; + break; + case GL_TRIANGLE_STRIP: + primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; + minCount = CullsEverything(glState) ? std::numeric_limits::max() : 3; + break; + // emulate fans via rewriting index buffer + case GL_TRIANGLE_FAN: + primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + minCount = CullsEverything(glState) ? std::numeric_limits::max() : 3; + break; + default: + UNREACHABLE(); + return false; } - // If instanced pointsprite emulation is being used and If gl_PointSize is used in the shader, - // GL_POINTS mode is expected to render pointsprites. - // Instanced PointSprite emulation requires that the topology to be D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST. - if (mode == GL_POINTS && usesPointSize && getWorkarounds().useInstancedPointSpriteEmulation) - { - primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; - } - - if (primitiveTopology != mCurrentPrimitiveTopology) - { - mDeviceContext->IASetPrimitiveTopology(primitiveTopology); - mCurrentPrimitiveTopology = primitiveTopology; - } + mStateManager.setPrimitiveTopology(primitiveTopology); return count >= minCount; } -gl::Error Renderer11::applyRenderTarget(const gl::Framebuffer *framebuffer) +gl::Error Renderer11::drawArrays(const gl::Context *context, + GLenum mode, + GLint startVertex, + GLsizei count, + GLsizei instances) { - return mStateManager.syncFramebuffer(framebuffer); -} + const auto &glState = context->getGLState(); -gl::Error Renderer11::applyVertexBuffer(const gl::State &state, - GLenum mode, - GLint first, - GLsizei count, - GLsizei instances, - TranslatedIndexData *indexInfo) -{ - gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, &mTranslatedAttribCache, instances); - if (error.isError()) + if (!applyPrimitiveType(glState, mode, count)) { - return error; + return gl::NoError(); } - // If index information is passed, mark it with the current changed status. - if (indexInfo) + DrawCallVertexParams vertexParams(startVertex, count, instances); + ANGLE_TRY(mStateManager.applyVertexBuffer(context, mode, vertexParams, false)); + + if (glState.isTransformFeedbackActiveUnpaused()) { - indexInfo->srcIndexData.srcIndicesChanged = mAppliedIBChanged; + ANGLE_TRY(markTransformFeedbackUsage(context)); } - GLsizei numIndicesPerInstance = 0; - if (instances > 0) - { - numIndicesPerInstance = count; - } - return mInputLayoutCache.applyVertexBuffers(mTranslatedAttribCache, mode, state.getProgram(), - indexInfo, numIndicesPerInstance); -} + gl::Program *program = glState.getProgram(); + ASSERT(program != nullptr); + GLsizei adjustedInstanceCount = GetAdjustedInstanceCount(program, instances); + ProgramD3D *programD3D = GetImplAs(program); -gl::Error Renderer11::applyIndexBuffer(const gl::Data &data, - const GLvoid *indices, - GLsizei count, - GLenum mode, - GLenum type, - TranslatedIndexData *indexInfo) -{ - gl::VertexArray *vao = data.state->getVertexArray(); - gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get(); - gl::Error error = - mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo, - data.state->isPrimitiveRestartEnabled()); - if (error.isError()) - { - return error; - } - - ID3D11Buffer *buffer = NULL; - DXGI_FORMAT bufferFormat = (indexInfo->indexType == GL_UNSIGNED_INT) ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT; - - if (indexInfo->storage) - { - Buffer11 *storage = GetAs(indexInfo->storage); - buffer = storage->getBuffer(BUFFER_USAGE_INDEX); - } - else - { - IndexBuffer11* indexBuffer = GetAs(indexInfo->indexBuffer); - buffer = indexBuffer->getBuffer(); - } - - mAppliedIBChanged = false; - if (buffer != mAppliedIB || bufferFormat != mAppliedIBFormat || indexInfo->startOffset != mAppliedIBOffset) - { - mDeviceContext->IASetIndexBuffer(buffer, bufferFormat, indexInfo->startOffset); - - mAppliedIB = buffer; - mAppliedIBFormat = bufferFormat; - mAppliedIBOffset = indexInfo->startOffset; - mAppliedIBChanged = true; - } - - return gl::Error(GL_NO_ERROR); -} - -void Renderer11::applyTransformFeedbackBuffers(const gl::State &state) -{ - size_t numXFBBindings = 0; - bool requiresUpdate = false; - - if (state.isTransformFeedbackActiveUnpaused()) - { - const gl::TransformFeedback *transformFeedback = state.getCurrentTransformFeedback(); - numXFBBindings = transformFeedback->getIndexedBufferCount(); - ASSERT(numXFBBindings <= gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS); - - for (size_t i = 0; i < numXFBBindings; i++) - { - const OffsetBindingPointer &binding = transformFeedback->getIndexedBuffer(i); - - ID3D11Buffer *d3dBuffer = NULL; - if (binding.get() != nullptr) - { - Buffer11 *storage = GetImplAs(binding.get()); - d3dBuffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); - } - - // TODO: mAppliedTFBuffers and friends should also be kept in a vector. - if (d3dBuffer != mAppliedTFBuffers[i] || binding.getOffset() != mAppliedTFOffsets[i]) - { - requiresUpdate = true; - } - } - } - - if (requiresUpdate || numXFBBindings != mAppliedNumXFBBindings) - { - const gl::TransformFeedback *transformFeedback = state.getCurrentTransformFeedback(); - for (size_t i = 0; i < numXFBBindings; ++i) - { - const OffsetBindingPointer &binding = transformFeedback->getIndexedBuffer(i); - if (binding.get() != nullptr) - { - Buffer11 *storage = GetImplAs(binding.get()); - ID3D11Buffer *d3dBuffer = storage->getBuffer(BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK); - - mCurrentD3DOffsets[i] = (mAppliedTFBuffers[i] != d3dBuffer || mAppliedTFOffsets[i] != binding.getOffset()) ? - static_cast(binding.getOffset()) : -1; - mAppliedTFBuffers[i] = d3dBuffer; - } - else - { - mAppliedTFBuffers[i] = NULL; - mCurrentD3DOffsets[i] = 0; - } - mAppliedTFOffsets[i] = binding.getOffset(); - } - - mAppliedNumXFBBindings = numXFBBindings; - - mDeviceContext->SOSetTargets(static_cast(numXFBBindings), mAppliedTFBuffers, - mCurrentD3DOffsets); - } -} - -gl::Error Renderer11::drawArraysImpl(const gl::Data &data, - GLenum mode, - GLsizei count, - GLsizei instances) -{ - ProgramD3D *programD3D = GetImplAs(data.state->getProgram()); - - if (programD3D->usesGeometryShader(mode) && data.state->isTransformFeedbackActiveUnpaused()) + if (programD3D->usesGeometryShader(mode) && glState.isTransformFeedbackActiveUnpaused()) { // Since we use a geometry if-and-only-if we rewrite vertex streams, transform feedback // won't get the correct output. To work around this, draw with *only* the stream out // first (no pixel shader) to feed the stream out buffers and then draw again with the // geometry shader + pixel shader to rasterize the primitives. - mDeviceContext->PSSetShader(nullptr, nullptr, 0); + mStateManager.setPixelShader(nullptr); - if (instances > 0) + if (adjustedInstanceCount > 0) { - mDeviceContext->DrawInstanced(count, instances, 0, 0); + mDeviceContext->DrawInstanced(count, adjustedInstanceCount, 0, 0); } else { @@ -1673,203 +1561,330 @@ gl::Error Renderer11::drawArraysImpl(const gl::Data &data, } rx::ShaderExecutableD3D *pixelExe = nullptr; - gl::Error error = programD3D->getPixelExecutableForFramebuffer(data.state->getDrawFramebuffer(), &pixelExe); - if (error.isError()) - { - return error; - } + ANGLE_TRY(programD3D->getPixelExecutableForCachedOutputLayout(&pixelExe, nullptr)); // Skip the draw call if rasterizer discard is enabled (or no fragment shader). - if (!pixelExe || data.state->getRasterizerState().rasterizerDiscard) + if (!pixelExe || glState.getRasterizerState().rasterizerDiscard) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } - ID3D11PixelShader *pixelShader = GetAs(pixelExe)->getPixelShader(); - ASSERT(reinterpret_cast(pixelShader) == mAppliedPixelShader); - mDeviceContext->PSSetShader(pixelShader, NULL, 0); + mStateManager.setPixelShader(&GetAs(pixelExe)->getPixelShader()); // Retrieve the geometry shader. rx::ShaderExecutableD3D *geometryExe = nullptr; - error = - programD3D->getGeometryExecutableForPrimitiveType(data, mode, &geometryExe, nullptr); - if (error.isError()) - { - return error; - } + ANGLE_TRY(programD3D->getGeometryExecutableForPrimitiveType(context, mode, &geometryExe, + nullptr)); - ID3D11GeometryShader *geometryShader = - (geometryExe ? GetAs(geometryExe)->getGeometryShader() : NULL); - mAppliedGeometryShader = reinterpret_cast(geometryShader); - ASSERT(geometryShader); - mDeviceContext->GSSetShader(geometryShader, NULL, 0); + mStateManager.setGeometryShader( + &GetAs(geometryExe)->getGeometryShader()); - if (instances > 0) + if (adjustedInstanceCount > 0) { - mDeviceContext->DrawInstanced(count, instances, 0, 0); + mDeviceContext->DrawInstanced(count, adjustedInstanceCount, 0, 0); } else { mDeviceContext->Draw(count, 0); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } if (mode == GL_LINE_LOOP) { - return drawLineLoop(data, count, GL_NONE, nullptr, nullptr, instances); + return drawLineLoop(context, count, GL_NONE, nullptr, 0, adjustedInstanceCount); } if (mode == GL_TRIANGLE_FAN) { - return drawTriangleFan(data, count, GL_NONE, nullptr, 0, instances); + return drawTriangleFan(context, count, GL_NONE, nullptr, 0, adjustedInstanceCount); } bool useInstancedPointSpriteEmulation = programD3D->usesPointSize() && getWorkarounds().useInstancedPointSpriteEmulation; - if (instances > 0) + if (mode != GL_POINTS || !useInstancedPointSpriteEmulation) { - if (mode == GL_POINTS && useInstancedPointSpriteEmulation) + if (adjustedInstanceCount == 0) { - // If pointsprite emulation is used with glDrawArraysInstanced then we need to take a - // less efficent code path. - // Instanced rendering of emulated pointsprites requires a loop to draw each batch of - // points. An offset into the instanced data buffer is calculated and applied on each - // iteration to ensure all instances are rendered correctly. - - // Each instance being rendered requires the inputlayout cache to reapply buffers and - // offsets. - for (GLsizei i = 0; i < instances; i++) - { - gl::Error error = mInputLayoutCache.updateVertexOffsetsForPointSpritesEmulation(i); - if (error.isError()) - { - return error; - } - - mDeviceContext->DrawIndexedInstanced(6, count, 0, 0, 0); - } + mDeviceContext->Draw(count, 0); } else { - mDeviceContext->DrawInstanced(count, instances, 0, 0); + mDeviceContext->DrawInstanced(count, adjustedInstanceCount, 0, 0); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } + // This code should not be reachable by multi-view programs. + ASSERT(program->usesMultiview() == false); + // If the shader is writing to gl_PointSize, then pointsprites are being rendered. // Emulating instanced point sprites for FL9_3 requires the topology to be // D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST and DrawIndexedInstanced is called instead. - if (mode == GL_POINTS && useInstancedPointSpriteEmulation) + if (adjustedInstanceCount == 0) { mDeviceContext->DrawIndexedInstanced(6, count, 0, 0, 0); + return gl::NoError(); } - else + + // If pointsprite emulation is used with glDrawArraysInstanced then we need to take a less + // efficent code path. Instanced rendering of emulated pointsprites requires a loop to draw each + // batch of points. An offset into the instanced data buffer is calculated and applied on each + // iteration to ensure all instances are rendered correctly. Each instance being rendered + // requires the inputlayout cache to reapply buffers and offsets. + for (GLsizei i = 0; i < instances; i++) { - mDeviceContext->Draw(count, 0); + ANGLE_TRY(mStateManager.updateVertexOffsetsForPointSpritesEmulation(startVertex, i)); + mDeviceContext->DrawIndexedInstanced(6, count, 0, 0, 0); } - return gl::Error(GL_NO_ERROR); + + // This required by updateVertexOffsets... above but is outside of the loop for speed. + mStateManager.invalidateVertexBuffer(); + return gl::NoError(); } -gl::Error Renderer11::drawElementsImpl(const gl::Data &data, - const TranslatedIndexData &indexInfo, - GLenum mode, - GLsizei count, - GLenum type, - const GLvoid *indices, - GLsizei instances) +gl::Error Renderer11::drawElements(const gl::Context *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei instances) { - int minIndex = static_cast(indexInfo.indexRange.start); + const auto &glState = context->getGLState(); + + if (!applyPrimitiveType(glState, mode, count)) + { + return gl::NoError(); + } + + // Transform feedback is not allowed for DrawElements, this error should have been caught at the + // API validation layer. + ASSERT(!glState.isTransformFeedbackActiveUnpaused()); + + const auto &lazyIndexRange = context->getParams(); + + bool usePrimitiveRestartWorkaround = + UsePrimitiveRestartWorkaround(glState.isPrimitiveRestartEnabled(), type); + DrawCallVertexParams vertexParams(!usePrimitiveRestartWorkaround, lazyIndexRange, 0, instances); + + ANGLE_TRY(mStateManager.applyIndexBuffer(context, indices, count, type, lazyIndexRange, + usePrimitiveRestartWorkaround)); + ANGLE_TRY(mStateManager.applyVertexBuffer(context, mode, vertexParams, true)); + + int startVertex = static_cast(vertexParams.firstVertex()); + int baseVertex = -startVertex; + + const gl::Program *program = glState.getProgram(); + GLsizei adjustedInstanceCount = GetAdjustedInstanceCount(program, instances); if (mode == GL_LINE_LOOP) { - return drawLineLoop(data, count, type, indices, &indexInfo, instances); + return drawLineLoop(context, count, type, indices, baseVertex, adjustedInstanceCount); } if (mode == GL_TRIANGLE_FAN) { - return drawTriangleFan(data, count, type, indices, minIndex, instances); + return drawTriangleFan(context, count, type, indices, baseVertex, adjustedInstanceCount); } - const ProgramD3D *programD3D = GetImplAs(data.state->getProgram()); - if (instances > 0) + const ProgramD3D *programD3D = GetImplAs(glState.getProgram()); + + if (mode != GL_POINTS || !programD3D->usesInstancedPointSpriteEmulation()) { - if (mode == GL_POINTS && programD3D->usesInstancedPointSpriteEmulation()) + if (adjustedInstanceCount == 0) { - // If pointsprite emulation is used with glDrawElementsInstanced then we need to take a - // less efficent code path. - // Instanced rendering of emulated pointsprites requires a loop to draw each batch of - // points. An offset into the instanced data buffer is calculated and applied on each - // iteration to ensure all instances are rendered correctly. - GLsizei elementsToRender = static_cast(indexInfo.indexRange.vertexCount()); - - // Each instance being rendered requires the inputlayout cache to reapply buffers and - // offsets. - for (GLsizei i = 0; i < instances; i++) - { - gl::Error error = mInputLayoutCache.updateVertexOffsetsForPointSpritesEmulation(i); - if (error.isError()) - { - return error; - } - - mDeviceContext->DrawIndexedInstanced(6, elementsToRender, 0, 0, 0); - } + mDeviceContext->DrawIndexed(count, 0, baseVertex); } else { - mDeviceContext->DrawIndexedInstanced(count, instances, 0, -minIndex, 0); + mDeviceContext->DrawIndexedInstanced(count, adjustedInstanceCount, 0, baseVertex, 0); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } + // This code should not be reachable by multi-view programs. + ASSERT(program->usesMultiview() == false); + // If the shader is writing to gl_PointSize, then pointsprites are being rendered. // Emulating instanced point sprites for FL9_3 requires the topology to be // D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST and DrawIndexedInstanced is called instead. - if (mode == GL_POINTS && programD3D->usesInstancedPointSpriteEmulation()) + // + // The count parameter passed to drawElements represents the total number of instances to be + // rendered. Each instance is referenced by the bound index buffer from the the caller. + // + // Indexed pointsprite emulation replicates data for duplicate entries found in the index + // buffer. This is not an efficent rendering mechanism and is only used on downlevel renderers + // that do not support geometry shaders. + if (instances == 0) { - // The count parameter passed to drawElements represents the total number of instances - // to be rendered. Each instance is referenced by the bound index buffer from the - // the caller. - // - // Indexed pointsprite emulation replicates data for duplicate entries found - // in the index buffer. - // This is not an efficent rendering mechanism and is only used on downlevel renderers - // that do not support geometry shaders. mDeviceContext->DrawIndexedInstanced(6, count, 0, 0, 0); + return gl::NoError(); } - else + + // If pointsprite emulation is used with glDrawElementsInstanced then we need to take a less + // efficent code path. Instanced rendering of emulated pointsprites requires a loop to draw each + // batch of points. An offset into the instanced data buffer is calculated and applied on each + // iteration to ensure all instances are rendered correctly. + GLsizei elementsToRender = vertexParams.vertexCount(); + + // Each instance being rendered requires the inputlayout cache to reapply buffers and offsets. + for (GLsizei i = 0; i < instances; i++) { - mDeviceContext->DrawIndexed(count, 0, -minIndex); + ANGLE_TRY(mStateManager.updateVertexOffsetsForPointSpritesEmulation(startVertex, i)); + mDeviceContext->DrawIndexedInstanced(6, elementsToRender, 0, 0, 0); } - return gl::Error(GL_NO_ERROR); + mStateManager.invalidateVertexBuffer(); + return gl::NoError(); } -gl::Error Renderer11::drawLineLoop(const gl::Data &data, +gl::Error Renderer11::drawArraysIndirect(const gl::Context *context, + GLenum mode, + const void *indirect) +{ + const auto &glState = context->getGLState(); + ASSERT(!glState.isTransformFeedbackActiveUnpaused()); + + if (!applyPrimitiveType(glState, mode, std::numeric_limits::max() - 1)) + { + return gl::NoError(); + } + + gl::Buffer *drawIndirectBuffer = glState.getTargetBuffer(gl::BufferBinding::DrawIndirect); + ASSERT(drawIndirectBuffer); + Buffer11 *storage = GetImplAs(drawIndirectBuffer); + uintptr_t offset = reinterpret_cast(indirect); + + if (!DrawCallNeedsTranslation(context, mode)) + { + DrawCallVertexParams vertexParams(0, 0, 0); + ANGLE_TRY(mStateManager.applyVertexBuffer(context, mode, vertexParams, false)); + ID3D11Buffer *buffer = nullptr; + ANGLE_TRY_RESULT(storage->getBuffer(context, BUFFER_USAGE_INDIRECT), buffer); + mDeviceContext->DrawInstancedIndirect(buffer, static_cast(offset)); + return gl::NoError(); + } + + const uint8_t *bufferData = nullptr; + ANGLE_TRY(storage->getData(context, &bufferData)); + ASSERT(bufferData); + const gl::DrawArraysIndirectCommand *args = + reinterpret_cast(bufferData + offset); + GLuint count = args->count; + GLuint instances = args->instanceCount; + GLuint first = args->first; + + DrawCallVertexParams vertexParams(first, count, instances); + ANGLE_TRY(mStateManager.applyVertexBuffer(context, mode, vertexParams, false)); + + if (mode == GL_LINE_LOOP) + { + return drawLineLoop(context, count, GL_NONE, nullptr, 0, instances); + } + if (mode == GL_TRIANGLE_FAN) + { + return drawTriangleFan(context, count, GL_NONE, nullptr, 0, instances); + } + + mDeviceContext->DrawInstanced(count, instances, 0, 0); + return gl::NoError(); +} + +gl::Error Renderer11::drawElementsIndirect(const gl::Context *context, + GLenum mode, + GLenum type, + const void *indirect) +{ + const auto &glState = context->getGLState(); + ASSERT(!glState.isTransformFeedbackActiveUnpaused()); + + if (!applyPrimitiveType(glState, mode, std::numeric_limits::max() - 1)) + { + return gl::NoError(); + } + + gl::Buffer *drawIndirectBuffer = glState.getTargetBuffer(gl::BufferBinding::DrawIndirect); + ASSERT(drawIndirectBuffer); + Buffer11 *storage = GetImplAs(drawIndirectBuffer); + uintptr_t offset = reinterpret_cast(indirect); + + // TODO(jmadill): Remove the if statement and compute indirect parameters lazily. + bool usePrimitiveRestartWorkaround = + UsePrimitiveRestartWorkaround(glState.isPrimitiveRestartEnabled(), type); + + if (!DrawCallNeedsTranslation(context, mode) && !IsStreamingIndexData(context, type)) + { + ANGLE_TRY(mStateManager.applyIndexBuffer(context, nullptr, 0, type, gl::HasIndexRange(), + usePrimitiveRestartWorkaround)); + DrawCallVertexParams vertexParams(0, 0, 0); + ANGLE_TRY(mStateManager.applyVertexBuffer(context, mode, vertexParams, true)); + ID3D11Buffer *buffer = nullptr; + ANGLE_TRY_RESULT(storage->getBuffer(context, BUFFER_USAGE_INDIRECT), buffer); + mDeviceContext->DrawIndexedInstancedIndirect(buffer, static_cast(offset)); + return gl::NoError(); + } + + const uint8_t *bufferData = nullptr; + ANGLE_TRY(storage->getData(context, &bufferData)); + ASSERT(bufferData); + + const gl::DrawElementsIndirectCommand *cmd = + reinterpret_cast(bufferData + offset); + GLsizei count = cmd->count; + GLuint instances = cmd->primCount; + GLuint firstIndex = cmd->firstIndex; + GLint baseVertex = cmd->baseVertex; + + // TODO(jmadill): Fix const cast. + const gl::Type &typeInfo = gl::GetTypeInfo(type); + const void *indices = + reinterpret_cast(static_cast(firstIndex * typeInfo.bytes)); + gl::HasIndexRange lazyIndexRange(const_cast(context), count, type, indices); + + ANGLE_TRY(mStateManager.applyIndexBuffer(context, indices, count, type, lazyIndexRange, + usePrimitiveRestartWorkaround)); + + DrawCallVertexParams vertexParams(false, lazyIndexRange, baseVertex, instances); + + ANGLE_TRY(mStateManager.applyVertexBuffer(context, mode, vertexParams, true)); + + int baseVertexLocation = -static_cast(lazyIndexRange.getIndexRange().value().start); + + if (mode == GL_LINE_LOOP) + { + return drawLineLoop(context, count, type, indices, baseVertexLocation, instances); + } + + if (mode == GL_TRIANGLE_FAN) + { + return drawTriangleFan(context, count, type, indices, baseVertexLocation, instances); + } + + mDeviceContext->DrawIndexedInstanced(count, instances, 0, baseVertexLocation, 0); + return gl::NoError(); +} + +gl::Error Renderer11::drawLineLoop(const gl::Context *context, GLsizei count, GLenum type, - const GLvoid *indexPointer, - const TranslatedIndexData *indexInfo, + const void *indexPointer, + int baseVertex, int instances) { - gl::VertexArray *vao = data.state->getVertexArray(); + const gl::State &glState = context->getGLState(); + gl::VertexArray *vao = glState.getVertexArray(); gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get(); - const GLvoid *indices = indexPointer; + const void *indices = indexPointer; // Get the raw indices for an indexed draw if (type != GL_NONE && elementArrayBuffer) { BufferD3D *storage = GetImplAs(elementArrayBuffer); - intptr_t offset = reinterpret_cast(indices); + intptr_t offset = reinterpret_cast(indices); - const uint8_t *bufferData = NULL; - gl::Error error = storage->getData(&bufferData); - if (error.isError()) - { - return error; - } + const uint8_t *bufferData = nullptr; + ANGLE_TRY(storage->getData(context, &bufferData)); indices = bufferData + offset; } @@ -1877,7 +1892,8 @@ gl::Error Renderer11::drawLineLoop(const gl::Data &data, if (!mLineLoopIB) { mLineLoopIB = new StreamingIndexBufferInterface(this); - gl::Error error = mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT); + gl::Error error = + mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT); if (error.isError()) { SafeDelete(mLineLoopIB); @@ -1888,92 +1904,71 @@ gl::Error Renderer11::drawLineLoop(const gl::Data &data, // Checked by Renderer11::applyPrimitiveType ASSERT(count >= 0); - if (static_cast(count) + 1 > (std::numeric_limits::max() / sizeof(unsigned int))) + if (static_cast(count) + 1 > + (std::numeric_limits::max() / sizeof(unsigned int))) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required."); + return gl::OutOfMemory() << "Failed to create a 32-bit looping index buffer for " + "GL_LINE_LOOP, too many indices required."; } GetLineLoopIndices(indices, type, static_cast(count), - data.state->isPrimitiveRestartEnabled(), &mScratchIndexDataBuffer); + glState.isPrimitiveRestartEnabled(), &mScratchIndexDataBuffer); unsigned int spaceNeeded = static_cast(sizeof(GLuint) * mScratchIndexDataBuffer.size()); - gl::Error error = mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT)); - void* mappedMemory = NULL; + void *mappedMemory = nullptr; unsigned int offset; - error = mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset)); // Copy over the converted index data. memcpy(mappedMemory, &mScratchIndexDataBuffer[0], sizeof(GLuint) * mScratchIndexDataBuffer.size()); - error = mLineLoopIB->unmapBuffer(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mLineLoopIB->unmapBuffer()); - IndexBuffer11 *indexBuffer = GetAs(mLineLoopIB->getIndexBuffer()); - ID3D11Buffer *d3dIndexBuffer = indexBuffer->getBuffer(); - DXGI_FORMAT indexFormat = indexBuffer->getIndexFormat(); + IndexBuffer11 *indexBuffer = GetAs(mLineLoopIB->getIndexBuffer()); + const d3d11::Buffer &d3dIndexBuffer = indexBuffer->getBuffer(); + DXGI_FORMAT indexFormat = indexBuffer->getIndexFormat(); - if (mAppliedIB != d3dIndexBuffer || mAppliedIBFormat != indexFormat || - mAppliedIBOffset != offset) - { - mDeviceContext->IASetIndexBuffer(d3dIndexBuffer, indexFormat, offset); - mAppliedIB = d3dIndexBuffer; - mAppliedIBFormat = indexFormat; - mAppliedIBOffset = offset; - } + mStateManager.setIndexBuffer(d3dIndexBuffer.get(), indexFormat, offset); - INT baseVertexLocation = (indexInfo ? -static_cast(indexInfo->indexRange.start) : 0); UINT indexCount = static_cast(mScratchIndexDataBuffer.size()); if (instances > 0) { - mDeviceContext->DrawIndexedInstanced(indexCount, instances, 0, baseVertexLocation, 0); + mDeviceContext->DrawIndexedInstanced(indexCount, instances, 0, baseVertex, 0); } else { - mDeviceContext->DrawIndexed(indexCount, 0, baseVertexLocation); + mDeviceContext->DrawIndexed(indexCount, 0, baseVertex); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Renderer11::drawTriangleFan(const gl::Data &data, +gl::Error Renderer11::drawTriangleFan(const gl::Context *context, GLsizei count, GLenum type, - const GLvoid *indices, - int minIndex, + const void *indices, + int baseVertex, int instances) { - gl::VertexArray *vao = data.state->getVertexArray(); + const gl::State &glState = context->getGLState(); + gl::VertexArray *vao = glState.getVertexArray(); gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get(); - const GLvoid *indexPointer = indices; + const void *indexPointer = indices; // Get the raw indices for an indexed draw if (type != GL_NONE && elementArrayBuffer) { BufferD3D *storage = GetImplAs(elementArrayBuffer); - intptr_t offset = reinterpret_cast(indices); + intptr_t offset = reinterpret_cast(indices); - const uint8_t *bufferData = NULL; - gl::Error error = storage->getData(&bufferData); - if (error.isError()) - { - return error; - } + const uint8_t *bufferData = nullptr; + ANGLE_TRY(storage->getData(context, &bufferData)); indexPointer = bufferData + offset; } @@ -1981,7 +1976,8 @@ gl::Error Renderer11::drawTriangleFan(const gl::Data &data, if (!mTriangleFanIB) { mTriangleFanIB = new StreamingIndexBufferInterface(this); - gl::Error error = mTriangleFanIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT); + gl::Error error = + mTriangleFanIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT); if (error.isError()) { SafeDelete(mTriangleFanIB); @@ -1996,386 +1992,50 @@ gl::Error Renderer11::drawTriangleFan(const gl::Data &data, if (numTris > (std::numeric_limits::max() / (sizeof(unsigned int) * 3))) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create a scratch index buffer for GL_TRIANGLE_FAN, too many indices required."); + return gl::OutOfMemory() << "Failed to create a scratch index buffer for GL_TRIANGLE_FAN, " + "too many indices required."; } - GetTriFanIndices(indexPointer, type, count, data.state->isPrimitiveRestartEnabled(), + GetTriFanIndices(indexPointer, type, count, glState.isPrimitiveRestartEnabled(), &mScratchIndexDataBuffer); const unsigned int spaceNeeded = static_cast(mScratchIndexDataBuffer.size() * sizeof(unsigned int)); - gl::Error error = mTriangleFanIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mTriangleFanIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT)); void *mappedMemory = nullptr; unsigned int offset; - error = mTriangleFanIB->mapBuffer(spaceNeeded, &mappedMemory, &offset); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mTriangleFanIB->mapBuffer(spaceNeeded, &mappedMemory, &offset)); memcpy(mappedMemory, &mScratchIndexDataBuffer[0], spaceNeeded); - error = mTriangleFanIB->unmapBuffer(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mTriangleFanIB->unmapBuffer()); - IndexBuffer11 *indexBuffer = GetAs(mTriangleFanIB->getIndexBuffer()); - ID3D11Buffer *d3dIndexBuffer = indexBuffer->getBuffer(); - DXGI_FORMAT indexFormat = indexBuffer->getIndexFormat(); + IndexBuffer11 *indexBuffer = GetAs(mTriangleFanIB->getIndexBuffer()); + const d3d11::Buffer &d3dIndexBuffer = indexBuffer->getBuffer(); + DXGI_FORMAT indexFormat = indexBuffer->getIndexFormat(); - if (mAppliedIB != d3dIndexBuffer || mAppliedIBFormat != indexFormat || - mAppliedIBOffset != offset) - { - mDeviceContext->IASetIndexBuffer(d3dIndexBuffer, indexFormat, offset); - mAppliedIB = d3dIndexBuffer; - mAppliedIBFormat = indexFormat; - mAppliedIBOffset = offset; - } + mStateManager.setIndexBuffer(d3dIndexBuffer.get(), indexFormat, offset); UINT indexCount = static_cast(mScratchIndexDataBuffer.size()); if (instances > 0) { - mDeviceContext->DrawIndexedInstanced(indexCount, instances, 0, -minIndex, 0); + mDeviceContext->DrawIndexedInstanced(indexCount, instances, 0, baseVertex, 0); } else { - mDeviceContext->DrawIndexed(indexCount, 0, -minIndex); + mDeviceContext->DrawIndexed(indexCount, 0, baseVertex); } - return gl::Error(GL_NO_ERROR); -} - -gl::Error Renderer11::applyShadersImpl(const gl::Data &data, GLenum drawMode) -{ - ProgramD3D *programD3D = GetImplAs(data.state->getProgram()); - const auto &inputLayout = programD3D->getCachedInputLayout(); - - ShaderExecutableD3D *vertexExe = NULL; - gl::Error error = programD3D->getVertexExecutableForInputLayout(inputLayout, &vertexExe, nullptr); - if (error.isError()) - { - return error; - } - - const gl::Framebuffer *drawFramebuffer = data.state->getDrawFramebuffer(); - ShaderExecutableD3D *pixelExe = NULL; - error = programD3D->getPixelExecutableForFramebuffer(drawFramebuffer, &pixelExe); - if (error.isError()) - { - return error; - } - - ShaderExecutableD3D *geometryExe = nullptr; - error = - programD3D->getGeometryExecutableForPrimitiveType(data, drawMode, &geometryExe, nullptr); - if (error.isError()) - { - return error; - } - - ID3D11VertexShader *vertexShader = (vertexExe ? GetAs(vertexExe)->getVertexShader() : NULL); - - ID3D11PixelShader *pixelShader = NULL; - // Skip pixel shader if we're doing rasterizer discard. - bool rasterizerDiscard = data.state->getRasterizerState().rasterizerDiscard; - if (!rasterizerDiscard) - { - pixelShader = (pixelExe ? GetAs(pixelExe)->getPixelShader() : NULL); - } - - ID3D11GeometryShader *geometryShader = NULL; - bool transformFeedbackActive = data.state->isTransformFeedbackActiveUnpaused(); - if (transformFeedbackActive) - { - geometryShader = (vertexExe ? GetAs(vertexExe)->getStreamOutShader() : NULL); - } - else - { - geometryShader = (geometryExe ? GetAs(geometryExe)->getGeometryShader() : NULL); - } - - bool dirtyUniforms = false; - - if (reinterpret_cast(vertexShader) != mAppliedVertexShader) - { - mDeviceContext->VSSetShader(vertexShader, NULL, 0); - mAppliedVertexShader = reinterpret_cast(vertexShader); - dirtyUniforms = true; - } - - if (reinterpret_cast(geometryShader) != mAppliedGeometryShader) - { - mDeviceContext->GSSetShader(geometryShader, NULL, 0); - mAppliedGeometryShader = reinterpret_cast(geometryShader); - dirtyUniforms = true; - } - - if (reinterpret_cast(pixelShader) != mAppliedPixelShader) - { - mDeviceContext->PSSetShader(pixelShader, NULL, 0); - mAppliedPixelShader = reinterpret_cast(pixelShader); - dirtyUniforms = true; - } - - if (dirtyUniforms) - { - programD3D->dirtyAllUniforms(); - } - - return gl::Error(GL_NO_ERROR); -} - -gl::Error Renderer11::applyUniforms(const ProgramD3D &programD3D, - GLenum drawMode, - const std::vector &uniformArray) -{ - unsigned int totalRegisterCountVS = 0; - unsigned int totalRegisterCountPS = 0; - - bool vertexUniformsDirty = false; - bool pixelUniformsDirty = false; - - for (const D3DUniform *uniform : uniformArray) - { - if (uniform->isReferencedByVertexShader() && !uniform->isSampler()) - { - totalRegisterCountVS += uniform->registerCount; - vertexUniformsDirty = (vertexUniformsDirty || uniform->dirty); - } - - if (uniform->isReferencedByFragmentShader() && !uniform->isSampler()) - { - totalRegisterCountPS += uniform->registerCount; - pixelUniformsDirty = (pixelUniformsDirty || uniform->dirty); - } - } - - const UniformStorage11 *vertexUniformStorage = - GetAs(&programD3D.getVertexUniformStorage()); - const UniformStorage11 *fragmentUniformStorage = - GetAs(&programD3D.getFragmentUniformStorage()); - ASSERT(vertexUniformStorage); - ASSERT(fragmentUniformStorage); - - ID3D11Buffer *vertexConstantBuffer = vertexUniformStorage->getConstantBuffer(); - ID3D11Buffer *pixelConstantBuffer = fragmentUniformStorage->getConstantBuffer(); - - float (*mapVS)[4] = NULL; - float (*mapPS)[4] = NULL; - - if (totalRegisterCountVS > 0 && vertexUniformsDirty) - { - D3D11_MAPPED_SUBRESOURCE map = {0}; - HRESULT result = mDeviceContext->Map(vertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); - UNUSED_ASSERTION_VARIABLE(result); - ASSERT(SUCCEEDED(result)); - mapVS = (float(*)[4])map.pData; - } - - if (totalRegisterCountPS > 0 && pixelUniformsDirty) - { - D3D11_MAPPED_SUBRESOURCE map = {0}; - HRESULT result = mDeviceContext->Map(pixelConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); - UNUSED_ASSERTION_VARIABLE(result); - ASSERT(SUCCEEDED(result)); - mapPS = (float(*)[4])map.pData; - } - - for (const D3DUniform *uniform : uniformArray) - { - if (uniform->isSampler()) - continue; - - unsigned int componentCount = (4 - uniform->registerElement); - - // we assume that uniforms from structs are arranged in struct order in our uniforms list. - // otherwise we would overwrite previously written regions of memory. - - if (uniform->isReferencedByVertexShader() && mapVS) - { - memcpy(&mapVS[uniform->vsRegisterIndex][uniform->registerElement], uniform->data, - uniform->registerCount * sizeof(float) * componentCount); - } - - if (uniform->isReferencedByFragmentShader() && mapPS) - { - memcpy(&mapPS[uniform->psRegisterIndex][uniform->registerElement], uniform->data, - uniform->registerCount * sizeof(float) * componentCount); - } - } - - if (mapVS) - { - mDeviceContext->Unmap(vertexConstantBuffer, 0); - } - - if (mapPS) - { - mDeviceContext->Unmap(pixelConstantBuffer, 0); - } - - if (mCurrentVertexConstantBuffer != vertexConstantBuffer) - { - mDeviceContext->VSSetConstantBuffers(0, 1, &vertexConstantBuffer); - mCurrentVertexConstantBuffer = vertexConstantBuffer; - } - - if (mCurrentPixelConstantBuffer != pixelConstantBuffer) - { - mDeviceContext->PSSetConstantBuffers(0, 1, &pixelConstantBuffer); - mCurrentPixelConstantBuffer = pixelConstantBuffer; - } - - // Driver uniforms - if (!mDriverConstantBufferVS) - { - D3D11_BUFFER_DESC constantBufferDescription = {0}; - constantBufferDescription.ByteWidth = sizeof(dx_VertexConstants11); - constantBufferDescription.Usage = D3D11_USAGE_DEFAULT; - constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - constantBufferDescription.CPUAccessFlags = 0; - constantBufferDescription.MiscFlags = 0; - constantBufferDescription.StructureByteStride = 0; - - HRESULT result = mDevice->CreateBuffer(&constantBufferDescription, NULL, &mDriverConstantBufferVS); - ASSERT(SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create vertex shader constant buffer, result: 0x%X.", result); - } - mDeviceContext->VSSetConstantBuffers(1, 1, &mDriverConstantBufferVS); - } - - if (!mDriverConstantBufferPS) - { - D3D11_BUFFER_DESC constantBufferDescription = {0}; - constantBufferDescription.ByteWidth = sizeof(dx_PixelConstants11); - constantBufferDescription.Usage = D3D11_USAGE_DEFAULT; - constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - constantBufferDescription.CPUAccessFlags = 0; - constantBufferDescription.MiscFlags = 0; - constantBufferDescription.StructureByteStride = 0; - - HRESULT result = mDevice->CreateBuffer(&constantBufferDescription, NULL, &mDriverConstantBufferPS); - ASSERT(SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create pixel shader constant buffer, result: 0x%X.", result); - } - mDeviceContext->PSSetConstantBuffers(1, 1, &mDriverConstantBufferPS); - } - - const dx_VertexConstants11 &vertexConstants = mStateManager.getVertexConstants(); - if (memcmp(&vertexConstants, &mAppliedVertexConstants, sizeof(dx_VertexConstants11)) != 0) - { - ASSERT(mDriverConstantBufferVS != nullptr); - if (mDriverConstantBufferVS) - { - mDeviceContext->UpdateSubresource(mDriverConstantBufferVS, 0, NULL, &vertexConstants, - 16, 0); - memcpy(&mAppliedVertexConstants, &vertexConstants, sizeof(dx_VertexConstants11)); - } - } - - const dx_PixelConstants11 &pixelConstants = mStateManager.getPixelConstants(); - if (memcmp(&pixelConstants, &mAppliedPixelConstants, sizeof(dx_PixelConstants11)) != 0) - { - ASSERT(mDriverConstantBufferPS != nullptr); - if (mDriverConstantBufferPS) - { - mDeviceContext->UpdateSubresource(mDriverConstantBufferPS, 0, NULL, &pixelConstants, 16, - 0); - memcpy(&mAppliedPixelConstants, &pixelConstants, sizeof(dx_PixelConstants11)); - } - } - - // GSSetConstantBuffers triggers device removal on 9_3, so we should only call it if necessary - if (programD3D.usesGeometryShader(drawMode)) - { - // needed for the point sprite geometry shader - if (mCurrentGeometryConstantBuffer != mDriverConstantBufferPS) - { - ASSERT(mDriverConstantBufferPS != nullptr); - if (mDriverConstantBufferPS) - { - mDeviceContext->GSSetConstantBuffers(0, 1, &mDriverConstantBufferPS); - mCurrentGeometryConstantBuffer = mDriverConstantBufferPS; - } - } - } - - return gl::Error(GL_NO_ERROR); -} - -void Renderer11::markAllStateDirty() -{ - TRACE_EVENT0("gpu.angle", "Renderer11::markAllStateDirty"); - - for (size_t vsamplerId = 0; vsamplerId < mForceSetVertexSamplerStates.size(); ++vsamplerId) - { - mForceSetVertexSamplerStates[vsamplerId] = true; - } - - for (size_t fsamplerId = 0; fsamplerId < mForceSetPixelSamplerStates.size(); ++fsamplerId) - { - mForceSetPixelSamplerStates[fsamplerId] = true; - } - - mStateManager.invalidateEverything(); - - mAppliedIB = NULL; - mAppliedIBFormat = DXGI_FORMAT_UNKNOWN; - mAppliedIBOffset = 0; - - mAppliedVertexShader = angle::DirtyPointer; - mAppliedGeometryShader = angle::DirtyPointer; - mAppliedPixelShader = angle::DirtyPointer; - - mAppliedNumXFBBindings = static_cast(-1); - - for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++) - { - mAppliedTFBuffers[i] = NULL; - mAppliedTFOffsets[i] = 0; - } - - memset(&mAppliedVertexConstants, 0, sizeof(dx_VertexConstants11)); - memset(&mAppliedPixelConstants, 0, sizeof(dx_PixelConstants11)); - - mInputLayoutCache.markDirty(); - - for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS; i++) - { - mCurrentConstantBufferVS[i] = static_cast(-1); - mCurrentConstantBufferVSOffset[i] = 0; - mCurrentConstantBufferVSSize[i] = 0; - mCurrentConstantBufferPS[i] = static_cast(-1); - mCurrentConstantBufferPSOffset[i] = 0; - mCurrentConstantBufferPSSize[i] = 0; - } - - mCurrentVertexConstantBuffer = NULL; - mCurrentPixelConstantBuffer = NULL; - mCurrentGeometryConstantBuffer = NULL; - - mCurrentPrimitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; + return gl::NoError(); } void Renderer11::releaseDeviceResources() { + mStateManager.deinitialize(); mStateCache.clear(); - mInputLayoutCache.clear(); - SafeDelete(mVertexDataManager); - SafeDelete(mIndexDataManager); SafeDelete(mLineLoopIB); SafeDelete(mTriangleFanIB); SafeDelete(mBlit); @@ -2383,9 +2043,9 @@ void Renderer11::releaseDeviceResources() SafeDelete(mTrim); SafeDelete(mPixelTransfer); - SafeRelease(mDriverConstantBufferVS); - SafeRelease(mDriverConstantBufferPS); - SafeRelease(mSyncQuery); + mSyncQuery.reset(); + + mCachedResolveTexture.reset(); } // set notify to true to broadcast a message to all contexts of the device loss @@ -2393,24 +2053,18 @@ bool Renderer11::testDeviceLost() { bool isLost = false; + if (!mDevice) + { + return true; + } + // GetRemovedReason is used to test if the device is removed HRESULT result = mDevice->GetDeviceRemovedReason(); - isLost = d3d11::isDeviceLostError(result); + isLost = d3d11::isDeviceLostError(result); if (isLost) { - // Log error if this is a new device lost event - if (mDeviceLost == false) - { - ERR("The D3D11 device was removed: 0x%08X", result); - } - - // ensure we note the device loss -- - // we'll probably get this done again by notifyDeviceLost - // but best to remember it! - // Note that we don't want to clear the device loss status here - // -- this needs to be done by resetDevice - mDeviceLost = true; + ERR() << "The D3D11 device was removed, " << gl::FmtHR(result); } return isLost; @@ -2419,27 +2073,24 @@ bool Renderer11::testDeviceLost() bool Renderer11::testDeviceResettable() { // determine if the device is resettable by creating a dummy device - PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice"); + PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = + (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice"); - if (D3D11CreateDevice == NULL) + if (D3D11CreateDevice == nullptr) { return false; } - ID3D11Device* dummyDevice; + ID3D11Device *dummyDevice; D3D_FEATURE_LEVEL dummyFeatureLevel; - ID3D11DeviceContext* dummyContext; + ID3D11DeviceContext *dummyContext; + UINT flags = (mCreateDebugDevice ? D3D11_CREATE_DEVICE_DEBUG : 0); ASSERT(mRequestedDriverType != D3D_DRIVER_TYPE_UNKNOWN); HRESULT result = D3D11CreateDevice( - NULL, mRequestedDriverType, NULL, - #if defined(_DEBUG) - D3D11_CREATE_DEVICE_DEBUG, - #else - 0, - #endif - mAvailableFeatureLevels.data(), static_cast(mAvailableFeatureLevels.size()), - D3D11_SDK_VERSION, &dummyDevice, &dummyFeatureLevel, &dummyContext); + nullptr, mRequestedDriverType, nullptr, flags, mAvailableFeatureLevels.data(), + static_cast(mAvailableFeatureLevels.size()), D3D11_SDK_VERSION, &dummyDevice, + &dummyFeatureLevel, &dummyContext); if (!mDevice || FAILED(result)) { @@ -2456,6 +2107,14 @@ void Renderer11::release() { RendererD3D::cleanup(); + mScratchMemoryBuffer.clear(); + + if (mAnnotator != nullptr) + { + gl::UninitializeDebugAnnotations(); + SafeDelete(mAnnotator); + } + releaseDeviceResources(); if (!mCreatedWithDeviceEXT) @@ -2468,9 +2127,8 @@ void Renderer11::release() SafeRelease(mDxgiFactory); SafeRelease(mDxgiAdapter); -#if defined(ANGLE_ENABLE_D3D11_1) + SafeRelease(mDeviceContext3); SafeRelease(mDeviceContext1); -#endif if (mDeviceContext) { @@ -2480,26 +2138,24 @@ void Renderer11::release() } SafeRelease(mDevice); -#if !defined(ANGLE_MINGW32_COMPAT) SafeRelease(mDebug); -#endif if (mD3d11Module) { FreeLibrary(mD3d11Module); - mD3d11Module = NULL; + mD3d11Module = nullptr; } if (mDxgiModule) { FreeLibrary(mDxgiModule); - mDxgiModule = NULL; + mDxgiModule = nullptr; } if (mDCompModule) { FreeLibrary(mDCompModule); - mDCompModule = NULL; + mDCompModule = nullptr; } mCompiler.release(); @@ -2515,12 +2171,10 @@ bool Renderer11::resetDevice() if (result.isError()) { - ERR("Could not reinitialize D3D11 device: %08X", result.getCode()); + ERR() << "Could not reinitialize D3D11 device: " << result; return false; } - mDeviceLost = false; - return true; } @@ -2531,8 +2185,10 @@ std::string Renderer11::getRendererDescription() const rendererString << mDescription; rendererString << " Direct3D11"; - rendererString << " vs_" << getMajorShaderModel() << "_" << getMinorShaderModel() << getShaderModelSuffix(); - rendererString << " ps_" << getMajorShaderModel() << "_" << getMinorShaderModel() << getShaderModelSuffix(); + rendererString << " vs_" << getMajorShaderModel() << "_" << getMinorShaderModel() + << getShaderModelSuffix(); + rendererString << " ps_" << getMajorShaderModel() << "_" << getMinorShaderModel() + << getShaderModelSuffix(); return rendererString.str(); } @@ -2540,12 +2196,12 @@ std::string Renderer11::getRendererDescription() const DeviceIdentifier Renderer11::getAdapterIdentifier() const { // Don't use the AdapterLuid here, since that doesn't persist across reboot. - DeviceIdentifier deviceIdentifier = { 0 }; - deviceIdentifier.VendorId = mAdapterDescription.VendorId; - deviceIdentifier.DeviceId = mAdapterDescription.DeviceId; - deviceIdentifier.SubSysId = mAdapterDescription.SubSysId; - deviceIdentifier.Revision = mAdapterDescription.Revision; - deviceIdentifier.FeatureLevel = static_cast(mRenderer11DeviceCaps.featureLevel); + DeviceIdentifier deviceIdentifier = {0}; + deviceIdentifier.VendorId = mAdapterDescription.VendorId; + deviceIdentifier.DeviceId = mAdapterDescription.DeviceId; + deviceIdentifier.SubSysId = mAdapterDescription.SubSysId; + deviceIdentifier.Revision = mAdapterDescription.Revision; + deviceIdentifier.FeatureLevel = static_cast(mRenderer11DeviceCaps.featureLevel); return deviceIdentifier; } @@ -2605,7 +2261,7 @@ bool Renderer11::getShareHandleSupport() const // We only currently support share handles with BGRA surfaces, because // chrome needs BGRA. Once chrome fixes this, we should always support them. - if (!getRendererExtensions().textureFormatBGRA8888) + if (!getNativeExtensions().textureFormatBGRA8888) { mSupportsShareHandles = false; return false; @@ -2620,7 +2276,8 @@ bool Renderer11::getShareHandleSupport() const // Qt: we don't care about the 9_3 limitation #if 0 - // Also disable share handles on Feature Level 9_3, since it doesn't support share handles on RGBA8 textures/swapchains. + // Also disable share handles on Feature Level 9_3, since it doesn't support share handles on + // RGBA8 textures/swapchains. if (mRenderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3) { mSupportsShareHandles = false; @@ -2668,15 +2325,34 @@ bool Renderer11::getShareHandleSupport() const return true; } +bool Renderer11::getNV12TextureSupport() const +{ + HRESULT result; + UINT formatSupport; + result = mDevice->CheckFormatSupport(DXGI_FORMAT_NV12, &formatSupport); + if (result == E_FAIL) + { + return false; + } + return (formatSupport & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0; +} + int Renderer11::getMajorShaderModel() const { switch (mRenderer11DeviceCaps.featureLevel) { - case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MAJOR_VERSION; // 5 - case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MAJOR_VERSION; // 4 - case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MAJOR_VERSION; // 4 - case D3D_FEATURE_LEVEL_9_3: return D3D10_SHADER_MAJOR_VERSION; // 4 - default: UNREACHABLE(); return 0; + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_SHADER_MAJOR_VERSION; // 5 + case D3D_FEATURE_LEVEL_10_1: + return D3D10_1_SHADER_MAJOR_VERSION; // 4 + case D3D_FEATURE_LEVEL_10_0: + return D3D10_SHADER_MAJOR_VERSION; // 4 + case D3D_FEATURE_LEVEL_9_3: + return D3D10_SHADER_MAJOR_VERSION; // 4 + default: + UNREACHABLE(); + return 0; } } @@ -2684,11 +2360,18 @@ int Renderer11::getMinorShaderModel() const { switch (mRenderer11DeviceCaps.featureLevel) { - case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MINOR_VERSION; // 0 - case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MINOR_VERSION; // 1 - case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MINOR_VERSION; // 0 - case D3D_FEATURE_LEVEL_9_3: return D3D10_SHADER_MINOR_VERSION; // 0 - default: UNREACHABLE(); return 0; + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_SHADER_MINOR_VERSION; // 0 + case D3D_FEATURE_LEVEL_10_1: + return D3D10_1_SHADER_MINOR_VERSION; // 1 + case D3D_FEATURE_LEVEL_10_0: + return D3D10_SHADER_MINOR_VERSION; // 0 + case D3D_FEATURE_LEVEL_9_3: + return D3D10_SHADER_MINOR_VERSION; // 0 + default: + UNREACHABLE(); + return 0; } } @@ -2696,15 +2379,22 @@ std::string Renderer11::getShaderModelSuffix() const { switch (mRenderer11DeviceCaps.featureLevel) { - case D3D_FEATURE_LEVEL_11_0: return ""; - case D3D_FEATURE_LEVEL_10_1: return ""; - case D3D_FEATURE_LEVEL_10_0: return ""; - case D3D_FEATURE_LEVEL_9_3: return "_level_9_3"; - default: UNREACHABLE(); return ""; + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return ""; + case D3D_FEATURE_LEVEL_10_1: + return ""; + case D3D_FEATURE_LEVEL_10_0: + return ""; + case D3D_FEATURE_LEVEL_9_3: + return "_level_9_3"; + default: + UNREACHABLE(); + return ""; } } -const WorkaroundsD3D &RendererD3D::getWorkarounds() const +const angle::WorkaroundsD3D &RendererD3D::getWorkarounds() const { if (!mWorkaroundsInitialized) { @@ -2715,271 +2405,301 @@ const WorkaroundsD3D &RendererD3D::getWorkarounds() const return mWorkarounds; } -gl::Error Renderer11::copyImage2D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLint level) +gl::Error Renderer11::copyImageInternal(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + RenderTargetD3D *destRenderTarget) { - const gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); - ASSERT(colorbuffer); + const gl::FramebufferAttachment *colorAttachment = framebuffer->getReadColorbuffer(); + ASSERT(colorAttachment); - RenderTarget11 *sourceRenderTarget = NULL; - gl::Error error = colorbuffer->getRenderTarget(&sourceRenderTarget); - if (error.isError()) - { - return error; - } + RenderTarget11 *sourceRenderTarget = nullptr; + ANGLE_TRY(colorAttachment->getRenderTarget(context, &sourceRenderTarget)); ASSERT(sourceRenderTarget); - ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView(); - ASSERT(source); + const d3d11::SharedSRV &source = sourceRenderTarget->getBlitShaderResourceView(); + ASSERT(source.valid()); + const d3d11::RenderTargetView &dest = + GetAs(destRenderTarget)->getRenderTargetView(); + ASSERT(dest.valid()); + + gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1); + gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1); + + const bool invertSource = UsePresentPathFast(this, colorAttachment); + if (invertSource) + { + sourceArea.y = sourceSize.height - sourceRect.y; + sourceArea.height = -sourceArea.height; + } + + gl::Box destArea(destOffset.x, destOffset.y, 0, sourceRect.width, sourceRect.height, 1); + gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1); + + // Use nearest filtering because source and destination are the same size for the direct copy. + // Convert to the unsized format before calling copyTexture. + GLenum sourceFormat = colorAttachment->getFormat().info->format; + ANGLE_TRY(mBlit->copyTexture(context, source, sourceArea, sourceSize, sourceFormat, dest, + destArea, destSize, nullptr, gl::GetUnsizedFormat(destFormat), + GL_NEAREST, false, false, false)); + + return gl::NoError(); +} + +gl::Error Renderer11::copyImage2D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) +{ TextureStorage11_2D *storage11 = GetAs(storage); ASSERT(storage11); - gl::ImageIndex index = gl::ImageIndex::Make2D(level); - RenderTargetD3D *destRenderTarget = NULL; - error = storage11->getRenderTarget(index, &destRenderTarget); - if (error.isError()) - { - return error; - } + gl::ImageIndex index = gl::ImageIndex::Make2D(level); + RenderTargetD3D *destRenderTarget = nullptr; + ANGLE_TRY(storage11->getRenderTarget(context, index, &destRenderTarget)); ASSERT(destRenderTarget); - ID3D11RenderTargetView *dest = GetAs(destRenderTarget)->getRenderTargetView(); - ASSERT(dest); + ANGLE_TRY(copyImageInternal(context, framebuffer, sourceRect, destFormat, destOffset, + destRenderTarget)); - gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1); - gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1); + storage11->markLevelDirty(level); - const bool invertSource = UsePresentPathFast(this, colorbuffer); - if (invertSource) - { - sourceArea.y = sourceSize.height - sourceRect.y; - sourceArea.height = -sourceArea.height; - } - - gl::Box destArea(destOffset.x, destOffset.y, 0, sourceRect.width, sourceRect.height, 1); - gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1); - - // Use nearest filtering because source and destination are the same size for the direct - // copy - error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, - destFormat, GL_NEAREST, false); - if (error.isError()) - { - return error; - } - - storage11->invalidateSwizzleCacheLevel(level); - - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Renderer11::copyImageCube(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLenum target, GLint level) +gl::Error Renderer11::copyImageCube(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLenum target, + GLint level) { - const gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); - ASSERT(colorbuffer); - - RenderTarget11 *sourceRenderTarget = NULL; - gl::Error error = colorbuffer->getRenderTarget(&sourceRenderTarget); - if (error.isError()) - { - return error; - } - ASSERT(sourceRenderTarget); - - ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView(); - ASSERT(source); - TextureStorage11_Cube *storage11 = GetAs(storage); ASSERT(storage11); - gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level); - RenderTargetD3D *destRenderTarget = NULL; - error = storage11->getRenderTarget(index, &destRenderTarget); - if (error.isError()) - { - return error; - } + gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level); + RenderTargetD3D *destRenderTarget = nullptr; + ANGLE_TRY(storage11->getRenderTarget(context, index, &destRenderTarget)); ASSERT(destRenderTarget); - ID3D11RenderTargetView *dest = GetAs(destRenderTarget)->getRenderTargetView(); - ASSERT(dest); + ANGLE_TRY(copyImageInternal(context, framebuffer, sourceRect, destFormat, destOffset, + destRenderTarget)); - gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1); - gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1); + storage11->markLevelDirty(level); - const bool invertSource = UsePresentPathFast(this, colorbuffer); - if (invertSource) - { - sourceArea.y = sourceSize.height - sourceRect.y; - sourceArea.height = -sourceArea.height; - } - - gl::Box destArea(destOffset.x, destOffset.y, 0, sourceRect.width, sourceRect.height, 1); - gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1); - - // Use nearest filtering because source and destination are the same size for the direct - // copy - error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, - destFormat, GL_NEAREST, false); - if (error.isError()) - { - return error; - } - - storage11->invalidateSwizzleCacheLevel(level); - - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Renderer11::copyImage3D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLint level) +gl::Error Renderer11::copyImage3D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) { - const gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); - ASSERT(colorbuffer); - - RenderTarget11 *sourceRenderTarget = NULL; - gl::Error error = colorbuffer->getRenderTarget(&sourceRenderTarget); - if (error.isError()) - { - return error; - } - ASSERT(sourceRenderTarget); - - ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView(); - ASSERT(source); - TextureStorage11_3D *storage11 = GetAs(storage); ASSERT(storage11); - gl::ImageIndex index = gl::ImageIndex::Make3D(level, destOffset.z); - RenderTargetD3D *destRenderTarget = NULL; - error = storage11->getRenderTarget(index, &destRenderTarget); - if (error.isError()) - { - return error; - } + gl::ImageIndex index = gl::ImageIndex::Make3D(level, destOffset.z); + RenderTargetD3D *destRenderTarget = nullptr; + ANGLE_TRY(storage11->getRenderTarget(context, index, &destRenderTarget)); ASSERT(destRenderTarget); - ID3D11RenderTargetView *dest = GetAs(destRenderTarget)->getRenderTargetView(); - ASSERT(dest); + ANGLE_TRY(copyImageInternal(context, framebuffer, sourceRect, destFormat, destOffset, + destRenderTarget)); - gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1); - gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1); + storage11->markLevelDirty(level); - gl::Box destArea(destOffset.x, destOffset.y, 0, sourceRect.width, sourceRect.height, 1); - gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1); - - // Use nearest filtering because source and destination are the same size for the direct - // copy - error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, - destFormat, GL_NEAREST, false); - if (error.isError()) - { - return error; - } - - storage11->invalidateSwizzleCacheLevel(level); - - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Renderer11::copyImage2DArray(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLint level) +gl::Error Renderer11::copyImage2DArray(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) { - const gl::FramebufferAttachment *colorbuffer = framebuffer->getReadColorbuffer(); - ASSERT(colorbuffer); - - RenderTarget11 *sourceRenderTarget = NULL; - gl::Error error = colorbuffer->getRenderTarget(&sourceRenderTarget); - if (error.isError()) - { - return error; - } - ASSERT(sourceRenderTarget); - - ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView(); - ASSERT(source); - TextureStorage11_2DArray *storage11 = GetAs(storage); ASSERT(storage11); - gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, destOffset.z); - RenderTargetD3D *destRenderTarget = NULL; - error = storage11->getRenderTarget(index, &destRenderTarget); - if (error.isError()) - { - return error; - } + gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, destOffset.z); + RenderTargetD3D *destRenderTarget = nullptr; + ANGLE_TRY(storage11->getRenderTarget(context, index, &destRenderTarget)); ASSERT(destRenderTarget); - ID3D11RenderTargetView *dest = GetAs(destRenderTarget)->getRenderTargetView(); - ASSERT(dest); + ANGLE_TRY(copyImageInternal(context, framebuffer, sourceRect, destFormat, destOffset, + destRenderTarget)); + storage11->markLevelDirty(level); - gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1); - gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1); + return gl::NoError(); +} - gl::Box destArea(destOffset.x, destOffset.y, 0, sourceRect.width, sourceRect.height, 1); - gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1); +gl::Error Renderer11::copyTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLenum destTarget, + GLint destLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) +{ + TextureD3D *sourceD3D = GetImplAs(source); - // Use nearest filtering because source and destination are the same size for the direct - // copy - error = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize, NULL, - destFormat, GL_NEAREST, false); - if (error.isError()) + TextureStorage *sourceStorage = nullptr; + ANGLE_TRY(sourceD3D->getNativeTexture(context, &sourceStorage)); + + TextureStorage11_2D *sourceStorage11 = GetAs(sourceStorage); + ASSERT(sourceStorage11); + + TextureStorage11 *destStorage11 = GetAs(storage); + ASSERT(destStorage11); + + // Check for fast path where a CopySubresourceRegion can be used. + if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha && !unpackFlipY && + source->getFormat(GL_TEXTURE_2D, sourceLevel).info->format == destFormat && + sourceStorage11->getFormatSet().texFormat == destStorage11->getFormatSet().texFormat) { - return error; + const TextureHelper11 *sourceResource = nullptr; + ANGLE_TRY(sourceStorage11->getResource(context, &sourceResource)); + + gl::ImageIndex sourceIndex = gl::ImageIndex::Make2D(sourceLevel); + UINT sourceSubresource = sourceStorage11->getSubresourceIndex(sourceIndex); + + const TextureHelper11 *destResource = nullptr; + ANGLE_TRY(destStorage11->getResource(context, &destResource)); + + gl::ImageIndex destIndex = gl::ImageIndex::MakeGeneric(destTarget, destLevel); + UINT destSubresource = destStorage11->getSubresourceIndex(destIndex); + + D3D11_BOX sourceBox{ + static_cast(sourceRect.x), + static_cast(sourceRect.y), + 0u, + static_cast(sourceRect.x + sourceRect.width), + static_cast(sourceRect.y + sourceRect.height), + 1u, + }; + + mDeviceContext->CopySubresourceRegion(destResource->get(), destSubresource, destOffset.x, + destOffset.y, destOffset.z, sourceResource->get(), + sourceSubresource, &sourceBox); + } + else + { + const d3d11::SharedSRV *sourceSRV = nullptr; + ANGLE_TRY(sourceStorage11->getSRVLevels(context, sourceLevel, sourceLevel, &sourceSRV)); + + gl::ImageIndex destIndex = gl::ImageIndex::MakeGeneric(destTarget, destLevel); + RenderTargetD3D *destRenderTargetD3D = nullptr; + ANGLE_TRY(destStorage11->getRenderTarget(context, destIndex, &destRenderTargetD3D)); + + RenderTarget11 *destRenderTarget11 = GetAs(destRenderTargetD3D); + + const d3d11::RenderTargetView &destRTV = destRenderTarget11->getRenderTargetView(); + ASSERT(destRTV.valid()); + + gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1); + gl::Extents sourceSize( + static_cast(source->getWidth(source->getTarget(), sourceLevel)), + static_cast(source->getHeight(source->getTarget(), sourceLevel)), 1); + if (unpackFlipY) + { + sourceArea.y += sourceArea.height; + sourceArea.height = -sourceArea.height; + } + + gl::Box destArea(destOffset.x, destOffset.y, 0, sourceRect.width, sourceRect.height, 1); + gl::Extents destSize(destRenderTarget11->getWidth(), destRenderTarget11->getHeight(), 1); + + // Use nearest filtering because source and destination are the same size for the direct + // copy + GLenum sourceFormat = source->getFormat(GL_TEXTURE_2D, sourceLevel).info->format; + ANGLE_TRY(mBlit->copyTexture(context, *sourceSRV, sourceArea, sourceSize, sourceFormat, + destRTV, destArea, destSize, nullptr, destFormat, GL_NEAREST, + false, unpackPremultiplyAlpha, unpackUnmultiplyAlpha)); } - storage11->invalidateSwizzleCacheLevel(level); + destStorage11->markLevelDirty(destLevel); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -void Renderer11::unapplyRenderTargets() +gl::Error Renderer11::copyCompressedTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + TextureStorage *storage, + GLint destLevel) { - setOneTimeRenderTarget(NULL); + TextureStorage11_2D *destStorage11 = GetAs(storage); + ASSERT(destStorage11); + + const TextureHelper11 *destResource = nullptr; + ANGLE_TRY(destStorage11->getResource(context, &destResource)); + + gl::ImageIndex destIndex = gl::ImageIndex::Make2D(destLevel); + UINT destSubresource = destStorage11->getSubresourceIndex(destIndex); + + TextureD3D *sourceD3D = GetImplAs(source); + ASSERT(sourceD3D); + + TextureStorage *sourceStorage = nullptr; + ANGLE_TRY(sourceD3D->getNativeTexture(context, &sourceStorage)); + + TextureStorage11_2D *sourceStorage11 = GetAs(sourceStorage); + ASSERT(sourceStorage11); + + const TextureHelper11 *sourceResource = nullptr; + ANGLE_TRY(sourceStorage11->getResource(context, &sourceResource)); + + gl::ImageIndex sourceIndex = gl::ImageIndex::Make2D(sourceLevel); + UINT sourceSubresource = sourceStorage11->getSubresourceIndex(sourceIndex); + + mDeviceContext->CopySubresourceRegion(destResource->get(), destSubresource, 0, 0, 0, + sourceResource->get(), sourceSubresource, nullptr); + + return gl::NoError(); } -// When finished with this rendertarget, markAllStateDirty must be called. -void Renderer11::setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView) +gl::Error Renderer11::createRenderTarget(int width, + int height, + GLenum format, + GLsizei samples, + RenderTargetD3D **outRT) { - ID3D11RenderTargetView *rtvArray[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL}; + const d3d11::Format &formatInfo = d3d11::Format::Get(format, mRenderer11DeviceCaps); - rtvArray[0] = renderTargetView; - - mDeviceContext->OMSetRenderTargets(getRendererCaps().maxDrawBuffers, rtvArray, NULL); - - // Do not preserve the serial for this one-time-use render target - for (size_t rtIndex = 0; rtIndex < ArraySize(mAppliedRTVs); rtIndex++) - { - mAppliedRTVs[rtIndex] = angle::DirtyPointer; - } - mAppliedDSV = angle::DirtyPointer; -} - -gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT) -{ - const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(format, mRenderer11DeviceCaps); - - const gl::TextureCaps &textureCaps = getRendererTextureCaps().get(format); - GLuint supportedSamples = textureCaps.getNearestSamples(samples); + const gl::TextureCaps &textureCaps = getNativeTextureCaps().get(format); + GLuint supportedSamples = textureCaps.getNearestSamples(samples); if (width > 0 && height > 0) { // Create texture resource D3D11_TEXTURE2D_DESC desc; - desc.Width = width; - desc.Height = height; - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.Format = formatInfo.texFormat; - desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples; + desc.Width = width; + desc.Height = height; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = formatInfo.texFormat; + desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples; desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; // If a rendertarget or depthstencil format exists for this texture format, // we'll flag it to allow binding that way. Shader resource views are a little @@ -2987,110 +2707,105 @@ gl::Error Renderer11::createRenderTarget(int width, int height, GLenum format, G bool bindRTV = false, bindDSV = false, bindSRV = false; bindRTV = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN); bindDSV = (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN); - if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN) + bindSRV = (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN); + + bool isMultisampledDepthStencil = bindDSV && desc.SampleDesc.Count > 1; + if (isMultisampledDepthStencil && + !mRenderer11DeviceCaps.supportsMultisampledDepthStencilSRVs) { - // Multisample targets flagged for binding as depth stencil cannot also be - // flagged for binding as SRV, so make certain not to add the SRV flag for - // these targets. - bindSRV = !(formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN && desc.SampleDesc.Count > 1); + bindSRV = false; } - desc.BindFlags = (bindRTV ? D3D11_BIND_RENDER_TARGET : 0) | - (bindDSV ? D3D11_BIND_DEPTH_STENCIL : 0) | + desc.BindFlags = (bindRTV ? D3D11_BIND_RENDER_TARGET : 0) | + (bindDSV ? D3D11_BIND_DEPTH_STENCIL : 0) | (bindSRV ? D3D11_BIND_SHADER_RESOURCE : 0); // The format must be either an RTV or a DSV ASSERT(bindRTV != bindDSV); - ID3D11Texture2D *texture = NULL; - HRESULT result = mDevice->CreateTexture2D(&desc, NULL, &texture); - if (FAILED(result)) - { - ASSERT(result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target texture, result: 0x%X.", result); - } + TextureHelper11 texture; + ANGLE_TRY(allocateTexture(desc, formatInfo, &texture)); - ID3D11ShaderResourceView *srv = NULL; + d3d11::SharedSRV srv; + d3d11::SharedSRV blitSRV; if (bindSRV) { D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = formatInfo.srvFormat; - srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS; + srvDesc.Format = formatInfo.srvFormat; + srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D + : D3D11_SRV_DIMENSION_TEXTURE2DMS; srvDesc.Texture2D.MostDetailedMip = 0; - srvDesc.Texture2D.MipLevels = 1; + srvDesc.Texture2D.MipLevels = 1; - result = mDevice->CreateShaderResourceView(texture, &srvDesc, &srv); - if (FAILED(result)) + ANGLE_TRY(allocateResource(srvDesc, texture.get(), &srv)); + + if (formatInfo.blitSRVFormat != formatInfo.srvFormat) { - ASSERT(result == E_OUTOFMEMORY); - SafeRelease(texture); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target shader resource view, result: 0x%X.", result); + D3D11_SHADER_RESOURCE_VIEW_DESC blitSRVDesc; + blitSRVDesc.Format = formatInfo.blitSRVFormat; + blitSRVDesc.ViewDimension = (supportedSamples == 0) + ? D3D11_SRV_DIMENSION_TEXTURE2D + : D3D11_SRV_DIMENSION_TEXTURE2DMS; + blitSRVDesc.Texture2D.MostDetailedMip = 0; + blitSRVDesc.Texture2D.MipLevels = 1; + + ANGLE_TRY(allocateResource(blitSRVDesc, texture.get(), &blitSRV)); + } + else + { + blitSRV = srv.makeCopy(); } } if (bindDSV) { D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsvDesc.Format = formatInfo.dsvFormat; - dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS; + dsvDesc.Format = formatInfo.dsvFormat; + dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D + : D3D11_DSV_DIMENSION_TEXTURE2DMS; dsvDesc.Texture2D.MipSlice = 0; - dsvDesc.Flags = 0; + dsvDesc.Flags = 0; - ID3D11DepthStencilView *dsv = NULL; - result = mDevice->CreateDepthStencilView(texture, &dsvDesc, &dsv); - if (FAILED(result)) - { - ASSERT(result == E_OUTOFMEMORY); - SafeRelease(texture); - SafeRelease(srv); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target depth stencil view, result: 0x%X.", result); - } + d3d11::DepthStencilView dsv; + ANGLE_TRY(allocateResource(dsvDesc, texture.get(), &dsv)); - *outRT = new TextureRenderTarget11(dsv, texture, srv, format, width, height, 1, supportedSamples); - - SafeRelease(dsv); + *outRT = new TextureRenderTarget11(std::move(dsv), texture, srv, format, formatInfo, + width, height, 1, supportedSamples); } else if (bindRTV) { D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = formatInfo.rtvFormat; - rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS; + rtvDesc.Format = formatInfo.rtvFormat; + rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D + : D3D11_RTV_DIMENSION_TEXTURE2DMS; rtvDesc.Texture2D.MipSlice = 0; - ID3D11RenderTargetView *rtv = NULL; - result = mDevice->CreateRenderTargetView(texture, &rtvDesc, &rtv); - if (FAILED(result)) + d3d11::RenderTargetView rtv; + ANGLE_TRY(allocateResource(rtvDesc, texture.get(), &rtv)); + + if (formatInfo.dataInitializerFunction != nullptr) { - ASSERT(result == E_OUTOFMEMORY); - SafeRelease(texture); - SafeRelease(srv); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target render target view, result: 0x%X.", result); + const float clearValues[4] = {0.0f, 0.0f, 0.0f, 1.0f}; + mDeviceContext->ClearRenderTargetView(rtv.get(), clearValues); } - if (formatInfo.dataInitializerFunction != NULL) - { - const float clearValues[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; - mDeviceContext->ClearRenderTargetView(rtv, clearValues); - } - - *outRT = new TextureRenderTarget11(rtv, texture, srv, format, width, height, 1, supportedSamples); - - SafeRelease(rtv); + *outRT = new TextureRenderTarget11(std::move(rtv), texture, srv, blitSRV, format, + formatInfo, width, height, 1, supportedSamples); } else { UNREACHABLE(); } - - SafeRelease(texture); - SafeRelease(srv); } else { - *outRT = new TextureRenderTarget11(reinterpret_cast(NULL), NULL, NULL, format, width, height, 1, supportedSamples); + *outRT = new TextureRenderTarget11(d3d11::RenderTargetView(), TextureHelper11(), + d3d11::SharedSRV(), d3d11::SharedSRV(), format, + d3d11::Format::Get(GL_NONE, mRenderer11DeviceCaps), + width, height, 1, supportedSamples); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Renderer11::createRenderTargetCopy(RenderTargetD3D *source, RenderTargetD3D **outRT) @@ -3098,58 +2813,35 @@ gl::Error Renderer11::createRenderTargetCopy(RenderTargetD3D *source, RenderTarg ASSERT(source != nullptr); RenderTargetD3D *newRT = nullptr; - gl::Error error = createRenderTarget(source->getWidth(), source->getHeight(), - source->getInternalFormat(), source->getSamples(), &newRT); - if (error.isError()) - { - return error; - } + ANGLE_TRY(createRenderTarget(source->getWidth(), source->getHeight(), + source->getInternalFormat(), source->getSamples(), &newRT)); RenderTarget11 *source11 = GetAs(source); RenderTarget11 *dest11 = GetAs(newRT); - mDeviceContext->CopySubresourceRegion(dest11->getTexture(), dest11->getSubresourceIndex(), 0, 0, - 0, source11->getTexture(), + mDeviceContext->CopySubresourceRegion(dest11->getTexture().get(), dest11->getSubresourceIndex(), + 0, 0, 0, source11->getTexture().get(), source11->getSubresourceIndex(), nullptr); *outRT = newRT; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -FramebufferImpl *Renderer11::createFramebuffer(const gl::Framebuffer::Data &data) -{ - return new Framebuffer11(data, this); -} - -ShaderImpl *Renderer11::createShader(const gl::Shader::Data &data) -{ - return new ShaderD3D(data); -} - -ProgramImpl *Renderer11::createProgram(const gl::Program::Data &data) -{ - return new ProgramD3D(data, this); -} - -gl::Error Renderer11::loadExecutable(const void *function, +gl::Error Renderer11::loadExecutable(const uint8_t *function, size_t length, - ShaderType type, + gl::ShaderType type, const std::vector &streamOutVaryings, bool separatedOutputBuffers, ShaderExecutableD3D **outExecutable) { + ShaderData shaderData(function, length); + switch (type) { - case SHADER_VERTEX: + case gl::SHADER_VERTEX: { - ID3D11VertexShader *vertexShader = NULL; - ID3D11GeometryShader *streamOutShader = NULL; - - HRESULT result = mDevice->CreateVertexShader(function, length, NULL, &vertexShader); - ASSERT(SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create vertex shader, result: 0x%X.", result); - } + d3d11::VertexShader vertexShader; + d3d11::GeometryShader streamOutShader; + ANGLE_TRY(allocateResource(shaderData, &vertexShader)); if (!streamOutVaryings.empty()) { @@ -3163,88 +2855,80 @@ gl::Error Renderer11::loadExecutable(const void *function, entry.SemanticName = streamOutVarying.semanticName.c_str(); entry.SemanticIndex = streamOutVarying.semanticIndex; entry.StartComponent = 0; - entry.ComponentCount = static_cast(streamOutVarying.componentCount); - entry.OutputSlot = static_cast( + entry.ComponentCount = static_cast(streamOutVarying.componentCount); + entry.OutputSlot = static_cast( (separatedOutputBuffers ? streamOutVarying.outputSlot : 0)); soDeclaration.push_back(entry); } - result = mDevice->CreateGeometryShaderWithStreamOutput( - function, static_cast(length), soDeclaration.data(), - static_cast(soDeclaration.size()), NULL, 0, 0, NULL, - &streamOutShader); - ASSERT(SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create steam output shader, result: 0x%X.", result); - } + ANGLE_TRY(allocateResource(shaderData, &soDeclaration, &streamOutShader)); } - *outExecutable = new ShaderExecutable11(function, length, vertexShader, streamOutShader); + *outExecutable = new ShaderExecutable11(function, length, std::move(vertexShader), + std::move(streamOutShader)); } break; - case SHADER_PIXEL: + case gl::SHADER_FRAGMENT: { - ID3D11PixelShader *pixelShader = NULL; - - HRESULT result = mDevice->CreatePixelShader(function, length, NULL, &pixelShader); - ASSERT(SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create pixel shader, result: 0x%X.", result); - } - - *outExecutable = new ShaderExecutable11(function, length, pixelShader); + d3d11::PixelShader pixelShader; + ANGLE_TRY(allocateResource(shaderData, &pixelShader)); + *outExecutable = new ShaderExecutable11(function, length, std::move(pixelShader)); } break; - case SHADER_GEOMETRY: + case gl::SHADER_GEOMETRY: { - ID3D11GeometryShader *geometryShader = NULL; - - HRESULT result = mDevice->CreateGeometryShader(function, length, NULL, &geometryShader); - ASSERT(SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create geometry shader, result: 0x%X.", result); - } - - *outExecutable = new ShaderExecutable11(function, length, geometryShader); + d3d11::GeometryShader geometryShader; + ANGLE_TRY(allocateResource(shaderData, &geometryShader)); + *outExecutable = new ShaderExecutable11(function, length, std::move(geometryShader)); } break; - default: - UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + case gl::SHADER_COMPUTE: + { + d3d11::ComputeShader computeShader; + ANGLE_TRY(allocateResource(shaderData, &computeShader)); + *outExecutable = new ShaderExecutable11(function, length, std::move(computeShader)); + } + break; + default: + UNREACHABLE(); + return gl::InternalError(); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, - ShaderType type, + gl::ShaderType type, const std::vector &streamOutVaryings, bool separatedOutputBuffers, - const D3DCompilerWorkarounds &workarounds, + const angle::CompilerWorkaroundsD3D &workarounds, ShaderExecutableD3D **outExectuable) { - const char *profileType = NULL; + std::stringstream profileStream; + switch (type) { - case SHADER_VERTEX: - profileType = "vs"; - break; - case SHADER_PIXEL: - profileType = "ps"; - break; - case SHADER_GEOMETRY: - profileType = "gs"; - break; - default: - UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + case gl::SHADER_VERTEX: + profileStream << "vs"; + break; + case gl::SHADER_FRAGMENT: + profileStream << "ps"; + break; + case gl::SHADER_GEOMETRY: + profileStream << "gs"; + break; + case gl::SHADER_COMPUTE: + profileStream << "cs"; + break; + default: + UNREACHABLE(); + return gl::InternalError(); } - std::string profile = FormatString("%s_%d_%d%s", profileType, getMajorShaderModel(), getMinorShaderModel(), getShaderModelSuffix().c_str()); + profileStream << "_" << getMajorShaderModel() << "_" << getMinorShaderModel() + << getShaderModelSuffix(); + std::string profile = profileStream.str(); UINT flags = D3DCOMPILE_OPTIMIZATION_LEVEL2; @@ -3260,11 +2944,12 @@ gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, if (workarounds.enableIEEEStrictness) flags |= D3DCOMPILE_IEEE_STRICTNESS; - // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options. + // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders + // when it would otherwise pass with alternative options. // Try the default flags first and if compilation fails, try some alternatives. std::vector configs; - configs.push_back(CompileConfig(flags, "default" )); - configs.push_back(CompileConfig(flags | D3DCOMPILE_SKIP_VALIDATION, "skip validation" )); + configs.push_back(CompileConfig(flags, "default")); + configs.push_back(CompileConfig(flags | D3DCOMPILE_SKIP_VALIDATION, "skip validation")); configs.push_back(CompileConfig(flags | D3DCOMPILE_SKIP_OPTIMIZATION, "skip optimization")); if (getMajorShaderModel() == 4 && getShaderModelSuffix() != "") @@ -3276,26 +2961,26 @@ gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, CompileConfig(flags | D3DCOMPILE_AVOID_FLOW_CONTROL, "avoid flow control")); } - D3D_SHADER_MACRO loopMacros[] = { {"ANGLE_ENABLE_LOOP_FLATTEN", "1"}, {0, 0} }; + D3D_SHADER_MACRO loopMacros[] = {{"ANGLE_ENABLE_LOOP_FLATTEN", "1"}, {0, 0}}; - ID3DBlob *binary = NULL; + // TODO(jmadill): Use ComPtr? + ID3DBlob *binary = nullptr; std::string debugInfo; - gl::Error error = mCompiler.compileToBinary(infoLog, shaderHLSL, profile, configs, loopMacros, &binary, &debugInfo); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mCompiler.compileToBinary(infoLog, shaderHLSL, profile, configs, loopMacros, &binary, + &debugInfo)); - // It's possible that binary is NULL if the compiler failed in all configurations. Set the executable to NULL - // and return GL_NO_ERROR to signify that there was a link error but the internal state is still OK. + // It's possible that binary is NULL if the compiler failed in all configurations. Set the + // executable to NULL and return GL_NO_ERROR to signify that there was a link error but the + // internal state is still OK. if (!binary) { - *outExectuable = NULL; - return gl::Error(GL_NO_ERROR); + *outExectuable = nullptr; + return gl::NoError(); } - error = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type, - streamOutVaryings, separatedOutputBuffers, outExectuable); + gl::Error error = loadExecutable(reinterpret_cast(binary->GetBufferPointer()), + binary->GetBufferSize(), type, streamOutVaryings, + separatedOutputBuffers, outExectuable); SafeRelease(binary); if (error.isError()) @@ -3308,12 +2993,17 @@ gl::Error Renderer11::compileToExecutable(gl::InfoLog &infoLog, (*outExectuable)->appendDebugInfo(debugInfo); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); +} + +gl::Error Renderer11::ensureHLSLCompilerInitialized() +{ + return mCompiler.ensureInitialized(); } UniformStorageD3D *Renderer11::createUniformStorage(size_t storageSize) { - return new UniformStorage11(this, storageSize); + return new UniformStorage11(storageSize); } VertexBuffer *Renderer11::createVertexBuffer() @@ -3326,45 +3016,20 @@ IndexBuffer *Renderer11::createIndexBuffer() return new IndexBuffer11(this); } -BufferImpl *Renderer11::createBuffer() +StreamProducerImpl *Renderer11::createStreamProducerD3DTextureNV12( + egl::Stream::ConsumerType consumerType, + const egl::AttributeMap &attribs) { - Buffer11 *buffer = new Buffer11(this); - mAliveBuffers.insert(buffer); - return buffer; -} - -VertexArrayImpl *Renderer11::createVertexArray(const gl::VertexArray::Data &data) -{ - return new VertexArray11(data); -} - -QueryImpl *Renderer11::createQuery(GLenum type) -{ - return new Query11(this, type); -} - -FenceNVImpl *Renderer11::createFenceNV() -{ - return new FenceNV11(this); -} - -FenceSyncImpl *Renderer11::createFenceSync() -{ - return new FenceSync11(this); -} - -TransformFeedbackImpl* Renderer11::createTransformFeedback() -{ - return new TransformFeedbackD3D(); + return new StreamProducerNV12(this); } bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const { - ASSERT(getRendererExtensions().pixelBufferObject); + ASSERT(getNativeExtensions().pixelBufferObject); - const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat); - const d3d11::TextureFormat &d3d11FormatInfo = d3d11::GetTextureFormatInfo(internalFormat, mRenderer11DeviceCaps); - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3d11FormatInfo.texFormat); + const gl::InternalFormat &internalFormatInfo = gl::GetSizedInternalFormatInfo(internalFormat); + const d3d11::Format &d3d11FormatInfo = + d3d11::Format::Get(internalFormat, mRenderer11DeviceCaps); // sRGB formats do not work with D3D11 buffer SRVs if (internalFormatInfo.colorEncoding == GL_SRGB) @@ -3385,7 +3050,19 @@ bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const } // We don't support formats which we can't represent without conversion - if (dxgiFormatInfo.internalFormat != internalFormat) + if (d3d11FormatInfo.format().glInternalFormat != internalFormat) + { + return false; + } + + // Buffer SRV creation for this format was not working on Windows 10. + if (d3d11FormatInfo.texFormat == DXGI_FORMAT_B5G5R5A1_UNORM) + { + return false; + } + + // This format is not supported as a buffer SRV. + if (d3d11FormatInfo.texFormat == DXGI_FORMAT_A8_UNORM) { return false; } @@ -3393,11 +3070,17 @@ bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const return true; } -gl::Error Renderer11::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget, - GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) +gl::Error Renderer11::fastCopyBufferToTexture(const gl::Context *context, + const gl::PixelUnpackState &unpack, + unsigned int offset, + RenderTargetD3D *destRenderTarget, + GLenum destinationFormat, + GLenum sourcePixelsType, + const gl::Box &destArea) { ASSERT(supportsFastCopyBufferToTexture(destinationFormat)); - return mPixelTransfer->copyBufferToTexture(unpack, offset, destRenderTarget, destinationFormat, sourcePixelsType, destArea); + return mPixelTransfer->copyBufferToTexture(context, unpack, offset, destRenderTarget, + destinationFormat, sourcePixelsType, destArea); } ImageD3D *Renderer11::createImage() @@ -3405,31 +3088,44 @@ ImageD3D *Renderer11::createImage() return new Image11(this); } -gl::Error Renderer11::generateMipmap(ImageD3D *dest, ImageD3D *src) +gl::Error Renderer11::generateMipmap(const gl::Context *context, ImageD3D *dest, ImageD3D *src) { Image11 *dest11 = GetAs(dest); - Image11 *src11 = GetAs(src); - return Image11::generateMipmap(dest11, src11); + Image11 *src11 = GetAs(src); + return Image11::GenerateMipmap(context, dest11, src11, mRenderer11DeviceCaps); } -gl::Error Renderer11::generateMipmapsUsingD3D(TextureStorage *storage, - const gl::TextureState &textureState) +gl::Error Renderer11::generateMipmapUsingD3D(const gl::Context *context, + TextureStorage *storage, + const gl::TextureState &textureState) { TextureStorage11 *storage11 = GetAs(storage); ASSERT(storage11->isRenderTarget()); ASSERT(storage11->supportsNativeMipmapFunction()); - ID3D11ShaderResourceView *srv; - gl::Error error = storage11->getSRVLevels(textureState.baseLevel, textureState.maxLevel, &srv); - if (error.isError()) - { - return error; - } + const d3d11::SharedSRV *srv = nullptr; + ANGLE_TRY(storage11->getSRVLevels(context, textureState.getEffectiveBaseLevel(), + textureState.getEffectiveMaxLevel(), &srv)); - mDeviceContext->GenerateMips(srv); + mDeviceContext->GenerateMips(srv->get()); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); +} + +gl::Error Renderer11::copyImage(const gl::Context *context, + ImageD3D *dest, + ImageD3D *source, + const gl::Rectangle &sourceRect, + const gl::Offset &destOffset, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) +{ + Image11 *dest11 = GetAs(dest); + Image11 *src11 = GetAs(source); + return Image11::CopyImage(context, dest11, src11, sourceRect, destOffset, unpackFlipY, + unpackPremultiplyAlpha, unpackUnmultiplyAlpha, mRenderer11DeviceCaps); } TextureStorage *Renderer11::createTextureStorage2D(SwapChainD3D *swapChain) @@ -3438,53 +3134,75 @@ TextureStorage *Renderer11::createTextureStorage2D(SwapChainD3D *swapChain) return new TextureStorage11_2D(this, swapChain11); } -TextureStorage *Renderer11::createTextureStorageEGLImage(EGLImageD3D *eglImage) +TextureStorage *Renderer11::createTextureStorageEGLImage(EGLImageD3D *eglImage, + RenderTargetD3D *renderTargetD3D) { - return new TextureStorage11_EGLImage(this, eglImage); + return new TextureStorage11_EGLImage(this, eglImage, GetAs(renderTargetD3D)); } -TextureStorage *Renderer11::createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly) +TextureStorage *Renderer11::createTextureStorageExternal( + egl::Stream *stream, + const egl::Stream::GLTextureDescription &desc) { - return new TextureStorage11_2D(this, internalformat, renderTarget, width, height, levels, hintLevelZeroOnly); + return new TextureStorage11_External(this, stream, desc); } -TextureStorage *Renderer11::createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly) +TextureStorage *Renderer11::createTextureStorage2D(GLenum internalformat, + bool renderTarget, + GLsizei width, + GLsizei height, + int levels, + bool hintLevelZeroOnly) { - return new TextureStorage11_Cube(this, internalformat, renderTarget, size, levels, hintLevelZeroOnly); + return new TextureStorage11_2D(this, internalformat, renderTarget, width, height, levels, + hintLevelZeroOnly); } -TextureStorage *Renderer11::createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) +TextureStorage *Renderer11::createTextureStorageCube(GLenum internalformat, + bool renderTarget, + int size, + int levels, + bool hintLevelZeroOnly) { - return new TextureStorage11_3D(this, internalformat, renderTarget, width, height, depth, levels); + return new TextureStorage11_Cube(this, internalformat, renderTarget, size, levels, + hintLevelZeroOnly); } -TextureStorage *Renderer11::createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) +TextureStorage *Renderer11::createTextureStorage3D(GLenum internalformat, + bool renderTarget, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels) { - return new TextureStorage11_2DArray(this, internalformat, renderTarget, width, height, depth, levels); + return new TextureStorage11_3D(this, internalformat, renderTarget, width, height, depth, + levels); } -TextureImpl *Renderer11::createTexture(GLenum target) +TextureStorage *Renderer11::createTextureStorage2DArray(GLenum internalformat, + bool renderTarget, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels) { - switch(target) - { - case GL_TEXTURE_2D: return new TextureD3D_2D(this); - case GL_TEXTURE_CUBE_MAP: return new TextureD3D_Cube(this); - case GL_TEXTURE_3D: return new TextureD3D_3D(this); - case GL_TEXTURE_2D_ARRAY: return new TextureD3D_2DArray(this); - default: - UNREACHABLE(); - } - - return NULL; + return new TextureStorage11_2DArray(this, internalformat, renderTarget, width, height, depth, + levels); } -RenderbufferImpl *Renderer11::createRenderbuffer() +TextureStorage *Renderer11::createTextureStorage2DMultisample(GLenum internalformat, + GLsizei width, + GLsizei height, + int levels, + int samples, + bool fixedSampleLocations) { - RenderbufferD3D *renderbuffer = new RenderbufferD3D(this); - return renderbuffer; + return new TextureStorage11_2DMultisample(this, internalformat, width, height, levels, samples, + fixedSampleLocations); } -gl::Error Renderer11::readFromAttachment(const gl::FramebufferAttachment &srcAttachment, +gl::Error Renderer11::readFromAttachment(const gl::Context *context, + const gl::FramebufferAttachment &srcAttachment, const gl::Rectangle &sourceArea, GLenum format, GLenum type, @@ -3497,17 +3215,11 @@ gl::Error Renderer11::readFromAttachment(const gl::FramebufferAttachment &srcAtt const bool invertTexture = UsePresentPathFast(this, &srcAttachment); - RenderTargetD3D *renderTarget = nullptr; - gl::Error error = srcAttachment.getRenderTarget(&renderTarget); - if (error.isError()) - { - return error; - } + RenderTarget11 *rt11 = nullptr; + ANGLE_TRY(srcAttachment.getRenderTarget(context, &rt11)); + ASSERT(rt11->getTexture().valid()); - RenderTarget11 *rt11 = GetAs(renderTarget); - ASSERT(rt11->getTexture()); - - TextureHelper11 textureHelper = TextureHelper11::MakeAndReference(rt11->getTexture()); + const TextureHelper11 &textureHelper = rt11->getTexture(); unsigned int sourceSubResource = rt11->getSubresourceIndex(); const gl::Extents &texSize = textureHelper.getExtents(); @@ -3535,52 +3247,42 @@ gl::Error Renderer11::readFromAttachment(const gl::FramebufferAttachment &srcAtt if (safeArea.width == 0 || safeArea.height == 0) { // no work to do - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Extents safeSize(safeArea.width, safeArea.height, 1); - auto errorOrResult = CreateStagingTexture(textureHelper.getTextureType(), - textureHelper.getFormat(), safeSize, mDevice); - if (errorOrResult.isError()) - { - return errorOrResult.getError(); - } + TextureHelper11 stagingHelper; + ANGLE_TRY_RESULT( + createStagingTexture(textureHelper.getTextureType(), textureHelper.getFormatSet(), safeSize, + StagingAccess::READ), + stagingHelper); - TextureHelper11 stagingHelper(errorOrResult.getResult()); TextureHelper11 resolvedTextureHelper; // "srcTexture" usually points to the source texture. // For 2D multisampled textures, it points to the multisampled resolve texture. const TextureHelper11 *srcTexture = &textureHelper; - if (textureHelper.getTextureType() == GL_TEXTURE_2D && textureHelper.getSampleCount() > 1) + if (textureHelper.is2D() && textureHelper.getSampleCount() > 1) { D3D11_TEXTURE2D_DESC resolveDesc; resolveDesc.Width = static_cast(texSize.width); resolveDesc.Height = static_cast(texSize.height); - resolveDesc.MipLevels = 1; - resolveDesc.ArraySize = 1; + resolveDesc.MipLevels = 1; + resolveDesc.ArraySize = 1; resolveDesc.Format = textureHelper.getFormat(); - resolveDesc.SampleDesc.Count = 1; + resolveDesc.SampleDesc.Count = 1; resolveDesc.SampleDesc.Quality = 0; - resolveDesc.Usage = D3D11_USAGE_DEFAULT; - resolveDesc.BindFlags = 0; - resolveDesc.CPUAccessFlags = 0; - resolveDesc.MiscFlags = 0; + resolveDesc.Usage = D3D11_USAGE_DEFAULT; + resolveDesc.BindFlags = 0; + resolveDesc.CPUAccessFlags = 0; + resolveDesc.MiscFlags = 0; - ID3D11Texture2D *resolveTex2D = nullptr; - HRESULT result = mDevice->CreateTexture2D(&resolveDesc, nullptr, &resolveTex2D); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, - "Renderer11::readTextureData failed to create internal resolve " - "texture for ReadPixels, HRESULT: 0x%X.", - result); - } + ANGLE_TRY( + allocateTexture(resolveDesc, textureHelper.getFormatSet(), &resolvedTextureHelper)); - mDeviceContext->ResolveSubresource(resolveTex2D, 0, textureHelper.getTexture2D(), + mDeviceContext->ResolveSubresource(resolvedTextureHelper.get(), 0, textureHelper.get(), sourceSubResource, textureHelper.getFormat()); - resolvedTextureHelper = TextureHelper11::MakeAndReference(resolveTex2D); sourceSubResource = 0; srcTexture = &resolvedTextureHelper; @@ -3594,132 +3296,66 @@ gl::Error Renderer11::readFromAttachment(const gl::FramebufferAttachment &srcAtt // Select the correct layer from a 3D attachment srcBox.front = 0; - if (textureHelper.getTextureType() == GL_TEXTURE_3D) + if (textureHelper.is3D()) { srcBox.front = static_cast(srcAttachment.layer()); } srcBox.back = srcBox.front + 1; - mDeviceContext->CopySubresourceRegion(stagingHelper.getResource(), 0, 0, 0, 0, - srcTexture->getResource(), sourceSubResource, &srcBox); + mDeviceContext->CopySubresourceRegion(stagingHelper.get(), 0, 0, 0, 0, srcTexture->get(), + sourceSubResource, &srcBox); - if (invertTexture) + gl::Buffer *packBuffer = context->getGLState().getTargetBuffer(gl::BufferBinding::PixelPack); + if (!invertTexture) { - gl::PixelPackState invertTexturePack; - - // Create a new PixelPackState with reversed row order. Note that we can't just assign - // 'invertTexturePack' to be 'pack' (or memcpy) since that breaks the ref counting/object - // tracking in the 'pixelBuffer' members, causing leaks. Instead we must use - // pixelBuffer.set() twice, which performs the addRef/release correctly - invertTexturePack.alignment = pack.alignment; - invertTexturePack.pixelBuffer.set(pack.pixelBuffer.get()); - invertTexturePack.reverseRowOrder = !pack.reverseRowOrder; - - PackPixelsParams packParams(safeArea, format, type, outputPitch, invertTexturePack, 0); - error = packPixels(stagingHelper, packParams, pixelsOut); - - invertTexturePack.pixelBuffer.set(nullptr); - - return error; - } - else - { - PackPixelsParams packParams(safeArea, format, type, outputPitch, pack, 0); + PackPixelsParams packParams(safeArea, format, type, outputPitch, pack, packBuffer, 0); return packPixels(stagingHelper, packParams, pixelsOut); } + + // Create a new PixelPackState with reversed row order. Note that we can't just assign + // 'invertTexturePack' to be 'pack' (or memcpy) since that breaks the ref counting/object + // tracking in the 'pixelBuffer' members, causing leaks. Instead we must use + // pixelBuffer.set() twice, which performs the addRef/release correctly + gl::PixelPackState invertTexturePack; + invertTexturePack.alignment = pack.alignment; + invertTexturePack.reverseRowOrder = !pack.reverseRowOrder; + + PackPixelsParams packParams(safeArea, format, type, outputPitch, invertTexturePack, packBuffer, + 0); + gl::Error error = packPixels(stagingHelper, packParams, pixelsOut); + ANGLE_TRY(error); + return gl::NoError(); } gl::Error Renderer11::packPixels(const TextureHelper11 &textureHelper, const PackPixelsParams ¶ms, uint8_t *pixelsOut) { - ID3D11Resource *readResource = textureHelper.getResource(); + ID3D11Resource *readResource = textureHelper.get(); D3D11_MAPPED_SUBRESOURCE mapping; HRESULT hr = mDeviceContext->Map(readResource, 0, D3D11_MAP_READ, 0, &mapping); if (FAILED(hr)) { ASSERT(hr == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal texture for reading, result: 0x%X.", hr); + return gl::OutOfMemory() << "Failed to map internal texture for reading, " << gl::FmtHR(hr); } - uint8_t *source; - int inputPitch; - if (params.pack.reverseRowOrder) - { - source = static_cast(mapping.pData) + mapping.RowPitch * (params.area.height - 1); - inputPitch = -static_cast(mapping.RowPitch); - } - else - { - source = static_cast(mapping.pData); - inputPitch = static_cast(mapping.RowPitch); - } + uint8_t *source = static_cast(mapping.pData); + int inputPitch = static_cast(mapping.RowPitch); - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(textureHelper.getFormat()); - const gl::InternalFormat &sourceFormatInfo = gl::GetInternalFormatInfo(dxgiFormatInfo.internalFormat); - if (sourceFormatInfo.format == params.format && sourceFormatInfo.type == params.type) - { - uint8_t *dest = pixelsOut + params.offset; - for (int y = 0; y < params.area.height; y++) - { - memcpy(dest + y * params.outputPitch, source + y * inputPitch, params.area.width * sourceFormatInfo.pixelBytes); - } - } - else - { - ColorCopyFunction fastCopyFunc = - dxgiFormatInfo.getFastCopyFunction(params.format, params.type); - GLenum sizedDestInternalFormat = gl::GetSizedInternalFormat(params.format, params.type); - const gl::InternalFormat &destFormatInfo = gl::GetInternalFormatInfo(sizedDestInternalFormat); + const auto &formatInfo = textureHelper.getFormatSet(); + ASSERT(formatInfo.format().glInternalFormat != GL_NONE); - if (fastCopyFunc) - { - // Fast copy is possible through some special function - for (int y = 0; y < params.area.height; y++) - { - for (int x = 0; x < params.area.width; x++) - { - uint8_t *dest = pixelsOut + params.offset + y * params.outputPitch + x * destFormatInfo.pixelBytes; - const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes; - - fastCopyFunc(src, dest); - } - } - } - else - { - ColorReadFunction colorReadFunction = dxgiFormatInfo.colorReadFunction; - ColorWriteFunction colorWriteFunction = GetColorWriteFunction(params.format, params.type); - - uint8_t temp[16]; // Maximum size of any Color type used. - static_assert(sizeof(temp) >= sizeof(gl::ColorF) && - sizeof(temp) >= sizeof(gl::ColorUI) && - sizeof(temp) >= sizeof(gl::ColorI), - "Unexpected size of gl::Color struct."); - - for (int y = 0; y < params.area.height; y++) - { - for (int x = 0; x < params.area.width; x++) - { - uint8_t *dest = pixelsOut + params.offset + y * params.outputPitch + x * destFormatInfo.pixelBytes; - const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes; - - // readFunc and writeFunc will be using the same type of color, CopyTexImage - // will not allow the copy otherwise. - colorReadFunction(src, temp); - colorWriteFunction(temp, dest); - } - } - } - } + PackPixels(params, formatInfo.format(), inputPitch, source, pixelsOut); mDeviceContext->Unmap(readResource, 0); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn, +gl::Error Renderer11::blitRenderbufferRect(const gl::Context *context, + const gl::Rectangle &readRectIn, const gl::Rectangle &drawRectIn, RenderTargetD3D *readRenderTarget, RenderTargetD3D *drawRenderTarget, @@ -3735,63 +3371,64 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn, ASSERT(colorBlit != (depthBlit || stencilBlit)); RenderTarget11 *drawRenderTarget11 = GetAs(drawRenderTarget); - if (!drawRenderTarget) + if (!drawRenderTarget11) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal draw render target from the draw framebuffer."); + return gl::OutOfMemory() + << "Failed to retrieve the internal draw render target from the draw framebuffer."; } - ID3D11Resource *drawTexture = drawRenderTarget11->getTexture(); - unsigned int drawSubresource = drawRenderTarget11->getSubresourceIndex(); - ID3D11RenderTargetView *drawRTV = drawRenderTarget11->getRenderTargetView(); - ID3D11DepthStencilView *drawDSV = drawRenderTarget11->getDepthStencilView(); + const TextureHelper11 &drawTexture = drawRenderTarget11->getTexture(); + unsigned int drawSubresource = drawRenderTarget11->getSubresourceIndex(); RenderTarget11 *readRenderTarget11 = GetAs(readRenderTarget); - if (!readRenderTarget) + if (!readRenderTarget11) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal read render target from the read framebuffer."); + return gl::OutOfMemory() + << "Failed to retrieve the internal read render target from the read framebuffer."; } - ID3D11Resource *readTexture = NULL; - ID3D11ShaderResourceView *readSRV = NULL; - unsigned int readSubresource = 0; - if (readRenderTarget->getSamples() > 0) + TextureHelper11 readTexture; + unsigned int readSubresource = 0; + d3d11::SharedSRV readSRV; + + if (readRenderTarget->isMultisampled()) { - ID3D11Resource *unresolvedResource = readRenderTarget11->getTexture(); - ID3D11Texture2D *unresolvedTexture = d3d11::DynamicCastComObject(unresolvedResource); + ANGLE_TRY_RESULT( + resolveMultisampledTexture(context, readRenderTarget11, depthBlit, stencilBlit), + readTexture); - if (unresolvedTexture) + if (!stencilBlit) { - readTexture = resolveMultisampledTexture(unresolvedTexture, readRenderTarget11->getSubresourceIndex()); - readSubresource = 0; + const auto &readFormatSet = readTexture.getFormatSet(); - SafeRelease(unresolvedTexture); + D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc; + viewDesc.Format = readFormatSet.srvFormat; + viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + viewDesc.Texture2D.MipLevels = 1; + viewDesc.Texture2D.MostDetailedMip = 0; - HRESULT hresult = mDevice->CreateShaderResourceView(readTexture, NULL, &readSRV); - if (FAILED(hresult)) - { - SafeRelease(readTexture); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create shader resource view to resolve multisampled framebuffer."); - } + ANGLE_TRY(allocateResource(viewDesc, readTexture.get(), &readSRV)); } } else { - readTexture = readRenderTarget11->getTexture(); - readTexture->AddRef(); + ASSERT(readRenderTarget11); + readTexture = readRenderTarget11->getTexture(); readSubresource = readRenderTarget11->getSubresourceIndex(); - readSRV = readRenderTarget11->getShaderResourceView(); - readSRV->AddRef(); + readSRV = readRenderTarget11->getBlitShaderResourceView().makeCopy(); + if (!readSRV.valid()) + { + ASSERT(depthBlit || stencilBlit); + readSRV = readRenderTarget11->getShaderResourceView().makeCopy(); + } + ASSERT(readSRV.valid()); } - if (!readTexture || !readSRV) - { - SafeRelease(readTexture); - SafeRelease(readSRV); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal read render target view from the read render target."); - } + // Stencil blits don't use shaders. + ASSERT(readSRV.valid() || stencilBlit); - gl::Extents readSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1); - gl::Extents drawSize(drawRenderTarget->getWidth(), drawRenderTarget->getHeight(), 1); + const gl::Extents readSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1); + const gl::Extents drawSize(drawRenderTarget->getWidth(), drawRenderTarget->getHeight(), 1); // From the spec: // "The actual region taken from the read framebuffer is limited to the intersection of the @@ -3801,8 +3438,32 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn, // by internally scaling the read and draw rectangles. gl::Rectangle readRect = readRectIn; gl::Rectangle drawRect = drawRectIn; - auto readToDrawX = [&drawRectIn, &readRectIn](int readOffset) + + auto flip = [](int val) { return val >= 0 ? 1 : -1; }; + + if (readRect.x > readSize.width && readRect.width < 0) { + int delta = readRect.x - readSize.width; + readRect.x -= delta; + readRect.width += delta; + + int drawDelta = delta * flip(drawRect.width); + drawRect.x += drawDelta; + drawRect.width -= drawDelta; + } + + if (readRect.y > readSize.height && readRect.height < 0) + { + int delta = readRect.y - readSize.height; + readRect.y -= delta; + readRect.height += delta; + + int drawDelta = delta * flip(drawRect.height); + drawRect.y += drawDelta; + drawRect.height -= drawDelta; + } + + auto readToDrawX = [&drawRectIn, &readRectIn](int readOffset) { double readToDrawScale = static_cast(drawRectIn.width) / static_cast(readRectIn.width); return static_cast(round(static_cast(readOffset) * readToDrawScale)); @@ -3818,8 +3479,7 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn, drawRect.width -= drawOffset; } - auto readToDrawY = [&drawRectIn, &readRectIn](int readOffset) - { + auto readToDrawY = [&drawRectIn, &readRectIn](int readOffset) { double readToDrawScale = static_cast(drawRectIn.height) / static_cast(readRectIn.height); return static_cast(round(static_cast(readOffset) * readToDrawScale)); @@ -3853,24 +3513,41 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn, drawRect.height += drawOffset; } - bool scissorNeeded = scissor && gl::ClipRectangle(drawRect, *scissor, NULL); + if (readRect.x1() > readSize.width) + { + int delta = readRect.x1() - readSize.width; + readRect.width -= delta; + drawRect.width -= delta * flip(drawRect.width); + } - const auto &destFormatInfo = gl::GetInternalFormatInfo(drawRenderTarget->getInternalFormat()); - const auto &srcFormatInfo = gl::GetInternalFormatInfo(readRenderTarget->getInternalFormat()); - const auto &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(drawRenderTarget11->getDXGIFormat()); + if (readRect.y1() > readSize.height) + { + int delta = readRect.y1() - readSize.height; + readRect.height -= delta; + drawRect.height -= delta * flip(drawRect.height); + } + + bool scissorNeeded = scissor && gl::ClipRectangle(drawRect, *scissor, nullptr); + + const auto &destFormatInfo = + gl::GetSizedInternalFormatInfo(drawRenderTarget->getInternalFormat()); + const auto &srcFormatInfo = + gl::GetSizedInternalFormatInfo(readRenderTarget->getInternalFormat()); + const auto &formatSet = drawRenderTarget11->getFormatSet(); + const auto &nativeFormat = formatSet.format(); // Some blits require masking off emulated texture channels. eg: from RGBA8 to RGB8, we // emulate RGB8 with RGBA8, so we need to mask off the alpha channel when we copy. gl::Color colorMask; - colorMask.red = (srcFormatInfo.redBits > 0) && (destFormatInfo.redBits == 0) && - (dxgiFormatInfo.redBits > 0); + colorMask.red = + (srcFormatInfo.redBits > 0) && (destFormatInfo.redBits == 0) && (nativeFormat.redBits > 0); colorMask.green = (srcFormatInfo.greenBits > 0) && (destFormatInfo.greenBits == 0) && - (dxgiFormatInfo.greenBits > 0); + (nativeFormat.greenBits > 0); colorMask.blue = (srcFormatInfo.blueBits > 0) && (destFormatInfo.blueBits == 0) && - (dxgiFormatInfo.blueBits > 0); + (nativeFormat.blueBits > 0); colorMask.alpha = (srcFormatInfo.alphaBits > 0) && (destFormatInfo.alphaBits == 0) && - (dxgiFormatInfo.alphaBits > 0); + (nativeFormat.alphaBits > 0); // We only currently support masking off the alpha channel. bool colorMaskingNeeded = colorMask.alpha; @@ -3884,18 +3561,19 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn, bool stretchRequired = readRect.width != drawRect.width || readRect.height != drawRect.height; - bool flipRequired = readRect.width < 0 || readRect.height < 0 || drawRect.width < 0 || drawRect.height < 0; + bool flipRequired = + readRect.width < 0 || readRect.height < 0 || drawRect.width < 0 || drawRect.height < 0; bool outOfBounds = readRect.x < 0 || readRect.x + readRect.width > readSize.width || readRect.y < 0 || readRect.y + readRect.height > readSize.height || drawRect.x < 0 || drawRect.x + drawRect.width > drawSize.width || drawRect.y < 0 || drawRect.y + drawRect.height > drawSize.height; - bool partialDSBlit = (dxgiFormatInfo.depthBits > 0 && depthBlit) != (dxgiFormatInfo.stencilBits > 0 && stencilBlit); + bool partialDSBlit = + (nativeFormat.depthBits > 0 && depthBlit) != (nativeFormat.stencilBits > 0 && stencilBlit); - gl::Error result(GL_NO_ERROR); - - if (readRenderTarget11->getDXGIFormat() == drawRenderTarget11->getDXGIFormat() && + if (readRenderTarget11->getFormatSet().formatID == + drawRenderTarget11->getFormatSet().formatID && !stretchRequired && !outOfBounds && !flipRequired && !partialDSBlit && !colorMaskingNeeded && (!(depthBlit || stencilBlit) || wholeBufferCopy)) { @@ -3903,16 +3581,17 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn, UINT dstY = drawRect.y; D3D11_BOX readBox; - readBox.left = readRect.x; - readBox.right = readRect.x + readRect.width; - readBox.top = readRect.y; + readBox.left = readRect.x; + readBox.right = readRect.x + readRect.width; + readBox.top = readRect.y; readBox.bottom = readRect.y + readRect.height; - readBox.front = 0; - readBox.back = 1; + readBox.front = 0; + readBox.back = 1; if (scissorNeeded) { - // drawRect is guaranteed to have positive width and height because stretchRequired is false. + // drawRect is guaranteed to have positive width and height because stretchRequired is + // false. ASSERT(drawRect.width >= 0 || drawRect.height >= 0); if (drawRect.x < scissor->x) @@ -3937,11 +3616,10 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn, // D3D11 needs depth-stencil CopySubresourceRegions to have a NULL pSrcBox // We also require complete framebuffer copies for depth-stencil blit. - D3D11_BOX *pSrcBox = wholeBufferCopy ? NULL : &readBox; + D3D11_BOX *pSrcBox = wholeBufferCopy ? nullptr : &readBox; - mDeviceContext->CopySubresourceRegion(drawTexture, drawSubresource, dstX, dstY, 0, - readTexture, readSubresource, pSrcBox); - result = gl::Error(GL_NO_ERROR); + mDeviceContext->CopySubresourceRegion(drawTexture.get(), drawSubresource, dstX, dstY, 0, + readTexture.get(), readSubresource, pSrcBox); } else { @@ -3950,47 +3628,56 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn, if (depthBlit && stencilBlit) { - result = mBlit->copyDepthStencil(readTexture, readSubresource, readArea, readSize, - drawTexture, drawSubresource, drawArea, drawSize, - scissor); + ANGLE_TRY(mBlit->copyDepthStencil(readTexture, readSubresource, readArea, readSize, + drawTexture, drawSubresource, drawArea, drawSize, + scissor)); } else if (depthBlit) { - result = mBlit->copyDepth(readSRV, readArea, readSize, drawDSV, drawArea, drawSize, - scissor); + const d3d11::DepthStencilView &drawDSV = drawRenderTarget11->getDepthStencilView(); + ASSERT(readSRV.valid()); + ANGLE_TRY(mBlit->copyDepth(context, readSRV, readArea, readSize, drawDSV, drawArea, + drawSize, scissor)); } else if (stencilBlit) { - result = mBlit->copyStencil(readTexture, readSubresource, readArea, readSize, - drawTexture, drawSubresource, drawArea, drawSize, - scissor); + ANGLE_TRY(mBlit->copyStencil(context, readTexture, readSubresource, readArea, readSize, + drawTexture, drawSubresource, drawArea, drawSize, + scissor)); } else { + const d3d11::RenderTargetView &drawRTV = drawRenderTarget11->getRenderTargetView(); + // We don't currently support masking off any other channel than alpha bool maskOffAlpha = colorMaskingNeeded && colorMask.alpha; - result = mBlit->copyTexture(readSRV, readArea, readSize, drawRTV, drawArea, drawSize, - scissor, destFormatInfo.format, filter, maskOffAlpha); + ASSERT(readSRV.valid()); + ANGLE_TRY(mBlit->copyTexture( + context, readSRV, readArea, readSize, srcFormatInfo.format, drawRTV, drawArea, + drawSize, scissor, destFormatInfo.format, filter, maskOffAlpha, false, false)); } } - SafeRelease(readTexture); - SafeRelease(readSRV); - - return result; + return gl::NoError(); } bool Renderer11::isES3Capable() const { - return (d3d11_gl::GetMaximumClientVersion(mRenderer11DeviceCaps.featureLevel) > 2); -}; + return (d3d11_gl::GetMaximumClientVersion(mRenderer11DeviceCaps.featureLevel).major > 2); +} + +RendererClass Renderer11::getRendererClass() const +{ + return RENDERER_D3D11; +} void Renderer11::onSwap() { // Send histogram updates every half hour const double kHistogramUpdateInterval = 30 * 60; - const double currentTime = ANGLEPlatformCurrent()->monotonicallyIncreasingTime(); + auto *platform = ANGLEPlatformCurrent(); + const double currentTime = platform->monotonicallyIncreasingTime(platform); const double timeSinceLastUpdate = currentTime - mLastHistogramUpdateTime; if (timeSinceLastUpdate > kHistogramUpdateInterval) @@ -4005,7 +3692,7 @@ void Renderer11::updateHistograms() // Update the buffer CPU memory histogram { size_t sizeSum = 0; - for (auto &buffer : mAliveBuffers) + for (const Buffer11 *buffer : mAliveBuffers) { sizeSum += buffer->getTotalCPUBufferMemoryBytes(); } @@ -4015,53 +3702,71 @@ void Renderer11::updateHistograms() } } +void Renderer11::onBufferCreate(const Buffer11 *created) +{ + mAliveBuffers.insert(created); +} + void Renderer11::onBufferDelete(const Buffer11 *deleted) { mAliveBuffers.erase(deleted); } -ID3D11Texture2D *Renderer11::resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource) +gl::ErrorOrResult Renderer11::resolveMultisampledTexture( + const gl::Context *context, + RenderTarget11 *renderTarget, + bool depth, + bool stencil) { - D3D11_TEXTURE2D_DESC textureDesc; - source->GetDesc(&textureDesc); + if (depth && !stencil) + { + return mBlit->resolveDepth(context, renderTarget); + } - if (textureDesc.SampleDesc.Count > 1) + if (stencil) + { + return mBlit->resolveStencil(context, renderTarget, depth); + } + + const auto &formatSet = renderTarget->getFormatSet(); + + ASSERT(renderTarget->isMultisampled()); + const d3d11::SharedSRV &sourceSRV = renderTarget->getShaderResourceView(); + D3D11_SHADER_RESOURCE_VIEW_DESC sourceSRVDesc; + sourceSRV.get()->GetDesc(&sourceSRVDesc); + ASSERT(sourceSRVDesc.ViewDimension == D3D_SRV_DIMENSION_TEXTURE2DMS); + + if (!mCachedResolveTexture.valid() || + mCachedResolveTexture.getExtents().width != renderTarget->getWidth() || + mCachedResolveTexture.getExtents().height != renderTarget->getHeight() || + mCachedResolveTexture.getFormat() != formatSet.texFormat) { D3D11_TEXTURE2D_DESC resolveDesc; - resolveDesc.Width = textureDesc.Width; - resolveDesc.Height = textureDesc.Height; - resolveDesc.MipLevels = 1; - resolveDesc.ArraySize = 1; - resolveDesc.Format = textureDesc.Format; - resolveDesc.SampleDesc.Count = 1; + resolveDesc.Width = renderTarget->getWidth(); + resolveDesc.Height = renderTarget->getHeight(); + resolveDesc.MipLevels = 1; + resolveDesc.ArraySize = 1; + resolveDesc.Format = formatSet.texFormat; + resolveDesc.SampleDesc.Count = 1; resolveDesc.SampleDesc.Quality = 0; - resolveDesc.Usage = textureDesc.Usage; - resolveDesc.BindFlags = textureDesc.BindFlags; - resolveDesc.CPUAccessFlags = 0; - resolveDesc.MiscFlags = 0; + resolveDesc.Usage = D3D11_USAGE_DEFAULT; + resolveDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + resolveDesc.CPUAccessFlags = 0; + resolveDesc.MiscFlags = 0; - ID3D11Texture2D *resolveTexture = NULL; - HRESULT result = mDevice->CreateTexture2D(&resolveDesc, NULL, &resolveTexture); - if (FAILED(result)) - { - ERR("Failed to create a multisample resolve texture, HRESULT: 0x%X.", result); - return NULL; - } + ANGLE_TRY(allocateTexture(resolveDesc, formatSet, &mCachedResolveTexture)); + } - mDeviceContext->ResolveSubresource(resolveTexture, 0, source, subresource, textureDesc.Format); - return resolveTexture; - } - else - { - source->AddRef(); - return source; - } + mDeviceContext->ResolveSubresource(mCachedResolveTexture.get(), 0, + renderTarget->getTexture().get(), + renderTarget->getSubresourceIndex(), formatSet.texFormat); + return mCachedResolveTexture; } bool Renderer11::getLUID(LUID *adapterLuid) const { adapterLuid->HighPart = 0; - adapterLuid->LowPart = 0; + adapterLuid->LowPart = 0; if (!mDxgiAdapter) { @@ -4078,45 +3783,70 @@ bool Renderer11::getLUID(LUID *adapterLuid) const return true; } -VertexConversionType Renderer11::getVertexConversionType(gl::VertexFormatType vertexFormatType) const +VertexConversionType Renderer11::getVertexConversionType( + gl::VertexFormatType vertexFormatType) const { - return d3d11::GetVertexFormatInfo(vertexFormatType, mRenderer11DeviceCaps.featureLevel).conversionType; + return d3d11::GetVertexFormatInfo(vertexFormatType, mRenderer11DeviceCaps.featureLevel) + .conversionType; } GLenum Renderer11::getVertexComponentType(gl::VertexFormatType vertexFormatType) const { - return d3d11::GetDXGIFormatInfo(d3d11::GetVertexFormatInfo(vertexFormatType, mRenderer11DeviceCaps.featureLevel).nativeFormat).componentType; + const auto &format = + d3d11::GetVertexFormatInfo(vertexFormatType, mRenderer11DeviceCaps.featureLevel); + return d3d11::GetComponentType(format.nativeFormat); } -void Renderer11::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, - gl::Extensions *outExtensions, gl::Limitations *outLimitations) const +gl::ErrorOrResult Renderer11::getVertexSpaceRequired( + const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + GLsizei count, + GLsizei instances) const +{ + if (!attrib.enabled) + { + return 16u; + } + + unsigned int elementCount = 0; + const unsigned int divisor = binding.getDivisor(); + if (instances == 0 || divisor == 0) + { + elementCount = count; + } + else + { + // Round up to divisor, if possible + elementCount = UnsignedCeilDivide(static_cast(instances), divisor); + } + + gl::VertexFormatType formatType = gl::GetVertexFormatType(attrib); + const D3D_FEATURE_LEVEL featureLevel = mRenderer11DeviceCaps.featureLevel; + const d3d11::VertexFormat &vertexFormatInfo = + d3d11::GetVertexFormatInfo(formatType, featureLevel); + const d3d11::DXGIFormatSize &dxgiFormatInfo = + d3d11::GetDXGIFormatSizeInfo(vertexFormatInfo.nativeFormat); + unsigned int elementSize = dxgiFormatInfo.pixelBytes; + if (elementSize > std::numeric_limits::max() / elementCount) + { + return gl::OutOfMemory() << "New vertex buffer size would result in an overflow."; + } + + return elementSize * elementCount; +} + +void Renderer11::generateCaps(gl::Caps *outCaps, + gl::TextureCapsMap *outTextureCaps, + gl::Extensions *outExtensions, + gl::Limitations *outLimitations) const { d3d11_gl::GenerateCaps(mDevice, mDeviceContext, mRenderer11DeviceCaps, outCaps, outTextureCaps, outExtensions, outLimitations); } -WorkaroundsD3D Renderer11::generateWorkarounds() const +angle::WorkaroundsD3D Renderer11::generateWorkarounds() const { - return d3d11::GenerateWorkarounds(mRenderer11DeviceCaps.featureLevel); -} - -void Renderer11::createAnnotator() -{ - // The D3D11 renderer must choose the D3D9 debug annotator because the D3D11 interface - // method ID3DUserDefinedAnnotation::GetStatus on desktop builds doesn't work with the Graphics - // Diagnostics tools in Visual Studio 2013. - // The D3D9 annotator works properly for both D3D11 and D3D9. - // Incorrect status reporting can cause ANGLE to log unnecessary debug events. -#ifdef ANGLE_ENABLE_D3D9 - mAnnotator = new DebugAnnotator9(); -#else - mAnnotator = new DebugAnnotator11(); -#endif -} - -gl::Error Renderer11::clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) -{ - return mStateManager.clearTextures(samplerType, rangeStart, rangeEnd); + return d3d11::GenerateWorkarounds(mRenderer11DeviceCaps, mAdapterDescription); } egl::Error Renderer11::getEGLDevice(DeviceImpl **device) @@ -4136,6 +3866,224 @@ egl::Error Renderer11::getEGLDevice(DeviceImpl **device) } *device = static_cast(mEGLDevice); - return egl::Error(EGL_SUCCESS); + return egl::NoError(); } + +ContextImpl *Renderer11::createContext(const gl::ContextState &state) +{ + return new Context11(state, this); } + +FramebufferImpl *Renderer11::createDefaultFramebuffer(const gl::FramebufferState &state) +{ + return new Framebuffer11(state, this); +} + +gl::Error Renderer11::getScratchMemoryBuffer(size_t requestedSize, angle::MemoryBuffer **bufferOut) +{ + if (!mScratchMemoryBuffer.get(requestedSize, bufferOut)) + { + return gl::OutOfMemory() << "Failed to allocate internal buffer."; + } + return gl::NoError(); +} + +gl::Version Renderer11::getMaxSupportedESVersion() const +{ + return d3d11_gl::GetMaximumClientVersion(mRenderer11DeviceCaps.featureLevel); +} + +gl::DebugAnnotator *Renderer11::getAnnotator() +{ + return mAnnotator; +} + +gl::Error Renderer11::applyComputeShader(const gl::Context *context) +{ + ANGLE_TRY(ensureHLSLCompilerInitialized()); + + const auto &glState = context->getGLState(); + ProgramD3D *programD3D = GetImplAs(glState.getProgram()); + + ShaderExecutableD3D *computeExe = nullptr; + ANGLE_TRY(programD3D->getComputeExecutable(&computeExe)); + ASSERT(computeExe != nullptr); + + mStateManager.setComputeShader(&GetAs(computeExe)->getComputeShader()); + ANGLE_TRY(mStateManager.applyComputeUniforms(programD3D)); + + return gl::NoError(); +} + +gl::Error Renderer11::dispatchCompute(const gl::Context *context, + GLuint numGroupsX, + GLuint numGroupsY, + GLuint numGroupsZ) +{ + ANGLE_TRY(mStateManager.updateStateForCompute(context, numGroupsX, numGroupsY, numGroupsZ)); + ANGLE_TRY(applyComputeShader(context)); + + mDeviceContext->Dispatch(numGroupsX, numGroupsY, numGroupsZ); + + return gl::NoError(); +} + +gl::ErrorOrResult Renderer11::createStagingTexture( + ResourceType textureType, + const d3d11::Format &formatSet, + const gl::Extents &size, + StagingAccess readAndWriteAccess) +{ + if (textureType == ResourceType::Texture2D) + { + D3D11_TEXTURE2D_DESC stagingDesc; + stagingDesc.Width = size.width; + stagingDesc.Height = size.height; + stagingDesc.MipLevels = 1; + stagingDesc.ArraySize = 1; + stagingDesc.Format = formatSet.texFormat; + stagingDesc.SampleDesc.Count = 1; + stagingDesc.SampleDesc.Quality = 0; + stagingDesc.Usage = D3D11_USAGE_STAGING; + stagingDesc.BindFlags = 0; + stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + stagingDesc.MiscFlags = 0; + + if (readAndWriteAccess == StagingAccess::READ_WRITE) + { + stagingDesc.CPUAccessFlags |= D3D11_CPU_ACCESS_WRITE; + } + + TextureHelper11 stagingTex; + ANGLE_TRY(allocateTexture(stagingDesc, formatSet, &stagingTex)); + return stagingTex; + } + ASSERT(textureType == ResourceType::Texture3D); + + D3D11_TEXTURE3D_DESC stagingDesc; + stagingDesc.Width = size.width; + stagingDesc.Height = size.height; + stagingDesc.Depth = 1; + stagingDesc.MipLevels = 1; + stagingDesc.Format = formatSet.texFormat; + stagingDesc.Usage = D3D11_USAGE_STAGING; + stagingDesc.BindFlags = 0; + stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + stagingDesc.MiscFlags = 0; + + TextureHelper11 stagingTex; + ANGLE_TRY(allocateTexture(stagingDesc, formatSet, &stagingTex)); + return stagingTex; +} + +gl::Error Renderer11::allocateTexture(const D3D11_TEXTURE2D_DESC &desc, + const d3d11::Format &format, + const D3D11_SUBRESOURCE_DATA *initData, + TextureHelper11 *textureOut) +{ + d3d11::Texture2D texture; + ANGLE_TRY(mResourceManager11.allocate(this, &desc, initData, &texture)); + textureOut->init(std::move(texture), desc, format); + return gl::NoError(); +} + +gl::Error Renderer11::allocateTexture(const D3D11_TEXTURE3D_DESC &desc, + const d3d11::Format &format, + const D3D11_SUBRESOURCE_DATA *initData, + TextureHelper11 *textureOut) +{ + d3d11::Texture3D texture; + ANGLE_TRY(mResourceManager11.allocate(this, &desc, initData, &texture)); + textureOut->init(std::move(texture), desc, format); + return gl::NoError(); +} + +gl::Error Renderer11::getBlendState(const d3d11::BlendStateKey &key, + const d3d11::BlendState **outBlendState) +{ + return mStateCache.getBlendState(this, key, outBlendState); +} + +gl::Error Renderer11::getRasterizerState(const gl::RasterizerState &rasterState, + bool scissorEnabled, + ID3D11RasterizerState **outRasterizerState) +{ + return mStateCache.getRasterizerState(this, rasterState, scissorEnabled, outRasterizerState); +} + +gl::Error Renderer11::getDepthStencilState(const gl::DepthStencilState &dsState, + const d3d11::DepthStencilState **outDSState) +{ + return mStateCache.getDepthStencilState(this, dsState, outDSState); +} + +gl::Error Renderer11::getSamplerState(const gl::SamplerState &samplerState, + ID3D11SamplerState **outSamplerState) +{ + return mStateCache.getSamplerState(this, samplerState, outSamplerState); +} + +gl::Error Renderer11::clearRenderTarget(RenderTargetD3D *renderTarget, + const gl::ColorF &clearColorValue, + const float clearDepthValue, + const unsigned int clearStencilValue) +{ + RenderTarget11 *rt11 = GetAs(renderTarget); + + if (rt11->getDepthStencilView().valid()) + { + const auto &format = rt11->getFormatSet(); + const UINT clearFlags = (format.format().depthBits > 0 ? D3D11_CLEAR_DEPTH : 0) | + (format.format().stencilBits ? D3D11_CLEAR_STENCIL : 0); + mDeviceContext->ClearDepthStencilView(rt11->getDepthStencilView().get(), clearFlags, + clearDepthValue, + static_cast(clearStencilValue)); + return gl::NoError(); + } + + ASSERT(rt11->getRenderTargetView().valid()); + ID3D11RenderTargetView *rtv = rt11->getRenderTargetView().get(); + + // There are complications with some types of RTV and FL 9_3 with ClearRenderTargetView. + // See https://msdn.microsoft.com/en-us/library/windows/desktop/ff476388(v=vs.85).aspx + ASSERT(mRenderer11DeviceCaps.featureLevel > D3D_FEATURE_LEVEL_9_3 || !IsArrayRTV(rtv)); + + const auto &d3d11Format = rt11->getFormatSet(); + const auto &glFormat = gl::GetSizedInternalFormatInfo(renderTarget->getInternalFormat()); + + gl::ColorF safeClearColor = clearColorValue; + + if (d3d11Format.format().alphaBits > 0 && glFormat.alphaBits == 0) + { + safeClearColor.alpha = 1.0f; + } + + mDeviceContext->ClearRenderTargetView(rtv, &safeClearColor.red); + return gl::NoError(); +} + +bool Renderer11::canSelectViewInVertexShader() const +{ + return !getWorkarounds().selectViewInGeometryShader && + getRenderer11DeviceCaps().supportsVpRtIndexWriteFromVertexShader; +} + +gl::Error Renderer11::markTransformFeedbackUsage(const gl::Context *context) +{ + const gl::State &glState = context->getGLState(); + const gl::TransformFeedback *transformFeedback = glState.getCurrentTransformFeedback(); + for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++) + { + const gl::OffsetBindingPointer &binding = + transformFeedback->getIndexedBuffer(i); + if (binding.get() != nullptr) + { + BufferD3D *bufferD3D = GetImplAs(binding.get()); + ANGLE_TRY(bufferD3D->markTransformFeedbackUsage(context)); + } + } + + return gl::NoError(); +} + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h index b4e7761ffc..a8c24e681b 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h @@ -14,13 +14,14 @@ #include "libANGLE/AttributeMap.h" #include "libANGLE/angletypes.h" #include "libANGLE/renderer/d3d/HLSLCompiler.h" -#include "libANGLE/renderer/d3d/RendererD3D.h" +#include "libANGLE/renderer/d3d/ProgramD3D.h" #include "libANGLE/renderer/d3d/RenderTargetD3D.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h" -#include "libANGLE/renderer/d3d/d3d11/InputLayoutCache.h" -#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #include "libANGLE/renderer/d3d/d3d11/RenderStateCache.h" +#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h" #include "libANGLE/renderer/d3d/d3d11/StateManager11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" namespace gl { @@ -28,36 +29,46 @@ class FramebufferAttachment; struct ImageIndex; } -struct ID3D11DeviceContext1; - namespace rx { - -class VertexDataManager; -class IndexDataManager; -class StreamingIndexBufferInterface; class Blit11; class Buffer11; class Clear11; +class Context11; +class IndexDataManager; +struct PackPixelsParams; class PixelTransfer11; class RenderTarget11; +class StreamingIndexBufferInterface; class Trim11; -struct PackPixelsParams; +class VertexDataManager; struct Renderer11DeviceCaps { + Renderer11DeviceCaps(); + D3D_FEATURE_LEVEL featureLevel; - bool supportsDXGI1_2; // Support for DXGI 1.2 - bool supportsClearView; // Support for ID3D11DeviceContext1::ClearView - bool supportsConstantBufferOffsets; // Support for Constant buffer offset - UINT B5G6R5support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B5G6R5_UNORM - UINT B4G4R4A4support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B4G4R4A4_UNORM - UINT B5G5R5A1support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B5G5R5A1_UNORM + bool supportsDXGI1_2; // Support for DXGI 1.2 + bool supportsClearView; // Support for ID3D11DeviceContext1::ClearView + bool supportsConstantBufferOffsets; // Support for Constant buffer offset + bool supportsVpRtIndexWriteFromVertexShader; // VP/RT can be selected in the Vertex Shader + // stage. + bool supportsMultisampledDepthStencilSRVs; // D3D feature level 10.0 no longer allows creation + // of textures with both the bind SRV and DSV flags + // when multisampled. Textures will need to be + // resolved before reading. crbug.com/656989 + UINT B5G6R5support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B5G6R5_UNORM + UINT B5G6R5maxSamples; // Maximum number of samples supported by DXGI_FORMAT_B5G6R5_UNORM + UINT B4G4R4A4support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B4G4R4A4_UNORM + UINT B4G4R4A4maxSamples; // Maximum number of samples supported by DXGI_FORMAT_B4G4R4A4_UNORM + UINT B5G5R5A1support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B5G5R5A1_UNORM + UINT B5G5R5A1maxSamples; // Maximum number of samples supported by DXGI_FORMAT_B5G5R5A1_UNORM + Optional driverVersion; // Four-part driver version number. }; enum { - MAX_VERTEX_UNIFORM_VECTORS_D3D11 = 1024, + MAX_VERTEX_UNIFORM_VECTORS_D3D11 = 1024, MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 = 1024 }; @@ -103,172 +114,244 @@ class Renderer11 : public RendererD3D { public: explicit Renderer11(egl::Display *display); - virtual ~Renderer11(); + ~Renderer11() override; egl::Error initialize() override; - virtual bool resetDevice(); + bool resetDevice() override; - egl::ConfigSet generateConfigs() const override; + egl::ConfigSet generateConfigs() override; void generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const override; - gl::Error flush() override; - gl::Error finish() override; + ContextImpl *createContext(const gl::ContextState &state) override; - SwapChainD3D *createSwapChain(NativeWindow nativeWindow, + gl::Error flush(); + gl::Error finish(); + + bool isValidNativeWindow(EGLNativeWindowType window) const override; + NativeWindowD3D *createNativeWindow(EGLNativeWindowType window, + const egl::Config *config, + const egl::AttributeMap &attribs) const override; + + SwapChainD3D *createSwapChain(NativeWindowD3D *nativeWindow, HANDLE shareHandle, + IUnknown *d3dTexture, GLenum backBufferFormat, GLenum depthBufferFormat, - EGLint orientation) override; + EGLint orientation, + EGLint samples) override; + egl::Error getD3DTextureInfo(const egl::Config *configuration, + IUnknown *d3dTexture, + EGLint *width, + EGLint *height, + GLenum *fboFormat) const override; + egl::Error validateShareHandle(const egl::Config *config, + HANDLE shareHandle, + const egl::AttributeMap &attribs) const override; - CompilerImpl *createCompiler() override; - - virtual gl::Error generateSwizzle(gl::Texture *texture); - virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler); - virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture); - - gl::Error setUniformBuffers(const gl::Data &data, - const std::vector &vertexUniformBuffers, - const std::vector &fragmentUniformBuffers) override; - - gl::Error updateState(const gl::Data &data, GLenum drawMode) override; - - virtual bool applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize); - gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) override; - gl::Error applyUniforms(const ProgramD3D &programD3D, - GLenum drawMode, - const std::vector &uniformArray) override; - virtual gl::Error applyVertexBuffer(const gl::State &state, - GLenum mode, - GLint first, - GLsizei count, - GLsizei instances, - TranslatedIndexData *indexInfo); - gl::Error applyIndexBuffer(const gl::Data &data, - const GLvoid *indices, - GLsizei count, - GLenum mode, - GLenum type, - TranslatedIndexData *indexInfo) override; - void applyTransformFeedbackBuffers(const gl::State &state) override; + bool applyPrimitiveType(const gl::State &glState, GLenum mode, GLsizei count); // lost device bool testDeviceLost() override; bool testDeviceResettable() override; - std::string getRendererDescription() const override; + std::string getRendererDescription() const; DeviceIdentifier getAdapterIdentifier() const override; - virtual unsigned int getReservedVertexUniformVectors() const; - virtual unsigned int getReservedFragmentUniformVectors() const; - virtual unsigned int getReservedVertexUniformBuffers() const; - virtual unsigned int getReservedFragmentUniformBuffers() const; + unsigned int getReservedVertexUniformVectors() const; + unsigned int getReservedFragmentUniformVectors() const; + unsigned int getReservedVertexUniformBuffers() const; + unsigned int getReservedFragmentUniformBuffers() const; bool getShareHandleSupport() const; - virtual int getMajorShaderModel() const; + bool getNV12TextureSupport() const; + + int getMajorShaderModel() const override; int getMinorShaderModel() const override; std::string getShaderModelSuffix() const override; // Pixel operations - virtual gl::Error copyImage2D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLint level); - virtual gl::Error copyImageCube(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLenum target, GLint level); - virtual gl::Error copyImage3D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLint level); - virtual gl::Error copyImage2DArray(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLint level); + gl::Error copyImage2D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) override; + gl::Error copyImageCube(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLenum target, + GLint level) override; + gl::Error copyImage3D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) override; + gl::Error copyImage2DArray(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) override; + + gl::Error copyTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLenum destTarget, + GLint destLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) override; + gl::Error copyCompressedTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + TextureStorage *storage, + GLint destLevel) override; // RenderTarget creation - virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT); + gl::Error createRenderTarget(int width, + int height, + GLenum format, + GLsizei samples, + RenderTargetD3D **outRT) override; gl::Error createRenderTargetCopy(RenderTargetD3D *source, RenderTargetD3D **outRT) override; - // Framebuffer creation - FramebufferImpl *createFramebuffer(const gl::Framebuffer::Data &data) override; - - // Shader creation - ShaderImpl *createShader(const gl::Shader::Data &data) override; - ProgramImpl *createProgram(const gl::Program::Data &data) override; - // Shader operations - gl::Error loadExecutable(const void *function, + gl::Error loadExecutable(const uint8_t *function, size_t length, - ShaderType type, + gl::ShaderType type, const std::vector &streamOutVaryings, bool separatedOutputBuffers, ShaderExecutableD3D **outExecutable) override; gl::Error compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, - ShaderType type, + gl::ShaderType type, const std::vector &streamOutVaryings, bool separatedOutputBuffers, - const D3DCompilerWorkarounds &workarounds, + const angle::CompilerWorkaroundsD3D &workarounds, ShaderExecutableD3D **outExectuable) override; + gl::Error ensureHLSLCompilerInitialized() override; + UniformStorageD3D *createUniformStorage(size_t storageSize) override; // Image operations - virtual ImageD3D *createImage(); - gl::Error generateMipmap(ImageD3D *dest, ImageD3D *source) override; - gl::Error generateMipmapsUsingD3D(TextureStorage *storage, - const gl::TextureState &textureState) override; - virtual TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain); - TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage) override; - virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly); - virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly); - virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels); - virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels); + ImageD3D *createImage() override; + gl::Error generateMipmap(const gl::Context *context, ImageD3D *dest, ImageD3D *source) override; + gl::Error generateMipmapUsingD3D(const gl::Context *context, + TextureStorage *storage, + const gl::TextureState &textureState) override; + gl::Error copyImage(const gl::Context *context, + ImageD3D *dest, + ImageD3D *source, + const gl::Rectangle &sourceRect, + const gl::Offset &destOffset, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) override; + TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain) override; + TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage, + RenderTargetD3D *renderTargetD3D) override; + TextureStorage *createTextureStorageExternal( + egl::Stream *stream, + const egl::Stream::GLTextureDescription &desc) override; + TextureStorage *createTextureStorage2D(GLenum internalformat, + bool renderTarget, + GLsizei width, + GLsizei height, + int levels, + bool hintLevelZeroOnly) override; + TextureStorage *createTextureStorageCube(GLenum internalformat, + bool renderTarget, + int size, + int levels, + bool hintLevelZeroOnly) override; + TextureStorage *createTextureStorage3D(GLenum internalformat, + bool renderTarget, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels) override; + TextureStorage *createTextureStorage2DArray(GLenum internalformat, + bool renderTarget, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels) override; + TextureStorage *createTextureStorage2DMultisample(GLenum internalformat, + GLsizei width, + GLsizei height, + int levels, + int samples, + bool fixedSampleLocations) override; - // Texture creation - virtual TextureImpl *createTexture(GLenum target); + VertexBuffer *createVertexBuffer() override; + IndexBuffer *createIndexBuffer() override; - // Renderbuffer creation - virtual RenderbufferImpl *createRenderbuffer(); - - // Buffer creation - virtual BufferImpl *createBuffer(); - virtual VertexBuffer *createVertexBuffer(); - virtual IndexBuffer *createIndexBuffer(); - - // Vertex Array creation - VertexArrayImpl *createVertexArray(const gl::VertexArray::Data &data) override; - - // Query and Fence creation - virtual QueryImpl *createQuery(GLenum type); - virtual FenceNVImpl *createFenceNV(); - virtual FenceSyncImpl *createFenceSync(); - - // Transform Feedback creation - virtual TransformFeedbackImpl* createTransformFeedback(); + // Stream Creation + StreamProducerImpl *createStreamProducerD3DTextureNV12( + egl::Stream::ConsumerType consumerType, + const egl::AttributeMap &attribs) override; // D3D11-renderer specific methods ID3D11Device *getDevice() { return mDevice; } void *getD3DDevice() override; ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; }; ID3D11DeviceContext1 *getDeviceContext1IfSupported() { return mDeviceContext1; }; - DXGIFactory *getDxgiFactory() { return mDxgiFactory; }; + IDXGIFactory *getDxgiFactory() { return mDxgiFactory; }; - RenderStateCache &getStateCache() { return mStateCache; } + gl::Error getBlendState(const d3d11::BlendStateKey &key, + const d3d11::BlendState **outBlendState); + gl::Error getRasterizerState(const gl::RasterizerState &rasterState, + bool scissorEnabled, + ID3D11RasterizerState **outRasterizerState); + gl::Error getDepthStencilState(const gl::DepthStencilState &dsState, + const d3d11::DepthStencilState **outDSState); + gl::Error getSamplerState(const gl::SamplerState &samplerState, + ID3D11SamplerState **outSamplerState); Blit11 *getBlitter() { return mBlit; } Clear11 *getClearer() { return mClear; } + gl::DebugAnnotator *getAnnotator(); // Buffer-to-texture and Texture-to-buffer copies - virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const; - virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget, - GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea); + bool supportsFastCopyBufferToTexture(GLenum internalFormat) const override; + gl::Error fastCopyBufferToTexture(const gl::Context *context, + const gl::PixelUnpackState &unpack, + unsigned int offset, + RenderTargetD3D *destRenderTarget, + GLenum destinationFormat, + GLenum sourcePixelsType, + const gl::Box &destArea) override; - void markAllStateDirty(); - void unapplyRenderTargets(); - void setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView); gl::Error packPixels(const TextureHelper11 &textureHelper, const PackPixelsParams ¶ms, uint8_t *pixelsOut); bool getLUID(LUID *adapterLuid) const override; - VertexConversionType getVertexConversionType(gl::VertexFormatType vertexFormatType) const override; + VertexConversionType getVertexConversionType( + gl::VertexFormatType vertexFormatType) const override; GLenum getVertexComponentType(gl::VertexFormatType vertexFormatType) const override; - gl::Error readFromAttachment(const gl::FramebufferAttachment &srcAttachment, + // Warning: you should ensure binding really matches attrib.bindingIndex before using this + // function. + gl::ErrorOrResult getVertexSpaceRequired(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + GLsizei count, + GLsizei instances) const override; + + gl::Error readFromAttachment(const gl::Context *context, + const gl::FramebufferAttachment &srcAttachment, const gl::Rectangle &sourceArea, GLenum format, GLenum type, @@ -276,145 +359,175 @@ class Renderer11 : public RendererD3D const gl::PixelPackState &pack, uint8_t *pixels); - gl::Error blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTargetD3D *readRenderTarget, - RenderTargetD3D *drawRenderTarget, GLenum filter, const gl::Rectangle *scissor, - bool colorBlit, bool depthBlit, bool stencilBlit); + gl::Error blitRenderbufferRect(const gl::Context *context, + const gl::Rectangle &readRect, + const gl::Rectangle &drawRect, + RenderTargetD3D *readRenderTarget, + RenderTargetD3D *drawRenderTarget, + GLenum filter, + const gl::Rectangle *scissor, + bool colorBlit, + bool depthBlit, + bool stencilBlit); bool isES3Capable() const; - const Renderer11DeviceCaps &getRenderer11DeviceCaps() { return mRenderer11DeviceCaps; }; + const Renderer11DeviceCaps &getRenderer11DeviceCaps() const { return mRenderer11DeviceCaps; }; - RendererClass getRendererClass() const override { return RENDERER_D3D11; } - InputLayoutCache *getInputLayoutCache() { return &mInputLayoutCache; } + RendererClass getRendererClass() const override; StateManager11 *getStateManager() { return &mStateManager; } void onSwap(); + void onBufferCreate(const Buffer11 *created); void onBufferDelete(const Buffer11 *deleted); egl::Error getEGLDevice(DeviceImpl **device) override; - protected: - void createAnnotator() override; - gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) override; - gl::Error applyShadersImpl(const gl::Data &data, GLenum drawMode) override; + gl::Error drawArrays(const gl::Context *context, + GLenum mode, + GLint startVertex, + GLsizei count, + GLsizei instances); - void syncState(const gl::State &state, const gl::State::DirtyBits &bitmask) override; + gl::Error drawElements(const gl::Context *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei instances); + + gl::Error drawArraysIndirect(const gl::Context *context, GLenum mode, const void *indirect); + gl::Error drawElementsIndirect(const gl::Context *context, + GLenum mode, + GLenum type, + const void *indirect); + + // Necessary hack for default framebuffers in D3D. + FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override; + + gl::Error getScratchMemoryBuffer(size_t requestedSize, angle::MemoryBuffer **bufferOut); + + gl::Version getMaxSupportedESVersion() const override; + + gl::Error dispatchCompute(const gl::Context *context, + GLuint numGroupsX, + GLuint numGroupsY, + GLuint numGroupsZ); + gl::Error applyComputeShader(const gl::Context *context); + + gl::ErrorOrResult createStagingTexture(ResourceType textureType, + const d3d11::Format &formatSet, + const gl::Extents &size, + StagingAccess readAndWriteAccess); + + template + gl::Error allocateResource(const DescT &desc, ResourceT *resourceOut) + { + return mResourceManager11.allocate(this, &desc, nullptr, resourceOut); + } + + template + gl::Error allocateResource(const DescT &desc, InitDataT *initData, ResourceT *resourceOut) + { + return mResourceManager11.allocate(this, &desc, initData, resourceOut); + } + + template + gl::Error allocateResourceNoDesc(InitDataT *initData, ResourceT *resourceOut) + { + return mResourceManager11.allocate(this, nullptr, initData, resourceOut); + } + + template + gl::Error allocateTexture(const DescT &desc, + const d3d11::Format &format, + TextureHelper11 *textureOut) + { + return allocateTexture(desc, format, nullptr, textureOut); + } + + gl::Error allocateTexture(const D3D11_TEXTURE2D_DESC &desc, + const d3d11::Format &format, + const D3D11_SUBRESOURCE_DATA *initData, + TextureHelper11 *textureOut); + + gl::Error allocateTexture(const D3D11_TEXTURE3D_DESC &desc, + const d3d11::Format &format, + const D3D11_SUBRESOURCE_DATA *initData, + TextureHelper11 *textureOut); + + gl::Error clearRenderTarget(RenderTargetD3D *renderTarget, + const gl::ColorF &clearColorValue, + const float clearDepthValue, + const unsigned int clearStencilValue) override; + + bool canSelectViewInVertexShader() const override; private: - gl::Error drawArraysImpl(const gl::Data &data, - GLenum mode, - GLsizei count, - GLsizei instances) override; - gl::Error drawElementsImpl(const gl::Data &data, - const TranslatedIndexData &indexInfo, - GLenum mode, - GLsizei count, - GLenum type, - const GLvoid *indices, - GLsizei instances) override; - - void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, + void generateCaps(gl::Caps *outCaps, + gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions, gl::Limitations *outLimitations) const override; - WorkaroundsD3D generateWorkarounds() const override; + angle::WorkaroundsD3D generateWorkarounds() const override; - gl::Error drawLineLoop(const gl::Data &data, + gl::Error drawLineLoop(const gl::Context *context, GLsizei count, GLenum type, - const GLvoid *indices, - const TranslatedIndexData *indexInfo, + const void *indices, + int baseVertex, int instances); - gl::Error drawTriangleFan(const gl::Data &data, + gl::Error drawTriangleFan(const gl::Context *context, GLsizei count, GLenum type, - const GLvoid *indices, - int minIndex, + const void *indices, + int baseVertex, int instances); - ID3D11Texture2D *resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource); + gl::ErrorOrResult resolveMultisampledTexture(const gl::Context *context, + RenderTarget11 *renderTarget, + bool depth, + bool stencil); void populateRenderer11DeviceCaps(); void updateHistograms(); + gl::Error copyImageInternal(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + RenderTargetD3D *destRenderTarget); + + gl::SupportedSampleSet generateSampleSetForEGLConfig( + const gl::TextureCaps &colorBufferFormatCaps, + const gl::TextureCaps &depthStencilBufferFormatCaps) const; + + HRESULT callD3D11CreateDevice(PFN_D3D11_CREATE_DEVICE createDevice, bool debug); + egl::Error initializeD3DDevice(); + egl::Error initializeDevice(); + void releaseDeviceResources(); + void release(); + + d3d11::ANGLED3D11DeviceType getDeviceType() const; + + gl::Error markTransformFeedbackUsage(const gl::Context *context); + HMODULE mD3d11Module; HMODULE mDxgiModule; HMODULE mDCompModule; std::vector mAvailableFeatureLevels; D3D_DRIVER_TYPE mRequestedDriverType; + bool mCreateDebugDevice; bool mCreatedWithDeviceEXT; DeviceD3D *mEGLDevice; HLSLCompiler mCompiler; - egl::Error initializeD3DDevice(); - void initializeDevice(); - void releaseDeviceResources(); - void release(); - - d3d11::ANGLED3D11DeviceType getDeviceType() const; - RenderStateCache mStateCache; - // current render target states - uintptr_t mAppliedRTVs[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS]; - uintptr_t mAppliedDSV; - - // Currently applied sampler states - std::vector mForceSetVertexSamplerStates; - std::vector mCurVertexSamplerStates; - - std::vector mForceSetPixelSamplerStates; - std::vector mCurPixelSamplerStates; - StateManager11 mStateManager; - // Currently applied primitive topology - D3D11_PRIMITIVE_TOPOLOGY mCurrentPrimitiveTopology; - - // Currently applied index buffer - ID3D11Buffer *mAppliedIB; - DXGI_FORMAT mAppliedIBFormat; - unsigned int mAppliedIBOffset; - bool mAppliedIBChanged; - - // Currently applied transform feedback buffers - size_t mAppliedNumXFBBindings; - ID3D11Buffer *mAppliedTFBuffers[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; // Tracks the current D3D buffers - // in use for streamout - GLintptr mAppliedTFOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; // Tracks the current GL-specified - // buffer offsets to transform feedback - // buffers - UINT mCurrentD3DOffsets[gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS]; // Tracks the D3D buffer offsets, - // which may differ from GLs, due - // to different append behavior - - // Currently applied shaders - uintptr_t mAppliedVertexShader; - uintptr_t mAppliedGeometryShader; - uintptr_t mAppliedPixelShader; - - dx_VertexConstants11 mAppliedVertexConstants; - ID3D11Buffer *mDriverConstantBufferVS; - ID3D11Buffer *mCurrentVertexConstantBuffer; - unsigned int mCurrentConstantBufferVS[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS]; - GLintptr mCurrentConstantBufferVSOffset[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS]; - GLsizeiptr mCurrentConstantBufferVSSize[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS]; - - dx_PixelConstants11 mAppliedPixelConstants; - ID3D11Buffer *mDriverConstantBufferPS; - ID3D11Buffer *mCurrentPixelConstantBuffer; - unsigned int mCurrentConstantBufferPS[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS]; - GLintptr mCurrentConstantBufferPSOffset[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS]; - GLsizeiptr mCurrentConstantBufferPSSize[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS]; - - ID3D11Buffer *mCurrentGeometryConstantBuffer; - - // Vertex, index and input layouts - VertexDataManager *mVertexDataManager; - IndexDataManager *mIndexDataManager; - InputLayoutCache mInputLayoutCache; - StreamingIndexBufferInterface *mLineLoopIB; StreamingIndexBufferInterface *mTriangleFanIB; @@ -429,10 +542,10 @@ class Renderer11 : public RendererD3D Trim11 *mTrim; // Sync query - ID3D11Query *mSyncQuery; + d3d11::Query mSyncQuery; // Created objects state tracking - std::set mAliveBuffers; + std::set mAliveBuffers; double mLastHistogramUpdateTime; @@ -440,18 +553,24 @@ class Renderer11 : public RendererD3D Renderer11DeviceCaps mRenderer11DeviceCaps; ID3D11DeviceContext *mDeviceContext; ID3D11DeviceContext1 *mDeviceContext1; + ID3D11DeviceContext3 *mDeviceContext3; IDXGIAdapter *mDxgiAdapter; DXGI_ADAPTER_DESC mAdapterDescription; char mDescription[128]; - DXGIFactory *mDxgiFactory; -#if !defined(ANGLE_MINGW32_COMPAT) + IDXGIFactory *mDxgiFactory; ID3D11Debug *mDebug; -#endif std::vector mScratchIndexDataBuffer; + angle::ScratchBuffer mScratchMemoryBuffer; + + gl::DebugAnnotator *mAnnotator; + mutable Optional mSupportsShareHandles; + ResourceManager11 mResourceManager11; + + TextureHelper11 mCachedResolveTexture; }; -} -#endif // LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_H_ +} // namespace rx +#endif // LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.cpp new file mode 100644 index 0000000000..c228380a34 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.cpp @@ -0,0 +1,533 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ResourceManager11: +// Centralized point of allocation for all D3D11 Resources. + +#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h" + +#include "common/debug.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" + +namespace rx +{ + +namespace +{ + +constexpr uint8_t kDebugInitTextureDataValue = 0x48; +constexpr FLOAT kDebugColorInitClearValue[4] = {0.3f, 0.5f, 0.7f, 0.5f}; +constexpr FLOAT kDebugDepthInitValue = 0.2f; +constexpr UINT8 kDebugStencilInitValue = 3; + +uint64_t ComputeMippedMemoryUsage(unsigned int width, + unsigned int height, + unsigned int depth, + uint64_t pixelSize, + unsigned int mipLevels) +{ + uint64_t sizeSum = 0; + + for (unsigned int level = 0; level < mipLevels; ++level) + { + unsigned int mipWidth = std::max(width >> level, 1u); + unsigned int mipHeight = std::max(height >> level, 1u); + unsigned int mipDepth = std::max(depth >> level, 1u); + sizeSum += static_cast(mipWidth * mipHeight * mipDepth) * pixelSize; + } + + return sizeSum; +} + +uint64_t ComputeMemoryUsage(const D3D11_TEXTURE2D_DESC *desc) +{ + ASSERT(desc); + uint64_t pixelBytes = + static_cast(d3d11::GetDXGIFormatSizeInfo(desc->Format).pixelBytes); + return ComputeMippedMemoryUsage(desc->Width, desc->Height, 1, pixelBytes, desc->MipLevels); +} + +uint64_t ComputeMemoryUsage(const D3D11_TEXTURE3D_DESC *desc) +{ + ASSERT(desc); + uint64_t pixelBytes = + static_cast(d3d11::GetDXGIFormatSizeInfo(desc->Format).pixelBytes); + return ComputeMippedMemoryUsage(desc->Width, desc->Height, desc->Depth, pixelBytes, + desc->MipLevels); +} + +uint64_t ComputeMemoryUsage(const D3D11_BUFFER_DESC *desc) +{ + ASSERT(desc); + return static_cast(desc->ByteWidth); +} + +template +uint64_t ComputeMemoryUsage(const T *desc) +{ + return 0; +} + +template +uint64_t ComputeGenericMemoryUsage(ID3D11DeviceChild *genericResource) +{ + auto *typedResource = static_cast *>(genericResource); + GetDescType desc; + typedResource->GetDesc(&desc); + return ComputeMemoryUsage(&desc); +} + +uint64_t ComputeGenericMemoryUsage(ResourceType resourceType, ID3D11DeviceChild *resource) +{ + switch (resourceType) + { + case ResourceType::Texture2D: + return ComputeGenericMemoryUsage(resource); + case ResourceType::Texture3D: + return ComputeGenericMemoryUsage(resource); + case ResourceType::Buffer: + return ComputeGenericMemoryUsage(resource); + + default: + return 0; + } +} + +HRESULT CreateResource(ID3D11Device *device, + const D3D11_BLEND_DESC *desc, + void * /*initData*/, + ID3D11BlendState **blendState) +{ + return device->CreateBlendState(desc, blendState); +} + +HRESULT CreateResource(ID3D11Device *device, + const D3D11_BUFFER_DESC *desc, + const D3D11_SUBRESOURCE_DATA *initData, + ID3D11Buffer **buffer) +{ + return device->CreateBuffer(desc, initData, buffer); +} + +HRESULT CreateResource(ID3D11Device *device, + const ShaderData *desc, + void * /*initData*/, + ID3D11ComputeShader **resourceOut) +{ + return device->CreateComputeShader(desc->get(), desc->size(), nullptr, resourceOut); +} + +HRESULT CreateResource(ID3D11Device *device, + const D3D11_DEPTH_STENCIL_DESC *desc, + void * /*initData*/, + ID3D11DepthStencilState **resourceOut) +{ + return device->CreateDepthStencilState(desc, resourceOut); +} + +HRESULT CreateResource(ID3D11Device *device, + const D3D11_DEPTH_STENCIL_VIEW_DESC *desc, + ID3D11Resource *resource, + ID3D11DepthStencilView **resourceOut) +{ + return device->CreateDepthStencilView(resource, desc, resourceOut); +} + +HRESULT CreateResource(ID3D11Device *device, + const ShaderData *desc, + const std::vector *initData, + ID3D11GeometryShader **resourceOut) +{ + if (initData) + { + return device->CreateGeometryShaderWithStreamOutput( + desc->get(), desc->size(), initData->data(), static_cast(initData->size()), + nullptr, 0, 0, nullptr, resourceOut); + } + else + { + return device->CreateGeometryShader(desc->get(), desc->size(), nullptr, resourceOut); + } +} + +HRESULT CreateResource(ID3D11Device *device, + const InputElementArray *desc, + const ShaderData *initData, + ID3D11InputLayout **resourceOut) +{ + return device->CreateInputLayout(desc->get(), static_cast(desc->size()), initData->get(), + initData->size(), resourceOut); +} + +HRESULT CreateResource(ID3D11Device *device, + const ShaderData *desc, + void * /*initData*/, + ID3D11PixelShader **resourceOut) +{ + return device->CreatePixelShader(desc->get(), desc->size(), nullptr, resourceOut); +} + +HRESULT CreateResource(ID3D11Device *device, + const D3D11_QUERY_DESC *desc, + void * /*initData*/, + ID3D11Query **resourceOut) +{ + return device->CreateQuery(desc, resourceOut); +} + +HRESULT CreateResource(ID3D11Device *device, + const D3D11_RASTERIZER_DESC *desc, + void * /*initData*/, + ID3D11RasterizerState **rasterizerState) +{ + return device->CreateRasterizerState(desc, rasterizerState); +} + +HRESULT CreateResource(ID3D11Device *device, + const D3D11_RENDER_TARGET_VIEW_DESC *desc, + ID3D11Resource *resource, + ID3D11RenderTargetView **renderTargetView) +{ + return device->CreateRenderTargetView(resource, desc, renderTargetView); +} + +HRESULT CreateResource(ID3D11Device *device, + const D3D11_SAMPLER_DESC *desc, + void * /*initData*/, + ID3D11SamplerState **resourceOut) +{ + return device->CreateSamplerState(desc, resourceOut); +} + +HRESULT CreateResource(ID3D11Device *device, + const D3D11_SHADER_RESOURCE_VIEW_DESC *desc, + ID3D11Resource *resource, + ID3D11ShaderResourceView **resourceOut) +{ + return device->CreateShaderResourceView(resource, desc, resourceOut); +} + +HRESULT CreateResource(ID3D11Device *device, + const D3D11_TEXTURE2D_DESC *desc, + const D3D11_SUBRESOURCE_DATA *initData, + ID3D11Texture2D **texture) +{ + return device->CreateTexture2D(desc, initData, texture); +} + +HRESULT CreateResource(ID3D11Device *device, + const D3D11_TEXTURE3D_DESC *desc, + const D3D11_SUBRESOURCE_DATA *initData, + ID3D11Texture3D **texture) +{ + return device->CreateTexture3D(desc, initData, texture); +} + +HRESULT CreateResource(ID3D11Device *device, + const ShaderData *desc, + void * /*initData*/, + ID3D11VertexShader **resourceOut) +{ + return device->CreateVertexShader(desc->get(), desc->size(), nullptr, resourceOut); +} + +DXGI_FORMAT GetTypedDepthStencilFormat(DXGI_FORMAT dxgiFormat) +{ + switch (dxgiFormat) + { + case DXGI_FORMAT_R16_TYPELESS: + return DXGI_FORMAT_D16_UNORM; + case DXGI_FORMAT_R24G8_TYPELESS: + return DXGI_FORMAT_D24_UNORM_S8_UINT; + case DXGI_FORMAT_R32_TYPELESS: + return DXGI_FORMAT_D32_FLOAT; + case DXGI_FORMAT_R32G8X24_TYPELESS: + return DXGI_FORMAT_D32_FLOAT_S8X24_UINT; + default: + return dxgiFormat; + } +} + +template +gl::Error ClearResource(Renderer11 *renderer, const DescT *desc, ResourceT *texture) +{ + // No-op. + return gl::NoError(); +} + +template <> +gl::Error ClearResource(Renderer11 *renderer, + const D3D11_TEXTURE2D_DESC *desc, + ID3D11Texture2D *texture) +{ + ID3D11DeviceContext *context = renderer->getDeviceContext(); + + if ((desc->BindFlags & D3D11_BIND_DEPTH_STENCIL) != 0) + { + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Flags = 0; + dsvDesc.Format = GetTypedDepthStencilFormat(desc->Format); + + const auto &format = d3d11_angle::GetFormat(dsvDesc.Format); + UINT clearFlags = (format.depthBits > 0 ? D3D11_CLEAR_DEPTH : 0) | + (format.stencilBits > 0 ? D3D11_CLEAR_STENCIL : 0); + + // Must process each mip level individually. + for (UINT mipLevel = 0; mipLevel < desc->MipLevels; ++mipLevel) + { + if (desc->SampleDesc.Count == 0) + { + dsvDesc.Texture2D.MipSlice = mipLevel; + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + } + else + { + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS; + } + + d3d11::DepthStencilView dsv; + ANGLE_TRY(renderer->allocateResource(dsvDesc, texture, &dsv)); + + context->ClearDepthStencilView(dsv.get(), clearFlags, kDebugDepthInitValue, + kDebugStencilInitValue); + } + } + else + { + ASSERT((desc->BindFlags & D3D11_BIND_RENDER_TARGET) != 0); + d3d11::RenderTargetView rtv; + ANGLE_TRY(renderer->allocateResourceNoDesc(texture, &rtv)); + + context->ClearRenderTargetView(rtv.get(), kDebugColorInitClearValue); + } + + return gl::NoError(); +} + +template <> +gl::Error ClearResource(Renderer11 *renderer, + const D3D11_TEXTURE3D_DESC *desc, + ID3D11Texture3D *texture) +{ + ID3D11DeviceContext *context = renderer->getDeviceContext(); + + ASSERT((desc->BindFlags & D3D11_BIND_DEPTH_STENCIL) == 0); + ASSERT((desc->BindFlags & D3D11_BIND_RENDER_TARGET) != 0); + + d3d11::RenderTargetView rtv; + ANGLE_TRY(renderer->allocateResourceNoDesc(texture, &rtv)); + + context->ClearRenderTargetView(rtv.get(), kDebugColorInitClearValue); + return gl::NoError(); +} + +#define ANGLE_RESOURCE_STRINGIFY_OP(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) #RESTYPE, + +constexpr std::array kResourceTypeNames = { + {ANGLE_RESOURCE_TYPE_OP(Stringify, ANGLE_RESOURCE_STRINGIFY_OP)}}; +static_assert(kResourceTypeNames[NumResourceTypes - 1] != nullptr, + "All members must be initialized."); + +} // anonymous namespace + +// ResourceManager11 Implementation. +ResourceManager11::ResourceManager11() + : mInitializeAllocations(false), + mAllocatedResourceCounts({{}}), + mAllocatedResourceDeviceMemory({{}}) +{ +} + +ResourceManager11::~ResourceManager11() +{ + for (size_t count : mAllocatedResourceCounts) + { + ASSERT(count == 0); + } + + for (uint64_t memorySize : mAllocatedResourceDeviceMemory) + { + ASSERT(memorySize == 0); + } +} + +template +gl::Error ResourceManager11::allocate(Renderer11 *renderer, + const GetDescFromD3D11 *desc, + GetInitDataFromD3D11 *initData, + Resource11 *resourceOut) +{ + ID3D11Device *device = renderer->getDevice(); + T *resource = nullptr; + + GetInitDataFromD3D11 *shadowInitData = initData; + if (!shadowInitData && mInitializeAllocations) + { + shadowInitData = createInitDataIfNeeded(desc); + } + + HRESULT hr = CreateResource(device, desc, shadowInitData, &resource); + if (FAILED(hr)) + { + ASSERT(!resource); + if (d3d11::isDeviceLostError(hr)) + { + renderer->notifyDeviceLost(); + } + return gl::OutOfMemory() << "Error allocating " + << std::string(kResourceTypeNames[ResourceTypeIndex()]) << ". " + << gl::FmtHR(hr); + } + + if (!shadowInitData && mInitializeAllocations) + { + ANGLE_TRY(ClearResource(renderer, desc, resource)); + } + + ASSERT(resource); + incrResource(GetResourceTypeFromD3D11(), ComputeMemoryUsage(desc)); + *resourceOut = std::move(Resource11(resource, this)); + return gl::NoError(); +} + +void ResourceManager11::incrResource(ResourceType resourceType, uint64_t memorySize) +{ + size_t typeIndex = ResourceTypeIndex(resourceType); + + mAllocatedResourceCounts[typeIndex]++; + mAllocatedResourceDeviceMemory[typeIndex] += memorySize; + + // This checks for integer overflow. + ASSERT(mAllocatedResourceCounts[typeIndex] > 0); + ASSERT(mAllocatedResourceDeviceMemory[typeIndex] >= memorySize); +} + +void ResourceManager11::decrResource(ResourceType resourceType, uint64_t memorySize) +{ + size_t typeIndex = ResourceTypeIndex(resourceType); + + ASSERT(mAllocatedResourceCounts[typeIndex] > 0); + mAllocatedResourceCounts[typeIndex]--; + ASSERT(mAllocatedResourceDeviceMemory[typeIndex] >= memorySize); + mAllocatedResourceDeviceMemory[typeIndex] -= memorySize; +} + +void ResourceManager11::onReleaseGeneric(ResourceType resourceType, ID3D11DeviceChild *resource) +{ + ASSERT(resource); + decrResource(resourceType, ComputeGenericMemoryUsage(resourceType, resource)); +} + +template <> +const D3D11_SUBRESOURCE_DATA *ResourceManager11::createInitDataIfNeeded( + const D3D11_TEXTURE2D_DESC *desc) +{ + ASSERT(desc); + + if ((desc->BindFlags & (D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_RENDER_TARGET)) != 0) + { + // This will be done using ClearView methods. + return nullptr; + } + + size_t requiredSize = static_cast(ComputeMemoryUsage(desc)); + if (mZeroMemory.size() < requiredSize) + { + mZeroMemory.resize(requiredSize); + mZeroMemory.fill(kDebugInitTextureDataValue); + } + + const auto &formatSizeInfo = d3d11::GetDXGIFormatSizeInfo(desc->Format); + + UINT subresourceCount = desc->MipLevels * desc->ArraySize; + if (mShadowInitData.size() < subresourceCount) + { + mShadowInitData.resize(subresourceCount); + } + + for (UINT mipLevel = 0; mipLevel < desc->MipLevels; ++mipLevel) + { + for (UINT arrayIndex = 0; arrayIndex < desc->ArraySize; ++arrayIndex) + { + UINT subresourceIndex = D3D11CalcSubresource(mipLevel, arrayIndex, desc->MipLevels); + D3D11_SUBRESOURCE_DATA *data = &mShadowInitData[subresourceIndex]; + + UINT levelWidth = std::max(desc->Width >> mipLevel, 1u); + UINT levelHeight = std::max(desc->Height >> mipLevel, 1u); + + data->SysMemPitch = levelWidth * formatSizeInfo.pixelBytes; + data->SysMemSlicePitch = data->SysMemPitch * levelHeight; + data->pSysMem = mZeroMemory.data(); + } + } + + return mShadowInitData.data(); +} + +template <> +const D3D11_SUBRESOURCE_DATA *ResourceManager11::createInitDataIfNeeded( + const D3D11_TEXTURE3D_DESC *desc) +{ + ASSERT(desc); + + if ((desc->BindFlags & D3D11_BIND_RENDER_TARGET) != 0) + { + // This will be done using ClearView methods. + return nullptr; + } + + size_t requiredSize = static_cast(ComputeMemoryUsage(desc)); + if (mZeroMemory.size() < requiredSize) + { + mZeroMemory.resize(requiredSize); + mZeroMemory.fill(kDebugInitTextureDataValue); + } + + const auto &formatSizeInfo = d3d11::GetDXGIFormatSizeInfo(desc->Format); + + UINT subresourceCount = desc->MipLevels; + if (mShadowInitData.size() < subresourceCount) + { + mShadowInitData.resize(subresourceCount); + } + + for (UINT mipLevel = 0; mipLevel < desc->MipLevels; ++mipLevel) + { + UINT subresourceIndex = D3D11CalcSubresource(mipLevel, 0, desc->MipLevels); + D3D11_SUBRESOURCE_DATA *data = &mShadowInitData[subresourceIndex]; + + UINT levelWidth = std::max(desc->Width >> mipLevel, 1u); + UINT levelHeight = std::max(desc->Height >> mipLevel, 1u); + + data->SysMemPitch = levelWidth * formatSizeInfo.pixelBytes; + data->SysMemSlicePitch = data->SysMemPitch * levelHeight; + data->pSysMem = mZeroMemory.data(); + } + + return mShadowInitData.data(); +} + +template +GetInitDataFromD3D11 *ResourceManager11::createInitDataIfNeeded(const GetDescFromD3D11 *desc) +{ + // No-op. + return nullptr; +} + +void ResourceManager11::setAllocationsInitialized(bool initialize) +{ + mInitializeAllocations = initialize; +} + +#define ANGLE_INSTANTIATE_OP(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \ + \ +template \ +gl::Error \ + ResourceManager11::allocate(Renderer11 *, const DESCTYPE *, INITDATATYPE *, \ + Resource11 *); + +ANGLE_RESOURCE_TYPE_OP(Instantitate, ANGLE_INSTANTIATE_OP) +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.h new file mode 100644 index 0000000000..0bdde9f8b6 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.h @@ -0,0 +1,366 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// ResourceManager11: +// Centralized point of allocation for all D3D11 Resources. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_RESOURCEFACTORY11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_RESOURCEFACTORY11_H_ + +#include +#include + +#include "common/MemoryBuffer.h" +#include "common/angleutils.h" +#include "common/debug.h" +#include "libANGLE/Error.h" +#include "libANGLE/renderer/renderer_utils.h" + +namespace rx +{ +// These two methods are declared here to prevent circular includes. +namespace d3d11 +{ +HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name); + +template +HRESULT SetDebugName(angle::ComPtr &resource, const char *name) +{ + return SetDebugName(resource.Get(), name); +} +} // namespace d3d11 + +class Renderer11; +class ResourceManager11; +template +class SharedResource11; +class TextureHelper11; + +using InputElementArray = WrappedArray; +using ShaderData = WrappedArray; + +// Format: ResourceType, D3D11 type, DESC type, init data type. +#define ANGLE_RESOURCE_TYPE_OP(NAME, OP) \ + OP(NAME, BlendState, ID3D11BlendState, D3D11_BLEND_DESC, void) \ + OP(NAME, Buffer, ID3D11Buffer, D3D11_BUFFER_DESC, const D3D11_SUBRESOURCE_DATA) \ + OP(NAME, ComputeShader, ID3D11ComputeShader, ShaderData, void) \ + OP(NAME, DepthStencilState, ID3D11DepthStencilState, D3D11_DEPTH_STENCIL_DESC, void) \ + OP(NAME, DepthStencilView, ID3D11DepthStencilView, D3D11_DEPTH_STENCIL_VIEW_DESC, \ + ID3D11Resource) \ + OP(NAME, GeometryShader, ID3D11GeometryShader, ShaderData, \ + const std::vector) \ + OP(NAME, InputLayout, ID3D11InputLayout, InputElementArray, const ShaderData) \ + OP(NAME, PixelShader, ID3D11PixelShader, ShaderData, void) \ + OP(NAME, Query, ID3D11Query, D3D11_QUERY_DESC, void) \ + OP(NAME, RasterizerState, ID3D11RasterizerState, D3D11_RASTERIZER_DESC, void) \ + OP(NAME, RenderTargetView, ID3D11RenderTargetView, D3D11_RENDER_TARGET_VIEW_DESC, \ + ID3D11Resource) \ + OP(NAME, SamplerState, ID3D11SamplerState, D3D11_SAMPLER_DESC, void) \ + OP(NAME, ShaderResourceView, ID3D11ShaderResourceView, D3D11_SHADER_RESOURCE_VIEW_DESC, \ + ID3D11Resource) \ + OP(NAME, Texture2D, ID3D11Texture2D, D3D11_TEXTURE2D_DESC, const D3D11_SUBRESOURCE_DATA) \ + OP(NAME, Texture3D, ID3D11Texture3D, D3D11_TEXTURE3D_DESC, const D3D11_SUBRESOURCE_DATA) \ + OP(NAME, VertexShader, ID3D11VertexShader, ShaderData, void) + +#define ANGLE_RESOURCE_TYPE_LIST(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) RESTYPE, + +enum class ResourceType +{ + ANGLE_RESOURCE_TYPE_OP(List, ANGLE_RESOURCE_TYPE_LIST) Last +}; + +#undef ANGLE_RESOURCE_TYPE_LIST + +constexpr size_t ResourceTypeIndex(ResourceType resourceType) +{ + return static_cast(resourceType); +} + +constexpr size_t NumResourceTypes = ResourceTypeIndex(ResourceType::Last); + +#define ANGLE_RESOURCE_TYPE_TO_D3D11(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \ + \ +template<> struct NAME \ + { \ + using Value = D3D11TYPE; \ + }; + +#define ANGLE_RESOURCE_TYPE_TO_DESC(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \ + \ +template<> struct NAME \ + { \ + using Value = DESCTYPE; \ + }; + +#define ANGLE_RESOURCE_TYPE_TO_INIT_DATA(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \ + \ +template<> struct NAME \ + { \ + using Value = INITDATATYPE; \ + }; + +#define ANGLE_RESOURCE_TYPE_TO_TYPE(NAME, OP) \ + template \ + struct NAME; \ + ANGLE_RESOURCE_TYPE_OP(NAME, OP) \ + \ +template struct NAME \ + { \ + }; \ + \ +template using Get##NAME = typename NAME::Value; + +ANGLE_RESOURCE_TYPE_TO_TYPE(D3D11Type, ANGLE_RESOURCE_TYPE_TO_D3D11) +ANGLE_RESOURCE_TYPE_TO_TYPE(DescType, ANGLE_RESOURCE_TYPE_TO_DESC) +ANGLE_RESOURCE_TYPE_TO_TYPE(InitDataType, ANGLE_RESOURCE_TYPE_TO_INIT_DATA) + +#undef ANGLE_RESOURCE_TYPE_TO_D3D11 +#undef ANGLE_RESOURCE_TYPE_TO_DESC +#undef ANGLE_RESOURCE_TYPE_TO_INIT_DATA +#undef ANGLE_RESOURCE_TYPE_TO_TYPE + +#define ANGLE_TYPE_TO_RESOURCE_TYPE(NAME, OP) \ + template \ + struct NAME; \ + ANGLE_RESOURCE_TYPE_OP(NAME, OP) \ + \ +template struct NAME \ + { \ + }; \ + \ +template constexpr ResourceType Get##NAME() \ + { \ + return NAME::Value; \ + } + +#define ANGLE_D3D11_TO_RESOURCE_TYPE(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \ + \ +template<> struct NAME \ + { \ + static constexpr ResourceType Value = ResourceType::RESTYPE; \ + }; + +ANGLE_TYPE_TO_RESOURCE_TYPE(ResourceTypeFromD3D11, ANGLE_D3D11_TO_RESOURCE_TYPE) + +#undef ANGLE_D3D11_TO_RESOURCE_TYPE +#undef ANGLE_TYPE_TO_RESOURCE_TYPE + +template +using GetDescFromD3D11 = GetDescType::Value>; + +template +using GetInitDataFromD3D11 = GetInitDataType::Value>; + +template +constexpr size_t ResourceTypeIndex() +{ + return static_cast(GetResourceTypeFromD3D11()); +} + +template +struct TypedData +{ + TypedData() {} + ~TypedData(); + + T *object = nullptr; + ResourceManager11 *manager = nullptr; +}; + +// Smart pointer type. Wraps the resource and a factory for safe deletion. +template class Pointer, typename DataT> +class Resource11Base : angle::NonCopyable +{ + public: + T *get() const { return mData->object; } + T *const *getPointer() const { return &mData->object; } + + void setDebugName(const char *name) { d3d11::SetDebugName(mData->object, name); } + + void set(T *object) + { + ASSERT(!valid()); + mData->object = object; + } + + bool valid() const { return (mData->object != nullptr); } + + void reset() + { + if (valid()) + mData.reset(new DataT()); + } + + ResourceSerial getSerial() const + { + return ResourceSerial(reinterpret_cast(mData->object)); + } + + protected: + friend class TextureHelper11; + + Resource11Base() : mData(new DataT()) {} + + Resource11Base(Resource11Base &&movedObj) : mData(new DataT()) + { + std::swap(mData, movedObj.mData); + } + + virtual ~Resource11Base() { mData.reset(); } + + Resource11Base &operator=(Resource11Base &&movedObj) + { + std::swap(mData, movedObj.mData); + return *this; + } + + Pointer mData; +}; + +template +using UniquePtr = typename std::unique_ptr>; + +template +class Resource11 : public Resource11Base> +{ + public: + Resource11() {} + Resource11(Resource11 &&other) + : Resource11Base>(std::move(other)) + { + } + Resource11 &operator=(Resource11 &&other) + { + std::swap(this->mData, other.mData); + return *this; + } + + private: + template + friend class SharedResource11; + friend class ResourceManager11; + + Resource11(ResourceT *object, ResourceManager11 *manager) + { + this->mData->object = object; + this->mData->manager = manager; + } +}; + +template +class SharedResource11 : public Resource11Base> +{ + public: + SharedResource11() {} + SharedResource11(SharedResource11 &&movedObj) + : Resource11Base>(std::move(movedObj)) + { + } + + SharedResource11 &operator=(SharedResource11 &&other) + { + std::swap(this->mData, other.mData); + return *this; + } + + SharedResource11 makeCopy() const + { + SharedResource11 copy; + copy.mData = this->mData; + return std::move(copy); + } + + private: + friend class ResourceManager11; + SharedResource11(Resource11 &&obj) : Resource11Base>() + { + std::swap(this->mData->manager, obj.mData->manager); + + // Can't use std::swap because of ID3D11Resource. + auto temp = this->mData->object; + this->mData->object = obj.mData->object; + obj.mData->object = static_cast(temp); + } +}; + +class ResourceManager11 final : angle::NonCopyable +{ + public: + ResourceManager11(); + ~ResourceManager11(); + + template + gl::Error allocate(Renderer11 *renderer, + const GetDescFromD3D11 *desc, + GetInitDataFromD3D11 *initData, + Resource11 *resourceOut); + + template + gl::Error allocate(Renderer11 *renderer, + const GetDescFromD3D11 *desc, + GetInitDataFromD3D11 *initData, + SharedResource11 *sharedRes) + { + Resource11 res; + ANGLE_TRY(allocate(renderer, desc, initData, &res)); + *sharedRes = std::move(res); + return gl::NoError(); + } + + template + void onRelease(T *resource) + { + onReleaseGeneric(GetResourceTypeFromD3D11(), resource); + } + + void onReleaseGeneric(ResourceType resourceType, ID3D11DeviceChild *resource); + + void setAllocationsInitialized(bool initialize); + + private: + void incrResource(ResourceType resourceType, uint64_t memorySize); + void decrResource(ResourceType resourceType, uint64_t memorySize); + + template + GetInitDataFromD3D11 *createInitDataIfNeeded(const GetDescFromD3D11 *desc); + + bool mInitializeAllocations; + + std::array mAllocatedResourceCounts; + std::array mAllocatedResourceDeviceMemory; + angle::MemoryBuffer mZeroMemory; + + std::vector mShadowInitData; +}; + +template +TypedData::~TypedData() +{ + if (object) + { + // We can have a nullptr factory when holding passed-in resources. + if (manager) + { + manager->onRelease(object); + } + object->Release(); + } +} + +#define ANGLE_RESOURCE_TYPE_CLASS(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \ + using RESTYPE = Resource11; + +namespace d3d11 +{ +ANGLE_RESOURCE_TYPE_OP(ClassList, ANGLE_RESOURCE_TYPE_CLASS) + +using SharedSRV = SharedResource11; +} // namespace d3d11 + +#undef ANGLE_RESOURCE_TYPE_CLASS + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_RESOURCEFACTORY11_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp index 4da51afe49..73a530add0 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp @@ -13,86 +13,107 @@ namespace rx { -ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D11PixelShader *executable) - : ShaderExecutableD3D(function, length) +ShaderExecutable11::ShaderExecutable11(const void *function, + size_t length, + d3d11::PixelShader &&executable) + : ShaderExecutableD3D(function, length), + mPixelExecutable(std::move(executable)), + mVertexExecutable(), + mGeometryExecutable(), + mStreamOutExecutable(), + mComputeExecutable() { - mPixelExecutable = executable; - mVertexExecutable = NULL; - mGeometryExecutable = NULL; - mStreamOutExecutable = NULL; } -ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D11VertexShader *executable, ID3D11GeometryShader *streamOut) - : ShaderExecutableD3D(function, length) +ShaderExecutable11::ShaderExecutable11(const void *function, + size_t length, + d3d11::VertexShader &&executable, + d3d11::GeometryShader &&streamOut) + : ShaderExecutableD3D(function, length), + mPixelExecutable(), + mVertexExecutable(std::move(executable)), + mGeometryExecutable(), + mStreamOutExecutable(std::move(streamOut)), + mComputeExecutable() { - mVertexExecutable = executable; - mPixelExecutable = NULL; - mGeometryExecutable = NULL; - mStreamOutExecutable = streamOut; } -ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D11GeometryShader *executable) - : ShaderExecutableD3D(function, length) +ShaderExecutable11::ShaderExecutable11(const void *function, + size_t length, + d3d11::GeometryShader &&executable) + : ShaderExecutableD3D(function, length), + mPixelExecutable(), + mVertexExecutable(), + mGeometryExecutable(std::move(executable)), + mStreamOutExecutable(), + mComputeExecutable() +{ +} + +ShaderExecutable11::ShaderExecutable11(const void *function, + size_t length, + d3d11::ComputeShader &&executable) + : ShaderExecutableD3D(function, length), + mPixelExecutable(), + mVertexExecutable(), + mGeometryExecutable(), + mStreamOutExecutable(), + mComputeExecutable(std::move(executable)) { - mGeometryExecutable = executable; - mVertexExecutable = NULL; - mPixelExecutable = NULL; - mStreamOutExecutable = NULL; } ShaderExecutable11::~ShaderExecutable11() { - SafeRelease(mVertexExecutable); - SafeRelease(mPixelExecutable); - SafeRelease(mGeometryExecutable); - SafeRelease(mStreamOutExecutable); } -ID3D11VertexShader *ShaderExecutable11::getVertexShader() const +const d3d11::VertexShader &ShaderExecutable11::getVertexShader() const { return mVertexExecutable; } -ID3D11PixelShader *ShaderExecutable11::getPixelShader() const +const d3d11::PixelShader &ShaderExecutable11::getPixelShader() const { return mPixelExecutable; } -ID3D11GeometryShader *ShaderExecutable11::getGeometryShader() const +const d3d11::GeometryShader &ShaderExecutable11::getGeometryShader() const { return mGeometryExecutable; } -ID3D11GeometryShader *ShaderExecutable11::getStreamOutShader() const +const d3d11::GeometryShader &ShaderExecutable11::getStreamOutShader() const { return mStreamOutExecutable; } -UniformStorage11::UniformStorage11(Renderer11 *renderer, size_t initialSize) - : UniformStorageD3D(initialSize), - mConstantBuffer(NULL) +const d3d11::ComputeShader &ShaderExecutable11::getComputeShader() const { - ID3D11Device *d3d11Device = renderer->getDevice(); + return mComputeExecutable; +} - if (initialSize > 0) - { - D3D11_BUFFER_DESC constantBufferDescription = {0}; - constantBufferDescription.ByteWidth = static_cast(initialSize); - constantBufferDescription.Usage = D3D11_USAGE_DYNAMIC; - constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - constantBufferDescription.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - constantBufferDescription.MiscFlags = 0; - constantBufferDescription.StructureByteStride = 0; - - HRESULT result = d3d11Device->CreateBuffer(&constantBufferDescription, NULL, &mConstantBuffer); - UNUSED_ASSERTION_VARIABLE(result); - ASSERT(SUCCEEDED(result)); - } +UniformStorage11::UniformStorage11(size_t initialSize) + : UniformStorageD3D(initialSize), mConstantBuffer() +{ } UniformStorage11::~UniformStorage11() { - SafeRelease(mConstantBuffer); } +gl::Error UniformStorage11::getConstantBuffer(Renderer11 *renderer, const d3d11::Buffer **bufferOut) +{ + if (size() > 0 && !mConstantBuffer.valid()) + { + D3D11_BUFFER_DESC desc = {0}; + desc.ByteWidth = static_cast(size()); + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + + ANGLE_TRY(renderer->allocateResource(desc, &mConstantBuffer)); + } + + *bufferOut = &mConstantBuffer; + return gl::NoError(); } + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h index 379f39fe53..3f417578a3 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h @@ -11,6 +11,7 @@ #define LIBANGLE_RENDERER_D3D_D3D11_SHADEREXECUTABLE11_H_ #include "libANGLE/renderer/d3d/ShaderExecutableD3D.h" +#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h" namespace rx { @@ -20,36 +21,42 @@ class UniformStorage11; class ShaderExecutable11 : public ShaderExecutableD3D { public: - ShaderExecutable11(const void *function, size_t length, ID3D11PixelShader *executable); - ShaderExecutable11(const void *function, size_t length, ID3D11VertexShader *executable, ID3D11GeometryShader *streamOut); - ShaderExecutable11(const void *function, size_t length, ID3D11GeometryShader *executable); + ShaderExecutable11(const void *function, size_t length, d3d11::PixelShader &&executable); + ShaderExecutable11(const void *function, + size_t length, + d3d11::VertexShader &&executable, + d3d11::GeometryShader &&streamOut); + ShaderExecutable11(const void *function, size_t length, d3d11::GeometryShader &&executable); + ShaderExecutable11(const void *function, size_t length, d3d11::ComputeShader &&executable); - virtual ~ShaderExecutable11(); + ~ShaderExecutable11() override; - ID3D11PixelShader *getPixelShader() const; - ID3D11VertexShader *getVertexShader() const; - ID3D11GeometryShader *getGeometryShader() const; - ID3D11GeometryShader *getStreamOutShader() const; + const d3d11::PixelShader &getPixelShader() const; + const d3d11::VertexShader &getVertexShader() const; + const d3d11::GeometryShader &getGeometryShader() const; + const d3d11::GeometryShader &getStreamOutShader() const; + const d3d11::ComputeShader &getComputeShader() const; private: - ID3D11PixelShader *mPixelExecutable; - ID3D11VertexShader *mVertexExecutable; - ID3D11GeometryShader *mGeometryExecutable; - ID3D11GeometryShader *mStreamOutExecutable; + d3d11::PixelShader mPixelExecutable; + d3d11::VertexShader mVertexExecutable; + d3d11::GeometryShader mGeometryExecutable; + d3d11::GeometryShader mStreamOutExecutable; + d3d11::ComputeShader mComputeExecutable; }; class UniformStorage11 : public UniformStorageD3D { public: - UniformStorage11(Renderer11 *renderer, size_t initialSize); - virtual ~UniformStorage11(); + UniformStorage11(size_t initialSize); + ~UniformStorage11() override; - ID3D11Buffer *getConstantBuffer() const { return mConstantBuffer; } + gl::Error getConstantBuffer(Renderer11 *renderer, const d3d11::Buffer **bufferOut); private: - ID3D11Buffer *mConstantBuffer; + d3d11::Buffer mConstantBuffer; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_D3D11_SHADEREXECUTABLE11_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp index aa34fd4de8..e9902d3f14 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp @@ -8,11 +8,22 @@ #include "libANGLE/renderer/d3d/d3d11/StateManager11.h" -#include "common/BitSetIterator.h" +#include "common/bitset_utils.h" #include "common/utilities.h" +#include "libANGLE/Context.h" +#include "libANGLE/Query.h" +#include "libANGLE/VertexArray.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" +#include "libANGLE/renderer/d3d/d3d11/Buffer11.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" #include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h" -#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/IndexBuffer11.h" #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h" +#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h" +#include "libANGLE/renderer/d3d/d3d11/TransformFeedback11.h" +#include "libANGLE/renderer/d3d/d3d11/VertexArray11.h" namespace rx { @@ -22,15 +33,16 @@ namespace bool ImageIndexConflictsWithSRV(const gl::ImageIndex &index, D3D11_SHADER_RESOURCE_VIEW_DESC desc) { unsigned mipLevel = index.mipIndex; - unsigned layerIndex = index.layerIndex; + GLint layerIndex = index.layerIndex; GLenum type = index.type; switch (desc.ViewDimension) { case D3D11_SRV_DIMENSION_TEXTURE2D: { - unsigned maxSrvMip = desc.Texture2D.MipLevels + desc.Texture2D.MostDetailedMip; - maxSrvMip = (desc.Texture2D.MipLevels == -1) ? INT_MAX : maxSrvMip; + bool allLevels = (desc.Texture2D.MipLevels == std::numeric_limits::max()); + unsigned int maxSrvMip = desc.Texture2D.MipLevels + desc.Texture2D.MostDetailedMip; + maxSrvMip = allLevels ? INT_MAX : maxSrvMip; unsigned mipMin = index.mipIndex; unsigned mipMax = (layerIndex == -1) ? INT_MAX : layerIndex; @@ -42,22 +54,25 @@ bool ImageIndexConflictsWithSRV(const gl::ImageIndex &index, D3D11_SHADER_RESOUR case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: { - unsigned maxSrvMip = + bool allLevels = (desc.Texture2DArray.MipLevels == std::numeric_limits::max()); + unsigned int maxSrvMip = desc.Texture2DArray.MipLevels + desc.Texture2DArray.MostDetailedMip; - maxSrvMip = (desc.Texture2DArray.MipLevels == -1) ? INT_MAX : maxSrvMip; + maxSrvMip = allLevels ? INT_MAX : maxSrvMip; unsigned maxSlice = desc.Texture2DArray.FirstArraySlice + desc.Texture2DArray.ArraySize; // Cube maps can be mapped to Texture2DArray SRVs return (type == GL_TEXTURE_2D_ARRAY || gl::IsCubeMapTextureTarget(type)) && desc.Texture2DArray.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip && - desc.Texture2DArray.FirstArraySlice <= layerIndex && layerIndex < maxSlice; + desc.Texture2DArray.FirstArraySlice <= static_cast(layerIndex) && + static_cast(layerIndex) < maxSlice; } case D3D11_SRV_DIMENSION_TEXTURECUBE: { - unsigned maxSrvMip = desc.TextureCube.MipLevels + desc.TextureCube.MostDetailedMip; - maxSrvMip = (desc.TextureCube.MipLevels == -1) ? INT_MAX : maxSrvMip; + bool allLevels = (desc.TextureCube.MipLevels == std::numeric_limits::max()); + unsigned int maxSrvMip = desc.TextureCube.MipLevels + desc.TextureCube.MostDetailedMip; + maxSrvMip = allLevels ? INT_MAX : maxSrvMip; return gl::IsCubeMapTextureTarget(type) && desc.TextureCube.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip; @@ -65,8 +80,9 @@ bool ImageIndexConflictsWithSRV(const gl::ImageIndex &index, D3D11_SHADER_RESOUR case D3D11_SRV_DIMENSION_TEXTURE3D: { - unsigned maxSrvMip = desc.Texture3D.MipLevels + desc.Texture3D.MostDetailedMip; - maxSrvMip = (desc.Texture3D.MipLevels == -1) ? INT_MAX : maxSrvMip; + bool allLevels = (desc.Texture3D.MipLevels == std::numeric_limits::max()); + unsigned int maxSrvMip = desc.Texture3D.MipLevels + desc.Texture3D.MostDetailedMip; + maxSrvMip = allLevels ? INT_MAX : maxSrvMip; return type == GL_TEXTURE_3D && desc.Texture3D.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip; @@ -82,15 +98,97 @@ bool ImageIndexConflictsWithSRV(const gl::ImageIndex &index, D3D11_SHADER_RESOUR // Does *not* increment the resource ref count!! ID3D11Resource *GetViewResource(ID3D11View *view) { - ID3D11Resource *resource = NULL; + ID3D11Resource *resource = nullptr; ASSERT(view); view->GetResource(&resource); resource->Release(); return resource; } +int GetWrapBits(GLenum wrap) +{ + switch (wrap) + { + case GL_CLAMP_TO_EDGE: + return 0x1; + case GL_REPEAT: + return 0x2; + case GL_MIRRORED_REPEAT: + return 0x3; + default: + UNREACHABLE(); + return 0; + } +} + +Optional FindFirstNonInstanced( + const std::vector ¤tAttributes) +{ + for (size_t index = 0; index < currentAttributes.size(); ++index) + { + if (currentAttributes[index]->divisor == 0) + { + return Optional(index); + } + } + + return Optional::Invalid(); +} + +void SortAttributesByLayout(const gl::Program *program, + const std::vector &vertexArrayAttribs, + const std::vector ¤tValueAttribs, + AttribIndexArray *sortedD3DSemanticsOut, + std::vector *sortedAttributesOut) +{ + sortedAttributesOut->clear(); + + const auto &locationToSemantic = + GetImplAs(program)->getAttribLocationToD3DSemantics(); + + for (auto locationIndex : program->getActiveAttribLocationsMask()) + { + int d3dSemantic = locationToSemantic[locationIndex]; + if (sortedAttributesOut->size() <= static_cast(d3dSemantic)) + { + sortedAttributesOut->resize(d3dSemantic + 1); + } + + (*sortedD3DSemanticsOut)[d3dSemantic] = d3dSemantic; + + const auto *arrayAttrib = &vertexArrayAttribs[locationIndex]; + if (arrayAttrib->attribute && arrayAttrib->attribute->enabled) + { + (*sortedAttributesOut)[d3dSemantic] = arrayAttrib; + } + else + { + ASSERT(currentValueAttribs[locationIndex].attribute); + (*sortedAttributesOut)[d3dSemantic] = ¤tValueAttribs[locationIndex]; + } + } +} + +void UpdateUniformBuffer(ID3D11DeviceContext *deviceContext, + UniformStorage11 *storage, + const d3d11::Buffer *buffer) +{ + deviceContext->UpdateSubresource(buffer->get(), 0, nullptr, storage->getDataPointer(0, 0), 0, + 0); +} + } // anonymous namespace +// StateManager11::SRVCache Implementation. + +StateManager11::SRVCache::SRVCache() : mHighestUsedSRV(0) +{ +} + +StateManager11::SRVCache::~SRVCache() +{ +} + void StateManager11::SRVCache::update(size_t resourceIndex, ID3D11ShaderResourceView *srv) { ASSERT(resourceIndex < mCurrentSRVs.size()); @@ -128,27 +226,348 @@ void StateManager11::SRVCache::clear() mHighestUsedSRV = 0; } +// ShaderConstants11 implementation + +ShaderConstants11::ShaderConstants11() + : mVertexDirty(true), + mPixelDirty(true), + mComputeDirty(true), + mSamplerMetadataVSDirty(true), + mSamplerMetadataPSDirty(true), + mSamplerMetadataCSDirty(true) +{ +} + +ShaderConstants11::~ShaderConstants11() +{ +} + +void ShaderConstants11::init(const gl::Caps &caps) +{ + mSamplerMetadataVS.resize(caps.maxVertexTextureImageUnits); + mSamplerMetadataPS.resize(caps.maxTextureImageUnits); + mSamplerMetadataCS.resize(caps.maxComputeTextureImageUnits); +} + +size_t ShaderConstants11::getRequiredBufferSize(gl::SamplerType samplerType) const +{ + switch (samplerType) + { + case gl::SAMPLER_VERTEX: + return sizeof(Vertex) + mSamplerMetadataVS.size() * sizeof(SamplerMetadata); + case gl::SAMPLER_PIXEL: + return sizeof(Pixel) + mSamplerMetadataPS.size() * sizeof(SamplerMetadata); + case gl::SAMPLER_COMPUTE: + return sizeof(Compute) + mSamplerMetadataCS.size() * sizeof(SamplerMetadata); + default: + UNREACHABLE(); + return 0; + } +} + +void ShaderConstants11::markDirty() +{ + mVertexDirty = true; + mPixelDirty = true; + mComputeDirty = true; + mSamplerMetadataVSDirty = true; + mSamplerMetadataPSDirty = true; + mSamplerMetadataCSDirty = true; +} + +bool ShaderConstants11::updateSamplerMetadata(SamplerMetadata *data, const gl::Texture &texture) +{ + bool dirty = false; + unsigned int baseLevel = texture.getTextureState().getEffectiveBaseLevel(); + GLenum sizedFormat = + texture.getFormat(texture.getTarget(), baseLevel).info->sizedInternalFormat; + if (data->baseLevel != static_cast(baseLevel)) + { + data->baseLevel = static_cast(baseLevel); + dirty = true; + } + + // Some metadata is needed only for integer textures. We avoid updating the constant buffer + // unnecessarily by changing the data only in case the texture is an integer texture and + // the values have changed. + bool needIntegerTextureMetadata = false; + // internalFormatBits == 0 means a 32-bit texture in the case of integer textures. + int internalFormatBits = 0; + switch (sizedFormat) + { + case GL_RGBA32I: + case GL_RGBA32UI: + case GL_RGB32I: + case GL_RGB32UI: + case GL_RG32I: + case GL_RG32UI: + case GL_R32I: + case GL_R32UI: + needIntegerTextureMetadata = true; + break; + case GL_RGBA16I: + case GL_RGBA16UI: + case GL_RGB16I: + case GL_RGB16UI: + case GL_RG16I: + case GL_RG16UI: + case GL_R16I: + case GL_R16UI: + needIntegerTextureMetadata = true; + internalFormatBits = 16; + break; + case GL_RGBA8I: + case GL_RGBA8UI: + case GL_RGB8I: + case GL_RGB8UI: + case GL_RG8I: + case GL_RG8UI: + case GL_R8I: + case GL_R8UI: + needIntegerTextureMetadata = true; + internalFormatBits = 8; + break; + case GL_RGB10_A2UI: + needIntegerTextureMetadata = true; + internalFormatBits = 10; + break; + default: + break; + } + if (needIntegerTextureMetadata) + { + if (data->internalFormatBits != internalFormatBits) + { + data->internalFormatBits = internalFormatBits; + dirty = true; + } + // Pack the wrap values into one integer so we can fit all the metadata in one 4-integer + // vector. + GLenum wrapS = texture.getWrapS(); + GLenum wrapT = texture.getWrapT(); + GLenum wrapR = texture.getWrapR(); + int wrapModes = GetWrapBits(wrapS) | (GetWrapBits(wrapT) << 2) | (GetWrapBits(wrapR) << 4); + if (data->wrapModes != wrapModes) + { + data->wrapModes = wrapModes; + dirty = true; + } + } + + return dirty; +} + +void ShaderConstants11::setComputeWorkGroups(GLuint numGroupsX, + GLuint numGroupsY, + GLuint numGroupsZ) +{ + mCompute.numWorkGroups[0] = numGroupsX; + mCompute.numWorkGroups[1] = numGroupsY; + mCompute.numWorkGroups[2] = numGroupsZ; + mComputeDirty = true; +} + +void ShaderConstants11::setMultiviewWriteToViewportIndex(GLfloat index) +{ + mVertex.multiviewWriteToViewportIndex = index; + mVertexDirty = true; + mPixel.multiviewWriteToViewportIndex = index; + mPixelDirty = true; +} + +void ShaderConstants11::onViewportChange(const gl::Rectangle &glViewport, + const D3D11_VIEWPORT &dxViewport, + bool is9_3, + bool presentPathFast) +{ + mVertexDirty = true; + mPixelDirty = true; + + // On Feature Level 9_*, we must emulate large and/or negative viewports in the shaders + // using viewAdjust (like the D3D9 renderer). + if (is9_3) + { + mVertex.viewAdjust[0] = static_cast((glViewport.width - dxViewport.Width) + + 2 * (glViewport.x - dxViewport.TopLeftX)) / + dxViewport.Width; + mVertex.viewAdjust[1] = static_cast((glViewport.height - dxViewport.Height) + + 2 * (glViewport.y - dxViewport.TopLeftY)) / + dxViewport.Height; + mVertex.viewAdjust[2] = static_cast(glViewport.width) / dxViewport.Width; + mVertex.viewAdjust[3] = static_cast(glViewport.height) / dxViewport.Height; + } + + mPixel.viewCoords[0] = glViewport.width * 0.5f; + mPixel.viewCoords[1] = glViewport.height * 0.5f; + mPixel.viewCoords[2] = glViewport.x + (glViewport.width * 0.5f); + mPixel.viewCoords[3] = glViewport.y + (glViewport.height * 0.5f); + + // Instanced pointsprite emulation requires ViewCoords to be defined in the + // the vertex shader. + mVertex.viewCoords[0] = mPixel.viewCoords[0]; + mVertex.viewCoords[1] = mPixel.viewCoords[1]; + mVertex.viewCoords[2] = mPixel.viewCoords[2]; + mVertex.viewCoords[3] = mPixel.viewCoords[3]; + + const float zNear = dxViewport.MinDepth; + const float zFar = dxViewport.MaxDepth; + + mPixel.depthFront[0] = (zFar - zNear) * 0.5f; + mPixel.depthFront[1] = (zNear + zFar) * 0.5f; + + mVertex.depthRange[0] = zNear; + mVertex.depthRange[1] = zFar; + mVertex.depthRange[2] = zFar - zNear; + + mPixel.depthRange[0] = zNear; + mPixel.depthRange[1] = zFar; + mPixel.depthRange[2] = zFar - zNear; + + mPixel.viewScale[0] = 1.0f; + mPixel.viewScale[1] = presentPathFast ? 1.0f : -1.0f; + // Updates to the multiviewWriteToViewportIndex member are to be handled whenever the draw + // framebuffer's layout is changed. + + mVertex.viewScale[0] = mPixel.viewScale[0]; + mVertex.viewScale[1] = mPixel.viewScale[1]; +} + +void ShaderConstants11::onSamplerChange(gl::SamplerType samplerType, + unsigned int samplerIndex, + const gl::Texture &texture) +{ + switch (samplerType) + { + case gl::SAMPLER_VERTEX: + if (updateSamplerMetadata(&mSamplerMetadataVS[samplerIndex], texture)) + { + mSamplerMetadataVSDirty = true; + } + break; + case gl::SAMPLER_PIXEL: + if (updateSamplerMetadata(&mSamplerMetadataPS[samplerIndex], texture)) + { + mSamplerMetadataPSDirty = true; + } + break; + case gl::SAMPLER_COMPUTE: + if (updateSamplerMetadata(&mSamplerMetadataCS[samplerIndex], texture)) + { + mSamplerMetadataCSDirty = true; + } + break; + default: + UNREACHABLE(); + break; + } +} + +gl::Error ShaderConstants11::updateBuffer(ID3D11DeviceContext *deviceContext, + gl::SamplerType samplerType, + const ProgramD3D &programD3D, + const d3d11::Buffer &driverConstantBuffer) +{ + bool dirty = false; + size_t dataSize = 0; + const uint8_t *data = nullptr; + const uint8_t *samplerData = nullptr; + + switch (samplerType) + { + case gl::SAMPLER_VERTEX: + dirty = mVertexDirty || mSamplerMetadataVSDirty; + dataSize = sizeof(Vertex); + data = reinterpret_cast(&mVertex); + samplerData = reinterpret_cast(mSamplerMetadataVS.data()); + mVertexDirty = false; + mSamplerMetadataVSDirty = false; + break; + case gl::SAMPLER_PIXEL: + dirty = mPixelDirty || mSamplerMetadataPSDirty; + dataSize = sizeof(Pixel); + data = reinterpret_cast(&mPixel); + samplerData = reinterpret_cast(mSamplerMetadataPS.data()); + mPixelDirty = false; + mSamplerMetadataPSDirty = false; + break; + case gl::SAMPLER_COMPUTE: + dirty = mComputeDirty || mSamplerMetadataCSDirty; + dataSize = sizeof(Compute); + data = reinterpret_cast(&mCompute); + samplerData = reinterpret_cast(mSamplerMetadataCS.data()); + mComputeDirty = false; + mSamplerMetadataCSDirty = false; + break; + default: + UNREACHABLE(); + break; + } + + ASSERT(driverConstantBuffer.valid()); + + if (!dirty) + { + return gl::NoError(); + } + + // Previous buffer contents are discarded, so we need to refresh the whole buffer. + D3D11_MAPPED_SUBRESOURCE mapping = {0}; + HRESULT result = + deviceContext->Map(driverConstantBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapping); + + if (FAILED(result)) + { + return gl::OutOfMemory() << "Internal error mapping constant buffer: " << gl::FmtHR(result); + } + + size_t samplerDataBytes = sizeof(SamplerMetadata) * programD3D.getUsedSamplerRange(samplerType); + + memcpy(mapping.pData, data, dataSize); + memcpy(reinterpret_cast(mapping.pData) + dataSize, samplerData, samplerDataBytes); + + deviceContext->Unmap(driverConstantBuffer.get(), 0); + + return gl::NoError(); +} + +static const GLenum QueryTypes[] = {GL_ANY_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED_CONSERVATIVE, + GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_TIME_ELAPSED_EXT, + GL_COMMANDS_COMPLETED_CHROMIUM}; + StateManager11::StateManager11(Renderer11 *renderer) : mRenderer(renderer), - mBlendStateIsDirty(false), + mInternalDirtyBits(), mCurBlendColor(0, 0, 0, 0), mCurSampleMask(0), - mDepthStencilStateIsDirty(false), mCurStencilRef(0), mCurStencilBackRef(0), mCurStencilSize(0), - mRasterizerStateIsDirty(false), - mScissorStateIsDirty(false), mCurScissorEnabled(false), mCurScissorRect(), - mViewportStateIsDirty(false), mCurViewport(), mCurNear(0.0f), mCurFar(0.0f), mViewportBounds(), + mRenderTargetIsDirty(true), mCurPresentPathFastEnabled(false), mCurPresentPathFastColorBufferHeight(0), - mAppliedDSV(angle::DirtyPointer) + mDirtyCurrentValueAttribs(), + mCurrentValueAttribs(), + mCurrentInputLayout(), + mInputLayoutIsDirty(false), + mVertexAttribsNeedTranslation(false), + mDirtyVertexBufferRange(gl::MAX_VERTEX_ATTRIBS, 0), + mCurrentPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_UNDEFINED), + mDirtySwizzles(false), + mAppliedIB(nullptr), + mAppliedIBFormat(DXGI_FORMAT_UNKNOWN), + mAppliedIBOffset(0), + mIndexBufferIsDirty(false), + mVertexDataManager(renderer), + mIndexDataManager(renderer), + mIsMultiviewEnabled(false), + mEmptySerial(mRenderer->generateSerial()), + mIsTransformFeedbackCurrentlyActiveUnpaused(false) { mCurBlendState.blend = false; mCurBlendState.sourceBlendRGB = GL_ONE; @@ -182,64 +601,127 @@ StateManager11::StateManager11(Renderer11 *renderer) mCurRasterState.rasterizerDiscard = false; mCurRasterState.cullFace = false; - mCurRasterState.cullMode = GL_BACK; + mCurRasterState.cullMode = gl::CullFaceMode::Back; mCurRasterState.frontFace = GL_CCW; mCurRasterState.polygonOffsetFill = false; mCurRasterState.polygonOffsetFactor = 0.0f; mCurRasterState.polygonOffsetUnits = 0.0f; mCurRasterState.pointDrawMode = false; mCurRasterState.multiSample = false; + + // Start with all internal dirty bits set. + mInternalDirtyBits.set(); + + // Initially all current value attributes must be updated on first use. + mDirtyCurrentValueAttribs.set(); + + mCurrentVertexBuffers.fill(nullptr); + mCurrentVertexStrides.fill(std::numeric_limits::max()); + mCurrentVertexOffsets.fill(std::numeric_limits::max()); } StateManager11::~StateManager11() { } +template +void StateManager11::setShaderResourceInternal(gl::SamplerType shaderType, + UINT resourceSlot, + const SRVType *srv) +{ + auto ¤tSRVs = (shaderType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs); + + ASSERT(static_cast(resourceSlot) < currentSRVs.size()); + const SRVRecord &record = currentSRVs[resourceSlot]; + + if (record.srv != reinterpret_cast(srv)) + { + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + ID3D11ShaderResourceView *srvPtr = srv ? srv->get() : nullptr; + if (shaderType == gl::SAMPLER_VERTEX) + { + deviceContext->VSSetShaderResources(resourceSlot, 1, &srvPtr); + } + else + { + deviceContext->PSSetShaderResources(resourceSlot, 1, &srvPtr); + } + + currentSRVs.update(resourceSlot, srvPtr); + } +} + void StateManager11::updateStencilSizeIfChanged(bool depthStencilInitialized, unsigned int stencilSize) { if (!depthStencilInitialized || stencilSize != mCurStencilSize) { - mCurStencilSize = stencilSize; - mDepthStencilStateIsDirty = true; + mCurStencilSize = stencilSize; + mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE); } } -void StateManager11::setViewportBounds(const int width, const int height) +void StateManager11::checkPresentPath(const gl::Context *context) { - if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3 && - (mViewportBounds.width != width || mViewportBounds.height != height)) - { - mViewportBounds = gl::Extents(width, height, 1); - mViewportStateIsDirty = true; - } -} + if (!mRenderer->presentPathFastEnabled()) + return; -void StateManager11::updatePresentPath(bool presentPathFastActive, - const gl::FramebufferAttachment *framebufferAttachment) -{ - const int colorBufferHeight = - framebufferAttachment ? framebufferAttachment->getSize().height : 0; + const auto *framebuffer = context->getGLState().getDrawFramebuffer(); + const auto *firstColorAttachment = framebuffer->getFirstColorbuffer(); + const bool presentPathFastActive = UsePresentPathFast(mRenderer, firstColorAttachment); + + const int colorBufferHeight = firstColorAttachment ? firstColorAttachment->getSize().height : 0; if ((mCurPresentPathFastEnabled != presentPathFastActive) || (presentPathFastActive && (colorBufferHeight != mCurPresentPathFastColorBufferHeight))) { mCurPresentPathFastEnabled = presentPathFastActive; mCurPresentPathFastColorBufferHeight = colorBufferHeight; - mViewportStateIsDirty = true; // Viewport may need to be vertically inverted - mScissorStateIsDirty = true; // Scissor rect may need to be vertically inverted - mRasterizerStateIsDirty = true; // Cull Mode may need to be inverted + + // Scissor rect may need to be vertically inverted + mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE); + + // Cull Mode may need to be inverted + mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE); + + // Viewport may need to be vertically inverted + invalidateViewport(context); } } -void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits) +gl::Error StateManager11::updateStateForCompute(const gl::Context *context, + GLuint numGroupsX, + GLuint numGroupsY, + GLuint numGroupsZ) +{ + mShaderConstants.setComputeWorkGroups(numGroupsX, numGroupsY, numGroupsZ); + + // TODO(jmadill): Use dirty bits. + const auto &glState = context->getGLState(); + auto *programD3D = GetImplAs(glState.getProgram()); + programD3D->updateSamplerMapping(); + + // TODO(jmadill): Use dirty bits. + ANGLE_TRY(generateSwizzlesForShader(context, gl::SAMPLER_COMPUTE)); + + // TODO(jmadill): More complete implementation. + ANGLE_TRY(syncTextures(context)); + + // TODO(Xinghua): applyUniformBuffers for compute shader. + + return gl::NoError(); +} + +void StateManager11::syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits) { if (!dirtyBits.any()) { return; } - for (unsigned int dirtyBit : angle::IterateBitSet(dirtyBits)) + const auto &state = context->getGLState(); + + for (auto dirtyBit : dirtyBits) { switch (dirtyBit) { @@ -249,7 +731,7 @@ void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBit if (blendState.blendEquationRGB != mCurBlendState.blendEquationRGB || blendState.blendEquationAlpha != mCurBlendState.blendEquationAlpha) { - mBlendStateIsDirty = true; + mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE); } break; } @@ -261,27 +743,27 @@ void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBit blendState.sourceBlendAlpha != mCurBlendState.sourceBlendAlpha || blendState.destBlendAlpha != mCurBlendState.destBlendAlpha) { - mBlendStateIsDirty = true; + mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE); } break; } case gl::State::DIRTY_BIT_BLEND_ENABLED: if (state.getBlendState().blend != mCurBlendState.blend) { - mBlendStateIsDirty = true; + mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE); } break; case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED: if (state.getBlendState().sampleAlphaToCoverage != mCurBlendState.sampleAlphaToCoverage) { - mBlendStateIsDirty = true; + mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE); } break; case gl::State::DIRTY_BIT_DITHER_ENABLED: if (state.getBlendState().dither != mCurBlendState.dither) { - mBlendStateIsDirty = true; + mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE); } break; case gl::State::DIRTY_BIT_COLOR_MASK: @@ -292,38 +774,38 @@ void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBit blendState.colorMaskBlue != mCurBlendState.colorMaskBlue || blendState.colorMaskAlpha != mCurBlendState.colorMaskAlpha) { - mBlendStateIsDirty = true; + mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE); } break; } case gl::State::DIRTY_BIT_BLEND_COLOR: if (state.getBlendColor() != mCurBlendColor) { - mBlendStateIsDirty = true; + mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE); } break; case gl::State::DIRTY_BIT_DEPTH_MASK: if (state.getDepthStencilState().depthMask != mCurDepthStencilState.depthMask) { - mDepthStencilStateIsDirty = true; + mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE); } break; case gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED: if (state.getDepthStencilState().depthTest != mCurDepthStencilState.depthTest) { - mDepthStencilStateIsDirty = true; + mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE); } break; case gl::State::DIRTY_BIT_DEPTH_FUNC: if (state.getDepthStencilState().depthFunc != mCurDepthStencilState.depthFunc) { - mDepthStencilStateIsDirty = true; + mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE); } break; case gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED: if (state.getDepthStencilState().stencilTest != mCurDepthStencilState.stencilTest) { - mDepthStencilStateIsDirty = true; + mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE); } break; case gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT: @@ -333,7 +815,7 @@ void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBit depthStencil.stencilMask != mCurDepthStencilState.stencilMask || state.getStencilRef() != mCurStencilRef) { - mDepthStencilStateIsDirty = true; + mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE); } break; } @@ -344,7 +826,7 @@ void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBit depthStencil.stencilBackMask != mCurDepthStencilState.stencilBackMask || state.getStencilBackRef() != mCurStencilBackRef) { - mDepthStencilStateIsDirty = true; + mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE); } break; } @@ -352,14 +834,14 @@ void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBit if (state.getDepthStencilState().stencilWritemask != mCurDepthStencilState.stencilWritemask) { - mDepthStencilStateIsDirty = true; + mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE); } break; case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK: if (state.getDepthStencilState().stencilBackWritemask != mCurDepthStencilState.stencilBackWritemask) { - mDepthStencilStateIsDirty = true; + mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE); } break; case gl::State::DIRTY_BIT_STENCIL_OPS_FRONT: @@ -370,7 +852,7 @@ void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBit mCurDepthStencilState.stencilPassDepthFail || depthStencil.stencilPassDepthPass != mCurDepthStencilState.stencilPassDepthPass) { - mDepthStencilStateIsDirty = true; + mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE); } break; } @@ -383,33 +865,33 @@ void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBit depthStencil.stencilBackPassDepthPass != mCurDepthStencilState.stencilBackPassDepthPass) { - mDepthStencilStateIsDirty = true; + mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE); } break; } case gl::State::DIRTY_BIT_CULL_FACE_ENABLED: if (state.getRasterizerState().cullFace != mCurRasterState.cullFace) { - mRasterizerStateIsDirty = true; + mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE); } break; case gl::State::DIRTY_BIT_CULL_FACE: if (state.getRasterizerState().cullMode != mCurRasterState.cullMode) { - mRasterizerStateIsDirty = true; + mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE); } break; case gl::State::DIRTY_BIT_FRONT_FACE: if (state.getRasterizerState().frontFace != mCurRasterState.frontFace) { - mRasterizerStateIsDirty = true; + mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE); } break; case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED: if (state.getRasterizerState().polygonOffsetFill != mCurRasterState.polygonOffsetFill) { - mRasterizerStateIsDirty = true; + mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE); } break; case gl::State::DIRTY_BIT_POLYGON_OFFSET: @@ -418,7 +900,7 @@ void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBit if (rasterState.polygonOffsetFactor != mCurRasterState.polygonOffsetFactor || rasterState.polygonOffsetUnits != mCurRasterState.polygonOffsetUnits) { - mRasterizerStateIsDirty = true; + mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE); } break; } @@ -426,58 +908,150 @@ void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBit if (state.getRasterizerState().rasterizerDiscard != mCurRasterState.rasterizerDiscard) { - mRasterizerStateIsDirty = true; + mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE); + + // Enabling/disabling rasterizer discard affects the pixel shader. + invalidateShaders(); } break; case gl::State::DIRTY_BIT_SCISSOR: if (state.getScissor() != mCurScissorRect) { - mScissorStateIsDirty = true; + mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE); } break; case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED: if (state.isScissorTestEnabled() != mCurScissorEnabled) { - mScissorStateIsDirty = true; + mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE); // Rasterizer state update needs mCurScissorsEnabled and updates when it changes - mRasterizerStateIsDirty = true; + mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE); } break; case gl::State::DIRTY_BIT_DEPTH_RANGE: if (state.getNearPlane() != mCurNear || state.getFarPlane() != mCurFar) { - mViewportStateIsDirty = true; + invalidateViewport(context); } break; case gl::State::DIRTY_BIT_VIEWPORT: if (state.getViewport() != mCurViewport) { - mViewportStateIsDirty = true; + invalidateViewport(context); } break; + case gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING: + invalidateRenderTarget(); + if (mIsMultiviewEnabled) + { + handleMultiviewDrawFramebufferChange(context); + } + break; + case gl::State::DIRTY_BIT_VERTEX_ARRAY_BINDING: + invalidateVertexBuffer(); + // Force invalidate the current value attributes, since the VertexArray11 keeps an + // internal cache of TranslatedAttributes, and they CurrentValue attributes are + // owned by the StateManager11/Context. + mDirtyCurrentValueAttribs.set(); + // Invalidate the cached index buffer. + mIndexBufferIsDirty = true; + break; + case gl::State::DIRTY_BIT_TEXTURE_BINDINGS: + invalidateTexturesAndSamplers(); + break; + case gl::State::DIRTY_BIT_SAMPLER_BINDINGS: + invalidateTexturesAndSamplers(); + break; + case gl::State::DIRTY_BIT_PROGRAM_EXECUTABLE: + { + mInternalDirtyBits.set(DIRTY_BIT_SHADERS); + invalidateVertexBuffer(); + invalidateRenderTarget(); + invalidateTexturesAndSamplers(); + invalidateProgramUniforms(); + invalidateProgramUniformBuffers(); + gl::VertexArray *vao = state.getVertexArray(); + if (mIsMultiviewEnabled && vao != nullptr) + { + // If ANGLE_multiview is enabled, the attribute divisor has to be updated for + // each binding. + VertexArray11 *vao11 = GetImplAs(vao); + const gl::Program *program = state.getProgram(); + int numViews = 1; + if (program != nullptr && program->usesMultiview()) + { + numViews = program->getNumViews(); + } + vao11->markAllAttributeDivisorsForAdjustment(numViews); + } + break; + } + case gl::State::DIRTY_BIT_CURRENT_VALUES: + { + for (auto attribIndex : state.getAndResetDirtyCurrentValues()) + { + invalidateCurrentValueAttrib(attribIndex); + } + } default: break; } } + + // TODO(jmadill): Input layout and vertex buffer state. } -gl::Error StateManager11::setBlendState(const gl::Framebuffer *framebuffer, - const gl::BlendState &blendState, - const gl::ColorF &blendColor, - unsigned int sampleMask) +void StateManager11::handleMultiviewDrawFramebufferChange(const gl::Context *context) { - if (!mBlendStateIsDirty && sampleMask == mCurSampleMask) - { - return gl::Error(GL_NO_ERROR); - } + const auto &glState = context->getGLState(); + const gl::Framebuffer *drawFramebuffer = glState.getDrawFramebuffer(); + ASSERT(drawFramebuffer != nullptr); - ID3D11BlendState *dxBlendState = nullptr; - gl::Error error = - mRenderer->getStateCache().getBlendState(framebuffer, blendState, &dxBlendState); - if (error.isError()) + // Update viewport offsets. + const std::vector *attachmentViewportOffsets = + drawFramebuffer->getViewportOffsets(); + const std::vector &viewportOffsets = + attachmentViewportOffsets != nullptr + ? *attachmentViewportOffsets + : gl::FramebufferAttachment::GetDefaultViewportOffsetVector(); + if (mViewportOffsets != viewportOffsets) { - return error; + mViewportOffsets = viewportOffsets; + + // Because new viewport offsets are to be applied, we have to mark the internal viewport and + // scissor state as dirty. + invalidateViewport(context); + mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE); } + switch (drawFramebuffer->getMultiviewLayout()) + { + case GL_FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE: + mShaderConstants.setMultiviewWriteToViewportIndex(1.0f); + break; + case GL_FRAMEBUFFER_MULTIVIEW_LAYERED_ANGLE: + // Because the base view index is applied as an offset to the 2D texture array when the + // RTV is created, we just have to pass a boolean to select which code path is to be + // used. + mShaderConstants.setMultiviewWriteToViewportIndex(0.0f); + break; + default: + // There is no need to update the value in the constant buffer if the active framebuffer + // object does not have a multiview layout. + break; + } +} + +gl::Error StateManager11::syncBlendState(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::BlendState &blendState, + const gl::ColorF &blendColor, + unsigned int sampleMask) +{ + const d3d11::BlendState *dxBlendState = nullptr; + const d3d11::BlendStateKey &key = + RenderStateCache::GetBlendStateKey(context, framebuffer, blendState); + + ANGLE_TRY(mRenderer->getBlendState(key, &dxBlendState)); ASSERT(dxBlendState != nullptr); @@ -500,62 +1074,53 @@ gl::Error StateManager11::setBlendState(const gl::Framebuffer *framebuffer, blendColors[3] = blendColor.alpha; } - mRenderer->getDeviceContext()->OMSetBlendState(dxBlendState, blendColors, sampleMask); + mRenderer->getDeviceContext()->OMSetBlendState(dxBlendState->get(), blendColors, sampleMask); mCurBlendState = blendState; mCurBlendColor = blendColor; mCurSampleMask = sampleMask; - mBlendStateIsDirty = false; - - return error; + return gl::NoError(); } -gl::Error StateManager11::setDepthStencilState(const gl::State &glState) +gl::Error StateManager11::syncDepthStencilState(const gl::State &glState) { - const auto &fbo = *glState.getDrawFramebuffer(); - - // Disable the depth test/depth write if we are using a stencil-only attachment. - // This is because ANGLE emulates stencil-only with D24S8 on D3D11 - we should neither read - // nor write to the unused depth part of this emulated texture. - bool disableDepth = (!fbo.hasDepth() && fbo.hasStencil()); - - // Similarly we disable the stencil portion of the DS attachment if the app only binds depth. - bool disableStencil = (fbo.hasDepth() && !fbo.hasStencil()); - - // CurDisableDepth/Stencil are reset automatically after we call forceSetDepthStencilState. - if (!mDepthStencilStateIsDirty && mCurDisableDepth.valid() && - disableDepth == mCurDisableDepth.value() && mCurDisableStencil.valid() && - disableStencil == mCurDisableStencil.value()) - { - return gl::Error(GL_NO_ERROR); - } - - const auto &depthStencilState = glState.getDepthStencilState(); - int stencilRef = glState.getStencilRef(); - int stencilBackRef = glState.getStencilBackRef(); + mCurDepthStencilState = glState.getDepthStencilState(); + mCurStencilRef = glState.getStencilRef(); + mCurStencilBackRef = glState.getStencilBackRef(); // get the maximum size of the stencil ref unsigned int maxStencil = 0; - if (depthStencilState.stencilTest && mCurStencilSize > 0) + if (mCurDepthStencilState.stencilTest && mCurStencilSize > 0) { maxStencil = (1 << mCurStencilSize) - 1; } - ASSERT((depthStencilState.stencilWritemask & maxStencil) == - (depthStencilState.stencilBackWritemask & maxStencil)); - ASSERT(stencilRef == stencilBackRef); - ASSERT((depthStencilState.stencilMask & maxStencil) == - (depthStencilState.stencilBackMask & maxStencil)); + ASSERT((mCurDepthStencilState.stencilWritemask & maxStencil) == + (mCurDepthStencilState.stencilBackWritemask & maxStencil)); + ASSERT(mCurStencilRef == mCurStencilBackRef); + ASSERT((mCurDepthStencilState.stencilMask & maxStencil) == + (mCurDepthStencilState.stencilBackMask & maxStencil)); - ID3D11DepthStencilState *dxDepthStencilState = NULL; - gl::Error error = mRenderer->getStateCache().getDepthStencilState( - depthStencilState, disableDepth, disableStencil, &dxDepthStencilState); - if (error.isError()) + gl::DepthStencilState modifiedGLState = glState.getDepthStencilState(); + + ASSERT(mCurDisableDepth.valid() && mCurDisableStencil.valid()); + + if (mCurDisableDepth.value()) { - return error; + modifiedGLState.depthTest = false; + modifiedGLState.depthMask = false; } - ASSERT(dxDepthStencilState); + if (mCurDisableStencil.value()) + { + modifiedGLState.stencilWritemask = 0; + modifiedGLState.stencilBackWritemask = 0; + modifiedGLState.stencilTest = false; + } + + const d3d11::DepthStencilState *d3dState = nullptr; + ANGLE_TRY(mRenderer->getDepthStencilState(modifiedGLState, &d3dState)); + ASSERT(d3dState); // Max D3D11 stencil reference value is 0xFF, // corresponding to the max 8 bits in a stencil buffer @@ -565,30 +1130,21 @@ gl::Error StateManager11::setDepthStencilState(const gl::State &glState) "Unexpected value of D3D11_DEFAULT_STENCIL_READ_MASK"); static_assert(D3D11_DEFAULT_STENCIL_WRITE_MASK == 0xFF, "Unexpected value of D3D11_DEFAULT_STENCIL_WRITE_MASK"); - UINT dxStencilRef = std::min(stencilRef, 0xFFu); + UINT dxStencilRef = std::min(mCurStencilRef, 0xFFu); - mRenderer->getDeviceContext()->OMSetDepthStencilState(dxDepthStencilState, dxStencilRef); + mRenderer->getDeviceContext()->OMSetDepthStencilState(d3dState->get(), dxStencilRef); - mCurDepthStencilState = depthStencilState; - mCurStencilRef = stencilRef; - mCurStencilBackRef = stencilBackRef; - mCurDisableDepth = disableDepth; - mCurDisableStencil = disableStencil; - - mDepthStencilStateIsDirty = false; - - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error StateManager11::setRasterizerState(const gl::RasterizerState &rasterState) +gl::Error StateManager11::syncRasterizerState(const gl::Context *context, bool pointDrawMode) { - if (!mRasterizerStateIsDirty) - { - return gl::Error(GL_NO_ERROR); - } + // TODO: Remove pointDrawMode and multiSample from gl::RasterizerState. + gl::RasterizerState rasterState = context->getGLState().getRasterizerState(); + rasterState.pointDrawMode = pointDrawMode; + rasterState.multiSample = mCurRasterState.multiSample; ID3D11RasterizerState *dxRasterState = nullptr; - gl::Error error(GL_NO_ERROR); if (mCurPresentPathFastEnabled) { @@ -607,33 +1163,23 @@ gl::Error StateManager11::setRasterizerState(const gl::RasterizerState &rasterSt modifiedRasterState.frontFace = GL_CCW; } - error = mRenderer->getStateCache().getRasterizerState(modifiedRasterState, - mCurScissorEnabled, &dxRasterState); + ANGLE_TRY( + mRenderer->getRasterizerState(modifiedRasterState, mCurScissorEnabled, &dxRasterState)); } else { - error = mRenderer->getStateCache().getRasterizerState(rasterState, mCurScissorEnabled, - &dxRasterState); - } - - if (error.isError()) - { - return error; + ANGLE_TRY(mRenderer->getRasterizerState(rasterState, mCurScissorEnabled, &dxRasterState)); } mRenderer->getDeviceContext()->RSSetState(dxRasterState); - mCurRasterState = rasterState; - mRasterizerStateIsDirty = false; + mCurRasterState = rasterState; - return error; + return gl::NoError(); } -void StateManager11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) +void StateManager11::syncScissorRectangle(const gl::Rectangle &scissor, bool enabled) { - if (!mScissorStateIsDirty) - return; - int modifiedScissorY = scissor.y; if (mCurPresentPathFastEnabled) { @@ -642,37 +1188,41 @@ void StateManager11::setScissorRectangle(const gl::Rectangle &scissor, bool enab if (enabled) { - D3D11_RECT rect; - rect.left = std::max(0, scissor.x); - rect.top = std::max(0, modifiedScissorY); - rect.right = scissor.x + std::max(0, scissor.width); - rect.bottom = modifiedScissorY + std::max(0, scissor.height); - - mRenderer->getDeviceContext()->RSSetScissorRects(1, &rect); + std::array rectangles; + const UINT numRectangles = static_cast(mViewportOffsets.size()); + for (UINT i = 0u; i < numRectangles; ++i) + { + D3D11_RECT &rect = rectangles[i]; + int x = scissor.x + mViewportOffsets[i].x; + int y = modifiedScissorY + mViewportOffsets[i].y; + rect.left = std::max(0, x); + rect.top = std::max(0, y); + rect.right = x + std::max(0, scissor.width); + rect.bottom = y + std::max(0, scissor.height); + } + mRenderer->getDeviceContext()->RSSetScissorRects(numRectangles, rectangles.data()); } mCurScissorRect = scissor; mCurScissorEnabled = enabled; - mScissorStateIsDirty = false; } -void StateManager11::setViewport(const gl::Caps *caps, - const gl::Rectangle &viewport, - float zNear, - float zFar) +void StateManager11::syncViewport(const gl::Context *context) { - if (!mViewportStateIsDirty) - return; + const auto &glState = context->getGLState(); + gl::Framebuffer *framebuffer = glState.getDrawFramebuffer(); + float actualZNear = gl::clamp01(glState.getNearPlane()); + float actualZFar = gl::clamp01(glState.getFarPlane()); - float actualZNear = gl::clamp01(zNear); - float actualZFar = gl::clamp01(zFar); - - int dxMaxViewportBoundsX = static_cast(caps->maxViewportWidth); - int dxMaxViewportBoundsY = static_cast(caps->maxViewportHeight); + const auto &caps = context->getCaps(); + int dxMaxViewportBoundsX = static_cast(caps.maxViewportWidth); + int dxMaxViewportBoundsY = static_cast(caps.maxViewportHeight); int dxMinViewportBoundsX = -dxMaxViewportBoundsX; int dxMinViewportBoundsY = -dxMaxViewportBoundsY; - if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) + bool is9_3 = mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3; + + if (is9_3) { // Feature Level 9 viewports shouldn't exceed the dimensions of the rendertarget. dxMaxViewportBoundsX = static_cast(mViewportBounds.width); @@ -681,173 +1231,295 @@ void StateManager11::setViewport(const gl::Caps *caps, dxMinViewportBoundsY = 0; } - int dxViewportTopLeftX = gl::clamp(viewport.x, dxMinViewportBoundsX, dxMaxViewportBoundsX); - int dxViewportTopLeftY = gl::clamp(viewport.y, dxMinViewportBoundsY, dxMaxViewportBoundsY); - int dxViewportWidth = gl::clamp(viewport.width, 0, dxMaxViewportBoundsX - dxViewportTopLeftX); - int dxViewportHeight = gl::clamp(viewport.height, 0, dxMaxViewportBoundsY - dxViewportTopLeftY); + const auto &viewport = glState.getViewport(); + std::array dxViewports; + const UINT numRectangles = static_cast(mViewportOffsets.size()); - D3D11_VIEWPORT dxViewport; - dxViewport.TopLeftX = static_cast(dxViewportTopLeftX); + int dxViewportTopLeftX = 0; + int dxViewportTopLeftY = 0; + int dxViewportWidth = 0; + int dxViewportHeight = 0; - if (mCurPresentPathFastEnabled) + for (UINT i = 0u; i < numRectangles; ++i) { - // When present path fast is active and we're rendering to framebuffer 0, we must invert - // the viewport in Y-axis. - // NOTE: We delay the inversion until right before the call to RSSetViewports, and leave - // dxViewportTopLeftY unchanged. This allows us to calculate viewAdjust below using the - // unaltered dxViewportTopLeftY value. - dxViewport.TopLeftY = static_cast(mCurPresentPathFastColorBufferHeight - - dxViewportTopLeftY - dxViewportHeight); - } - else - { - dxViewport.TopLeftY = static_cast(dxViewportTopLeftY); + dxViewportTopLeftX = gl::clamp(viewport.x + mViewportOffsets[i].x, dxMinViewportBoundsX, + dxMaxViewportBoundsX); + dxViewportTopLeftY = gl::clamp(viewport.y + mViewportOffsets[i].y, dxMinViewportBoundsY, + dxMaxViewportBoundsY); + dxViewportWidth = gl::clamp(viewport.width, 0, dxMaxViewportBoundsX - dxViewportTopLeftX); + dxViewportHeight = gl::clamp(viewport.height, 0, dxMaxViewportBoundsY - dxViewportTopLeftY); + + D3D11_VIEWPORT &dxViewport = dxViewports[i]; + dxViewport.TopLeftX = static_cast(dxViewportTopLeftX); + if (mCurPresentPathFastEnabled) + { + // When present path fast is active and we're rendering to framebuffer 0, we must invert + // the viewport in Y-axis. + // NOTE: We delay the inversion until right before the call to RSSetViewports, and leave + // dxViewportTopLeftY unchanged. This allows us to calculate viewAdjust below using the + // unaltered dxViewportTopLeftY value. + dxViewport.TopLeftY = static_cast(mCurPresentPathFastColorBufferHeight - + dxViewportTopLeftY - dxViewportHeight); + } + else + { + dxViewport.TopLeftY = static_cast(dxViewportTopLeftY); + } + + // The es 3.1 spec section 9.2 states that, "If there are no attachments, rendering + // will be limited to a rectangle having a lower left of (0, 0) and an upper right of + // (width, height), where width and height are the framebuffer object's default width + // and height." See http://anglebug.com/1594 + // If the Framebuffer has no color attachment and the default width or height is smaller + // than the current viewport, use the smaller of the two sizes. + // If framebuffer default width or height is 0, the params should not set. + if (!framebuffer->getFirstNonNullAttachment() && + (framebuffer->getDefaultWidth() || framebuffer->getDefaultHeight())) + { + dxViewport.Width = + static_cast(std::min(viewport.width, framebuffer->getDefaultWidth())); + dxViewport.Height = + static_cast(std::min(viewport.height, framebuffer->getDefaultHeight())); + } + else + { + dxViewport.Width = static_cast(dxViewportWidth); + dxViewport.Height = static_cast(dxViewportHeight); + } + dxViewport.MinDepth = actualZNear; + dxViewport.MaxDepth = actualZFar; } - dxViewport.Width = static_cast(dxViewportWidth); - dxViewport.Height = static_cast(dxViewportHeight); - dxViewport.MinDepth = actualZNear; - dxViewport.MaxDepth = actualZFar; - - mRenderer->getDeviceContext()->RSSetViewports(1, &dxViewport); + mRenderer->getDeviceContext()->RSSetViewports(numRectangles, dxViewports.data()); mCurViewport = viewport; mCurNear = actualZNear; mCurFar = actualZFar; - // On Feature Level 9_*, we must emulate large and/or negative viewports in the shaders - // using viewAdjust (like the D3D9 renderer). - if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) - { - mVertexConstants.viewAdjust[0] = static_cast((viewport.width - dxViewportWidth) + - 2 * (viewport.x - dxViewportTopLeftX)) / - dxViewport.Width; - mVertexConstants.viewAdjust[1] = static_cast((viewport.height - dxViewportHeight) + - 2 * (viewport.y - dxViewportTopLeftY)) / - dxViewport.Height; - mVertexConstants.viewAdjust[2] = static_cast(viewport.width) / dxViewport.Width; - mVertexConstants.viewAdjust[3] = static_cast(viewport.height) / dxViewport.Height; - } - - mPixelConstants.viewCoords[0] = viewport.width * 0.5f; - mPixelConstants.viewCoords[1] = viewport.height * 0.5f; - mPixelConstants.viewCoords[2] = viewport.x + (viewport.width * 0.5f); - mPixelConstants.viewCoords[3] = viewport.y + (viewport.height * 0.5f); - - // Instanced pointsprite emulation requires ViewCoords to be defined in the - // the vertex shader. - mVertexConstants.viewCoords[0] = mPixelConstants.viewCoords[0]; - mVertexConstants.viewCoords[1] = mPixelConstants.viewCoords[1]; - mVertexConstants.viewCoords[2] = mPixelConstants.viewCoords[2]; - mVertexConstants.viewCoords[3] = mPixelConstants.viewCoords[3]; - - mPixelConstants.depthFront[0] = (actualZFar - actualZNear) * 0.5f; - mPixelConstants.depthFront[1] = (actualZNear + actualZFar) * 0.5f; - - mVertexConstants.depthRange[0] = actualZNear; - mVertexConstants.depthRange[1] = actualZFar; - mVertexConstants.depthRange[2] = actualZFar - actualZNear; - - mPixelConstants.depthRange[0] = actualZNear; - mPixelConstants.depthRange[1] = actualZFar; - mPixelConstants.depthRange[2] = actualZFar - actualZNear; - - mPixelConstants.viewScale[0] = 1.0f; - mPixelConstants.viewScale[1] = mCurPresentPathFastEnabled ? 1.0f : -1.0f; - mPixelConstants.viewScale[2] = 1.0f; - mPixelConstants.viewScale[3] = 1.0f; - - mVertexConstants.viewScale[0] = mPixelConstants.viewScale[0]; - mVertexConstants.viewScale[1] = mPixelConstants.viewScale[1]; - mVertexConstants.viewScale[2] = mPixelConstants.viewScale[2]; - mVertexConstants.viewScale[3] = mPixelConstants.viewScale[3]; - - mViewportStateIsDirty = false; + const D3D11_VIEWPORT adjustViewport = {static_cast(dxViewportTopLeftX), + static_cast(dxViewportTopLeftY), + static_cast(dxViewportWidth), + static_cast(dxViewportHeight), + actualZNear, + actualZFar}; + mShaderConstants.onViewportChange(viewport, adjustViewport, is9_3, mCurPresentPathFastEnabled); } void StateManager11::invalidateRenderTarget() { - for (auto &appliedRTV : mAppliedRTVs) - { - appliedRTV = angle::DirtyPointer; - } - mAppliedDSV = angle::DirtyPointer; + mRenderTargetIsDirty = true; } -void StateManager11::invalidateEverything() +void StateManager11::processFramebufferInvalidation(const gl::Context *context) { - mBlendStateIsDirty = true; - mDepthStencilStateIsDirty = true; - mRasterizerStateIsDirty = true; - mScissorStateIsDirty = true; - mViewportStateIsDirty = true; + if (!mRenderTargetIsDirty) + { + return; + } - // We reset the current SRV data because it might not be in sync with D3D's state - // anymore. For example when a currently used SRV is used as an RTV, D3D silently - // remove it from its state. + ASSERT(context); + + mRenderTargetIsDirty = false; + mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET); + + // The pixel shader is dependent on the output layout. + invalidateShaders(); + + // The D3D11 blend state is heavily dependent on the current render target. + mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE); + + gl::Framebuffer *fbo = context->getGLState().getDrawFramebuffer(); + ASSERT(fbo); + + // Disable the depth test/depth write if we are using a stencil-only attachment. + // This is because ANGLE emulates stencil-only with D24S8 on D3D11 - we should neither read + // nor write to the unused depth part of this emulated texture. + bool disableDepth = (!fbo->hasDepth() && fbo->hasStencil()); + + // Similarly we disable the stencil portion of the DS attachment if the app only binds depth. + bool disableStencil = (fbo->hasDepth() && !fbo->hasStencil()); + + if (!mCurDisableDepth.valid() || disableDepth != mCurDisableDepth.value() || + !mCurDisableStencil.valid() || disableStencil != mCurDisableStencil.value()) + { + mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE); + mCurDisableDepth = disableDepth; + mCurDisableStencil = disableStencil; + } + + bool multiSample = (fbo->getCachedSamples(context) != 0); + if (multiSample != mCurRasterState.multiSample) + { + mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE); + mCurRasterState.multiSample = multiSample; + } + + checkPresentPath(context); + + if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) + { + const auto *firstAttachment = fbo->getFirstNonNullAttachment(); + if (firstAttachment) + { + const auto &size = firstAttachment->getSize(); + if (mViewportBounds.width != size.width || mViewportBounds.height != size.height) + { + mViewportBounds = gl::Extents(size.width, size.height, 1); + invalidateViewport(context); + } + } + } +} + +void StateManager11::invalidateBoundViews() +{ mCurVertexSRVs.clear(); mCurPixelSRVs.clear(); invalidateRenderTarget(); } -bool StateManager11::setRenderTargets(const RenderTargetArray &renderTargets, - ID3D11DepthStencilView *depthStencil) +void StateManager11::invalidateVertexBuffer() { - // TODO(jmadill): Use context caps? - UINT drawBuffers = mRenderer->getRendererCaps().maxDrawBuffers; - - // Apply the render target and depth stencil - size_t arraySize = sizeof(uintptr_t) * drawBuffers; - if (memcmp(renderTargets.data(), mAppliedRTVs.data(), arraySize) == 0 && - reinterpret_cast(depthStencil) == mAppliedDSV) - { - return false; - } - - // The D3D11 blend state is heavily dependent on the current render target. - mBlendStateIsDirty = true; - - for (UINT rtIndex = 0; rtIndex < drawBuffers; rtIndex++) - { - mAppliedRTVs[rtIndex] = reinterpret_cast(renderTargets[rtIndex]); - } - mAppliedDSV = reinterpret_cast(depthStencil); - - mRenderer->getDeviceContext()->OMSetRenderTargets(drawBuffers, renderTargets.data(), - depthStencil); - return true; + unsigned int limit = std::min(mRenderer->getNativeCaps().maxVertexAttributes, + gl::MAX_VERTEX_ATTRIBS); + mDirtyVertexBufferRange = gl::RangeUI(0, limit); + mInputLayoutIsDirty = true; + mInternalDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_ATTRIBS); + invalidateVertexAttributeTranslation(); } -void StateManager11::setRenderTarget(ID3D11RenderTargetView *renderTarget, - ID3D11DepthStencilView *depthStencil) +void StateManager11::invalidateViewport(const gl::Context *context) { - mRenderer->getDeviceContext()->OMSetRenderTargets(1, &renderTarget, depthStencil); + mInternalDirtyBits.set(DIRTY_BIT_VIEWPORT_STATE); + + // Viewport affects the driver constants. + invalidateDriverUniforms(); } -void StateManager11::setShaderResource(gl::SamplerType shaderType, - UINT resourceSlot, - ID3D11ShaderResourceView *srv) +void StateManager11::invalidateTexturesAndSamplers() { - auto ¤tSRVs = (shaderType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs); + mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE); + invalidateSwizzles(); - ASSERT(static_cast(resourceSlot) < currentSRVs.size()); - const SRVRecord &record = currentSRVs[resourceSlot]; + // Texture state affects the driver uniforms (base level, etc). + invalidateDriverUniforms(); +} - if (record.srv != reinterpret_cast(srv)) +void StateManager11::invalidateSwizzles() +{ + mDirtySwizzles = true; +} + +void StateManager11::invalidateProgramUniforms() +{ + mInternalDirtyBits.set(DIRTY_BIT_PROGRAM_UNIFORMS); +} + +void StateManager11::invalidateDriverUniforms() +{ + mInternalDirtyBits.set(DIRTY_BIT_DRIVER_UNIFORMS); +} + +void StateManager11::invalidateProgramUniformBuffers() +{ + mInternalDirtyBits.set(DIRTY_BIT_PROGRAM_UNIFORM_BUFFERS); +} + +void StateManager11::invalidateConstantBuffer(unsigned int slot) +{ + if (slot == d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER) { - auto deviceContext = mRenderer->getDeviceContext(); - if (shaderType == gl::SAMPLER_VERTEX) - { - deviceContext->VSSetShaderResources(resourceSlot, 1, &srv); - } - else - { - deviceContext->PSSetShaderResources(resourceSlot, 1, &srv); - } - - currentSRVs.update(resourceSlot, srv); + invalidateDriverUniforms(); } + else if (slot == d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK) + { + invalidateProgramUniforms(); + } + else + { + invalidateProgramUniformBuffers(); + } +} + +void StateManager11::invalidateShaders() +{ + mInternalDirtyBits.set(DIRTY_BIT_SHADERS); +} + +void StateManager11::setRenderTarget(ID3D11RenderTargetView *rtv, ID3D11DepthStencilView *dsv) +{ + if ((rtv && unsetConflictingView(rtv)) || (dsv && unsetConflictingView(dsv))) + { + mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE); + } + + mRenderer->getDeviceContext()->OMSetRenderTargets(1, &rtv, dsv); + mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET); +} + +void StateManager11::setRenderTargets(ID3D11RenderTargetView **rtvs, + UINT numRTVs, + ID3D11DepthStencilView *dsv) +{ + bool anyDirty = false; + + for (UINT rtvIndex = 0; rtvIndex < numRTVs; ++rtvIndex) + { + anyDirty = anyDirty || unsetConflictingView(rtvs[rtvIndex]); + } + + if (dsv) + { + anyDirty = anyDirty || unsetConflictingView(dsv); + } + + if (anyDirty) + { + mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE); + } + + mRenderer->getDeviceContext()->OMSetRenderTargets(numRTVs, (numRTVs > 0) ? rtvs : nullptr, dsv); + mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET); +} + +void StateManager11::invalidateVertexAttributeTranslation() +{ + mVertexAttribsNeedTranslation = true; +} + +void StateManager11::onBeginQuery(Query11 *query) +{ + mCurrentQueries.insert(query); +} + +void StateManager11::onDeleteQueryObject(Query11 *query) +{ + mCurrentQueries.erase(query); +} + +gl::Error StateManager11::onMakeCurrent(const gl::Context *context) +{ + const gl::State &state = context->getGLState(); + + for (Query11 *query : mCurrentQueries) + { + ANGLE_TRY(query->pause()); + } + mCurrentQueries.clear(); + + for (GLenum queryType : QueryTypes) + { + gl::Query *query = state.getActiveQuery(queryType); + if (query != nullptr) + { + Query11 *query11 = GetImplAs(query); + ANGLE_TRY(query11->resume()); + mCurrentQueries.insert(query11); + } + } + + return gl::NoError(); } gl::Error StateManager11::clearTextures(gl::SamplerType samplerType, @@ -856,185 +1528,1548 @@ gl::Error StateManager11::clearTextures(gl::SamplerType samplerType, { if (rangeStart == rangeEnd) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } auto ¤tSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs); - gl::Range clearRange(rangeStart, rangeStart); - clearRange.extend(std::min(rangeEnd, currentSRVs.highestUsed())); - + gl::Range clearRange(rangeStart, std::min(rangeEnd, currentSRVs.highestUsed())); if (clearRange.empty()) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } - auto deviceContext = mRenderer->getDeviceContext(); + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); if (samplerType == gl::SAMPLER_VERTEX) { - deviceContext->VSSetShaderResources(static_cast(rangeStart), - static_cast(rangeEnd - rangeStart), + deviceContext->VSSetShaderResources(static_cast(clearRange.low()), + static_cast(clearRange.length()), &mNullSRVs[0]); } else { - deviceContext->PSSetShaderResources(static_cast(rangeStart), - static_cast(rangeEnd - rangeStart), + deviceContext->PSSetShaderResources(static_cast(clearRange.low()), + static_cast(clearRange.length()), &mNullSRVs[0]); } - for (size_t samplerIndex = rangeStart; samplerIndex < rangeEnd; ++samplerIndex) + for (size_t samplerIndex : clearRange) { currentSRVs.update(samplerIndex, nullptr); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -void StateManager11::unsetConflictingSRVs(gl::SamplerType samplerType, +bool StateManager11::unsetConflictingView(ID3D11View *view) +{ + uintptr_t resource = reinterpret_cast(GetViewResource(view)); + return unsetConflictingSRVs(gl::SAMPLER_VERTEX, resource, nullptr) || + unsetConflictingSRVs(gl::SAMPLER_PIXEL, resource, nullptr); +} + +bool StateManager11::unsetConflictingSRVs(gl::SamplerType samplerType, uintptr_t resource, - const gl::ImageIndex &index) + const gl::ImageIndex *index) { auto ¤tSRVs = (samplerType == gl::SAMPLER_VERTEX ? mCurVertexSRVs : mCurPixelSRVs); + bool foundOne = false; + for (size_t resourceIndex = 0; resourceIndex < currentSRVs.size(); ++resourceIndex) { auto &record = currentSRVs[resourceIndex]; if (record.srv && record.resource == resource && - ImageIndexConflictsWithSRV(index, record.desc)) + (!index || ImageIndexConflictsWithSRV(*index, record.desc))) { - setShaderResource(samplerType, static_cast(resourceIndex), NULL); + setShaderResourceInternal( + samplerType, static_cast(resourceIndex), nullptr); + foundOne = true; } } + + return foundOne; +} + +void StateManager11::unsetConflictingAttachmentResources( + const gl::FramebufferAttachment *attachment, + ID3D11Resource *resource) +{ + // Unbind render target SRVs from the shader here to prevent D3D11 warnings. + if (attachment->type() == GL_TEXTURE) + { + uintptr_t resourcePtr = reinterpret_cast(resource); + const gl::ImageIndex &index = attachment->getTextureImageIndex(); + // The index doesn't need to be corrected for the small compressed texture workaround + // because a rendertarget is never compressed. + unsetConflictingSRVs(gl::SAMPLER_VERTEX, resourcePtr, &index); + unsetConflictingSRVs(gl::SAMPLER_PIXEL, resourcePtr, &index); + } + else if (attachment->type() == GL_FRAMEBUFFER_DEFAULT) + { + uintptr_t resourcePtr = reinterpret_cast(resource); + unsetConflictingSRVs(gl::SAMPLER_VERTEX, resourcePtr, nullptr); + unsetConflictingSRVs(gl::SAMPLER_PIXEL, resourcePtr, nullptr); + } } -void StateManager11::initialize(const gl::Caps &caps) +gl::Error StateManager11::initialize(const gl::Caps &caps, const gl::Extensions &extensions) { mCurVertexSRVs.initialize(caps.maxVertexTextureImageUnits); mCurPixelSRVs.initialize(caps.maxTextureImageUnits); // Initialize cached NULL SRV block mNullSRVs.resize(caps.maxTextureImageUnits, nullptr); + + mCurrentValueAttribs.resize(caps.maxVertexAttributes); + + mForceSetVertexSamplerStates.resize(caps.maxVertexTextureImageUnits, true); + mForceSetPixelSamplerStates.resize(caps.maxTextureImageUnits, true); + mForceSetComputeSamplerStates.resize(caps.maxComputeTextureImageUnits, true); + + mCurVertexSamplerStates.resize(caps.maxVertexTextureImageUnits); + mCurPixelSamplerStates.resize(caps.maxTextureImageUnits); + mCurComputeSamplerStates.resize(caps.maxComputeTextureImageUnits); + + mShaderConstants.init(caps); + + mIsMultiviewEnabled = extensions.multiview; + mViewportOffsets.resize(1u); + + ANGLE_TRY(mVertexDataManager.initialize()); + + mCurrentAttributes.reserve(gl::MAX_VERTEX_ATTRIBS); + + return gl::NoError(); } -gl::Error StateManager11::syncFramebuffer(const gl::Framebuffer *framebuffer) +void StateManager11::deinitialize() { - // Get the color render buffer and serial - // Also extract the render target dimensions and view - unsigned int renderTargetWidth = 0; - unsigned int renderTargetHeight = 0; - DXGI_FORMAT renderTargetFormat = DXGI_FORMAT_UNKNOWN; - RenderTargetArray framebufferRTVs; - bool missingColorRenderTarget = true; + mCurrentValueAttribs.clear(); + mInputLayoutCache.clear(); + mVertexDataManager.deinitialize(); + mIndexDataManager.deinitialize(); - framebufferRTVs.fill(nullptr); + mDriverConstantBufferVS.reset(); + mDriverConstantBufferPS.reset(); + mDriverConstantBufferCS.reset(); +} - const Framebuffer11 *framebuffer11 = GetImplAs(framebuffer); - const gl::AttachmentList &colorbuffers = framebuffer11->getColorAttachmentsForRender(); +gl::Error StateManager11::syncFramebuffer(const gl::Context *context, gl::Framebuffer *framebuffer) +{ + Framebuffer11 *framebuffer11 = GetImplAs(framebuffer); - for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment) + // Applies the render target surface, depth stencil surface, viewport rectangle and + // scissor rectangle to the renderer + ASSERT(framebuffer && !framebuffer->hasAnyDirtyBit() && framebuffer->cachedComplete()); + + // Check for zero-sized default framebuffer, which is a special case. + // in this case we do not wish to modify any state and just silently return false. + // this will not report any gl error but will cause the calling method to return. + if (framebuffer->id() == 0) { - const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment]; - - if (colorbuffer) + ASSERT(!framebuffer11->hasAnyInternalDirtyBit()); + const gl::Extents &size = framebuffer->getFirstColorbuffer()->getSize(); + if (size.width == 0 || size.height == 0) { - // the draw buffer must be either "none", "back" for the default buffer or the same - // index as this color (in order) - - // check for zero-sized default framebuffer, which is a special case. - // in this case we do not wish to modify any state and just silently return false. - // this will not report any gl error but will cause the calling method to return. - const gl::Extents &size = colorbuffer->getSize(); - if (size.width == 0 || size.height == 0) - { - return gl::Error(GL_NO_ERROR); - } - - // Extract the render target dimensions and view - RenderTarget11 *renderTarget = NULL; - gl::Error error = colorbuffer->getRenderTarget(&renderTarget); - if (error.isError()) - { - return error; - } - ASSERT(renderTarget); - - framebufferRTVs[colorAttachment] = renderTarget->getRenderTargetView(); - ASSERT(framebufferRTVs[colorAttachment]); - - if (missingColorRenderTarget) - { - renderTargetWidth = renderTarget->getWidth(); - renderTargetHeight = renderTarget->getHeight(); - renderTargetFormat = renderTarget->getDXGIFormat(); - missingColorRenderTarget = false; - } - - // Unbind render target SRVs from the shader here to prevent D3D11 warnings. - if (colorbuffer->type() == GL_TEXTURE) - { - uintptr_t rtResource = - reinterpret_cast(GetViewResource(framebufferRTVs[colorAttachment])); - const gl::ImageIndex &index = colorbuffer->getTextureImageIndex(); - // The index doesn't need to be corrected for the small compressed texture - // workaround - // because a rendertarget is never compressed. - unsetConflictingSRVs(gl::SAMPLER_VERTEX, rtResource, index); - unsetConflictingSRVs(gl::SAMPLER_PIXEL, rtResource, index); - } + return gl::NoError(); } } + RTVArray framebufferRTVs = {{}}; + + const auto &colorRTs = framebuffer11->getCachedColorRenderTargets(); + + size_t appliedRTIndex = 0; + bool skipInactiveRTs = mRenderer->getWorkarounds().mrtPerfWorkaround; + const auto &drawStates = framebuffer->getDrawBufferStates(); + gl::DrawBufferMask activeProgramOutputs = + context->getContextState().getState().getProgram()->getActiveOutputVariables(); + UINT maxExistingRT = 0; + + for (size_t rtIndex = 0; rtIndex < colorRTs.size(); ++rtIndex) + { + const RenderTarget11 *renderTarget = colorRTs[rtIndex]; + + // Skip inactive rendertargets if the workaround is enabled. + if (skipInactiveRTs && + (!renderTarget || drawStates[rtIndex] == GL_NONE || !activeProgramOutputs[rtIndex])) + { + continue; + } + + if (renderTarget) + { + framebufferRTVs[appliedRTIndex] = renderTarget->getRenderTargetView().get(); + ASSERT(framebufferRTVs[appliedRTIndex]); + maxExistingRT = static_cast(appliedRTIndex) + 1; + + // Unset conflicting texture SRVs + const auto *attachment = framebuffer->getColorbuffer(rtIndex); + ASSERT(attachment); + unsetConflictingAttachmentResources(attachment, renderTarget->getTexture().get()); + } + + appliedRTIndex++; + } + // Get the depth stencil buffers - ID3D11DepthStencilView *framebufferDSV = NULL; - const gl::FramebufferAttachment *depthStencil = framebuffer->getDepthOrStencilbuffer(); - if (depthStencil) + ID3D11DepthStencilView *framebufferDSV = nullptr; + const auto *depthStencilRenderTarget = framebuffer11->getCachedDepthStencilRenderTarget(); + if (depthStencilRenderTarget) { - RenderTarget11 *depthStencilRenderTarget = NULL; - gl::Error error = depthStencil->getRenderTarget(&depthStencilRenderTarget); - if (error.isError()) - { - return error; - } - ASSERT(depthStencilRenderTarget); - - framebufferDSV = depthStencilRenderTarget->getDepthStencilView(); + framebufferDSV = depthStencilRenderTarget->getDepthStencilView().get(); ASSERT(framebufferDSV); - // If there is no render buffer, the width, height and format values come from - // the depth stencil - if (missingColorRenderTarget) - { - renderTargetWidth = depthStencilRenderTarget->getWidth(); - renderTargetHeight = depthStencilRenderTarget->getHeight(); - } + // Unset conflicting texture SRVs + const auto *attachment = framebuffer->getDepthOrStencilbuffer(); + ASSERT(attachment); + unsetConflictingAttachmentResources(attachment, + depthStencilRenderTarget->getTexture().get()); + } - // Unbind render target SRVs from the shader here to prevent D3D11 warnings. - if (depthStencil->type() == GL_TEXTURE) + // TODO(jmadill): Use context caps? + ASSERT(maxExistingRT <= static_cast(mRenderer->getNativeCaps().maxDrawBuffers)); + + // Apply the render target and depth stencil + mRenderer->getDeviceContext()->OMSetRenderTargets(maxExistingRT, framebufferRTVs.data(), + framebufferDSV); + + return gl::NoError(); +} + +void StateManager11::invalidateCurrentValueAttrib(size_t attribIndex) +{ + mDirtyCurrentValueAttribs.set(attribIndex); + mInternalDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_ATTRIBS); +} + +gl::Error StateManager11::syncCurrentValueAttribs(const gl::State &glState) +{ + const auto &activeAttribsMask = glState.getProgram()->getActiveAttribLocationsMask(); + const auto &dirtyActiveAttribs = (activeAttribsMask & mDirtyCurrentValueAttribs); + + if (!dirtyActiveAttribs.any()) + { + return gl::NoError(); + } + + const auto &vertexAttributes = glState.getVertexArray()->getVertexAttributes(); + const auto &vertexBindings = glState.getVertexArray()->getVertexBindings(); + mDirtyCurrentValueAttribs = (mDirtyCurrentValueAttribs & ~dirtyActiveAttribs); + + for (auto attribIndex : dirtyActiveAttribs) + { + if (vertexAttributes[attribIndex].enabled) + continue; + + const auto *attrib = &vertexAttributes[attribIndex]; + const auto ¤tValue = glState.getVertexAttribCurrentValue(attribIndex); + TranslatedAttribute *currentValueAttrib = &mCurrentValueAttribs[attribIndex]; + currentValueAttrib->currentValueType = currentValue.Type; + currentValueAttrib->attribute = attrib; + currentValueAttrib->binding = &vertexBindings[attrib->bindingIndex]; + + mDirtyVertexBufferRange.extend(static_cast(attribIndex)); + mInputLayoutIsDirty = true; + + ANGLE_TRY(mVertexDataManager.storeCurrentValue(currentValue, currentValueAttrib, + static_cast(attribIndex))); + } + + return gl::NoError(); +} + +void StateManager11::setInputLayout(const d3d11::InputLayout *inputLayout) +{ + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + if (inputLayout == nullptr) + { + if (!mCurrentInputLayout.empty()) { - uintptr_t depthStencilResource = - reinterpret_cast(GetViewResource(framebufferDSV)); - const gl::ImageIndex &index = depthStencil->getTextureImageIndex(); - // The index doesn't need to be corrected for the small compressed texture workaround - // because a rendertarget is never compressed. - unsetConflictingSRVs(gl::SAMPLER_VERTEX, depthStencilResource, index); - unsetConflictingSRVs(gl::SAMPLER_PIXEL, depthStencilResource, index); + deviceContext->IASetInputLayout(nullptr); + mCurrentInputLayout.clear(); + mInputLayoutIsDirty = true; + } + } + else if (inputLayout->getSerial() != mCurrentInputLayout) + { + deviceContext->IASetInputLayout(inputLayout->get()); + mCurrentInputLayout = inputLayout->getSerial(); + mInputLayoutIsDirty = true; + } +} + +bool StateManager11::queueVertexBufferChange(size_t bufferIndex, + ID3D11Buffer *buffer, + UINT stride, + UINT offset) +{ + if (buffer != mCurrentVertexBuffers[bufferIndex] || + stride != mCurrentVertexStrides[bufferIndex] || + offset != mCurrentVertexOffsets[bufferIndex]) + { + mInputLayoutIsDirty = true; + mDirtyVertexBufferRange.extend(static_cast(bufferIndex)); + + mCurrentVertexBuffers[bufferIndex] = buffer; + mCurrentVertexStrides[bufferIndex] = stride; + mCurrentVertexOffsets[bufferIndex] = offset; + return true; + } + + return false; +} + +bool StateManager11::queueVertexOffsetChange(size_t bufferIndex, UINT offsetOnly) +{ + if (offsetOnly != mCurrentVertexOffsets[bufferIndex]) + { + mInputLayoutIsDirty = true; + mDirtyVertexBufferRange.extend(static_cast(bufferIndex)); + mCurrentVertexOffsets[bufferIndex] = offsetOnly; + return true; + } + return false; +} + +void StateManager11::applyVertexBufferChanges() +{ + if (mDirtyVertexBufferRange.empty()) + { + return; + } + + ASSERT(mDirtyVertexBufferRange.high() <= gl::MAX_VERTEX_ATTRIBS); + + UINT start = static_cast(mDirtyVertexBufferRange.low()); + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + deviceContext->IASetVertexBuffers(start, static_cast(mDirtyVertexBufferRange.length()), + &mCurrentVertexBuffers[start], &mCurrentVertexStrides[start], + &mCurrentVertexOffsets[start]); + + mDirtyVertexBufferRange = gl::RangeUI(gl::MAX_VERTEX_ATTRIBS, 0); +} + +void StateManager11::setSingleVertexBuffer(const d3d11::Buffer *buffer, UINT stride, UINT offset) +{ + ID3D11Buffer *native = buffer ? buffer->get() : nullptr; + if (queueVertexBufferChange(0, native, stride, offset)) + { + applyVertexBufferChanges(); + } +} + +gl::Error StateManager11::updateState(const gl::Context *context, GLenum drawMode) +{ + const auto &glState = context->getGLState(); + auto *programD3D = GetImplAs(glState.getProgram()); + + // TODO(jmadill): Use dirty bits. + processFramebufferInvalidation(context); + + // TODO(jmadill): Use dirty bits. + if (programD3D->updateSamplerMapping() == ProgramD3D::SamplerMapping::WasDirty) + { + invalidateTexturesAndSamplers(); + } + + // TODO(jmadill): Use dirty bits. + if (programD3D->areVertexUniformsDirty() || programD3D->areFragmentUniformsDirty()) + { + mInternalDirtyBits.set(DIRTY_BIT_PROGRAM_UNIFORMS); + } + + // Transform feedback affects the stream-out geometry shader. + // TODO(jmadill): Use dirty bits. + if (glState.isTransformFeedbackActiveUnpaused() != mIsTransformFeedbackCurrentlyActiveUnpaused) + { + mIsTransformFeedbackCurrentlyActiveUnpaused = glState.isTransformFeedbackActiveUnpaused(); + invalidateShaders(); + } + + // Swizzling can cause internal state changes with blit shaders. + if (mDirtySwizzles) + { + ANGLE_TRY(generateSwizzles(context)); + mDirtySwizzles = false; + } + + gl::Framebuffer *framebuffer = glState.getDrawFramebuffer(); + Framebuffer11 *framebuffer11 = GetImplAs(framebuffer); + ANGLE_TRY(framebuffer11->markAttachmentsDirty(context)); + + if (framebuffer11->hasAnyInternalDirtyBit()) + { + ASSERT(framebuffer->id() != 0); + framebuffer11->syncInternalState(context); + } + + bool pointDrawMode = (drawMode == GL_POINTS); + if (pointDrawMode != mCurRasterState.pointDrawMode) + { + mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE); + + // Changing from points to not points (or vice-versa) affects the geometry shader. + invalidateShaders(); + } + + // TODO(jiawei.shao@intel.com): This can be recomputed only on framebuffer or multisample mask + // state changes. + RenderTarget11 *firstRT = framebuffer11->getFirstRenderTarget(); + int samples = (firstRT ? firstRT->getSamples() : 0); + unsigned int sampleMask = GetBlendSampleMask(glState, samples); + if (sampleMask != mCurSampleMask) + { + mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE); + } + + // Changing the vertex attribute state can affect the vertex shader. + gl::VertexArray *vao = glState.getVertexArray(); + VertexArray11 *vao11 = GetImplAs(vao); + if (vao11->flushAttribUpdates(context)) + { + mInternalDirtyBits.set(DIRTY_BIT_SHADERS); + } + + auto dirtyBitsCopy = mInternalDirtyBits; + mInternalDirtyBits.reset(); + + for (auto dirtyBit : dirtyBitsCopy) + { + switch (dirtyBit) + { + case DIRTY_BIT_RENDER_TARGET: + ANGLE_TRY(syncFramebuffer(context, framebuffer)); + break; + case DIRTY_BIT_VIEWPORT_STATE: + syncViewport(context); + break; + case DIRTY_BIT_SCISSOR_STATE: + syncScissorRectangle(glState.getScissor(), glState.isScissorTestEnabled()); + break; + case DIRTY_BIT_RASTERIZER_STATE: + ANGLE_TRY(syncRasterizerState(context, pointDrawMode)); + break; + case DIRTY_BIT_BLEND_STATE: + ANGLE_TRY(syncBlendState(context, framebuffer, glState.getBlendState(), + glState.getBlendColor(), sampleMask)); + break; + case DIRTY_BIT_DEPTH_STENCIL_STATE: + ANGLE_TRY(syncDepthStencilState(glState)); + break; + case DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE: + // TODO(jmadill): More fine-grained update. + ANGLE_TRY(syncTextures(context)); + break; + case DIRTY_BIT_PROGRAM_UNIFORMS: + ANGLE_TRY(applyUniforms(programD3D)); + break; + case DIRTY_BIT_DRIVER_UNIFORMS: + // This must happen after viewport sync; the viewport affects builtin uniforms. + ANGLE_TRY(applyDriverUniforms(*programD3D)); + break; + case DIRTY_BIT_PROGRAM_UNIFORM_BUFFERS: + ANGLE_TRY(syncUniformBuffers(context, programD3D)); + break; + case DIRTY_BIT_SHADERS: + ANGLE_TRY(syncProgram(context, drawMode)); + break; + case DIRTY_BIT_CURRENT_VALUE_ATTRIBS: + ANGLE_TRY(syncCurrentValueAttribs(glState)); + break; + default: + UNREACHABLE(); + break; } } - if (setRenderTargets(framebufferRTVs, framebufferDSV)) + ANGLE_TRY(syncTransformFeedbackBuffers(context)); + + // Check that we haven't set any dirty bits in the flushing of the dirty bits loop. + ASSERT(mInternalDirtyBits.none()); + + return gl::NoError(); +} + +void StateManager11::setShaderResourceShared(gl::SamplerType shaderType, + UINT resourceSlot, + const d3d11::SharedSRV *srv) +{ + setShaderResourceInternal(shaderType, resourceSlot, srv); + + // TODO(jmadill): Narrower dirty region. + mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE); +} + +void StateManager11::setShaderResource(gl::SamplerType shaderType, + UINT resourceSlot, + const d3d11::ShaderResourceView *srv) +{ + setShaderResourceInternal(shaderType, resourceSlot, srv); + + // TODO(jmadill): Narrower dirty region. + mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE); +} + +void StateManager11::setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY primitiveTopology) +{ + if (primitiveTopology != mCurrentPrimitiveTopology) { - setViewportBounds(renderTargetWidth, renderTargetHeight); + mRenderer->getDeviceContext()->IASetPrimitiveTopology(primitiveTopology); + mCurrentPrimitiveTopology = primitiveTopology; + } +} + +void StateManager11::setDrawShaders(const d3d11::VertexShader *vertexShader, + const d3d11::GeometryShader *geometryShader, + const d3d11::PixelShader *pixelShader) +{ + setVertexShader(vertexShader); + setGeometryShader(geometryShader); + setPixelShader(pixelShader); +} + +void StateManager11::setVertexShader(const d3d11::VertexShader *shader) +{ + ResourceSerial serial = shader ? shader->getSerial() : ResourceSerial(0); + + if (serial != mAppliedVertexShader) + { + ID3D11VertexShader *appliedShader = shader ? shader->get() : nullptr; + mRenderer->getDeviceContext()->VSSetShader(appliedShader, nullptr, 0); + mAppliedVertexShader = serial; + invalidateShaders(); + } +} + +void StateManager11::setGeometryShader(const d3d11::GeometryShader *shader) +{ + ResourceSerial serial = shader ? shader->getSerial() : ResourceSerial(0); + + if (serial != mAppliedGeometryShader) + { + ID3D11GeometryShader *appliedShader = shader ? shader->get() : nullptr; + mRenderer->getDeviceContext()->GSSetShader(appliedShader, nullptr, 0); + mAppliedGeometryShader = serial; + invalidateShaders(); + } +} + +void StateManager11::setPixelShader(const d3d11::PixelShader *shader) +{ + ResourceSerial serial = shader ? shader->getSerial() : ResourceSerial(0); + + if (serial != mAppliedPixelShader) + { + ID3D11PixelShader *appliedShader = shader ? shader->get() : nullptr; + mRenderer->getDeviceContext()->PSSetShader(appliedShader, nullptr, 0); + mAppliedPixelShader = serial; + invalidateShaders(); + } +} + +void StateManager11::setComputeShader(const d3d11::ComputeShader *shader) +{ + ResourceSerial serial = shader ? shader->getSerial() : ResourceSerial(0); + + if (serial != mAppliedComputeShader) + { + ID3D11ComputeShader *appliedShader = shader ? shader->get() : nullptr; + mRenderer->getDeviceContext()->CSSetShader(appliedShader, nullptr, 0); + mAppliedComputeShader = serial; + // TODO(jmadill): Dirty bits for compute. + } +} + +void StateManager11::setVertexConstantBuffer(unsigned int slot, const d3d11::Buffer *buffer) +{ + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + auto ¤tSerial = mCurrentConstantBufferVS[slot]; + + mCurrentConstantBufferVSOffset[slot] = 0; + mCurrentConstantBufferVSSize[slot] = 0; + + if (buffer) + { + if (currentSerial != buffer->getSerial()) + { + deviceContext->VSSetConstantBuffers(slot, 1, buffer->getPointer()); + currentSerial = buffer->getSerial(); + invalidateConstantBuffer(slot); + } + } + else + { + if (!currentSerial.empty()) + { + ID3D11Buffer *nullBuffer = nullptr; + deviceContext->VSSetConstantBuffers(slot, 1, &nullBuffer); + currentSerial.clear(); + invalidateConstantBuffer(slot); + } + } +} + +void StateManager11::setPixelConstantBuffer(unsigned int slot, const d3d11::Buffer *buffer) +{ + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + auto ¤tSerial = mCurrentConstantBufferPS[slot]; + + mCurrentConstantBufferPSOffset[slot] = 0; + mCurrentConstantBufferPSSize[slot] = 0; + + if (buffer) + { + if (currentSerial != buffer->getSerial()) + { + deviceContext->PSSetConstantBuffers(slot, 1, buffer->getPointer()); + currentSerial = buffer->getSerial(); + invalidateConstantBuffer(slot); + } + } + else + { + if (!currentSerial.empty()) + { + ID3D11Buffer *nullBuffer = nullptr; + deviceContext->PSSetConstantBuffers(slot, 1, &nullBuffer); + currentSerial.clear(); + invalidateConstantBuffer(slot); + } + } +} + +void StateManager11::setDepthStencilState(const d3d11::DepthStencilState *depthStencilState, + UINT stencilRef) +{ + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + if (depthStencilState) + { + deviceContext->OMSetDepthStencilState(depthStencilState->get(), stencilRef); + } + else + { + deviceContext->OMSetDepthStencilState(nullptr, stencilRef); } - gl::Error error = framebuffer11->invalidateSwizzles(); - if (error.isError()) + mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE); +} + +void StateManager11::setSimpleBlendState(const d3d11::BlendState *blendState) +{ + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + if (blendState) { - return error; + deviceContext->OMSetBlendState(blendState->get(), nullptr, 0xFFFFFFFF); + } + else + { + deviceContext->OMSetBlendState(nullptr, nullptr, 0xFFFFFFFF); } - return gl::Error(GL_NO_ERROR); + mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE); +} + +void StateManager11::setRasterizerState(const d3d11::RasterizerState *rasterizerState) +{ + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + if (rasterizerState) + { + deviceContext->RSSetState(rasterizerState->get()); + } + else + { + deviceContext->RSSetState(nullptr); + } + + mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE); +} + +void StateManager11::setSimpleViewport(const gl::Extents &extents) +{ + setSimpleViewport(extents.width, extents.height); +} + +void StateManager11::setSimpleViewport(int width, int height) +{ + D3D11_VIEWPORT viewport; + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; + viewport.Width = static_cast(width); + viewport.Height = static_cast(height); + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + + mRenderer->getDeviceContext()->RSSetViewports(1, &viewport); + mInternalDirtyBits.set(DIRTY_BIT_VIEWPORT_STATE); +} + +void StateManager11::setSimplePixelTextureAndSampler(const d3d11::SharedSRV &srv, + const d3d11::SamplerState &samplerState) +{ + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + setShaderResourceInternal(gl::SAMPLER_PIXEL, 0, &srv); + deviceContext->PSSetSamplers(0, 1, samplerState.getPointer()); + + mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE); + mForceSetPixelSamplerStates[0] = true; +} + +void StateManager11::setSimpleScissorRect(const gl::Rectangle &glRect) +{ + D3D11_RECT scissorRect; + scissorRect.left = glRect.x; + scissorRect.right = glRect.x + glRect.width; + scissorRect.top = glRect.y; + scissorRect.bottom = glRect.y + glRect.height; + setScissorRectD3D(scissorRect); +} + +void StateManager11::setScissorRectD3D(const D3D11_RECT &d3dRect) +{ + mRenderer->getDeviceContext()->RSSetScissorRects(1, &d3dRect); + mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE); +} + +// For each Direct3D sampler of either the pixel or vertex stage, +// looks up the corresponding OpenGL texture image unit and texture type, +// and sets the texture and its addressing/filtering state (or NULL when inactive). +// Sampler mapping needs to be up-to-date on the program object before this is called. +gl::Error StateManager11::applyTextures(const gl::Context *context, gl::SamplerType shaderType) +{ + const auto &glState = context->getGLState(); + const auto &caps = context->getCaps(); + ProgramD3D *programD3D = GetImplAs(glState.getProgram()); + + ASSERT(!programD3D->isSamplerMappingDirty()); + + // TODO(jmadill): Use the Program's sampler bindings. + const auto &completeTextures = glState.getCompleteTextureCache(); + + unsigned int samplerRange = programD3D->getUsedSamplerRange(shaderType); + for (unsigned int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++) + { + GLint textureUnit = programD3D->getSamplerMapping(shaderType, samplerIndex, caps); + ASSERT(textureUnit != -1); + gl::Texture *texture = completeTextures[textureUnit]; + + // A nullptr texture indicates incomplete. + if (texture) + { + gl::Sampler *samplerObject = glState.getSampler(textureUnit); + + const gl::SamplerState &samplerState = + samplerObject ? samplerObject->getSamplerState() : texture->getSamplerState(); + + ANGLE_TRY(setSamplerState(context, shaderType, samplerIndex, texture, samplerState)); + ANGLE_TRY(setTexture(context, shaderType, samplerIndex, texture)); + } + else + { + GLenum textureType = programD3D->getSamplerTextureType(shaderType, samplerIndex); + + // Texture is not sampler complete or it is in use by the framebuffer. Bind the + // incomplete texture. + gl::Texture *incompleteTexture = nullptr; + ANGLE_TRY(mRenderer->getIncompleteTexture(context, textureType, &incompleteTexture)); + ANGLE_TRY(setSamplerState(context, shaderType, samplerIndex, incompleteTexture, + incompleteTexture->getSamplerState())); + ANGLE_TRY(setTexture(context, shaderType, samplerIndex, incompleteTexture)); + } + } + + // Set all the remaining textures to NULL + size_t samplerCount = (shaderType == gl::SAMPLER_PIXEL) ? caps.maxTextureImageUnits + : caps.maxVertexTextureImageUnits; + ANGLE_TRY(clearTextures(shaderType, samplerRange, samplerCount)); + + return gl::NoError(); +} + +gl::Error StateManager11::syncTextures(const gl::Context *context) +{ + ANGLE_TRY(applyTextures(context, gl::SAMPLER_VERTEX)); + ANGLE_TRY(applyTextures(context, gl::SAMPLER_PIXEL)); + return gl::NoError(); +} + +gl::Error StateManager11::setSamplerState(const gl::Context *context, + gl::SamplerType type, + int index, + gl::Texture *texture, + const gl::SamplerState &samplerState) +{ +#if !defined(NDEBUG) + // Storage should exist, texture should be complete. Only verified in Debug. + TextureD3D *textureD3D = GetImplAs(texture); + TextureStorage *storage = nullptr; + ANGLE_TRY(textureD3D->getNativeTexture(context, &storage)); + ASSERT(storage); +#endif // !defined(NDEBUG) + + auto *deviceContext = mRenderer->getDeviceContext(); + + if (type == gl::SAMPLER_PIXEL) + { + ASSERT(static_cast(index) < mRenderer->getNativeCaps().maxTextureImageUnits); + + if (mForceSetPixelSamplerStates[index] || + memcmp(&samplerState, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0) + { + ID3D11SamplerState *dxSamplerState = nullptr; + ANGLE_TRY(mRenderer->getSamplerState(samplerState, &dxSamplerState)); + + ASSERT(dxSamplerState != nullptr); + deviceContext->PSSetSamplers(index, 1, &dxSamplerState); + + mCurPixelSamplerStates[index] = samplerState; + } + + mForceSetPixelSamplerStates[index] = false; + } + else if (type == gl::SAMPLER_VERTEX) + { + ASSERT(static_cast(index) < + mRenderer->getNativeCaps().maxVertexTextureImageUnits); + + if (mForceSetVertexSamplerStates[index] || + memcmp(&samplerState, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0) + { + ID3D11SamplerState *dxSamplerState = nullptr; + ANGLE_TRY(mRenderer->getSamplerState(samplerState, &dxSamplerState)); + + ASSERT(dxSamplerState != nullptr); + deviceContext->VSSetSamplers(index, 1, &dxSamplerState); + + mCurVertexSamplerStates[index] = samplerState; + } + + mForceSetVertexSamplerStates[index] = false; + } + else if (type == gl::SAMPLER_COMPUTE) + { + ASSERT(static_cast(index) < + mRenderer->getNativeCaps().maxComputeTextureImageUnits); + + if (mForceSetComputeSamplerStates[index] || + memcmp(&samplerState, &mCurComputeSamplerStates[index], sizeof(gl::SamplerState)) != 0) + { + ID3D11SamplerState *dxSamplerState = nullptr; + ANGLE_TRY(mRenderer->getSamplerState(samplerState, &dxSamplerState)); + + ASSERT(dxSamplerState != nullptr); + deviceContext->CSSetSamplers(index, 1, &dxSamplerState); + + mCurComputeSamplerStates[index] = samplerState; + } + + mForceSetComputeSamplerStates[index] = false; + } + else + UNREACHABLE(); + + // Sampler metadata that's passed to shaders in uniforms is stored separately from rest of the + // sampler state since having it in contiguous memory makes it possible to memcpy to a constant + // buffer, and it doesn't affect the state set by PSSetSamplers/VSSetSamplers. + mShaderConstants.onSamplerChange(type, index, *texture); + + return gl::NoError(); +} + +gl::Error StateManager11::setTexture(const gl::Context *context, + gl::SamplerType type, + int index, + gl::Texture *texture) +{ + const d3d11::SharedSRV *textureSRV = nullptr; + + if (texture) + { + TextureD3D *textureImpl = GetImplAs(texture); + + TextureStorage *texStorage = nullptr; + ANGLE_TRY(textureImpl->getNativeTexture(context, &texStorage)); + + // Texture should be complete and have a storage + ASSERT(texStorage); + + TextureStorage11 *storage11 = GetAs(texStorage); + + ANGLE_TRY(storage11->getSRV(context, texture->getTextureState(), &textureSRV)); + + // If we get an invalid SRV here, something went wrong in the texture class and we're + // unexpectedly missing the shader resource view. + ASSERT(textureSRV->valid()); + + textureImpl->resetDirty(); + } + + ASSERT( + (type == gl::SAMPLER_PIXEL && + static_cast(index) < mRenderer->getNativeCaps().maxTextureImageUnits) || + (type == gl::SAMPLER_VERTEX && + static_cast(index) < mRenderer->getNativeCaps().maxVertexTextureImageUnits)); + + setShaderResourceInternal(type, index, textureSRV); + return gl::NoError(); +} + +// Things that affect a program's dirtyness: +// 1. Directly changing the program executable -> triggered in StateManager11::syncState. +// 2. The vertex attribute layout -> triggered in VertexArray11::syncState/signal. +// 3. The fragment shader's rendertargets -> triggered in Framebuffer11::syncState/signal. +// 4. Enabling/disabling rasterizer discard. -> triggered in StateManager11::syncState. +// 5. Enabling/disabling transform feedback. -> checked in StateManager11::updateState. +// 6. An internal shader was used. -> triggered in StateManager11::set*Shader. +// 7. Drawing with/without point sprites. -> checked in StateManager11::updateState. +// TODO(jmadill): Use dirty bits for transform feedback. +gl::Error StateManager11::syncProgram(const gl::Context *context, GLenum drawMode) +{ + Context11 *context11 = GetImplAs(context); + ANGLE_TRY(context11->triggerDrawCallProgramRecompilation(context, drawMode)); + + const auto &glState = context->getGLState(); + const auto *va11 = GetImplAs(glState.getVertexArray()); + auto *programD3D = GetImplAs(glState.getProgram()); + + programD3D->updateCachedInputLayout(va11->getCurrentStateSerial(), glState); + + // Binaries must be compiled before the sync. + ASSERT(programD3D->hasVertexExecutableForCachedInputLayout()); + ASSERT(programD3D->hasGeometryExecutableForPrimitiveType(drawMode)); + ASSERT(programD3D->hasPixelExecutableForCachedOutputLayout()); + + ShaderExecutableD3D *vertexExe = nullptr; + ANGLE_TRY(programD3D->getVertexExecutableForCachedInputLayout(&vertexExe, nullptr)); + + ShaderExecutableD3D *pixelExe = nullptr; + ANGLE_TRY(programD3D->getPixelExecutableForCachedOutputLayout(&pixelExe, nullptr)); + + ShaderExecutableD3D *geometryExe = nullptr; + ANGLE_TRY(programD3D->getGeometryExecutableForPrimitiveType(context, drawMode, &geometryExe, + nullptr)); + + const d3d11::VertexShader *vertexShader = + (vertexExe ? &GetAs(vertexExe)->getVertexShader() : nullptr); + + // Skip pixel shader if we're doing rasterizer discard. + const d3d11::PixelShader *pixelShader = nullptr; + if (!glState.getRasterizerState().rasterizerDiscard) + { + pixelShader = (pixelExe ? &GetAs(pixelExe)->getPixelShader() : nullptr); + } + + const d3d11::GeometryShader *geometryShader = nullptr; + if (glState.isTransformFeedbackActiveUnpaused()) + { + geometryShader = + (vertexExe ? &GetAs(vertexExe)->getStreamOutShader() : nullptr); + } + else + { + geometryShader = + (geometryExe ? &GetAs(geometryExe)->getGeometryShader() : nullptr); + } + + setDrawShaders(vertexShader, geometryShader, pixelShader); + + // Explicitly clear the shaders dirty bit. + mInternalDirtyBits.reset(DIRTY_BIT_SHADERS); + + return gl::NoError(); +} + +gl::Error StateManager11::applyVertexBuffer(const gl::Context *context, + GLenum mode, + const DrawCallVertexParams &vertexParams, + bool isIndexedRendering) +{ + const auto &state = context->getGLState(); + const gl::VertexArray *vertexArray = state.getVertexArray(); + VertexArray11 *vertexArray11 = GetImplAs(vertexArray); + + if (mVertexAttribsNeedTranslation) + { + ANGLE_TRY(vertexArray11->updateDirtyAndDynamicAttribs(context, &mVertexDataManager, + vertexParams)); + mInputLayoutIsDirty = true; + + // Determine if we need to update attribs on the next draw. + mVertexAttribsNeedTranslation = (vertexArray11->hasActiveDynamicAttrib(context)); + } + + if (!mLastFirstVertex.valid() || mLastFirstVertex.value() != vertexParams.firstVertex()) + { + mLastFirstVertex = vertexParams.firstVertex(); + mInputLayoutIsDirty = true; + } + + if (!mInputLayoutIsDirty) + { + return gl::NoError(); + } + + const auto &vertexArrayAttribs = vertexArray11->getTranslatedAttribs(); + gl::Program *program = state.getProgram(); + + // Sort the attributes according to ensure we re-use similar input layouts. + AttribIndexArray sortedSemanticIndices; + SortAttributesByLayout(program, vertexArrayAttribs, mCurrentValueAttribs, + &sortedSemanticIndices, &mCurrentAttributes); + + auto featureLevel = mRenderer->getRenderer11DeviceCaps().featureLevel; + + // If we are using FL 9_3, make sure the first attribute is not instanced + if (featureLevel <= D3D_FEATURE_LEVEL_9_3 && !mCurrentAttributes.empty()) + { + if (mCurrentAttributes[0]->divisor > 0) + { + Optional firstNonInstancedIndex = FindFirstNonInstanced(mCurrentAttributes); + if (firstNonInstancedIndex.valid()) + { + size_t index = firstNonInstancedIndex.value(); + std::swap(mCurrentAttributes[0], mCurrentAttributes[index]); + std::swap(sortedSemanticIndices[0], sortedSemanticIndices[index]); + } + } + } + + // Update the applied input layout by querying the cache. + ANGLE_TRY(mInputLayoutCache.updateInputLayout(mRenderer, state, mCurrentAttributes, mode, + sortedSemanticIndices, vertexParams)); + + // Update the applied vertex buffers. + ANGLE_TRY(mInputLayoutCache.applyVertexBuffers(context, mCurrentAttributes, mode, + vertexParams.firstVertex(), isIndexedRendering)); + + // InputLayoutCache::applyVertexBuffers calls through to the Bufer11 to get the native vertex + // buffer (ID3D11Buffer *). Because we allocate these buffers lazily, this will trigger + // allocation. This in turn will signal that the buffer is dirty. Since we just resolved the + // dirty-ness in VertexArray11::updateDirtyAndDynamicAttribs, this can make us do a needless + // update on the second draw call. + // Hence we clear the flags here, after we've applied vertex data, since we know everything + // is clean. This is a bit of a hack. + vertexArray11->clearDirtyAndPromoteDynamicAttribs(context, vertexParams); + + mInputLayoutIsDirty = false; + return gl::NoError(); +} + +gl::Error StateManager11::applyIndexBuffer(const gl::Context *context, + const void *indices, + GLsizei count, + GLenum type, + const gl::HasIndexRange &lazyIndexRange, + bool usePrimitiveRestartWorkaround) +{ + const auto &glState = context->getGLState(); + gl::VertexArray *vao = glState.getVertexArray(); + VertexArray11 *vao11 = GetImplAs(vao); + + GLenum destElementType = + GetIndexTranslationDestType(type, lazyIndexRange, usePrimitiveRestartWorkaround); + + if (!vao11->updateElementArrayStorage(context, type, destElementType, indices) && + !mIndexBufferIsDirty) + { + // No streaming or index buffer application necessary. + return gl::NoError(); + } + + gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get(); + + TranslatedIndexData *indexInfo = vao11->getCachedIndexInfo(); + ANGLE_TRY(mIndexDataManager.prepareIndexData(context, type, destElementType, count, + elementArrayBuffer, indices, indexInfo)); + + ID3D11Buffer *buffer = nullptr; + DXGI_FORMAT bufferFormat = + (indexInfo->indexType == GL_UNSIGNED_INT) ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT; + + if (indexInfo->storage) + { + Buffer11 *storage = GetAs(indexInfo->storage); + ANGLE_TRY_RESULT(storage->getBuffer(context, BUFFER_USAGE_INDEX), buffer); + } + else + { + IndexBuffer11 *indexBuffer = GetAs(indexInfo->indexBuffer); + buffer = indexBuffer->getBuffer().get(); + } + + // Track dirty indices in the index range cache. + indexInfo->srcIndexData.srcIndicesChanged = + syncIndexBuffer(buffer, bufferFormat, indexInfo->startOffset); + + mIndexBufferIsDirty = false; + + vao11->setCachedIndexInfoValid(); + return gl::NoError(); +} + +void StateManager11::setIndexBuffer(ID3D11Buffer *buffer, + DXGI_FORMAT indexFormat, + unsigned int offset) +{ + if (syncIndexBuffer(buffer, indexFormat, offset)) + { + mIndexBufferIsDirty = true; + } +} + +bool StateManager11::syncIndexBuffer(ID3D11Buffer *buffer, + DXGI_FORMAT indexFormat, + unsigned int offset) +{ + if (buffer != mAppliedIB || indexFormat != mAppliedIBFormat || offset != mAppliedIBOffset) + { + mRenderer->getDeviceContext()->IASetIndexBuffer(buffer, indexFormat, offset); + + mAppliedIB = buffer; + mAppliedIBFormat = indexFormat; + mAppliedIBOffset = offset; + return true; + } + + return false; +} + +// Vertex buffer is invalidated outside this function. +gl::Error StateManager11::updateVertexOffsetsForPointSpritesEmulation(GLint startVertex, + GLsizei emulatedInstanceId) +{ + return mInputLayoutCache.updateVertexOffsetsForPointSpritesEmulation( + mRenderer, mCurrentAttributes, startVertex, emulatedInstanceId); +} + +gl::Error StateManager11::generateSwizzle(const gl::Context *context, gl::Texture *texture) +{ + if (!texture) + { + return gl::NoError(); + } + + TextureD3D *textureD3D = GetImplAs(texture); + ASSERT(textureD3D); + + TextureStorage *texStorage = nullptr; + ANGLE_TRY(textureD3D->getNativeTexture(context, &texStorage)); + + if (texStorage) + { + TextureStorage11 *storage11 = GetAs(texStorage); + const gl::TextureState &textureState = texture->getTextureState(); + ANGLE_TRY(storage11->generateSwizzles(context, textureState.getSwizzleState())); + } + + return gl::NoError(); +} + +gl::Error StateManager11::generateSwizzlesForShader(const gl::Context *context, + gl::SamplerType type) +{ + const auto &glState = context->getGLState(); + ProgramD3D *programD3D = GetImplAs(glState.getProgram()); + + unsigned int samplerRange = programD3D->getUsedSamplerRange(type); + + for (unsigned int i = 0; i < samplerRange; i++) + { + GLenum textureType = programD3D->getSamplerTextureType(type, i); + GLint textureUnit = programD3D->getSamplerMapping(type, i, context->getCaps()); + if (textureUnit != -1) + { + gl::Texture *texture = glState.getSamplerTexture(textureUnit, textureType); + ASSERT(texture); + if (texture->getTextureState().swizzleRequired()) + { + ANGLE_TRY(generateSwizzle(context, texture)); + } + } + } + + return gl::NoError(); +} + +gl::Error StateManager11::generateSwizzles(const gl::Context *context) +{ + ANGLE_TRY(generateSwizzlesForShader(context, gl::SAMPLER_VERTEX)); + ANGLE_TRY(generateSwizzlesForShader(context, gl::SAMPLER_PIXEL)); + return gl::NoError(); +} + +gl::Error StateManager11::applyUniforms(ProgramD3D *programD3D) +{ + UniformStorage11 *vertexUniformStorage = + GetAs(&programD3D->getVertexUniformStorage()); + UniformStorage11 *fragmentUniformStorage = + GetAs(&programD3D->getFragmentUniformStorage()); + ASSERT(vertexUniformStorage); + ASSERT(fragmentUniformStorage); + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + const d3d11::Buffer *vertexConstantBuffer = nullptr; + ANGLE_TRY(vertexUniformStorage->getConstantBuffer(mRenderer, &vertexConstantBuffer)); + const d3d11::Buffer *pixelConstantBuffer = nullptr; + ANGLE_TRY(fragmentUniformStorage->getConstantBuffer(mRenderer, &pixelConstantBuffer)); + + if (vertexUniformStorage->size() > 0 && programD3D->areVertexUniformsDirty()) + { + UpdateUniformBuffer(deviceContext, vertexUniformStorage, vertexConstantBuffer); + } + + if (fragmentUniformStorage->size() > 0 && programD3D->areFragmentUniformsDirty()) + { + UpdateUniformBuffer(deviceContext, fragmentUniformStorage, pixelConstantBuffer); + } + + unsigned int slot = d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK; + + if (mCurrentConstantBufferVS[slot] != vertexConstantBuffer->getSerial()) + { + deviceContext->VSSetConstantBuffers(slot, 1, vertexConstantBuffer->getPointer()); + mCurrentConstantBufferVS[slot] = vertexConstantBuffer->getSerial(); + mCurrentConstantBufferVSOffset[slot] = 0; + mCurrentConstantBufferVSSize[slot] = 0; + } + + if (mCurrentConstantBufferPS[slot] != pixelConstantBuffer->getSerial()) + { + deviceContext->PSSetConstantBuffers(slot, 1, pixelConstantBuffer->getPointer()); + mCurrentConstantBufferPS[slot] = pixelConstantBuffer->getSerial(); + mCurrentConstantBufferPSOffset[slot] = 0; + mCurrentConstantBufferPSSize[slot] = 0; + } + + programD3D->markUniformsClean(); + + return gl::NoError(); +} + +gl::Error StateManager11::applyDriverUniforms(const ProgramD3D &programD3D) +{ + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + if (!mDriverConstantBufferVS.valid()) + { + size_t requiredSize = mShaderConstants.getRequiredBufferSize(gl::SAMPLER_VERTEX); + + D3D11_BUFFER_DESC constantBufferDescription = {0}; + d3d11::InitConstantBufferDesc(&constantBufferDescription, requiredSize); + ANGLE_TRY(mRenderer->allocateResource(constantBufferDescription, &mDriverConstantBufferVS)); + + ID3D11Buffer *driverVSConstants = mDriverConstantBufferVS.get(); + deviceContext->VSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1, + &driverVSConstants); + } + + if (!mDriverConstantBufferPS.valid()) + { + size_t requiredSize = mShaderConstants.getRequiredBufferSize(gl::SAMPLER_PIXEL); + + D3D11_BUFFER_DESC constantBufferDescription = {0}; + d3d11::InitConstantBufferDesc(&constantBufferDescription, requiredSize); + ANGLE_TRY(mRenderer->allocateResource(constantBufferDescription, &mDriverConstantBufferPS)); + + ID3D11Buffer *driverVSConstants = mDriverConstantBufferPS.get(); + deviceContext->PSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1, + &driverVSConstants); + } + + // Sampler metadata and driver constants need to coexist in the same constant buffer to conserve + // constant buffer slots. We update both in the constant buffer if needed. + ANGLE_TRY(mShaderConstants.updateBuffer(deviceContext, gl::SAMPLER_VERTEX, programD3D, + mDriverConstantBufferVS)); + ANGLE_TRY(mShaderConstants.updateBuffer(deviceContext, gl::SAMPLER_PIXEL, programD3D, + mDriverConstantBufferPS)); + + // needed for the point sprite geometry shader + // GSSetConstantBuffers triggers device removal on 9_3, so we should only call it for ES3. + if (mRenderer->isES3Capable()) + { + if (mCurrentGeometryConstantBuffer != mDriverConstantBufferPS.getSerial()) + { + ASSERT(mDriverConstantBufferPS.valid()); + deviceContext->GSSetConstantBuffers(0, 1, mDriverConstantBufferPS.getPointer()); + mCurrentGeometryConstantBuffer = mDriverConstantBufferPS.getSerial(); + } + } + + return gl::NoError(); +} + +gl::Error StateManager11::applyComputeUniforms(ProgramD3D *programD3D) +{ + UniformStorage11 *computeUniformStorage = + GetAs(&programD3D->getComputeUniformStorage()); + ASSERT(computeUniformStorage); + + const d3d11::Buffer *constantBuffer = nullptr; + ANGLE_TRY(computeUniformStorage->getConstantBuffer(mRenderer, &constantBuffer)); + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + if (computeUniformStorage->size() > 0 && programD3D->areComputeUniformsDirty()) + { + UpdateUniformBuffer(deviceContext, computeUniformStorage, constantBuffer); + programD3D->markUniformsClean(); + } + + if (mCurrentComputeConstantBuffer != constantBuffer->getSerial()) + { + deviceContext->CSSetConstantBuffers( + d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK, 1, + constantBuffer->getPointer()); + mCurrentComputeConstantBuffer = constantBuffer->getSerial(); + } + + if (!mDriverConstantBufferCS.valid()) + { + size_t requiredSize = mShaderConstants.getRequiredBufferSize(gl::SAMPLER_COMPUTE); + + D3D11_BUFFER_DESC constantBufferDescription = {0}; + d3d11::InitConstantBufferDesc(&constantBufferDescription, requiredSize); + ANGLE_TRY(mRenderer->allocateResource(constantBufferDescription, &mDriverConstantBufferCS)); + ID3D11Buffer *buffer = mDriverConstantBufferCS.get(); + deviceContext->CSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1, + &buffer); + } + + ANGLE_TRY(mShaderConstants.updateBuffer(deviceContext, gl::SAMPLER_COMPUTE, *programD3D, + mDriverConstantBufferCS)); + + return gl::NoError(); +} + +gl::Error StateManager11::syncUniformBuffers(const gl::Context *context, ProgramD3D *programD3D) +{ + unsigned int reservedVertex = mRenderer->getReservedVertexUniformBuffers(); + unsigned int reservedFragment = mRenderer->getReservedFragmentUniformBuffers(); + + programD3D->updateUniformBufferCache(context->getCaps(), reservedVertex, reservedFragment); + + const auto &vertexUniformBuffers = programD3D->getVertexUniformBufferCache(); + const auto &fragmentUniformBuffers = programD3D->getFragmentUniformBufferCache(); + const auto &glState = context->getGLState(); + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported(); + + for (size_t bufferIndex = 0; bufferIndex < vertexUniformBuffers.size(); bufferIndex++) + { + GLint binding = vertexUniformBuffers[bufferIndex]; + + if (binding == -1) + { + continue; + } + + const auto &uniformBuffer = glState.getIndexedUniformBuffer(binding); + GLintptr uniformBufferOffset = uniformBuffer.getOffset(); + GLsizeiptr uniformBufferSize = uniformBuffer.getSize(); + + if (uniformBuffer.get() == nullptr) + { + continue; + } + + Buffer11 *bufferStorage = GetImplAs(uniformBuffer.get()); + const d3d11::Buffer *constantBuffer = nullptr; + UINT firstConstant = 0; + UINT numConstants = 0; + + ANGLE_TRY(bufferStorage->getConstantBufferRange(context, uniformBufferOffset, + uniformBufferSize, &constantBuffer, + &firstConstant, &numConstants)); + + ASSERT(constantBuffer); + + if (mCurrentConstantBufferVS[bufferIndex] == constantBuffer->getSerial() && + mCurrentConstantBufferVSOffset[bufferIndex] == uniformBufferOffset && + mCurrentConstantBufferVSSize[bufferIndex] == uniformBufferSize) + { + continue; + } + + unsigned int appliedIndex = reservedVertex + static_cast(bufferIndex); + + if (firstConstant != 0 && uniformBufferSize != 0) + { + ASSERT(numConstants != 0); + deviceContext1->VSSetConstantBuffers1(appliedIndex, 1, constantBuffer->getPointer(), + &firstConstant, &numConstants); + } + else + { + deviceContext->VSSetConstantBuffers(appliedIndex, 1, constantBuffer->getPointer()); + } + + mCurrentConstantBufferVS[appliedIndex] = constantBuffer->getSerial(); + mCurrentConstantBufferVSOffset[appliedIndex] = uniformBufferOffset; + mCurrentConstantBufferVSSize[appliedIndex] = uniformBufferSize; + } + + for (size_t bufferIndex = 0; bufferIndex < fragmentUniformBuffers.size(); bufferIndex++) + { + GLint binding = fragmentUniformBuffers[bufferIndex]; + + if (binding == -1) + { + continue; + } + + const auto &uniformBuffer = glState.getIndexedUniformBuffer(binding); + GLintptr uniformBufferOffset = uniformBuffer.getOffset(); + GLsizeiptr uniformBufferSize = uniformBuffer.getSize(); + + if (uniformBuffer.get() == nullptr) + { + continue; + } + + Buffer11 *bufferStorage = GetImplAs(uniformBuffer.get()); + const d3d11::Buffer *constantBuffer = nullptr; + UINT firstConstant = 0; + UINT numConstants = 0; + + ANGLE_TRY(bufferStorage->getConstantBufferRange(context, uniformBufferOffset, + uniformBufferSize, &constantBuffer, + &firstConstant, &numConstants)); + + ASSERT(constantBuffer); + + if (mCurrentConstantBufferPS[bufferIndex] == constantBuffer->getSerial() && + mCurrentConstantBufferPSOffset[bufferIndex] == uniformBufferOffset && + mCurrentConstantBufferPSSize[bufferIndex] == uniformBufferSize) + { + continue; + } + + unsigned int appliedIndex = reservedFragment + static_cast(bufferIndex); + + if (firstConstant != 0 && uniformBufferSize != 0) + { + deviceContext1->PSSetConstantBuffers1(appliedIndex, 1, constantBuffer->getPointer(), + &firstConstant, &numConstants); + } + else + { + deviceContext->PSSetConstantBuffers(appliedIndex, 1, constantBuffer->getPointer()); + } + + mCurrentConstantBufferPS[appliedIndex] = constantBuffer->getSerial(); + mCurrentConstantBufferPSOffset[appliedIndex] = uniformBufferOffset; + mCurrentConstantBufferPSSize[appliedIndex] = uniformBufferSize; + } + + return gl::NoError(); +} + +gl::Error StateManager11::syncTransformFeedbackBuffers(const gl::Context *context) +{ + const auto &glState = context->getGLState(); + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + // If transform feedback is not active, unbind all buffers + if (!glState.isTransformFeedbackActiveUnpaused()) + { + if (mAppliedTFSerial != mEmptySerial) + { + deviceContext->SOSetTargets(0, nullptr, nullptr); + mAppliedTFSerial = mEmptySerial; + } + return gl::NoError(); + } + + gl::TransformFeedback *transformFeedback = glState.getCurrentTransformFeedback(); + TransformFeedback11 *tf11 = GetImplAs(transformFeedback); + if (mAppliedTFSerial == tf11->getSerial() && !tf11->isDirty()) + { + return gl::NoError(); + } + + const std::vector *soBuffers = nullptr; + ANGLE_TRY_RESULT(tf11->getSOBuffers(context), soBuffers); + const std::vector &soOffsets = tf11->getSOBufferOffsets(); + + deviceContext->SOSetTargets(tf11->getNumSOBuffers(), soBuffers->data(), soOffsets.data()); + + mAppliedTFSerial = tf11->getSerial(); + tf11->onApply(); + + return gl::NoError(); +} + +// DrawCallVertexParams implementation. +DrawCallVertexParams::DrawCallVertexParams(GLint firstVertex, + GLsizei vertexCount, + GLsizei instances) + : mHasIndexRange(nullptr), + mFirstVertex(firstVertex), + mVertexCount(vertexCount), + mInstances(instances), + mBaseVertex(0) +{ +} + +// Use when in a drawElements call. +DrawCallVertexParams::DrawCallVertexParams(bool firstVertexDefinitelyZero, + const gl::HasIndexRange &hasIndexRange, + GLint baseVertex, + GLsizei instances) + : mHasIndexRange(&hasIndexRange), + mFirstVertex(), + mVertexCount(0), + mInstances(instances), + mBaseVertex(baseVertex) +{ + if (firstVertexDefinitelyZero) + { + mFirstVertex = baseVertex; + } +} + +GLint DrawCallVertexParams::firstVertex() const +{ + if (!mFirstVertex.valid()) + { + ensureResolved(); + ASSERT(mFirstVertex.valid()); + } + return mFirstVertex.value(); +} + +GLsizei DrawCallVertexParams::vertexCount() const +{ + ensureResolved(); + return mVertexCount; +} + +GLsizei DrawCallVertexParams::instances() const +{ + return mInstances; +} + +void DrawCallVertexParams::ensureResolved() const +{ + if (mHasIndexRange) + { + ASSERT(!mFirstVertex.valid() || mFirstVertex == mBaseVertex); + + // Resolve the index range now if we need to. + const auto &indexRange = mHasIndexRange->getIndexRange().value(); + mFirstVertex = mBaseVertex + static_cast(indexRange.start); + mVertexCount = static_cast(indexRange.vertexCount()); + mHasIndexRange = nullptr; + } } } // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.h index f900882d7e..e48bc83a22 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StateManager11.h @@ -11,12 +11,15 @@ #include -#include "libANGLE/angletypes.h" -#include "libANGLE/Data.h" +#include "libANGLE/ContextState.h" #include "libANGLE/State.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/renderer/d3d/IndexDataManager.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" +#include "libANGLE/renderer/d3d/d3d11/InputLayoutCache.h" +#include "libANGLE/renderer/d3d/d3d11/Query11.h" #include "libANGLE/renderer/d3d/d3d11/RenderStateCache.h" #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" -#include "libANGLE/renderer/d3d/RendererD3D.h" namespace rx { @@ -24,20 +27,147 @@ namespace rx struct RenderTargetDesc; struct Renderer11DeviceCaps; -struct dx_VertexConstants11 +class ShaderConstants11 : angle::NonCopyable { - float depthRange[4]; - float viewAdjust[4]; - float viewCoords[4]; - float viewScale[4]; + public: + ShaderConstants11(); + ~ShaderConstants11(); + + void init(const gl::Caps &caps); + size_t getRequiredBufferSize(gl::SamplerType samplerType) const; + void markDirty(); + + void setComputeWorkGroups(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ); + void setMultiviewWriteToViewportIndex(GLfloat index); + void onViewportChange(const gl::Rectangle &glViewport, + const D3D11_VIEWPORT &dxViewport, + bool is9_3, + bool presentPathFast); + void onSamplerChange(gl::SamplerType samplerType, + unsigned int samplerIndex, + const gl::Texture &texture); + + gl::Error updateBuffer(ID3D11DeviceContext *deviceContext, + gl::SamplerType samplerType, + const ProgramD3D &programD3D, + const d3d11::Buffer &driverConstantBuffer); + + private: + struct Vertex + { + Vertex() + : depthRange{.0f}, + viewAdjust{.0f}, + viewCoords{.0f}, + viewScale{.0f}, + multiviewWriteToViewportIndex{.0f}, + padding{.0f} + { + } + + float depthRange[4]; + float viewAdjust[4]; + float viewCoords[4]; + float viewScale[2]; + // multiviewWriteToViewportIndex is used to select either the side-by-side or layered + // code-path in the GS. It's value, if set, is either 0.0f or 1.0f. The value is updated + // whenever a multi-view draw framebuffer is made active. + float multiviewWriteToViewportIndex; + + // Added here to manually pad the struct. + float padding; + }; + + struct Pixel + { + Pixel() + : depthRange{.0f}, + viewCoords{.0f}, + depthFront{.0f}, + viewScale{.0f}, + multiviewWriteToViewportIndex(0), + padding(0) + { + } + + float depthRange[4]; + float viewCoords[4]; + float depthFront[4]; + float viewScale[2]; + // multiviewWriteToViewportIndex is used to select either the side-by-side or layered + // code-path in the GS. It's value, if set, is either 0.0f or 1.0f. The value is updated + // whenever a multi-view draw framebuffer is made active. + float multiviewWriteToViewportIndex; + + // Added here to manually pad the struct. + float padding; + }; + + struct Compute + { + Compute() : numWorkGroups{0u}, padding(0u) {} + unsigned int numWorkGroups[3]; + unsigned int padding; // This just pads the struct to 16 bytes + }; + + struct SamplerMetadata + { + SamplerMetadata() : baseLevel(0), internalFormatBits(0), wrapModes(0), padding(0) {} + + int baseLevel; + int internalFormatBits; + int wrapModes; + int padding; // This just pads the struct to 16 bytes + }; + + static_assert(sizeof(SamplerMetadata) == 16u, + "Sampler metadata struct must be one 4-vec / 16 bytes."); + + // Return true if dirty. + bool updateSamplerMetadata(SamplerMetadata *data, const gl::Texture &texture); + + Vertex mVertex; + bool mVertexDirty; + Pixel mPixel; + bool mPixelDirty; + Compute mCompute; + bool mComputeDirty; + + std::vector mSamplerMetadataVS; + bool mSamplerMetadataVSDirty; + std::vector mSamplerMetadataPS; + bool mSamplerMetadataPSDirty; + std::vector mSamplerMetadataCS; + bool mSamplerMetadataCSDirty; }; -struct dx_PixelConstants11 +class DrawCallVertexParams final : angle::NonCopyable { - float depthRange[4]; - float viewCoords[4]; - float depthFront[4]; - float viewScale[4]; + public: + // Use when in a drawArrays call. + DrawCallVertexParams(GLint firstVertex, GLsizei vertexCount, GLsizei instances); + + // Use when in a drawElements call. + DrawCallVertexParams(bool firstVertexDefinitelyZero, + const gl::HasIndexRange &hasIndexRange, + GLint baseVertex, + GLsizei instances); + + // It should be possible to also use an overload to handle the 'slow' indirect draw path. + // TODO(jmadill): Indirect draw slow path overload. + + GLint firstVertex() const; + GLsizei vertexCount() const; + GLsizei instances() const; + + private: + void ensureResolved() const; + + mutable const gl::HasIndexRange *mHasIndexRange; + mutable Optional mFirstVertex; + mutable GLsizei mVertexCount; + GLsizei mInstances; + GLint mBaseVertex; }; class StateManager11 final : angle::NonCopyable @@ -46,62 +176,221 @@ class StateManager11 final : angle::NonCopyable StateManager11(Renderer11 *renderer); ~StateManager11(); - void initialize(const gl::Caps &caps); - void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits); + gl::Error initialize(const gl::Caps &caps, const gl::Extensions &extensions); + void deinitialize(); - gl::Error setBlendState(const gl::Framebuffer *framebuffer, - const gl::BlendState &blendState, - const gl::ColorF &blendColor, - unsigned int sampleMask); + void syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits); - gl::Error setDepthStencilState(const gl::State &glState); - - gl::Error setRasterizerState(const gl::RasterizerState &rasterState); - - void setScissorRectangle(const gl::Rectangle &scissor, bool enabled); - - void setViewport(const gl::Caps *caps, const gl::Rectangle &viewport, float zNear, float zFar); - - void updatePresentPath(bool presentPathFastActive, - const gl::FramebufferAttachment *framebufferAttachment); - - const dx_VertexConstants11 &getVertexConstants() const { return mVertexConstants; } - const dx_PixelConstants11 &getPixelConstants() const { return mPixelConstants; } + gl::Error updateStateForCompute(const gl::Context *context, + GLuint numGroupsX, + GLuint numGroupsY, + GLuint numGroupsZ); void updateStencilSizeIfChanged(bool depthStencilInitialized, unsigned int stencilSize); + // These invalidations methods are called externally. + + // Called from TextureStorage11. + void invalidateBoundViews(); + + // Called from VertexArray11::updateVertexAttribStorage. + void invalidateCurrentValueAttrib(size_t attribIndex); + + // Checks are done on a framebuffer state change to trigger other state changes. + // The Context is allowed to be nullptr for these methods, when called in EGL init code. + void invalidateRenderTarget(); + + // Called by instanced point sprite emulation. + void invalidateVertexBuffer(); + + // Called by Framebuffer11::syncState for the default sized viewport. + void invalidateViewport(const gl::Context *context); + + // Called by TextureStorage11::markLevelDirty. + void invalidateSwizzles(); + + // Called by the Framebuffer11 and VertexArray11. + void invalidateShaders(); + + // Called by VertexArray11 to trigger attribute translation. + void invalidateVertexAttributeTranslation(); + + void setRenderTarget(ID3D11RenderTargetView *rtv, ID3D11DepthStencilView *dsv); + void setRenderTargets(ID3D11RenderTargetView **rtvs, UINT numRtvs, ID3D11DepthStencilView *dsv); + + void onBeginQuery(Query11 *query); + void onDeleteQueryObject(Query11 *query); + gl::Error onMakeCurrent(const gl::Context *context); + + void setInputLayout(const d3d11::InputLayout *inputLayout); + + // TODO(jmadill): Migrate to d3d11::Buffer. + bool queueVertexBufferChange(size_t bufferIndex, + ID3D11Buffer *buffer, + UINT stride, + UINT offset); + bool queueVertexOffsetChange(size_t bufferIndex, UINT offsetOnly); + void applyVertexBufferChanges(); + + void setSingleVertexBuffer(const d3d11::Buffer *buffer, UINT stride, UINT offset); + + gl::Error updateState(const gl::Context *context, GLenum drawMode); + + void setShaderResourceShared(gl::SamplerType shaderType, + UINT resourceSlot, + const d3d11::SharedSRV *srv); void setShaderResource(gl::SamplerType shaderType, UINT resourceSlot, - ID3D11ShaderResourceView *srv); - gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd); + const d3d11::ShaderResourceView *srv); + void setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY primitiveTopology); - gl::Error syncFramebuffer(const gl::Framebuffer *framebuffer); + void setDrawShaders(const d3d11::VertexShader *vertexShader, + const d3d11::GeometryShader *geometryShader, + const d3d11::PixelShader *pixelShader); + void setVertexShader(const d3d11::VertexShader *shader); + void setGeometryShader(const d3d11::GeometryShader *shader); + void setPixelShader(const d3d11::PixelShader *shader); + void setComputeShader(const d3d11::ComputeShader *shader); + void setVertexConstantBuffer(unsigned int slot, const d3d11::Buffer *buffer); + void setPixelConstantBuffer(unsigned int slot, const d3d11::Buffer *buffer); + void setDepthStencilState(const d3d11::DepthStencilState *depthStencilState, UINT stencilRef); + void setSimpleBlendState(const d3d11::BlendState *blendState); + void setRasterizerState(const d3d11::RasterizerState *rasterizerState); + void setSimpleViewport(const gl::Extents &viewportExtents); + void setSimpleViewport(int width, int height); + void setSimplePixelTextureAndSampler(const d3d11::SharedSRV &srv, + const d3d11::SamplerState &samplerState); + void setSimpleScissorRect(const gl::Rectangle &glRect); + void setScissorRectD3D(const D3D11_RECT &d3dRect); - void invalidateRenderTarget(); - void invalidateEverything(); - bool setRenderTargets(const RenderTargetArray &renderTargets, - ID3D11DepthStencilView *depthStencil); - void setRenderTarget(ID3D11RenderTargetView *renderTarget, - ID3D11DepthStencilView *depthStencil); + // Not handled by an internal dirty bit because of the extra draw parameters. + gl::Error applyVertexBuffer(const gl::Context *context, + GLenum mode, + const DrawCallVertexParams &vertexParams, + bool isIndexedRendering); + + gl::Error applyIndexBuffer(const gl::Context *context, + const void *indices, + GLsizei count, + GLenum type, + const gl::HasIndexRange &lazyIndexRange, + bool usePrimitiveRestartWorkaround); + + void setIndexBuffer(ID3D11Buffer *buffer, DXGI_FORMAT indexFormat, unsigned int offset); + + gl::Error updateVertexOffsetsForPointSpritesEmulation(GLint startVertex, + GLsizei emulatedInstanceId); + + // TODO(jmadill): Should be private. + gl::Error applyComputeUniforms(ProgramD3D *programD3D); + + // Only used in testing. + InputLayoutCache *getInputLayoutCache() { return &mInputLayoutCache; } private: - void unsetConflictingSRVs(gl::SamplerType shaderType, + template + void setShaderResourceInternal(gl::SamplerType shaderType, + UINT resourceSlot, + const SRVType *srv); + + bool unsetConflictingView(ID3D11View *view); + bool unsetConflictingSRVs(gl::SamplerType shaderType, uintptr_t resource, - const gl::ImageIndex &index); - void setViewportBounds(const int width, const int height); + const gl::ImageIndex *index); + void unsetConflictingAttachmentResources(const gl::FramebufferAttachment *attachment, + ID3D11Resource *resource); + + gl::Error syncBlendState(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::BlendState &blendState, + const gl::ColorF &blendColor, + unsigned int sampleMask); + + gl::Error syncDepthStencilState(const gl::State &glState); + + gl::Error syncRasterizerState(const gl::Context *context, bool pointDrawMode); + + void syncScissorRectangle(const gl::Rectangle &scissor, bool enabled); + + void syncViewport(const gl::Context *context); + + void checkPresentPath(const gl::Context *context); + + gl::Error syncFramebuffer(const gl::Context *context, gl::Framebuffer *framebuffer); + gl::Error syncProgram(const gl::Context *context, GLenum drawMode); + + gl::Error syncTextures(const gl::Context *context); + gl::Error applyTextures(const gl::Context *context, gl::SamplerType shaderType); + + gl::Error setSamplerState(const gl::Context *context, + gl::SamplerType type, + int index, + gl::Texture *texture, + const gl::SamplerState &sampler); + gl::Error setTexture(const gl::Context *context, + gl::SamplerType type, + int index, + gl::Texture *texture); + + // Faster than calling setTexture a jillion times + gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd); + void handleMultiviewDrawFramebufferChange(const gl::Context *context); + + gl::Error syncCurrentValueAttribs(const gl::State &glState); + + gl::Error generateSwizzle(const gl::Context *context, gl::Texture *texture); + gl::Error generateSwizzlesForShader(const gl::Context *context, gl::SamplerType type); + gl::Error generateSwizzles(const gl::Context *context); + + gl::Error applyDriverUniforms(const ProgramD3D &programD3D); + gl::Error applyUniforms(ProgramD3D *programD3D); + + gl::Error syncUniformBuffers(const gl::Context *context, ProgramD3D *programD3D); + gl::Error syncTransformFeedbackBuffers(const gl::Context *context); + + // These are currently only called internally. + void invalidateTexturesAndSamplers(); + void invalidateDriverUniforms(); + void invalidateProgramUniforms(); + void invalidateProgramUniformBuffers(); + void invalidateConstantBuffer(unsigned int slot); + + // Called by the Framebuffer11 directly. + void processFramebufferInvalidation(const gl::Context *context); + + bool syncIndexBuffer(ID3D11Buffer *buffer, DXGI_FORMAT indexFormat, unsigned int offset); + + enum DirtyBitType + { + DIRTY_BIT_RENDER_TARGET, + DIRTY_BIT_VIEWPORT_STATE, + DIRTY_BIT_SCISSOR_STATE, + DIRTY_BIT_RASTERIZER_STATE, + DIRTY_BIT_BLEND_STATE, + DIRTY_BIT_DEPTH_STENCIL_STATE, + DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE, + DIRTY_BIT_PROGRAM_UNIFORMS, + DIRTY_BIT_DRIVER_UNIFORMS, + DIRTY_BIT_PROGRAM_UNIFORM_BUFFERS, + DIRTY_BIT_SHADERS, + DIRTY_BIT_CURRENT_VALUE_ATTRIBS, + DIRTY_BIT_INVALID, + DIRTY_BIT_MAX = DIRTY_BIT_INVALID, + }; + + using DirtyBits = angle::BitSet; Renderer11 *mRenderer; + // Internal dirty bits. + DirtyBits mInternalDirtyBits; + // Blend State - bool mBlendStateIsDirty; - // TODO(dianx) temporary representation of a dirty bit. once we move enough states in, - // try experimenting with dirty bit instead of a bool gl::BlendState mCurBlendState; gl::ColorF mCurBlendColor; unsigned int mCurSampleMask; // Currently applied depth stencil state - bool mDepthStencilStateIsDirty; gl::DepthStencilState mCurDepthStencilState; int mCurStencilRef; int mCurStencilBackRef; @@ -110,34 +399,35 @@ class StateManager11 final : angle::NonCopyable Optional mCurDisableStencil; // Currently applied rasterizer state - bool mRasterizerStateIsDirty; gl::RasterizerState mCurRasterState; // Currently applied scissor rectangle state - bool mScissorStateIsDirty; bool mCurScissorEnabled; gl::Rectangle mCurScissorRect; // Currently applied viewport state - bool mViewportStateIsDirty; gl::Rectangle mCurViewport; float mCurNear; float mCurFar; + // The viewport offsets are guaranteed to be updated whenever the gl::State::DirtyBits are + // resolved and can be applied to the viewport and scissor whenever the internal viewport and + // scissor bits are resolved. + std::vector mViewportOffsets; + // Things needed in viewport state - dx_VertexConstants11 mVertexConstants; - dx_PixelConstants11 mPixelConstants; + ShaderConstants11 mShaderConstants; // Render target variables gl::Extents mViewportBounds; + bool mRenderTargetIsDirty; // EGL_ANGLE_experimental_present_path variables bool mCurPresentPathFastEnabled; int mCurPresentPathFastColorBufferHeight; - // Current RenderTarget state - std::array mAppliedRTVs; - uintptr_t mAppliedDSV; + // Queries that are currently active in this state + std::set mCurrentQueries; // Currently applied textures struct SRVRecord @@ -154,7 +444,8 @@ class StateManager11 final : angle::NonCopyable class SRVCache : angle::NonCopyable { public: - SRVCache() : mHighestUsedSRV(0) {} + SRVCache(); + ~SRVCache(); void initialize(size_t size) { mCurrentSRVs.resize(size); } @@ -175,6 +466,91 @@ class StateManager11 final : angle::NonCopyable // A block of NULL pointers, cached so we don't re-allocate every draw call std::vector mNullSRVs; + + // Current translations of "Current-Value" data - owned by Context, not VertexArray. + gl::AttributesMask mDirtyCurrentValueAttribs; + std::vector mCurrentValueAttribs; + + // Current applied input layout. + ResourceSerial mCurrentInputLayout; + bool mInputLayoutIsDirty; + bool mVertexAttribsNeedTranslation; + + // Current applied vertex states. + // TODO(jmadill): Figure out how to use ResourceSerial here. + std::array mCurrentVertexBuffers; + std::array mCurrentVertexStrides; + std::array mCurrentVertexOffsets; + gl::RangeUI mDirtyVertexBufferRange; + + // Currently applied primitive topology + D3D11_PRIMITIVE_TOPOLOGY mCurrentPrimitiveTopology; + + // Currently applied shaders + ResourceSerial mAppliedVertexShader; + ResourceSerial mAppliedGeometryShader; + ResourceSerial mAppliedPixelShader; + ResourceSerial mAppliedComputeShader; + + // Currently applied sampler states + std::vector mForceSetVertexSamplerStates; + std::vector mCurVertexSamplerStates; + + std::vector mForceSetPixelSamplerStates; + std::vector mCurPixelSamplerStates; + + std::vector mForceSetComputeSamplerStates; + std::vector mCurComputeSamplerStates; + + // Special dirty bit for swizzles. Since they use internal shaders, must be done in a pre-pass. + bool mDirtySwizzles; + + // Currently applied index buffer + ID3D11Buffer *mAppliedIB; + DXGI_FORMAT mAppliedIBFormat; + unsigned int mAppliedIBOffset; + bool mIndexBufferIsDirty; + + // Vertex, index and input layouts + VertexDataManager mVertexDataManager; + IndexDataManager mIndexDataManager; + InputLayoutCache mInputLayoutCache; + std::vector mCurrentAttributes; + Optional mLastFirstVertex; + + // ANGLE_multiview. + bool mIsMultiviewEnabled; + + // Driver Constants. + d3d11::Buffer mDriverConstantBufferVS; + d3d11::Buffer mDriverConstantBufferPS; + d3d11::Buffer mDriverConstantBufferCS; + + ResourceSerial mCurrentComputeConstantBuffer; + ResourceSerial mCurrentGeometryConstantBuffer; + + template + using VertexConstantBufferArray = + std::array; + + VertexConstantBufferArray mCurrentConstantBufferVS; + VertexConstantBufferArray mCurrentConstantBufferVSOffset; + VertexConstantBufferArray mCurrentConstantBufferVSSize; + + template + using FragmentConstantBufferArray = + std::array; + + FragmentConstantBufferArray mCurrentConstantBufferPS; + FragmentConstantBufferArray mCurrentConstantBufferPSOffset; + FragmentConstantBufferArray mCurrentConstantBufferPSSize; + + // Currently applied transform feedback buffers + Serial mAppliedTFSerial; + + Serial mEmptySerial; + + bool mIsTransformFeedbackCurrentlyActiveUnpaused; }; } // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StreamProducerNV12.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StreamProducerNV12.cpp new file mode 100644 index 0000000000..1981b5f7b2 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StreamProducerNV12.cpp @@ -0,0 +1,102 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// StreamProducerNV12.cpp: Implements the stream producer for NV12 textures + +#include "libANGLE/renderer/d3d/d3d11/StreamProducerNV12.h" + +#include "common/utilities.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" + +namespace rx +{ + +StreamProducerNV12::StreamProducerNV12(Renderer11 *renderer) + : mRenderer(renderer), mTexture(nullptr), mArraySlice(0), mTextureWidth(0), mTextureHeight(0) +{ +} + +StreamProducerNV12::~StreamProducerNV12() +{ + SafeRelease(mTexture); +} + +egl::Error StreamProducerNV12::validateD3DNV12Texture(void *pointer) const +{ + ID3D11Texture2D *textureD3D = static_cast(pointer); + + // Check that the texture originated from our device + ID3D11Device *device; + textureD3D->GetDevice(&device); + if (device != mRenderer->getDevice()) + { + return egl::EglBadParameter() << "Texture not created on ANGLE D3D device"; + } + + // Get the description and validate it + D3D11_TEXTURE2D_DESC desc; + textureD3D->GetDesc(&desc); + if (desc.Format != DXGI_FORMAT_NV12) + { + return egl::EglBadParameter() << "Texture format not DXGI_FORMAT_NV12"; + } + if (desc.Width < 1 || desc.Height < 1) + { + return egl::EglBadParameter() << "Texture is of size 0"; + } + if ((desc.Width % 2) != 0 || (desc.Height % 2) != 0) + { + return egl::EglBadParameter() << "Texture dimensions are not even"; + } + return egl::NoError(); +} + +void StreamProducerNV12::postD3DNV12Texture(void *pointer, const egl::AttributeMap &attributes) +{ + ASSERT(pointer != nullptr); + ID3D11Texture2D *textureD3D = static_cast(pointer); + + // Check that the texture originated from our device + ID3D11Device *device; + textureD3D->GetDevice(&device); + + // Get the description + D3D11_TEXTURE2D_DESC desc; + textureD3D->GetDesc(&desc); + + // Release the previous texture if there is one + SafeRelease(mTexture); + + mTexture = textureD3D; + mTexture->AddRef(); + mTextureWidth = desc.Width; + mTextureHeight = desc.Height; + mArraySlice = static_cast(attributes.get(EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE, 0)); +} + +egl::Stream::GLTextureDescription StreamProducerNV12::getGLFrameDescription(int planeIndex) +{ + // The UV plane of NV12 textures has half the width/height of the Y plane + egl::Stream::GLTextureDescription desc; + desc.width = (planeIndex == 0) ? mTextureWidth : (mTextureWidth / 2); + desc.height = (planeIndex == 0) ? mTextureHeight : (mTextureHeight / 2); + desc.internalFormat = (planeIndex == 0) ? GL_R8 : GL_RG8; + desc.mipLevels = 0; + return desc; +} + +ID3D11Texture2D *StreamProducerNV12::getD3DTexture() +{ + return mTexture; +} + +UINT StreamProducerNV12::getArraySlice() +{ + return mArraySlice; +} + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StreamProducerNV12.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StreamProducerNV12.h new file mode 100644 index 0000000000..304c9dfe53 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/StreamProducerNV12.h @@ -0,0 +1,44 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// StreamProducerNV12.h: Interface for a NV12 texture stream producer + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_STREAM11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_STREAM11_H_ + +#include "libANGLE/renderer/StreamProducerImpl.h" + +namespace rx +{ +class Renderer11; + +class StreamProducerNV12 : public StreamProducerImpl +{ + public: + StreamProducerNV12(Renderer11 *renderer); + ~StreamProducerNV12() override; + + egl::Error validateD3DNV12Texture(void *pointer) const override; + void postD3DNV12Texture(void *pointer, const egl::AttributeMap &attributes) override; + egl::Stream::GLTextureDescription getGLFrameDescription(int planeIndex) override; + + // Gets a pointer to the internal D3D texture + ID3D11Texture2D *getD3DTexture(); + + // Gets the slice index for the D3D texture that the frame is in + UINT getArraySlice(); + + private: + Renderer11 *mRenderer; + + ID3D11Texture2D *mTexture; + UINT mArraySlice; + UINT mTextureWidth; + UINT mTextureHeight; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_STREAM11_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp index 42c336c8cf..dcfd06484d 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp @@ -11,9 +11,9 @@ #include #include "libANGLE/features.h" -#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" -#include "libANGLE/renderer/d3d/d3d11/NativeWindow.h" +#include "libANGLE/renderer/d3d/d3d11/NativeWindow11.h" #include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" #include "third_party/trace_event/trace_event.h" @@ -21,6 +21,7 @@ // Precompiled shaders #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h" #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h" +#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dms11ps.h" #ifdef ANGLE_ENABLE_KEYEDMUTEX #define ANGLE_RESOURCE_SHARE_TYPE D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX @@ -33,22 +34,30 @@ namespace rx namespace { -bool NeedsOffscreenTexture(Renderer11 *renderer, NativeWindow nativeWindow, EGLint orientation) +// To avoid overflow in QPC to Microseconds calculations, since we multiply +// by kMicrosecondsPerSecond, then the QPC value should not exceed +// (2^63 - 1) / 1E6. If it exceeds that threshold, we divide then multiply. +static constexpr int64_t kQPCOverflowThreshold = 0x8637BD05AF7; +static constexpr int64_t kMicrosecondsPerSecond = 1000000; + +bool NeedsOffscreenTexture(Renderer11 *renderer, NativeWindow11 *nativeWindow, EGLint orientation) { // We don't need an offscreen texture if either orientation = INVERT_Y, // or present path fast is enabled and we're not rendering onto an offscreen surface. return orientation != EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE && - !(renderer->presentPathFastEnabled() && nativeWindow.getNativeWindow()); + !(renderer->presentPathFastEnabled() && nativeWindow->getNativeWindow()); } } // anonymous namespace SwapChain11::SwapChain11(Renderer11 *renderer, - NativeWindow nativeWindow, + NativeWindow11 *nativeWindow, HANDLE shareHandle, + IUnknown *d3dTexture, GLenum backBufferFormat, GLenum depthBufferFormat, - EGLint orientation) - : SwapChainD3D(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat), + EGLint orientation, + EGLint samples) + : SwapChainD3D(shareHandle, d3dTexture, backBufferFormat, depthBufferFormat), mRenderer(renderer), mWidth(-1), mHeight(-1), @@ -56,33 +65,42 @@ SwapChain11::SwapChain11(Renderer11 *renderer, mAppCreatedShareHandle(mShareHandle != nullptr), mSwapInterval(0), mPassThroughResourcesInit(false), + mNativeWindow(nativeWindow), mFirstSwap(true), mSwapChain(nullptr), -#if defined(ANGLE_ENABLE_D3D11_1) mSwapChain1(nullptr), -#endif mKeyedMutex(nullptr), - mBackBufferTexture(nullptr), - mBackBufferRTView(nullptr), - mBackBufferSRView(nullptr), + mBackBufferTexture(), + mBackBufferRTView(), + mBackBufferSRView(), mNeedsOffscreenTexture(NeedsOffscreenTexture(renderer, nativeWindow, orientation)), - mOffscreenTexture(nullptr), - mOffscreenRTView(nullptr), - mOffscreenSRView(nullptr), - mDepthStencilTexture(nullptr), - mDepthStencilDSView(nullptr), - mDepthStencilSRView(nullptr), - mQuadVB(nullptr), - mPassThroughSampler(nullptr), - mPassThroughIL(nullptr), - mPassThroughVS(nullptr), - mPassThroughPS(nullptr), - mPassThroughRS(nullptr), + mOffscreenTexture(), + mOffscreenRTView(), + mOffscreenSRView(), + mNeedsOffscreenTextureCopy(false), + mOffscreenTextureCopyForSRV(), + mDepthStencilTexture(), + mDepthStencilDSView(), + mDepthStencilSRView(), + mQuadVB(), + mPassThroughSampler(), + mPassThroughIL(), + mPassThroughVS(), + mPassThroughPS(), + mPassThroughRS(), mColorRenderTarget(this, renderer, false), - mDepthStencilRenderTarget(this, renderer, true) + mDepthStencilRenderTarget(this, renderer, true), + mEGLSamples(samples) { // Sanity check that if present path fast is active then we're using the default orientation ASSERT(!mRenderer->presentPathFastEnabled() || orientation == 0); + + // Get the performance counter + LARGE_INTEGER counterFreqency = {}; + BOOL success = QueryPerformanceFrequency(&counterFreqency); + ASSERT(success); + + mQPCFrequency = counterFreqency.QuadPart; } SwapChain11::~SwapChain11() @@ -92,52 +110,56 @@ SwapChain11::~SwapChain11() void SwapChain11::release() { -#if defined(ANGLE_ENABLE_D3D11_1) + // TODO(jmadill): Should probably signal that the RenderTarget is dirty. + SafeRelease(mSwapChain1); -#endif SafeRelease(mSwapChain); SafeRelease(mKeyedMutex); - SafeRelease(mBackBufferTexture); - SafeRelease(mBackBufferRTView); - SafeRelease(mBackBufferSRView); - SafeRelease(mOffscreenTexture); - SafeRelease(mOffscreenRTView); - SafeRelease(mOffscreenSRView); - SafeRelease(mDepthStencilTexture); - SafeRelease(mDepthStencilDSView); - SafeRelease(mDepthStencilSRView); - SafeRelease(mQuadVB); - SafeRelease(mPassThroughSampler); - SafeRelease(mPassThroughIL); - SafeRelease(mPassThroughVS); - SafeRelease(mPassThroughPS); - SafeRelease(mPassThroughRS); + mBackBufferTexture.reset(); + mBackBufferRTView.reset(); + mBackBufferSRView.reset(); + mOffscreenTexture.reset(); + mOffscreenRTView.reset(); + mOffscreenSRView.reset(); + mDepthStencilTexture.reset(); + mDepthStencilDSView.reset(); + mDepthStencilSRView.reset(); + mQuadVB.reset(); + mPassThroughSampler.reset(); + mPassThroughIL.reset(); + mPassThroughVS.reset(); + mPassThroughPS.reset(); + mPassThroughRS.reset(); if (!mAppCreatedShareHandle) { - mShareHandle = NULL; + mShareHandle = nullptr; } } void SwapChain11::releaseOffscreenColorBuffer() { - SafeRelease(mOffscreenTexture); - SafeRelease(mOffscreenRTView); - SafeRelease(mOffscreenSRView); + mOffscreenTexture.reset(); + mOffscreenRTView.reset(); + mOffscreenSRView.reset(); + mNeedsOffscreenTextureCopy = false; + mOffscreenTextureCopyForSRV.reset(); } void SwapChain11::releaseOffscreenDepthBuffer() { - SafeRelease(mDepthStencilTexture); - SafeRelease(mDepthStencilDSView); - SafeRelease(mDepthStencilSRView); + mDepthStencilTexture.reset(); + mDepthStencilDSView.reset(); + mDepthStencilSRView.reset(); } -EGLint SwapChain11::resetOffscreenBuffers(int backbufferWidth, int backbufferHeight) +EGLint SwapChain11::resetOffscreenBuffers(const gl::Context *context, + int backbufferWidth, + int backbufferHeight) { if (mNeedsOffscreenTexture) { - EGLint result = resetOffscreenColorBuffer(backbufferWidth, backbufferHeight); + EGLint result = resetOffscreenColorBuffer(context, backbufferWidth, backbufferHeight); if (result != EGL_SUCCESS) { return result; @@ -156,117 +178,106 @@ EGLint SwapChain11::resetOffscreenBuffers(int backbufferWidth, int backbufferHei return EGL_SUCCESS; } -EGLint SwapChain11::resetOffscreenColorBuffer(int backbufferWidth, int backbufferHeight) +EGLint SwapChain11::resetOffscreenColorBuffer(const gl::Context *context, + int backbufferWidth, + int backbufferHeight) { ASSERT(mNeedsOffscreenTexture); TRACE_EVENT0("gpu.angle", "SwapChain11::resetOffscreenTexture"); ID3D11Device *device = mRenderer->getDevice(); - ASSERT(device != NULL); + ASSERT(device != nullptr); // D3D11 does not allow zero size textures ASSERT(backbufferWidth >= 1); ASSERT(backbufferHeight >= 1); // Preserve the render target content - ID3D11Texture2D *previousOffscreenTexture = mOffscreenTexture; - if (previousOffscreenTexture) - { - previousOffscreenTexture->AddRef(); - } + TextureHelper11 previousOffscreenTexture(std::move(mOffscreenTexture)); const int previousWidth = mWidth; const int previousHeight = mHeight; releaseOffscreenColorBuffer(); - const d3d11::TextureFormat &backbufferFormatInfo = d3d11::GetTextureFormatInfo(mOffscreenRenderTargetFormat, mRenderer->getRenderer11DeviceCaps()); + const d3d11::Format &backbufferFormatInfo = + d3d11::Format::Get(mOffscreenRenderTargetFormat, mRenderer->getRenderer11DeviceCaps()); + D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; - // If the app passed in a share handle, open the resource - // See EGL_ANGLE_d3d_share_handle_client_buffer - if (mAppCreatedShareHandle) + // If the app passed in a share handle or D3D texture, open the resource + // See EGL_ANGLE_d3d_share_handle_client_buffer and EGL_ANGLE_d3d_texture_client_buffer + if (mAppCreatedShareHandle || mD3DTexture != nullptr) { - ID3D11Resource *tempResource11; - HRESULT result = device->OpenSharedResource(mShareHandle, __uuidof(ID3D11Resource), (void**)&tempResource11); - - if (FAILED(result)) + if (mAppCreatedShareHandle) { - ERR("Failed to open the swap chain pbuffer share handle: %08lX", result); - release(); - return EGL_BAD_PARAMETER; + ID3D11Resource *tempResource11; + HRESULT result = device->OpenSharedResource(mShareHandle, __uuidof(ID3D11Resource), + (void **)&tempResource11); + ASSERT(SUCCEEDED(result)); + + mOffscreenTexture.set(d3d11::DynamicCastComObject(tempResource11), + backbufferFormatInfo); + SafeRelease(tempResource11); } - - result = tempResource11->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&mOffscreenTexture); - SafeRelease(tempResource11); - - if (FAILED(result)) + else if (mD3DTexture != nullptr) { - ERR("Failed to query texture2d interface in pbuffer share handle: %08lX", result); - release(); - return EGL_BAD_PARAMETER; + mOffscreenTexture.set(d3d11::DynamicCastComObject(mD3DTexture), + backbufferFormatInfo); } - - // Validate offscreen texture parameters - D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; - mOffscreenTexture->GetDesc(&offscreenTextureDesc); - - if (offscreenTextureDesc.Width != (UINT)backbufferWidth || - offscreenTextureDesc.Height != (UINT)backbufferHeight || - offscreenTextureDesc.Format != backbufferFormatInfo.texFormat || - offscreenTextureDesc.MipLevels != 1 || - offscreenTextureDesc.ArraySize != 1) + else { - ERR("Invalid texture parameters in the shared offscreen texture pbuffer"); + UNREACHABLE(); + } + ASSERT(mOffscreenTexture.valid()); + mOffscreenTexture.getDesc(&offscreenTextureDesc); + + // Fail if the offscreen texture is not renderable. + if ((offscreenTextureDesc.BindFlags & D3D11_BIND_RENDER_TARGET) == 0) + { + ERR() << "Could not use provided offscreen texture, texture not renderable."; release(); - return EGL_BAD_PARAMETER; + return EGL_BAD_SURFACE; } } else { - const bool useSharedResource = !mNativeWindow.getNativeWindow() && mRenderer->getShareHandleSupport(); + const bool useSharedResource = + !mNativeWindow->getNativeWindow() && mRenderer->getShareHandleSupport(); - D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; offscreenTextureDesc.Width = backbufferWidth; offscreenTextureDesc.Height = backbufferHeight; - offscreenTextureDesc.Format = backbufferFormatInfo.texFormat; + offscreenTextureDesc.Format = backbufferFormatInfo.texFormat; offscreenTextureDesc.MipLevels = 1; offscreenTextureDesc.ArraySize = 1; - offscreenTextureDesc.SampleDesc.Count = 1; + offscreenTextureDesc.SampleDesc.Count = getD3DSamples(); offscreenTextureDesc.SampleDesc.Quality = 0; offscreenTextureDesc.Usage = D3D11_USAGE_DEFAULT; offscreenTextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; offscreenTextureDesc.CPUAccessFlags = 0; offscreenTextureDesc.MiscFlags = useSharedResource ? ANGLE_RESOURCE_SHARE_TYPE : 0; - HRESULT result = device->CreateTexture2D(&offscreenTextureDesc, NULL, &mOffscreenTexture); - - if (FAILED(result)) + gl::Error err = mRenderer->allocateTexture(offscreenTextureDesc, backbufferFormatInfo, + &mOffscreenTexture); + if (err.isError()) { - ERR("Could not create offscreen texture: %08lX", result); + ERR() << "Could not create offscreen texture, " << err; release(); - - if (d3d11::isDeviceLostError(result)) - { - return EGL_CONTEXT_LOST; - } - else - { - return EGL_BAD_ALLOC; - } + return EGL_BAD_ALLOC; } - d3d11::SetDebugName(mOffscreenTexture, "Offscreen back buffer texture"); + mOffscreenTexture.setDebugName("Offscreen back buffer texture"); // EGL_ANGLE_surface_d3d_texture_2d_share_handle requires that we store a share handle for the client if (useSharedResource) { - IDXGIResource *offscreenTextureResource = NULL; - result = mOffscreenTexture->QueryInterface(__uuidof(IDXGIResource), (void**)&offscreenTextureResource); + IDXGIResource *offscreenTextureResource = nullptr; + HRESULT result = mOffscreenTexture.get()->QueryInterface( + __uuidof(IDXGIResource), (void **)&offscreenTextureResource); // Fall back to no share handle on failure if (FAILED(result)) { - ERR("Could not query offscreen texture resource: %08lX", result); + ERR() << "Could not query offscreen texture resource, " << gl::FmtHR(result); } else { @@ -275,36 +286,49 @@ EGLint SwapChain11::resetOffscreenColorBuffer(int backbufferWidth, int backbuffe if (FAILED(result)) { - mShareHandle = NULL; - ERR("Could not get offscreen texture shared handle: %08lX", result); + mShareHandle = nullptr; + ERR() << "Could not get offscreen texture shared handle, " << gl::FmtHR(result); } } } } // This may return null if the original texture was created without a keyed mutex. - mKeyedMutex = d3d11::DynamicCastComObject(mOffscreenTexture); + mKeyedMutex = d3d11::DynamicCastComObject(mOffscreenTexture.get()); D3D11_RENDER_TARGET_VIEW_DESC offscreenRTVDesc; - offscreenRTVDesc.Format = backbufferFormatInfo.rtvFormat; - offscreenRTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + offscreenRTVDesc.Format = backbufferFormatInfo.rtvFormat; + offscreenRTVDesc.ViewDimension = + (mEGLSamples <= 1) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS; offscreenRTVDesc.Texture2D.MipSlice = 0; - HRESULT result = device->CreateRenderTargetView(mOffscreenTexture, &offscreenRTVDesc, &mOffscreenRTView); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mOffscreenRTView, "Offscreen back buffer render target"); + gl::Error err = + mRenderer->allocateResource(offscreenRTVDesc, mOffscreenTexture.get(), &mOffscreenRTView); + ASSERT(!err.isError()); + mOffscreenRTView.setDebugName("Offscreen back buffer render target"); D3D11_SHADER_RESOURCE_VIEW_DESC offscreenSRVDesc; - offscreenSRVDesc.Format = backbufferFormatInfo.srvFormat; - offscreenSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + offscreenSRVDesc.Format = backbufferFormatInfo.srvFormat; + offscreenSRVDesc.ViewDimension = + (mEGLSamples <= 1) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS; offscreenSRVDesc.Texture2D.MostDetailedMip = 0; offscreenSRVDesc.Texture2D.MipLevels = static_cast(-1); - result = device->CreateShaderResourceView(mOffscreenTexture, &offscreenSRVDesc, &mOffscreenSRView); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mOffscreenSRView, "Offscreen back buffer shader resource"); + if (offscreenTextureDesc.BindFlags & D3D11_BIND_SHADER_RESOURCE) + { + err = mRenderer->allocateResource(offscreenSRVDesc, mOffscreenTexture.get(), + &mOffscreenSRView); + ASSERT(!err.isError()); + mOffscreenSRView.setDebugName("Offscreen back buffer shader resource"); + } + else + { + // Special case for external textures that cannot support sampling. Since internally we + // assume our SwapChain is always readable, we make a copy texture that is compatible. + mNeedsOffscreenTextureCopy = true; + } - if (previousOffscreenTexture != nullptr) + if (previousOffscreenTexture.valid()) { D3D11_BOX sourceBox = {0}; sourceBox.left = 0; @@ -316,14 +340,12 @@ EGLint SwapChain11::resetOffscreenColorBuffer(int backbufferWidth, int backbuffe ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); const int yoffset = std::max(backbufferHeight - previousHeight, 0); - deviceContext->CopySubresourceRegion(mOffscreenTexture, 0, 0, yoffset, 0, - previousOffscreenTexture, 0, &sourceBox); - - SafeRelease(previousOffscreenTexture); + deviceContext->CopySubresourceRegion(mOffscreenTexture.get(), 0, 0, yoffset, 0, + previousOffscreenTexture.get(), 0, &sourceBox); if (mSwapChain) { - swapRect(0, 0, backbufferWidth, backbufferHeight); + swapRect(context, 0, 0, backbufferWidth, backbufferHeight); } } @@ -336,21 +358,38 @@ EGLint SwapChain11::resetOffscreenDepthBuffer(int backbufferWidth, int backbuffe if (mDepthBufferFormat != GL_NONE) { - const d3d11::TextureFormat &depthBufferFormatInfo = - d3d11::GetTextureFormatInfo(mDepthBufferFormat, mRenderer->getRenderer11DeviceCaps()); + const d3d11::Format &depthBufferFormatInfo = + d3d11::Format::Get(mDepthBufferFormat, mRenderer->getRenderer11DeviceCaps()); D3D11_TEXTURE2D_DESC depthStencilTextureDesc; depthStencilTextureDesc.Width = backbufferWidth; depthStencilTextureDesc.Height = backbufferHeight; - depthStencilTextureDesc.Format = depthBufferFormatInfo.texFormat; + depthStencilTextureDesc.Format = depthBufferFormatInfo.texFormat; depthStencilTextureDesc.MipLevels = 1; depthStencilTextureDesc.ArraySize = 1; - depthStencilTextureDesc.SampleDesc.Count = 1; - depthStencilTextureDesc.SampleDesc.Quality = 0; + depthStencilTextureDesc.SampleDesc.Count = getD3DSamples(); depthStencilTextureDesc.Usage = D3D11_USAGE_DEFAULT; depthStencilTextureDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; - if (depthBufferFormatInfo.srvFormat != DXGI_FORMAT_UNKNOWN) + // If there is a multisampled offscreen color texture, the offscreen depth-stencil texture + // must also have the same quality value. + if (mOffscreenTexture.valid() && getD3DSamples() > 1) + { + D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; + mOffscreenTexture.getDesc(&offscreenTextureDesc); + depthStencilTextureDesc.SampleDesc.Quality = offscreenTextureDesc.SampleDesc.Quality; + } + else + { + depthStencilTextureDesc.SampleDesc.Quality = 0; + } + + // Only create an SRV if it is supported + bool depthStencilSRV = + depthBufferFormatInfo.srvFormat != DXGI_FORMAT_UNKNOWN && + (mRenderer->getRenderer11DeviceCaps().supportsMultisampledDepthStencilSRVs || + depthStencilTextureDesc.SampleDesc.Count <= 1); + if (depthStencilSRV) { depthStencilTextureDesc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; } @@ -358,58 +397,56 @@ EGLint SwapChain11::resetOffscreenDepthBuffer(int backbufferWidth, int backbuffe depthStencilTextureDesc.CPUAccessFlags = 0; depthStencilTextureDesc.MiscFlags = 0; - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result = - device->CreateTexture2D(&depthStencilTextureDesc, NULL, &mDepthStencilTexture); - if (FAILED(result)) + gl::Error err = mRenderer->allocateTexture(depthStencilTextureDesc, depthBufferFormatInfo, + &mDepthStencilTexture); + if (err.isError()) { - ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result); + ERR() << "Could not create depthstencil surface for new swap chain, " << err; release(); - - if (d3d11::isDeviceLostError(result)) - { - return EGL_CONTEXT_LOST; - } - else - { - return EGL_BAD_ALLOC; - } + return EGL_BAD_ALLOC; } - d3d11::SetDebugName(mDepthStencilTexture, "Offscreen depth stencil texture"); + mDepthStencilTexture.setDebugName("Offscreen depth stencil texture"); D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilDesc; - depthStencilDesc.Format = depthBufferFormatInfo.dsvFormat; - depthStencilDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + depthStencilDesc.Format = depthBufferFormatInfo.dsvFormat; + depthStencilDesc.ViewDimension = + (mEGLSamples <= 1) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS; depthStencilDesc.Flags = 0; depthStencilDesc.Texture2D.MipSlice = 0; - result = device->CreateDepthStencilView(mDepthStencilTexture, &depthStencilDesc, &mDepthStencilDSView); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mDepthStencilDSView, "Offscreen depth stencil view"); + err = mRenderer->allocateResource(depthStencilDesc, mDepthStencilTexture.get(), + &mDepthStencilDSView); + ASSERT(!err.isError()); + mDepthStencilDSView.setDebugName("Offscreen depth stencil view"); - if (depthBufferFormatInfo.srvFormat != DXGI_FORMAT_UNKNOWN) + if (depthStencilSRV) { D3D11_SHADER_RESOURCE_VIEW_DESC depthStencilSRVDesc; - depthStencilSRVDesc.Format = depthBufferFormatInfo.srvFormat; - depthStencilSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + depthStencilSRVDesc.Format = depthBufferFormatInfo.srvFormat; + depthStencilSRVDesc.ViewDimension = (mEGLSamples <= 1) + ? D3D11_SRV_DIMENSION_TEXTURE2D + : D3D11_SRV_DIMENSION_TEXTURE2DMS; depthStencilSRVDesc.Texture2D.MostDetailedMip = 0; depthStencilSRVDesc.Texture2D.MipLevels = static_cast(-1); - result = device->CreateShaderResourceView(mDepthStencilTexture, &depthStencilSRVDesc, &mDepthStencilSRView); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mDepthStencilSRView, "Offscreen depth stencil shader resource"); + err = mRenderer->allocateResource(depthStencilSRVDesc, mDepthStencilTexture.get(), + &mDepthStencilSRView); + ASSERT(!err.isError()); + mDepthStencilSRView.setDebugName("Offscreen depth stencil shader resource"); } } return EGL_SUCCESS; } -EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) +EGLint SwapChain11::resize(const gl::Context *context, + EGLint backbufferWidth, + EGLint backbufferHeight) { TRACE_EVENT0("gpu.angle", "SwapChain11::resize"); ID3D11Device *device = mRenderer->getDevice(); - if (device == NULL) + if (device == nullptr) { return EGL_BAD_ACCESS; } @@ -427,18 +464,19 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) } // Can only call resize if we have already created our swap buffer and resources - ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView && mBackBufferSRView); + ASSERT(mSwapChain && mBackBufferTexture.valid() && mBackBufferRTView.valid() && + mBackBufferSRView.valid()); - SafeRelease(mBackBufferTexture); - SafeRelease(mBackBufferRTView); - SafeRelease(mBackBufferSRView); + mBackBufferTexture.reset(); + mBackBufferRTView.reset(); + mBackBufferSRView.reset(); // Resize swap chain DXGI_SWAP_CHAIN_DESC desc; HRESULT result = mSwapChain->GetDesc(&desc); if (FAILED(result)) { - ERR("Error reading swap chain description: 0x%08X", result); + ERR() << "Error reading swap chain description, " << gl::FmtHR(result); release(); return EGL_BAD_ALLOC; } @@ -447,7 +485,7 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) if (FAILED(result)) { - ERR("Error resizing swap chain buffers: 0x%08X", result); + ERR() << "Error resizing swap chain buffers, " << gl::FmtHR(result); release(); if (d3d11::isDeviceLostError(result)) @@ -460,39 +498,64 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) } } - result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture); + ID3D11Texture2D *backbufferTexture = nullptr; + result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), + reinterpret_cast(&backbufferTexture)); ASSERT(SUCCEEDED(result)); if (SUCCEEDED(result)) { - d3d11::SetDebugName(mBackBufferTexture, "Back buffer texture"); - result = device->CreateRenderTargetView(mBackBufferTexture, NULL, &mBackBufferRTView); - ASSERT(SUCCEEDED(result)); - if (SUCCEEDED(result)) - { - d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target"); - } + const auto &format = + d3d11::Format::Get(mOffscreenRenderTargetFormat, mRenderer->getRenderer11DeviceCaps()); + mBackBufferTexture.set(backbufferTexture, format); + mBackBufferTexture.setDebugName("Back buffer texture"); - result = device->CreateShaderResourceView(mBackBufferTexture, nullptr, &mBackBufferSRView); - ASSERT(SUCCEEDED(result)); - if (SUCCEEDED(result)) - { - d3d11::SetDebugName(mBackBufferSRView, "Back buffer shader resource"); - } + gl::Error err = + mRenderer->allocateResourceNoDesc(mBackBufferTexture.get(), &mBackBufferRTView); + ASSERT(!err.isError()); + mBackBufferRTView.setDebugName("Back buffer render target"); + + err = mRenderer->allocateResourceNoDesc(mBackBufferTexture.get(), &mBackBufferSRView); + ASSERT(!err.isError()); + mBackBufferSRView.setDebugName("Back buffer shader resource"); } mFirstSwap = true; - return resetOffscreenBuffers(backbufferWidth, backbufferHeight); + return resetOffscreenBuffers(context, backbufferWidth, backbufferHeight); } DXGI_FORMAT SwapChain11::getSwapChainNativeFormat() const { // Return a render target format for offscreen rendering is supported by IDXGISwapChain. // MSDN https://msdn.microsoft.com/en-us/library/windows/desktop/bb173064(v=vs.85).aspx - return (mOffscreenRenderTargetFormat == GL_BGRA8_EXT) ? DXGI_FORMAT_B8G8R8A8_UNORM : DXGI_FORMAT_R8G8B8A8_UNORM; + switch (mOffscreenRenderTargetFormat) + { + case GL_RGBA8: + case GL_RGBA4: + case GL_RGB5_A1: + case GL_RGB8: + case GL_RGB565: + return DXGI_FORMAT_R8G8B8A8_UNORM; + + case GL_BGRA8_EXT: + return DXGI_FORMAT_B8G8R8A8_UNORM; + + case GL_RGB10_A2: + return DXGI_FORMAT_R10G10B10A2_UNORM; + + case GL_RGBA16F: + return DXGI_FORMAT_R16G16B16A16_FLOAT; + + default: + UNREACHABLE(); + return DXGI_FORMAT_UNKNOWN; + } } -EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval) +EGLint SwapChain11::reset(const gl::Context *context, + EGLint backbufferWidth, + EGLint backbufferHeight, + EGLint swapInterval) { mSwapInterval = static_cast(swapInterval); if (mSwapInterval > 4) @@ -505,25 +568,23 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap // If the swap chain already exists, just resize if (mSwapChain != nullptr) { - return resize(backbufferWidth, backbufferHeight); + return resize(context, backbufferWidth, backbufferHeight); } TRACE_EVENT0("gpu.angle", "SwapChain11::reset"); ID3D11Device *device = mRenderer->getDevice(); - if (device == NULL) + if (device == nullptr) { return EGL_BAD_ACCESS; } // Release specific resources to free up memory for the new render target, while the // old render target still exists for the purpose of preserving its contents. -#if defined(ANGLE_ENABLE_D3D11_1) SafeRelease(mSwapChain1); -#endif SafeRelease(mSwapChain); - SafeRelease(mBackBufferTexture); - SafeRelease(mBackBufferRTView); + mBackBufferTexture.reset(); + mBackBufferRTView.reset(); // EGL allows creating a surface with 0x0 dimension, however, DXGI does not like 0x0 swapchains if (backbufferWidth < 1 || backbufferHeight < 1) @@ -532,15 +593,16 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap return EGL_SUCCESS; } - if (mNativeWindow.getNativeWindow()) + if (mNativeWindow->getNativeWindow()) { - HRESULT result = mNativeWindow.createSwapChain(device, mRenderer->getDxgiFactory(), - getSwapChainNativeFormat(), - backbufferWidth, backbufferHeight, &mSwapChain); + HRESULT result = mNativeWindow->createSwapChain( + device, mRenderer->getDxgiFactory(), getSwapChainNativeFormat(), backbufferWidth, + backbufferHeight, getD3DSamples(), &mSwapChain); if (FAILED(result)) { - ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result); + ERR() << "Could not create additional swap chains or offscreen surfaces, " + << gl::FmtHR(result); release(); if (d3d11::isDeviceLostError(result)) @@ -555,27 +617,31 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap if (mRenderer->getRenderer11DeviceCaps().supportsDXGI1_2) { -#if defined(ANGLE_ENABLE_D3D11_1) mSwapChain1 = d3d11::DynamicCastComObject(mSwapChain); -#endif } - result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture); + ID3D11Texture2D *backbufferTex = nullptr; + result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), + reinterpret_cast(&backbufferTex)); ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mBackBufferTexture, "Back buffer texture"); + const auto &format = + d3d11::Format::Get(mOffscreenRenderTargetFormat, mRenderer->getRenderer11DeviceCaps()); + mBackBufferTexture.set(backbufferTex, format); + mBackBufferTexture.setDebugName("Back buffer texture"); - result = device->CreateRenderTargetView(mBackBufferTexture, NULL, &mBackBufferRTView); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target"); + gl::Error err = + mRenderer->allocateResourceNoDesc(mBackBufferTexture.get(), &mBackBufferRTView); + ASSERT(!err.isError()); + mBackBufferRTView.setDebugName("Back buffer render target"); - result = device->CreateShaderResourceView(mBackBufferTexture, nullptr, &mBackBufferSRView); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mBackBufferSRView, "Back buffer shader resource view"); + err = mRenderer->allocateResourceNoDesc(mBackBufferTexture.get(), &mBackBufferSRView); + ASSERT(!err.isError()); + mBackBufferSRView.setDebugName("Back buffer shader resource view"); } mFirstSwap = true; - return resetOffscreenBuffers(backbufferWidth, backbufferHeight); + return resetOffscreenBuffers(context, backbufferWidth, backbufferHeight); } void SwapChain11::initPassThroughResources() @@ -588,11 +654,11 @@ void SwapChain11::initPassThroughResources() TRACE_EVENT0("gpu.angle", "SwapChain11::initPassThroughResources"); ID3D11Device *device = mRenderer->getDevice(); - ASSERT(device != NULL); + ASSERT(device != nullptr); // Make sure our resources are all not allocated, when we create - ASSERT(mQuadVB == NULL && mPassThroughSampler == NULL); - ASSERT(mPassThroughIL == NULL && mPassThroughVS == NULL && mPassThroughPS == NULL); + ASSERT(!mQuadVB.valid() && !mPassThroughSampler.valid()); + ASSERT(!mPassThroughIL.valid() && !mPassThroughVS.valid() && !mPassThroughPS.valid()); D3D11_BUFFER_DESC vbDesc; vbDesc.ByteWidth = sizeof(d3d11::PositionTexCoordVertex) * 4; @@ -602,9 +668,9 @@ void SwapChain11::initPassThroughResources() vbDesc.MiscFlags = 0; vbDesc.StructureByteStride = 0; - HRESULT result = device->CreateBuffer(&vbDesc, NULL, &mQuadVB); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mQuadVB, "Swap chain quad vertex buffer"); + gl::Error err = mRenderer->allocateResource(vbDesc, &mQuadVB); + ASSERT(!err.isError()); + mQuadVB.setDebugName("Swap chain quad vertex buffer"); D3D11_SAMPLER_DESC samplerDesc; samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; @@ -621,9 +687,9 @@ void SwapChain11::initPassThroughResources() samplerDesc.MinLOD = 0; samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; - result = device->CreateSamplerState(&samplerDesc, &mPassThroughSampler); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mPassThroughSampler, "Swap chain pass through sampler"); + err = mRenderer->allocateResource(samplerDesc, &mPassThroughSampler); + ASSERT(!err.isError()); + mPassThroughSampler.setDebugName("Swap chain pass through sampler"); D3D11_INPUT_ELEMENT_DESC quadLayout[] = { @@ -631,17 +697,30 @@ void SwapChain11::initPassThroughResources() { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; - result = device->CreateInputLayout(quadLayout, 2, g_VS_Passthrough2D, sizeof(g_VS_Passthrough2D), &mPassThroughIL); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mPassThroughIL, "Swap chain pass through layout"); + InputElementArray quadElements(quadLayout); + ShaderData vertexShaderData(g_VS_Passthrough2D); - result = device->CreateVertexShader(g_VS_Passthrough2D, sizeof(g_VS_Passthrough2D), NULL, &mPassThroughVS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mPassThroughVS, "Swap chain pass through vertex shader"); + err = mRenderer->allocateResource(quadElements, &vertexShaderData, &mPassThroughIL); + ASSERT(!err.isError()); + mPassThroughIL.setDebugName("Swap chain pass through layout"); - result = device->CreatePixelShader(g_PS_PassthroughRGBA2D, sizeof(g_PS_PassthroughRGBA2D), NULL, &mPassThroughPS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mPassThroughPS, "Swap chain pass through pixel shader"); + err = mRenderer->allocateResource(vertexShaderData, &mPassThroughVS); + ASSERT(!err.isError()); + mPassThroughVS.setDebugName("Swap chain pass through vertex shader"); + + if (mEGLSamples <= 1) + { + ShaderData pixelShaderData(g_PS_PassthroughRGBA2D); + err = mRenderer->allocateResource(pixelShaderData, &mPassThroughPS); + } + else + { + ShaderData pixelShaderData(g_PS_PassthroughRGBA2DMS); + err = mRenderer->allocateResource(pixelShaderData, &mPassThroughPS); + } + + ASSERT(!err.isError()); + mPassThroughPS.setDebugName("Swap chain pass through pixel shader"); // Use the default rasterizer state but without culling D3D11_RASTERIZER_DESC rasterizerDesc; @@ -655,26 +734,31 @@ void SwapChain11::initPassThroughResources() rasterizerDesc.ScissorEnable = FALSE; rasterizerDesc.MultisampleEnable = FALSE; rasterizerDesc.AntialiasedLineEnable = FALSE; - result = device->CreateRasterizerState(&rasterizerDesc, &mPassThroughRS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mPassThroughRS, "Swap chain pass through rasterizer state"); + + err = mRenderer->allocateResource(rasterizerDesc, &mPassThroughRS); + ASSERT(!err.isError()); + mPassThroughRS.setDebugName("Swap chain pass through rasterizer state"); mPassThroughResourcesInit = true; } // parameters should be validated/clamped by caller -EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) +EGLint SwapChain11::swapRect(const gl::Context *context, + EGLint x, + EGLint y, + EGLint width, + EGLint height) { if (mNeedsOffscreenTexture) { - EGLint result = copyOffscreenToBackbuffer(x, y, width, height); + EGLint result = copyOffscreenToBackbuffer(context, x, y, width, height); if (result != EGL_SUCCESS) { return result; } } - EGLint result = present(x, y, width, height); + EGLint result = present(context, x, y, width, height); if (result != EGL_SUCCESS) { return result; @@ -685,7 +769,11 @@ EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) return EGL_SUCCESS; } -EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, EGLint height) +EGLint SwapChain11::copyOffscreenToBackbuffer(const gl::Context *context, + EGLint x, + EGLint y, + EGLint width, + EGLint height) { if (!mSwapChain) { @@ -698,7 +786,8 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, // Set vertices D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT result = deviceContext->Map(mQuadVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + HRESULT result = + deviceContext->Map(mQuadVB.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); if (FAILED(result)) { return EGL_BAD_ACCESS; @@ -716,7 +805,6 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, float v1 = y / float(height); float u2 = (x + width) / float(width); float v2 = (y + height) / float(height); - // Invert the quad vertices depending on the surface orientation. if ((mOrientation & EGL_SURFACE_ORIENTATION_INVERT_X_ANGLE) != 0) { @@ -732,60 +820,43 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v1); d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v2); - deviceContext->Unmap(mQuadVB, 0); + deviceContext->Unmap(mQuadVB.get(), 0); - static UINT stride = sizeof(d3d11::PositionTexCoordVertex); - static UINT startIdx = 0; - deviceContext->IASetVertexBuffers(0, 1, &mQuadVB, &stride, &startIdx); + StateManager11 *stateManager = mRenderer->getStateManager(); + + constexpr UINT stride = sizeof(d3d11::PositionTexCoordVertex); + stateManager->setSingleVertexBuffer(&mQuadVB, stride, 0); // Apply state - deviceContext->OMSetDepthStencilState(NULL, 0xFFFFFFFF); - - static const float blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; - deviceContext->OMSetBlendState(NULL, blendFactor, 0xFFFFFFF); - - deviceContext->RSSetState(mPassThroughRS); + stateManager->setDepthStencilState(nullptr, 0xFFFFFFFF); + stateManager->setSimpleBlendState(nullptr); + stateManager->setRasterizerState(&mPassThroughRS); // Apply shaders - deviceContext->IASetInputLayout(mPassThroughIL); - deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - deviceContext->VSSetShader(mPassThroughVS, NULL, 0); - deviceContext->PSSetShader(mPassThroughPS, NULL, 0); - deviceContext->GSSetShader(NULL, NULL, 0); + stateManager->setInputLayout(&mPassThroughIL); + stateManager->setPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + stateManager->setDrawShaders(&mPassThroughVS, nullptr, &mPassThroughPS); - // Apply render targets - mRenderer->setOneTimeRenderTarget(mBackBufferRTView); + // Apply render targets. Use the proxy context in display. + stateManager->setRenderTarget(mBackBufferRTView.get(), nullptr); // Set the viewport - D3D11_VIEWPORT viewport; - viewport.TopLeftX = 0; - viewport.TopLeftY = 0; - viewport.Width = static_cast(width); - viewport.Height = static_cast(height); - viewport.MinDepth = 0.0f; - viewport.MaxDepth = 1.0f; - deviceContext->RSSetViewports(1, &viewport); + stateManager->setSimpleViewport(mWidth, mHeight); // Apply textures - auto stateManager = mRenderer->getStateManager(); - stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, mOffscreenSRView); - deviceContext->PSSetSamplers(0, 1, &mPassThroughSampler); + stateManager->setSimplePixelTextureAndSampler(mOffscreenSRView, mPassThroughSampler); // Draw deviceContext->Draw(4, 0); - // Rendering to the swapchain is now complete. Now we can call Present(). - // Before that, we perform any cleanup on the D3D device. We do this before Present() to make sure the - // cleanup is caught under the current eglSwapBuffers() PIX/Graphics Diagnostics call rather than the next one. - stateManager->setShaderResource(gl::SAMPLER_PIXEL, 0, NULL); - - mRenderer->unapplyRenderTargets(); - mRenderer->markAllStateDirty(); - return EGL_SUCCESS; } -EGLint SwapChain11::present(EGLint x, EGLint y, EGLint width, EGLint height) +EGLint SwapChain11::present(const gl::Context *context, + EGLint x, + EGLint y, + EGLint width, + EGLint height) { if (!mSwapChain) { @@ -799,9 +870,9 @@ EGLint SwapChain11::present(EGLint x, EGLint y, EGLint width, EGLint height) HRESULT result = S_OK; -#if defined(ANGLE_ENABLE_D3D11_1) // Use IDXGISwapChain1::Present1 with a dirty rect if DXGI 1.2 is available. - if (mSwapChain1 != nullptr) + // Dirty rect present is not supported with a multisampled swapchain. + if (mSwapChain1 != nullptr && mEGLSamples <= 1) { if (mFirstSwap) { @@ -818,7 +889,6 @@ EGLint SwapChain11::present(EGLint x, EGLint y, EGLint width, EGLint height) } } else -#endif { result = mSwapChain->Present(swapInterval, 0); } @@ -826,60 +896,111 @@ EGLint SwapChain11::present(EGLint x, EGLint y, EGLint width, EGLint height) mFirstSwap = false; // Some swapping mechanisms such as DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL unbind the current render - // target. Mark it dirty. + // target. Mark it dirty. Use the proxy context in display since there is none available. mRenderer->getStateManager()->invalidateRenderTarget(); if (result == DXGI_ERROR_DEVICE_REMOVED) { - ERR("Present failed: the D3D11 device was removed: 0x%08X", - mRenderer->getDevice()->GetDeviceRemovedReason()); + ERR() << "Present failed: the D3D11 device was removed, " + << gl::FmtHR(mRenderer->getDevice()->GetDeviceRemovedReason()); return EGL_CONTEXT_LOST; } else if (result == DXGI_ERROR_DEVICE_RESET) { - ERR("Present failed: the D3D11 device was reset from a bad command."); + ERR() << "Present failed: the D3D11 device was reset from a bad command."; return EGL_CONTEXT_LOST; } else if (FAILED(result)) { - ERR("Present failed with error code 0x%08X", result); + ERR() << "Present failed with " << gl::FmtHR(result); } - mNativeWindow.commitChange(); + mNativeWindow->commitChange(); return EGL_SUCCESS; } -ID3D11Texture2D *SwapChain11::getOffscreenTexture() +const TextureHelper11 &SwapChain11::getOffscreenTexture() { return mNeedsOffscreenTexture ? mOffscreenTexture : mBackBufferTexture; } -ID3D11RenderTargetView *SwapChain11::getRenderTarget() +const d3d11::RenderTargetView &SwapChain11::getRenderTarget() { return mNeedsOffscreenTexture ? mOffscreenRTView : mBackBufferRTView; } -ID3D11ShaderResourceView *SwapChain11::getRenderTargetShaderResource() +const d3d11::SharedSRV &SwapChain11::getRenderTargetShaderResource() { - return mNeedsOffscreenTexture ? mOffscreenSRView : mBackBufferSRView; + if (!mNeedsOffscreenTexture) + { + ASSERT(mBackBufferSRView.valid()); + return mBackBufferSRView; + } + + if (!mNeedsOffscreenTextureCopy) + { + ASSERT(mOffscreenSRView.valid()); + return mOffscreenSRView; + } + + if (!mOffscreenTextureCopyForSRV.valid()) + { + const d3d11::Format &backbufferFormatInfo = + d3d11::Format::Get(mOffscreenRenderTargetFormat, mRenderer->getRenderer11DeviceCaps()); + + D3D11_TEXTURE2D_DESC offscreenCopyDesc; + mOffscreenTexture.getDesc(&offscreenCopyDesc); + + offscreenCopyDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + offscreenCopyDesc.MiscFlags = 0; + offscreenCopyDesc.CPUAccessFlags = 0; + gl::Error err = mRenderer->allocateTexture(offscreenCopyDesc, backbufferFormatInfo, + &mOffscreenTextureCopyForSRV); + ASSERT(!err.isError()); + mOffscreenTextureCopyForSRV.setDebugName("Offscreen back buffer copy for SRV"); + + D3D11_SHADER_RESOURCE_VIEW_DESC offscreenSRVDesc; + offscreenSRVDesc.Format = backbufferFormatInfo.srvFormat; + offscreenSRVDesc.ViewDimension = + (mEGLSamples <= 1) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS; + offscreenSRVDesc.Texture2D.MostDetailedMip = 0; + offscreenSRVDesc.Texture2D.MipLevels = static_cast(-1); + + err = mRenderer->allocateResource(offscreenSRVDesc, mOffscreenTextureCopyForSRV.get(), + &mOffscreenSRView); + ASSERT(!err.isError()); + mOffscreenSRView.setDebugName("Offscreen back buffer shader resource"); + } + + // Need to copy the offscreen texture into the shader-readable copy, since it's external and + // we don't know if the copy is up-to-date. This works around the problem we have when the app + // passes in a texture that isn't shader-readable. + mRenderer->getDeviceContext()->CopyResource(mOffscreenTextureCopyForSRV.get(), + mOffscreenTexture.get()); + return mOffscreenSRView; } -ID3D11DepthStencilView *SwapChain11::getDepthStencil() +const d3d11::DepthStencilView &SwapChain11::getDepthStencil() { return mDepthStencilDSView; } -ID3D11ShaderResourceView * SwapChain11::getDepthStencilShaderResource() +const d3d11::SharedSRV &SwapChain11::getDepthStencilShaderResource() { return mDepthStencilSRView; } -ID3D11Texture2D *SwapChain11::getDepthStencilTexture() +const TextureHelper11 &SwapChain11::getDepthStencilTexture() { return mDepthStencilTexture; } +void *SwapChain11::getKeyedMutex() +{ + return mKeyedMutex; +} + void SwapChain11::recreate() { // possibly should use this method instead of reset @@ -890,4 +1011,61 @@ void *rx::SwapChain11::getDevice() return mRenderer->getDevice(); } +RenderTargetD3D *SwapChain11::getColorRenderTarget() +{ + return &mColorRenderTarget; } + +RenderTargetD3D *SwapChain11::getDepthStencilRenderTarget() +{ + return &mDepthStencilRenderTarget; +} + +egl::Error SwapChain11::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) +{ + if (!mSwapChain) + { + return egl::EglNotInitialized() << "Swap chain uninitialized"; + } + + DXGI_FRAME_STATISTICS stats = {}; + HRESULT result = mSwapChain->GetFrameStatistics(&stats); + + if (FAILED(result)) + { + return egl::EglBadAlloc() << "Failed to get frame statistics, " << gl::FmtHR(result); + } + + // Conversion from DXGI_FRAME_STATISTICS to the output values: + // stats.SyncRefreshCount -> msc + // stats.PresentCount -> sbc + // stats.SyncQPCTime -> ust with conversion to microseconds via QueryPerformanceFrequency + *msc = stats.SyncRefreshCount; + *sbc = stats.PresentCount; + + LONGLONG syncQPCValue = stats.SyncQPCTime.QuadPart; + // If the QPC Value is below the overflow threshold, we proceed with + // simple multiply and divide. + if (syncQPCValue < kQPCOverflowThreshold) + { + *ust = syncQPCValue * kMicrosecondsPerSecond / mQPCFrequency; + } + else + { + // Otherwise, calculate microseconds in a round about manner to avoid + // overflow and precision issues. + int64_t wholeSeconds = syncQPCValue / mQPCFrequency; + int64_t leftoverTicks = syncQPCValue - (wholeSeconds * mQPCFrequency); + *ust = wholeSeconds * kMicrosecondsPerSecond + + leftoverTicks * kMicrosecondsPerSecond / mQPCFrequency; + } + + return egl::NoError(); +} + +UINT SwapChain11::getD3DSamples() const +{ + return (mEGLSamples == 0) ? 1 : mEGLSamples; +} + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h index adcd07adb0..eca068210b 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h @@ -16,39 +16,54 @@ namespace rx { class Renderer11; +class NativeWindow11; -class SwapChain11 : public SwapChainD3D +class SwapChain11 final : public SwapChainD3D { public: SwapChain11(Renderer11 *renderer, - NativeWindow nativeWindow, + NativeWindow11 *nativeWindow, HANDLE shareHandle, + IUnknown *d3dTexture, GLenum backBufferFormat, GLenum depthBufferFormat, - EGLint orientation); - virtual ~SwapChain11(); + EGLint orientation, + EGLint samples); + ~SwapChain11() override; - EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight); - virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval); - virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height); - virtual void recreate(); + EGLint resize(const gl::Context *context, + EGLint backbufferWidth, + EGLint backbufferHeight) override; + EGLint reset(const gl::Context *context, + EGLint backbufferWidth, + EGLint backbufferHeight, + EGLint swapInterval) override; + EGLint swapRect(const gl::Context *context, + EGLint x, + EGLint y, + EGLint width, + EGLint height) override; + void recreate() override; - RenderTargetD3D *getColorRenderTarget() override { return &mColorRenderTarget; } - RenderTargetD3D *getDepthStencilRenderTarget() override { return &mDepthStencilRenderTarget; } + RenderTargetD3D *getColorRenderTarget() override; + RenderTargetD3D *getDepthStencilRenderTarget() override; - virtual ID3D11Texture2D *getOffscreenTexture(); - virtual ID3D11RenderTargetView *getRenderTarget(); - virtual ID3D11ShaderResourceView *getRenderTargetShaderResource(); + const TextureHelper11 &getOffscreenTexture(); + const d3d11::RenderTargetView &getRenderTarget(); + const d3d11::SharedSRV &getRenderTargetShaderResource(); - virtual ID3D11Texture2D *getDepthStencilTexture(); - virtual ID3D11DepthStencilView *getDepthStencil(); - virtual ID3D11ShaderResourceView *getDepthStencilShaderResource(); + const TextureHelper11 &getDepthStencilTexture(); + const d3d11::DepthStencilView &getDepthStencil(); + const d3d11::SharedSRV &getDepthStencilShaderResource(); EGLint getWidth() const { return mWidth; } EGLint getHeight() const { return mHeight; } - void *getKeyedMutex() override { return mKeyedMutex; } + void *getKeyedMutex() override; + EGLint getSamples() const { return mEGLSamples; } - virtual void *getDevice(); + void *getDevice() override; + + egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override; private: void release(); @@ -56,14 +71,23 @@ class SwapChain11 : public SwapChainD3D void releaseOffscreenColorBuffer(); void releaseOffscreenDepthBuffer(); - EGLint resetOffscreenBuffers(int backbufferWidth, int backbufferHeight); - EGLint resetOffscreenColorBuffer(int backbufferWidth, int backbufferHeight); + EGLint resetOffscreenBuffers(const gl::Context *context, + int backbufferWidth, + int backbufferHeight); + EGLint resetOffscreenColorBuffer(const gl::Context *context, + int backbufferWidth, + int backbufferHeight); EGLint resetOffscreenDepthBuffer(int backbufferWidth, int backbufferHeight); DXGI_FORMAT getSwapChainNativeFormat() const; - EGLint copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, EGLint height); - EGLint present(EGLint x, EGLint y, EGLint width, EGLint height); + EGLint copyOffscreenToBackbuffer(const gl::Context *context, + EGLint x, + EGLint y, + EGLint width, + EGLint height); + EGLint present(const gl::Context *context, EGLint x, EGLint y, EGLint width, EGLint height); + UINT getD3DSamples() const; Renderer11 *mRenderer; EGLint mWidth; @@ -73,36 +97,41 @@ class SwapChain11 : public SwapChainD3D unsigned int mSwapInterval; bool mPassThroughResourcesInit; + NativeWindow11 *mNativeWindow; // Handler for the Window that the surface is created for. + bool mFirstSwap; - DXGISwapChain *mSwapChain; -#if defined(ANGLE_ENABLE_D3D11_1) + IDXGISwapChain *mSwapChain; IDXGISwapChain1 *mSwapChain1; -#endif IDXGIKeyedMutex *mKeyedMutex; - ID3D11Texture2D *mBackBufferTexture; - ID3D11RenderTargetView *mBackBufferRTView; - ID3D11ShaderResourceView *mBackBufferSRView; + TextureHelper11 mBackBufferTexture; + d3d11::RenderTargetView mBackBufferRTView; + d3d11::SharedSRV mBackBufferSRView; const bool mNeedsOffscreenTexture; - ID3D11Texture2D *mOffscreenTexture; - ID3D11RenderTargetView *mOffscreenRTView; - ID3D11ShaderResourceView *mOffscreenSRView; + TextureHelper11 mOffscreenTexture; + d3d11::RenderTargetView mOffscreenRTView; + d3d11::SharedSRV mOffscreenSRView; + bool mNeedsOffscreenTextureCopy; + TextureHelper11 mOffscreenTextureCopyForSRV; - ID3D11Texture2D *mDepthStencilTexture; - ID3D11DepthStencilView *mDepthStencilDSView; - ID3D11ShaderResourceView *mDepthStencilSRView; + TextureHelper11 mDepthStencilTexture; + d3d11::DepthStencilView mDepthStencilDSView; + d3d11::SharedSRV mDepthStencilSRView; - ID3D11Buffer *mQuadVB; - ID3D11SamplerState *mPassThroughSampler; - ID3D11InputLayout *mPassThroughIL; - ID3D11VertexShader *mPassThroughVS; - ID3D11PixelShader *mPassThroughPS; - ID3D11RasterizerState *mPassThroughRS; + d3d11::Buffer mQuadVB; + d3d11::SamplerState mPassThroughSampler; + d3d11::InputLayout mPassThroughIL; + d3d11::VertexShader mPassThroughVS; + d3d11::PixelShader mPassThroughPS; + d3d11::RasterizerState mPassThroughRS; SurfaceRenderTarget11 mColorRenderTarget; SurfaceRenderTarget11 mDepthStencilRenderTarget; + + EGLint mEGLSamples; + LONGLONG mQPCFrequency; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_D3D11_SWAPCHAIN11_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp index 11b9f76464..b702450ded 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp @@ -5,7 +5,8 @@ // // TextureStorage11.cpp: Implements the abstract rx::TextureStorage11 class and its concrete derived -// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture. +// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 +// texture. #include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h" @@ -21,6 +22,7 @@ #include "libANGLE/renderer/d3d/d3d11/Renderer11.h" #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" +#include "libANGLE/renderer/d3d/d3d11/StreamProducerNV12.h" #include "libANGLE/renderer/d3d/d3d11/SwapChain11.h" #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" #include "libANGLE/renderer/d3d/EGLImageD3D.h" @@ -29,82 +31,79 @@ namespace rx { -TextureStorage11::SwizzleCacheValue::SwizzleCacheValue() - : swizzleRed(GL_INVALID_INDEX), - swizzleGreen(GL_INVALID_INDEX), - swizzleBlue(GL_INVALID_INDEX), - swizzleAlpha(GL_INVALID_INDEX) +namespace { + +void InvalidateRenderTarget(const gl::Context *context, RenderTarget11 *renderTarget) +{ + if (renderTarget) + { + renderTarget->signalDirty(context); + } } -TextureStorage11::SwizzleCacheValue::SwizzleCacheValue(GLenum red, GLenum green, GLenum blue, GLenum alpha) - : swizzleRed(red), swizzleGreen(green), swizzleBlue(blue), swizzleAlpha(alpha) +RenderTarget11 *GetRenderTarget(std::unique_ptr *pointer) { + return pointer->get(); } -bool TextureStorage11::SwizzleCacheValue::operator==(const SwizzleCacheValue &other) const +template +RenderTarget11 *GetRenderTarget(std::pair> *pair) { - return swizzleRed == other.swizzleRed && - swizzleGreen == other.swizzleGreen && - swizzleBlue == other.swizzleBlue && - swizzleAlpha == other.swizzleAlpha; + return pair->second.get(); } -bool TextureStorage11::SwizzleCacheValue::operator!=(const SwizzleCacheValue &other) const +template +void InvalidateRenderTargetContainer(const gl::Context *context, T *renderTargetContainer) { - return !(*this == other); + for (auto &rt : *renderTargetContainer) + { + InvalidateRenderTarget(context, GetRenderTarget(&rt)); + } } -TextureStorage11::SRVKey::SRVKey(int baseLevel, int mipLevels, bool swizzle) - : baseLevel(baseLevel), mipLevels(mipLevels), swizzle(swizzle) +} // anonymous namespace + +TextureStorage11::SRVKey::SRVKey(int baseLevel, int mipLevels, bool swizzle, bool dropStencil) + : baseLevel(baseLevel), mipLevels(mipLevels), swizzle(swizzle), dropStencil(dropStencil) { } bool TextureStorage11::SRVKey::operator<(const SRVKey &rhs) const { - return std::tie(baseLevel, mipLevels, swizzle) < std::tie(rhs.baseLevel, rhs.mipLevels, rhs.swizzle); + return std::tie(baseLevel, mipLevels, swizzle, dropStencil) < + std::tie(rhs.baseLevel, rhs.mipLevels, rhs.swizzle, rhs.dropStencil); } -TextureStorage11::TextureStorage11(Renderer11 *renderer, UINT bindFlags, UINT miscFlags) +TextureStorage11::TextureStorage11(Renderer11 *renderer, + UINT bindFlags, + UINT miscFlags, + GLenum internalFormat) : mRenderer(renderer), mTopLevel(0), mMipLevels(0), - mInternalFormat(GL_NONE), - mTextureFormat(DXGI_FORMAT_UNKNOWN), - mShaderResourceFormat(DXGI_FORMAT_UNKNOWN), - mRenderTargetFormat(DXGI_FORMAT_UNKNOWN), - mDepthStencilFormat(DXGI_FORMAT_UNKNOWN), + mFormatInfo(d3d11::Format::Get(internalFormat, mRenderer->getRenderer11DeviceCaps())), mTextureWidth(0), mTextureHeight(0), mTextureDepth(0), + mDropStencilTexture(), mBindFlags(bindFlags), mMiscFlags(miscFlags) { - for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) - { - mLevelSRVs[i] = nullptr; - } } TextureStorage11::~TextureStorage11() { - for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) - { - SafeRelease(mLevelSRVs[level]); - } - - for (SRVCache::iterator i = mSrvCache.begin(); i != mSrvCache.end(); i++) - { - SafeRelease(i->second); - } mSrvCache.clear(); } -DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat, const Renderer11DeviceCaps &renderer11DeviceCaps, bool renderTarget) +DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat, + const Renderer11DeviceCaps &renderer11DeviceCaps, + bool renderTarget) { UINT bindFlags = 0; - const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat, renderer11DeviceCaps); + const d3d11::Format &formatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps); if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN) { bindFlags |= D3D11_BIND_SHADER_RESOURCE; @@ -121,16 +120,17 @@ DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat, const Rendere return bindFlags; } -DWORD TextureStorage11::GetTextureMiscFlags(GLenum internalFormat, const Renderer11DeviceCaps &renderer11DeviceCaps, bool renderTarget, int levels) +DWORD TextureStorage11::GetTextureMiscFlags(GLenum internalFormat, + const Renderer11DeviceCaps &renderer11DeviceCaps, + bool renderTarget, + int levels) { UINT miscFlags = 0; - const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat, renderer11DeviceCaps); + const d3d11::Format &formatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps); if (renderTarget && levels > 1) { - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(formatInfo.texFormat); - - if (dxgiFormatInfo.nativeMipmapSupport(renderer11DeviceCaps.featureLevel)) + if (d3d11::SupportsMipGen(formatInfo.texFormat, renderer11DeviceCaps.featureLevel)) { miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; } @@ -151,6 +151,8 @@ UINT TextureStorage11::getMiscFlags() const int TextureStorage11::getTopLevel() const { + // Applying top level is meant to be encapsulated inside TextureStorage11. + UNREACHABLE(); return mTopLevel; } @@ -189,24 +191,35 @@ int TextureStorage11::getLevelDepth(int mipLevel) const return std::max(static_cast(mTextureDepth) >> mipLevel, 1); } +gl::Error TextureStorage11::getMippedResource(const gl::Context *context, + const TextureHelper11 **outResource) +{ + return getResource(context, outResource); +} + UINT TextureStorage11::getSubresourceIndex(const gl::ImageIndex &index) const { - UINT mipSlice = static_cast(index.mipIndex + mTopLevel); - UINT arraySlice = static_cast(index.hasLayer() ? index.layerIndex : 0); + UINT mipSlice = static_cast(index.mipIndex + mTopLevel); + UINT arraySlice = static_cast(index.hasLayer() ? index.layerIndex : 0); UINT subresource = D3D11CalcSubresource(mipSlice, arraySlice, mMipLevels); ASSERT(subresource != std::numeric_limits::max()); return subresource; } -gl::Error TextureStorage11::getSRV(const gl::TextureState &textureState, - ID3D11ShaderResourceView **outSRV) +gl::Error TextureStorage11::getSRV(const gl::Context *context, + const gl::TextureState &textureState, + const d3d11::SharedSRV **outSRV) { - bool swizzleRequired = textureState.swizzleRequired(); - bool mipmapping = gl::IsMipmapFiltered(textureState.samplerState); - unsigned int mipLevels = mipmapping ? (textureState.maxLevel - textureState.baseLevel + 1) : 1; + // Make sure to add the level offset for our tiny compressed texture workaround + const GLuint effectiveBaseLevel = textureState.getEffectiveBaseLevel(); + bool swizzleRequired = textureState.swizzleRequired(); + bool mipmapping = gl::IsMipmapFiltered(textureState.getSamplerState()); + unsigned int mipLevels = + mipmapping ? (textureState.getEffectiveMaxLevel() - effectiveBaseLevel + 1) : 1; - // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level, which corresponds to GL level 0) - mipLevels = std::min(mipLevels, mMipLevels - mTopLevel - textureState.baseLevel); + // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level, + // which corresponds to GL level 0) + mipLevels = std::min(mipLevels, mMipLevels - mTopLevel - effectiveBaseLevel); if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) { @@ -217,89 +230,133 @@ gl::Error TextureStorage11::getSRV(const gl::TextureState &textureState, if (mRenderer->getWorkarounds().zeroMaxLodWorkaround) { // We must ensure that the level zero texture is in sync with mipped texture. - gl::Error error = useLevelZeroWorkaroundTexture(mipLevels == 1); - if (error.isError()) - { - return error; - } + ANGLE_TRY(useLevelZeroWorkaroundTexture(context, mipLevels == 1)); } if (swizzleRequired) { - verifySwizzleExists(textureState.swizzleRed, textureState.swizzleGreen, - textureState.swizzleBlue, textureState.swizzleAlpha); + verifySwizzleExists(textureState.getSwizzleState()); } - SRVKey key(textureState.baseLevel, mipLevels, swizzleRequired); + // We drop the stencil when sampling from the SRV if three conditions hold: + // 1. the drop stencil workaround is enabled. + bool workaround = mRenderer->getWorkarounds().emulateTinyStencilTextures; + // 2. this is a stencil texture. + bool hasStencil = (mFormatInfo.format().stencilBits > 0); + // 3. the texture has a 1x1 or 2x2 mip. + int effectiveTopLevel = effectiveBaseLevel + mipLevels - 1; + bool hasSmallMips = + (getLevelWidth(effectiveTopLevel) <= 2 || getLevelHeight(effectiveTopLevel) <= 2); + + bool useDropStencil = (workaround && hasStencil && hasSmallMips); + SRVKey key(effectiveBaseLevel, mipLevels, swizzleRequired, useDropStencil); + if (useDropStencil) + { + // Ensure drop texture gets created. + DropStencil result = DropStencil::CREATED; + ANGLE_TRY_RESULT(ensureDropStencilTexture(context), result); + + // Clear the SRV cache if necessary. + // TODO(jmadill): Re-use find query result. + auto srvEntry = mSrvCache.find(key); + if (result == DropStencil::CREATED && srvEntry != mSrvCache.end()) + { + mSrvCache.erase(key); + } + } + + ANGLE_TRY(getCachedOrCreateSRV(context, key, outSRV)); + + return gl::NoError(); +} + +gl::Error TextureStorage11::getCachedOrCreateSRV(const gl::Context *context, + const SRVKey &key, + const d3d11::SharedSRV **outSRV) +{ auto iter = mSrvCache.find(key); if (iter != mSrvCache.end()) { - *outSRV = iter->second; - return gl::Error(GL_NO_ERROR); + *outSRV = &iter->second; + return gl::NoError(); } - ID3D11Resource *texture = nullptr; - if (swizzleRequired) + const TextureHelper11 *texture = nullptr; + DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; + + if (key.swizzle) { - gl::Error error = getSwizzleTexture(&texture); - if (error.isError()) - { - return error; - } + const auto &swizzleFormat = + mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()); + ASSERT(!key.dropStencil || swizzleFormat.format().stencilBits == 0); + ANGLE_TRY(getSwizzleTexture(&texture)); + format = swizzleFormat.srvFormat; + } + else if (key.dropStencil) + { + ASSERT(mDropStencilTexture.valid()); + texture = &mDropStencilTexture; + format = DXGI_FORMAT_R32_FLOAT; } else { - gl::Error error = getResource(&texture); - if (error.isError()) - { - return error; - } + ANGLE_TRY(getResource(context, &texture)); + format = mFormatInfo.srvFormat; } - ID3D11ShaderResourceView *srv = nullptr; - DXGI_FORMAT format = (swizzleRequired ? mSwizzleShaderResourceFormat : mShaderResourceFormat); - gl::Error error = createSRV(textureState.baseLevel, mipLevels, format, texture, &srv); - if (error.isError()) - { - return error; - } + d3d11::SharedSRV srv; - mSrvCache.insert(std::make_pair(key, srv)); - *outSRV = srv; + ANGLE_TRY(createSRV(context, key.baseLevel, key.mipLevels, format, *texture, &srv)); - return gl::Error(GL_NO_ERROR); + const auto &insertIt = mSrvCache.insert(std::make_pair(key, std::move(srv))); + *outSRV = &insertIt.first->second; + + return gl::NoError(); } -gl::Error TextureStorage11::getSRVLevel(int mipLevel, ID3D11ShaderResourceView **outSRV) +gl::Error TextureStorage11::getSRVLevel(const gl::Context *context, + int mipLevel, + bool blitSRV, + const d3d11::SharedSRV **outSRV) { ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); - if (!mLevelSRVs[mipLevel]) - { - ID3D11Resource *resource = NULL; - gl::Error error = getResource(&resource); - if (error.isError()) - { - return error; - } + auto &levelSRVs = (blitSRV) ? mLevelBlitSRVs : mLevelSRVs; + auto &otherLevelSRVs = (blitSRV) ? mLevelSRVs : mLevelBlitSRVs; - error = createSRV(mipLevel, 1, mShaderResourceFormat, resource, &mLevelSRVs[mipLevel]); - if (error.isError()) + if (!levelSRVs[mipLevel].valid()) + { + // Only create a different SRV for blit if blit format is different from regular srv format + if (otherLevelSRVs[mipLevel].valid() && mFormatInfo.srvFormat == mFormatInfo.blitSRVFormat) { - return error; + levelSRVs[mipLevel] = otherLevelSRVs[mipLevel].makeCopy(); + } + else + { + const TextureHelper11 *resource = nullptr; + ANGLE_TRY(getResource(context, &resource)); + + DXGI_FORMAT resourceFormat = + blitSRV ? mFormatInfo.blitSRVFormat : mFormatInfo.srvFormat; + ANGLE_TRY( + createSRV(context, mipLevel, 1, resourceFormat, *resource, &levelSRVs[mipLevel])); } } - *outSRV = mLevelSRVs[mipLevel]; + *outSRV = &levelSRVs[mipLevel]; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage11::getSRVLevels(GLint baseLevel, GLint maxLevel, ID3D11ShaderResourceView **outSRV) +gl::Error TextureStorage11::getSRVLevels(const gl::Context *context, + GLint baseLevel, + GLint maxLevel, + const d3d11::SharedSRV **outSRV) { unsigned int mipLevels = maxLevel - baseLevel + 1; - // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level, which corresponds to GL level 0) + // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level, + // which corresponds to GL level 0) mipLevels = std::min(mipLevels, mMipLevels - mTopLevel - baseLevel); if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) @@ -310,245 +367,218 @@ gl::Error TextureStorage11::getSRVLevels(GLint baseLevel, GLint maxLevel, ID3D11 if (mRenderer->getWorkarounds().zeroMaxLodWorkaround) { // We must ensure that the level zero texture is in sync with mipped texture. - gl::Error error = useLevelZeroWorkaroundTexture(mipLevels == 1); - if (error.isError()) - { - return error; - } + ANGLE_TRY(useLevelZeroWorkaroundTexture(context, mipLevels == 1)); } - SRVKey key(baseLevel, mipLevels, false); - auto iter = mSrvCache.find(key); - if (iter != mSrvCache.end()) - { - *outSRV = iter->second; - return gl::Error(GL_NO_ERROR); - } + // TODO(jmadill): Assert we don't need to drop stencil. - ID3D11Resource *texture = nullptr; - gl::Error error = getResource(&texture); - if (error.isError()) - { - return error; - } + SRVKey key(baseLevel, mipLevels, false, false); + ANGLE_TRY(getCachedOrCreateSRV(context, key, outSRV)); - ID3D11ShaderResourceView *srv = nullptr; - error = createSRV(baseLevel, mipLevels, mShaderResourceFormat, texture, &srv); - if (error.isError()) - { - return error; - } - - mSrvCache[key] = srv; - *outSRV = srv; - - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage11::generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha) +const d3d11::Format &TextureStorage11::getFormatSet() const +{ + return mFormatInfo; +} + +gl::Error TextureStorage11::generateSwizzles(const gl::Context *context, + const gl::SwizzleState &swizzleTarget) { - SwizzleCacheValue swizzleTarget(swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha); for (int level = 0; level < getLevelCount(); level++) { // Check if the swizzle for this level is out of date if (mSwizzleCache[level] != swizzleTarget) { // Need to re-render the swizzle for this level - ID3D11ShaderResourceView *sourceSRV = NULL; - gl::Error error = getSRVLevel(level, &sourceSRV); - if (error.isError()) - { - return error; - } + const d3d11::SharedSRV *sourceSRV = nullptr; + ANGLE_TRY(getSRVLevel(context, level, true, &sourceSRV)); - ID3D11RenderTargetView *destRTV = NULL; - error = getSwizzleRenderTarget(level, &destRTV); - if (error.isError()) - { - return error; - } + const d3d11::RenderTargetView *destRTV; + ANGLE_TRY(getSwizzleRenderTarget(level, &destRTV)); gl::Extents size(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level)); Blit11 *blitter = mRenderer->getBlitter(); - error = blitter->swizzleTexture(sourceSRV, destRTV, size, swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha); - if (error.isError()) - { - return error; - } + ANGLE_TRY(blitter->swizzleTexture(context, *sourceSRV, *destRTV, size, swizzleTarget)); mSwizzleCache[level] = swizzleTarget; } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -void TextureStorage11::invalidateSwizzleCacheLevel(int mipLevel) +void TextureStorage11::markLevelDirty(int mipLevel) { - if (mipLevel >= 0 && static_cast(mipLevel) < ArraySize(mSwizzleCache)) + if (mipLevel >= 0 && static_cast(mipLevel) < mSwizzleCache.size()) { - // The default constructor of SwizzleCacheValue has GL_NONE for all channels which is not a - // valid swizzle combination - mSwizzleCache[mipLevel] = SwizzleCacheValue(); + // The default constructor of SwizzleState has GL_INVALID_INDEX for all channels which is + // not a valid swizzle combination + if (mSwizzleCache[mipLevel] != gl::SwizzleState()) + { + // TODO(jmadill): Invalidate specific swizzle. + mRenderer->getStateManager()->invalidateSwizzles(); + mSwizzleCache[mipLevel] = gl::SwizzleState(); + } + } + + if (mDropStencilTexture.valid()) + { + mDropStencilTexture.reset(); } } -void TextureStorage11::invalidateSwizzleCache() +void TextureStorage11::markDirty() { - for (unsigned int mipLevel = 0; mipLevel < ArraySize(mSwizzleCache); mipLevel++) + for (size_t mipLevel = 0; mipLevel < mSwizzleCache.size(); ++mipLevel) { - invalidateSwizzleCacheLevel(mipLevel); + markLevelDirty(static_cast(mipLevel)); } } -gl::Error TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, unsigned int sourceSubresource, - const gl::ImageIndex &index, const gl::Box ©Area) +gl::Error TextureStorage11::updateSubresourceLevel(const gl::Context *context, + const TextureHelper11 &srcTexture, + unsigned int sourceSubresource, + const gl::ImageIndex &index, + const gl::Box ©Area) { - ASSERT(srcTexture); + ASSERT(srcTexture.valid()); - GLint level = index.mipIndex; + const GLint level = index.mipIndex; - invalidateSwizzleCacheLevel(level); + markLevelDirty(level); gl::Extents texSize(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level)); - bool fullCopy = copyArea.x == 0 && - copyArea.y == 0 && - copyArea.z == 0 && - copyArea.width == texSize.width && - copyArea.height == texSize.height && - copyArea.depth == texSize.depth; + bool fullCopy = copyArea.x == 0 && copyArea.y == 0 && copyArea.z == 0 && + copyArea.width == texSize.width && copyArea.height == texSize.height && + copyArea.depth == texSize.depth; - ID3D11Resource *dstTexture = NULL; - gl::Error error(GL_NO_ERROR); + const TextureHelper11 *dstTexture = nullptr; - // If the zero-LOD workaround is active and we want to update a level greater than zero, then we should - // update the mipmapped texture, even if mapmaps are currently disabled. + // If the zero-LOD workaround is active and we want to update a level greater than zero, then we + // should update the mipmapped texture, even if mapmaps are currently disabled. if (index.mipIndex > 0 && mRenderer->getWorkarounds().zeroMaxLodWorkaround) { - error = getMippedResource(&dstTexture); + ANGLE_TRY(getMippedResource(context, &dstTexture)); } else { - error = getResource(&dstTexture); - } - - if (error.isError()) - { - return error; + ANGLE_TRY(getResource(context, &dstTexture)); } unsigned int dstSubresource = getSubresourceIndex(index); - ASSERT(dstTexture); + ASSERT(dstTexture->valid()); - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat); - if (!fullCopy && (dxgiFormatInfo.depthBits > 0 || dxgiFormatInfo.stencilBits > 0)) + const d3d11::DXGIFormatSize &dxgiFormatSizeInfo = + d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat); + if (!fullCopy && mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN) { // CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead - Blit11 *blitter = mRenderer->getBlitter(); - + Blit11 *blitter = mRenderer->getBlitter(); return blitter->copyDepthStencil(srcTexture, sourceSubresource, copyArea, texSize, - dstTexture, dstSubresource, copyArea, texSize, - NULL); + *dstTexture, dstSubresource, copyArea, texSize, nullptr); } - else - { - D3D11_BOX srcBox; - srcBox.left = copyArea.x; - srcBox.top = copyArea.y; - srcBox.right = copyArea.x + roundUp(static_cast(copyArea.width), dxgiFormatInfo.blockWidth); - srcBox.bottom = copyArea.y + roundUp(static_cast(copyArea.height), dxgiFormatInfo.blockHeight); - srcBox.front = copyArea.z; - srcBox.back = copyArea.z + copyArea.depth; - ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + D3D11_BOX srcBox; + srcBox.left = copyArea.x; + srcBox.top = copyArea.y; + srcBox.right = + copyArea.x + roundUp(static_cast(copyArea.width), dxgiFormatSizeInfo.blockWidth); + srcBox.bottom = + copyArea.y + roundUp(static_cast(copyArea.height), dxgiFormatSizeInfo.blockHeight); + srcBox.front = copyArea.z; + srcBox.back = copyArea.z + copyArea.depth; - context->CopySubresourceRegion(dstTexture, dstSubresource, copyArea.x, copyArea.y, copyArea.z, - srcTexture, sourceSubresource, fullCopy ? NULL : &srcBox); - return gl::Error(GL_NO_ERROR); - } + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + deviceContext->CopySubresourceRegion(dstTexture->get(), dstSubresource, copyArea.x, copyArea.y, + copyArea.z, srcTexture.get(), sourceSubresource, + fullCopy ? nullptr : &srcBox); + return gl::NoError(); } -gl::Error TextureStorage11::copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource, - const gl::ImageIndex &index, const gl::Box ®ion) +gl::Error TextureStorage11::copySubresourceLevel(const gl::Context *context, + const TextureHelper11 &dstTexture, + unsigned int dstSubresource, + const gl::ImageIndex &index, + const gl::Box ®ion) { - ASSERT(dstTexture); + ASSERT(dstTexture.valid()); - ID3D11Resource *srcTexture = NULL; - gl::Error error(GL_NO_ERROR); + const TextureHelper11 *srcTexture = nullptr; - // If the zero-LOD workaround is active and we want to update a level greater than zero, then we should - // update the mipmapped texture, even if mapmaps are currently disabled. + // If the zero-LOD workaround is active and we want to update a level greater than zero, then we + // should update the mipmapped texture, even if mapmaps are currently disabled. if (index.mipIndex > 0 && mRenderer->getWorkarounds().zeroMaxLodWorkaround) { - error = getMippedResource(&srcTexture); + ANGLE_TRY(getMippedResource(context, &srcTexture)); } else { - error = getResource(&srcTexture); + ANGLE_TRY(getResource(context, &srcTexture)); } - if (error.isError()) - { - return error; - } - - ASSERT(srcTexture); + ASSERT(srcTexture->valid()); unsigned int srcSubresource = getSubresourceIndex(index); - ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); - // D3D11 can't perform partial CopySubresourceRegion on depth/stencil textures, so pSrcBox should be NULL. + // D3D11 can't perform partial CopySubresourceRegion on depth/stencil textures, so pSrcBox + // should be nullptr. D3D11_BOX srcBox; - D3D11_BOX *pSrcBox = NULL; + D3D11_BOX *pSrcBox = nullptr; if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) { - // However, D3D10Level9 doesn't always perform CopySubresourceRegion correctly unless the source box - // is specified. This is okay, since we don't perform CopySubresourceRegion on depth/stencil - // textures on 9_3. - ASSERT(d3d11::GetDXGIFormatInfo(mTextureFormat).depthBits == 0); - ASSERT(d3d11::GetDXGIFormatInfo(mTextureFormat).stencilBits == 0); - srcBox.left = region.x; - srcBox.right = region.x + region.width; - srcBox.top = region.y; - srcBox.bottom = region.y + region.height; - srcBox.front = region.z; - srcBox.back = region.z + region.depth; - pSrcBox = &srcBox; + GLsizei width = region.width; + GLsizei height = region.height; + d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, nullptr); + + // Keep srcbox as nullptr if we're dealing with tiny mips of compressed textures. + if (width == region.width && height == region.height) + { + // However, D3D10Level9 doesn't always perform CopySubresourceRegion correctly unless + // the source box is specified. This is okay, since we don't perform + // CopySubresourceRegion on depth/stencil textures on 9_3. + ASSERT(mFormatInfo.dsvFormat == DXGI_FORMAT_UNKNOWN); + srcBox.left = region.x; + srcBox.right = region.x + region.width; + srcBox.top = region.y; + srcBox.bottom = region.y + region.height; + srcBox.front = region.z; + srcBox.back = region.z + region.depth; + pSrcBox = &srcBox; + } } - context->CopySubresourceRegion(dstTexture, dstSubresource, region.x, region.y, region.z, - srcTexture, srcSubresource, pSrcBox); + deviceContext->CopySubresourceRegion(dstTexture.get(), dstSubresource, region.x, region.y, + region.z, srcTexture->get(), srcSubresource, pSrcBox); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage11::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) +gl::Error TextureStorage11::generateMipmap(const gl::Context *context, + const gl::ImageIndex &sourceIndex, + const gl::ImageIndex &destIndex) { ASSERT(sourceIndex.layerIndex == destIndex.layerIndex); - invalidateSwizzleCacheLevel(destIndex.mipIndex); + markLevelDirty(destIndex.mipIndex); - RenderTargetD3D *source = NULL; - gl::Error error = getRenderTarget(sourceIndex, &source); - if (error.isError()) - { - return error; - } + RenderTargetD3D *source = nullptr; + ANGLE_TRY(getRenderTarget(context, sourceIndex, &source)); - RenderTargetD3D *dest = NULL; - error = getRenderTarget(destIndex, &dest); - if (error.isError()) - { - return error; - } + RenderTargetD3D *dest = nullptr; + ANGLE_TRY(getRenderTarget(context, destIndex, &dest)); - ID3D11ShaderResourceView *sourceSRV = GetAs(source)->getShaderResourceView(); - ID3D11RenderTargetView *destRTV = GetAs(dest)->getRenderTargetView(); + RenderTarget11 *rt11 = GetAs(source); + const d3d11::SharedSRV &sourceSRV = rt11->getBlitShaderResourceView(); + const d3d11::RenderTargetView &destRTV = rt11->getRenderTargetView(); gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth()); gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth()); @@ -557,90 +587,75 @@ gl::Error TextureStorage11::generateMipmap(const gl::ImageIndex &sourceIndex, co gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth()); Blit11 *blitter = mRenderer->getBlitter(); - return blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize, - NULL, gl::GetInternalFormatInfo(source->getInternalFormat()).format, - GL_LINEAR, false); + GLenum format = gl::GetUnsizedFormat(source->getInternalFormat()); + return blitter->copyTexture(context, sourceSRV, sourceArea, sourceSize, format, destRTV, + destArea, destSize, nullptr, format, GL_LINEAR, false, false, + false); } -void TextureStorage11::verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha) +void TextureStorage11::verifySwizzleExists(const gl::SwizzleState &swizzleState) { - SwizzleCacheValue swizzleTarget(swizzleRed, swizzleGreen, swizzleBlue, swizzleAlpha); for (unsigned int level = 0; level < mMipLevels; level++) { - ASSERT(mSwizzleCache[level] == swizzleTarget); + ASSERT(mSwizzleCache[level] == swizzleState); } } void TextureStorage11::clearSRVCache() { - invalidateSwizzleCache(); + markDirty(); + mSrvCache.clear(); - auto iter = mSrvCache.begin(); - while (iter != mSrvCache.end()) + for (size_t level = 0; level < mLevelSRVs.size(); level++) { - if (!iter->first.swizzle) - { - SafeRelease(iter->second); - iter = mSrvCache.erase(iter); - } - else - { - iter++; - } - } - - for (size_t level = 0; level < ArraySize(mLevelSRVs); level++) - { - SafeRelease(mLevelSRVs[level]); + mLevelSRVs[level].reset(); + mLevelBlitSRVs[level].reset(); } } -gl::Error TextureStorage11::copyToStorage(TextureStorage *destStorage) +gl::Error TextureStorage11::copyToStorage(const gl::Context *context, TextureStorage *destStorage) { ASSERT(destStorage); - ID3D11Resource *sourceResouce = NULL; - gl::Error error = getResource(&sourceResouce); - if (error.isError()) - { - return error; - } + const TextureHelper11 *sourceResouce = nullptr; + ANGLE_TRY(getResource(context, &sourceResouce)); - TextureStorage11 *dest11 = GetAs(destStorage); - ID3D11Resource *destResource = NULL; - error = dest11->getResource(&destResource); - if (error.isError()) - { - return error; - } + TextureStorage11 *dest11 = GetAs(destStorage); + const TextureHelper11 *destResource = nullptr; + ANGLE_TRY(dest11->getResource(context, &destResource)); ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); - immediateContext->CopyResource(destResource, sourceResouce); + immediateContext->CopyResource(destResource->get(), sourceResouce->get()); - dest11->invalidateSwizzleCache(); + dest11->markDirty(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage11::setData(const gl::ImageIndex &index, ImageD3D *image, const gl::Box *destBox, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixelData) +gl::Error TextureStorage11::setData(const gl::Context *context, + const gl::ImageIndex &index, + ImageD3D *image, + const gl::Box *destBox, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixelData) { ASSERT(!image->isDirty()); - ID3D11Resource *resource = NULL; - gl::Error error = getResource(&resource); - if (error.isError()) - { - return error; - } - ASSERT(resource); + markLevelDirty(index.mipIndex); + + const TextureHelper11 *resource = nullptr; + ANGLE_TRY(getResource(context, &resource)); + ASSERT(resource && resource->valid()); UINT destSubresource = getSubresourceIndex(index); - const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(image->getInternalFormat()); + const gl::InternalFormat &internalFormatInfo = + gl::GetInternalFormatInfo(image->getInternalFormat(), type); - gl::Box levelBox(0, 0, 0, getLevelWidth(index.mipIndex), getLevelHeight(index.mipIndex), getLevelDepth(index.mipIndex)); - bool fullUpdate = (destBox == NULL || *destBox == levelBox); + gl::Box levelBox(0, 0, 0, getLevelWidth(index.mipIndex), getLevelHeight(index.mipIndex), + getLevelDepth(index.mipIndex)); + bool fullUpdate = (destBox == nullptr || *destBox == levelBox); ASSERT(internalFormatInfo.depthBits == 0 || fullUpdate); // TODO(jmadill): Handle compressed formats @@ -649,36 +664,44 @@ gl::Error TextureStorage11::setData(const gl::ImageIndex &index, ImageD3D *image // with compressed formats in the calling logic. ASSERT(!internalFormatInfo.compressed); - int width = destBox ? destBox->width : static_cast(image->getWidth()); - int height = destBox ? destBox->height : static_cast(image->getHeight()); - int depth = destBox ? destBox->depth : static_cast(image->getDepth()); - UINT srcRowPitch = internalFormatInfo.computeRowPitch(type, width, unpack.alignment, unpack.rowLength); - UINT srcDepthPitch = internalFormatInfo.computeDepthPitch(type, width, height, unpack.alignment, - unpack.rowLength, unpack.imageHeight); - GLsizei srcSkipBytes = internalFormatInfo.computeSkipPixels( - srcRowPitch, srcDepthPitch, unpack.skipImages, unpack.skipRows, unpack.skipPixels); + const int imageWidth = static_cast(image->getWidth()); + const int width = destBox ? destBox->width : imageWidth; + const int imageHeight = static_cast(image->getHeight()); + const int height = destBox ? destBox->height : imageHeight; + const int imageDepth = static_cast(image->getDepth()); + const int depth = destBox ? destBox->depth : imageDepth; + if (imageWidth < width || imageHeight < height || imageDepth < depth) + fullUpdate = true; + GLuint srcRowPitch = 0; + ANGLE_TRY_RESULT( + internalFormatInfo.computeRowPitch(type, width, unpack.alignment, unpack.rowLength), + srcRowPitch); + GLuint srcDepthPitch = 0; + ANGLE_TRY_RESULT(internalFormatInfo.computeDepthPitch(height, unpack.imageHeight, srcRowPitch), + srcDepthPitch); + GLuint srcSkipBytes = 0; + ANGLE_TRY_RESULT( + internalFormatInfo.computeSkipBytes(srcRowPitch, srcDepthPitch, unpack, index.is3D()), + srcSkipBytes); - const d3d11::TextureFormat &d3d11Format = d3d11::GetTextureFormatInfo(image->getInternalFormat(), mRenderer->getRenderer11DeviceCaps()); - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3d11Format.texFormat); + const d3d11::Format &d3d11Format = + d3d11::Format::Get(image->getInternalFormat(), mRenderer->getRenderer11DeviceCaps()); + const d3d11::DXGIFormatSize &dxgiFormatInfo = + d3d11::GetDXGIFormatSizeInfo(d3d11Format.texFormat); - size_t outputPixelSize = dxgiFormatInfo.pixelBytes; + const size_t outputPixelSize = dxgiFormatInfo.pixelBytes; UINT bufferRowPitch = static_cast(outputPixelSize) * width; UINT bufferDepthPitch = bufferRowPitch * height; - size_t neededSize = bufferDepthPitch * depth; - MemoryBuffer *conversionBuffer = nullptr; + const size_t neededSize = bufferDepthPitch * depth; + angle::MemoryBuffer *conversionBuffer = nullptr; const uint8_t *data = nullptr; - d3d11::LoadImageFunctionInfo loadFunctionInfo = d3d11Format.loadFunctions.at(type); + LoadImageFunctionInfo loadFunctionInfo = d3d11Format.getLoadFunctions()(type); if (loadFunctionInfo.requiresConversion) { - error = mRenderer->getScratchMemoryBuffer(neededSize, &conversionBuffer); - if (error.isError()) - { - return error; - } - + ANGLE_TRY(mRenderer->getScratchMemoryBuffer(neededSize, &conversionBuffer)); loadFunctionInfo.loadFunction(width, height, depth, pixelData + srcSkipBytes, srcRowPitch, srcDepthPitch, conversionBuffer->data(), bufferRowPitch, bufferDepthPitch); @@ -698,264 +721,233 @@ gl::Error TextureStorage11::setData(const gl::ImageIndex &index, ImageD3D *image ASSERT(destBox); D3D11_BOX destD3DBox; - destD3DBox.left = destBox->x; - destD3DBox.right = destBox->x + destBox->width; - destD3DBox.top = destBox->y; + destD3DBox.left = destBox->x; + destD3DBox.right = destBox->x + destBox->width; + destD3DBox.top = destBox->y; destD3DBox.bottom = destBox->y + destBox->height; - destD3DBox.front = destBox->z; - destD3DBox.back = destBox->z + destBox->depth; + destD3DBox.front = destBox->z; + destD3DBox.back = destBox->z + destBox->depth; - immediateContext->UpdateSubresource(resource, destSubresource, &destD3DBox, data, + immediateContext->UpdateSubresource(resource->get(), destSubresource, &destD3DBox, data, bufferRowPitch, bufferDepthPitch); } else { - immediateContext->UpdateSubresource(resource, destSubresource, NULL, data, bufferRowPitch, - bufferDepthPitch); + immediateContext->UpdateSubresource(resource->get(), destSubresource, nullptr, data, + bufferRowPitch, bufferDepthPitch); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); +} + +gl::ErrorOrResult TextureStorage11::ensureDropStencilTexture( + const gl::Context *context) +{ + UNIMPLEMENTED(); + return gl::InternalError() << "Drop stencil texture not implemented."; } TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swapchain) - : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, 0), + : TextureStorage11(renderer, + D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, + 0, + swapchain->getRenderTargetInternalFormat()), mTexture(swapchain->getOffscreenTexture()), - mLevelZeroTexture(NULL), - mLevelZeroRenderTarget(NULL), + mLevelZeroTexture(), + mLevelZeroRenderTarget(nullptr), mUseLevelZeroTexture(false), - mSwizzleTexture(NULL) + mSwizzleTexture() { - mTexture->AddRef(); - for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) { - mAssociatedImages[i] = NULL; - mRenderTarget[i] = NULL; - mSwizzleRenderTargets[i] = NULL; + mAssociatedImages[i] = nullptr; + mRenderTarget[i] = nullptr; } D3D11_TEXTURE2D_DESC texDesc; - mTexture->GetDesc(&texDesc); - mMipLevels = texDesc.MipLevels; - mTextureFormat = texDesc.Format; - mTextureWidth = texDesc.Width; + mTexture.getDesc(&texDesc); + mMipLevels = texDesc.MipLevels; + mTextureWidth = texDesc.Width; mTextureHeight = texDesc.Height; - mTextureDepth = 1; - - mInternalFormat = swapchain->GetRenderTargetInternalFormat(); - - ID3D11ShaderResourceView *srv = swapchain->getRenderTargetShaderResource(); - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srv->GetDesc(&srvDesc); - mShaderResourceFormat = srvDesc.Format; - - ID3D11RenderTargetView* offscreenRTV = swapchain->getRenderTarget(); - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - offscreenRTV->GetDesc(&rtvDesc); - mRenderTargetFormat = rtvDesc.Format; - - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat); - const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(dxgiFormatInfo.internalFormat, mRenderer->getRenderer11DeviceCaps()); - mSwizzleTextureFormat = formatInfo.swizzleTexFormat; - mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat; - mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat; - - mDepthStencilFormat = DXGI_FORMAT_UNKNOWN; + mTextureDepth = 1; + mHasKeyedMutex = (texDesc.MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) != 0; } -TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly) - : TextureStorage11(renderer, - GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget), - GetTextureMiscFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget, levels)), - mTexture(NULL), - mLevelZeroTexture(NULL), - mLevelZeroRenderTarget(NULL), - mUseLevelZeroTexture(false), - mSwizzleTexture(NULL) +TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, + GLenum internalformat, + bool renderTarget, + GLsizei width, + GLsizei height, + int levels, + bool hintLevelZeroOnly) + : TextureStorage11( + renderer, + GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget), + GetTextureMiscFlags(internalformat, + renderer->getRenderer11DeviceCaps(), + renderTarget, + levels), + internalformat), + mTexture(), + mHasKeyedMutex(false), + mLevelZeroTexture(), + mLevelZeroRenderTarget(nullptr), + mUseLevelZeroTexture(hintLevelZeroOnly && levels > 1), + mSwizzleTexture() { for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) { - mAssociatedImages[i] = NULL; - mRenderTarget[i] = NULL; - mSwizzleRenderTargets[i] = NULL; + mAssociatedImages[i] = nullptr; + mRenderTarget[i] = nullptr; } - mInternalFormat = internalformat; - - const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat, renderer->getRenderer11DeviceCaps()); - mTextureFormat = formatInfo.texFormat; - mShaderResourceFormat = formatInfo.srvFormat; - mDepthStencilFormat = formatInfo.dsvFormat; - mRenderTargetFormat = formatInfo.rtvFormat; - mSwizzleTextureFormat = formatInfo.swizzleTexFormat; - mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat; - mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat; - - d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel); - mMipLevels = mTopLevel + levels; - mTextureWidth = width; + d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, &mTopLevel); + mMipLevels = mTopLevel + levels; + mTextureWidth = width; mTextureHeight = height; - mTextureDepth = 1; + mTextureDepth = 1; - if (hintLevelZeroOnly && levels > 1) + // The LevelZeroOnly hint should only be true if the zero max LOD workaround is active. + ASSERT(!mUseLevelZeroTexture || mRenderer->getWorkarounds().zeroMaxLodWorkaround); +} + +gl::Error TextureStorage11_2D::onDestroy(const gl::Context *context) +{ + for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) { - //The LevelZeroOnly hint should only be true if the zero max LOD workaround is active. - ASSERT(mRenderer->getWorkarounds().zeroMaxLodWorkaround); - mUseLevelZeroTexture = true; + if (mAssociatedImages[i] != nullptr) + { + mAssociatedImages[i]->verifyAssociatedStorageValid(this); + + // We must let the Images recover their data before we delete it from the + // TextureStorage. + ANGLE_TRY(mAssociatedImages[i]->recoverFromAssociatedStorage(context)); + } } + + if (mHasKeyedMutex) + { + // If the keyed mutex is released that will unbind it and cause the state cache to become + // desynchronized. + mRenderer->getStateManager()->invalidateBoundViews(); + } + + // Invalidate RenderTargets. + InvalidateRenderTargetContainer(context, &mRenderTarget); + InvalidateRenderTarget(context, mLevelZeroRenderTarget.get()); + + return gl::NoError(); } TextureStorage11_2D::~TextureStorage11_2D() { - for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) - { - if (mAssociatedImages[i] != NULL) - { - bool imageAssociationCorrect = mAssociatedImages[i]->isAssociatedStorageValid(this); - ASSERT(imageAssociationCorrect); - - if (imageAssociationCorrect) - { - // We must let the Images recover their data before we delete it from the TextureStorage. - gl::Error error = mAssociatedImages[i]->recoverFromAssociatedStorage(); - if (error.isError()) - { - // TODO: Find a way to report this back to the context - } - } - } - } - - SafeRelease(mTexture); - SafeRelease(mSwizzleTexture); - - SafeRelease(mLevelZeroTexture); - SafeDelete(mLevelZeroRenderTarget); - - for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) - { - SafeDelete(mRenderTarget[i]); - SafeRelease(mSwizzleRenderTargets[i]); - } } -gl::Error TextureStorage11_2D::copyToStorage(TextureStorage *destStorage) +gl::Error TextureStorage11_2D::copyToStorage(const gl::Context *context, + TextureStorage *destStorage) { ASSERT(destStorage); - TextureStorage11_2D *dest11 = GetAs(destStorage); + TextureStorage11_2D *dest11 = GetAs(destStorage); + ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); if (mRenderer->getWorkarounds().zeroMaxLodWorkaround) { - ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); - - // If either mTexture or mLevelZeroTexture exist, then we need to copy them into the corresponding textures in destStorage. - if (mTexture) + // If either mTexture or mLevelZeroTexture exist, then we need to copy them into the + // corresponding textures in destStorage. + if (mTexture.valid()) { - gl::Error error = dest11->useLevelZeroWorkaroundTexture(false); - if (error.isError()) - { - return error; - } + ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, false)); - ID3D11Resource *destResource = NULL; - error = dest11->getResource(&destResource); - if (error.isError()) - { - return error; - } + const TextureHelper11 *destResource = nullptr; + ANGLE_TRY(dest11->getResource(context, &destResource)); - immediateContext->CopyResource(destResource, mTexture); + immediateContext->CopyResource(destResource->get(), mTexture.get()); } - if (mLevelZeroTexture) + if (mLevelZeroTexture.valid()) { - gl::Error error = dest11->useLevelZeroWorkaroundTexture(true); - if (error.isError()) - { - return error; - } + ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, true)); - ID3D11Resource *destResource = NULL; - error = dest11->getResource(&destResource); - if (error.isError()) - { - return error; - } + const TextureHelper11 *destResource = nullptr; + ANGLE_TRY(dest11->getResource(context, &destResource)); - immediateContext->CopyResource(destResource, mLevelZeroTexture); - } - } - else - { - ID3D11Resource *sourceResouce = NULL; - gl::Error error = getResource(&sourceResouce); - if (error.isError()) - { - return error; + immediateContext->CopyResource(destResource->get(), mLevelZeroTexture.get()); } - ID3D11Resource *destResource = NULL; - error = dest11->getResource(&destResource); - if (error.isError()) - { - return error; - } - - ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); - immediateContext->CopyResource(destResource, sourceResouce); + return gl::NoError(); } - dest11->invalidateSwizzleCache(); + const TextureHelper11 *sourceResouce = nullptr; + ANGLE_TRY(getResource(context, &sourceResouce)); - return gl::Error(GL_NO_ERROR); + const TextureHelper11 *destResource = nullptr; + ANGLE_TRY(dest11->getResource(context, &destResource)); + + immediateContext->CopyResource(destResource->get(), sourceResouce->get()); + dest11->markDirty(); + + return gl::NoError(); } -gl::Error TextureStorage11_2D::useLevelZeroWorkaroundTexture(bool useLevelZeroTexture) +gl::Error TextureStorage11_2D::useLevelZeroWorkaroundTexture(const gl::Context *context, + bool useLevelZeroTexture) { + bool lastSetting = mUseLevelZeroTexture; + if (useLevelZeroTexture && mMipLevels > 1) { - if (!mUseLevelZeroTexture && mTexture) + if (!mUseLevelZeroTexture && mTexture.valid()) { - gl::Error error = ensureTextureExists(1); - if (error.isError()) - { - return error; - } + ANGLE_TRY(ensureTextureExists(1)); // Pull data back from the mipped texture if necessary. - ASSERT(mLevelZeroTexture); - ID3D11DeviceContext *context = mRenderer->getDeviceContext(); - context->CopySubresourceRegion(mLevelZeroTexture, 0, 0, 0, 0, mTexture, 0, NULL); + ASSERT(mLevelZeroTexture.valid()); + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + deviceContext->CopySubresourceRegion(mLevelZeroTexture.get(), 0, 0, 0, 0, + mTexture.get(), 0, nullptr); } mUseLevelZeroTexture = true; } else { - if (mUseLevelZeroTexture && mLevelZeroTexture) + if (mUseLevelZeroTexture && mLevelZeroTexture.valid()) { - gl::Error error = ensureTextureExists(mMipLevels); - if (error.isError()) - { - return error; - } + ANGLE_TRY(ensureTextureExists(mMipLevels)); // Pull data back from the level zero texture if necessary. - ASSERT(mTexture); - ID3D11DeviceContext *context = mRenderer->getDeviceContext(); - context->CopySubresourceRegion(mTexture, 0, 0, 0, 0, mLevelZeroTexture, 0, NULL); + ASSERT(mTexture.valid()); + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + deviceContext->CopySubresourceRegion(mTexture.get(), 0, 0, 0, 0, + mLevelZeroTexture.get(), 0, nullptr); } mUseLevelZeroTexture = false; } - return gl::Error(GL_NO_ERROR); + if (lastSetting != mUseLevelZeroTexture) + { + // Mark everything as dirty to be conservative. + if (mLevelZeroRenderTarget) + { + mLevelZeroRenderTarget->signalDirty(context); + } + for (auto &renderTarget : mRenderTarget) + { + if (renderTarget) + { + renderTarget->signalDirty(context); + } + } + } + + return gl::NoError(); } -void TextureStorage11_2D::associateImage(Image11* image, const gl::ImageIndex &index) +void TextureStorage11_2D::associateImage(Image11 *image, const gl::ImageIndex &index) { - GLint level = index.mipIndex; + const GLint level = index.mipIndex; ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); @@ -965,539 +957,569 @@ void TextureStorage11_2D::associateImage(Image11* image, const gl::ImageIndex &i } } -bool TextureStorage11_2D::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage) +void TextureStorage11_2D::verifyAssociatedImageValid(const gl::ImageIndex &index, + Image11 *expectedImage) { - GLint level = index.mipIndex; + const GLint level = index.mipIndex; - if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) - { - // This validation check should never return false. It means the Image/TextureStorage association is broken. - bool retValue = (mAssociatedImages[level] == expectedImage); - ASSERT(retValue); - return retValue; - } - - return false; + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + // This validation check should never return false. It means the Image/TextureStorage + // association is broken. + ASSERT(mAssociatedImages[level] == expectedImage); } // disassociateImage allows an Image to end its association with a Storage. -void TextureStorage11_2D::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage) +void TextureStorage11_2D::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) { - GLint level = index.mipIndex; + const GLint level = index.mipIndex; ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); - - if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) - { - ASSERT(mAssociatedImages[level] == expectedImage); - - if (mAssociatedImages[level] == expectedImage) - { - mAssociatedImages[level] = NULL; - } - } + ASSERT(mAssociatedImages[level] == expectedImage); + mAssociatedImages[level] = nullptr; } -// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association. -gl::Error TextureStorage11_2D::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage) +// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image +// recover its data before ending the association. +gl::Error TextureStorage11_2D::releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) { - GLint level = index.mipIndex; + const GLint level = index.mipIndex; ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) { // No need to let the old Image recover its data, if it is also the incoming Image. - if (mAssociatedImages[level] != NULL && mAssociatedImages[level] != incomingImage) + if (mAssociatedImages[level] != nullptr && mAssociatedImages[level] != incomingImage) { - // Ensure that the Image is still associated with this TextureStorage. This should be true. - bool imageAssociationCorrect = mAssociatedImages[level]->isAssociatedStorageValid(this); - ASSERT(imageAssociationCorrect); + // Ensure that the Image is still associated with this TextureStorage. + mAssociatedImages[level]->verifyAssociatedStorageValid(this); - if (imageAssociationCorrect) - { - // Force the image to recover from storage before its data is overwritten. - // This will reset mAssociatedImages[level] to NULL too. - gl::Error error = mAssociatedImages[level]->recoverFromAssociatedStorage(); - if (error.isError()) - { - return error; - } - } + // Force the image to recover from storage before its data is overwritten. + // This will reset mAssociatedImages[level] to nullptr too. + ANGLE_TRY(mAssociatedImages[level]->recoverFromAssociatedStorage(context)); } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage11_2D::getResource(ID3D11Resource **outResource) +gl::Error TextureStorage11_2D::getResource(const gl::Context *context, + const TextureHelper11 **outResource) { if (mUseLevelZeroTexture && mMipLevels > 1) { - gl::Error error = ensureTextureExists(1); - if (error.isError()) - { - return error; - } + ANGLE_TRY(ensureTextureExists(1)); - *outResource = mLevelZeroTexture; - return gl::Error(GL_NO_ERROR); + *outResource = &mLevelZeroTexture; + return gl::NoError(); } - else - { - gl::Error error = ensureTextureExists(mMipLevels); - if (error.isError()) - { - return error; - } - *outResource = mTexture; - return gl::Error(GL_NO_ERROR); - } + ANGLE_TRY(ensureTextureExists(mMipLevels)); + + *outResource = &mTexture; + return gl::NoError(); } -gl::Error TextureStorage11_2D::getMippedResource(ID3D11Resource **outResource) +gl::Error TextureStorage11_2D::getMippedResource(const gl::Context *context, + const TextureHelper11 **outResource) { // This shouldn't be called unless the zero max LOD workaround is active. ASSERT(mRenderer->getWorkarounds().zeroMaxLodWorkaround); - gl::Error error = ensureTextureExists(mMipLevels); - if (error.isError()) - { - return error; - } + ANGLE_TRY(ensureTextureExists(mMipLevels)); - *outResource = mTexture; - return gl::Error(GL_NO_ERROR); + *outResource = &mTexture; + return gl::NoError(); } gl::Error TextureStorage11_2D::ensureTextureExists(int mipLevels) { // If mMipLevels = 1 then always use mTexture rather than mLevelZeroTexture. - bool useLevelZeroTexture = mRenderer->getWorkarounds().zeroMaxLodWorkaround ? (mipLevels == 1) && (mMipLevels > 1) : false; - ID3D11Texture2D **outputTexture = useLevelZeroTexture ? &mLevelZeroTexture : &mTexture; + bool useLevelZeroTexture = mRenderer->getWorkarounds().zeroMaxLodWorkaround + ? (mipLevels == 1) && (mMipLevels > 1) + : false; + TextureHelper11 *outputTexture = useLevelZeroTexture ? &mLevelZeroTexture : &mTexture; // if the width or height is not positive this should be treated as an incomplete texture // we handle that here by skipping the d3d texture creation - if (*outputTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0) + if (!outputTexture->valid() && mTextureWidth > 0 && mTextureHeight > 0) { ASSERT(mipLevels > 0); - ID3D11Device *device = mRenderer->getDevice(); - D3D11_TEXTURE2D_DESC desc; - desc.Width = mTextureWidth; // Compressed texture size constraints? - desc.Height = mTextureHeight; - desc.MipLevels = mipLevels; - desc.ArraySize = 1; - desc.Format = mTextureFormat; - desc.SampleDesc.Count = 1; + desc.Width = mTextureWidth; // Compressed texture size constraints? + desc.Height = mTextureHeight; + desc.MipLevels = mipLevels; + desc.ArraySize = 1; + desc.Format = mFormatInfo.texFormat; + desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = getBindFlags(); - desc.CPUAccessFlags = 0; - desc.MiscFlags = getMiscFlags(); + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags(); + desc.CPUAccessFlags = 0; + desc.MiscFlags = getMiscFlags(); - HRESULT result = device->CreateTexture2D(&desc, NULL, outputTexture); - - // this can happen from windows TDR - if (d3d11::isDeviceLostError(result)) - { - mRenderer->notifyDeviceLost(); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D texture storage, result: 0x%X.", result); - } - else if (FAILED(result)) - { - ASSERT(result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D texture storage, result: 0x%X.", result); - } - - d3d11::SetDebugName(*outputTexture, "TexStorage2D.Texture"); + ANGLE_TRY(mRenderer->allocateTexture(desc, mFormatInfo, outputTexture)); + outputTexture->setDebugName("TexStorage2D.Texture"); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage11_2D::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) +gl::Error TextureStorage11_2D::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) { ASSERT(!index.hasLayer()); - int level = index.mipIndex; + const int level = index.mipIndex; ASSERT(level >= 0 && level < getLevelCount()); - // In GL ES 2.0, the application can only render to level zero of the texture (Section 4.4.3 of the GLES 2.0 spec, page 113 of version 2.0.25). - // Other parts of TextureStorage11_2D could create RTVs on non-zero levels of the texture (e.g. generateMipmap). - // On Feature Level 9_3, this is unlikely to be useful. The renderer can't create SRVs on the individual levels of the texture, - // so methods like generateMipmap can't do anything useful with non-zero-level RTVs. - // Therefore if level > 0 on 9_3 then there's almost certainly something wrong. - ASSERT(!(mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3 && level > 0)); - - if (!mRenderTarget[level]) + // In GL ES 2.0, the application can only render to level zero of the texture (Section 4.4.3 of + // the GLES 2.0 spec, page 113 of version 2.0.25). Other parts of TextureStorage11_2D could + // create RTVs on non-zero levels of the texture (e.g. generateMipmap). + // On Feature Level 9_3, this is unlikely to be useful. The renderer can't create SRVs on the + // individual levels of the texture, so methods like generateMipmap can't do anything useful + // with non-zero-level RTVs. Therefore if level > 0 on 9_3 then there's almost certainly + // something wrong. + ASSERT( + !(mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3 && level > 0)); + ASSERT(outRT); + if (mRenderTarget[level]) { - ID3D11Resource *texture = NULL; - gl::Error error = getResource(&texture); - if (error.isError()) - { - return error; - } - - ID3D11ShaderResourceView *srv = NULL; - error = getSRVLevel(level, &srv); - if (error.isError()) - { - return error; - } - - if (mUseLevelZeroTexture) - { - if (!mLevelZeroRenderTarget) - { - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - rtvDesc.Texture2D.MipSlice = mTopLevel + level; - - ID3D11RenderTargetView *rtv; - HRESULT result = device->CreateRenderTargetView(mLevelZeroTexture, &rtvDesc, &rtv); - - if (result == E_OUTOFMEMORY) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); - } - ASSERT(SUCCEEDED(result)); - - mLevelZeroRenderTarget = new TextureRenderTarget11(rtv, mLevelZeroTexture, NULL, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0); - - // RenderTarget will take ownership of these resources - SafeRelease(rtv); - } - - ASSERT(outRT); - *outRT = mLevelZeroRenderTarget; - return gl::Error(GL_NO_ERROR); - } - - if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) - { - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - rtvDesc.Texture2D.MipSlice = mTopLevel + level; - - ID3D11RenderTargetView *rtv; - HRESULT result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv); - - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); - } - - mRenderTarget[level] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0); - - // RenderTarget will take ownership of these resources - SafeRelease(rtv); - } - else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN) - { - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsvDesc.Format = mDepthStencilFormat; - dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; - dsvDesc.Texture2D.MipSlice = mTopLevel + level; - dsvDesc.Flags = 0; - - ID3D11DepthStencilView *dsv; - HRESULT result = device->CreateDepthStencilView(texture, &dsvDesc, &dsv); - - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY,"Failed to create internal depth stencil view for texture storage, result: 0x%X.", result); - } - - mRenderTarget[level] = new TextureRenderTarget11(dsv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0); - - // RenderTarget will take ownership of these resources - SafeRelease(dsv); - } - else - { - UNREACHABLE(); - } + *outRT = mRenderTarget[level].get(); + return gl::NoError(); } - ASSERT(outRT); - *outRT = mRenderTarget[level]; - return gl::Error(GL_NO_ERROR); + if (mRenderer->getWorkarounds().zeroMaxLodWorkaround) + { + ASSERT(index.mipIndex == 0); + ANGLE_TRY(useLevelZeroWorkaroundTexture(context, true)); + } + + const TextureHelper11 *texture = nullptr; + ANGLE_TRY(getResource(context, &texture)); + + const d3d11::SharedSRV *srv = nullptr; + ANGLE_TRY(getSRVLevel(context, level, false, &srv)); + + const d3d11::SharedSRV *blitSRV = nullptr; + ANGLE_TRY(getSRVLevel(context, level, true, &blitSRV)); + + if (mUseLevelZeroTexture) + { + if (!mLevelZeroRenderTarget) + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mFormatInfo.rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtvDesc.Texture2D.MipSlice = mTopLevel + level; + + d3d11::RenderTargetView rtv; + ANGLE_TRY(mRenderer->allocateResource(rtvDesc, mLevelZeroTexture.get(), &rtv)); + + mLevelZeroRenderTarget.reset(new TextureRenderTarget11( + std::move(rtv), mLevelZeroTexture, d3d11::SharedSRV(), d3d11::SharedSRV(), + mFormatInfo.internalFormat, getFormatSet(), getLevelWidth(level), + getLevelHeight(level), 1, 0)); + } + + *outRT = mLevelZeroRenderTarget.get(); + return gl::NoError(); + } + + if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN) + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mFormatInfo.rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtvDesc.Texture2D.MipSlice = mTopLevel + level; + + d3d11::RenderTargetView rtv; + ANGLE_TRY(mRenderer->allocateResource(rtvDesc, texture->get(), &rtv)); + + mRenderTarget[level].reset(new TextureRenderTarget11( + std::move(rtv), *texture, *srv, *blitSRV, mFormatInfo.internalFormat, getFormatSet(), + getLevelWidth(level), getLevelHeight(level), 1, 0)); + + *outRT = mRenderTarget[level].get(); + return gl::NoError(); + } + + ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN); + + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Format = mFormatInfo.dsvFormat; + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + dsvDesc.Texture2D.MipSlice = mTopLevel + level; + dsvDesc.Flags = 0; + + d3d11::DepthStencilView dsv; + ANGLE_TRY(mRenderer->allocateResource(dsvDesc, texture->get(), &dsv)); + + mRenderTarget[level].reset(new TextureRenderTarget11( + std::move(dsv), *texture, *srv, mFormatInfo.internalFormat, getFormatSet(), + getLevelWidth(level), getLevelHeight(level), 1, 0)); + + *outRT = mRenderTarget[level].get(); + return gl::NoError(); } -gl::Error TextureStorage11_2D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, - ID3D11ShaderResourceView **outSRV) const +gl::Error TextureStorage11_2D::createSRV(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) { ASSERT(outSRV); D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = format; - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + srvDesc.Format = format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel; - srvDesc.Texture2D.MipLevels = mipLevels; + srvDesc.Texture2D.MipLevels = mipLevels; - ID3D11Resource *srvTexture = texture; + const TextureHelper11 *srvTexture = &texture; if (mRenderer->getWorkarounds().zeroMaxLodWorkaround) { ASSERT(mTopLevel == 0); ASSERT(baseLevel == 0); - // This code also assumes that the incoming texture equals either mLevelZeroTexture or mTexture. + // This code also assumes that the incoming texture equals either mLevelZeroTexture or + // mTexture. if (mipLevels == 1 && mMipLevels > 1) { // We must use a SRV on the level-zero-only texture. - ASSERT(mLevelZeroTexture != NULL && texture == mLevelZeroTexture); - srvTexture = mLevelZeroTexture; + ANGLE_TRY(ensureTextureExists(1)); + srvTexture = &mLevelZeroTexture; } else { ASSERT(mipLevels == static_cast(mMipLevels)); - ASSERT(mTexture != NULL && texture == mTexture); - srvTexture = mTexture; + ASSERT(mTexture.valid() && texture == mTexture); + srvTexture = &mTexture; } } - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result = device->CreateShaderResourceView(srvTexture, &srvDesc, outSRV); + ANGLE_TRY(mRenderer->allocateResource(srvDesc, srvTexture->get(), outSRV)); + outSRV->setDebugName("TexStorage2D.SRV"); - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result); - } - - d3d11::SetDebugName(*outSRV, "TexStorage2D.SRV"); - - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage11_2D::getSwizzleTexture(ID3D11Resource **outTexture) +gl::Error TextureStorage11_2D::getSwizzleTexture(const TextureHelper11 **outTexture) { ASSERT(outTexture); - if (!mSwizzleTexture) + if (!mSwizzleTexture.valid()) { - ID3D11Device *device = mRenderer->getDevice(); + const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()); D3D11_TEXTURE2D_DESC desc; - desc.Width = mTextureWidth; - desc.Height = mTextureHeight; - desc.MipLevels = mMipLevels; - desc.ArraySize = 1; - desc.Format = mSwizzleTextureFormat; - desc.SampleDesc.Count = 1; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.MipLevels = mMipLevels; + desc.ArraySize = 1; + desc.Format = format.texFormat; + desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; - desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; - HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture); - - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result); - } - - d3d11::SetDebugName(mSwizzleTexture, "TexStorage2D.SwizzleTexture"); + ANGLE_TRY(mRenderer->allocateTexture(desc, format, &mSwizzleTexture)); + mSwizzleTexture.setDebugName("TexStorage2D.SwizzleTexture"); } - *outTexture = mSwizzleTexture; - return gl::Error(GL_NO_ERROR); + *outTexture = &mSwizzleTexture; + return gl::NoError(); } -gl::Error TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) +gl::Error TextureStorage11_2D::getSwizzleRenderTarget(int mipLevel, + const d3d11::RenderTargetView **outRTV) { ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); ASSERT(outRTV); - if (!mSwizzleRenderTargets[mipLevel]) + if (!mSwizzleRenderTargets[mipLevel].valid()) { - ID3D11Resource *swizzleTexture = NULL; - gl::Error error = getSwizzleTexture(&swizzleTexture); - if (error.isError()) - { - return error; - } - - ID3D11Device *device = mRenderer->getDevice(); + const TextureHelper11 *swizzleTexture = nullptr; + ANGLE_TRY(getSwizzleTexture(&swizzleTexture)); D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mSwizzleRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtvDesc.Format = + mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel; - HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); - - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result); - } + ANGLE_TRY(mRenderer->allocateResource(rtvDesc, mSwizzleTexture.get(), + &mSwizzleRenderTargets[mipLevel])); } - *outRTV = mSwizzleRenderTargets[mipLevel]; - return gl::Error(GL_NO_ERROR); + *outRTV = &mSwizzleRenderTargets[mipLevel]; + return gl::NoError(); } -TextureStorage11_EGLImage::TextureStorage11_EGLImage(Renderer11 *renderer, EGLImageD3D *eglImage) - : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, 0), +gl::ErrorOrResult TextureStorage11_2D::ensureDropStencilTexture( + const gl::Context *context) +{ + if (mDropStencilTexture.valid()) + { + return DropStencil::ALREADY_EXISTS; + } + + D3D11_TEXTURE2D_DESC dropDesc = {}; + dropDesc.ArraySize = 1; + dropDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL; + dropDesc.CPUAccessFlags = 0; + dropDesc.Format = DXGI_FORMAT_R32_TYPELESS; + dropDesc.Height = mTextureHeight; + dropDesc.MipLevels = mMipLevels; + dropDesc.MiscFlags = 0; + dropDesc.SampleDesc.Count = 1; + dropDesc.SampleDesc.Quality = 0; + dropDesc.Usage = D3D11_USAGE_DEFAULT; + dropDesc.Width = mTextureWidth; + + const auto &format = + d3d11::Format::Get(GL_DEPTH_COMPONENT32F, mRenderer->getRenderer11DeviceCaps()); + ANGLE_TRY(mRenderer->allocateTexture(dropDesc, format, &mDropStencilTexture)); + mDropStencilTexture.setDebugName("TexStorage2D.DropStencil"); + + ANGLE_TRY(initDropStencilTexture(context, gl::ImageIndexIterator::Make2D(0, mMipLevels))); + + return DropStencil::CREATED; +} + +TextureStorage11_External::TextureStorage11_External( + Renderer11 *renderer, + egl::Stream *stream, + const egl::Stream::GLTextureDescription &glDesc) + : TextureStorage11(renderer, D3D11_BIND_SHADER_RESOURCE, 0, glDesc.internalFormat) +{ + ASSERT(stream->getProducerType() == egl::Stream::ProducerType::D3D11TextureNV12); + StreamProducerNV12 *producer = static_cast(stream->getImplementation()); + mTexture.set(producer->getD3DTexture(), mFormatInfo); + mSubresourceIndex = producer->getArraySlice(); + mTexture.get()->AddRef(); + mMipLevels = 1; + + D3D11_TEXTURE2D_DESC desc; + mTexture.getDesc(&desc); + mTextureWidth = desc.Width; + mTextureHeight = desc.Height; + mTextureDepth = 1; + mHasKeyedMutex = (desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) != 0; +} + +gl::Error TextureStorage11_External::onDestroy(const gl::Context *context) +{ + if (mHasKeyedMutex) + { + // If the keyed mutex is released that will unbind it and cause the state cache to become + // desynchronized. + mRenderer->getStateManager()->invalidateBoundViews(); + } + + return gl::NoError(); +} + +TextureStorage11_External::~TextureStorage11_External() +{ +} + +gl::Error TextureStorage11_External::copyToStorage(const gl::Context *context, + TextureStorage *destStorage) +{ + UNIMPLEMENTED(); + return gl::NoError(); +} + +void TextureStorage11_External::associateImage(Image11 *image, const gl::ImageIndex &index) +{ + ASSERT(index.mipIndex == 0); + mAssociatedImage = image; +} + +void TextureStorage11_External::verifyAssociatedImageValid(const gl::ImageIndex &index, + Image11 *expectedImage) +{ + ASSERT(index.mipIndex == 0 && mAssociatedImage == expectedImage); +} + +void TextureStorage11_External::disassociateImage(const gl::ImageIndex &index, + Image11 *expectedImage) +{ + ASSERT(index.mipIndex == 0); + ASSERT(mAssociatedImage == expectedImage); + mAssociatedImage = nullptr; +} + +gl::Error TextureStorage11_External::releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) +{ + ASSERT(index.mipIndex == 0); + + if (mAssociatedImage != nullptr && mAssociatedImage != incomingImage) + { + mAssociatedImage->verifyAssociatedStorageValid(this); + + ANGLE_TRY(mAssociatedImage->recoverFromAssociatedStorage(context)); + } + + return gl::NoError(); +} + +gl::Error TextureStorage11_External::getResource(const gl::Context *context, + const TextureHelper11 **outResource) +{ + *outResource = &mTexture; + return gl::NoError(); +} + +gl::Error TextureStorage11_External::getMippedResource(const gl::Context *context, + const TextureHelper11 **outResource) +{ + *outResource = &mTexture; + return gl::NoError(); +} + +gl::Error TextureStorage11_External::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) +{ + // Render targets are not supported for external textures + UNREACHABLE(); + return gl::InternalError(); +} + +gl::Error TextureStorage11_External::createSRV(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) +{ + // Since external textures are treates as non-mipmapped textures, we ignore mipmap levels and + // use the specified subresource ID the storage was created with. + ASSERT(mipLevels == 1); + ASSERT(outSRV); + + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + // subresource index is equal to the mip level for 2D textures + srvDesc.Texture2DArray.MostDetailedMip = 0; + srvDesc.Texture2DArray.MipLevels = 1; + srvDesc.Texture2DArray.FirstArraySlice = mSubresourceIndex; + srvDesc.Texture2DArray.ArraySize = 1; + + ANGLE_TRY(mRenderer->allocateResource(srvDesc, texture.get(), outSRV)); + outSRV->setDebugName("TexStorage2D.SRV"); + + return gl::NoError(); +} + +gl::Error TextureStorage11_External::getSwizzleTexture(const TextureHelper11 **outTexture) +{ + UNIMPLEMENTED(); + return gl::InternalError(); +} + +gl::Error TextureStorage11_External::getSwizzleRenderTarget(int mipLevel, + const d3d11::RenderTargetView **outRTV) +{ + UNIMPLEMENTED(); + return gl::InternalError(); +} + +TextureStorage11_EGLImage::TextureStorage11_EGLImage(Renderer11 *renderer, + EGLImageD3D *eglImage, + RenderTarget11 *renderTarget11) + : TextureStorage11(renderer, + D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, + 0, + renderTarget11->getInternalFormat()), mImage(eglImage), mCurrentRenderTarget(0), - mSwizzleTexture(nullptr), - mSwizzleRenderTargets(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS, nullptr) + mSwizzleTexture(), + mSwizzleRenderTargets(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) { - RenderTargetD3D *renderTargetD3D = nullptr; - mImage->getRenderTarget(&renderTargetD3D); - RenderTarget11 *renderTarget11 = GetAs(renderTargetD3D); - mCurrentRenderTarget = reinterpret_cast(renderTarget11); + mCurrentRenderTarget = reinterpret_cast(renderTarget11); - mMipLevels = 1; - mTextureFormat = renderTarget11->getDXGIFormat(); - mTextureWidth = renderTarget11->getWidth(); - mTextureHeight = renderTarget11->getHeight(); - mTextureDepth = 1; - mInternalFormat = renderTarget11->getInternalFormat(); - - ID3D11ShaderResourceView *srv = renderTarget11->getShaderResourceView(); - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srv->GetDesc(&srvDesc); - mShaderResourceFormat = srvDesc.Format; - - ID3D11RenderTargetView *rtv = renderTarget11->getRenderTargetView(); - if (rtv != nullptr) - { - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtv->GetDesc(&rtvDesc); - mRenderTargetFormat = rtvDesc.Format; - } - else - { - mRenderTargetFormat = DXGI_FORMAT_UNKNOWN; - } - - ID3D11DepthStencilView *dsv = renderTarget11->getDepthStencilView(); - if (dsv != nullptr) - { - D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsv->GetDesc(&dsvDesc); - mDepthStencilFormat = dsvDesc.Format; - } - else - { - mDepthStencilFormat = DXGI_FORMAT_UNKNOWN; - } - - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(mTextureFormat); - const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo( - dxgiFormatInfo.internalFormat, mRenderer->getRenderer11DeviceCaps()); - mSwizzleTextureFormat = formatInfo.swizzleTexFormat; - mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat; - mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat; + mMipLevels = 1; + mTextureWidth = renderTarget11->getWidth(); + mTextureHeight = renderTarget11->getHeight(); + mTextureDepth = 1; } TextureStorage11_EGLImage::~TextureStorage11_EGLImage() { - SafeRelease(mSwizzleTexture); - for (size_t i = 0; i < mSwizzleRenderTargets.size(); i++) - { - SafeRelease(mSwizzleRenderTargets[i]); - } } -gl::Error TextureStorage11_EGLImage::getResource(ID3D11Resource **outResource) +gl::Error TextureStorage11_EGLImage::getResource(const gl::Context *context, + const TextureHelper11 **outResource) { - gl::Error error = checkForUpdatedRenderTarget(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(checkForUpdatedRenderTarget(context)); RenderTarget11 *renderTarget11 = nullptr; - error = getImageRenderTarget(&renderTarget11); - if (error.isError()) - { - return error; - } - - *outResource = renderTarget11->getTexture(); - return gl::Error(GL_NO_ERROR); + ANGLE_TRY(getImageRenderTarget(context, &renderTarget11)); + *outResource = &renderTarget11->getTexture(); + return gl::NoError(); } -gl::Error TextureStorage11_EGLImage::getSRV(const gl::TextureState &textureState, - ID3D11ShaderResourceView **outSRV) +gl::Error TextureStorage11_EGLImage::getSRV(const gl::Context *context, + const gl::TextureState &textureState, + const d3d11::SharedSRV **outSRV) { - gl::Error error = checkForUpdatedRenderTarget(); - if (error.isError()) - { - return error; - } - - return TextureStorage11::getSRV(textureState, outSRV); + ANGLE_TRY(checkForUpdatedRenderTarget(context)); + return TextureStorage11::getSRV(context, textureState, outSRV); } -gl::Error TextureStorage11_EGLImage::getMippedResource(ID3D11Resource **) +gl::Error TextureStorage11_EGLImage::getMippedResource(const gl::Context *context, + const TextureHelper11 **) { // This shouldn't be called unless the zero max LOD workaround is active. // EGL images are unavailable in this configuration. UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + return gl::InternalError(); } -gl::Error TextureStorage11_EGLImage::getRenderTarget(const gl::ImageIndex &index, +gl::Error TextureStorage11_EGLImage::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, RenderTargetD3D **outRT) { ASSERT(!index.hasLayer()); ASSERT(index.mipIndex == 0); - UNUSED_ASSERTION_VARIABLE(index); - gl::Error error = checkForUpdatedRenderTarget(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(checkForUpdatedRenderTarget(context)); - return mImage->getRenderTarget(outRT); + return mImage->getRenderTarget(context, outRT); } -gl::Error TextureStorage11_EGLImage::copyToStorage(TextureStorage *destStorage) +gl::Error TextureStorage11_EGLImage::copyToStorage(const gl::Context *context, + TextureStorage *destStorage) { - ID3D11Resource *sourceResouce = nullptr; - gl::Error error = getResource(&sourceResouce); - if (error.isError()) - { - return error; - } + const TextureHelper11 *sourceResouce = nullptr; + ANGLE_TRY(getResource(context, &sourceResouce)); ASSERT(destStorage); TextureStorage11_2D *dest11 = GetAs(destStorage); - ID3D11Resource *destResource = nullptr; - error = dest11->getResource(&destResource); - if (error.isError()) - { - return error; - } + const TextureHelper11 *destResource = nullptr; + ANGLE_TRY(dest11->getResource(context, &destResource)); ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); - immediateContext->CopyResource(destResource, sourceResouce); + immediateContext->CopyResource(destResource->get(), sourceResouce->get()); - dest11->invalidateSwizzleCache(); + dest11->markDirty(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } void TextureStorage11_EGLImage::associateImage(Image11 *, const gl::ImageIndex &) @@ -1508,36 +1530,37 @@ void TextureStorage11_EGLImage::disassociateImage(const gl::ImageIndex &, Image1 { } -bool TextureStorage11_EGLImage::isAssociatedImageValid(const gl::ImageIndex &, Image11 *) +void TextureStorage11_EGLImage::verifyAssociatedImageValid(const gl::ImageIndex &, Image11 *) { - return false; } -gl::Error TextureStorage11_EGLImage::releaseAssociatedImage(const gl::ImageIndex &, Image11 *) +gl::Error TextureStorage11_EGLImage::releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &, + Image11 *) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage11_EGLImage::useLevelZeroWorkaroundTexture(bool) +gl::Error TextureStorage11_EGLImage::useLevelZeroWorkaroundTexture(const gl::Context *context, bool) { UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + return gl::InternalError(); } -gl::Error TextureStorage11_EGLImage::getSwizzleTexture(ID3D11Resource **outTexture) +gl::Error TextureStorage11_EGLImage::getSwizzleTexture(const TextureHelper11 **outTexture) { ASSERT(outTexture); - if (!mSwizzleTexture) + if (!mSwizzleTexture.valid()) { - ID3D11Device *device = mRenderer->getDevice(); + const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()); D3D11_TEXTURE2D_DESC desc; desc.Width = mTextureWidth; desc.Height = mTextureHeight; desc.MipLevels = mMipLevels; desc.ArraySize = 1; - desc.Format = mSwizzleTextureFormat; + desc.Format = format.texFormat; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_DEFAULT; @@ -1545,68 +1568,43 @@ gl::Error TextureStorage11_EGLImage::getSwizzleTexture(ID3D11Resource **outTextu desc.CPUAccessFlags = 0; desc.MiscFlags = 0; - HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture); - - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, - "Failed to create internal swizzle texture, result: 0x%X.", result); - } - - d3d11::SetDebugName(mSwizzleTexture, "TexStorageEGLImage.SwizzleTexture"); + ANGLE_TRY(mRenderer->allocateTexture(desc, format, &mSwizzleTexture)); + mSwizzleTexture.setDebugName("TexStorageEGLImage.SwizzleTexture"); } - *outTexture = mSwizzleTexture; - return gl::Error(GL_NO_ERROR); + *outTexture = &mSwizzleTexture; + return gl::NoError(); } gl::Error TextureStorage11_EGLImage::getSwizzleRenderTarget(int mipLevel, - ID3D11RenderTargetView **outRTV) + const d3d11::RenderTargetView **outRTV) { ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); ASSERT(outRTV); - if (!mSwizzleRenderTargets[mipLevel]) + if (!mSwizzleRenderTargets[mipLevel].valid()) { - ID3D11Resource *swizzleTexture = NULL; - gl::Error error = getSwizzleTexture(&swizzleTexture); - if (error.isError()) - { - return error; - } - - ID3D11Device *device = mRenderer->getDevice(); + const TextureHelper11 *swizzleTexture = nullptr; + ANGLE_TRY(getSwizzleTexture(&swizzleTexture)); D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mSwizzleRenderTargetFormat; + rtvDesc.Format = + mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat; rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel; - HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, - &mSwizzleRenderTargets[mipLevel]); - - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, - "Failed to create internal swizzle render target view, result: 0x%X.", - result); - } + ANGLE_TRY(mRenderer->allocateResource(rtvDesc, mSwizzleTexture.get(), + &mSwizzleRenderTargets[mipLevel])); } - *outRTV = mSwizzleRenderTargets[mipLevel]; - return gl::Error(GL_NO_ERROR); + *outRTV = &mSwizzleRenderTargets[mipLevel]; + return gl::NoError(); } -gl::Error TextureStorage11_EGLImage::checkForUpdatedRenderTarget() +gl::Error TextureStorage11_EGLImage::checkForUpdatedRenderTarget(const gl::Context *context) { RenderTarget11 *renderTarget11 = nullptr; - gl::Error error = getImageRenderTarget(&renderTarget11); - if (error.isError()) - { - return error; - } + ANGLE_TRY(getImageRenderTarget(context, &renderTarget11)); if (mCurrentRenderTarget != reinterpret_cast(renderTarget11)) { @@ -1614,14 +1612,15 @@ gl::Error TextureStorage11_EGLImage::checkForUpdatedRenderTarget() mCurrentRenderTarget = reinterpret_cast(renderTarget11); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage11_EGLImage::createSRV(int baseLevel, +gl::Error TextureStorage11_EGLImage::createSRV(const gl::Context *context, + int baseLevel, int mipLevels, DXGI_FORMAT format, - ID3D11Resource *texture, - ID3D11ShaderResourceView **outSRV) const + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) { ASSERT(baseLevel == 0); ASSERT(mipLevels == 1); @@ -1637,163 +1636,129 @@ gl::Error TextureStorage11_EGLImage::createSRV(int baseLevel, srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel; srvDesc.Texture2D.MipLevels = mipLevels; - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV); - - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, - "Failed to create internal texture storage SRV, result: 0x%X.", - result); - } - - d3d11::SetDebugName(*outSRV, "TexStorageEGLImage.SRV"); + ANGLE_TRY(mRenderer->allocateResource(srvDesc, texture.get(), outSRV)); + outSRV->setDebugName("TexStorageEGLImage.SRV"); } else { RenderTarget11 *renderTarget = nullptr; - gl::Error error = getImageRenderTarget(&renderTarget); - if (error.isError()) - { - return error; - } + ANGLE_TRY(getImageRenderTarget(context, &renderTarget)); ASSERT(texture == renderTarget->getTexture()); - *outSRV = renderTarget->getShaderResourceView(); - (*outSRV)->AddRef(); + *outSRV = renderTarget->getShaderResourceView().makeCopy(); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage11_EGLImage::getImageRenderTarget(RenderTarget11 **outRT) const +gl::Error TextureStorage11_EGLImage::getImageRenderTarget(const gl::Context *context, + RenderTarget11 **outRT) const { RenderTargetD3D *renderTargetD3D = nullptr; - gl::Error error = mImage->getRenderTarget(&renderTargetD3D); - if (error.isError()) - { - return error; - } - + ANGLE_TRY(mImage->getRenderTarget(context, &renderTargetD3D)); *outRT = GetAs(renderTargetD3D); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer, GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly) - : TextureStorage11(renderer, - GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget), - GetTextureMiscFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget, levels)) +TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer, + GLenum internalformat, + bool renderTarget, + int size, + int levels, + bool hintLevelZeroOnly) + : TextureStorage11( + renderer, + GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget), + GetTextureMiscFlags(internalformat, + renderer->getRenderer11DeviceCaps(), + renderTarget, + levels), + internalformat), + mTexture(), + mLevelZeroTexture(), + mUseLevelZeroTexture(hintLevelZeroOnly && levels > 1), + mSwizzleTexture() { - mTexture = NULL; - mSwizzleTexture = NULL; - for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) { - mSwizzleRenderTargets[level] = NULL; - for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++) + for (unsigned int face = 0; face < gl::CUBE_FACE_COUNT; face++) { - mAssociatedImages[face][level] = NULL; - mRenderTarget[face][level] = NULL; + mAssociatedImages[face][level] = nullptr; + mRenderTarget[face][level] = nullptr; } } - mLevelZeroTexture = NULL; - mUseLevelZeroTexture = false; - - for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++) + for (unsigned int face = 0; face < gl::CUBE_FACE_COUNT; face++) { - mLevelZeroRenderTarget[face] = NULL; + mLevelZeroRenderTarget[face] = nullptr; } - mInternalFormat = internalformat; - - const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat, renderer->getRenderer11DeviceCaps()); - mTextureFormat = formatInfo.texFormat; - mShaderResourceFormat = formatInfo.srvFormat; - mDepthStencilFormat = formatInfo.dsvFormat; - mRenderTargetFormat = formatInfo.rtvFormat; - mSwizzleTextureFormat = formatInfo.swizzleTexFormat; - mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat; - mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat; - // adjust size if needed for compressed textures int height = size; - d3d11::MakeValidSize(false, mTextureFormat, &size, &height, &mTopLevel); + d3d11::MakeValidSize(false, mFormatInfo.texFormat, &size, &height, &mTopLevel); - mMipLevels = mTopLevel + levels; - mTextureWidth = size; + mMipLevels = mTopLevel + levels; + mTextureWidth = size; mTextureHeight = size; - mTextureDepth = 1; + mTextureDepth = 1; - if (hintLevelZeroOnly && levels > 1) - { - //The LevelZeroOnly hint should only be true if the zero max LOD workaround is active. - ASSERT(mRenderer->getWorkarounds().zeroMaxLodWorkaround); - mUseLevelZeroTexture = true; - } + // The LevelZeroOnly hint should only be true if the zero max LOD workaround is active. + ASSERT(!mUseLevelZeroTexture || mRenderer->getWorkarounds().zeroMaxLodWorkaround); } -TextureStorage11_Cube::~TextureStorage11_Cube() +gl::Error TextureStorage11_Cube::onDestroy(const gl::Context *context) { for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) { - for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++) + for (unsigned int face = 0; face < gl::CUBE_FACE_COUNT; face++) { - if (mAssociatedImages[face][level] != NULL) + if (mAssociatedImages[face][level] != nullptr) { - bool imageAssociationCorrect = mAssociatedImages[face][level]->isAssociatedStorageValid(this); - ASSERT(imageAssociationCorrect); + mAssociatedImages[face][level]->verifyAssociatedStorageValid(this); - if (imageAssociationCorrect) - { - // We must let the Images recover their data before we delete it from the TextureStorage. - mAssociatedImages[face][level]->recoverFromAssociatedStorage(); - } + // We must let the Images recover their data before we delete it from the + // TextureStorage. + ANGLE_TRY(mAssociatedImages[face][level]->recoverFromAssociatedStorage(context)); } } } - SafeRelease(mTexture); - SafeRelease(mSwizzleTexture); - SafeRelease(mLevelZeroTexture); - - for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++) + for (auto &faceRenderTargets : mRenderTarget) { - SafeDelete(mLevelZeroRenderTarget[face]); + InvalidateRenderTargetContainer(context, &faceRenderTargets); } + InvalidateRenderTargetContainer(context, &mLevelZeroRenderTarget); - for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) - { - SafeRelease(mSwizzleRenderTargets[level]); - for (unsigned int face = 0; face < CUBE_FACE_COUNT; face++) - { - SafeDelete(mRenderTarget[face][level]); - } - } + return gl::NoError(); +} + +TextureStorage11_Cube::~TextureStorage11_Cube() +{ } UINT TextureStorage11_Cube::getSubresourceIndex(const gl::ImageIndex &index) const { - if (mRenderer->getWorkarounds().zeroMaxLodWorkaround && mUseLevelZeroTexture && index.mipIndex == 0) + if (mRenderer->getWorkarounds().zeroMaxLodWorkaround && mUseLevelZeroTexture && + index.mipIndex == 0) { - UINT arraySlice = static_cast(index.hasLayer() ? index.layerIndex : 0); + UINT arraySlice = static_cast(index.hasLayer() ? index.layerIndex : 0); UINT subresource = D3D11CalcSubresource(0, arraySlice, 1); ASSERT(subresource != std::numeric_limits::max()); return subresource; } else { - UINT mipSlice = static_cast(index.mipIndex + mTopLevel); - UINT arraySlice = static_cast(index.hasLayer() ? index.layerIndex : 0); + UINT mipSlice = static_cast(index.mipIndex + mTopLevel); + UINT arraySlice = static_cast(index.hasLayer() ? index.layerIndex : 0); UINT subresource = D3D11CalcSubresource(mipSlice, arraySlice, mMipLevels); ASSERT(subresource != std::numeric_limits::max()); return subresource; } } -gl::Error TextureStorage11_Cube::copyToStorage(TextureStorage *destStorage) +gl::Error TextureStorage11_Cube::copyToStorage(const gl::Context *context, + TextureStorage *destStorage) { ASSERT(destStorage); @@ -1803,87 +1768,63 @@ gl::Error TextureStorage11_Cube::copyToStorage(TextureStorage *destStorage) { ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); - // If either mTexture or mLevelZeroTexture exist, then we need to copy them into the corresponding textures in destStorage. - if (mTexture) + // If either mTexture or mLevelZeroTexture exist, then we need to copy them into the + // corresponding textures in destStorage. + if (mTexture.valid()) { - gl::Error error = dest11->useLevelZeroWorkaroundTexture(false); - if (error.isError()) - { - return error; - } + ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, false)); - ID3D11Resource *destResource = NULL; - error = dest11->getResource(&destResource); - if (error.isError()) - { - return error; - } + const TextureHelper11 *destResource = nullptr; + ANGLE_TRY(dest11->getResource(context, &destResource)); - immediateContext->CopyResource(destResource, mTexture); + immediateContext->CopyResource(destResource->get(), mTexture.get()); } - if (mLevelZeroTexture) + if (mLevelZeroTexture.valid()) { - gl::Error error = dest11->useLevelZeroWorkaroundTexture(true); - if (error.isError()) - { - return error; - } + ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, true)); - ID3D11Resource *destResource = NULL; - error = dest11->getResource(&destResource); - if (error.isError()) - { - return error; - } + const TextureHelper11 *destResource = nullptr; + ANGLE_TRY(dest11->getResource(context, &destResource)); - immediateContext->CopyResource(destResource, mLevelZeroTexture); + immediateContext->CopyResource(destResource->get(), mLevelZeroTexture.get()); } } else { - ID3D11Resource *sourceResouce = NULL; - gl::Error error = getResource(&sourceResouce); - if (error.isError()) - { - return error; - } + const TextureHelper11 *sourceResouce = nullptr; + ANGLE_TRY(getResource(context, &sourceResouce)); - ID3D11Resource *destResource = NULL; - error = dest11->getResource(&destResource); - if (error.isError()) - { - return error; - } + const TextureHelper11 *destResource = nullptr; + ANGLE_TRY(dest11->getResource(context, &destResource)); ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext(); - immediateContext->CopyResource(destResource, sourceResouce); + immediateContext->CopyResource(destResource->get(), sourceResouce->get()); } - dest11->invalidateSwizzleCache(); + dest11->markDirty(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage11_Cube::useLevelZeroWorkaroundTexture(bool useLevelZeroTexture) +gl::Error TextureStorage11_Cube::useLevelZeroWorkaroundTexture(const gl::Context *context, + bool useLevelZeroTexture) { if (useLevelZeroTexture && mMipLevels > 1) { - if (!mUseLevelZeroTexture && mTexture) + if (!mUseLevelZeroTexture && mTexture.valid()) { - gl::Error error = ensureTextureExists(1); - if (error.isError()) - { - return error; - } + ANGLE_TRY(ensureTextureExists(1)); // Pull data back from the mipped texture if necessary. - ASSERT(mLevelZeroTexture); - ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + ASSERT(mLevelZeroTexture.valid()); + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); for (int face = 0; face < 6; face++) { - context->CopySubresourceRegion(mLevelZeroTexture, D3D11CalcSubresource(0, face, 1), 0, 0, 0, mTexture, face * mMipLevels, NULL); + deviceContext->CopySubresourceRegion(mLevelZeroTexture.get(), + D3D11CalcSubresource(0, face, 1), 0, 0, 0, + mTexture.get(), face * mMipLevels, nullptr); } } @@ -1891,346 +1832,286 @@ gl::Error TextureStorage11_Cube::useLevelZeroWorkaroundTexture(bool useLevelZero } else { - if (mUseLevelZeroTexture && mLevelZeroTexture) + if (mUseLevelZeroTexture && mLevelZeroTexture.valid()) { - gl::Error error = ensureTextureExists(mMipLevels); - if (error.isError()) - { - return error; - } + ANGLE_TRY(ensureTextureExists(mMipLevels)); // Pull data back from the level zero texture if necessary. - ASSERT(mTexture); - ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + ASSERT(mTexture.valid()); + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); for (int face = 0; face < 6; face++) { - context->CopySubresourceRegion(mTexture, D3D11CalcSubresource(0, face, mMipLevels), 0, 0, 0, mLevelZeroTexture, face, NULL); + deviceContext->CopySubresourceRegion(mTexture.get(), + D3D11CalcSubresource(0, face, mMipLevels), 0, + 0, 0, mLevelZeroTexture.get(), face, nullptr); } } mUseLevelZeroTexture = false; } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -void TextureStorage11_Cube::associateImage(Image11* image, const gl::ImageIndex &index) +void TextureStorage11_Cube::associateImage(Image11 *image, const gl::ImageIndex &index) { - GLint level = index.mipIndex; - GLint layerTarget = index.layerIndex; + const GLint level = index.mipIndex; + const GLint layerTarget = index.layerIndex; ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); - ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT); + ASSERT(0 <= layerTarget && layerTarget < static_cast(gl::CUBE_FACE_COUNT)); if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) { - if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT) + if (0 <= layerTarget && layerTarget < static_cast(gl::CUBE_FACE_COUNT)) { mAssociatedImages[layerTarget][level] = image; } } } -bool TextureStorage11_Cube::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage) +void TextureStorage11_Cube::verifyAssociatedImageValid(const gl::ImageIndex &index, + Image11 *expectedImage) { - GLint level = index.mipIndex; - GLint layerTarget = index.layerIndex; + const GLint level = index.mipIndex; + const GLint layerTarget = index.layerIndex; - if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) - { - if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT) - { - // This validation check should never return false. It means the Image/TextureStorage association is broken. - bool retValue = (mAssociatedImages[layerTarget][level] == expectedImage); - ASSERT(retValue); - return retValue; - } - } - - return false; + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + ASSERT(0 <= layerTarget && layerTarget < static_cast(gl::CUBE_FACE_COUNT)); + // This validation check should never return false. It means the Image/TextureStorage + // association is broken. + ASSERT(mAssociatedImages[layerTarget][level] == expectedImage); } // disassociateImage allows an Image to end its association with a Storage. -void TextureStorage11_Cube::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage) +void TextureStorage11_Cube::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) { - GLint level = index.mipIndex; - GLint layerTarget = index.layerIndex; + const GLint level = index.mipIndex; + const GLint layerTarget = index.layerIndex; ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); - ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT); - - if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) - { - if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT) - { - ASSERT(mAssociatedImages[layerTarget][level] == expectedImage); - - if (mAssociatedImages[layerTarget][level] == expectedImage) - { - mAssociatedImages[layerTarget][level] = NULL; - } - } - } + ASSERT(0 <= layerTarget && layerTarget < static_cast(gl::CUBE_FACE_COUNT)); + ASSERT(mAssociatedImages[layerTarget][level] == expectedImage); + mAssociatedImages[layerTarget][level] = nullptr; } -// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association. -gl::Error TextureStorage11_Cube::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage) +// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image +// recover its data before ending the association. +gl::Error TextureStorage11_Cube::releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) { - GLint level = index.mipIndex; - GLint layerTarget = index.layerIndex; + const GLint level = index.mipIndex; + const GLint layerTarget = index.layerIndex; ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); - ASSERT(0 <= layerTarget && layerTarget < CUBE_FACE_COUNT); + ASSERT(0 <= layerTarget && layerTarget < static_cast(gl::CUBE_FACE_COUNT)); if ((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)) { - if (0 <= layerTarget && layerTarget < CUBE_FACE_COUNT) + if (0 <= layerTarget && layerTarget < static_cast(gl::CUBE_FACE_COUNT)) { // No need to let the old Image recover its data, if it is also the incoming Image. - if (mAssociatedImages[layerTarget][level] != NULL && mAssociatedImages[layerTarget][level] != incomingImage) + if (mAssociatedImages[layerTarget][level] != nullptr && + mAssociatedImages[layerTarget][level] != incomingImage) { - // Ensure that the Image is still associated with this TextureStorage. This should be true. - bool imageAssociationCorrect = mAssociatedImages[layerTarget][level]->isAssociatedStorageValid(this); - ASSERT(imageAssociationCorrect); + // Ensure that the Image is still associated with this TextureStorage. + mAssociatedImages[layerTarget][level]->verifyAssociatedStorageValid(this); - if (imageAssociationCorrect) - { - // Force the image to recover from storage before its data is overwritten. - // This will reset mAssociatedImages[level] to NULL too. - gl::Error error = mAssociatedImages[layerTarget][level]->recoverFromAssociatedStorage(); - if (error.isError()) - { - return error; - } - } + // Force the image to recover from storage before its data is overwritten. + // This will reset mAssociatedImages[level] to nullptr too. + ANGLE_TRY( + mAssociatedImages[layerTarget][level]->recoverFromAssociatedStorage(context)); } } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage11_Cube::getResource(ID3D11Resource **outResource) +gl::Error TextureStorage11_Cube::getResource(const gl::Context *context, + const TextureHelper11 **outResource) { if (mUseLevelZeroTexture && mMipLevels > 1) { - gl::Error error = ensureTextureExists(1); - if (error.isError()) - { - return error; - } - - *outResource = mLevelZeroTexture; - return gl::Error(GL_NO_ERROR); + ANGLE_TRY(ensureTextureExists(1)); + *outResource = &mLevelZeroTexture; + return gl::NoError(); } else { - gl::Error error = ensureTextureExists(mMipLevels); - if (error.isError()) - { - return error; - } - - *outResource = mTexture; - return gl::Error(GL_NO_ERROR); + ANGLE_TRY(ensureTextureExists(mMipLevels)); + *outResource = &mTexture; + return gl::NoError(); } } -gl::Error TextureStorage11_Cube::getMippedResource(ID3D11Resource **outResource) +gl::Error TextureStorage11_Cube::getMippedResource(const gl::Context *context, + const TextureHelper11 **outResource) { // This shouldn't be called unless the zero max LOD workaround is active. ASSERT(mRenderer->getWorkarounds().zeroMaxLodWorkaround); - gl::Error error = ensureTextureExists(mMipLevels); - if (error.isError()) - { - return error; - } - - *outResource = mTexture; - return gl::Error(GL_NO_ERROR); + ANGLE_TRY(ensureTextureExists(mMipLevels)); + *outResource = &mTexture; + return gl::NoError(); } gl::Error TextureStorage11_Cube::ensureTextureExists(int mipLevels) { // If mMipLevels = 1 then always use mTexture rather than mLevelZeroTexture. - bool useLevelZeroTexture = mRenderer->getWorkarounds().zeroMaxLodWorkaround ? (mipLevels == 1) && (mMipLevels > 1) : false; - ID3D11Texture2D **outputTexture = useLevelZeroTexture ? &mLevelZeroTexture : &mTexture; + bool useLevelZeroTexture = mRenderer->getWorkarounds().zeroMaxLodWorkaround + ? (mipLevels == 1) && (mMipLevels > 1) + : false; + TextureHelper11 *outputTexture = useLevelZeroTexture ? &mLevelZeroTexture : &mTexture; // if the size is not positive this should be treated as an incomplete texture // we handle that here by skipping the d3d texture creation - if (*outputTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0) + if (!outputTexture->valid() && mTextureWidth > 0 && mTextureHeight > 0) { ASSERT(mMipLevels > 0); - ID3D11Device *device = mRenderer->getDevice(); - D3D11_TEXTURE2D_DESC desc; - desc.Width = mTextureWidth; - desc.Height = mTextureHeight; - desc.MipLevels = mipLevels; - desc.ArraySize = CUBE_FACE_COUNT; - desc.Format = mTextureFormat; - desc.SampleDesc.Count = 1; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.MipLevels = mipLevels; + desc.ArraySize = gl::CUBE_FACE_COUNT; + desc.Format = mFormatInfo.texFormat; + desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = getBindFlags(); - desc.CPUAccessFlags = 0; - desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE | getMiscFlags(); + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags(); + desc.CPUAccessFlags = 0; + desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE | getMiscFlags(); - HRESULT result = device->CreateTexture2D(&desc, NULL, outputTexture); - - // this can happen from windows TDR - if (d3d11::isDeviceLostError(result)) - { - mRenderer->notifyDeviceLost(); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create cube texture storage, result: 0x%X.", result); - } - else if (FAILED(result)) - { - ASSERT(result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create cube texture storage, result: 0x%X.", result); - } - - d3d11::SetDebugName(*outputTexture, "TexStorageCube.Texture"); + ANGLE_TRY(mRenderer->allocateTexture(desc, mFormatInfo, outputTexture)); + outputTexture->setDebugName("TexStorageCube.Texture"); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) +gl::Error TextureStorage11_Cube::createRenderTargetSRV(const TextureHelper11 &texture, + const gl::ImageIndex &index, + DXGI_FORMAT resourceFormat, + d3d11::SharedSRV *srv) const { - int faceIndex = index.layerIndex; - int level = index.mipIndex; + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = resourceFormat; + srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + index.mipIndex; + srvDesc.Texture2DArray.MipLevels = 1; + srvDesc.Texture2DArray.FirstArraySlice = index.layerIndex; + srvDesc.Texture2DArray.ArraySize = 1; + + if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_10_0) + { + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; + } + else + { + // Will be used with Texture2D sampler, not TextureCube + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + } + + ANGLE_TRY(mRenderer->allocateResource(srvDesc, texture.get(), srv)); + return gl::NoError(); +} + +gl::Error TextureStorage11_Cube::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) +{ + const int faceIndex = index.layerIndex; + const int level = index.mipIndex; ASSERT(level >= 0 && level < getLevelCount()); - ASSERT(faceIndex >= 0 && faceIndex < CUBE_FACE_COUNT); + ASSERT(faceIndex >= 0 && faceIndex < static_cast(gl::CUBE_FACE_COUNT)); if (!mRenderTarget[faceIndex][level]) { - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result; - - ID3D11Resource *texture = NULL; - gl::Error error = getResource(&texture); - if (error.isError()) + if (mRenderer->getWorkarounds().zeroMaxLodWorkaround) { - return error; + ASSERT(index.mipIndex == 0); + ANGLE_TRY(useLevelZeroWorkaroundTexture(context, true)); } + const TextureHelper11 *texture = nullptr; + ANGLE_TRY(getResource(context, &texture)); + if (mUseLevelZeroTexture) { if (!mLevelZeroRenderTarget[faceIndex]) { D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - rtvDesc.Texture2DArray.MipSlice = mTopLevel + level; + rtvDesc.Format = mFormatInfo.rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = mTopLevel + level; rtvDesc.Texture2DArray.FirstArraySlice = faceIndex; - rtvDesc.Texture2DArray.ArraySize = 1; + rtvDesc.Texture2DArray.ArraySize = 1; - ID3D11RenderTargetView *rtv; - result = device->CreateRenderTargetView(mLevelZeroTexture, &rtvDesc, &rtv); + d3d11::RenderTargetView rtv; + ANGLE_TRY(mRenderer->allocateResource(rtvDesc, mLevelZeroTexture.get(), &rtv)); - if (result == E_OUTOFMEMORY) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); - } - ASSERT(SUCCEEDED(result)); - - mLevelZeroRenderTarget[faceIndex] = new TextureRenderTarget11(rtv, mLevelZeroTexture, NULL, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0); - - // RenderTarget will take ownership of these resources - SafeRelease(rtv); + mLevelZeroRenderTarget[faceIndex].reset(new TextureRenderTarget11( + std::move(rtv), mLevelZeroTexture, d3d11::SharedSRV(), d3d11::SharedSRV(), + mFormatInfo.internalFormat, getFormatSet(), getLevelWidth(level), + getLevelHeight(level), 1, 0)); } ASSERT(outRT); - *outRT = mLevelZeroRenderTarget[faceIndex]; - return gl::Error(GL_NO_ERROR); + *outRT = mLevelZeroRenderTarget[faceIndex].get(); + return gl::NoError(); } - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = mShaderResourceFormat; - srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level; - srvDesc.Texture2DArray.MipLevels = 1; - srvDesc.Texture2DArray.FirstArraySlice = faceIndex; - srvDesc.Texture2DArray.ArraySize = 1; - - if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3) + d3d11::SharedSRV srv; + ANGLE_TRY(createRenderTargetSRV(*texture, index, mFormatInfo.srvFormat, &srv)); + d3d11::SharedSRV blitSRV; + if (mFormatInfo.blitSRVFormat != mFormatInfo.srvFormat) { - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; + ANGLE_TRY(createRenderTargetSRV(*texture, index, mFormatInfo.blitSRVFormat, &blitSRV)); } else { - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; // Will be used with Texture2D sampler, not TextureCube + blitSRV = srv.makeCopy(); } - ID3D11ShaderResourceView *srv; - result = device->CreateShaderResourceView(texture, &srvDesc, &srv); + srv.setDebugName("TexStorageCube.RenderTargetSRV"); - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal shader resource view for texture storage, result: 0x%X.", result); - } - - d3d11::SetDebugName(srv, "TexStorageCube.RenderTargetSRV"); - - if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) + if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN) { D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - rtvDesc.Texture2DArray.MipSlice = mTopLevel + level; + rtvDesc.Format = mFormatInfo.rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = mTopLevel + level; rtvDesc.Texture2DArray.FirstArraySlice = faceIndex; - rtvDesc.Texture2DArray.ArraySize = 1; + rtvDesc.Texture2DArray.ArraySize = 1; - ID3D11RenderTargetView *rtv; - result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv); + d3d11::RenderTargetView rtv; + ANGLE_TRY(mRenderer->allocateResource(rtvDesc, texture->get(), &rtv)); + rtv.setDebugName("TexStorageCube.RenderTargetRTV"); - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) - { - SafeRelease(srv); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); - } - - d3d11::SetDebugName(rtv, "TexStorageCube.RenderTargetRTV"); - - mRenderTarget[faceIndex][level] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0); - - // RenderTarget will take ownership of these resources - SafeRelease(rtv); - SafeRelease(srv); + mRenderTarget[faceIndex][level].reset(new TextureRenderTarget11( + std::move(rtv), *texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(), + getLevelWidth(level), getLevelHeight(level), 1, 0)); } - else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN) + else if (mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN) { D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsvDesc.Format = mDepthStencilFormat; - dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; - dsvDesc.Flags = 0; - dsvDesc.Texture2DArray.MipSlice = mTopLevel + level; + dsvDesc.Format = mFormatInfo.dsvFormat; + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; + dsvDesc.Flags = 0; + dsvDesc.Texture2DArray.MipSlice = mTopLevel + level; dsvDesc.Texture2DArray.FirstArraySlice = faceIndex; - dsvDesc.Texture2DArray.ArraySize = 1; + dsvDesc.Texture2DArray.ArraySize = 1; - ID3D11DepthStencilView *dsv; - result = device->CreateDepthStencilView(texture, &dsvDesc, &dsv); + d3d11::DepthStencilView dsv; + ANGLE_TRY(mRenderer->allocateResource(dsvDesc, texture->get(), &dsv)); + dsv.setDebugName("TexStorageCube.RenderTargetDSV"); - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) - { - SafeRelease(srv); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal depth stencil view for texture storage, result: 0x%X.", result); - } - - d3d11::SetDebugName(dsv, "TexStorageCube.RenderTargetDSV"); - - mRenderTarget[faceIndex][level] = new TextureRenderTarget11(dsv, texture, srv, mInternalFormat, getLevelWidth(level), getLevelHeight(level), 1, 0); - - // RenderTarget will take ownership of these resources - SafeRelease(dsv); - SafeRelease(srv); + mRenderTarget[faceIndex][level].reset(new TextureRenderTarget11( + std::move(dsv), *texture, srv, mFormatInfo.internalFormat, getFormatSet(), + getLevelWidth(level), getLevelHeight(level), 1, 0)); } else { @@ -2239,215 +2120,237 @@ gl::Error TextureStorage11_Cube::getRenderTarget(const gl::ImageIndex &index, Re } ASSERT(outRT); - *outRT = mRenderTarget[faceIndex][level]; - return gl::Error(GL_NO_ERROR); + *outRT = mRenderTarget[faceIndex][level].get(); + return gl::NoError(); } -gl::Error TextureStorage11_Cube::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, - ID3D11ShaderResourceView **outSRV) const +gl::Error TextureStorage11_Cube::createSRV(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) { ASSERT(outSRV); D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.Format = format; - // Unnormalized integer cube maps are not supported by DX11; we emulate them as an array of six 2D textures - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(format); - if (dxgiFormatInfo.componentType == GL_INT || dxgiFormatInfo.componentType == GL_UNSIGNED_INT) + // Unnormalized integer cube maps are not supported by DX11; we emulate them as an array of six + // 2D textures + const GLenum componentType = d3d11::GetComponentType(format); + if (componentType == GL_INT || componentType == GL_UNSIGNED_INT) { - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel; srvDesc.Texture2DArray.MipLevels = mipLevels; srvDesc.Texture2DArray.FirstArraySlice = 0; - srvDesc.Texture2DArray.ArraySize = CUBE_FACE_COUNT; + srvDesc.Texture2DArray.ArraySize = gl::CUBE_FACE_COUNT; } else { - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; - srvDesc.TextureCube.MipLevels = mipLevels; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; + srvDesc.TextureCube.MipLevels = mipLevels; srvDesc.TextureCube.MostDetailedMip = mTopLevel + baseLevel; } - ID3D11Resource *srvTexture = texture; + const TextureHelper11 *srvTexture = &texture; if (mRenderer->getWorkarounds().zeroMaxLodWorkaround) { ASSERT(mTopLevel == 0); ASSERT(baseLevel == 0); - // This code also assumes that the incoming texture equals either mLevelZeroTexture or mTexture. + // This code also assumes that the incoming texture equals either mLevelZeroTexture or + // mTexture. if (mipLevels == 1 && mMipLevels > 1) { // We must use a SRV on the level-zero-only texture. - ASSERT(mLevelZeroTexture != NULL && texture == mLevelZeroTexture); - srvTexture = mLevelZeroTexture; + ANGLE_TRY(ensureTextureExists(1)); + srvTexture = &mLevelZeroTexture; } else { ASSERT(mipLevels == static_cast(mMipLevels)); - ASSERT(mTexture != NULL && texture == mTexture); - srvTexture = mTexture; + ASSERT(mTexture.valid() && texture == mTexture); + srvTexture = &mTexture; } } - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result = device->CreateShaderResourceView(srvTexture, &srvDesc, outSRV); + ANGLE_TRY(mRenderer->allocateResource(srvDesc, srvTexture->get(), outSRV)); + outSRV->setDebugName("TexStorageCube.SRV"); - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result); - } - - d3d11::SetDebugName(*outSRV, "TexStorageCube.SRV"); - - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage11_Cube::getSwizzleTexture(ID3D11Resource **outTexture) +gl::Error TextureStorage11_Cube::getSwizzleTexture(const TextureHelper11 **outTexture) { ASSERT(outTexture); - if (!mSwizzleTexture) + if (!mSwizzleTexture.valid()) { - ID3D11Device *device = mRenderer->getDevice(); + const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()); D3D11_TEXTURE2D_DESC desc; - desc.Width = mTextureWidth; - desc.Height = mTextureHeight; - desc.MipLevels = mMipLevels; - desc.ArraySize = CUBE_FACE_COUNT; - desc.Format = mSwizzleTextureFormat; - desc.SampleDesc.Count = 1; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.MipLevels = mMipLevels; + desc.ArraySize = gl::CUBE_FACE_COUNT; + desc.Format = format.texFormat; + desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; - desc.CPUAccessFlags = 0; - desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + desc.CPUAccessFlags = 0; + desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; - HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture); - - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result); - } - - d3d11::SetDebugName(*outTexture, "TexStorageCube.SwizzleTexture"); + ANGLE_TRY(mRenderer->allocateTexture(desc, format, &mSwizzleTexture)); + mSwizzleTexture.setDebugName("TexStorageCube.SwizzleTexture"); } - *outTexture = mSwizzleTexture; - return gl::Error(GL_NO_ERROR); + *outTexture = &mSwizzleTexture; + return gl::NoError(); } -gl::Error TextureStorage11_Cube::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) +gl::Error TextureStorage11_Cube::getSwizzleRenderTarget(int mipLevel, + const d3d11::RenderTargetView **outRTV) { ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); ASSERT(outRTV); - if (!mSwizzleRenderTargets[mipLevel]) + if (!mSwizzleRenderTargets[mipLevel].valid()) { - ID3D11Resource *swizzleTexture = NULL; - gl::Error error = getSwizzleTexture(&swizzleTexture); - if (error.isError()) - { - return error; - } - - ID3D11Device *device = mRenderer->getDevice(); + const TextureHelper11 *swizzleTexture = nullptr; + ANGLE_TRY(getSwizzleTexture(&swizzleTexture)); D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mSwizzleRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; + rtvDesc.Format = + mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; rtvDesc.Texture2DArray.FirstArraySlice = 0; - rtvDesc.Texture2DArray.ArraySize = CUBE_FACE_COUNT; + rtvDesc.Texture2DArray.ArraySize = gl::CUBE_FACE_COUNT; - HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); + ANGLE_TRY(mRenderer->allocateResource(rtvDesc, mSwizzleTexture.get(), + &mSwizzleRenderTargets[mipLevel])); + } - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) + *outRTV = &mSwizzleRenderTargets[mipLevel]; + return gl::NoError(); +} + +gl::Error TextureStorage11::initDropStencilTexture(const gl::Context *context, + const gl::ImageIndexIterator &it) +{ + const TextureHelper11 *sourceTexture = nullptr; + ANGLE_TRY(getResource(context, &sourceTexture)); + + gl::ImageIndexIterator itCopy = it; + + while (itCopy.hasNext()) + { + gl::ImageIndex index = itCopy.next(); + gl::Box wholeArea(0, 0, 0, getLevelWidth(index.mipIndex), getLevelHeight(index.mipIndex), + 1); + gl::Extents wholeSize(wholeArea.width, wholeArea.height, 1); + UINT subresource = getSubresourceIndex(index); + ANGLE_TRY(mRenderer->getBlitter()->copyDepthStencil( + *sourceTexture, subresource, wholeArea, wholeSize, mDropStencilTexture, subresource, + wholeArea, wholeSize, nullptr)); + } + + return gl::NoError(); +} + +gl::ErrorOrResult TextureStorage11_Cube::ensureDropStencilTexture( + const gl::Context *context) +{ + if (mDropStencilTexture.valid()) + { + return DropStencil::ALREADY_EXISTS; + } + + D3D11_TEXTURE2D_DESC dropDesc = {}; + dropDesc.ArraySize = 6; + dropDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL; + dropDesc.CPUAccessFlags = 0; + dropDesc.Format = DXGI_FORMAT_R32_TYPELESS; + dropDesc.Height = mTextureHeight; + dropDesc.MipLevels = mMipLevels; + dropDesc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; + dropDesc.SampleDesc.Count = 1; + dropDesc.SampleDesc.Quality = 0; + dropDesc.Usage = D3D11_USAGE_DEFAULT; + dropDesc.Width = mTextureWidth; + + const auto &format = + d3d11::Format::Get(GL_DEPTH_COMPONENT32F, mRenderer->getRenderer11DeviceCaps()); + ANGLE_TRY(mRenderer->allocateTexture(dropDesc, format, &mDropStencilTexture)); + mDropStencilTexture.setDebugName("TexStorageCube.DropStencil"); + + ANGLE_TRY(initDropStencilTexture(context, gl::ImageIndexIterator::MakeCube(0, mMipLevels))); + + return DropStencil::CREATED; +} + +TextureStorage11_3D::TextureStorage11_3D(Renderer11 *renderer, + GLenum internalformat, + bool renderTarget, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels) + : TextureStorage11( + renderer, + GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget), + GetTextureMiscFlags(internalformat, + renderer->getRenderer11DeviceCaps(), + renderTarget, + levels), + internalformat) +{ + for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + { + mAssociatedImages[i] = nullptr; + mLevelRenderTargets[i] = nullptr; + } + + // adjust size if needed for compressed textures + d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, &mTopLevel); + + mMipLevels = mTopLevel + levels; + mTextureWidth = width; + mTextureHeight = height; + mTextureDepth = depth; +} + +gl::Error TextureStorage11_3D::onDestroy(const gl::Context *context) +{ + for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + { + if (mAssociatedImages[i] != nullptr) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result); + mAssociatedImages[i]->verifyAssociatedStorageValid(this); + + // We must let the Images recover their data before we delete it from the + // TextureStorage. + ANGLE_TRY(mAssociatedImages[i]->recoverFromAssociatedStorage(context)); } } - *outRTV = mSwizzleRenderTargets[mipLevel]; - return gl::Error(GL_NO_ERROR); -} + InvalidateRenderTargetContainer(context, &mLevelRenderTargets); + InvalidateRenderTargetContainer(context, &mLevelLayerRenderTargets); -TextureStorage11_3D::TextureStorage11_3D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, - GLsizei width, GLsizei height, GLsizei depth, int levels) - : TextureStorage11(renderer, - GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget), - GetTextureMiscFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget, levels)) -{ - mTexture = NULL; - mSwizzleTexture = NULL; - - for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) - { - mAssociatedImages[i] = NULL; - mLevelRenderTargets[i] = NULL; - mSwizzleRenderTargets[i] = NULL; - } - - mInternalFormat = internalformat; - - const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat, renderer->getRenderer11DeviceCaps()); - mTextureFormat = formatInfo.texFormat; - mShaderResourceFormat = formatInfo.srvFormat; - mDepthStencilFormat = formatInfo.dsvFormat; - mRenderTargetFormat = formatInfo.rtvFormat; - mSwizzleTextureFormat = formatInfo.swizzleTexFormat; - mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat; - mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat; - - // adjust size if needed for compressed textures - d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel); - - mMipLevels = mTopLevel + levels; - mTextureWidth = width; - mTextureHeight = height; - mTextureDepth = depth; + return gl::NoError(); } TextureStorage11_3D::~TextureStorage11_3D() { - for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) - { - if (mAssociatedImages[i] != NULL) - { - bool imageAssociationCorrect = mAssociatedImages[i]->isAssociatedStorageValid(this); - ASSERT(imageAssociationCorrect); - - if (imageAssociationCorrect) - { - // We must let the Images recover their data before we delete it from the TextureStorage. - mAssociatedImages[i]->recoverFromAssociatedStorage(); - } - } - } - - SafeRelease(mTexture); - SafeRelease(mSwizzleTexture); - - for (RenderTargetMap::iterator i = mLevelLayerRenderTargets.begin(); i != mLevelLayerRenderTargets.end(); i++) - { - SafeDelete(i->second); - } - mLevelLayerRenderTargets.clear(); - - for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) - { - SafeDelete(mLevelRenderTargets[i]); - SafeRelease(mSwizzleRenderTargets[i]); - } } -void TextureStorage11_3D::associateImage(Image11* image, const gl::ImageIndex &index) +void TextureStorage11_3D::associateImage(Image11 *image, const gl::ImageIndex &index) { - GLint level = index.mipIndex; + const GLint level = index.mipIndex; ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); @@ -2457,676 +2360,796 @@ void TextureStorage11_3D::associateImage(Image11* image, const gl::ImageIndex &i } } -bool TextureStorage11_3D::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage) +void TextureStorage11_3D::verifyAssociatedImageValid(const gl::ImageIndex &index, + Image11 *expectedImage) { - GLint level = index.mipIndex; + const GLint level = index.mipIndex; - if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) - { - // This validation check should never return false. It means the Image/TextureStorage association is broken. - bool retValue = (mAssociatedImages[level] == expectedImage); - ASSERT(retValue); - return retValue; - } - - return false; + ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); + // This validation check should never return false. It means the Image/TextureStorage + // association is broken. + ASSERT(mAssociatedImages[level] == expectedImage); } // disassociateImage allows an Image to end its association with a Storage. -void TextureStorage11_3D::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage) +void TextureStorage11_3D::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) { - GLint level = index.mipIndex; + const GLint level = index.mipIndex; ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS); - - if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) - { - ASSERT(mAssociatedImages[level] == expectedImage); - - if (mAssociatedImages[level] == expectedImage) - { - mAssociatedImages[level] = NULL; - } - } + ASSERT(mAssociatedImages[level] == expectedImage); + mAssociatedImages[level] = nullptr; } -// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association. -gl::Error TextureStorage11_3D::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage) +// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image +// recover its data before ending the association. +gl::Error TextureStorage11_3D::releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) { - GLint level = index.mipIndex; + const GLint level = index.mipIndex; ASSERT((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)); if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) { // No need to let the old Image recover its data, if it is also the incoming Image. - if (mAssociatedImages[level] != NULL && mAssociatedImages[level] != incomingImage) + if (mAssociatedImages[level] != nullptr && mAssociatedImages[level] != incomingImage) { - // Ensure that the Image is still associated with this TextureStorage. This should be true. - bool imageAssociationCorrect = mAssociatedImages[level]->isAssociatedStorageValid(this); - ASSERT(imageAssociationCorrect); + // Ensure that the Image is still associated with this TextureStorage. + mAssociatedImages[level]->verifyAssociatedStorageValid(this); - if (imageAssociationCorrect) - { - // Force the image to recover from storage before its data is overwritten. - // This will reset mAssociatedImages[level] to NULL too. - gl::Error error = mAssociatedImages[level]->recoverFromAssociatedStorage(); - if (error.isError()) - { - return error; - } - } + // Force the image to recover from storage before its data is overwritten. + // This will reset mAssociatedImages[level] to nullptr too. + ANGLE_TRY(mAssociatedImages[level]->recoverFromAssociatedStorage(context)); } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage11_3D::getResource(ID3D11Resource **outResource) +gl::Error TextureStorage11_3D::getResource(const gl::Context *context, + const TextureHelper11 **outResource) { - // If the width, height or depth are not positive this should be treated as an incomplete texture - // we handle that here by skipping the d3d texture creation - if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0) + // If the width, height or depth are not positive this should be treated as an incomplete + // texture. We handle that here by skipping the d3d texture creation. + if (!mTexture.valid() && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0) { ASSERT(mMipLevels > 0); - ID3D11Device *device = mRenderer->getDevice(); - D3D11_TEXTURE3D_DESC desc; - desc.Width = mTextureWidth; - desc.Height = mTextureHeight; - desc.Depth = mTextureDepth; - desc.MipLevels = mMipLevels; - desc.Format = mTextureFormat; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = getBindFlags(); + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.Depth = mTextureDepth; + desc.MipLevels = mMipLevels; + desc.Format = mFormatInfo.texFormat; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags(); desc.CPUAccessFlags = 0; - desc.MiscFlags = getMiscFlags(); + desc.MiscFlags = getMiscFlags(); - HRESULT result = device->CreateTexture3D(&desc, NULL, &mTexture); - - // this can happen from windows TDR - if (d3d11::isDeviceLostError(result)) - { - mRenderer->notifyDeviceLost(); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 3D texture storage, result: 0x%X.", result); - } - else if (FAILED(result)) - { - ASSERT(result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 3D texture storage, result: 0x%X.", result); - } - - d3d11::SetDebugName(mTexture, "TexStorage3D.Texture"); + ANGLE_TRY(mRenderer->allocateTexture(desc, mFormatInfo, &mTexture)); + mTexture.setDebugName("TexStorage3D.Texture"); } - *outResource = mTexture; - return gl::Error(GL_NO_ERROR); + *outResource = &mTexture; + return gl::NoError(); } -gl::Error TextureStorage11_3D::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, - ID3D11ShaderResourceView **outSRV) const +gl::Error TextureStorage11_3D::createSRV(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) { ASSERT(outSRV); D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = format; - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; + srvDesc.Format = format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; srvDesc.Texture3D.MostDetailedMip = baseLevel; - srvDesc.Texture3D.MipLevels = mipLevels; + srvDesc.Texture3D.MipLevels = mipLevels; - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV); + ANGLE_TRY(mRenderer->allocateResource(srvDesc, texture.get(), outSRV)); + outSRV->setDebugName("TexStorage3D.SRV"); - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result); - } - - d3d11::SetDebugName(*outSRV, "TexStorage3D.SRV"); - - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage11_3D::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) +gl::Error TextureStorage11_3D::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) { - int mipLevel = index.mipIndex; + const int mipLevel = index.mipIndex; ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); - ASSERT(mRenderTargetFormat != DXGI_FORMAT_UNKNOWN); + ASSERT(mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN); if (!index.hasLayer()) { if (!mLevelRenderTargets[mipLevel]) { - ID3D11Resource *texture = NULL; - gl::Error error = getResource(&texture); - if (error.isError()) - { - return error; - } + const TextureHelper11 *texture = nullptr; + ANGLE_TRY(getResource(context, &texture)); - ID3D11ShaderResourceView *srv = NULL; - error = getSRVLevel(mipLevel, &srv); - if (error.isError()) - { - return error; - } + const d3d11::SharedSRV *srv = nullptr; + ANGLE_TRY(getSRVLevel(context, mipLevel, false, &srv)); - ID3D11Device *device = mRenderer->getDevice(); + const d3d11::SharedSRV *blitSRV = nullptr; + ANGLE_TRY(getSRVLevel(context, mipLevel, true, &blitSRV)); D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; - rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; + rtvDesc.Format = mFormatInfo.rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; rtvDesc.Texture3D.FirstWSlice = 0; - rtvDesc.Texture3D.WSize = static_cast(-1); + rtvDesc.Texture3D.WSize = static_cast(-1); - ID3D11RenderTargetView *rtv; - HRESULT result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv); + d3d11::RenderTargetView rtv; + ANGLE_TRY(mRenderer->allocateResource(rtvDesc, texture->get(), &rtv)); + rtv.setDebugName("TexStorage3D.RTV"); - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) - { - SafeRelease(srv); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); - } - - d3d11::SetDebugName(rtv, "TexStorage3D.RTV"); - - mLevelRenderTargets[mipLevel] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(mipLevel), getLevelHeight(mipLevel), getLevelDepth(mipLevel), 0); - - // RenderTarget will take ownership of these resources - SafeRelease(rtv); + mLevelRenderTargets[mipLevel].reset(new TextureRenderTarget11( + std::move(rtv), *texture, *srv, *blitSRV, mFormatInfo.internalFormat, + getFormatSet(), getLevelWidth(mipLevel), getLevelHeight(mipLevel), + getLevelDepth(mipLevel), 0)); } ASSERT(outRT); - *outRT = mLevelRenderTargets[mipLevel]; - return gl::Error(GL_NO_ERROR); + *outRT = mLevelRenderTargets[mipLevel].get(); + return gl::NoError(); } - else + + const int layer = index.layerIndex; + + LevelLayerKey key(mipLevel, layer); + if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end()) { - int layer = index.layerIndex; + const TextureHelper11 *texture = nullptr; + ANGLE_TRY(getResource(context, &texture)); - LevelLayerKey key(mipLevel, layer); - if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end()) - { - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result; + // TODO, what kind of SRV is expected here? + const d3d11::SharedSRV srv; + const d3d11::SharedSRV blitSRV; - ID3D11Resource *texture = NULL; - gl::Error error = getResource(&texture); - if (error.isError()) - { - return error; - } + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mFormatInfo.rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; + rtvDesc.Texture3D.FirstWSlice = layer; + rtvDesc.Texture3D.WSize = 1; - // TODO, what kind of SRV is expected here? - ID3D11ShaderResourceView *srv = NULL; + d3d11::RenderTargetView rtv; + ANGLE_TRY(mRenderer->allocateResource(rtvDesc, texture->get(), &rtv)); + rtv.setDebugName("TexStorage3D.LayerRTV"); - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; - rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; - rtvDesc.Texture3D.FirstWSlice = layer; - rtvDesc.Texture3D.WSize = 1; - - ID3D11RenderTargetView *rtv; - result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv); - - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) - { - SafeRelease(srv); return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); - } - ASSERT(SUCCEEDED(result)); - - d3d11::SetDebugName(rtv, "TexStorage3D.LayerRTV"); - - mLevelLayerRenderTargets[key] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0); - - // RenderTarget will take ownership of these resources - SafeRelease(rtv); - } - - ASSERT(outRT); - *outRT = mLevelLayerRenderTargets[key]; - return gl::Error(GL_NO_ERROR); + mLevelLayerRenderTargets[key].reset(new TextureRenderTarget11( + std::move(rtv), *texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(), + getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0)); } + + ASSERT(outRT); + *outRT = mLevelLayerRenderTargets[key].get(); + return gl::NoError(); } -gl::Error TextureStorage11_3D::getSwizzleTexture(ID3D11Resource **outTexture) +gl::Error TextureStorage11_3D::getSwizzleTexture(const TextureHelper11 **outTexture) { ASSERT(outTexture); - if (!mSwizzleTexture) + if (!mSwizzleTexture.valid()) { - ID3D11Device *device = mRenderer->getDevice(); + const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()); D3D11_TEXTURE3D_DESC desc; - desc.Width = mTextureWidth; - desc.Height = mTextureHeight; - desc.Depth = mTextureDepth; - desc.MipLevels = mMipLevels; - desc.Format = mSwizzleTextureFormat; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.Depth = mTextureDepth; + desc.MipLevels = mMipLevels; + desc.Format = format.texFormat; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; + desc.MiscFlags = 0; - HRESULT result = device->CreateTexture3D(&desc, NULL, &mSwizzleTexture); - - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result); - } - - d3d11::SetDebugName(mSwizzleTexture, "TexStorage3D.SwizzleTexture"); + ANGLE_TRY(mRenderer->allocateTexture(desc, format, &mSwizzleTexture)); + mSwizzleTexture.setDebugName("TexStorage3D.SwizzleTexture"); } - *outTexture = mSwizzleTexture; - return gl::Error(GL_NO_ERROR); + *outTexture = &mSwizzleTexture; + return gl::NoError(); } -gl::Error TextureStorage11_3D::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) +gl::Error TextureStorage11_3D::getSwizzleRenderTarget(int mipLevel, + const d3d11::RenderTargetView **outRTV) { ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); ASSERT(outRTV); - if (!mSwizzleRenderTargets[mipLevel]) + if (!mSwizzleRenderTargets[mipLevel].valid()) { - ID3D11Resource *swizzleTexture = NULL; - gl::Error error = getSwizzleTexture(&swizzleTexture); - if (error.isError()) - { - return error; - } - - ID3D11Device *device = mRenderer->getDevice(); + const TextureHelper11 *swizzleTexture = nullptr; + ANGLE_TRY(getSwizzleTexture(&swizzleTexture)); D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mSwizzleRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; - rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; + rtvDesc.Format = + mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel; rtvDesc.Texture3D.FirstWSlice = 0; - rtvDesc.Texture3D.WSize = static_cast(-1); + rtvDesc.Texture3D.WSize = static_cast(-1); - HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); - - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result); - } - - d3d11::SetDebugName(mSwizzleTexture, "TexStorage3D.SwizzleRTV"); + ANGLE_TRY(mRenderer->allocateResource(rtvDesc, mSwizzleTexture.get(), + &mSwizzleRenderTargets[mipLevel])); + mSwizzleRenderTargets[mipLevel].setDebugName("TexStorage3D.SwizzleRTV"); } - *outRTV = mSwizzleRenderTargets[mipLevel]; - return gl::Error(GL_NO_ERROR); + *outRTV = &mSwizzleRenderTargets[mipLevel]; + return gl::NoError(); } -TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer11 *renderer, GLenum internalformat, bool renderTarget, - GLsizei width, GLsizei height, GLsizei depth, int levels) - : TextureStorage11(renderer, - GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget), - GetTextureMiscFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget, levels)) +TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer11 *renderer, + GLenum internalformat, + bool renderTarget, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels) + : TextureStorage11( + renderer, + GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget), + GetTextureMiscFlags(internalformat, + renderer->getRenderer11DeviceCaps(), + renderTarget, + levels), + internalformat) { - mTexture = NULL; - mSwizzleTexture = NULL; - - for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) - { - mSwizzleRenderTargets[level] = NULL; - } - - mInternalFormat = internalformat; - - const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalformat, renderer->getRenderer11DeviceCaps()); - mTextureFormat = formatInfo.texFormat; - mShaderResourceFormat = formatInfo.srvFormat; - mDepthStencilFormat = formatInfo.dsvFormat; - mRenderTargetFormat = formatInfo.rtvFormat; - mSwizzleTextureFormat = formatInfo.swizzleTexFormat; - mSwizzleShaderResourceFormat = formatInfo.swizzleSRVFormat; - mSwizzleRenderTargetFormat = formatInfo.swizzleRTVFormat; - // adjust size if needed for compressed textures - d3d11::MakeValidSize(false, mTextureFormat, &width, &height, &mTopLevel); + d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, &mTopLevel); - mMipLevels = mTopLevel + levels; - mTextureWidth = width; + mMipLevels = mTopLevel + levels; + mTextureWidth = width; mTextureHeight = height; - mTextureDepth = depth; + mTextureDepth = depth; } -TextureStorage11_2DArray::~TextureStorage11_2DArray() +gl::Error TextureStorage11_2DArray::onDestroy(const gl::Context *context) { - for (ImageMap::iterator i = mAssociatedImages.begin(); i != mAssociatedImages.end(); i++) + for (auto iter : mAssociatedImages) { - if (i->second) + if (iter.second) { - bool imageAssociationCorrect = i->second->isAssociatedStorageValid(this); - ASSERT(imageAssociationCorrect); + iter.second->verifyAssociatedStorageValid(this); - if (imageAssociationCorrect) - { - // We must let the Images recover their data before we delete it from the TextureStorage. - i->second->recoverFromAssociatedStorage(); - } + // We must let the Images recover their data before we delete it from the + // TextureStorage. + ANGLE_TRY(iter.second->recoverFromAssociatedStorage(context)); } } mAssociatedImages.clear(); - SafeRelease(mTexture); - SafeRelease(mSwizzleTexture); + InvalidateRenderTargetContainer(context, &mRenderTargets); - for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) - { - SafeRelease(mSwizzleRenderTargets[level]); - } - - for (RenderTargetMap::iterator i = mRenderTargets.begin(); i != mRenderTargets.end(); i++) - { - SafeDelete(i->second); - } - mRenderTargets.clear(); + return gl::NoError(); } -void TextureStorage11_2DArray::associateImage(Image11* image, const gl::ImageIndex &index) +TextureStorage11_2DArray::~TextureStorage11_2DArray() { - GLint level = index.mipIndex; - GLint layerTarget = index.layerIndex; +} + +void TextureStorage11_2DArray::associateImage(Image11 *image, const gl::ImageIndex &index) +{ + const GLint level = index.mipIndex; + const GLint layerTarget = index.layerIndex; + const GLint numLayers = index.numLayers; ASSERT(0 <= level && level < getLevelCount()); if (0 <= level && level < getLevelCount()) { - LevelLayerKey key(level, layerTarget); + LevelLayerRangeKey key(level, layerTarget, numLayers); mAssociatedImages[key] = image; } } -bool TextureStorage11_2DArray::isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage) +void TextureStorage11_2DArray::verifyAssociatedImageValid(const gl::ImageIndex &index, + Image11 *expectedImage) { - GLint level = index.mipIndex; - GLint layerTarget = index.layerIndex; + const GLint level = index.mipIndex; + const GLint layerTarget = index.layerIndex; + const GLint numLayers = index.numLayers; - LevelLayerKey key(level, layerTarget); + LevelLayerRangeKey key(level, layerTarget, numLayers); - // This validation check should never return false. It means the Image/TextureStorage association is broken. - bool retValue = (mAssociatedImages.find(key) != mAssociatedImages.end() && (mAssociatedImages[key] == expectedImage)); + // This validation check should never return false. It means the Image/TextureStorage + // association is broken. + bool retValue = (mAssociatedImages.find(key) != mAssociatedImages.end() && + (mAssociatedImages[key] == expectedImage)); ASSERT(retValue); - return retValue; } // disassociateImage allows an Image to end its association with a Storage. -void TextureStorage11_2DArray::disassociateImage(const gl::ImageIndex &index, Image11* expectedImage) +void TextureStorage11_2DArray::disassociateImage(const gl::ImageIndex &index, + Image11 *expectedImage) { - GLint level = index.mipIndex; - GLint layerTarget = index.layerIndex; + const GLint level = index.mipIndex; + const GLint layerTarget = index.layerIndex; + const GLint numLayers = index.numLayers; - LevelLayerKey key(level, layerTarget); + LevelLayerRangeKey key(level, layerTarget, numLayers); - bool imageAssociationCorrect = (mAssociatedImages.find(key) != mAssociatedImages.end() && (mAssociatedImages[key] == expectedImage)); + bool imageAssociationCorrect = (mAssociatedImages.find(key) != mAssociatedImages.end() && + (mAssociatedImages[key] == expectedImage)); ASSERT(imageAssociationCorrect); - - if (imageAssociationCorrect) - { - mAssociatedImages[key] = NULL; - } + mAssociatedImages[key] = nullptr; } -// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image recover its data before ending the association. -gl::Error TextureStorage11_2DArray::releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage) +// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image +// recover its data before ending the association. +gl::Error TextureStorage11_2DArray::releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) { - GLint level = index.mipIndex; - GLint layerTarget = index.layerIndex; + const GLint level = index.mipIndex; + const GLint layerTarget = index.layerIndex; + const GLint numLayers = index.numLayers; - LevelLayerKey key(level, layerTarget); + LevelLayerRangeKey key(level, layerTarget, numLayers); if (mAssociatedImages.find(key) != mAssociatedImages.end()) { - if (mAssociatedImages[key] != NULL && mAssociatedImages[key] != incomingImage) + if (mAssociatedImages[key] != nullptr && mAssociatedImages[key] != incomingImage) { - // Ensure that the Image is still associated with this TextureStorage. This should be true. - bool imageAssociationCorrect = mAssociatedImages[key]->isAssociatedStorageValid(this); - ASSERT(imageAssociationCorrect); + // Ensure that the Image is still associated with this TextureStorage. + mAssociatedImages[key]->verifyAssociatedStorageValid(this); - if (imageAssociationCorrect) - { - // Force the image to recover from storage before its data is overwritten. - // This will reset mAssociatedImages[level] to NULL too. - gl::Error error = mAssociatedImages[key]->recoverFromAssociatedStorage(); - if (error.isError()) - { - return error; - } - } + // Force the image to recover from storage before its data is overwritten. + // This will reset mAssociatedImages[level] to nullptr too. + ANGLE_TRY(mAssociatedImages[key]->recoverFromAssociatedStorage(context)); } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage11_2DArray::getResource(ID3D11Resource **outResource) +gl::Error TextureStorage11_2DArray::getResource(const gl::Context *context, + const TextureHelper11 **outResource) { // if the width, height or depth is not positive this should be treated as an incomplete texture // we handle that here by skipping the d3d texture creation - if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0) + if (!mTexture.valid() && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0) { ASSERT(mMipLevels > 0); - ID3D11Device *device = mRenderer->getDevice(); - D3D11_TEXTURE2D_DESC desc; - desc.Width = mTextureWidth; - desc.Height = mTextureHeight; - desc.MipLevels = mMipLevels; - desc.ArraySize = mTextureDepth; - desc.Format = mTextureFormat; - desc.SampleDesc.Count = 1; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.MipLevels = mMipLevels; + desc.ArraySize = mTextureDepth; + desc.Format = mFormatInfo.texFormat; + desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = getBindFlags(); - desc.CPUAccessFlags = 0; - desc.MiscFlags = getMiscFlags(); + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags(); + desc.CPUAccessFlags = 0; + desc.MiscFlags = getMiscFlags(); - HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); - - // this can happen from windows TDR - if (d3d11::isDeviceLostError(result)) - { - mRenderer->notifyDeviceLost(); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D array texture storage, result: 0x%X.", result); - } - else if (FAILED(result)) - { - ASSERT(result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D array texture storage, result: 0x%X.", result); - } - - d3d11::SetDebugName(mTexture, "TexStorage2DArray.Texture"); + ANGLE_TRY(mRenderer->allocateTexture(desc, mFormatInfo, &mTexture)); + mTexture.setDebugName("TexStorage2DArray.Texture"); } - *outResource = mTexture; - return gl::Error(GL_NO_ERROR); + *outResource = &mTexture; + return gl::NoError(); } -gl::Error TextureStorage11_2DArray::createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, - ID3D11ShaderResourceView **outSRV) const +gl::Error TextureStorage11_2DArray::createSRV(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) { D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = format; - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + srvDesc.Format = format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel; - srvDesc.Texture2DArray.MipLevels = mipLevels; + srvDesc.Texture2DArray.MipLevels = mipLevels; srvDesc.Texture2DArray.FirstArraySlice = 0; - srvDesc.Texture2DArray.ArraySize = mTextureDepth; + srvDesc.Texture2DArray.ArraySize = mTextureDepth; - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result = device->CreateShaderResourceView(texture, &srvDesc, outSRV); + ANGLE_TRY(mRenderer->allocateResource(srvDesc, texture.get(), outSRV)); + outSRV->setDebugName("TexStorage2DArray.SRV"); - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal texture storage SRV, result: 0x%X.", result); - } - - d3d11::SetDebugName(*outSRV, "TexStorage2DArray.SRV"); - - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) +gl::Error TextureStorage11_2DArray::createRenderTargetSRV(const TextureHelper11 &texture, + const gl::ImageIndex &index, + DXGI_FORMAT resourceFormat, + d3d11::SharedSRV *srv) const +{ + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = resourceFormat; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + index.mipIndex; + srvDesc.Texture2DArray.MipLevels = 1; + srvDesc.Texture2DArray.FirstArraySlice = index.layerIndex; + srvDesc.Texture2DArray.ArraySize = index.numLayers; + + ANGLE_TRY(mRenderer->allocateResource(srvDesc, texture.get(), srv)); + + return gl::NoError(); +} + +gl::Error TextureStorage11_2DArray::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) { ASSERT(index.hasLayer()); - int mipLevel = index.mipIndex; - int layer = index.layerIndex; + const int mipLevel = index.mipIndex; + const int layer = index.layerIndex; + const int numLayers = index.numLayers; ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); - LevelLayerKey key(mipLevel, layer); + LevelLayerRangeKey key(mipLevel, layer, numLayers); if (mRenderTargets.find(key) == mRenderTargets.end()) { - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result; - - ID3D11Resource *texture = NULL; - gl::Error error = getResource(&texture); - if (error.isError()) + const TextureHelper11 *texture = nullptr; + ANGLE_TRY(getResource(context, &texture)); + d3d11::SharedSRV srv; + ANGLE_TRY(createRenderTargetSRV(*texture, index, mFormatInfo.srvFormat, &srv)); + d3d11::SharedSRV blitSRV; + if (mFormatInfo.blitSRVFormat != mFormatInfo.srvFormat) { - return error; - } - - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = mShaderResourceFormat; - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; - srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + mipLevel; - srvDesc.Texture2DArray.MipLevels = 1; - srvDesc.Texture2DArray.FirstArraySlice = layer; - srvDesc.Texture2DArray.ArraySize = 1; - - ID3D11ShaderResourceView *srv; - result = device->CreateShaderResourceView(texture, &srvDesc, &srv); - - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal shader resource view for texture storage, result: 0x%X.", result); - } - - d3d11::SetDebugName(srv, "TexStorage2DArray.RenderTargetSRV"); - - if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) - { - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; - rtvDesc.Texture2DArray.FirstArraySlice = layer; - rtvDesc.Texture2DArray.ArraySize = 1; - - ID3D11RenderTargetView *rtv; - result = device->CreateRenderTargetView(texture, &rtvDesc, &rtv); - - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) - { - SafeRelease(srv); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal render target view for texture storage, result: 0x%X.", result); - } - - d3d11::SetDebugName(rtv, "TexStorage2DArray.RenderTargetRTV"); - - mRenderTargets[key] = new TextureRenderTarget11(rtv, texture, srv, mInternalFormat, getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0); - - // RenderTarget will take ownership of these resources - SafeRelease(rtv); - SafeRelease(srv); + ANGLE_TRY(createRenderTargetSRV(*texture, index, mFormatInfo.blitSRVFormat, &blitSRV)); } else { - UNREACHABLE(); + blitSRV = srv.makeCopy(); + } + + srv.setDebugName("TexStorage2DArray.RenderTargetSRV"); + + if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN) + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mFormatInfo.rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; + rtvDesc.Texture2DArray.FirstArraySlice = layer; + rtvDesc.Texture2DArray.ArraySize = numLayers; + + d3d11::RenderTargetView rtv; + ANGLE_TRY(mRenderer->allocateResource(rtvDesc, texture->get(), &rtv)); + rtv.setDebugName("TexStorage2DArray.RenderTargetRTV"); + + mRenderTargets[key].reset(new TextureRenderTarget11( + std::move(rtv), *texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(), + getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0)); + } + else + { + ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN); + + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Format = mFormatInfo.dsvFormat; + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; + dsvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; + dsvDesc.Texture2DArray.FirstArraySlice = layer; + dsvDesc.Texture2DArray.ArraySize = numLayers; + dsvDesc.Flags = 0; + + d3d11::DepthStencilView dsv; + ANGLE_TRY(mRenderer->allocateResource(dsvDesc, texture->get(), &dsv)); + dsv.setDebugName("TexStorage2DArray.RenderTargetDSV"); + + mRenderTargets[key].reset(new TextureRenderTarget11( + std::move(dsv), *texture, srv, mFormatInfo.internalFormat, getFormatSet(), + getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0)); } } ASSERT(outRT); - *outRT = mRenderTargets[key]; - return gl::Error(GL_NO_ERROR); + *outRT = mRenderTargets[key].get(); + return gl::NoError(); } -gl::Error TextureStorage11_2DArray::getSwizzleTexture(ID3D11Resource **outTexture) +gl::Error TextureStorage11_2DArray::getSwizzleTexture(const TextureHelper11 **outTexture) { - if (!mSwizzleTexture) + if (!mSwizzleTexture.valid()) { - ID3D11Device *device = mRenderer->getDevice(); + const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()); D3D11_TEXTURE2D_DESC desc; - desc.Width = mTextureWidth; - desc.Height = mTextureHeight; - desc.MipLevels = mMipLevels; - desc.ArraySize = mTextureDepth; - desc.Format = mSwizzleTextureFormat; - desc.SampleDesc.Count = 1; + desc.Width = mTextureWidth; + desc.Height = mTextureHeight; + desc.MipLevels = mMipLevels; + desc.ArraySize = mTextureDepth; + desc.Format = format.texFormat; + desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; - desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; - HRESULT result = device->CreateTexture2D(&desc, NULL, &mSwizzleTexture); - - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle texture, result: 0x%X.", result); - } - - d3d11::SetDebugName(*outTexture, "TexStorage2DArray.SwizzleTexture"); + ANGLE_TRY(mRenderer->allocateTexture(desc, format, &mSwizzleTexture)); + mSwizzleTexture.setDebugName("TexStorage2DArray.SwizzleTexture"); } - *outTexture = mSwizzleTexture; - return gl::Error(GL_NO_ERROR); + *outTexture = &mSwizzleTexture; + return gl::NoError(); } -gl::Error TextureStorage11_2DArray::getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) +gl::Error TextureStorage11_2DArray::getSwizzleRenderTarget(int mipLevel, + const d3d11::RenderTargetView **outRTV) { ASSERT(mipLevel >= 0 && mipLevel < getLevelCount()); ASSERT(outRTV); - if (!mSwizzleRenderTargets[mipLevel]) + if (!mSwizzleRenderTargets[mipLevel].valid()) { - ID3D11Resource *swizzleTexture = NULL; - gl::Error error = getSwizzleTexture(&swizzleTexture); - if (error.isError()) - { - return error; - } - - ID3D11Device *device = mRenderer->getDevice(); + const TextureHelper11 *swizzleTexture = nullptr; + ANGLE_TRY(getSwizzleTexture(&swizzleTexture)); D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mSwizzleRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; + rtvDesc.Format = + mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel; rtvDesc.Texture2DArray.FirstArraySlice = 0; - rtvDesc.Texture2DArray.ArraySize = mTextureDepth; + rtvDesc.Texture2DArray.ArraySize = mTextureDepth; - HRESULT result = device->CreateRenderTargetView(mSwizzleTexture, &rtvDesc, &mSwizzleRenderTargets[mipLevel]); - - ASSERT(result == E_OUTOFMEMORY || SUCCEEDED(result)); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal swizzle render target view, result: 0x%X.", result); - } + ANGLE_TRY(mRenderer->allocateResource(rtvDesc, mSwizzleTexture.get(), + &mSwizzleRenderTargets[mipLevel])); } - *outRTV = mSwizzleRenderTargets[mipLevel]; - return gl::Error(GL_NO_ERROR); + *outRTV = &mSwizzleRenderTargets[mipLevel]; + return gl::NoError(); } +gl::ErrorOrResult TextureStorage11_2DArray::ensureDropStencilTexture( + const gl::Context *context) +{ + if (mDropStencilTexture.valid()) + { + return DropStencil::ALREADY_EXISTS; + } + + D3D11_TEXTURE2D_DESC dropDesc = {}; + dropDesc.ArraySize = mTextureDepth; + dropDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL; + dropDesc.CPUAccessFlags = 0; + dropDesc.Format = DXGI_FORMAT_R32_TYPELESS; + dropDesc.Height = mTextureHeight; + dropDesc.MipLevels = mMipLevels; + dropDesc.MiscFlags = 0; + dropDesc.SampleDesc.Count = 1; + dropDesc.SampleDesc.Quality = 0; + dropDesc.Usage = D3D11_USAGE_DEFAULT; + dropDesc.Width = mTextureWidth; + + const auto &format = + d3d11::Format::Get(GL_DEPTH_COMPONENT32F, mRenderer->getRenderer11DeviceCaps()); + ANGLE_TRY(mRenderer->allocateTexture(dropDesc, format, &mDropStencilTexture)); + mDropStencilTexture.setDebugName("TexStorage2DArray.DropStencil"); + + std::vector layerCounts(mMipLevels, mTextureDepth); + + ANGLE_TRY(initDropStencilTexture( + context, gl::ImageIndexIterator::Make2DArray(0, mMipLevels, layerCounts.data()))); + + return DropStencil::CREATED; } + +TextureStorage11_2DMultisample::TextureStorage11_2DMultisample(Renderer11 *renderer, + GLenum internalformat, + GLsizei width, + GLsizei height, + int levels, + int samples, + bool fixedSampleLocations) + : TextureStorage11( + renderer, + GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), true), + GetTextureMiscFlags(internalformat, renderer->getRenderer11DeviceCaps(), true, levels), + internalformat), + mTexture(), + mRenderTarget(nullptr) +{ + // adjust size if needed for compressed textures + d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, &mTopLevel); + + mMipLevels = 1; + mTextureWidth = width; + mTextureHeight = height; + mTextureDepth = 1; + mSamples = samples; + mFixedSampleLocations = fixedSampleLocations; +} + +gl::Error TextureStorage11_2DMultisample::onDestroy(const gl::Context *context) +{ + InvalidateRenderTarget(context, mRenderTarget.get()); + mRenderTarget.reset(); + return gl::NoError(); +} + +TextureStorage11_2DMultisample::~TextureStorage11_2DMultisample() +{ +} + +gl::Error TextureStorage11_2DMultisample::copyToStorage(const gl::Context *context, + TextureStorage *destStorage) +{ + UNIMPLEMENTED(); + return gl::InternalError() << "copyToStorage is unimplemented"; +} + +void TextureStorage11_2DMultisample::associateImage(Image11 *image, const gl::ImageIndex &index) +{ +} + +void TextureStorage11_2DMultisample::verifyAssociatedImageValid(const gl::ImageIndex &index, + Image11 *expectedImage) +{ +} + +void TextureStorage11_2DMultisample::disassociateImage(const gl::ImageIndex &index, + Image11 *expectedImage) +{ +} + +gl::Error TextureStorage11_2DMultisample::releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) +{ + return gl::NoError(); +} + +gl::Error TextureStorage11_2DMultisample::getResource(const gl::Context *context, + const TextureHelper11 **outResource) +{ + ANGLE_TRY(ensureTextureExists(1)); + + *outResource = &mTexture; + return gl::NoError(); +} + +gl::Error TextureStorage11_2DMultisample::ensureTextureExists(int mipLevels) +{ + // For Multisampled textures, mipLevels always equals 1. + ASSERT(mipLevels == 1); + + // if the width or height is not positive this should be treated as an incomplete texture + // we handle that here by skipping the d3d texture creation + if (!mTexture.valid() && mTextureWidth > 0 && mTextureHeight > 0) + { + D3D11_TEXTURE2D_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.Width = mTextureWidth; // Compressed texture size constraints? + desc.Height = mTextureHeight; + desc.MipLevels = mipLevels; + desc.ArraySize = 1; + desc.Format = mFormatInfo.texFormat; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags(); + desc.CPUAccessFlags = 0; + desc.MiscFlags = getMiscFlags(); + + const gl::TextureCaps &textureCaps = + mRenderer->getNativeTextureCaps().get(mFormatInfo.internalFormat); + GLuint supportedSamples = textureCaps.getNearestSamples(mSamples); + desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples; + desc.SampleDesc.Quality = static_cast(D3D11_STANDARD_MULTISAMPLE_PATTERN); + + ANGLE_TRY(mRenderer->allocateTexture(desc, mFormatInfo, &mTexture)); + mTexture.setDebugName("TexStorage2DMS.Texture"); + } + + return gl::NoError(); +} + +gl::Error TextureStorage11_2DMultisample::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) +{ + ASSERT(!index.hasLayer()); + + const int level = index.mipIndex; + ASSERT(level == 0); + + ASSERT(outRT); + if (mRenderTarget) + { + *outRT = mRenderTarget.get(); + return gl::NoError(); + } + + const TextureHelper11 *texture = nullptr; + ANGLE_TRY(getResource(context, &texture)); + + const d3d11::SharedSRV *srv = nullptr; + ANGLE_TRY(getSRVLevel(context, level, false, &srv)); + + const d3d11::SharedSRV *blitSRV = nullptr; + ANGLE_TRY(getSRVLevel(context, level, true, &blitSRV)); + + if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN) + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mFormatInfo.rtvFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; + + d3d11::RenderTargetView rtv; + ANGLE_TRY(mRenderer->allocateResource(rtvDesc, texture->get(), &rtv)); + + mRenderTarget.reset(new TextureRenderTarget11( + std::move(rtv), *texture, *srv, *blitSRV, mFormatInfo.internalFormat, getFormatSet(), + getLevelWidth(level), getLevelHeight(level), 1, mSamples)); + + *outRT = mRenderTarget.get(); + return gl::NoError(); + } + + ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN); + + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Format = mFormatInfo.dsvFormat; + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS; + dsvDesc.Flags = 0; + + d3d11::DepthStencilView dsv; + ANGLE_TRY(mRenderer->allocateResource(dsvDesc, texture->get(), &dsv)); + + mRenderTarget.reset(new TextureRenderTarget11( + std::move(dsv), *texture, *srv, mFormatInfo.internalFormat, getFormatSet(), + getLevelWidth(level), getLevelHeight(level), 1, mSamples)); + + *outRT = mRenderTarget.get(); + return gl::NoError(); +} + +gl::Error TextureStorage11_2DMultisample::createSRV(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) +{ + ASSERT(outSRV); + + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = format; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; + + ANGLE_TRY(mRenderer->allocateResource(srvDesc, texture.get(), outSRV)); + outSRV->setDebugName("TexStorage2DMS.SRV"); + return gl::NoError(); +} + +gl::Error TextureStorage11_2DMultisample::getSwizzleTexture(const TextureHelper11 **outTexture) +{ + UNIMPLEMENTED(); + return gl::InternalError() << "getSwizzleTexture is unimplemented."; +} + +gl::Error TextureStorage11_2DMultisample::getSwizzleRenderTarget( + int mipLevel, + const d3d11::RenderTargetView **outRTV) +{ + UNIMPLEMENTED(); + return gl::InternalError() << "getSwizzleRenderTarget is unimplemented."; +} + +gl::ErrorOrResult +TextureStorage11_2DMultisample::ensureDropStencilTexture(const gl::Context *context) +{ + UNIMPLEMENTED(); + return gl::InternalError() << "Drop stencil texture not implemented."; +} + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h index a88db2f0af..336aa495a8 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h @@ -10,10 +10,13 @@ #ifndef LIBANGLE_RENDERER_D3D_D3D11_TEXTURESTORAGE11_H_ #define LIBANGLE_RENDERER_D3D_D3D11_TEXTURESTORAGE11_H_ -#include "libANGLE/Texture.h" #include "libANGLE/Error.h" +#include "libANGLE/Texture.h" #include "libANGLE/renderer/d3d/TextureStorage.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" +#include #include namespace gl @@ -31,69 +34,111 @@ class SwapChain11; class Image11; struct Renderer11DeviceCaps; +template +using TexLevelArray = std::array; + +template +using CubeFaceArray = std::array; + class TextureStorage11 : public TextureStorage { public: - virtual ~TextureStorage11(); + ~TextureStorage11() override; static DWORD GetTextureBindFlags(GLenum internalFormat, const Renderer11DeviceCaps &renderer11DeviceCaps, bool renderTarget); static DWORD GetTextureMiscFlags(GLenum internalFormat, const Renderer11DeviceCaps &renderer11DeviceCaps, bool renderTarget, int levels); UINT getBindFlags() const; UINT getMiscFlags() const; + const d3d11::Format &getFormatSet() const; + gl::Error getSRVLevels(const gl::Context *context, + GLint baseLevel, + GLint maxLevel, + const d3d11::SharedSRV **outSRV); + gl::Error generateSwizzles(const gl::Context *context, const gl::SwizzleState &swizzleTarget); + void markLevelDirty(int mipLevel); + void markDirty(); - virtual gl::Error getResource(ID3D11Resource **outResource) = 0; - virtual gl::Error getSRV(const gl::TextureState &textureState, - ID3D11ShaderResourceView **outSRV); - virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) = 0; + gl::Error updateSubresourceLevel(const gl::Context *context, + const TextureHelper11 &texture, + unsigned int sourceSubresource, + const gl::ImageIndex &index, + const gl::Box ©Area); - virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex); + gl::Error copySubresourceLevel(const gl::Context *context, + const TextureHelper11 &dstTexture, + unsigned int dstSubresource, + const gl::ImageIndex &index, + const gl::Box ®ion); - virtual int getTopLevel() const; - virtual bool isRenderTarget() const; - virtual bool isManaged() const; + // TextureStorage virtual functions + int getTopLevel() const override; + bool isRenderTarget() const override; + bool isManaged() const override; bool supportsNativeMipmapFunction() const override; - virtual int getLevelCount() const; + int getLevelCount() const override; + gl::Error generateMipmap(const gl::Context *context, + const gl::ImageIndex &sourceIndex, + const gl::ImageIndex &destIndex) override; + gl::Error copyToStorage(const gl::Context *context, TextureStorage *destStorage) override; + gl::Error setData(const gl::Context *context, + const gl::ImageIndex &index, + ImageD3D *image, + const gl::Box *destBox, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixelData) override; + + virtual gl::Error getSRV(const gl::Context *context, + const gl::TextureState &textureState, + const d3d11::SharedSRV **outSRV); virtual UINT getSubresourceIndex(const gl::ImageIndex &index) const; - - gl::Error generateSwizzles(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha); - void invalidateSwizzleCacheLevel(int mipLevel); - void invalidateSwizzleCache(); - - gl::Error updateSubresourceLevel(ID3D11Resource *texture, unsigned int sourceSubresource, - const gl::ImageIndex &index, const gl::Box ©Area); - - gl::Error copySubresourceLevel(ID3D11Resource* dstTexture, unsigned int dstSubresource, - const gl::ImageIndex &index, const gl::Box ®ion); - + virtual gl::Error getResource(const gl::Context *context, + const TextureHelper11 **outResource) = 0; virtual void associateImage(Image11* image, const gl::ImageIndex &index) = 0; virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage) = 0; - virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage) = 0; - virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage) = 0; - - virtual gl::Error copyToStorage(TextureStorage *destStorage); - virtual gl::Error setData(const gl::ImageIndex &index, ImageD3D *image, const gl::Box *destBox, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixelData); - - gl::Error getSRVLevels(GLint baseLevel, GLint maxLevel, ID3D11ShaderResourceView **outSRV); + virtual void verifyAssociatedImageValid(const gl::ImageIndex &index, + Image11 *expectedImage) = 0; + virtual gl::Error releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) = 0; protected: - TextureStorage11(Renderer11 *renderer, UINT bindFlags, UINT miscFlags); + TextureStorage11(Renderer11 *renderer, UINT bindFlags, UINT miscFlags, GLenum internalFormat); int getLevelWidth(int mipLevel) const; int getLevelHeight(int mipLevel) const; int getLevelDepth(int mipLevel) const; // Some classes (e.g. TextureStorage11_2D) will override getMippedResource. - virtual gl::Error getMippedResource(ID3D11Resource **outResource) { return getResource(outResource); } + virtual gl::Error getMippedResource(const gl::Context *context, + const TextureHelper11 **outResource); - virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture) = 0; - virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) = 0; - gl::Error getSRVLevel(int mipLevel, ID3D11ShaderResourceView **outSRV); + virtual gl::Error getSwizzleTexture(const TextureHelper11 **outTexture) = 0; + virtual gl::Error getSwizzleRenderTarget(int mipLevel, + const d3d11::RenderTargetView **outRTV) = 0; + gl::Error getSRVLevel(const gl::Context *context, + int mipLevel, + bool blitSRV, + const d3d11::SharedSRV **outSRV); - virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, - ID3D11ShaderResourceView **outSRV) const = 0; + // Get a version of a depth texture with only depth information, not stencil. + enum DropStencil + { + CREATED, + ALREADY_EXISTS + }; + virtual gl::ErrorOrResult ensureDropStencilTexture(const gl::Context *context); + gl::Error initDropStencilTexture(const gl::Context *context, const gl::ImageIndexIterator &it); - void verifySwizzleExists(GLenum swizzleRed, GLenum swizzleGreen, GLenum swizzleBlue, GLenum swizzleAlpha); + // The baseLevel parameter should *not* have mTopLevel applied. + virtual gl::Error createSRV(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) = 0; + + void verifySwizzleExists(const gl::SwizzleState &swizzleState); // Clear all cached non-swizzle SRVs and invalidate the swizzle cache. void clearSRVCache(); @@ -102,32 +147,13 @@ class TextureStorage11 : public TextureStorage int mTopLevel; unsigned int mMipLevels; - GLenum mInternalFormat; - DXGI_FORMAT mTextureFormat; - DXGI_FORMAT mShaderResourceFormat; - DXGI_FORMAT mRenderTargetFormat; - DXGI_FORMAT mDepthStencilFormat; - DXGI_FORMAT mSwizzleTextureFormat; - DXGI_FORMAT mSwizzleShaderResourceFormat; - DXGI_FORMAT mSwizzleRenderTargetFormat; + const d3d11::Format &mFormatInfo; unsigned int mTextureWidth; unsigned int mTextureHeight; unsigned int mTextureDepth; - struct SwizzleCacheValue - { - GLenum swizzleRed; - GLenum swizzleGreen; - GLenum swizzleBlue; - GLenum swizzleAlpha; - - SwizzleCacheValue(); - SwizzleCacheValue(GLenum red, GLenum green, GLenum blue, GLenum alpha); - - bool operator ==(const SwizzleCacheValue &other) const; - bool operator !=(const SwizzleCacheValue &other) const; - }; - SwizzleCacheValue mSwizzleCache[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + TexLevelArray mSwizzleCache; + TextureHelper11 mDropStencilTexture; private: const UINT mBindFlags; @@ -135,18 +161,24 @@ class TextureStorage11 : public TextureStorage struct SRVKey { - SRVKey(int baseLevel = 0, int mipLevels = 0, bool swizzle = false); + SRVKey(int baseLevel, int mipLevels, bool swizzle, bool dropStencil); bool operator<(const SRVKey &rhs) const; - int baseLevel; - int mipLevels; - bool swizzle; + int baseLevel = 0; // Without mTopLevel applied. + int mipLevels = 0; + bool swizzle = false; + bool dropStencil = false; }; - typedef std::map SRVCache; + typedef std::map SRVCache; + + gl::Error getCachedOrCreateSRV(const gl::Context *context, + const SRVKey &key, + const d3d11::SharedSRV **outSRV); SRVCache mSrvCache; - ID3D11ShaderResourceView *mLevelSRVs[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + TexLevelArray mLevelSRVs; + TexLevelArray mLevelBlitSRVs; }; class TextureStorage11_2D : public TextureStorage11 @@ -154,33 +186,48 @@ class TextureStorage11_2D : public TextureStorage11 public: TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swapchain); TextureStorage11_2D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly = false); - virtual ~TextureStorage11_2D(); + ~TextureStorage11_2D() override; - virtual gl::Error getResource(ID3D11Resource **outResource); - virtual gl::Error getMippedResource(ID3D11Resource **outResource); - virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT); + gl::Error onDestroy(const gl::Context *context) override; - virtual gl::Error copyToStorage(TextureStorage *destStorage); + gl::Error getResource(const gl::Context *context, const TextureHelper11 **outResource) override; + gl::Error getMippedResource(const gl::Context *context, + const TextureHelper11 **outResource) override; + gl::Error getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) override; - virtual void associateImage(Image11* image, const gl::ImageIndex &index); - virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage); - virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage); - virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage); + gl::Error copyToStorage(const gl::Context *context, TextureStorage *destStorage) override; - virtual gl::Error useLevelZeroWorkaroundTexture(bool useLevelZeroTexture); + void associateImage(Image11 *image, const gl::ImageIndex &index) override; + void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override; + void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override; + gl::Error releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) override; + + gl::Error useLevelZeroWorkaroundTexture(const gl::Context *context, + bool useLevelZeroTexture) override; protected: - virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture); - virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV); + gl::Error getSwizzleTexture(const TextureHelper11 **outTexture) override; + gl::Error getSwizzleRenderTarget(int mipLevel, const d3d11::RenderTargetView **outRTV) override; + + gl::ErrorOrResult ensureDropStencilTexture(const gl::Context *context) override; gl::Error ensureTextureExists(int mipLevels); private: - virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, - ID3D11ShaderResourceView **outSRV) const; + gl::Error createSRV(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) override; - ID3D11Texture2D *mTexture; - RenderTarget11 *mRenderTarget[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + TextureHelper11 mTexture; + TexLevelArray> mRenderTarget; + bool mHasKeyedMutex; // These are members related to the zero max-LOD workaround. // D3D11 Feature Level 9_3 can't disable mipmaps on a mipmapped texture (i.e. solely sample from level zero). @@ -191,108 +238,179 @@ class TextureStorage11_2D : public TextureStorage11 // One example of this is an application that creates a texture, calls glGenerateMipmap, and then disables mipmaps on the texture. // A more likely example is an app that creates an empty texture, renders to it, and then calls glGenerateMipmap // TODO: In this rendering scenario, release the mLevelZeroTexture after mTexture has been created to save memory. - ID3D11Texture2D *mLevelZeroTexture; - RenderTarget11 *mLevelZeroRenderTarget; + TextureHelper11 mLevelZeroTexture; + std::unique_ptr mLevelZeroRenderTarget; bool mUseLevelZeroTexture; // Swizzle-related variables - ID3D11Texture2D *mSwizzleTexture; - ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + TextureHelper11 mSwizzleTexture; + TexLevelArray mSwizzleRenderTargets; - Image11 *mAssociatedImages[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + TexLevelArray mAssociatedImages; +}; + +class TextureStorage11_External : public TextureStorage11 +{ + public: + TextureStorage11_External(Renderer11 *renderer, + egl::Stream *stream, + const egl::Stream::GLTextureDescription &glDesc); + ~TextureStorage11_External() override; + + gl::Error onDestroy(const gl::Context *context) override; + + gl::Error getResource(const gl::Context *context, const TextureHelper11 **outResource) override; + gl::Error getMippedResource(const gl::Context *context, + const TextureHelper11 **outResource) override; + gl::Error getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) override; + + gl::Error copyToStorage(const gl::Context *context, TextureStorage *destStorage) override; + + void associateImage(Image11 *image, const gl::ImageIndex &index) override; + void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override; + void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override; + gl::Error releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) override; + + protected: + gl::Error getSwizzleTexture(const TextureHelper11 **outTexture) override; + gl::Error getSwizzleRenderTarget(int mipLevel, const d3d11::RenderTargetView **outRTV) override; + + private: + gl::Error createSRV(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) override; + + TextureHelper11 mTexture; + int mSubresourceIndex; + bool mHasKeyedMutex; + + Image11 *mAssociatedImage; }; class TextureStorage11_EGLImage final : public TextureStorage11 { public: - TextureStorage11_EGLImage(Renderer11 *renderer, EGLImageD3D *eglImage); + TextureStorage11_EGLImage(Renderer11 *renderer, + EGLImageD3D *eglImage, + RenderTarget11 *renderTarget11); ~TextureStorage11_EGLImage() override; - gl::Error getResource(ID3D11Resource **outResource) override; - gl::Error getSRV(const gl::TextureState &textureState, - ID3D11ShaderResourceView **outSRV) override; - gl::Error getMippedResource(ID3D11Resource **outResource) override; - gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) override; + gl::Error getResource(const gl::Context *context, const TextureHelper11 **outResource) override; + gl::Error getSRV(const gl::Context *context, + const gl::TextureState &textureState, + const d3d11::SharedSRV **outSRV) override; + gl::Error getMippedResource(const gl::Context *context, + const TextureHelper11 **outResource) override; + gl::Error getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) override; - gl::Error copyToStorage(TextureStorage *destStorage) override; + gl::Error copyToStorage(const gl::Context *context, TextureStorage *destStorage) override; void associateImage(Image11 *image, const gl::ImageIndex &index) override; void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override; - bool isAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override; - gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11 *incomingImage) override; + void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override; + gl::Error releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) override; - gl::Error useLevelZeroWorkaroundTexture(bool useLevelZeroTexture) override; + gl::Error useLevelZeroWorkaroundTexture(const gl::Context *context, + bool useLevelZeroTexture) override; protected: - gl::Error getSwizzleTexture(ID3D11Resource **outTexture) override; - gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV) override; + gl::Error getSwizzleTexture(const TextureHelper11 **outTexture) override; + gl::Error getSwizzleRenderTarget(int mipLevel, const d3d11::RenderTargetView **outRTV) override; private: // Check if the EGL image's render target has been updated due to orphaning and delete // any SRVs and other resources based on the image's old render target. - gl::Error checkForUpdatedRenderTarget(); + gl::Error checkForUpdatedRenderTarget(const gl::Context *context); - gl::Error createSRV(int baseLevel, + gl::Error createSRV(const gl::Context *context, + int baseLevel, int mipLevels, DXGI_FORMAT format, - ID3D11Resource *texture, - ID3D11ShaderResourceView **outSRV) const override; + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) override; - gl::Error getImageRenderTarget(RenderTarget11 **outRT) const; + gl::Error getImageRenderTarget(const gl::Context *context, RenderTarget11 **outRT) const; EGLImageD3D *mImage; uintptr_t mCurrentRenderTarget; // Swizzle-related variables - ID3D11Texture2D *mSwizzleTexture; - std::vector mSwizzleRenderTargets; + TextureHelper11 mSwizzleTexture; + std::vector mSwizzleRenderTargets; }; class TextureStorage11_Cube : public TextureStorage11 { public: TextureStorage11_Cube(Renderer11 *renderer, GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly); - virtual ~TextureStorage11_Cube(); + ~TextureStorage11_Cube() override; - virtual UINT getSubresourceIndex(const gl::ImageIndex &index) const; + gl::Error onDestroy(const gl::Context *context) override; - virtual gl::Error getResource(ID3D11Resource **outResource); - virtual gl::Error getMippedResource(ID3D11Resource **outResource); - virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT); + UINT getSubresourceIndex(const gl::ImageIndex &index) const override; - virtual gl::Error copyToStorage(TextureStorage *destStorage); + gl::Error getResource(const gl::Context *context, const TextureHelper11 **outResource) override; + gl::Error getMippedResource(const gl::Context *context, + const TextureHelper11 **outResource) override; + gl::Error getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) override; - virtual void associateImage(Image11* image, const gl::ImageIndex &index); - virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage); - virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage); - virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage); + gl::Error copyToStorage(const gl::Context *context, TextureStorage *destStorage) override; - virtual gl::Error useLevelZeroWorkaroundTexture(bool useLevelZeroTexture); + void associateImage(Image11 *image, const gl::ImageIndex &index) override; + void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override; + void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override; + gl::Error releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) override; + + gl::Error useLevelZeroWorkaroundTexture(const gl::Context *context, + bool useLevelZeroTexture) override; protected: - virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture); - virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV); + gl::Error getSwizzleTexture(const TextureHelper11 **outTexture) override; + gl::Error getSwizzleRenderTarget(int mipLevel, const d3d11::RenderTargetView **outRTV) override; + + gl::ErrorOrResult ensureDropStencilTexture(const gl::Context *context) override; gl::Error ensureTextureExists(int mipLevels); private: - virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, - ID3D11ShaderResourceView **outSRV) const; + gl::Error createSRV(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) override; + gl::Error createRenderTargetSRV(const TextureHelper11 &texture, + const gl::ImageIndex &index, + DXGI_FORMAT resourceFormat, + d3d11::SharedSRV *srv) const; - static const size_t CUBE_FACE_COUNT = 6; - - ID3D11Texture2D *mTexture; - RenderTarget11 *mRenderTarget[CUBE_FACE_COUNT][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + TextureHelper11 mTexture; + CubeFaceArray>> mRenderTarget; // Level-zero workaround members. See TextureStorage11_2D's workaround members for a description. - ID3D11Texture2D *mLevelZeroTexture; - RenderTarget11 *mLevelZeroRenderTarget[CUBE_FACE_COUNT]; + TextureHelper11 mLevelZeroTexture; + CubeFaceArray> mLevelZeroRenderTarget; bool mUseLevelZeroTexture; - ID3D11Texture2D *mSwizzleTexture; - ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + TextureHelper11 mSwizzleTexture; + TexLevelArray mSwizzleRenderTargets; - Image11 *mAssociatedImages[CUBE_FACE_COUNT][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + CubeFaceArray> mAssociatedImages; }; class TextureStorage11_3D : public TextureStorage11 @@ -300,37 +418,46 @@ class TextureStorage11_3D : public TextureStorage11 public: TextureStorage11_3D(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels); - virtual ~TextureStorage11_3D(); + ~TextureStorage11_3D() override; - virtual gl::Error getResource(ID3D11Resource **outResource); + gl::Error onDestroy(const gl::Context *context) override; + + gl::Error getResource(const gl::Context *context, const TextureHelper11 **outResource) override; // Handles both layer and non-layer RTs - virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT); + gl::Error getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) override; - virtual void associateImage(Image11* image, const gl::ImageIndex &index); - virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage); - virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage); - virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage); + void associateImage(Image11 *image, const gl::ImageIndex &index) override; + void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override; + void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override; + gl::Error releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) override; protected: - virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture); - virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV); + gl::Error getSwizzleTexture(const TextureHelper11 **outTexture) override; + gl::Error getSwizzleRenderTarget(int mipLevel, const d3d11::RenderTargetView **outRTV) override; private: - virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, - ID3D11ShaderResourceView **outSRV) const; + gl::Error createSRV(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) override; typedef std::pair LevelLayerKey; - typedef std::map RenderTargetMap; - RenderTargetMap mLevelLayerRenderTargets; + std::map> mLevelLayerRenderTargets; - RenderTarget11 *mLevelRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + TexLevelArray> mLevelRenderTargets; - ID3D11Texture3D *mTexture; - ID3D11Texture3D *mSwizzleTexture; - ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + TextureHelper11 mTexture; + TextureHelper11 mSwizzleTexture; + TexLevelArray mSwizzleRenderTargets; - Image11 *mAssociatedImages[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + TexLevelArray mAssociatedImages; }; class TextureStorage11_2DArray : public TextureStorage11 @@ -338,37 +465,125 @@ class TextureStorage11_2DArray : public TextureStorage11 public: TextureStorage11_2DArray(Renderer11 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels); - virtual ~TextureStorage11_2DArray(); + ~TextureStorage11_2DArray() override; - virtual gl::Error getResource(ID3D11Resource **outResource); - virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT); + gl::Error onDestroy(const gl::Context *context) override; - virtual void associateImage(Image11* image, const gl::ImageIndex &index); - virtual void disassociateImage(const gl::ImageIndex &index, Image11* expectedImage); - virtual bool isAssociatedImageValid(const gl::ImageIndex &index, Image11* expectedImage); - virtual gl::Error releaseAssociatedImage(const gl::ImageIndex &index, Image11* incomingImage); + gl::Error getResource(const gl::Context *context, const TextureHelper11 **outResource) override; + gl::Error getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) override; + + void associateImage(Image11 *image, const gl::ImageIndex &index) override; + void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override; + void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override; + gl::Error releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) override; protected: - virtual gl::Error getSwizzleTexture(ID3D11Resource **outTexture); - virtual gl::Error getSwizzleRenderTarget(int mipLevel, ID3D11RenderTargetView **outRTV); + gl::Error getSwizzleTexture(const TextureHelper11 **outTexture) override; + gl::Error getSwizzleRenderTarget(int mipLevel, const d3d11::RenderTargetView **outRTV) override; + + gl::ErrorOrResult ensureDropStencilTexture(const gl::Context *context) override; private: - virtual gl::Error createSRV(int baseLevel, int mipLevels, DXGI_FORMAT format, ID3D11Resource *texture, - ID3D11ShaderResourceView **outSRV) const; + struct LevelLayerRangeKey + { + LevelLayerRangeKey(int mipLevelIn, int layerIn, int numLayersIn) + : mipLevel(mipLevelIn), layer(layerIn), numLayers(numLayersIn) + { + } + bool operator<(const LevelLayerRangeKey &other) const + { + if (mipLevel != other.mipLevel) + { + return mipLevel < other.mipLevel; + } + if (layer != other.layer) + { + return layer < other.layer; + } + return numLayers < other.numLayers; + } + int mipLevel; + int layer; + int numLayers; + }; - typedef std::pair LevelLayerKey; - typedef std::map RenderTargetMap; - RenderTargetMap mRenderTargets; + private: + gl::Error createSRV(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) override; + gl::Error createRenderTargetSRV(const TextureHelper11 &texture, + const gl::ImageIndex &index, + DXGI_FORMAT resourceFormat, + d3d11::SharedSRV *srv) const; - ID3D11Texture2D *mTexture; + std::map> mRenderTargets; - ID3D11Texture2D *mSwizzleTexture; - ID3D11RenderTargetView *mSwizzleRenderTargets[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; + TextureHelper11 mTexture; - typedef std::map ImageMap; + TextureHelper11 mSwizzleTexture; + TexLevelArray mSwizzleRenderTargets; + + typedef std::map ImageMap; ImageMap mAssociatedImages; }; +class TextureStorage11_2DMultisample : public TextureStorage11 +{ + public: + TextureStorage11_2DMultisample(Renderer11 *renderer, + GLenum internalformat, + GLsizei width, + GLsizei height, + int levels, + int samples, + bool fixedSampleLocations); + ~TextureStorage11_2DMultisample() override; + + gl::Error onDestroy(const gl::Context *context) override; + + gl::Error getResource(const gl::Context *context, const TextureHelper11 **outResource) override; + gl::Error getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) override; + + gl::Error copyToStorage(const gl::Context *context, TextureStorage *destStorage) override; + + void associateImage(Image11 *image, const gl::ImageIndex &index) override; + void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override; + void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override; + gl::Error releaseAssociatedImage(const gl::Context *context, + const gl::ImageIndex &index, + Image11 *incomingImage) override; + + protected: + gl::Error getSwizzleTexture(const TextureHelper11 **outTexture) override; + gl::Error getSwizzleRenderTarget(int mipLevel, const d3d11::RenderTargetView **outRTV) override; + + gl::ErrorOrResult ensureDropStencilTexture(const gl::Context *context) override; + + gl::Error ensureTextureExists(int mipLevels); + + private: + gl::Error createSRV(const gl::Context *context, + int baseLevel, + int mipLevels, + DXGI_FORMAT format, + const TextureHelper11 &texture, + d3d11::SharedSRV *outSRV) override; + + TextureHelper11 mTexture; + std::unique_ptr mRenderTarget; + + unsigned int mSamples; + GLboolean mFixedSampleLocations; +}; } #endif // LIBANGLE_RENDERER_D3D_D3D11_TEXTURESTORAGE11_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.cpp new file mode 100644 index 0000000000..4b08edf71f --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.cpp @@ -0,0 +1,124 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// TransformFeedbackD3D.cpp is a no-op implementation for both the D3D9 and D3D11 renderers. + +#include "libANGLE/renderer/d3d/d3d11/TransformFeedback11.h" + +#include "libANGLE/Buffer.h" +#include "libANGLE/renderer/d3d/d3d11/Buffer11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" + +namespace rx +{ + +TransformFeedback11::TransformFeedback11(const gl::TransformFeedbackState &state, + Renderer11 *renderer) + : TransformFeedbackImpl(state), + mRenderer(renderer), + mIsDirty(true), + mBuffers(state.getIndexedBuffers().size(), nullptr), + mBufferOffsets(state.getIndexedBuffers().size(), 0), + mSerial(mRenderer->generateSerial()) +{ +} + +TransformFeedback11::~TransformFeedback11() +{ +} + +void TransformFeedback11::begin(GLenum primitiveMode) +{ + // Reset all the cached offsets to the binding offsets + mIsDirty = true; + for (size_t bindingIdx = 0; bindingIdx < mBuffers.size(); bindingIdx++) + { + const auto &binding = mState.getIndexedBuffer(bindingIdx); + if (binding.get() != nullptr) + { + mBufferOffsets[bindingIdx] = static_cast(binding.getOffset()); + } + else + { + mBufferOffsets[bindingIdx] = 0; + } + } +} + +void TransformFeedback11::end() +{ + if (mRenderer->getWorkarounds().flushAfterEndingTransformFeedback) + { + mRenderer->getDeviceContext()->Flush(); + } +} + +void TransformFeedback11::pause() +{ +} + +void TransformFeedback11::resume() +{ +} + +void TransformFeedback11::bindGenericBuffer(const gl::BindingPointer &binding) +{ +} + +void TransformFeedback11::bindIndexedBuffer(size_t index, + const gl::OffsetBindingPointer &binding) +{ + mIsDirty = true; + mBufferOffsets[index] = static_cast(binding.getOffset()); +} + +void TransformFeedback11::onApply() +{ + mIsDirty = false; + + // Change all buffer offsets to -1 so that if any of them need to be re-applied, the are set to + // append + std::fill(mBufferOffsets.begin(), mBufferOffsets.end(), -1); +} + +bool TransformFeedback11::isDirty() const +{ + return mIsDirty; +} + +UINT TransformFeedback11::getNumSOBuffers() const +{ + return static_cast(mBuffers.size()); +} + +gl::ErrorOrResult *> TransformFeedback11::getSOBuffers( + const gl::Context *context) +{ + for (size_t bindingIdx = 0; bindingIdx < mBuffers.size(); bindingIdx++) + { + const auto &binding = mState.getIndexedBuffer(bindingIdx); + if (binding.get() != nullptr) + { + Buffer11 *storage = GetImplAs(binding.get()); + ANGLE_TRY_RESULT(storage->getBuffer(context, BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK), + mBuffers[bindingIdx]); + } + } + + return &mBuffers; +} + +const std::vector &TransformFeedback11::getSOBufferOffsets() const +{ + return mBufferOffsets; +} + +Serial TransformFeedback11::getSerial() const +{ + return mSerial; +} + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.h new file mode 100644 index 0000000000..cc9fcc335a --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.h @@ -0,0 +1,60 @@ +// +// Copyright 2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// TransformFeedback11.h: Implements the abstract rx::TransformFeedbackImpl class. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_TRANSFORMFEEDBACK11_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_TRANSFORMFEEDBACK11_H_ + +#include "common/platform.h" + +#include "libANGLE/Error.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/renderer/TransformFeedbackImpl.h" +#include "libANGLE/renderer/renderer_utils.h" + +namespace rx +{ + +class Renderer11; + +class TransformFeedback11 : public TransformFeedbackImpl +{ + public: + TransformFeedback11(const gl::TransformFeedbackState &state, Renderer11 *renderer); + ~TransformFeedback11() override; + + void begin(GLenum primitiveMode) override; + void end() override; + void pause() override; + void resume() override; + + void bindGenericBuffer(const gl::BindingPointer &binding) override; + void bindIndexedBuffer(size_t index, + const gl::OffsetBindingPointer &binding) override; + + void onApply(); + + bool isDirty() const; + + UINT getNumSOBuffers() const; + gl::ErrorOrResult *> getSOBuffers(const gl::Context *context); + const std::vector &getSOBufferOffsets() const; + + Serial getSerial() const; + + private: + Renderer11 *mRenderer; + + bool mIsDirty; + std::vector mBuffers; + std::vector mBufferOffsets; + + Serial mSerial; +}; +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_TRANSFORMFEEDBACK11_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.cpp index 213ce31817..29185a9d93 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.cpp @@ -11,9 +11,15 @@ #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #if defined (ANGLE_ENABLE_WINDOWS_STORE) -using namespace ABI::Windows::Foundation; +#include +#include +#include +using namespace Microsoft::WRL; +using namespace Microsoft::WRL::Wrappers; using namespace ABI::Windows::ApplicationModel; using namespace ABI::Windows::ApplicationModel::Core; +using namespace ABI::Windows::Foundation; +using namespace ABI::Windows::Foundation::Collections; #endif namespace rx @@ -41,7 +47,6 @@ void Trim11::trim() #if defined (ANGLE_ENABLE_WINDOWS_STORE) ID3D11Device* device = mRenderer->getDevice(); - // IDXGIDevice3 is only supported on Windows 8.1 and Windows Phone 8.1 and above. IDXGIDevice3 *dxgiDevice3 = d3d11::DynamicCastComObject(device); if (dxgiDevice3) { diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.h index 4741e81601..69fa05a57b 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Trim11.h @@ -13,9 +13,7 @@ #include "libANGLE/angletypes.h" #include "libANGLE/Error.h" -#if !defined(ANGLE_ENABLE_WINDOWS_STORE) -typedef void* EventRegistrationToken; -#else +#if defined(ANGLE_ENABLE_WINDOWS_STORE) #include #endif diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp new file mode 100644 index 0000000000..97c29415ed --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp @@ -0,0 +1,413 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// VertexArray11: +// Implementation of rx::VertexArray11. +// + +#include "libANGLE/renderer/d3d/d3d11/VertexArray11.h" + +#include "common/bitset_utils.h" +#include "libANGLE/Context.h" +#include "libANGLE/renderer/d3d/d3d11/Buffer11.h" +#include "libANGLE/renderer/d3d/d3d11/Context11.h" + +using namespace angle; + +namespace rx +{ + +namespace +{ +OnBufferDataDirtyChannel *GetBufferBroadcastChannel(Buffer11 *buffer11, + IndexStorageType storageType) +{ + switch (storageType) + { + case IndexStorageType::Direct: + return buffer11->getDirectBroadcastChannel(); + case IndexStorageType::Static: + return buffer11->getStaticBroadcastChannel(); + case IndexStorageType::Dynamic: + return buffer11 ? buffer11->getStaticBroadcastChannel() : nullptr; + default: + UNREACHABLE(); + return nullptr; + } +} +} // anonymous namespace + +VertexArray11::VertexArray11(const gl::VertexArrayState &data) + : VertexArrayImpl(data), + mAttributeStorageTypes(data.getMaxAttribs(), VertexStorageType::CURRENT_VALUE), + mTranslatedAttribs(data.getMaxAttribs()), + mCurrentArrayBuffers(data.getMaxAttribs()), + mCurrentElementArrayBuffer(), + mOnArrayBufferDataDirty(), + mOnElementArrayBufferDataDirty(this, mCurrentArrayBuffers.size()), + mAppliedNumViewsToDivisor(1), + mLastElementType(GL_NONE), + mLastDrawElementsOffset(0), + mCurrentElementArrayStorage(IndexStorageType::Invalid), + mCachedIndexInfoValid(false) +{ + for (size_t attribIndex = 0; attribIndex < mCurrentArrayBuffers.size(); ++attribIndex) + { + mOnArrayBufferDataDirty.emplace_back(this, attribIndex); + } +} + +VertexArray11::~VertexArray11() +{ +} + +void VertexArray11::destroy(const gl::Context *context) +{ + for (auto &buffer : mCurrentArrayBuffers) + { + if (buffer.get()) + { + buffer.set(context, nullptr); + } + } + + mCurrentElementArrayBuffer.set(context, nullptr); +} + +void VertexArray11::syncState(const gl::Context *context, + const gl::VertexArray::DirtyBits &dirtyBits) +{ + ASSERT(dirtyBits.any()); + + // Generate a state serial. This serial is used in the program class to validate the cached + // input layout, and skip recomputation in the fast path. + Renderer11 *renderer = GetImplAs(context)->getRenderer(); + mCurrentStateSerial = renderer->generateSerial(); + + // TODO(jmadill): Individual attribute invalidation. + renderer->getStateManager()->invalidateVertexBuffer(); + + for (auto dirtyBit : dirtyBits) + { + if (dirtyBit == gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER) + { + mCachedIndexInfoValid = false; + mLastElementType = GL_NONE; + } + else + { + size_t index = gl::VertexArray::GetVertexIndexFromDirtyBit(dirtyBit); + // TODO(jiawei.shao@intel.com): Vertex Attrib Bindings + ASSERT(index == mState.getBindingIndexFromAttribIndex(index)); + mAttribsToUpdate.set(index); + } + } +} + +bool VertexArray11::flushAttribUpdates(const gl::Context *context) +{ + if (mAttribsToUpdate.any()) + { + const auto &activeLocations = + context->getGLState().getProgram()->getActiveAttribLocationsMask(); + + // Skip attrib locations the program doesn't use. + gl::AttributesMask activeToUpdate = mAttribsToUpdate & activeLocations; + + for (auto toUpdateIndex : activeToUpdate) + { + mAttribsToUpdate.reset(toUpdateIndex); + updateVertexAttribStorage(context, toUpdateIndex); + } + + return true; + } + + return false; +} + +bool VertexArray11::updateElementArrayStorage(const gl::Context *context, + GLenum elementType, + GLenum destElementType, + const void *indices) +{ + unsigned int offset = static_cast(reinterpret_cast(indices)); + + if (mCachedIndexInfoValid && mLastElementType == elementType && + offset == mLastDrawElementsOffset) + { + // Dynamic index buffers must be re-streamed every draw. + return (mCurrentElementArrayStorage == IndexStorageType::Dynamic); + } + + gl::Buffer *newBuffer = mState.getElementArrayBuffer().get(); + gl::Buffer *oldBuffer = mCurrentElementArrayBuffer.get(); + bool needsTranslation = false; + IndexStorageType newStorageType = ClassifyIndexStorage( + context->getGLState(), newBuffer, elementType, destElementType, offset, &needsTranslation); + + if (newBuffer != oldBuffer) + { + mCurrentElementArrayBuffer.set(context, newBuffer); + } + + if (newStorageType != mCurrentElementArrayStorage || newBuffer != oldBuffer) + { + Buffer11 *newBuffer11 = SafeGetImplAs(newBuffer); + + auto *newChannel = GetBufferBroadcastChannel(newBuffer11, newStorageType); + + mCurrentElementArrayStorage = newStorageType; + mOnElementArrayBufferDataDirty.bind(newChannel); + needsTranslation = true; + } + + if (mLastDrawElementsOffset != offset) + { + needsTranslation = true; + mLastDrawElementsOffset = offset; + } + + if (mLastElementType != elementType) + { + needsTranslation = true; + mLastElementType = elementType; + } + + // TODO(jmadill): We should probably promote static usage immediately, because this can change + // the storage type for dynamic buffers. + return needsTranslation || !mCachedIndexInfoValid; +} + +void VertexArray11::updateVertexAttribStorage(const gl::Context *context, size_t attribIndex) +{ + const auto &attrib = mState.getVertexAttribute(attribIndex); + const auto &binding = mState.getBindingFromAttribIndex(attribIndex); + + // Note: having an unchanged storage type doesn't mean the attribute is clean. + auto oldStorageType = mAttributeStorageTypes[attribIndex]; + auto newStorageType = ClassifyAttributeStorage(attrib, binding); + + mAttributeStorageTypes[attribIndex] = newStorageType; + + StateManager11 *stateManager = GetImplAs(context)->getRenderer()->getStateManager(); + + if (newStorageType == VertexStorageType::DYNAMIC) + { + if (oldStorageType != VertexStorageType::DYNAMIC) + { + // Sync dynamic attribs in a different set. + mAttribsToTranslate.reset(attribIndex); + mDynamicAttribsMask.set(attribIndex); + } + } + else + { + mAttribsToTranslate.set(attribIndex); + stateManager->invalidateVertexAttributeTranslation(); + + if (oldStorageType == VertexStorageType::DYNAMIC) + { + ASSERT(mDynamicAttribsMask[attribIndex]); + mDynamicAttribsMask.reset(attribIndex); + } + } + + gl::Buffer *oldBufferGL = mCurrentArrayBuffers[attribIndex].get(); + gl::Buffer *newBufferGL = binding.getBuffer().get(); + Buffer11 *oldBuffer11 = oldBufferGL ? GetImplAs(oldBufferGL) : nullptr; + Buffer11 *newBuffer11 = newBufferGL ? GetImplAs(newBufferGL) : nullptr; + + if (oldBuffer11 != newBuffer11 || oldStorageType != newStorageType) + { + OnBufferDataDirtyChannel *newChannel = nullptr; + + if (newStorageType == VertexStorageType::CURRENT_VALUE) + { + stateManager->invalidateCurrentValueAttrib(attribIndex); + } + else if (newBuffer11 != nullptr) + { + // Note that for static callbacks, promotion to a static buffer from a dynamic buffer + // means we need to tag dynamic buffers with static callbacks. + switch (newStorageType) + { + case VertexStorageType::DIRECT: + newChannel = newBuffer11->getDirectBroadcastChannel(); + break; + case VertexStorageType::STATIC: + case VertexStorageType::DYNAMIC: + newChannel = newBuffer11->getStaticBroadcastChannel(); + break; + default: + UNREACHABLE(); + break; + } + } + + mOnArrayBufferDataDirty[attribIndex].bind(newChannel); + mCurrentArrayBuffers[attribIndex].set(context, binding.getBuffer().get()); + } +} + +bool VertexArray11::hasActiveDynamicAttrib(const gl::Context *context) +{ + flushAttribUpdates(context); + const auto &activeLocations = + context->getGLState().getProgram()->getActiveAttribLocationsMask(); + auto activeDynamicAttribs = (mDynamicAttribsMask & activeLocations); + return activeDynamicAttribs.any(); +} + +gl::Error VertexArray11::updateDirtyAndDynamicAttribs(const gl::Context *context, + VertexDataManager *vertexDataManager, + const DrawCallVertexParams &vertexParams) +{ + flushAttribUpdates(context); + + const auto &glState = context->getGLState(); + const gl::Program *program = glState.getProgram(); + const auto &activeLocations = program->getActiveAttribLocationsMask(); + const auto &attribs = mState.getVertexAttributes(); + const auto &bindings = mState.getVertexBindings(); + mAppliedNumViewsToDivisor = + (program != nullptr && program->usesMultiview()) ? program->getNumViews() : 1; + + if (mAttribsToTranslate.any()) + { + // Skip attrib locations the program doesn't use, saving for the next frame. + gl::AttributesMask dirtyActiveAttribs = (mAttribsToTranslate & activeLocations); + + for (auto dirtyAttribIndex : dirtyActiveAttribs) + { + mAttribsToTranslate.reset(dirtyAttribIndex); + + auto *translatedAttrib = &mTranslatedAttribs[dirtyAttribIndex]; + const auto ¤tValue = glState.getVertexAttribCurrentValue(dirtyAttribIndex); + + // Record basic attrib info + translatedAttrib->attribute = &attribs[dirtyAttribIndex]; + translatedAttrib->binding = &bindings[translatedAttrib->attribute->bindingIndex]; + translatedAttrib->currentValueType = currentValue.Type; + translatedAttrib->divisor = + translatedAttrib->binding->getDivisor() * mAppliedNumViewsToDivisor; + + switch (mAttributeStorageTypes[dirtyAttribIndex]) + { + case VertexStorageType::DIRECT: + VertexDataManager::StoreDirectAttrib(translatedAttrib); + break; + case VertexStorageType::STATIC: + { + ANGLE_TRY(VertexDataManager::StoreStaticAttrib(context, translatedAttrib)); + break; + } + case VertexStorageType::CURRENT_VALUE: + // Current value attribs are managed by the StateManager11. + break; + default: + UNREACHABLE(); + break; + } + } + } + + if (mDynamicAttribsMask.any()) + { + auto activeDynamicAttribs = (mDynamicAttribsMask & activeLocations); + if (activeDynamicAttribs.none()) + { + return gl::NoError(); + } + + for (auto dynamicAttribIndex : activeDynamicAttribs) + { + auto *dynamicAttrib = &mTranslatedAttribs[dynamicAttribIndex]; + const auto ¤tValue = glState.getVertexAttribCurrentValue(dynamicAttribIndex); + + // Record basic attrib info + dynamicAttrib->attribute = &attribs[dynamicAttribIndex]; + dynamicAttrib->binding = &bindings[dynamicAttrib->attribute->bindingIndex]; + dynamicAttrib->currentValueType = currentValue.Type; + dynamicAttrib->divisor = + dynamicAttrib->binding->getDivisor() * mAppliedNumViewsToDivisor; + } + + ANGLE_TRY(vertexDataManager->storeDynamicAttribs( + context, &mTranslatedAttribs, activeDynamicAttribs, vertexParams.firstVertex(), + vertexParams.vertexCount(), vertexParams.instances())); + } + + return gl::NoError(); +} + +const std::vector &VertexArray11::getTranslatedAttribs() const +{ + return mTranslatedAttribs; +} + +void VertexArray11::signal(size_t channelID, const gl::Context *context) +{ + if (channelID == mAttributeStorageTypes.size()) + { + mCachedIndexInfoValid = false; + mLastElementType = GL_NONE; + mLastDrawElementsOffset = 0; + } + else + { + ASSERT(mAttributeStorageTypes[channelID] != VertexStorageType::CURRENT_VALUE); + + // This can change a buffer's storage, we'll need to re-check. + mAttribsToUpdate.set(channelID); + + // Changing the vertex attribute state can affect the vertex shader. + Renderer11 *renderer = GetImplAs(context)->getRenderer(); + renderer->getStateManager()->invalidateShaders(); + } +} + +void VertexArray11::clearDirtyAndPromoteDynamicAttribs(const gl::Context *context, + const DrawCallVertexParams &vertexParams) +{ + const gl::State &state = context->getGLState(); + const gl::Program *program = state.getProgram(); + const auto &activeLocations = program->getActiveAttribLocationsMask(); + mAttribsToUpdate &= ~activeLocations; + + // Promote to static after we clear the dirty attributes, otherwise we can lose dirtyness. + auto activeDynamicAttribs = (mDynamicAttribsMask & activeLocations); + if (activeDynamicAttribs.any()) + { + VertexDataManager::PromoteDynamicAttribs(context, mTranslatedAttribs, activeDynamicAttribs, + vertexParams.vertexCount()); + } +} + +void VertexArray11::markAllAttributeDivisorsForAdjustment(int numViews) +{ + if (mAppliedNumViewsToDivisor != numViews) + { + mAppliedNumViewsToDivisor = numViews; + mAttribsToUpdate.set(); + } +} + +TranslatedIndexData *VertexArray11::getCachedIndexInfo() +{ + return &mCachedIndexInfo; +} + +void VertexArray11::setCachedIndexInfoValid() +{ + mCachedIndexInfoValid = true; +} + +bool VertexArray11::isCachedIndexInfoValid() const +{ + return mCachedIndexInfoValid; +} + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h index b397140e71..4cdc92531d 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h @@ -9,23 +9,91 @@ #ifndef LIBANGLE_RENDERER_D3D_D3D11_VERTEXARRAY11_H_ #define LIBANGLE_RENDERER_D3D_D3D11_VERTEXARRAY11_H_ +#include "libANGLE/Framebuffer.h" #include "libANGLE/renderer/VertexArrayImpl.h" #include "libANGLE/renderer/d3d/d3d11/Renderer11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/signal_utils.h" namespace rx { class Renderer11; -class VertexArray11 : public VertexArrayImpl +class VertexArray11 : public VertexArrayImpl, public OnBufferDataDirtyReceiver { public: - VertexArray11(const gl::VertexArray::Data &data) - : VertexArrayImpl(data) - { - } - virtual ~VertexArray11() {} + VertexArray11(const gl::VertexArrayState &data); + ~VertexArray11() override; + void destroy(const gl::Context *context) override; + + void syncState(const gl::Context *context, + const gl::VertexArray::DirtyBits &dirtyBits) override; + // This will flush any pending attrib updates and then check the dynamic attribs mask. + bool hasActiveDynamicAttrib(const gl::Context *context); + gl::Error updateDirtyAndDynamicAttribs(const gl::Context *context, + VertexDataManager *vertexDataManager, + const DrawCallVertexParams &vertexParams); + void clearDirtyAndPromoteDynamicAttribs(const gl::Context *context, + const DrawCallVertexParams &vertexParams); + + const std::vector &getTranslatedAttribs() const; + + // SignalReceiver implementation + void signal(size_t channelID, const gl::Context *context) override; + + Serial getCurrentStateSerial() const { return mCurrentStateSerial; } + + // In case of a multi-view program change, we have to update all attributes so that the divisor + // is adjusted. + void markAllAttributeDivisorsForAdjustment(int numViews); + + bool flushAttribUpdates(const gl::Context *context); + + // Returns true if the element array buffer needs to be translated. + bool updateElementArrayStorage(const gl::Context *context, + GLenum elementType, + GLenum destElementType, + const void *indices); + + TranslatedIndexData *getCachedIndexInfo(); + void setCachedIndexInfoValid(); + bool isCachedIndexInfoValid() const; + + private: + void updateVertexAttribStorage(const gl::Context *context, size_t attribIndex); + + std::vector mAttributeStorageTypes; + std::vector mTranslatedAttribs; + + // The mask of attributes marked as dynamic. + gl::AttributesMask mDynamicAttribsMask; + + // A mask of attributes that need to be re-evaluated. + gl::AttributesMask mAttribsToUpdate; + + // A set of attributes we know are dirty, and need to be re-translated. + gl::AttributesMask mAttribsToTranslate; + + // We need to keep a safe pointer to the Buffer so we can attach the correct dirty callbacks. + std::vector> mCurrentArrayBuffers; + gl::BindingPointer mCurrentElementArrayBuffer; + + std::vector mOnArrayBufferDataDirty; + OnBufferDataDirtyBinding mOnElementArrayBufferDataDirty; + + Serial mCurrentStateSerial; + + // The numViews value used to adjust the divisor. + int mAppliedNumViewsToDivisor; + + // If the index buffer needs re-streaming. + GLenum mLastElementType; + unsigned int mLastDrawElementsOffset; + IndexStorageType mCurrentElementArrayStorage; + TranslatedIndexData mCachedIndexInfo; + bool mCachedIndexInfoValid; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_D3D11_VERTEXARRAY11_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp index 098cefcd53..611bd0f18b 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp @@ -19,92 +19,88 @@ namespace rx { -VertexBuffer11::VertexBuffer11(Renderer11 *const renderer) : mRenderer(renderer) +VertexBuffer11::VertexBuffer11(Renderer11 *const renderer) + : mRenderer(renderer), + mBuffer(), + mBufferSize(0), + mDynamicUsage(false), + mMappedResourceData(nullptr) { - mBuffer = NULL; - mBufferSize = 0; - mDynamicUsage = false; - mMappedResourceData = NULL; } VertexBuffer11::~VertexBuffer11() { - ASSERT(mMappedResourceData == NULL); - SafeRelease(mBuffer); + ASSERT(mMappedResourceData == nullptr); } gl::Error VertexBuffer11::initialize(unsigned int size, bool dynamicUsage) { - SafeRelease(mBuffer); - + mBuffer.reset(); updateSerial(); if (size > 0) { - ID3D11Device* dxDevice = mRenderer->getDevice(); - D3D11_BUFFER_DESC bufferDesc; - bufferDesc.ByteWidth = size; - bufferDesc.Usage = D3D11_USAGE_DYNAMIC; - bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - bufferDesc.MiscFlags = 0; + bufferDesc.ByteWidth = size; + bufferDesc.Usage = D3D11_USAGE_DYNAMIC; + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bufferDesc.MiscFlags = 0; bufferDesc.StructureByteStride = 0; - HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal vertex buffer of size, %lu.", size); - } + ANGLE_TRY(mRenderer->allocateResource(bufferDesc, &mBuffer)); if (dynamicUsage) { - d3d11::SetDebugName(mBuffer, "VertexBuffer11 (dynamic)"); + mBuffer.setDebugName("VertexBuffer11 (dynamic)"); } else { - d3d11::SetDebugName(mBuffer, "VertexBuffer11 (static)"); + mBuffer.setDebugName("VertexBuffer11 (static)"); } } - mBufferSize = size; + mBufferSize = size; mDynamicUsage = dynamicUsage; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error VertexBuffer11::mapResource() { - if (mMappedResourceData == NULL) + if (mMappedResourceData == nullptr) { ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); + HRESULT result = + dxContext->Map(mBuffer.get(), 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer, HRESULT: 0x%08x.", result); + return gl::OutOfMemory() + << "Failed to map internal vertex buffer, " << gl::FmtHR(result); } - mMappedResourceData = reinterpret_cast(mappedResource.pData); + mMappedResourceData = reinterpret_cast(mappedResource.pData); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } void VertexBuffer11::hintUnmapResource() { - if (mMappedResourceData != NULL) + if (mMappedResourceData != nullptr) { ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); - dxContext->Unmap(mBuffer, 0); + dxContext->Unmap(mBuffer.get(), 0); - mMappedResourceData = NULL; + mMappedResourceData = nullptr; } } gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, GLenum currentValueType, GLint start, GLsizei count, @@ -112,81 +108,33 @@ gl::Error VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attri unsigned int offset, const uint8_t *sourceData) { - if (!mBuffer) + if (!mBuffer.valid()) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized."); + return gl::OutOfMemory() << "Internal vertex buffer is not initialized."; } - int inputStride = static_cast(ComputeVertexAttributeStride(attrib)); + int inputStride = static_cast(ComputeVertexAttributeStride(attrib, binding)); // This will map the resource if it isn't already mapped. - gl::Error error = mapResource(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mapResource()); uint8_t *output = mMappedResourceData + offset; const uint8_t *input = sourceData; - if (instances == 0 || attrib.divisor == 0) + if (instances == 0 || binding.getDivisor() == 0) { input += inputStride * start; } gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib, currentValueType); - const D3D_FEATURE_LEVEL featureLevel = mRenderer->getRenderer11DeviceCaps().featureLevel; - const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormatType, featureLevel); - ASSERT(vertexFormatInfo.copyFunction != NULL); + const D3D_FEATURE_LEVEL featureLevel = mRenderer->getRenderer11DeviceCaps().featureLevel; + const d3d11::VertexFormat &vertexFormatInfo = + d3d11::GetVertexFormatInfo(vertexFormatType, featureLevel); + ASSERT(vertexFormatInfo.copyFunction != nullptr); vertexFormatInfo.copyFunction(input, inputStride, count, output); - return gl::Error(GL_NO_ERROR); -} - -gl::Error VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, - GLsizei instances, unsigned int *outSpaceRequired) const -{ - unsigned int elementCount = 0; - if (attrib.enabled) - { - if (instances == 0 || attrib.divisor == 0) - { - elementCount = count; - } - else - { - // Round up to divisor, if possible - elementCount = UnsignedCeilDivide(static_cast(instances), attrib.divisor); - } - - gl::VertexFormatType formatType = gl::GetVertexFormatType(attrib); - const D3D_FEATURE_LEVEL featureLevel = mRenderer->getRenderer11DeviceCaps().featureLevel; - const d3d11::VertexFormat &vertexFormatInfo = d3d11::GetVertexFormatInfo(formatType, featureLevel); - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(vertexFormatInfo.nativeFormat); - unsigned int elementSize = dxgiFormatInfo.pixelBytes; - if (elementSize <= std::numeric_limits::max() / elementCount) - { - if (outSpaceRequired) - { - *outSpaceRequired = elementSize * elementCount; - } - return gl::Error(GL_NO_ERROR); - } - else - { - return gl::Error(GL_OUT_OF_MEMORY, "New vertex buffer size would result in an overflow."); - } - } - else - { - const unsigned int elementSize = 4; - if (outSpaceRequired) - { - *outSpaceRequired = elementSize * 4; - } - return gl::Error(GL_NO_ERROR); - } + return gl::NoError(); } unsigned int VertexBuffer11::getBufferSize() const @@ -202,34 +150,35 @@ gl::Error VertexBuffer11::setBufferSize(unsigned int size) } else { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } } gl::Error VertexBuffer11::discard() { - if (!mBuffer) + if (!mBuffer.valid()) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized."); + return gl::OutOfMemory() << "Internal vertex buffer is not initialized."; } ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + HRESULT result = dxContext->Map(mBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer for discarding, HRESULT: 0x%08x", result); + return gl::OutOfMemory() << "Failed to map internal buffer for discarding, " + << gl::FmtHR(result); } - dxContext->Unmap(mBuffer, 0); + dxContext->Unmap(mBuffer.get(), 0); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -ID3D11Buffer *VertexBuffer11::getBuffer() const +const d3d11::Buffer &VertexBuffer11::getBuffer() const { return mBuffer; } -} +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h index 773c4474e1..ab619ae503 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h @@ -12,6 +12,7 @@ #include #include "libANGLE/renderer/d3d/VertexBuffer.h" +#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h" namespace rx { @@ -21,11 +22,13 @@ class VertexBuffer11 : public VertexBuffer { public: explicit VertexBuffer11(Renderer11 *const renderer); - virtual ~VertexBuffer11(); - virtual gl::Error initialize(unsigned int size, bool dynamicUsage); + gl::Error initialize(unsigned int size, bool dynamicUsage) override; + // Warning: you should ensure binding really matches attrib.bindingIndex before using this + // function. gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, GLenum currentValueType, GLint start, GLsizei count, @@ -33,29 +36,27 @@ class VertexBuffer11 : public VertexBuffer unsigned int offset, const uint8_t *sourceData) override; - virtual gl::Error getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, - unsigned int *outSpaceRequired) const; + unsigned int getBufferSize() const override; + gl::Error setBufferSize(unsigned int size) override; + gl::Error discard() override; - virtual unsigned int getBufferSize() const; - virtual gl::Error setBufferSize(unsigned int size); - virtual gl::Error discard(); + void hintUnmapResource() override; - virtual void hintUnmapResource(); - - ID3D11Buffer *getBuffer() const; + const d3d11::Buffer &getBuffer() const; private: + ~VertexBuffer11() override; gl::Error mapResource(); Renderer11 *const mRenderer; - ID3D11Buffer *mBuffer; + d3d11::Buffer mBuffer; unsigned int mBufferSize; bool mDynamicUsage; uint8_t *mMappedResourceData; }; -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_D3D11_VERTEXBUFFER11_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/copyvertex.inl b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/copyvertex.inl index 1ec21dee55..7c5c157c6f 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/copyvertex.inl +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/copyvertex.inl @@ -15,33 +15,42 @@ inline void CopyNativeVertexData(const uint8_t *input, size_t stride, size_t cou if (attribSize == stride && inputComponentCount == outputComponentCount) { memcpy(output, input, count * attribSize); + return; } - else - { - const T defaultAlphaValue = gl::bitCast(alphaDefaultValueBits); - const size_t lastNonAlphaOutputComponent = std::min(outputComponentCount, 3); + if (inputComponentCount == outputComponentCount) + { for (size_t i = 0; i < count; i++) { const T *offsetInput = reinterpret_cast(input + (i * stride)); T *offsetOutput = reinterpret_cast(output) + i * outputComponentCount; - for (size_t j = 0; j < inputComponentCount; j++) - { - offsetOutput[j] = offsetInput[j]; - } + memcpy(offsetOutput, offsetInput, attribSize); + } + return; + } - for (size_t j = inputComponentCount; j < lastNonAlphaOutputComponent; j++) - { - // Set the remaining G/B channels to 0. - offsetOutput[j] = 0; - } + const T defaultAlphaValue = gl::bitCast(alphaDefaultValueBits); + const size_t lastNonAlphaOutputComponent = std::min(outputComponentCount, 3); - if (inputComponentCount < outputComponentCount && outputComponentCount == 4) - { - // Set the remaining alpha channel to the defaultAlphaValue. - offsetOutput[3] = defaultAlphaValue; - } + for (size_t i = 0; i < count; i++) + { + const T *offsetInput = reinterpret_cast(input + (i * stride)); + T *offsetOutput = reinterpret_cast(output) + i * outputComponentCount; + + memcpy(offsetOutput, offsetInput, attribSize); + + if (inputComponentCount < lastNonAlphaOutputComponent) + { + // Set the remaining G/B channels to 0. + size_t numComponents = (lastNonAlphaOutputComponent - inputComponentCount); + memset(&offsetOutput[inputComponentCount], 0, numComponents * sizeof(T)); + } + + if (inputComponentCount < outputComponentCount && outputComponentCount == 4) + { + // Set the remaining alpha channel to the defaultAlphaValue. + offsetOutput[3] = defaultAlphaValue; } } } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_format_data.json b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_format_data.json new file mode 100644 index 0000000000..891d30d252 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_format_data.json @@ -0,0 +1,118 @@ +{ + "UNKNOWN": "NONE", + "R32G32B32A32_TYPELESS": "", + "R32G32B32A32_FLOAT": "", + "R32G32B32A32_UINT": "", + "R32G32B32A32_SINT": "", + "R32G32B32_TYPELESS": "", + "R32G32B32_FLOAT": "", + "R32G32B32_UINT": "", + "R32G32B32_SINT": "", + "R16G16B16A16_TYPELESS": "", + "R16G16B16A16_FLOAT": "", + "R16G16B16A16_UNORM": "", + "R16G16B16A16_UINT": "", + "R16G16B16A16_SNORM": "", + "R16G16B16A16_SINT": "", + "R32G32_TYPELESS": "", + "R32G32_FLOAT": "", + "R32G32_UINT": "", + "R32G32_SINT": "", + "R32G8X24_TYPELESS": "", + "D32_FLOAT_S8X24_UINT": "", + "R32_FLOAT_X8X24_TYPELESS": "", + "X32_TYPELESS_G8X24_UINT": "", + "R10G10B10A2_TYPELESS": "", + "R10G10B10A2_UNORM": "", + "R10G10B10A2_UINT": "", + "R11G11B10_FLOAT": "", + "R8G8B8A8_TYPELESS": "", + "R8G8B8A8_UNORM": "", + "R8G8B8A8_UNORM_SRGB": "", + "R8G8B8A8_UINT": "", + "R8G8B8A8_SNORM": "", + "R8G8B8A8_SINT": "", + "R16G16_TYPELESS": "", + "R16G16_FLOAT": "", + "R16G16_UNORM": "", + "R16G16_UINT": "", + "R16G16_SNORM": "", + "R16G16_SINT": "", + "R32_TYPELESS": "", + "D32_FLOAT": "", + "R32_FLOAT": "", + "R32_UINT": "", + "R32_SINT": "", + "R24G8_TYPELESS": "", + "D24_UNORM_S8_UINT": "", + "R24_UNORM_X8_TYPELESS": "", + "X24_TYPELESS_G8_UINT": "", + "R8G8_TYPELESS": "", + "R8G8_UNORM": "", + "R8G8_UINT": "", + "R8G8_SNORM": "", + "R8G8_SINT": "", + "R16_TYPELESS": "", + "R16_FLOAT": "", + "D16_UNORM": "", + "R16_UNORM": "", + "R16_UINT": "", + "R16_SNORM": "", + "R16_SINT": "", + "R8_TYPELESS": "", + "R8_UNORM": "", + "R8_UINT": "", + "R8_SNORM": "", + "R8_SINT": "", + "A8_UNORM": "", + "R1_UNORM": "", + "R9G9B9E5_SHAREDEXP": "", + "R8G8_B8G8_UNORM": "", + "G8R8_G8B8_UNORM": "", + "BC1_TYPELESS": "", + "BC1_UNORM": "BC1_RGBA_UNORM_BLOCK", + "BC1_UNORM_SRGB": "BC1_RGBA_UNORM_SRGB_BLOCK", + "BC2_TYPELESS": "", + "BC2_UNORM": "BC2_RGBA_UNORM_BLOCK", + "BC2_UNORM_SRGB": "BC2_RGBA_UNORM_SRGB_BLOCK", + "BC3_TYPELESS": "", + "BC3_UNORM": "BC3_RGBA_UNORM_BLOCK", + "BC3_UNORM_SRGB": "BC3_RGBA_UNORM_SRGB_BLOCK", + "BC4_TYPELESS": "", + "BC4_UNORM": "", + "BC4_SNORM": "", + "BC5_TYPELESS": "", + "BC5_UNORM": "", + "BC5_SNORM": "", + "B5G6R5_UNORM": "", + "B5G5R5A1_UNORM": "", + "B8G8R8A8_UNORM": "", + "B8G8R8X8_UNORM": "", + "R10G10B10_XR_BIAS_A2_UNORM": "", + "B8G8R8A8_TYPELESS": "", + "B8G8R8A8_UNORM_SRGB": "", + "B8G8R8X8_TYPELESS": "", + "B8G8R8X8_UNORM_SRGB": "", + "BC6H_TYPELESS": "", + "BC6H_UF16": "", + "BC6H_SF16": "", + "BC7_TYPELESS": "", + "BC7_UNORM": "", + "BC7_UNORM_SRGB": "", + "AYUV": "", + "Y410": "", + "Y416": "", + "NV12": "", + "P010": "", + "P016": "", + "420_OPAQUE": "", + "YUY2": "", + "Y210": "", + "Y216": "", + "NV11": "", + "AI44": "", + "IA44": "", + "P8": "", + "A8P8": "", + "B4G4R4A4_UNORM": "" +} diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_format_map_autogen.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_format_map_autogen.cpp new file mode 100644 index 0000000000..b0697bc5db --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_format_map_autogen.cpp @@ -0,0 +1,516 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_dxgi_format_table.py using data from dxgi_format_data.json. +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// DXGI format info: +// Determining metadata about a DXGI format. + +#include "libANGLE/renderer/Format.h" + +using namespace angle; + +namespace rx +{ + +namespace d3d11 +{ + +GLenum GetComponentType(DXGI_FORMAT dxgiFormat) +{ + switch (dxgiFormat) + { + case DXGI_FORMAT_420_OPAQUE: + break; + case DXGI_FORMAT_A8P8: + break; + case DXGI_FORMAT_A8_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_AI44: + break; + case DXGI_FORMAT_AYUV: + break; + case DXGI_FORMAT_B4G4R4A4_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_B5G5R5A1_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_B5G6R5_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + break; + case DXGI_FORMAT_B8G8R8A8_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + break; + case DXGI_FORMAT_B8G8R8X8_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_BC1_TYPELESS: + break; + case DXGI_FORMAT_BC1_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_BC1_UNORM_SRGB: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_BC2_TYPELESS: + break; + case DXGI_FORMAT_BC2_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_BC2_UNORM_SRGB: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_BC3_TYPELESS: + break; + case DXGI_FORMAT_BC3_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_BC3_UNORM_SRGB: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_BC4_SNORM: + return GL_SIGNED_NORMALIZED; + case DXGI_FORMAT_BC4_TYPELESS: + break; + case DXGI_FORMAT_BC4_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_BC5_SNORM: + return GL_SIGNED_NORMALIZED; + case DXGI_FORMAT_BC5_TYPELESS: + break; + case DXGI_FORMAT_BC5_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_BC6H_SF16: + break; + case DXGI_FORMAT_BC6H_TYPELESS: + break; + case DXGI_FORMAT_BC6H_UF16: + break; + case DXGI_FORMAT_BC7_TYPELESS: + break; + case DXGI_FORMAT_BC7_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_BC7_UNORM_SRGB: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_D16_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_D24_UNORM_S8_UINT: + break; + case DXGI_FORMAT_D32_FLOAT: + return GL_FLOAT; + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + break; + case DXGI_FORMAT_G8R8_G8B8_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_IA44: + break; + case DXGI_FORMAT_NV11: + break; + case DXGI_FORMAT_NV12: + break; + case DXGI_FORMAT_P010: + break; + case DXGI_FORMAT_P016: + break; + case DXGI_FORMAT_P8: + break; + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + break; + case DXGI_FORMAT_R10G10B10A2_UINT: + return GL_UNSIGNED_INT; + case DXGI_FORMAT_R10G10B10A2_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_R11G11B10_FLOAT: + return GL_FLOAT; + case DXGI_FORMAT_R16G16B16A16_FLOAT: + return GL_FLOAT; + case DXGI_FORMAT_R16G16B16A16_SINT: + return GL_INT; + case DXGI_FORMAT_R16G16B16A16_SNORM: + return GL_SIGNED_NORMALIZED; + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + break; + case DXGI_FORMAT_R16G16B16A16_UINT: + return GL_UNSIGNED_INT; + case DXGI_FORMAT_R16G16B16A16_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_R16G16_FLOAT: + return GL_FLOAT; + case DXGI_FORMAT_R16G16_SINT: + return GL_INT; + case DXGI_FORMAT_R16G16_SNORM: + return GL_SIGNED_NORMALIZED; + case DXGI_FORMAT_R16G16_TYPELESS: + break; + case DXGI_FORMAT_R16G16_UINT: + return GL_UNSIGNED_INT; + case DXGI_FORMAT_R16G16_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_R16_FLOAT: + return GL_FLOAT; + case DXGI_FORMAT_R16_SINT: + return GL_INT; + case DXGI_FORMAT_R16_SNORM: + return GL_SIGNED_NORMALIZED; + case DXGI_FORMAT_R16_TYPELESS: + break; + case DXGI_FORMAT_R16_UINT: + return GL_UNSIGNED_INT; + case DXGI_FORMAT_R16_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_R1_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_R24G8_TYPELESS: + break; + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_R32G32B32A32_FLOAT: + return GL_FLOAT; + case DXGI_FORMAT_R32G32B32A32_SINT: + return GL_INT; + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + break; + case DXGI_FORMAT_R32G32B32A32_UINT: + return GL_UNSIGNED_INT; + case DXGI_FORMAT_R32G32B32_FLOAT: + return GL_FLOAT; + case DXGI_FORMAT_R32G32B32_SINT: + return GL_INT; + case DXGI_FORMAT_R32G32B32_TYPELESS: + break; + case DXGI_FORMAT_R32G32B32_UINT: + return GL_UNSIGNED_INT; + case DXGI_FORMAT_R32G32_FLOAT: + return GL_FLOAT; + case DXGI_FORMAT_R32G32_SINT: + return GL_INT; + case DXGI_FORMAT_R32G32_TYPELESS: + break; + case DXGI_FORMAT_R32G32_UINT: + return GL_UNSIGNED_INT; + case DXGI_FORMAT_R32G8X24_TYPELESS: + break; + case DXGI_FORMAT_R32_FLOAT: + return GL_FLOAT; + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + return GL_FLOAT; + case DXGI_FORMAT_R32_SINT: + return GL_INT; + case DXGI_FORMAT_R32_TYPELESS: + break; + case DXGI_FORMAT_R32_UINT: + return GL_UNSIGNED_INT; + case DXGI_FORMAT_R8G8B8A8_SINT: + return GL_INT; + case DXGI_FORMAT_R8G8B8A8_SNORM: + return GL_SIGNED_NORMALIZED; + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + break; + case DXGI_FORMAT_R8G8B8A8_UINT: + return GL_UNSIGNED_INT; + case DXGI_FORMAT_R8G8B8A8_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_R8G8_B8G8_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_R8G8_SINT: + return GL_INT; + case DXGI_FORMAT_R8G8_SNORM: + return GL_SIGNED_NORMALIZED; + case DXGI_FORMAT_R8G8_TYPELESS: + break; + case DXGI_FORMAT_R8G8_UINT: + return GL_UNSIGNED_INT; + case DXGI_FORMAT_R8G8_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_R8_SINT: + return GL_INT; + case DXGI_FORMAT_R8_SNORM: + return GL_SIGNED_NORMALIZED; + case DXGI_FORMAT_R8_TYPELESS: + break; + case DXGI_FORMAT_R8_UINT: + return GL_UNSIGNED_INT; + case DXGI_FORMAT_R8_UNORM: + return GL_UNSIGNED_NORMALIZED; + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + return GL_FLOAT; + case DXGI_FORMAT_UNKNOWN: + break; + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + return GL_UNSIGNED_INT; + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + return GL_UNSIGNED_INT; + case DXGI_FORMAT_Y210: + break; + case DXGI_FORMAT_Y216: + break; + case DXGI_FORMAT_Y410: + break; + case DXGI_FORMAT_Y416: + break; + case DXGI_FORMAT_YUY2: + break; + default: + break; + } + + UNREACHABLE(); + return GL_NONE; +} + +} // namespace d3d11 + +namespace d3d11_angle +{ + +const Format &GetFormat(DXGI_FORMAT dxgiFormat) +{ + switch (dxgiFormat) + { + case DXGI_FORMAT_420_OPAQUE: + break; + case DXGI_FORMAT_A8P8: + break; + case DXGI_FORMAT_A8_UNORM: + return Format::Get(Format::ID::A8_UNORM); + case DXGI_FORMAT_AI44: + break; + case DXGI_FORMAT_AYUV: + break; + case DXGI_FORMAT_B4G4R4A4_UNORM: + return Format::Get(Format::ID::B4G4R4A4_UNORM); + case DXGI_FORMAT_B5G5R5A1_UNORM: + return Format::Get(Format::ID::B5G5R5A1_UNORM); + case DXGI_FORMAT_B5G6R5_UNORM: + return Format::Get(Format::ID::B5G6R5_UNORM); + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + break; + case DXGI_FORMAT_B8G8R8A8_UNORM: + return Format::Get(Format::ID::B8G8R8A8_UNORM); + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + return Format::Get(Format::ID::B8G8R8A8_UNORM_SRGB); + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + break; + case DXGI_FORMAT_B8G8R8X8_UNORM: + return Format::Get(Format::ID::B8G8R8X8_UNORM); + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + break; + case DXGI_FORMAT_BC1_TYPELESS: + break; + case DXGI_FORMAT_BC1_UNORM: + return Format::Get(Format::ID::BC1_RGBA_UNORM_BLOCK); + case DXGI_FORMAT_BC1_UNORM_SRGB: + return Format::Get(Format::ID::BC1_RGBA_UNORM_SRGB_BLOCK); + case DXGI_FORMAT_BC2_TYPELESS: + break; + case DXGI_FORMAT_BC2_UNORM: + return Format::Get(Format::ID::BC2_RGBA_UNORM_BLOCK); + case DXGI_FORMAT_BC2_UNORM_SRGB: + return Format::Get(Format::ID::BC2_RGBA_UNORM_SRGB_BLOCK); + case DXGI_FORMAT_BC3_TYPELESS: + break; + case DXGI_FORMAT_BC3_UNORM: + return Format::Get(Format::ID::BC3_RGBA_UNORM_BLOCK); + case DXGI_FORMAT_BC3_UNORM_SRGB: + return Format::Get(Format::ID::BC3_RGBA_UNORM_SRGB_BLOCK); + case DXGI_FORMAT_BC4_SNORM: + break; + case DXGI_FORMAT_BC4_TYPELESS: + break; + case DXGI_FORMAT_BC4_UNORM: + break; + case DXGI_FORMAT_BC5_SNORM: + break; + case DXGI_FORMAT_BC5_TYPELESS: + break; + case DXGI_FORMAT_BC5_UNORM: + break; + case DXGI_FORMAT_BC6H_SF16: + break; + case DXGI_FORMAT_BC6H_TYPELESS: + break; + case DXGI_FORMAT_BC6H_UF16: + break; + case DXGI_FORMAT_BC7_TYPELESS: + break; + case DXGI_FORMAT_BC7_UNORM: + break; + case DXGI_FORMAT_BC7_UNORM_SRGB: + break; + case DXGI_FORMAT_D16_UNORM: + return Format::Get(Format::ID::D16_UNORM); + case DXGI_FORMAT_D24_UNORM_S8_UINT: + return Format::Get(Format::ID::D24_UNORM_S8_UINT); + case DXGI_FORMAT_D32_FLOAT: + return Format::Get(Format::ID::D32_FLOAT); + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + return Format::Get(Format::ID::D32_FLOAT_S8X24_UINT); + case DXGI_FORMAT_G8R8_G8B8_UNORM: + break; + case DXGI_FORMAT_IA44: + break; + case DXGI_FORMAT_NV11: + break; + case DXGI_FORMAT_NV12: + break; + case DXGI_FORMAT_P010: + break; + case DXGI_FORMAT_P016: + break; + case DXGI_FORMAT_P8: + break; + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + break; + case DXGI_FORMAT_R10G10B10A2_UINT: + return Format::Get(Format::ID::R10G10B10A2_UINT); + case DXGI_FORMAT_R10G10B10A2_UNORM: + return Format::Get(Format::ID::R10G10B10A2_UNORM); + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + break; + case DXGI_FORMAT_R11G11B10_FLOAT: + return Format::Get(Format::ID::R11G11B10_FLOAT); + case DXGI_FORMAT_R16G16B16A16_FLOAT: + return Format::Get(Format::ID::R16G16B16A16_FLOAT); + case DXGI_FORMAT_R16G16B16A16_SINT: + return Format::Get(Format::ID::R16G16B16A16_SINT); + case DXGI_FORMAT_R16G16B16A16_SNORM: + return Format::Get(Format::ID::R16G16B16A16_SNORM); + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + break; + case DXGI_FORMAT_R16G16B16A16_UINT: + return Format::Get(Format::ID::R16G16B16A16_UINT); + case DXGI_FORMAT_R16G16B16A16_UNORM: + return Format::Get(Format::ID::R16G16B16A16_UNORM); + case DXGI_FORMAT_R16G16_FLOAT: + return Format::Get(Format::ID::R16G16_FLOAT); + case DXGI_FORMAT_R16G16_SINT: + return Format::Get(Format::ID::R16G16_SINT); + case DXGI_FORMAT_R16G16_SNORM: + return Format::Get(Format::ID::R16G16_SNORM); + case DXGI_FORMAT_R16G16_TYPELESS: + break; + case DXGI_FORMAT_R16G16_UINT: + return Format::Get(Format::ID::R16G16_UINT); + case DXGI_FORMAT_R16G16_UNORM: + return Format::Get(Format::ID::R16G16_UNORM); + case DXGI_FORMAT_R16_FLOAT: + return Format::Get(Format::ID::R16_FLOAT); + case DXGI_FORMAT_R16_SINT: + return Format::Get(Format::ID::R16_SINT); + case DXGI_FORMAT_R16_SNORM: + return Format::Get(Format::ID::R16_SNORM); + case DXGI_FORMAT_R16_TYPELESS: + break; + case DXGI_FORMAT_R16_UINT: + return Format::Get(Format::ID::R16_UINT); + case DXGI_FORMAT_R16_UNORM: + return Format::Get(Format::ID::R16_UNORM); + case DXGI_FORMAT_R1_UNORM: + break; + case DXGI_FORMAT_R24G8_TYPELESS: + break; + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + break; + case DXGI_FORMAT_R32G32B32A32_FLOAT: + return Format::Get(Format::ID::R32G32B32A32_FLOAT); + case DXGI_FORMAT_R32G32B32A32_SINT: + return Format::Get(Format::ID::R32G32B32A32_SINT); + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + break; + case DXGI_FORMAT_R32G32B32A32_UINT: + return Format::Get(Format::ID::R32G32B32A32_UINT); + case DXGI_FORMAT_R32G32B32_FLOAT: + return Format::Get(Format::ID::R32G32B32_FLOAT); + case DXGI_FORMAT_R32G32B32_SINT: + return Format::Get(Format::ID::R32G32B32_SINT); + case DXGI_FORMAT_R32G32B32_TYPELESS: + break; + case DXGI_FORMAT_R32G32B32_UINT: + return Format::Get(Format::ID::R32G32B32_UINT); + case DXGI_FORMAT_R32G32_FLOAT: + return Format::Get(Format::ID::R32G32_FLOAT); + case DXGI_FORMAT_R32G32_SINT: + return Format::Get(Format::ID::R32G32_SINT); + case DXGI_FORMAT_R32G32_TYPELESS: + break; + case DXGI_FORMAT_R32G32_UINT: + return Format::Get(Format::ID::R32G32_UINT); + case DXGI_FORMAT_R32G8X24_TYPELESS: + break; + case DXGI_FORMAT_R32_FLOAT: + return Format::Get(Format::ID::R32_FLOAT); + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + break; + case DXGI_FORMAT_R32_SINT: + return Format::Get(Format::ID::R32_SINT); + case DXGI_FORMAT_R32_TYPELESS: + break; + case DXGI_FORMAT_R32_UINT: + return Format::Get(Format::ID::R32_UINT); + case DXGI_FORMAT_R8G8B8A8_SINT: + return Format::Get(Format::ID::R8G8B8A8_SINT); + case DXGI_FORMAT_R8G8B8A8_SNORM: + return Format::Get(Format::ID::R8G8B8A8_SNORM); + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + break; + case DXGI_FORMAT_R8G8B8A8_UINT: + return Format::Get(Format::ID::R8G8B8A8_UINT); + case DXGI_FORMAT_R8G8B8A8_UNORM: + return Format::Get(Format::ID::R8G8B8A8_UNORM); + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + return Format::Get(Format::ID::R8G8B8A8_UNORM_SRGB); + case DXGI_FORMAT_R8G8_B8G8_UNORM: + break; + case DXGI_FORMAT_R8G8_SINT: + return Format::Get(Format::ID::R8G8_SINT); + case DXGI_FORMAT_R8G8_SNORM: + return Format::Get(Format::ID::R8G8_SNORM); + case DXGI_FORMAT_R8G8_TYPELESS: + break; + case DXGI_FORMAT_R8G8_UINT: + return Format::Get(Format::ID::R8G8_UINT); + case DXGI_FORMAT_R8G8_UNORM: + return Format::Get(Format::ID::R8G8_UNORM); + case DXGI_FORMAT_R8_SINT: + return Format::Get(Format::ID::R8_SINT); + case DXGI_FORMAT_R8_SNORM: + return Format::Get(Format::ID::R8_SNORM); + case DXGI_FORMAT_R8_TYPELESS: + break; + case DXGI_FORMAT_R8_UINT: + return Format::Get(Format::ID::R8_UINT); + case DXGI_FORMAT_R8_UNORM: + return Format::Get(Format::ID::R8_UNORM); + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + return Format::Get(Format::ID::R9G9B9E5_SHAREDEXP); + case DXGI_FORMAT_UNKNOWN: + return Format::Get(Format::ID::NONE); + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + break; + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + break; + case DXGI_FORMAT_Y210: + break; + case DXGI_FORMAT_Y216: + break; + case DXGI_FORMAT_Y410: + break; + case DXGI_FORMAT_Y416: + break; + case DXGI_FORMAT_YUY2: + break; + default: + break; + } + + UNREACHABLE(); + return Format::Get(Format::ID::NONE); +} + +} // namespace d3d11_angle + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_support_data.json b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_support_data.json index e81b4deea5..942745674f 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_support_data.json +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_support_data.json @@ -8,7 +8,8 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R32G32B32A32_TYPELESS": { @@ -18,7 +19,8 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R32G32B32A32_FLOAT": { @@ -28,27 +30,30 @@ "shaderSample": "10_0check10_1always", "renderTarget": "always", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "always" }, "DXGI_FORMAT_R32G32B32A32_UINT": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "never", - "renderTarget": "always", + "renderTarget": "10_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R32G32B32A32_SINT": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "never", - "renderTarget": "always", + "renderTarget": "10_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R32G32B32_TYPELESS": { @@ -58,7 +63,8 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R32G32B32_FLOAT": { @@ -68,7 +74,8 @@ "shaderSample": "11_0check", "renderTarget": "check", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R32G32B32_UINT": { @@ -78,7 +85,8 @@ "shaderSample": "never", "renderTarget": "check", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R32G32B32_SINT": { @@ -88,7 +96,8 @@ "shaderSample": "never", "renderTarget": "check", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R16G16B16A16_TYPELESS": { @@ -98,57 +107,63 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R16G16B16A16_FLOAT": { "texture2D": "always", "texture3D": "always", "textureCube": "always", - "shaderSample": "10_0", + "shaderSample": "9_3check_10_0always", "renderTarget": "always", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "always" }, "DXGI_FORMAT_R16G16B16A16_UNORM": { "texture2D": "always", "texture3D": "always", "textureCube": "always", - "shaderSample": "10_0", + "shaderSample": "always", "renderTarget": "always", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "always" }, "DXGI_FORMAT_R16G16B16A16_UINT": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "never", - "renderTarget": "always", + "renderTarget": "10_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R16G16B16A16_SNORM": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "10_0", - "renderTarget": "always", + "renderTarget": "10_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "10_0" }, "DXGI_FORMAT_R16G16B16A16_SINT": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "never", - "renderTarget": "always", + "renderTarget": "10_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R32G32_TYPELESS": { @@ -158,7 +173,8 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R32G32_FLOAT": { @@ -168,37 +184,41 @@ "shaderSample": "10_0check10_1always", "renderTarget": "always", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "10_0" }, "DXGI_FORMAT_R32G32_UINT": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "never", - "renderTarget": "always", + "renderTarget": "10_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R32G32_SINT": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "never", - "renderTarget": "always", + "renderTarget": "10_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R32G8X24_TYPELESS": { - "texture2D": "always", + "texture2D": "10_0", "texture3D": "never", - "textureCube": "always", + "textureCube": "10_0", "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_D32_FLOAT_S8X24_UINT": { @@ -208,7 +228,8 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "check", - "depthStencil": "always" + "depthStencil": "10_0", + "mipAutoGen": "never" }, "DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS": { @@ -218,7 +239,8 @@ "shaderSample": "10_0check10_1always", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_X32_TYPELESS_G8X24_UINT": { @@ -228,47 +250,52 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R10G10B10A2_TYPELESS": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R10G10B10A2_UNORM": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "10_0", - "renderTarget": "always", + "renderTarget": "10_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "10_0" }, "DXGI_FORMAT_R10G10B10A2_UINT": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "never", - "renderTarget": "always", + "renderTarget": "10_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R11G11B10_FLOAT": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "10_0", - "renderTarget": "always", + "renderTarget": "10_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "10_0" }, "DXGI_FORMAT_R8G8B8A8_TYPELESS": { @@ -278,57 +305,63 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R8G8B8A8_UNORM": { "texture2D": "always", "texture3D": "always", "textureCube": "always", - "shaderSample": "10_0", + "shaderSample": "always", "renderTarget": "always", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "always" }, "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB": { "texture2D": "always", "texture3D": "always", "textureCube": "always", - "shaderSample": "10_0", + "shaderSample": "always", "renderTarget": "always", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "always" }, "DXGI_FORMAT_R8G8B8A8_UINT": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "never", - "renderTarget": "always", + "renderTarget": "10_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R8G8B8A8_SNORM": { "texture2D": "always", "texture3D": "always", "textureCube": "always", - "shaderSample": "10_0", + "shaderSample": "always", "renderTarget": "always", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "10_0" }, "DXGI_FORMAT_R8G8B8A8_SINT": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "never", - "renderTarget": "always", + "renderTarget": "10_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R16G16_TYPELESS": { @@ -338,7 +371,8 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R16G16_FLOAT": { @@ -348,57 +382,63 @@ "shaderSample": "10_0", "renderTarget": "always", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "always" }, "DXGI_FORMAT_R16G16_UNORM": { "texture2D": "always", "texture3D": "always", "textureCube": "always", - "shaderSample": "10_0", + "shaderSample": "always", "renderTarget": "always", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "always" }, "DXGI_FORMAT_R16G16_UINT": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "never", - "renderTarget": "always", + "renderTarget": "10_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R16G16_SNORM": { "texture2D": "always", "texture3D": "always", "textureCube": "always", - "shaderSample": "10_0", + "shaderSample": "always", "renderTarget": "always", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "10_0" }, "DXGI_FORMAT_R16G16_SINT": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "never", - "renderTarget": "always", + "renderTarget": "10_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R32_TYPELESS": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_D32_FLOAT": { @@ -408,7 +448,8 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "check", - "depthStencil": "always" + "depthStencil": "10_0", + "mipAutoGen": "never" }, "DXGI_FORMAT_R32_FLOAT": { @@ -418,27 +459,30 @@ "shaderSample": "10_0check10_1always", "renderTarget": "always", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "always" }, "DXGI_FORMAT_R32_UINT": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "never", - "renderTarget": "always", + "renderTarget": "10_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R32_SINT": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "never", - "renderTarget": "always", + "renderTarget": "10_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R24G8_TYPELESS": { @@ -448,7 +492,8 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_D24_UNORM_S8_UINT": { @@ -468,7 +513,8 @@ "shaderSample": "10_0check10_1always", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_X24_TYPELESS_G8_UINT": { @@ -478,7 +524,8 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R8G8_TYPELESS": { @@ -488,47 +535,52 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R8G8_UNORM": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", - "shaderSample": "10_0", - "renderTarget": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", + "shaderSample": "9_3check_10_0always", + "renderTarget": "9_3check_10_0always", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "10_0" }, "DXGI_FORMAT_R8G8_UINT": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "never", - "renderTarget": "always", + "renderTarget": "10_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R8G8_SNORM": { "texture2D": "always", - "texture3D": "always", - "textureCube": "always", - "shaderSample": "10_0", - "renderTarget": "always", + "texture3D": "10_0", + "textureCube": "10_0", + "shaderSample": "always", + "renderTarget": "10_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "10_0" }, "DXGI_FORMAT_R8G8_SINT": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "never", - "renderTarget": "always", + "renderTarget": "10_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R16_TYPELESS": { @@ -538,17 +590,19 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R16_FLOAT": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "10_0", - "renderTarget": "always", + "renderTarget": "10_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "10_0" }, "DXGI_FORMAT_D16_UNORM": { @@ -558,47 +612,52 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "check", - "depthStencil": "always" + "depthStencil": "always", + "mipAutoGen": "never" }, "DXGI_FORMAT_R16_UNORM": { "texture2D": "always", "texture3D": "always", "textureCube": "always", - "shaderSample": "10_0", - "renderTarget": "always", + "shaderSample": "always", + "renderTarget": "10_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "10_0" }, "DXGI_FORMAT_R16_UINT": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "never", - "renderTarget": "always", + "renderTarget": "10_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R16_SNORM": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "10_0", - "renderTarget": "always", + "renderTarget": "10_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "10_0" }, "DXGI_FORMAT_R16_SINT": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "never", - "renderTarget": "always", + "renderTarget": "10_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R8_TYPELESS": { @@ -608,47 +667,52 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R8_UNORM": { "texture2D": "always", "texture3D": "always", "textureCube": "always", - "shaderSample": "10_0", - "renderTarget": "always", + "shaderSample": "always", + "renderTarget": "9_3check_10_0always", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "10_0" }, "DXGI_FORMAT_R8_UINT": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "never", - "renderTarget": "always", + "renderTarget": "10_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R8_SNORM": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "10_0", - "renderTarget": "always", + "renderTarget": "10_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "10_0" }, "DXGI_FORMAT_R8_SINT": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "never", - "renderTarget": "always", + "renderTarget": "10_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_A8_UNORM": { @@ -658,7 +722,8 @@ "shaderSample": "10_0", "renderTarget": "always", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "10_0" }, "DXGI_FORMAT_R1_UNORM": { @@ -668,17 +733,19 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R9G9B9E5_SHAREDEXP": { - "texture2D": "always", - "texture3D": "always", - "textureCube": "always", + "texture2D": "10_0", + "texture3D": "10_0", + "textureCube": "10_0", "shaderSample": "10_0", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R8G8_B8G8_UNORM": { @@ -688,7 +755,8 @@ "shaderSample": "10_0", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_G8R8_G8B8_UNORM": { @@ -698,7 +766,8 @@ "shaderSample": "10_0", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_BC1_TYPELESS": { @@ -708,27 +777,30 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_BC1_UNORM": { "texture2D": "always", "texture3D": "always", "textureCube": "always", - "shaderSample": "10_0", + "shaderSample": "always", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_BC1_UNORM_SRGB": { "texture2D": "always", "texture3D": "always", "textureCube": "always", - "shaderSample": "10_0", + "shaderSample": "always", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_BC2_TYPELESS": { @@ -738,27 +810,30 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_BC2_UNORM": { "texture2D": "always", "texture3D": "always", "textureCube": "always", - "shaderSample": "10_0", + "shaderSample": "always", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_BC2_UNORM_SRGB": { "texture2D": "always", "texture3D": "always", "textureCube": "always", - "shaderSample": "10_0", + "shaderSample": "always", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_BC3_TYPELESS": { @@ -768,27 +843,30 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_BC3_UNORM": { "texture2D": "always", "texture3D": "always", "textureCube": "always", - "shaderSample": "10_0", + "shaderSample": "always", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_BC3_UNORM_SRGB": { "texture2D": "always", "texture3D": "always", "textureCube": "always", - "shaderSample": "10_0", + "shaderSample": "always", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_BC4_TYPELESS": { @@ -798,7 +876,8 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_BC4_UNORM": { @@ -808,7 +887,8 @@ "shaderSample": "10_0", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_BC4_SNORM": { @@ -818,7 +898,8 @@ "shaderSample": "10_0", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_BC5_TYPELESS": { @@ -828,7 +909,8 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_BC5_UNORM": { @@ -838,7 +920,8 @@ "shaderSample": "10_0", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_BC5_SNORM": { @@ -848,7 +931,8 @@ "shaderSample": "10_0", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_B5G6R5_UNORM": { @@ -858,7 +942,8 @@ "shaderSample": "dxgi1_2", "renderTarget": "dxgi1_2", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "dxgi1_2" }, "DXGI_FORMAT_B5G5R5A1_UNORM": { @@ -868,17 +953,19 @@ "shaderSample": "dxgi1_2", "renderTarget": "check", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "dxgi1_2" }, "DXGI_FORMAT_B8G8R8A8_UNORM": { "texture2D": "check", "texture3D": "check", "textureCube": "check", - "shaderSample": "10_0check11_0always", - "renderTarget": "10_0check11_0always", + "shaderSample": "9_3always_10_0check11_0always", + "renderTarget": "9_3always_10_0check11_0always", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "always" }, "DXGI_FORMAT_B8G8R8X8_UNORM": { @@ -888,7 +975,8 @@ "shaderSample": "10_0check11_0always", "renderTarget": "11_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM": { @@ -898,7 +986,8 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_B8G8R8A8_TYPELESS": { @@ -908,7 +997,8 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_B8G8R8A8_UNORM_SRGB": { @@ -918,7 +1008,8 @@ "shaderSample": "10_0check11_0always", "renderTarget": "11_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_B8G8R8X8_TYPELESS": { @@ -928,7 +1019,8 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_B8G8R8X8_UNORM_SRGB": { @@ -938,7 +1030,8 @@ "shaderSample": "10_0check11_0always", "renderTarget": "11_0", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_BC6H_TYPELESS": { @@ -948,7 +1041,8 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_BC6H_UF16": { @@ -958,7 +1052,8 @@ "shaderSample": "11_0", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_BC6H_SF16": { @@ -968,7 +1063,8 @@ "shaderSample": "11_0", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_BC7_TYPELESS": { @@ -978,7 +1074,8 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_BC7_UNORM": { @@ -988,7 +1085,8 @@ "shaderSample": "11_0", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_BC7_UNORM_SRGB": { @@ -998,7 +1096,8 @@ "shaderSample": "11_0", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_AYUV": { @@ -1008,7 +1107,8 @@ "shaderSample": "11_1", "renderTarget": "11_1", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_Y410": { @@ -1018,7 +1118,8 @@ "shaderSample": "11_1", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_Y416": { @@ -1028,7 +1129,8 @@ "shaderSample": "11_1", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_NV12": { @@ -1038,7 +1140,8 @@ "shaderSample": "11_1", "renderTarget": "11_1", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_P010": { @@ -1048,7 +1151,8 @@ "shaderSample": "11_1", "renderTarget": "11_1", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_P016": { @@ -1058,7 +1162,8 @@ "shaderSample": "11_1", "renderTarget": "11_1", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_420_OPAQUE": { @@ -1068,7 +1173,8 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_YUY2": { @@ -1078,7 +1184,8 @@ "shaderSample": "11_1", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_Y210": { @@ -1088,7 +1195,8 @@ "shaderSample": "11_1", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_Y216": { @@ -1098,7 +1206,8 @@ "shaderSample": "11_1", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_NV11": { @@ -1108,7 +1217,8 @@ "shaderSample": "11_1", "renderTarget": "11_1", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_AI44": { @@ -1118,7 +1228,8 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_IA44": { @@ -1128,7 +1239,8 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_P8": { @@ -1138,7 +1250,8 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_A8P8": { @@ -1148,7 +1261,8 @@ "shaderSample": "never", "renderTarget": "never", "multisampleRT": "never", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "never" }, "DXGI_FORMAT_B4G4R4A4_UNORM": { @@ -1158,7 +1272,8 @@ "shaderSample": "dxgi1_2", "renderTarget": "check", "multisampleRT": "check", - "depthStencil": "never" + "depthStencil": "never", + "mipAutoGen": "dxgi1_2" } } ] diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.cpp index cbc36445e6..4d7e46bdf2 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.cpp @@ -26,205 +26,205 @@ namespace d3d11 #define F_RT D3D11_FORMAT_SUPPORT_RENDER_TARGET #define F_MS D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET #define F_DS D3D11_FORMAT_SUPPORT_DEPTH_STENCIL +#define F_MIPGEN D3D11_FORMAT_SUPPORT_MIP_AUTOGEN namespace { const DXGISupport &GetDefaultSupport() { - static UINT AllSupportFlags = D3D11_FORMAT_SUPPORT_TEXTURE2D | - D3D11_FORMAT_SUPPORT_TEXTURE3D | - D3D11_FORMAT_SUPPORT_TEXTURECUBE | - D3D11_FORMAT_SUPPORT_SHADER_SAMPLE | - D3D11_FORMAT_SUPPORT_RENDER_TARGET | - D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET | - D3D11_FORMAT_SUPPORT_DEPTH_STENCIL; + static UINT AllSupportFlags = + D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURE3D | + D3D11_FORMAT_SUPPORT_TEXTURECUBE | D3D11_FORMAT_SUPPORT_SHADER_SAMPLE | + D3D11_FORMAT_SUPPORT_RENDER_TARGET | D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET | + D3D11_FORMAT_SUPPORT_DEPTH_STENCIL | D3D11_FORMAT_SUPPORT_MIP_AUTOGEN; static const DXGISupport defaultSupport(0, 0, AllSupportFlags); return defaultSupport; } -const DXGISupport &GetDXGISupport_10_0(DXGI_FORMAT dxgiFormat) +const DXGISupport &GetDXGISupport_9_3(DXGI_FORMAT dxgiFormat) { + // clang-format off switch (dxgiFormat) { case DXGI_FORMAT_420_OPAQUE: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_A8P8: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_A8_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS, F_MS); return info; } case DXGI_FORMAT_AI44: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_AYUV: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); return info; } case DXGI_FORMAT_B4G4R4A4_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS, F_MS | F_RT); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT); return info; } case DXGI_FORMAT_B5G5R5A1_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS, F_MS | F_RT); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT); return info; } case DXGI_FORMAT_B5G6R5_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_B8G8R8A8_TYPELESS: { - static const DXGISupport info(0, F_DS | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); return info; } case DXGI_FORMAT_B8G8R8A8_UNORM: { - static const DXGISupport info(0, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_RT | F_SAMPLE); + static const DXGISupport info(F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_2D | F_3D | F_CUBE | F_MS); return info; } case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: { - static const DXGISupport info(0, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE); + static const DXGISupport info(0, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS); return info; } case DXGI_FORMAT_B8G8R8X8_TYPELESS: { - static const DXGISupport info(0, F_DS | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); return info; } case DXGI_FORMAT_B8G8R8X8_UNORM: { - static const DXGISupport info(0, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE); + static const DXGISupport info(0, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS); return info; } case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: { - static const DXGISupport info(0, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE); + static const DXGISupport info(0, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS); return info; } case DXGI_FORMAT_BC1_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_BC1_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC1_UNORM_SRGB: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC2_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_BC2_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC2_UNORM_SRGB: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC3_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_BC3_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC3_UNORM_SRGB: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC4_SNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC4_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_BC4_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC5_SNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC5_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_BC5_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC6H_SF16: { - static const DXGISupport info(0, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC6H_TYPELESS: { - static const DXGISupport info(0, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_BC6H_UF16: { - static const DXGISupport info(0, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC7_TYPELESS: { - static const DXGISupport info(0, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_BC7_UNORM: { - static const DXGISupport info(0, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC7_UNORM_SRGB: { - static const DXGISupport info(0, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_D16_UNORM: { - static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_D24_UNORM_S8_UINT: @@ -234,112 +234,112 @@ const DXGISupport &GetDXGISupport_10_0(DXGI_FORMAT dxgiFormat) } case DXGI_FORMAT_D32_FLOAT: { - static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: { - static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_G8R8_G8B8_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_IA44: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_NV11: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); return info; } case DXGI_FORMAT_NV12: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); return info; } case DXGI_FORMAT_P010: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); return info; } case DXGI_FORMAT_P016: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); return info; } case DXGI_FORMAT_P8: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R10G10B10A2_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R10G10B10A2_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R10G10B10A2_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(0, F_DS, F_MS); return info; } case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: { - static const DXGISupport info(0, F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, F_2D | F_3D); + static const DXGISupport info(0, F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D); return info; } case DXGI_FORMAT_R11G11B10_FLOAT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(0, F_DS, F_MS); return info; } case DXGI_FORMAT_R16G16B16A16_FLOAT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT, F_DS, F_MS | F_SAMPLE); return info; } case DXGI_FORMAT_R16G16B16A16_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R16G16B16A16_SNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(0, F_DS, F_MS); return info; } case DXGI_FORMAT_R16G16B16A16_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R16G16B16A16_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R16G16B16A16_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R16G16_FLOAT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT, F_DS, F_MS); return info; } case DXGI_FORMAT_R16G16_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R16G16_SNORM: @@ -349,157 +349,157 @@ const DXGISupport &GetDXGISupport_10_0(DXGI_FORMAT dxgiFormat) } case DXGI_FORMAT_R16G16_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R16G16_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R16G16_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R16_FLOAT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(0, F_DS, F_MS); return info; } case DXGI_FORMAT_R16_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R16_SNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(0, F_DS, F_MS); return info; } case DXGI_FORMAT_R16_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R16_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R16_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R1_UNORM: { - static const DXGISupport info(F_2D, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R24G8_TYPELESS: { - static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: { - static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT, F_SAMPLE); + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_R32G32B32A32_FLOAT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS, F_MS | F_SAMPLE); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT, F_DS, F_MS); return info; } case DXGI_FORMAT_R32G32B32A32_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R32G32B32A32_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R32G32B32A32_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R32G32B32_FLOAT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS, F_MS | F_RT); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN, F_MS | F_RT); return info; } case DXGI_FORMAT_R32G32B32_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_SAMPLE, F_MS | F_RT); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT); return info; } case DXGI_FORMAT_R32G32B32_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R32G32B32_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_SAMPLE, F_MS | F_RT); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT); return info; } case DXGI_FORMAT_R32G32_FLOAT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS, F_MS | F_SAMPLE); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS, F_MS); return info; } case DXGI_FORMAT_R32G32_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R32G32_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R32G32_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R32G8X24_TYPELESS: { - static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R32_FLOAT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS, F_MS | F_SAMPLE); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT, F_DS, F_MS); return info; } case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: { - static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT, F_SAMPLE); + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_R32_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R32_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R32_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R8G8B8A8_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R8G8B8A8_SNORM: @@ -509,122 +509,122 @@ const DXGISupport &GetDXGISupport_10_0(DXGI_FORMAT dxgiFormat) } case DXGI_FORMAT_R8G8B8A8_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R8G8B8A8_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R8G8B8A8_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R8G8_B8G8_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_R8G8_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R8G8_SNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R8G8_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R8G8_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R8G8_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(0, F_DS, F_MS | F_RT | F_SAMPLE); return info; } case DXGI_FORMAT_R8_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R8_SNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(0, F_DS, F_MS); return info; } case DXGI_FORMAT_R8_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R8_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R8_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS, F_MS | F_RT); return info; } case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_UNKNOWN: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_X24_TYPELESS_G8_UINT: { - static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: { - static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_Y210: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_Y216: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_Y410: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_Y416: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_YUY2: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } @@ -632,190 +632,785 @@ const DXGISupport &GetDXGISupport_10_0(DXGI_FORMAT dxgiFormat) UNREACHABLE(); return GetDefaultSupport(); } + // clang-format on +} + +const DXGISupport &GetDXGISupport_10_0(DXGI_FORMAT dxgiFormat) +{ + // clang-format off + switch (dxgiFormat) + { + case DXGI_FORMAT_420_OPAQUE: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_A8P8: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_A8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_AI44: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_AYUV: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_B4G4R4A4_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_B5G5R5A1_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_B5G6R5_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); + return info; + } + case DXGI_FORMAT_B8G8R8A8_UNORM: + { + static const DXGISupport info(F_MIPGEN, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_RT | F_SAMPLE); + return info; + } + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + { + static const DXGISupport info(0, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE); + return info; + } + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); + return info; + } + case DXGI_FORMAT_B8G8R8X8_UNORM: + { + static const DXGISupport info(0, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE); + return info; + } + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + { + static const DXGISupport info(0, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE); + return info; + } + case DXGI_FORMAT_BC1_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC1_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC1_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC2_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC2_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC2_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC3_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC3_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC3_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC4_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC4_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC4_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC5_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC5_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC5_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC6H_SF16: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC6H_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC6H_UF16: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC7_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC7_UNORM: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC7_UNORM_SRGB: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_D16_UNORM: + { + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_D24_UNORM_S8_UINT: + { + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_D32_FLOAT: + { + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + { + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_G8R8_G8B8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_IA44: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_NV11: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_NV12: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_P010: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_P016: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_P8: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R10G10B10A2_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R10G10B10A2_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + { + static const DXGISupport info(0, F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D); + return info; + } + case DXGI_FORMAT_R11G11B10_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R16G16B16A16_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R16G16_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R16_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R1_UNORM: + { + static const DXGISupport info(F_2D, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R24G8_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, F_SAMPLE); + return info; + } + case DXGI_FORMAT_R32G32B32A32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT, F_DS, F_MS | F_SAMPLE); + return info; + } + case DXGI_FORMAT_R32G32B32A32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32G32B32A32_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32B32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_R32G32B32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_R32G32B32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32G32B32_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_R32G32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT, F_DS, F_MS | F_SAMPLE); + return info; + } + case DXGI_FORMAT_R32G32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32G32_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G8X24_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT, F_DS, F_MS | F_SAMPLE); + return info; + } + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, F_SAMPLE); + return info; + } + case DXGI_FORMAT_R32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R8G8B8A8_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_B8G8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_R8G8_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R8G8_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R8_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_UNKNOWN: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_Y210: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_Y216: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_Y410: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_Y416: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_YUY2: + { + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + + default: + UNREACHABLE(); + return GetDefaultSupport(); + } + // clang-format on } const DXGISupport &GetDXGISupport_10_1(DXGI_FORMAT dxgiFormat) { + // clang-format off switch (dxgiFormat) { case DXGI_FORMAT_420_OPAQUE: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_A8P8: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_A8_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_AI44: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_AYUV: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); return info; } case DXGI_FORMAT_B4G4R4A4_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS, F_MS | F_RT); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT); return info; } case DXGI_FORMAT_B5G5R5A1_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS, F_MS | F_RT); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT); return info; } case DXGI_FORMAT_B5G6R5_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_B8G8R8A8_TYPELESS: { - static const DXGISupport info(0, F_DS | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); return info; } case DXGI_FORMAT_B8G8R8A8_UNORM: { - static const DXGISupport info(0, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_RT | F_SAMPLE); + static const DXGISupport info(F_MIPGEN, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_RT | F_SAMPLE); return info; } case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: { - static const DXGISupport info(0, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE); + static const DXGISupport info(0, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE); return info; } case DXGI_FORMAT_B8G8R8X8_TYPELESS: { - static const DXGISupport info(0, F_DS | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); return info; } case DXGI_FORMAT_B8G8R8X8_UNORM: { - static const DXGISupport info(0, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE); + static const DXGISupport info(0, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE); return info; } case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: { - static const DXGISupport info(0, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE); + static const DXGISupport info(0, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE); return info; } case DXGI_FORMAT_BC1_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_BC1_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC1_UNORM_SRGB: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC2_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_BC2_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC2_UNORM_SRGB: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC3_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_BC3_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC3_UNORM_SRGB: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC4_SNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC4_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_BC4_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC5_SNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC5_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_BC5_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC6H_SF16: { - static const DXGISupport info(0, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC6H_TYPELESS: { - static const DXGISupport info(0, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_BC6H_UF16: { - static const DXGISupport info(0, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC7_TYPELESS: { - static const DXGISupport info(0, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_BC7_UNORM: { - static const DXGISupport info(0, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC7_UNORM_SRGB: { - static const DXGISupport info(0, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_D16_UNORM: { - static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_D24_UNORM_S8_UINT: @@ -825,397 +1420,397 @@ const DXGISupport &GetDXGISupport_10_1(DXGI_FORMAT dxgiFormat) } case DXGI_FORMAT_D32_FLOAT: { - static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: { - static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_G8R8_G8B8_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_IA44: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_NV11: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); return info; } case DXGI_FORMAT_NV12: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); return info; } case DXGI_FORMAT_P010: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); return info; } case DXGI_FORMAT_P016: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); return info; } case DXGI_FORMAT_P8: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R10G10B10A2_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R10G10B10A2_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R10G10B10A2_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: { - static const DXGISupport info(0, F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, F_2D | F_3D); + static const DXGISupport info(0, F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D); return info; } case DXGI_FORMAT_R11G11B10_FLOAT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R16G16B16A16_FLOAT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R16G16B16A16_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R16G16B16A16_SNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R16G16B16A16_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R16G16B16A16_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R16G16B16A16_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R16G16_FLOAT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R16G16_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R16G16_SNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R16G16_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R16G16_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R16G16_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R16_FLOAT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R16_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R16_SNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R16_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R16_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R16_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R1_UNORM: { - static const DXGISupport info(F_2D, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R24G8_TYPELESS: { - static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: { - static const DXGISupport info(F_2D | F_CUBE | F_SAMPLE, F_3D | F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_CUBE | F_SAMPLE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_R32G32B32A32_FLOAT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R32G32B32A32_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R32G32B32A32_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R32G32B32A32_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R32G32B32_FLOAT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS, F_MS | F_RT); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN, F_MS | F_RT); return info; } case DXGI_FORMAT_R32G32B32_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_SAMPLE, F_MS | F_RT); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT); return info; } case DXGI_FORMAT_R32G32B32_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R32G32B32_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_SAMPLE, F_MS | F_RT); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT); return info; } case DXGI_FORMAT_R32G32_FLOAT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R32G32_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R32G32_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R32G32_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R32G8X24_TYPELESS: { - static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R32_FLOAT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: { - static const DXGISupport info(F_2D | F_CUBE | F_SAMPLE, F_3D | F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_CUBE | F_SAMPLE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_R32_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R32_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R32_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R8G8B8A8_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R8G8B8A8_SNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R8G8B8A8_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R8G8B8A8_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R8G8B8A8_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R8G8_B8G8_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_R8G8_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R8G8_SNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R8G8_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R8G8_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R8G8_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R8_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R8_SNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R8_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R8_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R8_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_UNKNOWN: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_X24_TYPELESS_G8_UINT: { - static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: { - static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_Y210: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_Y216: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_Y410: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_Y416: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_YUY2: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } @@ -1223,190 +1818,192 @@ const DXGISupport &GetDXGISupport_10_1(DXGI_FORMAT dxgiFormat) UNREACHABLE(); return GetDefaultSupport(); } + // clang-format on } const DXGISupport &GetDXGISupport_11_0(DXGI_FORMAT dxgiFormat) { + // clang-format off switch (dxgiFormat) { case DXGI_FORMAT_420_OPAQUE: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_A8P8: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_A8_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_AI44: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_AYUV: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); return info; } case DXGI_FORMAT_B4G4R4A4_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS, F_MS | F_RT); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT); return info; } case DXGI_FORMAT_B5G5R5A1_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS, F_MS | F_RT); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT); return info; } case DXGI_FORMAT_B5G6R5_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_B8G8R8A8_TYPELESS: { - static const DXGISupport info(0, F_DS | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); return info; } case DXGI_FORMAT_B8G8R8A8_UNORM: { - static const DXGISupport info(F_RT | F_SAMPLE, F_DS, F_2D | F_3D | F_CUBE | F_MS); + static const DXGISupport info(F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_2D | F_3D | F_CUBE | F_MS); return info; } case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: { - static const DXGISupport info(F_RT | F_SAMPLE, F_DS, F_2D | F_3D | F_CUBE | F_MS); + static const DXGISupport info(F_RT | F_SAMPLE, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS); return info; } case DXGI_FORMAT_B8G8R8X8_TYPELESS: { - static const DXGISupport info(0, F_DS | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); return info; } case DXGI_FORMAT_B8G8R8X8_UNORM: { - static const DXGISupport info(F_RT | F_SAMPLE, F_DS, F_2D | F_3D | F_CUBE | F_MS); + static const DXGISupport info(F_RT | F_SAMPLE, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS); return info; } case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: { - static const DXGISupport info(F_RT | F_SAMPLE, F_DS, F_2D | F_3D | F_CUBE | F_MS); + static const DXGISupport info(F_RT | F_SAMPLE, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS); return info; } case DXGI_FORMAT_BC1_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_BC1_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC1_UNORM_SRGB: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC2_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_BC2_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC2_UNORM_SRGB: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC3_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_BC3_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC3_UNORM_SRGB: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC4_SNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC4_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_BC4_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC5_SNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC5_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_BC5_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC6H_SF16: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC6H_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_BC6H_UF16: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC7_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_BC7_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_BC7_UNORM_SRGB: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_D16_UNORM: { - static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_D24_UNORM_S8_UINT: @@ -1416,397 +2013,397 @@ const DXGISupport &GetDXGISupport_11_0(DXGI_FORMAT dxgiFormat) } case DXGI_FORMAT_D32_FLOAT: { - static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: { - static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_G8R8_G8B8_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_IA44: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_NV11: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); return info; } case DXGI_FORMAT_NV12: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); return info; } case DXGI_FORMAT_P010: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); return info; } case DXGI_FORMAT_P016: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_RT | F_SAMPLE, F_MS); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); return info; } case DXGI_FORMAT_P8: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R10G10B10A2_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R10G10B10A2_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R10G10B10A2_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: { - static const DXGISupport info(0, F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, F_2D | F_3D); + static const DXGISupport info(0, F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D); return info; } case DXGI_FORMAT_R11G11B10_FLOAT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R16G16B16A16_FLOAT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R16G16B16A16_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R16G16B16A16_SNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R16G16B16A16_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R16G16B16A16_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R16G16B16A16_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R16G16_FLOAT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R16G16_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R16G16_SNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R16G16_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R16G16_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R16G16_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R16_FLOAT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R16_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R16_SNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R16_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R16_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R16_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R1_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R24G8_TYPELESS: { - static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: { - static const DXGISupport info(F_2D | F_CUBE | F_SAMPLE, F_3D | F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_CUBE | F_SAMPLE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_R32G32B32A32_FLOAT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R32G32B32A32_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R32G32B32A32_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R32G32B32A32_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R32G32B32_FLOAT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS, F_MS | F_RT); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN, F_MS | F_RT); return info; } case DXGI_FORMAT_R32G32B32_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_SAMPLE, F_MS | F_RT); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT); return info; } case DXGI_FORMAT_R32G32B32_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R32G32B32_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_SAMPLE, F_MS | F_RT); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT); return info; } case DXGI_FORMAT_R32G32_FLOAT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R32G32_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R32G32_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R32G32_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R32G8X24_TYPELESS: { - static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R32_FLOAT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: { - static const DXGISupport info(F_2D | F_CUBE | F_SAMPLE, F_3D | F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_CUBE | F_SAMPLE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_R32_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R32_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R32_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R8G8B8A8_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R8G8B8A8_SNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R8G8B8A8_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R8G8B8A8_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R8G8B8A8_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R8G8_B8G8_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_R8G8_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R8G8_SNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R8G8_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R8G8_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R8G8_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R8_SINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R8_SNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R8_TYPELESS: { - static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_R8_UINT: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_SAMPLE, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); return info; } case DXGI_FORMAT_R8_UNORM: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); return info; } case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: { - static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MS | F_RT, 0); + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_UNKNOWN: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_X24_TYPELESS_G8_UINT: { - static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: { - static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); return info; } case DXGI_FORMAT_Y210: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_Y216: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_Y410: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_Y416: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } case DXGI_FORMAT_YUY2: { - static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MS | F_RT | F_SAMPLE, 0); + static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); return info; } @@ -1814,6 +2411,600 @@ const DXGISupport &GetDXGISupport_11_0(DXGI_FORMAT dxgiFormat) UNREACHABLE(); return GetDefaultSupport(); } + // clang-format on +} + +const DXGISupport &GetDXGISupport_11_1(DXGI_FORMAT dxgiFormat) +{ + // clang-format off + switch (dxgiFormat) + { + case DXGI_FORMAT_420_OPAQUE: + { + static const DXGISupport info(F_2D, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_A8P8: + { + static const DXGISupport info(F_2D, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_A8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_AI44: + { + static const DXGISupport info(F_2D, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_AYUV: + { + static const DXGISupport info(F_2D | F_RT | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_B4G4R4A4_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_B5G5R5A1_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_B5G6R5_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); + return info; + } + case DXGI_FORMAT_B8G8R8A8_UNORM: + { + static const DXGISupport info(F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_2D | F_3D | F_CUBE | F_MS); + return info; + } + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + { + static const DXGISupport info(F_RT | F_SAMPLE, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS); + return info; + } + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + { + static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE); + return info; + } + case DXGI_FORMAT_B8G8R8X8_UNORM: + { + static const DXGISupport info(F_RT | F_SAMPLE, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS); + return info; + } + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + { + static const DXGISupport info(F_RT | F_SAMPLE, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS); + return info; + } + case DXGI_FORMAT_BC1_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC1_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC1_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC2_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC2_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC2_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC3_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC3_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC3_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC4_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC4_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC4_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC5_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC5_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC5_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC6H_SF16: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC6H_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC6H_UF16: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC7_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_BC7_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_BC7_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_D16_UNORM: + { + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_D24_UNORM_S8_UINT: + { + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_D32_FLOAT: + { + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + { + static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_G8R8_G8B8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_IA44: + { + static const DXGISupport info(F_2D, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_NV11: + { + static const DXGISupport info(F_2D | F_RT | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_NV12: + { + static const DXGISupport info(F_2D | F_RT | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_P010: + { + static const DXGISupport info(F_2D | F_RT | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_P016: + { + static const DXGISupport info(F_2D | F_RT | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS); + return info; + } + case DXGI_FORMAT_P8: + { + static const DXGISupport info(F_2D, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R10G10B10A2_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R10G10B10A2_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + { + static const DXGISupport info(0, F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D); + return info; + } + case DXGI_FORMAT_R11G11B10_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R16G16B16A16_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16B16A16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R16G16_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16G16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R16_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R16_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R16_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R1_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R24G8_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE | F_SAMPLE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_R32G32B32A32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R32G32B32A32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32G32B32A32_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32B32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_R32G32B32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_R32G32B32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32G32B32_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT); + return info; + } + case DXGI_FORMAT_R32G32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R32G32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32G32_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32G8X24_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32_FLOAT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + { + static const DXGISupport info(F_2D | F_CUBE | F_SAMPLE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_R32_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R32_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R32_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R8G8B8A8_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_B8G8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_R8G8_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R8G8_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8G8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8_SINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8_SNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R8_TYPELESS: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_R8_UINT: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS); + return info; + } + case DXGI_FORMAT_R8_UNORM: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS); + return info; + } + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + { + static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_UNKNOWN: + { + static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + { + static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0); + return info; + } + case DXGI_FORMAT_Y210: + { + static const DXGISupport info(F_2D | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_Y216: + { + static const DXGISupport info(F_2D | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_Y410: + { + static const DXGISupport info(F_2D | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_Y416: + { + static const DXGISupport info(F_2D | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + case DXGI_FORMAT_YUY2: + { + static const DXGISupport info(F_2D | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0); + return info; + } + + default: + UNREACHABLE(); + return GetDefaultSupport(); + } + // clang-format on } } @@ -1825,17 +3016,22 @@ const DXGISupport &GetDXGISupport_11_0(DXGI_FORMAT dxgiFormat) #undef F_RT #undef F_MS #undef F_DS +#undef F_MIPGEN const DXGISupport &GetDXGISupport(DXGI_FORMAT dxgiFormat, D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { + case D3D_FEATURE_LEVEL_9_3: + return GetDXGISupport_9_3(dxgiFormat); case D3D_FEATURE_LEVEL_10_0: return GetDXGISupport_10_0(dxgiFormat); case D3D_FEATURE_LEVEL_10_1: return GetDXGISupport_10_1(dxgiFormat); case D3D_FEATURE_LEVEL_11_0: return GetDXGISupport_11_0(dxgiFormat); + case D3D_FEATURE_LEVEL_11_1: + return GetDXGISupport_11_1(dxgiFormat); default: return GetDefaultSupport(); } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.h index 1d8d68565e..a818f376ef 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.h @@ -8,6 +8,9 @@ // version, D3D feature level, and is sometimes guaranteed or optional. // +#ifndef LIBANGLE_RENDERER_D3D_D3D11_DXGI_SUPPORT_TABLE_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_DXGI_SUPPORT_TABLE_H_ + #include "common/platform.h" namespace rx @@ -42,3 +45,5 @@ const DXGISupport &GetDXGISupport(DXGI_FORMAT dxgiFormat, D3D_FEATURE_LEVEL feat } // namespace d3d11 } // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_DXGI_SUPPORT_TABLE_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp index f073e9f46f..ce4edd26db 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp @@ -9,14 +9,15 @@ #include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "image_util/copyimage.h" +#include "image_util/generatemip.h" +#include "image_util/loadimage.h" + #include "libANGLE/formatutils.h" -#include "libANGLE/renderer/d3d/copyimage.h" #include "libANGLE/renderer/d3d/d3d11/copyvertex.h" +#include "libANGLE/renderer/d3d/d3d11/dxgi_support_table.h" #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #include "libANGLE/renderer/d3d/d3d11/Renderer11.h" -#include "libANGLE/renderer/d3d/generatemip.h" -#include "libANGLE/renderer/d3d/loadimage.h" -#include "libANGLE/renderer/Renderer.h" namespace rx { @@ -24,559 +25,388 @@ namespace rx namespace d3d11 { -typedef std::map DXGIToESFormatMap; - -inline void AddDXGIToESEntry(DXGIToESFormatMap *map, DXGI_FORMAT key, GLenum value) +bool SupportsMipGen(DXGI_FORMAT dxgiFormat, D3D_FEATURE_LEVEL featureLevel) { - map->insert(std::make_pair(key, value)); + const auto &support = GetDXGISupport(dxgiFormat, featureLevel); + ASSERT((support.optionallySupportedFlags & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN) == 0); + return ((support.alwaysSupportedFlags & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN) != 0); } -static DXGIToESFormatMap BuildDXGIToESFormatMap() +DXGIFormatSize::DXGIFormatSize(GLuint pixelBits, GLuint blockWidth, GLuint blockHeight) + : pixelBytes(pixelBits / 8), blockWidth(blockWidth), blockHeight(blockHeight) { - DXGIToESFormatMap map; - - AddDXGIToESEntry(&map, DXGI_FORMAT_UNKNOWN, GL_NONE); - - AddDXGIToESEntry(&map, DXGI_FORMAT_A8_UNORM, GL_ALPHA8_EXT); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8_UNORM, GL_R8); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_UNORM, GL_RG8); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_UNORM, GL_RGBA8); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, GL_SRGB8_ALPHA8); - AddDXGIToESEntry(&map, DXGI_FORMAT_B8G8R8A8_UNORM, GL_BGRA8_EXT); - - AddDXGIToESEntry(&map, DXGI_FORMAT_R8_SNORM, GL_R8_SNORM); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_SNORM, GL_RG8_SNORM); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_SNORM, GL_RGBA8_SNORM); - - AddDXGIToESEntry(&map, DXGI_FORMAT_R8_UINT, GL_R8UI); - AddDXGIToESEntry(&map, DXGI_FORMAT_R16_UINT, GL_R16UI); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32_UINT, GL_R32UI); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_UINT, GL_RG8UI); - AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16_UINT, GL_RG16UI); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32_UINT, GL_RG32UI); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32_UINT, GL_RGB32UI); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_UINT, GL_RGBA8UI); - AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16B16A16_UINT, GL_RGBA16UI); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32A32_UINT, GL_RGBA32UI); - - AddDXGIToESEntry(&map, DXGI_FORMAT_R8_SINT, GL_R8I); - AddDXGIToESEntry(&map, DXGI_FORMAT_R16_SINT, GL_R16I); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32_SINT, GL_R32I); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8_SINT, GL_RG8I); - AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16_SINT, GL_RG16I); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32_SINT, GL_RG32I); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32_SINT, GL_RGB32I); - AddDXGIToESEntry(&map, DXGI_FORMAT_R8G8B8A8_SINT, GL_RGBA8I); - AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16B16A16_SINT, GL_RGBA16I); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32A32_SINT, GL_RGBA32I); - - AddDXGIToESEntry(&map, DXGI_FORMAT_R10G10B10A2_UNORM, GL_RGB10_A2); - AddDXGIToESEntry(&map, DXGI_FORMAT_R10G10B10A2_UINT, GL_RGB10_A2UI); - - AddDXGIToESEntry(&map, DXGI_FORMAT_R16_FLOAT, GL_R16F); - AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16_FLOAT, GL_RG16F); - AddDXGIToESEntry(&map, DXGI_FORMAT_R16G16B16A16_FLOAT, GL_RGBA16F); - - AddDXGIToESEntry(&map, DXGI_FORMAT_R32_FLOAT, GL_R32F); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32_FLOAT, GL_RG32F); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32_FLOAT, GL_RGB32F); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G32B32A32_FLOAT, GL_RGBA32F); - - AddDXGIToESEntry(&map, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, GL_RGB9_E5); - AddDXGIToESEntry(&map, DXGI_FORMAT_R11G11B10_FLOAT, GL_R11F_G11F_B10F); - - AddDXGIToESEntry(&map, DXGI_FORMAT_R16_TYPELESS, GL_DEPTH_COMPONENT16); - AddDXGIToESEntry(&map, DXGI_FORMAT_R16_UNORM, GL_DEPTH_COMPONENT16); - AddDXGIToESEntry(&map, DXGI_FORMAT_D16_UNORM, GL_DEPTH_COMPONENT16); - AddDXGIToESEntry(&map, DXGI_FORMAT_R24G8_TYPELESS, GL_DEPTH24_STENCIL8_OES); - AddDXGIToESEntry(&map, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, GL_DEPTH24_STENCIL8_OES); - AddDXGIToESEntry(&map, DXGI_FORMAT_D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8_OES); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32G8X24_TYPELESS, GL_DEPTH32F_STENCIL8); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, GL_DEPTH32F_STENCIL8); - AddDXGIToESEntry(&map, DXGI_FORMAT_D32_FLOAT_S8X24_UINT, GL_DEPTH32F_STENCIL8); - AddDXGIToESEntry(&map, DXGI_FORMAT_R32_TYPELESS, GL_DEPTH_COMPONENT32F); - AddDXGIToESEntry(&map, DXGI_FORMAT_D32_FLOAT, GL_DEPTH_COMPONENT32F); - - AddDXGIToESEntry(&map, DXGI_FORMAT_BC1_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT); - AddDXGIToESEntry(&map, DXGI_FORMAT_BC2_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE); - AddDXGIToESEntry(&map, DXGI_FORMAT_BC3_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE); - - AddDXGIToESEntry(&map, DXGI_FORMAT_B5G6R5_UNORM, GL_RGB565); - AddDXGIToESEntry(&map, DXGI_FORMAT_B5G5R5A1_UNORM, GL_RGB5_A1); - AddDXGIToESEntry(&map, DXGI_FORMAT_B4G4R4A4_UNORM, GL_RGBA4); - - return map; } -struct D3D11FastCopyFormat +const DXGIFormatSize &GetDXGIFormatSizeInfo(DXGI_FORMAT format) { - GLenum destFormat; - GLenum destType; - ColorCopyFunction copyFunction; - - D3D11FastCopyFormat(GLenum destFormat, GLenum destType, ColorCopyFunction copyFunction) - : destFormat(destFormat), destType(destType), copyFunction(copyFunction) - { } - - bool operator<(const D3D11FastCopyFormat& other) const + static const DXGIFormatSize sizeUnknown(0, 0, 0); + static const DXGIFormatSize size128(128, 1, 1); + static const DXGIFormatSize size96(96, 1, 1); + static const DXGIFormatSize size64(64, 1, 1); + static const DXGIFormatSize size32(32, 1, 1); + static const DXGIFormatSize size16(16, 1, 1); + static const DXGIFormatSize size8(8, 1, 1); + static const DXGIFormatSize sizeBC1(64, 4, 4); + static const DXGIFormatSize sizeBC2(128, 4, 4); + static const DXGIFormatSize sizeBC3(128, 4, 4); + static const DXGIFormatSize sizeBC4(64, 4, 4); + static const DXGIFormatSize sizeBC5(128, 4, 4); + static const DXGIFormatSize sizeBC6H(128, 4, 4); + static const DXGIFormatSize sizeBC7(128, 4, 4); + switch (format) { - return memcmp(this, &other, sizeof(D3D11FastCopyFormat)) < 0; - } -}; - -typedef std::multimap D3D11FastCopyMap; - -static D3D11FastCopyMap BuildFastCopyMap() -{ - D3D11FastCopyMap map; - - map.insert(std::make_pair(DXGI_FORMAT_B8G8R8A8_UNORM, D3D11FastCopyFormat(GL_RGBA, GL_UNSIGNED_BYTE, CopyBGRA8ToRGBA8))); - - return map; -} - -struct DXGIColorFormatInfo -{ - size_t redBits; - size_t greenBits; - size_t blueBits; - - size_t luminanceBits; - - size_t alphaBits; - size_t sharedBits; -}; - -typedef std::map ColorFormatInfoMap; -typedef std::pair ColorFormatInfoPair; - -static inline void InsertDXGIColorFormatInfo(ColorFormatInfoMap *map, DXGI_FORMAT format, size_t redBits, size_t greenBits, - size_t blueBits, size_t alphaBits, size_t sharedBits) -{ - DXGIColorFormatInfo info; - info.redBits = redBits; - info.greenBits = greenBits; - info.blueBits = blueBits; - info.alphaBits = alphaBits; - info.sharedBits = sharedBits; - - map->insert(std::make_pair(format, info)); -} - -static ColorFormatInfoMap BuildColorFormatInfoMap() -{ - ColorFormatInfoMap map; - - // | DXGI format | R | G | B | A | S | - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_A8_UNORM, 0, 0, 0, 8, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8_UNORM, 8, 0, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8_UNORM, 8, 8, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8B8A8_UNORM, 8, 8, 8, 8, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, 8, 8, 8, 8, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_B8G8R8A8_UNORM, 8, 8, 8, 8, 0); - - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8_SNORM, 8, 0, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8_SNORM, 8, 8, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8B8A8_SNORM, 8, 8, 8, 8, 0); - - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8_UINT, 8, 0, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16_UINT, 16, 0, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32_UINT, 32, 0, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8_UINT, 8, 8, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16_UINT, 16, 16, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32_UINT, 32, 32, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32B32_UINT, 32, 32, 32, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8B8A8_UINT, 8, 8, 8, 8, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16B16A16_UINT, 16, 16, 16, 16, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32B32A32_UINT, 32, 32, 32, 32, 0); - - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8_SINT, 8, 0, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16_SINT, 16, 0, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32_SINT, 32, 0, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8_SINT, 8, 8, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16_SINT, 16, 16, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32_SINT, 32, 32, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32B32_SINT, 32, 32, 32, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R8G8B8A8_SINT, 8, 8, 8, 8, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16B16A16_SINT, 16, 16, 16, 16, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32B32A32_SINT, 32, 32, 32, 32, 0); - - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R10G10B10A2_UNORM, 10, 10, 10, 2, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R10G10B10A2_UINT, 10, 10, 10, 2, 0); - - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16_FLOAT, 16, 0, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16_FLOAT, 16, 16, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R16G16B16A16_FLOAT, 16, 16, 16, 16, 0); - - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32_FLOAT, 32, 0, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32_FLOAT, 32, 32, 0, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32B32_FLOAT, 32, 32, 32, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R32G32B32A32_FLOAT, 32, 32, 32, 32, 0); - - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, 9, 9, 9, 0, 5); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_R11G11B10_FLOAT, 11, 11, 10, 0, 0); - - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_B5G6R5_UNORM, 5, 6, 5, 0, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_B4G4R4A4_UNORM, 4, 4, 4, 4, 0); - InsertDXGIColorFormatInfo(&map, DXGI_FORMAT_B5G5R5A1_UNORM, 5, 5, 5, 1, 0); - - return map; -} - -struct DXGIDepthStencilInfo -{ - unsigned int depthBits; - unsigned int depthOffset; - unsigned int stencilBits; - unsigned int stencilOffset; -}; - -typedef std::map DepthStencilInfoMap; -typedef std::pair DepthStencilInfoPair; - -static inline void InsertDXGIDepthStencilInfo(DepthStencilInfoMap *map, DXGI_FORMAT format, unsigned int depthBits, - unsigned int depthOffset, unsigned int stencilBits, unsigned int stencilOffset) -{ - DXGIDepthStencilInfo info; - info.depthBits = depthBits; - info.depthOffset = depthOffset; - info.stencilBits = stencilBits; - info.stencilOffset = stencilOffset; - - map->insert(std::make_pair(format, info)); -} - -static DepthStencilInfoMap BuildDepthStencilInfoMap() -{ - DepthStencilInfoMap map; - - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R16_TYPELESS, 16, 0, 0, 0); - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R16_UNORM, 16, 0, 0, 0); - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D16_UNORM, 16, 0, 0, 0); - - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R24G8_TYPELESS, 24, 0, 8, 24); - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, 24, 0, 8, 24); - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D24_UNORM_S8_UINT, 24, 0, 8, 24); - - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R32_TYPELESS, 32, 0, 0, 0); - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R32_FLOAT, 32, 0, 0, 0); - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D32_FLOAT, 32, 0, 0, 0); - - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R32G8X24_TYPELESS, 32, 0, 8, 32); - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, 32, 0, 8, 32); - InsertDXGIDepthStencilInfo(&map, DXGI_FORMAT_D32_FLOAT_S8X24_UINT, 32, 0, 8, 32); - - return map; -} - -typedef std::map DXGIFormatInfoMap; - -DXGIFormat::DXGIFormat() - : pixelBytes(0), - blockWidth(0), - blockHeight(0), - redBits(0), - greenBits(0), - blueBits(0), - alphaBits(0), - sharedBits(0), - depthBits(0), - depthOffset(0), - stencilBits(0), - stencilOffset(0), - internalFormat(GL_NONE), - componentType(GL_NONE), - mipGenerationFunction(NULL), - colorReadFunction(NULL), - fastCopyFunctions(), - nativeMipmapSupport(NULL) -{ -} - -static bool NeverSupported(D3D_FEATURE_LEVEL) -{ - return false; -} - -template -static bool RequiresFeatureLevel(D3D_FEATURE_LEVEL featureLevel) -{ - return featureLevel >= requiredFeatureLevel; -} - -ColorCopyFunction DXGIFormat::getFastCopyFunction(GLenum format, GLenum type) const -{ - FastCopyFunctionMap::const_iterator iter = fastCopyFunctions.find(std::make_pair(format, type)); - return (iter != fastCopyFunctions.end()) ? iter->second : NULL; -} - -void AddDXGIFormat(DXGIFormatInfoMap *map, DXGI_FORMAT dxgiFormat, GLuint pixelBits, GLuint blockWidth, GLuint blockHeight, - GLenum componentType, MipGenerationFunction mipFunc, ColorReadFunction readFunc, NativeMipmapGenerationSupportFunction nativeMipmapSupport) -{ - DXGIFormat info; - info.pixelBytes = pixelBits / 8; - info.blockWidth = blockWidth; - info.blockHeight = blockHeight; - - static const ColorFormatInfoMap colorInfoMap = BuildColorFormatInfoMap(); - ColorFormatInfoMap::const_iterator colorInfoIter = colorInfoMap.find(dxgiFormat); - if (colorInfoIter != colorInfoMap.end()) - { - const DXGIColorFormatInfo &colorInfo = colorInfoIter->second; - info.redBits = static_cast(colorInfo.redBits); - info.greenBits = static_cast(colorInfo.greenBits); - info.blueBits = static_cast(colorInfo.blueBits); - info.alphaBits = static_cast(colorInfo.alphaBits); - info.sharedBits = static_cast(colorInfo.sharedBits); - } - - static const DepthStencilInfoMap dsInfoMap = BuildDepthStencilInfoMap(); - DepthStencilInfoMap::const_iterator dsInfoIter = dsInfoMap.find(dxgiFormat); - if (dsInfoIter != dsInfoMap.end()) - { - const DXGIDepthStencilInfo &dsInfo = dsInfoIter->second; - info.depthBits = dsInfo.depthBits; - info.depthOffset = dsInfo.depthOffset; - info.stencilBits = dsInfo.stencilBits; - info.stencilOffset = dsInfo.stencilOffset; - } - - static const DXGIToESFormatMap dxgiToESMap = BuildDXGIToESFormatMap(); - DXGIToESFormatMap::const_iterator dxgiToESIter = dxgiToESMap.find(dxgiFormat); - info.internalFormat = (dxgiToESIter != dxgiToESMap.end()) ? dxgiToESIter->second : GL_NONE; - - info.componentType = componentType; - - info.mipGenerationFunction = mipFunc; - info.colorReadFunction = readFunc; - - static const D3D11FastCopyMap fastCopyMap = BuildFastCopyMap(); - std::pair fastCopyIter = fastCopyMap.equal_range(dxgiFormat); - for (D3D11FastCopyMap::const_iterator i = fastCopyIter.first; i != fastCopyIter.second; i++) - { - info.fastCopyFunctions.insert(std::make_pair(std::make_pair(i->second.destFormat, i->second.destType), i->second.copyFunction)); - } - - info.nativeMipmapSupport = nativeMipmapSupport; - - map->insert(std::make_pair(dxgiFormat, info)); -} - -// A map to determine the pixel size and mipmap generation function of a given DXGI format -static DXGIFormatInfoMap BuildDXGIFormatInfoMap() -{ - DXGIFormatInfoMap map; - - // | DXGI format |S |W |H |Component Type | Mip generation function | Color read function | Native mipmap function - AddDXGIFormat(&map, DXGI_FORMAT_UNKNOWN, 0, 0, 0, GL_NONE, NULL, NULL, NeverSupported); - - AddDXGIFormat(&map, DXGI_FORMAT_A8_UNORM, 8, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip, ReadColor, RequiresFeatureLevel); - AddDXGIFormat(&map, DXGI_FORMAT_R8_UNORM, 8, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip, ReadColor, RequiresFeatureLevel); - AddDXGIFormat(&map, DXGI_FORMAT_R8G8_UNORM, 16, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip, ReadColor, RequiresFeatureLevel); - AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_UNORM, 32, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip, ReadColor, RequiresFeatureLevel); - AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, 32, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip, ReadColor, RequiresFeatureLevel); - AddDXGIFormat(&map, DXGI_FORMAT_B8G8R8A8_UNORM, 32, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip, ReadColor, RequiresFeatureLevel); - - AddDXGIFormat(&map, DXGI_FORMAT_R8_SNORM, 8, 1, 1, GL_SIGNED_NORMALIZED, GenerateMip, ReadColor , RequiresFeatureLevel); - AddDXGIFormat(&map, DXGI_FORMAT_R8G8_SNORM, 16, 1, 1, GL_SIGNED_NORMALIZED, GenerateMip, ReadColor , RequiresFeatureLevel); - AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_SNORM, 32, 1, 1, GL_SIGNED_NORMALIZED, GenerateMip, ReadColor, RequiresFeatureLevel); - - AddDXGIFormat(&map, DXGI_FORMAT_R8_UINT, 8, 1, 1, GL_UNSIGNED_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R16_UINT, 16, 1, 1, GL_UNSIGNED_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R32_UINT, 32, 1, 1, GL_UNSIGNED_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R8G8_UINT, 16, 1, 1, GL_UNSIGNED_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R16G16_UINT, 32, 1, 1, GL_UNSIGNED_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R32G32_UINT, 64, 1, 1, GL_UNSIGNED_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32_UINT, 96, 1, 1, GL_UNSIGNED_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_UINT, 32, 1, 1, GL_UNSIGNED_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_UINT, 64, 1, 1, GL_UNSIGNED_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32A32_UINT, 128, 1, 1, GL_UNSIGNED_INT, GenerateMip, ReadColor, NeverSupported); - - AddDXGIFormat(&map, DXGI_FORMAT_R8_SINT, 8, 1, 1, GL_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R16_SINT, 16, 1, 1, GL_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R32_SINT, 32, 1, 1, GL_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R8G8_SINT, 16, 1, 1, GL_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R16G16_SINT, 32, 1, 1, GL_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R32G32_SINT, 64, 1, 1, GL_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32_SINT, 96, 1, 1, GL_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R8G8B8A8_SINT, 32, 1, 1, GL_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_SINT, 64, 1, 1, GL_INT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32A32_SINT, 128, 1, 1, GL_INT, GenerateMip, ReadColor, NeverSupported); - - AddDXGIFormat(&map, DXGI_FORMAT_R10G10B10A2_UNORM, 32, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip, ReadColor, RequiresFeatureLevel); - AddDXGIFormat(&map, DXGI_FORMAT_R10G10B10A2_UINT, 32, 1, 1, GL_UNSIGNED_INT, GenerateMip, ReadColor, NeverSupported); - - AddDXGIFormat(&map, DXGI_FORMAT_R16_FLOAT, 16, 1, 1, GL_FLOAT, GenerateMip, ReadColor, RequiresFeatureLevel); - AddDXGIFormat(&map, DXGI_FORMAT_R16G16_FLOAT, 32, 1, 1, GL_FLOAT, GenerateMip, ReadColor, RequiresFeatureLevel); - AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_FLOAT, 64, 1, 1, GL_FLOAT, GenerateMip, ReadColor, RequiresFeatureLevel); - - AddDXGIFormat(&map, DXGI_FORMAT_R32_FLOAT, 32, 1, 1, GL_FLOAT, GenerateMip, ReadColor, RequiresFeatureLevel); - AddDXGIFormat(&map, DXGI_FORMAT_R32G32_FLOAT, 64, 1, 1, GL_FLOAT, GenerateMip, ReadColor, RequiresFeatureLevel); - AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32_FLOAT, 96, 1, 1, GL_FLOAT, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R32G32B32A32_FLOAT, 128, 1, 1, GL_FLOAT, GenerateMip, ReadColor, RequiresFeatureLevel); - - AddDXGIFormat(&map, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, 32, 1, 1, GL_FLOAT, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R11G11B10_FLOAT, 32, 1, 1, GL_FLOAT, GenerateMip, ReadColor, RequiresFeatureLevel); - - AddDXGIFormat(&map, DXGI_FORMAT_R16_TYPELESS, 16, 1, 1, GL_NONE, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R16_UNORM, 16, 1, 1, GL_UNSIGNED_NORMALIZED, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_D16_UNORM, 16, 1, 1, GL_UNSIGNED_NORMALIZED, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R24G8_TYPELESS, 32, 1, 1, GL_NONE, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, 32, 1, 1, GL_NONE, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_D24_UNORM_S8_UINT, 32, 1, 1, GL_UNSIGNED_INT, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R32G8X24_TYPELESS, 64, 1, 1, GL_NONE, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, 64, 1, 1, GL_NONE, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_D32_FLOAT_S8X24_UINT, 64, 1, 1, GL_UNSIGNED_INT, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R32_TYPELESS, 32, 1, 1, GL_NONE, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_D32_FLOAT, 32, 1, 1, GL_FLOAT, NULL, NULL, NeverSupported); - - AddDXGIFormat(&map, DXGI_FORMAT_BC1_UNORM, 64, 4, 4, GL_UNSIGNED_NORMALIZED, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_BC2_UNORM, 128, 4, 4, GL_UNSIGNED_NORMALIZED, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_BC3_UNORM, 128, 4, 4, GL_UNSIGNED_NORMALIZED, NULL, NULL, NeverSupported); - - // B5G6R5 in D3D11 is treated the same as R5G6B5 in D3D9, so reuse the R5G6B5 functions used by the D3D9 renderer. - // The same applies to B4G4R4A4 and B5G5R5A1 with A4R4G4B4 and A1R5G5B5 respectively. - AddDXGIFormat(&map, DXGI_FORMAT_B5G6R5_UNORM, 16, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip, ReadColor, RequiresFeatureLevel); - AddDXGIFormat(&map, DXGI_FORMAT_B4G4R4A4_UNORM, 16, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip, ReadColor, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_B5G5R5A1_UNORM, 16, 1, 1, GL_UNSIGNED_NORMALIZED, GenerateMip, ReadColor, NeverSupported); - - // Useful formats for vertex buffers - AddDXGIFormat(&map, DXGI_FORMAT_R16_UNORM, 16, 1, 1, GL_UNSIGNED_NORMALIZED, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R16_SNORM, 16, 1, 1, GL_SIGNED_NORMALIZED, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R16G16_UNORM, 32, 1, 1, GL_UNSIGNED_NORMALIZED, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R16G16_SNORM, 32, 1, 1, GL_SIGNED_NORMALIZED, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_UNORM, 64, 1, 1, GL_UNSIGNED_NORMALIZED, NULL, NULL, NeverSupported); - AddDXGIFormat(&map, DXGI_FORMAT_R16G16B16A16_SNORM, 64, 1, 1, GL_SIGNED_NORMALIZED, NULL, NULL, NeverSupported); - - return map; -} - -const DXGIFormat &GetDXGIFormatInfo(DXGI_FORMAT format) -{ - static const DXGIFormatInfoMap infoMap = BuildDXGIFormatInfoMap(); - DXGIFormatInfoMap::const_iterator iter = infoMap.find(format); - if (iter != infoMap.end()) - { - return iter->second; - } - else - { - static DXGIFormat defaultInfo; - return defaultInfo; + case DXGI_FORMAT_UNKNOWN: + return sizeUnknown; + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DXGI_FORMAT_R32G32B32A32_FLOAT: + case DXGI_FORMAT_R32G32B32A32_UINT: + case DXGI_FORMAT_R32G32B32A32_SINT: + return size128; + case DXGI_FORMAT_R32G32B32_TYPELESS: + case DXGI_FORMAT_R32G32B32_FLOAT: + case DXGI_FORMAT_R32G32B32_UINT: + case DXGI_FORMAT_R32G32B32_SINT: + return size96; + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_R16G16B16A16_UNORM: + case DXGI_FORMAT_R16G16B16A16_UINT: + case DXGI_FORMAT_R16G16B16A16_SNORM: + case DXGI_FORMAT_R16G16B16A16_SINT: + case DXGI_FORMAT_R32G32_TYPELESS: + case DXGI_FORMAT_R32G32_FLOAT: + case DXGI_FORMAT_R32G32_UINT: + case DXGI_FORMAT_R32G32_SINT: + case DXGI_FORMAT_R32G8X24_TYPELESS: + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + return size64; + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_R10G10B10A2_UNORM: + case DXGI_FORMAT_R10G10B10A2_UINT: + case DXGI_FORMAT_R11G11B10_FLOAT: + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R8G8B8A8_SNORM: + case DXGI_FORMAT_R8G8B8A8_SINT: + case DXGI_FORMAT_R16G16_TYPELESS: + case DXGI_FORMAT_R16G16_FLOAT: + case DXGI_FORMAT_R16G16_UNORM: + case DXGI_FORMAT_R16G16_UINT: + case DXGI_FORMAT_R16G16_SNORM: + case DXGI_FORMAT_R16G16_SINT: + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_R32_UINT: + case DXGI_FORMAT_R32_SINT: + case DXGI_FORMAT_R24G8_TYPELESS: + case DXGI_FORMAT_D24_UNORM_S8_UINT: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + return size32; + case DXGI_FORMAT_R8G8_TYPELESS: + case DXGI_FORMAT_R8G8_UNORM: + case DXGI_FORMAT_R8G8_UINT: + case DXGI_FORMAT_R8G8_SNORM: + case DXGI_FORMAT_R8G8_SINT: + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_R16_FLOAT: + case DXGI_FORMAT_D16_UNORM: + case DXGI_FORMAT_R16_UNORM: + case DXGI_FORMAT_R16_UINT: + case DXGI_FORMAT_R16_SNORM: + case DXGI_FORMAT_R16_SINT: + return size16; + case DXGI_FORMAT_R8_TYPELESS: + case DXGI_FORMAT_R8_UNORM: + case DXGI_FORMAT_R8_UINT: + case DXGI_FORMAT_R8_SNORM: + case DXGI_FORMAT_R8_SINT: + case DXGI_FORMAT_A8_UNORM: + return size8; + case DXGI_FORMAT_R1_UNORM: + UNREACHABLE(); + return sizeUnknown; + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + case DXGI_FORMAT_R8G8_B8G8_UNORM: + case DXGI_FORMAT_G8R8_G8B8_UNORM: + return size32; + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + return sizeBC1; + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + return sizeBC2; + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: + return sizeBC3; + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC4_SNORM: + return sizeBC4; + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC5_SNORM: + return sizeBC5; + case DXGI_FORMAT_B5G6R5_UNORM: + case DXGI_FORMAT_B5G5R5A1_UNORM: + return size16; + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_B8G8R8X8_UNORM: + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + return size32; + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC6H_SF16: + return sizeBC6H; + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: + return sizeBC7; + case DXGI_FORMAT_AYUV: + case DXGI_FORMAT_Y410: + case DXGI_FORMAT_Y416: + case DXGI_FORMAT_NV12: + case DXGI_FORMAT_P010: + case DXGI_FORMAT_P016: + case DXGI_FORMAT_420_OPAQUE: + case DXGI_FORMAT_YUY2: + case DXGI_FORMAT_Y210: + case DXGI_FORMAT_Y216: + case DXGI_FORMAT_NV11: + case DXGI_FORMAT_AI44: + case DXGI_FORMAT_IA44: + case DXGI_FORMAT_P8: + case DXGI_FORMAT_A8P8: + UNREACHABLE(); + return sizeUnknown; + case DXGI_FORMAT_B4G4R4A4_UNORM: + return size16; + default: + UNREACHABLE(); + return sizeUnknown; } } -typedef std::map D3D11VertexFormatInfoMap; -typedef std::pair D3D11VertexFormatPair; - -VertexFormat::VertexFormat() - : conversionType(VERTEX_CONVERT_NONE), - nativeFormat(DXGI_FORMAT_UNKNOWN), - copyFunction(NULL) +constexpr VertexFormat::VertexFormat() + : conversionType(VERTEX_CONVERT_NONE), nativeFormat(DXGI_FORMAT_UNKNOWN), copyFunction(nullptr) { } -VertexFormat::VertexFormat(VertexConversionType conversionTypeIn, - DXGI_FORMAT nativeFormatIn, - VertexCopyFunction copyFunctionIn) - : conversionType(conversionTypeIn), - nativeFormat(nativeFormatIn), - copyFunction(copyFunctionIn) +constexpr VertexFormat::VertexFormat(VertexConversionType conversionTypeIn, + DXGI_FORMAT nativeFormatIn, + VertexCopyFunction copyFunctionIn) + : conversionType(conversionTypeIn), nativeFormat(nativeFormatIn), copyFunction(copyFunctionIn) { } -static void AddVertexFormatInfo(D3D11VertexFormatInfoMap *map, - GLenum inputType, - GLboolean normalized, - GLuint componentCount, - VertexConversionType conversionType, - DXGI_FORMAT nativeFormat, - VertexCopyFunction copyFunction) +const VertexFormat *GetVertexFormatInfo_FL_9_3(gl::VertexFormatType vertexFormatType) { - gl::VertexFormatType formatType = gl::GetVertexFormatType(inputType, normalized, componentCount, false); - - VertexFormat info; - info.conversionType = conversionType; - info.nativeFormat = nativeFormat; - info.copyFunction = copyFunction; - - map->insert(D3D11VertexFormatPair(formatType, info)); -} - -static D3D11VertexFormatInfoMap BuildD3D11_FL9_3VertexFormatInfoOverrideMap() -{ - // D3D11 Feature Level 9_3 doesn't support as many formats for vertex buffer resource as Feature Level 10_0+. + // D3D11 Feature Level 9_3 doesn't support as many formats for vertex buffer resource as Feature + // Level 10_0+. // http://msdn.microsoft.com/en-us/library/windows/desktop/ff471324(v=vs.85).aspx - D3D11VertexFormatInfoMap map; + switch (vertexFormatType) + { + // GL_BYTE -- unnormalized + case gl::VERTEX_FORMAT_SBYTE1: + { + static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16_SINT, + &Copy8SintTo16SintVertexData<1, 2>); + return &info; + } + case gl::VERTEX_FORMAT_SBYTE2: + { + static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16_SINT, + &Copy8SintTo16SintVertexData<2, 2>); + return &info; + } + case gl::VERTEX_FORMAT_SBYTE3: + { + static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_SINT, + &Copy8SintTo16SintVertexData<3, 4>); + return &info; + } + case gl::VERTEX_FORMAT_SBYTE4: + { + static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_SINT, + &Copy8SintTo16SintVertexData<4, 4>); + return &info; + } - // GL_BYTE -- unnormalized - AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 1, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16_SINT, &Copy8SintTo16SintVertexData<1, 2>); - AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 2, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16_SINT, &Copy8SintTo16SintVertexData<2, 2>); - AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 3, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_SINT, &Copy8SintTo16SintVertexData<3, 4>); - AddVertexFormatInfo(&map, GL_BYTE, GL_FALSE, 4, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_SINT, &Copy8SintTo16SintVertexData<4, 4>); + // GL_BYTE -- normalized + case gl::VERTEX_FORMAT_SBYTE1_NORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16_SNORM, + &Copy8SnormTo16SnormVertexData<1, 2>); + return &info; + } + case gl::VERTEX_FORMAT_SBYTE2_NORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16_SNORM, + &Copy8SnormTo16SnormVertexData<2, 2>); + return &info; + } + case gl::VERTEX_FORMAT_SBYTE3_NORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SNORM, + &Copy8SnormTo16SnormVertexData<3, 4>); + return &info; + } + case gl::VERTEX_FORMAT_SBYTE4_NORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SNORM, + &Copy8SnormTo16SnormVertexData<4, 4>); + return &info; + } - // GL_BYTE -- normalized - AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16_SNORM, &Copy8SnormTo16SnormVertexData<1, 2>); - AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 2, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16_SNORM, &Copy8SnormTo16SnormVertexData<2, 2>); - AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SNORM, &Copy8SnormTo16SnormVertexData<3, 4>); - AddVertexFormatInfo(&map, GL_BYTE, GL_TRUE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SNORM, &Copy8SnormTo16SnormVertexData<4, 4>); + // GL_UNSIGNED_BYTE -- un-normalized + // NOTE: 3 and 4 component unnormalized GL_UNSIGNED_BYTE should use the default format + // table. + case gl::VERTEX_FORMAT_UBYTE1: + { + static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_UINT, + &CopyNativeVertexData); + return &info; + } + case gl::VERTEX_FORMAT_UBYTE2: + { + static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_UINT, + &CopyNativeVertexData); + return &info; + } - // GL_UNSIGNED_BYTE -- unnormalized - AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 1, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_FALSE, 2, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData); - // NOTE: 3 and 4 component unnormalized GL_UNSIGNED_BYTE should use the default format table. + // GL_UNSIGNED_BYTE -- normalized + // NOTE: 3 and 4 component normalized GL_UNSIGNED_BYTE should use the default format table. - // GL_UNSIGNED_BYTE -- normalized - AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UNORM, &CopyNativeVertexData); - AddVertexFormatInfo(&map, GL_UNSIGNED_BYTE, GL_TRUE, 2, VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UNORM, &CopyNativeVertexData); - // NOTE: 3 and 4 component normalized GL_UNSIGNED_BYTE should use the default format table. + // GL_UNSIGNED_BYTE -- normalized + case gl::VERTEX_FORMAT_UBYTE1_NORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UNORM, + &CopyNativeVertexData); + return &info; + } + case gl::VERTEX_FORMAT_UBYTE2_NORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UNORM, + &CopyNativeVertexData); + return &info; + } - // GL_SHORT -- unnormalized - AddVertexFormatInfo(&map, GL_SHORT, GL_FALSE, 1, VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16_SINT, &CopyNativeVertexData); - // NOTE: 2, 3 and 4 component unnormalized GL_SHORT should use the default format table. + // GL_SHORT -- un-normalized + // NOTE: 2, 3 and 4 component unnormalized GL_SHORT should use the default format table. + case gl::VERTEX_FORMAT_SSHORT1: + { + static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16_SINT, + &CopyNativeVertexData); + return &info; + } - // GL_SHORT -- normalized - AddVertexFormatInfo(&map, GL_SHORT, GL_TRUE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16_SNORM, &CopyNativeVertexData); - // NOTE: 2, 3 and 4 component normalized GL_SHORT should use the default format table. + // GL_SHORT -- normalized + // NOTE: 2, 3 and 4 component normalized GL_SHORT should use the default format table. + case gl::VERTEX_FORMAT_SSHORT1_NORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16_SNORM, + &CopyNativeVertexData); + return &info; + } - // GL_UNSIGNED_SHORT -- unnormalized - AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &CopyTo32FVertexData); - AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 2, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &CopyTo32FVertexData); - AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &CopyTo32FVertexData); - AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_FALSE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyTo32FVertexData); + // GL_UNSIGNED_SHORT -- un-normalized + case gl::VERTEX_FORMAT_USHORT1: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, + &CopyTo32FVertexData); + return &info; + } + case gl::VERTEX_FORMAT_USHORT2: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, + &CopyTo32FVertexData); + return &info; + } + case gl::VERTEX_FORMAT_USHORT3: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, + &CopyTo32FVertexData); + return &info; + } + case gl::VERTEX_FORMAT_USHORT4: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, + &CopyTo32FVertexData); + return &info; + } - // GL_UNSIGNED_SHORT -- normalized - AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &CopyTo32FVertexData); - AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 2, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &CopyTo32FVertexData); - AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 3, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &CopyTo32FVertexData); - AddVertexFormatInfo(&map, GL_UNSIGNED_SHORT, GL_TRUE, 4, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyTo32FVertexData); + // GL_UNSIGNED_SHORT -- normalized + case gl::VERTEX_FORMAT_USHORT1_NORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, + &CopyTo32FVertexData); + return &info; + } + case gl::VERTEX_FORMAT_USHORT2_NORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, + &CopyTo32FVertexData); + return &info; + } + case gl::VERTEX_FORMAT_USHORT3_NORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, + &CopyTo32FVertexData); + return &info; + } + case gl::VERTEX_FORMAT_USHORT4_NORM: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, + &CopyTo32FVertexData); + return &info; + } - // GL_FIXED - // TODO: Add test to verify that this works correctly. - AddVertexFormatInfo(&map, GL_FIXED, GL_FALSE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &Copy32FixedTo32FVertexData<1, 2>); - // NOTE: 2, 3 and 4 component GL_FIXED should use the default format table. + // GL_FIXED + // TODO: Add test to verify that this works correctly. + // NOTE: 2, 3 and 4 component GL_FIXED should use the default format table. + case gl::VERTEX_FORMAT_FIXED1: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, + &Copy32FixedTo32FVertexData<1, 2>); + return &info; + } - // GL_FLOAT - // TODO: Add test to verify that this works correctly. - AddVertexFormatInfo(&map, GL_FLOAT, GL_FALSE, 1, VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &CopyNativeVertexData); - // NOTE: 2, 3 and 4 component GL_FLOAT should use the default format table. + // GL_FLOAT + // TODO: Add test to verify that this works correctly. + // NOTE: 2, 3 and 4 component GL_FLOAT should use the default format table. + case gl::VERTEX_FORMAT_FLOAT1: + { + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, + &CopyNativeVertexData); + return &info; + } - return map; + default: + return nullptr; + } } const VertexFormat &GetVertexFormatInfo(gl::VertexFormatType vertexFormatType, D3D_FEATURE_LEVEL featureLevel) { if (featureLevel == D3D_FEATURE_LEVEL_9_3) { - static const D3D11VertexFormatInfoMap vertexFormatMapFL9_3Override = - BuildD3D11_FL9_3VertexFormatInfoOverrideMap(); - - // First see if the format has a special mapping for FL9_3 - auto iter = vertexFormatMapFL9_3Override.find(vertexFormatType); - if (iter != vertexFormatMapFL9_3Override.end()) + const VertexFormat *result = GetVertexFormatInfo_FL_9_3(vertexFormatType); + if (result) { - return iter->second; + return *result; } } @@ -589,354 +419,418 @@ const VertexFormat &GetVertexFormatInfo(gl::VertexFormatType vertexFormatType, D // GL_BYTE -- un-normalized case gl::VERTEX_FORMAT_SBYTE1: { - static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_SINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_SBYTE2: { - static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_SINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_SBYTE3: { - static const VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_SINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_SBYTE4: { - static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_SINT, + &CopyNativeVertexData); return info; } // GL_BYTE -- normalized case gl::VERTEX_FORMAT_SBYTE1_NORM: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SNORM, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SNORM, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_SBYTE2_NORM: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SNORM, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SNORM, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_SBYTE3_NORM: { - static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SNORM, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SNORM, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_SBYTE4_NORM: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SNORM, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SNORM, + &CopyNativeVertexData); return info; } // GL_UNSIGNED_BYTE -- un-normalized case gl::VERTEX_FORMAT_UBYTE1: { - static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_UINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_UINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_UBYTE2: { - static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_UINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_UINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_UBYTE3: { - static const VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_UINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_UBYTE4: { - static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_UINT, + &CopyNativeVertexData); return info; } // GL_UNSIGNED_BYTE -- normalized case gl::VERTEX_FORMAT_UBYTE1_NORM: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UNORM, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UNORM, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_UBYTE2_NORM: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UNORM, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UNORM, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_UBYTE3_NORM: { - static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UNORM, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UNORM, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_UBYTE4_NORM: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UNORM, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UNORM, + &CopyNativeVertexData); return info; } // GL_SHORT -- un-normalized case gl::VERTEX_FORMAT_SSHORT1: { - static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_SINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_SSHORT2: { - static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_SINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_SSHORT3: { - static const VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_SINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_SSHORT4: { - static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_SINT, + &CopyNativeVertexData); return info; } // GL_SHORT -- normalized case gl::VERTEX_FORMAT_SSHORT1_NORM: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SNORM, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SNORM, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_SSHORT2_NORM: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SNORM, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SNORM, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_SSHORT3_NORM: { - static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SNORM, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SNORM, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_SSHORT4_NORM: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SNORM, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SNORM, + &CopyNativeVertexData); return info; } // GL_UNSIGNED_SHORT -- un-normalized case gl::VERTEX_FORMAT_USHORT1: { - static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_UINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_UINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_USHORT2: { - static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_UINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_UINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_USHORT3: { - static const VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_UINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_USHORT4: { - static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_UINT, + &CopyNativeVertexData); return info; } // GL_UNSIGNED_SHORT -- normalized case gl::VERTEX_FORMAT_USHORT1_NORM: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UNORM, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UNORM, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_USHORT2_NORM: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UNORM, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UNORM, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_USHORT3_NORM: { - static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UNORM, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UNORM, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_USHORT4_NORM: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UNORM, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UNORM, + &CopyNativeVertexData); return info; } // GL_INT -- un-normalized case gl::VERTEX_FORMAT_SINT1: { - static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_SINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_SINT2: { - static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_SINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_SINT3: { - static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_SINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_SINT4: { - static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_SINT, + &CopyNativeVertexData); return info; } // GL_INT -- normalized case gl::VERTEX_FORMAT_SINT1_NORM: { - static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, &CopyTo32FVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, + &CopyTo32FVertexData); return info; } case gl::VERTEX_FORMAT_SINT2_NORM: { - static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &CopyTo32FVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, + &CopyTo32FVertexData); return info; } case gl::VERTEX_FORMAT_SINT3_NORM: { - static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &CopyTo32FVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, + &CopyTo32FVertexData); return info; } case gl::VERTEX_FORMAT_SINT4_NORM: { - static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyTo32FVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, + &CopyTo32FVertexData); return info; } // GL_UNSIGNED_INT -- un-normalized case gl::VERTEX_FORMAT_UINT1: { - static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_UINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_UINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_UINT2: { - static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_UINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_UINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_UINT3: { - static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_UINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_UINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_UINT4: { - static const VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_UINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_UINT, + &CopyNativeVertexData); return info; } // GL_UNSIGNED_INT -- normalized case gl::VERTEX_FORMAT_UINT1_NORM: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT, &CopyTo32FVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, + &CopyTo32FVertexData); return info; } case gl::VERTEX_FORMAT_UINT2_NORM: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT, &CopyTo32FVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, + &CopyTo32FVertexData); return info; } case gl::VERTEX_FORMAT_UINT3_NORM: { - static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &CopyTo32FVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, + &CopyTo32FVertexData); return info; } case gl::VERTEX_FORMAT_UINT4_NORM: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyTo32FVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, + &CopyTo32FVertexData); return info; } // GL_FIXED case gl::VERTEX_FORMAT_FIXED1: { - static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, &Copy32FixedTo32FVertexData<1, 1>); + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT, + &Copy32FixedTo32FVertexData<1, 1>); return info; } case gl::VERTEX_FORMAT_FIXED2: { - static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, &Copy32FixedTo32FVertexData<2, 2>); + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT, + &Copy32FixedTo32FVertexData<2, 2>); return info; } case gl::VERTEX_FORMAT_FIXED3: { - static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, &Copy32FixedTo32FVertexData<3, 3>); + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT, + &Copy32FixedTo32FVertexData<3, 3>); return info; } case gl::VERTEX_FORMAT_FIXED4: { - static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &Copy32FixedTo32FVertexData<4, 4>); + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, + &Copy32FixedTo32FVertexData<4, 4>); return info; } // GL_HALF_FLOAT case gl::VERTEX_FORMAT_HALF1: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_FLOAT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_FLOAT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_HALF2: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_FLOAT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_FLOAT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_HALF3: { - static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_FLOAT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_FLOAT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_HALF4: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_FLOAT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_FLOAT, + &CopyNativeVertexData); return info; } // GL_FLOAT case gl::VERTEX_FORMAT_FLOAT1: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_FLOAT2: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_FLOAT3: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_FLOAT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_FLOAT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_FLOAT4: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT, + &CopyNativeVertexData); return info; } // GL_INT_2_10_10_10_REV case gl::VERTEX_FORMAT_SINT210: { - static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyXYZ10W2ToXYZW32FVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, + &CopyXYZ10W2ToXYZW32FVertexData); return info; } case gl::VERTEX_FORMAT_SINT210_NORM: { - static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyXYZ10W2ToXYZW32FVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, + &CopyXYZ10W2ToXYZW32FVertexData); return info; } // GL_UNSIGNED_INT_2_10_10_10_REV case gl::VERTEX_FORMAT_UINT210: { - static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, &CopyXYZ10W2ToXYZW32FVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT, + &CopyXYZ10W2ToXYZW32FVertexData); return info; } case gl::VERTEX_FORMAT_UINT210_NORM: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UNORM, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UNORM, + &CopyNativeVertexData); return info; } @@ -947,157 +841,183 @@ const VertexFormat &GetVertexFormatInfo(gl::VertexFormatType vertexFormatType, D // GL_BYTE case gl::VERTEX_FORMAT_SBYTE1_INT: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_SBYTE2_INT: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_SBYTE3_INT: { - static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_SBYTE4_INT: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SINT, + &CopyNativeVertexData); return info; } // GL_UNSIGNED_BYTE case gl::VERTEX_FORMAT_UBYTE1_INT: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_UBYTE2_INT: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_UBYTE3_INT: { - static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_UBYTE4_INT: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UINT, + &CopyNativeVertexData); return info; } // GL_SHORT case gl::VERTEX_FORMAT_SSHORT1_INT: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_SSHORT2_INT: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_SSHORT3_INT: { - static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_SSHORT4_INT: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SINT, + &CopyNativeVertexData); return info; } // GL_UNSIGNED_SHORT case gl::VERTEX_FORMAT_USHORT1_INT: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_USHORT2_INT: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_USHORT3_INT: { - static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_USHORT4_INT: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UINT, + &CopyNativeVertexData); return info; } // GL_INT case gl::VERTEX_FORMAT_SINT1_INT: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_SINT2_INT: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_SINT3_INT: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_SINT4_INT: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, + &CopyNativeVertexData); return info; } // GL_UNSIGNED_INT case gl::VERTEX_FORMAT_UINT1_INT: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_UINT2_INT: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_UINT3_INT: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT, + &CopyNativeVertexData); return info; } case gl::VERTEX_FORMAT_UINT4_INT: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT, + &CopyNativeVertexData); return info; } // GL_INT_2_10_10_10_REV case gl::VERTEX_FORMAT_SINT210_INT: { - static const VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT, &CopyXYZ10W2ToXYZW32FVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT, + &CopyXYZ10W2ToXYZW32FVertexData); return info; } // GL_UNSIGNED_INT_2_10_10_10_REV case gl::VERTEX_FORMAT_UINT210_INT: { - static const VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UINT, &CopyNativeVertexData); + static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UINT, + &CopyNativeVertexData); return info; } default: { - static const VertexFormat info; + static constexpr VertexFormat info; return info; } } } -} +} // namespace d3d11 -} +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.h index 7b97527140..883d338377 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/formatutils11.h @@ -15,6 +15,7 @@ #include "common/platform.h" #include "libANGLE/angletypes.h" #include "libANGLE/formatutils.h" +#include "libANGLE/renderer/renderer_utils.h" #include "libANGLE/renderer/d3d/formatutilsD3D.h" namespace rx @@ -24,58 +25,47 @@ struct Renderer11DeviceCaps; namespace d3d11 { -typedef std::map, ColorCopyFunction> FastCopyFunctionMap; -typedef bool (*NativeMipmapGenerationSupportFunction)(D3D_FEATURE_LEVEL); +// A texture might be stored as DXGI_FORMAT_R16_TYPELESS but store integer components, +// which are accessed through an DXGI_FORMAT_R16_SINT view. It's easy to write code which queries +// information about the wrong format. Therefore, use of this should be avoided where possible. -struct DXGIFormat +bool SupportsMipGen(DXGI_FORMAT dxgiFormat, D3D_FEATURE_LEVEL featureLevel); + +struct DXGIFormatSize { - DXGIFormat(); + DXGIFormatSize(GLuint pixelBits, GLuint blockWidth, GLuint blockHeight); GLuint pixelBytes; GLuint blockWidth; GLuint blockHeight; - - GLuint redBits; - GLuint greenBits; - GLuint blueBits; - GLuint alphaBits; - GLuint sharedBits; - - GLuint depthBits; - GLuint depthOffset; - GLuint stencilBits; - GLuint stencilOffset; - - GLenum internalFormat; - GLenum componentType; - - MipGenerationFunction mipGenerationFunction; - ColorReadFunction colorReadFunction; - - FastCopyFunctionMap fastCopyFunctions; - - NativeMipmapGenerationSupportFunction nativeMipmapSupport; - - ColorCopyFunction getFastCopyFunction(GLenum format, GLenum type) const; }; -const DXGIFormat &GetDXGIFormatInfo(DXGI_FORMAT format); +const DXGIFormatSize &GetDXGIFormatSizeInfo(DXGI_FORMAT format); -struct VertexFormat +struct VertexFormat : private angle::NonCopyable { - VertexFormat(); - VertexFormat(VertexConversionType conversionType, - DXGI_FORMAT nativeFormat, - VertexCopyFunction copyFunction); + constexpr VertexFormat(); + constexpr VertexFormat(VertexConversionType conversionType, + DXGI_FORMAT nativeFormat, + VertexCopyFunction copyFunction); VertexConversionType conversionType; DXGI_FORMAT nativeFormat; VertexCopyFunction copyFunction; }; + const VertexFormat &GetVertexFormatInfo(gl::VertexFormatType vertexFormatType, D3D_FEATURE_LEVEL featureLevel); +// Auto-generated in dxgi_format_map_autogen.cpp. +GLenum GetComponentType(DXGI_FORMAT dxgiFormat); + } // namespace d3d11 +namespace d3d11_angle +{ +const angle::Format &GetFormat(DXGI_FORMAT dxgiFormat); +} + } // namespace rx #endif // LIBANGLE_RENDERER_D3D_D3D11_FORMATUTILS11_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/gen_load_functions_table.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/gen_load_functions_table.cpp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.cpp deleted file mode 100644 index adb20a5e60..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.cpp +++ /dev/null @@ -1,170 +0,0 @@ -// -// Copyright 2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// internal_format_initializer_table: -// Contains table to go from internal format and dxgi format to initializer function -// for TextureFormat -// - -#include "libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.h" -#include "libANGLE/renderer/d3d/loadimage.h" - -namespace rx -{ - -namespace d3d11 -{ - -// TODO: This should be generated by a JSON file -InitializeTextureDataFunction GetInternalFormatInitializer(GLenum internalFormat, - DXGI_FORMAT dxgiFormat) -{ - switch (internalFormat) - { - case GL_RGB8: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: - { - return Initialize4ComponentData; - } - default: - break; - } - } - case GL_RGB565: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: - { - return Initialize4ComponentData; - } - default: - break; - } - } - case GL_SRGB8: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - { - return Initialize4ComponentData; - } - default: - break; - } - } - case GL_RGB16F: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16B16A16_FLOAT: - { - return Initialize4ComponentData; - } - default: - break; - } - } - case GL_RGB32F: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32G32B32A32_FLOAT: - { - return Initialize4ComponentData; - } - default: - break; - } - } - case GL_RGB8UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UINT: - { - return Initialize4ComponentData; - } - default: - break; - } - } - case GL_RGB8I: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_SINT: - { - return Initialize4ComponentData; - } - default: - break; - } - } - case GL_RGB16UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16B16A16_UINT: - { - return Initialize4ComponentData; - } - default: - break; - } - } - case GL_RGB16I: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16B16A16_SINT: - { - return Initialize4ComponentData; - } - default: - break; - } - } - case GL_RGB32UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32G32B32A32_UINT: - { - return Initialize4ComponentData; - } - default: - break; - } - } - case GL_RGB32I: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32G32B32A32_SINT: - { - return Initialize4ComponentData; - } - default: - break; - } - } - default: - { - return nullptr; - } - } -} - -} // namespace d3d11 - -} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.h deleted file mode 100644 index 2d538e1d82..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.h +++ /dev/null @@ -1,31 +0,0 @@ -// -// Copyright 2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// internal_format_initializer_table: -// Contains table to go from internal format and dxgi format to initializer function -// for TextureFormat -// - -#ifndef LIBANGLE_RENDERER_D3D_D3D11_INTERNALFORMATINITIALIZERTABLE_H_ -#define LIBANGLE_RENDERER_D3D_D3D11_INTERNALFORMATINITIALIZERTABLE_H_ - -#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" - -#include - -namespace rx -{ - -namespace d3d11 -{ - -InitializeTextureDataFunction GetInternalFormatInitializer(GLenum internalFormat, - DXGI_FORMAT dxgiFormat); - -} // namespace d3d11 - -} // namespace rx - -#endif // LIBANGLE_RENDERER_D3D_D3D11_INTERNALFORMATINITIALIZERTABLE_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_data.json b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_data.json deleted file mode 100644 index c85393e06b..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_data.json +++ /dev/null @@ -1,1116 +0,0 @@ -{ - "GL_RG8_SNORM": { - "GL_BYTE": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R8G8_SNORM", - "requiresConversion": "false" - } - ] - }, - "GL_SRGB8": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative3To4", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", - "requiresConversion": "true" - } - ] - }, - "GL_RGBA8I": { - "GL_BYTE": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_SINT", - "requiresConversion": "false" - } - ] - }, - "GL_R8_SNORM": { - "GL_BYTE": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R8_SNORM", - "requiresConversion": "false" - } - ] - }, - "GL_RGBA8_SNORM": { - "GL_BYTE": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_SNORM", - "requiresConversion": "false" - } - ] - }, - "GL_R16I": { - "GL_SHORT": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R16_SINT", - "requiresConversion": "false" - } - ] - }, - "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadETC2SRGBA8ToSRGBA8", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", - "requiresConversion": "true" - } - ] - }, - "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadETC2RGB8A1ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "true" - } - ] - }, - "GL_RGB32UI": { - "GL_UNSIGNED_INT": [ - { - "loadFunction": "LoadToNative3To4", - "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_UINT", - "requiresConversion": "true" - } - ] - }, - "GL_ALPHA32F_EXT": { - "GL_FLOAT": [ - { - "loadFunction": "LoadA32FToRGBA32F", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_R16UI": { - "GL_UNSIGNED_SHORT": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R16_UINT", - "requiresConversion": "false" - } - ] - }, - "GL_RGB9_E5": { - "GL_HALF_FLOAT": [ - { - "loadFunction": "LoadRGB16FToRGB9E5", - "dxgiFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP", - "requiresConversion": "true" - } - ], - "GL_UNSIGNED_INT_5_9_9_9_REV": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP", - "requiresConversion": "false" - } - ], - "GL_FLOAT": [ - { - "loadFunction": "LoadRGB32FToRGB9E5", - "dxgiFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP", - "requiresConversion": "true" - } - ], - "GL_HALF_FLOAT_OES": [ - { - "loadFunction": "LoadRGB16FToRGB9E5", - "dxgiFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP", - "requiresConversion": "true" - } - ] - }, - "GL_COMPRESSED_R11_EAC": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadEACR11ToR8", - "dxgiFormat": "DXGI_FORMAT_R8_UNORM", - "requiresConversion": "true" - } - ] - }, - "GL_RGBA32UI": { - "GL_UNSIGNED_INT": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_UINT", - "requiresConversion": "false" - } - ] - }, - "GL_RG8UI": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R8G8_UINT", - "requiresConversion": "false" - } - ] - }, - "GL_LUMINANCE32F_EXT": { - "GL_FLOAT": [ - { - "loadFunction": "LoadL32FToRGBA32F", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadETC2SRGB8A1ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", - "requiresConversion": "true" - } - ] - }, - "GL_R16F": { - "GL_HALF_FLOAT": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R16_FLOAT", - "requiresConversion": "false" - } - ], - "GL_FLOAT": [ - { - "loadFunction": "Load32FTo16F<1>", - "dxgiFormat": "DXGI_FORMAT_R16_FLOAT", - "requiresConversion": "true" - } - ], - "GL_HALF_FLOAT_OES": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R16_FLOAT", - "requiresConversion": "false" - } - ] - }, - "GL_RGBA8UI": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UINT", - "requiresConversion": "false" - } - ] - }, - "GL_BGRA4_ANGLEX": { - "GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT": [ - { - "loadFunction": "LoadRGBA4ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ], - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "false" - } - ] - }, - "GL_RGBA16F": { - "GL_HALF_FLOAT": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "requiresConversion": "false" - } - ], - "GL_FLOAT": [ - { - "loadFunction": "Load32FTo16F<4>", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "requiresConversion": "true" - } - ], - "GL_HALF_FLOAT_OES": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "requiresConversion": "false" - } - ] - }, - "GL_LUMINANCE8_EXT": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadL8ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadCompressedToNative<4,4,16>", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_RGB": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "UnreachableLoadFunction", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ], - "GL_UNSIGNED_SHORT_5_6_5": [ - { - "loadFunction": "UnreachableLoadFunction", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_RGB5_A1": { - "GL_UNSIGNED_INT_2_10_10_10_REV": [ - { - "loadFunction": "LoadRGB10A2ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "true" - } - ], - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "false" - } - ], - "GL_UNSIGNED_SHORT_5_5_5_1": [ - { - "loadFunction": "LoadRGB5A1ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "true" - }, - { - "loadFunction": "LoadRGB5A1ToA1RGB5", - "dxgiFormat": "DXGI_FORMAT_B5G5R5A1_UNORM", - "requiresConversion": "true" - } - ] - }, - "GL_RGB16UI": { - "GL_UNSIGNED_SHORT": [ - { - "loadFunction": "LoadToNative3To4", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_UINT", - "requiresConversion": "true" - } - ] - }, - "GL_BGRA_EXT": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "UnreachableLoadFunction", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_COMPRESSED_RGB8_ETC2": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadETC2RGB8ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "true" - } - ] - }, - "GL_RGBA32F": { - "GL_FLOAT": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", - "requiresConversion": "false" - } - ] - }, - "GL_RGBA32I": { - "GL_INT": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_SINT", - "requiresConversion": "false" - } - ] - }, - "GL_LUMINANCE8_ALPHA8_EXT": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadLA8ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_RG8": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R8G8_UNORM", - "requiresConversion": "false" - } - ] - }, - "GL_RGB10_A2": { - "GL_UNSIGNED_INT_2_10_10_10_REV": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R10G10B10A2_UNORM", - "requiresConversion": "false" - } - ] - }, - "GL_COMPRESSED_SIGNED_RG11_EAC": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadEACRG11SToRG8", - "dxgiFormat": "DXGI_FORMAT_R8G8_SNORM", - "requiresConversion": "true" - } - ] - }, - "GL_DEPTH_COMPONENT16": { - "GL_UNSIGNED_INT": [ - { - "loadFunction": "LoadR32ToR16", - "dxgiFormat": "DXGI_FORMAT_R16_TYPELESS", - "requiresConversion": "true" - } - ], - "GL_UNSIGNED_SHORT": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R16_TYPELESS", - "requiresConversion": "false" - }, - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_D16_UNORM", - "requiresConversion": "false" - } - ] - }, - "GL_RGB32I": { - "GL_INT": [ - { - "loadFunction": "LoadToNative3To4", - "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_SINT", - "requiresConversion": "true" - } - ] - }, - "GL_R8": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R8_UNORM", - "requiresConversion": "false" - } - ] - }, - "GL_RGB32F": { - "GL_FLOAT": [ - { - "loadFunction": "LoadToNative3To4", - "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", - "requiresConversion": "true" - } - ] - }, - "GL_R11F_G11F_B10F": { - "GL_UNSIGNED_INT_10F_11F_11F_REV": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R11G11B10_FLOAT", - "requiresConversion": "false" - } - ], - "GL_HALF_FLOAT": [ - { - "loadFunction": "LoadRGB16FToRG11B10F", - "dxgiFormat": "DXGI_FORMAT_R11G11B10_FLOAT", - "requiresConversion": "true" - } - ], - "GL_FLOAT": [ - { - "loadFunction": "LoadRGB32FToRG11B10F", - "dxgiFormat": "DXGI_FORMAT_R11G11B10_FLOAT", - "requiresConversion": "true" - } - ], - "GL_HALF_FLOAT_OES": [ - { - "loadFunction": "LoadRGB16FToRG11B10F", - "dxgiFormat": "DXGI_FORMAT_R11G11B10_FLOAT", - "requiresConversion": "true" - } - ] - }, - "GL_RGB8": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative3To4", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "true" - } - ] - }, - "GL_LUMINANCE_ALPHA": { - "GL_HALF_FLOAT": [ - { - "loadFunction": "LoadLA16FToRGBA16F", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "requiresConversion": "true" - } - ], - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "UnreachableLoadFunction", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ], - "GL_FLOAT": [ - { - "loadFunction": "LoadLA32FToRGBA32F", - "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", - "requiresConversion": "true" - } - ], - "GL_HALF_FLOAT_OES": [ - { - "loadFunction": "LoadLA16FToRGBA16F", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "requiresConversion": "true" - } - ] - }, - "GL_RGBA16I": { - "GL_SHORT": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_SINT", - "requiresConversion": "false" - } - ] - }, - "GL_R8I": { - "GL_BYTE": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R8_SINT", - "requiresConversion": "false" - } - ] - }, - "GL_RGB8_SNORM": { - "GL_BYTE": [ - { - "loadFunction": "LoadToNative3To4", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_SNORM", - "requiresConversion": "true" - } - ] - }, - "GL_RG32F": { - "GL_FLOAT": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R32G32_FLOAT", - "requiresConversion": "false" - } - ] - }, - "GL_DEPTH_COMPONENT32F": { - "GL_FLOAT": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R32_TYPELESS", - "requiresConversion": "false" - }, - { - "loadFunction": "UnimplementedLoadFunction", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_RG32I": { - "GL_INT": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R32G32_SINT", - "requiresConversion": "false" - } - ] - }, - "GL_ALPHA8_EXT": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_A8_UNORM", - "requiresConversion": "false" - }, - { - "loadFunction": "LoadA8ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "true" - } - ] - }, - "GL_RG32UI": { - "GL_UNSIGNED_INT": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R32G32_UINT", - "requiresConversion": "false" - } - ] - }, - "GL_RGBA16UI": { - "GL_UNSIGNED_SHORT": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_UINT", - "requiresConversion": "false" - } - ] - }, - "GL_COMPRESSED_RGBA8_ETC2_EAC": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadETC2RGBA8ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "true" - } - ] - }, - "GL_RGB8I": { - "GL_BYTE": [ - { - "loadFunction": "LoadToNative3To4", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_SINT", - "requiresConversion": "true" - } - ] - }, - "GL_COMPRESSED_SRGB8_ETC2": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadETC2SRGB8ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", - "requiresConversion": "true" - } - ] - }, - "GL_DEPTH32F_STENCIL8": { - "GL_FLOAT_32_UNSIGNED_INT_24_8_REV": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R32G8X24_TYPELESS", - "requiresConversion": "false" - }, - { - "loadFunction": "UnimplementedLoadFunction", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_RG8I": { - "GL_BYTE": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R8G8_SINT", - "requiresConversion": "false" - } - ] - }, - "GL_R32UI": { - "GL_UNSIGNED_INT": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R32_UINT", - "requiresConversion": "false" - } - ] - }, - "GL_BGR5_A1_ANGLEX": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "false" - } - ], - "GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT": [ - { - "loadFunction": "LoadRGB5A1ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_COMPRESSED_RG11_EAC": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadEACRG11ToRG8", - "dxgiFormat": "DXGI_FORMAT_R8G8_UNORM", - "requiresConversion": "true" - } - ] - }, - "GL_SRGB8_ALPHA8": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", - "requiresConversion": "false" - } - ] - }, - "GL_LUMINANCE_ALPHA16F_EXT": { - "GL_HALF_FLOAT": [ - { - "loadFunction": "LoadLA16FToRGBA16F", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ], - "GL_HALF_FLOAT_OES": [ - { - "loadFunction": "LoadLA16FToRGBA16F", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_RGBA": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "UnreachableLoadFunction", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ], - "GL_UNSIGNED_SHORT_4_4_4_4": [ - { - "loadFunction": "UnreachableLoadFunction", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ], - "GL_UNSIGNED_SHORT_5_5_5_1": [ - { - "loadFunction": "UnreachableLoadFunction", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_DEPTH24_STENCIL8": { - "GL_UNSIGNED_INT_24_8": [ - { - "loadFunction": "LoadR32ToR24G8", - "dxgiFormat": "DXGI_FORMAT_R24G8_TYPELESS", - "requiresConversion": "true" - }, - { - "loadFunction": "LoadR32ToR24G8", - "dxgiFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT", - "requiresConversion": "true" - } - ] - }, - "GL_RGB16I": { - "GL_SHORT": [ - { - "loadFunction": "LoadToNative3To4", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_SINT", - "requiresConversion": "true" - } - ] - }, - "GL_R8UI": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R8_UINT", - "requiresConversion": "false" - } - ] - }, - "GL_ALPHA": { - "GL_HALF_FLOAT": [ - { - "loadFunction": "LoadA16FToRGBA16F", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "requiresConversion": "true" - } - ], - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "UnreachableLoadFunction", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ], - "GL_FLOAT": [ - { - "loadFunction": "LoadA32FToRGBA32F", - "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", - "requiresConversion": "true" - } - ], - "GL_HALF_FLOAT_OES": [ - { - "loadFunction": "LoadA16FToRGBA16F", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "requiresConversion": "true" - } - ] - }, - "GL_RGB16F": { - "GL_HALF_FLOAT": [ - { - "loadFunction": "LoadToNative3To4", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "requiresConversion": "true" - } - ], - "GL_FLOAT": [ - { - "loadFunction": "LoadRGB32FToRGBA16F", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "requiresConversion": "true" - } - ], - "GL_HALF_FLOAT_OES": [ - { - "loadFunction": "LoadToNative3To4", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "requiresConversion": "true" - } - ] - }, - "GL_COMPRESSED_SIGNED_R11_EAC": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadEACR11SToR8", - "dxgiFormat": "DXGI_FORMAT_R8_SNORM", - "requiresConversion": "true" - } - ] - }, - "GL_COMPRESSED_RGB_S3TC_DXT1_EXT": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadCompressedToNative<4,4,8>", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadCompressedToNative<4,4,8>", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_STENCIL_INDEX8": { - "DXGI_FORMAT_R24G8_TYPELESS": [ - { - "loadFunction": "UnimplementedLoadFunction", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ], - "DXGI_FORMAT_D24_UNORM_S8_UINT": [ - { - "loadFunction": "UnimplementedLoadFunction", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_LUMINANCE_ALPHA32F_EXT": { - "GL_FLOAT": [ - { - "loadFunction": "LoadLA32FToRGBA32F", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_RGB8UI": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative3To4", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UINT", - "requiresConversion": "true" - } - ] - }, - "GL_DEPTH_COMPONENT24": { - "GL_UNSIGNED_INT": [ - { - "loadFunction": "LoadR32ToR24G8", - "dxgiFormat": "DXGI_FORMAT_R24G8_TYPELESS", - "requiresConversion": "true" - }, - { - "loadFunction": "LoadR32ToR24G8", - "dxgiFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT", - "requiresConversion": "true" - } - ] - }, - "GL_R32I": { - "GL_INT": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R32_SINT", - "requiresConversion": "false" - } - ] - }, - "GL_DEPTH_COMPONENT32_OES": { - "GL_UNSIGNED_INT": [ - { - "loadFunction": "LoadR32ToR24G8", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_R32F": { - "GL_FLOAT": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R32_FLOAT", - "requiresConversion": "false" - } - ] - }, - "GL_RG16F": { - "GL_HALF_FLOAT": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R16G16_FLOAT", - "requiresConversion": "false" - } - ], - "GL_FLOAT": [ - { - "loadFunction": "Load32FTo16F<2>", - "dxgiFormat": "DXGI_FORMAT_R16G16_FLOAT", - "requiresConversion": "true" - } - ], - "GL_HALF_FLOAT_OES": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R16G16_FLOAT", - "requiresConversion": "false" - } - ] - }, - "GL_RGB565": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative3To4", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "true" - } - ], - "GL_UNSIGNED_SHORT_5_6_5": [ - { - "loadFunction": "LoadR5G6B5ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "true" - }, - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_B5G6R5_UNORM", - "requiresConversion": "false" - } - ] - }, - "GL_LUMINANCE16F_EXT": { - "GL_HALF_FLOAT": [ - { - "loadFunction": "LoadL16FToRGBA16F", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ], - "GL_HALF_FLOAT_OES": [ - { - "loadFunction": "LoadL16FToRGBA16F", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_RG16UI": { - "GL_UNSIGNED_SHORT": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R16G16_UINT", - "requiresConversion": "false" - } - ] - }, - "GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadCompressedToNative<4,4,16>", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_RG16I": { - "GL_SHORT": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R16G16_SINT", - "requiresConversion": "false" - } - ] - }, - "GL_BGRA8_EXT": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "false" - } - ] - }, - "GL_ALPHA16F_EXT": { - "GL_HALF_FLOAT": [ - { - "loadFunction": "LoadA16FToRGBA16F", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ], - "GL_HALF_FLOAT_OES": [ - { - "loadFunction": "LoadA16FToRGBA16F", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ] - }, - "GL_RGBA4": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "false" - } - ], - "GL_UNSIGNED_SHORT_4_4_4_4": [ - { - "loadFunction": "LoadRGBA4ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "true" - }, - { - "loadFunction": "LoadRGBA4ToARGB4", - "dxgiFormat": "DXGI_FORMAT_B4G4R4A4_UNORM", - "requiresConversion": "true" - } - ] - }, - "GL_RGBA8": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "false" - } - ] - }, - "GL_LUMINANCE": { - "GL_HALF_FLOAT": [ - { - "loadFunction": "LoadL16FToRGBA16F", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "requiresConversion": "true" - } - ], - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "UnreachableLoadFunction", - "dxgiFormat": "DXGI_FORMAT_UNKNOWN", - "requiresConversion": "true" - } - ], - "GL_FLOAT": [ - { - "loadFunction": "LoadL32FToRGBA32F", - "dxgiFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", - "requiresConversion": "true" - } - ], - "GL_HALF_FLOAT_OES": [ - { - "loadFunction": "LoadL16FToRGBA16F", - "dxgiFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "requiresConversion": "true" - } - ] - }, - "GL_RGB10_A2UI": { - "GL_UNSIGNED_INT_2_10_10_10_REV": [ - { - "loadFunction": "LoadToNative", - "dxgiFormat": "DXGI_FORMAT_R10G10B10A2_UINT", - "requiresConversion": "false" - } - ] - }, - "GL_ETC1_RGB8_OES": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadETC1RGB8ToRGBA8", - "dxgiFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requiresConversion": "true" - } - ] - }, - "GL_ETC1_RGB8_LOSSY_DECODE_ANGLE": { - "GL_UNSIGNED_BYTE": [ - { - "loadFunction": "LoadETC1RGB8ToBC1", - "dxgiFormat": "DXGI_FORMAT_BC1_UNORM", - "requiresConversion": "true" - } - ] - } -} \ No newline at end of file diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_table.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_table.h deleted file mode 100644 index b17062f68d..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_table.h +++ /dev/null @@ -1,31 +0,0 @@ -// -// Copyright 2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// load_functions_table: -// Contains load functions table depending on internal format and dxgi format -// - -#ifndef LIBANGLE_RENDERER_D3D_D3D11_LOADFUNCTIONSTABLE_H_ -#define LIBANGLE_RENDERER_D3D_D3D11_LOADFUNCTIONSTABLE_H_ - -#include - -#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" -#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" - -namespace rx -{ - -namespace d3d11 -{ - -const std::map &GetLoadFunctionsMap(GLenum internalFormat, - DXGI_FORMAT dxgiFormat); - -} // namespace d3d11 - -} // namespace rx - -#endif // LIBANGLE_RENDERER_D3D_D3D11_LOADFUNCTIONSTABLE_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_table_autogen.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_table_autogen.cpp deleted file mode 100644 index acb48b9573..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/load_functions_table_autogen.cpp +++ /dev/null @@ -1,2098 +0,0 @@ -// GENERATED FILE - DO NOT EDIT. -// Generated by gen_load_functions_table.py using data from load_functions_data.json -// -// Copyright 2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// load_functions_table: -// Contains the GetLoadFunctionsMap for texture_format_util.h -// - -#include "libANGLE/renderer/d3d/d3d11/load_functions_table.h" -#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" -#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" -#include "libANGLE/renderer/d3d/loadimage.h" -#include "libANGLE/renderer/d3d/loadimage_etc.h" - -namespace rx -{ - -namespace d3d11 -{ - -namespace -{ - -// ES3 image loading functions vary based on: -// - the GL internal format (supplied to glTex*Image*D) -// - the GL data type given (supplied to glTex*Image*D) -// - the target DXGI_FORMAT that the image will be loaded into (which is chosen based on the D3D -// device's capabilities) -// This map type determines which loading function to use, based on these three parameters. -// Source formats and types are taken from Tables 3.2 and 3.3 of the ES 3 spec. -void UnimplementedLoadFunction(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch) -{ - UNIMPLEMENTED(); -} - -void UnreachableLoadFunction(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch) -{ - UNREACHABLE(); -} - -} // namespace - -// TODO we can replace these maps with more generated code -const std::map &GetLoadFunctionsMap(GLenum internalFormat, - DXGI_FORMAT dxgiFormat) -{ - // clang-format off - switch (internalFormat) - { - case GL_ALPHA: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16B16A16_FLOAT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadA16FToRGBA16F, true); - loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadA16FToRGBA16F, true); - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - case DXGI_FORMAT_R32G32B32A32_FLOAT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadA32FToRGBA32F, true); - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - case DXGI_FORMAT_UNKNOWN: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - } - } - case GL_ALPHA16F_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadA16FToRGBA16F, true); - loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadA16FToRGBA16F, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadA16FToRGBA16F, true); - loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadA16FToRGBA16F, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - } - } - case GL_ALPHA32F_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadA32FToRGBA32F, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadA32FToRGBA32F, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - } - } - case GL_ALPHA8_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_A8_UNORM: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - case DXGI_FORMAT_R8G8B8A8_UNORM: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadA8ToRGBA8, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_BGR5_A1_ANGLEX: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT] = LoadImageFunctionInfo(LoadRGB5A1ToRGBA8, true); - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, true); - loadMap[GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT] = LoadImageFunctionInfo(LoadRGB5A1ToRGBA8, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - } - } - case GL_BGRA4_ANGLEX: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT] = LoadImageFunctionInfo(LoadRGBA4ToRGBA8, true); - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, true); - loadMap[GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT] = LoadImageFunctionInfo(LoadRGBA4ToRGBA8, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - } - } - case GL_BGRA8_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - } - } - case GL_BGRA_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - } - } - case GL_COMPRESSED_R11_EAC: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8_UNORM: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadEACR11ToR8, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_COMPRESSED_RG11_EAC: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8_UNORM: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadEACRG11ToRG8, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_COMPRESSED_RGB8_ETC2: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadETC2RGB8ToRGBA8, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadETC2RGB8A1ToRGBA8, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_COMPRESSED_RGBA8_ETC2_EAC: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadETC2RGBA8ToRGBA8, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadCompressedToNative<4,4,8>, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadCompressedToNative<4,4,8>, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - } - } - case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadCompressedToNative<4,4,16>, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadCompressedToNative<4,4,16>, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - } - } - case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadCompressedToNative<4,4,16>, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadCompressedToNative<4,4,16>, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - } - } - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadCompressedToNative<4,4,8>, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadCompressedToNative<4,4,8>, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - } - } - case GL_COMPRESSED_SIGNED_R11_EAC: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8_SNORM: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadEACR11SToR8, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_COMPRESSED_SIGNED_RG11_EAC: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8_SNORM: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadEACRG11SToRG8, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadETC2SRGBA8ToSRGBA8, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_COMPRESSED_SRGB8_ETC2: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadETC2SRGB8ToRGBA8, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadETC2SRGB8A1ToRGBA8, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_DEPTH24_STENCIL8: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_D24_UNORM_S8_UINT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_INT_24_8] = LoadImageFunctionInfo(LoadR32ToR24G8, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - case DXGI_FORMAT_R24G8_TYPELESS: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_INT_24_8] = LoadImageFunctionInfo(LoadR32ToR24G8, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_DEPTH32F_STENCIL8: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32G8X24_TYPELESS: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_FLOAT_32_UNSIGNED_INT_24_8_REV] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - case DXGI_FORMAT_UNKNOWN: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_FLOAT_32_UNSIGNED_INT_24_8_REV] = LoadImageFunctionInfo(UnimplementedLoadFunction, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_FLOAT_32_UNSIGNED_INT_24_8_REV] = LoadImageFunctionInfo(UnimplementedLoadFunction, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - } - } - case GL_DEPTH_COMPONENT16: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_D16_UNORM: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_SHORT] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - case DXGI_FORMAT_R16_TYPELESS: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_INT] = LoadImageFunctionInfo(LoadR32ToR16, true); - loadMap[GL_UNSIGNED_SHORT] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_DEPTH_COMPONENT24: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_D24_UNORM_S8_UINT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_INT] = LoadImageFunctionInfo(LoadR32ToR24G8, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - case DXGI_FORMAT_R24G8_TYPELESS: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_INT] = LoadImageFunctionInfo(LoadR32ToR24G8, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_DEPTH_COMPONENT32F: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32_TYPELESS: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - case DXGI_FORMAT_UNKNOWN: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_FLOAT] = LoadImageFunctionInfo(UnimplementedLoadFunction, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_FLOAT] = LoadImageFunctionInfo(UnimplementedLoadFunction, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - } - } - case GL_DEPTH_COMPONENT32_OES: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_INT] = LoadImageFunctionInfo(LoadR32ToR24G8, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_INT] = LoadImageFunctionInfo(LoadR32ToR24G8, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - } - } - case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_BC1_UNORM: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadETC1RGB8ToBC1, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_ETC1_RGB8_OES: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadETC1RGB8ToRGBA8, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_LUMINANCE: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16B16A16_FLOAT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadL16FToRGBA16F, true); - loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadL16FToRGBA16F, true); - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - case DXGI_FORMAT_R32G32B32A32_FLOAT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadL32FToRGBA32F, true); - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - case DXGI_FORMAT_UNKNOWN: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - } - } - case GL_LUMINANCE16F_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadL16FToRGBA16F, true); - loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadL16FToRGBA16F, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadL16FToRGBA16F, true); - loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadL16FToRGBA16F, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - } - } - case GL_LUMINANCE32F_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadL32FToRGBA32F, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadL32FToRGBA32F, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - } - } - case GL_LUMINANCE8_ALPHA8_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadLA8ToRGBA8, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadLA8ToRGBA8, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - } - } - case GL_LUMINANCE8_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadL8ToRGBA8, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadL8ToRGBA8, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - } - } - case GL_LUMINANCE_ALPHA: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16B16A16_FLOAT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadLA16FToRGBA16F, true); - loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadLA16FToRGBA16F, true); - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - case DXGI_FORMAT_R32G32B32A32_FLOAT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadLA32FToRGBA32F, true); - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - case DXGI_FORMAT_UNKNOWN: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - } - } - case GL_LUMINANCE_ALPHA16F_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadLA16FToRGBA16F, true); - loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadLA16FToRGBA16F, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadLA16FToRGBA16F, true); - loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadLA16FToRGBA16F, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - } - } - case GL_LUMINANCE_ALPHA32F_EXT: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadLA32FToRGBA32F, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadLA32FToRGBA32F, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - } - } - case GL_R11F_G11F_B10F: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R11G11B10_FLOAT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadRGB16FToRG11B10F, true); - loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadRGB16FToRG11B10F, true); - loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadRGB32FToRG11B10F, true); - loadMap[GL_UNSIGNED_INT_10F_11F_11F_REV] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_R16F: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16_FLOAT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_FLOAT] = LoadImageFunctionInfo(Load32FTo16F<1>, true); - loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadToNative, false); - loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_R16I: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16_SINT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_SHORT] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_R16UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16_UINT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_SHORT] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_R32F: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32_FLOAT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_R32I: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32_SINT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_INT] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_R32UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32_UINT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_INT] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_R8: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8_UNORM: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_R8I: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8_SINT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_BYTE] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_R8UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8_UINT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_R8_SNORM: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8_SNORM: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_BYTE] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RG16F: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16_FLOAT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_FLOAT] = LoadImageFunctionInfo(Load32FTo16F<2>, true); - loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadToNative, false); - loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RG16I: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16_SINT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_SHORT] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RG16UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16_UINT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_SHORT] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RG32F: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32G32_FLOAT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RG32I: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32G32_SINT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_INT] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RG32UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32G32_UINT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_INT] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RG8: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8_UNORM: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RG8I: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8_SINT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_BYTE] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RG8UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8_UINT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RG8_SNORM: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8_SNORM: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_BYTE] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); - loadMap[GL_UNSIGNED_SHORT_5_6_5] = LoadImageFunctionInfo(UnreachableLoadFunction, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); - loadMap[GL_UNSIGNED_SHORT_5_6_5] = LoadImageFunctionInfo(UnreachableLoadFunction, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - } - } - case GL_RGB10_A2: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R10G10B10A2_UNORM: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_INT_2_10_10_10_REV] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB10_A2UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R10G10B10A2_UINT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_INT_2_10_10_10_REV] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB16F: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16B16A16_FLOAT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadRGB32FToRGBA16F, true); - loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadToNative3To4, true); - loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadToNative3To4, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB16I: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16B16A16_SINT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_SHORT] = LoadImageFunctionInfo(LoadToNative3To4, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB16UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16B16A16_UINT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_SHORT] = LoadImageFunctionInfo(LoadToNative3To4, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB32F: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32G32B32A32_FLOAT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadToNative3To4, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB32I: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32G32B32A32_SINT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_INT] = LoadImageFunctionInfo(LoadToNative3To4, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB32UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32G32B32A32_UINT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_INT] = LoadImageFunctionInfo(LoadToNative3To4, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB565: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_B5G6R5_UNORM: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_SHORT_5_6_5] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - case DXGI_FORMAT_R8G8B8A8_UNORM: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_SHORT_5_6_5] = LoadImageFunctionInfo(LoadR5G6B5ToRGBA8, true); - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative3To4, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB5_A1: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_B5G5R5A1_UNORM: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_SHORT_5_5_5_1] = LoadImageFunctionInfo(LoadRGB5A1ToA1RGB5, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - case DXGI_FORMAT_R8G8B8A8_UNORM: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_INT_2_10_10_10_REV] = LoadImageFunctionInfo(LoadRGB10A2ToRGBA8, true); - loadMap[GL_UNSIGNED_SHORT_5_5_5_1] = LoadImageFunctionInfo(LoadRGB5A1ToRGBA8, true); - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB8: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative3To4, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB8I: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_SINT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_BYTE] = LoadImageFunctionInfo(LoadToNative3To4, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB8UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UINT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative3To4, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB8_SNORM: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_SNORM: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_BYTE] = LoadImageFunctionInfo(LoadToNative3To4, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGB9_E5: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadRGB16FToRGB9E5, true); - loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadRGB16FToRGB9E5, true); - loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadRGB32FToRGB9E5, true); - loadMap[GL_UNSIGNED_INT_5_9_9_9_REV] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGBA: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); - loadMap[GL_UNSIGNED_SHORT_4_4_4_4] = LoadImageFunctionInfo(UnreachableLoadFunction, true); - loadMap[GL_UNSIGNED_SHORT_5_5_5_1] = LoadImageFunctionInfo(UnreachableLoadFunction, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(UnreachableLoadFunction, true); - loadMap[GL_UNSIGNED_SHORT_4_4_4_4] = LoadImageFunctionInfo(UnreachableLoadFunction, true); - loadMap[GL_UNSIGNED_SHORT_5_5_5_1] = LoadImageFunctionInfo(UnreachableLoadFunction, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - } - } - case GL_RGBA16F: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16B16A16_FLOAT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_FLOAT] = LoadImageFunctionInfo(Load32FTo16F<4>, true); - loadMap[GL_HALF_FLOAT] = LoadImageFunctionInfo(LoadToNative, false); - loadMap[GL_HALF_FLOAT_OES] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGBA16I: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16B16A16_SINT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_SHORT] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGBA16UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R16G16B16A16_UINT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_SHORT] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGBA32F: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32G32B32A32_FLOAT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_FLOAT] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGBA32I: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32G32B32A32_SINT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_INT] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGBA32UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R32G32B32A32_UINT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_INT] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGBA4: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_B4G4R4A4_UNORM: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_SHORT_4_4_4_4] = LoadImageFunctionInfo(LoadRGBA4ToARGB4, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - case DXGI_FORMAT_R8G8B8A8_UNORM: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_SHORT_4_4_4_4] = LoadImageFunctionInfo(LoadRGBA4ToRGBA8, true); - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGBA8: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGBA8I: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_SINT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_BYTE] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGBA8UI: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UINT: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_RGBA8_SNORM: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_SNORM: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_BYTE] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_SRGB8: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative3To4, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_SRGB8_ALPHA8: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[GL_UNSIGNED_BYTE] = LoadImageFunctionInfo(LoadToNative, false); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - break; - } - } - case GL_STENCIL_INDEX8: - { - switch (dxgiFormat) - { - case DXGI_FORMAT_UNKNOWN: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[DXGI_FORMAT_D24_UNORM_S8_UINT] = LoadImageFunctionInfo(UnimplementedLoadFunction, true); - loadMap[DXGI_FORMAT_R24G8_TYPELESS] = LoadImageFunctionInfo(UnimplementedLoadFunction, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - default: - { - static const std::map loadFunctionsMap = []() { - std::map loadMap; - loadMap[DXGI_FORMAT_D24_UNORM_S8_UINT] = LoadImageFunctionInfo(UnimplementedLoadFunction, true); - loadMap[DXGI_FORMAT_R24G8_TYPELESS] = LoadImageFunctionInfo(UnimplementedLoadFunction, true); - return loadMap; - }(); - - return loadFunctionsMap; - } - } - } - - default: - { - static std::map emptyLoadFunctionsMap; - return emptyLoadFunctionsMap; - } - } - // clang-format on - -} // GetLoadFunctionsMap - -} // namespace d3d11 - -} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp index a1175db9af..d059b36120 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp @@ -12,319 +12,52 @@ #include #include "common/debug.h" -#include "libANGLE/formatutils.h" +#include "libANGLE/Buffer.h" +#include "libANGLE/Context.h" #include "libANGLE/Framebuffer.h" #include "libANGLE/Program.h" +#include "libANGLE/State.h" +#include "libANGLE/VertexArray.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/BufferD3D.h" +#include "libANGLE/renderer/d3d/FramebufferD3D.h" +#include "libANGLE/renderer/d3d/IndexBuffer.h" +#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" #include "libANGLE/renderer/d3d/d3d11/dxgi_support_table.h" #include "libANGLE/renderer/d3d/d3d11/formatutils11.h" -#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" -#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" -#include "libANGLE/renderer/d3d/FramebufferD3D.h" -#include "libANGLE/renderer/d3d/WorkaroundsD3D.h" - -#ifndef D3D_FL9_1_DEFAULT_MAX_ANISOTROPY -# define D3D_FL9_1_DEFAULT_MAX_ANISOTROPY 2 -#endif -#ifndef D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT -# define D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT 1 -#endif -#ifndef D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT -# define D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT 4 -#endif -#ifndef D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT -# define D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT 65535 -#endif -#ifndef D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT -# define D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT 1048575 -#endif -#ifndef D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION -# define D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION 512 -#endif -#ifndef D3D_FL9_3_REQ_TEXTURECUBE_DIMENSION -# define D3D_FL9_3_REQ_TEXTURECUBE_DIMENSION 4096 -#endif -#ifndef D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION -# define D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION 2048 -#endif -#ifndef D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION -# define D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION 256 -#endif -#ifndef D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION -# define D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION 4096 -#endif -#ifndef D3D11_REQ_TEXTURECUBE_DIMENSION -# define D3D11_REQ_TEXTURECUBE_DIMENSION 16384 -#endif -#ifndef D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION -# define D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION 2048 -#endif -#ifndef D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION -# define D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION 2048 -#endif -#ifndef D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP -# define D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP 32 -#endif -#ifndef D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP -# define D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP 32 -#endif -#ifndef D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT -# define D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT 32 -#endif -#ifndef D3D11_STANDARD_VERTEX_ELEMENT_COUNT -# define D3D11_STANDARD_VERTEX_ELEMENT_COUNT 32 -#endif -#ifndef D3D10_1_SO_BUFFER_SLOT_COUNT -# define D3D10_1_SO_BUFFER_SLOT_COUNT 4 -#endif -#ifndef D3D11_SO_BUFFER_SLOT_COUNT -# define D3D11_SO_BUFFER_SLOT_COUNT 4 -#endif -#ifndef D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT -# define D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT 14 -#endif -#ifndef D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT -# define D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT 16 -#endif -#ifndef D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE -# define D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE -8 -#endif -#ifndef D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE -# define D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE 7 -#endif -#ifndef D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT -# define D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT 4096 -#endif -#ifndef D3D11_PS_INPUT_REGISTER_COUNT -# define D3D11_PS_INPUT_REGISTER_COUNT 32 -#endif -#ifndef D3D10_1_VS_OUTPUT_REGISTER_COUNT -# define D3D10_1_VS_OUTPUT_REGISTER_COUNT 32 -#endif -#if defined(ANGLE_MINGW32_COMPAT) -static const IID WKPDID_D3DDebugObjectName = { 0x429b8c22, 0x9188, 0x4b0c, 0x87, 0x42, 0xac, 0xb0, 0xbf, 0x85, 0xc2, 0x00 }; -#endif +#include "libANGLE/renderer/driver_utils.h" +#include "platform/Platform.h" +#include "platform/WorkaroundsD3D.h" namespace rx { -namespace gl_d3d11 -{ - -D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha) -{ - D3D11_BLEND d3dBlend = D3D11_BLEND_ZERO; - - switch (glBlend) - { - case GL_ZERO: d3dBlend = D3D11_BLEND_ZERO; break; - case GL_ONE: d3dBlend = D3D11_BLEND_ONE; break; - case GL_SRC_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_SRC_ALPHA : D3D11_BLEND_SRC_COLOR); break; - case GL_ONE_MINUS_SRC_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_INV_SRC_ALPHA : D3D11_BLEND_INV_SRC_COLOR); break; - case GL_DST_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_DEST_ALPHA : D3D11_BLEND_DEST_COLOR); break; - case GL_ONE_MINUS_DST_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_INV_DEST_ALPHA : D3D11_BLEND_INV_DEST_COLOR); break; - case GL_SRC_ALPHA: d3dBlend = D3D11_BLEND_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: d3dBlend = D3D11_BLEND_INV_SRC_ALPHA; break; - case GL_DST_ALPHA: d3dBlend = D3D11_BLEND_DEST_ALPHA; break; - case GL_ONE_MINUS_DST_ALPHA: d3dBlend = D3D11_BLEND_INV_DEST_ALPHA; break; - case GL_CONSTANT_COLOR: d3dBlend = D3D11_BLEND_BLEND_FACTOR; break; - case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR; break; - case GL_CONSTANT_ALPHA: d3dBlend = D3D11_BLEND_BLEND_FACTOR; break; - case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR; break; - case GL_SRC_ALPHA_SATURATE: d3dBlend = D3D11_BLEND_SRC_ALPHA_SAT; break; - default: UNREACHABLE(); - } - - return d3dBlend; -} - -D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp) -{ - D3D11_BLEND_OP d3dBlendOp = D3D11_BLEND_OP_ADD; - - switch (glBlendOp) - { - case GL_FUNC_ADD: d3dBlendOp = D3D11_BLEND_OP_ADD; break; - case GL_FUNC_SUBTRACT: d3dBlendOp = D3D11_BLEND_OP_SUBTRACT; break; - case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3D11_BLEND_OP_REV_SUBTRACT; break; - case GL_MIN: d3dBlendOp = D3D11_BLEND_OP_MIN; break; - case GL_MAX: d3dBlendOp = D3D11_BLEND_OP_MAX; break; - default: UNREACHABLE(); - } - - return d3dBlendOp; -} - -UINT8 ConvertColorMask(bool red, bool green, bool blue, bool alpha) -{ - UINT8 mask = 0; - if (red) - { - mask |= D3D11_COLOR_WRITE_ENABLE_RED; - } - if (green) - { - mask |= D3D11_COLOR_WRITE_ENABLE_GREEN; - } - if (blue) - { - mask |= D3D11_COLOR_WRITE_ENABLE_BLUE; - } - if (alpha) - { - mask |= D3D11_COLOR_WRITE_ENABLE_ALPHA; - } - return mask; -} - -D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, GLenum cullMode) -{ - D3D11_CULL_MODE cull = D3D11_CULL_NONE; - - if (cullEnabled) - { - switch (cullMode) - { - case GL_FRONT: cull = D3D11_CULL_FRONT; break; - case GL_BACK: cull = D3D11_CULL_BACK; break; - case GL_FRONT_AND_BACK: cull = D3D11_CULL_NONE; break; - default: UNREACHABLE(); - } - } - else - { - cull = D3D11_CULL_NONE; - } - - return cull; -} - -D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison) -{ - D3D11_COMPARISON_FUNC d3dComp = D3D11_COMPARISON_NEVER; - switch (comparison) - { - case GL_NEVER: d3dComp = D3D11_COMPARISON_NEVER; break; - case GL_ALWAYS: d3dComp = D3D11_COMPARISON_ALWAYS; break; - case GL_LESS: d3dComp = D3D11_COMPARISON_LESS; break; - case GL_LEQUAL: d3dComp = D3D11_COMPARISON_LESS_EQUAL; break; - case GL_EQUAL: d3dComp = D3D11_COMPARISON_EQUAL; break; - case GL_GREATER: d3dComp = D3D11_COMPARISON_GREATER; break; - case GL_GEQUAL: d3dComp = D3D11_COMPARISON_GREATER_EQUAL; break; - case GL_NOTEQUAL: d3dComp = D3D11_COMPARISON_NOT_EQUAL; break; - default: UNREACHABLE(); - } - - return d3dComp; -} - -D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled) -{ - return depthWriteEnabled ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; -} - -UINT8 ConvertStencilMask(GLuint stencilmask) -{ - return static_cast(stencilmask); -} - -D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp) -{ - D3D11_STENCIL_OP d3dStencilOp = D3D11_STENCIL_OP_KEEP; - - switch (stencilOp) - { - case GL_ZERO: d3dStencilOp = D3D11_STENCIL_OP_ZERO; break; - case GL_KEEP: d3dStencilOp = D3D11_STENCIL_OP_KEEP; break; - case GL_REPLACE: d3dStencilOp = D3D11_STENCIL_OP_REPLACE; break; - case GL_INCR: d3dStencilOp = D3D11_STENCIL_OP_INCR_SAT; break; - case GL_DECR: d3dStencilOp = D3D11_STENCIL_OP_DECR_SAT; break; - case GL_INVERT: d3dStencilOp = D3D11_STENCIL_OP_INVERT; break; - case GL_INCR_WRAP: d3dStencilOp = D3D11_STENCIL_OP_INCR; break; - case GL_DECR_WRAP: d3dStencilOp = D3D11_STENCIL_OP_DECR; break; - default: UNREACHABLE(); - } - - return d3dStencilOp; -} - -D3D11_FILTER ConvertFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy, GLenum comparisonMode) -{ - bool comparison = comparisonMode != GL_NONE; - - if (maxAnisotropy > 1.0f) - { - return D3D11_ENCODE_ANISOTROPIC_FILTER(static_cast(comparison)); - } - else - { - D3D11_FILTER_TYPE dxMin = D3D11_FILTER_TYPE_POINT; - D3D11_FILTER_TYPE dxMip = D3D11_FILTER_TYPE_POINT; - switch (minFilter) - { - case GL_NEAREST: dxMin = D3D11_FILTER_TYPE_POINT; dxMip = D3D11_FILTER_TYPE_POINT; break; - case GL_LINEAR: dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_POINT; break; - case GL_NEAREST_MIPMAP_NEAREST: dxMin = D3D11_FILTER_TYPE_POINT; dxMip = D3D11_FILTER_TYPE_POINT; break; - case GL_LINEAR_MIPMAP_NEAREST: dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_POINT; break; - case GL_NEAREST_MIPMAP_LINEAR: dxMin = D3D11_FILTER_TYPE_POINT; dxMip = D3D11_FILTER_TYPE_LINEAR; break; - case GL_LINEAR_MIPMAP_LINEAR: dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_LINEAR; break; - default: UNREACHABLE(); - } - - D3D11_FILTER_TYPE dxMag = D3D11_FILTER_TYPE_POINT; - switch (magFilter) - { - case GL_NEAREST: dxMag = D3D11_FILTER_TYPE_POINT; break; - case GL_LINEAR: dxMag = D3D11_FILTER_TYPE_LINEAR; break; - default: UNREACHABLE(); - } - - return D3D11_ENCODE_BASIC_FILTER(dxMin, dxMag, dxMip, static_cast(comparison)); - } -} - -D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap) -{ - switch (wrap) - { - case GL_REPEAT: return D3D11_TEXTURE_ADDRESS_WRAP; - case GL_CLAMP_TO_EDGE: return D3D11_TEXTURE_ADDRESS_CLAMP; - case GL_MIRRORED_REPEAT: return D3D11_TEXTURE_ADDRESS_MIRROR; - default: UNREACHABLE(); - } - - return D3D11_TEXTURE_ADDRESS_WRAP; -} - -D3D11_QUERY ConvertQueryType(GLenum queryType) -{ - switch (queryType) - { - case GL_ANY_SAMPLES_PASSED_EXT: - case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: return D3D11_QUERY_OCCLUSION; - case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: return D3D11_QUERY_SO_STATISTICS; - case GL_TIME_ELAPSED_EXT: - // Two internal queries are also created for begin/end timestamps - return D3D11_QUERY_TIMESTAMP_DISJOINT; - default: UNREACHABLE(); return D3D11_QUERY_EVENT; - } -} - -} // namespace gl_d3d11 - namespace d3d11_gl { - namespace { +// Standard D3D sample positions from +// https://msdn.microsoft.com/en-us/library/windows/desktop/ff476218.aspx +using SamplePositionsArray = std::array; +static constexpr std::array kSamplePositions = { + {{{0.5f, 0.5f}}, + {{0.75f, 0.75f, 0.25f, 0.25f}}, + {{0.375f, 0.125f, 0.875f, 0.375f, 0.125f, 0.625f, 0.625f, 0.875f}}, + {{0.5625f, 0.3125f, 0.4375f, 0.6875f, 0.8125f, 0.5625f, 0.3125f, 0.1875f, 0.1875f, 0.8125f, + 0.0625f, 0.4375f, 0.6875f, 0.9375f, 0.9375f, 0.0625f}}, + {{0.5625f, 0.5625f, 0.4375f, 0.3125f, 0.3125f, 0.625f, 0.75f, 0.4375f, + 0.1875f, 0.375f, 0.625f, 0.8125f, 0.8125f, 0.6875f, 0.6875f, 0.1875f, + 0.375f, 0.875f, 0.5f, 0.0625f, 0.25f, 0.125f, 0.125f, 0.75f, + 0.0f, 0.5f, 0.9375f, 0.25f, 0.875f, 0.9375f, 0.0625f, 0.0f}}}}; // Helper functor for querying DXGI support. Saves passing the parameters repeatedly. class DXGISupportHelper : angle::NonCopyable { public: DXGISupportHelper(ID3D11Device *device, D3D_FEATURE_LEVEL featureLevel) - : mDevice(device), - mFeatureLevel(featureLevel) + : mDevice(device), mFeatureLevel(featureLevel) { } @@ -347,7 +80,7 @@ class DXGISupportHelper : angle::NonCopyable else { // TODO(jmadill): find out why we fail this call sometimes in FL9_3 - // ERR("Error checking format support for format 0x%x", dxgiFormat); + // ERR() << "Error checking format support for format 0x" << std::hex << dxgiFormat; } } @@ -359,7 +92,1057 @@ class DXGISupportHelper : angle::NonCopyable D3D_FEATURE_LEVEL mFeatureLevel; }; -} // anonymous namespace +gl::TextureCaps GenerateTextureFormatCaps(gl::Version maxClientVersion, + GLenum internalFormat, + ID3D11Device *device, + const Renderer11DeviceCaps &renderer11DeviceCaps) +{ + gl::TextureCaps textureCaps; + + DXGISupportHelper support(device, renderer11DeviceCaps.featureLevel); + const d3d11::Format &formatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps); + + const gl::InternalFormat &internalFormatInfo = gl::GetSizedInternalFormatInfo(internalFormat); + + UINT texSupportMask = D3D11_FORMAT_SUPPORT_TEXTURE2D; + if (internalFormatInfo.depthBits == 0 && internalFormatInfo.stencilBits == 0) + { + texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURECUBE; + if (maxClientVersion.major > 2) + { + texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURE3D; + } + } + + textureCaps.texturable = support.query(formatInfo.texFormat, texSupportMask); + textureCaps.filterable = + support.query(formatInfo.srvFormat, D3D11_FORMAT_SUPPORT_SHADER_SAMPLE); + textureCaps.renderable = + (support.query(formatInfo.rtvFormat, D3D11_FORMAT_SUPPORT_RENDER_TARGET)) || + (support.query(formatInfo.dsvFormat, D3D11_FORMAT_SUPPORT_DEPTH_STENCIL)); + + DXGI_FORMAT renderFormat = DXGI_FORMAT_UNKNOWN; + if (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN) + { + renderFormat = formatInfo.dsvFormat; + } + else if (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN) + { + renderFormat = formatInfo.rtvFormat; + } + if (renderFormat != DXGI_FORMAT_UNKNOWN && + support.query(renderFormat, D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET)) + { + // Assume 1x + textureCaps.sampleCounts.insert(1); + + for (unsigned int sampleCount = 2; sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; + sampleCount *= 2) + { + UINT qualityCount = 0; + if (SUCCEEDED(device->CheckMultisampleQualityLevels(renderFormat, sampleCount, + &qualityCount))) + { + // Assume we always support lower sample counts + if (qualityCount == 0) + { + break; + } + textureCaps.sampleCounts.insert(sampleCount); + } + } + } + + return textureCaps; +} + +bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return true; + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return false; + + default: + UNREACHABLE(); + return false; + } +} + +float GetMaximumAnisotropy(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_MAX_MAXANISOTROPY; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_MAX_MAXANISOTROPY; + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + return 16; + + case D3D_FEATURE_LEVEL_9_1: + return D3D_FL9_1_DEFAULT_MAX_ANISOTROPY; + + default: + UNREACHABLE(); + return 0; + } +} + +bool GetOcclusionQuerySupport(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return true; + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx + // ID3D11Device::CreateQuery + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + return true; + case D3D_FEATURE_LEVEL_9_1: + return false; + + default: + UNREACHABLE(); + return false; + } +} + +bool GetEventQuerySupport(D3D_FEATURE_LEVEL featureLevel) +{ + // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx + // ID3D11Device::CreateQuery + + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return true; + + default: + UNREACHABLE(); + return false; + } +} + +bool GetInstancingSupport(D3D_FEATURE_LEVEL featureLevel) +{ + // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx + // ID3D11Device::CreateInputLayout + + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return true; + + // Feature Level 9_3 supports instancing, but slot 0 in the input layout must not be + // instanced. + // D3D9 has a similar restriction, where stream 0 must not be instanced. + // This restriction can be worked around by remapping any non-instanced slot to slot + // 0. + // This works because HLSL uses shader semantics to match the vertex inputs to the + // elements in the input layout, rather than the slots. + // Note that we only support instancing via ANGLE_instanced_array on 9_3, since 9_3 + // doesn't support OpenGL ES 3.0 + case D3D_FEATURE_LEVEL_9_3: + return true; + + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return false; + + default: + UNREACHABLE(); + return false; + } +} + +bool GetFramebufferMultisampleSupport(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return true; + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return false; + + default: + UNREACHABLE(); + return false; + } +} + +bool GetFramebufferBlitSupport(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return true; + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return false; + + default: + UNREACHABLE(); + return false; + } +} + +bool GetDerivativeInstructionSupport(D3D_FEATURE_LEVEL featureLevel) +{ + // http://msdn.microsoft.com/en-us/library/windows/desktop/bb509588.aspx states that + // shader model + // ps_2_x is required for the ddx (and other derivative functions). + + // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx states that + // feature level + // 9.3 supports shader model ps_2_x. + + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + case D3D_FEATURE_LEVEL_9_3: + return true; + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return false; + + default: + UNREACHABLE(); + return false; + } +} + +bool GetShaderTextureLODSupport(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return true; + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return false; + + default: + UNREACHABLE(); + return false; + } +} + +size_t GetMaximumSimultaneousRenderTargets(D3D_FEATURE_LEVEL featureLevel) +{ + // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx + // ID3D11Device::CreateInputLayout + + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; + + case D3D_FEATURE_LEVEL_9_3: + return D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT; + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT; + + default: + UNREACHABLE(); + return 0; + } +} + +size_t GetMaximum2DTextureSize(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; + + case D3D_FEATURE_LEVEL_9_3: + return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; + + default: + UNREACHABLE(); + return 0; + } +} + +size_t GetMaximumCubeMapTextureSize(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_REQ_TEXTURECUBE_DIMENSION; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_REQ_TEXTURECUBE_DIMENSION; + + case D3D_FEATURE_LEVEL_9_3: + return D3D_FL9_3_REQ_TEXTURECUBE_DIMENSION; + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION; + + default: + UNREACHABLE(); + return 0; + } +} + +size_t GetMaximum2DTextureArraySize(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 0; + + default: + UNREACHABLE(); + return 0; + } +} + +size_t GetMaximum3DTextureSize(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION; + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION; + + default: + UNREACHABLE(); + return 0; + } +} + +size_t GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_VIEWPORT_BOUNDS_MAX; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_VIEWPORT_BOUNDS_MAX; + + // No constants for D3D11 Feature Level 9 viewport size limits, use the maximum + // texture sizes + case D3D_FEATURE_LEVEL_9_3: + return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; + + default: + UNREACHABLE(); + return 0; + } +} + +size_t GetMaximumDrawIndexedIndexCount(D3D_FEATURE_LEVEL featureLevel) +{ + // D3D11 allows up to 2^32 elements, but we report max signed int for convenience since + // that's what's + // returned from glGetInteger + static_assert(D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32, + "Unexpected D3D11 constant value."); + static_assert(D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32, + "Unexpected D3D11 constant value."); + + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return std::numeric_limits::max(); + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + return D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT; + case D3D_FEATURE_LEVEL_9_1: + return D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT; + + default: + UNREACHABLE(); + return 0; + } +} + +size_t GetMaximumDrawVertexCount(D3D_FEATURE_LEVEL featureLevel) +{ + // D3D11 allows up to 2^32 elements, but we report max signed int for convenience since + // that's what's + // returned from glGetInteger + static_assert(D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32, "Unexpected D3D11 constant value."); + static_assert(D3D10_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32, "Unexpected D3D11 constant value."); + + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return std::numeric_limits::max(); + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + return D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT; + case D3D_FEATURE_LEVEL_9_1: + return D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT; + + default: + UNREACHABLE(); + return 0; + } +} + +size_t GetMaximumVertexInputSlots(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_STANDARD_VERTEX_ELEMENT_COUNT; + + case D3D_FEATURE_LEVEL_10_1: + return D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT; + case D3D_FEATURE_LEVEL_10_0: + return D3D10_STANDARD_VERTEX_ELEMENT_COUNT; + + // From http://http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx + // "Max Input Slots" + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 16; + + default: + UNREACHABLE(); + return 0; + } +} + +size_t GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx + // ID3D11DeviceContext::VSSetConstantBuffers + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 255 - d3d11_gl::GetReservedVertexUniformVectors(featureLevel); + + default: + UNREACHABLE(); + return 0; + } +} + +size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - + d3d11::RESERVED_CONSTANT_BUFFER_SLOT_COUNT; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - + d3d11::RESERVED_CONSTANT_BUFFER_SLOT_COUNT; + + // Uniform blocks not supported on D3D11 Feature Level 9 + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 0; + + default: + UNREACHABLE(); + return 0; + } +} + +size_t GetReservedVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel) +{ + // According to The OpenGL ES Shading Language specifications + // (Language Version 1.00 section 10.16, Language Version 3.10 section 12.21) + // built-in special variables (e.g. gl_FragCoord, or gl_PointCoord) + // which are statically used in the shader should be included in the variable packing + // algorithm. + // Therefore, we should not reserve output vectors for them. + + switch (featureLevel) + { + // We must reserve one output vector for dx_Position. + // We also reserve one for gl_Position, which we unconditionally output on Feature + // Levels 10_0+, + // even if it's unused in the shader (e.g. for transform feedback). TODO: This could + // be improved. + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return 2; + + // Just reserve dx_Position on Feature Level 9, since we don't ever need to output + // gl_Position. + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 1; + + default: + UNREACHABLE(); + return 0; + } +} + +size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel) +{ + static_assert(gl::IMPLEMENTATION_MAX_VARYING_VECTORS == D3D11_VS_OUTPUT_REGISTER_COUNT, + "Unexpected D3D11 constant value."); + + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel); + + case D3D_FEATURE_LEVEL_10_1: + return D3D10_1_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel); + case D3D_FEATURE_LEVEL_10_0: + return D3D10_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel); + + // Use Shader Model 2.X limits + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 8 - GetReservedVertexOutputVectors(featureLevel); + + default: + UNREACHABLE(); + return 0; + } +} + +size_t GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; + + // Vertex textures not supported on D3D11 Feature Level 9 according to + // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx + // ID3D11DeviceContext::VSSetSamplers and ID3D11DeviceContext::VSSetShaderResources + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 0; + + default: + UNREACHABLE(); + return 0; + } +} + +size_t GetMaximumPixelUniformVectors(D3D_FEATURE_LEVEL featureLevel) +{ + // TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return 1024; // D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx + // ID3D11DeviceContext::PSSetConstantBuffers + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 32 - d3d11_gl::GetReservedFragmentUniformVectors(featureLevel); + + default: + UNREACHABLE(); + return 0; + } +} + +size_t GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - + d3d11::RESERVED_CONSTANT_BUFFER_SLOT_COUNT; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - + d3d11::RESERVED_CONSTANT_BUFFER_SLOT_COUNT; + + // Uniform blocks not supported on D3D11 Feature Level 9 + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 0; + + default: + UNREACHABLE(); + return 0; + } +} + +size_t GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel); + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel); + + // Use Shader Model 2.X limits + case D3D_FEATURE_LEVEL_9_3: + return 8 - GetReservedVertexOutputVectors(featureLevel); + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 8 - GetReservedVertexOutputVectors(featureLevel); + + default: + UNREACHABLE(); + return 0; + } +} + +size_t GetMaximumPixelTextureUnits(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; + + // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx + // ID3D11DeviceContext::PSSetShaderResources + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 16; + + default: + UNREACHABLE(); + return 0; + } +} + +std::array GetMaxComputeWorkGroupCount(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return {{D3D11_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION, + D3D11_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION, + D3D11_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION}}; + break; + default: + return {{0, 0, 0}}; + } +} + +std::array GetMaxComputeWorkGroupSize(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return {{D3D11_CS_THREAD_GROUP_MAX_X, D3D11_CS_THREAD_GROUP_MAX_Y, + D3D11_CS_THREAD_GROUP_MAX_Z}}; + break; + default: + return {{0, 0, 0}}; + } +} + +size_t GetMaxComputeWorkGroupInvocations(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_CS_THREAD_GROUP_MAX_THREADS_PER_GROUP; + default: + return 0; + } +} + +size_t GetMaximumComputeUniformVectors(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; + default: + return 0; + } +} + +size_t GetMaximumComputeUniformBlocks(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - + d3d11::RESERVED_CONSTANT_BUFFER_SLOT_COUNT; + default: + return 0; + } +} + +size_t GetMaximumComputeTextureUnits(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; + default: + return 0; + } +} + +size_t GetMaximumImageUnits(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + // TODO(xinghua.cao@intel.com): Get a more accurate limit. For now using + // the minimum requirement for GLES 3.1. + return 4; + default: + return 0; + } +} + +size_t GetMaximumComputeImageUniforms(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + // TODO(xinghua.cao@intel.com): Get a more accurate limit. For now using + // the minimum requirement for GLES 3.1. + return 4; + default: + return 0; + } +} + +int GetMinimumTexelOffset(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE; + + // Sampling functions with offsets are not available below shader model 4.0. + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 0; + + default: + UNREACHABLE(); + return 0; + } +} + +int GetMaximumTexelOffset(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE; + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE; + + // Sampling functions with offsets are not available below shader model 4.0. + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 0; + + default: + UNREACHABLE(); + return 0; + } +} + +size_t GetMaximumConstantBufferSize(D3D_FEATURE_LEVEL featureLevel) +{ + // Returns a size_t despite the limit being a GLuint64 because size_t is the maximum + // size of + // any buffer that could be allocated. + + const size_t bytesPerComponent = 4 * sizeof(float); + + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent; + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent; + + // Limits from http://msdn.microsoft.com/en-us/library/windows/desktop/ff476501.aspx + // remarks section + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 4096 * bytesPerComponent; + + default: + UNREACHABLE(); + return 0; + } +} + +size_t GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_SO_BUFFER_SLOT_COUNT; + + case D3D_FEATURE_LEVEL_10_1: + return D3D10_1_SO_BUFFER_SLOT_COUNT; + case D3D_FEATURE_LEVEL_10_0: + return D3D10_SO_BUFFER_SLOT_COUNT; + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 0; + + default: + UNREACHABLE(); + return 0; + } +} + +size_t GetMaximumStreamOutputInterleavedComponents(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return GetMaximumVertexOutputVectors(featureLevel) * 4; + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 0; + + default: + UNREACHABLE(); + return 0; + } +} + +size_t GetMaximumStreamOutputSeparateComponents(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return GetMaximumStreamOutputInterleavedComponents(featureLevel) / + GetMaximumStreamOutputBuffers(featureLevel); + + // D3D 10 and 10.1 only allow one output per output slot if an output slot other + // than zero is used. + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return 4; + + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 0; + + default: + UNREACHABLE(); + return 0; + } +} + +size_t GetMaximumRenderToBufferWindowSize(D3D_FEATURE_LEVEL featureLevel) +{ + switch (featureLevel) + { + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_REQ_RENDER_TO_BUFFER_WINDOW_WIDTH; + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_REQ_RENDER_TO_BUFFER_WINDOW_WIDTH; + + // REQ_RENDER_TO_BUFFER_WINDOW_WIDTH not supported on D3D11 Feature Level 9, + // use the maximum texture sizes + case D3D_FEATURE_LEVEL_9_3: + return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; + + default: + UNREACHABLE(); + return 0; + } +} + +IntelDriverVersion GetIntelDriverVersion(const Optional driverVersion) +{ + if (!driverVersion.valid()) + return IntelDriverVersion(0); + + // According to http://www.intel.com/content/www/us/en/support/graphics-drivers/000005654.html, + // only the fourth part is necessary since it stands for the driver specific unique version + // number. + WORD part = LOWORD(driverVersion.value().LowPart); + return IntelDriverVersion(part); +} + +} // anonymous namespace unsigned int GetReservedVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel) { @@ -403,757 +1186,94 @@ unsigned int GetReservedFragmentUniformVectors(D3D_FEATURE_LEVEL featureLevel) } } -GLint GetMaximumClientVersion(D3D_FEATURE_LEVEL featureLevel) +gl::Version GetMaximumClientVersion(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return 3; + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return gl::Version(3, 1); + case D3D_FEATURE_LEVEL_10_1: + return gl::Version(3, 0); - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return 2; + case D3D_FEATURE_LEVEL_10_0: + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return gl::Version(2, 0); - default: UNREACHABLE(); return 0; + default: + UNREACHABLE(); + return gl::Version(0, 0); } } -static gl::TextureCaps GenerateTextureFormatCaps(GLint maxClientVersion, GLenum internalFormat, ID3D11Device *device, const Renderer11DeviceCaps &renderer11DeviceCaps) -{ - gl::TextureCaps textureCaps; - - DXGISupportHelper support(device, renderer11DeviceCaps.featureLevel); - const d3d11::TextureFormat &formatInfo = - d3d11::GetTextureFormatInfo(internalFormat, renderer11DeviceCaps); - - const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat); - - UINT texSupportMask = D3D11_FORMAT_SUPPORT_TEXTURE2D; - if (internalFormatInfo.depthBits == 0 && internalFormatInfo.stencilBits == 0) - { - texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURECUBE; - if (maxClientVersion > 2) - { - texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURE3D; - } - } - - textureCaps.texturable = support.query(formatInfo.texFormat, texSupportMask); - textureCaps.filterable = support.query(formatInfo.srvFormat, D3D11_FORMAT_SUPPORT_SHADER_SAMPLE); - textureCaps.renderable = (support.query(formatInfo.rtvFormat, D3D11_FORMAT_SUPPORT_RENDER_TARGET)) || - (support.query(formatInfo.dsvFormat, D3D11_FORMAT_SUPPORT_DEPTH_STENCIL)); - - if (support.query(formatInfo.renderFormat, D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET)) - { - // Assume 1x - textureCaps.sampleCounts.insert(1); - - for (unsigned int sampleCount = 2; sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; - sampleCount *= 2) - { - UINT qualityCount = 0; - if (SUCCEEDED(device->CheckMultisampleQualityLevels(formatInfo.renderFormat, sampleCount, &qualityCount))) - { - // Assume we always support lower sample counts - if (qualityCount == 0) - { - break; - } - textureCaps.sampleCounts.insert(sampleCount); - } - } - } - - return textureCaps; -} - -static bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel) +unsigned int GetMaxViewportAndScissorRectanglesPerPipeline(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return true; - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return false; - - default: UNREACHABLE(); return false; + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 1; + default: + UNREACHABLE(); + return 0; } } -static float GetMaximumAnisotropy(D3D_FEATURE_LEVEL featureLevel) +bool IsMultiviewSupported(D3D_FEATURE_LEVEL featureLevel) { + // The ANGLE_multiview extension can always be supported in D3D11 through geometry shaders. switch (featureLevel) { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: return D3D11_MAX_MAXANISOTROPY; - - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return D3D10_MAX_MAXANISOTROPY; - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: return 16; - - case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_DEFAULT_MAX_ANISOTROPY; - - default: UNREACHABLE(); return 0; + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + return true; + default: + return false; } } -static bool GetOcclusionQuerySupport(D3D_FEATURE_LEVEL featureLevel) +unsigned int GetMaxSampleMaskWords(D3D_FEATURE_LEVEL featureLevel) { switch (featureLevel) { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return true; - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx ID3D11Device::CreateQuery - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: return true; - case D3D_FEATURE_LEVEL_9_1: return false; - - default: UNREACHABLE(); return false; - } -} - -static bool GetEventQuerySupport(D3D_FEATURE_LEVEL featureLevel) -{ - // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx ID3D11Device::CreateQuery - - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return true; - - default: UNREACHABLE(); return false; - } -} - -static bool GetInstancingSupport(D3D_FEATURE_LEVEL featureLevel) -{ - // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx ID3D11Device::CreateInputLayout - - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return true; - - // Feature Level 9_3 supports instancing, but slot 0 in the input layout must not be instanced. - // D3D9 has a similar restriction, where stream 0 must not be instanced. - // This restriction can be worked around by remapping any non-instanced slot to slot 0. - // This works because HLSL uses shader semantics to match the vertex inputs to the elements in the input layout, rather than the slots. - // Note that we only support instancing via ANGLE_instanced_array on 9_3, since 9_3 doesn't support OpenGL ES 3.0 - case D3D_FEATURE_LEVEL_9_3: return true; - - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return false; - - default: UNREACHABLE(); return false; - } -} - -static bool GetFramebufferMultisampleSupport(D3D_FEATURE_LEVEL featureLevel) -{ - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return true; - - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return false; - - default: UNREACHABLE(); return false; - } -} - -static bool GetFramebufferBlitSupport(D3D_FEATURE_LEVEL featureLevel) -{ - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return true; - - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return false; - - default: UNREACHABLE(); return false; - } -} - -static bool GetDerivativeInstructionSupport(D3D_FEATURE_LEVEL featureLevel) -{ - // http://msdn.microsoft.com/en-us/library/windows/desktop/bb509588.aspx states that shader model - // ps_2_x is required for the ddx (and other derivative functions). - - // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx states that feature level - // 9.3 supports shader model ps_2_x. - - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: - case D3D_FEATURE_LEVEL_9_3: return true; - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return false; - - default: UNREACHABLE(); return false; - } -} - -static bool GetShaderTextureLODSupport(D3D_FEATURE_LEVEL featureLevel) -{ - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return true; - - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return false; - - default: UNREACHABLE(); return false; - } -} - -static size_t GetMaximumSimultaneousRenderTargets(D3D_FEATURE_LEVEL featureLevel) -{ - // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx ID3D11Device::CreateInputLayout - - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; - - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; - - case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT; - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT; - - default: UNREACHABLE(); return 0; - } -} - -static size_t GetMaximum2DTextureSize(D3D_FEATURE_LEVEL featureLevel) -{ - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; - - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; - - case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; - - default: UNREACHABLE(); return 0; - } -} - -static size_t GetMaximumCubeMapTextureSize(D3D_FEATURE_LEVEL featureLevel) -{ - switch (featureLevel) - { -#if defined(ANGLE_ENABLE_D3D11_1) - case D3D_FEATURE_LEVEL_11_1: -#endif - case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURECUBE_DIMENSION; - - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURECUBE_DIMENSION; - - case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_REQ_TEXTURECUBE_DIMENSION; - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION; - - default: UNREACHABLE(); return 0; - } -} - -static size_t GetMaximum2DTextureArraySize(D3D_FEATURE_LEVEL featureLevel) -{ - switch (featureLevel) - { -#if defined(ANGLE_ENABLE_D3D11_1) - case D3D_FEATURE_LEVEL_11_1: -#endif - case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; - - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; - - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return 0; - - default: UNREACHABLE(); return 0; - } -} - -static size_t GetMaximum3DTextureSize(D3D_FEATURE_LEVEL featureLevel) -{ - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION; - - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION; - - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION; - - default: UNREACHABLE(); return 0; - } -} - -static size_t GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel) -{ - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: return D3D11_VIEWPORT_BOUNDS_MAX; - - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return D3D10_VIEWPORT_BOUNDS_MAX; - - // No constants for D3D11 Feature Level 9 viewport size limits, use the maximum texture sizes - case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; - - default: UNREACHABLE(); return 0; - } -} - -static size_t GetMaximumDrawIndexedIndexCount(D3D_FEATURE_LEVEL featureLevel) -{ - // D3D11 allows up to 2^32 elements, but we report max signed int for convenience since that's what's - // returned from glGetInteger - static_assert(D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32, "Unexpected D3D11 constant value."); - static_assert(D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32, "Unexpected D3D11 constant value."); - - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return std::numeric_limits::max(); - - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: return D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT; - case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT; - - default: UNREACHABLE(); return 0; - } -} - -static size_t GetMaximumDrawVertexCount(D3D_FEATURE_LEVEL featureLevel) -{ - // D3D11 allows up to 2^32 elements, but we report max signed int for convenience since that's what's - // returned from glGetInteger - static_assert(D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32, "Unexpected D3D11 constant value."); - static_assert(D3D10_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32, "Unexpected D3D11 constant value."); - - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return std::numeric_limits::max(); - - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: return D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT; - case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT; - - default: UNREACHABLE(); return 0; - } -} - -static size_t GetMaximumVertexInputSlots(D3D_FEATURE_LEVEL featureLevel) -{ - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: return D3D11_STANDARD_VERTEX_ELEMENT_COUNT; - - case D3D_FEATURE_LEVEL_10_1: return D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT; - case D3D_FEATURE_LEVEL_10_0: return D3D10_STANDARD_VERTEX_ELEMENT_COUNT; - - // From http://http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx "Max Input Slots" - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return 16; - - default: UNREACHABLE(); return 0; - } -} - -static size_t GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel) -{ - // TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; - - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return 1024; // D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx ID3D11DeviceContext::VSSetConstantBuffers - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return 255 - d3d11_gl::GetReservedVertexUniformVectors(featureLevel); - - default: UNREACHABLE(); return 0; - } -} - -static size_t GetReservedVertexUniformBuffers() -{ - // Reserve one buffer for the application uniforms, and one for driver uniforms - return 2; -} - -static size_t GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel) -{ - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers(); - - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedVertexUniformBuffers(); - - // Uniform blocks not supported on D3D11 Feature Level 9 - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return 0; - - default: UNREACHABLE(); return 0; - } -} - -static size_t GetReservedVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel) -{ - // According to The OpenGL ES Shading Language specifications - // (Language Version 1.00 section 10.16, Language Version 3.10 section 12.21) - // built-in special variables (e.g. gl_FragCoord, or gl_PointCoord) - // which are statically used in the shader should be included in the variable packing algorithm. - // Therefore, we should not reserve output vectors for them. - - switch (featureLevel) - { - // We must reserve one output vector for dx_Position. - // We also reserve one for gl_Position, which we unconditionally output on Feature Levels 10_0+, - // even if it's unused in the shader (e.g. for transform feedback). TODO: This could be improved. - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return 2; - - // Just reserve dx_Position on Feature Level 9, since we don't ever need to output gl_Position. - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return 1; - - default: UNREACHABLE(); return 0; - } - - return 1; -} - -static size_t GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel) -{ - static_assert(gl::IMPLEMENTATION_MAX_VARYING_VECTORS == D3D11_VS_OUTPUT_REGISTER_COUNT, "Unexpected D3D11 constant value."); - - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: return D3D11_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel); - - case D3D_FEATURE_LEVEL_10_1: return D3D10_1_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel); - case D3D_FEATURE_LEVEL_10_0: return D3D10_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel); - - // Use Shader Model 2.X limits - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return 8 - GetReservedVertexOutputVectors(featureLevel); - - default: UNREACHABLE(); return 0; - } -} - -static size_t GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel) -{ - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; - - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; - - // Vertex textures not supported on D3D11 Feature Level 9 according to - // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx - // ID3D11DeviceContext::VSSetSamplers and ID3D11DeviceContext::VSSetShaderResources - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return 0; - - default: UNREACHABLE(); return 0; - } -} - -static size_t GetMaximumPixelUniformVectors(D3D_FEATURE_LEVEL featureLevel) -{ - // TODO(geofflang): Remove hard-coded limit once the gl-uniform-arrays test can pass - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: return 1024; // D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; - - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return 1024; // D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT; - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx ID3D11DeviceContext::PSSetConstantBuffers - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return 32 - d3d11_gl::GetReservedFragmentUniformVectors(featureLevel); - - default: UNREACHABLE(); return 0; - } -} - -static size_t GetReservedPixelUniformBuffers() -{ - // Reserve one buffer for the application uniforms, and one for driver uniforms - return 2; -} - -static size_t GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel) -{ - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers(); - - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - GetReservedPixelUniformBuffers(); - - // Uniform blocks not supported on D3D11 Feature Level 9 - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return 0; - - default: UNREACHABLE(); return 0; - } -} - -static size_t GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel) -{ - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: return D3D11_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel); - - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return D3D10_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel); - - // Use Shader Model 2.X limits - case D3D_FEATURE_LEVEL_9_3: return 8 - GetReservedVertexOutputVectors(featureLevel); - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return 8 - GetReservedVertexOutputVectors(featureLevel); - - default: UNREACHABLE(); return 0; - } -} - -static size_t GetMaximumPixelTextureUnits(D3D_FEATURE_LEVEL featureLevel) -{ - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; - - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT; - - // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx ID3D11DeviceContext::PSSetShaderResources - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return 16; - - default: UNREACHABLE(); return 0; - } -} - -static int GetMinimumTexelOffset(D3D_FEATURE_LEVEL featureLevel) -{ - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE; - - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return D3D10_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE; - - // Sampling functions with offsets are not available below shader model 4.0. - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return 0; - - default: UNREACHABLE(); return 0; - } -} - -static int GetMaximumTexelOffset(D3D_FEATURE_LEVEL featureLevel) -{ - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE; - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE; - - // Sampling functions with offsets are not available below shader model 4.0. - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return 0; - - default: UNREACHABLE(); return 0; - } -} - -static size_t GetMaximumConstantBufferSize(D3D_FEATURE_LEVEL featureLevel) -{ - // Returns a size_t despite the limit being a GLuint64 because size_t is the maximum size of - // any buffer that could be allocated. - - const size_t bytesPerComponent = 4 * sizeof(float); - - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent; - - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent; - - // Limits from http://msdn.microsoft.com/en-us/library/windows/desktop/ff476501.aspx remarks section - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return 4096 * bytesPerComponent; - - default: UNREACHABLE(); return 0; - } -} - -static size_t GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel) -{ - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: return D3D11_SO_BUFFER_SLOT_COUNT; - - case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SO_BUFFER_SLOT_COUNT; - case D3D_FEATURE_LEVEL_10_0: return D3D10_SO_BUFFER_SLOT_COUNT; - - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return 0; - - default: UNREACHABLE(); return 0; - } -} - -static size_t GetMaximumStreamOutputInterleavedComponents(D3D_FEATURE_LEVEL featureLevel) -{ - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return GetMaximumVertexOutputVectors(featureLevel) * 4; - - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return 0; - - default: UNREACHABLE(); return 0; - } -} - -static size_t GetMaximumStreamOutputSeparateComponents(D3D_FEATURE_LEVEL featureLevel) -{ - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: return GetMaximumStreamOutputInterleavedComponents(featureLevel) / - GetMaximumStreamOutputBuffers(featureLevel); - - - // D3D 10 and 10.1 only allow one output per output slot if an output slot other than zero is used. - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return 4; - - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return 0; - - default: UNREACHABLE(); return 0; + // D3D10+ only allows 1 sample mask. + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return 1u; + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 0u; + default: + UNREACHABLE(); + return 0u; } } void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, const Renderer11DeviceCaps &renderer11DeviceCaps, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions, gl::Limitations *limitations) { - GLuint maxSamples = 0; D3D_FEATURE_LEVEL featureLevel = renderer11DeviceCaps.featureLevel; const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats(); - for (gl::FormatSet::const_iterator internalFormat = allFormats.begin(); internalFormat != allFormats.end(); ++internalFormat) + for (GLenum internalFormat : allFormats) { - gl::TextureCaps textureCaps = GenerateTextureFormatCaps(GetMaximumClientVersion(featureLevel), *internalFormat, device, renderer11DeviceCaps); - textureCapsMap->insert(*internalFormat, textureCaps); + gl::TextureCaps textureCaps = GenerateTextureFormatCaps( + GetMaximumClientVersion(featureLevel), internalFormat, device, renderer11DeviceCaps); + textureCapsMap->insert(internalFormat, textureCaps); - maxSamples = std::max(maxSamples, textureCaps.getMaxSamples()); - - if (gl::GetInternalFormatInfo(*internalFormat).compressed) + if (gl::GetSizedInternalFormatInfo(internalFormat).compressed) { - caps->compressedTextureFormats.push_back(*internalFormat); + caps->compressedTextureFormats.push_back(internalFormat); } } @@ -1226,6 +1346,14 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, cons caps->maxVertexTextureImageUnits = static_cast(GetMaximumVertexTextureUnits(featureLevel)); + // Vertex Attribute Bindings are emulated on D3D11. + caps->maxVertexAttribBindings = caps->maxVertexAttributes; + // Experimental testing confirmed there is no explicit limit on maximum buffer offset in D3D11. + caps->maxVertexAttribRelativeOffset = std::numeric_limits::max(); + // Experimental testing confirmed 2048 is the maximum stride that D3D11 can support on all + // platforms. + caps->maxVertexAttribStride = 2048; + // Fragment shader limits caps->maxFragmentUniformComponents = static_cast(GetMaximumPixelUniformVectors(featureLevel)) * 4; @@ -1239,10 +1367,28 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, cons caps->minProgramTexelOffset = GetMinimumTexelOffset(featureLevel); caps->maxProgramTexelOffset = GetMaximumTexelOffset(featureLevel); + // Compute shader limits + caps->maxComputeWorkGroupCount = GetMaxComputeWorkGroupCount(featureLevel); + caps->maxComputeWorkGroupSize = GetMaxComputeWorkGroupSize(featureLevel); + caps->maxComputeWorkGroupInvocations = + static_cast(GetMaxComputeWorkGroupInvocations(featureLevel)); + caps->maxComputeUniformComponents = + static_cast(GetMaximumComputeUniformVectors(featureLevel)) * 4; + caps->maxComputeUniformBlocks = + static_cast(GetMaximumComputeUniformBlocks(featureLevel)); + caps->maxComputeTextureImageUnits = + static_cast(GetMaximumComputeTextureUnits(featureLevel)); + caps->maxImageUnits = static_cast(GetMaximumImageUnits(featureLevel)); + caps->maxComputeImageUniforms = + static_cast(GetMaximumComputeImageUniforms(featureLevel)); + // Aggregate shader limits caps->maxUniformBufferBindings = caps->maxVertexUniformBlocks + caps->maxFragmentUniformBlocks; caps->maxUniformBlockSize = GetMaximumConstantBufferSize(featureLevel); + // TODO(oetuaho): Get a more accurate limit. For now using the minimum requirement for GLES 3.1. + caps->maxUniformLocations = 1024; + // With DirectX 11.1, constant buffer offset and size must be a multiple of 16 constants of 16 bytes each. // https://msdn.microsoft.com/en-us/library/windows/desktop/hh404649%28v=vs.85%29.aspx // With DirectX 11.0, we emulate UBO offsets using copies of ranges of the UBO however @@ -1254,6 +1400,9 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, cons static_cast(caps->maxVertexUniformComponents); caps->maxCombinedFragmentUniformComponents = (static_cast(caps->maxFragmentUniformBlocks) * static_cast(caps->maxUniformBlockSize / 4)) + static_cast(caps->maxFragmentUniformComponents); + caps->maxCombinedComputeUniformComponents = + static_cast(caps->maxComputeUniformBlocks * (caps->maxUniformBlockSize / 4) + + caps->maxComputeUniformComponents); caps->maxVaryingComponents = static_cast(GetMaximumVertexOutputVectors(featureLevel)) * 4; caps->maxVaryingVectors = static_cast(GetMaximumVertexOutputVectors(featureLevel)); @@ -1267,8 +1416,21 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, cons caps->maxTransformFeedbackSeparateComponents = static_cast(GetMaximumStreamOutputSeparateComponents(featureLevel)); - // Multisample limits - caps->maxSamples = maxSamples; + // Defer the computation of multisample limits to Context::updateCaps() where max*Samples values + // are determined according to available sample counts for each individual format. + caps->maxSamples = std::numeric_limits::max(); + caps->maxColorTextureSamples = std::numeric_limits::max(); + caps->maxDepthTextureSamples = std::numeric_limits::max(); + caps->maxIntegerSamples = std::numeric_limits::max(); + + // Sample mask words limits + caps->maxSampleMaskWords = GetMaxSampleMaskWords(featureLevel); + + // Framebuffer limits + caps->maxFramebufferSamples = std::numeric_limits::max(); + caps->maxFramebufferWidth = + static_cast(GetMaximumRenderToBufferWindowSize(featureLevel)); + caps->maxFramebufferHeight = caps->maxFramebufferWidth; // GL extension support extensions->setTextureExtensionSupport(*textureCapsMap); @@ -1286,12 +1448,15 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, cons extensions->maxTextureAnisotropy = GetMaximumAnisotropy(featureLevel); extensions->occlusionQueryBoolean = GetOcclusionQuerySupport(featureLevel); extensions->fence = GetEventQuerySupport(featureLevel); - extensions->timerQuery = false; // Unimplemented extensions->disjointTimerQuery = true; extensions->queryCounterBitsTimeElapsed = 64; extensions->queryCounterBitsTimestamp = 0; // Timestamps cannot be supported due to D3D11 limitations extensions->robustness = true; + // Direct3D guarantees to return zero for any resource that is accessed out of bounds. + // See https://msdn.microsoft.com/en-us/library/windows/desktop/ff476332(v=vs.85).aspx + // and https://msdn.microsoft.com/en-us/library/windows/desktop/ff476900(v=vs.85).aspx + extensions->robustBufferAccessBehavior = true; extensions->blendMinMax = true; extensions->framebufferBlit = GetFramebufferBlitSupport(featureLevel); extensions->framebufferMultisample = GetFramebufferMultisampleSupport(featureLevel); @@ -1300,17 +1465,29 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, cons extensions->standardDerivatives = GetDerivativeInstructionSupport(featureLevel); extensions->shaderTextureLOD = GetShaderTextureLODSupport(featureLevel); extensions->fragDepth = true; + extensions->multiview = IsMultiviewSupported(featureLevel); + if (extensions->multiview) + { + extensions->maxViews = + std::min(static_cast(gl::IMPLEMENTATION_ANGLE_MULTIVIEW_MAX_VIEWS), + std::min(static_cast(GetMaximum2DTextureArraySize(featureLevel)), + GetMaxViewportAndScissorRectanglesPerPipeline(featureLevel))); + } extensions->textureUsage = true; // This could be false since it has no effect in D3D11 extensions->discardFramebuffer = true; extensions->translatedShaderSource = true; extensions->fboRenderMipmap = false; extensions->debugMarker = true; extensions->eglImage = true; + extensions->eglImageExternal = true; + extensions->eglImageExternalEssl3 = true; + extensions->eglStreamConsumerExternal = true; extensions->unpackSubimage = true; extensions->packSubimage = true; - extensions->vertexArrayObject = true; - extensions->noError = true; extensions->lossyETCDecode = true; + extensions->syncQuery = GetEventQuerySupport(featureLevel); + extensions->copyTexture = true; + extensions->copyCompressedTexture = true; // D3D11 Feature Level 10_0+ uses SV_IsFrontFace in HLSL to emulate gl_FrontFacing. // D3D11 Feature Level 9_3 doesn't support SV_IsFrontFace, and has no equivalent, so can't support gl_FrontFacing. @@ -1340,8 +1517,355 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, cons #endif } +void GetSamplePosition(GLsizei sampleCount, size_t index, GLfloat *xy) +{ + size_t indexKey = static_cast(ceil(log(sampleCount))); + ASSERT(indexKey < kSamplePositions.size() && + (2 * index + 1) < kSamplePositions[indexKey].size()); + + xy[0] = kSamplePositions[indexKey][2 * index]; + xy[1] = kSamplePositions[indexKey][2 * index + 1]; +} + } // namespace d3d11_gl +namespace gl_d3d11 +{ + +D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha) +{ + D3D11_BLEND d3dBlend = D3D11_BLEND_ZERO; + + switch (glBlend) + { + case GL_ZERO: + d3dBlend = D3D11_BLEND_ZERO; + break; + case GL_ONE: + d3dBlend = D3D11_BLEND_ONE; + break; + case GL_SRC_COLOR: + d3dBlend = (isAlpha ? D3D11_BLEND_SRC_ALPHA : D3D11_BLEND_SRC_COLOR); + break; + case GL_ONE_MINUS_SRC_COLOR: + d3dBlend = (isAlpha ? D3D11_BLEND_INV_SRC_ALPHA : D3D11_BLEND_INV_SRC_COLOR); + break; + case GL_DST_COLOR: + d3dBlend = (isAlpha ? D3D11_BLEND_DEST_ALPHA : D3D11_BLEND_DEST_COLOR); + break; + case GL_ONE_MINUS_DST_COLOR: + d3dBlend = (isAlpha ? D3D11_BLEND_INV_DEST_ALPHA : D3D11_BLEND_INV_DEST_COLOR); + break; + case GL_SRC_ALPHA: + d3dBlend = D3D11_BLEND_SRC_ALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + d3dBlend = D3D11_BLEND_INV_SRC_ALPHA; + break; + case GL_DST_ALPHA: + d3dBlend = D3D11_BLEND_DEST_ALPHA; + break; + case GL_ONE_MINUS_DST_ALPHA: + d3dBlend = D3D11_BLEND_INV_DEST_ALPHA; + break; + case GL_CONSTANT_COLOR: + d3dBlend = D3D11_BLEND_BLEND_FACTOR; + break; + case GL_ONE_MINUS_CONSTANT_COLOR: + d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR; + break; + case GL_CONSTANT_ALPHA: + d3dBlend = D3D11_BLEND_BLEND_FACTOR; + break; + case GL_ONE_MINUS_CONSTANT_ALPHA: + d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR; + break; + case GL_SRC_ALPHA_SATURATE: + d3dBlend = D3D11_BLEND_SRC_ALPHA_SAT; + break; + default: + UNREACHABLE(); + } + + return d3dBlend; +} + +D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp) +{ + D3D11_BLEND_OP d3dBlendOp = D3D11_BLEND_OP_ADD; + + switch (glBlendOp) + { + case GL_FUNC_ADD: + d3dBlendOp = D3D11_BLEND_OP_ADD; + break; + case GL_FUNC_SUBTRACT: + d3dBlendOp = D3D11_BLEND_OP_SUBTRACT; + break; + case GL_FUNC_REVERSE_SUBTRACT: + d3dBlendOp = D3D11_BLEND_OP_REV_SUBTRACT; + break; + case GL_MIN: + d3dBlendOp = D3D11_BLEND_OP_MIN; + break; + case GL_MAX: + d3dBlendOp = D3D11_BLEND_OP_MAX; + break; + default: + UNREACHABLE(); + } + + return d3dBlendOp; +} + +UINT8 ConvertColorMask(bool red, bool green, bool blue, bool alpha) +{ + UINT8 mask = 0; + if (red) + { + mask |= D3D11_COLOR_WRITE_ENABLE_RED; + } + if (green) + { + mask |= D3D11_COLOR_WRITE_ENABLE_GREEN; + } + if (blue) + { + mask |= D3D11_COLOR_WRITE_ENABLE_BLUE; + } + if (alpha) + { + mask |= D3D11_COLOR_WRITE_ENABLE_ALPHA; + } + return mask; +} + +D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, gl::CullFaceMode cullMode) +{ + D3D11_CULL_MODE cull = D3D11_CULL_NONE; + + if (cullEnabled) + { + switch (cullMode) + { + case gl::CullFaceMode::Front: + cull = D3D11_CULL_FRONT; + break; + case gl::CullFaceMode::Back: + cull = D3D11_CULL_BACK; + break; + case gl::CullFaceMode::FrontAndBack: + cull = D3D11_CULL_NONE; + break; + default: + UNREACHABLE(); + } + } + else + { + cull = D3D11_CULL_NONE; + } + + return cull; +} + +D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison) +{ + D3D11_COMPARISON_FUNC d3dComp = D3D11_COMPARISON_NEVER; + switch (comparison) + { + case GL_NEVER: + d3dComp = D3D11_COMPARISON_NEVER; + break; + case GL_ALWAYS: + d3dComp = D3D11_COMPARISON_ALWAYS; + break; + case GL_LESS: + d3dComp = D3D11_COMPARISON_LESS; + break; + case GL_LEQUAL: + d3dComp = D3D11_COMPARISON_LESS_EQUAL; + break; + case GL_EQUAL: + d3dComp = D3D11_COMPARISON_EQUAL; + break; + case GL_GREATER: + d3dComp = D3D11_COMPARISON_GREATER; + break; + case GL_GEQUAL: + d3dComp = D3D11_COMPARISON_GREATER_EQUAL; + break; + case GL_NOTEQUAL: + d3dComp = D3D11_COMPARISON_NOT_EQUAL; + break; + default: + UNREACHABLE(); + } + + return d3dComp; +} + +D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled) +{ + return depthWriteEnabled ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; +} + +UINT8 ConvertStencilMask(GLuint stencilmask) +{ + return static_cast(stencilmask); +} + +D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp) +{ + D3D11_STENCIL_OP d3dStencilOp = D3D11_STENCIL_OP_KEEP; + + switch (stencilOp) + { + case GL_ZERO: + d3dStencilOp = D3D11_STENCIL_OP_ZERO; + break; + case GL_KEEP: + d3dStencilOp = D3D11_STENCIL_OP_KEEP; + break; + case GL_REPLACE: + d3dStencilOp = D3D11_STENCIL_OP_REPLACE; + break; + case GL_INCR: + d3dStencilOp = D3D11_STENCIL_OP_INCR_SAT; + break; + case GL_DECR: + d3dStencilOp = D3D11_STENCIL_OP_DECR_SAT; + break; + case GL_INVERT: + d3dStencilOp = D3D11_STENCIL_OP_INVERT; + break; + case GL_INCR_WRAP: + d3dStencilOp = D3D11_STENCIL_OP_INCR; + break; + case GL_DECR_WRAP: + d3dStencilOp = D3D11_STENCIL_OP_DECR; + break; + default: + UNREACHABLE(); + } + + return d3dStencilOp; +} + +D3D11_FILTER ConvertFilter(GLenum minFilter, + GLenum magFilter, + float maxAnisotropy, + GLenum comparisonMode) +{ + bool comparison = comparisonMode != GL_NONE; + + if (maxAnisotropy > 1.0f) + { + return D3D11_ENCODE_ANISOTROPIC_FILTER(static_cast(comparison)); + } + else + { + D3D11_FILTER_TYPE dxMin = D3D11_FILTER_TYPE_POINT; + D3D11_FILTER_TYPE dxMip = D3D11_FILTER_TYPE_POINT; + switch (minFilter) + { + case GL_NEAREST: + dxMin = D3D11_FILTER_TYPE_POINT; + dxMip = D3D11_FILTER_TYPE_POINT; + break; + case GL_LINEAR: + dxMin = D3D11_FILTER_TYPE_LINEAR; + dxMip = D3D11_FILTER_TYPE_POINT; + break; + case GL_NEAREST_MIPMAP_NEAREST: + dxMin = D3D11_FILTER_TYPE_POINT; + dxMip = D3D11_FILTER_TYPE_POINT; + break; + case GL_LINEAR_MIPMAP_NEAREST: + dxMin = D3D11_FILTER_TYPE_LINEAR; + dxMip = D3D11_FILTER_TYPE_POINT; + break; + case GL_NEAREST_MIPMAP_LINEAR: + dxMin = D3D11_FILTER_TYPE_POINT; + dxMip = D3D11_FILTER_TYPE_LINEAR; + break; + case GL_LINEAR_MIPMAP_LINEAR: + dxMin = D3D11_FILTER_TYPE_LINEAR; + dxMip = D3D11_FILTER_TYPE_LINEAR; + break; + default: + UNREACHABLE(); + } + + D3D11_FILTER_TYPE dxMag = D3D11_FILTER_TYPE_POINT; + switch (magFilter) + { + case GL_NEAREST: + dxMag = D3D11_FILTER_TYPE_POINT; + break; + case GL_LINEAR: + dxMag = D3D11_FILTER_TYPE_LINEAR; + break; + default: + UNREACHABLE(); + } + + return D3D11_ENCODE_BASIC_FILTER(dxMin, dxMag, dxMip, + static_cast(comparison)); + } +} + +D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap) +{ + switch (wrap) + { + case GL_REPEAT: + return D3D11_TEXTURE_ADDRESS_WRAP; + case GL_CLAMP_TO_EDGE: + return D3D11_TEXTURE_ADDRESS_CLAMP; + case GL_MIRRORED_REPEAT: + return D3D11_TEXTURE_ADDRESS_MIRROR; + default: + UNREACHABLE(); + } + + return D3D11_TEXTURE_ADDRESS_WRAP; +} + +UINT ConvertMaxAnisotropy(float maxAnisotropy, D3D_FEATURE_LEVEL featureLevel) +{ + return static_cast(std::min(maxAnisotropy, d3d11_gl::GetMaximumAnisotropy(featureLevel))); +} + +D3D11_QUERY ConvertQueryType(GLenum queryType) +{ + switch (queryType) + { + case GL_ANY_SAMPLES_PASSED_EXT: + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: + return D3D11_QUERY_OCCLUSION; + case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: + return D3D11_QUERY_SO_STATISTICS; + case GL_TIME_ELAPSED_EXT: + // Two internal queries are also created for begin/end timestamps + return D3D11_QUERY_TIMESTAMP_DISJOINT; + case GL_COMMANDS_COMPLETED_CHROMIUM: + return D3D11_QUERY_EVENT; + default: + UNREACHABLE(); + return D3D11_QUERY_EVENT; + } +} + +// Get the D3D11 write mask covering all color channels of a given format +UINT8 GetColorMask(const gl::InternalFormat &format) +{ + return ConvertColorMask(format.redBits > 0, format.greenBits > 0, format.blueBits > 0, + format.alphaBits > 0); +} + +} // namespace gl_d3d11 + namespace d3d11 { @@ -1352,9 +1876,7 @@ ANGLED3D11DeviceType GetDeviceType(ID3D11Device *device) IDXGIDevice *dxgiDevice = nullptr; IDXGIAdapter *dxgiAdapter = nullptr; -#if defined(ANGLE_ENABLE_D3D11_1) IDXGIAdapter2 *dxgiAdapter2 = nullptr; -#endif ANGLED3D11DeviceType retDeviceType = ANGLE_D3D11_DEVICE_TYPE_UNKNOWN; @@ -1365,7 +1887,6 @@ ANGLED3D11DeviceType GetDeviceType(ID3D11Device *device) if (SUCCEEDED(hr)) { std::wstring adapterString; -#if defined(ANGLE_ENABLE_D3D11_1) HRESULT adapter2hr = dxgiAdapter->QueryInterface(__uuidof(dxgiAdapter2), (void **)&dxgiAdapter2); if (SUCCEEDED(adapter2hr)) @@ -1378,7 +1899,6 @@ ANGLED3D11DeviceType GetDeviceType(ID3D11Device *device) adapterString = std::wstring(adapterDesc2.Description); } else -#endif { DXGI_ADAPTER_DESC adapterDesc; dxgiAdapter->GetDesc(&adapterDesc); @@ -1410,16 +1930,14 @@ ANGLED3D11DeviceType GetDeviceType(ID3D11Device *device) SafeRelease(dxgiDevice); SafeRelease(dxgiAdapter); -#if defined(ANGLE_ENABLE_D3D11_1) SafeRelease(dxgiAdapter2); -#endif return retDeviceType; } void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset) { - const DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(format); + const DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(format); int upsampleCount = 0; // Don't expand the size of full textures that are at least (blockWidth x blockHeight) already. @@ -1433,7 +1951,10 @@ void MakeValidSize(bool isImage, DXGI_FORMAT format, GLsizei *requestWidth, GLsi upsampleCount++; } } - *levelOffset = upsampleCount; + if (levelOffset) + { + *levelOffset = upsampleCount; + } } void GenerateInitialTextureData(GLint internalFormat, @@ -1445,10 +1966,11 @@ void GenerateInitialTextureData(GLint internalFormat, std::vector *outSubresourceData, std::vector> *outData) { - const d3d11::TextureFormat &d3dFormatInfo = d3d11::GetTextureFormatInfo(internalFormat, renderer11DeviceCaps); - ASSERT(d3dFormatInfo.dataInitializerFunction != NULL); + const d3d11::Format &d3dFormatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps); + ASSERT(d3dFormatInfo.dataInitializerFunction != nullptr); - const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(d3dFormatInfo.texFormat); + const d3d11::DXGIFormatSize &dxgiFormatInfo = + d3d11::GetDXGIFormatSizeInfo(d3dFormatInfo.texFormat); outSubresourceData->resize(mipLevels); outData->resize(mipLevels); @@ -1495,6 +2017,36 @@ void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex* vertex, flo vertex->s = s; } +BlendStateKey::BlendStateKey() +{ + memset(this, 0, sizeof(BlendStateKey)); +} + +bool operator==(const BlendStateKey &a, const BlendStateKey &b) +{ + return memcmp(&a, &b, sizeof(BlendStateKey)) == 0; +} + +bool operator!=(const BlendStateKey &a, const BlendStateKey &b) +{ + return !(a == b); +} + +RasterizerStateKey::RasterizerStateKey() +{ + memset(this, 0, sizeof(RasterizerStateKey)); +} + +bool operator==(const RasterizerStateKey &a, const RasterizerStateKey &b) +{ + return memcmp(&a, &b, sizeof(RasterizerStateKey)) == 0; +} + +bool operator!=(const RasterizerStateKey &a, const RasterizerStateKey &b) +{ + return !(a == b); +} + HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name) { #if defined(_DEBUG) @@ -1533,34 +2085,66 @@ HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name) #endif } +// Keep this in cpp file where it has visibility of Renderer11.h, otherwise calling +// allocateResource is only compatible with Clang and MSVS, which support calling a +// method on a forward declared class in a template. +template +gl::Error LazyResource::resolveImpl(Renderer11 *renderer, + const GetDescType &desc, + GetInitDataType *initData, + const char *name) +{ + if (!mResource.valid()) + { + ANGLE_TRY(renderer->allocateResource(desc, initData, &mResource)); + mResource.setDebugName(name); + } + return gl::NoError(); +} + +template gl::Error LazyResource::resolveImpl(Renderer11 *renderer, + const D3D11_BLEND_DESC &desc, + void *initData, + const char *name); +template gl::Error LazyResource::resolveImpl(Renderer11 *renderer, + const ShaderData &desc, + void *initData, + const char *name); +template gl::Error LazyResource::resolveImpl( + Renderer11 *renderer, + const ShaderData &desc, + const std::vector *initData, + const char *name); +template gl::Error LazyResource::resolveImpl( + Renderer11 *renderer, + const InputElementArray &desc, + const ShaderData *initData, + const char *name); +template gl::Error LazyResource::resolveImpl(Renderer11 *renderer, + const ShaderData &desc, + void *initData, + const char *name); +template gl::Error LazyResource::resolveImpl(Renderer11 *renderer, + const ShaderData &desc, + void *initData, + const char *name); + LazyInputLayout::LazyInputLayout(const D3D11_INPUT_ELEMENT_DESC *inputDesc, size_t inputDescLen, const BYTE *byteCode, size_t byteCodeLen, const char *debugName) - : mInputDesc(inputDescLen), - mByteCodeLen(byteCodeLen), - mByteCode(byteCode), - mDebugName(debugName) + : mInputDesc(inputDesc, inputDescLen), mByteCode(byteCode, byteCodeLen), mDebugName(debugName) { - memcpy(&mInputDesc[0], inputDesc, sizeof(D3D11_INPUT_ELEMENT_DESC) * inputDescLen); } -ID3D11InputLayout *LazyInputLayout::resolve(ID3D11Device *device) +LazyInputLayout::~LazyInputLayout() { - checkAssociatedDevice(device); +} - if (mResource == nullptr) - { - HRESULT result = - device->CreateInputLayout(&mInputDesc[0], static_cast(mInputDesc.size()), - mByteCode, mByteCodeLen, &mResource); - ASSERT(SUCCEEDED(result)); - UNUSED_ASSERTION_VARIABLE(result); - d3d11::SetDebugName(mResource, mDebugName); - } - - return mResource; +gl::Error LazyInputLayout::resolve(Renderer11 *renderer) +{ + return resolveImpl(renderer, mInputDesc, &mByteCode, mDebugName); } LazyBlendState::LazyBlendState(const D3D11_BLEND_DESC &desc, const char *debugName) @@ -1568,201 +2152,174 @@ LazyBlendState::LazyBlendState(const D3D11_BLEND_DESC &desc, const char *debugNa { } -ID3D11BlendState *LazyBlendState::resolve(ID3D11Device *device) +gl::Error LazyBlendState::resolve(Renderer11 *renderer) { - checkAssociatedDevice(device); - - if (mResource == nullptr) - { - HRESULT result = device->CreateBlendState(&mDesc, &mResource); - ASSERT(SUCCEEDED(result)); - UNUSED_ASSERTION_VARIABLE(result); - d3d11::SetDebugName(mResource, mDebugName); - } - - return mResource; + return resolveImpl(renderer, mDesc, nullptr, mDebugName); } -WorkaroundsD3D GenerateWorkarounds(D3D_FEATURE_LEVEL featureLevel) +angle::WorkaroundsD3D GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps, + const DXGI_ADAPTER_DESC &adapterDesc) { - WorkaroundsD3D workarounds; + bool is9_3 = (deviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3); + + angle::WorkaroundsD3D workarounds; workarounds.mrtPerfWorkaround = true; workarounds.setDataFasterThanImageUpload = true; - workarounds.zeroMaxLodWorkaround = (featureLevel <= D3D_FEATURE_LEVEL_9_3); - workarounds.useInstancedPointSpriteEmulation = (featureLevel <= D3D_FEATURE_LEVEL_9_3); + workarounds.zeroMaxLodWorkaround = is9_3; + workarounds.useInstancedPointSpriteEmulation = is9_3; + + // TODO(jmadill): Narrow problematic driver range. + if (IsNvidia(adapterDesc.VendorId)) + { + if (deviceCaps.driverVersion.valid()) + { + WORD part1 = HIWORD(deviceCaps.driverVersion.value().LowPart); + WORD part2 = LOWORD(deviceCaps.driverVersion.value().LowPart); + + // Disable the workaround to fix a second driver bug on newer NVIDIA. + workarounds.depthStencilBlitExtraCopy = (part1 <= 13u && part2 < 6881); + } + else + { + workarounds.depthStencilBlitExtraCopy = true; + } + } + + // TODO(jmadill): Disable workaround when we have a fixed compiler DLL. + workarounds.expandIntegerPowExpressions = true; + + workarounds.flushAfterEndingTransformFeedback = IsNvidia(adapterDesc.VendorId); + workarounds.getDimensionsIgnoresBaseLevel = IsNvidia(adapterDesc.VendorId); + + if (IsIntel(adapterDesc.VendorId)) + { + IntelDriverVersion capsVersion = d3d11_gl::GetIntelDriverVersion(deviceCaps.driverVersion); + + workarounds.preAddTexelFetchOffsets = true; + workarounds.useSystemMemoryForConstantBuffers = true; + workarounds.disableB5G6R5Support = capsVersion < IntelDriverVersion(4539); + workarounds.addDummyTextureNoRenderTarget = capsVersion < IntelDriverVersion(4815); + if (IsSkylake(adapterDesc.DeviceId)) + { + workarounds.callClearTwice = capsVersion < IntelDriverVersion(4771); + workarounds.emulateIsnanFloat = capsVersion < IntelDriverVersion(4542); + } + else if (IsBroadwell(adapterDesc.DeviceId) || IsHaswell(adapterDesc.DeviceId)) + { + workarounds.rewriteUnaryMinusOperator = capsVersion < IntelDriverVersion(4624); + } + } + + // TODO(jmadill): Disable when we have a fixed driver version. + workarounds.emulateTinyStencilTextures = IsAMD(adapterDesc.VendorId); + + // The tiny stencil texture workaround involves using CopySubresource or UpdateSubresource on a + // depth stencil texture. This is not allowed until feature level 10.1 but since it is not + // possible to support ES3 on these devices, there is no need for the workaround to begin with + // (anglebug.com/1572). + if (deviceCaps.featureLevel < D3D_FEATURE_LEVEL_10_1) + { + workarounds.emulateTinyStencilTextures = false; + } + + // If the VPAndRTArrayIndexFromAnyShaderFeedingRasterizer feature is not available, we have to + // select the viewport / RT array index in the geometry shader. + workarounds.selectViewInGeometryShader = + (deviceCaps.supportsVpRtIndexWriteFromVertexShader == false); + + // Call platform hooks for testing overrides. + auto *platform = ANGLEPlatformCurrent(); + platform->overrideWorkaroundsD3D(platform, &workarounds); + return workarounds; } +void InitConstantBufferDesc(D3D11_BUFFER_DESC *constantBufferDescription, size_t byteWidth) +{ + constantBufferDescription->ByteWidth = static_cast(byteWidth); + constantBufferDescription->Usage = D3D11_USAGE_DYNAMIC; + constantBufferDescription->BindFlags = D3D11_BIND_CONSTANT_BUFFER; + constantBufferDescription->CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + constantBufferDescription->MiscFlags = 0; + constantBufferDescription->StructureByteStride = 0; +} + } // namespace d3d11 -TextureHelper11::TextureHelper11() - : mTextureType(GL_NONE), - mFormat(DXGI_FORMAT_UNKNOWN), - mSampleCount(0), - mTexture2D(nullptr), - mTexture3D(nullptr) +// TextureHelper11 implementation. +TextureHelper11::TextureHelper11() : mFormatSet(nullptr), mSampleCount(0) { } -TextureHelper11::TextureHelper11(TextureHelper11 &&toCopy) - : mTextureType(toCopy.mTextureType), - mExtents(toCopy.mExtents), - mFormat(toCopy.mFormat), - mSampleCount(toCopy.mSampleCount), - mTexture2D(toCopy.mTexture2D), - mTexture3D(toCopy.mTexture3D) +TextureHelper11::TextureHelper11(TextureHelper11 &&toCopy) : TextureHelper11() { - toCopy.reset(); + *this = std::move(toCopy); } -// static -TextureHelper11 TextureHelper11::MakeAndReference(ID3D11Resource *genericResource) +TextureHelper11::TextureHelper11(const TextureHelper11 &other) + : mFormatSet(other.mFormatSet), mExtents(other.mExtents), mSampleCount(other.mSampleCount) { - TextureHelper11 newHelper; - newHelper.mTexture2D = d3d11::DynamicCastComObject(genericResource); - newHelper.mTexture3D = d3d11::DynamicCastComObject(genericResource); - newHelper.mTextureType = newHelper.mTexture2D ? GL_TEXTURE_2D : GL_TEXTURE_3D; - newHelper.initDesc(); - return newHelper; -} - -// static -TextureHelper11 TextureHelper11::MakeAndPossess2D(ID3D11Texture2D *texToOwn) -{ - TextureHelper11 newHelper; - newHelper.mTexture2D = texToOwn; - newHelper.mTextureType = GL_TEXTURE_2D; - newHelper.initDesc(); - return newHelper; -} - -// static -TextureHelper11 TextureHelper11::MakeAndPossess3D(ID3D11Texture3D *texToOwn) -{ - TextureHelper11 newHelper; - newHelper.mTexture3D = texToOwn; - newHelper.mTextureType = GL_TEXTURE_3D; - newHelper.initDesc(); - return newHelper; -} - -void TextureHelper11::initDesc() -{ - if (mTextureType == GL_TEXTURE_2D) - { - ASSERT(!mTexture3D); - D3D11_TEXTURE2D_DESC desc2D; - mTexture2D->GetDesc(&desc2D); - - mExtents.width = static_cast(desc2D.Width); - mExtents.height = static_cast(desc2D.Height); - mExtents.depth = 1; - mFormat = desc2D.Format; - mSampleCount = desc2D.SampleDesc.Count; - } - else - { - ASSERT(mTexture3D && mTextureType == GL_TEXTURE_3D); - D3D11_TEXTURE3D_DESC desc3D; - mTexture3D->GetDesc(&desc3D); - - mExtents.width = static_cast(desc3D.Width); - mExtents.height = static_cast(desc3D.Height); - mExtents.depth = static_cast(desc3D.Depth); - mFormat = desc3D.Format; - mSampleCount = 1; - } + mData = other.mData; } TextureHelper11::~TextureHelper11() { - SafeRelease(mTexture2D); - SafeRelease(mTexture3D); } -ID3D11Resource *TextureHelper11::getResource() const +void TextureHelper11::getDesc(D3D11_TEXTURE2D_DESC *desc) const { - return mTexture2D ? static_cast(mTexture2D) - : static_cast(mTexture3D); + static_cast(mData->object)->GetDesc(desc); } -TextureHelper11 &TextureHelper11::operator=(TextureHelper11 &&texture) +void TextureHelper11::getDesc(D3D11_TEXTURE3D_DESC *desc) const { - SafeRelease(mTexture2D); - SafeRelease(mTexture3D); + static_cast(mData->object)->GetDesc(desc); +} - mTextureType = texture.mTextureType; - mExtents = texture.mExtents; - mFormat = texture.mFormat; - mSampleCount = texture.mSampleCount; - mTexture2D = texture.mTexture2D; - mTexture3D = texture.mTexture3D; - texture.reset(); +void TextureHelper11::initDesc(const D3D11_TEXTURE2D_DESC &desc2D) +{ + mData->resourceType = ResourceType::Texture2D; + mExtents.width = static_cast(desc2D.Width); + mExtents.height = static_cast(desc2D.Height); + mExtents.depth = 1; + mSampleCount = desc2D.SampleDesc.Count; +} + +void TextureHelper11::initDesc(const D3D11_TEXTURE3D_DESC &desc3D) +{ + mData->resourceType = ResourceType::Texture3D; + mExtents.width = static_cast(desc3D.Width); + mExtents.height = static_cast(desc3D.Height); + mExtents.depth = static_cast(desc3D.Depth); + mSampleCount = 1; +} + +TextureHelper11 &TextureHelper11::operator=(TextureHelper11 &&other) +{ + std::swap(mData, other.mData); + std::swap(mExtents, other.mExtents); + std::swap(mFormatSet, other.mFormatSet); + std::swap(mSampleCount, other.mSampleCount); return *this; } -void TextureHelper11::reset() +TextureHelper11 &TextureHelper11::operator=(const TextureHelper11 &other) { - mTextureType = GL_NONE; - mExtents = gl::Extents(); - mFormat = DXGI_FORMAT_UNKNOWN; - mSampleCount = 0; - mTexture2D = nullptr; - mTexture3D = nullptr; + mData = other.mData; + mExtents = other.mExtents; + mFormatSet = other.mFormatSet; + mSampleCount = other.mSampleCount; + return *this; } -gl::ErrorOrResult CreateStagingTexture(GLenum textureType, - DXGI_FORMAT dxgiFormat, - const gl::Extents &size, - ID3D11Device *device) +bool TextureHelper11::operator==(const TextureHelper11 &other) const { - if (textureType == GL_TEXTURE_2D) - { - D3D11_TEXTURE2D_DESC stagingDesc; - stagingDesc.Width = size.width; - stagingDesc.Height = size.height; - stagingDesc.MipLevels = 1; - stagingDesc.ArraySize = 1; - stagingDesc.Format = dxgiFormat; - stagingDesc.SampleDesc.Count = 1; - stagingDesc.SampleDesc.Quality = 0; - stagingDesc.Usage = D3D11_USAGE_STAGING; - stagingDesc.BindFlags = 0; - stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - stagingDesc.MiscFlags = 0; + return mData->object == other.mData->object; +} - ID3D11Texture2D *stagingTex = nullptr; - HRESULT result = device->CreateTexture2D(&stagingDesc, nullptr, &stagingTex); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "CreateStagingTextureFor failed, HRESULT: 0x%X.", - result); - } - - return TextureHelper11::MakeAndPossess2D(stagingTex); - } - ASSERT(textureType == GL_TEXTURE_3D); - - D3D11_TEXTURE3D_DESC stagingDesc; - stagingDesc.Width = size.width; - stagingDesc.Height = size.height; - stagingDesc.Depth = 1; - stagingDesc.MipLevels = 1; - stagingDesc.Format = dxgiFormat; - stagingDesc.Usage = D3D11_USAGE_STAGING; - stagingDesc.BindFlags = 0; - stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - stagingDesc.MiscFlags = 0; - - ID3D11Texture3D *stagingTex = nullptr; - HRESULT result = device->CreateTexture3D(&stagingDesc, nullptr, &stagingTex); - if (FAILED(result)) - { - return gl::Error(GL_OUT_OF_MEMORY, "CreateStagingTextureFor failed, HRESULT: 0x%X.", - result); - } - - return TextureHelper11::MakeAndPossess3D(stagingTex); +bool TextureHelper11::operator!=(const TextureHelper11 &other) const +{ + return mData->object != other.mData->object; } bool UsePresentPathFast(const Renderer11 *renderer, @@ -1777,4 +2334,88 @@ bool UsePresentPathFast(const Renderer11 *renderer, renderer->presentPathFastEnabled()); } +bool UsePrimitiveRestartWorkaround(bool primitiveRestartFixedIndexEnabled, GLenum type) +{ + // We should never have to deal with primitive restart workaround issue with GL_UNSIGNED_INT + // indices, since we restrict it via MAX_ELEMENT_INDEX. + return (!primitiveRestartFixedIndexEnabled && type == GL_UNSIGNED_SHORT); +} + +bool IsStreamingIndexData(const gl::Context *context, GLenum srcType) +{ + const auto &glState = context->getGLState(); + gl::Buffer *glBuffer = glState.getVertexArray()->getElementArrayBuffer().get(); + + // Case 1: the indices are passed by pointer, which forces the streaming of index data + if (glBuffer == nullptr) + { + return true; + } + + bool primitiveRestartWorkaround = + UsePrimitiveRestartWorkaround(glState.isPrimitiveRestartEnabled(), srcType); + + BufferD3D *buffer = GetImplAs(glBuffer); + const GLenum dstType = (srcType == GL_UNSIGNED_INT || primitiveRestartWorkaround) + ? GL_UNSIGNED_INT + : GL_UNSIGNED_SHORT; + + // Case 2a: the buffer can be used directly + if (buffer->supportsDirectBinding() && dstType == srcType) + { + return false; + } + + // Case 2b: use a static translated copy or fall back to streaming + StaticIndexBufferInterface *staticBuffer = buffer->getStaticIndexBuffer(); + if (staticBuffer == nullptr) + { + return true; + } + + if ((staticBuffer->getBufferSize() == 0) || (staticBuffer->getIndexType() != dstType)) + { + return true; + } + + return false; +} + +IndexStorageType ClassifyIndexStorage(const gl::State &glState, + const gl::Buffer *elementArrayBuffer, + GLenum elementType, + GLenum destElementType, + unsigned int offset, + bool *needsTranslation) +{ + // No buffer bound means we are streaming from a client pointer. + if (!elementArrayBuffer || !IsOffsetAligned(elementType, offset)) + { + *needsTranslation = true; + return IndexStorageType::Dynamic; + } + + // The buffer can be used directly if the storage supports it and no translation needed. + BufferD3D *bufferD3D = GetImplAs(elementArrayBuffer); + if (bufferD3D->supportsDirectBinding() && destElementType == elementType) + { + *needsTranslation = false; + return IndexStorageType::Direct; + } + + // Use a static copy when available. + StaticIndexBufferInterface *staticBuffer = bufferD3D->getStaticIndexBuffer(); + if (staticBuffer != nullptr) + { + // Need to re-translate the static data if has never been used, or changed type. + *needsTranslation = + (staticBuffer->getBufferSize() == 0 || staticBuffer->getIndexType() != destElementType); + return IndexStorageType::Static; + } + + // Static buffer not available, fall back to streaming. + *needsTranslation = true; + return IndexStorageType::Dynamic; +} + } // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h index 4925a2d227..3af51bb0f6 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h @@ -11,12 +11,16 @@ #define LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_UTILS_H_ #include +#include #include -#include "libANGLE/angletypes.h" +#include "common/Color.h" + #include "libANGLE/Caps.h" #include "libANGLE/Error.h" #include "libANGLE/renderer/d3d/RendererD3D.h" +#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" namespace gl { @@ -27,10 +31,10 @@ namespace rx { class Renderer11; class RenderTarget11; -struct WorkaroundsD3D; struct Renderer11DeviceCaps; -using RenderTargetArray = std::array; +using RenderTargetArray = std::array; +using RTVArray = std::array; namespace gl_d3d11 { @@ -39,7 +43,7 @@ D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha); D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp); UINT8 ConvertColorMask(bool maskRed, bool maskGreen, bool maskBlue, bool maskAlpha); -D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, GLenum cullMode); +D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, gl::CullFaceMode cullMode); D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison); D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled); @@ -48,9 +52,12 @@ D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp); D3D11_FILTER ConvertFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy, GLenum comparisonMode); D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap); +UINT ConvertMaxAnisotropy(float maxAnisotropy, D3D_FEATURE_LEVEL featureLevel); D3D11_QUERY ConvertQueryType(GLenum queryType); +UINT8 GetColorMask(const gl::InternalFormat &formatInfo); + } // namespace gl_d3d11 namespace d3d11_gl @@ -60,10 +67,12 @@ unsigned int GetReservedVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel); unsigned int GetReservedFragmentUniformVectors(D3D_FEATURE_LEVEL featureLevel); -GLint GetMaximumClientVersion(D3D_FEATURE_LEVEL featureLevel); +gl::Version GetMaximumClientVersion(D3D_FEATURE_LEVEL featureLevel); void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, const Renderer11DeviceCaps &renderer11DeviceCaps, gl::Caps *caps, gl::TextureCapsMap *textureCapsMap, gl::Extensions *extensions, gl::Limitations *limitations); +void GetSamplePosition(GLsizei sampleCount, size_t index, GLfloat *xy); + } // namespace d3d11_gl namespace d3d11 @@ -108,32 +117,45 @@ struct PositionLayerTexCoord3DVertex void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex* vertex, float x, float y, unsigned int layer, float u, float v, float s); -template -struct PositionDepthColorVertex +struct PositionVertex { - float x, y, z; - T r, g, b, a; + float x, y, z, w; }; -template -void SetPositionDepthColorVertex(PositionDepthColorVertex* vertex, float x, float y, float z, - const gl::Color &color) +struct BlendStateKey final { - vertex->x = x; - vertex->y = y; - vertex->z = z; - vertex->r = color.red; - vertex->g = color.green; - vertex->b = color.blue; - vertex->a = color.alpha; -} + // This will zero-initialize the struct, including padding. + BlendStateKey(); -HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name); + gl::BlendState blendState; + + // An int so struct size rounds nicely. + uint32_t rtvMax; + + uint8_t rtvMasks[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT]; +}; + +bool operator==(const BlendStateKey &a, const BlendStateKey &b); +bool operator!=(const BlendStateKey &a, const BlendStateKey &b); + +struct RasterizerStateKey final +{ + // This will zero-initialize the struct, including padding. + RasterizerStateKey(); + + gl::RasterizerState rasterizerState; + + // Use a 32-bit int to round the struct nicely. + uint32_t scissorEnabled; +}; + +bool operator==(const RasterizerStateKey &a, const RasterizerStateKey &b); +bool operator!=(const RasterizerStateKey &a, const RasterizerStateKey &b); template outType* DynamicCastComObject(IUnknown* object) { - outType *outObject = NULL; + outType *outObject = nullptr; HRESULT result = object->QueryInterface(__uuidof(outType), reinterpret_cast(&outObject)); if (SUCCEEDED(result)) { @@ -142,7 +164,7 @@ outType* DynamicCastComObject(IUnknown* object) else { SafeRelease(outObject); - return NULL; + return nullptr; } } @@ -161,143 +183,63 @@ inline bool isDeviceLostError(HRESULT errorCode) } } -inline ID3D11VertexShader *CompileVS(ID3D11Device *device, const BYTE *byteCode, size_t N, const char *name) -{ - ID3D11VertexShader *vs = nullptr; - HRESULT result = device->CreateVertexShader(byteCode, N, nullptr, &vs); - ASSERT(SUCCEEDED(result)); - if (SUCCEEDED(result)) - { - SetDebugName(vs, name); - return vs; - } - return nullptr; -} - -template -ID3D11VertexShader *CompileVS(ID3D11Device *device, const BYTE (&byteCode)[N], const char *name) -{ - return CompileVS(device, byteCode, N, name); -} - -inline ID3D11GeometryShader *CompileGS(ID3D11Device *device, const BYTE *byteCode, size_t N, const char *name) -{ - ID3D11GeometryShader *gs = nullptr; - HRESULT result = device->CreateGeometryShader(byteCode, N, nullptr, &gs); - ASSERT(SUCCEEDED(result)); - if (SUCCEEDED(result)) - { - SetDebugName(gs, name); - return gs; - } - return nullptr; -} - -template -ID3D11GeometryShader *CompileGS(ID3D11Device *device, const BYTE (&byteCode)[N], const char *name) -{ - return CompileGS(device, byteCode, N, name); -} - -inline ID3D11PixelShader *CompilePS(ID3D11Device *device, const BYTE *byteCode, size_t N, const char *name) -{ - ID3D11PixelShader *ps = nullptr; - HRESULT result = device->CreatePixelShader(byteCode, N, nullptr, &ps); - ASSERT(SUCCEEDED(result)); - if (SUCCEEDED(result)) - { - SetDebugName(ps, name); - return ps; - } - return nullptr; -} - -template -ID3D11PixelShader *CompilePS(ID3D11Device *device, const BYTE (&byteCode)[N], const char *name) -{ - return CompilePS(device, byteCode, N, name); -} - -template -class LazyResource : public angle::NonCopyable +template +class LazyResource : angle::NonCopyable { public: - LazyResource() : mResource(nullptr), mAssociatedDevice(nullptr) {} - virtual ~LazyResource() { release(); } + constexpr LazyResource() : mResource() {} + virtual ~LazyResource() {} - virtual ResourceType *resolve(ID3D11Device *device) = 0; - void release() { SafeRelease(mResource); } + virtual gl::Error resolve(Renderer11 *renderer) = 0; + void reset() { mResource.reset(); } + GetD3D11Type *get() const + { + ASSERT(mResource.valid()); + return mResource.get(); + } + + const Resource11> &getObj() const { return mResource; } protected: - void checkAssociatedDevice(ID3D11Device *device); + LazyResource(LazyResource &&other) : mResource(std::move(other.mResource)) {} - ResourceType *mResource; - ID3D11Device *mAssociatedDevice; + // Specialized in the cpp file to avoid MSVS/Clang specific code. + gl::Error resolveImpl(Renderer11 *renderer, + const GetDescType &desc, + GetInitDataType *initData, + const char *name); + + Resource11> mResource; }; -template -void LazyResource::checkAssociatedDevice(ID3D11Device *device) -{ - ASSERT(mAssociatedDevice == nullptr || device == mAssociatedDevice); - mAssociatedDevice = device; -} - template -class LazyShader final : public LazyResource +class LazyShader final : public LazyResource()> { public: // All parameters must be constexpr. Not supported in VS2013. - LazyShader(const BYTE *byteCode, - size_t byteCodeSize, - const char *name) - : mByteCode(byteCode), - mByteCodeSize(byteCodeSize), - mName(name) + constexpr LazyShader(const BYTE *byteCode, size_t byteCodeSize, const char *name) + : mByteCode(byteCode, byteCodeSize), mName(name) { } - D3D11ShaderType *resolve(ID3D11Device *device) override; + constexpr LazyShader(LazyShader &&shader) + : LazyResource()>(std::move(shader)), + mByteCode(std::move(shader.mByteCode)), + mName(shader.mName) + { + } + + gl::Error resolve(Renderer11 *renderer) override + { + return this->resolveImpl(renderer, mByteCode, nullptr, mName); + } private: - const BYTE *mByteCode; - size_t mByteCodeSize; + ShaderData mByteCode; const char *mName; }; -template <> -inline ID3D11VertexShader *LazyShader::resolve(ID3D11Device *device) -{ - checkAssociatedDevice(device); - if (mResource == nullptr) - { - mResource = CompileVS(device, mByteCode, mByteCodeSize, mName); - } - return mResource; -} - -template <> -inline ID3D11GeometryShader *LazyShader::resolve(ID3D11Device *device) -{ - checkAssociatedDevice(device); - if (mResource == nullptr) - { - mResource = CompileGS(device, mByteCode, mByteCodeSize, mName); - } - return mResource; -} - -template <> -inline ID3D11PixelShader *LazyShader::resolve(ID3D11Device *device) -{ - checkAssociatedDevice(device); - if (mResource == nullptr) - { - mResource = CompilePS(device, mByteCode, mByteCodeSize, mName); - } - return mResource; -} - -class LazyInputLayout final : public LazyResource +class LazyInputLayout final : public LazyResource { public: LazyInputLayout(const D3D11_INPUT_ELEMENT_DESC *inputDesc, @@ -305,22 +247,22 @@ class LazyInputLayout final : public LazyResource const BYTE *byteCode, size_t byteCodeLen, const char *debugName); + ~LazyInputLayout() override; - ID3D11InputLayout *resolve(ID3D11Device *device) override; + gl::Error resolve(Renderer11 *renderer) override; private: - std::vector mInputDesc; - size_t mByteCodeLen; - const BYTE *mByteCode; + InputElementArray mInputDesc; + ShaderData mByteCode; const char *mDebugName; }; -class LazyBlendState final : public LazyResource +class LazyBlendState final : public LazyResource { public: LazyBlendState(const D3D11_BLEND_DESC &desc, const char *debugName); - ID3D11BlendState *resolve(ID3D11Device *device) override; + gl::Error resolve(Renderer11 *renderer) override; private: D3D11_BLEND_DESC mDesc; @@ -342,48 +284,147 @@ void SetBufferData(ID3D11DeviceContext *context, ID3D11Buffer *constantBuffer, c } } -WorkaroundsD3D GenerateWorkarounds(D3D_FEATURE_LEVEL featureLevel); +angle::WorkaroundsD3D GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps, + const DXGI_ADAPTER_DESC &adapterDesc); + +enum ReservedConstantBufferSlot +{ + RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK = 0, + RESERVED_CONSTANT_BUFFER_SLOT_DRIVER = 1, + + RESERVED_CONSTANT_BUFFER_SLOT_COUNT = 2 +}; + +void InitConstantBufferDesc(D3D11_BUFFER_DESC *constantBufferDescription, size_t byteWidth); } // namespace d3d11 +struct GenericData +{ + GenericData() {} + ~GenericData() + { + if (object) + { + // We can have a nullptr factory when holding passed-in resources. + if (manager) + { + manager->onReleaseGeneric(resourceType, object); + manager = nullptr; + } + object->Release(); + object = nullptr; + } + } + + ResourceType resourceType = ResourceType::Last; + ID3D11Resource *object = nullptr; + ResourceManager11 *manager = nullptr; +}; + // A helper class which wraps a 2D or 3D texture. -class TextureHelper11 : angle::NonCopyable +class TextureHelper11 : public Resource11Base { public: TextureHelper11(); - TextureHelper11(TextureHelper11 &&toCopy); - ~TextureHelper11(); - TextureHelper11 &operator=(TextureHelper11 &&texture); + TextureHelper11(TextureHelper11 &&other); + TextureHelper11(const TextureHelper11 &other); + ~TextureHelper11() override; + TextureHelper11 &operator=(TextureHelper11 &&other); + TextureHelper11 &operator=(const TextureHelper11 &other); - static TextureHelper11 MakeAndReference(ID3D11Resource *genericResource); - static TextureHelper11 MakeAndPossess2D(ID3D11Texture2D *texToOwn); - static TextureHelper11 MakeAndPossess3D(ID3D11Texture3D *texToOwn); - - GLenum getTextureType() const { return mTextureType; } + bool is2D() const { return mData->resourceType == ResourceType::Texture2D; } + bool is3D() const { return mData->resourceType == ResourceType::Texture3D; } + ResourceType getTextureType() const { return mData->resourceType; } gl::Extents getExtents() const { return mExtents; } - DXGI_FORMAT getFormat() const { return mFormat; } + DXGI_FORMAT getFormat() const { return mFormatSet->texFormat; } + const d3d11::Format &getFormatSet() const { return *mFormatSet; } int getSampleCount() const { return mSampleCount; } - ID3D11Texture2D *getTexture2D() const { return mTexture2D; } - ID3D11Texture3D *getTexture3D() const { return mTexture3D; } - ID3D11Resource *getResource() const; + + template + void init(Resource11 &&texture, const DescT &desc, const d3d11::Format &format) + { + std::swap(mData->manager, texture.mData->manager); + + // Can't use std::swap because texture is typed, and here we use ID3D11Resource. + ID3D11Resource *temp = mData->object; + mData->object = texture.mData->object; + texture.mData->object = static_cast(temp); + + mFormatSet = &format; + initDesc(desc); + } + + template + void set(ResourceT *object, const d3d11::Format &format) + { + ASSERT(!valid()); + mFormatSet = &format; + mData->object = object; + mData->manager = nullptr; + + GetDescFromD3D11 desc; + getDesc(&desc); + initDesc(desc); + } + + bool operator==(const TextureHelper11 &other) const; + bool operator!=(const TextureHelper11 &other) const; + + void getDesc(D3D11_TEXTURE2D_DESC *desc) const; + void getDesc(D3D11_TEXTURE3D_DESC *desc) const; private: - void reset(); - void initDesc(); + void initDesc(const D3D11_TEXTURE2D_DESC &desc2D); + void initDesc(const D3D11_TEXTURE3D_DESC &desc3D); - GLenum mTextureType; + const d3d11::Format *mFormatSet; gl::Extents mExtents; - DXGI_FORMAT mFormat; int mSampleCount; - ID3D11Texture2D *mTexture2D; - ID3D11Texture3D *mTexture3D; }; -gl::ErrorOrResult CreateStagingTexture(GLenum textureType, - DXGI_FORMAT dxgiFormat, - const gl::Extents &size, - ID3D11Device *device); +enum class StagingAccess +{ + READ, + READ_WRITE, +}; bool UsePresentPathFast(const Renderer11 *renderer, const gl::FramebufferAttachment *colorbuffer); +bool UsePrimitiveRestartWorkaround(bool primitiveRestartFixedIndexEnabled, GLenum type); +bool IsStreamingIndexData(const gl::Context *context, GLenum srcType); + +enum class IndexStorageType +{ + // Dynamic indexes are re-streamed every frame. They come from a client data pointer or + // from buffers that are updated frequently. + Dynamic, + + // Static indexes are translated from the original storage once, and re-used multiple times. + Static, + + // Direct indexes are never transated and are used directly from the source buffer. They are + // the fastest available path. + Direct, + + // Not a real storage type. + Invalid, +}; + +IndexStorageType ClassifyIndexStorage(const gl::State &glState, + const gl::Buffer *elementArrayBuffer, + GLenum elementType, + GLenum destElementType, + unsigned int offset, + bool *needsTranslation); + +// Used for state change notifications between buffers and vertex arrays. +using OnBufferDataDirtyBinding = angle::ChannelBinding; +using OnBufferDataDirtyChannel = angle::BroadcastChannel; +using OnBufferDataDirtyReceiver = angle::SignalReceiver; + +// Used for state change notifications between RenderTarget11 and Framebuffer11. +using OnRenderTargetDirtyBinding = angle::ChannelBinding; +using OnRenderTargetDirtyChannel = angle::BroadcastChannel; +using OnRenderTargetDirtyReceiver = angle::SignalReceiver; } // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Clear11.hlsl b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Clear11.hlsl index 2b3e1ebe4c..48f5b427ec 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Clear11.hlsl +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Clear11.hlsl @@ -1,13 +1,175 @@ -// Assume we are in SM4+, which has 8 color outputs +// +// Copyright (c) 2017 The ANGLE Project. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// -void VS_ClearFloat( in float3 inPosition : POSITION, in float4 inColor : COLOR, - out float4 outPosition : SV_POSITION, out float4 outColor : COLOR) +// Clear11.hlsl: Shaders for clearing RTVs and DSVs using draw calls and +// specifying float depth values and either float, uint or sint clear colors. +// Notes: +// - UINT & SINT clears can only be compiled with FL10+ +// - VS_Clear_FL9 requires a VB to be bound with vertices to create +// a primitive covering the entire surface (in clip co-ordinates) + +// Constants +static const float2 g_Corners[6] = { - outPosition = float4(inPosition, 1.0f); - outColor = inColor; + float2(-1.0f, 1.0f), + float2( 1.0f, -1.0f), + float2(-1.0f, -1.0f), + float2(-1.0f, 1.0f), + float2( 1.0f, 1.0f), + float2( 1.0f, -1.0f), +}; + +// Vertex Shaders +void VS_Clear(in uint id : SV_VertexID, + out float4 outPosition : SV_POSITION) +{ + float2 corner = g_Corners[id]; + outPosition = float4(corner.x, corner.y, 0.0f, 1.0f); } -struct PS_OutputFloat +void VS_Multiview_Clear(in uint id : SV_VertexID, + in uint instanceID : SV_InstanceID, + out float4 outPosition : SV_POSITION, + out uint outLayerID : TEXCOORD0) +{ + float2 corner = g_Corners[id]; + outPosition = float4(corner.x, corner.y, 0.0f, 1.0f); + outLayerID = instanceID; +} + +void VS_Clear_FL9( in float4 inPosition : POSITION, + out float4 outPosition : SV_POSITION) +{ + outPosition = inPosition; +} + +// Geometry shader for clearing multiview layered textures +struct GS_INPUT +{ + float4 inPosition : SV_Position; + uint inLayerID : TEXCOORD0; +}; + +struct GS_OUTPUT +{ + float4 outPosition : SV_Position; + uint outLayerID : SV_RenderTargetArrayIndex; +}; + +[maxvertexcount(3)] +void GS_Multiview_Clear(triangle GS_INPUT input[3], inout TriangleStream outStream) +{ + GS_OUTPUT output = (GS_OUTPUT)0; + for (int i = 0; i < 3; i++) + { + output.outPosition = input[i].inPosition; + output.outLayerID = input[i].inLayerID; + outStream.Append(output); + } + outStream.RestartStrip(); +} + +// Pixel Shader Constant Buffers +cbuffer ColorAndDepthDataFloat : register(b0) +{ + float4 color_Float : packoffset(c0); + float zValueF_Float : packoffset(c1); +} + +cbuffer ColorAndDepthDataSint : register(b0) +{ + int4 color_Sint : packoffset(c0); + float zValueF_Sint : packoffset(c1); +} + +cbuffer ColorAndDepthDataUint : register(b0) +{ + uint4 color_Uint : packoffset(c0); + float zValueF_Uint : packoffset(c1); +} + +cbuffer DepthOnlyData : register(b0) +{ + float zValue_Depth : packoffset(c1); +} + +// Pixel Shader Output Structs +struct PS_OutputFloat_FL9 +{ + float4 color0 : SV_TARGET0; + float4 color1 : SV_TARGET1; + float4 color2 : SV_TARGET2; + float4 color3 : SV_TARGET3; + float depth : SV_DEPTH; +}; + +struct PS_OutputFloat1 +{ + float4 color0 : SV_TARGET0; + float depth : SV_DEPTH; +}; + +struct PS_OutputFloat2 +{ + float4 color0 : SV_TARGET0; + float4 color1 : SV_TARGET1; + float depth : SV_DEPTH; +}; + +struct PS_OutputFloat3 +{ + float4 color0 : SV_TARGET0; + float4 color1 : SV_TARGET1; + float4 color2 : SV_TARGET2; + float depth : SV_DEPTH; +}; + +struct PS_OutputFloat4 +{ + float4 color0 : SV_TARGET0; + float4 color1 : SV_TARGET1; + float4 color2 : SV_TARGET2; + float4 color3 : SV_TARGET3; + float depth : SV_DEPTH; +}; + +struct PS_OutputFloat5 +{ + float4 color0 : SV_TARGET0; + float4 color1 : SV_TARGET1; + float4 color2 : SV_TARGET2; + float4 color3 : SV_TARGET3; + float4 color4 : SV_TARGET4; + float depth : SV_DEPTH; +}; + +struct PS_OutputFloat6 +{ + float4 color0 : SV_TARGET0; + float4 color1 : SV_TARGET1; + float4 color2 : SV_TARGET2; + float4 color3 : SV_TARGET3; + float4 color4 : SV_TARGET4; + float4 color5 : SV_TARGET5; + float depth : SV_DEPTH; +}; + +struct PS_OutputFloat7 +{ + float4 color0 : SV_TARGET0; + float4 color1 : SV_TARGET1; + float4 color2 : SV_TARGET2; + float4 color3 : SV_TARGET3; + float4 color4 : SV_TARGET4; + float4 color5 : SV_TARGET5; + float4 color6 : SV_TARGET6; + float depth : SV_DEPTH; +}; + +struct PS_OutputFloat8 { float4 color0 : SV_TARGET0; float4 color1 : SV_TARGET1; @@ -17,48 +179,73 @@ struct PS_OutputFloat float4 color5 : SV_TARGET5; float4 color6 : SV_TARGET6; float4 color7 : SV_TARGET7; + float depth : SV_DEPTH; }; -PS_OutputFloat PS_ClearFloat(in float4 inPosition : SV_POSITION, in float4 inColor : COLOR) +struct PS_OutputUint1 { - PS_OutputFloat outColor; - outColor.color0 = inColor; - outColor.color1 = inColor; - outColor.color2 = inColor; - outColor.color3 = inColor; - outColor.color4 = inColor; - outColor.color5 = inColor; - outColor.color6 = inColor; - outColor.color7 = inColor; - return outColor; -} - -struct PS_OutputFloat_FL9 -{ - float4 color0 : SV_TARGET0; - float4 color1 : SV_TARGET1; - float4 color2 : SV_TARGET2; - float4 color3 : SV_TARGET3; + uint4 color0 : SV_TARGET0; + float depth : SV_DEPTH; }; -PS_OutputFloat_FL9 PS_ClearFloat_FL9(in float4 inPosition : SV_POSITION, in float4 inColor : COLOR) +struct PS_OutputUint2 { - PS_OutputFloat_FL9 outColor; - outColor.color0 = inColor; - outColor.color1 = inColor; - outColor.color2 = inColor; - outColor.color3 = inColor; - return outColor; -} + uint4 color0 : SV_TARGET0; + uint4 color1 : SV_TARGET1; + float depth : SV_DEPTH; +}; -void VS_ClearUint( in float3 inPosition : POSITION, in uint4 inColor : COLOR, - out float4 outPosition : SV_POSITION, out uint4 outColor : COLOR) +struct PS_OutputUint3 { - outPosition = float4(inPosition, 1.0f); - outColor = inColor; -} + uint4 color0 : SV_TARGET0; + uint4 color1 : SV_TARGET1; + uint4 color2 : SV_TARGET2; + float depth : SV_DEPTH; +}; -struct PS_OutputUint +struct PS_OutputUint4 +{ + uint4 color0 : SV_TARGET0; + uint4 color1 : SV_TARGET1; + uint4 color2 : SV_TARGET2; + uint4 color3 : SV_TARGET3; + float depth : SV_DEPTH; +}; + +struct PS_OutputUint5 +{ + uint4 color0 : SV_TARGET0; + uint4 color1 : SV_TARGET1; + uint4 color2 : SV_TARGET2; + uint4 color3 : SV_TARGET3; + uint4 color4 : SV_TARGET4; + float depth : SV_DEPTH; +}; + +struct PS_OutputUint6 +{ + uint4 color0 : SV_TARGET0; + uint4 color1 : SV_TARGET1; + uint4 color2 : SV_TARGET2; + uint4 color3 : SV_TARGET3; + uint4 color4 : SV_TARGET4; + uint4 color5 : SV_TARGET5; + float depth : SV_DEPTH; +}; + +struct PS_OutputUint7 +{ + uint4 color0 : SV_TARGET0; + uint4 color1 : SV_TARGET1; + uint4 color2 : SV_TARGET2; + uint4 color3 : SV_TARGET3; + uint4 color4 : SV_TARGET4; + uint4 color5 : SV_TARGET5; + uint4 color6 : SV_TARGET6; + float depth : SV_DEPTH; +}; + +struct PS_OutputUint8 { uint4 color0 : SV_TARGET0; uint4 color1 : SV_TARGET1; @@ -68,31 +255,73 @@ struct PS_OutputUint uint4 color5 : SV_TARGET5; uint4 color6 : SV_TARGET6; uint4 color7 : SV_TARGET7; + float depth : SV_DEPTH; }; -PS_OutputUint PS_ClearUint(in float4 inPosition : SV_POSITION, in uint4 inColor : COLOR) +struct PS_OutputSint1 { - PS_OutputUint outColor; - outColor.color0 = inColor; - outColor.color1 = inColor; - outColor.color2 = inColor; - outColor.color3 = inColor; - outColor.color4 = inColor; - outColor.color5 = inColor; - outColor.color6 = inColor; - outColor.color7 = inColor; - return outColor; -} + int4 color0 : SV_TARGET0; + float depth : SV_DEPTH; +}; - -void VS_ClearSint( in float3 inPosition : POSITION, in int4 inColor : COLOR, - out float4 outPosition : SV_POSITION, out int4 outColor : COLOR) +struct PS_OutputSint2 { - outPosition = float4(inPosition, 1.0f); - outColor = inColor; -} + int4 color0 : SV_TARGET0; + int4 color1 : SV_TARGET1; + float depth : SV_DEPTH; +}; -struct PS_OutputSint +struct PS_OutputSint3 +{ + int4 color0 : SV_TARGET0; + int4 color1 : SV_TARGET1; + int4 color2 : SV_TARGET2; + float depth : SV_DEPTH; +}; + +struct PS_OutputSint4 +{ + int4 color0 : SV_TARGET0; + int4 color1 : SV_TARGET1; + int4 color2 : SV_TARGET2; + int4 color3 : SV_TARGET3; + float depth : SV_DEPTH; +}; + +struct PS_OutputSint5 +{ + int4 color0 : SV_TARGET0; + int4 color1 : SV_TARGET1; + int4 color2 : SV_TARGET2; + int4 color3 : SV_TARGET3; + int4 color4 : SV_TARGET4; + float depth : SV_DEPTH; +}; + +struct PS_OutputSint6 +{ + int4 color0 : SV_TARGET0; + int4 color1 : SV_TARGET1; + int4 color2 : SV_TARGET2; + int4 color3 : SV_TARGET3; + int4 color4 : SV_TARGET4; + int4 color5 : SV_TARGET5; + float depth : SV_DEPTH; +}; + +struct PS_OutputSint7 +{ + int4 color0 : SV_TARGET0; + int4 color1 : SV_TARGET1; + int4 color2 : SV_TARGET2; + int4 color3 : SV_TARGET3; + int4 color4 : SV_TARGET4; + int4 color5 : SV_TARGET5; + int4 color6 : SV_TARGET6; + float depth : SV_DEPTH; +}; + +struct PS_OutputSint8 { int4 color0 : SV_TARGET0; int4 color1 : SV_TARGET1; @@ -102,18 +331,305 @@ struct PS_OutputSint int4 color5 : SV_TARGET5; int4 color6 : SV_TARGET6; int4 color7 : SV_TARGET7; + float depth : SV_DEPTH; }; -PS_OutputSint PS_ClearSint(in float4 inPosition : SV_POSITION, in int4 inColor : COLOR) +struct PS_OutputDepth { - PS_OutputSint outColor; - outColor.color0 = inColor; - outColor.color1 = inColor; - outColor.color2 = inColor; - outColor.color3 = inColor; - outColor.color4 = inColor; - outColor.color5 = inColor; - outColor.color6 = inColor; - outColor.color7 = inColor; - return outColor; + float depth : SV_DEPTH; +}; + +// Pixel Shaders +PS_OutputFloat_FL9 PS_ClearFloat_FL9(in float4 inPosition : SV_POSITION) +{ + PS_OutputFloat_FL9 outData; + outData.color0 = color_Float; + outData.color1 = color_Float; + outData.color2 = color_Float; + outData.color3 = color_Float; + outData.depth = zValueF_Float; + return outData; +} + +PS_OutputFloat1 PS_ClearFloat1(in float4 inPosition : SV_POSITION) +{ + PS_OutputFloat1 outData; + outData.color0 = color_Float; + outData.depth = zValueF_Float; + return outData; +} + +PS_OutputFloat2 PS_ClearFloat2(in float4 inPosition : SV_POSITION) +{ + PS_OutputFloat2 outData; + outData.color0 = color_Float; + outData.color1 = color_Float; + outData.depth = zValueF_Float; + return outData; +} + +PS_OutputFloat3 PS_ClearFloat3(in float4 inPosition : SV_POSITION) +{ + PS_OutputFloat3 outData; + outData.color0 = color_Float; + outData.color1 = color_Float; + outData.color2 = color_Float; + outData.depth = zValueF_Float; + return outData; +} + +PS_OutputFloat4 PS_ClearFloat4(in float4 inPosition : SV_POSITION) +{ + PS_OutputFloat4 outData; + outData.color0 = color_Float; + outData.color1 = color_Float; + outData.color2 = color_Float; + outData.color3 = color_Float; + outData.depth = zValueF_Float; + return outData; +} + +PS_OutputFloat5 PS_ClearFloat5(in float4 inPosition : SV_POSITION) +{ + PS_OutputFloat5 outData; + outData.color0 = color_Float; + outData.color1 = color_Float; + outData.color2 = color_Float; + outData.color3 = color_Float; + outData.color4 = color_Float; + outData.depth = zValueF_Float; + return outData; +} + +PS_OutputFloat6 PS_ClearFloat6(in float4 inPosition : SV_POSITION) +{ + PS_OutputFloat6 outData; + outData.color0 = color_Float; + outData.color1 = color_Float; + outData.color2 = color_Float; + outData.color3 = color_Float; + outData.color4 = color_Float; + outData.color5 = color_Float; + outData.depth = zValueF_Float; + return outData; +} + +PS_OutputFloat7 PS_ClearFloat7(in float4 inPosition : SV_POSITION) +{ + PS_OutputFloat7 outData; + outData.color0 = color_Float; + outData.color1 = color_Float; + outData.color2 = color_Float; + outData.color3 = color_Float; + outData.color4 = color_Float; + outData.color5 = color_Float; + outData.color6 = color_Float; + outData.depth = zValueF_Float; + return outData; +} + +PS_OutputFloat8 PS_ClearFloat8(in float4 inPosition : SV_POSITION) +{ + PS_OutputFloat8 outData; + outData.color0 = color_Float; + outData.color1 = color_Float; + outData.color2 = color_Float; + outData.color3 = color_Float; + outData.color4 = color_Float; + outData.color5 = color_Float; + outData.color6 = color_Float; + outData.color7 = color_Float; + outData.depth = zValueF_Float; + return outData; +} + +PS_OutputUint1 PS_ClearUint1(in float4 inPosition : SV_POSITION) +{ + PS_OutputUint1 outData; + outData.color0 = color_Uint; + outData.depth = zValueF_Uint; + return outData; +} + +PS_OutputUint2 PS_ClearUint2(in float4 inPosition : SV_POSITION) +{ + PS_OutputUint2 outData; + outData.color0 = color_Uint; + outData.color1 = color_Uint; + outData.depth = zValueF_Uint; + return outData; +} + +PS_OutputUint3 PS_ClearUint3(in float4 inPosition : SV_POSITION) +{ + PS_OutputUint3 outData; + outData.color0 = color_Uint; + outData.color1 = color_Uint; + outData.color2 = color_Uint; + outData.depth = zValueF_Uint; + return outData; +} + +PS_OutputUint4 PS_ClearUint4(in float4 inPosition : SV_POSITION) +{ + PS_OutputUint4 outData; + outData.color0 = color_Uint; + outData.color1 = color_Uint; + outData.color2 = color_Uint; + outData.color3 = color_Uint; + outData.depth = zValueF_Uint; + return outData; +} + +PS_OutputUint5 PS_ClearUint5(in float4 inPosition : SV_POSITION) +{ + PS_OutputUint5 outData; + outData.color0 = color_Uint; + outData.color1 = color_Uint; + outData.color2 = color_Uint; + outData.color3 = color_Uint; + outData.color4 = color_Uint; + outData.depth = zValueF_Uint; + return outData; +} + +PS_OutputUint6 PS_ClearUint6(in float4 inPosition : SV_POSITION) +{ + PS_OutputUint6 outData; + outData.color0 = color_Uint; + outData.color1 = color_Uint; + outData.color2 = color_Uint; + outData.color3 = color_Uint; + outData.color4 = color_Uint; + outData.color5 = color_Uint; + outData.depth = zValueF_Uint; + return outData; +} + +PS_OutputUint7 PS_ClearUint7(in float4 inPosition : SV_POSITION) +{ + PS_OutputUint7 outData; + outData.color0 = color_Uint; + outData.color1 = color_Uint; + outData.color2 = color_Uint; + outData.color3 = color_Uint; + outData.color4 = color_Uint; + outData.color5 = color_Uint; + outData.color6 = color_Uint; + outData.depth = zValueF_Uint; + return outData; +} + +PS_OutputUint8 PS_ClearUint8(in float4 inPosition : SV_POSITION) +{ + PS_OutputUint8 outData; + outData.color0 = color_Uint; + outData.color1 = color_Uint; + outData.color2 = color_Uint; + outData.color3 = color_Uint; + outData.color4 = color_Uint; + outData.color5 = color_Uint; + outData.color6 = color_Uint; + outData.color7 = color_Uint; + outData.depth = zValueF_Uint; + return outData; +} + +PS_OutputSint1 PS_ClearSint1(in float4 inPosition : SV_POSITION) +{ + PS_OutputSint1 outData; + outData.color0 = color_Sint; + outData.depth = zValueF_Sint; + return outData; +} + +PS_OutputSint2 PS_ClearSint2(in float4 inPosition : SV_POSITION) +{ + PS_OutputSint2 outData; + outData.color0 = color_Sint; + outData.color1 = color_Sint; + outData.depth = zValueF_Sint; + return outData; +} + +PS_OutputSint3 PS_ClearSint3(in float4 inPosition : SV_POSITION) +{ + PS_OutputSint3 outData; + outData.color0 = color_Sint; + outData.color1 = color_Sint; + outData.color2 = color_Sint; + outData.depth = zValueF_Sint; + return outData; +} + +PS_OutputSint4 PS_ClearSint4(in float4 inPosition : SV_POSITION) +{ + PS_OutputSint4 outData; + outData.color0 = color_Sint; + outData.color1 = color_Sint; + outData.color2 = color_Sint; + outData.color3 = color_Sint; + outData.depth = zValueF_Sint; + return outData; +} + +PS_OutputSint5 PS_ClearSint5(in float4 inPosition : SV_POSITION) +{ + PS_OutputSint5 outData; + outData.color0 = color_Sint; + outData.color1 = color_Sint; + outData.color2 = color_Sint; + outData.color3 = color_Sint; + outData.color4 = color_Sint; + outData.depth = zValueF_Sint; + return outData; +} + +PS_OutputSint6 PS_ClearSint6(in float4 inPosition : SV_POSITION) +{ + PS_OutputSint6 outData; + outData.color0 = color_Sint; + outData.color1 = color_Sint; + outData.color2 = color_Sint; + outData.color3 = color_Sint; + outData.color4 = color_Sint; + outData.color5 = color_Sint; + outData.depth = zValueF_Sint; + return outData; +} + +PS_OutputSint7 PS_ClearSint7(in float4 inPosition : SV_POSITION) +{ + PS_OutputSint7 outData; + outData.color0 = color_Sint; + outData.color1 = color_Sint; + outData.color2 = color_Sint; + outData.color3 = color_Sint; + outData.color4 = color_Sint; + outData.color5 = color_Sint; + outData.color6 = color_Sint; + outData.depth = zValueF_Sint; + return outData; +} + +PS_OutputSint8 PS_ClearSint8(in float4 inPosition : SV_POSITION) +{ + PS_OutputSint8 outData; + outData.color0 = color_Sint; + outData.color1 = color_Sint; + outData.color2 = color_Sint; + outData.color3 = color_Sint; + outData.color4 = color_Sint; + outData.color5 = color_Sint; + outData.color6 = color_Sint; + outData.color7 = color_Sint; + outData.depth = zValueF_Sint; + return outData; +} + +PS_OutputDepth PS_ClearDepth(in float4 inPosition : SV_POSITION) +{ + PS_OutputDepth outData; + outData.depth = zValue_Depth; + return outData; } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/MultiplyAlpha.hlsl b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/MultiplyAlpha.hlsl new file mode 100644 index 0000000000..0d10b8eafa --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/MultiplyAlpha.hlsl @@ -0,0 +1,131 @@ +Texture2D TextureF : register(t0); +Texture2D TextureUI : register(t0); + +SamplerState Sampler : register(s0); + +// Notation: +// PM: premultiply, UM: unmulitply, PT: passthrough +// F: float, U: uint + +// Float to float LUMA +float4 PS_FtoF_PM_LUMA(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + float4 color = TextureF.Sample(Sampler, inTexCoord).rgba; + color.rgb = color.r * color.a; + color.a = 1.0f; + return color; +} +float4 PS_FtoF_UM_LUMA(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + float4 color = TextureF.Sample(Sampler, inTexCoord).rgba; + if (color.a > 0.0f) + { + color.rgb = color.r / color.a; + } + color.a = 1.0f; + return color; +} + +// Float to float LUMAALPHA +float4 PS_FtoF_PM_LUMAALPHA(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + float4 color = TextureF.Sample(Sampler, inTexCoord).rgba; + color.rgb = color.r * color.a; + return color; +} + +float4 PS_FtoF_UM_LUMAALPHA(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + float4 color = TextureF.Sample(Sampler, inTexCoord).rgba; + if (color.a > 0.0f) + { + color.rgb = color.r / color.a; + } + return color; +} + +// Float to float RGBA +float4 PS_FtoF_PM_RGBA(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + float4 color = TextureF.Sample(Sampler, inTexCoord).rgba; + color.rgb *= color.a; + return color; +} + +float4 PS_FtoF_UM_RGBA(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + float4 color = TextureF.Sample(Sampler, inTexCoord).rgba; + if (color.a > 0.0f) + { + color.rgb /= color.a; + } + return color; +} + +// Float to float RGB +float4 PS_FtoF_PM_RGB(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + float4 color = TextureF.Sample(Sampler, inTexCoord).rgba; + color.rgb *= color.a; + color.a = 1.0f; + return color; +} + +float4 PS_FtoF_UM_RGB(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + float4 color = TextureF.Sample(Sampler, inTexCoord).rgba; + if (color.a > 0.0f) + { + color.rgb /= color.a; + } + color.a = 1.0f; + return color; +} + +// Float to uint RGBA +uint4 PS_FtoU_PT_RGBA(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + float4 color = TextureF.Sample(Sampler, inTexCoord).rgba; + return uint4(color * 255); +} + +uint4 PS_FtoU_PM_RGBA(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + float4 color = TextureF.Sample(Sampler, inTexCoord).rgba; + color.rgb *= color.a; + return uint4(color * 255); +} + +uint4 PS_FtoU_UM_RGBA(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + float4 color = TextureF.Sample(Sampler, inTexCoord).rgba; + if (color.a > 0.0f) + { + color.rgb /= color.a; + } + return uint4(color * 255); +} + +// Float to uint RGB +uint4 PS_FtoU_PT_RGB(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + float4 color = TextureF.Sample(Sampler, inTexCoord).rgba; + return uint4(color.rgb * 255, 1); +} + +uint4 PS_FtoU_PM_RGB(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + float4 color = TextureF.Sample(Sampler, inTexCoord).rgba; + color.rgb *= color.a; + return uint4(color.rgb * 255, 1); +} + +uint4 PS_FtoU_UM_RGB(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + float4 color = TextureF.Sample(Sampler, inTexCoord).rgba; + if (color.a > 0.0f) + { + color.rgb /= color.a; + } + return uint4(color.rgb * 255, 1); +} diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Passthrough2D11.hlsl b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Passthrough2D11.hlsl index 8671c39fb7..0b1a5ad169 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Passthrough2D11.hlsl +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/Passthrough2D11.hlsl @@ -1,4 +1,5 @@ Texture2D TextureF : register(t0); +Texture2DMS TextureF_MS: register(t0); Texture2D TextureUI : register(t0); Texture2D TextureI : register(t0); @@ -21,6 +22,16 @@ float4 PS_PassthroughRGBA2D(in float4 inPosition : SV_POSITION, in float2 inTexC return TextureF.Sample(Sampler, inTexCoord).rgba; } +float4 PS_PassthroughA2D(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + return float4(0.0f, 0.0f, 0.0f, TextureF.Sample(Sampler, inTexCoord).a); +} + +float4 PS_PassthroughRGBA2DMS(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCORD0, in uint inSampleIndex : SV_SAMPLEINDEX) : SV_TARGET0 +{ + return TextureF_MS.sample[inSampleIndex][inTexCoord].rgba; +} + uint4 PS_PassthroughRGBA2DUI(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 { uint2 size; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/ResolveDepthStencil.hlsl b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/ResolveDepthStencil.hlsl new file mode 100644 index 0000000000..7dc40d4b6a --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/ResolveDepthStencil.hlsl @@ -0,0 +1,56 @@ +static const float2 g_Corners[6] = +{ + float2(-1.0f, 1.0f), + float2( 1.0f, -1.0f), + float2(-1.0f, -1.0f), + float2(-1.0f, 1.0f), + float2( 1.0f, 1.0f), + float2( 1.0f, -1.0f), +}; + +void VS_ResolveDepthStencil(in uint id : SV_VertexID, + out float4 position : SV_Position, + out float2 texCoord : TEXCOORD0) +{ + float2 corner = g_Corners[id]; + position = float4(corner.x, corner.y, 0.0f, 1.0f); + texCoord = float2((corner.x + 1.0f) * 0.5f, (-corner.y + 1.0f) * 0.5f); +} + +Texture2DMS Depth : register(t0); +Texture2DMS Stencil : register(t1); + +void PS_ResolveDepth(in float4 position : SV_Position, + in float2 texCoord : TEXCOORD0, + out float depth : SV_Depth) +{ + // MS samplers must use Load + uint width, height, samples; + Depth.GetDimensions(width, height, samples); + uint2 coord = uint2(texCoord.x * float(width), texCoord.y * float(height)); + depth = Depth.Load(coord, 0).r; +} + +void PS_ResolveDepthStencil(in float4 position : SV_Position, + in float2 texCoord : TEXCOORD0, + out float2 depthStencil : SV_Target0) +{ + // MS samplers must use Load + uint width, height, samples; + Depth.GetDimensions(width, height, samples); + uint2 coord = uint2(texCoord.x * float(width), texCoord.y * float(height)); + depthStencil.r = Depth.Load(coord, 0).r; + depthStencil.g = float(Stencil.Load(coord, 0).g); +} + +void PS_ResolveStencil(in float4 position : SV_Position, + in float2 texCoord : TEXCOORD0, + out float2 stencil : SV_Target0) +{ + // MS samplers must use Load + uint width, height, samples; + Stencil.GetDimensions(width, height, samples); + uint2 coord = uint2(texCoord.x * float(width), texCoord.y * float(height)); + stencil.r = 0.0f; + stencil.g = float(Stencil.Load(coord, 0).g); +} diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dms11ps.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dms11ps.h new file mode 100644 index 0000000000..a5cccdc98e --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dms11ps.h @@ -0,0 +1,155 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 10.1 +// +// +// Resource Bindings: +// +// Name Type Format Dim HLSL Bind Count +// ------------------------------ ---------- ------- ----------- -------------- ------ +// TextureF_MS texture float4 2dMS t0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_POSITION 0 xyzw 0 POS float +// TEXCORD 0 xy 1 NONE float xy +// SV_SAMPLEINDEX 0 x 2 SAMPLE uint x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_TARGET 0 xyzw 0 TARGET float xyzw +// +// Pixel Shader runs at sample frequency +// +ps_4_1 +dcl_globalFlags refactoringAllowed +dcl_resource_texture2dms(0) (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_input_ps_sgv constant v2.x, sampleIndex +dcl_output o0.xyzw +dcl_temps 1 +ftou r0.xy, v1.xyxx +mov r0.zw, l(0,0,0,0) +ldms o0.xyzw, r0.xyzw, t0.xyzw, v2.x +ret +// Approximately 4 instruction slots used +#endif + +const BYTE g_PS_PassthroughRGBA2DMS[] = +{ + 68, 88, 66, 67, 206, 115, + 73, 27, 160, 237, 59, 223, + 179, 180, 28, 146, 74, 174, + 29, 197, 1, 0, 0, 0, + 136, 2, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, + 172, 0, 0, 0, 40, 1, + 0, 0, 92, 1, 0, 0, + 12, 2, 0, 0, 82, 68, + 69, 70, 112, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 28, 0, 0, 0, 1, 4, + 255, 255, 0, 1, 0, 0, + 72, 0, 0, 0, 60, 0, + 0, 0, 2, 0, 0, 0, + 5, 0, 0, 0, 6, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 13, 0, 0, 0, + 84, 101, 120, 116, 117, 114, + 101, 70, 95, 77, 83, 0, + 77, 105, 99, 114, 111, 115, + 111, 102, 116, 32, 40, 82, + 41, 32, 72, 76, 83, 76, + 32, 83, 104, 97, 100, 101, + 114, 32, 67, 111, 109, 112, + 105, 108, 101, 114, 32, 49, + 48, 46, 49, 0, 73, 83, + 71, 78, 116, 0, 0, 0, + 3, 0, 0, 0, 8, 0, + 0, 0, 80, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 92, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 1, 0, 0, 0, 3, 3, + 0, 0, 100, 0, 0, 0, + 0, 0, 0, 0, 10, 0, + 0, 0, 1, 0, 0, 0, + 2, 0, 0, 0, 1, 1, + 0, 0, 83, 86, 95, 80, + 79, 83, 73, 84, 73, 79, + 78, 0, 84, 69, 88, 67, + 79, 82, 68, 0, 83, 86, + 95, 83, 65, 77, 80, 76, + 69, 73, 78, 68, 69, 88, + 0, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 65, 82, + 71, 69, 84, 0, 171, 171, + 83, 72, 68, 82, 168, 0, + 0, 0, 65, 0, 0, 0, + 42, 0, 0, 0, 106, 8, + 0, 1, 88, 32, 0, 4, + 0, 112, 16, 0, 0, 0, + 0, 0, 85, 85, 0, 0, + 98, 16, 0, 3, 50, 16, + 16, 0, 1, 0, 0, 0, + 99, 8, 0, 4, 18, 16, + 16, 0, 2, 0, 0, 0, + 10, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 0, 0, 0, 0, 104, 0, + 0, 2, 1, 0, 0, 0, + 28, 0, 0, 5, 50, 0, + 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 1, 0, + 0, 0, 54, 0, 0, 8, + 194, 0, 16, 0, 0, 0, + 0, 0, 2, 64, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 46, 0, + 0, 9, 242, 32, 16, 0, + 0, 0, 0, 0, 70, 14, + 16, 0, 0, 0, 0, 0, + 70, 126, 16, 0, 0, 0, + 0, 0, 10, 16, 16, 0, + 2, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, + 116, 0, 0, 0, 4, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0 +}; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_data.json b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_data.json deleted file mode 100644 index 3e9e6877d9..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_data.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "GL_UNSIGNED_NORMALIZED": { - "8": { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM" - }, - "16": { - "texFormat": "DXGI_FORMAT_R16G16B16A16_UNORM", - "srvFormat": "DXGI_FORMAT_R16G16B16A16_UNORM", - "rtvFormat": "DXGI_FORMAT_R16G16B16A16_UNORM" - }, - "24": { - "texFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", - "srvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", - "rtvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT" - }, - "32": { - "texFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", - "srvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", - "rtvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT" - } - }, - "GL_SIGNED_NORMALIZED": { - "8": { - "texFormat": "DXGI_FORMAT_R8G8B8A8_SNORM", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_SNORM", - "rtvFormat": "DXGI_FORMAT_R8G8B8A8_SNORM" - } - }, - "GL_FLOAT": { - "16": { - "texFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "srvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "rtvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT" - }, - "32": { - "texFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", - "srvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", - "rtvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT" - } - }, - "GL_UNSIGNED_INT": { - "8": { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UINT", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UINT", - "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UINT" - }, - "16": { - "texFormat": "DXGI_FORMAT_R16G16B16A16_UINT", - "srvFormat": "DXGI_FORMAT_R16G16B16A16_UINT", - "rtvFormat": "DXGI_FORMAT_R16G16B16A16_UINT" - }, - "32": { - "texFormat": "DXGI_FORMAT_R32G32B32A32_UINT", - "srvFormat": "DXGI_FORMAT_R32G32B32A32_UINT", - "rtvFormat": "DXGI_FORMAT_R32G32B32A32_UINT" - } - }, - "GL_INT": { - "8": { - "texFormat": "DXGI_FORMAT_R8G8B8A8_SINT", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_SINT", - "rtvFormat": "DXGI_FORMAT_R8G8B8A8_SINT" - }, - "16": { - "texFormat": "DXGI_FORMAT_R16G16B16A16_SINT", - "srvFormat": "DXGI_FORMAT_R16G16B16A16_SINT", - "rtvFormat": "DXGI_FORMAT_R16G16B16A16_SINT" - }, - "32": { - "texFormat": "DXGI_FORMAT_R32G32B32A32_SINT", - "srvFormat": "DXGI_FORMAT_R32G32B32A32_SINT", - "rtvFormat": "DXGI_FORMAT_R32G32B32A32_SINT" - } - } -} \ No newline at end of file diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_info.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_info.h deleted file mode 100644 index df9a30ff50..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_info.h +++ /dev/null @@ -1,51 +0,0 @@ -// -// Copyright 2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// swizzle_format_info: -// Provides information for swizzle format and a map from type->formatinfo -// - -#ifndef LIBANGLE_RENDERER_D3D_D3D11_SWIZZLEFORMATINFO_H_ -#define LIBANGLE_RENDERER_D3D_D3D11_SWIZZLEFORMATINFO_H_ - -#include -#include - -#include "common/platform.h" - -namespace rx -{ - -namespace d3d11 -{ - -struct SwizzleSizeType -{ - size_t maxComponentSize; - GLenum componentType; - - SwizzleSizeType(); - SwizzleSizeType(size_t maxComponentSize, GLenum componentType); - - bool operator<(const SwizzleSizeType &other) const; -}; - -struct SwizzleFormatInfo -{ - DXGI_FORMAT mTexFormat; - DXGI_FORMAT mSRVFormat; - DXGI_FORMAT mRTVFormat; - - SwizzleFormatInfo(); - SwizzleFormatInfo(DXGI_FORMAT texFormat, DXGI_FORMAT srvFormat, DXGI_FORMAT rtvFormat); -}; - -const SwizzleFormatInfo &GetSwizzleFormatInfo(GLuint maxBits, GLenum componentType); - -} // namespace d3d11 - -} // namespace rx - -#endif // LIBANGLE_RENDERER_D3D_D3D11_SWIZZLEFORMATINFO_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_info_autogen.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_info_autogen.cpp deleted file mode 100644 index 84d6fada97..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/swizzle_format_info_autogen.cpp +++ /dev/null @@ -1,203 +0,0 @@ -// GENERATED FILE - DO NOT EDIT -// Generated by gen_swizzle_format_table.py using data from swizzle_format_data.json -// -// Copyright 2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// swizzle_format_info: -// Provides information for swizzle format and a map from type->formatinfo -// - -#include "libANGLE/renderer/d3d/d3d11/swizzle_format_info.h" - -#include - -namespace rx -{ - -namespace d3d11 -{ - -SwizzleSizeType::SwizzleSizeType() : maxComponentSize(0), componentType(GL_NONE) -{ -} - -SwizzleSizeType::SwizzleSizeType(size_t maxComponentSize, GLenum componentType) - : maxComponentSize(maxComponentSize), componentType(componentType) -{ -} - -bool SwizzleSizeType::operator<(const SwizzleSizeType &other) const -{ - return (maxComponentSize != other.maxComponentSize) - ? (maxComponentSize < other.maxComponentSize) - : (componentType < other.componentType); -} - -SwizzleFormatInfo::SwizzleFormatInfo() - : mTexFormat(DXGI_FORMAT_UNKNOWN), - mSRVFormat(DXGI_FORMAT_UNKNOWN), - mRTVFormat(DXGI_FORMAT_UNKNOWN) -{ -} - -SwizzleFormatInfo::SwizzleFormatInfo(DXGI_FORMAT texFormat, - DXGI_FORMAT srvFormat, - DXGI_FORMAT rtvFormat) - : mTexFormat(texFormat), mSRVFormat(srvFormat), mRTVFormat(rtvFormat) -{ -} - -const SwizzleFormatInfo &GetSwizzleFormatInfo(GLuint maxBits, GLenum componentType) -{ - // clang-format off - switch (componentType) - { - case GL_FLOAT: - { - switch (maxBits) - { - case 16: - { - static const SwizzleFormatInfo formatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, - DXGI_FORMAT_R16G16B16A16_FLOAT, - DXGI_FORMAT_R16G16B16A16_FLOAT); - return formatInfo; - } - case 32: - { - static const SwizzleFormatInfo formatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_R32G32B32A32_FLOAT); - return formatInfo; - } - default: - break; - } - } - case GL_INT: - { - switch (maxBits) - { - case 16: - { - static const SwizzleFormatInfo formatInfo(DXGI_FORMAT_R16G16B16A16_SINT, - DXGI_FORMAT_R16G16B16A16_SINT, - DXGI_FORMAT_R16G16B16A16_SINT); - return formatInfo; - } - case 32: - { - static const SwizzleFormatInfo formatInfo(DXGI_FORMAT_R32G32B32A32_SINT, - DXGI_FORMAT_R32G32B32A32_SINT, - DXGI_FORMAT_R32G32B32A32_SINT); - return formatInfo; - } - case 8: - { - static const SwizzleFormatInfo formatInfo(DXGI_FORMAT_R8G8B8A8_SINT, - DXGI_FORMAT_R8G8B8A8_SINT, - DXGI_FORMAT_R8G8B8A8_SINT); - return formatInfo; - } - default: - break; - } - } - case GL_SIGNED_NORMALIZED: - { - switch (maxBits) - { - case 8: - { - static const SwizzleFormatInfo formatInfo(DXGI_FORMAT_R8G8B8A8_SNORM, - DXGI_FORMAT_R8G8B8A8_SNORM, - DXGI_FORMAT_R8G8B8A8_SNORM); - return formatInfo; - } - default: - break; - } - } - case GL_UNSIGNED_INT: - { - switch (maxBits) - { - case 16: - { - static const SwizzleFormatInfo formatInfo(DXGI_FORMAT_R16G16B16A16_UINT, - DXGI_FORMAT_R16G16B16A16_UINT, - DXGI_FORMAT_R16G16B16A16_UINT); - return formatInfo; - } - case 32: - { - static const SwizzleFormatInfo formatInfo(DXGI_FORMAT_R32G32B32A32_UINT, - DXGI_FORMAT_R32G32B32A32_UINT, - DXGI_FORMAT_R32G32B32A32_UINT); - return formatInfo; - } - case 8: - { - static const SwizzleFormatInfo formatInfo(DXGI_FORMAT_R8G8B8A8_UINT, - DXGI_FORMAT_R8G8B8A8_UINT, - DXGI_FORMAT_R8G8B8A8_UINT); - return formatInfo; - } - default: - break; - } - } - case GL_UNSIGNED_NORMALIZED: - { - switch (maxBits) - { - case 16: - { - static const SwizzleFormatInfo formatInfo(DXGI_FORMAT_R16G16B16A16_UNORM, - DXGI_FORMAT_R16G16B16A16_UNORM, - DXGI_FORMAT_R16G16B16A16_UNORM); - return formatInfo; - } - case 24: - { - static const SwizzleFormatInfo formatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_R32G32B32A32_FLOAT); - return formatInfo; - } - case 32: - { - static const SwizzleFormatInfo formatInfo(DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_R32G32B32A32_FLOAT); - return formatInfo; - } - case 8: - { - static const SwizzleFormatInfo formatInfo(DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM); - return formatInfo; - } - default: - break; - } - } - - default: - { - static const SwizzleFormatInfo defaultInfo(DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN); - return defaultInfo; - } - } - // clang-format on - -} // GetSwizzleFormatInfo - -} // namespace d3d11 - -} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_data.json b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_data.json index 87d303437f..61cd44a62b 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_data.json +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_data.json @@ -1,692 +1,523 @@ { - "GL_ALPHA": [ - { - "texFormat": "DXGI_FORMAT_A8_UNORM", - "srvFormat": "DXGI_FORMAT_A8_UNORM", - "rtvFormat": "DXGI_FORMAT_A8_UNORM", - "requirementsFcn": "OnlyFL10Plus" - }, - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requirementsFcn": "OnlyFL9_3" - } - ], - "GL_ALPHA16F_EXT": [ - { - "texFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "srvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "rtvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT" - } - ], - "GL_ALPHA32F_EXT": [ - { - "texFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", - "srvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", - "rtvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT" - } - ], - "GL_ALPHA8_EXT": [ - { - "texFormat": "DXGI_FORMAT_A8_UNORM", - "srvFormat": "DXGI_FORMAT_A8_UNORM", - "rtvFormat": "DXGI_FORMAT_A8_UNORM", - "requirementsFcn": "OnlyFL10Plus" - }, - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requirementsFcn": "OnlyFL9_3" - } - ], - "GL_BGR5_A1_ANGLEX": [ - { - "texFormat": "DXGI_FORMAT_B8G8R8A8_UNORM", - "srvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM", - "rtvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM" - } - ], - "GL_BGRA4_ANGLEX": [ - { - "texFormat": "DXGI_FORMAT_B8G8R8A8_UNORM", - "srvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM", - "rtvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM" - } - ], - "GL_BGRA8_EXT": [ - { - "texFormat": "DXGI_FORMAT_B8G8R8A8_UNORM", - "srvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM", - "rtvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM" - } - ], - "GL_BGRA_EXT": [ - { - "texFormat": "DXGI_FORMAT_B8G8R8A8_UNORM", - "srvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM", - "rtvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM" - } - ], - "GL_COMPRESSED_R11_EAC": [ - { - "texFormat": "DXGI_FORMAT_R8_UNORM", - "srvFormat": "DXGI_FORMAT_R8_UNORM", - "requirementsFcn": "OnlyFL10Plus" - } - ], - "GL_COMPRESSED_RG11_EAC": [ - { - "texFormat": "DXGI_FORMAT_R8G8_UNORM", - "srvFormat": "DXGI_FORMAT_R8G8_UNORM", - "requirementsFcn": "OnlyFL10Plus" - } - ], - "GL_COMPRESSED_RGB8_ETC2": [ - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requirementsFcn": "OnlyFL10Plus" - } - ], - "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2": [ - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requirementsFcn": "OnlyFL10Plus" - } - ], - "GL_COMPRESSED_RGBA8_ETC2_EAC": [ - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requirementsFcn": "OnlyFL10Plus" - } - ], - "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT": [ - { - "texFormat": "DXGI_FORMAT_BC1_UNORM", - "srvFormat": "DXGI_FORMAT_BC1_UNORM" - } - ], - "GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE": [ - { - "texFormat": "DXGI_FORMAT_BC2_UNORM", - "srvFormat": "DXGI_FORMAT_BC2_UNORM" - } - ], - "GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE": [ - { - "texFormat": "DXGI_FORMAT_BC3_UNORM", - "srvFormat": "DXGI_FORMAT_BC3_UNORM" - } - ], - "GL_COMPRESSED_RGB_S3TC_DXT1_EXT": [ - { - "texFormat": "DXGI_FORMAT_BC1_UNORM", - "srvFormat": "DXGI_FORMAT_BC1_UNORM" - } - ], - "GL_COMPRESSED_SIGNED_R11_EAC": [ - { - "texFormat": "DXGI_FORMAT_R8_SNORM", - "srvFormat": "DXGI_FORMAT_R8_SNORM", - "requirementsFcn": "OnlyFL10Plus" - } - ], - "GL_COMPRESSED_SIGNED_RG11_EAC": [ - { - "texFormat": "DXGI_FORMAT_R8G8_SNORM", - "srvFormat": "DXGI_FORMAT_R8G8_SNORM", - "requirementsFcn": "OnlyFL10Plus" - } - ], - "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC": [ - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", - "requirementsFcn": "OnlyFL10Plus" - } - ], - "GL_COMPRESSED_SRGB8_ETC2": [ - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", - "requirementsFcn": "OnlyFL10Plus" - } - ], - "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2": [ - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", - "requirementsFcn": "OnlyFL10Plus" - } - ], - "GL_DEPTH24_STENCIL8": [ - { + "NONE": { + }, + "A8_UNORM": { + "texFormat": "DXGI_FORMAT_A8_UNORM", + "srvFormat": "DXGI_FORMAT_A8_UNORM", + "rtvFormat": "DXGI_FORMAT_A8_UNORM", + "channels": "a", + "componentType": "unorm", + "bits": { "alpha": 8 }, + "supportTest": "OnlyFL10Plus(deviceCaps)", + "fallbackFormat": "R8G8B8A8_UNORM" + }, + "R8G8B8A8_UNORM": { + "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", + "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", + "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", + "channels": "rgba", + "componentType": "unorm", + "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 }, + "glInternalFormat": "GL_RGBA8" + }, + "R16G16B16A16_UNORM": { + "texFormat": "DXGI_FORMAT_R16G16B16A16_UNORM", + "srvFormat": "DXGI_FORMAT_R16G16B16A16_UNORM", + "rtvFormat": "DXGI_FORMAT_R16G16B16A16_UNORM", + "channels": "rgba", + "componentType": "unorm", + "bits": { "red": 16, "green": 16, "blue": 16, "alpha": 16 }, + "glInternalFormat": "GL_RGBA16_EXT" + }, + "R16G16B16A16_FLOAT": { + "texFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", + "srvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", + "rtvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", + "channels": "rgba", + "componentType": "float", + "bits": { "red": 16, "green": 16, "blue": 16, "alpha": 16 }, + "glInternalFormat": "GL_RGBA16F" + }, + "R32G32B32A32_FLOAT": { + "texFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", + "srvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", + "rtvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", + "channels": "rgba", + "componentType": "float", + "bits": { "red": 32, "green": 32, "blue": 32, "alpha": 32 }, + "glInternalFormat": "GL_RGBA32F" + }, + "B8G8R8A8_UNORM": { + "texFormat": "DXGI_FORMAT_B8G8R8A8_UNORM", + "srvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM", + "rtvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM", + "channels": "bgra", + "componentType": "unorm", + "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 }, + "glInternalFormat": "GL_BGRA8_EXT" + }, + "B8G8R8A8_UNORM_SRGB": { + "texFormat": "DXGI_FORMAT_B8G8R8A8_UNORM_SRGB", + "srvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM_SRGB", + "rtvFormat": "DXGI_FORMAT_B8G8R8A8_UNORM_SRGB", + "channels": "bgra", + "componentType": "unorm", + "bits": {"red": 8, "green": 8, "blue": 8,"alpha": 8}, + "siwzzleFormat": "GL_RGBA8" + }, + "BC1_RGBA_UNORM_BLOCK": { + "texFormat": "DXGI_FORMAT_BC1_UNORM", + "srvFormat": "DXGI_FORMAT_BC1_UNORM", + "channels": "rgba", + "componentType": "unorm", + "swizzleFormat": "GL_RGBA8" + }, + "BC1_RGB_UNORM_BLOCK": { + "texFormat": "DXGI_FORMAT_BC1_UNORM", + "srvFormat": "DXGI_FORMAT_BC1_UNORM", + "channels": "rgba", + "componentType": "unorm", + "swizzleFormat": "GL_RGBA8" + }, + "BC2_RGBA_UNORM_BLOCK": { + "texFormat": "DXGI_FORMAT_BC2_UNORM", + "srvFormat": "DXGI_FORMAT_BC2_UNORM", + "channels": "rgba", + "componentType": "unorm", + "swizzleFormat": "GL_RGBA8" + }, + "BC3_RGBA_UNORM_BLOCK": { + "texFormat": "DXGI_FORMAT_BC3_UNORM", + "srvFormat": "DXGI_FORMAT_BC3_UNORM", + "channels": "rgba", + "componentType": "unorm", + "swizzleFormat": "GL_RGBA8" + }, + "BC1_RGBA_UNORM_SRGB_BLOCK": { + "texFormat": "DXGI_FORMAT_BC1_UNORM_SRGB", + "srvFormat": "DXGI_FORMAT_BC1_UNORM_SRGB", + "channels": "rgba", + "componentType": "unorm", + "swizzleFormat": "GL_RGBA8" + }, + "BC1_RGB_UNORM_SRGB_BLOCK": { + "texFormat": "DXGI_FORMAT_BC1_UNORM_SRGB", + "srvFormat": "DXGI_FORMAT_BC1_UNORM_SRGB", + "channels": "rgba", + "componentType": "unorm", + "swizzleFormat": "GL_RGBA8" + }, + "BC2_RGBA_UNORM_SRGB_BLOCK": { + "texFormat": "DXGI_FORMAT_BC2_UNORM_SRGB", + "srvFormat": "DXGI_FORMAT_BC2_UNORM_SRGB", + "channels": "rgba", + "componentType": "unorm", + "swizzleFormat": "GL_RGBA8" + }, + "BC3_RGBA_UNORM_SRGB_BLOCK": { + "texFormat": "DXGI_FORMAT_BC3_UNORM_SRGB", + "srvFormat": "DXGI_FORMAT_BC3_UNORM_SRGB", + "channels": "rgba", + "componentType": "unorm", + "swizzleFormat": "GL_RGBA8" + }, + "D24_UNORM_S8_UINT": { + "FL10Plus": { "texFormat": "DXGI_FORMAT_R24G8_TYPELESS", - "srvFormat": "DXGI_FORMAT_R24_UNORM_X8_TYPELESS", - "dsvFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT", - "requirementsFcn": "OnlyFL10Plus" + "srvFormat": "DXGI_FORMAT_R24_UNORM_X8_TYPELESS" }, - { - "texFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT", - "dsvFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT", - "requirementsFcn": "OnlyFL9_3" - } - ], - "GL_DEPTH32F_STENCIL8": [ - { - "texFormat": "DXGI_FORMAT_R32G8X24_TYPELESS", - "srvFormat": "DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS", - "dsvFormat": "DXGI_FORMAT_D32_FLOAT_S8X24_UINT", - "requirementsFcn": "OnlyFL10Plus" + "FL9_3": { + "texFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT" }, - { - "requirementsFcn": "OnlyFL9_3" - } - ], - "GL_DEPTH_COMPONENT16": [ - { + "dsvFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT", + "channels": "ds", + "bits": { "depth": 24, "stencil": 8 }, + "glInternalFormat": "GL_DEPTH24_STENCIL8_OES" + }, + "D32_FLOAT_S8X24_UINT": { + "texFormat": "DXGI_FORMAT_R32G8X24_TYPELESS", + "srvFormat": "DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS", + "dsvFormat": "DXGI_FORMAT_D32_FLOAT_S8X24_UINT", + "channels": "ds", + "bits": { "depth": 32, "stencil": 8 }, + "glInternalFormat": "GL_DEPTH32F_STENCIL8" + }, + "D16_UNORM": { + "FL10Plus": { "texFormat": "DXGI_FORMAT_R16_TYPELESS", - "srvFormat": "DXGI_FORMAT_R16_UNORM", - "dsvFormat": "DXGI_FORMAT_D16_UNORM", - "requirementsFcn": "OnlyFL10Plus" + "srvFormat": "DXGI_FORMAT_R16_UNORM" }, - { - "texFormat": "DXGI_FORMAT_D16_UNORM", - "dsvFormat": "DXGI_FORMAT_D16_UNORM", - "requirementsFcn": "OnlyFL9_3" - } - ], - "GL_DEPTH_COMPONENT24": [ - { - "texFormat": "DXGI_FORMAT_R24G8_TYPELESS", - "srvFormat": "DXGI_FORMAT_R24_UNORM_X8_TYPELESS", - "dsvFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT", - "requirementsFcn": "OnlyFL10Plus" + "FL9_3": { + "texFormat": "DXGI_FORMAT_D16_UNORM" }, - { - "texFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT", - "dsvFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT", - "requirementsFcn": "OnlyFL9_3" - } - ], - "GL_DEPTH_COMPONENT32F": [ - { - "texFormat": "DXGI_FORMAT_R32_TYPELESS", - "srvFormat": "DXGI_FORMAT_R32_FLOAT", - "dsvFormat": "DXGI_FORMAT_D32_FLOAT", - "requirementsFcn": "OnlyFL10Plus" - }, - { - "requirementsFcn": "OnlyFL9_3" - } - ], - "GL_DEPTH_COMPONENT32_OES": [ - { - "texFormat": "DXGI_FORMAT_R24G8_TYPELESS", - "srvFormat": "DXGI_FORMAT_R24_UNORM_X8_TYPELESS", - "dsvFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT", - "requirementsFcn": "OnlyFL10Plus" - } - ], - "GL_ETC1_RGB8_OES": [ - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM" - } - ], - "GL_ETC1_RGB8_LOSSY_DECODE_ANGLE": [ - { - "texFormat": "DXGI_FORMAT_BC1_UNORM", - "srvFormat": "DXGI_FORMAT_BC1_UNORM" - } - ], - "GL_LUMINANCE": [ - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM" - } - ], - "GL_LUMINANCE16F_EXT": [ - { - "texFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "srvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "rtvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT" - } - ], - "GL_LUMINANCE32F_EXT": [ - { - "texFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", - "srvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", - "rtvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT" - } - ], - "GL_LUMINANCE8_ALPHA8_EXT": [ - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM" - } - ], - "GL_LUMINANCE8_EXT": [ - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM" - } - ], - "GL_LUMINANCE_ALPHA": [ - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM" - } - ], - "GL_LUMINANCE_ALPHA16F_EXT": [ - { - "texFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "srvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "rtvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT" - } - ], - "GL_LUMINANCE_ALPHA32F_EXT": [ - { - "texFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", - "srvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", - "rtvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT" - } - ], - "GL_NONE": [ - { - } - ], - "GL_R11F_G11F_B10F": [ - { - "texFormat": "DXGI_FORMAT_R11G11B10_FLOAT", - "srvFormat": "DXGI_FORMAT_R11G11B10_FLOAT", - "rtvFormat": "DXGI_FORMAT_R11G11B10_FLOAT" - } - ], - "GL_R16F": [ - { - "texFormat": "DXGI_FORMAT_R16_FLOAT", - "srvFormat": "DXGI_FORMAT_R16_FLOAT", - "rtvFormat": "DXGI_FORMAT_R16_FLOAT" - } - ], - "GL_R16I": [ - { - "texFormat": "DXGI_FORMAT_R16_SINT", - "srvFormat": "DXGI_FORMAT_R16_SINT", - "rtvFormat": "DXGI_FORMAT_R16_SINT" - } - ], - "GL_R16UI": [ - { - "texFormat": "DXGI_FORMAT_R16_UINT", - "srvFormat": "DXGI_FORMAT_R16_UINT", - "rtvFormat": "DXGI_FORMAT_R16_UINT" - } - ], - "GL_R32F": [ - { - "texFormat": "DXGI_FORMAT_R32_FLOAT", - "srvFormat": "DXGI_FORMAT_R32_FLOAT", - "rtvFormat": "DXGI_FORMAT_R32_FLOAT" - } - ], - "GL_R32I": [ - { - "texFormat": "DXGI_FORMAT_R32_SINT", - "srvFormat": "DXGI_FORMAT_R32_SINT", - "rtvFormat": "DXGI_FORMAT_R32_SINT" - } - ], - "GL_R32UI": [ - { - "texFormat": "DXGI_FORMAT_R32_UINT", - "srvFormat": "DXGI_FORMAT_R32_UINT", - "rtvFormat": "DXGI_FORMAT_R32_UINT" - } - ], - "GL_R8": [ - { - "texFormat": "DXGI_FORMAT_R8_UNORM", - "srvFormat": "DXGI_FORMAT_R8_UNORM", - "rtvFormat": "DXGI_FORMAT_R8_UNORM" - } - ], - "GL_R8I": [ - { - "texFormat": "DXGI_FORMAT_R8_SINT", - "srvFormat": "DXGI_FORMAT_R8_SINT", - "rtvFormat": "DXGI_FORMAT_R8_SINT" - } - ], - "GL_R8UI": [ - { - "texFormat": "DXGI_FORMAT_R8_UINT", - "srvFormat": "DXGI_FORMAT_R8_UINT", - "rtvFormat": "DXGI_FORMAT_R8_UINT" - } - ], - "GL_R8_SNORM": [ - { - "texFormat": "DXGI_FORMAT_R8_SNORM", - "srvFormat": "DXGI_FORMAT_R8_SNORM" - } - ], - "GL_RG16F": [ - { - "texFormat": "DXGI_FORMAT_R16G16_FLOAT", - "srvFormat": "DXGI_FORMAT_R16G16_FLOAT", - "rtvFormat": "DXGI_FORMAT_R16G16_FLOAT" - } - ], - "GL_RG16I": [ - { - "texFormat": "DXGI_FORMAT_R16G16_SINT", - "srvFormat": "DXGI_FORMAT_R16G16_SINT", - "rtvFormat": "DXGI_FORMAT_R16G16_SINT" - } - ], - "GL_RG16UI": [ - { - "texFormat": "DXGI_FORMAT_R16G16_UINT", - "srvFormat": "DXGI_FORMAT_R16G16_UINT", - "rtvFormat": "DXGI_FORMAT_R16G16_UINT" - } - ], - "GL_RG32F": [ - { - "texFormat": "DXGI_FORMAT_R32G32_FLOAT", - "srvFormat": "DXGI_FORMAT_R32G32_FLOAT", - "rtvFormat": "DXGI_FORMAT_R32G32_FLOAT" - } - ], - "GL_RG32I": [ - { - "texFormat": "DXGI_FORMAT_R32G32_SINT", - "srvFormat": "DXGI_FORMAT_R32G32_SINT", - "rtvFormat": "DXGI_FORMAT_R32G32_SINT" - } - ], - "GL_RG32UI": [ - { - "texFormat": "DXGI_FORMAT_R32G32_UINT", - "srvFormat": "DXGI_FORMAT_R32G32_UINT", - "rtvFormat": "DXGI_FORMAT_R32G32_UINT" - } - ], - "GL_RG8": [ - { - "texFormat": "DXGI_FORMAT_R8G8_UNORM", - "srvFormat": "DXGI_FORMAT_R8G8_UNORM", - "rtvFormat": "DXGI_FORMAT_R8G8_UNORM" - } - ], - "GL_RG8I": [ - { - "texFormat": "DXGI_FORMAT_R8G8_SINT", - "srvFormat": "DXGI_FORMAT_R8G8_SINT", - "rtvFormat": "DXGI_FORMAT_R8G8_SINT" - } - ], - "GL_RG8UI": [ - { - "texFormat": "DXGI_FORMAT_R8G8_UINT", - "srvFormat": "DXGI_FORMAT_R8G8_UINT", - "rtvFormat": "DXGI_FORMAT_R8G8_UINT" - } - ], - "GL_RG8_SNORM": [ - { - "texFormat": "DXGI_FORMAT_R8G8_SNORM", - "srvFormat": "DXGI_FORMAT_R8G8_SNORM" - } - ], - "GL_RGB": [ - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM" - } - ], - "GL_RGB10_A2": [ - { - "texFormat": "DXGI_FORMAT_R10G10B10A2_UNORM", - "srvFormat": "DXGI_FORMAT_R10G10B10A2_UNORM", - "rtvFormat": "DXGI_FORMAT_R10G10B10A2_UNORM" - } - ], - "GL_RGB10_A2UI": [ - { - "texFormat": "DXGI_FORMAT_R10G10B10A2_UINT", - "srvFormat": "DXGI_FORMAT_R10G10B10A2_UINT", - "rtvFormat": "DXGI_FORMAT_R10G10B10A2_UINT" - } - ], - "GL_RGB16F": [ - { - "texFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "srvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "rtvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT" - } - ], - "GL_RGB16I": [ - { - "texFormat": "DXGI_FORMAT_R16G16B16A16_SINT", - "srvFormat": "DXGI_FORMAT_R16G16B16A16_SINT", - "rtvFormat": "DXGI_FORMAT_R16G16B16A16_SINT" - } - ], - "GL_RGB16UI": [ - { - "texFormat": "DXGI_FORMAT_R16G16B16A16_UINT", - "srvFormat": "DXGI_FORMAT_R16G16B16A16_UINT", - "rtvFormat": "DXGI_FORMAT_R16G16B16A16_UINT" - } - ], - "GL_RGB32F": [ - { - "texFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", - "srvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", - "rtvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT" - } - ], - "GL_RGB32I": [ - { - "texFormat": "DXGI_FORMAT_R32G32B32A32_SINT", - "srvFormat": "DXGI_FORMAT_R32G32B32A32_SINT", - "rtvFormat": "DXGI_FORMAT_R32G32B32A32_SINT" - } - ], - "GL_RGB32UI": [ - { - "texFormat": "DXGI_FORMAT_R32G32B32A32_UINT", - "srvFormat": "DXGI_FORMAT_R32G32B32A32_UINT", - "rtvFormat": "DXGI_FORMAT_R32G32B32A32_UINT" - } - ], - "GL_RGB565": [ - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requirementsFcn": "SupportsFormat" - }, - { - "texFormat": "DXGI_FORMAT_B5G6R5_UNORM", - "srvFormat": "DXGI_FORMAT_B5G6R5_UNORM", - "rtvFormat": "DXGI_FORMAT_B5G6R5_UNORM", - "requirementsFcn": "SupportsFormat" - } - ], - "GL_RGB5_A1": [ - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requirementsFcn": "SupportsFormat" - }, - { - "texFormat": "DXGI_FORMAT_B5G5R5A1_UNORM", - "srvFormat": "DXGI_FORMAT_B5G5R5A1_UNORM", - "rtvFormat": "DXGI_FORMAT_B5G5R5A1_UNORM", - "requirementsFcn": "SupportsFormat" - } - ], - "GL_RGB8": [ - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM" - } - ], - "GL_RGB8I": [ - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_SINT", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_SINT", - "rtvFormat": "DXGI_FORMAT_R8G8B8A8_SINT" - } - ], - "GL_RGB8UI": [ - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UINT", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UINT", - "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UINT" - } - ], - "GL_RGB8_SNORM": [ - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_SNORM", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_SNORM" - } - ], - "GL_RGB9_E5": [ - { - "texFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP", - "srvFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP" - } - ], - "GL_RGBA": [ - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM" - } - ], - "GL_RGBA16F": [ - { - "texFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "srvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT", - "rtvFormat": "DXGI_FORMAT_R16G16B16A16_FLOAT" - } - ], - "GL_RGBA16I": [ - { - "texFormat": "DXGI_FORMAT_R16G16B16A16_SINT", - "srvFormat": "DXGI_FORMAT_R16G16B16A16_SINT", - "rtvFormat": "DXGI_FORMAT_R16G16B16A16_SINT" - } - ], - "GL_RGBA16UI": [ - { - "texFormat": "DXGI_FORMAT_R16G16B16A16_UINT", - "srvFormat": "DXGI_FORMAT_R16G16B16A16_UINT", - "rtvFormat": "DXGI_FORMAT_R16G16B16A16_UINT" - } - ], - "GL_RGBA32F": [ - { - "texFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", - "srvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT", - "rtvFormat": "DXGI_FORMAT_R32G32B32A32_FLOAT" - } - ], - "GL_RGBA32I": [ - { - "texFormat": "DXGI_FORMAT_R32G32B32A32_SINT", - "srvFormat": "DXGI_FORMAT_R32G32B32A32_SINT", - "rtvFormat": "DXGI_FORMAT_R32G32B32A32_SINT" - } - ], - "GL_RGBA32UI": [ - { - "texFormat": "DXGI_FORMAT_R32G32B32A32_UINT", - "srvFormat": "DXGI_FORMAT_R32G32B32A32_UINT", - "rtvFormat": "DXGI_FORMAT_R32G32B32A32_UINT" - } - ], - "GL_RGBA4": [ - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "requirementsFcn": "SupportsFormat" - }, - { - "texFormat": "DXGI_FORMAT_B4G4R4A4_UNORM", - "srvFormat": "DXGI_FORMAT_B4G4R4A4_UNORM", - "rtvFormat": "DXGI_FORMAT_B4G4R4A4_UNORM", - "requirementsFcn": "SupportsFormat" - } - ], - "GL_RGBA8": [ - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM", - "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM" - } - ], - "GL_RGBA8I": [ - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_SINT", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_SINT", - "rtvFormat": "DXGI_FORMAT_R8G8B8A8_SINT" - } - ], - "GL_RGBA8UI": [ - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UINT", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UINT", - "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UINT" - } - ], - "GL_RGBA8_SNORM": [ - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_SNORM", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_SNORM" - } - ], - "GL_SRGB8": [ - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB" - } - ], - "GL_SRGB8_ALPHA8": [ - { - "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", - "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", - "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB" - } - ], - "GL_STENCIL_INDEX8": [ - { - "texFormat": "DXGI_FORMAT_R24G8_TYPELESS", - "srvFormat": "DXGI_FORMAT_X24_TYPELESS_G8_UINT", - "dsvFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT", - "requirementsFcn": "OnlyFL10Plus" - }, - { - "texFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT", - "dsvFormat": "DXGI_FORMAT_D24_UNORM_S8_UINT", - "requirementsFcn": "OnlyFL9_3" - } - ] + "dsvFormat": "DXGI_FORMAT_D16_UNORM", + "channels": "d", + "componentType": "unorm", + "bits": { "depth": 16 }, + "glInternalFormat": "GL_DEPTH_COMPONENT16" + }, + "D32_FLOAT": { + "texFormat": "DXGI_FORMAT_R32_TYPELESS", + "srvFormat": "DXGI_FORMAT_R32_FLOAT", + "dsvFormat": "DXGI_FORMAT_D32_FLOAT", + "channels": "d", + "componentType": "float", + "bits": { "depth": 32 }, + "glInternalFormat": "GL_DEPTH_COMPONENT32F" + }, + "R11G11B10_FLOAT": { + "texFormat": "DXGI_FORMAT_R11G11B10_FLOAT", + "srvFormat": "DXGI_FORMAT_R11G11B10_FLOAT", + "rtvFormat": "DXGI_FORMAT_R11G11B10_FLOAT", + "channels": "rgb", + "componentType": "float", + "bits": { "red": 11, "green": 11, "blue": 10 }, + "glInternalFormat": "GL_R11F_G11F_B10F" + }, + "R16_FLOAT": { + "texFormat": "DXGI_FORMAT_R16_FLOAT", + "srvFormat": "DXGI_FORMAT_R16_FLOAT", + "rtvFormat": "DXGI_FORMAT_R16_FLOAT", + "channels": "r", + "componentType": "float", + "bits": { "red": 16 }, + "glInternalFormat": "GL_R16F" + }, + "R16_SINT": { + "texFormat": "DXGI_FORMAT_R16_SINT", + "srvFormat": "DXGI_FORMAT_R16_SINT", + "rtvFormat": "DXGI_FORMAT_R16_SINT", + "channels": "r", + "componentType": "int", + "bits": { "red": 16 }, + "glInternalFormat": "GL_R16I" + }, + "R16_UINT": { + "texFormat": "DXGI_FORMAT_R16_UINT", + "srvFormat": "DXGI_FORMAT_R16_UINT", + "rtvFormat": "DXGI_FORMAT_R16_UINT", + "channels": "r", + "componentType": "uint", + "bits": { "red": 16 }, + "glInternalFormat": "GL_R16UI" + }, + "R32_FLOAT": { + "texFormat": "DXGI_FORMAT_R32_FLOAT", + "srvFormat": "DXGI_FORMAT_R32_FLOAT", + "rtvFormat": "DXGI_FORMAT_R32_FLOAT", + "channels": "r", + "componentType": "float", + "bits": { "red": 32 }, + "glInternalFormat": "GL_R32F" + }, + "R32_SINT": { + "texFormat": "DXGI_FORMAT_R32_SINT", + "srvFormat": "DXGI_FORMAT_R32_SINT", + "rtvFormat": "DXGI_FORMAT_R32_SINT", + "channels": "r", + "componentType": "int", + "bits": { "red": 32 }, + "glInternalFormat": "GL_R32I" + }, + "R32_UINT": { + "texFormat": "DXGI_FORMAT_R32_UINT", + "srvFormat": "DXGI_FORMAT_R32_UINT", + "rtvFormat": "DXGI_FORMAT_R32_UINT", + "channels": "r", + "componentType": "uint", + "bits": { "red": 32 }, + "glInternalFormat": "GL_R32UI" + }, + "R8_UNORM": { + "texFormat": "DXGI_FORMAT_R8_UNORM", + "srvFormat": "DXGI_FORMAT_R8_UNORM", + "rtvFormat": "DXGI_FORMAT_R8_UNORM", + "channels": "r", + "componentType": "unorm", + "bits": { "red": 8 }, + "glInternalFormat": "GL_R8" + }, + "R8_SINT": { + "texFormat": "DXGI_FORMAT_R8_SINT", + "srvFormat": "DXGI_FORMAT_R8_SINT", + "rtvFormat": "DXGI_FORMAT_R8_SINT", + "channels": "r", + "componentType": "int", + "bits": { "red": 8 }, + "glInternalFormat": "GL_R8I" + }, + "R8_UINT": { + "texFormat": "DXGI_FORMAT_R8_UINT", + "srvFormat": "DXGI_FORMAT_R8_UINT", + "rtvFormat": "DXGI_FORMAT_R8_UINT", + "channels": "r", + "componentType": "uint", + "bits": { "red": 8 }, + "glInternalFormat": "GL_R8UI" + }, + "R8_SNORM": { + "texFormat": "DXGI_FORMAT_R8_SNORM", + "srvFormat": "DXGI_FORMAT_R8_SNORM", + "channels": "r", + "componentType": "snorm", + "bits": { "red": 8 }, + "glInternalFormat": "GL_R8_SNORM" + }, + "R16G16_FLOAT": { + "texFormat": "DXGI_FORMAT_R16G16_FLOAT", + "srvFormat": "DXGI_FORMAT_R16G16_FLOAT", + "rtvFormat": "DXGI_FORMAT_R16G16_FLOAT", + "channels": "rg", + "componentType": "float", + "bits": { "red": 16, "green": 16 }, + "glInternalFormat": "GL_RG16F" + }, + "R16G16_SINT": { + "texFormat": "DXGI_FORMAT_R16G16_SINT", + "srvFormat": "DXGI_FORMAT_R16G16_SINT", + "rtvFormat": "DXGI_FORMAT_R16G16_SINT", + "channels": "rg", + "componentType": "int", + "bits": { "red": 16, "green": 16 }, + "glInternalFormat": "GL_RG16I" + }, + "R16G16_UINT": { + "texFormat": "DXGI_FORMAT_R16G16_UINT", + "srvFormat": "DXGI_FORMAT_R16G16_UINT", + "rtvFormat": "DXGI_FORMAT_R16G16_UINT", + "channels": "rg", + "componentType": "uint", + "bits": { "red": 16, "green": 16 }, + "glInternalFormat": "GL_RG16UI" + }, + "R32G32_FLOAT": { + "texFormat": "DXGI_FORMAT_R32G32_FLOAT", + "srvFormat": "DXGI_FORMAT_R32G32_FLOAT", + "rtvFormat": "DXGI_FORMAT_R32G32_FLOAT", + "channels": "rg", + "componentType": "float", + "bits": { "red": 32, "green": 32 }, + "glInternalFormat": "GL_RG32F" + }, + "R32G32_SINT": { + "texFormat": "DXGI_FORMAT_R32G32_SINT", + "srvFormat": "DXGI_FORMAT_R32G32_SINT", + "rtvFormat": "DXGI_FORMAT_R32G32_SINT", + "channels": "rg", + "componentType": "int", + "bits": { "red": 32, "green": 32 }, + "glInternalFormat": "GL_RG32I" + }, + "R32G32_UINT": { + "texFormat": "DXGI_FORMAT_R32G32_UINT", + "srvFormat": "DXGI_FORMAT_R32G32_UINT", + "rtvFormat": "DXGI_FORMAT_R32G32_UINT", + "channels": "rg", + "componentType": "uint", + "bits": { "red": 32, "green": 32 }, + "glInternalFormat": "GL_RG32UI" + }, + "R8G8_UNORM": { + "texFormat": "DXGI_FORMAT_R8G8_UNORM", + "srvFormat": "DXGI_FORMAT_R8G8_UNORM", + "rtvFormat": "DXGI_FORMAT_R8G8_UNORM", + "channels": "rg", + "componentType": "unorm", + "bits": { "red": 8, "green": 8 }, + "glInternalFormat": "GL_RG8" + }, + "R8G8_SINT": { + "texFormat": "DXGI_FORMAT_R8G8_SINT", + "srvFormat": "DXGI_FORMAT_R8G8_SINT", + "rtvFormat": "DXGI_FORMAT_R8G8_SINT", + "channels": "rg", + "componentType": "int", + "bits": { "red": 8, "green": 8 }, + "glInternalFormat": "GL_RG8I" + }, + "R8G8_UINT": { + "texFormat": "DXGI_FORMAT_R8G8_UINT", + "srvFormat": "DXGI_FORMAT_R8G8_UINT", + "rtvFormat": "DXGI_FORMAT_R8G8_UINT", + "channels": "rg", + "componentType": "uint", + "bits": { "red": 8, "green": 8 }, + "glInternalFormat": "GL_RG8UI" + }, + "R8G8_SNORM": { + "texFormat": "DXGI_FORMAT_R8G8_SNORM", + "srvFormat": "DXGI_FORMAT_R8G8_SNORM", + "channels": "rg", + "componentType": "snorm", + "bits": { "red": 8, "green": 8 }, + "glInternalFormat": "GL_RG8_SNORM" + }, + "R10G10B10A2_UNORM": { + "texFormat": "DXGI_FORMAT_R10G10B10A2_UNORM", + "srvFormat": "DXGI_FORMAT_R10G10B10A2_UNORM", + "rtvFormat": "DXGI_FORMAT_R10G10B10A2_UNORM", + "channels": "rgba", + "componentType": "unorm", + "bits": { "red": 10, "green": 10, "blue": 10, "alpha": 2 }, + "glInternalFormat": "GL_RGB10_A2" + }, + "R10G10B10A2_UINT": { + "texFormat": "DXGI_FORMAT_R10G10B10A2_UINT", + "srvFormat": "DXGI_FORMAT_R10G10B10A2_UINT", + "rtvFormat": "DXGI_FORMAT_R10G10B10A2_UINT", + "channels": "rgba", + "componentType": "uint", + "bits": { "red": 10, "green": 10, "blue": 10, "alpha": 2 }, + "glInternalFormat": "GL_RGB10_A2UI" + }, + "R16G16B16A16_SINT": { + "texFormat": "DXGI_FORMAT_R16G16B16A16_SINT", + "srvFormat": "DXGI_FORMAT_R16G16B16A16_SINT", + "rtvFormat": "DXGI_FORMAT_R16G16B16A16_SINT", + "channels": "rgba", + "componentType": "int", + "bits": { "red": 16, "green": 16, "blue": 16, "alpha": 16 }, + "glInternalFormat": "GL_RGBA16I" + }, + "R16G16B16A16_UINT": { + "texFormat": "DXGI_FORMAT_R16G16B16A16_UINT", + "srvFormat": "DXGI_FORMAT_R16G16B16A16_UINT", + "rtvFormat": "DXGI_FORMAT_R16G16B16A16_UINT", + "channels": "rgba", + "componentType": "uint", + "bits": { "red": 16, "green": 16, "blue": 16, "alpha": 16 }, + "glInternalFormat": "GL_RGBA16UI" + }, + "R32G32B32A32_SINT": { + "texFormat": "DXGI_FORMAT_R32G32B32A32_SINT", + "srvFormat": "DXGI_FORMAT_R32G32B32A32_SINT", + "rtvFormat": "DXGI_FORMAT_R32G32B32A32_SINT", + "channels": "rgba", + "componentType": "int", + "bits": { "red": 32, "green": 32, "blue": 32, "alpha": 32 }, + "glInternalFormat": "GL_RGBA32I" + }, + "R32G32B32A32_UINT": { + "texFormat": "DXGI_FORMAT_R32G32B32A32_UINT", + "srvFormat": "DXGI_FORMAT_R32G32B32A32_UINT", + "rtvFormat": "DXGI_FORMAT_R32G32B32A32_UINT", + "channels": "rgba", + "componentType": "uint", + "bits": { "red": 32, "green": 32, "blue": 32, "alpha": 32 }, + "glInternalFormat": "GL_RGBA32UI" + }, + "B5G6R5_UNORM": { + "texFormat": "DXGI_FORMAT_B5G6R5_UNORM", + "srvFormat": "DXGI_FORMAT_B5G6R5_UNORM", + "rtvFormat": "DXGI_FORMAT_B5G6R5_UNORM", + "channels": "bgr", + "componentType": "unorm", + "bits": { "red": 5, "green": 6, "blue": 5 }, + "supportTest": "SupportsFormat(DXGI_FORMAT_B5G6R5_UNORM, deviceCaps)", + "fallbackFormat": "R8G8B8A8_UNORM" + }, + "B5G5R5A1_UNORM": { + "texFormat": "DXGI_FORMAT_B5G5R5A1_UNORM", + "srvFormat": "DXGI_FORMAT_B5G5R5A1_UNORM", + "rtvFormat": "DXGI_FORMAT_B5G5R5A1_UNORM", + "channels": "bgra", + "componentType": "unorm", + "bits": { "red": 5, "green": 5, "blue": 5, "alpha": 1 }, + "supportTest": "SupportsFormat(DXGI_FORMAT_B5G5R5A1_UNORM, deviceCaps)", + "fallbackFormat": "R8G8B8A8_UNORM" + }, + "R8G8B8A8_SINT": { + "texFormat": "DXGI_FORMAT_R8G8B8A8_SINT", + "srvFormat": "DXGI_FORMAT_R8G8B8A8_SINT", + "rtvFormat": "DXGI_FORMAT_R8G8B8A8_SINT", + "channels": "rgba", + "componentType": "int", + "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 }, + "glInternalFormat": "GL_RGBA8I" + }, + "R8G8B8A8_UINT": { + "texFormat": "DXGI_FORMAT_R8G8B8A8_UINT", + "srvFormat": "DXGI_FORMAT_R8G8B8A8_UINT", + "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UINT", + "channels": "rgba", + "componentType": "uint", + "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 }, + "glInternalFormat": "GL_RGBA8UI" + }, + "R8G8B8A8_SNORM": { + "texFormat": "DXGI_FORMAT_R8G8B8A8_SNORM", + "srvFormat": "DXGI_FORMAT_R8G8B8A8_SNORM", + "channels": "rgba", + "componentType": "snorm", + "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 }, + "glInternalFormat": "GL_RGBA8_SNORM" + }, + "R9G9B9E5_SHAREDEXP": { + "texFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP", + "srvFormat": "DXGI_FORMAT_R9G9B9E5_SHAREDEXP", + "channels": "rgb", + "componentType": "float", + "bits": { "red": 9, "green": 9, "blue": 9, "shared": 5 } + }, + "B4G4R4A4_UNORM": { + "texFormat": "DXGI_FORMAT_B4G4R4A4_UNORM", + "srvFormat": "DXGI_FORMAT_B4G4R4A4_UNORM", + "rtvFormat": "DXGI_FORMAT_B4G4R4A4_UNORM", + "channels": "bgra", + "componentType": "unorm", + "bits": { "red": 4, "green": 4, "blue": 4, "alpha": 4 }, + "supportTest": "SupportsFormat(DXGI_FORMAT_B4G4R4A4_UNORM, deviceCaps)", + "fallbackFormat": "R8G8B8A8_UNORM" + }, + "R8G8B8A8_UNORM_SRGB": { + "texFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", + "srvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", + "rtvFormat": "DXGI_FORMAT_R8G8B8A8_UNORM_SRGB", + "channels": "rgba", + "componentType": "unorm", + "bits": { "red": 8, "green": 8, "blue": 8, "alpha": 8 }, + "glInternalFormat": "GL_SRGB8_ALPHA8" + }, + "R16_UNORM": { + "texFormat": "DXGI_FORMAT_R16_UNORM", + "srvFormat": "DXGI_FORMAT_R16_UNORM", + "rtvFormat": "DXGI_FORMAT_R16_UNORM", + "channels": "r", + "componentType": "unorm", + "bits": { "red": 16 }, + "glInternalFormat": "GL_R16_EXT" + }, + "R16G16_UNORM": { + "texFormat": "DXGI_FORMAT_R16G16_UNORM", + "srvFormat": "DXGI_FORMAT_R16G16_UNORM", + "rtvFormat": "DXGI_FORMAT_R16G16_UNORM", + "channels": "rg", + "componentType": "unorm", + "bits": { "red": 16, "green": 16 }, + "glInternalFormat": "GL_RG16_EXT" + }, + "R16_SNORM": { + "texFormat": "DXGI_FORMAT_R16_SNORM", + "srvFormat": "DXGI_FORMAT_R16_SNORM", + "channels": "r", + "componentType": "snorm", + "bits": { "red": 16 }, + "glInternalFormat": "GL_R16_SNORM_EXT" + }, + "R16G16_SNORM": { + "texFormat": "DXGI_FORMAT_R16G16_SNORM", + "srvFormat": "DXGI_FORMAT_R16G16_SNORM", + "channels": "rg", + "componentType": "snorm", + "bits": { "red": 16, "green": 16 }, + "glInternalFormat": "GL_RG16_SNORM_EXT" + }, + "R16G16B16A16_SNORM": { + "texFormat": "DXGI_FORMAT_R16G16B16A16_SNORM", + "srvFormat": "DXGI_FORMAT_R16G16B16A16_SNORM", + "channels": "rgba", + "componentType": "snorm", + "bits": { "red": 16, "green": 16, "blue": 16, "alpha": 16 }, + "glInternalFormat": "GL_RGBA16_SNORM_EXT" + } } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_map.json b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_map.json new file mode 100644 index 0000000000..3ef2355645 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_map.json @@ -0,0 +1,78 @@ +{ + "GL_ALPHA16F_EXT": "R16G16B16A16_FLOAT", + "GL_ALPHA32F_EXT": "R32G32B32A32_FLOAT", + "GL_BGR5_A1_ANGLEX": "B8G8R8A8_UNORM", + "GL_BGRA4_ANGLEX": "B8G8R8A8_UNORM", + "GL_BGRA8_SRGB_ANGLEX": "B8G8R8A8_UNORM_SRGB", + "GL_COMPRESSED_R11_EAC": "R8_UNORM", + "GL_COMPRESSED_RG11_EAC": "R8G8_UNORM", + "GL_COMPRESSED_RGB8_ETC2": "R8G8B8A8_UNORM", + "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2": "R8G8B8A8_UNORM", + "GL_COMPRESSED_RGBA8_ETC2_EAC": "R8G8B8A8_UNORM", + "GL_COMPRESSED_RGBA_ASTC_4x4_KHR": "NONE", + "GL_COMPRESSED_RGBA_ASTC_5x4_KHR": "NONE", + "GL_COMPRESSED_RGBA_ASTC_5x5_KHR": "NONE", + "GL_COMPRESSED_RGBA_ASTC_6x5_KHR": "NONE", + "GL_COMPRESSED_RGBA_ASTC_6x6_KHR": "NONE", + "GL_COMPRESSED_RGBA_ASTC_8x5_KHR": "NONE", + "GL_COMPRESSED_RGBA_ASTC_8x6_KHR": "NONE", + "GL_COMPRESSED_RGBA_ASTC_8x8_KHR": "NONE", + "GL_COMPRESSED_RGBA_ASTC_10x5_KHR": "NONE", + "GL_COMPRESSED_RGBA_ASTC_10x6_KHR": "NONE", + "GL_COMPRESSED_RGBA_ASTC_10x8_KHR": "NONE", + "GL_COMPRESSED_RGBA_ASTC_10x10_KHR": "NONE", + "GL_COMPRESSED_RGBA_ASTC_12x10_KHR": "NONE", + "GL_COMPRESSED_RGBA_ASTC_12x12_KHR": "NONE", + "GL_COMPRESSED_SIGNED_R11_EAC": "R8_SNORM", + "GL_COMPRESSED_SIGNED_RG11_EAC": "R8G8_SNORM", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR": "NONE", + "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC": "R8G8B8A8_UNORM_SRGB", + "GL_COMPRESSED_SRGB8_ETC2": "R8G8B8A8_UNORM_SRGB", + "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2": "R8G8B8A8_UNORM_SRGB", + "GL_DEPTH_COMPONENT24": "D24_UNORM_S8_UINT", + "GL_DEPTH_COMPONENT32_OES": "D24_UNORM_S8_UINT", + "GL_ETC1_RGB8_OES": "R8G8B8A8_UNORM", + "GL_ETC1_RGB8_LOSSY_DECODE_ANGLE": "BC1_RGB_UNORM_BLOCK", + "GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE": "BC1_RGB_UNORM_BLOCK", + "GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE": "BC1_RGB_UNORM_SRGB_BLOCK", + "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE": "BC1_RGBA_UNORM_BLOCK", + "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE": "BC1_RGBA_UNORM_SRGB_BLOCK", + "GL_LUMINANCE16F_EXT": "R16G16B16A16_FLOAT", + "GL_LUMINANCE32F_EXT": "R32G32B32A32_FLOAT", + "GL_LUMINANCE8_ALPHA8_EXT": "R8G8B8A8_UNORM", + "GL_LUMINANCE8_EXT": "R8G8B8A8_UNORM", + "GL_LUMINANCE_ALPHA16F_EXT": "R16G16B16A16_FLOAT", + "GL_LUMINANCE_ALPHA32F_EXT": "R32G32B32A32_FLOAT", + "GL_RGB": "R8G8B8A8_UNORM", + "GL_RGB16F": "R16G16B16A16_FLOAT", + "GL_RGB16I": "R16G16B16A16_SINT", + "GL_RGB16UI": "R16G16B16A16_UINT", + "GL_RGB565": "B5G6R5_UNORM", + "GL_RGB5_A1": "B5G5R5A1_UNORM", + "GL_RGB8": "R8G8B8A8_UNORM", + "GL_RGB8I": "R8G8B8A8_SINT", + "GL_RGB8UI": "R8G8B8A8_UINT", + "GL_RGB8_SNORM": "R8G8B8A8_SNORM", + "GL_RGBA4": "B4G4R4A4_UNORM", + "GL_SRGB8": "R8G8B8A8_UNORM_SRGB", + "GL_STENCIL_INDEX8": "D24_UNORM_S8_UINT", + "GL_RGB16_EXT": "R16G16B16A16_UNORM", + "GL_RGBA16_EXT": "R16G16B16A16_UNORM", + "GL_RGB16_SNORM_EXT": "R16G16B16A16_SNORM", + "GL_RGB32F": "R32G32B32A32_FLOAT", + "GL_RGB32I": "R32G32B32A32_SINT", + "GL_RGB32UI": "R32G32B32A32_UINT" +} diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table.cpp new file mode 100644 index 0000000000..a9dfec56b8 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table.cpp @@ -0,0 +1,35 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Helper routines for the D3D11 texture format table. + +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" + +#include "libANGLE/renderer/load_functions_table.h" + +namespace rx +{ + +namespace d3d11 +{ + +const Format &Format::getSwizzleFormat(const Renderer11DeviceCaps &deviceCaps) const +{ + return (swizzleFormat == internalFormat ? *this : Format::Get(swizzleFormat, deviceCaps)); +} + +LoadFunctionMap Format::getLoadFunctions() const +{ + return GetLoadFunctionsMap(internalFormat, formatID); +} + +const angle::Format &Format::format() const +{ + return angle::Format::Get(formatID); +} + +} // namespace d3d11 + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h index 1606a28a73..3efcb81adb 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h @@ -12,50 +12,91 @@ #include +#include "common/angleutils.h" #include "common/platform.h" +#include "libANGLE/renderer/Format.h" +#include "libANGLE/renderer/renderer_utils.h" #include "libANGLE/renderer/d3d/formatutilsD3D.h" -#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" namespace rx { +struct Renderer11DeviceCaps; + namespace d3d11 { -struct LoadImageFunctionInfo +// For sized GL internal formats, there are several possible corresponding D3D11 formats depending +// on device capabilities. +// This structure allows querying for the DXGI texture formats to use for textures, SRVs, RTVs and +// DSVs given a GL internal format. +struct Format final : private angle::NonCopyable { - LoadImageFunctionInfo() : loadFunction(nullptr), requiresConversion(false) {} - LoadImageFunctionInfo(LoadImageFunction loadFunction, bool requiresConversion) - : loadFunction(loadFunction), requiresConversion(requiresConversion) - { - } + constexpr Format(); + constexpr Format(GLenum internalFormat, + angle::Format::ID formatID, + DXGI_FORMAT texFormat, + DXGI_FORMAT srvFormat, + DXGI_FORMAT rtvFormat, + DXGI_FORMAT dsvFormat, + DXGI_FORMAT blitSRVFormat, + GLenum swizzleFormat, + InitializeTextureDataFunction internalFormatInitializer); - LoadImageFunction loadFunction; - bool requiresConversion; -}; + static const Format &Get(GLenum internalFormat, const Renderer11DeviceCaps &deviceCaps); -struct TextureFormat -{ - TextureFormat(); + const Format &getSwizzleFormat(const Renderer11DeviceCaps &deviceCaps) const; + LoadFunctionMap getLoadFunctions() const; + const angle::Format &format() const; + + GLenum internalFormat; + angle::Format::ID formatID; DXGI_FORMAT texFormat; DXGI_FORMAT srvFormat; DXGI_FORMAT rtvFormat; DXGI_FORMAT dsvFormat; - DXGI_FORMAT renderFormat; - DXGI_FORMAT swizzleTexFormat; - DXGI_FORMAT swizzleSRVFormat; - DXGI_FORMAT swizzleRTVFormat; + DXGI_FORMAT blitSRVFormat; + + GLenum swizzleFormat; InitializeTextureDataFunction dataInitializerFunction; - typedef std::map LoadFunctionMap; - - LoadFunctionMap loadFunctions; }; -const TextureFormat &GetTextureFormatInfo(GLenum internalformat, - const Renderer11DeviceCaps &renderer11DeviceCaps); +constexpr Format::Format() + : internalFormat(GL_NONE), + formatID(angle::Format::ID::NONE), + texFormat(DXGI_FORMAT_UNKNOWN), + srvFormat(DXGI_FORMAT_UNKNOWN), + rtvFormat(DXGI_FORMAT_UNKNOWN), + dsvFormat(DXGI_FORMAT_UNKNOWN), + blitSRVFormat(DXGI_FORMAT_UNKNOWN), + swizzleFormat(GL_NONE), + dataInitializerFunction(nullptr) +{ +} + +constexpr Format::Format(GLenum internalFormat, + angle::Format::ID formatID, + DXGI_FORMAT texFormat, + DXGI_FORMAT srvFormat, + DXGI_FORMAT rtvFormat, + DXGI_FORMAT dsvFormat, + DXGI_FORMAT blitSRVFormat, + GLenum swizzleFormat, + InitializeTextureDataFunction internalFormatInitializer) + : internalFormat(internalFormat), + formatID(formatID), + texFormat(texFormat), + srvFormat(srvFormat), + rtvFormat(rtvFormat), + dsvFormat(dsvFormat), + blitSRVFormat(blitSRVFormat), + swizzleFormat(swizzleFormat), + dataInitializerFunction(internalFormatInitializer) +{ +} } // namespace d3d11 diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp index 0b214c9756..3c1c2bcd50 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp @@ -1,7 +1,7 @@ // GENERATED FILE - DO NOT EDIT. // Generated by gen_texture_format_table.py using data from texture_format_data.json // -// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Copyright 2017 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -11,12 +11,15 @@ #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" +#include "image_util/copyimage.h" +#include "image_util/generatemip.h" +#include "image_util/loadimage.h" + #include "libANGLE/renderer/d3d/d3d11/formatutils11.h" -#include "libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.h" -#include "libANGLE/renderer/d3d/d3d11/load_functions_table.h" #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" -#include "libANGLE/renderer/d3d/d3d11/swizzle_format_info.h" -#include "libANGLE/renderer/d3d/loadimage.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table_utils.h" + +using namespace angle; namespace rx { @@ -24,1756 +27,1899 @@ namespace rx namespace d3d11 { -namespace -{ - -typedef bool (*FormatSupportFunction)(const Renderer11DeviceCaps &); - -bool AnyDevice(const Renderer11DeviceCaps &deviceCaps) -{ - return true; -} - -bool OnlyFL10Plus(const Renderer11DeviceCaps &deviceCaps) -{ - return (deviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_0); -} - -bool OnlyFL9_3(const Renderer11DeviceCaps &deviceCaps) -{ - return (deviceCaps.featureLevel == D3D_FEATURE_LEVEL_9_3); -} - -template -bool SupportsFormat(const Renderer11DeviceCaps &deviceCaps) -{ - // Must support texture, SRV and RTV support - UINT mustSupport = D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURECUBE | - D3D11_FORMAT_SUPPORT_SHADER_SAMPLE | D3D11_FORMAT_SUPPORT_MIP | - D3D11_FORMAT_SUPPORT_RENDER_TARGET; - - if (d3d11_gl::GetMaximumClientVersion(deviceCaps.featureLevel) > 2) - { - mustSupport |= D3D11_FORMAT_SUPPORT_TEXTURE3D; - } - - bool fullSupport = false; - if (format == DXGI_FORMAT_B5G6R5_UNORM) - { - // All hardware that supports DXGI_FORMAT_B5G6R5_UNORM should support autogen mipmaps, but - // check anyway. - mustSupport |= D3D11_FORMAT_SUPPORT_MIP_AUTOGEN; - fullSupport = ((deviceCaps.B5G6R5support & mustSupport) == mustSupport); - } - else if (format == DXGI_FORMAT_B4G4R4A4_UNORM) - { - fullSupport = ((deviceCaps.B4G4R4A4support & mustSupport) == mustSupport); - } - else if (format == DXGI_FORMAT_B5G5R5A1_UNORM) - { - fullSupport = ((deviceCaps.B5G5R5A1support & mustSupport) == mustSupport); - } - else - { - UNREACHABLE(); - return false; - } - - // This 'SupportsFormat' function is used by individual entries in the D3D11 Format Map below, - // which maps GL formats to DXGI formats. - if (requireSupport) - { - // This means that ANGLE would like to use the entry in the map if the inputted DXGI format - // *IS* supported. - // e.g. the entry might map GL_RGB5_A1 to DXGI_FORMAT_B5G5R5A1, which should only be used if - // DXGI_FORMAT_B5G5R5A1 is supported. - // In this case, we should only return 'true' if the format *IS* supported. - return fullSupport; - } - else - { - // This means that ANGLE would like to use the entry in the map if the inputted DXGI format - // *ISN'T* supported. - // This might be a fallback entry. e.g. for ANGLE to use DXGI_FORMAT_R8G8B8A8_UNORM if - // DXGI_FORMAT_B5G5R5A1 isn't supported. - // In this case, we should only return 'true' if the format *ISN'T* supported. - return !fullSupport; - } -} - -// End Format Support Functions - -// For sized GL internal formats, there are several possible corresponding D3D11 formats depending -// on device capabilities. -// This function allows querying for the DXGI texture formats to use for textures, SRVs, RTVs and -// DSVs given a GL internal format. -const TextureFormat GetD3D11FormatInfo(GLenum internalFormat, - DXGI_FORMAT texFormat, - DXGI_FORMAT srvFormat, - DXGI_FORMAT rtvFormat, - DXGI_FORMAT dsvFormat) -{ - TextureFormat info; - info.texFormat = texFormat; - info.srvFormat = srvFormat; - info.rtvFormat = rtvFormat; - info.dsvFormat = dsvFormat; - - // Given a GL internal format, the renderFormat is the DSV format if it is depth- or - // stencil-renderable, - // the RTV format if it is color-renderable, and the (nonrenderable) texture format otherwise. - if (dsvFormat != DXGI_FORMAT_UNKNOWN) - { - info.renderFormat = dsvFormat; - } - else if (rtvFormat != DXGI_FORMAT_UNKNOWN) - { - info.renderFormat = rtvFormat; - } - else if (texFormat != DXGI_FORMAT_UNKNOWN) - { - info.renderFormat = texFormat; - } - else - { - info.renderFormat = DXGI_FORMAT_UNKNOWN; - } - - // Compute the swizzle formats - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); - if (internalFormat != GL_NONE && formatInfo.pixelBytes > 0) - { - if (formatInfo.componentCount != 4 || texFormat == DXGI_FORMAT_UNKNOWN || - srvFormat == DXGI_FORMAT_UNKNOWN || rtvFormat == DXGI_FORMAT_UNKNOWN) - { - // Get the maximum sized component - unsigned int maxBits = 1; - if (formatInfo.compressed) - { - unsigned int compressedBitsPerBlock = formatInfo.pixelBytes * 8; - unsigned int blockSize = - formatInfo.compressedBlockWidth * formatInfo.compressedBlockHeight; - maxBits = std::max(compressedBitsPerBlock / blockSize, maxBits); - } - else - { - maxBits = std::max(maxBits, formatInfo.alphaBits); - maxBits = std::max(maxBits, formatInfo.redBits); - maxBits = std::max(maxBits, formatInfo.greenBits); - maxBits = std::max(maxBits, formatInfo.blueBits); - maxBits = std::max(maxBits, formatInfo.luminanceBits); - maxBits = std::max(maxBits, formatInfo.depthBits); - } - - maxBits = roundUp(maxBits, 8U); - - const SwizzleFormatInfo &swizzleInfo = - GetSwizzleFormatInfo(maxBits, formatInfo.componentType); - info.swizzleTexFormat = swizzleInfo.mTexFormat; - info.swizzleSRVFormat = swizzleInfo.mSRVFormat; - info.swizzleRTVFormat = swizzleInfo.mRTVFormat; - } - else - { - // The original texture format is suitable for swizzle operations - info.swizzleTexFormat = texFormat; - info.swizzleSRVFormat = srvFormat; - info.swizzleRTVFormat = rtvFormat; - } - } - else - { - // Not possible to swizzle with this texture format since it is either unsized or GL_NONE - info.swizzleTexFormat = DXGI_FORMAT_UNKNOWN; - info.swizzleSRVFormat = DXGI_FORMAT_UNKNOWN; - info.swizzleRTVFormat = DXGI_FORMAT_UNKNOWN; - } - - // Check if there is an initialization function for this texture format - info.dataInitializerFunction = GetInternalFormatInitializer(internalFormat, texFormat); - // Gather all the load functions for this internal format - info.loadFunctions = GetLoadFunctionsMap(internalFormat, texFormat); - - ASSERT(info.loadFunctions.size() != 0 || internalFormat == GL_NONE); - - return info; -} - -} // namespace - -TextureFormat::TextureFormat() - : texFormat(DXGI_FORMAT_UNKNOWN), - srvFormat(DXGI_FORMAT_UNKNOWN), - rtvFormat(DXGI_FORMAT_UNKNOWN), - dsvFormat(DXGI_FORMAT_UNKNOWN), - renderFormat(DXGI_FORMAT_UNKNOWN), - swizzleTexFormat(DXGI_FORMAT_UNKNOWN), - swizzleSRVFormat(DXGI_FORMAT_UNKNOWN), - swizzleRTVFormat(DXGI_FORMAT_UNKNOWN), - dataInitializerFunction(NULL), - loadFunctions() -{ -} - -const TextureFormat &GetTextureFormatInfo(GLenum internalFormat, - const Renderer11DeviceCaps &renderer11DeviceCaps) +// static +const Format &Format::Get(GLenum internalFormat, const Renderer11DeviceCaps &deviceCaps) { // clang-format off switch (internalFormat) { - case GL_ALPHA: - { - if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_A8_UNORM, - DXGI_FORMAT_A8_UNORM, - DXGI_FORMAT_A8_UNORM, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else if (OnlyFL9_3(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } - } case GL_ALPHA16F_EXT: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R16G16B16A16_FLOAT, - DXGI_FORMAT_R16G16B16A16_FLOAT, - DXGI_FORMAT_R16G16B16A16_FLOAT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_ALPHA16F_EXT, + angle::Format::ID::R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_FLOAT, + GL_RGBA16F, + nullptr); + return info; } case GL_ALPHA32F_EXT: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_ALPHA32F_EXT, + angle::Format::ID::R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_FLOAT, + GL_RGBA32F, + nullptr); + return info; } case GL_ALPHA8_EXT: { - if (OnlyFL10Plus(renderer11DeviceCaps)) + if (OnlyFL10Plus(deviceCaps)) { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_A8_UNORM, - DXGI_FORMAT_A8_UNORM, - DXGI_FORMAT_A8_UNORM, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else if (OnlyFL9_3(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_UNKNOWN); - return textureFormat; + static constexpr Format info(GL_ALPHA8_EXT, + angle::Format::ID::A8_UNORM, + DXGI_FORMAT_A8_UNORM, + DXGI_FORMAT_A8_UNORM, + DXGI_FORMAT_A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_A8_UNORM, + GL_RGBA8, + nullptr); + return info; } else { - break; + static constexpr Format info(GL_ALPHA8_EXT, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + nullptr); + return info; + } + } + case GL_BGR565_ANGLEX: + { + if (SupportsFormat(DXGI_FORMAT_B5G6R5_UNORM, deviceCaps)) + { + static constexpr Format info(GL_BGR565_ANGLEX, + angle::Format::ID::B5G6R5_UNORM, + DXGI_FORMAT_B5G6R5_UNORM, + DXGI_FORMAT_B5G6R5_UNORM, + DXGI_FORMAT_B5G6R5_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B5G6R5_UNORM, + GL_RGBA8, + nullptr); + return info; + } + else + { + static constexpr Format info(GL_BGR565_ANGLEX, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + nullptr); + return info; } } case GL_BGR5_A1_ANGLEX: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_B8G8R8A8_UNORM, - DXGI_FORMAT_B8G8R8A8_UNORM, - DXGI_FORMAT_B8G8R8A8_UNORM, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_BGR5_A1_ANGLEX, + angle::Format::ID::B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B8G8R8A8_UNORM, + GL_BGRA8_EXT, + nullptr); + return info; } case GL_BGRA4_ANGLEX: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_B8G8R8A8_UNORM, - DXGI_FORMAT_B8G8R8A8_UNORM, - DXGI_FORMAT_B8G8R8A8_UNORM, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_BGRA4_ANGLEX, + angle::Format::ID::B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B8G8R8A8_UNORM, + GL_BGRA8_EXT, + nullptr); + return info; } case GL_BGRA8_EXT: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_B8G8R8A8_UNORM, - DXGI_FORMAT_B8G8R8A8_UNORM, - DXGI_FORMAT_B8G8R8A8_UNORM, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_BGRA8_EXT, + angle::Format::ID::B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B8G8R8A8_UNORM, + GL_BGRA8_EXT, + nullptr); + return info; } - case GL_BGRA_EXT: + case GL_BGRA8_SRGB_ANGLEX: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_B8G8R8A8_UNORM, - DXGI_FORMAT_B8G8R8A8_UNORM, - DXGI_FORMAT_B8G8R8A8_UNORM, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_BGRA8_SRGB_ANGLEX, + angle::Format::ID::B8G8R8A8_UNORM_SRGB, + DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, + DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, + DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, + GL_BGRA8_SRGB_ANGLEX, + nullptr); + return info; } case GL_COMPRESSED_R11_EAC: { - if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8_UNORM, - DXGI_FORMAT_R8_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_COMPRESSED_R11_EAC, + angle::Format::ID::R8_UNORM, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_UNORM, + GL_RGBA8, + nullptr); + return info; } case GL_COMPRESSED_RG11_EAC: { - if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8_UNORM, - DXGI_FORMAT_R8G8_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_COMPRESSED_RG11_EAC, + angle::Format::ID::R8G8_UNORM, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_UNORM, + GL_RGBA8, + nullptr); + return info; } case GL_COMPRESSED_RGB8_ETC2: { - if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_COMPRESSED_RGB8_ETC2, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + Initialize4ComponentData); + return info; + } + case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE: + { + static constexpr Format info(GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE, + angle::Format::ID::BC1_RGB_UNORM_BLOCK, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC1_UNORM, + GL_RGBA8, + nullptr); + return info; } case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: { - if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + Initialize4ComponentData); + return info; + } + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE: + { + static constexpr Format info(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE, + angle::Format::ID::BC1_RGBA_UNORM_BLOCK, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC1_UNORM, + GL_RGBA8, + nullptr); + return info; } case GL_COMPRESSED_RGBA8_ETC2_EAC: { - if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_COMPRESSED_RGBA8_ETC2_EAC, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_10x10_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_10x10_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_10x5_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_10x5_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_10x6_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_10x6_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_10x8_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_10x8_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_12x10_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_12x10_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_12x12_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_12x12_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_4x4_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_4x4_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_5x4_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_5x4_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_5x5_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_5x5_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_6x5_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_6x5_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_6x6_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_6x6_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_8x5_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_8x5_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_8x6_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_8x6_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_RGBA_ASTC_8x8_KHR: + { + static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_8x8_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; } case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_BC1_UNORM, - DXGI_FORMAT_BC1_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, + angle::Format::ID::BC1_RGBA_UNORM_BLOCK, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC1_UNORM, + GL_RGBA8, + nullptr); + return info; } case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_BC2_UNORM, - DXGI_FORMAT_BC2_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, + angle::Format::ID::BC2_RGBA_UNORM_BLOCK, + DXGI_FORMAT_BC2_UNORM, + DXGI_FORMAT_BC2_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC2_UNORM, + GL_RGBA8, + nullptr); + return info; } case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_BC3_UNORM, - DXGI_FORMAT_BC3_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, + angle::Format::ID::BC3_RGBA_UNORM_BLOCK, + DXGI_FORMAT_BC3_UNORM, + DXGI_FORMAT_BC3_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC3_UNORM, + GL_RGBA8, + nullptr); + return info; } case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_BC1_UNORM, - DXGI_FORMAT_BC1_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, + angle::Format::ID::BC1_RGB_UNORM_BLOCK, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC1_UNORM, + GL_RGBA8, + nullptr); + return info; } case GL_COMPRESSED_SIGNED_R11_EAC: { - if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8_SNORM, - DXGI_FORMAT_R8_SNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_COMPRESSED_SIGNED_R11_EAC, + angle::Format::ID::R8_SNORM, + DXGI_FORMAT_R8_SNORM, + DXGI_FORMAT_R8_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_SNORM, + GL_RGBA8_SNORM, + nullptr); + return info; } case GL_COMPRESSED_SIGNED_RG11_EAC: { - if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8_SNORM, - DXGI_FORMAT_R8G8_SNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_COMPRESSED_SIGNED_RG11_EAC, + angle::Format::ID::R8G8_SNORM, + DXGI_FORMAT_R8G8_SNORM, + DXGI_FORMAT_R8G8_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_SNORM, + GL_RGBA8_SNORM, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; } case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: { - if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, - DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, + angle::Format::ID::R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + GL_SRGB8_ALPHA8, + nullptr); + return info; } case GL_COMPRESSED_SRGB8_ETC2: { - if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, - DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_COMPRESSED_SRGB8_ETC2, + angle::Format::ID::R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + GL_SRGB8_ALPHA8, + Initialize4ComponentData); + return info; + } + case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE, + angle::Format::ID::BC1_RGB_UNORM_SRGB_BLOCK, + DXGI_FORMAT_BC1_UNORM_SRGB, + DXGI_FORMAT_BC1_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC1_UNORM_SRGB, + GL_RGBA8, + nullptr); + return info; } case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: { - if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, - DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, + angle::Format::ID::R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + GL_SRGB8_ALPHA8, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE: + { + static constexpr Format info(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE, + angle::Format::ID::BC1_RGBA_UNORM_SRGB_BLOCK, + DXGI_FORMAT_BC1_UNORM_SRGB, + DXGI_FORMAT_BC1_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC1_UNORM_SRGB, + GL_RGBA8, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + { + static constexpr Format info(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, + angle::Format::ID::BC1_RGBA_UNORM_SRGB_BLOCK, + DXGI_FORMAT_BC1_UNORM_SRGB, + DXGI_FORMAT_BC1_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC1_UNORM_SRGB, + GL_RGBA8, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + { + static constexpr Format info(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, + angle::Format::ID::BC2_RGBA_UNORM_SRGB_BLOCK, + DXGI_FORMAT_BC2_UNORM_SRGB, + DXGI_FORMAT_BC2_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC2_UNORM_SRGB, + GL_RGBA8, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + { + static constexpr Format info(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, + angle::Format::ID::BC3_RGBA_UNORM_SRGB_BLOCK, + DXGI_FORMAT_BC3_UNORM_SRGB, + DXGI_FORMAT_BC3_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC3_UNORM_SRGB, + GL_RGBA8, + nullptr); + return info; + } + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + { + static constexpr Format info(GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, + angle::Format::ID::BC1_RGB_UNORM_SRGB_BLOCK, + DXGI_FORMAT_BC1_UNORM_SRGB, + DXGI_FORMAT_BC1_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC1_UNORM_SRGB, + GL_RGBA8, + nullptr); + return info; } case GL_DEPTH24_STENCIL8: { - if (OnlyFL9_3(renderer11DeviceCaps)) + if (OnlyFL10Plus(deviceCaps)) { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_D24_UNORM_S8_UINT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_D24_UNORM_S8_UINT); - return textureFormat; - } - else if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R24G8_TYPELESS, - DXGI_FORMAT_R24_UNORM_X8_TYPELESS, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_D24_UNORM_S8_UINT); - return textureFormat; + static constexpr Format info(GL_DEPTH24_STENCIL8, + angle::Format::ID::D24_UNORM_S8_UINT, + DXGI_FORMAT_R24G8_TYPELESS, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + GL_RGBA32F, + nullptr); + return info; } else { - break; + static constexpr Format info(GL_DEPTH24_STENCIL8, + angle::Format::ID::D24_UNORM_S8_UINT, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_UNKNOWN, + GL_RGBA32F, + nullptr); + return info; } } case GL_DEPTH32F_STENCIL8: { - if (OnlyFL9_3(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R32G8X24_TYPELESS, - DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_D32_FLOAT_S8X24_UINT); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_DEPTH32F_STENCIL8, + angle::Format::ID::D32_FLOAT_S8X24_UINT, + DXGI_FORMAT_R32G8X24_TYPELESS, + DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D32_FLOAT_S8X24_UINT, + DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, + GL_RGBA32F, + nullptr); + return info; } case GL_DEPTH_COMPONENT16: { - if (OnlyFL9_3(renderer11DeviceCaps)) + if (OnlyFL10Plus(deviceCaps)) { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_D16_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_D16_UNORM); - return textureFormat; - } - else if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R16_TYPELESS, - DXGI_FORMAT_R16_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_D16_UNORM); - return textureFormat; + static constexpr Format info(GL_DEPTH_COMPONENT16, + angle::Format::ID::D16_UNORM, + DXGI_FORMAT_R16_TYPELESS, + DXGI_FORMAT_R16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D16_UNORM, + DXGI_FORMAT_R16_UNORM, + GL_RGBA16_EXT, + nullptr); + return info; } else { - break; + static constexpr Format info(GL_DEPTH_COMPONENT16, + angle::Format::ID::D16_UNORM, + DXGI_FORMAT_D16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D16_UNORM, + DXGI_FORMAT_UNKNOWN, + GL_RGBA16_EXT, + nullptr); + return info; } } case GL_DEPTH_COMPONENT24: { - if (OnlyFL9_3(renderer11DeviceCaps)) + if (OnlyFL10Plus(deviceCaps)) { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_D24_UNORM_S8_UINT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_D24_UNORM_S8_UINT); - return textureFormat; - } - else if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R24G8_TYPELESS, - DXGI_FORMAT_R24_UNORM_X8_TYPELESS, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_D24_UNORM_S8_UINT); - return textureFormat; + static constexpr Format info(GL_DEPTH_COMPONENT24, + angle::Format::ID::D24_UNORM_S8_UINT, + DXGI_FORMAT_R24G8_TYPELESS, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + GL_RGBA32F, + nullptr); + return info; } else { - break; + static constexpr Format info(GL_DEPTH_COMPONENT24, + angle::Format::ID::D24_UNORM_S8_UINT, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_UNKNOWN, + GL_RGBA32F, + nullptr); + return info; } } case GL_DEPTH_COMPONENT32F: { - if (OnlyFL9_3(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R32_TYPELESS, - DXGI_FORMAT_R32_FLOAT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_D32_FLOAT); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_DEPTH_COMPONENT32F, + angle::Format::ID::D32_FLOAT, + DXGI_FORMAT_R32_TYPELESS, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D32_FLOAT, + DXGI_FORMAT_R32_FLOAT, + GL_RGBA32F, + nullptr); + return info; } case GL_DEPTH_COMPONENT32_OES: { - if (OnlyFL10Plus(renderer11DeviceCaps)) + if (OnlyFL10Plus(deviceCaps)) { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R24G8_TYPELESS, - DXGI_FORMAT_R24_UNORM_X8_TYPELESS, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_D24_UNORM_S8_UINT); - return textureFormat; + static constexpr Format info(GL_DEPTH_COMPONENT32_OES, + angle::Format::ID::D24_UNORM_S8_UINT, + DXGI_FORMAT_R24G8_TYPELESS, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + GL_RGBA32F, + nullptr); + return info; } else { - break; + static constexpr Format info(GL_DEPTH_COMPONENT32_OES, + angle::Format::ID::D24_UNORM_S8_UINT, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_UNKNOWN, + GL_RGBA32F, + nullptr); + return info; } } case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_BC1_UNORM, - DXGI_FORMAT_BC1_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_ETC1_RGB8_LOSSY_DECODE_ANGLE, + angle::Format::ID::BC1_RGB_UNORM_BLOCK, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_BC1_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_BC1_UNORM, + GL_RGBA8, + nullptr); + return info; } case GL_ETC1_RGB8_OES: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } - } - case GL_LUMINANCE: - { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_ETC1_RGB8_OES, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + Initialize4ComponentData); + return info; } case GL_LUMINANCE16F_EXT: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R16G16B16A16_FLOAT, - DXGI_FORMAT_R16G16B16A16_FLOAT, - DXGI_FORMAT_R16G16B16A16_FLOAT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_LUMINANCE16F_EXT, + angle::Format::ID::R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_FLOAT, + GL_RGBA16F, + Initialize4ComponentData); + return info; } case GL_LUMINANCE32F_EXT: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_LUMINANCE32F_EXT, + angle::Format::ID::R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_FLOAT, + GL_RGBA32F, + Initialize4ComponentData); + return info; } case GL_LUMINANCE8_ALPHA8_EXT: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_LUMINANCE8_ALPHA8_EXT, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + nullptr); + return info; } case GL_LUMINANCE8_EXT: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } - } - case GL_LUMINANCE_ALPHA: - { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_LUMINANCE8_EXT, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + Initialize4ComponentData); + return info; } case GL_LUMINANCE_ALPHA16F_EXT: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R16G16B16A16_FLOAT, - DXGI_FORMAT_R16G16B16A16_FLOAT, - DXGI_FORMAT_R16G16B16A16_FLOAT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_LUMINANCE_ALPHA16F_EXT, + angle::Format::ID::R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_FLOAT, + GL_RGBA16F, + nullptr); + return info; } case GL_LUMINANCE_ALPHA32F_EXT: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_LUMINANCE_ALPHA32F_EXT, + angle::Format::ID::R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_FLOAT, + GL_RGBA32F, + nullptr); + return info; } case GL_NONE: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_NONE, + angle::Format::ID::NONE, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + GL_NONE, + nullptr); + return info; } case GL_R11F_G11F_B10F: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R11G11B10_FLOAT, - DXGI_FORMAT_R11G11B10_FLOAT, - DXGI_FORMAT_R11G11B10_FLOAT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_R11F_G11F_B10F, + angle::Format::ID::R11G11B10_FLOAT, + DXGI_FORMAT_R11G11B10_FLOAT, + DXGI_FORMAT_R11G11B10_FLOAT, + DXGI_FORMAT_R11G11B10_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R11G11B10_FLOAT, + GL_RGBA16F_EXT, + nullptr); + return info; } case GL_R16F: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R16_FLOAT, - DXGI_FORMAT_R16_FLOAT, - DXGI_FORMAT_R16_FLOAT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_R16F, + angle::Format::ID::R16_FLOAT, + DXGI_FORMAT_R16_FLOAT, + DXGI_FORMAT_R16_FLOAT, + DXGI_FORMAT_R16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_FLOAT, + GL_RGBA16F_EXT, + nullptr); + return info; } case GL_R16I: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R16_SINT, - DXGI_FORMAT_R16_SINT, - DXGI_FORMAT_R16_SINT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_R16I, + angle::Format::ID::R16_SINT, + DXGI_FORMAT_R16_SINT, + DXGI_FORMAT_R16_SINT, + DXGI_FORMAT_R16_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_SINT, + GL_RGBA16I, + nullptr); + return info; } case GL_R16UI: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R16_UINT, - DXGI_FORMAT_R16_UINT, - DXGI_FORMAT_R16_UINT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_R16UI, + angle::Format::ID::R16_UINT, + DXGI_FORMAT_R16_UINT, + DXGI_FORMAT_R16_UINT, + DXGI_FORMAT_R16_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_UINT, + GL_RGBA16I, + nullptr); + return info; + } + case GL_R16_EXT: + { + static constexpr Format info(GL_R16_EXT, + angle::Format::ID::R16_UNORM, + DXGI_FORMAT_R16_UNORM, + DXGI_FORMAT_R16_UNORM, + DXGI_FORMAT_R16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_UNORM, + GL_RGBA16_EXT, + nullptr); + return info; + } + case GL_R16_SNORM_EXT: + { + static constexpr Format info(GL_R16_SNORM_EXT, + angle::Format::ID::R16_SNORM, + DXGI_FORMAT_R16_SNORM, + DXGI_FORMAT_R16_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16_SNORM, + GL_RGBA16_SNORM_EXT, + nullptr); + return info; } case GL_R32F: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R32_FLOAT, - DXGI_FORMAT_R32_FLOAT, - DXGI_FORMAT_R32_FLOAT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_R32F, + angle::Format::ID::R32_FLOAT, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32_FLOAT, + GL_RGBA32F, + nullptr); + return info; } case GL_R32I: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R32_SINT, - DXGI_FORMAT_R32_SINT, - DXGI_FORMAT_R32_SINT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_R32I, + angle::Format::ID::R32_SINT, + DXGI_FORMAT_R32_SINT, + DXGI_FORMAT_R32_SINT, + DXGI_FORMAT_R32_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32_SINT, + GL_RGBA32I, + nullptr); + return info; } case GL_R32UI: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R32_UINT, - DXGI_FORMAT_R32_UINT, - DXGI_FORMAT_R32_UINT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_R32UI, + angle::Format::ID::R32_UINT, + DXGI_FORMAT_R32_UINT, + DXGI_FORMAT_R32_UINT, + DXGI_FORMAT_R32_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32_UINT, + GL_RGBA32I, + nullptr); + return info; } case GL_R8: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8_UNORM, - DXGI_FORMAT_R8_UNORM, - DXGI_FORMAT_R8_UNORM, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_R8, + angle::Format::ID::R8_UNORM, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_R8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_UNORM, + GL_RGBA8, + nullptr); + return info; } case GL_R8I: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8_SINT, - DXGI_FORMAT_R8_SINT, - DXGI_FORMAT_R8_SINT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_R8I, + angle::Format::ID::R8_SINT, + DXGI_FORMAT_R8_SINT, + DXGI_FORMAT_R8_SINT, + DXGI_FORMAT_R8_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_SINT, + GL_RGBA8I, + nullptr); + return info; } case GL_R8UI: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8_UINT, - DXGI_FORMAT_R8_UINT, - DXGI_FORMAT_R8_UINT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_R8UI, + angle::Format::ID::R8_UINT, + DXGI_FORMAT_R8_UINT, + DXGI_FORMAT_R8_UINT, + DXGI_FORMAT_R8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_UINT, + GL_RGBA8I, + nullptr); + return info; } case GL_R8_SNORM: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8_SNORM, - DXGI_FORMAT_R8_SNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_R8_SNORM, + angle::Format::ID::R8_SNORM, + DXGI_FORMAT_R8_SNORM, + DXGI_FORMAT_R8_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8_SNORM, + GL_RGBA8_SNORM, + nullptr); + return info; } case GL_RG16F: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R16G16_FLOAT, - DXGI_FORMAT_R16G16_FLOAT, - DXGI_FORMAT_R16G16_FLOAT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RG16F, + angle::Format::ID::R16G16_FLOAT, + DXGI_FORMAT_R16G16_FLOAT, + DXGI_FORMAT_R16G16_FLOAT, + DXGI_FORMAT_R16G16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_FLOAT, + GL_RGBA16F_EXT, + nullptr); + return info; } case GL_RG16I: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R16G16_SINT, - DXGI_FORMAT_R16G16_SINT, - DXGI_FORMAT_R16G16_SINT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RG16I, + angle::Format::ID::R16G16_SINT, + DXGI_FORMAT_R16G16_SINT, + DXGI_FORMAT_R16G16_SINT, + DXGI_FORMAT_R16G16_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_SINT, + GL_RGBA16I, + nullptr); + return info; } case GL_RG16UI: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R16G16_UINT, - DXGI_FORMAT_R16G16_UINT, - DXGI_FORMAT_R16G16_UINT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RG16UI, + angle::Format::ID::R16G16_UINT, + DXGI_FORMAT_R16G16_UINT, + DXGI_FORMAT_R16G16_UINT, + DXGI_FORMAT_R16G16_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_UINT, + GL_RGBA16I, + nullptr); + return info; + } + case GL_RG16_EXT: + { + static constexpr Format info(GL_RG16_EXT, + angle::Format::ID::R16G16_UNORM, + DXGI_FORMAT_R16G16_UNORM, + DXGI_FORMAT_R16G16_UNORM, + DXGI_FORMAT_R16G16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_UNORM, + GL_RGBA16_EXT, + nullptr); + return info; + } + case GL_RG16_SNORM_EXT: + { + static constexpr Format info(GL_RG16_SNORM_EXT, + angle::Format::ID::R16G16_SNORM, + DXGI_FORMAT_R16G16_SNORM, + DXGI_FORMAT_R16G16_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16_SNORM, + GL_RGBA16_SNORM_EXT, + nullptr); + return info; } case GL_RG32F: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R32G32_FLOAT, - DXGI_FORMAT_R32G32_FLOAT, - DXGI_FORMAT_R32G32_FLOAT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RG32F, + angle::Format::ID::R32G32_FLOAT, + DXGI_FORMAT_R32G32_FLOAT, + DXGI_FORMAT_R32G32_FLOAT, + DXGI_FORMAT_R32G32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32_FLOAT, + GL_RGBA32F, + nullptr); + return info; } case GL_RG32I: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R32G32_SINT, - DXGI_FORMAT_R32G32_SINT, - DXGI_FORMAT_R32G32_SINT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RG32I, + angle::Format::ID::R32G32_SINT, + DXGI_FORMAT_R32G32_SINT, + DXGI_FORMAT_R32G32_SINT, + DXGI_FORMAT_R32G32_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32_SINT, + GL_RGBA32I, + nullptr); + return info; } case GL_RG32UI: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R32G32_UINT, - DXGI_FORMAT_R32G32_UINT, - DXGI_FORMAT_R32G32_UINT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RG32UI, + angle::Format::ID::R32G32_UINT, + DXGI_FORMAT_R32G32_UINT, + DXGI_FORMAT_R32G32_UINT, + DXGI_FORMAT_R32G32_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32_UINT, + GL_RGBA32I, + nullptr); + return info; } case GL_RG8: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8_UNORM, - DXGI_FORMAT_R8G8_UNORM, - DXGI_FORMAT_R8G8_UNORM, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RG8, + angle::Format::ID::R8G8_UNORM, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_R8G8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_UNORM, + GL_RGBA8, + nullptr); + return info; } case GL_RG8I: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8_SINT, - DXGI_FORMAT_R8G8_SINT, - DXGI_FORMAT_R8G8_SINT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RG8I, + angle::Format::ID::R8G8_SINT, + DXGI_FORMAT_R8G8_SINT, + DXGI_FORMAT_R8G8_SINT, + DXGI_FORMAT_R8G8_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_SINT, + GL_RGBA8I, + nullptr); + return info; } case GL_RG8UI: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8_UINT, - DXGI_FORMAT_R8G8_UINT, - DXGI_FORMAT_R8G8_UINT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RG8UI, + angle::Format::ID::R8G8_UINT, + DXGI_FORMAT_R8G8_UINT, + DXGI_FORMAT_R8G8_UINT, + DXGI_FORMAT_R8G8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_UINT, + GL_RGBA8I, + nullptr); + return info; } case GL_RG8_SNORM: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8_SNORM, - DXGI_FORMAT_R8G8_SNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RG8_SNORM, + angle::Format::ID::R8G8_SNORM, + DXGI_FORMAT_R8G8_SNORM, + DXGI_FORMAT_R8G8_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8_SNORM, + GL_RGBA8_SNORM, + nullptr); + return info; } case GL_RGB: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RGB, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + Initialize4ComponentData); + return info; } case GL_RGB10_A2: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R10G10B10A2_UNORM, - DXGI_FORMAT_R10G10B10A2_UNORM, - DXGI_FORMAT_R10G10B10A2_UNORM, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RGB10_A2, + angle::Format::ID::R10G10B10A2_UNORM, + DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_R10G10B10A2_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R10G10B10A2_UNORM, + GL_RGBA16_EXT, + nullptr); + return info; } case GL_RGB10_A2UI: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R10G10B10A2_UINT, - DXGI_FORMAT_R10G10B10A2_UINT, - DXGI_FORMAT_R10G10B10A2_UINT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RGB10_A2UI, + angle::Format::ID::R10G10B10A2_UINT, + DXGI_FORMAT_R10G10B10A2_UINT, + DXGI_FORMAT_R10G10B10A2_UINT, + DXGI_FORMAT_R10G10B10A2_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R10G10B10A2_UINT, + GL_RGBA16I, + nullptr); + return info; } case GL_RGB16F: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R16G16B16A16_FLOAT, - DXGI_FORMAT_R16G16B16A16_FLOAT, - DXGI_FORMAT_R16G16B16A16_FLOAT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RGB16F, + angle::Format::ID::R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_FLOAT, + GL_RGBA16F, + Initialize4ComponentData); + return info; } case GL_RGB16I: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R16G16B16A16_SINT, - DXGI_FORMAT_R16G16B16A16_SINT, - DXGI_FORMAT_R16G16B16A16_SINT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RGB16I, + angle::Format::ID::R16G16B16A16_SINT, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_SINT, + GL_RGBA16I, + Initialize4ComponentData); + return info; } case GL_RGB16UI: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R16G16B16A16_UINT, - DXGI_FORMAT_R16G16B16A16_UINT, - DXGI_FORMAT_R16G16B16A16_UINT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RGB16UI, + angle::Format::ID::R16G16B16A16_UINT, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_UINT, + GL_RGBA16UI, + Initialize4ComponentData); + return info; + } + case GL_RGB16_EXT: + { + static constexpr Format info(GL_RGB16_EXT, + angle::Format::ID::R16G16B16A16_UNORM, + DXGI_FORMAT_R16G16B16A16_UNORM, + DXGI_FORMAT_R16G16B16A16_UNORM, + DXGI_FORMAT_R16G16B16A16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_UNORM, + GL_RGBA16_EXT, + Initialize4ComponentData); + return info; + } + case GL_RGB16_SNORM_EXT: + { + static constexpr Format info(GL_RGB16_SNORM_EXT, + angle::Format::ID::R16G16B16A16_SNORM, + DXGI_FORMAT_R16G16B16A16_SNORM, + DXGI_FORMAT_R16G16B16A16_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_SNORM, + GL_RGBA16_SNORM_EXT, + Initialize4ComponentData); + return info; } case GL_RGB32F: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RGB32F, + angle::Format::ID::R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_FLOAT, + GL_RGBA32F, + Initialize4ComponentData); + return info; } case GL_RGB32I: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R32G32B32A32_SINT, - DXGI_FORMAT_R32G32B32A32_SINT, - DXGI_FORMAT_R32G32B32A32_SINT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RGB32I, + angle::Format::ID::R32G32B32A32_SINT, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_SINT, + GL_RGBA32I, + Initialize4ComponentData); + return info; } case GL_RGB32UI: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R32G32B32A32_UINT, - DXGI_FORMAT_R32G32B32A32_UINT, - DXGI_FORMAT_R32G32B32A32_UINT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RGB32UI, + angle::Format::ID::R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_UINT, + GL_RGBA32UI, + Initialize4ComponentData); + return info; } case GL_RGB565: { - if (SupportsFormat(renderer11DeviceCaps)) + if (SupportsFormat(DXGI_FORMAT_B5G6R5_UNORM, deviceCaps)) { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else if (SupportsFormat(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_B5G6R5_UNORM, - DXGI_FORMAT_B5G6R5_UNORM, - DXGI_FORMAT_B5G6R5_UNORM, - DXGI_FORMAT_UNKNOWN); - return textureFormat; + static constexpr Format info(GL_RGB565, + angle::Format::ID::B5G6R5_UNORM, + DXGI_FORMAT_B5G6R5_UNORM, + DXGI_FORMAT_B5G6R5_UNORM, + DXGI_FORMAT_B5G6R5_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B5G6R5_UNORM, + GL_RGBA8, + nullptr); + return info; } else { - break; + static constexpr Format info(GL_RGB565, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + Initialize4ComponentData); + return info; } } case GL_RGB5_A1: { - if (SupportsFormat(renderer11DeviceCaps)) + if (SupportsFormat(DXGI_FORMAT_B5G5R5A1_UNORM, deviceCaps)) { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else if (SupportsFormat(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_B5G5R5A1_UNORM, - DXGI_FORMAT_B5G5R5A1_UNORM, - DXGI_FORMAT_B5G5R5A1_UNORM, - DXGI_FORMAT_UNKNOWN); - return textureFormat; + static constexpr Format info(GL_RGB5_A1, + angle::Format::ID::B5G5R5A1_UNORM, + DXGI_FORMAT_B5G5R5A1_UNORM, + DXGI_FORMAT_B5G5R5A1_UNORM, + DXGI_FORMAT_B5G5R5A1_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B5G5R5A1_UNORM, + GL_RGBA8, + nullptr); + return info; } else { - break; + static constexpr Format info(GL_RGB5_A1, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + nullptr); + return info; } } case GL_RGB8: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RGB8, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + Initialize4ComponentData); + return info; } case GL_RGB8I: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_SINT, - DXGI_FORMAT_R8G8B8A8_SINT, - DXGI_FORMAT_R8G8B8A8_SINT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RGB8I, + angle::Format::ID::R8G8B8A8_SINT, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_SINT, + GL_RGBA8I, + Initialize4ComponentData); + return info; } case GL_RGB8UI: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_UINT, - DXGI_FORMAT_R8G8B8A8_UINT, - DXGI_FORMAT_R8G8B8A8_UINT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RGB8UI, + angle::Format::ID::R8G8B8A8_UINT, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UINT, + GL_RGBA8UI, + Initialize4ComponentData); + return info; } case GL_RGB8_SNORM: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_SNORM, - DXGI_FORMAT_R8G8B8A8_SNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RGB8_SNORM, + angle::Format::ID::R8G8B8A8_SNORM, + DXGI_FORMAT_R8G8B8A8_SNORM, + DXGI_FORMAT_R8G8B8A8_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_SNORM, + GL_RGBA8_SNORM, + Initialize4ComponentData); + return info; } case GL_RGB9_E5: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R9G9B9E5_SHAREDEXP, - DXGI_FORMAT_R9G9B9E5_SHAREDEXP, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RGB9_E5, + angle::Format::ID::R9G9B9E5_SHAREDEXP, + DXGI_FORMAT_R9G9B9E5_SHAREDEXP, + DXGI_FORMAT_R9G9B9E5_SHAREDEXP, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R9G9B9E5_SHAREDEXP, + GL_RGBA16F_EXT, + nullptr); + return info; } case GL_RGBA: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RGBA, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + nullptr); + return info; } case GL_RGBA16F: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R16G16B16A16_FLOAT, - DXGI_FORMAT_R16G16B16A16_FLOAT, - DXGI_FORMAT_R16G16B16A16_FLOAT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RGBA16F, + angle::Format::ID::R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_FLOAT, + GL_RGBA16F, + nullptr); + return info; } case GL_RGBA16I: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R16G16B16A16_SINT, - DXGI_FORMAT_R16G16B16A16_SINT, - DXGI_FORMAT_R16G16B16A16_SINT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RGBA16I, + angle::Format::ID::R16G16B16A16_SINT, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_R16G16B16A16_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_SINT, + GL_RGBA16I, + nullptr); + return info; } case GL_RGBA16UI: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R16G16B16A16_UINT, - DXGI_FORMAT_R16G16B16A16_UINT, - DXGI_FORMAT_R16G16B16A16_UINT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RGBA16UI, + angle::Format::ID::R16G16B16A16_UINT, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_R16G16B16A16_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_UINT, + GL_RGBA16UI, + nullptr); + return info; + } + case GL_RGBA16_EXT: + { + static constexpr Format info(GL_RGBA16_EXT, + angle::Format::ID::R16G16B16A16_UNORM, + DXGI_FORMAT_R16G16B16A16_UNORM, + DXGI_FORMAT_R16G16B16A16_UNORM, + DXGI_FORMAT_R16G16B16A16_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_UNORM, + GL_RGBA16_EXT, + nullptr); + return info; + } + case GL_RGBA16_SNORM_EXT: + { + static constexpr Format info(GL_RGBA16_SNORM_EXT, + angle::Format::ID::R16G16B16A16_SNORM, + DXGI_FORMAT_R16G16B16A16_SNORM, + DXGI_FORMAT_R16G16B16A16_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R16G16B16A16_SNORM, + GL_RGBA16_SNORM_EXT, + nullptr); + return info; } case GL_RGBA32F: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RGBA32F, + angle::Format::ID::R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_FLOAT, + GL_RGBA32F, + nullptr); + return info; } case GL_RGBA32I: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R32G32B32A32_SINT, - DXGI_FORMAT_R32G32B32A32_SINT, - DXGI_FORMAT_R32G32B32A32_SINT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RGBA32I, + angle::Format::ID::R32G32B32A32_SINT, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_R32G32B32A32_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_SINT, + GL_RGBA32I, + nullptr); + return info; } case GL_RGBA32UI: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R32G32B32A32_UINT, - DXGI_FORMAT_R32G32B32A32_UINT, - DXGI_FORMAT_R32G32B32A32_UINT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RGBA32UI, + angle::Format::ID::R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_R32G32B32A32_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R32G32B32A32_UINT, + GL_RGBA32UI, + nullptr); + return info; } case GL_RGBA4: { - if (SupportsFormat(renderer11DeviceCaps)) + if (SupportsFormat(DXGI_FORMAT_B4G4R4A4_UNORM, deviceCaps)) { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else if (SupportsFormat(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_B4G4R4A4_UNORM, - DXGI_FORMAT_B4G4R4A4_UNORM, - DXGI_FORMAT_B4G4R4A4_UNORM, - DXGI_FORMAT_UNKNOWN); - return textureFormat; + static constexpr Format info(GL_RGBA4, + angle::Format::ID::B4G4R4A4_UNORM, + DXGI_FORMAT_B4G4R4A4_UNORM, + DXGI_FORMAT_B4G4R4A4_UNORM, + DXGI_FORMAT_B4G4R4A4_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_B4G4R4A4_UNORM, + GL_RGBA4, + nullptr); + return info; } else { - break; + static constexpr Format info(GL_RGBA4, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + nullptr); + return info; } } case GL_RGBA8: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RGBA8, + angle::Format::ID::R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM, + GL_RGBA8, + nullptr); + return info; } case GL_RGBA8I: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_SINT, - DXGI_FORMAT_R8G8B8A8_SINT, - DXGI_FORMAT_R8G8B8A8_SINT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RGBA8I, + angle::Format::ID::R8G8B8A8_SINT, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_R8G8B8A8_SINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_SINT, + GL_RGBA8I, + nullptr); + return info; } case GL_RGBA8UI: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_UINT, - DXGI_FORMAT_R8G8B8A8_UINT, - DXGI_FORMAT_R8G8B8A8_UINT, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RGBA8UI, + angle::Format::ID::R8G8B8A8_UINT, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_R8G8B8A8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UINT, + GL_RGBA8UI, + nullptr); + return info; } case GL_RGBA8_SNORM: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_SNORM, - DXGI_FORMAT_R8G8B8A8_SNORM, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_RGBA8_SNORM, + angle::Format::ID::R8G8B8A8_SNORM, + DXGI_FORMAT_R8G8B8A8_SNORM, + DXGI_FORMAT_R8G8B8A8_SNORM, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_SNORM, + GL_RGBA8_SNORM, + nullptr); + return info; } case GL_SRGB8: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, - DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_SRGB8, + angle::Format::ID::R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + GL_SRGB8_ALPHA8, + Initialize4ComponentData); + return info; } case GL_SRGB8_ALPHA8: { - if (AnyDevice(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, - DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, - DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, - DXGI_FORMAT_UNKNOWN); - return textureFormat; - } - else - { - break; - } + static constexpr Format info(GL_SRGB8_ALPHA8, + angle::Format::ID::R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + GL_SRGB8_ALPHA8, + nullptr); + return info; } case GL_STENCIL_INDEX8: { - if (OnlyFL9_3(renderer11DeviceCaps)) + if (OnlyFL10Plus(deviceCaps)) { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_D24_UNORM_S8_UINT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_D24_UNORM_S8_UINT); - return textureFormat; - } - else if (OnlyFL10Plus(renderer11DeviceCaps)) - { - static const TextureFormat textureFormat = GetD3D11FormatInfo(internalFormat, - DXGI_FORMAT_R24G8_TYPELESS, - DXGI_FORMAT_X24_TYPELESS_G8_UINT, - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_D24_UNORM_S8_UINT); - return textureFormat; + static constexpr Format info(GL_STENCIL_INDEX8, + angle::Format::ID::D24_UNORM_S8_UINT, + DXGI_FORMAT_R24G8_TYPELESS, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS, + GL_RGBA32F, + nullptr); + return info; } else { - break; + static constexpr Format info(GL_STENCIL_INDEX8, + angle::Format::ID::D24_UNORM_S8_UINT, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_UNKNOWN, + GL_RGBA32F, + nullptr); + return info; } } @@ -1782,9 +1928,10 @@ const TextureFormat &GetTextureFormatInfo(GLenum internalFormat, } // clang-format on - static const TextureFormat defaultInfo; + UNREACHABLE(); + static constexpr Format defaultInfo; return defaultInfo; -} // GetTextureFormatInfo +} } // namespace d3d11 diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_utils.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_utils.h new file mode 100644 index 0000000000..d5351ff882 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/texture_format_table_utils.h @@ -0,0 +1,85 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Helper routines for the D3D11 texture format table. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_TEXTURE_FORMAT_TABLE_UTILS_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_TEXTURE_FORMAT_TABLE_UTILS_H_ + +#include "libANGLE/renderer/d3d/d3d11/Renderer11.h" + +namespace rx +{ + +namespace d3d11 +{ + +using FormatSupportFunction = bool (*)(const Renderer11DeviceCaps &); + +inline bool OnlyFL10Plus(const Renderer11DeviceCaps &deviceCaps) +{ + return (deviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_0); +} + +inline bool OnlyFL9_3(const Renderer11DeviceCaps &deviceCaps) +{ + return (deviceCaps.featureLevel == D3D_FEATURE_LEVEL_9_3); +} + +inline bool SupportsFormat(DXGI_FORMAT format, const Renderer11DeviceCaps &deviceCaps) +{ + // Must support texture, SRV and RTV support + UINT mustSupport = D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURECUBE | + D3D11_FORMAT_SUPPORT_SHADER_SAMPLE | D3D11_FORMAT_SUPPORT_MIP | + D3D11_FORMAT_SUPPORT_RENDER_TARGET; + UINT minimumRequiredSamples = 0; + + if (d3d11_gl::GetMaximumClientVersion(deviceCaps.featureLevel).major > 2) + { + mustSupport |= D3D11_FORMAT_SUPPORT_TEXTURE3D; + + // RGBA4, RGB5A1 and RGB565 are all required multisampled renderbuffer formats in ES3 and + // need to support a minimum of 4 samples. + minimumRequiredSamples = 4; + } + + bool fullSupport = false; + if (format == DXGI_FORMAT_B5G6R5_UNORM) + { + // All hardware that supports DXGI_FORMAT_B5G6R5_UNORM should support autogen mipmaps, but + // check anyway. + mustSupport |= D3D11_FORMAT_SUPPORT_MIP_AUTOGEN; + fullSupport = ((deviceCaps.B5G6R5support & mustSupport) == mustSupport) && + deviceCaps.B5G6R5maxSamples >= minimumRequiredSamples; + } + else if (format == DXGI_FORMAT_B4G4R4A4_UNORM) + { + fullSupport = ((deviceCaps.B4G4R4A4support & mustSupport) == mustSupport) && + deviceCaps.B4G4R4A4maxSamples >= minimumRequiredSamples; + } + else if (format == DXGI_FORMAT_B5G5R5A1_UNORM) + { + fullSupport = ((deviceCaps.B5G5R5A1support & mustSupport) == mustSupport) && + deviceCaps.B5G5R5A1maxSamples >= minimumRequiredSamples; + } + else + { + UNREACHABLE(); + return false; + } + + // This means that ANGLE would like to use the entry in the map if the inputted DXGI format + // *IS* supported. + // e.g. the entry might map GL_RGB5_A1 to DXGI_FORMAT_B5G5R5A1, which should only be used if + // DXGI_FORMAT_B5G5R5A1 is supported. + // In this case, we should only return 'true' if the format *IS* supported. + return fullSupport; +} + +} // namespace d3d11 + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_TEXTURE_FORMAT_TABLE_UTILS_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.cpp similarity index 51% rename from src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp rename to src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.cpp index da6460b136..5394e3d3e7 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.cpp @@ -1,76 +1,70 @@ // -// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// NativeWindow.cpp: Handler for managing HWND native window types. +// NativeWindow11Win32.cpp: Implementation of NativeWindow11 using win32 window APIs. -#include "libANGLE/renderer/d3d/d3d11/NativeWindow.h" +#include "libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.h" #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" #include "common/debug.h" #include -#if !defined(__MINGW32__) #include -#endif namespace rx { -NativeWindow::NativeWindow(EGLNativeWindowType window, - const egl::Config *config, - bool directComposition) - : mWindow(window), +NativeWindow11Win32::NativeWindow11Win32(EGLNativeWindowType window, + bool hasAlpha, + bool directComposition) + : NativeWindow11(window), mDirectComposition(directComposition), + mHasAlpha(hasAlpha), mDevice(nullptr), mCompositionTarget(nullptr), - mVisual(nullptr), - mConfig(config) + mVisual(nullptr) { } -NativeWindow::~NativeWindow() +NativeWindow11Win32::~NativeWindow11Win32() { -#if !defined(__MINGW32__) SafeRelease(mCompositionTarget); SafeRelease(mDevice); SafeRelease(mVisual); -#endif } -bool NativeWindow::initialize() +bool NativeWindow11Win32::initialize() { return true; } -bool NativeWindow::getClientRect(LPRECT rect) +bool NativeWindow11Win32::getClientRect(LPRECT rect) const { - return GetClientRect(mWindow, rect) == TRUE; + return GetClientRect(getNativeWindow(), rect) == TRUE; } -bool NativeWindow::isIconic() +bool NativeWindow11Win32::isIconic() const { - return IsIconic(mWindow) == TRUE; + return IsIconic(getNativeWindow()) == TRUE; } -bool NativeWindow::isValidNativeWindow(EGLNativeWindowType window) +HRESULT NativeWindow11Win32::createSwapChain(ID3D11Device *device, + IDXGIFactory *factory, + DXGI_FORMAT format, + UINT width, + UINT height, + UINT samples, + IDXGISwapChain **swapChain) { - return IsWindow(window) == TRUE; -} - -#if defined(ANGLE_ENABLE_D3D11) -HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory, - DXGI_FORMAT format, unsigned int width, unsigned int height, - DXGISwapChain** swapChain) -{ - if (device == NULL || factory == NULL || swapChain == NULL || width == 0 || height == 0) + if (device == nullptr || factory == nullptr || swapChain == nullptr || width == 0 || + height == 0) { return E_INVALIDARG; } -#if !defined(__MINGW32__) if (mDirectComposition) { HMODULE dcomp = ::GetModuleHandle(TEXT("dcomp.dll")); @@ -104,7 +98,8 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory if (!mCompositionTarget) { - HRESULT result = mDevice->CreateTargetForHwnd(mWindow, TRUE, &mCompositionTarget); + HRESULT result = + mDevice->CreateTargetForHwnd(getNativeWindow(), TRUE, &mCompositionTarget); if (FAILED(result)) { return result; @@ -127,21 +122,21 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory swapChainDesc.Format = format; swapChainDesc.Stereo = FALSE; swapChainDesc.SampleDesc.Count = 1; - swapChainDesc.SampleDesc.Quality = 0; + swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER | DXGI_USAGE_SHADER_INPUT; - swapChainDesc.BufferCount = 2; - swapChainDesc.Scaling = DXGI_SCALING_STRETCH; + swapChainDesc.BufferCount = 2; + swapChainDesc.Scaling = DXGI_SCALING_STRETCH; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; swapChainDesc.AlphaMode = - mConfig->alphaSize == 0 ? DXGI_ALPHA_MODE_IGNORE : DXGI_ALPHA_MODE_PREMULTIPLIED; + mHasAlpha ? DXGI_ALPHA_MODE_PREMULTIPLIED : DXGI_ALPHA_MODE_IGNORE; swapChainDesc.Flags = 0; IDXGISwapChain1 *swapChain1 = nullptr; HRESULT result = factory2->CreateSwapChainForComposition(device, &swapChainDesc, nullptr, &swapChain1); if (SUCCEEDED(result)) { - *swapChain = static_cast(swapChain1); + *swapChain = static_cast(swapChain1); } mVisual->SetContent(swapChain1); mCompositionTarget->SetRoot(mVisual); @@ -149,72 +144,74 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory return result; } - // Use IDXGIFactory2::CreateSwapChainForHwnd if DXGI 1.2 is available to create a DXGI_SWAP_EFFECT_SEQUENTIAL swap chain. + // Use IDXGIFactory2::CreateSwapChainForHwnd if DXGI 1.2 is available to create a + // DXGI_SWAP_EFFECT_SEQUENTIAL swap chain. IDXGIFactory2 *factory2 = d3d11::DynamicCastComObject(factory); if (factory2 != nullptr) { - DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 }; - swapChainDesc.Width = width; - swapChainDesc.Height = height; - swapChainDesc.Format = format; - swapChainDesc.Stereo = FALSE; - swapChainDesc.SampleDesc.Count = 1; - swapChainDesc.SampleDesc.Quality = 0; + DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0}; + swapChainDesc.Width = width; + swapChainDesc.Height = height; + swapChainDesc.Format = format; + swapChainDesc.Stereo = FALSE; + swapChainDesc.SampleDesc.Count = samples; + swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_BACK_BUFFER; - swapChainDesc.BufferCount = 1; - swapChainDesc.Scaling = DXGI_SCALING_STRETCH; - swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL; - swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; - swapChainDesc.Flags = 0; + swapChainDesc.BufferCount = 1; + swapChainDesc.Scaling = DXGI_SCALING_STRETCH; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL; + swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; + swapChainDesc.Flags = 0; IDXGISwapChain1 *swapChain1 = nullptr; - HRESULT result = factory2->CreateSwapChainForHwnd(device, mWindow, &swapChainDesc, nullptr, nullptr, &swapChain1); + HRESULT result = factory2->CreateSwapChainForHwnd(device, getNativeWindow(), &swapChainDesc, + nullptr, nullptr, &swapChain1); if (SUCCEEDED(result)) { - const HRESULT makeWindowAssociationResult = factory->MakeWindowAssociation(mWindow, DXGI_MWA_NO_ALT_ENTER); - UNUSED_VARIABLE(makeWindowAssociationResult); - *swapChain = static_cast(swapChain1); + factory2->MakeWindowAssociation(getNativeWindow(), DXGI_MWA_NO_ALT_ENTER); + *swapChain = static_cast(swapChain1); } SafeRelease(factory2); return result; } -#endif // !__MINGW32__ - DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; - swapChainDesc.BufferCount = 1; - swapChainDesc.BufferDesc.Format = format; - swapChainDesc.BufferDesc.Width = width; - swapChainDesc.BufferDesc.Height = height; - swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; - swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; - swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; + DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; + swapChainDesc.BufferCount = 1; + swapChainDesc.BufferDesc.Format = format; + swapChainDesc.BufferDesc.Width = width; + swapChainDesc.BufferDesc.Height = height; + swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_BACK_BUFFER; - swapChainDesc.Flags = 0; - swapChainDesc.OutputWindow = mWindow; - swapChainDesc.SampleDesc.Count = 1; + swapChainDesc.Flags = 0; + swapChainDesc.OutputWindow = getNativeWindow(); + swapChainDesc.SampleDesc.Count = samples; swapChainDesc.SampleDesc.Quality = 0; - swapChainDesc.Windowed = TRUE; - swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + swapChainDesc.Windowed = TRUE; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; - const HRESULT result = factory->CreateSwapChain(device, &swapChainDesc, swapChain); + HRESULT result = factory->CreateSwapChain(device, &swapChainDesc, swapChain); if (SUCCEEDED(result)) { - const HRESULT makeWindowAssociationResult = factory->MakeWindowAssociation(mWindow, DXGI_MWA_NO_ALT_ENTER); - UNUSED_VARIABLE(makeWindowAssociationResult); + factory->MakeWindowAssociation(getNativeWindow(), DXGI_MWA_NO_ALT_ENTER); } return result; } -#endif -void NativeWindow::commitChange() +void NativeWindow11Win32::commitChange() { -#if !defined(__MINGW32__) if (mDevice) { mDevice->Commit(); } -#endif } + +// static +bool NativeWindow11Win32::IsValidNativeWindow(EGLNativeWindowType window) +{ + return IsWindow(window) == TRUE; } +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.h new file mode 100644 index 0000000000..baeba6a347 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.h @@ -0,0 +1,53 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// NativeWindow11Win32.h: Implementation of NativeWindow11 using win32 window APIs. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_WIN32_NATIVEWINDOW11WIN32_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_WIN32_NATIVEWINDOW11WIN32_H_ + +#include "libANGLE/renderer/d3d/d3d11/NativeWindow11.h" + +typedef interface IDCompositionDevice IDCompositionDevice; +typedef interface IDCompositionTarget IDCompositionTarget; +typedef interface IDCompositionVisual IDCompositionVisual; + +namespace rx +{ + +class NativeWindow11Win32 : public NativeWindow11 +{ + public: + NativeWindow11Win32(EGLNativeWindowType window, bool hasAlpha, bool directComposition); + ~NativeWindow11Win32() override; + + bool initialize() override; + bool getClientRect(LPRECT rect) const override; + bool isIconic() const override; + + HRESULT createSwapChain(ID3D11Device *device, + IDXGIFactory *factory, + DXGI_FORMAT format, + UINT width, + UINT height, + UINT samples, + IDXGISwapChain **swapChain) override; + + void commitChange() override; + + static bool IsValidNativeWindow(EGLNativeWindowType window); + + private: + bool mDirectComposition; + bool mHasAlpha; + IDCompositionDevice *mDevice; + IDCompositionTarget *mCompositionTarget; + IDCompositionVisual *mVisual; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_WIN32_NATIVEWINDOW11WIN32_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp index f401db614b..1ef90e7b09 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp @@ -8,6 +8,8 @@ #include "libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h" +#include + using namespace ABI::Windows::Foundation::Collections; namespace rx @@ -19,7 +21,6 @@ CoreWindowNativeWindow::~CoreWindowNativeWindow() bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet *propertySet) { - mOrientationChangedEventToken.value = 0; ComPtr props = propertySet; ComPtr win = window; SIZE swapChainSize = {}; @@ -63,7 +64,8 @@ bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet // A EGLRenderSurfaceSizeProperty and a EGLRenderResolutionScaleProperty can't both be specified if (mSwapChainScaleSpecified && mSwapChainSizeSpecified) { - ERR("It is invalid to specify both an EGLRenderSurfaceSizeProperty and a EGLRenderResolutionScaleProperty."); + ERR() << "It is invalid to specify both an EGLRenderSurfaceSizeProperty and a " + "EGLRenderResolutionScaleProperty."; return false; } } @@ -87,26 +89,16 @@ bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet } else { - SIZE coreWindowSize; + Size coreWindowSize; result = GetCoreWindowSizeInPixels(mCoreWindow, &coreWindowSize); if (SUCCEEDED(result)) { - mClientRect = { 0, 0, static_cast(coreWindowSize.cx * mSwapChainScale), static_cast(coreWindowSize.cy * mSwapChainScale) }; + mClientRect = clientRect(coreWindowSize); } } } - if (SUCCEEDED(result)) - { - ComPtr displayInformation; - result = GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayInformation).Get(), &displayInformation); - if (SUCCEEDED(result)) - { - result = displayInformation->GetForCurrentView(&mDisplayInformation); - } - } - if (SUCCEEDED(result)) { mNewClientRect = mClientRect; @@ -126,16 +118,6 @@ bool CoreWindowNativeWindow::registerForSizeChangeEvents() result = mCoreWindow->add_SizeChanged(sizeChangedHandler.Get(), &mSizeChangedEventToken); } -#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) - ComPtr orientationChangedHandler; - result = sizeChangedHandler.As(&orientationChangedHandler); - if (SUCCEEDED(result)) - { - result = mDisplayInformation->add_OrientationChanged(orientationChangedHandler.Get(), &mOrientationChangedEventToken); - orientationChangedHandler->Invoke(mDisplayInformation.Get(), nullptr); - } -#endif - if (SUCCEEDED(result)) { return true; @@ -150,34 +132,26 @@ void CoreWindowNativeWindow::unregisterForSizeChangeEvents() { (void)mCoreWindow->remove_SizeChanged(mSizeChangedEventToken); } - -#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) - if (mDisplayInformation) - { - (void)mDisplayInformation->remove_OrientationChanged(mOrientationChangedEventToken); - } -#endif - mSizeChangedEventToken.value = 0; - mOrientationChangedEventToken.value = 0; } HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, - DXGIFactory *factory, + IDXGIFactory2 *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, bool containsAlpha, - DXGISwapChain **swapChain) + IDXGISwapChain1 **swapChain) { - if (device == NULL || factory == NULL || swapChain == NULL || width == 0 || height == 0) + if (device == nullptr || factory == nullptr || swapChain == nullptr || width == 0 || + height == 0) { return E_INVALIDARG; } DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 }; - swapChainDesc.Width = mRotationFlags ? height : width; - swapChainDesc.Height = mRotationFlags ? width : height; + swapChainDesc.Width = width; + swapChainDesc.Height = height; swapChainDesc.Format = format; swapChainDesc.Stereo = FALSE; swapChainDesc.SampleDesc.Count = 1; @@ -195,17 +169,6 @@ HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, HRESULT result = factory->CreateSwapChainForCoreWindow(device, mCoreWindow.Get(), &swapChainDesc, nullptr, newSwapChain.ReleaseAndGetAddressOf()); if (SUCCEEDED(result)) { - -#if 0 //(WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) // Qt: allow Windows Phone to resize, but don't modify the backing texture in the swap chain. - // Test if swapchain supports resize. On Windows Phone devices, this will return DXGI_ERROR_UNSUPPORTED. On - // other devices DXGI_ERROR_INVALID_CALL should be returned because the combination of flags passed - // (DXGI_SWAP_CHAIN_FLAG_NONPREROTATED | DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE) are invalid flag combinations. - if (newSwapChain->ResizeBuffers(swapChainDesc.BufferCount, swapChainDesc.Width, swapChainDesc.Height, swapChainDesc.Format, DXGI_SWAP_CHAIN_FLAG_NONPREROTATED | DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE) == DXGI_ERROR_UNSUPPORTED) - { - mSupportsSwapChainResize = false; - } -#endif // (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) - result = newSwapChain.CopyTo(swapChain); } @@ -222,14 +185,16 @@ HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, return result; } -inline HRESULT CoreWindowNativeWindow::scaleSwapChain(const Size &windowSize, const RECT &clientRect) +inline HRESULT CoreWindowNativeWindow::scaleSwapChain(const Size &windowSize, + const RECT &clientRect) { // We don't need to do any additional work to scale CoreWindow swapchains. // Using DXGI_SCALING_STRETCH to create the swapchain above does all the necessary work. return S_OK; } -HRESULT GetCoreWindowSizeInPixels(const ComPtr& coreWindow, SIZE *windowSize) +HRESULT GetCoreWindowSizeInPixels(const ComPtr &coreWindow, + Size *windowSize) { ABI::Windows::Foundation::Rect bounds; HRESULT result = coreWindow->get_Bounds(&bounds); diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h index fc1cd124a1..21855c2c3b 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h @@ -12,10 +12,10 @@ #include "libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h" #include -#include + +#include typedef ABI::Windows::Foundation::__FITypedEventHandler_2_Windows__CUI__CCore__CCoreWindow_Windows__CUI__CCore__CWindowSizeChangedEventArgs_t IWindowSizeChangedEventHandler; -typedef ABI::Windows::Foundation::__FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable_t IDisplayOrientationEventHandler; namespace rx { @@ -26,12 +26,12 @@ class CoreWindowNativeWindow : public InspectableNativeWindow, public std::enabl bool initialize(EGLNativeWindowType window, IPropertySet *propertySet) override; HRESULT createSwapChain(ID3D11Device *device, - DXGIFactory *factory, + IDXGIFactory2 *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, bool containsAlpha, - DXGISwapChain **swapChain) override; + IDXGISwapChain1 **swapChain) override; protected: HRESULT scaleSwapChain(const Size &windowSize, const RECT &clientRect) override; @@ -42,13 +42,11 @@ class CoreWindowNativeWindow : public InspectableNativeWindow, public std::enabl private: ComPtr mCoreWindow; ComPtr> mPropertyMap; - ComPtr mDisplayInformation; - EventRegistrationToken mOrientationChangedEventToken; }; [uuid(7F924F66-EBAE-40E5-A10B-B8F35E245190)] class CoreWindowSizeChangedHandler : - public Microsoft::WRL::RuntimeClass, IWindowSizeChangedEventHandler, IDisplayOrientationEventHandler> + public Microsoft::WRL::RuntimeClass, IWindowSizeChangedEventHandler> { public: CoreWindowSizeChangedHandler() { } @@ -72,47 +70,21 @@ class CoreWindowSizeChangedHandler : ABI::Windows::Foundation::Size windowSize; if (SUCCEEDED(sizeChangedEventArgs->get_Size(&windowSize))) { - host->setNewClientSize(windowSize); + Size windowSizeInPixels = {ConvertDipsToPixels(windowSize.Width), + ConvertDipsToPixels(windowSize.Height)}; + host->setNewClientSize(windowSizeInPixels); } } return S_OK; } - IFACEMETHOD(Invoke)(ABI::Windows::Graphics::Display::IDisplayInformation *displayInformation, IInspectable *) - { - #if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) - NativeWindow::RotationFlags flags = NativeWindow::RotateNone; - ABI::Windows::Graphics::Display::DisplayOrientations orientation; - if (SUCCEEDED(displayInformation->get_CurrentOrientation(&orientation))) - { - switch (orientation) - { - case ABI::Windows::Graphics::Display::DisplayOrientations_Landscape: - flags = NativeWindow::RotateLeft; - break; - case ABI::Windows::Graphics::Display::DisplayOrientations_LandscapeFlipped: - flags = NativeWindow::RotateRight; - break; - default: - break; - } - } - std::shared_ptr host = mHost.lock(); - if (host) - { - host->setRotationFlags(flags); - } - #endif - return S_OK; - } - - private: std::weak_ptr mHost; }; -HRESULT GetCoreWindowSizeInPixels(const ComPtr& coreWindow, SIZE *windowSize); +HRESULT GetCoreWindowSizeInPixels(const ComPtr &coreWindow, + Size *windowSize); } #endif // LIBANGLE_RENDERER_D3D_D3D11_WINRT_COREWINDOWNATIVEWINDOW_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp index aacfadd2f0..1bd796e58f 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp @@ -11,108 +11,6 @@ namespace rx { -NativeWindow::NativeWindow(EGLNativeWindowType window, - const egl::Config *config, - bool directComposition) -{ - mWindow = window; - mConfig = config; -} - -NativeWindow::~NativeWindow() -{ -} - -void NativeWindow::commitChange() -{ -} - -bool NativeWindow::initialize() -{ - // If the native window type is a IPropertySet, extract the - // EGLNativeWindowType (IInspectable) and initialize the - // proper host with this IPropertySet. - ComPtr propertySet; - ComPtr eglNativeWindow; - if (IsEGLConfiguredPropertySet(mWindow, &propertySet, &eglNativeWindow)) - { - // A property set was found and the EGLNativeWindowType was - // retrieved. The mWindow member of the host to must be updated - // to use the EGLNativeWindowType specified in the property set. - // mWindow is treated as a raw pointer not an AddRef'd interface, so - // the old mWindow does not need a Release() before this assignment. - mWindow = eglNativeWindow.Get(); - } - - ComPtr coreWindow; - ComPtr swapChainPanel; - if (IsCoreWindow(mWindow, &coreWindow)) - { - mImpl = std::make_shared(); - if (mImpl) - { - return mImpl->initialize(mWindow, propertySet.Get()); - } - } - else if (IsSwapChainPanel(mWindow, &swapChainPanel)) - { - mImpl = std::make_shared(); - if (mImpl) - { - return mImpl->initialize(mWindow, propertySet.Get()); - } - } - else - { - ERR("Invalid IInspectable EGLNativeWindowType detected. Valid IInspectables include ICoreWindow, ISwapChainPanel and IPropertySet"); - } - - return false; -} - -bool NativeWindow::getClientRect(RECT *rect) -{ - if (mImpl) - { - return mImpl->getClientRect(rect); - } - - return false; -} - -#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) -NativeWindow::RotationFlags NativeWindow::rotationFlags() const -{ - if (mImpl) - { - return mImpl->rotationFlags(); - } - - return NativeWindow::RotateNone; -} -#endif - -bool NativeWindow::isIconic() -{ - return false; -} - -bool NativeWindow::isValidNativeWindow(EGLNativeWindowType window) -{ - return IsValidEGLNativeWindowType(window); -} - -HRESULT NativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain) -{ - if (mImpl) - { - bool containsAlpha = (mConfig->alphaSize > 0); - return mImpl->createSwapChain(device, factory, format, width, height, containsAlpha, - swapChain); - } - - return E_UNEXPECTED; -} bool IsCoreWindow(EGLNativeWindowType window, ComPtr *coreWindow) { @@ -127,7 +25,7 @@ bool IsCoreWindow(EGLNativeWindowType window, ComPtr> &propertyMap, const wchar_t *propertyName, @@ -381,7 +268,13 @@ HRESULT GetOptionalSinglePropertyValue(const ComPtr(ConvertDipsToPixels(size.Width)), + static_cast(ConvertDipsToPixels(size.Height))}; +} + +float GetLogicalDpi() { ComPtr displayProperties; float dpi = 96.0f; @@ -396,7 +289,7 @@ static float GetLogicalDpi() return dpi; } -long ConvertDipsToPixels(float dips) +float ConvertDipsToPixels(float dips) { static const float dipsPerInch = 96.0f; return lround((dips * GetLogicalDpi() / dipsPerInch)); diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h index 2d58f1c00a..d81c3e5fb9 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h @@ -10,14 +10,18 @@ #ifndef LIBANGLE_RENDERER_D3D_D3D11_WINRT_INSPECTABLENATIVEWINDOW_H_ #define LIBANGLE_RENDERER_D3D_D3D11_WINRT_INSPECTABLENATIVEWINDOW_H_ -#include "libANGLE/renderer/d3d/d3d11/NativeWindow.h" - +#include "common/debug.h" #include "common/platform.h" #include "angle_windowsstore.h" +#include + +#include #include #include +#include +#include using namespace Microsoft::WRL; using namespace Microsoft::WRL::Wrappers; @@ -26,7 +30,8 @@ using namespace ABI::Windows::Foundation::Collections; namespace rx { -long ConvertDipsToPixels(float dips); +float ConvertDipsToPixels(float dips); +float GetLogicalDpi(); class InspectableNativeWindow { @@ -35,24 +40,25 @@ class InspectableNativeWindow mSupportsSwapChainResize(true), mSwapChainSizeSpecified(false), mSwapChainScaleSpecified(false), - mSwapChainScale(1.0f), mClientRectChanged(false), mClientRect({0,0,0,0}), - mNewClientRect({0,0,0,0}), - mRotationFlags(NativeWindow::RotateNone) + mNewClientRect({0,0,0,0}) { mSizeChangedEventToken.value = 0; + mSwapChainScale = 96.0f / GetLogicalDpi(); + if (mSwapChainScale != 1.0f) + mSwapChainScaleSpecified = true; } virtual ~InspectableNativeWindow(){} virtual bool initialize(EGLNativeWindowType window, IPropertySet *propertySet) = 0; virtual HRESULT createSwapChain(ID3D11Device *device, - DXGIFactory *factory, + IDXGIFactory2 *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, bool containsAlpha, - DXGISwapChain **swapChain) = 0; + IDXGISwapChain1 **swapChain) = 0; bool getClientRect(RECT *rect) { @@ -77,8 +83,7 @@ class InspectableNativeWindow // If the swapchain size was specified then we should ignore this call too if (!mSwapChainSizeSpecified) { - // We don't have to check if a swapchain scale was specified here; the default value is 1.0f which will have no effect. - mNewClientRect = { 0, 0, ConvertDipsToPixels(newWindowSize.Width), ConvertDipsToPixels(newWindowSize.Height) }; + mNewClientRect = clientRect(newWindowSize); mClientRectChanged = true; // If a scale was specified, then now is the time to apply the scale matrix for the new swapchain size and window size @@ -97,18 +102,9 @@ class InspectableNativeWindow } } - NativeWindow::RotationFlags rotationFlags() const - { - return mRotationFlags; - } - - void setRotationFlags(NativeWindow::RotationFlags flags) - { - mRotationFlags = flags; - } - protected: virtual HRESULT scaleSwapChain(const Size &windowSize, const RECT &clientRect) = 0; + RECT clientRect(const Size &size); bool mSupportsSwapChainResize; // Support for IDXGISwapChain::ResizeBuffers method bool mSwapChainSizeSpecified; // If an EGLRenderSurfaceSizeProperty was specified @@ -117,12 +113,10 @@ class InspectableNativeWindow RECT mClientRect; RECT mNewClientRect; bool mClientRectChanged; - NativeWindow::RotationFlags mRotationFlags; EventRegistrationToken mSizeChangedEventToken; }; -bool IsValidEGLNativeWindowType(EGLNativeWindowType window); bool IsCoreWindow(EGLNativeWindowType window, ComPtr *coreWindow = nullptr); bool IsSwapChainPanel(EGLNativeWindowType window, ComPtr *swapChainPanel = nullptr); bool IsEGLConfiguredPropertySet(EGLNativeWindowType window, ABI::Windows::Foundation::Collections::IPropertySet **propertySet = nullptr, IInspectable **inspectable = nullptr); diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/NativeWindow11WinRT.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/NativeWindow11WinRT.cpp new file mode 100644 index 0000000000..655b23be83 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/NativeWindow11WinRT.cpp @@ -0,0 +1,126 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// NativeWindow11WinRT.cpp: NativeWindow base class for managing IInspectable native window types. + +#include "libANGLE/renderer/d3d/d3d11/winrt/NativeWindow11WinRT.h" + +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h" +#include "libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h" +#include "libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h" + +using namespace Microsoft::WRL; +using namespace Microsoft::WRL::Wrappers; + +namespace rx +{ +NativeWindow11WinRT::NativeWindow11WinRT(EGLNativeWindowType window, bool hasAlpha) + : NativeWindow11(window), mHasAlpha(hasAlpha) +{ +} + +bool NativeWindow11WinRT::initialize() +{ + EGLNativeWindowType window = getNativeWindow(); + + // If the native window type is a IPropertySet, extract the + // EGLNativeWindowType (IInspectable) and initialize the + // proper host with this IPropertySet. + ComPtr propertySet; + ComPtr eglNativeWindow; + if (IsEGLConfiguredPropertySet(window, &propertySet, &eglNativeWindow)) + { + // A property set was found and the EGLNativeWindowType was + // retrieved. The mWindow member of the host to must be updated + // to use the EGLNativeWindowType specified in the property set. + // mWindow is treated as a raw pointer not an AddRef'd interface, so + // the old mWindow does not need a Release() before this assignment. + window = eglNativeWindow.Get(); + } + + ComPtr coreWindow; + ComPtr swapChainPanel; + if (IsCoreWindow(window, &coreWindow)) + { + mImpl = std::make_shared(); + if (mImpl) + { + return mImpl->initialize(window, propertySet.Get()); + } + } + else if (IsSwapChainPanel(window, &swapChainPanel)) + { + mImpl = std::make_shared(); + if (mImpl) + { + return mImpl->initialize(window, propertySet.Get()); + } + } + else + { + ERR() << "Invalid IInspectable EGLNativeWindowType detected. Valid IInspectables include " + "ICoreWindow, ISwapChainPanel and IPropertySet"; + } + + return false; +} + +bool NativeWindow11WinRT::getClientRect(LPRECT rect) const +{ + if (mImpl) + { + return mImpl->getClientRect(rect); + } + + return false; +} + +bool NativeWindow11WinRT::isIconic() const +{ + return false; +} + +HRESULT NativeWindow11WinRT::createSwapChain(ID3D11Device *device, + IDXGIFactory *factory, + DXGI_FORMAT format, + UINT width, + UINT height, + UINT samples, + IDXGISwapChain **swapChain) +{ + if (mImpl) + { + IDXGIFactory2 *factory2 = d3d11::DynamicCastComObject(factory); + IDXGISwapChain1 *swapChain1 = nullptr; + HRESULT result = + mImpl->createSwapChain(device, factory2, format, width, height, mHasAlpha, &swapChain1); + SafeRelease(factory2); + *swapChain = static_cast(swapChain1); + return result; + } + + return E_UNEXPECTED; +} + +void NativeWindow11WinRT::commitChange() +{ +} + +// static +bool NativeWindow11WinRT::IsValidNativeWindow(EGLNativeWindowType window) +{ + // A Valid EGLNativeWindowType IInspectable can only be: + // + // ICoreWindow + // ISwapChainPanel + // IPropertySet + // + // Anything else will be rejected as an invalid IInspectable. + return IsCoreWindow(window) || IsSwapChainPanel(window) || IsEGLConfiguredPropertySet(window); +} + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/NativeWindow11WinRT.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/NativeWindow11WinRT.h new file mode 100644 index 0000000000..c4ac997a55 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/NativeWindow11WinRT.h @@ -0,0 +1,51 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// NativeWindow11WinRT.h: NativeWindow base class for managing IInspectable native window types. + +#ifndef LIBANGLE_RENDERER_D3D_D3D11_WINRT_NATIVEWINDOW11WINRT_H_ +#define LIBANGLE_RENDERER_D3D_D3D11_WINRT_NATIVEWINDOW11WINRT_H_ + +#include "libANGLE/renderer/d3d/d3d11/NativeWindow11.h" + +#include +#include +#include +#include + +namespace rx +{ +class InspectableNativeWindow; + +class NativeWindow11WinRT : public NativeWindow11 +{ + public: + NativeWindow11WinRT(EGLNativeWindowType window, bool hasAlpha); + + bool initialize() override; + bool getClientRect(LPRECT rect) const override; + bool isIconic() const override; + + HRESULT createSwapChain(ID3D11Device *device, + IDXGIFactory *factory, + DXGI_FORMAT format, + UINT width, + UINT height, + UINT samples, + IDXGISwapChain **swapChain) override; + + void commitChange() override; + + static bool IsValidNativeWindow(EGLNativeWindowType window); + + private: + bool mHasAlpha; + std::shared_ptr mImpl; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D11_WINRT_NATIVEWINDOW11WINRT_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp index 548b4602fd..3425fad95d 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp @@ -49,7 +49,8 @@ HRESULT RunOnUIThread(CODE &&code, const ComPtr &dispatcher) } else { - Event waitEvent(CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS)); + Event waitEvent( + CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS)); if (!waitEvent.IsValid()) { return E_FAIL; @@ -78,7 +79,8 @@ HRESULT RunOnUIThread(CODE &&code, const ComPtr &dispatcher) // unrecoverable state (probably deadlocked). We therefore terminate the application // entirely. This also prevents stack corruption if the async operation is eventually // run. - ERR("Timeout waiting for async action on UI thread. The UI thread might be blocked."); + ERR() + << "Timeout waiting for async action on UI thread. The UI thread might be blocked."; std::terminate(); return E_FAIL; } @@ -132,7 +134,8 @@ bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, IPropert // A EGLRenderSurfaceSizeProperty and a EGLRenderResolutionScaleProperty can't both be specified if (mSwapChainScaleSpecified && mSwapChainSizeSpecified) { - ERR("It is invalid to specify both an EGLRenderSurfaceSizeProperty and a EGLRenderResolutionScaleProperty."); + ERR() << "It is invalid to specify both an EGLRenderSurfaceSizeProperty and a " + "EGLRenderResolutionScaleProperty."; return false; } } @@ -169,17 +172,14 @@ bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, IPropert } else { - SIZE swapChainPanelSize; + Size swapChainPanelSize; result = GetSwapChainPanelSize(mSwapChainPanel, mSwapChainPanelDispatcher, - &swapChainPanelSize, &mSwapChainScale); - if (mSwapChainScale != 1.0f) - mSwapChainScaleSpecified = true; + &swapChainPanelSize); if (SUCCEEDED(result)) { // Update the client rect to account for any swapchain scale factor - mClientRect = { 0, 0, static_cast(ConvertDipsToPixels(swapChainPanelSize.cx * mSwapChainScale)), - static_cast(ConvertDipsToPixels(swapChainPanelSize.cy * mSwapChainScale)) }; + mClientRect = clientRect(swapChainPanelSize); } } } @@ -241,14 +241,15 @@ void SwapChainPanelNativeWindow::unregisterForSizeChangeEvents() } HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, - DXGIFactory *factory, + IDXGIFactory2 *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, bool containsAlpha, - DXGISwapChain **swapChain) + IDXGISwapChain1 **swapChain) { - if (device == NULL || factory == NULL || swapChain == NULL || width == 0 || height == 0) + if (device == nullptr || factory == nullptr || swapChain == nullptr || width == 0 || + height == 0) { return E_INVALIDARG; } @@ -272,6 +273,7 @@ HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, ComPtr newSwapChain; ComPtr swapChainPanelNative; + Size currentPanelSize = {}; HRESULT result = factory->CreateSwapChainForComposition(device, &swapChainDesc, nullptr, newSwapChain.ReleaseAndGetAddressOf()); @@ -306,14 +308,14 @@ HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, { if (mSwapChainSizeSpecified || mSwapChainScaleSpecified) { - ComPtr uiElement; - result = mSwapChainPanel.As(&uiElement); - ASSERT(SUCCEEDED(result)); + result = GetSwapChainPanelSize(mSwapChainPanel, mSwapChainPanelDispatcher, + ¤tPanelSize); - Size currentSize; - result = uiElement->get_RenderSize(¤tSize); - ASSERT(SUCCEEDED(result)); - result = scaleSwapChain(currentSize, mClientRect); + // Scale the swapchain to fit inside the contents of the panel. + if (SUCCEEDED(result)) + { + result = scaleSwapChain(currentPanelSize, mClientRect); + } } } @@ -342,31 +344,14 @@ HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const Size &windowSize, const HRESULT GetSwapChainPanelSize( const ComPtr &swapChainPanel, const ComPtr &dispatcher, - SIZE *windowSize, float *scaleFactor) + Size *windowSize) { ComPtr uiElement; - Size renderSize = {0, 0}; HRESULT result = swapChainPanel.As(&uiElement); if (SUCCEEDED(result)) { result = RunOnUIThread( - [uiElement, &renderSize] - { - return uiElement->get_RenderSize(&renderSize); - }, - dispatcher); - } - - if (SUCCEEDED(result)) - { - long width = ConvertDipsToPixels(renderSize.Width); - long height = ConvertDipsToPixels(renderSize.Height); - *windowSize = { width, height }; - - if (scaleFactor) - { - *scaleFactor = renderSize.Width / width; - } + [uiElement, windowSize] { return uiElement->get_RenderSize(windowSize); }, dispatcher); } return result; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h index 09d87ad523..f9a2fc0e4b 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h @@ -11,6 +11,8 @@ #include "libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h" +#include + namespace rx { class SwapChainPanelNativeWindow : public InspectableNativeWindow, public std::enable_shared_from_this @@ -20,12 +22,12 @@ class SwapChainPanelNativeWindow : public InspectableNativeWindow, public std::e bool initialize(EGLNativeWindowType window, IPropertySet *propertySet) override; HRESULT createSwapChain(ID3D11Device *device, - DXGIFactory *factory, + IDXGIFactory2 *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, bool containsAlpha, - DXGISwapChain **swapChain) override; + IDXGISwapChain1 **swapChain) override; protected: HRESULT scaleSwapChain(const Size &windowSize, const RECT &clientRect) override; @@ -37,7 +39,7 @@ class SwapChainPanelNativeWindow : public InspectableNativeWindow, public std::e ComPtr mSwapChainPanel; ComPtr mSwapChainPanelDispatcher; ComPtr> mPropertyMap; - ComPtr mSwapChain; + ComPtr mSwapChain; }; [uuid(8ACBD974-8187-4508-AD80-AEC77F93CF36)] @@ -86,6 +88,6 @@ class SwapChainPanelSizeChangedHandler : HRESULT GetSwapChainPanelSize( const ComPtr &swapChainPanel, const ComPtr &dispatcher, - SIZE *windowSize, float *scaleFactor); + Size *windowSize); } #endif // LIBANGLE_RENDERER_D3D_D3D11_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp index 2ac8ee3a29..36f2bd0db8 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp @@ -7,6 +7,8 @@ // Blit9.cpp: Surface copy utility class. #include "libANGLE/renderer/d3d/d3d9/Blit9.h" + +#include "libANGLE/renderer/d3d/TextureD3D.h" #include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" #include "libANGLE/renderer/d3d/d3d9/formatutils9.h" #include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h" @@ -20,27 +22,34 @@ namespace { // Precompiled shaders #include "libANGLE/renderer/d3d/d3d9/shaders/compiled/standardvs.h" -#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/flipyvs.h" #include "libANGLE/renderer/d3d/d3d9/shaders/compiled/passthroughps.h" #include "libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceps.h" +#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/luminancepremultps.h" +#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceunmultps.h" #include "libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskps.h" +#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskpremultps.h" +#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskunmultps.h" -const BYTE* const g_shaderCode[] = -{ +const BYTE *const g_shaderCode[] = { g_vs20_standardvs, - g_vs20_flipyvs, g_ps20_passthroughps, g_ps20_luminanceps, - g_ps20_componentmaskps + g_ps20_luminancepremultps, + g_ps20_luminanceunmultps, + g_ps20_componentmaskps, + g_ps20_componentmaskpremultps, + g_ps20_componentmaskunmultps, }; -const size_t g_shaderSize[] = -{ +const size_t g_shaderSize[] = { sizeof(g_vs20_standardvs), - sizeof(g_vs20_flipyvs), sizeof(g_ps20_passthroughps), sizeof(g_ps20_luminanceps), - sizeof(g_ps20_componentmaskps) + sizeof(g_ps20_luminancepremultps), + sizeof(g_ps20_luminanceunmultps), + sizeof(g_ps20_componentmaskps), + sizeof(g_ps20_componentmaskpremultps), + sizeof(g_ps20_componentmaskunmultps), }; } @@ -50,11 +59,11 @@ namespace rx Blit9::Blit9(Renderer9 *renderer) : mRenderer(renderer), mGeometryLoaded(false), - mQuadVertexBuffer(NULL), - mQuadVertexDeclaration(NULL), - mSavedStateBlock(NULL), - mSavedRenderTarget(NULL), - mSavedDepthStencil(NULL) + mQuadVertexBuffer(nullptr), + mQuadVertexDeclaration(nullptr), + mSavedStateBlock(nullptr), + mSavedRenderTarget(nullptr), + mSavedDepthStencil(nullptr) { memset(mCompiledShaders, 0, sizeof(mCompiledShaders)); } @@ -75,7 +84,7 @@ gl::Error Blit9::initialize() { if (mGeometryLoaded) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } static const float quad[] = @@ -88,22 +97,25 @@ gl::Error Blit9::initialize() IDirect3DDevice9 *device = mRenderer->getDevice(); - HRESULT result = device->CreateVertexBuffer(sizeof(quad), D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &mQuadVertexBuffer, NULL); + HRESULT result = device->CreateVertexBuffer(sizeof(quad), D3DUSAGE_WRITEONLY, 0, + D3DPOOL_DEFAULT, &mQuadVertexBuffer, nullptr); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal blit vertex shader, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to create internal blit vertex shader, " + << gl::FmtHR(result); } - void *lockPtr = NULL; + void *lockPtr = nullptr; result = mQuadVertexBuffer->Lock(0, 0, &lockPtr, 0); - if (FAILED(result) || lockPtr == NULL) + if (FAILED(result) || lockPtr == nullptr) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); SafeRelease(mQuadVertexBuffer); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal blit vertex shader, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to lock internal blit vertex shader, " + << gl::FmtHR(result); } memcpy(lockPtr, quad, sizeof(quad)); @@ -121,11 +133,12 @@ gl::Error Blit9::initialize() { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); SafeRelease(mQuadVertexBuffer); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal blit vertex declaration, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to lock internal blit vertex declaration, " + << gl::FmtHR(result); } mGeometryLoaded = true; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } template @@ -137,7 +150,7 @@ gl::Error Blit9::setShader(ShaderId source, const char *profile, D3DShaderType *shader = nullptr; - if (mCompiledShaders[source] != NULL) + if (mCompiledShaders[source] != nullptr) { shader = static_cast(mCompiledShaders[source]); } @@ -145,23 +158,17 @@ gl::Error Blit9::setShader(ShaderId source, const char *profile, { const BYTE* shaderCode = g_shaderCode[source]; size_t shaderSize = g_shaderSize[source]; - - gl::Error error = (mRenderer->*createShader)(reinterpret_cast(shaderCode), shaderSize, &shader); - if (error.isError()) - { - return error; - } - + ANGLE_TRY((mRenderer->*createShader)(reinterpret_cast(shaderCode), shaderSize, &shader)); mCompiledShaders[source] = shader; } HRESULT hr = (device->*setShader)(shader); if (FAILED(hr)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to set shader for blit operation, result: 0x%X.", hr); + return gl::OutOfMemory() << "Failed to set shader for blit operation, " << gl::FmtHR(hr); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Blit9::setVertexShader(ShaderId shader) @@ -188,20 +195,20 @@ RECT Blit9::getSurfaceRect(IDirect3DSurface9 *surface) const return rect; } +gl::Extents Blit9::getSurfaceSize(IDirect3DSurface9 *surface) const +{ + D3DSURFACE_DESC desc; + surface->GetDesc(&desc); + + return gl::Extents(desc.Width, desc.Height, 1); +} + gl::Error Blit9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest) { - gl::Error error = initialize(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(initialize()); - IDirect3DTexture9 *texture = NULL; - error = copySurfaceToTexture(source, getSurfaceRect(source), &texture); - if (error.isError()) - { - return error; - } + IDirect3DBaseTexture9 *texture = nullptr; + ANGLE_TRY(copySurfaceToTexture(source, getSurfaceRect(source), &texture)); IDirect3DDevice9 *device = mRenderer->getDevice(); @@ -210,14 +217,15 @@ gl::Error Blit9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest) device->SetTexture(0, texture); device->SetRenderTarget(0, dest); - setVertexShader(SHADER_VS_STANDARD); - setPixelShader(SHADER_PS_PASSTHROUGH); + ANGLE_TRY(setVertexShader(SHADER_VS_STANDARD)); + ANGLE_TRY(setPixelShader(SHADER_PS_PASSTHROUGH)); setCommonBlitState(); device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - setViewport(getSurfaceRect(dest), gl::Offset(0, 0, 0)); + setViewportAndShaderConstants(getSurfaceRect(source), getSurfaceSize(source), + getSurfaceRect(dest), false); render(); @@ -225,10 +233,56 @@ gl::Error Blit9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest) restoreState(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Blit9::copy2D(const gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, const gl::Offset &destOffset, TextureStorage *storage, GLint level) +gl::Error Blit9::copy2D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const RECT &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) +{ + ANGLE_TRY(initialize()); + + const gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0); + ASSERT(colorbuffer); + + RenderTarget9 *renderTarget9 = nullptr; + ANGLE_TRY(colorbuffer->getRenderTarget(context, &renderTarget9)); + ASSERT(renderTarget9); + + IDirect3DSurface9 *source = renderTarget9->getSurface(); + ASSERT(source); + + IDirect3DSurface9 *destSurface = nullptr; + TextureStorage9 *storage9 = GetAs(storage); + gl::Error error = storage9->getSurfaceLevel(context, GL_TEXTURE_2D, level, true, &destSurface); + if (error.isError()) + { + SafeRelease(source); + return error; + } + ASSERT(destSurface); + + gl::Error result = + copy(source, nullptr, sourceRect, destFormat, destOffset, destSurface, false, false, false); + + SafeRelease(destSurface); + SafeRelease(source); + + return result; +} + +gl::Error Blit9::copyCube(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const RECT &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLenum target, + GLint level) { gl::Error error = initialize(); if (error.isError()) @@ -240,7 +294,7 @@ gl::Error Blit9::copy2D(const gl::Framebuffer *framebuffer, const RECT &sourceRe ASSERT(colorbuffer); RenderTarget9 *renderTarget9 = nullptr; - error = colorbuffer->getRenderTarget(&renderTarget9); + error = colorbuffer->getRenderTarget(context, &renderTarget9); if (error.isError()) { return error; @@ -250,9 +304,9 @@ gl::Error Blit9::copy2D(const gl::Framebuffer *framebuffer, const RECT &sourceRe IDirect3DSurface9 *source = renderTarget9->getSurface(); ASSERT(source); - IDirect3DSurface9 *destSurface = NULL; + IDirect3DSurface9 *destSurface = nullptr; TextureStorage9 *storage9 = GetAs(storage); - error = storage9->getSurfaceLevel(GL_TEXTURE_2D, level, true, &destSurface); + error = storage9->getSurfaceLevel(context, target, level, true, &destSurface); if (error.isError()) { SafeRelease(source); @@ -260,7 +314,8 @@ gl::Error Blit9::copy2D(const gl::Framebuffer *framebuffer, const RECT &sourceRe } ASSERT(destSurface); - gl::Error result = copy(source, sourceRect, destFormat, destOffset, destSurface); + gl::Error result = + copy(source, nullptr, sourceRect, destFormat, destOffset, destSurface, false, false, false); SafeRelease(destSurface); SafeRelease(source); @@ -268,49 +323,69 @@ gl::Error Blit9::copy2D(const gl::Framebuffer *framebuffer, const RECT &sourceRe return result; } -gl::Error Blit9::copyCube(const gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, const gl::Offset &destOffset, TextureStorage *storage, GLenum target, GLint level) +gl::Error Blit9::copyTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + const RECT &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLenum destTarget, + GLint destLevel, + bool flipY, + bool premultiplyAlpha, + bool unmultiplyAlpha) { - gl::Error error = initialize(); + ANGLE_TRY(initialize()); + + const TextureD3D *sourceD3D = GetImplAs(source); + + TextureStorage *sourceStorage = nullptr; + ANGLE_TRY(const_cast(sourceD3D)->getNativeTexture(context, &sourceStorage)); + + TextureStorage9_2D *sourceStorage9 = GetAs(sourceStorage); + ASSERT(sourceStorage9); + + TextureStorage9 *destStorage9 = GetAs(storage); + ASSERT(destStorage9); + + ASSERT(sourceLevel == 0); + IDirect3DBaseTexture9 *sourceTexture = nullptr; + ANGLE_TRY(sourceStorage9->getBaseTexture(context, &sourceTexture)); + + IDirect3DSurface9 *sourceSurface = nullptr; + ANGLE_TRY( + sourceStorage9->getSurfaceLevel(context, GL_TEXTURE_2D, sourceLevel, true, &sourceSurface)); + + IDirect3DSurface9 *destSurface = nullptr; + gl::Error error = + destStorage9->getSurfaceLevel(context, destTarget, destLevel, true, &destSurface); if (error.isError()) { + SafeRelease(sourceSurface); return error; } - const gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0); - ASSERT(colorbuffer); - - RenderTarget9 *renderTarget9 = nullptr; - error = colorbuffer->getRenderTarget(&renderTarget9); - if (error.isError()) - { - return error; - } - ASSERT(renderTarget9); - - IDirect3DSurface9 *source = renderTarget9->getSurface(); - ASSERT(source); - - IDirect3DSurface9 *destSurface = NULL; - TextureStorage9 *storage9 = GetAs(storage); - error = storage9->getSurfaceLevel(target, level, true, &destSurface); - if (error.isError()) - { - SafeRelease(source); - return error; - } - ASSERT(destSurface); - - gl::Error result = copy(source, sourceRect, destFormat, destOffset, destSurface); + error = copy(sourceSurface, sourceTexture, sourceRect, destFormat, destOffset, destSurface, + flipY, premultiplyAlpha, unmultiplyAlpha); + SafeRelease(sourceSurface); SafeRelease(destSurface); - SafeRelease(source); - return result; + return error; } -gl::Error Blit9::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, const gl::Offset &destOffset, IDirect3DSurface9 *dest) +gl::Error Blit9::copy(IDirect3DSurface9 *source, + IDirect3DBaseTexture9 *sourceTexture, + const RECT &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + IDirect3DSurface9 *dest, + bool flipY, + bool premultiplyAlpha, + bool unmultiplyAlpha) { - ASSERT(source != NULL && dest != NULL); + ASSERT(source != nullptr && dest != nullptr); IDirect3DDevice9 *device = mRenderer->getDevice(); @@ -319,8 +394,10 @@ gl::Error Blit9::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum source->GetDesc(&sourceDesc); dest->GetDesc(&destDesc); - if (sourceDesc.Format == destDesc.Format && destDesc.Usage & D3DUSAGE_RENDERTARGET && - d3d9_gl::IsFormatChannelEquivalent(destDesc.Format, destFormat)) // Can use StretchRect + // Check if it's possible to use StetchRect + if (sourceDesc.Format == destDesc.Format && (destDesc.Usage & D3DUSAGE_RENDERTARGET) && + d3d9_gl::IsFormatChannelEquivalent(destDesc.Format, destFormat) && !flipY && + premultiplyAlpha == unmultiplyAlpha) { RECT destRect = { destOffset.x, destOffset.y, destOffset.x + (sourceRect.right - sourceRect.left), destOffset.y + (sourceRect.bottom - sourceRect.top)}; HRESULT result = device->StretchRect(source, &sourceRect, dest, &destRect, D3DTEXF_POINT); @@ -328,85 +405,135 @@ gl::Error Blit9::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to blit between textures, StretchRect result: 0x%X.", result); + return gl::OutOfMemory() + << "Failed to blit between textures, StretchRect " << gl::FmtHR(result); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } else { - return formatConvert(source, sourceRect, destFormat, destOffset, dest); + IDirect3DBaseTexture9 *texture = sourceTexture; + RECT adjustedSourceRect = sourceRect; + gl::Extents sourceSize(sourceDesc.Width, sourceDesc.Height, 1); + + if (texture == nullptr) + { + ANGLE_TRY(copySurfaceToTexture(source, sourceRect, &texture)); + + // copySurfaceToTexture only copies in the sourceRect area of the source surface. + // Adjust sourceRect so that it is now covering the entire source texture + adjustedSourceRect.left = 0; + adjustedSourceRect.right = sourceRect.right - sourceRect.left; + adjustedSourceRect.top = 0; + adjustedSourceRect.bottom = sourceRect.bottom - sourceRect.top; + + sourceSize.width = sourceRect.right - sourceRect.left; + sourceSize.height = sourceRect.bottom - sourceRect.top; + } + else + { + texture->AddRef(); + } + + gl::Error error = formatConvert(texture, adjustedSourceRect, sourceSize, destFormat, + destOffset, dest, flipY, premultiplyAlpha, unmultiplyAlpha); + + SafeRelease(texture); + + return error; } } -gl::Error Blit9::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, const gl::Offset &destOffset, IDirect3DSurface9 *dest) +gl::Error Blit9::formatConvert(IDirect3DBaseTexture9 *source, + const RECT &sourceRect, + const gl::Extents &sourceSize, + GLenum destFormat, + const gl::Offset &destOffset, + IDirect3DSurface9 *dest, + bool flipY, + bool premultiplyAlpha, + bool unmultiplyAlpha) { - gl::Error error = initialize(); - if (error.isError()) - { - return error; - } - - IDirect3DTexture9 *texture = NULL; - error = copySurfaceToTexture(source, sourceRect, &texture); - if (error.isError()) - { - return error; - } + ANGLE_TRY(initialize()); IDirect3DDevice9 *device = mRenderer->getDevice(); saveState(); - device->SetTexture(0, texture); + device->SetTexture(0, source); device->SetRenderTarget(0, dest); - setViewport(sourceRect, destOffset); + RECT destRect; + destRect.left = destOffset.x; + destRect.right = destOffset.x + (sourceRect.right - sourceRect.left); + destRect.top = destOffset.y; + destRect.bottom = destOffset.y + (sourceRect.bottom - sourceRect.top); + + setViewportAndShaderConstants(sourceRect, sourceSize, destRect, flipY); setCommonBlitState(); - error = setFormatConvertShaders(destFormat); + gl::Error error = setFormatConvertShaders(destFormat, flipY, premultiplyAlpha, unmultiplyAlpha); if (!error.isError()) { render(); } - SafeRelease(texture); - restoreState(); return error; } -gl::Error Blit9::setFormatConvertShaders(GLenum destFormat) +gl::Error Blit9::setFormatConvertShaders(GLenum destFormat, + bool flipY, + bool premultiplyAlpha, + bool unmultiplyAlpha) { - gl::Error error = setVertexShader(SHADER_VS_STANDARD); - if (error.isError()) - { - return error; - } + ANGLE_TRY(setVertexShader(SHADER_VS_STANDARD)); switch (destFormat) { - default: UNREACHABLE(); case GL_RGBA: case GL_BGRA_EXT: case GL_RGB: case GL_RG_EXT: case GL_RED_EXT: case GL_ALPHA: - error = setPixelShader(SHADER_PS_COMPONENTMASK); - break; + if (premultiplyAlpha == unmultiplyAlpha) + { + ANGLE_TRY(setPixelShader(SHADER_PS_COMPONENTMASK)); + } + else if (premultiplyAlpha) + { + ANGLE_TRY(setPixelShader(SHADER_PS_COMPONENTMASK_PREMULTIPLY_ALPHA)); + } + else + { + ASSERT(unmultiplyAlpha); + ANGLE_TRY(setPixelShader(SHADER_PS_COMPONENTMASK_UNMULTIPLY_ALPHA)); + } + break; case GL_LUMINANCE: case GL_LUMINANCE_ALPHA: - error = setPixelShader(SHADER_PS_LUMINANCE); - break; - } + if (premultiplyAlpha == unmultiplyAlpha) + { + ANGLE_TRY(setPixelShader(SHADER_PS_LUMINANCE)); + } + else if (premultiplyAlpha) + { + ANGLE_TRY(setPixelShader(SHADER_PS_LUMINANCE_PREMULTIPLY_ALPHA)); + } + else + { + ASSERT(unmultiplyAlpha); + ANGLE_TRY(setPixelShader(SHADER_PS_LUMINANCE_UNMULTIPLY_ALPHA)); + } + break; - if (error.isError()) - { - return error; + default: + UNREACHABLE(); } enum { X = 0, Y = 1, Z = 2, W = 3 }; @@ -502,10 +629,12 @@ gl::Error Blit9::setFormatConvertShaders(GLenum destFormat) mRenderer->getDevice()->SetPixelShaderConstantF(0, psConst, 2); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect, IDirect3DTexture9 **outTexture) +gl::Error Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, + const RECT &sourceRect, + IDirect3DBaseTexture9 **outTexture) { ASSERT(surface); @@ -516,12 +645,15 @@ gl::Error Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &so // Copy the render target into a texture IDirect3DTexture9 *texture; - HRESULT result = device->CreateTexture(sourceRect.right - sourceRect.left, sourceRect.bottom - sourceRect.top, 1, D3DUSAGE_RENDERTARGET, sourceDesc.Format, D3DPOOL_DEFAULT, &texture, NULL); + HRESULT result = device->CreateTexture( + sourceRect.right - sourceRect.left, sourceRect.bottom - sourceRect.top, 1, + D3DUSAGE_RENDERTARGET, sourceDesc.Format, D3DPOOL_DEFAULT, &texture, nullptr); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal texture for blit, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to allocate internal texture for blit, " + << gl::FmtHR(result); } IDirect3DSurface9 *textureSurface; @@ -531,11 +663,12 @@ gl::Error Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &so { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); SafeRelease(texture); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to query surface of internal blit texture, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to query surface of internal blit texture, " + << gl::FmtHR(result); } mRenderer->endScene(); - result = device->StretchRect(surface, &sourceRect, textureSurface, NULL, D3DTEXF_NONE); + result = device->StretchRect(surface, &sourceRect, textureSurface, nullptr, D3DTEXF_NONE); SafeRelease(textureSurface); @@ -543,35 +676,50 @@ gl::Error Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &so { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); SafeRelease(texture); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to copy between internal blit textures, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to copy between internal blit textures, " + << gl::FmtHR(result); } *outTexture = texture; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -void Blit9::setViewport(const RECT &sourceRect, const gl::Offset &offset) +void Blit9::setViewportAndShaderConstants(const RECT &sourceRect, + const gl::Extents &sourceSize, + const RECT &destRect, + bool flipY) { IDirect3DDevice9 *device = mRenderer->getDevice(); D3DVIEWPORT9 vp; - vp.X = offset.x; - vp.Y = offset.y; - vp.Width = sourceRect.right - sourceRect.left; - vp.Height = sourceRect.bottom - sourceRect.top; + vp.X = destRect.left; + vp.Y = destRect.top; + vp.Width = destRect.right - destRect.left; + vp.Height = destRect.bottom - destRect.top; vp.MinZ = 0.0f; vp.MaxZ = 1.0f; device->SetViewport(&vp); - float halfPixelAdjust[4] = { -1.0f/vp.Width, 1.0f/vp.Height, 0, 0 }; - device->SetVertexShaderConstantF(0, halfPixelAdjust, 1); + float vertexConstants[8] = { + // halfPixelAdjust + -1.0f / vp.Width, 1.0f / vp.Height, 0, 0, + // texcoordOffset + static_cast(sourceRect.left) / sourceSize.width, + static_cast(flipY ? sourceRect.bottom : sourceRect.top) / sourceSize.height, + static_cast(sourceRect.right - sourceRect.left) / sourceSize.width, + static_cast(flipY ? sourceRect.top - sourceRect.bottom + : sourceRect.bottom - sourceRect.top) / + sourceSize.height, + }; + + device->SetVertexShaderConstantF(0, vertexConstants, 2); } void Blit9::setCommonBlitState() { IDirect3DDevice9 *device = mRenderer->getDevice(); - device->SetDepthStencilSurface(NULL); + device->SetDepthStencilSurface(nullptr); device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); @@ -617,7 +765,7 @@ void Blit9::saveState() device->GetDepthStencilSurface(&mSavedDepthStencil); device->GetRenderTarget(0, &mSavedRenderTarget); - if (mSavedStateBlock == NULL) + if (mSavedStateBlock == nullptr) { hr = device->BeginStateBlock(); ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); @@ -626,9 +774,9 @@ void Blit9::saveState() static const float dummyConst[8] = { 0 }; - device->SetVertexShader(NULL); + device->SetVertexShader(nullptr); device->SetVertexShaderConstantF(0, dummyConst, 2); - device->SetPixelShader(NULL); + device->SetPixelShader(nullptr); device->SetPixelShaderConstantF(0, dummyConst, 2); D3DVIEWPORT9 dummyVp; @@ -641,7 +789,7 @@ void Blit9::saveState() device->SetViewport(&dummyVp); - device->SetTexture(0, NULL); + device->SetTexture(0, nullptr); device->SetStreamSource(0, mQuadVertexBuffer, 0, 0); @@ -651,9 +799,9 @@ void Blit9::saveState() ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); } - ASSERT(mSavedStateBlock != NULL); + ASSERT(mSavedStateBlock != nullptr); - if (mSavedStateBlock != NULL) + if (mSavedStateBlock != nullptr) { hr = mSavedStateBlock->Capture(); ASSERT(SUCCEEDED(hr)); @@ -670,9 +818,9 @@ void Blit9::restoreState() device->SetRenderTarget(0, mSavedRenderTarget); SafeRelease(mSavedRenderTarget); - ASSERT(mSavedStateBlock != NULL); + ASSERT(mSavedStateBlock != nullptr); - if (mSavedStateBlock != NULL) + if (mSavedStateBlock != nullptr) { mSavedStateBlock->Apply(); } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.h index 586abd2580..026874f8ae 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.h @@ -16,7 +16,10 @@ namespace gl { +class Context; class Framebuffer; +class Texture; +struct Extents; struct Offset; } @@ -35,13 +38,33 @@ class Blit9 : angle::NonCopyable // Copy from source surface to dest surface. // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left) - gl::Error copy2D(const gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, const gl::Offset &destOffset, TextureStorage *storage, GLint level); - gl::Error copyCube(const gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, const gl::Offset &destOffset, TextureStorage *storage, GLenum target, GLint level); - - // Copy from source surface to dest surface. - // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left) - // source is interpreted as RGBA and destFormat specifies the desired result format. For example, if destFormat = GL_RGB, the alpha channel will be forced to 0. - gl::Error formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, const gl::Offset &destOffset, IDirect3DSurface9 *dest); + gl::Error copy2D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const RECT &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level); + gl::Error copyCube(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const RECT &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLenum target, + GLint level); + gl::Error copyTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + const RECT &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLenum destTarget, + GLint destLevel, + bool flipY, + bool premultiplyAlpha, + bool unmultiplyAlpha); // 2x2 box filter sample from source to dest. // Requires that source is RGB(A) and dest has the same format as source. @@ -54,23 +77,56 @@ class Blit9 : angle::NonCopyable IDirect3DVertexBuffer9 *mQuadVertexBuffer; IDirect3DVertexDeclaration9 *mQuadVertexDeclaration; - gl::Error setFormatConvertShaders(GLenum destFormat); + // Copy from source texture to dest surface. + // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left) + // source is interpreted as RGBA and destFormat specifies the desired result format. For + // example, if destFormat = GL_RGB, the alpha channel will be forced to 0. + gl::Error formatConvert(IDirect3DBaseTexture9 *source, + const RECT &sourceRect, + const gl::Extents &sourceSize, + GLenum destFormat, + const gl::Offset &destOffset, + IDirect3DSurface9 *dest, + bool flipY, + bool premultiplyAlpha, + bool unmultiplyAlpha); + gl::Error setFormatConvertShaders(GLenum destFormat, + bool flipY, + bool premultiplyAlpha, + bool unmultiplyAlpha); - gl::Error copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, const gl::Offset &destOffset, IDirect3DSurface9 *dest); - gl::Error copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect, IDirect3DTexture9 **outTexture); - void setViewport(const RECT &sourceRect, const gl::Offset &offset); + gl::Error copy(IDirect3DSurface9 *source, + IDirect3DBaseTexture9 *sourceTexture, + const RECT &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + IDirect3DSurface9 *dest, + bool flipY, + bool premultiplyAlpha, + bool unmultiplyAlpha); + gl::Error copySurfaceToTexture(IDirect3DSurface9 *surface, + const RECT &sourceRect, + IDirect3DBaseTexture9 **outTexture); + void setViewportAndShaderConstants(const RECT &sourceRect, + const gl::Extents &sourceSize, + const RECT &destRect, + bool flipY); void setCommonBlitState(); RECT getSurfaceRect(IDirect3DSurface9 *surface) const; + gl::Extents getSurfaceSize(IDirect3DSurface9 *surface) const; // This enum is used to index mCompiledShaders and mShaderSource. enum ShaderId { SHADER_VS_STANDARD, - SHADER_VS_FLIPY, SHADER_PS_PASSTHROUGH, SHADER_PS_LUMINANCE, + SHADER_PS_LUMINANCE_PREMULTIPLY_ALPHA, + SHADER_PS_LUMINANCE_UNMULTIPLY_ALPHA, SHADER_PS_COMPONENTMASK, - SHADER_COUNT + SHADER_PS_COMPONENTMASK_PREMULTIPLY_ALPHA, + SHADER_PS_COMPONENTMASK_UNMULTIPLY_ALPHA, + SHADER_COUNT, }; // This actually contains IDirect3DVertexShader9 or IDirect3DPixelShader9 casted to IUnknown. diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp index 804b6971ce..dc308e7752 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp @@ -12,23 +12,37 @@ namespace rx { -Buffer9::Buffer9(Renderer9 *renderer) - : BufferD3D(renderer), - mSize(0) -{} +Buffer9::Buffer9(const gl::BufferState &state, Renderer9 *renderer) + : BufferD3D(state, renderer), mSize(0) +{ +} Buffer9::~Buffer9() { mSize = 0; } -gl::Error Buffer9::setData(const void* data, size_t size, GLenum usage) +size_t Buffer9::getSize() const +{ + return mSize; +} + +bool Buffer9::supportsDirectBinding() const +{ + return false; +} + +gl::Error Buffer9::setData(const gl::Context *context, + gl::BufferBinding /*target*/, + const void *data, + size_t size, + gl::BufferUsage usage) { if (size > mMemory.size()) { if (!mMemory.resize(size)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal buffer."); + return gl::OutOfMemory() << "Failed to resize internal buffer."; } } @@ -38,25 +52,30 @@ gl::Error Buffer9::setData(const void* data, size_t size, GLenum usage) memcpy(mMemory.data(), data, size); } - invalidateStaticData(D3D_BUFFER_INVALIDATE_WHOLE_CACHE); + updateD3DBufferUsage(context, usage); - updateD3DBufferUsage(usage); - return gl::Error(GL_NO_ERROR); + invalidateStaticData(context); + + return gl::NoError(); } -gl::Error Buffer9::getData(const uint8_t **outData) +gl::Error Buffer9::getData(const gl::Context *context, const uint8_t **outData) { *outData = mMemory.data(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Buffer9::setSubData(const void* data, size_t size, size_t offset) +gl::Error Buffer9::setSubData(const gl::Context *context, + gl::BufferBinding /*target*/, + const void *data, + size_t size, + size_t offset) { if (offset + size > mMemory.size()) { if (!mMemory.resize(offset + size)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal buffer."); + return gl::OutOfMemory() << "Failed to resize internal buffer."; } } @@ -66,46 +85,55 @@ gl::Error Buffer9::setSubData(const void* data, size_t size, size_t offset) memcpy(mMemory.data() + offset, data, size); } - invalidateStaticData(D3D_BUFFER_INVALIDATE_WHOLE_CACHE); + invalidateStaticData(context); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Buffer9::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) +gl::Error Buffer9::copySubData(const gl::Context *context, + BufferImpl *source, + GLintptr sourceOffset, + GLintptr destOffset, + GLsizeiptr size) { // Note: this method is currently unreachable - Buffer9* sourceBuffer = GetAs(source); + Buffer9 *sourceBuffer = GetAs(source); ASSERT(sourceBuffer); memcpy(mMemory.data() + destOffset, sourceBuffer->mMemory.data() + sourceOffset, size); - invalidateStaticData(D3D_BUFFER_INVALIDATE_WHOLE_CACHE); + invalidateStaticData(context); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } // We do not support buffer mapping in D3D9 -gl::Error Buffer9::map(GLenum access, GLvoid **mapPtr) +gl::Error Buffer9::map(const gl::Context *context, GLenum access, void **mapPtr) { UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + return gl::InternalError(); } -gl::Error Buffer9::mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) +gl::Error Buffer9::mapRange(const gl::Context *context, + size_t offset, + size_t length, + GLbitfield access, + void **mapPtr) { UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + return gl::InternalError(); } -gl::Error Buffer9::unmap(GLboolean *result) +gl::Error Buffer9::unmap(const gl::Context *context, GLboolean *result) { UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + return gl::InternalError(); } -void Buffer9::markTransformFeedbackUsage() +gl::Error Buffer9::markTransformFeedbackUsage(const gl::Context *context) { UNREACHABLE(); + return gl::InternalError(); } -} +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.h index 44a524ba28..960b2a2474 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.h @@ -20,28 +20,44 @@ class Renderer9; class Buffer9 : public BufferD3D { public: - Buffer9(Renderer9 *renderer); - virtual ~Buffer9(); + Buffer9(const gl::BufferState &state, Renderer9 *renderer); + ~Buffer9() override; // BufferD3D implementation - virtual size_t getSize() const { return mSize; } - virtual bool supportsDirectBinding() const { return false; } - gl::Error getData(const uint8_t **outData) override; + size_t getSize() const override; + bool supportsDirectBinding() const override; + gl::Error getData(const gl::Context *context, const uint8_t **outData) override; // BufferImpl implementation - virtual gl::Error setData(const void* data, size_t size, GLenum usage); - virtual gl::Error setSubData(const void* data, size_t size, size_t offset); - virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); - virtual gl::Error map(GLenum access, GLvoid **mapPtr); - virtual gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr); - virtual gl::Error unmap(GLboolean *result); - virtual void markTransformFeedbackUsage(); + gl::Error setData(const gl::Context *context, + gl::BufferBinding target, + const void *data, + size_t size, + gl::BufferUsage usage) override; + gl::Error setSubData(const gl::Context *context, + gl::BufferBinding target, + const void *data, + size_t size, + size_t offset) override; + gl::Error copySubData(const gl::Context *context, + BufferImpl *source, + GLintptr sourceOffset, + GLintptr destOffset, + GLsizeiptr size) override; + gl::Error map(const gl::Context *context, GLenum access, void **mapPtr) override; + gl::Error mapRange(const gl::Context *context, + size_t offset, + size_t length, + GLbitfield access, + void **mapPtr) override; + gl::Error unmap(const gl::Context *context, GLboolean *result) override; + gl::Error markTransformFeedbackUsage(const gl::Context *context) override; private: - MemoryBuffer mMemory; + angle::MemoryBuffer mMemory; size_t mSize; }; -} +} // namespace rx -#endif // LIBANGLE_RENDERER_D3D_D3D9_BUFFER9_H_ +#endif // LIBANGLE_RENDERER_D3D_D3D9_BUFFER9_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Context9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Context9.cpp new file mode 100644 index 0000000000..1b9874cc20 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Context9.cpp @@ -0,0 +1,303 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Context9: +// D3D9-specific functionality associated with a GL Context. +// + +#include "libANGLE/renderer/d3d/d3d9/Context9.h" + +#include "common/string_utils.h" +#include "libANGLE/renderer/d3d/CompilerD3D.h" +#include "libANGLE/renderer/d3d/ProgramD3D.h" +#include "libANGLE/renderer/d3d/RenderbufferD3D.h" +#include "libANGLE/renderer/d3d/SamplerD3D.h" +#include "libANGLE/renderer/d3d/ShaderD3D.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" +#include "libANGLE/renderer/d3d/d3d9/Buffer9.h" +#include "libANGLE/renderer/d3d/d3d9/Fence9.h" +#include "libANGLE/renderer/d3d/d3d9/Framebuffer9.h" +#include "libANGLE/renderer/d3d/d3d9/Query9.h" +#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" +#include "libANGLE/renderer/d3d/d3d9/StateManager9.h" +#include "libANGLE/renderer/d3d/d3d9/VertexArray9.h" + +namespace rx +{ + +Context9::Context9(const gl::ContextState &state, Renderer9 *renderer) + : ContextImpl(state), mRenderer(renderer) +{ +} + +Context9::~Context9() +{ +} + +gl::Error Context9::initialize() +{ + return gl::NoError(); +} + +CompilerImpl *Context9::createCompiler() +{ + return new CompilerD3D(SH_HLSL_3_0_OUTPUT); +} + +ShaderImpl *Context9::createShader(const gl::ShaderState &data) +{ + return new ShaderD3D(data, mRenderer->getWorkarounds(), mRenderer->getNativeExtensions()); +} + +ProgramImpl *Context9::createProgram(const gl::ProgramState &data) +{ + return new ProgramD3D(data, mRenderer); +} + +FramebufferImpl *Context9::createFramebuffer(const gl::FramebufferState &data) +{ + return new Framebuffer9(data, mRenderer); +} + +TextureImpl *Context9::createTexture(const gl::TextureState &state) +{ + switch (state.getTarget()) + { + case GL_TEXTURE_2D: + return new TextureD3D_2D(state, mRenderer); + case GL_TEXTURE_CUBE_MAP: + return new TextureD3D_Cube(state, mRenderer); + case GL_TEXTURE_EXTERNAL_OES: + return new TextureD3D_External(state, mRenderer); + default: + UNREACHABLE(); + } + return nullptr; +} + +RenderbufferImpl *Context9::createRenderbuffer() +{ + return new RenderbufferD3D(mRenderer); +} + +BufferImpl *Context9::createBuffer(const gl::BufferState &state) +{ + return new Buffer9(state, mRenderer); +} + +VertexArrayImpl *Context9::createVertexArray(const gl::VertexArrayState &data) +{ + return new VertexArray9(data); +} + +QueryImpl *Context9::createQuery(GLenum type) +{ + return new Query9(mRenderer, type); +} + +FenceNVImpl *Context9::createFenceNV() +{ + return new FenceNV9(mRenderer); +} + +SyncImpl *Context9::createSync() +{ + // D3D9 doesn't support ES 3.0 and its sync objects. + UNREACHABLE(); + return nullptr; +} + +TransformFeedbackImpl *Context9::createTransformFeedback(const gl::TransformFeedbackState &state) +{ + UNREACHABLE(); + return nullptr; +} + +SamplerImpl *Context9::createSampler(const gl::SamplerState &state) +{ + return new SamplerD3D(state); +} + +ProgramPipelineImpl *Context9::createProgramPipeline(const gl::ProgramPipelineState &data) +{ + UNREACHABLE(); + return nullptr; +} + +std::vector Context9::createPaths(GLsizei) +{ + return std::vector(); +} + +gl::Error Context9::flush(const gl::Context *context) +{ + return mRenderer->flush(); +} + +gl::Error Context9::finish(const gl::Context *context) +{ + return mRenderer->finish(); +} + +gl::Error Context9::drawArrays(const gl::Context *context, GLenum mode, GLint first, GLsizei count) +{ + return mRenderer->genericDrawArrays(context, mode, first, count, 0); +} + +gl::Error Context9::drawArraysInstanced(const gl::Context *context, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instanceCount) +{ + return mRenderer->genericDrawArrays(context, mode, first, count, instanceCount); +} + +gl::Error Context9::drawElements(const gl::Context *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices) +{ + return mRenderer->genericDrawElements(context, mode, count, type, indices, 0); +} + +gl::Error Context9::drawElementsInstanced(const gl::Context *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei instances) +{ + return mRenderer->genericDrawElements(context, mode, count, type, indices, instances); +} + +gl::Error Context9::drawRangeElements(const gl::Context *context, + GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const void *indices) +{ + return mRenderer->genericDrawElements(context, mode, count, type, indices, 0); +} + +gl::Error Context9::drawArraysIndirect(const gl::Context *context, + GLenum mode, + const void *indirect) +{ + UNREACHABLE(); + return gl::InternalError() << "D3D9 doesn't support ES 3.1 DrawArraysIndirect API"; +} + +gl::Error Context9::drawElementsIndirect(const gl::Context *context, + GLenum mode, + GLenum type, + const void *indirect) +{ + UNREACHABLE(); + return gl::InternalError() << "D3D9 doesn't support ES 3.1 DrawElementsIndirect API"; +} + +GLenum Context9::getResetStatus() +{ + return mRenderer->getResetStatus(); +} + +std::string Context9::getVendorString() const +{ + return mRenderer->getVendorString(); +} + +std::string Context9::getRendererDescription() const +{ + return mRenderer->getRendererDescription(); +} + +void Context9::insertEventMarker(GLsizei length, const char *marker) +{ + auto optionalString = angle::WidenString(static_cast(length), marker); + if (optionalString.valid()) + { + mRenderer->getAnnotator()->setMarker(optionalString.value().data()); + } +} + +void Context9::pushGroupMarker(GLsizei length, const char *marker) +{ + auto optionalString = angle::WidenString(static_cast(length), marker); + if (optionalString.valid()) + { + mRenderer->getAnnotator()->beginEvent(optionalString.value().data()); + } +} + +void Context9::popGroupMarker() +{ + mRenderer->getAnnotator()->endEvent(); +} + +void Context9::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message) +{ + // Fall through to the EXT_debug_marker functions + pushGroupMarker(length, message); +} + +void Context9::popDebugGroup() +{ + // Fall through to the EXT_debug_marker functions + popGroupMarker(); +} + +void Context9::syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits) +{ + mRenderer->getStateManager()->syncState(mState.getState(), dirtyBits); +} + +GLint Context9::getGPUDisjoint() +{ + return mRenderer->getGPUDisjoint(); +} + +GLint64 Context9::getTimestamp() +{ + return mRenderer->getTimestamp(); +} + +void Context9::onMakeCurrent(const gl::Context *context) +{ +} + +const gl::Caps &Context9::getNativeCaps() const +{ + return mRenderer->getNativeCaps(); +} + +const gl::TextureCapsMap &Context9::getNativeTextureCaps() const +{ + return mRenderer->getNativeTextureCaps(); +} + +const gl::Extensions &Context9::getNativeExtensions() const +{ + return mRenderer->getNativeExtensions(); +} + +const gl::Limitations &Context9::getNativeLimitations() const +{ + return mRenderer->getNativeLimitations(); +} + +gl::Error Context9::dispatchCompute(const gl::Context *context, + GLuint numGroupsX, + GLuint numGroupsY, + GLuint numGroupsZ) +{ + UNREACHABLE(); + return gl::InternalError() << "D3D9 doesn't support ES 3.1 DispatchCompute API"; +} + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Context9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Context9.h new file mode 100644 index 0000000000..d681bfde89 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Context9.h @@ -0,0 +1,151 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Context9: +// D3D9-specific functionality associated with a GL Context. +// + +#ifndef LIBANGLE_RENDERER_D3D_D3D9_CONTEXT9_H_ +#define LIBANGLE_RENDERER_D3D_D3D9_CONTEXT9_H_ + +#include "libANGLE/renderer/ContextImpl.h" + +namespace rx +{ +class Renderer9; + +class Context9 : public ContextImpl +{ + public: + Context9(const gl::ContextState &state, Renderer9 *renderer); + ~Context9() override; + + gl::Error initialize() override; + + // Shader creation + CompilerImpl *createCompiler() override; + ShaderImpl *createShader(const gl::ShaderState &data) override; + ProgramImpl *createProgram(const gl::ProgramState &data) override; + + // Framebuffer creation + FramebufferImpl *createFramebuffer(const gl::FramebufferState &data) override; + + // Texture creation + TextureImpl *createTexture(const gl::TextureState &state) override; + + // Renderbuffer creation + RenderbufferImpl *createRenderbuffer() override; + + // Buffer creation + BufferImpl *createBuffer(const gl::BufferState &state) override; + + // Vertex Array creation + VertexArrayImpl *createVertexArray(const gl::VertexArrayState &data) override; + + // Query and Fence creation + QueryImpl *createQuery(GLenum type) override; + FenceNVImpl *createFenceNV() override; + SyncImpl *createSync() override; + + // Transform Feedback creation + TransformFeedbackImpl *createTransformFeedback( + const gl::TransformFeedbackState &state) override; + + // Sampler object creation + SamplerImpl *createSampler(const gl::SamplerState &state) override; + + // Program Pipeline object creation + ProgramPipelineImpl *createProgramPipeline(const gl::ProgramPipelineState &data) override; + + // Path object creation + std::vector createPaths(GLsizei) override; + + // Flush and finish. + gl::Error flush(const gl::Context *context) override; + gl::Error finish(const gl::Context *context) override; + + // Drawing methods. + gl::Error drawArrays(const gl::Context *context, + GLenum mode, + GLint first, + GLsizei count) override; + gl::Error drawArraysInstanced(const gl::Context *context, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instanceCount) override; + + gl::Error drawElements(const gl::Context *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices) override; + gl::Error drawElementsInstanced(const gl::Context *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei instances) override; + gl::Error drawRangeElements(const gl::Context *context, + GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const void *indices) override; + gl::Error drawArraysIndirect(const gl::Context *context, + GLenum mode, + const void *indirect) override; + gl::Error drawElementsIndirect(const gl::Context *context, + GLenum mode, + GLenum type, + const void *indirect) override; + + // Device loss + GLenum getResetStatus() override; + + // Vendor and description strings. + std::string getVendorString() const override; + std::string getRendererDescription() const override; + + // EXT_debug_marker + void insertEventMarker(GLsizei length, const char *marker) override; + void pushGroupMarker(GLsizei length, const char *marker) override; + void popGroupMarker() override; + + // KHR_debug + void pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message) override; + void popDebugGroup() override; + + // State sync with dirty bits. + void syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits) override; + + // Disjoint timer queries + GLint getGPUDisjoint() override; + GLint64 getTimestamp() override; + + // Context switching + void onMakeCurrent(const gl::Context *context) override; + + // Caps queries + const gl::Caps &getNativeCaps() const override; + const gl::TextureCapsMap &getNativeTextureCaps() const override; + const gl::Extensions &getNativeExtensions() const override; + const gl::Limitations &getNativeLimitations() const override; + + gl::Error dispatchCompute(const gl::Context *context, + GLuint numGroupsX, + GLuint numGroupsY, + GLuint numGroupsZ) override; + + Renderer9 *getRenderer() const { return mRenderer; } + + private: + Renderer9 *mRenderer; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D9_CONTEXT9_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h index 54e3bb9490..b28008335f 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h @@ -9,12 +9,12 @@ #ifndef LIBANGLE_RENDERER_D3D_D3D9_DEBUGANNOTATOR9_H_ #define LIBANGLE_RENDERER_D3D_D3D9_DEBUGANNOTATOR9_H_ -#include "common/debug.h" +#include "libANGLE/LoggingAnnotator.h" namespace rx { -class DebugAnnotator9 : public gl::DebugAnnotator +class DebugAnnotator9 : public angle::LoggingAnnotator { public: DebugAnnotator9() {} diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp index 3300681277..bff3881655 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp @@ -13,10 +13,7 @@ namespace rx { -FenceNV9::FenceNV9(Renderer9 *renderer) - : FenceNVImpl(), - mRenderer(renderer), - mQuery(NULL) +FenceNV9::FenceNV9(Renderer9 *renderer) : FenceNVImpl(), mRenderer(renderer), mQuery(nullptr) { } @@ -41,10 +38,10 @@ gl::Error FenceNV9::set(GLenum condition) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); SafeRelease(mQuery); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to end event query, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to end event query, " << gl::FmtHR(result); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error FenceNV9::test(GLboolean *outFinished) @@ -66,7 +63,7 @@ gl::Error FenceNV9::finish() Sleep(0); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error FenceNV9::testHelper(bool flushCommandBuffer, GLboolean *outFinished) @@ -74,21 +71,21 @@ gl::Error FenceNV9::testHelper(bool flushCommandBuffer, GLboolean *outFinished) ASSERT(mQuery); DWORD getDataFlags = (flushCommandBuffer ? D3DGETDATA_FLUSH : 0); - HRESULT result = mQuery->GetData(NULL, 0, getDataFlags); + HRESULT result = mQuery->GetData(nullptr, 0, getDataFlags); if (d3d9::isDeviceLostError(result)) { mRenderer->notifyDeviceLost(); - return gl::Error(GL_OUT_OF_MEMORY, "Device was lost while querying result of an event query."); + return gl::OutOfMemory() << "Device was lost while querying result of an event query."; } else if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to get query data, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to get query data, " << gl::FmtHR(result); } ASSERT(result == S_OK || result == S_FALSE); *outFinished = ((result == S_OK) ? GL_TRUE : GL_FALSE); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.h index 200ac68d27..de0ff20774 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.h @@ -10,7 +10,7 @@ #define LIBANGLE_RENDERER_D3D_D3D9_FENCE9_H_ #include "libANGLE/renderer/FenceNVImpl.h" -#include "libANGLE/renderer/FenceSyncImpl.h" +#include "libANGLE/renderer/SyncImpl.h" namespace rx { diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp index 9c269a8565..dff12e03f8 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp @@ -7,21 +7,25 @@ // Framebuffer9.cpp: Implements the Framebuffer9 class. #include "libANGLE/renderer/d3d/d3d9/Framebuffer9.h" -#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" -#include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h" -#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" -#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" -#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" -#include "libANGLE/renderer/d3d/TextureD3D.h" -#include "libANGLE/formatutils.h" + +#include "libANGLE/Context.h" #include "libANGLE/Framebuffer.h" #include "libANGLE/FramebufferAttachment.h" #include "libANGLE/Texture.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/ContextImpl.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" +#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" +#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" +#include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h" +#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" +#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" +#include "libANGLE/renderer/renderer_utils.h" namespace rx { -Framebuffer9::Framebuffer9(const gl::Framebuffer::Data &data, Renderer9 *renderer) +Framebuffer9::Framebuffer9(const gl::FramebufferState &data, Renderer9 *renderer) : FramebufferD3D(data, renderer), mRenderer(renderer) { ASSERT(mRenderer != nullptr); @@ -31,66 +35,61 @@ Framebuffer9::~Framebuffer9() { } -gl::Error Framebuffer9::discard(size_t, const GLenum *) +gl::Error Framebuffer9::discard(const gl::Context *context, size_t, const GLenum *) { // Extension not implemented in D3D9 renderer UNREACHABLE(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Framebuffer9::invalidate(size_t, const GLenum *) +gl::Error Framebuffer9::invalidate(const gl::Context *context, size_t, const GLenum *) { // Shouldn't ever reach here in D3D9 UNREACHABLE(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Framebuffer9::invalidateSub(size_t, const GLenum *, const gl::Rectangle &) +gl::Error Framebuffer9::invalidateSub(const gl::Context *context, + size_t, + const GLenum *, + const gl::Rectangle &) { // Shouldn't ever reach here in D3D9 UNREACHABLE(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Framebuffer9::clear(const gl::Data &data, const ClearParameters &clearParams) +gl::Error Framebuffer9::clearImpl(const gl::Context *context, const ClearParameters &clearParams) { - const gl::FramebufferAttachment *colorAttachment = mData.getColorAttachment(0); - const gl::FramebufferAttachment *depthStencilAttachment = mData.getDepthOrStencilAttachment(); + const gl::FramebufferAttachment *colorAttachment = mState.getColorAttachment(0); + const gl::FramebufferAttachment *depthStencilAttachment = mState.getDepthOrStencilAttachment(); - gl::Error error = mRenderer->applyRenderTarget(colorAttachment, depthStencilAttachment); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mRenderer->applyRenderTarget(context, colorAttachment, depthStencilAttachment)); - float nearZ = data.state->getNearPlane(); - float farZ = data.state->getFarPlane(); - mRenderer->setViewport(data.caps, data.state->getViewport(), nearZ, farZ, GL_TRIANGLES, - data.state->getRasterizerState().frontFace, true); + const gl::State &glState = context->getGLState(); + float nearZ = glState.getNearPlane(); + float farZ = glState.getFarPlane(); + mRenderer->setViewport(glState.getViewport(), nearZ, farZ, GL_TRIANGLES, + glState.getRasterizerState().frontFace, true); - mRenderer->setScissorRectangle(data.state->getScissor(), data.state->isScissorTestEnabled()); + mRenderer->setScissorRectangle(glState.getScissor(), glState.isScissorTestEnabled()); - return mRenderer->clear(clearParams, colorAttachment, depthStencilAttachment); + return mRenderer->clear(context, clearParams, colorAttachment, depthStencilAttachment); } -gl::Error Framebuffer9::readPixelsImpl(const gl::Rectangle &area, +gl::Error Framebuffer9::readPixelsImpl(const gl::Context *context, + const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch, const gl::PixelPackState &pack, - uint8_t *pixels) const + uint8_t *pixels) { - ASSERT(pack.pixelBuffer.get() == nullptr); - - const gl::FramebufferAttachment *colorbuffer = mData.getColorAttachment(0); + const gl::FramebufferAttachment *colorbuffer = mState.getColorAttachment(0); ASSERT(colorbuffer); RenderTarget9 *renderTarget = nullptr; - gl::Error error = colorbuffer->getRenderTarget(&renderTarget); - if (error.isError()) - { - return error; - } + ANGLE_TRY(colorbuffer->getRenderTarget(context, &renderTarget)); ASSERT(renderTarget); IDirect3DSurface9 *surface = renderTarget->getSurface(); @@ -103,7 +102,8 @@ gl::Error Framebuffer9::readPixelsImpl(const gl::Rectangle &area, { UNIMPLEMENTED(); // FIXME: Requires resolve using StretchRect into non-multisampled render target SafeRelease(surface); - return gl::Error(GL_OUT_OF_MEMORY, "ReadPixels is unimplemented for multisampled framebuffer attachments."); + return gl::OutOfMemory() + << "ReadPixels is unimplemented for multisampled framebuffer attachments."; } IDirect3DDevice9 *device = mRenderer->getDevice(); @@ -135,7 +135,7 @@ gl::Error Framebuffer9::readPixelsImpl(const gl::Rectangle &area, { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); SafeRelease(surface); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal texture for ReadPixels."); + return gl::OutOfMemory() << "Failed to allocate internal texture for ReadPixels."; } } @@ -157,13 +157,13 @@ gl::Error Framebuffer9::readPixelsImpl(const gl::Rectangle &area, UNREACHABLE(); } - return gl::Error(GL_OUT_OF_MEMORY, "Failed to read internal render target data."); + return gl::OutOfMemory() << "Failed to read internal render target data."; } if (directToPixels) { SafeRelease(systemSurface); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } RECT rect; @@ -180,85 +180,42 @@ gl::Error Framebuffer9::readPixelsImpl(const gl::Rectangle &area, UNREACHABLE(); SafeRelease(systemSurface); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal render target."); + return gl::OutOfMemory() << "Failed to lock internal render target."; } - uint8_t *source; - int inputPitch; - if (pack.reverseRowOrder) - { - source = reinterpret_cast(lock.pBits) + lock.Pitch * (rect.bottom - rect.top - 1); - inputPitch = -lock.Pitch; - } - else - { - source = reinterpret_cast(lock.pBits); - inputPitch = lock.Pitch; - } + uint8_t *source = reinterpret_cast(lock.pBits); + int inputPitch = lock.Pitch; const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format); - const gl::InternalFormat &sourceFormatInfo = gl::GetInternalFormatInfo(d3dFormatInfo.internalFormat); - if (sourceFormatInfo.format == format && sourceFormatInfo.type == type) - { - // Direct copy possible - for (int y = 0; y < rect.bottom - rect.top; y++) - { - memcpy(pixels + y * outputPitch, source + y * inputPitch, (rect.right - rect.left) * sourceFormatInfo.pixelBytes); - } - } - else - { - const d3d9::D3DFormat &sourceD3DFormatInfo = d3d9::GetD3DFormatInfo(desc.Format); - ColorCopyFunction fastCopyFunc = sourceD3DFormatInfo.getFastCopyFunction(format, type); + gl::FormatType formatType(format, type); - GLenum sizedDestInternalFormat = gl::GetSizedInternalFormat(format, type); - const gl::InternalFormat &destFormatInfo = gl::GetInternalFormatInfo(sizedDestInternalFormat); + PackPixelsParams packParams; + packParams.area.x = rect.left; + packParams.area.y = rect.top; + packParams.area.width = rect.right - rect.left; + packParams.area.height = rect.bottom - rect.top; + packParams.format = format; + packParams.type = type; + packParams.outputPitch = static_cast(outputPitch); + packParams.pack = pack; - if (fastCopyFunc) - { - // Fast copy is possible through some special function - for (int y = 0; y < rect.bottom - rect.top; y++) - { - for (int x = 0; x < rect.right - rect.left; x++) - { - uint8_t *dest = pixels + y * outputPitch + x * destFormatInfo.pixelBytes; - const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes; - - fastCopyFunc(src, dest); - } - } - } - else - { - ColorReadFunction colorReadFunction = sourceD3DFormatInfo.colorReadFunction; - ColorWriteFunction colorWriteFunction = GetColorWriteFunction(format, type); - - uint8_t temp[sizeof(gl::ColorF)]; - for (int y = 0; y < rect.bottom - rect.top; y++) - { - for (int x = 0; x < rect.right - rect.left; x++) - { - uint8_t *dest = pixels + y * outputPitch + x * destFormatInfo.pixelBytes; - const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes; - - // readFunc and writeFunc will be using the same type of color, CopyTexImage - // will not allow the copy otherwise. - colorReadFunction(src, temp); - colorWriteFunction(temp, dest); - } - } - } - } + PackPixels(packParams, d3dFormatInfo.info(), inputPitch, source, pixels); systemSurface->UnlockRect(); SafeRelease(systemSurface); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Framebuffer9::blit(const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, const gl::Rectangle *scissor, - bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter, - const gl::Framebuffer *sourceFramebuffer) +gl::Error Framebuffer9::blitImpl(const gl::Context *context, + const gl::Rectangle &sourceArea, + const gl::Rectangle &destArea, + const gl::Rectangle *scissor, + bool blitRenderTarget, + bool blitDepth, + bool blitStencil, + GLenum filter, + const gl::Framebuffer *sourceFramebuffer) { ASSERT(filter == GL_NEAREST); @@ -273,18 +230,18 @@ gl::Error Framebuffer9::blit(const gl::Rectangle &sourceArea, const gl::Rectangl ASSERT(readBuffer); RenderTarget9 *readRenderTarget = nullptr; - gl::Error error = readBuffer->getRenderTarget(&readRenderTarget); + gl::Error error = readBuffer->getRenderTarget(context, &readRenderTarget); if (error.isError()) { return error; } ASSERT(readRenderTarget); - const gl::FramebufferAttachment *drawBuffer = mData.getColorAttachment(0); + const gl::FramebufferAttachment *drawBuffer = mState.getColorAttachment(0); ASSERT(drawBuffer); RenderTarget9 *drawRenderTarget = nullptr; - error = drawBuffer->getRenderTarget(&drawRenderTarget); + error = drawBuffer->getRenderTarget(context, &drawRenderTarget); if (error.isError()) { return error; @@ -389,7 +346,7 @@ gl::Error Framebuffer9::blit(const gl::Rectangle &sourceArea, const gl::Rectangl if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal blit failed, StretchRect returned 0x%X.", result); + return gl::OutOfMemory() << "Internal blit failed, StretchRect " << gl::FmtHR(result); } } @@ -399,18 +356,18 @@ gl::Error Framebuffer9::blit(const gl::Rectangle &sourceArea, const gl::Rectangl ASSERT(readBuffer); RenderTarget9 *readDepthStencil = nullptr; - gl::Error error = readBuffer->getRenderTarget(&readDepthStencil); + gl::Error error = readBuffer->getRenderTarget(context, &readDepthStencil); if (error.isError()) { return error; } ASSERT(readDepthStencil); - const gl::FramebufferAttachment *drawBuffer = mData.getDepthOrStencilAttachment(); + const gl::FramebufferAttachment *drawBuffer = mState.getDepthOrStencilAttachment(); ASSERT(drawBuffer); RenderTarget9 *drawDepthStencil = nullptr; - error = drawBuffer->getRenderTarget(&drawDepthStencil); + error = drawBuffer->getRenderTarget(context, &drawDepthStencil); if (error.isError()) { return error; @@ -431,18 +388,24 @@ gl::Error Framebuffer9::blit(const gl::Rectangle &sourceArea, const gl::Rectangl if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal blit failed, StretchRect returned 0x%X.", result); + return gl::OutOfMemory() << "Internal blit failed, StretchRect " << gl::FmtHR(result); } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } GLenum Framebuffer9::getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const { RenderTarget9 *renderTarget9 = GetAs(renderTarget); const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(renderTarget9->getD3DFormat()); - return d3dFormatInfo.internalFormat; + return d3dFormatInfo.info().glInternalFormat; } +gl::Error Framebuffer9::getSamplePosition(size_t index, GLfloat *xy) const +{ + UNREACHABLE(); + return gl::InternalError() << "getSamplePosition is unsupported to d3d9."; } + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h index fe12079ae0..d2b46435ee 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h @@ -18,26 +18,40 @@ class Renderer9; class Framebuffer9 : public FramebufferD3D { public: - Framebuffer9(const gl::Framebuffer::Data &data, Renderer9 *renderer); - virtual ~Framebuffer9(); + Framebuffer9(const gl::FramebufferState &data, Renderer9 *renderer); + ~Framebuffer9() override; - gl::Error discard(size_t count, const GLenum *attachments) override; - gl::Error invalidate(size_t count, const GLenum *attachments) override; - gl::Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) override; + gl::Error discard(const gl::Context *context, size_t count, const GLenum *attachments) override; + gl::Error invalidate(const gl::Context *context, + size_t count, + const GLenum *attachments) override; + gl::Error invalidateSub(const gl::Context *context, + size_t count, + const GLenum *attachments, + const gl::Rectangle &area) override; + + gl::Error getSamplePosition(size_t index, GLfloat *xy) const override; private: - gl::Error clear(const gl::Data &data, const ClearParameters &clearParams) override; + gl::Error clearImpl(const gl::Context *context, const ClearParameters &clearParams) override; - gl::Error readPixelsImpl(const gl::Rectangle &area, + gl::Error readPixelsImpl(const gl::Context *context, + const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch, const gl::PixelPackState &pack, - uint8_t *pixels) const override; + uint8_t *pixels) override; - gl::Error blit(const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, const gl::Rectangle *scissor, - bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter, - const gl::Framebuffer *sourceFramebuffer) override; + gl::Error blitImpl(const gl::Context *context, + const gl::Rectangle &sourceArea, + const gl::Rectangle &destArea, + const gl::Rectangle *scissor, + bool blitRenderTarget, + bool blitDepth, + bool blitStencil, + GLenum filter, + const gl::Framebuffer *sourceFramebuffer) override; GLenum getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const override; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.cpp index fec7e3e19d..179629b362 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.cpp @@ -24,8 +24,8 @@ namespace rx Image9::Image9(Renderer9 *renderer) { - mSurface = NULL; - mRenderer = NULL; + mSurface = nullptr; + mRenderer = nullptr; mD3DPool = D3DPOOL_SYSTEMMEM; mD3DFormat = D3DFMT_UNKNOWN; @@ -45,7 +45,9 @@ gl::Error Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 ASSERT(SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to query the source surface description for mipmap generation, result: 0x%X.", result); + return gl::OutOfMemory() + << "Failed to query the source surface description for mipmap generation, " + << gl::FmtHR(result); } D3DSURFACE_DESC sourceDesc; @@ -53,7 +55,9 @@ gl::Error Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 ASSERT(SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to query the destination surface description for mipmap generation, result: 0x%X.", result); + return gl::OutOfMemory() + << "Failed to query the destination surface description for mipmap generation, " + << gl::FmtHR(result); } ASSERT(sourceDesc.Format == destDesc.Format); @@ -61,23 +65,25 @@ gl::Error Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 ASSERT(sourceDesc.Height == 1 || sourceDesc.Height / 2 == destDesc.Height); const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(sourceDesc.Format); - ASSERT(d3dFormatInfo.mipGenerationFunction != NULL); + ASSERT(d3dFormatInfo.info().mipGenerationFunction != nullptr); D3DLOCKED_RECT sourceLocked = {0}; - result = sourceSurface->LockRect(&sourceLocked, NULL, D3DLOCK_READONLY); + result = sourceSurface->LockRect(&sourceLocked, nullptr, D3DLOCK_READONLY); ASSERT(SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock the source surface for mipmap generation, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to lock the source surface for mipmap generation, " + << gl::FmtHR(result); } D3DLOCKED_RECT destLocked = {0}; - result = destSurface->LockRect(&destLocked, NULL, 0); + result = destSurface->LockRect(&destLocked, nullptr, 0); ASSERT(SUCCEEDED(result)); if (FAILED(result)) { sourceSurface->UnlockRect(); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock the destination surface for mipmap generation, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to lock the destination surface for mipmap generation, " + << gl::FmtHR(result); } const uint8_t *sourceData = reinterpret_cast(sourceLocked.pBits); @@ -85,40 +91,29 @@ gl::Error Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 ASSERT(sourceData && destData); - d3dFormatInfo.mipGenerationFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData, sourceLocked.Pitch, 0, - destData, destLocked.Pitch, 0); + d3dFormatInfo.info().mipGenerationFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData, + sourceLocked.Pitch, 0, destData, destLocked.Pitch, + 0); destSurface->UnlockRect(); sourceSurface->UnlockRect(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Image9::generateMipmap(Image9 *dest, Image9 *source) { - IDirect3DSurface9 *sourceSurface = NULL; - gl::Error error = source->getSurface(&sourceSurface); - if (error.isError()) - { - return error; - } + IDirect3DSurface9 *sourceSurface = nullptr; + ANGLE_TRY(source->getSurface(&sourceSurface)); - IDirect3DSurface9 *destSurface = NULL; - error = dest->getSurface(&destSurface); - if (error.isError()) - { - return error; - } + IDirect3DSurface9 *destSurface = nullptr; + ANGLE_TRY(dest->getSurface(&destSurface)); - error = generateMip(destSurface, sourceSurface); - if (error.isError()) - { - return error; - } + ANGLE_TRY(generateMip(destSurface, sourceSurface)); dest->markDirty(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source) @@ -128,17 +123,17 @@ gl::Error Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface HRESULT result; - result = source->LockRect(&sourceLock, NULL, 0); + result = source->LockRect(&sourceLock, nullptr, 0); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock source surface for copy, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to lock source surface for copy, " << gl::FmtHR(result); } - result = dest->LockRect(&destLock, NULL, 0); + result = dest->LockRect(&destLock, nullptr, 0); if (FAILED(result)) { source->UnlockRect(); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock source surface for copy, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to lock source surface for copy, " << gl::FmtHR(result); } ASSERT(sourceLock.pBits && destLock.pBits); @@ -161,7 +156,85 @@ gl::Error Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface source->UnlockRect(); dest->UnlockRect(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); +} + +// static +gl::Error Image9::CopyImage(const gl::Context *context, + Image9 *dest, + Image9 *source, + const gl::Rectangle &sourceRect, + const gl::Offset &destOffset, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) +{ + IDirect3DSurface9 *sourceSurface = nullptr; + ANGLE_TRY(source->getSurface(&sourceSurface)); + + IDirect3DSurface9 *destSurface = nullptr; + ANGLE_TRY(dest->getSurface(&destSurface)); + + D3DSURFACE_DESC destDesc; + HRESULT result = destSurface->GetDesc(&destDesc); + ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::OutOfMemory() + << "Failed to query the source surface description for mipmap generation, " + << gl::FmtHR(result); + } + const d3d9::D3DFormat &destD3DFormatInfo = d3d9::GetD3DFormatInfo(destDesc.Format); + + D3DSURFACE_DESC sourceDesc; + result = sourceSurface->GetDesc(&sourceDesc); + ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::OutOfMemory() + << "Failed to query the destination surface description for mipmap generation, " + << gl::FmtHR(result); + } + const d3d9::D3DFormat &sourceD3DFormatInfo = d3d9::GetD3DFormatInfo(sourceDesc.Format); + + D3DLOCKED_RECT sourceLocked = {0}; + result = sourceSurface->LockRect(&sourceLocked, nullptr, D3DLOCK_READONLY); + ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::OutOfMemory() << "Failed to lock the source surface for CopyImage, " + << gl::FmtHR(result); + } + + D3DLOCKED_RECT destLocked = {0}; + result = destSurface->LockRect(&destLocked, nullptr, 0); + ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + sourceSurface->UnlockRect(); + return gl::OutOfMemory() << "Failed to lock the destination surface for CopyImage, " + << gl::FmtHR(result); + } + + const uint8_t *sourceData = reinterpret_cast(sourceLocked.pBits) + + sourceRect.x * sourceD3DFormatInfo.pixelBytes + + sourceRect.y * sourceLocked.Pitch; + uint8_t *destData = reinterpret_cast(destLocked.pBits) + + destOffset.x * destD3DFormatInfo.pixelBytes + + destOffset.y * destLocked.Pitch; + ASSERT(sourceData && destData); + + CopyImageCHROMIUM(sourceData, sourceLocked.Pitch, sourceD3DFormatInfo.pixelBytes, + sourceD3DFormatInfo.info().colorReadFunction, destData, destLocked.Pitch, + destD3DFormatInfo.pixelBytes, destD3DFormatInfo.info().colorWriteFunction, + gl::GetUnsizedFormat(dest->getInternalFormat()), + destD3DFormatInfo.info().componentType, sourceRect.width, sourceRect.height, + unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha); + + destSurface->UnlockRect(); + sourceSurface->UnlockRect(); + + return gl::NoError(); } bool Image9::redefine(GLenum target, GLenum internalformat, const gl::Extents &size, bool forceRelease) @@ -189,7 +262,7 @@ bool Image9::redefine(GLenum target, GLenum internalformat, const gl::Extents &s mRenderable = (d3d9FormatInfo.renderFormat != D3DFMT_UNKNOWN); SafeRelease(mSurface); - mDirty = (d3d9FormatInfo.dataInitializerFunction != NULL); + mDirty = (d3d9FormatInfo.dataInitializerFunction != nullptr); return true; } @@ -201,11 +274,11 @@ gl::Error Image9::createSurface() { if (mSurface) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } - IDirect3DTexture9 *newTexture = NULL; - IDirect3DSurface9 *newSurface = NULL; + IDirect3DTexture9 *newTexture = nullptr; + IDirect3DSurface9 *newSurface = nullptr; const D3DPOOL poolToUse = D3DPOOL_SYSTEMMEM; const D3DFORMAT d3dFormat = getD3DFormat(); @@ -218,20 +291,20 @@ gl::Error Image9::createSurface() IDirect3DDevice9 *device = mRenderer->getDevice(); - HRESULT result = device->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, 0, d3dFormat, - poolToUse, &newTexture, NULL); + HRESULT result = device->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, 0, + d3dFormat, poolToUse, &newTexture, nullptr); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create image surface, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to create image surface, " << gl::FmtHR(result); } newTexture->GetSurfaceLevel(levelToFetch, &newSurface); SafeRelease(newTexture); const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat); - if (d3dFormatInfo.dataInitializerFunction != NULL) + if (d3dFormatInfo.dataInitializerFunction != nullptr) { RECT entireRect; entireRect.left = 0; @@ -244,7 +317,7 @@ gl::Error Image9::createSurface() ASSERT(SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock image surface, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to lock image surface, " << gl::FmtHR(result); } d3dFormatInfo.dataInitializerFunction(mWidth, mHeight, 1, reinterpret_cast(lockedRect.pBits), @@ -254,7 +327,7 @@ gl::Error Image9::createSurface() ASSERT(SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to unlock image surface, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to unlock image surface, " << gl::FmtHR(result); } } } @@ -263,7 +336,7 @@ gl::Error Image9::createSurface() mDirty = false; mD3DPool = poolToUse; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Image9::lock(D3DLOCKED_RECT *lockedRect, const RECT &rect) @@ -280,13 +353,13 @@ gl::Error Image9::lock(D3DLOCKED_RECT *lockedRect, const RECT &rect) ASSERT(SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock image surface, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to lock image surface, " << gl::FmtHR(result); } mDirty = true; } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } void Image9::unlock() @@ -294,7 +367,6 @@ void Image9::unlock() if (mSurface) { HRESULT result = mSurface->UnlockRect(); - UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); } } @@ -312,7 +384,9 @@ bool Image9::isDirty() const { // Make sure to that this image is marked as dirty even if the staging texture hasn't been created yet // if initialization is required before use. - return (mSurface || d3d9::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL) && mDirty; + return (mSurface || + d3d9::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != nullptr) && + mDirty; } gl::Error Image9::getSurface(IDirect3DSurface9 **outSurface) @@ -324,14 +398,16 @@ gl::Error Image9::getSurface(IDirect3DSurface9 **outSurface) } *outSurface = mSurface; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Image9::setManagedSurface2D(TextureStorage *storage, int level) +gl::Error Image9::setManagedSurface2D(const gl::Context *context, + TextureStorage *storage, + int level) { - IDirect3DSurface9 *surface = NULL; + IDirect3DSurface9 *surface = nullptr; TextureStorage9 *storage9 = GetAs(storage); - gl::Error error = storage9->getSurfaceLevel(GL_TEXTURE_2D, level, false, &surface); + gl::Error error = storage9->getSurfaceLevel(context, GL_TEXTURE_2D, level, false, &surface); if (error.isError()) { return error; @@ -339,12 +415,15 @@ gl::Error Image9::setManagedSurface2D(TextureStorage *storage, int level) return setManagedSurface(surface); } -gl::Error Image9::setManagedSurfaceCube(TextureStorage *storage, int face, int level) +gl::Error Image9::setManagedSurfaceCube(const gl::Context *context, + TextureStorage *storage, + int face, + int level) { - IDirect3DSurface9 *surface = NULL; + IDirect3DSurface9 *surface = nullptr; TextureStorage9 *storage9 = GetAs(storage); - gl::Error error = - storage9->getSurfaceLevel(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false, &surface); + gl::Error error = storage9->getSurfaceLevel(context, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, + level, false, &surface); if (error.isError()) { return error; @@ -374,10 +453,13 @@ gl::Error Image9::setManagedSurface(IDirect3DSurface9 *surface) mD3DPool = desc.Pool; } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Image9::copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box ®ion) +gl::Error Image9::copyToStorage(const gl::Context *context, + TextureStorage *storage, + const gl::ImageIndex &index, + const gl::Box ®ion) { gl::Error error = createSurface(); if (error.isError()) @@ -387,11 +469,12 @@ gl::Error Image9::copyToStorage(TextureStorage *storage, const gl::ImageIndex &i TextureStorage9 *storage9 = GetAs(storage); - IDirect3DSurface9 *destSurface = NULL; + IDirect3DSurface9 *destSurface = nullptr; if (index.type == GL_TEXTURE_2D) { - error = storage9->getSurfaceLevel(GL_TEXTURE_2D, index.mipIndex, true, &destSurface); + error = + storage9->getSurfaceLevel(context, GL_TEXTURE_2D, index.mipIndex, true, &destSurface); if (error.isError()) { return error; @@ -400,7 +483,7 @@ gl::Error Image9::copyToStorage(TextureStorage *storage, const gl::ImageIndex &i else { ASSERT(gl::IsCubeMapTextureTarget(index.type)); - error = storage9->getSurfaceLevel(index.type, index.mipIndex, true, &destSurface); + error = storage9->getSurfaceLevel(context, index.type, index.mipIndex, true, &destSurface); if (error.isError()) { return error; @@ -417,7 +500,7 @@ gl::Error Image9::copyToSurface(IDirect3DSurface9 *destSurface, const gl::Box &a ASSERT(area.width > 0 && area.height > 0 && area.depth == 1); ASSERT(destSurface); - IDirect3DSurface9 *sourceSurface = NULL; + IDirect3DSurface9 *sourceSurface = nullptr; gl::Error error = getSurface(&sourceSurface); if (error.isError()) { @@ -442,19 +525,22 @@ gl::Error Image9::copyToSurface(IDirect3DSurface9 *destSurface, const gl::Box &a sourceSurface->GetDesc(&desc); IDirect3DSurface9 *surf = 0; - HRESULT result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL); + HRESULT result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, + D3DPOOL_SYSTEMMEM, &surf, nullptr); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal CreateOffscreenPlainSurface call failed, result: 0x%X.", result); + return gl::OutOfMemory() + << "Internal CreateOffscreenPlainSurface call failed, " << gl::FmtHR(result); } - copyLockableSurfaces(surf, sourceSurface); + auto err = copyLockableSurfaces(surf, sourceSurface); result = device->UpdateSurface(surf, &rect, destSurface, &point); SafeRelease(surf); + ANGLE_TRY(err); ASSERT(SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal UpdateSurface call failed, result: 0x%X.", result); + return gl::OutOfMemory() << "Internal UpdateSurface call failed, " << gl::FmtHR(result); } } else @@ -464,27 +550,36 @@ gl::Error Image9::copyToSurface(IDirect3DSurface9 *destSurface, const gl::Box &a ASSERT(SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal UpdateSurface call failed, result: 0x%X.", result); + return gl::OutOfMemory() << "Internal UpdateSurface call failed, " << gl::FmtHR(result); } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } // Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input // into the target pixel rectangle. -gl::Error Image9::loadData(const gl::Box &area, const gl::PixelUnpackState &unpack, GLenum type, const void *input) +gl::Error Image9::loadData(const gl::Context *context, + const gl::Box &area, + const gl::PixelUnpackState &unpack, + GLenum type, + const void *input, + bool applySkipImages) { // 3D textures are not supported by the D3D9 backend. ASSERT(area.z == 0 && area.depth == 1); - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); - GLsizei inputRowPitch = formatInfo.computeRowPitch(type, area.width, unpack.alignment, unpack.rowLength); - GLsizei inputSkipBytes = formatInfo.computeSkipPixels(inputRowPitch, 0, unpack.skipImages, - unpack.skipRows, unpack.skipPixels); + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(mInternalFormat); + GLuint inputRowPitch = 0; + ANGLE_TRY_RESULT( + formatInfo.computeRowPitch(type, area.width, unpack.alignment, unpack.rowLength), + inputRowPitch); + ASSERT(!applySkipImages); + ASSERT(unpack.skipPixels == 0); + ASSERT(unpack.skipRows == 0); const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat); - ASSERT(d3dFormatInfo.loadFunction != NULL); + ASSERT(d3dFormatInfo.loadFunction != nullptr); RECT lockRect = { @@ -500,31 +595,34 @@ gl::Error Image9::loadData(const gl::Box &area, const gl::PixelUnpackState &unpa } d3dFormatInfo.loadFunction(area.width, area.height, area.depth, - reinterpret_cast(input) + inputSkipBytes, - inputRowPitch, 0, reinterpret_cast(locked.pBits), - locked.Pitch, 0); + reinterpret_cast(input), inputRowPitch, 0, + reinterpret_cast(locked.pBits), locked.Pitch, 0); unlock(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Image9::loadCompressedData(const gl::Box &area, const void *input) +gl::Error Image9::loadCompressedData(const gl::Context *context, + const gl::Box &area, + const void *input) { // 3D textures are not supported by the D3D9 backend. ASSERT(area.z == 0 && area.depth == 1); - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); - GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, area.width, 1, 0); - GLsizei inputDepthPitch = - formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0, 0); + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(mInternalFormat); + GLsizei inputRowPitch = 0; + ANGLE_TRY_RESULT(formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, area.width, 1, 0), inputRowPitch); + GLsizei inputDepthPitch = 0; + ANGLE_TRY_RESULT(formatInfo.computeDepthPitch(area.height, 0, inputDepthPitch), + inputDepthPitch); const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat); ASSERT(area.x % d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat).blockWidth == 0); ASSERT(area.y % d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat).blockHeight == 0); - ASSERT(d3d9FormatInfo.loadFunction != NULL); + ASSERT(d3d9FormatInfo.loadFunction != nullptr); RECT lockRect = { @@ -545,7 +643,7 @@ gl::Error Image9::loadCompressedData(const gl::Box &area, const void *input) unlock(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } // This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats and incomplete textures @@ -565,16 +663,19 @@ gl::Error Image9::copyFromRTInternal(const gl::Offset &destOffset, IDirect3DDevice9 *device = mRenderer->getDevice(); - IDirect3DSurface9 *renderTargetData = NULL; + IDirect3DSurface9 *renderTargetData = nullptr; D3DSURFACE_DESC description; surface->GetDesc(&description); - HRESULT result = device->CreateOffscreenPlainSurface(description.Width, description.Height, description.Format, D3DPOOL_SYSTEMMEM, &renderTargetData, NULL); + HRESULT result = device->CreateOffscreenPlainSurface(description.Width, description.Height, + description.Format, D3DPOOL_SYSTEMMEM, + &renderTargetData, nullptr); if (FAILED(result)) { SafeRelease(surface); - return gl::Error(GL_OUT_OF_MEMORY, "Could not create matching destination surface, result: 0x%X.", result); + return gl::OutOfMemory() << "Could not create matching destination surface, " + << gl::FmtHR(result); } result = device->GetRenderTargetData(surface, renderTargetData); @@ -583,7 +684,8 @@ gl::Error Image9::copyFromRTInternal(const gl::Offset &destOffset, { SafeRelease(renderTargetData); SafeRelease(surface); - return gl::Error(GL_OUT_OF_MEMORY, "GetRenderTargetData unexpectedly failed, result: 0x%X.", result); + return gl::OutOfMemory() << "GetRenderTargetData unexpectedly failed, " + << gl::FmtHR(result); } int width = sourceArea.width; @@ -599,7 +701,9 @@ gl::Error Image9::copyFromRTInternal(const gl::Offset &destOffset, { SafeRelease(renderTargetData); SafeRelease(surface); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock the source surface (rectangle might be invalid), result: 0x%X.", result); + return gl::OutOfMemory() + << "Failed to lock the source surface (rectangle might be invalid), " + << gl::FmtHR(result); } D3DLOCKED_RECT destLock = {0}; @@ -776,13 +880,15 @@ gl::Error Image9::copyFromRTInternal(const gl::Offset &destOffset, SafeRelease(surface); mDirty = true; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Image9::copyFromTexStorage(const gl::ImageIndex &imageIndex, TextureStorage *source) +gl::Error Image9::copyFromTexStorage(const gl::Context *context, + const gl::ImageIndex &imageIndex, + TextureStorage *source) { RenderTargetD3D *renderTarget = nullptr; - gl::Error error = source->getRenderTarget(imageIndex, &renderTarget); + gl::Error error = source->getRenderTarget(context, imageIndex, &renderTarget); if (error.isError()) { return error; @@ -792,15 +898,16 @@ gl::Error Image9::copyFromTexStorage(const gl::ImageIndex &imageIndex, TextureSt return copyFromRTInternal(gl::Offset(), sourceArea, renderTarget); } -gl::Error Image9::copyFromFramebuffer(const gl::Offset &destOffset, +gl::Error Image9::copyFromFramebuffer(const gl::Context *context, + const gl::Offset &destOffset, const gl::Rectangle &sourceArea, const gl::Framebuffer *source) { const gl::FramebufferAttachment *srcAttachment = source->getReadColorbuffer(); ASSERT(srcAttachment); - RenderTargetD3D *renderTarget = NULL; - gl::Error error = srcAttachment->getRenderTarget(&renderTarget); + RenderTargetD3D *renderTarget = nullptr; + gl::Error error = srcAttachment->getRenderTarget(context, &renderTarget); if (error.isError()) { return error; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.h index 91448cc849..01c60dc4fb 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.h @@ -26,27 +26,53 @@ class Image9 : public ImageD3D { public: Image9(Renderer9 *renderer); - ~Image9(); + ~Image9() override; static gl::Error generateMipmap(Image9 *dest, Image9 *source); static gl::Error generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface); static gl::Error copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source); + static gl::Error CopyImage(const gl::Context *context, + Image9 *dest, + Image9 *source, + const gl::Rectangle &sourceRect, + const gl::Offset &destOffset, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha); bool redefine(GLenum target, GLenum internalformat, const gl::Extents &size, bool forceRelease) override; D3DFORMAT getD3DFormat() const; - virtual bool isDirty() const; + bool isDirty() const override; - virtual gl::Error setManagedSurface2D(TextureStorage *storage, int level); - virtual gl::Error setManagedSurfaceCube(TextureStorage *storage, int face, int level); - virtual gl::Error copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box ®ion); + gl::Error setManagedSurface2D(const gl::Context *context, + TextureStorage *storage, + int level) override; + gl::Error setManagedSurfaceCube(const gl::Context *context, + TextureStorage *storage, + int face, + int level) override; + gl::Error copyToStorage(const gl::Context *context, + TextureStorage *storage, + const gl::ImageIndex &index, + const gl::Box ®ion) override; - virtual gl::Error loadData(const gl::Box &area, const gl::PixelUnpackState &unpack, GLenum type, const void *input); - virtual gl::Error loadCompressedData(const gl::Box &area, const void *input); + gl::Error loadData(const gl::Context *context, + const gl::Box &area, + const gl::PixelUnpackState &unpack, + GLenum type, + const void *input, + bool applySkipImages) override; + gl::Error loadCompressedData(const gl::Context *context, + const gl::Box &area, + const void *input) override; - gl::Error copyFromTexStorage(const gl::ImageIndex &imageIndex, TextureStorage *source) override; - gl::Error copyFromFramebuffer(const gl::Offset &destOffset, + gl::Error copyFromTexStorage(const gl::Context *context, + const gl::ImageIndex &imageIndex, + TextureStorage *source) override; + gl::Error copyFromFramebuffer(const gl::Context *context, + const gl::Offset &destOffset, const gl::Rectangle &sourceArea, const gl::Framebuffer *source) override; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp index 97c7f72136..df86331766 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp @@ -14,7 +14,7 @@ namespace rx IndexBuffer9::IndexBuffer9(Renderer9 *const renderer) : mRenderer(renderer) { - mIndexBuffer = NULL; + mIndexBuffer = nullptr; mBufferSize = 0; mIndexType = 0; mDynamic = false; @@ -40,7 +40,7 @@ gl::Error IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bo } else if (indexType == GL_UNSIGNED_INT) { - ASSERT(mRenderer->getRendererExtensions().elementIndexUint); + ASSERT(mRenderer->getNativeExtensions().elementIndexUint); format = D3DFMT_INDEX32; } else UNREACHABLE(); @@ -54,7 +54,8 @@ gl::Error IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bo HRESULT result = mRenderer->createIndexBuffer(bufferSize, usageFlags, format, &mIndexBuffer); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal index buffer of size, %lu.", bufferSize); + return gl::OutOfMemory() + << "Failed to allocate internal index buffer of size " << bufferSize; } } @@ -62,43 +63,43 @@ gl::Error IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bo mIndexType = indexType; mDynamic = dynamic; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error IndexBuffer9::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory) { if (!mIndexBuffer) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized."); + return gl::OutOfMemory() << "Internal index buffer is not initialized."; } DWORD lockFlags = mDynamic ? D3DLOCK_NOOVERWRITE : 0; - void *mapPtr = NULL; + void *mapPtr = nullptr; HRESULT result = mIndexBuffer->Lock(offset, size, &mapPtr, lockFlags); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal index buffer, HRESULT: 0x%08x.", result); + return gl::OutOfMemory() << "Failed to lock internal index buffer, " << gl::FmtHR(result); } *outMappedMemory = mapPtr; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error IndexBuffer9::unmapBuffer() { if (!mIndexBuffer) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized."); + return gl::OutOfMemory() << "Internal index buffer is not initialized."; } HRESULT result = mIndexBuffer->Unlock(); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to unlock internal index buffer, HRESULT: 0x%08x.", result); + return gl::OutOfMemory() << "Failed to unlock internal index buffer, " << gl::FmtHR(result); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } GLenum IndexBuffer9::getIndexType() const @@ -119,7 +120,7 @@ gl::Error IndexBuffer9::setSize(unsigned int bufferSize, GLenum indexType) } else { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } } @@ -127,7 +128,7 @@ gl::Error IndexBuffer9::discard() { if (!mIndexBuffer) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized."); + return gl::OutOfMemory() << "Internal index buffer is not initialized."; } void *dummy; @@ -136,16 +137,16 @@ gl::Error IndexBuffer9::discard() result = mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal index buffer, HRESULT: 0x%08x.", result); + return gl::OutOfMemory() << "Failed to lock internal index buffer, " << gl::FmtHR(result); } result = mIndexBuffer->Unlock(); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to unlock internal index buffer, HRESULT: 0x%08x.", result); + return gl::OutOfMemory() << "Failed to unlock internal index buffer, " << gl::FmtHR(result); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } D3DFORMAT IndexBuffer9::getIndexFormat() const diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h index ba03ba703f..5921d2a859 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h @@ -19,18 +19,18 @@ class IndexBuffer9 : public IndexBuffer { public: explicit IndexBuffer9(Renderer9 *const renderer); - virtual ~IndexBuffer9(); + ~IndexBuffer9() override; - virtual gl::Error initialize(unsigned int bufferSize, GLenum indexType, bool dynamic); + gl::Error initialize(unsigned int bufferSize, GLenum indexType, bool dynamic) override; - virtual gl::Error mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory); - virtual gl::Error unmapBuffer(); + gl::Error mapBuffer(unsigned int offset, unsigned int size, void **outMappedMemory) override; + gl::Error unmapBuffer() override; - virtual GLenum getIndexType() const; - virtual unsigned int getBufferSize() const; - virtual gl::Error setSize(unsigned int bufferSize, GLenum indexType); + GLenum getIndexType() const override; + unsigned int getBufferSize() const override; + gl::Error setSize(unsigned int bufferSize, GLenum indexType) override; - virtual gl::Error discard(); + gl::Error discard() override; D3DFORMAT getIndexFormat() const; IDirect3DIndexBuffer9 *getBuffer() const; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.cpp new file mode 100644 index 0000000000..388b8aa168 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.cpp @@ -0,0 +1,39 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// NativeWindow9.cpp: Defines NativeWindow9, a class for managing and +// performing operations on an EGLNativeWindowType for the D3D9 renderer. + +#include "libANGLE/renderer/d3d/d3d9/NativeWindow9.h" + +namespace rx +{ +NativeWindow9::NativeWindow9(EGLNativeWindowType window) : NativeWindowD3D(window) +{ +} + +bool NativeWindow9::initialize() +{ + return true; +} + +bool NativeWindow9::getClientRect(LPRECT rect) const +{ + return GetClientRect(getNativeWindow(), rect) == TRUE; +} + +bool NativeWindow9::isIconic() const +{ + return IsIconic(getNativeWindow()) == TRUE; +} + +// static +bool NativeWindow9::IsValidNativeWindow(EGLNativeWindowType window) +{ + return IsWindow(window) == TRUE; +} + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.h new file mode 100644 index 0000000000..a56b08dc81 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.h @@ -0,0 +1,35 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// NativeWindow9.h: Defines NativeWindow9, a class for managing and +// performing operations on an EGLNativeWindowType for the D3D9 renderer. + +#ifndef LIBANGLE_RENDERER_D3D_D3D9_NATIVEWINDOW9_H_ +#define LIBANGLE_RENDERER_D3D_D3D9_NATIVEWINDOW9_H_ + +#include "common/debug.h" +#include "common/platform.h" + +#include "libANGLE/renderer/d3d/NativeWindowD3D.h" + +namespace rx +{ + +class NativeWindow9 : public NativeWindowD3D +{ + public: + explicit NativeWindow9(EGLNativeWindowType window); + + bool initialize() override; + bool getClientRect(LPRECT rect) const override; + bool isIconic() const override; + + static bool IsValidNativeWindow(EGLNativeWindowType window); +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D9_NATIVEWINDOW9_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.cpp index c826abf81c..4ba053e6bd 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.cpp @@ -19,7 +19,7 @@ Query9::Query9(Renderer9 *renderer, GLenum type) mResult(GL_FALSE), mQueryFinished(false), mRenderer(renderer), - mQuery(NULL) + mQuery(nullptr) { } @@ -30,23 +30,27 @@ Query9::~Query9() gl::Error Query9::begin() { - if (mQuery == NULL) + D3DQUERYTYPE d3dQueryType = gl_d3d9::ConvertQueryType(getType()); + if (mQuery == nullptr) { - HRESULT result = mRenderer->getDevice()->CreateQuery(D3DQUERYTYPE_OCCLUSION, &mQuery); + HRESULT result = mRenderer->getDevice()->CreateQuery(d3dQueryType, &mQuery); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal query creation failed, result: 0x%X.", result); + return gl::OutOfMemory() << "Internal query creation failed, " << gl::FmtHR(result); } } - HRESULT result = mQuery->Issue(D3DISSUE_BEGIN); - ASSERT(SUCCEEDED(result)); - if (FAILED(result)) + if (d3dQueryType != D3DQUERYTYPE_EVENT) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to begin internal query, result: 0x%X.", result); + HRESULT result = mQuery->Issue(D3DISSUE_BEGIN); + ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::OutOfMemory() << "Failed to begin internal query, " << gl::FmtHR(result); + } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Query9::end() @@ -57,19 +61,19 @@ gl::Error Query9::end() ASSERT(SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to end internal query, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to end internal query, " << gl::FmtHR(result); } mQueryFinished = false; mResult = GL_FALSE; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Query9::queryCounter() { UNIMPLEMENTED(); - return gl::Error(GL_INVALID_OPERATION, "Unimplemented"); + return gl::InternalError() << "Unimplemented"; } template @@ -91,7 +95,7 @@ gl::Error Query9::getResultBase(T *params) ASSERT(mQueryFinished); *params = static_cast(mResult); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Query9::getResult(GLint *params) @@ -124,7 +128,7 @@ gl::Error Query9::isResultAvailable(bool *available) *available = mQueryFinished; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Query9::testQuery() @@ -133,38 +137,52 @@ gl::Error Query9::testQuery() { ASSERT(mQuery); - DWORD numPixels = 0; - - HRESULT hres = mQuery->GetData(&numPixels, sizeof(DWORD), D3DGETDATA_FLUSH); - if (hres == S_OK) + HRESULT result = S_OK; + switch (getType()) { - mQueryFinished = true; - - switch (getType()) + case GL_ANY_SAMPLES_PASSED_EXT: + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: { - case GL_ANY_SAMPLES_PASSED_EXT: - case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: - mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE; - break; - - default: - UNREACHABLE(); + DWORD numPixels = 0; + result = mQuery->GetData(&numPixels, sizeof(numPixels), D3DGETDATA_FLUSH); + if (result == S_OK) + { + mQueryFinished = true; + mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE; + } break; } + + case GL_COMMANDS_COMPLETED_CHROMIUM: + { + BOOL completed = FALSE; + result = mQuery->GetData(&completed, sizeof(completed), D3DGETDATA_FLUSH); + if (result == S_OK) + { + mQueryFinished = true; + mResult = (completed == TRUE) ? GL_TRUE : GL_FALSE; + } + break; + } + + default: + UNREACHABLE(); + break; } - else if (d3d9::isDeviceLostError(hres)) + + if (d3d9::isDeviceLostError(result)) { mRenderer->notifyDeviceLost(); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to test get query result, device is lost."); + return gl::OutOfMemory() << "Failed to test get query result, device is lost."; } else if (mRenderer->testDeviceLost()) { mRenderer->notifyDeviceLost(); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to test get query result, device is lost."); + return gl::OutOfMemory() << "Failed to test get query result, device is lost."; } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.h index 9d17711a00..6c7c22f096 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.h @@ -19,16 +19,16 @@ class Query9 : public QueryImpl { public: Query9(Renderer9 *renderer, GLenum type); - virtual ~Query9(); + ~Query9() override; - virtual gl::Error begin(); - virtual gl::Error end(); - virtual gl::Error queryCounter(); - virtual gl::Error getResult(GLint *params); - virtual gl::Error getResult(GLuint *params); - virtual gl::Error getResult(GLint64 *params); - virtual gl::Error getResult(GLuint64 *params); - virtual gl::Error isResultAvailable(bool *available); + gl::Error begin() override; + gl::Error end() override; + gl::Error queryCounter() override; + gl::Error getResult(GLint *params) override; + gl::Error getResult(GLuint *params) override; + gl::Error getResult(GLint64 *params) override; + gl::Error getResult(GLuint64 *params) override; + gl::Error isResultAvailable(bool *available) override; private: gl::Error testQuery(); diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp index 419bff1f63..3e54c27f43 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp @@ -130,7 +130,8 @@ GLsizei SurfaceRenderTarget9::getDepth() const GLenum SurfaceRenderTarget9::getInternalFormat() const { - return (mDepth ? mSwapChain->GetDepthBufferInternalFormat() : mSwapChain->GetRenderTargetInternalFormat()); + return (mDepth ? mSwapChain->getDepthBufferInternalFormat() + : mSwapChain->getRenderTargetInternalFormat()); } GLsizei SurfaceRenderTarget9::getSamples() const diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h index f19c54de7b..bb3b5a4ee4 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h @@ -21,7 +21,7 @@ class RenderTarget9 : public RenderTargetD3D { public: RenderTarget9() { } - virtual ~RenderTarget9() { } + ~RenderTarget9() override {} // Retrieve the texture that backs this render target, may be null for swap chain render // targets. virtual IDirect3DBaseTexture9 *getTexture() const = 0; @@ -43,7 +43,7 @@ class TextureRenderTarget9 : public RenderTarget9 GLsizei height, GLsizei depth, GLsizei samples); - virtual ~TextureRenderTarget9(); + ~TextureRenderTarget9() override; GLsizei getWidth() const override; GLsizei getHeight() const override; @@ -74,7 +74,7 @@ class SurfaceRenderTarget9 : public RenderTarget9 { public: SurfaceRenderTarget9(SwapChain9 *swapChain, bool depth); - virtual ~SurfaceRenderTarget9(); + ~SurfaceRenderTarget9() override; GLsizei getWidth() const override; GLsizei getHeight() const override; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp index 6bb975b0e4..75c6298868 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp @@ -8,34 +8,23 @@ #include "libANGLE/renderer/d3d/d3d9/Renderer9.h" -#include #include +#include #include "common/utilities.h" -#include "libANGLE/angletypes.h" #include "libANGLE/Buffer.h" +#include "libANGLE/Context.h" #include "libANGLE/Display.h" -#include "libANGLE/features.h" -#include "libANGLE/formatutils.h" #include "libANGLE/Framebuffer.h" #include "libANGLE/FramebufferAttachment.h" #include "libANGLE/Program.h" #include "libANGLE/Renderbuffer.h" -#include "libANGLE/renderer/d3d/d3d9/Blit9.h" -#include "libANGLE/renderer/d3d/d3d9/Buffer9.h" -#include "libANGLE/renderer/d3d/d3d9/Fence9.h" -#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" -#include "libANGLE/renderer/d3d/d3d9/Framebuffer9.h" -#include "libANGLE/renderer/d3d/d3d9/Image9.h" -#include "libANGLE/renderer/d3d/d3d9/IndexBuffer9.h" -#include "libANGLE/renderer/d3d/d3d9/Query9.h" -#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" -#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" -#include "libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h" -#include "libANGLE/renderer/d3d/d3d9/SwapChain9.h" -#include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h" -#include "libANGLE/renderer/d3d/d3d9/VertexArray9.h" -#include "libANGLE/renderer/d3d/d3d9/VertexBuffer9.h" +#include "libANGLE/State.h" +#include "libANGLE/Surface.h" +#include "libANGLE/Texture.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/features.h" +#include "libANGLE/formatutils.h" #include "libANGLE/renderer/d3d/CompilerD3D.h" #include "libANGLE/renderer/d3d/DeviceD3D.h" #include "libANGLE/renderer/d3d/FramebufferD3D.h" @@ -45,14 +34,25 @@ #include "libANGLE/renderer/d3d/ShaderD3D.h" #include "libANGLE/renderer/d3d/SurfaceD3D.h" #include "libANGLE/renderer/d3d/TextureD3D.h" -#include "libANGLE/renderer/d3d/TransformFeedbackD3D.h" -#include "libANGLE/State.h" -#include "libANGLE/Surface.h" -#include "libANGLE/Texture.h" +#include "libANGLE/renderer/d3d/d3d9/Blit9.h" +#include "libANGLE/renderer/d3d/d3d9/Buffer9.h" +#include "libANGLE/renderer/d3d/d3d9/Context9.h" +#include "libANGLE/renderer/d3d/d3d9/Fence9.h" +#include "libANGLE/renderer/d3d/d3d9/Framebuffer9.h" +#include "libANGLE/renderer/d3d/d3d9/Image9.h" +#include "libANGLE/renderer/d3d/d3d9/IndexBuffer9.h" +#include "libANGLE/renderer/d3d/d3d9/NativeWindow9.h" +#include "libANGLE/renderer/d3d/d3d9/Query9.h" +#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" +#include "libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h" +#include "libANGLE/renderer/d3d/d3d9/SwapChain9.h" +#include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h" +#include "libANGLE/renderer/d3d/d3d9/VertexArray9.h" +#include "libANGLE/renderer/d3d/d3d9/VertexBuffer9.h" +#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" +#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" #include "third_party/trace_event/trace_event.h" - - #if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL) #define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3 #endif @@ -69,69 +69,69 @@ namespace rx enum { MAX_VERTEX_CONSTANT_VECTORS_D3D9 = 256, - MAX_PIXEL_CONSTANT_VECTORS_SM2 = 32, - MAX_PIXEL_CONSTANT_VECTORS_SM3 = 224, - MAX_VARYING_VECTORS_SM2 = 8, - MAX_VARYING_VECTORS_SM3 = 10, + MAX_PIXEL_CONSTANT_VECTORS_SM2 = 32, + MAX_PIXEL_CONSTANT_VECTORS_SM3 = 224, + MAX_VARYING_VECTORS_SM2 = 8, + MAX_VARYING_VECTORS_SM3 = 10, MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 = 4 }; Renderer9::Renderer9(egl::Display *display) : RendererD3D(display), mStateManager(this) { - mD3d9Module = NULL; + mD3d9Module = nullptr; - mD3d9 = NULL; - mD3d9Ex = NULL; - mDevice = NULL; - mDeviceEx = NULL; - mDeviceWindow = NULL; - mBlit = NULL; + mD3d9 = nullptr; + mD3d9Ex = nullptr; + mDevice = nullptr; + mDeviceEx = nullptr; + mDeviceWindow = nullptr; + mBlit = nullptr; mAdapter = D3DADAPTER_DEFAULT; const egl::AttributeMap &attributes = display->getAttributeMap(); - EGLint requestedDeviceType = attributes.get(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, - EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE); + EGLint requestedDeviceType = static_cast(attributes.get( + EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE)); switch (requestedDeviceType) { - case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE: - mDeviceType = D3DDEVTYPE_HAL; - break; + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE: + mDeviceType = D3DDEVTYPE_HAL; + break; - case EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE: - mDeviceType = D3DDEVTYPE_REF; - break; + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE: + mDeviceType = D3DDEVTYPE_REF; + break; - case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE: - mDeviceType = D3DDEVTYPE_NULLREF; - break; + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE: + mDeviceType = D3DDEVTYPE_NULLREF; + break; - default: - UNREACHABLE(); + default: + UNREACHABLE(); } - mMaskedClearSavedState = NULL; + mMaskedClearSavedState = nullptr; - mVertexDataManager = NULL; - mIndexDataManager = NULL; - mLineLoopIB = NULL; - mCountingIB = NULL; + mVertexDataManager = nullptr; + mIndexDataManager = nullptr; + mLineLoopIB = nullptr; + mCountingIB = nullptr; mMaxNullColorbufferLRU = 0; for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++) { mNullColorbufferCache[i].lruCount = 0; - mNullColorbufferCache[i].width = 0; - mNullColorbufferCache[i].height = 0; - mNullColorbufferCache[i].buffer = NULL; + mNullColorbufferCache[i].width = 0; + mNullColorbufferCache[i].height = 0; + mNullColorbufferCache[i].buffer = nullptr; } - mAppliedVertexShader = NULL; - mAppliedPixelShader = NULL; + mAppliedVertexShader = nullptr; + mAppliedPixelShader = nullptr; mAppliedProgramSerial = 0; - initializeDebugAnnotator(); + gl::InitializeDebugAnnotations(&mAnnotator); mEGLDevice = nullptr; } @@ -154,6 +154,10 @@ void Renderer9::release() { RendererD3D::cleanup(); + gl::UninitializeDebugAnnotations(); + + mTranslatedAttribCache.clear(); + releaseDeviceResources(); SafeDelete(mEGLDevice); @@ -167,10 +171,10 @@ void Renderer9::release() if (mDeviceWindow) { DestroyWindow(mDeviceWindow); - mDeviceWindow = NULL; + mDeviceWindow = nullptr; } - mD3d9Module = NULL; + mD3d9Module = nullptr; } egl::Error Renderer9::initialize() @@ -178,22 +182,25 @@ egl::Error Renderer9::initialize() TRACE_EVENT0("gpu.angle", "GetModuleHandle_d3d9"); mD3d9Module = GetModuleHandle(TEXT("d3d9.dll")); - if (mD3d9Module == NULL) + if (mD3d9Module == nullptr) { - return egl::Error(EGL_NOT_INITIALIZED, D3D9_INIT_MISSING_DEP, "No D3D9 module found."); + return egl::EglNotInitialized(D3D9_INIT_MISSING_DEP) << "No D3D9 module found."; } - typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex**); - Direct3DCreate9ExFunc Direct3DCreate9ExPtr = reinterpret_cast(GetProcAddress(mD3d9Module, "Direct3DCreate9Ex")); + typedef HRESULT(WINAPI * Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex **); + Direct3DCreate9ExFunc Direct3DCreate9ExPtr = + reinterpret_cast(GetProcAddress(mD3d9Module, "Direct3DCreate9Ex")); // Use Direct3D9Ex if available. Among other things, this version is less // inclined to report a lost context, for example when the user switches - // desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are available. - if (ANGLE_D3D9EX == ANGLE_ENABLED && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex))) + // desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are + // available. + if (ANGLE_D3D9EX == ANGLE_ENABLED && Direct3DCreate9ExPtr && + SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex))) { TRACE_EVENT0("gpu.angle", "D3d9Ex_QueryInterface"); ASSERT(mD3d9Ex); - mD3d9Ex->QueryInterface(IID_IDirect3D9, reinterpret_cast(&mD3d9)); + mD3d9Ex->QueryInterface(__uuidof(IDirect3D9), reinterpret_cast(&mD3d9)); ASSERT(mD3d9); } else @@ -204,12 +211,13 @@ egl::Error Renderer9::initialize() if (!mD3d9) { - return egl::Error(EGL_NOT_INITIALIZED, D3D9_INIT_MISSING_DEP, "Could not create D3D9 device."); + return egl::EglNotInitialized(D3D9_INIT_MISSING_DEP) << "Could not create D3D9 device."; } if (mDisplay->getNativeDisplayId() != nullptr) { - // UNIMPLEMENTED(); // FIXME: Determine which adapter index the device context corresponds to + // UNIMPLEMENTED(); // FIXME: Determine which adapter index the device context + // corresponds to } HRESULT result; @@ -226,13 +234,14 @@ egl::Error Renderer9::initialize() } else if (result == D3DERR_NOTAVAILABLE) { - Sleep(100); // Give the driver some time to initialize/recover + Sleep(100); // Give the driver some time to initialize/recover } - else if (FAILED(result)) // D3DERR_OUTOFVIDEOMEMORY, E_OUTOFMEMORY, D3DERR_INVALIDDEVICE, or another error we can't recover from + else if (FAILED(result)) // D3DERR_OUTOFVIDEOMEMORY, E_OUTOFMEMORY, + // D3DERR_INVALIDDEVICE, or another error we can't recover + // from { - return egl::Error(EGL_NOT_INITIALIZED, - D3D9_INIT_OTHER_ERROR, - "Failed to get device caps: Error code 0x%x\n", result); + return egl::EglNotInitialized(D3D9_INIT_OTHER_ERROR) + << "Failed to get device caps, " << gl::FmtHR(result); } } } @@ -245,18 +254,17 @@ egl::Error Renderer9::initialize() if (mDeviceCaps.PixelShaderVersion < D3DPS_VERSION(minShaderModel, 0)) { - return egl::Error(EGL_NOT_INITIALIZED, - D3D9_INIT_UNSUPPORTED_VERSION, - "Renderer does not support PS %u.%u.aborting!", minShaderModel, 0); + return egl::EglNotInitialized(D3D9_INIT_UNSUPPORTED_VERSION) + << "Renderer does not support PS " << minShaderModel << ".0, aborting!"; } - // When DirectX9 is running with an older DirectX8 driver, a StretchRect from a regular texture to a render target texture is not supported. - // This is required by Texture2D::ensureRenderTarget. + // When DirectX9 is running with an older DirectX8 driver, a StretchRect from a regular texture + // to a render target texture is not supported. This is required by + // Texture2D::ensureRenderTarget. if ((mDeviceCaps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES) == 0) { - return egl::Error(EGL_NOT_INITIALIZED, - D3D9_INIT_UNSUPPORTED_STRETCHRECT, - "Renderer does not support StretctRect from textures."); + return egl::EglNotInitialized(D3D9_INIT_UNSUPPORTED_STRETCHRECT) + << "Renderer does not support StretctRect from textures."; } { @@ -265,43 +273,52 @@ egl::Error Renderer9::initialize() } static const TCHAR windowName[] = TEXT("AngleHiddenWindow"); - static const TCHAR className[] = TEXT("STATIC"); + static const TCHAR className[] = TEXT("STATIC"); { TRACE_EVENT0("gpu.angle", "CreateWindowEx"); - mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL); + mDeviceWindow = + CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, + 1, HWND_MESSAGE, nullptr, GetModuleHandle(nullptr), nullptr); } D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters(); - DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES | D3DCREATE_MULTITHREADED; + DWORD behaviorFlags = + D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES | D3DCREATE_MULTITHREADED; { TRACE_EVENT0("gpu.angle", "D3d9_CreateDevice"); - result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice); + result = mD3d9->CreateDevice( + mAdapter, mDeviceType, mDeviceWindow, + behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, + &presentParameters, &mDevice); } if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DEVICELOST) { - return egl::Error(EGL_BAD_ALLOC, D3D9_INIT_OUT_OF_MEMORY, - "CreateDevice failed: device lost of out of memory"); + return egl::EglBadAlloc(D3D9_INIT_OUT_OF_MEMORY) + << "CreateDevice failed: device lost of out of memory"; } if (FAILED(result)) { TRACE_EVENT0("gpu.angle", "D3d9_CreateDevice2"); - result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParameters, &mDevice); + result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, + behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, + &presentParameters, &mDevice); if (FAILED(result)) { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_NOTAVAILABLE || result == D3DERR_DEVICELOST); - return egl::Error(EGL_BAD_ALLOC, D3D9_INIT_OUT_OF_MEMORY, - "CreateDevice2 failed: device lost, not available, or of out of memory"); + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || + result == D3DERR_NOTAVAILABLE || result == D3DERR_DEVICELOST); + return egl::EglBadAlloc(D3D9_INIT_OUT_OF_MEMORY) + << "CreateDevice2 failed: device lost, not available, or of out of memory"; } } if (mD3d9Ex) { TRACE_EVENT0("gpu.angle", "mDevice_QueryInterface"); - result = mDevice->QueryInterface(IID_IDirect3DDevice9Ex, (void**)&mDeviceEx); + result = mDevice->QueryInterface(__uuidof(IDirect3DDevice9Ex), (void **)&mDeviceEx); ASSERT(SUCCEEDED(result)); } @@ -318,18 +335,19 @@ egl::Error Renderer9::initialize() // Only Direct3D 10 ready devices support all the necessary vertex texture formats. // We test this using D3D9 by checking support for the R16F format. mVertexTextureSupport = mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && - SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, - D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, D3DFMT_R16F)); + SUCCEEDED(mD3d9->CheckDeviceFormat( + mAdapter, mDeviceType, currentDisplayMode.Format, + D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, D3DFMT_R16F)); - initializeDevice(); + ANGLE_TRY(initializeDevice()); - return egl::Error(EGL_SUCCESS); + return egl::NoError(); } // do any one-time device initialization // NOTE: this is also needed after a device lost/reset // to reset the scene status and ensure the default states are reset. -void Renderer9::initializeDevice() +egl::Error Renderer9::initializeDevice() { // Permanent non-default states mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE); @@ -337,14 +355,14 @@ void Renderer9::initializeDevice() if (mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) { - mDevice->SetRenderState(D3DRS_POINTSIZE_MAX, (DWORD&)mDeviceCaps.MaxPointSize); + mDevice->SetRenderState(D3DRS_POINTSIZE_MAX, (DWORD &)mDeviceCaps.MaxPointSize); } else { - mDevice->SetRenderState(D3DRS_POINTSIZE_MAX, 0x3F800000); // 1.0f + mDevice->SetRenderState(D3DRS_POINTSIZE_MAX, 0x3F800000); // 1.0f } - const gl::Caps &rendererCaps = getRendererCaps(); + const gl::Caps &rendererCaps = getNativeCaps(); mCurVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits); mCurPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits); @@ -358,50 +376,55 @@ void Renderer9::initializeDevice() ASSERT(!mBlit); mBlit = new Blit9(this); - mBlit->initialize(); + ANGLE_TRY(mBlit->initialize()); ASSERT(!mVertexDataManager && !mIndexDataManager); mVertexDataManager = new VertexDataManager(this); - mIndexDataManager = new IndexDataManager(this, getRendererClass()); + mIndexDataManager = new IndexDataManager(this); - // TODO(jmadill): use context caps, and place in common D3D location - mTranslatedAttribCache.resize(getRendererCaps().maxVertexAttributes); + if (mVertexDataManager->initialize().isError()) + { + return egl::EglBadAlloc() << "Error initializing VertexDataManager"; + } + + mTranslatedAttribCache.resize(getNativeCaps().maxVertexAttributes); + + mStateManager.initialize(); + + return egl::NoError(); } D3DPRESENT_PARAMETERS Renderer9::getDefaultPresentParameters() { D3DPRESENT_PARAMETERS presentParameters = {0}; - // The default swap chain is never actually used. Surface will create a new swap chain with the proper parameters. + // The default swap chain is never actually used. Surface will create a new swap chain with the + // proper parameters. presentParameters.AutoDepthStencilFormat = D3DFMT_UNKNOWN; - presentParameters.BackBufferCount = 1; - presentParameters.BackBufferFormat = D3DFMT_UNKNOWN; - presentParameters.BackBufferWidth = 1; - presentParameters.BackBufferHeight = 1; + presentParameters.BackBufferCount = 1; + presentParameters.BackBufferFormat = D3DFMT_UNKNOWN; + presentParameters.BackBufferWidth = 1; + presentParameters.BackBufferHeight = 1; presentParameters.EnableAutoDepthStencil = FALSE; - presentParameters.Flags = 0; - presentParameters.hDeviceWindow = mDeviceWindow; - presentParameters.MultiSampleQuality = 0; - presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; - presentParameters.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; - presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD; - presentParameters.Windowed = TRUE; + presentParameters.Flags = 0; + presentParameters.hDeviceWindow = mDeviceWindow; + presentParameters.MultiSampleQuality = 0; + presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; + presentParameters.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD; + presentParameters.Windowed = TRUE; return presentParameters; } -egl::ConfigSet Renderer9::generateConfigs() const +egl::ConfigSet Renderer9::generateConfigs() { - static const GLenum colorBufferFormats[] = - { - GL_BGR5_A1_ANGLEX, - GL_BGRA8_EXT, - GL_RGB565, + static const GLenum colorBufferFormats[] = { + GL_BGR5_A1_ANGLEX, GL_BGRA8_EXT, GL_RGB565, }; - static const GLenum depthStencilBufferFormats[] = - { + static const GLenum depthStencilBufferFormats[] = { GL_NONE, GL_DEPTH_COMPONENT32_OES, GL_DEPTH24_STENCIL8_OES, @@ -409,8 +432,8 @@ egl::ConfigSet Renderer9::generateConfigs() const GL_DEPTH_COMPONENT16, }; - const gl::Caps &rendererCaps = getRendererCaps(); - const gl::TextureCapsMap &rendererTextureCaps = getRendererTextureCaps(); + const gl::Caps &rendererCaps = getNativeCaps(); + const gl::TextureCapsMap &rendererTextureCaps = getNativeTextureCaps(); D3DDISPLAYMODE currentDisplayMode; mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); @@ -449,56 +472,72 @@ egl::ConfigSet Renderer9::generateConfigs() const for (size_t formatIndex = 0; formatIndex < ArraySize(colorBufferFormats); formatIndex++) { GLenum colorBufferInternalFormat = colorBufferFormats[formatIndex]; - const gl::TextureCaps &colorBufferFormatCaps = rendererTextureCaps.get(colorBufferInternalFormat); + const gl::TextureCaps &colorBufferFormatCaps = + rendererTextureCaps.get(colorBufferInternalFormat); if (colorBufferFormatCaps.renderable) { - for (size_t depthStencilIndex = 0; depthStencilIndex < ArraySize(depthStencilBufferFormats); depthStencilIndex++) + for (size_t depthStencilIndex = 0; + depthStencilIndex < ArraySize(depthStencilBufferFormats); depthStencilIndex++) { - GLenum depthStencilBufferInternalFormat = depthStencilBufferFormats[depthStencilIndex]; - const gl::TextureCaps &depthStencilBufferFormatCaps = rendererTextureCaps.get(depthStencilBufferInternalFormat); - if (depthStencilBufferFormatCaps.renderable || depthStencilBufferInternalFormat == GL_NONE) + GLenum depthStencilBufferInternalFormat = + depthStencilBufferFormats[depthStencilIndex]; + const gl::TextureCaps &depthStencilBufferFormatCaps = + rendererTextureCaps.get(depthStencilBufferInternalFormat); + if (depthStencilBufferFormatCaps.renderable || + depthStencilBufferInternalFormat == GL_NONE) { - const gl::InternalFormat &colorBufferFormatInfo = gl::GetInternalFormatInfo(colorBufferInternalFormat); - const gl::InternalFormat &depthStencilBufferFormatInfo = gl::GetInternalFormatInfo(depthStencilBufferInternalFormat); - const d3d9::TextureFormat &d3d9ColorBufferFormatInfo = d3d9::GetTextureFormatInfo(colorBufferInternalFormat); + const gl::InternalFormat &colorBufferFormatInfo = + gl::GetSizedInternalFormatInfo(colorBufferInternalFormat); + const gl::InternalFormat &depthStencilBufferFormatInfo = + gl::GetSizedInternalFormatInfo(depthStencilBufferInternalFormat); + const d3d9::TextureFormat &d3d9ColorBufferFormatInfo = + d3d9::GetTextureFormatInfo(colorBufferInternalFormat); egl::Config config; config.renderTargetFormat = colorBufferInternalFormat; config.depthStencilFormat = depthStencilBufferInternalFormat; - config.bufferSize = colorBufferFormatInfo.pixelBytes * 8; - config.redSize = colorBufferFormatInfo.redBits; - config.greenSize = colorBufferFormatInfo.greenBits; - config.blueSize = colorBufferFormatInfo.blueBits; - config.luminanceSize = colorBufferFormatInfo.luminanceBits; - config.alphaSize = colorBufferFormatInfo.alphaBits; - config.alphaMaskSize = 0; - config.bindToTextureRGB = (colorBufferFormatInfo.format == GL_RGB); - config.bindToTextureRGBA = (colorBufferFormatInfo.format == GL_RGBA || colorBufferFormatInfo.format == GL_BGRA_EXT); + config.bufferSize = colorBufferFormatInfo.pixelBytes * 8; + config.redSize = colorBufferFormatInfo.redBits; + config.greenSize = colorBufferFormatInfo.greenBits; + config.blueSize = colorBufferFormatInfo.blueBits; + config.luminanceSize = colorBufferFormatInfo.luminanceBits; + config.alphaSize = colorBufferFormatInfo.alphaBits; + config.alphaMaskSize = 0; + config.bindToTextureRGB = (colorBufferFormatInfo.format == GL_RGB); + config.bindToTextureRGBA = (colorBufferFormatInfo.format == GL_RGBA || + colorBufferFormatInfo.format == GL_BGRA_EXT); config.colorBufferType = EGL_RGB_BUFFER; // Mark as slow if blits to the back-buffer won't be straight forward - config.configCaveat = (currentDisplayMode.Format == d3d9ColorBufferFormatInfo.renderFormat) ? EGL_NONE : EGL_SLOW_CONFIG; - config.configID = static_cast(configs.size() + 1); - config.conformant = EGL_OPENGL_ES2_BIT; - config.depthSize = depthStencilBufferFormatInfo.depthBits; - config.level = 0; + config.configCaveat = + (currentDisplayMode.Format == d3d9ColorBufferFormatInfo.renderFormat) + ? EGL_NONE + : EGL_SLOW_CONFIG; + config.configID = static_cast(configs.size() + 1); + config.conformant = EGL_OPENGL_ES2_BIT; + config.depthSize = depthStencilBufferFormatInfo.depthBits; + config.level = 0; config.matchNativePixmap = EGL_NONE; - config.maxPBufferWidth = rendererCaps.max2DTextureSize; - config.maxPBufferHeight = rendererCaps.max2DTextureSize; - config.maxPBufferPixels = rendererCaps.max2DTextureSize * rendererCaps.max2DTextureSize; - config.maxSwapInterval = maxSwapInterval; - config.minSwapInterval = minSwapInterval; + config.maxPBufferWidth = rendererCaps.max2DTextureSize; + config.maxPBufferHeight = rendererCaps.max2DTextureSize; + config.maxPBufferPixels = + rendererCaps.max2DTextureSize * rendererCaps.max2DTextureSize; + config.maxSwapInterval = maxSwapInterval; + config.minSwapInterval = minSwapInterval; config.nativeRenderable = EGL_FALSE; - config.nativeVisualID = 0; + config.nativeVisualID = 0; config.nativeVisualType = EGL_NONE; - config.renderableType = EGL_OPENGL_ES2_BIT; - config.sampleBuffers = 0; // FIXME: enumerate multi-sampling - config.samples = 0; - config.stencilSize = depthStencilBufferFormatInfo.stencilBits; - config.surfaceType = EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT; - config.transparentType = EGL_NONE; - config.transparentRedValue = 0; + config.renderableType = EGL_OPENGL_ES2_BIT; + config.sampleBuffers = 0; // FIXME: enumerate multi-sampling + config.samples = 0; + config.stencilSize = depthStencilBufferFormatInfo.stencilBits; + config.surfaceType = + EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT; + config.transparentType = EGL_NONE; + config.transparentRedValue = 0; config.transparentGreenValue = 0; - config.transparentBlueValue = 0; + config.transparentBlueValue = 0; + config.colorComponentType = gl_egl::GLComponentTypeToEGLColorComponentType( + colorBufferFormatInfo.componentType); configs.add(config); } @@ -519,13 +558,12 @@ void Renderer9::generateDisplayExtensions(egl::DisplayExtensions *outExtensions) outExtensions->d3dShareHandleClientBuffer = true; outExtensions->surfaceD3DTexture2DShareHandle = true; } + outExtensions->d3dTextureClientBuffer = true; outExtensions->querySurfacePointer = true; outExtensions->windowFixedSize = true; outExtensions->postSubBuffer = true; - outExtensions->createContext = true; outExtensions->deviceQuery = true; - outExtensions->createContextNoError = true; outExtensions->image = true; outExtensions->imageBase = true; @@ -533,6 +571,14 @@ void Renderer9::generateDisplayExtensions(egl::DisplayExtensions *outExtensions) outExtensions->glRenderbufferImage = true; outExtensions->flexibleSurfaceCompatibility = true; + + // Contexts are virtualized so textures can be shared globally + outExtensions->displayTextureShareGroup = true; + + // D3D9 can be used without an output surface + outExtensions->surfacelessContext = true; + + outExtensions->robustResourceInitialization = true; } void Renderer9::startScene() @@ -540,7 +586,8 @@ void Renderer9::startScene() if (!mSceneStarted) { long result = mDevice->BeginScene(); - if (SUCCEEDED(result)) { + if (SUCCEEDED(result)) + { // This is defensive checking against the device being // lost at unexpected times. mSceneStarted = true; @@ -561,8 +608,8 @@ void Renderer9::endScene() gl::Error Renderer9::flush() { - IDirect3DQuery9* query = NULL; - gl::Error error = allocateEventQuery(&query); + IDirect3DQuery9 *query = nullptr; + gl::Error error = allocateEventQuery(&query); if (error.isError()) { return error; @@ -572,11 +619,11 @@ gl::Error Renderer9::flush() if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to issue event query, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to issue event query, " << gl::FmtHR(result); } // Grab the query data once - result = query->GetData(NULL, 0, D3DGETDATA_FLUSH); + result = query->GetData(nullptr, 0, D3DGETDATA_FLUSH); freeEventQuery(query); if (FAILED(result)) { @@ -585,16 +632,16 @@ gl::Error Renderer9::flush() notifyDeviceLost(); } - return gl::Error(GL_OUT_OF_MEMORY, "Failed to get event query data, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to get event query data, " << gl::FmtHR(result); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Renderer9::finish() { - IDirect3DQuery9* query = NULL; - gl::Error error = allocateEventQuery(&query); + IDirect3DQuery9 *query = nullptr; + gl::Error error = allocateEventQuery(&query); if (error.isError()) { return error; @@ -604,11 +651,11 @@ gl::Error Renderer9::finish() if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to issue event query, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to issue event query, " << gl::FmtHR(result); } // Grab the query data once - result = query->GetData(NULL, 0, D3DGETDATA_FLUSH); + result = query->GetData(nullptr, 0, D3DGETDATA_FLUSH); if (FAILED(result)) { if (d3d9::isDeviceLostError(result)) @@ -617,7 +664,7 @@ gl::Error Renderer9::finish() } freeEventQuery(query); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to get event query data, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to get event query data, " << gl::FmtHR(result); } // Loop until the query completes @@ -626,7 +673,7 @@ gl::Error Renderer9::finish() // Keep polling, but allow other threads to do something useful first ScheduleYield(); - result = query->GetData(NULL, 0, D3DGETDATA_FLUSH); + result = query->GetData(nullptr, 0, D3DGETDATA_FLUSH); // explicitly check for device loss // some drivers seem to return S_FALSE even if the device is lost @@ -644,34 +691,146 @@ gl::Error Renderer9::finish() } freeEventQuery(query); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to get event query data, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to get event query data, " << gl::FmtHR(result); } - } freeEventQuery(query); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -SwapChainD3D *Renderer9::createSwapChain(NativeWindow nativeWindow, +bool Renderer9::isValidNativeWindow(EGLNativeWindowType window) const +{ + return NativeWindow9::IsValidNativeWindow(window); +} + +NativeWindowD3D *Renderer9::createNativeWindow(EGLNativeWindowType window, + const egl::Config *, + const egl::AttributeMap &) const +{ + return new NativeWindow9(window); +} + +SwapChainD3D *Renderer9::createSwapChain(NativeWindowD3D *nativeWindow, HANDLE shareHandle, + IUnknown *d3dTexture, GLenum backBufferFormat, GLenum depthBufferFormat, - EGLint orientation) + EGLint orientation, + EGLint samples) { - return new SwapChain9(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat, - orientation); + return new SwapChain9(this, GetAs(nativeWindow), shareHandle, d3dTexture, + backBufferFormat, depthBufferFormat, orientation); } -CompilerImpl *Renderer9::createCompiler() +egl::Error Renderer9::getD3DTextureInfo(const egl::Config *config, + IUnknown *d3dTexture, + EGLint *width, + EGLint *height, + GLenum *fboFormat) const { - return new CompilerD3D(SH_HLSL_3_0_OUTPUT); + IDirect3DTexture9 *texture = nullptr; + if (FAILED(d3dTexture->QueryInterface(&texture))) + { + return egl::EglBadParameter() << "Client buffer is not a IDirect3DTexture9"; + } + + IDirect3DDevice9 *textureDevice = nullptr; + texture->GetDevice(&textureDevice); + if (textureDevice != mDevice) + { + SafeRelease(texture); + return egl::EglBadParameter() << "Texture's device does not match."; + } + SafeRelease(textureDevice); + + D3DSURFACE_DESC desc; + texture->GetLevelDesc(0, &desc); + SafeRelease(texture); + + if (width) + { + *width = static_cast(desc.Width); + } + if (height) + { + *height = static_cast(desc.Height); + } + + // From table egl.restrictions in EGL_ANGLE_d3d_texture_client_buffer. + switch (desc.Format) + { + case D3DFMT_R8G8B8: + case D3DFMT_A8R8G8B8: + case D3DFMT_A16B16G16R16F: + case D3DFMT_A32B32G32R32F: + break; + + default: + return egl::EglBadParameter() + << "Unknown client buffer texture format: " << desc.Format; + } + + if (fboFormat) + { + const auto &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format); + ASSERT(d3dFormatInfo.info().id != angle::Format::ID::NONE); + *fboFormat = d3dFormatInfo.info().fboImplementationInternalFormat; + } + + return egl::NoError(); +} + +egl::Error Renderer9::validateShareHandle(const egl::Config *config, + HANDLE shareHandle, + const egl::AttributeMap &attribs) const +{ + if (shareHandle == nullptr) + { + return egl::EglBadParameter() << "NULL share handle."; + } + + EGLint width = attribs.getAsInt(EGL_WIDTH, 0); + EGLint height = attribs.getAsInt(EGL_HEIGHT, 0); + ASSERT(width != 0 && height != 0); + + const d3d9::TextureFormat &backBufferd3dFormatInfo = + d3d9::GetTextureFormatInfo(config->renderTargetFormat); + + IDirect3DTexture9 *texture = nullptr; + HRESULT result = mDevice->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET, + backBufferd3dFormatInfo.texFormat, D3DPOOL_DEFAULT, + &texture, &shareHandle); + if (FAILED(result)) + { + return egl::EglBadParameter() << "Failed to open share handle, " << gl::FmtHR(result); + } + + DWORD levelCount = texture->GetLevelCount(); + + D3DSURFACE_DESC desc; + texture->GetLevelDesc(0, &desc); + SafeRelease(texture); + + if (levelCount != 1 || desc.Width != static_cast(width) || + desc.Height != static_cast(height) || + desc.Format != backBufferd3dFormatInfo.texFormat) + { + return egl::EglBadParameter() << "Invalid texture parameters in share handle texture."; + } + + return egl::NoError(); +} + +ContextImpl *Renderer9::createContext(const gl::ContextState &state) +{ + return new Context9(state, this); } void *Renderer9::getD3DDevice() { - return reinterpret_cast(mDevice); + return reinterpret_cast(mDevice); } gl::Error Renderer9::allocateEventQuery(IDirect3DQuery9 **outQuery) @@ -682,7 +841,7 @@ gl::Error Renderer9::allocateEventQuery(IDirect3DQuery9 **outQuery) if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate event query, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to allocate event query, " << gl::FmtHR(result); } } else @@ -691,10 +850,10 @@ gl::Error Renderer9::allocateEventQuery(IDirect3DQuery9 **outQuery) mEventQueryPool.pop_back(); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -void Renderer9::freeEventQuery(IDirect3DQuery9* query) +void Renderer9::freeEventQuery(IDirect3DQuery9 *query) { if (mEventQueryPool.size() > 1000) { @@ -706,20 +865,26 @@ void Renderer9::freeEventQuery(IDirect3DQuery9* query) } } -gl::Error Renderer9::createVertexShader(const DWORD *function, size_t length, IDirect3DVertexShader9 **outShader) +gl::Error Renderer9::createVertexShader(const DWORD *function, + size_t length, + IDirect3DVertexShader9 **outShader) { return mVertexShaderCache.create(function, length, outShader); } -gl::Error Renderer9::createPixelShader(const DWORD *function, size_t length, IDirect3DPixelShader9 **outShader) +gl::Error Renderer9::createPixelShader(const DWORD *function, + size_t length, + IDirect3DPixelShader9 **outShader) { return mPixelShaderCache.create(function, length, outShader); } -HRESULT Renderer9::createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer) +HRESULT Renderer9::createVertexBuffer(UINT Length, + DWORD Usage, + IDirect3DVertexBuffer9 **ppVertexBuffer) { D3DPOOL Pool = getBufferPool(Usage); - return mDevice->CreateVertexBuffer(Length, Usage, 0, Pool, ppVertexBuffer, NULL); + return mDevice->CreateVertexBuffer(Length, Usage, 0, Pool, ppVertexBuffer, nullptr); } VertexBuffer *Renderer9::createVertexBuffer() @@ -727,10 +892,13 @@ VertexBuffer *Renderer9::createVertexBuffer() return new VertexBuffer9(this); } -HRESULT Renderer9::createIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, IDirect3DIndexBuffer9 **ppIndexBuffer) +HRESULT Renderer9::createIndexBuffer(UINT Length, + DWORD Usage, + D3DFORMAT Format, + IDirect3DIndexBuffer9 **ppIndexBuffer) { D3DPOOL Pool = getBufferPool(Usage); - return mDevice->CreateIndexBuffer(Length, Usage, Format, Pool, ppIndexBuffer, NULL); + return mDevice->CreateIndexBuffer(Length, Usage, Format, Pool, ppIndexBuffer, nullptr); } IndexBuffer *Renderer9::createIndexBuffer() @@ -738,36 +906,13 @@ IndexBuffer *Renderer9::createIndexBuffer() return new IndexBuffer9(this); } -BufferImpl *Renderer9::createBuffer() +StreamProducerImpl *Renderer9::createStreamProducerD3DTextureNV12( + egl::Stream::ConsumerType consumerType, + const egl::AttributeMap &attribs) { - return new Buffer9(this); -} - -VertexArrayImpl *Renderer9::createVertexArray(const gl::VertexArray::Data &data) -{ - return new VertexArray9(data); -} - -QueryImpl *Renderer9::createQuery(GLenum type) -{ - return new Query9(this, type); -} - -FenceNVImpl *Renderer9::createFenceNV() -{ - return new FenceNV9(this); -} - -FenceSyncImpl *Renderer9::createFenceSync() -{ - // Renderer9 doesn't support ES 3.0 and its sync objects. + // Streams are not supported under D3D9 UNREACHABLE(); - return NULL; -} - -TransformFeedbackImpl* Renderer9::createTransformFeedback() -{ - return new TransformFeedbackD3D(); + return nullptr; } bool Renderer9::supportsFastCopyBufferToTexture(GLenum internalFormat) const @@ -776,22 +921,24 @@ bool Renderer9::supportsFastCopyBufferToTexture(GLenum internalFormat) const return false; } -gl::Error Renderer9::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget, - GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) +gl::Error Renderer9::fastCopyBufferToTexture(const gl::Context *context, + const gl::PixelUnpackState &unpack, + unsigned int offset, + RenderTargetD3D *destRenderTarget, + GLenum destinationFormat, + GLenum sourcePixelsType, + const gl::Box &destArea) { // Pixel buffer objects are not supported in D3D9, since D3D9 is ES2-only and PBOs are ES3. UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + return gl::InternalError(); } -gl::Error Renderer9::generateSwizzle(gl::Texture *texture) -{ - // Swizzled textures are not available in ES2 or D3D9 - UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); -} - -gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &samplerState) +gl::Error Renderer9::setSamplerState(const gl::Context *context, + gl::SamplerType type, + int index, + gl::Texture *texture, + const gl::SamplerState &samplerState) { CurSamplerState &appliedSampler = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates[index] : mCurVertexSamplerStates[index]; @@ -800,11 +947,7 @@ gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, gl::Textur TextureD3D *textureD3D = GetImplAs(texture); TextureStorage *storage = nullptr; - gl::Error error = textureD3D->getNativeTexture(&storage); - if (error.isError()) - { - return error; - } + ANGLE_TRY(textureD3D->getNativeTexture(context, &storage)); // Storage should exist, texture should be complete ASSERT(storage); @@ -815,12 +958,16 @@ gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, gl::Textur memcmp(&samplerState, &appliedSampler, sizeof(gl::SamplerState)) != 0) { int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0; - int d3dSampler = index + d3dSamplerOffset; + int d3dSampler = index + d3dSamplerOffset; - mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU, gl_d3d9::ConvertTextureWrap(samplerState.wrapS)); - mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, gl_d3d9::ConvertTextureWrap(samplerState.wrapT)); + mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU, + gl_d3d9::ConvertTextureWrap(samplerState.wrapS)); + mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, + gl_d3d9::ConvertTextureWrap(samplerState.wrapT)); - mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAGFILTER, gl_d3d9::ConvertMagFilter(samplerState.magFilter, samplerState.maxAnisotropy)); + mDevice->SetSamplerState( + d3dSampler, D3DSAMP_MAGFILTER, + gl_d3d9::ConvertMagFilter(samplerState.magFilter, samplerState.maxAnisotropy)); D3DTEXTUREFILTERTYPE d3dMinFilter, d3dMipFilter; float lodBias; @@ -830,52 +977,50 @@ gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, gl::Textur mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter); mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, baseLevel); mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPMAPLODBIAS, static_cast(lodBias)); - if (getRendererExtensions().textureFilterAnisotropic) + if (getNativeExtensions().textureFilterAnisotropic) { - mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXANISOTROPY, (DWORD)samplerState.maxAnisotropy); + DWORD maxAnisotropy = + std::min(mDeviceCaps.MaxAnisotropy, static_cast(samplerState.maxAnisotropy)); + mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXANISOTROPY, maxAnisotropy); } } - appliedSampler.forceSet = false; + appliedSampler.forceSet = false; appliedSampler.samplerState = samplerState; - appliedSampler.baseLevel = baseLevel; + appliedSampler.baseLevel = baseLevel; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *texture) +gl::Error Renderer9::setTexture(const gl::Context *context, + gl::SamplerType type, + int index, + gl::Texture *texture) { - int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0; - int d3dSampler = index + d3dSamplerOffset; - IDirect3DBaseTexture9 *d3dTexture = NULL; - bool forceSetTexture = false; + int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0; + int d3dSampler = index + d3dSamplerOffset; + IDirect3DBaseTexture9 *d3dTexture = nullptr; + bool forceSetTexture = false; - std::vector &appliedTextures = (type == gl::SAMPLER_PIXEL) ? mCurPixelTextures : mCurVertexTextures; + std::vector &appliedTextures = + (type == gl::SAMPLER_PIXEL) ? mCurPixelTextures : mCurVertexTextures; if (texture) { TextureD3D *textureImpl = GetImplAs(texture); TextureStorage *texStorage = nullptr; - gl::Error error = textureImpl->getNativeTexture(&texStorage); - if (error.isError()) - { - return error; - } + ANGLE_TRY(textureImpl->getNativeTexture(context, &texStorage)); // Texture should be complete and have a storage ASSERT(texStorage); TextureStorage9 *storage9 = GetAs(texStorage); - error = storage9->getBaseTexture(&d3dTexture); - if (error.isError()) - { - return error; - } + ANGLE_TRY(storage9->getBaseTexture(context, &d3dTexture)); // If we get NULL back from getBaseTexture here, something went wrong // in the texture class and we're unexpectedly missing the d3d texture - ASSERT(d3dTexture != NULL); + ASSERT(d3dTexture != nullptr); forceSetTexture = textureImpl->hasDirtyImages(); textureImpl->resetDirty(); @@ -888,60 +1033,50 @@ gl::Error Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *te appliedTextures[index] = reinterpret_cast(d3dTexture); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Renderer9::setUniformBuffers(const gl::Data &/*data*/, - const std::vector &/*vertexUniformBuffers*/, - const std::vector &/*fragmentUniformBuffers*/) +gl::Error Renderer9::updateState(const gl::Context *context, GLenum drawMode) { - // No effect in ES2/D3D9 - return gl::Error(GL_NO_ERROR); -} + const auto &glState = context->getGLState(); -void Renderer9::syncState(const gl::State &state, const gl::State::DirtyBits &bitmask) -{ - mStateManager.syncState(state, bitmask); -} - -gl::Error Renderer9::updateState(const gl::Data &data, GLenum drawMode) -{ // Applies the render target surface, depth stencil surface, viewport rectangle and // scissor rectangle to the renderer - const gl::Framebuffer *framebufferObject = data.state->getDrawFramebuffer(); - ASSERT(framebufferObject && framebufferObject->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE); + gl::Framebuffer *framebuffer = glState.getDrawFramebuffer(); + ASSERT(framebuffer && !framebuffer->hasAnyDirtyBit() && framebuffer->cachedComplete()); - gl::Error error = applyRenderTarget(framebufferObject); - if (error.isError()) - { - return error; - } + ANGLE_TRY(applyRenderTarget(context, framebuffer)); // Setting viewport state - setViewport(data.caps, data.state->getViewport(), data.state->getNearPlane(), - data.state->getFarPlane(), drawMode, data.state->getRasterizerState().frontFace, - false); + setViewport(glState.getViewport(), glState.getNearPlane(), glState.getFarPlane(), drawMode, + glState.getRasterizerState().frontFace, false); // Setting scissors state - setScissorRectangle(data.state->getScissor(), data.state->isScissorTestEnabled()); + setScissorRectangle(glState.getScissor(), glState.isScissorTestEnabled()); // Setting blend, depth stencil, and rasterizer states - int samples = framebufferObject->getSamples(data); - gl::RasterizerState rasterizer = data.state->getRasterizerState(); + // Since framebuffer->getSamples will return the original samples which may be different with + // the sample counts that we set in render target view, here we use renderTarget->getSamples to + // get the actual samples. + GLsizei samples = 0; + const gl::FramebufferAttachment *firstColorAttachment = framebuffer->getFirstColorbuffer(); + if (firstColorAttachment) + { + ASSERT(firstColorAttachment->isAttached()); + RenderTarget9 *renderTarget = nullptr; + ANGLE_TRY(firstColorAttachment->getRenderTarget(context, &renderTarget)); + samples = renderTarget->getSamples(); + } + gl::RasterizerState rasterizer = glState.getRasterizerState(); rasterizer.pointDrawMode = (drawMode == GL_POINTS); rasterizer.multiSample = (samples != 0); - unsigned int mask = GetBlendSampleMask(data, samples); - error = setBlendDepthRasterStates(data, mask); - - if (error.isError()) - { - return error; - } + unsigned int mask = GetBlendSampleMask(glState, samples); + ANGLE_TRY(setBlendDepthRasterStates(context, mask)); mStateManager.resetDirtyBits(); - return error; + return gl::NoError(); } void Renderer9::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) @@ -949,71 +1084,85 @@ void Renderer9::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) mStateManager.setScissorState(scissor, enabled); } -gl::Error Renderer9::setBlendDepthRasterStates(const gl::Data &glData, GLenum drawMode) +gl::Error Renderer9::setBlendDepthRasterStates(const gl::Context *context, GLenum drawMode) { - int samples = glData.state->getDrawFramebuffer()->getSamples(glData); - gl::RasterizerState rasterizer = glData.state->getRasterizerState(); + const auto &glState = context->getGLState(); + gl::Framebuffer *drawFramebuffer = glState.getDrawFramebuffer(); + ASSERT(!drawFramebuffer->hasAnyDirtyBit()); + // Since framebuffer->getSamples will return the original samples which may be different with + // the sample counts that we set in render target view, here we use renderTarget->getSamples to + // get the actual samples. + GLsizei samples = 0; + const gl::FramebufferAttachment *firstColorAttachment = drawFramebuffer->getFirstColorbuffer(); + if (firstColorAttachment) + { + ASSERT(firstColorAttachment->isAttached()); + RenderTarget9 *renderTarget = nullptr; + ANGLE_TRY(firstColorAttachment->getRenderTarget(context, &renderTarget)); + samples = renderTarget->getSamples(); + } + gl::RasterizerState rasterizer = glState.getRasterizerState(); rasterizer.pointDrawMode = (drawMode == GL_POINTS); rasterizer.multiSample = (samples != 0); - unsigned int mask = GetBlendSampleMask(glData, samples); - return mStateManager.setBlendDepthRasterStates(*glData.state, mask); + unsigned int mask = GetBlendSampleMask(glState, samples); + return mStateManager.setBlendDepthRasterStates(glState, mask); } -void Renderer9::setViewport(const gl::Caps *caps, - const gl::Rectangle &viewport, +void Renderer9::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, bool ignoreViewport) { - mStateManager.setViewportState(caps, viewport, zNear, zFar, drawMode, frontFace, - ignoreViewport); + mStateManager.setViewportState(viewport, zNear, zFar, drawMode, frontFace, ignoreViewport); } bool Renderer9::applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize) { switch (mode) { - case GL_POINTS: - mPrimitiveType = D3DPT_POINTLIST; - mPrimitiveCount = count; - break; - case GL_LINES: - mPrimitiveType = D3DPT_LINELIST; - mPrimitiveCount = count / 2; - break; - case GL_LINE_LOOP: - mPrimitiveType = D3DPT_LINESTRIP; - mPrimitiveCount = count - 1; // D3D doesn't support line loops, so we draw the last line separately - break; - case GL_LINE_STRIP: - mPrimitiveType = D3DPT_LINESTRIP; - mPrimitiveCount = count - 1; - break; - case GL_TRIANGLES: - mPrimitiveType = D3DPT_TRIANGLELIST; - mPrimitiveCount = count / 3; - break; - case GL_TRIANGLE_STRIP: - mPrimitiveType = D3DPT_TRIANGLESTRIP; - mPrimitiveCount = count - 2; - break; - case GL_TRIANGLE_FAN: - mPrimitiveType = D3DPT_TRIANGLEFAN; - mPrimitiveCount = count - 2; - break; - default: - UNREACHABLE(); - return false; + case GL_POINTS: + mPrimitiveType = D3DPT_POINTLIST; + mPrimitiveCount = count; + break; + case GL_LINES: + mPrimitiveType = D3DPT_LINELIST; + mPrimitiveCount = count / 2; + break; + case GL_LINE_LOOP: + mPrimitiveType = D3DPT_LINESTRIP; + mPrimitiveCount = + count - 1; // D3D doesn't support line loops, so we draw the last line separately + break; + case GL_LINE_STRIP: + mPrimitiveType = D3DPT_LINESTRIP; + mPrimitiveCount = count - 1; + break; + case GL_TRIANGLES: + mPrimitiveType = D3DPT_TRIANGLELIST; + mPrimitiveCount = count / 3; + break; + case GL_TRIANGLE_STRIP: + mPrimitiveType = D3DPT_TRIANGLESTRIP; + mPrimitiveCount = count - 2; + break; + case GL_TRIANGLE_FAN: + mPrimitiveType = D3DPT_TRIANGLEFAN; + mPrimitiveCount = count - 2; + break; + default: + UNREACHABLE(); + return false; } return mPrimitiveCount > 0; } - -gl::Error Renderer9::getNullColorbuffer(const gl::FramebufferAttachment *depthbuffer, const gl::FramebufferAttachment **outColorBuffer) +gl::Error Renderer9::getNullColorbuffer(const gl::Context *context, + const gl::FramebufferAttachment *depthbuffer, + const gl::FramebufferAttachment **outColorBuffer) { ASSERT(depthbuffer); @@ -1022,25 +1171,28 @@ gl::Error Renderer9::getNullColorbuffer(const gl::FramebufferAttachment *depthbu // search cached nullcolorbuffers for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++) { - if (mNullColorbufferCache[i].buffer != NULL && + if (mNullColorbufferCache[i].buffer != nullptr && mNullColorbufferCache[i].width == size.width && mNullColorbufferCache[i].height == size.height) { mNullColorbufferCache[i].lruCount = ++mMaxNullColorbufferLRU; - *outColorBuffer = mNullColorbufferCache[i].buffer; - return gl::Error(GL_NO_ERROR); + *outColorBuffer = mNullColorbufferCache[i].buffer; + return gl::NoError(); } } - gl::Renderbuffer *nullRenderbuffer = new gl::Renderbuffer(createRenderbuffer(), 0); - gl::Error error = nullRenderbuffer->setStorage(GL_NONE, size.width, size.height); + auto *implFactory = context->getImplementation(); + + gl::Renderbuffer *nullRenderbuffer = new gl::Renderbuffer(implFactory->createRenderbuffer(), 0); + gl::Error error = nullRenderbuffer->setStorage(context, GL_NONE, size.width, size.height); if (error.isError()) { SafeDelete(nullRenderbuffer); return error; } - gl::FramebufferAttachment *nullbuffer = new gl::FramebufferAttachment(GL_RENDERBUFFER, GL_NONE, gl::ImageIndex::MakeInvalid(), nullRenderbuffer); + gl::FramebufferAttachment *nullbuffer = new gl::FramebufferAttachment( + context, GL_RENDERBUFFER, GL_NONE, gl::ImageIndex::MakeInvalid(), nullRenderbuffer); // add nullbuffer to the cache NullColorbufferCacheEntry *oldest = &mNullColorbufferCache[0]; @@ -1053,46 +1205,38 @@ gl::Error Renderer9::getNullColorbuffer(const gl::FramebufferAttachment *depthbu } delete oldest->buffer; - oldest->buffer = nullbuffer; + oldest->buffer = nullbuffer; oldest->lruCount = ++mMaxNullColorbufferLRU; oldest->width = size.width; oldest->height = size.height; *outColorBuffer = nullbuffer; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAttachment, +gl::Error Renderer9::applyRenderTarget(const gl::Context *context, + const gl::FramebufferAttachment *colorAttachment, const gl::FramebufferAttachment *depthStencilAttachment) { const gl::FramebufferAttachment *renderAttachment = colorAttachment; - gl::Error error(GL_NO_ERROR); // if there is no color attachment we must synthesize a NULL colorattachment // to keep the D3D runtime happy. This should only be possible if depth texturing. if (renderAttachment == nullptr) { - error = getNullColorbuffer(depthStencilAttachment, &renderAttachment); - if (error.isError()) - { - return error; - } + ANGLE_TRY(getNullColorbuffer(context, depthStencilAttachment, &renderAttachment)); } ASSERT(renderAttachment != nullptr); - size_t renderTargetWidth = 0; - size_t renderTargetHeight = 0; + size_t renderTargetWidth = 0; + size_t renderTargetHeight = 0; D3DFORMAT renderTargetFormat = D3DFMT_UNKNOWN; RenderTarget9 *renderTarget = nullptr; - error = renderAttachment->getRenderTarget(&renderTarget); - if (error.isError()) - { - return error; - } + ANGLE_TRY(renderAttachment->getRenderTarget(context, &renderTarget)); ASSERT(renderTarget); - bool renderTargetChanged = false; + bool renderTargetChanged = false; unsigned int renderTargetSerial = renderTarget->getSerial(); if (renderTargetSerial != mAppliedRenderTargetSerial) { @@ -1103,24 +1247,20 @@ gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAtt mDevice->SetRenderTarget(0, renderTargetSurface); SafeRelease(renderTargetSurface); - renderTargetWidth = renderTarget->getWidth(); + renderTargetWidth = renderTarget->getWidth(); renderTargetHeight = renderTarget->getHeight(); renderTargetFormat = renderTarget->getD3DFormat(); mAppliedRenderTargetSerial = renderTargetSerial; - renderTargetChanged = true; + renderTargetChanged = true; } RenderTarget9 *depthStencilRenderTarget = nullptr; - unsigned int depthStencilSerial = 0; + unsigned int depthStencilSerial = 0; if (depthStencilAttachment != nullptr) { - error = depthStencilAttachment->getRenderTarget(&depthStencilRenderTarget); - if (error.isError()) - { - return error; - } + ANGLE_TRY(depthStencilAttachment->getRenderTarget(context, &depthStencilRenderTarget)); ASSERT(depthStencilRenderTarget); depthStencilSerial = depthStencilRenderTarget->getSerial(); @@ -1128,7 +1268,7 @@ gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAtt if (depthStencilSerial != mAppliedDepthStencilSerial || !mDepthStencilInitialized) { - unsigned int depthSize = 0; + unsigned int depthSize = 0; unsigned int stencilSize = 0; // Apply the depth stencil on the device @@ -1140,19 +1280,19 @@ gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAtt mDevice->SetDepthStencilSurface(depthStencilSurface); SafeRelease(depthStencilSurface); - depthSize = depthStencilAttachment->getDepthSize(); + depthSize = depthStencilAttachment->getDepthSize(); stencilSize = depthStencilAttachment->getStencilSize(); } else { - mDevice->SetDepthStencilSurface(NULL); + mDevice->SetDepthStencilSurface(nullptr); } mStateManager.updateDepthSizeIfChanged(mDepthStencilInitialized, depthSize); mStateManager.updateStencilSizeIfChanged(mDepthStencilInitialized, stencilSize); mAppliedDepthStencilSerial = depthStencilSerial; - mDepthStencilInitialized = true; + mDepthStencilInitialized = true; } if (renderTargetChanged || !mRenderTargetDescInitialized) @@ -1163,83 +1303,84 @@ gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAtt mRenderTargetDescInitialized = true; } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Renderer9::applyRenderTarget(const gl::Framebuffer *framebuffer) +gl::Error Renderer9::applyRenderTarget(const gl::Context *context, + const gl::Framebuffer *framebuffer) { - return applyRenderTarget(framebuffer->getColorbuffer(0), framebuffer->getDepthOrStencilbuffer()); + return applyRenderTarget(context, framebuffer->getColorbuffer(0), + framebuffer->getDepthOrStencilbuffer()); } -gl::Error Renderer9::applyVertexBuffer(const gl::State &state, +gl::Error Renderer9::applyVertexBuffer(const gl::Context *context, GLenum mode, GLint first, GLsizei count, GLsizei instances, TranslatedIndexData * /*indexInfo*/) { - gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, &mTranslatedAttribCache, instances); + const gl::State &state = context->getGLState(); + gl::Error error = mVertexDataManager->prepareVertexData(context, first, count, + &mTranslatedAttribCache, instances); if (error.isError()) { return error; } - return mVertexDeclarationCache.applyDeclaration(mDevice, mTranslatedAttribCache, state.getProgram(), instances, &mRepeatDraw); + return mVertexDeclarationCache.applyDeclaration( + mDevice, mTranslatedAttribCache, state.getProgram(), first, instances, &mRepeatDraw); } // Applies the indices and element array bindings to the Direct3D 9 device -gl::Error Renderer9::applyIndexBuffer(const gl::Data &data, - const GLvoid *indices, +gl::Error Renderer9::applyIndexBuffer(const gl::Context *context, + const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) { - gl::VertexArray *vao = data.state->getVertexArray(); + gl::VertexArray *vao = context->getGLState().getVertexArray(); gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get(); - gl::Error error = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, - indexInfo, false); - if (error.isError()) - { - return error; - } + const auto &lazyIndexRange = context->getParams(); + + GLenum dstType = GetIndexTranslationDestType(type, lazyIndexRange, false); + + ANGLE_TRY(mIndexDataManager->prepareIndexData(context, type, dstType, count, elementArrayBuffer, + indices, indexInfo)); // Directly binding the storage buffer is not supported for d3d9 - ASSERT(indexInfo->storage == NULL); + ASSERT(indexInfo->storage == nullptr); if (indexInfo->serial != mAppliedIBSerial) { - IndexBuffer9* indexBuffer = GetAs(indexInfo->indexBuffer); + IndexBuffer9 *indexBuffer = GetAs(indexInfo->indexBuffer); mDevice->SetIndices(indexBuffer->getBuffer()); mAppliedIBSerial = indexInfo->serial; } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -void Renderer9::applyTransformFeedbackBuffers(const gl::State& state) -{ - ASSERT(!state.isTransformFeedbackActiveUnpaused()); -} - -gl::Error Renderer9::drawArraysImpl(const gl::Data &data, +gl::Error Renderer9::drawArraysImpl(const gl::Context *context, GLenum mode, + GLint startVertex, GLsizei count, GLsizei instances) { - ASSERT(!data.state->isTransformFeedbackActiveUnpaused()); + ASSERT(!context->getGLState().isTransformFeedbackActiveUnpaused()); startScene(); if (mode == GL_LINE_LOOP) { - return drawLineLoop(count, GL_NONE, NULL, 0, NULL); + return drawLineLoop(context, count, GL_NONE, nullptr, 0, nullptr); } else if (instances > 0) { - StaticIndexBufferInterface *countingIB = NULL; - gl::Error error = getCountingIB(count, &countingIB); + StaticIndexBufferInterface *countingIB = nullptr; + gl::Error error = getCountingIB(count, &countingIB); if (error.isError()) { return error; @@ -1258,60 +1399,73 @@ gl::Error Renderer9::drawArraysImpl(const gl::Data &data, mDevice->DrawIndexedPrimitive(mPrimitiveType, 0, 0, count, 0, mPrimitiveCount); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } - else // Regular case + else // Regular case { mDevice->DrawPrimitive(mPrimitiveType, 0, mPrimitiveCount); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } } -gl::Error Renderer9::drawElementsImpl(const gl::Data &data, - const TranslatedIndexData &indexInfo, +gl::Error Renderer9::drawElementsImpl(const gl::Context *context, GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, - GLsizei /*instances*/) + const void *indices, + GLsizei instances) { + TranslatedIndexData indexInfo; + + ANGLE_TRY(applyIndexBuffer(context, indices, count, mode, type, &indexInfo)); + + const auto &lazyIndexRange = context->getParams(); + const gl::IndexRange &indexRange = lazyIndexRange.getIndexRange().value(); + size_t vertexCount = indexRange.vertexCount(); + ANGLE_TRY(applyVertexBuffer(context, mode, static_cast(indexRange.start), + static_cast(vertexCount), instances, &indexInfo)); + startScene(); - int minIndex = static_cast(indexInfo.indexRange.start); + int minIndex = static_cast(indexRange.start); - gl::VertexArray *vao = data.state->getVertexArray(); + gl::VertexArray *vao = context->getGLState().getVertexArray(); gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get(); if (mode == GL_POINTS) { - return drawIndexedPoints(count, type, indices, minIndex, elementArrayBuffer); + return drawIndexedPoints(context, count, type, indices, minIndex, elementArrayBuffer); } else if (mode == GL_LINE_LOOP) { - return drawLineLoop(count, type, indices, minIndex, elementArrayBuffer); + return drawLineLoop(context, count, type, indices, minIndex, elementArrayBuffer); } else { - size_t vertexCount = indexInfo.indexRange.vertexCount(); for (int i = 0; i < mRepeatDraw; i++) { mDevice->DrawIndexedPrimitive(mPrimitiveType, -minIndex, minIndex, static_cast(vertexCount), indexInfo.startIndex, mPrimitiveCount); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } } -gl::Error Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer) +gl::Error Renderer9::drawLineLoop(const gl::Context *context, + GLsizei count, + GLenum type, + const void *indices, + int minIndex, + gl::Buffer *elementArrayBuffer) { // Get the raw indices for an indexed draw if (type != GL_NONE && elementArrayBuffer) { - BufferD3D *storage = GetImplAs(elementArrayBuffer); - intptr_t offset = reinterpret_cast(indices); - const uint8_t *bufferData = NULL; - gl::Error error = storage->getData(&bufferData); + BufferD3D *storage = GetImplAs(elementArrayBuffer); + intptr_t offset = reinterpret_cast(indices); + const uint8_t *bufferData = nullptr; + gl::Error error = storage->getData(context, &bufferData); if (error.isError()) { return error; @@ -1321,12 +1475,13 @@ gl::Error Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indi unsigned int startIndex = 0; - if (getRendererExtensions().elementIndexUint) + if (getNativeExtensions().elementIndexUint) { if (!mLineLoopIB) { mLineLoopIB = new StreamingIndexBufferInterface(this); - gl::Error error = mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT); + gl::Error error = + mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT); if (error.isError()) { SafeDelete(mLineLoopIB); @@ -1337,60 +1492,64 @@ gl::Error Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indi // Checked by Renderer9::applyPrimitiveType ASSERT(count >= 0); - if (static_cast(count) + 1 > (std::numeric_limits::max() / sizeof(unsigned int))) + if (static_cast(count) + 1 > + (std::numeric_limits::max() / sizeof(unsigned int))) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required."); + return gl::OutOfMemory() << "Failed to create a 32-bit looping index buffer for " + "GL_LINE_LOOP, too many indices required."; } - const unsigned int spaceNeeded = (static_cast(count)+1) * sizeof(unsigned int); + const unsigned int spaceNeeded = + (static_cast(count) + 1) * sizeof(unsigned int); gl::Error error = mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT); if (error.isError()) { return error; } - void* mappedMemory = NULL; + void *mappedMemory = nullptr; unsigned int offset = 0; - error = mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset); + error = mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset); if (error.isError()) { return error; } - startIndex = static_cast(offset) / 4; - unsigned int *data = reinterpret_cast(mappedMemory); + startIndex = static_cast(offset) / 4; + unsigned int *data = reinterpret_cast(mappedMemory); switch (type) { - case GL_NONE: // Non-indexed draw - for (int i = 0; i < count; i++) - { - data[i] = i; - } - data[count] = 0; - break; - case GL_UNSIGNED_BYTE: - for (int i = 0; i < count; i++) - { - data[i] = static_cast(indices)[i]; - } - data[count] = static_cast(indices)[0]; - break; - case GL_UNSIGNED_SHORT: - for (int i = 0; i < count; i++) - { - data[i] = static_cast(indices)[i]; - } - data[count] = static_cast(indices)[0]; - break; - case GL_UNSIGNED_INT: - for (int i = 0; i < count; i++) - { - data[i] = static_cast(indices)[i]; - } - data[count] = static_cast(indices)[0]; - break; - default: UNREACHABLE(); + case GL_NONE: // Non-indexed draw + for (int i = 0; i < count; i++) + { + data[i] = i; + } + data[count] = 0; + break; + case GL_UNSIGNED_BYTE: + for (int i = 0; i < count; i++) + { + data[i] = static_cast(indices)[i]; + } + data[count] = static_cast(indices)[0]; + break; + case GL_UNSIGNED_SHORT: + for (int i = 0; i < count; i++) + { + data[i] = static_cast(indices)[i]; + } + data[count] = static_cast(indices)[0]; + break; + case GL_UNSIGNED_INT: + for (int i = 0; i < count; i++) + { + data[i] = static_cast(indices)[i]; + } + data[count] = static_cast(indices)[0]; + break; + default: + UNREACHABLE(); } error = mLineLoopIB->unmapBuffer(); @@ -1404,7 +1563,8 @@ gl::Error Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indi if (!mLineLoopIB) { mLineLoopIB = new StreamingIndexBufferInterface(this); - gl::Error error = mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT); + gl::Error error = + mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT); if (error.isError()) { SafeDelete(mLineLoopIB); @@ -1415,19 +1575,22 @@ gl::Error Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indi // Checked by Renderer9::applyPrimitiveType ASSERT(count >= 0); - if (static_cast(count) + 1 > (std::numeric_limits::max() / sizeof(unsigned short))) + if (static_cast(count) + 1 > + (std::numeric_limits::max() / sizeof(unsigned short))) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create a 16-bit looping index buffer for GL_LINE_LOOP, too many indices required."); + return gl::OutOfMemory() << "Failed to create a 16-bit looping index buffer for " + "GL_LINE_LOOP, too many indices required."; } - const unsigned int spaceNeeded = (static_cast(count) + 1) * sizeof(unsigned short); + const unsigned int spaceNeeded = + (static_cast(count) + 1) * sizeof(unsigned short); gl::Error error = mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT); if (error.isError()) { return error; } - void* mappedMemory = NULL; + void *mappedMemory = nullptr; unsigned int offset; error = mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset); if (error.isError()) @@ -1435,40 +1598,41 @@ gl::Error Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indi return error; } - startIndex = static_cast(offset) / 2; - unsigned short *data = reinterpret_cast(mappedMemory); + startIndex = static_cast(offset) / 2; + unsigned short *data = reinterpret_cast(mappedMemory); switch (type) { - case GL_NONE: // Non-indexed draw - for (int i = 0; i < count; i++) - { - data[i] = static_cast(i); - } - data[count] = 0; - break; - case GL_UNSIGNED_BYTE: - for (int i = 0; i < count; i++) - { - data[i] = static_cast(indices)[i]; - } - data[count] = static_cast(indices)[0]; - break; - case GL_UNSIGNED_SHORT: - for (int i = 0; i < count; i++) - { - data[i] = static_cast(indices)[i]; - } - data[count] = static_cast(indices)[0]; - break; - case GL_UNSIGNED_INT: - for (int i = 0; i < count; i++) - { - data[i] = static_cast(static_cast(indices)[i]); - } - data[count] = static_cast(static_cast(indices)[0]); - break; - default: UNREACHABLE(); + case GL_NONE: // Non-indexed draw + for (int i = 0; i < count; i++) + { + data[i] = static_cast(i); + } + data[count] = 0; + break; + case GL_UNSIGNED_BYTE: + for (int i = 0; i < count; i++) + { + data[i] = static_cast(indices)[i]; + } + data[count] = static_cast(indices)[0]; + break; + case GL_UNSIGNED_SHORT: + for (int i = 0; i < count; i++) + { + data[i] = static_cast(indices)[i]; + } + data[count] = static_cast(indices)[0]; + break; + case GL_UNSIGNED_INT: + for (int i = 0; i < count; i++) + { + data[i] = static_cast(static_cast(indices)[i]); + } + data[count] = static_cast(static_cast(indices)[0]); + break; + default: + UNREACHABLE(); } error = mLineLoopIB->unmapBuffer(); @@ -1488,22 +1652,31 @@ gl::Error Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indi mDevice->DrawIndexedPrimitive(D3DPT_LINESTRIP, -minIndex, minIndex, count, startIndex, count); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } template -static gl::Error drawPoints(IDirect3DDevice9* device, GLsizei count, const GLvoid *indices, int minIndex) +static gl::Error drawPoints(IDirect3DDevice9 *device, + GLsizei count, + const void *indices, + int minIndex) { for (int i = 0; i < count; i++) { - unsigned int indexValue = static_cast(static_cast(indices)[i]) - minIndex; + unsigned int indexValue = + static_cast(static_cast(indices)[i]) - minIndex; device->DrawPrimitive(D3DPT_POINTLIST, indexValue, 1); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer) +gl::Error Renderer9::drawIndexedPoints(const gl::Context *context, + GLsizei count, + GLenum type, + const void *indices, + int minIndex, + gl::Buffer *elementArrayBuffer) { // Drawing index point lists is unsupported in d3d9, fall back to a regular DrawPrimitive call // for each individual point. This call is not expected to happen often. @@ -1511,10 +1684,10 @@ gl::Error Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid if (elementArrayBuffer) { BufferD3D *storage = GetImplAs(elementArrayBuffer); - intptr_t offset = reinterpret_cast(indices); + intptr_t offset = reinterpret_cast(indices); - const uint8_t *bufferData = NULL; - gl::Error error = storage->getData(&bufferData); + const uint8_t *bufferData = nullptr; + gl::Error error = storage->getData(context, &bufferData); if (error.isError()) { return error; @@ -1525,17 +1698,22 @@ gl::Error Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid switch (type) { - case GL_UNSIGNED_BYTE: return drawPoints(mDevice, count, indices, minIndex); - case GL_UNSIGNED_SHORT: return drawPoints(mDevice, count, indices, minIndex); - case GL_UNSIGNED_INT: return drawPoints(mDevice, count, indices, minIndex); - default: UNREACHABLE(); return gl::Error(GL_INVALID_OPERATION); + case GL_UNSIGNED_BYTE: + return drawPoints(mDevice, count, indices, minIndex); + case GL_UNSIGNED_SHORT: + return drawPoints(mDevice, count, indices, minIndex); + case GL_UNSIGNED_INT: + return drawPoints(mDevice, count, indices, minIndex); + default: + UNREACHABLE(); + return gl::InternalError(); } } gl::Error Renderer9::getCountingIB(size_t count, StaticIndexBufferInterface **outIB) { // Update the counting index buffer if it is not large enough or has not been created yet. - if (count <= 65536) // 16-bit indices + if (count <= 65536) // 16-bit indices { const unsigned int spaceNeeded = static_cast(count) * sizeof(unsigned short); @@ -1543,29 +1721,21 @@ gl::Error Renderer9::getCountingIB(size_t count, StaticIndexBufferInterface **ou { SafeDelete(mCountingIB); mCountingIB = new StaticIndexBufferInterface(this); - mCountingIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT); + ANGLE_TRY(mCountingIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT)); - void *mappedMemory = NULL; - gl::Error error = mCountingIB->mapBuffer(spaceNeeded, &mappedMemory, NULL); - if (error.isError()) - { - return error; - } + void *mappedMemory = nullptr; + ANGLE_TRY(mCountingIB->mapBuffer(spaceNeeded, &mappedMemory, nullptr)); - unsigned short *data = reinterpret_cast(mappedMemory); + unsigned short *data = reinterpret_cast(mappedMemory); for (size_t i = 0; i < count; i++) { data[i] = static_cast(i); } - error = mCountingIB->unmapBuffer(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mCountingIB->unmapBuffer()); } } - else if (getRendererExtensions().elementIndexUint) + else if (getNativeExtensions().elementIndexUint) { const unsigned int spaceNeeded = static_cast(count) * sizeof(unsigned int); @@ -1573,59 +1743,53 @@ gl::Error Renderer9::getCountingIB(size_t count, StaticIndexBufferInterface **ou { SafeDelete(mCountingIB); mCountingIB = new StaticIndexBufferInterface(this); - mCountingIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT); + ANGLE_TRY(mCountingIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT)); - void *mappedMemory = NULL; - gl::Error error = mCountingIB->mapBuffer(spaceNeeded, &mappedMemory, NULL); - if (error.isError()) - { - return error; - } + void *mappedMemory = nullptr; + ANGLE_TRY(mCountingIB->mapBuffer(spaceNeeded, &mappedMemory, nullptr)); - unsigned int *data = reinterpret_cast(mappedMemory); + unsigned int *data = reinterpret_cast(mappedMemory); for (unsigned int i = 0; i < count; i++) { data[i] = i; } - error = mCountingIB->unmapBuffer(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mCountingIB->unmapBuffer()); } } else { - return gl::Error(GL_OUT_OF_MEMORY, "Could not create a counting index buffer for glDrawArraysInstanced."); + return gl::OutOfMemory() + << "Could not create a counting index buffer for glDrawArraysInstanced."; } *outIB = mCountingIB; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Renderer9::applyShadersImpl(const gl::Data &data, GLenum /*drawMode*/) +gl::Error Renderer9::applyShaders(const gl::Context *context, GLenum drawMode) { - ProgramD3D *programD3D = GetImplAs(data.state->getProgram()); - const auto &inputLayout = programD3D->getCachedInputLayout(); + const gl::State &state = context->getContextState().getState(); + // This method is called single-threaded. + ANGLE_TRY(ensureHLSLCompilerInitialized()); - ShaderExecutableD3D *vertexExe = NULL; - gl::Error error = programD3D->getVertexExecutableForInputLayout(inputLayout, &vertexExe, nullptr); - if (error.isError()) - { - return error; - } + ProgramD3D *programD3D = GetImplAs(state.getProgram()); + VertexArray9 *vao = GetImplAs(state.getVertexArray()); + programD3D->updateCachedInputLayout(vao->getCurrentStateSerial(), state); - const gl::Framebuffer *drawFramebuffer = data.state->getDrawFramebuffer(); - ShaderExecutableD3D *pixelExe = NULL; - error = programD3D->getPixelExecutableForFramebuffer(drawFramebuffer, &pixelExe); - if (error.isError()) - { - return error; - } + ShaderExecutableD3D *vertexExe = nullptr; + ANGLE_TRY(programD3D->getVertexExecutableForCachedInputLayout(&vertexExe, nullptr)); - IDirect3DVertexShader9 *vertexShader = (vertexExe ? GetAs(vertexExe)->getVertexShader() : nullptr); - IDirect3DPixelShader9 *pixelShader = (pixelExe ? GetAs(pixelExe)->getPixelShader() : nullptr); + const gl::Framebuffer *drawFramebuffer = state.getDrawFramebuffer(); + programD3D->updateCachedOutputLayout(context, drawFramebuffer); + + ShaderExecutableD3D *pixelExe = nullptr; + ANGLE_TRY(programD3D->getPixelExecutableForCachedOutputLayout(&pixelExe, nullptr)); + + IDirect3DVertexShader9 *vertexShader = + (vertexExe ? GetAs(vertexExe)->getVertexShader() : nullptr); + IDirect3DPixelShader9 *pixelShader = + (pixelExe ? GetAs(pixelExe)->getPixelShader() : nullptr); if (vertexShader != mAppliedVertexShader) { @@ -1652,25 +1816,39 @@ gl::Error Renderer9::applyShadersImpl(const gl::Data &data, GLenum /*drawMode*/) mAppliedProgramSerial = programSerial; } - return gl::Error(GL_NO_ERROR); + ANGLE_TRY(applyUniforms(programD3D)); + + // Driver uniforms + mStateManager.setShaderConstants(); + + return gl::NoError(); } -gl::Error Renderer9::applyUniforms(const ProgramD3D &programD3D, - GLenum /*drawMode*/, - const std::vector &uniformArray) +gl::Error Renderer9::applyUniforms(ProgramD3D *programD3D) { + // Skip updates if we're not dirty. Note that D3D9 cannot have compute. + if (!programD3D->areVertexUniformsDirty() && !programD3D->areFragmentUniformsDirty()) + { + return gl::NoError(); + } + + const auto &uniformArray = programD3D->getD3DUniforms(); + for (const D3DUniform *targetUniform : uniformArray) { - if (!targetUniform->dirty) + // Built-in uniforms must be skipped. + if (!targetUniform->isReferencedByFragmentShader() && + !targetUniform->isReferencedByVertexShader()) continue; - GLfloat *f = (GLfloat *)targetUniform->data; - GLint *i = (GLint *)targetUniform->data; + const GLfloat *f = reinterpret_cast(targetUniform->firstNonNullData()); + const GLint *i = reinterpret_cast(targetUniform->firstNonNullData()); - switch (targetUniform->type) + switch (targetUniform->typeInfo.type) { case GL_SAMPLER_2D: case GL_SAMPLER_CUBE: + case GL_SAMPLER_EXTERNAL_OES: break; case GL_BOOL: case GL_BOOL_VEC2: @@ -1698,22 +1876,22 @@ gl::Error Renderer9::applyUniforms(const ProgramD3D &programD3D, } } - // Driver uniforms - mStateManager.setShaderConstants(); - - return gl::Error(GL_NO_ERROR); + programD3D->markUniformsClean(); + return gl::NoError(); } void Renderer9::applyUniformnfv(const D3DUniform *targetUniform, const GLfloat *v) { if (targetUniform->isReferencedByFragmentShader()) { - mDevice->SetPixelShaderConstantF(targetUniform->psRegisterIndex, v, targetUniform->registerCount); + mDevice->SetPixelShaderConstantF(targetUniform->psRegisterIndex, v, + targetUniform->registerCount); } if (targetUniform->isReferencedByVertexShader()) { - mDevice->SetVertexShaderConstantF(targetUniform->vsRegisterIndex, v, targetUniform->registerCount); + mDevice->SetVertexShaderConstantF(targetUniform->vsRegisterIndex, v, + targetUniform->registerCount); } } @@ -1730,7 +1908,7 @@ void Renderer9::applyUniformniv(const D3DUniform *targetUniform, const GLint *v) vector[i][3] = (GLfloat)v[4 * i + 3]; } - applyUniformnfv(targetUniform, (GLfloat*)vector); + applyUniformnfv(targetUniform, (GLfloat *)vector); } void Renderer9::applyUniformnbv(const D3DUniform *targetUniform, const GLint *v) @@ -1746,18 +1924,19 @@ void Renderer9::applyUniformnbv(const D3DUniform *targetUniform, const GLint *v) vector[i][3] = (v[4 * i + 3] == GL_FALSE) ? 0.0f : 1.0f; } - applyUniformnfv(targetUniform, (GLfloat*)vector); + applyUniformnfv(targetUniform, (GLfloat *)vector); } -gl::Error Renderer9::clear(const ClearParameters &clearParams, +gl::Error Renderer9::clear(const gl::Context *context, + const ClearParameters &clearParams, const gl::FramebufferAttachment *colorBuffer, const gl::FramebufferAttachment *depthStencilBuffer) { - if (clearParams.colorClearType != GL_FLOAT) + if (clearParams.colorType != GL_FLOAT) { // Clearing buffers with non-float values is not supported by Renderer9 and ES 2.0 UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + return gl::InternalError(); } bool clearColor = clearParams.clearColor[0]; @@ -1765,14 +1944,15 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, { if (clearParams.clearColor[i] != clearColor) { - // Clearing individual buffers other than buffer zero is not supported by Renderer9 and ES 2.0 + // Clearing individual buffers other than buffer zero is not supported by Renderer9 and + // ES 2.0 UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + return gl::InternalError(); } } - float depth = gl::clamp01(clearParams.depthClearValue); - DWORD stencil = clearParams.stencilClearValue & 0x000000FF; + float depth = gl::clamp01(clearParams.depthValue); + DWORD stencil = clearParams.stencilValue & 0x000000FF; unsigned int stencilUnmasked = 0x0; if (clearParams.clearStencil && depthStencilBuffer->getStencilSize() > 0) @@ -1780,7 +1960,7 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, ASSERT(depthStencilBuffer != nullptr); RenderTargetD3D *stencilRenderTarget = nullptr; - gl::Error error = depthStencilBuffer->getRenderTarget(&stencilRenderTarget); + gl::Error error = depthStencilBuffer->getRenderTarget(context, &stencilRenderTarget); if (error.isError()) { return error; @@ -1789,21 +1969,23 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, RenderTarget9 *stencilRenderTarget9 = GetAs(stencilRenderTarget); ASSERT(stencilRenderTarget9); - const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(stencilRenderTarget9->getD3DFormat()); + const d3d9::D3DFormat &d3dFormatInfo = + d3d9::GetD3DFormatInfo(stencilRenderTarget9->getD3DFormat()); stencilUnmasked = (0x1 << d3dFormatInfo.stencilBits) - 1; } - const bool needMaskedStencilClear = clearParams.clearStencil && - (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked; + const bool needMaskedStencilClear = + clearParams.clearStencil && + (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked; bool needMaskedColorClear = false; - D3DCOLOR color = D3DCOLOR_ARGB(255, 0, 0, 0); + D3DCOLOR color = D3DCOLOR_ARGB(255, 0, 0, 0); if (clearColor) { ASSERT(colorBuffer != nullptr); - RenderTargetD3D *colorRenderTarget = NULL; - gl::Error error = colorBuffer->getRenderTarget(&colorRenderTarget); + RenderTargetD3D *colorRenderTarget = nullptr; + gl::Error error = colorBuffer->getRenderTarget(context, &colorRenderTarget); if (error.isError()) { return error; @@ -1812,17 +1994,27 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, RenderTarget9 *colorRenderTarget9 = GetAs(colorRenderTarget); ASSERT(colorRenderTarget9); - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(colorBuffer->getInternalFormat()); - const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(colorRenderTarget9->getD3DFormat()); + const gl::InternalFormat &formatInfo = *colorBuffer->getFormat().info; + const d3d9::D3DFormat &d3dFormatInfo = + d3d9::GetD3DFormatInfo(colorRenderTarget9->getD3DFormat()); - color = D3DCOLOR_ARGB(gl::unorm<8>((formatInfo.alphaBits == 0 && d3dFormatInfo.alphaBits > 0) ? 1.0f : clearParams.colorFClearValue.alpha), - gl::unorm<8>((formatInfo.redBits == 0 && d3dFormatInfo.redBits > 0) ? 0.0f : clearParams.colorFClearValue.red), - gl::unorm<8>((formatInfo.greenBits == 0 && d3dFormatInfo.greenBits > 0) ? 0.0f : clearParams.colorFClearValue.green), - gl::unorm<8>((formatInfo.blueBits == 0 && d3dFormatInfo.blueBits > 0) ? 0.0f : clearParams.colorFClearValue.blue)); + color = + D3DCOLOR_ARGB(gl::unorm<8>((formatInfo.alphaBits == 0 && d3dFormatInfo.alphaBits > 0) + ? 1.0f + : clearParams.colorF.alpha), + gl::unorm<8>((formatInfo.redBits == 0 && d3dFormatInfo.redBits > 0) + ? 0.0f + : clearParams.colorF.red), + gl::unorm<8>((formatInfo.greenBits == 0 && d3dFormatInfo.greenBits > 0) + ? 0.0f + : clearParams.colorF.green), + gl::unorm<8>((formatInfo.blueBits == 0 && d3dFormatInfo.blueBits > 0) + ? 0.0f + : clearParams.colorF.blue)); - if ((formatInfo.redBits > 0 && !clearParams.colorMaskRed) || + if ((formatInfo.redBits > 0 && !clearParams.colorMaskRed) || (formatInfo.greenBits > 0 && !clearParams.colorMaskGreen) || - (formatInfo.blueBits > 0 && !clearParams.colorMaskBlue) || + (formatInfo.blueBits > 0 && !clearParams.colorMaskBlue) || (formatInfo.alphaBits > 0 && !clearParams.colorMaskAlpha)) { needMaskedColorClear = true; @@ -1835,7 +2027,7 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, // State which is altered in only some paths will be flagged dirty in the case that // that path is taken. HRESULT hr; - if (mMaskedClearSavedState == NULL) + if (mMaskedClearSavedState == nullptr) { hr = mDevice->BeginStateBlock(); ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); @@ -1850,10 +2042,10 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, mDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0); mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); - mDevice->SetPixelShader(NULL); - mDevice->SetVertexShader(NULL); + mDevice->SetPixelShader(nullptr); + mDevice->SetVertexShader(nullptr); mDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE); - mDevice->SetStreamSource(0, NULL, 0, 0); + mDevice->SetStreamSource(0, nullptr, 0, 0); mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); mDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); mDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); @@ -1862,7 +2054,7 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, mDevice->SetRenderState(D3DRS_TEXTUREFACTOR, color); mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF); - for(int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) { mDevice->SetStreamSourceFreq(i, 1); } @@ -1871,9 +2063,9 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); } - ASSERT(mMaskedClearSavedState != NULL); + ASSERT(mMaskedClearSavedState != nullptr); - if (mMaskedClearSavedState != NULL) + if (mMaskedClearSavedState != nullptr) { hr = mMaskedClearSavedState->Capture(); ASSERT(SUCCEEDED(hr)); @@ -1890,11 +2082,10 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, if (clearColor) { - mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, - gl_d3d9::ConvertColorMask(clearParams.colorMaskRed, - clearParams.colorMaskGreen, - clearParams.colorMaskBlue, - clearParams.colorMaskAlpha)); + mDevice->SetRenderState( + D3DRS_COLORWRITEENABLE, + gl_d3d9::ConvertColorMask(clearParams.colorMaskRed, clearParams.colorMaskGreen, + clearParams.colorMaskBlue, clearParams.colorMaskAlpha)); } else { @@ -1917,8 +2108,8 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); } - mDevice->SetPixelShader(NULL); - mDevice->SetVertexShader(NULL); + mDevice->SetPixelShader(nullptr); + mDevice->SetVertexShader(nullptr); mDevice->SetFVF(D3DFVF_XYZRHW); mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); mDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); @@ -1928,7 +2119,7 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, mDevice->SetRenderState(D3DRS_TEXTUREFACTOR, color); mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF); - for(int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) { mDevice->SetStreamSourceFreq(i, 1); } @@ -1936,7 +2127,7 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, int renderTargetWidth = mStateManager.getRenderTargetWidth(); int renderTargetHeight = mStateManager.getRenderTargetHeight(); - float quad[4][4]; // A quadrilateral covering the target, aligned to match the edges + float quad[4][4]; // A quadrilateral covering the target, aligned to match the edges quad[0][0] = -0.5f; quad[0][1] = renderTargetHeight - 0.5f; quad[0][2] = 0.0f; @@ -1964,10 +2155,10 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, { mDevice->SetRenderState(D3DRS_ZENABLE, TRUE); mDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); - mDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, color, depth, stencil); + mDevice->Clear(0, nullptr, D3DCLEAR_ZBUFFER, color, depth, stencil); } - if (mMaskedClearSavedState != NULL) + if (mMaskedClearSavedState != nullptr) { mMaskedClearSavedState->Apply(); } @@ -1988,17 +2179,17 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, dxClearFlags |= D3DCLEAR_STENCIL; } - mDevice->Clear(0, NULL, dxClearFlags, color, depth, stencil); + mDevice->Clear(0, nullptr, dxClearFlags, color, depth, stencil); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } void Renderer9::markAllStateDirty() { - mAppliedRenderTargetSerial = 0; - mAppliedDepthStencilSerial = 0; - mDepthStencilInitialized = false; + mAppliedRenderTargetSerial = 0; + mAppliedDepthStencilSerial = 0; + mDepthStencilInitialized = false; mRenderTargetDescInitialized = false; mStateManager.forceSetRasterState(); @@ -2021,9 +2212,9 @@ void Renderer9::markAllStateDirty() mCurPixelTextures[i] = angle::DirtyPointer; } - mAppliedIBSerial = 0; - mAppliedVertexShader = NULL; - mAppliedPixelShader = NULL; + mAppliedIBSerial = 0; + mAppliedVertexShader = nullptr; + mAppliedPixelShader = nullptr; mAppliedProgramSerial = 0; mStateManager.forceSetDXUniformsState(); @@ -2051,6 +2242,10 @@ void Renderer9::releaseDeviceResources() for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++) { + if (mNullColorbufferCache[i].buffer) + { + mNullColorbufferCache[i].buffer->detach(mDisplay->getProxyContext()); + } SafeDelete(mNullColorbufferCache[i].buffer); } } @@ -2059,19 +2254,7 @@ void Renderer9::releaseDeviceResources() bool Renderer9::testDeviceLost() { HRESULT status = getDeviceStatusCode(); - bool isLost = FAILED(status); - - if (isLost) - { - // ensure we note the device loss -- - // we'll probably get this done again by notifyDeviceLost - // but best to remember it! - // Note that we don't want to clear the device loss status here - // -- this needs to be done by resetDevice - mDeviceLost = true; - } - - return isLost; + return FAILED(status); } HRESULT Renderer9::getDeviceStatusCode() @@ -2080,7 +2263,7 @@ HRESULT Renderer9::getDeviceStatusCode() if (mDeviceEx) { - status = mDeviceEx->CheckDeviceState(NULL); + status = mDeviceEx->CheckDeviceState(nullptr); } else if (mDevice) { @@ -2096,16 +2279,16 @@ bool Renderer9::testDeviceResettable() // DEVICEREMOVED indicates the device has been stopped and must be recreated switch (getDeviceStatusCode()) { - case D3DERR_DEVICENOTRESET: - case D3DERR_DEVICEHUNG: - return true; - case D3DERR_DEVICELOST: - return (mDeviceEx != NULL); - case D3DERR_DEVICEREMOVED: - ASSERT(mDeviceEx != NULL); - return isRemovedDeviceResettable(); - default: - return false; + case D3DERR_DEVICENOTRESET: + case D3DERR_DEVICEHUNG: + return true; + case D3DERR_DEVICELOST: + return (mDeviceEx != nullptr); + case D3DERR_DEVICEREMOVED: + ASSERT(mDeviceEx != nullptr); + return isRemovedDeviceResettable(); + default: + return false; } } @@ -2115,12 +2298,12 @@ bool Renderer9::resetDevice() D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters(); - HRESULT result = D3D_OK; - bool lost = testDeviceLost(); + HRESULT result = D3D_OK; + bool lost = testDeviceLost(); bool removedDevice = (getDeviceStatusCode() == D3DERR_DEVICEREMOVED); // Device Removed is a feature which is only present with D3D9Ex - ASSERT(mDeviceEx != NULL || !removedDevice); + ASSERT(mDeviceEx != nullptr || !removedDevice); for (int attempts = 3; lost && attempts > 0; attempts--) { @@ -2134,16 +2317,16 @@ bool Renderer9::resetDevice() } else if (mDeviceEx) { - Sleep(500); // Give the graphics driver some CPU time - result = mDeviceEx->ResetEx(&presentParameters, NULL); - lost = testDeviceLost(); + Sleep(500); // Give the graphics driver some CPU time + result = mDeviceEx->ResetEx(&presentParameters, nullptr); + lost = testDeviceLost(); } else { result = mDevice->TestCooperativeLevel(); while (result == D3DERR_DEVICELOST) { - Sleep(100); // Give the graphics driver some CPU time + Sleep(100); // Give the graphics driver some CPU time result = mDevice->TestCooperativeLevel(); } @@ -2157,13 +2340,13 @@ bool Renderer9::resetDevice() if (FAILED(result)) { - ERR("Reset/ResetEx failed multiple times: 0x%08X", result); + ERR() << "Reset/ResetEx failed multiple times, " << gl::FmtHR(result); return false; } if (removedDevice && lost) { - ERR("Device lost reset failed multiple times"); + ERR() << "Device lost reset failed multiple times"; return false; } @@ -2171,11 +2354,12 @@ bool Renderer9::resetDevice() if (!removedDevice) { // reset device defaults - initializeDevice(); + if (initializeDevice().isError()) + { + return false; + } } - mDeviceLost = false; - return true; } @@ -2184,15 +2368,16 @@ bool Renderer9::isRemovedDeviceResettable() const bool success = false; #if ANGLE_D3D9EX == ANGLE_ENABLED - IDirect3D9Ex *d3d9Ex = NULL; - typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex**); - Direct3DCreate9ExFunc Direct3DCreate9ExPtr = reinterpret_cast(GetProcAddress(mD3d9Module, "Direct3DCreate9Ex")); + IDirect3D9Ex *d3d9Ex = nullptr; + typedef HRESULT(WINAPI * Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex **); + Direct3DCreate9ExFunc Direct3DCreate9ExPtr = + reinterpret_cast(GetProcAddress(mD3d9Module, "Direct3DCreate9Ex")); if (Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &d3d9Ex))) { D3DCAPS9 deviceCaps; HRESULT result = d3d9Ex->GetDeviceCaps(mAdapter, mDeviceType, &deviceCaps); - success = SUCCEEDED(result); + success = SUCCEEDED(result); } SafeRelease(d3d9Ex); @@ -2232,20 +2417,22 @@ std::string Renderer9::getRendererDescription() const rendererString << " Direct3D9"; } - rendererString << " vs_" << D3DSHADER_VERSION_MAJOR(mDeviceCaps.VertexShaderVersion) << "_" << D3DSHADER_VERSION_MINOR(mDeviceCaps.VertexShaderVersion); - rendererString << " ps_" << D3DSHADER_VERSION_MAJOR(mDeviceCaps.PixelShaderVersion) << "_" << D3DSHADER_VERSION_MINOR(mDeviceCaps.PixelShaderVersion); + rendererString << " vs_" << D3DSHADER_VERSION_MAJOR(mDeviceCaps.VertexShaderVersion) << "_" + << D3DSHADER_VERSION_MINOR(mDeviceCaps.VertexShaderVersion); + rendererString << " ps_" << D3DSHADER_VERSION_MAJOR(mDeviceCaps.PixelShaderVersion) << "_" + << D3DSHADER_VERSION_MINOR(mDeviceCaps.PixelShaderVersion); return rendererString.str(); } DeviceIdentifier Renderer9::getAdapterIdentifier() const { - DeviceIdentifier deviceIdentifier = { 0 }; - deviceIdentifier.VendorId = static_cast(mAdapterIdentifier.VendorId); - deviceIdentifier.DeviceId = static_cast(mAdapterIdentifier.DeviceId); - deviceIdentifier.SubSysId = static_cast(mAdapterIdentifier.SubSysId); - deviceIdentifier.Revision = static_cast(mAdapterIdentifier.Revision); - deviceIdentifier.FeatureLevel = 0; + DeviceIdentifier deviceIdentifier = {0}; + deviceIdentifier.VendorId = static_cast(mAdapterIdentifier.VendorId); + deviceIdentifier.DeviceId = static_cast(mAdapterIdentifier.DeviceId); + deviceIdentifier.SubSysId = static_cast(mAdapterIdentifier.SubSysId); + deviceIdentifier.Revision = static_cast(mAdapterIdentifier.Revision); + deviceIdentifier.FeatureLevel = 0; return deviceIdentifier; } @@ -2260,20 +2447,10 @@ unsigned int Renderer9::getReservedFragmentUniformVectors() const return d3d9_gl::GetReservedFragmentUniformVectors(); } -unsigned int Renderer9::getReservedVertexUniformBuffers() const -{ - return 0; -} - -unsigned int Renderer9::getReservedFragmentUniformBuffers() const -{ - return 0; -} - bool Renderer9::getShareHandleSupport() const { // PIX doesn't seem to support using share handles, so disable them. - return (mD3d9Ex != NULL) && !gl::DebugAnnotationsActive(); + return (mD3d9Ex != nullptr) && !gl::DebugAnnotationsActive(); } int Renderer9::getMajorShaderModel() const @@ -2298,7 +2475,7 @@ DWORD Renderer9::getCapsDeclTypes() const D3DPOOL Renderer9::getBufferPool(DWORD usage) const { - if (mD3d9Ex != NULL) + if (mD3d9Ex != nullptr) { return D3DPOOL_DEFAULT; } @@ -2313,66 +2490,126 @@ D3DPOOL Renderer9::getBufferPool(DWORD usage) const return D3DPOOL_DEFAULT; } -gl::Error Renderer9::copyImage2D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLint level) +gl::Error Renderer9::copyImage2D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) { RECT rect; - rect.left = sourceRect.x; - rect.top = sourceRect.y; - rect.right = sourceRect.x + sourceRect.width; + rect.left = sourceRect.x; + rect.top = sourceRect.y; + rect.right = sourceRect.x + sourceRect.width; rect.bottom = sourceRect.y + sourceRect.height; - return mBlit->copy2D(framebuffer, rect, destFormat, destOffset, storage, level); + return mBlit->copy2D(context, framebuffer, rect, destFormat, destOffset, storage, level); } -gl::Error Renderer9::copyImageCube(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLenum target, GLint level) +gl::Error Renderer9::copyImageCube(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLenum target, + GLint level) { RECT rect; - rect.left = sourceRect.x; - rect.top = sourceRect.y; - rect.right = sourceRect.x + sourceRect.width; + rect.left = sourceRect.x; + rect.top = sourceRect.y; + rect.right = sourceRect.x + sourceRect.width; rect.bottom = sourceRect.y + sourceRect.height; - return mBlit->copyCube(framebuffer, rect, destFormat, destOffset, storage, target, level); + return mBlit->copyCube(context, framebuffer, rect, destFormat, destOffset, storage, target, + level); } -gl::Error Renderer9::copyImage3D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLint level) +gl::Error Renderer9::copyImage3D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) { // 3D textures are not available in the D3D9 backend. UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + return gl::InternalError(); } -gl::Error Renderer9::copyImage2DArray(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLint level) +gl::Error Renderer9::copyImage2DArray(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) { // 2D array textures are not available in the D3D9 backend. UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + return gl::InternalError(); } -gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT) +gl::Error Renderer9::copyTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLenum destTarget, + GLint destLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) +{ + RECT rect; + rect.left = sourceRect.x; + rect.top = sourceRect.y; + rect.right = sourceRect.x + sourceRect.width; + rect.bottom = sourceRect.y + sourceRect.height; + + return mBlit->copyTexture(context, source, sourceLevel, rect, destFormat, destOffset, storage, + destTarget, destLevel, unpackFlipY, unpackPremultiplyAlpha, + unpackUnmultiplyAlpha); +} + +gl::Error Renderer9::copyCompressedTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + TextureStorage *storage, + GLint destLevel) +{ + UNIMPLEMENTED(); + return gl::InternalError(); +} + +gl::Error Renderer9::createRenderTarget(int width, + int height, + GLenum format, + GLsizei samples, + RenderTargetD3D **outRT) { const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(format); - const gl::TextureCaps &textureCaps = getRendererTextureCaps().get(format); - GLuint supportedSamples = textureCaps.getNearestSamples(samples); + const gl::TextureCaps &textureCaps = getNativeTextureCaps().get(format); + GLuint supportedSamples = textureCaps.getNearestSamples(samples); IDirect3DTexture9 *texture = nullptr; - IDirect3DSurface9 *renderTarget = NULL; + IDirect3DSurface9 *renderTarget = nullptr; if (width > 0 && height > 0) { bool requiresInitialization = false; - HRESULT result = D3DERR_INVALIDCALL; + HRESULT result = D3DERR_INVALIDCALL; - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format); + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(format); if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) { - result = mDevice->CreateDepthStencilSurface(width, height, d3d9FormatInfo.renderFormat, - gl_d3d9::GetMultisampleType(supportedSamples), - 0, FALSE, &renderTarget, NULL); + result = mDevice->CreateDepthStencilSurface( + width, height, d3d9FormatInfo.renderFormat, + gl_d3d9::GetMultisampleType(supportedSamples), 0, FALSE, &renderTarget, nullptr); } else { @@ -2398,25 +2635,25 @@ gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GL if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to create render target, " << gl::FmtHR(result); } if (requiresInitialization) { - // This format requires that the data be initialized before the render target can be used - // Unfortunately this requires a Get call on the d3d device but it is far better than having - // to mark the render target as lockable and copy data to the gpu. - IDirect3DSurface9 *prevRenderTarget = NULL; + // This format requires that the data be initialized before the render target can be + // used Unfortunately this requires a Get call on the d3d device but it is far better + // than having to mark the render target as lockable and copy data to the gpu. + IDirect3DSurface9 *prevRenderTarget = nullptr; mDevice->GetRenderTarget(0, &prevRenderTarget); mDevice->SetRenderTarget(0, renderTarget); - mDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 255), 0.0f, 0); + mDevice->Clear(0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 255), 0.0f, 0); mDevice->SetRenderTarget(0, prevRenderTarget); } } *outRT = new TextureRenderTarget9(texture, 0, renderTarget, format, width, height, 1, supportedSamples); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Renderer9::createRenderTargetCopy(RenderTargetD3D *source, RenderTargetD3D **outRT) @@ -2424,7 +2661,7 @@ gl::Error Renderer9::createRenderTargetCopy(RenderTargetD3D *source, RenderTarge ASSERT(source != nullptr); RenderTargetD3D *newRT = nullptr; - gl::Error error = createRenderTarget(source->getWidth(), source->getHeight(), + gl::Error error = createRenderTarget(source->getWidth(), source->getHeight(), source->getInternalFormat(), source->getSamples(), &newRT); if (error.isError()) { @@ -2439,31 +2676,16 @@ gl::Error Renderer9::createRenderTargetCopy(RenderTargetD3D *source, RenderTarge if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to copy render target, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to copy render target, " << gl::FmtHR(result); } *outRT = newRT; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -FramebufferImpl *Renderer9::createFramebuffer(const gl::Framebuffer::Data &data) -{ - return new Framebuffer9(data, this); -} - -ShaderImpl *Renderer9::createShader(const gl::Shader::Data &data) -{ - return new ShaderD3D(data); -} - -ProgramImpl *Renderer9::createProgram(const gl::Program::Data &data) -{ - return new ProgramD3D(data, this); -} - -gl::Error Renderer9::loadExecutable(const void *function, +gl::Error Renderer9::loadExecutable(const uint8_t *function, size_t length, - ShaderType type, + gl::ShaderType type, const std::vector &streamOutVaryings, bool separatedOutputBuffers, ShaderExecutableD3D **outExecutable) @@ -2473,10 +2695,10 @@ gl::Error Renderer9::loadExecutable(const void *function, switch (type) { - case SHADER_VERTEX: + case gl::SHADER_VERTEX: { - IDirect3DVertexShader9 *vshader = NULL; - gl::Error error = createVertexShader((DWORD*)function, length, &vshader); + IDirect3DVertexShader9 *vshader = nullptr; + gl::Error error = createVertexShader((DWORD *)function, length, &vshader); if (error.isError()) { return error; @@ -2484,10 +2706,10 @@ gl::Error Renderer9::loadExecutable(const void *function, *outExecutable = new ShaderExecutable9(function, length, vshader); } break; - case SHADER_PIXEL: + case gl::SHADER_FRAGMENT: { - IDirect3DPixelShader9 *pshader = NULL; - gl::Error error = createPixelShader((DWORD*)function, length, &pshader); + IDirect3DPixelShader9 *pshader = nullptr; + gl::Error error = createPixelShader((DWORD *)function, length, &pshader); if (error.isError()) { return error; @@ -2495,41 +2717,45 @@ gl::Error Renderer9::loadExecutable(const void *function, *outExecutable = new ShaderExecutable9(function, length, pshader); } break; - default: - UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + default: + UNREACHABLE(); + return gl::InternalError(); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, - ShaderType type, + gl::ShaderType type, const std::vector &streamOutVaryings, bool separatedOutputBuffers, - const D3DCompilerWorkarounds &workarounds, + const angle::CompilerWorkaroundsD3D &workarounds, ShaderExecutableD3D **outExectuable) { // Transform feedback is not supported in ES2 or D3D9 ASSERT(streamOutVaryings.empty()); - const char *profileType = NULL; + std::stringstream profileStream; + switch (type) { - case SHADER_VERTEX: - profileType = "vs"; - break; - case SHADER_PIXEL: - profileType = "ps"; - break; - default: - UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + case gl::SHADER_VERTEX: + profileStream << "vs"; + break; + case gl::SHADER_FRAGMENT: + profileStream << "ps"; + break; + default: + UNREACHABLE(); + return gl::InternalError(); } - unsigned int profileMajorVersion = (getMajorShaderModel() >= 3) ? 3 : 2; - unsigned int profileMinorVersion = 0; - std::string profile = FormatString("%s_%u_%u", profileType, profileMajorVersion, profileMinorVersion); + + profileStream << "_" << ((getMajorShaderModel() >= 3) ? 3 : 2); + profileStream << "_" + << "0"; + + std::string profile = profileStream.str(); UINT flags = ANGLE_COMPILE_OPTIMIZATION_LEVEL; @@ -2551,31 +2777,35 @@ gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, flags |= D3DCOMPILE_DEBUG; } - // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options. - // Try the default flags first and if compilation fails, try some alternatives. + // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders + // when it would otherwise pass with alternative options. Try the default flags first and if + // compilation fails, try some alternatives. std::vector configs; - configs.push_back(CompileConfig(flags, "default" )); - configs.push_back(CompileConfig(flags | D3DCOMPILE_AVOID_FLOW_CONTROL, "avoid flow control" )); + configs.push_back(CompileConfig(flags, "default")); + configs.push_back(CompileConfig(flags | D3DCOMPILE_AVOID_FLOW_CONTROL, "avoid flow control")); configs.push_back(CompileConfig(flags | D3DCOMPILE_PREFER_FLOW_CONTROL, "prefer flow control")); - ID3DBlob *binary = NULL; + ID3DBlob *binary = nullptr; std::string debugInfo; - gl::Error error = mCompiler.compileToBinary(infoLog, shaderHLSL, profile, configs, NULL, &binary, &debugInfo); + gl::Error error = mCompiler.compileToBinary(infoLog, shaderHLSL, profile, configs, nullptr, + &binary, &debugInfo); if (error.isError()) { return error; } - // It's possible that binary is NULL if the compiler failed in all configurations. Set the executable to NULL - // and return GL_NO_ERROR to signify that there was a link error but the internal state is still OK. + // It's possible that binary is NULL if the compiler failed in all configurations. Set the + // executable to NULL and return GL_NO_ERROR to signify that there was a link error but the + // internal state is still OK. if (!binary) { - *outExectuable = NULL; - return gl::Error(GL_NO_ERROR); + *outExectuable = nullptr; + return gl::NoError(); } - error = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type, - streamOutVaryings, separatedOutputBuffers, outExectuable); + error = loadExecutable(reinterpret_cast(binary->GetBufferPointer()), + binary->GetBufferSize(), type, streamOutVaryings, separatedOutputBuffers, + outExectuable); SafeRelease(binary); if (error.isError()) @@ -2588,7 +2818,12 @@ gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, (*outExectuable)->appendDebugInfo(debugInfo); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); +} + +gl::Error Renderer9::ensureHLSLCompilerInitialized() +{ + return mCompiler.ensureInitialized(); } UniformStorageD3D *Renderer9::createUniformStorage(size_t storageSize) @@ -2603,7 +2838,7 @@ gl::Error Renderer9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *des D3DPOOL Renderer9::getTexturePool(DWORD usage) const { - if (mD3d9Ex != NULL) + if (mD3d9Ex != nullptr) { return D3DPOOL_DEFAULT; } @@ -2618,7 +2853,9 @@ D3DPOOL Renderer9::getTexturePool(DWORD usage) const return D3DPOOL_DEFAULT; } -gl::Error Renderer9::copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged) +gl::Error Renderer9::copyToRenderTarget(IDirect3DSurface9 *dest, + IDirect3DSurface9 *source, + bool fromManaged) { ASSERT(source && dest); @@ -2630,28 +2867,34 @@ gl::Error Renderer9::copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurfac source->GetDesc(&desc); IDirect3DSurface9 *surf = 0; - result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL); + result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, + D3DPOOL_SYSTEMMEM, &surf, nullptr); if (SUCCEEDED(result)) { - Image9::copyLockableSurfaces(surf, source); - result = mDevice->UpdateSurface(surf, NULL, dest, NULL); + ANGLE_TRY(Image9::copyLockableSurfaces(surf, source)); + result = mDevice->UpdateSurface(surf, nullptr, dest, nullptr); SafeRelease(surf); } } else { endScene(); - result = mDevice->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE); + result = mDevice->StretchRect(source, nullptr, dest, nullptr, D3DTEXF_NONE); } if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to blit internal texture, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to blit internal texture, " << gl::FmtHR(result); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); +} + +RendererClass Renderer9::getRendererClass() const +{ + return RENDERER_D3D9; } ImageD3D *Renderer9::createImage() @@ -2659,18 +2902,34 @@ ImageD3D *Renderer9::createImage() return new Image9(this); } -gl::Error Renderer9::generateMipmap(ImageD3D *dest, ImageD3D *src) +gl::Error Renderer9::generateMipmap(const gl::Context *context, ImageD3D *dest, ImageD3D *src) { Image9 *src9 = GetAs(src); Image9 *dst9 = GetAs(dest); return Image9::generateMipmap(dst9, src9); } -gl::Error Renderer9::generateMipmapsUsingD3D(TextureStorage *storage, - const gl::TextureState &textureState) +gl::Error Renderer9::generateMipmapUsingD3D(const gl::Context *context, + TextureStorage *storage, + const gl::TextureState &textureState) { UNREACHABLE(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); +} + +gl::Error Renderer9::copyImage(const gl::Context *context, + ImageD3D *dest, + ImageD3D *source, + const gl::Rectangle &sourceRect, + const gl::Offset &destOffset, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) +{ + Image9 *dest9 = GetAs(dest); + Image9 *src9 = GetAs(source); + return Image9::CopyImage(context, dest9, src9, sourceRect, destOffset, unpackFlipY, + unpackPremultiplyAlpha, unpackUnmultiplyAlpha); } TextureStorage *Renderer9::createTextureStorage2D(SwapChainD3D *swapChain) @@ -2679,59 +2938,83 @@ TextureStorage *Renderer9::createTextureStorage2D(SwapChainD3D *swapChain) return new TextureStorage9_2D(this, swapChain9); } -TextureStorage *Renderer9::createTextureStorageEGLImage(EGLImageD3D *eglImage) +TextureStorage *Renderer9::createTextureStorageEGLImage(EGLImageD3D *eglImage, + RenderTargetD3D *renderTargetD3D) { - return new TextureStorage9_EGLImage(this, eglImage); + return new TextureStorage9_EGLImage(this, eglImage, GetAs(renderTargetD3D)); } -TextureStorage *Renderer9::createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly) +TextureStorage *Renderer9::createTextureStorageExternal( + egl::Stream *stream, + const egl::Stream::GLTextureDescription &desc) +{ + UNIMPLEMENTED(); + return nullptr; +} + +TextureStorage *Renderer9::createTextureStorage2D(GLenum internalformat, + bool renderTarget, + GLsizei width, + GLsizei height, + int levels, + bool hintLevelZeroOnly) { return new TextureStorage9_2D(this, internalformat, renderTarget, width, height, levels); } -TextureStorage *Renderer9::createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly) +TextureStorage *Renderer9::createTextureStorageCube(GLenum internalformat, + bool renderTarget, + int size, + int levels, + bool hintLevelZeroOnly) { - return new TextureStorage9_Cube(this, internalformat, renderTarget, size, levels, hintLevelZeroOnly); + return new TextureStorage9_Cube(this, internalformat, renderTarget, size, levels, + hintLevelZeroOnly); } -TextureStorage *Renderer9::createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) +TextureStorage *Renderer9::createTextureStorage3D(GLenum internalformat, + bool renderTarget, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels) { // 3D textures are not supported by the D3D9 backend. UNREACHABLE(); - return NULL; + return nullptr; } -TextureStorage *Renderer9::createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) +TextureStorage *Renderer9::createTextureStorage2DArray(GLenum internalformat, + bool renderTarget, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels) { // 2D array textures are not supported by the D3D9 backend. UNREACHABLE(); - return NULL; + return nullptr; } -TextureImpl *Renderer9::createTexture(GLenum target) +TextureStorage *Renderer9::createTextureStorage2DMultisample(GLenum internalformat, + GLsizei width, + GLsizei height, + int levels, + int samples, + bool fixedSampleLocations) { - switch(target) - { - case GL_TEXTURE_2D: return new TextureD3D_2D(this); - case GL_TEXTURE_CUBE_MAP: return new TextureD3D_Cube(this); - default: UNREACHABLE(); - } + // 2D multisampled textures are not supported by the D3D9 backend. + UNREACHABLE(); return NULL; } -RenderbufferImpl *Renderer9::createRenderbuffer() -{ - RenderbufferD3D *renderbuffer = new RenderbufferD3D(this); - return renderbuffer; -} - bool Renderer9::getLUID(LUID *adapterLuid) const { adapterLuid->HighPart = 0; - adapterLuid->LowPart = 0; + adapterLuid->LowPart = 0; if (mD3d9Ex) { @@ -2752,6 +3035,40 @@ GLenum Renderer9::getVertexComponentType(gl::VertexFormatType vertexFormatType) return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormatType).componentType; } +gl::ErrorOrResult Renderer9::getVertexSpaceRequired(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + GLsizei count, + GLsizei instances) const +{ + if (!attrib.enabled) + { + return 16u; + } + + gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib, GL_FLOAT); + const d3d9::VertexFormat &d3d9VertexInfo = + d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormatType); + + unsigned int elementCount = 0; + const unsigned int divisor = binding.getDivisor(); + if (instances == 0 || divisor == 0) + { + elementCount = static_cast(count); + } + else + { + // Round up to divisor, if possible + elementCount = UnsignedCeilDivide(static_cast(instances), divisor); + } + + if (d3d9VertexInfo.outputElementSize > std::numeric_limits::max() / elementCount) + { + return gl::OutOfMemory() << "New vertex buffer size would result in an overflow."; + } + + return static_cast(d3d9VertexInfo.outputElementSize) * elementCount; +} + void Renderer9::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions, @@ -2761,31 +3078,11 @@ void Renderer9::generateCaps(gl::Caps *outCaps, outExtensions, outLimitations); } -WorkaroundsD3D Renderer9::generateWorkarounds() const +angle::WorkaroundsD3D Renderer9::generateWorkarounds() const { return d3d9::GenerateWorkarounds(); } -void Renderer9::createAnnotator() -{ - mAnnotator = new DebugAnnotator9(); -} - -gl::Error Renderer9::clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) -{ - // TODO(jmadill): faster way? - for (size_t samplerIndex = rangeStart; samplerIndex < rangeEnd; samplerIndex++) - { - gl::Error error = setTexture(samplerType, static_cast(samplerIndex), nullptr); - if (error.isError()) - { - return error; - } - } - - return gl::Error(GL_NO_ERROR); -} - egl::Error Renderer9::getEGLDevice(DeviceImpl **device) { if (mEGLDevice == nullptr) @@ -2803,14 +3100,211 @@ egl::Error Renderer9::getEGLDevice(DeviceImpl **device) } *device = static_cast(mEGLDevice); - return egl::Error(EGL_SUCCESS); + return egl::NoError(); } Renderer9::CurSamplerState::CurSamplerState() - : forceSet(true), - baseLevel(std::numeric_limits::max()), - samplerState() + : forceSet(true), baseLevel(std::numeric_limits::max()), samplerState() { } +gl::Error Renderer9::genericDrawElements(const gl::Context *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei instances) +{ + const auto &data = context->getContextState(); + gl::Program *program = context->getGLState().getProgram(); + ASSERT(program != nullptr); + ProgramD3D *programD3D = GetImplAs(program); + bool usesPointSize = programD3D->usesPointSize(); + + programD3D->updateSamplerMapping(); + + if (!applyPrimitiveType(mode, count, usesPointSize)) + { + return gl::NoError(); + } + + ANGLE_TRY(updateState(context, mode)); + ANGLE_TRY(applyTextures(context)); + ANGLE_TRY(applyShaders(context, mode)); + + if (!skipDraw(data.getState(), mode)) + { + ANGLE_TRY(drawElementsImpl(context, mode, count, type, indices, instances)); + } + + return gl::NoError(); } + +gl::Error Renderer9::genericDrawArrays(const gl::Context *context, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instances) +{ + gl::Program *program = context->getGLState().getProgram(); + ASSERT(program != nullptr); + ProgramD3D *programD3D = GetImplAs(program); + bool usesPointSize = programD3D->usesPointSize(); + + programD3D->updateSamplerMapping(); + + if (!applyPrimitiveType(mode, count, usesPointSize)) + { + return gl::NoError(); + } + + ANGLE_TRY(updateState(context, mode)); + ANGLE_TRY(applyVertexBuffer(context, mode, first, count, instances, nullptr)); + ANGLE_TRY(applyTextures(context)); + ANGLE_TRY(applyShaders(context, mode)); + + if (!skipDraw(context->getGLState(), mode)) + { + ANGLE_TRY(drawArraysImpl(context, mode, first, count, instances)); + } + + return gl::NoError(); +} + +FramebufferImpl *Renderer9::createDefaultFramebuffer(const gl::FramebufferState &state) +{ + return new Framebuffer9(state, this); +} + +gl::Version Renderer9::getMaxSupportedESVersion() const +{ + return gl::Version(2, 0); +} + +gl::Error Renderer9::clearRenderTarget(RenderTargetD3D *renderTarget, + const gl::ColorF &clearColorValue, + const float clearDepthValue, + const unsigned int clearStencilValue) +{ + D3DCOLOR color = + D3DCOLOR_ARGB(gl::unorm<8>(clearColorValue.alpha), gl::unorm<8>(clearColorValue.red), + gl::unorm<8>(clearColorValue.green), gl::unorm<8>(clearColorValue.blue)); + float depth = clearDepthValue; + DWORD stencil = clearStencilValue & 0x000000FF; + + unsigned int renderTargetSerial = renderTarget->getSerial(); + RenderTarget9 *renderTarget9 = GetAs(renderTarget); + IDirect3DSurface9 *renderTargetSurface = renderTarget9->getSurface(); + ASSERT(renderTargetSurface); + + DWORD dxClearFlags = 0; + + const gl::InternalFormat &internalFormatInfo = + gl::GetSizedInternalFormatInfo(renderTarget->getInternalFormat()); + if (internalFormatInfo.depthBits > 0 || internalFormatInfo.stencilBits > 0) + { + dxClearFlags = D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL; + if (mAppliedDepthStencilSerial != renderTargetSerial) + { + mDevice->SetDepthStencilSurface(renderTargetSurface); + } + } + else + { + dxClearFlags = D3DCLEAR_TARGET; + if (mAppliedRenderTargetSerial != renderTargetSerial) + { + mDevice->SetRenderTarget(0, renderTargetSurface); + } + } + SafeRelease(renderTargetSurface); + + D3DVIEWPORT9 viewport; + viewport.X = 0; + viewport.Y = 0; + viewport.Width = renderTarget->getWidth(); + viewport.Height = renderTarget->getHeight(); + mDevice->SetViewport(&viewport); + + mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); + + mDevice->Clear(0, nullptr, dxClearFlags, color, depth, stencil); + + markAllStateDirty(); + + return gl::NoError(); +} + +bool Renderer9::canSelectViewInVertexShader() const +{ + return false; +} + +// For each Direct3D sampler of either the pixel or vertex stage, +// looks up the corresponding OpenGL texture image unit and texture type, +// and sets the texture and its addressing/filtering state (or NULL when inactive). +// Sampler mapping needs to be up-to-date on the program object before this is called. +gl::Error Renderer9::applyTextures(const gl::Context *context, gl::SamplerType shaderType) +{ + const auto &glState = context->getGLState(); + const auto &caps = context->getCaps(); + ProgramD3D *programD3D = GetImplAs(glState.getProgram()); + + ASSERT(!programD3D->isSamplerMappingDirty()); + + // TODO(jmadill): Use the Program's sampler bindings. + const auto &completeTextures = glState.getCompleteTextureCache(); + + unsigned int samplerRange = programD3D->getUsedSamplerRange(shaderType); + for (unsigned int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++) + { + GLint textureUnit = programD3D->getSamplerMapping(shaderType, samplerIndex, caps); + ASSERT(textureUnit != -1); + gl::Texture *texture = completeTextures[textureUnit]; + + // A nullptr texture indicates incomplete. + if (texture) + { + gl::Sampler *samplerObject = glState.getSampler(textureUnit); + + const gl::SamplerState &samplerState = + samplerObject ? samplerObject->getSamplerState() : texture->getSamplerState(); + + ANGLE_TRY(setSamplerState(context, shaderType, samplerIndex, texture, samplerState)); + ANGLE_TRY(setTexture(context, shaderType, samplerIndex, texture)); + } + else + { + GLenum textureType = programD3D->getSamplerTextureType(shaderType, samplerIndex); + + // Texture is not sampler complete or it is in use by the framebuffer. Bind the + // incomplete texture. + gl::Texture *incompleteTexture = nullptr; + ANGLE_TRY(getIncompleteTexture(context, textureType, &incompleteTexture)); + ANGLE_TRY(setSamplerState(context, shaderType, samplerIndex, incompleteTexture, + incompleteTexture->getSamplerState())); + ANGLE_TRY(setTexture(context, shaderType, samplerIndex, incompleteTexture)); + } + } + + // Set all the remaining textures to NULL + size_t samplerCount = (shaderType == gl::SAMPLER_PIXEL) ? caps.maxTextureImageUnits + : caps.maxVertexTextureImageUnits; + + // TODO(jmadill): faster way? + for (size_t samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++) + { + ANGLE_TRY(setTexture(context, shaderType, static_cast(samplerIndex), nullptr)); + } + + return gl::NoError(); +} + +gl::Error Renderer9::applyTextures(const gl::Context *context) +{ + ANGLE_TRY(applyTextures(context, gl::SAMPLER_VERTEX)); + ANGLE_TRY(applyTextures(context, gl::SAMPLER_PIXEL)); + return gl::NoError(); +} + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.h index a0dfecb02e..9ddee45f0f 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.h @@ -12,12 +12,13 @@ #include "common/angleutils.h" #include "common/mathutil.h" #include "libANGLE/renderer/d3d/HLSLCompiler.h" -#include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/RenderTargetD3D.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h" #include "libANGLE/renderer/d3d/d3d9/ShaderCache.h" -#include "libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h" #include "libANGLE/renderer/d3d/d3d9/StateManager9.h" +#include "libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h" +#include "libANGLE/renderer/driver_utils.h" namespace gl { @@ -32,6 +33,7 @@ class AttributeMap; namespace rx { class Blit9; +class Context9; class IndexDataManager; class ProgramD3D; class StreamingIndexBufferInterface; @@ -65,184 +67,270 @@ class Renderer9 : public RendererD3D { public: explicit Renderer9(egl::Display *display); - virtual ~Renderer9(); + ~Renderer9() override; egl::Error initialize() override; - virtual bool resetDevice(); + bool resetDevice() override; - egl::ConfigSet generateConfigs() const override; + egl::ConfigSet generateConfigs() override; void generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const override; void startScene(); void endScene(); - gl::Error flush() override; - gl::Error finish() override; + gl::Error flush(); + gl::Error finish(); - SwapChainD3D *createSwapChain(NativeWindow nativeWindow, + bool isValidNativeWindow(EGLNativeWindowType window) const override; + NativeWindowD3D *createNativeWindow(EGLNativeWindowType window, + const egl::Config *config, + const egl::AttributeMap &attribs) const override; + + SwapChainD3D *createSwapChain(NativeWindowD3D *nativeWindow, HANDLE shareHandle, + IUnknown *d3dTexture, GLenum backBufferFormat, GLenum depthBufferFormat, - EGLint orientation) override; + EGLint orientation, + EGLint samples) override; + egl::Error getD3DTextureInfo(const egl::Config *configuration, + IUnknown *d3dTexture, + EGLint *width, + EGLint *height, + GLenum *fboFormat) const override; + egl::Error validateShareHandle(const egl::Config *config, + HANDLE shareHandle, + const egl::AttributeMap &attribs) const override; - CompilerImpl *createCompiler() override; + ContextImpl *createContext(const gl::ContextState &state) override; gl::Error allocateEventQuery(IDirect3DQuery9 **outQuery); - void freeEventQuery(IDirect3DQuery9* query); + void freeEventQuery(IDirect3DQuery9 *query); // resource creation - gl::Error createVertexShader(const DWORD *function, size_t length, IDirect3DVertexShader9 **outShader); - gl::Error createPixelShader(const DWORD *function, size_t length, IDirect3DPixelShader9 **outShader); + gl::Error createVertexShader(const DWORD *function, + size_t length, + IDirect3DVertexShader9 **outShader); + gl::Error createPixelShader(const DWORD *function, + size_t length, + IDirect3DPixelShader9 **outShader); HRESULT createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer); - HRESULT createIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, IDirect3DIndexBuffer9 **ppIndexBuffer); - virtual gl::Error generateSwizzle(gl::Texture *texture); - virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler); - virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture); + HRESULT createIndexBuffer(UINT Length, + DWORD Usage, + D3DFORMAT Format, + IDirect3DIndexBuffer9 **ppIndexBuffer); + gl::Error setSamplerState(const gl::Context *context, + gl::SamplerType type, + int index, + gl::Texture *texture, + const gl::SamplerState &sampler); + gl::Error setTexture(const gl::Context *context, + gl::SamplerType type, + int index, + gl::Texture *texture); - gl::Error setUniformBuffers(const gl::Data &data, - const std::vector &vertexUniformBuffers, - const std::vector &fragmentUniformBuffers) override; - - gl::Error updateState(const gl::Data &data, GLenum drawMode) override; + gl::Error updateState(const gl::Context *context, GLenum drawMode); void setScissorRectangle(const gl::Rectangle &scissor, bool enabled); - void setViewport(const gl::Caps *caps, - const gl::Rectangle &viewport, + void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, bool ignoreViewport); - gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) override; - gl::Error applyRenderTarget(const gl::FramebufferAttachment *colorAttachment, + gl::Error applyRenderTarget(const gl::Context *context, const gl::Framebuffer *frameBuffer); + gl::Error applyRenderTarget(const gl::Context *context, + const gl::FramebufferAttachment *colorAttachment, const gl::FramebufferAttachment *depthStencilAttachment); - gl::Error applyUniforms(const ProgramD3D &programD3D, - GLenum drawMode, - const std::vector &uniformArray) override; - virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize); - virtual gl::Error applyVertexBuffer(const gl::State &state, - GLenum mode, - GLint first, - GLsizei count, - GLsizei instances, - TranslatedIndexData *indexInfo); - gl::Error applyIndexBuffer(const gl::Data &data, - const GLvoid *indices, + gl::Error applyUniforms(ProgramD3D *programD3D); + bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize); + gl::Error applyVertexBuffer(const gl::Context *context, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instances, + TranslatedIndexData *indexInfo); + gl::Error applyIndexBuffer(const gl::Context *context, + const void *indices, GLsizei count, GLenum mode, GLenum type, - TranslatedIndexData *indexInfo) override; + TranslatedIndexData *indexInfo); - void applyTransformFeedbackBuffers(const gl::State &state) override; - - gl::Error clear(const ClearParameters &clearParams, + gl::Error clear(const gl::Context *context, + const ClearParameters &clearParams, const gl::FramebufferAttachment *colorBuffer, const gl::FramebufferAttachment *depthStencilBuffer); - virtual void markAllStateDirty(); + void markAllStateDirty(); // lost device bool testDeviceLost() override; bool testDeviceResettable() override; VendorID getVendorId() const; - std::string getRendererDescription() const override; + std::string getRendererDescription() const; DeviceIdentifier getAdapterIdentifier() const override; IDirect3DDevice9 *getDevice() { return mDevice; } void *getD3DDevice() override; - virtual unsigned int getReservedVertexUniformVectors() const; - virtual unsigned int getReservedFragmentUniformVectors() const; - virtual unsigned int getReservedVertexUniformBuffers() const; - virtual unsigned int getReservedFragmentUniformBuffers() const; + unsigned int getReservedVertexUniformVectors() const; + unsigned int getReservedFragmentUniformVectors() const; bool getShareHandleSupport() const; - virtual int getMajorShaderModel() const; + int getMajorShaderModel() const override; int getMinorShaderModel() const override; std::string getShaderModelSuffix() const override; DWORD getCapsDeclTypes() const; // Pixel operations - virtual gl::Error copyImage2D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLint level); - virtual gl::Error copyImageCube(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLenum target, GLint level); - virtual gl::Error copyImage3D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLint level); - virtual gl::Error copyImage2DArray(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLint level); + gl::Error copyImage2D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) override; + gl::Error copyImageCube(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLenum target, + GLint level) override; + gl::Error copyImage3D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) override; + gl::Error copyImage2DArray(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) override; + + gl::Error copyTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLenum destTarget, + GLint destLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) override; + gl::Error copyCompressedTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + TextureStorage *storage, + GLint destLevel) override; // RenderTarget creation - virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT); + gl::Error createRenderTarget(int width, + int height, + GLenum format, + GLsizei samples, + RenderTargetD3D **outRT) override; gl::Error createRenderTargetCopy(RenderTargetD3D *source, RenderTargetD3D **outRT) override; - // Framebuffer creation - FramebufferImpl *createFramebuffer(const gl::Framebuffer::Data &data) override; - - // Shader creation - ShaderImpl *createShader(const gl::Shader::Data &data) override; - ProgramImpl *createProgram(const gl::Program::Data &data) override; - // Shader operations - gl::Error loadExecutable(const void *function, + gl::Error loadExecutable(const uint8_t *function, size_t length, - ShaderType type, + gl::ShaderType type, const std::vector &streamOutVaryings, bool separatedOutputBuffers, ShaderExecutableD3D **outExecutable) override; gl::Error compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, - ShaderType type, + gl::ShaderType type, const std::vector &streamOutVaryings, bool separatedOutputBuffers, - const D3DCompilerWorkarounds &workarounds, + const angle::CompilerWorkaroundsD3D &workarounds, ShaderExecutableD3D **outExectuable) override; + gl::Error ensureHLSLCompilerInitialized() override; + UniformStorageD3D *createUniformStorage(size_t storageSize) override; // Image operations - virtual ImageD3D *createImage(); - gl::Error generateMipmap(ImageD3D *dest, ImageD3D *source) override; - gl::Error generateMipmapsUsingD3D(TextureStorage *storage, - const gl::TextureState &textureState) override; - virtual TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain); - TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage) override; - virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly); - virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly); - virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels); - virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels); + ImageD3D *createImage() override; + gl::Error generateMipmap(const gl::Context *context, ImageD3D *dest, ImageD3D *source) override; + gl::Error generateMipmapUsingD3D(const gl::Context *context, + TextureStorage *storage, + const gl::TextureState &textureState) override; + gl::Error copyImage(const gl::Context *context, + ImageD3D *dest, + ImageD3D *source, + const gl::Rectangle &sourceRect, + const gl::Offset &destOffset, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) override; + TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain) override; + TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage, + RenderTargetD3D *renderTargetD3D) override; + TextureStorage *createTextureStorageExternal( + egl::Stream *stream, + const egl::Stream::GLTextureDescription &desc) override; + TextureStorage *createTextureStorage2D(GLenum internalformat, + bool renderTarget, + GLsizei width, + GLsizei height, + int levels, + bool hintLevelZeroOnly) override; + TextureStorage *createTextureStorageCube(GLenum internalformat, + bool renderTarget, + int size, + int levels, + bool hintLevelZeroOnly) override; + TextureStorage *createTextureStorage3D(GLenum internalformat, + bool renderTarget, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels) override; + TextureStorage *createTextureStorage2DArray(GLenum internalformat, + bool renderTarget, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels) override; - // Texture creation - virtual TextureImpl *createTexture(GLenum target); - - // Renderbuffer creation - virtual RenderbufferImpl *createRenderbuffer(); + TextureStorage *createTextureStorage2DMultisample(GLenum internalformat, + GLsizei width, + GLsizei height, + int levels, + int samples, + bool fixedSampleLocations) override; // Buffer creation - virtual BufferImpl *createBuffer(); - virtual VertexBuffer *createVertexBuffer(); - virtual IndexBuffer *createIndexBuffer(); + VertexBuffer *createVertexBuffer() override; + IndexBuffer *createIndexBuffer() override; - // Vertex Array creation - VertexArrayImpl *createVertexArray(const gl::VertexArray::Data &data) override; - - // Query and Fence creation - virtual QueryImpl *createQuery(GLenum type); - virtual FenceNVImpl *createFenceNV(); - virtual FenceSyncImpl *createFenceSync(); - - // Transform Feedback creation - virtual TransformFeedbackImpl* createTransformFeedback(); + // Stream Creation + StreamProducerImpl *createStreamProducerD3DTextureNV12( + egl::Stream::ConsumerType consumerType, + const egl::AttributeMap &attribs) override; // Buffer-to-texture and Texture-to-buffer copies - virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const; - virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget, - GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea); - - void syncState(const gl::State &state, const gl::State::DirtyBits &bitmask) override; + bool supportsFastCopyBufferToTexture(GLenum internalFormat) const override; + gl::Error fastCopyBufferToTexture(const gl::Context *context, + const gl::PixelUnpackState &unpack, + unsigned int offset, + RenderTargetD3D *destRenderTarget, + GLenum destinationFormat, + GLenum sourcePixelsType, + const gl::Box &destArea) override; // D3D9-renderer specific methods gl::Error boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest); @@ -250,42 +338,82 @@ class Renderer9 : public RendererD3D D3DPOOL getTexturePool(DWORD usage) const; bool getLUID(LUID *adapterLuid) const override; - VertexConversionType getVertexConversionType(gl::VertexFormatType vertexFormatType) const override; + VertexConversionType getVertexConversionType( + gl::VertexFormatType vertexFormatType) const override; GLenum getVertexComponentType(gl::VertexFormatType vertexFormatType) const override; - gl::Error copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged); + // Warning: you should ensure binding really matches attrib.bindingIndex before using this + // function. + gl::ErrorOrResult getVertexSpaceRequired(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + GLsizei count, + GLsizei instances) const override; - RendererClass getRendererClass() const override { return RENDERER_D3D9; } + gl::Error copyToRenderTarget(IDirect3DSurface9 *dest, + IDirect3DSurface9 *source, + bool fromManaged); + + RendererClass getRendererClass() const override; D3DDEVTYPE getD3D9DeviceType() const { return mDeviceType; } egl::Error getEGLDevice(DeviceImpl **device) override; - protected: - void createAnnotator() override; - gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) override; - gl::Error applyShadersImpl(const gl::Data &data, GLenum drawMode) override; + StateManager9 *getStateManager() { return &mStateManager; } + + gl::Error genericDrawArrays(const gl::Context *context, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instances); + + gl::Error genericDrawElements(const gl::Context *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei instances); + + // Necessary hack for default framebuffers in D3D. + FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override; + + DebugAnnotator9 *getAnnotator() { return &mAnnotator; } + + gl::Version getMaxSupportedESVersion() const override; + + gl::Error clearRenderTarget(RenderTargetD3D *renderTarget, + const gl::ColorF &clearColorValue, + const float clearDepthValue, + const unsigned int clearStencilValue) override; + + bool canSelectViewInVertexShader() const override; private: - gl::Error drawArraysImpl(const gl::Data &data, + gl::Error drawArraysImpl(const gl::Context *context, GLenum mode, + GLint startVertex, GLsizei count, - GLsizei instances) override; - gl::Error drawElementsImpl(const gl::Data &data, - const TranslatedIndexData &indexInfo, + GLsizei instances); + gl::Error drawElementsImpl(const gl::Context *context, GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, - GLsizei instances) override; + const void *indices, + GLsizei instances); - void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, + gl::Error applyShaders(const gl::Context *context, GLenum drawMode); + + gl::Error applyTextures(const gl::Context *context); + gl::Error applyTextures(const gl::Context *context, gl::SamplerType shaderType); + + void generateCaps(gl::Caps *outCaps, + gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions, gl::Limitations *outLimitations) const override; - WorkaroundsD3D generateWorkarounds() const override; + angle::WorkaroundsD3D generateWorkarounds() const override; - gl::Error setBlendDepthRasterStates(const gl::Data &glData, GLenum drawMode); + gl::Error setBlendDepthRasterStates(const gl::Context *context, GLenum drawMode); void release(); @@ -293,18 +421,30 @@ class Renderer9 : public RendererD3D void applyUniformniv(const D3DUniform *targetUniform, const GLint *v); void applyUniformnbv(const D3DUniform *targetUniform, const GLint *v); - gl::Error drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); - gl::Error drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); + gl::Error drawLineLoop(const gl::Context *context, + GLsizei count, + GLenum type, + const void *indices, + int minIndex, + gl::Buffer *elementArrayBuffer); + gl::Error drawIndexedPoints(const gl::Context *context, + GLsizei count, + GLenum type, + const void *indices, + int minIndex, + gl::Buffer *elementArrayBuffer); gl::Error getCountingIB(size_t count, StaticIndexBufferInterface **outIB); - gl::Error getNullColorbuffer(const gl::FramebufferAttachment *depthbuffer, const gl::FramebufferAttachment **outColorBuffer); + gl::Error getNullColorbuffer(const gl::Context *context, + const gl::FramebufferAttachment *depthbuffer, + const gl::FramebufferAttachment **outColorBuffer); D3DPOOL getBufferPool(DWORD usage) const; HMODULE mD3d9Module; - void initializeDevice(); + egl::Error initializeDevice(); D3DPRESENT_PARAMETERS getDefaultPresentParameters(); void releaseDeviceResources(); @@ -314,7 +454,7 @@ class Renderer9 : public RendererD3D UINT mAdapter; D3DDEVTYPE mDeviceType; - IDirect3D9 *mD3d9; // Always valid after successful initialization. + IDirect3D9 *mD3d9; // Always valid after successful initialization. IDirect3D9Ex *mD3d9Ex; // Might be null if D3D9Ex is not supported. IDirect3DDevice9 *mDevice; IDirect3DDevice9Ex *mDeviceEx; // Might be null if D3D9Ex is not supported. @@ -368,7 +508,7 @@ class Renderer9 : public RendererD3D unsigned int mAppliedProgramSerial; // A pool of event queries that are currently unused. - std::vector mEventQueryPool; + std::vector mEventQueryPool; VertexShaderCache mVertexShaderCache; PixelShaderCache mPixelShaderCache; @@ -379,7 +519,10 @@ class Renderer9 : public RendererD3D StreamingIndexBufferInterface *mLineLoopIB; StaticIndexBufferInterface *mCountingIB; - enum { NUM_NULL_COLORBUFFER_CACHE_ENTRIES = 12 }; + enum + { + NUM_NULL_COLORBUFFER_CACHE_ENTRIES = 12 + }; struct NullColorbufferCacheEntry { UINT lruCount; @@ -390,7 +533,11 @@ class Renderer9 : public RendererD3D UINT mMaxNullColorbufferLRU; DeviceD3D *mEGLDevice; + std::vector mTranslatedAttribCache; + + DebugAnnotator9 mAnnotator; }; -} -#endif // LIBANGLE_RENDERER_D3D_D3D9_RENDERER9_H_ +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D9_RENDERER9_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderCache.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderCache.h index cf831c62fa..399770dd8d 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderCache.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderCache.h @@ -24,9 +24,7 @@ template class ShaderCache : angle::NonCopyable { public: - ShaderCache() : mDevice(NULL) - { - } + ShaderCache() : mDevice(nullptr) {} ~ShaderCache() { @@ -47,14 +45,14 @@ class ShaderCache : angle::NonCopyable { it->second->AddRef(); *outShaderObject = it->second; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } ShaderObject *shader; HRESULT result = createShader(function, &shader); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create shader, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to create shader, " << gl::FmtHR(result); } // Random eviction policy. @@ -68,7 +66,7 @@ class ShaderCache : angle::NonCopyable mMap[key] = shader; *outShaderObject = shader; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } void clear() diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp index 28a486056b..362c6c60a3 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp @@ -18,14 +18,14 @@ ShaderExecutable9::ShaderExecutable9(const void *function, size_t length, IDirec : ShaderExecutableD3D(function, length) { mPixelExecutable = executable; - mVertexExecutable = NULL; + mVertexExecutable = nullptr; } ShaderExecutable9::ShaderExecutable9(const void *function, size_t length, IDirect3DVertexShader9 *executable) : ShaderExecutableD3D(function, length) { mVertexExecutable = executable; - mPixelExecutable = NULL; + mPixelExecutable = nullptr; } ShaderExecutable9::~ShaderExecutable9() @@ -44,4 +44,4 @@ IDirect3DPixelShader9 *ShaderExecutable9::getPixelShader() const return mPixelExecutable; } -} \ No newline at end of file +} diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h index 382a68c820..0b6b87947e 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h @@ -20,7 +20,7 @@ class ShaderExecutable9 : public ShaderExecutableD3D public: ShaderExecutable9(const void *function, size_t length, IDirect3DPixelShader9 *executable); ShaderExecutable9(const void *function, size_t length, IDirect3DVertexShader9 *executable); - virtual ~ShaderExecutable9(); + ~ShaderExecutable9() override; IDirect3DPixelShader9 *getPixelShader() const; IDirect3DVertexShader9 *getVertexShader() const; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp index c4c600aedb..a3bdc14efb 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp @@ -7,7 +7,7 @@ // StateManager9.cpp: Defines a class for caching D3D9 state #include "libANGLE/renderer/d3d/d3d9/StateManager9.h" -#include "common/BitSetIterator.h" +#include "common/bitset_utils.h" #include "common/utilities.h" #include "libANGLE/formatutils.h" #include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" @@ -18,7 +18,8 @@ namespace rx { StateManager9::StateManager9(Renderer9 *renderer9) - : mCurBlendState(), + : mUsingZeroColorMaskWorkaround(false), + mCurBlendState(), mCurBlendColor(0, 0, 0, 0), mCurSampleMask(0), mCurRasterState(), @@ -67,6 +68,11 @@ StateManager9::~StateManager9() { } +void StateManager9::initialize() +{ + mUsingZeroColorMaskWorkaround = IsAMD(mRenderer9->getVendorId()); +} + void StateManager9::forceSetBlendState() { mDirtyBits |= mBlendStateDirtyBits; @@ -114,7 +120,7 @@ void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits return; } - for (auto dirtyBit : angle::IterateBitSet(dirtyBits)) + for (auto dirtyBit : dirtyBits) { switch (dirtyBit) { @@ -125,6 +131,12 @@ void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits // BlendColor and funcs and equations has to be set if blend is enabled mDirtyBits.set(DIRTY_BIT_BLEND_COLOR); mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS); + + // The color mask may have to be updated if the blend state changes + if (mUsingZeroColorMaskWorkaround) + { + mDirtyBits.set(DIRTY_BIT_COLOR_MASK); + } } break; case gl::State::DIRTY_BIT_BLEND_FUNCS: @@ -138,6 +150,12 @@ void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS); // BlendColor depends on the values of blend funcs mDirtyBits.set(DIRTY_BIT_BLEND_COLOR); + + // The color mask may have to be updated if the blend funcs change + if (mUsingZeroColorMaskWorkaround) + { + mDirtyBits.set(DIRTY_BIT_COLOR_MASK); + } } break; } @@ -148,6 +166,12 @@ void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits blendState.blendEquationAlpha != mCurBlendState.blendEquationAlpha) { mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS); + + // The color mask may have to be updated if the blend funcs change + if (mUsingZeroColorMaskWorkaround) + { + mDirtyBits.set(DIRTY_BIT_COLOR_MASK); + } } break; } @@ -167,6 +191,14 @@ void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits blendState.colorMaskAlpha != mCurBlendState.colorMaskAlpha) { mDirtyBits.set(DIRTY_BIT_COLOR_MASK); + + // The color mask can cause the blend state to get out of sync when using the + // zero color mask workaround + if (mUsingZeroColorMaskWorkaround) + { + mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED); + mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS); + } } break; } @@ -364,7 +396,7 @@ gl::Error StateManager9::setBlendDepthRasterStates(const gl::State &glState, mCurFrontFaceCCW = frontFaceCCW; } - for (auto dirtyBit : angle::IterateBitSet(mDirtyBits)) + for (auto dirtyBit : mDirtyBits) { switch (dirtyBit) { @@ -438,11 +470,10 @@ gl::Error StateManager9::setBlendDepthRasterStates(const gl::State &glState, setSampleMask(sampleMask); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -void StateManager9::setViewportState(const gl::Caps *caps, - const gl::Rectangle &viewport, +void StateManager9::setViewportState(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, @@ -698,6 +729,7 @@ void StateManager9::setStencilTestEnabled(bool stencilTestEnabled) if (stencilTestEnabled && mCurStencilSize > 0) { mRenderer9->getDevice()->SetRenderState(D3DRS_STENCILENABLE, TRUE); + mRenderer9->getDevice()->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE); } else { @@ -718,7 +750,7 @@ void StateManager9::setSampleAlphaToCoverage(bool enabled) { if (enabled) { - FIXME("Sample alpha to coverage is unimplemented."); + UNREACHABLE(); } } @@ -800,42 +832,52 @@ void StateManager9::setColorMask(const gl::Framebuffer *framebuffer, bool alpha) { // Set the color mask - bool zeroColorMaskAllowed = mRenderer9->getVendorId() != VENDOR_ID_AMD; - // Apparently some ATI cards have a bug where a draw with a zero color - // write mask can cause later draws to have incorrect results. Instead, - // set a nonzero color write mask but modify the blend state so that no - // drawing is done. - // http://code.google.com/p/angleproject/issues/detail?id=169 - const gl::FramebufferAttachment *attachment = framebuffer->getFirstColorbuffer(); - GLenum internalFormat = attachment ? attachment->getInternalFormat() : GL_NONE; - - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); + const auto *attachment = framebuffer->getFirstColorbuffer(); + const auto &format = attachment ? attachment->getFormat() : gl::Format::Invalid(); DWORD colorMask = gl_d3d9::ConvertColorMask( - formatInfo.redBits > 0 && red, formatInfo.greenBits > 0 && green, - formatInfo.blueBits > 0 && blue, formatInfo.alphaBits > 0 && alpha); + format.info->redBits > 0 && red, format.info->greenBits > 0 && green, + format.info->blueBits > 0 && blue, format.info->alphaBits > 0 && alpha); - if (colorMask == 0 && !zeroColorMaskAllowed) + // Apparently some ATI cards have a bug where a draw with a zero color write mask can cause + // later draws to have incorrect results. Instead, set a nonzero color write mask but modify the + // blend state so that no drawing is done. + // http://anglebug.com/169 + if (colorMask == 0 && mUsingZeroColorMaskWorkaround) { IDirect3DDevice9 *device = mRenderer9->getDevice(); // Enable green channel, but set blending so nothing will be drawn. device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_GREEN); + device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); + + mCurBlendState.colorMaskRed = false; + mCurBlendState.colorMaskGreen = true; + mCurBlendState.colorMaskBlue = false; + mCurBlendState.colorMaskAlpha = false; + + mCurBlendState.blend = true; + mCurBlendState.sourceBlendRGB = GL_ZERO; + mCurBlendState.sourceBlendAlpha = GL_ZERO; + mCurBlendState.destBlendRGB = GL_ONE; + mCurBlendState.destBlendAlpha = GL_ONE; + mCurBlendState.blendEquationRGB = GL_FUNC_ADD; + mCurBlendState.blendEquationAlpha = GL_FUNC_ADD; } else { mRenderer9->getDevice()->SetRenderState(D3DRS_COLORWRITEENABLE, colorMask); - } - mCurBlendState.colorMaskRed = red; - mCurBlendState.colorMaskGreen = green; - mCurBlendState.colorMaskBlue = blue; - mCurBlendState.colorMaskAlpha = alpha; + mCurBlendState.colorMaskRed = red; + mCurBlendState.colorMaskGreen = green; + mCurBlendState.colorMaskBlue = blue; + mCurBlendState.colorMaskAlpha = alpha; + } } void StateManager9::setSampleMask(unsigned int sampleMask) @@ -848,7 +890,7 @@ void StateManager9::setSampleMask(unsigned int sampleMask) mCurSampleMask = sampleMask; } -void StateManager9::setCullMode(bool cullFace, GLenum cullMode, GLenum frontFace) +void StateManager9::setCullMode(bool cullFace, gl::CullFaceMode cullMode, GLenum frontFace) { if (cullFace) { diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.h index d8c1eb9812..63ce17cb1e 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.h @@ -10,7 +10,7 @@ #define LIBANGLE_RENDERER_D3D9_STATEMANAGER9_H_ #include "libANGLE/angletypes.h" -#include "libANGLE/Data.h" +#include "libANGLE/ContextState.h" #include "libANGLE/State.h" #include "libANGLE/renderer/d3d/RendererD3D.h" @@ -39,12 +39,13 @@ class StateManager9 final : angle::NonCopyable StateManager9(Renderer9 *renderer9); ~StateManager9(); + void initialize(); + void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits); gl::Error setBlendDepthRasterStates(const gl::State &glState, unsigned int sampleMask); void setScissorState(const gl::Rectangle &scissor, bool enabled); - void setViewportState(const gl::Caps *caps, - const gl::Rectangle &viewport, + void setViewportState(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, @@ -85,7 +86,7 @@ class StateManager9 final : angle::NonCopyable void setSampleMask(unsigned int sampleMask); // Current raster state functions - void setCullMode(bool cullFace, GLenum cullMode, GLenum frontFace); + void setCullMode(bool cullFace, gl::CullFaceMode cullMode, GLenum frontFace); void setDepthBias(bool polygonOffsetFill, GLfloat polygonOffsetFactor, GLfloat polygonOffsetUnits); @@ -154,7 +155,9 @@ class StateManager9 final : angle::NonCopyable DIRTY_BIT_MAX }; - typedef std::bitset DirtyBits; + using DirtyBits = angle::BitSet; + + bool mUsingZeroColorMaskWorkaround; // Currently applied blend state gl::BlendState mCurBlendState; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp index be6a9c424c..bc81aa18ec 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp @@ -7,25 +7,29 @@ // SwapChain9.cpp: Implements a back-end specific class for the D3D9 swap chain. #include "libANGLE/renderer/d3d/d3d9/SwapChain9.h" -#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" -#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" -#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" + #include "libANGLE/features.h" +#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" +#include "libANGLE/renderer/d3d/d3d9/NativeWindow9.h" +#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" +#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" namespace rx { SwapChain9::SwapChain9(Renderer9 *renderer, - NativeWindow nativeWindow, + NativeWindow9 *nativeWindow, HANDLE shareHandle, + IUnknown *d3dTexture, GLenum backBufferFormat, GLenum depthBufferFormat, EGLint orientation) - : SwapChainD3D(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat), + : SwapChainD3D(shareHandle, d3dTexture, backBufferFormat, depthBufferFormat), mRenderer(renderer), mWidth(-1), mHeight(-1), mSwapInterval(-1), + mNativeWindow(nativeWindow), mSwapChain(nullptr), mBackBuffer(nullptr), mRenderTarget(nullptr), @@ -50,9 +54,9 @@ void SwapChain9::release() SafeRelease(mRenderTarget); SafeRelease(mOffscreenTexture); - if (mNativeWindow.getNativeWindow()) + if (mNativeWindow->getNativeWindow()) { - mShareHandle = NULL; + mShareHandle = nullptr; } } @@ -75,17 +79,20 @@ static DWORD convertInterval(EGLint interval) #endif } -EGLint SwapChain9::resize(int backbufferWidth, int backbufferHeight) +EGLint SwapChain9::resize(const gl::Context *context, int backbufferWidth, int backbufferHeight) { // D3D9 does not support resizing swap chains without recreating them - return reset(backbufferWidth, backbufferHeight, mSwapInterval); + return reset(context, backbufferWidth, backbufferHeight, mSwapInterval); } -EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval) +EGLint SwapChain9::reset(const gl::Context *context, + int backbufferWidth, + int backbufferHeight, + EGLint swapInterval) { IDirect3DDevice9 *device = mRenderer->getDevice(); - if (device == NULL) + if (device == nullptr) { return EGL_BAD_ACCESS; } @@ -103,28 +110,37 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI SafeRelease(mOffscreenTexture); SafeRelease(mDepthStencil); - HANDLE *pShareHandle = NULL; - if (!mNativeWindow.getNativeWindow() && mRenderer->getShareHandleSupport()) + const d3d9::TextureFormat &backBufferd3dFormatInfo = + d3d9::GetTextureFormatInfo(mOffscreenRenderTargetFormat); + if (mD3DTexture != nullptr) { - pShareHandle = &mShareHandle; + result = mD3DTexture->QueryInterface(&mOffscreenTexture); + ASSERT(SUCCEEDED(result)); } - - const d3d9::TextureFormat &backBufferd3dFormatInfo = d3d9::GetTextureFormatInfo(mOffscreenRenderTargetFormat); - result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET, - backBufferd3dFormatInfo.texFormat, D3DPOOL_DEFAULT, &mOffscreenTexture, - pShareHandle); - if (FAILED(result)) + else { - ERR("Could not create offscreen texture: %08lX", result); - release(); - - if (d3d9::isDeviceLostError(result)) + HANDLE *pShareHandle = nullptr; + if (!mNativeWindow->getNativeWindow() && mRenderer->getShareHandleSupport()) { - return EGL_CONTEXT_LOST; + pShareHandle = &mShareHandle; } - else + + result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET, + backBufferd3dFormatInfo.texFormat, D3DPOOL_DEFAULT, + &mOffscreenTexture, pShareHandle); + if (FAILED(result)) { - return EGL_BAD_ALLOC; + ERR() << "Could not create offscreen texture, " << gl::FmtHR(result); + release(); + + if (d3d9::isDeviceLostError(result)) + { + return EGL_CONTEXT_LOST; + } + else + { + return EGL_BAD_ALLOC; + } } } @@ -163,7 +179,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI // Don't create a swapchain for NULLREF devices D3DDEVTYPE deviceType = mRenderer->getD3D9DeviceType(); - EGLNativeWindowType window = mNativeWindow.getNativeWindow(); + EGLNativeWindowType window = mNativeWindow->getNativeWindow(); if (window && deviceType != D3DDEVTYPE_NULLREF) { D3DPRESENT_PARAMETERS presentParameters = {0}; @@ -189,7 +205,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI // // Some non-switchable AMD GPUs / drivers do not respect the source rectangle to Present. Therefore, when the vendor ID // is not Intel, the back buffer width must be exactly the same width as the window or horizontal scaling will occur. - if (mRenderer->getVendorId() == VENDOR_ID_INTEL) + if (IsIntel(mRenderer->getVendorId())) { presentParameters.BackBufferWidth = (presentParameters.BackBufferWidth + 63) / 64 * 64; } @@ -200,7 +216,8 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL || result == D3DERR_DEVICELOST); - ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result); + ERR() << "Could not create additional swap chains or offscreen surfaces, " + << gl::FmtHR(result); release(); if (d3d9::isDeviceLostError(result)) @@ -215,20 +232,21 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer); ASSERT(SUCCEEDED(result)); - InvalidateRect(window, NULL, FALSE); + InvalidateRect(window, nullptr, FALSE); } if (mDepthBufferFormat != GL_NONE) { - result = device->CreateDepthStencilSurface(backbufferWidth, backbufferHeight, - depthBufferd3dFormatInfo.renderFormat, - D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, NULL); + result = device->CreateDepthStencilSurface( + backbufferWidth, backbufferHeight, depthBufferd3dFormatInfo.renderFormat, + D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, nullptr); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL); - ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result); + ERR() << "Could not create depthstencil surface for new swap chain, " + << gl::FmtHR(result); release(); if (d3d9::isDeviceLostError(result)) @@ -250,7 +268,11 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI } // parameters should be validated/clamped by caller -EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) +EGLint SwapChain9::swapRect(const gl::Context *context, + EGLint x, + EGLint y, + EGLint width, + EGLint height) { if (!mSwapChain) { @@ -270,11 +292,11 @@ EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED); device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE); device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); - device->SetPixelShader(NULL); - device->SetVertexShader(NULL); + device->SetPixelShader(nullptr); + device->SetVertexShader(nullptr); device->SetRenderTarget(0, mBackBuffer); - device->SetDepthStencilSurface(NULL); + device->SetDepthStencilSurface(nullptr); device->SetTexture(0, mOffscreenTexture); device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); @@ -313,7 +335,7 @@ EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float)); mRenderer->endScene(); - device->SetTexture(0, NULL); + device->SetTexture(0, nullptr); RECT rect = { @@ -321,7 +343,7 @@ EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) static_cast(x + width), static_cast(mHeight - y) }; - HRESULT result = mSwapChain->Present(&rect, &rect, NULL, NULL, 0); + HRESULT result = mSwapChain->Present(&rect, &rect, nullptr, nullptr, 0); mRenderer->markAllStateDirty(); @@ -333,7 +355,7 @@ EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) // On Windows 8 systems, IDirect3DSwapChain9::Present sometimes returns 0x88760873 when the windows is // in the process of entering/exiting fullscreen. This code doesn't seem to have any documentation. The // device appears to be ok after emitting this error so simply return a failure to swap. - if (result == 0x88760873) + if (result == static_cast(0x88760873)) { return EGL_BAD_MATCH; } @@ -395,6 +417,12 @@ void *SwapChain9::getKeyedMutex() return nullptr; } +egl::Error SwapChain9::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) +{ + UNREACHABLE(); + return egl::EglBadSurface(); +} + void SwapChain9::recreate() { if (!mSwapChain) @@ -403,7 +431,7 @@ void SwapChain9::recreate() } IDirect3DDevice9 *device = mRenderer->getDevice(); - if (device == NULL) + if (device == nullptr) { return; } @@ -412,7 +440,7 @@ void SwapChain9::recreate() HRESULT result = mSwapChain->GetPresentParameters(&presentParameters); ASSERT(SUCCEEDED(result)); - IDirect3DSwapChain9* newSwapChain = NULL; + IDirect3DSwapChain9 *newSwapChain = nullptr; result = device->CreateAdditionalSwapChain(&presentParameters, &newSwapChain); if (FAILED(result)) { @@ -427,4 +455,13 @@ void SwapChain9::recreate() ASSERT(SUCCEEDED(result)); } +RenderTargetD3D *SwapChain9::getColorRenderTarget() +{ + return &mColorRenderTarget; +} + +RenderTargetD3D *SwapChain9::getDepthStencilRenderTarget() +{ + return &mDepthStencilRenderTarget; +} } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h index 55a700c2d6..5753637c47 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h @@ -15,26 +15,36 @@ namespace rx { +class NativeWindow9; class Renderer9; class SwapChain9 : public SwapChainD3D { public: SwapChain9(Renderer9 *renderer, - NativeWindow nativeWindow, + NativeWindow9 *nativeWindow, HANDLE shareHandle, + IUnknown *d3dTexture, GLenum backBufferFormat, GLenum depthBufferFormat, EGLint orientation); - virtual ~SwapChain9(); + ~SwapChain9() override; - EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight); - virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval); - virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height); - virtual void recreate(); + EGLint resize(const gl::Context *context, EGLint backbufferWidth, EGLint backbufferHeight) + override; + EGLint reset(const gl::Context *context, + EGLint backbufferWidth, + EGLint backbufferHeight, + EGLint swapInterval) override; + EGLint swapRect(const gl::Context *context, + EGLint x, + EGLint y, + EGLint width, + EGLint height) override; + void recreate() override; - RenderTargetD3D *getColorRenderTarget() override { return &mColorRenderTarget; } - RenderTargetD3D *getDepthStencilRenderTarget() override { return &mDepthStencilRenderTarget; } + RenderTargetD3D *getColorRenderTarget() override; + RenderTargetD3D *getDepthStencilRenderTarget() override; virtual IDirect3DSurface9 *getRenderTarget(); virtual IDirect3DSurface9 *getDepthStencil(); @@ -45,6 +55,8 @@ class SwapChain9 : public SwapChainD3D void *getKeyedMutex() override; + egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override; + private: void release(); @@ -53,6 +65,8 @@ class SwapChain9 : public SwapChainD3D EGLint mHeight; EGLint mSwapInterval; + NativeWindow9 *mNativeWindow; + IDirect3DSwapChain9 *mSwapChain; IDirect3DSurface9 *mBackBuffer; IDirect3DSurface9 *mRenderTarget; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp index b28d5076b5..6404af6bba 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp @@ -43,7 +43,7 @@ DWORD TextureStorage9::GetTextureUsage(GLenum internalformat, bool renderTarget) { DWORD d3dusage = 0; - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat); + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat); const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat); if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) { @@ -93,11 +93,16 @@ int TextureStorage9::getLevelCount() const return static_cast(mMipLevels) - mTopLevel; } -gl::Error TextureStorage9::setData(const gl::ImageIndex &index, ImageD3D *image, const gl::Box *destBox, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixelData) +gl::Error TextureStorage9::setData(const gl::Context *context, + const gl::ImageIndex &index, + ImageD3D *image, + const gl::Box *destBox, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixelData) { UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + return gl::InternalError(); } TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, SwapChain9 *swapchain) @@ -107,7 +112,7 @@ TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, SwapChain9 *swapchai mTexture = surfaceTexture; mMipLevels = surfaceTexture->GetLevelCount(); - mInternalFormat = swapchain->GetRenderTargetInternalFormat(); + mInternalFormat = swapchain->getRenderTargetInternalFormat(); D3DSURFACE_DESC surfaceDesc; surfaceTexture->GetLevelDesc(0, &surfaceDesc); @@ -121,7 +126,7 @@ TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, SwapChain9 *swapchai TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) : TextureStorage9(renderer, GetTextureUsage(internalformat, renderTarget)) { - mTexture = NULL; + mTexture = nullptr; mInternalFormat = internalformat; @@ -139,7 +144,7 @@ TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, GLenum internalforma TextureStorage9_2D::~TextureStorage9_2D() { SafeRelease(mTexture); - for (auto &renderTarget : mRenderTargets) + for (RenderTargetD3D *renderTarget : mRenderTargets) { SafeDelete(renderTarget); } @@ -147,16 +152,16 @@ TextureStorage9_2D::~TextureStorage9_2D() // Increments refcount on surface. // caller must Release() the returned surface -gl::Error TextureStorage9_2D::getSurfaceLevel(GLenum target, +gl::Error TextureStorage9_2D::getSurfaceLevel(const gl::Context *context, + GLenum target, int level, bool dirty, IDirect3DSurface9 **outSurface) { ASSERT(target == GL_TEXTURE_2D); - UNUSED_ASSERTION_VARIABLE(target); - IDirect3DBaseTexture9 *baseTexture = NULL; - gl::Error error = getBaseTexture(&baseTexture); + IDirect3DBaseTexture9 *baseTexture = nullptr; + gl::Error error = getBaseTexture(context, &baseTexture); if (error.isError()) { return error; @@ -169,33 +174,36 @@ gl::Error TextureStorage9_2D::getSurfaceLevel(GLenum target, ASSERT(SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to get the surface from a texture, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to get the surface from a texture, " + << gl::FmtHR(result); } // With managed textures the driver needs to be informed of updates to the lower mipmap levels if (level + mTopLevel != 0 && isManaged() && dirty) { - texture->AddDirtyRect(NULL); + texture->AddDirtyRect(nullptr); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage9_2D::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) +gl::Error TextureStorage9_2D::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) { ASSERT(index.mipIndex < getLevelCount()); if (!mRenderTargets[index.mipIndex] && isRenderTarget()) { - IDirect3DBaseTexture9 *baseTexture = NULL; - gl::Error error = getBaseTexture(&baseTexture); + IDirect3DBaseTexture9 *baseTexture = nullptr; + gl::Error error = getBaseTexture(context, &baseTexture); if (error.isError()) { return error; } - IDirect3DSurface9 *surface = NULL; - error = getSurfaceLevel(GL_TEXTURE_2D, index.mipIndex, false, &surface); + IDirect3DSurface9 *surface = nullptr; + error = getSurfaceLevel(context, GL_TEXTURE_2D, index.mipIndex, false, &surface); if (error.isError()) { return error; @@ -213,20 +221,22 @@ gl::Error TextureStorage9_2D::getRenderTarget(const gl::ImageIndex &index, Rende ASSERT(outRT); *outRT = mRenderTargets[index.mipIndex]; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage9_2D::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) +gl::Error TextureStorage9_2D::generateMipmap(const gl::Context *context, + const gl::ImageIndex &sourceIndex, + const gl::ImageIndex &destIndex) { - IDirect3DSurface9 *upper = NULL; - gl::Error error = getSurfaceLevel(GL_TEXTURE_2D, sourceIndex.mipIndex, false, &upper); + IDirect3DSurface9 *upper = nullptr; + gl::Error error = getSurfaceLevel(context, GL_TEXTURE_2D, sourceIndex.mipIndex, false, &upper); if (error.isError()) { return error; } - IDirect3DSurface9 *lower = NULL; - error = getSurfaceLevel(GL_TEXTURE_2D, destIndex.mipIndex, true, &lower); + IDirect3DSurface9 *lower = nullptr; + error = getSurfaceLevel(context, GL_TEXTURE_2D, destIndex.mipIndex, true, &lower); if (error.isError()) { SafeRelease(upper); @@ -242,32 +252,34 @@ gl::Error TextureStorage9_2D::generateMipmap(const gl::ImageIndex &sourceIndex, return error; } -gl::Error TextureStorage9_2D::getBaseTexture(IDirect3DBaseTexture9 **outTexture) +gl::Error TextureStorage9_2D::getBaseTexture(const gl::Context *context, + IDirect3DBaseTexture9 **outTexture) { // if the width or height is not positive this should be treated as an incomplete texture // we handle that here by skipping the d3d texture creation - if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0) + if (mTexture == nullptr && mTextureWidth > 0 && mTextureHeight > 0) { ASSERT(mMipLevels > 0); IDirect3DDevice9 *device = mRenderer->getDevice(); - HRESULT result = device->CreateTexture(static_cast(mTextureWidth), + HRESULT result = device->CreateTexture(static_cast(mTextureWidth), static_cast(mTextureHeight), static_cast(mMipLevels), getUsage(), - mTextureFormat, getPool(), &mTexture, NULL); + mTextureFormat, getPool(), &mTexture, nullptr); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D storage texture, result: 0x%X.", result); + return gl::OutOfMemory() + << "Failed to create 2D storage texture, " << gl::FmtHR(result); } } *outTexture = mTexture; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage9_2D::copyToStorage(TextureStorage *destStorage) +gl::Error TextureStorage9_2D::copyToStorage(const gl::Context *context, TextureStorage *destStorage) { ASSERT(destStorage); @@ -276,15 +288,15 @@ gl::Error TextureStorage9_2D::copyToStorage(TextureStorage *destStorage) int levels = getLevelCount(); for (int i = 0; i < levels; ++i) { - IDirect3DSurface9 *srcSurf = NULL; - gl::Error error = getSurfaceLevel(GL_TEXTURE_2D, i, false, &srcSurf); + IDirect3DSurface9 *srcSurf = nullptr; + gl::Error error = getSurfaceLevel(context, GL_TEXTURE_2D, i, false, &srcSurf); if (error.isError()) { return error; } - IDirect3DSurface9 *dstSurf = NULL; - error = dest9->getSurfaceLevel(GL_TEXTURE_2D, i, true, &dstSurf); + IDirect3DSurface9 *dstSurf = nullptr; + error = dest9->getSurfaceLevel(context, GL_TEXTURE_2D, i, true, &dstSurf); if (error.isError()) { SafeRelease(srcSurf); @@ -302,17 +314,14 @@ gl::Error TextureStorage9_2D::copyToStorage(TextureStorage *destStorage) } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -TextureStorage9_EGLImage::TextureStorage9_EGLImage(Renderer9 *renderer, EGLImageD3D *image) +TextureStorage9_EGLImage::TextureStorage9_EGLImage(Renderer9 *renderer, + EGLImageD3D *image, + RenderTarget9 *renderTarget9) : TextureStorage9(renderer, D3DUSAGE_RENDERTARGET), mImage(image) { - RenderTargetD3D *renderTargetD3D = nullptr; - mImage->getRenderTarget(&renderTargetD3D); - - RenderTarget9 *renderTarget9 = GetAs(renderTargetD3D); - mInternalFormat = renderTarget9->getInternalFormat(); mTextureFormat = renderTarget9->getD3DFormat(); mTextureWidth = renderTarget9->getWidth(); @@ -325,18 +334,17 @@ TextureStorage9_EGLImage::~TextureStorage9_EGLImage() { } -gl::Error TextureStorage9_EGLImage::getSurfaceLevel(GLenum target, +gl::Error TextureStorage9_EGLImage::getSurfaceLevel(const gl::Context *context, + GLenum target, int level, bool, IDirect3DSurface9 **outSurface) { ASSERT(target == GL_TEXTURE_2D); ASSERT(level == 0); - UNUSED_ASSERTION_VARIABLE(target); - UNUSED_ASSERTION_VARIABLE(level); RenderTargetD3D *renderTargetD3D = nullptr; - gl::Error error = mImage->getRenderTarget(&renderTargetD3D); + gl::Error error = mImage->getRenderTarget(context, &renderTargetD3D); if (error.isError()) { return error; @@ -345,23 +353,24 @@ gl::Error TextureStorage9_EGLImage::getSurfaceLevel(GLenum target, RenderTarget9 *renderTarget9 = GetAs(renderTargetD3D); *outSurface = renderTarget9->getSurface(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage9_EGLImage::getRenderTarget(const gl::ImageIndex &index, +gl::Error TextureStorage9_EGLImage::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, RenderTargetD3D **outRT) { ASSERT(!index.hasLayer()); ASSERT(index.mipIndex == 0); - UNUSED_ASSERTION_VARIABLE(index); - return mImage->getRenderTarget(outRT); + return mImage->getRenderTarget(context, outRT); } -gl::Error TextureStorage9_EGLImage::getBaseTexture(IDirect3DBaseTexture9 **outTexture) +gl::Error TextureStorage9_EGLImage::getBaseTexture(const gl::Context *context, + IDirect3DBaseTexture9 **outTexture) { RenderTargetD3D *renderTargetD3D = nullptr; - gl::Error error = mImage->getRenderTarget(&renderTargetD3D); + gl::Error error = mImage->getRenderTarget(context, &renderTargetD3D); if (error.isError()) { return error; @@ -371,16 +380,19 @@ gl::Error TextureStorage9_EGLImage::getBaseTexture(IDirect3DBaseTexture9 **outTe *outTexture = renderTarget9->getTexture(); ASSERT(*outTexture != nullptr); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage9_EGLImage::generateMipmap(const gl::ImageIndex &, const gl::ImageIndex &) +gl::Error TextureStorage9_EGLImage::generateMipmap(const gl::Context *context, + const gl::ImageIndex &, + const gl::ImageIndex &) { UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + return gl::InternalError(); } -gl::Error TextureStorage9_EGLImage::copyToStorage(TextureStorage *destStorage) +gl::Error TextureStorage9_EGLImage::copyToStorage(const gl::Context *context, + TextureStorage *destStorage) { ASSERT(destStorage); ASSERT(getLevelCount() == 1); @@ -388,7 +400,7 @@ gl::Error TextureStorage9_EGLImage::copyToStorage(TextureStorage *destStorage) TextureStorage9 *dest9 = GetAs(destStorage); IDirect3DBaseTexture9 *destBaseTexture9 = nullptr; - gl::Error error = dest9->getBaseTexture(&destBaseTexture9); + gl::Error error = dest9->getBaseTexture(context, &destBaseTexture9); if (error.isError()) { return error; @@ -400,12 +412,12 @@ gl::Error TextureStorage9_EGLImage::copyToStorage(TextureStorage *destStorage) HRESULT result = destTexture9->GetSurfaceLevel(destStorage->getTopLevel(), &destSurface); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, - "Failed to get the surface from a texture, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to get the surface from a texture, " + << gl::FmtHR(result); } RenderTargetD3D *sourceRenderTarget = nullptr; - error = mImage->getRenderTarget(&sourceRenderTarget); + error = mImage->getRenderTarget(context, &sourceRenderTarget); if (error.isError()) { SafeRelease(destSurface); @@ -427,16 +439,16 @@ gl::Error TextureStorage9_EGLImage::copyToStorage(TextureStorage *destStorage) } SafeRelease(destSurface); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } TextureStorage9_Cube::TextureStorage9_Cube(Renderer9 *renderer, GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly) : TextureStorage9(renderer, GetTextureUsage(internalformat, renderTarget)) { - mTexture = NULL; - for (int i = 0; i < CUBE_FACE_COUNT; ++i) + mTexture = nullptr; + for (size_t i = 0; i < gl::CUBE_FACE_COUNT; ++i) { - mRenderTarget[i] = NULL; + mRenderTarget[i] = nullptr; } mInternalFormat = internalformat; @@ -455,7 +467,7 @@ TextureStorage9_Cube::~TextureStorage9_Cube() { SafeRelease(mTexture); - for (int i = 0; i < CUBE_FACE_COUNT; ++i) + for (size_t i = 0; i < gl::CUBE_FACE_COUNT; ++i) { SafeDelete(mRenderTarget[i]); } @@ -463,13 +475,14 @@ TextureStorage9_Cube::~TextureStorage9_Cube() // Increments refcount on surface. // caller must Release() the returned surface -gl::Error TextureStorage9_Cube::getSurfaceLevel(GLenum target, +gl::Error TextureStorage9_Cube::getSurfaceLevel(const gl::Context *context, + GLenum target, int level, bool dirty, IDirect3DSurface9 **outSurface) { - IDirect3DBaseTexture9 *baseTexture = NULL; - gl::Error error = getBaseTexture(&baseTexture); + IDirect3DBaseTexture9 *baseTexture = nullptr; + gl::Error error = getBaseTexture(context, &baseTexture); if (error.isError()) { return error; @@ -483,35 +496,38 @@ gl::Error TextureStorage9_Cube::getSurfaceLevel(GLenum target, ASSERT(SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to get the surface from a texture, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to get the surface from a texture, " + << gl::FmtHR(result); } // With managed textures the driver needs to be informed of updates to the lower mipmap levels if (level != 0 && isManaged() && dirty) { - texture->AddDirtyRect(face, NULL); + texture->AddDirtyRect(face, nullptr); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) +gl::Error TextureStorage9_Cube::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) { ASSERT(outRT); ASSERT(index.mipIndex == 0); - ASSERT(index.layerIndex >= 0 && index.layerIndex < CUBE_FACE_COUNT); + ASSERT(index.layerIndex >= 0 && static_cast(index.layerIndex) < gl::CUBE_FACE_COUNT); - if (mRenderTarget[index.layerIndex] == NULL && isRenderTarget()) + if (mRenderTarget[index.layerIndex] == nullptr && isRenderTarget()) { - IDirect3DBaseTexture9 *baseTexture = NULL; - gl::Error error = getBaseTexture(&baseTexture); + IDirect3DBaseTexture9 *baseTexture = nullptr; + gl::Error error = getBaseTexture(context, &baseTexture); if (error.isError()) { return error; } - IDirect3DSurface9 *surface = NULL; - error = getSurfaceLevel(GL_TEXTURE_CUBE_MAP_POSITIVE_X + index.layerIndex, + IDirect3DSurface9 *surface = nullptr; + error = getSurfaceLevel(context, GL_TEXTURE_CUBE_MAP_POSITIVE_X + index.layerIndex, mTopLevel + index.mipIndex, false, &surface); if (error.isError()) { @@ -525,20 +541,23 @@ gl::Error TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index, Ren } *outRT = mRenderTarget[index.layerIndex]; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage9_Cube::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) +gl::Error TextureStorage9_Cube::generateMipmap(const gl::Context *context, + const gl::ImageIndex &sourceIndex, + const gl::ImageIndex &destIndex) { - IDirect3DSurface9 *upper = NULL; - gl::Error error = getSurfaceLevel(sourceIndex.type, sourceIndex.mipIndex, false, &upper); + IDirect3DSurface9 *upper = nullptr; + gl::Error error = + getSurfaceLevel(context, sourceIndex.type, sourceIndex.mipIndex, false, &upper); if (error.isError()) { return error; } - IDirect3DSurface9 *lower = NULL; - error = getSurfaceLevel(destIndex.type, destIndex.mipIndex, true, &lower); + IDirect3DSurface9 *lower = nullptr; + error = getSurfaceLevel(context, destIndex.type, destIndex.mipIndex, true, &lower); if (error.isError()) { SafeRelease(upper); @@ -554,52 +573,56 @@ gl::Error TextureStorage9_Cube::generateMipmap(const gl::ImageIndex &sourceIndex return error; } -gl::Error TextureStorage9_Cube::getBaseTexture(IDirect3DBaseTexture9 **outTexture) +gl::Error TextureStorage9_Cube::getBaseTexture(const gl::Context *context, + IDirect3DBaseTexture9 **outTexture) { // if the size is not positive this should be treated as an incomplete texture // we handle that here by skipping the d3d texture creation - if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0) + if (mTexture == nullptr && mTextureWidth > 0 && mTextureHeight > 0) { ASSERT(mMipLevels > 0); ASSERT(mTextureWidth == mTextureHeight); IDirect3DDevice9 *device = mRenderer->getDevice(); - HRESULT result = device->CreateCubeTexture( + HRESULT result = device->CreateCubeTexture( static_cast(mTextureWidth), static_cast(mMipLevels), - getUsage(), mTextureFormat, getPool(), &mTexture, NULL); + getUsage(), mTextureFormat, getPool(), &mTexture, nullptr); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create cube storage texture, result: 0x%X.", result); + return gl::OutOfMemory() + << "Failed to create cube storage texture, " << gl::FmtHR(result); } } *outTexture = mTexture; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage9_Cube::copyToStorage(TextureStorage *destStorage) +gl::Error TextureStorage9_Cube::copyToStorage(const gl::Context *context, + TextureStorage *destStorage) { ASSERT(destStorage); TextureStorage9_Cube *dest9 = GetAs(destStorage); int levels = getLevelCount(); - for (int f = 0; f < CUBE_FACE_COUNT; f++) + for (int f = 0; f < static_cast(gl::CUBE_FACE_COUNT); f++) { for (int i = 0; i < levels; i++) { - IDirect3DSurface9 *srcSurf = NULL; + IDirect3DSurface9 *srcSurf = nullptr; gl::Error error = - getSurfaceLevel(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false, &srcSurf); + getSurfaceLevel(context, GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false, &srcSurf); if (error.isError()) { return error; } - IDirect3DSurface9 *dstSurf = NULL; - error = dest9->getSurfaceLevel(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true, &dstSurf); + IDirect3DSurface9 *dstSurf = nullptr; + error = dest9->getSurfaceLevel(context, GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true, + &dstSurf); if (error.isError()) { SafeRelease(srcSurf); @@ -618,7 +641,7 @@ gl::Error TextureStorage9_Cube::copyToStorage(TextureStorage *destStorage) } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h index 50e63a6f14..2f51901931 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h @@ -25,28 +25,34 @@ class RenderTarget9; class TextureStorage9 : public TextureStorage { public: - virtual ~TextureStorage9(); + ~TextureStorage9() override; static DWORD GetTextureUsage(GLenum internalformat, bool renderTarget); D3DPOOL getPool() const; DWORD getUsage() const; - virtual gl::Error getSurfaceLevel(GLenum target, + virtual gl::Error getSurfaceLevel(const gl::Context *context, + GLenum target, int level, bool dirty, IDirect3DSurface9 **outSurface) = 0; - virtual gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture) = 0; - virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) = 0; + virtual gl::Error getBaseTexture(const gl::Context *context, + IDirect3DBaseTexture9 **outTexture) = 0; - virtual int getTopLevel() const; - virtual bool isRenderTarget() const; - virtual bool isManaged() const; + int getTopLevel() const override; + bool isRenderTarget() const override; + bool isManaged() const override; bool supportsNativeMipmapFunction() const override; - virtual int getLevelCount() const; + int getLevelCount() const override; - virtual gl::Error setData(const gl::ImageIndex &index, ImageD3D *image, const gl::Box *destBox, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixelData); + gl::Error setData(const gl::Context *context, + const gl::ImageIndex &index, + ImageD3D *image, + const gl::Box *destBox, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixelData) override; protected: int mTopLevel; @@ -70,16 +76,22 @@ class TextureStorage9_2D : public TextureStorage9 public: TextureStorage9_2D(Renderer9 *renderer, SwapChain9 *swapchain); TextureStorage9_2D(Renderer9 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels); - virtual ~TextureStorage9_2D(); + ~TextureStorage9_2D() override; - gl::Error getSurfaceLevel(GLenum target, + gl::Error getSurfaceLevel(const gl::Context *context, + GLenum target, int level, bool dirty, IDirect3DSurface9 **outSurface) override; - virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT); - virtual gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture); - virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex); - virtual gl::Error copyToStorage(TextureStorage *destStorage); + gl::Error getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) override; + gl::Error getBaseTexture(const gl::Context *context, + IDirect3DBaseTexture9 **outTexture) override; + gl::Error generateMipmap(const gl::Context *context, + const gl::ImageIndex &sourceIndex, + const gl::ImageIndex &destIndex) override; + gl::Error copyToStorage(const gl::Context *context, TextureStorage *destStorage) override; private: IDirect3DTexture9 *mTexture; @@ -89,18 +101,23 @@ class TextureStorage9_2D : public TextureStorage9 class TextureStorage9_EGLImage final : public TextureStorage9 { public: - TextureStorage9_EGLImage(Renderer9 *renderer, EGLImageD3D *image); + TextureStorage9_EGLImage(Renderer9 *renderer, EGLImageD3D *image, RenderTarget9 *renderTarget9); ~TextureStorage9_EGLImage() override; - gl::Error getSurfaceLevel(GLenum target, + gl::Error getSurfaceLevel(const gl::Context *context, + GLenum target, int level, bool dirty, IDirect3DSurface9 **outSurface) override; - gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) override; - gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture) override; - gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, + gl::Error getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) override; + gl::Error getBaseTexture(const gl::Context *context, + IDirect3DBaseTexture9 **outTexture) override; + gl::Error generateMipmap(const gl::Context *context, + const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) override; - gl::Error copyToStorage(TextureStorage *destStorage) override; + gl::Error copyToStorage(const gl::Context *context, TextureStorage *destStorage) override; private: EGLImageD3D *mImage; @@ -110,25 +127,28 @@ class TextureStorage9_Cube : public TextureStorage9 { public: TextureStorage9_Cube(Renderer9 *renderer, GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly); - virtual ~TextureStorage9_Cube(); + ~TextureStorage9_Cube() override; - gl::Error getSurfaceLevel(GLenum target, + gl::Error getSurfaceLevel(const gl::Context *context, + GLenum target, int level, bool dirty, IDirect3DSurface9 **outSurface) override; - virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT); - virtual gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture); - virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex); - virtual gl::Error copyToStorage(TextureStorage *destStorage); + gl::Error getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) override; + gl::Error getBaseTexture(const gl::Context *context, + IDirect3DBaseTexture9 **outTexture) override; + gl::Error generateMipmap(const gl::Context *context, + const gl::ImageIndex &sourceIndex, + const gl::ImageIndex &destIndex) override; + gl::Error copyToStorage(const gl::Context *context, TextureStorage *destStorage) override; private: - static const size_t CUBE_FACE_COUNT = 6; - IDirect3DCubeTexture9 *mTexture; - RenderTarget9 *mRenderTarget[CUBE_FACE_COUNT]; + RenderTarget9 *mRenderTarget[gl::CUBE_FACE_COUNT]; }; } #endif // LIBANGLE_RENDERER_D3D_D3D9_TEXTURESTORAGE9_H_ - diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h index 992201737f..0f4410b8de 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h @@ -9,7 +9,9 @@ #ifndef LIBANGLE_RENDERER_D3D_D3D9_VERTEXARRAY9_H_ #define LIBANGLE_RENDERER_D3D_D3D9_VERTEXARRAY9_H_ +#include "libANGLE/Context.h" #include "libANGLE/renderer/VertexArrayImpl.h" +#include "libANGLE/renderer/d3d/d3d9/Context9.h" #include "libANGLE/renderer/d3d/d3d9/Renderer9.h" namespace rx @@ -19,14 +21,26 @@ class Renderer9; class VertexArray9 : public VertexArrayImpl { public: - VertexArray9(const gl::VertexArray::Data &data) - : VertexArrayImpl(data) - { - } + VertexArray9(const gl::VertexArrayState &data) : VertexArrayImpl(data) {} - virtual ~VertexArray9() { } + void syncState(const gl::Context *context, + const gl::VertexArray::DirtyBits &dirtyBits) override; + + ~VertexArray9() override {} + + Serial getCurrentStateSerial() const { return mCurrentStateSerial; } + + private: + Serial mCurrentStateSerial; }; +inline void VertexArray9::syncState(const gl::Context *context, + const gl::VertexArray::DirtyBits &dirtyBits) +{ + ASSERT(dirtyBits.any()); + Renderer9 *renderer = GetImplAs(context)->getRenderer(); + mCurrentStateSerial = renderer->generateSerial(); +} } #endif // LIBANGLE_RENDERER_D3D_D3D9_VERTEXARRAY9_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp index bfdf137126..c0b80a847c 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp @@ -19,7 +19,7 @@ namespace rx VertexBuffer9::VertexBuffer9(Renderer9 *renderer) : mRenderer(renderer) { - mVertexBuffer = NULL; + mVertexBuffer = nullptr; mBufferSize = 0; mDynamicUsage = false; } @@ -47,16 +47,18 @@ gl::Error VertexBuffer9::initialize(unsigned int size, bool dynamicUsage) if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal vertex buffer of size, %lu.", size); + return gl::OutOfMemory() + << "Failed to allocate internal vertex buffer of size " << size; } } mBufferSize = size; mDynamicUsage = dynamicUsage; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, GLenum currentValueType, GLint start, GLsizei count, @@ -66,32 +68,33 @@ gl::Error VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib { if (!mVertexBuffer) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized."); + return gl::OutOfMemory() << "Internal vertex buffer is not initialized."; } - int inputStride = static_cast(gl::ComputeVertexAttributeStride(attrib)); + int inputStride = static_cast(gl::ComputeVertexAttributeStride(attrib, binding)); int elementSize = static_cast(gl::ComputeVertexAttributeTypeSize(attrib)); DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0; - uint8_t *mapPtr = NULL; + uint8_t *mapPtr = nullptr; - unsigned int mapSize; - gl::Error error = spaceRequired(attrib, count, instances, &mapSize); - if (error.isError()) + auto errorOrMapSize = mRenderer->getVertexSpaceRequired(attrib, binding, count, instances); + if (errorOrMapSize.isError()) { - return error; + return errorOrMapSize.getError(); } + unsigned int mapSize = errorOrMapSize.getResult(); + HRESULT result = mVertexBuffer->Lock(offset, mapSize, reinterpret_cast(&mapPtr), lockFlags); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal vertex buffer, HRESULT: 0x%08x.", result); + return gl::OutOfMemory() << "Failed to lock internal vertex buffer, " << gl::FmtHR(result); } const uint8_t *input = sourceData; - if (instances == 0 || attrib.divisor == 0) + if (instances == 0 || binding.getDivisor() == 0) { input += inputStride * start; } @@ -112,13 +115,7 @@ gl::Error VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib mVertexBuffer->Unlock(); - return gl::Error(GL_NO_ERROR); -} - -gl::Error VertexBuffer9::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, - unsigned int *outSpaceRequired) const -{ - return spaceRequired(attrib, count, instances, outSpaceRequired); + return gl::NoError(); } unsigned int VertexBuffer9::getBufferSize() const @@ -134,7 +131,7 @@ gl::Error VertexBuffer9::setBufferSize(unsigned int size) } else { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } } @@ -142,7 +139,7 @@ gl::Error VertexBuffer9::discard() { if (!mVertexBuffer) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized."); + return gl::OutOfMemory() << "Internal vertex buffer is not initialized."; } void *dummy; @@ -151,65 +148,22 @@ gl::Error VertexBuffer9::discard() result = mVertexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal buffer for discarding, HRESULT: 0x%08x", result); + return gl::OutOfMemory() << "Failed to lock internal buffer for discarding, " + << gl::FmtHR(result); } result = mVertexBuffer->Unlock(); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to unlock internal buffer for discarding, HRESULT: 0x%08x", result); + return gl::OutOfMemory() << "Failed to unlock internal buffer for discarding, " + << gl::FmtHR(result); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } IDirect3DVertexBuffer9 * VertexBuffer9::getBuffer() const { return mVertexBuffer; } - -gl::Error VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances, - unsigned int *outSpaceRequired) const -{ - gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib, GL_FLOAT); - const d3d9::VertexFormat &d3d9VertexInfo = d3d9::GetVertexFormatInfo(mRenderer->getCapsDeclTypes(), vertexFormatType); - - if (attrib.enabled) - { - unsigned int elementCount = 0; - if (instances == 0 || attrib.divisor == 0) - { - elementCount = static_cast(count); - } - else - { - // Round up to divisor, if possible - elementCount = UnsignedCeilDivide(static_cast(instances), attrib.divisor); - } - - if (d3d9VertexInfo.outputElementSize <= std::numeric_limits::max() / elementCount) - { - if (outSpaceRequired) - { - *outSpaceRequired = - static_cast(d3d9VertexInfo.outputElementSize) * elementCount; - } - return gl::Error(GL_NO_ERROR); - } - else - { - return gl::Error(GL_OUT_OF_MEMORY, "New vertex buffer size would result in an overflow."); - } - } - else - { - const unsigned int elementSize = 4; - if (outSpaceRequired) - { - *outSpaceRequired = elementSize * 4; - } - return gl::Error(GL_NO_ERROR); - } -} - -} +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h index 64271cbe2a..983616f4e4 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h @@ -19,11 +19,13 @@ class VertexBuffer9 : public VertexBuffer { public: explicit VertexBuffer9(Renderer9 *renderer); - virtual ~VertexBuffer9(); - virtual gl::Error initialize(unsigned int size, bool dynamicUsage); + gl::Error initialize(unsigned int size, bool dynamicUsage) override; + // Warning: you should ensure binding really matches attrib.bindingIndex before using this + // function. gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, GLenum currentValueType, GLint start, GLsizei count, @@ -31,23 +33,19 @@ class VertexBuffer9 : public VertexBuffer unsigned int offset, const uint8_t *sourceData) override; - virtual gl::Error getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, unsigned int *outSpaceRequired) const; - - virtual unsigned int getBufferSize() const; - virtual gl::Error setBufferSize(unsigned int size); - virtual gl::Error discard(); + unsigned int getBufferSize() const override; + gl::Error setBufferSize(unsigned int size) override; + gl::Error discard() override; IDirect3DVertexBuffer9 *getBuffer() const; private: + ~VertexBuffer9() override; Renderer9 *mRenderer; IDirect3DVertexBuffer9 *mVertexBuffer; unsigned int mBufferSize; bool mDynamicUsage; - - gl::Error spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances, - unsigned int *outSpaceRequired) const; }; } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp index a23ab4a290..abadf5c0b5 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp @@ -21,7 +21,7 @@ VertexDeclarationCache::VertexDeclarationCache() : mMaxLru(0) { for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++) { - mVertexDeclCache[i].vertexDeclaration = NULL; + mVertexDeclCache[i].vertexDeclaration = nullptr; mVertexDeclCache[i].lruCount = 0; } @@ -30,7 +30,7 @@ VertexDeclarationCache::VertexDeclarationCache() : mMaxLru(0) mAppliedVBs[i].serial = 0; } - mLastSetVDecl = NULL; + mLastSetVDecl = nullptr; mInstancingEnabled = true; } @@ -42,11 +42,13 @@ VertexDeclarationCache::~VertexDeclarationCache() } } -gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, - const std::vector &attributes, - gl::Program *program, - GLsizei instances, - GLsizei *repeatDraw) +gl::Error VertexDeclarationCache::applyDeclaration( + IDirect3DDevice9 *device, + const std::vector &attributes, + gl::Program *program, + GLint start, + GLsizei instances, + GLsizei *repeatDraw) { ASSERT(gl::MAX_VERTEX_ATTRIBS >= attributes.size()); @@ -102,14 +104,14 @@ gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, D3DVERTEXELEMENT9 *element = &elements[0]; ProgramD3D *programD3D = GetImplAs(program); - const auto &semanticIndexes = programD3D->getSemanticIndexes(); + const auto &semanticIndexes = programD3D->getAttribLocationToD3DSemantics(); for (size_t i = 0; i < attributes.size(); i++) { if (attributes[i].active) { // Directly binding the storage buffer is not supported for d3d9 - ASSERT(attributes[i].storage == NULL); + ASSERT(attributes[i].storage == nullptr); int stream = static_cast(i); @@ -147,19 +149,24 @@ gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, } } - VertexBuffer9 *vertexBuffer = GetAs(attributes[i].vertexBuffer); + VertexBuffer9 *vertexBuffer = GetAs(attributes[i].vertexBuffer.get()); + + unsigned int offset = 0; + ANGLE_TRY_RESULT(attributes[i].computeOffset(start), offset); if (mAppliedVBs[stream].serial != attributes[i].serial || mAppliedVBs[stream].stride != attributes[i].stride || - mAppliedVBs[stream].offset != attributes[i].offset) + mAppliedVBs[stream].offset != offset) { - device->SetStreamSource(stream, vertexBuffer->getBuffer(), attributes[i].offset, attributes[i].stride); + device->SetStreamSource(stream, vertexBuffer->getBuffer(), offset, + attributes[i].stride); mAppliedVBs[stream].serial = attributes[i].serial; mAppliedVBs[stream].stride = attributes[i].stride; - mAppliedVBs[stream].offset = attributes[i].offset; + mAppliedVBs[stream].offset = offset; } - gl::VertexFormatType vertexformatType = gl::GetVertexFormatType(*attributes[i].attribute, GL_FLOAT); + gl::VertexFormatType vertexformatType = + gl::GetVertexFormatType(*attributes[i].attribute, GL_FLOAT); const d3d9::VertexFormat &d3d9VertexInfo = d3d9::GetVertexFormatInfo(caps.DeclTypes, vertexformatType); element->Stream = static_cast(stream); @@ -200,7 +207,7 @@ gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, mLastSetVDecl = entry->vertexDeclaration; } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } } @@ -214,7 +221,7 @@ gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, } } - if (lastCache->vertexDeclaration != NULL) + if (lastCache->vertexDeclaration != nullptr) { SafeRelease(lastCache->vertexDeclaration); // mLastSetVDecl is set to the replacement, so we don't have to worry @@ -225,14 +232,15 @@ gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, HRESULT result = device->CreateVertexDeclaration(elements, &lastCache->vertexDeclaration); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal vertex declaration, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to create internal vertex declaration, " + << gl::FmtHR(result); } device->SetVertexDeclaration(lastCache->vertexDeclaration); mLastSetVDecl = lastCache->vertexDeclaration; lastCache->lruCount = ++mMaxLru; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } void VertexDeclarationCache::markStateDirty() @@ -242,7 +250,7 @@ void VertexDeclarationCache::markStateDirty() mAppliedVBs[i].serial = 0; } - mLastSetVDecl = NULL; + mLastSetVDecl = nullptr; mInstancingEnabled = true; // Forces it to be disabled when not used } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h index bad4de4d6b..7bd7cabae4 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h @@ -30,6 +30,7 @@ class VertexDeclarationCache gl::Error applyDeclaration(IDirect3DDevice9 *device, const std::vector &attributes, gl::Program *program, + GLint start, GLsizei instances, GLsizei *repeatDraw); diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp index b672a60e3c..d10fa1ee87 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp @@ -7,12 +7,16 @@ // formatutils9.cpp: Queries for GL image formats and their translations to D3D9 // formats. -#include "libANGLE/renderer/d3d/copyimage.h" #include "libANGLE/renderer/d3d/d3d9/formatutils9.h" + +#include "image_util/copyimage.h" +#include "image_util/generatemip.h" +#include "image_util/loadimage.h" + #include "libANGLE/renderer/d3d/d3d9/Renderer9.h" #include "libANGLE/renderer/d3d/d3d9/vertexconversion.h" -#include "libANGLE/renderer/d3d/generatemip.h" -#include "libANGLE/renderer/d3d/loadimage.h" + +using namespace angle; namespace rx { @@ -20,35 +24,8 @@ namespace rx namespace d3d9 { -const D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I', 'N', 'T', 'Z'))); -const D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N', 'U', 'L', 'L'))); - -struct D3D9FastCopyFormat -{ - GLenum destFormat; - GLenum destType; - ColorCopyFunction copyFunction; - - D3D9FastCopyFormat(GLenum destFormat, GLenum destType, ColorCopyFunction copyFunction) - : destFormat(destFormat), destType(destType), copyFunction(copyFunction) - { } - - bool operator<(const D3D9FastCopyFormat& other) const - { - return memcmp(this, &other, sizeof(D3D9FastCopyFormat)) < 0; - } -}; - -typedef std::multimap D3D9FastCopyMap; - -static D3D9FastCopyMap BuildFastCopyMap() -{ - D3D9FastCopyMap map; - - map.insert(std::make_pair(D3DFMT_A8R8G8B8, D3D9FastCopyFormat(GL_RGBA, GL_UNSIGNED_BYTE, CopyBGRA8ToRGBA8))); - - return map; -} +constexpr D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I', 'N', 'T', 'Z'))); +constexpr D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N', 'U', 'L', 'L'))); // A map to determine the pixel size and mip generation function of a given D3D format typedef std::map D3D9FormatInfoMap; @@ -64,109 +41,188 @@ D3DFormat::D3DFormat() luminanceBits(0), depthBits(0), stencilBits(0), - internalFormat(GL_NONE), - mipGenerationFunction(NULL), - colorReadFunction(NULL), - fastCopyFunctions() + formatID(angle::Format::ID::NONE) { } -ColorCopyFunction D3DFormat::getFastCopyFunction(GLenum format, GLenum type) const +D3DFormat::D3DFormat(GLuint bits, + GLuint blockWidth, + GLuint blockHeight, + GLuint redBits, + GLuint greenBits, + GLuint blueBits, + GLuint alphaBits, + GLuint lumBits, + GLuint depthBits, + GLuint stencilBits, + Format::ID formatID) + : pixelBytes(bits / 8), + blockWidth(blockWidth), + blockHeight(blockHeight), + redBits(redBits), + greenBits(greenBits), + blueBits(blueBits), + alphaBits(alphaBits), + luminanceBits(lumBits), + depthBits(depthBits), + stencilBits(stencilBits), + formatID(formatID) { - FastCopyFunctionMap::const_iterator iter = fastCopyFunctions.find(std::make_pair(format, type)); - return (iter != fastCopyFunctions.end()) ? iter->second : NULL; -} - -static inline void InsertD3DFormatInfo(D3D9FormatInfoMap *map, D3DFORMAT format, GLuint bits, GLuint blockWidth, - GLuint blockHeight, GLuint redBits, GLuint greenBits, GLuint blueBits, - GLuint alphaBits, GLuint lumBits, GLuint depthBits, GLuint stencilBits, - GLenum internalFormat, MipGenerationFunction mipFunc, - ColorReadFunction colorReadFunc) -{ - D3DFormat info; - info.pixelBytes = bits / 8; - info.blockWidth = blockWidth; - info.blockHeight = blockHeight; - info.redBits = redBits; - info.greenBits = greenBits; - info.blueBits = blueBits; - info.alphaBits = alphaBits; - info.luminanceBits = lumBits; - info.depthBits = depthBits; - info.stencilBits = stencilBits; - info.internalFormat = internalFormat; - info.mipGenerationFunction = mipFunc; - info.colorReadFunction = colorReadFunc; - - static const D3D9FastCopyMap fastCopyMap = BuildFastCopyMap(); - std::pair fastCopyIter = fastCopyMap.equal_range(format); - for (D3D9FastCopyMap::const_iterator i = fastCopyIter.first; i != fastCopyIter.second; i++) - { - info.fastCopyFunctions.insert(std::make_pair(std::make_pair(i->second.destFormat, i->second.destType), i->second.copyFunction)); - } - - map->insert(std::make_pair(format, info)); -} - -static D3D9FormatInfoMap BuildD3D9FormatInfoMap() -{ - D3D9FormatInfoMap map; - - // | D3DFORMAT | S |W |H | R | G | B | A | L | D | S | Internal format | Mip generation function | Color read function | - InsertD3DFormatInfo(&map, D3DFMT_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, GL_NONE, NULL, NULL ); - InsertD3DFormatInfo(&map, D3DFMT_UNKNOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, GL_NONE, NULL, NULL ); - - InsertD3DFormatInfo(&map, D3DFMT_L8, 8, 1, 1, 0, 0, 0, 0, 8, 0, 0, GL_LUMINANCE8_EXT, GenerateMip, ReadColor ); - InsertD3DFormatInfo(&map, D3DFMT_A8, 8, 1, 1, 0, 0, 0, 8, 0, 0, 0, GL_ALPHA8_EXT, GenerateMip, ReadColor ); - InsertD3DFormatInfo(&map, D3DFMT_A8L8, 16, 1, 1, 0, 0, 0, 8, 8, 0, 0, GL_LUMINANCE8_ALPHA8_EXT, GenerateMip, ReadColor ); - InsertD3DFormatInfo(&map, D3DFMT_A4R4G4B4, 16, 1, 1, 4, 4, 4, 4, 0, 0, 0, GL_BGRA4_ANGLEX, GenerateMip, ReadColor ); - InsertD3DFormatInfo(&map, D3DFMT_A1R5G5B5, 16, 1, 1, 5, 5, 5, 1, 0, 0, 0, GL_BGR5_A1_ANGLEX, GenerateMip, ReadColor ); - InsertD3DFormatInfo(&map, D3DFMT_R5G6B5, 16, 1, 1, 5, 6, 5, 0, 0, 0, 0, GL_RGB565, GenerateMip, ReadColor ); - InsertD3DFormatInfo(&map, D3DFMT_X8R8G8B8, 32, 1, 1, 8, 8, 8, 0, 0, 0, 0, GL_BGRA8_EXT, GenerateMip, ReadColor ); - InsertD3DFormatInfo(&map, D3DFMT_A8R8G8B8, 32, 1, 1, 8, 8, 8, 8, 0, 0, 0, GL_BGRA8_EXT, GenerateMip, ReadColor ); - InsertD3DFormatInfo(&map, D3DFMT_R16F, 16, 1, 1, 16, 0, 0, 0, 0, 0, 0, GL_R16F_EXT, GenerateMip, ReadColor ); - InsertD3DFormatInfo(&map, D3DFMT_G16R16F, 32, 1, 1, 16, 16, 0, 0, 0, 0, 0, GL_RG16F_EXT, GenerateMip, ReadColor ); - InsertD3DFormatInfo(&map, D3DFMT_A16B16G16R16F, 64, 1, 1, 16, 16, 16, 16, 0, 0, 0, GL_RGBA16F_EXT, GenerateMip, ReadColor); - InsertD3DFormatInfo(&map, D3DFMT_R32F, 32, 1, 1, 32, 0, 0, 0, 0, 0, 0, GL_R32F_EXT, GenerateMip, ReadColor ); - InsertD3DFormatInfo(&map, D3DFMT_G32R32F, 64, 1, 1, 32, 32, 0, 0, 0, 0, 0, GL_RG32F_EXT, GenerateMip, ReadColor ); - InsertD3DFormatInfo(&map, D3DFMT_A32B32G32R32F, 128, 1, 1, 32, 32, 32, 32, 0, 0, 0, GL_RGBA32F_EXT, GenerateMip, ReadColor); - - InsertD3DFormatInfo(&map, D3DFMT_D16, 16, 1, 1, 0, 0, 0, 0, 0, 16, 0, GL_DEPTH_COMPONENT16, NULL, NULL ); - InsertD3DFormatInfo(&map, D3DFMT_D24S8, 32, 1, 1, 0, 0, 0, 0, 0, 24, 8, GL_DEPTH24_STENCIL8_OES, NULL, NULL ); - InsertD3DFormatInfo(&map, D3DFMT_D24X8, 32, 1, 1, 0, 0, 0, 0, 0, 24, 0, GL_DEPTH_COMPONENT16, NULL, NULL ); - InsertD3DFormatInfo(&map, D3DFMT_D32, 32, 1, 1, 0, 0, 0, 0, 0, 32, 0, GL_DEPTH_COMPONENT32_OES, NULL, NULL ); - - InsertD3DFormatInfo(&map, D3DFMT_INTZ, 32, 1, 1, 0, 0, 0, 0, 0, 24, 8, GL_DEPTH24_STENCIL8_OES, NULL, NULL ); - - InsertD3DFormatInfo(&map, D3DFMT_DXT1, 64, 4, 4, 0, 0, 0, 0, 0, 0, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, NULL, NULL ); - InsertD3DFormatInfo(&map, D3DFMT_DXT3, 128, 4, 4, 0, 0, 0, 0, 0, 0, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, NULL, NULL ); - InsertD3DFormatInfo(&map, D3DFMT_DXT5, 128, 4, 4, 0, 0, 0, 0, 0, 0, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, NULL, NULL ); - - return map; } const D3DFormat &GetD3DFormatInfo(D3DFORMAT format) { - static const D3D9FormatInfoMap infoMap = BuildD3D9FormatInfoMap(); - D3D9FormatInfoMap::const_iterator iter = infoMap.find(format); - if (iter != infoMap.end()) + if (format == D3DFMT_NULL) { - return iter->second; + static const D3DFormat info(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Format::ID::NONE); + return info; } - else + + if (format == D3DFMT_INTZ) { - static const D3DFormat defaultInfo; - return defaultInfo; + static const D3DFormat info(32, 1, 1, 0, 0, 0, 0, 0, 24, 8, Format::ID::D24_UNORM_S8_UINT); + return info; + } + + switch (format) + { + case D3DFMT_UNKNOWN: + { + static const D3DFormat info(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Format::ID::NONE); + return info; + } + + case D3DFMT_L8: + { + static const D3DFormat info(8, 1, 1, 0, 0, 0, 0, 8, 0, 0, Format::ID::L8_UNORM); + return info; + } + case D3DFMT_A8: + { + static const D3DFormat info(8, 1, 1, 0, 0, 0, 8, 0, 0, 0, Format::ID::A8_UNORM); + return info; + } + case D3DFMT_A8L8: + { + static const D3DFormat info(16, 1, 1, 0, 0, 0, 8, 8, 0, 0, Format::ID::L8A8_UNORM); + return info; + } + + case D3DFMT_A4R4G4B4: + { + static const D3DFormat info(16, 1, 1, 4, 4, 4, 4, 0, 0, 0, Format::ID::B4G4R4A4_UNORM); + return info; + } + case D3DFMT_A1R5G5B5: + { + static const D3DFormat info(16, 1, 1, 5, 5, 5, 1, 0, 0, 0, Format::ID::B5G5R5A1_UNORM); + return info; + } + case D3DFMT_R5G6B5: + { + static const D3DFormat info(16, 1, 1, 5, 6, 5, 0, 0, 0, 0, Format::ID::R5G6B5_UNORM); + return info; + } + case D3DFMT_X8R8G8B8: + { + static const D3DFormat info(32, 1, 1, 8, 8, 8, 0, 0, 0, 0, Format::ID::B8G8R8X8_UNORM); + return info; + } + case D3DFMT_A8R8G8B8: + { + static const D3DFormat info(32, 1, 1, 8, 8, 8, 8, 0, 0, 0, Format::ID::B8G8R8A8_UNORM); + return info; + } + + case D3DFMT_R16F: + { + static const D3DFormat info(16, 1, 1, 16, 0, 0, 0, 0, 0, 0, Format::ID::R16_FLOAT); + return info; + } + case D3DFMT_G16R16F: + { + static const D3DFormat info(32, 1, 1, 16, 16, 0, 0, 0, 0, 0, Format::ID::R16G16_FLOAT); + return info; + } + case D3DFMT_A16B16G16R16F: + { + static const D3DFormat info(64, 1, 1, 16, 16, 16, 16, 0, 0, 0, + Format::ID::R16G16B16A16_FLOAT); + return info; + } + case D3DFMT_R32F: + { + static const D3DFormat info(32, 1, 1, 32, 0, 0, 0, 0, 0, 0, Format::ID::R32_FLOAT); + return info; + } + case D3DFMT_G32R32F: + { + static const D3DFormat info(64, 1, 1, 32, 32, 0, 0, 0, 0, 0, Format::ID::R32G32_FLOAT); + return info; + } + case D3DFMT_A32B32G32R32F: + { + static const D3DFormat info(128, 1, 1, 32, 32, 32, 32, 0, 0, 0, + Format::ID::R32G32B32A32_FLOAT); + return info; + } + + case D3DFMT_D16: + { + static const D3DFormat info(16, 1, 1, 0, 0, 0, 0, 0, 16, 0, Format::ID::D16_UNORM); + return info; + } + case D3DFMT_D24S8: + { + static const D3DFormat info(32, 1, 1, 0, 0, 0, 0, 0, 24, 8, + Format::ID::D24_UNORM_S8_UINT); + return info; + } + case D3DFMT_D24X8: + { + static const D3DFormat info(32, 1, 1, 0, 0, 0, 0, 0, 24, 0, Format::ID::D16_UNORM); + return info; + } + case D3DFMT_D32: + { + static const D3DFormat info(32, 1, 1, 0, 0, 0, 0, 0, 32, 0, Format::ID::D32_UNORM); + return info; + } + + case D3DFMT_DXT1: + { + static const D3DFormat info(64, 4, 4, 0, 0, 0, 0, 0, 0, 0, + Format::ID::BC1_RGBA_UNORM_BLOCK); + return info; + } + case D3DFMT_DXT3: + { + static const D3DFormat info(128, 4, 4, 0, 0, 0, 0, 0, 0, 0, + Format::ID::BC2_RGBA_UNORM_BLOCK); + return info; + } + case D3DFMT_DXT5: + { + static const D3DFormat info(128, 4, 4, 0, 0, 0, 0, 0, 0, 0, + Format::ID::BC3_RGBA_UNORM_BLOCK); + return info; + } + + default: + { + static const D3DFormat defaultInfo; + return defaultInfo; + } } } - - typedef std::pair InternalFormatInitialzerPair; typedef std::map InternalFormatInitialzerMap; static InternalFormatInitialzerMap BuildInternalFormatInitialzerMap() { + using namespace angle; // For image initialization functions + InternalFormatInitialzerMap map; map.insert(InternalFormatInitialzerPair(GL_RGB16F, Initialize4ComponentData)); @@ -175,28 +231,6 @@ static InternalFormatInitialzerMap BuildInternalFormatInitialzerMap() return map; } -// Each GL internal format corresponds to one D3D format and data loading function. -// Due to not all formats being available all the time, some of the function/format types are wrapped -// in templates that perform format support queries on a Renderer9 object which is supplied -// when requesting the function or format. - -typedef bool(*FallbackPredicateFunction)(); - -template -static void FallbackLoad(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - if (pred()) - { - prefered(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch); - } - else - { - fallback(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch); - } -} - static void UnreachableLoad(size_t width, size_t height, size_t depth, const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) @@ -210,7 +244,7 @@ typedef std::map D3D9FormatMap; TextureFormat::TextureFormat() : texFormat(D3DFMT_UNKNOWN), renderFormat(D3DFMT_UNKNOWN), - dataInitializerFunction(NULL), + dataInitializerFunction(nullptr), loadFunction(UnreachableLoad) { } @@ -224,7 +258,8 @@ static inline void InsertD3D9FormatInfo(D3D9FormatMap *map, GLenum internalForma static const InternalFormatInitialzerMap dataInitializationMap = BuildInternalFormatInitialzerMap(); InternalFormatInitialzerMap::const_iterator dataInitIter = dataInitializationMap.find(internalFormat); - info.dataInitializerFunction = (dataInitIter != dataInitializationMap.end()) ? dataInitIter->second : NULL; + info.dataInitializerFunction = + (dataInitIter != dataInitializationMap.end()) ? dataInitIter->second : nullptr; info.loadFunction = loadFunction; @@ -233,8 +268,11 @@ static inline void InsertD3D9FormatInfo(D3D9FormatMap *map, GLenum internalForma static D3D9FormatMap BuildD3D9FormatMap() { + using namespace angle; // For image loading functions + D3D9FormatMap map; + // clang-format off // | Internal format | Texture format | Render format | Load function | InsertD3D9FormatInfo(&map, GL_NONE, D3DFMT_NULL, D3DFMT_NULL, UnreachableLoad ); @@ -268,11 +306,11 @@ static D3D9FormatMap BuildD3D9FormatMap() InsertD3D9FormatInfo(&map, GL_LUMINANCE16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadL16FToRGBA16F ); InsertD3D9FormatInfo(&map, GL_LUMINANCE_ALPHA16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadLA16FToRGBA16F ); - InsertD3D9FormatInfo(&map, GL_ALPHA8_EXT, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FallbackLoad); + InsertD3D9FormatInfo(&map, GL_ALPHA8_EXT, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadA8ToBGRA8 ); InsertD3D9FormatInfo(&map, GL_RGB8_OES, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadRGB8ToBGRX8 ); InsertD3D9FormatInfo(&map, GL_RGB565, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadR5G6B5ToBGRA8 ); - InsertD3D9FormatInfo(&map, GL_RGBA8_OES, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FallbackLoad); + InsertD3D9FormatInfo(&map, GL_RGBA8_OES, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadRGBA8ToBGRA8 ); InsertD3D9FormatInfo(&map, GL_RGBA4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadRGBA4ToBGRA8 ); InsertD3D9FormatInfo(&map, GL_RGB5_A1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadRGB5A1ToBGRA8 ); InsertD3D9FormatInfo(&map, GL_R8_EXT, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadR8ToBGRX8 ); @@ -291,6 +329,7 @@ static D3D9FormatMap BuildD3D9FormatMap() // then changing the format and loading function appropriately. InsertD3D9FormatInfo(&map, GL_LUMINANCE8_EXT, D3DFMT_L8, D3DFMT_UNKNOWN, LoadToNative ); InsertD3D9FormatInfo(&map, GL_LUMINANCE8_ALPHA8_EXT, D3DFMT_A8L8, D3DFMT_UNKNOWN, LoadToNative ); + // clang-format on return map; } @@ -503,7 +542,7 @@ public: VertexFormat::VertexFormat() : conversionType(VERTEX_CONVERT_NONE), outputElementSize(0), - copyFunction(NULL), + copyFunction(nullptr), nativeFormat(D3DDECLTYPE_UNUSED), componentType(GL_NONE) { diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.h index c55010760d..1bef320b53 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.h @@ -15,6 +15,8 @@ #include "common/platform.h" #include "libANGLE/angletypes.h" #include "libANGLE/formatutils.h" +#include "libANGLE/renderer/Format.h" +#include "libANGLE/renderer/renderer_utils.h" #include "libANGLE/renderer/d3d/formatutilsD3D.h" namespace rx @@ -25,11 +27,22 @@ class Renderer9; namespace d3d9 { -typedef std::map, ColorCopyFunction> FastCopyFunctionMap; - struct D3DFormat { D3DFormat(); + D3DFormat(GLuint pixelBytes, + GLuint blockWidth, + GLuint blockHeight, + GLuint redBits, + GLuint greenBits, + GLuint blueBits, + GLuint alphaBits, + GLuint luminanceBits, + GLuint depthBits, + GLuint stencilBits, + angle::Format::ID formatID); + + const angle::Format &info() const { return angle::Format::Get(formatID); } GLuint pixelBytes; GLuint blockWidth; @@ -44,14 +57,9 @@ struct D3DFormat GLuint depthBits; GLuint stencilBits; - GLenum internalFormat; - - MipGenerationFunction mipGenerationFunction; - ColorReadFunction colorReadFunction; - - FastCopyFunctionMap fastCopyFunctions; - ColorCopyFunction getFastCopyFunction(GLenum format, GLenum type) const; + angle::Format::ID formatID; }; + const D3DFormat &GetD3DFormatInfo(D3DFORMAT format); struct VertexFormat diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp index 8622dc4d13..fd451a6e51 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp @@ -17,7 +17,9 @@ #include "libANGLE/renderer/d3d/d3d9/formatutils9.h" #include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" #include "libANGLE/renderer/d3d/FramebufferD3D.h" -#include "libANGLE/renderer/d3d/WorkaroundsD3D.h" +#include "libANGLE/renderer/driver_utils.h" +#include "platform/Platform.h" +#include "platform/WorkaroundsD3D.h" #include "third_party/systeminfo/SystemInfo.h" @@ -133,21 +135,22 @@ D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap) return d3dWrap; } -D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace) +D3DCULL ConvertCullMode(gl::CullFaceMode cullFace, GLenum frontFace) { D3DCULL cull = D3DCULL_CCW; switch (cullFace) { - case GL_FRONT: - cull = (frontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW); - break; - case GL_BACK: - cull = (frontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW); - break; - case GL_FRONT_AND_BACK: - cull = D3DCULL_NONE; // culling will be handled during draw - break; - default: UNREACHABLE(); + case gl::CullFaceMode::Front: + cull = (frontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW); + break; + case gl::CullFaceMode::Back: + cull = (frontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW); + break; + case gl::CullFaceMode::FrontAndBack: + cull = D3DCULL_NONE; // culling will be handled during draw + break; + default: + UNREACHABLE(); } return cull; @@ -264,6 +267,21 @@ void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DT } } +D3DQUERYTYPE ConvertQueryType(GLenum queryType) +{ + switch (queryType) + { + case GL_ANY_SAMPLES_PASSED_EXT: + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: + return D3DQUERYTYPE_OCCLUSION; + case GL_COMMANDS_COMPLETED_CHROMIUM: + return D3DQUERYTYPE_EVENT; + default: + UNREACHABLE(); + return static_cast(0); + } +} + D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples) { return (samples > 1) ? static_cast(samples) : D3DMULTISAMPLE_NONE; @@ -291,8 +309,8 @@ GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type) bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format) { - GLenum internalFormat = d3d9::GetD3DFormatInfo(d3dformat).internalFormat; - GLenum convertedFormat = gl::GetInternalFormatInfo(internalFormat).format; + GLenum internalFormat = d3d9::GetD3DFormatInfo(d3dformat).info().glInternalFormat; + GLenum convertedFormat = gl::GetSizedInternalFormatInfo(internalFormat).format; return convertedFormat == format; } @@ -302,7 +320,7 @@ static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, IDirect3 gl::TextureCaps textureCaps; const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalFormat); - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalFormat); if (d3dFormatInfo.texFormat != D3DFMT_UNKNOWN) { @@ -333,7 +351,8 @@ static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, IDirect3 { D3DMULTISAMPLE_TYPE multisampleType = D3DMULTISAMPLE_TYPE(i); - HRESULT result = d3d9->CheckDeviceMultiSampleType(adapter, deviceType, d3dFormatInfo.renderFormat, TRUE, multisampleType, NULL); + HRESULT result = d3d9->CheckDeviceMultiSampleType( + adapter, deviceType, d3dFormatInfo.renderFormat, TRUE, multisampleType, nullptr); if (SUCCEEDED(result)) { textureCaps.sampleCounts.insert(i); @@ -364,18 +383,17 @@ void GenerateCaps(IDirect3D9 *d3d9, d3d9->GetAdapterDisplayMode(adapter, ¤tDisplayMode); GLuint maxSamples = 0; - const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats(); - for (gl::FormatSet::const_iterator internalFormat = allFormats.begin(); internalFormat != allFormats.end(); ++internalFormat) + for (GLenum internalFormat : gl::GetAllSizedInternalFormats()) { - gl::TextureCaps textureCaps = GenerateTextureFormatCaps(*internalFormat, d3d9, deviceType, adapter, - currentDisplayMode.Format); - textureCapsMap->insert(*internalFormat, textureCaps); + gl::TextureCaps textureCaps = GenerateTextureFormatCaps(internalFormat, d3d9, deviceType, + adapter, currentDisplayMode.Format); + textureCapsMap->insert(internalFormat, textureCaps); maxSamples = std::max(maxSamples, textureCaps.getMaxSamples()); - if (gl::GetInternalFormatInfo(*internalFormat).compressed) + if (gl::GetSizedInternalFormatInfo(internalFormat).compressed) { - caps->compressedTextureFormats.push_back(*internalFormat); + caps->compressedTextureFormats.push_back(internalFormat); } } @@ -444,6 +462,8 @@ void GenerateCaps(IDirect3D9 *d3d9, // Vertex shader limits caps->maxVertexAttributes = 16; + // Vertex Attrib Binding not supported. + caps->maxVertexAttribBindings = caps->maxVertexAttributes; const size_t MAX_VERTEX_CONSTANT_VECTORS_D3D9 = 256; caps->maxVertexUniformVectors = @@ -525,12 +545,12 @@ void GenerateCaps(IDirect3D9 *d3d9, { // ATI cards on XP have problems with non-power-of-two textures. extensions->textureNPOT = !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_POW2) && - !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) && - !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) && - !(!isWindowsVistaOrGreater() && adapterId.VendorId == VENDOR_ID_AMD); + !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) && + !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) && + !(!isWindowsVistaOrGreater() && IsAMD(adapterId.VendorId)); // Disable depth texture support on AMD cards (See ANGLE issue 839) - if (adapterId.VendorId == VENDOR_ID_AMD) + if (IsAMD(adapterId.VendorId)) { extensions->depthTextures = false; } @@ -548,18 +568,21 @@ void GenerateCaps(IDirect3D9 *d3d9, extensions->maxTextureAnisotropy = static_cast(deviceCaps.MaxAnisotropy); // Check occlusion query support by trying to create one - IDirect3DQuery9 *occlusionQuery = NULL; + IDirect3DQuery9 *occlusionQuery = nullptr; extensions->occlusionQueryBoolean = SUCCEEDED(device->CreateQuery(D3DQUERYTYPE_OCCLUSION, &occlusionQuery)) && occlusionQuery; SafeRelease(occlusionQuery); // Check event query support by trying to create one - IDirect3DQuery9 *eventQuery = NULL; + IDirect3DQuery9 *eventQuery = nullptr; extensions->fence = SUCCEEDED(device->CreateQuery(D3DQUERYTYPE_EVENT, &eventQuery)) && eventQuery; SafeRelease(eventQuery); - extensions->timerQuery = false; // Unimplemented extensions->disjointTimerQuery = false; extensions->robustness = true; + // It seems that only DirectX 10 and higher enforce the well-defined behavior of always + // returning zero values when out-of-bounds reads. See + // https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_robustness.txt + extensions->robustBufferAccessBehavior = false; extensions->blendMinMax = true; extensions->framebufferBlit = true; extensions->framebufferMultisample = true; @@ -575,10 +598,11 @@ void GenerateCaps(IDirect3D9 *d3d9, extensions->colorBufferFloat = false; extensions->debugMarker = true; extensions->eglImage = true; + extensions->eglImageExternal = true; extensions->unpackSubimage = true; extensions->packSubimage = true; - extensions->vertexArrayObject = true; - extensions->noError = true; + extensions->syncQuery = extensions->fence; + extensions->copyTexture = true; // D3D9 has no concept of separate masks and refs for front and back faces in the depth stencil // state. @@ -625,15 +649,23 @@ void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsize *levelOffset = upsampleCount; } -WorkaroundsD3D GenerateWorkarounds() +angle::WorkaroundsD3D GenerateWorkarounds() { - WorkaroundsD3D workarounds; + angle::WorkaroundsD3D workarounds; workarounds.mrtPerfWorkaround = true; workarounds.setDataFasterThanImageUpload = false; workarounds.useInstancedPointSpriteEmulation = false; + + // TODO(jmadill): Disable workaround when we have a fixed compiler DLL. + workarounds.expandIntegerPowExpressions = true; + + // Call platform hooks for testing overrides. + auto *platform = ANGLEPlatformCurrent(); + platform->overrideWorkaroundsD3D(platform, &workarounds); + return workarounds; } -} +} // namespace d3d9 -} +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h index aa494adb62..5b65b8910a 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h @@ -10,9 +10,10 @@ #ifndef LIBANGLE_RENDERER_D3D_D3D9_RENDERER9UTILS_H_ #define LIBANGLE_RENDERER_D3D_D3D9_RENDERER9UTILS_H_ -#include "libANGLE/angletypes.h" +#include "common/Color.h" #include "libANGLE/Caps.h" #include "libANGLE/Error.h" +#include "platform/WorkaroundsD3D.h" namespace gl { @@ -22,7 +23,6 @@ class FramebufferAttachment; namespace rx { class RenderTarget9; -struct WorkaroundsD3D; namespace gl_d3d9 { @@ -33,12 +33,13 @@ D3DBLEND ConvertBlendFunc(GLenum blend); D3DBLENDOP ConvertBlendOp(GLenum blendOp); D3DSTENCILOP ConvertStencilOp(GLenum stencilOp); D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap); -D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace); +D3DCULL ConvertCullMode(gl::CullFaceMode cullFace, GLenum frontFace); D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace); DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha); D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy); void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float *d3dLodBias, float maxAnisotropy, size_t baseLevel); +D3DQUERYTYPE ConvertQueryType(GLenum queryType); D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples); @@ -86,9 +87,9 @@ inline bool isDeviceLostError(HRESULT errorCode) } } -WorkaroundsD3D GenerateWorkarounds(); +angle::WorkaroundsD3D GenerateWorkarounds(); } -} +} // namespace d3d9 #endif // LIBANGLE_RENDERER_D3D_D3D9_RENDERER9UTILS_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.ps b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.ps index dc357d0fa6..ecc593cc78 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.ps +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.ps @@ -24,6 +24,23 @@ float4 luminanceps(float4 texcoord : TEXCOORD0) : COLOR return (tex2D(tex, texcoord.xy).xw * mult.xw + add.xw).xxxy; }; +float4 luminancepremultps(float4 texcoord : TEXCOORD0) : COLOR +{ + float4 luma = tex2D(tex, texcoord.xy).xxxw; + luma.rgb *= luma.a; + return luma * mult + add; +}; + +float4 luminanceunmultps(float4 texcoord : TEXCOORD0) : COLOR +{ + float4 luma = tex2D(tex, texcoord.xy).xxxw; + if (luma.a > 0.0f) + { + luma.rgb /= luma.a; + } + return luma * mult + add; +}; + // RGB/A Component Mask Pixel Shader // Performs a mad operation using the texture's RGBA data with mult.xyzw and add.xyzw. // Returns data in the form of rgba @@ -31,3 +48,20 @@ float4 componentmaskps(float4 texcoord : TEXCOORD0) : COLOR { return tex2D(tex, texcoord.xy) * mult + add; }; + +float4 componentmaskpremultps(float4 texcoord : TEXCOORD0) : COLOR +{ + float4 color = tex2D(tex, texcoord.xy); + color.rgb *= color.a; + return color * mult + add; +}; + +float4 componentmaskunmultps(float4 texcoord : TEXCOORD0) : COLOR +{ + float4 color = tex2D(tex, texcoord.xy); + if (color.a > 0.0f) + { + color.rgb /= color.a; + } + return color * mult + add; +}; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.vs b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.vs index 3a36980b93..c68395a69c 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.vs +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.vs @@ -11,6 +11,7 @@ struct VS_OUTPUT }; uniform float4 halfPixelSize : c0; +uniform float4 texcoordOffset : c1; // Standard Vertex Shader // Input 0 is the homogenous position. @@ -22,22 +23,7 @@ VS_OUTPUT standardvs(in float4 position : POSITION) VS_OUTPUT Out; Out.position = position + halfPixelSize; - Out.texcoord = position * float4(0.5, -0.5, 1.0, 1.0) + float4(0.5, 0.5, 0, 0); - - return Out; -}; - -// Flip Y Vertex Shader -// Input 0 is the homogenous position. -// Outputs the homogenous position as-is. -// Outputs a tex coord with (0,1) in the upper-left corner of the screen and (1,0) in the bottom right. -// C0.XY must be the half-pixel width and height. C0.ZW must be 0. -VS_OUTPUT flipyvs(in float4 position : POSITION) -{ - VS_OUTPUT Out; - - Out.position = position + halfPixelSize; - Out.texcoord = position * float4(0.5, 0.5, 1.0, 1.0) + float4(0.5, 0.5, 0, 0); + Out.texcoord = ((position * float4(0.5, -0.5, 1.0, 1.0) + float4(0.5, 0.5, 0, 0)) * float4(texcoordOffset.zw, 1.0, 1.0)) + float4(texcoordOffset.xy, 0, 0); return Out; }; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/formatutilsD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/formatutilsD3D.cpp deleted file mode 100644 index e1c955eb06..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/formatutilsD3D.cpp +++ /dev/null @@ -1,147 +0,0 @@ -// -// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// formatutils9.cpp: Queries for GL image formats and their translations to D3D -// formats. - -#include "libANGLE/renderer/d3d/formatutilsD3D.h" - -#include - -#include "common/debug.h" -#include "libANGLE/renderer/d3d/imageformats.h" -#include "libANGLE/renderer/d3d/copyimage.h" - -namespace rx -{ - -typedef std::pair FormatTypePair; -typedef std::pair FormatWriteFunctionPair; -typedef std::map FormatWriteFunctionMap; - -static inline void InsertFormatWriteFunctionMapping(FormatWriteFunctionMap *map, GLenum format, GLenum type, - ColorWriteFunction writeFunc) -{ - map->insert(FormatWriteFunctionPair(FormatTypePair(format, type), writeFunc)); -} - -static FormatWriteFunctionMap BuildFormatWriteFunctionMap() -{ - FormatWriteFunctionMap map; - - // | Format | Type | Color write function | - InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_UNSIGNED_BYTE, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_BYTE, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_FLOAT, WriteColor); - InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_HALF_FLOAT, WriteColor); - InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_HALF_FLOAT_OES, WriteColor); - - InsertFormatWriteFunctionMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RGBA_INTEGER, GL_BYTE, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RGBA_INTEGER, GL_SHORT, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RGBA_INTEGER, GL_INT, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, WriteColor ); - - InsertFormatWriteFunctionMapping(&map, GL_RGB, GL_UNSIGNED_BYTE, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RGB, GL_BYTE, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RGB, GL_FLOAT, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RGB, GL_HALF_FLOAT, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RGB, GL_HALF_FLOAT_OES, WriteColor ); - - InsertFormatWriteFunctionMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RGB_INTEGER, GL_BYTE, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RGB_INTEGER, GL_SHORT, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_INT, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RGB_INTEGER, GL_INT, WriteColor ); - - InsertFormatWriteFunctionMapping(&map, GL_RG, GL_UNSIGNED_BYTE, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RG, GL_BYTE, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RG, GL_FLOAT, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RG, GL_HALF_FLOAT, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RG, GL_HALF_FLOAT_OES, WriteColor ); - - InsertFormatWriteFunctionMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_BYTE, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RG_INTEGER, GL_BYTE, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_SHORT, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RG_INTEGER, GL_SHORT, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_INT, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RG_INTEGER, GL_INT, WriteColor ); - - InsertFormatWriteFunctionMapping(&map, GL_RED, GL_UNSIGNED_BYTE, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RED, GL_BYTE, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RED, GL_FLOAT, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RED, GL_HALF_FLOAT, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RED, GL_HALF_FLOAT_OES, WriteColor ); - - InsertFormatWriteFunctionMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_BYTE, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RED_INTEGER, GL_BYTE, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_SHORT, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RED_INTEGER, GL_SHORT, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_INT, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_RED_INTEGER, GL_INT, WriteColor ); - - InsertFormatWriteFunctionMapping(&map, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_LUMINANCE, GL_UNSIGNED_BYTE, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_ALPHA, GL_UNSIGNED_BYTE, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_LUMINANCE_ALPHA, GL_FLOAT, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_LUMINANCE, GL_FLOAT, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_ALPHA, GL_FLOAT, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT_OES, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_ALPHA, GL_HALF_FLOAT, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_ALPHA, GL_HALF_FLOAT_OES, WriteColor ); - - InsertFormatWriteFunctionMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_BYTE, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, WriteColor ); - - InsertFormatWriteFunctionMapping(&map, GL_SRGB_EXT, GL_UNSIGNED_BYTE, WriteColor ); - InsertFormatWriteFunctionMapping(&map, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, WriteColor ); - - InsertFormatWriteFunctionMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, NULL ); - InsertFormatWriteFunctionMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, NULL ); - InsertFormatWriteFunctionMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, NULL ); - InsertFormatWriteFunctionMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, NULL ); - - InsertFormatWriteFunctionMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NULL ); - InsertFormatWriteFunctionMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL ); - InsertFormatWriteFunctionMapping(&map, GL_DEPTH_COMPONENT, GL_FLOAT, NULL ); - - InsertFormatWriteFunctionMapping(&map, GL_STENCIL, GL_UNSIGNED_BYTE, NULL ); - - InsertFormatWriteFunctionMapping(&map, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL ); - InsertFormatWriteFunctionMapping(&map, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, NULL ); - - return map; -} - -ColorWriteFunction GetColorWriteFunction(GLenum format, GLenum type) -{ - static const FormatWriteFunctionMap formatTypeMap = BuildFormatWriteFunctionMap(); - FormatWriteFunctionMap::const_iterator iter = formatTypeMap.find(FormatTypePair(format, type)); - ASSERT(iter != formatTypeMap.end()); - if (iter != formatTypeMap.end()) - { - return iter->second; - } - else - { - return NULL; - } -} - -} diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/formatutilsD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/formatutilsD3D.h index 6dd59ca94b..a245a0432f 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/formatutilsD3D.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/formatutilsD3D.h @@ -15,24 +15,15 @@ #include #include +#include + +namespace gl +{ +struct FormatType; +} + namespace rx { - -typedef void (*MipGenerationFunction)(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth, - const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch, - uint8_t *destData, size_t destRowPitch, size_t destDepthPitch); - -typedef void (*LoadImageFunction)(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -typedef void (*InitializeTextureDataFunction)(size_t width, size_t height, size_t depth, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -typedef void (*ColorReadFunction)(const uint8_t *source, uint8_t *dest); -typedef void (*ColorWriteFunction)(const uint8_t *source, uint8_t *dest); -typedef void (*ColorCopyFunction)(const uint8_t *source, uint8_t *dest); - typedef void (*VertexCopyFunction)(const uint8_t *input, size_t stride, size_t count, uint8_t *output); enum VertexConversionType @@ -42,9 +33,6 @@ enum VertexConversionType VERTEX_CONVERT_GPU = 2, VERTEX_CONVERT_BOTH = 3 }; - -ColorWriteFunction GetColorWriteFunction(GLenum format, GLenum type); - -} +} // namespace rx #endif // LIBANGLE_RENDERER_D3D_FORMATUTILSD3D_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/generatemip.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/generatemip.h deleted file mode 100644 index 398ef26b30..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/generatemip.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// generatemip.h: Defines the GenerateMip function, templated on the format -// type of the image for which mip levels are being generated. - -#ifndef LIBANGLE_RENDERER_D3D_GENERATEMIP_H_ -#define LIBANGLE_RENDERER_D3D_GENERATEMIP_H_ - -#include "libANGLE/renderer/d3d/imageformats.h" -#include "libANGLE/angletypes.h" - -namespace rx -{ - -template -inline void GenerateMip(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth, - const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch, - uint8_t *destData, size_t destRowPitch, size_t destDepthPitch); - -} - -#include "generatemip.inl" - -#endif // LIBANGLE_RENDERER_D3D_GENERATEMIP_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/imageformats.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/imageformats.h deleted file mode 100644 index 76f1830e64..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/imageformats.h +++ /dev/null @@ -1,1999 +0,0 @@ -// -// Copyright (c) 2013-2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// imageformats.h: Defines image format types with functions for mip generation -// and copying. - -#ifndef LIBANGLE_RENDERER_D3D_IMAGEFORMATS_H_ -#define LIBANGLE_RENDERER_D3D_IMAGEFORMATS_H_ - -#include "libANGLE/angletypes.h" - -#include "common/mathutil.h" - -namespace rx -{ - -// Several structures share functionality for reading, writing or mipmapping but the layout -// must match the texture format which the structure represents. If collapsing or typedefing -// structs in this header, make sure the functionality and memory layout is exactly the same. - -struct L8 -{ - unsigned char L; - - static void readColor(gl::ColorF *dst, const L8 *src) - { - const float lum = gl::normalizedToFloat(src->L); - dst->red = lum; - dst->green = lum; - dst->blue = lum; - dst->alpha = 1.0f; - } - - static void writeColor(L8 *dst, const gl::ColorF *src) - { - dst->L = gl::floatToNormalized((src->red + src->green + src->blue) / 3.0f); - } - - static void average(L8 *dst, const L8 *src1, const L8 *src2) - { - dst->L = gl::average(src1->L, src2->L); - } -}; - -struct R8 -{ - unsigned char R; - - static void readColor(gl::ColorF *dst, const R8 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = 0.0f; - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorUI *dst, const R8 *src) - { - dst->red = src->R; - dst->green = 0; - dst->blue = 0; - dst->alpha = 1; - } - - static void writeColor(R8 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - } - - static void writeColor(R8 *dst, const gl::ColorUI *src) - { - dst->R = static_cast(src->red); - } - - static void average(R8 *dst, const R8 *src1, const R8 *src2) - { - dst->R = gl::average(src1->R, src2->R); - } -}; - -struct A8 -{ - unsigned char A; - - static void readColor(gl::ColorF *dst, const A8 *src) - { - dst->red = 0.0f; - dst->green = 0.0f; - dst->blue = 0.0f; - dst->alpha = gl::normalizedToFloat(src->A); - } - - static void writeColor(A8 *dst, const gl::ColorF *src) - { - dst->A = gl::floatToNormalized(src->alpha); - } - - static void average(A8 *dst, const A8 *src1, const A8 *src2) - { - dst->A = gl::average(src1->A, src2->A); - } -}; - -struct L8A8 -{ - unsigned char L; - unsigned char A; - - static void readColor(gl::ColorF *dst, const L8A8 *src) - { - const float lum = gl::normalizedToFloat(src->L); - dst->red = lum; - dst->green = lum; - dst->blue = lum; - dst->alpha = gl::normalizedToFloat(src->A); - } - - static void writeColor(L8A8 *dst, const gl::ColorF *src) - { - dst->L = gl::floatToNormalized((src->red + src->green + src->blue) / 3.0f); - dst->A = gl::floatToNormalized(src->alpha); - } - - static void average(L8A8 *dst, const L8A8 *src1, const L8A8 *src2) - { - *(unsigned short*)dst = (((*(unsigned short*)src1 ^ *(unsigned short*)src2) & 0xFEFE) >> 1) + (*(unsigned short*)src1 & *(unsigned short*)src2); - } -}; - -struct A8L8 -{ - unsigned char A; - unsigned char L; - - static void readColor(gl::ColorF *dst, const A8L8 *src) - { - const float lum = gl::normalizedToFloat(src->L); - dst->red = lum; - dst->green = lum; - dst->blue = lum; - dst->alpha = gl::normalizedToFloat(src->A); - } - - static void writeColor(A8L8 *dst, const gl::ColorF *src) - { - dst->L = gl::floatToNormalized((src->red + src->green + src->blue) / 3.0f); - dst->A = gl::floatToNormalized(src->alpha); - } - - static void average(A8L8 *dst, const A8L8 *src1, const A8L8 *src2) - { - *(unsigned short*)dst = (((*(unsigned short*)src1 ^ *(unsigned short*)src2) & 0xFEFE) >> 1) + (*(unsigned short*)src1 & *(unsigned short*)src2); - } -}; - -struct R8G8 -{ - unsigned char R; - unsigned char G; - - static void readColor(gl::ColorF *dst, const R8G8 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorUI *dst, const R8G8 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = 0; - dst->alpha = 1; - } - - static void writeColor(R8G8 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - dst->G = gl::floatToNormalized(src->green); - } - - static void writeColor(R8G8 *dst, const gl::ColorUI *src) - { - dst->R = static_cast(src->red); - dst->G = static_cast(src->green); - } - - static void average(R8G8 *dst, const R8G8 *src1, const R8G8 *src2) - { - *(unsigned short*)dst = (((*(unsigned short*)src1 ^ *(unsigned short*)src2) & 0xFEFE) >> 1) + (*(unsigned short*)src1 & *(unsigned short*)src2); - } -}; - -struct R8G8B8 -{ - unsigned char R; - unsigned char G; - unsigned char B; - - static void readColor(gl::ColorF *dst, const R8G8B8 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorUI *dst, const R8G8B8 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->G; - dst->alpha = 1; - } - - static void writeColor(R8G8B8 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - dst->G = gl::floatToNormalized(src->green); - dst->B = gl::floatToNormalized(src->blue); - } - - static void writeColor(R8G8B8 *dst, const gl::ColorUI *src) - { - dst->R = static_cast(src->red); - dst->G = static_cast(src->green); - dst->B = static_cast(src->blue); - } - - static void average(R8G8B8 *dst, const R8G8B8 *src1, const R8G8B8 *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - } -}; - -struct B8G8R8 -{ - unsigned char B; - unsigned char G; - unsigned char R; - - static void readColor(gl::ColorF *dst, const B8G8R8 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorUI *dst, const B8G8R8 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->G; - dst->alpha = 1; - } - - static void writeColor(B8G8R8 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - dst->G = gl::floatToNormalized(src->green); - dst->B = gl::floatToNormalized(src->blue); - } - - static void writeColor(B8G8R8 *dst, const gl::ColorUI *src) - { - dst->R = static_cast(src->red); - dst->G = static_cast(src->green); - dst->B = static_cast(src->blue); - } - - static void average(B8G8R8 *dst, const B8G8R8 *src1, const B8G8R8 *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - } -}; - -struct R5G6B5 -{ - // OpenGL ES 2.0.25 spec Section 3.6.2: "Components are packed with the first component in the most significant - // bits of the bitfield, and successive component occupying progressively less significant locations" - unsigned short RGB; - - static void readColor(gl::ColorF *dst, const R5G6B5 *src) - { - dst->red = gl::normalizedToFloat<5>(gl::getShiftedData<5, 11>(src->RGB)); - dst->green = gl::normalizedToFloat<6>(gl::getShiftedData<6, 5>(src->RGB)); - dst->blue = gl::normalizedToFloat<5>(gl::getShiftedData<5, 0>(src->RGB)); - dst->alpha = 1.0f; - } - - static void writeColor(R5G6B5 *dst, const gl::ColorF *src) - { - dst->RGB = gl::shiftData<5, 11>(gl::floatToNormalized<5, unsigned short>(src->red)) | - gl::shiftData<6, 5>(gl::floatToNormalized<6, unsigned short>(src->green)) | - gl::shiftData<5, 0>(gl::floatToNormalized<5, unsigned short>(src->blue)); - } - - static void average(R5G6B5 *dst, const R5G6B5 *src1, const R5G6B5 *src2) - { - dst->RGB = gl::shiftData<5, 11>(gl::average(gl::getShiftedData<5, 11>(src1->RGB), gl::getShiftedData<5, 11>(src2->RGB))) | - gl::shiftData<6, 5>(gl::average(gl::getShiftedData<6, 5>(src1->RGB), gl::getShiftedData<6, 5>(src2->RGB))) | - gl::shiftData<5, 0>(gl::average(gl::getShiftedData<5, 0>(src1->RGB), gl::getShiftedData<5, 0>(src2->RGB))); - } -}; - -struct A8R8G8B8 -{ - unsigned char A; - unsigned char R; - unsigned char G; - unsigned char B; - - static void readColor(gl::ColorF *dst, const A8R8G8B8 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = gl::normalizedToFloat(src->A); - } - - static void readColor(gl::ColorUI *dst, const A8R8G8B8 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = src->A; - } - - static void writeColor(A8R8G8B8 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - dst->G = gl::floatToNormalized(src->green); - dst->B = gl::floatToNormalized(src->blue); - dst->A = gl::floatToNormalized(src->alpha); - } - - static void writeColor(A8R8G8B8 *dst, const gl::ColorUI *src) - { - dst->R = static_cast(src->red); - dst->G = static_cast(src->green); - dst->B = static_cast(src->blue); - dst->A = static_cast(src->alpha); - } - - static void average(A8R8G8B8 *dst, const A8R8G8B8 *src1, const A8R8G8B8 *src2) - { - *(unsigned int*)dst = (((*(unsigned int*)src1 ^ *(unsigned int*)src2) & 0xFEFEFEFE) >> 1) + (*(unsigned int*)src1 & *(unsigned int*)src2); - } -}; - -struct R8G8B8A8 -{ - unsigned char R; - unsigned char G; - unsigned char B; - unsigned char A; - - static void readColor(gl::ColorF *dst, const R8G8B8A8 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = gl::normalizedToFloat(src->A); - } - - static void readColor(gl::ColorUI *dst, const R8G8B8A8 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = src->A; - } - - static void writeColor(R8G8B8A8 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - dst->G = gl::floatToNormalized(src->green); - dst->B = gl::floatToNormalized(src->blue); - dst->A = gl::floatToNormalized(src->alpha); - } - - static void writeColor(R8G8B8A8 *dst, const gl::ColorUI *src) - { - dst->R = static_cast(src->red); - dst->G = static_cast(src->green); - dst->B = static_cast(src->blue); - dst->A = static_cast(src->alpha); - } - - static void average(R8G8B8A8 *dst, const R8G8B8A8 *src1, const R8G8B8A8 *src2) - { - *(unsigned int*)dst = (((*(unsigned int*)src1 ^ *(unsigned int*)src2) & 0xFEFEFEFE) >> 1) + (*(unsigned int*)src1 & *(unsigned int*)src2); - } -}; - -struct B8G8R8A8 -{ - unsigned char B; - unsigned char G; - unsigned char R; - unsigned char A; - - static void readColor(gl::ColorF *dst, const B8G8R8A8 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = gl::normalizedToFloat(src->A); - } - - static void readColor(gl::ColorUI *dst, const B8G8R8A8 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = src->A; - } - - static void writeColor(B8G8R8A8 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - dst->G = gl::floatToNormalized(src->green); - dst->B = gl::floatToNormalized(src->blue); - dst->A = gl::floatToNormalized(src->alpha); - } - - static void writeColor(B8G8R8A8 *dst, const gl::ColorUI *src) - { - dst->R = static_cast(src->red); - dst->G = static_cast(src->green); - dst->B = static_cast(src->blue); - dst->A = static_cast(src->alpha); - } - - static void average(B8G8R8A8 *dst, const B8G8R8A8 *src1, const B8G8R8A8 *src2) - { - *(unsigned int*)dst = (((*(unsigned int*)src1 ^ *(unsigned int*)src2) & 0xFEFEFEFE) >> 1) + (*(unsigned int*)src1 & *(unsigned int*)src2); - } -}; - -struct B8G8R8X8 -{ - unsigned char B; - unsigned char G; - unsigned char R; - unsigned char X; - - static void readColor(gl::ColorF *dst, const B8G8R8X8 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorUI *dst, const B8G8R8X8 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = 1; - } - - static void writeColor(B8G8R8X8 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - dst->G = gl::floatToNormalized(src->green); - dst->B = gl::floatToNormalized(src->blue); - dst->X = 255; - } - - static void writeColor(B8G8R8X8 *dst, const gl::ColorUI *src) - { - dst->R = static_cast(src->red); - dst->G = static_cast(src->green); - dst->B = static_cast(src->blue); - dst->X = 255; - } - - static void average(B8G8R8X8 *dst, const B8G8R8X8 *src1, const B8G8R8X8 *src2) - { - *(unsigned int*)dst = (((*(unsigned int*)src1 ^ *(unsigned int*)src2) & 0xFEFEFEFE) >> 1) + (*(unsigned int*)src1 & *(unsigned int*)src2); - dst->X = 255; - } -}; - -struct A1R5G5B5 -{ - unsigned short ARGB; - - static void readColor(gl::ColorF *dst, const A1R5G5B5 *src) - { - dst->alpha = gl::normalizedToFloat<1>(gl::getShiftedData<1, 15>(src->ARGB)); - dst->red = gl::normalizedToFloat<5>(gl::getShiftedData<5, 10>(src->ARGB)); - dst->green = gl::normalizedToFloat<5>(gl::getShiftedData<5, 5>(src->ARGB)); - dst->blue = gl::normalizedToFloat<5>(gl::getShiftedData<5, 0>(src->ARGB)); - } - - static void writeColor(A1R5G5B5 *dst, const gl::ColorF *src) - { - dst->ARGB = gl::shiftData<1, 15>(gl::floatToNormalized<1, unsigned short>(src->alpha)) | - gl::shiftData<5, 10>(gl::floatToNormalized<5, unsigned short>(src->red)) | - gl::shiftData<5, 5>(gl::floatToNormalized<5, unsigned short>(src->green)) | - gl::shiftData<5, 0>(gl::floatToNormalized<5, unsigned short>(src->blue)); - } - - static void average(A1R5G5B5 *dst, const A1R5G5B5 *src1, const A1R5G5B5 *src2) - { - dst->ARGB = gl::shiftData<1, 15>(gl::average(gl::getShiftedData<1, 15>(src1->ARGB), gl::getShiftedData<1, 15>(src2->ARGB))) | - gl::shiftData<5, 10>(gl::average(gl::getShiftedData<5, 10>(src1->ARGB), gl::getShiftedData<5, 10>(src2->ARGB))) | - gl::shiftData<5, 5>(gl::average(gl::getShiftedData<5, 5>(src1->ARGB), gl::getShiftedData<5, 5>(src2->ARGB))) | - gl::shiftData<5, 0>(gl::average(gl::getShiftedData<5, 0>(src1->ARGB), gl::getShiftedData<5, 0>(src2->ARGB))); - } -}; - -struct R5G5B5A1 -{ - // OpenGL ES 2.0.25 spec Section 3.6.2: "Components are packed with the first component in the most significant - // bits of the bitfield, and successive component occupying progressively less significant locations" - unsigned short RGBA; - - static void readColor(gl::ColorF *dst, const R5G5B5A1 *src) - { - dst->red = gl::normalizedToFloat<5>(gl::getShiftedData<5, 11>(src->RGBA)); - dst->green = gl::normalizedToFloat<5>(gl::getShiftedData<5, 6>(src->RGBA)); - dst->blue = gl::normalizedToFloat<5>(gl::getShiftedData<5, 1>(src->RGBA)); - dst->alpha = gl::normalizedToFloat<1>(gl::getShiftedData<1, 0>(src->RGBA)); - } - - static void writeColor(R5G5B5A1 *dst, const gl::ColorF *src) - { - dst->RGBA = gl::shiftData<5, 11>(gl::floatToNormalized<5, unsigned short>(src->red)) | - gl::shiftData<5, 6>(gl::floatToNormalized<5, unsigned short>(src->green)) | - gl::shiftData<5, 1>(gl::floatToNormalized<5, unsigned short>(src->blue)) | - gl::shiftData<1, 0>(gl::floatToNormalized<1, unsigned short>(src->alpha)); - } - - static void average(R5G5B5A1 *dst, const R5G5B5A1 *src1, const R5G5B5A1 *src2) - { - dst->RGBA = gl::shiftData<5, 11>(gl::average(gl::getShiftedData<5, 11>(src1->RGBA), gl::getShiftedData<5, 11>(src2->RGBA))) | - gl::shiftData<5, 6>(gl::average(gl::getShiftedData<5, 6>(src1->RGBA), gl::getShiftedData<5, 6>(src2->RGBA))) | - gl::shiftData<5, 1>(gl::average(gl::getShiftedData<5, 1>(src1->RGBA), gl::getShiftedData<5, 1>(src2->RGBA))) | - gl::shiftData<1, 0>(gl::average(gl::getShiftedData<1, 0>(src1->RGBA), gl::getShiftedData<1, 0>(src2->RGBA))); - } -}; - -struct R4G4B4A4 -{ - // OpenGL ES 2.0.25 spec Section 3.6.2: "Components are packed with the first component in the most significant - // bits of the bitfield, and successive component occupying progressively less significant locations" - unsigned short RGBA; - - static void readColor(gl::ColorF *dst, const R4G4B4A4 *src) - { - dst->red = gl::normalizedToFloat<4>(gl::getShiftedData<4, 12>(src->RGBA)); - dst->green = gl::normalizedToFloat<4>(gl::getShiftedData<4, 8>(src->RGBA)); - dst->blue = gl::normalizedToFloat<4>(gl::getShiftedData<4, 4>(src->RGBA)); - dst->alpha = gl::normalizedToFloat<4>(gl::getShiftedData<4, 0>(src->RGBA)); - } - - static void writeColor(R4G4B4A4 *dst, const gl::ColorF *src) - { - dst->RGBA = gl::shiftData<4, 12>(gl::floatToNormalized<4, unsigned short>(src->red)) | - gl::shiftData<4, 8>(gl::floatToNormalized<4, unsigned short>(src->green)) | - gl::shiftData<4, 4>(gl::floatToNormalized<4, unsigned short>(src->blue)) | - gl::shiftData<4, 0>(gl::floatToNormalized<4, unsigned short>(src->alpha)); - } - - static void average(R4G4B4A4 *dst, const R4G4B4A4 *src1, const R4G4B4A4 *src2) - { - dst->RGBA = gl::shiftData<4, 12>(gl::average(gl::getShiftedData<4, 12>(src1->RGBA), gl::getShiftedData<4, 12>(src2->RGBA))) | - gl::shiftData<4, 8>(gl::average(gl::getShiftedData<4, 8>(src1->RGBA), gl::getShiftedData<4, 8>(src2->RGBA))) | - gl::shiftData<4, 4>(gl::average(gl::getShiftedData<4, 4>(src1->RGBA), gl::getShiftedData<4, 4>(src2->RGBA))) | - gl::shiftData<4, 0>(gl::average(gl::getShiftedData<4, 0>(src1->RGBA), gl::getShiftedData<4, 0>(src2->RGBA))); - } -}; - -struct A4R4G4B4 -{ - unsigned short ARGB; - - static void readColor(gl::ColorF *dst, const A4R4G4B4 *src) - { - dst->alpha = gl::normalizedToFloat<4>(gl::getShiftedData<4, 12>(src->ARGB)); - dst->red = gl::normalizedToFloat<4>(gl::getShiftedData<4, 8>(src->ARGB)); - dst->green = gl::normalizedToFloat<4>(gl::getShiftedData<4, 4>(src->ARGB)); - dst->blue = gl::normalizedToFloat<4>(gl::getShiftedData<4, 0>(src->ARGB)); - } - - static void writeColor(A4R4G4B4 *dst, const gl::ColorF *src) - { - dst->ARGB = gl::shiftData<4, 12>(gl::floatToNormalized<4, unsigned short>(src->alpha)) | - gl::shiftData<4, 8>(gl::floatToNormalized<4, unsigned short>(src->red)) | - gl::shiftData<4, 4>(gl::floatToNormalized<4, unsigned short>(src->green)) | - gl::shiftData<4, 0>(gl::floatToNormalized<4, unsigned short>(src->blue)); - } - - static void average(A4R4G4B4 *dst, const A4R4G4B4 *src1, const A4R4G4B4 *src2) - { - dst->ARGB = gl::shiftData<4, 12>(gl::average(gl::getShiftedData<4, 12>(src1->ARGB), gl::getShiftedData<4, 12>(src2->ARGB))) | - gl::shiftData<4, 8>(gl::average(gl::getShiftedData<4, 8>(src1->ARGB), gl::getShiftedData<4, 8>(src2->ARGB))) | - gl::shiftData<4, 4>(gl::average(gl::getShiftedData<4, 4>(src1->ARGB), gl::getShiftedData<4, 4>(src2->ARGB))) | - gl::shiftData<4, 0>(gl::average(gl::getShiftedData<4, 0>(src1->ARGB), gl::getShiftedData<4, 0>(src2->ARGB))); - } -}; - -struct R16 -{ - unsigned short R; - - static void readColor(gl::ColorF *dst, const R16 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = 0.0f; - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorUI *dst, const R16 *src) - { - dst->red = src->R; - dst->green = 0; - dst->blue = 0; - dst->alpha = 1; - } - - static void writeColor(R16 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - } - - static void writeColor(R16 *dst, const gl::ColorUI *src) - { - dst->R = static_cast(src->red); - } - - static void average(R16 *dst, const R16 *src1, const R16 *src2) - { - dst->R = gl::average(src1->R, src2->R); - } -}; - -struct R16G16 -{ - unsigned short R; - unsigned short G; - - static void readColor(gl::ColorF *dst, const R16G16 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorUI *dst, const R16G16 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = 0; - dst->alpha = 1; - } - - static void writeColor(R16G16 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - dst->G = gl::floatToNormalized(src->green); - } - - static void writeColor(R16G16 *dst, const gl::ColorUI *src) - { - dst->R = static_cast(src->red); - dst->G = static_cast(src->green); - } - - static void average(R16G16 *dst, const R16G16 *src1, const R16G16 *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - } -}; - -struct R16G16B16 -{ - unsigned short R; - unsigned short G; - unsigned short B; - - static void readColor(gl::ColorF *dst, const R16G16B16 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorUI *dst, const R16G16B16 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = 1; - } - - static void writeColor(R16G16B16 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - dst->G = gl::floatToNormalized(src->green); - dst->B = gl::floatToNormalized(src->blue); - } - - static void writeColor(R16G16B16 *dst, const gl::ColorUI *src) - { - dst->R = static_cast(src->red); - dst->G = static_cast(src->green); - dst->B = static_cast(src->blue); - } - - static void average(R16G16B16 *dst, const R16G16B16 *src1, const R16G16B16 *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - } -}; - -struct R16G16B16A16 -{ - unsigned short R; - unsigned short G; - unsigned short B; - unsigned short A; - - static void readColor(gl::ColorF *dst, const R16G16B16A16 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = gl::normalizedToFloat(src->A); - } - - static void readColor(gl::ColorUI *dst, const R16G16B16A16 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = src->A; - } - - static void writeColor(R16G16B16A16 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - dst->G = gl::floatToNormalized(src->green); - dst->B = gl::floatToNormalized(src->blue); - dst->A = gl::floatToNormalized(src->alpha); - } - - static void writeColor(R16G16B16A16 *dst, const gl::ColorUI *src) - { - dst->R = static_cast(src->red); - dst->G = static_cast(src->green); - dst->B = static_cast(src->blue); - dst->A = static_cast(src->alpha); - } - - static void average(R16G16B16A16 *dst, const R16G16B16A16 *src1, const R16G16B16A16 *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - dst->A = gl::average(src1->A, src2->A); - } -}; - -struct R32 -{ - unsigned int R; - - static void readColor(gl::ColorF *dst, const R32 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = 0.0f; - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorUI *dst, const R32 *src) - { - dst->red = src->R; - dst->green = 0; - dst->blue = 0; - dst->alpha = 1; - } - - static void writeColor(R32 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - } - - static void writeColor(R32 *dst, const gl::ColorUI *src) - { - dst->R = static_cast(src->red); - } - - static void average(R32 *dst, const R32 *src1, const R32 *src2) - { - dst->R = gl::average(src1->R, src2->R); - } -}; - -struct R32G32 -{ - unsigned int R; - unsigned int G; - - static void readColor(gl::ColorF *dst, const R32G32 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorUI *dst, const R32G32 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = 0; - dst->alpha = 1; - } - - static void writeColor(R32G32 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - dst->G = gl::floatToNormalized(src->green); - } - - static void writeColor(R32G32 *dst, const gl::ColorUI *src) - { - dst->R = static_cast(src->red); - dst->G = static_cast(src->green); - } - - static void average(R32G32 *dst, const R32G32 *src1, const R32G32 *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - } -}; - -struct R32G32B32 -{ - unsigned int R; - unsigned int G; - unsigned int B; - - static void readColor(gl::ColorF *dst, const R32G32B32 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorUI *dst, const R32G32B32 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = 1; - } - - static void writeColor(R32G32B32 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - dst->G = gl::floatToNormalized(src->green); - dst->B = gl::floatToNormalized(src->blue); - } - - static void writeColor(R32G32B32 *dst, const gl::ColorUI *src) - { - dst->R = static_cast(src->red); - dst->G = static_cast(src->green); - dst->B = static_cast(src->blue); - } - - static void average(R32G32B32 *dst, const R32G32B32 *src1, const R32G32B32 *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - } -}; - -struct R32G32B32A32 -{ - unsigned int R; - unsigned int G; - unsigned int B; - unsigned int A; - - static void readColor(gl::ColorF *dst, const R32G32B32A32 *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = gl::normalizedToFloat(src->A); - } - - static void readColor(gl::ColorUI *dst, const R32G32B32A32 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = src->A; - } - - static void writeColor(R32G32B32A32 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - dst->G = gl::floatToNormalized(src->green); - dst->B = gl::floatToNormalized(src->blue); - dst->A = gl::floatToNormalized(src->alpha); - } - - static void writeColor(R32G32B32A32 *dst, const gl::ColorUI *src) - { - dst->R = static_cast(src->red); - dst->G = static_cast(src->green); - dst->B = static_cast(src->blue); - dst->A = static_cast(src->alpha); - } - - static void average(R32G32B32A32 *dst, const R32G32B32A32 *src1, const R32G32B32A32 *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - dst->A = gl::average(src1->A, src2->A); - } -}; - -struct R8S -{ - char R; - - static void readColor(gl::ColorF *dst, const R8S *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = 0.0f; - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorI *dst, const R8S *src) - { - dst->red = src->R; - dst->green = 0; - dst->blue = 0; - dst->alpha = 1; - } - - static void writeColor(R8S *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - } - - static void writeColor(R8S *dst, const gl::ColorI *src) - { - dst->R = static_cast(src->red); - } - - static void average(R8S *dst, const R8S *src1, const R8S *src2) - { - dst->R = static_cast(gl::average(src1->R, src2->R)); - } -}; - -struct R8G8S -{ - char R; - char G; - - static void readColor(gl::ColorF *dst, const R8G8S *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorI *dst, const R8G8S *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = 0; - dst->alpha = 1; - } - - static void writeColor(R8G8S *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - dst->G = gl::floatToNormalized(src->green); - } - - static void writeColor(R8G8S *dst, const gl::ColorI *src) - { - dst->R = static_cast(src->red); - dst->G = static_cast(src->green); - } - - static void average(R8G8S *dst, const R8G8S *src1, const R8G8S *src2) - { - dst->R = static_cast(gl::average(src1->R, src2->R)); - dst->G = static_cast(gl::average(src1->G, src2->G)); - } -}; - -struct R8G8B8S -{ - char R; - char G; - char B; - - static void readColor(gl::ColorF *dst, const R8G8B8S *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorI *dst, const R8G8B8S *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = 1; - } - - static void writeColor(R8G8B8S *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - dst->G = gl::floatToNormalized(src->green); - dst->B = gl::floatToNormalized(src->blue); - } - - static void writeColor(R8G8B8S *dst, const gl::ColorI *src) - { - dst->R = static_cast(src->red); - dst->G = static_cast(src->green); - dst->B = static_cast(src->blue); - } - - static void average(R8G8B8S *dst, const R8G8B8S *src1, const R8G8B8S *src2) - { - dst->R = static_cast(gl::average(src1->R, src2->R)); - dst->G = static_cast(gl::average(src1->G, src2->G)); - dst->B = static_cast(gl::average(src1->B, src2->B)); - } -}; - -struct R8G8B8A8S -{ - char R; - char G; - char B; - char A; - - static void readColor(gl::ColorF *dst, const R8G8B8A8S *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = gl::normalizedToFloat(src->A); - } - - static void readColor(gl::ColorI *dst, const R8G8B8A8S *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = src->A; - } - - static void writeColor(R8G8B8A8S *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - dst->G = gl::floatToNormalized(src->green); - dst->B = gl::floatToNormalized(src->blue); - dst->A = gl::floatToNormalized(src->alpha); - } - - static void writeColor(R8G8B8A8S *dst, const gl::ColorI *src) - { - dst->R = static_cast(src->red); - dst->G = static_cast(src->green); - dst->B = static_cast(src->blue); - dst->A = static_cast(src->alpha); - } - - static void average(R8G8B8A8S *dst, const R8G8B8A8S *src1, const R8G8B8A8S *src2) - { - dst->R = static_cast(gl::average(src1->R, src2->R)); - dst->G = static_cast(gl::average(src1->G, src2->G)); - dst->B = static_cast(gl::average(src1->B, src2->B)); - dst->A = static_cast(gl::average(src1->A, src2->A)); - } -}; - -struct R16S -{ - short R; - - static void readColor(gl::ColorF *dst, const R16S *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = 0.0f; - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorI *dst, const R16S *src) - { - dst->red = src->R; - dst->green = 0; - dst->blue = 0; - dst->alpha = 1; - } - - static void writeColor(R16S *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - } - - static void writeColor(R16S *dst, const gl::ColorI *src) - { - dst->R = static_cast(src->red); - } - - static void average(R16S *dst, const R16S *src1, const R16S *src2) - { - dst->R = gl::average(src1->R, src2->R); - } -}; - -struct R16G16S -{ - short R; - short G; - - static void readColor(gl::ColorF *dst, const R16G16S *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorI *dst, const R16G16S *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = 0; - dst->alpha = 1; - } - - static void writeColor(R16G16S *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - dst->G = gl::floatToNormalized(src->green); - } - - static void writeColor(R16G16S *dst, const gl::ColorI *src) - { - dst->R = static_cast(src->red); - dst->G = static_cast(src->green); - } - - static void average(R16G16S *dst, const R16G16S *src1, const R16G16S *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - } -}; - -struct R16G16B16S -{ - short R; - short G; - short B; - - static void readColor(gl::ColorF *dst, const R16G16B16S *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorI *dst, const R16G16B16S *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = 1; - } - - static void writeColor(R16G16B16S *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - dst->G = gl::floatToNormalized(src->green); - dst->B = gl::floatToNormalized(src->blue); - } - - static void writeColor(R16G16B16S *dst, const gl::ColorI *src) - { - dst->R = static_cast(src->red); - dst->G = static_cast(src->green); - dst->B = static_cast(src->blue); - } - - static void average(R16G16B16S *dst, const R16G16B16S *src1, const R16G16B16S *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - } -}; - -struct R16G16B16A16S -{ - short R; - short G; - short B; - short A; - - static void readColor(gl::ColorF *dst, const R16G16B16A16S *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = gl::normalizedToFloat(src->A); - } - - static void readColor(gl::ColorI *dst, const R16G16B16A16S *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = src->A; - } - - static void writeColor(R16G16B16A16S *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - dst->G = gl::floatToNormalized(src->green); - dst->B = gl::floatToNormalized(src->blue); - dst->A = gl::floatToNormalized(src->alpha); - } - - static void writeColor(R16G16B16A16S *dst, const gl::ColorI *src) - { - dst->R = static_cast(src->red); - dst->G = static_cast(src->green); - dst->B = static_cast(src->blue); - dst->A = static_cast(src->alpha); - } - - static void average(R16G16B16A16S *dst, const R16G16B16A16S *src1, const R16G16B16A16S *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - dst->A = gl::average(src1->A, src2->A); - } -}; - -struct R32S -{ - int R; - - static void readColor(gl::ColorF *dst, const R32S *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = 0.0f; - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorI *dst, const R32S *src) - { - dst->red = src->R; - dst->green = 0; - dst->blue = 0; - dst->alpha = 1; - } - - static void writeColor(R32S *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - } - - static void writeColor(R32S *dst, const gl::ColorI *src) - { - dst->R = static_cast(src->red); - } - - static void average(R32S *dst, const R32S *src1, const R32S *src2) - { - dst->R = gl::average(src1->R, src2->R); - } -}; - -struct R32G32S -{ - int R; - int G; - - static void readColor(gl::ColorF *dst, const R32G32S *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorI *dst, const R32G32S *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = 0; - dst->alpha = 1; - } - - static void writeColor(R32G32S *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - dst->G = gl::floatToNormalized(src->green); - } - - static void writeColor(R32G32S *dst, const gl::ColorI *src) - { - dst->R = static_cast(src->red); - dst->G = static_cast(src->green); - } - - static void average(R32G32S *dst, const R32G32S *src1, const R32G32S *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - } -}; - -struct R32G32B32S -{ - int R; - int G; - int B; - - static void readColor(gl::ColorF *dst, const R32G32B32S *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = 1.0f; - } - - static void readColor(gl::ColorI *dst, const R32G32B32S *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = 1; - } - - static void writeColor(R32G32B32S *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - dst->G = gl::floatToNormalized(src->green); - dst->B = gl::floatToNormalized(src->blue); - } - - static void writeColor(R32G32B32S *dst, const gl::ColorI *src) - { - dst->R = static_cast(src->red); - dst->G = static_cast(src->green); - dst->B = static_cast(src->blue); - } - - static void average(R32G32B32S *dst, const R32G32B32S *src1, const R32G32B32S *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - } -}; - -struct R32G32B32A32S -{ - int R; - int G; - int B; - int A; - - static void readColor(gl::ColorF *dst, const R32G32B32A32S *src) - { - dst->red = gl::normalizedToFloat(src->R); - dst->green = gl::normalizedToFloat(src->G); - dst->blue = gl::normalizedToFloat(src->B); - dst->alpha = gl::normalizedToFloat(src->A); - } - - static void readColor(gl::ColorI *dst, const R32G32B32A32S *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = src->A; - } - - static void writeColor(R32G32B32A32S *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized(src->red); - dst->G = gl::floatToNormalized(src->green); - dst->B = gl::floatToNormalized(src->blue); - dst->A = gl::floatToNormalized(src->alpha); - } - - static void writeColor(R32G32B32A32S *dst, const gl::ColorI *src) - { - dst->R = static_cast(src->red); - dst->G = static_cast(src->green); - dst->B = static_cast(src->blue); - dst->A = static_cast(src->alpha); - } - - static void average(R32G32B32A32S *dst, const R32G32B32A32S *src1, const R32G32B32A32S *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - dst->A = gl::average(src1->A, src2->A); - } -}; - -struct A16B16G16R16F -{ - unsigned short A; - unsigned short R; - unsigned short G; - unsigned short B; - - static void readColor(gl::ColorF *dst, const A16B16G16R16F *src) - { - dst->red = gl::float16ToFloat32(src->R); - dst->green = gl::float16ToFloat32(src->G); - dst->blue = gl::float16ToFloat32(src->B); - dst->alpha = gl::float16ToFloat32(src->A); - } - - static void writeColor(A16B16G16R16F *dst, const gl::ColorF *src) - { - dst->R = gl::float32ToFloat16(src->red); - dst->G = gl::float32ToFloat16(src->green); - dst->B = gl::float32ToFloat16(src->blue); - dst->A = gl::float32ToFloat16(src->alpha); - } - - static void average(A16B16G16R16F *dst, const A16B16G16R16F *src1, const A16B16G16R16F *src2) - { - dst->R = gl::averageHalfFloat(src1->R, src2->R); - dst->G = gl::averageHalfFloat(src1->G, src2->G); - dst->B = gl::averageHalfFloat(src1->B, src2->B); - dst->A = gl::averageHalfFloat(src1->A, src2->A); - } -}; - -struct R16G16B16A16F -{ - unsigned short R; - unsigned short G; - unsigned short B; - unsigned short A; - - static void readColor(gl::ColorF *dst, const R16G16B16A16F *src) - { - dst->red = gl::float16ToFloat32(src->R); - dst->green = gl::float16ToFloat32(src->G); - dst->blue = gl::float16ToFloat32(src->B); - dst->alpha = gl::float16ToFloat32(src->A); - } - - static void writeColor(R16G16B16A16F *dst, const gl::ColorF *src) - { - dst->R = gl::float32ToFloat16(src->red); - dst->G = gl::float32ToFloat16(src->green); - dst->B = gl::float32ToFloat16(src->blue); - dst->A = gl::float32ToFloat16(src->alpha); - } - - static void average(R16G16B16A16F *dst, const R16G16B16A16F *src1, const R16G16B16A16F *src2) - { - dst->R = gl::averageHalfFloat(src1->R, src2->R); - dst->G = gl::averageHalfFloat(src1->G, src2->G); - dst->B = gl::averageHalfFloat(src1->B, src2->B); - dst->A = gl::averageHalfFloat(src1->A, src2->A); - } -}; - -struct R16F -{ - unsigned short R; - - static void readColor(gl::ColorF *dst, const R16F *src) - { - dst->red = gl::float16ToFloat32(src->R); - dst->green = 0.0f; - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void writeColor(R16F *dst, const gl::ColorF *src) - { - dst->R = gl::float32ToFloat16(src->red); - } - - static void average(R16F *dst, const R16F *src1, const R16F *src2) - { - dst->R = gl::averageHalfFloat(src1->R, src2->R); - } -}; - -struct A16F -{ - unsigned short A; - - static void readColor(gl::ColorF *dst, const A16F *src) - { - dst->red = 0.0f; - dst->green = 0.0f; - dst->blue = 0.0f; - dst->alpha = gl::float16ToFloat32(src->A); - } - - static void writeColor(A16F *dst, const gl::ColorF *src) - { - dst->A = gl::float32ToFloat16(src->alpha); - } - - static void average(A16F *dst, const A16F *src1, const A16F *src2) - { - dst->A = gl::averageHalfFloat(src1->A, src2->A); - } -}; - -struct L16F -{ - unsigned short L; - - static void readColor(gl::ColorF *dst, const L16F *src) - { - float lum = gl::float16ToFloat32(src->L); - dst->red = lum; - dst->green = lum; - dst->blue = lum; - dst->alpha = 1.0f; - } - - static void writeColor(L16F *dst, const gl::ColorF *src) - { - dst->L = gl::float32ToFloat16((src->red + src->green + src->blue) / 3.0f); - } - - static void average(L16F *dst, const L16F *src1, const L16F *src2) - { - dst->L = gl::averageHalfFloat(src1->L, src2->L); - } -}; - -struct L16A16F -{ - unsigned short L; - unsigned short A; - - static void readColor(gl::ColorF *dst, const L16A16F *src) - { - float lum = gl::float16ToFloat32(src->L); - dst->red = lum; - dst->green = lum; - dst->blue = lum; - dst->alpha = gl::float16ToFloat32(src->A); - } - - static void writeColor(L16A16F *dst, const gl::ColorF *src) - { - dst->L = gl::float32ToFloat16((src->red + src->green + src->blue) / 3.0f); - dst->A = gl::float32ToFloat16(src->alpha); - } - - static void average(L16A16F *dst, const L16A16F *src1, const L16A16F *src2) - { - dst->L = gl::averageHalfFloat(src1->L, src2->L); - dst->A = gl::averageHalfFloat(src1->A, src2->A); - } -}; - -struct R16G16F -{ - unsigned short R; - unsigned short G; - - static void readColor(gl::ColorF *dst, const R16G16F *src) - { - dst->red = gl::float16ToFloat32(src->R); - dst->green = gl::float16ToFloat32(src->G); - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void writeColor(R16G16F *dst, const gl::ColorF *src) - { - dst->R = gl::float32ToFloat16(src->red); - dst->G = gl::float32ToFloat16(src->green); - } - - static void average(R16G16F *dst, const R16G16F *src1, const R16G16F *src2) - { - dst->R = gl::averageHalfFloat(src1->R, src2->R); - dst->G = gl::averageHalfFloat(src1->G, src2->G); - } -}; - -struct R16G16B16F -{ - unsigned short R; - unsigned short G; - unsigned short B; - - static void readColor(gl::ColorF *dst, const R16G16B16F *src) - { - dst->red = gl::float16ToFloat32(src->R); - dst->green = gl::float16ToFloat32(src->G); - dst->blue = gl::float16ToFloat32(src->B); - dst->alpha = 1.0f; - } - - static void writeColor(R16G16B16F *dst, const gl::ColorF *src) - { - dst->R = gl::float32ToFloat16(src->red); - dst->G = gl::float32ToFloat16(src->green); - dst->B = gl::float32ToFloat16(src->blue); - } - - static void average(R16G16B16F *dst, const R16G16B16F *src1, const R16G16B16F *src2) - { - dst->R = gl::averageHalfFloat(src1->R, src2->R); - dst->G = gl::averageHalfFloat(src1->G, src2->G); - dst->B = gl::averageHalfFloat(src1->B, src2->B); - } -}; - -struct A32B32G32R32F -{ - float A; - float R; - float G; - float B; - - static void readColor(gl::ColorF *dst, const A32B32G32R32F *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = src->A; - } - - static void writeColor(A32B32G32R32F *dst, const gl::ColorF *src) - { - dst->R = src->red; - dst->G = src->green; - dst->B = src->blue; - dst->A = src->alpha; - } - - static void average(A32B32G32R32F *dst, const A32B32G32R32F *src1, const A32B32G32R32F *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - dst->A = gl::average(src1->A, src2->A); - } -}; - -struct R32G32B32A32F -{ - float R; - float G; - float B; - float A; - - static void readColor(gl::ColorF *dst, const R32G32B32A32F *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = src->A; - } - - static void writeColor(R32G32B32A32F *dst, const gl::ColorF *src) - { - dst->R = src->red; - dst->G = src->green; - dst->B = src->blue; - dst->A = src->alpha; - } - - static void average(R32G32B32A32F *dst, const R32G32B32A32F *src1, const R32G32B32A32F *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - dst->A = gl::average(src1->A, src2->A); - } -}; - -struct R32F -{ - float R; - - static void readColor(gl::ColorF *dst, const R32F *src) - { - dst->red = src->R; - dst->green = 0.0f; - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void writeColor(R32F *dst, const gl::ColorF *src) - { - dst->R = src->red; - } - - static void average(R32F *dst, const R32F *src1, const R32F *src2) - { - dst->R = gl::average(src1->R, src2->R); - } -}; - -struct A32F -{ - float A; - - static void readColor(gl::ColorF *dst, const A32F *src) - { - dst->red = 0.0f; - dst->green = 0.0f; - dst->blue = 0.0f; - dst->alpha = src->A; - } - - static void writeColor(A32F *dst, const gl::ColorF *src) - { - dst->A = src->alpha; - } - - static void average(A32F *dst, const A32F *src1, const A32F *src2) - { - dst->A = gl::average(src1->A, src2->A); - } -}; - -struct L32F -{ - float L; - - static void readColor(gl::ColorF *dst, const L32F *src) - { - dst->red = src->L; - dst->green = src->L; - dst->blue = src->L; - dst->alpha = 1.0f; - } - - static void writeColor(L32F *dst, const gl::ColorF *src) - { - dst->L = (src->red + src->green + src->blue) / 3.0f; - } - - static void average(L32F *dst, const L32F *src1, const L32F *src2) - { - dst->L = gl::average(src1->L, src2->L); - } -}; - -struct L32A32F -{ - float L; - float A; - - static void readColor(gl::ColorF *dst, const L32A32F *src) - { - dst->red = src->L; - dst->green = src->L; - dst->blue = src->L; - dst->alpha = src->A; - } - - static void writeColor(L32A32F *dst, const gl::ColorF *src) - { - dst->L = (src->red + src->green + src->blue) / 3.0f; - dst->A = src->alpha; - } - - static void average(L32A32F *dst, const L32A32F *src1, const L32A32F *src2) - { - dst->L = gl::average(src1->L, src2->L); - dst->A = gl::average(src1->A, src2->A); - } -}; - -struct R32G32F -{ - float R; - float G; - - static void readColor(gl::ColorF *dst, const R32G32F *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = 0.0f; - dst->alpha = 1.0f; - } - - static void writeColor(R32G32F *dst, const gl::ColorF *src) - { - dst->R = src->red; - dst->G = src->green; - } - - static void average(R32G32F *dst, const R32G32F *src1, const R32G32F *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - } -}; - -struct R32G32B32F -{ - float R; - float G; - float B; - - static void readColor(gl::ColorF *dst, const R32G32B32F *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = 1.0f; - } - - static void writeColor(R32G32B32F *dst, const gl::ColorF *src) - { - dst->R = src->red; - dst->G = src->green; - dst->B = src->blue; - } - - static void average(R32G32B32F *dst, const R32G32B32F *src1, const R32G32B32F *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - } -}; - -struct R10G10B10A2 -{ - unsigned int R : 10; - unsigned int G : 10; - unsigned int B : 10; - unsigned int A : 2; - - static void readColor(gl::ColorF *dst, const R10G10B10A2 *src) - { - dst->red = gl::normalizedToFloat<10>(src->R); - dst->green = gl::normalizedToFloat<10>(src->G); - dst->blue = gl::normalizedToFloat<10>(src->B); - dst->alpha = gl::normalizedToFloat< 2>(src->A); - } - - static void readColor(gl::ColorUI *dst, const R10G10B10A2 *src) - { - dst->red = src->R; - dst->green = src->G; - dst->blue = src->B; - dst->alpha = src->A; - } - - static void writeColor(R10G10B10A2 *dst, const gl::ColorF *src) - { - dst->R = gl::floatToNormalized<10, unsigned int>(src->red); - dst->G = gl::floatToNormalized<10, unsigned int>(src->green); - dst->B = gl::floatToNormalized<10, unsigned int>(src->blue); - dst->A = gl::floatToNormalized< 2, unsigned int>(src->alpha); - } - - static void writeColor(R10G10B10A2 *dst, const gl::ColorUI *src) - { - dst->R = static_cast(src->red); - dst->G = static_cast(src->green); - dst->B = static_cast(src->blue); - dst->A = static_cast(src->alpha); - } - - static void average(R10G10B10A2 *dst, const R10G10B10A2 *src1, const R10G10B10A2 *src2) - { - dst->R = gl::average(src1->R, src2->R); - dst->G = gl::average(src1->G, src2->G); - dst->B = gl::average(src1->B, src2->B); - dst->A = gl::average(src1->A, src2->A); - } -}; - -struct R9G9B9E5 -{ - unsigned int R : 9; - unsigned int G : 9; - unsigned int B : 9; - unsigned int E : 5; - - static void readColor(gl::ColorF *dst, const R9G9B9E5 *src) - { - gl::convert999E5toRGBFloats(gl::bitCast(*src), &dst->red, &dst->green, &dst->blue); - dst->alpha = 1.0f; - } - - static void writeColor(R9G9B9E5 *dst, const gl::ColorF *src) - { - *reinterpret_cast(dst) = gl::convertRGBFloatsTo999E5(src->red, - src->green, - src->blue); - } - - static void average(R9G9B9E5 *dst, const R9G9B9E5 *src1, const R9G9B9E5 *src2) - { - float r1, g1, b1; - gl::convert999E5toRGBFloats(*reinterpret_cast(src1), &r1, &g1, &b1); - - float r2, g2, b2; - gl::convert999E5toRGBFloats(*reinterpret_cast(src2), &r2, &g2, &b2); - - *reinterpret_cast(dst) = gl::convertRGBFloatsTo999E5(gl::average(r1, r2), - gl::average(g1, g2), - gl::average(b1, b2)); - } -}; - -struct R11G11B10F -{ - unsigned int R : 11; - unsigned int G : 11; - unsigned int B : 10; - - static void readColor(gl::ColorF *dst, const R11G11B10F *src) - { - dst->red = gl::float11ToFloat32(src->R); - dst->green = gl::float11ToFloat32(src->G); - dst->blue = gl::float10ToFloat32(src->B); - dst->alpha = 1.0f; - } - - static void writeColor(R11G11B10F *dst, const gl::ColorF *src) - { - dst->R = gl::float32ToFloat11(src->red); - dst->G = gl::float32ToFloat11(src->green); - dst->B = gl::float32ToFloat10(src->blue); - } - - static void average(R11G11B10F *dst, const R11G11B10F *src1, const R11G11B10F *src2) - { - dst->R = gl::averageFloat11(src1->R, src2->R); - dst->G = gl::averageFloat11(src1->G, src2->G); - dst->B = gl::averageFloat10(src1->B, src2->B); - } -}; - -} - -#endif // LIBANGLE_RENDERER_D3D_IMAGEFORMATS_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage.cpp deleted file mode 100644 index b9b9e5e4ab..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage.cpp +++ /dev/null @@ -1,697 +0,0 @@ -// -// Copyright (c) 2013-2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// loadimage.cpp: Defines image loading functions. - -#include "libANGLE/renderer/d3d/loadimage.h" - -namespace rx -{ - -void LoadA8ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint8_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint32_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[x] = static_cast(source[x]) << 24; - } - } - } -} - -void LoadA8ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - // Same as loading to RGBA - LoadA8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch); -} - -void LoadA32FToRGBA32F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const float *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - float *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[4 * x + 0] = 0.0f; - dest[4 * x + 1] = 0.0f; - dest[4 * x + 2] = 0.0f; - dest[4 * x + 3] = source[x]; - } - } - } -} - -void LoadA16FToRGBA16F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint16_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[4 * x + 0] = 0; - dest[4 * x + 1] = 0; - dest[4 * x + 2] = 0; - dest[4 * x + 3] = source[x]; - } - } - } -} - -void LoadL8ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint8_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - uint8_t sourceVal = source[x]; - dest[4 * x + 0] = sourceVal; - dest[4 * x + 1] = sourceVal; - dest[4 * x + 2] = sourceVal; - dest[4 * x + 3] = 0xFF; - } - } - } -} - -void LoadL8ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - // Same as loading to RGBA - LoadL8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch); -} - -void LoadL32FToRGBA32F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const float *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - float *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[4 * x + 0] = source[x]; - dest[4 * x + 1] = source[x]; - dest[4 * x + 2] = source[x]; - dest[4 * x + 3] = 1.0f; - } - } - } -} - -void LoadL16FToRGBA16F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint16_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[4 * x + 0] = source[x]; - dest[4 * x + 1] = source[x]; - dest[4 * x + 2] = source[x]; - dest[4 * x + 3] = gl::Float16One; - } - } - } -} - -void LoadLA8ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint8_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[4 * x + 0] = source[2 * x + 0]; - dest[4 * x + 1] = source[2 * x + 0]; - dest[4 * x + 2] = source[2 * x + 0]; - dest[4 * x + 3] = source[2 * x + 1]; - } - } - } -} - -void LoadLA8ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - // Same as loading to RGBA - LoadLA8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch); -} - -void LoadLA32FToRGBA32F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const float *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - float *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[4 * x + 0] = source[2 * x + 0]; - dest[4 * x + 1] = source[2 * x + 0]; - dest[4 * x + 2] = source[2 * x + 0]; - dest[4 * x + 3] = source[2 * x + 1]; - } - } - } -} - -void LoadLA16FToRGBA16F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint16_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[4 * x + 0] = source[2 * x + 0]; - dest[4 * x + 1] = source[2 * x + 0]; - dest[4 * x + 2] = source[2 * x + 0]; - dest[4 * x + 3] = source[2 * x + 1]; - } - } - } -} - -void LoadRGB8ToBGRX8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint8_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[4 * x + 0] = source[x * 3 + 2]; - dest[4 * x + 1] = source[x * 3 + 1]; - dest[4 * x + 2] = source[x * 3 + 0]; - dest[4 * x + 3] = 0xFF; - } - } - } -} - -void LoadRG8ToBGRX8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint8_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[4 * x + 0] = 0x00; - dest[4 * x + 1] = source[x * 2 + 1]; - dest[4 * x + 2] = source[x * 2 + 0]; - dest[4 * x + 3] = 0xFF; - } - } - } -} - -void LoadR8ToBGRX8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint8_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[4 * x + 0] = 0x00; - dest[4 * x + 1] = 0x00; - dest[4 * x + 2] = source[x]; - dest[4 * x + 3] = 0xFF; - } - } - } -} - -void LoadR5G6B5ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - uint16_t rgb = source[x]; - dest[4 * x + 0] = static_cast(((rgb & 0x001F) << 3) | ((rgb & 0x001F) >> 2)); - dest[4 * x + 1] = static_cast(((rgb & 0x07E0) >> 3) | ((rgb & 0x07E0) >> 9)); - dest[4 * x + 2] = static_cast(((rgb & 0xF800) >> 8) | ((rgb & 0xF800) >> 13)); - dest[4 * x + 3] = 0xFF; - } - } - } -} - -void LoadR5G6B5ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - uint16_t rgb = source[x]; - dest[4 * x + 0] = static_cast(((rgb & 0xF800) >> 8) | ((rgb & 0xF800) >> 13)); - dest[4 * x + 1] = static_cast(((rgb & 0x07E0) >> 3) | ((rgb & 0x07E0) >> 9)); - dest[4 * x + 2] = static_cast(((rgb & 0x001F) << 3) | ((rgb & 0x001F) >> 2)); - dest[4 * x + 3] = 0xFF; - } - } - } -} - -void LoadRGBA8ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint32_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint32_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - uint32_t rgba = source[x]; - dest[x] = (ANGLE_ROTL(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00); - } - } - } -} - -void LoadRGBA4ToARGB4(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint16_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[x] = ANGLE_ROTR16(source[x], 4); - } - } - } -} - -void LoadRGBA4ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - uint16_t rgba = source[x]; - dest[4 * x + 0] = static_cast(((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4)); - dest[4 * x + 1] = static_cast(((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8)); - dest[4 * x + 2] = static_cast(((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12)); - dest[4 * x + 3] = static_cast(((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0)); - } - } - } -} - -void LoadRGBA4ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - uint16_t rgba = source[x]; - dest[4 * x + 0] = static_cast(((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12)); - dest[4 * x + 1] = static_cast(((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8)); - dest[4 * x + 2] = static_cast(((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4)); - dest[4 * x + 3] = static_cast(((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0)); - } - } - } -} - -void LoadBGRA4ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - uint16_t bgra = source[x]; - dest[4 * x + 0] = static_cast(((bgra & 0xF000) >> 8) | ((bgra & 0xF000) >> 12)); - dest[4 * x + 1] = static_cast(((bgra & 0x0F00) >> 4) | ((bgra & 0x0F00) >> 8)); - dest[4 * x + 2] = static_cast(((bgra & 0x00F0) << 0) | ((bgra & 0x00F0) >> 4)); - dest[4 * x + 3] = static_cast(((bgra & 0x000F) << 4) | ((bgra & 0x000F) >> 0)); - } - } - } -} - -void LoadRGB5A1ToA1RGB5(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint16_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[x] = ANGLE_ROTR16(source[x], 1); - } - } - } -} - -void LoadRGB5A1ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - uint16_t rgba = source[x]; - dest[4 * x + 0] = static_cast(((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3)); - dest[4 * x + 1] = static_cast(((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8)); - dest[4 * x + 2] = static_cast(((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13)); - dest[4 * x + 3] = static_cast((rgba & 0x0001) ? 0xFF : 0); - } - } - } -} - -void LoadRGB5A1ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - uint16_t rgba = source[x]; - dest[4 * x + 0] = static_cast(((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13)); - dest[4 * x + 1] = static_cast(((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8)); - dest[4 * x + 2] = static_cast(((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3)); - dest[4 * x + 3] = static_cast((rgba & 0x0001) ? 0xFF : 0); - } - } - } -} - -void LoadBGR5A1ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - uint16_t bgra = source[x]; - dest[4 * x + 0] = static_cast(((bgra & 0xF800) >> 8) | ((bgra & 0xF800) >> 13)); - dest[4 * x + 1] = static_cast(((bgra & 0x07C0) >> 3) | ((bgra & 0x07C0) >> 8)); - dest[4 * x + 2] = static_cast(((bgra & 0x003E) << 2) | ((bgra & 0x003E) >> 3)); - dest[4 * x + 3] = static_cast((bgra & 0x0001) ? 0xFF : 0); - } - } - } -} - -void LoadRGB10A2ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint32_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint8_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - uint32_t rgba = source[x]; - dest[4 * x + 0] = static_cast((rgba & 0x000003FF) >> 2); - dest[4 * x + 1] = static_cast((rgba & 0x000FFC00) >> 12); - dest[4 * x + 2] = static_cast((rgba & 0x3FF00000) >> 22); - dest[4 * x + 3] = static_cast(((rgba & 0xC0000000) >> 30) * 0x55); - } - } - } -} - -void LoadRGB16FToRGB9E5(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint32_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[x] = gl::convertRGBFloatsTo999E5(gl::float16ToFloat32(source[x * 3 + 0]), - gl::float16ToFloat32(source[x * 3 + 1]), - gl::float16ToFloat32(source[x * 3 + 2])); - } - } - } -} - -void LoadRGB32FToRGB9E5(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const float *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint32_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[x] = gl::convertRGBFloatsTo999E5(source[x * 3 + 0], source[x * 3 + 1], source[x * 3 + 2]); - } - } - } -} - -void LoadRGB16FToRG11B10F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint16_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint32_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[x] = (gl::float32ToFloat11(gl::float16ToFloat32(source[x * 3 + 0])) << 0) | - (gl::float32ToFloat11(gl::float16ToFloat32(source[x * 3 + 1])) << 11) | - (gl::float32ToFloat10(gl::float16ToFloat32(source[x * 3 + 2])) << 22); - } - } - } -} - -void LoadRGB32FToRG11B10F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const float *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint32_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[x] = (gl::float32ToFloat11(source[x * 3 + 0]) << 0) | - (gl::float32ToFloat11(source[x * 3 + 1]) << 11) | - (gl::float32ToFloat10(source[x * 3 + 2]) << 22); - } - } - } -} - -void LoadG8R24ToR24G8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint32_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint32_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - uint32_t d = source[x] >> 8; - uint8_t s = source[x] & 0xFF; - dest[x] = d | (s << 24); - } - } - } -} - -void LoadRGB32FToRGBA16F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const float *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint16_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[x * 4 + 0] = gl::float32ToFloat16(source[x * 3 + 0]); - dest[x * 4 + 1] = gl::float32ToFloat16(source[x * 3 + 1]); - dest[x * 4 + 2] = gl::float32ToFloat16(source[x * 3 + 2]); - dest[x * 4 + 3] = gl::Float16One; - } - } - } -} - -void LoadR32ToR16(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint32_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint16_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - for (size_t x = 0; x < width; x++) - { - dest[x] = source[x] >> 16; - } - } - } -} - -void LoadR32ToR24G8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint32_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint32_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - - for (size_t x = 0; x < width; x++) - { - dest[x] = source[x] >> 8; - } - } - } -} - -} diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage.h deleted file mode 100644 index 6c5118365e..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage.h +++ /dev/null @@ -1,201 +0,0 @@ -// -// Copyright (c) 2013-2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// loadimage.h: Defines image loading functions - -#ifndef LIBANGLE_RENDERER_D3D_LOADIMAGE_H_ -#define LIBANGLE_RENDERER_D3D_LOADIMAGE_H_ - -#include "libANGLE/angletypes.h" - -#include - -namespace rx -{ - -void LoadA8ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadA8ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadA32FToRGBA32F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadA16FToRGBA16F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadL8ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadL8ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadL32FToRGBA32F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadL16FToRGBA16F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadLA8ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadLA8ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadLA32FToRGBA32F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadLA16FToRGBA16F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGB8ToBGRX8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRG8ToBGRX8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadR8ToBGRX8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadR5G6B5ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadR5G6B5ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGBA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGBA8ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGBA4ToARGB4(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGBA4ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGBA4ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadBGRA4ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGB5A1ToA1RGB5(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGB5A1ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGB5A1ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadBGR5A1ToBGRA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGB10A2ToRGBA8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGB16FToRGB9E5(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGB32FToRGB9E5(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGB16FToRG11B10F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGB32FToRG11B10F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadG8R24ToR24G8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -template -inline void LoadToNative(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -template -inline void LoadToNative3To4(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -template -inline void Load32FTo16F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadRGB32FToRGBA16F(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -template -inline void LoadCompressedToNative(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadR32ToR16(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -template -inline void Initialize4ComponentData(size_t width, size_t height, size_t depth, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -void LoadR32ToR24G8(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch); - -template -inline T *OffsetDataPointer(uint8_t *data, size_t y, size_t z, size_t rowPitch, size_t depthPitch); - -template -inline const T *OffsetDataPointer(const uint8_t *data, size_t y, size_t z, size_t rowPitch, size_t depthPitch); - -} - -#include "loadimage.inl" - -#endif // LIBANGLE_RENDERER_D3D_LOADIMAGE_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimageSSE2.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimageSSE2.cpp deleted file mode 100644 index c87d35c82b..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimageSSE2.cpp +++ /dev/null @@ -1,125 +0,0 @@ -// -// Copyright (c) 2002-2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// loadimageSSE2.cpp: Defines image loading functions. It's -// in a separated file for GCC, which can enable SSE usage only per-file, -// not for code blocks that use SSE2 explicitly. - -#include "libANGLE/renderer/d3d/loadimage.h" - -#include "common/platform.h" - -#ifdef ANGLE_USE_SSE -#include -#endif - -namespace rx -{ - -void LoadA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ -#if defined(ANGLE_USE_SSE) - __m128i zeroWide = _mm_setzero_si128(); - - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint8_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint32_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - - size_t x = 0; - - // Make output writes aligned - for (; ((reinterpret_cast(&dest[x]) & 0xF) != 0 && x < width); x++) - { - dest[x] = static_cast(source[x]) << 24; - } - - for (; x + 7 < width; x += 8) - { - __m128i sourceData = _mm_loadl_epi64(reinterpret_cast(&source[x])); - // Interleave each byte to 16bit, make the lower byte to zero - sourceData = _mm_unpacklo_epi8(zeroWide, sourceData); - // Interleave each 16bit to 32bit, make the lower 16bit to zero - __m128i lo = _mm_unpacklo_epi16(zeroWide, sourceData); - __m128i hi = _mm_unpackhi_epi16(zeroWide, sourceData); - - _mm_store_si128(reinterpret_cast<__m128i*>(&dest[x]), lo); - _mm_store_si128(reinterpret_cast<__m128i*>(&dest[x + 4]), hi); - } - - // Handle the remainder - for (; x < width; x++) - { - dest[x] = static_cast(source[x]) << 24; - } - } - } -#else - // Ensure that this function is reported as not implemented for ARM builds because - // the instructions below are not present for that architecture. - UNIMPLEMENTED(); - return; -#endif -} - -void LoadRGBA8ToBGRA8_SSE2(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ -#if defined(ANGLE_USE_SSE) - __m128i brMask = _mm_set1_epi32(0x00ff00ff); - - for (size_t z = 0; z < depth; z++) - { - for (size_t y = 0; y < height; y++) - { - const uint32_t *source = OffsetDataPointer(input, y, z, inputRowPitch, inputDepthPitch); - uint32_t *dest = OffsetDataPointer(output, y, z, outputRowPitch, outputDepthPitch); - - size_t x = 0; - - // Make output writes aligned - for (; ((reinterpret_cast(&dest[x]) & 15) != 0) && x < width; x++) - { - uint32_t rgba = source[x]; - dest[x] = (ANGLE_ROTL(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00); - } - - for (; x + 3 < width; x += 4) - { - __m128i sourceData = _mm_loadu_si128(reinterpret_cast(&source[x])); - // Mask out g and a, which don't change - __m128i gaComponents = _mm_andnot_si128(brMask, sourceData); - // Mask out b and r - __m128i brComponents = _mm_and_si128(sourceData, brMask); - // Swap b and r - __m128i brSwapped = _mm_shufflehi_epi16(_mm_shufflelo_epi16(brComponents, _MM_SHUFFLE(2, 3, 0, 1)), _MM_SHUFFLE(2, 3, 0, 1)); - __m128i result = _mm_or_si128(gaComponents, brSwapped); - _mm_store_si128(reinterpret_cast<__m128i*>(&dest[x]), result); - } - - // Perform leftover writes - for (; x < width; x++) - { - uint32_t rgba = source[x]; - dest[x] = (ANGLE_ROTL(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00); - } - } - } -#else - // Ensure that this function is reported as not implemented for ARM builds because - // the instructions below are not present for that architecture. - UNIMPLEMENTED(); - return; -#endif -} - -} - diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage_etc.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage_etc.h deleted file mode 100644 index dc64e0461b..0000000000 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/loadimage_etc.h +++ /dev/null @@ -1,140 +0,0 @@ -// -// Copyright (c) 2013-2015 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// loadimage_etc.h: Decodes ETC and EAC encoded textures. - -#ifndef LIBANGLE_RENDERER_D3D_LOADIMAGE_ETC_H_ -#define LIBANGLE_RENDERER_D3D_LOADIMAGE_ETC_H_ - -#include "libANGLE/angletypes.h" - -#include - -namespace rx -{ - -void LoadETC1RGB8ToRGBA8(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); - -void LoadETC1RGB8ToBC1(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); - -void LoadEACR11ToR8(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); - -void LoadEACR11SToR8(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); - -void LoadEACRG11ToRG8(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); - -void LoadEACRG11SToRG8(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); - -void LoadETC2RGB8ToRGBA8(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); - -void LoadETC2SRGB8ToRGBA8(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); - -void LoadETC2RGB8A1ToRGBA8(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); - -void LoadETC2SRGB8A1ToRGBA8(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); - -void LoadETC2RGBA8ToRGBA8(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); - -void LoadETC2SRGBA8ToSRGBA8(size_t width, - size_t height, - size_t depth, - const uint8_t *input, - size_t inputRowPitch, - size_t inputDepthPitch, - uint8_t *output, - size_t outputRowPitch, - size_t outputDepthPitch); -} - -#endif // LIBANGLE_RENDERER_D3D_LOADIMAGE_ETC_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/driver_utils.cpp b/src/3rdparty/angle/src/libANGLE/renderer/driver_utils.cpp new file mode 100644 index 0000000000..d97b8e7c22 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/driver_utils.cpp @@ -0,0 +1,120 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// driver_utils.h : provides more information about current driver. + +#include + +#include "libANGLE/renderer/driver_utils.h" + +namespace rx +{ +// Intel +// Referenced from https://cgit.freedesktop.org/vaapi/intel-driver/tree/src/i965_pciids.h +namespace +{ +// gen7 +const uint32_t Haswell[] = { + 0x0402, 0x0406, 0x040A, 0x040B, 0x040E, 0x0C02, 0x0C06, 0x0C0A, 0x0C0B, 0x0C0E, + 0x0A02, 0x0A06, 0x0A0A, 0x0A0B, 0x0A0E, 0x0D02, 0x0D06, 0x0D0A, 0x0D0B, 0x0D0E, // hsw_gt1 + 0x0412, 0x0416, 0x041A, 0x041B, 0x041E, 0x0C12, 0x0C16, 0x0C1A, 0x0C1B, 0x0C1E, + 0x0A12, 0x0A16, 0x0A1A, 0x0A1B, 0x0A1E, 0x0D12, 0x0D16, 0x0D1A, 0x0D1B, 0x0D1E, // hsw_gt2 + 0x0422, 0x0426, 0x042A, 0x042B, 0x042E, 0x0C22, 0x0C26, 0x0C2A, 0x0C2B, 0x0C2E, + 0x0A22, 0x0A26, 0x0A2A, 0x0A2B, 0x0A2E, 0x0D22, 0x0D26, 0x0D2A, 0x0D2B, 0x0D2E // hsw_gt3 +}; + +// gen8 +const uint32_t Broadwell[] = {0x1602, 0x1606, 0x160A, 0x160B, 0x160D, 0x160E, + 0x1612, 0x1616, 0x161A, 0x161B, 0x161D, 0x161E, + 0x1622, 0x1626, 0x162A, 0x162B, 0x162D, 0x162E}; + +const uint32_t CherryView[] = {0x22B0, 0x22B1, 0x22B2, 0x22B3}; + +// gen9 +const uint32_t Skylake[] = {0x1902, 0x1906, 0x190A, 0x190B, 0x190E, 0x1912, 0x1913, 0x1915, 0x1916, + 0x1917, 0x191A, 0x191B, 0x191D, 0x191E, 0x1921, 0x1923, 0x1926, 0x1927, + 0x192A, 0x192B, 0x192D, 0x1932, 0x193A, 0x193B, 0x193D}; + +const uint32_t Broxton[] = {0x0A84, 0x1A84, 0x1A85, 0x5A84, 0x5A85}; + +// gen9p5 +const uint32_t Kabylake[] = {0x5916, 0x5913, 0x5906, 0x5926, 0x5921, 0x5915, 0x590E, + 0x591E, 0x5912, 0x5917, 0x5902, 0x591B, 0x593B, 0x590B, + 0x591A, 0x590A, 0x591D, 0x5908, 0x5923, 0x5927}; + +} // anonymous namespace + +IntelDriverVersion::IntelDriverVersion(uint16_t lastPart) : mVersionPart(lastPart) +{ +} + +bool IntelDriverVersion::operator==(const IntelDriverVersion &version) +{ + return mVersionPart == version.mVersionPart; +} + +bool IntelDriverVersion::operator!=(const IntelDriverVersion &version) +{ + return !(*this == version); +} + +bool IntelDriverVersion::operator<(const IntelDriverVersion &version) +{ + // See http://www.intel.com/content/www/us/en/support/graphics-drivers/000005654.html to + // understand the Intel graphics driver version number on Windows. + // mVersionPart1 changes with OS version. mVersionPart2 changes with DirectX version. + // mVersionPart3 stands for release year. mVersionPart4 is driver specific unique version + // number. + // For example: Intel driver version '20.19.15.4539' + // 20 -> windows 10 driver + // 19 -> DirectX 12 first version(12.0) supported + // 15 -> Driver released in 2015 + // 4539 -> Driver specific unique version number + // For linux, Intel graphics driver version is the mesa version. The version number has three + // parts: major revision, minor revision, release number. So, for linux, we need to compare + // three parts. + // Currently, it's only used in windows. So, checking the last part is enough. Once it's needed + // in other platforms, it's easy to be extended. + return mVersionPart < version.mVersionPart; +} + +bool IntelDriverVersion::operator>=(const IntelDriverVersion &version) +{ + return !(*this < version); +} + +bool IsHaswell(uint32_t DeviceId) +{ + return std::find(std::begin(Haswell), std::end(Haswell), DeviceId) != std::end(Haswell); +} + +bool IsBroadwell(uint32_t DeviceId) +{ + return std::find(std::begin(Broadwell), std::end(Broadwell), DeviceId) != std::end(Broadwell); +} + +bool IsCherryView(uint32_t DeviceId) +{ + return std::find(std::begin(CherryView), std::end(CherryView), DeviceId) != + std::end(CherryView); +} + +bool IsSkylake(uint32_t DeviceId) +{ + return std::find(std::begin(Skylake), std::end(Skylake), DeviceId) != std::end(Skylake); +} + +bool IsBroxton(uint32_t DeviceId) +{ + return std::find(std::begin(Broxton), std::end(Broxton), DeviceId) != std::end(Broxton); +} + +bool IsKabylake(uint32_t DeviceId) +{ + return std::find(std::begin(Kabylake), std::end(Kabylake), DeviceId) != std::end(Kabylake); +} + +} // namespace rx \ No newline at end of file diff --git a/src/3rdparty/angle/src/libANGLE/renderer/driver_utils.h b/src/3rdparty/angle/src/libANGLE/renderer/driver_utils.h new file mode 100644 index 0000000000..62bdc502fc --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/driver_utils.h @@ -0,0 +1,73 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// driver_utils.h : provides more information about current driver. + +#ifndef LIBANGLE_RENDERER_DRIVER_UTILS_H_ +#define LIBANGLE_RENDERER_DRIVER_UTILS_H_ + +#include "libANGLE/angletypes.h" + +namespace rx +{ + +enum VendorID : uint32_t +{ + VENDOR_ID_UNKNOWN = 0x0, + VENDOR_ID_AMD = 0x1002, + VENDOR_ID_INTEL = 0x8086, + VENDOR_ID_NVIDIA = 0x10DE, + // This is Qualcomm PCI Vendor ID. + // Android doesn't have a PCI bus, but all we need is a unique id. + VENDOR_ID_QUALCOMM = 0x5143, +}; + +inline bool IsAMD(uint32_t vendor_id) +{ + return vendor_id == VENDOR_ID_AMD; +} + +inline bool IsIntel(uint32_t vendor_id) +{ + return vendor_id == VENDOR_ID_INTEL; +} + +inline bool IsNvidia(uint32_t vendor_id) +{ + return vendor_id == VENDOR_ID_NVIDIA; +} + +inline bool IsQualcomm(uint32_t vendor_id) +{ + return vendor_id == VENDOR_ID_QUALCOMM; +} + +// Intel +class IntelDriverVersion +{ + public: + // Currently, We only provide the constructor with one parameter. It mainly used in Intel + // version number on windows. If you want to use this class on other platforms, it's easy to + // be extended. + IntelDriverVersion(uint16_t lastPart); + bool operator==(const IntelDriverVersion &); + bool operator!=(const IntelDriverVersion &); + bool operator<(const IntelDriverVersion &); + bool operator>=(const IntelDriverVersion &); + + private: + uint16_t mVersionPart; +}; + +bool IsHaswell(uint32_t DeviceId); +bool IsBroadwell(uint32_t DeviceId); +bool IsCherryView(uint32_t DeviceId); +bool IsSkylake(uint32_t DeviceId); +bool IsBroxton(uint32_t DeviceId); +bool IsKabylake(uint32_t DeviceId); + +} // namespace rx +#endif // LIBANGLE_RENDERER_DRIVER_UTILS_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/load_functions_data.json b/src/3rdparty/angle/src/libANGLE/renderer/load_functions_data.json new file mode 100644 index 0000000000..198274998c --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/load_functions_data.json @@ -0,0 +1,602 @@ +{ + "GL_RG8_SNORM": { + "R8G8_SNORM": { + "GL_BYTE": "LoadToNative" + } + }, + "GL_SRGB8": { + "R8G8B8A8_UNORM_SRGB": { + "GL_UNSIGNED_BYTE": "LoadToNative3To4" + } + }, + "GL_RGBA8I": { + "R8G8B8A8_SINT": { + "GL_BYTE": "LoadToNative" + } + }, + "GL_R8_SNORM": { + "R8_SNORM": { + "GL_BYTE": "LoadToNative" + } + }, + "GL_RGBA8_SNORM": { + "R8G8B8A8_SNORM": { + "GL_BYTE": "LoadToNative" + } + }, + "GL_R16I": { + "R16_SINT": { + "GL_SHORT": "LoadToNative" + } + }, + "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC": { + "R8G8B8A8_UNORM_SRGB": { + "GL_UNSIGNED_BYTE": "LoadETC2SRGBA8ToSRGBA8" + } + }, + "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2": { + "R8G8B8A8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadETC2RGB8A1ToRGBA8" + } + }, + "GL_RGB32UI": { + "R32G32B32A32_UINT": { + "GL_UNSIGNED_INT": "LoadToNative3To4" + } + }, + "GL_ALPHA32F_EXT": { + "NONE": { + "GL_FLOAT": "LoadA32FToRGBA32F" + } + }, + "GL_R16UI": { + "R16_UINT": { + "GL_UNSIGNED_SHORT": "LoadToNative" + } + }, + "GL_RGB9_E5": { + "R9G9B9E5_SHAREDEXP": { + "GL_HALF_FLOAT": "LoadRGB16FToRGB9E5", + "GL_UNSIGNED_INT_5_9_9_9_REV": "LoadToNative", + "GL_FLOAT": "LoadRGB32FToRGB9E5", + "GL_HALF_FLOAT_OES": "LoadRGB16FToRGB9E5" + } + }, + "GL_COMPRESSED_R11_EAC": { + "R8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadEACR11ToR8" + } + }, + "GL_RGBA32UI": { + "R32G32B32A32_UINT": { + "GL_UNSIGNED_INT": "LoadToNative" + } + }, + "GL_RG8UI": { + "R8G8_UINT": { + "GL_UNSIGNED_BYTE": "LoadToNative" + } + }, + "GL_LUMINANCE32F_EXT": { + "NONE": { + "GL_FLOAT": "LoadL32FToRGBA32F" + } + }, + "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2": { + "R8G8B8A8_UNORM_SRGB": { + "GL_UNSIGNED_BYTE": "LoadETC2SRGB8A1ToRGBA8" + } + }, + "GL_R16F": { + "R16_FLOAT": { + "GL_HALF_FLOAT": "LoadToNative", + "GL_FLOAT": "Load32FTo16F<1>", + "GL_HALF_FLOAT_OES": "LoadToNative" + } + }, + "GL_RGBA8UI": { + "R8G8B8A8_UINT": { + "GL_UNSIGNED_BYTE": "LoadToNative" + } + }, + "GL_BGRA4_ANGLEX": { + "NONE": { + "GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT": "LoadRGBA4ToRGBA8", + "GL_UNSIGNED_BYTE": "LoadToNative" + } + }, + "GL_RGBA16F": { + "R16G16B16A16_FLOAT": { + "GL_HALF_FLOAT": "LoadToNative", + "GL_FLOAT": "Load32FTo16F<4>", + "GL_HALF_FLOAT_OES": "LoadToNative" + } + }, + "GL_LUMINANCE8_EXT": { + "NONE": { + "GL_UNSIGNED_BYTE": "LoadL8ToRGBA8" + } + }, + "GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE": { + "NONE": { + "GL_UNSIGNED_BYTE": "LoadCompressedToNative<4, 4, 16>" + } + }, + "GL_RGB": { + "NONE": { + "GL_UNSIGNED_BYTE": "UnreachableLoadFunction", + "GL_UNSIGNED_SHORT_5_6_5": "UnreachableLoadFunction" + } + }, + "GL_RGB5_A1": { + "R8G8B8A8_UNORM": { + "GL_UNSIGNED_INT_2_10_10_10_REV": "LoadRGB10A2ToRGBA8", + "GL_UNSIGNED_BYTE": "LoadToNative", + "GL_UNSIGNED_SHORT_5_5_5_1": "LoadRGB5A1ToRGBA8" + }, + "B5G5R5A1_UNORM": { + "GL_UNSIGNED_INT_2_10_10_10_REV": "LoadRGB10A2ToBGR5A1", + "GL_UNSIGNED_BYTE": "LoadRGBA8ToBGR5A1", + "GL_UNSIGNED_SHORT_5_5_5_1": "LoadRGB5A1ToA1RGB5" + } + }, + "GL_RGB16UI": { + "R16G16B16A16_UINT": { + "GL_UNSIGNED_SHORT": "LoadToNative3To4" + } + }, + "GL_BGRA_EXT": { + "NONE": { + "GL_UNSIGNED_BYTE": "UnreachableLoadFunction" + } + }, + "GL_COMPRESSED_RGB8_ETC2": { + "R8G8B8A8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadETC2RGB8ToRGBA8" + } + }, + "GL_RGBA32F": { + "R32G32B32A32_FLOAT": { + "GL_FLOAT": "LoadToNative" + } + }, + "GL_RGBA32I": { + "R32G32B32A32_SINT": { + "GL_INT": "LoadToNative" + } + }, + "GL_LUMINANCE8_ALPHA8_EXT": { + "NONE": { + "GL_UNSIGNED_BYTE": "LoadLA8ToRGBA8" + } + }, + "GL_RG8": { + "R8G8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadToNative" + } + }, + "GL_RGB10_A2": { + "R10G10B10A2_UNORM": { + "GL_UNSIGNED_INT_2_10_10_10_REV": "LoadToNative" + } + }, + "GL_COMPRESSED_SIGNED_RG11_EAC": { + "R8G8_SNORM": { + "GL_UNSIGNED_BYTE": "LoadEACRG11SToRG8" + } + }, + "GL_DEPTH_COMPONENT16": { + "D16_UNORM": { + "GL_UNSIGNED_INT": "LoadR32ToR16", + "GL_UNSIGNED_SHORT": "LoadToNative" + } + }, + "GL_RGB32I": { + "R32G32B32A32_SINT": { + "GL_INT": "LoadToNative3To4" + } + }, + "GL_R8": { + "R8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadToNative" + } + }, + "GL_RGB32F": { + "R32G32B32A32_FLOAT": { + "GL_FLOAT": "LoadToNative3To4" + } + }, + "GL_R11F_G11F_B10F": { + "R11G11B10_FLOAT": { + "GL_UNSIGNED_INT_10F_11F_11F_REV": "LoadToNative", + "GL_HALF_FLOAT": "LoadRGB16FToRG11B10F", + "GL_FLOAT": "LoadRGB32FToRG11B10F", + "GL_HALF_FLOAT_OES": "LoadRGB16FToRG11B10F" + } + }, + "GL_RGB8": { + "R8G8B8A8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadToNative3To4" + } + }, + "GL_LUMINANCE_ALPHA": { + "R16G16B16A16_FLOAT": { + "GL_HALF_FLOAT": "LoadLA16FToRGBA16F", + "GL_HALF_FLOAT_OES": "LoadLA16FToRGBA16F" + }, + "NONE": { + "GL_UNSIGNED_BYTE": "UnreachableLoadFunction" + }, + "R32G32B32A32_FLOAT": { + "GL_FLOAT": "LoadLA32FToRGBA32F" + } + }, + "GL_RGBA16I": { + "R16G16B16A16_SINT": { + "GL_SHORT": "LoadToNative" + } + }, + "GL_R8I": { + "R8_SINT": { + "GL_BYTE": "LoadToNative" + } + }, + "GL_RGB8_SNORM": { + "R8G8B8A8_SNORM": { + "GL_BYTE": "LoadToNative3To4" + } + }, + "GL_RG32F": { + "R32G32_FLOAT": { + "GL_FLOAT": "LoadToNative" + } + }, + "GL_DEPTH_COMPONENT32F": { + "D32_FLOAT": { + "GL_FLOAT": "LoadD32FToD32F" + } + }, + "GL_RG32I": { + "R32G32_SINT": { + "GL_INT": "LoadToNative" + } + }, + "GL_ALPHA8_EXT": { + "A8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadToNative" + }, + "R8G8B8A8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadA8ToRGBA8" + } + }, + "GL_RG32UI": { + "R32G32_UINT": { + "GL_UNSIGNED_INT": "LoadToNative" + } + }, + "GL_RGBA16UI": { + "R16G16B16A16_UINT": { + "GL_UNSIGNED_SHORT": "LoadToNative" + } + }, + "GL_COMPRESSED_RGBA8_ETC2_EAC": { + "R8G8B8A8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadETC2RGBA8ToRGBA8" + } + }, + "GL_RGB8I": { + "R8G8B8A8_SINT": { + "GL_BYTE": "LoadToNative3To4" + } + }, + "GL_COMPRESSED_SRGB8_ETC2": { + "R8G8B8A8_UNORM_SRGB": { + "GL_UNSIGNED_BYTE": "LoadETC2SRGB8ToRGBA8" + } + }, + "GL_DEPTH32F_STENCIL8": { + "D32_FLOAT_S8X24_UINT": { + "GL_FLOAT_32_UNSIGNED_INT_24_8_REV": "LoadD32FS8X24ToD32FS8X24" + } + }, + "GL_RG8I": { + "R8G8_SINT": { + "GL_BYTE": "LoadToNative" + } + }, + "GL_R32UI": { + "R32_UINT": { + "GL_UNSIGNED_INT": "LoadToNative" + } + }, + "GL_BGR5_A1_ANGLEX": { + "NONE": { + "GL_UNSIGNED_BYTE": "LoadToNative", + "GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT": "LoadRGB5A1ToRGBA8" + } + }, + "GL_BGR565_ANGLEX": { + "B5G6R5_UNORM": { + "GL_UNSIGNED_SHORT_5_6_5": "LoadRGB565ToBGR565", + "GL_UNSIGNED_BYTE": "LoadToNative" + } + }, + "GL_COMPRESSED_RG11_EAC": { + "R8G8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadEACRG11ToRG8" + } + }, + "GL_SRGB8_ALPHA8": { + "R8G8B8A8_UNORM_SRGB": { + "GL_UNSIGNED_BYTE": "LoadToNative" + } + }, + "GL_LUMINANCE_ALPHA16F_EXT": { + "NONE": { + "GL_HALF_FLOAT": "LoadLA16FToRGBA16F", + "GL_HALF_FLOAT_OES": "LoadLA16FToRGBA16F" + } + }, + "GL_RGBA": { + "NONE": { + "GL_UNSIGNED_BYTE": "UnreachableLoadFunction", + "GL_UNSIGNED_SHORT_4_4_4_4": "UnreachableLoadFunction", + "GL_UNSIGNED_SHORT_5_5_5_1": "UnreachableLoadFunction" + } + }, + "GL_DEPTH24_STENCIL8": { + "D24_UNORM_S8_UINT": { + "GL_UNSIGNED_INT_24_8": "LoadR32ToR24G8" + } + }, + "GL_RGB16I": { + "R16G16B16A16_SINT": { + "GL_SHORT": "LoadToNative3To4" + } + }, + "GL_R8UI": { + "R8_UINT": { + "GL_UNSIGNED_BYTE": "LoadToNative" + } + }, + "GL_ALPHA": { + "R16G16B16A16_FLOAT": { + "GL_HALF_FLOAT": "LoadA16FToRGBA16F", + "GL_HALF_FLOAT_OES": "LoadA16FToRGBA16F" + }, + "NONE": { + "GL_UNSIGNED_BYTE": "UnreachableLoadFunction" + }, + "R32G32B32A32_FLOAT": { + "GL_FLOAT": "LoadA32FToRGBA32F" + } + }, + "GL_RGB16F": { + "R16G16B16A16_FLOAT": { + "GL_HALF_FLOAT": "LoadToNative3To4", + "GL_FLOAT": "LoadRGB32FToRGBA16F", + "GL_HALF_FLOAT_OES": "LoadToNative3To4" + } + }, + "GL_COMPRESSED_SIGNED_R11_EAC": { + "R8_SNORM": { + "GL_UNSIGNED_BYTE": "LoadEACR11SToR8" + } + }, + "GL_COMPRESSED_RGB_S3TC_DXT1_EXT": { + "NONE": { + "GL_UNSIGNED_BYTE": "LoadCompressedToNative<4, 4, 8>" + } + }, + "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT": { + "NONE": { + "GL_UNSIGNED_BYTE": "LoadCompressedToNative<4, 4, 8>" + } + }, + "GL_STENCIL_INDEX8": { + "NONE": { + "GL_UNSIGNED_BYTE": "UnimplementedLoadFunction" + } + }, + "GL_LUMINANCE_ALPHA32F_EXT": { + "NONE": { + "GL_FLOAT": "LoadLA32FToRGBA32F" + } + }, + "GL_RGB8UI": { + "R8G8B8A8_UINT": { + "GL_UNSIGNED_BYTE": "LoadToNative3To4" + } + }, + "GL_DEPTH_COMPONENT24": { + "D24_UNORM_S8_UINT": { + "GL_UNSIGNED_INT": "LoadR32ToR24G8" + } + }, + "GL_R32I": { + "R32_SINT": { + "GL_INT": "LoadToNative" + } + }, + "GL_DEPTH_COMPONENT32_OES": { + "NONE": { + "GL_UNSIGNED_INT": "LoadR32ToR24G8" + } + }, + "GL_R32F": { + "R32_FLOAT": { + "GL_FLOAT": "LoadToNative" + } + }, + "GL_RG16F": { + "R16G16_FLOAT": { + "GL_HALF_FLOAT": "LoadToNative", + "GL_FLOAT": "Load32FTo16F<2>", + "GL_HALF_FLOAT_OES": "LoadToNative" + } + }, + "GL_RGB565": { + "R8G8B8A8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadToNative3To4", + "GL_UNSIGNED_SHORT_5_6_5": "LoadR5G6B5ToRGBA8" + }, + "B5G6R5_UNORM": { + "GL_UNSIGNED_BYTE": "LoadRGB8ToBGR565", + "GL_UNSIGNED_SHORT_5_6_5": "LoadToNative" + } + }, + "GL_LUMINANCE16F_EXT": { + "NONE": { + "GL_HALF_FLOAT": "LoadL16FToRGBA16F", + "GL_HALF_FLOAT_OES": "LoadL16FToRGBA16F" + } + }, + "GL_RG16UI": { + "R16G16_UINT": { + "GL_UNSIGNED_SHORT": "LoadToNative" + } + }, + "GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE": { + "NONE": { + "GL_UNSIGNED_BYTE": "LoadCompressedToNative<4, 4, 16>" + } + }, + "GL_RG16I": { + "R16G16_SINT": { + "GL_SHORT": "LoadToNative" + } + }, + "GL_BGRA8_EXT": { + "NONE": { + "GL_UNSIGNED_BYTE": "LoadToNative" + } + }, + "GL_ALPHA16F_EXT": { + "NONE": { + "GL_HALF_FLOAT": "LoadA16FToRGBA16F", + "GL_HALF_FLOAT_OES": "LoadA16FToRGBA16F" + } + }, + "GL_RGBA4": { + "R8G8B8A8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadToNative", + "GL_UNSIGNED_SHORT_4_4_4_4": "LoadRGBA4ToRGBA8" + }, + "B4G4R4A4_UNORM": { + "GL_UNSIGNED_BYTE": "LoadRGBA8ToBGRA4", + "GL_UNSIGNED_SHORT_4_4_4_4": "LoadRGBA4ToARGB4" + } + }, + "GL_RGBA8": { + "R8G8B8A8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadToNative" + } + }, + "GL_LUMINANCE": { + "R16G16B16A16_FLOAT": { + "GL_HALF_FLOAT": "LoadL16FToRGBA16F", + "GL_HALF_FLOAT_OES": "LoadL16FToRGBA16F" + }, + "NONE": { + "GL_UNSIGNED_BYTE": "UnreachableLoadFunction" + }, + "R32G32B32A32_FLOAT": { + "GL_FLOAT": "LoadL32FToRGBA32F" + } + }, + "GL_RGB10_A2UI": { + "R10G10B10A2_UINT": { + "GL_UNSIGNED_INT_2_10_10_10_REV": "LoadToNative" + } + }, + "GL_ETC1_RGB8_OES": { + "R8G8B8A8_UNORM": { + "GL_UNSIGNED_BYTE": "LoadETC1RGB8ToRGBA8" + } + }, + "GL_ETC1_RGB8_LOSSY_DECODE_ANGLE": { + "BC1_RGB_UNORM_BLOCK": { + "GL_UNSIGNED_BYTE": "LoadETC1RGB8ToBC1" + } + }, + "GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE": { + "BC1_RGB_UNORM_BLOCK": { + "GL_UNSIGNED_BYTE": "LoadETC2RGB8ToBC1" + } + }, + "GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE": { + "BC1_RGB_UNORM_SRGB_BLOCK": { + "GL_UNSIGNED_BYTE": "LoadETC2SRGB8ToBC1" + } + }, + "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE": { + "BC1_RGBA_UNORM_BLOCK": { + "GL_UNSIGNED_BYTE": "LoadETC2RGB8A1ToBC1" + } + }, + "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE": { + "BC1_RGBA_UNORM_SRGB_BLOCK": { + "GL_UNSIGNED_BYTE": "LoadETC2SRGB8A1ToBC1" + } + }, + "GL_R16_EXT": { + "R16_UNORM": { + "GL_UNSIGNED_SHORT": "LoadToNative" + } + }, + "GL_RG16_EXT": { + "R16G16_UNORM": { + "GL_UNSIGNED_SHORT": "LoadToNative" + } + }, + "GL_RGB16_EXT": { + "R16G16B16A16_UNORM": { + "GL_UNSIGNED_SHORT": "LoadToNative3To4" + } + }, + "GL_RGBA16_EXT": { + "R16G16B16A16_UNORM": { + "GL_UNSIGNED_SHORT": "LoadToNative" + } + }, + "GL_R16_SNORM_EXT": { + "R16_SNORM": { + "GL_SHORT": "LoadToNative" + } + }, + "GL_RG16_SNORM_EXT": { + "R16G16_SNORM": { + "GL_SHORT": "LoadToNative" + } + }, + "GL_RGB16_SNORM_EXT": { + "R16G16B16A16_SNORM": { + "GL_SHORT": "LoadToNative3To4" + } + }, + "GL_RGBA16_SNORM_EXT": { + "R16G16B16A16_SNORM": { + "GL_SHORT": "LoadToNative" + } + }, + "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT": { + "NONE": { + "GL_UNSIGNED_BYTE": "LoadCompressedToNative<4, 4, 16>" + } + }, + "GL_COMPRESSED_SRGB_S3TC_DXT1_EXT": { + "NONE": { + "GL_UNSIGNED_BYTE": "LoadCompressedToNative<4, 4, 8>" + } + }, + "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT": { + "NONE": { + "GL_UNSIGNED_BYTE": "LoadCompressedToNative<4, 4, 8>" + } + }, + "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT": { + "NONE": { + "GL_UNSIGNED_BYTE": "LoadCompressedToNative<4, 4, 16>" + } + } +} diff --git a/src/3rdparty/angle/src/libANGLE/renderer/load_functions_table.h b/src/3rdparty/angle/src/libANGLE/renderer/load_functions_table.h new file mode 100644 index 0000000000..f3da31c100 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/load_functions_table.h @@ -0,0 +1,22 @@ +// +// Copyright 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// load_functions_table: +// Contains load functions table depending on internal format and ANGLE format. +// + +#ifndef LIBANGLE_RENDERER_LOADFUNCTIONSTABLE_H_ +#define LIBANGLE_RENDERER_LOADFUNCTIONSTABLE_H_ + +#include "libANGLE/renderer/Format.h" + +namespace angle +{ + +rx::LoadFunctionMap GetLoadFunctionsMap(GLenum internalFormat, Format::ID angleFormat); + +} // namespace angle + +#endif // LIBANGLE_RENDERER_LOADFUNCTIONSTABLE_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/load_functions_table_autogen.cpp b/src/3rdparty/angle/src/libANGLE/renderer/load_functions_table_autogen.cpp new file mode 100644 index 0000000000..ed9fe2864c --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/load_functions_table_autogen.cpp @@ -0,0 +1,2459 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_load_functions_table.py using data from load_functions_data.json +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// load_functions_table: +// Contains the GetLoadFunctionsMap for texture_format_util.h +// + +#include "libANGLE/renderer/load_functions_table.h" + +#include "image_util/copyimage.h" +#include "image_util/generatemip.h" +#include "image_util/loadimage.h" + +using namespace rx; + +namespace angle +{ + +namespace +{ + +// ES3 image loading functions vary based on: +// - the GL internal format (supplied to glTex*Image*D) +// - the GL data type given (supplied to glTex*Image*D) +// - the target DXGI_FORMAT that the image will be loaded into (which is chosen based on the D3D +// device's capabilities) +// This map type determines which loading function to use, based on these three parameters. +// Source formats and types are taken from Tables 3.2 and 3.3 of the ES 3 spec. +void UnimplementedLoadFunction(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + UNIMPLEMENTED(); +} + +void UnreachableLoadFunction(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch) +{ + UNREACHABLE(); +} + +LoadImageFunctionInfo ALPHA_to_R16G16B16A16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadA16FToRGBA16F, true); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadA16FToRGBA16F, true); + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ALPHA_to_R32G32B32A32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadA32FToRGBA32F, true); + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ALPHA_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ALPHA16F_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadA16FToRGBA16F, true); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadA16FToRGBA16F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ALPHA32F_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadA32FToRGBA32F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ALPHA8_EXT_to_A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ALPHA8_EXT_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadA8ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo BGR565_ANGLEX_to_B5G6R5_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + case GL_UNSIGNED_SHORT_5_6_5: + return LoadImageFunctionInfo(LoadRGB565ToBGR565, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo BGR5_A1_ANGLEX_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: + return LoadImageFunctionInfo(LoadRGB5A1ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo BGRA4_ANGLEX_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: + return LoadImageFunctionInfo(LoadRGBA4ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo BGRA8_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo BGRA_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_R11_EAC_to_R8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadEACR11ToR8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RG11_EAC_to_R8G8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadEACRG11ToRG8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGB8_ETC2_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC2RGB8ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE_to_BC1_RGB_UNORM_BLOCK(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC2RGB8ToBC1, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC2RGB8A1ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo +COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE_to_BC1_RGBA_UNORM_BLOCK(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC2RGB8A1ToBC1, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA8_ETC2_EAC_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC2RGBA8ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_S3TC_DXT1_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 8>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_S3TC_DXT3_ANGLE_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGBA_S3TC_DXT5_ANGLE_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_RGB_S3TC_DXT1_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 8>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SIGNED_R11_EAC_to_R8_SNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadEACR11SToR8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SIGNED_RG11_EAC_to_R8G8_SNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadEACRG11SToRG8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC2SRGBA8ToSRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_ETC2_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC2SRGB8ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE_to_BC1_RGB_UNORM_SRGB_BLOCK( + GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC2SRGB8ToBC1, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC2SRGB8A1ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo +COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE_to_BC1_RGBA_UNORM_SRGB_BLOCK( + GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC2SRGB8A1ToBC1, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 8>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 16>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo COMPRESSED_SRGB_S3TC_DXT1_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 8>, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo DEPTH24_STENCIL8_to_D24_UNORM_S8_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT_24_8: + return LoadImageFunctionInfo(LoadR32ToR24G8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo DEPTH32F_STENCIL8_to_D32_FLOAT_S8X24_UINT(GLenum type) +{ + switch (type) + { + case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: + return LoadImageFunctionInfo(LoadD32FS8X24ToD32FS8X24, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo DEPTH_COMPONENT16_to_D16_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT: + return LoadImageFunctionInfo(LoadR32ToR16, true); + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo DEPTH_COMPONENT24_to_D24_UNORM_S8_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT: + return LoadImageFunctionInfo(LoadR32ToR24G8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo DEPTH_COMPONENT32F_to_D32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadD32FToD32F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo DEPTH_COMPONENT32_OES_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT: + return LoadImageFunctionInfo(LoadR32ToR24G8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ETC1_RGB8_LOSSY_DECODE_ANGLE_to_BC1_RGB_UNORM_BLOCK(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC1RGB8ToBC1, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo ETC1_RGB8_OES_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadETC1RGB8ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE_to_R16G16B16A16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadL16FToRGBA16F, true); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadL16FToRGBA16F, true); + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE_to_R32G32B32A32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadL32FToRGBA32F, true); + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE16F_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadL16FToRGBA16F, true); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadL16FToRGBA16F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE32F_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadL32FToRGBA32F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE8_ALPHA8_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadLA8ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE8_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadL8ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE_ALPHA_to_R16G16B16A16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadLA16FToRGBA16F, true); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadLA16FToRGBA16F, true); + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE_ALPHA_to_R32G32B32A32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadLA32FToRGBA32F, true); + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE_ALPHA_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE_ALPHA16F_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadLA16FToRGBA16F, true); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadLA16FToRGBA16F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo LUMINANCE_ALPHA32F_EXT_to_default(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadLA32FToRGBA32F, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R11F_G11F_B10F_to_R11G11B10_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadRGB32FToRG11B10F, true); + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadRGB16FToRG11B10F, true); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadRGB16FToRG11B10F, true); + case GL_UNSIGNED_INT_10F_11F_11F_REV: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R16F_to_R16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(Load32FTo16F<1>, true); + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadToNative, false); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R16I_to_R16_SINT(GLenum type) +{ + switch (type) + { + case GL_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R16UI_to_R16_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R16_EXT_to_R16_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R16_SNORM_EXT_to_R16_SNORM(GLenum type) +{ + switch (type) + { + case GL_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R32F_to_R32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R32I_to_R32_SINT(GLenum type) +{ + switch (type) + { + case GL_INT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R32UI_to_R32_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R8_to_R8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R8I_to_R8_SINT(GLenum type) +{ + switch (type) + { + case GL_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R8UI_to_R8_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo R8_SNORM_to_R8_SNORM(GLenum type) +{ + switch (type) + { + case GL_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG16F_to_R16G16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(Load32FTo16F<2>, true); + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadToNative, false); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG16I_to_R16G16_SINT(GLenum type) +{ + switch (type) + { + case GL_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG16UI_to_R16G16_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG16_EXT_to_R16G16_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG16_SNORM_EXT_to_R16G16_SNORM(GLenum type) +{ + switch (type) + { + case GL_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG32F_to_R32G32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG32I_to_R32G32_SINT(GLenum type) +{ + switch (type) + { + case GL_INT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG32UI_to_R32G32_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG8_to_R8G8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG8I_to_R8G8_SINT(GLenum type) +{ + switch (type) + { + case GL_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG8UI_to_R8G8_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RG8_SNORM_to_R8G8_SNORM(GLenum type) +{ + switch (type) + { + case GL_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + case GL_UNSIGNED_SHORT_5_6_5: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB10_A2_to_R10G10B10A2_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT_2_10_10_10_REV: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB10_A2UI_to_R10G10B10A2_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT_2_10_10_10_REV: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB16F_to_R16G16B16A16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadRGB32FToRGBA16F, true); + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadToNative3To4, true); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB16I_to_R16G16B16A16_SINT(GLenum type) +{ + switch (type) + { + case GL_SHORT: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB16UI_to_R16G16B16A16_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB16_EXT_to_R16G16B16A16_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB16_SNORM_EXT_to_R16G16B16A16_SNORM(GLenum type) +{ + switch (type) + { + case GL_SHORT: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB32F_to_R32G32B32A32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB32I_to_R32G32B32A32_SINT(GLenum type) +{ + switch (type) + { + case GL_INT: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB32UI_to_R32G32B32A32_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB565_to_B5G6R5_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadRGB8ToBGR565, true); + case GL_UNSIGNED_SHORT_5_6_5: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB565_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative3To4, true); + case GL_UNSIGNED_SHORT_5_6_5: + return LoadImageFunctionInfo(LoadR5G6B5ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB5_A1_to_B5G5R5A1_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadRGBA8ToBGR5A1, true); + case GL_UNSIGNED_INT_2_10_10_10_REV: + return LoadImageFunctionInfo(LoadRGB10A2ToBGR5A1, true); + case GL_UNSIGNED_SHORT_5_5_5_1: + return LoadImageFunctionInfo(LoadRGB5A1ToA1RGB5, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB5_A1_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + case GL_UNSIGNED_INT_2_10_10_10_REV: + return LoadImageFunctionInfo(LoadRGB10A2ToRGBA8, true); + case GL_UNSIGNED_SHORT_5_5_5_1: + return LoadImageFunctionInfo(LoadRGB5A1ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB8_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB8I_to_R8G8B8A8_SINT(GLenum type) +{ + switch (type) + { + case GL_BYTE: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB8UI_to_R8G8B8A8_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB8_SNORM_to_R8G8B8A8_SNORM(GLenum type) +{ + switch (type) + { + case GL_BYTE: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGB9_E5_to_R9G9B9E5_SHAREDEXP(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadRGB32FToRGB9E5, true); + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadRGB16FToRGB9E5, true); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadRGB16FToRGB9E5, true); + case GL_UNSIGNED_INT_5_9_9_9_REV: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + case GL_UNSIGNED_SHORT_4_4_4_4: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + case GL_UNSIGNED_SHORT_5_5_5_1: + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA16F_to_R16G16B16A16_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(Load32FTo16F<4>, true); + case GL_HALF_FLOAT: + return LoadImageFunctionInfo(LoadToNative, false); + case GL_HALF_FLOAT_OES: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA16I_to_R16G16B16A16_SINT(GLenum type) +{ + switch (type) + { + case GL_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA16UI_to_R16G16B16A16_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA16_EXT_to_R16G16B16A16_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA16_SNORM_EXT_to_R16G16B16A16_SNORM(GLenum type) +{ + switch (type) + { + case GL_SHORT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA32F_to_R32G32B32A32_FLOAT(GLenum type) +{ + switch (type) + { + case GL_FLOAT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA32I_to_R32G32B32A32_SINT(GLenum type) +{ + switch (type) + { + case GL_INT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA32UI_to_R32G32B32A32_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_INT: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA4_to_B4G4R4A4_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadRGBA8ToBGRA4, true); + case GL_UNSIGNED_SHORT_4_4_4_4: + return LoadImageFunctionInfo(LoadRGBA4ToARGB4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA4_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + case GL_UNSIGNED_SHORT_4_4_4_4: + return LoadImageFunctionInfo(LoadRGBA4ToRGBA8, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA8_to_R8G8B8A8_UNORM(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA8I_to_R8G8B8A8_SINT(GLenum type) +{ + switch (type) + { + case GL_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA8UI_to_R8G8B8A8_UINT(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo RGBA8_SNORM_to_R8G8B8A8_SNORM(GLenum type) +{ + switch (type) + { + case GL_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo SRGB8_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative3To4, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo SRGB8_ALPHA8_to_R8G8B8A8_UNORM_SRGB(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(LoadToNative, false); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +LoadImageFunctionInfo STENCIL_INDEX8_to_default(GLenum type) +{ + switch (type) + { + case GL_UNSIGNED_BYTE: + return LoadImageFunctionInfo(UnimplementedLoadFunction, true); + default: + UNREACHABLE(); + return LoadImageFunctionInfo(UnreachableLoadFunction, true); + } +} + +} // namespace + +LoadFunctionMap GetLoadFunctionsMap(GLenum internalFormat, Format::ID angleFormat) +{ + // clang-format off + switch (internalFormat) + { + case GL_ALPHA: + { + switch (angleFormat) + { + case Format::ID::R16G16B16A16_FLOAT: + return ALPHA_to_R16G16B16A16_FLOAT; + case Format::ID::R32G32B32A32_FLOAT: + return ALPHA_to_R32G32B32A32_FLOAT; + default: + return ALPHA_to_default; + } + } + case GL_ALPHA16F_EXT: + return ALPHA16F_EXT_to_default; + case GL_ALPHA32F_EXT: + return ALPHA32F_EXT_to_default; + case GL_ALPHA8_EXT: + { + switch (angleFormat) + { + case Format::ID::A8_UNORM: + return ALPHA8_EXT_to_A8_UNORM; + case Format::ID::R8G8B8A8_UNORM: + return ALPHA8_EXT_to_R8G8B8A8_UNORM; + default: + break; + } + } + case GL_BGR565_ANGLEX: + { + switch (angleFormat) + { + case Format::ID::B5G6R5_UNORM: + return BGR565_ANGLEX_to_B5G6R5_UNORM; + default: + break; + } + } + case GL_BGR5_A1_ANGLEX: + return BGR5_A1_ANGLEX_to_default; + case GL_BGRA4_ANGLEX: + return BGRA4_ANGLEX_to_default; + case GL_BGRA8_EXT: + return BGRA8_EXT_to_default; + case GL_BGRA_EXT: + return BGRA_EXT_to_default; + case GL_COMPRESSED_R11_EAC: + { + switch (angleFormat) + { + case Format::ID::R8_UNORM: + return COMPRESSED_R11_EAC_to_R8_UNORM; + default: + break; + } + } + case GL_COMPRESSED_RG11_EAC: + { + switch (angleFormat) + { + case Format::ID::R8G8_UNORM: + return COMPRESSED_RG11_EAC_to_R8G8_UNORM; + default: + break; + } + } + case GL_COMPRESSED_RGB8_ETC2: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_UNORM: + return COMPRESSED_RGB8_ETC2_to_R8G8B8A8_UNORM; + default: + break; + } + } + case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE: + { + switch (angleFormat) + { + case Format::ID::BC1_RGB_UNORM_BLOCK: + return COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE_to_BC1_RGB_UNORM_BLOCK; + default: + break; + } + } + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_UNORM: + return COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_to_R8G8B8A8_UNORM; + default: + break; + } + } + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE: + { + switch (angleFormat) + { + case Format::ID::BC1_RGBA_UNORM_BLOCK: + return COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE_to_BC1_RGBA_UNORM_BLOCK; + default: + break; + } + } + case GL_COMPRESSED_RGBA8_ETC2_EAC: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_UNORM: + return COMPRESSED_RGBA8_ETC2_EAC_to_R8G8B8A8_UNORM; + default: + break; + } + } + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return COMPRESSED_RGBA_S3TC_DXT1_EXT_to_default; + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + return COMPRESSED_RGBA_S3TC_DXT3_ANGLE_to_default; + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + return COMPRESSED_RGBA_S3TC_DXT5_ANGLE_to_default; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + return COMPRESSED_RGB_S3TC_DXT1_EXT_to_default; + case GL_COMPRESSED_SIGNED_R11_EAC: + { + switch (angleFormat) + { + case Format::ID::R8_SNORM: + return COMPRESSED_SIGNED_R11_EAC_to_R8_SNORM; + default: + break; + } + } + case GL_COMPRESSED_SIGNED_RG11_EAC: + { + switch (angleFormat) + { + case Format::ID::R8G8_SNORM: + return COMPRESSED_SIGNED_RG11_EAC_to_R8G8_SNORM; + default: + break; + } + } + case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_UNORM_SRGB: + return COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_to_R8G8B8A8_UNORM_SRGB; + default: + break; + } + } + case GL_COMPRESSED_SRGB8_ETC2: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_UNORM_SRGB: + return COMPRESSED_SRGB8_ETC2_to_R8G8B8A8_UNORM_SRGB; + default: + break; + } + } + case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE: + { + switch (angleFormat) + { + case Format::ID::BC1_RGB_UNORM_SRGB_BLOCK: + return COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE_to_BC1_RGB_UNORM_SRGB_BLOCK; + default: + break; + } + } + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_UNORM_SRGB: + return COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_to_R8G8B8A8_UNORM_SRGB; + default: + break; + } + } + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE: + { + switch (angleFormat) + { + case Format::ID::BC1_RGBA_UNORM_SRGB_BLOCK: + return COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE_to_BC1_RGBA_UNORM_SRGB_BLOCK; + default: + break; + } + } + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + return COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT_to_default; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + return COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT_to_default; + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + return COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT_to_default; + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + return COMPRESSED_SRGB_S3TC_DXT1_EXT_to_default; + case GL_DEPTH24_STENCIL8: + { + switch (angleFormat) + { + case Format::ID::D24_UNORM_S8_UINT: + return DEPTH24_STENCIL8_to_D24_UNORM_S8_UINT; + default: + break; + } + } + case GL_DEPTH32F_STENCIL8: + { + switch (angleFormat) + { + case Format::ID::D32_FLOAT_S8X24_UINT: + return DEPTH32F_STENCIL8_to_D32_FLOAT_S8X24_UINT; + default: + break; + } + } + case GL_DEPTH_COMPONENT16: + { + switch (angleFormat) + { + case Format::ID::D16_UNORM: + return DEPTH_COMPONENT16_to_D16_UNORM; + default: + break; + } + } + case GL_DEPTH_COMPONENT24: + { + switch (angleFormat) + { + case Format::ID::D24_UNORM_S8_UINT: + return DEPTH_COMPONENT24_to_D24_UNORM_S8_UINT; + default: + break; + } + } + case GL_DEPTH_COMPONENT32F: + { + switch (angleFormat) + { + case Format::ID::D32_FLOAT: + return DEPTH_COMPONENT32F_to_D32_FLOAT; + default: + break; + } + } + case GL_DEPTH_COMPONENT32_OES: + return DEPTH_COMPONENT32_OES_to_default; + case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: + { + switch (angleFormat) + { + case Format::ID::BC1_RGB_UNORM_BLOCK: + return ETC1_RGB8_LOSSY_DECODE_ANGLE_to_BC1_RGB_UNORM_BLOCK; + default: + break; + } + } + case GL_ETC1_RGB8_OES: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_UNORM: + return ETC1_RGB8_OES_to_R8G8B8A8_UNORM; + default: + break; + } + } + case GL_LUMINANCE: + { + switch (angleFormat) + { + case Format::ID::R16G16B16A16_FLOAT: + return LUMINANCE_to_R16G16B16A16_FLOAT; + case Format::ID::R32G32B32A32_FLOAT: + return LUMINANCE_to_R32G32B32A32_FLOAT; + default: + return LUMINANCE_to_default; + } + } + case GL_LUMINANCE16F_EXT: + return LUMINANCE16F_EXT_to_default; + case GL_LUMINANCE32F_EXT: + return LUMINANCE32F_EXT_to_default; + case GL_LUMINANCE8_ALPHA8_EXT: + return LUMINANCE8_ALPHA8_EXT_to_default; + case GL_LUMINANCE8_EXT: + return LUMINANCE8_EXT_to_default; + case GL_LUMINANCE_ALPHA: + { + switch (angleFormat) + { + case Format::ID::R16G16B16A16_FLOAT: + return LUMINANCE_ALPHA_to_R16G16B16A16_FLOAT; + case Format::ID::R32G32B32A32_FLOAT: + return LUMINANCE_ALPHA_to_R32G32B32A32_FLOAT; + default: + return LUMINANCE_ALPHA_to_default; + } + } + case GL_LUMINANCE_ALPHA16F_EXT: + return LUMINANCE_ALPHA16F_EXT_to_default; + case GL_LUMINANCE_ALPHA32F_EXT: + return LUMINANCE_ALPHA32F_EXT_to_default; + case GL_R11F_G11F_B10F: + { + switch (angleFormat) + { + case Format::ID::R11G11B10_FLOAT: + return R11F_G11F_B10F_to_R11G11B10_FLOAT; + default: + break; + } + } + case GL_R16F: + { + switch (angleFormat) + { + case Format::ID::R16_FLOAT: + return R16F_to_R16_FLOAT; + default: + break; + } + } + case GL_R16I: + { + switch (angleFormat) + { + case Format::ID::R16_SINT: + return R16I_to_R16_SINT; + default: + break; + } + } + case GL_R16UI: + { + switch (angleFormat) + { + case Format::ID::R16_UINT: + return R16UI_to_R16_UINT; + default: + break; + } + } + case GL_R16_EXT: + { + switch (angleFormat) + { + case Format::ID::R16_UNORM: + return R16_EXT_to_R16_UNORM; + default: + break; + } + } + case GL_R16_SNORM_EXT: + { + switch (angleFormat) + { + case Format::ID::R16_SNORM: + return R16_SNORM_EXT_to_R16_SNORM; + default: + break; + } + } + case GL_R32F: + { + switch (angleFormat) + { + case Format::ID::R32_FLOAT: + return R32F_to_R32_FLOAT; + default: + break; + } + } + case GL_R32I: + { + switch (angleFormat) + { + case Format::ID::R32_SINT: + return R32I_to_R32_SINT; + default: + break; + } + } + case GL_R32UI: + { + switch (angleFormat) + { + case Format::ID::R32_UINT: + return R32UI_to_R32_UINT; + default: + break; + } + } + case GL_R8: + { + switch (angleFormat) + { + case Format::ID::R8_UNORM: + return R8_to_R8_UNORM; + default: + break; + } + } + case GL_R8I: + { + switch (angleFormat) + { + case Format::ID::R8_SINT: + return R8I_to_R8_SINT; + default: + break; + } + } + case GL_R8UI: + { + switch (angleFormat) + { + case Format::ID::R8_UINT: + return R8UI_to_R8_UINT; + default: + break; + } + } + case GL_R8_SNORM: + { + switch (angleFormat) + { + case Format::ID::R8_SNORM: + return R8_SNORM_to_R8_SNORM; + default: + break; + } + } + case GL_RG16F: + { + switch (angleFormat) + { + case Format::ID::R16G16_FLOAT: + return RG16F_to_R16G16_FLOAT; + default: + break; + } + } + case GL_RG16I: + { + switch (angleFormat) + { + case Format::ID::R16G16_SINT: + return RG16I_to_R16G16_SINT; + default: + break; + } + } + case GL_RG16UI: + { + switch (angleFormat) + { + case Format::ID::R16G16_UINT: + return RG16UI_to_R16G16_UINT; + default: + break; + } + } + case GL_RG16_EXT: + { + switch (angleFormat) + { + case Format::ID::R16G16_UNORM: + return RG16_EXT_to_R16G16_UNORM; + default: + break; + } + } + case GL_RG16_SNORM_EXT: + { + switch (angleFormat) + { + case Format::ID::R16G16_SNORM: + return RG16_SNORM_EXT_to_R16G16_SNORM; + default: + break; + } + } + case GL_RG32F: + { + switch (angleFormat) + { + case Format::ID::R32G32_FLOAT: + return RG32F_to_R32G32_FLOAT; + default: + break; + } + } + case GL_RG32I: + { + switch (angleFormat) + { + case Format::ID::R32G32_SINT: + return RG32I_to_R32G32_SINT; + default: + break; + } + } + case GL_RG32UI: + { + switch (angleFormat) + { + case Format::ID::R32G32_UINT: + return RG32UI_to_R32G32_UINT; + default: + break; + } + } + case GL_RG8: + { + switch (angleFormat) + { + case Format::ID::R8G8_UNORM: + return RG8_to_R8G8_UNORM; + default: + break; + } + } + case GL_RG8I: + { + switch (angleFormat) + { + case Format::ID::R8G8_SINT: + return RG8I_to_R8G8_SINT; + default: + break; + } + } + case GL_RG8UI: + { + switch (angleFormat) + { + case Format::ID::R8G8_UINT: + return RG8UI_to_R8G8_UINT; + default: + break; + } + } + case GL_RG8_SNORM: + { + switch (angleFormat) + { + case Format::ID::R8G8_SNORM: + return RG8_SNORM_to_R8G8_SNORM; + default: + break; + } + } + case GL_RGB: + return RGB_to_default; + case GL_RGB10_A2: + { + switch (angleFormat) + { + case Format::ID::R10G10B10A2_UNORM: + return RGB10_A2_to_R10G10B10A2_UNORM; + default: + break; + } + } + case GL_RGB10_A2UI: + { + switch (angleFormat) + { + case Format::ID::R10G10B10A2_UINT: + return RGB10_A2UI_to_R10G10B10A2_UINT; + default: + break; + } + } + case GL_RGB16F: + { + switch (angleFormat) + { + case Format::ID::R16G16B16A16_FLOAT: + return RGB16F_to_R16G16B16A16_FLOAT; + default: + break; + } + } + case GL_RGB16I: + { + switch (angleFormat) + { + case Format::ID::R16G16B16A16_SINT: + return RGB16I_to_R16G16B16A16_SINT; + default: + break; + } + } + case GL_RGB16UI: + { + switch (angleFormat) + { + case Format::ID::R16G16B16A16_UINT: + return RGB16UI_to_R16G16B16A16_UINT; + default: + break; + } + } + case GL_RGB16_EXT: + { + switch (angleFormat) + { + case Format::ID::R16G16B16A16_UNORM: + return RGB16_EXT_to_R16G16B16A16_UNORM; + default: + break; + } + } + case GL_RGB16_SNORM_EXT: + { + switch (angleFormat) + { + case Format::ID::R16G16B16A16_SNORM: + return RGB16_SNORM_EXT_to_R16G16B16A16_SNORM; + default: + break; + } + } + case GL_RGB32F: + { + switch (angleFormat) + { + case Format::ID::R32G32B32A32_FLOAT: + return RGB32F_to_R32G32B32A32_FLOAT; + default: + break; + } + } + case GL_RGB32I: + { + switch (angleFormat) + { + case Format::ID::R32G32B32A32_SINT: + return RGB32I_to_R32G32B32A32_SINT; + default: + break; + } + } + case GL_RGB32UI: + { + switch (angleFormat) + { + case Format::ID::R32G32B32A32_UINT: + return RGB32UI_to_R32G32B32A32_UINT; + default: + break; + } + } + case GL_RGB565: + { + switch (angleFormat) + { + case Format::ID::B5G6R5_UNORM: + return RGB565_to_B5G6R5_UNORM; + case Format::ID::R8G8B8A8_UNORM: + return RGB565_to_R8G8B8A8_UNORM; + default: + break; + } + } + case GL_RGB5_A1: + { + switch (angleFormat) + { + case Format::ID::B5G5R5A1_UNORM: + return RGB5_A1_to_B5G5R5A1_UNORM; + case Format::ID::R8G8B8A8_UNORM: + return RGB5_A1_to_R8G8B8A8_UNORM; + default: + break; + } + } + case GL_RGB8: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_UNORM: + return RGB8_to_R8G8B8A8_UNORM; + default: + break; + } + } + case GL_RGB8I: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_SINT: + return RGB8I_to_R8G8B8A8_SINT; + default: + break; + } + } + case GL_RGB8UI: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_UINT: + return RGB8UI_to_R8G8B8A8_UINT; + default: + break; + } + } + case GL_RGB8_SNORM: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_SNORM: + return RGB8_SNORM_to_R8G8B8A8_SNORM; + default: + break; + } + } + case GL_RGB9_E5: + { + switch (angleFormat) + { + case Format::ID::R9G9B9E5_SHAREDEXP: + return RGB9_E5_to_R9G9B9E5_SHAREDEXP; + default: + break; + } + } + case GL_RGBA: + return RGBA_to_default; + case GL_RGBA16F: + { + switch (angleFormat) + { + case Format::ID::R16G16B16A16_FLOAT: + return RGBA16F_to_R16G16B16A16_FLOAT; + default: + break; + } + } + case GL_RGBA16I: + { + switch (angleFormat) + { + case Format::ID::R16G16B16A16_SINT: + return RGBA16I_to_R16G16B16A16_SINT; + default: + break; + } + } + case GL_RGBA16UI: + { + switch (angleFormat) + { + case Format::ID::R16G16B16A16_UINT: + return RGBA16UI_to_R16G16B16A16_UINT; + default: + break; + } + } + case GL_RGBA16_EXT: + { + switch (angleFormat) + { + case Format::ID::R16G16B16A16_UNORM: + return RGBA16_EXT_to_R16G16B16A16_UNORM; + default: + break; + } + } + case GL_RGBA16_SNORM_EXT: + { + switch (angleFormat) + { + case Format::ID::R16G16B16A16_SNORM: + return RGBA16_SNORM_EXT_to_R16G16B16A16_SNORM; + default: + break; + } + } + case GL_RGBA32F: + { + switch (angleFormat) + { + case Format::ID::R32G32B32A32_FLOAT: + return RGBA32F_to_R32G32B32A32_FLOAT; + default: + break; + } + } + case GL_RGBA32I: + { + switch (angleFormat) + { + case Format::ID::R32G32B32A32_SINT: + return RGBA32I_to_R32G32B32A32_SINT; + default: + break; + } + } + case GL_RGBA32UI: + { + switch (angleFormat) + { + case Format::ID::R32G32B32A32_UINT: + return RGBA32UI_to_R32G32B32A32_UINT; + default: + break; + } + } + case GL_RGBA4: + { + switch (angleFormat) + { + case Format::ID::B4G4R4A4_UNORM: + return RGBA4_to_B4G4R4A4_UNORM; + case Format::ID::R8G8B8A8_UNORM: + return RGBA4_to_R8G8B8A8_UNORM; + default: + break; + } + } + case GL_RGBA8: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_UNORM: + return RGBA8_to_R8G8B8A8_UNORM; + default: + break; + } + } + case GL_RGBA8I: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_SINT: + return RGBA8I_to_R8G8B8A8_SINT; + default: + break; + } + } + case GL_RGBA8UI: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_UINT: + return RGBA8UI_to_R8G8B8A8_UINT; + default: + break; + } + } + case GL_RGBA8_SNORM: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_SNORM: + return RGBA8_SNORM_to_R8G8B8A8_SNORM; + default: + break; + } + } + case GL_SRGB8: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_UNORM_SRGB: + return SRGB8_to_R8G8B8A8_UNORM_SRGB; + default: + break; + } + } + case GL_SRGB8_ALPHA8: + { + switch (angleFormat) + { + case Format::ID::R8G8B8A8_UNORM_SRGB: + return SRGB8_ALPHA8_to_R8G8B8A8_UNORM_SRGB; + default: + break; + } + } + case GL_STENCIL_INDEX8: + return STENCIL_INDEX8_to_default; + + default: + { + static LoadFunctionMap emptyLoadFunctionsMap; + return emptyLoadFunctionsMap; + } + } + // clang-format on + +} // GetLoadFunctionsMap + +} // namespace angle diff --git a/src/3rdparty/angle/src/libANGLE/renderer/renderer_utils.cpp b/src/3rdparty/angle/src/libANGLE/renderer/renderer_utils.cpp new file mode 100644 index 0000000000..55471c1d20 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/renderer_utils.cpp @@ -0,0 +1,549 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// renderer_utils: +// Helper methods pertaining to most or all back-ends. +// + +#include "libANGLE/renderer/renderer_utils.h" + +#include "image_util/copyimage.h" +#include "image_util/imageformats.h" + +#include "libANGLE/AttributeMap.h" +#include "libANGLE/Context.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/ContextImpl.h" +#include "libANGLE/renderer/Format.h" + +#include + +namespace rx +{ + +namespace +{ +typedef std::pair FormatWriteFunctionPair; +typedef std::map FormatWriteFunctionMap; + +static inline void InsertFormatWriteFunctionMapping(FormatWriteFunctionMap *map, + GLenum format, + GLenum type, + ColorWriteFunction writeFunc) +{ + map->insert(FormatWriteFunctionPair(gl::FormatType(format, type), writeFunc)); +} + +static FormatWriteFunctionMap BuildFormatWriteFunctionMap() +{ + using namespace angle; // For image writing functions + + FormatWriteFunctionMap map; + + // clang-format off + // | Format | Type | Color write function | + InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_UNSIGNED_BYTE, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_BYTE, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_FLOAT, WriteColor); + InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_HALF_FLOAT, WriteColor); + InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_HALF_FLOAT_OES, WriteColor); + InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_UNSIGNED_SHORT, + WriteColor); + InsertFormatWriteFunctionMapping(&map, GL_RGBA, GL_SHORT, WriteColor); + + InsertFormatWriteFunctionMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RGBA_INTEGER, GL_BYTE, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RGBA_INTEGER, GL_SHORT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RGBA_INTEGER, GL_INT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, WriteColor ); + + InsertFormatWriteFunctionMapping(&map, GL_RGB, GL_UNSIGNED_BYTE, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RGB, GL_BYTE, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RGB, GL_FLOAT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RGB, GL_HALF_FLOAT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RGB, GL_HALF_FLOAT_OES, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RGB, GL_UNSIGNED_SHORT, + WriteColor); + InsertFormatWriteFunctionMapping(&map, GL_RGB, GL_SHORT, WriteColor); + + InsertFormatWriteFunctionMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RGB_INTEGER, GL_BYTE, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RGB_INTEGER, GL_SHORT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RGB_INTEGER, GL_UNSIGNED_INT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RGB_INTEGER, GL_INT, WriteColor ); + + InsertFormatWriteFunctionMapping(&map, GL_RG, GL_UNSIGNED_BYTE, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RG, GL_BYTE, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RG, GL_FLOAT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RG, GL_HALF_FLOAT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RG, GL_HALF_FLOAT_OES, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RG, GL_UNSIGNED_SHORT, WriteColor); + InsertFormatWriteFunctionMapping(&map, GL_RG, GL_SHORT, WriteColor); + + InsertFormatWriteFunctionMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_BYTE, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RG_INTEGER, GL_BYTE, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_SHORT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RG_INTEGER, GL_SHORT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RG_INTEGER, GL_UNSIGNED_INT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RG_INTEGER, GL_INT, WriteColor ); + + InsertFormatWriteFunctionMapping(&map, GL_RED, GL_UNSIGNED_BYTE, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RED, GL_BYTE, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RED, GL_FLOAT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RED, GL_HALF_FLOAT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RED, GL_HALF_FLOAT_OES, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RED, GL_UNSIGNED_SHORT, WriteColor); + InsertFormatWriteFunctionMapping(&map, GL_RED, GL_SHORT, WriteColor); + + InsertFormatWriteFunctionMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_BYTE, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RED_INTEGER, GL_BYTE, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_SHORT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RED_INTEGER, GL_SHORT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RED_INTEGER, GL_UNSIGNED_INT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_RED_INTEGER, GL_INT, WriteColor ); + + InsertFormatWriteFunctionMapping(&map, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_LUMINANCE, GL_UNSIGNED_BYTE, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_ALPHA, GL_UNSIGNED_BYTE, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_LUMINANCE_ALPHA, GL_FLOAT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_LUMINANCE, GL_FLOAT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_ALPHA, GL_FLOAT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_LUMINANCE, GL_HALF_FLOAT_OES, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_ALPHA, GL_HALF_FLOAT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_ALPHA, GL_HALF_FLOAT_OES, WriteColor ); + + InsertFormatWriteFunctionMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_BYTE, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, WriteColor ); + + InsertFormatWriteFunctionMapping(&map, GL_SRGB_EXT, GL_UNSIGNED_BYTE, WriteColor ); + InsertFormatWriteFunctionMapping(&map, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, WriteColor ); + + InsertFormatWriteFunctionMapping(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, nullptr ); + InsertFormatWriteFunctionMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_UNSIGNED_BYTE, nullptr ); + InsertFormatWriteFunctionMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_UNSIGNED_BYTE, nullptr ); + InsertFormatWriteFunctionMapping(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_UNSIGNED_BYTE, nullptr ); + + InsertFormatWriteFunctionMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, nullptr ); + InsertFormatWriteFunctionMapping(&map, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr ); + InsertFormatWriteFunctionMapping(&map, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr ); + + InsertFormatWriteFunctionMapping(&map, GL_STENCIL, GL_UNSIGNED_BYTE, nullptr ); + + InsertFormatWriteFunctionMapping(&map, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr ); + InsertFormatWriteFunctionMapping(&map, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, nullptr ); + // clang-format on + + return map; +} + +void CopyColor(gl::ColorF *color) +{ + // No-op +} + +void PremultiplyAlpha(gl::ColorF *color) +{ + color->red *= color->alpha; + color->green *= color->alpha; + color->blue *= color->alpha; +} + +void UnmultiplyAlpha(gl::ColorF *color) +{ + if (color->alpha != 0.0f) + { + float invAlpha = 1.0f / color->alpha; + color->red *= invAlpha; + color->green *= invAlpha; + color->blue *= invAlpha; + } +} + +void ClipChannelsR(gl::ColorF *color) +{ + color->green = 0.0f; + color->blue = 0.0f; + color->alpha = 1.0f; +} + +void ClipChannelsRG(gl::ColorF *color) +{ + color->blue = 0.0f; + color->alpha = 1.0f; +} + +void ClipChannelsRGB(gl::ColorF *color) +{ + color->alpha = 1.0f; +} + +void ClipChannelsLuminance(gl::ColorF *color) +{ + color->alpha = 1.0f; +} + +void ClipChannelsAlpha(gl::ColorF *color) +{ + color->red = 0.0f; + color->green = 0.0f; + color->blue = 0.0f; +} + +void ClipChannelsNoOp(gl::ColorF *color) +{ +} + +void WriteUintColor(const gl::ColorF &color, + ColorWriteFunction colorWriteFunction, + uint8_t *destPixelData) +{ + gl::ColorUI destColor( + static_cast(color.red * 255), static_cast(color.green * 255), + static_cast(color.blue * 255), static_cast(color.alpha * 255)); + colorWriteFunction(reinterpret_cast(&destColor), destPixelData); +} + +void WriteFloatColor(const gl::ColorF &color, + ColorWriteFunction colorWriteFunction, + uint8_t *destPixelData) +{ + colorWriteFunction(reinterpret_cast(&color), destPixelData); +} + +} // anonymous namespace + +PackPixelsParams::PackPixelsParams() + : format(GL_NONE), type(GL_NONE), outputPitch(0), packBuffer(nullptr), offset(0) +{ +} + +PackPixelsParams::PackPixelsParams(const gl::Rectangle &areaIn, + GLenum formatIn, + GLenum typeIn, + GLuint outputPitchIn, + const gl::PixelPackState &packIn, + gl::Buffer *packBufferIn, + ptrdiff_t offsetIn) + : area(areaIn), + format(formatIn), + type(typeIn), + outputPitch(outputPitchIn), + packBuffer(packBufferIn), + pack(), + offset(offsetIn) +{ + pack.alignment = packIn.alignment; + pack.reverseRowOrder = packIn.reverseRowOrder; +} + +void PackPixels(const PackPixelsParams ¶ms, + const angle::Format &sourceFormat, + int inputPitchIn, + const uint8_t *sourceIn, + uint8_t *destWithoutOffset) +{ + uint8_t *destWithOffset = destWithoutOffset + params.offset; + + const uint8_t *source = sourceIn; + int inputPitch = inputPitchIn; + + if (params.pack.reverseRowOrder) + { + source += inputPitch * (params.area.height - 1); + inputPitch = -inputPitch; + } + + const auto &sourceGLInfo = gl::GetSizedInternalFormatInfo(sourceFormat.glInternalFormat); + + if (sourceGLInfo.format == params.format && sourceGLInfo.type == params.type) + { + // Direct copy possible + for (int y = 0; y < params.area.height; ++y) + { + memcpy(destWithOffset + y * params.outputPitch, source + y * inputPitch, + params.area.width * sourceGLInfo.pixelBytes); + } + return; + } + + ASSERT(sourceGLInfo.sized); + + gl::FormatType formatType(params.format, params.type); + ColorCopyFunction fastCopyFunc = + GetFastCopyFunction(sourceFormat.fastCopyFunctions, formatType); + const auto &destFormatInfo = gl::GetInternalFormatInfo(formatType.format, formatType.type); + + if (fastCopyFunc) + { + // Fast copy is possible through some special function + for (int y = 0; y < params.area.height; ++y) + { + for (int x = 0; x < params.area.width; ++x) + { + uint8_t *dest = + destWithOffset + y * params.outputPitch + x * destFormatInfo.pixelBytes; + const uint8_t *src = source + y * inputPitch + x * sourceGLInfo.pixelBytes; + + fastCopyFunc(src, dest); + } + } + return; + } + + ColorWriteFunction colorWriteFunction = GetColorWriteFunction(formatType); + + // Maximum size of any Color type used. + uint8_t temp[16]; + static_assert(sizeof(temp) >= sizeof(gl::ColorF) && sizeof(temp) >= sizeof(gl::ColorUI) && + sizeof(temp) >= sizeof(gl::ColorI), + "Unexpected size of gl::Color struct."); + + const auto &colorReadFunction = sourceFormat.colorReadFunction; + + for (int y = 0; y < params.area.height; ++y) + { + for (int x = 0; x < params.area.width; ++x) + { + uint8_t *dest = destWithOffset + y * params.outputPitch + x * destFormatInfo.pixelBytes; + const uint8_t *src = source + y * inputPitch + x * sourceGLInfo.pixelBytes; + + // readFunc and writeFunc will be using the same type of color, CopyTexImage + // will not allow the copy otherwise. + colorReadFunction(src, temp); + colorWriteFunction(temp, dest); + } + } +} + +ColorWriteFunction GetColorWriteFunction(const gl::FormatType &formatType) +{ + static const FormatWriteFunctionMap formatTypeMap = BuildFormatWriteFunctionMap(); + auto iter = formatTypeMap.find(formatType); + ASSERT(iter != formatTypeMap.end()); + if (iter != formatTypeMap.end()) + { + return iter->second; + } + else + { + return nullptr; + } +} + +ColorCopyFunction GetFastCopyFunction(const FastCopyFunctionMap &fastCopyFunctions, + const gl::FormatType &formatType) +{ + return fastCopyFunctions.get(formatType); +} + +bool FastCopyFunctionMap::has(const gl::FormatType &formatType) const +{ + return (get(formatType) != nullptr); +} + +ColorCopyFunction FastCopyFunctionMap::get(const gl::FormatType &formatType) const +{ + for (size_t index = 0; index < mSize; ++index) + { + if (mData[index].format == formatType.format && mData[index].type == formatType.type) + { + return mData[index].func; + } + } + + return nullptr; +} + +bool ShouldUseDebugLayers(const egl::AttributeMap &attribs) +{ + EGLAttrib debugSetting = + attribs.get(EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE, EGL_DONT_CARE); + +// Prefer to enable debug layers if compiling in Debug, and disabled in Release. +#if !defined(NDEBUG) + return (debugSetting != EGL_FALSE); +#else + return (debugSetting == EGL_TRUE); +#endif // !defined(NDEBUG) +} + +void CopyImageCHROMIUM(const uint8_t *sourceData, + size_t sourceRowPitch, + size_t sourcePixelBytes, + ColorReadFunction colorReadFunction, + uint8_t *destData, + size_t destRowPitch, + size_t destPixelBytes, + ColorWriteFunction colorWriteFunction, + GLenum destUnsizedFormat, + GLenum destComponentType, + size_t width, + size_t height, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) +{ + using ConversionFunction = void (*)(gl::ColorF *); + ConversionFunction conversionFunction = CopyColor; + if (unpackPremultiplyAlpha != unpackUnmultiplyAlpha) + { + if (unpackPremultiplyAlpha) + { + conversionFunction = PremultiplyAlpha; + } + else + { + conversionFunction = UnmultiplyAlpha; + } + } + + auto clipChannelsFunction = ClipChannelsNoOp; + switch (destUnsizedFormat) + { + case GL_RED: + clipChannelsFunction = ClipChannelsR; + break; + case GL_RG: + clipChannelsFunction = ClipChannelsRG; + break; + case GL_RGB: + clipChannelsFunction = ClipChannelsRGB; + break; + case GL_LUMINANCE: + clipChannelsFunction = ClipChannelsLuminance; + break; + case GL_ALPHA: + clipChannelsFunction = ClipChannelsAlpha; + break; + } + + auto writeFunction = (destComponentType == GL_UNSIGNED_INT) ? WriteUintColor : WriteFloatColor; + + for (size_t y = 0; y < height; y++) + { + for (size_t x = 0; x < width; x++) + { + const uint8_t *sourcePixelData = sourceData + y * sourceRowPitch + x * sourcePixelBytes; + + gl::ColorF sourceColor; + colorReadFunction(sourcePixelData, reinterpret_cast(&sourceColor)); + + conversionFunction(&sourceColor); + clipChannelsFunction(&sourceColor); + + size_t destY = 0; + if (unpackFlipY) + { + destY += (height - 1); + destY -= y; + } + else + { + destY += y; + } + + uint8_t *destPixelData = destData + destY * destRowPitch + x * destPixelBytes; + writeFunction(sourceColor, colorWriteFunction, destPixelData); + } + } +} + +// IncompleteTextureSet implementation. +IncompleteTextureSet::IncompleteTextureSet() +{ +} + +IncompleteTextureSet::~IncompleteTextureSet() +{ +} + +void IncompleteTextureSet::onDestroy(const gl::Context *context) +{ + // Clear incomplete textures. + for (auto &incompleteTexture : mIncompleteTextures) + { + ANGLE_SWALLOW_ERR(incompleteTexture.second->onDestroy(context)); + incompleteTexture.second.set(context, nullptr); + } + mIncompleteTextures.clear(); +} + +gl::Error IncompleteTextureSet::getIncompleteTexture( + const gl::Context *context, + GLenum type, + MultisampleTextureInitializer *multisampleInitializer, + gl::Texture **textureOut) +{ + auto iter = mIncompleteTextures.find(type); + if (iter != mIncompleteTextures.end()) + { + *textureOut = iter->second.get(); + return gl::NoError(); + } + + ContextImpl *implFactory = context->getImplementation(); + + const GLubyte color[] = {0, 0, 0, 255}; + const gl::Extents colorSize(1, 1, 1); + gl::PixelUnpackState unpack; + unpack.alignment = 1; + const gl::Box area(0, 0, 0, 1, 1, 1); + + // If a texture is external use a 2D texture for the incomplete texture + GLenum createType = (type == GL_TEXTURE_EXTERNAL_OES) ? GL_TEXTURE_2D : type; + + gl::Texture *tex = new gl::Texture(implFactory, std::numeric_limits::max(), createType); + angle::UniqueObjectPointer t(tex, context); + + if (createType == GL_TEXTURE_2D_MULTISAMPLE) + { + ANGLE_TRY(t->setStorageMultisample(context, createType, 1, GL_RGBA8, colorSize, true)); + } + else + { + ANGLE_TRY(t->setStorage(context, createType, 1, GL_RGBA8, colorSize)); + } + + if (type == GL_TEXTURE_CUBE_MAP) + { + for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; + face++) + { + ANGLE_TRY( + t->setSubImage(context, unpack, face, 0, area, GL_RGBA, GL_UNSIGNED_BYTE, color)); + } + } + else if (type == GL_TEXTURE_2D_MULTISAMPLE) + { + // Call a specialized clear function to init a multisample texture. + ANGLE_TRY(multisampleInitializer->initializeMultisampleTextureToBlack(context, t.get())); + } + else + { + ANGLE_TRY( + t->setSubImage(context, unpack, createType, 0, area, GL_RGBA, GL_UNSIGNED_BYTE, color)); + } + + t->syncState(); + + mIncompleteTextures[type].set(context, t.release()); + *textureOut = mIncompleteTextures[type].get(); + return gl::NoError(); +} + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/renderer_utils.h b/src/3rdparty/angle/src/libANGLE/renderer/renderer_utils.h new file mode 100644 index 0000000000..5a1cb38a6a --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/renderer_utils.h @@ -0,0 +1,254 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// renderer_utils: +// Helper methods pertaining to most or all back-ends. +// + +#ifndef LIBANGLE_RENDERER_RENDERER_UTILS_H_ +#define LIBANGLE_RENDERER_RENDERER_UTILS_H_ + +#include + +#include +#include + +#include "common/angleutils.h" +#include "libANGLE/angletypes.h" + +namespace angle +{ +struct Format; +} // namespace angle + +namespace gl +{ +struct FormatType; +struct InternalFormat; +} // namespace gl + +namespace egl +{ +class AttributeMap; +} // namespace egl + +namespace rx +{ + +class ResourceSerial +{ + public: + constexpr ResourceSerial() : mValue(kDirty) {} + explicit constexpr ResourceSerial(uintptr_t value) : mValue(value) {} + constexpr bool operator==(ResourceSerial other) const { return mValue == other.mValue; } + constexpr bool operator!=(ResourceSerial other) const { return mValue != other.mValue; } + + void dirty() { mValue = kDirty; } + void clear() { mValue = kEmpty; } + + constexpr bool valid() const { return mValue != kEmpty && mValue != kDirty; } + constexpr bool empty() const { return mValue == kEmpty; } + + private: + constexpr static uintptr_t kDirty = std::numeric_limits::max(); + constexpr static uintptr_t kEmpty = 0; + + uintptr_t mValue; +}; + +class SerialFactory; + +class Serial final +{ + public: + constexpr Serial() : mValue(kInvalid) {} + constexpr Serial(const Serial &other) = default; + Serial &operator=(const Serial &other) = default; + + constexpr bool operator==(const Serial &other) const + { + return mValue != kInvalid && mValue == other.mValue; + } + constexpr bool operator!=(const Serial &other) const + { + return mValue == kInvalid || mValue != other.mValue; + } + constexpr bool operator>(const Serial &other) const { return mValue > other.mValue; } + constexpr bool operator>=(const Serial &other) const { return mValue >= other.mValue; } + constexpr bool operator<(const Serial &other) const { return mValue < other.mValue; } + constexpr bool operator<=(const Serial &other) const { return mValue <= other.mValue; } + + private: + friend class SerialFactory; + constexpr explicit Serial(uint64_t value) : mValue(value) {} + uint64_t mValue; + static constexpr uint64_t kInvalid = 0; +}; + +class SerialFactory final : angle::NonCopyable +{ + public: + SerialFactory() : mSerial(1) {} + + Serial generate() + { + ASSERT(mSerial != std::numeric_limits::max()); + return Serial(mSerial++); + } + + private: + uint64_t mSerial; +}; + +using MipGenerationFunction = void (*)(size_t sourceWidth, + size_t sourceHeight, + size_t sourceDepth, + const uint8_t *sourceData, + size_t sourceRowPitch, + size_t sourceDepthPitch, + uint8_t *destData, + size_t destRowPitch, + size_t destDepthPitch); + +typedef void (*ColorReadFunction)(const uint8_t *source, uint8_t *dest); +typedef void (*ColorWriteFunction)(const uint8_t *source, uint8_t *dest); +typedef void (*ColorCopyFunction)(const uint8_t *source, uint8_t *dest); + +class FastCopyFunctionMap +{ + public: + struct Entry + { + GLenum format; + GLenum type; + ColorCopyFunction func; + }; + + constexpr FastCopyFunctionMap() : FastCopyFunctionMap(nullptr, 0) {} + + constexpr FastCopyFunctionMap(const Entry *data, size_t size) : mSize(size), mData(data) {} + + bool has(const gl::FormatType &formatType) const; + ColorCopyFunction get(const gl::FormatType &formatType) const; + + private: + size_t mSize; + const Entry *mData; +}; + +struct PackPixelsParams +{ + PackPixelsParams(); + PackPixelsParams(const gl::Rectangle &area, + GLenum format, + GLenum type, + GLuint outputPitch, + const gl::PixelPackState &pack, + gl::Buffer *packBufferIn, + ptrdiff_t offset); + + gl::Rectangle area; + GLenum format; + GLenum type; + GLuint outputPitch; + gl::Buffer *packBuffer; + gl::PixelPackState pack; + ptrdiff_t offset; +}; + +void PackPixels(const PackPixelsParams ¶ms, + const angle::Format &sourceFormat, + int inputPitch, + const uint8_t *source, + uint8_t *destination); + +ColorWriteFunction GetColorWriteFunction(const gl::FormatType &formatType); +ColorCopyFunction GetFastCopyFunction(const FastCopyFunctionMap &fastCopyFunctions, + const gl::FormatType &formatType); + +using InitializeTextureDataFunction = void (*)(size_t width, + size_t height, + size_t depth, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +using LoadImageFunction = void (*)(size_t width, + size_t height, + size_t depth, + const uint8_t *input, + size_t inputRowPitch, + size_t inputDepthPitch, + uint8_t *output, + size_t outputRowPitch, + size_t outputDepthPitch); + +struct LoadImageFunctionInfo +{ + LoadImageFunctionInfo() : loadFunction(nullptr), requiresConversion(false) {} + LoadImageFunctionInfo(LoadImageFunction loadFunction, bool requiresConversion) + : loadFunction(loadFunction), requiresConversion(requiresConversion) + { + } + + LoadImageFunction loadFunction; + bool requiresConversion; +}; + +using LoadFunctionMap = LoadImageFunctionInfo (*)(GLenum); + +bool ShouldUseDebugLayers(const egl::AttributeMap &attribs); + +void CopyImageCHROMIUM(const uint8_t *sourceData, + size_t sourceRowPitch, + size_t sourcePixelBytes, + ColorReadFunction readFunction, + uint8_t *destData, + size_t destRowPitch, + size_t destPixelBytes, + ColorWriteFunction colorWriteFunction, + GLenum destUnsizedFormat, + GLenum destComponentType, + size_t width, + size_t height, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha); + +// Incomplete textures are 1x1 textures filled with black, used when samplers are incomplete. +// This helper class encapsulates handling incomplete textures. Because the GL back-end +// can take advantage of the driver's incomplete textures, and because clearing multisample +// textures is so difficult, we can keep an instance of this class in the back-end instead +// of moving the logic to the Context front-end. + +// This interface allows us to call-back to init a multisample texture. +class MultisampleTextureInitializer +{ + public: + virtual ~MultisampleTextureInitializer() {} + virtual gl::Error initializeMultisampleTextureToBlack(const gl::Context *context, + gl::Texture *glTexture) = 0; +}; + +class IncompleteTextureSet final : angle::NonCopyable +{ + public: + IncompleteTextureSet(); + ~IncompleteTextureSet(); + + void onDestroy(const gl::Context *context); + + gl::Error getIncompleteTexture(const gl::Context *context, + GLenum type, + MultisampleTextureInitializer *multisampleInitializer, + gl::Texture **textureOut); + + private: + gl::TextureMap mIncompleteTextures; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_RENDERER_UTILS_H_ diff --git a/src/3rdparty/angle/src/libANGLE/signal_utils.h b/src/3rdparty/angle/src/libANGLE/signal_utils.h new file mode 100644 index 0000000000..3dd1332013 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/signal_utils.h @@ -0,0 +1,187 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// signal_utils: +// Helper classes for tracking dependent state changes between objects. +// These changes are signaled to the dependent class via channels. +// See design document: +// https://docs.google.com/document/d/15Edfotqg6_l1skTEL8ADQudF_oIdNa7i8Po43k6jMd4/ + +#ifndef LIBANGLE_SIGNAL_UTILS_H_ +#define LIBANGLE_SIGNAL_UTILS_H_ + +#include + +#include "common/angleutils.h" +#include "common/debug.h" + +namespace angle +{ + +// Interface that the depending class inherits from. +template +class SignalReceiver +{ + public: + virtual ~SignalReceiver() = default; + virtual void signal(ChannelID channelID, MessageT... message) = 0; +}; + +template +class ChannelBinding; + +// The host class owns the channel. It uses the channel to fire signals to the receiver. +template +class BroadcastChannel final : NonCopyable +{ + public: + BroadcastChannel(); + ~BroadcastChannel(); + + void signal(MessageT... message) const; + + void reset(); + + bool empty() const; + + private: + // Only the ChannelBinding class should add or remove receivers. + friend class ChannelBinding; + void addReceiver(ChannelBinding *receiver); + void removeReceiver(ChannelBinding *receiver); + + std::vector *> mReceivers; +}; + +template +BroadcastChannel::BroadcastChannel() +{ +} + +template +BroadcastChannel::~BroadcastChannel() +{ + reset(); +} + +template +void BroadcastChannel::addReceiver( + ChannelBinding *receiver) +{ + ASSERT(std::find(mReceivers.begin(), mReceivers.end(), receiver) == mReceivers.end()); + mReceivers.push_back(receiver); +} + +template +void BroadcastChannel::removeReceiver( + ChannelBinding *receiver) +{ + auto iter = std::find(mReceivers.begin(), mReceivers.end(), receiver); + ASSERT(iter != mReceivers.end()); + mReceivers.erase(iter); +} + +template +void BroadcastChannel::signal(MessageT... message) const +{ + if (mReceivers.empty()) + return; + + for (const auto *receiver : mReceivers) + { + receiver->signal(message...); + } +} + +template +void BroadcastChannel::reset() +{ + for (auto receiver : mReceivers) + { + receiver->onChannelClosed(); + } + mReceivers.clear(); +} + +template +bool BroadcastChannel::empty() const +{ + return mReceivers.empty(); +} + +// The dependent class keeps bindings to the host's BroadcastChannel. +template +class ChannelBinding final +{ + public: + ChannelBinding(SignalReceiver *receiver, ChannelID channelID); + ~ChannelBinding(); + ChannelBinding(const ChannelBinding &other) = default; + ChannelBinding &operator=(const ChannelBinding &other) = default; + + void bind(BroadcastChannel *channel); + void reset(); + void signal(MessageT... message) const; + void onChannelClosed(); + + private: + BroadcastChannel *mChannel; + SignalReceiver *mReceiver; + ChannelID mChannelID; +}; + +template +ChannelBinding::ChannelBinding( + SignalReceiver *receiver, + ChannelID channelID) + : mChannel(nullptr), mReceiver(receiver), mChannelID(channelID) +{ + ASSERT(receiver); +} + +template +ChannelBinding::~ChannelBinding() +{ + reset(); +} + +template +void ChannelBinding::bind(BroadcastChannel *channel) +{ + ASSERT(mReceiver); + if (mChannel) + { + mChannel->removeReceiver(this); + } + + mChannel = channel; + + if (mChannel) + { + mChannel->addReceiver(this); + } +} + +template +void ChannelBinding::reset() +{ + bind(nullptr); +} + +template +void ChannelBinding::signal(MessageT... message) const +{ + mReceiver->signal(mChannelID, message...); +} + +template +void ChannelBinding::onChannelClosed() +{ + mChannel = nullptr; +} + +} // namespace angle + +#endif // LIBANGLE_SIGNAL_UTILS_H_ diff --git a/src/3rdparty/angle/src/libANGLE/validationEGL.cpp b/src/3rdparty/angle/src/libANGLE/validationEGL.cpp index 903f51b158..13a3a9e280 100644 --- a/src/3rdparty/angle/src/libANGLE/validationEGL.cpp +++ b/src/3rdparty/angle/src/libANGLE/validationEGL.cpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -14,10 +14,15 @@ #include "libANGLE/Device.h" #include "libANGLE/Display.h" #include "libANGLE/Image.h" +#include "libANGLE/Stream.h" #include "libANGLE/Surface.h" +#include "libANGLE/Texture.h" +#include "libANGLE/formatutils.h" #include +namespace egl +{ namespace { size_t GetMaximumMipLevel(const gl::Context *context, GLenum target) @@ -30,6 +35,9 @@ size_t GetMaximumMipLevel(const gl::Context *context, GLenum target) case GL_TEXTURE_2D: maxDimension = caps.max2DTextureSize; break; + case GL_TEXTURE_RECTANGLE_ANGLE: + maxDimension = caps.maxRectangleTextureSize; + break; case GL_TEXTURE_CUBE_MAP: maxDimension = caps.maxCubeMapTextureSize; break; @@ -56,7 +64,7 @@ bool TextureHasNonZeroMipLevelsSpecified(const gl::Context *context, const gl::T for (GLenum face = gl::FirstCubeMapTextureTarget; face <= gl::LastCubeMapTextureTarget; face++) { - if (texture->getInternalFormat(face, level) != GL_NONE) + if (texture->getFormat(face, level).valid()) { return true; } @@ -64,7 +72,7 @@ bool TextureHasNonZeroMipLevelsSpecified(const gl::Context *context, const gl::T } else { - if (texture->getInternalFormat(texture->getTarget(), level) != GL_NONE) + if (texture->getFormat(texture->getTarget(), level).valid()) { return true; } @@ -79,7 +87,7 @@ bool CubeTextureHasUnspecifiedLevel0Face(const gl::Texture *texture) ASSERT(texture->getTarget() == GL_TEXTURE_CUBE_MAP); for (GLenum face = gl::FirstCubeMapTextureTarget; face <= gl::LastCubeMapTextureTarget; face++) { - if (texture->getInternalFormat(face, 0) == GL_NONE) + if (!texture->getFormat(face, 0).valid()) { return true; } @@ -87,114 +95,482 @@ bool CubeTextureHasUnspecifiedLevel0Face(const gl::Texture *texture) return false; } + +Error ValidateStreamAttribute(const EGLAttrib attribute, + const EGLAttrib value, + const DisplayExtensions &extensions) +{ + switch (attribute) + { + case EGL_STREAM_STATE_KHR: + case EGL_PRODUCER_FRAME_KHR: + case EGL_CONSUMER_FRAME_KHR: + return EglBadAccess() << "Attempt to initialize readonly parameter"; + case EGL_CONSUMER_LATENCY_USEC_KHR: + // Technically not in spec but a latency < 0 makes no sense so we check it + if (value < 0) + { + return EglBadParameter() << "Latency must be positive"; + } + break; + case EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR: + if (!extensions.streamConsumerGLTexture) + { + return EglBadAttribute() << "Consumer GL extension not enabled"; + } + // Again not in spec but it should be positive anyways + if (value < 0) + { + return EglBadParameter() << "Timeout must be positive"; + } + break; + default: + return EglBadAttribute() << "Invalid stream attribute"; + } + return NoError(); } -namespace egl +Error ValidateCreateImageKHRMipLevelCommon(gl::Context *context, + const gl::Texture *texture, + EGLAttrib level) { + // Note that the spec EGL_KHR_create_image spec does not explicitly specify an error + // when the level is outside the base/max level range, but it does mention that the + // level "must be a part of the complete texture object ". It can be argued + // that out-of-range levels are not a part of the complete texture. + const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel(); + if (level > 0 && + (!texture->isMipmapComplete() || static_cast(level) < effectiveBaseLevel || + static_cast(level) > texture->getTextureState().getMipmapMaxLevel())) + { + return EglBadParameter() << "texture must be complete if level is non-zero."; + } + + if (level == 0 && !texture->isMipmapComplete() && + TextureHasNonZeroMipLevelsSpecified(context, texture)) + { + return EglBadParameter() << "if level is zero and the texture is incomplete, it must " + "have no mip levels specified except zero."; + } + + return NoError(); +} + +Error ValidateConfigAttribute(const Display *display, EGLAttrib attribute) +{ + switch (attribute) + { + case EGL_BUFFER_SIZE: + case EGL_ALPHA_SIZE: + case EGL_BLUE_SIZE: + case EGL_GREEN_SIZE: + case EGL_RED_SIZE: + case EGL_DEPTH_SIZE: + case EGL_STENCIL_SIZE: + case EGL_CONFIG_CAVEAT: + case EGL_CONFIG_ID: + case EGL_LEVEL: + case EGL_NATIVE_RENDERABLE: + case EGL_NATIVE_VISUAL_ID: + case EGL_NATIVE_VISUAL_TYPE: + case EGL_SAMPLES: + case EGL_SAMPLE_BUFFERS: + case EGL_SURFACE_TYPE: + case EGL_TRANSPARENT_TYPE: + case EGL_TRANSPARENT_BLUE_VALUE: + case EGL_TRANSPARENT_GREEN_VALUE: + case EGL_TRANSPARENT_RED_VALUE: + case EGL_BIND_TO_TEXTURE_RGB: + case EGL_BIND_TO_TEXTURE_RGBA: + case EGL_MIN_SWAP_INTERVAL: + case EGL_MAX_SWAP_INTERVAL: + case EGL_LUMINANCE_SIZE: + case EGL_ALPHA_MASK_SIZE: + case EGL_COLOR_BUFFER_TYPE: + case EGL_RENDERABLE_TYPE: + case EGL_MATCH_NATIVE_PIXMAP: + case EGL_CONFORMANT: + case EGL_MAX_PBUFFER_WIDTH: + case EGL_MAX_PBUFFER_HEIGHT: + case EGL_MAX_PBUFFER_PIXELS: + break; + + case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE: + if (!display->getExtensions().surfaceOrientation) + { + return EglBadAttribute() << "EGL_ANGLE_surface_orientation is not enabled."; + } + break; + + case EGL_COLOR_COMPONENT_TYPE_EXT: + if (!display->getExtensions().pixelFormatFloat) + { + return EglBadAttribute() << "EGL_EXT_pixel_format_float is not enabled."; + } + break; + + default: + return EglBadAttribute() << "Unknown attribute."; + } + + return NoError(); +} + +Error ValidateConfigAttributes(const Display *display, const AttributeMap &attributes) +{ + for (const auto &attrib : attributes) + { + ANGLE_TRY(ValidateConfigAttribute(display, attrib.first)); + } + + return NoError(); +} + +Error ValidatePlatformType(const ClientExtensions &clientExtensions, EGLAttrib platformType) +{ + switch (platformType) + { + case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE: + break; + + case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE: + case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE: + if (!clientExtensions.platformANGLED3D) + { + return EglBadAttribute() << "Direct3D platform is unsupported."; + } + break; + + case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE: + case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE: + if (!clientExtensions.platformANGLEOpenGL) + { + return EglBadAttribute() << "OpenGL platform is unsupported."; + } + break; + + case EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE: + if (!clientExtensions.platformANGLENULL) + { + return EglBadAttribute() << "Display type EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE " + "requires EGL_ANGLE_platform_angle_null."; + } + break; + + case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE: + if (!clientExtensions.platformANGLEVulkan) + { + return EglBadAttribute() << "Vulkan platform is unsupported."; + } + break; + + default: + return EglBadAttribute() << "Unknown platform type."; + } + + return NoError(); +} + +Error ValidateGetPlatformDisplayCommon(EGLenum platform, + void *native_display, + const AttributeMap &attribMap) +{ + const ClientExtensions &clientExtensions = Display::GetClientExtensions(); + + switch (platform) + { + case EGL_PLATFORM_ANGLE_ANGLE: + if (!clientExtensions.platformANGLE) + { + return EglBadParameter() << "Platform ANGLE extension is not active"; + } + break; + case EGL_PLATFORM_DEVICE_EXT: + if (!clientExtensions.platformDevice) + { + return EglBadParameter() << "Platform Device extension is not active"; + } + break; + default: + return EglBadConfig() << "Bad platform type."; + } + + if (platform == EGL_PLATFORM_ANGLE_ANGLE) + { + EGLAttrib platformType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE; + EGLAttrib deviceType = EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE; + bool enableAutoTrimSpecified = false; + bool deviceTypeSpecified = false; + bool presentPathSpecified = false; + + Optional majorVersion; + Optional minorVersion; + + for (const auto &curAttrib : attribMap) + { + const EGLAttrib value = curAttrib.second; + + switch (curAttrib.first) + { + case EGL_PLATFORM_ANGLE_TYPE_ANGLE: + { + ANGLE_TRY(ValidatePlatformType(clientExtensions, value)); + platformType = value; + break; + } + + case EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE: + if (value != EGL_DONT_CARE) + { + majorVersion = value; + } + break; + + case EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE: + if (value != EGL_DONT_CARE) + { + minorVersion = value; + } + break; + + case EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE: + switch (value) + { + case EGL_TRUE: + case EGL_FALSE: + break; + default: + return EglBadAttribute() << "Invalid automatic trim attribute"; + } + enableAutoTrimSpecified = true; + break; + + case EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE: + if (!clientExtensions.experimentalPresentPath) + { + return EglBadAttribute() + << "EGL_ANGLE_experimental_present_path extension not active"; + } + + switch (value) + { + case EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE: + case EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE: + break; + default: + return EglBadAttribute() + << "Invalid value for EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE"; + } + presentPathSpecified = true; + break; + + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE: + switch (value) + { + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE: + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE: + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE: + deviceTypeSpecified = true; + break; + + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE: + // This is a hidden option, accepted by the OpenGL back-end. + break; + + default: + return EglBadAttribute() << "Invalid value for " + "EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE " + "attrib"; + } + deviceType = value; + break; + + case EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE: + if (!clientExtensions.platformANGLE) + { + return EglBadAttribute() << "EGL_ANGLE_platform_angle extension not active"; + } + if (value != EGL_TRUE && value != EGL_FALSE && value != EGL_DONT_CARE) + { + return EglBadAttribute() << "EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE " + "must be EGL_TRUE, EGL_FALSE, or " + "EGL_DONT_CARE."; + } + break; + + default: + break; + } + } + + if (!majorVersion.valid() && minorVersion.valid()) + { + return EglBadAttribute() + << "Must specify major version if you specify a minor version."; + } + + if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE && + platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + return EglBadAttribute() << "EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE requires a " + "device type of EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE."; + } + + if (enableAutoTrimSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + return EglBadAttribute() << "EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE " + "requires a device type of " + "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE."; + } + + if (presentPathSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + return EglBadAttribute() << "EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE requires a " + "device type of EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE."; + } + + if (deviceTypeSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE && + platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) + { + return EglBadAttribute() << "EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE requires a " + "device type of EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE or " + "EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE."; + } + + if (platformType == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) + { + if ((majorVersion.valid() && majorVersion.value() != 1) || + (minorVersion.valid() && minorVersion.value() != 0)) + { + return EglBadAttribute() << "EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE currently " + "only supports Vulkan 1.0."; + } + } + } + else if (platform == EGL_PLATFORM_DEVICE_EXT) + { + Device *eglDevice = reinterpret_cast(native_display); + if (eglDevice == nullptr || !Device::IsValidDevice(eglDevice)) + { + return EglBadAttribute() << "native_display should be a valid EGL device if " + "platform equals EGL_PLATFORM_DEVICE_EXT"; + } + } + else + { + UNREACHABLE(); + } + + return NoError(); +} + +} // namespace Error ValidateDisplay(const Display *display) { if (display == EGL_NO_DISPLAY) { - return Error(EGL_BAD_DISPLAY, "display is EGL_NO_DISPLAY."); + return EglBadDisplay() << "display is EGL_NO_DISPLAY."; } if (!Display::isValidDisplay(display)) { - return Error(EGL_BAD_DISPLAY, "display is not a valid display."); + return EglBadDisplay() << "display is not a valid display."; } if (!display->isInitialized()) { - return Error(EGL_NOT_INITIALIZED, "display is not initialized."); + return EglNotInitialized() << "display is not initialized."; } - return Error(EGL_SUCCESS); + if (display->isDeviceLost()) + { + return EglContextLost() << "display had a context loss"; + } + + return NoError(); } -Error ValidateSurface(const Display *display, Surface *surface) +Error ValidateSurface(const Display *display, const Surface *surface) { - Error error = ValidateDisplay(display); - if (error.isError()) - { - return error; - } + ANGLE_TRY(ValidateDisplay(display)); if (!display->isValidSurface(surface)) { - return Error(EGL_BAD_SURFACE); + return EglBadSurface(); } - return Error(EGL_SUCCESS); + return NoError(); } Error ValidateConfig(const Display *display, const Config *config) { - Error error = ValidateDisplay(display); - if (error.isError()) - { - return error; - } + ANGLE_TRY(ValidateDisplay(display)); if (!display->isValidConfig(config)) { - return Error(EGL_BAD_CONFIG); + return EglBadConfig(); } - return Error(EGL_SUCCESS); + return NoError(); } -Error ValidateContext(const Display *display, gl::Context *context) +Error ValidateContext(const Display *display, const gl::Context *context) { - Error error = ValidateDisplay(display); - if (error.isError()) - { - return error; - } + ANGLE_TRY(ValidateDisplay(display)); if (!display->isValidContext(context)) { - return Error(EGL_BAD_CONTEXT); + return EglBadContext(); } - return Error(EGL_SUCCESS); + return NoError(); } Error ValidateImage(const Display *display, const Image *image) { - Error error = ValidateDisplay(display); - if (error.isError()) - { - return error; - } + ANGLE_TRY(ValidateDisplay(display)); if (!display->isValidImage(image)) { - return Error(EGL_BAD_PARAMETER, "image is not valid."); + return EglBadParameter() << "image is not valid."; } - return Error(EGL_SUCCESS); + return NoError(); +} + +Error ValidateStream(const Display *display, const Stream *stream) +{ + ANGLE_TRY(ValidateDisplay(display)); + + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.stream) + { + return EglBadAccess() << "Stream extension not active"; + } + + if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream)) + { + return EglBadStream() << "Invalid stream"; + } + + return NoError(); } Error ValidateCreateContext(Display *display, Config *configuration, gl::Context *shareContext, const AttributeMap& attributes) { - Error error = ValidateConfig(display, configuration); - if (error.isError()) - { - return error; - } + ANGLE_TRY(ValidateConfig(display, configuration)); // Get the requested client version (default is 1) and check it is 2 or 3. - EGLint clientMajorVersion = 1; - EGLint clientMinorVersion = 0; - EGLint contextFlags = 0; + EGLAttrib clientMajorVersion = 1; + EGLAttrib clientMinorVersion = 0; + EGLAttrib contextFlags = 0; bool resetNotification = false; - bool robustAccess = false; for (AttributeMap::const_iterator attributeIter = attributes.begin(); attributeIter != attributes.end(); attributeIter++) { - EGLint attribute = attributeIter->first; - EGLint value = attributeIter->second; + EGLAttrib attribute = attributeIter->first; + EGLAttrib value = attributeIter->second; switch (attribute) { @@ -215,28 +591,27 @@ Error ValidateCreateContext(Display *display, Config *configuration, gl::Context case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR: // Only valid for OpenGL (non-ES) contexts - return Error(EGL_BAD_ATTRIBUTE); + return EglBadAttribute(); case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT: if (!display->getExtensions().createContextRobustness) { - return Error(EGL_BAD_ATTRIBUTE); + return EglBadAttribute(); } if (value != EGL_TRUE && value != EGL_FALSE) { - return Error(EGL_BAD_ATTRIBUTE); + return EglBadAttribute(); } - robustAccess = (value == EGL_TRUE); break; case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR: - static_assert(EGL_LOSE_CONTEXT_ON_RESET_EXT == EGL_LOSE_CONTEXT_ON_RESET_KHR, "EGL extension enums not equal."); - static_assert(EGL_NO_RESET_NOTIFICATION_EXT == EGL_NO_RESET_NOTIFICATION_KHR, "EGL extension enums not equal."); - // same as EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, fall through + return EglBadAttribute() << "EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR is not" + << " valid for GLES with EGL 1.4 and KHR_create_context. Use" + << " EXT_create_context_robustness."; case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT: if (!display->getExtensions().createContextRobustness) { - return Error(EGL_BAD_ATTRIBUTE); + return EglBadAttribute(); } if (value == EGL_LOSE_CONTEXT_ON_RESET_EXT) { @@ -244,34 +619,143 @@ Error ValidateCreateContext(Display *display, Config *configuration, gl::Context } else if (value != EGL_NO_RESET_NOTIFICATION_EXT) { - return Error(EGL_BAD_ATTRIBUTE); + return EglBadAttribute(); } break; case EGL_CONTEXT_OPENGL_NO_ERROR_KHR: if (!display->getExtensions().createContextNoError) { - return Error(EGL_BAD_ATTRIBUTE, "Invalid Context attribute."); + return EglBadAttribute() << "Invalid Context attribute."; } if (value != EGL_TRUE && value != EGL_FALSE) { - return Error(EGL_BAD_ATTRIBUTE, "Attribute must be EGL_TRUE or EGL_FALSE."); + return EglBadAttribute() << "Attribute must be EGL_TRUE or EGL_FALSE."; + } + break; + + case EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE: + if (!display->getExtensions().createContextWebGLCompatibility) + { + return EglBadAttribute() << "Attribute " + "EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE requires " + "EGL_ANGLE_create_context_webgl_compatibility."; + } + if (value != EGL_TRUE && value != EGL_FALSE) + { + return EglBadAttribute() + << "EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE must be EGL_TRUE or EGL_FALSE."; + } + break; + + case EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM: + if (!display->getExtensions().createContextBindGeneratesResource) + { + return EglBadAttribute() + << "Attribute EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM requires " + "EGL_CHROMIUM_create_context_bind_generates_resource."; + } + if (value != EGL_TRUE && value != EGL_FALSE) + { + return EglBadAttribute() << "EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM " + "must be EGL_TRUE or EGL_FALSE."; + } + break; + + case EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE: + if (!display->getExtensions().displayTextureShareGroup) + { + return EglBadAttribute() << "Attribute " + "EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE requires " + "EGL_ANGLE_display_texture_share_group."; + } + if (value != EGL_TRUE && value != EGL_FALSE) + { + return EglBadAttribute() + << "EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE must be EGL_TRUE or EGL_FALSE."; + } + if (shareContext && + (shareContext->usingDisplayTextureShareGroup() != (value == EGL_TRUE))) + { + return EglBadAttribute() << "All contexts within a share group must be " + "created with the same value of " + "EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE."; + } + break; + + case EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE: + if (!display->getExtensions().createContextClientArrays) + { + return EglBadAttribute() + << "Attribute EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE requires " + "EGL_ANGLE_create_context_client_arrays."; + } + if (value != EGL_TRUE && value != EGL_FALSE) + { + return EglBadAttribute() << "EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE must " + "be EGL_TRUE or EGL_FALSE."; + } + break; + + case EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE: + if (!display->getExtensions().programCacheControl) + { + return EglBadAttribute() + << "Attribute EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE " + "requires EGL_ANGLE_program_cache_control."; + } + if (value != EGL_TRUE && value != EGL_FALSE) + { + return EglBadAttribute() << "EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE must " + "be EGL_TRUE or EGL_FALSE."; + } + break; + + case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: + if (!display->getExtensions().robustResourceInitialization) + { + return EglBadAttribute() << "Attribute EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE " + "requires EGL_ANGLE_robust_resource_initialization."; + } + if (value != EGL_TRUE && value != EGL_FALSE) + { + return EglBadAttribute() << "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE must be " + "either EGL_TRUE or EGL_FALSE."; } break; default: - return Error(EGL_BAD_ATTRIBUTE); + return EglBadAttribute() << "Unknown attribute."; } } - if ((clientMajorVersion != 2 && clientMajorVersion != 3) || clientMinorVersion != 0) + switch (clientMajorVersion) { - return Error(EGL_BAD_CONFIG); - } - - if (clientMajorVersion == 3 && !(configuration->conformant & EGL_OPENGL_ES3_BIT_KHR) && !(configuration->configCaveat & EGL_NON_CONFORMANT_CONFIG)) - { - return Error(EGL_BAD_CONFIG); + case 2: + if (clientMinorVersion != 0) + { + return EglBadConfig(); + } + break; + case 3: + if (clientMinorVersion != 0 && clientMinorVersion != 1) + { + return EglBadConfig(); + } + if (!(configuration->conformant & EGL_OPENGL_ES3_BIT_KHR)) + { + return EglBadConfig(); + } + if (display->getMaxSupportedESVersion() < + gl::Version(static_cast(clientMajorVersion), + static_cast(clientMinorVersion))) + { + return EglBadConfig() << "Requested GLES version is not supported."; + } + break; + default: + return EglBadConfig(); + break; } // Note: EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR does not apply to ES @@ -279,18 +763,7 @@ Error ValidateCreateContext(Display *display, Config *configuration, gl::Context EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR); if ((contextFlags & ~validContextFlags) != 0) { - return Error(EGL_BAD_ATTRIBUTE); - } - - if ((contextFlags & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) > 0) - { - robustAccess = true; - } - - if (robustAccess) - { - // Unimplemented - return Error(EGL_BAD_CONFIG); + return EglBadAttribute(); } if (shareContext) @@ -298,43 +771,40 @@ Error ValidateCreateContext(Display *display, Config *configuration, gl::Context // Shared context is invalid or is owned by another display if (!display->isValidContext(shareContext)) { - return Error(EGL_BAD_MATCH); + return EglBadMatch(); } if (shareContext->isResetNotificationEnabled() != resetNotification) { - return Error(EGL_BAD_MATCH); + return EglBadMatch(); } - if (shareContext->getClientVersion() != clientMajorVersion) + if (shareContext->getClientMajorVersion() != clientMajorVersion || + shareContext->getClientMinorVersion() != clientMinorVersion) { - return Error(EGL_BAD_CONTEXT); + return EglBadContext(); } } - return Error(EGL_SUCCESS); + return NoError(); } Error ValidateCreateWindowSurface(Display *display, Config *config, EGLNativeWindowType window, const AttributeMap& attributes) { - Error error = ValidateConfig(display, config); - if (error.isError()) - { - return error; - } + ANGLE_TRY(ValidateConfig(display, config)); if (!display->isValidNativeWindow(window)) { - return Error(EGL_BAD_NATIVE_WINDOW); + return EglBadNativeWindow(); } const DisplayExtensions &displayExtensions = display->getExtensions(); for (AttributeMap::const_iterator attributeIter = attributes.begin(); attributeIter != attributes.end(); attributeIter++) { - EGLint attribute = attributeIter->first; - EGLint value = attributeIter->second; + EGLAttrib attribute = attributeIter->first; + EGLAttrib value = attributeIter->second; switch (attribute) { @@ -344,23 +814,23 @@ Error ValidateCreateWindowSurface(Display *display, Config *config, EGLNativeWin case EGL_BACK_BUFFER: break; case EGL_SINGLE_BUFFER: - return Error(EGL_BAD_MATCH); // Rendering directly to front buffer not supported + return EglBadMatch(); // Rendering directly to front buffer not supported default: - return Error(EGL_BAD_ATTRIBUTE); + return EglBadAttribute(); } break; case EGL_POST_SUB_BUFFER_SUPPORTED_NV: if (!displayExtensions.postSubBuffer) { - return Error(EGL_BAD_ATTRIBUTE); + return EglBadAttribute(); } break; case EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE: if (!displayExtensions.flexibleSurfaceCompatibility) { - return Error(EGL_BAD_ATTRIBUTE); + return EglBadAttribute(); } break; @@ -368,68 +838,77 @@ Error ValidateCreateWindowSurface(Display *display, Config *config, EGLNativeWin case EGL_HEIGHT: if (!displayExtensions.windowFixedSize) { - return Error(EGL_BAD_ATTRIBUTE); + return EglBadAttribute(); } if (value < 0) { - return Error(EGL_BAD_PARAMETER); + return EglBadParameter(); } break; case EGL_FIXED_SIZE_ANGLE: if (!displayExtensions.windowFixedSize) { - return Error(EGL_BAD_ATTRIBUTE); + return EglBadAttribute(); } break; case EGL_SURFACE_ORIENTATION_ANGLE: if (!displayExtensions.surfaceOrientation) { - return Error(EGL_BAD_ATTRIBUTE, "EGL_ANGLE_surface_orientation is not enabled."); + return EglBadAttribute() << "EGL_ANGLE_surface_orientation is not enabled."; } break; case EGL_VG_COLORSPACE: - return Error(EGL_BAD_MATCH); + return EglBadMatch(); case EGL_VG_ALPHA_FORMAT: - return Error(EGL_BAD_MATCH); + return EglBadMatch(); case EGL_DIRECT_COMPOSITION_ANGLE: if (!displayExtensions.directComposition) { - return Error(EGL_BAD_ATTRIBUTE); + return EglBadAttribute(); + } + break; + + case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: + if (!display->getExtensions().robustResourceInitialization) + { + return EglBadAttribute() << "Attribute EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE " + "requires EGL_ANGLE_robust_resource_initialization."; + } + if (value != EGL_TRUE && value != EGL_FALSE) + { + return EglBadAttribute() << "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE must be " + "either EGL_TRUE or EGL_FALSE."; } break; default: - return Error(EGL_BAD_ATTRIBUTE); + return EglBadAttribute(); } } if (Display::hasExistingWindowSurface(window)) { - return Error(EGL_BAD_ALLOC); + return EglBadAlloc(); } - return Error(EGL_SUCCESS); + return NoError(); } Error ValidateCreatePbufferSurface(Display *display, Config *config, const AttributeMap& attributes) { - Error error = ValidateConfig(display, config); - if (error.isError()) - { - return error; - } + ANGLE_TRY(ValidateConfig(display, config)); const DisplayExtensions &displayExtensions = display->getExtensions(); for (AttributeMap::const_iterator attributeIter = attributes.begin(); attributeIter != attributes.end(); attributeIter++) { - EGLint attribute = attributeIter->first; - EGLint value = attributeIter->second; + EGLAttrib attribute = attributeIter->first; + EGLAttrib value = attributeIter->second; switch (attribute) { @@ -437,7 +916,7 @@ Error ValidateCreatePbufferSurface(Display *display, Config *config, const Attri case EGL_HEIGHT: if (value < 0) { - return Error(EGL_BAD_PARAMETER); + return EglBadParameter(); } break; @@ -452,7 +931,7 @@ Error ValidateCreatePbufferSurface(Display *display, Config *config, const Attri case EGL_TEXTURE_RGBA: break; default: - return Error(EGL_BAD_ATTRIBUTE); + return EglBadAttribute(); } break; @@ -463,7 +942,7 @@ Error ValidateCreatePbufferSurface(Display *display, Config *config, const Attri case EGL_TEXTURE_2D: break; default: - return Error(EGL_BAD_ATTRIBUTE); + return EglBadAttribute(); } break; @@ -479,60 +958,66 @@ Error ValidateCreatePbufferSurface(Display *display, Config *config, const Attri case EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE: if (!displayExtensions.flexibleSurfaceCompatibility) { - return Error( - EGL_BAD_ATTRIBUTE, - "EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE cannot be used without " - "EGL_ANGLE_flexible_surface_compatibility support."); + return EglBadAttribute() + << "EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE cannot be used " + "without EGL_ANGLE_flexible_surface_compatibility support."; + } + break; + + case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: + if (!display->getExtensions().robustResourceInitialization) + { + return EglBadAttribute() << "Attribute EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE " + "requires EGL_ANGLE_robust_resource_initialization."; + } + if (value != EGL_TRUE && value != EGL_FALSE) + { + return EglBadAttribute() << "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE must be " + "either EGL_TRUE or EGL_FALSE."; } break; default: - return Error(EGL_BAD_ATTRIBUTE); + return EglBadAttribute(); } } if (!(config->surfaceType & EGL_PBUFFER_BIT)) { - return Error(EGL_BAD_MATCH); + return EglBadMatch(); } -#if !defined(ANGLE_ENABLE_WINDOWS_STORE) // On Windows Store, we know the originating texture came from D3D11, so bypass this check const Caps &caps = display->getCaps(); - EGLenum textureFormat = attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE); - EGLenum textureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE); + EGLAttrib textureFormat = attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE); + EGLAttrib textureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE); if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) || (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE)) { - return Error(EGL_BAD_MATCH); + return EglBadMatch(); } if ((textureFormat == EGL_TEXTURE_RGB && config->bindToTextureRGB != EGL_TRUE) || (textureFormat == EGL_TEXTURE_RGBA && config->bindToTextureRGBA != EGL_TRUE)) { - return Error(EGL_BAD_ATTRIBUTE); + return EglBadAttribute(); } - EGLint width = attributes.get(EGL_WIDTH, 0); - EGLint height = attributes.get(EGL_HEIGHT, 0); + EGLint width = static_cast(attributes.get(EGL_WIDTH, 0)); + EGLint height = static_cast(attributes.get(EGL_HEIGHT, 0)); if (textureFormat != EGL_NO_TEXTURE && !caps.textureNPOT && (!gl::isPow2(width) || !gl::isPow2(height))) { - return Error(EGL_BAD_MATCH); + return EglBadMatch(); } -#endif - return Error(EGL_SUCCESS); + return NoError(); } Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, EGLClientBuffer buffer, Config *config, const AttributeMap& attributes) { - Error error = ValidateConfig(display, config); - if (error.isError()) - { - return error; - } + ANGLE_TRY(ValidateConfig(display, config)); const DisplayExtensions &displayExtensions = display->getExtensions(); @@ -541,22 +1026,33 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, E case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE: if (!displayExtensions.d3dShareHandleClientBuffer) { - return Error(EGL_BAD_PARAMETER); + return EglBadParameter(); } if (buffer == nullptr) { - return Error(EGL_BAD_PARAMETER); + return EglBadParameter(); } break; + case EGL_D3D_TEXTURE_ANGLE: + if (!displayExtensions.d3dTextureClientBuffer) + { + return EglBadParameter(); + } + if (buffer == nullptr) + { + return EglBadParameter(); + } + break; + default: - return Error(EGL_BAD_PARAMETER); + return EglBadParameter(); } for (AttributeMap::const_iterator attributeIter = attributes.begin(); attributeIter != attributes.end(); attributeIter++) { - EGLint attribute = attributeIter->first; - EGLint value = attributeIter->second; + EGLAttrib attribute = attributeIter->first; + EGLAttrib value = attributeIter->second; switch (attribute) { @@ -564,11 +1060,11 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, E case EGL_HEIGHT: if (!displayExtensions.d3dShareHandleClientBuffer) { - return Error(EGL_BAD_PARAMETER); + return EglBadParameter(); } if (value < 0) { - return Error(EGL_BAD_PARAMETER); + return EglBadParameter(); } break; @@ -580,7 +1076,7 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, E case EGL_TEXTURE_RGBA: break; default: - return Error(EGL_BAD_ATTRIBUTE); + return EglBadAttribute(); } break; @@ -591,7 +1087,7 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, E case EGL_TEXTURE_2D: break; default: - return Error(EGL_BAD_ATTRIBUTE); + return EglBadAttribute(); } break; @@ -601,58 +1097,143 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, E case EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE: if (!displayExtensions.flexibleSurfaceCompatibility) { - return Error( - EGL_BAD_ATTRIBUTE, - "EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE cannot be used without " - "EGL_ANGLE_flexible_surface_compatibility support."); + return EglBadAttribute() + << "EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE cannot be used " + "without EGL_ANGLE_flexible_surface_compatibility support."; } break; default: - return Error(EGL_BAD_ATTRIBUTE); + return EglBadAttribute(); } } if (!(config->surfaceType & EGL_PBUFFER_BIT)) { - return Error(EGL_BAD_MATCH); + return EglBadMatch(); } - EGLenum textureFormat = attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE); - EGLenum textureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE); + EGLAttrib textureFormat = attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE); + EGLAttrib textureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE); if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) || (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE)) { - return Error(EGL_BAD_MATCH); + return EglBadMatch(); } if ((textureFormat == EGL_TEXTURE_RGB && config->bindToTextureRGB != EGL_TRUE) || (textureFormat == EGL_TEXTURE_RGBA && config->bindToTextureRGBA != EGL_TRUE)) { - return Error(EGL_BAD_ATTRIBUTE); + return EglBadAttribute(); } if (buftype == EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE) { - EGLint width = attributes.get(EGL_WIDTH, 0); - EGLint height = attributes.get(EGL_HEIGHT, 0); + EGLint width = static_cast(attributes.get(EGL_WIDTH, 0)); + EGLint height = static_cast(attributes.get(EGL_HEIGHT, 0)); if (width == 0 || height == 0) { - return Error(EGL_BAD_ATTRIBUTE); + return EglBadAttribute(); } -// On Windows Store, we know the originating texture came from D3D11, so bypass this check -#if !defined(ANGLE_ENABLE_WINDOWS_STORE) const Caps &caps = display->getCaps(); if (textureFormat != EGL_NO_TEXTURE && !caps.textureNPOT && (!gl::isPow2(width) || !gl::isPow2(height))) { - return Error(EGL_BAD_MATCH); + return EglBadMatch(); } -#endif } - return Error(EGL_SUCCESS); + ANGLE_TRY(display->validateClientBuffer(config, buftype, buffer, attributes)); + + return NoError(); +} + +Error ValidateMakeCurrent(Display *display, EGLSurface draw, EGLSurface read, gl::Context *context) +{ + if (context == EGL_NO_CONTEXT && (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE)) + { + return EglBadMatch() << "If ctx is EGL_NO_CONTEXT, surfaces must be EGL_NO_SURFACE"; + } + + // If ctx is EGL_NO_CONTEXT and either draw or read are not EGL_NO_SURFACE, an EGL_BAD_MATCH + // error is generated. EGL_KHR_surfaceless_context allows both surfaces to be EGL_NO_SURFACE. + if (context != EGL_NO_CONTEXT && (draw == EGL_NO_SURFACE || read == EGL_NO_SURFACE)) + { + if (display->getExtensions().surfacelessContext) + { + if ((draw == EGL_NO_SURFACE) != (read == EGL_NO_SURFACE)) + { + return EglBadMatch() << "If ctx is not EGL_NOT_CONTEXT, draw or read must " + "both be EGL_NO_SURFACE, or both not"; + } + } + else + { + return EglBadMatch() + << "If ctx is not EGL_NO_CONTEXT, surfaces must not be EGL_NO_SURFACE"; + } + } + + // If either of draw or read is a valid surface and the other is EGL_NO_SURFACE, an + // EGL_BAD_MATCH error is generated. + if ((read == EGL_NO_SURFACE) != (draw == EGL_NO_SURFACE)) + { + return EglBadMatch() + << "read and draw must both be valid surfaces, or both be EGL_NO_SURFACE"; + } + + if (display == EGL_NO_DISPLAY || !Display::isValidDisplay(display)) + { + return EglBadDisplay() << "'dpy' not a valid EGLDisplay handle"; + } + + // EGL 1.5 spec: dpy can be uninitialized if all other parameters are null + if (!display->isInitialized() && + (context != EGL_NO_CONTEXT || draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE)) + { + return EglNotInitialized() << "'dpy' not initialized"; + } + + if (context != EGL_NO_CONTEXT) + { + ANGLE_TRY(ValidateContext(display, context)); + } + + if (display->isInitialized() && display->testDeviceLost()) + { + return EglContextLost(); + } + + Surface *drawSurface = static_cast(draw); + if (draw != EGL_NO_SURFACE) + { + ANGLE_TRY(ValidateSurface(display, drawSurface)); + } + + Surface *readSurface = static_cast(read); + if (read != EGL_NO_SURFACE) + { + ANGLE_TRY(ValidateSurface(display, readSurface)); + } + + if (readSurface) + { + ANGLE_TRY(ValidateCompatibleConfigs(display, readSurface->getConfig(), readSurface, + context->getConfig(), readSurface->getType())); + } + + if (draw != read) + { + UNIMPLEMENTED(); // FIXME + + if (drawSurface) + { + ANGLE_TRY(ValidateCompatibleConfigs(display, drawSurface->getConfig(), drawSurface, + context->getConfig(), drawSurface->getType())); + } + } + return NoError(); } Error ValidateCompatibleConfigs(const Display *display, @@ -669,7 +1250,7 @@ Error ValidateCompatibleConfigs(const Display *display, bool colorBufferCompat = config1->colorBufferType == config2->colorBufferType; if (!colorBufferCompat) { - return Error(EGL_BAD_MATCH, "Color buffer types are not compatible."); + return EglBadMatch() << "Color buffer types are not compatible."; } bool colorCompat = @@ -678,24 +1259,30 @@ Error ValidateCompatibleConfigs(const Display *display, config1->luminanceSize == config2->luminanceSize; if (!colorCompat) { - return Error(EGL_BAD_MATCH, "Color buffer sizes are not compatible."); + return EglBadMatch() << "Color buffer sizes are not compatible."; + } + + bool componentTypeCompat = config1->colorComponentType == config2->colorComponentType; + if (!componentTypeCompat) + { + return EglBadMatch() << "Color buffer component types are not compatible."; } bool dsCompat = config1->depthSize == config2->depthSize && config1->stencilSize == config2->stencilSize; if (!dsCompat) { - return Error(EGL_BAD_MATCH, "Depth-stencil buffer types are not compatible."); + return EglBadMatch() << "Depth-stencil buffer types are not compatible."; } } bool surfaceTypeCompat = (config1->surfaceType & config2->surfaceType & surfaceType) != 0; if (!surfaceTypeCompat) { - return Error(EGL_BAD_MATCH, "Surface types are not compatible."); + return EglBadMatch() << "Surface types are not compatible."; } - return Error(EGL_SUCCESS); + return NoError(); } Error ValidateCreateImageKHR(const Display *display, @@ -704,11 +1291,7 @@ Error ValidateCreateImageKHR(const Display *display, EGLClientBuffer buffer, const AttributeMap &attributes) { - Error error = ValidateContext(display, context); - if (error.isError()) - { - return error; - } + ANGLE_TRY(ValidateContext(display, context)); const DisplayExtensions &displayExtensions = display->getExtensions(); @@ -717,7 +1300,7 @@ Error ValidateCreateImageKHR(const Display *display, // It is out of spec what happens when calling an extension function when the extension is // not available. // EGL_BAD_DISPLAY seems like a reasonable error. - return Error(EGL_BAD_DISPLAY, "EGL_KHR_image not supported."); + return EglBadDisplay() << "EGL_KHR_image not supported."; } // TODO(geofflang): Complete validation from EGL_KHR_image_base: @@ -727,8 +1310,8 @@ Error ValidateCreateImageKHR(const Display *display, for (AttributeMap::const_iterator attributeIter = attributes.begin(); attributeIter != attributes.end(); attributeIter++) { - EGLint attribute = attributeIter->first; - EGLint value = attributeIter->second; + EGLAttrib attribute = attributeIter->first; + EGLAttrib value = attributeIter->second; switch (attribute) { @@ -740,8 +1323,8 @@ Error ValidateCreateImageKHR(const Display *display, break; default: - return Error(EGL_BAD_PARAMETER, - "EGL_IMAGE_PRESERVED_KHR must be EGL_TRUE or EGL_FALSE."); + return EglBadParameter() + << "EGL_IMAGE_PRESERVED_KHR must be EGL_TRUE or EGL_FALSE."; } break; @@ -749,28 +1332,27 @@ Error ValidateCreateImageKHR(const Display *display, if (!displayExtensions.glTexture2DImage && !displayExtensions.glTextureCubemapImage && !displayExtensions.glTexture3DImage) { - return Error(EGL_BAD_PARAMETER, - "EGL_GL_TEXTURE_LEVEL_KHR cannot be used without " - "KHR_gl_texture_*_image support."); + return EglBadParameter() << "EGL_GL_TEXTURE_LEVEL_KHR cannot be used " + "without KHR_gl_texture_*_image support."; } if (value < 0) { - return Error(EGL_BAD_PARAMETER, "EGL_GL_TEXTURE_LEVEL_KHR cannot be negative."); + return EglBadParameter() << "EGL_GL_TEXTURE_LEVEL_KHR cannot be negative."; } break; case EGL_GL_TEXTURE_ZOFFSET_KHR: if (!displayExtensions.glTexture3DImage) { - return Error(EGL_BAD_PARAMETER, - "EGL_GL_TEXTURE_ZOFFSET_KHR cannot be used without " - "KHR_gl_texture_3D_image support."); + return EglBadParameter() << "EGL_GL_TEXTURE_ZOFFSET_KHR cannot be used " + "without KHR_gl_texture_3D_image support."; } break; default: - return Error(EGL_BAD_PARAMETER, "invalid attribute: 0x%X", attribute); + return EglBadParameter() + << "invalid attribute: 0x" << std::hex << std::uppercase << attribute; } } @@ -780,48 +1362,35 @@ Error ValidateCreateImageKHR(const Display *display, { if (!displayExtensions.glTexture2DImage) { - return Error(EGL_BAD_PARAMETER, "KHR_gl_texture_2D_image not supported."); + return EglBadParameter() << "KHR_gl_texture_2D_image not supported."; } if (buffer == 0) { - return Error(EGL_BAD_PARAMETER, - "buffer cannot reference a 2D texture with the name 0."); + return EglBadParameter() << "buffer cannot reference a 2D texture with the name 0."; } const gl::Texture *texture = context->getTexture(egl_gl::EGLClientBufferToGLObjectHandle(buffer)); if (texture == nullptr || texture->getTarget() != GL_TEXTURE_2D) { - return Error(EGL_BAD_PARAMETER, "target is not a 2D texture."); + return EglBadParameter() << "target is not a 2D texture."; } if (texture->getBoundSurface() != nullptr) { - return Error(EGL_BAD_ACCESS, "texture has a surface bound to it."); + return EglBadAccess() << "texture has a surface bound to it."; } - EGLint level = attributes.get(EGL_GL_TEXTURE_LEVEL_KHR, 0); + EGLAttrib level = attributes.get(EGL_GL_TEXTURE_LEVEL_KHR, 0); if (texture->getWidth(GL_TEXTURE_2D, static_cast(level)) == 0 || texture->getHeight(GL_TEXTURE_2D, static_cast(level)) == 0) { - return Error(EGL_BAD_PARAMETER, - "target 2D texture does not have a valid size at specified level."); + return EglBadParameter() + << "target 2D texture does not have a valid size at specified level."; } - if (level > 0 && (!texture->isMipmapComplete() || - static_cast(level) >= texture->getMipCompleteLevels())) - { - return Error(EGL_BAD_PARAMETER, "texture must be complete if level is non-zero."); - } - - if (level == 0 && !texture->isMipmapComplete() && - TextureHasNonZeroMipLevelsSpecified(context, texture)) - { - return Error(EGL_BAD_PARAMETER, - "if level is zero and the texture is incomplete, it must have no mip " - "levels specified except zero."); - } + ANGLE_TRY(ValidateCreateImageKHRMipLevelCommon(context, texture, level)); } break; @@ -834,57 +1403,44 @@ Error ValidateCreateImageKHR(const Display *display, { if (!displayExtensions.glTextureCubemapImage) { - return Error(EGL_BAD_PARAMETER, "KHR_gl_texture_cubemap_image not supported."); + return EglBadParameter() << "KHR_gl_texture_cubemap_image not supported."; } if (buffer == 0) { - return Error(EGL_BAD_PARAMETER, - "buffer cannot reference a cubemap texture with the name 0."); + return EglBadParameter() + << "buffer cannot reference a cubemap texture with the name 0."; } const gl::Texture *texture = context->getTexture(egl_gl::EGLClientBufferToGLObjectHandle(buffer)); if (texture == nullptr || texture->getTarget() != GL_TEXTURE_CUBE_MAP) { - return Error(EGL_BAD_PARAMETER, "target is not a cubemap texture."); + return EglBadParameter() << "target is not a cubemap texture."; } if (texture->getBoundSurface() != nullptr) { - return Error(EGL_BAD_ACCESS, "texture has a surface bound to it."); + return EglBadAccess() << "texture has a surface bound to it."; } - EGLint level = attributes.get(EGL_GL_TEXTURE_LEVEL_KHR, 0); + EGLAttrib level = attributes.get(EGL_GL_TEXTURE_LEVEL_KHR, 0); GLenum cubeMapFace = egl_gl::EGLCubeMapTargetToGLCubeMapTarget(target); if (texture->getWidth(cubeMapFace, static_cast(level)) == 0 || texture->getHeight(cubeMapFace, static_cast(level)) == 0) { - return Error(EGL_BAD_PARAMETER, - "target cubemap texture does not have a valid size at specified level " - "and face."); + return EglBadParameter() << "target cubemap texture does not have a valid " + "size at specified level and face."; } - if (level > 0 && (!texture->isMipmapComplete() || - static_cast(level) >= texture->getMipCompleteLevels())) - { - return Error(EGL_BAD_PARAMETER, "texture must be complete if level is non-zero."); - } - - if (level == 0 && !texture->isMipmapComplete() && - TextureHasNonZeroMipLevelsSpecified(context, texture)) - { - return Error(EGL_BAD_PARAMETER, - "if level is zero and the texture is incomplete, it must have no mip " - "levels specified except zero."); - } + ANGLE_TRY(ValidateCreateImageKHRMipLevelCommon(context, texture, level)); if (level == 0 && !texture->isMipmapComplete() && CubeTextureHasUnspecifiedLevel0Face(texture)) { - return Error(EGL_BAD_PARAMETER, - "if level is zero and the texture is incomplete, it must have all of " - "its faces specified at level zero."); + return EglBadParameter() << "if level is zero and the texture is incomplete, " + "it must have all of its faces specified at level " + "zero."; } } break; @@ -893,58 +1449,45 @@ Error ValidateCreateImageKHR(const Display *display, { if (!displayExtensions.glTexture3DImage) { - return Error(EGL_BAD_PARAMETER, "KHR_gl_texture_3D_image not supported."); + return EglBadParameter() << "KHR_gl_texture_3D_image not supported."; } if (buffer == 0) { - return Error(EGL_BAD_PARAMETER, - "buffer cannot reference a 3D texture with the name 0."); + return EglBadParameter() << "buffer cannot reference a 3D texture with the name 0."; } const gl::Texture *texture = context->getTexture(egl_gl::EGLClientBufferToGLObjectHandle(buffer)); if (texture == nullptr || texture->getTarget() != GL_TEXTURE_3D) { - return Error(EGL_BAD_PARAMETER, "target is not a 3D texture."); + return EglBadParameter() << "target is not a 3D texture."; } if (texture->getBoundSurface() != nullptr) { - return Error(EGL_BAD_ACCESS, "texture has a surface bound to it."); + return EglBadAccess() << "texture has a surface bound to it."; } - EGLint level = attributes.get(EGL_GL_TEXTURE_LEVEL_KHR, 0); - EGLint zOffset = attributes.get(EGL_GL_TEXTURE_ZOFFSET_KHR, 0); + EGLAttrib level = attributes.get(EGL_GL_TEXTURE_LEVEL_KHR, 0); + EGLAttrib zOffset = attributes.get(EGL_GL_TEXTURE_ZOFFSET_KHR, 0); if (texture->getWidth(GL_TEXTURE_3D, static_cast(level)) == 0 || texture->getHeight(GL_TEXTURE_3D, static_cast(level)) == 0 || texture->getDepth(GL_TEXTURE_3D, static_cast(level)) == 0) { - return Error(EGL_BAD_PARAMETER, - "target 3D texture does not have a valid size at specified level."); + return EglBadParameter() + << "target 3D texture does not have a valid size at specified level."; } if (static_cast(zOffset) >= texture->getDepth(GL_TEXTURE_3D, static_cast(level))) { - return Error(EGL_BAD_PARAMETER, - "target 3D texture does not have enough layers for the specified Z " - "offset at the specified level."); + return EglBadParameter() << "target 3D texture does not have enough layers " + "for the specified Z offset at the specified " + "level."; } - if (level > 0 && (!texture->isMipmapComplete() || - static_cast(level) >= texture->getMipCompleteLevels())) - { - return Error(EGL_BAD_PARAMETER, "texture must be complete if level is non-zero."); - } - - if (level == 0 && !texture->isMipmapComplete() && - TextureHasNonZeroMipLevelsSpecified(context, texture)) - { - return Error(EGL_BAD_PARAMETER, - "if level is zero and the texture is incomplete, it must have no mip " - "levels specified except zero."); - } + ANGLE_TRY(ValidateCreateImageKHRMipLevelCommon(context, texture, level)); } break; @@ -952,75 +1495,71 @@ Error ValidateCreateImageKHR(const Display *display, { if (!displayExtensions.glRenderbufferImage) { - return Error(EGL_BAD_PARAMETER, "KHR_gl_renderbuffer_image not supported."); + return EglBadParameter() << "KHR_gl_renderbuffer_image not supported."; } if (attributes.contains(EGL_GL_TEXTURE_LEVEL_KHR)) { - return Error(EGL_BAD_PARAMETER, - "EGL_GL_TEXTURE_LEVEL_KHR cannot be used in conjunction with a " - "renderbuffer target."); + return EglBadParameter() << "EGL_GL_TEXTURE_LEVEL_KHR cannot be used in " + "conjunction with a renderbuffer target."; } if (buffer == 0) { - return Error(EGL_BAD_PARAMETER, - "buffer cannot reference a renderbuffer with the name 0."); + return EglBadParameter() + << "buffer cannot reference a renderbuffer with the name 0."; } const gl::Renderbuffer *renderbuffer = context->getRenderbuffer(egl_gl::EGLClientBufferToGLObjectHandle(buffer)); if (renderbuffer == nullptr) { - return Error(EGL_BAD_PARAMETER, "target is not a renderbuffer."); + return EglBadParameter() << "target is not a renderbuffer."; } if (renderbuffer->getSamples() > 0) { - return Error(EGL_BAD_PARAMETER, "target renderbuffer cannot be multisampled."); + return EglBadParameter() << "target renderbuffer cannot be multisampled."; } } break; default: - return Error(EGL_BAD_PARAMETER, "invalid target: 0x%X", target); + return EglBadParameter() + << "invalid target: 0x" << std::hex << std::uppercase << target; } - return Error(EGL_SUCCESS); + return NoError(); } Error ValidateDestroyImageKHR(const Display *display, const Image *image) { - Error error = ValidateImage(display, image); - if (error.isError()) - { - return error; - } + ANGLE_TRY(ValidateImage(display, image)); if (!display->getExtensions().imageBase && !display->getExtensions().image) { // It is out of spec what happens when calling an extension function when the extension is // not available. // EGL_BAD_DISPLAY seems like a reasonable error. - return Error(EGL_BAD_DISPLAY); + return EglBadDisplay(); } - return Error(EGL_SUCCESS); + return NoError(); } Error ValidateCreateDeviceANGLE(EGLint device_type, void *native_device, const EGLAttrib *attrib_list) { - const ClientExtensions &clientExtensions = Display::getClientExtensions(); + const ClientExtensions &clientExtensions = Display::GetClientExtensions(); if (!clientExtensions.deviceCreation) { - return Error(EGL_BAD_ACCESS, "Device creation extension not active"); + return EglBadAccess() << "Device creation extension not active"; } if (attrib_list != nullptr && attrib_list[0] != EGL_NONE) { - return Error(EGL_BAD_ATTRIBUTE, "Invalid attrib_list parameter"); + return EglBadAttribute() << "Invalid attrib_list parameter"; } switch (device_type) @@ -1028,35 +1567,935 @@ Error ValidateCreateDeviceANGLE(EGLint device_type, case EGL_D3D11_DEVICE_ANGLE: if (!clientExtensions.deviceCreationD3D11) { - return Error(EGL_BAD_ATTRIBUTE, "D3D11 device creation extension not active"); + return EglBadAttribute() << "D3D11 device creation extension not active"; } break; default: - return Error(EGL_BAD_ATTRIBUTE, "Invalid device_type parameter"); + return EglBadAttribute() << "Invalid device_type parameter"; } - return Error(EGL_SUCCESS); + return NoError(); } Error ValidateReleaseDeviceANGLE(Device *device) { - const ClientExtensions &clientExtensions = Display::getClientExtensions(); + const ClientExtensions &clientExtensions = Display::GetClientExtensions(); if (!clientExtensions.deviceCreation) { - return Error(EGL_BAD_ACCESS, "Device creation extension not active"); + return EglBadAccess() << "Device creation extension not active"; } if (device == EGL_NO_DEVICE_EXT || !Device::IsValidDevice(device)) { - return Error(EGL_BAD_DEVICE_EXT, "Invalid device parameter"); + return EglBadDevice() << "Invalid device parameter"; } Display *owningDisplay = device->getOwningDisplay(); if (owningDisplay != nullptr) { - return Error(EGL_BAD_DEVICE_EXT, "Device must have been created using eglCreateDevice"); + return EglBadDevice() << "Device must have been created using eglCreateDevice"; } - return Error(EGL_SUCCESS); + return NoError(); } + +Error ValidateCreateStreamKHR(const Display *display, const AttributeMap &attributes) +{ + ANGLE_TRY(ValidateDisplay(display)); + + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.stream) + { + return EglBadAlloc() << "Stream extension not active"; + } + + for (const auto &attributeIter : attributes) + { + EGLAttrib attribute = attributeIter.first; + EGLAttrib value = attributeIter.second; + + ANGLE_TRY(ValidateStreamAttribute(attribute, value, displayExtensions)); + } + + return NoError(); } + +Error ValidateDestroyStreamKHR(const Display *display, const Stream *stream) +{ + ANGLE_TRY(ValidateStream(display, stream)); + return NoError(); +} + +Error ValidateStreamAttribKHR(const Display *display, + const Stream *stream, + EGLint attribute, + EGLint value) +{ + ANGLE_TRY(ValidateStream(display, stream)); + + if (stream->getState() == EGL_STREAM_STATE_DISCONNECTED_KHR) + { + return EglBadState() << "Bad stream state"; + } + + return ValidateStreamAttribute(attribute, value, display->getExtensions()); +} + +Error ValidateQueryStreamKHR(const Display *display, + const Stream *stream, + EGLenum attribute, + EGLint *value) +{ + ANGLE_TRY(ValidateStream(display, stream)); + + switch (attribute) + { + case EGL_STREAM_STATE_KHR: + case EGL_CONSUMER_LATENCY_USEC_KHR: + break; + case EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR: + if (!display->getExtensions().streamConsumerGLTexture) + { + return EglBadAttribute() << "Consumer GLTexture extension not active"; + } + break; + default: + return EglBadAttribute() << "Invalid attribute"; + } + + return NoError(); +} + +Error ValidateQueryStreamu64KHR(const Display *display, + const Stream *stream, + EGLenum attribute, + EGLuint64KHR *value) +{ + ANGLE_TRY(ValidateStream(display, stream)); + + switch (attribute) + { + case EGL_CONSUMER_FRAME_KHR: + case EGL_PRODUCER_FRAME_KHR: + break; + default: + return EglBadAttribute() << "Invalid attribute"; + } + + return NoError(); +} + +Error ValidateStreamConsumerGLTextureExternalKHR(const Display *display, + gl::Context *context, + const Stream *stream) +{ + ANGLE_TRY(ValidateDisplay(display)); + ANGLE_TRY(ValidateContext(display, context)); + + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.streamConsumerGLTexture) + { + return EglBadAccess() << "Stream consumer extension not active"; + } + + if (!context->getExtensions().eglStreamConsumerExternal) + { + return EglBadAccess() << "EGL stream consumer external GL extension not enabled"; + } + + if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream)) + { + return EglBadStream() << "Invalid stream"; + } + + if (stream->getState() != EGL_STREAM_STATE_CREATED_KHR) + { + return EglBadState() << "Invalid stream state"; + } + + // Lookup the texture and ensure it is correct + gl::Texture *texture = context->getGLState().getTargetTexture(GL_TEXTURE_EXTERNAL_OES); + if (texture == nullptr || texture->getId() == 0) + { + return EglBadAccess() << "No external texture bound"; + } + + return NoError(); +} + +Error ValidateStreamConsumerAcquireKHR(const Display *display, + gl::Context *context, + const Stream *stream) +{ + ANGLE_TRY(ValidateDisplay(display)); + + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.streamConsumerGLTexture) + { + return EglBadAccess() << "Stream consumer extension not active"; + } + + if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream)) + { + return EglBadStream() << "Invalid stream"; + } + + if (!context) + { + return EglBadAccess() << "No GL context current to calling thread."; + } + + ANGLE_TRY(ValidateContext(display, context)); + + if (!stream->isConsumerBoundToContext(context)) + { + return EglBadAccess() << "Current GL context not associated with stream consumer"; + } + + if (stream->getConsumerType() != Stream::ConsumerType::GLTextureRGB && + stream->getConsumerType() != Stream::ConsumerType::GLTextureYUV) + { + return EglBadAccess() << "Invalid stream consumer type"; + } + + // Note: technically EGL_STREAM_STATE_EMPTY_KHR is a valid state when the timeout is non-zero. + // However, the timeout is effectively ignored since it has no useful functionality with the + // current producers that are implemented, so we don't allow that state + if (stream->getState() != EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR && + stream->getState() != EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR) + { + return EglBadState() << "Invalid stream state"; + } + + return NoError(); +} + +Error ValidateStreamConsumerReleaseKHR(const Display *display, + gl::Context *context, + const Stream *stream) +{ + ANGLE_TRY(ValidateDisplay(display)); + + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.streamConsumerGLTexture) + { + return EglBadAccess() << "Stream consumer extension not active"; + } + + if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream)) + { + return EglBadStream() << "Invalid stream"; + } + + if (!context) + { + return EglBadAccess() << "No GL context current to calling thread."; + } + + ANGLE_TRY(ValidateContext(display, context)); + + if (!stream->isConsumerBoundToContext(context)) + { + return EglBadAccess() << "Current GL context not associated with stream consumer"; + } + + if (stream->getConsumerType() != Stream::ConsumerType::GLTextureRGB && + stream->getConsumerType() != Stream::ConsumerType::GLTextureYUV) + { + return EglBadAccess() << "Invalid stream consumer type"; + } + + if (stream->getState() != EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR && + stream->getState() != EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR) + { + return EglBadState() << "Invalid stream state"; + } + + return NoError(); +} + +Error ValidateStreamConsumerGLTextureExternalAttribsNV(const Display *display, + gl::Context *context, + const Stream *stream, + const AttributeMap &attribs) +{ + ANGLE_TRY(ValidateDisplay(display)); + + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.streamConsumerGLTexture) + { + return EglBadAccess() << "Stream consumer extension not active"; + } + + // Although technically not a requirement in spec, the context needs to be checked for support + // for external textures or future logic will cause assertations. This extension is also + // effectively useless without external textures. + if (!context->getExtensions().eglStreamConsumerExternal) + { + return EglBadAccess() << "EGL stream consumer external GL extension not enabled"; + } + + if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream)) + { + return EglBadStream() << "Invalid stream"; + } + + if (!context) + { + return EglBadAccess() << "No GL context current to calling thread."; + } + + ANGLE_TRY(ValidateContext(display, context)); + + if (stream->getState() != EGL_STREAM_STATE_CREATED_KHR) + { + return EglBadState() << "Invalid stream state"; + } + + const gl::Caps &glCaps = context->getCaps(); + + EGLAttrib colorBufferType = EGL_RGB_BUFFER; + EGLAttrib planeCount = -1; + EGLAttrib plane[3]; + for (int i = 0; i < 3; i++) + { + plane[i] = -1; + } + for (const auto &attributeIter : attribs) + { + EGLAttrib attribute = attributeIter.first; + EGLAttrib value = attributeIter.second; + + switch (attribute) + { + case EGL_COLOR_BUFFER_TYPE: + if (value != EGL_RGB_BUFFER && value != EGL_YUV_BUFFER_EXT) + { + return EglBadParameter() << "Invalid color buffer type"; + } + colorBufferType = value; + break; + case EGL_YUV_NUMBER_OF_PLANES_EXT: + // planeCount = -1 is a tag for the default plane count so the value must be checked + // to be positive here to ensure future logic doesn't break on invalid negative + // inputs + if (value < 0) + { + return EglBadMatch() << "Invalid plane count"; + } + planeCount = value; + break; + default: + if (attribute >= EGL_YUV_PLANE0_TEXTURE_UNIT_NV && + attribute <= EGL_YUV_PLANE2_TEXTURE_UNIT_NV) + { + if ((value < 0 || + value >= static_cast(glCaps.maxCombinedTextureImageUnits)) && + value != EGL_NONE) + { + return EglBadAccess() << "Invalid texture unit"; + } + plane[attribute - EGL_YUV_PLANE0_TEXTURE_UNIT_NV] = value; + } + else + { + return EglBadAttribute() << "Invalid attribute"; + } + } + } + + if (colorBufferType == EGL_RGB_BUFFER) + { + if (planeCount > 0) + { + return EglBadMatch() << "Plane count must be 0 for RGB buffer"; + } + for (int i = 0; i < 3; i++) + { + if (plane[i] != -1) + { + return EglBadMatch() << "Planes cannot be specified"; + } + } + + // Lookup the texture and ensure it is correct + gl::Texture *texture = context->getGLState().getTargetTexture(GL_TEXTURE_EXTERNAL_OES); + if (texture == nullptr || texture->getId() == 0) + { + return EglBadAccess() << "No external texture bound"; + } + } + else + { + if (planeCount == -1) + { + planeCount = 2; + } + if (planeCount < 1 || planeCount > 3) + { + return EglBadMatch() << "Invalid YUV plane count"; + } + for (EGLAttrib i = planeCount; i < 3; i++) + { + if (plane[i] != -1) + { + return EglBadMatch() << "Invalid plane specified"; + } + } + + // Set to ensure no texture is referenced more than once + std::set textureSet; + for (EGLAttrib i = 0; i < planeCount; i++) + { + if (plane[i] == -1) + { + return EglBadMatch() << "Not all planes specified"; + } + if (plane[i] != EGL_NONE) + { + gl::Texture *texture = context->getGLState().getSamplerTexture( + static_cast(plane[i]), GL_TEXTURE_EXTERNAL_OES); + if (texture == nullptr || texture->getId() == 0) + { + return EglBadAccess() + << "No external texture bound at one or more specified texture units"; + } + if (textureSet.find(texture) != textureSet.end()) + { + return EglBadAccess() << "Multiple planes bound to same texture object"; + } + textureSet.insert(texture); + } + } + } + + return NoError(); +} + +Error ValidateCreateStreamProducerD3DTextureNV12ANGLE(const Display *display, + const Stream *stream, + const AttributeMap &attribs) +{ + ANGLE_TRY(ValidateDisplay(display)); + + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.streamProducerD3DTextureNV12) + { + return EglBadAccess() << "Stream producer extension not active"; + } + + ANGLE_TRY(ValidateStream(display, stream)); + + if (!attribs.isEmpty()) + { + return EglBadAttribute() << "Invalid attribute"; + } + + if (stream->getState() != EGL_STREAM_STATE_CONNECTING_KHR) + { + return EglBadState() << "Stream not in connecting state"; + } + + if (stream->getConsumerType() != Stream::ConsumerType::GLTextureYUV || + stream->getPlaneCount() != 2) + { + return EglBadMatch() << "Incompatible stream consumer type"; + } + + return NoError(); +} + +Error ValidateStreamPostD3DTextureNV12ANGLE(const Display *display, + const Stream *stream, + void *texture, + const AttributeMap &attribs) +{ + ANGLE_TRY(ValidateDisplay(display)); + + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.streamProducerD3DTextureNV12) + { + return EglBadAccess() << "Stream producer extension not active"; + } + + ANGLE_TRY(ValidateStream(display, stream)); + + for (auto &attributeIter : attribs) + { + EGLAttrib attribute = attributeIter.first; + EGLAttrib value = attributeIter.second; + + switch (attribute) + { + case EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE: + if (value < 0) + { + return EglBadParameter() << "Invalid subresource index"; + } + break; + default: + return EglBadAttribute() << "Invalid attribute"; + } + } + + if (stream->getState() != EGL_STREAM_STATE_EMPTY_KHR && + stream->getState() != EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR && + stream->getState() != EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR) + { + return EglBadState() << "Stream not fully configured"; + } + + if (stream->getProducerType() != Stream::ProducerType::D3D11TextureNV12) + { + return EglBadMatch() << "Incompatible stream producer"; + } + + if (texture == nullptr) + { + return EglBadParameter() << "Texture is null"; + } + + return stream->validateD3D11NV12Texture(texture); +} + +Error ValidateGetSyncValuesCHROMIUM(const Display *display, + const Surface *surface, + const EGLuint64KHR *ust, + const EGLuint64KHR *msc, + const EGLuint64KHR *sbc) +{ + ANGLE_TRY(ValidateDisplay(display)); + + const DisplayExtensions &displayExtensions = display->getExtensions(); + if (!displayExtensions.getSyncValues) + { + return EglBadAccess() << "getSyncValues extension not active"; + } + + if (display->isDeviceLost()) + { + return EglContextLost() << "Context is lost."; + } + + if (surface == EGL_NO_SURFACE) + { + return EglBadSurface() << "getSyncValues surface cannot be EGL_NO_SURFACE"; + } + + if (!surface->directComposition()) + { + return EglBadSurface() << "getSyncValues surface requires Direct Composition to be enabled"; + } + + if (ust == nullptr) + { + return EglBadParameter() << "ust is null"; + } + + if (msc == nullptr) + { + return EglBadParameter() << "msc is null"; + } + + if (sbc == nullptr) + { + return EglBadParameter() << "sbc is null"; + } + + return NoError(); +} + +Error ValidateSwapBuffersWithDamageEXT(const Display *display, + const Surface *surface, + EGLint *rects, + EGLint n_rects) +{ + Error error = ValidateSurface(display, surface); + if (error.isError()) + { + return error; + } + + if (!display->getExtensions().swapBuffersWithDamage) + { + // It is out of spec what happens when calling an extension function when the extension is + // not available. EGL_BAD_DISPLAY seems like a reasonable error. + return EglBadDisplay() << "EGL_EXT_swap_buffers_with_damage is not available."; + } + + if (surface == EGL_NO_SURFACE) + { + return EglBadSurface() << "Swap surface cannot be EGL_NO_SURFACE."; + } + + if (n_rects < 0) + { + return EglBadParameter() << "n_rects cannot be negative."; + } + + if (n_rects > 0 && rects == nullptr) + { + return EglBadParameter() << "n_rects cannot be greater than zero when rects is NULL."; + } + + // TODO(jmadill): Validate Surface is bound to the thread. + + return NoError(); +} + +Error ValidateGetConfigAttrib(const Display *display, const Config *config, EGLint attribute) +{ + ANGLE_TRY(ValidateConfig(display, config)); + ANGLE_TRY(ValidateConfigAttribute(display, static_cast(attribute))); + return NoError(); +} + +Error ValidateChooseConfig(const Display *display, + const AttributeMap &attribs, + EGLint configSize, + EGLint *numConfig) +{ + ANGLE_TRY(ValidateDisplay(display)); + ANGLE_TRY(ValidateConfigAttributes(display, attribs)); + + if (numConfig == nullptr) + { + return EglBadParameter() << "num_config cannot be null."; + } + + return NoError(); +} + +Error ValidateGetConfigs(const Display *display, EGLint configSize, EGLint *numConfig) +{ + ANGLE_TRY(ValidateDisplay(display)); + + if (numConfig == nullptr) + { + return EglBadParameter() << "num_config cannot be null."; + } + + return NoError(); +} + +Error ValidateGetPlatformDisplay(EGLenum platform, + void *native_display, + const EGLAttrib *attrib_list) +{ + const auto &attribMap = AttributeMap::CreateFromAttribArray(attrib_list); + return ValidateGetPlatformDisplayCommon(platform, native_display, attribMap); +} + +Error ValidateGetPlatformDisplayEXT(EGLenum platform, + void *native_display, + const EGLint *attrib_list) +{ + const auto &attribMap = AttributeMap::CreateFromIntArray(attrib_list); + return ValidateGetPlatformDisplayCommon(platform, native_display, attribMap); +} + +Error ValidateProgramCacheGetAttribANGLE(const Display *display, EGLenum attrib) +{ + ANGLE_TRY(ValidateDisplay(display)); + + if (!display->getExtensions().programCacheControl) + { + return EglBadAccess() << "Extension not supported"; + } + + switch (attrib) + { + case EGL_PROGRAM_CACHE_KEY_LENGTH_ANGLE: + case EGL_PROGRAM_CACHE_SIZE_ANGLE: + break; + + default: + return EglBadParameter() << "Invalid program cache attribute."; + } + + return NoError(); +} + +Error ValidateProgramCacheQueryANGLE(const Display *display, + EGLint index, + void *key, + EGLint *keysize, + void *binary, + EGLint *binarysize) +{ + ANGLE_TRY(ValidateDisplay(display)); + + if (!display->getExtensions().programCacheControl) + { + return EglBadAccess() << "Extension not supported"; + } + + if (index < 0 || index >= display->programCacheGetAttrib(EGL_PROGRAM_CACHE_SIZE_ANGLE)) + { + return EglBadParameter() << "Program index out of range."; + } + + if (keysize == nullptr || binarysize == nullptr) + { + return EglBadParameter() << "keysize and binarysize must always be valid pointers."; + } + + if (binary && *keysize != static_cast(gl::kProgramHashLength)) + { + return EglBadParameter() << "Invalid program key size."; + } + + if ((key == nullptr) != (binary == nullptr)) + { + return EglBadParameter() << "key and binary must both be null or both non-null."; + } + + return NoError(); +} + +Error ValidateProgramCachePopulateANGLE(const Display *display, + const void *key, + EGLint keysize, + const void *binary, + EGLint binarysize) +{ + ANGLE_TRY(ValidateDisplay(display)); + + if (!display->getExtensions().programCacheControl) + { + return EglBadAccess() << "Extension not supported"; + } + + if (keysize != static_cast(gl::kProgramHashLength)) + { + return EglBadParameter() << "Invalid program key size."; + } + + if (key == nullptr || binary == nullptr) + { + return EglBadParameter() << "null pointer in arguments."; + } + + // Upper bound for binarysize is arbitrary. + if (binarysize <= 0 || binarysize > egl::kProgramCacheSizeAbsoluteMax) + { + return EglBadParameter() << "binarysize out of valid range."; + } + + return NoError(); +} + +Error ValidateProgramCacheResizeANGLE(const Display *display, EGLint limit, EGLenum mode) +{ + ANGLE_TRY(ValidateDisplay(display)); + + if (!display->getExtensions().programCacheControl) + { + return EglBadAccess() << "Extension not supported"; + } + + if (limit < 0) + { + return EglBadParameter() << "limit must be non-negative."; + } + + switch (mode) + { + case EGL_PROGRAM_CACHE_RESIZE_ANGLE: + case EGL_PROGRAM_CACHE_TRIM_ANGLE: + break; + + default: + return EglBadParameter() << "Invalid cache resize mode."; + } + + return NoError(); +} + +Error ValidateSurfaceAttrib(const Display *display, + const Surface *surface, + EGLint attribute, + EGLint value) +{ + ANGLE_TRY(ValidateDisplay(display)); + ANGLE_TRY(ValidateSurface(display, surface)); + + if (surface == EGL_NO_SURFACE) + { + return EglBadSurface() << "Surface cannot be EGL_NO_SURFACE."; + } + + switch (attribute) + { + case EGL_MIPMAP_LEVEL: + break; + + case EGL_MULTISAMPLE_RESOLVE: + switch (value) + { + case EGL_MULTISAMPLE_RESOLVE_DEFAULT: + break; + + case EGL_MULTISAMPLE_RESOLVE_BOX: + if ((surface->getConfig()->surfaceType & EGL_MULTISAMPLE_RESOLVE_BOX_BIT) == 0) + { + return EglBadMatch() + << "Surface does not support EGL_MULTISAMPLE_RESOLVE_BOX."; + } + break; + + default: + return EglBadAttribute() << "Invalid multisample resolve type."; + } + + case EGL_SWAP_BEHAVIOR: + switch (value) + { + case EGL_BUFFER_PRESERVED: + if ((surface->getConfig()->surfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) == 0) + { + return EglBadMatch() + << "Surface does not support EGL_SWAP_BEHAVIOR_PRESERVED."; + } + break; + + case EGL_BUFFER_DESTROYED: + break; + + default: + return EglBadAttribute() << "Invalid swap behaviour."; + } + + default: + return EglBadAttribute() << "Invalid surface attribute."; + } + + return NoError(); +} + +Error ValidateQuerySurface(const Display *display, + const Surface *surface, + EGLint attribute, + EGLint *value) +{ + ANGLE_TRY(ValidateDisplay(display)); + ANGLE_TRY(ValidateSurface(display, surface)); + + if (surface == EGL_NO_SURFACE) + { + return EglBadSurface() << "Surface cannot be EGL_NO_SURFACE."; + } + + switch (attribute) + { + case EGL_GL_COLORSPACE: + case EGL_VG_ALPHA_FORMAT: + case EGL_VG_COLORSPACE: + case EGL_CONFIG_ID: + case EGL_HEIGHT: + case EGL_HORIZONTAL_RESOLUTION: + case EGL_LARGEST_PBUFFER: + case EGL_MIPMAP_TEXTURE: + case EGL_MIPMAP_LEVEL: + case EGL_MULTISAMPLE_RESOLVE: + case EGL_PIXEL_ASPECT_RATIO: + case EGL_RENDER_BUFFER: + case EGL_SWAP_BEHAVIOR: + case EGL_TEXTURE_FORMAT: + case EGL_TEXTURE_TARGET: + case EGL_VERTICAL_RESOLUTION: + case EGL_WIDTH: + break; + + case EGL_POST_SUB_BUFFER_SUPPORTED_NV: + if (!display->getExtensions().postSubBuffer) + { + return EglBadAttribute() << "EGL_POST_SUB_BUFFER_SUPPORTED_NV cannot be used " + "without EGL_ANGLE_surface_orientation support."; + } + break; + + case EGL_FIXED_SIZE_ANGLE: + if (!display->getExtensions().windowFixedSize) + { + return EglBadAttribute() << "EGL_FIXED_SIZE_ANGLE cannot be used without " + "EGL_ANGLE_window_fixed_size support."; + } + break; + + case EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE: + if (!display->getExtensions().flexibleSurfaceCompatibility) + { + return EglBadAttribute() + << "EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE cannot be " + "used without EGL_ANGLE_flexible_surface_compatibility support."; + } + break; + + case EGL_SURFACE_ORIENTATION_ANGLE: + if (!display->getExtensions().surfaceOrientation) + { + return EglBadAttribute() << "EGL_SURFACE_ORIENTATION_ANGLE cannot be " + "queried without " + "EGL_ANGLE_surface_orientation support."; + } + break; + + case EGL_DIRECT_COMPOSITION_ANGLE: + if (!display->getExtensions().directComposition) + { + return EglBadAttribute() << "EGL_DIRECT_COMPOSITION_ANGLE cannot be " + "used without " + "EGL_ANGLE_direct_composition support."; + } + break; + + case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: + if (!display->getExtensions().robustResourceInitialization) + { + return EglBadAttribute() << "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE cannot be " + "used without EGL_ANGLE_robust_resource_initialization " + "support."; + } + break; + + default: + return EglBadAttribute() << "Invalid surface attribute."; + } + + return NoError(); +} + +Error ValidateQueryContext(const Display *display, + const gl::Context *context, + EGLint attribute, + EGLint *value) +{ + ANGLE_TRY(ValidateDisplay(display)); + ANGLE_TRY(ValidateContext(display, context)); + + switch (attribute) + { + case EGL_CONFIG_ID: + case EGL_CONTEXT_CLIENT_TYPE: + case EGL_CONTEXT_CLIENT_VERSION: + case EGL_RENDER_BUFFER: + break; + + case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: + if (!display->getExtensions().robustResourceInitialization) + { + return EglBadAttribute() << "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE cannot be " + "used without EGL_ANGLE_robust_resource_initialization " + "support."; + } + break; + + default: + return EglBadAttribute() << "Invalid context attribute."; + } + + return NoError(); +} + +} // namespace egl diff --git a/src/3rdparty/angle/src/libANGLE/validationEGL.h b/src/3rdparty/angle/src/libANGLE/validationEGL.h index eaafddc20d..3ab8232c7f 100644 --- a/src/3rdparty/angle/src/libANGLE/validationEGL.h +++ b/src/3rdparty/angle/src/libANGLE/validationEGL.h @@ -12,6 +12,7 @@ #include "libANGLE/Error.h" #include +#include namespace gl { @@ -22,17 +23,19 @@ namespace egl { class AttributeMap; +struct ClientExtensions; struct Config; class Device; class Display; class Image; +class Stream; class Surface; // Object validation Error ValidateDisplay(const Display *display); -Error ValidateSurface(const Display *display, Surface *surface); +Error ValidateSurface(const Display *display, const Surface *surface); Error ValidateConfig(const Display *display, const Config *config); -Error ValidateContext(const Display *display, gl::Context *context); +Error ValidateContext(const Display *display, const gl::Context *context); Error ValidateImage(const Display *display, const Image *image); // Entry point validation @@ -46,6 +49,8 @@ Error ValidateCreatePbufferSurface(Display *display, Config *config, const Attri Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, EGLClientBuffer buffer, Config *config, const AttributeMap& attributes); +Error ValidateMakeCurrent(Display *display, EGLSurface draw, EGLSurface read, gl::Context *context); + Error ValidateCreateImageKHR(const Display *display, gl::Context *context, EGLenum target, @@ -58,12 +63,120 @@ Error ValidateCreateDeviceANGLE(EGLint device_type, const EGLAttrib *attrib_list); Error ValidateReleaseDeviceANGLE(Device *device); +Error ValidateCreateStreamKHR(const Display *display, const AttributeMap &attributes); +Error ValidateDestroyStreamKHR(const Display *display, const Stream *stream); +Error ValidateStreamAttribKHR(const Display *display, + const Stream *stream, + EGLint attribute, + EGLint value); +Error ValidateQueryStreamKHR(const Display *display, + const Stream *stream, + EGLenum attribute, + EGLint *value); +Error ValidateQueryStreamu64KHR(const Display *display, + const Stream *stream, + EGLenum attribute, + EGLuint64KHR *value); +Error ValidateStreamConsumerGLTextureExternalKHR(const Display *display, + gl::Context *context, + const Stream *stream); +Error ValidateStreamConsumerAcquireKHR(const Display *display, + gl::Context *context, + const Stream *stream); +Error ValidateStreamConsumerReleaseKHR(const Display *display, + gl::Context *context, + const Stream *stream); +Error ValidateStreamConsumerGLTextureExternalAttribsNV(const Display *display, + gl::Context *context, + const Stream *stream, + const AttributeMap &attribs); +Error ValidateCreateStreamProducerD3DTextureNV12ANGLE(const Display *display, + const Stream *stream, + const AttributeMap &attribs); +Error ValidateStreamPostD3DTextureNV12ANGLE(const Display *display, + const Stream *stream, + void *texture, + const AttributeMap &attribs); + +Error ValidateGetSyncValuesCHROMIUM(const Display *display, + const Surface *surface, + const EGLuint64KHR *ust, + const EGLuint64KHR *msc, + const EGLuint64KHR *sbc); + +Error ValidateSwapBuffersWithDamageEXT(const Display *display, + const Surface *surface, + EGLint *rects, + EGLint n_rects); + +Error ValidateGetConfigAttrib(const Display *display, const Config *config, EGLint attribute); +Error ValidateChooseConfig(const Display *display, + const AttributeMap &attribs, + EGLint configSize, + EGLint *numConfig); +Error ValidateGetConfigs(const Display *display, EGLint configSize, EGLint *numConfig); + // Other validation Error ValidateCompatibleConfigs(const Display *display, const Config *config1, const Surface *surface, const Config *config2, EGLint surfaceType); -} + +Error ValidateGetPlatformDisplay(EGLenum platform, + void *native_display, + const EGLAttrib *attrib_list); +Error ValidateGetPlatformDisplayEXT(EGLenum platform, + void *native_display, + const EGLint *attrib_list); + +Error ValidateProgramCacheGetAttribANGLE(const Display *display, EGLenum attrib); + +Error ValidateProgramCacheQueryANGLE(const Display *display, + EGLint index, + void *key, + EGLint *keysize, + void *binary, + EGLint *binarysize); + +Error ValidateProgramCachePopulateANGLE(const Display *display, + const void *key, + EGLint keysize, + const void *binary, + EGLint binarysize); + +Error ValidateProgramCacheResizeANGLE(const Display *display, EGLint limit, EGLenum mode); + +Error ValidateSurfaceAttrib(const Display *display, + const Surface *surface, + EGLint attribute, + EGLint value); +Error ValidateQuerySurface(const Display *display, + const Surface *surface, + EGLint attribute, + EGLint *value); +Error ValidateQueryContext(const Display *display, + const gl::Context *context, + EGLint attribute, + EGLint *value); + +} // namespace egl + +#define ANGLE_EGL_TRY(THREAD, EXPR) \ + { \ + auto ANGLE_LOCAL_VAR = (EXPR); \ + if (ANGLE_LOCAL_VAR.isError()) \ + return THREAD->setError(ANGLE_LOCAL_VAR); \ + } + +#define ANGLE_EGL_TRY_RETURN(THREAD, EXPR, RETVAL) \ + { \ + auto ANGLE_LOCAL_VAR = (EXPR); \ + if (ANGLE_LOCAL_VAR.isError()) \ + { \ + THREAD->setError(ANGLE_LOCAL_VAR); \ + return RETVAL; \ + } \ + } #endif // LIBANGLE_VALIDATIONEGL_H_ diff --git a/src/3rdparty/angle/src/libANGLE/validationES.cpp b/src/3rdparty/angle/src/libANGLE/validationES.cpp index 12c76120bd..ae564b7412 100644 --- a/src/3rdparty/angle/src/libANGLE/validationES.cpp +++ b/src/3rdparty/angle/src/libANGLE/validationES.cpp @@ -7,86 +7,441 @@ // validationES.h: Validation functions for generic OpenGL ES entry point parameters #include "libANGLE/validationES.h" -#include "libANGLE/validationES2.h" -#include "libANGLE/validationES3.h" + #include "libANGLE/Context.h" #include "libANGLE/Display.h" -#include "libANGLE/Texture.h" +#include "libANGLE/ErrorStrings.h" #include "libANGLE/Framebuffer.h" #include "libANGLE/FramebufferAttachment.h" -#include "libANGLE/formatutils.h" #include "libANGLE/Image.h" -#include "libANGLE/Query.h" #include "libANGLE/Program.h" -#include "libANGLE/Uniform.h" +#include "libANGLE/Query.h" +#include "libANGLE/Texture.h" #include "libANGLE/TransformFeedback.h" #include "libANGLE/VertexArray.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/queryconversions.h" +#include "libANGLE/validationES2.h" +#include "libANGLE/validationES3.h" #include "common/mathutil.h" #include "common/utilities.h" +using namespace angle; + namespace gl { -const char *g_ExceedsMaxElementErrorMessage = "Element value exceeds maximum element index."; - namespace { -bool ValidateDrawAttribs(ValidationContext *context, GLint primcount, GLint maxVertex) + +bool ValidateDrawAttribs(ValidationContext *context, + GLint primcount, + GLint maxVertex, + GLint vertexCount) { - const gl::State &state = context->getState(); + const gl::State &state = context->getGLState(); const gl::Program *program = state.getProgram(); + bool webglCompatibility = context->getExtensions().webglCompatibility; + const VertexArray *vao = state.getVertexArray(); const auto &vertexAttribs = vao->getVertexAttributes(); - size_t maxEnabledAttrib = vao->getMaxEnabledAttribute(); + const auto &vertexBindings = vao->getVertexBindings(); + size_t maxEnabledAttrib = vao->getMaxEnabledAttribute(); for (size_t attributeIndex = 0; attributeIndex < maxEnabledAttrib; ++attributeIndex) { const VertexAttribute &attrib = vertexAttribs[attributeIndex]; - if (program->isAttribLocationActive(attributeIndex) && attrib.enabled) + + // No need to range check for disabled attribs. + if (!attrib.enabled) { - gl::Buffer *buffer = attrib.buffer.get(); + continue; + } - if (buffer) + // If we have no buffer, then we either get an error, or there are no more checks to be + // done. + const VertexBinding &binding = vertexBindings[attrib.bindingIndex]; + gl::Buffer *buffer = binding.getBuffer().get(); + if (!buffer) + { + if (webglCompatibility || !state.areClientArraysEnabled()) { - GLint64 attribStride = static_cast(ComputeVertexAttributeStride(attrib)); - GLint64 maxVertexElement = 0; - - if (attrib.divisor > 0) - { - maxVertexElement = - static_cast(primcount) / static_cast(attrib.divisor); - } - else - { - maxVertexElement = static_cast(maxVertex); - } - - // If we're drawing zero vertices, we have enough data. - if (maxVertexElement > 0) - { - // Note: Last vertex element does not take the full stride! - GLint64 attribSize = - static_cast(ComputeVertexAttributeTypeSize(attrib)); - GLint64 attribDataSize = (maxVertexElement - 1) * attribStride + attribSize; - - // [OpenGL ES 3.0.2] section 2.9.4 page 40: - // We can return INVALID_OPERATION if our vertex attribute does not have - // enough backing data. - if (attribDataSize > buffer->getSize()) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - } + // [WebGL 1.0] Section 6.5 Enabled Vertex Attributes and Range Checking + // If a vertex attribute is enabled as an array via enableVertexAttribArray but + // no buffer is bound to that attribute via bindBuffer and vertexAttribPointer, + // then calls to drawArrays or drawElements will generate an INVALID_OPERATION + // error. + ANGLE_VALIDATION_ERR(context, InvalidOperation(), VertexArrayNoBuffer); + return false; } - else if (attrib.pointer == NULL) + else if (attrib.pointer == nullptr) { // This is an application error that would normally result in a crash, // but we catch it and return an error - context->recordError(Error( - GL_INVALID_OPERATION, "An enabled vertex array has no buffer and no pointer.")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), VertexArrayNoBufferPointer); return false; } + continue; + } + + // This needs to come after the check for client arrays as even unused attributes cannot use + // client-side arrays + if (!program->isAttribLocationActive(attributeIndex)) + { + continue; + } + + // If we're drawing zero vertices, we have enough data. + if (vertexCount <= 0 || primcount <= 0) + { + continue; + } + + GLint maxVertexElement = 0; + GLuint divisor = binding.getDivisor(); + if (divisor == 0) + { + maxVertexElement = maxVertex; + } + else + { + maxVertexElement = (primcount - 1) / divisor; + } + + // We do manual overflow checks here instead of using safe_math.h because it was + // a bottleneck. Thanks to some properties of GL we know inequalities that can + // help us make the overflow checks faster. + + // The max possible attribSize is 16 for a vector of 4 32 bit values. + constexpr uint64_t kMaxAttribSize = 16; + constexpr uint64_t kIntMax = std::numeric_limits::max(); + constexpr uint64_t kUint64Max = std::numeric_limits::max(); + + // We know attribStride is given as a GLsizei which is typedefed to int. + // We also know an upper bound for attribSize. + static_assert(std::is_same::value, ""); + uint64_t attribStride = ComputeVertexAttributeStride(attrib, binding); + uint64_t attribSize = ComputeVertexAttributeTypeSize(attrib); + ASSERT(attribStride <= kIntMax && attribSize <= kMaxAttribSize); + + // Computing the max offset using uint64_t without attrib.offset is overflow + // safe. Note: Last vertex element does not take the full stride! + static_assert(kIntMax * kIntMax < kUint64Max - kMaxAttribSize, ""); + uint64_t attribDataSizeNoOffset = maxVertexElement * attribStride + attribSize; + + // An overflow can happen when adding the offset, check for it. + uint64_t attribOffset = ComputeVertexAttributeOffset(attrib, binding); + if (attribDataSizeNoOffset > kUint64Max - attribOffset) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow); + return false; + } + uint64_t attribDataSizeWithOffset = attribDataSizeNoOffset + attribOffset; + + // [OpenGL ES 3.0.2] section 2.9.4 page 40: + // We can return INVALID_OPERATION if our vertex attribute does not have + // enough backing data. + if (attribDataSizeWithOffset > static_cast(buffer->getSize())) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientVertexBufferSize); + return false; + } + } + + return true; +} + +bool ValidReadPixelsTypeEnum(ValidationContext *context, GLenum type) +{ + switch (type) + { + // Types referenced in Table 3.4 of the ES 2.0.25 spec + case GL_UNSIGNED_BYTE: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_5_6_5: + return context->getClientVersion() >= ES_2_0; + + // Types referenced in Table 3.2 of the ES 3.0.5 spec (Except depth stencil) + case GL_BYTE: + case GL_INT: + case GL_SHORT: + case GL_UNSIGNED_INT: + case GL_UNSIGNED_INT_10F_11F_11F_REV: + case GL_UNSIGNED_INT_24_8: + case GL_UNSIGNED_INT_2_10_10_10_REV: + case GL_UNSIGNED_INT_5_9_9_9_REV: + case GL_UNSIGNED_SHORT: + case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: + case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: + return context->getClientVersion() >= ES_3_0; + + case GL_FLOAT: + return context->getClientVersion() >= ES_3_0 || context->getExtensions().textureFloat || + context->getExtensions().colorBufferHalfFloat; + + case GL_HALF_FLOAT: + return context->getClientVersion() >= ES_3_0 || + context->getExtensions().textureHalfFloat; + + case GL_HALF_FLOAT_OES: + return context->getExtensions().colorBufferHalfFloat; + + default: + return false; + } +} + +bool ValidReadPixelsFormatEnum(ValidationContext *context, GLenum format) +{ + switch (format) + { + // Formats referenced in Table 3.4 of the ES 2.0.25 spec (Except luminance) + case GL_RGBA: + case GL_RGB: + case GL_ALPHA: + return context->getClientVersion() >= ES_2_0; + + // Formats referenced in Table 3.2 of the ES 3.0.5 spec + case GL_RG: + case GL_RED: + case GL_RGBA_INTEGER: + case GL_RGB_INTEGER: + case GL_RG_INTEGER: + case GL_RED_INTEGER: + return context->getClientVersion() >= ES_3_0; + + case GL_SRGB_ALPHA_EXT: + case GL_SRGB_EXT: + return context->getExtensions().sRGB; + + case GL_BGRA_EXT: + return context->getExtensions().readFormatBGRA; + + default: + return false; + } +} + +bool ValidReadPixelsFormatType(ValidationContext *context, + GLenum framebufferComponentType, + GLenum format, + GLenum type) +{ + switch (framebufferComponentType) + { + case GL_UNSIGNED_NORMALIZED: + // TODO(geofflang): Don't accept BGRA here. Some chrome internals appear to try to use + // ReadPixels with BGRA even if the extension is not present + return (format == GL_RGBA && type == GL_UNSIGNED_BYTE) || + (context->getExtensions().readFormatBGRA && format == GL_BGRA_EXT && + type == GL_UNSIGNED_BYTE); + + case GL_SIGNED_NORMALIZED: + return (format == GL_RGBA && type == GL_UNSIGNED_BYTE); + + case GL_INT: + return (format == GL_RGBA_INTEGER && type == GL_INT); + + case GL_UNSIGNED_INT: + return (format == GL_RGBA_INTEGER && type == GL_UNSIGNED_INT); + + case GL_FLOAT: + return (format == GL_RGBA && type == GL_FLOAT); + + default: + UNREACHABLE(); + return false; + } +} + +template +bool ValidateTextureWrapModeValue(Context *context, ParamType *params, bool restrictedWrapModes) +{ + switch (ConvertToGLenum(params[0])) + { + case GL_CLAMP_TO_EDGE: + break; + + case GL_REPEAT: + case GL_MIRRORED_REPEAT: + if (restrictedWrapModes) + { + // OES_EGL_image_external and ANGLE_texture_rectangle specifies this error. + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidWrapModeTexture); + return false; + } + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureWrap); + return false; + } + + return true; +} + +template +bool ValidateTextureMinFilterValue(Context *context, ParamType *params, bool restrictedMinFilter) +{ + switch (ConvertToGLenum(params[0])) + { + case GL_NEAREST: + case GL_LINEAR: + break; + + case GL_NEAREST_MIPMAP_NEAREST: + case GL_LINEAR_MIPMAP_NEAREST: + case GL_NEAREST_MIPMAP_LINEAR: + case GL_LINEAR_MIPMAP_LINEAR: + if (restrictedMinFilter) + { + // OES_EGL_image_external specifies this error. + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFilterTexture); + return false; + } + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureFilterParam); + return false; + } + + return true; +} + +template +bool ValidateTextureMagFilterValue(Context *context, ParamType *params) +{ + switch (ConvertToGLenum(params[0])) + { + case GL_NEAREST: + case GL_LINEAR: + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureFilterParam); + return false; + } + + return true; +} + +template +bool ValidateTextureCompareModeValue(Context *context, ParamType *params) +{ + // Acceptable mode parameters from GLES 3.0.2 spec, table 3.17 + switch (ConvertToGLenum(params[0])) + { + case GL_NONE: + case GL_COMPARE_REF_TO_TEXTURE: + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), UnknownParameter); + return false; + } + + return true; +} + +template +bool ValidateTextureCompareFuncValue(Context *context, ParamType *params) +{ + // Acceptable function parameters from GLES 3.0.2 spec, table 3.17 + switch (ConvertToGLenum(params[0])) + { + case GL_LEQUAL: + case GL_GEQUAL: + case GL_LESS: + case GL_GREATER: + case GL_EQUAL: + case GL_NOTEQUAL: + case GL_ALWAYS: + case GL_NEVER: + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), UnknownParameter); + return false; + } + + return true; +} + +template +bool ValidateTextureSRGBDecodeValue(Context *context, ParamType *params) +{ + if (!context->getExtensions().textureSRGBDecode) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled); + return false; + } + + switch (ConvertToGLenum(params[0])) + { + case GL_DECODE_EXT: + case GL_SKIP_DECODE_EXT: + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), UnknownParameter); + return false; + } + + return true; +} + +bool ValidateFragmentShaderColorBufferTypeMatch(ValidationContext *context) +{ + const Program *program = context->getGLState().getProgram(); + const Framebuffer *framebuffer = context->getGLState().getDrawFramebuffer(); + + const auto &programOutputTypes = program->getOutputVariableTypes(); + for (size_t drawBufferIdx = 0; drawBufferIdx < programOutputTypes.size(); drawBufferIdx++) + { + GLenum outputType = programOutputTypes[drawBufferIdx]; + GLenum inputType = framebuffer->getDrawbufferWriteType(drawBufferIdx); + if (outputType != GL_NONE && inputType != GL_NONE && inputType != outputType) + { + context->handleError(InvalidOperation() << "Fragment shader output type does not " + "match the bound framebuffer attachment " + "type."); + return false; + } + } + + return true; +} + +bool ValidateVertexShaderAttributeTypeMatch(ValidationContext *context) +{ + const auto &glState = context->getGLState(); + const Program *program = context->getGLState().getProgram(); + const VertexArray *vao = context->getGLState().getVertexArray(); + const auto &vertexAttribs = vao->getVertexAttributes(); + const auto ¤tValues = glState.getVertexAttribCurrentValues(); + + for (const sh::Attribute &shaderAttribute : program->getAttributes()) + { + // gl_VertexID and gl_InstanceID are active attributes but don't have a bound attribute. + if (shaderAttribute.isBuiltIn()) + { + continue; + } + + GLenum shaderInputType = VariableComponentType(shaderAttribute.type); + + const auto &attrib = vertexAttribs[shaderAttribute.location]; + GLenum vertexType = attrib.enabled ? GetVertexAttributeBaseType(attrib) + : currentValues[shaderAttribute.location].Type; + + if (shaderInputType != GL_NONE && vertexType != GL_NONE && shaderInputType != vertexType) + { + context->handleError(InvalidOperation() << "Vertex shader input type does not " + "match the type of the bound vertex " + "attribute."); + return false; } } @@ -95,48 +450,26 @@ bool ValidateDrawAttribs(ValidationContext *context, GLint primcount, GLint maxV } // anonymous namespace -bool ValidCap(const Context *context, GLenum cap) -{ - switch (cap) - { - case GL_CULL_FACE: - case GL_POLYGON_OFFSET_FILL: - case GL_SAMPLE_ALPHA_TO_COVERAGE: - case GL_SAMPLE_COVERAGE: - case GL_SCISSOR_TEST: - case GL_STENCIL_TEST: - case GL_DEPTH_TEST: - case GL_BLEND: - case GL_DITHER: - return true; - - case GL_PRIMITIVE_RESTART_FIXED_INDEX: - case GL_RASTERIZER_DISCARD: - return (context->getClientVersion() >= 3); - - case GL_DEBUG_OUTPUT_SYNCHRONOUS: - case GL_DEBUG_OUTPUT: - return context->getExtensions().debug; - - default: - return false; - } -} - bool ValidTextureTarget(const ValidationContext *context, GLenum target) { switch (target) { - case GL_TEXTURE_2D: - case GL_TEXTURE_CUBE_MAP: - return true; + case GL_TEXTURE_2D: + case GL_TEXTURE_CUBE_MAP: + return true; - case GL_TEXTURE_3D: - case GL_TEXTURE_2D_ARRAY: - return (context->getClientVersion() >= 3); + case GL_TEXTURE_RECTANGLE_ANGLE: + return context->getExtensions().textureRectangle; - default: - return false; + case GL_TEXTURE_3D: + case GL_TEXTURE_2D_ARRAY: + return (context->getClientMajorVersion() >= 3); + + case GL_TEXTURE_2D_MULTISAMPLE: + return (context->getClientVersion() >= Version(3, 1)); + + default: + return false; } } @@ -148,6 +481,9 @@ bool ValidTexture2DTarget(const ValidationContext *context, GLenum target) case GL_TEXTURE_CUBE_MAP: return true; + case GL_TEXTURE_RECTANGLE_ANGLE: + return context->getExtensions().textureRectangle; + default: return false; } @@ -159,13 +495,22 @@ bool ValidTexture3DTarget(const ValidationContext *context, GLenum target) { case GL_TEXTURE_3D: case GL_TEXTURE_2D_ARRAY: - return (context->getClientVersion() >= 3); + return (context->getClientMajorVersion() >= 3); default: return false; } } +// Most texture GL calls are not compatible with external textures, so we have a separate validation +// function for use in the GL calls that do +bool ValidTextureExternalTarget(const ValidationContext *context, GLenum target) +{ + return (target == GL_TEXTURE_EXTERNAL_OES) && + (context->getExtensions().eglImageExternal || + context->getExtensions().eglStreamConsumerExternal); +} + // This function differs from ValidTextureTarget in that the target must be // usable as the destination of a 2D operation-- so a cube face is valid, but // GL_TEXTURE_CUBE_MAP is not. @@ -174,94 +519,169 @@ bool ValidTexture2DDestinationTarget(const ValidationContext *context, GLenum ta { switch (target) { - case GL_TEXTURE_2D: - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - return true; - default: - return false; + case GL_TEXTURE_2D: + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + return true; + case GL_TEXTURE_RECTANGLE_ANGLE: + return context->getExtensions().textureRectangle; + default: + return false; } } +bool ValidateDrawElementsInstancedBase(ValidationContext *context, + GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei primcount) +{ + if (primcount < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativePrimcount); + return false; + } + + if (!ValidateDrawElementsCommon(context, mode, count, type, indices, primcount)) + { + return false; + } + + // No-op zero primitive count + return (primcount > 0); +} + +bool ValidateDrawArraysInstancedBase(Context *context, + GLenum mode, + GLint first, + GLsizei count, + GLsizei primcount) +{ + if (primcount < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativePrimcount); + return false; + } + + if (!ValidateDrawArraysCommon(context, mode, first, count, primcount)) + { + return false; + } + + // No-op if zero primitive count + return (primcount > 0); +} + +bool ValidateDrawInstancedANGLE(ValidationContext *context) +{ + // Verify there is at least one active attribute with a divisor of zero + const State &state = context->getGLState(); + + Program *program = state.getProgram(); + + const auto &attribs = state.getVertexArray()->getVertexAttributes(); + const auto &bindings = state.getVertexArray()->getVertexBindings(); + for (size_t attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) + { + const VertexAttribute &attrib = attribs[attributeIndex]; + const VertexBinding &binding = bindings[attrib.bindingIndex]; + if (program->isAttribLocationActive(attributeIndex) && binding.getDivisor() == 0) + { + return true; + } + } + + ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoZeroDivisor); + return false; +} + bool ValidTexture3DDestinationTarget(const ValidationContext *context, GLenum target) { switch (target) { - case GL_TEXTURE_3D: - case GL_TEXTURE_2D_ARRAY: - return true; - default: - return false; + case GL_TEXTURE_3D: + case GL_TEXTURE_2D_ARRAY: + return true; + default: + return false; } } -bool ValidFramebufferTarget(GLenum target) +bool ValidTexLevelDestinationTarget(const ValidationContext *context, GLenum target) { - static_assert(GL_DRAW_FRAMEBUFFER_ANGLE == GL_DRAW_FRAMEBUFFER && GL_READ_FRAMEBUFFER_ANGLE == GL_READ_FRAMEBUFFER, + switch (target) + { + case GL_TEXTURE_2D: + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + case GL_TEXTURE_3D: + case GL_TEXTURE_2D_ARRAY: + case GL_TEXTURE_2D_MULTISAMPLE: + return true; + case GL_TEXTURE_RECTANGLE_ANGLE: + return context->getExtensions().textureRectangle; + default: + return false; + } +} + +bool ValidFramebufferTarget(const ValidationContext *context, GLenum target) +{ + static_assert(GL_DRAW_FRAMEBUFFER_ANGLE == GL_DRAW_FRAMEBUFFER && + GL_READ_FRAMEBUFFER_ANGLE == GL_READ_FRAMEBUFFER, "ANGLE framebuffer enums must equal the ES3 framebuffer enums."); switch (target) { - case GL_FRAMEBUFFER: return true; - case GL_READ_FRAMEBUFFER: return true; - case GL_DRAW_FRAMEBUFFER: return true; - default: return false; + case GL_FRAMEBUFFER: + return true; + + case GL_READ_FRAMEBUFFER: + case GL_DRAW_FRAMEBUFFER: + return (context->getExtensions().framebufferBlit || + context->getClientMajorVersion() >= 3); + + default: + return false; } } -bool ValidBufferTarget(const Context *context, GLenum target) +bool ValidBufferType(const ValidationContext *context, BufferBinding target) { switch (target) { - case GL_ARRAY_BUFFER: - case GL_ELEMENT_ARRAY_BUFFER: - return true; + case BufferBinding::ElementArray: + case BufferBinding::Array: + return true; - case GL_PIXEL_PACK_BUFFER: - case GL_PIXEL_UNPACK_BUFFER: - return (context->getExtensions().pixelBufferObject || context->getClientVersion() >= 3); + case BufferBinding::PixelPack: + case BufferBinding::PixelUnpack: + return (context->getExtensions().pixelBufferObject || + context->getClientMajorVersion() >= 3); - case GL_COPY_READ_BUFFER: - case GL_COPY_WRITE_BUFFER: - case GL_TRANSFORM_FEEDBACK_BUFFER: - case GL_UNIFORM_BUFFER: - return (context->getClientVersion() >= 3); + case BufferBinding::CopyRead: + case BufferBinding::CopyWrite: + case BufferBinding::TransformFeedback: + case BufferBinding::Uniform: + return (context->getClientMajorVersion() >= 3); - default: - return false; - } -} + case BufferBinding::AtomicCounter: + case BufferBinding::ShaderStorage: + case BufferBinding::DrawIndirect: + case BufferBinding::DispatchIndirect: + return context->getClientVersion() >= Version(3, 1); -bool ValidBufferParameter(const Context *context, GLenum pname) -{ - const Extensions &extensions = context->getExtensions(); - - switch (pname) - { - case GL_BUFFER_USAGE: - case GL_BUFFER_SIZE: - return true; - - case GL_BUFFER_ACCESS_OES: - return extensions.mapBuffer; - - case GL_BUFFER_MAPPED: - static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal."); - return (context->getClientVersion() >= 3) || extensions.mapBuffer || extensions.mapBufferRange; - - // GL_BUFFER_MAP_POINTER is a special case, and may only be - // queried with GetBufferPointerv - case GL_BUFFER_ACCESS_FLAGS: - case GL_BUFFER_MAP_OFFSET: - case GL_BUFFER_MAP_LENGTH: - return (context->getClientVersion() >= 3) || extensions.mapBufferRange; - - default: - return false; + default: + return false; } } @@ -274,28 +694,34 @@ bool ValidMipLevel(const ValidationContext *context, GLenum target, GLint level) case GL_TEXTURE_2D: maxDimension = caps.max2DTextureSize; break; - case GL_TEXTURE_CUBE_MAP: - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - maxDimension = caps.maxCubeMapTextureSize; - break; - case GL_TEXTURE_3D: - maxDimension = caps.max3DTextureSize; - break; - case GL_TEXTURE_2D_ARRAY: - maxDimension = caps.max2DTextureSize; - break; - default: UNREACHABLE(); + case GL_TEXTURE_CUBE_MAP: + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + maxDimension = caps.maxCubeMapTextureSize; + break; + case GL_TEXTURE_RECTANGLE_ANGLE: + return level == 0; + case GL_TEXTURE_3D: + maxDimension = caps.max3DTextureSize; + break; + case GL_TEXTURE_2D_ARRAY: + maxDimension = caps.max2DTextureSize; + break; + case GL_TEXTURE_2D_MULTISAMPLE: + maxDimension = caps.max2DTextureSize; + break; + default: + UNREACHABLE(); } - return level <= gl::log2(static_cast(maxDimension)); + return level <= gl::log2(static_cast(maxDimension)) && level >= 0; } -bool ValidImageSizeParameters(const Context *context, +bool ValidImageSizeParameters(ValidationContext *context, GLenum target, GLint level, GLsizei width, @@ -303,21 +729,25 @@ bool ValidImageSizeParameters(const Context *context, GLsizei depth, bool isSubImage) { - if (level < 0 || width < 0 || height < 0 || depth < 0) + if (width < 0 || height < 0 || depth < 0) { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize); return false; } - // TexSubImage parameters can be NPOT without textureNPOT extension, // as long as the destination texture is POT. - if (!isSubImage && !context->getExtensions().textureNPOT && + bool hasNPOTSupport = + context->getExtensions().textureNPOT || context->getClientVersion() >= Version(3, 0); + if (!isSubImage && !hasNPOTSupport && (level != 0 && (!gl::isPow2(width) || !gl::isPow2(height) || !gl::isPow2(depth)))) { + ANGLE_VALIDATION_ERR(context, InvalidValue(), TextureNotPow2); return false; } if (!ValidMipLevel(context, target, level)) { + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel); return false; } @@ -334,7 +764,17 @@ bool CompressedTextureFormatRequiresExactSize(GLenum internalFormat) case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: + case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE: + case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE: + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE: + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE: + case GL_COMPRESSED_RGBA8_LOSSY_DECODE_ETC2_EAC_ANGLE: + case GL_COMPRESSED_SRGB8_ALPHA8_LOSSY_DECODE_ETC2_EAC_ANGLE: return true; default: @@ -342,12 +782,19 @@ bool CompressedTextureFormatRequiresExactSize(GLenum internalFormat) } } +bool ValidCompressedDimension(GLsizei size, GLuint blockSize, bool smallerThanBlockSizeAllowed) +{ + return (smallerThanBlockSizeAllowed && (size > 0) && (blockSize % size == 0)) || + (size % blockSize == 0); +} + bool ValidCompressedImageSize(const ValidationContext *context, GLenum internalFormat, + GLint level, GLsizei width, GLsizei height) { - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalFormat); if (!formatInfo.compressed) { return false; @@ -360,10 +807,15 @@ bool ValidCompressedImageSize(const ValidationContext *context, if (CompressedTextureFormatRequiresExactSize(internalFormat)) { - if ((static_cast(width) > formatInfo.compressedBlockWidth && - width % formatInfo.compressedBlockWidth != 0) || - (static_cast(height) > formatInfo.compressedBlockHeight && - height % formatInfo.compressedBlockHeight != 0)) + // The ANGLE extensions allow specifying compressed textures with sizes smaller than the + // block size for level 0 but WebGL disallows this. + bool smallerThanBlockSizeAllowed = + level > 0 || !context->getExtensions().webglCompatibility; + + if (!ValidCompressedDimension(width, formatInfo.compressedBlockWidth, + smallerThanBlockSizeAllowed) || + !ValidCompressedDimension(height, formatInfo.compressedBlockHeight, + smallerThanBlockSizeAllowed)) { return false; } @@ -372,30 +824,193 @@ bool ValidCompressedImageSize(const ValidationContext *context, return true; } +bool ValidCompressedSubImageSize(const ValidationContext *context, + GLenum internalFormat, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + size_t textureWidth, + size_t textureHeight) +{ + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalFormat); + if (!formatInfo.compressed) + { + return false; + } + + if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0) + { + return false; + } + + if (CompressedTextureFormatRequiresExactSize(internalFormat)) + { + if (xoffset % formatInfo.compressedBlockWidth != 0 || + yoffset % formatInfo.compressedBlockHeight != 0) + { + return false; + } + + // Allowed to either have data that is a multiple of block size or is smaller than the block + // size but fills the entire mip + bool fillsEntireMip = xoffset == 0 && yoffset == 0 && + static_cast(width) == textureWidth && + static_cast(height) == textureHeight; + bool sizeMultipleOfBlockSize = (width % formatInfo.compressedBlockWidth) == 0 && + (height % formatInfo.compressedBlockHeight) == 0; + if (!sizeMultipleOfBlockSize && !fillsEntireMip) + { + return false; + } + } + + return true; +} + +bool ValidImageDataSize(ValidationContext *context, + GLenum textureTarget, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *pixels, + GLsizei imageSize) +{ + gl::Buffer *pixelUnpackBuffer = + context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack); + if (pixelUnpackBuffer == nullptr && imageSize < 0) + { + // Checks are not required + return true; + } + + // ...the data would be unpacked from the buffer object such that the memory reads required + // would exceed the data store size. + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format, type); + ASSERT(formatInfo.internalFormat != GL_NONE); + const gl::Extents size(width, height, depth); + const auto &unpack = context->getGLState().getUnpackState(); + + bool targetIs3D = textureTarget == GL_TEXTURE_3D || textureTarget == GL_TEXTURE_2D_ARRAY; + auto endByteOrErr = formatInfo.computePackUnpackEndByte(type, size, unpack, targetIs3D); + if (endByteOrErr.isError()) + { + context->handleError(endByteOrErr.getError()); + return false; + } + + GLuint endByte = endByteOrErr.getResult(); + + if (pixelUnpackBuffer) + { + CheckedNumeric checkedEndByte(endByteOrErr.getResult()); + CheckedNumeric checkedOffset(reinterpret_cast(pixels)); + checkedEndByte += checkedOffset; + + if (!checkedEndByte.IsValid() || + (checkedEndByte.ValueOrDie() > static_cast(pixelUnpackBuffer->getSize()))) + { + // Overflow past the end of the buffer + context->handleError(InvalidOperation()); + return false; + } + } + else + { + ASSERT(imageSize >= 0); + if (pixels == nullptr && imageSize != 0) + { + context->handleError(InvalidOperation() + << "imageSize must be 0 if no texture data is provided."); + return false; + } + + if (pixels != nullptr && endByte > static_cast(imageSize)) + { + context->handleError(InvalidOperation() << "imageSize must be at least " << endByte); + return false; + } + } + + return true; +} + bool ValidQueryType(const Context *context, GLenum queryType) { - static_assert(GL_ANY_SAMPLES_PASSED == GL_ANY_SAMPLES_PASSED_EXT, "GL extension enums not equal."); - static_assert(GL_ANY_SAMPLES_PASSED_CONSERVATIVE == GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, "GL extension enums not equal."); + static_assert(GL_ANY_SAMPLES_PASSED == GL_ANY_SAMPLES_PASSED_EXT, + "GL extension enums not equal."); + static_assert(GL_ANY_SAMPLES_PASSED_CONSERVATIVE == GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, + "GL extension enums not equal."); switch (queryType) { - case GL_ANY_SAMPLES_PASSED: - case GL_ANY_SAMPLES_PASSED_CONSERVATIVE: - return true; - case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: - return (context->getClientVersion() >= 3); - case GL_TIME_ELAPSED_EXT: - return context->getExtensions().disjointTimerQuery; - default: - return false; + case GL_ANY_SAMPLES_PASSED: + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE: + return context->getClientMajorVersion() >= 3 || + context->getExtensions().occlusionQueryBoolean; + case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: + return (context->getClientMajorVersion() >= 3); + case GL_TIME_ELAPSED_EXT: + return context->getExtensions().disjointTimerQuery; + case GL_COMMANDS_COMPLETED_CHROMIUM: + return context->getExtensions().syncQuery; + default: + return false; } } -Program *GetValidProgram(Context *context, GLuint id) +bool ValidateWebGLVertexAttribPointer(ValidationContext *context, + GLenum type, + GLboolean normalized, + GLsizei stride, + const void *ptr, + bool pureInteger) { - // ES3 spec (section 2.11.1) -- "Commands that accept shader or program object names will generate the - // error INVALID_VALUE if the provided name is not the name of either a shader or program object and - // INVALID_OPERATION if the provided name identifies an object that is not the expected type." + ASSERT(context->getExtensions().webglCompatibility); + // WebGL 1.0 [Section 6.11] Vertex Attribute Data Stride + // The WebGL API supports vertex attribute data strides up to 255 bytes. A call to + // vertexAttribPointer will generate an INVALID_VALUE error if the value for the stride + // parameter exceeds 255. + constexpr GLsizei kMaxWebGLStride = 255; + if (stride > kMaxWebGLStride) + { + context->handleError(InvalidValue() + << "Stride is over the maximum stride allowed by WebGL."); + return false; + } + + // WebGL 1.0 [Section 6.4] Buffer Offset and Stride Requirements + // The offset arguments to drawElements and vertexAttribPointer, and the stride argument to + // vertexAttribPointer, must be a multiple of the size of the data type passed to the call, + // or an INVALID_OPERATION error is generated. + VertexFormatType internalType = GetVertexFormatType(type, normalized, 1, pureInteger); + size_t typeSize = GetVertexFormatTypeSize(internalType); + + ASSERT(isPow2(typeSize) && typeSize > 0); + size_t sizeMask = (typeSize - 1); + if ((reinterpret_cast(ptr) & sizeMask) != 0) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), OffsetMustBeMultipleOfType); + return false; + } + + if ((stride & sizeMask) != 0) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), StrideMustBeMultipleOfType); + return false; + } + + return true; +} + +Program *GetValidProgram(ValidationContext *context, GLuint id) +{ + // ES3 spec (section 2.11.1) -- "Commands that accept shader or program object names will + // generate the error INVALID_VALUE if the provided name is not the name of either a shader + // or program object and INVALID_OPERATION if the provided name identifies an object + // that is not the expected type." Program *validProgram = context->getProgram(id); @@ -403,19 +1018,18 @@ Program *GetValidProgram(Context *context, GLuint id) { if (context->getShader(id)) { - context->recordError( - Error(GL_INVALID_OPERATION, "Expected a program name, but found a shader name")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName); } else { - context->recordError(Error(GL_INVALID_VALUE, "Program name is not valid")); + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName); } } return validProgram; } -Shader *GetValidShader(Context *context, GLuint id) +Shader *GetValidShader(ValidationContext *context, GLuint id) { // See ValidProgram for spec details. @@ -425,12 +1039,11 @@ Shader *GetValidShader(Context *context, GLuint id) { if (context->getProgram(id)) { - context->recordError( - Error(GL_INVALID_OPERATION, "Expected a shader name, but found a program name")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedShaderName); } else { - context->recordError(Error(GL_INVALID_VALUE, "Shader name is invalid")); + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidShaderName); } } @@ -439,13 +1052,19 @@ Shader *GetValidShader(Context *context, GLuint id) bool ValidateAttachmentTarget(gl::Context *context, GLenum attachment) { - if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) + if (attachment >= GL_COLOR_ATTACHMENT1_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) { - const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); + if (context->getClientMajorVersion() < 3 && !context->getExtensions().drawBuffers) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment); + return false; + } + // Color attachment 0 is validated below because it is always valid + const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); if (colorAttachment >= context->getCaps().maxColorAttachments) { - context->recordError(Error(GL_INVALID_VALUE)); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidAttachment); return false; } } @@ -453,124 +1072,105 @@ bool ValidateAttachmentTarget(gl::Context *context, GLenum attachment) { switch (attachment) { - case GL_DEPTH_ATTACHMENT: - case GL_STENCIL_ATTACHMENT: - break; + case GL_COLOR_ATTACHMENT0: + case GL_DEPTH_ATTACHMENT: + case GL_STENCIL_ATTACHMENT: + break; - case GL_DEPTH_STENCIL_ATTACHMENT: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); + case GL_DEPTH_STENCIL_ATTACHMENT: + if (!context->getExtensions().webglCompatibility && + context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment); + return false; + } + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment); return false; - } - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return false; } } return true; } -bool ValidateRenderbufferStorageParametersBase(gl::Context *context, GLenum target, GLsizei samples, - GLenum internalformat, GLsizei width, GLsizei height) +bool ValidateRenderbufferStorageParametersBase(ValidationContext *context, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height) { switch (target) { - case GL_RENDERBUFFER: - break; - default: - context->recordError(Error(GL_INVALID_ENUM)); - return false; + case GL_RENDERBUFFER: + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget); + return false; } if (width < 0 || height < 0 || samples < 0) { - context->recordError(Error(GL_INVALID_VALUE)); + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRenderbufferWidthHeight); return false; } - const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat); + // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format. + GLenum convertedInternalFormat = context->getConvertedRenderbufferFormat(internalformat); + + const TextureCaps &formatCaps = context->getTextureCaps().get(convertedInternalFormat); if (!formatCaps.renderable) { - context->recordError(Error(GL_INVALID_ENUM)); + context->handleError(InvalidEnum()); return false; } // ANGLE_framebuffer_multisample does not explicitly state that the internal format must be // sized but it does state that the format must be in the ES2.0 spec table 4.5 which contains // only sized internal formats. - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat); - if (formatInfo.pixelBytes == 0) + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(convertedInternalFormat); + if (formatInfo.internalFormat == GL_NONE) { - context->recordError(Error(GL_INVALID_ENUM)); + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferInternalFormat); return false; } if (static_cast(std::max(width, height)) > context->getCaps().maxRenderbufferSize) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } - GLuint handle = context->getState().getRenderbufferId(); + GLuint handle = context->getGLState().getRenderbufferId(); if (handle == 0) { - context->recordError(Error(GL_INVALID_OPERATION)); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidRenderbufferTarget); return false; } return true; } -bool ValidateRenderbufferStorageParametersANGLE(gl::Context *context, GLenum target, GLsizei samples, - GLenum internalformat, GLsizei width, GLsizei height) +bool ValidateFramebufferRenderbufferParameters(gl::Context *context, + GLenum target, + GLenum attachment, + GLenum renderbuffertarget, + GLuint renderbuffer) { - ASSERT(samples == 0 || context->getExtensions().framebufferMultisample); - - // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal - // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_VALUE is - // generated. - if (static_cast(samples) > context->getCaps().maxSamples) + if (!ValidFramebufferTarget(context, target)) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidEnum()); return false; } - // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create - // the specified storage. This is different than ES 3.0 in which a sample number higher - // than the maximum sample number supported by this format generates a GL_INVALID_VALUE. - // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3. - if (context->getClientVersion() >= 3) - { - const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat); - if (static_cast(samples) > formatCaps.getMaxSamples()) - { - context->recordError(Error(GL_OUT_OF_MEMORY)); - return false; - } - } - - return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat, width, height); -} - -bool ValidateFramebufferRenderbufferParameters(gl::Context *context, GLenum target, GLenum attachment, - GLenum renderbuffertarget, GLuint renderbuffer) -{ - if (!ValidFramebufferTarget(target)) - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - - gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); + gl::Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target); ASSERT(framebuffer); if (framebuffer->id() == 0) { - context->recordError(Error(GL_INVALID_OPERATION, "Cannot change default FBO's attachments")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), DefaultFramebufferTarget); return false; } @@ -587,7 +1187,7 @@ bool ValidateFramebufferRenderbufferParameters(gl::Context *context, GLenum targ { if (!context->getRenderbuffer(renderbuffer)) { - context->recordError(Error(GL_INVALID_OPERATION)); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidRenderbufferTarget); return false; } } @@ -595,7 +1195,7 @@ bool ValidateFramebufferRenderbufferParameters(gl::Context *context, GLenum targ return true; } -bool ValidateBlitFramebufferParameters(gl::Context *context, +bool ValidateBlitFramebufferParameters(ValidationContext *context, GLint srcX0, GLint srcY0, GLint srcX1, @@ -609,18 +1209,18 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, { switch (filter) { - case GL_NEAREST: - break; - case GL_LINEAR: - break; - default: - context->recordError(Error(GL_INVALID_ENUM)); - return false; + case GL_NEAREST: + break; + case GL_LINEAR: + break; + default: + context->handleError(InvalidEnum()); + return false; } if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } @@ -635,40 +1235,41 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, // color buffer, leaving only nearest being unfiltered from above if ((mask & ~GL_COLOR_BUFFER_BIT) != 0 && filter != GL_NEAREST) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } - if (context->getState().getReadFramebuffer()->id() == context->getState().getDrawFramebuffer()->id()) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - - const gl::Framebuffer *readFramebuffer = context->getState().getReadFramebuffer(); - const gl::Framebuffer *drawFramebuffer = context->getState().getDrawFramebuffer(); + const auto &glState = context->getGLState(); + gl::Framebuffer *readFramebuffer = glState.getReadFramebuffer(); + gl::Framebuffer *drawFramebuffer = glState.getDrawFramebuffer(); if (!readFramebuffer || !drawFramebuffer) { - context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION)); + context->handleError(InvalidFramebufferOperation()); return false; } - if (!readFramebuffer->checkStatus(context->getData())) + if (readFramebuffer->id() == drawFramebuffer->id()) { - context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION)); + context->handleError(InvalidOperation()); return false; } - if (!drawFramebuffer->checkStatus(context->getData())) + if (readFramebuffer->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE) { - context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION)); + context->handleError(InvalidFramebufferOperation()); return false; } - if (drawFramebuffer->getSamples(context->getData()) != 0) + if (drawFramebuffer->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidFramebufferOperation()); + return false; + } + + if (drawFramebuffer->getSamples(context) != 0) + { + context->handleError(InvalidOperation()); return false; } @@ -677,13 +1278,11 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, if (mask & GL_COLOR_BUFFER_BIT) { const gl::FramebufferAttachment *readColorBuffer = readFramebuffer->getReadColorbuffer(); - const gl::FramebufferAttachment *drawColorBuffer = drawFramebuffer->getFirstColorbuffer(); const Extensions &extensions = context->getExtensions(); - if (readColorBuffer && drawColorBuffer) + if (readColorBuffer) { - GLenum readInternalFormat = readColorBuffer->getInternalFormat(); - const InternalFormat &readFormatInfo = GetInternalFormatInfo(readInternalFormat); + const Format &readFormat = readColorBuffer->getFormat(); for (size_t drawbufferIdx = 0; drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx) @@ -692,18 +1291,19 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, drawFramebuffer->getDrawBuffer(drawbufferIdx); if (attachment) { - GLenum drawInternalFormat = attachment->getInternalFormat(); - const InternalFormat &drawFormatInfo = GetInternalFormatInfo(drawInternalFormat); + const Format &drawFormat = attachment->getFormat(); // The GL ES 3.0.2 spec (pg 193) states that: // 1) If the read buffer is fixed point format, the draw buffer must be as well - // 2) If the read buffer is an unsigned integer format, the draw buffer must be as well - // 3) If the read buffer is a signed integer format, the draw buffer must be as well + // 2) If the read buffer is an unsigned integer format, the draw buffer must be + // as well + // 3) If the read buffer is a signed integer format, the draw buffer must be as + // well // Changes with EXT_color_buffer_float: // Case 1) is changed to fixed point OR floating point - GLenum readComponentType = readFormatInfo.componentType; - GLenum drawComponentType = drawFormatInfo.componentType; - bool readFixedPoint = (readComponentType == GL_UNSIGNED_NORMALIZED || + GLenum readComponentType = readFormat.info->componentType; + GLenum drawComponentType = drawFormat.info->componentType; + bool readFixedPoint = (readComponentType == GL_UNSIGNED_NORMALIZED || readComponentType == GL_SIGNED_NORMALIZED); bool drawFixedPoint = (drawComponentType == GL_UNSIGNED_NORMALIZED || drawComponentType == GL_SIGNED_NORMALIZED); @@ -715,350 +1315,162 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, if (readFixedOrFloat != drawFixedOrFloat) { - context->recordError(Error(GL_INVALID_OPERATION, - "If the read buffer contains fixed-point or " - "floating-point values, the draw buffer " - "must as well.")); + context->handleError(InvalidOperation() + << "If the read buffer contains fixed-point or " + "floating-point values, the draw buffer must " + "as well."); return false; } } else if (readFixedPoint != drawFixedPoint) { - context->recordError(Error(GL_INVALID_OPERATION, - "If the read buffer contains fixed-point " - "values, the draw buffer must as well.")); + context->handleError(InvalidOperation() + << "If the read buffer contains fixed-point values, " + "the draw buffer must as well."); return false; } if (readComponentType == GL_UNSIGNED_INT && drawComponentType != GL_UNSIGNED_INT) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } if (readComponentType == GL_INT && drawComponentType != GL_INT) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } - if (readColorBuffer->getSamples() > 0 && (readInternalFormat != drawInternalFormat || !sameBounds)) + if (readColorBuffer->getSamples() > 0 && + (!Format::EquivalentForBlit(readFormat, drawFormat) || !sameBounds)) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); + return false; + } + + if (context->getExtensions().webglCompatibility && + *readColorBuffer == *attachment) + { + context->handleError( + InvalidOperation() + << "Read and write color attachments cannot be the same image."); return false; } } } - if ((readFormatInfo.componentType == GL_INT || readFormatInfo.componentType == GL_UNSIGNED_INT) && filter == GL_LINEAR) + if ((readFormat.info->componentType == GL_INT || + readFormat.info->componentType == GL_UNSIGNED_INT) && + filter == GL_LINEAR) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } } + // WebGL 2.0 BlitFramebuffer when blitting from a missing attachment + // In OpenGL ES it is undefined what happens when an operation tries to blit from a missing + // attachment and WebGL defines it to be an error. We do the check unconditionally as the + // situation is an application error that would lead to a crash in ANGLE. + else if (drawFramebuffer->hasEnabledDrawBuffer()) + { + context->handleError( + InvalidOperation() + << "Attempt to read from a missing color attachment of a complete framebuffer."); + return false; + } } - GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT}; + GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT}; GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT}; for (size_t i = 0; i < 2; i++) { if (mask & masks[i]) { - const gl::FramebufferAttachment *readBuffer = readFramebuffer->getAttachment(attachments[i]); - const gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getAttachment(attachments[i]); + const gl::FramebufferAttachment *readBuffer = + readFramebuffer->getAttachment(attachments[i]); + const gl::FramebufferAttachment *drawBuffer = + drawFramebuffer->getAttachment(attachments[i]); if (readBuffer && drawBuffer) { - if (readBuffer->getInternalFormat() != drawBuffer->getInternalFormat()) + if (!Format::EquivalentForBlit(readBuffer->getFormat(), drawBuffer->getFormat())) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } if (readBuffer->getSamples() > 0 && !sameBounds) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); + return false; + } + + if (context->getExtensions().webglCompatibility && *readBuffer == *drawBuffer) + { + context->handleError( + InvalidOperation() + << "Read and write depth stencil attachments cannot be the same image."); return false; } } + // WebGL 2.0 BlitFramebuffer when blitting from a missing attachment + else if (drawBuffer) + { + context->handleError(InvalidOperation() << "Attempt to read from a missing " + "depth/stencil attachment of a " + "complete framebuffer."); + return false; + } } } + // ANGLE_multiview, Revision 1: + // Calling BlitFramebuffer will result in an INVALID_FRAMEBUFFER_OPERATION error if the + // multi-view layout of the current draw framebuffer or read framebuffer is not NONE. + if (readFramebuffer->getMultiviewLayout() != GL_NONE) + { + context->handleError(InvalidFramebufferOperation() + << "Attempt to read from a multi-view framebuffer."); + return false; + } + if (drawFramebuffer->getMultiviewLayout() != GL_NONE) + { + context->handleError(InvalidFramebufferOperation() + << "Attempt to write to a multi-view framebuffer."); + return false; + } + return true; } -bool ValidateGetVertexAttribParameters(Context *context, GLenum pname) +bool ValidateReadPixelsRobustANGLE(Context *context, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + GLsizei *columns, + GLsizei *rows, + void *pixels) { - switch (pname) + if (!ValidateRobustEntryPoint(context, bufSize)) { - case GL_VERTEX_ATTRIB_ARRAY_ENABLED: - case GL_VERTEX_ATTRIB_ARRAY_SIZE: - case GL_VERTEX_ATTRIB_ARRAY_STRIDE: - case GL_VERTEX_ATTRIB_ARRAY_TYPE: - case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: - case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: - case GL_CURRENT_VERTEX_ATTRIB: - return true; - - case GL_VERTEX_ATTRIB_ARRAY_DIVISOR: - // Don't verify ES3 context because GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE uses - // the same constant. - static_assert(GL_VERTEX_ATTRIB_ARRAY_DIVISOR == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE, - "ANGLE extension enums not equal to GL enums."); - return true; - - case GL_VERTEX_ATTRIB_ARRAY_INTEGER: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - return true; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } -} - -bool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param) -{ - switch (pname) - { - case GL_TEXTURE_WRAP_R: - case GL_TEXTURE_SWIZZLE_R: - case GL_TEXTURE_SWIZZLE_G: - case GL_TEXTURE_SWIZZLE_B: - case GL_TEXTURE_SWIZZLE_A: - case GL_TEXTURE_BASE_LEVEL: - case GL_TEXTURE_MAX_LEVEL: - case GL_TEXTURE_COMPARE_MODE: - case GL_TEXTURE_COMPARE_FUNC: - case GL_TEXTURE_MIN_LOD: - case GL_TEXTURE_MAX_LOD: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - - default: break; - } - - switch (pname) - { - case GL_TEXTURE_WRAP_S: - case GL_TEXTURE_WRAP_T: - case GL_TEXTURE_WRAP_R: - switch (param) - { - case GL_REPEAT: - case GL_CLAMP_TO_EDGE: - case GL_MIRRORED_REPEAT: - return true; - default: - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - - case GL_TEXTURE_MIN_FILTER: - switch (param) - { - case GL_NEAREST: - case GL_LINEAR: - case GL_NEAREST_MIPMAP_NEAREST: - case GL_LINEAR_MIPMAP_NEAREST: - case GL_NEAREST_MIPMAP_LINEAR: - case GL_LINEAR_MIPMAP_LINEAR: - return true; - default: - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - - case GL_TEXTURE_MAG_FILTER: - switch (param) - { - case GL_NEAREST: - case GL_LINEAR: - return true; - default: - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - - case GL_TEXTURE_USAGE_ANGLE: - switch (param) - { - case GL_NONE: - case GL_FRAMEBUFFER_ATTACHMENT_ANGLE: - return true; - default: - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - - case GL_TEXTURE_MAX_ANISOTROPY_EXT: - if (!context->getExtensions().textureFilterAnisotropic) - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - - // we assume the parameter passed to this validation method is truncated, not rounded - if (param < 1) - { - context->recordError(Error(GL_INVALID_VALUE)); - return false; - } - return true; - - case GL_TEXTURE_MIN_LOD: - case GL_TEXTURE_MAX_LOD: - // any value is permissible - return true; - - case GL_TEXTURE_COMPARE_MODE: - // Acceptable mode parameters from GLES 3.0.2 spec, table 3.17 - switch (param) - { - case GL_NONE: - case GL_COMPARE_REF_TO_TEXTURE: - return true; - default: - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - - case GL_TEXTURE_COMPARE_FUNC: - // Acceptable function parameters from GLES 3.0.2 spec, table 3.17 - switch (param) - { - case GL_LEQUAL: - case GL_GEQUAL: - case GL_LESS: - case GL_GREATER: - case GL_EQUAL: - case GL_NOTEQUAL: - case GL_ALWAYS: - case GL_NEVER: - return true; - default: - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - - case GL_TEXTURE_SWIZZLE_R: - case GL_TEXTURE_SWIZZLE_G: - case GL_TEXTURE_SWIZZLE_B: - case GL_TEXTURE_SWIZZLE_A: - switch (param) - { - case GL_RED: - case GL_GREEN: - case GL_BLUE: - case GL_ALPHA: - case GL_ZERO: - case GL_ONE: - return true; - default: - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - - case GL_TEXTURE_BASE_LEVEL: - case GL_TEXTURE_MAX_LEVEL: - if (param < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return false; - } - return true; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } -} - -bool ValidateSamplerObjectParameter(gl::Context *context, GLenum pname) -{ - switch (pname) - { - case GL_TEXTURE_MIN_FILTER: - case GL_TEXTURE_MAG_FILTER: - case GL_TEXTURE_WRAP_S: - case GL_TEXTURE_WRAP_T: - case GL_TEXTURE_WRAP_R: - case GL_TEXTURE_MIN_LOD: - case GL_TEXTURE_MAX_LOD: - case GL_TEXTURE_COMPARE_MODE: - case GL_TEXTURE_COMPARE_FUNC: - return true; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } -} - -bool ValidateReadPixels(Context *context, - GLint x, - GLint y, - GLsizei width, - GLsizei height, - GLenum format, - GLenum type, - GLvoid *pixels) -{ - if (width < 0 || height < 0) - { - context->recordError(Error(GL_INVALID_VALUE, "width and height must be positive")); return false; } - Framebuffer *framebuffer = context->getState().getReadFramebuffer(); - ASSERT(framebuffer); - - if (framebuffer->checkStatus(context->getData()) != GL_FRAMEBUFFER_COMPLETE) + if (!ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, length, + columns, rows, pixels)) { - context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION)); return false; } - if (context->getState().getReadFramebuffer()->id() != 0 && - framebuffer->getSamples(context->getData()) != 0) + if (!ValidateRobustBufferSize(context, bufSize, *length)) { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - - const FramebufferAttachment *readBuffer = framebuffer->getReadColorbuffer(); - if (!readBuffer) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - - GLenum currentFormat = framebuffer->getImplementationColorReadFormat(); - GLenum currentType = framebuffer->getImplementationColorReadType(); - GLenum currentInternalFormat = readBuffer->getInternalFormat(); - GLuint clientVersion = context->getClientVersion(); - - bool validReadFormat = (clientVersion < 3) ? ValidES2ReadFormatType(context, format, type) : - ValidES3ReadFormatType(context, currentInternalFormat, format, type); - - if (!(currentFormat == format && currentType == type) && !validReadFormat) - { - context->recordError(Error(GL_INVALID_OPERATION)); return false; } @@ -1073,63 +1485,60 @@ bool ValidateReadnPixelsEXT(Context *context, GLenum format, GLenum type, GLsizei bufSize, - GLvoid *pixels) + void *pixels) { if (bufSize < 0) { - context->recordError(Error(GL_INVALID_VALUE, "bufSize must be a positive number")); + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize); return false; } - GLenum sizedInternalFormat = GetSizedInternalFormat(format, type); - const InternalFormat &sizedFormatInfo = GetInternalFormatInfo(sizedInternalFormat); - - GLsizei outputPitch = - sizedFormatInfo.computeRowPitch(type, width, context->getState().getPackAlignment(), - context->getState().getPackRowLength()); - // sized query sanity check - int requiredSize = outputPitch * height; - if (requiredSize > bufSize) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - - return ValidateReadPixels(context, x, y, width, height, format, type, pixels); + return ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, nullptr, + nullptr, nullptr, pixels); } -bool ValidateGenQueriesBase(gl::Context *context, GLsizei n, const GLuint *ids) +bool ValidateReadnPixelsRobustANGLE(Context *context, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + GLsizei *columns, + GLsizei *rows, + void *data) { - if (n < 0) + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, length, + columns, rows, data)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *length)) { - context->recordError(Error(GL_INVALID_VALUE, "Query count < 0")); return false; } return true; } -bool ValidateGenQueriesEXT(gl::Context *context, GLsizei n, const GLuint *ids) +bool ValidateGenQueriesEXT(gl::Context *context, GLsizei n, GLuint *ids) { if (!context->getExtensions().occlusionQueryBoolean && !context->getExtensions().disjointTimerQuery) { - context->recordError(Error(GL_INVALID_OPERATION, "Query extension not enabled")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryExtensionNotEnabled); return false; } - return ValidateGenQueriesBase(context, n, ids); -} - -bool ValidateDeleteQueriesBase(gl::Context *context, GLsizei n, const GLuint *ids) -{ - if (n < 0) - { - context->recordError(Error(GL_INVALID_VALUE, "Query count < 0")); - return false; - } - - return true; + return ValidateGenOrDelete(context, n); } bool ValidateDeleteQueriesEXT(gl::Context *context, GLsizei n, const GLuint *ids) @@ -1137,24 +1546,36 @@ bool ValidateDeleteQueriesEXT(gl::Context *context, GLsizei n, const GLuint *ids if (!context->getExtensions().occlusionQueryBoolean && !context->getExtensions().disjointTimerQuery) { - context->recordError(Error(GL_INVALID_OPERATION, "Query extension not enabled")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryExtensionNotEnabled); return false; } - return ValidateDeleteQueriesBase(context, n, ids); + return ValidateGenOrDelete(context, n); +} + +bool ValidateIsQueryEXT(gl::Context *context, GLuint id) +{ + if (!context->getExtensions().occlusionQueryBoolean && + !context->getExtensions().disjointTimerQuery) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryExtensionNotEnabled); + return false; + } + + return true; } bool ValidateBeginQueryBase(gl::Context *context, GLenum target, GLuint id) { if (!ValidQueryType(context, target)) { - context->recordError(Error(GL_INVALID_ENUM, "Invalid query target")); + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidQueryType); return false; } if (id == 0) { - context->recordError(Error(GL_INVALID_OPERATION, "Query id is 0")); + context->handleError(InvalidOperation() << "Query id is 0"); return false; } @@ -1174,11 +1595,9 @@ bool ValidateBeginQueryBase(gl::Context *context, GLenum target, GLuint id) // of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, // no query may be active for either if glBeginQuery targets either. - // TODO(ewell): I think this needs to be changed for timer and occlusion queries to work at the - // same time - if (context->getState().isQueryActive()) + if (context->getGLState().isQueryActive(target)) { - context->recordError(Error(GL_INVALID_OPERATION, "Other query is active")); + context->handleError(InvalidOperation() << "Other query is active"); return false; } @@ -1187,14 +1606,14 @@ bool ValidateBeginQueryBase(gl::Context *context, GLenum target, GLuint id) // check that name was obtained with glGenQueries if (!queryObject) { - context->recordError(Error(GL_INVALID_OPERATION, "Invalid query id")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidQueryId); return false; } // check for type mismatch if (queryObject->getType() != target) { - context->recordError(Error(GL_INVALID_OPERATION, "Query type does not match target")); + context->handleError(InvalidOperation() << "Query type does not match target"); return false; } @@ -1204,9 +1623,9 @@ bool ValidateBeginQueryBase(gl::Context *context, GLenum target, GLuint id) bool ValidateBeginQueryEXT(gl::Context *context, GLenum target, GLuint id) { if (!context->getExtensions().occlusionQueryBoolean && - !context->getExtensions().disjointTimerQuery) + !context->getExtensions().disjointTimerQuery && !context->getExtensions().syncQuery) { - context->recordError(Error(GL_INVALID_OPERATION, "Query extension not enabled")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryExtensionNotEnabled); return false; } @@ -1217,15 +1636,15 @@ bool ValidateEndQueryBase(gl::Context *context, GLenum target) { if (!ValidQueryType(context, target)) { - context->recordError(Error(GL_INVALID_ENUM, "Invalid query target")); + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidQueryType); return false; } - const Query *queryObject = context->getState().getActiveQuery(target); + const Query *queryObject = context->getGLState().getActiveQuery(target); if (queryObject == nullptr) { - context->recordError(Error(GL_INVALID_OPERATION, "Query target not active")); + context->handleError(InvalidOperation() << "Query target not active"); return false; } @@ -1235,9 +1654,9 @@ bool ValidateEndQueryBase(gl::Context *context, GLenum target) bool ValidateEndQueryEXT(gl::Context *context, GLenum target) { if (!context->getExtensions().occlusionQueryBoolean && - !context->getExtensions().disjointTimerQuery) + !context->getExtensions().disjointTimerQuery && !context->getExtensions().syncQuery) { - context->recordError(Error(GL_INVALID_OPERATION, "Query extension not enabled")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryExtensionNotEnabled); return false; } @@ -1248,37 +1667,42 @@ bool ValidateQueryCounterEXT(Context *context, GLuint id, GLenum target) { if (!context->getExtensions().disjointTimerQuery) { - context->recordError(Error(GL_INVALID_OPERATION, "Disjoint timer query not enabled")); + context->handleError(InvalidOperation() << "Disjoint timer query not enabled"); return false; } if (target != GL_TIMESTAMP_EXT) { - context->recordError(Error(GL_INVALID_ENUM, "Invalid query target")); + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidQueryTarget); return false; } Query *queryObject = context->getQuery(id, true, target); if (queryObject == nullptr) { - context->recordError(Error(GL_INVALID_OPERATION, "Invalid query id")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidQueryId); return false; } - if (context->getState().isQueryActive(queryObject)) + if (context->getGLState().isQueryActive(queryObject)) { - context->recordError(Error(GL_INVALID_OPERATION, "Query is active")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryActive); return false; } return true; } -bool ValidateGetQueryivBase(Context *context, GLenum target, GLenum pname) +bool ValidateGetQueryivBase(Context *context, GLenum target, GLenum pname, GLsizei *numParams) { + if (numParams) + { + *numParams = 0; + } + if (!ValidQueryType(context, target) && target != GL_TIMESTAMP_EXT) { - context->recordError(Error(GL_INVALID_ENUM, "Invalid query type")); + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidQueryType); return false; } @@ -1287,8 +1711,7 @@ bool ValidateGetQueryivBase(Context *context, GLenum target, GLenum pname) case GL_CURRENT_QUERY_EXT: if (target == GL_TIMESTAMP_EXT) { - context->recordError( - Error(GL_INVALID_ENUM, "Cannot use current query for timestamp")); + context->handleError(InvalidEnum() << "Cannot use current query for timestamp"); return false; } break; @@ -1296,43 +1719,79 @@ bool ValidateGetQueryivBase(Context *context, GLenum target, GLenum pname) if (!context->getExtensions().disjointTimerQuery || (target != GL_TIMESTAMP_EXT && target != GL_TIME_ELAPSED_EXT)) { - context->recordError(Error(GL_INVALID_ENUM, "Invalid pname")); + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname); return false; } break; default: - context->recordError(Error(GL_INVALID_ENUM, "Invalid pname")); + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname); return false; } + if (numParams) + { + // All queries return only one value + *numParams = 1; + } + return true; } bool ValidateGetQueryivEXT(Context *context, GLenum target, GLenum pname, GLint *params) { if (!context->getExtensions().occlusionQueryBoolean && - !context->getExtensions().disjointTimerQuery) + !context->getExtensions().disjointTimerQuery && !context->getExtensions().syncQuery) { - context->recordError(Error(GL_INVALID_OPERATION, "Query extension not enabled")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); return false; } - return ValidateGetQueryivBase(context, target, pname); + return ValidateGetQueryivBase(context, target, pname, nullptr); } -bool ValidateGetQueryObjectValueBase(Context *context, GLuint id, GLenum pname) +bool ValidateGetQueryivRobustANGLE(Context *context, + GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) { + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateGetQueryivBase(context, target, pname, length)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *length)) + { + return false; + } + + return true; +} + +bool ValidateGetQueryObjectValueBase(Context *context, GLuint id, GLenum pname, GLsizei *numParams) +{ + if (numParams) + { + *numParams = 0; + } + Query *queryObject = context->getQuery(id, false, GL_NONE); if (!queryObject) { - context->recordError(Error(GL_INVALID_OPERATION, "Query does not exist")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidQueryId); return false; } - if (context->getState().isQueryActive(queryObject)) + if (context->getGLState().isQueryActive(queryObject)) { - context->recordError(Error(GL_INVALID_OPERATION, "Query currently active")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryActive); return false; } @@ -1343,10 +1802,15 @@ bool ValidateGetQueryObjectValueBase(Context *context, GLuint id, GLenum pname) break; default: - context->recordError(Error(GL_INVALID_ENUM, "Invalid pname enum")); + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); return false; } + if (numParams) + { + *numParams = 1; + } + return true; } @@ -1354,59 +1818,190 @@ bool ValidateGetQueryObjectivEXT(Context *context, GLuint id, GLenum pname, GLin { if (!context->getExtensions().disjointTimerQuery) { - context->recordError(Error(GL_INVALID_OPERATION, "Timer query extension not enabled")); + context->handleError(InvalidOperation() << "Timer query extension not enabled"); return false; } - return ValidateGetQueryObjectValueBase(context, id, pname); + return ValidateGetQueryObjectValueBase(context, id, pname, nullptr); +} + +bool ValidateGetQueryObjectivRobustANGLE(Context *context, + GLuint id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + if (!context->getExtensions().disjointTimerQuery) + { + context->handleError(InvalidOperation() << "Timer query extension not enabled"); + return false; + } + + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateGetQueryObjectValueBase(context, id, pname, length)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *length)) + { + return false; + } + + return true; } bool ValidateGetQueryObjectuivEXT(Context *context, GLuint id, GLenum pname, GLuint *params) { if (!context->getExtensions().disjointTimerQuery && - !context->getExtensions().occlusionQueryBoolean) + !context->getExtensions().occlusionQueryBoolean && !context->getExtensions().syncQuery) { - context->recordError(Error(GL_INVALID_OPERATION, "Query extension not enabled")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); return false; } - return ValidateGetQueryObjectValueBase(context, id, pname); + return ValidateGetQueryObjectValueBase(context, id, pname, nullptr); +} + +bool ValidateGetQueryObjectuivRobustANGLE(Context *context, + GLuint id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params) +{ + if (!context->getExtensions().disjointTimerQuery && + !context->getExtensions().occlusionQueryBoolean && !context->getExtensions().syncQuery) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); + return false; + } + + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateGetQueryObjectValueBase(context, id, pname, length)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *length)) + { + return false; + } + + return true; } bool ValidateGetQueryObjecti64vEXT(Context *context, GLuint id, GLenum pname, GLint64 *params) { if (!context->getExtensions().disjointTimerQuery) { - context->recordError(Error(GL_INVALID_OPERATION, "Timer query extension not enabled")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); return false; } - return ValidateGetQueryObjectValueBase(context, id, pname); + return ValidateGetQueryObjectValueBase(context, id, pname, nullptr); +} + +bool ValidateGetQueryObjecti64vRobustANGLE(Context *context, + GLuint id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint64 *params) +{ + if (!context->getExtensions().disjointTimerQuery) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); + return false; + } + + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateGetQueryObjectValueBase(context, id, pname, length)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *length)) + { + return false; + } + + return true; } bool ValidateGetQueryObjectui64vEXT(Context *context, GLuint id, GLenum pname, GLuint64 *params) { if (!context->getExtensions().disjointTimerQuery) { - context->recordError(Error(GL_INVALID_OPERATION, "Timer query extension not enabled")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); return false; } - return ValidateGetQueryObjectValueBase(context, id, pname); + return ValidateGetQueryObjectValueBase(context, id, pname, nullptr); } -static bool ValidateUniformCommonBase(gl::Context *context, - GLenum targetUniformType, - GLint location, - GLsizei count, - const LinkedUniform **uniformOut) +bool ValidateGetQueryObjectui64vRobustANGLE(Context *context, + GLuint id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint64 *params) { - if (count < 0) + if (!context->getExtensions().disjointTimerQuery) { - context->recordError(Error(GL_INVALID_VALUE)); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); + return false; + } + + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateGetQueryObjectValueBase(context, id, pname, length)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *length)) + { + return false; + } + + return true; +} + +bool ValidateUniformCommonBase(ValidationContext *context, + gl::Program *program, + GLint location, + GLsizei count, + const LinkedUniform **uniformOut) +{ + // TODO(Jiajia): Add image uniform check in future. + if (count < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount); return false; } - gl::Program *program = context->getState().getProgram(); if (!program) { - context->recordError(Error(GL_INVALID_OPERATION)); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidProgramName); + return false; + } + + if (!program->isLinked()) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked); return false; } @@ -1416,18 +2011,33 @@ static bool ValidateUniformCommonBase(gl::Context *context, return false; } - if (!program->isValidUniformLocation(location)) + const auto &uniformLocations = program->getUniformLocations(); + size_t castedLocation = static_cast(location); + if (castedLocation >= uniformLocations.size()) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation() << "Invalid uniform location"); return false; } - const LinkedUniform &uniform = program->getUniformByLocation(location); + const auto &uniformLocation = uniformLocations[castedLocation]; + if (uniformLocation.ignored) + { + // Silently ignore the uniform command + return false; + } + + if (!uniformLocation.used()) + { + context->handleError(InvalidOperation()); + return false; + } + + const auto &uniform = program->getUniformByIndex(uniformLocation.index); // attempting to write an array to a non-array uniform is an INVALID_OPERATION if (!uniform.isArray() && count > 1) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } @@ -1435,70 +2045,108 @@ static bool ValidateUniformCommonBase(gl::Context *context, return true; } -bool ValidateUniform(gl::Context *context, GLenum uniformType, GLint location, GLsizei count) +bool ValidateUniform1ivValue(ValidationContext *context, + GLenum uniformType, + GLsizei count, + const GLint *value) { - // Check for ES3 uniform entry points - if (VariableComponentType(uniformType) == GL_UNSIGNED_INT && context->getClientVersion() < 3) + // Value type is GL_INT, because we only get here from glUniform1i{v}. + // It is compatible with INT or BOOL. + // Do these cheap tests first, for a little extra speed. + if (GL_INT == uniformType || GL_BOOL == uniformType) { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; + return true; } - const LinkedUniform *uniform = nullptr; - if (!ValidateUniformCommonBase(context, uniformType, location, count, &uniform)) + if (IsSamplerType(uniformType)) { - return false; + // Check that the values are in range. + const GLint max = context->getCaps().maxCombinedTextureImageUnits; + for (GLsizei i = 0; i < count; ++i) + { + if (value[i] < 0 || value[i] >= max) + { + context->handleError(InvalidValue() << "sampler uniform value out of range"); + return false; + } + } + return true; } - GLenum targetBoolType = VariableBoolVectorType(uniformType); - bool samplerUniformCheck = (IsSamplerType(uniform->type) && uniformType == GL_INT); - if (!samplerUniformCheck && uniformType != uniform->type && targetBoolType != uniform->type) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - - return true; + context->handleError(InvalidOperation() << "wrong type of value for uniform"); + return false; } -bool ValidateUniformMatrix(gl::Context *context, GLenum matrixType, GLint location, GLsizei count, +bool ValidateUniformValue(ValidationContext *context, GLenum valueType, GLenum uniformType) +{ + // Check that the value type is compatible with uniform type. + // Do the cheaper test first, for a little extra speed. + if (valueType == uniformType || VariableBoolVectorType(valueType) == uniformType) + { + return true; + } + + ANGLE_VALIDATION_ERR(context, InvalidOperation(), UniformSizeMismatch); + return false; +} + +bool ValidateUniformMatrixValue(ValidationContext *context, GLenum valueType, GLenum uniformType) +{ + // Check that the value type is compatible with uniform type. + if (valueType == uniformType) + { + return true; + } + + context->handleError(InvalidOperation() << "wrong type of value for uniform"); + return false; +} + +bool ValidateUniform(ValidationContext *context, GLenum valueType, GLint location, GLsizei count) +{ + const LinkedUniform *uniform = nullptr; + gl::Program *programObject = context->getGLState().getProgram(); + return ValidateUniformCommonBase(context, programObject, location, count, &uniform) && + ValidateUniformValue(context, valueType, uniform->type); +} + +bool ValidateUniform1iv(ValidationContext *context, + GLint location, + GLsizei count, + const GLint *value) +{ + const LinkedUniform *uniform = nullptr; + gl::Program *programObject = context->getGLState().getProgram(); + return ValidateUniformCommonBase(context, programObject, location, count, &uniform) && + ValidateUniform1ivValue(context, uniform->type, count, value); +} + +bool ValidateUniformMatrix(ValidationContext *context, + GLenum valueType, + GLint location, + GLsizei count, GLboolean transpose) { - // Check for ES3 uniform entry points - int rows = VariableRowCount(matrixType); - int cols = VariableColumnCount(matrixType); - if (rows != cols && context->getClientVersion() < 3) + if (ConvertToBool(transpose) && context->getClientMajorVersion() < 3) { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - - if (transpose != GL_FALSE && context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } const LinkedUniform *uniform = nullptr; - if (!ValidateUniformCommonBase(context, matrixType, location, count, &uniform)) - { - return false; - } - - if (uniform->type != matrixType) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - - return true; + gl::Program *programObject = context->getGLState().getProgram(); + return ValidateUniformCommonBase(context, programObject, location, count, &uniform) && + ValidateUniformMatrixValue(context, valueType, uniform->type); } -bool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType, unsigned int *numParams) +bool ValidateStateQuery(ValidationContext *context, + GLenum pname, + GLenum *nativeType, + unsigned int *numParams) { if (!context->getQueryParameterInfo(pname, nativeType, numParams)) { - context->recordError(Error(GL_INVALID_ENUM)); + context->handleError(InvalidEnum()); return false; } @@ -1510,50 +2158,96 @@ bool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType, if (colorAttachment >= caps.maxDrawBuffers) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } } switch (pname) { - case GL_TEXTURE_BINDING_2D: - case GL_TEXTURE_BINDING_CUBE_MAP: - case GL_TEXTURE_BINDING_3D: - case GL_TEXTURE_BINDING_2D_ARRAY: - if (context->getState().getActiveSampler() >= caps.maxCombinedTextureImageUnits) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - break; - - case GL_IMPLEMENTATION_COLOR_READ_TYPE: - case GL_IMPLEMENTATION_COLOR_READ_FORMAT: - { - Framebuffer *framebuffer = context->getState().getReadFramebuffer(); - ASSERT(framebuffer); - if (framebuffer->checkStatus(context->getData()) != GL_FRAMEBUFFER_COMPLETE) + case GL_TEXTURE_BINDING_2D: + case GL_TEXTURE_BINDING_CUBE_MAP: + case GL_TEXTURE_BINDING_3D: + case GL_TEXTURE_BINDING_2D_ARRAY: + case GL_TEXTURE_BINDING_2D_MULTISAMPLE: + break; + case GL_TEXTURE_BINDING_RECTANGLE_ANGLE: + if (!context->getExtensions().textureRectangle) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidEnum() + << "ANGLE_texture_rectangle extension not present"); + return false; + } + break; + case GL_TEXTURE_BINDING_EXTERNAL_OES: + if (!context->getExtensions().eglStreamConsumerExternal && + !context->getExtensions().eglImageExternal) + { + context->handleError(InvalidEnum() << "Neither NV_EGL_stream_consumer_external " + "nor GL_OES_EGL_image_external " + "extensions enabled"); + return false; + } + break; + + case GL_IMPLEMENTATION_COLOR_READ_TYPE: + case GL_IMPLEMENTATION_COLOR_READ_FORMAT: + { + if (context->getGLState().getReadFramebuffer()->checkStatus(context) != + GL_FRAMEBUFFER_COMPLETE) + { + context->handleError(InvalidOperation()); + return false; + } + + const Framebuffer *framebuffer = context->getGLState().getReadFramebuffer(); + ASSERT(framebuffer); + + if (framebuffer->getReadBufferState() == GL_NONE) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ReadBufferNone); return false; } const FramebufferAttachment *attachment = framebuffer->getReadColorbuffer(); if (!attachment) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } } break; - default: - break; + default: + break; } // pname is valid, but there are no parameters to return - if (numParams == 0) + if (*numParams == 0) + { + return false; + } + + return true; +} + +bool ValidateRobustStateQuery(ValidationContext *context, + GLenum pname, + GLsizei bufSize, + GLenum *nativeType, + unsigned int *numParams) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateStateQuery(context, pname, nativeType, numParams)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *numParams)) { return false; } @@ -1574,43 +2268,78 @@ bool ValidateCopyTexImageParametersBase(ValidationContext *context, GLsizei width, GLsizei height, GLint border, - GLenum *textureFormatOut) + Format *textureFormatOut) { - if (level < 0 || xoffset < 0 || yoffset < 0 || zoffset < 0 || width < 0 || height < 0) + if (xoffset < 0 || yoffset < 0 || zoffset < 0) { - context->recordError(Error(GL_INVALID_VALUE)); + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset); return false; } - if (std::numeric_limits::max() - xoffset < width || std::numeric_limits::max() - yoffset < height) + if (width < 0 || height < 0) { - context->recordError(Error(GL_INVALID_VALUE)); + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize); + return false; + } + + if (std::numeric_limits::max() - xoffset < width || + std::numeric_limits::max() - yoffset < height) + { + context->handleError(InvalidValue()); return false; } if (border != 0) { - context->recordError(Error(GL_INVALID_VALUE)); + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder); return false; } if (!ValidMipLevel(context, target, level)) { - context->recordError(Error(GL_INVALID_VALUE)); + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel); return false; } - const gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer(); - if (framebuffer->checkStatus(context->getData()) != GL_FRAMEBUFFER_COMPLETE) + const auto &state = context->getGLState(); + Framebuffer *readFramebuffer = state.getReadFramebuffer(); + if (readFramebuffer->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE) { - context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION)); + context->handleError(InvalidFramebufferOperation()); return false; } - const auto &state = context->getState(); - if (state.getReadFramebuffer()->id() != 0 && framebuffer->getSamples(context->getData()) != 0) + if (readFramebuffer->id() != 0 && readFramebuffer->getSamples(context) != 0) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); + return false; + } + + if (readFramebuffer->getReadBufferState() == GL_NONE) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ReadBufferNone); + return false; + } + + // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment + // In OpenGL ES it is undefined what happens when an operation tries to read from a missing + // attachment and WebGL defines it to be an error. We do the check unconditionally as the + // situation is an application error that would lead to a crash in ANGLE. + const FramebufferAttachment *source = readFramebuffer->getReadColorbuffer(); + if (source == nullptr) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), MissingReadAttachment); + return false; + } + + // ANGLE_multiview spec, Revision 1: + // Calling CopyTexSubImage3D, CopyTexImage2D, or CopyTexSubImage2D will result in an + // INVALID_FRAMEBUFFER_OPERATION error if the multi-view layout of the current read framebuffer + // is not NONE. + if (source->getMultiviewLayout() != GL_NONE) + { + context->handleError(InvalidFramebufferOperation() + << "The active read framebuffer object has multiview attachments."); return false; } @@ -1619,57 +2348,57 @@ bool ValidateCopyTexImageParametersBase(ValidationContext *context, GLuint maxDimension = 0; switch (target) { - case GL_TEXTURE_2D: - maxDimension = caps.max2DTextureSize; - break; + case GL_TEXTURE_2D: + maxDimension = caps.max2DTextureSize; + break; - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - maxDimension = caps.maxCubeMapTextureSize; - break; + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + maxDimension = caps.maxCubeMapTextureSize; + break; - case GL_TEXTURE_2D_ARRAY: - maxDimension = caps.max2DTextureSize; - break; + case GL_TEXTURE_RECTANGLE_ANGLE: + maxDimension = caps.maxRectangleTextureSize; + break; - case GL_TEXTURE_3D: - maxDimension = caps.max3DTextureSize; - break; + case GL_TEXTURE_2D_ARRAY: + maxDimension = caps.max2DTextureSize; + break; - default: - context->recordError(Error(GL_INVALID_ENUM)); - return false; + case GL_TEXTURE_3D: + maxDimension = caps.max3DTextureSize; + break; + + default: + context->handleError(InvalidEnum()); + return false; } gl::Texture *texture = state.getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); if (!texture) { - context->recordError(Error(GL_INVALID_OPERATION)); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound); return false; } if (texture->getImmutableFormat() && !isSubImage) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat); + const gl::InternalFormat &formatInfo = + isSubImage ? *texture->getFormat(target, level).info + : gl::GetInternalFormatInfo(internalformat, GL_UNSIGNED_BYTE); - if (formatInfo.depthBits > 0) + if (formatInfo.depthBits > 0 || formatInfo.compressed) { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - - if (formatInfo.compressed && !ValidCompressedImageSize(context, internalformat, width, height)) - { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } @@ -1679,7 +2408,7 @@ bool ValidateCopyTexImageParametersBase(ValidationContext *context, static_cast(yoffset + height) > texture->getHeight(target, level) || static_cast(zoffset) >= texture->getDepth(target, level)) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } } @@ -1687,118 +2416,193 @@ bool ValidateCopyTexImageParametersBase(ValidationContext *context, { if (IsCubeMapTextureTarget(target) && width != height) { - context->recordError(Error(GL_INVALID_VALUE)); + ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapIncomplete); return false; } if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions())) { - context->recordError(Error(GL_INVALID_ENUM)); + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); return false; } int maxLevelDimension = (maxDimension >> level); - if (static_cast(width) > maxLevelDimension || static_cast(height) > maxLevelDimension) + if (static_cast(width) > maxLevelDimension || + static_cast(height) > maxLevelDimension) { - context->recordError(Error(GL_INVALID_VALUE)); + ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize); + return false; + } + } + + if (textureFormatOut) + { + *textureFormatOut = texture->getFormat(target, level); + } + + // Detect texture copying feedback loops for WebGL. + if (context->getExtensions().webglCompatibility) + { + if (readFramebuffer->formsCopyingFeedbackLoopWith(texture->id(), level, zoffset)) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), FeedbackLoop); return false; } } - *textureFormatOut = texture->getInternalFormat(target, level); return true; } -static bool ValidateDrawBase(ValidationContext *context, - GLenum mode, - GLsizei count, - GLsizei primcount) +bool ValidateDrawBase(ValidationContext *context, GLenum mode, GLsizei count) { switch (mode) { - case GL_POINTS: - case GL_LINES: - case GL_LINE_LOOP: - case GL_LINE_STRIP: - case GL_TRIANGLES: - case GL_TRIANGLE_STRIP: - case GL_TRIANGLE_FAN: - break; - default: - context->recordError(Error(GL_INVALID_ENUM)); - return false; + case GL_POINTS: + case GL_LINES: + case GL_LINE_LOOP: + case GL_LINE_STRIP: + case GL_TRIANGLES: + case GL_TRIANGLE_STRIP: + case GL_TRIANGLE_FAN: + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDrawMode); + return false; } if (count < 0) { - context->recordError(Error(GL_INVALID_VALUE)); + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount); return false; } - const State &state = context->getState(); + const State &state = context->getGLState(); - // Check for mapped buffers - if (state.hasMappedBuffer(GL_ARRAY_BUFFER)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } + const Extensions &extensions = context->getExtensions(); - if (context->getLimitations().noSeparateStencilRefsAndMasks) + // WebGL buffers cannot be mapped/unmapped because the MapBufferRange, FlushMappedBufferRange, + // and UnmapBuffer entry points are removed from the WebGL 2.0 API. + // https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.14 + if (!extensions.webglCompatibility) { - const Framebuffer *framebuffer = context->getState().getDrawFramebuffer(); - const FramebufferAttachment *stencilBuffer = framebuffer->getStencilbuffer(); - GLuint stencilBits = stencilBuffer ? stencilBuffer->getStencilSize() : 0; - GLuint minimumRequiredStencilMask = (1 << stencilBits) - 1; - const DepthStencilState &depthStencilState = state.getDepthStencilState(); - if ((depthStencilState.stencilWritemask & minimumRequiredStencilMask) != - (depthStencilState.stencilBackWritemask & minimumRequiredStencilMask) || - state.getStencilRef() != state.getStencilBackRef() || - (depthStencilState.stencilMask & minimumRequiredStencilMask) != - (depthStencilState.stencilBackMask & minimumRequiredStencilMask)) + // Check for mapped buffers + // TODO(jmadill): Optimize this check for non - WebGL contexts. + if (state.hasMappedBuffer(BufferBinding::Array)) { - // Note: these separate values are not supported in WebGL, due to D3D's limitations. See - // Section 6.10 of the WebGL 1.0 spec - ERR( - "This ANGLE implementation does not support separate front/back stencil " - "writemasks, reference values, or stencil mask values."); - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } } - const gl::Framebuffer *fbo = state.getDrawFramebuffer(); - if (!fbo || fbo->checkStatus(context->getData()) != GL_FRAMEBUFFER_COMPLETE) + // Note: these separate values are not supported in WebGL, due to D3D's limitations. See + // Section 6.10 of the WebGL 1.0 spec. + Framebuffer *framebuffer = state.getDrawFramebuffer(); + if (context->getLimitations().noSeparateStencilRefsAndMasks || extensions.webglCompatibility) { - context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION)); + const FramebufferAttachment *dsAttachment = + framebuffer->getStencilOrDepthStencilAttachment(); + GLuint stencilBits = dsAttachment ? dsAttachment->getStencilSize() : 0; + GLuint minimumRequiredStencilMask = (1 << stencilBits) - 1; + const DepthStencilState &depthStencilState = state.getDepthStencilState(); + + bool differentRefs = state.getStencilRef() != state.getStencilBackRef(); + bool differentWritemasks = + (depthStencilState.stencilWritemask & minimumRequiredStencilMask) != + (depthStencilState.stencilBackWritemask & minimumRequiredStencilMask); + bool differentMasks = (depthStencilState.stencilMask & minimumRequiredStencilMask) != + (depthStencilState.stencilBackMask & minimumRequiredStencilMask); + + if (differentRefs || differentWritemasks || differentMasks) + { + if (!extensions.webglCompatibility) + { + ERR() << "This ANGLE implementation does not support separate front/back stencil " + "writemasks, reference values, or stencil mask values."; + } + ANGLE_VALIDATION_ERR(context, InvalidOperation(), StencilReferenceMaskOrMismatch); + return false; + } + } + + if (framebuffer->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE) + { + context->handleError(InvalidFramebufferOperation()); return false; } gl::Program *program = state.getProgram(); if (!program) { - context->recordError(Error(GL_INVALID_OPERATION)); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound); return false; } - if (!program->validateSamplers(NULL, context->getCaps())) + // In OpenGL ES spec for UseProgram at section 7.3, trying to render without + // vertex shader stage or fragment shader stage is a undefined behaviour. + // But ANGLE should clearly generate an INVALID_OPERATION error instead of + // produce undefined result. + if (program->isLinked() && + (!program->hasLinkedVertexShader() || !program->hasLinkedFragmentShader())) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation() << "It is a undefined behaviour to render without " + "vertex shader stage or fragment shader stage."); return false; } + if (!program->validateSamplers(nullptr, context->getCaps())) + { + context->handleError(InvalidOperation()); + return false; + } + + if (extensions.multiview) + { + const int programNumViews = program->usesMultiview() ? program->getNumViews() : 1; + const int framebufferNumViews = framebuffer->getNumViews(); + if (framebufferNumViews != programNumViews) + { + context->handleError(InvalidOperation() << "The number of views in the active program " + "and draw framebuffer does not match."); + return false; + } + + const TransformFeedback *transformFeedbackObject = state.getCurrentTransformFeedback(); + if (transformFeedbackObject != nullptr && transformFeedbackObject->isActive() && + framebufferNumViews > 1) + { + context->handleError(InvalidOperation() + << "There is an active transform feedback object " + "when the number of views in the active draw " + "framebuffer is greater than 1."); + return false; + } + + if (extensions.disjointTimerQuery && framebufferNumViews > 1 && + state.isQueryActive(GL_TIME_ELAPSED_EXT)) + { + context->handleError(InvalidOperation() << "There is an active query for target " + "GL_TIME_ELAPSED_EXT when the number of " + "views in the active draw framebuffer is " + "greater than 1."); + return false; + } + } + // Uniform buffer validation - for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < program->getActiveUniformBlockCount(); uniformBlockIndex++) + for (unsigned int uniformBlockIndex = 0; + uniformBlockIndex < program->getActiveUniformBlockCount(); uniformBlockIndex++) { - const gl::UniformBlock &uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex); - GLuint blockBinding = program->getUniformBlockBinding(uniformBlockIndex); + const gl::InterfaceBlock &uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex); + GLuint blockBinding = program->getUniformBlockBinding(uniformBlockIndex); const OffsetBindingPointer &uniformBuffer = state.getIndexedUniformBuffer(blockBinding); if (uniformBuffer.get() == nullptr) { // undefined behaviour - context->recordError(Error(GL_INVALID_OPERATION, "It is undefined behaviour to have a used but unbound uniform buffer.")); + context->handleError( + InvalidOperation() + << "It is undefined behaviour to have a used but unbound uniform buffer."); return false; } @@ -1812,7 +2616,32 @@ static bool ValidateDrawBase(ValidationContext *context, if (uniformBufferSize < uniformBlock.dataSize) { // undefined behaviour - context->recordError(Error(GL_INVALID_OPERATION, "It is undefined behaviour to use a uniform buffer that is too small.")); + context->handleError( + InvalidOperation() + << "It is undefined behaviour to use a uniform buffer that is too small."); + return false; + } + } + + // Do some additonal WebGL-specific validation + if (extensions.webglCompatibility) + { + // Detect rendering feedback loops for WebGL. + if (framebuffer->formsRenderingFeedbackLoopWith(state)) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), FeedbackLoop); + return false; + } + + // Detect that the vertex shader input types match the attribute types + if (!ValidateVertexShaderAttributeTypeMatch(context)) + { + return false; + } + + // Detect that the color buffer types match the fragment shader output types + if (!ValidateFragmentShaderColorBufferTypeMatch(context)) + { return false; } } @@ -1821,32 +2650,49 @@ static bool ValidateDrawBase(ValidationContext *context, return (count > 0); } -bool ValidateDrawArrays(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount) +bool ValidateDrawArraysCommon(ValidationContext *context, + GLenum mode, + GLint first, + GLsizei count, + GLsizei primcount) { if (first < 0) { - context->recordError(Error(GL_INVALID_VALUE)); + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStart); return false; } - const State &state = context->getState(); + const State &state = context->getGLState(); gl::TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback(); - if (curTransformFeedback && curTransformFeedback->isActive() && !curTransformFeedback->isPaused() && - curTransformFeedback->getPrimitiveMode() != mode) + if (curTransformFeedback && curTransformFeedback->isActive() && + !curTransformFeedback->isPaused() && curTransformFeedback->getPrimitiveMode() != mode) { // It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode - // that does not match the current transform feedback object's draw mode (if transform feedback + // that does not match the current transform feedback object's draw mode (if transform + // feedback // is active), (3.0.2, section 2.14, pg 86) - context->recordError(Error(GL_INVALID_OPERATION)); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDrawModeTransformFeedback); return false; } - if (!ValidateDrawBase(context, mode, count, primcount)) + if (!ValidateDrawBase(context, mode, count)) { return false; } - if (!ValidateDrawAttribs(context, primcount, count)) + // Check the computation of maxVertex doesn't overflow. + // - first < 0 or count < 0 have been checked as an error condition + // - count > 0 has been checked in ValidateDrawBase as it makes the call a noop + // From this we know maxVertex will be positive, and only need to check if it overflows GLint. + ASSERT(count > 0 && first >= 0); + int64_t maxVertex = static_cast(first) + static_cast(count) - 1; + if (maxVertex > static_cast(std::numeric_limits::max())) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow); + return false; + } + + if (!ValidateDrawAttribs(context, primcount, static_cast(maxVertex), count)) { return false; } @@ -1854,223 +2700,264 @@ bool ValidateDrawArrays(Context *context, GLenum mode, GLint first, GLsizei coun return true; } -bool ValidateDrawArraysInstanced(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount) +bool ValidateDrawArraysInstancedANGLE(Context *context, + GLenum mode, + GLint first, + GLsizei count, + GLsizei primcount) { - if (primcount < 0) + if (!context->getExtensions().instancedArrays) { - context->recordError(Error(GL_INVALID_VALUE)); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); return false; } - if (!ValidateDrawArrays(context, mode, first, count, primcount)) + if (!ValidateDrawArraysInstancedBase(context, mode, first, count, primcount)) { return false; } - // No-op if zero primitive count - return (primcount > 0); + return ValidateDrawInstancedANGLE(context); } -static bool ValidateDrawInstancedANGLE(Context *context) -{ - // Verify there is at least one active attribute with a divisor of zero - const gl::State& state = context->getState(); - - gl::Program *program = state.getProgram(); - - const VertexArray *vao = state.getVertexArray(); - for (size_t attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) - { - const VertexAttribute &attrib = vao->getVertexAttribute(attributeIndex); - if (program->isAttribLocationActive(attributeIndex) && attrib.divisor == 0) - { - return true; - } - } - - context->recordError(Error(GL_INVALID_OPERATION, "ANGLE_instanced_arrays requires that at least one active attribute" - "has a divisor of zero.")); - return false; -} - -bool ValidateDrawArraysInstancedANGLE(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount) -{ - if (!ValidateDrawInstancedANGLE(context)) - { - return false; - } - - return ValidateDrawArraysInstanced(context, mode, first, count, primcount); -} - -bool ValidateDrawElements(ValidationContext *context, - GLenum mode, - GLsizei count, - GLenum type, - const GLvoid *indices, - GLsizei primcount, - IndexRange *indexRangeOut) +bool ValidateDrawElementsBase(ValidationContext *context, GLenum type) { switch (type) { - case GL_UNSIGNED_BYTE: - case GL_UNSIGNED_SHORT: - break; - case GL_UNSIGNED_INT: - if (context->getClientVersion() < 3 && !context->getExtensions().elementIndexUint) - { - context->recordError(Error(GL_INVALID_ENUM)); + case GL_UNSIGNED_BYTE: + case GL_UNSIGNED_SHORT: + break; + case GL_UNSIGNED_INT: + if (context->getClientMajorVersion() < 3 && !context->getExtensions().elementIndexUint) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), TypeNotUnsignedShortByte); + return false; + } + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), TypeNotUnsignedShortByte); return false; - } - break; - default: - context->recordError(Error(GL_INVALID_ENUM)); - return false; } - const State &state = context->getState(); + const State &state = context->getGLState(); gl::TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback(); - if (curTransformFeedback && curTransformFeedback->isActive() && !curTransformFeedback->isPaused()) + if (curTransformFeedback && curTransformFeedback->isActive() && + !curTransformFeedback->isPaused()) { - // It is an invalid operation to call DrawElements, DrawRangeElements or DrawElementsInstanced + // It is an invalid operation to call DrawElements, DrawRangeElements or + // DrawElementsInstanced // while transform feedback is active, (3.0.2, section 2.14, pg 86) - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } - // Check for mapped buffers - if (state.hasMappedBuffer(GL_ELEMENT_ARRAY_BUFFER)) + return true; +} + +bool ValidateDrawElementsCommon(ValidationContext *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei primcount) +{ + if (!ValidateDrawElementsBase(context, type)) + return false; + + const State &state = context->getGLState(); + + if (!ValidateDrawBase(context, mode, count)) { - context->recordError(Error(GL_INVALID_OPERATION)); return false; } - const gl::VertexArray *vao = state.getVertexArray(); + // WebGL buffers cannot be mapped/unmapped because the MapBufferRange, FlushMappedBufferRange, + // and UnmapBuffer entry points are removed from the WebGL 2.0 API. + // https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.14 + if (!context->getExtensions().webglCompatibility) + { + // Check for mapped buffers + // TODO(jmadill): Optimize this check for non - WebGL contexts. + if (state.hasMappedBuffer(gl::BufferBinding::ElementArray)) + { + context->handleError(InvalidOperation() << "Index buffer is mapped."); + return false; + } + } + + const gl::VertexArray *vao = state.getVertexArray(); gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get(); - if (!indices && !elementArrayBuffer) + + GLuint typeBytes = gl::GetTypeInfo(type).bytes; + + if (context->getExtensions().webglCompatibility) { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - - if (elementArrayBuffer) - { - const gl::Type &typeInfo = gl::GetTypeInfo(type); - - GLint64 offset = reinterpret_cast(indices); - GLint64 byteCount = static_cast(typeInfo.bytes) * static_cast(count)+offset; - - // check for integer overflows - if (static_cast(count) > (std::numeric_limits::max() / typeInfo.bytes) || - byteCount > static_cast(std::numeric_limits::max())) + ASSERT(isPow2(typeBytes) && typeBytes > 0); + if ((reinterpret_cast(indices) & static_cast(typeBytes - 1)) != 0) { - context->recordError(Error(GL_OUT_OF_MEMORY)); + // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements + // The offset arguments to drawElements and [...], must be a multiple of the size of the + // data type passed to the call, or an INVALID_OPERATION error is generated. + ANGLE_VALIDATION_ERR(context, InvalidOperation(), OffsetMustBeMultipleOfType); return false; } - // Check for reading past the end of the bound buffer object - if (byteCount > elementArrayBuffer->getSize()) + // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements + // In addition the offset argument to drawElements must be non-negative or an INVALID_VALUE + // error is generated. + if (reinterpret_cast(indices) < 0) { - context->recordError(Error(GL_INVALID_OPERATION)); + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset); return false; } } - else if (!indices) - { - // Catch this programming error here - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - if (!ValidateDrawBase(context, mode, count, primcount)) + if (context->getExtensions().webglCompatibility || + !context->getGLState().areClientArraysEnabled()) { - return false; - } - - // Use max index to validate if our vertex buffers are large enough for the pull. - // TODO: offer fast path, with disabled index validation. - // TODO: also disable index checking on back-ends that are robust to out-of-range accesses. - if (elementArrayBuffer) - { - uintptr_t offset = reinterpret_cast(indices); - Error error = - elementArrayBuffer->getIndexRange(type, static_cast(offset), count, - state.isPrimitiveRestartEnabled(), indexRangeOut); - if (error.isError()) + if (!elementArrayBuffer && count > 0) + { + // [WebGL 1.0] Section 6.2 No Client Side Arrays + // If drawElements is called with a count greater than zero, and no WebGLBuffer is bound + // to the ELEMENT_ARRAY_BUFFER binding point, an INVALID_OPERATION error is generated. + ANGLE_VALIDATION_ERR(context, InvalidOperation(), MustHaveElementArrayBinding); + return false; + } + } + + if (count > 0) + { + if (elementArrayBuffer) + { + // The max possible type size is 8 and count is on 32 bits so doing the multiplication + // in a 64 bit integer is safe. Also we are guaranteed that here count > 0. + static_assert(std::is_same::value, "GLsizei isn't the expected type"); + constexpr uint64_t kMaxTypeSize = 8; + constexpr uint64_t kIntMax = std::numeric_limits::max(); + constexpr uint64_t kUint64Max = std::numeric_limits::max(); + static_assert(kIntMax < kUint64Max / kMaxTypeSize, ""); + + uint64_t typeSize = typeBytes; + uint64_t elementCount = static_cast(count); + ASSERT(elementCount > 0 && typeSize <= kMaxTypeSize); + + // Doing the multiplication here is overflow-safe + uint64_t elementDataSizeNoOffset = typeSize * elementCount; + + // The offset can be any value, check for overflows + uint64_t offset = static_cast(reinterpret_cast(indices)); + if (elementDataSizeNoOffset > kUint64Max - offset) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow); + return false; + } + + uint64_t elementDataSizeWithOffset = elementDataSizeNoOffset + offset; + if (elementDataSizeWithOffset > static_cast(elementArrayBuffer->getSize())) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize); + return false; + } + + ASSERT(isPow2(typeSize) && typeSize > 0); + if ((elementArrayBuffer->getSize() & (typeSize - 1)) != 0) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedByteCountType); + return false; + } + } + else if (!indices) + { + // This is an application error that would normally result in a crash, + // but we catch it and return an error + context->handleError(InvalidOperation() << "No element array buffer and no pointer."); + return false; + } + } + + if (context->getExtensions().robustBufferAccessBehavior) + { + // Here we use maxVertex = 0 and vertexCount = 1 to avoid retrieving IndexRange when robust + // access is enabled. + if (!ValidateDrawAttribs(context, primcount, 0, 1)) { - context->recordError(error); return false; } } else { - *indexRangeOut = ComputeIndexRange(type, indices, count, state.isPrimitiveRestartEnabled()); + // Use the parameter buffer to retrieve and cache the index range. + const auto ¶ms = context->getParams(); + const auto &indexRangeOpt = params.getIndexRange(); + if (!indexRangeOpt.valid()) + { + // Unexpected error. + return false; + } + + // If we use an index greater than our maximum supported index range, return an error. + // The ES3 spec does not specify behaviour here, it is undefined, but ANGLE should always + // return an error if possible here. + if (static_cast(indexRangeOpt.value().end) >= context->getCaps().maxElementIndex) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExceedsMaxElement); + return false; + } + + if (!ValidateDrawAttribs(context, primcount, static_cast(indexRangeOpt.value().end), + static_cast(indexRangeOpt.value().vertexCount()))) + { + return false; + } + + // No op if there are no real indices in the index data (all are primitive restart). + return (indexRangeOpt.value().vertexIndexCount > 0); } - // If we use an index greater than our maximum supported index range, return an error. - // The ES3 spec does not specify behaviour here, it is undefined, but ANGLE should always - // return an error if possible here. - if (static_cast(indexRangeOut->end) >= context->getCaps().maxElementIndex) - { - context->recordError(Error(GL_INVALID_OPERATION, g_ExceedsMaxElementErrorMessage)); - return false; - } - - if (!ValidateDrawAttribs(context, primcount, static_cast(indexRangeOut->end))) - { - return false; - } - - // No op if there are no real indices in the index data (all are primitive restart). - return (indexRangeOut->vertexIndexCount > 0); + return true; } -bool ValidateDrawElementsInstanced(Context *context, - GLenum mode, - GLsizei count, - GLenum type, - const GLvoid *indices, - GLsizei primcount, - IndexRange *indexRangeOut) +bool ValidateDrawElementsInstancedCommon(ValidationContext *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei primcount) { - if (primcount < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return false; - } - - if (!ValidateDrawElements(context, mode, count, type, indices, primcount, indexRangeOut)) - { - return false; - } - - // No-op zero primitive count - return (primcount > 0); + return ValidateDrawElementsInstancedBase(context, mode, count, type, indices, primcount); } bool ValidateDrawElementsInstancedANGLE(Context *context, GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, - GLsizei primcount, - IndexRange *indexRangeOut) + const void *indices, + GLsizei primcount) { - if (!ValidateDrawInstancedANGLE(context)) + if (!context->getExtensions().instancedArrays) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); + return false; + } + + if (!ValidateDrawElementsInstancedBase(context, mode, count, type, indices, primcount)) { return false; } - return ValidateDrawElementsInstanced(context, mode, count, type, indices, primcount, indexRangeOut); + return ValidateDrawInstancedANGLE(context); } -bool ValidateFramebufferTextureBase(Context *context, GLenum target, GLenum attachment, - GLuint texture, GLint level) +bool ValidateFramebufferTextureBase(Context *context, + GLenum target, + GLenum attachment, + GLuint texture, + GLint level) { - if (!ValidFramebufferTarget(target)) + if (!ValidFramebufferTarget(context, target)) { - context->recordError(Error(GL_INVALID_ENUM)); + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget); return false; } @@ -2085,109 +2972,34 @@ bool ValidateFramebufferTextureBase(Context *context, GLenum target, GLenum atta if (tex == NULL) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } if (level < 0) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } } - const gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); + const gl::Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target); ASSERT(framebuffer); if (framebuffer->id() == 0) { - context->recordError(Error(GL_INVALID_OPERATION, "Cannot change default FBO's attachments")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), DefaultFramebufferTarget); return false; } return true; } -bool ValidateFramebufferTexture2D(Context *context, GLenum target, GLenum attachment, - GLenum textarget, GLuint texture, GLint level) -{ - // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap extension - if (context->getClientVersion() < 3 && !context->getExtensions().fboRenderMipmap && level != 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return false; - } - - if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level)) - { - return false; - } - - if (texture != 0) - { - gl::Texture *tex = context->getTexture(texture); - ASSERT(tex); - - const gl::Caps &caps = context->getCaps(); - - switch (textarget) - { - case GL_TEXTURE_2D: - { - if (level > gl::log2(caps.max2DTextureSize)) - { - context->recordError(Error(GL_INVALID_VALUE)); - return false; - } - if (tex->getTarget() != GL_TEXTURE_2D) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - } - break; - - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - { - if (level > gl::log2(caps.maxCubeMapTextureSize)) - { - context->recordError(Error(GL_INVALID_VALUE)); - return false; - } - if (tex->getTarget() != GL_TEXTURE_CUBE_MAP) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - } - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - - const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(tex->getInternalFormat(textarget, level)); - if (internalFormatInfo.compressed) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - } - - return true; -} - bool ValidateGetUniformBase(Context *context, GLuint program, GLint location) { if (program == 0) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } @@ -2199,84 +3011,160 @@ bool ValidateGetUniformBase(Context *context, GLuint program, GLint location) if (!programObject || !programObject->isLinked()) { - context->recordError(Error(GL_INVALID_OPERATION)); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked); return false; } if (!programObject->isValidUniformLocation(location)) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } return true; } -bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat* params) +static bool ValidateSizedGetUniform(Context *context, + GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length) { - return ValidateGetUniformBase(context, program, location); -} + if (length) + { + *length = 0; + } -bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint* params) -{ - return ValidateGetUniformBase(context, program, location); -} - -static bool ValidateSizedGetUniform(Context *context, GLuint program, GLint location, GLsizei bufSize) -{ if (!ValidateGetUniformBase(context, program, location)) { return false; } + if (bufSize < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize); + return false; + } + gl::Program *programObject = context->getProgram(program); ASSERT(programObject); // sized queries -- ensure the provided buffer is large enough const LinkedUniform &uniform = programObject->getUniformByLocation(location); - size_t requiredBytes = VariableExternalSize(uniform.type); + size_t requiredBytes = VariableExternalSize(uniform.type); if (static_cast(bufSize) < requiredBytes) { - context->recordError(Error(GL_INVALID_OPERATION)); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize); return false; } + if (length) + { + *length = VariableComponentCount(uniform.type); + } + return true; } -bool ValidateGetnUniformfvEXT(Context *context, GLuint program, GLint location, GLsizei bufSize, GLfloat* params) +bool ValidateGetnUniformfvEXT(Context *context, + GLuint program, + GLint location, + GLsizei bufSize, + GLfloat *params) { - return ValidateSizedGetUniform(context, program, location, bufSize); + return ValidateSizedGetUniform(context, program, location, bufSize, nullptr); } -bool ValidateGetnUniformivEXT(Context *context, GLuint program, GLint location, GLsizei bufSize, GLint* params) +bool ValidateGetnUniformivEXT(Context *context, + GLuint program, + GLint location, + GLsizei bufSize, + GLint *params) { - return ValidateSizedGetUniform(context, program, location, bufSize); + return ValidateSizedGetUniform(context, program, location, bufSize, nullptr); } -bool ValidateDiscardFramebufferBase(Context *context, GLenum target, GLsizei numAttachments, - const GLenum *attachments, bool defaultFramebuffer) +bool ValidateGetUniformfvRobustANGLE(Context *context, + GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLfloat *params) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + // bufSize is validated in ValidateSizedGetUniform + return ValidateSizedGetUniform(context, program, location, bufSize, length); +} + +bool ValidateGetUniformivRobustANGLE(Context *context, + GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + // bufSize is validated in ValidateSizedGetUniform + return ValidateSizedGetUniform(context, program, location, bufSize, length); +} + +bool ValidateGetUniformuivRobustANGLE(Context *context, + GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLuint *params) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + // bufSize is validated in ValidateSizedGetUniform + return ValidateSizedGetUniform(context, program, location, bufSize, length); +} + +bool ValidateDiscardFramebufferBase(Context *context, + GLenum target, + GLsizei numAttachments, + const GLenum *attachments, + bool defaultFramebuffer) { if (numAttachments < 0) { - context->recordError(Error(GL_INVALID_VALUE, "numAttachments must not be less than zero")); + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeAttachments); return false; } for (GLsizei i = 0; i < numAttachments; ++i) { - if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT15) + if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT31) { if (defaultFramebuffer) { - context->recordError(Error(GL_INVALID_ENUM, "Invalid attachment when the default framebuffer is bound")); + ANGLE_VALIDATION_ERR(context, InvalidEnum(), DefaultFramebufferInvalidAttachment); return false; } if (attachments[i] >= GL_COLOR_ATTACHMENT0 + context->getCaps().maxColorAttachments) { - context->recordError(Error(GL_INVALID_OPERATION, - "Requested color attachment is greater than the maximum supported color attachments")); + context->handleError(InvalidOperation() << "Requested color attachment is " + "greater than the maximum supported " + "color attachments"); return false; } } @@ -2284,27 +3172,29 @@ bool ValidateDiscardFramebufferBase(Context *context, GLenum target, GLsizei num { switch (attachments[i]) { - case GL_DEPTH_ATTACHMENT: - case GL_STENCIL_ATTACHMENT: - case GL_DEPTH_STENCIL_ATTACHMENT: - if (defaultFramebuffer) - { - context->recordError(Error(GL_INVALID_ENUM, "Invalid attachment when the default framebuffer is bound")); + case GL_DEPTH_ATTACHMENT: + case GL_STENCIL_ATTACHMENT: + case GL_DEPTH_STENCIL_ATTACHMENT: + if (defaultFramebuffer) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), + DefaultFramebufferInvalidAttachment); + return false; + } + break; + case GL_COLOR: + case GL_DEPTH: + case GL_STENCIL: + if (!defaultFramebuffer) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), + DefaultFramebufferInvalidAttachment); + return false; + } + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment); return false; - } - break; - case GL_COLOR: - case GL_DEPTH: - case GL_STENCIL: - if (!defaultFramebuffer) - { - context->recordError(Error(GL_INVALID_ENUM, "Invalid attachment when the default framebuffer is not bound")); - return false; - } - break; - default: - context->recordError(Error(GL_INVALID_ENUM, "Invalid attachment")); - return false; } } } @@ -2347,44 +3237,58 @@ bool ValidatePushGroupMarkerEXT(Context *context, GLsizei length, const char *ma } bool ValidateEGLImageTargetTexture2DOES(Context *context, - egl::Display *display, GLenum target, egl::Image *image) { if (!context->getExtensions().eglImage && !context->getExtensions().eglImageExternal) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } switch (target) { case GL_TEXTURE_2D: + if (!context->getExtensions().eglImage) + { + context->handleError(InvalidEnum() + << "GL_TEXTURE_2D texture target requires GL_OES_EGL_image."); + } + break; + + case GL_TEXTURE_EXTERNAL_OES: + if (!context->getExtensions().eglImageExternal) + { + context->handleError(InvalidEnum() << "GL_TEXTURE_EXTERNAL_OES texture target " + "requires GL_OES_EGL_image_external."); + } break; default: - context->recordError(Error(GL_INVALID_ENUM, "invalid texture target.")); + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget); return false; } - if (!display->isValidImage(image)) + ASSERT(context->getCurrentDisplay()); + if (!context->getCurrentDisplay()->isValidImage(image)) { - context->recordError(Error(GL_INVALID_VALUE, "EGL image is not valid.")); + context->handleError(InvalidValue() << "EGL image is not valid."); return false; } if (image->getSamples() > 0) { - context->recordError(Error(GL_INVALID_OPERATION, - "cannot create a 2D texture from a multisampled EGL image.")); + context->handleError(InvalidOperation() + << "cannot create a 2D texture from a multisampled EGL image."); return false; } - const TextureCaps &textureCaps = context->getTextureCaps().get(image->getInternalFormat()); + const TextureCaps &textureCaps = + context->getTextureCaps().get(image->getFormat().info->sizedInternalFormat); if (!textureCaps.texturable) { - context->recordError(Error(GL_INVALID_OPERATION, - "EGL image internal format is not supported as a texture.")); + context->handleError(InvalidOperation() + << "EGL image internal format is not supported as a texture."); return false; } @@ -2392,13 +3296,12 @@ bool ValidateEGLImageTargetTexture2DOES(Context *context, } bool ValidateEGLImageTargetRenderbufferStorageOES(Context *context, - egl::Display *display, GLenum target, egl::Image *image) { if (!context->getExtensions().eglImage) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } @@ -2408,21 +3311,23 @@ bool ValidateEGLImageTargetRenderbufferStorageOES(Context *context, break; default: - context->recordError(Error(GL_INVALID_ENUM, "invalid renderbuffer target.")); + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget); return false; } - if (!display->isValidImage(image)) + ASSERT(context->getCurrentDisplay()); + if (!context->getCurrentDisplay()->isValidImage(image)) { - context->recordError(Error(GL_INVALID_VALUE, "EGL image is not valid.")); + context->handleError(InvalidValue() << "EGL image is not valid."); return false; } - const TextureCaps &textureCaps = context->getTextureCaps().get(image->getInternalFormat()); + const TextureCaps &textureCaps = + context->getTextureCaps().get(image->getFormat().info->sizedInternalFormat); if (!textureCaps.renderable) { - context->recordError(Error( - GL_INVALID_OPERATION, "EGL image internal format is not supported as a renderbuffer.")); + context->handleError(InvalidOperation() + << "EGL image internal format is not supported as a renderbuffer."); return false; } @@ -2435,29 +3340,7 @@ bool ValidateBindVertexArrayBase(Context *context, GLuint array) { // The default VAO should always exist ASSERT(array != 0); - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - - return true; -} - -bool ValidateDeleteVertexArraysBase(Context *context, GLsizei n) -{ - if (n < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return false; - } - - return true; -} - -bool ValidateGenVertexArraysBase(Context *context, GLsizei n) -{ - if (n < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidOperation()); return false; } @@ -2480,7 +3363,16 @@ bool ValidateProgramBinaryBase(Context *context, if (std::find(programBinaryFormats.begin(), programBinaryFormats.end(), binaryFormat) == programBinaryFormats.end()) { - context->recordError(Error(GL_INVALID_ENUM, "Program binary format is not valid.")); + context->handleError(InvalidEnum() << "Program binary format is not valid."); + return false; + } + + if (context->hasActiveTransformFeedback(program)) + { + // ES 3.0.4 section 2.15 page 91 + context->handleError(InvalidOperation() << "Cannot change program binary while program " + "is associated with an active transform " + "feedback object."); return false; } @@ -2502,63 +3394,35 @@ bool ValidateGetProgramBinaryBase(Context *context, if (!programObject->isLinked()) { - context->recordError(Error(GL_INVALID_OPERATION, "Program is not linked.")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked); + return false; + } + + if (context->getCaps().programBinaryFormats.empty()) + { + context->handleError(InvalidOperation() << "No program binary formats supported."); return false; } return true; } -bool ValidateCopyTexImage2D(ValidationContext *context, - GLenum target, - GLint level, - GLenum internalformat, - GLint x, - GLint y, - GLsizei width, - GLsizei height, - GLint border) -{ - if (context->getClientVersion() < 3) - { - return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0, - 0, x, y, width, height, border); - } - - ASSERT(context->getClientVersion() == 3); - return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0, - 0, x, y, width, height, border); -} - -bool ValidateFramebufferRenderbuffer(Context *context, - GLenum target, - GLenum attachment, - GLenum renderbuffertarget, - GLuint renderbuffer) -{ - if (!ValidFramebufferTarget(target) || - (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)) - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - - return ValidateFramebufferRenderbufferParameters(context, target, attachment, - renderbuffertarget, renderbuffer); -} - bool ValidateDrawBuffersBase(ValidationContext *context, GLsizei n, const GLenum *bufs) { // INVALID_VALUE is generated if n is negative or greater than value of MAX_DRAW_BUFFERS - if (n < 0 || static_cast(n) > context->getCaps().maxDrawBuffers) + if (n < 0) { - context->recordError( - Error(GL_INVALID_VALUE, "n must be non-negative and no greater than MAX_DRAW_BUFFERS")); + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount); + return false; + } + if (static_cast(n) > context->getCaps().maxDrawBuffers) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxDrawBuffer); return false; } - ASSERT(context->getState().getDrawFramebuffer()); - GLuint frameBufferId = context->getState().getDrawFramebuffer()->id(); + ASSERT(context->getGLState().getDrawFramebuffer()); + GLuint frameBufferId = context->getGLState().getDrawFramebuffer()->id(); GLuint maxColorAttachment = GL_COLOR_ATTACHMENT0_EXT + context->getCaps().maxColorAttachments; // This should come first before the check for the default frame buffer @@ -2569,13 +3433,21 @@ bool ValidateDrawBuffersBase(ValidationContext *context, GLsizei n, const GLenum const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment; if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != GL_BACK && - (bufs[colorAttachment] < GL_COLOR_ATTACHMENT0_EXT || - bufs[colorAttachment] >= maxColorAttachment)) + (bufs[colorAttachment] < GL_COLOR_ATTACHMENT0 || + bufs[colorAttachment] > GL_COLOR_ATTACHMENT31)) { // Value in bufs is not NONE, BACK, or GL_COLOR_ATTACHMENTi - // In the 3.0 specs, the error should return GL_INVALID_OPERATION. - // When we move to 3.1 specs, we should change the error to be GL_INVALID_ENUM - context->recordError(Error(GL_INVALID_OPERATION, "Invalid buffer value")); + // The 3.0.4 spec says to generate GL_INVALID_OPERATION here, but this + // was changed to GL_INVALID_ENUM in 3.1, which dEQP also expects. + // 3.1 is still a bit ambiguous about the error, but future specs are + // expected to clarify that GL_INVALID_ENUM is the correct error. + context->handleError(InvalidEnum() << "Invalid buffer value"); + return false; + } + else if (bufs[colorAttachment] >= maxColorAttachment) + { + context->handleError(InvalidOperation() + << "Buffer value is greater than MAX_DRAW_BUFFERS"); return false; } else if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment && @@ -2583,8 +3455,8 @@ bool ValidateDrawBuffersBase(ValidationContext *context, GLsizei n, const GLenum { // INVALID_OPERATION-GL is bound to buffer and ith argument // is not COLOR_ATTACHMENTi or NONE - context->recordError( - Error(GL_INVALID_OPERATION, "Ith value does not match COLOR_ATTACHMENTi or NONE")); + context->handleError(InvalidOperation() + << "Ith value does not match COLOR_ATTACHMENTi or NONE"); return false; } } @@ -2595,16 +3467,16 @@ bool ValidateDrawBuffersBase(ValidationContext *context, GLsizei n, const GLenum { if (n != 1) { - context->recordError(Error(GL_INVALID_OPERATION, - "n must be 1 when GL is bound to the default framebuffer")); + context->handleError(InvalidOperation() + << "n must be 1 when GL is bound to the default framebuffer"); return false; } if (bufs[0] != GL_NONE && bufs[0] != GL_BACK) { - context->recordError(Error( - GL_INVALID_OPERATION, - "Only NONE or BACK are valid values when drawing to the default framebuffer")); + context->handleError( + InvalidOperation() + << "Only NONE or BACK are valid values when drawing to the default framebuffer"); return false; } } @@ -2612,24 +3484,2345 @@ bool ValidateDrawBuffersBase(ValidationContext *context, GLsizei n, const GLenum return true; } -bool ValidateCopyTexSubImage2D(Context *context, - GLenum target, - GLint level, - GLint xoffset, - GLint yoffset, - GLint x, - GLint y, - GLsizei width, - GLsizei height) +bool ValidateGetBufferPointervBase(Context *context, + BufferBinding target, + GLenum pname, + GLsizei *length, + void **params) { - if (context->getClientVersion() < 3) + if (length) { - return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset, - yoffset, x, y, width, height, 0); + *length = 0; } - return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset, - yoffset, 0, x, y, width, height, 0); + if (context->getClientMajorVersion() < 3 && !context->getExtensions().mapBuffer) + { + context->handleError( + InvalidOperation() + << "Context does not support OpenGL ES 3.0 or GL_OES_mapbuffer is not enabled."); + return false; + } + + if (!ValidBufferType(context, target)) + { + context->handleError(InvalidEnum() << "Buffer target not valid"); + return false; + } + + switch (pname) + { + case GL_BUFFER_MAP_POINTER: + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + + // GLES 3.0 section 2.10.1: "Attempts to attempts to modify or query buffer object state for a + // target bound to zero generate an INVALID_OPERATION error." + // GLES 3.1 section 6.6 explicitly specifies this error. + if (context->getGLState().getTargetBuffer(target) == nullptr) + { + context->handleError(InvalidOperation() + << "Can not get pointer for reserved buffer name zero."); + return false; + } + + if (length) + { + *length = 1; + } + + return true; +} + +bool ValidateUnmapBufferBase(Context *context, BufferBinding target) +{ + if (!ValidBufferType(context, target)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes); + return false; + } + + Buffer *buffer = context->getGLState().getTargetBuffer(target); + + if (buffer == nullptr || !buffer->isMapped()) + { + context->handleError(InvalidOperation() << "Buffer not mapped."); + return false; + } + + return true; +} + +bool ValidateMapBufferRangeBase(Context *context, + BufferBinding target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access) +{ + if (!ValidBufferType(context, target)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes); + return false; + } + + if (offset < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset); + return false; + } + + if (length < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeLength); + return false; + } + + Buffer *buffer = context->getGLState().getTargetBuffer(target); + + if (!buffer) + { + context->handleError(InvalidOperation() << "Attempted to map buffer object zero."); + return false; + } + + // Check for buffer overflow + CheckedNumeric checkedOffset(offset); + auto checkedSize = checkedOffset + length; + + if (!checkedSize.IsValid() || checkedSize.ValueOrDie() > static_cast(buffer->getSize())) + { + context->handleError(InvalidValue() << "Mapped range does not fit into buffer dimensions."); + return false; + } + + // Check for invalid bits in the mask + GLbitfield allAccessBits = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | + GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | + GL_MAP_UNSYNCHRONIZED_BIT; + + if (access & ~(allAccessBits)) + { + context->handleError(InvalidValue() + << "Invalid access bits: 0x" << std::hex << std::uppercase << access); + return false; + } + + if (length == 0) + { + context->handleError(InvalidOperation() << "Buffer mapping length is zero."); + return false; + } + + if (buffer->isMapped()) + { + context->handleError(InvalidOperation() << "Buffer is already mapped."); + return false; + } + + // Check for invalid bit combinations + if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0) + { + context->handleError(InvalidOperation() + << "Need to map buffer for either reading or writing."); + return false; + } + + GLbitfield writeOnlyBits = + GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT; + + if ((access & GL_MAP_READ_BIT) != 0 && (access & writeOnlyBits) != 0) + { + context->handleError(InvalidOperation() + << "Invalid access bits when mapping buffer for reading: 0x" + << std::hex << std::uppercase << access); + return false; + } + + if ((access & GL_MAP_WRITE_BIT) == 0 && (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0) + { + context->handleError( + InvalidOperation() + << "The explicit flushing bit may only be set if the buffer is mapped for writing."); + return false; + } + + return ValidateMapBufferBase(context, target); +} + +bool ValidateFlushMappedBufferRangeBase(Context *context, + BufferBinding target, + GLintptr offset, + GLsizeiptr length) +{ + if (offset < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset); + return false; + } + + if (length < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeLength); + return false; + } + + if (!ValidBufferType(context, target)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes); + return false; + } + + Buffer *buffer = context->getGLState().getTargetBuffer(target); + + if (buffer == nullptr) + { + context->handleError(InvalidOperation() << "Attempted to flush buffer object zero."); + return false; + } + + if (!buffer->isMapped() || (buffer->getAccessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0) + { + context->handleError(InvalidOperation() + << "Attempted to flush a buffer not mapped for explicit flushing."); + return false; + } + + // Check for buffer overflow + CheckedNumeric checkedOffset(offset); + auto checkedSize = checkedOffset + length; + + if (!checkedSize.IsValid() || + checkedSize.ValueOrDie() > static_cast(buffer->getMapLength())) + { + context->handleError(InvalidValue() + << "Flushed range does not fit into buffer mapping dimensions."); + return false; + } + + return true; +} + +bool ValidateGenOrDelete(Context *context, GLint n) +{ + if (n < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount); + return false; + } + return true; +} + +bool ValidateRobustEntryPoint(ValidationContext *context, GLsizei bufSize) +{ + if (!context->getExtensions().robustClientMemory) + { + context->handleError(InvalidOperation() + << "GL_ANGLE_robust_client_memory is not available."); + return false; + } + + if (bufSize < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize); + return false; + } + + return true; +} + +bool ValidateRobustBufferSize(ValidationContext *context, GLsizei bufSize, GLsizei numParams) +{ + if (bufSize < numParams) + { + context->handleError(InvalidOperation() << numParams << " parameters are required but " + << bufSize << " were provided."); + return false; + } + + return true; +} + +bool ValidateGetFramebufferAttachmentParameterivBase(ValidationContext *context, + GLenum target, + GLenum attachment, + GLenum pname, + GLsizei *numParams) +{ + if (!ValidFramebufferTarget(context, target)) + { + context->handleError(InvalidEnum()); + return false; + } + + int clientVersion = context->getClientMajorVersion(); + + switch (pname) + { + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE: + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE: + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE: + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE: + if (clientVersion < 3 || !context->getExtensions().multiview) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + break; + + case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: + if (clientVersion < 3 && !context->getExtensions().sRGB) + { + context->handleError(InvalidEnum()); + return false; + } + break; + + case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE: + case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: + case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE: + case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE: + case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE: + case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: + case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER: + if (clientVersion < 3) + { + context->handleError(InvalidEnum()); + return false; + } + break; + + default: + context->handleError(InvalidEnum()); + return false; + } + + // Determine if the attachment is a valid enum + switch (attachment) + { + case GL_BACK: + case GL_DEPTH: + case GL_STENCIL: + if (clientVersion < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment); + return false; + } + break; + + case GL_DEPTH_STENCIL_ATTACHMENT: + if (clientVersion < 3 && !context->isWebGL1()) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment); + return false; + } + break; + + case GL_COLOR_ATTACHMENT0: + case GL_DEPTH_ATTACHMENT: + case GL_STENCIL_ATTACHMENT: + break; + + default: + if ((clientVersion < 3 && !context->getExtensions().drawBuffers) || + attachment < GL_COLOR_ATTACHMENT0_EXT || + (attachment - GL_COLOR_ATTACHMENT0_EXT) >= context->getCaps().maxColorAttachments) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment); + return false; + } + break; + } + + const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target); + ASSERT(framebuffer); + + if (framebuffer->id() == 0) + { + if (clientVersion < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), DefaultFramebufferTarget); + return false; + } + + switch (attachment) + { + case GL_BACK: + case GL_DEPTH: + case GL_STENCIL: + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidAttachment); + return false; + } + } + else + { + if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) + { + // Valid attachment query + } + else + { + switch (attachment) + { + case GL_DEPTH_ATTACHMENT: + case GL_STENCIL_ATTACHMENT: + break; + + case GL_DEPTH_STENCIL_ATTACHMENT: + if (!framebuffer->hasValidDepthStencil() && !context->isWebGL1()) + { + context->handleError(InvalidOperation()); + return false; + } + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidAttachment); + return false; + } + } + } + + const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(attachment); + if (attachmentObject) + { + ASSERT(attachmentObject->type() == GL_RENDERBUFFER || + attachmentObject->type() == GL_TEXTURE || + attachmentObject->type() == GL_FRAMEBUFFER_DEFAULT); + + switch (pname) + { + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: + if (attachmentObject->type() != GL_RENDERBUFFER && + attachmentObject->type() != GL_TEXTURE) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), FramebufferIncompleteAttachment); + return false; + } + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: + if (attachmentObject->type() != GL_TEXTURE) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), FramebufferIncompleteAttachment); + return false; + } + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: + if (attachmentObject->type() != GL_TEXTURE) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), FramebufferIncompleteAttachment); + return false; + } + break; + + case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: + if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidAttachment); + return false; + } + break; + + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER: + if (attachmentObject->type() != GL_TEXTURE) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), FramebufferIncompleteAttachment); + return false; + } + break; + + default: + break; + } + } + else + { + // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE + // is NONE, then querying any other pname will generate INVALID_ENUM. + + // ES 3.0.2 spec pg 235 states that if the attachment type is none, + // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an + // INVALID_OPERATION for all other pnames + + switch (pname) + { + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: + break; + + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: + if (clientVersion < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), + InvalidFramebufferAttachmentParameter); + return false; + } + break; + + default: + if (clientVersion < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), + InvalidFramebufferAttachmentParameter); + return false; + } + else + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), + InvalidFramebufferAttachmentParameter); + return false; + } + } + } + + if (numParams) + { + if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE) + { + // Only when the viewport offsets are queried we can have a varying number of output + // parameters. + const int numViews = attachmentObject ? attachmentObject->getNumViews() : 1; + *numParams = numViews * 2; + } + else + { + // For all other queries we can have only one output parameter. + *numParams = 1; + } + } + + return true; +} + +bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(ValidationContext *context, + GLenum target, + GLenum attachment, + GLenum pname, + GLsizei bufSize, + GLsizei *numParams) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname, + numParams)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *numParams)) + { + return false; + } + + return true; +} + +bool ValidateGetBufferParameterivRobustANGLE(ValidationContext *context, + BufferBinding target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateGetBufferParameterBase(context, target, pname, false, length)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *length)) + { + return false; + } + + return true; +} + +bool ValidateGetBufferParameteri64vRobustANGLE(ValidationContext *context, + BufferBinding target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint64 *params) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateGetBufferParameterBase(context, target, pname, false, length)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *length)) + { + return false; + } + + return true; +} + +bool ValidateGetProgramivBase(ValidationContext *context, + GLuint program, + GLenum pname, + GLsizei *numParams) +{ + // Currently, all GetProgramiv queries return 1 parameter + if (numParams) + { + *numParams = 1; + } + + Program *programObject = GetValidProgram(context, program); + if (!programObject) + { + return false; + } + + switch (pname) + { + case GL_DELETE_STATUS: + case GL_LINK_STATUS: + case GL_VALIDATE_STATUS: + case GL_INFO_LOG_LENGTH: + case GL_ATTACHED_SHADERS: + case GL_ACTIVE_ATTRIBUTES: + case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: + case GL_ACTIVE_UNIFORMS: + case GL_ACTIVE_UNIFORM_MAX_LENGTH: + break; + + case GL_PROGRAM_BINARY_LENGTH: + if (context->getClientMajorVersion() < 3 && !context->getExtensions().getProgramBinary) + { + context->handleError(InvalidEnum() << "Querying GL_PROGRAM_BINARY_LENGTH " + "requires GL_OES_get_program_binary or " + "ES 3.0."); + return false; + } + break; + + case GL_ACTIVE_UNIFORM_BLOCKS: + case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: + case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: + case GL_TRANSFORM_FEEDBACK_VARYINGS: + case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: + case GL_PROGRAM_BINARY_RETRIEVABLE_HINT: + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required); + return false; + } + break; + + case GL_PROGRAM_SEPARABLE: + case GL_COMPUTE_WORK_GROUP_SIZE: + case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS: + if (context->getClientVersion() < Version(3, 1)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required); + return false; + } + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + + return true; +} + +bool ValidateGetProgramivRobustANGLE(Context *context, + GLuint program, + GLenum pname, + GLsizei bufSize, + GLsizei *numParams) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateGetProgramivBase(context, program, pname, numParams)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *numParams)) + { + return false; + } + + return true; +} + +bool ValidateGetRenderbufferParameterivRobustANGLE(Context *context, + GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateGetRenderbufferParameterivBase(context, target, pname, length)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *length)) + { + return false; + } + + return true; +} + +bool ValidateGetShaderivRobustANGLE(Context *context, + GLuint shader, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateGetShaderivBase(context, shader, pname, length)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *length)) + { + return false; + } + + return true; +} + +bool ValidateGetTexParameterfvRobustANGLE(Context *context, + GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateGetTexParameterBase(context, target, pname, length)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *length)) + { + return false; + } + + return true; +} + +bool ValidateGetTexParameterivRobustANGLE(Context *context, + GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateGetTexParameterBase(context, target, pname, length)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *length)) + { + return false; + } + + return true; +} + +bool ValidateTexParameterfvRobustANGLE(Context *context, + GLenum target, + GLenum pname, + GLsizei bufSize, + const GLfloat *params) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + return ValidateTexParameterBase(context, target, pname, bufSize, params); +} + +bool ValidateTexParameterivRobustANGLE(Context *context, + GLenum target, + GLenum pname, + GLsizei bufSize, + const GLint *params) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + return ValidateTexParameterBase(context, target, pname, bufSize, params); +} + +bool ValidateGetSamplerParameterfvRobustANGLE(Context *context, + GLuint sampler, + GLenum pname, + GLuint bufSize, + GLsizei *length, + GLfloat *params) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateGetSamplerParameterBase(context, sampler, pname, length)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *length)) + { + return false; + } + + return true; +} + +bool ValidateGetSamplerParameterivRobustANGLE(Context *context, + GLuint sampler, + GLenum pname, + GLuint bufSize, + GLsizei *length, + GLint *params) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateGetSamplerParameterBase(context, sampler, pname, length)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *length)) + { + return false; + } + + return true; +} + +bool ValidateSamplerParameterfvRobustANGLE(Context *context, + GLuint sampler, + GLenum pname, + GLsizei bufSize, + const GLfloat *params) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + return ValidateSamplerParameterBase(context, sampler, pname, bufSize, params); +} + +bool ValidateSamplerParameterivRobustANGLE(Context *context, + GLuint sampler, + GLenum pname, + GLsizei bufSize, + const GLint *params) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + return ValidateSamplerParameterBase(context, sampler, pname, bufSize, params); +} + +bool ValidateGetVertexAttribfvRobustANGLE(Context *context, + GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateGetVertexAttribBase(context, index, pname, length, false, false)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *length)) + { + return false; + } + + return true; +} + +bool ValidateGetVertexAttribivRobustANGLE(Context *context, + GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateGetVertexAttribBase(context, index, pname, length, false, false)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *length)) + { + return false; + } + + return true; +} + +bool ValidateGetVertexAttribPointervRobustANGLE(Context *context, + GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **pointer) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateGetVertexAttribBase(context, index, pname, length, true, false)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *length)) + { + return false; + } + + return true; +} + +bool ValidateGetVertexAttribIivRobustANGLE(Context *context, + GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateGetVertexAttribBase(context, index, pname, length, false, true)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *length)) + { + return false; + } + + return true; +} + +bool ValidateGetVertexAttribIuivRobustANGLE(Context *context, + GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateGetVertexAttribBase(context, index, pname, length, false, true)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *length)) + { + return false; + } + + return true; +} + +bool ValidateGetActiveUniformBlockivRobustANGLE(Context *context, + GLuint program, + GLuint uniformBlockIndex, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateGetActiveUniformBlockivBase(context, program, uniformBlockIndex, pname, length)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *length)) + { + return false; + } + + return true; +} + +bool ValidateGetInternalFormativRobustANGLE(Context *context, + GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateGetInternalFormativBase(context, target, internalformat, pname, bufSize, length)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *length)) + { + return false; + } + + return true; +} + +bool ValidateVertexFormatBase(ValidationContext *context, + GLuint attribIndex, + GLint size, + GLenum type, + GLboolean pureInteger) +{ + const Caps &caps = context->getCaps(); + if (attribIndex >= caps.maxVertexAttributes) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute); + return false; + } + + if (size < 1 || size > 4) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidVertexAttrSize); + return false; + } + + switch (type) + { + case GL_BYTE: + case GL_UNSIGNED_BYTE: + case GL_SHORT: + case GL_UNSIGNED_SHORT: + break; + + case GL_INT: + case GL_UNSIGNED_INT: + if (context->getClientMajorVersion() < 3) + { + context->handleError(InvalidEnum() + << "Vertex type not supported before OpenGL ES 3.0."); + return false; + } + break; + + case GL_FIXED: + case GL_FLOAT: + if (pureInteger) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTypePureInt); + return false; + } + break; + + case GL_HALF_FLOAT: + if (context->getClientMajorVersion() < 3) + { + context->handleError(InvalidEnum() + << "Vertex type not supported before OpenGL ES 3.0."); + return false; + } + if (pureInteger) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTypePureInt); + return false; + } + break; + + case GL_INT_2_10_10_10_REV: + case GL_UNSIGNED_INT_2_10_10_10_REV: + if (context->getClientMajorVersion() < 3) + { + context->handleError(InvalidEnum() + << "Vertex type not supported before OpenGL ES 3.0."); + return false; + } + if (pureInteger) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTypePureInt); + return false; + } + if (size != 4) + { + context->handleError(InvalidOperation() << "Type is INT_2_10_10_10_REV or " + "UNSIGNED_INT_2_10_10_10_REV and " + "size is not 4."); + return false; + } + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType); + return false; + } + + return true; +} + +// Perform validation from WebGL 2 section 5.10 "Invalid Clears": +// In the WebGL 2 API, trying to perform a clear when there is a mismatch between the type of the +// specified clear value and the type of a buffer that is being cleared generates an +// INVALID_OPERATION error instead of producing undefined results +bool ValidateWebGLFramebufferAttachmentClearType(ValidationContext *context, + GLint drawbuffer, + const GLenum *validComponentTypes, + size_t validComponentTypeCount) +{ + const FramebufferAttachment *attachment = + context->getGLState().getDrawFramebuffer()->getDrawBuffer(drawbuffer); + if (attachment) + { + GLenum componentType = attachment->getFormat().info->componentType; + const GLenum *end = validComponentTypes + validComponentTypeCount; + if (std::find(validComponentTypes, end, componentType) == end) + { + context->handleError( + InvalidOperation() + << "No defined conversion between clear value and attachment format."); + return false; + } + } + + return true; +} + +bool ValidateRobustCompressedTexImageBase(ValidationContext *context, + GLsizei imageSize, + GLsizei dataSize) +{ + if (!ValidateRobustEntryPoint(context, dataSize)) + { + return false; + } + + gl::Buffer *pixelUnpackBuffer = + context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack); + if (pixelUnpackBuffer == nullptr) + { + if (dataSize < imageSize) + { + context->handleError(InvalidOperation() << "dataSize must be at least " << imageSize); + } + } + return true; +} + +bool ValidateGetBufferParameterBase(ValidationContext *context, + BufferBinding target, + GLenum pname, + bool pointerVersion, + GLsizei *numParams) +{ + if (numParams) + { + *numParams = 0; + } + + if (!ValidBufferType(context, target)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes); + return false; + } + + const Buffer *buffer = context->getGLState().getTargetBuffer(target); + if (!buffer) + { + // A null buffer means that "0" is bound to the requested buffer target + ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound); + return false; + } + + const Extensions &extensions = context->getExtensions(); + + switch (pname) + { + case GL_BUFFER_USAGE: + case GL_BUFFER_SIZE: + break; + + case GL_BUFFER_ACCESS_OES: + if (!extensions.mapBuffer) + { + context->handleError(InvalidEnum() + << "pname requires OpenGL ES 3.0 or GL_OES_mapbuffer."); + return false; + } + break; + + case GL_BUFFER_MAPPED: + static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal."); + if (context->getClientMajorVersion() < 3 && !extensions.mapBuffer && + !extensions.mapBufferRange) + { + context->handleError(InvalidEnum() << "pname requires OpenGL ES 3.0, " + "GL_OES_mapbuffer or " + "GL_EXT_map_buffer_range."); + return false; + } + break; + + case GL_BUFFER_MAP_POINTER: + if (!pointerVersion) + { + context->handleError( + InvalidEnum() + << "GL_BUFFER_MAP_POINTER can only be queried with GetBufferPointerv."); + return false; + } + break; + + case GL_BUFFER_ACCESS_FLAGS: + case GL_BUFFER_MAP_OFFSET: + case GL_BUFFER_MAP_LENGTH: + if (context->getClientMajorVersion() < 3 && !extensions.mapBufferRange) + { + context->handleError(InvalidEnum() + << "pname requires OpenGL ES 3.0 or GL_EXT_map_buffer_range."); + return false; + } + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + + // All buffer parameter queries return one value. + if (numParams) + { + *numParams = 1; + } + + return true; +} + +bool ValidateGetRenderbufferParameterivBase(Context *context, + GLenum target, + GLenum pname, + GLsizei *length) +{ + if (length) + { + *length = 0; + } + + if (target != GL_RENDERBUFFER) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget); + return false; + } + + Renderbuffer *renderbuffer = context->getGLState().getCurrentRenderbuffer(); + if (renderbuffer == nullptr) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), RenderbufferNotBound); + return false; + } + + switch (pname) + { + case GL_RENDERBUFFER_WIDTH: + case GL_RENDERBUFFER_HEIGHT: + case GL_RENDERBUFFER_INTERNAL_FORMAT: + case GL_RENDERBUFFER_RED_SIZE: + case GL_RENDERBUFFER_GREEN_SIZE: + case GL_RENDERBUFFER_BLUE_SIZE: + case GL_RENDERBUFFER_ALPHA_SIZE: + case GL_RENDERBUFFER_DEPTH_SIZE: + case GL_RENDERBUFFER_STENCIL_SIZE: + break; + + case GL_RENDERBUFFER_SAMPLES_ANGLE: + if (!context->getExtensions().framebufferMultisample) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled); + return false; + } + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + + if (length) + { + *length = 1; + } + return true; +} + +bool ValidateGetShaderivBase(Context *context, GLuint shader, GLenum pname, GLsizei *length) +{ + if (length) + { + *length = 0; + } + + if (GetValidShader(context, shader) == nullptr) + { + return false; + } + + switch (pname) + { + case GL_SHADER_TYPE: + case GL_DELETE_STATUS: + case GL_COMPILE_STATUS: + case GL_INFO_LOG_LENGTH: + case GL_SHADER_SOURCE_LENGTH: + break; + + case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE: + if (!context->getExtensions().translatedShaderSource) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled); + return false; + } + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + + if (length) + { + *length = 1; + } + return true; +} + +bool ValidateGetTexParameterBase(Context *context, GLenum target, GLenum pname, GLsizei *length) +{ + if (length) + { + *length = 0; + } + + if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget); + return false; + } + + if (context->getTargetTexture(target) == nullptr) + { + // Should only be possible for external textures + ANGLE_VALIDATION_ERR(context, InvalidEnum(), TextureNotBound); + return false; + } + + switch (pname) + { + case GL_TEXTURE_MAG_FILTER: + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + break; + + case GL_TEXTURE_USAGE_ANGLE: + if (!context->getExtensions().textureUsage) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled); + return false; + } + break; + + case GL_TEXTURE_MAX_ANISOTROPY_EXT: + if (!context->getExtensions().textureFilterAnisotropic) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled); + return false; + } + break; + + case GL_TEXTURE_IMMUTABLE_FORMAT: + if (context->getClientMajorVersion() < 3 && !context->getExtensions().textureStorage) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled); + return false; + } + break; + + case GL_TEXTURE_WRAP_R: + case GL_TEXTURE_IMMUTABLE_LEVELS: + case GL_TEXTURE_SWIZZLE_R: + case GL_TEXTURE_SWIZZLE_G: + case GL_TEXTURE_SWIZZLE_B: + case GL_TEXTURE_SWIZZLE_A: + case GL_TEXTURE_BASE_LEVEL: + case GL_TEXTURE_MAX_LEVEL: + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: + case GL_TEXTURE_COMPARE_MODE: + case GL_TEXTURE_COMPARE_FUNC: + if (context->getClientMajorVersion() < 3) + { + context->handleError(InvalidEnum() << "pname requires OpenGL ES 3.0."); + return false; + } + break; + + case GL_TEXTURE_SRGB_DECODE_EXT: + if (!context->getExtensions().textureSRGBDecode) + { + context->handleError(InvalidEnum() << "GL_EXT_texture_sRGB_decode is not enabled."); + return false; + } + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + + if (length) + { + *length = 1; + } + return true; +} + +bool ValidateGetVertexAttribBase(Context *context, + GLuint index, + GLenum pname, + GLsizei *length, + bool pointer, + bool pureIntegerEntryPoint) +{ + if (length) + { + *length = 0; + } + + if (pureIntegerEntryPoint && context->getClientMajorVersion() < 3) + { + context->handleError(InvalidOperation() << "Context does not support OpenGL ES 3.0."); + return false; + } + + if (index >= context->getCaps().maxVertexAttributes) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute); + return false; + } + + if (pointer) + { + if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + } + else + { + switch (pname) + { + case GL_VERTEX_ATTRIB_ARRAY_ENABLED: + case GL_VERTEX_ATTRIB_ARRAY_SIZE: + case GL_VERTEX_ATTRIB_ARRAY_STRIDE: + case GL_VERTEX_ATTRIB_ARRAY_TYPE: + case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: + case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: + case GL_CURRENT_VERTEX_ATTRIB: + break; + + case GL_VERTEX_ATTRIB_ARRAY_DIVISOR: + static_assert( + GL_VERTEX_ATTRIB_ARRAY_DIVISOR == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE, + "ANGLE extension enums not equal to GL enums."); + if (context->getClientMajorVersion() < 3 && + !context->getExtensions().instancedArrays) + { + context->handleError(InvalidEnum() << "GL_VERTEX_ATTRIB_ARRAY_DIVISOR " + "requires OpenGL ES 3.0 or " + "GL_ANGLE_instanced_arrays."); + return false; + } + break; + + case GL_VERTEX_ATTRIB_ARRAY_INTEGER: + if (context->getClientMajorVersion() < 3) + { + context->handleError( + InvalidEnum() << "GL_VERTEX_ATTRIB_ARRAY_INTEGER requires OpenGL ES 3.0."); + return false; + } + break; + + case GL_VERTEX_ATTRIB_BINDING: + case GL_VERTEX_ATTRIB_RELATIVE_OFFSET: + if (context->getClientVersion() < ES_3_1) + { + context->handleError(InvalidEnum() + << "Vertex Attrib Bindings require OpenGL ES 3.1."); + return false; + } + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + } + + if (length) + { + if (pname == GL_CURRENT_VERTEX_ATTRIB) + { + *length = 4; + } + else + { + *length = 1; + } + } + + return true; +} + +bool ValidateReadPixelsBase(Context *context, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + GLsizei *columns, + GLsizei *rows, + void *pixels) +{ + if (length != nullptr) + { + *length = 0; + } + if (rows != nullptr) + { + *rows = 0; + } + if (columns != nullptr) + { + *columns = 0; + } + + if (width < 0 || height < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize); + return false; + } + + Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer(); + + if (readFramebuffer->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE) + { + context->handleError(InvalidFramebufferOperation()); + return false; + } + + if (readFramebuffer->id() != 0 && readFramebuffer->getSamples(context) != 0) + { + context->handleError(InvalidOperation()); + return false; + } + + const Framebuffer *framebuffer = context->getGLState().getReadFramebuffer(); + ASSERT(framebuffer); + + if (framebuffer->getReadBufferState() == GL_NONE) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ReadBufferNone); + return false; + } + + const FramebufferAttachment *readBuffer = framebuffer->getReadColorbuffer(); + // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment + // In OpenGL ES it is undefined what happens when an operation tries to read from a missing + // attachment and WebGL defines it to be an error. We do the check unconditionnaly as the + // situation is an application error that would lead to a crash in ANGLE. + if (readBuffer == nullptr) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), MissingReadAttachment); + return false; + } + + // ANGLE_multiview, Revision 1: + // ReadPixels generates an INVALID_FRAMEBUFFER_OPERATION error if the multi-view layout of the + // current read framebuffer is not NONE. + if (readBuffer->getMultiviewLayout() != GL_NONE) + { + context->handleError(InvalidFramebufferOperation() + << "Attempting to read from a multi-view framebuffer."); + return false; + } + + if (context->getExtensions().webglCompatibility) + { + // The ES 2.0 spec states that the format must be "among those defined in table 3.4, + // excluding formats LUMINANCE and LUMINANCE_ALPHA.". This requires validating the format + // and type before validating the combination of format and type. However, the + // dEQP-GLES3.functional.negative_api.buffer.read_pixels passes GL_LUMINANCE as a format and + // verifies that GL_INVALID_OPERATION is generated. + // TODO(geofflang): Update this check to be done in all/no cases once this is resolved in + // dEQP/WebGL. + if (!ValidReadPixelsFormatEnum(context, format)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFormat); + return false; + } + + if (!ValidReadPixelsTypeEnum(context, type)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType); + return false; + } + } + + GLenum currentFormat = framebuffer->getImplementationColorReadFormat(context); + GLenum currentType = framebuffer->getImplementationColorReadType(context); + GLenum currentComponentType = readBuffer->getFormat().info->componentType; + + bool validFormatTypeCombination = + ValidReadPixelsFormatType(context, currentComponentType, format, type); + + if (!(currentFormat == format && currentType == type) && !validFormatTypeCombination) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat); + return false; + } + + // Check for pixel pack buffer related API errors + gl::Buffer *pixelPackBuffer = context->getGLState().getTargetBuffer(BufferBinding::PixelPack); + if (pixelPackBuffer != nullptr && pixelPackBuffer->isMapped()) + { + // ...the buffer object's data store is currently mapped. + context->handleError(InvalidOperation() << "Pixel pack buffer is mapped."); + return false; + } + + // .. the data would be packed to the buffer object such that the memory writes required + // would exceed the data store size. + const InternalFormat &formatInfo = GetInternalFormatInfo(format, type); + const gl::Extents size(width, height, 1); + const auto &pack = context->getGLState().getPackState(); + + auto endByteOrErr = formatInfo.computePackUnpackEndByte(type, size, pack, false); + if (endByteOrErr.isError()) + { + context->handleError(endByteOrErr.getError()); + return false; + } + + size_t endByte = endByteOrErr.getResult(); + if (bufSize >= 0) + { + if (pixelPackBuffer == nullptr && static_cast(bufSize) < endByte) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize); + return false; + } + } + + if (pixelPackBuffer != nullptr) + { + CheckedNumeric checkedEndByte(endByte); + CheckedNumeric checkedOffset(reinterpret_cast(pixels)); + checkedEndByte += checkedOffset; + + if (checkedEndByte.ValueOrDie() > static_cast(pixelPackBuffer->getSize())) + { + // Overflow past the end of the buffer + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ParamOverflow); + return false; + } + } + + if (pixelPackBuffer == nullptr && length != nullptr) + { + if (endByte > static_cast(std::numeric_limits::max())) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow); + return false; + } + + *length = static_cast(endByte); + } + + auto getClippedExtent = [](GLint start, GLsizei length, int bufferSize) { + angle::CheckedNumeric clippedExtent(length); + if (start < 0) + { + // "subtract" the area that is less than 0 + clippedExtent += start; + } + + const int readExtent = start + length; + if (readExtent > bufferSize) + { + // Subtract the region to the right of the read buffer + clippedExtent -= (readExtent - bufferSize); + } + + if (!clippedExtent.IsValid()) + { + return 0; + } + + return std::max(clippedExtent.ValueOrDie(), 0); + }; + + if (columns != nullptr) + { + *columns = getClippedExtent(x, width, readBuffer->getSize().width); + } + + if (rows != nullptr) + { + *rows = getClippedExtent(y, height, readBuffer->getSize().height); + } + + return true; +} + +template +bool ValidateTexParameterBase(Context *context, + GLenum target, + GLenum pname, + GLsizei bufSize, + const ParamType *params) +{ + if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget); + return false; + } + + if (context->getTargetTexture(target) == nullptr) + { + // Should only be possible for external textures + ANGLE_VALIDATION_ERR(context, InvalidEnum(), TextureNotBound); + return false; + } + + const GLsizei minBufSize = 1; + if (bufSize >= 0 && bufSize < minBufSize) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize); + return false; + } + + switch (pname) + { + case GL_TEXTURE_WRAP_R: + case GL_TEXTURE_SWIZZLE_R: + case GL_TEXTURE_SWIZZLE_G: + case GL_TEXTURE_SWIZZLE_B: + case GL_TEXTURE_SWIZZLE_A: + case GL_TEXTURE_BASE_LEVEL: + case GL_TEXTURE_MAX_LEVEL: + case GL_TEXTURE_COMPARE_MODE: + case GL_TEXTURE_COMPARE_FUNC: + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required); + return false; + } + if (target == GL_TEXTURE_EXTERNAL_OES && + !context->getExtensions().eglImageExternalEssl3) + { + context->handleError(InvalidEnum() << "ES3 texture parameters are not " + "available without " + "GL_OES_EGL_image_external_essl3."); + return false; + } + break; + + default: + break; + } + + if (target == GL_TEXTURE_2D_MULTISAMPLE) + { + switch (pname) + { + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_MAG_FILTER: + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + case GL_TEXTURE_WRAP_R: + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: + case GL_TEXTURE_COMPARE_MODE: + case GL_TEXTURE_COMPARE_FUNC: + context->handleError(InvalidEnum() + << "Invalid parameter for 2D multisampled textures."); + return false; + } + } + + switch (pname) + { + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + case GL_TEXTURE_WRAP_R: + { + bool restrictedWrapModes = + target == GL_TEXTURE_EXTERNAL_OES || target == GL_TEXTURE_RECTANGLE_ANGLE; + if (!ValidateTextureWrapModeValue(context, params, restrictedWrapModes)) + { + return false; + } + } + break; + + case GL_TEXTURE_MIN_FILTER: + { + bool restrictedMinFilter = + target == GL_TEXTURE_EXTERNAL_OES || target == GL_TEXTURE_RECTANGLE_ANGLE; + if (!ValidateTextureMinFilterValue(context, params, restrictedMinFilter)) + { + return false; + } + } + break; + + case GL_TEXTURE_MAG_FILTER: + if (!ValidateTextureMagFilterValue(context, params)) + { + return false; + } + break; + + case GL_TEXTURE_USAGE_ANGLE: + if (!context->getExtensions().textureUsage) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + + switch (ConvertToGLenum(params[0])) + { + case GL_NONE: + case GL_FRAMEBUFFER_ATTACHMENT_ANGLE: + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + break; + + case GL_TEXTURE_MAX_ANISOTROPY_EXT: + if (!context->getExtensions().textureFilterAnisotropic) + { + context->handleError(InvalidEnum() << "GL_EXT_texture_anisotropic is not enabled."); + return false; + } + + // we assume the parameter passed to this validation method is truncated, not rounded + if (params[0] < 1) + { + context->handleError(InvalidValue() << "Max anisotropy must be at least 1."); + return false; + } + break; + + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: + // any value is permissible + break; + + case GL_TEXTURE_COMPARE_MODE: + if (!ValidateTextureCompareModeValue(context, params)) + { + return false; + } + break; + + case GL_TEXTURE_COMPARE_FUNC: + if (!ValidateTextureCompareFuncValue(context, params)) + { + return false; + } + break; + + case GL_TEXTURE_SWIZZLE_R: + case GL_TEXTURE_SWIZZLE_G: + case GL_TEXTURE_SWIZZLE_B: + case GL_TEXTURE_SWIZZLE_A: + switch (ConvertToGLenum(params[0])) + { + case GL_RED: + case GL_GREEN: + case GL_BLUE: + case GL_ALPHA: + case GL_ZERO: + case GL_ONE: + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + break; + + case GL_TEXTURE_BASE_LEVEL: + if (ConvertToGLint(params[0]) < 0) + { + context->handleError(InvalidValue() << "Base level must be at least 0."); + return false; + } + if (target == GL_TEXTURE_EXTERNAL_OES && static_cast(params[0]) != 0) + { + context->handleError(InvalidOperation() + << "Base level must be 0 for external textures."); + return false; + } + if (target == GL_TEXTURE_2D_MULTISAMPLE && static_cast(params[0]) != 0) + { + context->handleError(InvalidOperation() + << "Base level must be 0 for multisampled textures."); + return false; + } + if (target == GL_TEXTURE_RECTANGLE_ANGLE && static_cast(params[0]) != 0) + { + context->handleError(InvalidOperation() + << "Base level must be 0 for rectangle textures."); + return false; + } + break; + + case GL_TEXTURE_MAX_LEVEL: + if (ConvertToGLint(params[0]) < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel); + return false; + } + break; + + case GL_DEPTH_STENCIL_TEXTURE_MODE: + if (context->getClientVersion() < Version(3, 1)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumRequiresGLES31); + return false; + } + switch (ConvertToGLenum(params[0])) + { + case GL_DEPTH_COMPONENT: + case GL_STENCIL_INDEX: + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + break; + + case GL_TEXTURE_SRGB_DECODE_EXT: + if (!ValidateTextureSRGBDecodeValue(context, params)) + { + return false; + } + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + + return true; +} + +template bool ValidateTexParameterBase(Context *, GLenum, GLenum, GLsizei, const GLfloat *); +template bool ValidateTexParameterBase(Context *, GLenum, GLenum, GLsizei, const GLint *); + +bool ValidateVertexAttribIndex(ValidationContext *context, GLuint index) +{ + if (index >= MAX_VERTEX_ATTRIBS) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute); + return false; + } + + return true; +} + +bool ValidateGetActiveUniformBlockivBase(Context *context, + GLuint program, + GLuint uniformBlockIndex, + GLenum pname, + GLsizei *length) +{ + if (length) + { + *length = 0; + } + + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + Program *programObject = GetValidProgram(context, program); + if (!programObject) + { + return false; + } + + if (uniformBlockIndex >= programObject->getActiveUniformBlockCount()) + { + context->handleError(InvalidValue() + << "uniformBlockIndex exceeds active uniform block count."); + return false; + } + + switch (pname) + { + case GL_UNIFORM_BLOCK_BINDING: + case GL_UNIFORM_BLOCK_DATA_SIZE: + case GL_UNIFORM_BLOCK_NAME_LENGTH: + case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: + case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: + case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: + case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + + if (length) + { + if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) + { + const InterfaceBlock &uniformBlock = + programObject->getUniformBlockByIndex(uniformBlockIndex); + *length = static_cast(uniformBlock.memberIndexes.size()); + } + else + { + *length = 1; + } + } + + return true; +} + +template +bool ValidateSamplerParameterBase(Context *context, + GLuint sampler, + GLenum pname, + GLsizei bufSize, + ParamType *params) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + if (!context->isSampler(sampler)) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidSampler); + return false; + } + + const GLsizei minBufSize = 1; + if (bufSize >= 0 && bufSize < minBufSize) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize); + return false; + } + + switch (pname) + { + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + case GL_TEXTURE_WRAP_R: + if (!ValidateTextureWrapModeValue(context, params, false)) + { + return false; + } + break; + + case GL_TEXTURE_MIN_FILTER: + if (!ValidateTextureMinFilterValue(context, params, false)) + { + return false; + } + break; + + case GL_TEXTURE_MAG_FILTER: + if (!ValidateTextureMagFilterValue(context, params)) + { + return false; + } + break; + + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: + // any value is permissible + break; + + case GL_TEXTURE_COMPARE_MODE: + if (!ValidateTextureCompareModeValue(context, params)) + { + return false; + } + break; + + case GL_TEXTURE_COMPARE_FUNC: + if (!ValidateTextureCompareFuncValue(context, params)) + { + return false; + } + break; + + case GL_TEXTURE_SRGB_DECODE_EXT: + if (!ValidateTextureSRGBDecodeValue(context, params)) + { + return false; + } + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + + return true; +} + +template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, GLfloat *); +template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, GLint *); + +bool ValidateGetSamplerParameterBase(Context *context, + GLuint sampler, + GLenum pname, + GLsizei *length) +{ + if (length) + { + *length = 0; + } + + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + if (!context->isSampler(sampler)) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidSampler); + return false; + } + + switch (pname) + { + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + case GL_TEXTURE_WRAP_R: + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_MAG_FILTER: + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: + case GL_TEXTURE_COMPARE_MODE: + case GL_TEXTURE_COMPARE_FUNC: + break; + + case GL_TEXTURE_SRGB_DECODE_EXT: + if (!context->getExtensions().textureSRGBDecode) + { + context->handleError(InvalidEnum() << "GL_EXT_texture_sRGB_decode is not enabled."); + return false; + } + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + + if (length) + { + *length = 1; + } + return true; +} + +bool ValidateGetInternalFormativBase(Context *context, + GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei bufSize, + GLsizei *numParams) +{ + if (numParams) + { + *numParams = 0; + } + + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat); + if (!formatCaps.renderable) + { + context->handleError(InvalidEnum() << "Internal format is not renderable."); + return false; + } + + switch (target) + { + case GL_RENDERBUFFER: + break; + + case GL_TEXTURE_2D_MULTISAMPLE: + if (context->getClientVersion() < ES_3_1) + { + context->handleError(InvalidOperation() + << "Texture target requires at least OpenGL ES 3.1."); + return false; + } + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTarget); + return false; + } + + if (bufSize < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize); + return false; + } + + GLsizei maxWriteParams = 0; + switch (pname) + { + case GL_NUM_SAMPLE_COUNTS: + maxWriteParams = 1; + break; + + case GL_SAMPLES: + maxWriteParams = static_cast(formatCaps.sampleCounts.size()); + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + + if (numParams) + { + // glGetInternalFormativ will not overflow bufSize + *numParams = std::min(bufSize, maxWriteParams); + } + + return true; } } // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/validationES.h b/src/3rdparty/angle/src/libANGLE/validationES.h index 5d8486a6ab..e29432b8c3 100644 --- a/src/3rdparty/angle/src/libANGLE/validationES.h +++ b/src/3rdparty/angle/src/libANGLE/validationES.h @@ -10,9 +10,11 @@ #define LIBANGLE_VALIDATION_ES_H_ #include "common/mathutil.h" +#include "libANGLE/PackedGLEnums.h" #include #include +#include namespace egl { @@ -23,21 +25,24 @@ class Image; namespace gl { class Context; +struct Format; +struct LinkedUniform; class Program; class Shader; class ValidationContext; -bool ValidCap(const Context *context, GLenum cap); bool ValidTextureTarget(const ValidationContext *context, GLenum target); bool ValidTexture2DTarget(const ValidationContext *context, GLenum target); bool ValidTexture3DTarget(const ValidationContext *context, GLenum target); +bool ValidTextureExternalTarget(const ValidationContext *context, GLenum target); bool ValidTexture2DDestinationTarget(const ValidationContext *context, GLenum target); bool ValidTexture3DDestinationTarget(const ValidationContext *context, GLenum target); -bool ValidFramebufferTarget(GLenum target); -bool ValidBufferTarget(const Context *context, GLenum target); -bool ValidBufferParameter(const Context *context, GLenum pname); +bool ValidTexLevelDestinationTarget(const ValidationContext *context, GLenum target); +bool ValidFramebufferTarget(const ValidationContext *context, GLenum target); +bool ValidBufferType(const ValidationContext *context, BufferBinding target); +bool ValidBufferParameter(const ValidationContext *context, GLenum pname, GLsizei *numParams); bool ValidMipLevel(const ValidationContext *context, GLenum target, GLint level); -bool ValidImageSizeParameters(const Context *context, +bool ValidImageSizeParameters(ValidationContext *context, GLenum target, GLint level, GLsizei width, @@ -46,30 +51,60 @@ bool ValidImageSizeParameters(const Context *context, bool isSubImage); bool ValidCompressedImageSize(const ValidationContext *context, GLenum internalFormat, + GLint level, GLsizei width, GLsizei height); +bool ValidCompressedSubImageSize(const ValidationContext *context, + GLenum internalFormat, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + size_t textureWidth, + size_t textureHeight); +bool ValidImageDataSize(ValidationContext *context, + GLenum textureTarget, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *pixels, + GLsizei imageSize); + bool ValidQueryType(const Context *context, GLenum queryType); +bool ValidateWebGLVertexAttribPointer(ValidationContext *context, + GLenum type, + GLboolean normalized, + GLsizei stride, + const void *ptr, + bool pureInteger); + // Returns valid program if id is a valid program name // Errors INVALID_OPERATION if valid shader is given and returns NULL // Errors INVALID_VALUE otherwise and returns NULL -Program *GetValidProgram(Context *context, GLuint id); +Program *GetValidProgram(ValidationContext *context, GLuint id); // Returns valid shader if id is a valid shader name // Errors INVALID_OPERATION if valid program is given and returns NULL // Errors INVALID_VALUE otherwise and returns NULL -Shader *GetValidShader(Context *context, GLuint id); +Shader *GetValidShader(ValidationContext *context, GLuint id); bool ValidateAttachmentTarget(Context *context, GLenum attachment); -bool ValidateRenderbufferStorageParametersBase(Context *context, GLenum target, GLsizei samples, - GLenum internalformat, GLsizei width, GLsizei height); -bool ValidateRenderbufferStorageParametersANGLE(Context *context, GLenum target, GLsizei samples, - GLenum internalformat, GLsizei width, GLsizei height); +bool ValidateRenderbufferStorageParametersBase(ValidationContext *context, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height); +bool ValidateFramebufferRenderbufferParameters(Context *context, + GLenum target, + GLenum attachment, + GLenum renderbuffertarget, + GLuint renderbuffer); -bool ValidateFramebufferRenderbufferParameters(Context *context, GLenum target, GLenum attachment, - GLenum renderbuffertarget, GLuint renderbuffer); - -bool ValidateBlitFramebufferParameters(Context *context, +bool ValidateBlitFramebufferParameters(ValidationContext *context, GLint srcX0, GLint srcY0, GLint srcX1, @@ -81,20 +116,30 @@ bool ValidateBlitFramebufferParameters(Context *context, GLbitfield mask, GLenum filter); -bool ValidateGetVertexAttribParameters(Context *context, GLenum pname); - -bool ValidateTexParamParameters(Context *context, GLenum pname, GLint param); - -bool ValidateSamplerObjectParameter(Context *context, GLenum pname); - -bool ValidateReadPixels(Context *context, - GLint x, - GLint y, - GLsizei width, - GLsizei height, - GLenum format, - GLenum type, - GLvoid *pixels); +bool ValidateReadPixelsBase(Context *context, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + GLsizei *columns, + GLsizei *rows, + void *pixels); +bool ValidateReadPixelsRobustANGLE(Context *context, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + GLsizei *columns, + GLsizei *rows, + void *pixels); bool ValidateReadnPixelsEXT(Context *context, GLint x, GLint y, @@ -103,30 +148,97 @@ bool ValidateReadnPixelsEXT(Context *context, GLenum format, GLenum type, GLsizei bufSize, - GLvoid *pixels); + void *pixels); +bool ValidateReadnPixelsRobustANGLE(Context *context, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + GLsizei *columns, + GLsizei *rows, + void *data); -bool ValidateGenQueriesBase(gl::Context *context, GLsizei n, const GLuint *ids); -bool ValidateGenQueriesEXT(gl::Context *context, GLsizei n, const GLuint *ids); -bool ValidateDeleteQueriesBase(gl::Context *context, GLsizei n, const GLuint *ids); +bool ValidateGenQueriesEXT(gl::Context *context, GLsizei n, GLuint *ids); bool ValidateDeleteQueriesEXT(gl::Context *context, GLsizei n, const GLuint *ids); +bool ValidateIsQueryEXT(gl::Context *context, GLuint id); bool ValidateBeginQueryBase(Context *context, GLenum target, GLuint id); bool ValidateBeginQueryEXT(Context *context, GLenum target, GLuint id); bool ValidateEndQueryBase(Context *context, GLenum target); bool ValidateEndQueryEXT(Context *context, GLenum target); bool ValidateQueryCounterEXT(Context *context, GLuint id, GLenum target); -bool ValidateGetQueryivBase(Context *context, GLenum target, GLenum pname); +bool ValidateGetQueryivBase(Context *context, GLenum target, GLenum pname, GLsizei *numParams); bool ValidateGetQueryivEXT(Context *context, GLenum target, GLenum pname, GLint *params); -bool ValidateGetQueryObjectValueBase(Context *context, GLenum target, GLenum pname); +bool ValidateGetQueryivRobustANGLE(Context *context, + GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +bool ValidateGetQueryObjectValueBase(Context *context, + GLenum target, + GLenum pname, + GLsizei *numParams); bool ValidateGetQueryObjectivEXT(Context *context, GLuint id, GLenum pname, GLint *params); +bool ValidateGetQueryObjectivRobustANGLE(Context *context, + GLuint id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); bool ValidateGetQueryObjectuivEXT(Context *context, GLuint id, GLenum pname, GLuint *params); +bool ValidateGetQueryObjectuivRobustANGLE(Context *context, + GLuint id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params); bool ValidateGetQueryObjecti64vEXT(Context *context, GLuint id, GLenum pname, GLint64 *params); +bool ValidateGetQueryObjecti64vRobustANGLE(Context *context, + GLuint id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint64 *params); bool ValidateGetQueryObjectui64vEXT(Context *context, GLuint id, GLenum pname, GLuint64 *params); +bool ValidateGetQueryObjectui64vRobustANGLE(Context *context, + GLuint id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint64 *params); -bool ValidateUniform(Context *context, GLenum uniformType, GLint location, GLsizei count); -bool ValidateUniformMatrix(Context *context, GLenum matrixType, GLint location, GLsizei count, +bool ValidateUniformCommonBase(ValidationContext *context, + gl::Program *program, + GLint location, + GLsizei count, + const LinkedUniform **uniformOut); +bool ValidateUniform1ivValue(ValidationContext *context, + GLenum uniformType, + GLsizei count, + const GLint *value); +bool ValidateUniformValue(ValidationContext *context, GLenum valueType, GLenum uniformType); +bool ValidateUniformMatrixValue(ValidationContext *context, GLenum valueType, GLenum uniformType); +bool ValidateUniform(ValidationContext *context, GLenum uniformType, GLint location, GLsizei count); +bool ValidateUniformMatrix(ValidationContext *context, + GLenum matrixType, + GLint location, + GLsizei count, GLboolean transpose); -bool ValidateStateQuery(Context *context, GLenum pname, GLenum *nativeType, unsigned int *numParams); +bool ValidateStateQuery(ValidationContext *context, + GLenum pname, + GLenum *nativeType, + unsigned int *numParams); + +bool ValidateRobustStateQuery(ValidationContext *context, + GLenum pname, + GLsizei bufSize, + GLenum *nativeType, + unsigned int *numParams); bool ValidateCopyTexImageParametersBase(ValidationContext *context, GLenum target, @@ -141,69 +253,99 @@ bool ValidateCopyTexImageParametersBase(ValidationContext *context, GLsizei width, GLsizei height, GLint border, - GLenum *textureInternalFormatOut); + Format *textureFormatOut); -bool ValidateDrawArrays(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount); -bool ValidateDrawArraysInstanced(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount); -bool ValidateDrawArraysInstancedANGLE(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount); +bool ValidateDrawBase(ValidationContext *context, GLenum mode, GLsizei count); +bool ValidateDrawArraysCommon(ValidationContext *context, + GLenum mode, + GLint first, + GLsizei count, + GLsizei primcount); +bool ValidateDrawArraysInstancedBase(Context *context, + GLenum mode, + GLint first, + GLsizei count, + GLsizei primcount); +bool ValidateDrawArraysInstancedANGLE(Context *context, + GLenum mode, + GLint first, + GLsizei count, + GLsizei primcount); -bool ValidateDrawElements(ValidationContext *context, - GLenum mode, - GLsizei count, - GLenum type, - const GLvoid *indices, - GLsizei primcount, - IndexRange *indexRangeOut); +bool ValidateDrawElementsBase(ValidationContext *context, GLenum type); +bool ValidateDrawElementsCommon(ValidationContext *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei primcount); -bool ValidateDrawElementsInstanced(Context *context, - GLenum mode, - GLsizei count, - GLenum type, - const GLvoid *indices, - GLsizei primcount, - IndexRange *indexRangeOut); +bool ValidateDrawElementsInstancedCommon(ValidationContext *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei primcount); bool ValidateDrawElementsInstancedANGLE(Context *context, GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, - GLsizei primcount, - IndexRange *indexRangeOut); + const void *indices, + GLsizei primcount); -bool ValidateFramebufferTextureBase(Context *context, GLenum target, GLenum attachment, - GLuint texture, GLint level); -bool ValidateFramebufferTexture2D(Context *context, GLenum target, GLenum attachment, - GLenum textarget, GLuint texture, GLint level); -bool ValidateFramebufferRenderbuffer(Context *context, - GLenum target, - GLenum attachment, - GLenum renderbuffertarget, - GLuint renderbuffer); +bool ValidateFramebufferTextureBase(Context *context, + GLenum target, + GLenum attachment, + GLuint texture, + GLint level); bool ValidateGetUniformBase(Context *context, GLuint program, GLint location); -bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat* params); -bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint* params); -bool ValidateGetnUniformfvEXT(Context *context, GLuint program, GLint location, GLsizei bufSize, GLfloat* params); -bool ValidateGetnUniformivEXT(Context *context, GLuint program, GLint location, GLsizei bufSize, GLint* params); +bool ValidateGetnUniformfvEXT(Context *context, + GLuint program, + GLint location, + GLsizei bufSize, + GLfloat *params); +bool ValidateGetnUniformivEXT(Context *context, + GLuint program, + GLint location, + GLsizei bufSize, + GLint *params); +bool ValidateGetUniformfvRobustANGLE(Context *context, + GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLfloat *params); +bool ValidateGetUniformivRobustANGLE(Context *context, + GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLint *params); +bool ValidateGetUniformuivRobustANGLE(Context *context, + GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLuint *params); -bool ValidateDiscardFramebufferBase(Context *context, GLenum target, GLsizei numAttachments, - const GLenum *attachments, bool defaultFramebuffer); +bool ValidateDiscardFramebufferBase(Context *context, + GLenum target, + GLsizei numAttachments, + const GLenum *attachments, + bool defaultFramebuffer); bool ValidateInsertEventMarkerEXT(Context *context, GLsizei length, const char *marker); bool ValidatePushGroupMarkerEXT(Context *context, GLsizei length, const char *marker); bool ValidateEGLImageTargetTexture2DOES(Context *context, - egl::Display *display, GLenum target, egl::Image *image); bool ValidateEGLImageTargetRenderbufferStorageOES(Context *context, - egl::Display *display, GLenum target, egl::Image *image); bool ValidateBindVertexArrayBase(Context *context, GLuint array); -bool ValidateDeleteVertexArraysBase(Context *context, GLsizei n); -bool ValidateGenVertexArraysBase(Context *context, GLsizei n); bool ValidateProgramBinaryBase(Context *context, GLuint program, @@ -217,28 +359,243 @@ bool ValidateGetProgramBinaryBase(Context *context, GLenum *binaryFormat, void *binary); -bool ValidateCopyTexImage2D(ValidationContext *context, - GLenum target, - GLint level, - GLenum internalformat, - GLint x, - GLint y, - GLsizei width, - GLsizei height, - GLint border); bool ValidateDrawBuffersBase(ValidationContext *context, GLsizei n, const GLenum *bufs); -bool ValidateCopyTexSubImage2D(Context *context, - GLenum target, - GLint level, - GLint xoffset, - GLint yoffset, - GLint x, - GLint y, - GLsizei width, - GLsizei height); -// Error messages shared here for use in testing. -extern const char *g_ExceedsMaxElementErrorMessage; +bool ValidateGetBufferPointervBase(Context *context, + BufferBinding target, + GLenum pname, + GLsizei *length, + void **params); +bool ValidateUnmapBufferBase(Context *context, BufferBinding target); +bool ValidateMapBufferRangeBase(Context *context, + BufferBinding target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access); +bool ValidateFlushMappedBufferRangeBase(Context *context, + BufferBinding target, + GLintptr offset, + GLsizeiptr length); + +bool ValidateGenOrDelete(Context *context, GLint n); + +bool ValidateRobustEntryPoint(ValidationContext *context, GLsizei bufSize); +bool ValidateRobustBufferSize(ValidationContext *context, GLsizei bufSize, GLsizei numParams); + +bool ValidateGetFramebufferAttachmentParameterivBase(ValidationContext *context, + GLenum target, + GLenum attachment, + GLenum pname, + GLsizei *numParams); +bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(ValidationContext *context, + GLenum target, + GLenum attachment, + GLenum pname, + GLsizei bufSize, + GLsizei *numParams); + +bool ValidateGetBufferParameterBase(ValidationContext *context, + BufferBinding target, + GLenum pname, + bool pointerVersion, + GLsizei *numParams); +bool ValidateGetBufferParameterivRobustANGLE(ValidationContext *context, + BufferBinding target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); + +bool ValidateGetBufferParameteri64vRobustANGLE(ValidationContext *context, + BufferBinding target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint64 *params); + +bool ValidateGetProgramivBase(ValidationContext *context, + GLuint program, + GLenum pname, + GLsizei *numParams); +bool ValidateGetProgramivRobustANGLE(Context *context, + GLuint program, + GLenum pname, + GLsizei bufSize, + GLsizei *numParams); + +bool ValidateGetRenderbufferParameterivBase(Context *context, + GLenum target, + GLenum pname, + GLsizei *length); +bool ValidateGetRenderbufferParameterivRobustANGLE(Context *context, + GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); + +bool ValidateGetShaderivBase(Context *context, GLuint shader, GLenum pname, GLsizei *length); +bool ValidateGetShaderivRobustANGLE(Context *context, + GLuint shader, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); + +bool ValidateGetTexParameterBase(Context *context, GLenum target, GLenum pname, GLsizei *length); +bool ValidateGetTexParameterfvRobustANGLE(Context *context, + GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params); +bool ValidateGetTexParameterivRobustANGLE(Context *context, + GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); + +template +bool ValidateTexParameterBase(Context *context, + GLenum target, + GLenum pname, + GLsizei bufSize, + const ParamType *params); +bool ValidateTexParameterfvRobustANGLE(Context *context, + GLenum target, + GLenum pname, + GLsizei bufSize, + const GLfloat *params); +bool ValidateTexParameterivRobustANGLE(Context *context, + GLenum target, + GLenum pname, + GLsizei bufSize, + const GLint *params); + +bool ValidateGetSamplerParameterfvRobustANGLE(Context *context, + GLuint sampler, + GLenum pname, + GLuint bufSize, + GLsizei *length, + GLfloat *params); +bool ValidateGetSamplerParameterivRobustANGLE(Context *context, + GLuint sampler, + GLenum pname, + GLuint bufSize, + GLsizei *length, + GLint *params); + +bool ValidateSamplerParameterfvRobustANGLE(Context *context, + GLuint sampler, + GLenum pname, + GLsizei bufSize, + const GLfloat *params); +bool ValidateSamplerParameterivRobustANGLE(Context *context, + GLuint sampler, + GLenum pname, + GLsizei bufSize, + const GLint *params); + +bool ValidateGetVertexAttribBase(Context *context, + GLuint index, + GLenum pname, + GLsizei *length, + bool pointer, + bool pureIntegerEntryPoint); +bool ValidateGetVertexAttribfvRobustANGLE(Context *context, + GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params); + +bool ValidateGetVertexAttribivRobustANGLE(Context *context, + GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); + +bool ValidateGetVertexAttribPointervRobustANGLE(Context *context, + GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **pointer); + +bool ValidateGetVertexAttribIivRobustANGLE(Context *context, + GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); + +bool ValidateGetVertexAttribIuivRobustANGLE(Context *context, + GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params); + +bool ValidateGetActiveUniformBlockivRobustANGLE(Context *context, + GLuint program, + GLuint uniformBlockIndex, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); + +bool ValidateGetInternalFormativRobustANGLE(Context *context, + GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); + +bool ValidateVertexFormatBase(ValidationContext *context, + GLuint attribIndex, + GLint size, + GLenum type, + GLboolean pureInteger); + +bool ValidateWebGLFramebufferAttachmentClearType(ValidationContext *context, + GLint drawbuffer, + const GLenum *validComponentTypes, + size_t validComponentTypeCount); + +bool ValidateRobustCompressedTexImageBase(ValidationContext *context, + GLsizei imageSize, + GLsizei dataSize); + +bool ValidateVertexAttribIndex(ValidationContext *context, GLuint index); + +bool ValidateGetActiveUniformBlockivBase(Context *context, + GLuint program, + GLuint uniformBlockIndex, + GLenum pname, + GLsizei *length); + +bool ValidateGetSamplerParameterBase(Context *context, + GLuint sampler, + GLenum pname, + GLsizei *length); + +template +bool ValidateSamplerParameterBase(Context *context, + GLuint sampler, + GLenum pname, + GLsizei bufSize, + ParamType *params); + +bool ValidateGetInternalFormativBase(Context *context, + GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei bufSize, + GLsizei *numParams); + } // namespace gl -#endif // LIBANGLE_VALIDATION_ES_H_ +#endif // LIBANGLE_VALIDATION_ES_H_ diff --git a/src/3rdparty/angle/src/libANGLE/validationES2.cpp b/src/3rdparty/angle/src/libANGLE/validationES2.cpp index 2e5b955e99..5e505aa607 100644 --- a/src/3rdparty/angle/src/libANGLE/validationES2.cpp +++ b/src/3rdparty/angle/src/libANGLE/validationES2.cpp @@ -7,16 +7,24 @@ // validationES2.cpp: Validation functions for OpenGL ES 2.0 entry point parameters #include "libANGLE/validationES2.h" -#include "libANGLE/validationES.h" -#include "libANGLE/Context.h" -#include "libANGLE/Texture.h" -#include "libANGLE/Framebuffer.h" -#include "libANGLE/Renderbuffer.h" -#include "libANGLE/formatutils.h" -#include "libANGLE/FramebufferAttachment.h" + +#include #include "common/mathutil.h" +#include "common/string_utils.h" #include "common/utilities.h" +#include "libANGLE/Context.h" +#include "libANGLE/ErrorStrings.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/Renderbuffer.h" +#include "libANGLE/Shader.h" +#include "libANGLE/Texture.h" +#include "libANGLE/Uniform.h" +#include "libANGLE/VertexArray.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/validationES.h" +#include "libANGLE/validationES3.h" namespace gl { @@ -45,9 +53,9 @@ bool IsPartialBlit(gl::Context *context, return true; } - if (context->getState().isScissorTestEnabled()) + if (context->getGLState().isScissorTestEnabled()) { - const Rectangle &scissor = context->getState().getScissor(); + const Rectangle &scissor = context->getGLState().getScissor(); return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width || scissor.height < writeSize.height; } @@ -55,417 +63,407 @@ bool IsPartialBlit(gl::Context *context, return false; } -} // anonymous namespace - -bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage, - GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - GLint border, GLenum format, GLenum type, const GLvoid *pixels) +template +bool ValidatePathInstances(gl::Context *context, + GLsizei numPaths, + const void *paths, + GLuint pathBase) { - if (!ValidTexture2DDestinationTarget(context, target)) + const auto *array = static_cast(paths); + + for (GLsizei i = 0; i < numPaths; ++i) { - context->recordError(Error(GL_INVALID_ENUM)); + const GLuint pathName = array[i] + pathBase; + if (context->hasPath(pathName) && !context->hasPathData(pathName)) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath); + return false; + } + } + return true; +} + +bool ValidateInstancedPathParameters(gl::Context *context, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum transformType, + const GLfloat *transformValues) +{ + if (!context->getExtensions().pathRendering) + { + context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available."); return false; } - if (!ValidImageSizeParameters(context, target, level, width, height, 1, isSubImage)) + if (paths == nullptr) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue() << "No path name array."); return false; } - if (level < 0 || xoffset < 0 || - std::numeric_limits::max() - xoffset < width || - std::numeric_limits::max() - yoffset < height) + if (numPaths < 0) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue() << "Invalid (negative) numPaths."); return false; } - if (!isSubImage && !isCompressed && internalformat != format) + if (!angle::IsValueInRangeForNumericType(numPaths)) { - context->recordError(Error(GL_INVALID_OPERATION)); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow); return false; } - const gl::Caps &caps = context->getCaps(); + std::uint32_t pathNameTypeSize = 0; + std::uint32_t componentCount = 0; + switch (pathNameType) + { + case GL_UNSIGNED_BYTE: + pathNameTypeSize = sizeof(GLubyte); + if (!ValidatePathInstances(context, numPaths, paths, pathBase)) + return false; + break; + + case GL_BYTE: + pathNameTypeSize = sizeof(GLbyte); + if (!ValidatePathInstances(context, numPaths, paths, pathBase)) + return false; + break; + + case GL_UNSIGNED_SHORT: + pathNameTypeSize = sizeof(GLushort); + if (!ValidatePathInstances(context, numPaths, paths, pathBase)) + return false; + break; + + case GL_SHORT: + pathNameTypeSize = sizeof(GLshort); + if (!ValidatePathInstances(context, numPaths, paths, pathBase)) + return false; + break; + + case GL_UNSIGNED_INT: + pathNameTypeSize = sizeof(GLuint); + if (!ValidatePathInstances(context, numPaths, paths, pathBase)) + return false; + break; + + case GL_INT: + pathNameTypeSize = sizeof(GLint); + if (!ValidatePathInstances(context, numPaths, paths, pathBase)) + return false; + break; + + default: + context->handleError(InvalidEnum() << "Invalid path name type."); + return false; + } + + switch (transformType) + { + case GL_NONE: + componentCount = 0; + break; + case GL_TRANSLATE_X_CHROMIUM: + case GL_TRANSLATE_Y_CHROMIUM: + componentCount = 1; + break; + case GL_TRANSLATE_2D_CHROMIUM: + componentCount = 2; + break; + case GL_TRANSLATE_3D_CHROMIUM: + componentCount = 3; + break; + case GL_AFFINE_2D_CHROMIUM: + case GL_TRANSPOSE_AFFINE_2D_CHROMIUM: + componentCount = 6; + break; + case GL_AFFINE_3D_CHROMIUM: + case GL_TRANSPOSE_AFFINE_3D_CHROMIUM: + componentCount = 12; + break; + default: + context->handleError(InvalidEnum() << "Invalid transformation."); + return false; + } + if (componentCount != 0 && transformValues == nullptr) + { + context->handleError(InvalidValue() << "No transform array given."); + return false; + } + + angle::CheckedNumeric checkedSize(0); + checkedSize += (numPaths * pathNameTypeSize); + checkedSize += (numPaths * sizeof(GLfloat) * componentCount); + if (!checkedSize.IsValid()) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow); + return false; + } + + return true; +} + +bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat) +{ + // Table 1.1 from the CHROMIUM_copy_texture spec + switch (GetUnsizedFormat(internalFormat)) + { + case GL_RED: + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_RGB: + case GL_RGBA: + case GL_RGB8: + case GL_RGBA8: + case GL_BGRA_EXT: + case GL_BGRA8_EXT: + return true; + + default: + return false; + } +} + +bool IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat) +{ + return IsValidCopyTextureSourceInternalFormatEnum(internalFormat); +} + +bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat) +{ + // Table 1.0 from the CHROMIUM_copy_texture spec + switch (internalFormat) + { + case GL_RGB: + case GL_RGBA: + case GL_RGB8: + case GL_RGBA8: + case GL_BGRA_EXT: + case GL_BGRA8_EXT: + case GL_SRGB_EXT: + case GL_SRGB_ALPHA_EXT: + case GL_R8: + case GL_R8UI: + case GL_RG8: + case GL_RG8UI: + case GL_SRGB8: + case GL_RGB565: + case GL_RGB8UI: + case GL_RGB10_A2: + case GL_SRGB8_ALPHA8: + case GL_RGB5_A1: + case GL_RGBA4: + case GL_RGBA8UI: + case GL_RGB9_E5: + case GL_R16F: + case GL_R32F: + case GL_RG16F: + case GL_RG32F: + case GL_RGB16F: + case GL_RGB32F: + case GL_RGBA16F: + case GL_RGBA32F: + case GL_R11F_G11F_B10F: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_ALPHA: + return true; + + default: + return false; + } +} + +bool IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat) +{ + return IsValidCopyTextureDestinationInternalFormatEnum(internalFormat); +} + +bool IsValidCopyTextureDestinationFormatType(Context *context, GLint internalFormat, GLenum type) +{ + if (!IsValidCopyTextureDestinationInternalFormatEnum(internalFormat)) + { + return false; + } + + if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat)) + { + context->handleError(InvalidOperation() + << "Invalid combination of type and internalFormat."); + return false; + } + + const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type); + if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions())) + { + return false; + } + + return true; +} + +bool IsValidCopyTextureDestinationTargetEnum(Context *context, GLenum target) +{ + switch (target) + { + case GL_TEXTURE_2D: + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + return true; + + case GL_TEXTURE_RECTANGLE_ANGLE: + return context->getExtensions().textureRectangle; + + default: + return false; + } +} + +bool IsValidCopyTextureDestinationTarget(Context *context, GLenum textureType, GLenum target) +{ + if (IsCubeMapTextureTarget(target)) + { + return textureType == GL_TEXTURE_CUBE_MAP; + } + else + { + return textureType == target; + } +} + +bool IsValidCopyTextureSourceTarget(Context *context, GLenum target) +{ + switch (target) + { + case GL_TEXTURE_2D: + return true; + case GL_TEXTURE_RECTANGLE_ANGLE: + return context->getExtensions().textureRectangle; + + // TODO(geofflang): accept GL_TEXTURE_EXTERNAL_OES if the texture_external extension is + // supported + + default: + return false; + } +} + +bool IsValidCopyTextureSourceLevel(Context *context, GLenum target, GLint level) +{ + if (!ValidMipLevel(context, target, level)) + { + return false; + } + + if (level > 0 && context->getClientVersion() < ES_3_0) + { + return false; + } + + return true; +} + +bool IsValidCopyTextureDestinationLevel(Context *context, + GLenum target, + GLint level, + GLsizei width, + GLsizei height) +{ + if (!ValidMipLevel(context, target, level)) + { + return false; + } + + const Caps &caps = context->getCaps(); if (target == GL_TEXTURE_2D) { if (static_cast(width) > (caps.max2DTextureSize >> level) || static_cast(height) > (caps.max2DTextureSize >> level)) { - context->recordError(Error(GL_INVALID_VALUE)); + return false; + } + } + else if (target == GL_TEXTURE_RECTANGLE_ANGLE) + { + ASSERT(level == 0); + if (static_cast(width) > caps.maxRectangleTextureSize || + static_cast(height) > caps.maxRectangleTextureSize) + { return false; } } else if (IsCubeMapTextureTarget(target)) { - if (!isSubImage && width != height) - { - context->recordError(Error(GL_INVALID_VALUE)); - return false; - } - if (static_cast(width) > (caps.maxCubeMapTextureSize >> level) || static_cast(height) > (caps.maxCubeMapTextureSize >> level)) { - context->recordError(Error(GL_INVALID_VALUE)); return false; } } - else - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - - gl::Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); - if (!texture) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - - if (isSubImage) - { - if (format != GL_NONE) - { - if (gl::GetSizedInternalFormat(format, type) != texture->getInternalFormat(target, level)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - } - - if (static_cast(xoffset + width) > texture->getWidth(target, level) || - static_cast(yoffset + height) > texture->getHeight(target, level)) - { - context->recordError(Error(GL_INVALID_VALUE)); - return false; - } - } - else - { - if (texture->getImmutableFormat()) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - } - - // Verify zero border - if (border != 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return false; - } - - if (isCompressed) - { - GLenum actualInternalFormat = - isSubImage ? texture->getInternalFormat(target, level) : internalformat; - switch (actualInternalFormat) - { - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - if (!context->getExtensions().textureCompressionDXT1) - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: - if (!context->getExtensions().textureCompressionDXT1) - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: - if (!context->getExtensions().textureCompressionDXT5) - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - case GL_ETC1_RGB8_OES: - if (!context->getExtensions().compressedETC1RGB8Texture) - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: - if (!context->getExtensions().lossyETCDecode) - { - context->recordError( - Error(GL_INVALID_ENUM, "ANGLE_lossy_etc_decode extension is not supported")); - return false; - } - break; - default: - context->recordError(Error( - GL_INVALID_ENUM, "internalformat is not a supported compressed internal format")); - return false; - } - if (!ValidCompressedImageSize(context, actualInternalFormat, width, height)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - } - else - { - // validate by itself (used as secondary key below) - switch (type) - { - case GL_UNSIGNED_BYTE: - case GL_UNSIGNED_SHORT_5_6_5: - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_5_5_5_1: - case GL_UNSIGNED_SHORT: - case GL_UNSIGNED_INT: - case GL_UNSIGNED_INT_24_8_OES: - case GL_HALF_FLOAT_OES: - case GL_FLOAT: - break; - default: - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - - // validate + combinations - // - invalid -> sets INVALID_ENUM - // - invalid + combination -> sets INVALID_OPERATION - switch (format) - { - case GL_ALPHA: - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - switch (type) - { - case GL_UNSIGNED_BYTE: - case GL_FLOAT: - case GL_HALF_FLOAT_OES: - break; - default: - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - break; - case GL_RED: - case GL_RG: - if (!context->getExtensions().textureRG) - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - switch (type) - { - case GL_UNSIGNED_BYTE: - case GL_FLOAT: - case GL_HALF_FLOAT_OES: - break; - default: - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - break; - case GL_RGB: - switch (type) - { - case GL_UNSIGNED_BYTE: - case GL_UNSIGNED_SHORT_5_6_5: - case GL_FLOAT: - case GL_HALF_FLOAT_OES: - break; - default: - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - break; - case GL_RGBA: - switch (type) - { - case GL_UNSIGNED_BYTE: - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_5_5_5_1: - case GL_FLOAT: - case GL_HALF_FLOAT_OES: - break; - default: - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - break; - case GL_BGRA_EXT: - switch (type) - { - case GL_UNSIGNED_BYTE: - break; - default: - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - break; - case GL_SRGB_EXT: - case GL_SRGB_ALPHA_EXT: - if (!context->getExtensions().sRGB) - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - switch (type) - { - case GL_UNSIGNED_BYTE: - break; - default: - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - break; - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: - case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: - break; - case GL_DEPTH_COMPONENT: - switch (type) - { - case GL_UNSIGNED_SHORT: - case GL_UNSIGNED_INT: - break; - default: - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - break; - case GL_DEPTH_STENCIL_OES: - switch (type) - { - case GL_UNSIGNED_INT_24_8_OES: - break; - default: - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - break; - default: - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - - switch (format) - { - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - if (context->getExtensions().textureCompressionDXT1) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - else - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: - if (context->getExtensions().textureCompressionDXT3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - else - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: - if (context->getExtensions().textureCompressionDXT5) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - else - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - case GL_ETC1_RGB8_OES: - if (context->getExtensions().compressedETC1RGB8Texture) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - else - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: - if (context->getExtensions().lossyETCDecode) - { - context->recordError( - Error(GL_INVALID_OPERATION, - "ETC1_RGB8_LOSSY_DECODE_ANGLE can't work with this type.")); - return false; - } - else - { - context->recordError( - Error(GL_INVALID_ENUM, "ANGLE_lossy_etc_decode extension is not supported.")); - return false; - } - break; - case GL_DEPTH_COMPONENT: - case GL_DEPTH_STENCIL_OES: - if (!context->getExtensions().depthTextures) - { - context->recordError(Error(GL_INVALID_VALUE)); - return false; - } - if (target != GL_TEXTURE_2D) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - // OES_depth_texture supports loading depth data and multiple levels, - // but ANGLE_depth_texture does not - if (pixels != NULL || level != 0) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - break; - default: - break; - } - - if (type == GL_FLOAT) - { - if (!context->getExtensions().textureFloat) - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - } - else if (type == GL_HALF_FLOAT_OES) - { - if (!context->getExtensions().textureHalfFloat) - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - } - } return true; } +bool IsValidStencilFunc(GLenum func) +{ + switch (func) + { + case GL_NEVER: + case GL_ALWAYS: + case GL_LESS: + case GL_LEQUAL: + case GL_EQUAL: + case GL_GEQUAL: + case GL_GREATER: + case GL_NOTEQUAL: + return true; + + default: + return false; + } +} + +bool IsValidStencilFace(GLenum face) +{ + switch (face) + { + case GL_FRONT: + case GL_BACK: + case GL_FRONT_AND_BACK: + return true; + + default: + return false; + } +} + +bool IsValidStencilOp(GLenum op) +{ + switch (op) + { + case GL_ZERO: + case GL_KEEP: + case GL_REPLACE: + case GL_INCR: + case GL_DECR: + case GL_INVERT: + case GL_INCR_WRAP: + case GL_DECR_WRAP: + return true; + + default: + return false; + } +} + bool ValidateES2CopyTexImageParameters(ValidationContext *context, GLenum target, GLint level, @@ -479,130 +477,126 @@ bool ValidateES2CopyTexImageParameters(ValidationContext *context, GLsizei height, GLint border) { - GLenum textureInternalFormat = GL_NONE; - if (!ValidTexture2DDestinationTarget(context, target)) { - context->recordError(Error(GL_INVALID_ENUM, "Invalid texture target")); + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget); return false; } + if (!ValidImageSizeParameters(context, target, level, width, height, 1, isSubImage)) + { + context->handleError(InvalidValue() << "Invalid texture dimensions."); + return false; + } + + Format textureFormat = Format::Invalid(); if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage, - xoffset, yoffset, 0, x, y, width, height, border, &textureInternalFormat)) + xoffset, yoffset, 0, x, y, width, height, border, + &textureFormat)) { return false; } - const gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer(); - GLenum colorbufferFormat = framebuffer->getReadColorbuffer()->getInternalFormat(); - const auto &internalFormatInfo = gl::GetInternalFormatInfo(textureInternalFormat); - GLenum textureFormat = internalFormatInfo.format; + const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer(); + GLenum colorbufferFormat = + framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat; + const auto &formatInfo = *textureFormat.info; // [OpenGL ES 2.0.24] table 3.9 if (isSubImage) { - switch (textureFormat) + switch (formatInfo.format) { - case GL_ALPHA: - if (colorbufferFormat != GL_ALPHA8_EXT && - colorbufferFormat != GL_RGBA4 && - colorbufferFormat != GL_RGB5_A1 && - colorbufferFormat != GL_RGBA8_OES) - { - context->recordError(Error(GL_INVALID_OPERATION)); + case GL_ALPHA: + if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 && + colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES && + colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat); + return false; + } + break; + case GL_LUMINANCE: + if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT && + colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES && + colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 && + colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT && + colorbufferFormat != GL_BGR5_A1_ANGLEX) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat); + return false; + } + break; + case GL_RED_EXT: + if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT && + colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES && + colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 && + colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F && + colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F && + colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT && + colorbufferFormat != GL_BGR5_A1_ANGLEX) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat); + return false; + } + break; + case GL_RG_EXT: + if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 && + colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 && + colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES && + colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F && + colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT && + colorbufferFormat != GL_BGR5_A1_ANGLEX) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat); + return false; + } + break; + case GL_RGB: + if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES && + colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 && + colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F && + colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT && + colorbufferFormat != GL_BGR5_A1_ANGLEX) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat); + return false; + } + break; + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 && + colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F && + colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat); + return false; + } + break; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + case GL_ETC1_RGB8_OES: + case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: + case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE: + case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE: + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE: + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE: + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat); return false; - } - break; - case GL_LUMINANCE: - if (colorbufferFormat != GL_R8_EXT && - colorbufferFormat != GL_RG8_EXT && - colorbufferFormat != GL_RGB565 && - colorbufferFormat != GL_RGB8_OES && - colorbufferFormat != GL_RGBA4 && - colorbufferFormat != GL_RGB5_A1 && - colorbufferFormat != GL_RGBA8_OES) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - break; - case GL_RED_EXT: - if (colorbufferFormat != GL_R8_EXT && - colorbufferFormat != GL_RG8_EXT && - colorbufferFormat != GL_RGB565 && - colorbufferFormat != GL_RGB8_OES && - colorbufferFormat != GL_RGBA4 && - colorbufferFormat != GL_RGB5_A1 && - colorbufferFormat != GL_RGBA8_OES && - colorbufferFormat != GL_R32F && - colorbufferFormat != GL_RG32F && - colorbufferFormat != GL_RGB32F && - colorbufferFormat != GL_RGBA32F) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - break; - case GL_RG_EXT: - if (colorbufferFormat != GL_RG8_EXT && - colorbufferFormat != GL_RGB565 && - colorbufferFormat != GL_RGB8_OES && - colorbufferFormat != GL_RGBA4 && - colorbufferFormat != GL_RGB5_A1 && - colorbufferFormat != GL_RGBA8_OES && - colorbufferFormat != GL_RG32F && - colorbufferFormat != GL_RGB32F && - colorbufferFormat != GL_RGBA32F) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - break; - case GL_RGB: - if (colorbufferFormat != GL_RGB565 && - colorbufferFormat != GL_RGB8_OES && - colorbufferFormat != GL_RGBA4 && - colorbufferFormat != GL_RGB5_A1 && - colorbufferFormat != GL_RGBA8_OES && - colorbufferFormat != GL_RGB32F && - colorbufferFormat != GL_RGBA32F) - { - context->recordError(Error(GL_INVALID_OPERATION)); + case GL_DEPTH_COMPONENT: + case GL_DEPTH_STENCIL_OES: + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat); return false; - } - break; - case GL_LUMINANCE_ALPHA: - case GL_RGBA: - if (colorbufferFormat != GL_RGBA4 && - colorbufferFormat != GL_RGB5_A1 && - colorbufferFormat != GL_RGBA8_OES && - colorbufferFormat != GL_RGBA32F) - { - context->recordError(Error(GL_INVALID_OPERATION)); + default: + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat); return false; - } - break; - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: - case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: - case GL_ETC1_RGB8_OES: - case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - case GL_DEPTH_COMPONENT: - case GL_DEPTH_STENCIL_OES: - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - default: - context->recordError(Error(GL_INVALID_OPERATION)); - return false; } - if (internalFormatInfo.type == GL_FLOAT && - !context->getExtensions().textureFloat) + if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat) { - context->recordError(Error(GL_INVALID_OPERATION)); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat); return false; } } @@ -610,168 +604,152 @@ bool ValidateES2CopyTexImageParameters(ValidationContext *context, { switch (internalformat) { - case GL_ALPHA: - if (colorbufferFormat != GL_ALPHA8_EXT && - colorbufferFormat != GL_RGBA4 && - colorbufferFormat != GL_RGB5_A1 && - colorbufferFormat != GL_BGRA8_EXT && - colorbufferFormat != GL_RGBA8_OES && - colorbufferFormat != GL_BGR5_A1_ANGLEX) - { - context->recordError(Error(GL_INVALID_OPERATION)); + case GL_ALPHA: + if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 && + colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT && + colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat); + return false; + } + break; + case GL_LUMINANCE: + if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT && + colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES && + colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 && + colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES && + colorbufferFormat != GL_BGR5_A1_ANGLEX) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat); + return false; + } + break; + case GL_RED_EXT: + if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT && + colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES && + colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 && + colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES && + colorbufferFormat != GL_BGR5_A1_ANGLEX) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat); + return false; + } + break; + case GL_RG_EXT: + if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 && + colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 && + colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT && + colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat); + return false; + } + break; + case GL_RGB: + if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES && + colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 && + colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES && + colorbufferFormat != GL_BGR5_A1_ANGLEX) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat); + return false; + } + break; + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 && + colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES && + colorbufferFormat != GL_BGR5_A1_ANGLEX) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat); + return false; + } + break; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + if (context->getExtensions().textureCompressionDXT1) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat); + return false; + } + else + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + break; + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + if (context->getExtensions().textureCompressionDXT3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat); + return false; + } + else + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + break; + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + if (context->getExtensions().textureCompressionDXT5) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat); + return false; + } + else + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + break; + case GL_ETC1_RGB8_OES: + if (context->getExtensions().compressedETC1RGB8Texture) + { + context->handleError(InvalidOperation()); + return false; + } + else + { + context->handleError(InvalidEnum()); + return false; + } + break; + case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: + case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE: + case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE: + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE: + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE: + if (context->getExtensions().lossyETCDecode) + { + context->handleError(InvalidOperation() + << "ETC lossy decode formats can't be copied to."); + return false; + } + else + { + context->handleError(InvalidEnum() + << "ANGLE_lossy_etc_decode extension is not supported."); + return false; + } + break; + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT32_OES: + case GL_DEPTH_STENCIL_OES: + case GL_DEPTH24_STENCIL8_OES: + if (context->getExtensions().depthTextures) + { + context->handleError(InvalidOperation()); + return false; + } + else + { + context->handleError(InvalidEnum()); + return false; + } + default: + context->handleError(InvalidEnum()); return false; - } - break; - case GL_LUMINANCE: - if (colorbufferFormat != GL_R8_EXT && - colorbufferFormat != GL_RG8_EXT && - colorbufferFormat != GL_RGB565 && - colorbufferFormat != GL_RGB8_OES && - colorbufferFormat != GL_RGBA4 && - colorbufferFormat != GL_RGB5_A1 && - colorbufferFormat != GL_BGRA8_EXT && - colorbufferFormat != GL_RGBA8_OES && - colorbufferFormat != GL_BGR5_A1_ANGLEX) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - break; - case GL_RED_EXT: - if (colorbufferFormat != GL_R8_EXT && - colorbufferFormat != GL_RG8_EXT && - colorbufferFormat != GL_RGB565 && - colorbufferFormat != GL_RGB8_OES && - colorbufferFormat != GL_RGBA4 && - colorbufferFormat != GL_RGB5_A1 && - colorbufferFormat != GL_BGRA8_EXT && - colorbufferFormat != GL_RGBA8_OES && - colorbufferFormat != GL_BGR5_A1_ANGLEX) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - break; - case GL_RG_EXT: - if (colorbufferFormat != GL_RG8_EXT && - colorbufferFormat != GL_RGB565 && - colorbufferFormat != GL_RGB8_OES && - colorbufferFormat != GL_RGBA4 && - colorbufferFormat != GL_RGB5_A1 && - colorbufferFormat != GL_BGRA8_EXT && - colorbufferFormat != GL_RGBA8_OES && - colorbufferFormat != GL_BGR5_A1_ANGLEX) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - break; - case GL_RGB: - if (colorbufferFormat != GL_RGB565 && - colorbufferFormat != GL_RGB8_OES && - colorbufferFormat != GL_RGBA4 && - colorbufferFormat != GL_RGB5_A1 && - colorbufferFormat != GL_BGRA8_EXT && - colorbufferFormat != GL_RGBA8_OES && - colorbufferFormat != GL_BGR5_A1_ANGLEX) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - break; - case GL_LUMINANCE_ALPHA: - case GL_RGBA: - if (colorbufferFormat != GL_RGBA4 && - colorbufferFormat != GL_RGB5_A1 && - colorbufferFormat != GL_BGRA8_EXT && - colorbufferFormat != GL_RGBA8_OES && - colorbufferFormat != GL_BGR5_A1_ANGLEX) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - break; - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - if (context->getExtensions().textureCompressionDXT1) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - else - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: - if (context->getExtensions().textureCompressionDXT3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - else - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: - if (context->getExtensions().textureCompressionDXT5) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - else - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - case GL_ETC1_RGB8_OES: - if (context->getExtensions().compressedETC1RGB8Texture) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - else - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: - if (context->getExtensions().lossyETCDecode) - { - context->recordError(Error(GL_INVALID_OPERATION, - "ETC1_RGB8_LOSSY_DECODE_ANGLE can't be copied to.")); - return false; - } - else - { - context->recordError( - Error(GL_INVALID_ENUM, "ANGLE_lossy_etc_decode extension is not supported.")); - return false; - } - break; - case GL_DEPTH_COMPONENT: - case GL_DEPTH_COMPONENT16: - case GL_DEPTH_COMPONENT32_OES: - case GL_DEPTH_STENCIL_OES: - case GL_DEPTH24_STENCIL8_OES: - if (context->getExtensions().depthTextures) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - else - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - default: - context->recordError(Error(GL_INVALID_ENUM)); - return false; } } @@ -779,37 +757,869 @@ bool ValidateES2CopyTexImageParameters(ValidationContext *context, return (width > 0 && height > 0); } -bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat, - GLsizei width, GLsizei height) +bool ValidCap(const Context *context, GLenum cap, bool queryOnly) { - if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP) + switch (cap) { - context->recordError(Error(GL_INVALID_ENUM)); + // EXT_multisample_compatibility + case GL_MULTISAMPLE_EXT: + case GL_SAMPLE_ALPHA_TO_ONE_EXT: + return context->getExtensions().multisampleCompatibility; + + case GL_CULL_FACE: + case GL_POLYGON_OFFSET_FILL: + case GL_SAMPLE_ALPHA_TO_COVERAGE: + case GL_SAMPLE_COVERAGE: + case GL_SCISSOR_TEST: + case GL_STENCIL_TEST: + case GL_DEPTH_TEST: + case GL_BLEND: + case GL_DITHER: + return true; + + case GL_PRIMITIVE_RESTART_FIXED_INDEX: + case GL_RASTERIZER_DISCARD: + return (context->getClientMajorVersion() >= 3); + + case GL_DEBUG_OUTPUT_SYNCHRONOUS: + case GL_DEBUG_OUTPUT: + return context->getExtensions().debug; + + case GL_BIND_GENERATES_RESOURCE_CHROMIUM: + return queryOnly && context->getExtensions().bindGeneratesResource; + + case GL_CLIENT_ARRAYS_ANGLE: + return queryOnly && context->getExtensions().clientArrays; + + case GL_FRAMEBUFFER_SRGB_EXT: + return context->getExtensions().sRGBWriteControl; + + case GL_SAMPLE_MASK: + return context->getClientVersion() >= Version(3, 1); + + case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE: + return queryOnly && context->getExtensions().robustResourceInitialization; + + default: + return false; + } +} + +// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section +// 3.1. +bool IsValidESSLCharacter(unsigned char c) +{ + // Printing characters are valid except " $ ` @ \ ' DEL. + if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' && + c != '\'') + { + return true; + } + + // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid. + if (c >= 9 && c <= 13) + { + return true; + } + + return false; +} + +bool IsValidESSLString(const char *str, size_t len) +{ + for (size_t i = 0; i < len; i++) + { + if (!IsValidESSLCharacter(str[i])) + { + return false; + } + } + + return true; +} + +bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed) +{ + enum class ParseState + { + // Have not seen an ASCII non-whitespace character yet on + // this line. Possible that we might see a preprocessor + // directive. + BEGINING_OF_LINE, + + // Have seen at least one ASCII non-whitespace character + // on this line. + MIDDLE_OF_LINE, + + // Handling a preprocessor directive. Passes through all + // characters up to the end of the line. Disables comment + // processing. + IN_PREPROCESSOR_DIRECTIVE, + + // Handling a single-line comment. The comment text is + // replaced with a single space. + IN_SINGLE_LINE_COMMENT, + + // Handling a multi-line comment. Newlines are passed + // through to preserve line numbers. + IN_MULTI_LINE_COMMENT + }; + + ParseState state = ParseState::BEGINING_OF_LINE; + size_t pos = 0; + + while (pos < len) + { + char c = str[pos]; + char next = pos + 1 < len ? str[pos + 1] : 0; + + // Check for newlines + if (c == '\n' || c == '\r') + { + if (state != ParseState::IN_MULTI_LINE_COMMENT) + { + state = ParseState::BEGINING_OF_LINE; + } + + pos++; + continue; + } + + switch (state) + { + case ParseState::BEGINING_OF_LINE: + if (c == ' ') + { + // Maintain the BEGINING_OF_LINE state until a non-space is seen + pos++; + } + else if (c == '#') + { + state = ParseState::IN_PREPROCESSOR_DIRECTIVE; + pos++; + } + else + { + // Don't advance, re-process this character with the MIDDLE_OF_LINE state + state = ParseState::MIDDLE_OF_LINE; + } + break; + + case ParseState::MIDDLE_OF_LINE: + if (c == '/' && next == '/') + { + state = ParseState::IN_SINGLE_LINE_COMMENT; + pos++; + } + else if (c == '/' && next == '*') + { + state = ParseState::IN_MULTI_LINE_COMMENT; + pos++; + } + else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r')) + { + // Skip line continuation characters + } + else if (!IsValidESSLCharacter(c)) + { + return false; + } + pos++; + break; + + case ParseState::IN_PREPROCESSOR_DIRECTIVE: + // Line-continuation characters may not be permitted. + // Otherwise, just pass it through. Do not parse comments in this state. + if (!lineContinuationAllowed && c == '\\') + { + return false; + } + pos++; + break; + + case ParseState::IN_SINGLE_LINE_COMMENT: + // Line-continuation characters are processed before comment processing. + // Advance string if a new line character is immediately behind + // line-continuation character. + if (c == '\\' && (next == '\n' || next == '\r')) + { + pos++; + } + pos++; + break; + + case ParseState::IN_MULTI_LINE_COMMENT: + if (c == '*' && next == '/') + { + state = ParseState::MIDDLE_OF_LINE; + pos++; + } + pos++; + break; + } + } + + return true; +} + +bool ValidateWebGLNamePrefix(ValidationContext *context, const GLchar *name) +{ + ASSERT(context->isWebGL()); + + // WebGL 1.0 [Section 6.16] GLSL Constructs + // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL. + if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix); + return false; + } + + return true; +} + +bool ValidateWebGLNameLength(ValidationContext *context, size_t length) +{ + ASSERT(context->isWebGL()); + + if (context->isWebGL1() && length > 256) + { + // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths + // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute + // locations. + ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded); + + return false; + } + else if (length > 1024) + { + // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of + // uniform and attribute locations. + ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded); + return false; + } + + return true; +} + +} // anonymous namespace + +bool ValidateES2TexImageParameters(Context *context, + GLenum target, + GLint level, + GLenum internalformat, + bool isCompressed, + bool isSubImage, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + GLsizei imageSize, + const void *pixels) +{ + if (!ValidTexture2DDestinationTarget(context, target)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget); + return false; + } + + if (!ValidImageSizeParameters(context, target, level, width, height, 1, isSubImage)) + { + context->handleError(InvalidValue()); + return false; + } + + if (!ValidMipLevel(context, target, level)) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel); + return false; + } + + if (xoffset < 0 || std::numeric_limits::max() - xoffset < width || + std::numeric_limits::max() - yoffset < height) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize); + return false; + } + + // From GL_CHROMIUM_color_buffer_float_rgb[a]: + // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for + // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the + // internalformat parameter and format parameter of TexImage2D must match is lifted for this + // case. + bool nonEqualFormatsAllowed = + (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) || + (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA); + + if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed) + { + context->handleError(InvalidOperation()); + return false; + } + + const gl::Caps &caps = context->getCaps(); + + if (target == GL_TEXTURE_2D) + { + if (static_cast(width) > (caps.max2DTextureSize >> level) || + static_cast(height) > (caps.max2DTextureSize >> level)) + { + context->handleError(InvalidValue()); + return false; + } + } + else if (target == GL_TEXTURE_RECTANGLE_ANGLE) + { + ASSERT(level == 0); + if (static_cast(width) > caps.maxRectangleTextureSize || + static_cast(height) > caps.maxRectangleTextureSize) + { + context->handleError(InvalidValue()); + return false; + } + if (isCompressed) + { + context->handleError(InvalidEnum() + << "Rectangle texture cannot have a compressed format."); + return false; + } + } + else if (IsCubeMapTextureTarget(target)) + { + if (!isSubImage && width != height) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions); + return false; + } + + if (static_cast(width) > (caps.maxCubeMapTextureSize >> level) || + static_cast(height) > (caps.maxCubeMapTextureSize >> level)) + { + context->handleError(InvalidValue()); + return false; + } + } + else + { + context->handleError(InvalidEnum()); + return false; + } + + gl::Texture *texture = + context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); + if (!texture) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound); + return false; + } + + if (isSubImage) + { + const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info; + if (textureInternalFormat.internalFormat == GL_NONE) + { + context->handleError(InvalidOperation() << "Texture level does not exist."); + return false; + } + + if (format != GL_NONE) + { + if (GetInternalFormatInfo(format, type).sizedInternalFormat != + textureInternalFormat.sizedInternalFormat) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch); + return false; + } + } + + if (static_cast(xoffset + width) > texture->getWidth(target, level) || + static_cast(yoffset + height) > texture->getHeight(target, level)) + { + context->handleError(InvalidValue()); + return false; + } + + if (width > 0 && height > 0 && pixels == nullptr && + context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack) == nullptr) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull); + return false; + } + } + else + { + if (texture->getImmutableFormat()) + { + context->handleError(InvalidOperation()); + return false; + } + } + + // Verify zero border + if (border != 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder); + return false; + } + + if (isCompressed) + { + GLenum actualInternalFormat = + isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat + : internalformat; + switch (actualInternalFormat) + { + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + if (!context->getExtensions().textureCompressionDXT1) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat); + return false; + } + break; + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + if (!context->getExtensions().textureCompressionDXT3) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat); + return false; + } + break; + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + if (!context->getExtensions().textureCompressionDXT5) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat); + return false; + } + break; + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + if (!context->getExtensions().textureCompressionS3TCsRGB) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat); + return false; + } + break; + case GL_ETC1_RGB8_OES: + if (!context->getExtensions().compressedETC1RGB8Texture) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat); + return false; + } + if (isSubImage) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat); + return false; + } + break; + case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: + case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE: + case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE: + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE: + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE: + if (!context->getExtensions().lossyETCDecode) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat); + return false; + } + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat); + return false; + } + + if (isSubImage) + { + if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width, + height, texture->getWidth(target, level), + texture->getHeight(target, level))) + { + context->handleError(InvalidOperation() << "Invalid compressed format dimension."); + return false; + } + + if (format != actualInternalFormat) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat); + return false; + } + } + else + { + if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height)) + { + context->handleError(InvalidOperation() << "Invalid compressed format dimension."); + return false; + } + } + } + else + { + // validate by itself (used as secondary key below) + switch (type) + { + case GL_UNSIGNED_BYTE: + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT: + case GL_UNSIGNED_INT: + case GL_UNSIGNED_INT_24_8_OES: + case GL_HALF_FLOAT_OES: + case GL_FLOAT: + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType); + return false; + } + + // validate + combinations + // - invalid -> sets INVALID_ENUM + // - invalid + combination -> sets INVALID_OPERATION + switch (format) + { + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + switch (type) + { + case GL_UNSIGNED_BYTE: + case GL_FLOAT: + case GL_HALF_FLOAT_OES: + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat); + return false; + } + break; + case GL_RED: + case GL_RG: + if (!context->getExtensions().textureRG) + { + context->handleError(InvalidEnum()); + return false; + } + switch (type) + { + case GL_UNSIGNED_BYTE: + break; + case GL_FLOAT: + case GL_HALF_FLOAT_OES: + if (!context->getExtensions().textureFloat) + { + context->handleError(InvalidEnum()); + return false; + } + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat); + return false; + } + break; + case GL_RGB: + switch (type) + { + case GL_UNSIGNED_BYTE: + case GL_UNSIGNED_SHORT_5_6_5: + case GL_FLOAT: + case GL_HALF_FLOAT_OES: + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat); + return false; + } + break; + case GL_RGBA: + switch (type) + { + case GL_UNSIGNED_BYTE: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_FLOAT: + case GL_HALF_FLOAT_OES: + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat); + return false; + } + break; + case GL_BGRA_EXT: + if (!context->getExtensions().textureFormatBGRA8888) + { + context->handleError(InvalidEnum()); + return false; + } + switch (type) + { + case GL_UNSIGNED_BYTE: + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat); + return false; + } + break; + case GL_SRGB_EXT: + case GL_SRGB_ALPHA_EXT: + if (!context->getExtensions().sRGB) + { + context->handleError(InvalidEnum()); + return false; + } + switch (type) + { + case GL_UNSIGNED_BYTE: + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat); + return false; + } + break; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are + // handled below + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + break; + case GL_DEPTH_COMPONENT: + switch (type) + { + case GL_UNSIGNED_SHORT: + case GL_UNSIGNED_INT: + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat); + return false; + } + break; + case GL_DEPTH_STENCIL_OES: + switch (type) + { + case GL_UNSIGNED_INT_24_8_OES: + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat); + return false; + } + break; + default: + context->handleError(InvalidEnum()); + return false; + } + + switch (format) + { + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + if (context->getExtensions().textureCompressionDXT1) + { + context->handleError(InvalidOperation()); + return false; + } + else + { + context->handleError(InvalidEnum()); + return false; + } + break; + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + if (context->getExtensions().textureCompressionDXT3) + { + context->handleError(InvalidOperation()); + return false; + } + else + { + context->handleError(InvalidEnum()); + return false; + } + break; + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + if (context->getExtensions().textureCompressionDXT5) + { + context->handleError(InvalidOperation()); + return false; + } + else + { + context->handleError(InvalidEnum()); + return false; + } + break; + case GL_ETC1_RGB8_OES: + if (context->getExtensions().compressedETC1RGB8Texture) + { + context->handleError(InvalidOperation()); + return false; + } + else + { + context->handleError(InvalidEnum()); + return false; + } + break; + case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: + case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE: + case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE: + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE: + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE: + if (context->getExtensions().lossyETCDecode) + { + context->handleError(InvalidOperation() + << "ETC lossy decode formats can't work with this type."); + return false; + } + else + { + context->handleError(InvalidEnum() + << "ANGLE_lossy_etc_decode extension is not supported."); + return false; + } + break; + case GL_DEPTH_COMPONENT: + case GL_DEPTH_STENCIL_OES: + if (!context->getExtensions().depthTextures) + { + context->handleError(InvalidValue()); + return false; + } + if (target != GL_TEXTURE_2D) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat); + return false; + } + // OES_depth_texture supports loading depth data and multiple levels, + // but ANGLE_depth_texture does not + if (pixels != nullptr) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull); + return false; + } + if (level != 0) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero); + return false; + } + break; + default: + break; + } + + if (!isSubImage) + { + switch (internalformat) + { + case GL_RGBA32F: + if (!context->getExtensions().colorBufferFloatRGBA) + { + context->handleError(InvalidValue() + << "Sized GL_RGBA32F internal format requires " + "GL_CHROMIUM_color_buffer_float_rgba"); + return false; + } + if (type != GL_FLOAT) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat); + return false; + } + if (format != GL_RGBA) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat); + return false; + } + break; + + case GL_RGB32F: + if (!context->getExtensions().colorBufferFloatRGB) + { + context->handleError(InvalidValue() + << "Sized GL_RGB32F internal format requires " + "GL_CHROMIUM_color_buffer_float_rgb"); + return false; + } + if (type != GL_FLOAT) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat); + return false; + } + if (format != GL_RGB) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat); + return false; + } + break; + + default: + break; + } + } + + if (type == GL_FLOAT) + { + if (!context->getExtensions().textureFloat) + { + context->handleError(InvalidEnum()); + return false; + } + } + else if (type == GL_HALF_FLOAT_OES) + { + if (!context->getExtensions().textureHalfFloat) + { + context->handleError(InvalidEnum()); + return false; + } + } + } + + GLenum sizeCheckFormat = isSubImage ? format : internalformat; + if (!ValidImageDataSize(context, target, width, height, 1, sizeCheckFormat, type, pixels, + imageSize)) + { + return false; + } + + return true; +} + +bool ValidateES2TexStorageParameters(Context *context, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP && + target != GL_TEXTURE_RECTANGLE_ANGLE) + { + context->handleError(InvalidEnum()); return false; } if (width < 1 || height < 1 || levels < 1) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } if (target == GL_TEXTURE_CUBE_MAP && width != height) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat); + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat); if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE) { - context->recordError(Error(GL_INVALID_ENUM)); + context->handleError(InvalidEnum()); return false; } @@ -817,201 +1627,187 @@ bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei le switch (target) { - case GL_TEXTURE_2D: - if (static_cast(width) > caps.max2DTextureSize || - static_cast(height) > caps.max2DTextureSize) - { - context->recordError(Error(GL_INVALID_VALUE)); + case GL_TEXTURE_2D: + if (static_cast(width) > caps.max2DTextureSize || + static_cast(height) > caps.max2DTextureSize) + { + context->handleError(InvalidValue()); + return false; + } + break; + case GL_TEXTURE_RECTANGLE_ANGLE: + if (static_cast(width) > caps.maxRectangleTextureSize || + static_cast(height) > caps.maxRectangleTextureSize || levels != 1) + { + context->handleError(InvalidValue()); + return false; + } + if (formatInfo.compressed) + { + context->handleError(InvalidEnum() + << "Rectangle texture cannot have a compressed format."); + return false; + } + break; + case GL_TEXTURE_CUBE_MAP: + if (static_cast(width) > caps.maxCubeMapTextureSize || + static_cast(height) > caps.maxCubeMapTextureSize) + { + context->handleError(InvalidValue()); + return false; + } + break; + default: + context->handleError(InvalidEnum()); return false; - } - break; - case GL_TEXTURE_CUBE_MAP: - if (static_cast(width) > caps.maxCubeMapTextureSize || - static_cast(height) > caps.maxCubeMapTextureSize) - { - context->recordError(Error(GL_INVALID_VALUE)); - return false; - } - break; - default: - context->recordError(Error(GL_INVALID_ENUM)); - return false; } if (levels != 1 && !context->getExtensions().textureNPOT) { if (!gl::isPow2(width) || !gl::isPow2(height)) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } } switch (internalformat) { - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - if (!context->getExtensions().textureCompressionDXT1) - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: - if (!context->getExtensions().textureCompressionDXT3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: - if (!context->getExtensions().textureCompressionDXT5) - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - case GL_ETC1_RGB8_OES: - if (!context->getExtensions().compressedETC1RGB8Texture) - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: - if (!context->getExtensions().lossyETCDecode) - { - context->recordError( - Error(GL_INVALID_ENUM, "ANGLE_lossy_etc_decode extension is not supported.")); - return false; - } - break; - case GL_RGBA32F_EXT: - case GL_RGB32F_EXT: - case GL_ALPHA32F_EXT: - case GL_LUMINANCE32F_EXT: - case GL_LUMINANCE_ALPHA32F_EXT: - if (!context->getExtensions().textureFloat) - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - case GL_RGBA16F_EXT: - case GL_RGB16F_EXT: - case GL_ALPHA16F_EXT: - case GL_LUMINANCE16F_EXT: - case GL_LUMINANCE_ALPHA16F_EXT: - if (!context->getExtensions().textureHalfFloat) - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - case GL_R8_EXT: - case GL_RG8_EXT: - case GL_R16F_EXT: - case GL_RG16F_EXT: - case GL_R32F_EXT: - case GL_RG32F_EXT: - if (!context->getExtensions().textureRG) - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - break; - case GL_DEPTH_COMPONENT16: - case GL_DEPTH_COMPONENT32_OES: - case GL_DEPTH24_STENCIL8_OES: - if (!context->getExtensions().depthTextures) - { - context->recordError(Error(GL_INVALID_ENUM)); - return false; - } - if (target != GL_TEXTURE_2D) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - // ANGLE_depth_texture only supports 1-level textures - if (levels != 1) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - break; - default: - break; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + if (!context->getExtensions().textureCompressionDXT1) + { + context->handleError(InvalidEnum()); + return false; + } + break; + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + if (!context->getExtensions().textureCompressionDXT3) + { + context->handleError(InvalidEnum()); + return false; + } + break; + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + if (!context->getExtensions().textureCompressionDXT5) + { + context->handleError(InvalidEnum()); + return false; + } + break; + case GL_ETC1_RGB8_OES: + if (!context->getExtensions().compressedETC1RGB8Texture) + { + context->handleError(InvalidEnum()); + return false; + } + break; + case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE: + case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE: + case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE: + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE: + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE: + if (!context->getExtensions().lossyETCDecode) + { + context->handleError(InvalidEnum() + << "ANGLE_lossy_etc_decode extension is not supported."); + return false; + } + break; + case GL_RGBA32F_EXT: + case GL_RGB32F_EXT: + case GL_ALPHA32F_EXT: + case GL_LUMINANCE32F_EXT: + case GL_LUMINANCE_ALPHA32F_EXT: + if (!context->getExtensions().textureFloat) + { + context->handleError(InvalidEnum()); + return false; + } + break; + case GL_RGBA16F_EXT: + case GL_RGB16F_EXT: + case GL_ALPHA16F_EXT: + case GL_LUMINANCE16F_EXT: + case GL_LUMINANCE_ALPHA16F_EXT: + if (!context->getExtensions().textureHalfFloat) + { + context->handleError(InvalidEnum()); + return false; + } + break; + case GL_R8_EXT: + case GL_RG8_EXT: + if (!context->getExtensions().textureRG) + { + context->handleError(InvalidEnum()); + return false; + } + break; + case GL_R16F_EXT: + case GL_RG16F_EXT: + if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat) + { + context->handleError(InvalidEnum()); + return false; + } + break; + case GL_R32F_EXT: + case GL_RG32F_EXT: + if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat) + { + context->handleError(InvalidEnum()); + return false; + } + break; + case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT32_OES: + case GL_DEPTH24_STENCIL8_OES: + if (!context->getExtensions().depthTextures) + { + context->handleError(InvalidEnum()); + return false; + } + if (target != GL_TEXTURE_2D) + { + context->handleError(InvalidOperation()); + return false; + } + // ANGLE_depth_texture only supports 1-level textures + if (levels != 1) + { + context->handleError(InvalidOperation()); + return false; + } + break; + default: + break; } gl::Texture *texture = context->getTargetTexture(target); if (!texture || texture->id() == 0) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } if (texture->getImmutableFormat()) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } return true; } -// check for combinations of format and type that are valid for ReadPixels -bool ValidES2ReadFormatType(Context *context, GLenum format, GLenum type) -{ - switch (format) - { - case GL_RGBA: - switch (type) - { - case GL_UNSIGNED_BYTE: - break; - default: - return false; - } - break; - case GL_BGRA_EXT: - switch (type) - { - case GL_UNSIGNED_BYTE: - case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: - case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: - break; - default: - return false; - } - break; - case GL_RG_EXT: - case GL_RED_EXT: - if (!context->getExtensions().textureRG) - { - return false; - } - switch (type) - { - case GL_UNSIGNED_BYTE: - break; - default: - return false; - } - break; - - default: - return false; - } - return true; -} - -bool ValidateDiscardFramebufferEXT(Context *context, GLenum target, GLsizei numAttachments, +bool ValidateDiscardFramebufferEXT(Context *context, + GLenum target, + GLsizei numAttachments, const GLenum *attachments) { if (!context->getExtensions().discardFramebuffer) { - context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); return false; } @@ -1019,55 +1815,57 @@ bool ValidateDiscardFramebufferEXT(Context *context, GLenum target, GLsizei numA switch (target) { - case GL_FRAMEBUFFER: - defaultFramebuffer = (context->getState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0); - break; - default: - context->recordError(Error(GL_INVALID_ENUM, "Invalid framebuffer target")); - return false; + case GL_FRAMEBUFFER: + defaultFramebuffer = + (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0); + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget); + return false; } - return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments, defaultFramebuffer); + return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments, + defaultFramebuffer); } bool ValidateBindVertexArrayOES(Context *context, GLuint array) { if (!context->getExtensions().vertexArrayObject) { - context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); return false; } return ValidateBindVertexArrayBase(context, array); } -bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n) +bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays) { if (!context->getExtensions().vertexArrayObject) { - context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); return false; } - return ValidateDeleteVertexArraysBase(context, n); + return ValidateGenOrDelete(context, n); } -bool ValidateGenVertexArraysOES(Context *context, GLsizei n) +bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays) { if (!context->getExtensions().vertexArrayObject) { - context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); return false; } - return ValidateGenVertexArraysBase(context, n); + return ValidateGenOrDelete(context, n); } -bool ValidateIsVertexArrayOES(Context *context) +bool ValidateIsVertexArrayOES(Context *context, GLuint array) { if (!context->getExtensions().vertexArrayObject) { - context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); return false; } @@ -1082,7 +1880,7 @@ bool ValidateProgramBinaryOES(Context *context, { if (!context->getExtensions().getProgramBinary) { - context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); return false; } @@ -1098,7 +1896,7 @@ bool ValidateGetProgramBinaryOES(Context *context, { if (!context->getExtensions().getProgramBinary) { - context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); return false; } @@ -1170,25 +1968,25 @@ bool ValidateDebugMessageControlKHR(Context *context, { if (!context->getExtensions().debug) { - context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); return false; } if (!ValidDebugSource(source, false) && source != GL_DONT_CARE) { - context->recordError(Error(GL_INVALID_ENUM, "Invalid debug source.")); + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource); return false; } if (!ValidDebugType(type) && type != GL_DONT_CARE) { - context->recordError(Error(GL_INVALID_ENUM, "Invalid debug type.")); + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType); return false; } if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE) { - context->recordError(Error(GL_INVALID_ENUM, "Invalid debug severity.")); + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity); return false; } @@ -1196,17 +1994,17 @@ bool ValidateDebugMessageControlKHR(Context *context, { if (source == GL_DONT_CARE || type == GL_DONT_CARE) { - context->recordError(Error( - GL_INVALID_OPERATION, - "If count is greater than zero, source and severity cannot be GL_DONT_CARE.")); + context->handleError( + InvalidOperation() + << "If count is greater than zero, source and severity cannot be GL_DONT_CARE."); return false; } if (severity != GL_DONT_CARE) { - context->recordError( - Error(GL_INVALID_OPERATION, - "If count is greater than zero, severity must be GL_DONT_CARE.")); + context->handleError( + InvalidOperation() + << "If count is greater than zero, severity must be GL_DONT_CARE."); return false; } } @@ -1224,11 +2022,11 @@ bool ValidateDebugMessageInsertKHR(Context *context, { if (!context->getExtensions().debug) { - context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); return false; } - if (!context->getState().getDebug().isOutputEnabled()) + if (!context->getGLState().getDebug().isOutputEnabled()) { // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do // not generate an error. @@ -1237,27 +2035,27 @@ bool ValidateDebugMessageInsertKHR(Context *context, if (!ValidDebugSeverity(severity)) { - context->recordError(Error(GL_INVALID_ENUM, "Invalid debug severity.")); + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource); return false; } if (!ValidDebugType(type)) { - context->recordError(Error(GL_INVALID_ENUM, "Invalid debug type.")); + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType); return false; } if (!ValidDebugSource(source, true)) { - context->recordError(Error(GL_INVALID_ENUM, "Invalid debug source.")); + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource); return false; } size_t messageLength = (length < 0) ? strlen(buf) : length; if (messageLength > context->getExtensions().maxDebugMessageLength) { - context->recordError( - Error(GL_INVALID_VALUE, "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.")); + context->handleError(InvalidValue() + << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH."); return false; } @@ -1270,7 +2068,7 @@ bool ValidateDebugMessageCallbackKHR(Context *context, { if (!context->getExtensions().debug) { - context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); return false; } @@ -1289,14 +2087,13 @@ bool ValidateGetDebugMessageLogKHR(Context *context, { if (!context->getExtensions().debug) { - context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); return false; } if (bufSize < 0 && messageLog != nullptr) { - context->recordError( - Error(GL_INVALID_VALUE, "bufSize must be positive if messageLog is not null.")); + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize); return false; } @@ -1311,30 +2108,30 @@ bool ValidatePushDebugGroupKHR(Context *context, { if (!context->getExtensions().debug) { - context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); return false; } if (!ValidDebugSource(source, true)) { - context->recordError(Error(GL_INVALID_ENUM, "Invalid debug source.")); + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource); return false; } size_t messageLength = (length < 0) ? strlen(message) : length; if (messageLength > context->getExtensions().maxDebugMessageLength) { - context->recordError( - Error(GL_INVALID_VALUE, "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.")); + context->handleError(InvalidValue() + << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH."); return false; } - size_t currentStackSize = context->getState().getDebug().getGroupStackDepth(); + size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth(); if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth) { - context->recordError( - Error(GL_STACK_OVERFLOW, - "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.")); + context + ->handleError(StackOverflow() + << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups."); return false; } @@ -1345,14 +2142,14 @@ bool ValidatePopDebugGroupKHR(Context *context) { if (!context->getExtensions().debug) { - context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); return false; } - size_t currentStackSize = context->getState().getDebug().getGroupStackDepth(); + size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth(); if (currentStackSize <= 1) { - context->recordError(Error(GL_STACK_UNDERFLOW, "Cannot pop the default debug group.")); + context->handleError(StackUnderflow() << "Cannot pop the default debug group."); return false; } @@ -1366,7 +2163,7 @@ static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, case GL_BUFFER: if (context->getBuffer(name) == nullptr) { - context->recordError(Error(GL_INVALID_VALUE, "name is not a valid buffer.")); + context->handleError(InvalidValue() << "name is not a valid buffer."); return false; } return true; @@ -1374,7 +2171,7 @@ static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, case GL_SHADER: if (context->getShader(name) == nullptr) { - context->recordError(Error(GL_INVALID_VALUE, "name is not a valid shader.")); + context->handleError(InvalidValue() << "name is not a valid shader."); return false; } return true; @@ -1382,7 +2179,7 @@ static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, case GL_PROGRAM: if (context->getProgram(name) == nullptr) { - context->recordError(Error(GL_INVALID_VALUE, "name is not a valid program.")); + context->handleError(InvalidValue() << "name is not a valid program."); return false; } return true; @@ -1390,7 +2187,7 @@ static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, case GL_VERTEX_ARRAY: if (context->getVertexArray(name) == nullptr) { - context->recordError(Error(GL_INVALID_VALUE, "name is not a valid vertex array.")); + context->handleError(InvalidValue() << "name is not a valid vertex array."); return false; } return true; @@ -1398,7 +2195,7 @@ static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, case GL_QUERY: if (context->getQuery(name) == nullptr) { - context->recordError(Error(GL_INVALID_VALUE, "name is not a valid query.")); + context->handleError(InvalidValue() << "name is not a valid query."); return false; } return true; @@ -1406,8 +2203,7 @@ static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, case GL_TRANSFORM_FEEDBACK: if (context->getTransformFeedback(name) == nullptr) { - context->recordError( - Error(GL_INVALID_VALUE, "name is not a valid transform feedback.")); + context->handleError(InvalidValue() << "name is not a valid transform feedback."); return false; } return true; @@ -1415,7 +2211,7 @@ static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, case GL_SAMPLER: if (context->getSampler(name) == nullptr) { - context->recordError(Error(GL_INVALID_VALUE, "name is not a valid sampler.")); + context->handleError(InvalidValue() << "name is not a valid sampler."); return false; } return true; @@ -1423,7 +2219,7 @@ static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, case GL_TEXTURE: if (context->getTexture(name) == nullptr) { - context->recordError(Error(GL_INVALID_VALUE, "name is not a valid texture.")); + context->handleError(InvalidValue() << "name is not a valid texture."); return false; } return true; @@ -1431,7 +2227,7 @@ static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, case GL_RENDERBUFFER: if (context->getRenderbuffer(name) == nullptr) { - context->recordError(Error(GL_INVALID_VALUE, "name is not a valid renderbuffer.")); + context->handleError(InvalidValue() << "name is not a valid renderbuffer."); return false; } return true; @@ -1439,15 +2235,38 @@ static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, case GL_FRAMEBUFFER: if (context->getFramebuffer(name) == nullptr) { - context->recordError(Error(GL_INVALID_VALUE, "name is not a valid framebuffer.")); + context->handleError(InvalidValue() << "name is not a valid framebuffer."); return false; } return true; default: - context->recordError(Error(GL_INVALID_ENUM, "Invalid identifier.")); + context->handleError(InvalidEnum() << "Invalid identifier."); return false; } +} + +static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label) +{ + size_t labelLength = 0; + + if (length < 0) + { + if (label != nullptr) + { + labelLength = strlen(label); + } + } + else + { + labelLength = static_cast(length); + } + + if (labelLength > context->getExtensions().maxLabelLength) + { + context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH."); + return false; + } return true; } @@ -1460,7 +2279,7 @@ bool ValidateObjectLabelKHR(Context *context, { if (!context->getExtensions().debug) { - context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); return false; } @@ -1469,11 +2288,8 @@ bool ValidateObjectLabelKHR(Context *context, return false; } - size_t labelLength = (length < 0) ? strlen(label) : length; - if (labelLength > context->getExtensions().maxLabelLength) + if (!ValidateLabelLength(context, length, label)) { - context->recordError( - Error(GL_INVALID_VALUE, "Label length is larger than GL_MAX_LABEL_LENGTH.")); return false; } @@ -1489,13 +2305,13 @@ bool ValidateGetObjectLabelKHR(Context *context, { if (!context->getExtensions().debug) { - context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); return false; } if (bufSize < 0) { - context->recordError(Error(GL_INVALID_VALUE, "bufSize cannot be negative.")); + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize); return false; } @@ -1504,15 +2320,14 @@ bool ValidateGetObjectLabelKHR(Context *context, return false; } - // Can no-op if bufSize is zero. - return bufSize > 0; + return true; } static bool ValidateObjectPtrName(Context *context, const void *ptr) { - if (context->getFenceSync(reinterpret_cast(const_cast(ptr))) == nullptr) + if (context->getSync(reinterpret_cast(const_cast(ptr))) == nullptr) { - context->recordError(Error(GL_INVALID_VALUE, "name is not a valid sync.")); + context->handleError(InvalidValue() << "name is not a valid sync."); return false; } @@ -1526,7 +2341,7 @@ bool ValidateObjectPtrLabelKHR(Context *context, { if (!context->getExtensions().debug) { - context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); return false; } @@ -1535,11 +2350,8 @@ bool ValidateObjectPtrLabelKHR(Context *context, return false; } - size_t labelLength = (length < 0) ? strlen(label) : length; - if (labelLength > context->getExtensions().maxLabelLength) + if (!ValidateLabelLength(context, length, label)) { - context->recordError( - Error(GL_INVALID_VALUE, "Label length is larger than GL_MAX_LABEL_LENGTH.")); return false; } @@ -1554,13 +2366,13 @@ bool ValidateGetObjectPtrLabelKHR(Context *context, { if (!context->getExtensions().debug) { - context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); return false; } if (bufSize < 0) { - context->recordError(Error(GL_INVALID_VALUE, "bufSize cannot be negative.")); + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize); return false; } @@ -1569,15 +2381,14 @@ bool ValidateGetObjectPtrLabelKHR(Context *context, return false; } - // Can no-op if bufSize is zero. - return bufSize > 0; + return true; } bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params) { if (!context->getExtensions().debug) { - context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); return false; } @@ -1589,7 +2400,7 @@ bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params) break; default: - context->recordError(Error(GL_INVALID_ENUM, "Invalid pname.")); + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); return false; } @@ -1610,27 +2421,27 @@ bool ValidateBlitFramebufferANGLE(Context *context, { if (!context->getExtensions().framebufferBlit) { - context->recordError(Error(GL_INVALID_OPERATION, "Blit extension not available.")); + context->handleError(InvalidOperation() << "Blit extension not available."); return false; } if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0) { // TODO(jmadill): Determine if this should be available on other implementations. - context->recordError(Error( - GL_INVALID_OPERATION, - "Scaling and flipping in BlitFramebufferANGLE not supported by this implementation.")); + context->handleError(InvalidOperation() << "Scaling and flipping in " + "BlitFramebufferANGLE not supported by this " + "implementation."); return false; } if (filter == GL_LINEAR) { - context->recordError(Error(GL_INVALID_ENUM, "Linear blit not supported in this extension")); + context->handleError(InvalidEnum() << "Linear blit not supported in this extension"); return false; } - const Framebuffer *readFramebuffer = context->getState().getReadFramebuffer(); - const Framebuffer *drawFramebuffer = context->getState().getDrawFramebuffer(); + Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer(); + Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer(); if (mask & GL_COLOR_BUFFER_BIT) { @@ -1644,7 +2455,7 @@ bool ValidateBlitFramebufferANGLE(Context *context, readColorAttachment->type() != GL_RENDERBUFFER && readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } @@ -1660,26 +2471,25 @@ bool ValidateBlitFramebufferANGLE(Context *context, attachment->type() != GL_RENDERBUFFER && attachment->type() != GL_FRAMEBUFFER_DEFAULT) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } // Return an error if the destination formats do not match - if (attachment->getInternalFormat() != readColorAttachment->getInternalFormat()) + if (!Format::EquivalentForBlit(attachment->getFormat(), + readColorAttachment->getFormat())) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } } } - int readSamples = readFramebuffer->getSamples(context->getData()); - - if (readSamples != 0 && + if (readFramebuffer->getSamples(context) != 0 && IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1)) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } } @@ -1702,16 +2512,15 @@ bool ValidateBlitFramebufferANGLE(Context *context, dstX0, dstY0, dstX1, dstY1)) { // only whole-buffer copies are permitted - ERR( - "Only whole-buffer depth and stencil blits are supported by this " - "implementation."); - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation() << "Only whole-buffer depth and " + "stencil blits are supported by " + "this extension."); return false; } if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } } @@ -1724,21 +2533,35 @@ bool ValidateBlitFramebufferANGLE(Context *context, bool ValidateClear(ValidationContext *context, GLbitfield mask) { - const Framebuffer *framebufferObject = context->getState().getDrawFramebuffer(); - ASSERT(framebufferObject); - - if (framebufferObject->checkStatus(context->getData()) != GL_FRAMEBUFFER_COMPLETE) + Framebuffer *fbo = context->getGLState().getDrawFramebuffer(); + if (fbo->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE) { - context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION)); + context->handleError(InvalidFramebufferOperation()); return false; } if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0) { - context->recordError(Error(GL_INVALID_VALUE)); + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask); return false; } + if (context->getExtensions().webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0) + { + constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED, + GL_SIGNED_NORMALIZED}; + + for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount(); + drawBufferIdx++) + { + if (!ValidateWebGLFramebufferAttachmentClearType( + context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes))) + { + return false; + } + } + } + return true; } @@ -1746,11 +2569,3783 @@ bool ValidateDrawBuffersEXT(ValidationContext *context, GLsizei n, const GLenum { if (!context->getExtensions().drawBuffers) { - context->recordError(Error(GL_INVALID_OPERATION, "Extension not supported.")); + context->handleError(InvalidOperation() << "Extension not supported."); return false; } return ValidateDrawBuffersBase(context, n, bufs); } +bool ValidateTexImage2D(Context *context, + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + const void *pixels) +{ + if (context->getClientMajorVersion() < 3) + { + return ValidateES2TexImageParameters(context, target, level, internalformat, false, false, + 0, 0, width, height, border, format, type, -1, pixels); + } + + ASSERT(context->getClientMajorVersion() >= 3); + return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0, + 0, 0, width, height, 1, border, format, type, -1, + pixels); +} + +bool ValidateTexImage2DRobust(Context *context, + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (context->getClientMajorVersion() < 3) + { + return ValidateES2TexImageParameters(context, target, level, internalformat, false, false, + 0, 0, width, height, border, format, type, bufSize, + pixels); + } + + ASSERT(context->getClientMajorVersion() >= 3); + return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0, + 0, 0, width, height, 1, border, format, type, bufSize, + pixels); +} + +bool ValidateTexSubImage2D(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void *pixels) +{ + + if (context->getClientMajorVersion() < 3) + { + return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset, + yoffset, width, height, 0, format, type, -1, pixels); + } + + ASSERT(context->getClientMajorVersion() >= 3); + return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset, + yoffset, 0, width, height, 1, 0, format, type, -1, + pixels); +} + +bool ValidateTexSubImage2DRobustANGLE(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (context->getClientMajorVersion() < 3) + { + return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset, + yoffset, width, height, 0, format, type, bufSize, + pixels); + } + + ASSERT(context->getClientMajorVersion() >= 3); + return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset, + yoffset, 0, width, height, 1, 0, format, type, bufSize, + pixels); +} + +bool ValidateCompressedTexImage2D(Context *context, + GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + const void *data) +{ + if (context->getClientMajorVersion() < 3) + { + if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0, + 0, width, height, border, GL_NONE, GL_NONE, -1, data)) + { + return false; + } + } + else + { + ASSERT(context->getClientMajorVersion() >= 3); + if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0, + 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1, + data)) + { + return false; + } + } + + const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat); + auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1)); + if (blockSizeOrErr.isError()) + { + context->handleError(blockSizeOrErr.getError()); + return false; + } + + if (imageSize < 0 || static_cast(imageSize) != blockSizeOrErr.getResult()) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData); + return false; + } + + if (target == GL_TEXTURE_RECTANGLE_ANGLE) + { + context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format."); + return false; + } + + return true; +} + +bool ValidateCompressedTexImage2DRobustANGLE(Context *context, + GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + GLsizei dataSize, + const void *data) +{ + if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize)) + { + return false; + } + + return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height, + border, imageSize, data); +} +bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + GLsizei dataSize, + const void *data) +{ + if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize)) + { + return false; + } + + return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height, + format, imageSize, data); +} + +bool ValidateCompressedTexSubImage2D(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const void *data) +{ + if (context->getClientMajorVersion() < 3) + { + if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset, + yoffset, width, height, 0, format, GL_NONE, -1, data)) + { + return false; + } + } + else + { + ASSERT(context->getClientMajorVersion() >= 3); + if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset, + yoffset, 0, width, height, 1, 0, format, GL_NONE, -1, + data)) + { + return false; + } + } + + const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format); + auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1)); + if (blockSizeOrErr.isError()) + { + context->handleError(blockSizeOrErr.getError()); + return false; + } + + if (imageSize < 0 || static_cast(imageSize) != blockSizeOrErr.getResult()) + { + context->handleError(InvalidValue()); + return false; + } + + return true; +} + +bool ValidateGetBufferPointervOES(Context *context, + BufferBinding target, + GLenum pname, + void **params) +{ + return ValidateGetBufferPointervBase(context, target, pname, nullptr, params); +} + +bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access) +{ + if (!context->getExtensions().mapBuffer) + { + context->handleError(InvalidOperation() << "Map buffer extension not available."); + return false; + } + + if (!ValidBufferType(context, target)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes); + return false; + } + + Buffer *buffer = context->getGLState().getTargetBuffer(target); + + if (buffer == nullptr) + { + context->handleError(InvalidOperation() << "Attempted to map buffer object zero."); + return false; + } + + if (access != GL_WRITE_ONLY_OES) + { + context->handleError(InvalidEnum() << "Non-write buffer mapping not supported."); + return false; + } + + if (buffer->isMapped()) + { + context->handleError(InvalidOperation() << "Buffer is already mapped."); + return false; + } + + return ValidateMapBufferBase(context, target); +} + +bool ValidateUnmapBufferOES(Context *context, BufferBinding target) +{ + if (!context->getExtensions().mapBuffer) + { + context->handleError(InvalidOperation() << "Map buffer extension not available."); + return false; + } + + return ValidateUnmapBufferBase(context, target); +} + +bool ValidateMapBufferRangeEXT(Context *context, + BufferBinding target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access) +{ + if (!context->getExtensions().mapBufferRange) + { + context->handleError(InvalidOperation() << "Map buffer range extension not available."); + return false; + } + + return ValidateMapBufferRangeBase(context, target, offset, length, access); +} + +bool ValidateMapBufferBase(Context *context, BufferBinding target) +{ + Buffer *buffer = context->getGLState().getTargetBuffer(target); + ASSERT(buffer != nullptr); + + // Check if this buffer is currently being used as a transform feedback output buffer + TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback(); + if (transformFeedback != nullptr && transformFeedback->isActive()) + { + for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++) + { + const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i); + if (transformFeedbackBuffer.get() == buffer) + { + context->handleError(InvalidOperation() + << "Buffer is currently bound for transform feedback."); + return false; + } + } + } + + return true; +} + +bool ValidateFlushMappedBufferRangeEXT(Context *context, + BufferBinding target, + GLintptr offset, + GLsizeiptr length) +{ + if (!context->getExtensions().mapBufferRange) + { + context->handleError(InvalidOperation() << "Map buffer range extension not available."); + return false; + } + + return ValidateFlushMappedBufferRangeBase(context, target, offset, length); +} + +bool ValidateBindTexture(Context *context, GLenum target, GLuint texture) +{ + Texture *textureObject = context->getTexture(texture); + if (textureObject && textureObject->getTarget() != target && texture != 0) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch); + return false; + } + + if (!context->getGLState().isBindGeneratesResourceEnabled() && + !context->isTextureGenerated(texture)) + { + context->handleError(InvalidOperation() << "Texture was not generated"); + return false; + } + + switch (target) + { + case GL_TEXTURE_2D: + case GL_TEXTURE_CUBE_MAP: + break; + + case GL_TEXTURE_RECTANGLE_ANGLE: + if (!context->getExtensions().textureRectangle) + { + context->handleError(InvalidEnum() + << "Context does not support GL_ANGLE_texture_rectangle"); + return false; + } + break; + + case GL_TEXTURE_3D: + case GL_TEXTURE_2D_ARRAY: + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required); + return false; + } + break; + + case GL_TEXTURE_2D_MULTISAMPLE: + if (context->getClientVersion() < Version(3, 1)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required); + return false; + } + break; + + case GL_TEXTURE_EXTERNAL_OES: + if (!context->getExtensions().eglImageExternal && + !context->getExtensions().eglStreamConsumerExternal) + { + context->handleError(InvalidEnum() << "External texture extension not enabled"); + return false; + } + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget); + return false; + } + + return true; +} + +bool ValidateBindUniformLocationCHROMIUM(Context *context, + GLuint program, + GLint location, + const GLchar *name) +{ + if (!context->getExtensions().bindUniformLocation) + { + context->handleError(InvalidOperation() + << "GL_CHROMIUM_bind_uniform_location is not available."); + return false; + } + + Program *programObject = GetValidProgram(context, program); + if (!programObject) + { + return false; + } + + if (location < 0) + { + context->handleError(InvalidValue() << "Location cannot be less than 0."); + return false; + } + + const Caps &caps = context->getCaps(); + if (static_cast(location) >= + (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4) + { + context->handleError(InvalidValue() << "Location must be less than " + "(MAX_VERTEX_UNIFORM_VECTORS + " + "MAX_FRAGMENT_UNIFORM_VECTORS) * 4"); + return false; + } + + // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for + // shader-related entry points + if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name))) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters); + return false; + } + + if (strncmp(name, "gl_", 3) == 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL); + return false; + } + + return true; +} + +bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components) +{ + if (!context->getExtensions().framebufferMixedSamples) + { + context->handleError(InvalidOperation() + << "GL_CHROMIUM_framebuffer_mixed_samples is not available."); + return false; + } + switch (components) + { + case GL_RGB: + case GL_RGBA: + case GL_ALPHA: + case GL_NONE: + break; + default: + context->handleError( + InvalidEnum() + << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE."); + return false; + } + + return true; +} + +// CHROMIUM_path_rendering + +bool ValidateMatrix(Context *context, GLenum matrixMode, const GLfloat *matrix) +{ + if (!context->getExtensions().pathRendering) + { + context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available."); + return false; + } + if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode); + return false; + } + if (matrix == nullptr) + { + context->handleError(InvalidOperation() << "Invalid matrix."); + return false; + } + return true; +} + +bool ValidateMatrixMode(Context *context, GLenum matrixMode) +{ + if (!context->getExtensions().pathRendering) + { + context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available."); + return false; + } + if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode); + return false; + } + return true; +} + +bool ValidateGenPaths(Context *context, GLsizei range) +{ + if (!context->getExtensions().pathRendering) + { + context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available."); + return false; + } + + // range = 0 is undefined in NV_path_rendering. + // we add stricter semantic check here and require a non zero positive range. + if (range <= 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange); + return false; + } + + if (!angle::IsValueInRangeForNumericType(range)) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow); + return false; + } + + return true; +} + +bool ValidateDeletePaths(Context *context, GLuint path, GLsizei range) +{ + if (!context->getExtensions().pathRendering) + { + context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available."); + return false; + } + + // range = 0 is undefined in NV_path_rendering. + // we add stricter semantic check here and require a non zero positive range. + if (range <= 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange); + return false; + } + + angle::CheckedNumeric checkedRange(path); + checkedRange += range; + + if (!angle::IsValueInRangeForNumericType(range) || !checkedRange.IsValid()) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow); + return false; + } + return true; +} + +bool ValidatePathCommands(Context *context, + GLuint path, + GLsizei numCommands, + const GLubyte *commands, + GLsizei numCoords, + GLenum coordType, + const void *coords) +{ + if (!context->getExtensions().pathRendering) + { + context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available."); + return false; + } + if (!context->hasPath(path)) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath); + return false; + } + + if (numCommands < 0) + { + context->handleError(InvalidValue() << "Invalid number of commands."); + return false; + } + else if (numCommands > 0) + { + if (!commands) + { + context->handleError(InvalidValue() << "No commands array given."); + return false; + } + } + + if (numCoords < 0) + { + context->handleError(InvalidValue() << "Invalid number of coordinates."); + return false; + } + else if (numCoords > 0) + { + if (!coords) + { + context->handleError(InvalidValue() << "No coordinate array given."); + return false; + } + } + + std::uint32_t coordTypeSize = 0; + switch (coordType) + { + case GL_BYTE: + coordTypeSize = sizeof(GLbyte); + break; + + case GL_UNSIGNED_BYTE: + coordTypeSize = sizeof(GLubyte); + break; + + case GL_SHORT: + coordTypeSize = sizeof(GLshort); + break; + + case GL_UNSIGNED_SHORT: + coordTypeSize = sizeof(GLushort); + break; + + case GL_FLOAT: + coordTypeSize = sizeof(GLfloat); + break; + + default: + context->handleError(InvalidEnum() << "Invalid coordinate type."); + return false; + } + + angle::CheckedNumeric checkedSize(numCommands); + checkedSize += (coordTypeSize * numCoords); + if (!checkedSize.IsValid()) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow); + return false; + } + + // early return skips command data validation when it doesn't exist. + if (!commands) + return true; + + GLsizei expectedNumCoords = 0; + for (GLsizei i = 0; i < numCommands; ++i) + { + switch (commands[i]) + { + case GL_CLOSE_PATH_CHROMIUM: // no coordinates. + break; + case GL_MOVE_TO_CHROMIUM: + case GL_LINE_TO_CHROMIUM: + expectedNumCoords += 2; + break; + case GL_QUADRATIC_CURVE_TO_CHROMIUM: + expectedNumCoords += 4; + break; + case GL_CUBIC_CURVE_TO_CHROMIUM: + expectedNumCoords += 6; + break; + case GL_CONIC_CURVE_TO_CHROMIUM: + expectedNumCoords += 5; + break; + default: + context->handleError(InvalidEnum() << "Invalid command."); + return false; + } + } + if (expectedNumCoords != numCoords) + { + context->handleError(InvalidValue() << "Invalid number of coordinates."); + return false; + } + + return true; +} + +bool ValidateSetPathParameter(Context *context, GLuint path, GLenum pname, GLfloat value) +{ + if (!context->getExtensions().pathRendering) + { + context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available."); + return false; + } + if (!context->hasPath(path)) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath); + return false; + } + + switch (pname) + { + case GL_PATH_STROKE_WIDTH_CHROMIUM: + if (value < 0.0f) + { + context->handleError(InvalidValue() << "Invalid stroke width."); + return false; + } + break; + case GL_PATH_END_CAPS_CHROMIUM: + switch (static_cast(value)) + { + case GL_FLAT_CHROMIUM: + case GL_SQUARE_CHROMIUM: + case GL_ROUND_CHROMIUM: + break; + default: + context->handleError(InvalidEnum() << "Invalid end caps."); + return false; + } + break; + case GL_PATH_JOIN_STYLE_CHROMIUM: + switch (static_cast(value)) + { + case GL_MITER_REVERT_CHROMIUM: + case GL_BEVEL_CHROMIUM: + case GL_ROUND_CHROMIUM: + break; + default: + context->handleError(InvalidEnum() << "Invalid join style."); + return false; + } + case GL_PATH_MITER_LIMIT_CHROMIUM: + if (value < 0.0f) + { + context->handleError(InvalidValue() << "Invalid miter limit."); + return false; + } + break; + + case GL_PATH_STROKE_BOUND_CHROMIUM: + // no errors, only clamping. + break; + + default: + context->handleError(InvalidEnum() << "Invalid path parameter."); + return false; + } + return true; +} + +bool ValidateGetPathParameter(Context *context, GLuint path, GLenum pname, GLfloat *value) +{ + if (!context->getExtensions().pathRendering) + { + context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available."); + return false; + } + + if (!context->hasPath(path)) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath); + return false; + } + if (!value) + { + context->handleError(InvalidValue() << "No value array."); + return false; + } + + switch (pname) + { + case GL_PATH_STROKE_WIDTH_CHROMIUM: + case GL_PATH_END_CAPS_CHROMIUM: + case GL_PATH_JOIN_STYLE_CHROMIUM: + case GL_PATH_MITER_LIMIT_CHROMIUM: + case GL_PATH_STROKE_BOUND_CHROMIUM: + break; + + default: + context->handleError(InvalidEnum() << "Invalid path parameter."); + return false; + } + + return true; +} + +bool ValidatePathStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask) +{ + if (!context->getExtensions().pathRendering) + { + context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available."); + return false; + } + + switch (func) + { + case GL_NEVER: + case GL_ALWAYS: + case GL_LESS: + case GL_LEQUAL: + case GL_EQUAL: + case GL_GEQUAL: + case GL_GREATER: + case GL_NOTEQUAL: + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil); + return false; + } + + return true; +} + +// Note that the spec specifies that for the path drawing commands +// if the path object is not an existing path object the command +// does nothing and no error is generated. +// However if the path object exists but has not been specified any +// commands then an error is generated. + +bool ValidateStencilFillPath(Context *context, GLuint path, GLenum fillMode, GLuint mask) +{ + if (!context->getExtensions().pathRendering) + { + context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available."); + return false; + } + if (context->hasPath(path) && !context->hasPathData(path)) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath); + return false; + } + + switch (fillMode) + { + case GL_COUNT_UP_CHROMIUM: + case GL_COUNT_DOWN_CHROMIUM: + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode); + return false; + } + + if (!isPow2(mask + 1)) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask); + return false; + } + + return true; +} + +bool ValidateStencilStrokePath(Context *context, GLuint path, GLint reference, GLuint mask) +{ + if (!context->getExtensions().pathRendering) + { + context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available."); + return false; + } + if (context->hasPath(path) && !context->hasPathData(path)) + { + context->handleError(InvalidOperation() << "No such path or path has no data."); + return false; + } + + return true; +} + +bool ValidateCoverPath(Context *context, GLuint path, GLenum coverMode) +{ + if (!context->getExtensions().pathRendering) + { + context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available."); + return false; + } + if (context->hasPath(path) && !context->hasPathData(path)) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath); + return false; + } + + switch (coverMode) + { + case GL_CONVEX_HULL_CHROMIUM: + case GL_BOUNDING_BOX_CHROMIUM: + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode); + return false; + } + return true; +} + +bool ValidateStencilThenCoverFillPath(Context *context, + GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode) +{ + return ValidateStencilFillPath(context, path, fillMode, mask) && + ValidateCoverPath(context, path, coverMode); +} + +bool ValidateStencilThenCoverStrokePath(Context *context, + GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode) +{ + return ValidateStencilStrokePath(context, path, reference, mask) && + ValidateCoverPath(context, path, coverMode); +} + +bool ValidateIsPath(Context *context) +{ + if (!context->getExtensions().pathRendering) + { + context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available."); + return false; + } + return true; +} + +bool ValidateCoverFillPathInstanced(Context *context, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase, + transformType, transformValues)) + return false; + + switch (coverMode) + { + case GL_CONVEX_HULL_CHROMIUM: + case GL_BOUNDING_BOX_CHROMIUM: + case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM: + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode); + return false; + } + + return true; +} + +bool ValidateCoverStrokePathInstanced(Context *context, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase, + transformType, transformValues)) + return false; + + switch (coverMode) + { + case GL_CONVEX_HULL_CHROMIUM: + case GL_BOUNDING_BOX_CHROMIUM: + case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM: + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode); + return false; + } + + return true; +} + +bool ValidateStencilFillPathInstanced(Context *context, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + + if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase, + transformType, transformValues)) + return false; + + switch (fillMode) + { + case GL_COUNT_UP_CHROMIUM: + case GL_COUNT_DOWN_CHROMIUM: + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode); + return false; + } + if (!isPow2(mask + 1)) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask); + return false; + } + return true; +} + +bool ValidateStencilStrokePathInstanced(Context *context, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase, + transformType, transformValues)) + return false; + + // no more validation here. + + return true; +} + +bool ValidateStencilThenCoverFillPathInstanced(Context *context, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase, + transformType, transformValues)) + return false; + + switch (coverMode) + { + case GL_CONVEX_HULL_CHROMIUM: + case GL_BOUNDING_BOX_CHROMIUM: + case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM: + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode); + return false; + } + + switch (fillMode) + { + case GL_COUNT_UP_CHROMIUM: + case GL_COUNT_DOWN_CHROMIUM: + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode); + return false; + } + if (!isPow2(mask + 1)) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask); + return false; + } + + return true; +} + +bool ValidateStencilThenCoverStrokePathInstanced(Context *context, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase, + transformType, transformValues)) + return false; + + switch (coverMode) + { + case GL_CONVEX_HULL_CHROMIUM: + case GL_BOUNDING_BOX_CHROMIUM: + case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM: + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode); + return false; + } + + return true; +} + +bool ValidateBindFragmentInputLocation(Context *context, + GLuint program, + GLint location, + const GLchar *name) +{ + if (!context->getExtensions().pathRendering) + { + context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available."); + return false; + } + + const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4; + if (location >= MaxLocation) + { + context->handleError(InvalidValue() << "Location exceeds max varying."); + return false; + } + + const auto *programObject = context->getProgram(program); + if (!programObject) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound); + return false; + } + + if (!name) + { + context->handleError(InvalidValue() << "No name given."); + return false; + } + + if (angle::BeginsWith(name, "gl_")) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL); + return false; + } + + return true; +} + +bool ValidateProgramPathFragmentInputGen(Context *context, + GLuint program, + GLint location, + GLenum genMode, + GLint components, + const GLfloat *coeffs) +{ + if (!context->getExtensions().pathRendering) + { + context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available."); + return false; + } + + const auto *programObject = context->getProgram(program); + if (!programObject || programObject->isFlaggedForDeletion()) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist); + return false; + } + + if (!programObject->isLinked()) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked); + return false; + } + + switch (genMode) + { + case GL_NONE: + if (components != 0) + { + context->handleError(InvalidValue() << "Invalid components."); + return false; + } + break; + + case GL_OBJECT_LINEAR_CHROMIUM: + case GL_EYE_LINEAR_CHROMIUM: + case GL_CONSTANT_CHROMIUM: + if (components < 1 || components > 4) + { + context->handleError(InvalidValue() << "Invalid components."); + return false; + } + if (!coeffs) + { + context->handleError(InvalidValue() << "No coefficients array given."); + return false; + } + break; + + default: + context->handleError(InvalidEnum() << "Invalid gen mode."); + return false; + } + + // If the location is -1 then the command is silently ignored + // and no further validation is needed. + if (location == -1) + return true; + + const auto &binding = programObject->getFragmentInputBindingInfo(context, location); + + if (!binding.valid) + { + context->handleError(InvalidOperation() << "No such binding."); + return false; + } + + if (binding.type != GL_NONE) + { + GLint expectedComponents = 0; + switch (binding.type) + { + case GL_FLOAT: + expectedComponents = 1; + break; + case GL_FLOAT_VEC2: + expectedComponents = 2; + break; + case GL_FLOAT_VEC3: + expectedComponents = 3; + break; + case GL_FLOAT_VEC4: + expectedComponents = 4; + break; + default: + context->handleError( + InvalidOperation() + << "Fragment input type is not a floating point scalar or vector."); + return false; + } + if (expectedComponents != components && genMode != GL_NONE) + { + context->handleError(InvalidOperation() << "Unexpected number of components"); + return false; + } + } + return true; +} + +bool ValidateCopyTextureCHROMIUM(Context *context, + GLuint sourceId, + GLint sourceLevel, + GLenum destTarget, + GLuint destId, + GLint destLevel, + GLint internalFormat, + GLenum destType, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha) +{ + if (!context->getExtensions().copyTexture) + { + context->handleError(InvalidOperation() + << "GL_CHROMIUM_copy_texture extension not available."); + return false; + } + + const Texture *source = context->getTexture(sourceId); + if (source == nullptr) + { + context->handleError(InvalidValue() << "Source texture is not a valid texture object."); + return false; + } + + if (!IsValidCopyTextureSourceTarget(context, source->getTarget())) + { + context->handleError(InvalidValue() << "Source texture a valid texture type."); + return false; + } + + GLenum sourceTarget = source->getTarget(); + ASSERT(sourceTarget != GL_TEXTURE_CUBE_MAP); + + if (!IsValidCopyTextureSourceLevel(context, source->getTarget(), sourceLevel)) + { + context->handleError(InvalidValue() << "Source texture level is not valid."); + return false; + } + + GLsizei sourceWidth = static_cast(source->getWidth(sourceTarget, sourceLevel)); + GLsizei sourceHeight = static_cast(source->getHeight(sourceTarget, sourceLevel)); + if (sourceWidth == 0 || sourceHeight == 0) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat); + return false; + } + + const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info; + if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat)) + { + context->handleError(InvalidOperation() << "Source texture internal format is invalid."); + return false; + } + + if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget); + return false; + } + + const Texture *dest = context->getTexture(destId); + if (dest == nullptr) + { + context->handleError(InvalidValue() + << "Destination texture is not a valid texture object."); + return false; + } + + if (!IsValidCopyTextureDestinationTarget(context, dest->getTarget(), destTarget)) + { + context->handleError(InvalidValue() << "Destination texture a valid texture type."); + return false; + } + + if (!IsValidCopyTextureDestinationLevel(context, destTarget, destLevel, sourceWidth, + sourceHeight)) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel); + return false; + } + + if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType)) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat); + return false; + } + + if (IsCubeMapTextureTarget(destTarget) && sourceWidth != sourceHeight) + { + context->handleError( + InvalidValue() << "Destination width and height must be equal for cube map textures."); + return false; + } + + if (dest->getImmutableFormat()) + { + context->handleError(InvalidOperation() << "Destination texture is immutable."); + return false; + } + + return true; +} + +bool ValidateCopySubTextureCHROMIUM(Context *context, + GLuint sourceId, + GLint sourceLevel, + GLenum destTarget, + GLuint destId, + GLint destLevel, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha) +{ + if (!context->getExtensions().copyTexture) + { + context->handleError(InvalidOperation() + << "GL_CHROMIUM_copy_texture extension not available."); + return false; + } + + const Texture *source = context->getTexture(sourceId); + if (source == nullptr) + { + context->handleError(InvalidValue() << "Source texture is not a valid texture object."); + return false; + } + + if (!IsValidCopyTextureSourceTarget(context, source->getTarget())) + { + context->handleError(InvalidValue() << "Source texture a valid texture type."); + return false; + } + + GLenum sourceTarget = source->getTarget(); + ASSERT(sourceTarget != GL_TEXTURE_CUBE_MAP); + + if (!IsValidCopyTextureSourceLevel(context, source->getTarget(), sourceLevel)) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel); + return false; + } + + if (source->getWidth(sourceTarget, sourceLevel) == 0 || + source->getHeight(sourceTarget, sourceLevel) == 0) + { + context->handleError(InvalidValue() + << "The source level of the source texture must be defined."); + return false; + } + + if (x < 0 || y < 0) + { + context->handleError(InvalidValue() << "x and y cannot be negative."); + return false; + } + + if (width < 0 || height < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize); + return false; + } + + if (static_cast(x + width) > source->getWidth(sourceTarget, sourceLevel) || + static_cast(y + height) > source->getHeight(sourceTarget, sourceLevel)) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall); + return false; + } + + const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel); + if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat)) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat); + return false; + } + + if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget); + return false; + } + + const Texture *dest = context->getTexture(destId); + if (dest == nullptr) + { + context->handleError(InvalidValue() + << "Destination texture is not a valid texture object."); + return false; + } + + if (!IsValidCopyTextureDestinationTarget(context, dest->getTarget(), destTarget)) + { + context->handleError(InvalidValue() << "Destination texture a valid texture type."); + return false; + } + + if (!IsValidCopyTextureDestinationLevel(context, destTarget, destLevel, width, height)) + { + context->handleError(InvalidValue() << "Destination texture level is not valid."); + return false; + } + + if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0) + { + context + ->handleError(InvalidOperation() + << "The destination level of the destination texture must be defined."); + return false; + } + + const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info; + if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat)) + { + context->handleError(InvalidOperation() + << "Destination internal format and type combination is not valid."); + return false; + } + + if (xoffset < 0 || yoffset < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset); + return false; + } + + if (static_cast(xoffset + width) > dest->getWidth(destTarget, destLevel) || + static_cast(yoffset + height) > dest->getHeight(destTarget, destLevel)) + { + context->handleError(InvalidValue() << "Destination texture not large enough to copy to."); + return false; + } + + return true; +} + +bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId) +{ + if (!context->getExtensions().copyCompressedTexture) + { + context->handleError(InvalidOperation() + << "GL_CHROMIUM_copy_compressed_texture extension not available."); + return false; + } + + const gl::Texture *source = context->getTexture(sourceId); + if (source == nullptr) + { + context->handleError(InvalidValue() << "Source texture is not a valid texture object."); + return false; + } + + if (source->getTarget() != GL_TEXTURE_2D) + { + context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D."); + return false; + } + + if (source->getWidth(GL_TEXTURE_2D, 0) == 0 || source->getHeight(GL_TEXTURE_2D, 0) == 0) + { + context->handleError(InvalidValue() << "Source texture must level 0 defined."); + return false; + } + + const gl::Format &sourceFormat = source->getFormat(GL_TEXTURE_2D, 0); + if (!sourceFormat.info->compressed) + { + context->handleError(InvalidOperation() + << "Source texture must have a compressed internal format."); + return false; + } + + const gl::Texture *dest = context->getTexture(destId); + if (dest == nullptr) + { + context->handleError(InvalidValue() + << "Destination texture is not a valid texture object."); + return false; + } + + if (dest->getTarget() != GL_TEXTURE_2D) + { + context->handleError(InvalidValue() + << "Destination texture must be of type GL_TEXTURE_2D."); + return false; + } + + if (dest->getImmutableFormat()) + { + context->handleError(InvalidOperation() << "Destination cannot be immutable."); + return false; + } + + return true; +} + +bool ValidateCreateShader(Context *context, GLenum type) +{ + switch (type) + { + case GL_VERTEX_SHADER: + case GL_FRAGMENT_SHADER: + break; + + case GL_COMPUTE_SHADER: + if (context->getClientVersion() < Version(3, 1)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required); + return false; + } + break; + + case GL_GEOMETRY_SHADER_EXT: + if (!context->getExtensions().geometryShader) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType); + return false; + } + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType); + return false; + } + + return true; +} + +bool ValidateBufferData(ValidationContext *context, + BufferBinding target, + GLsizeiptr size, + const void *data, + BufferUsage usage) +{ + if (size < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize); + return false; + } + + switch (usage) + { + case BufferUsage::StreamDraw: + case BufferUsage::StaticDraw: + case BufferUsage::DynamicDraw: + break; + + case BufferUsage::StreamRead: + case BufferUsage::StaticRead: + case BufferUsage::DynamicRead: + case BufferUsage::StreamCopy: + case BufferUsage::StaticCopy: + case BufferUsage::DynamicCopy: + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage); + return false; + } + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage); + return false; + } + + if (!ValidBufferType(context, target)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes); + return false; + } + + Buffer *buffer = context->getGLState().getTargetBuffer(target); + + if (!buffer) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound); + return false; + } + + return true; +} + +bool ValidateBufferSubData(ValidationContext *context, + BufferBinding target, + GLintptr offset, + GLsizeiptr size, + const void *data) +{ + if (size < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize); + return false; + } + + if (offset < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset); + return false; + } + + if (!ValidBufferType(context, target)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes); + return false; + } + + Buffer *buffer = context->getGLState().getTargetBuffer(target); + + if (!buffer) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound); + return false; + } + + if (buffer->isMapped()) + { + context->handleError(InvalidOperation()); + return false; + } + + // Check for possible overflow of size + offset + angle::CheckedNumeric checkedSize(size); + checkedSize += offset; + if (!checkedSize.IsValid()) + { + context->handleError(OutOfMemory()); + return false; + } + + if (size + offset > buffer->getSize()) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize); + return false; + } + + return true; +} + +bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name) +{ + if (!context->getExtensions().requestExtension) + { + context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available."); + return false; + } + + if (!context->isExtensionRequestable(name)) + { + context->handleError(InvalidOperation() << "Extension " << name << " is not requestable."); + return false; + } + + return true; +} + +bool ValidateActiveTexture(ValidationContext *context, GLenum texture) +{ + if (texture < GL_TEXTURE0 || + texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1) + { + context->handleError(InvalidEnum()); + return false; + } + + return true; +} + +bool ValidateAttachShader(ValidationContext *context, GLuint program, GLuint shader) +{ + Program *programObject = GetValidProgram(context, program); + if (!programObject) + { + return false; + } + + Shader *shaderObject = GetValidShader(context, shader); + if (!shaderObject) + { + return false; + } + + switch (shaderObject->getType()) + { + case GL_VERTEX_SHADER: + { + if (programObject->getAttachedVertexShader()) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader); + return false; + } + break; + } + case GL_FRAGMENT_SHADER: + { + if (programObject->getAttachedFragmentShader()) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader); + return false; + } + break; + } + case GL_COMPUTE_SHADER: + { + if (programObject->getAttachedComputeShader()) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader); + return false; + } + break; + } + case GL_GEOMETRY_SHADER_EXT: + { + if (programObject->getAttachedGeometryShader()) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader); + return false; + } + break; + } + default: + UNREACHABLE(); + break; + } + + return true; +} + +bool ValidateBindAttribLocation(ValidationContext *context, + GLuint program, + GLuint index, + const GLchar *name) +{ + if (index >= MAX_VERTEX_ATTRIBS) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute); + return false; + } + + if (strncmp(name, "gl_", 3) == 0) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL); + return false; + } + + if (context->isWebGL()) + { + const size_t length = strlen(name); + + if (!IsValidESSLString(name, length)) + { + // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters + // for shader-related entry points + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters); + return false; + } + + if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name)) + { + return false; + } + } + + return GetValidProgram(context, program) != nullptr; +} + +bool ValidateBindBuffer(ValidationContext *context, BufferBinding target, GLuint buffer) +{ + if (!ValidBufferType(context, target)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes); + return false; + } + + if (!context->getGLState().isBindGeneratesResourceEnabled() && + !context->isBufferGenerated(buffer)) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated); + return false; + } + + return true; +} + +bool ValidateBindFramebuffer(ValidationContext *context, GLenum target, GLuint framebuffer) +{ + if (!ValidFramebufferTarget(context, target)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget); + return false; + } + + if (!context->getGLState().isBindGeneratesResourceEnabled() && + !context->isFramebufferGenerated(framebuffer)) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated); + return false; + } + + return true; +} + +bool ValidateBindRenderbuffer(ValidationContext *context, GLenum target, GLuint renderbuffer) +{ + if (target != GL_RENDERBUFFER) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget); + return false; + } + + if (!context->getGLState().isBindGeneratesResourceEnabled() && + !context->isRenderbufferGenerated(renderbuffer)) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated); + return false; + } + + return true; +} + +static bool ValidBlendEquationMode(const ValidationContext *context, GLenum mode) +{ + switch (mode) + { + case GL_FUNC_ADD: + case GL_FUNC_SUBTRACT: + case GL_FUNC_REVERSE_SUBTRACT: + return true; + + case GL_MIN: + case GL_MAX: + return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax; + + default: + return false; + } +} + +bool ValidateBlendColor(ValidationContext *context, + GLfloat red, + GLfloat green, + GLfloat blue, + GLfloat alpha) +{ + return true; +} + +bool ValidateBlendEquation(ValidationContext *context, GLenum mode) +{ + if (!ValidBlendEquationMode(context, mode)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation); + return false; + } + + return true; +} + +bool ValidateBlendEquationSeparate(ValidationContext *context, GLenum modeRGB, GLenum modeAlpha) +{ + if (!ValidBlendEquationMode(context, modeRGB)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation); + return false; + } + + if (!ValidBlendEquationMode(context, modeAlpha)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation); + return false; + } + + return true; +} + +bool ValidateBlendFunc(ValidationContext *context, GLenum sfactor, GLenum dfactor) +{ + return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor); +} + +static bool ValidSrcBlendFunc(GLenum srcBlend) +{ + switch (srcBlend) + { + case GL_ZERO: + case GL_ONE: + case GL_SRC_COLOR: + case GL_ONE_MINUS_SRC_COLOR: + case GL_DST_COLOR: + case GL_ONE_MINUS_DST_COLOR: + case GL_SRC_ALPHA: + case GL_ONE_MINUS_SRC_ALPHA: + case GL_DST_ALPHA: + case GL_ONE_MINUS_DST_ALPHA: + case GL_CONSTANT_COLOR: + case GL_ONE_MINUS_CONSTANT_COLOR: + case GL_CONSTANT_ALPHA: + case GL_ONE_MINUS_CONSTANT_ALPHA: + case GL_SRC_ALPHA_SATURATE: + return true; + + default: + return false; + } +} + +static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion) +{ + switch (dstBlend) + { + case GL_ZERO: + case GL_ONE: + case GL_SRC_COLOR: + case GL_ONE_MINUS_SRC_COLOR: + case GL_DST_COLOR: + case GL_ONE_MINUS_DST_COLOR: + case GL_SRC_ALPHA: + case GL_ONE_MINUS_SRC_ALPHA: + case GL_DST_ALPHA: + case GL_ONE_MINUS_DST_ALPHA: + case GL_CONSTANT_COLOR: + case GL_ONE_MINUS_CONSTANT_COLOR: + case GL_CONSTANT_ALPHA: + case GL_ONE_MINUS_CONSTANT_ALPHA: + return true; + + case GL_SRC_ALPHA_SATURATE: + return (contextMajorVersion >= 3); + + default: + return false; + } +} + +bool ValidateBlendFuncSeparate(ValidationContext *context, + GLenum srcRGB, + GLenum dstRGB, + GLenum srcAlpha, + GLenum dstAlpha) +{ + if (!ValidSrcBlendFunc(srcRGB)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction); + return false; + } + + if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion())) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction); + return false; + } + + if (!ValidSrcBlendFunc(srcAlpha)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction); + return false; + } + + if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion())) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction); + return false; + } + + if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc || + context->getExtensions().webglCompatibility) + { + bool constantColorUsed = + (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR || + dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR); + + bool constantAlphaUsed = + (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA || + dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA); + + if (constantColorUsed && constantAlphaUsed) + { + const char *msg; + if (context->getExtensions().webglCompatibility) + { + msg = kErrorInvalidConstantColor; + } + else + { + msg = + "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and " + "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this " + "implementation."; + ERR() << msg; + } + context->handleError(InvalidOperation() << msg); + return false; + } + } + + return true; +} + +bool ValidateGetString(Context *context, GLenum name) +{ + switch (name) + { + case GL_VENDOR: + case GL_RENDERER: + case GL_VERSION: + case GL_SHADING_LANGUAGE_VERSION: + case GL_EXTENSIONS: + break; + + case GL_REQUESTABLE_EXTENSIONS_ANGLE: + if (!context->getExtensions().requestExtension) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName); + return false; + } + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName); + return false; + } + + return true; +} + +bool ValidateLineWidth(ValidationContext *context, GLfloat width) +{ + if (width <= 0.0f || isNaN(width)) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth); + return false; + } + + return true; +} + +bool ValidateVertexAttribPointer(ValidationContext *context, + GLuint index, + GLint size, + GLenum type, + GLboolean normalized, + GLsizei stride, + const void *ptr) +{ + if (!ValidateVertexFormatBase(context, index, size, type, false)) + { + return false; + } + + if (stride < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride); + return false; + } + + const Caps &caps = context->getCaps(); + if (context->getClientVersion() >= ES_3_1) + { + if (stride > caps.maxVertexAttribStride) + { + context->handleError(InvalidValue() + << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE."); + return false; + } + + if (index >= caps.maxVertexAttribBindings) + { + context->handleError(InvalidValue() + << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS."); + return false; + } + } + + // [OpenGL ES 3.0.2] Section 2.8 page 24: + // An INVALID_OPERATION error is generated when a non-zero vertex array object + // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point, + // and the pointer argument is not NULL. + bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() && + context->getGLState().getVertexArray()->id() == 0; + if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 && + ptr != nullptr) + { + context + ->handleError(InvalidOperation() + << "Client data cannot be used with a non-default vertex array object."); + return false; + } + + if (context->getExtensions().webglCompatibility) + { + // WebGL 1.0 [Section 6.14] Fixed point support + // The WebGL API does not support the GL_FIXED data type. + if (type == GL_FIXED) + { + context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL."); + return false; + } + + if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false)) + { + return false; + } + } + + return true; +} + +bool ValidateDepthRangef(ValidationContext *context, GLfloat zNear, GLfloat zFar) +{ + if (context->getExtensions().webglCompatibility && zNear > zFar) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange); + return false; + } + + return true; +} + +bool ValidateRenderbufferStorage(ValidationContext *context, + GLenum target, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width, + height); +} + +bool ValidateRenderbufferStorageMultisampleANGLE(ValidationContext *context, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + if (!context->getExtensions().framebufferMultisample) + { + context->handleError(InvalidOperation() + << "GL_ANGLE_framebuffer_multisample not available"); + return false; + } + + // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal + // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is + // generated. + if (static_cast(samples) > context->getCaps().maxSamples) + { + context->handleError(InvalidValue()); + return false; + } + + // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create + // the specified storage. This is different than ES 3.0 in which a sample number higher + // than the maximum sample number supported by this format generates a GL_INVALID_VALUE. + // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3. + if (context->getClientMajorVersion() >= 3) + { + const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat); + if (static_cast(samples) > formatCaps.getMaxSamples()) + { + context->handleError(OutOfMemory()); + return false; + } + } + + return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat, + width, height); +} + +bool ValidateCheckFramebufferStatus(ValidationContext *context, GLenum target) +{ + if (!ValidFramebufferTarget(context, target)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget); + return false; + } + + return true; +} + +bool ValidateClearColor(ValidationContext *context, + GLfloat red, + GLfloat green, + GLfloat blue, + GLfloat alpha) +{ + return true; +} + +bool ValidateClearDepthf(ValidationContext *context, GLfloat depth) +{ + return true; +} + +bool ValidateClearStencil(ValidationContext *context, GLint s) +{ + return true; +} + +bool ValidateColorMask(ValidationContext *context, + GLboolean red, + GLboolean green, + GLboolean blue, + GLboolean alpha) +{ + return true; +} + +bool ValidateCompileShader(ValidationContext *context, GLuint shader) +{ + return true; +} + +bool ValidateCreateProgram(ValidationContext *context) +{ + return true; +} + +bool ValidateCullFace(ValidationContext *context, CullFaceMode mode) +{ + switch (mode) + { + case CullFaceMode::Front: + case CullFaceMode::Back: + case CullFaceMode::FrontAndBack: + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode); + return false; + } + + return true; +} + +bool ValidateDeleteProgram(ValidationContext *context, GLuint program) +{ + if (program == 0) + { + return false; + } + + if (!context->getProgram(program)) + { + if (context->getShader(program)) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName); + return false; + } + else + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName); + return false; + } + } + + return true; +} + +bool ValidateDeleteShader(ValidationContext *context, GLuint shader) +{ + if (shader == 0) + { + return false; + } + + if (!context->getShader(shader)) + { + if (context->getProgram(shader)) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName); + return false; + } + else + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName); + return false; + } + } + + return true; +} + +bool ValidateDepthFunc(ValidationContext *context, GLenum func) +{ + switch (func) + { + case GL_NEVER: + case GL_ALWAYS: + case GL_LESS: + case GL_LEQUAL: + case GL_EQUAL: + case GL_GREATER: + case GL_GEQUAL: + case GL_NOTEQUAL: + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + + return true; +} + +bool ValidateDepthMask(ValidationContext *context, GLboolean flag) +{ + return true; +} + +bool ValidateDetachShader(ValidationContext *context, GLuint program, GLuint shader) +{ + Program *programObject = GetValidProgram(context, program); + if (!programObject) + { + return false; + } + + Shader *shaderObject = GetValidShader(context, shader); + if (!shaderObject) + { + return false; + } + + const Shader *attachedShader = nullptr; + + switch (shaderObject->getType()) + { + case GL_VERTEX_SHADER: + { + attachedShader = programObject->getAttachedVertexShader(); + break; + } + case GL_FRAGMENT_SHADER: + { + attachedShader = programObject->getAttachedFragmentShader(); + break; + } + case GL_COMPUTE_SHADER: + { + attachedShader = programObject->getAttachedComputeShader(); + break; + } + case GL_GEOMETRY_SHADER_EXT: + { + attachedShader = programObject->getAttachedGeometryShader(); + break; + } + default: + UNREACHABLE(); + return false; + } + + if (attachedShader != shaderObject) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached); + return false; + } + + return true; +} + +bool ValidateDisableVertexAttribArray(ValidationContext *context, GLuint index) +{ + if (index >= MAX_VERTEX_ATTRIBS) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute); + return false; + } + + return true; +} + +bool ValidateEnableVertexAttribArray(ValidationContext *context, GLuint index) +{ + if (index >= MAX_VERTEX_ATTRIBS) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute); + return false; + } + + return true; +} + +bool ValidateFinish(ValidationContext *context) +{ + return true; +} + +bool ValidateFlush(ValidationContext *context) +{ + return true; +} + +bool ValidateFrontFace(ValidationContext *context, GLenum mode) +{ + switch (mode) + { + case GL_CW: + case GL_CCW: + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + + return true; +} + +bool ValidateGetActiveAttrib(ValidationContext *context, + GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name) +{ + if (bufsize < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize); + return false; + } + + Program *programObject = GetValidProgram(context, program); + + if (!programObject) + { + return false; + } + + if (index >= static_cast(programObject->getActiveAttributeCount())) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform); + return false; + } + + return true; +} + +bool ValidateGetActiveUniform(ValidationContext *context, + GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name) +{ + if (bufsize < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize); + return false; + } + + Program *programObject = GetValidProgram(context, program); + + if (!programObject) + { + return false; + } + + if (index >= static_cast(programObject->getActiveUniformCount())) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform); + return false; + } + + return true; +} + +bool ValidateGetAttachedShaders(ValidationContext *context, + GLuint program, + GLsizei maxcount, + GLsizei *count, + GLuint *shaders) +{ + if (maxcount < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount); + return false; + } + + Program *programObject = GetValidProgram(context, program); + + if (!programObject) + { + return false; + } + + return true; +} + +bool ValidateGetAttribLocation(ValidationContext *context, GLuint program, const GLchar *name) +{ + // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for + // shader-related entry points + if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name))) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters); + return false; + } + + Program *programObject = GetValidProgram(context, program); + + if (!programObject) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound); + return false; + } + + if (!programObject->isLinked()) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked); + return false; + } + + return true; +} + +bool ValidateGetBooleanv(ValidationContext *context, GLenum pname, GLboolean *params) +{ + GLenum nativeType; + unsigned int numParams = 0; + return ValidateStateQuery(context, pname, &nativeType, &numParams); +} + +bool ValidateGetError(ValidationContext *context) +{ + return true; +} + +bool ValidateGetFloatv(ValidationContext *context, GLenum pname, GLfloat *params) +{ + GLenum nativeType; + unsigned int numParams = 0; + return ValidateStateQuery(context, pname, &nativeType, &numParams); +} + +bool ValidateGetIntegerv(ValidationContext *context, GLenum pname, GLint *params) +{ + GLenum nativeType; + unsigned int numParams = 0; + return ValidateStateQuery(context, pname, &nativeType, &numParams); +} + +bool ValidateGetProgramInfoLog(ValidationContext *context, + GLuint program, + GLsizei bufsize, + GLsizei *length, + GLchar *infolog) +{ + if (bufsize < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize); + return false; + } + + Program *programObject = GetValidProgram(context, program); + if (!programObject) + { + return false; + } + + return true; +} + +bool ValidateGetShaderInfoLog(ValidationContext *context, + GLuint shader, + GLsizei bufsize, + GLsizei *length, + GLchar *infolog) +{ + if (bufsize < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize); + return false; + } + + Shader *shaderObject = GetValidShader(context, shader); + if (!shaderObject) + { + return false; + } + + return true; +} + +bool ValidateGetShaderPrecisionFormat(ValidationContext *context, + GLenum shadertype, + GLenum precisiontype, + GLint *range, + GLint *precision) +{ + switch (shadertype) + { + case GL_VERTEX_SHADER: + case GL_FRAGMENT_SHADER: + break; + case GL_COMPUTE_SHADER: + context->handleError(InvalidOperation() + << "compute shader precision not yet implemented."); + return false; + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType); + return false; + } + + switch (precisiontype) + { + case GL_LOW_FLOAT: + case GL_MEDIUM_FLOAT: + case GL_HIGH_FLOAT: + case GL_LOW_INT: + case GL_MEDIUM_INT: + case GL_HIGH_INT: + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision); + return false; + } + + return true; +} + +bool ValidateGetShaderSource(ValidationContext *context, + GLuint shader, + GLsizei bufsize, + GLsizei *length, + GLchar *source) +{ + if (bufsize < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize); + return false; + } + + Shader *shaderObject = GetValidShader(context, shader); + if (!shaderObject) + { + return false; + } + + return true; +} + +bool ValidateGetUniformLocation(ValidationContext *context, GLuint program, const GLchar *name) +{ + if (strstr(name, "gl_") == name) + { + return false; + } + + // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for + // shader-related entry points + if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name))) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters); + return false; + } + + Program *programObject = GetValidProgram(context, program); + + if (!programObject) + { + return false; + } + + if (!programObject->isLinked()) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked); + return false; + } + + return true; +} + +bool ValidateHint(ValidationContext *context, GLenum target, GLenum mode) +{ + switch (mode) + { + case GL_FASTEST: + case GL_NICEST: + case GL_DONT_CARE: + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + + switch (target) + { + case GL_GENERATE_MIPMAP_HINT: + break; + + case GL_FRAGMENT_SHADER_DERIVATIVE_HINT: + if (context->getClientVersion() < ES_3_0 && + !context->getExtensions().standardDerivatives) + { + context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives."); + return false; + } + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + + return true; +} + +bool ValidateIsBuffer(ValidationContext *context, GLuint buffer) +{ + return true; +} + +bool ValidateIsFramebuffer(ValidationContext *context, GLuint framebuffer) +{ + return true; +} + +bool ValidateIsProgram(ValidationContext *context, GLuint program) +{ + return true; +} + +bool ValidateIsRenderbuffer(ValidationContext *context, GLuint renderbuffer) +{ + return true; +} + +bool ValidateIsShader(ValidationContext *context, GLuint shader) +{ + return true; +} + +bool ValidateIsTexture(ValidationContext *context, GLuint texture) +{ + return true; +} + +bool ValidatePixelStorei(ValidationContext *context, GLenum pname, GLint param) +{ + if (context->getClientMajorVersion() < 3) + { + switch (pname) + { + case GL_UNPACK_IMAGE_HEIGHT: + case GL_UNPACK_SKIP_IMAGES: + context->handleError(InvalidEnum()); + return false; + + case GL_UNPACK_ROW_LENGTH: + case GL_UNPACK_SKIP_ROWS: + case GL_UNPACK_SKIP_PIXELS: + if (!context->getExtensions().unpackSubimage) + { + context->handleError(InvalidEnum()); + return false; + } + break; + + case GL_PACK_ROW_LENGTH: + case GL_PACK_SKIP_ROWS: + case GL_PACK_SKIP_PIXELS: + if (!context->getExtensions().packSubimage) + { + context->handleError(InvalidEnum()); + return false; + } + break; + } + } + + if (param < 0) + { + context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei"); + return false; + } + + switch (pname) + { + case GL_UNPACK_ALIGNMENT: + if (param != 1 && param != 2 && param != 4 && param != 8) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment); + return false; + } + break; + + case GL_PACK_ALIGNMENT: + if (param != 1 && param != 2 && param != 4 && param != 8) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment); + return false; + } + break; + + case GL_PACK_REVERSE_ROW_ORDER_ANGLE: + if (!context->getExtensions().packReverseRowOrder) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + } + break; + + case GL_UNPACK_ROW_LENGTH: + case GL_UNPACK_IMAGE_HEIGHT: + case GL_UNPACK_SKIP_IMAGES: + case GL_UNPACK_SKIP_ROWS: + case GL_UNPACK_SKIP_PIXELS: + case GL_PACK_ROW_LENGTH: + case GL_PACK_SKIP_ROWS: + case GL_PACK_SKIP_PIXELS: + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + + return true; +} + +bool ValidatePolygonOffset(ValidationContext *context, GLfloat factor, GLfloat units) +{ + return true; +} + +bool ValidateReleaseShaderCompiler(ValidationContext *context) +{ + return true; +} + +bool ValidateSampleCoverage(ValidationContext *context, GLfloat value, GLboolean invert) +{ + return true; +} + +bool ValidateScissor(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height) +{ + if (width < 0 || height < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize); + return false; + } + + return true; +} + +bool ValidateShaderBinary(ValidationContext *context, + GLsizei n, + const GLuint *shaders, + GLenum binaryformat, + const void *binary, + GLsizei length) +{ + const std::vector &shaderBinaryFormats = context->getCaps().shaderBinaryFormats; + if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) == + shaderBinaryFormats.end()) + { + context->handleError(InvalidEnum() << "Invalid shader binary format."); + return false; + } + + return true; +} + +bool ValidateShaderSource(ValidationContext *context, + GLuint shader, + GLsizei count, + const GLchar *const *string, + const GLint *length) +{ + if (count < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount); + return false; + } + + // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for + // shader-related entry points + if (context->getExtensions().webglCompatibility) + { + for (GLsizei i = 0; i < count; i++) + { + size_t len = + (length && length[i] >= 0) ? static_cast(length[i]) : strlen(string[i]); + + // Backslash as line-continuation is allowed in WebGL 2.0. + if (!IsValidESSLShaderSourceString(string[i], len, + context->getClientVersion() >= ES_3_0)) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters); + return false; + } + } + } + + Shader *shaderObject = GetValidShader(context, shader); + if (!shaderObject) + { + return false; + } + + return true; +} + +bool ValidateStencilFunc(ValidationContext *context, GLenum func, GLint ref, GLuint mask) +{ + if (!IsValidStencilFunc(func)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil); + return false; + } + + return true; +} + +bool ValidateStencilFuncSeparate(ValidationContext *context, + GLenum face, + GLenum func, + GLint ref, + GLuint mask) +{ + if (!IsValidStencilFace(face)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil); + return false; + } + + if (!IsValidStencilFunc(func)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil); + return false; + } + + return true; +} + +bool ValidateStencilMask(ValidationContext *context, GLuint mask) +{ + return true; +} + +bool ValidateStencilMaskSeparate(ValidationContext *context, GLenum face, GLuint mask) +{ + if (!IsValidStencilFace(face)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil); + return false; + } + + return true; +} + +bool ValidateStencilOp(ValidationContext *context, GLenum fail, GLenum zfail, GLenum zpass) +{ + if (!IsValidStencilOp(fail)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil); + return false; + } + + if (!IsValidStencilOp(zfail)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil); + return false; + } + + if (!IsValidStencilOp(zpass)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil); + return false; + } + + return true; +} + +bool ValidateStencilOpSeparate(ValidationContext *context, + GLenum face, + GLenum fail, + GLenum zfail, + GLenum zpass) +{ + if (!IsValidStencilFace(face)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil); + return false; + } + + return ValidateStencilOp(context, fail, zfail, zpass); +} + +bool ValidateUniform1f(ValidationContext *context, GLint location, GLfloat x) +{ + return ValidateUniform(context, GL_FLOAT, location, 1); +} + +bool ValidateUniform1fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v) +{ + return ValidateUniform(context, GL_FLOAT, location, count); +} + +bool ValidateUniform1i(ValidationContext *context, GLint location, GLint x) +{ + return ValidateUniform1iv(context, location, 1, &x); +} + +bool ValidateUniform2f(ValidationContext *context, GLint location, GLfloat x, GLfloat y) +{ + return ValidateUniform(context, GL_FLOAT_VEC2, location, 1); +} + +bool ValidateUniform2fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v) +{ + return ValidateUniform(context, GL_FLOAT_VEC2, location, count); +} + +bool ValidateUniform2i(ValidationContext *context, GLint location, GLint x, GLint y) +{ + return ValidateUniform(context, GL_INT_VEC2, location, 1); +} + +bool ValidateUniform2iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v) +{ + return ValidateUniform(context, GL_INT_VEC2, location, count); +} + +bool ValidateUniform3f(ValidationContext *context, GLint location, GLfloat x, GLfloat y, GLfloat z) +{ + return ValidateUniform(context, GL_FLOAT_VEC3, location, 1); +} + +bool ValidateUniform3fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v) +{ + return ValidateUniform(context, GL_FLOAT_VEC3, location, count); +} + +bool ValidateUniform3i(ValidationContext *context, GLint location, GLint x, GLint y, GLint z) +{ + return ValidateUniform(context, GL_INT_VEC3, location, 1); +} + +bool ValidateUniform3iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v) +{ + return ValidateUniform(context, GL_INT_VEC3, location, count); +} + +bool ValidateUniform4f(ValidationContext *context, + GLint location, + GLfloat x, + GLfloat y, + GLfloat z, + GLfloat w) +{ + return ValidateUniform(context, GL_FLOAT_VEC4, location, 1); +} + +bool ValidateUniform4fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v) +{ + return ValidateUniform(context, GL_FLOAT_VEC4, location, count); +} + +bool ValidateUniform4i(ValidationContext *context, + GLint location, + GLint x, + GLint y, + GLint z, + GLint w) +{ + return ValidateUniform(context, GL_INT_VEC4, location, 1); +} + +bool ValidateUniform4iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v) +{ + return ValidateUniform(context, GL_INT_VEC4, location, count); +} + +bool ValidateUniformMatrix2fv(ValidationContext *context, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose); +} + +bool ValidateUniformMatrix3fv(ValidationContext *context, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose); +} + +bool ValidateUniformMatrix4fv(ValidationContext *context, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose); +} + +bool ValidateValidateProgram(ValidationContext *context, GLuint program) +{ + Program *programObject = GetValidProgram(context, program); + + if (!programObject) + { + return false; + } + + return true; +} + +bool ValidateVertexAttrib1f(ValidationContext *context, GLuint index, GLfloat x) +{ + return ValidateVertexAttribIndex(context, index); +} + +bool ValidateVertexAttrib1fv(ValidationContext *context, GLuint index, const GLfloat *values) +{ + return ValidateVertexAttribIndex(context, index); +} + +bool ValidateVertexAttrib2f(ValidationContext *context, GLuint index, GLfloat x, GLfloat y) +{ + return ValidateVertexAttribIndex(context, index); +} + +bool ValidateVertexAttrib2fv(ValidationContext *context, GLuint index, const GLfloat *values) +{ + return ValidateVertexAttribIndex(context, index); +} + +bool ValidateVertexAttrib3f(ValidationContext *context, + GLuint index, + GLfloat x, + GLfloat y, + GLfloat z) +{ + return ValidateVertexAttribIndex(context, index); +} + +bool ValidateVertexAttrib3fv(ValidationContext *context, GLuint index, const GLfloat *values) +{ + return ValidateVertexAttribIndex(context, index); +} + +bool ValidateVertexAttrib4f(ValidationContext *context, + GLuint index, + GLfloat x, + GLfloat y, + GLfloat z, + GLfloat w) +{ + return ValidateVertexAttribIndex(context, index); +} + +bool ValidateVertexAttrib4fv(ValidationContext *context, GLuint index, const GLfloat *values) +{ + return ValidateVertexAttribIndex(context, index); +} + +bool ValidateViewport(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height) +{ + if (width < 0 || height < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize); + return false; + } + + return true; +} + +bool ValidateDrawArrays(ValidationContext *context, GLenum mode, GLint first, GLsizei count) +{ + return ValidateDrawArraysCommon(context, mode, first, count, 1); +} + +bool ValidateDrawElements(ValidationContext *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices) +{ + return ValidateDrawElementsCommon(context, mode, count, type, indices, 1); +} + +bool ValidateGetFramebufferAttachmentParameteriv(ValidationContext *context, + GLenum target, + GLenum attachment, + GLenum pname, + GLint *params) +{ + return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname, + nullptr); +} + +bool ValidateGetProgramiv(ValidationContext *context, GLuint program, GLenum pname, GLint *params) +{ + return ValidateGetProgramivBase(context, program, pname, nullptr); +} + +bool ValidateCopyTexImage2D(ValidationContext *context, + GLenum target, + GLint level, + GLenum internalformat, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border) +{ + if (context->getClientMajorVersion() < 3) + { + return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0, + 0, x, y, width, height, border); + } + + ASSERT(context->getClientMajorVersion() == 3); + return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0, + 0, x, y, width, height, border); +} + +bool ValidateCopyTexSubImage2D(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + if (context->getClientMajorVersion() < 3) + { + return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset, + yoffset, x, y, width, height, 0); + } + + return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset, + yoffset, 0, x, y, width, height, 0); +} + +bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *) +{ + return ValidateGenOrDelete(context, n); +} + +bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *) +{ + return ValidateGenOrDelete(context, n); +} + +bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *) +{ + return ValidateGenOrDelete(context, n); +} + +bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *) +{ + return ValidateGenOrDelete(context, n); +} + +bool ValidateDisable(Context *context, GLenum cap) +{ + if (!ValidCap(context, cap, false)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + + return true; +} + +bool ValidateEnable(Context *context, GLenum cap) +{ + if (!ValidCap(context, cap, false)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + + if (context->getLimitations().noSampleAlphaToCoverageSupport && + cap == GL_SAMPLE_ALPHA_TO_COVERAGE) + { + const char *errorMessage = "Current renderer doesn't support alpha-to-coverage"; + context->handleError(InvalidOperation() << errorMessage); + + // We also output an error message to the debugger window if tracing is active, so that + // developers can see the error message. + ERR() << errorMessage; + return false; + } + + return true; +} + +bool ValidateFramebufferRenderbuffer(Context *context, + GLenum target, + GLenum attachment, + GLenum renderbuffertarget, + GLuint renderbuffer) +{ + if (!ValidFramebufferTarget(context, target)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget); + return false; + } + + if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget); + return false; + } + + return ValidateFramebufferRenderbufferParameters(context, target, attachment, + renderbuffertarget, renderbuffer); +} + +bool ValidateFramebufferTexture2D(Context *context, + GLenum target, + GLenum attachment, + GLenum textarget, + GLuint texture, + GLint level) +{ + // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap + // extension + if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap && + level != 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel); + return false; + } + + if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level)) + { + return false; + } + + if (texture != 0) + { + gl::Texture *tex = context->getTexture(texture); + ASSERT(tex); + + const gl::Caps &caps = context->getCaps(); + + switch (textarget) + { + case GL_TEXTURE_2D: + { + if (level > gl::log2(caps.max2DTextureSize)) + { + context->handleError(InvalidValue()); + return false; + } + if (tex->getTarget() != GL_TEXTURE_2D) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget); + return false; + } + } + break; + + case GL_TEXTURE_RECTANGLE_ANGLE: + { + if (level != 0) + { + context->handleError(InvalidValue()); + return false; + } + if (tex->getTarget() != GL_TEXTURE_RECTANGLE_ANGLE) + { + context->handleError(InvalidOperation() + << "Textarget must match the texture target type."); + return false; + } + } + break; + + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + { + if (level > gl::log2(caps.maxCubeMapTextureSize)) + { + context->handleError(InvalidValue()); + return false; + } + if (tex->getTarget() != GL_TEXTURE_CUBE_MAP) + { + context->handleError(InvalidOperation() + << "Textarget must match the texture target type."); + return false; + } + } + break; + + case GL_TEXTURE_2D_MULTISAMPLE: + { + if (context->getClientVersion() < ES_3_1) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required); + return false; + } + + if (level != 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero); + return false; + } + if (tex->getTarget() != GL_TEXTURE_2D_MULTISAMPLE) + { + context->handleError(InvalidOperation() + << "Textarget must match the texture target type."); + return false; + } + } + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget); + return false; + } + + const Format &format = tex->getFormat(textarget, level); + if (format.info->compressed) + { + context->handleError(InvalidOperation()); + return false; + } + } + + return true; +} + +bool ValidateGenBuffers(Context *context, GLint n, GLuint *) +{ + return ValidateGenOrDelete(context, n); +} + +bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *) +{ + return ValidateGenOrDelete(context, n); +} + +bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *) +{ + return ValidateGenOrDelete(context, n); +} + +bool ValidateGenTextures(Context *context, GLint n, GLuint *) +{ + return ValidateGenOrDelete(context, n); +} + +bool ValidateGenerateMipmap(Context *context, GLenum target) +{ + if (!ValidTextureTarget(context, target)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget); + return false; + } + + Texture *texture = context->getTargetTexture(target); + + if (texture == nullptr) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound); + return false; + } + + const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel(); + + // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so + // that out-of-range base level has a non-color-renderable / non-texture-filterable format. + if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS) + { + context->handleError(InvalidOperation()); + return false; + } + + GLenum baseTarget = (target == GL_TEXTURE_CUBE_MAP) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : target; + const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info); + if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 || + format.stencilBits > 0) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed); + return false; + } + + // GenerateMipmap accepts formats that are unsized or both color renderable and filterable. + bool formatUnsized = !format.sized; + bool formatColorRenderableAndFilterable = + format.filterSupport(context->getClientVersion(), context->getExtensions()) && + format.renderSupport(context->getClientVersion(), context->getExtensions()); + if (!formatUnsized && !formatColorRenderableAndFilterable) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed); + return false; + } + + // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap + // generation + if (format.colorEncoding == GL_SRGB && format.format == GL_RGB) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed); + return false; + } + + // ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does + // not. + bool supportsSRGBMipmapGeneration = + context->getClientVersion() >= ES_3_0 || context->getExtensions().webglCompatibility; + if (!supportsSRGBMipmapGeneration && format.colorEncoding == GL_SRGB) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed); + return false; + } + + // Non-power of 2 ES2 check + if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT && + (!isPow2(static_cast(texture->getWidth(baseTarget, 0))) || + !isPow2(static_cast(texture->getHeight(baseTarget, 0))))) + { + ASSERT(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ANGLE || + target == GL_TEXTURE_CUBE_MAP); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2); + return false; + } + + // Cube completeness check + if (target == GL_TEXTURE_CUBE_MAP && !texture->getTextureState().isCubeComplete()) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete); + return false; + } + + return true; +} + +bool ValidateGetBufferParameteriv(ValidationContext *context, + BufferBinding target, + GLenum pname, + GLint *params) +{ + return ValidateGetBufferParameterBase(context, target, pname, false, nullptr); +} + +bool ValidateGetRenderbufferParameteriv(Context *context, + GLenum target, + GLenum pname, + GLint *params) +{ + return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr); +} + +bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params) +{ + return ValidateGetShaderivBase(context, shader, pname, nullptr); +} + +bool ValidateGetTexParameterfv(Context *context, GLenum target, GLenum pname, GLfloat *params) +{ + return ValidateGetTexParameterBase(context, target, pname, nullptr); +} + +bool ValidateGetTexParameteriv(Context *context, GLenum target, GLenum pname, GLint *params) +{ + return ValidateGetTexParameterBase(context, target, pname, nullptr); +} + +bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params) +{ + return ValidateGetUniformBase(context, program, location); +} + +bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params) +{ + return ValidateGetUniformBase(context, program, location); +} + +bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params) +{ + return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false); +} + +bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params) +{ + return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false); +} + +bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer) +{ + return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false); +} + +bool ValidateIsEnabled(Context *context, GLenum cap) +{ + if (!ValidCap(context, cap, true)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported); + return false; + } + + return true; +} + +bool ValidateLinkProgram(Context *context, GLuint program) +{ + if (context->hasActiveTransformFeedback(program)) + { + // ES 3.0.4 section 2.15 page 91 + context->handleError(InvalidOperation() << "Cannot link program while program is " + "associated with an active transform " + "feedback object."); + return false; + } + + Program *programObject = GetValidProgram(context, program); + if (!programObject) + { + return false; + } + + return true; +} + +bool ValidateReadPixels(Context *context, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + void *pixels) +{ + return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr, + nullptr, pixels); +} + +bool ValidateTexParameterf(Context *context, GLenum target, GLenum pname, GLfloat param) +{ + return ValidateTexParameterBase(context, target, pname, -1, ¶m); +} + +bool ValidateTexParameterfv(Context *context, GLenum target, GLenum pname, const GLfloat *params) +{ + return ValidateTexParameterBase(context, target, pname, -1, params); +} + +bool ValidateTexParameteri(Context *context, GLenum target, GLenum pname, GLint param) +{ + return ValidateTexParameterBase(context, target, pname, -1, ¶m); +} + +bool ValidateTexParameteriv(Context *context, GLenum target, GLenum pname, const GLint *params) +{ + return ValidateTexParameterBase(context, target, pname, -1, params); +} + +bool ValidateUseProgram(Context *context, GLuint program) +{ + if (program != 0) + { + Program *programObject = context->getProgram(program); + if (!programObject) + { + // ES 3.1.0 section 7.3 page 72 + if (context->getShader(program)) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName); + return false; + } + else + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName); + return false; + } + } + if (!programObject->isLinked()) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked); + return false; + } + } + if (context->getGLState().isTransformFeedbackActiveUnpaused()) + { + // ES 3.0.4 section 2.15 page 91 + context + ->handleError(InvalidOperation() + << "Cannot change active program while transform feedback is unpaused."); + return false; + } + + return true; +} + } // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/validationES2.h b/src/3rdparty/angle/src/libANGLE/validationES2.h index 1b2cf13f60..5dc09176a1 100644 --- a/src/3rdparty/angle/src/libANGLE/validationES2.h +++ b/src/3rdparty/angle/src/libANGLE/validationES2.h @@ -9,6 +9,8 @@ #ifndef LIBANGLE_VALIDATION_ES2_H_ #define LIBANGLE_VALIDATION_ES2_H_ +#include "libANGLE/PackedGLEnums.h" + #include #include @@ -17,37 +19,24 @@ namespace gl class Context; class ValidationContext; -bool ValidateES2TexImageParameters(Context *context, GLenum target, GLint level, GLenum internalformat, bool isCompressed, bool isSubImage, - GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - GLint border, GLenum format, GLenum type, const GLvoid *pixels); +bool ValidateES2TexStorageParameters(Context *context, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height); -bool ValidateES2CopyTexImageParameters(ValidationContext *context, - GLenum target, - GLint level, - GLenum internalformat, - bool isSubImage, - GLint xoffset, - GLint yoffset, - GLint x, - GLint y, - GLsizei width, - GLsizei height, - GLint border); - -bool ValidateES2TexStorageParameters(Context *context, GLenum target, GLsizei levels, GLenum internalformat, - GLsizei width, GLsizei height); - -bool ValidES2ReadFormatType(Context *context, GLenum format, GLenum type); - -bool ValidateDiscardFramebufferEXT(Context *context, GLenum target, GLsizei numAttachments, +bool ValidateDiscardFramebufferEXT(Context *context, + GLenum target, + GLsizei numAttachments, const GLenum *attachments); bool ValidateDrawBuffersEXT(ValidationContext *context, GLsizei n, const GLenum *bufs); bool ValidateBindVertexArrayOES(Context *context, GLuint array); -bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n); -bool ValidateGenVertexArraysOES(Context *context, GLsizei n); -bool ValidateIsVertexArrayOES(Context *context); +bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays); +bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays); +bool ValidateIsVertexArrayOES(Context *context, GLuint array); bool ValidateProgramBinaryOES(Context *context, GLuint program, @@ -128,7 +117,571 @@ bool ValidateBlitFramebufferANGLE(Context *context, GLenum filter); bool ValidateClear(ValidationContext *context, GLbitfield mask); +bool ValidateTexImage2D(Context *context, + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + const void *pixels); +bool ValidateTexImage2DRobust(Context *context, + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels); +bool ValidateTexSubImage2D(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void *pixels); +bool ValidateTexSubImage2DRobustANGLE(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels); +bool ValidateCompressedTexImage2D(Context *context, + GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + const void *data); +bool ValidateCompressedTexSubImage2D(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const void *data); +bool ValidateCompressedTexImage2DRobustANGLE(Context *context, + GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + GLsizei dataSize, + const void *data); +bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + GLsizei dataSize, + const void *data); + +bool ValidateBindTexture(Context *context, GLenum target, GLuint texture); + +bool ValidateGetBufferPointervOES(Context *context, + BufferBinding target, + GLenum pname, + void **params); +bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access); +bool ValidateUnmapBufferOES(Context *context, BufferBinding target); +bool ValidateMapBufferRangeEXT(Context *context, + BufferBinding target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access); +bool ValidateMapBufferBase(Context *context, BufferBinding target); +bool ValidateFlushMappedBufferRangeEXT(Context *context, + BufferBinding target, + GLintptr offset, + GLsizeiptr length); + +bool ValidateBindUniformLocationCHROMIUM(Context *context, + GLuint program, + GLint location, + const GLchar *name); + +bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components); + +// CHROMIUM_path_rendering +bool ValidateMatrix(Context *context, GLenum matrixMode, const GLfloat *matrix); +bool ValidateMatrixMode(Context *context, GLenum matrixMode); +bool ValidateGenPaths(Context *context, GLsizei range); +bool ValidateDeletePaths(Context *context, GLuint first, GLsizei range); +bool ValidatePathCommands(Context *context, + GLuint path, + GLsizei numCommands, + const GLubyte *commands, + GLsizei numCoords, + GLenum coordType, + const void *coords); +bool ValidateSetPathParameter(Context *context, GLuint path, GLenum pname, GLfloat value); +bool ValidateGetPathParameter(Context *context, GLuint path, GLenum pname, GLfloat *value); +bool ValidatePathStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask); +bool ValidateStencilFillPath(Context *context, GLuint path, GLenum fillMode, GLuint mask); +bool ValidateStencilStrokePath(Context *context, GLuint path, GLint reference, GLuint mask); +bool ValidateCoverPath(Context *context, GLuint path, GLenum coverMode); +bool ValidateStencilThenCoverFillPath(Context *context, + GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode); +bool ValidateStencilThenCoverStrokePath(Context *context, + GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode); +bool ValidateIsPath(Context *context); +bool ValidateCoverFillPathInstanced(Context *context, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); +bool ValidateCoverStrokePathInstanced(Context *context, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); +bool ValidateStencilFillPathInstanced(Context *context, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBAse, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); +bool ValidateStencilStrokePathInstanced(Context *context, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); +bool ValidateStencilThenCoverFillPathInstanced(Context *context, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); +bool ValidateStencilThenCoverStrokePathInstanced(Context *context, + GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); +bool ValidateBindFragmentInputLocation(Context *context, + GLuint program, + GLint location, + const GLchar *name); +bool ValidateProgramPathFragmentInputGen(Context *context, + GLuint program, + GLint location, + GLenum genMode, + GLint components, + const GLfloat *coeffs); + +bool ValidateCopyTextureCHROMIUM(Context *context, + GLuint sourceId, + GLint sourceLevel, + GLenum destTarget, + GLuint destId, + GLint destLevel, + GLint internalFormat, + GLenum destType, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha); +bool ValidateCopySubTextureCHROMIUM(Context *context, + GLuint sourceId, + GLint sourceLevel, + GLenum destTarget, + GLuint destId, + GLint destLevel, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha); +bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId); + +bool ValidateCreateShader(Context *context, GLenum type); +bool ValidateBufferData(ValidationContext *context, + BufferBinding target, + GLsizeiptr size, + const void *data, + BufferUsage usage); +bool ValidateBufferSubData(ValidationContext *context, + BufferBinding target, + GLintptr offset, + GLsizeiptr size, + const void *data); + +bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name); + +bool ValidateActiveTexture(ValidationContext *context, GLenum texture); +bool ValidateAttachShader(ValidationContext *context, GLuint program, GLuint shader); +bool ValidateBindAttribLocation(ValidationContext *context, + GLuint program, + GLuint index, + const GLchar *name); +bool ValidateBindBuffer(ValidationContext *context, BufferBinding target, GLuint buffer); +bool ValidateBindFramebuffer(ValidationContext *context, GLenum target, GLuint framebuffer); +bool ValidateBindRenderbuffer(ValidationContext *context, GLenum target, GLuint renderbuffer); +bool ValidateBlendColor(ValidationContext *context, + GLclampf red, + GLclampf green, + GLclampf blue, + GLclampf alpha); +bool ValidateBlendEquation(ValidationContext *context, GLenum mode); +bool ValidateBlendEquationSeparate(ValidationContext *context, GLenum modeRGB, GLenum modeAlpha); +bool ValidateBlendFunc(ValidationContext *context, GLenum sfactor, GLenum dfactor); +bool ValidateBlendFuncSeparate(ValidationContext *context, + GLenum srcRGB, + GLenum dstRGB, + GLenum srcAlpha, + GLenum dstAlpha); + +bool ValidateGetString(Context *context, GLenum name); +bool ValidateLineWidth(ValidationContext *context, GLfloat width); +bool ValidateVertexAttribPointer(ValidationContext *context, + GLuint index, + GLint size, + GLenum type, + GLboolean normalized, + GLsizei stride, + const void *ptr); + +bool ValidateDepthRangef(ValidationContext *context, GLclampf zNear, GLclampf zFar); +bool ValidateRenderbufferStorage(ValidationContext *context, + GLenum target, + GLenum internalformat, + GLsizei width, + GLsizei height); +bool ValidateRenderbufferStorageMultisampleANGLE(ValidationContext *context, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height); + +bool ValidateCheckFramebufferStatus(ValidationContext *context, GLenum target); +bool ValidateClearColor(ValidationContext *context, + GLclampf red, + GLclampf green, + GLclampf blue, + GLclampf alpha); +bool ValidateClearDepthf(ValidationContext *context, GLclampf depth); +bool ValidateClearStencil(ValidationContext *context, GLint s); +bool ValidateColorMask(ValidationContext *context, + GLboolean red, + GLboolean green, + GLboolean blue, + GLboolean alpha); +bool ValidateCompileShader(ValidationContext *context, GLuint shader); +bool ValidateCreateProgram(ValidationContext *context); +bool ValidateCullFace(ValidationContext *context, CullFaceMode mode); +bool ValidateDeleteProgram(ValidationContext *context, GLuint program); +bool ValidateDeleteShader(ValidationContext *context, GLuint shader); +bool ValidateDepthFunc(ValidationContext *context, GLenum func); +bool ValidateDepthMask(ValidationContext *context, GLboolean flag); +bool ValidateDetachShader(ValidationContext *context, GLuint program, GLuint shader); +bool ValidateDisableVertexAttribArray(ValidationContext *context, GLuint index); +bool ValidateEnableVertexAttribArray(ValidationContext *context, GLuint index); +bool ValidateFinish(ValidationContext *context); +bool ValidateFlush(ValidationContext *context); +bool ValidateFrontFace(ValidationContext *context, GLenum mode); +bool ValidateGetActiveAttrib(ValidationContext *context, + GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name); +bool ValidateGetActiveUniform(ValidationContext *context, + GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name); +bool ValidateGetAttachedShaders(ValidationContext *context, + GLuint program, + GLsizei maxcount, + GLsizei *count, + GLuint *shaders); +bool ValidateGetAttribLocation(ValidationContext *context, GLuint program, const GLchar *name); +bool ValidateGetBooleanv(ValidationContext *context, GLenum pname, GLboolean *params); +bool ValidateGetError(ValidationContext *context); +bool ValidateGetFloatv(ValidationContext *context, GLenum pname, GLfloat *params); +bool ValidateGetIntegerv(ValidationContext *context, GLenum pname, GLint *params); +bool ValidateGetProgramInfoLog(ValidationContext *context, + GLuint program, + GLsizei bufsize, + GLsizei *length, + GLchar *infolog); +bool ValidateGetShaderInfoLog(ValidationContext *context, + GLuint shader, + GLsizei bufsize, + GLsizei *length, + GLchar *infolog); +bool ValidateGetShaderPrecisionFormat(ValidationContext *context, + GLenum shadertype, + GLenum precisiontype, + GLint *range, + GLint *precision); +bool ValidateGetShaderSource(ValidationContext *context, + GLuint shader, + GLsizei bufsize, + GLsizei *length, + GLchar *source); +bool ValidateGetUniformLocation(ValidationContext *context, GLuint program, const GLchar *name); +bool ValidateHint(ValidationContext *context, GLenum target, GLenum mode); +bool ValidateIsBuffer(ValidationContext *context, GLuint buffer); +bool ValidateIsFramebuffer(ValidationContext *context, GLuint framebuffer); +bool ValidateIsProgram(ValidationContext *context, GLuint program); +bool ValidateIsRenderbuffer(ValidationContext *context, GLuint renderbuffer); +bool ValidateIsShader(ValidationContext *context, GLuint shader); +bool ValidateIsTexture(ValidationContext *context, GLuint texture); +bool ValidatePixelStorei(ValidationContext *context, GLenum pname, GLint param); +bool ValidatePolygonOffset(ValidationContext *context, GLfloat factor, GLfloat units); +bool ValidateReleaseShaderCompiler(ValidationContext *context); +bool ValidateSampleCoverage(ValidationContext *context, GLclampf value, GLboolean invert); +bool ValidateScissor(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height); +bool ValidateShaderBinary(ValidationContext *context, + GLsizei n, + const GLuint *shaders, + GLenum binaryformat, + const void *binary, + GLsizei length); +bool ValidateShaderSource(ValidationContext *context, + GLuint shader, + GLsizei count, + const GLchar *const *string, + const GLint *length); +bool ValidateStencilFunc(ValidationContext *context, GLenum func, GLint ref, GLuint mask); +bool ValidateStencilFuncSeparate(ValidationContext *context, + GLenum face, + GLenum func, + GLint ref, + GLuint mask); +bool ValidateStencilMask(ValidationContext *context, GLuint mask); +bool ValidateStencilMaskSeparate(ValidationContext *context, GLenum face, GLuint mask); +bool ValidateStencilOp(ValidationContext *context, GLenum fail, GLenum zfail, GLenum zpass); +bool ValidateStencilOpSeparate(ValidationContext *context, + GLenum face, + GLenum fail, + GLenum zfail, + GLenum zpass); +bool ValidateUniform1f(ValidationContext *context, GLint location, GLfloat x); +bool ValidateUniform1fv(ValidationContext *context, + GLint location, + GLsizei count, + const GLfloat *v); +bool ValidateUniform1i(ValidationContext *context, GLint location, GLint x); +bool ValidateUniform2f(ValidationContext *context, GLint location, GLfloat x, GLfloat y); +bool ValidateUniform2fv(ValidationContext *context, + GLint location, + GLsizei count, + const GLfloat *v); +bool ValidateUniform2i(ValidationContext *context, GLint location, GLint x, GLint y); +bool ValidateUniform2iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v); +bool ValidateUniform3f(ValidationContext *context, GLint location, GLfloat x, GLfloat y, GLfloat z); +bool ValidateUniform3fv(ValidationContext *context, + GLint location, + GLsizei count, + const GLfloat *v); +bool ValidateUniform3i(ValidationContext *context, GLint location, GLint x, GLint y, GLint z); +bool ValidateUniform3iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v); +bool ValidateUniform4f(ValidationContext *context, + GLint location, + GLfloat x, + GLfloat y, + GLfloat z, + GLfloat w); +bool ValidateUniform4fv(ValidationContext *context, + GLint location, + GLsizei count, + const GLfloat *v); +bool ValidateUniform4i(ValidationContext *context, + GLint location, + GLint x, + GLint y, + GLint z, + GLint w); +bool ValidateUniform4iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v); +bool ValidateUniformMatrix2fv(ValidationContext *context, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateUniformMatrix3fv(ValidationContext *context, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateUniformMatrix4fv(ValidationContext *context, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateValidateProgram(ValidationContext *context, GLuint program); +bool ValidateVertexAttrib1f(ValidationContext *context, GLuint index, GLfloat x); +bool ValidateVertexAttrib1fv(ValidationContext *context, GLuint index, const GLfloat *values); +bool ValidateVertexAttrib2f(ValidationContext *context, GLuint index, GLfloat x, GLfloat y); +bool ValidateVertexAttrib2fv(ValidationContext *context, GLuint index, const GLfloat *values); +bool ValidateVertexAttrib3f(ValidationContext *context, + GLuint index, + GLfloat x, + GLfloat y, + GLfloat z); +bool ValidateVertexAttrib3fv(ValidationContext *context, GLuint index, const GLfloat *values); +bool ValidateVertexAttrib4f(ValidationContext *context, + GLuint index, + GLfloat x, + GLfloat y, + GLfloat z, + GLfloat w); +bool ValidateVertexAttrib4fv(ValidationContext *context, GLuint index, const GLfloat *values); +bool ValidateViewport(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height); +bool ValidateDrawElements(ValidationContext *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices); + +bool ValidateDrawArrays(ValidationContext *context, GLenum mode, GLint first, GLsizei count); + +bool ValidateGetFramebufferAttachmentParameteriv(ValidationContext *context, + GLenum target, + GLenum attachment, + GLenum pname, + GLint *params); +bool ValidateGetProgramiv(ValidationContext *context, GLuint program, GLenum pname, GLint *params); + +bool ValidateCopyTexImage2D(ValidationContext *context, + GLenum target, + GLint level, + GLenum internalformat, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border); + +bool ValidateCopyTexSubImage2D(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height); + +bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *buffers); +bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *framebuffers); +bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *renderbuffers); +bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *textures); +bool ValidateDisable(Context *context, GLenum cap); +bool ValidateEnable(Context *context, GLenum cap); +bool ValidateFramebufferRenderbuffer(Context *context, + GLenum target, + GLenum attachment, + GLenum renderbuffertarget, + GLuint renderbuffer); +bool ValidateFramebufferTexture2D(Context *context, + GLenum target, + GLenum attachment, + GLenum textarget, + GLuint texture, + GLint level); +bool ValidateGenBuffers(Context *context, GLint n, GLuint *buffers); +bool ValidateGenerateMipmap(Context *context, GLenum target); +bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *framebuffers); +bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *renderbuffers); +bool ValidateGenTextures(Context *context, GLint n, GLuint *textures); +bool ValidateGetBufferParameteriv(ValidationContext *context, + BufferBinding target, + GLenum pname, + GLint *params); +bool ValidateGetRenderbufferParameteriv(Context *context, + GLenum target, + GLenum pname, + GLint *params); +bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params); +bool ValidateGetTexParameterfv(Context *context, GLenum target, GLenum pname, GLfloat *params); +bool ValidateGetTexParameteriv(Context *context, GLenum target, GLenum pname, GLint *params); +bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params); +bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params); +bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params); +bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params); +bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer); +bool ValidateIsEnabled(Context *context, GLenum cap); +bool ValidateLinkProgram(Context *context, GLuint program); +bool ValidateReadPixels(Context *context, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + void *pixels); +bool ValidateTexParameterf(Context *context, GLenum target, GLenum pname, GLfloat param); +bool ValidateTexParameterfv(Context *context, GLenum target, GLenum pname, const GLfloat *params); +bool ValidateTexParameteri(Context *context, GLenum target, GLenum pname, GLint param); +bool ValidateTexParameteriv(Context *context, GLenum target, GLenum pname, const GLint *params); +bool ValidateUniform1iv(ValidationContext *context, + GLint location, + GLsizei count, + const GLint *value); +bool ValidateUseProgram(Context *context, GLuint program); } // namespace gl -#endif // LIBANGLE_VALIDATION_ES2_H_ +#endif // LIBANGLE_VALIDATION_ES2_H_ diff --git a/src/3rdparty/angle/src/libANGLE/validationES3.cpp b/src/3rdparty/angle/src/libANGLE/validationES3.cpp index 2db64ec4cc..1aadfc876e 100644 --- a/src/3rdparty/angle/src/libANGLE/validationES3.cpp +++ b/src/3rdparty/angle/src/libANGLE/validationES3.cpp @@ -7,255 +7,190 @@ // validationES3.cpp: Validation functions for OpenGL ES 3.0 entry point parameters #include "libANGLE/validationES3.h" -#include "libANGLE/validationES.h" -#include "libANGLE/Context.h" -#include "libANGLE/Texture.h" -#include "libANGLE/Framebuffer.h" -#include "libANGLE/Renderbuffer.h" -#include "libANGLE/formatutils.h" -#include "libANGLE/FramebufferAttachment.h" +#include "anglebase/numerics/safe_conversions.h" #include "common/mathutil.h" #include "common/utilities.h" +#include "libANGLE/Context.h" +#include "libANGLE/ErrorStrings.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/FramebufferAttachment.h" +#include "libANGLE/Renderbuffer.h" +#include "libANGLE/Texture.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/validationES.h" + +using namespace angle; namespace gl { -struct ES3FormatCombination +namespace { - GLenum internalFormat; - GLenum format; - GLenum type; -}; +bool ValidateFramebufferTextureMultiviewBaseANGLE(Context *context, + GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLsizei numViews) +{ + if (!context->getExtensions().multiview) + { + context->handleError(InvalidOperation() << "ANGLE_multiview is not available."); + return false; + } -bool operator<(const ES3FormatCombination& a, const ES3FormatCombination& b) -{ - return memcmp(&a, &b, sizeof(ES3FormatCombination)) < 0; + if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level)) + { + return false; + } + + if (texture != 0 && numViews < 1) + { + context->handleError(InvalidValue() << "numViews cannot be less than 1."); + return false; + } + + const Extensions &extensions = context->getExtensions(); + if (static_cast(numViews) > extensions.maxViews) + { + context->handleError(InvalidValue() + << "numViews cannot be greater than GL_MAX_VIEWS_ANGLE."); + return false; + } + + return true; } -typedef std::set ES3FormatCombinationSet; - -static inline void InsertES3FormatCombo(ES3FormatCombinationSet *set, GLenum internalFormat, GLenum format, GLenum type) +bool ValidateFramebufferTextureMultiviewLevelAndFormat(Context *context, + Texture *texture, + GLint level) { - ES3FormatCombination info; - info.internalFormat = internalFormat; - info.format = format; - info.type = type; - set->insert(info); + GLenum texTarget = texture->getTarget(); + if (!ValidMipLevel(context, texTarget, level)) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel); + return false; + } + + const auto &format = texture->getFormat(texTarget, level); + if (format.info->compressed) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), CompressedTexturesNotAttachable); + return false; + } + return true; } -ES3FormatCombinationSet BuildES3FormatSet() +bool ValidateUniformES3(Context *context, GLenum uniformType, GLint location, GLint count) { - ES3FormatCombinationSet set; + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } - // Format combinations from ES 3.0.1 spec, table 3.2 - - // | Internal format | Format | Type | - // | | | | - InsertES3FormatCombo(&set, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_RGBA4, GL_RGBA, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_RGBA8_SNORM, GL_RGBA, GL_BYTE ); - InsertES3FormatCombo(&set, GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4 ); - InsertES3FormatCombo(&set, GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV ); - InsertES3FormatCombo(&set, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV ); - InsertES3FormatCombo(&set, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1 ); - InsertES3FormatCombo(&set, GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT ); - InsertES3FormatCombo(&set, GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT_OES ); - InsertES3FormatCombo(&set, GL_RGBA32F, GL_RGBA, GL_FLOAT ); - InsertES3FormatCombo(&set, GL_RGBA16F, GL_RGBA, GL_FLOAT ); - InsertES3FormatCombo(&set, GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE ); - InsertES3FormatCombo(&set, GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT ); - InsertES3FormatCombo(&set, GL_RGBA16I, GL_RGBA_INTEGER, GL_SHORT ); - InsertES3FormatCombo(&set, GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT ); - InsertES3FormatCombo(&set, GL_RGBA32I, GL_RGBA_INTEGER, GL_INT ); - InsertES3FormatCombo(&set, GL_RGB10_A2UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV ); - InsertES3FormatCombo(&set, GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_RGB565, GL_RGB, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_SRGB8, GL_RGB, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_RGB8_SNORM, GL_RGB, GL_BYTE ); - InsertES3FormatCombo(&set, GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5 ); - InsertES3FormatCombo(&set, GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV ); - InsertES3FormatCombo(&set, GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV ); - InsertES3FormatCombo(&set, GL_RGB16F, GL_RGB, GL_HALF_FLOAT ); - InsertES3FormatCombo(&set, GL_RGB16F, GL_RGB, GL_HALF_FLOAT_OES ); - InsertES3FormatCombo(&set, GL_R11F_G11F_B10F, GL_RGB, GL_HALF_FLOAT ); - InsertES3FormatCombo(&set, GL_R11F_G11F_B10F, GL_RGB, GL_HALF_FLOAT_OES ); - InsertES3FormatCombo(&set, GL_RGB9_E5, GL_RGB, GL_HALF_FLOAT ); - InsertES3FormatCombo(&set, GL_RGB9_E5, GL_RGB, GL_HALF_FLOAT_OES ); - InsertES3FormatCombo(&set, GL_RGB32F, GL_RGB, GL_FLOAT ); - InsertES3FormatCombo(&set, GL_RGB16F, GL_RGB, GL_FLOAT ); - InsertES3FormatCombo(&set, GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT ); - InsertES3FormatCombo(&set, GL_RGB9_E5, GL_RGB, GL_FLOAT ); - InsertES3FormatCombo(&set, GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_RGB8I, GL_RGB_INTEGER, GL_BYTE ); - InsertES3FormatCombo(&set, GL_RGB16UI, GL_RGB_INTEGER, GL_UNSIGNED_SHORT ); - InsertES3FormatCombo(&set, GL_RGB16I, GL_RGB_INTEGER, GL_SHORT ); - InsertES3FormatCombo(&set, GL_RGB32UI, GL_RGB_INTEGER, GL_UNSIGNED_INT ); - InsertES3FormatCombo(&set, GL_RGB32I, GL_RGB_INTEGER, GL_INT ); - InsertES3FormatCombo(&set, GL_RG8, GL_RG, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_RG8_SNORM, GL_RG, GL_BYTE ); - InsertES3FormatCombo(&set, GL_RG16F, GL_RG, GL_HALF_FLOAT ); - InsertES3FormatCombo(&set, GL_RG16F, GL_RG, GL_HALF_FLOAT_OES ); - InsertES3FormatCombo(&set, GL_RG32F, GL_RG, GL_FLOAT ); - InsertES3FormatCombo(&set, GL_RG16F, GL_RG, GL_FLOAT ); - InsertES3FormatCombo(&set, GL_RG8UI, GL_RG_INTEGER, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_RG8I, GL_RG_INTEGER, GL_BYTE ); - InsertES3FormatCombo(&set, GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT ); - InsertES3FormatCombo(&set, GL_RG16I, GL_RG_INTEGER, GL_SHORT ); - InsertES3FormatCombo(&set, GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT ); - InsertES3FormatCombo(&set, GL_RG32I, GL_RG_INTEGER, GL_INT ); - InsertES3FormatCombo(&set, GL_R8, GL_RED, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_R8_SNORM, GL_RED, GL_BYTE ); - InsertES3FormatCombo(&set, GL_R16F, GL_RED, GL_HALF_FLOAT ); - InsertES3FormatCombo(&set, GL_R16F, GL_RED, GL_HALF_FLOAT_OES ); - InsertES3FormatCombo(&set, GL_R32F, GL_RED, GL_FLOAT ); - InsertES3FormatCombo(&set, GL_R16F, GL_RED, GL_FLOAT ); - InsertES3FormatCombo(&set, GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_R8I, GL_RED_INTEGER, GL_BYTE ); - InsertES3FormatCombo(&set, GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT ); - InsertES3FormatCombo(&set, GL_R16I, GL_RED_INTEGER, GL_SHORT ); - InsertES3FormatCombo(&set, GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT ); - InsertES3FormatCombo(&set, GL_R32I, GL_RED_INTEGER, GL_INT ); - - // Unsized formats - InsertES3FormatCombo(&set, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4 ); - InsertES3FormatCombo(&set, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1 ); - InsertES3FormatCombo(&set, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5 ); - InsertES3FormatCombo(&set, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_SRGB_ALPHA_EXT, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_SRGB_EXT, GL_SRGB_EXT, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_RG, GL_RG, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_RG, GL_RG, GL_FLOAT ); - InsertES3FormatCombo(&set, GL_RG, GL_RG, GL_HALF_FLOAT ); - InsertES3FormatCombo(&set, GL_RG, GL_RG, GL_HALF_FLOAT_OES ); - InsertES3FormatCombo(&set, GL_RED, GL_RED, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_RED, GL_RED, GL_FLOAT ); - InsertES3FormatCombo(&set, GL_RED, GL_RED, GL_HALF_FLOAT ); - InsertES3FormatCombo(&set, GL_RED, GL_RED, GL_HALF_FLOAT_OES ); - InsertES3FormatCombo(&set, GL_DEPTH_STENCIL, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8 ); - - // Depth stencil formats - InsertES3FormatCombo(&set, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT ); - InsertES3FormatCombo(&set, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT ); - InsertES3FormatCombo(&set, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT ); - InsertES3FormatCombo(&set, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT ); - InsertES3FormatCombo(&set, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8 ); - InsertES3FormatCombo(&set, GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV); - - // From GL_EXT_sRGB - InsertES3FormatCombo(&set, GL_SRGB8_ALPHA8_EXT, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_SRGB8, GL_SRGB_EXT, GL_UNSIGNED_BYTE ); - - // From GL_OES_texture_float - InsertES3FormatCombo(&set, GL_RGBA, GL_RGBA, GL_FLOAT ); - InsertES3FormatCombo(&set, GL_RGB, GL_RGB, GL_FLOAT ); - InsertES3FormatCombo(&set, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_FLOAT ); - InsertES3FormatCombo(&set, GL_LUMINANCE, GL_LUMINANCE, GL_FLOAT ); - InsertES3FormatCombo(&set, GL_ALPHA, GL_ALPHA, GL_FLOAT ); - - // From GL_OES_texture_half_float - InsertES3FormatCombo(&set, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT ); - InsertES3FormatCombo(&set, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES ); - InsertES3FormatCombo(&set, GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT ); - InsertES3FormatCombo(&set, GL_LUMINANCE, GL_LUMINANCE, GL_HALF_FLOAT_OES ); - InsertES3FormatCombo(&set, GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT ); - InsertES3FormatCombo(&set, GL_ALPHA, GL_ALPHA, GL_HALF_FLOAT_OES ); - - // From GL_EXT_texture_format_BGRA8888 - InsertES3FormatCombo(&set, GL_BGRA_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE ); - - // From GL_EXT_texture_storage - // | Internal format | Format | Type | - // | | | | - InsertES3FormatCombo(&set, GL_ALPHA8_EXT, GL_ALPHA, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_LUMINANCE8_EXT, GL_LUMINANCE, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_LUMINANCE8_ALPHA8_EXT, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_ALPHA32F_EXT, GL_ALPHA, GL_FLOAT ); - InsertES3FormatCombo(&set, GL_LUMINANCE32F_EXT, GL_LUMINANCE, GL_FLOAT ); - InsertES3FormatCombo(&set, GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA, GL_FLOAT ); - InsertES3FormatCombo(&set, GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT ); - InsertES3FormatCombo(&set, GL_ALPHA16F_EXT, GL_ALPHA, GL_HALF_FLOAT_OES ); - InsertES3FormatCombo(&set, GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT ); - InsertES3FormatCombo(&set, GL_LUMINANCE16F_EXT, GL_LUMINANCE, GL_HALF_FLOAT_OES ); - InsertES3FormatCombo(&set, GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT ); - InsertES3FormatCombo(&set, GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES ); - - // From GL_EXT_texture_storage and GL_EXT_texture_format_BGRA8888 - InsertES3FormatCombo(&set, GL_BGRA8_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_BGRA4_ANGLEX, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT); - InsertES3FormatCombo(&set, GL_BGRA4_ANGLEX, GL_BGRA_EXT, GL_UNSIGNED_BYTE ); - InsertES3FormatCombo(&set, GL_BGR5_A1_ANGLEX, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT); - InsertES3FormatCombo(&set, GL_BGR5_A1_ANGLEX, GL_BGRA_EXT, GL_UNSIGNED_BYTE ); - - // From GL_ANGLE_depth_texture - InsertES3FormatCombo(&set, GL_DEPTH_COMPONENT32_OES, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8_OES ); - - return set; + return ValidateUniform(context, uniformType, location, count); } -static bool ValidateTexImageFormatCombination(gl::Context *context, GLenum internalFormat, GLenum format, GLenum type) +bool ValidateUniformMatrixES3(Context *context, + GLenum valueType, + GLint location, + GLsizei count, + GLboolean transpose) { + // Check for ES3 uniform entry points + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + return ValidateUniformMatrix(context, valueType, location, count, transpose); +} + +bool ValidateGenOrDeleteES3(Context *context, GLint n) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + return ValidateGenOrDelete(context, n); +} + +bool ValidateGenOrDeleteCountES3(Context *context, GLint count) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + if (count < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount); + return false; + } + return true; +} + +} // anonymous namespace + +static bool ValidateTexImageFormatCombination(gl::Context *context, + GLenum target, + GLenum internalFormat, + GLenum format, + GLenum type) +{ + + // The type and format are valid if any supported internal format has that type and format + if (!ValidES3Format(format)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFormat); + return false; + } + + if (!ValidES3Type(type)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType); + return false; + } + // For historical reasons, glTexImage2D and glTexImage3D pass in their internal format as a // GLint instead of a GLenum. Therefor an invalid internal format gives a GL_INVALID_VALUE // error instead of a GL_INVALID_ENUM error. As this validation function is only called in // the validation codepaths for glTexImage2D/3D, we record a GL_INVALID_VALUE error. - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); - if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions())) + if (!ValidES3InternalFormat(internalFormat)) { - context->recordError(Error(GL_INVALID_VALUE)); + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidInternalFormat); return false; } - // The type and format are valid if any supported internal format has that type and format - bool formatSupported = false; - bool typeSupported = false; - - static const ES3FormatCombinationSet es3FormatSet = BuildES3FormatSet(); - for (ES3FormatCombinationSet::const_iterator i = es3FormatSet.begin(); i != es3FormatSet.end(); i++) + // From the ES 3.0 spec section 3.8.3: + // Textures with a base internal format of DEPTH_COMPONENT or DEPTH_STENCIL are supported by + // texture image specification commands only if target is TEXTURE_2D, TEXTURE_2D_ARRAY, or + // TEXTURE_CUBE_MAP.Using these formats in conjunction with any other target will result in an + // INVALID_OPERATION error. + if (target == GL_TEXTURE_3D && (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL)) { - if (i->format == format || i->type == type) - { - const gl::InternalFormat &info = gl::GetInternalFormatInfo(i->internalFormat); - bool supported = info.textureSupport(context->getClientVersion(), context->getExtensions()); - if (supported && i->type == type) - { - typeSupported = true; - } - if (supported && i->format == format) - { - formatSupported = true; - } - - // Early-out if both type and format are supported now - if (typeSupported && formatSupported) - { - break; - } - } - } - - if (!typeSupported || !formatSupported) - { - context->recordError(Error(GL_INVALID_ENUM)); + context->handleError(InvalidOperation() << "Format cannot be GL_DEPTH_COMPONENT or " + "GL_DEPTH_STENCIL if target is " + "GL_TEXTURE_3D"); return false; } // Check if this is a valid format combination to load texture data - ES3FormatCombination searchFormat; - searchFormat.internalFormat = internalFormat; - searchFormat.format = format; - searchFormat.type = type; - - if (es3FormatSet.find(searchFormat) == es3FormatSet.end()) + if (!ValidES3FormatCombination(format, type, internalFormat)) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation() + << "Invalid combination of format, type and internalFormat."); + return false; + } + + const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat, type); + if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions())) + { + context->handleError(InvalidOperation() << "Unsupported internal format."); return false; } @@ -277,19 +212,20 @@ bool ValidateES3TexImageParametersBase(Context *context, GLint border, GLenum format, GLenum type, - const GLvoid *pixels) + GLsizei imageSize, + const void *pixels) { // Validate image size if (!ValidImageSizeParameters(context, target, level, width, height, depth, isSubImage)) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } // Verify zero border if (border != 0) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } @@ -298,7 +234,7 @@ bool ValidateES3TexImageParametersBase(Context *context, std::numeric_limits::max() - yoffset < height || std::numeric_limits::max() - zoffset < depth) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } @@ -306,114 +242,160 @@ bool ValidateES3TexImageParametersBase(Context *context, switch (target) { - case GL_TEXTURE_2D: - if (static_cast(width) > (caps.max2DTextureSize >> level) || - static_cast(height) > (caps.max2DTextureSize >> level)) - { - context->recordError(Error(GL_INVALID_VALUE)); - return false; - } - break; + case GL_TEXTURE_2D: + if (static_cast(width) > (caps.max2DTextureSize >> level) || + static_cast(height) > (caps.max2DTextureSize >> level)) + { + context->handleError(InvalidValue()); + return false; + } + break; - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - if (!isSubImage && width != height) - { - context->recordError(Error(GL_INVALID_VALUE)); - return false; - } + case GL_TEXTURE_RECTANGLE_ANGLE: + ASSERT(level == 0); + if (static_cast(width) > caps.maxRectangleTextureSize || + static_cast(height) > caps.maxRectangleTextureSize) + { + context->handleError(InvalidValue()); + return false; + } + if (isCompressed) + { + context->handleError(InvalidEnum() + << "Rectangle texture cannot have a compressed format."); + return false; + } + break; - if (static_cast(width) > (caps.maxCubeMapTextureSize >> level)) - { - context->recordError(Error(GL_INVALID_VALUE)); - return false; - } - break; + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + if (!isSubImage && width != height) + { + context->handleError(InvalidValue()); + return false; + } - case GL_TEXTURE_3D: - if (static_cast(width) > (caps.max3DTextureSize >> level) || - static_cast(height) > (caps.max3DTextureSize >> level) || - static_cast(depth) > (caps.max3DTextureSize >> level)) - { - context->recordError(Error(GL_INVALID_VALUE)); - return false; - } - break; + if (static_cast(width) > (caps.maxCubeMapTextureSize >> level)) + { + context->handleError(InvalidValue()); + return false; + } + break; - case GL_TEXTURE_2D_ARRAY: - if (static_cast(width) > (caps.max2DTextureSize >> level) || - static_cast(height) > (caps.max2DTextureSize >> level) || - static_cast(depth) > caps.maxArrayTextureLayers) - { - context->recordError(Error(GL_INVALID_VALUE)); - return false; - } - break; + case GL_TEXTURE_3D: + if (static_cast(width) > (caps.max3DTextureSize >> level) || + static_cast(height) > (caps.max3DTextureSize >> level) || + static_cast(depth) > (caps.max3DTextureSize >> level)) + { + context->handleError(InvalidValue()); + return false; + } + break; - default: - context->recordError(Error(GL_INVALID_ENUM)); - return false; + case GL_TEXTURE_2D_ARRAY: + if (static_cast(width) > (caps.max2DTextureSize >> level) || + static_cast(height) > (caps.max2DTextureSize >> level) || + static_cast(depth) > caps.maxArrayTextureLayers) + { + context->handleError(InvalidValue()); + return false; + } + break; + + default: + context->handleError(InvalidEnum()); + return false; } - gl::Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); + gl::Texture *texture = + context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); if (!texture) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } if (texture->getImmutableFormat() && !isSubImage) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } // Validate texture formats - GLenum actualInternalFormat = isSubImage ? texture->getInternalFormat(target, level) : internalformat; - const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(actualInternalFormat); + GLenum actualInternalFormat = + isSubImage ? texture->getFormat(target, level).info->internalFormat : internalformat; + if (isSubImage && actualInternalFormat == GL_NONE) + { + context->handleError(InvalidOperation() << "Texture level does not exist."); + return false; + } + + const gl::InternalFormat &actualFormatInfo = isSubImage + ? *texture->getFormat(target, level).info + : GetInternalFormatInfo(internalformat, type); if (isCompressed) { if (!actualFormatInfo.compressed) { - context->recordError(Error( - GL_INVALID_ENUM, "internalformat is not a supported compressed internal format.")); + context->handleError( + InvalidEnum() << "internalformat is not a supported compressed internal format."); return false; } - if (!ValidCompressedImageSize(context, actualInternalFormat, width, height)) + if (isSubImage) { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; + if (!ValidCompressedSubImageSize( + context, actualFormatInfo.internalFormat, xoffset, yoffset, width, height, + texture->getWidth(target, level), texture->getHeight(target, level))) + { + context->handleError(InvalidOperation() << "Invalid compressed format dimension."); + return false; + } + + if (format != actualInternalFormat) + { + context->handleError(InvalidOperation() + << "Format must match the internal format of the texture."); + return false; + } + + if (actualInternalFormat == GL_ETC1_RGB8_OES) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat); + return false; + } + } + else + { + if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height)) + { + context->handleError(InvalidOperation() << "Invalid compressed format dimension."); + return false; + } } if (!actualFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions())) { - context->recordError(Error(GL_INVALID_ENUM)); + context->handleError(InvalidEnum()); return false; } if (target == GL_TEXTURE_3D) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } } else { - if (!ValidateTexImageFormatCombination(context, actualInternalFormat, format, type)) + if (!ValidateTexImageFormatCombination(context, target, actualInternalFormat, format, type)) { return false; } - - if (target == GL_TEXTURE_3D && (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } } // Validate sub image parameters @@ -421,18 +403,13 @@ bool ValidateES3TexImageParametersBase(Context *context, { if (isCompressed != actualFormatInfo.compressed) { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - - if (width == 0 || height == 0 || depth == 0) - { + context->handleError(InvalidOperation()); return false; } if (xoffset < 0 || yoffset < 0 || zoffset < 0) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } @@ -440,7 +417,7 @@ bool ValidateES3TexImageParametersBase(Context *context, std::numeric_limits::max() - yoffset < height || std::numeric_limits::max() - zoffset < depth) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } @@ -448,54 +425,42 @@ bool ValidateES3TexImageParametersBase(Context *context, static_cast(yoffset + height) > texture->getHeight(target, level) || static_cast(zoffset + depth) > texture->getDepth(target, level)) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); + return false; + } + + if (width > 0 && height > 0 && depth > 0 && pixels == nullptr && + context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack) == nullptr) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull); return false; } } - // Check for pixel unpack buffer related API errors - gl::Buffer *pixelUnpackBuffer = context->getState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER); - if (pixelUnpackBuffer != NULL) + GLenum sizeCheckFormat = isSubImage ? format : internalformat; + if (!ValidImageDataSize(context, target, width, height, depth, sizeCheckFormat, type, pixels, + imageSize)) { - // ...the data would be unpacked from the buffer object such that the memory reads required - // would exceed the data store size. - size_t widthSize = static_cast(width); - size_t heightSize = static_cast(height); - size_t depthSize = static_cast(depth); - GLenum sizedFormat = GetSizedInternalFormat(actualInternalFormat, type); + return false; + } - size_t pixelBytes = static_cast(gl::GetInternalFormatInfo(sizedFormat).pixelBytes); - - if (!rx::IsUnsignedMultiplicationSafe(widthSize, heightSize) || - !rx::IsUnsignedMultiplicationSafe(widthSize * heightSize, depthSize) || - !rx::IsUnsignedMultiplicationSafe(widthSize * heightSize * depthSize, pixelBytes)) - { - // Overflow past the end of the buffer - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(sizedFormat); - size_t copyBytes = formatInfo.computeBlockSize(type, width, height); - size_t offset = reinterpret_cast(pixels); - - if (!rx::IsUnsignedAdditionSafe(offset, copyBytes) || - ((offset + copyBytes) > static_cast(pixelUnpackBuffer->getSize()))) - { - // Overflow past the end of the buffer - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - - // ...data is not evenly divisible into the number of bytes needed to store in memory a datum + // Check for pixel unpack buffer related API errors + gl::Buffer *pixelUnpackBuffer = + context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack); + if (pixelUnpackBuffer != nullptr) + { + // ...data is not evenly divisible into the number of bytes needed to store in memory a + // datum // indicated by type. if (!isCompressed) { + size_t offset = reinterpret_cast(pixels); size_t dataBytesPerPixel = static_cast(gl::GetTypeInfo(type).bytes); if ((offset % dataBytesPerPixel) != 0) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation() + << "Reads would overflow the pixel unpack buffer."); return false; } } @@ -503,7 +468,7 @@ bool ValidateES3TexImageParametersBase(Context *context, // ...the buffer object's data store is currently mapped. if (pixelUnpackBuffer->isMapped()) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation() << "Pixel unpack buffer is mapped."); return false; } } @@ -526,17 +491,18 @@ bool ValidateES3TexImage2DParameters(Context *context, GLint border, GLenum format, GLenum type, - const GLvoid *pixels) + GLsizei imageSize, + const void *pixels) { if (!ValidTexture2DDestinationTarget(context, target)) { - context->recordError(Error(GL_INVALID_ENUM)); + context->handleError(InvalidEnum()); return false; } return ValidateES3TexImageParametersBase(context, target, level, internalformat, isCompressed, isSubImage, xoffset, yoffset, zoffset, width, height, - depth, border, format, type, pixels); + depth, border, format, type, imageSize, pixels); } bool ValidateES3TexImage3DParameters(Context *context, @@ -554,301 +520,260 @@ bool ValidateES3TexImage3DParameters(Context *context, GLint border, GLenum format, GLenum type, - const GLvoid *pixels) + GLsizei bufSize, + const void *pixels) { if (!ValidTexture3DDestinationTarget(context, target)) { - context->recordError(Error(GL_INVALID_ENUM)); + context->handleError(InvalidEnum()); return false; } return ValidateES3TexImageParametersBase(context, target, level, internalformat, isCompressed, isSubImage, xoffset, yoffset, zoffset, width, height, - depth, border, format, type, pixels); + depth, border, format, type, bufSize, pixels); } struct EffectiveInternalFormatInfo { - GLenum mEffectiveFormat; - GLenum mDestFormat; - GLuint mMinRedBits; - GLuint mMaxRedBits; - GLuint mMinGreenBits; - GLuint mMaxGreenBits; - GLuint mMinBlueBits; - GLuint mMaxBlueBits; - GLuint mMinAlphaBits; - GLuint mMaxAlphaBits; - - EffectiveInternalFormatInfo(GLenum effectiveFormat, GLenum destFormat, GLuint minRedBits, GLuint maxRedBits, - GLuint minGreenBits, GLuint maxGreenBits, GLuint minBlueBits, GLuint maxBlueBits, - GLuint minAlphaBits, GLuint maxAlphaBits) - : mEffectiveFormat(effectiveFormat), mDestFormat(destFormat), mMinRedBits(minRedBits), - mMaxRedBits(maxRedBits), mMinGreenBits(minGreenBits), mMaxGreenBits(maxGreenBits), - mMinBlueBits(minBlueBits), mMaxBlueBits(maxBlueBits), mMinAlphaBits(minAlphaBits), - mMaxAlphaBits(maxAlphaBits) {}; + GLenum effectiveFormat; + GLenum destFormat; + GLuint minRedBits; + GLuint maxRedBits; + GLuint minGreenBits; + GLuint maxGreenBits; + GLuint minBlueBits; + GLuint maxBlueBits; + GLuint minAlphaBits; + GLuint maxAlphaBits; }; -typedef std::vector EffectiveInternalFormatList; - -static EffectiveInternalFormatList BuildSizedEffectiveInternalFormatList() +static bool QueryEffectiveFormatList(const InternalFormat &srcFormat, + GLenum targetFormat, + const EffectiveInternalFormatInfo *list, + size_t size, + GLenum *outEffectiveFormat) { - EffectiveInternalFormatList list; - - // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141: Effective internal format coresponding to destination internal format and - // linear source buffer component sizes. - // | Source channel min/max sizes | - // Effective Internal Format | N/A | R | G | B | A | - list.push_back(EffectiveInternalFormatInfo(GL_ALPHA8_EXT, GL_NONE, 0, 0, 0, 0, 0, 0, 1, 8)); - list.push_back(EffectiveInternalFormatInfo(GL_R8, GL_NONE, 1, 8, 0, 0, 0, 0, 0, 0)); - list.push_back(EffectiveInternalFormatInfo(GL_RG8, GL_NONE, 1, 8, 1, 8, 0, 0, 0, 0)); - list.push_back(EffectiveInternalFormatInfo(GL_RGB565, GL_NONE, 1, 5, 1, 6, 1, 5, 0, 0)); - list.push_back(EffectiveInternalFormatInfo(GL_RGB8, GL_NONE, 6, 8, 7, 8, 6, 8, 0, 0)); - list.push_back(EffectiveInternalFormatInfo(GL_RGBA4, GL_NONE, 1, 4, 1, 4, 1, 4, 1, 4)); - list.push_back(EffectiveInternalFormatInfo(GL_RGB5_A1, GL_NONE, 5, 5, 5, 5, 5, 5, 1, 1)); - list.push_back(EffectiveInternalFormatInfo(GL_RGBA8, GL_NONE, 5, 8, 5, 8, 5, 8, 2, 8)); - list.push_back(EffectiveInternalFormatInfo(GL_RGB10_A2, GL_NONE, 9, 10, 9, 10, 9, 10, 2, 2)); - - return list; -} - -static EffectiveInternalFormatList BuildUnsizedEffectiveInternalFormatList() -{ - EffectiveInternalFormatList list; - - // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141: Effective internal format coresponding to destination internal format and - // linear source buffer component sizes. - // | Source channel min/max sizes | - // Effective Internal Format | Dest Format | R | G | B | A | - list.push_back(EffectiveInternalFormatInfo(GL_ALPHA8_EXT, GL_ALPHA, 0, UINT_MAX, 0, UINT_MAX, 0, UINT_MAX, 1, 8)); - list.push_back(EffectiveInternalFormatInfo(GL_LUMINANCE8_EXT, GL_LUMINANCE, 1, 8, 0, UINT_MAX, 0, UINT_MAX, 0, UINT_MAX)); - list.push_back(EffectiveInternalFormatInfo(GL_LUMINANCE8_ALPHA8_EXT, GL_LUMINANCE_ALPHA, 1, 8, 0, UINT_MAX, 0, UINT_MAX, 1, 8)); - list.push_back(EffectiveInternalFormatInfo(GL_RGB565, GL_RGB, 1, 5, 1, 6, 1, 5, 0, UINT_MAX)); - list.push_back(EffectiveInternalFormatInfo(GL_RGB8, GL_RGB, 6, 8, 7, 8, 6, 8, 0, UINT_MAX)); - list.push_back(EffectiveInternalFormatInfo(GL_RGBA4, GL_RGBA, 1, 4, 1, 4, 1, 4, 1, 4)); - list.push_back(EffectiveInternalFormatInfo(GL_RGB5_A1, GL_RGBA, 5, 5, 5, 5, 5, 5, 1, 1)); - list.push_back(EffectiveInternalFormatInfo(GL_RGBA8, GL_RGBA, 5, 8, 5, 8, 5, 8, 5, 8)); - - return list; -} - -static bool GetEffectiveInternalFormat(const InternalFormat &srcFormat, const InternalFormat &destFormat, - GLenum *outEffectiveFormat) -{ - const EffectiveInternalFormatList *list = NULL; - GLenum targetFormat = GL_NONE; - - if (destFormat.pixelBytes > 0) + for (size_t curFormat = 0; curFormat < size; ++curFormat) { - static const EffectiveInternalFormatList sizedList = BuildSizedEffectiveInternalFormatList(); - list = &sizedList; - } - else - { - static const EffectiveInternalFormatList unsizedList = BuildUnsizedEffectiveInternalFormatList(); - list = &unsizedList; - targetFormat = destFormat.format; - } - - for (size_t curFormat = 0; curFormat < list->size(); ++curFormat) - { - const EffectiveInternalFormatInfo& formatInfo = list->at(curFormat); - if ((formatInfo.mDestFormat == targetFormat) && - (formatInfo.mMinRedBits <= srcFormat.redBits && formatInfo.mMaxRedBits >= srcFormat.redBits) && - (formatInfo.mMinGreenBits <= srcFormat.greenBits && formatInfo.mMaxGreenBits >= srcFormat.greenBits) && - (formatInfo.mMinBlueBits <= srcFormat.blueBits && formatInfo.mMaxBlueBits >= srcFormat.blueBits) && - (formatInfo.mMinAlphaBits <= srcFormat.alphaBits && formatInfo.mMaxAlphaBits >= srcFormat.alphaBits)) + const EffectiveInternalFormatInfo &formatInfo = list[curFormat]; + if ((formatInfo.destFormat == targetFormat) && + (formatInfo.minRedBits <= srcFormat.redBits && + formatInfo.maxRedBits >= srcFormat.redBits) && + (formatInfo.minGreenBits <= srcFormat.greenBits && + formatInfo.maxGreenBits >= srcFormat.greenBits) && + (formatInfo.minBlueBits <= srcFormat.blueBits && + formatInfo.maxBlueBits >= srcFormat.blueBits) && + (formatInfo.minAlphaBits <= srcFormat.alphaBits && + formatInfo.maxAlphaBits >= srcFormat.alphaBits)) { - *outEffectiveFormat = formatInfo.mEffectiveFormat; + *outEffectiveFormat = formatInfo.effectiveFormat; return true; } } + *outEffectiveFormat = GL_NONE; return false; } -struct CopyConversion +bool GetSizedEffectiveInternalFormatInfo(const InternalFormat &srcFormat, + GLenum *outEffectiveFormat) { - GLenum mTextureFormat; - GLenum mFramebufferFormat; + // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141: + // Effective internal format coresponding to destination internal format and linear source + // buffer component sizes. + // | Source channel min/max sizes | + // Effective Internal Format | N/A | R | G | B | A | + // clang-format off + constexpr EffectiveInternalFormatInfo list[] = { + { GL_ALPHA8_EXT, GL_NONE, 0, 0, 0, 0, 0, 0, 1, 8 }, + { GL_R8, GL_NONE, 1, 8, 0, 0, 0, 0, 0, 0 }, + { GL_RG8, GL_NONE, 1, 8, 1, 8, 0, 0, 0, 0 }, + { GL_RGB565, GL_NONE, 1, 5, 1, 6, 1, 5, 0, 0 }, + { GL_RGB8, GL_NONE, 6, 8, 7, 8, 6, 8, 0, 0 }, + { GL_RGBA4, GL_NONE, 1, 4, 1, 4, 1, 4, 1, 4 }, + { GL_RGB5_A1, GL_NONE, 5, 5, 5, 5, 5, 5, 1, 1 }, + { GL_RGBA8, GL_NONE, 5, 8, 5, 8, 5, 8, 2, 8 }, + { GL_RGB10_A2, GL_NONE, 9, 10, 9, 10, 9, 10, 2, 2 }, + }; + // clang-format on - CopyConversion(GLenum textureFormat, GLenum framebufferFormat) - : mTextureFormat(textureFormat), mFramebufferFormat(framebufferFormat) { } - - bool operator<(const CopyConversion& other) const - { - return memcmp(this, &other, sizeof(CopyConversion)) < 0; - } -}; - -typedef std::set CopyConversionSet; - -static CopyConversionSet BuildValidES3CopyTexImageCombinations() -{ - CopyConversionSet set; - - // From ES 3.0.1 spec, table 3.15 - set.insert(CopyConversion(GL_ALPHA, GL_RGBA)); - set.insert(CopyConversion(GL_LUMINANCE, GL_RED)); - set.insert(CopyConversion(GL_LUMINANCE, GL_RG)); - set.insert(CopyConversion(GL_LUMINANCE, GL_RGB)); - set.insert(CopyConversion(GL_LUMINANCE, GL_RGBA)); - set.insert(CopyConversion(GL_LUMINANCE_ALPHA, GL_RGBA)); - set.insert(CopyConversion(GL_RED, GL_RED)); - set.insert(CopyConversion(GL_RED, GL_RG)); - set.insert(CopyConversion(GL_RED, GL_RGB)); - set.insert(CopyConversion(GL_RED, GL_RGBA)); - set.insert(CopyConversion(GL_RG, GL_RG)); - set.insert(CopyConversion(GL_RG, GL_RGB)); - set.insert(CopyConversion(GL_RG, GL_RGBA)); - set.insert(CopyConversion(GL_RGB, GL_RGB)); - set.insert(CopyConversion(GL_RGB, GL_RGBA)); - set.insert(CopyConversion(GL_RGBA, GL_RGBA)); - - // Necessary for ANGLE back-buffers - set.insert(CopyConversion(GL_ALPHA, GL_BGRA_EXT)); - set.insert(CopyConversion(GL_LUMINANCE, GL_BGRA_EXT)); - set.insert(CopyConversion(GL_LUMINANCE_ALPHA, GL_BGRA_EXT)); - set.insert(CopyConversion(GL_RED, GL_BGRA_EXT)); - set.insert(CopyConversion(GL_RG, GL_BGRA_EXT)); - set.insert(CopyConversion(GL_RGB, GL_BGRA_EXT)); - set.insert(CopyConversion(GL_RGBA, GL_BGRA_EXT)); - - set.insert(CopyConversion(GL_RED_INTEGER, GL_RED_INTEGER)); - set.insert(CopyConversion(GL_RED_INTEGER, GL_RG_INTEGER)); - set.insert(CopyConversion(GL_RED_INTEGER, GL_RGB_INTEGER)); - set.insert(CopyConversion(GL_RED_INTEGER, GL_RGBA_INTEGER)); - set.insert(CopyConversion(GL_RG_INTEGER, GL_RG_INTEGER)); - set.insert(CopyConversion(GL_RG_INTEGER, GL_RGB_INTEGER)); - set.insert(CopyConversion(GL_RG_INTEGER, GL_RGBA_INTEGER)); - set.insert(CopyConversion(GL_RGB_INTEGER, GL_RGB_INTEGER)); - set.insert(CopyConversion(GL_RGB_INTEGER, GL_RGBA_INTEGER)); - set.insert(CopyConversion(GL_RGBA_INTEGER, GL_RGBA_INTEGER)); - - return set; + return QueryEffectiveFormatList(srcFormat, GL_NONE, list, ArraySize(list), outEffectiveFormat); } -static bool IsValidES3CopyTexImageCombination(GLenum textureInternalFormat, GLenum frameBufferInternalFormat, GLuint readBufferHandle) +bool GetUnsizedEffectiveInternalFormatInfo(const InternalFormat &srcFormat, + const InternalFormat &destFormat, + GLenum *outEffectiveFormat) { - const InternalFormat &textureInternalFormatInfo = GetInternalFormatInfo(textureInternalFormat); - const InternalFormat &framebufferInternalFormatInfo = GetInternalFormatInfo(frameBufferInternalFormat); + constexpr GLuint umax = UINT_MAX; - static const CopyConversionSet conversionSet = BuildValidES3CopyTexImageCombinations(); - if (conversionSet.find(CopyConversion(textureInternalFormatInfo.format, framebufferInternalFormatInfo.format)) != conversionSet.end()) + // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141: + // Effective internal format coresponding to destination internal format andlinear source buffer + // component sizes. + // | Source channel min/max sizes | + // Effective Internal Format | Dest Format | R | G | B | A | + // clang-format off + constexpr EffectiveInternalFormatInfo list[] = { + { GL_ALPHA8_EXT, GL_ALPHA, 0, umax, 0, umax, 0, umax, 1, 8 }, + { GL_LUMINANCE8_EXT, GL_LUMINANCE, 1, 8, 0, umax, 0, umax, 0, umax }, + { GL_LUMINANCE8_ALPHA8_EXT, GL_LUMINANCE_ALPHA, 1, 8, 0, umax, 0, umax, 1, 8 }, + { GL_RGB565, GL_RGB, 1, 5, 1, 6, 1, 5, 0, umax }, + { GL_RGB8, GL_RGB, 6, 8, 7, 8, 6, 8, 0, umax }, + { GL_RGBA4, GL_RGBA, 1, 4, 1, 4, 1, 4, 1, 4 }, + { GL_RGB5_A1, GL_RGBA, 5, 5, 5, 5, 5, 5, 1, 1 }, + { GL_RGBA8, GL_RGBA, 5, 8, 5, 8, 5, 8, 5, 8 }, + }; + // clang-format on + + return QueryEffectiveFormatList(srcFormat, destFormat.format, list, ArraySize(list), + outEffectiveFormat); +} + +static bool GetEffectiveInternalFormat(const InternalFormat &srcFormat, + const InternalFormat &destFormat, + GLenum *outEffectiveFormat) +{ + if (destFormat.sized) { - // Section 3.8.5 of the GLES 3.0.3 spec states that source and destination formats - // must both be signed, unsigned, or fixed point and both source and destinations - // must be either both SRGB or both not SRGB. EXT_color_buffer_float adds allowed - // conversion between fixed and floating point. + return GetSizedEffectiveInternalFormatInfo(srcFormat, outEffectiveFormat); + } + else + { + return GetUnsizedEffectiveInternalFormatInfo(srcFormat, destFormat, outEffectiveFormat); + } +} - if ((textureInternalFormatInfo.colorEncoding == GL_SRGB) != (framebufferInternalFormatInfo.colorEncoding == GL_SRGB)) +static bool EqualOrFirstZero(GLuint first, GLuint second) +{ + return first == 0 || first == second; +} + +static bool IsValidES3CopyTexImageCombination(const InternalFormat &textureFormatInfo, + const InternalFormat &framebufferFormatInfo, + GLuint readBufferHandle) +{ + if (!ValidES3CopyConversion(textureFormatInfo.format, framebufferFormatInfo.format)) + { + return false; + } + + // Section 3.8.5 of the GLES 3.0.3 spec states that source and destination formats + // must both be signed, unsigned, or fixed point and both source and destinations + // must be either both SRGB or both not SRGB. EXT_color_buffer_float adds allowed + // conversion between fixed and floating point. + + if ((textureFormatInfo.colorEncoding == GL_SRGB) != + (framebufferFormatInfo.colorEncoding == GL_SRGB)) + { + return false; + } + + if (((textureFormatInfo.componentType == GL_INT) != + (framebufferFormatInfo.componentType == GL_INT)) || + ((textureFormatInfo.componentType == GL_UNSIGNED_INT) != + (framebufferFormatInfo.componentType == GL_UNSIGNED_INT))) + { + return false; + } + + if ((textureFormatInfo.componentType == GL_UNSIGNED_NORMALIZED || + textureFormatInfo.componentType == GL_SIGNED_NORMALIZED || + textureFormatInfo.componentType == GL_FLOAT) && + !(framebufferFormatInfo.componentType == GL_UNSIGNED_NORMALIZED || + framebufferFormatInfo.componentType == GL_SIGNED_NORMALIZED || + framebufferFormatInfo.componentType == GL_FLOAT)) + { + return false; + } + + // GLES specification 3.0.3, sec 3.8.5, pg 139-140: + // The effective internal format of the source buffer is determined with the following rules + // applied in order: + // * If the source buffer is a texture or renderbuffer that was created with a sized internal + // format then the effective internal format is the source buffer's sized internal format. + // * If the source buffer is a texture that was created with an unsized base internal format, + // then the effective internal format is the source image array's effective internal + // format, as specified by table 3.12, which is determined from the and + // that were used when the source image array was specified by TexImage*. + // * Otherwise the effective internal format is determined by the row in table 3.17 or 3.18 + // where Destination Internal Format matches internalformat and where the [source channel + // sizes] are consistent with the values of the source buffer's [channel sizes]. Table 3.17 + // is used if the FRAMEBUFFER_ATTACHMENT_ENCODING is LINEAR and table 3.18 is used if the + // FRAMEBUFFER_ATTACHMENT_ENCODING is SRGB. + const InternalFormat *sourceEffectiveFormat = nullptr; + if (readBufferHandle != 0) + { + // Not the default framebuffer, therefore the read buffer must be a user-created texture or + // renderbuffer + if (framebufferFormatInfo.sized) { - return false; + sourceEffectiveFormat = &framebufferFormatInfo; } - - if (((textureInternalFormatInfo.componentType == GL_INT) != (framebufferInternalFormatInfo.componentType == GL_INT )) || - ((textureInternalFormatInfo.componentType == GL_UNSIGNED_INT) != (framebufferInternalFormatInfo.componentType == GL_UNSIGNED_INT))) + else { - return false; + // Renderbuffers cannot be created with an unsized internal format, so this must be an + // unsized-format texture. We can use the same table we use when creating textures to + // get its effective sized format. + sourceEffectiveFormat = + &GetSizedInternalFormatInfo(framebufferFormatInfo.sizedInternalFormat); } - - if ((textureInternalFormatInfo.componentType == GL_UNSIGNED_NORMALIZED || - textureInternalFormatInfo.componentType == GL_SIGNED_NORMALIZED || - textureInternalFormatInfo.componentType == GL_FLOAT) && - !(framebufferInternalFormatInfo.componentType == GL_UNSIGNED_NORMALIZED || - framebufferInternalFormatInfo.componentType == GL_SIGNED_NORMALIZED || - framebufferInternalFormatInfo.componentType == GL_FLOAT)) + } + else + { + // The effective internal format must be derived from the source framebuffer's channel + // sizes. This is done in GetEffectiveInternalFormat for linear buffers (table 3.17) + if (framebufferFormatInfo.colorEncoding == GL_LINEAR) { - return false; - } - - // GLES specification 3.0.3, sec 3.8.5, pg 139-140: - // The effective internal format of the source buffer is determined with the following rules applied in order: - // * If the source buffer is a texture or renderbuffer that was created with a sized internal format then the - // effective internal format is the source buffer's sized internal format. - // * If the source buffer is a texture that was created with an unsized base internal format, then the - // effective internal format is the source image array's effective internal format, as specified by table - // 3.12, which is determined from the and that were used when the source image array was - // specified by TexImage*. - // * Otherwise the effective internal format is determined by the row in table 3.17 or 3.18 where - // Destination Internal Format matches internalformat and where the [source channel sizes] are consistent - // with the values of the source buffer's [channel sizes]. Table 3.17 is used if the - // FRAMEBUFFER_ATTACHMENT_ENCODING is LINEAR and table 3.18 is used if the FRAMEBUFFER_ATTACHMENT_ENCODING - // is SRGB. - InternalFormat sourceEffectiveFormat; - if (readBufferHandle != 0) - { - // Not the default framebuffer, therefore the read buffer must be a user-created texture or renderbuffer - if (framebufferInternalFormatInfo.pixelBytes > 0) + GLenum effectiveFormat; + if (GetEffectiveInternalFormat(framebufferFormatInfo, textureFormatInfo, + &effectiveFormat)) { - sourceEffectiveFormat = framebufferInternalFormatInfo; + sourceEffectiveFormat = &GetSizedInternalFormatInfo(effectiveFormat); } else { - // Renderbuffers cannot be created with an unsized internal format, so this must be an unsized-format - // texture. We can use the same table we use when creating textures to get its effective sized format. - GLenum sizedInternalFormat = GetSizedInternalFormat(framebufferInternalFormatInfo.format, framebufferInternalFormatInfo.type); - sourceEffectiveFormat = GetInternalFormatInfo(sizedInternalFormat); + return false; + } + } + else if (framebufferFormatInfo.colorEncoding == GL_SRGB) + { + // SRGB buffers can only be copied to sized format destinations according to table 3.18 + if (textureFormatInfo.sized && + (framebufferFormatInfo.redBits >= 1 && framebufferFormatInfo.redBits <= 8) && + (framebufferFormatInfo.greenBits >= 1 && framebufferFormatInfo.greenBits <= 8) && + (framebufferFormatInfo.blueBits >= 1 && framebufferFormatInfo.blueBits <= 8) && + (framebufferFormatInfo.alphaBits >= 1 && framebufferFormatInfo.alphaBits <= 8)) + { + sourceEffectiveFormat = &GetSizedInternalFormatInfo(GL_SRGB8_ALPHA8); + } + else + { + return false; } } else { - // The effective internal format must be derived from the source framebuffer's channel sizes. - // This is done in GetEffectiveInternalFormat for linear buffers (table 3.17) - if (framebufferInternalFormatInfo.colorEncoding == GL_LINEAR) - { - GLenum effectiveFormat; - if (GetEffectiveInternalFormat(framebufferInternalFormatInfo, textureInternalFormatInfo, &effectiveFormat)) - { - sourceEffectiveFormat = GetInternalFormatInfo(effectiveFormat); - } - else - { - return false; - } - } - else if (framebufferInternalFormatInfo.colorEncoding == GL_SRGB) - { - // SRGB buffers can only be copied to sized format destinations according to table 3.18 - if ((textureInternalFormatInfo.pixelBytes > 0) && - (framebufferInternalFormatInfo.redBits >= 1 && framebufferInternalFormatInfo.redBits <= 8) && - (framebufferInternalFormatInfo.greenBits >= 1 && framebufferInternalFormatInfo.greenBits <= 8) && - (framebufferInternalFormatInfo.blueBits >= 1 && framebufferInternalFormatInfo.blueBits <= 8) && - (framebufferInternalFormatInfo.alphaBits >= 1 && framebufferInternalFormatInfo.alphaBits <= 8)) - { - sourceEffectiveFormat = GetInternalFormatInfo(GL_SRGB8_ALPHA8); - } - else - { - return false; - } - } - else - { - UNREACHABLE(); - return false; - } + UNREACHABLE(); + return false; } - - if (textureInternalFormatInfo.pixelBytes > 0) - { - // Section 3.8.5 of the GLES 3.0.3 spec, pg 139, requires that, if the destination format is sized, - // component sizes of the source and destination formats must exactly match - if (textureInternalFormatInfo.redBits != sourceEffectiveFormat.redBits || - textureInternalFormatInfo.greenBits != sourceEffectiveFormat.greenBits || - textureInternalFormatInfo.blueBits != sourceEffectiveFormat.blueBits || - textureInternalFormatInfo.alphaBits != sourceEffectiveFormat.alphaBits) - { - return false; - } - } - - - return true; // A conversion function exists, and no rule in the specification has precluded conversion - // between these formats. } - return false; + if (textureFormatInfo.sized) + { + // Section 3.8.5 of the GLES 3.0.3 spec, pg 139, requires that, if the destination format is + // sized, component sizes of the source and destination formats must exactly match if the + // destination format exists. + if (!EqualOrFirstZero(textureFormatInfo.redBits, sourceEffectiveFormat->redBits) || + !EqualOrFirstZero(textureFormatInfo.greenBits, sourceEffectiveFormat->greenBits) || + !EqualOrFirstZero(textureFormatInfo.blueBits, sourceEffectiveFormat->blueBits) || + !EqualOrFirstZero(textureFormatInfo.alphaBits, sourceEffectiveFormat->alphaBits)) + { + return false; + } + } + + return true; // A conversion function exists, and no rule in the specification has precluded + // conversion between these formats. } bool ValidateES3CopyTexImageParametersBase(ValidationContext *context, @@ -865,48 +790,50 @@ bool ValidateES3CopyTexImageParametersBase(ValidationContext *context, GLsizei height, GLint border) { - GLenum textureInternalFormat; + Format textureFormat = Format::Invalid(); if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage, - xoffset, yoffset, zoffset, x, y, width, height, - border, &textureInternalFormat)) + xoffset, yoffset, zoffset, x, y, width, height, border, + &textureFormat)) { return false; } + ASSERT(textureFormat.valid() || !isSubImage); - const auto &state = context->getState(); - const gl::Framebuffer *framebuffer = state.getReadFramebuffer(); - GLuint readFramebufferID = framebuffer->id(); + const auto &state = context->getGLState(); + gl::Framebuffer *framebuffer = state.getReadFramebuffer(); + GLuint readFramebufferID = framebuffer->id(); - if (framebuffer->checkStatus(context->getData()) != GL_FRAMEBUFFER_COMPLETE) + if (framebuffer->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE) { - context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION)); + context->handleError(InvalidFramebufferOperation()); return false; } - if (readFramebufferID != 0 && framebuffer->getSamples(context->getData()) != 0) + if (readFramebufferID != 0 && framebuffer->getSamples(context) != 0) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } - const gl::FramebufferAttachment *source = framebuffer->getReadColorbuffer(); - GLenum colorbufferInternalFormat = source->getInternalFormat(); + const FramebufferAttachment *source = framebuffer->getReadColorbuffer(); if (isSubImage) { - if (!IsValidES3CopyTexImageCombination(textureInternalFormat, colorbufferInternalFormat, + if (!IsValidES3CopyTexImageCombination(*textureFormat.info, *source->getFormat().info, readFramebufferID)) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } } else { - if (!gl::IsValidES3CopyTexImageCombination(internalformat, colorbufferInternalFormat, - readFramebufferID)) + // Use format/type from the source FBO. (Might not be perfect for all cases?) + const InternalFormat &framebufferFormat = *source->getFormat().info; + const InternalFormat ©Format = GetInternalFormatInfo(internalformat, GL_UNSIGNED_BYTE); + if (!IsValidES3CopyTexImageCombination(copyFormat, framebufferFormat, readFramebufferID)) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } } @@ -931,7 +858,7 @@ bool ValidateES3CopyTexImage2DParameters(ValidationContext *context, { if (!ValidTexture2DDestinationTarget(context, target)) { - context->recordError(Error(GL_INVALID_ENUM)); + context->handleError(InvalidEnum()); return false; } @@ -956,7 +883,7 @@ bool ValidateES3CopyTexImage3DParameters(ValidationContext *context, { if (!ValidTexture3DDestinationTarget(context, target)) { - context->recordError(Error(GL_INVALID_ENUM)); + context->handleError(InvalidEnum()); return false; } @@ -975,7 +902,7 @@ bool ValidateES3TexStorageParametersBase(Context *context, { if (width < 1 || height < 1 || depth < 1 || levels < 1) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } @@ -987,7 +914,7 @@ bool ValidateES3TexStorageParametersBase(Context *context, if (levels > gl::log2(maxDim) + 1) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } @@ -995,85 +922,102 @@ bool ValidateES3TexStorageParametersBase(Context *context, switch (target) { - case GL_TEXTURE_2D: + case GL_TEXTURE_2D: { if (static_cast(width) > caps.max2DTextureSize || static_cast(height) > caps.max2DTextureSize) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } } break; - case GL_TEXTURE_CUBE_MAP: + case GL_TEXTURE_RECTANGLE_ANGLE: + { + if (static_cast(width) > caps.maxRectangleTextureSize || + static_cast(height) > caps.maxRectangleTextureSize || levels != 1) + { + context->handleError(InvalidValue()); + return false; + } + } + break; + + case GL_TEXTURE_CUBE_MAP: { if (width != height) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } if (static_cast(width) > caps.maxCubeMapTextureSize) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } } break; - case GL_TEXTURE_3D: + case GL_TEXTURE_3D: { if (static_cast(width) > caps.max3DTextureSize || static_cast(height) > caps.max3DTextureSize || static_cast(depth) > caps.max3DTextureSize) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } } break; - case GL_TEXTURE_2D_ARRAY: + case GL_TEXTURE_2D_ARRAY: { if (static_cast(width) > caps.max2DTextureSize || static_cast(height) > caps.max2DTextureSize || static_cast(depth) > caps.maxArrayTextureLayers) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } } break; - default: - UNREACHABLE(); - return false; + default: + UNREACHABLE(); + return false; } gl::Texture *texture = context->getTargetTexture(target); if (!texture || texture->id() == 0) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } if (texture->getImmutableFormat()) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat); + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat); if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions())) { - context->recordError(Error(GL_INVALID_ENUM)); + context->handleError(InvalidEnum()); return false; } - if (formatInfo.pixelBytes == 0) + if (!formatInfo.sized) { - context->recordError(Error(GL_INVALID_ENUM)); + context->handleError(InvalidEnum()); + return false; + } + + if (formatInfo.compressed && target == GL_TEXTURE_RECTANGLE_ANGLE) + { + context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format."); return false; } @@ -1090,7 +1034,7 @@ bool ValidateES3TexStorage2DParameters(Context *context, { if (!ValidTexture2DTarget(context, target)) { - context->recordError(Error(GL_INVALID_ENUM)); + context->handleError(InvalidEnum()); return false; } @@ -1108,7 +1052,7 @@ bool ValidateES3TexStorage3DParameters(Context *context, { if (!ValidTexture3DTarget(context, target)) { - context->recordError(Error(GL_INVALID_ENUM)); + context->handleError(InvalidEnum()); return false; } @@ -1116,33 +1060,11 @@ bool ValidateES3TexStorage3DParameters(Context *context, height, depth); } -bool ValidateGenQueries(gl::Context *context, GLsizei n, const GLuint *ids) -{ - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION, "GLES version < 3.0")); - return false; - } - - return ValidateGenQueriesBase(context, n, ids); -} - -bool ValidateDeleteQueries(gl::Context *context, GLsizei n, const GLuint *ids) -{ - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION, "GLES version < 3.0")); - return false; - } - - return ValidateDeleteQueriesBase(context, n, ids); -} - bool ValidateBeginQuery(gl::Context *context, GLenum target, GLuint id) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { - context->recordError(Error(GL_INVALID_OPERATION, "GLES version < 3.0")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); return false; } @@ -1151,9 +1073,9 @@ bool ValidateBeginQuery(gl::Context *context, GLenum target, GLuint id) bool ValidateEndQuery(gl::Context *context, GLenum target) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { - context->recordError(Error(GL_INVALID_OPERATION, "GLES version < 3.0")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); return false; } @@ -1162,38 +1084,36 @@ bool ValidateEndQuery(gl::Context *context, GLenum target) bool ValidateGetQueryiv(Context *context, GLenum target, GLenum pname, GLint *params) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { - context->recordError(Error(GL_INVALID_OPERATION, "GLES version < 3.0")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); return false; } - return ValidateGetQueryivBase(context, target, pname); + return ValidateGetQueryivBase(context, target, pname, nullptr); } bool ValidateGetQueryObjectuiv(Context *context, GLuint id, GLenum pname, GLuint *params) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { - context->recordError(Error(GL_INVALID_OPERATION, "GLES version < 3.0")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); return false; } - return ValidateGetQueryObjectValueBase(context, id, pname); + return ValidateGetQueryObjectValueBase(context, id, pname, nullptr); } -bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum attachment, - GLuint texture, GLint level, GLint layer) +bool ValidateFramebufferTextureLayer(Context *context, + GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint layer) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - - if (layer < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); return false; } @@ -1205,52 +1125,58 @@ bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum att const gl::Caps &caps = context->getCaps(); if (texture != 0) { + if (layer < 0) + { + context->handleError(InvalidValue()); + return false; + } + gl::Texture *tex = context->getTexture(texture); ASSERT(tex); switch (tex->getTarget()) { - case GL_TEXTURE_2D_ARRAY: + case GL_TEXTURE_2D_ARRAY: { if (level > gl::log2(caps.max2DTextureSize)) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } if (static_cast(layer) >= caps.maxArrayTextureLayers) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } } break; - case GL_TEXTURE_3D: + case GL_TEXTURE_3D: { if (level > gl::log2(caps.max3DTextureSize)) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } if (static_cast(layer) >= caps.max3DTextureSize) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } } break; - default: - context->recordError(Error(GL_INVALID_OPERATION)); - return false; + default: + context->handleError(InvalidOperation()); + return false; } - const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(tex->getInternalFormat(tex->getTarget(), level)); - if (internalFormatInfo.compressed) + const auto &format = tex->getFormat(tex->getTarget(), level); + if (format.info->compressed) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return false; } } @@ -1258,116 +1184,14 @@ bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum att return true; } -bool ValidES3ReadFormatType(Context *context, GLenum internalFormat, GLenum format, GLenum type) -{ - const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat); - - switch (format) - { - case GL_RGBA: - switch (type) - { - case GL_UNSIGNED_BYTE: - break; - case GL_UNSIGNED_INT_2_10_10_10_REV: - if (internalFormat != GL_RGB10_A2) - { - return false; - } - break; - case GL_FLOAT: - if (internalFormatInfo.componentType != GL_FLOAT) - { - return false; - } - break; - default: - return false; - } - break; - case GL_RGBA_INTEGER: - switch (type) - { - case GL_INT: - if (internalFormatInfo.componentType != GL_INT) - { - return false; - } - break; - case GL_UNSIGNED_INT: - if (internalFormatInfo.componentType != GL_UNSIGNED_INT) - { - return false; - } - break; - default: - return false; - } - break; - case GL_BGRA_EXT: - switch (type) - { - case GL_UNSIGNED_BYTE: - case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: - case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: - break; - default: - return false; - } - break; - case GL_RG_EXT: - case GL_RED_EXT: - if (!context->getExtensions().textureRG) - { - return false; - } - switch (type) - { - case GL_UNSIGNED_BYTE: - break; - default: - return false; - } - break; - default: - return false; - } - return true; -} - -bool ValidateES3RenderbufferStorageParameters(gl::Context *context, GLenum target, GLsizei samples, - GLenum internalformat, GLsizei width, GLsizei height) -{ - if (!ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat, width, height)) - { - return false; - } - - //The ES3 spec(section 4.4.2) states that the internal format must be sized and not an integer format if samples is greater than zero. - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat); - if ((formatInfo.componentType == GL_UNSIGNED_INT || formatInfo.componentType == GL_INT) && samples > 0) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - - // The behavior is different than the ANGLE version, which would generate a GL_OUT_OF_MEMORY. - const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat); - if (static_cast(samples) > formatCaps.getMaxSamples()) - { - context->recordError(Error(GL_INVALID_VALUE)); - return false; - } - - return true; -} - -bool ValidateInvalidateFramebuffer(Context *context, GLenum target, GLsizei numAttachments, +bool ValidateInvalidateFramebuffer(Context *context, + GLenum target, + GLsizei numAttachments, const GLenum *attachments) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { - context->recordError(Error(GL_INVALID_OPERATION, "Operation only supported on ES 3.0 and above")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); return false; } @@ -1375,44 +1199,99 @@ bool ValidateInvalidateFramebuffer(Context *context, GLenum target, GLsizei numA switch (target) { - case GL_DRAW_FRAMEBUFFER: - case GL_FRAMEBUFFER: - defaultFramebuffer = context->getState().getDrawFramebuffer()->id() == 0; - break; - case GL_READ_FRAMEBUFFER: - defaultFramebuffer = context->getState().getReadFramebuffer()->id() == 0; - break; - default: - context->recordError(Error(GL_INVALID_ENUM, "Invalid framebuffer target")); - return false; + case GL_DRAW_FRAMEBUFFER: + case GL_FRAMEBUFFER: + defaultFramebuffer = context->getGLState().getDrawFramebuffer()->id() == 0; + break; + case GL_READ_FRAMEBUFFER: + defaultFramebuffer = context->getGLState().getReadFramebuffer()->id() == 0; + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget); + return false; } - return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments, defaultFramebuffer); + return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments, + defaultFramebuffer); +} + +bool ValidateInvalidateSubFramebuffer(Context *context, + GLenum target, + GLsizei numAttachments, + const GLenum *attachments, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + return ValidateInvalidateFramebuffer(context, target, numAttachments, attachments); } bool ValidateClearBuffer(ValidationContext *context) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { - context->recordError(Error(GL_INVALID_OPERATION)); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); return false; } - const gl::Framebuffer *fbo = context->getState().getDrawFramebuffer(); - if (!fbo || fbo->checkStatus(context->getData()) != GL_FRAMEBUFFER_COMPLETE) + if (context->getGLState().getDrawFramebuffer()->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE) { - context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION)); + context->handleError(InvalidFramebufferOperation()); return false; } return true; } -bool ValidateGetUniformuiv(Context *context, GLuint program, GLint location, GLuint* params) +bool ValidateDrawRangeElements(Context *context, + GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const void *indices) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { - context->recordError(Error(GL_INVALID_OPERATION)); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + if (end < start) + { + context->handleError(InvalidValue() << "end < start"); + return false; + } + + if (!ValidateDrawElementsCommon(context, mode, count, type, indices, 0)) + { + return false; + } + + // Use the parameter buffer to retrieve and cache the index range. + const auto ¶ms = context->getParams(); + const auto &indexRangeOpt = params.getIndexRange(); + if (!indexRangeOpt.valid()) + { + // Unexpected error. + return false; + } + + if (indexRangeOpt.value().end > end || indexRangeOpt.value().start < start) + { + // GL spec says that behavior in this case is undefined - generating an error is fine. + context->handleError(InvalidOperation() << "Indices are out of the start, end range."); + return false; + } + return true; +} + +bool ValidateGetUniformuiv(Context *context, GLuint program, GLint location, GLuint *params) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); return false; } @@ -1421,17 +1300,17 @@ bool ValidateGetUniformuiv(Context *context, GLuint program, GLint location, GLu bool ValidateReadBuffer(Context *context, GLenum src) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { - context->recordError(Error(GL_INVALID_OPERATION)); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); return false; } - Framebuffer *readFBO = context->getState().getReadFramebuffer(); + const Framebuffer *readFBO = context->getGLState().getReadFramebuffer(); if (readFBO == nullptr) { - context->recordError(gl::Error(GL_INVALID_OPERATION, "No active read framebuffer.")); + context->handleError(InvalidOperation() << "No active read framebuffer."); return false; } @@ -1440,9 +1319,9 @@ bool ValidateReadBuffer(Context *context, GLenum src) return true; } - if (src != GL_BACK && (src < GL_COLOR_ATTACHMENT0 || src > GL_COLOR_ATTACHMENT15)) + if (src != GL_BACK && (src < GL_COLOR_ATTACHMENT0 || src > GL_COLOR_ATTACHMENT31)) { - context->recordError(gl::Error(GL_INVALID_ENUM, "Unknown enum for 'src' in ReadBuffer")); + context->handleError(InvalidEnum() << "Unknown enum for 'src' in ReadBuffer"); return false; } @@ -1450,8 +1329,9 @@ bool ValidateReadBuffer(Context *context, GLenum src) { if (src != GL_BACK) { - const char *errorMsg = "'src' must be GL_NONE or GL_BACK when reading from the default framebuffer."; - context->recordError(gl::Error(GL_INVALID_OPERATION, errorMsg)); + context->handleError( + InvalidOperation() + << "'src' must be GL_NONE or GL_BACK when reading from the default framebuffer."); return false; } } @@ -1461,8 +1341,7 @@ bool ValidateReadBuffer(Context *context, GLenum src) if (drawBuffer >= context->getCaps().maxDrawBuffers) { - const char *errorMsg = "'src' is greater than MAX_DRAW_BUFFERS."; - context->recordError(gl::Error(GL_INVALID_OPERATION, errorMsg)); + context->handleError(InvalidOperation() << "'src' is greater than MAX_DRAW_BUFFERS."); return false; } } @@ -1479,34 +1358,57 @@ bool ValidateCompressedTexImage3D(Context *context, GLsizei depth, GLint border, GLsizei imageSize, - const GLvoid *data) + const void *data) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { - context->recordError(Error(GL_INVALID_OPERATION)); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); return false; } - const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat); - if (imageSize < 0 || - static_cast(imageSize) != - formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height)) + if (!ValidTextureTarget(context, target)) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidEnum()); + return false; + } + + // Validate image size + if (!ValidImageSizeParameters(context, target, level, width, height, depth, false)) + { + context->handleError(InvalidValue()); + return false; + } + + const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat); + if (!formatInfo.compressed) + { + context->handleError(InvalidEnum() << "Not a valid compressed texture format"); + return false; + } + + auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, depth)); + if (blockSizeOrErr.isError()) + { + context->handleError(InvalidValue()); + return false; + } + if (imageSize < 0 || static_cast(imageSize) != blockSizeOrErr.getResult()) + { + context->handleError(InvalidValue()); return false; } // 3D texture target validation if (target != GL_TEXTURE_3D && target != GL_TEXTURE_2D_ARRAY) { - context->recordError( - Error(GL_INVALID_ENUM, "Must specify a valid 3D texture destination target")); + context->handleError(InvalidEnum() << "Must specify a valid 3D texture destination target"); return false; } // validateES3TexImageFormat sets the error code if there is an error if (!ValidateES3TexImage3DParameters(context, target, level, internalformat, true, false, 0, 0, - 0, width, height, depth, border, GL_NONE, GL_NONE, data)) + 0, width, height, depth, border, GL_NONE, GL_NONE, -1, + data)) { return false; } @@ -1514,59 +1416,207 @@ bool ValidateCompressedTexImage3D(Context *context, return true; } +bool ValidateCompressedTexImage3DRobustANGLE(Context *context, + GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + GLsizei dataSize, + const void *data) +{ + if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize)) + { + return false; + } + + return ValidateCompressedTexImage3D(context, target, level, internalformat, width, height, + depth, border, imageSize, data); +} + bool ValidateBindVertexArray(Context *context, GLuint array) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { - context->recordError(Error(GL_INVALID_OPERATION)); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); return false; } return ValidateBindVertexArrayBase(context, array); } -bool ValidateDeleteVertexArrays(Context *context, GLsizei n) +bool ValidateIsVertexArray(Context *context, GLuint array) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - - return ValidateDeleteVertexArraysBase(context, n); -} - -bool ValidateGenVertexArrays(Context *context, GLsizei n) -{ - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return false; - } - - return ValidateGenVertexArraysBase(context, n); -} - -bool ValidateIsVertexArray(Context *context) -{ - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); return false; } return true; } +static bool ValidateBindBufferCommon(Context *context, + BufferBinding target, + GLuint index, + GLuint buffer, + GLintptr offset, + GLsizeiptr size) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + if (buffer != 0 && offset < 0) + { + context->handleError(InvalidValue() << "buffer is non-zero and offset is negative."); + return false; + } + + if (!context->getGLState().isBindGeneratesResourceEnabled() && + !context->isBufferGenerated(buffer)) + { + context->handleError(InvalidOperation() << "Buffer was not generated."); + return false; + } + + const Caps &caps = context->getCaps(); + switch (target) + { + case BufferBinding::TransformFeedback: + { + if (index >= caps.maxTransformFeedbackSeparateAttributes) + { + context->handleError(InvalidValue() << "index is greater than or equal to the " + "number of TRANSFORM_FEEDBACK_BUFFER " + "indexed binding points."); + return false; + } + if (buffer != 0 && ((offset % 4) != 0 || (size % 4) != 0)) + { + context->handleError(InvalidValue() << "offset and size must be multiple of 4."); + return false; + } + + TransformFeedback *curTransformFeedback = + context->getGLState().getCurrentTransformFeedback(); + if (curTransformFeedback && curTransformFeedback->isActive()) + { + context->handleError(InvalidOperation() + << "target is TRANSFORM_FEEDBACK_BUFFER and transform " + "feedback is currently active."); + return false; + } + break; + } + case BufferBinding::Uniform: + { + if (index >= caps.maxUniformBufferBindings) + { + context->handleError(InvalidValue() << "index is greater than or equal to the " + "number of UNIFORM_BUFFER indexed " + "binding points."); + return false; + } + + if (buffer != 0 && (offset % caps.uniformBufferOffsetAlignment) != 0) + { + context->handleError( + InvalidValue() + << "offset must be multiple of value of UNIFORM_BUFFER_OFFSET_ALIGNMENT."); + return false; + } + break; + } + case BufferBinding::AtomicCounter: + { + if (context->getClientVersion() < ES_3_1) + { + context->handleError(InvalidEnum() + << "ATOMIC_COUNTER_BUFFER is not supported before GLES 3.1"); + return false; + } + if (index >= caps.maxAtomicCounterBufferBindings) + { + context->handleError(InvalidValue() << "index is greater than or equal to the " + "number of ATOMIC_COUNTER_BUFFER " + "indexed binding points."); + return false; + } + if (buffer != 0 && (offset % 4) != 0) + { + context->handleError(InvalidValue() << "offset must be a multiple of 4."); + return false; + } + break; + } + case BufferBinding::ShaderStorage: + { + if (context->getClientVersion() < ES_3_1) + { + context->handleError(InvalidEnum() + << "SHADER_STORAGE_BUFFER is not supported in GLES3."); + return false; + } + if (index >= caps.maxShaderStorageBufferBindings) + { + context->handleError(InvalidValue() << "index is greater than or equal to the " + "number of SHADER_STORAGE_BUFFER " + "indexed binding points."); + return false; + } + if (buffer != 0 && (offset % caps.shaderStorageBufferOffsetAlignment) != 0) + { + context->handleError(InvalidValue() << "offset must be multiple of value of " + "SHADER_STORAGE_BUFFER_OFFSET_" + "ALIGNMENT."); + return false; + } + break; + } + default: + context->handleError(InvalidEnum() << "the target is not supported."); + return false; + } + + return true; +} + +bool ValidateBindBufferBase(Context *context, BufferBinding target, GLuint index, GLuint buffer) +{ + return ValidateBindBufferCommon(context, target, index, buffer, 0, 0); +} + +bool ValidateBindBufferRange(Context *context, + BufferBinding target, + GLuint index, + GLuint buffer, + GLintptr offset, + GLsizeiptr size) +{ + if (buffer != 0 && size <= 0) + { + context->handleError(InvalidValue() + << "buffer is non-zero and size is less than or equal to zero."); + return false; + } + return ValidateBindBufferCommon(context, target, index, buffer, offset, size); +} + bool ValidateProgramBinary(Context *context, GLuint program, GLenum binaryFormat, const void *binary, GLint length) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { - context->recordError(Error(GL_INVALID_OPERATION)); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); return false; } @@ -1580,20 +1630,20 @@ bool ValidateGetProgramBinary(Context *context, GLenum *binaryFormat, void *binary) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { - context->recordError(Error(GL_INVALID_OPERATION)); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); return false; } return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary); } -bool ValidateProgramParameter(Context *context, GLuint program, GLenum pname, GLint value) +bool ValidateProgramParameteri(Context *context, GLuint program, GLenum pname, GLint value) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { - context->recordError(Error(GL_INVALID_OPERATION)); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); return false; } @@ -1605,10 +1655,33 @@ bool ValidateProgramParameter(Context *context, GLuint program, GLenum pname, GL switch (pname) { case GL_PROGRAM_BINARY_RETRIEVABLE_HINT: + if (value != GL_FALSE && value != GL_TRUE) + { + context->handleError(InvalidValue() + << "Invalid value, expected GL_FALSE or GL_TRUE: " << value); + return false; + } + break; + + case GL_PROGRAM_SEPARABLE: + if (context->getClientVersion() < ES_3_1) + { + context->handleError(InvalidEnum() + << "PROGRAM_SEPARABLE is not supported before GLES 3.1"); + return false; + } + + if (value != GL_FALSE && value != GL_TRUE) + { + context->handleError(InvalidValue() + << "Invalid value, expected GL_FALSE or GL_TRUE: " << value); + return false; + } break; default: - context->recordError(Error(GL_INVALID_ENUM, "Invalid pname: 0x%X", pname)); + context->handleError(InvalidEnum() + << "Invalid pname: 0x" << std::hex << std::uppercase << pname); return false; } @@ -1627,9 +1700,9 @@ bool ValidateBlitFramebuffer(Context *context, GLbitfield mask, GLenum filter) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { - context->recordError(Error(GL_INVALID_OPERATION)); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); return false; } @@ -1648,21 +1721,30 @@ bool ValidateClearBufferiv(ValidationContext *context, if (drawbuffer < 0 || static_cast(drawbuffer) >= context->getCaps().maxDrawBuffers) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } + if (context->getExtensions().webglCompatibility) + { + constexpr GLenum validComponentTypes[] = {GL_INT}; + if (!ValidateWebGLFramebufferAttachmentClearType( + context, drawbuffer, validComponentTypes, ArraySize(validComponentTypes))) + { + return false; + } + } break; case GL_STENCIL: if (drawbuffer != 0) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } break; default: - context->recordError(Error(GL_INVALID_ENUM)); + context->handleError(InvalidEnum()); return false; } @@ -1680,13 +1762,22 @@ bool ValidateClearBufferuiv(ValidationContext *context, if (drawbuffer < 0 || static_cast(drawbuffer) >= context->getCaps().maxDrawBuffers) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } + if (context->getExtensions().webglCompatibility) + { + constexpr GLenum validComponentTypes[] = {GL_UNSIGNED_INT}; + if (!ValidateWebGLFramebufferAttachmentClearType( + context, drawbuffer, validComponentTypes, ArraySize(validComponentTypes))) + { + return false; + } + } break; default: - context->recordError(Error(GL_INVALID_ENUM)); + context->handleError(InvalidEnum()); return false; } @@ -1704,21 +1795,31 @@ bool ValidateClearBufferfv(ValidationContext *context, if (drawbuffer < 0 || static_cast(drawbuffer) >= context->getCaps().maxDrawBuffers) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } + if (context->getExtensions().webglCompatibility) + { + constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED, + GL_SIGNED_NORMALIZED}; + if (!ValidateWebGLFramebufferAttachmentClearType( + context, drawbuffer, validComponentTypes, ArraySize(validComponentTypes))) + { + return false; + } + } break; case GL_DEPTH: if (drawbuffer != 0) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } break; default: - context->recordError(Error(GL_INVALID_ENUM)); + context->handleError(InvalidEnum()); return false; } @@ -1736,13 +1837,13 @@ bool ValidateClearBufferfi(ValidationContext *context, case GL_DEPTH_STENCIL: if (drawbuffer != 0) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return false; } break; default: - context->recordError(Error(GL_INVALID_ENUM)); + context->handleError(InvalidEnum()); return false; } @@ -1751,9 +1852,9 @@ bool ValidateClearBufferfi(ValidationContext *context, bool ValidateDrawBuffers(ValidationContext *context, GLsizei n, const GLenum *bufs) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { - context->recordError(Error(GL_INVALID_OPERATION, "Context does not support GLES3.")); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); return false; } @@ -1771,9 +1872,9 @@ bool ValidateCopyTexSubImage3D(Context *context, GLsizei width, GLsizei height) { - if (context->getClientVersion() < 3) + if (context->getClientMajorVersion() < 3) { - context->recordError(Error(GL_INVALID_OPERATION)); + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); return false; } @@ -1781,4 +1882,1821 @@ bool ValidateCopyTexSubImage3D(Context *context, yoffset, zoffset, x, y, width, height, 0); } +bool ValidateTexImage3D(Context *context, + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const void *pixels) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + return ValidateES3TexImage3DParameters(context, target, level, internalformat, false, false, 0, + 0, 0, width, height, depth, border, format, type, -1, + pixels); +} + +bool ValidateTexImage3DRobustANGLE(Context *context, + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + return ValidateES3TexImage3DParameters(context, target, level, internalformat, false, false, 0, + 0, 0, width, height, depth, border, format, type, + bufSize, pixels); +} + +bool ValidateTexSubImage3D(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *pixels) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + return ValidateES3TexImage3DParameters(context, target, level, GL_NONE, false, true, xoffset, + yoffset, zoffset, width, height, depth, 0, format, type, + -1, pixels); +} + +bool ValidateTexSubImage3DRobustANGLE(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + return ValidateES3TexImage3DParameters(context, target, level, GL_NONE, false, true, xoffset, + yoffset, zoffset, width, height, depth, 0, format, type, + bufSize, pixels); +} + +bool ValidateCompressedTexSubImage3D(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void *data) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format); + if (!formatInfo.compressed) + { + context->handleError(InvalidEnum() << "Not a valid compressed texture format"); + return false; + } + + auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, depth)); + if (blockSizeOrErr.isError()) + { + context->handleError(blockSizeOrErr.getError()); + return false; + } + if (imageSize < 0 || static_cast(imageSize) != blockSizeOrErr.getResult()) + { + context->handleError(InvalidValue()); + return false; + } + + if (!data) + { + context->handleError(InvalidValue()); + return false; + } + + return ValidateES3TexImage3DParameters(context, target, level, GL_NONE, true, true, xoffset, + yoffset, zoffset, width, height, depth, 0, format, + GL_NONE, -1, data); +} +bool ValidateCompressedTexSubImage3DRobustANGLE(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + GLsizei dataSize, + const void *data) +{ + if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize)) + { + return false; + } + + return ValidateCompressedTexSubImage3D(context, target, level, xoffset, yoffset, zoffset, width, + height, depth, format, imageSize, data); +} + +bool ValidateGenQueries(Context *context, GLint n, GLuint *) +{ + return ValidateGenOrDeleteES3(context, n); +} + +bool ValidateDeleteQueries(Context *context, GLint n, const GLuint *) +{ + return ValidateGenOrDeleteES3(context, n); +} + +bool ValidateGenSamplers(Context *context, GLint count, GLuint *) +{ + return ValidateGenOrDeleteCountES3(context, count); +} + +bool ValidateDeleteSamplers(Context *context, GLint count, const GLuint *) +{ + return ValidateGenOrDeleteCountES3(context, count); +} + +bool ValidateGenTransformFeedbacks(Context *context, GLint n, GLuint *) +{ + return ValidateGenOrDeleteES3(context, n); +} + +bool ValidateDeleteTransformFeedbacks(Context *context, GLint n, const GLuint *ids) +{ + if (!ValidateGenOrDeleteES3(context, n)) + { + return false; + } + for (GLint i = 0; i < n; ++i) + { + auto *transformFeedback = context->getTransformFeedback(ids[i]); + if (transformFeedback != nullptr && transformFeedback->isActive()) + { + // ES 3.0.4 section 2.15.1 page 86 + context->handleError(InvalidOperation() + << "Attempt to delete active transform feedback."); + return false; + } + } + return true; +} + +bool ValidateGenVertexArrays(Context *context, GLint n, GLuint *) +{ + return ValidateGenOrDeleteES3(context, n); +} + +bool ValidateDeleteVertexArrays(Context *context, GLint n, const GLuint *) +{ + return ValidateGenOrDeleteES3(context, n); +} + +bool ValidateBeginTransformFeedback(Context *context, GLenum primitiveMode) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + switch (primitiveMode) + { + case GL_TRIANGLES: + case GL_LINES: + case GL_POINTS: + break; + + default: + context->handleError(InvalidEnum() << "Invalid primitive mode."); + return false; + } + + TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback(); + ASSERT(transformFeedback != nullptr); + + if (transformFeedback->isActive()) + { + context->handleError(InvalidOperation() << "Transform feedback is already active."); + return false; + } + + for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++) + { + const auto &buffer = transformFeedback->getIndexedBuffer(i); + if (buffer.get() && buffer->isMapped()) + { + context->handleError(InvalidOperation() << "Transform feedback has a mapped buffer."); + return false; + } + } + + Program *program = context->getGLState().getProgram(); + + if (!program) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound); + return false; + } + + if (program->getTransformFeedbackVaryingCount() == 0) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoTransformFeedbackOutputVariables); + return false; + } + + return true; +} + +bool ValidateGetBufferPointerv(Context *context, BufferBinding target, GLenum pname, void **params) +{ + return ValidateGetBufferPointervBase(context, target, pname, nullptr, params); +} + +bool ValidateGetBufferPointervRobustANGLE(Context *context, + BufferBinding target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **params) +{ + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateGetBufferPointervBase(context, target, pname, length, params)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *length)) + { + return false; + } + + return true; +} + +bool ValidateUnmapBuffer(Context *context, BufferBinding target) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + return ValidateUnmapBufferBase(context, target); +} + +bool ValidateMapBufferRange(Context *context, + BufferBinding target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + return ValidateMapBufferRangeBase(context, target, offset, length, access); +} + +bool ValidateFlushMappedBufferRange(Context *context, + BufferBinding target, + GLintptr offset, + GLsizeiptr length) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + return ValidateFlushMappedBufferRangeBase(context, target, offset, length); +} + +bool ValidateIndexedStateQuery(ValidationContext *context, + GLenum pname, + GLuint index, + GLsizei *length) +{ + if (length) + { + *length = 0; + } + + GLenum nativeType; + unsigned int numParams; + if (!context->getIndexedQueryParameterInfo(pname, &nativeType, &numParams)) + { + context->handleError(InvalidEnum()); + return false; + } + + const Caps &caps = context->getCaps(); + switch (pname) + { + case GL_TRANSFORM_FEEDBACK_BUFFER_START: + case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: + case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: + if (index >= caps.maxTransformFeedbackSeparateAttributes) + { + context->handleError(InvalidValue()); + return false; + } + break; + + case GL_UNIFORM_BUFFER_START: + case GL_UNIFORM_BUFFER_SIZE: + case GL_UNIFORM_BUFFER_BINDING: + if (index >= caps.maxUniformBufferBindings) + { + context->handleError(InvalidValue()); + return false; + } + break; + + case GL_MAX_COMPUTE_WORK_GROUP_SIZE: + case GL_MAX_COMPUTE_WORK_GROUP_COUNT: + if (index >= 3u) + { + context->handleError(InvalidValue()); + return false; + } + break; + + case GL_ATOMIC_COUNTER_BUFFER_START: + case GL_ATOMIC_COUNTER_BUFFER_SIZE: + case GL_ATOMIC_COUNTER_BUFFER_BINDING: + if (context->getClientVersion() < ES_3_1) + { + context->handleError( + InvalidEnum() + << "Atomic Counter buffers are not supported in this version of GL"); + return false; + } + if (index >= caps.maxAtomicCounterBufferBindings) + { + context->handleError( + InvalidValue() + << "index is outside the valid range for GL_ATOMIC_COUNTER_BUFFER_BINDING"); + return false; + } + break; + + case GL_SHADER_STORAGE_BUFFER_START: + case GL_SHADER_STORAGE_BUFFER_SIZE: + case GL_SHADER_STORAGE_BUFFER_BINDING: + if (context->getClientVersion() < ES_3_1) + { + context->handleError( + InvalidEnum() + << "Shader storage buffers are not supported in this version of GL"); + return false; + } + if (index >= caps.maxShaderStorageBufferBindings) + { + context->handleError( + InvalidValue() + << "index is outside the valid range for GL_SHADER_STORAGE_BUFFER_BINDING"); + return false; + } + break; + + case GL_VERTEX_BINDING_BUFFER: + case GL_VERTEX_BINDING_DIVISOR: + case GL_VERTEX_BINDING_OFFSET: + case GL_VERTEX_BINDING_STRIDE: + if (context->getClientVersion() < ES_3_1) + { + context->handleError( + InvalidEnum() + << "Vertex Attrib Bindings are not supported in this version of GL"); + return false; + } + if (index >= caps.maxVertexAttribBindings) + { + context->handleError( + InvalidValue() + << "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS."); + return false; + } + break; + case GL_SAMPLE_MASK_VALUE: + if (context->getClientVersion() < ES_3_1) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumRequiresGLES31); + return false; + } + if (index >= caps.maxSampleMaskWords) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidSampleMaskNumber); + return false; + } + break; + default: + context->handleError(InvalidEnum()); + return false; + } + + if (length) + { + *length = 1; + } + + return true; +} + +bool ValidateGetIntegeri_v(ValidationContext *context, GLenum target, GLuint index, GLint *data) +{ + if (context->getClientVersion() < ES_3_0) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + return ValidateIndexedStateQuery(context, target, index, nullptr); +} + +bool ValidateGetIntegeri_vRobustANGLE(ValidationContext *context, + GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint *data) +{ + if (context->getClientVersion() < ES_3_0) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateIndexedStateQuery(context, target, index, length)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *length)) + { + return false; + } + + return true; +} + +bool ValidateGetInteger64i_v(ValidationContext *context, GLenum target, GLuint index, GLint64 *data) +{ + if (context->getClientVersion() < ES_3_0) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + return ValidateIndexedStateQuery(context, target, index, nullptr); +} + +bool ValidateGetInteger64i_vRobustANGLE(ValidationContext *context, + GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint64 *data) +{ + if (context->getClientVersion() < ES_3_0) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateIndexedStateQuery(context, target, index, length)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *length)) + { + return false; + } + + return true; +} + +bool ValidateCopyBufferSubData(ValidationContext *context, + BufferBinding readTarget, + BufferBinding writeTarget, + GLintptr readOffset, + GLintptr writeOffset, + GLsizeiptr size) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + if (!ValidBufferType(context, readTarget) || !ValidBufferType(context, writeTarget)) + { + context->handleError(InvalidEnum() << "Invalid buffer target"); + return false; + } + + Buffer *readBuffer = context->getGLState().getTargetBuffer(readTarget); + Buffer *writeBuffer = context->getGLState().getTargetBuffer(writeTarget); + + if (!readBuffer || !writeBuffer) + { + context->handleError(InvalidOperation() << "No buffer bound to target"); + return false; + } + + // Verify that readBuffer and writeBuffer are not currently mapped + if (readBuffer->isMapped() || writeBuffer->isMapped()) + { + context->handleError(InvalidOperation() + << "Cannot call CopyBufferSubData on a mapped buffer"); + return false; + } + + CheckedNumeric checkedReadOffset(readOffset); + CheckedNumeric checkedWriteOffset(writeOffset); + CheckedNumeric checkedSize(size); + + auto checkedReadSum = checkedReadOffset + checkedSize; + auto checkedWriteSum = checkedWriteOffset + checkedSize; + + if (!checkedReadSum.IsValid() || !checkedWriteSum.IsValid() || + !IsValueInRangeForNumericType(readBuffer->getSize()) || + !IsValueInRangeForNumericType(writeBuffer->getSize())) + { + context->handleError(InvalidValue() << "Integer overflow when validating copy offsets."); + return false; + } + + if (readOffset < 0 || writeOffset < 0 || size < 0) + { + context->handleError(InvalidValue() + << "readOffset, writeOffset and size must all be non-negative"); + return false; + } + + if (checkedReadSum.ValueOrDie() > readBuffer->getSize() || + checkedWriteSum.ValueOrDie() > writeBuffer->getSize()) + { + context->handleError(InvalidValue() << "Buffer offset overflow in CopyBufferSubData"); + return false; + } + + if (readBuffer == writeBuffer) + { + auto checkedOffsetDiff = (checkedReadOffset - checkedWriteOffset).Abs(); + if (!checkedOffsetDiff.IsValid()) + { + // This shold not be possible. + UNREACHABLE(); + context->handleError(InvalidValue() + << "Integer overflow when validating same buffer copy."); + return false; + } + + if (checkedOffsetDiff.ValueOrDie() < size) + { + context->handleError(InvalidValue()); + return false; + } + } + + return true; +} + +bool ValidateGetStringi(Context *context, GLenum name, GLuint index) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + switch (name) + { + case GL_EXTENSIONS: + if (index >= context->getExtensionStringCount()) + { + context->handleError(InvalidValue() + << "index must be less than the number of extension strings."); + return false; + } + break; + + case GL_REQUESTABLE_EXTENSIONS_ANGLE: + if (!context->getExtensions().requestExtension) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName); + return false; + } + if (index >= context->getRequestableExtensionStringCount()) + { + context->handleError( + InvalidValue() + << "index must be less than the number of requestable extension strings."); + return false; + } + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName); + return false; + } + + return true; +} + +bool ValidateRenderbufferStorageMultisample(ValidationContext *context, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + if (!ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat, width, + height)) + { + return false; + } + + // The ES3 spec(section 4.4.2) states that the internal format must be sized and not an integer + // format if samples is greater than zero. + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat); + if ((formatInfo.componentType == GL_UNSIGNED_INT || formatInfo.componentType == GL_INT) && + samples > 0) + { + context->handleError(InvalidOperation()); + return false; + } + + // The behavior is different than the ANGLE version, which would generate a GL_OUT_OF_MEMORY. + const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat); + if (static_cast(samples) > formatCaps.getMaxSamples()) + { + context->handleError( + InvalidOperation() + << "Samples must not be greater than maximum supported value for the format."); + return false; + } + + return true; +} + +bool ValidateVertexAttribIPointer(ValidationContext *context, + GLuint index, + GLint size, + GLenum type, + GLsizei stride, + const void *pointer) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + if (!ValidateVertexFormatBase(context, index, size, type, true)) + { + return false; + } + + if (stride < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride); + return false; + } + + const Caps &caps = context->getCaps(); + if (context->getClientVersion() >= ES_3_1) + { + if (stride > caps.maxVertexAttribStride) + { + context->handleError(InvalidValue() + << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE."); + return false; + } + + // [OpenGL ES 3.1] Section 10.3.1 page 245: + // glVertexAttribBinding is part of the equivalent code of VertexAttribIPointer, so its + // validation should be inherited. + if (index >= caps.maxVertexAttribBindings) + { + context->handleError(InvalidValue() + << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS."); + return false; + } + } + + // [OpenGL ES 3.0.2] Section 2.8 page 24: + // An INVALID_OPERATION error is generated when a non-zero vertex array object + // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point, + // and the pointer argument is not NULL. + if (context->getGLState().getVertexArrayId() != 0 && + context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 && pointer != nullptr) + { + context + ->handleError(InvalidOperation() + << "Client data cannot be used with a non-default vertex array object."); + return false; + } + + if (context->getExtensions().webglCompatibility) + { + if (!ValidateWebGLVertexAttribPointer(context, type, false, stride, pointer, true)) + { + return false; + } + } + + return true; +} + +bool ValidateGetSynciv(Context *context, + GLsync sync, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *values) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + if (bufSize < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize); + return false; + } + + Sync *syncObject = context->getSync(sync); + if (!syncObject) + { + context->handleError(InvalidValue() << "Invalid sync object."); + return false; + } + + switch (pname) + { + case GL_OBJECT_TYPE: + case GL_SYNC_CONDITION: + case GL_SYNC_FLAGS: + case GL_SYNC_STATUS: + break; + + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname); + return false; + } + + return true; +} + +bool ValidateDrawElementsInstanced(ValidationContext *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei instanceCount) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + return ValidateDrawElementsInstancedCommon(context, mode, count, type, indices, instanceCount); +} + +bool ValidateFramebufferTextureMultiviewLayeredANGLE(Context *context, + GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint baseViewIndex, + GLsizei numViews) +{ + + if (!ValidateFramebufferTextureMultiviewBaseANGLE(context, target, attachment, texture, level, + numViews)) + { + return false; + } + + if (texture != 0) + { + if (baseViewIndex < 0) + { + context->handleError(InvalidValue() << "baseViewIndex cannot be less than 0."); + return false; + } + + Texture *tex = context->getTexture(texture); + ASSERT(tex); + + switch (tex->getTarget()) + { + case GL_TEXTURE_2D_ARRAY: + { + const Caps &caps = context->getCaps(); + if (static_cast(baseViewIndex + numViews) > caps.maxArrayTextureLayers) + { + context->handleError(InvalidValue() << "baseViewIndex+numViews cannot be " + "greater than " + "GL_MAX_ARRAY_TEXTURE_LAYERS."); + return false; + } + } + break; + default: + context->handleError(InvalidOperation() + << "Texture's target must be GL_TEXTURE_2D_ARRAY."); + return false; + } + + if (!ValidateFramebufferTextureMultiviewLevelAndFormat(context, tex, level)) + { + return false; + } + } + + return true; +} + +bool ValidateFramebufferTextureMultiviewSideBySideANGLE(Context *context, + GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLsizei numViews, + const GLint *viewportOffsets) +{ + if (!ValidateFramebufferTextureMultiviewBaseANGLE(context, target, attachment, texture, level, + numViews)) + { + return false; + } + + if (texture != 0) + { + const GLsizei numViewportOffsetValues = numViews * 2; + for (GLsizei i = 0; i < numViewportOffsetValues; ++i) + { + if (viewportOffsets[i] < 0) + { + context->handleError(InvalidValue() + << "viewportOffsets cannot contain negative values."); + return false; + } + } + + Texture *tex = context->getTexture(texture); + ASSERT(tex); + + switch (tex->getTarget()) + { + case GL_TEXTURE_2D: + break; + default: + context->handleError(InvalidOperation() + << "Texture's target must be GL_TEXTURE_2D."); + return false; + } + + if (!ValidateFramebufferTextureMultiviewLevelAndFormat(context, tex, level)) + { + return false; + } + } + + return true; +} + +bool ValidateUniform1ui(Context *context, GLint location, GLuint v0) +{ + return ValidateUniformES3(context, GL_UNSIGNED_INT, location, 1); +} + +bool ValidateUniform2ui(Context *context, GLint location, GLuint v0, GLuint v1) +{ + return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC2, location, 1); +} + +bool ValidateUniform3ui(Context *context, GLint location, GLuint v0, GLuint v1, GLuint v2) +{ + return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC3, location, 1); +} + +bool ValidateUniform4ui(Context *context, + GLint location, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3) +{ + return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC4, location, 1); +} + +bool ValidateUniform1uiv(Context *context, GLint location, GLsizei count, const GLuint *value) +{ + return ValidateUniformES3(context, GL_UNSIGNED_INT, location, count); +} + +bool ValidateUniform2uiv(Context *context, GLint location, GLsizei count, const GLuint *value) +{ + return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC2, location, count); +} + +bool ValidateUniform3uiv(Context *context, GLint location, GLsizei count, const GLuint *value) +{ + return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC3, location, count); +} + +bool ValidateUniform4uiv(Context *context, GLint location, GLsizei count, const GLuint *value) +{ + return ValidateUniformES3(context, GL_UNSIGNED_INT_VEC4, location, count); +} + +bool ValidateIsQuery(Context *context, GLuint id) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + return true; +} + +bool ValidateUniformMatrix2x3fv(Context *context, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateUniformMatrixES3(context, GL_FLOAT_MAT2x3, location, count, transpose); +} + +bool ValidateUniformMatrix3x2fv(Context *context, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateUniformMatrixES3(context, GL_FLOAT_MAT3x2, location, count, transpose); +} + +bool ValidateUniformMatrix2x4fv(Context *context, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateUniformMatrixES3(context, GL_FLOAT_MAT2x4, location, count, transpose); +} + +bool ValidateUniformMatrix4x2fv(Context *context, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateUniformMatrixES3(context, GL_FLOAT_MAT4x2, location, count, transpose); +} + +bool ValidateUniformMatrix3x4fv(Context *context, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateUniformMatrixES3(context, GL_FLOAT_MAT3x4, location, count, transpose); +} + +bool ValidateUniformMatrix4x3fv(Context *context, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateUniformMatrixES3(context, GL_FLOAT_MAT4x3, location, count, transpose); +} + +bool ValidateEndTransformFeedback(Context *context) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback(); + ASSERT(transformFeedback != nullptr); + + if (!transformFeedback->isActive()) + { + context->handleError(InvalidOperation()); + return false; + } + + return true; +} + +bool ValidateTransformFeedbackVaryings(Context *context, + GLuint program, + GLsizei count, + const GLchar *const *varyings, + GLenum bufferMode) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + if (count < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount); + return false; + } + + switch (bufferMode) + { + case GL_INTERLEAVED_ATTRIBS: + break; + case GL_SEPARATE_ATTRIBS: + { + const Caps &caps = context->getCaps(); + if (static_cast(count) > caps.maxTransformFeedbackSeparateAttributes) + { + context->handleError(InvalidValue()); + return false; + } + break; + } + default: + context->handleError(InvalidEnum()); + return false; + } + + Program *programObject = GetValidProgram(context, program); + if (!programObject) + { + return false; + } + + return true; +} + +bool ValidateGetTransformFeedbackVarying(Context *context, + GLuint program, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLsizei *size, + GLenum *type, + GLchar *name) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + if (bufSize < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize); + return false; + } + + Program *programObject = GetValidProgram(context, program); + if (!programObject) + { + return false; + } + + if (index >= static_cast(programObject->getTransformFeedbackVaryingCount())) + { + context->handleError(InvalidValue()); + return false; + } + + return true; +} + +bool ValidateBindTransformFeedback(Context *context, GLenum target, GLuint id) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + switch (target) + { + case GL_TRANSFORM_FEEDBACK: + { + // Cannot bind a transform feedback object if the current one is started and not + // paused (3.0.2 pg 85 section 2.14.1) + TransformFeedback *curTransformFeedback = + context->getGLState().getCurrentTransformFeedback(); + if (curTransformFeedback && curTransformFeedback->isActive() && + !curTransformFeedback->isPaused()) + { + context->handleError(InvalidOperation()); + return false; + } + + // Cannot bind a transform feedback object that does not exist (3.0.2 pg 85 section + // 2.14.1) + if (!context->isTransformFeedbackGenerated(id)) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), TransformFeedbackDoesNotExist); + return false; + } + } + break; + + default: + context->handleError(InvalidEnum()); + return false; + } + + return true; +} + +bool ValidateIsTransformFeedback(Context *context, GLuint id) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + return true; +} + +bool ValidatePauseTransformFeedback(Context *context) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback(); + ASSERT(transformFeedback != nullptr); + + // Current transform feedback must be active and not paused in order to pause (3.0.2 pg 86) + if (!transformFeedback->isActive() || transformFeedback->isPaused()) + { + context->handleError(InvalidOperation()); + return false; + } + + return true; +} + +bool ValidateResumeTransformFeedback(Context *context) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback(); + ASSERT(transformFeedback != nullptr); + + // Current transform feedback must be active and paused in order to resume (3.0.2 pg 86) + if (!transformFeedback->isActive() || !transformFeedback->isPaused()) + { + context->handleError(InvalidOperation()); + return false; + } + + return true; +} + +bool ValidateVertexAttribI4i(Context *context, GLuint index, GLint x, GLint y, GLint z, GLint w) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + return ValidateVertexAttribIndex(context, index); +} + +bool ValidateVertexAttribI4ui(Context *context, + GLuint index, + GLuint x, + GLuint y, + GLuint z, + GLuint w) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + return ValidateVertexAttribIndex(context, index); +} + +bool ValidateVertexAttribI4iv(Context *context, GLuint index, const GLint *v) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + return ValidateVertexAttribIndex(context, index); +} + +bool ValidateVertexAttribI4uiv(Context *context, GLuint index, const GLuint *v) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + return ValidateVertexAttribIndex(context, index); +} + +bool ValidateGetFragDataLocation(Context *context, GLuint program, const GLchar *name) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + Program *programObject = GetValidProgram(context, program); + if (!programObject) + { + return false; + } + + if (!programObject->isLinked()) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked); + return false; + } + + return true; +} + +bool ValidateGetUniformIndices(Context *context, + GLuint program, + GLsizei uniformCount, + const GLchar *const *uniformNames, + GLuint *uniformIndices) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + if (uniformCount < 0) + { + context->handleError(InvalidValue()); + return false; + } + + Program *programObject = GetValidProgram(context, program); + if (!programObject) + { + return false; + } + + return true; +} + +bool ValidateGetActiveUniformsiv(Context *context, + GLuint program, + GLsizei uniformCount, + const GLuint *uniformIndices, + GLenum pname, + GLint *params) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + if (uniformCount < 0) + { + context->handleError(InvalidValue()); + return false; + } + + Program *programObject = GetValidProgram(context, program); + if (!programObject) + { + return false; + } + + switch (pname) + { + case GL_UNIFORM_TYPE: + case GL_UNIFORM_SIZE: + case GL_UNIFORM_NAME_LENGTH: + case GL_UNIFORM_BLOCK_INDEX: + case GL_UNIFORM_OFFSET: + case GL_UNIFORM_ARRAY_STRIDE: + case GL_UNIFORM_MATRIX_STRIDE: + case GL_UNIFORM_IS_ROW_MAJOR: + break; + + default: + context->handleError(InvalidEnum()); + return false; + } + + if (uniformCount > programObject->getActiveUniformCount()) + { + context->handleError(InvalidValue()); + return false; + } + + for (int uniformId = 0; uniformId < uniformCount; uniformId++) + { + const GLuint index = uniformIndices[uniformId]; + + if (index >= static_cast(programObject->getActiveUniformCount())) + { + context->handleError(InvalidValue()); + return false; + } + } + + return true; +} + +bool ValidateGetUniformBlockIndex(Context *context, GLuint program, const GLchar *uniformBlockName) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + Program *programObject = GetValidProgram(context, program); + if (!programObject) + { + return false; + } + + return true; +} + +bool ValidateGetActiveUniformBlockiv(Context *context, + GLuint program, + GLuint uniformBlockIndex, + GLenum pname, + GLint *params) +{ + return ValidateGetActiveUniformBlockivBase(context, program, uniformBlockIndex, pname, nullptr); +} + +bool ValidateGetActiveUniformBlockName(Context *context, + GLuint program, + GLuint uniformBlockIndex, + GLsizei bufSize, + GLsizei *length, + GLchar *uniformBlockName) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + Program *programObject = GetValidProgram(context, program); + if (!programObject) + { + return false; + } + + if (uniformBlockIndex >= programObject->getActiveUniformBlockCount()) + { + context->handleError(InvalidValue()); + return false; + } + + return true; +} + +bool ValidateUniformBlockBinding(Context *context, + GLuint program, + GLuint uniformBlockIndex, + GLuint uniformBlockBinding) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + if (uniformBlockBinding >= context->getCaps().maxUniformBufferBindings) + { + context->handleError(InvalidValue()); + return false; + } + + Program *programObject = GetValidProgram(context, program); + if (!programObject) + { + return false; + } + + // if never linked, there won't be any uniform blocks + if (uniformBlockIndex >= programObject->getActiveUniformBlockCount()) + { + context->handleError(InvalidValue()); + return false; + } + + return true; +} + +bool ValidateDrawArraysInstanced(Context *context, + GLenum mode, + GLint first, + GLsizei count, + GLsizei primcount) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + return ValidateDrawArraysInstancedBase(context, mode, first, count, primcount); +} + +bool ValidateFenceSync(Context *context, GLenum condition, GLbitfield flags) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + if (condition != GL_SYNC_GPU_COMMANDS_COMPLETE) + { + context->handleError(InvalidEnum()); + return false; + } + + if (flags != 0) + { + context->handleError(InvalidValue()); + return false; + } + + return true; +} + +bool ValidateIsSync(Context *context, GLsync sync) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + return true; +} + +bool ValidateDeleteSync(Context *context, GLsync sync) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + if (sync != static_cast(0) && !context->getSync(sync)) + { + context->handleError(InvalidValue()); + return false; + } + + return true; +} + +bool ValidateClientWaitSync(Context *context, GLsync sync, GLbitfield flags, GLuint64 timeout) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + if ((flags & ~(GL_SYNC_FLUSH_COMMANDS_BIT)) != 0) + { + context->handleError(InvalidValue()); + return false; + } + + Sync *clientWaitSync = context->getSync(sync); + if (!clientWaitSync) + { + context->handleError(InvalidValue()); + return false; + } + + return true; +} + +bool ValidateWaitSync(Context *context, GLsync sync, GLbitfield flags, GLuint64 timeout) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + if (flags != 0) + { + context->handleError(InvalidValue()); + return false; + } + + if (timeout != GL_TIMEOUT_IGNORED) + { + context->handleError(InvalidValue()); + return false; + } + + Sync *waitSync = context->getSync(sync); + if (!waitSync) + { + context->handleError(InvalidValue()); + return false; + } + + return true; +} + +bool ValidateGetInteger64v(Context *context, GLenum pname, GLint64 *params) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + GLenum nativeType = GL_NONE; + unsigned int numParams = 0; + if (!ValidateStateQuery(context, pname, &nativeType, &numParams)) + { + return false; + } + + return true; +} + +bool ValidateIsSampler(Context *context, GLuint sampler) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + return true; +} + +bool ValidateBindSampler(Context *context, GLuint unit, GLuint sampler) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + if (sampler != 0 && !context->isSampler(sampler)) + { + context->handleError(InvalidOperation()); + return false; + } + + if (unit >= context->getCaps().maxCombinedTextureImageUnits) + { + context->handleError(InvalidValue()); + return false; + } + + return true; +} + +bool ValidateVertexAttribDivisor(Context *context, GLuint index, GLuint divisor) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + return ValidateVertexAttribIndex(context, index); +} + +bool ValidateTexStorage2D(Context *context, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + if (!ValidateES3TexStorage2DParameters(context, target, levels, internalformat, width, height, + 1)) + { + return false; + } + + return true; +} + +bool ValidateTexStorage3D(Context *context, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth) +{ + if (context->getClientMajorVersion() < 3) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required); + return false; + } + + if (!ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height, + depth)) + { + return false; + } + + return true; +} + +bool ValidateGetBufferParameteri64v(ValidationContext *context, + BufferBinding target, + GLenum pname, + GLint64 *params) +{ + return ValidateGetBufferParameterBase(context, target, pname, false, nullptr); +} + +bool ValidateGetSamplerParameterfv(Context *context, GLuint sampler, GLenum pname, GLfloat *params) +{ + return ValidateGetSamplerParameterBase(context, sampler, pname, nullptr); +} + +bool ValidateGetSamplerParameteriv(Context *context, GLuint sampler, GLenum pname, GLint *params) +{ + return ValidateGetSamplerParameterBase(context, sampler, pname, nullptr); +} + +bool ValidateSamplerParameterf(Context *context, GLuint sampler, GLenum pname, GLfloat param) +{ + return ValidateSamplerParameterBase(context, sampler, pname, -1, ¶m); +} + +bool ValidateSamplerParameterfv(Context *context, + GLuint sampler, + GLenum pname, + const GLfloat *params) +{ + return ValidateSamplerParameterBase(context, sampler, pname, -1, params); +} + +bool ValidateSamplerParameteri(Context *context, GLuint sampler, GLenum pname, GLint param) +{ + return ValidateSamplerParameterBase(context, sampler, pname, -1, ¶m); +} + +bool ValidateSamplerParameteriv(Context *context, GLuint sampler, GLenum pname, const GLint *params) +{ + return ValidateSamplerParameterBase(context, sampler, pname, -1, params); +} + +bool ValidateGetVertexAttribIiv(Context *context, GLuint index, GLenum pname, GLint *params) +{ + return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, true); +} + +bool ValidateGetVertexAttribIuiv(Context *context, GLuint index, GLenum pname, GLuint *params) +{ + return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, true); +} + +bool ValidateGetInternalformativ(Context *context, + GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei bufSize, + GLint *params) +{ + return ValidateGetInternalFormativBase(context, target, internalformat, pname, bufSize, + nullptr); +} + } // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/validationES3.h b/src/3rdparty/angle/src/libANGLE/validationES3.h index 7bc657790a..631b1ca43a 100644 --- a/src/3rdparty/angle/src/libANGLE/validationES3.h +++ b/src/3rdparty/angle/src/libANGLE/validationES3.h @@ -9,11 +9,14 @@ #ifndef LIBANGLE_VALIDATION_ES3_H_ #define LIBANGLE_VALIDATION_ES3_H_ +#include "libANGLE/PackedGLEnums.h" + #include namespace gl { class Context; +struct IndexRange; class ValidationContext; bool ValidateES3TexImageParametersBase(ValidationContext *context, @@ -31,7 +34,8 @@ bool ValidateES3TexImageParametersBase(ValidationContext *context, GLint border, GLenum format, GLenum type, - const GLvoid *pixels); + GLsizei imageSize, + const void *pixels); bool ValidateES3TexStorageParameters(Context *context, GLenum target, @@ -56,7 +60,8 @@ bool ValidateES3TexImage2DParameters(Context *context, GLint border, GLenum format, GLenum type, - const GLvoid *pixels); + GLsizei imageSize, + const void *pixels); bool ValidateES3TexImage3DParameters(Context *context, GLenum target, @@ -73,7 +78,8 @@ bool ValidateES3TexImage3DParameters(Context *context, GLint border, GLenum format, GLenum type, - const GLvoid *pixels); + GLsizei bufSize, + const void *pixels); bool ValidateES3CopyTexImageParametersBase(ValidationContext *context, GLenum target, @@ -141,10 +147,6 @@ bool ValidateES3TexStorage3DParameters(Context *context, GLsizei height, GLsizei depth); -bool ValidateGenQueries(Context *context, GLsizei n, const GLuint *ids); - -bool ValidateDeleteQueries(Context *context, GLsizei n, const GLuint *ids); - bool ValidateBeginQuery(Context *context, GLenum target, GLuint id); bool ValidateEndQuery(Context *context, GLenum target); @@ -153,20 +155,38 @@ bool ValidateGetQueryiv(Context *context, GLenum target, GLenum pname, GLint *pa bool ValidateGetQueryObjectuiv(Context *context, GLuint id, GLenum pname, GLuint *params); -bool ValidateFramebufferTextureLayer(Context *context, GLenum target, GLenum attachment, - GLuint texture, GLint level, GLint layer); +bool ValidateFramebufferTextureLayer(Context *context, + GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint layer); -bool ValidES3ReadFormatType(Context *context, GLenum internalFormat, GLenum format, GLenum type); - -bool ValidateES3RenderbufferStorageParameters(Context *context, GLenum target, GLsizei samples, - GLenum internalformat, GLsizei width, GLsizei height); - -bool ValidateInvalidateFramebuffer(Context *context, GLenum target, GLsizei numAttachments, +bool ValidateInvalidateFramebuffer(Context *context, + GLenum target, + GLsizei numAttachments, const GLenum *attachments); +bool ValidateInvalidateSubFramebuffer(Context *context, + GLenum target, + GLsizei numAttachments, + const GLenum *attachments, + GLint x, + GLint y, + GLsizei width, + GLsizei height); + bool ValidateClearBuffer(ValidationContext *context); -bool ValidateGetUniformuiv(Context *context, GLuint program, GLint location, GLuint* params); +bool ValidateDrawRangeElements(Context *context, + GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const void *indices); + +bool ValidateGetUniformuiv(Context *context, GLuint program, GLint location, GLuint *params); bool ValidateReadBuffer(Context *context, GLenum mode); @@ -179,12 +199,29 @@ bool ValidateCompressedTexImage3D(Context *context, GLsizei depth, GLint border, GLsizei imageSize, - const GLvoid *data); + const void *data); +bool ValidateCompressedTexImage3DRobustANGLE(Context *context, + GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + GLsizei dataSize, + const void *data); bool ValidateBindVertexArray(Context *context, GLuint array); -bool ValidateDeleteVertexArrays(Context *context, GLsizei n); -bool ValidateGenVertexArrays(Context *context, GLsizei n); -bool ValidateIsVertexArray(Context *context); +bool ValidateIsVertexArray(Context *context, GLuint array); + +bool ValidateBindBufferBase(Context *context, BufferBinding target, GLuint index, GLuint buffer); +bool ValidateBindBufferRange(Context *context, + BufferBinding target, + GLuint index, + GLuint buffer, + GLintptr offset, + GLsizeiptr size); bool ValidateProgramBinary(Context *context, GLuint program, @@ -197,7 +234,7 @@ bool ValidateGetProgramBinary(Context *context, GLsizei *length, GLenum *binaryFormat, void *binary); -bool ValidateProgramParameter(Context *context, GLuint program, GLenum pname, GLint value); +bool ValidateProgramParameteri(Context *context, GLuint program, GLenum pname, GLint value); bool ValidateBlitFramebuffer(Context *context, GLint srcX0, GLint srcY0, @@ -237,7 +274,341 @@ bool ValidateCopyTexSubImage3D(Context *context, GLint y, GLsizei width, GLsizei height); +bool ValidateTexImage3D(Context *context, + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const void *pixels); +bool ValidateTexImage3DRobustANGLE(Context *context, + GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels); +bool ValidateTexSubImage3D(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *pixels); +bool ValidateTexSubImage3DRobustANGLE(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels); +bool ValidateCompressedTexSubImage3D(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void *data); +bool ValidateCompressedTexSubImage3DRobustANGLE(Context *context, + GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + GLsizei dataSize, + const void *data); + +bool ValidateGenQueries(Context *context, GLint n, GLuint *ids); +bool ValidateDeleteQueries(Context *context, GLint n, const GLuint *ids); +bool ValidateGenSamplers(Context *context, GLint count, GLuint *samplers); +bool ValidateDeleteSamplers(Context *context, GLint count, const GLuint *samplers); +bool ValidateGenTransformFeedbacks(Context *context, GLint n, GLuint *ids); +bool ValidateDeleteTransformFeedbacks(Context *context, GLint n, const GLuint *ids); +bool ValidateGenVertexArrays(Context *context, GLint n, GLuint *arrays); +bool ValidateDeleteVertexArrays(Context *context, GLint n, const GLuint *arrays); + +bool ValidateBeginTransformFeedback(Context *context, GLenum primitiveMode); + +bool ValidateGetBufferPointerv(Context *context, BufferBinding target, GLenum pname, void **params); +bool ValidateGetBufferPointervRobustANGLE(Context *context, + BufferBinding target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **params); +bool ValidateUnmapBuffer(Context *context, BufferBinding target); +bool ValidateMapBufferRange(Context *context, + BufferBinding target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access); +bool ValidateFlushMappedBufferRange(Context *context, + BufferBinding target, + GLintptr offset, + GLsizeiptr length); + +bool ValidateIndexedStateQuery(ValidationContext *context, + GLenum pname, + GLuint index, + GLsizei *length); +bool ValidateGetIntegeri_v(ValidationContext *context, GLenum target, GLuint index, GLint *data); +bool ValidateGetIntegeri_vRobustANGLE(ValidationContext *context, + GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint *data); +bool ValidateGetInteger64i_v(ValidationContext *context, + GLenum target, + GLuint index, + GLint64 *data); +bool ValidateGetInteger64i_vRobustANGLE(ValidationContext *context, + GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint64 *data); + +bool ValidateCopyBufferSubData(ValidationContext *context, + BufferBinding readTarget, + BufferBinding writeTarget, + GLintptr readOffset, + GLintptr writeOffset, + GLsizeiptr size); + +bool ValidateGetStringi(Context *context, GLenum name, GLuint index); +bool ValidateRenderbufferStorageMultisample(ValidationContext *context, + GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height); + +bool ValidateVertexAttribIPointer(ValidationContext *context, + GLuint index, + GLint size, + GLenum type, + GLsizei stride, + const void *pointer); + +bool ValidateGetSynciv(Context *context, + GLsync sync, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *values); + +bool ValidateDrawElementsInstanced(ValidationContext *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei instanceCount); + +bool ValidateFramebufferTextureMultiviewLayeredANGLE(Context *context, + GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint baseViewIndex, + GLsizei numViews); + +bool ValidateFramebufferTextureMultiviewSideBySideANGLE(Context *context, + GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLsizei numViews, + const GLint *viewportOffsets); + +bool ValidateIsQuery(Context *context, GLuint id); + +bool ValidateUniform1ui(Context *context, GLint location, GLuint v0); +bool ValidateUniform2ui(Context *context, GLint location, GLuint v0, GLuint v1); +bool ValidateUniform3ui(Context *context, GLint location, GLuint v0, GLuint v1, GLuint v2); +bool ValidateUniform4ui(Context *context, + GLint location, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3); + +bool ValidateUniform1uiv(Context *context, GLint location, GLsizei count, const GLuint *value); +bool ValidateUniform2uiv(Context *context, GLint location, GLsizei count, const GLuint *value); +bool ValidateUniform3uiv(Context *context, GLint location, GLsizei count, const GLuint *value); +bool ValidateUniform4uiv(Context *context, GLint location, GLsizei count, const GLuint *value); + +bool ValidateUniformMatrix2x3fv(Context *context, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateUniformMatrix3x2fv(Context *context, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateUniformMatrix2x4fv(Context *context, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateUniformMatrix4x2fv(Context *context, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateUniformMatrix3x4fv(Context *context, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateUniformMatrix4x3fv(Context *context, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + +bool ValidateEndTransformFeedback(Context *context); +bool ValidateTransformFeedbackVaryings(Context *context, + GLuint program, + GLsizei count, + const GLchar *const *varyings, + GLenum bufferMode); +bool ValidateGetTransformFeedbackVarying(Context *context, + GLuint program, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLsizei *size, + GLenum *type, + GLchar *name); +bool ValidateBindTransformFeedback(Context *context, GLenum target, GLuint id); +bool ValidateIsTransformFeedback(Context *context, GLuint id); +bool ValidatePauseTransformFeedback(Context *context); +bool ValidateResumeTransformFeedback(Context *context); +bool ValidateVertexAttribI4i(Context *context, GLuint index, GLint x, GLint y, GLint z, GLint w); +bool ValidateVertexAttribI4ui(Context *context, + GLuint index, + GLuint x, + GLuint y, + GLuint z, + GLuint w); +bool ValidateVertexAttribI4iv(Context *context, GLuint index, const GLint *v); +bool ValidateVertexAttribI4uiv(Context *context, GLuint index, const GLuint *v); +bool ValidateGetFragDataLocation(Context *context, GLuint program, const GLchar *name); +bool ValidateGetUniformIndices(Context *context, + GLuint program, + GLsizei uniformCount, + const GLchar *const *uniformNames, + GLuint *uniformIndices); +bool ValidateGetActiveUniformsiv(Context *context, + GLuint program, + GLsizei uniformCount, + const GLuint *uniformIndices, + GLenum pname, + GLint *params); +bool ValidateGetUniformBlockIndex(Context *context, GLuint program, const GLchar *uniformBlockName); +bool ValidateGetActiveUniformBlockiv(Context *context, + GLuint program, + GLuint uniformBlockIndex, + GLenum pname, + GLint *params); +bool ValidateGetActiveUniformBlockName(Context *context, + GLuint program, + GLuint uniformBlockIndex, + GLsizei bufSize, + GLsizei *length, + GLchar *uniformBlockName); +bool ValidateUniformBlockBinding(Context *context, + GLuint program, + GLuint uniformBlockIndex, + GLuint uniformBlockBinding); +bool ValidateDrawArraysInstanced(Context *context, + GLenum mode, + GLint first, + GLsizei count, + GLsizei primcount); + +bool ValidateFenceSync(Context *context, GLenum condition, GLbitfield flags); +bool ValidateIsSync(Context *context, GLsync sync); +bool ValidateDeleteSync(Context *context, GLsync sync); +bool ValidateClientWaitSync(Context *context, GLsync sync, GLbitfield flags, GLuint64 timeout); +bool ValidateWaitSync(Context *context, GLsync sync, GLbitfield flags, GLuint64 timeout); +bool ValidateGetInteger64v(Context *context, GLenum pname, GLint64 *params); + +bool ValidateIsSampler(Context *context, GLuint sampler); +bool ValidateBindSampler(Context *context, GLuint unit, GLuint sampler); +bool ValidateVertexAttribDivisor(Context *context, GLuint index, GLuint divisor); +bool ValidateTexStorage2D(Context *context, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height); +bool ValidateTexStorage3D(Context *context, + GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth); + +bool ValidateGetVertexAttribIiv(Context *context, GLuint index, GLenum pname, GLint *params); +bool ValidateGetVertexAttribIuiv(Context *context, GLuint index, GLenum pname, GLuint *params); +bool ValidateGetBufferParameteri64v(ValidationContext *context, + BufferBinding target, + GLenum pname, + GLint64 *params); +bool ValidateSamplerParameteri(Context *context, GLuint sampler, GLenum pname, GLint param); +bool ValidateSamplerParameteriv(Context *context, + GLuint sampler, + GLenum pname, + const GLint *params); +bool ValidateSamplerParameterf(Context *context, GLuint sampler, GLenum pname, GLfloat param); +bool ValidateSamplerParameterfv(Context *context, + GLuint sampler, + GLenum pname, + const GLfloat *params); +bool ValidateGetSamplerParameteriv(Context *context, GLuint sampler, GLenum pname, GLint *params); +bool ValidateGetSamplerParameterfv(Context *context, GLuint sampler, GLenum pname, GLfloat *params); +bool ValidateGetInternalformativ(Context *context, + GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei bufSize, + GLint *params); } // namespace gl -#endif // LIBANGLE_VALIDATION_ES3_H_ +#endif // LIBANGLE_VALIDATION_ES3_H_ diff --git a/src/3rdparty/angle/src/libANGLE/validationES31.cpp b/src/3rdparty/angle/src/libANGLE/validationES31.cpp new file mode 100644 index 0000000000..b1bdccacf7 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/validationES31.cpp @@ -0,0 +1,1786 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// validationES31.cpp: Validation functions for OpenGL ES 3.1 entry point parameters + +#include "libANGLE/validationES31.h" + +#include "libANGLE/Context.h" +#include "libANGLE/ErrorStrings.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/VertexArray.h" +#include "libANGLE/validationES.h" +#include "libANGLE/validationES2.h" +#include "libANGLE/validationES3.h" + +#include "common/utilities.h" + +using namespace angle; + +namespace gl +{ + +namespace +{ + +bool ValidateNamedProgramInterface(GLenum programInterface) +{ + switch (programInterface) + { + case GL_UNIFORM: + case GL_UNIFORM_BLOCK: + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + case GL_TRANSFORM_FEEDBACK_VARYING: + case GL_BUFFER_VARIABLE: + case GL_SHADER_STORAGE_BLOCK: + return true; + default: + return false; + } +} + +bool ValidateLocationProgramInterface(GLenum programInterface) +{ + switch (programInterface) + { + case GL_UNIFORM: + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + return true; + default: + return false; + } +} + +bool ValidateProgramInterface(GLenum programInterface) +{ + return (programInterface == GL_ATOMIC_COUNTER_BUFFER || + ValidateNamedProgramInterface(programInterface)); +} + +bool ValidateProgramResourceProperty(GLenum prop) +{ + switch (prop) + { + case GL_ACTIVE_VARIABLES: + case GL_BUFFER_BINDING: + case GL_NUM_ACTIVE_VARIABLES: + + case GL_ARRAY_SIZE: + + case GL_ARRAY_STRIDE: + case GL_BLOCK_INDEX: + case GL_IS_ROW_MAJOR: + case GL_MATRIX_STRIDE: + + case GL_ATOMIC_COUNTER_BUFFER_INDEX: + + case GL_BUFFER_DATA_SIZE: + + case GL_LOCATION: + + case GL_NAME_LENGTH: + + case GL_OFFSET: + + case GL_REFERENCED_BY_VERTEX_SHADER: + case GL_REFERENCED_BY_FRAGMENT_SHADER: + case GL_REFERENCED_BY_COMPUTE_SHADER: + + case GL_TOP_LEVEL_ARRAY_SIZE: + case GL_TOP_LEVEL_ARRAY_STRIDE: + + case GL_TYPE: + return true; + + default: + return false; + } +} + +// GLES 3.10 spec: Page 82 -- Table 7.2 +bool ValidateProgramResourcePropertyByInterface(GLenum prop, GLenum programInterface) +{ + switch (prop) + { + case GL_ACTIVE_VARIABLES: + case GL_BUFFER_BINDING: + case GL_NUM_ACTIVE_VARIABLES: + { + switch (programInterface) + { + case GL_ATOMIC_COUNTER_BUFFER: + case GL_SHADER_STORAGE_BLOCK: + case GL_UNIFORM_BLOCK: + return true; + default: + return false; + } + } + + case GL_ARRAY_SIZE: + { + switch (programInterface) + { + case GL_BUFFER_VARIABLE: + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + case GL_TRANSFORM_FEEDBACK_VARYING: + case GL_UNIFORM: + return true; + default: + return false; + } + } + + case GL_ARRAY_STRIDE: + case GL_BLOCK_INDEX: + case GL_IS_ROW_MAJOR: + case GL_MATRIX_STRIDE: + { + switch (programInterface) + { + case GL_BUFFER_VARIABLE: + case GL_UNIFORM: + return true; + default: + return false; + } + } + + case GL_ATOMIC_COUNTER_BUFFER_INDEX: + { + if (programInterface == GL_UNIFORM) + { + return true; + } + return false; + } + + case GL_BUFFER_DATA_SIZE: + { + switch (programInterface) + { + case GL_ATOMIC_COUNTER_BUFFER: + case GL_SHADER_STORAGE_BLOCK: + case GL_UNIFORM_BLOCK: + return true; + default: + return false; + } + } + + case GL_LOCATION: + { + return ValidateLocationProgramInterface(programInterface); + } + + case GL_NAME_LENGTH: + { + return ValidateNamedProgramInterface(programInterface); + } + + case GL_OFFSET: + { + switch (programInterface) + { + case GL_BUFFER_VARIABLE: + case GL_UNIFORM: + return true; + default: + return false; + } + } + + case GL_REFERENCED_BY_VERTEX_SHADER: + case GL_REFERENCED_BY_FRAGMENT_SHADER: + case GL_REFERENCED_BY_COMPUTE_SHADER: + { + switch (programInterface) + { + case GL_ATOMIC_COUNTER_BUFFER: + case GL_BUFFER_VARIABLE: + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + case GL_SHADER_STORAGE_BLOCK: + case GL_UNIFORM: + case GL_UNIFORM_BLOCK: + return true; + default: + return false; + } + } + + case GL_TOP_LEVEL_ARRAY_SIZE: + case GL_TOP_LEVEL_ARRAY_STRIDE: + { + if (programInterface == GL_BUFFER_VARIABLE) + { + return true; + } + return false; + } + + case GL_TYPE: + { + switch (programInterface) + { + case GL_BUFFER_VARIABLE: + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + case GL_TRANSFORM_FEEDBACK_VARYING: + case GL_UNIFORM: + return true; + default: + return false; + } + } + + default: + return false; + } +} + +bool ValidateProgramResourceIndex(const Program *programObject, + GLenum programInterface, + GLuint index) +{ + switch (programInterface) + { + case GL_PROGRAM_INPUT: + return (index < static_cast(programObject->getActiveAttributeCount())); + + case GL_PROGRAM_OUTPUT: + return (index < static_cast(programObject->getOutputResourceCount())); + + case GL_UNIFORM: + return (index < static_cast(programObject->getActiveUniformCount())); + + case GL_BUFFER_VARIABLE: + return (index < static_cast(programObject->getActiveBufferVariableCount())); + + case GL_SHADER_STORAGE_BLOCK: + return (index < static_cast(programObject->getActiveShaderStorageBlockCount())); + + case GL_UNIFORM_BLOCK: + return (index < programObject->getActiveUniformBlockCount()); + + case GL_ATOMIC_COUNTER_BUFFER: + return (index < programObject->getActiveAtomicCounterBufferCount()); + + // TODO(jie.a.chen@intel.com): more interfaces. + case GL_TRANSFORM_FEEDBACK_VARYING: + UNIMPLEMENTED(); + return false; + + default: + UNREACHABLE(); + return false; + } +} + +bool ValidateProgramUniform(gl::Context *context, + GLenum valueType, + GLuint program, + GLint location, + GLsizei count) +{ + // Check for ES31 program uniform entry points + if (context->getClientVersion() < Version(3, 1)) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required); + return false; + } + + const LinkedUniform *uniform = nullptr; + gl::Program *programObject = GetValidProgram(context, program); + return ValidateUniformCommonBase(context, programObject, location, count, &uniform) && + ValidateUniformValue(context, valueType, uniform->type); +} + +bool ValidateProgramUniformMatrix(gl::Context *context, + GLenum valueType, + GLuint program, + GLint location, + GLsizei count, + GLboolean transpose) +{ + // Check for ES31 program uniform entry points + if (context->getClientVersion() < Version(3, 1)) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required); + return false; + } + + const LinkedUniform *uniform = nullptr; + gl::Program *programObject = GetValidProgram(context, program); + return ValidateUniformCommonBase(context, programObject, location, count, &uniform) && + ValidateUniformMatrixValue(context, valueType, uniform->type); +} + +bool ValidateVertexAttribFormatCommon(ValidationContext *context, + GLuint attribIndex, + GLint size, + GLenum type, + GLuint relativeOffset, + GLboolean pureInteger) +{ + if (context->getClientVersion() < ES_3_1) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required); + return false; + } + + const Caps &caps = context->getCaps(); + if (relativeOffset > static_cast(caps.maxVertexAttribRelativeOffset)) + { + context->handleError( + InvalidValue() + << "relativeOffset cannot be greater than MAX_VERTEX_ATTRIB_RELATIVE_OFFSET."); + return false; + } + + // [OpenGL ES 3.1] Section 10.3.1 page 243: + // An INVALID_OPERATION error is generated if the default vertex array object is bound. + if (context->getGLState().getVertexArrayId() == 0) + { + context->handleError(InvalidOperation() << "Default vertex array object is bound."); + return false; + } + + return ValidateVertexFormatBase(context, attribIndex, size, type, pureInteger); +} + +} // anonymous namespace + +bool ValidateGetBooleani_v(Context *context, GLenum target, GLuint index, GLboolean *data) +{ + if (context->getClientVersion() < ES_3_1) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required); + return false; + } + + if (!ValidateIndexedStateQuery(context, target, index, nullptr)) + { + return false; + } + + return true; +} + +bool ValidateGetBooleani_vRobustANGLE(Context *context, + GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLboolean *data) +{ + if (context->getClientVersion() < ES_3_1) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required); + return false; + } + + if (!ValidateRobustEntryPoint(context, bufSize)) + { + return false; + } + + if (!ValidateIndexedStateQuery(context, target, index, length)) + { + return false; + } + + if (!ValidateRobustBufferSize(context, bufSize, *length)) + { + return false; + } + + return true; +} + +bool ValidateDrawIndirectBase(Context *context, GLenum mode, const void *indirect) +{ + if (context->getClientVersion() < ES_3_1) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required); + return false; + } + + // Here the third parameter 1 is only to pass the count validation. + if (!ValidateDrawBase(context, mode, 1)) + { + return false; + } + + const State &state = context->getGLState(); + + // An INVALID_OPERATION error is generated if zero is bound to VERTEX_ARRAY_BINDING, + // DRAW_INDIRECT_BUFFER or to any enabled vertex array. + if (!state.getVertexArrayId()) + { + context->handleError(InvalidOperation() << "zero is bound to VERTEX_ARRAY_BINDING"); + return false; + } + + gl::Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect); + if (!drawIndirectBuffer) + { + context->handleError(InvalidOperation() << "zero is bound to DRAW_INDIRECT_BUFFER"); + return false; + } + + // An INVALID_VALUE error is generated if indirect is not a multiple of the size, in basic + // machine units, of uint. + GLint64 offset = reinterpret_cast(indirect); + if ((static_cast(offset) % sizeof(GLuint)) != 0) + { + context->handleError( + InvalidValue() + << "indirect is not a multiple of the size, in basic machine units, of uint"); + return false; + } + + // ANGLE_multiview spec, revision 1: + // An INVALID_OPERATION is generated by DrawArraysIndirect and DrawElementsIndirect if the + // number of views in the draw framebuffer is greater than 1. + const Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer(); + ASSERT(drawFramebuffer != nullptr); + if (drawFramebuffer->getNumViews() > 1) + { + context->handleError( + InvalidOperation() + << "The number of views in the active draw framebuffer is greater than 1."); + return false; + } + + return true; +} + +bool ValidateDrawArraysIndirect(Context *context, GLenum mode, const void *indirect) +{ + const State &state = context->getGLState(); + gl::TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback(); + if (curTransformFeedback && curTransformFeedback->isActive() && + !curTransformFeedback->isPaused()) + { + // An INVALID_OPERATION error is generated if transform feedback is active and not paused. + context->handleError(InvalidOperation() << "transform feedback is active and not paused."); + return false; + } + + if (!ValidateDrawIndirectBase(context, mode, indirect)) + return false; + + gl::Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect); + CheckedNumeric checkedOffset(reinterpret_cast(indirect)); + // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawArraysIndirectCommand + // which's size is 4 * sizeof(uint). + auto checkedSum = checkedOffset + 4 * sizeof(GLuint); + if (!checkedSum.IsValid() || + checkedSum.ValueOrDie() > static_cast(drawIndirectBuffer->getSize())) + { + context->handleError( + InvalidOperation() + << "the command would source data beyond the end of the buffer object."); + return false; + } + + return true; +} + +bool ValidateDrawElementsIndirect(Context *context, GLenum mode, GLenum type, const void *indirect) +{ + if (!ValidateDrawElementsBase(context, type)) + return false; + + const State &state = context->getGLState(); + const VertexArray *vao = state.getVertexArray(); + gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get(); + if (!elementArrayBuffer) + { + context->handleError(InvalidOperation() << "zero is bound to ELEMENT_ARRAY_BUFFER"); + return false; + } + + if (!ValidateDrawIndirectBase(context, mode, indirect)) + return false; + + gl::Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect); + CheckedNumeric checkedOffset(reinterpret_cast(indirect)); + // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawElementsIndirectCommand + // which's size is 5 * sizeof(uint). + auto checkedSum = checkedOffset + 5 * sizeof(GLuint); + if (!checkedSum.IsValid() || + checkedSum.ValueOrDie() > static_cast(drawIndirectBuffer->getSize())) + { + context->handleError( + InvalidOperation() + << "the command would source data beyond the end of the buffer object."); + return false; + } + + return true; +} + +bool ValidateProgramUniform1i(Context *context, GLuint program, GLint location, GLint v0) +{ + return ValidateProgramUniform1iv(context, program, location, 1, &v0); +} + +bool ValidateProgramUniform2i(Context *context, GLuint program, GLint location, GLint v0, GLint v1) +{ + GLint xy[2] = {v0, v1}; + return ValidateProgramUniform2iv(context, program, location, 1, xy); +} + +bool ValidateProgramUniform3i(Context *context, + GLuint program, + GLint location, + GLint v0, + GLint v1, + GLint v2) +{ + GLint xyz[3] = {v0, v1, v2}; + return ValidateProgramUniform3iv(context, program, location, 1, xyz); +} + +bool ValidateProgramUniform4i(Context *context, + GLuint program, + GLint location, + GLint v0, + GLint v1, + GLint v2, + GLint v3) +{ + GLint xyzw[4] = {v0, v1, v2, v3}; + return ValidateProgramUniform4iv(context, program, location, 1, xyzw); +} + +bool ValidateProgramUniform1ui(Context *context, GLuint program, GLint location, GLuint v0) +{ + return ValidateProgramUniform1uiv(context, program, location, 1, &v0); +} + +bool ValidateProgramUniform2ui(Context *context, + GLuint program, + GLint location, + GLuint v0, + GLuint v1) +{ + GLuint xy[2] = {v0, v1}; + return ValidateProgramUniform2uiv(context, program, location, 1, xy); +} + +bool ValidateProgramUniform3ui(Context *context, + GLuint program, + GLint location, + GLuint v0, + GLuint v1, + GLuint v2) +{ + GLuint xyz[3] = {v0, v1, v2}; + return ValidateProgramUniform3uiv(context, program, location, 1, xyz); +} + +bool ValidateProgramUniform4ui(Context *context, + GLuint program, + GLint location, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3) +{ + GLuint xyzw[4] = {v0, v1, v2, v3}; + return ValidateProgramUniform4uiv(context, program, location, 1, xyzw); +} + +bool ValidateProgramUniform1f(Context *context, GLuint program, GLint location, GLfloat v0) +{ + return ValidateProgramUniform1fv(context, program, location, 1, &v0); +} + +bool ValidateProgramUniform2f(Context *context, + GLuint program, + GLint location, + GLfloat v0, + GLfloat v1) +{ + GLfloat xy[2] = {v0, v1}; + return ValidateProgramUniform2fv(context, program, location, 1, xy); +} + +bool ValidateProgramUniform3f(Context *context, + GLuint program, + GLint location, + GLfloat v0, + GLfloat v1, + GLfloat v2) +{ + GLfloat xyz[3] = {v0, v1, v2}; + return ValidateProgramUniform3fv(context, program, location, 1, xyz); +} + +bool ValidateProgramUniform4f(Context *context, + GLuint program, + GLint location, + GLfloat v0, + GLfloat v1, + GLfloat v2, + GLfloat v3) +{ + GLfloat xyzw[4] = {v0, v1, v2, v3}; + return ValidateProgramUniform4fv(context, program, location, 1, xyzw); +} + +bool ValidateProgramUniform1iv(Context *context, + GLuint program, + GLint location, + GLsizei count, + const GLint *value) +{ + // Check for ES31 program uniform entry points + if (context->getClientVersion() < Version(3, 1)) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required); + return false; + } + + const LinkedUniform *uniform = nullptr; + gl::Program *programObject = GetValidProgram(context, program); + return ValidateUniformCommonBase(context, programObject, location, count, &uniform) && + ValidateUniform1ivValue(context, uniform->type, count, value); +} + +bool ValidateProgramUniform2iv(Context *context, + GLuint program, + GLint location, + GLsizei count, + const GLint *value) +{ + return ValidateProgramUniform(context, GL_INT_VEC2, program, location, count); +} + +bool ValidateProgramUniform3iv(Context *context, + GLuint program, + GLint location, + GLsizei count, + const GLint *value) +{ + return ValidateProgramUniform(context, GL_INT_VEC3, program, location, count); +} + +bool ValidateProgramUniform4iv(Context *context, + GLuint program, + GLint location, + GLsizei count, + const GLint *value) +{ + return ValidateProgramUniform(context, GL_INT_VEC4, program, location, count); +} + +bool ValidateProgramUniform1uiv(Context *context, + GLuint program, + GLint location, + GLsizei count, + const GLuint *value) +{ + return ValidateProgramUniform(context, GL_UNSIGNED_INT, program, location, count); +} + +bool ValidateProgramUniform2uiv(Context *context, + GLuint program, + GLint location, + GLsizei count, + const GLuint *value) +{ + return ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC2, program, location, count); +} + +bool ValidateProgramUniform3uiv(Context *context, + GLuint program, + GLint location, + GLsizei count, + const GLuint *value) +{ + return ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC3, program, location, count); +} + +bool ValidateProgramUniform4uiv(Context *context, + GLuint program, + GLint location, + GLsizei count, + const GLuint *value) +{ + return ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC4, program, location, count); +} + +bool ValidateProgramUniform1fv(Context *context, + GLuint program, + GLint location, + GLsizei count, + const GLfloat *value) +{ + return ValidateProgramUniform(context, GL_FLOAT, program, location, count); +} + +bool ValidateProgramUniform2fv(Context *context, + GLuint program, + GLint location, + GLsizei count, + const GLfloat *value) +{ + return ValidateProgramUniform(context, GL_FLOAT_VEC2, program, location, count); +} + +bool ValidateProgramUniform3fv(Context *context, + GLuint program, + GLint location, + GLsizei count, + const GLfloat *value) +{ + return ValidateProgramUniform(context, GL_FLOAT_VEC3, program, location, count); +} + +bool ValidateProgramUniform4fv(Context *context, + GLuint program, + GLint location, + GLsizei count, + const GLfloat *value) +{ + return ValidateProgramUniform(context, GL_FLOAT_VEC4, program, location, count); +} + +bool ValidateProgramUniformMatrix2fv(Context *context, + GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2, program, location, count, + transpose); +} + +bool ValidateProgramUniformMatrix3fv(Context *context, + GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3, program, location, count, + transpose); +} + +bool ValidateProgramUniformMatrix4fv(Context *context, + GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4, program, location, count, + transpose); +} + +bool ValidateProgramUniformMatrix2x3fv(Context *context, + GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2x3, program, location, count, + transpose); +} + +bool ValidateProgramUniformMatrix3x2fv(Context *context, + GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3x2, program, location, count, + transpose); +} + +bool ValidateProgramUniformMatrix2x4fv(Context *context, + GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2x4, program, location, count, + transpose); +} + +bool ValidateProgramUniformMatrix4x2fv(Context *context, + GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4x2, program, location, count, + transpose); +} + +bool ValidateProgramUniformMatrix3x4fv(Context *context, + GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3x4, program, location, count, + transpose); +} + +bool ValidateProgramUniformMatrix4x3fv(Context *context, + GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4x3, program, location, count, + transpose); +} + +bool ValidateGetTexLevelParameterBase(Context *context, + GLenum target, + GLint level, + GLenum pname, + GLsizei *length) +{ + if (context->getClientVersion() < ES_3_1) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required); + return false; + } + + if (length) + { + *length = 0; + } + + if (!ValidTexLevelDestinationTarget(context, target)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget); + return false; + } + + if (context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target) == + nullptr) + { + context->handleError(InvalidEnum() << "No texture bound."); + return false; + } + + if (!ValidMipLevel(context, target, level)) + { + context->handleError(InvalidValue()); + return false; + } + + switch (pname) + { + case GL_TEXTURE_RED_TYPE: + case GL_TEXTURE_GREEN_TYPE: + case GL_TEXTURE_BLUE_TYPE: + case GL_TEXTURE_ALPHA_TYPE: + case GL_TEXTURE_DEPTH_TYPE: + break; + case GL_TEXTURE_RED_SIZE: + case GL_TEXTURE_GREEN_SIZE: + case GL_TEXTURE_BLUE_SIZE: + case GL_TEXTURE_ALPHA_SIZE: + case GL_TEXTURE_DEPTH_SIZE: + case GL_TEXTURE_STENCIL_SIZE: + case GL_TEXTURE_SHARED_SIZE: + break; + case GL_TEXTURE_INTERNAL_FORMAT: + case GL_TEXTURE_WIDTH: + case GL_TEXTURE_HEIGHT: + case GL_TEXTURE_DEPTH: + break; + case GL_TEXTURE_SAMPLES: + case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS: + break; + case GL_TEXTURE_COMPRESSED: + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname); + return false; + } + + if (length) + { + *length = 1; + } + return true; +} + +bool ValidateGetTexLevelParameterfv(Context *context, + GLenum target, + GLint level, + GLenum pname, + GLfloat *params) +{ + return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr); +} + +bool ValidateGetTexLevelParameteriv(Context *context, + GLenum target, + GLint level, + GLenum pname, + GLint *params) +{ + return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr); +} + +bool ValidateTexStorage2DMultisample(Context *context, + GLenum target, + GLsizei samples, + GLint internalFormat, + GLsizei width, + GLsizei height, + GLboolean fixedSampleLocations) +{ + if (context->getClientVersion() < ES_3_1) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required); + return false; + } + + if (target != GL_TEXTURE_2D_MULTISAMPLE) + { + context->handleError(InvalidEnum() << "Target must be TEXTURE_2D_MULTISAMPLE."); + return false; + } + + if (width < 1 || height < 1) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize); + return false; + } + + const Caps &caps = context->getCaps(); + if (static_cast(width) > caps.max2DTextureSize || + static_cast(height) > caps.max2DTextureSize) + { + context + ->handleError(InvalidValue() + << "Width and height must be less than or equal to GL_MAX_TEXTURE_SIZE."); + return false; + } + + if (samples == 0) + { + context->handleError(InvalidValue() << "Samples may not be zero."); + return false; + } + + const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat); + if (!formatCaps.renderable) + { + context->handleError(InvalidEnum() << "SizedInternalformat must be color-renderable, " + "depth-renderable, or stencil-renderable."); + return false; + } + + // The ES3.1 spec(section 8.8) states that an INVALID_ENUM error is generated if internalformat + // is one of the unsized base internalformats listed in table 8.11. + const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat); + if (formatInfo.internalFormat == GL_NONE) + { + context->handleError( + InvalidEnum() + << "Internalformat is one of the unsupported unsized base internalformats."); + return false; + } + + if (static_cast(samples) > formatCaps.getMaxSamples()) + { + context->handleError( + InvalidOperation() + << "Samples must not be greater than maximum supported value for the format."); + return false; + } + + Texture *texture = context->getTargetTexture(target); + if (!texture || texture->id() == 0) + { + context->handleError(InvalidOperation() << "Zero is bound to target."); + return false; + } + + if (texture->getImmutableFormat()) + { + context->handleError(InvalidOperation() << "The value of TEXTURE_IMMUTABLE_FORMAT for " + "the texture currently bound to target on " + "the active texture unit is true."); + return false; + } + + return true; +} + +bool ValidateGetMultisamplefv(Context *context, GLenum pname, GLuint index, GLfloat *val) +{ + if (context->getClientVersion() < ES_3_1) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required); + return false; + } + + if (pname != GL_SAMPLE_POSITION) + { + context->handleError(InvalidEnum() << "Pname must be SAMPLE_POSITION."); + return false; + } + + Framebuffer *framebuffer = context->getGLState().getDrawFramebuffer(); + + if (index >= static_cast(framebuffer->getSamples(context))) + { + context->handleError(InvalidValue() << "Index must be less than the value of SAMPLES."); + return false; + } + + return true; +} + +bool ValidateFramebufferParameteri(Context *context, GLenum target, GLenum pname, GLint param) +{ + if (context->getClientVersion() < ES_3_1) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required); + return false; + } + + if (!ValidFramebufferTarget(context, target)) + { + context->handleError(InvalidEnum() << "Invalid framebuffer target."); + return false; + } + + switch (pname) + { + case GL_FRAMEBUFFER_DEFAULT_WIDTH: + { + GLint maxWidth = context->getCaps().maxFramebufferWidth; + if (param < 0 || param > maxWidth) + { + context->handleError( + InvalidValue() + << "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_WIDTH."); + return false; + } + break; + } + case GL_FRAMEBUFFER_DEFAULT_HEIGHT: + { + GLint maxHeight = context->getCaps().maxFramebufferHeight; + if (param < 0 || param > maxHeight) + { + context->handleError( + InvalidValue() + << "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_HEIGHT."); + return false; + } + break; + } + case GL_FRAMEBUFFER_DEFAULT_SAMPLES: + { + GLint maxSamples = context->getCaps().maxFramebufferSamples; + if (param < 0 || param > maxSamples) + { + context->handleError( + InvalidValue() + << "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_SAMPLES."); + return false; + } + break; + } + case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS: + { + break; + } + default: + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname); + return false; + } + } + + const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target); + ASSERT(framebuffer); + if (framebuffer->id() == 0) + { + context->handleError(InvalidOperation() << "Default framebuffer is bound to target."); + return false; + } + return true; +} + +bool ValidateGetFramebufferParameteriv(Context *context, GLenum target, GLenum pname, GLint *params) +{ + if (context->getClientVersion() < ES_3_1) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required); + return false; + } + + if (!ValidFramebufferTarget(context, target)) + { + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget); + return false; + } + + switch (pname) + { + case GL_FRAMEBUFFER_DEFAULT_WIDTH: + case GL_FRAMEBUFFER_DEFAULT_HEIGHT: + case GL_FRAMEBUFFER_DEFAULT_SAMPLES: + case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS: + break; + default: + ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname); + return false; + } + + const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target); + ASSERT(framebuffer); + + if (framebuffer->id() == 0) + { + context->handleError(InvalidOperation() << "Default framebuffer is bound to target."); + return false; + } + return true; +} + +bool ValidateGetProgramResourceIndex(Context *context, + GLuint program, + GLenum programInterface, + const GLchar *name) +{ + if (context->getClientVersion() < ES_3_1) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required); + return false; + } + + Program *programObject = GetValidProgram(context, program); + if (programObject == nullptr) + { + return false; + } + + if (!ValidateNamedProgramInterface(programInterface)) + { + context->handleError(InvalidEnum() << "Invalid program interface: 0x" << std::hex + << std::uppercase << programInterface); + return false; + } + + return true; +} + +bool ValidateBindVertexBuffer(ValidationContext *context, + GLuint bindingIndex, + GLuint buffer, + GLintptr offset, + GLsizei stride) +{ + if (context->getClientVersion() < ES_3_1) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required); + return false; + } + + if (!context->isBufferGenerated(buffer)) + { + context->handleError(InvalidOperation() << "Buffer is not generated."); + return false; + } + + const Caps &caps = context->getCaps(); + if (bindingIndex >= caps.maxVertexAttribBindings) + { + context->handleError(InvalidValue() + << "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS."); + return false; + } + + if (offset < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset); + return false; + } + + if (stride < 0 || stride > caps.maxVertexAttribStride) + { + context->handleError(InvalidValue() + << "stride must be between 0 and MAX_VERTEX_ATTRIB_STRIDE."); + return false; + } + + // [OpenGL ES 3.1] Section 10.3.1 page 244: + // An INVALID_OPERATION error is generated if the default vertex array object is bound. + if (context->getGLState().getVertexArrayId() == 0) + { + context->handleError(InvalidOperation() << "Default vertex array buffer is bound."); + return false; + } + + return true; +} + +bool ValidateVertexBindingDivisor(ValidationContext *context, GLuint bindingIndex, GLuint divisor) +{ + if (context->getClientVersion() < ES_3_1) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required); + return false; + } + + const Caps &caps = context->getCaps(); + if (bindingIndex >= caps.maxVertexAttribBindings) + { + context->handleError(InvalidValue() + << "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS."); + return false; + } + + // [OpenGL ES 3.1] Section 10.3.1 page 243: + // An INVALID_OPERATION error is generated if the default vertex array object is bound. + if (context->getGLState().getVertexArrayId() == 0) + { + context->handleError(InvalidOperation() << "Default vertex array object is bound."); + return false; + } + + return true; +} + +bool ValidateVertexAttribFormat(ValidationContext *context, + GLuint attribindex, + GLint size, + GLenum type, + GLboolean normalized, + GLuint relativeoffset) +{ + return ValidateVertexAttribFormatCommon(context, attribindex, size, type, relativeoffset, + false); +} + +bool ValidateVertexAttribIFormat(ValidationContext *context, + GLuint attribindex, + GLint size, + GLenum type, + GLuint relativeoffset) +{ + return ValidateVertexAttribFormatCommon(context, attribindex, size, type, relativeoffset, true); +} + +bool ValidateVertexAttribBinding(ValidationContext *context, + GLuint attribIndex, + GLuint bindingIndex) +{ + if (context->getClientVersion() < ES_3_1) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required); + return false; + } + + // [OpenGL ES 3.1] Section 10.3.1 page 243: + // An INVALID_OPERATION error is generated if the default vertex array object is bound. + if (context->getGLState().getVertexArrayId() == 0) + { + context->handleError(InvalidOperation() << "Default vertex array object is bound."); + return false; + } + + const Caps &caps = context->getCaps(); + if (attribIndex >= caps.maxVertexAttributes) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute); + return false; + } + + if (bindingIndex >= caps.maxVertexAttribBindings) + { + context->handleError(InvalidValue() + << "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS"); + return false; + } + + return true; +} + +bool ValidateGetProgramResourceName(Context *context, + GLuint program, + GLenum programInterface, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name) +{ + if (context->getClientVersion() < ES_3_1) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required); + return false; + } + + Program *programObject = GetValidProgram(context, program); + if (programObject == nullptr) + { + return false; + } + + if (!ValidateNamedProgramInterface(programInterface)) + { + context->handleError(InvalidEnum() << "Invalid program interface: 0x" << std::hex + << std::uppercase << programInterface); + return false; + } + + if (!ValidateProgramResourceIndex(programObject, programInterface, index)) + { + context->handleError(InvalidValue() << "Invalid index: " << index); + return false; + } + + if (bufSize < 0) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize); + return false; + } + + return true; +} + +bool ValidateDispatchCompute(Context *context, + GLuint numGroupsX, + GLuint numGroupsY, + GLuint numGroupsZ) +{ + if (context->getClientVersion() < ES_3_1) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required); + return false; + } + + const State &state = context->getGLState(); + Program *program = state.getProgram(); + + if (program == nullptr) + { + context->handleError(InvalidOperation() + << "No active program object for the compute shader stage."); + return false; + } + + if (!program->isLinked() || !program->hasLinkedComputeShader()) + { + context->handleError( + InvalidOperation() + << "Program has not been successfully linked, or program contains no compute shaders."); + return false; + } + + const Caps &caps = context->getCaps(); + if (numGroupsX > caps.maxComputeWorkGroupCount[0]) + { + context->handleError( + InvalidValue() << "num_groups_x cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[0]=" + << caps.maxComputeWorkGroupCount[0]); + return false; + } + if (numGroupsY > caps.maxComputeWorkGroupCount[1]) + { + context->handleError( + InvalidValue() << "num_groups_y cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[1]=" + << caps.maxComputeWorkGroupCount[1]); + return false; + } + if (numGroupsZ > caps.maxComputeWorkGroupCount[2]) + { + context->handleError( + InvalidValue() << "num_groups_z cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[2]=" + << caps.maxComputeWorkGroupCount[2]); + return false; + } + + return true; +} + +bool ValidateDispatchComputeIndirect(Context *context, GLintptr indirect) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateBindImageTexture(Context *context, + GLuint unit, + GLuint texture, + GLint level, + GLboolean layered, + GLint layer, + GLenum access, + GLenum format) +{ + GLuint maxImageUnits = context->getCaps().maxImageUnits; + if (unit >= maxImageUnits) + { + context->handleError(InvalidValue() + << "unit cannot be greater than or equal than MAX_IMAGE_UNITS = " + << maxImageUnits); + return false; + } + + if (level < 0) + { + context->handleError(InvalidValue() << "level is negative."); + return false; + } + + if (layer < 0) + { + context->handleError(InvalidValue() << "layer is negative."); + return false; + } + + if (access != GL_READ_ONLY && access != GL_WRITE_ONLY && access != GL_READ_WRITE) + { + context->handleError(InvalidEnum() << "access is not one of the supported tokens."); + return false; + } + + switch (format) + { + case GL_RGBA32F: + case GL_RGBA16F: + case GL_R32F: + case GL_RGBA32UI: + case GL_RGBA16UI: + case GL_RGBA8UI: + case GL_R32UI: + case GL_RGBA32I: + case GL_RGBA16I: + case GL_RGBA8I: + case GL_R32I: + case GL_RGBA8: + case GL_RGBA8_SNORM: + break; + default: + context->handleError(InvalidValue() + << "format is not one of supported image unit formats."); + return false; + } + + if (texture != 0) + { + Texture *tex = context->getTexture(texture); + + if (tex == nullptr) + { + context->handleError(InvalidValue() + << "texture is not the name of an existing texture object."); + return false; + } + + if (!tex->getImmutableFormat()) + { + context->handleError(InvalidOperation() + << "texture is not the name of an immutable texture object."); + return false; + } + } + + return true; +} + +bool ValidateGetProgramResourceLocation(Context *context, + GLuint program, + GLenum programInterface, + const GLchar *name) +{ + if (context->getClientVersion() < ES_3_1) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required); + return false; + } + + Program *programObject = GetValidProgram(context, program); + if (programObject == nullptr) + { + return false; + } + + if (!programObject->isLinked()) + { + context->handleError(InvalidOperation() << "Program is not successfully linked."); + return false; + } + + if (!ValidateLocationProgramInterface(programInterface)) + { + context->handleError(InvalidEnum() << "Invalid program interface."); + return false; + } + return true; +} + +bool ValidateGetProgramResourceiv(Context *context, + GLuint program, + GLenum programInterface, + GLuint index, + GLsizei propCount, + const GLenum *props, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + if (context->getClientVersion() < ES_3_1) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required); + return false; + } + + Program *programObject = GetValidProgram(context, program); + if (programObject == nullptr) + { + return false; + } + if (!ValidateProgramInterface(programInterface)) + { + context->handleError(InvalidEnum() << "Invalid program interface."); + return false; + } + if (propCount <= 0) + { + context->handleError(InvalidValue() << "Invalid propCount."); + return false; + } + if (bufSize < 0) + { + context->handleError(InvalidValue() << "Invalid bufSize."); + return false; + } + if (!ValidateProgramResourceIndex(programObject, programInterface, index)) + { + context->handleError(InvalidValue() << "Invalid index: " << index); + return false; + } + for (GLsizei i = 0; i < propCount; i++) + { + if (!ValidateProgramResourceProperty(props[i])) + { + context->handleError(InvalidEnum() << "Invalid prop."); + return false; + } + if (!ValidateProgramResourcePropertyByInterface(props[i], programInterface)) + { + context->handleError(InvalidOperation() << "Not an allowed prop for interface"); + return false; + } + } + return true; +} + +bool ValidateGetProgramInterfaceiv(Context *context, + GLuint program, + GLenum programInterface, + GLenum pname, + GLint *params) +{ + if (context->getClientVersion() < ES_3_1) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required); + return false; + } + + Program *programObject = GetValidProgram(context, program); + if (programObject == nullptr) + { + return false; + } + + if (!ValidateProgramInterface(programInterface)) + { + context->handleError(InvalidEnum() << "Invalid program interface."); + return false; + } + + switch (pname) + { + case GL_ACTIVE_RESOURCES: + case GL_MAX_NAME_LENGTH: + case GL_MAX_NUM_ACTIVE_VARIABLES: + break; + + default: + context->handleError(InvalidEnum() << "Unknown property of program interface."); + return false; + } + + if (pname == GL_MAX_NAME_LENGTH && programInterface == GL_ATOMIC_COUNTER_BUFFER) + { + context->handleError(InvalidOperation() + << "Active atomic counter resources are not assigned name strings."); + return false; + } + + if (pname == GL_MAX_NUM_ACTIVE_VARIABLES) + { + switch (programInterface) + { + case GL_ATOMIC_COUNTER_BUFFER: + case GL_SHADER_STORAGE_BLOCK: + case GL_UNIFORM_BLOCK: + break; + + default: + context->handleError( + InvalidOperation() + << "MAX_NUM_ACTIVE_VARIABLES requires a buffer or block interface."); + return false; + } + } + + return true; +} + +static bool ValidateGenOrDeleteES31(Context *context, GLint n) +{ + if (context->getClientVersion() < ES_3_1) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required); + return false; + } + + return ValidateGenOrDelete(context, n); +} + +bool ValidateGenProgramPipelines(Context *context, GLint n, GLuint *) +{ + return ValidateGenOrDeleteES31(context, n); +} + +bool ValidateDeleteProgramPipelines(Context *context, GLint n, const GLuint *) +{ + return ValidateGenOrDeleteES31(context, n); +} + +bool ValidateBindProgramPipeline(Context *context, GLuint pipeline) +{ + if (context->getClientVersion() < ES_3_1) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required); + return false; + } + + if (!context->isProgramPipelineGenerated(pipeline)) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated); + return false; + } + + return true; +} + +bool ValidateIsProgramPipeline(Context *context, GLuint pipeline) +{ + if (context->getClientVersion() < ES_3_1) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required); + return false; + } + + return true; +} + +bool ValidateUseProgramStages(Context *context, GLuint pipeline, GLbitfield stages, GLuint program) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateActiveShaderProgram(Context *context, GLuint pipeline, GLuint program) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateCreateShaderProgramv(Context *context, + GLenum type, + GLsizei count, + const GLchar *const *strings) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateGetProgramPipelineiv(Context *context, GLuint pipeline, GLenum pname, GLint *params) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateValidateProgramPipeline(Context *context, GLuint pipeline) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateGetProgramPipelineInfoLog(Context *context, + GLuint pipeline, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateMemoryBarrier(Context *context, GLbitfield barriers) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateMemoryBarrierByRegion(Context *context, GLbitfield barriers) +{ + UNIMPLEMENTED(); + return false; +} + +bool ValidateSampleMaski(Context *context, GLuint maskNumber, GLbitfield mask) +{ + if (context->getClientVersion() < ES_3_1) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required); + return false; + } + + if (maskNumber >= context->getCaps().maxSampleMaskWords) + { + ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidSampleMaskNumber); + return false; + } + + return true; +} + +} // namespace gl diff --git a/src/3rdparty/angle/src/libANGLE/validationES31.h b/src/3rdparty/angle/src/libANGLE/validationES31.h new file mode 100644 index 0000000000..a0b76a5bcb --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/validationES31.h @@ -0,0 +1,325 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// validationES31.h: Validation functions for OpenGL ES 3.1 entry point parameters + +#ifndef LIBANGLE_VALIDATION_ES31_H_ +#define LIBANGLE_VALIDATION_ES31_H_ + +#include + +namespace gl +{ +class Context; +class ValidationContext; + +bool ValidateGetBooleani_v(Context *context, GLenum target, GLuint index, GLboolean *data); +bool ValidateGetBooleani_vRobustANGLE(Context *context, + GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLboolean *data); + +bool ValidateGetTexLevelParameterfv(Context *context, + GLenum target, + GLint level, + GLenum pname, + GLfloat *params); +bool ValidateGetTexLevelParameteriv(Context *context, + GLenum target, + GLint level, + GLenum pname, + GLint *param); + +bool ValidateTexStorage2DMultisample(Context *context, + GLenum target, + GLsizei samples, + GLint internalFormat, + GLsizei width, + GLsizei height, + GLboolean fixedSampleLocations); +bool ValidateGetMultisamplefv(Context *context, GLenum pname, GLuint index, GLfloat *val); + +bool ValidateDrawIndirectBase(Context *context, GLenum mode, const void *indirect); +bool ValidateDrawArraysIndirect(Context *context, GLenum mode, const void *indirect); +bool ValidateDrawElementsIndirect(Context *context, GLenum mode, GLenum type, const void *indirect); + +bool ValidateProgramUniform1i(Context *context, GLuint program, GLint location, GLint v0); +bool ValidateProgramUniform2i(Context *context, GLuint program, GLint location, GLint v0, GLint v1); +bool ValidateProgramUniform3i(Context *context, + GLuint program, + GLint location, + GLint v0, + GLint v1, + GLint v2); +bool ValidateProgramUniform4i(Context *context, + GLuint program, + GLint location, + GLint v0, + GLint v1, + GLint v2, + GLint v3); +bool ValidateProgramUniform1ui(Context *context, GLuint program, GLint location, GLuint v0); +bool ValidateProgramUniform2ui(Context *context, + GLuint program, + GLint location, + GLuint v0, + GLuint v1); +bool ValidateProgramUniform3ui(Context *context, + GLuint program, + GLint location, + GLuint v0, + GLuint v1, + GLuint v2); +bool ValidateProgramUniform4ui(Context *context, + GLuint program, + GLint location, + GLuint v0, + GLuint v1, + GLuint v2, + GLuint v3); +bool ValidateProgramUniform1f(Context *context, GLuint program, GLint location, GLfloat v0); +bool ValidateProgramUniform2f(Context *context, + GLuint program, + GLint location, + GLfloat v0, + GLfloat v1); +bool ValidateProgramUniform3f(Context *context, + GLuint program, + GLint location, + GLfloat v0, + GLfloat v1, + GLfloat v2); +bool ValidateProgramUniform4f(Context *context, + GLuint program, + GLint location, + GLfloat v0, + GLfloat v1, + GLfloat v2, + GLfloat v3); + +bool ValidateProgramUniform1iv(Context *context, + GLuint program, + GLint location, + GLsizei count, + const GLint *value); +bool ValidateProgramUniform2iv(Context *context, + GLuint program, + GLint location, + GLsizei count, + const GLint *value); +bool ValidateProgramUniform3iv(Context *context, + GLuint program, + GLint location, + GLsizei count, + const GLint *value); +bool ValidateProgramUniform4iv(Context *context, + GLuint program, + GLint location, + GLsizei count, + const GLint *value); +bool ValidateProgramUniform1uiv(Context *context, + GLuint program, + GLint location, + GLsizei count, + const GLuint *value); +bool ValidateProgramUniform2uiv(Context *context, + GLuint program, + GLint location, + GLsizei count, + const GLuint *value); +bool ValidateProgramUniform3uiv(Context *context, + GLuint program, + GLint location, + GLsizei count, + const GLuint *value); +bool ValidateProgramUniform4uiv(Context *context, + GLuint program, + GLint location, + GLsizei count, + const GLuint *value); +bool ValidateProgramUniform1fv(Context *context, + GLuint program, + GLint location, + GLsizei count, + const GLfloat *value); +bool ValidateProgramUniform2fv(Context *context, + GLuint program, + GLint location, + GLsizei count, + const GLfloat *value); +bool ValidateProgramUniform3fv(Context *context, + GLuint program, + GLint location, + GLsizei count, + const GLfloat *value); +bool ValidateProgramUniform4fv(Context *context, + GLuint program, + GLint location, + GLsizei count, + const GLfloat *value); +bool ValidateProgramUniformMatrix2fv(Context *context, + GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix2fv(Context *context, + GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix3fv(Context *context, + GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix4fv(Context *context, + GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix2x3fv(Context *context, + GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix3x2fv(Context *context, + GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix2x4fv(Context *context, + GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix4x2fv(Context *context, + GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix3x4fv(Context *context, + GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +bool ValidateProgramUniformMatrix4x3fv(Context *context, + GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); + +bool ValidateFramebufferParameteri(Context *context, GLenum target, GLenum pname, GLint param); +bool ValidateGetFramebufferParameteriv(Context *context, + GLenum target, + GLenum pname, + GLint *params); + +bool ValidateGetProgramResourceIndex(Context *context, + GLuint program, + GLenum programInterface, + const GLchar *name); +bool ValidateGetProgramResourceName(Context *context, + GLuint program, + GLenum programInterface, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name); +bool ValidateGetProgramResourceLocation(Context *context, + GLuint program, + GLenum programInterface, + const GLchar *name); + +bool ValidateGetProgramResourceiv(Context *context, + GLuint program, + GLenum programInterface, + GLuint index, + GLsizei propCount, + const GLenum *props, + GLsizei bufSize, + GLsizei *length, + GLint *params); + +bool ValidateGetProgramInterfaceiv(Context *context, + GLuint program, + GLenum programInterface, + GLenum pname, + GLint *params); + +bool ValidateBindVertexBuffer(ValidationContext *context, + GLuint bindingIndex, + GLuint buffer, + GLintptr offset, + GLsizei stride); +bool ValidateVertexAttribFormat(ValidationContext *context, + GLuint attribindex, + GLint size, + GLenum type, + GLboolean normalized, + GLuint relativeoffset); +bool ValidateVertexAttribIFormat(ValidationContext *context, + GLuint attribindex, + GLint size, + GLenum type, + GLuint relativeoffset); +bool ValidateVertexAttribBinding(ValidationContext *context, + GLuint attribIndex, + GLuint bindingIndex); +bool ValidateVertexBindingDivisor(ValidationContext *context, GLuint bindingIndex, GLuint divisor); + +bool ValidateDispatchCompute(Context *context, + GLuint numGroupsX, + GLuint numGroupsY, + GLuint numGroupsZ); +bool ValidateDispatchComputeIndirect(Context *context, GLintptr indirect); + +bool ValidateBindImageTexture(Context *context, + GLuint unit, + GLuint texture, + GLint level, + GLboolean layered, + GLint layer, + GLenum access, + GLenum format); + +bool ValidateGenProgramPipelines(Context *context, GLint n, GLuint *pipelines); +bool ValidateDeleteProgramPipelines(Context *context, GLint n, const GLuint *pipelines); +bool ValidateBindProgramPipeline(Context *context, GLuint pipeline); +bool ValidateIsProgramPipeline(Context *context, GLuint pipeline); +bool ValidateUseProgramStages(Context *context, GLuint pipeline, GLbitfield stages, GLuint program); +bool ValidateActiveShaderProgram(Context *context, GLuint pipeline, GLuint program); +bool ValidateCreateShaderProgramv(Context *context, + GLenum type, + GLsizei count, + const GLchar *const *strings); +bool ValidateGetProgramPipelineiv(Context *context, GLuint pipeline, GLenum pname, GLint *params); +bool ValidateValidateProgramPipeline(Context *context, GLuint pipeline); +bool ValidateGetProgramPipelineInfoLog(Context *context, + GLuint pipeline, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog); + +bool ValidateMemoryBarrier(Context *context, GLbitfield barriers); +bool ValidateMemoryBarrierByRegion(Context *context, GLbitfield barriers); + +bool ValidateSampleMaski(Context *context, GLuint maskNumber, GLbitfield mask); + +} // namespace gl + +#endif // LIBANGLE_VALIDATION_ES31_H_ diff --git a/src/3rdparty/angle/src/libEGL/libEGL.cpp b/src/3rdparty/angle/src/libEGL/libEGL.cpp index f28f40fcf5..efe0b0c124 100644 --- a/src/3rdparty/angle/src/libEGL/libEGL.cpp +++ b/src/3rdparty/angle/src/libEGL/libEGL.cpp @@ -288,4 +288,121 @@ __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const cha return egl::GetProcAddress(procname); } +EGLStreamKHR EGLAPIENTRY eglCreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_list) +{ + return egl::CreateStreamKHR(dpy, attrib_list); } + +EGLBoolean EGLAPIENTRY eglDestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream) +{ + return egl::DestroyStreamKHR(dpy, stream); +} + +EGLBoolean EGLAPIENTRY eglStreamAttribKHR(EGLDisplay dpy, + EGLStreamKHR stream, + EGLenum attribute, + EGLint value) +{ + return egl::StreamAttribKHR(dpy, stream, attribute, value); +} + +EGLBoolean EGLAPIENTRY eglQueryStreamKHR(EGLDisplay dpy, + EGLStreamKHR stream, + EGLenum attribute, + EGLint *value) +{ + return egl::QueryStreamKHR(dpy, stream, attribute, value); +} + +EGLBoolean EGLAPIENTRY eglQueryStreamu64KHR(EGLDisplay dpy, + EGLStreamKHR stream, + EGLenum attribute, + EGLuint64KHR *value) +{ + return egl::QueryStreamu64KHR(dpy, stream, attribute, value); +} + +EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalKHR(EGLDisplay dpy, EGLStreamKHR stream) +{ + return egl::StreamConsumerGLTextureExternalKHR(dpy, stream); +} + +EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireKHR(EGLDisplay dpy, EGLStreamKHR stream) +{ + return egl::StreamConsumerAcquireKHR(dpy, stream); +} + +EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseKHR(EGLDisplay dpy, EGLStreamKHR stream) +{ + return egl::StreamConsumerReleaseKHR(dpy, stream); +} + +EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalAttribsNV(EGLDisplay dpy, + EGLStreamKHR stream, + EGLAttrib *attrib_list) +{ + return egl::StreamConsumerGLTextureExternalAttribsNV(dpy, stream, attrib_list); +} + +EGLBoolean EGLAPIENTRY eglCreateStreamProducerD3DTextureNV12ANGLE(EGLDisplay dpy, + EGLStreamKHR stream, + const EGLAttrib *attrib_list) +{ + return egl::CreateStreamProducerD3DTextureNV12ANGLE(dpy, stream, attrib_list); +} + +EGLBoolean EGLAPIENTRY eglStreamPostD3DTextureNV12ANGLE(EGLDisplay dpy, + EGLStreamKHR stream, + void *texture, + const EGLAttrib *attrib_list) +{ + return egl::StreamPostD3DTextureNV12ANGLE(dpy, stream, texture, attrib_list); +} + +EGLBoolean EGLAPIENTRY eglGetSyncValuesCHROMIUM(EGLDisplay dpy, + EGLSurface surface, + EGLuint64KHR *ust, + EGLuint64KHR *msc, + EGLuint64KHR *sbc) +{ + return egl::GetSyncValuesCHROMIUM(dpy, surface, ust, msc, sbc); +} + +EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT(EGLDisplay dpy, + EGLSurface surface, + EGLint *rects, + EGLint n_rects) +{ + return egl::SwapBuffersWithDamageEXT(dpy, surface, rects, n_rects); +} + +EGLint EGLAPIENTRY eglProgramCacheGetAttribANGLE(EGLDisplay dpy, EGLenum attrib) +{ + return egl::ProgramCacheGetAttribANGLE(dpy, attrib); +} + +void EGLAPIENTRY eglProgramCacheQueryANGLE(EGLDisplay dpy, + EGLint index, + void *key, + EGLint *keysize, + void *binary, + EGLint *binarysize) +{ + egl::ProgramCacheQueryANGLE(dpy, index, key, keysize, binary, binarysize); +} + +void EGLAPIENTRY eglProgramCachePopulateANGLE(EGLDisplay dpy, + const void *key, + EGLint keysize, + const void *binary, + EGLint binarysize) +{ + egl::ProgramCachePopulateANGLE(dpy, key, keysize, binary, binarysize); +} + +EGLint EGLAPIENTRY eglProgramCacheResizeANGLE(EGLDisplay dpy, EGLint limit, EGLenum mode) +{ + return egl::ProgramCacheResizeANGLE(dpy, limit, mode); +} + +} // extern "C" diff --git a/src/3rdparty/angle/src/libEGL/libEGL.def b/src/3rdparty/angle/src/libEGL/libEGL.def index 74b7c2ae14..e68d27295e 100644 --- a/src/3rdparty/angle/src/libEGL/libEGL.def +++ b/src/3rdparty/angle/src/libEGL/libEGL.def @@ -1,60 +1,77 @@ LIBRARY libEGL EXPORTS - eglBindAPI @14 - eglBindTexImage @20 - eglChooseConfig @7 - eglCopyBuffers @33 - eglCreateContext @23 - eglCreatePbufferFromClientBuffer @18 - eglCreatePbufferSurface @10 - eglCreatePixmapSurface @11 - eglCreateWindowSurface @9 - eglDestroyContext @24 - eglDestroySurface @12 - eglGetConfigAttrib @8 - eglGetConfigs @6 - eglGetCurrentContext @26 - eglGetCurrentDisplay @28 - eglGetCurrentSurface @27 - eglGetDisplay @2 - eglGetError @1 - eglGetProcAddress @34 - eglInitialize @3 - eglMakeCurrent @25 - eglQueryAPI @15 - eglQueryContext @29 - eglQueryString @5 - eglQuerySurface @13 - eglReleaseTexImage @21 - eglReleaseThread @17 - eglSurfaceAttrib @19 - eglSwapBuffers @32 - eglSwapInterval @22 - eglTerminate @4 - eglWaitClient @16 - eglWaitGL @30 - eglWaitNative @31 + eglBindAPI @14 + eglBindTexImage @20 + eglChooseConfig @7 + eglCopyBuffers @33 + eglCreateContext @23 + eglCreatePbufferFromClientBuffer @18 + eglCreatePbufferSurface @10 + eglCreatePixmapSurface @11 + eglCreateWindowSurface @9 + eglDestroyContext @24 + eglDestroySurface @12 + eglGetConfigAttrib @8 + eglGetConfigs @6 + eglGetCurrentContext @26 + eglGetCurrentDisplay @28 + eglGetCurrentSurface @27 + eglGetDisplay @2 + eglGetError @1 + eglGetProcAddress @34 + eglInitialize @3 + eglMakeCurrent @25 + eglQueryAPI @15 + eglQueryContext @29 + eglQueryString @5 + eglQuerySurface @13 + eglReleaseTexImage @21 + eglReleaseThread @17 + eglSurfaceAttrib @19 + eglSwapBuffers @32 + eglSwapInterval @22 + eglTerminate @4 + eglWaitClient @16 + eglWaitGL @30 + eglWaitNative @31 ; Extensions - eglGetPlatformDisplayEXT @35 - eglQuerySurfacePointerANGLE @36 - eglPostSubBufferNV @37 - eglQueryDisplayAttribEXT @48 - eglQueryDeviceAttribEXT @49 - eglQueryDeviceStringEXT @50 - eglCreateImageKHR @51 - eglDestroyImageKHR @52 - eglCreateDeviceANGLE @53 - eglReleaseDeviceANGLE @54 + eglGetPlatformDisplayEXT @35 + eglQuerySurfacePointerANGLE @36 + eglPostSubBufferNV @37 + eglQueryDisplayAttribEXT @48 + eglQueryDeviceAttribEXT @49 + eglQueryDeviceStringEXT @50 + eglCreateImageKHR @51 + eglDestroyImageKHR @52 + eglCreateDeviceANGLE @53 + eglReleaseDeviceANGLE @54 + eglCreateStreamKHR @55 + eglDestroyStreamKHR @56 + eglStreamAttribKHR @57 + eglQueryStreamKHR @58 + eglQueryStreamu64KHR @59 + eglStreamConsumerGLTextureExternalKHR @60 + eglStreamConsumerAcquireKHR @61 + eglStreamConsumerReleaseKHR @62 + eglStreamConsumerGLTextureExternalAttribsNV @63 + eglCreateStreamProducerD3DTextureNV12ANGLE @64 + eglStreamPostD3DTextureNV12ANGLE @65 + eglGetSyncValuesCHROMIUM @66 + eglSwapBuffersWithDamageEXT @67 + eglProgramCacheGetAttribANGLE @68 + eglProgramCachePopulateANGLE @69 + eglProgramCacheQueryANGLE @70 + eglProgramCacheResizeANGLE @71 ; 1.5 entry points - eglCreateSync @38 - eglDestroySync @39 - eglClientWaitSync @40 - eglGetSyncAttrib @41 - eglCreateImage @42 - eglDestroyImage @43 - eglGetPlatformDisplay @44 - eglCreatePlatformWindowSurface @45 - eglCreatePlatformPixmapSurface @46 - eglWaitSync @47 + eglCreateSync @38 + eglDestroySync @39 + eglClientWaitSync @40 + eglGetSyncAttrib @41 + eglCreateImage @42 + eglDestroyImage @43 + eglGetPlatformDisplay @44 + eglCreatePlatformWindowSurface @45 + eglCreatePlatformPixmapSurface @46 + eglWaitSync @47 diff --git a/src/3rdparty/angle/src/libEGL/libEGL_mingw32.def b/src/3rdparty/angle/src/libEGL/libEGL_mingw32.def index d8fcf51620..e68d27295e 100644 --- a/src/3rdparty/angle/src/libEGL/libEGL_mingw32.def +++ b/src/3rdparty/angle/src/libEGL/libEGL_mingw32.def @@ -1,60 +1,77 @@ LIBRARY libEGL EXPORTS - eglBindAPI@4 @14 - eglBindTexImage@12 @20 - eglChooseConfig@20 @7 - eglCopyBuffers@12 @33 - eglCreateContext@16 @23 - eglCreatePbufferFromClientBuffer@20 @18 - eglCreatePbufferSurface@12 @10 - eglCreatePixmapSurface@16 @11 - eglCreateWindowSurface@16 @9 - eglDestroyContext@8 @24 - eglDestroySurface@8 @12 - eglGetConfigAttrib@16 @8 - eglGetConfigs@16 @6 - eglGetCurrentContext@0 @26 - eglGetCurrentDisplay@0 @28 - eglGetCurrentSurface@4 @27 - eglGetDisplay@4 @2 - eglGetError@0 @1 - eglGetProcAddress@4 @34 - eglInitialize@12 @3 - eglMakeCurrent@16 @25 - eglQueryAPI@0 @15 - eglQueryContext@16 @29 - eglQueryString@8 @5 - eglQuerySurface@16 @13 - eglReleaseTexImage@12 @21 - eglReleaseThread@0 @17 - eglSurfaceAttrib@16 @19 - eglSwapBuffers@8 @32 - eglSwapInterval@8 @22 - eglTerminate@4 @4 - eglWaitClient@0 @16 - eglWaitGL@0 @30 - eglWaitNative@4 @31 + eglBindAPI @14 + eglBindTexImage @20 + eglChooseConfig @7 + eglCopyBuffers @33 + eglCreateContext @23 + eglCreatePbufferFromClientBuffer @18 + eglCreatePbufferSurface @10 + eglCreatePixmapSurface @11 + eglCreateWindowSurface @9 + eglDestroyContext @24 + eglDestroySurface @12 + eglGetConfigAttrib @8 + eglGetConfigs @6 + eglGetCurrentContext @26 + eglGetCurrentDisplay @28 + eglGetCurrentSurface @27 + eglGetDisplay @2 + eglGetError @1 + eglGetProcAddress @34 + eglInitialize @3 + eglMakeCurrent @25 + eglQueryAPI @15 + eglQueryContext @29 + eglQueryString @5 + eglQuerySurface @13 + eglReleaseTexImage @21 + eglReleaseThread @17 + eglSurfaceAttrib @19 + eglSwapBuffers @32 + eglSwapInterval @22 + eglTerminate @4 + eglWaitClient @16 + eglWaitGL @30 + eglWaitNative @31 ; Extensions - eglGetPlatformDisplayEXT@12 @35 - eglQuerySurfacePointerANGLE@16 @36 - eglPostSubBufferNV@24 @37 - eglQueryDisplayAttribEXT@12 @48 - eglQueryDeviceAttribEXT@12 @49 - eglQueryDeviceStringEXT@8 @50 - eglCreateImageKHR@20 @51 - eglDestroyImageKHR@8 @52 - eglCreateDeviceANGLE@12 @53 - eglReleaseDeviceANGLE@4 @54 + eglGetPlatformDisplayEXT @35 + eglQuerySurfacePointerANGLE @36 + eglPostSubBufferNV @37 + eglQueryDisplayAttribEXT @48 + eglQueryDeviceAttribEXT @49 + eglQueryDeviceStringEXT @50 + eglCreateImageKHR @51 + eglDestroyImageKHR @52 + eglCreateDeviceANGLE @53 + eglReleaseDeviceANGLE @54 + eglCreateStreamKHR @55 + eglDestroyStreamKHR @56 + eglStreamAttribKHR @57 + eglQueryStreamKHR @58 + eglQueryStreamu64KHR @59 + eglStreamConsumerGLTextureExternalKHR @60 + eglStreamConsumerAcquireKHR @61 + eglStreamConsumerReleaseKHR @62 + eglStreamConsumerGLTextureExternalAttribsNV @63 + eglCreateStreamProducerD3DTextureNV12ANGLE @64 + eglStreamPostD3DTextureNV12ANGLE @65 + eglGetSyncValuesCHROMIUM @66 + eglSwapBuffersWithDamageEXT @67 + eglProgramCacheGetAttribANGLE @68 + eglProgramCachePopulateANGLE @69 + eglProgramCacheQueryANGLE @70 + eglProgramCacheResizeANGLE @71 ; 1.5 entry points - eglCreateSync @38 - eglDestroySync @39 - eglClientWaitSync @40 - eglGetSyncAttrib @41 - eglCreateImage @42 - eglDestroyImage @43 - eglGetPlatformDisplay @44 - eglCreatePlatformWindowSurface @45 - eglCreatePlatformPixmapSurface @46 - eglWaitSync @47 + eglCreateSync @38 + eglDestroySync @39 + eglClientWaitSync @40 + eglGetSyncAttrib @41 + eglCreateImage @42 + eglDestroyImage @43 + eglGetPlatformDisplay @44 + eglCreatePlatformWindowSurface @45 + eglCreatePlatformPixmapSurface @46 + eglWaitSync @47 diff --git a/src/3rdparty/angle/src/libEGL/libEGLd.def b/src/3rdparty/angle/src/libEGL/libEGLd.def index 318e04cfa6..e6a8b1bac7 100644 --- a/src/3rdparty/angle/src/libEGL/libEGLd.def +++ b/src/3rdparty/angle/src/libEGL/libEGLd.def @@ -1,60 +1,77 @@ LIBRARY libEGLd EXPORTS - eglBindAPI @14 - eglBindTexImage @20 - eglChooseConfig @7 - eglCopyBuffers @33 - eglCreateContext @23 - eglCreatePbufferFromClientBuffer @18 - eglCreatePbufferSurface @10 - eglCreatePixmapSurface @11 - eglCreateWindowSurface @9 - eglDestroyContext @24 - eglDestroySurface @12 - eglGetConfigAttrib @8 - eglGetConfigs @6 - eglGetCurrentContext @26 - eglGetCurrentDisplay @28 - eglGetCurrentSurface @27 - eglGetDisplay @2 - eglGetError @1 - eglGetProcAddress @34 - eglInitialize @3 - eglMakeCurrent @25 - eglQueryAPI @15 - eglQueryContext @29 - eglQueryString @5 - eglQuerySurface @13 - eglReleaseTexImage @21 - eglReleaseThread @17 - eglSurfaceAttrib @19 - eglSwapBuffers @32 - eglSwapInterval @22 - eglTerminate @4 - eglWaitClient @16 - eglWaitGL @30 - eglWaitNative @31 + eglBindAPI @14 + eglBindTexImage @20 + eglChooseConfig @7 + eglCopyBuffers @33 + eglCreateContext @23 + eglCreatePbufferFromClientBuffer @18 + eglCreatePbufferSurface @10 + eglCreatePixmapSurface @11 + eglCreateWindowSurface @9 + eglDestroyContext @24 + eglDestroySurface @12 + eglGetConfigAttrib @8 + eglGetConfigs @6 + eglGetCurrentContext @26 + eglGetCurrentDisplay @28 + eglGetCurrentSurface @27 + eglGetDisplay @2 + eglGetError @1 + eglGetProcAddress @34 + eglInitialize @3 + eglMakeCurrent @25 + eglQueryAPI @15 + eglQueryContext @29 + eglQueryString @5 + eglQuerySurface @13 + eglReleaseTexImage @21 + eglReleaseThread @17 + eglSurfaceAttrib @19 + eglSwapBuffers @32 + eglSwapInterval @22 + eglTerminate @4 + eglWaitClient @16 + eglWaitGL @30 + eglWaitNative @31 ; Extensions - eglGetPlatformDisplayEXT @35 - eglQuerySurfacePointerANGLE @36 - eglPostSubBufferNV @37 - eglQueryDisplayAttribEXT @48 - eglQueryDeviceAttribEXT @49 - eglQueryDeviceStringEXT @50 - eglCreateImageKHR @51 - eglDestroyImageKHR @52 - eglCreateDeviceANGLE @53 - eglReleaseDeviceANGLE @54 + eglGetPlatformDisplayEXT @35 + eglQuerySurfacePointerANGLE @36 + eglPostSubBufferNV @37 + eglQueryDisplayAttribEXT @48 + eglQueryDeviceAttribEXT @49 + eglQueryDeviceStringEXT @50 + eglCreateImageKHR @51 + eglDestroyImageKHR @52 + eglCreateDeviceANGLE @53 + eglReleaseDeviceANGLE @54 + eglCreateStreamKHR @55 + eglDestroyStreamKHR @56 + eglStreamAttribKHR @57 + eglQueryStreamKHR @58 + eglQueryStreamu64KHR @59 + eglStreamConsumerGLTextureExternalKHR @60 + eglStreamConsumerAcquireKHR @61 + eglStreamConsumerReleaseKHR @62 + eglStreamConsumerGLTextureExternalAttribsNV @63 + eglCreateStreamProducerD3DTextureNV12ANGLE @64 + eglStreamPostD3DTextureNV12ANGLE @65 + eglGetSyncValuesCHROMIUM @66 + eglSwapBuffersWithDamageEXT @67 + eglProgramCacheGetAttribANGLE @68 + eglProgramCachePopulateANGLE @69 + eglProgramCacheQueryANGLE @70 + eglProgramCacheResizeANGLE @71 ; 1.5 entry points - eglCreateSync @38 - eglDestroySync @39 - eglClientWaitSync @40 - eglGetSyncAttrib @41 - eglCreateImage @42 - eglDestroyImage @43 - eglGetPlatformDisplay @44 - eglCreatePlatformWindowSurface @45 - eglCreatePlatformPixmapSurface @46 - eglWaitSync @47 + eglCreateSync @38 + eglDestroySync @39 + eglClientWaitSync @40 + eglGetSyncAttrib @41 + eglCreateImage @42 + eglDestroyImage @43 + eglGetPlatformDisplay @44 + eglCreatePlatformWindowSurface @45 + eglCreatePlatformPixmapSurface @46 + eglWaitSync @47 diff --git a/src/3rdparty/angle/src/libEGL/libEGLd_mingw32.def b/src/3rdparty/angle/src/libEGL/libEGLd_mingw32.def deleted file mode 100644 index d322cf67de..0000000000 --- a/src/3rdparty/angle/src/libEGL/libEGLd_mingw32.def +++ /dev/null @@ -1,48 +0,0 @@ -LIBRARY libEGLd -EXPORTS - eglBindAPI@4 @14 - eglBindTexImage@12 @20 - eglChooseConfig@20 @7 - eglCopyBuffers@12 @33 - eglCreateContext@16 @23 - eglCreatePbufferFromClientBuffer@20 @18 - eglCreatePbufferSurface@12 @10 - eglCreatePixmapSurface@16 @11 - eglCreateWindowSurface@16 @9 - eglDestroyContext@8 @24 - eglDestroySurface@8 @12 - eglGetConfigAttrib@16 @8 - eglGetConfigs@16 @6 - eglGetCurrentContext@0 @26 - eglGetCurrentDisplay@0 @28 - eglGetCurrentSurface@4 @27 - eglGetDisplay@4 @2 - eglGetError@0 @1 - eglGetProcAddress@4 @34 - eglInitialize@12 @3 - eglMakeCurrent@16 @25 - eglQueryAPI@0 @15 - eglQueryContext@16 @29 - eglQueryString@8 @5 - eglQuerySurface@16 @13 - eglReleaseTexImage@12 @21 - eglReleaseThread@0 @17 - eglSurfaceAttrib@16 @19 - eglSwapBuffers@8 @32 - eglSwapInterval@8 @22 - eglTerminate@4 @4 - eglWaitClient@0 @16 - eglWaitGL@0 @30 - eglWaitNative@4 @31 - - ; Extensions - eglGetPlatformDisplayEXT@12 @35 - eglQuerySurfacePointerANGLE@16 @36 - eglPostSubBufferNV@24 @37 - eglQueryDisplayAttribEXT@12 @48 - eglQueryDeviceAttribEXT@12 @49 - eglQueryDeviceStringEXT@8 @50 - eglCreateImageKHR@20 @51 - eglDestroyImageKHR@8 @52 - eglCreateDeviceANGLE@12 @53 - eglReleaseDeviceANGLE@4 @54 diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_egl.cpp b/src/3rdparty/angle/src/libGLESv2/entry_points_egl.cpp index 6f9770c57c..97546ee900 100644 --- a/src/3rdparty/angle/src/libGLESv2/entry_points_egl.cpp +++ b/src/3rdparty/angle/src/libGLESv2/entry_points_egl.cpp @@ -7,33 +7,59 @@ // entry_points_egl.cpp : Implements the EGL entry points. #include "libGLESv2/entry_points_egl.h" -#include "libGLESv2/entry_points_egl_ext.h" -#include "libGLESv2/entry_points_gles_2_0.h" -#include "libGLESv2/entry_points_gles_2_0_ext.h" -#include "libGLESv2/entry_points_gles_3_0.h" -#include "libGLESv2/global_state.h" - -#include "libANGLE/Context.h" -#include "libANGLE/Display.h" -#include "libANGLE/Texture.h" -#include "libANGLE/Surface.h" -#include "libANGLE/validationEGL.h" #include "common/debug.h" #include "common/version.h" +#include "libANGLE/Context.h" +#include "libANGLE/Display.h" +#include "libANGLE/Surface.h" +#include "libANGLE/Texture.h" +#include "libANGLE/Thread.h" +#include "libANGLE/queryutils.h" +#include "libANGLE/validationEGL.h" +#include "libGLESv2/global_state.h" +#include "libGLESv2/proc_table.h" #include namespace egl { +namespace +{ + +bool CompareProc(const ProcEntry &a, const char *b) +{ + return strcmp(a.first, b) < 0; +} + +void ClipConfigs(const std::vector &filteredConfigs, + EGLConfig *output_configs, + EGLint config_size, + EGLint *num_config) +{ + EGLint result_size = static_cast(filteredConfigs.size()); + if (output_configs) + { + result_size = std::max(std::min(result_size, config_size), 0); + for (EGLint i = 0; i < result_size; i++) + { + output_configs[i] = const_cast(filteredConfigs[i]); + } + } + *num_config = result_size; +} + +} // anonymous namespace + // EGL 1.0 EGLint EGLAPIENTRY GetError(void) { EVENT("()"); + Thread *thread = GetCurrentThread(); - EGLint error = GetGlobalError(); - SetGlobalError(Error(EGL_SUCCESS)); + EGLint error = thread->getError(); + thread->setError(NoError()); return error; } @@ -41,445 +67,367 @@ EGLDisplay EGLAPIENTRY GetDisplay(EGLNativeDisplayType display_id) { EVENT("(EGLNativeDisplayType display_id = 0x%0.8p)", display_id); - return Display::GetDisplayFromAttribs(reinterpret_cast(display_id), AttributeMap()); + return Display::GetDisplayFromNativeDisplay(display_id, AttributeMap()); } EGLBoolean EGLAPIENTRY Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor) { - EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint *major = 0x%0.8p, EGLint *minor = 0x%0.8p)", - dpy, major, minor); + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint *major = 0x%0.8p, EGLint *minor = 0x%0.8p)", dpy, + major, minor); + Thread *thread = GetCurrentThread(); Display *display = static_cast(dpy); if (dpy == EGL_NO_DISPLAY || !Display::isValidDisplay(display)) { - SetGlobalError(Error(EGL_BAD_DISPLAY)); + thread->setError(EglBadDisplay()); return EGL_FALSE; } Error error = display->initialize(); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - if (major) *major = 1; - if (minor) *minor = 4; + if (major) + *major = 1; + if (minor) + *minor = 4; - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } EGLBoolean EGLAPIENTRY Terminate(EGLDisplay dpy) { EVENT("(EGLDisplay dpy = 0x%0.8p)", dpy); + Thread *thread = GetCurrentThread(); Display *display = static_cast(dpy); if (dpy == EGL_NO_DISPLAY || !Display::isValidDisplay(display)) { - SetGlobalError(Error(EGL_BAD_DISPLAY)); + thread->setError(EglBadDisplay()); return EGL_FALSE; } - gl::Context *context = GetGlobalContext(); - - if (display->isValidContext(context)) + if (display->isValidContext(thread->getContext())) { - SetGlobalContext(NULL); - SetGlobalDisplay(NULL); + thread->setCurrent(nullptr); } - display->terminate(); + Error error = display->terminate(); + if (error.isError()) + { + thread->setError(error); + return EGL_FALSE; + } - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } const char *EGLAPIENTRY QueryString(EGLDisplay dpy, EGLint name) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint name = %d)", dpy, name); + Thread *thread = GetCurrentThread(); - Display *display = static_cast(dpy); + Display *display = static_cast(dpy); if (!(display == EGL_NO_DISPLAY && name == EGL_EXTENSIONS)) { Error error = ValidateDisplay(display); if (error.isError()) { - SetGlobalError(error); - return NULL; + thread->setError(error); + return nullptr; } } const char *result; switch (name) { - case EGL_CLIENT_APIS: - result = "OpenGL_ES"; - break; - case EGL_EXTENSIONS: - if (display == EGL_NO_DISPLAY) - { - result = Display::getClientExtensionString().c_str(); - } - else - { - result = display->getExtensionString().c_str(); - } - break; - case EGL_VENDOR: - result = display->getVendorString().c_str(); - break; - case EGL_VERSION: - result = "1.4 (ANGLE " ANGLE_VERSION_STRING ")"; - break; - default: - SetGlobalError(Error(EGL_BAD_PARAMETER)); - return NULL; + case EGL_CLIENT_APIS: + result = "OpenGL_ES"; + break; + case EGL_EXTENSIONS: + if (display == EGL_NO_DISPLAY) + { + result = Display::GetClientExtensionString().c_str(); + } + else + { + result = display->getExtensionString().c_str(); + } + break; + case EGL_VENDOR: + result = display->getVendorString().c_str(); + break; + case EGL_VERSION: + result = "1.4 (ANGLE " ANGLE_VERSION_STRING ")"; + break; + default: + thread->setError(EglBadParameter()); + return nullptr; } - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return result; } -EGLBoolean EGLAPIENTRY GetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config) +EGLBoolean EGLAPIENTRY GetConfigs(EGLDisplay dpy, + EGLConfig *configs, + EGLint config_size, + EGLint *num_config) { - EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig *configs = 0x%0.8p, " - "EGLint config_size = %d, EGLint *num_config = 0x%0.8p)", - dpy, configs, config_size, num_config); + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLConfig *configs = 0x%0.8p, " + "EGLint config_size = %d, EGLint *num_config = 0x%0.8p)", + dpy, configs, config_size, num_config); + Thread *thread = GetCurrentThread(); - Display *display = static_cast(dpy); + Display *display = static_cast(dpy); - Error error = ValidateDisplay(display); + Error error = ValidateGetConfigs(display, config_size, num_config); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - if (!num_config) - { - SetGlobalError(Error(EGL_BAD_PARAMETER)); - return EGL_FALSE; - } + ClipConfigs(display->getConfigs(AttributeMap()), configs, config_size, num_config); - std::vector filteredConfigs = display->getConfigs(AttributeMap()); - if (configs) - { - filteredConfigs.resize(std::min(filteredConfigs.size(), config_size)); - for (size_t i = 0; i < filteredConfigs.size(); i++) - { - configs[i] = const_cast(filteredConfigs[i]); - } - } - *num_config = static_cast(filteredConfigs.size()); - - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } -EGLBoolean EGLAPIENTRY ChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config) +EGLBoolean EGLAPIENTRY ChooseConfig(EGLDisplay dpy, + const EGLint *attrib_list, + EGLConfig *configs, + EGLint config_size, + EGLint *num_config) { - EVENT("(EGLDisplay dpy = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p, " - "EGLConfig *configs = 0x%0.8p, EGLint config_size = %d, EGLint *num_config = 0x%0.8p)", - dpy, attrib_list, configs, config_size, num_config); + EVENT( + "(EGLDisplay dpy = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p, " + "EGLConfig *configs = 0x%0.8p, EGLint config_size = %d, EGLint *num_config = 0x%0.8p)", + dpy, attrib_list, configs, config_size, num_config); + Thread *thread = GetCurrentThread(); - Display *display = static_cast(dpy); + Display *display = static_cast(dpy); + AttributeMap attribMap = AttributeMap::CreateFromIntArray(attrib_list); - Error error = ValidateDisplay(display); + Error error = ValidateChooseConfig(display, attribMap, config_size, num_config); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - if (!num_config) - { - SetGlobalError(Error(EGL_BAD_PARAMETER)); - return EGL_FALSE; - } + ClipConfigs(display->getConfigs(attribMap), configs, config_size, num_config); - std::vector filteredConfigs = display->getConfigs(AttributeMap(attrib_list)); - if (configs) - { - filteredConfigs.resize(std::min(filteredConfigs.size(), config_size)); - for (size_t i = 0; i < filteredConfigs.size(); i++) - { - configs[i] = const_cast(filteredConfigs[i]); - } - } - *num_config = static_cast(filteredConfigs.size()); - - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } -EGLBoolean EGLAPIENTRY GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) +EGLBoolean EGLAPIENTRY GetConfigAttrib(EGLDisplay dpy, + EGLConfig config, + EGLint attribute, + EGLint *value) { - EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", - dpy, config, attribute, value); + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLint attribute = %d, EGLint " + "*value = 0x%0.8p)", + dpy, config, attribute, value); + Thread *thread = GetCurrentThread(); - Display *display = static_cast(dpy); - Config *configuration = static_cast(config); + Display *display = static_cast(dpy); + Config *configuration = static_cast(config); - Error error = ValidateConfig(display, configuration); + Error error = ValidateGetConfigAttrib(display, configuration, attribute); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - if (!display->getConfigAttrib(configuration, attribute, value)) - { - SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); - return EGL_FALSE; - } + QueryConfigAttrib(configuration, attribute, value); - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } -EGLSurface EGLAPIENTRY CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list) +EGLSurface EGLAPIENTRY CreateWindowSurface(EGLDisplay dpy, + EGLConfig config, + EGLNativeWindowType win, + const EGLint *attrib_list) { - EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativeWindowType win = 0x%0.8p, " - "const EGLint *attrib_list = 0x%0.8p)", dpy, config, win, attrib_list); + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativeWindowType win = 0x%0.8p, " + "const EGLint *attrib_list = 0x%0.8p)", + dpy, config, win, attrib_list); + Thread *thread = GetCurrentThread(); - Display *display = static_cast(dpy); - Config *configuration = static_cast(config); - AttributeMap attributes(attrib_list); + Display *display = static_cast(dpy); + Config *configuration = static_cast(config); + AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list); Error error = ValidateCreateWindowSurface(display, configuration, win, attributes); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_NO_SURFACE; } egl::Surface *surface = nullptr; - error = display->createWindowSurface(configuration, win, attributes, &surface); + error = display->createWindowSurface(configuration, win, attributes, &surface); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_NO_SURFACE; } return static_cast(surface); } -EGLSurface EGLAPIENTRY CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) +EGLSurface EGLAPIENTRY CreatePbufferSurface(EGLDisplay dpy, + EGLConfig config, + const EGLint *attrib_list) { - EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)", - dpy, config, attrib_list); + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, const EGLint *attrib_list = " + "0x%0.8p)", + dpy, config, attrib_list); + Thread *thread = GetCurrentThread(); - Display *display = static_cast(dpy); - Config *configuration = static_cast(config); - AttributeMap attributes(attrib_list); + Display *display = static_cast(dpy); + Config *configuration = static_cast(config); + AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list); Error error = ValidateCreatePbufferSurface(display, configuration, attributes); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_NO_SURFACE; } egl::Surface *surface = nullptr; - error = display->createPbufferSurface(configuration, attributes, &surface); + error = display->createPbufferSurface(configuration, attributes, &surface); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_NO_SURFACE; } return static_cast(surface); } -EGLSurface EGLAPIENTRY CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list) +EGLSurface EGLAPIENTRY CreatePixmapSurface(EGLDisplay dpy, + EGLConfig config, + EGLNativePixmapType pixmap, + const EGLint *attrib_list) { - EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativePixmapType pixmap = 0x%0.8p, " - "const EGLint *attrib_list = 0x%0.8p)", dpy, config, pixmap, attrib_list); + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativePixmapType pixmap = " + "0x%0.8p, " + "const EGLint *attrib_list = 0x%0.8p)", + dpy, config, pixmap, attrib_list); + Thread *thread = GetCurrentThread(); - Display *display = static_cast(dpy); - Config *configuration = static_cast(config); + Display *display = static_cast(dpy); + Config *configuration = static_cast(config); Error error = ValidateConfig(display, configuration); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_NO_SURFACE; } - UNIMPLEMENTED(); // FIXME + UNIMPLEMENTED(); // FIXME - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_NO_SURFACE; } EGLBoolean EGLAPIENTRY DestroySurface(EGLDisplay dpy, EGLSurface surface) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface); + Thread *thread = GetCurrentThread(); - Display *display = static_cast(dpy); - Surface *eglSurface = static_cast(surface); + Display *display = static_cast(dpy); + Surface *eglSurface = static_cast(surface); Error error = ValidateSurface(display, eglSurface); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } if (surface == EGL_NO_SURFACE) { - SetGlobalError(Error(EGL_BAD_SURFACE)); + thread->setError(EglBadSurface()); return EGL_FALSE; } - display->destroySurface((Surface*)surface); - - SetGlobalError(Error(EGL_SUCCESS)); - return EGL_TRUE; -} - -EGLBoolean EGLAPIENTRY QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value) -{ - EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", - dpy, surface, attribute, value); - - Display *display = static_cast(dpy); - Surface *eglSurface = (Surface*)surface; - - Error error = ValidateSurface(display, eglSurface); + error = display->destroySurface(reinterpret_cast(surface)); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - if (surface == EGL_NO_SURFACE) - { - SetGlobalError(Error(EGL_BAD_SURFACE)); - return EGL_FALSE; - } - - switch (attribute) - { - case EGL_VG_ALPHA_FORMAT: - UNIMPLEMENTED(); // FIXME - break; - case EGL_VG_COLORSPACE: - UNIMPLEMENTED(); // FIXME - break; - case EGL_CONFIG_ID: - *value = eglSurface->getConfig()->configID; - break; - case EGL_HEIGHT: - *value = eglSurface->getHeight(); - break; - case EGL_HORIZONTAL_RESOLUTION: - UNIMPLEMENTED(); // FIXME - break; - case EGL_LARGEST_PBUFFER: - UNIMPLEMENTED(); // FIXME - break; - case EGL_MIPMAP_TEXTURE: - UNIMPLEMENTED(); // FIXME - break; - case EGL_MIPMAP_LEVEL: - UNIMPLEMENTED(); // FIXME - break; - case EGL_MULTISAMPLE_RESOLVE: - UNIMPLEMENTED(); // FIXME - break; - case EGL_PIXEL_ASPECT_RATIO: - *value = eglSurface->getPixelAspectRatio(); - break; - case EGL_RENDER_BUFFER: - *value = eglSurface->getRenderBuffer(); - break; - case EGL_SWAP_BEHAVIOR: - *value = eglSurface->getSwapBehavior(); - break; - case EGL_TEXTURE_FORMAT: - *value = eglSurface->getTextureFormat(); - break; - case EGL_TEXTURE_TARGET: - *value = eglSurface->getTextureTarget(); - break; - case EGL_VERTICAL_RESOLUTION: - UNIMPLEMENTED(); // FIXME - break; - case EGL_WIDTH: - *value = eglSurface->getWidth(); - break; - case EGL_POST_SUB_BUFFER_SUPPORTED_NV: - if (!display->getExtensions().postSubBuffer) - { - SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); - return EGL_FALSE; - } - *value = eglSurface->isPostSubBufferSupported(); - break; - case EGL_FIXED_SIZE_ANGLE: - if (!display->getExtensions().windowFixedSize) - { - SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); - return EGL_FALSE; - } - *value = eglSurface->isFixedSize(); - break; - case EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE: - if (!display->getExtensions().flexibleSurfaceCompatibility) - { - SetGlobalError( - Error(EGL_BAD_ATTRIBUTE, - "EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE cannot be used without " - "EGL_ANGLE_flexible_surface_compatibility support.")); - return EGL_FALSE; - } - *value = eglSurface->flexibleSurfaceCompatibilityRequested(); - break; - case EGL_SURFACE_ORIENTATION_ANGLE: - if (!display->getExtensions().surfaceOrientation) - { - SetGlobalError(Error(EGL_BAD_ATTRIBUTE, - "EGL_SURFACE_ORIENTATION_ANGLE cannot be queried without " - "EGL_ANGLE_surface_orientation support.")); - return EGL_FALSE; - } - *value = eglSurface->getOrientation(); - break; - case EGL_DIRECT_COMPOSITION_ANGLE: - if (!display->getExtensions().directComposition) - { - SetGlobalError(Error(EGL_BAD_ATTRIBUTE, - "EGL_DIRECT_COMPOSITION_ANGLE cannot be used without " - "EGL_ANGLE_direct_composition support.")); - return EGL_FALSE; - } - *value = eglSurface->directComposition(); - break; - default: - SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); - return EGL_FALSE; - } - - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } -EGLContext EGLAPIENTRY CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list) +EGLBoolean EGLAPIENTRY QuerySurface(EGLDisplay dpy, + EGLSurface surface, + EGLint attribute, + EGLint *value) { - EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLContext share_context = 0x%0.8p, " - "const EGLint *attrib_list = 0x%0.8p)", dpy, config, share_context, attrib_list); + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint " + "*value = 0x%0.8p)", + dpy, surface, attribute, value); + Thread *thread = GetCurrentThread(); - Display *display = static_cast(dpy); - Config *configuration = static_cast(config); - gl::Context* sharedGLContext = static_cast(share_context); - AttributeMap attributes(attrib_list); + const Display *display = static_cast(dpy); + const Surface *eglSurface = static_cast(surface); + + Error error = ValidateQuerySurface(display, eglSurface, attribute, value); + if (error.isError()) + { + thread->setError(error); + return EGL_FALSE; + } + + QuerySurfaceAttrib(eglSurface, attribute, value); + + thread->setError(NoError()); + return EGL_TRUE; +} + +EGLContext EGLAPIENTRY CreateContext(EGLDisplay dpy, + EGLConfig config, + EGLContext share_context, + const EGLint *attrib_list) +{ + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLContext share_context = " + "0x%0.8p, " + "const EGLint *attrib_list = 0x%0.8p)", + dpy, config, share_context, attrib_list); + Thread *thread = GetCurrentThread(); + + Display *display = static_cast(dpy); + Config *configuration = static_cast(config); + gl::Context *sharedGLContext = static_cast(share_context); + AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list); Error error = ValidateCreateContext(display, configuration, sharedGLContext, attributes); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_NO_CONTEXT; } @@ -487,208 +435,115 @@ EGLContext EGLAPIENTRY CreateContext(EGLDisplay dpy, EGLConfig config, EGLContex error = display->createContext(configuration, sharedGLContext, attributes, &context); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_NO_CONTEXT; } - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return static_cast(context); } EGLBoolean EGLAPIENTRY DestroyContext(EGLDisplay dpy, EGLContext ctx) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, ctx); + Thread *thread = GetCurrentThread(); - Display *display = static_cast(dpy); - gl::Context *context = static_cast(ctx); + Display *display = static_cast(dpy); + gl::Context *context = static_cast(ctx); Error error = ValidateContext(display, context); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } if (ctx == EGL_NO_CONTEXT) { - SetGlobalError(Error(EGL_BAD_CONTEXT)); + thread->setError(EglBadContext()); return EGL_FALSE; } - if (context == GetGlobalContext()) + if (context == thread->getContext()) { - SetGlobalDisplay(NULL); - SetGlobalContext(NULL); + thread->setCurrent(nullptr); } - display->destroyContext(context); + error = display->destroyContext(context); + if (error.isError()) + { + thread->setError(error); + return EGL_FALSE; + } - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) { - EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface draw = 0x%0.8p, EGLSurface read = 0x%0.8p, EGLContext ctx = 0x%0.8p)", - dpy, draw, read, ctx); + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLSurface draw = 0x%0.8p, EGLSurface read = 0x%0.8p, " + "EGLContext ctx = 0x%0.8p)", + dpy, draw, read, ctx); + Thread *thread = GetCurrentThread(); - Display *display = static_cast(dpy); - gl::Context *context = static_cast(ctx); + Display *display = static_cast(dpy); + gl::Context *context = static_cast(ctx); - // If ctx is EGL_NO_CONTEXT and either draw or read are not EGL_NO_SURFACE, an EGL_BAD_MATCH - // error is generated. - if (ctx == EGL_NO_CONTEXT && (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE)) + Error error = ValidateMakeCurrent(display, draw, read, context); + if (error.isError()) { - SetGlobalError(Error(EGL_BAD_MATCH)); + thread->setError(error); return EGL_FALSE; } - if (ctx != EGL_NO_CONTEXT && draw == EGL_NO_SURFACE && read == EGL_NO_SURFACE) - { - SetGlobalError(Error(EGL_BAD_MATCH)); - return EGL_FALSE; - } - - // If either of draw or read is a valid surface and the other is EGL_NO_SURFACE, an - // EGL_BAD_MATCH error is generated. - if ((read == EGL_NO_SURFACE) != (draw == EGL_NO_SURFACE)) - { - SetGlobalError(Error( - EGL_BAD_MATCH, "read and draw must both be valid surfaces, or both be EGL_NO_SURFACE")); - return EGL_FALSE; - } - - if (dpy == EGL_NO_DISPLAY || !Display::isValidDisplay(display)) - { - SetGlobalError(Error(EGL_BAD_DISPLAY, "'dpy' not a valid EGLDisplay handle")); - return EGL_FALSE; - } - - // EGL 1.5 spec: dpy can be uninitialized if all other parameters are null - if (!display->isInitialized() && (ctx != EGL_NO_CONTEXT || draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE)) - { - SetGlobalError(Error(EGL_NOT_INITIALIZED, "'dpy' not initialized")); - return EGL_FALSE; - } - - if (ctx != EGL_NO_CONTEXT) - { - Error error = ValidateContext(display, context); - if (error.isError()) - { - SetGlobalError(error); - return EGL_FALSE; - } - } - - if (display->isInitialized()) - { - if (display->testDeviceLost()) - { - display->notifyDeviceLost(); - return EGL_FALSE; - } - - if (display->isDeviceLost()) - { - SetGlobalError(Error(EGL_CONTEXT_LOST)); - return EGL_FALSE; - } - } - - Surface *drawSurface = static_cast(draw); - if (draw != EGL_NO_SURFACE) - { - Error error = ValidateSurface(display, drawSurface); - if (error.isError()) - { - SetGlobalError(error); - return EGL_FALSE; - } - } - - Surface *readSurface = static_cast(read); - if (read != EGL_NO_SURFACE) - { - Error error = ValidateSurface(display, readSurface); - if (error.isError()) - { - SetGlobalError(error); - return EGL_FALSE; - } - } - - if (readSurface) - { - Error readCompatError = - ValidateCompatibleConfigs(display, readSurface->getConfig(), readSurface, - context->getConfig(), readSurface->getType()); - if (readCompatError.isError()) - { - SetGlobalError(readCompatError); - return EGL_FALSE; - } - } - - if (draw != read) - { - UNIMPLEMENTED(); // FIXME - - if (drawSurface) - { - Error drawCompatError = - ValidateCompatibleConfigs(display, drawSurface->getConfig(), drawSurface, - context->getConfig(), drawSurface->getType()); - if (drawCompatError.isError()) - { - SetGlobalError(drawCompatError); - return EGL_FALSE; - } - } - } - + Surface *readSurface = static_cast(read); + Surface *drawSurface = static_cast(draw); Error makeCurrentError = display->makeCurrent(drawSurface, readSurface, context); if (makeCurrentError.isError()) { - SetGlobalError(makeCurrentError); + thread->setError(makeCurrentError); return EGL_FALSE; } - gl::Context *previousContext = GetGlobalContext(); - - SetGlobalDisplay(display); - SetGlobalDrawSurface(drawSurface); - SetGlobalReadSurface(readSurface); - SetGlobalContext(context); + gl::Context *previousContext = thread->getContext(); + thread->setCurrent(context); // Release the surface from the previously-current context, to allow // destroyed surfaces to delete themselves. if (previousContext != nullptr && context != previousContext) { - previousContext->releaseSurface(); + auto err = previousContext->releaseSurface(display); + if (err.isError()) + { + thread->setError(err); + return EGL_FALSE; + } } - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } EGLSurface EGLAPIENTRY GetCurrentSurface(EGLint readdraw) { EVENT("(EGLint readdraw = %d)", readdraw); + Thread *thread = GetCurrentThread(); if (readdraw == EGL_READ) { - SetGlobalError(Error(EGL_SUCCESS)); - return GetGlobalReadSurface(); + thread->setError(NoError()); + return thread->getCurrentReadSurface(); } else if (readdraw == EGL_DRAW) { - SetGlobalError(Error(EGL_SUCCESS)); - return GetGlobalDrawSurface(); + thread->setError(NoError()); + return thread->getCurrentDrawSurface(); } else { - SetGlobalError(Error(EGL_BAD_PARAMETER)); + thread->setError(EglBadParameter()); return EGL_NO_SURFACE; } } @@ -696,283 +551,294 @@ EGLSurface EGLAPIENTRY GetCurrentSurface(EGLint readdraw) EGLDisplay EGLAPIENTRY GetCurrentDisplay(void) { EVENT("()"); + Thread *thread = GetCurrentThread(); - EGLDisplay dpy = GetGlobalDisplay(); - - SetGlobalError(Error(EGL_SUCCESS)); - return dpy; + thread->setError(NoError()); + if (thread->getContext() != nullptr) + { + return thread->getContext()->getCurrentDisplay(); + } + return EGL_NO_DISPLAY; } EGLBoolean EGLAPIENTRY QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value) { - EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", - dpy, ctx, attribute, value); + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLint attribute = %d, EGLint *value " + "= 0x%0.8p)", + dpy, ctx, attribute, value); + Thread *thread = GetCurrentThread(); - Display *display = static_cast(dpy); - gl::Context *context = static_cast(ctx); + Display *display = static_cast(dpy); + gl::Context *context = static_cast(ctx); - Error error = ValidateContext(display, context); + Error error = ValidateQueryContext(display, context, attribute, value); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - switch (attribute) - { - case EGL_CONFIG_ID: - *value = context->getConfig()->configID; - break; - case EGL_CONTEXT_CLIENT_TYPE: - *value = context->getClientType(); - break; - case EGL_CONTEXT_CLIENT_VERSION: - *value = context->getClientVersion(); - break; - case EGL_RENDER_BUFFER: - *value = context->getRenderBuffer(); - break; - default: - SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); - return EGL_FALSE; - } + QueryContextAttrib(context, attribute, value); - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } EGLBoolean EGLAPIENTRY WaitGL(void) { EVENT("()"); + Thread *thread = GetCurrentThread(); - Display *display = GetGlobalDisplay(); + Display *display = thread->getCurrentDisplay(); Error error = ValidateDisplay(display); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } // eglWaitGL like calling eglWaitClient with the OpenGL ES API bound. Since we only implement // OpenGL ES we can do the call directly. - error = display->waitClient(); + error = display->waitClient(thread->getContext()); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } EGLBoolean EGLAPIENTRY WaitNative(EGLint engine) { EVENT("(EGLint engine = %d)", engine); + Thread *thread = GetCurrentThread(); - Display *display = GetGlobalDisplay(); + Display *display = thread->getCurrentDisplay(); Error error = ValidateDisplay(display); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } if (engine != EGL_CORE_NATIVE_ENGINE) { - SetGlobalError( - Error(EGL_BAD_PARAMETER, "the 'engine' parameter has an unrecognized value")); + thread->setError(EglBadParameter() << "the 'engine' parameter has an unrecognized value"); } - error = display->waitNative(engine, GetGlobalDrawSurface(), GetGlobalReadSurface()); + error = display->waitNative(thread->getContext(), engine); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } EGLBoolean EGLAPIENTRY SwapBuffers(EGLDisplay dpy, EGLSurface surface) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface); + Thread *thread = GetCurrentThread(); - Display *display = static_cast(dpy); - Surface *eglSurface = (Surface*)surface; + Display *display = static_cast(dpy); + Surface *eglSurface = (Surface *)surface; Error error = ValidateSurface(display, eglSurface); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - if (display->isDeviceLost()) + if (display->testDeviceLost()) { - SetGlobalError(Error(EGL_CONTEXT_LOST)); + thread->setError(EglContextLost()); return EGL_FALSE; } if (surface == EGL_NO_SURFACE) { - SetGlobalError(Error(EGL_BAD_SURFACE)); + thread->setError(EglBadSurface()); return EGL_FALSE; } - error = eglSurface->swap(); + if (!thread->getContext() || thread->getCurrentDrawSurface() != eglSurface) + { + thread->setError(EglBadSurface()); + return EGL_FALSE; + } + + error = eglSurface->swap(thread->getContext()); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } EGLBoolean EGLAPIENTRY CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) { - EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLNativePixmapType target = 0x%0.8p)", dpy, surface, target); + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLNativePixmapType target = " + "0x%0.8p)", + dpy, surface, target); + Thread *thread = GetCurrentThread(); - Display *display = static_cast(dpy); - Surface *eglSurface = static_cast(surface); + Display *display = static_cast(dpy); + Surface *eglSurface = static_cast(surface); Error error = ValidateSurface(display, eglSurface); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - if (display->isDeviceLost()) + if (display->testDeviceLost()) { - SetGlobalError(Error(EGL_CONTEXT_LOST)); + thread->setError(EglContextLost()); return EGL_FALSE; } - UNIMPLEMENTED(); // FIXME + UNIMPLEMENTED(); // FIXME - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return 0; } // EGL 1.1 EGLBoolean EGLAPIENTRY BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { - EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer); + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, + surface, buffer); + Thread *thread = GetCurrentThread(); - Display *display = static_cast(dpy); - Surface *eglSurface = static_cast(surface); + Display *display = static_cast(dpy); + Surface *eglSurface = static_cast(surface); Error error = ValidateSurface(display, eglSurface); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } if (buffer != EGL_BACK_BUFFER) { - SetGlobalError(Error(EGL_BAD_PARAMETER)); + thread->setError(EglBadParameter()); return EGL_FALSE; } if (surface == EGL_NO_SURFACE || eglSurface->getType() == EGL_WINDOW_BIT) { - SetGlobalError(Error(EGL_BAD_SURFACE)); + thread->setError(EglBadSurface()); return EGL_FALSE; } if (eglSurface->getBoundTexture()) { - SetGlobalError(Error(EGL_BAD_ACCESS)); + thread->setError(EglBadAccess()); return EGL_FALSE; } if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE) { - SetGlobalError(Error(EGL_BAD_MATCH)); + thread->setError(EglBadMatch()); return EGL_FALSE; } - gl::Context *context = GetGlobalContext(); + gl::Context *context = thread->getContext(); if (context) { gl::Texture *textureObject = context->getTargetTexture(GL_TEXTURE_2D); - ASSERT(textureObject != NULL); + ASSERT(textureObject != nullptr); if (textureObject->getImmutableFormat()) { - SetGlobalError(Error(EGL_BAD_MATCH)); + thread->setError(EglBadMatch()); return EGL_FALSE; } - error = eglSurface->bindTexImage(textureObject, buffer); + error = eglSurface->bindTexImage(context, textureObject, buffer); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } } - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } -EGLBoolean EGLAPIENTRY SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) +EGLBoolean EGLAPIENTRY SurfaceAttrib(EGLDisplay dpy, + EGLSurface surface, + EGLint attribute, + EGLint value) { - EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint value = %d)", + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint " + "value = %d)", dpy, surface, attribute, value); + Thread *thread = GetCurrentThread(); - Display *display = static_cast(dpy); - Surface *eglSurface = static_cast(surface); + Display *display = static_cast(dpy); + Surface *eglSurface = static_cast(surface); - Error error = ValidateSurface(display, eglSurface); + Error error = ValidateSurfaceAttrib(display, eglSurface, attribute, value); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - UNIMPLEMENTED(); // FIXME + SetSurfaceAttrib(eglSurface, attribute, value); - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } EGLBoolean EGLAPIENTRY ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { - EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer); + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, + surface, buffer); + Thread *thread = GetCurrentThread(); - Display *display = static_cast(dpy); - Surface *eglSurface = static_cast(surface); + Display *display = static_cast(dpy); + Surface *eglSurface = static_cast(surface); Error error = ValidateSurface(display, eglSurface); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } if (buffer != EGL_BACK_BUFFER) { - SetGlobalError(Error(EGL_BAD_PARAMETER)); + thread->setError(EglBadParameter()); return EGL_FALSE; } if (surface == EGL_NO_SURFACE || eglSurface->getType() == EGL_WINDOW_BIT) { - SetGlobalError(Error(EGL_BAD_SURFACE)); + thread->setError(EglBadSurface()); return EGL_FALSE; } if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE) { - SetGlobalError(Error(EGL_BAD_MATCH)); + thread->setError(EglBadMatch()); return EGL_FALSE; } @@ -980,105 +846,116 @@ EGLBoolean EGLAPIENTRY ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLin if (texture) { - error = eglSurface->releaseTexImage(buffer); + error = eglSurface->releaseTexImage(thread->getContext(), buffer); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } } - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } EGLBoolean EGLAPIENTRY SwapInterval(EGLDisplay dpy, EGLint interval) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint interval = %d)", dpy, interval); + Thread *thread = GetCurrentThread(); - Display *display = static_cast(dpy); + Display *display = static_cast(dpy); Error error = ValidateDisplay(display); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - Surface *draw_surface = static_cast(GetGlobalDrawSurface()); + Surface *draw_surface = static_cast(thread->getCurrentDrawSurface()); - if (draw_surface == NULL) + if (draw_surface == nullptr) { - SetGlobalError(Error(EGL_BAD_SURFACE)); + thread->setError(EglBadSurface()); return EGL_FALSE; } const egl::Config *surfaceConfig = draw_surface->getConfig(); - EGLint clampedInterval = std::min(std::max(interval, surfaceConfig->minSwapInterval), surfaceConfig->maxSwapInterval); + EGLint clampedInterval = std::min(std::max(interval, surfaceConfig->minSwapInterval), + surfaceConfig->maxSwapInterval); draw_surface->setSwapInterval(clampedInterval); - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } - // EGL 1.2 EGLBoolean EGLAPIENTRY BindAPI(EGLenum api) { EVENT("(EGLenum api = 0x%X)", api); + Thread *thread = GetCurrentThread(); switch (api) { - case EGL_OPENGL_API: - case EGL_OPENVG_API: - SetGlobalError(Error(EGL_BAD_PARAMETER)); - return EGL_FALSE; // Not supported by this implementation - case EGL_OPENGL_ES_API: - break; - default: - SetGlobalError(Error(EGL_BAD_PARAMETER)); - return EGL_FALSE; + case EGL_OPENGL_API: + case EGL_OPENVG_API: + thread->setError(EglBadParameter()); + return EGL_FALSE; // Not supported by this implementation + case EGL_OPENGL_ES_API: + break; + default: + thread->setError(EglBadParameter()); + return EGL_FALSE; } - SetGlobalAPI(api); + thread->setAPI(api); - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } EGLenum EGLAPIENTRY QueryAPI(void) { EVENT("()"); + Thread *thread = GetCurrentThread(); - EGLenum API = GetGlobalAPI(); + EGLenum API = thread->getAPI(); - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return API; } -EGLSurface EGLAPIENTRY CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list) +EGLSurface EGLAPIENTRY CreatePbufferFromClientBuffer(EGLDisplay dpy, + EGLenum buftype, + EGLClientBuffer buffer, + EGLConfig config, + const EGLint *attrib_list) { - EVENT("(EGLDisplay dpy = 0x%0.8p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = 0x%0.8p, " - "EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)", - dpy, buftype, buffer, config, attrib_list); + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = 0x%0.8p, " + "EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)", + dpy, buftype, buffer, config, attrib_list); + Thread *thread = GetCurrentThread(); - Display *display = static_cast(dpy); - Config *configuration = static_cast(config); - AttributeMap attributes(attrib_list); + Display *display = static_cast(dpy); + Config *configuration = static_cast(config); + AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list); - Error error = ValidateCreatePbufferFromClientBuffer(display, buftype, buffer, configuration, attributes); + Error error = + ValidateCreatePbufferFromClientBuffer(display, buftype, buffer, configuration, attributes); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_NO_SURFACE; } egl::Surface *surface = nullptr; - error = display->createPbufferFromClientBuffer(configuration, buffer, attributes, &surface); + error = display->createPbufferFromClientBuffer(configuration, buftype, buffer, attributes, + &surface); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_NO_SURFACE; } @@ -1088,34 +965,36 @@ EGLSurface EGLAPIENTRY CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buf EGLBoolean EGLAPIENTRY ReleaseThread(void) { EVENT("()"); + Thread *thread = GetCurrentThread(); MakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE); - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } EGLBoolean EGLAPIENTRY WaitClient(void) { EVENT("()"); + Thread *thread = GetCurrentThread(); - Display *display = GetGlobalDisplay(); + Display *display = thread->getCurrentDisplay(); Error error = ValidateDisplay(display); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - error = display->waitClient(); + error = display->waitClient(thread->getContext()); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } @@ -1123,540 +1002,185 @@ EGLBoolean EGLAPIENTRY WaitClient(void) EGLContext EGLAPIENTRY GetCurrentContext(void) { EVENT("()"); + Thread *thread = GetCurrentThread(); - gl::Context *context = GetGlobalContext(); + gl::Context *context = thread->getContext(); - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return static_cast(context); } // EGL 1.5 EGLSync EGLAPIENTRY CreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list) { - EVENT("(EGLDisplay dpy = 0x%0.8p, EGLenum type = 0x%X, const EGLint* attrib_list = 0x%0.8p)", dpy, type, attrib_list); + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLenum type = 0x%X, const EGLint* attrib_list = 0x%0.8p)", + dpy, type, attrib_list); + Thread *thread = GetCurrentThread(); UNIMPLEMENTED(); + thread->setError(EglBadDisplay() << "eglCreateSync unimplemented."); return EGL_NO_SYNC; } EGLBoolean EGLAPIENTRY DestroySync(EGLDisplay dpy, EGLSync sync) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p)", dpy, sync); + Thread *thread = GetCurrentThread(); UNIMPLEMENTED(); + thread->setError(EglBadDisplay() << "eglDestroySync unimplemented."); return EGL_FALSE; } EGLint EGLAPIENTRY ClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout) { - EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint flags = 0x%X, EGLTime timeout = %d)", dpy, sync, flags, timeout); + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint flags = 0x%X, EGLTime timeout = " + "%d)", + dpy, sync, flags, timeout); + Thread *thread = GetCurrentThread(); UNIMPLEMENTED(); + thread->setError(EglBadDisplay() << "eglClientWaitSync unimplemented."); return 0; } -EGLBoolean EGLAPIENTRY GetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value) +EGLBoolean EGLAPIENTRY GetSyncAttrib(EGLDisplay dpy, + EGLSync sync, + EGLint attribute, + EGLAttrib *value) { - EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint attribute = 0x%X, EGLAttrib *value = 0x%0.8p)", dpy, sync, attribute, value); + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint attribute = 0x%X, EGLAttrib " + "*value = 0x%0.8p)", + dpy, sync, attribute, value); + Thread *thread = GetCurrentThread(); UNIMPLEMENTED(); + thread->setError(EglBadDisplay() << "eglSyncAttrib unimplemented."); return EGL_FALSE; } -EGLImage EGLAPIENTRY CreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list) +EGLImage EGLAPIENTRY CreateImage(EGLDisplay dpy, + EGLContext ctx, + EGLenum target, + EGLClientBuffer buffer, + const EGLAttrib *attrib_list) { - EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLenum target = 0x%X, " - "EGLClientBuffer buffer = 0x%0.8p, const EGLAttrib *attrib_list = 0x%0.8p)", - dpy, ctx, target, buffer, attrib_list); + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLenum target = 0x%X, " + "EGLClientBuffer buffer = 0x%0.8p, const EGLAttrib *attrib_list = 0x%0.8p)", + dpy, ctx, target, buffer, attrib_list); + Thread *thread = GetCurrentThread(); UNIMPLEMENTED(); + thread->setError(EglBadDisplay() << "eglCreateImage unimplemented."); return EGL_NO_IMAGE; } EGLBoolean EGLAPIENTRY DestroyImage(EGLDisplay dpy, EGLImage image) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLImage image = 0x%0.8p)", dpy, image); + Thread *thread = GetCurrentThread(); UNIMPLEMENTED(); + thread->setError(EglBadDisplay() << "eglDestroyImage unimplemented."); return EGL_FALSE; } -EGLDisplay EGLAPIENTRY GetPlatformDisplay(EGLenum platform, void *native_display, const EGLAttrib *attrib_list) +EGLDisplay EGLAPIENTRY GetPlatformDisplay(EGLenum platform, + void *native_display, + const EGLAttrib *attrib_list) { - EVENT("(EGLenum platform = %d, void* native_display = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)", - platform, native_display, attrib_list); + EVENT( + "(EGLenum platform = %d, void* native_display = 0x%0.8p, const EGLint* attrib_list = " + "0x%0.8p)", + platform, native_display, attrib_list); + Thread *thread = GetCurrentThread(); - UNIMPLEMENTED(); - return EGL_NO_DISPLAY; + Error err = ValidateGetPlatformDisplay(platform, native_display, attrib_list); + thread->setError(err); + if (err.isError()) + { + return EGL_NO_DISPLAY; + } + + const auto &attribMap = AttributeMap::CreateFromAttribArray(attrib_list); + if (platform == EGL_PLATFORM_ANGLE_ANGLE) + { + return Display::GetDisplayFromNativeDisplay( + gl::bitCast(native_display), attribMap); + } + else if (platform == EGL_PLATFORM_DEVICE_EXT) + { + Device *eglDevice = reinterpret_cast(native_display); + return Display::GetDisplayFromDevice(eglDevice, attribMap); + } + else + { + UNREACHABLE(); + return EGL_NO_DISPLAY; + } } -EGLSurface EGLAPIENTRY CreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list) +EGLSurface EGLAPIENTRY CreatePlatformWindowSurface(EGLDisplay dpy, + EGLConfig config, + void *native_window, + const EGLAttrib *attrib_list) { - EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, void* native_window = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)", - dpy, config, native_window, attrib_list); + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, void* native_window = 0x%0.8p, " + "const EGLint* attrib_list = 0x%0.8p)", + dpy, config, native_window, attrib_list); + Thread *thread = GetCurrentThread(); UNIMPLEMENTED(); + thread->setError(EglBadDisplay() << "eglCreatePlatformWindowSurface unimplemented."); return EGL_NO_SURFACE; } -EGLSurface EGLAPIENTRY CreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list) +EGLSurface EGLAPIENTRY CreatePlatformPixmapSurface(EGLDisplay dpy, + EGLConfig config, + void *native_pixmap, + const EGLAttrib *attrib_list) { - EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, void* native_pixmap = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)", - dpy, config, native_pixmap, attrib_list); + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, void* native_pixmap = 0x%0.8p, " + "const EGLint* attrib_list = 0x%0.8p)", + dpy, config, native_pixmap, attrib_list); + Thread *thread = GetCurrentThread(); UNIMPLEMENTED(); + thread->setError(EglBadDisplay() << "eglCreatePlatformPixmapSurface unimplemented."); return EGL_NO_SURFACE; } EGLBoolean EGLAPIENTRY WaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags) { - EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint flags = 0x%X)", dpy, sync, flags); + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint flags = 0x%X)", dpy, sync, + flags); + Thread *thread = GetCurrentThread(); UNIMPLEMENTED(); + thread->setError(EglBadDisplay() << "eglWaitSync unimplemented."); return EGL_FALSE; } __eglMustCastToProperFunctionPointerType EGLAPIENTRY GetProcAddress(const char *procname) { EVENT("(const char *procname = \"%s\")", procname); + Thread *thread = GetCurrentThread(); - typedef std::map ProcAddressMap; - auto generateProcAddressMap = []() - { - ProcAddressMap map; -#define INSERT_PROC_ADDRESS(ns, proc) \ - map[#ns #proc] = reinterpret_cast<__eglMustCastToProperFunctionPointerType>(ns::proc) + ProcEntry *entry = + std::lower_bound(&g_procTable[0], &g_procTable[g_numProcs], procname, CompareProc); - // GLES2 core - INSERT_PROC_ADDRESS(gl, ActiveTexture); - INSERT_PROC_ADDRESS(gl, AttachShader); - INSERT_PROC_ADDRESS(gl, BindAttribLocation); - INSERT_PROC_ADDRESS(gl, BindBuffer); - INSERT_PROC_ADDRESS(gl, BindFramebuffer); - INSERT_PROC_ADDRESS(gl, BindRenderbuffer); - INSERT_PROC_ADDRESS(gl, BindTexture); - INSERT_PROC_ADDRESS(gl, BlendColor); - INSERT_PROC_ADDRESS(gl, BlendEquation); - INSERT_PROC_ADDRESS(gl, BlendEquationSeparate); - INSERT_PROC_ADDRESS(gl, BlendFunc); - INSERT_PROC_ADDRESS(gl, BlendFuncSeparate); - INSERT_PROC_ADDRESS(gl, BufferData); - INSERT_PROC_ADDRESS(gl, BufferSubData); - INSERT_PROC_ADDRESS(gl, CheckFramebufferStatus); - INSERT_PROC_ADDRESS(gl, Clear); - INSERT_PROC_ADDRESS(gl, ClearColor); - INSERT_PROC_ADDRESS(gl, ClearDepthf); - INSERT_PROC_ADDRESS(gl, ClearStencil); - INSERT_PROC_ADDRESS(gl, ColorMask); - INSERT_PROC_ADDRESS(gl, CompileShader); - INSERT_PROC_ADDRESS(gl, CompressedTexImage2D); - INSERT_PROC_ADDRESS(gl, CompressedTexSubImage2D); - INSERT_PROC_ADDRESS(gl, CopyTexImage2D); - INSERT_PROC_ADDRESS(gl, CopyTexSubImage2D); - INSERT_PROC_ADDRESS(gl, CreateProgram); - INSERT_PROC_ADDRESS(gl, CreateShader); - INSERT_PROC_ADDRESS(gl, CullFace); - INSERT_PROC_ADDRESS(gl, DeleteBuffers); - INSERT_PROC_ADDRESS(gl, DeleteFramebuffers); - INSERT_PROC_ADDRESS(gl, DeleteProgram); - INSERT_PROC_ADDRESS(gl, DeleteRenderbuffers); - INSERT_PROC_ADDRESS(gl, DeleteShader); - INSERT_PROC_ADDRESS(gl, DeleteTextures); - INSERT_PROC_ADDRESS(gl, DepthFunc); - INSERT_PROC_ADDRESS(gl, DepthMask); - INSERT_PROC_ADDRESS(gl, DepthRangef); - INSERT_PROC_ADDRESS(gl, DetachShader); - INSERT_PROC_ADDRESS(gl, Disable); - INSERT_PROC_ADDRESS(gl, DisableVertexAttribArray); - INSERT_PROC_ADDRESS(gl, DrawArrays); - INSERT_PROC_ADDRESS(gl, DrawElements); - INSERT_PROC_ADDRESS(gl, Enable); - INSERT_PROC_ADDRESS(gl, EnableVertexAttribArray); - INSERT_PROC_ADDRESS(gl, Finish); - INSERT_PROC_ADDRESS(gl, Flush); - INSERT_PROC_ADDRESS(gl, FramebufferRenderbuffer); - INSERT_PROC_ADDRESS(gl, FramebufferTexture2D); - INSERT_PROC_ADDRESS(gl, FrontFace); - INSERT_PROC_ADDRESS(gl, GenBuffers); - INSERT_PROC_ADDRESS(gl, GenerateMipmap); - INSERT_PROC_ADDRESS(gl, GenFramebuffers); - INSERT_PROC_ADDRESS(gl, GenRenderbuffers); - INSERT_PROC_ADDRESS(gl, GenTextures); - INSERT_PROC_ADDRESS(gl, GetActiveAttrib); - INSERT_PROC_ADDRESS(gl, GetActiveUniform); - INSERT_PROC_ADDRESS(gl, GetAttachedShaders); - INSERT_PROC_ADDRESS(gl, GetAttribLocation); - INSERT_PROC_ADDRESS(gl, GetBooleanv); - INSERT_PROC_ADDRESS(gl, GetBufferParameteriv); - INSERT_PROC_ADDRESS(gl, GetError); - INSERT_PROC_ADDRESS(gl, GetFloatv); - INSERT_PROC_ADDRESS(gl, GetFramebufferAttachmentParameteriv); - INSERT_PROC_ADDRESS(gl, GetIntegerv); - INSERT_PROC_ADDRESS(gl, GetProgramiv); - INSERT_PROC_ADDRESS(gl, GetProgramInfoLog); - INSERT_PROC_ADDRESS(gl, GetRenderbufferParameteriv); - INSERT_PROC_ADDRESS(gl, GetShaderiv); - INSERT_PROC_ADDRESS(gl, GetShaderInfoLog); - INSERT_PROC_ADDRESS(gl, GetShaderPrecisionFormat); - INSERT_PROC_ADDRESS(gl, GetShaderSource); - INSERT_PROC_ADDRESS(gl, GetString); - INSERT_PROC_ADDRESS(gl, GetTexParameterfv); - INSERT_PROC_ADDRESS(gl, GetTexParameteriv); - INSERT_PROC_ADDRESS(gl, GetUniformfv); - INSERT_PROC_ADDRESS(gl, GetUniformiv); - INSERT_PROC_ADDRESS(gl, GetUniformLocation); - INSERT_PROC_ADDRESS(gl, GetVertexAttribfv); - INSERT_PROC_ADDRESS(gl, GetVertexAttribiv); - INSERT_PROC_ADDRESS(gl, GetVertexAttribPointerv); - INSERT_PROC_ADDRESS(gl, Hint); - INSERT_PROC_ADDRESS(gl, IsBuffer); - INSERT_PROC_ADDRESS(gl, IsEnabled); - INSERT_PROC_ADDRESS(gl, IsFramebuffer); - INSERT_PROC_ADDRESS(gl, IsProgram); - INSERT_PROC_ADDRESS(gl, IsRenderbuffer); - INSERT_PROC_ADDRESS(gl, IsShader); - INSERT_PROC_ADDRESS(gl, IsTexture); - INSERT_PROC_ADDRESS(gl, LineWidth); - INSERT_PROC_ADDRESS(gl, LinkProgram); - INSERT_PROC_ADDRESS(gl, PixelStorei); - INSERT_PROC_ADDRESS(gl, PolygonOffset); - INSERT_PROC_ADDRESS(gl, ReadPixels); - INSERT_PROC_ADDRESS(gl, ReleaseShaderCompiler); - INSERT_PROC_ADDRESS(gl, RenderbufferStorage); - INSERT_PROC_ADDRESS(gl, SampleCoverage); - INSERT_PROC_ADDRESS(gl, Scissor); - INSERT_PROC_ADDRESS(gl, ShaderBinary); - INSERT_PROC_ADDRESS(gl, ShaderSource); - INSERT_PROC_ADDRESS(gl, StencilFunc); - INSERT_PROC_ADDRESS(gl, StencilFuncSeparate); - INSERT_PROC_ADDRESS(gl, StencilMask); - INSERT_PROC_ADDRESS(gl, StencilMaskSeparate); - INSERT_PROC_ADDRESS(gl, StencilOp); - INSERT_PROC_ADDRESS(gl, StencilOpSeparate); - INSERT_PROC_ADDRESS(gl, TexImage2D); - INSERT_PROC_ADDRESS(gl, TexParameterf); - INSERT_PROC_ADDRESS(gl, TexParameterfv); - INSERT_PROC_ADDRESS(gl, TexParameteri); - INSERT_PROC_ADDRESS(gl, TexParameteriv); - INSERT_PROC_ADDRESS(gl, TexSubImage2D); - INSERT_PROC_ADDRESS(gl, Uniform1f); - INSERT_PROC_ADDRESS(gl, Uniform1fv); - INSERT_PROC_ADDRESS(gl, Uniform1i); - INSERT_PROC_ADDRESS(gl, Uniform1iv); - INSERT_PROC_ADDRESS(gl, Uniform2f); - INSERT_PROC_ADDRESS(gl, Uniform2fv); - INSERT_PROC_ADDRESS(gl, Uniform2i); - INSERT_PROC_ADDRESS(gl, Uniform2iv); - INSERT_PROC_ADDRESS(gl, Uniform3f); - INSERT_PROC_ADDRESS(gl, Uniform3fv); - INSERT_PROC_ADDRESS(gl, Uniform3i); - INSERT_PROC_ADDRESS(gl, Uniform3iv); - INSERT_PROC_ADDRESS(gl, Uniform4f); - INSERT_PROC_ADDRESS(gl, Uniform4fv); - INSERT_PROC_ADDRESS(gl, Uniform4i); - INSERT_PROC_ADDRESS(gl, Uniform4iv); - INSERT_PROC_ADDRESS(gl, UniformMatrix2fv); - INSERT_PROC_ADDRESS(gl, UniformMatrix3fv); - INSERT_PROC_ADDRESS(gl, UniformMatrix4fv); - INSERT_PROC_ADDRESS(gl, UseProgram); - INSERT_PROC_ADDRESS(gl, ValidateProgram); - INSERT_PROC_ADDRESS(gl, VertexAttrib1f); - INSERT_PROC_ADDRESS(gl, VertexAttrib1fv); - INSERT_PROC_ADDRESS(gl, VertexAttrib2f); - INSERT_PROC_ADDRESS(gl, VertexAttrib2fv); - INSERT_PROC_ADDRESS(gl, VertexAttrib3f); - INSERT_PROC_ADDRESS(gl, VertexAttrib3fv); - INSERT_PROC_ADDRESS(gl, VertexAttrib4f); - INSERT_PROC_ADDRESS(gl, VertexAttrib4fv); - INSERT_PROC_ADDRESS(gl, VertexAttribPointer); - INSERT_PROC_ADDRESS(gl, Viewport); + thread->setError(NoError()); - // GL_ANGLE_framebuffer_blit - INSERT_PROC_ADDRESS(gl, BlitFramebufferANGLE); - - // GL_ANGLE_framebuffer_multisample - INSERT_PROC_ADDRESS(gl, RenderbufferStorageMultisampleANGLE); - - // GL_EXT_discard_framebuffer - INSERT_PROC_ADDRESS(gl, DiscardFramebufferEXT); - - // GL_NV_fence - INSERT_PROC_ADDRESS(gl, DeleteFencesNV); - INSERT_PROC_ADDRESS(gl, GenFencesNV); - INSERT_PROC_ADDRESS(gl, IsFenceNV); - INSERT_PROC_ADDRESS(gl, TestFenceNV); - INSERT_PROC_ADDRESS(gl, GetFenceivNV); - INSERT_PROC_ADDRESS(gl, FinishFenceNV); - INSERT_PROC_ADDRESS(gl, SetFenceNV); - - // GL_ANGLE_translated_shader_source - INSERT_PROC_ADDRESS(gl, GetTranslatedShaderSourceANGLE); - - // GL_EXT_texture_storage - INSERT_PROC_ADDRESS(gl, TexStorage2DEXT); - - // GL_EXT_robustness - INSERT_PROC_ADDRESS(gl, GetGraphicsResetStatusEXT); - INSERT_PROC_ADDRESS(gl, ReadnPixelsEXT); - INSERT_PROC_ADDRESS(gl, GetnUniformfvEXT); - INSERT_PROC_ADDRESS(gl, GetnUniformivEXT); - - // GL_EXT_occlusion_query_boolean - INSERT_PROC_ADDRESS(gl, GenQueriesEXT); - INSERT_PROC_ADDRESS(gl, DeleteQueriesEXT); - INSERT_PROC_ADDRESS(gl, IsQueryEXT); - INSERT_PROC_ADDRESS(gl, BeginQueryEXT); - INSERT_PROC_ADDRESS(gl, EndQueryEXT); - INSERT_PROC_ADDRESS(gl, GetQueryivEXT); - INSERT_PROC_ADDRESS(gl, GetQueryObjectuivEXT); - - // GL_EXT_draw_buffers - INSERT_PROC_ADDRESS(gl, DrawBuffersEXT); - - // GL_ANGLE_instanced_arrays - INSERT_PROC_ADDRESS(gl, DrawArraysInstancedANGLE); - INSERT_PROC_ADDRESS(gl, DrawElementsInstancedANGLE); - INSERT_PROC_ADDRESS(gl, VertexAttribDivisorANGLE); - - // GL_OES_get_program_binary - INSERT_PROC_ADDRESS(gl, GetProgramBinaryOES); - INSERT_PROC_ADDRESS(gl, ProgramBinaryOES); - - // GL_OES_mapbuffer - INSERT_PROC_ADDRESS(gl, MapBufferOES); - INSERT_PROC_ADDRESS(gl, UnmapBufferOES); - INSERT_PROC_ADDRESS(gl, GetBufferPointervOES); - - // GL_EXT_map_buffer_range - INSERT_PROC_ADDRESS(gl, MapBufferRangeEXT); - INSERT_PROC_ADDRESS(gl, FlushMappedBufferRangeEXT); - - // GL_EXT_debug_marker - INSERT_PROC_ADDRESS(gl, InsertEventMarkerEXT); - INSERT_PROC_ADDRESS(gl, PushGroupMarkerEXT); - INSERT_PROC_ADDRESS(gl, PopGroupMarkerEXT); - - // GL_OES_EGL_image - INSERT_PROC_ADDRESS(gl, EGLImageTargetTexture2DOES); - INSERT_PROC_ADDRESS(gl, EGLImageTargetRenderbufferStorageOES); - - // GL_OES_vertex_array_object - INSERT_PROC_ADDRESS(gl, BindVertexArrayOES); - INSERT_PROC_ADDRESS(gl, DeleteVertexArraysOES); - INSERT_PROC_ADDRESS(gl, GenVertexArraysOES); - INSERT_PROC_ADDRESS(gl, IsVertexArrayOES); - - // GL_KHR_debug - INSERT_PROC_ADDRESS(gl, DebugMessageControlKHR); - INSERT_PROC_ADDRESS(gl, DebugMessageInsertKHR); - INSERT_PROC_ADDRESS(gl, DebugMessageCallbackKHR); - INSERT_PROC_ADDRESS(gl, GetDebugMessageLogKHR); - INSERT_PROC_ADDRESS(gl, PushDebugGroupKHR); - INSERT_PROC_ADDRESS(gl, PopDebugGroupKHR); - INSERT_PROC_ADDRESS(gl, ObjectLabelKHR); - INSERT_PROC_ADDRESS(gl, GetObjectLabelKHR); - INSERT_PROC_ADDRESS(gl, ObjectPtrLabelKHR); - INSERT_PROC_ADDRESS(gl, GetObjectPtrLabelKHR); - INSERT_PROC_ADDRESS(gl, GetPointervKHR); - - // GLES3 core - INSERT_PROC_ADDRESS(gl, ReadBuffer); - INSERT_PROC_ADDRESS(gl, DrawRangeElements); - INSERT_PROC_ADDRESS(gl, TexImage3D); - INSERT_PROC_ADDRESS(gl, TexSubImage3D); - INSERT_PROC_ADDRESS(gl, CopyTexSubImage3D); - INSERT_PROC_ADDRESS(gl, CompressedTexImage3D); - INSERT_PROC_ADDRESS(gl, CompressedTexSubImage3D); - INSERT_PROC_ADDRESS(gl, GenQueries); - INSERT_PROC_ADDRESS(gl, DeleteQueries); - INSERT_PROC_ADDRESS(gl, IsQuery); - INSERT_PROC_ADDRESS(gl, BeginQuery); - INSERT_PROC_ADDRESS(gl, EndQuery); - INSERT_PROC_ADDRESS(gl, GetQueryiv); - INSERT_PROC_ADDRESS(gl, GetQueryObjectuiv); - INSERT_PROC_ADDRESS(gl, UnmapBuffer); - INSERT_PROC_ADDRESS(gl, GetBufferPointerv); - INSERT_PROC_ADDRESS(gl, DrawBuffers); - INSERT_PROC_ADDRESS(gl, UniformMatrix2x3fv); - INSERT_PROC_ADDRESS(gl, UniformMatrix3x2fv); - INSERT_PROC_ADDRESS(gl, UniformMatrix2x4fv); - INSERT_PROC_ADDRESS(gl, UniformMatrix4x2fv); - INSERT_PROC_ADDRESS(gl, UniformMatrix3x4fv); - INSERT_PROC_ADDRESS(gl, UniformMatrix4x3fv); - INSERT_PROC_ADDRESS(gl, BlitFramebuffer); - INSERT_PROC_ADDRESS(gl, RenderbufferStorageMultisample); - INSERT_PROC_ADDRESS(gl, FramebufferTextureLayer); - INSERT_PROC_ADDRESS(gl, MapBufferRange); - INSERT_PROC_ADDRESS(gl, FlushMappedBufferRange); - INSERT_PROC_ADDRESS(gl, BindVertexArray); - INSERT_PROC_ADDRESS(gl, DeleteVertexArrays); - INSERT_PROC_ADDRESS(gl, GenVertexArrays); - INSERT_PROC_ADDRESS(gl, IsVertexArray); - INSERT_PROC_ADDRESS(gl, GetIntegeri_v); - INSERT_PROC_ADDRESS(gl, BeginTransformFeedback); - INSERT_PROC_ADDRESS(gl, EndTransformFeedback); - INSERT_PROC_ADDRESS(gl, BindBufferRange); - INSERT_PROC_ADDRESS(gl, BindBufferBase); - INSERT_PROC_ADDRESS(gl, TransformFeedbackVaryings); - INSERT_PROC_ADDRESS(gl, GetTransformFeedbackVarying); - INSERT_PROC_ADDRESS(gl, VertexAttribIPointer); - INSERT_PROC_ADDRESS(gl, GetVertexAttribIiv); - INSERT_PROC_ADDRESS(gl, GetVertexAttribIuiv); - INSERT_PROC_ADDRESS(gl, VertexAttribI4i); - INSERT_PROC_ADDRESS(gl, VertexAttribI4ui); - INSERT_PROC_ADDRESS(gl, VertexAttribI4iv); - INSERT_PROC_ADDRESS(gl, VertexAttribI4uiv); - INSERT_PROC_ADDRESS(gl, GetUniformuiv); - INSERT_PROC_ADDRESS(gl, GetFragDataLocation); - INSERT_PROC_ADDRESS(gl, Uniform1ui); - INSERT_PROC_ADDRESS(gl, Uniform2ui); - INSERT_PROC_ADDRESS(gl, Uniform3ui); - INSERT_PROC_ADDRESS(gl, Uniform4ui); - INSERT_PROC_ADDRESS(gl, Uniform1uiv); - INSERT_PROC_ADDRESS(gl, Uniform2uiv); - INSERT_PROC_ADDRESS(gl, Uniform3uiv); - INSERT_PROC_ADDRESS(gl, Uniform4uiv); - INSERT_PROC_ADDRESS(gl, ClearBufferiv); - INSERT_PROC_ADDRESS(gl, ClearBufferuiv); - INSERT_PROC_ADDRESS(gl, ClearBufferfv); - INSERT_PROC_ADDRESS(gl, ClearBufferfi); - INSERT_PROC_ADDRESS(gl, GetStringi); - INSERT_PROC_ADDRESS(gl, CopyBufferSubData); - INSERT_PROC_ADDRESS(gl, GetUniformIndices); - INSERT_PROC_ADDRESS(gl, GetActiveUniformsiv); - INSERT_PROC_ADDRESS(gl, GetUniformBlockIndex); - INSERT_PROC_ADDRESS(gl, GetActiveUniformBlockiv); - INSERT_PROC_ADDRESS(gl, GetActiveUniformBlockName); - INSERT_PROC_ADDRESS(gl, UniformBlockBinding); - INSERT_PROC_ADDRESS(gl, DrawArraysInstanced); - INSERT_PROC_ADDRESS(gl, DrawElementsInstanced); - map["glFenceSync"] = - reinterpret_cast<__eglMustCastToProperFunctionPointerType>(gl::FenceSync_); - INSERT_PROC_ADDRESS(gl, IsSync); - INSERT_PROC_ADDRESS(gl, DeleteSync); - INSERT_PROC_ADDRESS(gl, ClientWaitSync); - INSERT_PROC_ADDRESS(gl, WaitSync); - INSERT_PROC_ADDRESS(gl, GetInteger64v); - INSERT_PROC_ADDRESS(gl, GetSynciv); - INSERT_PROC_ADDRESS(gl, GetInteger64i_v); - INSERT_PROC_ADDRESS(gl, GetBufferParameteri64v); - INSERT_PROC_ADDRESS(gl, GenSamplers); - INSERT_PROC_ADDRESS(gl, DeleteSamplers); - INSERT_PROC_ADDRESS(gl, IsSampler); - INSERT_PROC_ADDRESS(gl, BindSampler); - INSERT_PROC_ADDRESS(gl, SamplerParameteri); - INSERT_PROC_ADDRESS(gl, SamplerParameteriv); - INSERT_PROC_ADDRESS(gl, SamplerParameterf); - INSERT_PROC_ADDRESS(gl, SamplerParameterfv); - INSERT_PROC_ADDRESS(gl, GetSamplerParameteriv); - INSERT_PROC_ADDRESS(gl, GetSamplerParameterfv); - INSERT_PROC_ADDRESS(gl, VertexAttribDivisor); - INSERT_PROC_ADDRESS(gl, BindTransformFeedback); - INSERT_PROC_ADDRESS(gl, DeleteTransformFeedbacks); - INSERT_PROC_ADDRESS(gl, GenTransformFeedbacks); - INSERT_PROC_ADDRESS(gl, IsTransformFeedback); - INSERT_PROC_ADDRESS(gl, PauseTransformFeedback); - INSERT_PROC_ADDRESS(gl, ResumeTransformFeedback); - INSERT_PROC_ADDRESS(gl, GetProgramBinary); - INSERT_PROC_ADDRESS(gl, ProgramBinary); - INSERT_PROC_ADDRESS(gl, ProgramParameteri); - INSERT_PROC_ADDRESS(gl, InvalidateFramebuffer); - INSERT_PROC_ADDRESS(gl, InvalidateSubFramebuffer); - INSERT_PROC_ADDRESS(gl, TexStorage2D); - INSERT_PROC_ADDRESS(gl, TexStorage3D); - INSERT_PROC_ADDRESS(gl, GetInternalformativ); - - // EGL 1.0 - INSERT_PROC_ADDRESS(egl, ChooseConfig); - INSERT_PROC_ADDRESS(egl, CopyBuffers); - INSERT_PROC_ADDRESS(egl, CreateContext); - INSERT_PROC_ADDRESS(egl, CreatePbufferSurface); - INSERT_PROC_ADDRESS(egl, CreatePixmapSurface); - INSERT_PROC_ADDRESS(egl, CreateWindowSurface); - INSERT_PROC_ADDRESS(egl, DestroyContext); - INSERT_PROC_ADDRESS(egl, DestroySurface); - INSERT_PROC_ADDRESS(egl, GetConfigAttrib); - INSERT_PROC_ADDRESS(egl, GetConfigs); - INSERT_PROC_ADDRESS(egl, GetCurrentDisplay); - INSERT_PROC_ADDRESS(egl, GetCurrentSurface); - INSERT_PROC_ADDRESS(egl, GetDisplay); - INSERT_PROC_ADDRESS(egl, GetError); - INSERT_PROC_ADDRESS(egl, GetProcAddress); - INSERT_PROC_ADDRESS(egl, Initialize); - INSERT_PROC_ADDRESS(egl, MakeCurrent); - INSERT_PROC_ADDRESS(egl, QueryContext); - INSERT_PROC_ADDRESS(egl, QueryString); - INSERT_PROC_ADDRESS(egl, QuerySurface); - INSERT_PROC_ADDRESS(egl, SwapBuffers); - INSERT_PROC_ADDRESS(egl, Terminate); - INSERT_PROC_ADDRESS(egl, WaitGL); - INSERT_PROC_ADDRESS(egl, WaitNative); - - // EGL 1.1 - INSERT_PROC_ADDRESS(egl, BindTexImage); - INSERT_PROC_ADDRESS(egl, ReleaseTexImage); - INSERT_PROC_ADDRESS(egl, SurfaceAttrib); - INSERT_PROC_ADDRESS(egl, SwapInterval); - - // EGL 1.2 - INSERT_PROC_ADDRESS(egl, BindAPI); - INSERT_PROC_ADDRESS(egl, QueryAPI); - INSERT_PROC_ADDRESS(egl, CreatePbufferFromClientBuffer); - INSERT_PROC_ADDRESS(egl, ReleaseThread); - INSERT_PROC_ADDRESS(egl, WaitClient); - - // EGL 1.4 - INSERT_PROC_ADDRESS(egl, GetCurrentContext); - - // EGL 1.5 - INSERT_PROC_ADDRESS(egl, CreateSync); - INSERT_PROC_ADDRESS(egl, DestroySync); - INSERT_PROC_ADDRESS(egl, ClientWaitSync); - INSERT_PROC_ADDRESS(egl, GetSyncAttrib); - INSERT_PROC_ADDRESS(egl, CreateImage); - INSERT_PROC_ADDRESS(egl, DestroyImage); - INSERT_PROC_ADDRESS(egl, GetPlatformDisplay); - INSERT_PROC_ADDRESS(egl, CreatePlatformWindowSurface); - INSERT_PROC_ADDRESS(egl, CreatePlatformPixmapSurface); - INSERT_PROC_ADDRESS(egl, WaitSync); - - // EGL_ANGLE_query_surface_pointer - INSERT_PROC_ADDRESS(egl, QuerySurfacePointerANGLE); - - // EGL_NV_post_sub_buffer - INSERT_PROC_ADDRESS(egl, PostSubBufferNV); - - // EGL_EXT_platform_base - INSERT_PROC_ADDRESS(egl, GetPlatformDisplayEXT); - - // EGL_EXT_device_query - INSERT_PROC_ADDRESS(egl, QueryDisplayAttribEXT); - INSERT_PROC_ADDRESS(egl, QueryDeviceAttribEXT); - INSERT_PROC_ADDRESS(egl, QueryDeviceStringEXT); - - // EGL_KHR_image_base/EGL_KHR_image - INSERT_PROC_ADDRESS(egl, CreateImageKHR); - INSERT_PROC_ADDRESS(egl, DestroyImageKHR); - - // EGL_EXT_device_creation - INSERT_PROC_ADDRESS(egl, CreateDeviceANGLE); - INSERT_PROC_ADDRESS(egl, ReleaseDeviceANGLE); - -#undef INSERT_PROC_ADDRESS - return map; - }; - - static const ProcAddressMap procAddressMap = generateProcAddressMap(); - - auto iter = procAddressMap.find(procname); - if (iter != procAddressMap.end()) - { - return iter->second; - } - else + if (entry == &g_procTable[g_numProcs] || strcmp(entry->first, procname) != 0) { return nullptr; } -} + return entry->second; +} } diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp b/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp index 6c7e2ffc3d..ee8cdb94dc 100644 --- a/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp +++ b/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp @@ -9,9 +9,12 @@ #include "libGLESv2/entry_points_egl_ext.h" #include "libGLESv2/global_state.h" +#include "libANGLE/Context.h" #include "libANGLE/Display.h" #include "libANGLE/Device.h" #include "libANGLE/Surface.h" +#include "libANGLE/Stream.h" +#include "libANGLE/Thread.h" #include "libANGLE/validationEGL.h" #include "common/debug.h" @@ -24,6 +27,7 @@ EGLBoolean EGLAPIENTRY QuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surfa { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, void **value = 0x%0.8p)", dpy, surface, attribute, value); + Thread *thread = GetCurrentThread(); Display *display = static_cast(dpy); Surface *eglSurface = static_cast(surface); @@ -31,19 +35,19 @@ EGLBoolean EGLAPIENTRY QuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surfa Error error = ValidateSurface(display, eglSurface); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } if (!display->getExtensions().querySurfacePointer) { - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_FALSE; } if (surface == EGL_NO_SURFACE) { - SetGlobalError(Error(EGL_BAD_SURFACE)); + thread->setError(EglBadSurface()); return EGL_FALSE; } @@ -55,24 +59,24 @@ EGLBoolean EGLAPIENTRY QuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surfa case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE: if (!display->getExtensions().surfaceD3DTexture2DShareHandle) { - SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); + thread->setError(EglBadAttribute()); return EGL_FALSE; } break; case EGL_DXGI_KEYED_MUTEX_ANGLE: if (!display->getExtensions().keyedMutex) { - SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); + thread->setError(EglBadAttribute()); return EGL_FALSE; } break; default: - SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); - return EGL_FALSE; + thread->setError(EglBadAttribute()); + return EGL_FALSE; } error = eglSurface->querySurfacePointerANGLE(attribute, value); - SetGlobalError(error); + thread->setError(error); return (error.isError() ? EGL_FALSE : EGL_TRUE); } @@ -81,10 +85,11 @@ EGLBoolean EGLAPIENTRY QuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surfa EGLBoolean EGLAPIENTRY PostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint x = %d, EGLint y = %d, EGLint width = %d, EGLint height = %d)", dpy, surface, x, y, width, height); + Thread *thread = GetCurrentThread(); if (x < 0 || y < 0 || width < 0 || height < 0) { - SetGlobalError(Error(EGL_BAD_PARAMETER)); + thread->setError(EglBadParameter()); return EGL_FALSE; } @@ -94,39 +99,38 @@ EGLBoolean EGLAPIENTRY PostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLin Error error = ValidateSurface(display, eglSurface); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - if (display->isDeviceLost()) + if (display->testDeviceLost()) { - SetGlobalError(Error(EGL_CONTEXT_LOST)); + thread->setError(EglContextLost()); return EGL_FALSE; } if (surface == EGL_NO_SURFACE) { - SetGlobalError(Error(EGL_BAD_SURFACE)); + thread->setError(EglBadSurface()); return EGL_FALSE; } -#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (defined(ANGLE_ENABLE_WINDOWS_STORE) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) // Qt WP: Allow this entry point as a workaround if (!display->getExtensions().postSubBuffer) { // Spec is not clear about how this should be handled. - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } -#endif - error = eglSurface->postSubBuffer(x, y, width, height); + // TODO(jmadill): Validate Surface is bound to the thread. + error = eglSurface->postSubBuffer(thread->getContext(), x, y, width, height); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } @@ -135,215 +139,25 @@ EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_disp { EVENT("(EGLenum platform = %d, void* native_display = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)", platform, native_display, attrib_list); + Thread *thread = GetCurrentThread(); - const ClientExtensions &clientExtensions = Display::getClientExtensions(); - - switch (platform) + Error err = ValidateGetPlatformDisplayEXT(platform, native_display, attrib_list); + thread->setError(err); + if (err.isError()) { - case EGL_PLATFORM_ANGLE_ANGLE: - if (!clientExtensions.platformANGLE) - { - SetGlobalError(Error(EGL_BAD_PARAMETER)); - return EGL_NO_DISPLAY; - } - break; - case EGL_PLATFORM_DEVICE_EXT: - if (!clientExtensions.platformDevice) - { - SetGlobalError(Error(EGL_BAD_PARAMETER, "Platform Device extension is not active")); - return EGL_NO_DISPLAY; - } - break; - default: - SetGlobalError(Error(EGL_BAD_CONFIG)); return EGL_NO_DISPLAY; } + const auto &attribMap = AttributeMap::CreateFromIntArray(attrib_list); if (platform == EGL_PLATFORM_ANGLE_ANGLE) { - EGLint platformType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE; - EGLint deviceType = EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE; - bool majorVersionSpecified = false; - bool minorVersionSpecified = false; - bool enableAutoTrimSpecified = false; - bool deviceTypeSpecified = false; - bool presentPathSpecified = false; - - if (attrib_list) - { - for (const EGLint *curAttrib = attrib_list; curAttrib[0] != EGL_NONE; curAttrib += 2) - { - switch (curAttrib[0]) - { - case EGL_PLATFORM_ANGLE_TYPE_ANGLE: - switch (curAttrib[1]) - { - case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE: - break; - - case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE: - case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE: - if (!clientExtensions.platformANGLED3D) - { - SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); - return EGL_NO_DISPLAY; - } - break; - - case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE: - case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE: - if (!clientExtensions.platformANGLEOpenGL) - { - SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); - return EGL_NO_DISPLAY; - } - break; - - default: - SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); - return EGL_NO_DISPLAY; - } - platformType = curAttrib[1]; - break; - - case EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE: - if (curAttrib[1] != EGL_DONT_CARE) - { - majorVersionSpecified = true; - } - break; - - case EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE: - if (curAttrib[1] != EGL_DONT_CARE) - { - minorVersionSpecified = true; - } - break; - - case EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE: - switch (curAttrib[1]) - { - case EGL_TRUE: - case EGL_FALSE: - break; - default: - SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); - return EGL_NO_DISPLAY; - } - enableAutoTrimSpecified = true; - break; - - case EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE: - if (!clientExtensions.experimentalPresentPath) - { - SetGlobalError( - Error(EGL_BAD_ATTRIBUTE, - "EGL_ANGLE_experimental_present_path extension not active")); - return EGL_NO_DISPLAY; - } - - switch (curAttrib[1]) - { - case EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE: - case EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE: - break; - default: - SetGlobalError( - Error(EGL_BAD_ATTRIBUTE, - "Invalid value for EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE")); - return EGL_NO_DISPLAY; - } - presentPathSpecified = true; - break; - - case EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE: - switch (curAttrib[1]) - { - case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE: - case EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE: - case EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE: - deviceTypeSpecified = true; - break; - - case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE: - // This is a hidden option, accepted by the OpenGL back-end. - break; - - default: - SetGlobalError(Error(EGL_BAD_ATTRIBUTE, - "Invalid value for " - "EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE " - "attrib")); - return EGL_NO_DISPLAY; - } - deviceType = curAttrib[1]; - break; - - default: - break; - } - } - } - - if (!majorVersionSpecified && minorVersionSpecified) - { - SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); - return EGL_NO_DISPLAY; - } - - if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE && - platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) - { - SetGlobalError( - Error(EGL_BAD_ATTRIBUTE, - "EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE requires a device type of " - "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.")); - return EGL_NO_DISPLAY; - } - - if (enableAutoTrimSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) - { - SetGlobalError( - Error(EGL_BAD_ATTRIBUTE, - "EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE requires a device type of " - "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.")); - return EGL_NO_DISPLAY; - } - - if (presentPathSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) - { - SetGlobalError(Error(EGL_BAD_ATTRIBUTE, - "EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE requires a device type of " - "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.")); - return EGL_NO_DISPLAY; - } - - if (deviceTypeSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE && - platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) - { - SetGlobalError( - Error(EGL_BAD_ATTRIBUTE, - "EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE requires a device type of " - "EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE or EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE.")); - return EGL_NO_DISPLAY; - } - - SetGlobalError(Error(EGL_SUCCESS)); - return Display::GetDisplayFromAttribs(native_display, AttributeMap(attrib_list)); + return Display::GetDisplayFromNativeDisplay( + gl::bitCast(native_display), attribMap); } else if (platform == EGL_PLATFORM_DEVICE_EXT) { Device *eglDevice = reinterpret_cast(native_display); - if (eglDevice == nullptr || !Device::IsValidDevice(eglDevice)) - { - SetGlobalError(Error(EGL_BAD_ATTRIBUTE, - "native_display should be a valid EGL device if platform equals " - "EGL_PLATFORM_DEVICE_EXT")); - return EGL_NO_DISPLAY; - } - - SetGlobalError(Error(EGL_SUCCESS)); - return Display::GetDisplayFromDevice(native_display); + return Display::GetDisplayFromDevice(eglDevice, attribMap); } else { @@ -357,11 +171,12 @@ EGLBoolean EGLAPIENTRY QueryDeviceAttribEXT(EGLDeviceEXT device, EGLint attribut { EVENT("(EGLDeviceEXT device = 0x%0.8p, EGLint attribute = %d, EGLAttrib *value = 0x%0.8p)", device, attribute, value); + Thread *thread = GetCurrentThread(); Device *dev = static_cast(device); if (dev == EGL_NO_DEVICE_EXT || !Device::IsValidDevice(dev)) { - SetGlobalError(Error(EGL_BAD_ACCESS)); + thread->setError(EglBadAccess()); return EGL_FALSE; } @@ -370,13 +185,13 @@ EGLBoolean EGLAPIENTRY QueryDeviceAttribEXT(EGLDeviceEXT device, EGLint attribut Display *owningDisplay = dev->getOwningDisplay(); if (owningDisplay != nullptr && !owningDisplay->getExtensions().deviceQuery) { - SetGlobalError(Error(EGL_BAD_ACCESS, - "Device wasn't created using eglCreateDeviceANGLE, and the Display " - "that created it doesn't support device querying")); + thread->setError(EglBadAccess() << "Device wasn't created using eglCreateDeviceANGLE, " + "and the Display that created it doesn't support " + "device querying"); return EGL_FALSE; } - Error error(EGL_SUCCESS); + Error error(NoError()); // validate the attribute parameter switch (attribute) @@ -385,17 +200,17 @@ EGLBoolean EGLAPIENTRY QueryDeviceAttribEXT(EGLDeviceEXT device, EGLint attribut case EGL_D3D9_DEVICE_ANGLE: if (!dev->getExtensions().deviceD3D || dev->getType() != attribute) { - SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); + thread->setError(EglBadAttribute()); return EGL_FALSE; } error = dev->getDevice(value); break; default: - SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); - return EGL_FALSE; + thread->setError(EglBadAttribute()); + return EGL_FALSE; } - SetGlobalError(error); + thread->setError(error); return (error.isError() ? EGL_FALSE : EGL_TRUE); } @@ -404,11 +219,12 @@ const char * EGLAPIENTRY QueryDeviceStringEXT(EGLDeviceEXT device, EGLint name) { EVENT("(EGLDeviceEXT device = 0x%0.8p, EGLint name = %d)", device, name); + Thread *thread = GetCurrentThread(); Device *dev = static_cast(device); if (dev == EGL_NO_DEVICE_EXT || !Device::IsValidDevice(dev)) { - SetGlobalError(Error(EGL_BAD_DEVICE_EXT)); + thread->setError(EglBadDevice()); return nullptr; } @@ -419,11 +235,11 @@ const char * EGLAPIENTRY QueryDeviceStringEXT(EGLDeviceEXT device, EGLint name) result = dev->getExtensionString().c_str(); break; default: - SetGlobalError(Error(EGL_BAD_DEVICE_EXT)); - return nullptr; + thread->setError(EglBadDevice()); + return nullptr; } - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return result; } @@ -432,13 +248,20 @@ EGLBoolean EGLAPIENTRY QueryDisplayAttribEXT(EGLDisplay dpy, EGLint attribute, E { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint attribute = %d, EGLAttrib *value = 0x%0.8p)", dpy, attribute, value); + Thread *thread = GetCurrentThread(); Display *display = static_cast(dpy); - Error error(EGL_SUCCESS); + + Error error = ValidateDisplay(display); + if (error.isError()) + { + thread->setError(error); + return EGL_FALSE; + } if (!display->getExtensions().deviceQuery) { - SetGlobalError(Error(EGL_BAD_ACCESS)); + thread->setError(EglBadAccess()); return EGL_FALSE; } @@ -450,11 +273,11 @@ EGLBoolean EGLAPIENTRY QueryDisplayAttribEXT(EGLDisplay dpy, EGLint attribute, E break; default: - SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); - return EGL_FALSE; + thread->setError(EglBadAttribute()); + return EGL_FALSE; } - SetGlobalError(error); + thread->setError(error); return (error.isError() ? EGL_FALSE : EGL_TRUE); } @@ -468,23 +291,24 @@ ANGLE_EXPORT EGLImageKHR EGLAPIENTRY CreateImageKHR(EGLDisplay dpy, "(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLenum target = 0x%X, " "EGLClientBuffer buffer = 0x%0.8p, const EGLAttrib *attrib_list = 0x%0.8p)", dpy, ctx, target, buffer, attrib_list); + Thread *thread = GetCurrentThread(); Display *display = static_cast(dpy); gl::Context *context = static_cast(ctx); - AttributeMap attributes(attrib_list); + AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list); Error error = ValidateCreateImageKHR(display, context, target, buffer, attributes); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_NO_IMAGE; } Image *image = nullptr; - error = display->createImage(context, target, buffer, attributes, &image); + error = display->createImage(context, target, buffer, attributes, &image); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_NO_IMAGE; } @@ -494,6 +318,7 @@ ANGLE_EXPORT EGLImageKHR EGLAPIENTRY CreateImageKHR(EGLDisplay dpy, ANGLE_EXPORT EGLBoolean EGLAPIENTRY DestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) { EVENT("(EGLDisplay dpy = 0x%0.8p, EGLImage image = 0x%0.8p)", dpy, image); + Thread *thread = GetCurrentThread(); Display *display = static_cast(dpy); Image *img = static_cast(image); @@ -501,7 +326,7 @@ ANGLE_EXPORT EGLBoolean EGLAPIENTRY DestroyImageKHR(EGLDisplay dpy, EGLImageKHR Error error = ValidateDestroyImageKHR(display, img); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } @@ -518,11 +343,12 @@ ANGLE_EXPORT EGLDeviceEXT EGLAPIENTRY CreateDeviceANGLE(EGLint device_type, "(EGLint device_type = %d, void* native_device = 0x%0.8p, const EGLAttrib* attrib_list = " "0x%0.8p)", device_type, native_device, attrib_list); + Thread *thread = GetCurrentThread(); Error error = ValidateCreateDeviceANGLE(device_type, native_device, attrib_list); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_NO_DEVICE_EXT; } @@ -531,7 +357,7 @@ ANGLE_EXPORT EGLDeviceEXT EGLAPIENTRY CreateDeviceANGLE(EGLint device_type, if (error.isError()) { ASSERT(device == nullptr); - SetGlobalError(error); + thread->setError(error); return EGL_NO_DEVICE_EXT; } @@ -541,13 +367,14 @@ ANGLE_EXPORT EGLDeviceEXT EGLAPIENTRY CreateDeviceANGLE(EGLint device_type, ANGLE_EXPORT EGLBoolean EGLAPIENTRY ReleaseDeviceANGLE(EGLDeviceEXT device) { EVENT("(EGLDeviceEXT device = 0x%0.8p)", device); + Thread *thread = GetCurrentThread(); Device *dev = static_cast(device); Error error = ValidateReleaseDeviceANGLE(dev); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } @@ -555,4 +382,475 @@ ANGLE_EXPORT EGLBoolean EGLAPIENTRY ReleaseDeviceANGLE(EGLDeviceEXT device) return EGL_TRUE; } + +// EGL_KHR_stream +EGLStreamKHR EGLAPIENTRY CreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_list) +{ + EVENT("(EGLDisplay dpy = 0x%0.8p, const EGLAttrib* attrib_list = 0x%0.8p)", dpy, attrib_list); + Thread *thread = GetCurrentThread(); + + Display *display = static_cast(dpy); + AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list); + + Error error = ValidateCreateStreamKHR(display, attributes); + if (error.isError()) + { + thread->setError(error); + return EGL_NO_STREAM_KHR; + } + + Stream *stream; + error = display->createStream(attributes, &stream); + if (error.isError()) + { + thread->setError(error); + return EGL_NO_STREAM_KHR; + } + + thread->setError(error); + return static_cast(stream); } + +EGLBoolean EGLAPIENTRY DestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream) +{ + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR = 0x%0.8p)", dpy, stream); + Thread *thread = GetCurrentThread(); + + Display *display = static_cast(dpy); + Stream *streamObject = static_cast(stream); + + Error error = ValidateDestroyStreamKHR(display, streamObject); + if (error.isError()) + { + thread->setError(error); + return EGL_FALSE; + } + + display->destroyStream(streamObject); + thread->setError(error); + return EGL_TRUE; +} + +EGLBoolean EGLAPIENTRY StreamAttribKHR(EGLDisplay dpy, + EGLStreamKHR stream, + EGLenum attribute, + EGLint value) +{ + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, EGLenum attribute = 0x%X, " + "EGLint value = 0x%X)", + dpy, stream, attribute, value); + Thread *thread = GetCurrentThread(); + + Display *display = static_cast(dpy); + Stream *streamObject = static_cast(stream); + + Error error = ValidateStreamAttribKHR(display, streamObject, attribute, value); + if (error.isError()) + { + thread->setError(error); + return EGL_FALSE; + } + + switch (attribute) + { + case EGL_CONSUMER_LATENCY_USEC_KHR: + streamObject->setConsumerLatency(value); + break; + case EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR: + streamObject->setConsumerAcquireTimeout(value); + break; + default: + UNREACHABLE(); + } + + thread->setError(error); + return EGL_TRUE; +} + +EGLBoolean EGLAPIENTRY QueryStreamKHR(EGLDisplay dpy, + EGLStreamKHR stream, + EGLenum attribute, + EGLint *value) +{ + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, EGLenum attribute = 0x%X, " + "EGLint value = 0x%0.8p)", + dpy, stream, attribute, value); + Thread *thread = GetCurrentThread(); + + Display *display = static_cast(dpy); + Stream *streamObject = static_cast(stream); + + Error error = ValidateQueryStreamKHR(display, streamObject, attribute, value); + if (error.isError()) + { + thread->setError(error); + return EGL_FALSE; + } + + switch (attribute) + { + case EGL_STREAM_STATE_KHR: + *value = streamObject->getState(); + break; + case EGL_CONSUMER_LATENCY_USEC_KHR: + *value = streamObject->getConsumerLatency(); + break; + case EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR: + *value = streamObject->getConsumerAcquireTimeout(); + break; + default: + UNREACHABLE(); + } + + thread->setError(error); + return EGL_TRUE; +} + +EGLBoolean EGLAPIENTRY QueryStreamu64KHR(EGLDisplay dpy, + EGLStreamKHR stream, + EGLenum attribute, + EGLuint64KHR *value) +{ + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, EGLenum attribute = 0x%X, " + "EGLuint64KHR value = 0x%0.8p)", + dpy, stream, attribute, value); + Thread *thread = GetCurrentThread(); + + Display *display = static_cast(dpy); + Stream *streamObject = static_cast(stream); + + Error error = ValidateQueryStreamu64KHR(display, streamObject, attribute, value); + if (error.isError()) + { + thread->setError(error); + return EGL_FALSE; + } + + switch (attribute) + { + case EGL_PRODUCER_FRAME_KHR: + *value = streamObject->getProducerFrame(); + break; + case EGL_CONSUMER_FRAME_KHR: + *value = streamObject->getConsumerFrame(); + break; + default: + UNREACHABLE(); + } + + thread->setError(error); + return EGL_TRUE; +} + +EGLBoolean EGLAPIENTRY StreamConsumerGLTextureExternalKHR(EGLDisplay dpy, EGLStreamKHR stream) +{ + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR = 0x%0.8p)", dpy, stream); + Thread *thread = GetCurrentThread(); + + Display *display = static_cast(dpy); + Stream *streamObject = static_cast(stream); + gl::Context *context = gl::GetValidGlobalContext(); + + Error error = ValidateStreamConsumerGLTextureExternalKHR(display, context, streamObject); + if (error.isError()) + { + thread->setError(error); + return EGL_FALSE; + } + + error = streamObject->createConsumerGLTextureExternal(AttributeMap(), context); + if (error.isError()) + { + thread->setError(error); + return EGL_FALSE; + } + + thread->setError(error); + return EGL_TRUE; +} + +EGLBoolean EGLAPIENTRY StreamConsumerAcquireKHR(EGLDisplay dpy, EGLStreamKHR stream) +{ + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR = 0x%0.8p)", dpy, stream); + Thread *thread = GetCurrentThread(); + + Display *display = static_cast(dpy); + Stream *streamObject = static_cast(stream); + gl::Context *context = gl::GetValidGlobalContext(); + + Error error = ValidateStreamConsumerAcquireKHR(display, context, streamObject); + if (error.isError()) + { + thread->setError(error); + return EGL_FALSE; + } + + error = streamObject->consumerAcquire(context); + if (error.isError()) + { + thread->setError(error); + return EGL_FALSE; + } + + thread->setError(error); + return EGL_TRUE; +} + +EGLBoolean EGLAPIENTRY StreamConsumerReleaseKHR(EGLDisplay dpy, EGLStreamKHR stream) +{ + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR = 0x%0.8p)", dpy, stream); + Thread *thread = GetCurrentThread(); + + Display *display = static_cast(dpy); + Stream *streamObject = static_cast(stream); + gl::Context *context = gl::GetValidGlobalContext(); + + Error error = ValidateStreamConsumerReleaseKHR(display, context, streamObject); + if (error.isError()) + { + thread->setError(error); + return EGL_FALSE; + } + + error = streamObject->consumerRelease(context); + if (error.isError()) + { + thread->setError(error); + return EGL_FALSE; + } + + thread->setError(error); + return EGL_TRUE; +} + +EGLBoolean EGLAPIENTRY StreamConsumerGLTextureExternalAttribsNV(EGLDisplay dpy, + EGLStreamKHR stream, + const EGLAttrib *attrib_list) +{ + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, EGLAttrib attrib_list = 0x%0.8p", + dpy, stream, attrib_list); + Thread *thread = GetCurrentThread(); + + Display *display = static_cast(dpy); + Stream *streamObject = static_cast(stream); + gl::Context *context = gl::GetValidGlobalContext(); + AttributeMap attributes = AttributeMap::CreateFromAttribArray(attrib_list); + + Error error = ValidateStreamConsumerGLTextureExternalAttribsNV(display, context, streamObject, + attributes); + if (error.isError()) + { + thread->setError(error); + return EGL_FALSE; + } + + error = streamObject->createConsumerGLTextureExternal(attributes, context); + if (error.isError()) + { + thread->setError(error); + return EGL_FALSE; + } + + thread->setError(error); + return EGL_TRUE; +} + +EGLBoolean EGLAPIENTRY CreateStreamProducerD3DTextureNV12ANGLE(EGLDisplay dpy, + EGLStreamKHR stream, + const EGLAttrib *attrib_list) +{ + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, EGLAttrib attrib_list = 0x%0.8p", + dpy, stream, attrib_list); + Thread *thread = GetCurrentThread(); + + Display *display = static_cast(dpy); + Stream *streamObject = static_cast(stream); + AttributeMap attributes = AttributeMap::CreateFromAttribArray(attrib_list); + + Error error = + ValidateCreateStreamProducerD3DTextureNV12ANGLE(display, streamObject, attributes); + if (error.isError()) + { + thread->setError(error); + return EGL_FALSE; + } + + error = streamObject->createProducerD3D11TextureNV12(attributes); + if (error.isError()) + { + thread->setError(error); + return EGL_FALSE; + } + + thread->setError(error); + return EGL_TRUE; +} + +EGLBoolean EGLAPIENTRY StreamPostD3DTextureNV12ANGLE(EGLDisplay dpy, + EGLStreamKHR stream, + void *texture, + const EGLAttrib *attrib_list) +{ + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, void* texture = 0x%0.8p, " + "EGLAttrib attrib_list = 0x%0.8p", + dpy, stream, texture, attrib_list); + Thread *thread = GetCurrentThread(); + + Display *display = static_cast(dpy); + Stream *streamObject = static_cast(stream); + AttributeMap attributes = AttributeMap::CreateFromAttribArray(attrib_list); + + Error error = ValidateStreamPostD3DTextureNV12ANGLE(display, streamObject, texture, attributes); + if (error.isError()) + { + thread->setError(error); + return EGL_FALSE; + } + + error = streamObject->postD3D11NV12Texture(texture, attributes); + if (error.isError()) + { + thread->setError(error); + return EGL_FALSE; + } + + thread->setError(error); + return EGL_TRUE; +} + +EGLBoolean EGLAPIENTRY GetSyncValuesCHROMIUM(EGLDisplay dpy, + EGLSurface surface, + EGLuint64KHR *ust, + EGLuint64KHR *msc, + EGLuint64KHR *sbc) +{ + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLuint64KHR* ust = 0x%0.8p, " + "EGLuint64KHR* msc = 0x%0.8p, EGLuint64KHR* sbc = 0x%0.8p", + dpy, surface, ust, msc, sbc); + Thread *thread = GetCurrentThread(); + + Display *display = static_cast(dpy); + Surface *eglSurface = static_cast(surface); + + Error error = ValidateGetSyncValuesCHROMIUM(display, eglSurface, ust, msc, sbc); + if (error.isError()) + { + thread->setError(error); + return EGL_FALSE; + } + + error = eglSurface->getSyncValues(ust, msc, sbc); + if (error.isError()) + { + thread->setError(error); + return EGL_FALSE; + } + + thread->setError(error); + return EGL_TRUE; +} + +ANGLE_EXPORT EGLBoolean SwapBuffersWithDamageEXT(EGLDisplay dpy, + EGLSurface surface, + EGLint *rects, + EGLint n_rects) +{ + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint *rects = 0x%0.8p, EGLint " + "n_rects = %d)", + dpy, surface, rects, n_rects); + Thread *thread = GetCurrentThread(); + + Display *display = static_cast(dpy); + Surface *eglSurface = static_cast(surface); + + Error error = ValidateSwapBuffersWithDamageEXT(display, eglSurface, rects, n_rects); + if (error.isError()) + { + thread->setError(error); + return EGL_FALSE; + } + + error = eglSurface->swapWithDamage(thread->getContext(), rects, n_rects); + if (error.isError()) + { + thread->setError(error); + return EGL_FALSE; + } + + return EGL_TRUE; +} + +EGLint EGLAPIENTRY ProgramCacheGetAttribANGLE(EGLDisplay dpy, EGLenum attrib) +{ + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLenum attrib = 0x%X)", dpy, attrib); + + Display *display = static_cast(dpy); + Thread *thread = GetCurrentThread(); + + ANGLE_EGL_TRY_RETURN(thread, ValidateProgramCacheGetAttribANGLE(display, attrib), 0); + + return display->programCacheGetAttrib(attrib); +} + +void EGLAPIENTRY ProgramCacheQueryANGLE(EGLDisplay dpy, + EGLint index, + void *key, + EGLint *keysize, + void *binary, + EGLint *binarysize) +{ + EVENT( + "(EGLDisplay dpy = 0x%0.8p, EGLint index = %d, void *key = 0x%0.8p, EGLint *keysize = " + "0x%0.8p, void *binary = 0x%0.8p, EGLint *size = 0x%0.8p)", + dpy, index, key, keysize, binary, binarysize); + + Display *display = static_cast(dpy); + Thread *thread = GetCurrentThread(); + + ANGLE_EGL_TRY(thread, + ValidateProgramCacheQueryANGLE(display, index, key, keysize, binary, binarysize)); + + ANGLE_EGL_TRY(thread, display->programCacheQuery(index, key, keysize, binary, binarysize)); +} + +void EGLAPIENTRY ProgramCachePopulateANGLE(EGLDisplay dpy, + const void *key, + EGLint keysize, + const void *binary, + EGLint binarysize) +{ + EVENT( + "(EGLDisplay dpy = 0x%0.8p, void *key = 0x%0.8p, EGLint keysize = %d, void *binary = " + "0x%0.8p, EGLint *size = 0x%0.8p)", + dpy, key, keysize, binary, binarysize); + + Display *display = static_cast(dpy); + Thread *thread = GetCurrentThread(); + + ANGLE_EGL_TRY(thread, + ValidateProgramCachePopulateANGLE(display, key, keysize, binary, binarysize)); + + ANGLE_EGL_TRY(thread, display->programCachePopulate(key, keysize, binary, binarysize)); +} + +EGLint EGLAPIENTRY ProgramCacheResizeANGLE(EGLDisplay dpy, EGLint limit, EGLenum mode) +{ + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint limit = %d, EGLenum mode = 0x%X)", dpy, limit, mode); + + Display *display = static_cast(dpy); + Thread *thread = GetCurrentThread(); + + ANGLE_EGL_TRY_RETURN(thread, ValidateProgramCacheResizeANGLE(display, limit, mode), 0); + + return display->programCacheResize(limit, mode); +} + +} // namespace egl diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.h b/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.h index d64fa6e483..3cde6ec9c6 100644 --- a/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.h +++ b/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.h @@ -43,6 +43,71 @@ ANGLE_EXPORT EGLDeviceEXT EGLAPIENTRY CreateDeviceANGLE(EGLint device_type, void *native_device, const EGLAttrib *attrib_list); ANGLE_EXPORT EGLBoolean EGLAPIENTRY ReleaseDeviceANGLE(EGLDeviceEXT device); -} + +// EGL_KHR_stream +ANGLE_EXPORT EGLStreamKHR EGLAPIENTRY CreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_list); +ANGLE_EXPORT EGLBoolean EGLAPIENTRY DestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream); +ANGLE_EXPORT EGLBoolean EGLAPIENTRY StreamAttribKHR(EGLDisplay dpy, + EGLStreamKHR stream, + EGLenum attribute, + EGLint value); +ANGLE_EXPORT EGLBoolean EGLAPIENTRY QueryStreamKHR(EGLDisplay dpy, + EGLStreamKHR stream, + EGLenum attribute, + EGLint *value); +ANGLE_EXPORT EGLBoolean EGLAPIENTRY QueryStreamu64KHR(EGLDisplay dpy, + EGLStreamKHR stream, + EGLenum attribute, + EGLuint64KHR *value); + +// EGL_KHR_stream_consumer_gltexture +ANGLE_EXPORT EGLBoolean EGLAPIENTRY StreamConsumerGLTextureExternalKHR(EGLDisplay dpy, + EGLStreamKHR stream); +ANGLE_EXPORT EGLBoolean EGLAPIENTRY StreamConsumerAcquireKHR(EGLDisplay dpy, EGLStreamKHR stream); +ANGLE_EXPORT EGLBoolean EGLAPIENTRY StreamConsumerReleaseKHR(EGLDisplay dpy, EGLStreamKHR stream); +ANGLE_EXPORT EGLBoolean EGLAPIENTRY +StreamConsumerGLTextureExternalAttribsNV(EGLDisplay dpy, + EGLStreamKHR stream, + const EGLAttrib *attrib_list); + +// EGL_ANGLE_stream_producer_d3d_texture_nv12 +ANGLE_EXPORT EGLBoolean EGLAPIENTRY +CreateStreamProducerD3DTextureNV12ANGLE(EGLDisplay dpy, + EGLStreamKHR stream, + const EGLAttrib *attrib_list); +ANGLE_EXPORT EGLBoolean EGLAPIENTRY StreamPostD3DTextureNV12ANGLE(EGLDisplay dpy, + EGLStreamKHR stream, + void *texture, + const EGLAttrib *attrib_list); + +// EGL_CHROMIUM_get_sync_values +ANGLE_EXPORT EGLBoolean EGLAPIENTRY GetSyncValuesCHROMIUM(EGLDisplay dpy, + EGLSurface surface, + EGLuint64KHR *ust, + EGLuint64KHR *msc, + EGLuint64KHR *sbc); + +// EGL_EXT_swap_buffers_with_damage +ANGLE_EXPORT EGLBoolean SwapBuffersWithDamageEXT(EGLDisplay dpy, + EGLSurface surface, + EGLint *rects, + EGLint n_rects); + +// +ANGLE_EXPORT EGLint EGLAPIENTRY ProgramCacheGetAttribANGLE(EGLDisplay dpy, EGLenum attrib); +ANGLE_EXPORT void EGLAPIENTRY ProgramCacheQueryANGLE(EGLDisplay dpy, + EGLint index, + void *key, + EGLint *keysize, + void *binary, + EGLint *binarysize); +ANGLE_EXPORT void EGLAPIENTRY ProgramCachePopulateANGLE(EGLDisplay dpy, + const void *key, + EGLint keysize, + const void *binary, + EGLint binarysize); +ANGLE_EXPORT EGLint EGLAPIENTRY ProgramCacheResizeANGLE(EGLDisplay dpy, EGLint limit, EGLenum mode); + +} // namespace egl #endif // LIBGLESV2_ENTRYPOINTSEGLEXT_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0.cpp b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0.cpp deleted file mode 100644 index 336b320ba5..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0.cpp +++ /dev/null @@ -1,4155 +0,0 @@ -// -// Copyright(c) 2014 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// entry_points_gles_2_0.cpp : Implements the GLES 2.0 entry points. - -#include "libGLESv2/entry_points_gles_2_0.h" -#include "libGLESv2/global_state.h" - -#include "libANGLE/formatutils.h" -#include "libANGLE/Buffer.h" -#include "libANGLE/Compiler.h" -#include "libANGLE/Context.h" -#include "libANGLE/Error.h" -#include "libANGLE/Framebuffer.h" -#include "libANGLE/Renderbuffer.h" -#include "libANGLE/Shader.h" -#include "libANGLE/Program.h" -#include "libANGLE/Texture.h" -#include "libANGLE/VertexArray.h" -#include "libANGLE/VertexAttribute.h" -#include "libANGLE/FramebufferAttachment.h" - -#include "libANGLE/validationES.h" -#include "libANGLE/validationES2.h" -#include "libANGLE/validationES3.h" -#include "libANGLE/queryconversions.h" - -#include "common/debug.h" -#include "common/utilities.h" -#include "common/version.h" - -namespace gl -{ - -void GL_APIENTRY ActiveTexture(GLenum texture) -{ - EVENT("(GLenum texture = 0x%X)", texture); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - context->getState().setActiveSampler(texture - GL_TEXTURE0); - } -} - -void GL_APIENTRY AttachShader(GLuint program, GLuint shader) -{ - EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader); - - Context *context = GetValidGlobalContext(); - if (context) - { - Program *programObject = GetValidProgram(context, program); - if (!programObject) - { - return; - } - - Shader *shaderObject = GetValidShader(context, shader); - if (!shaderObject) - { - return; - } - - if (!programObject->attachShader(shaderObject)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - } -} - -void GL_APIENTRY BindAttribLocation(GLuint program, GLuint index, const GLchar* name) -{ - EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (index >= MAX_VERTEX_ATTRIBS) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - Program *programObject = GetValidProgram(context, program); - - if (!programObject) - { - return; - } - - if (strncmp(name, "gl_", 3) == 0) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - programObject->bindAttributeLocation(index, name); - } -} - -void GL_APIENTRY BindBuffer(GLenum target, GLuint buffer) -{ - EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidBufferTarget(context, target)) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - switch (target) - { - case GL_ARRAY_BUFFER: - context->bindArrayBuffer(buffer); - return; - case GL_ELEMENT_ARRAY_BUFFER: - context->bindElementArrayBuffer(buffer); - return; - case GL_COPY_READ_BUFFER: - context->bindCopyReadBuffer(buffer); - return; - case GL_COPY_WRITE_BUFFER: - context->bindCopyWriteBuffer(buffer); - return; - case GL_PIXEL_PACK_BUFFER: - context->bindPixelPackBuffer(buffer); - return; - case GL_PIXEL_UNPACK_BUFFER: - context->bindPixelUnpackBuffer(buffer); - return; - case GL_UNIFORM_BUFFER: - context->bindGenericUniformBuffer(buffer); - return; - case GL_TRANSFORM_FEEDBACK_BUFFER: - context->bindGenericTransformFeedbackBuffer(buffer); - return; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - } -} - -void GL_APIENTRY BindFramebuffer(GLenum target, GLuint framebuffer) -{ - EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidFramebufferTarget(target)) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER) - { - context->bindReadFramebuffer(framebuffer); - } - - if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER) - { - context->bindDrawFramebuffer(framebuffer); - } - } -} - -void GL_APIENTRY BindRenderbuffer(GLenum target, GLuint renderbuffer) -{ - EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (target != GL_RENDERBUFFER) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - context->bindRenderbuffer(renderbuffer); - } -} - -void GL_APIENTRY BindTexture(GLenum target, GLuint texture) -{ - EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture); - - Context *context = GetValidGlobalContext(); - if (context) - { - Texture *textureObject = context->getTexture(texture); - - if (textureObject && textureObject->getTarget() != target && texture != 0) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - switch (target) - { - case GL_TEXTURE_2D: - case GL_TEXTURE_CUBE_MAP: - break; - - case GL_TEXTURE_3D: - case GL_TEXTURE_2D_ARRAY: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - context->bindTexture(target, texture); - } -} - -void GL_APIENTRY BlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) -{ - EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)", - red, green, blue, alpha); - - Context *context = GetValidGlobalContext(); - if (context) - { - context->getState().setBlendColor(clamp01(red), clamp01(green), clamp01(blue), clamp01(alpha)); - } -} - -void GL_APIENTRY BlendEquation(GLenum mode) -{ - BlendEquationSeparate(mode, mode); -} - -void GL_APIENTRY BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) -{ - EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha); - - Context *context = GetValidGlobalContext(); - if (context) - { - switch (modeRGB) - { - case GL_FUNC_ADD: - case GL_FUNC_SUBTRACT: - case GL_FUNC_REVERSE_SUBTRACT: - case GL_MIN: - case GL_MAX: - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - switch (modeAlpha) - { - case GL_FUNC_ADD: - case GL_FUNC_SUBTRACT: - case GL_FUNC_REVERSE_SUBTRACT: - case GL_MIN: - case GL_MAX: - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - context->getState().setBlendEquation(modeRGB, modeAlpha); - } -} - -void GL_APIENTRY BlendFunc(GLenum sfactor, GLenum dfactor) -{ - BlendFuncSeparate(sfactor, dfactor, sfactor, dfactor); -} - -void GL_APIENTRY BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) -{ - EVENT("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)", - srcRGB, dstRGB, srcAlpha, dstAlpha); - - Context *context = GetValidGlobalContext(); - if (context) - { - switch (srcRGB) - { - case GL_ZERO: - case GL_ONE: - case GL_SRC_COLOR: - case GL_ONE_MINUS_SRC_COLOR: - case GL_DST_COLOR: - case GL_ONE_MINUS_DST_COLOR: - case GL_SRC_ALPHA: - case GL_ONE_MINUS_SRC_ALPHA: - case GL_DST_ALPHA: - case GL_ONE_MINUS_DST_ALPHA: - case GL_CONSTANT_COLOR: - case GL_ONE_MINUS_CONSTANT_COLOR: - case GL_CONSTANT_ALPHA: - case GL_ONE_MINUS_CONSTANT_ALPHA: - case GL_SRC_ALPHA_SATURATE: - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - switch (dstRGB) - { - case GL_ZERO: - case GL_ONE: - case GL_SRC_COLOR: - case GL_ONE_MINUS_SRC_COLOR: - case GL_DST_COLOR: - case GL_ONE_MINUS_DST_COLOR: - case GL_SRC_ALPHA: - case GL_ONE_MINUS_SRC_ALPHA: - case GL_DST_ALPHA: - case GL_ONE_MINUS_DST_ALPHA: - case GL_CONSTANT_COLOR: - case GL_ONE_MINUS_CONSTANT_COLOR: - case GL_CONSTANT_ALPHA: - case GL_ONE_MINUS_CONSTANT_ALPHA: - break; - - case GL_SRC_ALPHA_SATURATE: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - switch (srcAlpha) - { - case GL_ZERO: - case GL_ONE: - case GL_SRC_COLOR: - case GL_ONE_MINUS_SRC_COLOR: - case GL_DST_COLOR: - case GL_ONE_MINUS_DST_COLOR: - case GL_SRC_ALPHA: - case GL_ONE_MINUS_SRC_ALPHA: - case GL_DST_ALPHA: - case GL_ONE_MINUS_DST_ALPHA: - case GL_CONSTANT_COLOR: - case GL_ONE_MINUS_CONSTANT_COLOR: - case GL_CONSTANT_ALPHA: - case GL_ONE_MINUS_CONSTANT_ALPHA: - case GL_SRC_ALPHA_SATURATE: - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - switch (dstAlpha) - { - case GL_ZERO: - case GL_ONE: - case GL_SRC_COLOR: - case GL_ONE_MINUS_SRC_COLOR: - case GL_DST_COLOR: - case GL_ONE_MINUS_DST_COLOR: - case GL_SRC_ALPHA: - case GL_ONE_MINUS_SRC_ALPHA: - case GL_DST_ALPHA: - case GL_ONE_MINUS_DST_ALPHA: - case GL_CONSTANT_COLOR: - case GL_ONE_MINUS_CONSTANT_COLOR: - case GL_CONSTANT_ALPHA: - case GL_ONE_MINUS_CONSTANT_ALPHA: - break; - - case GL_SRC_ALPHA_SATURATE: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc) - { - bool constantColorUsed = - (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR || - dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR); - - bool constantAlphaUsed = - (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA || - dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA); - - if (constantColorUsed && constantAlphaUsed) - { - ERR( - "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and " - "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this " - "implementation."); - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - } - - context->getState().setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha); - } -} - -void GL_APIENTRY BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) -{ - EVENT("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)", - target, size, data, usage); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (size < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - switch (usage) - { - case GL_STREAM_DRAW: - case GL_STATIC_DRAW: - case GL_DYNAMIC_DRAW: - break; - - case GL_STREAM_READ: - case GL_STREAM_COPY: - case GL_STATIC_READ: - case GL_STATIC_COPY: - case GL_DYNAMIC_READ: - case GL_DYNAMIC_COPY: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - if (!ValidBufferTarget(context, target)) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - Buffer *buffer = context->getState().getTargetBuffer(target); - - if (!buffer) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - Error error = buffer->bufferData(data, size, usage); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -void GL_APIENTRY BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) -{ - EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)", - target, offset, size, data); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (size < 0 || offset < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - if (!ValidBufferTarget(context, target)) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - Buffer *buffer = context->getState().getTargetBuffer(target); - - if (!buffer) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (buffer->isMapped()) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - // Check for possible overflow of size + offset - if (!rx::IsUnsignedAdditionSafe(size, offset)) - { - context->recordError(Error(GL_OUT_OF_MEMORY)); - return; - } - - if (size + offset > buffer->getSize()) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - if (data == NULL) - { - return; - } - - Error error = buffer->bufferSubData(data, size, offset); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -GLenum GL_APIENTRY CheckFramebufferStatus(GLenum target) -{ - EVENT("(GLenum target = 0x%X)", target); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidFramebufferTarget(target)) - { - context->recordError(Error(GL_INVALID_ENUM)); - return 0; - } - - Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); - ASSERT(framebuffer); - - return framebuffer->checkStatus(context->getData()); - } - - return 0; -} - -void GL_APIENTRY Clear(GLbitfield mask) -{ - EVENT("(GLbitfield mask = 0x%X)", mask); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!context->skipValidation() && !ValidateClear(context, mask)) - { - return; - } - - context->clear(mask); - } -} - -void GL_APIENTRY ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) -{ - EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)", - red, green, blue, alpha); - - Context *context = GetValidGlobalContext(); - if (context) - { - context->getState().setColorClearValue(red, green, blue, alpha); - } -} - -void GL_APIENTRY ClearDepthf(GLclampf depth) -{ - EVENT("(GLclampf depth = %f)", depth); - - Context *context = GetValidGlobalContext(); - if (context) - { - context->getState().setDepthClearValue(depth); - } -} - -void GL_APIENTRY ClearStencil(GLint s) -{ - EVENT("(GLint s = %d)", s); - - Context *context = GetValidGlobalContext(); - if (context) - { - context->getState().setStencilClearValue(s); - } -} - -void GL_APIENTRY ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) -{ - EVENT("(GLboolean red = %d, GLboolean green = %u, GLboolean blue = %u, GLboolean alpha = %u)", - red, green, blue, alpha); - - Context *context = GetValidGlobalContext(); - if (context) - { - context->getState().setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE); - } -} - -void GL_APIENTRY CompileShader(GLuint shader) -{ - EVENT("(GLuint shader = %d)", shader); - - Context *context = GetValidGlobalContext(); - if (context) - { - Shader *shaderObject = GetValidShader(context, shader); - if (!shaderObject) - { - return; - } - shaderObject->compile(context->getCompiler()); - } -} - -void GL_APIENTRY CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, - GLint border, GLsizei imageSize, const GLvoid* data) -{ - EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, " - "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)", - target, level, internalformat, width, height, border, imageSize, data); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3 && - !ValidateES2TexImageParameters(context, target, level, internalformat, true, false, - 0, 0, width, height, border, GL_NONE, GL_NONE, data)) - { - return; - } - - if (context->getClientVersion() >= 3 && - !ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0, - 0, 0, width, height, 1, border, GL_NONE, GL_NONE, - data)) - { - return; - } - - const InternalFormat &formatInfo = GetInternalFormatInfo(internalformat); - if (imageSize < 0 || static_cast(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height)) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - Extents size(width, height, 1); - Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); - Error error = - texture->setCompressedImage(context, target, level, internalformat, size, imageSize, - reinterpret_cast(data)); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -void GL_APIENTRY CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - GLenum format, GLsizei imageSize, const GLvoid* data) -{ - EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " - "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, " - "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)", - target, level, xoffset, yoffset, width, height, format, imageSize, data); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3 && - !ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, - xoffset, yoffset, width, height, 0, GL_NONE, GL_NONE, data)) - { - return; - } - - if (context->getClientVersion() >= 3 && - !ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset, - yoffset, 0, width, height, 1, 0, GL_NONE, GL_NONE, - data)) - { - return; - } - - const InternalFormat &formatInfo = GetInternalFormatInfo(format); - if (imageSize < 0 || static_cast(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height)) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - Box area(xoffset, yoffset, 0, width, height, 1); - Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); - Error error = - texture->setCompressedSubImage(context, target, level, area, format, imageSize, - reinterpret_cast(data)); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -void GL_APIENTRY CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) -{ - EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, " - "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)", - target, level, internalformat, x, y, width, height, border); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!context->skipValidation() && - !ValidateCopyTexImage2D(context, target, level, internalformat, x, y, width, height, - border)) - { - return; - } - context->copyTexImage2D(target, level, internalformat, x, y, width, height, border); - } -} - -void GL_APIENTRY CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) -{ - EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " - "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", - target, level, xoffset, yoffset, x, y, width, height); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!context->skipValidation() && - !ValidateCopyTexSubImage2D(context, target, level, xoffset, yoffset, x, y, width, - height)) - { - return; - } - - context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); - } -} - -GLuint GL_APIENTRY CreateProgram(void) -{ - EVENT("()"); - - Context *context = GetValidGlobalContext(); - if (context) - { - return context->createProgram(); - } - - return 0; -} - -GLuint GL_APIENTRY CreateShader(GLenum type) -{ - EVENT("(GLenum type = 0x%X)", type); - - Context *context = GetValidGlobalContext(); - if (context) - { - switch (type) - { - case GL_FRAGMENT_SHADER: - case GL_VERTEX_SHADER: - return context->createShader(type); - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return 0; - } - } - - return 0; -} - -void GL_APIENTRY CullFace(GLenum mode) -{ - EVENT("(GLenum mode = 0x%X)", mode); - - Context *context = GetValidGlobalContext(); - if (context) - { - switch (mode) - { - case GL_FRONT: - case GL_BACK: - case GL_FRONT_AND_BACK: - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - context->getState().setCullMode(mode); - } -} - -void GL_APIENTRY DeleteBuffers(GLsizei n, const GLuint* buffers) -{ - EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (n < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - for (int i = 0; i < n; i++) - { - context->deleteBuffer(buffers[i]); - } - } -} - -void GL_APIENTRY DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) -{ - EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (n < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - for (int i = 0; i < n; i++) - { - if (framebuffers[i] != 0) - { - context->deleteFramebuffer(framebuffers[i]); - } - } - } -} - -void GL_APIENTRY DeleteProgram(GLuint program) -{ - EVENT("(GLuint program = %d)", program); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (program == 0) - { - return; - } - - if (!context->getProgram(program)) - { - if(context->getShader(program)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - else - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - } - - context->deleteProgram(program); - } -} - -void GL_APIENTRY DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) -{ - EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (n < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - for (int i = 0; i < n; i++) - { - context->deleteRenderbuffer(renderbuffers[i]); - } - } -} - -void GL_APIENTRY DeleteShader(GLuint shader) -{ - EVENT("(GLuint shader = %d)", shader); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (shader == 0) - { - return; - } - - if (!context->getShader(shader)) - { - if(context->getProgram(shader)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - else - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - } - - context->deleteShader(shader); - } -} - -void GL_APIENTRY DeleteTextures(GLsizei n, const GLuint* textures) -{ - EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (n < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - for (int i = 0; i < n; i++) - { - if (textures[i] != 0) - { - context->deleteTexture(textures[i]); - } - } - } -} - -void GL_APIENTRY DepthFunc(GLenum func) -{ - EVENT("(GLenum func = 0x%X)", func); - - Context *context = GetValidGlobalContext(); - if (context) - { - switch (func) - { - case GL_NEVER: - case GL_ALWAYS: - case GL_LESS: - case GL_LEQUAL: - case GL_EQUAL: - case GL_GREATER: - case GL_GEQUAL: - case GL_NOTEQUAL: - context->getState().setDepthFunc(func); - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - } -} - -void GL_APIENTRY DepthMask(GLboolean flag) -{ - EVENT("(GLboolean flag = %u)", flag); - - Context *context = GetValidGlobalContext(); - if (context) - { - context->getState().setDepthMask(flag != GL_FALSE); - } -} - -void GL_APIENTRY DepthRangef(GLclampf zNear, GLclampf zFar) -{ - EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar); - - Context *context = GetValidGlobalContext(); - if (context) - { - context->getState().setDepthRange(zNear, zFar); - } -} - -void GL_APIENTRY DetachShader(GLuint program, GLuint shader) -{ - EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader); - - Context *context = GetValidGlobalContext(); - if (context) - { - Program *programObject = GetValidProgram(context, program); - if (!programObject) - { - return; - } - - Shader *shaderObject = GetValidShader(context, shader); - if (!shaderObject) - { - return; - } - - if (!programObject->detachShader(shaderObject)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - } -} - -void GL_APIENTRY Disable(GLenum cap) -{ - EVENT("(GLenum cap = 0x%X)", cap); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidCap(context, cap)) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - context->getState().setEnableFeature(cap, false); - } -} - -void GL_APIENTRY DisableVertexAttribArray(GLuint index) -{ - EVENT("(GLuint index = %d)", index); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (index >= MAX_VERTEX_ATTRIBS) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - context->getState().setEnableVertexAttribArray(index, false); - } -} - -void GL_APIENTRY DrawArrays(GLenum mode, GLint first, GLsizei count) -{ - EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateDrawArrays(context, mode, first, count, 0)) - { - return; - } - - Error error = context->drawArrays(mode, first, count); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -void GL_APIENTRY DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) -{ - EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)", - mode, count, type, indices); - - Context *context = GetValidGlobalContext(); - if (context) - { - IndexRange indexRange; - if (!ValidateDrawElements(context, mode, count, type, indices, 0, &indexRange)) - { - return; - } - - Error error = context->drawElements(mode, count, type, indices, indexRange); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -void GL_APIENTRY Enable(GLenum cap) -{ - EVENT("(GLenum cap = 0x%X)", cap); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidCap(context, cap)) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - if (context->getLimitations().noSampleAlphaToCoverageSupport) - { - if (cap == GL_SAMPLE_ALPHA_TO_COVERAGE) - { - const char *errorMessage = "Current renderer doesn't support alpha-to-coverage"; - context->recordError(Error(GL_INVALID_OPERATION, errorMessage)); - - // We also output an error message to the debugger window if tracing is active, so that developers can see the error message. - ERR("%s", errorMessage); - - return; - } - } - - context->getState().setEnableFeature(cap, true); - } -} - -void GL_APIENTRY EnableVertexAttribArray(GLuint index) -{ - EVENT("(GLuint index = %d)", index); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (index >= MAX_VERTEX_ATTRIBS) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - context->getState().setEnableVertexAttribArray(index, true); - } -} - -void GL_APIENTRY Finish(void) -{ - EVENT("()"); - - Context *context = GetValidGlobalContext(); - if (context) - { - Error error = context->finish(); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -void GL_APIENTRY Flush(void) -{ - EVENT("()"); - - Context *context = GetValidGlobalContext(); - if (context) - { - Error error = context->flush(); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -void GL_APIENTRY FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) -{ - EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, " - "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!context->skipValidation() && - !ValidateFramebufferRenderbuffer(context, target, attachment, renderbuffertarget, - renderbuffer)) - { - return; - } - - context->framebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer); - } -} - -void GL_APIENTRY FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) -{ - EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, " - "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!context->skipValidation() && - !ValidateFramebufferTexture2D(context, target, attachment, textarget, texture, level)) - { - return; - } - - context->framebufferTexture2D(target, attachment, textarget, texture, level); - } -} - -void GL_APIENTRY FrontFace(GLenum mode) -{ - EVENT("(GLenum mode = 0x%X)", mode); - - Context *context = GetValidGlobalContext(); - if (context) - { - switch (mode) - { - case GL_CW: - case GL_CCW: - context->getState().setFrontFace(mode); - break; - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - } -} - -void GL_APIENTRY GenBuffers(GLsizei n, GLuint* buffers) -{ - EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (n < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - for (int i = 0; i < n; i++) - { - buffers[i] = context->createBuffer(); - } - } -} - -void GL_APIENTRY GenerateMipmap(GLenum target) -{ - EVENT("(GLenum target = 0x%X)", target); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidTextureTarget(context, target)) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - Texture *texture = context->getTargetTexture(target); - - if (texture == NULL) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - GLenum baseTarget = (target == GL_TEXTURE_CUBE_MAP) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : target; - GLenum internalFormat = texture->getInternalFormat(baseTarget, 0); - const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat); - const InternalFormat &formatInfo = GetInternalFormatInfo(internalFormat); - - // GenerateMipmap should not generate an INVALID_OPERATION for textures created with - // unsized formats or that are color renderable and filterable. Since we do not track if - // the texture was created with sized or unsized format (only sized formats are stored), - // it is not possible to make sure the the LUMA formats can generate mipmaps (they should - // be able to) because they aren't color renderable. Simply do a special case for LUMA - // textures since they're the only texture format that can be created with unsized formats - // that is not color renderable. New unsized formats are unlikely to be added, since ES2 - // was the last version to use add them. - bool isLUMA = internalFormat == GL_LUMINANCE8_EXT || - internalFormat == GL_LUMINANCE8_ALPHA8_EXT || - internalFormat == GL_ALPHA8_EXT; - - if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0 || !formatCaps.filterable || - (!formatCaps.renderable && !isLUMA) || formatInfo.compressed) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - // GL_EXT_sRGB does not support mipmap generation on sRGB textures - if (context->getClientVersion() == 2 && formatInfo.colorEncoding == GL_SRGB) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - // Non-power of 2 ES2 check - if (!context->getExtensions().textureNPOT && - (!isPow2(static_cast(texture->getWidth(baseTarget, 0))) || - !isPow2(static_cast(texture->getHeight(baseTarget, 0))))) - { - ASSERT(context->getClientVersion() <= 2 && (target == GL_TEXTURE_2D || target == GL_TEXTURE_CUBE_MAP)); - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - // Cube completeness check - if (target == GL_TEXTURE_CUBE_MAP && !texture->isCubeComplete()) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - Error error = texture->generateMipmaps(); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -void GL_APIENTRY GenFramebuffers(GLsizei n, GLuint* framebuffers) -{ - EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (n < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - for (int i = 0; i < n; i++) - { - framebuffers[i] = context->createFramebuffer(); - } - } -} - -void GL_APIENTRY GenRenderbuffers(GLsizei n, GLuint* renderbuffers) -{ - EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (n < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - for (int i = 0; i < n; i++) - { - renderbuffers[i] = context->createRenderbuffer(); - } - } -} - -void GL_APIENTRY GenTextures(GLsizei n, GLuint* textures) -{ - EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (n < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - for (int i = 0; i < n; i++) - { - textures[i] = context->createTexture(); - } - } -} - -void GL_APIENTRY GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) -{ - EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, " - "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)", - program, index, bufsize, length, size, type, name); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (bufsize < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - Program *programObject = GetValidProgram(context, program); - - if (!programObject) - { - return; - } - - if (index >= (GLuint)programObject->getActiveAttributeCount()) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - programObject->getActiveAttribute(index, bufsize, length, size, type, name); - } -} - -void GL_APIENTRY GetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) -{ - EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, " - "GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)", - program, index, bufsize, length, size, type, name); - - - Context *context = GetValidGlobalContext(); - if (context) - { - if (bufsize < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - Program *programObject = GetValidProgram(context, program); - - if (!programObject) - { - return; - } - - if (index >= (GLuint)programObject->getActiveUniformCount()) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - programObject->getActiveUniform(index, bufsize, length, size, type, name); - } -} - -void GL_APIENTRY GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) -{ - EVENT("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)", - program, maxcount, count, shaders); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (maxcount < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - Program *programObject = GetValidProgram(context, program); - - if (!programObject) - { - return; - } - - return programObject->getAttachedShaders(maxcount, count, shaders); - } -} - -GLint GL_APIENTRY GetAttribLocation(GLuint program, const GLchar* name) -{ - EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name); - - Context *context = GetValidGlobalContext(); - if (context) - { - Program *programObject = GetValidProgram(context, program); - - if (!programObject) - { - return -1; - } - - if (!programObject->isLinked()) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return -1; - } - - return programObject->getAttributeLocation(name); - } - - return -1; -} - -void GL_APIENTRY GetBooleanv(GLenum pname, GLboolean* params) -{ - EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - GLenum nativeType; - unsigned int numParams = 0; - if (!ValidateStateQuery(context, pname, &nativeType, &numParams)) - { - return; - } - - if (nativeType == GL_BOOL) - { - context->getBooleanv(pname, params); - } - else - { - CastStateValues(context, nativeType, pname, numParams, params); - } - } -} - -void GL_APIENTRY GetBufferParameteriv(GLenum target, GLenum pname, GLint* params) -{ - EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidBufferTarget(context, target)) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - if (!ValidBufferParameter(context, pname)) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - Buffer *buffer = context->getState().getTargetBuffer(target); - - if (!buffer) - { - // A null buffer means that "0" is bound to the requested buffer target - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - switch (pname) - { - case GL_BUFFER_USAGE: - *params = static_cast(buffer->getUsage()); - break; - case GL_BUFFER_SIZE: - *params = clampCast(buffer->getSize()); - break; - case GL_BUFFER_ACCESS_FLAGS: - *params = buffer->getAccessFlags(); - break; - case GL_BUFFER_ACCESS_OES: - *params = buffer->getAccess(); - break; - case GL_BUFFER_MAPPED: - static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal."); - *params = static_cast(buffer->isMapped()); - break; - case GL_BUFFER_MAP_OFFSET: - *params = clampCast(buffer->getMapOffset()); - break; - case GL_BUFFER_MAP_LENGTH: - *params = clampCast(buffer->getMapLength()); - break; - default: UNREACHABLE(); break; - } - } -} - -GLenum GL_APIENTRY GetError(void) -{ - EVENT("()"); - - Context *context = GetGlobalContext(); - - if (context) - { - return context->getError(); - } - - return GL_NO_ERROR; -} - -void GL_APIENTRY GetFloatv(GLenum pname, GLfloat* params) -{ - EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - GLenum nativeType; - unsigned int numParams = 0; - if (!ValidateStateQuery(context, pname, &nativeType, &numParams)) - { - return; - } - - if (nativeType == GL_FLOAT) - { - context->getFloatv(pname, params); - } - else - { - CastStateValues(context, nativeType, pname, numParams, params); - } - } -} - -void GL_APIENTRY GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params) -{ - EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", - target, attachment, pname, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidFramebufferTarget(target)) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - int clientVersion = context->getClientVersion(); - - switch (pname) - { - case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: - case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: - case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: - case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: - break; - - case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: - if (clientVersion < 3 && !context->getExtensions().sRGB) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - break; - - case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE: - case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: - case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE: - case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE: - case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE: - case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: - case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: - case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER: - if (clientVersion < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - // Determine if the attachment is a valid enum - switch (attachment) - { - case GL_BACK: - case GL_FRONT: - case GL_DEPTH: - case GL_STENCIL: - case GL_DEPTH_STENCIL_ATTACHMENT: - if (clientVersion < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - break; - - case GL_DEPTH_ATTACHMENT: - case GL_STENCIL_ATTACHMENT: - break; - - default: - if (attachment < GL_COLOR_ATTACHMENT0_EXT || - (attachment - GL_COLOR_ATTACHMENT0_EXT) >= context->getCaps().maxColorAttachments) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - break; - } - - const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target); - ASSERT(framebuffer); - - if (framebuffer->id() == 0) - { - if (clientVersion < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - switch (attachment) - { - case GL_BACK: - case GL_DEPTH: - case GL_STENCIL: - break; - - default: - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - } - else - { - if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) - { - // Valid attachment query - } - else - { - switch (attachment) - { - case GL_DEPTH_ATTACHMENT: - case GL_STENCIL_ATTACHMENT: - break; - - case GL_DEPTH_STENCIL_ATTACHMENT: - if (framebuffer->hasValidDepthStencil()) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - break; - - default: - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - } - } - - const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(attachment); - if (attachmentObject) - { - ASSERT(attachmentObject->type() == GL_RENDERBUFFER || - attachmentObject->type() == GL_TEXTURE || - attachmentObject->type() == GL_FRAMEBUFFER_DEFAULT); - - switch (pname) - { - case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: - *params = attachmentObject->type(); - break; - - case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: - if (attachmentObject->type() != GL_RENDERBUFFER && attachmentObject->type() != GL_TEXTURE) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = attachmentObject->id(); - break; - - case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: - if (attachmentObject->type() != GL_TEXTURE) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = attachmentObject->mipLevel(); - break; - - case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: - if (attachmentObject->type() != GL_TEXTURE) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = attachmentObject->cubeMapFace(); - break; - - case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE: - *params = attachmentObject->getRedSize(); - break; - - case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: - *params = attachmentObject->getGreenSize(); - break; - - case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE: - *params = attachmentObject->getBlueSize(); - break; - - case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE: - *params = attachmentObject->getAlphaSize(); - break; - - case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE: - *params = attachmentObject->getDepthSize(); - break; - - case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: - *params = attachmentObject->getStencilSize(); - break; - - case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: - if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - *params = attachmentObject->getComponentType(); - break; - - case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: - *params = attachmentObject->getColorEncoding(); - break; - - case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER: - if (attachmentObject->type() != GL_TEXTURE) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = attachmentObject->layer(); - break; - - default: - UNREACHABLE(); - break; - } - } - else - { - // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE - // is NONE, then querying any other pname will generate INVALID_ENUM. - - // ES 3.0.2 spec pg 235 states that if the attachment type is none, - // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an - // INVALID_OPERATION for all other pnames - - switch (pname) - { - case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: - *params = GL_NONE; - break; - - case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: - if (clientVersion < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = 0; - break; - - default: - if (clientVersion < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - else - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - } - } - } -} - -void GL_APIENTRY GetIntegerv(GLenum pname, GLint* params) -{ - EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - GLenum nativeType; - unsigned int numParams = 0; - - if (!ValidateStateQuery(context, pname, &nativeType, &numParams)) - { - return; - } - - if (nativeType == GL_INT) - { - context->getIntegerv(pname, params); - } - else - { - CastStateValues(context, nativeType, pname, numParams, params); - } - } -} - -void GL_APIENTRY GetProgramiv(GLuint program, GLenum pname, GLint* params) -{ - EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - Program *programObject = GetValidProgram(context, program); - - if (!programObject) - { - return; - } - - if (context->getClientVersion() < 3) - { - switch (pname) - { - case GL_ACTIVE_UNIFORM_BLOCKS: - case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: - case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: - case GL_TRANSFORM_FEEDBACK_VARYINGS: - case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: - case GL_PROGRAM_BINARY_RETRIEVABLE_HINT: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - } - - switch (pname) - { - case GL_DELETE_STATUS: - *params = programObject->isFlaggedForDeletion(); - return; - case GL_LINK_STATUS: - *params = programObject->isLinked(); - return; - case GL_VALIDATE_STATUS: - *params = programObject->isValidated(); - return; - case GL_INFO_LOG_LENGTH: - *params = programObject->getInfoLogLength(); - return; - case GL_ATTACHED_SHADERS: - *params = programObject->getAttachedShadersCount(); - return; - case GL_ACTIVE_ATTRIBUTES: - *params = programObject->getActiveAttributeCount(); - return; - case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: - *params = programObject->getActiveAttributeMaxLength(); - return; - case GL_ACTIVE_UNIFORMS: - *params = programObject->getActiveUniformCount(); - return; - case GL_ACTIVE_UNIFORM_MAX_LENGTH: - *params = programObject->getActiveUniformMaxLength(); - return; - case GL_PROGRAM_BINARY_LENGTH_OES: - *params = programObject->getBinaryLength(); - return; - case GL_ACTIVE_UNIFORM_BLOCKS: - *params = programObject->getActiveUniformBlockCount(); - return; - case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: - *params = programObject->getActiveUniformBlockMaxLength(); - break; - case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: - *params = programObject->getTransformFeedbackBufferMode(); - break; - case GL_TRANSFORM_FEEDBACK_VARYINGS: - *params = programObject->getTransformFeedbackVaryingCount(); - break; - case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: - *params = programObject->getTransformFeedbackVaryingMaxLength(); - break; - case GL_PROGRAM_BINARY_RETRIEVABLE_HINT: - *params = programObject->getBinaryRetrievableHint(); - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - } -} - -void GL_APIENTRY GetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog) -{ - EVENT("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)", - program, bufsize, length, infolog); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (bufsize < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - Program *programObject = GetValidProgram(context, program); - if (!programObject) - { - return; - } - - programObject->getInfoLog(bufsize, length, infolog); - } -} - -void GL_APIENTRY GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) -{ - EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (target != GL_RENDERBUFFER) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - if (context->getState().getRenderbufferId() == 0) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - Renderbuffer *renderbuffer = context->getRenderbuffer(context->getState().getRenderbufferId()); - - switch (pname) - { - case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break; - case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break; - case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break; - case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break; - case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break; - case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break; - case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break; - case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break; - case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break; - - case GL_RENDERBUFFER_SAMPLES_ANGLE: - if (!context->getExtensions().framebufferMultisample) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = renderbuffer->getSamples(); - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - } -} - -void GL_APIENTRY GetShaderiv(GLuint shader, GLenum pname, GLint* params) -{ - EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - Shader *shaderObject = GetValidShader(context, shader); - if (!shaderObject) - { - return; - } - - switch (pname) - { - case GL_SHADER_TYPE: - *params = shaderObject->getType(); - return; - case GL_DELETE_STATUS: - *params = shaderObject->isFlaggedForDeletion(); - return; - case GL_COMPILE_STATUS: - *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE; - return; - case GL_INFO_LOG_LENGTH: - *params = shaderObject->getInfoLogLength(); - return; - case GL_SHADER_SOURCE_LENGTH: - *params = shaderObject->getSourceLength(); - return; - case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE: - *params = shaderObject->getTranslatedSourceWithDebugInfoLength(); - return; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - } -} - -void GL_APIENTRY GetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog) -{ - EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)", - shader, bufsize, length, infolog); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (bufsize < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - Shader *shaderObject = GetValidShader(context, shader); - if (!shaderObject) - { - return; - } - - shaderObject->getInfoLog(bufsize, length, infolog); - } -} - -void GL_APIENTRY GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) -{ - EVENT("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)", - shadertype, precisiontype, range, precision); - - Context *context = GetValidGlobalContext(); - if (context) - { - switch (shadertype) - { - case GL_VERTEX_SHADER: - switch (precisiontype) - { - case GL_LOW_FLOAT: - context->getCaps().vertexLowpFloat.get(range, precision); - break; - case GL_MEDIUM_FLOAT: - context->getCaps().vertexMediumpFloat.get(range, precision); - break; - case GL_HIGH_FLOAT: - context->getCaps().vertexHighpFloat.get(range, precision); - break; - - case GL_LOW_INT: - context->getCaps().vertexLowpInt.get(range, precision); - break; - case GL_MEDIUM_INT: - context->getCaps().vertexMediumpInt.get(range, precision); - break; - case GL_HIGH_INT: - context->getCaps().vertexHighpInt.get(range, precision); - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - break; - case GL_FRAGMENT_SHADER: - switch (precisiontype) - { - case GL_LOW_FLOAT: - context->getCaps().fragmentLowpFloat.get(range, precision); - break; - case GL_MEDIUM_FLOAT: - context->getCaps().fragmentMediumpFloat.get(range, precision); - break; - case GL_HIGH_FLOAT: - context->getCaps().fragmentHighpFloat.get(range, precision); - break; - - case GL_LOW_INT: - context->getCaps().fragmentLowpInt.get(range, precision); - break; - case GL_MEDIUM_INT: - context->getCaps().fragmentMediumpInt.get(range, precision); - break; - case GL_HIGH_INT: - context->getCaps().fragmentHighpInt.get(range, precision); - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - break; - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - } -} - -void GL_APIENTRY GetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source) -{ - EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)", - shader, bufsize, length, source); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (bufsize < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - Shader *shaderObject = GetValidShader(context, shader); - if (!shaderObject) - { - return; - } - - shaderObject->getSource(bufsize, length, source); - } -} - -const GLubyte *GL_APIENTRY GetString(GLenum name) -{ - EVENT("(GLenum name = 0x%X)", name); - - Context *context = GetValidGlobalContext(); - - if (context) - { - switch (name) - { - case GL_VENDOR: - return reinterpret_cast("Google Inc."); - - case GL_RENDERER: - return reinterpret_cast(context->getRendererString().c_str()); - - case GL_VERSION: - if (context->getClientVersion() == 2) - { - return reinterpret_cast( - "OpenGL ES 2.0 (ANGLE " ANGLE_VERSION_STRING ")"); - } - else - { - return reinterpret_cast( - "OpenGL ES 3.0 (ANGLE " ANGLE_VERSION_STRING ")"); - } - - case GL_SHADING_LANGUAGE_VERSION: - if (context->getClientVersion() == 2) - { - return reinterpret_cast( - "OpenGL ES GLSL ES 1.00 (ANGLE " ANGLE_VERSION_STRING ")"); - } - else - { - return reinterpret_cast( - "OpenGL ES GLSL ES 3.00 (ANGLE " ANGLE_VERSION_STRING ")"); - } - - case GL_EXTENSIONS: - return reinterpret_cast(context->getExtensionString().c_str()); - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return nullptr; - } - } - - return nullptr; -} - -void GL_APIENTRY GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) -{ - EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidTextureTarget(context, target)) - { - context->recordError(Error(GL_INVALID_ENUM, "Invalid texture target")); - return; - } - - Texture *texture = context->getTargetTexture(target); - - if (!texture) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - switch (pname) - { - case GL_TEXTURE_MAG_FILTER: - *params = (GLfloat)texture->getMagFilter(); - break; - case GL_TEXTURE_MIN_FILTER: - *params = (GLfloat)texture->getMinFilter(); - break; - case GL_TEXTURE_WRAP_S: - *params = (GLfloat)texture->getWrapS(); - break; - case GL_TEXTURE_WRAP_T: - *params = (GLfloat)texture->getWrapT(); - break; - case GL_TEXTURE_WRAP_R: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = (GLfloat)texture->getWrapR(); - break; - case GL_TEXTURE_IMMUTABLE_FORMAT: - // Exposed to ES2.0 through EXT_texture_storage, no client version validation. - *params = (GLfloat)(texture->getImmutableFormat() ? GL_TRUE : GL_FALSE); - break; - case GL_TEXTURE_IMMUTABLE_LEVELS: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = (GLfloat)texture->getImmutableLevels(); - break; - case GL_TEXTURE_USAGE_ANGLE: - *params = (GLfloat)texture->getUsage(); - break; - case GL_TEXTURE_MAX_ANISOTROPY_EXT: - if (!context->getExtensions().textureFilterAnisotropic) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = (GLfloat)texture->getMaxAnisotropy(); - break; - case GL_TEXTURE_SWIZZLE_R: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = (GLfloat)texture->getSwizzleRed(); - break; - case GL_TEXTURE_SWIZZLE_G: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = (GLfloat)texture->getSwizzleGreen(); - break; - case GL_TEXTURE_SWIZZLE_B: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = (GLfloat)texture->getSwizzleBlue(); - break; - case GL_TEXTURE_SWIZZLE_A: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = (GLfloat)texture->getSwizzleAlpha(); - break; - case GL_TEXTURE_BASE_LEVEL: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = (GLfloat)texture->getBaseLevel(); - break; - case GL_TEXTURE_MAX_LEVEL: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = (GLfloat)texture->getMaxLevel(); - break; - case GL_TEXTURE_MIN_LOD: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = texture->getSamplerState().minLod; - break; - case GL_TEXTURE_MAX_LOD: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = texture->getSamplerState().maxLod; - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - } -} - -void GL_APIENTRY GetTexParameteriv(GLenum target, GLenum pname, GLint* params) -{ - EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidTextureTarget(context, target)) - { - context->recordError(Error(GL_INVALID_ENUM, "Invalid texture target")); - return; - } - - Texture *texture = context->getTargetTexture(target); - - if (!texture) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - switch (pname) - { - case GL_TEXTURE_MAG_FILTER: - *params = texture->getSamplerState().magFilter; - break; - case GL_TEXTURE_MIN_FILTER: - *params = texture->getSamplerState().minFilter; - break; - case GL_TEXTURE_WRAP_S: - *params = texture->getSamplerState().wrapS; - break; - case GL_TEXTURE_WRAP_T: - *params = texture->getSamplerState().wrapT; - break; - case GL_TEXTURE_WRAP_R: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = texture->getSamplerState().wrapR; - break; - case GL_TEXTURE_IMMUTABLE_FORMAT: - // Exposed to ES2.0 through EXT_texture_storage, no client version validation. - *params = texture->getImmutableFormat() ? GL_TRUE : GL_FALSE; - break; - case GL_TEXTURE_IMMUTABLE_LEVELS: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = static_cast(texture->getImmutableLevels()); - break; - case GL_TEXTURE_USAGE_ANGLE: - *params = texture->getUsage(); - break; - case GL_TEXTURE_MAX_ANISOTROPY_EXT: - if (!context->getExtensions().textureFilterAnisotropic) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = (GLint)texture->getMaxAnisotropy(); - break; - case GL_TEXTURE_SWIZZLE_R: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = texture->getSwizzleRed(); - break; - case GL_TEXTURE_SWIZZLE_G: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = texture->getSwizzleGreen(); - break; - case GL_TEXTURE_SWIZZLE_B: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = texture->getSwizzleBlue(); - break; - case GL_TEXTURE_SWIZZLE_A: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = texture->getSwizzleAlpha(); - break; - case GL_TEXTURE_BASE_LEVEL: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = texture->getBaseLevel(); - break; - case GL_TEXTURE_MAX_LEVEL: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = texture->getMaxLevel(); - break; - case GL_TEXTURE_MIN_LOD: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = (GLint)texture->getMinLod(); - break; - case GL_TEXTURE_MAX_LOD: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - *params = (GLint)texture->getMaxLod(); - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - } -} - -void GL_APIENTRY GetUniformfv(GLuint program, GLint location, GLfloat* params) -{ - EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateGetUniformfv(context, program, location, params)) - { - return; - } - - Program *programObject = context->getProgram(program); - ASSERT(programObject); - - programObject->getUniformfv(location, params); - } -} - -void GL_APIENTRY GetUniformiv(GLuint program, GLint location, GLint* params) -{ - EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateGetUniformiv(context, program, location, params)) - { - return; - } - - Program *programObject = context->getProgram(program); - ASSERT(programObject); - - programObject->getUniformiv(location, params); - } -} - -GLint GL_APIENTRY GetUniformLocation(GLuint program, const GLchar* name) -{ - EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (strstr(name, "gl_") == name) - { - return -1; - } - - Program *programObject = GetValidProgram(context, program); - - if (!programObject) - { - return -1; - } - - if (!programObject->isLinked()) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return -1; - } - - return programObject->getUniformLocation(name); - } - - return -1; -} - -void GL_APIENTRY GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) -{ - EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (index >= MAX_VERTEX_ATTRIBS) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - if (!ValidateGetVertexAttribParameters(context, pname)) - { - return; - } - - if (pname == GL_CURRENT_VERTEX_ATTRIB) - { - const VertexAttribCurrentValueData ¤tValueData = context->getState().getVertexAttribCurrentValue(index); - for (int i = 0; i < 4; ++i) - { - params[i] = currentValueData.FloatValues[i]; - } - } - else - { - const VertexAttribute &attribState = context->getState().getVertexArray()->getVertexAttribute(index); - *params = QuerySingleVertexAttributeParameter(attribState, pname); - } - } -} - -void GL_APIENTRY GetVertexAttribiv(GLuint index, GLenum pname, GLint* params) -{ - EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (index >= MAX_VERTEX_ATTRIBS) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - if (!ValidateGetVertexAttribParameters(context, pname)) - { - return; - } - - if (pname == GL_CURRENT_VERTEX_ATTRIB) - { - const VertexAttribCurrentValueData ¤tValueData = context->getState().getVertexAttribCurrentValue(index); - for (int i = 0; i < 4; ++i) - { - float currentValue = currentValueData.FloatValues[i]; - params[i] = iround(currentValue); - } - } - else - { - const VertexAttribute &attribState = context->getState().getVertexArray()->getVertexAttribute(index); - *params = QuerySingleVertexAttributeParameter(attribState, pname); - } - } -} - -void GL_APIENTRY GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer) -{ - EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (index >= MAX_VERTEX_ATTRIBS) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - *pointer = const_cast(context->getState().getVertexAttribPointer(index)); - } -} - -void GL_APIENTRY Hint(GLenum target, GLenum mode) -{ - EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode); - - Context *context = GetValidGlobalContext(); - if (context) - { - switch (mode) - { - case GL_FASTEST: - case GL_NICEST: - case GL_DONT_CARE: - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - switch (target) - { - case GL_GENERATE_MIPMAP_HINT: - context->getState().setGenerateMipmapHint(mode); - break; - - case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: - context->getState().setFragmentShaderDerivativeHint(mode); - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - } -} - -GLboolean GL_APIENTRY IsBuffer(GLuint buffer) -{ - EVENT("(GLuint buffer = %d)", buffer); - - Context *context = GetValidGlobalContext(); - if (context && buffer) - { - Buffer *bufferObject = context->getBuffer(buffer); - - if (bufferObject) - { - return GL_TRUE; - } - } - - return GL_FALSE; -} - -GLboolean GL_APIENTRY IsEnabled(GLenum cap) -{ - EVENT("(GLenum cap = 0x%X)", cap); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidCap(context, cap)) - { - context->recordError(Error(GL_INVALID_ENUM)); - return GL_FALSE; - } - - return context->getState().getEnableFeature(cap); - } - - return false; -} - -GLboolean GL_APIENTRY IsFramebuffer(GLuint framebuffer) -{ - EVENT("(GLuint framebuffer = %d)", framebuffer); - - Context *context = GetValidGlobalContext(); - if (context && framebuffer) - { - Framebuffer *framebufferObject = context->getFramebuffer(framebuffer); - - if (framebufferObject) - { - return GL_TRUE; - } - } - - return GL_FALSE; -} - -GLboolean GL_APIENTRY IsProgram(GLuint program) -{ - EVENT("(GLuint program = %d)", program); - - Context *context = GetValidGlobalContext(); - if (context && program) - { - Program *programObject = context->getProgram(program); - - if (programObject) - { - return GL_TRUE; - } - } - - return GL_FALSE; -} - -GLboolean GL_APIENTRY IsRenderbuffer(GLuint renderbuffer) -{ - EVENT("(GLuint renderbuffer = %d)", renderbuffer); - - Context *context = GetValidGlobalContext(); - if (context && renderbuffer) - { - Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer); - - if (renderbufferObject) - { - return GL_TRUE; - } - } - - return GL_FALSE; -} - -GLboolean GL_APIENTRY IsShader(GLuint shader) -{ - EVENT("(GLuint shader = %d)", shader); - - Context *context = GetValidGlobalContext(); - if (context && shader) - { - Shader *shaderObject = context->getShader(shader); - - if (shaderObject) - { - return GL_TRUE; - } - } - - return GL_FALSE; -} - -GLboolean GL_APIENTRY IsTexture(GLuint texture) -{ - EVENT("(GLuint texture = %d)", texture); - - Context *context = GetValidGlobalContext(); - if (context && texture) - { - Texture *textureObject = context->getTexture(texture); - - if (textureObject) - { - return GL_TRUE; - } - } - - return GL_FALSE; -} - -void GL_APIENTRY LineWidth(GLfloat width) -{ - EVENT("(GLfloat width = %f)", width); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (width <= 0.0f) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - context->getState().setLineWidth(width); - } -} - -void GL_APIENTRY LinkProgram(GLuint program) -{ - EVENT("(GLuint program = %d)", program); - - Context *context = GetValidGlobalContext(); - if (context) - { - Program *programObject = GetValidProgram(context, program); - if (!programObject) - { - return; - } - - Error error = programObject->link(context->getData()); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -void GL_APIENTRY PixelStorei(GLenum pname, GLint param) -{ - EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - switch (pname) - { - case GL_UNPACK_IMAGE_HEIGHT: - case GL_UNPACK_SKIP_IMAGES: - context->recordError(Error(GL_INVALID_ENUM)); - return; - - case GL_UNPACK_ROW_LENGTH: - case GL_UNPACK_SKIP_ROWS: - case GL_UNPACK_SKIP_PIXELS: - if (!context->getExtensions().unpackSubimage) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - break; - - case GL_PACK_ROW_LENGTH: - case GL_PACK_SKIP_ROWS: - case GL_PACK_SKIP_PIXELS: - if (!context->getExtensions().packSubimage) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - break; - } - } - - if (param < 0) - { - context->recordError(Error(GL_INVALID_VALUE, "Cannot use negative values in PixelStorei")); - return; - } - - State &state = context->getState(); - - switch (pname) - { - case GL_UNPACK_ALIGNMENT: - if (param != 1 && param != 2 && param != 4 && param != 8) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - state.setUnpackAlignment(param); - break; - - case GL_PACK_ALIGNMENT: - if (param != 1 && param != 2 && param != 4 && param != 8) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - state.setPackAlignment(param); - break; - - case GL_PACK_REVERSE_ROW_ORDER_ANGLE: - state.setPackReverseRowOrder(param != 0); - break; - - case GL_UNPACK_ROW_LENGTH: - ASSERT((context->getClientVersion() >= 3) || context->getExtensions().unpackSubimage); - state.setUnpackRowLength(param); - break; - - case GL_UNPACK_IMAGE_HEIGHT: - ASSERT(context->getClientVersion() >= 3); - state.setUnpackImageHeight(param); - break; - - case GL_UNPACK_SKIP_IMAGES: - ASSERT(context->getClientVersion() >= 3); - state.setUnpackSkipImages(param); - break; - - case GL_UNPACK_SKIP_ROWS: - ASSERT((context->getClientVersion() >= 3) || context->getExtensions().unpackSubimage); - state.setUnpackSkipRows(param); - break; - - case GL_UNPACK_SKIP_PIXELS: - ASSERT((context->getClientVersion() >= 3) || context->getExtensions().unpackSubimage); - state.setUnpackSkipPixels(param); - break; - - case GL_PACK_ROW_LENGTH: - ASSERT((context->getClientVersion() >= 3) || context->getExtensions().packSubimage); - state.setPackRowLength(param); - break; - - case GL_PACK_SKIP_ROWS: - ASSERT((context->getClientVersion() >= 3) || context->getExtensions().packSubimage); - state.setPackSkipRows(param); - break; - - case GL_PACK_SKIP_PIXELS: - ASSERT((context->getClientVersion() >= 3) || context->getExtensions().packSubimage); - state.setPackSkipPixels(param); - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - } -} - -void GL_APIENTRY PolygonOffset(GLfloat factor, GLfloat units) -{ - EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units); - - Context *context = GetValidGlobalContext(); - if (context) - { - context->getState().setPolygonOffsetParams(factor, units); - } -} - -void GL_APIENTRY ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, GLvoid* pixels) -{ - EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, " - "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)", - x, y, width, height, format, type, pixels); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!context->skipValidation() && - !ValidateReadPixels(context, x, y, width, height, format, type, pixels)) - { - return; - } - - context->readPixels(x, y, width, height, format, type, pixels); - } -} - -void GL_APIENTRY ReleaseShaderCompiler(void) -{ - EVENT("()"); - - Context *context = GetValidGlobalContext(); - - if (context) - { - Compiler *compiler = context->getCompiler(); - Error error = compiler->release(); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -void GL_APIENTRY RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) -{ - EVENT("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", - target, internalformat, width, height); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateRenderbufferStorageParametersANGLE(context, target, 0, internalformat, - width, height)) - { - return; - } - - Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer(); - Error error = renderbuffer->setStorage(internalformat, width, height); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -void GL_APIENTRY SampleCoverage(GLclampf value, GLboolean invert) -{ - EVENT("(GLclampf value = %f, GLboolean invert = %u)", value, invert); - - Context* context = GetValidGlobalContext(); - - if (context) - { - context->getState().setSampleCoverageParams(clamp01(value), invert == GL_TRUE); - } -} - -void GL_APIENTRY Scissor(GLint x, GLint y, GLsizei width, GLsizei height) -{ - EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height); - - Context* context = GetValidGlobalContext(); - if (context) - { - if (width < 0 || height < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - context->getState().setScissorParams(x, y, width, height); - } -} - -void GL_APIENTRY ShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length) -{ - EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, " - "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)", - n, shaders, binaryformat, binary, length); - - Context* context = GetValidGlobalContext(); - if (context) - { - const std::vector &shaderBinaryFormats = context->getCaps().shaderBinaryFormats; - if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) == shaderBinaryFormats.end()) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - // No binary shader formats are supported. - UNIMPLEMENTED(); - } -} - -void GL_APIENTRY ShaderSource(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length) -{ - EVENT("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)", - shader, count, string, length); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (count < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - Shader *shaderObject = GetValidShader(context, shader); - if (!shaderObject) - { - return; - } - shaderObject->setSource(count, string, length); - } -} - -void GL_APIENTRY StencilFunc(GLenum func, GLint ref, GLuint mask) -{ - StencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask); -} - -void GL_APIENTRY StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) -{ - EVENT("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask); - - Context *context = GetValidGlobalContext(); - if (context) - { - switch (face) - { - case GL_FRONT: - case GL_BACK: - case GL_FRONT_AND_BACK: - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - switch (func) - { - case GL_NEVER: - case GL_ALWAYS: - case GL_LESS: - case GL_LEQUAL: - case GL_EQUAL: - case GL_GEQUAL: - case GL_GREATER: - case GL_NOTEQUAL: - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - if (face == GL_FRONT || face == GL_FRONT_AND_BACK) - { - context->getState().setStencilParams(func, ref, mask); - } - - if (face == GL_BACK || face == GL_FRONT_AND_BACK) - { - context->getState().setStencilBackParams(func, ref, mask); - } - } -} - -void GL_APIENTRY StencilMask(GLuint mask) -{ - StencilMaskSeparate(GL_FRONT_AND_BACK, mask); -} - -void GL_APIENTRY StencilMaskSeparate(GLenum face, GLuint mask) -{ - EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask); - - Context *context = GetValidGlobalContext(); - if (context) - { - switch (face) - { - case GL_FRONT: - case GL_BACK: - case GL_FRONT_AND_BACK: - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - if (face == GL_FRONT || face == GL_FRONT_AND_BACK) - { - context->getState().setStencilWritemask(mask); - } - - if (face == GL_BACK || face == GL_FRONT_AND_BACK) - { - context->getState().setStencilBackWritemask(mask); - } - } -} - -void GL_APIENTRY StencilOp(GLenum fail, GLenum zfail, GLenum zpass) -{ - StencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass); -} - -void GL_APIENTRY StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) -{ - EVENT("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)", - face, fail, zfail, zpass); - - Context *context = GetValidGlobalContext(); - if (context) - { - switch (face) - { - case GL_FRONT: - case GL_BACK: - case GL_FRONT_AND_BACK: - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - switch (fail) - { - case GL_ZERO: - case GL_KEEP: - case GL_REPLACE: - case GL_INCR: - case GL_DECR: - case GL_INVERT: - case GL_INCR_WRAP: - case GL_DECR_WRAP: - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - switch (zfail) - { - case GL_ZERO: - case GL_KEEP: - case GL_REPLACE: - case GL_INCR: - case GL_DECR: - case GL_INVERT: - case GL_INCR_WRAP: - case GL_DECR_WRAP: - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - switch (zpass) - { - case GL_ZERO: - case GL_KEEP: - case GL_REPLACE: - case GL_INCR: - case GL_DECR: - case GL_INVERT: - case GL_INCR_WRAP: - case GL_DECR_WRAP: - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - if (face == GL_FRONT || face == GL_FRONT_AND_BACK) - { - context->getState().setStencilOperations(fail, zfail, zpass); - } - - if (face == GL_BACK || face == GL_FRONT_AND_BACK) - { - context->getState().setStencilBackOperations(fail, zfail, zpass); - } - } -} - -void GL_APIENTRY TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, - GLint border, GLenum format, GLenum type, const GLvoid* pixels) -{ - EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, " - "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)", - target, level, internalformat, width, height, border, format, type, pixels); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3 && - !ValidateES2TexImageParameters(context, target, level, internalformat, false, false, - 0, 0, width, height, border, format, type, pixels)) - { - return; - } - - if (context->getClientVersion() >= 3 && - !ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, - 0, 0, 0, width, height, 1, border, format, type, - pixels)) - { - return; - } - - Extents size(width, height, 1); - Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); - Error error = texture->setImage(context, target, level, internalformat, size, format, type, - reinterpret_cast(pixels)); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -void GL_APIENTRY TexParameterf(GLenum target, GLenum pname, GLfloat param) -{ - EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %f)", target, pname, param); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidTextureTarget(context, target)) - { - context->recordError(Error(GL_INVALID_ENUM, "Invalid texture target")); - return; - } - - if (!ValidateTexParamParameters(context, pname, static_cast(param))) - { - return; - } - - Texture *texture = context->getTargetTexture(target); - - if (!texture) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - // clang-format off - switch (pname) - { - case GL_TEXTURE_WRAP_S: texture->setWrapS(uiround(param)); break; - case GL_TEXTURE_WRAP_T: texture->setWrapT(uiround(param)); break; - case GL_TEXTURE_WRAP_R: texture->setWrapR(uiround(param)); break; - case GL_TEXTURE_MIN_FILTER: texture->setMinFilter(uiround(param)); break; - case GL_TEXTURE_MAG_FILTER: texture->setMagFilter(uiround(param)); break; - case GL_TEXTURE_USAGE_ANGLE: texture->setUsage(uiround(param)); break; - case GL_TEXTURE_MAX_ANISOTROPY_EXT: texture->setMaxAnisotropy(std::min(param, context->getExtensions().maxTextureAnisotropy)); break; - case GL_TEXTURE_COMPARE_MODE: texture->setCompareMode(uiround(param)); break; - case GL_TEXTURE_COMPARE_FUNC: texture->setCompareFunc(uiround(param)); break; - case GL_TEXTURE_SWIZZLE_R: texture->setSwizzleRed(uiround(param)); break; - case GL_TEXTURE_SWIZZLE_G: texture->setSwizzleGreen(uiround(param)); break; - case GL_TEXTURE_SWIZZLE_B: texture->setSwizzleBlue(uiround(param)); break; - case GL_TEXTURE_SWIZZLE_A: texture->setSwizzleAlpha(uiround(param)); break; - case GL_TEXTURE_BASE_LEVEL: texture->setBaseLevel(uiround(param)); break; - case GL_TEXTURE_MAX_LEVEL: texture->setMaxLevel(uiround(param)); break; - case GL_TEXTURE_MIN_LOD: texture->setMinLod(param); break; - case GL_TEXTURE_MAX_LOD: texture->setMaxLod(param); break; - default: UNREACHABLE(); break; - } - // clang-format on - } -} - -void GL_APIENTRY TexParameterfv(GLenum target, GLenum pname, const GLfloat* params) -{ - TexParameterf(target, pname, (GLfloat)*params); -} - -void GL_APIENTRY TexParameteri(GLenum target, GLenum pname, GLint param) -{ - EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidTextureTarget(context, target)) - { - context->recordError(Error(GL_INVALID_ENUM, "Invalid Texture target")); - return; - } - - if (!ValidateTexParamParameters(context, pname, param)) - { - return; - } - - Texture *texture = context->getTargetTexture(target); - - if (!texture) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - // clang-format off - switch (pname) - { - case GL_TEXTURE_WRAP_S: texture->setWrapS(static_cast(param)); break; - case GL_TEXTURE_WRAP_T: texture->setWrapT(static_cast(param)); break; - case GL_TEXTURE_WRAP_R: texture->setWrapR(static_cast(param)); break; - case GL_TEXTURE_MIN_FILTER: texture->setMinFilter(static_cast(param)); break; - case GL_TEXTURE_MAG_FILTER: texture->setMagFilter(static_cast(param)); break; - case GL_TEXTURE_USAGE_ANGLE: texture->setUsage(static_cast(param)); break; - case GL_TEXTURE_MAX_ANISOTROPY_EXT: texture->setMaxAnisotropy(std::min(static_cast(param), context->getExtensions().maxTextureAnisotropy)); break; - case GL_TEXTURE_COMPARE_MODE: texture->setCompareMode(static_cast(param)); break; - case GL_TEXTURE_COMPARE_FUNC: texture->setCompareFunc(static_cast(param)); break; - case GL_TEXTURE_SWIZZLE_R: texture->setSwizzleRed(static_cast(param)); break; - case GL_TEXTURE_SWIZZLE_G: texture->setSwizzleGreen(static_cast(param)); break; - case GL_TEXTURE_SWIZZLE_B: texture->setSwizzleBlue(static_cast(param)); break; - case GL_TEXTURE_SWIZZLE_A: texture->setSwizzleAlpha(static_cast(param)); break; - case GL_TEXTURE_BASE_LEVEL: texture->setBaseLevel(static_cast(param)); break; - case GL_TEXTURE_MAX_LEVEL: texture->setMaxLevel(static_cast(param)); break; - case GL_TEXTURE_MIN_LOD: texture->setMinLod(static_cast(param)); break; - case GL_TEXTURE_MAX_LOD: texture->setMaxLod(static_cast(param)); break; - default: UNREACHABLE(); break; - } - // clang-format on - } -} - -void GL_APIENTRY TexParameteriv(GLenum target, GLenum pname, const GLint* params) -{ - TexParameteri(target, pname, *params); -} - -void GL_APIENTRY TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - GLenum format, GLenum type, const GLvoid* pixels) -{ - EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " - "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, " - "const GLvoid* pixels = 0x%0.8p)", - target, level, xoffset, yoffset, width, height, format, type, pixels); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3 && - !ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, - xoffset, yoffset, width, height, 0, format, type, pixels)) - { - return; - } - - if (context->getClientVersion() >= 3 && - !ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset, - yoffset, 0, width, height, 1, 0, format, type, pixels)) - { - return; - } - - // Zero sized uploads are valid but no-ops - if (width == 0 || height == 0) - { - return; - } - - Box area(xoffset, yoffset, 0, width, height, 1); - Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target); - Error error = texture->setSubImage(context, target, level, area, format, type, - reinterpret_cast(pixels)); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -void GL_APIENTRY Uniform1f(GLint location, GLfloat x) -{ - Uniform1fv(location, 1, &x); -} - -void GL_APIENTRY Uniform1fv(GLint location, GLsizei count, const GLfloat* v) -{ - EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateUniform(context, GL_FLOAT, location, count)) - { - return; - } - - Program *program = context->getState().getProgram(); - program->setUniform1fv(location, count, v); - } -} - -void GL_APIENTRY Uniform1i(GLint location, GLint x) -{ - Uniform1iv(location, 1, &x); -} - -void GL_APIENTRY Uniform1iv(GLint location, GLsizei count, const GLint* v) -{ - EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateUniform(context, GL_INT, location, count)) - { - return; - } - - Program *program = context->getState().getProgram(); - program->setUniform1iv(location, count, v); - } -} - -void GL_APIENTRY Uniform2f(GLint location, GLfloat x, GLfloat y) -{ - GLfloat xy[2] = {x, y}; - - Uniform2fv(location, 1, xy); -} - -void GL_APIENTRY Uniform2fv(GLint location, GLsizei count, const GLfloat* v) -{ - EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateUniform(context, GL_FLOAT_VEC2, location, count)) - { - return; - } - - Program *program = context->getState().getProgram(); - program->setUniform2fv(location, count, v); - } -} - -void GL_APIENTRY Uniform2i(GLint location, GLint x, GLint y) -{ - GLint xy[2] = {x, y}; - - Uniform2iv(location, 1, xy); -} - -void GL_APIENTRY Uniform2iv(GLint location, GLsizei count, const GLint* v) -{ - EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateUniform(context, GL_INT_VEC2, location, count)) - { - return; - } - - Program *program = context->getState().getProgram(); - program->setUniform2iv(location, count, v); - } -} - -void GL_APIENTRY Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) -{ - GLfloat xyz[3] = {x, y, z}; - - Uniform3fv(location, 1, xyz); -} - -void GL_APIENTRY Uniform3fv(GLint location, GLsizei count, const GLfloat* v) -{ - EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateUniform(context, GL_FLOAT_VEC3, location, count)) - { - return; - } - - Program *program = context->getState().getProgram(); - program->setUniform3fv(location, count, v); - } -} - -void GL_APIENTRY Uniform3i(GLint location, GLint x, GLint y, GLint z) -{ - GLint xyz[3] = {x, y, z}; - - Uniform3iv(location, 1, xyz); -} - -void GL_APIENTRY Uniform3iv(GLint location, GLsizei count, const GLint* v) -{ - EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateUniform(context, GL_INT_VEC3, location, count)) - { - return; - } - - Program *program = context->getState().getProgram(); - program->setUniform3iv(location, count, v); - } -} - -void GL_APIENTRY Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) -{ - GLfloat xyzw[4] = {x, y, z, w}; - - Uniform4fv(location, 1, xyzw); -} - -void GL_APIENTRY Uniform4fv(GLint location, GLsizei count, const GLfloat* v) -{ - EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateUniform(context, GL_FLOAT_VEC4, location, count)) - { - return; - } - - Program *program = context->getState().getProgram(); - program->setUniform4fv(location, count, v); - } -} - -void GL_APIENTRY Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) -{ - GLint xyzw[4] = {x, y, z, w}; - - Uniform4iv(location, 1, xyzw); -} - -void GL_APIENTRY Uniform4iv(GLint location, GLsizei count, const GLint* v) -{ - EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateUniform(context, GL_INT_VEC4, location, count)) - { - return; - } - - Program *program = context->getState().getProgram(); - program->setUniform4iv(location, count, v); - } -} - -void GL_APIENTRY UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) -{ - EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", - location, count, transpose, value); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose)) - { - return; - } - - Program *program = context->getState().getProgram(); - program->setUniformMatrix2fv(location, count, transpose, value); - } -} - -void GL_APIENTRY UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) -{ - EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", - location, count, transpose, value); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose)) - { - return; - } - - Program *program = context->getState().getProgram(); - program->setUniformMatrix3fv(location, count, transpose, value); - } -} - -void GL_APIENTRY UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) -{ - EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", - location, count, transpose, value); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose)) - { - return; - } - - Program *program = context->getState().getProgram(); - program->setUniformMatrix4fv(location, count, transpose, value); - } -} - -void GL_APIENTRY UseProgram(GLuint program) -{ - EVENT("(GLuint program = %d)", program); - - Context *context = GetValidGlobalContext(); - if (context) - { - Program *programObject = context->getProgram(program); - - if (!programObject && program != 0) - { - if (context->getShader(program)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - else - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - } - - if (program != 0 && !programObject->isLinked()) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - context->useProgram(program); - } -} - -void GL_APIENTRY ValidateProgram(GLuint program) -{ - EVENT("(GLuint program = %d)", program); - - Context *context = GetValidGlobalContext(); - if (context) - { - Program *programObject = GetValidProgram(context, program); - - if (!programObject) - { - return; - } - - programObject->validate(context->getCaps()); - } -} - -void GL_APIENTRY VertexAttrib1f(GLuint index, GLfloat x) -{ - EVENT("(GLuint index = %d, GLfloat x = %f)", index, x); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (index >= MAX_VERTEX_ATTRIBS) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - GLfloat vals[4] = { x, 0, 0, 1 }; - context->getState().setVertexAttribf(index, vals); - } -} - -void GL_APIENTRY VertexAttrib1fv(GLuint index, const GLfloat* values) -{ - EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (index >= MAX_VERTEX_ATTRIBS) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - GLfloat vals[4] = { values[0], 0, 0, 1 }; - context->getState().setVertexAttribf(index, vals); - } -} - -void GL_APIENTRY VertexAttrib2f(GLuint index, GLfloat x, GLfloat y) -{ - EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (index >= MAX_VERTEX_ATTRIBS) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - GLfloat vals[4] = { x, y, 0, 1 }; - context->getState().setVertexAttribf(index, vals); - } -} - -void GL_APIENTRY VertexAttrib2fv(GLuint index, const GLfloat* values) -{ - EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (index >= MAX_VERTEX_ATTRIBS) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - GLfloat vals[4] = { values[0], values[1], 0, 1 }; - context->getState().setVertexAttribf(index, vals); - } -} - -void GL_APIENTRY VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) -{ - EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (index >= MAX_VERTEX_ATTRIBS) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - GLfloat vals[4] = { x, y, z, 1 }; - context->getState().setVertexAttribf(index, vals); - } -} - -void GL_APIENTRY VertexAttrib3fv(GLuint index, const GLfloat* values) -{ - EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (index >= MAX_VERTEX_ATTRIBS) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - GLfloat vals[4] = { values[0], values[1], values[2], 1 }; - context->getState().setVertexAttribf(index, vals); - } -} - -void GL_APIENTRY VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) -{ - EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (index >= MAX_VERTEX_ATTRIBS) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - GLfloat vals[4] = { x, y, z, w }; - context->getState().setVertexAttribf(index, vals); - } -} - -void GL_APIENTRY VertexAttrib4fv(GLuint index, const GLfloat* values) -{ - EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (index >= MAX_VERTEX_ATTRIBS) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - context->getState().setVertexAttribf(index, values); - } -} - -void GL_APIENTRY VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr) -{ - EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, " - "GLboolean normalized = %u, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)", - index, size, type, normalized, stride, ptr); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (index >= MAX_VERTEX_ATTRIBS) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - if (size < 1 || size > 4) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - switch (type) - { - case GL_BYTE: - case GL_UNSIGNED_BYTE: - case GL_SHORT: - case GL_UNSIGNED_SHORT: - case GL_FIXED: - case GL_FLOAT: - break; - - case GL_HALF_FLOAT: - case GL_INT: - case GL_UNSIGNED_INT: - case GL_INT_2_10_10_10_REV: - case GL_UNSIGNED_INT_2_10_10_10_REV: - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - if (stride < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - if ((type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV) && size != 4) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - // [OpenGL ES 3.0.2] Section 2.8 page 24: - // An INVALID_OPERATION error is generated when a non-zero vertex array object - // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point, - // and the pointer argument is not NULL. - if (context->getState().getVertexArray()->id() != 0 && context->getState().getArrayBufferId() == 0 && ptr != NULL) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - context->getState().setVertexAttribState(index, context->getState().getTargetBuffer(GL_ARRAY_BUFFER), size, type, - normalized == GL_TRUE, false, stride, ptr); - } -} - -void GL_APIENTRY Viewport(GLint x, GLint y, GLsizei width, GLsizei height) -{ - EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (width < 0 || height < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - context->getState().setViewportParams(x, y, width, height); - } -} - -} diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0.h b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0.h deleted file mode 100644 index eee5fb5468..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0.h +++ /dev/null @@ -1,163 +0,0 @@ -// -// Copyright(c) 2014 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// entry_points_gles_2_0.h : Defines the GLES 2.0 entry points. - -#ifndef LIBGLESV2_ENTRYPOINTGLES20_H_ -#define LIBGLESV2_ENTRYPOINTGLES20_H_ - -#include -#include - -namespace gl -{ - -ANGLE_EXPORT void GL_APIENTRY ActiveTexture(GLenum texture); -ANGLE_EXPORT void GL_APIENTRY AttachShader(GLuint program, GLuint shader); -ANGLE_EXPORT void GL_APIENTRY BindAttribLocation(GLuint program, GLuint index, const GLchar* name); -ANGLE_EXPORT void GL_APIENTRY BindBuffer(GLenum target, GLuint buffer); -ANGLE_EXPORT void GL_APIENTRY BindFramebuffer(GLenum target, GLuint framebuffer); -ANGLE_EXPORT void GL_APIENTRY BindRenderbuffer(GLenum target, GLuint renderbuffer); -ANGLE_EXPORT void GL_APIENTRY BindTexture(GLenum target, GLuint texture); -ANGLE_EXPORT void GL_APIENTRY BlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -ANGLE_EXPORT void GL_APIENTRY BlendEquation(GLenum mode); -ANGLE_EXPORT void GL_APIENTRY BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha); -ANGLE_EXPORT void GL_APIENTRY BlendFunc(GLenum sfactor, GLenum dfactor); -ANGLE_EXPORT void GL_APIENTRY BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -ANGLE_EXPORT void GL_APIENTRY BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage); -ANGLE_EXPORT void GL_APIENTRY BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data); -ANGLE_EXPORT GLenum GL_APIENTRY CheckFramebufferStatus(GLenum target); -ANGLE_EXPORT void GL_APIENTRY Clear(GLbitfield mask); -ANGLE_EXPORT void GL_APIENTRY ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -ANGLE_EXPORT void GL_APIENTRY ClearDepthf(GLfloat depth); -ANGLE_EXPORT void GL_APIENTRY ClearStencil(GLint s); -ANGLE_EXPORT void GL_APIENTRY ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); -ANGLE_EXPORT void GL_APIENTRY CompileShader(GLuint shader); -ANGLE_EXPORT void GL_APIENTRY CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data); -ANGLE_EXPORT void GL_APIENTRY CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data); -ANGLE_EXPORT void GL_APIENTRY CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -ANGLE_EXPORT void GL_APIENTRY CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -ANGLE_EXPORT GLuint GL_APIENTRY CreateProgram(void); -ANGLE_EXPORT GLuint GL_APIENTRY CreateShader(GLenum type); -ANGLE_EXPORT void GL_APIENTRY CullFace(GLenum mode); -ANGLE_EXPORT void GL_APIENTRY DeleteBuffers(GLsizei n, const GLuint* buffers); -ANGLE_EXPORT void GL_APIENTRY DeleteFramebuffers(GLsizei n, const GLuint* framebuffers); -ANGLE_EXPORT void GL_APIENTRY DeleteProgram(GLuint program); -ANGLE_EXPORT void GL_APIENTRY DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers); -ANGLE_EXPORT void GL_APIENTRY DeleteShader(GLuint shader); -ANGLE_EXPORT void GL_APIENTRY DeleteTextures(GLsizei n, const GLuint* textures); -ANGLE_EXPORT void GL_APIENTRY DepthFunc(GLenum func); -ANGLE_EXPORT void GL_APIENTRY DepthMask(GLboolean flag); -ANGLE_EXPORT void GL_APIENTRY DepthRangef(GLfloat n, GLfloat f); -ANGLE_EXPORT void GL_APIENTRY DetachShader(GLuint program, GLuint shader); -ANGLE_EXPORT void GL_APIENTRY Disable(GLenum cap); -ANGLE_EXPORT void GL_APIENTRY DisableVertexAttribArray(GLuint index); -ANGLE_EXPORT void GL_APIENTRY DrawArrays(GLenum mode, GLint first, GLsizei count); -ANGLE_EXPORT void GL_APIENTRY DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices); -ANGLE_EXPORT void GL_APIENTRY Enable(GLenum cap); -ANGLE_EXPORT void GL_APIENTRY EnableVertexAttribArray(GLuint index); -ANGLE_EXPORT void GL_APIENTRY Finish(void); -ANGLE_EXPORT void GL_APIENTRY Flush(void); -ANGLE_EXPORT void GL_APIENTRY FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -ANGLE_EXPORT void GL_APIENTRY FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -ANGLE_EXPORT void GL_APIENTRY FrontFace(GLenum mode); -ANGLE_EXPORT void GL_APIENTRY GenBuffers(GLsizei n, GLuint* buffers); -ANGLE_EXPORT void GL_APIENTRY GenerateMipmap(GLenum target); -ANGLE_EXPORT void GL_APIENTRY GenFramebuffers(GLsizei n, GLuint* framebuffers); -ANGLE_EXPORT void GL_APIENTRY GenRenderbuffers(GLsizei n, GLuint* renderbuffers); -ANGLE_EXPORT void GL_APIENTRY GenTextures(GLsizei n, GLuint* textures); -ANGLE_EXPORT void GL_APIENTRY GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name); -ANGLE_EXPORT void GL_APIENTRY GetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name); -ANGLE_EXPORT void GL_APIENTRY GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders); -ANGLE_EXPORT GLint GL_APIENTRY GetAttribLocation(GLuint program, const GLchar* name); -ANGLE_EXPORT void GL_APIENTRY GetBooleanv(GLenum pname, GLboolean* params); -ANGLE_EXPORT void GL_APIENTRY GetBufferParameteriv(GLenum target, GLenum pname, GLint* params); -ANGLE_EXPORT GLenum GL_APIENTRY GetError(void); -ANGLE_EXPORT void GL_APIENTRY GetFloatv(GLenum pname, GLfloat* params); -ANGLE_EXPORT void GL_APIENTRY GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params); -ANGLE_EXPORT void GL_APIENTRY GetIntegerv(GLenum pname, GLint* params); -ANGLE_EXPORT void GL_APIENTRY GetProgramiv(GLuint program, GLenum pname, GLint* params); -ANGLE_EXPORT void GL_APIENTRY GetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog); -ANGLE_EXPORT void GL_APIENTRY GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params); -ANGLE_EXPORT void GL_APIENTRY GetShaderiv(GLuint shader, GLenum pname, GLint* params); -ANGLE_EXPORT void GL_APIENTRY GetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog); -ANGLE_EXPORT void GL_APIENTRY GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision); -ANGLE_EXPORT void GL_APIENTRY GetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source); -ANGLE_EXPORT const GLubyte *GL_APIENTRY GetString(GLenum name); -ANGLE_EXPORT void GL_APIENTRY GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params); -ANGLE_EXPORT void GL_APIENTRY GetTexParameteriv(GLenum target, GLenum pname, GLint* params); -ANGLE_EXPORT void GL_APIENTRY GetUniformfv(GLuint program, GLint location, GLfloat* params); -ANGLE_EXPORT void GL_APIENTRY GetUniformiv(GLuint program, GLint location, GLint* params); -ANGLE_EXPORT GLint GL_APIENTRY GetUniformLocation(GLuint program, const GLchar* name); -ANGLE_EXPORT void GL_APIENTRY GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params); -ANGLE_EXPORT void GL_APIENTRY GetVertexAttribiv(GLuint index, GLenum pname, GLint* params); -ANGLE_EXPORT void GL_APIENTRY GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer); -ANGLE_EXPORT void GL_APIENTRY Hint(GLenum target, GLenum mode); -ANGLE_EXPORT GLboolean GL_APIENTRY IsBuffer(GLuint buffer); -ANGLE_EXPORT GLboolean GL_APIENTRY IsEnabled(GLenum cap); -ANGLE_EXPORT GLboolean GL_APIENTRY IsFramebuffer(GLuint framebuffer); -ANGLE_EXPORT GLboolean GL_APIENTRY IsProgram(GLuint program); -ANGLE_EXPORT GLboolean GL_APIENTRY IsRenderbuffer(GLuint renderbuffer); -ANGLE_EXPORT GLboolean GL_APIENTRY IsShader(GLuint shader); -ANGLE_EXPORT GLboolean GL_APIENTRY IsTexture(GLuint texture); -ANGLE_EXPORT void GL_APIENTRY LineWidth(GLfloat width); -ANGLE_EXPORT void GL_APIENTRY LinkProgram(GLuint program); -ANGLE_EXPORT void GL_APIENTRY PixelStorei(GLenum pname, GLint param); -ANGLE_EXPORT void GL_APIENTRY PolygonOffset(GLfloat factor, GLfloat units); -ANGLE_EXPORT void GL_APIENTRY ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels); -ANGLE_EXPORT void GL_APIENTRY ReleaseShaderCompiler(void); -ANGLE_EXPORT void GL_APIENTRY RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -ANGLE_EXPORT void GL_APIENTRY SampleCoverage(GLfloat value, GLboolean invert); -ANGLE_EXPORT void GL_APIENTRY Scissor(GLint x, GLint y, GLsizei width, GLsizei height); -ANGLE_EXPORT void GL_APIENTRY ShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length); -ANGLE_EXPORT void GL_APIENTRY ShaderSource(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length); -ANGLE_EXPORT void GL_APIENTRY StencilFunc(GLenum func, GLint ref, GLuint mask); -ANGLE_EXPORT void GL_APIENTRY StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask); -ANGLE_EXPORT void GL_APIENTRY StencilMask(GLuint mask); -ANGLE_EXPORT void GL_APIENTRY StencilMaskSeparate(GLenum face, GLuint mask); -ANGLE_EXPORT void GL_APIENTRY StencilOp(GLenum fail, GLenum zfail, GLenum zpass); -ANGLE_EXPORT void GL_APIENTRY StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass); -ANGLE_EXPORT void GL_APIENTRY TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels); -ANGLE_EXPORT void GL_APIENTRY TexParameterf(GLenum target, GLenum pname, GLfloat param); -ANGLE_EXPORT void GL_APIENTRY TexParameterfv(GLenum target, GLenum pname, const GLfloat* params); -ANGLE_EXPORT void GL_APIENTRY TexParameteri(GLenum target, GLenum pname, GLint param); -ANGLE_EXPORT void GL_APIENTRY TexParameteriv(GLenum target, GLenum pname, const GLint* params); -ANGLE_EXPORT void GL_APIENTRY TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels); -ANGLE_EXPORT void GL_APIENTRY Uniform1f(GLint location, GLfloat x); -ANGLE_EXPORT void GL_APIENTRY Uniform1fv(GLint location, GLsizei count, const GLfloat* v); -ANGLE_EXPORT void GL_APIENTRY Uniform1i(GLint location, GLint x); -ANGLE_EXPORT void GL_APIENTRY Uniform1iv(GLint location, GLsizei count, const GLint* v); -ANGLE_EXPORT void GL_APIENTRY Uniform2f(GLint location, GLfloat x, GLfloat y); -ANGLE_EXPORT void GL_APIENTRY Uniform2fv(GLint location, GLsizei count, const GLfloat* v); -ANGLE_EXPORT void GL_APIENTRY Uniform2i(GLint location, GLint x, GLint y); -ANGLE_EXPORT void GL_APIENTRY Uniform2iv(GLint location, GLsizei count, const GLint* v); -ANGLE_EXPORT void GL_APIENTRY Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z); -ANGLE_EXPORT void GL_APIENTRY Uniform3fv(GLint location, GLsizei count, const GLfloat* v); -ANGLE_EXPORT void GL_APIENTRY Uniform3i(GLint location, GLint x, GLint y, GLint z); -ANGLE_EXPORT void GL_APIENTRY Uniform3iv(GLint location, GLsizei count, const GLint* v); -ANGLE_EXPORT void GL_APIENTRY Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -ANGLE_EXPORT void GL_APIENTRY Uniform4fv(GLint location, GLsizei count, const GLfloat* v); -ANGLE_EXPORT void GL_APIENTRY Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w); -ANGLE_EXPORT void GL_APIENTRY Uniform4iv(GLint location, GLsizei count, const GLint* v); -ANGLE_EXPORT void GL_APIENTRY UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -ANGLE_EXPORT void GL_APIENTRY UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -ANGLE_EXPORT void GL_APIENTRY UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -ANGLE_EXPORT void GL_APIENTRY UseProgram(GLuint program); -ANGLE_EXPORT void GL_APIENTRY ValidateProgram(GLuint program); -ANGLE_EXPORT void GL_APIENTRY VertexAttrib1f(GLuint indx, GLfloat x); -ANGLE_EXPORT void GL_APIENTRY VertexAttrib1fv(GLuint indx, const GLfloat* values); -ANGLE_EXPORT void GL_APIENTRY VertexAttrib2f(GLuint indx, GLfloat x, GLfloat y); -ANGLE_EXPORT void GL_APIENTRY VertexAttrib2fv(GLuint indx, const GLfloat* values); -ANGLE_EXPORT void GL_APIENTRY VertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z); -ANGLE_EXPORT void GL_APIENTRY VertexAttrib3fv(GLuint indx, const GLfloat* values); -ANGLE_EXPORT void GL_APIENTRY VertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -ANGLE_EXPORT void GL_APIENTRY VertexAttrib4fv(GLuint indx, const GLfloat* values); -ANGLE_EXPORT void GL_APIENTRY VertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr); -ANGLE_EXPORT void GL_APIENTRY Viewport(GLint x, GLint y, GLsizei width, GLsizei height); - -} - -#endif // LIBGLESV2_ENTRYPOINTGLES20_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_autogen.cpp b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_autogen.cpp new file mode 100644 index 0000000000..ae0e944406 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_autogen.cpp @@ -0,0 +1,2612 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml. +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// entry_points_gles_2_0_autogen.cpp: +// Defines the GLES 2.0 entry points. + +#include "libANGLE/Context.h" +#include "libANGLE/validationES2.h" +#include "libGLESv2/global_state.h" + +namespace gl +{ +void GL_APIENTRY ActiveTexture(GLenum texture) +{ + EVENT("(GLenum texture = 0x%X)", texture); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(texture); + + if (context->skipValidation() || ValidateActiveTexture(context, texture)) + { + context->activeTexture(texture); + } + } +} + +void GL_APIENTRY AttachShader(GLuint program, GLuint shader) +{ + EVENT("(GLuint program = %u, GLuint shader = %u)", program, shader); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, shader); + + if (context->skipValidation() || ValidateAttachShader(context, program, shader)) + { + context->attachShader(program, shader); + } + } +} + +void GL_APIENTRY BindAttribLocation(GLuint program, GLuint index, const GLchar *name) +{ + EVENT("(GLuint program = %u, GLuint index = %u, const GLchar *name = 0x%0.8p)", program, index, + name); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, index, name); + + if (context->skipValidation() || ValidateBindAttribLocation(context, program, index, name)) + { + context->bindAttribLocation(program, index, name); + } + } +} + +void GL_APIENTRY BindBuffer(GLenum target, GLuint buffer) +{ + EVENT("(GLenum target = 0x%X, GLuint buffer = %u)", target, buffer); + + Context *context = GetValidGlobalContext(); + if (context) + { + BufferBinding targetPacked = FromGLenum(target); + context->gatherParams(targetPacked, buffer); + + if (context->skipValidation() || ValidateBindBuffer(context, targetPacked, buffer)) + { + context->bindBuffer(targetPacked, buffer); + } + } +} + +void GL_APIENTRY BindFramebuffer(GLenum target, GLuint framebuffer) +{ + EVENT("(GLenum target = 0x%X, GLuint framebuffer = %u)", target, framebuffer); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, framebuffer); + + if (context->skipValidation() || ValidateBindFramebuffer(context, target, framebuffer)) + { + context->bindFramebuffer(target, framebuffer); + } + } +} + +void GL_APIENTRY BindRenderbuffer(GLenum target, GLuint renderbuffer) +{ + EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %u)", target, renderbuffer); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, renderbuffer); + + if (context->skipValidation() || ValidateBindRenderbuffer(context, target, renderbuffer)) + { + context->bindRenderbuffer(target, renderbuffer); + } + } +} + +void GL_APIENTRY BindTexture(GLenum target, GLuint texture) +{ + EVENT("(GLenum target = 0x%X, GLuint texture = %u)", target, texture); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, texture); + + if (context->skipValidation() || ValidateBindTexture(context, target, texture)) + { + context->bindTexture(target, texture); + } + } +} + +void GL_APIENTRY BlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) +{ + EVENT("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f, GLfloat alpha = %f)", red, + green, blue, alpha); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(red, green, blue, alpha); + + if (context->skipValidation() || ValidateBlendColor(context, red, green, blue, alpha)) + { + context->blendColor(red, green, blue, alpha); + } + } +} + +void GL_APIENTRY BlendEquation(GLenum mode) +{ + EVENT("(GLenum mode = 0x%X)", mode); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(mode); + + if (context->skipValidation() || ValidateBlendEquation(context, mode)) + { + context->blendEquation(mode); + } + } +} + +void GL_APIENTRY BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) +{ + EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(modeRGB, modeAlpha); + + if (context->skipValidation() || ValidateBlendEquationSeparate(context, modeRGB, modeAlpha)) + { + context->blendEquationSeparate(modeRGB, modeAlpha); + } + } +} + +void GL_APIENTRY BlendFunc(GLenum sfactor, GLenum dfactor) +{ + EVENT("(GLenum sfactor = 0x%X, GLenum dfactor = 0x%X)", sfactor, dfactor); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(sfactor, dfactor); + + if (context->skipValidation() || ValidateBlendFunc(context, sfactor, dfactor)) + { + context->blendFunc(sfactor, dfactor); + } + } +} + +void GL_APIENTRY BlendFuncSeparate(GLenum sfactorRGB, + GLenum dfactorRGB, + GLenum sfactorAlpha, + GLenum dfactorAlpha) +{ + EVENT( + "(GLenum sfactorRGB = 0x%X, GLenum dfactorRGB = 0x%X, GLenum sfactorAlpha = 0x%X, GLenum " + "dfactorAlpha = 0x%X)", + sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(sfactorRGB, dfactorRGB, sfactorAlpha, + dfactorAlpha); + + if (context->skipValidation() || + ValidateBlendFuncSeparate(context, sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha)) + { + context->blendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); + } + } +} + +void GL_APIENTRY BufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage) +{ + EVENT( + "(GLenum target = 0x%X, GLsizeiptr size = %d, const void *data = 0x%0.8p, GLenum usage = " + "0x%X)", + target, size, data, usage); + + Context *context = GetValidGlobalContext(); + if (context) + { + BufferBinding targetPacked = FromGLenum(target); + BufferUsage usagePacked = FromGLenum(usage); + context->gatherParams(targetPacked, size, data, usagePacked); + + if (context->skipValidation() || + ValidateBufferData(context, targetPacked, size, data, usagePacked)) + { + context->bufferData(targetPacked, size, data, usagePacked); + } + } +} + +void GL_APIENTRY BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data) +{ + EVENT( + "(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const void *data = " + "0x%0.8p)", + target, offset, size, data); + + Context *context = GetValidGlobalContext(); + if (context) + { + BufferBinding targetPacked = FromGLenum(target); + context->gatherParams(targetPacked, offset, size, data); + + if (context->skipValidation() || + ValidateBufferSubData(context, targetPacked, offset, size, data)) + { + context->bufferSubData(targetPacked, offset, size, data); + } + } +} + +GLenum GL_APIENTRY CheckFramebufferStatus(GLenum target) +{ + EVENT("(GLenum target = 0x%X)", target); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target); + + if (context->skipValidation() || ValidateCheckFramebufferStatus(context, target)) + { + return context->checkFramebufferStatus(target); + } + } + + return GetDefaultReturnValue(); +} + +void GL_APIENTRY Clear(GLbitfield mask) +{ + EVENT("(GLbitfield mask = 0x%X)", mask); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(mask); + + if (context->skipValidation() || ValidateClear(context, mask)) + { + context->clear(mask); + } + } +} + +void GL_APIENTRY ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) +{ + EVENT("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f, GLfloat alpha = %f)", red, + green, blue, alpha); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(red, green, blue, alpha); + + if (context->skipValidation() || ValidateClearColor(context, red, green, blue, alpha)) + { + context->clearColor(red, green, blue, alpha); + } + } +} + +void GL_APIENTRY ClearDepthf(GLfloat d) +{ + EVENT("(GLfloat d = %f)", d); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(d); + + if (context->skipValidation() || ValidateClearDepthf(context, d)) + { + context->clearDepthf(d); + } + } +} + +void GL_APIENTRY ClearStencil(GLint s) +{ + EVENT("(GLint s = %d)", s); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(s); + + if (context->skipValidation() || ValidateClearStencil(context, s)) + { + context->clearStencil(s); + } + } +} + +void GL_APIENTRY ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) +{ + EVENT("(GLboolean red = %u, GLboolean green = %u, GLboolean blue = %u, GLboolean alpha = %u)", + red, green, blue, alpha); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(red, green, blue, alpha); + + if (context->skipValidation() || ValidateColorMask(context, red, green, blue, alpha)) + { + context->colorMask(red, green, blue, alpha); + } + } +} + +void GL_APIENTRY CompileShader(GLuint shader) +{ + EVENT("(GLuint shader = %u)", shader); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(shader); + + if (context->skipValidation() || ValidateCompileShader(context, shader)) + { + context->compileShader(shader); + } + } +} + +void GL_APIENTRY CompressedTexImage2D(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + const void *data) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = " + "%d, GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const void *data = " + "0x%0.8p)", + target, level, internalformat, width, height, border, imageSize, data); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams( + target, level, internalformat, width, height, border, imageSize, data); + + if (context->skipValidation() || + ValidateCompressedTexImage2D(context, target, level, internalformat, width, height, + border, imageSize, data)) + { + context->compressedTexImage2D(target, level, internalformat, width, height, border, + imageSize, data); + } + } +} + +void GL_APIENTRY CompressedTexSubImage2D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const void *data) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, GLsizei " + "width = %d, GLsizei height = %d, GLenum format = 0x%X, GLsizei imageSize = %d, const void " + "*data = 0x%0.8p)", + target, level, xoffset, yoffset, width, height, format, imageSize, data); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams( + target, level, xoffset, yoffset, width, height, format, imageSize, data); + + if (context->skipValidation() || + ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height, + format, imageSize, data)) + { + context->compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, + imageSize, data); + } + } +} + +void GL_APIENTRY CopyTexImage2D(GLenum target, + GLint level, + GLenum internalformat, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLint x = %d, " + "GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)", + target, level, internalformat, x, y, width, height, border); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, level, internalformat, x, y, + width, height, border); + + if (context->skipValidation() || + ValidateCopyTexImage2D(context, target, level, internalformat, x, y, width, height, + border)) + { + context->copyTexImage2D(target, level, internalformat, x, y, width, height, border); + } + } +} + +void GL_APIENTRY CopyTexSubImage2D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, GLint x " + "= %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", + target, level, xoffset, yoffset, x, y, width, height); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, level, xoffset, yoffset, x, y, + width, height); + + if (context->skipValidation() || ValidateCopyTexSubImage2D(context, target, level, xoffset, + yoffset, x, y, width, height)) + { + context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); + } + } +} + +GLuint GL_APIENTRY CreateProgram() +{ + EVENT("()"); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(); + + if (context->skipValidation() || ValidateCreateProgram(context)) + { + return context->createProgram(); + } + } + + return GetDefaultReturnValue(); +} + +GLuint GL_APIENTRY CreateShader(GLenum type) +{ + EVENT("(GLenum type = 0x%X)", type); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(type); + + if (context->skipValidation() || ValidateCreateShader(context, type)) + { + return context->createShader(type); + } + } + + return GetDefaultReturnValue(); +} + +void GL_APIENTRY CullFace(GLenum mode) +{ + EVENT("(GLenum mode = 0x%X)", mode); + + Context *context = GetValidGlobalContext(); + if (context) + { + CullFaceMode modePacked = FromGLenum(mode); + context->gatherParams(modePacked); + + if (context->skipValidation() || ValidateCullFace(context, modePacked)) + { + context->cullFace(modePacked); + } + } +} + +void GL_APIENTRY DeleteBuffers(GLsizei n, const GLuint *buffers) +{ + EVENT("(GLsizei n = %d, const GLuint *buffers = 0x%0.8p)", n, buffers); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(n, buffers); + + if (context->skipValidation() || ValidateDeleteBuffers(context, n, buffers)) + { + context->deleteBuffers(n, buffers); + } + } +} + +void GL_APIENTRY DeleteFramebuffers(GLsizei n, const GLuint *framebuffers) +{ + EVENT("(GLsizei n = %d, const GLuint *framebuffers = 0x%0.8p)", n, framebuffers); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(n, framebuffers); + + if (context->skipValidation() || ValidateDeleteFramebuffers(context, n, framebuffers)) + { + context->deleteFramebuffers(n, framebuffers); + } + } +} + +void GL_APIENTRY DeleteProgram(GLuint program) +{ + EVENT("(GLuint program = %u)", program); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program); + + if (context->skipValidation() || ValidateDeleteProgram(context, program)) + { + context->deleteProgram(program); + } + } +} + +void GL_APIENTRY DeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers) +{ + EVENT("(GLsizei n = %d, const GLuint *renderbuffers = 0x%0.8p)", n, renderbuffers); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(n, renderbuffers); + + if (context->skipValidation() || ValidateDeleteRenderbuffers(context, n, renderbuffers)) + { + context->deleteRenderbuffers(n, renderbuffers); + } + } +} + +void GL_APIENTRY DeleteShader(GLuint shader) +{ + EVENT("(GLuint shader = %u)", shader); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(shader); + + if (context->skipValidation() || ValidateDeleteShader(context, shader)) + { + context->deleteShader(shader); + } + } +} + +void GL_APIENTRY DeleteTextures(GLsizei n, const GLuint *textures) +{ + EVENT("(GLsizei n = %d, const GLuint *textures = 0x%0.8p)", n, textures); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(n, textures); + + if (context->skipValidation() || ValidateDeleteTextures(context, n, textures)) + { + context->deleteTextures(n, textures); + } + } +} + +void GL_APIENTRY DepthFunc(GLenum func) +{ + EVENT("(GLenum func = 0x%X)", func); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(func); + + if (context->skipValidation() || ValidateDepthFunc(context, func)) + { + context->depthFunc(func); + } + } +} + +void GL_APIENTRY DepthMask(GLboolean flag) +{ + EVENT("(GLboolean flag = %u)", flag); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(flag); + + if (context->skipValidation() || ValidateDepthMask(context, flag)) + { + context->depthMask(flag); + } + } +} + +void GL_APIENTRY DepthRangef(GLfloat n, GLfloat f) +{ + EVENT("(GLfloat n = %f, GLfloat f = %f)", n, f); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(n, f); + + if (context->skipValidation() || ValidateDepthRangef(context, n, f)) + { + context->depthRangef(n, f); + } + } +} + +void GL_APIENTRY DetachShader(GLuint program, GLuint shader) +{ + EVENT("(GLuint program = %u, GLuint shader = %u)", program, shader); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, shader); + + if (context->skipValidation() || ValidateDetachShader(context, program, shader)) + { + context->detachShader(program, shader); + } + } +} + +void GL_APIENTRY Disable(GLenum cap) +{ + EVENT("(GLenum cap = 0x%X)", cap); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(cap); + + if (context->skipValidation() || ValidateDisable(context, cap)) + { + context->disable(cap); + } + } +} + +void GL_APIENTRY DisableVertexAttribArray(GLuint index) +{ + EVENT("(GLuint index = %u)", index); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(index); + + if (context->skipValidation() || ValidateDisableVertexAttribArray(context, index)) + { + context->disableVertexAttribArray(index); + } + } +} + +void GL_APIENTRY DrawArrays(GLenum mode, GLint first, GLsizei count) +{ + EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(mode, first, count); + + if (context->skipValidation() || ValidateDrawArrays(context, mode, first, count)) + { + context->drawArrays(mode, first, count); + } + } +} + +void GL_APIENTRY DrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) +{ + EVENT( + "(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = " + "0x%0.8p)", + mode, count, type, indices); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(mode, count, type, indices); + + if (context->skipValidation() || ValidateDrawElements(context, mode, count, type, indices)) + { + context->drawElements(mode, count, type, indices); + } + } +} + +void GL_APIENTRY Enable(GLenum cap) +{ + EVENT("(GLenum cap = 0x%X)", cap); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(cap); + + if (context->skipValidation() || ValidateEnable(context, cap)) + { + context->enable(cap); + } + } +} + +void GL_APIENTRY EnableVertexAttribArray(GLuint index) +{ + EVENT("(GLuint index = %u)", index); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(index); + + if (context->skipValidation() || ValidateEnableVertexAttribArray(context, index)) + { + context->enableVertexAttribArray(index); + } + } +} + +void GL_APIENTRY Finish() +{ + EVENT("()"); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(); + + if (context->skipValidation() || ValidateFinish(context)) + { + context->finish(); + } + } +} + +void GL_APIENTRY Flush() +{ + EVENT("()"); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(); + + if (context->skipValidation() || ValidateFlush(context)) + { + context->flush(); + } + } +} + +void GL_APIENTRY FramebufferRenderbuffer(GLenum target, + GLenum attachment, + GLenum renderbuffertarget, + GLuint renderbuffer) +{ + EVENT( + "(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, GLuint " + "renderbuffer = %u)", + target, attachment, renderbuffertarget, renderbuffer); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams( + target, attachment, renderbuffertarget, renderbuffer); + + if (context->skipValidation() || + ValidateFramebufferRenderbuffer(context, target, attachment, renderbuffertarget, + renderbuffer)) + { + context->framebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer); + } + } +} + +void GL_APIENTRY FramebufferTexture2D(GLenum target, + GLenum attachment, + GLenum textarget, + GLuint texture, + GLint level) +{ + EVENT( + "(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, GLuint texture " + "= %u, GLint level = %d)", + target, attachment, textarget, texture, level); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, attachment, textarget, + texture, level); + + if (context->skipValidation() || + ValidateFramebufferTexture2D(context, target, attachment, textarget, texture, level)) + { + context->framebufferTexture2D(target, attachment, textarget, texture, level); + } + } +} + +void GL_APIENTRY FrontFace(GLenum mode) +{ + EVENT("(GLenum mode = 0x%X)", mode); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(mode); + + if (context->skipValidation() || ValidateFrontFace(context, mode)) + { + context->frontFace(mode); + } + } +} + +void GL_APIENTRY GenBuffers(GLsizei n, GLuint *buffers) +{ + EVENT("(GLsizei n = %d, GLuint *buffers = 0x%0.8p)", n, buffers); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(n, buffers); + + if (context->skipValidation() || ValidateGenBuffers(context, n, buffers)) + { + context->genBuffers(n, buffers); + } + } +} + +void GL_APIENTRY GenerateMipmap(GLenum target) +{ + EVENT("(GLenum target = 0x%X)", target); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target); + + if (context->skipValidation() || ValidateGenerateMipmap(context, target)) + { + context->generateMipmap(target); + } + } +} + +void GL_APIENTRY GenFramebuffers(GLsizei n, GLuint *framebuffers) +{ + EVENT("(GLsizei n = %d, GLuint *framebuffers = 0x%0.8p)", n, framebuffers); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(n, framebuffers); + + if (context->skipValidation() || ValidateGenFramebuffers(context, n, framebuffers)) + { + context->genFramebuffers(n, framebuffers); + } + } +} + +void GL_APIENTRY GenRenderbuffers(GLsizei n, GLuint *renderbuffers) +{ + EVENT("(GLsizei n = %d, GLuint *renderbuffers = 0x%0.8p)", n, renderbuffers); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(n, renderbuffers); + + if (context->skipValidation() || ValidateGenRenderbuffers(context, n, renderbuffers)) + { + context->genRenderbuffers(n, renderbuffers); + } + } +} + +void GL_APIENTRY GenTextures(GLsizei n, GLuint *textures) +{ + EVENT("(GLsizei n = %d, GLuint *textures = 0x%0.8p)", n, textures); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(n, textures); + + if (context->skipValidation() || ValidateGenTextures(context, n, textures)) + { + context->genTextures(n, textures); + } + } +} + +void GL_APIENTRY GetActiveAttrib(GLuint program, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name) +{ + EVENT( + "(GLuint program = %u, GLuint index = %u, GLsizei bufSize = %d, GLsizei *length = 0x%0.8p, " + "GLint *size = 0x%0.8p, GLenum *type = 0x%0.8p, GLchar *name = 0x%0.8p)", + program, index, bufSize, length, size, type, name); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, index, bufSize, length, size, + type, name); + + if (context->skipValidation() || + ValidateGetActiveAttrib(context, program, index, bufSize, length, size, type, name)) + { + context->getActiveAttrib(program, index, bufSize, length, size, type, name); + } + } +} + +void GL_APIENTRY GetActiveUniform(GLuint program, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name) +{ + EVENT( + "(GLuint program = %u, GLuint index = %u, GLsizei bufSize = %d, GLsizei *length = 0x%0.8p, " + "GLint *size = 0x%0.8p, GLenum *type = 0x%0.8p, GLchar *name = 0x%0.8p)", + program, index, bufSize, length, size, type, name); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, index, bufSize, length, size, + type, name); + + if (context->skipValidation() || + ValidateGetActiveUniform(context, program, index, bufSize, length, size, type, name)) + { + context->getActiveUniform(program, index, bufSize, length, size, type, name); + } + } +} + +void GL_APIENTRY GetAttachedShaders(GLuint program, + GLsizei maxCount, + GLsizei *count, + GLuint *shaders) +{ + EVENT( + "(GLuint program = %u, GLsizei maxCount = %d, GLsizei *count = 0x%0.8p, GLuint *shaders = " + "0x%0.8p)", + program, maxCount, count, shaders); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, maxCount, count, shaders); + + if (context->skipValidation() || + ValidateGetAttachedShaders(context, program, maxCount, count, shaders)) + { + context->getAttachedShaders(program, maxCount, count, shaders); + } + } +} + +GLint GL_APIENTRY GetAttribLocation(GLuint program, const GLchar *name) +{ + EVENT("(GLuint program = %u, const GLchar *name = 0x%0.8p)", program, name); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, name); + + if (context->skipValidation() || ValidateGetAttribLocation(context, program, name)) + { + return context->getAttribLocation(program, name); + } + } + + return GetDefaultReturnValue(); +} + +void GL_APIENTRY GetBooleanv(GLenum pname, GLboolean *data) +{ + EVENT("(GLenum pname = 0x%X, GLboolean *data = 0x%0.8p)", pname, data); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(pname, data); + + if (context->skipValidation() || ValidateGetBooleanv(context, pname, data)) + { + context->getBooleanv(pname, data); + } + } +} + +void GL_APIENTRY GetBufferParameteriv(GLenum target, GLenum pname, GLint *params) +{ + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, + params); + + Context *context = GetValidGlobalContext(); + if (context) + { + BufferBinding targetPacked = FromGLenum(target); + context->gatherParams(targetPacked, pname, params); + + if (context->skipValidation() || + ValidateGetBufferParameteriv(context, targetPacked, pname, params)) + { + context->getBufferParameteriv(targetPacked, pname, params); + } + } +} + +GLenum GL_APIENTRY GetError() +{ + EVENT("()"); + + Context *context = GetGlobalContext(); + if (context) + { + context->gatherParams(); + + if (context->skipValidation() || ValidateGetError(context)) + { + return context->getError(); + } + } + + return GetDefaultReturnValue(); +} + +void GL_APIENTRY GetFloatv(GLenum pname, GLfloat *data) +{ + EVENT("(GLenum pname = 0x%X, GLfloat *data = 0x%0.8p)", pname, data); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(pname, data); + + if (context->skipValidation() || ValidateGetFloatv(context, pname, data)) + { + context->getFloatv(pname, data); + } + } +} + +void GL_APIENTRY GetFramebufferAttachmentParameteriv(GLenum target, + GLenum attachment, + GLenum pname, + GLint *params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint *params = " + "0x%0.8p)", + target, attachment, pname, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, attachment, + pname, params); + + if (context->skipValidation() || + ValidateGetFramebufferAttachmentParameteriv(context, target, attachment, pname, params)) + { + context->getFramebufferAttachmentParameteriv(target, attachment, pname, params); + } + } +} + +void GL_APIENTRY GetIntegerv(GLenum pname, GLint *data) +{ + EVENT("(GLenum pname = 0x%X, GLint *data = 0x%0.8p)", pname, data); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(pname, data); + + if (context->skipValidation() || ValidateGetIntegerv(context, pname, data)) + { + context->getIntegerv(pname, data); + } + } +} + +void GL_APIENTRY GetProgramiv(GLuint program, GLenum pname, GLint *params) +{ + EVENT("(GLuint program = %u, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", program, pname, + params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, pname, params); + + if (context->skipValidation() || ValidateGetProgramiv(context, program, pname, params)) + { + context->getProgramiv(program, pname, params); + } + } +} + +void GL_APIENTRY GetProgramInfoLog(GLuint program, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog) +{ + EVENT( + "(GLuint program = %u, GLsizei bufSize = %d, GLsizei *length = 0x%0.8p, GLchar *infoLog = " + "0x%0.8p)", + program, bufSize, length, infoLog); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, bufSize, length, infoLog); + + if (context->skipValidation() || + ValidateGetProgramInfoLog(context, program, bufSize, length, infoLog)) + { + context->getProgramInfoLog(program, bufSize, length, infoLog); + } + } +} + +void GL_APIENTRY GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params) +{ + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, + params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, pname, params); + + if (context->skipValidation() || + ValidateGetRenderbufferParameteriv(context, target, pname, params)) + { + context->getRenderbufferParameteriv(target, pname, params); + } + } +} + +void GL_APIENTRY GetShaderiv(GLuint shader, GLenum pname, GLint *params) +{ + EVENT("(GLuint shader = %u, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", shader, pname, + params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(shader, pname, params); + + if (context->skipValidation() || ValidateGetShaderiv(context, shader, pname, params)) + { + context->getShaderiv(shader, pname, params); + } + } +} + +void GL_APIENTRY GetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog) +{ + EVENT( + "(GLuint shader = %u, GLsizei bufSize = %d, GLsizei *length = 0x%0.8p, GLchar *infoLog = " + "0x%0.8p)", + shader, bufSize, length, infoLog); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(shader, bufSize, length, infoLog); + + if (context->skipValidation() || + ValidateGetShaderInfoLog(context, shader, bufSize, length, infoLog)) + { + context->getShaderInfoLog(shader, bufSize, length, infoLog); + } + } +} + +void GL_APIENTRY GetShaderPrecisionFormat(GLenum shadertype, + GLenum precisiontype, + GLint *range, + GLint *precision) +{ + EVENT( + "(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint *range = 0x%0.8p, GLint " + "*precision = 0x%0.8p)", + shadertype, precisiontype, range, precision); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(shadertype, precisiontype, + range, precision); + + if (context->skipValidation() || + ValidateGetShaderPrecisionFormat(context, shadertype, precisiontype, range, precision)) + { + context->getShaderPrecisionFormat(shadertype, precisiontype, range, precision); + } + } +} + +void GL_APIENTRY GetShaderSource(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source) +{ + EVENT( + "(GLuint shader = %u, GLsizei bufSize = %d, GLsizei *length = 0x%0.8p, GLchar *source = " + "0x%0.8p)", + shader, bufSize, length, source); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(shader, bufSize, length, source); + + if (context->skipValidation() || + ValidateGetShaderSource(context, shader, bufSize, length, source)) + { + context->getShaderSource(shader, bufSize, length, source); + } + } +} + +const GLubyte *GL_APIENTRY GetString(GLenum name) +{ + EVENT("(GLenum name = 0x%X)", name); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(name); + + if (context->skipValidation() || ValidateGetString(context, name)) + { + return context->getString(name); + } + } + + return GetDefaultReturnValue(); +} + +void GL_APIENTRY GetTexParameterfv(GLenum target, GLenum pname, GLfloat *params) +{ + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat *params = 0x%0.8p)", target, pname, + params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, pname, params); + + if (context->skipValidation() || ValidateGetTexParameterfv(context, target, pname, params)) + { + context->getTexParameterfv(target, pname, params); + } + } +} + +void GL_APIENTRY GetTexParameteriv(GLenum target, GLenum pname, GLint *params) +{ + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, + params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, pname, params); + + if (context->skipValidation() || ValidateGetTexParameteriv(context, target, pname, params)) + { + context->getTexParameteriv(target, pname, params); + } + } +} + +void GL_APIENTRY GetUniformfv(GLuint program, GLint location, GLfloat *params) +{ + EVENT("(GLuint program = %u, GLint location = %d, GLfloat *params = 0x%0.8p)", program, + location, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, params); + + if (context->skipValidation() || ValidateGetUniformfv(context, program, location, params)) + { + context->getUniformfv(program, location, params); + } + } +} + +void GL_APIENTRY GetUniformiv(GLuint program, GLint location, GLint *params) +{ + EVENT("(GLuint program = %u, GLint location = %d, GLint *params = 0x%0.8p)", program, location, + params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, params); + + if (context->skipValidation() || ValidateGetUniformiv(context, program, location, params)) + { + context->getUniformiv(program, location, params); + } + } +} + +GLint GL_APIENTRY GetUniformLocation(GLuint program, const GLchar *name) +{ + EVENT("(GLuint program = %u, const GLchar *name = 0x%0.8p)", program, name); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, name); + + if (context->skipValidation() || ValidateGetUniformLocation(context, program, name)) + { + return context->getUniformLocation(program, name); + } + } + + return GetDefaultReturnValue(); +} + +void GL_APIENTRY GetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params) +{ + EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLfloat *params = 0x%0.8p)", index, pname, + params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(index, pname, params); + + if (context->skipValidation() || ValidateGetVertexAttribfv(context, index, pname, params)) + { + context->getVertexAttribfv(index, pname, params); + } + } +} + +void GL_APIENTRY GetVertexAttribiv(GLuint index, GLenum pname, GLint *params) +{ + EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", index, pname, + params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(index, pname, params); + + if (context->skipValidation() || ValidateGetVertexAttribiv(context, index, pname, params)) + { + context->getVertexAttribiv(index, pname, params); + } + } +} + +void GL_APIENTRY GetVertexAttribPointerv(GLuint index, GLenum pname, void **pointer) +{ + EVENT("(GLuint index = %u, GLenum pname = 0x%X, void **pointer = 0x%0.8p)", index, pname, + pointer); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(index, pname, pointer); + + if (context->skipValidation() || + ValidateGetVertexAttribPointerv(context, index, pname, pointer)) + { + context->getVertexAttribPointerv(index, pname, pointer); + } + } +} + +void GL_APIENTRY Hint(GLenum target, GLenum mode) +{ + EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, mode); + + if (context->skipValidation() || ValidateHint(context, target, mode)) + { + context->hint(target, mode); + } + } +} + +GLboolean GL_APIENTRY IsBuffer(GLuint buffer) +{ + EVENT("(GLuint buffer = %u)", buffer); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(buffer); + + if (context->skipValidation() || ValidateIsBuffer(context, buffer)) + { + return context->isBuffer(buffer); + } + } + + return GetDefaultReturnValue(); +} + +GLboolean GL_APIENTRY IsEnabled(GLenum cap) +{ + EVENT("(GLenum cap = 0x%X)", cap); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(cap); + + if (context->skipValidation() || ValidateIsEnabled(context, cap)) + { + return context->isEnabled(cap); + } + } + + return GetDefaultReturnValue(); +} + +GLboolean GL_APIENTRY IsFramebuffer(GLuint framebuffer) +{ + EVENT("(GLuint framebuffer = %u)", framebuffer); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(framebuffer); + + if (context->skipValidation() || ValidateIsFramebuffer(context, framebuffer)) + { + return context->isFramebuffer(framebuffer); + } + } + + return GetDefaultReturnValue(); +} + +GLboolean GL_APIENTRY IsProgram(GLuint program) +{ + EVENT("(GLuint program = %u)", program); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program); + + if (context->skipValidation() || ValidateIsProgram(context, program)) + { + return context->isProgram(program); + } + } + + return GetDefaultReturnValue(); +} + +GLboolean GL_APIENTRY IsRenderbuffer(GLuint renderbuffer) +{ + EVENT("(GLuint renderbuffer = %u)", renderbuffer); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(renderbuffer); + + if (context->skipValidation() || ValidateIsRenderbuffer(context, renderbuffer)) + { + return context->isRenderbuffer(renderbuffer); + } + } + + return GetDefaultReturnValue(); +} + +GLboolean GL_APIENTRY IsShader(GLuint shader) +{ + EVENT("(GLuint shader = %u)", shader); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(shader); + + if (context->skipValidation() || ValidateIsShader(context, shader)) + { + return context->isShader(shader); + } + } + + return GetDefaultReturnValue(); +} + +GLboolean GL_APIENTRY IsTexture(GLuint texture) +{ + EVENT("(GLuint texture = %u)", texture); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(texture); + + if (context->skipValidation() || ValidateIsTexture(context, texture)) + { + return context->isTexture(texture); + } + } + + return GetDefaultReturnValue(); +} + +void GL_APIENTRY LineWidth(GLfloat width) +{ + EVENT("(GLfloat width = %f)", width); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(width); + + if (context->skipValidation() || ValidateLineWidth(context, width)) + { + context->lineWidth(width); + } + } +} + +void GL_APIENTRY LinkProgram(GLuint program) +{ + EVENT("(GLuint program = %u)", program); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program); + + if (context->skipValidation() || ValidateLinkProgram(context, program)) + { + context->linkProgram(program); + } + } +} + +void GL_APIENTRY PixelStorei(GLenum pname, GLint param) +{ + EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(pname, param); + + if (context->skipValidation() || ValidatePixelStorei(context, pname, param)) + { + context->pixelStorei(pname, param); + } + } +} + +void GL_APIENTRY PolygonOffset(GLfloat factor, GLfloat units) +{ + EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(factor, units); + + if (context->skipValidation() || ValidatePolygonOffset(context, factor, units)) + { + context->polygonOffset(factor, units); + } + } +} + +void GL_APIENTRY ReadPixels(GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + void *pixels) +{ + EVENT( + "(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLenum format = " + "0x%X, GLenum type = 0x%X, void *pixels = 0x%0.8p)", + x, y, width, height, format, type, pixels); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(x, y, width, height, format, type, pixels); + + if (context->skipValidation() || + ValidateReadPixels(context, x, y, width, height, format, type, pixels)) + { + context->readPixels(x, y, width, height, format, type, pixels); + } + } +} + +void GL_APIENTRY ReleaseShaderCompiler() +{ + EVENT("()"); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(); + + if (context->skipValidation() || ValidateReleaseShaderCompiler(context)) + { + context->releaseShaderCompiler(); + } + } +} + +void GL_APIENTRY RenderbufferStorage(GLenum target, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + EVENT( + "(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = " + "%d)", + target, internalformat, width, height); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, internalformat, width, + height); + + if (context->skipValidation() || + ValidateRenderbufferStorage(context, target, internalformat, width, height)) + { + context->renderbufferStorage(target, internalformat, width, height); + } + } +} + +void GL_APIENTRY SampleCoverage(GLfloat value, GLboolean invert) +{ + EVENT("(GLfloat value = %f, GLboolean invert = %u)", value, invert); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(value, invert); + + if (context->skipValidation() || ValidateSampleCoverage(context, value, invert)) + { + context->sampleCoverage(value, invert); + } + } +} + +void GL_APIENTRY Scissor(GLint x, GLint y, GLsizei width, GLsizei height) +{ + EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, + height); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(x, y, width, height); + + if (context->skipValidation() || ValidateScissor(context, x, y, width, height)) + { + context->scissor(x, y, width, height); + } + } +} + +void GL_APIENTRY ShaderBinary(GLsizei count, + const GLuint *shaders, + GLenum binaryformat, + const void *binary, + GLsizei length) +{ + EVENT( + "(GLsizei count = %d, const GLuint *shaders = 0x%0.8p, GLenum binaryformat = 0x%X, const " + "void *binary = 0x%0.8p, GLsizei length = %d)", + count, shaders, binaryformat, binary, length); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(count, shaders, binaryformat, binary, + length); + + if (context->skipValidation() || + ValidateShaderBinary(context, count, shaders, binaryformat, binary, length)) + { + context->shaderBinary(count, shaders, binaryformat, binary, length); + } + } +} + +void GL_APIENTRY ShaderSource(GLuint shader, + GLsizei count, + const GLchar *const *string, + const GLint *length) +{ + EVENT( + "(GLuint shader = %u, GLsizei count = %d, const GLchar *const*string = 0x%0.8p, const " + "GLint *length = 0x%0.8p)", + shader, count, string, length); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(shader, count, string, length); + + if (context->skipValidation() || + ValidateShaderSource(context, shader, count, string, length)) + { + context->shaderSource(shader, count, string, length); + } + } +} + +void GL_APIENTRY StencilFunc(GLenum func, GLint ref, GLuint mask) +{ + EVENT("(GLenum func = 0x%X, GLint ref = %d, GLuint mask = %u)", func, ref, mask); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(func, ref, mask); + + if (context->skipValidation() || ValidateStencilFunc(context, func, ref, mask)) + { + context->stencilFunc(func, ref, mask); + } + } +} + +void GL_APIENTRY StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) +{ + EVENT("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %u)", face, func, + ref, mask); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(face, func, ref, mask); + + if (context->skipValidation() || + ValidateStencilFuncSeparate(context, face, func, ref, mask)) + { + context->stencilFuncSeparate(face, func, ref, mask); + } + } +} + +void GL_APIENTRY StencilMask(GLuint mask) +{ + EVENT("(GLuint mask = %u)", mask); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(mask); + + if (context->skipValidation() || ValidateStencilMask(context, mask)) + { + context->stencilMask(mask); + } + } +} + +void GL_APIENTRY StencilMaskSeparate(GLenum face, GLuint mask) +{ + EVENT("(GLenum face = 0x%X, GLuint mask = %u)", face, mask); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(face, mask); + + if (context->skipValidation() || ValidateStencilMaskSeparate(context, face, mask)) + { + context->stencilMaskSeparate(face, mask); + } + } +} + +void GL_APIENTRY StencilOp(GLenum fail, GLenum zfail, GLenum zpass) +{ + EVENT("(GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpass = 0x%X)", fail, zfail, zpass); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(fail, zfail, zpass); + + if (context->skipValidation() || ValidateStencilOp(context, fail, zfail, zpass)) + { + context->stencilOp(fail, zfail, zpass); + } + } +} + +void GL_APIENTRY StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) +{ + EVENT("(GLenum face = 0x%X, GLenum sfail = 0x%X, GLenum dpfail = 0x%X, GLenum dppass = 0x%X)", + face, sfail, dpfail, dppass); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(face, sfail, dpfail, dppass); + + if (context->skipValidation() || + ValidateStencilOpSeparate(context, face, sfail, dpfail, dppass)) + { + context->stencilOpSeparate(face, sfail, dpfail, dppass); + } + } +} + +void GL_APIENTRY TexImage2D(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + const void *pixels) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, " + "GLsizei height = %d, GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const " + "void *pixels = 0x%0.8p)", + target, level, internalformat, width, height, border, format, type, pixels); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, level, internalformat, width, height, + border, format, type, pixels); + + if (context->skipValidation() || + ValidateTexImage2D(context, target, level, internalformat, width, height, border, + format, type, pixels)) + { + context->texImage2D(target, level, internalformat, width, height, border, format, type, + pixels); + } + } +} + +void GL_APIENTRY TexParameterf(GLenum target, GLenum pname, GLfloat param) +{ + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, pname, param); + + if (context->skipValidation() || ValidateTexParameterf(context, target, pname, param)) + { + context->texParameterf(target, pname, param); + } + } +} + +void GL_APIENTRY TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) +{ + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, const GLfloat *params = 0x%0.8p)", target, + pname, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, pname, params); + + if (context->skipValidation() || ValidateTexParameterfv(context, target, pname, params)) + { + context->texParameterfv(target, pname, params); + } + } +} + +void GL_APIENTRY TexParameteri(GLenum target, GLenum pname, GLint param) +{ + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, pname, param); + + if (context->skipValidation() || ValidateTexParameteri(context, target, pname, param)) + { + context->texParameteri(target, pname, param); + } + } +} + +void GL_APIENTRY TexParameteriv(GLenum target, GLenum pname, const GLint *params) +{ + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, const GLint *params = 0x%0.8p)", target, + pname, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, pname, params); + + if (context->skipValidation() || ValidateTexParameteriv(context, target, pname, params)) + { + context->texParameteriv(target, pname, params); + } + } +} + +void GL_APIENTRY TexSubImage2D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void *pixels) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, GLsizei " + "width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, const void " + "*pixels = 0x%0.8p)", + target, level, xoffset, yoffset, width, height, format, type, pixels); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, level, xoffset, yoffset, width, + height, format, type, pixels); + + if (context->skipValidation() || + ValidateTexSubImage2D(context, target, level, xoffset, yoffset, width, height, format, + type, pixels)) + { + context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, + pixels); + } + } +} + +void GL_APIENTRY Uniform1f(GLint location, GLfloat v0) +{ + EVENT("(GLint location = %d, GLfloat v0 = %f)", location, v0); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, v0); + + if (context->skipValidation() || ValidateUniform1f(context, location, v0)) + { + context->uniform1f(location, v0); + } + } +} + +void GL_APIENTRY Uniform1fv(GLint location, GLsizei count, const GLfloat *value) +{ + EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat *value = 0x%0.8p)", location, + count, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, count, value); + + if (context->skipValidation() || ValidateUniform1fv(context, location, count, value)) + { + context->uniform1fv(location, count, value); + } + } +} + +void GL_APIENTRY Uniform1i(GLint location, GLint v0) +{ + EVENT("(GLint location = %d, GLint v0 = %d)", location, v0); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, v0); + + if (context->skipValidation() || ValidateUniform1i(context, location, v0)) + { + context->uniform1i(location, v0); + } + } +} + +void GL_APIENTRY Uniform1iv(GLint location, GLsizei count, const GLint *value) +{ + EVENT("(GLint location = %d, GLsizei count = %d, const GLint *value = 0x%0.8p)", location, + count, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, count, value); + + if (context->skipValidation() || ValidateUniform1iv(context, location, count, value)) + { + context->uniform1iv(location, count, value); + } + } +} + +void GL_APIENTRY Uniform2f(GLint location, GLfloat v0, GLfloat v1) +{ + EVENT("(GLint location = %d, GLfloat v0 = %f, GLfloat v1 = %f)", location, v0, v1); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, v0, v1); + + if (context->skipValidation() || ValidateUniform2f(context, location, v0, v1)) + { + context->uniform2f(location, v0, v1); + } + } +} + +void GL_APIENTRY Uniform2fv(GLint location, GLsizei count, const GLfloat *value) +{ + EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat *value = 0x%0.8p)", location, + count, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, count, value); + + if (context->skipValidation() || ValidateUniform2fv(context, location, count, value)) + { + context->uniform2fv(location, count, value); + } + } +} + +void GL_APIENTRY Uniform2i(GLint location, GLint v0, GLint v1) +{ + EVENT("(GLint location = %d, GLint v0 = %d, GLint v1 = %d)", location, v0, v1); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, v0, v1); + + if (context->skipValidation() || ValidateUniform2i(context, location, v0, v1)) + { + context->uniform2i(location, v0, v1); + } + } +} + +void GL_APIENTRY Uniform2iv(GLint location, GLsizei count, const GLint *value) +{ + EVENT("(GLint location = %d, GLsizei count = %d, const GLint *value = 0x%0.8p)", location, + count, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, count, value); + + if (context->skipValidation() || ValidateUniform2iv(context, location, count, value)) + { + context->uniform2iv(location, count, value); + } + } +} + +void GL_APIENTRY Uniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) +{ + EVENT("(GLint location = %d, GLfloat v0 = %f, GLfloat v1 = %f, GLfloat v2 = %f)", location, v0, + v1, v2); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, v0, v1, v2); + + if (context->skipValidation() || ValidateUniform3f(context, location, v0, v1, v2)) + { + context->uniform3f(location, v0, v1, v2); + } + } +} + +void GL_APIENTRY Uniform3fv(GLint location, GLsizei count, const GLfloat *value) +{ + EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat *value = 0x%0.8p)", location, + count, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, count, value); + + if (context->skipValidation() || ValidateUniform3fv(context, location, count, value)) + { + context->uniform3fv(location, count, value); + } + } +} + +void GL_APIENTRY Uniform3i(GLint location, GLint v0, GLint v1, GLint v2) +{ + EVENT("(GLint location = %d, GLint v0 = %d, GLint v1 = %d, GLint v2 = %d)", location, v0, v1, + v2); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, v0, v1, v2); + + if (context->skipValidation() || ValidateUniform3i(context, location, v0, v1, v2)) + { + context->uniform3i(location, v0, v1, v2); + } + } +} + +void GL_APIENTRY Uniform3iv(GLint location, GLsizei count, const GLint *value) +{ + EVENT("(GLint location = %d, GLsizei count = %d, const GLint *value = 0x%0.8p)", location, + count, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, count, value); + + if (context->skipValidation() || ValidateUniform3iv(context, location, count, value)) + { + context->uniform3iv(location, count, value); + } + } +} + +void GL_APIENTRY Uniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) +{ + EVENT( + "(GLint location = %d, GLfloat v0 = %f, GLfloat v1 = %f, GLfloat v2 = %f, GLfloat v3 = %f)", + location, v0, v1, v2, v3); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, v0, v1, v2, v3); + + if (context->skipValidation() || ValidateUniform4f(context, location, v0, v1, v2, v3)) + { + context->uniform4f(location, v0, v1, v2, v3); + } + } +} + +void GL_APIENTRY Uniform4fv(GLint location, GLsizei count, const GLfloat *value) +{ + EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat *value = 0x%0.8p)", location, + count, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, count, value); + + if (context->skipValidation() || ValidateUniform4fv(context, location, count, value)) + { + context->uniform4fv(location, count, value); + } + } +} + +void GL_APIENTRY Uniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) +{ + EVENT("(GLint location = %d, GLint v0 = %d, GLint v1 = %d, GLint v2 = %d, GLint v3 = %d)", + location, v0, v1, v2, v3); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, v0, v1, v2, v3); + + if (context->skipValidation() || ValidateUniform4i(context, location, v0, v1, v2, v3)) + { + context->uniform4i(location, v0, v1, v2, v3); + } + } +} + +void GL_APIENTRY Uniform4iv(GLint location, GLsizei count, const GLint *value) +{ + EVENT("(GLint location = %d, GLsizei count = %d, const GLint *value = 0x%0.8p)", location, + count, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, count, value); + + if (context->skipValidation() || ValidateUniform4iv(context, location, count, value)) + { + context->uniform4iv(location, count, value); + } + } +} + +void GL_APIENTRY UniformMatrix2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + EVENT( + "(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat *value " + "= 0x%0.8p)", + location, count, transpose, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, count, transpose, value); + + if (context->skipValidation() || + ValidateUniformMatrix2fv(context, location, count, transpose, value)) + { + context->uniformMatrix2fv(location, count, transpose, value); + } + } +} + +void GL_APIENTRY UniformMatrix3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + EVENT( + "(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat *value " + "= 0x%0.8p)", + location, count, transpose, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, count, transpose, value); + + if (context->skipValidation() || + ValidateUniformMatrix3fv(context, location, count, transpose, value)) + { + context->uniformMatrix3fv(location, count, transpose, value); + } + } +} + +void GL_APIENTRY UniformMatrix4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + EVENT( + "(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat *value " + "= 0x%0.8p)", + location, count, transpose, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, count, transpose, value); + + if (context->skipValidation() || + ValidateUniformMatrix4fv(context, location, count, transpose, value)) + { + context->uniformMatrix4fv(location, count, transpose, value); + } + } +} + +void GL_APIENTRY UseProgram(GLuint program) +{ + EVENT("(GLuint program = %u)", program); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program); + + if (context->skipValidation() || ValidateUseProgram(context, program)) + { + context->useProgram(program); + } + } +} + +void GL_APIENTRY ValidateProgram(GLuint program) +{ + EVENT("(GLuint program = %u)", program); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program); + + if (context->skipValidation() || ValidateValidateProgram(context, program)) + { + context->validateProgram(program); + } + } +} + +void GL_APIENTRY VertexAttrib1f(GLuint index, GLfloat x) +{ + EVENT("(GLuint index = %u, GLfloat x = %f)", index, x); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(index, x); + + if (context->skipValidation() || ValidateVertexAttrib1f(context, index, x)) + { + context->vertexAttrib1f(index, x); + } + } +} + +void GL_APIENTRY VertexAttrib1fv(GLuint index, const GLfloat *v) +{ + EVENT("(GLuint index = %u, const GLfloat *v = 0x%0.8p)", index, v); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(index, v); + + if (context->skipValidation() || ValidateVertexAttrib1fv(context, index, v)) + { + context->vertexAttrib1fv(index, v); + } + } +} + +void GL_APIENTRY VertexAttrib2f(GLuint index, GLfloat x, GLfloat y) +{ + EVENT("(GLuint index = %u, GLfloat x = %f, GLfloat y = %f)", index, x, y); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(index, x, y); + + if (context->skipValidation() || ValidateVertexAttrib2f(context, index, x, y)) + { + context->vertexAttrib2f(index, x, y); + } + } +} + +void GL_APIENTRY VertexAttrib2fv(GLuint index, const GLfloat *v) +{ + EVENT("(GLuint index = %u, const GLfloat *v = 0x%0.8p)", index, v); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(index, v); + + if (context->skipValidation() || ValidateVertexAttrib2fv(context, index, v)) + { + context->vertexAttrib2fv(index, v); + } + } +} + +void GL_APIENTRY VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) +{ + EVENT("(GLuint index = %u, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(index, x, y, z); + + if (context->skipValidation() || ValidateVertexAttrib3f(context, index, x, y, z)) + { + context->vertexAttrib3f(index, x, y, z); + } + } +} + +void GL_APIENTRY VertexAttrib3fv(GLuint index, const GLfloat *v) +{ + EVENT("(GLuint index = %u, const GLfloat *v = 0x%0.8p)", index, v); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(index, v); + + if (context->skipValidation() || ValidateVertexAttrib3fv(context, index, v)) + { + context->vertexAttrib3fv(index, v); + } + } +} + +void GL_APIENTRY VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + EVENT("(GLuint index = %u, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", + index, x, y, z, w); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(index, x, y, z, w); + + if (context->skipValidation() || ValidateVertexAttrib4f(context, index, x, y, z, w)) + { + context->vertexAttrib4f(index, x, y, z, w); + } + } +} + +void GL_APIENTRY VertexAttrib4fv(GLuint index, const GLfloat *v) +{ + EVENT("(GLuint index = %u, const GLfloat *v = 0x%0.8p)", index, v); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(index, v); + + if (context->skipValidation() || ValidateVertexAttrib4fv(context, index, v)) + { + context->vertexAttrib4fv(index, v); + } + } +} + +void GL_APIENTRY VertexAttribPointer(GLuint index, + GLint size, + GLenum type, + GLboolean normalized, + GLsizei stride, + const void *pointer) +{ + EVENT( + "(GLuint index = %u, GLint size = %d, GLenum type = 0x%X, GLboolean normalized = %u, " + "GLsizei stride = %d, const void *pointer = 0x%0.8p)", + index, size, type, normalized, stride, pointer); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(index, size, type, normalized, + stride, pointer); + + if (context->skipValidation() || + ValidateVertexAttribPointer(context, index, size, type, normalized, stride, pointer)) + { + context->vertexAttribPointer(index, size, type, normalized, stride, pointer); + } + } +} + +void GL_APIENTRY Viewport(GLint x, GLint y, GLsizei width, GLsizei height) +{ + EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, + height); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(x, y, width, height); + + if (context->skipValidation() || ValidateViewport(context, x, y, width, height)) + { + context->viewport(x, y, width, height); + } + } +} +} // namespace gl diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_autogen.h b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_autogen.h new file mode 100644 index 0000000000..7735b46fa4 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_autogen.h @@ -0,0 +1,297 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml. +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// entry_points_gles_2_0_autogen.h: +// Defines the GLES 2.0 entry points. + +#ifndef LIBGLESV2_ENTRYPOINTSGLES20_AUTOGEN_H_ +#define LIBGLESV2_ENTRYPOINTSGLES20_AUTOGEN_H_ + +#include +#include + +namespace gl +{ +ANGLE_EXPORT void GL_APIENTRY ActiveTexture(GLenum texture); +ANGLE_EXPORT void GL_APIENTRY AttachShader(GLuint program, GLuint shader); +ANGLE_EXPORT void GL_APIENTRY BindAttribLocation(GLuint program, GLuint index, const GLchar *name); +ANGLE_EXPORT void GL_APIENTRY BindBuffer(GLenum target, GLuint buffer); +ANGLE_EXPORT void GL_APIENTRY BindFramebuffer(GLenum target, GLuint framebuffer); +ANGLE_EXPORT void GL_APIENTRY BindRenderbuffer(GLenum target, GLuint renderbuffer); +ANGLE_EXPORT void GL_APIENTRY BindTexture(GLenum target, GLuint texture); +ANGLE_EXPORT void GL_APIENTRY BlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +ANGLE_EXPORT void GL_APIENTRY BlendEquation(GLenum mode); +ANGLE_EXPORT void GL_APIENTRY BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha); +ANGLE_EXPORT void GL_APIENTRY BlendFunc(GLenum sfactor, GLenum dfactor); +ANGLE_EXPORT void GL_APIENTRY BlendFuncSeparate(GLenum sfactorRGB, + GLenum dfactorRGB, + GLenum sfactorAlpha, + GLenum dfactorAlpha); +ANGLE_EXPORT void GL_APIENTRY BufferData(GLenum target, + GLsizeiptr size, + const void *data, + GLenum usage); +ANGLE_EXPORT void GL_APIENTRY BufferSubData(GLenum target, + GLintptr offset, + GLsizeiptr size, + const void *data); +ANGLE_EXPORT GLenum GL_APIENTRY CheckFramebufferStatus(GLenum target); +ANGLE_EXPORT void GL_APIENTRY Clear(GLbitfield mask); +ANGLE_EXPORT void GL_APIENTRY ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +ANGLE_EXPORT void GL_APIENTRY ClearDepthf(GLfloat d); +ANGLE_EXPORT void GL_APIENTRY ClearStencil(GLint s); +ANGLE_EXPORT void GL_APIENTRY ColorMask(GLboolean red, + GLboolean green, + GLboolean blue, + GLboolean alpha); +ANGLE_EXPORT void GL_APIENTRY CompileShader(GLuint shader); +ANGLE_EXPORT void GL_APIENTRY CompressedTexImage2D(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + const void *data); +ANGLE_EXPORT void GL_APIENTRY CompressedTexSubImage2D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const void *data); +ANGLE_EXPORT void GL_APIENTRY CopyTexImage2D(GLenum target, + GLint level, + GLenum internalformat, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border); +ANGLE_EXPORT void GL_APIENTRY CopyTexSubImage2D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +ANGLE_EXPORT GLuint GL_APIENTRY CreateProgram(); +ANGLE_EXPORT GLuint GL_APIENTRY CreateShader(GLenum type); +ANGLE_EXPORT void GL_APIENTRY CullFace(GLenum mode); +ANGLE_EXPORT void GL_APIENTRY DeleteBuffers(GLsizei n, const GLuint *buffers); +ANGLE_EXPORT void GL_APIENTRY DeleteFramebuffers(GLsizei n, const GLuint *framebuffers); +ANGLE_EXPORT void GL_APIENTRY DeleteProgram(GLuint program); +ANGLE_EXPORT void GL_APIENTRY DeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers); +ANGLE_EXPORT void GL_APIENTRY DeleteShader(GLuint shader); +ANGLE_EXPORT void GL_APIENTRY DeleteTextures(GLsizei n, const GLuint *textures); +ANGLE_EXPORT void GL_APIENTRY DepthFunc(GLenum func); +ANGLE_EXPORT void GL_APIENTRY DepthMask(GLboolean flag); +ANGLE_EXPORT void GL_APIENTRY DepthRangef(GLfloat n, GLfloat f); +ANGLE_EXPORT void GL_APIENTRY DetachShader(GLuint program, GLuint shader); +ANGLE_EXPORT void GL_APIENTRY Disable(GLenum cap); +ANGLE_EXPORT void GL_APIENTRY DisableVertexAttribArray(GLuint index); +ANGLE_EXPORT void GL_APIENTRY DrawArrays(GLenum mode, GLint first, GLsizei count); +ANGLE_EXPORT void GL_APIENTRY DrawElements(GLenum mode, + GLsizei count, + GLenum type, + const void *indices); +ANGLE_EXPORT void GL_APIENTRY Enable(GLenum cap); +ANGLE_EXPORT void GL_APIENTRY EnableVertexAttribArray(GLuint index); +ANGLE_EXPORT void GL_APIENTRY Finish(); +ANGLE_EXPORT void GL_APIENTRY Flush(); +ANGLE_EXPORT void GL_APIENTRY FramebufferRenderbuffer(GLenum target, + GLenum attachment, + GLenum renderbuffertarget, + GLuint renderbuffer); +ANGLE_EXPORT void GL_APIENTRY FramebufferTexture2D(GLenum target, + GLenum attachment, + GLenum textarget, + GLuint texture, + GLint level); +ANGLE_EXPORT void GL_APIENTRY FrontFace(GLenum mode); +ANGLE_EXPORT void GL_APIENTRY GenBuffers(GLsizei n, GLuint *buffers); +ANGLE_EXPORT void GL_APIENTRY GenerateMipmap(GLenum target); +ANGLE_EXPORT void GL_APIENTRY GenFramebuffers(GLsizei n, GLuint *framebuffers); +ANGLE_EXPORT void GL_APIENTRY GenRenderbuffers(GLsizei n, GLuint *renderbuffers); +ANGLE_EXPORT void GL_APIENTRY GenTextures(GLsizei n, GLuint *textures); +ANGLE_EXPORT void GL_APIENTRY GetActiveAttrib(GLuint program, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name); +ANGLE_EXPORT void GL_APIENTRY GetActiveUniform(GLuint program, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name); +ANGLE_EXPORT void GL_APIENTRY GetAttachedShaders(GLuint program, + GLsizei maxCount, + GLsizei *count, + GLuint *shaders); +ANGLE_EXPORT GLint GL_APIENTRY GetAttribLocation(GLuint program, const GLchar *name); +ANGLE_EXPORT void GL_APIENTRY GetBooleanv(GLenum pname, GLboolean *data); +ANGLE_EXPORT void GL_APIENTRY GetBufferParameteriv(GLenum target, GLenum pname, GLint *params); +ANGLE_EXPORT GLenum GL_APIENTRY GetError(); +ANGLE_EXPORT void GL_APIENTRY GetFloatv(GLenum pname, GLfloat *data); +ANGLE_EXPORT void GL_APIENTRY GetFramebufferAttachmentParameteriv(GLenum target, + GLenum attachment, + GLenum pname, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetIntegerv(GLenum pname, GLint *data); +ANGLE_EXPORT void GL_APIENTRY GetProgramiv(GLuint program, GLenum pname, GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetProgramInfoLog(GLuint program, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog); +ANGLE_EXPORT void GL_APIENTRY GetRenderbufferParameteriv(GLenum target, + GLenum pname, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetShaderiv(GLuint shader, GLenum pname, GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetShaderInfoLog(GLuint shader, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog); +ANGLE_EXPORT void GL_APIENTRY GetShaderPrecisionFormat(GLenum shadertype, + GLenum precisiontype, + GLint *range, + GLint *precision); +ANGLE_EXPORT void GL_APIENTRY GetShaderSource(GLuint shader, + GLsizei bufSize, + GLsizei *length, + GLchar *source); +ANGLE_EXPORT const GLubyte *GL_APIENTRY GetString(GLenum name); +ANGLE_EXPORT void GL_APIENTRY GetTexParameterfv(GLenum target, GLenum pname, GLfloat *params); +ANGLE_EXPORT void GL_APIENTRY GetTexParameteriv(GLenum target, GLenum pname, GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetUniformfv(GLuint program, GLint location, GLfloat *params); +ANGLE_EXPORT void GL_APIENTRY GetUniformiv(GLuint program, GLint location, GLint *params); +ANGLE_EXPORT GLint GL_APIENTRY GetUniformLocation(GLuint program, const GLchar *name); +ANGLE_EXPORT void GL_APIENTRY GetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params); +ANGLE_EXPORT void GL_APIENTRY GetVertexAttribiv(GLuint index, GLenum pname, GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetVertexAttribPointerv(GLuint index, GLenum pname, void **pointer); +ANGLE_EXPORT void GL_APIENTRY Hint(GLenum target, GLenum mode); +ANGLE_EXPORT GLboolean GL_APIENTRY IsBuffer(GLuint buffer); +ANGLE_EXPORT GLboolean GL_APIENTRY IsEnabled(GLenum cap); +ANGLE_EXPORT GLboolean GL_APIENTRY IsFramebuffer(GLuint framebuffer); +ANGLE_EXPORT GLboolean GL_APIENTRY IsProgram(GLuint program); +ANGLE_EXPORT GLboolean GL_APIENTRY IsRenderbuffer(GLuint renderbuffer); +ANGLE_EXPORT GLboolean GL_APIENTRY IsShader(GLuint shader); +ANGLE_EXPORT GLboolean GL_APIENTRY IsTexture(GLuint texture); +ANGLE_EXPORT void GL_APIENTRY LineWidth(GLfloat width); +ANGLE_EXPORT void GL_APIENTRY LinkProgram(GLuint program); +ANGLE_EXPORT void GL_APIENTRY PixelStorei(GLenum pname, GLint param); +ANGLE_EXPORT void GL_APIENTRY PolygonOffset(GLfloat factor, GLfloat units); +ANGLE_EXPORT void GL_APIENTRY ReadPixels(GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + void *pixels); +ANGLE_EXPORT void GL_APIENTRY ReleaseShaderCompiler(); +ANGLE_EXPORT void GL_APIENTRY RenderbufferStorage(GLenum target, + GLenum internalformat, + GLsizei width, + GLsizei height); +ANGLE_EXPORT void GL_APIENTRY SampleCoverage(GLfloat value, GLboolean invert); +ANGLE_EXPORT void GL_APIENTRY Scissor(GLint x, GLint y, GLsizei width, GLsizei height); +ANGLE_EXPORT void GL_APIENTRY ShaderBinary(GLsizei count, + const GLuint *shaders, + GLenum binaryformat, + const void *binary, + GLsizei length); +ANGLE_EXPORT void GL_APIENTRY ShaderSource(GLuint shader, + GLsizei count, + const GLchar *const *string, + const GLint *length); +ANGLE_EXPORT void GL_APIENTRY StencilFunc(GLenum func, GLint ref, GLuint mask); +ANGLE_EXPORT void GL_APIENTRY StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask); +ANGLE_EXPORT void GL_APIENTRY StencilMask(GLuint mask); +ANGLE_EXPORT void GL_APIENTRY StencilMaskSeparate(GLenum face, GLuint mask); +ANGLE_EXPORT void GL_APIENTRY StencilOp(GLenum fail, GLenum zfail, GLenum zpass); +ANGLE_EXPORT void GL_APIENTRY StencilOpSeparate(GLenum face, + GLenum sfail, + GLenum dpfail, + GLenum dppass); +ANGLE_EXPORT void GL_APIENTRY TexImage2D(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + const void *pixels); +ANGLE_EXPORT void GL_APIENTRY TexParameterf(GLenum target, GLenum pname, GLfloat param); +ANGLE_EXPORT void GL_APIENTRY TexParameterfv(GLenum target, GLenum pname, const GLfloat *params); +ANGLE_EXPORT void GL_APIENTRY TexParameteri(GLenum target, GLenum pname, GLint param); +ANGLE_EXPORT void GL_APIENTRY TexParameteriv(GLenum target, GLenum pname, const GLint *params); +ANGLE_EXPORT void GL_APIENTRY TexSubImage2D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void *pixels); +ANGLE_EXPORT void GL_APIENTRY Uniform1f(GLint location, GLfloat v0); +ANGLE_EXPORT void GL_APIENTRY Uniform1fv(GLint location, GLsizei count, const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY Uniform1i(GLint location, GLint v0); +ANGLE_EXPORT void GL_APIENTRY Uniform1iv(GLint location, GLsizei count, const GLint *value); +ANGLE_EXPORT void GL_APIENTRY Uniform2f(GLint location, GLfloat v0, GLfloat v1); +ANGLE_EXPORT void GL_APIENTRY Uniform2fv(GLint location, GLsizei count, const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY Uniform2i(GLint location, GLint v0, GLint v1); +ANGLE_EXPORT void GL_APIENTRY Uniform2iv(GLint location, GLsizei count, const GLint *value); +ANGLE_EXPORT void GL_APIENTRY Uniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +ANGLE_EXPORT void GL_APIENTRY Uniform3fv(GLint location, GLsizei count, const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY Uniform3i(GLint location, GLint v0, GLint v1, GLint v2); +ANGLE_EXPORT void GL_APIENTRY Uniform3iv(GLint location, GLsizei count, const GLint *value); +ANGLE_EXPORT void GL_APIENTRY +Uniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +ANGLE_EXPORT void GL_APIENTRY Uniform4fv(GLint location, GLsizei count, const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY Uniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +ANGLE_EXPORT void GL_APIENTRY Uniform4iv(GLint location, GLsizei count, const GLint *value); +ANGLE_EXPORT void GL_APIENTRY UniformMatrix2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY UniformMatrix3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY UniformMatrix4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY UseProgram(GLuint program); +ANGLE_EXPORT void GL_APIENTRY ValidateProgram(GLuint program); +ANGLE_EXPORT void GL_APIENTRY VertexAttrib1f(GLuint index, GLfloat x); +ANGLE_EXPORT void GL_APIENTRY VertexAttrib1fv(GLuint index, const GLfloat *v); +ANGLE_EXPORT void GL_APIENTRY VertexAttrib2f(GLuint index, GLfloat x, GLfloat y); +ANGLE_EXPORT void GL_APIENTRY VertexAttrib2fv(GLuint index, const GLfloat *v); +ANGLE_EXPORT void GL_APIENTRY VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z); +ANGLE_EXPORT void GL_APIENTRY VertexAttrib3fv(GLuint index, const GLfloat *v); +ANGLE_EXPORT void GL_APIENTRY +VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +ANGLE_EXPORT void GL_APIENTRY VertexAttrib4fv(GLuint index, const GLfloat *v); +ANGLE_EXPORT void GL_APIENTRY VertexAttribPointer(GLuint index, + GLint size, + GLenum type, + GLboolean normalized, + GLsizei stride, + const void *pointer); +ANGLE_EXPORT void GL_APIENTRY Viewport(GLint x, GLint y, GLsizei width, GLsizei height); +} // namespace gl + +#endif // LIBGLESV2_ENTRYPOINTSGLES20_AUTOGEN_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_ext.cpp b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_ext.cpp index 7df6fcb0cd..d4459ec287 100644 --- a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_ext.cpp +++ b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_ext.cpp @@ -12,14 +12,20 @@ #include "libANGLE/Buffer.h" #include "libANGLE/Context.h" #include "libANGLE/Error.h" +#include "libANGLE/ErrorStrings.h" #include "libANGLE/Fence.h" #include "libANGLE/Framebuffer.h" -#include "libANGLE/Shader.h" #include "libANGLE/Query.h" +#include "libANGLE/Shader.h" +#include "libANGLE/Thread.h" +#include "libANGLE/VertexArray.h" +#include "libANGLE/queryconversions.h" +#include "libANGLE/queryutils.h" #include "libANGLE/validationES.h" #include "libANGLE/validationES2.h" #include "libANGLE/validationES3.h" +#include "libANGLE/validationES31.h" #include "common/debug.h" #include "common/utilities.h" @@ -27,6 +33,19 @@ namespace gl { +namespace +{ + +void SetRobustLengthParam(GLsizei *length, GLsizei value) +{ + if (length) + { + *length = value; + } +} + +} // anonymous namespace + void GL_APIENTRY GenQueriesEXT(GLsizei n, GLuint *ids) { EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids); @@ -34,15 +53,12 @@ void GL_APIENTRY GenQueriesEXT(GLsizei n, GLuint *ids) Context *context = GetValidGlobalContext(); if (context) { - if (!ValidateGenQueriesEXT(context, n, ids)) + if (!context->skipValidation() && !ValidateGenQueriesEXT(context, n, ids)) { return; } - for (GLsizei i = 0; i < n; i++) - { - ids[i] = context->createQuery(); - } + context->genQueries(n, ids); } } @@ -53,15 +69,12 @@ void GL_APIENTRY DeleteQueriesEXT(GLsizei n, const GLuint *ids) Context *context = GetValidGlobalContext(); if (context) { - if (!ValidateDeleteQueriesEXT(context, n, ids)) + if (!context->skipValidation() && !ValidateDeleteQueriesEXT(context, n, ids)) { return; } - for (int i = 0; i < n; i++) - { - context->deleteQuery(ids[i]); - } + context->deleteQueries(n, ids); } } @@ -72,7 +85,12 @@ GLboolean GL_APIENTRY IsQueryEXT(GLuint id) Context *context = GetValidGlobalContext(); if (context) { - return (context->getQuery(id, false, GL_NONE) != NULL) ? GL_TRUE : GL_FALSE; + if (!context->skipValidation() && !ValidateIsQueryEXT(context, id)) + { + return GL_FALSE; + } + + return context->isQuery(id); } return GL_FALSE; @@ -85,17 +103,12 @@ void GL_APIENTRY BeginQueryEXT(GLenum target, GLuint id) Context *context = GetValidGlobalContext(); if (context) { - if (!ValidateBeginQueryEXT(context, target, id)) + if (!context->skipValidation() && !ValidateBeginQueryEXT(context, target, id)) { return; } - Error error = context->beginQuery(target, id); - if (error.isError()) - { - context->recordError(error); - return; - } + context->beginQuery(target, id); } } @@ -106,17 +119,12 @@ void GL_APIENTRY EndQueryEXT(GLenum target) Context *context = GetValidGlobalContext(); if (context) { - if (!ValidateEndQueryEXT(context, target)) + if (!context->skipValidation() && !ValidateEndQueryEXT(context, target)) { return; } - Error error = context->endQuery(target); - if (error.isError()) - { - context->recordError(error); - return; - } + context->endQuery(target); } } @@ -127,17 +135,12 @@ void GL_APIENTRY QueryCounterEXT(GLuint id, GLenum target) Context *context = GetValidGlobalContext(); if (context) { - if (!ValidateQueryCounterEXT(context, id, target)) + if (!context->skipValidation() && !ValidateQueryCounterEXT(context, id, target)) { return; } - Error error = context->queryCounter(id, target); - if (error.isError()) - { - context->recordError(error); - return; - } + context->queryCounter(id, target); } } @@ -170,12 +173,7 @@ void GL_APIENTRY GetQueryObjectivEXT(GLuint id, GLenum pname, GLint *params) return; } - Error error = context->getQueryObjectiv(id, pname, params); - if (error.isError()) - { - context->recordError(error); - return; - } + context->getQueryObjectiv(id, pname, params); } } @@ -191,12 +189,7 @@ void GL_APIENTRY GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params) return; } - Error error = context->getQueryObjectuiv(id, pname, params); - if (error.isError()) - { - context->recordError(error); - return; - } + context->getQueryObjectuiv(id, pname, params); } } @@ -212,12 +205,7 @@ void GL_APIENTRY GetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64 *params) return; } - Error error = context->getQueryObjecti64v(id, pname, params); - if (error.isError()) - { - context->recordError(error); - return; - } + context->getQueryObjecti64v(id, pname, params); } } @@ -233,12 +221,7 @@ void GL_APIENTRY GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64 *param return; } - Error error = context->getQueryObjectui64v(id, pname, params); - if (error.isError()) - { - context->recordError(error); - return; - } + context->getQueryObjectui64v(id, pname, params); } } @@ -251,7 +234,7 @@ void GL_APIENTRY DeleteFencesNV(GLsizei n, const GLuint *fences) { if (n < 0) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return; } @@ -278,43 +261,34 @@ void GL_APIENTRY DrawArraysInstancedANGLE(GLenum mode, return; } - Error error = context->drawArraysInstanced(mode, first, count, primcount); - if (error.isError()) - { - context->recordError(error); - return; - } + context->drawArraysInstanced(mode, first, count, primcount); } } void GL_APIENTRY DrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, + const void *indices, GLsizei primcount) { EVENT( - "(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = " + "(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void* indices = " "0x%0.8p, GLsizei primcount = %d)", mode, count, type, indices, primcount); Context *context = GetValidGlobalContext(); if (context) { - IndexRange indexRange; - if (!ValidateDrawElementsInstancedANGLE(context, mode, count, type, indices, primcount, - &indexRange)) + context->gatherParams(mode, count, type, indices, + primcount); + + if (!context->skipValidation() && + !ValidateDrawElementsInstancedANGLE(context, mode, count, type, indices, primcount)) { return; } - Error error = - context->drawElementsInstanced(mode, count, type, indices, primcount, indexRange); - if (error.isError()) - { - context->recordError(error); - return; - } + context->drawElementsInstanced(mode, count, type, indices, primcount); } } @@ -327,19 +301,19 @@ void GL_APIENTRY FinishFenceNV(GLuint fence) { FenceNV *fenceObject = context->getFenceNV(fence); - if (fenceObject == NULL) + if (fenceObject == nullptr) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return; } if (fenceObject->isSet() != GL_TRUE) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return; } - fenceObject->finish(); + context->handleError(fenceObject->finish()); } } @@ -352,7 +326,7 @@ void GL_APIENTRY GenFencesNV(GLsizei n, GLuint *fences) { if (n < 0) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return; } @@ -365,39 +339,41 @@ void GL_APIENTRY GenFencesNV(GLsizei n, GLuint *fences) void GL_APIENTRY GetFenceivNV(GLuint fence, GLenum pname, GLint *params) { - EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params); + EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, + params); Context *context = GetValidGlobalContext(); if (context) { FenceNV *fenceObject = context->getFenceNV(fence); - if (fenceObject == NULL) + if (fenceObject == nullptr) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return; } if (fenceObject->isSet() != GL_TRUE) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return; } switch (pname) { - case GL_FENCE_STATUS_NV: + case GL_FENCE_STATUS_NV: { // GL_NV_fence spec: - // Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV - // or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence. + // Once the status of a fence has been finished (via FinishFenceNV) or tested and + // the returned status is TRUE (via either TestFenceNV or GetFenceivNV querying the + // FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence. GLboolean status = GL_TRUE; if (fenceObject->getStatus() != GL_TRUE) { Error error = fenceObject->test(&status); if (error.isError()) { - context->recordError(error); + context->handleError(error); return; } } @@ -405,15 +381,15 @@ void GL_APIENTRY GetFenceivNV(GLuint fence, GLenum pname, GLint *params) break; } - case GL_FENCE_CONDITION_NV: + case GL_FENCE_CONDITION_NV: { *params = static_cast(fenceObject->getCondition()); break; } - default: + default: { - context->recordError(Error(GL_INVALID_ENUM)); + context->handleError(InvalidEnum()); return; } } @@ -434,17 +410,22 @@ GLenum GL_APIENTRY GetGraphicsResetStatusEXT(void) return GL_NO_ERROR; } -void GL_APIENTRY GetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source) +void GL_APIENTRY GetTranslatedShaderSourceANGLE(GLuint shader, + GLsizei bufsize, + GLsizei *length, + GLchar *source) { - EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)", - shader, bufsize, length, source); + EVENT( + "(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = " + "0x%0.8p)", + shader, bufsize, length, source); Context *context = GetValidGlobalContext(); if (context) { if (bufsize < 0) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return; } @@ -452,18 +433,20 @@ void GL_APIENTRY GetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, if (!shaderObject) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return; } - shaderObject->getTranslatedSourceWithDebugInfo(bufsize, length, source); + shaderObject->getTranslatedSourceWithDebugInfo(context, bufsize, length, source); } } -void GL_APIENTRY GetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params) +void GL_APIENTRY GetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat *params) { - EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)", - program, location, bufSize, params); + EVENT( + "(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = " + "0x%0.8p)", + program, location, bufSize, params); Context *context = GetValidGlobalContext(); if (context) @@ -476,14 +459,15 @@ void GL_APIENTRY GetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSiz Program *programObject = context->getProgram(program); ASSERT(programObject); - programObject->getUniformfv(location, params); + programObject->getUniformfv(context, location, params); } } -void GL_APIENTRY GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params) +void GL_APIENTRY GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint *params) { - EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)", - program, location, bufSize, params); + EVENT( + "(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)", + program, location, bufSize, params); Context *context = GetValidGlobalContext(); if (context) @@ -496,7 +480,7 @@ void GL_APIENTRY GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSiz Program *programObject = context->getProgram(program); ASSERT(programObject); - programObject->getUniformiv(location, params); + programObject->getUniformiv(context, location, params); } } @@ -509,26 +493,33 @@ GLboolean GL_APIENTRY IsFenceNV(GLuint fence) { FenceNV *fenceObject = context->getFenceNV(fence); - if (fenceObject == NULL) + if (fenceObject == nullptr) { return GL_FALSE; } // GL_NV_fence spec: - // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence. + // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an + // existing fence. return fenceObject->isSet(); } return GL_FALSE; } -void GL_APIENTRY ReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, GLsizei bufSize, - GLvoid *data) +void GL_APIENTRY ReadnPixelsEXT(GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + void *data) { - EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, " - "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)", - x, y, width, height, format, type, bufSize, data); + EVENT( + "(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, " + "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, void *data = 0x%0.8p)", + x, y, width, height, format, type, bufSize, data); Context *context = GetValidGlobalContext(); if (context) @@ -543,27 +534,28 @@ void GL_APIENTRY ReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height, } } -void GL_APIENTRY RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) +void GL_APIENTRY RenderbufferStorageMultisampleANGLE(GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height) { - EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", + EVENT( + "(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width " + "= %d, GLsizei height = %d)", target, samples, internalformat, width, height); Context *context = GetValidGlobalContext(); if (context) { - if (!ValidateRenderbufferStorageParametersANGLE(context, target, samples, internalformat, - width, height)) + if (!context->skipValidation() && + !ValidateRenderbufferStorageMultisampleANGLE(context, target, samples, internalformat, + width, height)) { return; } - Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer(); - Error error = renderbuffer->setStorageMultisample(samples, internalformat, width, height); - if (error.isError()) - { - context->recordError(error); - return; - } + context->renderbufferStorageMultisample(target, samples, internalformat, width, height); } } @@ -576,22 +568,22 @@ void GL_APIENTRY SetFenceNV(GLuint fence, GLenum condition) { if (condition != GL_ALL_COMPLETED_NV) { - context->recordError(Error(GL_INVALID_ENUM)); + context->handleError(InvalidEnum()); return; } FenceNV *fenceObject = context->getFenceNV(fence); - if (fenceObject == NULL) + if (fenceObject == nullptr) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return; } Error error = fenceObject->set(condition); if (error.isError()) { - context->recordError(error); + context->handleError(error); return; } } @@ -606,15 +598,15 @@ GLboolean GL_APIENTRY TestFenceNV(GLuint fence) { FenceNV *fenceObject = context->getFenceNV(fence); - if (fenceObject == NULL) + if (fenceObject == nullptr) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return GL_TRUE; } if (fenceObject->isSet() != GL_TRUE) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return GL_TRUE; } @@ -622,7 +614,7 @@ GLboolean GL_APIENTRY TestFenceNV(GLuint fence) Error error = fenceObject->test(&result); if (error.isError()) { - context->recordError(error); + context->handleError(error); return GL_TRUE; } @@ -632,41 +624,38 @@ GLboolean GL_APIENTRY TestFenceNV(GLuint fence) return GL_TRUE; } -void GL_APIENTRY TexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) +void GL_APIENTRY +TexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) { - EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", - target, levels, internalformat, width, height); + EVENT( + "(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = " + "%d, GLsizei height = %d)", + target, levels, internalformat, width, height); Context *context = GetValidGlobalContext(); if (context) { if (!context->getExtensions().textureStorage) { - context->recordError(Error(GL_INVALID_OPERATION)); + context->handleError(InvalidOperation()); return; } - if (context->getClientVersion() < 3 && - !ValidateES2TexStorageParameters(context, target, levels, internalformat, width, height)) + if (context->getClientMajorVersion() < 3 && + !ValidateES2TexStorageParameters(context, target, levels, internalformat, width, + height)) { return; } - if (context->getClientVersion() >= 3 && + if (context->getClientMajorVersion() >= 3 && !ValidateES3TexStorage2DParameters(context, target, levels, internalformat, width, height, 1)) { return; } - Extents size(width, height, 1); - Texture *texture = context->getTargetTexture(target); - Error error = texture->setStorage(target, levels, internalformat, size); - if (error.isError()) - { - context->recordError(error); - return; - } + context->texStorage2D(target, levels, internalformat, width, height); } } @@ -677,9 +666,15 @@ void GL_APIENTRY VertexAttribDivisorANGLE(GLuint index, GLuint divisor) Context *context = GetValidGlobalContext(); if (context) { + if (!context->getExtensions().instancedArrays) + { + ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled); + return; + } + if (index >= MAX_VERTEX_ATTRIBS) { - context->recordError(Error(GL_INVALID_VALUE)); + context->handleError(InvalidValue()); return; } @@ -687,28 +682,41 @@ void GL_APIENTRY VertexAttribDivisorANGLE(GLuint index, GLuint divisor) { if (index == 0 && divisor != 0) { - const char *errorMessage = "The current context doesn't support setting a non-zero divisor on the attribute with index zero. " - "Please reorder the attributes in your vertex shader so that attribute zero can have a zero divisor."; - context->recordError(Error(GL_INVALID_OPERATION, errorMessage)); + const char *errorMessage = + "The current context doesn't support setting a non-zero divisor on the " + "attribute with index zero. " + "Please reorder the attributes in your vertex shader so that attribute zero " + "can have a zero divisor."; + context->handleError(InvalidOperation() << errorMessage); - // We also output an error message to the debugger window if tracing is active, so that developers can see the error message. - ERR("%s", errorMessage); + // We also output an error message to the debugger window if tracing is active, so + // that developers can see the error message. + ERR() << errorMessage; return; } } - context->setVertexAttribDivisor(index, divisor); + context->vertexAttribDivisor(index, divisor); } } -void GL_APIENTRY BlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter) +void GL_APIENTRY BlitFramebufferANGLE(GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter) { - EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, " - "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, " - "GLbitfield mask = 0x%X, GLenum filter = 0x%X)", - srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter); + EVENT( + "(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, " + "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, " + "GLbitfield mask = 0x%X, GLenum filter = 0x%X)", + srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter); Context *context = GetValidGlobalContext(); if (context) @@ -725,9 +733,12 @@ void GL_APIENTRY BlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLi } } -void GL_APIENTRY DiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum *attachments) +void GL_APIENTRY DiscardFramebufferEXT(GLenum target, + GLsizei numAttachments, + const GLenum *attachments) { - EVENT("(GLenum target = 0x%X, GLsizei numAttachments = %d, attachments = 0x%0.8p)", target, numAttachments, attachments); + EVENT("(GLenum target = 0x%X, GLsizei numAttachments = %d, attachments = 0x%0.8p)", target, + numAttachments, attachments); Context *context = GetValidGlobalContext(); if (context) @@ -742,64 +753,68 @@ void GL_APIENTRY DiscardFramebufferEXT(GLenum target, GLsizei numAttachments, co } } -void GL_APIENTRY TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, - GLint border, GLenum format, GLenum type, const GLvoid* pixels) +void GL_APIENTRY TexImage3DOES(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const void *pixels) { - EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, " - "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, " - "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)", - target, level, internalformat, width, height, depth, border, format, type, pixels); + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, " + "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, " + "GLenum format = 0x%X, GLenum type = 0x%x, const void* pixels = 0x%0.8p)", + target, level, internalformat, width, height, depth, border, format, type, pixels); - UNIMPLEMENTED(); // FIXME + UNIMPLEMENTED(); // FIXME } -void GL_APIENTRY GetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary) +void GL_APIENTRY GetProgramBinaryOES(GLuint program, + GLsizei bufSize, + GLsizei *length, + GLenum *binaryFormat, + void *binary) { - EVENT("(GLenum program = 0x%X, bufSize = %d, length = 0x%0.8p, binaryFormat = 0x%0.8p, binary = 0x%0.8p)", - program, bufSize, length, binaryFormat, binary); + EVENT( + "(GLenum program = 0x%X, bufSize = %d, length = 0x%0.8p, binaryFormat = 0x%0.8p, binary = " + "0x%0.8p)", + program, bufSize, length, binaryFormat, binary); Context *context = GetValidGlobalContext(); if (context) { - if (!ValidateGetProgramBinaryOES(context, program, bufSize, length, binaryFormat, binary)) + if (!context->skipValidation() && + !ValidateGetProgramBinaryOES(context, program, bufSize, length, binaryFormat, binary)) { return; } - Program *programObject = context->getProgram(program); - ASSERT(programObject != nullptr); - - Error error = programObject->saveBinary(binaryFormat, binary, bufSize, length); - if (error.isError()) - { - context->recordError(error); - return; - } + context->getProgramBinary(program, bufSize, length, binaryFormat, binary); } } -void GL_APIENTRY ProgramBinaryOES(GLuint program, GLenum binaryFormat, const void *binary, GLint length) +void GL_APIENTRY ProgramBinaryOES(GLuint program, + GLenum binaryFormat, + const void *binary, + GLint length) { - EVENT("(GLenum program = 0x%X, binaryFormat = 0x%x, binary = 0x%0.8p, length = %d)", - program, binaryFormat, binary, length); + EVENT("(GLenum program = 0x%X, binaryFormat = 0x%x, binary = 0x%0.8p, length = %d)", program, + binaryFormat, binary, length); Context *context = GetValidGlobalContext(); if (context) { - if (!ValidateProgramBinaryOES(context, program, binaryFormat, binary, length)) + if (!context->skipValidation() && + !ValidateProgramBinaryOES(context, program, binaryFormat, binary, length)) { return; } - Program *programObject = context->getProgram(program); - ASSERT(programObject != nullptr); - - Error error = programObject->loadBinary(binaryFormat, binary, length); - if (error.isError()) - { - context->recordError(error); - return; - } + context->programBinary(program, binaryFormat, binary, length); } } @@ -819,35 +834,23 @@ void GL_APIENTRY DrawBuffersEXT(GLsizei n, const GLenum *bufs) } } -void GL_APIENTRY GetBufferPointervOES(GLenum target, GLenum pname, void** params) +void GL_APIENTRY GetBufferPointervOES(GLenum target, GLenum pname, void **params) { - EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params); + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, void** params = 0x%0.8p)", target, pname, + params); Context *context = GetValidGlobalContext(); if (context) { - if (!ValidBufferTarget(context, target)) + BufferBinding targetPacked = FromGLenum(target); + + if (!context->skipValidation() && + !ValidateGetBufferPointervOES(context, targetPacked, pname, params)) { - context->recordError(Error(GL_INVALID_ENUM)); return; } - if (pname != GL_BUFFER_MAP_POINTER) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - Buffer *buffer = context->getState().getTargetBuffer(target); - - if (!buffer || !buffer->isMapped()) - { - *params = NULL; - } - else - { - *params = buffer->getMapPointer(); - } + context->getBufferPointerv(targetPacked, pname, params); } } @@ -858,43 +861,17 @@ void *GL_APIENTRY MapBufferOES(GLenum target, GLenum access) Context *context = GetValidGlobalContext(); if (context) { - if (!ValidBufferTarget(context, target)) + BufferBinding targetPacked = FromGLenum(target); + + if (!context->skipValidation() && !ValidateMapBufferOES(context, targetPacked, access)) { - context->recordError(Error(GL_INVALID_ENUM)); - return NULL; + return nullptr; } - Buffer *buffer = context->getState().getTargetBuffer(target); - - if (buffer == NULL) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return NULL; - } - - if (access != GL_WRITE_ONLY_OES) - { - context->recordError(Error(GL_INVALID_ENUM)); - return NULL; - } - - if (buffer->isMapped()) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return NULL; - } - - Error error = buffer->map(access); - if (error.isError()) - { - context->recordError(error); - return NULL; - } - - return buffer->getMapPointer(); + return context->mapBuffer(targetPacked, access); } - return NULL; + return nullptr; } GLboolean GL_APIENTRY UnmapBufferOES(GLenum target) @@ -904,174 +881,63 @@ GLboolean GL_APIENTRY UnmapBufferOES(GLenum target) Context *context = GetValidGlobalContext(); if (context) { - if (!ValidBufferTarget(context, target)) + BufferBinding targetPacked = FromGLenum(target); + + if (!context->skipValidation() && !ValidateUnmapBufferOES(context, targetPacked)) { - context->recordError(Error(GL_INVALID_ENUM)); return GL_FALSE; } - Buffer *buffer = context->getState().getTargetBuffer(target); - - if (buffer == NULL || !buffer->isMapped()) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return GL_FALSE; - } - - GLboolean result; - Error error = buffer->unmap(&result); - if (error.isError()) - { - context->recordError(error); - return GL_FALSE; - } - - return result; + return context->unmapBuffer(targetPacked); } return GL_FALSE; } -void *GL_APIENTRY MapBufferRangeEXT(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) +void *GL_APIENTRY MapBufferRangeEXT(GLenum target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access) { - EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = 0x%X)", - target, offset, length, access); + EVENT( + "(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = " + "0x%X)", + target, offset, length, access); Context *context = GetValidGlobalContext(); if (context) { - if (!ValidBufferTarget(context, target)) + BufferBinding targetPacked = FromGLenum(target); + + if (!context->skipValidation() && + !ValidateMapBufferRangeEXT(context, targetPacked, offset, length, access)) { - context->recordError(Error(GL_INVALID_ENUM)); - return NULL; + return nullptr; } - if (offset < 0 || length < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return NULL; - } - - Buffer *buffer = context->getState().getTargetBuffer(target); - - if (buffer == NULL) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return NULL; - } - - // Check for buffer overflow - size_t offsetSize = static_cast(offset); - size_t lengthSize = static_cast(length); - - if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) || - offsetSize + lengthSize > static_cast(buffer->getSize())) - { - context->recordError(Error(GL_INVALID_VALUE)); - return NULL; - } - - // Check for invalid bits in the mask - GLbitfield allAccessBits = GL_MAP_READ_BIT | - GL_MAP_WRITE_BIT | - GL_MAP_INVALIDATE_RANGE_BIT | - GL_MAP_INVALIDATE_BUFFER_BIT | - GL_MAP_FLUSH_EXPLICIT_BIT | - GL_MAP_UNSYNCHRONIZED_BIT; - - if (access & ~(allAccessBits)) - { - context->recordError(Error(GL_INVALID_VALUE)); - return NULL; - } - - if (length == 0 || buffer->isMapped()) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return NULL; - } - - // Check for invalid bit combinations - if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return NULL; - } - - GLbitfield writeOnlyBits = GL_MAP_INVALIDATE_RANGE_BIT | - GL_MAP_INVALIDATE_BUFFER_BIT | - GL_MAP_UNSYNCHRONIZED_BIT; - - if ((access & GL_MAP_READ_BIT) != 0 && (access & writeOnlyBits) != 0) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return NULL; - } - - if ((access & GL_MAP_WRITE_BIT) == 0 && (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return NULL; - } - - Error error = buffer->mapRange(offset, length, access); - if (error.isError()) - { - context->recordError(error); - return NULL; - } - - return buffer->getMapPointer(); + return context->mapBufferRange(targetPacked, offset, length, access); } - return NULL; + return nullptr; } void GL_APIENTRY FlushMappedBufferRangeEXT(GLenum target, GLintptr offset, GLsizeiptr length) { - EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length); + EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, + length); Context *context = GetValidGlobalContext(); if (context) { - if (offset < 0 || length < 0) + BufferBinding targetPacked = FromGLenum(target); + + if (!context->skipValidation() && + !ValidateFlushMappedBufferRangeEXT(context, targetPacked, offset, length)) { - context->recordError(Error(GL_INVALID_VALUE)); return; } - if (!ValidBufferTarget(context, target)) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - Buffer *buffer = context->getState().getTargetBuffer(target); - - if (buffer == NULL) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (!buffer->isMapped() || (buffer->getAccessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - // Check for buffer overflow - size_t offsetSize = static_cast(offset); - size_t lengthSize = static_cast(length); - - if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) || - offsetSize + lengthSize > static_cast(buffer->getMapLength())) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - // We do not currently support a non-trivial implementation of FlushMappedBufferRange + context->flushMappedBufferRange(targetPacked, offset, length); } } @@ -1087,7 +953,7 @@ void GL_APIENTRY InsertEventMarkerEXT(GLsizei length, const char *marker) { // The debug marker calls should not set error state // However, it seems reasonable to set an error state if the extension is not enabled - context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + context->handleError(InvalidOperation() << "Extension not enabled"); return; } @@ -1112,7 +978,7 @@ void GL_APIENTRY PushGroupMarkerEXT(GLsizei length, const char *marker) { // The debug marker calls should not set error state // However, it seems reasonable to set an error state if the extension is not enabled - context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + context->handleError(InvalidOperation() << "Extension not enabled"); return; } @@ -1146,7 +1012,7 @@ void GL_APIENTRY PopGroupMarkerEXT() { // The debug marker calls should not set error state // However, it seems reasonable to set an error state if the extension is not enabled - context->recordError(Error(GL_INVALID_OPERATION, "Extension not enabled")); + context->handleError(InvalidOperation() << "Extension not enabled"); return; } @@ -1161,18 +1027,17 @@ ANGLE_EXPORT void GL_APIENTRY EGLImageTargetTexture2DOES(GLenum target, GLeglIma Context *context = GetValidGlobalContext(); if (context) { - egl::Display *display = egl::GetGlobalDisplay(); egl::Image *imageObject = reinterpret_cast(image); - if (!ValidateEGLImageTargetTexture2DOES(context, display, target, imageObject)) + if (!ValidateEGLImageTargetTexture2DOES(context, target, imageObject)) { return; } Texture *texture = context->getTargetTexture(target); - Error error = texture->setEGLImageTarget(target, imageObject); + Error error = texture->setEGLImageTarget(context, target, imageObject); if (error.isError()) { - context->recordError(error); + context->handleError(error); return; } } @@ -1186,18 +1051,17 @@ ANGLE_EXPORT void GL_APIENTRY EGLImageTargetRenderbufferStorageOES(GLenum target Context *context = GetValidGlobalContext(); if (context) { - egl::Display *display = egl::GetGlobalDisplay(); egl::Image *imageObject = reinterpret_cast(image); - if (!ValidateEGLImageTargetRenderbufferStorageOES(context, display, target, imageObject)) + if (!ValidateEGLImageTargetRenderbufferStorageOES(context, target, imageObject)) { return; } - Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer(); - Error error = renderbuffer->setStorageEGLImageTarget(imageObject); + Renderbuffer *renderbuffer = context->getGLState().getCurrentRenderbuffer(); + Error error = renderbuffer->setStorageEGLImageTarget(context, imageObject); if (error.isError()) { - context->recordError(error); + context->handleError(error); return; } } @@ -1210,7 +1074,7 @@ void GL_APIENTRY BindVertexArrayOES(GLuint array) Context *context = GetValidGlobalContext(); if (context) { - if (!ValidateBindVertexArrayOES(context, array)) + if (!context->skipValidation() && !ValidateBindVertexArrayOES(context, array)) { return; } @@ -1226,18 +1090,12 @@ void GL_APIENTRY DeleteVertexArraysOES(GLsizei n, const GLuint *arrays) Context *context = GetValidGlobalContext(); if (context) { - if (!ValidateDeleteVertexArraysOES(context, n)) + if (!context->skipValidation() && !ValidateDeleteVertexArraysOES(context, n, arrays)) { return; } - for (int arrayIndex = 0; arrayIndex < n; arrayIndex++) - { - if (arrays[arrayIndex] != 0) - { - context->deleteVertexArray(arrays[arrayIndex]); - } - } + context->deleteVertexArrays(n, arrays); } } @@ -1248,15 +1106,12 @@ void GL_APIENTRY GenVertexArraysOES(GLsizei n, GLuint *arrays) Context *context = GetValidGlobalContext(); if (context) { - if (!ValidateGenVertexArraysOES(context, n)) + if (!context->skipValidation() && !ValidateGenVertexArraysOES(context, n, arrays)) { return; } - for (int arrayIndex = 0; arrayIndex < n; arrayIndex++) - { - arrays[arrayIndex] = context->createVertexArray(); - } + context->genVertexArrays(n, arrays); } } @@ -1267,19 +1122,12 @@ GLboolean GL_APIENTRY IsVertexArrayOES(GLuint array) Context *context = GetValidGlobalContext(); if (context) { - if (!ValidateIsVertexArrayOES(context)) + if (!context->skipValidation() && !ValidateIsVertexArrayOES(context, array)) { return GL_FALSE; } - if (array == 0) - { - return GL_FALSE; - } - - VertexArray *vao = context->getVertexArray(array); - - return (vao != nullptr ? GL_TRUE : GL_FALSE); + return context->isVertexArray(array); } return GL_FALSE; @@ -1305,9 +1153,7 @@ void GL_APIENTRY DebugMessageControlKHR(GLenum source, return; } - std::vector idVector(ids, ids + count); - context->getState().getDebug().setMessageControl( - source, type, severity, std::move(idVector), (enabled != GL_FALSE)); + context->debugMessageControl(source, type, severity, count, ids, enabled); } } @@ -1331,8 +1177,7 @@ void GL_APIENTRY DebugMessageInsertKHR(GLenum source, return; } - std::string msg(buf, (length > 0) ? static_cast(length) : strlen(buf)); - context->getState().getDebug().insertMessage(source, type, id, severity, std::move(msg)); + context->debugMessageInsert(source, type, id, severity, length, buf); } } @@ -1349,7 +1194,7 @@ void GL_APIENTRY DebugMessageCallbackKHR(GLDEBUGPROCKHR callback, const void *us return; } - context->getState().getDebug().setCallback(callback, userParam); + context->debugMessageCallback(callback, userParam); } } @@ -1377,8 +1222,8 @@ GLuint GL_APIENTRY GetDebugMessageLogKHR(GLuint count, return 0; } - return static_cast(context->getState().getDebug().getMessages( - count, bufSize, sources, types, ids, severities, lengths, messageLog)); + return context->getDebugMessageLog(count, bufSize, sources, types, ids, severities, lengths, + messageLog); } return 0; @@ -1400,7 +1245,7 @@ void GL_APIENTRY PushDebugGroupKHR(GLenum source, GLuint id, GLsizei length, con } std::string msg(message, (length > 0) ? static_cast(length) : strlen(message)); - context->getState().getDebug().pushGroup(source, id, std::move(msg)); + context->pushDebugGroup(source, id, length, message); } } @@ -1416,7 +1261,7 @@ void GL_APIENTRY PopDebugGroupKHR(void) return; } - context->getState().getDebug().popGroup(); + context->popDebugGroup(); } } @@ -1435,11 +1280,7 @@ void GL_APIENTRY ObjectLabelKHR(GLenum identifier, GLuint name, GLsizei length, return; } - LabeledObject *object = context->getLabeledObject(identifier, name); - ASSERT(object != nullptr); - - std::string lbl(label, (length > 0) ? static_cast(length) : strlen(label)); - object->setLabel(lbl); + context->objectLabel(identifier, name, length, label); } } @@ -1459,14 +1300,7 @@ GetObjectLabelKHR(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *leng return; } - LabeledObject *object = context->getLabeledObject(identifier, name); - ASSERT(object != nullptr); - - const std::string &objectLabel = object->getLabel(); - size_t writeLength = std::min(static_cast(bufSize) - 1, objectLabel.length()); - std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label); - label[writeLength] = '\0'; - *length = static_cast(writeLength); + context->getObjectLabel(identifier, name, bufSize, length, label); } } @@ -1483,11 +1317,7 @@ void GL_APIENTRY ObjectPtrLabelKHR(const void *ptr, GLsizei length, const GLchar return; } - LabeledObject *object = context->getLabeledObjectFromPtr(ptr); - ASSERT(object != nullptr); - - std::string lbl(label, (length > 0) ? static_cast(length) : strlen(label)); - object->setLabel(lbl); + context->objectPtrLabel(ptr, length, label); } } @@ -1509,14 +1339,7 @@ void GL_APIENTRY GetObjectPtrLabelKHR(const void *ptr, return; } - LabeledObject *object = context->getLabeledObjectFromPtr(ptr); - ASSERT(object != nullptr); - - const std::string &objectLabel = object->getLabel(); - size_t writeLength = std::min(static_cast(bufSize) - 1, objectLabel.length()); - std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label); - label[writeLength] = '\0'; - *length = static_cast(writeLength); + context->getObjectPtrLabel(ptr, bufSize, length, label); } } @@ -1535,4 +1358,2201 @@ void GL_APIENTRY GetPointervKHR(GLenum pname, void **params) context->getPointerv(pname, params); } } + +ANGLE_EXPORT void GL_APIENTRY BindUniformLocationCHROMIUM(GLuint program, + GLint location, + const GLchar *name) +{ + EVENT("(GLuint program = %u, GLint location = %d, const GLchar *name = 0x%0.8p)", program, + location, name); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!ValidateBindUniformLocationCHROMIUM(context, program, location, name)) + { + return; + } + + context->bindUniformLocation(program, location, name); + } } + +ANGLE_EXPORT void GL_APIENTRY CoverageModulationCHROMIUM(GLenum components) +{ + EVENT("(GLenum components = %u)", components); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!ValidateCoverageModulationCHROMIUM(context, components)) + { + return; + } + context->setCoverageModulation(components); + } +} + +// CHROMIUM_path_rendering +ANGLE_EXPORT void GL_APIENTRY MatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat *matrix) +{ + EVENT("(GLenum matrixMode = %u)", matrixMode); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && !ValidateMatrix(context, matrixMode, matrix)) + { + return; + } + context->loadPathRenderingMatrix(matrixMode, matrix); + } +} + +ANGLE_EXPORT void GL_APIENTRY MatrixLoadIdentityCHROMIUM(GLenum matrixMode) +{ + EVENT("(GLenum matrixMode = %u)", matrixMode); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && !ValidateMatrixMode(context, matrixMode)) + { + return; + } + context->loadPathRenderingIdentityMatrix(matrixMode); + } +} + +ANGLE_EXPORT GLuint GL_APIENTRY GenPathsCHROMIUM(GLsizei range) +{ + EVENT("(GLsizei range = %d)", range); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && !ValidateGenPaths(context, range)) + { + return 0; + } + return context->createPaths(range); + } + return 0; +} + +ANGLE_EXPORT void GL_APIENTRY DeletePathsCHROMIUM(GLuint first, GLsizei range) +{ + EVENT("(GLuint first = %u, GLsizei range = %d)", first, range); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && !ValidateDeletePaths(context, first, range)) + { + return; + } + context->deletePaths(first, range); + } +} + +ANGLE_EXPORT GLboolean GL_APIENTRY IsPathCHROMIUM(GLuint path) +{ + EVENT("(GLuint path = %u)", path); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && !ValidateIsPath(context)) + { + return GL_FALSE; + } + return context->hasPathData(path); + } + return GL_FALSE; +} + +ANGLE_EXPORT void GL_APIENTRY PathCommandsCHROMIUM(GLuint path, + GLsizei numCommands, + const GLubyte *commands, + GLsizei numCoords, + GLenum coordType, + const void *coords) +{ + EVENT( + "(GLuint path = %u, GLsizei numCommands = %d, commands = %p, " + "GLsizei numCoords = %d, GLenum coordType = %u, void* coords = %p)", + path, numCommands, commands, numCoords, coordType, coords); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation()) + { + if (!ValidatePathCommands(context, path, numCommands, commands, numCoords, coordType, + coords)) + { + return; + } + } + context->setPathCommands(path, numCommands, commands, numCoords, coordType, coords); + } +} + +ANGLE_EXPORT void GL_APIENTRY PathParameterfCHROMIUM(GLuint path, GLenum pname, GLfloat value) +{ + EVENT("(GLuint path = %u, GLenum pname = %u, GLfloat value = %f)", path, pname, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && !ValidateSetPathParameter(context, path, pname, value)) + { + return; + } + context->setPathParameterf(path, pname, value); + } +} + +ANGLE_EXPORT void GL_APIENTRY PathParameteriCHROMIUM(GLuint path, GLenum pname, GLint value) +{ + PathParameterfCHROMIUM(path, pname, static_cast(value)); +} + +ANGLE_EXPORT void GL_APIENTRY GetPathParameterfCHROMIUM(GLuint path, GLenum pname, GLfloat *value) +{ + EVENT("(GLuint path = %u, GLenum pname = %u)", path, pname); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && !ValidateGetPathParameter(context, path, pname, value)) + { + return; + } + context->getPathParameterfv(path, pname, value); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetPathParameteriCHROMIUM(GLuint path, GLenum pname, GLint *value) +{ + GLfloat val = 0.0f; + GetPathParameterfCHROMIUM(path, pname, value != nullptr ? &val : nullptr); + if (value) + *value = static_cast(val); +} + +ANGLE_EXPORT void GL_APIENTRY PathStencilFuncCHROMIUM(GLenum func, GLint ref, GLuint mask) +{ + EVENT("(GLenum func = %u, GLint ref = %d, GLuint mask = %u)", func, ref, mask); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && !ValidatePathStencilFunc(context, func, ref, mask)) + { + return; + } + context->setPathStencilFunc(func, ref, mask); + } +} + +ANGLE_EXPORT void GL_APIENTRY StencilFillPathCHROMIUM(GLuint path, GLenum fillMode, GLuint mask) +{ + EVENT("(GLuint path = %u, GLenum fillMode = %u, GLuint mask = %u)", path, fillMode, mask); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && !ValidateStencilFillPath(context, path, fillMode, mask)) + { + return; + } + context->stencilFillPath(path, fillMode, mask); + } +} + +ANGLE_EXPORT void GL_APIENTRY StencilStrokePathCHROMIUM(GLuint path, GLint reference, GLuint mask) +{ + EVENT("(GLuint path = %u, GLint ference = %d, GLuint mask = %u)", path, reference, mask); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateStencilStrokePath(context, path, reference, mask)) + { + return; + } + context->stencilStrokePath(path, reference, mask); + } +} + +ANGLE_EXPORT void GL_APIENTRY CoverFillPathCHROMIUM(GLuint path, GLenum coverMode) +{ + EVENT("(GLuint path = %u, GLenum coverMode = %u)", path, coverMode); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && !ValidateCoverPath(context, path, coverMode)) + { + return; + } + context->coverFillPath(path, coverMode); + } +} + +ANGLE_EXPORT void GL_APIENTRY CoverStrokePathCHROMIUM(GLuint path, GLenum coverMode) +{ + EVENT("(GLuint path = %u, GLenum coverMode = %u)", path, coverMode); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && !ValidateCoverPath(context, path, coverMode)) + { + return; + } + context->coverStrokePath(path, coverMode); + } +} + +ANGLE_EXPORT void GL_APIENTRY StencilThenCoverFillPathCHROMIUM(GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode) +{ + EVENT("(GLuint path = %u, GLenum fillMode = %u, GLuint mask = %u, GLenum coverMode = %u)", path, + fillMode, mask, coverMode); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateStencilThenCoverFillPath(context, path, fillMode, mask, coverMode)) + { + return; + } + context->stencilThenCoverFillPath(path, fillMode, mask, coverMode); + } +} + +ANGLE_EXPORT void GL_APIENTRY StencilThenCoverStrokePathCHROMIUM(GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode) +{ + EVENT("(GLuint path = %u, GLint reference = %d, GLuint mask = %u, GLenum coverMode = %u)", path, + reference, mask, coverMode); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateStencilThenCoverStrokePath(context, path, reference, mask, coverMode)) + { + return; + } + context->stencilThenCoverStrokePath(path, reference, mask, coverMode); + } +} + +ANGLE_EXPORT void GL_APIENTRY CoverFillPathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + EVENT( + "(GLsizei numPaths = %d, GLenum pathNameType = %u, const void *paths = %p " + "GLuint pathBase = %u, GLenum coverMode = %u, GLenum transformType = %u " + "const GLfloat *transformValues = %p)", + numPaths, pathNameType, paths, pathBase, coverMode, transformType, transformValues); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateCoverFillPathInstanced(context, numPaths, pathNameType, paths, pathBase, + coverMode, transformType, transformValues)) + { + return; + } + context->coverFillPathInstanced(numPaths, pathNameType, paths, pathBase, coverMode, + transformType, transformValues); + } +} + +ANGLE_EXPORT void GL_APIENTRY CoverStrokePathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + EVENT( + "(GLsizei numPaths = %d, GLenum pathNameType = %u, const void *paths = %p " + "GLuint pathBase = %u, GLenum coverMode = %u, GLenum transformType = %u " + "const GLfloat *transformValues = %p)", + numPaths, pathNameType, paths, pathBase, coverMode, transformType, transformValues); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateCoverStrokePathInstanced(context, numPaths, pathNameType, paths, pathBase, + coverMode, transformType, transformValues)) + { + return; + } + context->coverStrokePathInstanced(numPaths, pathNameType, paths, pathBase, coverMode, + transformType, transformValues); + } +} + +ANGLE_EXPORT void GL_APIENTRY StencilStrokePathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + EVENT( + "(GLsizei numPaths = %u, GLenum pathNameType = %u, const void *paths = %p " + "GLuint pathBase = %u, GLint reference = %d GLuint mask = %u GLenum transformType = %u " + "const GLfloat *transformValues = %p)", + numPaths, pathNameType, paths, pathBase, reference, mask, transformType, transformValues); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateStencilStrokePathInstanced(context, numPaths, pathNameType, paths, pathBase, + reference, mask, transformType, transformValues)) + { + return; + } + context->stencilStrokePathInstanced(numPaths, pathNameType, paths, pathBase, reference, + mask, transformType, transformValues); + } +} + +ANGLE_EXPORT void GL_APIENTRY StencilFillPathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + EVENT( + "(GLsizei numPaths = %u, GLenum pathNameType = %u const void *paths = %p " + "GLuint pathBase = %u, GLenum fillMode = %u, GLuint mask = %u, GLenum transformType = %u " + "const GLfloat *transformValues = %p)", + numPaths, pathNameType, paths, pathBase, fillMode, mask, transformType, transformValues); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateStencilFillPathInstanced(context, numPaths, pathNameType, paths, pathBase, + fillMode, mask, transformType, transformValues)) + { + return; + } + context->stencilFillPathInstanced(numPaths, pathNameType, paths, pathBase, fillMode, mask, + transformType, transformValues); + } +} + +ANGLE_EXPORT void GL_APIENTRY +StencilThenCoverFillPathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + EVENT( + "(GLsizei numPaths = %u, GLenum pathNameType = %u const void *paths = %p " + "GLuint pathBase = %u, GLenum coverMode = %u, GLuint mask = %u, GLenum transformType = %u " + "const GLfloat *transformValues = %p)", + numPaths, pathNameType, paths, pathBase, coverMode, mask, transformType, transformValues); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateStencilThenCoverFillPathInstanced(context, numPaths, pathNameType, paths, + pathBase, fillMode, mask, coverMode, + transformType, transformValues)) + { + return; + } + context->stencilThenCoverFillPathInstanced(numPaths, pathNameType, paths, pathBase, + fillMode, mask, coverMode, transformType, + transformValues); + } +} + +ANGLE_EXPORT void GL_APIENTRY +StencilThenCoverStrokePathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + EVENT( + "(GLsizei numPaths = %u, GLenum pathNameType = %u, const void *paths = %p " + "GLuint pathBase = %u GLenum coverMode = %u GLint reference = %d GLuint mask = %u GLenum " + "transformType = %u " + "const GLfloat *transformValues = %p)", + numPaths, pathNameType, paths, pathBase, coverMode, reference, mask, transformType, + transformValues); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateStencilThenCoverStrokePathInstanced(context, numPaths, pathNameType, paths, + pathBase, reference, mask, coverMode, + transformType, transformValues)) + { + return; + } + context->stencilThenCoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase, + reference, mask, coverMode, transformType, + transformValues); + } +} + +ANGLE_EXPORT void GL_APIENTRY BindFragmentInputLocationCHROMIUM(GLuint program, + GLint location, + const GLchar *name) +{ + EVENT("(GLuint program = %u, GLint location = %d, const GLchar *name = %p)", program, location, + name); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateBindFragmentInputLocation(context, program, location, name)) + { + return; + } + context->bindFragmentInputLocation(program, location, name); + } +} + +ANGLE_EXPORT void GL_APIENTRY ProgramPathFragmentInputGenCHROMIUM(GLuint program, + GLint location, + GLenum genMode, + GLint components, + const GLfloat *coeffs) +{ + EVENT( + "(GLuint program = %u, GLint location %d, GLenum genMode = %u, GLint components = %d, " + "const GLfloat * coeffs = %p)", + program, location, genMode, components, coeffs); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateProgramPathFragmentInputGen(context, program, location, genMode, components, + coeffs)) + { + return; + } + context->programPathFragmentInputGen(program, location, genMode, components, coeffs); + } +} + +ANGLE_EXPORT void GL_APIENTRY CopyTextureCHROMIUM(GLuint sourceId, + GLint sourceLevel, + GLenum destTarget, + GLuint destId, + GLint destLevel, + GLint internalFormat, + GLenum destType, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha) +{ + EVENT( + "(GLuint sourceId = %u, GLint sourceLevel = %d, GLenum destTarget = 0x%X, GLuint destId = " + "%u, GLint destLevel = %d, GLint internalFormat = 0x%X, GLenum destType = " + "0x%X, GLboolean unpackFlipY = %u, GLboolean unpackPremultiplyAlpha = %u, GLboolean " + "unpackUnmultiplyAlpha = %u)", + sourceId, sourceLevel, destTarget, destId, destLevel, internalFormat, destType, unpackFlipY, + unpackPremultiplyAlpha, unpackUnmultiplyAlpha); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateCopyTextureCHROMIUM(context, sourceId, sourceLevel, destTarget, destId, + destLevel, internalFormat, destType, unpackFlipY, + unpackPremultiplyAlpha, unpackUnmultiplyAlpha)) + { + return; + } + + context->copyTextureCHROMIUM(sourceId, sourceLevel, destTarget, destId, destLevel, + internalFormat, destType, unpackFlipY, unpackPremultiplyAlpha, + unpackUnmultiplyAlpha); + } +} + +ANGLE_EXPORT void GL_APIENTRY CopySubTextureCHROMIUM(GLuint sourceId, + GLint sourceLevel, + GLenum destTarget, + GLuint destId, + GLint destLevel, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha) +{ + EVENT( + "(GLuint sourceId = %u, GLint sourceLevel = %d, GLenum destTarget = 0x%X, GLuint destId = " + "%u, GLint destLevel = %d, GLint xoffset = " + "%d, GLint yoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = " + "%d, GLboolean unpackPremultiplyAlpha = %u, GLboolean unpackUnmultiplyAlpha = %u)", + sourceId, sourceLevel, destTarget, destId, destLevel, xoffset, yoffset, x, y, width, height, + unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateCopySubTextureCHROMIUM( + context, sourceId, sourceLevel, destTarget, destId, destLevel, xoffset, yoffset, x, + y, width, height, unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha)) + { + return; + } + + context->copySubTextureCHROMIUM(sourceId, sourceLevel, destTarget, destId, destLevel, + xoffset, yoffset, x, y, width, height, unpackFlipY, + unpackPremultiplyAlpha, unpackUnmultiplyAlpha); + } +} + +ANGLE_EXPORT void GL_APIENTRY CompressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId) +{ + EVENT("(GLuint sourceId = %u, GLuint destId = %u)", sourceId, destId); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateCompressedCopyTextureCHROMIUM(context, sourceId, destId)) + { + return; + } + + context->compressedCopyTextureCHROMIUM(sourceId, destId); + } +} + +ANGLE_EXPORT void GL_APIENTRY RequestExtensionANGLE(const GLchar *name) +{ + EVENT("(const GLchar *name = %p)", name); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && !ValidateRequestExtensionANGLE(context, name)) + { + return; + } + + context->requestExtension(name); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetBooleanvRobustANGLE(GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLboolean *params) +{ + EVENT( + "(GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLboolean* params " + "= 0x%0.8p)", + pname, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLenum nativeType; + unsigned int numParams = 0; + if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams)) + { + return; + } + + context->getBooleanv(pname, params); + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetBufferParameterivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, + params); + + Context *context = GetValidGlobalContext(); + if (context) + { + BufferBinding targetPacked = FromGLenum(target); + + GLsizei numParams = 0; + if (!ValidateGetBufferParameterivRobustANGLE(context, targetPacked, pname, bufSize, + &numParams, params)) + { + return; + } + + Buffer *buffer = context->getGLState().getTargetBuffer(targetPacked); + QueryBufferParameteriv(buffer, pname, params); + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetFloatvRobustANGLE(GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params) +{ + EVENT( + "(GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLfloat* params = " + "0x%0.8p)", + pname, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLenum nativeType; + unsigned int numParams = 0; + if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams)) + { + return; + } + + context->getFloatv(pname, params); + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetFramebufferAttachmentParameterivRobustANGLE(GLenum target, + GLenum attachment, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = " + "%d, GLsizei* length = 0x%0.8p, GLint* params = 0x%0.8p)", + target, attachment, pname, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei numParams = 0; + if (!ValidateGetFramebufferAttachmentParameterivRobustANGLE(context, target, attachment, + pname, bufSize, &numParams)) + { + return; + } + + const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target); + QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params); + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetIntegervRobustANGLE(GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *data) +{ + EVENT( + "(GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLint* params = " + "0x%0.8p)", + pname, bufSize, length, data); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLenum nativeType; + unsigned int numParams = 0; + if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams)) + { + return; + } + + context->getIntegerv(pname, data); + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetProgramivRobustANGLE(GLuint program, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLuint program = %d, GLenum pname = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, " + "GLint* params = 0x%0.8p)", + program, pname, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei numParams = 0; + if (!ValidateGetProgramivRobustANGLE(context, program, pname, bufSize, &numParams)) + { + return; + } + + Program *programObject = context->getProgram(program); + QueryProgramiv(context, programObject, pname, params); + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetRenderbufferParameterivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLint* params = 0x%0.8p)", + target, pname, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei numParams = 0; + if (!ValidateGetRenderbufferParameterivRobustANGLE(context, target, pname, bufSize, + &numParams, params)) + { + return; + } + + Renderbuffer *renderbuffer = context->getGLState().getCurrentRenderbuffer(); + QueryRenderbufferiv(context, renderbuffer, pname, params); + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY +GetShaderivRobustANGLE(GLuint shader, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params) +{ + EVENT( + "(GLuint shader = %d, GLenum pname = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, " + "GLint* params = 0x%0.8p)", + shader, pname, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei numParams = 0; + if (!ValidateGetShaderivRobustANGLE(context, shader, pname, bufSize, &numParams, params)) + { + return; + } + + Shader *shaderObject = context->getShader(shader); + QueryShaderiv(context, shaderObject, pname, params); + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetTexParameterfvRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLfloat* params = 0x%0.8p)", + target, pname, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei numParams = 0; + if (!ValidateGetTexParameterfvRobustANGLE(context, target, pname, bufSize, &numParams, + params)) + { + return; + } + + Texture *texture = context->getTargetTexture(target); + QueryTexParameterfv(texture, pname, params); + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetTexParameterivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLfloat* params = 0x%0.8p)", + target, pname, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei numParams = 0; + if (!ValidateGetTexParameterivRobustANGLE(context, target, pname, bufSize, &numParams, + params)) + { + return; + } + + Texture *texture = context->getTargetTexture(target); + QueryTexParameteriv(texture, pname, params); + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetUniformfvRobustANGLE(GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLfloat *params) +{ + EVENT( + "(GLuint program = %d, GLint location = %d, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLfloat* params = 0x%0.8p)", + program, location, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei writeLength = 0; + if (!ValidateGetUniformfvRobustANGLE(context, program, location, bufSize, &writeLength, + params)) + { + return; + } + + Program *programObject = context->getProgram(program); + ASSERT(programObject); + + programObject->getUniformfv(context, location, params); + SetRobustLengthParam(length, writeLength); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetUniformivRobustANGLE(GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLuint program = %d, GLint location = %d, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLint* params = 0x%0.8p)", + program, location, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei writeLength = 0; + if (!ValidateGetUniformivRobustANGLE(context, program, location, bufSize, &writeLength, + params)) + { + return; + } + + Program *programObject = context->getProgram(program); + ASSERT(programObject); + + programObject->getUniformiv(context, location, params); + SetRobustLengthParam(length, writeLength); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetVertexAttribfvRobustANGLE(GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params) +{ + EVENT( + "(GLuint index = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, " + "GLfloat* params = 0x%0.8p)", + index, pname, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei writeLength = 0; + if (!ValidateGetVertexAttribfvRobustANGLE(context, index, pname, bufSize, &writeLength, + params)) + { + return; + } + + context->getVertexAttribfv(index, pname, params); + SetRobustLengthParam(length, writeLength); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetVertexAttribivRobustANGLE(GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLuint index = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, " + "GLint* params = 0x%0.8p)", + index, pname, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei writeLength = 0; + if (!ValidateGetVertexAttribivRobustANGLE(context, index, pname, bufSize, &writeLength, + params)) + { + return; + } + + context->getVertexAttribiv(index, pname, params); + SetRobustLengthParam(length, writeLength); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetVertexAttribPointervRobustANGLE(GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **pointer) +{ + EVENT( + "(GLuint index = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, " + "void** pointer = 0x%0.8p)", + index, pname, bufSize, length, pointer); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei writeLength = 0; + if (!ValidateGetVertexAttribPointervRobustANGLE(context, index, pname, bufSize, + &writeLength, pointer)) + { + return; + } + + context->getVertexAttribPointerv(index, pname, pointer); + SetRobustLengthParam(length, writeLength); + } +} + +ANGLE_EXPORT void GL_APIENTRY ReadPixelsRobustANGLE(GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + GLsizei *columns, + GLsizei *rows, + void *pixels) +{ + EVENT( + "(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, " + "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLsizei* columns = 0x%0.8p, GLsizei* rows = 0x%0.8p, void* pixels = 0x%0.8p)", + x, y, width, height, format, type, bufSize, length, columns, rows, pixels); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei writeLength = 0; + GLsizei writeColumns = 0; + GLsizei writeRows = 0; + if (!ValidateReadPixelsRobustANGLE(context, x, y, width, height, format, type, bufSize, + &writeLength, &writeColumns, &writeRows, pixels)) + { + return; + } + + context->readPixels(x, y, width, height, format, type, pixels); + + SetRobustLengthParam(length, writeLength); + SetRobustLengthParam(columns, writeColumns); + SetRobustLengthParam(rows, writeRows); + } +} + +ANGLE_EXPORT void GL_APIENTRY TexImage2DRobustANGLE(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, " + "GLsizei height = %d, GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, GLsizei " + "bufSize = %d, const void* pixels = 0x%0.8p)", + target, level, internalformat, width, height, border, format, type, bufSize, pixels); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!ValidateTexImage2DRobust(context, target, level, internalformat, width, height, border, + format, type, bufSize, pixels)) + { + return; + } + + context->texImage2D(target, level, internalformat, width, height, border, format, type, + pixels); + } +} + +ANGLE_EXPORT void GL_APIENTRY TexParameterfvRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + const GLfloat *params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, GLfloat* params = " + "0x%0.8p)", + target, pname, bufSize, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!ValidateTexParameterfvRobustANGLE(context, target, pname, bufSize, params)) + { + return; + } + + Texture *texture = context->getTargetTexture(target); + SetTexParameterfv(context, texture, pname, params); + } +} + +ANGLE_EXPORT void GL_APIENTRY TexParameterivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + const GLint *params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, GLfloat* params = " + "0x%0.8p)", + target, pname, bufSize, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!ValidateTexParameterivRobustANGLE(context, target, pname, bufSize, params)) + { + return; + } + + Texture *texture = context->getTargetTexture(target); + SetTexParameteriv(context, texture, pname, params); + } +} + +ANGLE_EXPORT void GL_APIENTRY TexSubImage2DRobustANGLE(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " + "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, " + "GLsizei bufsize = %d, const void* pixels = 0x%0.8p)", + target, level, xoffset, yoffset, width, height, format, type, bufSize, pixels); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!ValidateTexSubImage2DRobustANGLE(context, target, level, xoffset, yoffset, width, + height, format, type, bufSize, pixels)) + { + return; + } + + context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, + pixels); + } +} + +ANGLE_EXPORT void GL_APIENTRY TexImage3DRobustANGLE(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, " + "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLenum format = 0x%X, " + "GLenum type = 0x%X, GLsizei bufsize = %d, const void* pixels = 0x%0.8p)", + target, level, internalformat, width, height, depth, border, format, type, bufSize, pixels); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!ValidateTexImage3DRobustANGLE(context, target, level, internalformat, width, height, + depth, border, format, type, bufSize, pixels)) + { + return; + } + + context->texImage3D(target, level, internalformat, width, height, depth, border, format, + type, pixels); + } +} + +ANGLE_EXPORT void GL_APIENTRY TexSubImage3DRobustANGLE(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " + "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, " + "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufsize = %d, const void* pixels = " + "0x%0.8p)", + target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, bufSize, + pixels); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!ValidateTexSubImage3DRobustANGLE(context, target, level, xoffset, yoffset, zoffset, + width, height, depth, format, type, bufSize, pixels)) + { + return; + } + + context->texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, + format, type, pixels); + } +} + +void GL_APIENTRY CompressedTexImage2DRobustANGLE(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + GLsizei dataSize, + const GLvoid *data) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = " + "%d, " + "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, GLsizei dataSize = %d, " + "const GLvoid* data = 0x%0.8p)", + target, level, internalformat, width, height, border, imageSize, dataSize, data); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateCompressedTexImage2DRobustANGLE(context, target, level, internalformat, width, + height, border, imageSize, dataSize, data)) + { + return; + } + + context->compressedTexImage2D(target, level, internalformat, width, height, border, + imageSize, data); + } +} + +void GL_APIENTRY CompressedTexSubImage2DRobustANGLE(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + GLsizei dataSize, + const GLvoid *data) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " + "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, " + "GLsizei imageSize = %d, GLsizei dataSize = %d, const GLvoid* data = 0x%0.8p)", + target, level, xoffset, yoffset, width, height, format, imageSize, dataSize, data); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && !ValidateCompressedTexSubImage2DRobustANGLE( + context, target, level, xoffset, yoffset, width, + height, format, imageSize, dataSize, data)) + { + return; + } + + context->compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, + imageSize, data); + } +} + +void GL_APIENTRY CompressedTexImage3DRobustANGLE(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + GLsizei dataSize, + const GLvoid *data) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = " + "%d, " + "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, " + "GLsizei dataSize = %d, const GLvoid* data = 0x%0.8p)", + target, level, internalformat, width, height, depth, border, imageSize, dataSize, data); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && !ValidateCompressedTexImage3DRobustANGLE( + context, target, level, internalformat, width, height, + depth, border, imageSize, dataSize, data)) + { + return; + } + + context->compressedTexImage3D(target, level, internalformat, width, height, depth, border, + imageSize, data); + } +} + +void GL_APIENTRY CompressedTexSubImage3DRobustANGLE(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + GLsizei dataSize, + const GLvoid *data) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " + "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, " + "GLenum format = 0x%X, GLsizei imageSize = %d, GLsizei dataSize = %d, const GLvoid* data = " + "0x%0.8p)", + target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, dataSize, + data); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateCompressedTexSubImage3DRobustANGLE(context, target, level, xoffset, yoffset, + zoffset, width, height, depth, format, + imageSize, dataSize, data)) + { + return; + } + + context->compressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, + depth, format, imageSize, data); + } +} + +ANGLE_EXPORT void GL_APIENTRY +GetQueryivRobustANGLE(GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLint* params = 0x%0.8p)", + target, pname, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei numParams = 0; + if (!ValidateGetQueryivRobustANGLE(context, target, pname, bufSize, &numParams, params)) + { + return; + } + + context->getQueryiv(target, pname, params); + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetQueryObjectuivRobustANGLE(GLuint id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params) +{ + EVENT( + "(GLuint id = %u, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, " + "GLint* params = 0x%0.8p)", + id, pname, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei numParams = 0; + if (!ValidateGetQueryObjectuivRobustANGLE(context, id, pname, bufSize, &numParams, params)) + { + return; + } + + context->getQueryObjectuiv(id, pname, params); + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetBufferPointervRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, void** params = 0x%0.8p)", + target, pname, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + BufferBinding targetPacked = FromGLenum(target); + + GLsizei numParams = 0; + if (!ValidateGetBufferPointervRobustANGLE(context, targetPacked, pname, bufSize, &numParams, + params)) + { + return; + } + + context->getBufferPointerv(targetPacked, pname, params); + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY +GetIntegeri_vRobustANGLE(GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, GLint *data) +{ + EVENT( + "(GLenum target = 0x%X, GLuint index = %u, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLint* data = 0x%0.8p)", + target, index, bufSize, length, data); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei numParams = 0; + if (!ValidateGetIntegeri_vRobustANGLE(context, target, index, bufSize, &numParams, data)) + { + return; + } + + context->getIntegeri_v(target, index, data); + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetInternalformativRobustANGLE(GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLenum pname = 0x%X, GLsizei bufSize " + "= %d, GLsizei* length = 0x%0.8p, GLint* params = 0x%0.8p)", + target, internalformat, pname, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei numParams = 0; + if (!ValidateGetInternalFormativRobustANGLE(context, target, internalformat, pname, bufSize, + &numParams, params)) + { + return; + } + + const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat); + QueryInternalFormativ(formatCaps, pname, bufSize, params); + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetVertexAttribIivRobustANGLE(GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLuint index = %u, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, " + "GLint* params = 0x%0.8p)", + index, pname, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei writeLength = 0; + if (!ValidateGetVertexAttribIivRobustANGLE(context, index, pname, bufSize, &writeLength, + params)) + { + return; + } + + context->getVertexAttribIiv(index, pname, params); + SetRobustLengthParam(length, writeLength); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetVertexAttribIuivRobustANGLE(GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params) +{ + EVENT( + "(GLuint index = %u, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, " + "GLuint* params = 0x%0.8p)", + index, pname, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei writeLength = 0; + if (!ValidateGetVertexAttribIuivRobustANGLE(context, index, pname, bufSize, &writeLength, + params)) + { + return; + } + + context->getVertexAttribIuiv(index, pname, params); + SetRobustLengthParam(length, writeLength); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetUniformuivRobustANGLE(GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLuint *params) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLuint* params = 0x%0.8p)", + program, location, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei writeLength = 0; + if (!ValidateGetUniformuivRobustANGLE(context, program, location, bufSize, &writeLength, + params)) + { + return; + } + + Program *programObject = context->getProgram(program); + ASSERT(programObject); + + programObject->getUniformuiv(context, location, params); + SetRobustLengthParam(length, writeLength); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetActiveUniformBlockivRobustANGLE(GLuint program, + GLuint uniformBlockIndex, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLuint program = %u, GLuint uniformBlockIndex = %u, GLenum pname = 0x%X, GLsizei bufsize " + "= %d, GLsizei* length = 0x%0.8p, GLint* params = 0x%0.8p)", + program, uniformBlockIndex, pname, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei writeLength = 0; + if (!ValidateGetActiveUniformBlockivRobustANGLE(context, program, uniformBlockIndex, pname, + bufSize, &writeLength, params)) + { + return; + } + + const Program *programObject = context->getProgram(program); + QueryActiveUniformBlockiv(programObject, uniformBlockIndex, pname, params); + SetRobustLengthParam(length, writeLength); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetInteger64vRobustANGLE(GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint64 *data) +{ + EVENT( + "(GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLint64* params = " + "0x%0.8p)", + pname, bufSize, length, data); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLenum nativeType; + unsigned int numParams = 0; + if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams)) + { + return; + } + + if (nativeType == GL_INT_64_ANGLEX) + { + context->getInteger64v(pname, data); + } + else + { + CastStateValues(context, nativeType, pname, numParams, data); + } + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetInteger64i_vRobustANGLE(GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint64 *data) +{ + EVENT( + "(GLenum target = 0x%X, GLuint index = %u, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLint64* data = 0x%0.8p)", + target, index, bufSize, length, data); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei numParams = 0; + if (!ValidateGetInteger64i_vRobustANGLE(context, target, index, bufSize, &numParams, data)) + { + return; + } + + context->getInteger64i_v(target, index, data); + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetBufferParameteri64vRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint64 *params) +{ + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint64* params = 0x%0.8p)", target, pname, + bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + BufferBinding targetPacked = FromGLenum(target); + + GLsizei numParams = 0; + if (!ValidateGetBufferParameteri64vRobustANGLE(context, targetPacked, pname, bufSize, + &numParams, params)) + { + return; + } + + Buffer *buffer = context->getGLState().getTargetBuffer(targetPacked); + QueryBufferParameteri64v(buffer, pname, params); + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY SamplerParameterivRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + const GLint *param) +{ + EVENT( + "(GLuint sampler = %u, GLenum pname = 0x%X, GLsizei bufsize = %d, const GLint* params = " + "0x%0.8p)", + sampler, pname, bufSize, param); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!ValidateSamplerParameterivRobustANGLE(context, sampler, pname, bufSize, param)) + { + return; + } + + context->samplerParameteriv(sampler, pname, param); + } +} + +ANGLE_EXPORT void GL_APIENTRY SamplerParameterfvRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + const GLfloat *param) +{ + EVENT( + "(GLuint sampler = %u, GLenum pname = 0x%X, GLsizei bufsize = %d, const GLfloat* params = " + "0x%0.8p)", + sampler, pname, bufSize, param); + + Context *context = GetValidGlobalContext(); + if (context) + { + if (!ValidateSamplerParameterfvRobustANGLE(context, sampler, pname, bufSize, param)) + { + return; + } + + context->samplerParameterfv(sampler, pname, param); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetSamplerParameterivRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLuint sampler = %u, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLint* params = 0x%0.8p)", + sampler, pname, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei numParams = 0; + if (!ValidateGetSamplerParameterivRobustANGLE(context, sampler, pname, bufSize, &numParams, + params)) + { + return; + } + + context->getSamplerParameteriv(sampler, pname, params); + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetSamplerParameterfvRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params) +{ + EVENT( + "(GLuint sample = %ur, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLfloat* params = 0x%0.8p)", + sampler, pname, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei numParams = 0; + if (!ValidateGetSamplerParameterfvRobustANGLE(context, sampler, pname, bufSize, &numParams, + params)) + { + return; + } + + context->getSamplerParameterfv(sampler, pname, params); + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetFramebufferParameterivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLint* params = 0x%0.8p)", + target, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetProgramInterfaceivRobustANGLE(GLuint program, + GLenum programInterface, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLuint program = %u, GLenum programInterface = 0x%X, GLenum pname = 0x%X, GLsizei " + "bufsize = %d, GLsizei* length = 0x%0.8p, GLint* params = 0x%0.8p)", + program, programInterface, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetBooleani_vRobustANGLE(GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLboolean *data) +{ + EVENT( + "(GLenum target = 0x%X, GLuint index = %u, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLboolean* data = 0x%0.8p)", + target, index, bufSize, length, data); + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei numParams = 0; + if (!ValidateGetBooleani_vRobustANGLE(context, target, index, bufSize, &numParams, data)) + { + return; + } + + context->getBooleani_v(target, index, data); + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetMultisamplefvRobustANGLE(GLenum pname, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLfloat *val) +{ + EVENT( + "(GLenum pname = 0x%X, GLuint index = %u, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, " + "GLfloat* val = 0x%0.8p)", + pname, index, bufSize, length, val); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetTexLevelParameterivRobustANGLE(GLenum target, + GLint level, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, " + "GLsizei* length = 0x%0.8p, GLint* params = 0x%0.8p)", + target, level, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetTexLevelParameterfvRobustANGLE(GLenum target, + GLint level, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, " + "GLsizei* length = 0x%0.8p, GLfloat* params = 0x%0.8p)", + target, level, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetPointervRobustANGLERobustANGLE(GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **params) +{ + EVENT( + "(GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, void **params = " + "0x%0.8p)", + pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY ReadnPixelsRobustANGLE(GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + GLsizei *columns, + GLsizei *rows, + void *data) +{ + EVENT( + "(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, " + "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLsizei* columns = 0x%0.8p, GLsizei* rows = 0x%0.8p, void *data = 0x%0.8p)", + x, y, width, height, format, type, bufSize, length, columns, rows, data); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei writeLength = 0; + GLsizei writeColumns = 0; + GLsizei writeRows = 0; + if (!ValidateReadnPixelsRobustANGLE(context, x, y, width, height, format, type, bufSize, + &writeLength, &writeColumns, &writeRows, data)) + { + return; + } + + context->readPixels(x, y, width, height, format, type, data); + + SetRobustLengthParam(length, writeLength); + SetRobustLengthParam(columns, writeColumns); + SetRobustLengthParam(rows, writeRows); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetnUniformfvRobustANGLE(GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLfloat *params) +{ + EVENT( + "(GLuint program = %d, GLint location = %d, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLfloat* params = 0x%0.8p)", + program, location, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetnUniformivRobustANGLE(GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLuint program = %d, GLint location = %d, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLint* params = 0x%0.8p)", + program, location, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetnUniformuivRobustANGLE(GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLuint *params) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLuint* params = 0x%0.8p)", + program, location, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY TexParameterIivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + const GLint *params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, const GLint *params = " + "0x%0.8p)", + target, pname, bufSize, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY TexParameterIuivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + const GLuint *params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, const GLuint *params = " + "0x%0.8p)", + target, pname, bufSize, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetTexParameterIivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLint *params = 0x%0.8p)", + target, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetTexParameterIuivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLuint *params = 0x%0.8p)", + target, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY SamplerParameterIivRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + const GLint *param) +{ + EVENT( + "(GLuint sampler = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, const GLint *param = " + "0x%0.8p)", + sampler, pname, bufSize, param); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY SamplerParameterIuivRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + const GLuint *param) +{ + EVENT( + "(GLuint sampler = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, const GLuint *param = " + "0x%0.8p)", + sampler, pname, bufSize, param); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetSamplerParameterIivRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLuint sampler = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLint *params = 0x%0.8p)", + sampler, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetSamplerParameterIuivRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params) +{ + EVENT( + "(GLuint sampler = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = " + "0x%0.8p, GLuint *params = 0x%0.8p)", + sampler, pname, bufSize, length, params); + UNIMPLEMENTED(); +} + +ANGLE_EXPORT void GL_APIENTRY GetQueryObjectivRobustANGLE(GLuint id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLuint id = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, " + "GLuint *params = 0x%0.8p)", + id, pname, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei numParams = 0; + if (!ValidateGetQueryObjectivRobustANGLE(context, id, pname, bufSize, &numParams, params)) + { + return; + } + + context->getQueryObjectiv(id, pname, params); + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetQueryObjecti64vRobustANGLE(GLuint id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint64 *params) +{ + EVENT( + "(GLuint id = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, " + "GLint64 *params = 0x%0.8p)", + id, pname, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei numParams = 0; + if (!ValidateGetQueryObjecti64vRobustANGLE(context, id, pname, bufSize, &numParams, params)) + { + return; + } + + context->getQueryObjecti64v(id, pname, params); + SetRobustLengthParam(length, numParams); + } +} + +ANGLE_EXPORT void GL_APIENTRY GetQueryObjectui64vRobustANGLE(GLuint id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint64 *params) +{ + EVENT( + "(GLuint id = %d, GLenum pname = 0x%X, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, " + "GLuint64 *params = 0x%0.8p)", + id, pname, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + GLsizei numParams = 0; + if (!ValidateGetQueryObjectui64vRobustANGLE(context, id, pname, bufSize, &numParams, + params)) + { + return; + } + + context->getQueryObjectui64v(id, pname, params); + SetRobustLengthParam(length, numParams); + } +} + +GL_APICALL void GL_APIENTRY FramebufferTextureMultiviewLayeredANGLE(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint baseViewIndex, + GLsizei numViews) +{ + EVENT( + "(GLenum target = 0x%X, GLenum attachment = 0x%X, GLuint texture = %u, GLint level = %d, " + "GLint baseViewIndex = %d, GLsizei numViews = %d)", + target, attachment, texture, level, baseViewIndex, numViews); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateFramebufferTextureMultiviewLayeredANGLE(context, target, attachment, texture, + level, baseViewIndex, numViews)) + { + return; + } + context->framebufferTextureMultiviewLayeredANGLE(target, attachment, texture, level, + baseViewIndex, numViews); + } +} + +GL_APICALL void GL_APIENTRY FramebufferTextureMultiviewSideBySideANGLE(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLsizei numViews, + const GLint *viewportOffsets) +{ + EVENT( + "(GLenum target = 0x%X, GLenum attachment = 0x%X, GLuint texture = %u, GLint level = %d, " + "GLsizei numViews = %d, GLsizei* viewportOffsets = 0x%0.8p)", + target, attachment, texture, level, numViews, viewportOffsets); + Context *context = GetValidGlobalContext(); + if (context) + { + if (!context->skipValidation() && + !ValidateFramebufferTextureMultiviewSideBySideANGLE( + context, target, attachment, texture, level, numViews, viewportOffsets)) + { + return; + } + context->framebufferTextureMultiviewSideBySideANGLE(target, attachment, texture, level, + numViews, viewportOffsets); + } +} + +} // gl diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_ext.h b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_ext.h index a2fb9c5e80..2a3fa607cf 100644 --- a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_ext.h +++ b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_2_0_ext.h @@ -17,17 +17,32 @@ namespace gl { // GL_ANGLE_framebuffer_blit -ANGLE_EXPORT void GL_APIENTRY BlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +ANGLE_EXPORT void GL_APIENTRY BlitFramebufferANGLE(GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter); // GL_ANGLE_framebuffer_multisample -ANGLE_EXPORT void GL_APIENTRY RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +ANGLE_EXPORT void GL_APIENTRY RenderbufferStorageMultisampleANGLE(GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height); // GL_EXT_discard_framebuffer -ANGLE_EXPORT void GL_APIENTRY DiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum *attachments); +ANGLE_EXPORT void GL_APIENTRY DiscardFramebufferEXT(GLenum target, + GLsizei numAttachments, + const GLenum *attachments); // GL_NV_fence -ANGLE_EXPORT void GL_APIENTRY DeleteFencesNV(GLsizei n, const GLuint* fences); -ANGLE_EXPORT void GL_APIENTRY GenFencesNV(GLsizei n, GLuint* fences); +ANGLE_EXPORT void GL_APIENTRY DeleteFencesNV(GLsizei n, const GLuint *fences); +ANGLE_EXPORT void GL_APIENTRY GenFencesNV(GLsizei n, GLuint *fences); ANGLE_EXPORT GLboolean GL_APIENTRY IsFenceNV(GLuint fence); ANGLE_EXPORT GLboolean GL_APIENTRY TestFenceNV(GLuint fence); ANGLE_EXPORT void GL_APIENTRY GetFenceivNV(GLuint fence, GLenum pname, GLint *params); @@ -35,16 +50,36 @@ ANGLE_EXPORT void GL_APIENTRY FinishFenceNV(GLuint fence); ANGLE_EXPORT void GL_APIENTRY SetFenceNV(GLuint fence, GLenum condition); // GL_ANGLE_translated_shader_source -ANGLE_EXPORT void GL_APIENTRY GetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source); +ANGLE_EXPORT void GL_APIENTRY GetTranslatedShaderSourceANGLE(GLuint shader, + GLsizei bufsize, + GLsizei *length, + GLchar *source); // GL_EXT_texture_storage -ANGLE_EXPORT void GL_APIENTRY TexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +ANGLE_EXPORT void GL_APIENTRY TexStorage2DEXT(GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height); // GL_EXT_robustness ANGLE_EXPORT GLenum GL_APIENTRY GetGraphicsResetStatusEXT(void); -ANGLE_EXPORT void GL_APIENTRY ReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); -ANGLE_EXPORT void GL_APIENTRY GetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, float *params); -ANGLE_EXPORT void GL_APIENTRY GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint *params); +ANGLE_EXPORT void GL_APIENTRY ReadnPixelsEXT(GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + void *data); +ANGLE_EXPORT void GL_APIENTRY GetnUniformfvEXT(GLuint program, + GLint location, + GLsizei bufSize, + float *params); +ANGLE_EXPORT void GL_APIENTRY GetnUniformivEXT(GLuint program, + GLint location, + GLsizei bufSize, + GLint *params); // GL_EXT_occlusion_query_boolean ANGLE_EXPORT void GL_APIENTRY GenQueriesEXT(GLsizei n, GLuint *ids); @@ -65,22 +100,41 @@ ANGLE_EXPORT void GL_APIENTRY GetQueryObjectui64vEXT(GLuint id, GLenum pname, GL ANGLE_EXPORT void GL_APIENTRY DrawBuffersEXT(GLsizei n, const GLenum *bufs); // GL_ANGLE_instanced_arrays -ANGLE_EXPORT void GL_APIENTRY DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount); -ANGLE_EXPORT void GL_APIENTRY DrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +ANGLE_EXPORT void GL_APIENTRY DrawArraysInstancedANGLE(GLenum mode, + GLint first, + GLsizei count, + GLsizei primcount); +ANGLE_EXPORT void GL_APIENTRY DrawElementsInstancedANGLE(GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei primcount); ANGLE_EXPORT void GL_APIENTRY VertexAttribDivisorANGLE(GLuint index, GLuint divisor); // GL_OES_get_program_binary -ANGLE_EXPORT void GL_APIENTRY GetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary); -ANGLE_EXPORT void GL_APIENTRY ProgramBinaryOES(GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length); +ANGLE_EXPORT void GL_APIENTRY GetProgramBinaryOES(GLuint program, + GLsizei bufSize, + GLsizei *length, + GLenum *binaryFormat, + void *binary); +ANGLE_EXPORT void GL_APIENTRY ProgramBinaryOES(GLuint program, + GLenum binaryFormat, + const void *binary, + GLint length); // GL_OES_mapbuffer ANGLE_EXPORT void *GL_APIENTRY MapBufferOES(GLenum target, GLenum access); ANGLE_EXPORT GLboolean GL_APIENTRY UnmapBufferOES(GLenum target); -ANGLE_EXPORT void GL_APIENTRY GetBufferPointervOES(GLenum target, GLenum pname, GLvoid **params); +ANGLE_EXPORT void GL_APIENTRY GetBufferPointervOES(GLenum target, GLenum pname, void **params); // GL_EXT_map_buffer_range -ANGLE_EXPORT void *GL_APIENTRY MapBufferRangeEXT(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); -ANGLE_EXPORT void GL_APIENTRY FlushMappedBufferRangeEXT(GLenum target, GLintptr offset, GLsizeiptr length); +ANGLE_EXPORT void *GL_APIENTRY MapBufferRangeEXT(GLenum target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access); +ANGLE_EXPORT void GL_APIENTRY FlushMappedBufferRangeEXT(GLenum target, + GLintptr offset, + GLsizeiptr length); // GL_EXT_debug_marker ANGLE_EXPORT void GL_APIENTRY InsertEventMarkerEXT(GLsizei length, const char *marker); @@ -140,6 +194,524 @@ ANGLE_EXPORT void GL_APIENTRY GetObjectPtrLabelKHR(const void *ptr, GLsizei *length, GLchar *label); ANGLE_EXPORT void GL_APIENTRY GetPointervKHR(GLenum pname, void **params); -} -#endif // LIBGLESV2_ENTRYPOINTGLES20EXT_H_ +// GL_CHROMIUM_bind_uniform_location +ANGLE_EXPORT void GL_APIENTRY BindUniformLocationCHROMIUM(GLuint program, + GLint location, + const GLchar *name); + +// GL_CHROMIUM_framebuffer_mixed_samples +ANGLE_EXPORT void GL_APIENTRY MatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat *matrix); +ANGLE_EXPORT void GL_APIENTRY MatrixLoadIdentityCHROMIUM(GLenum matrixMode); + +ANGLE_EXPORT void GL_APIENTRY CoverageModulationCHROMIUM(GLenum components); + +// GL_CHROMIUM_path_rendering +ANGLE_EXPORT GLuint GL_APIENTRY GenPathsCHROMIUM(GLsizei chromium); +ANGLE_EXPORT void GL_APIENTRY DeletePathsCHROMIUM(GLuint first, GLsizei range); +ANGLE_EXPORT GLboolean GL_APIENTRY IsPathCHROMIUM(GLuint path); +ANGLE_EXPORT void GL_APIENTRY PathCommandsCHROMIUM(GLuint path, + GLsizei numCommands, + const GLubyte *commands, + GLsizei numCoords, + GLenum coordType, + const void *coords); +ANGLE_EXPORT void GL_APIENTRY PathParameterfCHROMIUM(GLuint path, GLenum pname, GLfloat value); +ANGLE_EXPORT void GL_APIENTRY PathParameteriCHROMIUM(GLuint path, GLenum pname, GLint value); +ANGLE_EXPORT void GL_APIENTRY GetPathParameterfCHROMIUM(GLuint path, GLenum pname, GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY GetPathParameteriCHROMIUM(GLuint path, GLenum pname, GLint *value); +ANGLE_EXPORT void GL_APIENTRY PathStencilFuncCHROMIUM(GLenum func, GLint ref, GLuint mask); +ANGLE_EXPORT void GL_APIENTRY StencilFillPathCHROMIUM(GLuint path, GLenum fillMode, GLuint mask); +ANGLE_EXPORT void GL_APIENTRY StencilStrokePathCHROMIUM(GLuint path, GLint reference, GLuint mask); +ANGLE_EXPORT void GL_APIENTRY CoverFillPathCHROMIUM(GLuint path, GLenum coverMode); +ANGLE_EXPORT void GL_APIENTRY CoverStrokePathCHROMIUM(GLuint path, GLenum coverMode); +ANGLE_EXPORT void GL_APIENTRY StencilThenCoverFillPathCHROMIUM(GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode); +ANGLE_EXPORT void GL_APIENTRY StencilThenCoverStrokePathCHROMIUM(GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode); +ANGLE_EXPORT void GL_APIENTRY CoverFillPathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); +ANGLE_EXPORT void GL_APIENTRY CoverStrokePathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); +ANGLE_EXPORT void GL_APIENTRY StencilFillPathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBAse, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); +ANGLE_EXPORT void GL_APIENTRY StencilStrokePathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues); +ANGLE_EXPORT void GL_APIENTRY +StencilThenCoverFillPathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); +ANGLE_EXPORT void GL_APIENTRY +StencilThenCoverStrokePathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues); +ANGLE_EXPORT void GL_APIENTRY BindFragmentInputLocationCHROMIUM(GLuint program, + GLint location, + const GLchar *name); +ANGLE_EXPORT void GL_APIENTRY ProgramPathFragmentInputGenCHROMIUM(GLuint program, + GLint location, + GLenum genMode, + GLint components, + const GLfloat *coeffs); + +// GL_CHROMIUM_copy_texture +ANGLE_EXPORT void GL_APIENTRY CopyTextureCHROMIUM(GLuint sourceId, + GLint sourceLevel, + GLenum destTarget, + GLuint destId, + GLint destLevel, + GLint internalFormat, + GLenum destType, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha); + +ANGLE_EXPORT void GL_APIENTRY CopySubTextureCHROMIUM(GLuint sourceId, + GLint sourceLevel, + GLenum destTarget, + GLuint destId, + GLint destLevel, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLboolean unpackFlipY, + GLboolean unpackPremultiplyAlpha, + GLboolean unpackUnmultiplyAlpha); + +// GL_CHROMIUM_copy_compressed_texture +ANGLE_EXPORT void GL_APIENTRY CompressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId); + +// GL_ANGLE_request_extension +ANGLE_EXPORT void GL_APIENTRY RequestExtensionANGLE(const GLchar *name); + +// GL_ANGLE_robust_client_memory +ANGLE_EXPORT void GL_APIENTRY GetBooleanvRobustANGLE(GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLboolean *data); +ANGLE_EXPORT void GL_APIENTRY GetBufferParameterivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetFloatvRobustANGLE(GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *data); +ANGLE_EXPORT void GL_APIENTRY GetFramebufferAttachmentParameterivRobustANGLE(GLenum target, + GLenum attachment, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetIntegervRobustANGLE(GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *data); +ANGLE_EXPORT void GL_APIENTRY GetProgramivRobustANGLE(GLuint program, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetRenderbufferParameterivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetShaderivRobustANGLE(GLuint shader, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetTexParameterfvRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params); +ANGLE_EXPORT void GL_APIENTRY GetTexParameterivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetUniformfvRobustANGLE(GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLfloat *params); +ANGLE_EXPORT void GL_APIENTRY GetUniformivRobustANGLE(GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetVertexAttribfvRobustANGLE(GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params); +ANGLE_EXPORT void GL_APIENTRY GetVertexAttribivRobustANGLE(GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetVertexAttribPointervRobustANGLE(GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **pointer); +ANGLE_EXPORT void GL_APIENTRY ReadPixelsRobustANGLE(GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + GLsizei *columns, + GLsizei *rows, + void *pixels); +ANGLE_EXPORT void GL_APIENTRY TexImage2DRobustANGLE(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels); +ANGLE_EXPORT void GL_APIENTRY TexParameterfvRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + const GLfloat *params); +ANGLE_EXPORT void GL_APIENTRY TexParameterivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + const GLint *params); +ANGLE_EXPORT void GL_APIENTRY TexSubImage2DRobustANGLE(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels); + +ANGLE_EXPORT void GL_APIENTRY TexImage3DRobustANGLE(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels); +ANGLE_EXPORT void GL_APIENTRY TexSubImage3DRobustANGLE(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + GLsizei bufSize, + const void *pixels); + +ANGLE_EXPORT void GL_APIENTRY CompressedTexImage2DRobustANGLE(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + GLsizei dataSize, + const GLvoid *data); +ANGLE_EXPORT void GL_APIENTRY CompressedTexSubImage2DRobustANGLE(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + GLsizei dataSize, + const GLvoid *data); +ANGLE_EXPORT void GL_APIENTRY CompressedTexImage3DRobustANGLE(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + GLsizei dataSize, + const GLvoid *data); +ANGLE_EXPORT void GL_APIENTRY CompressedTexSubImage3DRobustANGLE(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + GLsizei dataSize, + const GLvoid *data); + +ANGLE_EXPORT void GL_APIENTRY +GetQueryivRobustANGLE(GLenum target, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetQueryObjectuivRobustANGLE(GLuint id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params); +ANGLE_EXPORT void GL_APIENTRY GetBufferPointervRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **params); +ANGLE_EXPORT void GL_APIENTRY GetIntegeri_vRobustANGLE(GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint *data); +ANGLE_EXPORT void GL_APIENTRY GetInternalformativRobustANGLE(GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetVertexAttribIivRobustANGLE(GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetVertexAttribIuivRobustANGLE(GLuint index, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params); +ANGLE_EXPORT void GL_APIENTRY GetUniformuivRobustANGLE(GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLuint *params); +ANGLE_EXPORT void GL_APIENTRY GetActiveUniformBlockivRobustANGLE(GLuint program, + GLuint uniformBlockIndex, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetInteger64vRobustANGLE(GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint64 *data); +ANGLE_EXPORT void GL_APIENTRY GetInteger64i_vRobustANGLE(GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLint64 *data); +ANGLE_EXPORT void GL_APIENTRY GetBufferParameteri64vRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint64 *params); +ANGLE_EXPORT void GL_APIENTRY SamplerParameterivRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + const GLint *param); +ANGLE_EXPORT void GL_APIENTRY SamplerParameterfvRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + const GLfloat *param); +ANGLE_EXPORT void GL_APIENTRY GetSamplerParameterivRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetSamplerParameterfvRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params); + +ANGLE_EXPORT void GL_APIENTRY GetFramebufferParameterivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetProgramInterfaceivRobustANGLE(GLuint program, + GLenum programInterface, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetBooleani_vRobustANGLE(GLenum target, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLboolean *data); +ANGLE_EXPORT void GL_APIENTRY GetMultisamplefvRobustANGLE(GLenum pname, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLfloat *val); +ANGLE_EXPORT void GL_APIENTRY GetTexLevelParameterivRobustANGLE(GLenum target, + GLint level, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetTexLevelParameterfvRobustANGLE(GLenum target, + GLint level, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLfloat *params); + +ANGLE_EXPORT void GL_APIENTRY GetPointervRobustANGLERobustANGLE(GLenum pname, + GLsizei bufSize, + GLsizei *length, + void **params); +ANGLE_EXPORT void GL_APIENTRY ReadnPixelsRobustANGLE(GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + GLsizei *length, + GLsizei *columns, + GLsizei *rows, + void *data); +ANGLE_EXPORT void GL_APIENTRY GetnUniformfvRobustANGLE(GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLfloat *params); +ANGLE_EXPORT void GL_APIENTRY GetnUniformivRobustANGLE(GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetnUniformuivRobustANGLE(GLuint program, + GLint location, + GLsizei bufSize, + GLsizei *length, + GLuint *params); +ANGLE_EXPORT void GL_APIENTRY TexParameterIivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + const GLint *params); +ANGLE_EXPORT void GL_APIENTRY TexParameterIuivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + const GLuint *params); +ANGLE_EXPORT void GL_APIENTRY GetTexParameterIivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetTexParameterIuivRobustANGLE(GLenum target, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params); +ANGLE_EXPORT void GL_APIENTRY SamplerParameterIivRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + const GLint *param); +ANGLE_EXPORT void GL_APIENTRY SamplerParameterIuivRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + const GLuint *param); +ANGLE_EXPORT void GL_APIENTRY GetSamplerParameterIivRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetSamplerParameterIuivRobustANGLE(GLuint sampler, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint *params); +ANGLE_EXPORT void GL_APIENTRY GetQueryObjectivRobustANGLE(GLuint id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetQueryObjecti64vRobustANGLE(GLuint id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLint64 *params); +ANGLE_EXPORT void GL_APIENTRY GetQueryObjectui64vRobustANGLE(GLuint id, + GLenum pname, + GLsizei bufSize, + GLsizei *length, + GLuint64 *params); + +// GL_ANGLE_multiview +ANGLE_EXPORT void GL_APIENTRY FramebufferTextureMultiviewLayeredANGLE(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint baseViewIndex, + GLsizei numViews); +ANGLE_EXPORT void GL_APIENTRY +FramebufferTextureMultiviewSideBySideANGLE(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLsizei numViews, + const GLint *viewportOffsets); +} // namespace gl + +#endif // LIBGLESV2_ENTRYPOINTGLES20EXT_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0.cpp b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0.cpp deleted file mode 100644 index 856129aa07..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0.cpp +++ /dev/null @@ -1,3057 +0,0 @@ -// -// Copyright(c) 2014 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// entry_points_gles_3_0.cpp : Implements the GLES 3.0 entry points. - -#include "libGLESv2/entry_points_gles_3_0.h" -#include "libGLESv2/entry_points_gles_2_0_ext.h" -#include "libGLESv2/global_state.h" - -#include "libANGLE/formatutils.h" -#include "libANGLE/Buffer.h" -#include "libANGLE/Context.h" -#include "libANGLE/Error.h" -#include "libANGLE/Fence.h" -#include "libANGLE/Framebuffer.h" -#include "libANGLE/Query.h" -#include "libANGLE/VertexArray.h" - -#include "libANGLE/validationES.h" -#include "libANGLE/validationES3.h" -#include "libANGLE/queryconversions.h" - -#include "common/debug.h" - -namespace gl -{ - -void GL_APIENTRY ReadBuffer(GLenum mode) -{ - EVENT("(GLenum mode = 0x%X)", mode); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!context->skipValidation() && !ValidateReadBuffer(context, mode)) - { - return; - } - - context->readBuffer(mode); - } -} - -void GL_APIENTRY DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices) -{ - EVENT("(GLenum mode = 0x%X, GLuint start = %u, GLuint end = %u, GLsizei count = %d, GLenum type = 0x%X, " - "const GLvoid* indices = 0x%0.8p)", mode, start, end, count, type, indices); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - IndexRange indexRange; - if (!ValidateDrawElements(context, mode, count, type, indices, 0, &indexRange)) - { - return; - } - if (indexRange.end > end || indexRange.start < start) - { - // GL spec says that behavior in this case is undefined - generating an error is fine. - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - // As long as index validation is done, it doesn't matter whether the context receives a drawElements or - // a drawRangeElements call - the GL back-end is free to choose to call drawRangeElements based on the - // validated index range. If index validation is removed, adding drawRangeElements to the context interface - // should be reconsidered. - Error error = - context->drawRangeElements(mode, start, end, count, type, indices, indexRange); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -void GL_APIENTRY TexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels) -{ - EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, " - "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLenum format = 0x%X, " - "GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)", - target, level, internalformat, width, height, depth, border, format, type, pixels); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - // validateES3TexImageFormat sets the error code if there is an error - if (!ValidateES3TexImage3DParameters(context, target, level, internalformat, false, false, - 0, 0, 0, width, height, depth, border, format, type, - pixels)) - { - return; - } - - Extents size(width, height, depth); - Texture *texture = context->getTargetTexture(target); - Error error = texture->setImage(context, target, level, internalformat, size, format, type, - reinterpret_cast(pixels)); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -void GL_APIENTRY TexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels) -{ - EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " - "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, " - "GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)", - target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - // validateES3TexImageFormat sets the error code if there is an error - if (!ValidateES3TexImage3DParameters(context, target, level, GL_NONE, false, true, xoffset, - yoffset, zoffset, width, height, depth, 0, format, - type, pixels)) - { - return; - } - - // Zero sized uploads are valid but no-ops - if (width == 0 || height == 0 || depth == 0) - { - return; - } - - Box area(xoffset, yoffset, zoffset, width, height, depth); - Texture *texture = context->getTargetTexture(target); - Error error = texture->setSubImage(context, target, level, area, format, type, - reinterpret_cast(pixels)); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -void GL_APIENTRY CopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) -{ - EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " - "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", - target, level, xoffset, yoffset, zoffset, x, y, width, height); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!context->skipValidation() && - !ValidateCopyTexSubImage3D(context, target, level, xoffset, yoffset, zoffset, x, y, - width, height)) - { - return; - } - - context->copyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height); - } -} - -void GL_APIENTRY CompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data) -{ - EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, " - "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, " - "const GLvoid* data = 0x%0.8p)", - target, level, internalformat, width, height, depth, border, imageSize, data); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateCompressedTexImage3D(context, target, level, internalformat, width, height, - depth, border, imageSize, data)) - { - return; - } - - Extents size(width, height, depth); - Texture *texture = context->getTargetTexture(target); - Error error = - texture->setCompressedImage(context, target, level, internalformat, size, imageSize, - reinterpret_cast(data)); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -void GL_APIENTRY CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data) -{ - EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " - "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, " - "GLenum format = 0x%X, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)", - target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - const InternalFormat &formatInfo = GetInternalFormatInfo(format); - if (imageSize < 0 || static_cast(imageSize) != formatInfo.computeBlockSize(GL_UNSIGNED_BYTE, width, height)) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - if (!data) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - // validateES3TexImageFormat sets the error code if there is an error - if (!ValidateES3TexImage3DParameters(context, target, level, GL_NONE, true, true, 0, 0, 0, - width, height, depth, 0, GL_NONE, GL_NONE, data)) - { - return; - } - - // Zero sized uploads are valid but no-ops - if (width == 0 || height == 0) - { - return; - } - - Box area(xoffset, yoffset, zoffset, width, height, depth); - Texture *texture = context->getTargetTexture(target); - Error error = - texture->setCompressedSubImage(context, target, level, area, format, imageSize, - reinterpret_cast(data)); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -void GL_APIENTRY GenQueries(GLsizei n, GLuint* ids) -{ - EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateGenQueries(context, n, ids)) - { - return; - } - - for (GLsizei i = 0; i < n; i++) - { - ids[i] = context->createQuery(); - } - } -} - -void GL_APIENTRY DeleteQueries(GLsizei n, const GLuint* ids) -{ - EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateDeleteQueries(context, n, ids)) - { - return; - } - - for (int i = 0; i < n; i++) - { - context->deleteQuery(ids[i]); - } - } -} - -GLboolean GL_APIENTRY IsQuery(GLuint id) -{ - EVENT("(GLuint id = %u)", id); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return GL_FALSE; - } - - return (context->getQuery(id, false, GL_NONE) != NULL) ? GL_TRUE : GL_FALSE; - } - - return GL_FALSE; -} - -void GL_APIENTRY BeginQuery(GLenum target, GLuint id) -{ - EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateBeginQuery(context, target, id)) - { - return; - } - - Error error = context->beginQuery(target, id); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -void GL_APIENTRY EndQuery(GLenum target) -{ - EVENT("(GLenum target = 0x%X)", target); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateEndQuery(context, target)) - { - return; - } - - Error error = context->endQuery(target); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -void GL_APIENTRY GetQueryiv(GLenum target, GLenum pname, GLint* params) -{ - EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateGetQueryiv(context, target, pname, params)) - { - return; - } - - context->getQueryiv(target, pname, params); - } -} - -void GL_APIENTRY GetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) -{ - EVENT("(GLuint id = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", id, pname, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateGetQueryObjectuiv(context, id, pname, params)) - { - return; - } - - Error error = context->getQueryObjectuiv(id, pname, params); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -GLboolean GL_APIENTRY UnmapBuffer(GLenum target) -{ - EVENT("(GLenum target = 0x%X)", target); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return GL_FALSE; - } - - return UnmapBufferOES(target); - } - - return GL_FALSE; -} - -void GL_APIENTRY GetBufferPointerv(GLenum target, GLenum pname, GLvoid** params) -{ - EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - GetBufferPointervOES(target, pname, params); - } -} - -void GL_APIENTRY DrawBuffers(GLsizei n, const GLenum* bufs) -{ - Context *context = GetValidGlobalContext(); - if (context) - { - if (!context->skipValidation() && !ValidateDrawBuffers(context, n, bufs)) - { - return; - } - - context->drawBuffers(n, bufs); - } -} - -void GL_APIENTRY UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) -{ - EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", - location, count, transpose, value); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2x3, location, count, transpose)) - { - return; - } - - Program *program = context->getState().getProgram(); - program->setUniformMatrix2x3fv(location, count, transpose, value); - } -} - -void GL_APIENTRY UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) -{ - EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", - location, count, transpose, value); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3x2, location, count, transpose)) - { - return; - } - - Program *program = context->getState().getProgram(); - program->setUniformMatrix3x2fv(location, count, transpose, value); - } -} - -void GL_APIENTRY UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) -{ - EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", - location, count, transpose, value); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2x4, location, count, transpose)) - { - return; - } - - Program *program = context->getState().getProgram(); - program->setUniformMatrix2x4fv(location, count, transpose, value); - } -} - -void GL_APIENTRY UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) -{ - EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", - location, count, transpose, value); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4x2, location, count, transpose)) - { - return; - } - - Program *program = context->getState().getProgram(); - program->setUniformMatrix4x2fv(location, count, transpose, value); - } -} - -void GL_APIENTRY UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) -{ - EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", - location, count, transpose, value); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3x4, location, count, transpose)) - { - return; - } - - Program *program = context->getState().getProgram(); - program->setUniformMatrix3x4fv(location, count, transpose, value); - } -} - -void GL_APIENTRY UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) -{ - EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", - location, count, transpose, value); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4x3, location, count, transpose)) - { - return; - } - - Program *program = context->getState().getProgram(); - program->setUniformMatrix4x3fv(location, count, transpose, value); - } -} - -void GL_APIENTRY BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) -{ - EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, GLint dstX0 = %d, " - "GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, GLbitfield mask = 0x%X, GLenum filter = 0x%X)", - srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!context->skipValidation() && - !ValidateBlitFramebuffer(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, - dstY1, mask, filter)) - { - return; - } - - context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, - filter); - } -} - -void GL_APIENTRY RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) -{ - EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", - target, samples, internalformat, width, height); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (!ValidateES3RenderbufferStorageParameters(context, target, samples, internalformat, width, height)) - { - return; - } - - Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer(); - renderbuffer->setStorageMultisample(samples, internalformat, width, height); - } -} - -void GL_APIENTRY FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) -{ - EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLuint texture = %u, GLint level = %d, GLint layer = %d)", - target, attachment, texture, level, layer); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!context->skipValidation() && - !ValidateFramebufferTextureLayer(context, target, attachment, texture, level, layer)) - { - return; - } - - context->framebufferTextureLayer(target, attachment, texture, level, layer); - } -} - -GLvoid *GL_APIENTRY MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) -{ - EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = 0x%X)", - target, offset, length, access); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return NULL; - } - - return MapBufferRangeEXT(target, offset, length, access); - } - - return NULL; -} - -void GL_APIENTRY FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) -{ - EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - FlushMappedBufferRangeEXT(target, offset, length); - } -} - -void GL_APIENTRY BindVertexArray(GLuint array) -{ - EVENT("(GLuint array = %u)", array); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateBindVertexArray(context, array)) - { - return; - } - - context->bindVertexArray(array); - } -} - -void GL_APIENTRY DeleteVertexArrays(GLsizei n, const GLuint* arrays) -{ - EVENT("(GLsizei n = %d, const GLuint* arrays = 0x%0.8p)", n, arrays); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateDeleteVertexArrays(context, n)) - { - return; - } - - for (int arrayIndex = 0; arrayIndex < n; arrayIndex++) - { - if (arrays[arrayIndex] != 0) - { - context->deleteVertexArray(arrays[arrayIndex]); - } - } - } -} - -void GL_APIENTRY GenVertexArrays(GLsizei n, GLuint* arrays) -{ - EVENT("(GLsizei n = %d, GLuint* arrays = 0x%0.8p)", n, arrays); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateGenVertexArrays(context, n)) - { - return; - } - - for (int arrayIndex = 0; arrayIndex < n; arrayIndex++) - { - arrays[arrayIndex] = context->createVertexArray(); - } - } -} - -GLboolean GL_APIENTRY IsVertexArray(GLuint array) -{ - EVENT("(GLuint array = %u)", array); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateIsVertexArray(context)) - { - return GL_FALSE; - } - - if (array == 0) - { - return GL_FALSE; - } - - VertexArray *vao = context->getVertexArray(array); - - return (vao != NULL ? GL_TRUE : GL_FALSE); - } - - return GL_FALSE; -} - -void GL_APIENTRY GetIntegeri_v(GLenum target, GLuint index, GLint* data) -{ - EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint* data = 0x%0.8p)", - target, index, data); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - const Caps &caps = context->getCaps(); - switch (target) - { - case GL_TRANSFORM_FEEDBACK_BUFFER_START: - case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: - case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: - if (index >= caps.maxTransformFeedbackSeparateAttributes) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - break; - - case GL_UNIFORM_BUFFER_START: - case GL_UNIFORM_BUFFER_SIZE: - case GL_UNIFORM_BUFFER_BINDING: - if (index >= caps.maxCombinedUniformBlocks) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - if (!(context->getIndexedIntegerv(target, index, data))) - { - GLenum nativeType; - unsigned int numParams = 0; - if (!context->getIndexedQueryParameterInfo(target, &nativeType, &numParams)) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - if (numParams == 0) - { - return; // it is known that pname is valid, but there are no parameters to return - } - - if (nativeType == GL_INT_64_ANGLEX) - { - GLint64 minIntValue = static_cast(std::numeric_limits::min()); - GLint64 maxIntValue = static_cast(std::numeric_limits::max()); - GLint64 *int64Params = new GLint64[numParams]; - - context->getIndexedInteger64v(target, index, int64Params); - - for (unsigned int i = 0; i < numParams; ++i) - { - GLint64 clampedValue = std::max(std::min(int64Params[i], maxIntValue), minIntValue); - data[i] = static_cast(clampedValue); - } - - delete [] int64Params; - } - else - { - UNREACHABLE(); - } - } - } -} - -void GL_APIENTRY BeginTransformFeedback(GLenum primitiveMode) -{ - EVENT("(GLenum primitiveMode = 0x%X)", primitiveMode); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - switch (primitiveMode) - { - case GL_TRIANGLES: - case GL_LINES: - case GL_POINTS: - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback(); - ASSERT(transformFeedback != NULL); - - if (transformFeedback->isActive()) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (transformFeedback->isPaused()) - { - transformFeedback->resume(); - } - else - { - transformFeedback->begin(primitiveMode); - } - } -} - -void GL_APIENTRY EndTransformFeedback(void) -{ - EVENT("(void)"); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback(); - ASSERT(transformFeedback != NULL); - - if (!transformFeedback->isActive()) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - transformFeedback->end(); - } -} - -void GL_APIENTRY BindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) -{ - EVENT("(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u, GLintptr offset = %d, GLsizeiptr size = %d)", - target, index, buffer, offset, size); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - const Caps &caps = context->getCaps(); - switch (target) - { - case GL_TRANSFORM_FEEDBACK_BUFFER: - if (index >= caps.maxTransformFeedbackSeparateAttributes) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - break; - - case GL_UNIFORM_BUFFER: - if (index >= caps.maxUniformBufferBindings) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - if (buffer != 0 && size <= 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - switch (target) - { - case GL_TRANSFORM_FEEDBACK_BUFFER: - { - // size and offset must be a multiple of 4 - if (buffer != 0 && ((offset % 4) != 0 || (size % 4) != 0)) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - // Cannot bind a transform feedback buffer if the current transform feedback is active (3.0.4 pg 91 section 2.15.2) - TransformFeedback *curTransformFeedback = context->getState().getCurrentTransformFeedback(); - if (curTransformFeedback && curTransformFeedback->isActive()) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - context->bindIndexedTransformFeedbackBuffer(buffer, index, offset, size); - context->bindGenericTransformFeedbackBuffer(buffer); - break; - } - - case GL_UNIFORM_BUFFER: - - // it is an error to bind an offset not a multiple of the alignment - if (buffer != 0 && (offset % caps.uniformBufferOffsetAlignment) != 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - context->bindIndexedUniformBuffer(buffer, index, offset, size); - context->bindGenericUniformBuffer(buffer); - break; - - default: - UNREACHABLE(); - } - } -} - -void GL_APIENTRY BindBufferBase(GLenum target, GLuint index, GLuint buffer) -{ - EVENT("(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u)", - target, index, buffer); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - const Caps &caps = context->getCaps(); - switch (target) - { - case GL_TRANSFORM_FEEDBACK_BUFFER: - if (index >= caps.maxTransformFeedbackSeparateAttributes) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - break; - - case GL_UNIFORM_BUFFER: - if (index >= caps.maxUniformBufferBindings) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - switch (target) - { - case GL_TRANSFORM_FEEDBACK_BUFFER: - { - // Cannot bind a transform feedback buffer if the current transform feedback is active (3.0.4 pg 91 section 2.15.2) - TransformFeedback *curTransformFeedback = context->getState().getCurrentTransformFeedback(); - if (curTransformFeedback && curTransformFeedback->isActive()) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - context->bindIndexedTransformFeedbackBuffer(buffer, index, 0, 0); - context->bindGenericTransformFeedbackBuffer(buffer); - break; - } - case GL_UNIFORM_BUFFER: - context->bindIndexedUniformBuffer(buffer, index, 0, 0); - context->bindGenericUniformBuffer(buffer); - break; - - default: - UNREACHABLE(); - } - } -} - -void GL_APIENTRY TransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode) -{ - EVENT("(GLuint program = %u, GLsizei count = %d, const GLchar* const* varyings = 0x%0.8p, GLenum bufferMode = 0x%X)", - program, count, varyings, bufferMode); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (count < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - const Caps &caps = context->getCaps(); - switch (bufferMode) - { - case GL_INTERLEAVED_ATTRIBS: - break; - case GL_SEPARATE_ATTRIBS: - if (static_cast(count) > caps.maxTransformFeedbackSeparateAttributes) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - break; - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - Program *programObject = GetValidProgram(context, program); - if (!programObject) - { - return; - } - - programObject->setTransformFeedbackVaryings(count, varyings, bufferMode); - } -} - -void GL_APIENTRY GetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name) -{ - EVENT("(GLuint program = %u, GLuint index = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, " - "GLsizei* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)", - program, index, bufSize, length, size, type, name); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (bufSize < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - Program *programObject = GetValidProgram(context, program); - if (!programObject) - { - return; - } - - if (index >= static_cast(programObject->getTransformFeedbackVaryingCount())) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name); - } -} - -void GL_APIENTRY VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) -{ - EVENT("(GLuint index = %u, GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid* pointer = 0x%0.8p)", - index, size, type, stride, pointer); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (index >= MAX_VERTEX_ATTRIBS) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - if (size < 1 || size > 4) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - switch (type) - { - case GL_BYTE: - case GL_UNSIGNED_BYTE: - case GL_SHORT: - case GL_UNSIGNED_SHORT: - case GL_INT: - case GL_UNSIGNED_INT: - case GL_INT_2_10_10_10_REV: - case GL_UNSIGNED_INT_2_10_10_10_REV: - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - if (stride < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - if ((type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV) && size != 4) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - // [OpenGL ES 3.0.2] Section 2.8 page 24: - // An INVALID_OPERATION error is generated when a non-zero vertex array object - // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point, - // and the pointer argument is not NULL. - if (context->getState().getVertexArray()->id() != 0 && context->getState().getArrayBufferId() == 0 && pointer != NULL) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - context->getState().setVertexAttribState(index, context->getState().getTargetBuffer(GL_ARRAY_BUFFER), size, type, false, true, - stride, pointer); - } -} - -void GL_APIENTRY GetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) -{ - EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", - index, pname, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (index >= MAX_VERTEX_ATTRIBS) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - if (!ValidateGetVertexAttribParameters(context, pname)) - { - return; - } - - if (pname == GL_CURRENT_VERTEX_ATTRIB) - { - const VertexAttribCurrentValueData ¤tValueData = context->getState().getVertexAttribCurrentValue(index); - for (int i = 0; i < 4; ++i) - { - params[i] = currentValueData.IntValues[i]; - } - } - else - { - const VertexAttribute &attribState = context->getState().getVertexArray()->getVertexAttribute(index); - *params = QuerySingleVertexAttributeParameter(attribState, pname); - } - } -} - -void GL_APIENTRY GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params) -{ - EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLuint* params = 0x%0.8p)", - index, pname, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (index >= MAX_VERTEX_ATTRIBS) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - if (!ValidateGetVertexAttribParameters(context, pname)) - { - return; - } - - if (pname == GL_CURRENT_VERTEX_ATTRIB) - { - const VertexAttribCurrentValueData ¤tValueData = context->getState().getVertexAttribCurrentValue(index); - for (int i = 0; i < 4; ++i) - { - params[i] = currentValueData.UnsignedIntValues[i]; - } - } - else - { - const VertexAttribute &attribState = context->getState().getVertexArray()->getVertexAttribute(index); - *params = QuerySingleVertexAttributeParameter(attribState, pname); - } - } -} - -void GL_APIENTRY VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w) -{ - EVENT("(GLuint index = %u, GLint x = %d, GLint y = %d, GLint z = %d, GLint w = %d)", - index, x, y, z, w); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (index >= MAX_VERTEX_ATTRIBS) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - GLint vals[4] = { x, y, z, w }; - context->getState().setVertexAttribi(index, vals); - } -} - -void GL_APIENTRY VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) -{ - EVENT("(GLuint index = %u, GLuint x = %u, GLuint y = %u, GLuint z = %u, GLuint w = %u)", - index, x, y, z, w); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (index >= MAX_VERTEX_ATTRIBS) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - GLuint vals[4] = { x, y, z, w }; - context->getState().setVertexAttribu(index, vals); - } -} - -void GL_APIENTRY VertexAttribI4iv(GLuint index, const GLint* v) -{ - EVENT("(GLuint index = %u, const GLint* v = 0x%0.8p)", index, v); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (index >= MAX_VERTEX_ATTRIBS) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - context->getState().setVertexAttribi(index, v); - } -} - -void GL_APIENTRY VertexAttribI4uiv(GLuint index, const GLuint* v) -{ - EVENT("(GLuint index = %u, const GLuint* v = 0x%0.8p)", index, v); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (index >= MAX_VERTEX_ATTRIBS) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - context->getState().setVertexAttribu(index, v); - } -} - -void GL_APIENTRY GetUniformuiv(GLuint program, GLint location, GLuint* params) -{ - EVENT("(GLuint program = %u, GLint location = %d, GLuint* params = 0x%0.8p)", - program, location, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateGetUniformuiv(context, program, location, params)) - { - return; - } - - Program *programObject = context->getProgram(program); - ASSERT(programObject); - - programObject->getUniformuiv(location, params); - } -} - -GLint GL_APIENTRY GetFragDataLocation(GLuint program, const GLchar *name) -{ - EVENT("(GLuint program = %u, const GLchar *name = 0x%0.8p)", - program, name); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return -1; - } - - if (program == 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return -1; - } - - Program *programObject = context->getProgram(program); - - if (!programObject || !programObject->isLinked()) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return -1; - } - - return programObject->getFragDataLocation(name); - } - - return 0; -} - -void GL_APIENTRY Uniform1ui(GLint location, GLuint v0) -{ - Uniform1uiv(location, 1, &v0); -} - -void GL_APIENTRY Uniform2ui(GLint location, GLuint v0, GLuint v1) -{ - const GLuint xy[] = { v0, v1 }; - Uniform2uiv(location, 1, xy); -} - -void GL_APIENTRY Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) -{ - const GLuint xyz[] = { v0, v1, v2 }; - Uniform3uiv(location, 1, xyz); -} - -void GL_APIENTRY Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) -{ - const GLuint xyzw[] = { v0, v1, v2, v3 }; - Uniform4uiv(location, 1, xyzw); -} - -void GL_APIENTRY Uniform1uiv(GLint location, GLsizei count, const GLuint* value) -{ - EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)", - location, count, value); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateUniform(context, GL_UNSIGNED_INT, location, count)) - { - return; - } - - Program *program = context->getState().getProgram(); - program->setUniform1uiv(location, count, value); - } -} - -void GL_APIENTRY Uniform2uiv(GLint location, GLsizei count, const GLuint* value) -{ - EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)", - location, count, value); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC2, location, count)) - { - return; - } - - Program *program = context->getState().getProgram(); - program->setUniform2uiv(location, count, value); - } -} - -void GL_APIENTRY Uniform3uiv(GLint location, GLsizei count, const GLuint* value) -{ - EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value)", - location, count, value); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC3, location, count)) - { - return; - } - - Program *program = context->getState().getProgram(); - program->setUniform3uiv(location, count, value); - } -} - -void GL_APIENTRY Uniform4uiv(GLint location, GLsizei count, const GLuint* value) -{ - EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)", - location, count, value); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC4, location, count)) - { - return; - } - - Program *program = context->getState().getProgram(); - program->setUniform4uiv(location, count, value); - } -} - -void GL_APIENTRY ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value) -{ - EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLint* value = 0x%0.8p)", - buffer, drawbuffer, value); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!context->skipValidation() && - !ValidateClearBufferiv(context, buffer, drawbuffer, value)) - { - return; - } - - context->clearBufferiv(buffer, drawbuffer, value); - } -} - -void GL_APIENTRY ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value) -{ - EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLuint* value = 0x%0.8p)", - buffer, drawbuffer, value); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!context->skipValidation() && - !ValidateClearBufferuiv(context, buffer, drawbuffer, value)) - { - return; - } - - context->clearBufferuiv(buffer, drawbuffer, value); - } -} - -void GL_APIENTRY ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value) -{ - EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLfloat* value = 0x%0.8p)", - buffer, drawbuffer, value); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!context->skipValidation() && - !ValidateClearBufferfv(context, buffer, drawbuffer, value)) - { - return; - } - - context->clearBufferfv(buffer, drawbuffer, value); - } -} - -void GL_APIENTRY ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) -{ - EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, GLfloat depth, GLint stencil = %d)", - buffer, drawbuffer, depth, stencil); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!context->skipValidation() && - !ValidateClearBufferfi(context, buffer, drawbuffer, depth, stencil)) - { - return; - } - - context->clearBufferfi(buffer, drawbuffer, depth, stencil); - } -} - -const GLubyte *GL_APIENTRY GetStringi(GLenum name, GLuint index) -{ - EVENT("(GLenum name = 0x%X, GLuint index = %u)", name, index); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return NULL; - } - - if (name != GL_EXTENSIONS) - { - context->recordError(Error(GL_INVALID_ENUM)); - return NULL; - } - - if (index >= context->getExtensionStringCount()) - { - context->recordError(Error(GL_INVALID_VALUE)); - return NULL; - } - - return reinterpret_cast(context->getExtensionString(index).c_str()); - } - - return NULL; -} - -void GL_APIENTRY CopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) -{ - EVENT("(GLenum readTarget = 0x%X, GLenum writeTarget = 0x%X, GLintptr readOffset = %d, GLintptr writeOffset = %d, GLsizeiptr size = %d)", - readTarget, writeTarget, readOffset, writeOffset, size); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (!ValidBufferTarget(context, readTarget) || !ValidBufferTarget(context, writeTarget)) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - Buffer *readBuffer = context->getState().getTargetBuffer(readTarget); - Buffer *writeBuffer = context->getState().getTargetBuffer(writeTarget); - - if (!readBuffer || !writeBuffer) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - // Verify that readBuffer and writeBuffer are not currently mapped - if (readBuffer->isMapped() || writeBuffer->isMapped()) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (readOffset < 0 || writeOffset < 0 || size < 0 || - static_cast(readOffset + size) > readBuffer->getSize() || - static_cast(writeOffset + size) > writeBuffer->getSize()) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - if (readBuffer == writeBuffer && std::abs(readOffset - writeOffset) < size) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - // if size is zero, the copy is a successful no-op - if (size > 0) - { - Error error = writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size); - if (error.isError()) - { - context->recordError(error); - return; - } - } - } -} - -void GL_APIENTRY GetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices) -{ - EVENT("(GLuint program = %u, GLsizei uniformCount = %d, const GLchar* const* uniformNames = 0x%0.8p, GLuint* uniformIndices = 0x%0.8p)", - program, uniformCount, uniformNames, uniformIndices); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (uniformCount < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - Program *programObject = GetValidProgram(context, program); - - if (!programObject) - { - return; - } - - if (!programObject->isLinked()) - { - for (int uniformId = 0; uniformId < uniformCount; uniformId++) - { - uniformIndices[uniformId] = GL_INVALID_INDEX; - } - } - else - { - for (int uniformId = 0; uniformId < uniformCount; uniformId++) - { - uniformIndices[uniformId] = programObject->getUniformIndex(uniformNames[uniformId]); - } - } - } -} - -void GL_APIENTRY GetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params) -{ - EVENT("(GLuint program = %u, GLsizei uniformCount = %d, const GLuint* uniformIndices = 0x%0.8p, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", - program, uniformCount, uniformIndices, pname, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (uniformCount < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - Program *programObject = GetValidProgram(context, program); - - if (!programObject) - { - return; - } - - switch (pname) - { - case GL_UNIFORM_TYPE: - case GL_UNIFORM_SIZE: - case GL_UNIFORM_NAME_LENGTH: - case GL_UNIFORM_BLOCK_INDEX: - case GL_UNIFORM_OFFSET: - case GL_UNIFORM_ARRAY_STRIDE: - case GL_UNIFORM_MATRIX_STRIDE: - case GL_UNIFORM_IS_ROW_MAJOR: - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - if (uniformCount > programObject->getActiveUniformCount()) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - for (int uniformId = 0; uniformId < uniformCount; uniformId++) - { - const GLuint index = uniformIndices[uniformId]; - - if (index >= static_cast(programObject->getActiveUniformCount())) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - } - - for (int uniformId = 0; uniformId < uniformCount; uniformId++) - { - const GLuint index = uniformIndices[uniformId]; - params[uniformId] = programObject->getActiveUniformi(index, pname); - } - } -} - -GLuint GL_APIENTRY GetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName) -{ - EVENT("(GLuint program = %u, const GLchar* uniformBlockName = 0x%0.8p)", program, uniformBlockName); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return GL_INVALID_INDEX; - } - - Program *programObject = GetValidProgram(context, program); - if (!programObject) - { - return GL_INVALID_INDEX; - } - - return programObject->getUniformBlockIndex(uniformBlockName); - } - - return 0; -} - -void GL_APIENTRY GetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) -{ - EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", - program, uniformBlockIndex, pname, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - Program *programObject = GetValidProgram(context, program); - - if (!programObject) - { - return; - } - - if (uniformBlockIndex >= programObject->getActiveUniformBlockCount()) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - switch (pname) - { - case GL_UNIFORM_BLOCK_BINDING: - *params = static_cast(programObject->getUniformBlockBinding(uniformBlockIndex)); - break; - - case GL_UNIFORM_BLOCK_DATA_SIZE: - case GL_UNIFORM_BLOCK_NAME_LENGTH: - case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: - case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: - case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: - case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: - programObject->getActiveUniformBlockiv(uniformBlockIndex, pname, params); - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - } -} - -void GL_APIENTRY GetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName) -{ - EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLchar* uniformBlockName = 0x%0.8p)", - program, uniformBlockIndex, bufSize, length, uniformBlockName); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - Program *programObject = GetValidProgram(context, program); - - if (!programObject) - { - return; - } - - if (uniformBlockIndex >= programObject->getActiveUniformBlockCount()) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName); - } -} - -void GL_APIENTRY UniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) -{ - EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLuint uniformBlockBinding = %u)", - program, uniformBlockIndex, uniformBlockBinding); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (uniformBlockBinding >= context->getCaps().maxUniformBufferBindings) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - Program *programObject = GetValidProgram(context, program); - - if (!programObject) - { - return; - } - - // if never linked, there won't be any uniform blocks - if (uniformBlockIndex >= programObject->getActiveUniformBlockCount()) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding); - } -} - -void GL_APIENTRY DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount) -{ - EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)", - mode, first, count, instanceCount); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (!ValidateDrawArraysInstanced(context, mode, first, count, instanceCount)) - { - return; - } - - Error error = context->drawArraysInstanced(mode, first, count, instanceCount); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -void GL_APIENTRY DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount) -{ - EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei instanceCount = %d)", - mode, count, type, indices, instanceCount); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - IndexRange indexRange; - if (!ValidateDrawElementsInstanced(context, mode, count, type, indices, instanceCount, &indexRange)) - { - return; - } - - Error error = - context->drawElementsInstanced(mode, count, type, indices, instanceCount, indexRange); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -GLsync GL_APIENTRY FenceSync_(GLenum condition, GLbitfield flags) -{ - EVENT("(GLenum condition = 0x%X, GLbitfield flags = 0x%X)", condition, flags); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return 0; - } - - if (condition != GL_SYNC_GPU_COMMANDS_COMPLETE) - { - context->recordError(Error(GL_INVALID_ENUM)); - return 0; - } - - if (flags != 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return 0; - } - - GLsync fenceSync = context->createFenceSync(); - - FenceSync *fenceSyncObject = context->getFenceSync(fenceSync); - Error error = fenceSyncObject->set(condition, flags); - if (error.isError()) - { - context->deleteFenceSync(fenceSync); - context->recordError(error); - return NULL; - } - - return fenceSync; - } - - return NULL; -} - -GLboolean GL_APIENTRY IsSync(GLsync sync) -{ - EVENT("(GLsync sync = 0x%0.8p)", sync); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return GL_FALSE; - } - - return (context->getFenceSync(sync) != NULL); - } - - return GL_FALSE; -} - -void GL_APIENTRY DeleteSync(GLsync sync) -{ - EVENT("(GLsync sync = 0x%0.8p)", sync); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (sync != static_cast(0) && !context->getFenceSync(sync)) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - context->deleteFenceSync(sync); - } -} - -GLenum GL_APIENTRY ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) -{ - EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)", - sync, flags, timeout); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return GL_WAIT_FAILED; - } - - if ((flags & ~(GL_SYNC_FLUSH_COMMANDS_BIT)) != 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return GL_WAIT_FAILED; - } - - FenceSync *fenceSync = context->getFenceSync(sync); - - if (!fenceSync) - { - context->recordError(Error(GL_INVALID_VALUE)); - return GL_WAIT_FAILED; - } - - GLenum result = GL_WAIT_FAILED; - Error error = fenceSync->clientWait(flags, timeout, &result); - if (error.isError()) - { - context->recordError(error); - return GL_WAIT_FAILED; - } - - return result; - } - - return GL_FALSE; -} - -void GL_APIENTRY WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) -{ - EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)", - sync, flags, timeout); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (flags != 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - if (timeout != GL_TIMEOUT_IGNORED) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - FenceSync *fenceSync = context->getFenceSync(sync); - - if (!fenceSync) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - Error error = fenceSync->serverWait(flags, timeout); - if (error.isError()) - { - context->recordError(error); - } - } -} - -void GL_APIENTRY GetInteger64v(GLenum pname, GLint64* params) -{ - EVENT("(GLenum pname = 0x%X, GLint64* params = 0x%0.8p)", - pname, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - GLenum nativeType; - unsigned int numParams = 0; - if (!ValidateStateQuery(context, pname, &nativeType, &numParams)) - { - return; - } - - if (nativeType == GL_INT_64_ANGLEX) - { - context->getInteger64v(pname, params); - } - else - { - CastStateValues(context, nativeType, pname, numParams, params); - } - } -} - -void GL_APIENTRY GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values) -{ - EVENT("(GLsync sync = 0x%0.8p, GLenum pname = 0x%X, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLint* values = 0x%0.8p)", - sync, pname, bufSize, length, values); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (bufSize < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - FenceSync *fenceSync = context->getFenceSync(sync); - - if (!fenceSync) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - switch (pname) - { - case GL_OBJECT_TYPE: values[0] = static_cast(GL_SYNC_FENCE); break; - case GL_SYNC_CONDITION: values[0] = static_cast(fenceSync->getCondition()); break; - case GL_SYNC_FLAGS: values[0] = static_cast(fenceSync->getFlags()); break; - - case GL_SYNC_STATUS: - { - Error error = fenceSync->getStatus(values); - if (error.isError()) - { - context->recordError(error); - return; - } - break; - } - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - } -} - -void GL_APIENTRY GetInteger64i_v(GLenum target, GLuint index, GLint64* data) -{ - EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint64* data = 0x%0.8p)", - target, index, data); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - const Caps &caps = context->getCaps(); - switch (target) - { - case GL_TRANSFORM_FEEDBACK_BUFFER_START: - case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: - case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: - if (index >= caps.maxTransformFeedbackSeparateAttributes) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - break; - - case GL_UNIFORM_BUFFER_START: - case GL_UNIFORM_BUFFER_SIZE: - case GL_UNIFORM_BUFFER_BINDING: - if (index >= caps.maxUniformBufferBindings) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - if (!(context->getIndexedInteger64v(target, index, data))) - { - GLenum nativeType; - unsigned int numParams = 0; - if (!context->getIndexedQueryParameterInfo(target, &nativeType, &numParams)) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - if (numParams == 0) - return; // it is known that pname is valid, but there are no parameters to return - - if (nativeType == GL_INT) - { - GLint *intParams = new GLint[numParams]; - - context->getIndexedIntegerv(target, index, intParams); - - for (unsigned int i = 0; i < numParams; ++i) - { - data[i] = static_cast(intParams[i]); - } - - delete [] intParams; - } - else - { - UNREACHABLE(); - } - } - } -} - -void GL_APIENTRY GetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params) -{ - EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint64* params = 0x%0.8p)", - target, pname, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (!ValidBufferTarget(context, target)) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - if (!ValidBufferParameter(context, pname)) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - Buffer *buffer = context->getState().getTargetBuffer(target); - - if (!buffer) - { - // A null buffer means that "0" is bound to the requested buffer target - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - switch (pname) - { - case GL_BUFFER_USAGE: - *params = static_cast(buffer->getUsage()); - break; - case GL_BUFFER_SIZE: - *params = buffer->getSize(); - break; - case GL_BUFFER_ACCESS_FLAGS: - *params = static_cast(buffer->getAccessFlags()); - break; - case GL_BUFFER_MAPPED: - *params = static_cast(buffer->isMapped()); - break; - case GL_BUFFER_MAP_OFFSET: - *params = buffer->getMapOffset(); - break; - case GL_BUFFER_MAP_LENGTH: - *params = buffer->getMapLength(); - break; - default: UNREACHABLE(); break; - } - } -} - -void GL_APIENTRY GenSamplers(GLsizei count, GLuint* samplers) -{ - EVENT("(GLsizei count = %d, GLuint* samplers = 0x%0.8p)", count, samplers); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (count < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - for (int i = 0; i < count; i++) - { - samplers[i] = context->createSampler(); - } - } -} - -void GL_APIENTRY DeleteSamplers(GLsizei count, const GLuint* samplers) -{ - EVENT("(GLsizei count = %d, const GLuint* samplers = 0x%0.8p)", count, samplers); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (count < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - for (int i = 0; i < count; i++) - { - context->deleteSampler(samplers[i]); - } - } -} - -GLboolean GL_APIENTRY IsSampler(GLuint sampler) -{ - EVENT("(GLuint sampler = %u)", sampler); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return GL_FALSE; - } - - return context->isSampler(sampler); - } - - return GL_FALSE; -} - -void GL_APIENTRY BindSampler(GLuint unit, GLuint sampler) -{ - EVENT("(GLuint unit = %u, GLuint sampler = %u)", unit, sampler); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (sampler != 0 && !context->isSampler(sampler)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (unit >= context->getCaps().maxCombinedTextureImageUnits) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - context->bindSampler(unit, sampler); - } -} - -void GL_APIENTRY SamplerParameteri(GLuint sampler, GLenum pname, GLint param) -{ - EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint param = %d)", sampler, pname, param); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (!ValidateSamplerObjectParameter(context, pname)) - { - return; - } - - if (!ValidateTexParamParameters(context, pname, param)) - { - return; - } - - if (!context->isSampler(sampler)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - context->samplerParameteri(sampler, pname, param); - } -} - -void GL_APIENTRY SamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param) -{ - SamplerParameteri(sampler, pname, *param); -} - -void GL_APIENTRY SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) -{ - EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLfloat param = %g)", sampler, pname, param); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (!ValidateSamplerObjectParameter(context, pname)) - { - return; - } - - if (!ValidateTexParamParameters(context, pname, static_cast(param))) - { - return; - } - - if (!context->isSampler(sampler)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - context->samplerParameterf(sampler, pname, param); - } -} - -void GL_APIENTRY SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param) -{ - SamplerParameterf(sampler, pname, *param); -} - -void GL_APIENTRY GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params) -{ - EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", sampler, pname, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (!ValidateSamplerObjectParameter(context, pname)) - { - return; - } - - if (!context->isSampler(sampler)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - *params = context->getSamplerParameteri(sampler, pname); - } -} - -void GL_APIENTRY GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params) -{ - EVENT("(GLuint sample = %ur, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", sampler, pname, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (!ValidateSamplerObjectParameter(context, pname)) - { - return; - } - - if (!context->isSampler(sampler)) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - *params = context->getSamplerParameterf(sampler, pname); - } -} - -void GL_APIENTRY VertexAttribDivisor(GLuint index, GLuint divisor) -{ - EVENT("(GLuint index = %u, GLuint divisor = %u)", index, divisor); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (index >= MAX_VERTEX_ATTRIBS) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - context->setVertexAttribDivisor(index, divisor); - } -} - -void GL_APIENTRY BindTransformFeedback(GLenum target, GLuint id) -{ - EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - switch (target) - { - case GL_TRANSFORM_FEEDBACK: - { - // Cannot bind a transform feedback object if the current one is started and not paused (3.0.2 pg 85 section 2.14.1) - TransformFeedback *curTransformFeedback = context->getState().getCurrentTransformFeedback(); - if (curTransformFeedback && curTransformFeedback->isActive() && !curTransformFeedback->isPaused()) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - // Cannot bind a transform feedback object that does not exist (3.0.2 pg 85 section 2.14.1) - if (!context->isTransformFeedbackGenerated(id)) - { - context->recordError( - Error(GL_INVALID_OPERATION, - "Cannot bind a transform feedback object that does not exist.")); - return; - } - - context->bindTransformFeedback(id); - } - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - } -} - -void GL_APIENTRY DeleteTransformFeedbacks(GLsizei n, const GLuint* ids) -{ - EVENT("(GLsizei n = %d, const GLuint* ids = 0x%0.8p)", n, ids); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - for (int i = 0; i < n; i++) - { - context->deleteTransformFeedback(ids[i]); - } - } -} - -void GL_APIENTRY GenTransformFeedbacks(GLsizei n, GLuint* ids) -{ - EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - for (int i = 0; i < n; i++) - { - ids[i] = context->createTransformFeedback(); - } - } -} - -GLboolean GL_APIENTRY IsTransformFeedback(GLuint id) -{ - EVENT("(GLuint id = %u)", id); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return GL_FALSE; - } - - if (id == 0) - { - // The 3.0.4 spec [section 6.1.11] states that if ID is zero, IsTransformFeedback - // returns FALSE - return GL_FALSE; - } - - const TransformFeedback *transformFeedback = context->getTransformFeedback(id); - return ((transformFeedback != nullptr) ? GL_TRUE : GL_FALSE); - } - - return GL_FALSE; -} - -void GL_APIENTRY PauseTransformFeedback(void) -{ - EVENT("(void)"); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback(); - ASSERT(transformFeedback != NULL); - - // Current transform feedback must be active and not paused in order to pause (3.0.2 pg 86) - if (!transformFeedback->isActive() || transformFeedback->isPaused()) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - transformFeedback->pause(); - } -} - -void GL_APIENTRY ResumeTransformFeedback(void) -{ - EVENT("(void)"); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback(); - ASSERT(transformFeedback != NULL); - - // Current transform feedback must be active and paused in order to resume (3.0.2 pg 86) - if (!transformFeedback->isActive() || !transformFeedback->isPaused()) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - transformFeedback->resume(); - } -} - -void GL_APIENTRY GetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary) -{ - EVENT("(GLuint program = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLenum* binaryFormat = 0x%0.8p, GLvoid* binary = 0x%0.8p)", - program, bufSize, length, binaryFormat, binary); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateGetProgramBinary(context, program, bufSize, length, binaryFormat, binary)) - { - return; - } - - Program *programObject = context->getProgram(program); - ASSERT(programObject != nullptr); - - Error error = programObject->saveBinary(binaryFormat, binary, bufSize, length); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -void GL_APIENTRY ProgramBinary(GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length) -{ - EVENT("(GLuint program = %u, GLenum binaryFormat = 0x%X, const GLvoid* binary = 0x%0.8p, GLsizei length = %d)", - program, binaryFormat, binary, length); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateProgramBinary(context, program, binaryFormat, binary, length)) - { - return; - } - - Program *programObject = context->getProgram(program); - ASSERT(programObject != nullptr); - - Error error = programObject->loadBinary(binaryFormat, binary, length); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -void GL_APIENTRY ProgramParameteri(GLuint program, GLenum pname, GLint value) -{ - EVENT("(GLuint program = %u, GLenum pname = 0x%X, GLint value = %d)", - program, pname, value); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!ValidateProgramParameter(context, program, pname, value)) - { - return; - } - - gl::Program *programObject = context->getProgram(program); - ASSERT(programObject != nullptr); - - switch (pname) - { - case GL_PROGRAM_BINARY_RETRIEVABLE_HINT: - programObject->setBinaryRetrievableHint(value != GL_FALSE); - break; - - default: - UNREACHABLE(); - } - } -} - -void GL_APIENTRY InvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments) -{ - EVENT("(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum* attachments = 0x%0.8p)", - target, numAttachments, attachments); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!context->skipValidation() && - !ValidateInvalidateFramebuffer(context, target, numAttachments, attachments)) - { - return; - } - - context->invalidateFramebuffer(target, numAttachments, attachments); - } -} - -void GL_APIENTRY InvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height) -{ - EVENT("(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum* attachments = 0x%0.8p, GLint x = %d, " - "GLint y = %d, GLsizei width = %d, GLsizei height = %d)", - target, numAttachments, attachments, x, y, width, height); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (!context->skipValidation() && - !ValidateInvalidateFramebuffer(context, target, numAttachments, attachments)) - { - return; - } - - context->invalidateSubFramebuffer(target, numAttachments, attachments, x, y, width, height); - } -} - -void GL_APIENTRY TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) -{ - EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", - target, levels, internalformat, width, height); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (!ValidateES3TexStorage2DParameters(context, target, levels, internalformat, width, - height, 1)) - { - return; - } - - Extents size(width, height, 1); - Texture *texture = context->getTargetTexture(target); - Error error = texture->setStorage(target, levels, internalformat, size); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -void GL_APIENTRY TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) -{ - EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, " - "GLsizei height = %d, GLsizei depth = %d)", - target, levels, internalformat, width, height, depth); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - if (!ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, - height, depth)) - { - return; - } - - Extents size(width, height, depth); - Texture *texture = context->getTargetTexture(target); - Error error = texture->setStorage(target, levels, internalformat, size); - if (error.isError()) - { - context->recordError(error); - return; - } - } -} - -void GL_APIENTRY GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params) -{ - EVENT("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLenum pname = 0x%X, GLsizei bufSize = %d, " - "GLint* params = 0x%0.8p)", - target, internalformat, pname, bufSize, params); - - Context *context = GetValidGlobalContext(); - if (context) - { - if (context->getClientVersion() < 3) - { - context->recordError(Error(GL_INVALID_OPERATION)); - return; - } - - const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat); - if (!formatCaps.renderable) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - if (target != GL_RENDERBUFFER) - { - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - - if (bufSize < 0) - { - context->recordError(Error(GL_INVALID_VALUE)); - return; - } - - switch (pname) - { - case GL_NUM_SAMPLE_COUNTS: - if (bufSize != 0) - { - *params = static_cast(formatCaps.sampleCounts.size()); - } - break; - - case GL_SAMPLES: - { - size_t returnCount = std::min(bufSize, formatCaps.sampleCounts.size()); - auto sampleReverseIt = formatCaps.sampleCounts.rbegin(); - for (size_t sampleIndex = 0; sampleIndex < returnCount; ++sampleIndex) - { - params[sampleIndex] = *sampleReverseIt++;; - } - } - break; - - default: - context->recordError(Error(GL_INVALID_ENUM)); - return; - } - } -} - -} diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0.h b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0.h deleted file mode 100644 index 09ca0e4641..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0.h +++ /dev/null @@ -1,125 +0,0 @@ -// -// Copyright(c) 2014 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// entry_points_gles_3_0.h : Defines the GLES 3.0 entry points. - -#ifndef LIBGLESV2_ENTRYPOINTGLES30_H_ -#define LIBGLESV2_ENTRYPOINTGLES30_H_ - -#include -#include - -namespace gl -{ - -ANGLE_EXPORT void GL_APIENTRY ReadBuffer(GLenum mode); -ANGLE_EXPORT void GL_APIENTRY DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices); -ANGLE_EXPORT void GL_APIENTRY TexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels); -ANGLE_EXPORT void GL_APIENTRY TexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels); -ANGLE_EXPORT void GL_APIENTRY CopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -ANGLE_EXPORT void GL_APIENTRY CompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data); -ANGLE_EXPORT void GL_APIENTRY CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data); -ANGLE_EXPORT void GL_APIENTRY GenQueries(GLsizei n, GLuint* ids); -ANGLE_EXPORT void GL_APIENTRY DeleteQueries(GLsizei n, const GLuint* ids); -ANGLE_EXPORT GLboolean GL_APIENTRY IsQuery(GLuint id); -ANGLE_EXPORT void GL_APIENTRY BeginQuery(GLenum target, GLuint id); -ANGLE_EXPORT void GL_APIENTRY EndQuery(GLenum target); -ANGLE_EXPORT void GL_APIENTRY GetQueryiv(GLenum target, GLenum pname, GLint* params); -ANGLE_EXPORT void GL_APIENTRY GetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params); -ANGLE_EXPORT GLboolean GL_APIENTRY UnmapBuffer(GLenum target); -ANGLE_EXPORT void GL_APIENTRY GetBufferPointerv(GLenum target, GLenum pname, GLvoid** params); -ANGLE_EXPORT void GL_APIENTRY DrawBuffers(GLsizei n, const GLenum* bufs); -ANGLE_EXPORT void GL_APIENTRY UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -ANGLE_EXPORT void GL_APIENTRY UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -ANGLE_EXPORT void GL_APIENTRY UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -ANGLE_EXPORT void GL_APIENTRY UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -ANGLE_EXPORT void GL_APIENTRY UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -ANGLE_EXPORT void GL_APIENTRY UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); -ANGLE_EXPORT void GL_APIENTRY BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -ANGLE_EXPORT void GL_APIENTRY RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -ANGLE_EXPORT void GL_APIENTRY FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -ANGLE_EXPORT GLvoid* GL_APIENTRY MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); -ANGLE_EXPORT void GL_APIENTRY FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length); -ANGLE_EXPORT void GL_APIENTRY BindVertexArray(GLuint array); -ANGLE_EXPORT void GL_APIENTRY DeleteVertexArrays(GLsizei n, const GLuint* arrays); -ANGLE_EXPORT void GL_APIENTRY GenVertexArrays(GLsizei n, GLuint* arrays); -ANGLE_EXPORT GLboolean GL_APIENTRY IsVertexArray(GLuint array); -ANGLE_EXPORT void GL_APIENTRY GetIntegeri_v(GLenum target, GLuint index, GLint* data); -ANGLE_EXPORT void GL_APIENTRY BeginTransformFeedback(GLenum primitiveMode); -ANGLE_EXPORT void GL_APIENTRY EndTransformFeedback(void); -ANGLE_EXPORT void GL_APIENTRY BindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -ANGLE_EXPORT void GL_APIENTRY BindBufferBase(GLenum target, GLuint index, GLuint buffer); -ANGLE_EXPORT void GL_APIENTRY TransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode); -ANGLE_EXPORT void GL_APIENTRY GetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name); -ANGLE_EXPORT void GL_APIENTRY VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer); -ANGLE_EXPORT void GL_APIENTRY GetVertexAttribIiv(GLuint index, GLenum pname, GLint* params); -ANGLE_EXPORT void GL_APIENTRY GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params); -ANGLE_EXPORT void GL_APIENTRY VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w); -ANGLE_EXPORT void GL_APIENTRY VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -ANGLE_EXPORT void GL_APIENTRY VertexAttribI4iv(GLuint index, const GLint* v); -ANGLE_EXPORT void GL_APIENTRY VertexAttribI4uiv(GLuint index, const GLuint* v); -ANGLE_EXPORT void GL_APIENTRY GetUniformuiv(GLuint program, GLint location, GLuint* params); -ANGLE_EXPORT GLint GL_APIENTRY GetFragDataLocation(GLuint program, const GLchar *name); -ANGLE_EXPORT void GL_APIENTRY Uniform1ui(GLint location, GLuint v0); -ANGLE_EXPORT void GL_APIENTRY Uniform2ui(GLint location, GLuint v0, GLuint v1); -ANGLE_EXPORT void GL_APIENTRY Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2); -ANGLE_EXPORT void GL_APIENTRY Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -ANGLE_EXPORT void GL_APIENTRY Uniform1uiv(GLint location, GLsizei count, const GLuint* value); -ANGLE_EXPORT void GL_APIENTRY Uniform2uiv(GLint location, GLsizei count, const GLuint* value); -ANGLE_EXPORT void GL_APIENTRY Uniform3uiv(GLint location, GLsizei count, const GLuint* value); -ANGLE_EXPORT void GL_APIENTRY Uniform4uiv(GLint location, GLsizei count, const GLuint* value); -ANGLE_EXPORT void GL_APIENTRY ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value); -ANGLE_EXPORT void GL_APIENTRY ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value); -ANGLE_EXPORT void GL_APIENTRY ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value); -ANGLE_EXPORT void GL_APIENTRY ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); -ANGLE_EXPORT const GLubyte *GL_APIENTRY GetStringi(GLenum name, GLuint index); -ANGLE_EXPORT void GL_APIENTRY CopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -ANGLE_EXPORT void GL_APIENTRY GetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices); -ANGLE_EXPORT void GL_APIENTRY GetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params); -ANGLE_EXPORT GLuint GL_APIENTRY GetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName); -ANGLE_EXPORT void GL_APIENTRY GetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params); -ANGLE_EXPORT void GL_APIENTRY GetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName); -ANGLE_EXPORT void GL_APIENTRY UniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); -ANGLE_EXPORT void GL_APIENTRY DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount); -ANGLE_EXPORT void GL_APIENTRY DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount); -ANGLE_EXPORT GLsync GL_APIENTRY FenceSync_(GLenum condition, GLbitfield flags); -ANGLE_EXPORT GLboolean GL_APIENTRY IsSync(GLsync sync); -ANGLE_EXPORT void GL_APIENTRY DeleteSync(GLsync sync); -ANGLE_EXPORT GLenum GL_APIENTRY ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout); -ANGLE_EXPORT void GL_APIENTRY WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout); -ANGLE_EXPORT void GL_APIENTRY GetInteger64v(GLenum pname, GLint64* params); -ANGLE_EXPORT void GL_APIENTRY GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values); -ANGLE_EXPORT void GL_APIENTRY GetInteger64i_v(GLenum target, GLuint index, GLint64* data); -ANGLE_EXPORT void GL_APIENTRY GetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params); -ANGLE_EXPORT void GL_APIENTRY GenSamplers(GLsizei count, GLuint* samplers); -ANGLE_EXPORT void GL_APIENTRY DeleteSamplers(GLsizei count, const GLuint* samplers); -ANGLE_EXPORT GLboolean GL_APIENTRY IsSampler(GLuint sampler); -ANGLE_EXPORT void GL_APIENTRY BindSampler(GLuint unit, GLuint sampler); -ANGLE_EXPORT void GL_APIENTRY SamplerParameteri(GLuint sampler, GLenum pname, GLint param); -ANGLE_EXPORT void GL_APIENTRY SamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param); -ANGLE_EXPORT void GL_APIENTRY SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param); -ANGLE_EXPORT void GL_APIENTRY SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param); -ANGLE_EXPORT void GL_APIENTRY GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params); -ANGLE_EXPORT void GL_APIENTRY GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params); -ANGLE_EXPORT void GL_APIENTRY VertexAttribDivisor(GLuint index, GLuint divisor); -ANGLE_EXPORT void GL_APIENTRY BindTransformFeedback(GLenum target, GLuint id); -ANGLE_EXPORT void GL_APIENTRY DeleteTransformFeedbacks(GLsizei n, const GLuint* ids); -ANGLE_EXPORT void GL_APIENTRY GenTransformFeedbacks(GLsizei n, GLuint* ids); -ANGLE_EXPORT GLboolean GL_APIENTRY IsTransformFeedback(GLuint id); -ANGLE_EXPORT void GL_APIENTRY PauseTransformFeedback(void); -ANGLE_EXPORT void GL_APIENTRY ResumeTransformFeedback(void); -ANGLE_EXPORT void GL_APIENTRY GetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary); -ANGLE_EXPORT void GL_APIENTRY ProgramBinary(GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length); -ANGLE_EXPORT void GL_APIENTRY ProgramParameteri(GLuint program, GLenum pname, GLint value); -ANGLE_EXPORT void GL_APIENTRY InvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments); -ANGLE_EXPORT void GL_APIENTRY InvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height); -ANGLE_EXPORT void GL_APIENTRY TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -ANGLE_EXPORT void GL_APIENTRY TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -ANGLE_EXPORT void GL_APIENTRY GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params); - -} - -#endif // LIBGLESV2_ENTRYPOINTGLES30_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0_autogen.cpp b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0_autogen.cpp new file mode 100644 index 0000000000..439f920bab --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0_autogen.cpp @@ -0,0 +1,2084 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml. +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// entry_points_gles_3_0_autogen.cpp: +// Defines the GLES 3.0 entry points. + +#include "libANGLE/Context.h" +#include "libANGLE/validationES3.h" +#include "libGLESv2/global_state.h" + +namespace gl +{ +void GL_APIENTRY ReadBuffer(GLenum src) +{ + EVENT("(GLenum src = 0x%X)", src); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(src); + + if (context->skipValidation() || ValidateReadBuffer(context, src)) + { + context->readBuffer(src); + } + } +} + +void GL_APIENTRY DrawRangeElements(GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const void *indices) +{ + EVENT( + "(GLenum mode = 0x%X, GLuint start = %u, GLuint end = %u, GLsizei count = %d, GLenum type " + "= 0x%X, const void *indices = 0x%0.8p)", + mode, start, end, count, type, indices); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(mode, start, end, count, type, + indices); + + if (context->skipValidation() || + ValidateDrawRangeElements(context, mode, start, end, count, type, indices)) + { + context->drawRangeElements(mode, start, end, count, type, indices); + } + } +} + +void GL_APIENTRY TexImage3D(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const void *pixels) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, " + "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLenum format = 0x%X, GLenum " + "type = 0x%X, const void *pixels = 0x%0.8p)", + target, level, internalformat, width, height, depth, border, format, type, pixels); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, level, internalformat, width, height, + depth, border, format, type, pixels); + + if (context->skipValidation() || + ValidateTexImage3D(context, target, level, internalformat, width, height, depth, border, + format, type, pixels)) + { + context->texImage3D(target, level, internalformat, width, height, depth, border, format, + type, pixels); + } + } +} + +void GL_APIENTRY TexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *pixels) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, GLint " + "zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLenum format " + "= 0x%X, GLenum type = 0x%X, const void *pixels = 0x%0.8p)", + target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams( + target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + + if (context->skipValidation() || + ValidateTexSubImage3D(context, target, level, xoffset, yoffset, zoffset, width, height, + depth, format, type, pixels)) + { + context->texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, + format, type, pixels); + } + } +} + +void GL_APIENTRY CopyTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, GLint " + "zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", + target, level, xoffset, yoffset, zoffset, x, y, width, height); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, level, xoffset, yoffset, + zoffset, x, y, width, height); + + if (context->skipValidation() || + ValidateCopyTexSubImage3D(context, target, level, xoffset, yoffset, zoffset, x, y, + width, height)) + { + context->copyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, + height); + } + } +} + +void GL_APIENTRY CompressedTexImage3D(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const void *data) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = " + "%d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, " + "const void *data = 0x%0.8p)", + target, level, internalformat, width, height, depth, border, imageSize, data); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams( + target, level, internalformat, width, height, depth, border, imageSize, data); + + if (context->skipValidation() || + ValidateCompressedTexImage3D(context, target, level, internalformat, width, height, + depth, border, imageSize, data)) + { + context->compressedTexImage3D(target, level, internalformat, width, height, depth, + border, imageSize, data); + } + } +} + +void GL_APIENTRY CompressedTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void *data) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, GLint " + "zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLenum format " + "= 0x%X, GLsizei imageSize = %d, const void *data = 0x%0.8p)", + target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, level, xoffset, yoffset, + zoffset, width, height, depth, + format, imageSize, data); + + if (context->skipValidation() || + ValidateCompressedTexSubImage3D(context, target, level, xoffset, yoffset, zoffset, + width, height, depth, format, imageSize, data)) + { + context->compressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, + height, depth, format, imageSize, data); + } + } +} + +void GL_APIENTRY GenQueries(GLsizei n, GLuint *ids) +{ + EVENT("(GLsizei n = %d, GLuint *ids = 0x%0.8p)", n, ids); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(n, ids); + + if (context->skipValidation() || ValidateGenQueries(context, n, ids)) + { + context->genQueries(n, ids); + } + } +} + +void GL_APIENTRY DeleteQueries(GLsizei n, const GLuint *ids) +{ + EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(n, ids); + + if (context->skipValidation() || ValidateDeleteQueries(context, n, ids)) + { + context->deleteQueries(n, ids); + } + } +} + +GLboolean GL_APIENTRY IsQuery(GLuint id) +{ + EVENT("(GLuint id = %u)", id); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(id); + + if (context->skipValidation() || ValidateIsQuery(context, id)) + { + return context->isQuery(id); + } + } + + return GetDefaultReturnValue(); +} + +void GL_APIENTRY BeginQuery(GLenum target, GLuint id) +{ + EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, id); + + if (context->skipValidation() || ValidateBeginQuery(context, target, id)) + { + context->beginQuery(target, id); + } + } +} + +void GL_APIENTRY EndQuery(GLenum target) +{ + EVENT("(GLenum target = 0x%X)", target); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target); + + if (context->skipValidation() || ValidateEndQuery(context, target)) + { + context->endQuery(target); + } + } +} + +void GL_APIENTRY GetQueryiv(GLenum target, GLenum pname, GLint *params) +{ + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, + params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, pname, params); + + if (context->skipValidation() || ValidateGetQueryiv(context, target, pname, params)) + { + context->getQueryiv(target, pname, params); + } + } +} + +void GL_APIENTRY GetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params) +{ + EVENT("(GLuint id = %u, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(id, pname, params); + + if (context->skipValidation() || ValidateGetQueryObjectuiv(context, id, pname, params)) + { + context->getQueryObjectuiv(id, pname, params); + } + } +} + +GLboolean GL_APIENTRY UnmapBuffer(GLenum target) +{ + EVENT("(GLenum target = 0x%X)", target); + + Context *context = GetValidGlobalContext(); + if (context) + { + BufferBinding targetPacked = FromGLenum(target); + context->gatherParams(targetPacked); + + if (context->skipValidation() || ValidateUnmapBuffer(context, targetPacked)) + { + return context->unmapBuffer(targetPacked); + } + } + + return GetDefaultReturnValue(); +} + +void GL_APIENTRY GetBufferPointerv(GLenum target, GLenum pname, void **params) +{ + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, void **params = 0x%0.8p)", target, pname, + params); + + Context *context = GetValidGlobalContext(); + if (context) + { + BufferBinding targetPacked = FromGLenum(target); + context->gatherParams(targetPacked, pname, params); + + if (context->skipValidation() || + ValidateGetBufferPointerv(context, targetPacked, pname, params)) + { + context->getBufferPointerv(targetPacked, pname, params); + } + } +} + +void GL_APIENTRY DrawBuffers(GLsizei n, const GLenum *bufs) +{ + EVENT("(GLsizei n = %d, const GLenum *bufs = 0x%0.8p)", n, bufs); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(n, bufs); + + if (context->skipValidation() || ValidateDrawBuffers(context, n, bufs)) + { + context->drawBuffers(n, bufs); + } + } +} + +void GL_APIENTRY UniformMatrix2x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + EVENT( + "(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat *value " + "= 0x%0.8p)", + location, count, transpose, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, count, transpose, value); + + if (context->skipValidation() || + ValidateUniformMatrix2x3fv(context, location, count, transpose, value)) + { + context->uniformMatrix2x3fv(location, count, transpose, value); + } + } +} + +void GL_APIENTRY UniformMatrix3x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + EVENT( + "(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat *value " + "= 0x%0.8p)", + location, count, transpose, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, count, transpose, value); + + if (context->skipValidation() || + ValidateUniformMatrix3x2fv(context, location, count, transpose, value)) + { + context->uniformMatrix3x2fv(location, count, transpose, value); + } + } +} + +void GL_APIENTRY UniformMatrix2x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + EVENT( + "(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat *value " + "= 0x%0.8p)", + location, count, transpose, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, count, transpose, value); + + if (context->skipValidation() || + ValidateUniformMatrix2x4fv(context, location, count, transpose, value)) + { + context->uniformMatrix2x4fv(location, count, transpose, value); + } + } +} + +void GL_APIENTRY UniformMatrix4x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + EVENT( + "(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat *value " + "= 0x%0.8p)", + location, count, transpose, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, count, transpose, value); + + if (context->skipValidation() || + ValidateUniformMatrix4x2fv(context, location, count, transpose, value)) + { + context->uniformMatrix4x2fv(location, count, transpose, value); + } + } +} + +void GL_APIENTRY UniformMatrix3x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + EVENT( + "(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat *value " + "= 0x%0.8p)", + location, count, transpose, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, count, transpose, value); + + if (context->skipValidation() || + ValidateUniformMatrix3x4fv(context, location, count, transpose, value)) + { + context->uniformMatrix3x4fv(location, count, transpose, value); + } + } +} + +void GL_APIENTRY UniformMatrix4x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + EVENT( + "(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat *value " + "= 0x%0.8p)", + location, count, transpose, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, count, transpose, value); + + if (context->skipValidation() || + ValidateUniformMatrix4x3fv(context, location, count, transpose, value)) + { + context->uniformMatrix4x3fv(location, count, transpose, value); + } + } +} + +void GL_APIENTRY BlitFramebuffer(GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter) +{ + EVENT( + "(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, GLint dstX0 = " + "%d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, GLbitfield mask = 0x%X, GLenum " + "filter = 0x%X)", + srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, + dstX1, dstY1, mask, filter); + + if (context->skipValidation() || + ValidateBlitFramebuffer(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, + mask, filter)) + { + context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, + filter); + } + } +} + +void GL_APIENTRY RenderbufferStorageMultisample(GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height) +{ + EVENT( + "(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width " + "= %d, GLsizei height = %d)", + target, samples, internalformat, width, height); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams( + target, samples, internalformat, width, height); + + if (context->skipValidation() || + ValidateRenderbufferStorageMultisample(context, target, samples, internalformat, width, + height)) + { + context->renderbufferStorageMultisample(target, samples, internalformat, width, height); + } + } +} + +void GL_APIENTRY +FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) +{ + EVENT( + "(GLenum target = 0x%X, GLenum attachment = 0x%X, GLuint texture = %u, GLint level = %d, " + "GLint layer = %d)", + target, attachment, texture, level, layer); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, attachment, texture, + level, layer); + + if (context->skipValidation() || + ValidateFramebufferTextureLayer(context, target, attachment, texture, level, layer)) + { + context->framebufferTextureLayer(target, attachment, texture, level, layer); + } + } +} + +void *GL_APIENTRY MapBufferRange(GLenum target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access) +{ + EVENT( + "(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = " + "0x%X)", + target, offset, length, access); + + Context *context = GetValidGlobalContext(); + if (context) + { + BufferBinding targetPacked = FromGLenum(target); + context->gatherParams(targetPacked, offset, length, access); + + if (context->skipValidation() || + ValidateMapBufferRange(context, targetPacked, offset, length, access)) + { + return context->mapBufferRange(targetPacked, offset, length, access); + } + } + + return GetDefaultReturnValue(); +} + +void GL_APIENTRY FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) +{ + EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, + length); + + Context *context = GetValidGlobalContext(); + if (context) + { + BufferBinding targetPacked = FromGLenum(target); + context->gatherParams(targetPacked, offset, length); + + if (context->skipValidation() || + ValidateFlushMappedBufferRange(context, targetPacked, offset, length)) + { + context->flushMappedBufferRange(targetPacked, offset, length); + } + } +} + +void GL_APIENTRY BindVertexArray(GLuint array) +{ + EVENT("(GLuint array = %u)", array); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(array); + + if (context->skipValidation() || ValidateBindVertexArray(context, array)) + { + context->bindVertexArray(array); + } + } +} + +void GL_APIENTRY DeleteVertexArrays(GLsizei n, const GLuint *arrays) +{ + EVENT("(GLsizei n = %d, const GLuint *arrays = 0x%0.8p)", n, arrays); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(n, arrays); + + if (context->skipValidation() || ValidateDeleteVertexArrays(context, n, arrays)) + { + context->deleteVertexArrays(n, arrays); + } + } +} + +void GL_APIENTRY GenVertexArrays(GLsizei n, GLuint *arrays) +{ + EVENT("(GLsizei n = %d, GLuint *arrays = 0x%0.8p)", n, arrays); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(n, arrays); + + if (context->skipValidation() || ValidateGenVertexArrays(context, n, arrays)) + { + context->genVertexArrays(n, arrays); + } + } +} + +GLboolean GL_APIENTRY IsVertexArray(GLuint array) +{ + EVENT("(GLuint array = %u)", array); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(array); + + if (context->skipValidation() || ValidateIsVertexArray(context, array)) + { + return context->isVertexArray(array); + } + } + + return GetDefaultReturnValue(); +} + +void GL_APIENTRY GetIntegeri_v(GLenum target, GLuint index, GLint *data) +{ + EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint *data = 0x%0.8p)", target, index, data); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, index, data); + + if (context->skipValidation() || ValidateGetIntegeri_v(context, target, index, data)) + { + context->getIntegeri_v(target, index, data); + } + } +} + +void GL_APIENTRY BeginTransformFeedback(GLenum primitiveMode) +{ + EVENT("(GLenum primitiveMode = 0x%X)", primitiveMode); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(primitiveMode); + + if (context->skipValidation() || ValidateBeginTransformFeedback(context, primitiveMode)) + { + context->beginTransformFeedback(primitiveMode); + } + } +} + +void GL_APIENTRY EndTransformFeedback() +{ + EVENT("()"); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(); + + if (context->skipValidation() || ValidateEndTransformFeedback(context)) + { + context->endTransformFeedback(); + } + } +} + +void GL_APIENTRY +BindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) +{ + EVENT( + "(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u, GLintptr offset = %d, " + "GLsizeiptr size = %d)", + target, index, buffer, offset, size); + + Context *context = GetValidGlobalContext(); + if (context) + { + BufferBinding targetPacked = FromGLenum(target); + context->gatherParams(targetPacked, index, buffer, offset, + size); + + if (context->skipValidation() || + ValidateBindBufferRange(context, targetPacked, index, buffer, offset, size)) + { + context->bindBufferRange(targetPacked, index, buffer, offset, size); + } + } +} + +void GL_APIENTRY BindBufferBase(GLenum target, GLuint index, GLuint buffer) +{ + EVENT("(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u)", target, index, buffer); + + Context *context = GetValidGlobalContext(); + if (context) + { + BufferBinding targetPacked = FromGLenum(target); + context->gatherParams(targetPacked, index, buffer); + + if (context->skipValidation() || + ValidateBindBufferBase(context, targetPacked, index, buffer)) + { + context->bindBufferBase(targetPacked, index, buffer); + } + } +} + +void GL_APIENTRY TransformFeedbackVaryings(GLuint program, + GLsizei count, + const GLchar *const *varyings, + GLenum bufferMode) +{ + EVENT( + "(GLuint program = %u, GLsizei count = %d, const GLchar *const*varyings = 0x%0.8p, GLenum " + "bufferMode = 0x%X)", + program, count, varyings, bufferMode); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, count, varyings, + bufferMode); + + if (context->skipValidation() || + ValidateTransformFeedbackVaryings(context, program, count, varyings, bufferMode)) + { + context->transformFeedbackVaryings(program, count, varyings, bufferMode); + } + } +} + +void GL_APIENTRY GetTransformFeedbackVarying(GLuint program, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLsizei *size, + GLenum *type, + GLchar *name) +{ + EVENT( + "(GLuint program = %u, GLuint index = %u, GLsizei bufSize = %d, GLsizei *length = 0x%0.8p, " + "GLsizei *size = 0x%0.8p, GLenum *type = 0x%0.8p, GLchar *name = 0x%0.8p)", + program, index, bufSize, length, size, type, name); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, index, bufSize, + length, size, type, name); + + if (context->skipValidation() || + ValidateGetTransformFeedbackVarying(context, program, index, bufSize, length, size, + type, name)) + { + context->getTransformFeedbackVarying(program, index, bufSize, length, size, type, name); + } + } +} + +void GL_APIENTRY +VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer) +{ + EVENT( + "(GLuint index = %u, GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const void " + "*pointer = 0x%0.8p)", + index, size, type, stride, pointer); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(index, size, type, stride, pointer); + + if (context->skipValidation() || + ValidateVertexAttribIPointer(context, index, size, type, stride, pointer)) + { + context->vertexAttribIPointer(index, size, type, stride, pointer); + } + } +} + +void GL_APIENTRY GetVertexAttribIiv(GLuint index, GLenum pname, GLint *params) +{ + EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", index, pname, + params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(index, pname, params); + + if (context->skipValidation() || ValidateGetVertexAttribIiv(context, index, pname, params)) + { + context->getVertexAttribIiv(index, pname, params); + } + } +} + +void GL_APIENTRY GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params) +{ + EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", index, pname, + params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(index, pname, params); + + if (context->skipValidation() || ValidateGetVertexAttribIuiv(context, index, pname, params)) + { + context->getVertexAttribIuiv(index, pname, params); + } + } +} + +void GL_APIENTRY VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w) +{ + EVENT("(GLuint index = %u, GLint x = %d, GLint y = %d, GLint z = %d, GLint w = %d)", index, x, + y, z, w); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(index, x, y, z, w); + + if (context->skipValidation() || ValidateVertexAttribI4i(context, index, x, y, z, w)) + { + context->vertexAttribI4i(index, x, y, z, w); + } + } +} + +void GL_APIENTRY VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) +{ + EVENT("(GLuint index = %u, GLuint x = %u, GLuint y = %u, GLuint z = %u, GLuint w = %u)", index, + x, y, z, w); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(index, x, y, z, w); + + if (context->skipValidation() || ValidateVertexAttribI4ui(context, index, x, y, z, w)) + { + context->vertexAttribI4ui(index, x, y, z, w); + } + } +} + +void GL_APIENTRY VertexAttribI4iv(GLuint index, const GLint *v) +{ + EVENT("(GLuint index = %u, const GLint *v = 0x%0.8p)", index, v); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(index, v); + + if (context->skipValidation() || ValidateVertexAttribI4iv(context, index, v)) + { + context->vertexAttribI4iv(index, v); + } + } +} + +void GL_APIENTRY VertexAttribI4uiv(GLuint index, const GLuint *v) +{ + EVENT("(GLuint index = %u, const GLuint *v = 0x%0.8p)", index, v); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(index, v); + + if (context->skipValidation() || ValidateVertexAttribI4uiv(context, index, v)) + { + context->vertexAttribI4uiv(index, v); + } + } +} + +void GL_APIENTRY GetUniformuiv(GLuint program, GLint location, GLuint *params) +{ + EVENT("(GLuint program = %u, GLint location = %d, GLuint *params = 0x%0.8p)", program, location, + params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, params); + + if (context->skipValidation() || ValidateGetUniformuiv(context, program, location, params)) + { + context->getUniformuiv(program, location, params); + } + } +} + +GLint GL_APIENTRY GetFragDataLocation(GLuint program, const GLchar *name) +{ + EVENT("(GLuint program = %u, const GLchar *name = 0x%0.8p)", program, name); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, name); + + if (context->skipValidation() || ValidateGetFragDataLocation(context, program, name)) + { + return context->getFragDataLocation(program, name); + } + } + + return GetDefaultReturnValue(); +} + +void GL_APIENTRY Uniform1ui(GLint location, GLuint v0) +{ + EVENT("(GLint location = %d, GLuint v0 = %u)", location, v0); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, v0); + + if (context->skipValidation() || ValidateUniform1ui(context, location, v0)) + { + context->uniform1ui(location, v0); + } + } +} + +void GL_APIENTRY Uniform2ui(GLint location, GLuint v0, GLuint v1) +{ + EVENT("(GLint location = %d, GLuint v0 = %u, GLuint v1 = %u)", location, v0, v1); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, v0, v1); + + if (context->skipValidation() || ValidateUniform2ui(context, location, v0, v1)) + { + context->uniform2ui(location, v0, v1); + } + } +} + +void GL_APIENTRY Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) +{ + EVENT("(GLint location = %d, GLuint v0 = %u, GLuint v1 = %u, GLuint v2 = %u)", location, v0, v1, + v2); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, v0, v1, v2); + + if (context->skipValidation() || ValidateUniform3ui(context, location, v0, v1, v2)) + { + context->uniform3ui(location, v0, v1, v2); + } + } +} + +void GL_APIENTRY Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +{ + EVENT("(GLint location = %d, GLuint v0 = %u, GLuint v1 = %u, GLuint v2 = %u, GLuint v3 = %u)", + location, v0, v1, v2, v3); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, v0, v1, v2, v3); + + if (context->skipValidation() || ValidateUniform4ui(context, location, v0, v1, v2, v3)) + { + context->uniform4ui(location, v0, v1, v2, v3); + } + } +} + +void GL_APIENTRY Uniform1uiv(GLint location, GLsizei count, const GLuint *value) +{ + EVENT("(GLint location = %d, GLsizei count = %d, const GLuint *value = 0x%0.8p)", location, + count, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, count, value); + + if (context->skipValidation() || ValidateUniform1uiv(context, location, count, value)) + { + context->uniform1uiv(location, count, value); + } + } +} + +void GL_APIENTRY Uniform2uiv(GLint location, GLsizei count, const GLuint *value) +{ + EVENT("(GLint location = %d, GLsizei count = %d, const GLuint *value = 0x%0.8p)", location, + count, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, count, value); + + if (context->skipValidation() || ValidateUniform2uiv(context, location, count, value)) + { + context->uniform2uiv(location, count, value); + } + } +} + +void GL_APIENTRY Uniform3uiv(GLint location, GLsizei count, const GLuint *value) +{ + EVENT("(GLint location = %d, GLsizei count = %d, const GLuint *value = 0x%0.8p)", location, + count, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, count, value); + + if (context->skipValidation() || ValidateUniform3uiv(context, location, count, value)) + { + context->uniform3uiv(location, count, value); + } + } +} + +void GL_APIENTRY Uniform4uiv(GLint location, GLsizei count, const GLuint *value) +{ + EVENT("(GLint location = %d, GLsizei count = %d, const GLuint *value = 0x%0.8p)", location, + count, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(location, count, value); + + if (context->skipValidation() || ValidateUniform4uiv(context, location, count, value)) + { + context->uniform4uiv(location, count, value); + } + } +} + +void GL_APIENTRY ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value) +{ + EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLint *value = 0x%0.8p)", buffer, + drawbuffer, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(buffer, drawbuffer, value); + + if (context->skipValidation() || ValidateClearBufferiv(context, buffer, drawbuffer, value)) + { + context->clearBufferiv(buffer, drawbuffer, value); + } + } +} + +void GL_APIENTRY ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value) +{ + EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLuint *value = 0x%0.8p)", buffer, + drawbuffer, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(buffer, drawbuffer, value); + + if (context->skipValidation() || ValidateClearBufferuiv(context, buffer, drawbuffer, value)) + { + context->clearBufferuiv(buffer, drawbuffer, value); + } + } +} + +void GL_APIENTRY ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value) +{ + EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLfloat *value = 0x%0.8p)", buffer, + drawbuffer, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(buffer, drawbuffer, value); + + if (context->skipValidation() || ValidateClearBufferfv(context, buffer, drawbuffer, value)) + { + context->clearBufferfv(buffer, drawbuffer, value); + } + } +} + +void GL_APIENTRY ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) +{ + EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, GLfloat depth = %f, GLint stencil = %d)", + buffer, drawbuffer, depth, stencil); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(buffer, drawbuffer, depth, stencil); + + if (context->skipValidation() || + ValidateClearBufferfi(context, buffer, drawbuffer, depth, stencil)) + { + context->clearBufferfi(buffer, drawbuffer, depth, stencil); + } + } +} + +const GLubyte *GL_APIENTRY GetStringi(GLenum name, GLuint index) +{ + EVENT("(GLenum name = 0x%X, GLuint index = %u)", name, index); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(name, index); + + if (context->skipValidation() || ValidateGetStringi(context, name, index)) + { + return context->getStringi(name, index); + } + } + + return GetDefaultReturnValue(); +} + +void GL_APIENTRY CopyBufferSubData(GLenum readTarget, + GLenum writeTarget, + GLintptr readOffset, + GLintptr writeOffset, + GLsizeiptr size) +{ + EVENT( + "(GLenum readTarget = 0x%X, GLenum writeTarget = 0x%X, GLintptr readOffset = %d, GLintptr " + "writeOffset = %d, GLsizeiptr size = %d)", + readTarget, writeTarget, readOffset, writeOffset, size); + + Context *context = GetValidGlobalContext(); + if (context) + { + BufferBinding readTargetPacked = FromGLenum(readTarget); + BufferBinding writeTargetPacked = FromGLenum(writeTarget); + context->gatherParams(readTargetPacked, writeTargetPacked, + readOffset, writeOffset, size); + + if (context->skipValidation() || + ValidateCopyBufferSubData(context, readTargetPacked, writeTargetPacked, readOffset, + writeOffset, size)) + { + context->copyBufferSubData(readTargetPacked, writeTargetPacked, readOffset, writeOffset, + size); + } + } +} + +void GL_APIENTRY GetUniformIndices(GLuint program, + GLsizei uniformCount, + const GLchar *const *uniformNames, + GLuint *uniformIndices) +{ + EVENT( + "(GLuint program = %u, GLsizei uniformCount = %d, const GLchar *const*uniformNames = " + "0x%0.8p, GLuint *uniformIndices = 0x%0.8p)", + program, uniformCount, uniformNames, uniformIndices); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, uniformCount, uniformNames, + uniformIndices); + + if (context->skipValidation() || + ValidateGetUniformIndices(context, program, uniformCount, uniformNames, uniformIndices)) + { + context->getUniformIndices(program, uniformCount, uniformNames, uniformIndices); + } + } +} + +void GL_APIENTRY GetActiveUniformsiv(GLuint program, + GLsizei uniformCount, + const GLuint *uniformIndices, + GLenum pname, + GLint *params) +{ + EVENT( + "(GLuint program = %u, GLsizei uniformCount = %d, const GLuint *uniformIndices = 0x%0.8p, " + "GLenum pname = 0x%X, GLint *params = 0x%0.8p)", + program, uniformCount, uniformIndices, pname, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, uniformCount, + uniformIndices, pname, params); + + if (context->skipValidation() || ValidateGetActiveUniformsiv(context, program, uniformCount, + uniformIndices, pname, params)) + { + context->getActiveUniformsiv(program, uniformCount, uniformIndices, pname, params); + } + } +} + +GLuint GL_APIENTRY GetUniformBlockIndex(GLuint program, const GLchar *uniformBlockName) +{ + EVENT("(GLuint program = %u, const GLchar *uniformBlockName = 0x%0.8p)", program, + uniformBlockName); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, uniformBlockName); + + if (context->skipValidation() || + ValidateGetUniformBlockIndex(context, program, uniformBlockName)) + { + return context->getUniformBlockIndex(program, uniformBlockName); + } + } + + return GetDefaultReturnValue(); +} + +void GL_APIENTRY GetActiveUniformBlockiv(GLuint program, + GLuint uniformBlockIndex, + GLenum pname, + GLint *params) +{ + EVENT( + "(GLuint program = %u, GLuint uniformBlockIndex = %u, GLenum pname = 0x%X, GLint *params = " + "0x%0.8p)", + program, uniformBlockIndex, pname, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, uniformBlockIndex, + pname, params); + + if (context->skipValidation() || + ValidateGetActiveUniformBlockiv(context, program, uniformBlockIndex, pname, params)) + { + context->getActiveUniformBlockiv(program, uniformBlockIndex, pname, params); + } + } +} + +void GL_APIENTRY GetActiveUniformBlockName(GLuint program, + GLuint uniformBlockIndex, + GLsizei bufSize, + GLsizei *length, + GLchar *uniformBlockName) +{ + EVENT( + "(GLuint program = %u, GLuint uniformBlockIndex = %u, GLsizei bufSize = %d, GLsizei " + "*length = 0x%0.8p, GLchar *uniformBlockName = 0x%0.8p)", + program, uniformBlockIndex, bufSize, length, uniformBlockName); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams( + program, uniformBlockIndex, bufSize, length, uniformBlockName); + + if (context->skipValidation() || + ValidateGetActiveUniformBlockName(context, program, uniformBlockIndex, bufSize, length, + uniformBlockName)) + { + context->getActiveUniformBlockName(program, uniformBlockIndex, bufSize, length, + uniformBlockName); + } + } +} + +void GL_APIENTRY UniformBlockBinding(GLuint program, + GLuint uniformBlockIndex, + GLuint uniformBlockBinding) +{ + EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLuint uniformBlockBinding = %u)", + program, uniformBlockIndex, uniformBlockBinding); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, uniformBlockIndex, + uniformBlockBinding); + + if (context->skipValidation() || + ValidateUniformBlockBinding(context, program, uniformBlockIndex, uniformBlockBinding)) + { + context->uniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); + } + } +} + +void GL_APIENTRY DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount) +{ + EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instancecount = %d)", + mode, first, count, instancecount); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(mode, first, count, instancecount); + + if (context->skipValidation() || + ValidateDrawArraysInstanced(context, mode, first, count, instancecount)) + { + context->drawArraysInstanced(mode, first, count, instancecount); + } + } +} + +void GL_APIENTRY DrawElementsInstanced(GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei instancecount) +{ + EVENT( + "(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = " + "0x%0.8p, GLsizei instancecount = %d)", + mode, count, type, indices, instancecount); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(mode, count, type, indices, + instancecount); + + if (context->skipValidation() || + ValidateDrawElementsInstanced(context, mode, count, type, indices, instancecount)) + { + context->drawElementsInstanced(mode, count, type, indices, instancecount); + } + } +} + +GLsync GL_APIENTRY FenceSync(GLenum condition, GLbitfield flags) +{ + EVENT("(GLenum condition = 0x%X, GLbitfield flags = 0x%X)", condition, flags); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(condition, flags); + + if (context->skipValidation() || ValidateFenceSync(context, condition, flags)) + { + return context->fenceSync(condition, flags); + } + } + + return GetDefaultReturnValue(); +} + +GLboolean GL_APIENTRY IsSync(GLsync sync) +{ + EVENT("(GLsync sync = 0x%0.8p)", sync); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(sync); + + if (context->skipValidation() || ValidateIsSync(context, sync)) + { + return context->isSync(sync); + } + } + + return GetDefaultReturnValue(); +} + +void GL_APIENTRY DeleteSync(GLsync sync) +{ + EVENT("(GLsync sync = 0x%0.8p)", sync); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(sync); + + if (context->skipValidation() || ValidateDeleteSync(context, sync)) + { + context->deleteSync(sync); + } + } +} + +GLenum GL_APIENTRY ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) +{ + EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)", sync, flags, + timeout); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(sync, flags, timeout); + + if (context->skipValidation() || ValidateClientWaitSync(context, sync, flags, timeout)) + { + return context->clientWaitSync(sync, flags, timeout); + } + } + + return GetDefaultReturnValue(); +} + +void GL_APIENTRY WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) +{ + EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)", sync, flags, + timeout); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(sync, flags, timeout); + + if (context->skipValidation() || ValidateWaitSync(context, sync, flags, timeout)) + { + context->waitSync(sync, flags, timeout); + } + } +} + +void GL_APIENTRY GetInteger64v(GLenum pname, GLint64 *data) +{ + EVENT("(GLenum pname = 0x%X, GLint64 *data = 0x%0.8p)", pname, data); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(pname, data); + + if (context->skipValidation() || ValidateGetInteger64v(context, pname, data)) + { + context->getInteger64v(pname, data); + } + } +} + +void GL_APIENTRY +GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values) +{ + EVENT( + "(GLsync sync = 0x%0.8p, GLenum pname = 0x%X, GLsizei bufSize = %d, GLsizei *length = " + "0x%0.8p, GLint *values = 0x%0.8p)", + sync, pname, bufSize, length, values); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(sync, pname, bufSize, length, values); + + if (context->skipValidation() || + ValidateGetSynciv(context, sync, pname, bufSize, length, values)) + { + context->getSynciv(sync, pname, bufSize, length, values); + } + } +} + +void GL_APIENTRY GetInteger64i_v(GLenum target, GLuint index, GLint64 *data) +{ + EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint64 *data = 0x%0.8p)", target, index, + data); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, index, data); + + if (context->skipValidation() || ValidateGetInteger64i_v(context, target, index, data)) + { + context->getInteger64i_v(target, index, data); + } + } +} + +void GL_APIENTRY GetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params) +{ + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint64 *params = 0x%0.8p)", target, pname, + params); + + Context *context = GetValidGlobalContext(); + if (context) + { + BufferBinding targetPacked = FromGLenum(target); + context->gatherParams(targetPacked, pname, params); + + if (context->skipValidation() || + ValidateGetBufferParameteri64v(context, targetPacked, pname, params)) + { + context->getBufferParameteri64v(targetPacked, pname, params); + } + } +} + +void GL_APIENTRY GenSamplers(GLsizei count, GLuint *samplers) +{ + EVENT("(GLsizei count = %d, GLuint *samplers = 0x%0.8p)", count, samplers); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(count, samplers); + + if (context->skipValidation() || ValidateGenSamplers(context, count, samplers)) + { + context->genSamplers(count, samplers); + } + } +} + +void GL_APIENTRY DeleteSamplers(GLsizei count, const GLuint *samplers) +{ + EVENT("(GLsizei count = %d, const GLuint *samplers = 0x%0.8p)", count, samplers); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(count, samplers); + + if (context->skipValidation() || ValidateDeleteSamplers(context, count, samplers)) + { + context->deleteSamplers(count, samplers); + } + } +} + +GLboolean GL_APIENTRY IsSampler(GLuint sampler) +{ + EVENT("(GLuint sampler = %u)", sampler); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(sampler); + + if (context->skipValidation() || ValidateIsSampler(context, sampler)) + { + return context->isSampler(sampler); + } + } + + return GetDefaultReturnValue(); +} + +void GL_APIENTRY BindSampler(GLuint unit, GLuint sampler) +{ + EVENT("(GLuint unit = %u, GLuint sampler = %u)", unit, sampler); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(unit, sampler); + + if (context->skipValidation() || ValidateBindSampler(context, unit, sampler)) + { + context->bindSampler(unit, sampler); + } + } +} + +void GL_APIENTRY SamplerParameteri(GLuint sampler, GLenum pname, GLint param) +{ + EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint param = %d)", sampler, pname, param); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(sampler, pname, param); + + if (context->skipValidation() || ValidateSamplerParameteri(context, sampler, pname, param)) + { + context->samplerParameteri(sampler, pname, param); + } + } +} + +void GL_APIENTRY SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *param) +{ + EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, const GLint *param = 0x%0.8p)", sampler, + pname, param); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(sampler, pname, param); + + if (context->skipValidation() || ValidateSamplerParameteriv(context, sampler, pname, param)) + { + context->samplerParameteriv(sampler, pname, param); + } + } +} + +void GL_APIENTRY SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) +{ + EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLfloat param = %f)", sampler, pname, param); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(sampler, pname, param); + + if (context->skipValidation() || ValidateSamplerParameterf(context, sampler, pname, param)) + { + context->samplerParameterf(sampler, pname, param); + } + } +} + +void GL_APIENTRY SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param) +{ + EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, const GLfloat *param = 0x%0.8p)", sampler, + pname, param); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(sampler, pname, param); + + if (context->skipValidation() || ValidateSamplerParameterfv(context, sampler, pname, param)) + { + context->samplerParameterfv(sampler, pname, param); + } + } +} + +void GL_APIENTRY GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params) +{ + EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", sampler, pname, + params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(sampler, pname, params); + + if (context->skipValidation() || + ValidateGetSamplerParameteriv(context, sampler, pname, params)) + { + context->getSamplerParameteriv(sampler, pname, params); + } + } +} + +void GL_APIENTRY GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params) +{ + EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLfloat *params = 0x%0.8p)", sampler, pname, + params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(sampler, pname, params); + + if (context->skipValidation() || + ValidateGetSamplerParameterfv(context, sampler, pname, params)) + { + context->getSamplerParameterfv(sampler, pname, params); + } + } +} + +void GL_APIENTRY VertexAttribDivisor(GLuint index, GLuint divisor) +{ + EVENT("(GLuint index = %u, GLuint divisor = %u)", index, divisor); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(index, divisor); + + if (context->skipValidation() || ValidateVertexAttribDivisor(context, index, divisor)) + { + context->vertexAttribDivisor(index, divisor); + } + } +} + +void GL_APIENTRY BindTransformFeedback(GLenum target, GLuint id) +{ + EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, id); + + if (context->skipValidation() || ValidateBindTransformFeedback(context, target, id)) + { + context->bindTransformFeedback(target, id); + } + } +} + +void GL_APIENTRY DeleteTransformFeedbacks(GLsizei n, const GLuint *ids) +{ + EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(n, ids); + + if (context->skipValidation() || ValidateDeleteTransformFeedbacks(context, n, ids)) + { + context->deleteTransformFeedbacks(n, ids); + } + } +} + +void GL_APIENTRY GenTransformFeedbacks(GLsizei n, GLuint *ids) +{ + EVENT("(GLsizei n = %d, GLuint *ids = 0x%0.8p)", n, ids); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(n, ids); + + if (context->skipValidation() || ValidateGenTransformFeedbacks(context, n, ids)) + { + context->genTransformFeedbacks(n, ids); + } + } +} + +GLboolean GL_APIENTRY IsTransformFeedback(GLuint id) +{ + EVENT("(GLuint id = %u)", id); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(id); + + if (context->skipValidation() || ValidateIsTransformFeedback(context, id)) + { + return context->isTransformFeedback(id); + } + } + + return GetDefaultReturnValue(); +} + +void GL_APIENTRY PauseTransformFeedback() +{ + EVENT("()"); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(); + + if (context->skipValidation() || ValidatePauseTransformFeedback(context)) + { + context->pauseTransformFeedback(); + } + } +} + +void GL_APIENTRY ResumeTransformFeedback() +{ + EVENT("()"); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(); + + if (context->skipValidation() || ValidateResumeTransformFeedback(context)) + { + context->resumeTransformFeedback(); + } + } +} + +void GL_APIENTRY GetProgramBinary(GLuint program, + GLsizei bufSize, + GLsizei *length, + GLenum *binaryFormat, + void *binary) +{ + EVENT( + "(GLuint program = %u, GLsizei bufSize = %d, GLsizei *length = 0x%0.8p, GLenum " + "*binaryFormat = 0x%0.8p, void *binary = 0x%0.8p)", + program, bufSize, length, binaryFormat, binary); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, bufSize, length, binaryFormat, + binary); + + if (context->skipValidation() || + ValidateGetProgramBinary(context, program, bufSize, length, binaryFormat, binary)) + { + context->getProgramBinary(program, bufSize, length, binaryFormat, binary); + } + } +} + +void GL_APIENTRY ProgramBinary(GLuint program, + GLenum binaryFormat, + const void *binary, + GLsizei length) +{ + EVENT( + "(GLuint program = %u, GLenum binaryFormat = 0x%X, const void *binary = 0x%0.8p, GLsizei " + "length = %d)", + program, binaryFormat, binary, length); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, binaryFormat, binary, length); + + if (context->skipValidation() || + ValidateProgramBinary(context, program, binaryFormat, binary, length)) + { + context->programBinary(program, binaryFormat, binary, length); + } + } +} + +void GL_APIENTRY ProgramParameteri(GLuint program, GLenum pname, GLint value) +{ + EVENT("(GLuint program = %u, GLenum pname = 0x%X, GLint value = %d)", program, pname, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, pname, value); + + if (context->skipValidation() || ValidateProgramParameteri(context, program, pname, value)) + { + context->programParameteri(program, pname, value); + } + } +} + +void GL_APIENTRY InvalidateFramebuffer(GLenum target, + GLsizei numAttachments, + const GLenum *attachments) +{ + EVENT( + "(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum *attachments = 0x%0.8p)", + target, numAttachments, attachments); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, numAttachments, + attachments); + + if (context->skipValidation() || + ValidateInvalidateFramebuffer(context, target, numAttachments, attachments)) + { + context->invalidateFramebuffer(target, numAttachments, attachments); + } + } +} + +void GL_APIENTRY InvalidateSubFramebuffer(GLenum target, + GLsizei numAttachments, + const GLenum *attachments, + GLint x, + GLint y, + GLsizei width, + GLsizei height) +{ + EVENT( + "(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum *attachments = 0x%0.8p, " + "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", + target, numAttachments, attachments, x, y, width, height); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams( + target, numAttachments, attachments, x, y, width, height); + + if (context->skipValidation() || + ValidateInvalidateSubFramebuffer(context, target, numAttachments, attachments, x, y, + width, height)) + { + context->invalidateSubFramebuffer(target, numAttachments, attachments, x, y, width, + height); + } + } +} + +void GL_APIENTRY +TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) +{ + EVENT( + "(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = " + "%d, GLsizei height = %d)", + target, levels, internalformat, width, height); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, levels, internalformat, width, + height); + + if (context->skipValidation() || + ValidateTexStorage2D(context, target, levels, internalformat, width, height)) + { + context->texStorage2D(target, levels, internalformat, width, height); + } + } +} + +void GL_APIENTRY TexStorage3D(GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth) +{ + EVENT( + "(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = " + "%d, GLsizei height = %d, GLsizei depth = %d)", + target, levels, internalformat, width, height, depth); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, levels, internalformat, width, + height, depth); + + if (context->skipValidation() || + ValidateTexStorage3D(context, target, levels, internalformat, width, height, depth)) + { + context->texStorage3D(target, levels, internalformat, width, height, depth); + } + } +} + +void GL_APIENTRY GetInternalformativ(GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei bufSize, + GLint *params) +{ + EVENT( + "(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLenum pname = 0x%X, GLsizei bufSize " + "= %d, GLint *params = 0x%0.8p)", + target, internalformat, pname, bufSize, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, internalformat, pname, + bufSize, params); + + if (context->skipValidation() || + ValidateGetInternalformativ(context, target, internalformat, pname, bufSize, params)) + { + context->getInternalformativ(target, internalformat, pname, bufSize, params); + } + } +} +} // namespace gl diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0_autogen.h b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0_autogen.h new file mode 100644 index 0000000000..e93dde96ed --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0_autogen.h @@ -0,0 +1,284 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml. +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// entry_points_gles_3_0_autogen.h: +// Defines the GLES 3.0 entry points. + +#ifndef LIBGLESV2_ENTRYPOINTSGLES30_AUTOGEN_H_ +#define LIBGLESV2_ENTRYPOINTSGLES30_AUTOGEN_H_ + +#include +#include + +namespace gl +{ +ANGLE_EXPORT void GL_APIENTRY ReadBuffer(GLenum src); +ANGLE_EXPORT void GL_APIENTRY DrawRangeElements(GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const void *indices); +ANGLE_EXPORT void GL_APIENTRY TexImage3D(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const void *pixels); +ANGLE_EXPORT void GL_APIENTRY TexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *pixels); +ANGLE_EXPORT void GL_APIENTRY CopyTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +ANGLE_EXPORT void GL_APIENTRY CompressedTexImage3D(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const void *data); +ANGLE_EXPORT void GL_APIENTRY CompressedTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void *data); +ANGLE_EXPORT void GL_APIENTRY GenQueries(GLsizei n, GLuint *ids); +ANGLE_EXPORT void GL_APIENTRY DeleteQueries(GLsizei n, const GLuint *ids); +ANGLE_EXPORT GLboolean GL_APIENTRY IsQuery(GLuint id); +ANGLE_EXPORT void GL_APIENTRY BeginQuery(GLenum target, GLuint id); +ANGLE_EXPORT void GL_APIENTRY EndQuery(GLenum target); +ANGLE_EXPORT void GL_APIENTRY GetQueryiv(GLenum target, GLenum pname, GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params); +ANGLE_EXPORT GLboolean GL_APIENTRY UnmapBuffer(GLenum target); +ANGLE_EXPORT void GL_APIENTRY GetBufferPointerv(GLenum target, GLenum pname, void **params); +ANGLE_EXPORT void GL_APIENTRY DrawBuffers(GLsizei n, const GLenum *bufs); +ANGLE_EXPORT void GL_APIENTRY UniformMatrix2x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY UniformMatrix3x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY UniformMatrix2x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY UniformMatrix4x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY UniformMatrix3x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY UniformMatrix4x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY BlitFramebuffer(GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter); +ANGLE_EXPORT void GL_APIENTRY RenderbufferStorageMultisample(GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height); +ANGLE_EXPORT void GL_APIENTRY +FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +ANGLE_EXPORT void *GL_APIENTRY MapBufferRange(GLenum target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access); +ANGLE_EXPORT void GL_APIENTRY FlushMappedBufferRange(GLenum target, + GLintptr offset, + GLsizeiptr length); +ANGLE_EXPORT void GL_APIENTRY BindVertexArray(GLuint array); +ANGLE_EXPORT void GL_APIENTRY DeleteVertexArrays(GLsizei n, const GLuint *arrays); +ANGLE_EXPORT void GL_APIENTRY GenVertexArrays(GLsizei n, GLuint *arrays); +ANGLE_EXPORT GLboolean GL_APIENTRY IsVertexArray(GLuint array); +ANGLE_EXPORT void GL_APIENTRY GetIntegeri_v(GLenum target, GLuint index, GLint *data); +ANGLE_EXPORT void GL_APIENTRY BeginTransformFeedback(GLenum primitiveMode); +ANGLE_EXPORT void GL_APIENTRY EndTransformFeedback(); +ANGLE_EXPORT void GL_APIENTRY +BindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +ANGLE_EXPORT void GL_APIENTRY BindBufferBase(GLenum target, GLuint index, GLuint buffer); +ANGLE_EXPORT void GL_APIENTRY TransformFeedbackVaryings(GLuint program, + GLsizei count, + const GLchar *const *varyings, + GLenum bufferMode); +ANGLE_EXPORT void GL_APIENTRY GetTransformFeedbackVarying(GLuint program, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLsizei *size, + GLenum *type, + GLchar *name); +ANGLE_EXPORT void GL_APIENTRY +VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +ANGLE_EXPORT void GL_APIENTRY GetVertexAttribIiv(GLuint index, GLenum pname, GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params); +ANGLE_EXPORT void GL_APIENTRY VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w); +ANGLE_EXPORT void GL_APIENTRY +VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +ANGLE_EXPORT void GL_APIENTRY VertexAttribI4iv(GLuint index, const GLint *v); +ANGLE_EXPORT void GL_APIENTRY VertexAttribI4uiv(GLuint index, const GLuint *v); +ANGLE_EXPORT void GL_APIENTRY GetUniformuiv(GLuint program, GLint location, GLuint *params); +ANGLE_EXPORT GLint GL_APIENTRY GetFragDataLocation(GLuint program, const GLchar *name); +ANGLE_EXPORT void GL_APIENTRY Uniform1ui(GLint location, GLuint v0); +ANGLE_EXPORT void GL_APIENTRY Uniform2ui(GLint location, GLuint v0, GLuint v1); +ANGLE_EXPORT void GL_APIENTRY Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2); +ANGLE_EXPORT void GL_APIENTRY +Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +ANGLE_EXPORT void GL_APIENTRY Uniform1uiv(GLint location, GLsizei count, const GLuint *value); +ANGLE_EXPORT void GL_APIENTRY Uniform2uiv(GLint location, GLsizei count, const GLuint *value); +ANGLE_EXPORT void GL_APIENTRY Uniform3uiv(GLint location, GLsizei count, const GLuint *value); +ANGLE_EXPORT void GL_APIENTRY Uniform4uiv(GLint location, GLsizei count, const GLuint *value); +ANGLE_EXPORT void GL_APIENTRY ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value); +ANGLE_EXPORT void GL_APIENTRY ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value); +ANGLE_EXPORT void GL_APIENTRY ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY ClearBufferfi(GLenum buffer, + GLint drawbuffer, + GLfloat depth, + GLint stencil); +ANGLE_EXPORT const GLubyte *GL_APIENTRY GetStringi(GLenum name, GLuint index); +ANGLE_EXPORT void GL_APIENTRY CopyBufferSubData(GLenum readTarget, + GLenum writeTarget, + GLintptr readOffset, + GLintptr writeOffset, + GLsizeiptr size); +ANGLE_EXPORT void GL_APIENTRY GetUniformIndices(GLuint program, + GLsizei uniformCount, + const GLchar *const *uniformNames, + GLuint *uniformIndices); +ANGLE_EXPORT void GL_APIENTRY GetActiveUniformsiv(GLuint program, + GLsizei uniformCount, + const GLuint *uniformIndices, + GLenum pname, + GLint *params); +ANGLE_EXPORT GLuint GL_APIENTRY GetUniformBlockIndex(GLuint program, + const GLchar *uniformBlockName); +ANGLE_EXPORT void GL_APIENTRY GetActiveUniformBlockiv(GLuint program, + GLuint uniformBlockIndex, + GLenum pname, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetActiveUniformBlockName(GLuint program, + GLuint uniformBlockIndex, + GLsizei bufSize, + GLsizei *length, + GLchar *uniformBlockName); +ANGLE_EXPORT void GL_APIENTRY UniformBlockBinding(GLuint program, + GLuint uniformBlockIndex, + GLuint uniformBlockBinding); +ANGLE_EXPORT void GL_APIENTRY DrawArraysInstanced(GLenum mode, + GLint first, + GLsizei count, + GLsizei instancecount); +ANGLE_EXPORT void GL_APIENTRY DrawElementsInstanced(GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei instancecount); +ANGLE_EXPORT GLsync GL_APIENTRY FenceSync(GLenum condition, GLbitfield flags); +ANGLE_EXPORT GLboolean GL_APIENTRY IsSync(GLsync sync); +ANGLE_EXPORT void GL_APIENTRY DeleteSync(GLsync sync); +ANGLE_EXPORT GLenum GL_APIENTRY ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout); +ANGLE_EXPORT void GL_APIENTRY WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout); +ANGLE_EXPORT void GL_APIENTRY GetInteger64v(GLenum pname, GLint64 *data); +ANGLE_EXPORT void GL_APIENTRY +GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +ANGLE_EXPORT void GL_APIENTRY GetInteger64i_v(GLenum target, GLuint index, GLint64 *data); +ANGLE_EXPORT void GL_APIENTRY GetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params); +ANGLE_EXPORT void GL_APIENTRY GenSamplers(GLsizei count, GLuint *samplers); +ANGLE_EXPORT void GL_APIENTRY DeleteSamplers(GLsizei count, const GLuint *samplers); +ANGLE_EXPORT GLboolean GL_APIENTRY IsSampler(GLuint sampler); +ANGLE_EXPORT void GL_APIENTRY BindSampler(GLuint unit, GLuint sampler); +ANGLE_EXPORT void GL_APIENTRY SamplerParameteri(GLuint sampler, GLenum pname, GLint param); +ANGLE_EXPORT void GL_APIENTRY SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *param); +ANGLE_EXPORT void GL_APIENTRY SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param); +ANGLE_EXPORT void GL_APIENTRY SamplerParameterfv(GLuint sampler, + GLenum pname, + const GLfloat *param); +ANGLE_EXPORT void GL_APIENTRY GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params); +ANGLE_EXPORT void GL_APIENTRY VertexAttribDivisor(GLuint index, GLuint divisor); +ANGLE_EXPORT void GL_APIENTRY BindTransformFeedback(GLenum target, GLuint id); +ANGLE_EXPORT void GL_APIENTRY DeleteTransformFeedbacks(GLsizei n, const GLuint *ids); +ANGLE_EXPORT void GL_APIENTRY GenTransformFeedbacks(GLsizei n, GLuint *ids); +ANGLE_EXPORT GLboolean GL_APIENTRY IsTransformFeedback(GLuint id); +ANGLE_EXPORT void GL_APIENTRY PauseTransformFeedback(); +ANGLE_EXPORT void GL_APIENTRY ResumeTransformFeedback(); +ANGLE_EXPORT void GL_APIENTRY GetProgramBinary(GLuint program, + GLsizei bufSize, + GLsizei *length, + GLenum *binaryFormat, + void *binary); +ANGLE_EXPORT void GL_APIENTRY ProgramBinary(GLuint program, + GLenum binaryFormat, + const void *binary, + GLsizei length); +ANGLE_EXPORT void GL_APIENTRY ProgramParameteri(GLuint program, GLenum pname, GLint value); +ANGLE_EXPORT void GL_APIENTRY InvalidateFramebuffer(GLenum target, + GLsizei numAttachments, + const GLenum *attachments); +ANGLE_EXPORT void GL_APIENTRY InvalidateSubFramebuffer(GLenum target, + GLsizei numAttachments, + const GLenum *attachments, + GLint x, + GLint y, + GLsizei width, + GLsizei height); +ANGLE_EXPORT void GL_APIENTRY +TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +ANGLE_EXPORT void GL_APIENTRY TexStorage3D(GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth); +ANGLE_EXPORT void GL_APIENTRY GetInternalformativ(GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei bufSize, + GLint *params); +} // namespace gl + +#endif // LIBGLESV2_ENTRYPOINTSGLES30_AUTOGEN_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0_ext.cpp b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0_ext.cpp deleted file mode 100644 index 6f6983fd91..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0_ext.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// -// Copyright(c) 2014 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// entry_points_gles_3_0_ext.cpp : Implements the GLES 3.0 extension entry points. - -#include "libGLESv2/entry_points_gles_3_0_ext.h" -#include "libGLESv2/global_state.h" - -namespace gl -{ -} diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0_ext.h b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0_ext.h deleted file mode 100644 index fec4c1298a..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_0_ext.h +++ /dev/null @@ -1,23 +0,0 @@ -// -// Copyright(c) 2014 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// - -// entry_points_gles_3_0_ext.h : Defines the GLES 3.0 extension entry points. - -#ifndef LIBGLESV2_ENTRYPOINTGLES30EXT_H_ -#define LIBGLESV2_ENTRYPOINTGLES30EXT_H_ - -#include -#include -#include - -namespace gl -{ - -// No GLES 3.0 extensions yet - -} - -#endif // LIBGLESV2_ENTRYPOINTGLES30EXT_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_1_autogen.cpp b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_1_autogen.cpp new file mode 100644 index 0000000000..5d836872d6 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_1_autogen.cpp @@ -0,0 +1,1430 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml. +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// entry_points_gles_3_1_autogen.cpp: +// Defines the GLES 3.1 entry points. + +#include "libANGLE/Context.h" +#include "libANGLE/validationES31.h" +#include "libGLESv2/global_state.h" + +namespace gl +{ +void GL_APIENTRY DispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z) +{ + EVENT("(GLuint num_groups_x = %u, GLuint num_groups_y = %u, GLuint num_groups_z = %u)", + num_groups_x, num_groups_y, num_groups_z); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(num_groups_x, num_groups_y, + num_groups_z); + + if (context->skipValidation() || + ValidateDispatchCompute(context, num_groups_x, num_groups_y, num_groups_z)) + { + context->dispatchCompute(num_groups_x, num_groups_y, num_groups_z); + } + } +} + +void GL_APIENTRY DispatchComputeIndirect(GLintptr indirect) +{ + EVENT("(GLintptr indirect = %d)", indirect); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(indirect); + + if (context->skipValidation() || ValidateDispatchComputeIndirect(context, indirect)) + { + context->dispatchComputeIndirect(indirect); + } + } +} + +void GL_APIENTRY DrawArraysIndirect(GLenum mode, const void *indirect) +{ + EVENT("(GLenum mode = 0x%X, const void *indirect = 0x%0.8p)", mode, indirect); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(mode, indirect); + + if (context->skipValidation() || ValidateDrawArraysIndirect(context, mode, indirect)) + { + context->drawArraysIndirect(mode, indirect); + } + } +} + +void GL_APIENTRY DrawElementsIndirect(GLenum mode, GLenum type, const void *indirect) +{ + EVENT("(GLenum mode = 0x%X, GLenum type = 0x%X, const void *indirect = 0x%0.8p)", mode, type, + indirect); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(mode, type, indirect); + + if (context->skipValidation() || + ValidateDrawElementsIndirect(context, mode, type, indirect)) + { + context->drawElementsIndirect(mode, type, indirect); + } + } +} + +void GL_APIENTRY FramebufferParameteri(GLenum target, GLenum pname, GLint param) +{ + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, pname, param); + + if (context->skipValidation() || + ValidateFramebufferParameteri(context, target, pname, param)) + { + context->framebufferParameteri(target, pname, param); + } + } +} + +void GL_APIENTRY GetFramebufferParameteriv(GLenum target, GLenum pname, GLint *params) +{ + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, + params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, pname, params); + + if (context->skipValidation() || + ValidateGetFramebufferParameteriv(context, target, pname, params)) + { + context->getFramebufferParameteriv(target, pname, params); + } + } +} + +void GL_APIENTRY GetProgramInterfaceiv(GLuint program, + GLenum programInterface, + GLenum pname, + GLint *params) +{ + EVENT( + "(GLuint program = %u, GLenum programInterface = 0x%X, GLenum pname = 0x%X, GLint *params " + "= 0x%0.8p)", + program, programInterface, pname, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, programInterface, pname, + params); + + if (context->skipValidation() || + ValidateGetProgramInterfaceiv(context, program, programInterface, pname, params)) + { + context->getProgramInterfaceiv(program, programInterface, pname, params); + } + } +} + +GLuint GL_APIENTRY GetProgramResourceIndex(GLuint program, + GLenum programInterface, + const GLchar *name) +{ + EVENT("(GLuint program = %u, GLenum programInterface = 0x%X, const GLchar *name = 0x%0.8p)", + program, programInterface, name); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, programInterface, name); + + if (context->skipValidation() || + ValidateGetProgramResourceIndex(context, program, programInterface, name)) + { + return context->getProgramResourceIndex(program, programInterface, name); + } + } + + return GetDefaultReturnValue(); +} + +void GL_APIENTRY GetProgramResourceName(GLuint program, + GLenum programInterface, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name) +{ + EVENT( + "(GLuint program = %u, GLenum programInterface = 0x%X, GLuint index = %u, GLsizei bufSize " + "= %d, GLsizei *length = 0x%0.8p, GLchar *name = 0x%0.8p)", + program, programInterface, index, bufSize, length, name); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, programInterface, index, + bufSize, length, name); + + if (context->skipValidation() || + ValidateGetProgramResourceName(context, program, programInterface, index, bufSize, + length, name)) + { + context->getProgramResourceName(program, programInterface, index, bufSize, length, + name); + } + } +} + +void GL_APIENTRY GetProgramResourceiv(GLuint program, + GLenum programInterface, + GLuint index, + GLsizei propCount, + const GLenum *props, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + EVENT( + "(GLuint program = %u, GLenum programInterface = 0x%X, GLuint index = %u, GLsizei " + "propCount = %d, const GLenum *props = 0x%0.8p, GLsizei bufSize = %d, GLsizei *length = " + "0x%0.8p, GLint *params = 0x%0.8p)", + program, programInterface, index, propCount, props, bufSize, length, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams( + program, programInterface, index, propCount, props, bufSize, length, params); + + if (context->skipValidation() || + ValidateGetProgramResourceiv(context, program, programInterface, index, propCount, + props, bufSize, length, params)) + { + context->getProgramResourceiv(program, programInterface, index, propCount, props, + bufSize, length, params); + } + } +} + +GLint GL_APIENTRY GetProgramResourceLocation(GLuint program, + GLenum programInterface, + const GLchar *name) +{ + EVENT("(GLuint program = %u, GLenum programInterface = 0x%X, const GLchar *name = 0x%0.8p)", + program, programInterface, name); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, programInterface, + name); + + if (context->skipValidation() || + ValidateGetProgramResourceLocation(context, program, programInterface, name)) + { + return context->getProgramResourceLocation(program, programInterface, name); + } + } + + return GetDefaultReturnValue(); +} + +void GL_APIENTRY UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program) +{ + EVENT("(GLuint pipeline = %u, GLbitfield stages = 0x%X, GLuint program = %u)", pipeline, stages, + program); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(pipeline, stages, program); + + if (context->skipValidation() || + ValidateUseProgramStages(context, pipeline, stages, program)) + { + context->useProgramStages(pipeline, stages, program); + } + } +} + +void GL_APIENTRY ActiveShaderProgram(GLuint pipeline, GLuint program) +{ + EVENT("(GLuint pipeline = %u, GLuint program = %u)", pipeline, program); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(pipeline, program); + + if (context->skipValidation() || ValidateActiveShaderProgram(context, pipeline, program)) + { + context->activeShaderProgram(pipeline, program); + } + } +} + +GLuint GL_APIENTRY CreateShaderProgramv(GLenum type, GLsizei count, const GLchar *const *strings) +{ + EVENT("(GLenum type = 0x%X, GLsizei count = %d, const GLchar *const*strings = 0x%0.8p)", type, + count, strings); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(type, count, strings); + + if (context->skipValidation() || + ValidateCreateShaderProgramv(context, type, count, strings)) + { + return context->createShaderProgramv(type, count, strings); + } + } + + return GetDefaultReturnValue(); +} + +void GL_APIENTRY BindProgramPipeline(GLuint pipeline) +{ + EVENT("(GLuint pipeline = %u)", pipeline); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(pipeline); + + if (context->skipValidation() || ValidateBindProgramPipeline(context, pipeline)) + { + context->bindProgramPipeline(pipeline); + } + } +} + +void GL_APIENTRY DeleteProgramPipelines(GLsizei n, const GLuint *pipelines) +{ + EVENT("(GLsizei n = %d, const GLuint *pipelines = 0x%0.8p)", n, pipelines); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(n, pipelines); + + if (context->skipValidation() || ValidateDeleteProgramPipelines(context, n, pipelines)) + { + context->deleteProgramPipelines(n, pipelines); + } + } +} + +void GL_APIENTRY GenProgramPipelines(GLsizei n, GLuint *pipelines) +{ + EVENT("(GLsizei n = %d, GLuint *pipelines = 0x%0.8p)", n, pipelines); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(n, pipelines); + + if (context->skipValidation() || ValidateGenProgramPipelines(context, n, pipelines)) + { + context->genProgramPipelines(n, pipelines); + } + } +} + +GLboolean GL_APIENTRY IsProgramPipeline(GLuint pipeline) +{ + EVENT("(GLuint pipeline = %u)", pipeline); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(pipeline); + + if (context->skipValidation() || ValidateIsProgramPipeline(context, pipeline)) + { + return context->isProgramPipeline(pipeline); + } + } + + return GetDefaultReturnValue(); +} + +void GL_APIENTRY GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params) +{ + EVENT("(GLuint pipeline = %u, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", pipeline, pname, + params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(pipeline, pname, params); + + if (context->skipValidation() || + ValidateGetProgramPipelineiv(context, pipeline, pname, params)) + { + context->getProgramPipelineiv(pipeline, pname, params); + } + } +} + +void GL_APIENTRY ProgramUniform1i(GLuint program, GLint location, GLint v0) +{ + EVENT("(GLuint program = %u, GLint location = %d, GLint v0 = %d)", program, location, v0); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, v0); + + if (context->skipValidation() || ValidateProgramUniform1i(context, program, location, v0)) + { + context->programUniform1i(program, location, v0); + } + } +} + +void GL_APIENTRY ProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1) +{ + EVENT("(GLuint program = %u, GLint location = %d, GLint v0 = %d, GLint v1 = %d)", program, + location, v0, v1); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, v0, v1); + + if (context->skipValidation() || + ValidateProgramUniform2i(context, program, location, v0, v1)) + { + context->programUniform2i(program, location, v0, v1); + } + } +} + +void GL_APIENTRY ProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2) +{ + EVENT("(GLuint program = %u, GLint location = %d, GLint v0 = %d, GLint v1 = %d, GLint v2 = %d)", + program, location, v0, v1, v2); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, v0, v1, v2); + + if (context->skipValidation() || + ValidateProgramUniform3i(context, program, location, v0, v1, v2)) + { + context->programUniform3i(program, location, v0, v1, v2); + } + } +} + +void GL_APIENTRY +ProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLint v0 = %d, GLint v1 = %d, GLint v2 = %d, " + "GLint v3 = %d)", + program, location, v0, v1, v2, v3); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, v0, v1, v2, v3); + + if (context->skipValidation() || + ValidateProgramUniform4i(context, program, location, v0, v1, v2, v3)) + { + context->programUniform4i(program, location, v0, v1, v2, v3); + } + } +} + +void GL_APIENTRY ProgramUniform1ui(GLuint program, GLint location, GLuint v0) +{ + EVENT("(GLuint program = %u, GLint location = %d, GLuint v0 = %u)", program, location, v0); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, v0); + + if (context->skipValidation() || ValidateProgramUniform1ui(context, program, location, v0)) + { + context->programUniform1ui(program, location, v0); + } + } +} + +void GL_APIENTRY ProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1) +{ + EVENT("(GLuint program = %u, GLint location = %d, GLuint v0 = %u, GLuint v1 = %u)", program, + location, v0, v1); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, v0, v1); + + if (context->skipValidation() || + ValidateProgramUniform2ui(context, program, location, v0, v1)) + { + context->programUniform2ui(program, location, v0, v1); + } + } +} + +void GL_APIENTRY ProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLuint v0 = %u, GLuint v1 = %u, GLuint v2 = " + "%u)", + program, location, v0, v1, v2); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, v0, v1, v2); + + if (context->skipValidation() || + ValidateProgramUniform3ui(context, program, location, v0, v1, v2)) + { + context->programUniform3ui(program, location, v0, v1, v2); + } + } +} + +void GL_APIENTRY +ProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLuint v0 = %u, GLuint v1 = %u, GLuint v2 = " + "%u, GLuint v3 = %u)", + program, location, v0, v1, v2, v3); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, v0, v1, v2, v3); + + if (context->skipValidation() || + ValidateProgramUniform4ui(context, program, location, v0, v1, v2, v3)) + { + context->programUniform4ui(program, location, v0, v1, v2, v3); + } + } +} + +void GL_APIENTRY ProgramUniform1f(GLuint program, GLint location, GLfloat v0) +{ + EVENT("(GLuint program = %u, GLint location = %d, GLfloat v0 = %f)", program, location, v0); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, v0); + + if (context->skipValidation() || ValidateProgramUniform1f(context, program, location, v0)) + { + context->programUniform1f(program, location, v0); + } + } +} + +void GL_APIENTRY ProgramUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1) +{ + EVENT("(GLuint program = %u, GLint location = %d, GLfloat v0 = %f, GLfloat v1 = %f)", program, + location, v0, v1); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, v0, v1); + + if (context->skipValidation() || + ValidateProgramUniform2f(context, program, location, v0, v1)) + { + context->programUniform2f(program, location, v0, v1); + } + } +} + +void GL_APIENTRY +ProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLfloat v0 = %f, GLfloat v1 = %f, GLfloat v2 = " + "%f)", + program, location, v0, v1, v2); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, v0, v1, v2); + + if (context->skipValidation() || + ValidateProgramUniform3f(context, program, location, v0, v1, v2)) + { + context->programUniform3f(program, location, v0, v1, v2); + } + } +} + +void GL_APIENTRY +ProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLfloat v0 = %f, GLfloat v1 = %f, GLfloat v2 = " + "%f, GLfloat v3 = %f)", + program, location, v0, v1, v2, v3); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, v0, v1, v2, v3); + + if (context->skipValidation() || + ValidateProgramUniform4f(context, program, location, v0, v1, v2, v3)) + { + context->programUniform4f(program, location, v0, v1, v2, v3); + } + } +} + +void GL_APIENTRY ProgramUniform1iv(GLuint program, + GLint location, + GLsizei count, + const GLint *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLint *value = " + "0x%0.8p)", + program, location, count, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, count, value); + + if (context->skipValidation() || + ValidateProgramUniform1iv(context, program, location, count, value)) + { + context->programUniform1iv(program, location, count, value); + } + } +} + +void GL_APIENTRY ProgramUniform2iv(GLuint program, + GLint location, + GLsizei count, + const GLint *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLint *value = " + "0x%0.8p)", + program, location, count, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, count, value); + + if (context->skipValidation() || + ValidateProgramUniform2iv(context, program, location, count, value)) + { + context->programUniform2iv(program, location, count, value); + } + } +} + +void GL_APIENTRY ProgramUniform3iv(GLuint program, + GLint location, + GLsizei count, + const GLint *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLint *value = " + "0x%0.8p)", + program, location, count, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, count, value); + + if (context->skipValidation() || + ValidateProgramUniform3iv(context, program, location, count, value)) + { + context->programUniform3iv(program, location, count, value); + } + } +} + +void GL_APIENTRY ProgramUniform4iv(GLuint program, + GLint location, + GLsizei count, + const GLint *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLint *value = " + "0x%0.8p)", + program, location, count, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, count, value); + + if (context->skipValidation() || + ValidateProgramUniform4iv(context, program, location, count, value)) + { + context->programUniform4iv(program, location, count, value); + } + } +} + +void GL_APIENTRY ProgramUniform1uiv(GLuint program, + GLint location, + GLsizei count, + const GLuint *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLuint *value = " + "0x%0.8p)", + program, location, count, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, count, value); + + if (context->skipValidation() || + ValidateProgramUniform1uiv(context, program, location, count, value)) + { + context->programUniform1uiv(program, location, count, value); + } + } +} + +void GL_APIENTRY ProgramUniform2uiv(GLuint program, + GLint location, + GLsizei count, + const GLuint *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLuint *value = " + "0x%0.8p)", + program, location, count, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, count, value); + + if (context->skipValidation() || + ValidateProgramUniform2uiv(context, program, location, count, value)) + { + context->programUniform2uiv(program, location, count, value); + } + } +} + +void GL_APIENTRY ProgramUniform3uiv(GLuint program, + GLint location, + GLsizei count, + const GLuint *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLuint *value = " + "0x%0.8p)", + program, location, count, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, count, value); + + if (context->skipValidation() || + ValidateProgramUniform3uiv(context, program, location, count, value)) + { + context->programUniform3uiv(program, location, count, value); + } + } +} + +void GL_APIENTRY ProgramUniform4uiv(GLuint program, + GLint location, + GLsizei count, + const GLuint *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLuint *value = " + "0x%0.8p)", + program, location, count, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, count, value); + + if (context->skipValidation() || + ValidateProgramUniform4uiv(context, program, location, count, value)) + { + context->programUniform4uiv(program, location, count, value); + } + } +} + +void GL_APIENTRY ProgramUniform1fv(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLfloat *value = " + "0x%0.8p)", + program, location, count, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, count, value); + + if (context->skipValidation() || + ValidateProgramUniform1fv(context, program, location, count, value)) + { + context->programUniform1fv(program, location, count, value); + } + } +} + +void GL_APIENTRY ProgramUniform2fv(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLfloat *value = " + "0x%0.8p)", + program, location, count, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, count, value); + + if (context->skipValidation() || + ValidateProgramUniform2fv(context, program, location, count, value)) + { + context->programUniform2fv(program, location, count, value); + } + } +} + +void GL_APIENTRY ProgramUniform3fv(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLfloat *value = " + "0x%0.8p)", + program, location, count, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, count, value); + + if (context->skipValidation() || + ValidateProgramUniform3fv(context, program, location, count, value)) + { + context->programUniform3fv(program, location, count, value); + } + } +} + +void GL_APIENTRY ProgramUniform4fv(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, const GLfloat *value = " + "0x%0.8p)", + program, location, count, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, count, value); + + if (context->skipValidation() || + ValidateProgramUniform4fv(context, program, location, count, value)) + { + context->programUniform4fv(program, location, count, value); + } + } +} + +void GL_APIENTRY ProgramUniformMatrix2fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, " + "const GLfloat *value = 0x%0.8p)", + program, location, count, transpose, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, count, + transpose, value); + + if (context->skipValidation() || + ValidateProgramUniformMatrix2fv(context, program, location, count, transpose, value)) + { + context->programUniformMatrix2fv(program, location, count, transpose, value); + } + } +} + +void GL_APIENTRY ProgramUniformMatrix3fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, " + "const GLfloat *value = 0x%0.8p)", + program, location, count, transpose, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, count, + transpose, value); + + if (context->skipValidation() || + ValidateProgramUniformMatrix3fv(context, program, location, count, transpose, value)) + { + context->programUniformMatrix3fv(program, location, count, transpose, value); + } + } +} + +void GL_APIENTRY ProgramUniformMatrix4fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, " + "const GLfloat *value = 0x%0.8p)", + program, location, count, transpose, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, count, + transpose, value); + + if (context->skipValidation() || + ValidateProgramUniformMatrix4fv(context, program, location, count, transpose, value)) + { + context->programUniformMatrix4fv(program, location, count, transpose, value); + } + } +} + +void GL_APIENTRY ProgramUniformMatrix2x3fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, " + "const GLfloat *value = 0x%0.8p)", + program, location, count, transpose, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, count, + transpose, value); + + if (context->skipValidation() || + ValidateProgramUniformMatrix2x3fv(context, program, location, count, transpose, value)) + { + context->programUniformMatrix2x3fv(program, location, count, transpose, value); + } + } +} + +void GL_APIENTRY ProgramUniformMatrix3x2fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, " + "const GLfloat *value = 0x%0.8p)", + program, location, count, transpose, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, count, + transpose, value); + + if (context->skipValidation() || + ValidateProgramUniformMatrix3x2fv(context, program, location, count, transpose, value)) + { + context->programUniformMatrix3x2fv(program, location, count, transpose, value); + } + } +} + +void GL_APIENTRY ProgramUniformMatrix2x4fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, " + "const GLfloat *value = 0x%0.8p)", + program, location, count, transpose, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, count, + transpose, value); + + if (context->skipValidation() || + ValidateProgramUniformMatrix2x4fv(context, program, location, count, transpose, value)) + { + context->programUniformMatrix2x4fv(program, location, count, transpose, value); + } + } +} + +void GL_APIENTRY ProgramUniformMatrix4x2fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, " + "const GLfloat *value = 0x%0.8p)", + program, location, count, transpose, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, count, + transpose, value); + + if (context->skipValidation() || + ValidateProgramUniformMatrix4x2fv(context, program, location, count, transpose, value)) + { + context->programUniformMatrix4x2fv(program, location, count, transpose, value); + } + } +} + +void GL_APIENTRY ProgramUniformMatrix3x4fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, " + "const GLfloat *value = 0x%0.8p)", + program, location, count, transpose, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, count, + transpose, value); + + if (context->skipValidation() || + ValidateProgramUniformMatrix3x4fv(context, program, location, count, transpose, value)) + { + context->programUniformMatrix3x4fv(program, location, count, transpose, value); + } + } +} + +void GL_APIENTRY ProgramUniformMatrix4x3fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + EVENT( + "(GLuint program = %u, GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, " + "const GLfloat *value = 0x%0.8p)", + program, location, count, transpose, value); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(program, location, count, + transpose, value); + + if (context->skipValidation() || + ValidateProgramUniformMatrix4x3fv(context, program, location, count, transpose, value)) + { + context->programUniformMatrix4x3fv(program, location, count, transpose, value); + } + } +} + +void GL_APIENTRY ValidateProgramPipeline(GLuint pipeline) +{ + EVENT("(GLuint pipeline = %u)", pipeline); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(pipeline); + + if (context->skipValidation() || ValidateValidateProgramPipeline(context, pipeline)) + { + context->validateProgramPipeline(pipeline); + } + } +} + +void GL_APIENTRY GetProgramPipelineInfoLog(GLuint pipeline, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog) +{ + EVENT( + "(GLuint pipeline = %u, GLsizei bufSize = %d, GLsizei *length = 0x%0.8p, GLchar *infoLog = " + "0x%0.8p)", + pipeline, bufSize, length, infoLog); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(pipeline, bufSize, length, + infoLog); + + if (context->skipValidation() || + ValidateGetProgramPipelineInfoLog(context, pipeline, bufSize, length, infoLog)) + { + context->getProgramPipelineInfoLog(pipeline, bufSize, length, infoLog); + } + } +} + +void GL_APIENTRY BindImageTexture(GLuint unit, + GLuint texture, + GLint level, + GLboolean layered, + GLint layer, + GLenum access, + GLenum format) +{ + EVENT( + "(GLuint unit = %u, GLuint texture = %u, GLint level = %d, GLboolean layered = %u, GLint " + "layer = %d, GLenum access = 0x%X, GLenum format = 0x%X)", + unit, texture, level, layered, layer, access, format); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(unit, texture, level, layered, layer, + access, format); + + if (context->skipValidation() || + ValidateBindImageTexture(context, unit, texture, level, layered, layer, access, format)) + { + context->bindImageTexture(unit, texture, level, layered, layer, access, format); + } + } +} + +void GL_APIENTRY GetBooleani_v(GLenum target, GLuint index, GLboolean *data) +{ + EVENT("(GLenum target = 0x%X, GLuint index = %u, GLboolean *data = 0x%0.8p)", target, index, + data); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, index, data); + + if (context->skipValidation() || ValidateGetBooleani_v(context, target, index, data)) + { + context->getBooleani_v(target, index, data); + } + } +} + +void GL_APIENTRY MemoryBarrier(GLbitfield barriers) +{ + EVENT("(GLbitfield barriers = 0x%X)", barriers); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(barriers); + + if (context->skipValidation() || ValidateMemoryBarrier(context, barriers)) + { + context->memoryBarrier(barriers); + } + } +} + +void GL_APIENTRY MemoryBarrierByRegion(GLbitfield barriers) +{ + EVENT("(GLbitfield barriers = 0x%X)", barriers); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(barriers); + + if (context->skipValidation() || ValidateMemoryBarrierByRegion(context, barriers)) + { + context->memoryBarrierByRegion(barriers); + } + } +} + +void GL_APIENTRY TexStorage2DMultisample(GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations) +{ + EVENT( + "(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width " + "= %d, GLsizei height = %d, GLboolean fixedsamplelocations = %u)", + target, samples, internalformat, width, height, fixedsamplelocations); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams( + target, samples, internalformat, width, height, fixedsamplelocations); + + if (context->skipValidation() || + ValidateTexStorage2DMultisample(context, target, samples, internalformat, width, height, + fixedsamplelocations)) + { + context->texStorage2DMultisample(target, samples, internalformat, width, height, + fixedsamplelocations); + } + } +} + +void GL_APIENTRY GetMultisamplefv(GLenum pname, GLuint index, GLfloat *val) +{ + EVENT("(GLenum pname = 0x%X, GLuint index = %u, GLfloat *val = 0x%0.8p)", pname, index, val); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(pname, index, val); + + if (context->skipValidation() || ValidateGetMultisamplefv(context, pname, index, val)) + { + context->getMultisamplefv(pname, index, val); + } + } +} + +void GL_APIENTRY SampleMaski(GLuint maskNumber, GLbitfield mask) +{ + EVENT("(GLuint maskNumber = %u, GLbitfield mask = 0x%X)", maskNumber, mask); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(maskNumber, mask); + + if (context->skipValidation() || ValidateSampleMaski(context, maskNumber, mask)) + { + context->sampleMaski(maskNumber, mask); + } + } +} + +void GL_APIENTRY GetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) +{ + EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", + target, level, pname, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, level, pname, params); + + if (context->skipValidation() || + ValidateGetTexLevelParameteriv(context, target, level, pname, params)) + { + context->getTexLevelParameteriv(target, level, pname, params); + } + } +} + +void GL_APIENTRY GetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params) +{ + EVENT( + "(GLenum target = 0x%X, GLint level = %d, GLenum pname = 0x%X, GLfloat *params = 0x%0.8p)", + target, level, pname, params); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(target, level, pname, params); + + if (context->skipValidation() || + ValidateGetTexLevelParameterfv(context, target, level, pname, params)) + { + context->getTexLevelParameterfv(target, level, pname, params); + } + } +} + +void GL_APIENTRY BindVertexBuffer(GLuint bindingindex, + GLuint buffer, + GLintptr offset, + GLsizei stride) +{ + EVENT( + "(GLuint bindingindex = %u, GLuint buffer = %u, GLintptr offset = %d, GLsizei stride = %d)", + bindingindex, buffer, offset, stride); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(bindingindex, buffer, offset, stride); + + if (context->skipValidation() || + ValidateBindVertexBuffer(context, bindingindex, buffer, offset, stride)) + { + context->bindVertexBuffer(bindingindex, buffer, offset, stride); + } + } +} + +void GL_APIENTRY VertexAttribFormat(GLuint attribindex, + GLint size, + GLenum type, + GLboolean normalized, + GLuint relativeoffset) +{ + EVENT( + "(GLuint attribindex = %u, GLint size = %d, GLenum type = 0x%X, GLboolean normalized = %u, " + "GLuint relativeoffset = %u)", + attribindex, size, type, normalized, relativeoffset); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(attribindex, size, type, normalized, + relativeoffset); + + if (context->skipValidation() || + ValidateVertexAttribFormat(context, attribindex, size, type, normalized, + relativeoffset)) + { + context->vertexAttribFormat(attribindex, size, type, normalized, relativeoffset); + } + } +} + +void GL_APIENTRY VertexAttribIFormat(GLuint attribindex, + GLint size, + GLenum type, + GLuint relativeoffset) +{ + EVENT( + "(GLuint attribindex = %u, GLint size = %d, GLenum type = 0x%X, GLuint relativeoffset = " + "%u)", + attribindex, size, type, relativeoffset); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(attribindex, size, type, + relativeoffset); + + if (context->skipValidation() || + ValidateVertexAttribIFormat(context, attribindex, size, type, relativeoffset)) + { + context->vertexAttribIFormat(attribindex, size, type, relativeoffset); + } + } +} + +void GL_APIENTRY VertexAttribBinding(GLuint attribindex, GLuint bindingindex) +{ + EVENT("(GLuint attribindex = %u, GLuint bindingindex = %u)", attribindex, bindingindex); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(attribindex, bindingindex); + + if (context->skipValidation() || + ValidateVertexAttribBinding(context, attribindex, bindingindex)) + { + context->vertexAttribBinding(attribindex, bindingindex); + } + } +} + +void GL_APIENTRY VertexBindingDivisor(GLuint bindingindex, GLuint divisor) +{ + EVENT("(GLuint bindingindex = %u, GLuint divisor = %u)", bindingindex, divisor); + + Context *context = GetValidGlobalContext(); + if (context) + { + context->gatherParams(bindingindex, divisor); + + if (context->skipValidation() || + ValidateVertexBindingDivisor(context, bindingindex, divisor)) + { + context->vertexBindingDivisor(bindingindex, divisor); + } + } +} +} // namespace gl diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_1_autogen.h b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_1_autogen.h new file mode 100644 index 0000000000..e11d5a10bf --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/entry_points_gles_3_1_autogen.h @@ -0,0 +1,228 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by generate_entry_points.py using data from gl.xml. +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// entry_points_gles_3_1_autogen.h: +// Defines the GLES 3.1 entry points. + +#ifndef LIBGLESV2_ENTRYPOINTSGLES31_AUTOGEN_H_ +#define LIBGLESV2_ENTRYPOINTSGLES31_AUTOGEN_H_ + +#include +#include + +#include "common/platform.h" + +namespace gl +{ +ANGLE_EXPORT void GL_APIENTRY DispatchCompute(GLuint num_groups_x, + GLuint num_groups_y, + GLuint num_groups_z); +ANGLE_EXPORT void GL_APIENTRY DispatchComputeIndirect(GLintptr indirect); +ANGLE_EXPORT void GL_APIENTRY DrawArraysIndirect(GLenum mode, const void *indirect); +ANGLE_EXPORT void GL_APIENTRY DrawElementsIndirect(GLenum mode, GLenum type, const void *indirect); +ANGLE_EXPORT void GL_APIENTRY FramebufferParameteri(GLenum target, GLenum pname, GLint param); +ANGLE_EXPORT void GL_APIENTRY GetFramebufferParameteriv(GLenum target, GLenum pname, GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetProgramInterfaceiv(GLuint program, + GLenum programInterface, + GLenum pname, + GLint *params); +ANGLE_EXPORT GLuint GL_APIENTRY GetProgramResourceIndex(GLuint program, + GLenum programInterface, + const GLchar *name); +ANGLE_EXPORT void GL_APIENTRY GetProgramResourceName(GLuint program, + GLenum programInterface, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name); +ANGLE_EXPORT void GL_APIENTRY GetProgramResourceiv(GLuint program, + GLenum programInterface, + GLuint index, + GLsizei propCount, + const GLenum *props, + GLsizei bufSize, + GLsizei *length, + GLint *params); +ANGLE_EXPORT GLint GL_APIENTRY GetProgramResourceLocation(GLuint program, + GLenum programInterface, + const GLchar *name); +ANGLE_EXPORT void GL_APIENTRY UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program); +ANGLE_EXPORT void GL_APIENTRY ActiveShaderProgram(GLuint pipeline, GLuint program); +ANGLE_EXPORT GLuint GL_APIENTRY CreateShaderProgramv(GLenum type, + GLsizei count, + const GLchar *const *strings); +ANGLE_EXPORT void GL_APIENTRY BindProgramPipeline(GLuint pipeline); +ANGLE_EXPORT void GL_APIENTRY DeleteProgramPipelines(GLsizei n, const GLuint *pipelines); +ANGLE_EXPORT void GL_APIENTRY GenProgramPipelines(GLsizei n, GLuint *pipelines); +ANGLE_EXPORT GLboolean GL_APIENTRY IsProgramPipeline(GLuint pipeline); +ANGLE_EXPORT void GL_APIENTRY GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform1i(GLuint program, GLint location, GLint v0); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1); +ANGLE_EXPORT void GL_APIENTRY +ProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +ANGLE_EXPORT void GL_APIENTRY +ProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform1ui(GLuint program, GLint location, GLuint v0); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform2ui(GLuint program, + GLint location, + GLuint v0, + GLuint v1); +ANGLE_EXPORT void GL_APIENTRY +ProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +ANGLE_EXPORT void GL_APIENTRY +ProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform1f(GLuint program, GLint location, GLfloat v0); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform2f(GLuint program, + GLint location, + GLfloat v0, + GLfloat v1); +ANGLE_EXPORT void GL_APIENTRY +ProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +ANGLE_EXPORT void GL_APIENTRY +ProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform1iv(GLuint program, + GLint location, + GLsizei count, + const GLint *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform2iv(GLuint program, + GLint location, + GLsizei count, + const GLint *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform3iv(GLuint program, + GLint location, + GLsizei count, + const GLint *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform4iv(GLuint program, + GLint location, + GLsizei count, + const GLint *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform1uiv(GLuint program, + GLint location, + GLsizei count, + const GLuint *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform2uiv(GLuint program, + GLint location, + GLsizei count, + const GLuint *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform3uiv(GLuint program, + GLint location, + GLsizei count, + const GLuint *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform4uiv(GLuint program, + GLint location, + GLsizei count, + const GLuint *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform1fv(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform2fv(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform3fv(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniform4fv(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix2fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix3fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix4fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix2x3fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix3x2fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix2x4fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix4x2fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix3x4fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY ProgramUniformMatrix4x3fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value); +ANGLE_EXPORT void GL_APIENTRY ValidateProgramPipeline(GLuint pipeline); +ANGLE_EXPORT void GL_APIENTRY GetProgramPipelineInfoLog(GLuint pipeline, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog); +ANGLE_EXPORT void GL_APIENTRY BindImageTexture(GLuint unit, + GLuint texture, + GLint level, + GLboolean layered, + GLint layer, + GLenum access, + GLenum format); +ANGLE_EXPORT void GL_APIENTRY GetBooleani_v(GLenum target, GLuint index, GLboolean *data); +ANGLE_EXPORT void GL_APIENTRY MemoryBarrier(GLbitfield barriers); +ANGLE_EXPORT void GL_APIENTRY MemoryBarrierByRegion(GLbitfield barriers); +ANGLE_EXPORT void GL_APIENTRY TexStorage2DMultisample(GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations); +ANGLE_EXPORT void GL_APIENTRY GetMultisamplefv(GLenum pname, GLuint index, GLfloat *val); +ANGLE_EXPORT void GL_APIENTRY SampleMaski(GLuint maskNumber, GLbitfield mask); +ANGLE_EXPORT void GL_APIENTRY GetTexLevelParameteriv(GLenum target, + GLint level, + GLenum pname, + GLint *params); +ANGLE_EXPORT void GL_APIENTRY GetTexLevelParameterfv(GLenum target, + GLint level, + GLenum pname, + GLfloat *params); +ANGLE_EXPORT void GL_APIENTRY BindVertexBuffer(GLuint bindingindex, + GLuint buffer, + GLintptr offset, + GLsizei stride); +ANGLE_EXPORT void GL_APIENTRY VertexAttribFormat(GLuint attribindex, + GLint size, + GLenum type, + GLboolean normalized, + GLuint relativeoffset); +ANGLE_EXPORT void GL_APIENTRY VertexAttribIFormat(GLuint attribindex, + GLint size, + GLenum type, + GLuint relativeoffset); +ANGLE_EXPORT void GL_APIENTRY VertexAttribBinding(GLuint attribindex, GLuint bindingindex); +ANGLE_EXPORT void GL_APIENTRY VertexBindingDivisor(GLuint bindingindex, GLuint divisor); +} // namespace gl + +#endif // LIBGLESV2_ENTRYPOINTSGLES31_AUTOGEN_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/global_state.cpp b/src/3rdparty/angle/src/libGLESv2/global_state.cpp index b99c3e1ca9..c5f3dfe4e1 100644 --- a/src/3rdparty/angle/src/libGLESv2/global_state.cpp +++ b/src/3rdparty/angle/src/libGLESv2/global_state.cpp @@ -8,229 +8,141 @@ #include "libGLESv2/global_state.h" -#include "libANGLE/Context.h" -#include "libANGLE/Error.h" - #include "common/debug.h" #include "common/platform.h" #include "common/tls.h" -namespace -{ - -static TLSIndex currentTLS = TLS_INVALID_INDEX; - -struct Current -{ - EGLint error; - EGLenum API; - egl::Display *display; - egl::Surface *drawSurface; - egl::Surface *readSurface; - gl::Context *context; -}; - -Current *AllocateCurrent() -{ - ASSERT(currentTLS != TLS_INVALID_INDEX); - if (currentTLS == TLS_INVALID_INDEX) - { - return NULL; - } - - Current *current = new Current(); - current->error = EGL_SUCCESS; - current->API = EGL_OPENGL_ES_API; - current->display = reinterpret_cast(EGL_NO_DISPLAY); - current->drawSurface = reinterpret_cast(EGL_NO_SURFACE); - current->readSurface = reinterpret_cast(EGL_NO_SURFACE); - current->context = reinterpret_cast(EGL_NO_CONTEXT); - - if (!SetTLSValue(currentTLS, current)) - { - ERR("Could not set thread local storage."); - return NULL; - } - - return current; -} - -Current *GetCurrentData() -{ - // Create a TLS index if one has not been created for this DLL - if (currentTLS == TLS_INVALID_INDEX) - { - currentTLS = CreateTLSIndex(); - } - - Current *current = reinterpret_cast(GetTLSValue(currentTLS)); - - // ANGLE issue 488: when the dll is loaded after thread initialization, - // thread local storage (current) might not exist yet. - return (current ? current : AllocateCurrent()); -} - -#ifdef ANGLE_PLATFORM_WINDOWS - -void DeallocateCurrent() -{ - Current *current = reinterpret_cast(GetTLSValue(currentTLS)); - SafeDelete(current); - SetTLSValue(currentTLS, NULL); -} - -extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD reason, LPVOID) -{ - switch (reason) - { - case DLL_PROCESS_ATTACH: - currentTLS = CreateTLSIndex(); - if (currentTLS == TLS_INVALID_INDEX) - { - return FALSE; - } - AllocateCurrent(); - break; - - case DLL_THREAD_ATTACH: - AllocateCurrent(); - break; - - case DLL_THREAD_DETACH: - DeallocateCurrent(); - break; - - case DLL_PROCESS_DETACH: - DeallocateCurrent(); - if (currentTLS != TLS_INVALID_INDEX) - { - DestroyTLSIndex(currentTLS); - currentTLS = TLS_INVALID_INDEX; - } - break; - } - - return TRUE; -} -#endif - -} +#include "libANGLE/Thread.h" namespace gl { Context *GetGlobalContext() { - Current *current = GetCurrentData(); - - return current->context; + egl::Thread *thread = egl::GetCurrentThread(); + return thread->getContext(); } Context *GetValidGlobalContext() { - gl::Context *context = GetGlobalContext(); - if (context) - { - if (context->isContextLost()) - { - context->recordError(gl::Error(GL_OUT_OF_MEMORY, "Context has been lost.")); - return nullptr; - } - else - { - return context; - } - } - return nullptr; + egl::Thread *thread = egl::GetCurrentThread(); + return thread->getValidContext(); } -} +} // namespace gl namespace egl { -void SetGlobalError(const Error &error) +namespace { - Current *current = GetCurrentData(); - current->error = error.getCode(); -} +static TLSIndex threadTLS = TLS_INVALID_INDEX; -EGLint GetGlobalError() +Thread *AllocateCurrentThread() { - Current *current = GetCurrentData(); + ASSERT(threadTLS != TLS_INVALID_INDEX); + if (threadTLS == TLS_INVALID_INDEX) + { + return nullptr; + } - return current->error; + Thread *thread = new Thread(); + if (!SetTLSValue(threadTLS, thread)) + { + ERR() << "Could not set thread local storage."; + return nullptr; + } + + return thread; } -EGLenum GetGlobalAPI() +} // anonymous namespace + +Thread *GetCurrentThread() { - Current *current = GetCurrentData(); + // Create a TLS index if one has not been created for this DLL + if (threadTLS == TLS_INVALID_INDEX) + { + threadTLS = CreateTLSIndex(); + } - return current->API; + Thread *current = static_cast(GetTLSValue(threadTLS)); + + // ANGLE issue 488: when the dll is loaded after thread initialization, + // thread local storage (current) might not exist yet. + return (current ? current : AllocateCurrentThread()); } -void SetGlobalAPI(EGLenum API) +} // namespace egl + +#ifdef ANGLE_PLATFORM_WINDOWS +namespace egl { - Current *current = GetCurrentData(); - current->API = API; -} - -void SetGlobalDisplay(Display *dpy) +namespace { - Current *current = GetCurrentData(); - current->display = dpy; -} - -Display *GetGlobalDisplay() +bool DeallocateCurrentThread() { - Current *current = GetCurrentData(); - - return current->display; + Thread *thread = static_cast(GetTLSValue(threadTLS)); + SafeDelete(thread); + return SetTLSValue(threadTLS, nullptr); } -void SetGlobalDrawSurface(Surface *surface) +bool InitializeProcess() { - Current *current = GetCurrentData(); + threadTLS = CreateTLSIndex(); + if (threadTLS == TLS_INVALID_INDEX) + { + return false; + } - current->drawSurface = surface; + return AllocateCurrentThread() != nullptr; } -Surface *GetGlobalDrawSurface() +bool TerminateProcess() { - Current *current = GetCurrentData(); + if (!DeallocateCurrentThread()) + { + return false; + } - return current->drawSurface; + if (threadTLS != TLS_INVALID_INDEX) + { + TLSIndex tlsCopy = threadTLS; + threadTLS = TLS_INVALID_INDEX; + + if (!DestroyTLSIndex(tlsCopy)) + { + return false; + } + } + + return true; } -void SetGlobalReadSurface(Surface *surface) +} // anonymous namespace + +} // namespace egl + +extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD reason, LPVOID) { - Current *current = GetCurrentData(); - - current->readSurface = surface; -} - -Surface *GetGlobalReadSurface() -{ - Current *current = GetCurrentData(); - - return current->readSurface; -} - -void SetGlobalContext(gl::Context *context) -{ - Current *current = GetCurrentData(); - - current->context = context; -} - -gl::Context *GetGlobalContext() -{ - Current *current = GetCurrentData(); - - return current->context; -} + switch (reason) + { + case DLL_PROCESS_ATTACH: + return static_cast(egl::InitializeProcess()); + case DLL_THREAD_ATTACH: + return static_cast(egl::AllocateCurrentThread() != nullptr); + + case DLL_THREAD_DETACH: + return static_cast(egl::DeallocateCurrentThread()); + + case DLL_PROCESS_DETACH: + return static_cast(egl::TerminateProcess()); + } + + return TRUE; } +#endif // ANGLE_PLATFORM_WINDOWS diff --git a/src/3rdparty/angle/src/libGLESv2/global_state.h b/src/3rdparty/angle/src/libGLESv2/global_state.h index db202539cb..3e3740c90e 100644 --- a/src/3rdparty/angle/src/libGLESv2/global_state.h +++ b/src/3rdparty/angle/src/libGLESv2/global_state.h @@ -9,8 +9,6 @@ #ifndef LIBGLESV2_GLOBALSTATE_H_ #define LIBGLESV2_GLOBALSTATE_H_ -#include - namespace gl { class Context; @@ -18,32 +16,14 @@ class Context; Context *GetGlobalContext(); Context *GetValidGlobalContext(); -} +} // namespace gl namespace egl { -class Error; -class Display; -class Surface; +class Thread; -void SetGlobalError(const Error &error); -EGLint GetGlobalError(); +Thread *GetCurrentThread(); -void SetGlobalAPI(EGLenum API); -EGLenum GetGlobalAPI(); - -void SetGlobalDisplay(Display *dpy); -Display *GetGlobalDisplay(); - -void SetGlobalDrawSurface(Surface *surface); -Surface *GetGlobalDrawSurface(); - -void SetGlobalReadSurface(Surface *surface); -Surface *GetGlobalReadSurface(); - -void SetGlobalContext(gl::Context *context); -gl::Context *GetGlobalContext(); - -} +} // namespace egl #endif // LIBGLESV2_GLOBALSTATE_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp index 42b749f373..ffd78a2ac0 100644 --- a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp +++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp @@ -6,14 +6,14 @@ // libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions. -#include "libGLESv2/entry_points_gles_2_0.h" +#include "libGLESv2/entry_points_gles_2_0_autogen.h" #include "libGLESv2/entry_points_gles_2_0_ext.h" -#include "libGLESv2/entry_points_gles_3_0.h" +#include "libGLESv2/entry_points_gles_3_0_autogen.h" +#include "libGLESv2/entry_points_gles_3_1_autogen.h" #include "common/event_tracer.h" -extern "C" -{ +extern "C" { void GL_APIENTRY glActiveTexture(GLenum texture) { @@ -25,7 +25,7 @@ void GL_APIENTRY glAttachShader(GLuint program, GLuint shader) return gl::AttachShader(program, shader); } -void GL_APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar* name) +void GL_APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar *name) { return gl::BindAttribLocation(program, index, name); } @@ -75,12 +75,12 @@ void GL_APIENTRY glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlp return gl::BlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); } -void GL_APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) +void GL_APIENTRY glBufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage) { return gl::BufferData(target, size, data, usage); } -void GL_APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) +void GL_APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data) { return gl::BufferSubData(target, offset, size, data); } @@ -120,22 +120,53 @@ void GL_APIENTRY glCompileShader(GLuint shader) return gl::CompileShader(shader); } -void GL_APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data) +void GL_APIENTRY glCompressedTexImage2D(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + const void *data) { - return gl::CompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data); + return gl::CompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, + data); } -void GL_APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data) +void GL_APIENTRY glCompressedTexSubImage2D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLsizei imageSize, + const void *data) { - return gl::CompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data); + return gl::CompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, + imageSize, data); } -void GL_APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) +void GL_APIENTRY glCopyTexImage2D(GLenum target, + GLint level, + GLenum internalformat, + GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLint border) { return gl::CopyTexImage2D(target, level, internalformat, x, y, width, height, border); } -void GL_APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) +void GL_APIENTRY glCopyTexSubImage2D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) { return gl::CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); } @@ -155,12 +186,12 @@ void GL_APIENTRY glCullFace(GLenum mode) return gl::CullFace(mode); } -void GL_APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers) +void GL_APIENTRY glDeleteBuffers(GLsizei n, const GLuint *buffers) { return gl::DeleteBuffers(n, buffers); } -void GL_APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers) +void GL_APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint *framebuffers) { return gl::DeleteFramebuffers(n, framebuffers); } @@ -170,7 +201,7 @@ void GL_APIENTRY glDeleteProgram(GLuint program) return gl::DeleteProgram(program); } -void GL_APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) +void GL_APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers) { return gl::DeleteRenderbuffers(n, renderbuffers); } @@ -180,7 +211,7 @@ void GL_APIENTRY glDeleteShader(GLuint shader) return gl::DeleteShader(shader); } -void GL_APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures) +void GL_APIENTRY glDeleteTextures(GLsizei n, const GLuint *textures) { return gl::DeleteTextures(n, textures); } @@ -220,7 +251,7 @@ void GL_APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count) return gl::DrawArrays(mode, first, count); } -void GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) +void GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) { return gl::DrawElements(mode, count, type, indices); } @@ -245,12 +276,19 @@ void GL_APIENTRY glFlush(void) return gl::Flush(); } -void GL_APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) +void GL_APIENTRY glFramebufferRenderbuffer(GLenum target, + GLenum attachment, + GLenum renderbuffertarget, + GLuint renderbuffer) { return gl::FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer); } -void GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) +void GL_APIENTRY glFramebufferTexture2D(GLenum target, + GLenum attachment, + GLenum textarget, + GLuint texture, + GLint level) { return gl::FramebufferTexture2D(target, attachment, textarget, texture, level); } @@ -260,7 +298,7 @@ void GL_APIENTRY glFrontFace(GLenum mode) return gl::FrontFace(mode); } -void GL_APIENTRY glGenBuffers(GLsizei n, GLuint* buffers) +void GL_APIENTRY glGenBuffers(GLsizei n, GLuint *buffers) { return gl::GenBuffers(n, buffers); } @@ -270,47 +308,62 @@ void GL_APIENTRY glGenerateMipmap(GLenum target) return gl::GenerateMipmap(target); } -void GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers) +void GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint *framebuffers) { return gl::GenFramebuffers(n, framebuffers); } -void GL_APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers) +void GL_APIENTRY glGenRenderbuffers(GLsizei n, GLuint *renderbuffers) { return gl::GenRenderbuffers(n, renderbuffers); } -void GL_APIENTRY glGenTextures(GLsizei n, GLuint* textures) +void GL_APIENTRY glGenTextures(GLsizei n, GLuint *textures) { return gl::GenTextures(n, textures); } -void GL_APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) +void GL_APIENTRY glGetActiveAttrib(GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name) { return gl::GetActiveAttrib(program, index, bufsize, length, size, type, name); } -void GL_APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) +void GL_APIENTRY glGetActiveUniform(GLuint program, + GLuint index, + GLsizei bufsize, + GLsizei *length, + GLint *size, + GLenum *type, + GLchar *name) { return gl::GetActiveUniform(program, index, bufsize, length, size, type, name); } -void GL_APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) +void GL_APIENTRY glGetAttachedShaders(GLuint program, + GLsizei maxcount, + GLsizei *count, + GLuint *shaders) { return gl::GetAttachedShaders(program, maxcount, count, shaders); } -GLint GL_APIENTRY glGetAttribLocation(GLuint program, const GLchar* name) +GLint GL_APIENTRY glGetAttribLocation(GLuint program, const GLchar *name) { return gl::GetAttribLocation(program, name); } -void GL_APIENTRY glGetBooleanv(GLenum pname, GLboolean* params) +void GL_APIENTRY glGetBooleanv(GLenum pname, GLboolean *params) { return gl::GetBooleanv(pname, params); } -void GL_APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params) +void GL_APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint *params) { return gl::GetBufferParameteriv(target, pname, params); } @@ -320,97 +373,109 @@ GLenum GL_APIENTRY glGetError(void) return gl::GetError(); } -void GL_APIENTRY glGetFloatv(GLenum pname, GLfloat* params) +void GL_APIENTRY glGetFloatv(GLenum pname, GLfloat *params) { return gl::GetFloatv(pname, params); } -void GL_APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params) +void GL_APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, + GLenum attachment, + GLenum pname, + GLint *params) { return gl::GetFramebufferAttachmentParameteriv(target, attachment, pname, params); } -void GL_APIENTRY glGetIntegerv(GLenum pname, GLint* params) +void GL_APIENTRY glGetIntegerv(GLenum pname, GLint *params) { return gl::GetIntegerv(pname, params); } -void GL_APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params) +void GL_APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint *params) { return gl::GetProgramiv(program, pname, params); } -void GL_APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog) +void GL_APIENTRY glGetProgramInfoLog(GLuint program, + GLsizei bufsize, + GLsizei *length, + GLchar *infolog) { return gl::GetProgramInfoLog(program, bufsize, length, infolog); } -void GL_APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) +void GL_APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params) { return gl::GetRenderbufferParameteriv(target, pname, params); } -void GL_APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params) +void GL_APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint *params) { return gl::GetShaderiv(shader, pname, params); } -void GL_APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog) +void GL_APIENTRY glGetShaderInfoLog(GLuint shader, + GLsizei bufsize, + GLsizei *length, + GLchar *infolog) { return gl::GetShaderInfoLog(shader, bufsize, length, infolog); } -void GL_APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) +void GL_APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, + GLenum precisiontype, + GLint *range, + GLint *precision) { return gl::GetShaderPrecisionFormat(shadertype, precisiontype, range, precision); } -void GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source) +void GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source) { return gl::GetShaderSource(shader, bufsize, length, source); } -const GLubyte* GL_APIENTRY glGetString(GLenum name) +const GLubyte *GL_APIENTRY glGetString(GLenum name) { return gl::GetString(name); } -void GL_APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) +void GL_APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params) { return gl::GetTexParameterfv(target, pname, params); } -void GL_APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params) +void GL_APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint *params) { return gl::GetTexParameteriv(target, pname, params); } -void GL_APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params) +void GL_APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat *params) { return gl::GetUniformfv(program, location, params); } -void GL_APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params) +void GL_APIENTRY glGetUniformiv(GLuint program, GLint location, GLint *params) { return gl::GetUniformiv(program, location, params); } -GLint GL_APIENTRY glGetUniformLocation(GLuint program, const GLchar* name) +GLint GL_APIENTRY glGetUniformLocation(GLuint program, const GLchar *name) { return gl::GetUniformLocation(program, name); } -void GL_APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) +void GL_APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params) { return gl::GetVertexAttribfv(index, pname, params); } -void GL_APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params) +void GL_APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint *params) { return gl::GetVertexAttribiv(index, pname, params); } -void GL_APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer) +void GL_APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, void **pointer) { return gl::GetVertexAttribPointerv(index, pname, pointer); } @@ -475,7 +540,13 @@ void GL_APIENTRY glPolygonOffset(GLfloat factor, GLfloat units) return gl::PolygonOffset(factor, units); } -void GL_APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) +void GL_APIENTRY glReadPixels(GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + void *pixels) { return gl::ReadPixels(x, y, width, height, format, type, pixels); } @@ -485,7 +556,10 @@ void GL_APIENTRY glReleaseShaderCompiler(void) return gl::ReleaseShaderCompiler(); } -void GL_APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) +void GL_APIENTRY glRenderbufferStorage(GLenum target, + GLenum internalformat, + GLsizei width, + GLsizei height) { return gl::RenderbufferStorage(target, internalformat, width, height); } @@ -500,12 +574,19 @@ void GL_APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height) return gl::Scissor(x, y, width, height); } -void GL_APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length) +void GL_APIENTRY glShaderBinary(GLsizei n, + const GLuint *shaders, + GLenum binaryformat, + const void *binary, + GLsizei length) { return gl::ShaderBinary(n, shaders, binaryformat, binary, length); } -void GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length) +void GL_APIENTRY glShaderSource(GLuint shader, + GLsizei count, + const GLchar *const *string, + const GLint *length) { return gl::ShaderSource(shader, count, string, length); } @@ -540,9 +621,18 @@ void GL_APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLe return gl::StencilOpSeparate(face, fail, zfail, zpass); } -void GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels) +void GL_APIENTRY glTexImage2D(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + const void *pixels) { - return gl::TexImage2D(target, level, internalformat, width, height, border, format, type, pixels); + return gl::TexImage2D(target, level, internalformat, width, height, border, format, type, + pixels); } void GL_APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param) @@ -550,7 +640,7 @@ void GL_APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param) return gl::TexParameterf(target, pname, param); } -void GL_APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params) +void GL_APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat *params) { return gl::TexParameterfv(target, pname, params); } @@ -560,12 +650,20 @@ void GL_APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) return gl::TexParameteri(target, pname, param); } -void GL_APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params) +void GL_APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint *params) { return gl::TexParameteriv(target, pname, params); } -void GL_APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels) +void GL_APIENTRY glTexSubImage2D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + const void *pixels) { return gl::TexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); } @@ -575,7 +673,7 @@ void GL_APIENTRY glUniform1f(GLint location, GLfloat x) return gl::Uniform1f(location, x); } -void GL_APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v) +void GL_APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat *v) { return gl::Uniform1fv(location, count, v); } @@ -585,7 +683,7 @@ void GL_APIENTRY glUniform1i(GLint location, GLint x) return gl::Uniform1i(location, x); } -void GL_APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v) +void GL_APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint *v) { return gl::Uniform1iv(location, count, v); } @@ -595,7 +693,7 @@ void GL_APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y) return gl::Uniform2f(location, x, y); } -void GL_APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v) +void GL_APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat *v) { return gl::Uniform2fv(location, count, v); } @@ -605,7 +703,7 @@ void GL_APIENTRY glUniform2i(GLint location, GLint x, GLint y) return gl::Uniform2i(location, x, y); } -void GL_APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v) +void GL_APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint *v) { return gl::Uniform2iv(location, count, v); } @@ -615,7 +713,7 @@ void GL_APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) return gl::Uniform3f(location, x, y, z); } -void GL_APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v) +void GL_APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat *v) { return gl::Uniform3fv(location, count, v); } @@ -625,7 +723,7 @@ void GL_APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z) return gl::Uniform3i(location, x, y, z); } -void GL_APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v) +void GL_APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint *v) { return gl::Uniform3iv(location, count, v); } @@ -635,7 +733,7 @@ void GL_APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GL return gl::Uniform4f(location, x, y, z, w); } -void GL_APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v) +void GL_APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat *v) { return gl::Uniform4fv(location, count, v); } @@ -645,22 +743,31 @@ void GL_APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) return gl::Uniform4i(location, x, y, z, w); } -void GL_APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v) +void GL_APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint *v) { return gl::Uniform4iv(location, count, v); } -void GL_APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void GL_APIENTRY glUniformMatrix2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) { return gl::UniformMatrix2fv(location, count, transpose, value); } -void GL_APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void GL_APIENTRY glUniformMatrix3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) { return gl::UniformMatrix3fv(location, count, transpose, value); } -void GL_APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void GL_APIENTRY glUniformMatrix4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) { return gl::UniformMatrix4fv(location, count, transpose, value); } @@ -680,7 +787,7 @@ void GL_APIENTRY glVertexAttrib1f(GLuint indx, GLfloat x) return gl::VertexAttrib1f(indx, x); } -void GL_APIENTRY glVertexAttrib1fv(GLuint indx, const GLfloat* values) +void GL_APIENTRY glVertexAttrib1fv(GLuint indx, const GLfloat *values) { return gl::VertexAttrib1fv(indx, values); } @@ -690,7 +797,7 @@ void GL_APIENTRY glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y) return gl::VertexAttrib2f(indx, x, y); } -void GL_APIENTRY glVertexAttrib2fv(GLuint indx, const GLfloat* values) +void GL_APIENTRY glVertexAttrib2fv(GLuint indx, const GLfloat *values) { return gl::VertexAttrib2fv(indx, values); } @@ -700,7 +807,7 @@ void GL_APIENTRY glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z) return gl::VertexAttrib3f(indx, x, y, z); } -void GL_APIENTRY glVertexAttrib3fv(GLuint indx, const GLfloat* values) +void GL_APIENTRY glVertexAttrib3fv(GLuint indx, const GLfloat *values) { return gl::VertexAttrib3fv(indx, values); } @@ -710,12 +817,17 @@ void GL_APIENTRY glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, return gl::VertexAttrib4f(indx, x, y, z, w); } -void GL_APIENTRY glVertexAttrib4fv(GLuint indx, const GLfloat* values) +void GL_APIENTRY glVertexAttrib4fv(GLuint indx, const GLfloat *values) { return gl::VertexAttrib4fv(indx, values); } -void GL_APIENTRY glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr) +void GL_APIENTRY glVertexAttribPointer(GLuint indx, + GLint size, + GLenum type, + GLboolean normalized, + GLsizei stride, + const void *ptr) { return gl::VertexAttribPointer(indx, size, type, normalized, stride, ptr); } @@ -730,42 +842,96 @@ void GL_APIENTRY glReadBuffer(GLenum mode) return gl::ReadBuffer(mode); } -void GL_APIENTRY glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices) +void GL_APIENTRY glDrawRangeElements(GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const void *indices) { return gl::DrawRangeElements(mode, start, end, count, type, indices); } -void GL_APIENTRY glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels) +void GL_APIENTRY glTexImage3D(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLenum format, + GLenum type, + const void *pixels) { - return gl::TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels); + return gl::TexImage3D(target, level, internalformat, width, height, depth, border, format, type, + pixels); } -void GL_APIENTRY glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels) +void GL_APIENTRY glTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLenum type, + const void *pixels) { - return gl::TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + return gl::TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, + type, pixels); } -void GL_APIENTRY glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) +void GL_APIENTRY glCopyTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLint x, + GLint y, + GLsizei width, + GLsizei height) { return gl::CopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height); } -void GL_APIENTRY glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data) +void GL_APIENTRY glCompressedTexImage3D(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth, + GLint border, + GLsizei imageSize, + const void *data) { - return gl::CompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, data); + return gl::CompressedTexImage3D(target, level, internalformat, width, height, depth, border, + imageSize, data); } -void GL_APIENTRY glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data) +void GL_APIENTRY glCompressedTexSubImage3D(GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLint zoffset, + GLsizei width, + GLsizei height, + GLsizei depth, + GLenum format, + GLsizei imageSize, + const void *data) { - return gl::CompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data); + return gl::CompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, + depth, format, imageSize, data); } -void GL_APIENTRY glGenQueries(GLsizei n, GLuint* ids) +void GL_APIENTRY glGenQueries(GLsizei n, GLuint *ids) { return gl::GenQueries(n, ids); } -void GL_APIENTRY glDeleteQueries(GLsizei n, const GLuint* ids) +void GL_APIENTRY glDeleteQueries(GLsizei n, const GLuint *ids) { return gl::DeleteQueries(n, ids); } @@ -785,12 +951,12 @@ void GL_APIENTRY glEndQuery(GLenum target) return gl::EndQuery(target); } -void GL_APIENTRY glGetQueryiv(GLenum target, GLenum pname, GLint* params) +void GL_APIENTRY glGetQueryiv(GLenum target, GLenum pname, GLint *params) { return gl::GetQueryiv(target, pname, params); } -void GL_APIENTRY glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) +void GL_APIENTRY glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params) { return gl::GetQueryObjectuiv(id, pname, params); } @@ -800,62 +966,101 @@ GLboolean GL_APIENTRY glUnmapBuffer(GLenum target) return gl::UnmapBuffer(target); } -void GL_APIENTRY glGetBufferPointerv(GLenum target, GLenum pname, GLvoid** params) +void GL_APIENTRY glGetBufferPointerv(GLenum target, GLenum pname, void **params) { return gl::GetBufferPointerv(target, pname, params); } -void GL_APIENTRY glDrawBuffers(GLsizei n, const GLenum* bufs) +void GL_APIENTRY glDrawBuffers(GLsizei n, const GLenum *bufs) { return gl::DrawBuffers(n, bufs); } -void GL_APIENTRY glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void GL_APIENTRY glUniformMatrix2x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) { return gl::UniformMatrix2x3fv(location, count, transpose, value); } -void GL_APIENTRY glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void GL_APIENTRY glUniformMatrix3x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) { return gl::UniformMatrix3x2fv(location, count, transpose, value); } -void GL_APIENTRY glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void GL_APIENTRY glUniformMatrix2x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) { return gl::UniformMatrix2x4fv(location, count, transpose, value); } -void GL_APIENTRY glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void GL_APIENTRY glUniformMatrix4x2fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) { return gl::UniformMatrix4x2fv(location, count, transpose, value); } -void GL_APIENTRY glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void GL_APIENTRY glUniformMatrix3x4fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) { return gl::UniformMatrix3x4fv(location, count, transpose, value); } -void GL_APIENTRY glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +void GL_APIENTRY glUniformMatrix4x3fv(GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) { return gl::UniformMatrix4x3fv(location, count, transpose, value); } -void GL_APIENTRY glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) +void GL_APIENTRY glBlitFramebuffer(GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter) { - return gl::BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + return gl::BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, + filter); } -void GL_APIENTRY glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) +void GL_APIENTRY glRenderbufferStorageMultisample(GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height) { return gl::RenderbufferStorageMultisample(target, samples, internalformat, width, height); } -void GL_APIENTRY glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) +void GL_APIENTRY glFramebufferTextureLayer(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint layer) { return gl::FramebufferTextureLayer(target, attachment, texture, level, layer); } -GLvoid* GL_APIENTRY glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) +void *GL_APIENTRY glMapBufferRange(GLenum target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access) { return gl::MapBufferRange(target, offset, length, access); } @@ -870,12 +1075,12 @@ void GL_APIENTRY glBindVertexArray(GLuint array) return gl::BindVertexArray(array); } -void GL_APIENTRY glDeleteVertexArrays(GLsizei n, const GLuint* arrays) +void GL_APIENTRY glDeleteVertexArrays(GLsizei n, const GLuint *arrays) { return gl::DeleteVertexArrays(n, arrays); } -void GL_APIENTRY glGenVertexArrays(GLsizei n, GLuint* arrays) +void GL_APIENTRY glGenVertexArrays(GLsizei n, GLuint *arrays) { return gl::GenVertexArrays(n, arrays); } @@ -885,7 +1090,7 @@ GLboolean GL_APIENTRY glIsVertexArray(GLuint array) return gl::IsVertexArray(array); } -void GL_APIENTRY glGetIntegeri_v(GLenum target, GLuint index, GLint* data) +void GL_APIENTRY glGetIntegeri_v(GLenum target, GLuint index, GLint *data) { return gl::GetIntegeri_v(target, index, data); } @@ -900,7 +1105,8 @@ void GL_APIENTRY glEndTransformFeedback(void) return gl::EndTransformFeedback(); } -void GL_APIENTRY glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) +void GL_APIENTRY +glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) { return gl::BindBufferRange(target, index, buffer, offset, size); } @@ -910,27 +1116,37 @@ void GL_APIENTRY glBindBufferBase(GLenum target, GLuint index, GLuint buffer) return gl::BindBufferBase(target, index, buffer); } -void GL_APIENTRY glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode) +void GL_APIENTRY glTransformFeedbackVaryings(GLuint program, + GLsizei count, + const GLchar *const *varyings, + GLenum bufferMode) { return gl::TransformFeedbackVaryings(program, count, varyings, bufferMode); } -void GL_APIENTRY glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name) +void GL_APIENTRY glGetTransformFeedbackVarying(GLuint program, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLsizei *size, + GLenum *type, + GLchar *name) { return gl::GetTransformFeedbackVarying(program, index, bufSize, length, size, type, name); } -void GL_APIENTRY glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) +void GL_APIENTRY +glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer) { return gl::VertexAttribIPointer(index, size, type, stride, pointer); } -void GL_APIENTRY glGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) +void GL_APIENTRY glGetVertexAttribIiv(GLuint index, GLenum pname, GLint *params) { return gl::GetVertexAttribIiv(index, pname, params); } -void GL_APIENTRY glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params) +void GL_APIENTRY glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params) { return gl::GetVertexAttribIuiv(index, pname, params); } @@ -945,17 +1161,17 @@ void GL_APIENTRY glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, return gl::VertexAttribI4ui(index, x, y, z, w); } -void GL_APIENTRY glVertexAttribI4iv(GLuint index, const GLint* v) +void GL_APIENTRY glVertexAttribI4iv(GLuint index, const GLint *v) { return gl::VertexAttribI4iv(index, v); } -void GL_APIENTRY glVertexAttribI4uiv(GLuint index, const GLuint* v) +void GL_APIENTRY glVertexAttribI4uiv(GLuint index, const GLuint *v) { return gl::VertexAttribI4uiv(index, v); } -void GL_APIENTRY glGetUniformuiv(GLuint program, GLint location, GLuint* params) +void GL_APIENTRY glGetUniformuiv(GLuint program, GLint location, GLuint *params) { return gl::GetUniformuiv(program, location, params); } @@ -985,37 +1201,37 @@ void GL_APIENTRY glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, G return gl::Uniform4ui(location, v0, v1, v2, v3); } -void GL_APIENTRY glUniform1uiv(GLint location, GLsizei count, const GLuint* value) +void GL_APIENTRY glUniform1uiv(GLint location, GLsizei count, const GLuint *value) { return gl::Uniform1uiv(location, count, value); } -void GL_APIENTRY glUniform2uiv(GLint location, GLsizei count, const GLuint* value) +void GL_APIENTRY glUniform2uiv(GLint location, GLsizei count, const GLuint *value) { return gl::Uniform2uiv(location, count, value); } -void GL_APIENTRY glUniform3uiv(GLint location, GLsizei count, const GLuint* value) +void GL_APIENTRY glUniform3uiv(GLint location, GLsizei count, const GLuint *value) { return gl::Uniform3uiv(location, count, value); } -void GL_APIENTRY glUniform4uiv(GLint location, GLsizei count, const GLuint* value) +void GL_APIENTRY glUniform4uiv(GLint location, GLsizei count, const GLuint *value) { return gl::Uniform4uiv(location, count, value); } -void GL_APIENTRY glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value) +void GL_APIENTRY glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value) { return gl::ClearBufferiv(buffer, drawbuffer, value); } -void GL_APIENTRY glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value) +void GL_APIENTRY glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value) { return gl::ClearBufferuiv(buffer, drawbuffer, value); } -void GL_APIENTRY glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value) +void GL_APIENTRY glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value) { return gl::ClearBufferfv(buffer, drawbuffer, value); } @@ -1025,59 +1241,87 @@ void GL_APIENTRY glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, return gl::ClearBufferfi(buffer, drawbuffer, depth, stencil); } -const GLubyte* GL_APIENTRY glGetStringi(GLenum name, GLuint index) +const GLubyte *GL_APIENTRY glGetStringi(GLenum name, GLuint index) { return gl::GetStringi(name, index); } -void GL_APIENTRY glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) +void GL_APIENTRY glCopyBufferSubData(GLenum readTarget, + GLenum writeTarget, + GLintptr readOffset, + GLintptr writeOffset, + GLsizeiptr size) { return gl::CopyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size); } -void GL_APIENTRY glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices) +void GL_APIENTRY glGetUniformIndices(GLuint program, + GLsizei uniformCount, + const GLchar *const *uniformNames, + GLuint *uniformIndices) { return gl::GetUniformIndices(program, uniformCount, uniformNames, uniformIndices); } -void GL_APIENTRY glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params) +void GL_APIENTRY glGetActiveUniformsiv(GLuint program, + GLsizei uniformCount, + const GLuint *uniformIndices, + GLenum pname, + GLint *params) { return gl::GetActiveUniformsiv(program, uniformCount, uniformIndices, pname, params); } -GLuint GL_APIENTRY glGetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName) +GLuint GL_APIENTRY glGetUniformBlockIndex(GLuint program, const GLchar *uniformBlockName) { return gl::GetUniformBlockIndex(program, uniformBlockName); } -void GL_APIENTRY glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) +void GL_APIENTRY glGetActiveUniformBlockiv(GLuint program, + GLuint uniformBlockIndex, + GLenum pname, + GLint *params) { return gl::GetActiveUniformBlockiv(program, uniformBlockIndex, pname, params); } -void GL_APIENTRY glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName) +void GL_APIENTRY glGetActiveUniformBlockName(GLuint program, + GLuint uniformBlockIndex, + GLsizei bufSize, + GLsizei *length, + GLchar *uniformBlockName) { - return gl::GetActiveUniformBlockName(program, uniformBlockIndex, bufSize, length, uniformBlockName); + return gl::GetActiveUniformBlockName(program, uniformBlockIndex, bufSize, length, + uniformBlockName); } -void GL_APIENTRY glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) +void GL_APIENTRY glUniformBlockBinding(GLuint program, + GLuint uniformBlockIndex, + GLuint uniformBlockBinding) { return gl::UniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); } -void GL_APIENTRY glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount) +void GL_APIENTRY glDrawArraysInstanced(GLenum mode, + GLint first, + GLsizei count, + GLsizei instanceCount) { return gl::DrawArraysInstanced(mode, first, count, instanceCount); } -void GL_APIENTRY glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount) +void GL_APIENTRY glDrawElementsInstanced(GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei instanceCount) { return gl::DrawElementsInstanced(mode, count, type, indices, instanceCount); } GLsync GL_APIENTRY glFenceSync(GLenum condition, GLbitfield flags) { - return gl::FenceSync_(condition, flags); + return gl::FenceSync(condition, flags); } GLboolean GL_APIENTRY glIsSync(GLsync sync) @@ -1100,32 +1344,33 @@ void GL_APIENTRY glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) return gl::WaitSync(sync, flags, timeout); } -void GL_APIENTRY glGetInteger64v(GLenum pname, GLint64* params) +void GL_APIENTRY glGetInteger64v(GLenum pname, GLint64 *params) { return gl::GetInteger64v(pname, params); } -void GL_APIENTRY glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values) +void GL_APIENTRY +glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values) { return gl::GetSynciv(sync, pname, bufSize, length, values); } -void GL_APIENTRY glGetInteger64i_v(GLenum target, GLuint index, GLint64* data) +void GL_APIENTRY glGetInteger64i_v(GLenum target, GLuint index, GLint64 *data) { return gl::GetInteger64i_v(target, index, data); } -void GL_APIENTRY glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params) +void GL_APIENTRY glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params) { return gl::GetBufferParameteri64v(target, pname, params); } -void GL_APIENTRY glGenSamplers(GLsizei count, GLuint* samplers) +void GL_APIENTRY glGenSamplers(GLsizei count, GLuint *samplers) { return gl::GenSamplers(count, samplers); } -void GL_APIENTRY glDeleteSamplers(GLsizei count, const GLuint* samplers) +void GL_APIENTRY glDeleteSamplers(GLsizei count, const GLuint *samplers) { return gl::DeleteSamplers(count, samplers); } @@ -1145,7 +1390,7 @@ void GL_APIENTRY glSamplerParameteri(GLuint sampler, GLenum pname, GLint param) return gl::SamplerParameteri(sampler, pname, param); } -void GL_APIENTRY glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param) +void GL_APIENTRY glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint *param) { return gl::SamplerParameteriv(sampler, pname, param); } @@ -1155,17 +1400,17 @@ void GL_APIENTRY glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param return gl::SamplerParameterf(sampler, pname, param); } -void GL_APIENTRY glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param) +void GL_APIENTRY glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param) { return gl::SamplerParameterfv(sampler, pname, param); } -void GL_APIENTRY glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params) +void GL_APIENTRY glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params) { return gl::GetSamplerParameteriv(sampler, pname, params); } -void GL_APIENTRY glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params) +void GL_APIENTRY glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params) { return gl::GetSamplerParameterfv(sampler, pname, params); } @@ -1180,12 +1425,12 @@ void GL_APIENTRY glBindTransformFeedback(GLenum target, GLuint id) return gl::BindTransformFeedback(target, id); } -void GL_APIENTRY glDeleteTransformFeedbacks(GLsizei n, const GLuint* ids) +void GL_APIENTRY glDeleteTransformFeedbacks(GLsizei n, const GLuint *ids) { return gl::DeleteTransformFeedbacks(n, ids); } -void GL_APIENTRY glGenTransformFeedbacks(GLsizei n, GLuint* ids) +void GL_APIENTRY glGenTransformFeedbacks(GLsizei n, GLuint *ids) { return gl::GenTransformFeedbacks(n, ids); } @@ -1205,12 +1450,19 @@ void GL_APIENTRY glResumeTransformFeedback(void) return gl::ResumeTransformFeedback(); } -void GL_APIENTRY glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary) +void GL_APIENTRY glGetProgramBinary(GLuint program, + GLsizei bufSize, + GLsizei *length, + GLenum *binaryFormat, + void *binary) { return gl::GetProgramBinary(program, bufSize, length, binaryFormat, binary); } -void GL_APIENTRY glProgramBinary(GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length) +void GL_APIENTRY glProgramBinary(GLuint program, + GLenum binaryFormat, + const void *binary, + GLsizei length) { return gl::ProgramBinary(program, binaryFormat, binary, length); } @@ -1220,52 +1472,86 @@ void GL_APIENTRY glProgramParameteri(GLuint program, GLenum pname, GLint value) return gl::ProgramParameteri(program, pname, value); } -void GL_APIENTRY glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments) +void GL_APIENTRY glInvalidateFramebuffer(GLenum target, + GLsizei numAttachments, + const GLenum *attachments) { return gl::InvalidateFramebuffer(target, numAttachments, attachments); } -void GL_APIENTRY glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height) +void GL_APIENTRY glInvalidateSubFramebuffer(GLenum target, + GLsizei numAttachments, + const GLenum *attachments, + GLint x, + GLint y, + GLsizei width, + GLsizei height) { return gl::InvalidateSubFramebuffer(target, numAttachments, attachments, x, y, width, height); } -void GL_APIENTRY glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) +void GL_APIENTRY +glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) { return gl::TexStorage2D(target, levels, internalformat, width, height); } -void GL_APIENTRY glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) +void GL_APIENTRY glTexStorage3D(GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLsizei depth) { return gl::TexStorage3D(target, levels, internalformat, width, height, depth); } -void GL_APIENTRY glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params) +void GL_APIENTRY glGetInternalformativ(GLenum target, + GLenum internalformat, + GLenum pname, + GLsizei bufSize, + GLint *params) { return gl::GetInternalformativ(target, internalformat, pname, bufSize, params); } -void GL_APIENTRY glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) +void GL_APIENTRY glBlitFramebufferANGLE(GLint srcX0, + GLint srcY0, + GLint srcX1, + GLint srcY1, + GLint dstX0, + GLint dstY0, + GLint dstX1, + GLint dstY1, + GLbitfield mask, + GLenum filter) { - return gl::BlitFramebufferANGLE(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + return gl::BlitFramebufferANGLE(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, + filter); } -void GL_APIENTRY glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) +void GL_APIENTRY glRenderbufferStorageMultisampleANGLE(GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height) { return gl::RenderbufferStorageMultisampleANGLE(target, samples, internalformat, width, height); } -void GL_APIENTRY glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum *attachments) +void GL_APIENTRY glDiscardFramebufferEXT(GLenum target, + GLsizei numAttachments, + const GLenum *attachments) { return gl::DiscardFramebufferEXT(target, numAttachments, attachments); } -void GL_APIENTRY glDeleteFencesNV(GLsizei n, const GLuint* fences) +void GL_APIENTRY glDeleteFencesNV(GLsizei n, const GLuint *fences) { return gl::DeleteFencesNV(n, fences); } -void GL_APIENTRY glGenFencesNV(GLsizei n, GLuint* fences) +void GL_APIENTRY glGenFencesNV(GLsizei n, GLuint *fences) { return gl::GenFencesNV(n, fences); } @@ -1295,12 +1581,19 @@ void GL_APIENTRY glSetFenceNV(GLuint fence, GLenum condition) return gl::SetFenceNV(fence, condition); } -void GL_APIENTRY glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source) +void GL_APIENTRY glGetTranslatedShaderSourceANGLE(GLuint shader, + GLsizei bufsize, + GLsizei *length, + GLchar *source) { return gl::GetTranslatedShaderSourceANGLE(shader, bufsize, length, source); } -void GL_APIENTRY glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) +void GL_APIENTRY glTexStorage2DEXT(GLenum target, + GLsizei levels, + GLenum internalformat, + GLsizei width, + GLsizei height) { return gl::TexStorage2DEXT(target, levels, internalformat, width, height); } @@ -1310,7 +1603,14 @@ GLenum GL_APIENTRY glGetGraphicsResetStatusEXT(void) return gl::GetGraphicsResetStatusEXT(); } -void GL_APIENTRY glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data) +void GL_APIENTRY glReadnPixelsEXT(GLint x, + GLint y, + GLsizei width, + GLsizei height, + GLenum format, + GLenum type, + GLsizei bufSize, + void *data) { return gl::ReadnPixelsEXT(x, y, width, height, format, type, bufSize, data); } @@ -1385,12 +1685,19 @@ void GL_APIENTRY glDrawBuffersEXT(GLsizei n, const GLenum *bufs) return gl::DrawBuffersEXT(n, bufs); } -void GL_APIENTRY glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount) +void GL_APIENTRY glDrawArraysInstancedANGLE(GLenum mode, + GLint first, + GLsizei count, + GLsizei primcount) { return gl::DrawArraysInstancedANGLE(mode, first, count, primcount); } -void GL_APIENTRY glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount) +void GL_APIENTRY glDrawElementsInstancedANGLE(GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei primcount) { return gl::DrawElementsInstancedANGLE(mode, count, type, indices, primcount); } @@ -1400,17 +1707,24 @@ void GL_APIENTRY glVertexAttribDivisorANGLE(GLuint index, GLuint divisor) return gl::VertexAttribDivisorANGLE(index, divisor); } -void GL_APIENTRY glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary) +void GL_APIENTRY glGetProgramBinaryOES(GLuint program, + GLsizei bufSize, + GLsizei *length, + GLenum *binaryFormat, + void *binary) { return gl::GetProgramBinaryOES(program, bufSize, length, binaryFormat, binary); } -void GL_APIENTRY glProgramBinaryOES(GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length) +void GL_APIENTRY glProgramBinaryOES(GLuint program, + GLenum binaryFormat, + const void *binary, + GLint length) { return gl::ProgramBinaryOES(program, binaryFormat, binary, length); } -void* GL_APIENTRY glMapBufferOES(GLenum target, GLenum access) +void *GL_APIENTRY glMapBufferOES(GLenum target, GLenum access) { return gl::MapBufferOES(target, access); } @@ -1420,12 +1734,15 @@ GLboolean GL_APIENTRY glUnmapBufferOES(GLenum target) return gl::UnmapBufferOES(target); } -void GL_APIENTRY glGetBufferPointervOES(GLenum target, GLenum pname, GLvoid **params) +void GL_APIENTRY glGetBufferPointervOES(GLenum target, GLenum pname, void **params) { return gl::GetBufferPointervOES(target, pname, params); } -void* GL_APIENTRY glMapBufferRangeEXT(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) +void *GL_APIENTRY glMapBufferRangeEXT(GLenum target, + GLintptr offset, + GLsizeiptr length, + GLbitfield access) { return gl::MapBufferRangeEXT(target, offset, length, access); } @@ -1562,4 +1879,697 @@ void GL_APIENTRY glGetPointervKHR(GLenum pname, void **params) { return gl::GetPointervKHR(pname, params); } + +void GL_APIENTRY glBindUniformLocationCHROMIUM(GLuint program, GLint location, const GLchar *name) +{ + return gl::BindUniformLocationCHROMIUM(program, location, name); } + +void GL_APIENTRY glCoverageModulationCHROMIUM(GLenum components) +{ + return gl::CoverageModulationCHROMIUM(components); +} + +// CHROMIUM_path_rendendering +void GL_APIENTRY glMatrixLoadfCHROMIUM(GLenum matrixMode, const GLfloat *matrix) +{ + gl::MatrixLoadfCHROMIUM(matrixMode, matrix); +} + +void GL_APIENTRY glMatrixLoadIdentityCHROMIUM(GLenum matrixMode) +{ + gl::MatrixLoadIdentityCHROMIUM(matrixMode); +} + +GLuint GL_APIENTRY glGenPathsCHROMIUM(GLsizei range) +{ + return gl::GenPathsCHROMIUM(range); +} + +void GL_APIENTRY glDeletePathsCHROMIUM(GLuint first, GLsizei range) +{ + gl::DeletePathsCHROMIUM(first, range); +} + +GLboolean GL_APIENTRY glIsPathCHROMIUM(GLuint path) +{ + return gl::IsPathCHROMIUM(path); +} + +void GL_APIENTRY glPathCommandsCHROMIUM(GLuint path, + GLsizei numCommands, + const GLubyte *commands, + GLsizei numCoords, + GLenum coordType, + const void *coords) +{ + gl::PathCommandsCHROMIUM(path, numCommands, commands, numCoords, coordType, coords); +} + +void GL_APIENTRY glPathParameterfCHROMIUM(GLuint path, GLenum pname, GLfloat value) +{ + gl::PathParameterfCHROMIUM(path, pname, value); +} + +void GL_APIENTRY glPathParameteriCHROMIUM(GLuint path, GLenum pname, GLint value) +{ + gl::PathParameteriCHROMIUM(path, pname, value); +} + +void GL_APIENTRY glGetPathParameterfvCHROMIUM(GLuint path, GLenum pname, GLfloat *value) +{ + gl::GetPathParameterfCHROMIUM(path, pname, value); +} + +void GL_APIENTRY glGetPathParameterivCHROMIUM(GLuint path, GLenum pname, GLint *value) +{ + gl::GetPathParameteriCHROMIUM(path, pname, value); +} + +void GL_APIENTRY glPathStencilFuncCHROMIUM(GLenum func, GLint ref, GLuint mask) +{ + gl::PathStencilFuncCHROMIUM(func, ref, mask); +} + +void GL_APIENTRY glStencilFillPathCHROMIUM(GLuint path, GLenum fillMode, GLuint mask) +{ + gl::StencilFillPathCHROMIUM(path, fillMode, mask); +} + +void GL_APIENTRY glStencilStrokePathCHROMIUM(GLuint path, GLint reference, GLuint mask) +{ + gl::StencilStrokePathCHROMIUM(path, reference, mask); +} + +void GL_APIENTRY glCoverFillPathCHROMIUM(GLuint path, GLenum coverMode) +{ + gl::CoverFillPathCHROMIUM(path, coverMode); +} + +void GL_APIENTRY glCoverStrokePathCHROMIUM(GLuint path, GLenum coverMode) +{ + gl::CoverStrokePathCHROMIUM(path, coverMode); +} + +void GL_APIENTRY glStencilThenCoverFillPathCHROMIUM(GLuint path, + GLenum fillMode, + GLuint mask, + GLenum coverMode) +{ + gl::StencilThenCoverFillPathCHROMIUM(path, fillMode, mask, coverMode); +} + +void GL_APIENTRY glStencilThenCoverStrokePathCHROMIUM(GLuint path, + GLint reference, + GLuint mask, + GLenum coverMode) +{ + gl::StencilThenCoverStrokePathCHROMIUM(path, reference, mask, coverMode); +} + +void GL_APIENTRY glCoverFillPathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + gl::CoverFillPathInstancedCHROMIUM(numPaths, pathNameType, paths, pathBase, coverMode, + transformType, transformValues); +} + +void GL_APIENTRY glCoverStrokePathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + gl::CoverStrokePathInstancedCHROMIUM(numPaths, pathNameType, paths, pathBase, coverMode, + transformType, transformValues); +} + +void GL_APIENTRY glStencilFillPathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + gl::StencilFillPathInstancedCHROMIUM(numPaths, pathNameType, paths, pathBase, fillMode, mask, + transformType, transformValues); +} + +void GL_APIENTRY glStencilStrokePathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum transformType, + const GLfloat *transformValues) +{ + gl::StencilStrokePathInstancedCHROMIUM(numPaths, pathNameType, paths, pathBase, reference, mask, + transformType, transformValues); +} + +void GL_APIENTRY glStencilThenCoverFillPathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLenum fillMode, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + gl::StencilThenCoverFillPathInstancedCHROMIUM(numPaths, pathNameType, paths, pathBase, fillMode, + mask, coverMode, transformType, transformValues); +} + +void GL_APIENTRY glStencilThenCoverStrokePathInstancedCHROMIUM(GLsizei numPaths, + GLenum pathNameType, + const void *paths, + GLuint pathBase, + GLint reference, + GLuint mask, + GLenum coverMode, + GLenum transformType, + const GLfloat *transformValues) +{ + gl::StencilThenCoverStrokePathInstancedCHROMIUM(numPaths, pathNameType, paths, pathBase, + reference, mask, coverMode, transformType, + transformValues); +} + +void GL_APIENTRY glBindFragmentInputLocationCHROMIUM(GLuint program, + GLint location, + const GLchar *name) +{ + gl::BindFragmentInputLocationCHROMIUM(program, location, name); +} + +void GL_APIENTRY glProgramPathFragmentInputGenCHROMIUM(GLuint program, + GLint location, + GLenum genMode, + GLint components, + const GLfloat *coeffs) +{ + gl::ProgramPathFragmentInputGenCHROMIUM(program, location, genMode, components, coeffs); +} + +// GLES 3.1 +void GL_APIENTRY glDispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ) +{ + gl::DispatchCompute(numGroupsX, numGroupsY, numGroupsZ); +} + +void GL_APIENTRY glDispatchComputeIndirect(GLintptr indirect) +{ + gl::DispatchComputeIndirect(indirect); +} + +void GL_APIENTRY glDrawArraysIndirect(GLenum mode, const void *indirect) +{ + gl::DrawArraysIndirect(mode, indirect); +} + +void GL_APIENTRY glDrawElementsIndirect(GLenum mode, GLenum type, const void *indirect) +{ + gl::DrawElementsIndirect(mode, type, indirect); +} + +void GL_APIENTRY glFramebufferParameteri(GLenum target, GLenum pname, GLint param) +{ + gl::FramebufferParameteri(target, pname, param); +} + +void GL_APIENTRY glGetFramebufferParameteriv(GLenum target, GLenum pname, GLint *params) +{ + gl::GetFramebufferParameteriv(target, pname, params); +} + +void GL_APIENTRY glGetProgramInterfaceiv(GLuint program, + GLenum programInterface, + GLenum pname, + GLint *params) +{ + gl::GetProgramInterfaceiv(program, programInterface, pname, params); +} + +GLuint GL_APIENTRY glGetProgramResourceIndex(GLuint program, + GLenum programInterface, + const GLchar *name) +{ + return gl::GetProgramResourceIndex(program, programInterface, name); +} + +void GL_APIENTRY glGetProgramResourceName(GLuint program, + GLenum programInterface, + GLuint index, + GLsizei bufSize, + GLsizei *length, + GLchar *name) +{ + gl::GetProgramResourceName(program, programInterface, index, bufSize, length, name); +} + +void GL_APIENTRY glGetProgramResourceiv(GLuint program, + GLenum programInterface, + GLuint index, + GLsizei propCount, + const GLenum *props, + GLsizei bufSize, + GLsizei *length, + GLint *params) +{ + gl::GetProgramResourceiv(program, programInterface, index, propCount, props, bufSize, length, + params); +} + +GLint GL_APIENTRY glGetProgramResourceLocation(GLuint program, + GLenum programInterface, + const GLchar *name) +{ + return gl::GetProgramResourceLocation(program, programInterface, name); +} + +void GL_APIENTRY glUseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program) +{ + gl::UseProgramStages(pipeline, stages, program); +} + +void GL_APIENTRY glActiveShaderProgram(GLuint pipeline, GLuint program) +{ + gl::ActiveShaderProgram(pipeline, program); +} + +GLuint GL_APIENTRY glCreateShaderProgramv(GLenum type, GLsizei count, const GLchar *const *strings) +{ + return gl::CreateShaderProgramv(type, count, strings); +} + +void GL_APIENTRY glBindProgramPipeline(GLuint pipeline) +{ + gl::BindProgramPipeline(pipeline); +} + +void GL_APIENTRY glDeleteProgramPipelines(GLsizei n, const GLuint *pipelines) +{ + gl::DeleteProgramPipelines(n, pipelines); +} + +void GL_APIENTRY glGenProgramPipelines(GLsizei n, GLuint *pipelines) +{ + gl::GenProgramPipelines(n, pipelines); +} + +GLboolean GL_APIENTRY glIsProgramPipeline(GLuint pipeline) +{ + return gl::IsProgramPipeline(pipeline); +} + +void GL_APIENTRY glGetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params) +{ + gl::GetProgramPipelineiv(pipeline, pname, params); +} + +void GL_APIENTRY glProgramUniform1i(GLuint program, GLint location, GLint v0) +{ + gl::ProgramUniform1i(program, location, v0); +} + +void GL_APIENTRY glProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1) +{ + gl::ProgramUniform2i(program, location, v0, v1); +} + +void GL_APIENTRY glProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2) +{ + gl::ProgramUniform3i(program, location, v0, v1, v2); +} + +void GL_APIENTRY +glProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3) +{ + gl::ProgramUniform4i(program, location, v0, v1, v2, v3); +} + +void GL_APIENTRY glProgramUniform1ui(GLuint program, GLint location, GLuint v0) +{ + gl::ProgramUniform1ui(program, location, v0); +} + +void GL_APIENTRY glProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1) +{ + gl::ProgramUniform2ui(program, location, v0, v1); +} + +void GL_APIENTRY +glProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2) +{ + gl::ProgramUniform3ui(program, location, v0, v1, v2); +} + +void GL_APIENTRY +glProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) +{ + gl::ProgramUniform4ui(program, location, v0, v1, v2, v3); +} + +void GL_APIENTRY glProgramUniform1f(GLuint program, GLint location, GLfloat v0) +{ + gl::ProgramUniform1f(program, location, v0); +} + +void GL_APIENTRY glProgramUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1) +{ + gl::ProgramUniform2f(program, location, v0, v1); +} + +void GL_APIENTRY +glProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) +{ + gl::ProgramUniform3f(program, location, v0, v1, v2); +} + +void GL_APIENTRY +glProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) +{ + gl::ProgramUniform4f(program, location, v0, v1, v2, v3); +} + +void GL_APIENTRY glProgramUniform1iv(GLuint program, + GLint location, + GLsizei count, + const GLint *value) +{ + gl::ProgramUniform1iv(program, location, count, value); +} + +void GL_APIENTRY glProgramUniform2iv(GLuint program, + GLint location, + GLsizei count, + const GLint *value) +{ + gl::ProgramUniform2iv(program, location, count, value); +} + +void GL_APIENTRY glProgramUniform3iv(GLuint program, + GLint location, + GLsizei count, + const GLint *value) +{ + gl::ProgramUniform3iv(program, location, count, value); +} + +void GL_APIENTRY glProgramUniform4iv(GLuint program, + GLint location, + GLsizei count, + const GLint *value) +{ + gl::ProgramUniform4iv(program, location, count, value); +} + +void GL_APIENTRY glProgramUniform1uiv(GLuint program, + GLint location, + GLsizei count, + const GLuint *value) +{ + gl::ProgramUniform1uiv(program, location, count, value); +} + +void GL_APIENTRY glProgramUniform2uiv(GLuint program, + GLint location, + GLsizei count, + const GLuint *value) +{ + gl::ProgramUniform2uiv(program, location, count, value); +} + +void GL_APIENTRY glProgramUniform3uiv(GLuint program, + GLint location, + GLsizei count, + const GLuint *value) +{ + gl::ProgramUniform3uiv(program, location, count, value); +} + +void GL_APIENTRY glProgramUniform4uiv(GLuint program, + GLint location, + GLsizei count, + const GLuint *value) +{ + gl::ProgramUniform4uiv(program, location, count, value); +} + +void GL_APIENTRY glProgramUniform1fv(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value) +{ + gl::ProgramUniform1fv(program, location, count, value); +} + +void GL_APIENTRY glProgramUniform2fv(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value) +{ + gl::ProgramUniform2fv(program, location, count, value); +} + +void GL_APIENTRY glProgramUniform3fv(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value) +{ + gl::ProgramUniform3fv(program, location, count, value); +} + +void GL_APIENTRY glProgramUniform4fv(GLuint program, + GLint location, + GLsizei count, + const GLfloat *value) +{ + gl::ProgramUniform4fv(program, location, count, value); +} + +void GL_APIENTRY glProgramUniformMatrix2fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + gl::ProgramUniformMatrix2fv(program, location, count, transpose, value); +} + +void GL_APIENTRY glProgramUniformMatrix3fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + gl::ProgramUniformMatrix3fv(program, location, count, transpose, value); +} + +void GL_APIENTRY glProgramUniformMatrix4fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + gl::ProgramUniformMatrix4fv(program, location, count, transpose, value); +} + +void GL_APIENTRY glProgramUniformMatrix2x3fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + gl::ProgramUniformMatrix2x3fv(program, location, count, transpose, value); +} + +void GL_APIENTRY glProgramUniformMatrix3x2fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + gl::ProgramUniformMatrix3x2fv(program, location, count, transpose, value); +} + +void GL_APIENTRY glProgramUniformMatrix2x4fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + gl::ProgramUniformMatrix2x4fv(program, location, count, transpose, value); +} + +void GL_APIENTRY glProgramUniformMatrix4x2fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + gl::ProgramUniformMatrix4x2fv(program, location, count, transpose, value); +} + +void GL_APIENTRY glProgramUniformMatrix3x4fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + gl::ProgramUniformMatrix3x4fv(program, location, count, transpose, value); +} + +void GL_APIENTRY glProgramUniformMatrix4x3fv(GLuint program, + GLint location, + GLsizei count, + GLboolean transpose, + const GLfloat *value) +{ + gl::ProgramUniformMatrix4x3fv(program, location, count, transpose, value); +} + +void GL_APIENTRY glValidateProgramPipeline(GLuint pipeline) +{ + gl::ValidateProgramPipeline(pipeline); +} + +void GL_APIENTRY glGetProgramPipelineInfoLog(GLuint pipeline, + GLsizei bufSize, + GLsizei *length, + GLchar *infoLog) +{ + gl::GetProgramPipelineInfoLog(pipeline, bufSize, length, infoLog); +} + +void GL_APIENTRY glBindImageTexture(GLuint unit, + GLuint texture, + GLint level, + GLboolean layered, + GLint layer, + GLenum access, + GLenum format) +{ + gl::BindImageTexture(unit, texture, level, layered, layer, access, format); +} + +void GL_APIENTRY glGetBooleani_v(GLenum target, GLuint index, GLboolean *data) +{ + gl::GetBooleani_v(target, index, data); +} + +void GL_APIENTRY glMemoryBarrier(GLbitfield barriers) +{ + gl::MemoryBarrier(barriers); +} + +void GL_APIENTRY glMemoryBarrierByRegion(GLbitfield barriers) +{ + gl::MemoryBarrierByRegion(barriers); +} + +void GL_APIENTRY glTexStorage2DMultisample(GLenum target, + GLsizei samples, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLboolean fixedsamplelocations) +{ + gl::TexStorage2DMultisample(target, samples, internalformat, width, height, + fixedsamplelocations); +} + +void GL_APIENTRY glGetMultisamplefv(GLenum pname, GLuint index, GLfloat *val) +{ + gl::GetMultisamplefv(pname, index, val); +} + +void GL_APIENTRY glSampleMaski(GLuint maskNumber, GLbitfield mask) +{ + gl::SampleMaski(maskNumber, mask); +} + +void GL_APIENTRY glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) +{ + gl::GetTexLevelParameteriv(target, level, pname, params); +} + +void GL_APIENTRY glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params) +{ + gl::GetTexLevelParameterfv(target, level, pname, params); +} + +void GL_APIENTRY glBindVertexBuffer(GLuint bindingindex, + GLuint buffer, + GLintptr offset, + GLsizei stride) +{ + gl::BindVertexBuffer(bindingindex, buffer, offset, stride); +} + +void GL_APIENTRY glVertexAttribFormat(GLuint attribindex, + GLint size, + GLenum type, + GLboolean normalized, + GLuint relativeoffset) +{ + gl::VertexAttribFormat(attribindex, size, type, normalized, relativeoffset); +} + +void GL_APIENTRY glVertexAttribIFormat(GLuint attribindex, + GLint size, + GLenum type, + GLuint relativeoffset) +{ + gl::VertexAttribIFormat(attribindex, size, type, relativeoffset); +} + +void GL_APIENTRY glVertexAttribBinding(GLuint attribindex, GLuint bindingindex) +{ + gl::VertexAttribBinding(attribindex, bindingindex); +} + +void GL_APIENTRY glVertexBindingDivisor(GLuint bindingindex, GLuint divisor) +{ + gl::VertexBindingDivisor(bindingindex, divisor); +} + +void GL_APIENTRY glFramebufferTextureMultiviewLayeredANGLE(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint baseViewIndex, + GLsizei numViews) +{ + gl::FramebufferTextureMultiviewLayeredANGLE(target, attachment, texture, level, baseViewIndex, + numViews); +} + +void GL_APIENTRY glFramebufferTextureMultiviewSideBySideANGLE(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLsizei numViews, + const GLint *viewportOffsets) +{ + gl::FramebufferTextureMultiviewSideBySideANGLE(target, attachment, texture, level, numViews, + viewportOffsets); +} + +void GL_APIENTRY glRequestExtensionANGLE(const GLchar *name) +{ + gl::RequestExtensionANGLE(name); +} + +} // extern "C" diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2.def index 0aebb6c864..2ff4cc0579 100644 --- a/src/3rdparty/angle/src/libGLESv2/libGLESv2.def +++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2.def @@ -202,6 +202,38 @@ EXPORTS glGetQueryObjectivEXT @315 glGetQueryObjecti64vEXT @316 glGetQueryObjectui64vEXT @317 + glBindUniformLocationCHROMIUM @318 + glCoverageModulationCHROMIUM @319 + + glMatrixLoadfCHROMIUM @320 + glMatrixLoadIdentityCHROMIUM @321 + glGenPathsCHROMIUM @322 + glDeletePathsCHROMIUM @323 + glIsPathCHROMIUM @324 + glPathCommandsCHROMIUM @325 + glPathParameterfCHROMIUM @326 + glPathParameteriCHROMIUM @327 + glGetPathParameterfvCHROMIUM @328 + glGetPathParameterivCHROMIUM @329 + glPathStencilFuncCHROMIUM @330 + glStencilFillPathCHROMIUM @331 + glStencilStrokePathCHROMIUM @332 + glCoverFillPathCHROMIUM @333 + glCoverStrokePathCHROMIUM @334 + glStencilThenCoverFillPathCHROMIUM @335 + glStencilThenCoverStrokePathCHROMIUM @336 + glCoverFillPathInstancedCHROMIUM @337 + glCoverStrokePathInstancedCHROMIUM @338 + glStencilStrokePathInstancedCHROMIUM @339 + glStencilFillPathInstancedCHROMIUM @340 + glStencilThenCoverFillPathInstancedCHROMIUM @341 + glStencilThenCoverStrokePathInstancedCHROMIUM @342 + glBindFragmentInputLocationCHROMIUM @343 + glProgramPathFragmentInputGenCHROMIUM @344 + + glFramebufferTextureMultiviewLayeredANGLE @413 + glFramebufferTextureMultiviewSideBySideANGLE @414 + glRequestExtensionANGLE @415 ; GLES 3.0 Functions glReadBuffer @180 @@ -309,7 +341,72 @@ EXPORTS glTexStorage3D @282 glGetInternalformativ @283 - ; ANGLE Platform Implementation - ANGLEPlatformCurrent @290 - ANGLEPlatformInitialize @291 - ANGLEPlatformShutdown @292 + ; GLES 3.1 Functions + glDispatchCompute @345 + glDispatchComputeIndirect @346 + glDrawArraysIndirect @347 + glDrawElementsIndirect @348 + glFramebufferParameteri @349 + glGetFramebufferParameteriv @350 + glGetProgramInterfaceiv @351 + glGetProgramResourceIndex @352 + glGetProgramResourceName @353 + glGetProgramResourceiv @354 + glGetProgramResourceLocation @355 + glUseProgramStages @356 + glActiveShaderProgram @357 + glCreateShaderProgramv @358 + glBindProgramPipeline @359 + glDeleteProgramPipelines @360 + glGenProgramPipelines @361 + glIsProgramPipeline @362 + glGetProgramPipelineiv @363 + glProgramUniform1i @364 + glProgramUniform2i @365 + glProgramUniform3i @366 + glProgramUniform4i @367 + glProgramUniform1ui @368 + glProgramUniform2ui @369 + glProgramUniform3ui @370 + glProgramUniform4ui @371 + glProgramUniform1f @372 + glProgramUniform2f @373 + glProgramUniform3f @374 + glProgramUniform4f @375 + glProgramUniform1iv @376 + glProgramUniform2iv @377 + glProgramUniform3iv @378 + glProgramUniform4iv @379 + glProgramUniform1uiv @380 + glProgramUniform2uiv @381 + glProgramUniform3uiv @382 + glProgramUniform4uiv @383 + glProgramUniform1fv @384 + glProgramUniform2fv @385 + glProgramUniform3fv @386 + glProgramUniform4fv @387 + glProgramUniformMatrix2fv @388 + glProgramUniformMatrix3fv @389 + glProgramUniformMatrix4fv @390 + glProgramUniformMatrix2x3fv @391 + glProgramUniformMatrix3x2fv @392 + glProgramUniformMatrix2x4fv @393 + glProgramUniformMatrix4x2fv @394 + glProgramUniformMatrix3x4fv @395 + glProgramUniformMatrix4x3fv @396 + glValidateProgramPipeline @397 + glGetProgramPipelineInfoLog @398 + glBindImageTexture @399 + glGetBooleani_v @400 + glMemoryBarrier @401 + glMemoryBarrierByRegion @402 + glTexStorage2DMultisample @403 + glGetMultisamplefv @404 + glSampleMaski @405 + glGetTexLevelParameteriv @406 + glGetTexLevelParameterfv @407 + glBindVertexBuffer @408 + glVertexAttribFormat @409 + glVertexAttribIFormat @410 + glVertexAttribBinding @411 + glVertexBindingDivisor @412 diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def index db17bb487b..2ff4cc0579 100644 --- a/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def +++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def @@ -1,316 +1,412 @@ LIBRARY libGLESv2 EXPORTS - glActiveTexture@4 @1 - glAttachShader@8 @2 - glBindAttribLocation@12 @3 - glBindBuffer@8 @4 - glBindFramebuffer@8 @5 - glBindRenderbuffer@8 @6 - glBindTexture@8 @7 - glBlendColor@16 @8 - glBlendEquation@4 @9 - glBlendEquationSeparate@8 @10 - glBlendFunc@8 @11 - glBlendFuncSeparate@16 @12 - glBufferData@16 @13 - glBufferSubData@16 @14 - glCheckFramebufferStatus@4 @15 - glClear@4 @16 - glClearColor@16 @17 - glClearDepthf@4 @18 - glClearStencil@4 @19 - glColorMask@16 @20 - glCompileShader@4 @21 - glCompressedTexImage2D@32 @22 - glCompressedTexSubImage2D@36 @23 - glCopyTexImage2D@32 @24 - glCopyTexSubImage2D@32 @25 - glCreateProgram@0 @26 - glCreateShader@4 @27 - glCullFace@4 @28 - glDeleteBuffers@8 @29 - glDeleteFramebuffers@8 @30 - glDeleteProgram@4 @32 - glDeleteRenderbuffers@8 @33 - glDeleteShader@4 @34 - glDeleteTextures@8 @31 - glDepthFunc@4 @36 - glDepthMask@4 @37 - glDepthRangef@8 @38 - glDetachShader@8 @35 - glDisable@4 @39 - glDisableVertexAttribArray@4 @40 - glDrawArrays@12 @41 - glDrawElements@16 @42 - glEnable@4 @43 - glEnableVertexAttribArray@4 @44 - glFinish@0 @45 - glFlush@0 @46 - glFramebufferRenderbuffer@16 @47 - glFramebufferTexture2D@20 @48 - glFrontFace@4 @49 - glGenBuffers@8 @50 - glGenFramebuffers@8 @52 - glGenRenderbuffers@8 @53 - glGenTextures@8 @54 - glGenerateMipmap@4 @51 - glGetActiveAttrib@28 @55 - glGetActiveUniform@28 @56 - glGetAttachedShaders@16 @57 - glGetAttribLocation@8 @58 - glGetBooleanv@8 @59 - glGetBufferParameteriv@12 @60 - glGetError@0 @61 - glGetFloatv@8 @62 - glGetFramebufferAttachmentParameteriv@16 @63 - glGetIntegerv@8 @64 - glGetProgramInfoLog@16 @66 - glGetProgramiv@12 @65 - glGetRenderbufferParameteriv@12 @67 - glGetShaderInfoLog@16 @69 - glGetShaderPrecisionFormat@16 @70 - glGetShaderSource@16 @71 - glGetShaderiv@12 @68 - glGetString@4 @72 - glGetTexParameterfv@12 @73 - glGetTexParameteriv@12 @74 - glGetUniformLocation@8 @77 - glGetUniformfv@12 @75 - glGetUniformiv@12 @76 - glGetVertexAttribPointerv@12 @80 - glGetVertexAttribfv@12 @78 - glGetVertexAttribiv@12 @79 - glHint@8 @81 - glIsBuffer@4 @82 - glIsEnabled@4 @83 - glIsFramebuffer@4 @84 - glIsProgram@4 @85 - glIsRenderbuffer@4 @86 - glIsShader@4 @87 - glIsTexture@4 @88 - glLineWidth@4 @89 - glLinkProgram@4 @90 - glPixelStorei@8 @91 - glPolygonOffset@8 @92 - glReadPixels@28 @93 - glReleaseShaderCompiler@0 @94 - glRenderbufferStorage@16 @95 - glSampleCoverage@8 @96 - glScissor@16 @97 - glShaderBinary@20 @98 - glShaderSource@16 @99 - glStencilFunc@12 @100 - glStencilFuncSeparate@16 @101 - glStencilMask@4 @102 - glStencilMaskSeparate@8 @103 - glStencilOp@12 @104 - glStencilOpSeparate@16 @105 - glTexImage2D@36 @106 - glTexParameterf@12 @107 - glTexParameterfv@12 @108 - glTexParameteri@12 @109 - glTexParameteriv@12 @110 - glTexSubImage2D@36 @111 - glUniform1f@8 @112 - glUniform1fv@12 @113 - glUniform1i@8 @114 - glUniform1iv@12 @115 - glUniform2f@12 @116 - glUniform2fv@12 @117 - glUniform2i@12 @118 - glUniform2iv@12 @119 - glUniform3f@16 @120 - glUniform3fv@12 @121 - glUniform3i@16 @122 - glUniform3iv@12 @123 - glUniform4f@20 @124 - glUniform4fv@12 @125 - glUniform4i@20 @126 - glUniform4iv@12 @127 - glUniformMatrix2fv@16 @128 - glUniformMatrix3fv@16 @129 - glUniformMatrix4fv@16 @130 - glUseProgram@4 @131 - glValidateProgram@4 @132 - glVertexAttrib1f@8 @133 - glVertexAttrib1fv@8 @134 - glVertexAttrib2f@12 @135 - glVertexAttrib2fv@8 @136 - glVertexAttrib3f@16 @137 - glVertexAttrib3fv@8 @138 - glVertexAttrib4f@20 @139 - glVertexAttrib4fv@8 @140 - glVertexAttribPointer@24 @141 - glViewport@16 @142 + glActiveTexture @1 + glAttachShader @2 + glBindAttribLocation @3 + glBindBuffer @4 + glBindFramebuffer @5 + glBindRenderbuffer @6 + glBindTexture @7 + glBlendColor @8 + glBlendEquation @9 + glBlendEquationSeparate @10 + glBlendFunc @11 + glBlendFuncSeparate @12 + glBufferData @13 + glBufferSubData @14 + glCheckFramebufferStatus @15 + glClear @16 + glClearColor @17 + glClearDepthf @18 + glClearStencil @19 + glColorMask @20 + glCompileShader @21 + glCompressedTexImage2D @22 + glCompressedTexSubImage2D @23 + glCopyTexImage2D @24 + glCopyTexSubImage2D @25 + glCreateProgram @26 + glCreateShader @27 + glCullFace @28 + glDeleteBuffers @29 + glDeleteFramebuffers @30 + glDeleteProgram @32 + glDeleteRenderbuffers @33 + glDeleteShader @34 + glDeleteTextures @31 + glDepthFunc @36 + glDepthMask @37 + glDepthRangef @38 + glDetachShader @35 + glDisable @39 + glDisableVertexAttribArray @40 + glDrawArrays @41 + glDrawElements @42 + glEnable @43 + glEnableVertexAttribArray @44 + glFinish @45 + glFlush @46 + glFramebufferRenderbuffer @47 + glFramebufferTexture2D @48 + glFrontFace @49 + glGenBuffers @50 + glGenFramebuffers @52 + glGenRenderbuffers @53 + glGenTextures @54 + glGenerateMipmap @51 + glGetActiveAttrib @55 + glGetActiveUniform @56 + glGetAttachedShaders @57 + glGetAttribLocation @58 + glGetBooleanv @59 + glGetBufferParameteriv @60 + glGetError @61 + glGetFloatv @62 + glGetFramebufferAttachmentParameteriv @63 + glGetIntegerv @64 + glGetProgramInfoLog @66 + glGetProgramiv @65 + glGetRenderbufferParameteriv @67 + glGetShaderInfoLog @69 + glGetShaderPrecisionFormat @70 + glGetShaderSource @71 + glGetShaderiv @68 + glGetString @72 + glGetTexParameterfv @73 + glGetTexParameteriv @74 + glGetUniformLocation @77 + glGetUniformfv @75 + glGetUniformiv @76 + glGetVertexAttribPointerv @80 + glGetVertexAttribfv @78 + glGetVertexAttribiv @79 + glHint @81 + glIsBuffer @82 + glIsEnabled @83 + glIsFramebuffer @84 + glIsProgram @85 + glIsRenderbuffer @86 + glIsShader @87 + glIsTexture @88 + glLineWidth @89 + glLinkProgram @90 + glPixelStorei @91 + glPolygonOffset @92 + glReadPixels @93 + glReleaseShaderCompiler @94 + glRenderbufferStorage @95 + glSampleCoverage @96 + glScissor @97 + glShaderBinary @98 + glShaderSource @99 + glStencilFunc @100 + glStencilFuncSeparate @101 + glStencilMask @102 + glStencilMaskSeparate @103 + glStencilOp @104 + glStencilOpSeparate @105 + glTexImage2D @106 + glTexParameterf @107 + glTexParameterfv @108 + glTexParameteri @109 + glTexParameteriv @110 + glTexSubImage2D @111 + glUniform1f @112 + glUniform1fv @113 + glUniform1i @114 + glUniform1iv @115 + glUniform2f @116 + glUniform2fv @117 + glUniform2i @118 + glUniform2iv @119 + glUniform3f @120 + glUniform3fv @121 + glUniform3i @122 + glUniform3iv @123 + glUniform4f @124 + glUniform4fv @125 + glUniform4i @126 + glUniform4iv @127 + glUniformMatrix2fv @128 + glUniformMatrix3fv @129 + glUniformMatrix4fv @130 + glUseProgram @131 + glValidateProgram @132 + glVertexAttrib1f @133 + glVertexAttrib1fv @134 + glVertexAttrib2f @135 + glVertexAttrib2fv @136 + glVertexAttrib3f @137 + glVertexAttrib3fv @138 + glVertexAttrib4f @139 + glVertexAttrib4fv @140 + glVertexAttribPointer @141 + glViewport @142 ; Extensions - glBlitFramebufferANGLE@40 @149 - glRenderbufferStorageMultisampleANGLE@20 @150 - glDeleteFencesNV@8 @151 - glFinishFenceNV@4 @152 - glGenFencesNV@8 @153 - glGetFenceivNV@12 @154 - glIsFenceNV@4 @155 - glSetFenceNV@8 @156 - glTestFenceNV@4 @157 - glGetTranslatedShaderSourceANGLE@16 @159 - glTexStorage2DEXT@20 @160 - glGetGraphicsResetStatusEXT@0 @161 - glReadnPixelsEXT@32 @162 - glGetnUniformfvEXT@16 @163 - glGetnUniformivEXT@16 @164 - glGenQueriesEXT@8 @165 - glDeleteQueriesEXT@8 @166 - glIsQueryEXT@4 @167 - glBeginQueryEXT@8 @168 - glEndQueryEXT@4 @169 - glGetQueryivEXT@12 @170 - glGetQueryObjectuivEXT@12 @171 - glVertexAttribDivisorANGLE@8 @172 - glDrawArraysInstancedANGLE@16 @173 - glDrawElementsInstancedANGLE@20 @174 - glProgramBinaryOES@16 @175 - glGetProgramBinaryOES@20 @176 - glDrawBuffersEXT@8 @179 - glMapBufferOES@8 @285 - glUnmapBufferOES@4 @286 - glGetBufferPointervOES@12 @287 - glMapBufferRangeEXT@16 @288 - glFlushMappedBufferRangeEXT@12 @289 - glDiscardFramebufferEXT@12 @293 - glInsertEventMarkerEXT@8 @294 - glPushGroupMarkerEXT@8 @295 - glPopGroupMarkerEXT@0 @296 - glEGLImageTargetTexture2DOES@8 @297 - glEGLImageTargetRenderbufferStorageOES@8 @298 - glBindVertexArrayOES@4 @299 - glDeleteVertexArraysOES@8 @300 - glGenVertexArraysOES@8 @301 - glIsVertexArrayOES@4 @302 - glDebugMessageControlKHR@24 @303 - glDebugMessageInsertKHR@24 @304 - glDebugMessageCallbackKHR@8 @305 - glGetDebugMessageLogKHR@32 @306 - glPushDebugGroupKHR@16 @307 - glPopDebugGroupKHR@0 @308 - glObjectLabelKHR@16 @309 - glGetObjectLabelKHR@20 @310 - glObjectPtrLabelKHR@12 @311 - glGetObjectPtrLabelKHR@16 @312 - glGetPointervKHR@8 @313 - glQueryCounterEXT@8 @314 - glGetQueryObjectivEXT@12 @315 - glGetQueryObjecti64vEXT@12 @316 - glGetQueryObjectui64vEXT@12 @317 + glBlitFramebufferANGLE @149 + glRenderbufferStorageMultisampleANGLE @150 + glDeleteFencesNV @151 + glFinishFenceNV @152 + glGenFencesNV @153 + glGetFenceivNV @154 + glIsFenceNV @155 + glSetFenceNV @156 + glTestFenceNV @157 + glGetTranslatedShaderSourceANGLE @159 + glTexStorage2DEXT @160 + glGetGraphicsResetStatusEXT @161 + glReadnPixelsEXT @162 + glGetnUniformfvEXT @163 + glGetnUniformivEXT @164 + glGenQueriesEXT @165 + glDeleteQueriesEXT @166 + glIsQueryEXT @167 + glBeginQueryEXT @168 + glEndQueryEXT @169 + glGetQueryivEXT @170 + glGetQueryObjectuivEXT @171 + glVertexAttribDivisorANGLE @172 + glDrawArraysInstancedANGLE @173 + glDrawElementsInstancedANGLE @174 + glProgramBinaryOES @175 + glGetProgramBinaryOES @176 + glDrawBuffersEXT @179 + glMapBufferOES @285 + glUnmapBufferOES @286 + glGetBufferPointervOES @287 + glMapBufferRangeEXT @288 + glFlushMappedBufferRangeEXT @289 + glDiscardFramebufferEXT @293 + glInsertEventMarkerEXT @294 + glPushGroupMarkerEXT @295 + glPopGroupMarkerEXT @296 + glEGLImageTargetTexture2DOES @297 + glEGLImageTargetRenderbufferStorageOES @298 + glBindVertexArrayOES @299 + glDeleteVertexArraysOES @300 + glGenVertexArraysOES @301 + glIsVertexArrayOES @302 + glDebugMessageControlKHR @303 + glDebugMessageInsertKHR @304 + glDebugMessageCallbackKHR @305 + glGetDebugMessageLogKHR @306 + glPushDebugGroupKHR @307 + glPopDebugGroupKHR @308 + glObjectLabelKHR @309 + glGetObjectLabelKHR @310 + glObjectPtrLabelKHR @311 + glGetObjectPtrLabelKHR @312 + glGetPointervKHR @313 + glQueryCounterEXT @314 + glGetQueryObjectivEXT @315 + glGetQueryObjecti64vEXT @316 + glGetQueryObjectui64vEXT @317 + glBindUniformLocationCHROMIUM @318 + glCoverageModulationCHROMIUM @319 + + glMatrixLoadfCHROMIUM @320 + glMatrixLoadIdentityCHROMIUM @321 + glGenPathsCHROMIUM @322 + glDeletePathsCHROMIUM @323 + glIsPathCHROMIUM @324 + glPathCommandsCHROMIUM @325 + glPathParameterfCHROMIUM @326 + glPathParameteriCHROMIUM @327 + glGetPathParameterfvCHROMIUM @328 + glGetPathParameterivCHROMIUM @329 + glPathStencilFuncCHROMIUM @330 + glStencilFillPathCHROMIUM @331 + glStencilStrokePathCHROMIUM @332 + glCoverFillPathCHROMIUM @333 + glCoverStrokePathCHROMIUM @334 + glStencilThenCoverFillPathCHROMIUM @335 + glStencilThenCoverStrokePathCHROMIUM @336 + glCoverFillPathInstancedCHROMIUM @337 + glCoverStrokePathInstancedCHROMIUM @338 + glStencilStrokePathInstancedCHROMIUM @339 + glStencilFillPathInstancedCHROMIUM @340 + glStencilThenCoverFillPathInstancedCHROMIUM @341 + glStencilThenCoverStrokePathInstancedCHROMIUM @342 + glBindFragmentInputLocationCHROMIUM @343 + glProgramPathFragmentInputGenCHROMIUM @344 + + glFramebufferTextureMultiviewLayeredANGLE @413 + glFramebufferTextureMultiviewSideBySideANGLE @414 + glRequestExtensionANGLE @415 ; GLES 3.0 Functions - glReadBuffer@4 @180 - glDrawRangeElements@24 @181 - glTexImage3D@40 @182 - glTexSubImage3D@44 @183 - glCopyTexSubImage3D@36 @184 - glCompressedTexImage3D@36 @185 - glCompressedTexSubImage3D@44 @186 - glGenQueries@8 @187 - glDeleteQueries@8 @188 - glIsQuery@4 @189 - glBeginQuery@8 @190 - glEndQuery@4 @191 - glGetQueryiv@12 @192 - glGetQueryObjectuiv@12 @193 - glUnmapBuffer@4 @194 - glGetBufferPointerv@12 @195 - glDrawBuffers@8 @196 - glUniformMatrix2x3fv@16 @197 - glUniformMatrix3x2fv@16 @198 - glUniformMatrix2x4fv@16 @199 - glUniformMatrix4x2fv@16 @200 - glUniformMatrix3x4fv@16 @201 - glUniformMatrix4x3fv@16 @202 - glBlitFramebuffer@40 @203 - glRenderbufferStorageMultisample@20 @204 - glFramebufferTextureLayer@20 @205 - glMapBufferRange@16 @206 - glFlushMappedBufferRange@12 @207 - glBindVertexArray@4 @208 - glDeleteVertexArrays@8 @209 - glGenVertexArrays@8 @210 - glIsVertexArray@4 @211 - glGetIntegeri_v@12 @212 - glBeginTransformFeedback@4 @213 - glEndTransformFeedback@0 @214 - glBindBufferRange@20 @215 - glBindBufferBase@12 @216 - glTransformFeedbackVaryings@16 @217 - glGetTransformFeedbackVarying@28 @218 - glVertexAttribIPointer@20 @219 - glGetVertexAttribIiv@12 @220 - glGetVertexAttribIuiv@12 @221 - glVertexAttribI4i@20 @222 - glVertexAttribI4ui@20 @223 - glVertexAttribI4iv@8 @224 - glVertexAttribI4uiv@8 @225 - glGetUniformuiv@12 @226 - glGetFragDataLocation@8 @227 - glUniform1ui@8 @228 - glUniform2ui@12 @229 - glUniform3ui@16 @230 - glUniform4ui@20 @231 - glUniform1uiv@12 @232 - glUniform2uiv@12 @233 - glUniform3uiv@12 @234 - glUniform4uiv@12 @235 - glClearBufferiv@12 @236 - glClearBufferuiv@12 @237 - glClearBufferfv@12 @238 - glClearBufferfi@16 @239 - glGetStringi@8 @240 - glCopyBufferSubData@20 @241 - glGetUniformIndices@16 @242 - glGetActiveUniformsiv@20 @243 - glGetUniformBlockIndex@8 @244 - glGetActiveUniformBlockiv@16 @245 - glGetActiveUniformBlockName@20 @246 - glUniformBlockBinding@12 @247 - glDrawArraysInstanced@16 @248 - glDrawElementsInstanced@20 @249 - glFenceSync@8 @250 - glIsSync@4 @251 - glDeleteSync@4 @252 - glClientWaitSync@16 @253 - glWaitSync@16 @254 - glGetInteger64v@8 @255 - glGetSynciv@20 @256 - glGetInteger64i_v@12 @257 - glGetBufferParameteri64v@12 @258 - glGenSamplers@8 @259 - glDeleteSamplers@8 @260 - glIsSampler@4 @261 - glBindSampler@8 @262 - glSamplerParameteri@12 @263 - glSamplerParameteriv@12 @264 - glSamplerParameterf@12 @265 - glSamplerParameterfv@12 @266 - glGetSamplerParameteriv@12 @267 - glGetSamplerParameterfv@12 @268 - glVertexAttribDivisor@8 @269 - glBindTransformFeedback@8 @270 - glDeleteTransformFeedbacks@8 @271 - glGenTransformFeedbacks@8 @272 - glIsTransformFeedback@4 @273 - glPauseTransformFeedback@0 @274 - glResumeTransformFeedback@0 @275 - glGetProgramBinary@20 @276 - glProgramBinary@16 @277 - glProgramParameteri@12 @278 - glInvalidateFramebuffer@12 @279 - glInvalidateSubFramebuffer@28 @280 - glTexStorage2D@20 @281 - glTexStorage3D@24 @282 - glGetInternalformativ@20 @283 + glReadBuffer @180 + glDrawRangeElements @181 + glTexImage3D @182 + glTexSubImage3D @183 + glCopyTexSubImage3D @184 + glCompressedTexImage3D @185 + glCompressedTexSubImage3D @186 + glGenQueries @187 + glDeleteQueries @188 + glIsQuery @189 + glBeginQuery @190 + glEndQuery @191 + glGetQueryiv @192 + glGetQueryObjectuiv @193 + glUnmapBuffer @194 + glGetBufferPointerv @195 + glDrawBuffers @196 + glUniformMatrix2x3fv @197 + glUniformMatrix3x2fv @198 + glUniformMatrix2x4fv @199 + glUniformMatrix4x2fv @200 + glUniformMatrix3x4fv @201 + glUniformMatrix4x3fv @202 + glBlitFramebuffer @203 + glRenderbufferStorageMultisample @204 + glFramebufferTextureLayer @205 + glMapBufferRange @206 + glFlushMappedBufferRange @207 + glBindVertexArray @208 + glDeleteVertexArrays @209 + glGenVertexArrays @210 + glIsVertexArray @211 + glGetIntegeri_v @212 + glBeginTransformFeedback @213 + glEndTransformFeedback @214 + glBindBufferRange @215 + glBindBufferBase @216 + glTransformFeedbackVaryings @217 + glGetTransformFeedbackVarying @218 + glVertexAttribIPointer @219 + glGetVertexAttribIiv @220 + glGetVertexAttribIuiv @221 + glVertexAttribI4i @222 + glVertexAttribI4ui @223 + glVertexAttribI4iv @224 + glVertexAttribI4uiv @225 + glGetUniformuiv @226 + glGetFragDataLocation @227 + glUniform1ui @228 + glUniform2ui @229 + glUniform3ui @230 + glUniform4ui @231 + glUniform1uiv @232 + glUniform2uiv @233 + glUniform3uiv @234 + glUniform4uiv @235 + glClearBufferiv @236 + glClearBufferuiv @237 + glClearBufferfv @238 + glClearBufferfi @239 + glGetStringi @240 + glCopyBufferSubData @241 + glGetUniformIndices @242 + glGetActiveUniformsiv @243 + glGetUniformBlockIndex @244 + glGetActiveUniformBlockiv @245 + glGetActiveUniformBlockName @246 + glUniformBlockBinding @247 + glDrawArraysInstanced @248 + glDrawElementsInstanced @249 + glFenceSync @250 + glIsSync @251 + glDeleteSync @252 + glClientWaitSync @253 + glWaitSync @254 + glGetInteger64v @255 + glGetSynciv @256 + glGetInteger64i_v @257 + glGetBufferParameteri64v @258 + glGenSamplers @259 + glDeleteSamplers @260 + glIsSampler @261 + glBindSampler @262 + glSamplerParameteri @263 + glSamplerParameteriv @264 + glSamplerParameterf @265 + glSamplerParameterfv @266 + glGetSamplerParameteriv @267 + glGetSamplerParameterfv @268 + glVertexAttribDivisor @269 + glBindTransformFeedback @270 + glDeleteTransformFeedbacks @271 + glGenTransformFeedbacks @272 + glIsTransformFeedback @273 + glPauseTransformFeedback @274 + glResumeTransformFeedback @275 + glGetProgramBinary @276 + glProgramBinary @277 + glProgramParameteri @278 + glInvalidateFramebuffer @279 + glInvalidateSubFramebuffer @280 + glTexStorage2D @281 + glTexStorage3D @282 + glGetInternalformativ @283 - ; ANGLE Platform Implementation - ANGLEPlatformCurrent@0 @290 - ANGLEPlatformInitialize@4 @291 - ANGLEPlatformShutdown@0 @292 - \ No newline at end of file + ; GLES 3.1 Functions + glDispatchCompute @345 + glDispatchComputeIndirect @346 + glDrawArraysIndirect @347 + glDrawElementsIndirect @348 + glFramebufferParameteri @349 + glGetFramebufferParameteriv @350 + glGetProgramInterfaceiv @351 + glGetProgramResourceIndex @352 + glGetProgramResourceName @353 + glGetProgramResourceiv @354 + glGetProgramResourceLocation @355 + glUseProgramStages @356 + glActiveShaderProgram @357 + glCreateShaderProgramv @358 + glBindProgramPipeline @359 + glDeleteProgramPipelines @360 + glGenProgramPipelines @361 + glIsProgramPipeline @362 + glGetProgramPipelineiv @363 + glProgramUniform1i @364 + glProgramUniform2i @365 + glProgramUniform3i @366 + glProgramUniform4i @367 + glProgramUniform1ui @368 + glProgramUniform2ui @369 + glProgramUniform3ui @370 + glProgramUniform4ui @371 + glProgramUniform1f @372 + glProgramUniform2f @373 + glProgramUniform3f @374 + glProgramUniform4f @375 + glProgramUniform1iv @376 + glProgramUniform2iv @377 + glProgramUniform3iv @378 + glProgramUniform4iv @379 + glProgramUniform1uiv @380 + glProgramUniform2uiv @381 + glProgramUniform3uiv @382 + glProgramUniform4uiv @383 + glProgramUniform1fv @384 + glProgramUniform2fv @385 + glProgramUniform3fv @386 + glProgramUniform4fv @387 + glProgramUniformMatrix2fv @388 + glProgramUniformMatrix3fv @389 + glProgramUniformMatrix4fv @390 + glProgramUniformMatrix2x3fv @391 + glProgramUniformMatrix3x2fv @392 + glProgramUniformMatrix2x4fv @393 + glProgramUniformMatrix4x2fv @394 + glProgramUniformMatrix3x4fv @395 + glProgramUniformMatrix4x3fv @396 + glValidateProgramPipeline @397 + glGetProgramPipelineInfoLog @398 + glBindImageTexture @399 + glGetBooleani_v @400 + glMemoryBarrier @401 + glMemoryBarrierByRegion @402 + glTexStorage2DMultisample @403 + glGetMultisamplefv @404 + glSampleMaski @405 + glGetTexLevelParameteriv @406 + glGetTexLevelParameterfv @407 + glBindVertexBuffer @408 + glVertexAttribFormat @409 + glVertexAttribIFormat @410 + glVertexAttribBinding @411 + glVertexBindingDivisor @412 diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def index e0c3823abf..9a00a9f8ae 100644 --- a/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def +++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def @@ -202,6 +202,38 @@ EXPORTS glGetQueryObjectivEXT @315 glGetQueryObjecti64vEXT @316 glGetQueryObjectui64vEXT @317 + glBindUniformLocationCHROMIUM @318 + glCoverageModulationCHROMIUM @319 + + glMatrixLoadfCHROMIUM @320 + glMatrixLoadIdentityCHROMIUM @321 + glGenPathsCHROMIUM @322 + glDeletePathsCHROMIUM @323 + glIsPathCHROMIUM @324 + glPathCommandsCHROMIUM @325 + glPathParameterfCHROMIUM @326 + glPathParameteriCHROMIUM @327 + glGetPathParameterfvCHROMIUM @328 + glGetPathParameterivCHROMIUM @329 + glPathStencilFuncCHROMIUM @330 + glStencilFillPathCHROMIUM @331 + glStencilStrokePathCHROMIUM @332 + glCoverFillPathCHROMIUM @333 + glCoverStrokePathCHROMIUM @334 + glStencilThenCoverFillPathCHROMIUM @335 + glStencilThenCoverStrokePathCHROMIUM @336 + glCoverFillPathInstancedCHROMIUM @337 + glCoverStrokePathInstancedCHROMIUM @338 + glStencilStrokePathInstancedCHROMIUM @339 + glStencilFillPathInstancedCHROMIUM @340 + glStencilThenCoverFillPathInstancedCHROMIUM @341 + glStencilThenCoverStrokePathInstancedCHROMIUM @342 + glBindFragmentInputLocationCHROMIUM @343 + glProgramPathFragmentInputGenCHROMIUM @344 + + glFramebufferTextureMultiviewLayeredANGLE @413 + glFramebufferTextureMultiviewSideBySideANGLE @414 + glRequestExtensionANGLE @415 ; GLES 3.0 Functions glReadBuffer @180 @@ -309,7 +341,72 @@ EXPORTS glTexStorage3D @282 glGetInternalformativ @283 - ; ANGLE Platform Implementation - ANGLEPlatformCurrent @290 - ANGLEPlatformInitialize @291 - ANGLEPlatformShutdown @292 + ; GLES 3.1 Functions + glDispatchCompute @345 + glDispatchComputeIndirect @346 + glDrawArraysIndirect @347 + glDrawElementsIndirect @348 + glFramebufferParameteri @349 + glGetFramebufferParameteriv @350 + glGetProgramInterfaceiv @351 + glGetProgramResourceIndex @352 + glGetProgramResourceName @353 + glGetProgramResourceiv @354 + glGetProgramResourceLocation @355 + glUseProgramStages @356 + glActiveShaderProgram @357 + glCreateShaderProgramv @358 + glBindProgramPipeline @359 + glDeleteProgramPipelines @360 + glGenProgramPipelines @361 + glIsProgramPipeline @362 + glGetProgramPipelineiv @363 + glProgramUniform1i @364 + glProgramUniform2i @365 + glProgramUniform3i @366 + glProgramUniform4i @367 + glProgramUniform1ui @368 + glProgramUniform2ui @369 + glProgramUniform3ui @370 + glProgramUniform4ui @371 + glProgramUniform1f @372 + glProgramUniform2f @373 + glProgramUniform3f @374 + glProgramUniform4f @375 + glProgramUniform1iv @376 + glProgramUniform2iv @377 + glProgramUniform3iv @378 + glProgramUniform4iv @379 + glProgramUniform1uiv @380 + glProgramUniform2uiv @381 + glProgramUniform3uiv @382 + glProgramUniform4uiv @383 + glProgramUniform1fv @384 + glProgramUniform2fv @385 + glProgramUniform3fv @386 + glProgramUniform4fv @387 + glProgramUniformMatrix2fv @388 + glProgramUniformMatrix3fv @389 + glProgramUniformMatrix4fv @390 + glProgramUniformMatrix2x3fv @391 + glProgramUniformMatrix3x2fv @392 + glProgramUniformMatrix2x4fv @393 + glProgramUniformMatrix4x2fv @394 + glProgramUniformMatrix3x4fv @395 + glProgramUniformMatrix4x3fv @396 + glValidateProgramPipeline @397 + glGetProgramPipelineInfoLog @398 + glBindImageTexture @399 + glGetBooleani_v @400 + glMemoryBarrier @401 + glMemoryBarrierByRegion @402 + glTexStorage2DMultisample @403 + glGetMultisamplefv @404 + glSampleMaski @405 + glGetTexLevelParameteriv @406 + glGetTexLevelParameterfv @407 + glBindVertexBuffer @408 + glVertexAttribFormat @409 + glVertexAttribIFormat @410 + glVertexAttribBinding @411 + glVertexBindingDivisor @412 diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def deleted file mode 100644 index 5a4966f66d..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def +++ /dev/null @@ -1,316 +0,0 @@ -LIBRARY libGLESv2d -EXPORTS - glActiveTexture@4 @1 - glAttachShader@8 @2 - glBindAttribLocation@12 @3 - glBindBuffer@8 @4 - glBindFramebuffer@8 @5 - glBindRenderbuffer@8 @6 - glBindTexture@8 @7 - glBlendColor@16 @8 - glBlendEquation@4 @9 - glBlendEquationSeparate@8 @10 - glBlendFunc@8 @11 - glBlendFuncSeparate@16 @12 - glBufferData@16 @13 - glBufferSubData@16 @14 - glCheckFramebufferStatus@4 @15 - glClear@4 @16 - glClearColor@16 @17 - glClearDepthf@4 @18 - glClearStencil@4 @19 - glColorMask@16 @20 - glCompileShader@4 @21 - glCompressedTexImage2D@32 @22 - glCompressedTexSubImage2D@36 @23 - glCopyTexImage2D@32 @24 - glCopyTexSubImage2D@32 @25 - glCreateProgram@0 @26 - glCreateShader@4 @27 - glCullFace@4 @28 - glDeleteBuffers@8 @29 - glDeleteFramebuffers@8 @30 - glDeleteProgram@4 @32 - glDeleteRenderbuffers@8 @33 - glDeleteShader@4 @34 - glDeleteTextures@8 @31 - glDepthFunc@4 @36 - glDepthMask@4 @37 - glDepthRangef@8 @38 - glDetachShader@8 @35 - glDisable@4 @39 - glDisableVertexAttribArray@4 @40 - glDrawArrays@12 @41 - glDrawElements@16 @42 - glEnable@4 @43 - glEnableVertexAttribArray@4 @44 - glFinish@0 @45 - glFlush@0 @46 - glFramebufferRenderbuffer@16 @47 - glFramebufferTexture2D@20 @48 - glFrontFace@4 @49 - glGenBuffers@8 @50 - glGenFramebuffers@8 @52 - glGenRenderbuffers@8 @53 - glGenTextures@8 @54 - glGenerateMipmap@4 @51 - glGetActiveAttrib@28 @55 - glGetActiveUniform@28 @56 - glGetAttachedShaders@16 @57 - glGetAttribLocation@8 @58 - glGetBooleanv@8 @59 - glGetBufferParameteriv@12 @60 - glGetError@0 @61 - glGetFloatv@8 @62 - glGetFramebufferAttachmentParameteriv@16 @63 - glGetIntegerv@8 @64 - glGetProgramInfoLog@16 @66 - glGetProgramiv@12 @65 - glGetRenderbufferParameteriv@12 @67 - glGetShaderInfoLog@16 @69 - glGetShaderPrecisionFormat@16 @70 - glGetShaderSource@16 @71 - glGetShaderiv@12 @68 - glGetString@4 @72 - glGetTexParameterfv@12 @73 - glGetTexParameteriv@12 @74 - glGetUniformLocation@8 @77 - glGetUniformfv@12 @75 - glGetUniformiv@12 @76 - glGetVertexAttribPointerv@12 @80 - glGetVertexAttribfv@12 @78 - glGetVertexAttribiv@12 @79 - glHint@8 @81 - glIsBuffer@4 @82 - glIsEnabled@4 @83 - glIsFramebuffer@4 @84 - glIsProgram@4 @85 - glIsRenderbuffer@4 @86 - glIsShader@4 @87 - glIsTexture@4 @88 - glLineWidth@4 @89 - glLinkProgram@4 @90 - glPixelStorei@8 @91 - glPolygonOffset@8 @92 - glReadPixels@28 @93 - glReleaseShaderCompiler@0 @94 - glRenderbufferStorage@16 @95 - glSampleCoverage@8 @96 - glScissor@16 @97 - glShaderBinary@20 @98 - glShaderSource@16 @99 - glStencilFunc@12 @100 - glStencilFuncSeparate@16 @101 - glStencilMask@4 @102 - glStencilMaskSeparate@8 @103 - glStencilOp@12 @104 - glStencilOpSeparate@16 @105 - glTexImage2D@36 @106 - glTexParameterf@12 @107 - glTexParameterfv@12 @108 - glTexParameteri@12 @109 - glTexParameteriv@12 @110 - glTexSubImage2D@36 @111 - glUniform1f@8 @112 - glUniform1fv@12 @113 - glUniform1i@8 @114 - glUniform1iv@12 @115 - glUniform2f@12 @116 - glUniform2fv@12 @117 - glUniform2i@12 @118 - glUniform2iv@12 @119 - glUniform3f@16 @120 - glUniform3fv@12 @121 - glUniform3i@16 @122 - glUniform3iv@12 @123 - glUniform4f@20 @124 - glUniform4fv@12 @125 - glUniform4i@20 @126 - glUniform4iv@12 @127 - glUniformMatrix2fv@16 @128 - glUniformMatrix3fv@16 @129 - glUniformMatrix4fv@16 @130 - glUseProgram@4 @131 - glValidateProgram@4 @132 - glVertexAttrib1f@8 @133 - glVertexAttrib1fv@8 @134 - glVertexAttrib2f@12 @135 - glVertexAttrib2fv@8 @136 - glVertexAttrib3f@16 @137 - glVertexAttrib3fv@8 @138 - glVertexAttrib4f@20 @139 - glVertexAttrib4fv@8 @140 - glVertexAttribPointer@24 @141 - glViewport@16 @142 - - ; Extensions - glBlitFramebufferANGLE@40 @149 - glRenderbufferStorageMultisampleANGLE@20 @150 - glDeleteFencesNV@8 @151 - glFinishFenceNV@4 @152 - glGenFencesNV@8 @153 - glGetFenceivNV@12 @154 - glIsFenceNV@4 @155 - glSetFenceNV@8 @156 - glTestFenceNV@4 @157 - glGetTranslatedShaderSourceANGLE@16 @159 - glTexStorage2DEXT@20 @160 - glGetGraphicsResetStatusEXT@0 @161 - glReadnPixelsEXT@32 @162 - glGetnUniformfvEXT@16 @163 - glGetnUniformivEXT@16 @164 - glGenQueriesEXT@8 @165 - glDeleteQueriesEXT@8 @166 - glIsQueryEXT@4 @167 - glBeginQueryEXT@8 @168 - glEndQueryEXT@4 @169 - glGetQueryivEXT@12 @170 - glGetQueryObjectuivEXT@12 @171 - glVertexAttribDivisorANGLE@8 @172 - glDrawArraysInstancedANGLE@16 @173 - glDrawElementsInstancedANGLE@20 @174 - glProgramBinaryOES@16 @175 - glGetProgramBinaryOES@20 @176 - glDrawBuffersEXT@8 @179 - glMapBufferOES@8 @285 - glUnmapBufferOES@4 @286 - glGetBufferPointervOES@12 @287 - glMapBufferRangeEXT@16 @288 - glFlushMappedBufferRangeEXT@12 @289 - glDiscardFramebufferEXT@12 @293 - glInsertEventMarkerEXT@8 @294 - glPushGroupMarkerEXT@8 @295 - glPopGroupMarkerEXT@0 @296 - glEGLImageTargetTexture2DOES@8 @297 - glEGLImageTargetRenderbufferStorageOES@8 @298 - glBindVertexArrayOES@4 @299 - glDeleteVertexArraysOES@8 @300 - glGenVertexArraysOES@8 @301 - glIsVertexArrayOES@4 @302 - glDebugMessageControlKHR@24 @303 - glDebugMessageInsertKHR@24 @304 - glDebugMessageCallbackKHR@8 @305 - glGetDebugMessageLogKHR@32 @306 - glPushDebugGroupKHR@16 @307 - glPopDebugGroupKHR@0 @308 - glObjectLabelKHR@16 @309 - glGetObjectLabelKHR@20 @310 - glObjectPtrLabelKHR@12 @311 - glGetObjectPtrLabelKHR@16 @312 - glGetPointervKHR@8 @313 - glQueryCounterEXT@8 @314 - glGetQueryObjectivEXT@12 @315 - glGetQueryObjecti64vEXT@12 @316 - glGetQueryObjectui64vEXT@12 @317 - - ; GLES 3.0 Functions - glReadBuffer@4 @180 - glDrawRangeElements@24 @181 - glTexImage3D@40 @182 - glTexSubImage3D@44 @183 - glCopyTexSubImage3D@36 @184 - glCompressedTexImage3D@36 @185 - glCompressedTexSubImage3D@44 @186 - glGenQueries@8 @187 - glDeleteQueries@8 @188 - glIsQuery@4 @189 - glBeginQuery@8 @190 - glEndQuery@4 @191 - glGetQueryiv@12 @192 - glGetQueryObjectuiv@12 @193 - glUnmapBuffer@4 @194 - glGetBufferPointerv@12 @195 - glDrawBuffers@8 @196 - glUniformMatrix2x3fv@16 @197 - glUniformMatrix3x2fv@16 @198 - glUniformMatrix2x4fv@16 @199 - glUniformMatrix4x2fv@16 @200 - glUniformMatrix3x4fv@16 @201 - glUniformMatrix4x3fv@16 @202 - glBlitFramebuffer@40 @203 - glRenderbufferStorageMultisample@20 @204 - glFramebufferTextureLayer@20 @205 - glMapBufferRange@16 @206 - glFlushMappedBufferRange@12 @207 - glBindVertexArray@4 @208 - glDeleteVertexArrays@8 @209 - glGenVertexArrays@8 @210 - glIsVertexArray@4 @211 - glGetIntegeri_v@12 @212 - glBeginTransformFeedback@4 @213 - glEndTransformFeedback@0 @214 - glBindBufferRange@20 @215 - glBindBufferBase@12 @216 - glTransformFeedbackVaryings@16 @217 - glGetTransformFeedbackVarying@28 @218 - glVertexAttribIPointer@20 @219 - glGetVertexAttribIiv@12 @220 - glGetVertexAttribIuiv@12 @221 - glVertexAttribI4i@20 @222 - glVertexAttribI4ui@20 @223 - glVertexAttribI4iv@8 @224 - glVertexAttribI4uiv@8 @225 - glGetUniformuiv@12 @226 - glGetFragDataLocation@8 @227 - glUniform1ui@8 @228 - glUniform2ui@12 @229 - glUniform3ui@16 @230 - glUniform4ui@20 @231 - glUniform1uiv@12 @232 - glUniform2uiv@12 @233 - glUniform3uiv@12 @234 - glUniform4uiv@12 @235 - glClearBufferiv@12 @236 - glClearBufferuiv@12 @237 - glClearBufferfv@12 @238 - glClearBufferfi@16 @239 - glGetStringi@8 @240 - glCopyBufferSubData@20 @241 - glGetUniformIndices@16 @242 - glGetActiveUniformsiv@20 @243 - glGetUniformBlockIndex@8 @244 - glGetActiveUniformBlockiv@16 @245 - glGetActiveUniformBlockName@20 @246 - glUniformBlockBinding@12 @247 - glDrawArraysInstanced@16 @248 - glDrawElementsInstanced@20 @249 - glFenceSync@8 @250 - glIsSync@4 @251 - glDeleteSync@4 @252 - glClientWaitSync@16 @253 - glWaitSync@16 @254 - glGetInteger64v@8 @255 - glGetSynciv@20 @256 - glGetInteger64i_v@12 @257 - glGetBufferParameteri64v@12 @258 - glGenSamplers@8 @259 - glDeleteSamplers@8 @260 - glIsSampler@4 @261 - glBindSampler@8 @262 - glSamplerParameteri@12 @263 - glSamplerParameteriv@12 @264 - glSamplerParameterf@12 @265 - glSamplerParameterfv@12 @266 - glGetSamplerParameteriv@12 @267 - glGetSamplerParameterfv@12 @268 - glVertexAttribDivisor@8 @269 - glBindTransformFeedback@8 @270 - glDeleteTransformFeedbacks@8 @271 - glGenTransformFeedbacks@8 @272 - glIsTransformFeedback@4 @273 - glPauseTransformFeedback@0 @274 - glResumeTransformFeedback@0 @275 - glGetProgramBinary@20 @276 - glProgramBinary@16 @277 - glProgramParameteri@12 @278 - glInvalidateFramebuffer@12 @279 - glInvalidateSubFramebuffer@28 @280 - glTexStorage2D@20 @281 - glTexStorage3D@24 @282 - glGetInternalformativ@20 @283 - - ; ANGLE Platform Implementation - ANGLEPlatformCurrent@0 @290 - ANGLEPlatformInitialize@4 @291 - ANGLEPlatformShutdown@0 @292 - \ No newline at end of file diff --git a/src/3rdparty/angle/src/libGLESv2/proc_table.h b/src/3rdparty/angle/src/libGLESv2/proc_table.h new file mode 100644 index 0000000000..f718291be7 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/proc_table.h @@ -0,0 +1,24 @@ +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// getProcAddress loader table: +// Mapping from a string entry point name to function address. +// + +#ifndef LIBGLESV2_PROC_TABLE_H_ +#define LIBGLESV2_PROC_TABLE_H_ + +#include +#include + +namespace egl +{ +using ProcEntry = std::pair; + +extern ProcEntry g_procTable[]; +extern size_t g_numProcs; +} // namespace egl + +#endif // LIBGLESV2_PROC_TABLE_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/proc_table_autogen.cpp b/src/3rdparty/angle/src/libGLESv2/proc_table_autogen.cpp new file mode 100644 index 0000000000..f294c1edc3 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/proc_table_autogen.cpp @@ -0,0 +1,548 @@ +// GENERATED FILE - DO NOT EDIT. +// Generated by gen_proc_table.py using data from proc_table_data.json. +// +// Copyright 2017 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// getProcAddress loader table: +// Mapping from a string entry point name to function address. +// + +#include "libGLESv2/proc_table.h" + +#include "libGLESv2/entry_points_egl.h" +#include "libGLESv2/entry_points_egl_ext.h" +#include "libGLESv2/entry_points_gles_2_0_autogen.h" +#include "libGLESv2/entry_points_gles_2_0_ext.h" +#include "libGLESv2/entry_points_gles_3_0_autogen.h" +#include "libGLESv2/entry_points_gles_3_1_autogen.h" +#include "platform/Platform.h" + +#define P(FUNC) reinterpret_cast<__eglMustCastToProperFunctionPointerType>(FUNC) + +namespace egl +{ +ProcEntry g_procTable[] = { + {"ANGLEGetDisplayPlatform", P(ANGLEGetDisplayPlatform)}, + {"ANGLEResetDisplayPlatform", P(ANGLEResetDisplayPlatform)}, + {"eglBindAPI", P(egl::BindAPI)}, + {"eglBindTexImage", P(egl::BindTexImage)}, + {"eglChooseConfig", P(egl::ChooseConfig)}, + {"eglClientWaitSync", P(egl::ClientWaitSync)}, + {"eglCopyBuffers", P(egl::CopyBuffers)}, + {"eglCreateContext", P(egl::CreateContext)}, + {"eglCreateDeviceANGLE", P(egl::CreateDeviceANGLE)}, + {"eglCreateImage", P(egl::CreateImage)}, + {"eglCreateImageKHR", P(egl::CreateImageKHR)}, + {"eglCreatePbufferFromClientBuffer", P(egl::CreatePbufferFromClientBuffer)}, + {"eglCreatePbufferSurface", P(egl::CreatePbufferSurface)}, + {"eglCreatePixmapSurface", P(egl::CreatePixmapSurface)}, + {"eglCreatePlatformPixmapSurface", P(egl::CreatePlatformPixmapSurface)}, + {"eglCreatePlatformWindowSurface", P(egl::CreatePlatformWindowSurface)}, + {"eglCreateStreamKHR", P(egl::CreateStreamKHR)}, + {"eglCreateStreamProducerD3DTextureNV12ANGLE", P(egl::CreateStreamProducerD3DTextureNV12ANGLE)}, + {"eglCreateSync", P(egl::CreateSync)}, + {"eglCreateWindowSurface", P(egl::CreateWindowSurface)}, + {"eglDestroyContext", P(egl::DestroyContext)}, + {"eglDestroyImage", P(egl::DestroyImage)}, + {"eglDestroyImageKHR", P(egl::DestroyImageKHR)}, + {"eglDestroyStreamKHR", P(egl::DestroyStreamKHR)}, + {"eglDestroySurface", P(egl::DestroySurface)}, + {"eglDestroySync", P(egl::DestroySync)}, + {"eglGetConfigAttrib", P(egl::GetConfigAttrib)}, + {"eglGetConfigs", P(egl::GetConfigs)}, + {"eglGetCurrentContext", P(egl::GetCurrentContext)}, + {"eglGetCurrentDisplay", P(egl::GetCurrentDisplay)}, + {"eglGetCurrentSurface", P(egl::GetCurrentSurface)}, + {"eglGetDisplay", P(egl::GetDisplay)}, + {"eglGetError", P(egl::GetError)}, + {"eglGetPlatformDisplay", P(egl::GetPlatformDisplay)}, + {"eglGetPlatformDisplayEXT", P(egl::GetPlatformDisplayEXT)}, + {"eglGetProcAddress", P(egl::GetProcAddress)}, + {"eglGetSyncAttrib", P(egl::GetSyncAttrib)}, + {"eglGetSyncValuesCHROMIUM", P(egl::GetSyncValuesCHROMIUM)}, + {"eglInitialize", P(egl::Initialize)}, + {"eglMakeCurrent", P(egl::MakeCurrent)}, + {"eglPostSubBufferNV", P(egl::PostSubBufferNV)}, + {"eglProgramCacheGetAttribANGLE", P(egl::ProgramCacheGetAttribANGLE)}, + {"eglProgramCachePopulateANGLE", P(egl::ProgramCachePopulateANGLE)}, + {"eglProgramCacheQueryANGLE", P(egl::ProgramCacheQueryANGLE)}, + {"eglProgramCacheResizeANGLE", P(egl::ProgramCacheResizeANGLE)}, + {"eglQueryAPI", P(egl::QueryAPI)}, + {"eglQueryContext", P(egl::QueryContext)}, + {"eglQueryDeviceAttribEXT", P(egl::QueryDeviceAttribEXT)}, + {"eglQueryDeviceStringEXT", P(egl::QueryDeviceStringEXT)}, + {"eglQueryDisplayAttribEXT", P(egl::QueryDisplayAttribEXT)}, + {"eglQueryStreamKHR", P(egl::QueryStreamKHR)}, + {"eglQueryStreamu64KHR", P(egl::QueryStreamu64KHR)}, + {"eglQueryString", P(egl::QueryString)}, + {"eglQuerySurface", P(egl::QuerySurface)}, + {"eglQuerySurfacePointerANGLE", P(egl::QuerySurfacePointerANGLE)}, + {"eglReleaseDeviceANGLE", P(egl::ReleaseDeviceANGLE)}, + {"eglReleaseTexImage", P(egl::ReleaseTexImage)}, + {"eglReleaseThread", P(egl::ReleaseThread)}, + {"eglStreamAttribKHR", P(egl::StreamAttribKHR)}, + {"eglStreamConsumerAcquireKHR", P(egl::StreamConsumerAcquireKHR)}, + {"eglStreamConsumerGLTextureExternalAttribsNV", + P(egl::StreamConsumerGLTextureExternalAttribsNV)}, + {"eglStreamConsumerGLTextureExternalKHR", P(egl::StreamConsumerGLTextureExternalKHR)}, + {"eglStreamConsumerReleaseKHR", P(egl::StreamConsumerReleaseKHR)}, + {"eglStreamPostD3DTextureNV12ANGLE", P(egl::StreamPostD3DTextureNV12ANGLE)}, + {"eglSurfaceAttrib", P(egl::SurfaceAttrib)}, + {"eglSwapBuffers", P(egl::SwapBuffers)}, + {"eglSwapBuffersWithDamageEXT", P(egl::SwapBuffersWithDamageEXT)}, + {"eglSwapInterval", P(egl::SwapInterval)}, + {"eglTerminate", P(egl::Terminate)}, + {"eglWaitClient", P(egl::WaitClient)}, + {"eglWaitGL", P(egl::WaitGL)}, + {"eglWaitNative", P(egl::WaitNative)}, + {"eglWaitSync", P(egl::WaitSync)}, + {"glActiveShaderProgram", P(gl::ActiveShaderProgram)}, + {"glActiveTexture", P(gl::ActiveTexture)}, + {"glAttachShader", P(gl::AttachShader)}, + {"glBeginQuery", P(gl::BeginQuery)}, + {"glBeginQueryEXT", P(gl::BeginQueryEXT)}, + {"glBeginTransformFeedback", P(gl::BeginTransformFeedback)}, + {"glBindAttribLocation", P(gl::BindAttribLocation)}, + {"glBindBuffer", P(gl::BindBuffer)}, + {"glBindBufferBase", P(gl::BindBufferBase)}, + {"glBindBufferRange", P(gl::BindBufferRange)}, + {"glBindFramebuffer", P(gl::BindFramebuffer)}, + {"glBindImageTexture", P(gl::BindImageTexture)}, + {"glBindProgramPipeline", P(gl::BindProgramPipeline)}, + {"glBindRenderbuffer", P(gl::BindRenderbuffer)}, + {"glBindSampler", P(gl::BindSampler)}, + {"glBindTexture", P(gl::BindTexture)}, + {"glBindTransformFeedback", P(gl::BindTransformFeedback)}, + {"glBindUniformLocationCHROMIUM", P(gl::BindUniformLocationCHROMIUM)}, + {"glBindVertexArray", P(gl::BindVertexArray)}, + {"glBindVertexArrayOES", P(gl::BindVertexArrayOES)}, + {"glBindVertexBuffer", P(gl::BindVertexBuffer)}, + {"glBlendColor", P(gl::BlendColor)}, + {"glBlendEquation", P(gl::BlendEquation)}, + {"glBlendEquationSeparate", P(gl::BlendEquationSeparate)}, + {"glBlendFunc", P(gl::BlendFunc)}, + {"glBlendFuncSeparate", P(gl::BlendFuncSeparate)}, + {"glBlitFramebuffer", P(gl::BlitFramebuffer)}, + {"glBlitFramebufferANGLE", P(gl::BlitFramebufferANGLE)}, + {"glBufferData", P(gl::BufferData)}, + {"glBufferSubData", P(gl::BufferSubData)}, + {"glCheckFramebufferStatus", P(gl::CheckFramebufferStatus)}, + {"glClear", P(gl::Clear)}, + {"glClearBufferfi", P(gl::ClearBufferfi)}, + {"glClearBufferfv", P(gl::ClearBufferfv)}, + {"glClearBufferiv", P(gl::ClearBufferiv)}, + {"glClearBufferuiv", P(gl::ClearBufferuiv)}, + {"glClearColor", P(gl::ClearColor)}, + {"glClearDepthf", P(gl::ClearDepthf)}, + {"glClearStencil", P(gl::ClearStencil)}, + {"glClientWaitSync", P(gl::ClientWaitSync)}, + {"glColorMask", P(gl::ColorMask)}, + {"glCompileShader", P(gl::CompileShader)}, + {"glCompressedCopyTextureCHROMIUM", P(gl::CompressedCopyTextureCHROMIUM)}, + {"glCompressedTexImage2D", P(gl::CompressedTexImage2D)}, + {"glCompressedTexImage2DRobustANGLE", P(gl::CompressedTexImage2DRobustANGLE)}, + {"glCompressedTexImage3D", P(gl::CompressedTexImage3D)}, + {"glCompressedTexImage3DRobustANGLE", P(gl::CompressedTexImage3DRobustANGLE)}, + {"glCompressedTexSubImage2D", P(gl::CompressedTexSubImage2D)}, + {"glCompressedTexSubImage2DRobustANGLE", P(gl::CompressedTexSubImage2DRobustANGLE)}, + {"glCompressedTexSubImage3D", P(gl::CompressedTexSubImage3D)}, + {"glCompressedTexSubImage3DRobustANGLE", P(gl::CompressedTexSubImage3DRobustANGLE)}, + {"glCopyBufferSubData", P(gl::CopyBufferSubData)}, + {"glCopySubTextureCHROMIUM", P(gl::CopySubTextureCHROMIUM)}, + {"glCopyTexImage2D", P(gl::CopyTexImage2D)}, + {"glCopyTexSubImage2D", P(gl::CopyTexSubImage2D)}, + {"glCopyTexSubImage3D", P(gl::CopyTexSubImage3D)}, + {"glCopyTextureCHROMIUM", P(gl::CopyTextureCHROMIUM)}, + {"glCreateProgram", P(gl::CreateProgram)}, + {"glCreateShader", P(gl::CreateShader)}, + {"glCreateShaderProgramv", P(gl::CreateShaderProgramv)}, + {"glCullFace", P(gl::CullFace)}, + {"glDebugMessageCallbackKHR", P(gl::DebugMessageCallbackKHR)}, + {"glDebugMessageControlKHR", P(gl::DebugMessageControlKHR)}, + {"glDebugMessageInsertKHR", P(gl::DebugMessageInsertKHR)}, + {"glDeleteBuffers", P(gl::DeleteBuffers)}, + {"glDeleteFencesNV", P(gl::DeleteFencesNV)}, + {"glDeleteFramebuffers", P(gl::DeleteFramebuffers)}, + {"glDeleteProgram", P(gl::DeleteProgram)}, + {"glDeleteProgramPipelines", P(gl::DeleteProgramPipelines)}, + {"glDeleteQueries", P(gl::DeleteQueries)}, + {"glDeleteQueriesEXT", P(gl::DeleteQueriesEXT)}, + {"glDeleteRenderbuffers", P(gl::DeleteRenderbuffers)}, + {"glDeleteSamplers", P(gl::DeleteSamplers)}, + {"glDeleteShader", P(gl::DeleteShader)}, + {"glDeleteSync", P(gl::DeleteSync)}, + {"glDeleteTextures", P(gl::DeleteTextures)}, + {"glDeleteTransformFeedbacks", P(gl::DeleteTransformFeedbacks)}, + {"glDeleteVertexArrays", P(gl::DeleteVertexArrays)}, + {"glDeleteVertexArraysOES", P(gl::DeleteVertexArraysOES)}, + {"glDepthFunc", P(gl::DepthFunc)}, + {"glDepthMask", P(gl::DepthMask)}, + {"glDepthRangef", P(gl::DepthRangef)}, + {"glDetachShader", P(gl::DetachShader)}, + {"glDisable", P(gl::Disable)}, + {"glDisableVertexAttribArray", P(gl::DisableVertexAttribArray)}, + {"glDiscardFramebufferEXT", P(gl::DiscardFramebufferEXT)}, + {"glDispatchCompute", P(gl::DispatchCompute)}, + {"glDispatchComputeIndirect", P(gl::DispatchComputeIndirect)}, + {"glDrawArrays", P(gl::DrawArrays)}, + {"glDrawArraysIndirect", P(gl::DrawArraysIndirect)}, + {"glDrawArraysInstanced", P(gl::DrawArraysInstanced)}, + {"glDrawArraysInstancedANGLE", P(gl::DrawArraysInstancedANGLE)}, + {"glDrawBuffers", P(gl::DrawBuffers)}, + {"glDrawBuffersEXT", P(gl::DrawBuffersEXT)}, + {"glDrawElements", P(gl::DrawElements)}, + {"glDrawElementsIndirect", P(gl::DrawElementsIndirect)}, + {"glDrawElementsInstanced", P(gl::DrawElementsInstanced)}, + {"glDrawElementsInstancedANGLE", P(gl::DrawElementsInstancedANGLE)}, + {"glDrawRangeElements", P(gl::DrawRangeElements)}, + {"glEGLImageTargetRenderbufferStorageOES", P(gl::EGLImageTargetRenderbufferStorageOES)}, + {"glEGLImageTargetTexture2DOES", P(gl::EGLImageTargetTexture2DOES)}, + {"glEnable", P(gl::Enable)}, + {"glEnableVertexAttribArray", P(gl::EnableVertexAttribArray)}, + {"glEndQuery", P(gl::EndQuery)}, + {"glEndQueryEXT", P(gl::EndQueryEXT)}, + {"glEndTransformFeedback", P(gl::EndTransformFeedback)}, + {"glFenceSync", P(gl::FenceSync)}, + {"glFinish", P(gl::Finish)}, + {"glFinishFenceNV", P(gl::FinishFenceNV)}, + {"glFlush", P(gl::Flush)}, + {"glFlushMappedBufferRange", P(gl::FlushMappedBufferRange)}, + {"glFlushMappedBufferRangeEXT", P(gl::FlushMappedBufferRangeEXT)}, + {"glFramebufferParameteri", P(gl::FramebufferParameteri)}, + {"glFramebufferRenderbuffer", P(gl::FramebufferRenderbuffer)}, + {"glFramebufferTexture2D", P(gl::FramebufferTexture2D)}, + {"glFramebufferTextureLayer", P(gl::FramebufferTextureLayer)}, + {"glFramebufferTextureMultiviewLayeredANGLE", P(gl::FramebufferTextureMultiviewLayeredANGLE)}, + {"glFramebufferTextureMultiviewSideBySideANGLE", + P(gl::FramebufferTextureMultiviewSideBySideANGLE)}, + {"glFrontFace", P(gl::FrontFace)}, + {"glGenBuffers", P(gl::GenBuffers)}, + {"glGenFencesNV", P(gl::GenFencesNV)}, + {"glGenFramebuffers", P(gl::GenFramebuffers)}, + {"glGenProgramPipelines", P(gl::GenProgramPipelines)}, + {"glGenQueries", P(gl::GenQueries)}, + {"glGenQueriesEXT", P(gl::GenQueriesEXT)}, + {"glGenRenderbuffers", P(gl::GenRenderbuffers)}, + {"glGenSamplers", P(gl::GenSamplers)}, + {"glGenTextures", P(gl::GenTextures)}, + {"glGenTransformFeedbacks", P(gl::GenTransformFeedbacks)}, + {"glGenVertexArrays", P(gl::GenVertexArrays)}, + {"glGenVertexArraysOES", P(gl::GenVertexArraysOES)}, + {"glGenerateMipmap", P(gl::GenerateMipmap)}, + {"glGetActiveAttrib", P(gl::GetActiveAttrib)}, + {"glGetActiveUniform", P(gl::GetActiveUniform)}, + {"glGetActiveUniformBlockName", P(gl::GetActiveUniformBlockName)}, + {"glGetActiveUniformBlockiv", P(gl::GetActiveUniformBlockiv)}, + {"glGetActiveUniformBlockivRobustANGLE", P(gl::GetActiveUniformBlockivRobustANGLE)}, + {"glGetActiveUniformsiv", P(gl::GetActiveUniformsiv)}, + {"glGetAttachedShaders", P(gl::GetAttachedShaders)}, + {"glGetAttribLocation", P(gl::GetAttribLocation)}, + {"glGetBooleani_v", P(gl::GetBooleani_v)}, + {"glGetBooleani_vRobustANGLE", P(gl::GetBooleani_vRobustANGLE)}, + {"glGetBooleanv", P(gl::GetBooleanv)}, + {"glGetBooleanvRobustANGLE", P(gl::GetBooleanvRobustANGLE)}, + {"glGetBufferParameteri64v", P(gl::GetBufferParameteri64v)}, + {"glGetBufferParameteri64vRobustANGLE", P(gl::GetBufferParameteri64vRobustANGLE)}, + {"glGetBufferParameteriv", P(gl::GetBufferParameteriv)}, + {"glGetBufferParameterivRobustANGLE", P(gl::GetBufferParameterivRobustANGLE)}, + {"glGetBufferPointerv", P(gl::GetBufferPointerv)}, + {"glGetBufferPointervOES", P(gl::GetBufferPointervOES)}, + {"glGetBufferPointervRobustANGLE", P(gl::GetBufferPointervRobustANGLE)}, + {"glGetDebugMessageLogKHR", P(gl::GetDebugMessageLogKHR)}, + {"glGetError", P(gl::GetError)}, + {"glGetFenceivNV", P(gl::GetFenceivNV)}, + {"glGetFloatv", P(gl::GetFloatv)}, + {"glGetFloatvRobustANGLE", P(gl::GetFloatvRobustANGLE)}, + {"glGetFragDataLocation", P(gl::GetFragDataLocation)}, + {"glGetFramebufferAttachmentParameteriv", P(gl::GetFramebufferAttachmentParameteriv)}, + {"glGetFramebufferAttachmentParameterivRobustANGLE", + P(gl::GetFramebufferAttachmentParameterivRobustANGLE)}, + {"glGetFramebufferParameteriv", P(gl::GetFramebufferParameteriv)}, + {"glGetFramebufferParameterivRobustANGLE", P(gl::GetFramebufferParameterivRobustANGLE)}, + {"glGetGraphicsResetStatusEXT", P(gl::GetGraphicsResetStatusEXT)}, + {"glGetInteger64i_v", P(gl::GetInteger64i_v)}, + {"glGetInteger64i_vRobustANGLE", P(gl::GetInteger64i_vRobustANGLE)}, + {"glGetInteger64v", P(gl::GetInteger64v)}, + {"glGetInteger64vRobustANGLE", P(gl::GetInteger64vRobustANGLE)}, + {"glGetIntegeri_v", P(gl::GetIntegeri_v)}, + {"glGetIntegeri_vRobustANGLE", P(gl::GetIntegeri_vRobustANGLE)}, + {"glGetIntegerv", P(gl::GetIntegerv)}, + {"glGetIntegervRobustANGLE", P(gl::GetIntegervRobustANGLE)}, + {"glGetInternalformativ", P(gl::GetInternalformativ)}, + {"glGetInternalformativRobustANGLE", P(gl::GetInternalformativRobustANGLE)}, + {"glGetMultisamplefv", P(gl::GetMultisamplefv)}, + {"glGetMultisamplefvRobustANGLE", P(gl::GetMultisamplefvRobustANGLE)}, + {"glGetObjectLabelKHR", P(gl::GetObjectLabelKHR)}, + {"glGetObjectPtrLabelKHR", P(gl::GetObjectPtrLabelKHR)}, + {"glGetPointervKHR", P(gl::GetPointervKHR)}, + {"glGetPointervRobustANGLERobustANGLE", P(gl::GetPointervRobustANGLERobustANGLE)}, + {"glGetProgramBinary", P(gl::GetProgramBinary)}, + {"glGetProgramBinaryOES", P(gl::GetProgramBinaryOES)}, + {"glGetProgramInfoLog", P(gl::GetProgramInfoLog)}, + {"glGetProgramInterfaceiv", P(gl::GetProgramInterfaceiv)}, + {"glGetProgramInterfaceivRobustANGLE", P(gl::GetProgramInterfaceivRobustANGLE)}, + {"glGetProgramPipelineInfoLog", P(gl::GetProgramPipelineInfoLog)}, + {"glGetProgramPipelineiv", P(gl::GetProgramPipelineiv)}, + {"glGetProgramResourceIndex", P(gl::GetProgramResourceIndex)}, + {"glGetProgramResourceLocation", P(gl::GetProgramResourceLocation)}, + {"glGetProgramResourceName", P(gl::GetProgramResourceName)}, + {"glGetProgramResourceiv", P(gl::GetProgramResourceiv)}, + {"glGetProgramiv", P(gl::GetProgramiv)}, + {"glGetProgramivRobustANGLE", P(gl::GetProgramivRobustANGLE)}, + {"glGetQueryObjecti64vEXT", P(gl::GetQueryObjecti64vEXT)}, + {"glGetQueryObjecti64vRobustANGLE", P(gl::GetQueryObjecti64vRobustANGLE)}, + {"glGetQueryObjectivEXT", P(gl::GetQueryObjectivEXT)}, + {"glGetQueryObjectivRobustANGLE", P(gl::GetQueryObjectivRobustANGLE)}, + {"glGetQueryObjectui64vEXT", P(gl::GetQueryObjectui64vEXT)}, + {"glGetQueryObjectui64vRobustANGLE", P(gl::GetQueryObjectui64vRobustANGLE)}, + {"glGetQueryObjectuiv", P(gl::GetQueryObjectuiv)}, + {"glGetQueryObjectuivEXT", P(gl::GetQueryObjectuivEXT)}, + {"glGetQueryObjectuivRobustANGLE", P(gl::GetQueryObjectuivRobustANGLE)}, + {"glGetQueryiv", P(gl::GetQueryiv)}, + {"glGetQueryivEXT", P(gl::GetQueryivEXT)}, + {"glGetQueryivRobustANGLE", P(gl::GetQueryivRobustANGLE)}, + {"glGetRenderbufferParameteriv", P(gl::GetRenderbufferParameteriv)}, + {"glGetRenderbufferParameterivRobustANGLE", P(gl::GetRenderbufferParameterivRobustANGLE)}, + {"glGetSamplerParameterIivRobustANGLE", P(gl::GetSamplerParameterIivRobustANGLE)}, + {"glGetSamplerParameterIuivRobustANGLE", P(gl::GetSamplerParameterIuivRobustANGLE)}, + {"glGetSamplerParameterfv", P(gl::GetSamplerParameterfv)}, + {"glGetSamplerParameterfvRobustANGLE", P(gl::GetSamplerParameterfvRobustANGLE)}, + {"glGetSamplerParameteriv", P(gl::GetSamplerParameteriv)}, + {"glGetSamplerParameterivRobustANGLE", P(gl::GetSamplerParameterivRobustANGLE)}, + {"glGetShaderInfoLog", P(gl::GetShaderInfoLog)}, + {"glGetShaderPrecisionFormat", P(gl::GetShaderPrecisionFormat)}, + {"glGetShaderSource", P(gl::GetShaderSource)}, + {"glGetShaderiv", P(gl::GetShaderiv)}, + {"glGetShaderivRobustANGLE", P(gl::GetShaderivRobustANGLE)}, + {"glGetString", P(gl::GetString)}, + {"glGetStringi", P(gl::GetStringi)}, + {"glGetSynciv", P(gl::GetSynciv)}, + {"glGetTexLevelParameterfv", P(gl::GetTexLevelParameterfv)}, + {"glGetTexLevelParameterfvRobustANGLE", P(gl::GetTexLevelParameterfvRobustANGLE)}, + {"glGetTexLevelParameteriv", P(gl::GetTexLevelParameteriv)}, + {"glGetTexLevelParameterivRobustANGLE", P(gl::GetTexLevelParameterivRobustANGLE)}, + {"glGetTexParameterIivRobustANGLE", P(gl::GetTexParameterIivRobustANGLE)}, + {"glGetTexParameterIuivRobustANGLE", P(gl::GetTexParameterIuivRobustANGLE)}, + {"glGetTexParameterfv", P(gl::GetTexParameterfv)}, + {"glGetTexParameterfvRobustANGLE", P(gl::GetTexParameterfvRobustANGLE)}, + {"glGetTexParameteriv", P(gl::GetTexParameteriv)}, + {"glGetTexParameterivRobustANGLE", P(gl::GetTexParameterivRobustANGLE)}, + {"glGetTransformFeedbackVarying", P(gl::GetTransformFeedbackVarying)}, + {"glGetTranslatedShaderSourceANGLE", P(gl::GetTranslatedShaderSourceANGLE)}, + {"glGetUniformBlockIndex", P(gl::GetUniformBlockIndex)}, + {"glGetUniformIndices", P(gl::GetUniformIndices)}, + {"glGetUniformLocation", P(gl::GetUniformLocation)}, + {"glGetUniformfv", P(gl::GetUniformfv)}, + {"glGetUniformfvRobustANGLE", P(gl::GetUniformfvRobustANGLE)}, + {"glGetUniformiv", P(gl::GetUniformiv)}, + {"glGetUniformivRobustANGLE", P(gl::GetUniformivRobustANGLE)}, + {"glGetUniformuiv", P(gl::GetUniformuiv)}, + {"glGetUniformuivRobustANGLE", P(gl::GetUniformuivRobustANGLE)}, + {"glGetVertexAttribIiv", P(gl::GetVertexAttribIiv)}, + {"glGetVertexAttribIivRobustANGLE", P(gl::GetVertexAttribIivRobustANGLE)}, + {"glGetVertexAttribIuiv", P(gl::GetVertexAttribIuiv)}, + {"glGetVertexAttribIuivRobustANGLE", P(gl::GetVertexAttribIuivRobustANGLE)}, + {"glGetVertexAttribPointerv", P(gl::GetVertexAttribPointerv)}, + {"glGetVertexAttribPointervRobustANGLE", P(gl::GetVertexAttribPointervRobustANGLE)}, + {"glGetVertexAttribfv", P(gl::GetVertexAttribfv)}, + {"glGetVertexAttribfvRobustANGLE", P(gl::GetVertexAttribfvRobustANGLE)}, + {"glGetVertexAttribiv", P(gl::GetVertexAttribiv)}, + {"glGetVertexAttribivRobustANGLE", P(gl::GetVertexAttribivRobustANGLE)}, + {"glGetnUniformfvEXT", P(gl::GetnUniformfvEXT)}, + {"glGetnUniformfvRobustANGLE", P(gl::GetnUniformfvRobustANGLE)}, + {"glGetnUniformivEXT", P(gl::GetnUniformivEXT)}, + {"glGetnUniformivRobustANGLE", P(gl::GetnUniformivRobustANGLE)}, + {"glGetnUniformuivRobustANGLE", P(gl::GetnUniformuivRobustANGLE)}, + {"glHint", P(gl::Hint)}, + {"glInsertEventMarkerEXT", P(gl::InsertEventMarkerEXT)}, + {"glInvalidateFramebuffer", P(gl::InvalidateFramebuffer)}, + {"glInvalidateSubFramebuffer", P(gl::InvalidateSubFramebuffer)}, + {"glIsBuffer", P(gl::IsBuffer)}, + {"glIsEnabled", P(gl::IsEnabled)}, + {"glIsFenceNV", P(gl::IsFenceNV)}, + {"glIsFramebuffer", P(gl::IsFramebuffer)}, + {"glIsProgram", P(gl::IsProgram)}, + {"glIsProgramPipeline", P(gl::IsProgramPipeline)}, + {"glIsQuery", P(gl::IsQuery)}, + {"glIsQueryEXT", P(gl::IsQueryEXT)}, + {"glIsRenderbuffer", P(gl::IsRenderbuffer)}, + {"glIsSampler", P(gl::IsSampler)}, + {"glIsShader", P(gl::IsShader)}, + {"glIsSync", P(gl::IsSync)}, + {"glIsTexture", P(gl::IsTexture)}, + {"glIsTransformFeedback", P(gl::IsTransformFeedback)}, + {"glIsVertexArray", P(gl::IsVertexArray)}, + {"glIsVertexArrayOES", P(gl::IsVertexArrayOES)}, + {"glLineWidth", P(gl::LineWidth)}, + {"glLinkProgram", P(gl::LinkProgram)}, + {"glMapBufferOES", P(gl::MapBufferOES)}, + {"glMapBufferRange", P(gl::MapBufferRange)}, + {"glMapBufferRangeEXT", P(gl::MapBufferRangeEXT)}, + {"glMemoryBarrier", P(gl::MemoryBarrier)}, + {"glMemoryBarrierByRegion", P(gl::MemoryBarrierByRegion)}, + {"glObjectLabelKHR", P(gl::ObjectLabelKHR)}, + {"glObjectPtrLabelKHR", P(gl::ObjectPtrLabelKHR)}, + {"glPauseTransformFeedback", P(gl::PauseTransformFeedback)}, + {"glPixelStorei", P(gl::PixelStorei)}, + {"glPolygonOffset", P(gl::PolygonOffset)}, + {"glPopDebugGroupKHR", P(gl::PopDebugGroupKHR)}, + {"glPopGroupMarkerEXT", P(gl::PopGroupMarkerEXT)}, + {"glProgramBinary", P(gl::ProgramBinary)}, + {"glProgramBinaryOES", P(gl::ProgramBinaryOES)}, + {"glProgramParameteri", P(gl::ProgramParameteri)}, + {"glProgramUniform1f", P(gl::ProgramUniform1f)}, + {"glProgramUniform1fv", P(gl::ProgramUniform1fv)}, + {"glProgramUniform1i", P(gl::ProgramUniform1i)}, + {"glProgramUniform1iv", P(gl::ProgramUniform1iv)}, + {"glProgramUniform1ui", P(gl::ProgramUniform1ui)}, + {"glProgramUniform1uiv", P(gl::ProgramUniform1uiv)}, + {"glProgramUniform2f", P(gl::ProgramUniform2f)}, + {"glProgramUniform2fv", P(gl::ProgramUniform2fv)}, + {"glProgramUniform2i", P(gl::ProgramUniform2i)}, + {"glProgramUniform2iv", P(gl::ProgramUniform2iv)}, + {"glProgramUniform2ui", P(gl::ProgramUniform2ui)}, + {"glProgramUniform2uiv", P(gl::ProgramUniform2uiv)}, + {"glProgramUniform3f", P(gl::ProgramUniform3f)}, + {"glProgramUniform3fv", P(gl::ProgramUniform3fv)}, + {"glProgramUniform3i", P(gl::ProgramUniform3i)}, + {"glProgramUniform3iv", P(gl::ProgramUniform3iv)}, + {"glProgramUniform3ui", P(gl::ProgramUniform3ui)}, + {"glProgramUniform3uiv", P(gl::ProgramUniform3uiv)}, + {"glProgramUniform4f", P(gl::ProgramUniform4f)}, + {"glProgramUniform4fv", P(gl::ProgramUniform4fv)}, + {"glProgramUniform4i", P(gl::ProgramUniform4i)}, + {"glProgramUniform4iv", P(gl::ProgramUniform4iv)}, + {"glProgramUniform4ui", P(gl::ProgramUniform4ui)}, + {"glProgramUniform4uiv", P(gl::ProgramUniform4uiv)}, + {"glProgramUniformMatrix2fv", P(gl::ProgramUniformMatrix2fv)}, + {"glProgramUniformMatrix2x3fv", P(gl::ProgramUniformMatrix2x3fv)}, + {"glProgramUniformMatrix2x4fv", P(gl::ProgramUniformMatrix2x4fv)}, + {"glProgramUniformMatrix3fv", P(gl::ProgramUniformMatrix3fv)}, + {"glProgramUniformMatrix3x2fv", P(gl::ProgramUniformMatrix3x2fv)}, + {"glProgramUniformMatrix3x4fv", P(gl::ProgramUniformMatrix3x4fv)}, + {"glProgramUniformMatrix4fv", P(gl::ProgramUniformMatrix4fv)}, + {"glProgramUniformMatrix4x2fv", P(gl::ProgramUniformMatrix4x2fv)}, + {"glProgramUniformMatrix4x3fv", P(gl::ProgramUniformMatrix4x3fv)}, + {"glPushDebugGroupKHR", P(gl::PushDebugGroupKHR)}, + {"glPushGroupMarkerEXT", P(gl::PushGroupMarkerEXT)}, + {"glQueryCounterEXT", P(gl::QueryCounterEXT)}, + {"glReadBuffer", P(gl::ReadBuffer)}, + {"glReadPixels", P(gl::ReadPixels)}, + {"glReadPixelsRobustANGLE", P(gl::ReadPixelsRobustANGLE)}, + {"glReadnPixelsEXT", P(gl::ReadnPixelsEXT)}, + {"glReadnPixelsRobustANGLE", P(gl::ReadnPixelsRobustANGLE)}, + {"glReleaseShaderCompiler", P(gl::ReleaseShaderCompiler)}, + {"glRenderbufferStorage", P(gl::RenderbufferStorage)}, + {"glRenderbufferStorageMultisample", P(gl::RenderbufferStorageMultisample)}, + {"glRenderbufferStorageMultisampleANGLE", P(gl::RenderbufferStorageMultisampleANGLE)}, + {"glRequestExtensionANGLE", P(gl::RequestExtensionANGLE)}, + {"glResumeTransformFeedback", P(gl::ResumeTransformFeedback)}, + {"glSampleCoverage", P(gl::SampleCoverage)}, + {"glSampleMaski", P(gl::SampleMaski)}, + {"glSamplerParameterIivRobustANGLE", P(gl::SamplerParameterIivRobustANGLE)}, + {"glSamplerParameterIuivRobustANGLE", P(gl::SamplerParameterIuivRobustANGLE)}, + {"glSamplerParameterf", P(gl::SamplerParameterf)}, + {"glSamplerParameterfv", P(gl::SamplerParameterfv)}, + {"glSamplerParameterfvRobustANGLE", P(gl::SamplerParameterfvRobustANGLE)}, + {"glSamplerParameteri", P(gl::SamplerParameteri)}, + {"glSamplerParameteriv", P(gl::SamplerParameteriv)}, + {"glSamplerParameterivRobustANGLE", P(gl::SamplerParameterivRobustANGLE)}, + {"glScissor", P(gl::Scissor)}, + {"glSetFenceNV", P(gl::SetFenceNV)}, + {"glShaderBinary", P(gl::ShaderBinary)}, + {"glShaderSource", P(gl::ShaderSource)}, + {"glStencilFunc", P(gl::StencilFunc)}, + {"glStencilFuncSeparate", P(gl::StencilFuncSeparate)}, + {"glStencilMask", P(gl::StencilMask)}, + {"glStencilMaskSeparate", P(gl::StencilMaskSeparate)}, + {"glStencilOp", P(gl::StencilOp)}, + {"glStencilOpSeparate", P(gl::StencilOpSeparate)}, + {"glTestFenceNV", P(gl::TestFenceNV)}, + {"glTexImage2D", P(gl::TexImage2D)}, + {"glTexImage2DRobustANGLE", P(gl::TexImage2DRobustANGLE)}, + {"glTexImage3D", P(gl::TexImage3D)}, + {"glTexImage3DRobustANGLE", P(gl::TexImage3DRobustANGLE)}, + {"glTexParameterIivRobustANGLE", P(gl::TexParameterIivRobustANGLE)}, + {"glTexParameterIuivRobustANGLE", P(gl::TexParameterIuivRobustANGLE)}, + {"glTexParameterf", P(gl::TexParameterf)}, + {"glTexParameterfv", P(gl::TexParameterfv)}, + {"glTexParameterfvRobustANGLE", P(gl::TexParameterfvRobustANGLE)}, + {"glTexParameteri", P(gl::TexParameteri)}, + {"glTexParameteriv", P(gl::TexParameteriv)}, + {"glTexParameterivRobustANGLE", P(gl::TexParameterivRobustANGLE)}, + {"glTexStorage2D", P(gl::TexStorage2D)}, + {"glTexStorage2DEXT", P(gl::TexStorage2DEXT)}, + {"glTexStorage2DMultisample", P(gl::TexStorage2DMultisample)}, + {"glTexStorage3D", P(gl::TexStorage3D)}, + {"glTexSubImage2D", P(gl::TexSubImage2D)}, + {"glTexSubImage2DRobustANGLE", P(gl::TexSubImage2DRobustANGLE)}, + {"glTexSubImage3D", P(gl::TexSubImage3D)}, + {"glTexSubImage3DRobustANGLE", P(gl::TexSubImage3DRobustANGLE)}, + {"glTransformFeedbackVaryings", P(gl::TransformFeedbackVaryings)}, + {"glUniform1f", P(gl::Uniform1f)}, + {"glUniform1fv", P(gl::Uniform1fv)}, + {"glUniform1i", P(gl::Uniform1i)}, + {"glUniform1iv", P(gl::Uniform1iv)}, + {"glUniform1ui", P(gl::Uniform1ui)}, + {"glUniform1uiv", P(gl::Uniform1uiv)}, + {"glUniform2f", P(gl::Uniform2f)}, + {"glUniform2fv", P(gl::Uniform2fv)}, + {"glUniform2i", P(gl::Uniform2i)}, + {"glUniform2iv", P(gl::Uniform2iv)}, + {"glUniform2ui", P(gl::Uniform2ui)}, + {"glUniform2uiv", P(gl::Uniform2uiv)}, + {"glUniform3f", P(gl::Uniform3f)}, + {"glUniform3fv", P(gl::Uniform3fv)}, + {"glUniform3i", P(gl::Uniform3i)}, + {"glUniform3iv", P(gl::Uniform3iv)}, + {"glUniform3ui", P(gl::Uniform3ui)}, + {"glUniform3uiv", P(gl::Uniform3uiv)}, + {"glUniform4f", P(gl::Uniform4f)}, + {"glUniform4fv", P(gl::Uniform4fv)}, + {"glUniform4i", P(gl::Uniform4i)}, + {"glUniform4iv", P(gl::Uniform4iv)}, + {"glUniform4ui", P(gl::Uniform4ui)}, + {"glUniform4uiv", P(gl::Uniform4uiv)}, + {"glUniformBlockBinding", P(gl::UniformBlockBinding)}, + {"glUniformMatrix2fv", P(gl::UniformMatrix2fv)}, + {"glUniformMatrix2x3fv", P(gl::UniformMatrix2x3fv)}, + {"glUniformMatrix2x4fv", P(gl::UniformMatrix2x4fv)}, + {"glUniformMatrix3fv", P(gl::UniformMatrix3fv)}, + {"glUniformMatrix3x2fv", P(gl::UniformMatrix3x2fv)}, + {"glUniformMatrix3x4fv", P(gl::UniformMatrix3x4fv)}, + {"glUniformMatrix4fv", P(gl::UniformMatrix4fv)}, + {"glUniformMatrix4x2fv", P(gl::UniformMatrix4x2fv)}, + {"glUniformMatrix4x3fv", P(gl::UniformMatrix4x3fv)}, + {"glUnmapBuffer", P(gl::UnmapBuffer)}, + {"glUnmapBufferOES", P(gl::UnmapBufferOES)}, + {"glUseProgram", P(gl::UseProgram)}, + {"glUseProgramStages", P(gl::UseProgramStages)}, + {"glValidateProgram", P(gl::ValidateProgram)}, + {"glValidateProgramPipeline", P(gl::ValidateProgramPipeline)}, + {"glVertexAttrib1f", P(gl::VertexAttrib1f)}, + {"glVertexAttrib1fv", P(gl::VertexAttrib1fv)}, + {"glVertexAttrib2f", P(gl::VertexAttrib2f)}, + {"glVertexAttrib2fv", P(gl::VertexAttrib2fv)}, + {"glVertexAttrib3f", P(gl::VertexAttrib3f)}, + {"glVertexAttrib3fv", P(gl::VertexAttrib3fv)}, + {"glVertexAttrib4f", P(gl::VertexAttrib4f)}, + {"glVertexAttrib4fv", P(gl::VertexAttrib4fv)}, + {"glVertexAttribBinding", P(gl::VertexAttribBinding)}, + {"glVertexAttribDivisor", P(gl::VertexAttribDivisor)}, + {"glVertexAttribDivisorANGLE", P(gl::VertexAttribDivisorANGLE)}, + {"glVertexAttribFormat", P(gl::VertexAttribFormat)}, + {"glVertexAttribI4i", P(gl::VertexAttribI4i)}, + {"glVertexAttribI4iv", P(gl::VertexAttribI4iv)}, + {"glVertexAttribI4ui", P(gl::VertexAttribI4ui)}, + {"glVertexAttribI4uiv", P(gl::VertexAttribI4uiv)}, + {"glVertexAttribIFormat", P(gl::VertexAttribIFormat)}, + {"glVertexAttribIPointer", P(gl::VertexAttribIPointer)}, + {"glVertexAttribPointer", P(gl::VertexAttribPointer)}, + {"glVertexBindingDivisor", P(gl::VertexBindingDivisor)}, + {"glViewport", P(gl::Viewport)}, + {"glWaitSync", P(gl::WaitSync)}}; + +size_t g_numProcs = 516; +} // namespace egl diff --git a/src/3rdparty/angle/src/libGLESv2/proc_table_data.json b/src/3rdparty/angle/src/libGLESv2/proc_table_data.json new file mode 100644 index 0000000000..5ce1d433a8 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/proc_table_data.json @@ -0,0 +1,662 @@ +{ + "GLES2 core": [ + "glActiveTexture", + "glAttachShader", + "glBindAttribLocation", + "glBindBuffer", + "glBindFramebuffer", + "glBindRenderbuffer", + "glBindTexture", + "glBlendColor", + "glBlendEquation", + "glBlendEquationSeparate", + "glBlendFunc", + "glBlendFuncSeparate", + "glBufferData", + "glBufferSubData", + "glCheckFramebufferStatus", + "glClear", + "glClearColor", + "glClearDepthf", + "glClearStencil", + "glCompileShader", + "glColorMask", + "glCompressedTexImage2D", + "glCompressedTexSubImage2D", + "glCopyTexImage2D", + "glCopyTexSubImage2D", + "glCreateProgram", + "glCreateShader", + "glCullFace", + "glDeleteBuffers", + "glDeleteFramebuffers", + "glDeleteProgram", + "glDeleteRenderbuffers", + "glDeleteShader", + "glDeleteTextures", + "glDepthFunc", + "glDepthMask", + "glDepthRangef", + "glDetachShader", + "glDisable", + "glDisableVertexAttribArray", + "glDrawArrays", + "glDrawElements", + "glEnable", + "glEnableVertexAttribArray", + "glFinish", + "glFlush", + "glFramebufferRenderbuffer", + "glFramebufferTexture2D", + "glFrontFace", + "glGenBuffers", + "glGenerateMipmap", + "glGenFramebuffers", + "glGenRenderbuffers", + "glGenTextures", + "glGetActiveAttrib", + "glGetActiveUniform", + "glGetAttachedShaders", + "glGetAttribLocation", + "glGetBooleanv", + "glGetBufferParameteriv", + "glGetError", + "glGetFloatv", + "glGetFramebufferAttachmentParameteriv", + "glGetIntegerv", + "glGetProgramiv", + "glGetProgramInfoLog", + "glGetRenderbufferParameteriv", + "glGetShaderiv", + "glGetShaderInfoLog", + "glGetShaderPrecisionFormat", + "glGetShaderSource", + "glGetString", + "glGetTexParameterfv", + "glGetTexParameteriv", + "glGetUniformfv", + "glGetUniformiv", + "glGetUniformLocation", + "glGetVertexAttribfv", + "glGetVertexAttribiv", + "glGetVertexAttribPointerv", + "glHint", + "glIsBuffer", + "glIsEnabled", + "glIsFramebuffer", + "glIsProgram", + "glIsRenderbuffer", + "glIsShader", + "glIsTexture", + "glLineWidth", + "glLinkProgram", + "glPixelStorei", + "glPolygonOffset", + "glReadPixels", + "glReleaseShaderCompiler", + "glRenderbufferStorage", + "glSampleCoverage", + "glScissor", + "glShaderBinary", + "glShaderSource", + "glStencilFunc", + "glStencilFuncSeparate", + "glStencilMask", + "glStencilMaskSeparate", + "glStencilOp", + "glStencilOpSeparate", + "glTexImage2D", + "glTexParameterf", + "glTexParameterfv", + "glTexParameteri", + "glTexParameteriv", + "glTexSubImage2D", + "glUniform1f", + "glUniform1fv", + "glUniform1i", + "glUniform1iv", + "glUniform2f", + "glUniform2fv", + "glUniform2i", + "glUniform2iv", + "glUniform3f", + "glUniform3fv", + "glUniform3i", + "glUniform3iv", + "glUniform4f", + "glUniform4fv", + "glUniform4i", + "glUniform4iv", + "glUniformMatrix2fv", + "glUniformMatrix3fv", + "glUniformMatrix4fv", + "glUseProgram", + "glValidateProgram", + "glVertexAttrib1f", + "glVertexAttrib1fv", + "glVertexAttrib2f", + "glVertexAttrib2fv", + "glVertexAttrib3f", + "glVertexAttrib3fv", + "glVertexAttrib4f", + "glVertexAttrib4fv", + "glVertexAttribPointer", + "glViewport" + ], + + "GL_ANGLE_framebuffer_blit": [ + "glBlitFramebufferANGLE" + ], + + "GL_ANGLE_framebuffer_multisample": [ + "glRenderbufferStorageMultisampleANGLE" + ], + + "GL_EXT_discard_framebuffer": [ + "glDiscardFramebufferEXT" + ], + + "GL_NV_fence": [ + "glDeleteFencesNV", + "glGenFencesNV", + "glIsFenceNV", + "glTestFenceNV", + "glGetFenceivNV", + "glFinishFenceNV", + "glSetFenceNV" + ], + + "GL_ANGLE_translated_shader_source": [ + "glGetTranslatedShaderSourceANGLE" + ], + + "GL_EXT_texture_storage": [ + "glTexStorage2DEXT" + ], + + "GL_EXT_robustness": [ + "glGetGraphicsResetStatusEXT", + "glReadnPixelsEXT", + "glGetnUniformfvEXT", + "glGetnUniformivEXT" + ], + + "GL_EXT_occlusion_query_boolean": [ + "glGenQueriesEXT", + "glDeleteQueriesEXT", + "glIsQueryEXT", + "glBeginQueryEXT", + "glEndQueryEXT", + "glGetQueryivEXT", + "glGetQueryObjectuivEXT" + ], + + "GL_EXT_disjoint_timer_query": [ + "glGenQueriesEXT", + "glDeleteQueriesEXT", + "glIsQueryEXT", + "glBeginQueryEXT", + "glEndQueryEXT", + "glQueryCounterEXT", + "glGetQueryivEXT", + "glGetQueryObjectivEXT", + "glGetQueryObjectuivEXT", + "glGetQueryObjecti64vEXT", + "glGetQueryObjectui64vEXT" + ], + + "GL_EXT_draw_buffers": [ + "glDrawBuffersEXT" + ], + + "GL_ANGLE_instanced_arrays": [ + "glDrawArraysInstancedANGLE", + "glDrawElementsInstancedANGLE", + "glVertexAttribDivisorANGLE" + ], + + "GL_OES_get_program_binary": [ + "glGetProgramBinaryOES", + "glProgramBinaryOES" + ], + + "GL_OES_mapbuffer": [ + "glMapBufferOES", + "glUnmapBufferOES", + "glGetBufferPointervOES" + ], + + "GL_EXT_map_buffer_range": [ + "glMapBufferRangeEXT", + "glFlushMappedBufferRangeEXT" + ], + + "GL_EXT_debug_marker": [ + "glInsertEventMarkerEXT", + "glPushGroupMarkerEXT", + "glPopGroupMarkerEXT" + ], + + "GL_OES_EGL_image": [ + "glEGLImageTargetTexture2DOES", + "glEGLImageTargetRenderbufferStorageOES" + ], + + "GL_OES_vertex_array_object": [ + "glBindVertexArrayOES", + "glDeleteVertexArraysOES", + "glGenVertexArraysOES", + "glIsVertexArrayOES" + ], + + "GL_KHR_debug": [ + "glDebugMessageControlKHR", + "glDebugMessageInsertKHR", + "glDebugMessageCallbackKHR", + "glGetDebugMessageLogKHR", + "glPushDebugGroupKHR", + "glPopDebugGroupKHR", + "glObjectLabelKHR", + "glGetObjectLabelKHR", + "glObjectPtrLabelKHR", + "glGetObjectPtrLabelKHR", + "glGetPointervKHR" + ], + + "GL_CHROMIUM_bind_uniform_location": [ + "glBindUniformLocationCHROMIUM" + ], + + "GL_CHROMIUM_copy_texture": [ + "glCopyTextureCHROMIUM", + "glCopySubTextureCHROMIUM" + ], + + "GL_CHROMIUM_copy_compressed_texture": [ + "glCompressedCopyTextureCHROMIUM" + ], + + "GL_ANGLE_request_extension": [ + "glRequestExtensionANGLE" + ], + + "GL_ANGLE_robust_client_memory": [ + "glGetBooleanvRobustANGLE", + "glGetBufferParameterivRobustANGLE", + "glGetFloatvRobustANGLE", + "glGetFramebufferAttachmentParameterivRobustANGLE", + "glGetIntegervRobustANGLE", + "glGetProgramivRobustANGLE", + "glGetRenderbufferParameterivRobustANGLE", + "glGetShaderivRobustANGLE", + "glGetTexParameterfvRobustANGLE", + "glGetTexParameterivRobustANGLE", + "glGetUniformfvRobustANGLE", + "glGetUniformivRobustANGLE", + "glGetVertexAttribfvRobustANGLE", + "glGetVertexAttribivRobustANGLE", + "glGetVertexAttribPointervRobustANGLE", + "glReadPixelsRobustANGLE", + "glTexImage2DRobustANGLE", + "glTexParameterfvRobustANGLE", + "glTexParameterivRobustANGLE", + "glTexSubImage2DRobustANGLE", + "glTexImage3DRobustANGLE", + "glTexSubImage3DRobustANGLE", + "glCompressedTexImage2DRobustANGLE", + "glCompressedTexSubImage2DRobustANGLE", + "glCompressedTexImage3DRobustANGLE", + "glCompressedTexSubImage3DRobustANGLE", + "glGetQueryivRobustANGLE", + "glGetQueryObjectuivRobustANGLE", + "glGetBufferPointervRobustANGLE", + "glGetIntegeri_vRobustANGLE", + "glGetInternalformativRobustANGLE", + "glGetVertexAttribIivRobustANGLE", + "glGetVertexAttribIuivRobustANGLE", + "glGetUniformuivRobustANGLE", + "glGetActiveUniformBlockivRobustANGLE", + "glGetInteger64vRobustANGLE", + "glGetInteger64i_vRobustANGLE", + "glGetBufferParameteri64vRobustANGLE", + "glSamplerParameterivRobustANGLE", + "glSamplerParameterfvRobustANGLE", + "glGetSamplerParameterivRobustANGLE", + "glGetSamplerParameterfvRobustANGLE", + "glGetFramebufferParameterivRobustANGLE", + "glGetProgramInterfaceivRobustANGLE", + "glGetBooleani_vRobustANGLE", + "glGetMultisamplefvRobustANGLE", + "glGetTexLevelParameterivRobustANGLE", + "glGetTexLevelParameterfvRobustANGLE", + "glGetPointervRobustANGLERobustANGLE", + "glReadnPixelsRobustANGLE", + "glGetnUniformfvRobustANGLE", + "glGetnUniformivRobustANGLE", + "glGetnUniformuivRobustANGLE", + "glTexParameterIivRobustANGLE", + "glTexParameterIuivRobustANGLE", + "glGetTexParameterIivRobustANGLE", + "glGetTexParameterIuivRobustANGLE", + "glSamplerParameterIivRobustANGLE", + "glSamplerParameterIuivRobustANGLE", + "glGetSamplerParameterIivRobustANGLE", + "glGetSamplerParameterIuivRobustANGLE", + "glGetQueryObjectivRobustANGLE", + "glGetQueryObjecti64vRobustANGLE", + "glGetQueryObjectui64vRobustANGLE" + ], + + "GL_ANGLE_multiview": [ + "glFramebufferTextureMultiviewLayeredANGLE", + "glFramebufferTextureMultiviewSideBySideANGLE" + ], + + "GLES3 core": [ + "glReadBuffer", + "glDrawRangeElements", + "glTexImage3D", + "glTexSubImage3D", + "glCopyTexSubImage3D", + "glCompressedTexImage3D", + "glCompressedTexSubImage3D", + "glGenQueries", + "glDeleteQueries", + "glIsQuery", + "glBeginQuery", + "glEndQuery", + "glGetQueryiv", + "glGetQueryObjectuiv", + "glUnmapBuffer", + "glGetBufferPointerv", + "glDrawBuffers", + "glUniformMatrix2x3fv", + "glUniformMatrix3x2fv", + "glUniformMatrix2x4fv", + "glUniformMatrix4x2fv", + "glUniformMatrix3x4fv", + "glUniformMatrix4x3fv", + "glBlitFramebuffer", + "glRenderbufferStorageMultisample", + "glFramebufferTextureLayer", + "glMapBufferRange", + "glFlushMappedBufferRange", + "glBindVertexArray", + "glDeleteVertexArrays", + "glGenVertexArrays", + "glIsVertexArray", + "glGetIntegeri_v", + "glBeginTransformFeedback", + "glEndTransformFeedback", + "glBindBufferRange", + "glBindBufferBase", + "glTransformFeedbackVaryings", + "glGetTransformFeedbackVarying", + "glVertexAttribIPointer", + "glGetVertexAttribIiv", + "glGetVertexAttribIuiv", + "glVertexAttribI4i", + "glVertexAttribI4ui", + "glVertexAttribI4iv", + "glVertexAttribI4uiv", + "glGetUniformuiv", + "glGetFragDataLocation", + "glUniform1ui", + "glUniform2ui", + "glUniform3ui", + "glUniform4ui", + "glUniform1uiv", + "glUniform2uiv", + "glUniform3uiv", + "glUniform4uiv", + "glClearBufferiv", + "glClearBufferuiv", + "glClearBufferfv", + "glClearBufferfi", + "glGetStringi", + "glCopyBufferSubData", + "glGetUniformIndices", + "glGetActiveUniformsiv", + "glGetUniformBlockIndex", + "glGetActiveUniformBlockiv", + "glGetActiveUniformBlockName", + "glUniformBlockBinding", + "glDrawArraysInstanced", + "glDrawElementsInstanced", + "glFenceSync", + "glIsSync", + "glDeleteSync", + "glClientWaitSync", + "glWaitSync", + "glGetInteger64v", + "glGetSynciv", + "glGetInteger64i_v", + "glGetBufferParameteri64v", + "glGenSamplers", + "glDeleteSamplers", + "glIsSampler", + "glBindSampler", + "glSamplerParameteri", + "glSamplerParameteriv", + "glSamplerParameterf", + "glSamplerParameterfv", + "glGetSamplerParameteriv", + "glGetSamplerParameterfv", + "glVertexAttribDivisor", + "glBindTransformFeedback", + "glDeleteTransformFeedbacks", + "glGenTransformFeedbacks", + "glIsTransformFeedback", + "glPauseTransformFeedback", + "glResumeTransformFeedback", + "glGetProgramBinary", + "glProgramBinary", + "glProgramParameteri", + "glInvalidateFramebuffer", + "glInvalidateSubFramebuffer", + "glTexStorage2D", + "glTexStorage3D", + "glGetInternalformativ" + ], + + "GLES31 core": [ + "glDispatchCompute", + "glDispatchComputeIndirect", + "glDrawArraysIndirect", + "glDrawElementsIndirect", + "glFramebufferParameteri", + "glGetFramebufferParameteriv", + "glGetProgramInterfaceiv", + "glGetProgramResourceIndex", + "glGetProgramResourceName", + "glGetProgramResourceiv", + "glGetProgramResourceLocation", + "glUseProgramStages", + "glActiveShaderProgram", + "glCreateShaderProgramv", + "glBindProgramPipeline", + "glDeleteProgramPipelines", + "glGenProgramPipelines", + "glIsProgramPipeline", + "glGetProgramPipelineiv", + "glProgramUniform1i", + "glProgramUniform2i", + "glProgramUniform3i", + "glProgramUniform4i", + "glProgramUniform1ui", + "glProgramUniform2ui", + "glProgramUniform3ui", + "glProgramUniform4ui", + "glProgramUniform1f", + "glProgramUniform2f", + "glProgramUniform3f", + "glProgramUniform4f", + "glProgramUniform1iv", + "glProgramUniform2iv", + "glProgramUniform3iv", + "glProgramUniform4iv", + "glProgramUniform1uiv", + "glProgramUniform2uiv", + "glProgramUniform3uiv", + "glProgramUniform4uiv", + "glProgramUniform1fv", + "glProgramUniform2fv", + "glProgramUniform3fv", + "glProgramUniform4fv", + "glProgramUniformMatrix2fv", + "glProgramUniformMatrix3fv", + "glProgramUniformMatrix4fv", + "glProgramUniformMatrix2x3fv", + "glProgramUniformMatrix3x2fv", + "glProgramUniformMatrix2x4fv", + "glProgramUniformMatrix4x2fv", + "glProgramUniformMatrix3x4fv", + "glProgramUniformMatrix4x3fv", + "glValidateProgramPipeline", + "glGetProgramPipelineInfoLog", + "glBindImageTexture", + "glGetBooleani_v", + "glMemoryBarrier", + "glMemoryBarrierByRegion", + "glTexStorage2DMultisample", + "glGetMultisamplefv", + "glSampleMaski", + "glGetTexLevelParameteriv", + "glGetTexLevelParameterfv", + "glBindVertexBuffer", + "glVertexAttribFormat", + "glVertexAttribIFormat", + "glVertexAttribBinding", + "glVertexBindingDivisor" + ], + + "EGL 1.0": [ + "eglChooseConfig", + "eglCopyBuffers", + "eglCreateContext", + "eglCreatePbufferSurface", + "eglCreatePixmapSurface", + "eglCreateWindowSurface", + "eglDestroyContext", + "eglDestroySurface", + "eglGetConfigAttrib", + "eglGetConfigs", + "eglGetCurrentDisplay", + "eglGetCurrentSurface", + "eglGetDisplay", + "eglGetError", + "eglGetProcAddress", + "eglInitialize", + "eglMakeCurrent", + "eglQueryContext", + "eglQueryString", + "eglQuerySurface", + "eglSwapBuffers", + "eglTerminate", + "eglWaitGL", + "eglWaitNative" + ], + + "EGL 1.1": [ + "eglBindTexImage", + "eglReleaseTexImage", + "eglSurfaceAttrib", + "eglSwapInterval" + ], + + "EGL 1.2": [ + "eglBindAPI", + "eglQueryAPI", + "eglCreatePbufferFromClientBuffer", + "eglReleaseThread", + "eglWaitClient" + ], + + "EGL 1.4": [ + "eglGetCurrentContext" + ], + + "EGL 1.5": [ + "eglCreateSync", + "eglDestroySync", + "eglClientWaitSync", + "eglGetSyncAttrib", + "eglCreateImage", + "eglDestroyImage", + "eglGetPlatformDisplay", + "eglCreatePlatformWindowSurface", + "eglCreatePlatformPixmapSurface", + "eglWaitSync" + ], + + "EGL_ANGLE_query_surface_pointer": [ + "eglQuerySurfacePointerANGLE" + ], + + "EGL_NV_post_sub_buffer": [ + "eglPostSubBufferNV" + ], + + "EGL_EXT_platform_base": [ + "eglGetPlatformDisplayEXT" + ], + + "EGL_EXT_device_query": [ + "eglQueryDisplayAttribEXT", + "eglQueryDeviceAttribEXT", + "eglQueryDeviceStringEXT" + ], + + "EGL_KHR_image_base/EGL_KHR_image": [ + "eglCreateImageKHR", + "eglDestroyImageKHR" + ], + + "EGL_EXT_device_creation": [ + "eglCreateDeviceANGLE", + "eglReleaseDeviceANGLE" + ], + + "EGL_KHR_stream": [ + "eglCreateStreamKHR", + "eglDestroyStreamKHR", + "eglStreamAttribKHR", + "eglQueryStreamKHR", + "eglQueryStreamu64KHR" + ], + + "EGL_KHR_stream_consumer_gltexture": [ + "eglStreamConsumerGLTextureExternalKHR", + "eglStreamConsumerAcquireKHR", + "eglStreamConsumerReleaseKHR" + ], + + "EGL_NV_stream_consumer_gltexture_yuv": [ + "eglStreamConsumerGLTextureExternalAttribsNV" + ], + + "EGL_ANGLE_stream_producer_d3d_texture_nv12": [ + "eglCreateStreamProducerD3DTextureNV12ANGLE", + "eglStreamPostD3DTextureNV12ANGLE" + ], + + "EGL_CHROMIUM_get_sync_values": [ + "eglGetSyncValuesCHROMIUM" + ], + + "EGL_EXT_swap_buffers_with_damage": [ + "eglSwapBuffersWithDamageEXT" + ], + + "EGL_ANGLE_program_cache_control": [ + "eglProgramCacheGetAttribANGLE", + "eglProgramCacheQueryANGLE", + "eglProgramCachePopulateANGLE", + "eglProgramCacheResizeANGLE" + ], + + "angle::Platform related entry points": [ + "ANGLEGetDisplayPlatform", + "ANGLEResetDisplayPlatform" + ] +} diff --git a/src/3rdparty/angle/src/third_party/compiler/ArrayBoundsClamper.cpp b/src/3rdparty/angle/src/third_party/compiler/ArrayBoundsClamper.cpp index fa6c8b8d79..17e272301a 100644 --- a/src/3rdparty/angle/src/third_party/compiler/ArrayBoundsClamper.cpp +++ b/src/3rdparty/angle/src/third_party/compiler/ArrayBoundsClamper.cpp @@ -25,6 +25,8 @@ #include "third_party/compiler/ArrayBoundsClamper.h" +#include "compiler/translator/IntermTraverse.h" + // The built-in 'clamp' instruction only accepts floats and returns a float. I // iterated a few times with our driver team who examined the output from our // compiler - they said the multiple casts generates more code than a single @@ -38,7 +40,11 @@ const char* kIntClampBegin = "// BEGIN: Generated code for array bounds clamping const char* kIntClampEnd = "// END: Generated code for array bounds clamping\n\n"; const char* kIntClampDefinition = "int webgl_int_clamp(int value, int minValue, int maxValue) { return ((value < minValue) ? minValue : ((value > maxValue) ? maxValue : value)); }\n\n"; -namespace { +namespace sh +{ + +namespace +{ class ArrayBoundsClamperMarker : public TIntermTraverser { public: @@ -105,3 +111,5 @@ void ArrayBoundsClamper::OutputClampingFunctionDefinition(TInfoSinkBase& out) co } out << kIntClampBegin << kIntClampDefinition << kIntClampEnd; } + +} // namespace sh diff --git a/src/3rdparty/angle/src/third_party/compiler/ArrayBoundsClamper.h b/src/3rdparty/angle/src/third_party/compiler/ArrayBoundsClamper.h index 27917e6eec..a4c407f760 100644 --- a/src/3rdparty/angle/src/third_party/compiler/ArrayBoundsClamper.h +++ b/src/3rdparty/angle/src/third_party/compiler/ArrayBoundsClamper.h @@ -29,8 +29,12 @@ #include "compiler/translator/InfoSink.h" #include "compiler/translator/IntermNode.h" -class ArrayBoundsClamper { -public: +namespace sh +{ + +class ArrayBoundsClamper +{ + public: ArrayBoundsClamper(); // Must be set before compiling any shaders to ensure consistency @@ -57,4 +61,6 @@ private: bool mArrayBoundsClampDefinitionNeeded; }; +} // namespace sh + #endif // THIRD_PARTY_COMPILER_ARRAYBOUNDSCLAMPER_H_ diff --git a/src/3rdparty/angle/src/third_party/libXNVCtrl/LICENSE b/src/3rdparty/angle/src/third_party/libXNVCtrl/LICENSE new file mode 100644 index 0000000000..74324c0c6f --- /dev/null +++ b/src/3rdparty/angle/src/third_party/libXNVCtrl/LICENSE @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2008 NVIDIA, Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ \ No newline at end of file diff --git a/src/3rdparty/angle/src/third_party/libXNVCtrl/NVCtrl.c b/src/3rdparty/angle/src/third_party/libXNVCtrl/NVCtrl.c new file mode 100644 index 0000000000..e984373947 --- /dev/null +++ b/src/3rdparty/angle/src/third_party/libXNVCtrl/NVCtrl.c @@ -0,0 +1,1240 @@ +/* + * Copyright (c) 2008 NVIDIA, Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * Make sure that XTHREADS is defined, so that the + * LockDisplay/UnlockDisplay macros are expanded properly and the + * libXNVCtrl library properly protects the Display connection. + */ + +#if !defined(XTHREADS) +#define XTHREADS +#endif /* XTHREADS */ + +#define NEED_EVENTS +#define NEED_REPLIES +#include +#include +#include +#include +#include +#include +#include "NVCtrlLib.h" +#include "nv_control.h" + +#define NVCTRL_EXT_EXISTS 1 +#define NVCTRL_EXT_NEED_TARGET_SWAP 2 +#define NVCTRL_EXT_64_BIT_ATTRIBUTES 4 +#define NVCTRL_EXT_NEED_CHECK (1 << (sizeof(XPointer) - 1)) + +static XExtensionInfo _nvctrl_ext_info_data; +static XExtensionInfo *nvctrl_ext_info = &_nvctrl_ext_info_data; +static const char *nvctrl_extension_name = NV_CONTROL_NAME; + +#define XNVCTRLCheckExtension(dpy,i,val) \ + XextCheckExtension (dpy, i, nvctrl_extension_name, val) +#define XNVCTRLSimpleCheckExtension(dpy,i) \ + XextSimpleCheckExtension (dpy, i, nvctrl_extension_name) + +static int close_display(); +static uintptr_t version_flags(Display *dpy, XExtDisplayInfo *info); +static Bool wire_to_event(); +static /* const */ XExtensionHooks nvctrl_extension_hooks = { + NULL, /* create_gc */ + NULL, /* copy_gc */ + NULL, /* flush_gc */ + NULL, /* free_gc */ + NULL, /* create_font */ + NULL, /* free_font */ + close_display, /* close_display */ + wire_to_event, /* wire_to_event */ + NULL, /* event_to_wire */ + NULL, /* error */ + NULL, /* error_string */ +}; + +static XEXT_GENERATE_FIND_DISPLAY (find_display, nvctrl_ext_info, + nvctrl_extension_name, + &nvctrl_extension_hooks, + NV_CONTROL_EVENTS, + (XPointer)NVCTRL_EXT_NEED_CHECK) + +static XEXT_GENERATE_CLOSE_DISPLAY (close_display, nvctrl_ext_info) + +/* + * NV-CONTROL versions 1.8 and 1.9 pack the target_type and target_id + * fields in reversed order. In order to talk to one of these servers, + * we need to swap these fields. + */ + +static void XNVCTRLCheckTargetData(Display *dpy, XExtDisplayInfo *info, + int *target_type, int *target_id) +{ + uintptr_t flags = version_flags(dpy, info); + + /* We need to swap the target_type and target_id */ + if (flags & NVCTRL_EXT_NEED_TARGET_SWAP) { + int tmp; + tmp = *target_type; + *target_type = *target_id; + *target_id = tmp; + } +} + + +Bool XNVCTRLQueryExtension ( + Display *dpy, + int *event_basep, + int *error_basep +){ + XExtDisplayInfo *info = find_display (dpy); + + if (XextHasExtension(info)) { + if (event_basep) *event_basep = info->codes->first_event; + if (error_basep) *error_basep = info->codes->first_error; + return True; + } else { + return False; + } +} + +/* + * Retrieve any cached flags that depend on the version of the NV-CONTROL + * extension. + */ + +static uintptr_t version_flags(Display *dpy, XExtDisplayInfo *info) +{ + uintptr_t data = (uintptr_t)info->data; + + /* If necessary, determine the NV-CONTROL version */ + if (data & NVCTRL_EXT_NEED_CHECK) { + int major, minor; + data = 0; + if (XNVCTRLQueryVersion(dpy, &major, &minor)) { + data |= NVCTRL_EXT_EXISTS; + if (major == 1 && (minor == 8 || minor == 9)) { + data |= NVCTRL_EXT_NEED_TARGET_SWAP; + } + if ((major > 1) || ((major == 1) && (minor > 20))) { + data |= NVCTRL_EXT_64_BIT_ATTRIBUTES; + } + } + + info->data = (XPointer)data; + } + + return data; +} + +Bool XNVCTRLQueryVersion ( + Display *dpy, + int *major, + int *minor +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlQueryExtensionReply rep; + xnvCtrlQueryExtensionReq *req; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay (dpy); + GetReq (nvCtrlQueryExtension, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlQueryExtension; + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + if (major) *major = rep.major; + if (minor) *minor = rep.minor; + UnlockDisplay (dpy); + SyncHandle (); + return True; +} + + +Bool XNVCTRLIsNvScreen ( + Display *dpy, + int screen +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlIsNvReply rep; + xnvCtrlIsNvReq *req; + Bool isnv; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay (dpy); + GetReq (nvCtrlIsNv, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlIsNv; + req->screen = screen; + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + isnv = rep.isnv; + UnlockDisplay (dpy); + SyncHandle (); + return isnv; +} + + +Bool XNVCTRLQueryTargetCount ( + Display *dpy, + int target_type, + int *value +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlQueryTargetCountReply rep; + xnvCtrlQueryTargetCountReq *req; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay (dpy); + GetReq (nvCtrlQueryTargetCount, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlQueryTargetCount; + req->target_type = target_type; + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + if (value) *value = rep.count; + UnlockDisplay (dpy); + SyncHandle (); + return True; +} + + +void XNVCTRLSetTargetAttribute ( + Display *dpy, + int target_type, + int target_id, + unsigned int display_mask, + unsigned int attribute, + int value +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlSetAttributeReq *req; + + XNVCTRLSimpleCheckExtension (dpy, info); + XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id); + + LockDisplay (dpy); + GetReq (nvCtrlSetAttribute, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlSetAttribute; + req->target_type = target_type; + req->target_id = target_id; + req->display_mask = display_mask; + req->attribute = attribute; + req->value = value; + UnlockDisplay (dpy); + SyncHandle (); +} + +void XNVCTRLSetAttribute ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + int value +){ + XNVCTRLSetTargetAttribute (dpy, NV_CTRL_TARGET_TYPE_X_SCREEN, screen, + display_mask, attribute, value); +} + + +Bool XNVCTRLSetTargetAttributeAndGetStatus ( + Display *dpy, + int target_type, + int target_id, + unsigned int display_mask, + unsigned int attribute, + int value +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlSetAttributeAndGetStatusReq *req; + xnvCtrlSetAttributeAndGetStatusReply rep; + Bool success; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay (dpy); + GetReq (nvCtrlSetAttributeAndGetStatus, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlSetAttributeAndGetStatus; + req->target_type = target_type; + req->target_id = target_id; + req->display_mask = display_mask; + req->attribute = attribute; + req->value = value; + if (!_XReply (dpy, (xReply *) &rep, 0, False)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + UnlockDisplay (dpy); + SyncHandle (); + + success = rep.flags; + return success; +} + +Bool XNVCTRLSetAttributeAndGetStatus ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + int value +){ + return XNVCTRLSetTargetAttributeAndGetStatus(dpy, + NV_CTRL_TARGET_TYPE_X_SCREEN, + screen, display_mask, + attribute, value); +} + + +Bool XNVCTRLQueryTargetAttribute ( + Display *dpy, + int target_type, + int target_id, + unsigned int display_mask, + unsigned int attribute, + int *value +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlQueryAttributeReply rep; + xnvCtrlQueryAttributeReq *req; + Bool exists; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id); + + LockDisplay (dpy); + GetReq (nvCtrlQueryAttribute, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlQueryAttribute; + req->target_type = target_type; + req->target_id = target_id; + req->display_mask = display_mask; + req->attribute = attribute; + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + exists = rep.flags; + if (exists && value) *value = rep.value; + UnlockDisplay (dpy); + SyncHandle (); + return exists; +} + +Bool XNVCTRLQueryAttribute ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + int *value +){ + return XNVCTRLQueryTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_X_SCREEN, + screen, display_mask, attribute, value); +} + + +Bool XNVCTRLQueryTargetAttribute64 ( + Display *dpy, + int target_type, + int target_id, + unsigned int display_mask, + unsigned int attribute, + int64_t *value +){ + XExtDisplayInfo *info = find_display(dpy); + xnvCtrlQueryAttribute64Reply rep; + xnvCtrlQueryAttributeReq *req; + Bool exists; + + if (!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension(dpy, info, False); + XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id); + + LockDisplay(dpy); + GetReq(nvCtrlQueryAttribute, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlQueryAttribute64; + req->target_type = target_type; + req->target_id = target_id; + req->display_mask = display_mask; + req->attribute = attribute; + if (!_XReply(dpy, (xReply *)&rep, 0, xTrue)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + exists = rep.flags; + if (exists && value) *value = rep.value_64; + UnlockDisplay(dpy); + SyncHandle(); + return exists; +} + + +Bool XNVCTRLQueryTargetStringAttribute ( + Display *dpy, + int target_type, + int target_id, + unsigned int display_mask, + unsigned int attribute, + char **ptr +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlQueryStringAttributeReply rep; + xnvCtrlQueryStringAttributeReq *req; + Bool exists; + int length, numbytes, slop; + + if (!ptr) return False; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id); + + LockDisplay (dpy); + GetReq (nvCtrlQueryStringAttribute, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlQueryStringAttribute; + req->target_type = target_type; + req->target_id = target_id; + req->display_mask = display_mask; + req->attribute = attribute; + if (!_XReply (dpy, (xReply *) &rep, 0, False)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + length = rep.length; + numbytes = rep.n; + slop = numbytes & 3; + exists = rep.flags; + if (exists) { + *ptr = (char *) Xmalloc(numbytes); + } + if (!exists || !*ptr) { + _XEatData(dpy, length); + UnlockDisplay (dpy); + SyncHandle (); + return False; + } else { + _XRead(dpy, (char *) *ptr, numbytes); + if (slop) _XEatData(dpy, 4-slop); + } + UnlockDisplay (dpy); + SyncHandle (); + return exists; +} + +Bool XNVCTRLQueryStringAttribute ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + char **ptr +){ + return XNVCTRLQueryTargetStringAttribute(dpy, NV_CTRL_TARGET_TYPE_X_SCREEN, + screen, display_mask, + attribute, ptr); +} + + +Bool XNVCTRLSetTargetStringAttribute ( + Display *dpy, + int target_type, + int target_id, + unsigned int display_mask, + unsigned int attribute, + char *ptr +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlSetStringAttributeReq *req; + xnvCtrlSetStringAttributeReply rep; + int size; + Bool success; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + size = strlen(ptr)+1; + + LockDisplay (dpy); + GetReq (nvCtrlSetStringAttribute, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlSetStringAttribute; + req->target_type = target_type; + req->target_id = target_id; + req->display_mask = display_mask; + req->attribute = attribute; + req->length += ((size + 3) & ~3) >> 2; + req->num_bytes = size; + Data(dpy, ptr, size); + + if (!_XReply (dpy, (xReply *) &rep, 0, False)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + UnlockDisplay (dpy); + SyncHandle (); + + success = rep.flags; + return success; +} + +Bool XNVCTRLSetStringAttribute ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + char *ptr +){ + return XNVCTRLSetTargetStringAttribute(dpy, NV_CTRL_TARGET_TYPE_X_SCREEN, + screen, display_mask, + attribute, ptr); +} + + +static Bool XNVCTRLQueryValidTargetAttributeValues32 ( + Display *dpy, + XExtDisplayInfo *info, + int target_type, + int target_id, + unsigned int display_mask, + unsigned int attribute, + NVCTRLAttributeValidValuesRec *values +){ + xnvCtrlQueryValidAttributeValuesReply rep; + xnvCtrlQueryValidAttributeValuesReq *req; + Bool exists; + + LockDisplay (dpy); + GetReq (nvCtrlQueryValidAttributeValues, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlQueryValidAttributeValues; + req->target_type = target_type; + req->target_id = target_id; + req->display_mask = display_mask; + req->attribute = attribute; + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + exists = rep.flags; + if (exists) { + values->type = rep.attr_type; + if (rep.attr_type == ATTRIBUTE_TYPE_RANGE) { + values->u.range.min = rep.min; + values->u.range.max = rep.max; + } + if (rep.attr_type == ATTRIBUTE_TYPE_INT_BITS) { + values->u.bits.ints = rep.bits; + } + values->permissions = rep.perms; + } + UnlockDisplay (dpy); + SyncHandle (); + return exists; +} + + +Bool XNVCTRLQueryValidTargetStringAttributeValues ( + Display *dpy, + int target_type, + int target_id, + unsigned int display_mask, + unsigned int attribute, + NVCTRLAttributeValidValuesRec *values +){ + XExtDisplayInfo *info = find_display(dpy); + Bool exists; + xnvCtrlQueryValidAttributeValuesReply rep; + xnvCtrlQueryValidAttributeValuesReq *req; + + if (!values) return False; + + if (!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension(dpy, info, False); + + LockDisplay(dpy); + GetReq (nvCtrlQueryValidAttributeValues, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlQueryValidStringAttributeValues; + req->target_type = target_type; + req->target_id = target_id; + req->display_mask = display_mask; + req->attribute = attribute; + if (!_XReply(dpy, (xReply *)&rep, 0, xTrue)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + exists = rep.flags; + if (exists) { + values->type = rep.attr_type; + values->permissions = rep.perms; + } + UnlockDisplay(dpy); + SyncHandle(); + return exists; +} + + +static Bool XNVCTRLQueryValidTargetAttributeValues64 ( + Display *dpy, + XExtDisplayInfo *info, + int target_type, + int target_id, + unsigned int display_mask, + unsigned int attribute, + NVCTRLAttributeValidValuesRec *values +){ + xnvCtrlQueryValidAttributeValues64Reply rep; + xnvCtrlQueryValidAttributeValuesReq *req; + Bool exists; + + LockDisplay(dpy); + GetReq(nvCtrlQueryValidAttributeValues, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlQueryValidAttributeValues64; + req->target_type = target_type; + req->target_id = target_id; + req->display_mask = display_mask; + req->attribute = attribute; + if (!_XReply(dpy, (xReply *)&rep, + sz_xnvCtrlQueryValidAttributeValues64Reply_extra, + xTrue)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + exists = rep.flags; + if (exists) { + values->type = rep.attr_type; + if (rep.attr_type == ATTRIBUTE_TYPE_RANGE) { + values->u.range.min = rep.min_64; + values->u.range.max = rep.max_64; + } + if (rep.attr_type == ATTRIBUTE_TYPE_INT_BITS) { + values->u.bits.ints = rep.bits_64; + } + values->permissions = rep.perms; + } + UnlockDisplay(dpy); + SyncHandle(); + return exists; +} + +Bool XNVCTRLQueryValidTargetAttributeValues ( + Display *dpy, + int target_type, + int target_id, + unsigned int display_mask, + unsigned int attribute, + NVCTRLAttributeValidValuesRec *values +){ + XExtDisplayInfo *info = find_display(dpy); + Bool exists; + uintptr_t flags; + + if (!values) return False; + + if (!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension(dpy, info, False); + XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id); + + flags = version_flags(dpy,info); + + if (!(flags & NVCTRL_EXT_EXISTS)) + return False; + + if (flags & NVCTRL_EXT_64_BIT_ATTRIBUTES) { + exists = XNVCTRLQueryValidTargetAttributeValues64(dpy, info, + target_type, + target_id, + display_mask, + attribute, + values); + } else { + exists = XNVCTRLQueryValidTargetAttributeValues32(dpy, info, + target_type, + target_id, + display_mask, + attribute, + values); + } + return exists; +} + + +Bool XNVCTRLQueryValidAttributeValues ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + NVCTRLAttributeValidValuesRec *values +){ + return XNVCTRLQueryValidTargetAttributeValues(dpy, + NV_CTRL_TARGET_TYPE_X_SCREEN, + screen, display_mask, + attribute, values); +} + + +static Bool QueryAttributePermissionsInternal ( + Display *dpy, + unsigned int attribute, + NVCTRLAttributePermissionsRec *permissions, + unsigned int reqType +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlQueryAttributePermissionsReply rep; + xnvCtrlQueryAttributePermissionsReq *req; + Bool exists; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(nvCtrlQueryAttributePermissions, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = reqType; + req->attribute = attribute; + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay (dpy); + SyncHandle(); + return False; + } + exists = rep.flags; + if (exists && permissions) { + permissions->type = rep.attr_type; + permissions->permissions = rep.perms; + } + UnlockDisplay(dpy); + SyncHandle(); + return exists; +} + + +Bool XNVCTRLQueryAttributePermissions ( + Display *dpy, + unsigned int attribute, + NVCTRLAttributePermissionsRec *permissions +){ + return QueryAttributePermissionsInternal(dpy, + attribute, + permissions, + X_nvCtrlQueryAttributePermissions); +} + + +Bool XNVCTRLQueryStringAttributePermissions ( + Display *dpy, + unsigned int attribute, + NVCTRLAttributePermissionsRec *permissions +){ + return QueryAttributePermissionsInternal(dpy, + attribute, + permissions, + X_nvCtrlQueryStringAttributePermissions); +} + + +Bool XNVCTRLQueryBinaryDataAttributePermissions ( + Display *dpy, + unsigned int attribute, + NVCTRLAttributePermissionsRec *permissions +){ + return QueryAttributePermissionsInternal(dpy, + attribute, + permissions, + X_nvCtrlQueryBinaryDataAttributePermissions); +} + + +Bool XNVCTRLQueryStringOperationAttributePermissions ( + Display *dpy, + unsigned int attribute, + NVCTRLAttributePermissionsRec *permissions +){ + return QueryAttributePermissionsInternal(dpy, + attribute, + permissions, + X_nvCtrlQueryStringOperationAttributePermissions); +} + + +void XNVCTRLSetGvoColorConversion ( + Display *dpy, + int screen, + float colorMatrix[3][3], + float colorOffset[3], + float colorScale[3] +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlSetGvoColorConversionReq *req; + + XNVCTRLSimpleCheckExtension (dpy, info); + + LockDisplay (dpy); + GetReq (nvCtrlSetGvoColorConversion, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlSetGvoColorConversion; + req->screen = screen; + + req->cscMatrix_y_r = colorMatrix[0][0]; + req->cscMatrix_y_g = colorMatrix[0][1]; + req->cscMatrix_y_b = colorMatrix[0][2]; + + req->cscMatrix_cr_r = colorMatrix[1][0]; + req->cscMatrix_cr_g = colorMatrix[1][1]; + req->cscMatrix_cr_b = colorMatrix[1][2]; + + req->cscMatrix_cb_r = colorMatrix[2][0]; + req->cscMatrix_cb_g = colorMatrix[2][1]; + req->cscMatrix_cb_b = colorMatrix[2][2]; + + req->cscOffset_y = colorOffset[0]; + req->cscOffset_cr = colorOffset[1]; + req->cscOffset_cb = colorOffset[2]; + + req->cscScale_y = colorScale[0]; + req->cscScale_cr = colorScale[1]; + req->cscScale_cb = colorScale[2]; + + UnlockDisplay (dpy); + SyncHandle (); +} + + +Bool XNVCTRLQueryGvoColorConversion ( + Display *dpy, + int screen, + float colorMatrix[3][3], + float colorOffset[3], + float colorScale[3] +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlQueryGvoColorConversionReply rep; + xnvCtrlQueryGvoColorConversionReq *req; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay (dpy); + + GetReq (nvCtrlQueryGvoColorConversion, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlQueryGvoColorConversion; + req->screen = screen; + + if (!_XReply(dpy, (xReply *) &rep, 0, xFalse)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + + _XRead(dpy, (char *)(colorMatrix), 36); + _XRead(dpy, (char *)(colorOffset), 12); + _XRead(dpy, (char *)(colorScale), 12); + + UnlockDisplay (dpy); + SyncHandle (); + + return True; +} + + +Bool XNVCtrlSelectTargetNotify ( + Display *dpy, + int target_type, + int target_id, + int notify_type, + Bool onoff +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlSelectTargetNotifyReq *req; + + if(!XextHasExtension (info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay (dpy); + GetReq (nvCtrlSelectTargetNotify, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlSelectTargetNotify; + req->target_type = target_type; + req->target_id = target_id; + req->notifyType = notify_type; + req->onoff = onoff; + UnlockDisplay (dpy); + SyncHandle (); + + return True; +} + + +Bool XNVCtrlSelectNotify ( + Display *dpy, + int screen, + int type, + Bool onoff +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlSelectNotifyReq *req; + + if(!XextHasExtension (info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay (dpy); + GetReq (nvCtrlSelectNotify, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlSelectNotify; + req->screen = screen; + req->notifyType = type; + req->onoff = onoff; + UnlockDisplay (dpy); + SyncHandle (); + + return True; +} + +Bool XNVCTRLQueryTargetBinaryData ( + Display *dpy, + int target_type, + int target_id, + unsigned int display_mask, + unsigned int attribute, + unsigned char **ptr, + int *len +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlQueryBinaryDataReply rep; + xnvCtrlQueryBinaryDataReq *req; + Bool exists; + int length, numbytes, slop; + + if (!ptr) return False; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id); + + LockDisplay (dpy); + GetReq (nvCtrlQueryBinaryData, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlQueryBinaryData; + req->target_type = target_type; + req->target_id = target_id; + req->display_mask = display_mask; + req->attribute = attribute; + if (!_XReply (dpy, (xReply *) &rep, 0, False)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + length = rep.length; + numbytes = rep.n; + slop = numbytes & 3; + exists = rep.flags; + if (exists) { + *ptr = (unsigned char *) Xmalloc(numbytes); + } + if (!exists || !*ptr) { + _XEatData(dpy, length); + UnlockDisplay (dpy); + SyncHandle (); + return False; + } else { + _XRead(dpy, (char *) *ptr, numbytes); + if (slop) _XEatData(dpy, 4-slop); + } + if (len) *len = numbytes; + UnlockDisplay (dpy); + SyncHandle (); + return exists; +} + +Bool XNVCTRLQueryBinaryData ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + unsigned char **ptr, + int *len +){ + return XNVCTRLQueryTargetBinaryData(dpy, NV_CTRL_TARGET_TYPE_X_SCREEN, + screen, display_mask, + attribute, ptr, len); +} + +Bool XNVCTRLStringOperation ( + Display *dpy, + int target_type, + int target_id, + unsigned int display_mask, + unsigned int attribute, + char *pIn, + char **ppOut +) { + XExtDisplayInfo *info = find_display(dpy); + xnvCtrlStringOperationReq *req; + xnvCtrlStringOperationReply rep; + Bool ret; + int inSize, outSize, length, slop; + + if (!XextHasExtension(info)) + return False; + + if (!ppOut) + return False; + + *ppOut = NULL; + + XNVCTRLCheckExtension(dpy, info, False); + XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id); + + if (pIn) { + inSize = strlen(pIn) + 1; + } else { + inSize = 0; + } + + LockDisplay(dpy); + GetReq(nvCtrlStringOperation, req); + + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlStringOperation; + req->target_type = target_type; + req->target_id = target_id; + req->display_mask = display_mask; + req->attribute = attribute; + + req->length += ((inSize + 3) & ~3) >> 2; + req->num_bytes = inSize; + + if (pIn) { + Data(dpy, pIn, inSize); + } + + if (!_XReply (dpy, (xReply *) &rep, 0, False)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + + length = rep.length; + outSize = rep.num_bytes; + slop = outSize & 3; + + if (outSize) *ppOut = (char *) Xmalloc(outSize); + + if (!*ppOut) { + _XEatData(dpy, length); + } else { + _XRead(dpy, (char *) *ppOut, outSize); + if (slop) _XEatData(dpy, 4-slop); + } + + ret = rep.ret; + + UnlockDisplay(dpy); + SyncHandle(); + + return ret; +} + + +static Bool wire_to_event (Display *dpy, XEvent *host, xEvent *wire) +{ + XExtDisplayInfo *info = find_display (dpy); + XNVCtrlEvent *re; + xnvctrlEvent *event; + XNVCtrlEventTarget *reTarget; + xnvctrlEventTarget *eventTarget; + XNVCtrlEventTargetAvailability *reTargetAvailability; + XNVCtrlStringEventTarget *reTargetString; + XNVCtrlBinaryEventTarget *reTargetBinary; + + XNVCTRLCheckExtension (dpy, info, False); + + switch ((wire->u.u.type & 0x7F) - info->codes->first_event) { + case ATTRIBUTE_CHANGED_EVENT: + re = (XNVCtrlEvent *) host; + event = (xnvctrlEvent *) wire; + re->attribute_changed.type = event->u.u.type & 0x7F; + re->attribute_changed.serial = + _XSetLastRequestRead(dpy, (xGenericReply*) event); + re->attribute_changed.send_event = ((event->u.u.type & 0x80) != 0); + re->attribute_changed.display = dpy; + re->attribute_changed.time = event->u.attribute_changed.time; + re->attribute_changed.screen = event->u.attribute_changed.screen; + re->attribute_changed.display_mask = + event->u.attribute_changed.display_mask; + re->attribute_changed.attribute = event->u.attribute_changed.attribute; + re->attribute_changed.value = event->u.attribute_changed.value; + break; + case TARGET_ATTRIBUTE_CHANGED_EVENT: + reTarget = (XNVCtrlEventTarget *) host; + eventTarget = (xnvctrlEventTarget *) wire; + reTarget->attribute_changed.type = eventTarget->u.u.type & 0x7F; + reTarget->attribute_changed.serial = + _XSetLastRequestRead(dpy, (xGenericReply*) eventTarget); + reTarget->attribute_changed.send_event = + ((eventTarget->u.u.type & 0x80) != 0); + reTarget->attribute_changed.display = dpy; + reTarget->attribute_changed.time = + eventTarget->u.attribute_changed.time; + reTarget->attribute_changed.target_type = + eventTarget->u.attribute_changed.target_type; + reTarget->attribute_changed.target_id = + eventTarget->u.attribute_changed.target_id; + reTarget->attribute_changed.display_mask = + eventTarget->u.attribute_changed.display_mask; + reTarget->attribute_changed.attribute = + eventTarget->u.attribute_changed.attribute; + reTarget->attribute_changed.value = + eventTarget->u.attribute_changed.value; + break; + case TARGET_ATTRIBUTE_AVAILABILITY_CHANGED_EVENT: + reTargetAvailability = (XNVCtrlEventTargetAvailability *) host; + eventTarget = (xnvctrlEventTarget *) wire; + reTargetAvailability->attribute_changed.type = + eventTarget->u.u.type & 0x7F; + reTargetAvailability->attribute_changed.serial = + _XSetLastRequestRead(dpy, (xGenericReply*) eventTarget); + reTargetAvailability->attribute_changed.send_event = + ((eventTarget->u.u.type & 0x80) != 0); + reTargetAvailability->attribute_changed.display = dpy; + reTargetAvailability->attribute_changed.time = + eventTarget->u.availability_changed.time; + reTargetAvailability->attribute_changed.target_type = + eventTarget->u.availability_changed.target_type; + reTargetAvailability->attribute_changed.target_id = + eventTarget->u.availability_changed.target_id; + reTargetAvailability->attribute_changed.display_mask = + eventTarget->u.availability_changed.display_mask; + reTargetAvailability->attribute_changed.attribute = + eventTarget->u.availability_changed.attribute; + reTargetAvailability->attribute_changed.availability = + eventTarget->u.availability_changed.availability; + reTargetAvailability->attribute_changed.value = + eventTarget->u.availability_changed.value; + break; + case TARGET_STRING_ATTRIBUTE_CHANGED_EVENT: + reTargetString = (XNVCtrlStringEventTarget *) host; + eventTarget = (xnvctrlEventTarget *) wire; + reTargetString->attribute_changed.type = eventTarget->u.u.type & 0x7F; + reTargetString->attribute_changed.serial = + _XSetLastRequestRead(dpy, (xGenericReply*) eventTarget); + reTargetString->attribute_changed.send_event = + ((eventTarget->u.u.type & 0x80) != 0); + reTargetString->attribute_changed.display = dpy; + reTargetString->attribute_changed.time = + eventTarget->u.attribute_changed.time; + reTargetString->attribute_changed.target_type = + eventTarget->u.attribute_changed.target_type; + reTargetString->attribute_changed.target_id = + eventTarget->u.attribute_changed.target_id; + reTargetString->attribute_changed.display_mask = + eventTarget->u.attribute_changed.display_mask; + reTargetString->attribute_changed.attribute = + eventTarget->u.attribute_changed.attribute; + break; + case TARGET_BINARY_ATTRIBUTE_CHANGED_EVENT: + reTargetBinary = (XNVCtrlBinaryEventTarget *) host; + eventTarget = (xnvctrlEventTarget *) wire; + reTargetBinary->attribute_changed.type = eventTarget->u.u.type & 0x7F; + reTargetBinary->attribute_changed.serial = + _XSetLastRequestRead(dpy, (xGenericReply*) eventTarget); + reTargetBinary->attribute_changed.send_event = + ((eventTarget->u.u.type & 0x80) != 0); + reTargetBinary->attribute_changed.display = dpy; + reTargetBinary->attribute_changed.time = + eventTarget->u.attribute_changed.time; + reTargetBinary->attribute_changed.target_type = + eventTarget->u.attribute_changed.target_type; + reTargetBinary->attribute_changed.target_id = + eventTarget->u.attribute_changed.target_id; + reTargetBinary->attribute_changed.display_mask = + eventTarget->u.attribute_changed.display_mask; + reTargetBinary->attribute_changed.attribute = + eventTarget->u.attribute_changed.attribute; + break; + + default: + return False; + } + + return True; +} + diff --git a/src/3rdparty/angle/src/third_party/libXNVCtrl/NVCtrl.h b/src/3rdparty/angle/src/third_party/libXNVCtrl/NVCtrl.h new file mode 100644 index 0000000000..7bd7ab7a33 --- /dev/null +++ b/src/3rdparty/angle/src/third_party/libXNVCtrl/NVCtrl.h @@ -0,0 +1,4365 @@ +/* + * Copyright (c) 2010 NVIDIA, Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __NVCTRL_H +#define __NVCTRL_H + +#include + +/**************************************************************************/ + +/* + * Attribute Targets + * + * Targets define attribute groups. For example, some attributes are only + * valid to set on a GPU, others are only valid when talking about an + * X Screen. Target types are then what is used to identify the target + * group of the attribute you wish to set/query. + * + * Here are the supported target types: + */ + +#define NV_CTRL_TARGET_TYPE_X_SCREEN 0 +#define NV_CTRL_TARGET_TYPE_GPU 1 +#define NV_CTRL_TARGET_TYPE_FRAMELOCK 2 +#define NV_CTRL_TARGET_TYPE_VCSC 3 /* Visual Computing System */ +#define NV_CTRL_TARGET_TYPE_GVI 4 +#define NV_CTRL_TARGET_TYPE_COOLER 5 /* e.g., fan */ +#define NV_CTRL_TARGET_TYPE_THERMAL_SENSOR 6 +#define NV_CTRL_TARGET_TYPE_3D_VISION_PRO_TRANSCEIVER 7 +#define NV_CTRL_TARGET_TYPE_DISPLAY 8 + +/**************************************************************************/ + +/* + * Attributes + * + * Some attributes may only be read; some may require a display_mask + * argument and others may be valid only for specific target types. + * This information is encoded in the "permission" comment after each + * attribute #define, and can be queried at run time with + * XNVCTRLQueryValidAttributeValues() and/or + * XNVCTRLQueryValidTargetAttributeValues() + * + * Key to Integer Attribute "Permissions": + * + * R: The attribute is readable (in general, all attributes will be + * readable) + * + * W: The attribute is writable (attributes may not be writable for + * various reasons: they represent static system information, they + * can only be changed by changing an XF86Config option, etc). + * + * D: The attribute requires the display mask argument. The + * attributes NV_CTRL_CONNECTED_DISPLAYS and NV_CTRL_ENABLED_DISPLAYS + * will be a bitmask of what display devices are connected and what + * display devices are enabled for use in X, respectively. Each bit + * in the bitmask represents a display device; it is these bits which + * should be used as the display_mask when dealing with attributes + * designated with "D" below. For attributes that do not require the + * display mask, the argument is ignored. + * + * Alternatively, NV-CONTROL versions 1.27 and greater allow these + * attributes to be accessed via display target types, in which case + * the display_mask is ignored. + * + * G: The attribute may be queried using an NV_CTRL_TARGET_TYPE_GPU + * target type via XNVCTRLQueryTargetAttribute(). + * + * F: The attribute may be queried using an NV_CTRL_TARGET_TYPE_FRAMELOCK + * target type via XNVCTRLQueryTargetAttribute(). + * + * X: When Xinerama is enabled, this attribute is kept consistent across + * all Physical X Screens; assignment of this attribute will be + * broadcast by the NVIDIA X Driver to all X Screens. + * + * V: The attribute may be queried using an NV_CTRL_TARGET_TYPE_VCSC + * target type via XNVCTRLQueryTargetAttribute(). + * + * I: The attribute may be queried using an NV_CTRL_TARGET_TYPE_GVI target type + * via XNVCTRLQueryTargetAttribute(). + * + * Q: The attribute is a 64-bit integer attribute; use the 64-bit versions + * of the appropriate query interfaces. + * + * C: The attribute may be queried using an NV_CTRL_TARGET_TYPE_COOLER target + * type via XNVCTRLQueryTargetAttribute(). + * + * S: The attribute may be queried using an NV_CTRL_TARGET_TYPE_THERMAL_SENSOR + * target type via XNVCTRLQueryTargetAttribute(). + * + * T: The attribute may be queried using an + * NV_CTRL_TARGET_TYPE_3D_VISION_PRO_TRANSCEIVER target type + * via XNVCTRLQueryTargetAttribute(). + * + * NOTE: Unless mentioned otherwise, all attributes may be queried using + * an NV_CTRL_TARGET_TYPE_X_SCREEN target type via + * XNVCTRLQueryTargetAttribute(). + */ + +/**************************************************************************/ + +/* + * Integer attributes: + * + * Integer attributes can be queried through the XNVCTRLQueryAttribute() and + * XNVCTRLQueryTargetAttribute() function calls. + * + * Integer attributes can be set through the XNVCTRLSetAttribute() and + * XNVCTRLSetTargetAttribute() function calls. + * + * Unless otherwise noted, all integer attributes can be queried/set + * using an NV_CTRL_TARGET_TYPE_X_SCREEN target. Attributes that cannot + * take an NV_CTRL_TARGET_TYPE_X_SCREEN also cannot be queried/set through + * XNVCTRLQueryAttribute()/XNVCTRLSetAttribute() (Since these assume + * an X Screen target). + */ + +/* + * NV_CTRL_FLATPANEL_SCALING - not supported + */ + +#define NV_CTRL_FLATPANEL_SCALING 2 /* RWDG */ +#define NV_CTRL_FLATPANEL_SCALING_DEFAULT 0 +#define NV_CTRL_FLATPANEL_SCALING_NATIVE 1 +#define NV_CTRL_FLATPANEL_SCALING_SCALED 2 +#define NV_CTRL_FLATPANEL_SCALING_CENTERED 3 +#define NV_CTRL_FLATPANEL_SCALING_ASPECT_SCALED 4 + +/* + * NV_CTRL_FLATPANEL_DITHERING is deprecated; NV_CTRL_DITHERING should + * be used instead. + */ + +#define NV_CTRL_FLATPANEL_DITHERING 3 /* RWDG */ +#define NV_CTRL_FLATPANEL_DITHERING_DEFAULT 0 +#define NV_CTRL_FLATPANEL_DITHERING_ENABLED 1 +#define NV_CTRL_FLATPANEL_DITHERING_DISABLED 2 + +/* + * NV_CTRL_DITHERING - the requested dithering configuration; + * possible values are: + * + * 0: auto (the driver will decide when to dither) + * 1: enabled (the driver will always dither when possible) + * 2: disabled (the driver will never dither) + */ + +#define NV_CTRL_DITHERING 3 /* RWDG */ +#define NV_CTRL_DITHERING_AUTO 0 +#define NV_CTRL_DITHERING_ENABLED 1 +#define NV_CTRL_DITHERING_DISABLED 2 + +/* + * NV_CTRL_DIGITAL_VIBRANCE - sets the digital vibrance level for the + * specified display device. + */ + +#define NV_CTRL_DIGITAL_VIBRANCE 4 /* RWDG */ + +/* + * NV_CTRL_BUS_TYPE - returns the bus type through which the specified device + * is connected to the computer. + * When this attribute is queried on an X screen target, the bus type of the + * GPU driving the X screen is returned. + */ + +#define NV_CTRL_BUS_TYPE 5 /* R--GI */ +#define NV_CTRL_BUS_TYPE_AGP 0 +#define NV_CTRL_BUS_TYPE_PCI 1 +#define NV_CTRL_BUS_TYPE_PCI_EXPRESS 2 +#define NV_CTRL_BUS_TYPE_INTEGRATED 3 + +/* + * NV_CTRL_VIDEO_RAM - returns the total amount of memory available + * to the specified GPU (or the GPU driving the specified X + * screen). Note: if the GPU supports TurboCache(TM), the value + * reported may exceed the amount of video memory installed on the + * GPU. The value reported for integrated GPUs may likewise exceed + * the amount of dedicated system memory set aside by the system + * BIOS for use by the integrated GPU. + */ + +#define NV_CTRL_VIDEO_RAM 6 /* R--G */ + +/* + * NV_CTRL_IRQ - returns the interrupt request line used by the specified + * device. + * When this attribute is queried on an X screen target, the IRQ of the GPU + * driving the X screen is returned. + */ + +#define NV_CTRL_IRQ 7 /* R--GI */ + +/* + * NV_CTRL_OPERATING_SYSTEM - returns the operating system on which + * the X server is running. + */ + +#define NV_CTRL_OPERATING_SYSTEM 8 /* R--G */ +#define NV_CTRL_OPERATING_SYSTEM_LINUX 0 +#define NV_CTRL_OPERATING_SYSTEM_FREEBSD 1 +#define NV_CTRL_OPERATING_SYSTEM_SUNOS 2 + +/* + * NV_CTRL_SYNC_TO_VBLANK - enables sync to vblank for OpenGL clients. + * This setting is only applied to OpenGL clients that are started + * after this setting is applied. + */ + +#define NV_CTRL_SYNC_TO_VBLANK 9 /* RW-X */ +#define NV_CTRL_SYNC_TO_VBLANK_OFF 0 +#define NV_CTRL_SYNC_TO_VBLANK_ON 1 + +/* + * NV_CTRL_LOG_ANISO - enables anisotropic filtering for OpenGL + * clients; on some NVIDIA hardware, this can only be enabled or + * disabled; on other hardware different levels of anisotropic + * filtering can be specified. This setting is only applied to OpenGL + * clients that are started after this setting is applied. + */ + +#define NV_CTRL_LOG_ANISO 10 /* RW-X */ + +/* + * NV_CTRL_FSAA_MODE - the FSAA setting for OpenGL clients; possible + * FSAA modes: + * + * NV_CTRL_FSAA_MODE_2x "2x Bilinear Multisampling" + * NV_CTRL_FSAA_MODE_2x_5t "2x Quincunx Multisampling" + * NV_CTRL_FSAA_MODE_15x15 "1.5 x 1.5 Supersampling" + * NV_CTRL_FSAA_MODE_2x2 "2 x 2 Supersampling" + * NV_CTRL_FSAA_MODE_4x "4x Bilinear Multisampling" + * NV_CTRL_FSAA_MODE_4x_9t "4x Gaussian Multisampling" + * NV_CTRL_FSAA_MODE_8x "2x Bilinear Multisampling by 4x Supersampling" + * NV_CTRL_FSAA_MODE_16x "4x Bilinear Multisampling by 4x Supersampling" + * NV_CTRL_FSAA_MODE_8xS "4x Multisampling by 2x Supersampling" + * + * This setting is only applied to OpenGL clients that are started + * after this setting is applied. + */ + +#define NV_CTRL_FSAA_MODE 11 /* RW-X */ +#define NV_CTRL_FSAA_MODE_NONE 0 +#define NV_CTRL_FSAA_MODE_2x 1 +#define NV_CTRL_FSAA_MODE_2x_5t 2 +#define NV_CTRL_FSAA_MODE_15x15 3 +#define NV_CTRL_FSAA_MODE_2x2 4 +#define NV_CTRL_FSAA_MODE_4x 5 +#define NV_CTRL_FSAA_MODE_4x_9t 6 +#define NV_CTRL_FSAA_MODE_8x 7 +#define NV_CTRL_FSAA_MODE_16x 8 +#define NV_CTRL_FSAA_MODE_8xS 9 +#define NV_CTRL_FSAA_MODE_8xQ 10 +#define NV_CTRL_FSAA_MODE_16xS 11 +#define NV_CTRL_FSAA_MODE_16xQ 12 +#define NV_CTRL_FSAA_MODE_32xS 13 +#define NV_CTRL_FSAA_MODE_32x 14 +#define NV_CTRL_FSAA_MODE_64xS 15 +#define NV_CTRL_FSAA_MODE_MAX NV_CTRL_FSAA_MODE_64xS + +/* + * NV_CTRL_TEXTURE_SHARPEN - enables texture sharpening for OpenGL + * clients. This setting is only applied to OpenGL clients that are + * started after this setting is applied. + */ + +#define NV_CTRL_TEXTURE_SHARPEN 12 /* RW-X */ +#define NV_CTRL_TEXTURE_SHARPEN_OFF 0 +#define NV_CTRL_TEXTURE_SHARPEN_ON 1 + +/* + * NV_CTRL_UBB - returns whether UBB is enabled for the specified X + * screen. + */ + +#define NV_CTRL_UBB 13 /* R-- */ +#define NV_CTRL_UBB_OFF 0 +#define NV_CTRL_UBB_ON 1 + +/* + * NV_CTRL_OVERLAY - returns whether the RGB overlay is enabled for + * the specified X screen. + */ + +#define NV_CTRL_OVERLAY 14 /* R-- */ +#define NV_CTRL_OVERLAY_OFF 0 +#define NV_CTRL_OVERLAY_ON 1 + +/* + * NV_CTRL_STEREO - returns whether stereo (and what type) is enabled + * for the specified X screen. + */ + +#define NV_CTRL_STEREO 16 /* R-- */ +#define NV_CTRL_STEREO_OFF 0 +#define NV_CTRL_STEREO_DDC 1 +#define NV_CTRL_STEREO_BLUELINE 2 +#define NV_CTRL_STEREO_DIN 3 +#define NV_CTRL_STEREO_PASSIVE_EYE_PER_DPY 4 +#define NV_CTRL_STEREO_VERTICAL_INTERLACED 5 +#define NV_CTRL_STEREO_COLOR_INTERLACED 6 +#define NV_CTRL_STEREO_HORIZONTAL_INTERLACED 7 +#define NV_CTRL_STEREO_CHECKERBOARD_PATTERN 8 +#define NV_CTRL_STEREO_INVERSE_CHECKERBOARD_PATTERN 9 +#define NV_CTRL_STEREO_3D_VISION 10 +#define NV_CTRL_STEREO_3D_VISION_PRO 11 + +/* + * NV_CTRL_EMULATE - controls OpenGL software emulation of future + * NVIDIA GPUs. + */ + +#define NV_CTRL_EMULATE 17 /* RW- */ +#define NV_CTRL_EMULATE_NONE 0 + +/* + * NV_CTRL_TWINVIEW - returns whether TwinView is enabled for the + * specified X screen. + */ + +#define NV_CTRL_TWINVIEW 18 /* R-- */ +#define NV_CTRL_TWINVIEW_NOT_ENABLED 0 +#define NV_CTRL_TWINVIEW_ENABLED 1 + +/* + * NV_CTRL_CONNECTED_DISPLAYS - returns a display mask indicating the last + * cached state of the display devices connected to the GPU or GPU driving + * the specified X screen. + * + * This attribute may be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_GPU or NV_CTRL_TARGET_TYPE_X_SCREEN target. + */ + +#define NV_CTRL_CONNECTED_DISPLAYS 19 /* R--G */ + +/* + * NV_CTRL_ENABLED_DISPLAYS - returns a display mask indicating what + * display devices are enabled for use on the specified X screen or + * GPU. + * + * This attribute may be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_GPU or NV_CTRL_TARGET_TYPE_X_SCREEN target. + */ + +#define NV_CTRL_ENABLED_DISPLAYS 20 /* R--G */ + +/**************************************************************************/ +/* + * Integer attributes specific to configuring Frame Lock on boards that + * support it. + */ + +/* + * NV_CTRL_FRAMELOCK - returns whether the underlying GPU supports + * Frame Lock. All of the other frame lock attributes are only + * applicable if NV_CTRL_FRAMELOCK is _SUPPORTED. + * + * This attribute may be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_GPU or NV_CTRL_TARGET_TYPE_X_SCREEN target. + */ + +#define NV_CTRL_FRAMELOCK 21 /* R--G */ +#define NV_CTRL_FRAMELOCK_NOT_SUPPORTED 0 +#define NV_CTRL_FRAMELOCK_SUPPORTED 1 + +/* + * NV_CTRL_FRAMELOCK_MASTER - get/set which display device to use + * as the frame lock master for the entire sync group. Note that only + * one node in the sync group should be configured as the master. + * + * This attribute can only be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_GPU target. This attribute cannot be + * queried using a NV_CTRL_TARGET_TYPE_X_SCREEN. + */ + +#define NV_CTRL_FRAMELOCK_MASTER 22 /* RW-G */ + +/* These are deprecated. NV_CTRL_FRAMELOCK_MASTER now takes and + returns a display mask as value. */ +#define NV_CTRL_FRAMELOCK_MASTER_FALSE 0 +#define NV_CTRL_FRAMELOCK_MASTER_TRUE 1 + +/* + * NV_CTRL_FRAMELOCK_POLARITY - sync either to the rising edge of the + * frame lock pulse, the falling edge of the frame lock pulse or both. + * + * This attribute may be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_FRAMELOCK or NV_CTRL_TARGET_TYPE_X_SCREEN + * target. + */ + +#define NV_CTRL_FRAMELOCK_POLARITY 23 /* RW-F */ +#define NV_CTRL_FRAMELOCK_POLARITY_RISING_EDGE 0x1 +#define NV_CTRL_FRAMELOCK_POLARITY_FALLING_EDGE 0x2 +#define NV_CTRL_FRAMELOCK_POLARITY_BOTH_EDGES 0x3 + +/* + * NV_CTRL_FRAMELOCK_SYNC_DELAY - delay between the frame lock pulse + * and the GPU sync. This value must be multiplied by + * NV_CTRL_FRAMELOCK_SYNC_DELAY_RESOLUTION to determine the sync delay in + * nanoseconds. + * + * This attribute may be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_FRAMELOCK or NV_CTRL_TARGET_TYPE_X_SCREEN + * target. + * + * USAGE NODE: NV_CTRL_FRAMELOCK_SYNC_DELAY_MAX and + * NV_CTRL_FRAMELOCK_SYNC_DELAY_FACTOR are deprecated. + * The Sync Delay _MAX and _FACTOR are different for different + * GSync products and so, to be correct, the valid values for + * NV_CTRL_FRAMELOCK_SYNC_DELAY must be queried to get the range + * of acceptable sync delay values, and + * NV_CTRL_FRAMELOCK_SYNC_DELAY_RESOLUTION must be queried to + * obtain the correct factor. + */ + +#define NV_CTRL_FRAMELOCK_SYNC_DELAY 24 /* RW-F */ +#define NV_CTRL_FRAMELOCK_SYNC_DELAY_MAX 2047 // deprecated +#define NV_CTRL_FRAMELOCK_SYNC_DELAY_FACTOR 7.81 // deprecated + +/* + * NV_CTRL_FRAMELOCK_SYNC_INTERVAL - how many house sync pulses + * between the frame lock sync generation (0 == sync every house sync); + * this only applies to the master when receiving house sync. + * + * This attribute may be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_FRAMELOCK or NV_CTRL_TARGET_TYPE_X_SCREEN + * target. + */ + +#define NV_CTRL_FRAMELOCK_SYNC_INTERVAL 25 /* RW-F */ + +/* + * NV_CTRL_FRAMELOCK_PORT0_STATUS - status of the rj45 port0. + * + * This attribute may be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_FRAMELOCK or NV_CTRL_TARGET_TYPE_X_SCREEN + * target. + */ + +#define NV_CTRL_FRAMELOCK_PORT0_STATUS 26 /* R--F */ +#define NV_CTRL_FRAMELOCK_PORT0_STATUS_INPUT 0 +#define NV_CTRL_FRAMELOCK_PORT0_STATUS_OUTPUT 1 + +/* + * NV_CTRL_FRAMELOCK_PORT1_STATUS - status of the rj45 port1. + * + * This attribute may be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_FRAMELOCK or NV_CTRL_TARGET_TYPE_X_SCREEN + * target. + */ + +#define NV_CTRL_FRAMELOCK_PORT1_STATUS 27 /* R--F */ +#define NV_CTRL_FRAMELOCK_PORT1_STATUS_INPUT 0 +#define NV_CTRL_FRAMELOCK_PORT1_STATUS_OUTPUT 1 + +/* + * NV_CTRL_FRAMELOCK_HOUSE_STATUS - returns whether or not the house + * sync signal was detected on the BNC connector of the frame lock + * board. + * + * This attribute may be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_FRAMELOCK or NV_CTRL_TARGET_TYPE_X_SCREEN + * target. + */ + +#define NV_CTRL_FRAMELOCK_HOUSE_STATUS 28 /* R--F */ +#define NV_CTRL_FRAMELOCK_HOUSE_STATUS_NOT_DETECTED 0 +#define NV_CTRL_FRAMELOCK_HOUSE_STATUS_DETECTED 1 + +/* + * NV_CTRL_FRAMELOCK_SYNC - enable/disable the syncing of display + * devices to the frame lock pulse as specified by previous calls to + * NV_CTRL_FRAMELOCK_MASTER and NV_CTRL_FRAMELOCK_SLAVES. + * + * This attribute can only be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_GPU target. This attribute cannot be + * queried using a NV_CTRL_TARGET_TYPE_X_SCREEN. + */ + +#define NV_CTRL_FRAMELOCK_SYNC 29 /* RW-G */ +#define NV_CTRL_FRAMELOCK_SYNC_DISABLE 0 +#define NV_CTRL_FRAMELOCK_SYNC_ENABLE 1 + +/* + * NV_CTRL_FRAMELOCK_SYNC_READY - reports whether a frame lock + * board is receiving sync (regardless of whether or not any display + * devices are using the sync). + * + * This attribute may be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_FRAMELOCK or NV_CTRL_TARGET_TYPE_X_SCREEN + * target. + */ + +#define NV_CTRL_FRAMELOCK_SYNC_READY 30 /* R--F */ +#define NV_CTRL_FRAMELOCK_SYNC_READY_FALSE 0 +#define NV_CTRL_FRAMELOCK_SYNC_READY_TRUE 1 + +/* + * NV_CTRL_FRAMELOCK_STEREO_SYNC - this indicates that the GPU stereo + * signal is in sync with the frame lock stereo signal. + * + * This attribute may be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_GPU or NV_CTRL_TARGET_TYPE_X_SCREEN + * target. + */ + +#define NV_CTRL_FRAMELOCK_STEREO_SYNC 31 /* R--G */ +#define NV_CTRL_FRAMELOCK_STEREO_SYNC_FALSE 0 +#define NV_CTRL_FRAMELOCK_STEREO_SYNC_TRUE 1 + +/* + * NV_CTRL_FRAMELOCK_TEST_SIGNAL - to test the connections in the sync + * group, tell the master to enable a test signal, then query port[01] + * status and sync_ready on all slaves. When done, tell the master to + * disable the test signal. Test signal should only be manipulated + * while NV_CTRL_FRAMELOCK_SYNC is enabled. + * + * The TEST_SIGNAL is also used to reset the Universal Frame Count (as + * returned by the glXQueryFrameCountNV() function in the + * GLX_NV_swap_group extension). Note: for best accuracy of the + * Universal Frame Count, it is recommended to toggle the TEST_SIGNAL + * on and off after enabling frame lock. + * + * This attribute may be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_GPU or NV_CTRL_TARGET_TYPE_X_SCREEN target. + */ + +#define NV_CTRL_FRAMELOCK_TEST_SIGNAL 32 /* RW-G */ +#define NV_CTRL_FRAMELOCK_TEST_SIGNAL_DISABLE 0 +#define NV_CTRL_FRAMELOCK_TEST_SIGNAL_ENABLE 1 + +/* + * NV_CTRL_FRAMELOCK_ETHERNET_DETECTED - The frame lock boards are + * cabled together using regular cat5 cable, connecting to rj45 ports + * on the backplane of the card. There is some concern that users may + * think these are ethernet ports and connect them to a + * router/hub/etc. The hardware can detect this and will shut off to + * prevent damage (either to itself or to the router). + * NV_CTRL_FRAMELOCK_ETHERNET_DETECTED may be called to find out if + * ethernet is connected to one of the rj45 ports. An appropriate + * error message should then be displayed. The _PORT0 and _PORT1 + * values may be or'ed together. + * + * This attribute may be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_FRAMELOCK or NV_CTRL_TARGET_TYPE_X_SCREEN + * target. + */ + +#define NV_CTRL_FRAMELOCK_ETHERNET_DETECTED 33 /* R--F */ +#define NV_CTRL_FRAMELOCK_ETHERNET_DETECTED_NONE 0 +#define NV_CTRL_FRAMELOCK_ETHERNET_DETECTED_PORT0 0x1 +#define NV_CTRL_FRAMELOCK_ETHERNET_DETECTED_PORT1 0x2 + +/* + * NV_CTRL_FRAMELOCK_VIDEO_MODE - get/set what video mode is used + * to interperate the house sync signal. This should only be set + * on the master. + * + * This attribute may be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_FRAMELOCK or NV_CTRL_TARGET_TYPE_X_SCREEN + * target. + */ + +#define NV_CTRL_FRAMELOCK_VIDEO_MODE 34 /* RW-F */ +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_NONE 0 +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_TTL 1 +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_NTSCPALSECAM 2 +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_HDTV 3 + +/* + * During FRAMELOCK bring-up, the above values were redefined to + * these: + */ + +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_COMPOSITE_AUTO 0 +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_TTL 1 +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_COMPOSITE_BI_LEVEL 2 +#define NV_CTRL_FRAMELOCK_VIDEO_MODE_COMPOSITE_TRI_LEVEL 3 + +/* + * NV_CTRL_FRAMELOCK_SYNC_RATE - this is the refresh rate that the + * frame lock board is sending to the GPU, in milliHz. + * + * This attribute may be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_FRAMELOCK or NV_CTRL_TARGET_TYPE_X_SCREEN + * target. + */ + +#define NV_CTRL_FRAMELOCK_SYNC_RATE 35 /* R--F */ + +/**************************************************************************/ + +/* + * NV_CTRL_FORCE_GENERIC_CPU - inhibit the use of CPU specific + * features such as MMX, SSE, or 3DNOW! for OpenGL clients; this + * option may result in performance loss, but may be useful in + * conjunction with software such as the Valgrind memory debugger. + * This setting is only applied to OpenGL clients that are started + * after this setting is applied. + * + * USAGE NOTE: This attribute is deprecated. CPU compatibility is now + * checked each time during initialization. + */ + +#define NV_CTRL_FORCE_GENERIC_CPU 37 /* RW-X */ +#define NV_CTRL_FORCE_GENERIC_CPU_DISABLE 0 +#define NV_CTRL_FORCE_GENERIC_CPU_ENABLE 1 + +/* + * NV_CTRL_OPENGL_AA_LINE_GAMMA - for OpenGL clients, allow + * Gamma-corrected antialiased lines to consider variances in the + * color display capabilities of output devices when rendering smooth + * lines. Only available on recent Quadro GPUs. This setting is only + * applied to OpenGL clients that are started after this setting is + * applied. + */ + +#define NV_CTRL_OPENGL_AA_LINE_GAMMA 38 /* RW-X */ +#define NV_CTRL_OPENGL_AA_LINE_GAMMA_DISABLE 0 +#define NV_CTRL_OPENGL_AA_LINE_GAMMA_ENABLE 1 + +/* + * NV_CTRL_FRAMELOCK_TIMING - this is TRUE when the gpu is both receiving + * and locked to an input timing signal. Timing information may come from + * the following places: Another frame lock device that is set to master, + * the house sync signal, or the GPU's internal timing from a display + * device. + * + * This attribute may be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_GPU or NV_CTRL_TARGET_TYPE_X_SCREEN target. + */ + +#define NV_CTRL_FRAMELOCK_TIMING 39 /* R--G */ +#define NV_CTRL_FRAMELOCK_TIMING_FALSE 0 +#define NV_CTRL_FRAMELOCK_TIMING_TRUE 1 + +/* + * NV_CTRL_FLIPPING_ALLOWED - when TRUE, OpenGL will swap by flipping + * when possible; when FALSE, OpenGL will alway swap by blitting. + */ + +#define NV_CTRL_FLIPPING_ALLOWED 40 /* RW-X */ +#define NV_CTRL_FLIPPING_ALLOWED_FALSE 0 +#define NV_CTRL_FLIPPING_ALLOWED_TRUE 1 + +/* + * NV_CTRL_ARCHITECTURE - returns the architecture on which the X server is + * running. + */ + +#define NV_CTRL_ARCHITECTURE 41 /* R-- */ +#define NV_CTRL_ARCHITECTURE_X86 0 +#define NV_CTRL_ARCHITECTURE_X86_64 1 +#define NV_CTRL_ARCHITECTURE_IA64 2 + +/* + * NV_CTRL_TEXTURE_CLAMPING - texture clamping mode in OpenGL. By + * default, _SPEC is used, which forces OpenGL texture clamping to + * conform with the OpenGL specification. _EDGE forces NVIDIA's + * OpenGL implementation to remap GL_CLAMP to GL_CLAMP_TO_EDGE, + * which is not strictly conformant, but some applications rely on + * the non-conformant behavior. + */ + +#define NV_CTRL_TEXTURE_CLAMPING 42 /* RW-X */ +#define NV_CTRL_TEXTURE_CLAMPING_EDGE 0 +#define NV_CTRL_TEXTURE_CLAMPING_SPEC 1 + +#define NV_CTRL_CURSOR_SHADOW 43 /* RW- */ +#define NV_CTRL_CURSOR_SHADOW_DISABLE 0 +#define NV_CTRL_CURSOR_SHADOW_ENABLE 1 + +#define NV_CTRL_CURSOR_SHADOW_ALPHA 44 /* RW- */ +#define NV_CTRL_CURSOR_SHADOW_RED 45 /* RW- */ +#define NV_CTRL_CURSOR_SHADOW_GREEN 46 /* RW- */ +#define NV_CTRL_CURSOR_SHADOW_BLUE 47 /* RW- */ + +#define NV_CTRL_CURSOR_SHADOW_X_OFFSET 48 /* RW- */ +#define NV_CTRL_CURSOR_SHADOW_Y_OFFSET 49 /* RW- */ + +/* + * When Application Control for FSAA is enabled, then what the + * application requests is used, and NV_CTRL_FSAA_MODE is ignored. If + * this is disabled, then any application setting is overridden with + * NV_CTRL_FSAA_MODE + */ + +#define NV_CTRL_FSAA_APPLICATION_CONTROLLED 50 /* RW-X */ +#define NV_CTRL_FSAA_APPLICATION_CONTROLLED_ENABLED 1 +#define NV_CTRL_FSAA_APPLICATION_CONTROLLED_DISABLED 0 + +/* + * When Application Control for LogAniso is enabled, then what the + * application requests is used, and NV_CTRL_LOG_ANISO is ignored. If + * this is disabled, then any application setting is overridden with + * NV_CTRL_LOG_ANISO + */ + +#define NV_CTRL_LOG_ANISO_APPLICATION_CONTROLLED 51 /* RW-X */ +#define NV_CTRL_LOG_ANISO_APPLICATION_CONTROLLED_ENABLED 1 +#define NV_CTRL_LOG_ANISO_APPLICATION_CONTROLLED_DISABLED 0 + +/* + * IMAGE_SHARPENING adjusts the sharpness of the display's image + * quality by amplifying high frequency content. Valid values will + * normally be in the range [0,32). Only available on GeForceFX or + * newer. + */ + +#define NV_CTRL_IMAGE_SHARPENING 52 /* RWDG */ + +/* + * NV_CTRL_TV_OVERSCAN adjusts the amount of overscan on the specified + * display device. + */ + +#define NV_CTRL_TV_OVERSCAN 53 /* RWDG */ + +/* + * NV_CTRL_TV_FLICKER_FILTER adjusts the amount of flicker filter on + * the specified display device. + */ + +#define NV_CTRL_TV_FLICKER_FILTER 54 /* RWDG */ + +/* + * NV_CTRL_TV_BRIGHTNESS adjusts the amount of brightness on the + * specified display device. + */ + +#define NV_CTRL_TV_BRIGHTNESS 55 /* RWDG */ + +/* + * NV_CTRL_TV_HUE adjusts the amount of hue on the specified display + * device. + */ + +#define NV_CTRL_TV_HUE 56 /* RWDG */ + +/* + * NV_CTRL_TV_CONTRAST adjusts the amount of contrast on the specified + * display device. + */ + +#define NV_CTRL_TV_CONTRAST 57 /* RWDG */ + +/* + * NV_CTRL_TV_SATURATION adjusts the amount of saturation on the + * specified display device. + */ + +#define NV_CTRL_TV_SATURATION 58 /* RWDG */ + +/* + * NV_CTRL_TV_RESET_SETTINGS - this write-only attribute can be used + * to request that all TV Settings be reset to their default values; + * typical usage would be that this attribute be sent, and then all + * the TV attributes be queried to retrieve their new values. + */ + +#define NV_CTRL_TV_RESET_SETTINGS 59 /* -WDG */ + +/* + * NV_CTRL_GPU_CORE_TEMPERATURE reports the current core temperature + * of the GPU driving the X screen. + */ + +#define NV_CTRL_GPU_CORE_TEMPERATURE 60 /* R--G */ + +/* + * NV_CTRL_GPU_CORE_THRESHOLD reports the current GPU core slowdown + * threshold temperature, NV_CTRL_GPU_DEFAULT_CORE_THRESHOLD and + * NV_CTRL_GPU_MAX_CORE_THRESHOLD report the default and MAX core + * slowdown threshold temperatures. + * + * NV_CTRL_GPU_CORE_THRESHOLD reflects the temperature at which the + * GPU is throttled to prevent overheating. + */ + +#define NV_CTRL_GPU_CORE_THRESHOLD 61 /* R--G */ +#define NV_CTRL_GPU_DEFAULT_CORE_THRESHOLD 62 /* R--G */ +#define NV_CTRL_GPU_MAX_CORE_THRESHOLD 63 /* R--G */ + +/* + * NV_CTRL_AMBIENT_TEMPERATURE reports the current temperature in the + * immediate neighbourhood of the GPU driving the X screen. + */ + +#define NV_CTRL_AMBIENT_TEMPERATURE 64 /* R--G */ + +/* + * NV_CTRL_PBUFFER_SCANOUT_SUPPORTED - returns whether this X screen + * supports scanout of FP pbuffers; + * + * if this screen does not support PBUFFER_SCANOUT, then all other + * PBUFFER_SCANOUT attributes are unavailable. + * + * PBUFFER_SCANOUT is supported if and only if: + * - Twinview is configured with clone mode. The secondary screen is used to + * scanout the pbuffer. + * - The desktop is running in with 16 bits per pixel. + */ +#define NV_CTRL_PBUFFER_SCANOUT_SUPPORTED 65 /* R-- */ +#define NV_CTRL_PBUFFER_SCANOUT_FALSE 0 +#define NV_CTRL_PBUFFER_SCANOUT_TRUE 1 + +/* + * NV_CTRL_PBUFFER_SCANOUT_XID indicates the XID of the pbuffer used for + * scanout. + */ +#define NV_CTRL_PBUFFER_SCANOUT_XID 66 /* RW- */ + +/**************************************************************************/ +/* + * The NV_CTRL_GVO_* integer attributes are used to configure GVO + * (Graphics to Video Out). This functionality is available, for + * example, on the Quadro FX 4000 SDI graphics board. + * + * The following is a typical usage pattern for the GVO attributes: + * + * - query NV_CTRL_GVO_SUPPORTED to determine if the X screen supports GV0. + * + * - specify NV_CTRL_GVO_SYNC_MODE (one of FREE_RUNNING, GENLOCK, or + * FRAMELOCK); if you specify GENLOCK or FRAMELOCK, you should also + * specify NV_CTRL_GVO_SYNC_SOURCE. + * + * - Use NV_CTRL_GVO_COMPOSITE_SYNC_INPUT_DETECTED and + * NV_CTRL_GVO_SDI_SYNC_INPUT_DETECTED to detect what input syncs are + * present. + * + * (If no analog sync is detected but it is known that a valid + * bi-level or tri-level sync is connected set + * NV_CTRL_GVO_COMPOSITE_SYNC_INPUT_DETECT_MODE appropriately and + * retest with NV_CTRL_GVO_COMPOSITE_SYNC_INPUT_DETECTED). + * + * - if syncing to input sync, query the + * NV_CTRL_GVIO_DETECTED_VIDEO_FORMAT attribute; note that Input video + * format can only be queried after SYNC_SOURCE is specified. + * + * - specify the NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT + * + * - specify the NV_CTRL_GVO_DATA_FORMAT + * + * - specify any custom Color Space Conversion (CSC) matrix, offset, + * and scale with XNVCTRLSetGvoColorConversion(). + * + * - if using the GLX_NV_video_out extension to display one or more + * pbuffers, call glXGetVideoDeviceNV() to lock the GVO output for use + * by the GLX client; then bind the pbuffer(s) to the GVO output with + * glXBindVideoImageNV() and send pbuffers to the GVO output with + * glXSendPbufferToVideoNV(); see the GLX_NV_video_out spec for more + * details. + * + * - if using the GLX_NV_present_video extension, call + * glXBindVideoDeviceNV() to bind the GVO video device to current + * OpenGL context. + * + * Note that setting most GVO attributes only causes the value to be + * cached in the X server. The values will be flushed to the hardware + * either when the next MetaMode is set that uses the GVO display + * device, or when a GLX pbuffer is bound to the GVO output (with + * glXBindVideoImageNV()). + * + * Note that GLX_NV_video_out/GLX_NV_present_video and X screen use + * are mutually exclusive. If a MetaMode is currently using the GVO + * device, then glXGetVideoDeviceNV and glXBindVideoImageNV() will + * fail. Similarly, if a GLX client has locked the GVO output (via + * glXGetVideoDeviceNV or glXBindVideoImageNV), then setting a + * MetaMode that uses the GVO device will fail. The + * NV_CTRL_GVO_GLX_LOCKED event will be sent when a GLX client locks + * the GVO output. + * + */ + +/* + * NV_CTRL_GVO_SUPPORTED - returns whether this X screen supports GVO; + * if this screen does not support GVO output, then all other GVO + * attributes are unavailable. + */ + +#define NV_CTRL_GVO_SUPPORTED 67 /* R-- */ +#define NV_CTRL_GVO_SUPPORTED_FALSE 0 +#define NV_CTRL_GVO_SUPPORTED_TRUE 1 + +/* + * NV_CTRL_GVO_SYNC_MODE - selects the GVO sync mode; possible values + * are: + * + * FREE_RUNNING - GVO does not sync to any external signal + * + * GENLOCK - the GVO output is genlocked to an incoming sync signal; + * genlocking locks at hsync. This requires that the output video + * format exactly match the incoming sync video format. + * + * FRAMELOCK - the GVO output is frame locked to an incoming sync + * signal; frame locking locks at vsync. This requires that the output + * video format have the same refresh rate as the incoming sync video + * format. + */ + +#define NV_CTRL_GVO_SYNC_MODE 68 /* RW- */ +#define NV_CTRL_GVO_SYNC_MODE_FREE_RUNNING 0 +#define NV_CTRL_GVO_SYNC_MODE_GENLOCK 1 +#define NV_CTRL_GVO_SYNC_MODE_FRAMELOCK 2 + +/* + * NV_CTRL_GVO_SYNC_SOURCE - if NV_CTRL_GVO_SYNC_MODE is set to either + * GENLOCK or FRAMELOCK, this controls which sync source is used as + * the incoming sync signal (either Composite or SDI). If + * NV_CTRL_GVO_SYNC_MODE is FREE_RUNNING, this attribute has no + * effect. + */ + +#define NV_CTRL_GVO_SYNC_SOURCE 69 /* RW- */ +#define NV_CTRL_GVO_SYNC_SOURCE_COMPOSITE 0 +#define NV_CTRL_GVO_SYNC_SOURCE_SDI 1 + +/* + * NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT - specifies the desired output video + * format for GVO devices or the desired input video format for GVI devices. + * + * Note that for GVO, the valid video formats may vary depending on + * the NV_CTRL_GVO_SYNC_MODE and the incoming sync video format. See + * the definition of NV_CTRL_GVO_SYNC_MODE. + * + * Note that when querying the ValidValues for this data type, the + * values are reported as bits within a bitmask + * (ATTRIBUTE_TYPE_INT_BITS); unfortunately, there are more valid + * value bits than will fit in a single 32-bit value. To solve this, + * query the ValidValues for NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT to + * check which of the first 31 VIDEO_FORMATS are valid, query the + * ValidValues for NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT2 to check which + * of the 32-63 VIDEO_FORMATS are valid, and query the ValidValues of + * NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT3 to check which of the 64-95 + * VIDEO_FORMATS are valid. + * + * Note: Setting this attribute on a GVI device may also result in the + * following NV-CONTROL attributes being reset on that device (to + * ensure the configuration remains valid): + * NV_CTRL_GVI_REQUESTED_STREAM_BITS_PER_COMPONENT + * NV_CTRL_GVI_REQUESTED_STREAM_COMPONENT_SAMPLING + */ + +#define NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT 70 /* RW--I */ + +#define NV_CTRL_GVIO_VIDEO_FORMAT_NONE 0 +#define NV_CTRL_GVIO_VIDEO_FORMAT_487I_59_94_SMPTE259_NTSC 1 +#define NV_CTRL_GVIO_VIDEO_FORMAT_576I_50_00_SMPTE259_PAL 2 +#define NV_CTRL_GVIO_VIDEO_FORMAT_720P_59_94_SMPTE296 3 +#define NV_CTRL_GVIO_VIDEO_FORMAT_720P_60_00_SMPTE296 4 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1035I_59_94_SMPTE260 5 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1035I_60_00_SMPTE260 6 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080I_50_00_SMPTE295 7 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080I_50_00_SMPTE274 8 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080I_59_94_SMPTE274 9 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080I_60_00_SMPTE274 10 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080P_23_976_SMPTE274 11 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080P_24_00_SMPTE274 12 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080P_25_00_SMPTE274 13 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080P_29_97_SMPTE274 14 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080P_30_00_SMPTE274 15 +#define NV_CTRL_GVIO_VIDEO_FORMAT_720P_50_00_SMPTE296 16 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080I_48_00_SMPTE274 17 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080I_47_96_SMPTE274 18 +#define NV_CTRL_GVIO_VIDEO_FORMAT_720P_30_00_SMPTE296 19 +#define NV_CTRL_GVIO_VIDEO_FORMAT_720P_29_97_SMPTE296 20 +#define NV_CTRL_GVIO_VIDEO_FORMAT_720P_25_00_SMPTE296 21 +#define NV_CTRL_GVIO_VIDEO_FORMAT_720P_24_00_SMPTE296 22 +#define NV_CTRL_GVIO_VIDEO_FORMAT_720P_23_98_SMPTE296 23 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080PSF_25_00_SMPTE274 24 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080PSF_29_97_SMPTE274 25 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080PSF_30_00_SMPTE274 26 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080PSF_24_00_SMPTE274 27 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080PSF_23_98_SMPTE274 28 +#define NV_CTRL_GVIO_VIDEO_FORMAT_2048P_30_00_SMPTE372 29 +#define NV_CTRL_GVIO_VIDEO_FORMAT_2048P_29_97_SMPTE372 30 +#define NV_CTRL_GVIO_VIDEO_FORMAT_2048I_60_00_SMPTE372 31 +#define NV_CTRL_GVIO_VIDEO_FORMAT_2048I_59_94_SMPTE372 32 +#define NV_CTRL_GVIO_VIDEO_FORMAT_2048P_25_00_SMPTE372 33 +#define NV_CTRL_GVIO_VIDEO_FORMAT_2048I_50_00_SMPTE372 34 +#define NV_CTRL_GVIO_VIDEO_FORMAT_2048P_24_00_SMPTE372 35 +#define NV_CTRL_GVIO_VIDEO_FORMAT_2048P_23_98_SMPTE372 36 +#define NV_CTRL_GVIO_VIDEO_FORMAT_2048I_48_00_SMPTE372 37 +#define NV_CTRL_GVIO_VIDEO_FORMAT_2048I_47_96_SMPTE372 38 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080P_50_00_3G_LEVEL_A_SMPTE274 39 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080P_59_94_3G_LEVEL_A_SMPTE274 40 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080P_60_00_3G_LEVEL_A_SMPTE274 41 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080P_60_00_3G_LEVEL_B_SMPTE274 42 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080I_60_00_3G_LEVEL_B_SMPTE274 43 +#define NV_CTRL_GVIO_VIDEO_FORMAT_2048I_60_00_3G_LEVEL_B_SMPTE372 44 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080P_50_00_3G_LEVEL_B_SMPTE274 45 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080I_50_00_3G_LEVEL_B_SMPTE274 46 +#define NV_CTRL_GVIO_VIDEO_FORMAT_2048I_50_00_3G_LEVEL_B_SMPTE372 47 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080P_30_00_3G_LEVEL_B_SMPTE274 48 +#define NV_CTRL_GVIO_VIDEO_FORMAT_2048P_30_00_3G_LEVEL_B_SMPTE372 49 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080P_25_00_3G_LEVEL_B_SMPTE274 50 +#define NV_CTRL_GVIO_VIDEO_FORMAT_2048P_25_00_3G_LEVEL_B_SMPTE372 51 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080P_24_00_3G_LEVEL_B_SMPTE274 52 +#define NV_CTRL_GVIO_VIDEO_FORMAT_2048P_24_00_3G_LEVEL_B_SMPTE372 53 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080I_48_00_3G_LEVEL_B_SMPTE274 54 +#define NV_CTRL_GVIO_VIDEO_FORMAT_2048I_48_00_3G_LEVEL_B_SMPTE372 55 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080P_59_94_3G_LEVEL_B_SMPTE274 56 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080I_59_94_3G_LEVEL_B_SMPTE274 57 +#define NV_CTRL_GVIO_VIDEO_FORMAT_2048I_59_94_3G_LEVEL_B_SMPTE372 58 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080P_29_97_3G_LEVEL_B_SMPTE274 59 +#define NV_CTRL_GVIO_VIDEO_FORMAT_2048P_29_97_3G_LEVEL_B_SMPTE372 60 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080P_23_98_3G_LEVEL_B_SMPTE274 61 +#define NV_CTRL_GVIO_VIDEO_FORMAT_2048P_23_98_3G_LEVEL_B_SMPTE372 62 +#define NV_CTRL_GVIO_VIDEO_FORMAT_1080I_47_96_3G_LEVEL_B_SMPTE274 63 +#define NV_CTRL_GVIO_VIDEO_FORMAT_2048I_47_96_3G_LEVEL_B_SMPTE372 64 + +/* + * The following are deprecated; NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT and the + * corresponding NV_CTRL_GVIO_* formats should be used instead. + */ +#define NV_CTRL_GVO_OUTPUT_VIDEO_FORMAT 70 /* RW- */ + +#define NV_CTRL_GVO_VIDEO_FORMAT_NONE 0 +#define NV_CTRL_GVO_VIDEO_FORMAT_487I_59_94_SMPTE259_NTSC 1 +#define NV_CTRL_GVO_VIDEO_FORMAT_576I_50_00_SMPTE259_PAL 2 +#define NV_CTRL_GVO_VIDEO_FORMAT_720P_59_94_SMPTE296 3 +#define NV_CTRL_GVO_VIDEO_FORMAT_720P_60_00_SMPTE296 4 +#define NV_CTRL_GVO_VIDEO_FORMAT_1035I_59_94_SMPTE260 5 +#define NV_CTRL_GVO_VIDEO_FORMAT_1035I_60_00_SMPTE260 6 +#define NV_CTRL_GVO_VIDEO_FORMAT_1080I_50_00_SMPTE295 7 +#define NV_CTRL_GVO_VIDEO_FORMAT_1080I_50_00_SMPTE274 8 +#define NV_CTRL_GVO_VIDEO_FORMAT_1080I_59_94_SMPTE274 9 +#define NV_CTRL_GVO_VIDEO_FORMAT_1080I_60_00_SMPTE274 10 +#define NV_CTRL_GVO_VIDEO_FORMAT_1080P_23_976_SMPTE274 11 +#define NV_CTRL_GVO_VIDEO_FORMAT_1080P_24_00_SMPTE274 12 +#define NV_CTRL_GVO_VIDEO_FORMAT_1080P_25_00_SMPTE274 13 +#define NV_CTRL_GVO_VIDEO_FORMAT_1080P_29_97_SMPTE274 14 +#define NV_CTRL_GVO_VIDEO_FORMAT_1080P_30_00_SMPTE274 15 +#define NV_CTRL_GVO_VIDEO_FORMAT_720P_50_00_SMPTE296 16 +#define NV_CTRL_GVO_VIDEO_FORMAT_1080I_48_00_SMPTE274 17 +#define NV_CTRL_GVO_VIDEO_FORMAT_1080I_47_96_SMPTE274 18 +#define NV_CTRL_GVO_VIDEO_FORMAT_720P_30_00_SMPTE296 19 +#define NV_CTRL_GVO_VIDEO_FORMAT_720P_29_97_SMPTE296 20 +#define NV_CTRL_GVO_VIDEO_FORMAT_720P_25_00_SMPTE296 21 +#define NV_CTRL_GVO_VIDEO_FORMAT_720P_24_00_SMPTE296 22 +#define NV_CTRL_GVO_VIDEO_FORMAT_720P_23_98_SMPTE296 23 +#define NV_CTRL_GVO_VIDEO_FORMAT_1080PSF_25_00_SMPTE274 24 +#define NV_CTRL_GVO_VIDEO_FORMAT_1080PSF_29_97_SMPTE274 25 +#define NV_CTRL_GVO_VIDEO_FORMAT_1080PSF_30_00_SMPTE274 26 +#define NV_CTRL_GVO_VIDEO_FORMAT_1080PSF_24_00_SMPTE274 27 +#define NV_CTRL_GVO_VIDEO_FORMAT_1080PSF_23_98_SMPTE274 28 +#define NV_CTRL_GVO_VIDEO_FORMAT_2048P_30_00_SMPTE372 29 +#define NV_CTRL_GVO_VIDEO_FORMAT_2048P_29_97_SMPTE372 30 +#define NV_CTRL_GVO_VIDEO_FORMAT_2048I_60_00_SMPTE372 31 +#define NV_CTRL_GVO_VIDEO_FORMAT_2048I_59_94_SMPTE372 32 +#define NV_CTRL_GVO_VIDEO_FORMAT_2048P_25_00_SMPTE372 33 +#define NV_CTRL_GVO_VIDEO_FORMAT_2048I_50_00_SMPTE372 34 +#define NV_CTRL_GVO_VIDEO_FORMAT_2048P_24_00_SMPTE372 35 +#define NV_CTRL_GVO_VIDEO_FORMAT_2048P_23_98_SMPTE372 36 +#define NV_CTRL_GVO_VIDEO_FORMAT_2048I_48_00_SMPTE372 37 +#define NV_CTRL_GVO_VIDEO_FORMAT_2048I_47_96_SMPTE372 38 + +/* + * NV_CTRL_GVIO_DETECTED_VIDEO_FORMAT - indicates the input video format + * detected for GVO or GVI devices; the possible values are the + * NV_CTRL_GVIO_VIDEO_FORMAT constants. + * + * For GVI devices, the jack number should be specified in the lower + * 16 bits of the "display_mask" parameter, while the channel number should be + * specified in the upper 16 bits. + */ + +#define NV_CTRL_GVIO_DETECTED_VIDEO_FORMAT 71 /* R--I */ + +/* + * The following is deprecated. Use NV_CTRL_GVIO_DETECTED_VIDEO_FORMAT, + * instead. + */ +#define NV_CTRL_GVO_INPUT_VIDEO_FORMAT 71 /* R-- */ + +/* + * NV_CTRL_GVO_DATA_FORMAT - This controls how the data in the source + * (either the X screen or the GLX pbuffer) is interpretted and + * displayed. + * + * Note: some of the below DATA_FORMATS have been renamed. For + * example, R8G8B8_TO_RGB444 has been renamed to X8X8X8_444_PASSTHRU. + * This is to more accurately reflect DATA_FORMATS where the + * per-channel data could be either RGB or YCrCb -- the point is that + * the driver and GVO hardware do not perform any implicit color space + * conversion on the data; it is passed through to the SDI out. + */ + +#define NV_CTRL_GVO_DATA_FORMAT 72 /* RW- */ +#define NV_CTRL_GVO_DATA_FORMAT_R8G8B8_TO_YCRCB444 0 +#define NV_CTRL_GVO_DATA_FORMAT_R8G8B8A8_TO_YCRCBA4444 1 +#define NV_CTRL_GVO_DATA_FORMAT_R8G8B8Z10_TO_YCRCBZ4444 2 +#define NV_CTRL_GVO_DATA_FORMAT_R8G8B8_TO_YCRCB422 3 +#define NV_CTRL_GVO_DATA_FORMAT_R8G8B8A8_TO_YCRCBA4224 4 +#define NV_CTRL_GVO_DATA_FORMAT_R8G8B8Z10_TO_YCRCBZ4224 5 +#define NV_CTRL_GVO_DATA_FORMAT_R8G8B8_TO_RGB444 6 // renamed +#define NV_CTRL_GVO_DATA_FORMAT_X8X8X8_444_PASSTHRU 6 +#define NV_CTRL_GVO_DATA_FORMAT_R8G8B8A8_TO_RGBA4444 7 // renamed +#define NV_CTRL_GVO_DATA_FORMAT_X8X8X8A8_4444_PASSTHRU 7 +#define NV_CTRL_GVO_DATA_FORMAT_R8G8B8Z10_TO_RGBZ4444 8 // renamed +#define NV_CTRL_GVO_DATA_FORMAT_X8X8X8Z8_4444_PASSTHRU 8 +#define NV_CTRL_GVO_DATA_FORMAT_Y10CR10CB10_TO_YCRCB444 9 // renamed +#define NV_CTRL_GVO_DATA_FORMAT_X10X10X10_444_PASSTHRU 9 +#define NV_CTRL_GVO_DATA_FORMAT_Y10CR8CB8_TO_YCRCB444 10 // renamed +#define NV_CTRL_GVO_DATA_FORMAT_X10X8X8_444_PASSTHRU 10 +#define NV_CTRL_GVO_DATA_FORMAT_Y10CR8CB8A10_TO_YCRCBA4444 11 // renamed +#define NV_CTRL_GVO_DATA_FORMAT_X10X8X8A10_4444_PASSTHRU 11 +#define NV_CTRL_GVO_DATA_FORMAT_Y10CR8CB8Z10_TO_YCRCBZ4444 12 // renamed +#define NV_CTRL_GVO_DATA_FORMAT_X10X8X8Z10_4444_PASSTHRU 12 +#define NV_CTRL_GVO_DATA_FORMAT_DUAL_R8G8B8_TO_DUAL_YCRCB422 13 +#define NV_CTRL_GVO_DATA_FORMAT_DUAL_Y8CR8CB8_TO_DUAL_YCRCB422 14 // renamed +#define NV_CTRL_GVO_DATA_FORMAT_DUAL_X8X8X8_TO_DUAL_422_PASSTHRU 14 +#define NV_CTRL_GVO_DATA_FORMAT_R10G10B10_TO_YCRCB422 15 +#define NV_CTRL_GVO_DATA_FORMAT_R10G10B10_TO_YCRCB444 16 +#define NV_CTRL_GVO_DATA_FORMAT_Y12CR12CB12_TO_YCRCB444 17 // renamed +#define NV_CTRL_GVO_DATA_FORMAT_X12X12X12_444_PASSTHRU 17 +#define NV_CTRL_GVO_DATA_FORMAT_R12G12B12_TO_YCRCB444 18 +#define NV_CTRL_GVO_DATA_FORMAT_X8X8X8_422_PASSTHRU 19 +#define NV_CTRL_GVO_DATA_FORMAT_X8X8X8A8_4224_PASSTHRU 20 +#define NV_CTRL_GVO_DATA_FORMAT_X8X8X8Z8_4224_PASSTHRU 21 +#define NV_CTRL_GVO_DATA_FORMAT_X10X10X10_422_PASSTHRU 22 +#define NV_CTRL_GVO_DATA_FORMAT_X10X8X8_422_PASSTHRU 23 +#define NV_CTRL_GVO_DATA_FORMAT_X10X8X8A10_4224_PASSTHRU 24 +#define NV_CTRL_GVO_DATA_FORMAT_X10X8X8Z10_4224_PASSTHRU 25 +#define NV_CTRL_GVO_DATA_FORMAT_X12X12X12_422_PASSTHRU 26 +#define NV_CTRL_GVO_DATA_FORMAT_R12G12B12_TO_YCRCB422 27 + +/* + * NV_CTRL_GVO_DISPLAY_X_SCREEN - no longer supported + */ + +#define NV_CTRL_GVO_DISPLAY_X_SCREEN 73 /* RW- */ +#define NV_CTRL_GVO_DISPLAY_X_SCREEN_ENABLE 1 +#define NV_CTRL_GVO_DISPLAY_X_SCREEN_DISABLE 0 + +/* + * NV_CTRL_GVO_COMPOSITE_SYNC_INPUT_DETECTED - indicates whether + * Composite Sync input is detected. + */ + +#define NV_CTRL_GVO_COMPOSITE_SYNC_INPUT_DETECTED 74 /* R-- */ +#define NV_CTRL_GVO_COMPOSITE_SYNC_INPUT_DETECTED_FALSE 0 +#define NV_CTRL_GVO_COMPOSITE_SYNC_INPUT_DETECTED_TRUE 1 + +/* + * NV_CTRL_GVO_COMPOSITE_SYNC_INPUT_DETECT_MODE - get/set the + * Composite Sync input detect mode. + */ + +#define NV_CTRL_GVO_COMPOSITE_SYNC_INPUT_DETECT_MODE 75 /* RW- */ +#define NV_CTRL_GVO_COMPOSITE_SYNC_INPUT_DETECT_MODE_AUTO 0 +#define NV_CTRL_GVO_COMPOSITE_SYNC_INPUT_DETECT_MODE_BI_LEVEL 1 +#define NV_CTRL_GVO_COMPOSITE_SYNC_INPUT_DETECT_MODE_TRI_LEVEL 2 + +/* + * NV_CTRL_GVO_SYNC_INPUT_DETECTED - indicates whether SDI Sync input + * is detected, and what type. + */ + +#define NV_CTRL_GVO_SDI_SYNC_INPUT_DETECTED 76 /* R-- */ +#define NV_CTRL_GVO_SDI_SYNC_INPUT_DETECTED_NONE 0 +#define NV_CTRL_GVO_SDI_SYNC_INPUT_DETECTED_HD 1 +#define NV_CTRL_GVO_SDI_SYNC_INPUT_DETECTED_SD 2 + +/* + * NV_CTRL_GVO_VIDEO_OUTPUTS - indicates which GVO video output + * connectors are currently outputing data. + */ + +#define NV_CTRL_GVO_VIDEO_OUTPUTS 77 /* R-- */ +#define NV_CTRL_GVO_VIDEO_OUTPUTS_NONE 0 +#define NV_CTRL_GVO_VIDEO_OUTPUTS_VIDEO1 1 +#define NV_CTRL_GVO_VIDEO_OUTPUTS_VIDEO2 2 +#define NV_CTRL_GVO_VIDEO_OUTPUTS_VIDEO_BOTH 3 + +/* + * NV_CTRL_GVO_FPGA_VERSION - indicates the version of the Firmware on + * the GVO device. Deprecated; use + * NV_CTRL_STRING_GVIO_FIRMWARE_VERSION instead. + */ + +#define NV_CTRL_GVO_FIRMWARE_VERSION 78 /* R-- */ + +/* + * NV_CTRL_GVO_SYNC_DELAY_PIXELS - controls the delay between the + * input sync and the output sync in numbers of pixels from hsync; + * this is a 12 bit value. + * + * If the NV_CTRL_GVO_CAPABILITIES_ADVANCE_SYNC_SKEW bit is set, + * then setting this value will set an advance instead of a delay. + */ + +#define NV_CTRL_GVO_SYNC_DELAY_PIXELS 79 /* RW- */ + +/* + * NV_CTRL_GVO_SYNC_DELAY_LINES - controls the delay between the input + * sync and the output sync in numbers of lines from vsync; this is a + * 12 bit value. + * + * If the NV_CTRL_GVO_CAPABILITIES_ADVANCE_SYNC_SKEW bit is set, + * then setting this value will set an advance instead of a delay. + */ + +#define NV_CTRL_GVO_SYNC_DELAY_LINES 80 /* RW- */ + +/* + * NV_CTRL_GVO_INPUT_VIDEO_FORMAT_REACQUIRE - must be set for a period + * of about 2 seconds for the new InputVideoFormat to be properly + * locked to. In nvidia-settings, we do a reacquire whenever genlock + * or frame lock mode is entered into, when the user clicks the + * "detect" button. This value can be written, but always reads back + * _FALSE. + */ + +#define NV_CTRL_GVO_INPUT_VIDEO_FORMAT_REACQUIRE 81 /* -W- */ +#define NV_CTRL_GVO_INPUT_VIDEO_FORMAT_REACQUIRE_FALSE 0 +#define NV_CTRL_GVO_INPUT_VIDEO_FORMAT_REACQUIRE_TRUE 1 + +/* + * NV_CTRL_GVO_GLX_LOCKED - indicates that GVO configurability is + * locked by GLX; this occurs when either glXGetVideoDeviceNV (part of + * GLX_NV_video_out) or glXBindVideoDeviceNV (part of + * GLX_NV_present_video) is called. All GVO output resources are + * locked until released by the GLX_NV_video_out/GLX_NV_present_video + * client. + * + * When GVO is locked, setting of the following GVO NV-CONTROL attributes will + * not happen immediately and will instead be cached. The GVO resource will + * need to be disabled/released and re-enabled/claimed for the values to be + * flushed. These attributes are: + * NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT + * NV_CTRL_GVO_DATA_FORMAT + * NV_CTRL_GVO_FLIP_QUEUE_SIZE + * + * This attribute is deprecated and may be removed in a future release. Its + * functionality has been replaced by NV_CTRL_GVO_LOCK_OWNER. + */ + +#define NV_CTRL_GVO_GLX_LOCKED 82 /* R-- */ +#define NV_CTRL_GVO_GLX_LOCKED_FALSE 0 +#define NV_CTRL_GVO_GLX_LOCKED_TRUE 1 + +/* + * NV_CTRL_GVIO_VIDEO_FORMAT_{WIDTH,HEIGHT,REFRESH_RATE} - query the + * width, height, and refresh rate for the specified + * NV_CTRL_GVIO_VIDEO_FORMAT_*. So that this can be queried with + * existing interfaces, XNVCTRLQueryAttribute() should be used, and + * the video format specified in the display_mask field; eg: + * + * XNVCTRLQueryAttribute (dpy, + * screen, + * NV_CTRL_GVIO_VIDEO_FORMAT_487I_59_94_SMPTE259_NTSC, + * NV_CTRL_GVIO_VIDEO_FORMAT_WIDTH, + * &value); + * + * Note that Refresh Rate is in milliHertz values + */ + +#define NV_CTRL_GVIO_VIDEO_FORMAT_WIDTH 83 /* R--I */ +#define NV_CTRL_GVIO_VIDEO_FORMAT_HEIGHT 84 /* R--I */ +#define NV_CTRL_GVIO_VIDEO_FORMAT_REFRESH_RATE 85 /* R--I */ + +/* The following are deprecated; use the NV_CTRL_GVIO_* versions, instead */ +#define NV_CTRL_GVO_VIDEO_FORMAT_WIDTH 83 /* R-- */ +#define NV_CTRL_GVO_VIDEO_FORMAT_HEIGHT 84 /* R-- */ +#define NV_CTRL_GVO_VIDEO_FORMAT_REFRESH_RATE 85 /* R-- */ + +/* + * NV_CTRL_GVO_X_SCREEN_PAN_[XY] - no longer supported + */ + +#define NV_CTRL_GVO_X_SCREEN_PAN_X 86 /* RW- */ +#define NV_CTRL_GVO_X_SCREEN_PAN_Y 87 /* RW- */ + +/* + * NV_CTRL_GPU_OVERCLOCKING_STATE - query the current or set a new + * overclocking state; the value of this attribute controls the + * availability of additional overclocking attributes (see below). + * + * Note: this attribute is unavailable unless overclocking support + * has been enabled in the X server (by the user). + */ + +#define NV_CTRL_GPU_OVERCLOCKING_STATE 88 /* RW-G */ +#define NV_CTRL_GPU_OVERCLOCKING_STATE_NONE 0 +#define NV_CTRL_GPU_OVERCLOCKING_STATE_MANUAL 1 + +/* + * NV_CTRL_GPU_{2,3}D_CLOCK_FREQS - query or set the GPU and memory + * clocks of the device driving the X screen. New clock frequencies + * are tested before being applied, and may be rejected. + * + * Note: if the target clocks are too aggressive, their testing may + * render the system unresponsive. + * + * Note: while this attribute can always be queried, it can't be set + * unless NV_CTRL_GPU_OVERCLOCKING_STATE is set to _MANUAL. Since + * the target clocks may be rejected, the requester should read this + * attribute after the set to determine success or failure. + * + * NV_CTRL_GPU_{2,3}D_CLOCK_FREQS are "packed" integer attributes; the + * GPU clock is stored in the upper 16 bits of the integer, and the + * memory clock is stored in the lower 16 bits of the integer. All + * clock values are in MHz. + */ + +#define NV_CTRL_GPU_2D_CLOCK_FREQS 89 /* RW-G */ +#define NV_CTRL_GPU_3D_CLOCK_FREQS 90 /* RW-G */ + +/* + * NV_CTRL_GPU_DEFAULT_{2,3}D_CLOCK_FREQS - query the default memory + * and GPU core clocks of the device driving the X screen. + * + * NV_CTRL_GPU_DEFAULT_{2,3}D_CLOCK_FREQS are "packed" integer + * attributes; the GPU clock is stored in the upper 16 bits of the + * integer, and the memory clock is stored in the lower 16 bits of the + * integer. All clock values are in MHz. + */ + +#define NV_CTRL_GPU_DEFAULT_2D_CLOCK_FREQS 91 /* R--G */ +#define NV_CTRL_GPU_DEFAULT_3D_CLOCK_FREQS 92 /* R--G */ + +/* + * NV_CTRL_GPU_CURRENT_CLOCK_FREQS - query the current GPU and memory + * clocks of the graphics device driving the X screen. + * + * NV_CTRL_GPU_CURRENT_CLOCK_FREQS is a "packed" integer attribute; + * the GPU clock is stored in the upper 16 bits of the integer, and + * the memory clock is stored in the lower 16 bits of the integer. + * All clock values are in MHz. All clock values are in MHz. + */ + +#define NV_CTRL_GPU_CURRENT_CLOCK_FREQS 93 /* R--G */ + +/* + * NV_CTRL_GPU_OPTIMAL_CLOCK_FREQS - Holds the last calculated + * optimal 3D clock frequencies found by the + * NV_CTRL_GPU_OPTIMAL_CLOCK_FREQS_DETECTION process. Querying this + * attribute before having probed for the optimal clocks will return + * NV_CTRL_GPU_OPTIMAL_CLOCK_FREQS_INVALID + * + * Note: unless NV_CTRL_GPU_OVERCLOCKING_STATE is set to _MANUAL, the + * optimal clock detection process is unavailable. + */ + +#define NV_CTRL_GPU_OPTIMAL_CLOCK_FREQS 94 /* R--G */ +#define NV_CTRL_GPU_OPTIMAL_CLOCK_FREQS_INVALID 0 + +/* + * NV_CTRL_GPU_OPTIMAL_CLOCK_FREQS_DETECTION - set to _START to + * initiate testing for the optimal 3D clock frequencies. Once + * found, the optimal clock frequencies will be returned by the + * NV_CTRL_GPU_OPTIMAL_CLOCK_FREQS attribute asynchronously + * (using an X event, see XNVCtrlSelectNotify). + * + * To cancel an ongoing test for the optimal clocks, set the + * NV_CTRL_GPU_OPTIMAL_CLOCK_FREQS_DETECTION attribute to _CANCEL + * + * Note: unless NV_CTRL_GPU_OVERCLOCKING_STATE is set to _MANUAL, the + * optimal clock detection process is unavailable. + */ + +#define NV_CTRL_GPU_OPTIMAL_CLOCK_FREQS_DETECTION 95 /* -W-G */ +#define NV_CTRL_GPU_OPTIMAL_CLOCK_FREQS_DETECTION_START 0 +#define NV_CTRL_GPU_OPTIMAL_CLOCK_FREQS_DETECTION_CANCEL 1 + +/* + * NV_CTRL_GPU_OPTIMAL_CLOCK_FREQS_DETECTION_STATE - query this + * variable to know if a test is currently being run to + * determine the optimal 3D clock frequencies. _BUSY means a + * test is currently running, _IDLE means the test is not running. + * + * Note: unless NV_CTRL_GPU_OVERCLOCKING_STATE is set to _MANUAL, the + * optimal clock detection process is unavailable. + */ + +#define NV_CTRL_GPU_OPTIMAL_CLOCK_FREQS_DETECTION_STATE 96 /* R--G */ +#define NV_CTRL_GPU_OPTIMAL_CLOCK_FREQS_DETECTION_STATE_IDLE 0 +#define NV_CTRL_GPU_OPTIMAL_CLOCK_FREQS_DETECTION_STATE_BUSY 1 + +/* + * NV_CTRL_FLATPANEL_CHIP_LOCATION - for the specified display device, + * report whether the flat panel is driven by the on-chip controller, + * or a separate controller chip elsewhere on the graphics board. + * This attribute is only available for flat panels. + */ + +#define NV_CTRL_FLATPANEL_CHIP_LOCATION 215 /* R-DG */ +#define NV_CTRL_FLATPANEL_CHIP_LOCATION_INTERNAL 0 +#define NV_CTRL_FLATPANEL_CHIP_LOCATION_EXTERNAL 1 + +/* + * NV_CTRL_FLATPANEL_LINK - report the number of links for a DVI connection, or + * the main link's active lane count for DisplayPort. + * This attribute is only available for flat panels. + */ + +#define NV_CTRL_FLATPANEL_LINK 216 /* R-DG */ +#define NV_CTRL_FLATPANEL_LINK_SINGLE 0 +#define NV_CTRL_FLATPANEL_LINK_DUAL 1 +#define NV_CTRL_FLATPANEL_LINK_QUAD 3 + +/* + * NV_CTRL_FLATPANEL_SIGNAL - for the specified display device, report + * whether the flat panel is driven by an LVDS, TMDS, or DisplayPort signal. + * This attribute is only available for flat panels. + */ + +#define NV_CTRL_FLATPANEL_SIGNAL 217 /* R-DG */ +#define NV_CTRL_FLATPANEL_SIGNAL_LVDS 0 +#define NV_CTRL_FLATPANEL_SIGNAL_TMDS 1 +#define NV_CTRL_FLATPANEL_SIGNAL_DISPLAYPORT 2 + +/* + * NV_CTRL_USE_HOUSE_SYNC - when TRUE, the server (master) frame lock + * device will propagate the incoming house sync signal as the outgoing + * frame lock sync signal. If the frame lock device cannot detect a + * frame lock sync signal, it will default to using the internal timings + * from the GPU connected to the primary connector. + * + * This attribute may be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_FRAMELOCK or NV_CTRL_TARGET_TYPE_X_SCREEN + * target. + */ + +#define NV_CTRL_USE_HOUSE_SYNC 218 /* RW-F */ +#define NV_CTRL_USE_HOUSE_SYNC_FALSE 0 +#define NV_CTRL_USE_HOUSE_SYNC_TRUE 1 + +/* + * NV_CTRL_EDID_AVAILABLE - report if an EDID is available for the + * specified display device. + * + * This attribute may also be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_GPU or NV_CTRL_TARGET_TYPE_X_SCREEN + * target. + */ + +#define NV_CTRL_EDID_AVAILABLE 219 /* R-DG */ +#define NV_CTRL_EDID_AVAILABLE_FALSE 0 +#define NV_CTRL_EDID_AVAILABLE_TRUE 1 + +/* + * NV_CTRL_FORCE_STEREO - when TRUE, OpenGL will force stereo flipping + * even when no stereo drawables are visible (if the device is configured + * to support it, see the "Stereo" X config option). + * When false, fall back to the default behavior of only flipping when a + * stereo drawable is visible. + */ + +#define NV_CTRL_FORCE_STEREO 220 /* RW- */ +#define NV_CTRL_FORCE_STEREO_FALSE 0 +#define NV_CTRL_FORCE_STEREO_TRUE 1 + +/* + * NV_CTRL_IMAGE_SETTINGS - the image quality setting for OpenGL clients. + * + * This setting is only applied to OpenGL clients that are started + * after this setting is applied. + */ + +#define NV_CTRL_IMAGE_SETTINGS 221 /* RW-X */ +#define NV_CTRL_IMAGE_SETTINGS_HIGH_QUALITY 0 +#define NV_CTRL_IMAGE_SETTINGS_QUALITY 1 +#define NV_CTRL_IMAGE_SETTINGS_PERFORMANCE 2 +#define NV_CTRL_IMAGE_SETTINGS_HIGH_PERFORMANCE 3 + +/* + * NV_CTRL_XINERAMA - return whether xinerama is enabled + */ + +#define NV_CTRL_XINERAMA 222 /* R--G */ +#define NV_CTRL_XINERAMA_OFF 0 +#define NV_CTRL_XINERAMA_ON 1 + +/* + * NV_CTRL_XINERAMA_STEREO - when TRUE, OpenGL will allow stereo flipping + * on multiple X screens configured with Xinerama. + * When FALSE, flipping is allowed only on one X screen at a time. + */ + +#define NV_CTRL_XINERAMA_STEREO 223 /* RW- */ +#define NV_CTRL_XINERAMA_STEREO_FALSE 0 +#define NV_CTRL_XINERAMA_STEREO_TRUE 1 + +/* + * NV_CTRL_BUS_RATE - if the bus type of the specified device is AGP, then + * NV_CTRL_BUS_RATE returns the configured AGP transfer rate. If the bus type + * is PCI Express, then this attribute returns the maximum link width. + * When this attribute is queried on an X screen target, the bus rate of the + * GPU driving the X screen is returned. + */ + +#define NV_CTRL_BUS_RATE 224 /* R--GI */ + +/* + * NV_CTRL_GPU_PCIE_MAX_LINK_WIDTH - returns the maximum + * PCIe link width, in number of lanes. + */ +#define NV_CTRL_GPU_PCIE_MAX_LINK_WIDTH NV_CTRL_BUS_RATE + +/* + * NV_CTRL_SHOW_SLI_HUD - when TRUE, OpenGL will draw information about the + * current SLI mode. + * Renamed this attribute to NV_CTRL_SHOW_SLI_VISUAL_INDICATOR + */ + +#define NV_CTRL_SHOW_SLI_HUD NV_CTRL_SHOW_SLI_VISUAL_INDICATOR +#define NV_CTRL_SHOW_SLI_HUD_FALSE NV_CTRL_SHOW_SLI_VISUAL_INDICATOR_FALSE +#define NV_CTRL_SHOW_SLI_HUD_TRUE NV_CTRL_SHOW_SLI_VISUAL_INDICATOR_TRUE + +/* + * NV_CTRL_SHOW_SLI_VISUAL_INDICATOR - when TRUE, OpenGL will draw information + * about the current SLI mode. + */ + +#define NV_CTRL_SHOW_SLI_VISUAL_INDICATOR 225 /* RW-X */ +#define NV_CTRL_SHOW_SLI_VISUAL_INDICATOR_FALSE 0 +#define NV_CTRL_SHOW_SLI_VISUAL_INDICATOR_TRUE 1 + +/* + * NV_CTRL_XV_SYNC_TO_DISPLAY - this control is valid when TwinView and + * XVideo Sync To VBlank are enabled. + * It controls which display device will be synched to. + */ + +#define NV_CTRL_XV_SYNC_TO_DISPLAY 226 /* RW- */ + +/* + * NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT2 - this attribute is only + * intended to be used to query the ValidValues for + * NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT for VIDEO_FORMAT values between + * 31 and 63. See NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT for details. + */ + +#define NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT2 227 /* ---GI */ + +/* + * The following is deprecated; use NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT2, + * instead + */ +#define NV_CTRL_GVO_OUTPUT_VIDEO_FORMAT2 227 /* --- */ + +/* + * NV_CTRL_GVO_OVERRIDE_HW_CSC - Override the SDI hardware's Color Space + * Conversion with the values controlled through + * XNVCTRLSetGvoColorConversion() and XNVCTRLGetGvoColorConversion(). If + * this attribute is FALSE, then the values specified through + * XNVCTRLSetGvoColorConversion() are ignored. + */ + +#define NV_CTRL_GVO_OVERRIDE_HW_CSC 228 /* RW- */ +#define NV_CTRL_GVO_OVERRIDE_HW_CSC_FALSE 0 +#define NV_CTRL_GVO_OVERRIDE_HW_CSC_TRUE 1 + +/* + * NV_CTRL_GVO_CAPABILITIES - this read-only attribute describes GVO + * capabilities that differ between NVIDIA SDI products. This value + * is a bitmask where each bit indicates whether that capability is + * available. + * + * APPLY_CSC_IMMEDIATELY - whether the CSC matrix, offset, and scale + * specified through XNVCTRLSetGvoColorConversion() will take affect + * immediately, or only after SDI output is disabled and enabled + * again. + * + * APPLY_CSC_TO_X_SCREEN - whether the CSC matrix, offset, and scale + * specified through XNVCTRLSetGvoColorConversion() will also apply + * to GVO output of an X screen, or only to OpenGL GVO output, as + * enabled through the GLX_NV_video_out extension. + * + * COMPOSITE_TERMINATION - whether the 75 ohm termination of the + * SDI composite input signal can be programmed through the + * NV_CTRL_GVO_COMPOSITE_TERMINATION attribute. + * + * SHARED_SYNC_BNC - whether the SDI device has a single BNC + * connector used for both (SDI & Composite) incoming signals. + * + * MULTIRATE_SYNC - whether the SDI device supports synchronization + * of input and output video modes that match in being odd or even + * modes (ie, AA.00 Hz modes can be synched to other BB.00 Hz modes and + * AA.XX Hz can match to BB.YY Hz where .XX and .YY are not .00) + */ + +#define NV_CTRL_GVO_CAPABILITIES 229 /* R-- */ +#define NV_CTRL_GVO_CAPABILITIES_APPLY_CSC_IMMEDIATELY 0x00000001 +#define NV_CTRL_GVO_CAPABILITIES_APPLY_CSC_TO_X_SCREEN 0x00000002 +#define NV_CTRL_GVO_CAPABILITIES_COMPOSITE_TERMINATION 0x00000004 +#define NV_CTRL_GVO_CAPABILITIES_SHARED_SYNC_BNC 0x00000008 +#define NV_CTRL_GVO_CAPABILITIES_MULTIRATE_SYNC 0x00000010 +#define NV_CTRL_GVO_CAPABILITIES_ADVANCE_SYNC_SKEW 0x00000020 + +/* + * NV_CTRL_GVO_COMPOSITE_TERMINATION - enable or disable 75 ohm + * termination of the SDI composite input signal. + */ + +#define NV_CTRL_GVO_COMPOSITE_TERMINATION 230 /* RW- */ +#define NV_CTRL_GVO_COMPOSITE_TERMINATION_ENABLE 1 +#define NV_CTRL_GVO_COMPOSITE_TERMINATION_DISABLE 0 + +/* + * NV_CTRL_ASSOCIATED_DISPLAY_DEVICES - display device mask indicating + * which display devices are "associated" with the specified X screen + * (ie: are available to the X screen for displaying the X screen). + */ + +#define NV_CTRL_ASSOCIATED_DISPLAY_DEVICES 231 /* RW- */ + +/* + * NV_CTRL_FRAMELOCK_SLAVES - get/set whether the display device(s) + * given should listen or ignore the master's sync signal. + * + * This attribute can only be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_GPU target. This attribute cannot be + * queried using a NV_CTRL_TARGET_TYPE_X_SCREEN. + */ + +#define NV_CTRL_FRAMELOCK_SLAVES 232 /* RW-G */ + +/* + * NV_CTRL_FRAMELOCK_MASTERABLE - Can any of the given display devices + * be set as master of the frame lock group. Returns a bitmask of the + * corresponding display devices that can be set as master. + * + * This attribute can only be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_GPU target. This attribute cannot be + * queried using a NV_CTRL_TARGET_TYPE_X_SCREEN. + */ + +#define NV_CTRL_FRAMELOCK_MASTERABLE 233 /* R-DG */ + +/* + * NV_CTRL_PROBE_DISPLAYS - re-probes the hardware to detect what + * display devices are connected to the GPU or GPU driving the + * specified X screen. Returns a display mask. + * + * This attribute may be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_GPU or NV_CTRL_TARGET_TYPE_X_SCREEN target. + */ + +#define NV_CTRL_PROBE_DISPLAYS 234 /* R--G */ + +/* + * NV_CTRL_REFRESH_RATE - Returns the refresh rate of the specified + * display device in 100 * Hz (ie. to get the refresh rate in Hz, divide + * the returned value by 100.) + * + * This attribute may be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_GPU or NV_CTRL_TARGET_TYPE_X_SCREEN target. + */ + +#define NV_CTRL_REFRESH_RATE 235 /* R-DG */ + +/* + * NV_CTRL_GVO_FLIP_QUEUE_SIZE - The Graphics to Video Out interface + * exposed through NV-CONTROL and the GLX_NV_video_out extension uses + * an internal flip queue when pbuffers are sent to the video device + * (via glXSendPbufferToVideoNV()). The NV_CTRL_GVO_FLIP_QUEUE_SIZE + * can be used to query and assign the flip queue size. This + * attribute is applied to GLX when glXGetVideoDeviceNV() is called by + * the application. + */ + +#define NV_CTRL_GVO_FLIP_QUEUE_SIZE 236 /* RW- */ + +/* + * NV_CTRL_CURRENT_SCANLINE - query the current scanline for the + * specified display device. + */ + +#define NV_CTRL_CURRENT_SCANLINE 237 /* R-DG */ + +/* + * NV_CTRL_INITIAL_PIXMAP_PLACEMENT - Controls where X pixmaps are initially + * created. + * + * NV_CTRL_INITIAL_PIXMAP_PLACEMENT_FORCE_SYSMEM causes pixmaps to stay in + * system memory. These pixmaps can't be accelerated by the NVIDIA driver; this + * will cause blank windows if used with an OpenGL compositing manager. + * NV_CTRL_INITIAL_PIXMAP_PLACEMENT_SYSMEM creates pixmaps in system memory + * initially, but allows them to migrate to video memory. + * NV_CTRL_INITIAL_PIXMAP_PLACEMENT_VIDMEM creates pixmaps in video memory + * when enough resources are available. + * NV_CTRL_INITIAL_PIXMAP_PLACEMENT_RESERVED is currently reserved for future + * use. Behavior is undefined. + * NV_CTRL_INITIAL_PIXMAP_PLACEMENT_GPU_SYSMEM creates pixmaps in GPU accessible + * system memory when enough resources are available. + */ + +#define NV_CTRL_INITIAL_PIXMAP_PLACEMENT 238 /* RW- */ +#define NV_CTRL_INITIAL_PIXMAP_PLACEMENT_FORCE_SYSMEM 0 +#define NV_CTRL_INITIAL_PIXMAP_PLACEMENT_SYSMEM 1 +#define NV_CTRL_INITIAL_PIXMAP_PLACEMENT_VIDMEM 2 +#define NV_CTRL_INITIAL_PIXMAP_PLACEMENT_RESERVED 3 +#define NV_CTRL_INITIAL_PIXMAP_PLACEMENT_GPU_SYSMEM 4 + +/* + * NV_CTRL_PCI_BUS - Returns the PCI bus number the specified device is using. + */ + +#define NV_CTRL_PCI_BUS 239 /* R--GI */ + +/* + * NV_CTRL_PCI_DEVICE - Returns the PCI device number the specified device is + * using. + */ + +#define NV_CTRL_PCI_DEVICE 240 /* R--GI */ + +/* + * NV_CTRL_PCI_FUNCTION - Returns the PCI function number the specified device + * is using. + */ + +#define NV_CTRL_PCI_FUNCTION 241 /* R--GI */ + +/* + * NV_CTRL_FRAMELOCK_FPGA_REVISION - Querys the FPGA revision of the + * Frame Lock device. + * + * This attribute must be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_FRAMELOCK target. + */ + +#define NV_CTRL_FRAMELOCK_FPGA_REVISION 242 /* R--F */ + +/* + * NV_CTRL_MAX_SCREEN_{WIDTH,HEIGHT} - the maximum allowable size, in + * pixels, of either the specified X screen (if the target_type of the + * query is an X screen), or any X screen on the specified GPU (if the + * target_type of the query is a GPU). + */ + +#define NV_CTRL_MAX_SCREEN_WIDTH 243 /* R--G */ +#define NV_CTRL_MAX_SCREEN_HEIGHT 244 /* R--G */ + +/* + * NV_CTRL_MAX_DISPLAYS - the maximum number of display devices that + * can be driven simultaneously on a GPU (e.g., that can be used in a + * MetaMode at once). Note that this does not indicate the maximum + * number of bits that can be set in NV_CTRL_CONNECTED_DISPLAYS, + * because more display devices can be connected than are actively in + * use. + */ + +#define NV_CTRL_MAX_DISPLAYS 245 /* R--G */ + +/* + * NV_CTRL_DYNAMIC_TWINVIEW - Returns whether or not the screen + * supports dynamic twinview. + */ + +#define NV_CTRL_DYNAMIC_TWINVIEW 246 /* R-- */ + +/* + * NV_CTRL_MULTIGPU_DISPLAY_OWNER - Returns the (NV-CONTROL) GPU ID of + * the GPU that has the display device(s) used for showing the X Screen. + */ + +#define NV_CTRL_MULTIGPU_DISPLAY_OWNER 247 /* R-- */ + +/* + * NV_CTRL_GPU_SCALING - not supported + */ + +#define NV_CTRL_GPU_SCALING 248 /* RWDG */ + +#define NV_CTRL_GPU_SCALING_TARGET_INVALID 0 +#define NV_CTRL_GPU_SCALING_TARGET_FLATPANEL_BEST_FIT 1 +#define NV_CTRL_GPU_SCALING_TARGET_FLATPANEL_NATIVE 2 + +#define NV_CTRL_GPU_SCALING_METHOD_INVALID 0 +#define NV_CTRL_GPU_SCALING_METHOD_STRETCHED 1 +#define NV_CTRL_GPU_SCALING_METHOD_CENTERED 2 +#define NV_CTRL_GPU_SCALING_METHOD_ASPECT_SCALED 3 + +/* + * NV_CTRL_FRONTEND_RESOLUTION - not supported + */ + +#define NV_CTRL_FRONTEND_RESOLUTION 249 /* R-DG */ + +/* + * NV_CTRL_BACKEND_RESOLUTION - not supported + */ + +#define NV_CTRL_BACKEND_RESOLUTION 250 /* R-DG */ + +/* + * NV_CTRL_FLATPANEL_NATIVE_RESOLUTION - Returns the dimensions of the + * native resolution of the flat panel as determined by the + * NVIDIA X Driver. + * + * The native resolution is the resolution at which a flat panel + * must display any image. All other resolutions must be scaled to this + * resolution through GPU scaling or the DFP's native scaling capabilities + * in order to be displayed. + * + * This attribute is only valid for flat panel (DFP) display devices. + * + * This attribute is a packed integer; the width is packed in the upper + * 16-bits and the height is packed in the lower 16-bits. + */ + +#define NV_CTRL_FLATPANEL_NATIVE_RESOLUTION 251 /* R-DG */ + +/* + * NV_CTRL_FLATPANEL_BEST_FIT_RESOLUTION - not supported + */ + +#define NV_CTRL_FLATPANEL_BEST_FIT_RESOLUTION 252 /* R-DG */ + +/* + * NV_CTRL_GPU_SCALING_ACTIVE - not supported + */ + +#define NV_CTRL_GPU_SCALING_ACTIVE 253 /* R-DG */ + +/* + * NV_CTRL_DFP_SCALING_ACTIVE - not supported + */ + +#define NV_CTRL_DFP_SCALING_ACTIVE 254 /* R-DG */ + +/* + * NV_CTRL_FSAA_APPLICATION_ENHANCED - Controls how the NV_CTRL_FSAA_MODE + * is applied when NV_CTRL_FSAA_APPLICATION_CONTROLLED is set to + * NV_CTRL_APPLICATION_CONTROLLED_DISABLED. When + * NV_CTRL_FSAA_APPLICATION_ENHANCED is _DISABLED, OpenGL applications will + * be forced to use the FSAA mode specified by NV_CTRL_FSAA_MODE. when set + * to _ENABLED, only those applications that have selected a multisample + * FBConfig will be made to use the NV_CTRL_FSAA_MODE specified. + * + * This attribute is ignored when NV_CTRL_FSAA_APPLICATION_CONTROLLED is + * set to NV_CTRL_FSAA_APPLICATION_CONTROLLED_ENABLED. + */ + +#define NV_CTRL_FSAA_APPLICATION_ENHANCED 255 /* RW-X */ +#define NV_CTRL_FSAA_APPLICATION_ENHANCED_ENABLED 1 +#define NV_CTRL_FSAA_APPLICATION_ENHANCED_DISABLED 0 + +/* + * NV_CTRL_FRAMELOCK_SYNC_RATE_4 - This is the refresh rate that the + * frame lock board is sending to the GPU with 4 digits of precision. + * + * This attribute may be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_FRAMELOCK. + */ + +#define NV_CTRL_FRAMELOCK_SYNC_RATE_4 256 /* R--F */ + +/* + * NV_CTRL_GVO_LOCK_OWNER - indicates that the GVO device is available + * or in use (by GLX or an X screen). + * + * The GVO device is locked by GLX when either glXGetVideoDeviceNV + * (part of GLX_NV_video_out) or glXBindVideoDeviceNV (part of + * GLX_NV_present_video) is called. All GVO output resources are + * locked until released by the GLX_NV_video_out/GLX_NV_present_video + * client. + * + * The GVO device is locked/unlocked by an X screen, when the GVO device is + * used in a MetaMode on an X screen. + * + * When the GVO device is locked, setting of the following GVO NV-CONTROL + * attributes will not happen immediately and will instead be cached. The + * GVO resource will need to be disabled/released and re-enabled/claimed for + * the values to be flushed. These attributes are: + * + * NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT + * NV_CTRL_GVO_DATA_FORMAT + * NV_CTRL_GVO_FLIP_QUEUE_SIZE + */ + +#define NV_CTRL_GVO_LOCK_OWNER 257 /* R-- */ +#define NV_CTRL_GVO_LOCK_OWNER_NONE 0 +#define NV_CTRL_GVO_LOCK_OWNER_GLX 1 +#define NV_CTRL_GVO_LOCK_OWNER_CLONE /* no longer supported */ 2 +#define NV_CTRL_GVO_LOCK_OWNER_X_SCREEN 3 + +/* + * NV_CTRL_HWOVERLAY - when a workstation overlay is in use, reports + * whether the hardware overlay is used, or if the overlay is emulated. + */ + +#define NV_CTRL_HWOVERLAY 258 /* R-- */ +#define NV_CTRL_HWOVERLAY_FALSE 0 +#define NV_CTRL_HWOVERLAY_TRUE 1 + +/* + * NV_CTRL_NUM_GPU_ERRORS_RECOVERED - Returns the number of GPU errors + * occured. This attribute may be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_X_SCREEN target. + */ + +#define NV_CTRL_NUM_GPU_ERRORS_RECOVERED 259 /* R--- */ + +/* + * NV_CTRL_REFRESH_RATE_3 - Returns the refresh rate of the specified + * display device in 1000 * Hz (ie. to get the refresh rate in Hz, divide + * the returned value by 1000.) + * + * This attribute may be queried through XNVCTRLQueryTargetAttribute() + * using a NV_CTRL_TARGET_TYPE_GPU or NV_CTRL_TARGET_TYPE_X_SCREEN target. + */ + +#define NV_CTRL_REFRESH_RATE_3 260 /* R-DG */ + +/* + * NV_CTRL_ONDEMAND_VBLANK_INTERRUPTS - if the OnDemandVBlankInterrupts + * X driver option is set to true, this attribute can be used to + * determine if on-demand VBlank interrupt control is enabled on the + * specified GPU, as well as to enable or disable this feature. + */ + +#define NV_CTRL_ONDEMAND_VBLANK_INTERRUPTS 261 /* RW-G */ +#define NV_CTRL_ONDEMAND_VBLANK_INTERRUPTS_OFF 0 +#define NV_CTRL_ONDEMAND_VBLANK_INTERRUPTS_ON 1 + +/* + * NV_CTRL_GPU_POWER_SOURCE reports the type of power source + * of the GPU driving the X screen. + */ + +#define NV_CTRL_GPU_POWER_SOURCE 262 /* R--G */ +#define NV_CTRL_GPU_POWER_SOURCE_AC 0 +#define NV_CTRL_GPU_POWER_SOURCE_BATTERY 1 + +/* + * NV_CTRL_GPU_CURRENT_PERFORMANCE_MODE is deprecated + */ + +#define NV_CTRL_GPU_CURRENT_PERFORMANCE_MODE 263 /* R--G */ +#define NV_CTRL_GPU_CURRENT_PERFORMANCE_MODE_DESKTOP 0 +#define NV_CTRL_GPU_CURRENT_PERFORMANCE_MODE_MAXPERF 1 + +/* NV_CTRL_GLYPH_CACHE - Enables RENDER Glyph Caching to VRAM */ + +#define NV_CTRL_GLYPH_CACHE 264 /* RW- */ +#define NV_CTRL_GLYPH_CACHE_DISABLED 0 +#define NV_CTRL_GLYPH_CACHE_ENABLED 1 + +/* + * NV_CTRL_GPU_CURRENT_PERFORMANCE_LEVEL reports the current + * Performance level of the GPU driving the X screen. Each + * Performance level has associated NVClock and Mem Clock values. + */ + +#define NV_CTRL_GPU_CURRENT_PERFORMANCE_LEVEL 265 /* R--G */ + +/* + * NV_CTRL_GPU_ADAPTIVE_CLOCK_STATE reports if Adaptive Clocking + * is Enabled on the GPU driving the X screen. + */ + +#define NV_CTRL_GPU_ADAPTIVE_CLOCK_STATE 266 /* R--G */ +#define NV_CTRL_GPU_ADAPTIVE_CLOCK_STATE_DISABLED 0 +#define NV_CTRL_GPU_ADAPTIVE_CLOCK_STATE_ENABLED 1 + +/* + * NV_CTRL_GVO_OUTPUT_VIDEO_LOCKED - Returns whether or not the GVO output + * video is locked to the GPU. + */ + +#define NV_CTRL_GVO_OUTPUT_VIDEO_LOCKED 267 /* R--- */ +#define NV_CTRL_GVO_OUTPUT_VIDEO_LOCKED_FALSE 0 +#define NV_CTRL_GVO_OUTPUT_VIDEO_LOCKED_TRUE 1 + +/* + * NV_CTRL_GVO_SYNC_LOCK_STATUS - Returns whether or not the GVO device + * is locked to the input ref signal. If the sync mode is set to + * NV_CTRL_GVO_SYNC_MODE_GENLOCK, then this returns the genlock + * sync status, and if the sync mode is set to NV_CTRL_GVO_SYNC_MODE_FRAMELOCK, + * then this reports the frame lock status. + */ + +#define NV_CTRL_GVO_SYNC_LOCK_STATUS 268 /* R--- */ +#define NV_CTRL_GVO_SYNC_LOCK_STATUS_UNLOCKED 0 +#define NV_CTRL_GVO_SYNC_LOCK_STATUS_LOCKED 1 + +/* + * NV_CTRL_GVO_ANC_TIME_CODE_GENERATION - Allows SDI device to generate + * time codes in the ANC region of the SDI video output stream. + */ + +#define NV_CTRL_GVO_ANC_TIME_CODE_GENERATION 269 /* RW-- */ +#define NV_CTRL_GVO_ANC_TIME_CODE_GENERATION_DISABLE 0 +#define NV_CTRL_GVO_ANC_TIME_CODE_GENERATION_ENABLE 1 + +/* + * NV_CTRL_GVO_COMPOSITE - Enables/Disables SDI compositing. This attribute + * is only available when an SDI input source is detected and is in genlock + * mode. + */ + +#define NV_CTRL_GVO_COMPOSITE 270 /* RW-- */ +#define NV_CTRL_GVO_COMPOSITE_DISABLE 0 +#define NV_CTRL_GVO_COMPOSITE_ENABLE 1 + +/* + * NV_CTRL_GVO_COMPOSITE_ALPHA_KEY - When compositing is enabled, this + * enables/disables alpha blending. + */ + +#define NV_CTRL_GVO_COMPOSITE_ALPHA_KEY 271 /* RW-- */ +#define NV_CTRL_GVO_COMPOSITE_ALPHA_KEY_DISABLE 0 +#define NV_CTRL_GVO_COMPOSITE_ALPHA_KEY_ENABLE 1 + +/* + * NV_CTRL_GVO_COMPOSITE_LUMA_KEY_RANGE - Set the values of a luma + * channel range. This is a packed int that has the following format + * (in order of high-bits to low bits): + * + * Range # (11 bits), (Enabled 1 bit), min value (10 bits), max value (10 bits) + * + * To query the current values, pass the range # throught the display_mask + * variable. + */ + +#define NV_CTRL_GVO_COMPOSITE_LUMA_KEY_RANGE 272 /* RW-- */ + +#define NV_CTRL_GVO_COMPOSITE_MAKE_RANGE(range, enable, min, max) \ + ((((min)&0x3FF) << 0) | (((max)&0x3FF) << 10) | (((enable)&0x1) << 20) | \ + (((range)&0x7FF) << 21)) + +#define NV_CTRL_GVO_COMPOSITE_GET_RANGE(val, range, enable, min, max) \ + (min) = ((val) >> 0) & 0x3FF; \ + (max) = ((val) >> 10) & 0x3FF; \ + (enable) = ((val) >> 20) & 0x1; \ + (range) = ((val) >> 21) & 0x7FF; + +/* + * NV_CTRL_GVO_COMPOSITE_CR_KEY_RANGE - Set the values of a CR + * channel range. This is a packed int that has the following format + * (in order of high-bits to low bits): + * + * Range # (11 bits), (Enabled 1 bit), min value (10 bits), max value (10 bits) + * + * To query the current values, pass the range # throught he display_mask + * variable. + */ + +#define NV_CTRL_GVO_COMPOSITE_CR_KEY_RANGE 273 /* RW-- */ + +/* + * NV_CTRL_GVO_COMPOSITE_CB_KEY_RANGE - Set the values of a CB + * channel range. This is a packed int that has the following format + * (in order of high-bits to low bits): + * + * Range # (11 bits), (Enabled 1 bit), min value (10 bits), max value (10 bits) + * + * To query the current values, pass the range # throught he display_mask + * variable. + */ + +#define NV_CTRL_GVO_COMPOSITE_CB_KEY_RANGE 274 /* RW-- */ + +/* + * NV_CTRL_GVO_COMPOSITE_NUM_KEY_RANGES - Returns the number of ranges + * available for each channel (Y/Luma, Cr, and Cb.) + */ + +#define NV_CTRL_GVO_COMPOSITE_NUM_KEY_RANGES 275 /* R--- */ + +/* + * NV_CTRL_SWITCH_TO_DISPLAYS - Can be used to select which displays + * to switch to (as a hotkey event). + */ + +#define NV_CTRL_SWITCH_TO_DISPLAYS 276 /* -W- */ + +/* + * NV_CTRL_NOTEBOOK_DISPLAY_CHANGE_LID_EVENT - Event that notifies + * when a notebook lid change occurs (i.e. when the lid is opened or + * closed.) This attribute can be queried to retrieve the current + * notebook lid status (opened/closed.) + */ + +#define NV_CTRL_NOTEBOOK_DISPLAY_CHANGE_LID_EVENT 277 /* RW- */ +#define NV_CTRL_NOTEBOOK_DISPLAY_CHANGE_LID_EVENT_CLOSE 0 +#define NV_CTRL_NOTEBOOK_DISPLAY_CHANGE_LID_EVENT_OPEN 1 + +/* + * NV_CTRL_NOTEBOOK_INTERNAL_LCD - Returns the display device mask of + * the intenal LCD of a notebook. + */ + +#define NV_CTRL_NOTEBOOK_INTERNAL_LCD 278 /* R-- */ + +/* + * NV_CTRL_DEPTH_30_ALLOWED - returns whether the NVIDIA X driver supports + * depth 30 on the specified X screen or GPU. + */ + +#define NV_CTRL_DEPTH_30_ALLOWED 279 /* R--G */ + +/* + * NV_CTRL_MODE_SET_EVENT This attribute is sent as an event + * when hotkey, ctrl-alt-+/- or randr event occurs. Note that + * This attribute cannot be set or queried and is meant to + * be received by clients that wish to be notified of when + * mode set events occur. + */ + +#define NV_CTRL_MODE_SET_EVENT 280 /* --- */ + +/* + * NV_CTRL_OPENGL_AA_LINE_GAMMA_VALUE - the gamma value used by + * OpenGL when NV_CTRL_OPENGL_AA_LINE_GAMMA is enabled + */ + +#define NV_CTRL_OPENGL_AA_LINE_GAMMA_VALUE 281 /* RW-X */ + +/* + * NV_CTRL_VCSC_HIGH_PERF_MODE - Is used to both query High Performance Mode + * status on the Visual Computing System, and also to enable or disable High + * Performance Mode. + */ + +#define NV_CTRL_VCSC_HIGH_PERF_MODE 282 /* RW-V */ +#define NV_CTRL_VCSC_HIGH_PERF_MODE_DISABLE 0 +#define NV_CTRL_VCSC_HIGH_PERF_MODE_ENABLE 1 + +/* + * NV_CTRL_DISPLAYPORT_LINK_RATE - returns the negotiated lane bandwidth of the + * DisplayPort main link. + * This attribute is only available for DisplayPort flat panels. + */ + +#define NV_CTRL_DISPLAYPORT_LINK_RATE 291 /* R-DG */ +#define NV_CTRL_DISPLAYPORT_LINK_RATE_DISABLED 0x0 +#define NV_CTRL_DISPLAYPORT_LINK_RATE_1_62GBPS 0x6 +#define NV_CTRL_DISPLAYPORT_LINK_RATE_2_70GBPS 0xA + +/* + * NV_CTRL_STEREO_EYES_EXCHANGE - Controls whether or not the left and right + * eyes of a stereo image are flipped. + */ + +#define NV_CTRL_STEREO_EYES_EXCHANGE 292 /* RW-X */ +#define NV_CTRL_STEREO_EYES_EXCHANGE_OFF 0 +#define NV_CTRL_STEREO_EYES_EXCHANGE_ON 1 + +/* + * NV_CTRL_NO_SCANOUT - returns whether the special "NoScanout" mode is + * enabled on the specified X screen or GPU; for details on this mode, + * see the description of the "none" value for the "UseDisplayDevice" + * X configuration option in the NVIDIA driver README. + */ + +#define NV_CTRL_NO_SCANOUT 293 /* R--G */ +#define NV_CTRL_NO_SCANOUT_DISABLED 0 +#define NV_CTRL_NO_SCANOUT_ENABLED 1 + +/* + * NV_CTRL_GVO_CSC_CHANGED_EVENT This attribute is sent as an event + * when the color space conversion matrix has been altered by another + * client. + */ + +#define NV_CTRL_GVO_CSC_CHANGED_EVENT 294 /* --- */ + +/* + * NV_CTRL_FRAMELOCK_SLAVEABLE - Returns a bitmask of the display devices + * that are (currently) allowed to be selected as slave devices for the + * given GPU + */ + +#define NV_CTRL_FRAMELOCK_SLAVEABLE 295 /* R-DG */ + +/* + * NV_CTRL_GVO_SYNC_TO_DISPLAY This attribute controls whether or not + * the non-SDI display device will be sync'ed to the SDI display device + * (when configured in TwinView, Clone Mode or when using the SDI device + * with OpenGL). + */ + +#define NV_CTRL_GVO_SYNC_TO_DISPLAY 296 /* --- */ +#define NV_CTRL_GVO_SYNC_TO_DISPLAY_DISABLE 0 +#define NV_CTRL_GVO_SYNC_TO_DISPLAY_ENABLE 1 + +/* + * NV_CTRL_X_SERVER_UNIQUE_ID - returns a pseudo-unique identifier for this + * X server. Intended for use in cases where an NV-CONTROL client communicates + * with multiple X servers, and wants some level of confidence that two + * X Display connections correspond to the same or different X servers. + */ + +#define NV_CTRL_X_SERVER_UNIQUE_ID 297 /* R--- */ + +/* + * NV_CTRL_PIXMAP_CACHE - This attribute controls whether the driver attempts to + * store video memory pixmaps in a cache. The cache speeds up allocation and + * deallocation of pixmaps, but could use more memory than when the cache is + * disabled. + */ + +#define NV_CTRL_PIXMAP_CACHE 298 /* RW-X */ +#define NV_CTRL_PIXMAP_CACHE_DISABLE 0 +#define NV_CTRL_PIXMAP_CACHE_ENABLE 1 + +/* + * NV_CTRL_PIXMAP_CACHE_ROUNDING_SIZE_KB - When the pixmap cache is enabled and + * there is not enough free space in the cache to fit a new pixmap, the driver + * will round up to the next multiple of this number of kilobytes when + * allocating more memory for the cache. + */ + +#define NV_CTRL_PIXMAP_CACHE_ROUNDING_SIZE_KB 299 /* RW-X */ + +/* + * NV_CTRL_IS_GVO_DISPLAY - returns whether or not a given display is an + * SDI device. + */ + +#define NV_CTRL_IS_GVO_DISPLAY 300 /* R-D */ +#define NV_CTRL_IS_GVO_DISPLAY_FALSE 0 +#define NV_CTRL_IS_GVO_DISPLAY_TRUE 1 + +/* + * NV_CTRL_PCI_ID - Returns the PCI vendor and device ID of the specified + * device. + * + * NV_CTRL_PCI_ID is a "packed" integer attribute; the PCI vendor ID is stored + * in the upper 16 bits of the integer, and the PCI device ID is stored in the + * lower 16 bits of the integer. + */ + +#define NV_CTRL_PCI_ID 301 /* R--GI */ + +/* + * NV_CTRL_GVO_FULL_RANGE_COLOR - Allow full range color data [4-1019] + * without clamping to [64-940]. + */ + +#define NV_CTRL_GVO_FULL_RANGE_COLOR 302 /* RW- */ +#define NV_CTRL_GVO_FULL_RANGE_COLOR_DISABLED 0 +#define NV_CTRL_GVO_FULL_RANGE_COLOR_ENABLED 1 + +/* + * NV_CTRL_SLI_MOSAIC_MODE_AVAILABLE - Returns whether or not + * SLI Mosaic Mode supported. + */ + +#define NV_CTRL_SLI_MOSAIC_MODE_AVAILABLE 303 /* R-- */ +#define NV_CTRL_SLI_MOSAIC_MODE_AVAILABLE_FALSE 0 +#define NV_CTRL_SLI_MOSAIC_MODE_AVAILABLE_TRUE 1 + +/* + * NV_CTRL_GVO_ENABLE_RGB_DATA - Allows clients to specify when + * the GVO board should process colors as RGB when the output data + * format is one of the NV_CTRL_GVO_DATA_FORMAT_???_PASSTRHU modes. + */ + +#define NV_CTRL_GVO_ENABLE_RGB_DATA 304 /* RW- */ +#define NV_CTRL_GVO_ENABLE_RGB_DATA_DISABLE 0 +#define NV_CTRL_GVO_ENABLE_RGB_DATA_ENABLE 1 + +/* + * NV_CTRL_IMAGE_SHARPENING_DEFAULT - Returns default value of + * Image Sharpening. + */ + +#define NV_CTRL_IMAGE_SHARPENING_DEFAULT 305 /* R-- */ + +/* + * NV_CTRL_PCI_DOMAIN - Returns the PCI domain number the specified device is + * using. + */ + +#define NV_CTRL_PCI_DOMAIN 306 /* R--GI */ + +/* + * NV_CTRL_GVI_NUM_JACKS - Returns the number of input BNC jacks available + * on a GVI device. + */ + +#define NV_CTRL_GVI_NUM_JACKS 307 /* R--I */ + +/* + * NV_CTRL_GVI_MAX_LINKS_PER_STREAM - Returns the maximum supported number of + * links that can be tied to one stream. + */ + +#define NV_CTRL_GVI_MAX_LINKS_PER_STREAM 308 /* R--I */ + +/* + * NV_CTRL_GVI_DETECTED_CHANNEL_BITS_PER_COMPONENT - Returns the detected + * number of bits per component (BPC) of data on the given input jack+ + * channel. + * + * The jack number should be specified in the lower 16 bits of the + * "display_mask" parameter, while the channel number should be specified in + * the upper 16 bits. + */ + +#define NV_CTRL_GVI_DETECTED_CHANNEL_BITS_PER_COMPONENT 309 /* R--I */ +#define NV_CTRL_GVI_BITS_PER_COMPONENT_UNKNOWN 0 +#define NV_CTRL_GVI_BITS_PER_COMPONENT_8 1 +#define NV_CTRL_GVI_BITS_PER_COMPONENT_10 2 +#define NV_CTRL_GVI_BITS_PER_COMPONENT_12 3 + +/* + * NV_CTRL_GVI_REQUESTED_STREAM_BITS_PER_COMPONENT - Specify the number of + * bits per component (BPC) of data for the captured stream. + * The stream number should be specified in the "display_mask" parameter. + * + * Note: Setting this attribute may also result in the following + * NV-CONTROL attributes being reset on the GVI device (to ensure + * the configuration remains valid): + * NV_CTRL_GVI_REQUESTED_STREAM_COMPONENT_SAMPLING + */ + +#define NV_CTRL_GVI_REQUESTED_STREAM_BITS_PER_COMPONENT 310 /* RW-I */ + +/* + * NV_CTRL_GVI_DETECTED_CHANNEL_COMPONENT_SAMPLING - Returns the detected + * sampling format for the input jack+channel. + * + * The jack number should be specified in the lower 16 bits of the + * "display_mask" parameter, while the channel number should be specified in + * the upper 16 bits. + */ + +#define NV_CTRL_GVI_DETECTED_CHANNEL_COMPONENT_SAMPLING 311 /* R--I */ +#define NV_CTRL_GVI_COMPONENT_SAMPLING_UNKNOWN 0 +#define NV_CTRL_GVI_COMPONENT_SAMPLING_4444 1 +#define NV_CTRL_GVI_COMPONENT_SAMPLING_4224 2 +#define NV_CTRL_GVI_COMPONENT_SAMPLING_444 3 +#define NV_CTRL_GVI_COMPONENT_SAMPLING_422 4 +#define NV_CTRL_GVI_COMPONENT_SAMPLING_420 5 + +/* + * NV_CTRL_GVI_REQUESTED_COMPONENT_SAMPLING - Specify the sampling format for + * the captured stream. + * The possible values are the NV_CTRL_GVI_DETECTED_COMPONENT_SAMPLING + * constants. + * The stream number should be specified in the "display_mask" parameter. + */ + +#define NV_CTRL_GVI_REQUESTED_STREAM_COMPONENT_SAMPLING 312 /* RW-I */ + +/* + * NV_CTRL_GVI_CHROMA_EXPAND - Enable or disable 4:2:2 -> 4:4:4 chroma + * expansion for the captured stream. This value is ignored when a + * COMPONENT_SAMPLING format is selected that does not use chroma subsampling, + * or if a BITS_PER_COMPONENT value is selected that is not supported. + * The stream number should be specified in the "display_mask" parameter. + */ + +#define NV_CTRL_GVI_REQUESTED_STREAM_CHROMA_EXPAND 313 /* RW-I */ +#define NV_CTRL_GVI_CHROMA_EXPAND_FALSE 0 +#define NV_CTRL_GVI_CHROMA_EXPAND_TRUE 1 + +/* + * NV_CTRL_GVI_DETECTED_CHANNEL_COLOR_SPACE - Returns the detected color space + * of the input jack+channel. + * + * The jack number should be specified in the lower 16 bits of the + * "display_mask" parameter, while the channel number should be specified in + * the upper 16 bits. + */ + +#define NV_CTRL_GVI_DETECTED_CHANNEL_COLOR_SPACE 314 /* R--I */ +#define NV_CTRL_GVI_COLOR_SPACE_UNKNOWN 0 +#define NV_CTRL_GVI_COLOR_SPACE_GBR 1 +#define NV_CTRL_GVI_COLOR_SPACE_GBRA 2 +#define NV_CTRL_GVI_COLOR_SPACE_GBRD 3 +#define NV_CTRL_GVI_COLOR_SPACE_YCBCR 4 +#define NV_CTRL_GVI_COLOR_SPACE_YCBCRA 5 +#define NV_CTRL_GVI_COLOR_SPACE_YCBCRD 6 + +/* + * NV_CTRL_GVI_DETECTED_CHANNEL_LINK_ID - Returns the detected link identifier + * for the given input jack+channel. + * + * The jack number should be specified in the lower 16 bits of the + * "display_mask" parameter, while the channel number should be specified in + * the upper 16 bits. + */ + +#define NV_CTRL_GVI_DETECTED_CHANNEL_LINK_ID 315 /* R--I */ +#define NV_CTRL_GVI_LINK_ID_UNKNOWN 0xFFFF + +/* + * NV_CTRL_GVI_DETECTED_CHANNEL_SMPTE352_IDENTIFIER - Returns the 4-byte + * SMPTE 352 identifier from the given input jack+channel. + * + * The jack number should be specified in the lower 16 bits of the + * "display_mask" parameter, while the channel number should be specified in + * the upper 16 bits. + */ + +#define NV_CTRL_GVI_DETECTED_CHANNEL_SMPTE352_IDENTIFIER 316 /* R--I */ + +/* + * NV_CTRL_GVI_GLOBAL_IDENTIFIER - Returns a global identifier for the + * GVI device. This identifier can be used to relate GVI devices named + * in NV-CONTROL with those enumerated in OpenGL. + */ + +#define NV_CTRL_GVI_GLOBAL_IDENTIFIER 317 /* R--I */ + +/* + * NV_CTRL_FRAMELOCK_SYNC_DELAY_RESOLUTION - Returns the number of nanoseconds + * that one unit of NV_CTRL_FRAMELOCK_SYNC_DELAY corresponds to. + */ +#define NV_CTRL_FRAMELOCK_SYNC_DELAY_RESOLUTION 318 /* R-- */ + +/* + * NV_CTRL_GPU_COOLER_MANUAL_CONTROL - Query the current or set a new + * cooler control state; the value of this attribute controls the + * availability of additional cooler control attributes (see below). + * + * Note: this attribute is unavailable unless cooler control support + * has been enabled in the X server (by the user). + */ + +#define NV_CTRL_GPU_COOLER_MANUAL_CONTROL 319 /* RW-G */ +#define NV_CTRL_GPU_COOLER_MANUAL_CONTROL_FALSE 0 +#define NV_CTRL_GPU_COOLER_MANUAL_CONTROL_TRUE 1 + +/* + * NV_CTRL_THERMAL_COOLER_LEVEL - Returns cooler's current operating + * level. + */ + +#define NV_CTRL_THERMAL_COOLER_LEVEL 320 /* RW-C */ + +/* NV_CTRL_THERMAL_COOLER_LEVEL_SET_DEFAULT - Sets default values of + * cooler. + */ + +#define NV_CTRL_THERMAL_COOLER_LEVEL_SET_DEFAULT 321 /* -W-C */ + +/* + * NV_CTRL_THERMAL_COOLER_CONTROL_TYPE - + * Returns a cooler's control signal characteristics. + * The possible types are restricted, Variable and Toggle. + */ + +#define NV_CTRL_THERMAL_COOLER_CONTROL_TYPE 322 /* R--C */ +#define NV_CTRL_THERMAL_COOLER_CONTROL_TYPE_NONE 0 +#define NV_CTRL_THERMAL_COOLER_CONTROL_TYPE_TOGGLE 1 +#define NV_CTRL_THERMAL_COOLER_CONTROL_TYPE_VARIABLE 2 + +/* + * NV_CTRL_THERMAL_COOLER_TARGET - Returns objects that cooler cools. + * Targets may be GPU, Memory, Power Supply or All of these. + * GPU_RELATED = GPU | MEMORY | POWER_SUPPLY + * + */ + +#define NV_CTRL_THERMAL_COOLER_TARGET 323 /* R--C */ +#define NV_CTRL_THERMAL_COOLER_TARGET_NONE 0 +#define NV_CTRL_THERMAL_COOLER_TARGET_GPU 1 +#define NV_CTRL_THERMAL_COOLER_TARGET_MEMORY 2 +#define NV_CTRL_THERMAL_COOLER_TARGET_POWER_SUPPLY 4 +#define NV_CTRL_THERMAL_COOLER_TARGET_GPU_RELATED \ + (NV_CTRL_THERMAL_COOLER_TARGET_GPU | NV_CTRL_THERMAL_COOLER_TARGET_MEMORY | \ + NV_CTRL_THERMAL_COOLER_TARGET_POWER_SUPPLY) + +/* + * NV_CTRL_GPU_ECC_SUPPORTED - Reports whether ECC is supported by the + * targeted GPU. + */ +#define NV_CTRL_GPU_ECC_SUPPORTED 324 /* R--G */ +#define NV_CTRL_GPU_ECC_SUPPORTED_FALSE 0 +#define NV_CTRL_GPU_ECC_SUPPORTED_TRUE 1 + +/* + * NV_CTRL_GPU_ECC_STATUS - Returns the current hardware ECC setting + * for the targeted GPU. + */ +#define NV_CTRL_GPU_ECC_STATUS 325 /* R--G */ +#define NV_CTRL_GPU_ECC_STATUS_DISABLED 0 +#define NV_CTRL_GPU_ECC_STATUS_ENABLED 1 + +/* + * NV_CTRL_GPU_ECC_CONFIGURATION - Reports whether ECC can be configured + * dynamically for the GPU in question. + */ +#define NV_CTRL_GPU_ECC_CONFIGURATION_SUPPORTED 326 /* R--G */ +#define NV_CTRL_GPU_ECC_CONFIGURATION_SUPPORTED_FALSE 0 +#define NV_CTRL_GPU_ECC_CONFIGURATION_SUPPORTED_TRUE 1 + +/* + * NV_CTRL_GPU_ECC_CONFIGURATION_SETTING - Returns the current ECC + * configuration setting or specifies new settings. New settings do not + * take effect until the next POST. + */ +#define NV_CTRL_GPU_ECC_CONFIGURATION 327 /* RW-G */ +#define NV_CTRL_GPU_ECC_CONFIGURATION_DISABLED 0 +#define NV_CTRL_GPU_ECC_CONFIGURATION_ENABLED 1 + +/* + * NV_CTRL_GPU_ECC_DEFAULT_CONFIGURATION_SETTING - Returns the default + * ECC configuration setting. + */ +#define NV_CTRL_GPU_ECC_DEFAULT_CONFIGURATION 328 /* R--G */ +#define NV_CTRL_GPU_ECC_DEFAULT_CONFIGURATION_DISABLED 0 +#define NV_CTRL_GPU_ECC_DEFAULT_CONFIGURATION_ENABLED 1 + +/* + * NV_CTRL_GPU_ECC_SINGLE_BIT_ERRORS - Returns the number of single-bit + * ECC errors detected by the targeted GPU since the last POST. + * Note: this attribute is a 64-bit integer attribute. + */ +#define NV_CTRL_GPU_ECC_SINGLE_BIT_ERRORS 329 /* R--GQ */ + +/* + * NV_CTRL_GPU_ECC_DOUBLE_BIT_ERRORS - Returns the number of double-bit + * ECC errors detected by the targeted GPU since the last POST. + * Note: this attribute is a 64-bit integer attribute. + */ +#define NV_CTRL_GPU_ECC_DOUBLE_BIT_ERRORS 330 /* R--GQ */ + +/* + * NV_CTRL_GPU_ECC_AGGREGATE_SINGLE_BIT_ERRORS - Returns the number of + * single-bit ECC errors detected by the targeted GPU since the + * last counter reset. + * Note: this attribute is a 64-bit integer attribute. + */ +#define NV_CTRL_GPU_ECC_AGGREGATE_SINGLE_BIT_ERRORS 331 /* R--GQ */ + +/* + * NV_CTRL_GPU_ECC_AGGREGATE_DOUBLE_BIT_ERRORS - Returns the number of + * double-bit ECC errors detected by the targeted GPU since the + * last counter reset. + * Note: this attribute is a 64-bit integer attribute. + */ +#define NV_CTRL_GPU_ECC_AGGREGATE_DOUBLE_BIT_ERRORS 332 /* R--GQ */ + +/* + * NV_CTRL_GPU_ECC_RESET_ERROR_STATUS - Resets the volatile/aggregate + * single-bit and double-bit error counters. This attribute is a + * bitmask attribute. + */ +#define NV_CTRL_GPU_ECC_RESET_ERROR_STATUS 333 /* -W-G */ +#define NV_CTRL_GPU_ECC_RESET_ERROR_STATUS_VOLATILE 0x00000001 +#define NV_CTRL_GPU_ECC_RESET_ERROR_STATUS_AGGREGATE 0x00000002 + +/* + * NV_CTRL_GPU_POWER_MIZER_MODE - Provides a hint to the driver + * as to how to manage the performance of the GPU. + * + * ADAPTIVE - adjust GPU clocks based on GPU + * utilization + * PREFER_MAXIMUM_PERFORMANCE - raise GPU clocks to favor + * maximum performance, to the extent + * that thermal and other constraints + * allow + */ +#define NV_CTRL_GPU_POWER_MIZER_MODE 334 /* RW-G */ +#define NV_CTRL_GPU_POWER_MIZER_MODE_ADAPTIVE 0 +#define NV_CTRL_GPU_POWER_MIZER_MODE_PREFER_MAXIMUM_PERFORMANCE 1 + +/* + * NV_CTRL_GVI_SYNC_OUTPUT_FORMAT - Returns the output sync signal + * from the GVI device. + */ + +#define NV_CTRL_GVI_SYNC_OUTPUT_FORMAT 335 /* R--I */ + +/* + * NV_CTRL_GVI_MAX_CHANNELS_PER_JACK - Returns the maximum + * supported number of (logical) channels within a single physical jack of + * a GVI device. For most SDI video formats, there is only one channel + * (channel 0). But for 3G video formats (as specified in SMPTE 425), + * as an example, there are two channels (channel 0 and channel 1) per + * physical jack. + */ + +#define NV_CTRL_GVI_MAX_CHANNELS_PER_JACK 336 /* R--I */ + +/* + * NV_CTRL_GVI_MAX_STREAMS - Returns the maximum number of streams + * that can be configured on the GVI device. + */ + +#define NV_CTRL_GVI_MAX_STREAMS 337 /* R--I */ + +/* + * NV_CTRL_GVI_NUM_CAPTURE_SURFACES - The GVI interface exposed through + * NV-CONTROL and the GLX_NV_video_input extension uses internal capture + * surfaces when frames are read from the GVI device. The + * NV_CTRL_GVI_NUM_CAPTURE_SURFACES can be used to query and assign the + * number of capture surfaces. This attribute is applied when + * glXBindVideoCaptureDeviceNV() is called by the application. + * + * A lower number of capture surfaces will mean less video memory is used, + * but can result in frames being dropped if the application cannot keep up + * with the capture device. A higher number will prevent frames from being + * dropped, making capture more reliable but will consume move video memory. + */ +#define NV_CTRL_GVI_NUM_CAPTURE_SURFACES 338 /* RW-I */ + +/* + * NV_CTRL_OVERSCAN_COMPENSATION - not supported + */ +#define NV_CTRL_OVERSCAN_COMPENSATION 339 /* RWDG */ + +/* + * NV_CTRL_GPU_PCIE_GENERATION - Reports the current PCIe generation. + */ +#define NV_CTRL_GPU_PCIE_GENERATION 341 /* R--GI */ +#define NV_CTRL_GPU_PCIE_GENERATION1 0x00000001 +#define NV_CTRL_GPU_PCIE_GENERATION2 0x00000002 +#define NV_CTRL_GPU_PCIE_GENERATION3 0x00000003 + +/* + * NV_CTRL_GVI_BOUND_GPU - Returns the NV_CTRL_TARGET_TYPE_GPU target_id of + * the GPU currently bound to the GVI device. Returns -1 if no GPU is + * currently bound to the GVI device. + */ +#define NV_CTRL_GVI_BOUND_GPU 342 /* R--I */ + +/* + * NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT3 - this attribute is only + * intended to be used to query the ValidValues for + * NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT for VIDEO_FORMAT values between + * 64 and 95. See NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT for details. + */ + +#define NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT3 343 /* ---GI */ + +/* + * NV_CTRL_ACCELERATE_TRAPEZOIDS - Toggles RENDER Trapezoid acceleration + */ + +#define NV_CTRL_ACCELERATE_TRAPEZOIDS 344 /* RW- */ +#define NV_CTRL_ACCELERATE_TRAPEZOIDS_DISABLE 0 +#define NV_CTRL_ACCELERATE_TRAPEZOIDS_ENABLE 1 + +/* + * NV_CTRL_GPU_CORES - Returns number of GPU cores supported by the graphics + * pipeline. + */ + +#define NV_CTRL_GPU_CORES 345 /* R--G */ + +/* + * NV_CTRL_GPU_MEMORY_BUS_WIDTH - Returns memory bus bandwidth on the associated + * subdevice. + */ + +#define NV_CTRL_GPU_MEMORY_BUS_WIDTH 346 /* R--G */ + +/* + * NV_CTRL_GVI_TEST_MODE - This attribute controls the GVI test mode. When + * enabled, the GVI device will generate fake data as quickly as possible. All + * GVI settings are still valid when this is enabled (e.g., the requested video + * format is honored and sets the video size). + * This may be used to test the pipeline. + */ + +#define NV_CTRL_GVI_TEST_MODE 347 /* R--I */ +#define NV_CTRL_GVI_TEST_MODE_DISABLE 0 +#define NV_CTRL_GVI_TEST_MODE_ENABLE 1 + +/* + * NV_CTRL_COLOR_SPACE - This option sets color space of the video + * signal. + */ +#define NV_CTRL_COLOR_SPACE 348 /* RWDG */ +#define NV_CTRL_COLOR_SPACE_RGB 0 +#define NV_CTRL_COLOR_SPACE_YCbCr422 1 +#define NV_CTRL_COLOR_SPACE_YCbCr444 2 + +/* + * NV_CTRL_COLOR_RANGE - This option sets color range of the video + * signal. + */ +#define NV_CTRL_COLOR_RANGE 349 /* RWDG */ +#define NV_CTRL_COLOR_RANGE_FULL 0 +#define NV_CTRL_COLOR_RANGE_LIMITED 1 + +/* + * NV_CTRL_GPU_SCALING_DEFAULT_TARGET - not supported + * + * NV_CTRL_GPU_SCALING_DEFAULT_METHOD - not supported + */ +#define NV_CTRL_GPU_SCALING_DEFAULT_TARGET 350 /* R-DG */ +#define NV_CTRL_GPU_SCALING_DEFAULT_METHOD 351 /* R-DG */ + +/* + * NV_CTRL_DITHERING_MODE - Controls the dithering mode, when + * NV_CTRL_CURRENT_DITHERING is Enabled. + * + * AUTO: allow the driver to choose the dithering mode automatically. + * + * DYNAMIC_2X2: use a 2x2 matrix to dither from the GPU's pixel + * pipeline to the bit depth of the flat panel. The matrix values + * are changed from frame to frame. + * + * STATIC_2X2: use a 2x2 matrix to dither from the GPU's pixel + * pipeline to the bit depth of the flat panel. The matrix values + * do not change from frame to frame. + * + * TEMPORAL: use a pseudorandom value from a uniform distribution calculated at + * every pixel to achieve stochastic dithering. This method produces a better + * visual result than 2x2 matrix approaches. + */ +#define NV_CTRL_DITHERING_MODE 352 /* RWDG */ +#define NV_CTRL_DITHERING_MODE_AUTO 0 +#define NV_CTRL_DITHERING_MODE_DYNAMIC_2X2 1 +#define NV_CTRL_DITHERING_MODE_STATIC_2X2 2 +#define NV_CTRL_DITHERING_MODE_TEMPORAL 3 + +/* + * NV_CTRL_CURRENT_DITHERING - Returns the current dithering state. + */ +#define NV_CTRL_CURRENT_DITHERING 353 /* R-DG */ +#define NV_CTRL_CURRENT_DITHERING_DISABLED 0 +#define NV_CTRL_CURRENT_DITHERING_ENABLED 1 + +/* + * NV_CTRL_CURRENT_DITHERING_MODE - Returns the current dithering + * mode. + */ +#define NV_CTRL_CURRENT_DITHERING_MODE 354 /* R-DG */ +#define NV_CTRL_CURRENT_DITHERING_MODE_NONE 0 +#define NV_CTRL_CURRENT_DITHERING_MODE_DYNAMIC_2X2 1 +#define NV_CTRL_CURRENT_DITHERING_MODE_STATIC_2X2 2 +#define NV_CTRL_CURRENT_DITHERING_MODE_TEMPORAL 3 + +/* + * NV_CTRL_THERMAL_SENSOR_READING - Returns the thermal sensor's current + * reading. + */ +#define NV_CTRL_THERMAL_SENSOR_READING 355 /* R--S */ + +/* + * NV_CTRL_THERMAL_SENSOR_PROVIDER - Returns the hardware device that + * provides the thermal sensor. + */ +#define NV_CTRL_THERMAL_SENSOR_PROVIDER 356 /* R--S */ +#define NV_CTRL_THERMAL_SENSOR_PROVIDER_NONE 0 +#define NV_CTRL_THERMAL_SENSOR_PROVIDER_GPU_INTERNAL 1 +#define NV_CTRL_THERMAL_SENSOR_PROVIDER_ADM1032 2 +#define NV_CTRL_THERMAL_SENSOR_PROVIDER_ADT7461 3 +#define NV_CTRL_THERMAL_SENSOR_PROVIDER_MAX6649 4 +#define NV_CTRL_THERMAL_SENSOR_PROVIDER_MAX1617 5 +#define NV_CTRL_THERMAL_SENSOR_PROVIDER_LM99 6 +#define NV_CTRL_THERMAL_SENSOR_PROVIDER_LM89 7 +#define NV_CTRL_THERMAL_SENSOR_PROVIDER_LM64 8 +#define NV_CTRL_THERMAL_SENSOR_PROVIDER_G781 9 +#define NV_CTRL_THERMAL_SENSOR_PROVIDER_ADT7473 10 +#define NV_CTRL_THERMAL_SENSOR_PROVIDER_SBMAX6649 11 +#define NV_CTRL_THERMAL_SENSOR_PROVIDER_VBIOSEVT 12 +#define NV_CTRL_THERMAL_SENSOR_PROVIDER_OS 13 +#define NV_CTRL_THERMAL_SENSOR_PROVIDER_UNKNOWN 0xFFFFFFFF + +/* + * NV_CTRL_THERMAL_SENSOR_TARGET - Returns what hardware component + * the thermal sensor is measuring. + */ +#define NV_CTRL_THERMAL_SENSOR_TARGET 357 /* R--S */ +#define NV_CTRL_THERMAL_SENSOR_TARGET_NONE 0 +#define NV_CTRL_THERMAL_SENSOR_TARGET_GPU 1 +#define NV_CTRL_THERMAL_SENSOR_TARGET_MEMORY 2 +#define NV_CTRL_THERMAL_SENSOR_TARGET_POWER_SUPPLY 4 +#define NV_CTRL_THERMAL_SENSOR_TARGET_BOARD 8 +#define NV_CTRL_THERMAL_SENSOR_TARGET_UNKNOWN 0xFFFFFFFF + +/* + * NV_CTRL_SHOW_MULTIGPU_VISUAL_INDICATOR - when TRUE, OpenGL will + * draw information about the current MULTIGPU mode. + */ +#define NV_CTRL_SHOW_MULTIGPU_VISUAL_INDICATOR 358 /* RW-X */ +#define NV_CTRL_SHOW_MULTIGPU_VISUAL_INDICATOR_FALSE 0 +#define NV_CTRL_SHOW_MULTIGPU_VISUAL_INDICATOR_TRUE 1 + +/* + * NV_CTRL_GPU_CURRENT_PROCESSOR_CLOCK_FREQS - Returns GPU's processor + * clock freqs. + */ +#define NV_CTRL_GPU_CURRENT_PROCESSOR_CLOCK_FREQS 359 /* RW-G */ + +/* + * NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS - query the flags (various information + * for the specified NV_CTRL_GVIO_VIDEO_FORMAT_*. So that this can be + * queried with existing interfaces, the video format should be specified + * in the display_mask field; eg: + * + * XNVCTRLQueryTargetAttribute(dpy, + * NV_CTRL_TARGET_TYPE_GVI, + * gvi, + * NV_CTRL_GVIO_VIDEO_FORMAT_720P_60_00_SMPTE296, + * NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS, + * &flags); + * + * Note: The NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_3G_1080P_NO_12BPC flag is set + * for those 1080P 3G modes (level A and B) that do not support + * 12 bits per component (when configuring a GVI stream.) + */ + +#define NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS 360 /* R--I */ +#define NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_NONE 0x00000000 +#define NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_INTERLACED 0x00000001 +#define NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_PROGRESSIVE 0x00000002 +#define NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_PSF 0x00000004 +#define NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_3G_LEVEL_A 0x00000008 +#define NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_3G_LEVEL_B 0x00000010 +#define NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_3G \ + ((NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_3G_LEVEL_A) | (NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_3G_LEVEL_B)) +#define NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_3G_1080P_NO_12BPC 0x00000020 + +/* + * NV_CTRL_GPU_PCIE_MAX_LINK_SPEED - returns maximum PCIe link speed, + * in gigatransfers per second (GT/s). + */ + +#define NV_CTRL_GPU_PCIE_MAX_LINK_SPEED 361 /* R--GI */ + +/* + * NV_CTRL_3D_VISION_PRO_RESET_TRANSCEIVER_TO_FACTORY_SETTINGS - Resets the + * 3D Vision Pro transceiver to its factory settings. + */ +#define NV_CTRL_3D_VISION_PRO_RESET_TRANSCEIVER_TO_FACTORY_SETTINGS 363 /* -W-T */ + +/* + * NV_CTRL_3D_VISION_PRO_TRANSCEIVER_CHANNEL - Controls the channel that is + * currently used by the 3D Vision Pro transceiver. + */ +#define NV_CTRL_3D_VISION_PRO_TRANSCEIVER_CHANNEL 364 /* RW-T */ + +/* + * NV_CTRL_3D_VISION_PRO_TRANSCEIVER_MODE - Controls the mode in which the + * 3D Vision Pro transceiver operates. + * NV_CTRL_3D_VISION_PRO_TM_LOW_RANGE is bidirectional + * NV_CTRL_3D_VISION_PRO_TM_MEDIUM_RANGE is bidirectional + * NV_CTRL_3D_VISION_PRO_TM_HIGH_RANGE may be bidirectional just up to a + * given range, and unidirectional beyond it + * NV_CTRL_3D_VISION_PRO_TM_COUNT is the total number of + * 3D Vision Pro transceiver modes + */ +#define NV_CTRL_3D_VISION_PRO_TRANSCEIVER_MODE 365 /* RW-T */ +#define NV_CTRL_3D_VISION_PRO_TRANSCEIVER_MODE_INVALID 0 +#define NV_CTRL_3D_VISION_PRO_TRANSCEIVER_MODE_LOW_RANGE 1 +#define NV_CTRL_3D_VISION_PRO_TRANSCEIVER_MODE_MEDIUM_RANGE 2 +#define NV_CTRL_3D_VISION_PRO_TRANSCEIVER_MODE_HIGH_RANGE 3 +#define NV_CTRL_3D_VISION_PRO_TRANSCEIVER_MODE_COUNT 4 + +/* + * NV_CTRL_SYNCHRONOUS_PALETTE_UPDATES - controls whether updates to the color + * lookup table (LUT) are synchronous with respect to X rendering. For example, + * if an X client sends XStoreColors followed by XFillRectangle, the driver will + * guarantee that the FillRectangle request is not processed until after the + * updated LUT colors are actually visible on the screen if + * NV_CTRL_SYNCHRONOUS_PALETTE_UPDATES is enabled. Otherwise, the rendering may + * occur first. + * + * This makes a difference for applications that use the LUT to animate, such as + * XPilot. If you experience flickering in applications that use LUT + * animations, try enabling this attribute. + * + * When synchronous updates are enabled, XStoreColors requests will be processed + * at your screen's refresh rate. + */ + +#define NV_CTRL_SYNCHRONOUS_PALETTE_UPDATES 367 /* RWDG */ +#define NV_CTRL_SYNCHRONOUS_PALETTE_UPDATES_DISABLE 0 +#define NV_CTRL_SYNCHRONOUS_PALETTE_UPDATES_ENABLE 1 + +/* + * NV_CTRL_DITHERING_DEPTH - Controls the dithering depth when + * NV_CTRL_CURRENT_DITHERING is ENABLED. Some displays connected + * to the GPU via the DVI or LVDS interfaces cannot display the + * full color range of ten bits per channel, so the GPU will + * dither to either 6 or 8 bits per channel. + */ +#define NV_CTRL_DITHERING_DEPTH 368 /* RWDG */ +#define NV_CTRL_DITHERING_DEPTH_AUTO 0 +#define NV_CTRL_DITHERING_DEPTH_6_BITS 1 +#define NV_CTRL_DITHERING_DEPTH_8_BITS 2 + +/* + * NV_CTRL_CURRENT_DITHERING_DEPTH - Returns the current dithering + * depth value. + */ +#define NV_CTRL_CURRENT_DITHERING_DEPTH 369 /* R-DG */ +#define NV_CTRL_CURRENT_DITHERING_DEPTH_NONE 0 +#define NV_CTRL_CURRENT_DITHERING_DEPTH_6_BITS 1 +#define NV_CTRL_CURRENT_DITHERING_DEPTH_8_BITS 2 + +/* + * NV_CTRL_3D_VISION_PRO_TRANSCEIVER_CHANNEL_FREQUENCY - Returns the + * frequency of the channel(in kHz) of the 3D Vision Pro transceiver. + * Use the display_mask parameter to specify the channel number. + */ +#define NV_CTRL_3D_VISION_PRO_TRANSCEIVER_CHANNEL_FREQUENCY 370 /* R--T */ + +/* + * NV_CTRL_3D_VISION_PRO_TRANSCEIVER_CHANNEL_QUALITY - Returns the + * quality of the channel(in percentage) of the 3D Vision Pro transceiver. + * Use the display_mask parameter to specify the channel number. + */ +#define NV_CTRL_3D_VISION_PRO_TRANSCEIVER_CHANNEL_QUALITY 371 /* R--T */ + +/* + * NV_CTRL_3D_VISION_PRO_TRANSCEIVER_CHANNEL_COUNT - Returns the number of + * channels on the 3D Vision Pro transceiver. + */ +#define NV_CTRL_3D_VISION_PRO_TRANSCEIVER_CHANNEL_COUNT 372 /* R--T */ + +/* + * NV_CTRL_3D_VISION_PRO_PAIR_GLASSES - Puts the 3D Vision Pro + * transceiver into pairing mode to gather additional glasses. + * NV_CTRL_3D_VISION_PRO_PAIR_GLASSES_STOP - stops any pairing + * NV_CTRL_3D_VISION_PRO_PAIR_GLASSES_BEACON - starts continuous + * pairing via beacon mode + * Any other value, N - Puts the 3D Vision Pro transceiver into + * authenticated pairing mode for N seconds. + */ +#define NV_CTRL_3D_VISION_PRO_PAIR_GLASSES 373 /* -W-T */ +#define NV_CTRL_3D_VISION_PRO_PAIR_GLASSES_STOP 0 +#define NV_CTRL_3D_VISION_PRO_PAIR_GLASSES_BEACON 0xFFFFFFFF + +/* + * NV_CTRL_3D_VISION_PRO_UNPAIR_GLASSES - Tells a specific pair + * of glasses to unpair. The glasses will "forget" the address + * of the 3D Vision Pro transceiver to which they have been paired. + * To unpair all the currently paired glasses, specify + * the glasses id as 0. + */ +#define NV_CTRL_3D_VISION_PRO_UNPAIR_GLASSES 374 /* -W-T */ + +/* + * NV_CTRL_3D_VISION_PRO_DISCOVER_GLASSES - Tells the 3D Vision Pro + * transceiver about the glasses that have been paired using + * NV_CTRL_3D_VISION_PRO_PAIR_GLASSES_BEACON. Unless this is done, + * the 3D Vision Pro transceiver will not know about glasses paired in + * beacon mode. + */ +#define NV_CTRL_3D_VISION_PRO_DISCOVER_GLASSES 375 /* -W-T */ + +/* + * NV_CTRL_3D_VISION_PRO_IDENTIFY_GLASSES - Causes glasses LEDs to + * flash for a short period of time. + */ +#define NV_CTRL_3D_VISION_PRO_IDENTIFY_GLASSES 376 /* -W-T */ + +/* + * NV_CTRL_3D_VISION_PRO_GLASSES_SYNC_CYCLE - Controls the + * sync cycle duration(in milliseconds) of the glasses. + * Use the display_mask parameter to specify the glasses id. + */ +#define NV_CTRL_3D_VISION_PRO_GLASSES_SYNC_CYCLE 378 /* RW-T */ + +/* + * NV_CTRL_3D_VISION_PRO_GLASSES_MISSED_SYNC_CYCLES - Returns the + * number of state sync cycles recently missed by the glasses. + * Use the display_mask parameter to specify the glasses id. + */ +#define NV_CTRL_3D_VISION_PRO_GLASSES_MISSED_SYNC_CYCLES 379 /* R--T */ + +/* + * NV_CTRL_3D_VISION_PRO_GLASSES_BATTERY_LEVEL - Returns the + * battery level(in percentage) of the glasses. + * Use the display_mask parameter to specify the glasses id. + */ +#define NV_CTRL_3D_VISION_PRO_GLASSES_BATTERY_LEVEL 380 /* R--T */ + +/* + * NV_CTRL_GVO_ANC_PARITY_COMPUTATION - Controls the SDI device's computation + * of the parity bit (bit 8) for ANC data words. + */ + +#define NV_CTRL_GVO_ANC_PARITY_COMPUTATION 381 /* RW--- */ +#define NV_CTRL_GVO_ANC_PARITY_COMPUTATION_AUTO 0 +#define NV_CTRL_GVO_ANC_PARITY_COMPUTATION_ON 1 +#define NV_CTRL_GVO_ANC_PARITY_COMPUTATION_OFF 2 + +/* + * NV_CTRL_3D_VISION_PRO_GLASSES_PAIR_EVENT - This attribute is sent + * as an event when glasses get paired in response to pair command + * from any of the clients. + */ +#define NV_CTRL_3D_VISION_PRO_GLASSES_PAIR_EVENT 382 /* ---T */ + +/* + * NV_CTRL_3D_VISION_PRO_GLASSES_UNPAIR_EVENT - This attribute is sent + * as an event when glasses get unpaired in response to unpair command + * from any of the clients. + */ +#define NV_CTRL_3D_VISION_PRO_GLASSES_UNPAIR_EVENT 383 /* ---T */ + +/* + * NV_CTRL_GPU_PCIE_CURRENT_LINK_WIDTH - returns the current + * PCIe link width, in number of lanes. + */ +#define NV_CTRL_GPU_PCIE_CURRENT_LINK_WIDTH 384 /* R--GI */ + +/* + * NV_CTRL_GPU_PCIE_CURRENT_LINK_SPEED - returns the current + * PCIe link speed, in megatransfers per second (GT/s). + */ +#define NV_CTRL_GPU_PCIE_CURRENT_LINK_SPEED 385 /* R--GI */ + +/* + * NV_CTRL_GVO_AUDIO_BLANKING - specifies whether the GVO device should delete + * audio ancillary data packets when frames are repeated. + * + * When a new frame is not ready in time, the current frame, including all + * ancillary data packets, is repeated. When this data includes audio packets, + * this can result in stutters or clicks. When this option is enabled, the GVO + * device will detect when frames are repeated, identify audio ancillary data + * packets, and mark them for deletion. + * + * This option is applied when the GVO device is bound. + */ +#define NV_CTRL_GVO_AUDIO_BLANKING 386 /* RW- */ +#define NV_CTRL_GVO_AUDIO_BLANKING_DISABLE 0 +#define NV_CTRL_GVO_AUDIO_BLANKING_ENABLE 1 + +/* + * NV_CTRL_CURRENT_METAMODE_ID - switch modes to the MetaMode with + * the specified ID. + */ +#define NV_CTRL_CURRENT_METAMODE_ID 387 /* RW- */ + +/* + * NV_CTRL_DISPLAY_ENABLED - Returns whether or not the display device + * is currently enabled. + */ +#define NV_CTRL_DISPLAY_ENABLED 388 /* R-D */ +#define NV_CTRL_DISPLAY_ENABLED_TRUE 1 +#define NV_CTRL_DISPLAY_ENABLED_FALSE 0 + +#define NV_CTRL_LAST_ATTRIBUTE NV_CTRL_DISPLAY_ENABLED + +/**************************************************************************/ + +/* + * String Attributes: + * + * String attributes can be queryied through the XNVCTRLQueryStringAttribute() + * and XNVCTRLQueryTargetStringAttribute() function calls. + * + * String attributes can be set through the XNVCTRLSetStringAttribute() + * function call. (There are currently no string attributes that can be + * set on non-X Screen targets.) + * + * Unless otherwise noted, all string attributes can be queried/set using an + * NV_CTRL_TARGET_TYPE_X_SCREEN target. Attributes that cannot take an + * NV_CTRL_TARGET_TYPE_X_SCREEN target also cannot be queried/set through + * XNVCTRLQueryStringAttribute()/XNVCTRLSetStringAttribute() (Since + * these assume an X Screen target). + */ + +/* + * NV_CTRL_STRING_PRODUCT_NAME - the GPU product name on which the + * specified X screen is running. + * + * This attribute may be queried through XNVCTRLQueryTargetStringAttribute() + * using a NV_CTRL_TARGET_TYPE_GPU or NV_CTRL_TARGET_TYPE_X_SCREEN target. + */ + +#define NV_CTRL_STRING_PRODUCT_NAME 0 /* R--G */ + +/* + * NV_CTRL_STRING_VBIOS_VERSION - the video bios version on the GPU on + * which the specified X screen is running. + */ + +#define NV_CTRL_STRING_VBIOS_VERSION 1 /* R--G */ + +/* + * NV_CTRL_STRING_NVIDIA_DRIVER_VERSION - string representation of the + * NVIDIA driver version number for the NVIDIA X driver in use. + */ + +#define NV_CTRL_STRING_NVIDIA_DRIVER_VERSION 3 /* R--G */ + +/* + * NV_CTRL_STRING_DISPLAY_DEVICE_NAME - name of the display device + * specified in the display_mask argument. + * + * This attribute may be queried through XNVCTRLQueryTargetStringAttribute() + * using a NV_CTRL_TARGET_TYPE_GPU or NV_CTRL_TARGET_TYPE_X_SCREEN target. + */ + +#define NV_CTRL_STRING_DISPLAY_DEVICE_NAME 4 /* R-DG */ + +/* + * NV_CTRL_STRING_TV_ENCODER_NAME - name of the TV encoder used by the + * specified display device; only valid if the display device is a TV. + */ + +#define NV_CTRL_STRING_TV_ENCODER_NAME 5 /* R-DG */ + +/* + * NV_CTRL_STRING_GVIO_FIRMWARE_VERSION - indicates the version of the + * Firmware on the GVIO device. + */ + +#define NV_CTRL_STRING_GVIO_FIRMWARE_VERSION 8 /* R--I */ + +/* + * The following is deprecated; use NV_CTRL_STRING_GVIO_FIRMWARE_VERSION, + * instead + */ +#define NV_CTRL_STRING_GVO_FIRMWARE_VERSION 8 /* R-- */ + +/* + * NV_CTRL_STRING_CURRENT_MODELINE - Return the ModeLine currently + * being used by the specified display device. + * + * This attribute may be queried through XNVCTRLQueryTargetStringAttribute() + * using an NV_CTRL_TARGET_TYPE_GPU or NV_CTRL_TARGET_TYPE_X_SCREEN target. + * + * The ModeLine string may be prepended with a comma-separated list of + * "token=value" pairs, separated from the ModeLine string by "::". + * This "token=value" syntax is the same as that used in + * NV_CTRL_BINARY_DATA_MODELINES + */ + +#define NV_CTRL_STRING_CURRENT_MODELINE 9 /* R-DG */ + +/* + * NV_CTRL_STRING_ADD_MODELINE - Adds a ModeLine to the specified + * display device. The ModeLine is not added if validation fails. + * + * The ModeLine string should have the same syntax as a ModeLine in + * the X configuration file; e.g., + * + * "1600x1200" 229.5 1600 1664 1856 2160 1200 1201 1204 1250 +HSync +VSync + */ + +#define NV_CTRL_STRING_ADD_MODELINE 10 /* -WDG */ + +/* + * NV_CTRL_STRING_DELETE_MODELINE - Deletes an existing ModeLine + * from the specified display device. The currently selected + * ModeLine cannot be deleted. (This also means you cannot delete + * the last ModeLine.) + * + * The ModeLine string should have the same syntax as a ModeLine in + * the X configuration file; e.g., + * + * "1600x1200" 229.5 1600 1664 1856 2160 1200 1201 1204 1250 +HSync +VSync + */ + +#define NV_CTRL_STRING_DELETE_MODELINE 11 /* -WDG */ + +/* + * NV_CTRL_STRING_CURRENT_METAMODE - Returns the metamode currently + * being used by the specified X screen. The MetaMode string has the + * same syntax as the MetaMode X configuration option, as documented + * in the NVIDIA driver README. + * + * The returned string may be prepended with a comma-separated list of + * "token=value" pairs, separated from the MetaMode string by "::". + * This "token=value" syntax is the same as that used in + * NV_CTRL_BINARY_DATA_METAMODES. + */ + +#define NV_CTRL_STRING_CURRENT_METAMODE 12 /* RW-- */ +#define NV_CTRL_STRING_CURRENT_METAMODE_VERSION_1 NV_CTRL_STRING_CURRENT_METAMODE + +/* + * NV_CTRL_STRING_ADD_METAMODE - Adds a MetaMode to the specified + * X Screen. + * + * It is recommended to not use this attribute, but instead use + * NV_CTRL_STRING_OPERATION_ADD_METAMODE. + */ + +#define NV_CTRL_STRING_ADD_METAMODE 13 /* -W-- */ + +/* + * NV_CTRL_STRING_DELETE_METAMODE - Deletes an existing MetaMode from + * the specified X Screen. The currently selected MetaMode cannot be + * deleted. (This also means you cannot delete the last MetaMode). + * The MetaMode string should have the same syntax as the MetaMode X + * configuration option, as documented in the NVIDIA driver README. + */ + +#define NV_CTRL_STRING_DELETE_METAMODE 14 /* -WD-- */ + +/* + * NV_CTRL_STRING_VCSC_PRODUCT_NAME - Querys the product name of the + * VCSC device. + * + * This attribute must be queried through XNVCTRLQueryTargetStringAttribute() + * using a NV_CTRL_TARGET_TYPE_VCSC target. + */ + +#define NV_CTRL_STRING_VCSC_PRODUCT_NAME 15 /* R---V */ + +/* + * NV_CTRL_STRING_VCSC_PRODUCT_ID - Querys the product ID of the VCSC device. + * + * This attribute must be queried through XNVCTRLQueryTargetStringAttribute() + * using a NV_CTRL_TARGET_TYPE_VCSC target. + */ + +#define NV_CTRL_STRING_VCSC_PRODUCT_ID 16 /* R---V */ + +/* + * NV_CTRL_STRING_VCSC_SERIAL_NUMBER - Querys the unique serial number + * of the VCS device. + * + * This attribute must be queried through XNVCTRLQueryTargetStringAttribute() + * using a NV_CTRL_TARGET_TYPE_VCSC target. + */ + +#define NV_CTRL_STRING_VCSC_SERIAL_NUMBER 17 /* R---V */ + +/* + * NV_CTRL_STRING_VCSC_BUILD_DATE - Querys the date of the VCS device. + * the returned string is in the following format: "Week.Year" + * + * This attribute must be queried through XNVCTRLQueryTargetStringAttribute() + * using a NV_CTRL_TARGET_TYPE_VCSC target. + */ + +#define NV_CTRL_STRING_VCSC_BUILD_DATE 18 /* R---V */ + +/* + * NV_CTRL_STRING_VCSC_FIRMWARE_VERSION - Querys the firmware version + * of the VCS device. + * + * This attribute must be queried through XNVCTRLQueryTargetStringAttribute() + * using a NV_CTRL_TARGET_TYPE_VCSC target. + */ + +#define NV_CTRL_STRING_VCSC_FIRMWARE_VERSION 19 /* R---V */ + +/* + * NV_CTRL_STRING_VCSC_FIRMWARE_REVISION - Querys the firmware revision + * of the VCS device. + * + * This attribute must be queried through XNVCTRLQueryTargetStringAttribute() + * using a NV_CTRL_TARGET_TYPE_VCS target. + */ + +#define NV_CTRL_STRING_VCSC_FIRMWARE_REVISION 20 /* R---V */ + +/* + * NV_CTRL_STRING_VCSC_HARDWARE_VERSION - Querys the hardware version + * of the VCS device. + * + * This attribute must be queried through XNVCTRLQueryTargetStringAttribute() + * using a NV_CTRL_TARGET_TYPE_VCSC target. + */ + +#define NV_CTRL_STRING_VCSC_HARDWARE_VERSION 21 /* R---V */ + +/* + * NV_CTRL_STRING_VCSC_HARDWARE_REVISION - Querys the hardware revision + * of the VCS device. + * + * This attribute must be queried through XNVCTRLQueryTargetStringAttribute() + * using a NV_CTRL_TARGET_TYPE_VCSC target. + */ + +#define NV_CTRL_STRING_VCSC_HARDWARE_REVISION 22 /* R---V */ + +/* + * NV_CTRL_STRING_MOVE_METAMODE - Moves a MetaMode to the specified + * index location. The MetaMode must already exist in the X Screen's + * list of MetaModes (as returned by the NV_CTRL_BINARY_DATA_METAMODES + * attribute). If the index is larger than the number of MetaModes in + * the list, the MetaMode is moved to the end of the list. The + * MetaMode string should have the same syntax as the MetaMode X + * configuration option, as documented in the NVIDIA driver README. + + * The MetaMode string must be prepended with a comma-separated list + * of "token=value" pairs, separated from the MetaMode string by "::". + * Currently, the only valid token is "index", which indicates where + * in the MetaMode list the MetaMode should be moved to. + * + * Other tokens may be added in the future. + * + * E.g., + * "index=5 :: CRT-0: 1024x768 @1024x768 +0+0" + */ + +#define NV_CTRL_STRING_MOVE_METAMODE 23 /* -W-- */ + +/* + * NV_CTRL_STRING_VALID_HORIZ_SYNC_RANGES - returns the valid + * horizontal sync ranges used to perform mode validation for the + * specified display device. The ranges are in the same format as the + * "HorizSync" X config option: + * + * "horizsync-range may be a comma separated list of either discrete + * values or ranges of values. A range of values is two values + * separated by a dash." + * + * The values are in kHz. + * + * Additionally, the string may be prepended with a comma-separated + * list of "token=value" pairs, separated from the HorizSync string by + * "::". Valid tokens: + * + * Token Value + * "source" "edid" - HorizSync is from the display device's EDID + * "xconfig" - HorizSync is from the "HorizSync" entry in + * the Monitor section of the X config file + * "option" - HorizSync is from the "HorizSync" NVIDIA X + * config option + * "twinview" - HorizSync is from the "SecondMonitorHorizSync" + * NVIDIA X config option + * "builtin" - HorizSync is from NVIDIA X driver builtin + * default values + * + * Additional tokens and/or values may be added in the future. + * + * Example: "source=edid :: 30.000-62.000" + */ + +#define NV_CTRL_STRING_VALID_HORIZ_SYNC_RANGES 24 /* R-DG */ + +/* + * NV_CTRL_STRING_VALID_VERT_REFRESH_RANGES - returns the valid + * vertical refresh ranges used to perform mode validation for the + * specified display device. The ranges are in the same format as the + * "VertRefresh" X config option: + * + * "vertrefresh-range may be a comma separated list of either discrete + * values or ranges of values. A range of values is two values + * separated by a dash." + * + * The values are in Hz. + * + * Additionally, the string may be prepended with a comma-separated + * list of "token=value" pairs, separated from the VertRefresh string by + * "::". Valid tokens: + * + * Token Value + * "source" "edid" - VertRefresh is from the display device's EDID + * "xconfig" - VertRefresh is from the "VertRefresh" entry in + * the Monitor section of the X config file + * "option" - VertRefresh is from the "VertRefresh" NVIDIA X + * config option + * "twinview" - VertRefresh is from the "SecondMonitorVertRefresh" + * NVIDIA X config option + * "builtin" - VertRefresh is from NVIDIA X driver builtin + * default values + * + * Additional tokens and/or values may be added in the future. + * + * Example: "source=edid :: 50.000-75.000" + */ + +#define NV_CTRL_STRING_VALID_VERT_REFRESH_RANGES 25 /* R-DG */ + +/* + * NV_CTRL_STRING_XINERAMA_SCREEN_INFO - returns the physical X Screen's + * initial position and size (in absolute coordinates) within the Xinerama + * desktop as the "token=value" string: "x=#, y=#, width=#, height=#" + * + * Querying this attribute returns FALSE if NV_CTRL_XINERAMA is not + * NV_CTRL_XINERAMA_ON. + */ + +#define NV_CTRL_STRING_XINERAMA_SCREEN_INFO 26 /* R--- */ + +/* + * NV_CTRL_STRING_TWINVIEW_XINERAMA_INFO_ORDER - used to specify the + * order that display devices will be returned via Xinerama when + * nvidiaXineramaInfo is enabled. Follows the same syntax as the + * nvidiaXineramaInfoOrder X config option. + */ + +#define NV_CTRL_STRING_NVIDIA_XINERAMA_INFO_ORDER 27 /* RW-- */ + +#define NV_CTRL_STRING_TWINVIEW_XINERAMA_INFO_ORDER \ + NV_CTRL_STRING_NVIDIA_XINERAMA_INFO_ORDER /* for backwards compatibility: */ + +/* + * NV_CTRL_STRING_SLI_MODE - returns a string describing the current + * SLI mode, if any, or FALSE if SLI is not currently enabled. + * + * This string should be used for informational purposes only, and + * should not be used to distinguish between SLI modes, other than to + * recognize when SLI is disabled (FALSE is returned) or + * enabled (the returned string is non-NULL and describes the current + * SLI configuration). + */ + +#define NV_CTRL_STRING_SLI_MODE 28 /* R---*/ + +/* + * NV_CTRL_STRING_PERFORMANCE_MODES - returns a string with all the + * performance modes defined for this GPU along with their associated + * NV Clock and Memory Clock values. + * + * Each performance modes are returned as a comma-separated list of + * "token=value" pairs. Each set of performance mode tokens are separated + * by a ";". Valid tokens: + * + * Token Value + * "perf" integer - the Performance level + * "nvclock" integer - the GPU clocks (in MHz) for the perf level + * "memclock" integer - the memory clocks (in MHz) for the perf level + * + * + * Example: + * + * perf=0, nvclock=500, memclock=505 ; perf=1, nvclock=650, memclock=505 + * + * This attribute may be queried through XNVCTRLQueryTargetStringAttribute() + * using a NV_CTRL_TARGET_TYPE_GPU or NV_CTRL_TARGET_TYPE_X_SCREEN target. + */ + +#define NV_CTRL_STRING_PERFORMANCE_MODES 29 /* R--G */ + +/* + * NV_CTRL_STRING_VCSC_FAN_STATUS - returns a string with status of all the + * fans in the Visual Computing System, if such a query is supported. Fan + * information is reported along with its tachometer reading (in RPM) and a + * flag indicating whether the fan has failed or not. + * + * Valid tokens: + * + * Token Value + * "fan" integer - the Fan index + * "speed" integer - the tachometer reading of the fan in rpm + * "fail" integer - flag to indicate whether the fan has failed + * + * Example: + * + * fan=0, speed=694, fail=0 ; fan=1, speed=693, fail=0 + * + * This attribute must be queried through XNVCTRLQueryTargetStringAttribute() + * using a NV_CTRL_TARGET_TYPE_VCSC target. + * + */ + +#define NV_CTRL_STRING_VCSC_FAN_STATUS 30 /* R---V */ + +/* + * NV_CTRL_STRING_VCSC_TEMPERATURES - returns a string with all Temperature + * readings in the Visual Computing System, if such a query is supported. + * Intake, Exhaust and Board Temperature values are reported in Celcius. + * + * Valid tokens: + * + * Token Value + * "intake" integer - the intake temperature for the VCS + * "exhaust" integer - the exhaust temperature for the VCS + * "board" integer - the board temperature of the VCS + * + * Example: + * + * intake=29, exhaust=46, board=41 + * + * This attribute must be queried through XNVCTRLQueryTargetStringAttribute() + * using a NV_CTRL_TARGET_TYPE_VCSC target. + * + */ + +#define NV_CTRL_STRING_VCSC_TEMPERATURES 31 /* R---V */ + +/* + * NV_CTRL_STRING_VCSC_PSU_INFO - returns a string with all Power Supply Unit + * related readings in the Visual Computing System, if such a query is + * supported. Current in amperes, Power in watts, Voltage in volts and PSU + * state may be reported. Not all PSU types support all of these values, and + * therefore some readings may be unknown. + * + * Valid tokens: + * + * Token Value + * "current" integer - the current drawn in amperes by the VCS + * "power" integer - the power drawn in watts by the VCS + * "voltage" integer - the voltage reading of the VCS + * "state" integer - flag to indicate whether PSU is operating normally + * + * Example: + * + * current=10, power=15, voltage=unknown, state=normal + * + * This attribute must be queried through XNVCTRLQueryTargetStringAttribute() + * using a NV_CTRL_TARGET_TYPE_VCSC target. + * + */ + +#define NV_CTRL_STRING_VCSC_PSU_INFO 32 /* R---V */ + +/* + * NV_CTRL_STRING_GVIO_VIDEO_FORMAT_NAME - query the name for the specified + * NV_CTRL_GVIO_VIDEO_FORMAT_*. So that this can be queried with existing + * interfaces, XNVCTRLQueryStringAttribute() should be used, and the video + * format specified in the display_mask field; eg: + * + * XNVCTRLQueryStringAttribute(dpy, + * screen, + * NV_CTRL_GVIO_VIDEO_FORMAT_720P_60_00_SMPTE296, + * NV_CTRL_GVIO_VIDEO_FORMAT_NAME, + * &name); + */ + +#define NV_CTRL_STRING_GVIO_VIDEO_FORMAT_NAME 33 /* R--GI */ + +/* + * The following is deprecated; use NV_CTRL_STRING_GVIO_VIDEO_FORMAT_NAME, + * instead + */ +#define NV_CTRL_STRING_GVO_VIDEO_FORMAT_NAME 33 /* R--- */ + +/* + * NV_CTRL_STRING_GPU_CURRENT_CLOCK_FREQS - returns a string with the + * associated NV Clock, Memory Clock and Processor Clock values. + * + * Current valid tokens are "nvclock", "memclock", and "processorclock". + * Not all tokens will be reported on all GPUs, and additional tokens + * may be added in the future. + * + * Clock values are returned as a comma-separated list of + * "token=value" pairs. + * Valid tokens: + * + * Token Value + * "nvclock" integer - the GPU clocks (in MHz) for the current + * perf level + * "memclock" integer - the memory clocks (in MHz) for the current + * perf level + * "processorclock" integer - the processor clocks (in MHz) for the perf level + * + * + * Example: + * + * nvclock=459, memclock=400, processorclock=918 + * + * This attribute may be queried through XNVCTRLQueryTargetStringAttribute() + * using an NV_CTRL_TARGET_TYPE_GPU or NV_CTRL_TARGET_TYPE_X_SCREEN target. + */ + +#define NV_CTRL_STRING_GPU_CURRENT_CLOCK_FREQS 34 /* RW-G */ + +/* + * NV_CTRL_STRING_3D_VISION_PRO_TRANSCEIVER_HARDWARE_REVISION - Returns the + * hardware revision of the 3D Vision Pro transceiver. + */ +#define NV_CTRL_STRING_3D_VISION_PRO_TRANSCEIVER_HARDWARE_REVISION 35 /* R--T */ + +/* + * NV_CTRL_STRING_3D_VISION_PRO_TRANSCEIVER_FIRMWARE_VERSION_A - Returns the + * firmware version of chip A of the 3D Vision Pro transceiver. + */ +#define NV_CTRL_STRING_3D_VISION_PRO_TRANSCEIVER_FIRMWARE_VERSION_A 36 /* R--T */ + +/* + * NV_CTRL_STRING_3D_VISION_PRO_TRANSCEIVER_FIRMWARE_DATE_A - Returns the + * date of the firmware of chip A of the 3D Vision Pro transceiver. + */ +#define NV_CTRL_STRING_3D_VISION_PRO_TRANSCEIVER_FIRMWARE_DATE_A 37 /* R--T */ + +/* + * NV_CTRL_STRING_3D_VISION_PRO_TRANSCEIVER_FIRMWARE_VERSION_B - Returns the + * firmware version of chip B of the 3D Vision Pro transceiver. + */ +#define NV_CTRL_STRING_3D_VISION_PRO_TRANSCEIVER_FIRMWARE_VERSION_B 38 /* R--T */ + +/* + * NV_CTRL_STRING_3D_VISION_PRO_TRANSCEIVER_FIRMWARE_DATE_B - Returns the + * date of the firmware of chip B of the 3D Vision Pro transceiver. + */ +#define NV_CTRL_STRING_3D_VISION_PRO_TRANSCEIVER_FIRMWARE_DATE_B 39 /* R--T */ + +/* + * NV_CTRL_STRING_3D_VISION_PRO_TRANSCEIVER_ADDRESS - Returns the RF address + * of the 3D Vision Pro transceiver. + */ +#define NV_CTRL_STRING_3D_VISION_PRO_TRANSCEIVER_ADDRESS 40 /* R--T */ + +/* + * NV_CTRL_STRING_3D_VISION_PRO_GLASSES_FIRMWARE_VERSION_A - Returns the + * firmware version of chip A of the glasses. + * Use the display_mask parameter to specify the glasses id. + */ +#define NV_CTRL_STRING_3D_VISION_PRO_GLASSES_FIRMWARE_VERSION_A 41 /* R--T */ + +/* + * NV_CTRL_STRING_3D_VISION_PRO_GLASSES_FIRMWARE_DATE_A - Returns the + * date of the firmware of chip A of the glasses. + * Use the display_mask parameter to specify the glasses id. + */ +#define NV_CTRL_STRING_3D_VISION_PRO_GLASSES_FIRMWARE_DATE_A 42 /* R--T */ + +/* + * NV_CTRL_STRING_3D_VISION_PRO_GLASSES_ADDRESS - Returns the RF address + * of the glasses. + * Use the display_mask parameter to specify the glasses id. + */ +#define NV_CTRL_STRING_3D_VISION_PRO_GLASSES_ADDRESS 43 /* R--T */ + +/* + * NV_CTRL_STRING_3D_VISION_PRO_GLASSES_NAME - Controls the name the + * glasses should use. + * Use the display_mask parameter to specify the glasses id. + * Glasses' name should start and end with an alpha-numeric character. + */ +#define NV_CTRL_STRING_3D_VISION_PRO_GLASSES_NAME 44 /* RW-T */ + +/* + * NV_CTRL_STRING_CURRENT_METAMODE_VERSION_2 - Returns the metamode currently + * being used by the specified X screen. The MetaMode string has the same + * syntax as the MetaMode X configuration option, as documented in the NVIDIA + * driver README. Also, see NV_CTRL_BINARY_DATA_METAMODES_VERSION_2 for more + * details on the base syntax. + * + * The returned string may also be prepended with a comma-separated list of + * "token=value" pairs, separated from the MetaMode string by "::". + */ +#define NV_CTRL_STRING_CURRENT_METAMODE_VERSION_2 45 /* RW-- */ + +/* + * NV_CTRL_STRING_DISPLAY_NAME_TYPE_BASENAME - Returns a type name for the + * display device ("CRT", "DFP", or "TV"). However, note that the determination + * of the name is based on the protocol through which the X driver communicates + * to the display device. E.g., if the driver communicates using VGA ,then the + * basename is "CRT"; if the driver communicates using TMDS, LVDS, or DP, then + * the name is "DFP". + */ +#define NV_CTRL_STRING_DISPLAY_NAME_TYPE_BASENAME 46 /* R-D- */ + +/* + * NV_CTRL_STRING_DISPLAY_NAME_TYPE_ID - Returns the type-based name + ID for + * the display device, e.g. "CRT-0", "DFP-1", "TV-2". If this device is a + * DisplayPort 1.2 device, then this name will also be prepended with the + * device's port address like so: "DFP-1.0.1.2.3". See + * NV_CTRL_STRING_DISPLAY_NAME_TYPE_BASENAME for more information about the + * construction of type-based names. + */ +#define NV_CTRL_STRING_DISPLAY_NAME_TYPE_ID 47 /* R-D- */ + +/* + * NV_CTRL_STRING_DISPLAY_NAME_DP_GUID - Returns the GUID of the DisplayPort + * display device. e.g. "DP-GUID-f16a5bde-79f3-11e1-b2ae-8b5a8969ba9c" + * + * The display device must be a DisplayPort 1.2 device. + */ +#define NV_CTRL_STRING_DISPLAY_NAME_DP_GUID 48 /* R-D- */ + +/* + * NV_CTRL_STRING_DISPLAY_NAME_EDID_HASH - Returns the SHA-1 hash of the + * display device's EDID in 8-4-4-4-12 UID format. e.g. + * "DPY-EDID-f16a5bde-79f3-11e1-b2ae-8b5a8969ba9c" + * + * The display device must have a valid EDID. + */ +#define NV_CTRL_STRING_DISPLAY_NAME_EDID_HASH 49 /* R-D- */ + +/* + * NV_CTRL_STRING_DISPLAY_NAME_TARGET_INDEX - Returns the current NV-CONTROL + * target ID (name) of the display device. e.g. "DPY-1", "DPY-4" + * + * This name for the display device is not guarenteed to be the same between + * different runs of the X server. + */ +#define NV_CTRL_STRING_DISPLAY_NAME_TARGET_INDEX 50 /* R-D- */ + +/* + * NV_CTRL_STRING_DISPLAY_NAME_RANDR - Returns the RandR output name for the + * display device. e.g. "VGA-1", "DVI-I-0", "DVI-D-3", "LVDS-1", "DP-2", + * "HDMI-3", "eDP-6". This name should match If this device is a DisplayPort + * 1.2 device, then this name will also be prepended with the device's port + * address like so: "DVI-I-3.0.1.2.3" + */ +#define NV_CTRL_STRING_DISPLAY_NAME_RANDR 51 /* R-D- */ + +#define NV_CTRL_STRING_LAST_ATTRIBUTE NV_CTRL_STRING_DISPLAY_NAME_RANDR + +/**************************************************************************/ + +/* + * Binary Data Attributes: + * + * Binary data attributes can be queryied through the XNVCTRLQueryBinaryData() + * and XNVCTRLQueryTargetBinaryData() function calls. + * + * There are currently no binary data attributes that can be set. + * + * Unless otherwise noted, all Binary data attributes can be queried + * using an NV_CTRL_TARGET_TYPE_X_SCREEN target. Attributes that cannot take + * an NV_CTRL_TARGET_TYPE_X_SCREEN target also cannot be queried through + * XNVCTRLQueryBinaryData() (Since an X Screen target is assumed). + */ + +/* + * NV_CTRL_BINARY_DATA_EDID - Returns a display device's EDID information + * data. + * + * This attribute may be queried through XNVCTRLQueryTargetBinaryData() + * using a NV_CTRL_TARGET_TYPE_GPU or NV_CTRL_TARGET_TYPE_X_SCREEN target. + */ + +#define NV_CTRL_BINARY_DATA_EDID 0 /* R-DG */ + +/* + * NV_CTRL_BINARY_DATA_MODELINES - Returns a display device's supported + * ModeLines. ModeLines are returned in a buffer, separated by a single + * '\0' and terminated by two consecutive '\0' s like so: + * + * "ModeLine 1\0ModeLine 2\0ModeLine 3\0Last ModeLine\0\0" + * + * This attribute may be queried through XNVCTRLQueryTargetBinaryData() + * using a NV_CTRL_TARGET_TYPE_GPU or NV_CTRL_TARGET_TYPE_X_SCREEN target. + * + * Each ModeLine string may be prepended with a comma-separated list + * of "token=value" pairs, separated from the ModeLine string with a + * "::". Valid tokens: + * + * Token Value + * "source" "xserver" - the ModeLine is from the core X server + * "xconfig" - the ModeLine was specified in the X config file + * "builtin" - the NVIDIA driver provided this builtin ModeLine + * "vesa" - this is a VESA standard ModeLine + * "edid" - the ModeLine was in the display device's EDID + * "nv-control" - the ModeLine was specified via NV-CONTROL + * + * "xconfig-name" - for ModeLines that were specified in the X config + * file, this is the name the X config file + * gave for the ModeLine. + * + * Note that a ModeLine can have several sources; the "source" token + * can appear multiple times in the "token=value" pairs list. + * Additional source values may be specified in the future. + * + * Additional tokens may be added in the future, so it is recommended + * that any token parser processing the returned string from + * NV_CTRL_BINARY_DATA_MODELINES be implemented to gracefully ignore + * unrecognized tokens. + * + * E.g., + * + * "source=xserver, source=vesa, source=edid :: "1024x768_70" 75.0 1024 1048 1184 1328 768 771 + * 777 806 -HSync -VSync" + * "source=xconfig, xconfig-name=1600x1200_60.00 :: "1600x1200_60_0" 161.0 1600 1704 1880 2160 + * 1200 1201 1204 1242 -HSync +VSync" + */ + +#define NV_CTRL_BINARY_DATA_MODELINES 1 /* R-DG */ + +/* + * NV_CTRL_BINARY_DATA_METAMODES - Returns an X Screen's supported + * MetaModes. MetaModes are returned in a buffer separated by a + * single '\0' and terminated by two consecutive '\0' s like so: + * + * "MetaMode 1\0MetaMode 2\0MetaMode 3\0Last MetaMode\0\0" + * + * The MetaMode string should have the same syntax as the MetaMode X + * configuration option, as documented in the NVIDIA driver README. + + * Each MetaMode string may be prepended with a comma-separated list + * of "token=value" pairs, separated from the MetaMode string with + * "::". Currently, valid tokens are: + * + * Token Value + * "id" - the id of this MetaMode; this is stored in + * the Vertical Refresh field, as viewed + * by the XRandR and XF86VidMode X * + * extensions. + * + * "switchable" "yes"/"no" - whether this MetaMode may be switched to via + * ctrl-alt-+/-; Implicit MetaModes (see + * the "IncludeImplicitMetaModes" X + * config option), for example, are not + * normally made available through + * ctrl-alt-+/-. + * + * "source" "xconfig" - the MetaMode was specified in the X + * config file. + * "implicit" - the MetaMode was implicitly added; see the + * "IncludeImplicitMetaModes" X config option + * for details. + * "nv-control" - the MetaMode was added via the NV-CONTROL X + * extension to the currently running X server. + * "RandR" - the MetaMode was modified in response to an + * RandR RRSetCrtcConfig request. + * + * Additional tokens may be added in the future, so it is recommended + * that any token parser processing the returned string from + * NV_CTRL_BINARY_DATA_METAMODES be implemented to gracefully ignore + * unrecognized tokens. + * + * E.g., + * + * "id=50, switchable=yes, source=xconfig :: CRT-0: 1024x768 @1024x768 +0+0" + */ + +#define NV_CTRL_BINARY_DATA_METAMODES 2 /* R-D- */ +#define NV_CTRL_BINARY_DATA_METAMODES_VERSION_1 NV_CTRL_BINARY_DATA_METAMODES + +/* + * NV_CTRL_BINARY_DATA_XSCREENS_USING_GPU - Returns the list of X + * screens currently driven by the given GPU. + * + * The format of the returned data is: + * + * 4 CARD32 number of screens + * 4 * n CARD32 screen indices + * + * This attribute can only be queried through XNVCTRLQueryTargetBinaryData() + * using a NV_CTRL_TARGET_TYPE_GPU target. This attribute cannot be + * queried using a NV_CTRL_TARGET_TYPE_X_SCREEN. + */ + +#define NV_CTRL_BINARY_DATA_XSCREENS_USING_GPU 3 /* R-DG */ + +/* + * NV_CTRL_BINARY_DATA_GPUS_USED_BY_XSCREEN - Returns the list of GPUs + * currently in use by the given X screen. + * + * The format of the returned data is: + * + * 4 CARD32 number of GPUs + * 4 * n CARD32 GPU indices + */ + +#define NV_CTRL_BINARY_DATA_GPUS_USED_BY_XSCREEN 4 /* R--- */ + +/* + * NV_CTRL_BINARY_DATA_GPUS_USING_FRAMELOCK - Returns the list of + * GPUs currently connected to the given frame lock board. + * + * The format of the returned data is: + * + * 4 CARD32 number of GPUs + * 4 * n CARD32 GPU indices + * + * This attribute can only be queried through XNVCTRLQueryTargetBinaryData() + * using a NV_CTRL_TARGET_TYPE_FRAMELOCK target. This attribute cannot be + * queried using a NV_CTRL_TARGET_TYPE_X_SCREEN. + */ + +#define NV_CTRL_BINARY_DATA_GPUS_USING_FRAMELOCK 5 /* R-DF */ + +/* + * NV_CTRL_BINARY_DATA_DISPLAY_VIEWPORT - Returns the Display Device's + * viewport box into the given X Screen (in X Screen coordinates.) + * + * The format of the returned data is: + * + * 4 CARD32 Offset X + * 4 CARD32 Offset Y + * 4 CARD32 Width + * 4 CARD32 Height + */ + +#define NV_CTRL_BINARY_DATA_DISPLAY_VIEWPORT 6 /* R-DG */ + +/* + * NV_CTRL_BINARY_DATA_FRAMELOCKS_USED_BY_GPU - Returns the list of + * Framelock devices currently connected to the given GPU. + * + * The format of the returned data is: + * + * 4 CARD32 number of Framelocks + * 4 * n CARD32 Framelock indices + * + * This attribute can only be queried through XNVCTRLQueryTargetBinaryData() + * using a NV_CTRL_TARGET_TYPE_GPU target. This attribute cannot be + * queried using a NV_CTRL_TARGET_TYPE_X_SCREEN. + */ + +#define NV_CTRL_BINARY_DATA_FRAMELOCKS_USED_BY_GPU 7 /* R-DG */ + +/* + * NV_CTRL_BINARY_DATA_GPUS_USING_VCSC - Returns the list of + * GPU devices connected to the given VCS. + * + * The format of the returned data is: + * + * 4 CARD32 number of GPUs + * 4 * n CARD32 GPU indices + * + * This attribute can only be queried through XNVCTRLQueryTargetBinaryData() + * using a NV_CTRL_TARGET_TYPE_VCSC target. This attribute cannot be + * queried using a NV_CTRL_TARGET_TYPE_X_SCREEN and cannot be queried using + * a NV_CTRL_TARGET_TYPE_X_GPU + */ + +#define NV_CTRL_BINARY_DATA_GPUS_USING_VCSC 8 /* R-DV */ + +/* + * NV_CTRL_BINARY_DATA_VCSCS_USED_BY_GPU - Returns the VCSC device + * that is controlling the given GPU. + * + * The format of the returned data is: + * + * 4 CARD32 number of VCS (always 1) + * 4 * n CARD32 VCS indices + * + * This attribute can only be queried through XNVCTRLQueryTargetBinaryData() + * using a NV_CTRL_TARGET_TYPE_GPU target. This attribute cannot be + * queried using a NV_CTRL_TARGET_TYPE_X_SCREEN + */ + +#define NV_CTRL_BINARY_DATA_VCSCS_USED_BY_GPU 9 /* R-DG */ + +/* + * NV_CTRL_BINARY_DATA_COOLERS_USED_BY_GPU - Returns the coolers that + * are cooling the given GPU. + * + * The format of the returned data is: + * + * 4 CARD32 number of COOLER + * 4 * n CARD32 COOLER indices + * + * This attribute can only be queried through XNVCTRLQueryTargetBinaryData() + * using a NV_CTRL_TARGET_TYPE_GPU target. This attribute cannot be + * queried using a NV_CTRL_TARGET_TYPE_X_SCREEN + */ + +#define NV_CTRL_BINARY_DATA_COOLERS_USED_BY_GPU 10 /* R-DG */ + +/* + * NV_CTRL_BINARY_DATA_GPUS_USED_BY_LOGICAL_XSCREEN - Returns the list of + * GPUs currently driving the given X screen. If Xinerama is enabled, this + * will return all GPUs that are driving any X screen. + * + * The format of the returned data is: + * + * 4 CARD32 number of GPUs + * 4 * n CARD32 GPU indices + */ + +#define NV_CTRL_BINARY_DATA_GPUS_USED_BY_LOGICAL_XSCREEN 11 /* R--- */ + +/* + * NV_CTRL_BINARY_DATA_THERMAL_SENSORS_USED_BY_GPU - Returns the sensors that + * are attached to the given GPU. + * + * The format of the returned data is: + * + * 4 CARD32 number of SENSOR + * 4 * n CARD32 SENSOR indices + * + * This attribute can only be queried through XNVCTRLQueryTargetBinaryData() + * using a NV_CTRL_TARGET_TYPE_GPU target. This attribute cannot be + * queried using a NV_CTRL_TARGET_TYPE_X_SCREEN + */ + +#define NV_CTRL_BINARY_DATA_THERMAL_SENSORS_USED_BY_GPU 12 /* R--G */ + +/* + * NV_CTRL_BINARY_DATA_GLASSES_PAIRED_TO_3D_VISION_PRO_TRANSCEIVER - Returns + * the id of the glasses that are currently paired to the given + * 3D Vision Pro transceiver. + * + * The format of the returned data is: + * + * 4 CARD32 number of glasses + * 4 * n CARD32 id of glasses + * + * This attribute can only be queried through XNVCTRLQueryTargetBinaryData() + * using a NV_CTRL_TARGET_TYPE_3D_VISION_PRO_TRANSCEIVER target. + */ +#define NV_CTRL_BINARY_DATA_GLASSES_PAIRED_TO_3D_VISION_PRO_TRANSCEIVER 13 /* R--T */ + +/* + * NV_CTRL_BINARY_DATA_DISPLAY_TARGETS - Returns all the display devices + * currently connected to any GPU on the X server. + * + * The format of the returned data is: + * + * 4 CARD32 number of display devices + * 4 * n CARD32 display device indices + * + * This attribute can only be queried through XNVCTRLQueryTargetBinaryData(). + */ + +#define NV_CTRL_BINARY_DATA_DISPLAY_TARGETS 14 /* R--- */ + +/* + * NV_CTRL_BINARY_DATA_DISPLAYS_CONNECTED_TO_GPU - Returns the list of + * display devices that are connected to the GPU target. + * + * The format of the returned data is: + * + * 4 CARD32 number of display devices + * 4 * n CARD32 display device indices + * + * This attribute can only be queried through XNVCTRLQueryTargetBinaryData() + * using a NV_CTRL_TARGET_TYPE_GPU target. + */ + +#define NV_CTRL_BINARY_DATA_DISPLAYS_CONNECTED_TO_GPU 15 /* R--G */ + +/* + * NV_CTRL_BINARY_DATA_METAMODES_VERSION_2 - Returns values similar to + * NV_CTRL_BINARY_DATA_METAMODES(_VERSION_1) but also returns extended syntax + * information to indicate a specific display device, as well as other per- + * display deviceflags as "token=value" pairs. For example: + * + * "DPY-1: 1280x1024 {Stereo=PassiveLeft}, + * DPY-2: 1280x1024 {Stereo=PassiveRight}," + * + * The display device names have the form "DPY-%d", where the integer + * part of the name is the NV-CONTROL target ID for that display device + * for this instance of the X server. Note that display device NV-CONTROL + * target IDs are not guaranteed to be the same from one run of the X + * server to the next. + */ + +#define NV_CTRL_BINARY_DATA_METAMODES_VERSION_2 16 /* R-D- */ + +/* + * NV_CTRL_BINARY_DATA_DISPLAYS_ENABLED_ON_XSCREEN - Returns the list of + * display devices that are currently scanning out the X screen target. + * + * The format of the returned data is: + * + * 4 CARD32 number of display devices + * 4 * n CARD32 display device indices + * + * This attribute can only be queried through XNVCTRLQueryTargetBinaryData() + * using a NV_CTRL_TARGET_TYPE_X_SCREEN target. + */ + +#define NV_CTRL_BINARY_DATA_DISPLAYS_ENABLED_ON_XSCREEN 17 /* R--- */ + +#define NV_CTRL_BINARY_DATA_LAST_ATTRIBUTE NV_CTRL_BINARY_DATA_DISPLAYS_ENABLED_ON_XSCREEN + +/**************************************************************************/ + +/* + * String Operation Attributes: + * + * These attributes are used with the XNVCTRLStringOperation() + * function; a string is specified as input, and a string is returned + * as output. + * + * Unless otherwise noted, all attributes can be operated upon using + * an NV_CTRL_TARGET_TYPE_X_SCREEN target. + */ + +/* + * NV_CTRL_STRING_OPERATION_ADD_METAMODE - provide a MetaMode string + * as input, and returns a string containing comma-separated list of + * "token=value" pairs as output. Currently, the only output token is + * "id", which indicates the id that was assigned to the MetaMode. + * + * All ModeLines referenced in the MetaMode must already exist for + * each display device (as returned by the + * NV_CTRL_BINARY_DATA_MODELINES attribute). + * + * The MetaMode string should have the same syntax as the MetaMode X + * configuration option, as documented in the NVIDIA driver README. + * + * The input string can optionally be prepended with a string of + * comma-separated "token=value" pairs, separated from the MetaMode + * string by "::". Currently, the only valid token is "index" which + * indicates the insertion index for the MetaMode. + * + * E.g., + * + * Input: "index=5 :: 1600x1200+0+0, 1600x1200+1600+0" + * Output: "id=58" + * + * which causes the MetaMode to be inserted at position 5 in the + * MetaMode list (all entries after 5 will be shifted down one slot in + * the list), and the X server's containing mode stores 58 as the + * VRefresh, so that the MetaMode can be uniquely identifed through + * XRandR and XF86VidMode. + */ + +#define NV_CTRL_STRING_OPERATION_ADD_METAMODE 0 + +/* + * NV_CTRL_STRING_OPERATION_GTF_MODELINE - provide as input a string + * of comma-separated "token=value" pairs, and returns a ModeLine + * string, computed using the GTF formula using the parameters from + * the input string. Valid tokens for the input string are "width", + * "height", and "refreshrate". + * + * E.g., + * + * Input: "width=1600, height=1200, refreshrate=60" + * Output: "160.96 1600 1704 1880 2160 1200 1201 1204 1242 -HSync +VSync" + * + * This operation does not have any impact on any display device's + * modePool, and the ModeLine is not validated; it is simply intended + * for generating ModeLines. + */ + +#define NV_CTRL_STRING_OPERATION_GTF_MODELINE 1 + +/* + * NV_CTRL_STRING_OPERATION_CVT_MODELINE - provide as input a string + * of comma-separated "token=value" pairs, and returns a ModeLine + * string, computed using the CVT formula using the parameters from + * the input string. Valid tokens for the input string are "width", + * "height", "refreshrate", and "reduced-blanking". The + * "reduced-blanking" argument can be "0" or "1", to enable or disable + * use of reduced blanking for the CVT formula. + * + * E.g., + * + * Input: "width=1600, height=1200, refreshrate=60, reduced-blanking=1" + * Output: "130.25 1600 1648 1680 1760 1200 1203 1207 1235 +HSync -VSync" + * + * This operation does not have any impact on any display device's + * modePool, and the ModeLine is not validated; it is simply intended + * for generating ModeLines. + */ + +#define NV_CTRL_STRING_OPERATION_CVT_MODELINE 2 + +/* + * NV_CTRL_STRING_OPERATION_BUILD_MODEPOOL - build a ModePool for the + * specified display device on the specified target (either an X + * screen or a GPU). This is typically used to generate a ModePool + * for a display device on a GPU on which no X screens are present. + * + * Currently, a display device's ModePool is static for the life of + * the X server, so XNVCTRLStringOperation will return FALSE if + * requested to build a ModePool on a display device that already has + * a ModePool. + * + * The string input to BUILD_MODEPOOL may be NULL. If it is not NULL, + * then it is interpreted as a double-colon ("::") separated list + * of "option=value" pairs, where the options and the syntax of their + * values are the X configuration options that impact the behavior of + * modePool construction; namely: + * + * "ModeValidation" + * "HorizSync" + * "VertRefresh" + * "FlatPanelProperties" + * "TVStandard" + * "ExactModeTimingsDVI" + * "UseEdidFreqs" + * + * An example input string might look like: + * + * "ModeValidation=NoVesaModes :: HorizSync=50-110 :: VertRefresh=50-150" + * + * This request currently does not return a string. + */ + +#define NV_CTRL_STRING_OPERATION_BUILD_MODEPOOL 3 /* DG */ + +/* + * NV_CTRL_STRING_OPERATION_GVI_CONFIGURE_STREAMS - Configure the streams- + * to-jack+channel topology for a GVI (Graphics capture board). + * + * The string input to GVI_CONFIGURE_STREAMS may be NULL. If this is the + * case, then the current topology is returned. + * + * If the input string to GVI_CONFIGURE_STREAMS is not NULL, the string + * is interpreted as a semicolon (";") separated list of comma-separated + * lists of "option=value" pairs that define a stream's composition. The + * available options and their values are: + * + * "stream": Defines which stream this comma-separated list describes. + * Valid values are the integers between 0 and + * NV_CTRL_GVI_NUM_STREAMS-1 (inclusive). + * + * "linkN": Defines a jack+channel pair to use for the given link N. + * Valid options are the string "linkN", where N is an integer + * between 0 and NV_CTRL_GVI_MAX_LINKS_PER_STREAM-1 (inclusive). + * Valid values for these options are strings of the form + * "jackX" and/or "jackX.Y", where X is an integer between 0 and + * NV_CTRL_GVI_NUM_JACKS-1 (inclusive), and Y (optional) is an + * integer between 0 and NV_CTRL_GVI_MAX_CHANNELS_PER_JACK-1 + * (inclusive). + * + * An example input string might look like: + * + * "stream=0, link0=jack0, link1=jack1; stream=1, link0=jack2.1" + * + * This example specifies two streams, stream 0 and stream 1. Stream 0 + * is defined to capture link0 data from the first channel (channel 0) of + * BNC jack 0 and link1 data from the first channel of BNC jack 1. The + * second stream (Stream 1) is defined to capture link0 data from channel 1 + * (second channel) of BNC jack 2. + * + * This example shows a possible configuration for capturing 3G input: + * + * "stream=0, link0=jack0.0, link1=jack0.1" + * + * Applications should query the following attributes to determine + * possible combinations: + * + * NV_CTRL_GVI_MAX_STREAMS + * NV_CTRL_GVI_MAX_LINKS_PER_STREAM + * NV_CTRL_GVI_NUM_JACKS + * NV_CTRL_GVI_MAX_CHANNELS_PER_JACK + * + * Note: A jack+channel pair can only be tied to one link/stream. + * + * Upon successful configuration or querying of this attribute, a string + * representing the current topology for all known streams on the device + * will be returned. On failure, NULL is returned. + * + * Note: Setting this attribute may also result in the following + * NV-CONTROL attributes being reset on the GVI device (to ensure + * the configuration remains valid): + * NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT + * NV_CTRL_GVI_REQUESTED_STREAM_BITS_PER_COMPONENT + * NV_CTRL_GVI_REQUESTED_STREAM_COMPONENT_SAMPLING + */ + +#define NV_CTRL_STRING_OPERATION_GVI_CONFIGURE_STREAMS 4 /* RW-I */ + +#define NV_CTRL_STRING_OPERATION_LAST_ATTRIBUTE NV_CTRL_STRING_OPERATION_GVI_CONFIGURE_STREAMS + +/**************************************************************************/ + +/* + * CTRLAttributeValidValuesRec - + * + * structure and related defines used by + * XNVCTRLQueryValidAttributeValues() to describe the valid values of + * a particular attribute. The type field will be one of: + * + * ATTRIBUTE_TYPE_INTEGER : the attribute is an integer value; there + * is no fixed range of valid values. + * + * ATTRIBUTE_TYPE_BITMASK : the attribute is an integer value, + * interpretted as a bitmask. + * + * ATTRIBUTE_TYPE_BOOL : the attribute is a boolean, valid values are + * either 1 (on/true) or 0 (off/false). + * + * ATTRIBUTE_TYPE_RANGE : the attribute can have any integer value + * between NVCTRLAttributeValidValues.u.range.min and + * NVCTRLAttributeValidValues.u.range.max (inclusive). + * + * ATTRIBUTE_TYPE_INT_BITS : the attribute can only have certain + * integer values, indicated by which bits in + * NVCTRLAttributeValidValues.u.bits.ints are on (for example: if bit + * 0 is on, then 0 is a valid value; if bit 5 is on, then 5 is a valid + * value, etc). This is useful for attributes like NV_CTRL_FSAA_MODE, + * which can only have certain values, depending on GPU. + * + * ATTRIBUTE_TYPE_64BIT_INTEGER : the attribute is a 64 bit integer value; + * there is no fixed range of valid values. + * + * ATTRIBUTE_TYPE_STRING : the attribute is a string value; there is no fixed + * range of valid values. + * + * ATTRIBUTE_TYPE_BINARY_DATA : the attribute is binary data; there is + * no fixed range of valid values. + * + * ATTRIBUTE_TYPE_STRING_OPERATION : the attribute is a string; there is + * no fixed range of valid values. + * + * + * The permissions field of NVCTRLAttributeValidValuesRec is a bitmask + * that may contain: + * + * ATTRIBUTE_TYPE_READ - Attribute may be read (queried.) + * ATTRIBUTE_TYPE_WRITE - Attribute may be written to (set.) + * ATTRIBUTE_TYPE_DISPLAY - Attribute is valid for display target types + * (requires a display_mask if queried via + * a GPU or X screen.) + * ATTRIBUTE_TYPE_GPU - Attribute is valid for GPU target types. + * ATTRIBUTE_TYPE_FRAMELOCK - Attribute is valid for Frame Lock target types. + * ATTRIBUTE_TYPE_X_SCREEN - Attribute is valid for X Screen target types. + * ATTRIBUTE_TYPE_XINERAMA - Attribute will be made consistent for all + * X Screens when the Xinerama extension is enabled. + * ATTRIBUTE_TYPE_VCSC - Attribute is valid for Visual Computing System + * target types. + * ATTRIBUTE_TYPE_GVI - Attribute is valid for Graphics Video In target + * types. + * ATTRIBUTE_TYPE_COOLER - Attribute is valid for Cooler target types. + * ATTRIBUTE_TYPE_3D_VISION_PRO_TRANSCEIVER - Attribute is valid for 3D Vision + * Pro Transceiver target types. + * + * See 'Key to Integer Attribute "Permissions"' at the top of this + * file for a description of what these permission bits mean. + */ + +#define ATTRIBUTE_TYPE_UNKNOWN 0 +#define ATTRIBUTE_TYPE_INTEGER 1 +#define ATTRIBUTE_TYPE_BITMASK 2 +#define ATTRIBUTE_TYPE_BOOL 3 +#define ATTRIBUTE_TYPE_RANGE 4 +#define ATTRIBUTE_TYPE_INT_BITS 5 +#define ATTRIBUTE_TYPE_64BIT_INTEGER 6 +#define ATTRIBUTE_TYPE_STRING 7 +#define ATTRIBUTE_TYPE_BINARY_DATA 8 +#define ATTRIBUTE_TYPE_STRING_OPERATION 9 + +#define ATTRIBUTE_TYPE_READ 0x001 +#define ATTRIBUTE_TYPE_WRITE 0x002 +#define ATTRIBUTE_TYPE_DISPLAY 0x004 +#define ATTRIBUTE_TYPE_GPU 0x008 +#define ATTRIBUTE_TYPE_FRAMELOCK 0x010 +#define ATTRIBUTE_TYPE_X_SCREEN 0x020 +#define ATTRIBUTE_TYPE_XINERAMA 0x040 +#define ATTRIBUTE_TYPE_VCSC 0x080 +#define ATTRIBUTE_TYPE_GVI 0x100 +#define ATTRIBUTE_TYPE_COOLER 0x200 +#define ATTRIBUTE_TYPE_THERMAL_SENSOR 0x400 +#define ATTRIBUTE_TYPE_3D_VISION_PRO_TRANSCEIVER 0x800 + +#define ATTRIBUTE_TYPE_ALL_TARGETS \ + ((ATTRIBUTE_TYPE_DISPLAY) | (ATTRIBUTE_TYPE_GPU) | (ATTRIBUTE_TYPE_FRAMELOCK) | \ + (ATTRIBUTE_TYPE_X_SCREEN) | (ATTRIBUTE_TYPE_VCSC) | (ATTRIBUTE_TYPE_GVI) | \ + (ATTRIBUTE_TYPE_COOLER) | (ATTRIBUTE_TYPE_THERMAL_SENSOR) | \ + (ATTRIBUTE_TYPE_3D_VISION_PRO_TRANSCEIVER)) + +typedef struct _NVCTRLAttributeValidValues +{ + int type; + union + { + struct + { + int64_t min; + int64_t max; + } range; + struct + { + unsigned int ints; + } bits; + } u; + unsigned int permissions; +} NVCTRLAttributeValidValuesRec; + +typedef struct _NVCTRLAttributePermissions +{ + int type; + unsigned int permissions; +} NVCTRLAttributePermissionsRec; + +/**************************************************************************/ + +/* + * NV-CONTROL X event notification. + * + * To receive X event notifications dealing with NV-CONTROL, you should + * call XNVCtrlSelectNotify() with one of the following set as the type + * of event to receive (see NVCtrlLib.h for more information): + */ + +#define ATTRIBUTE_CHANGED_EVENT 0 +#define TARGET_ATTRIBUTE_CHANGED_EVENT 1 +#define TARGET_ATTRIBUTE_AVAILABILITY_CHANGED_EVENT 2 +#define TARGET_STRING_ATTRIBUTE_CHANGED_EVENT 3 +#define TARGET_BINARY_ATTRIBUTE_CHANGED_EVENT 4 + +#endif /* __NVCTRL_H */ diff --git a/src/3rdparty/angle/src/third_party/libXNVCtrl/NVCtrlLib.h b/src/3rdparty/angle/src/third_party/libXNVCtrl/NVCtrlLib.h new file mode 100644 index 0000000000..1a5d5decfa --- /dev/null +++ b/src/3rdparty/angle/src/third_party/libXNVCtrl/NVCtrlLib.h @@ -0,0 +1,707 @@ +/* + * Copyright (c) 2008 NVIDIA, Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef __NVCTRLLIB_H +#define __NVCTRLLIB_H + +#include "NVCtrl.h" + +#if defined __cplusplus +extern "C" { +#endif + +/* + * XNVCTRLQueryExtension - + * + * Returns True if the extension exists, returns False otherwise. + * event_basep and error_basep are the extension event and error + * bases. Currently, no extension specific errors or events are + * defined. + */ + +Bool XNVCTRLQueryExtension(Display *dpy, int *event_basep, int *error_basep); + +/* + * XNVCTRLQueryVersion - + * + * Returns True if the extension exists, returns False otherwise. + * major and minor are the extension's major and minor version + * numbers. + */ + +Bool XNVCTRLQueryVersion(Display *dpy, int *major, int *minor); + +/* + * XNVCTRLIsNvScreen + * + * Returns True is the specified screen is controlled by the NVIDIA + * driver. Returns False otherwise. + */ + +Bool XNVCTRLIsNvScreen(Display *dpy, int screen); + +/* + * XNVCTRLQueryTargetCount - + * + * Returns True if the target type exists. Returns False otherwise. + * If XNVCTRLQueryTargetCount returns True, value will contain the + * count of existing targets on the server of the specified target + * type. + * + * Please see "Attribute Targets" in NVCtrl.h for the list of valid + * target types. + * + * Possible errors: + * BadValue - The target doesn't exist. + */ + +Bool XNVCTRLQueryTargetCount(Display *dpy, int target_type, int *value); + +/* + * XNVCTRLSetAttribute - + * + * Sets the attribute to the given value. The attributes and their + * possible values are listed in NVCtrl.h. + * + * Not all attributes require the display_mask parameter; see + * NVCtrl.h for details. + * + * Calling this function is equivalent to calling XNVCTRLSetTargetAttribute() + * with the target_type set to NV_CTRL_TARGET_TYPE_X_SCREEN and + * target_id set to 'screen'. + * + * Possible errors: + * BadValue - The screen or attribute doesn't exist. + * BadMatch - The NVIDIA driver is not present on that screen. + */ + +void XNVCTRLSetAttribute(Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + int value); + +/* + * XNVCTRLSetTargetAttribute - + * + * Sets the attribute to the given value. The attributes and their + * possible values are listed in NVCtrl.h. + * + * Not all attributes require the display_mask parameter; see + * NVCtrl.h for details. + * + * Possible errors: + * BadValue - The target or attribute doesn't exist. + * BadMatch - The NVIDIA driver is not present on that target. + */ + +void XNVCTRLSetTargetAttribute(Display *dpy, + int target_type, + int target_id, + unsigned int display_mask, + unsigned int attribute, + int value); + +/* + * XNVCTRLSetAttributeAndGetStatus - + * + * Same as XNVCTRLSetAttribute(). + * In addition, XNVCTRLSetAttributeAndGetStatus() returns + * True if the operation succeeds, False otherwise. + * + */ + +Bool XNVCTRLSetAttributeAndGetStatus(Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + int value); + +/* + * XNVCTRLSetTargetAttributeAndGetStatus - + * + * Same as XNVCTRLSetTargetAttribute(). + * In addition, XNVCTRLSetTargetAttributeAndGetStatus() returns + * True if the operation succeeds, False otherwise. + * + */ + +Bool XNVCTRLSetTargetAttributeAndGetStatus(Display *dpy, + int target_type, + int target_id, + unsigned int display_mask, + unsigned int attribute, + int value); + +/* + * XNVCTRLQueryAttribute - + * + * Returns True if the attribute exists. Returns False otherwise. + * If XNVCTRLQueryAttribute returns True, value will contain the + * value of the specified attribute. + * + * Not all attributes require the display_mask parameter; see + * NVCtrl.h for details. + * + * Calling this function is equivalent to calling + * XNVCTRLQueryTargetAttribute() with the target_type set to + * NV_CTRL_TARGET_TYPE_X_SCREEN and target_id set to 'screen'. + * + * Possible errors: + * BadValue - The screen doesn't exist. + * BadMatch - The NVIDIA driver is not present on that screen. + */ + +Bool XNVCTRLQueryAttribute(Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + int *value); + +/* + * XNVCTRLQueryTargetAttribute - + * + * Returns True if the attribute exists. Returns False otherwise. + * If XNVCTRLQueryTargetAttribute returns True, value will contain the + * value of the specified attribute. + * + * Not all attributes require the display_mask parameter; see + * NVCtrl.h for details. + * + * Possible errors: + * BadValue - The target doesn't exist. + * BadMatch - The NVIDIA driver does not control the target. + */ + +Bool XNVCTRLQueryTargetAttribute(Display *dpy, + int target_Type, + int target_id, + unsigned int display_mask, + unsigned int attribute, + int *value); + +/* + * XNVCTRLQueryTargetAttribute64 - + * + * Returns True if the attribute exists. Returns False otherwise. + * If XNVCTRLQueryTargetAttribute returns True, value will contain the + * value of the specified attribute. + * + * Not all attributes require the display_mask parameter; see + * NVCtrl.h for details. + * + * Note: this function behaves like XNVCTRLQueryTargetAttribute(), + * but supports 64-bit integer attributes. + * + * Possible errors: + * BadValue - The target doesn't exist. + * BadMatch - The NVIDIA driver does not control the target. + */ + +Bool XNVCTRLQueryTargetAttribute64(Display *dpy, + int target_Type, + int target_id, + unsigned int display_mask, + unsigned int attribute, + int64_t *value); + +/* + * XNVCTRLQueryStringAttribute - + * + * Returns True if the attribute exists. Returns False otherwise. + * If XNVCTRLQueryStringAttribute returns True, *ptr will point to an + * allocated string containing the string attribute requested. It is + * the caller's responsibility to free the string when done. + * + * Calling this function is equivalent to calling + * XNVCTRLQueryTargetStringAttribute() with the target_type set to + * NV_CTRL_TARGET_TYPE_X_SCREEN and target_id set to 'screen'. + * + * Possible errors: + * BadValue - The screen doesn't exist. + * BadMatch - The NVIDIA driver is not present on that screen. + * BadAlloc - Insufficient resources to fulfill the request. + */ + +Bool XNVCTRLQueryStringAttribute(Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + char **ptr); + +/* + * XNVCTRLQueryTargetStringAttribute - + * + * Returns True if the attribute exists. Returns False otherwise. + * If XNVCTRLQueryTargetStringAttribute returns True, *ptr will point + * to an allocated string containing the string attribute requested. + * It is the caller's responsibility to free the string when done. + * + * Possible errors: + * BadValue - The target doesn't exist. + * BadMatch - The NVIDIA driver does not control the target. + * BadAlloc - Insufficient resources to fulfill the request. + */ + +Bool XNVCTRLQueryTargetStringAttribute(Display *dpy, + int target_type, + int target_id, + unsigned int display_mask, + unsigned int attribute, + char **ptr); + +/* + * XNVCTRLSetStringAttribute - + * + * Returns True if the operation succeded. Returns False otherwise. + * + * Possible X errors: + * BadValue - The screen doesn't exist. + * BadMatch - The NVIDIA driver is not present on that screen. + * BadAlloc - Insufficient resources to fulfill the request. + */ + +Bool XNVCTRLSetStringAttribute(Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + char *ptr); + +/* + * XNVCTRLSetTargetStringAttribute - + * + * Returns True if the operation succeded. Returns False otherwise. + * + * Possible X errors: + * BadValue - The screen doesn't exist. + * BadMatch - The NVIDIA driver is not present on that screen. + * BadAlloc - Insufficient resources to fulfill the request. + */ + +Bool XNVCTRLSetTargetStringAttribute(Display *dpy, + int target_type, + int target_id, + unsigned int display_mask, + unsigned int attribute, + char *ptr); + +/* + * XNVCTRLQueryValidAttributeValues - + * + * Returns True if the attribute exists. Returns False otherwise. If + * XNVCTRLQueryValidAttributeValues returns True, values will indicate + * the valid values for the specified attribute; see the description + * of NVCTRLAttributeValidValues in NVCtrl.h. + * + * Calling this function is equivalent to calling + * XNVCTRLQueryValidTargetAttributeValues() with the target_type set to + * NV_CTRL_TARGET_TYPE_X_SCREEN and target_id set to 'screen'. + */ + +Bool XNVCTRLQueryValidAttributeValues(Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + NVCTRLAttributeValidValuesRec *values); + +/* + * XNVCTRLQueryValidTargetAttributeValues - + * + * Returns True if the attribute exists. Returns False otherwise. If + * XNVCTRLQueryValidTargetAttributeValues returns True, values will indicate + * the valid values for the specified attribute. + */ + +Bool XNVCTRLQueryValidTargetAttributeValues(Display *dpy, + int target_type, + int target_id, + unsigned int display_mask, + unsigned int attribute, + NVCTRLAttributeValidValuesRec *values); + +/* + * XNVCTRLQueryValidTargetStringAttributeValues - + * + * Returns True if the attribute exists. Returns False otherwise. If + * XNVCTRLQueryValidTargetStringAttributeValues returns True, values will + * indicate the valid values for the specified attribute. + */ + +Bool XNVCTRLQueryValidTargetStringAttributeValues(Display *dpy, + int target_type, + int target_id, + unsigned int display_mask, + unsigned int attribute, + NVCTRLAttributeValidValuesRec *values); + +/* + * XNVCTRLQueryAttributePermissions - + * + * Returns True if the attribute exists. Returns False otherwise. If + * XNVCTRLQueryAttributePermissions returns True, permissions will + * indicate the permission flags for the attribute. + */ + +Bool XNVCTRLQueryAttributePermissions(Display *dpy, + unsigned int attribute, + NVCTRLAttributePermissionsRec *permissions); + +/* + * XNVCTRLQueryStringAttributePermissions - + * + * Returns True if the attribute exists. Returns False otherwise. If + * XNVCTRLQueryStringAttributePermissions returns True, permissions will + * indicate the permission flags for the attribute. + */ + +Bool XNVCTRLQueryStringAttributePermissions(Display *dpy, + unsigned int attribute, + NVCTRLAttributePermissionsRec *permissions); + +/* + * XNVCTRLQueryBinaryDataAttributePermissions - + * + * Returns True if the attribute exists. Returns False otherwise. If + * XNVCTRLQueryBinaryDataAttributePermissions returns True, permissions + * will indicate the permission flags for the attribute. + */ + +Bool XNVCTRLQueryBinaryDataAttributePermissions(Display *dpy, + unsigned int attribute, + NVCTRLAttributePermissionsRec *permissions); + +/* + * XNVCTRLQueryStringOperationAttributePermissions - + * + * Returns True if the attribute exists. Returns False otherwise. If + * XNVCTRLQueryStringOperationAttributePermissions returns True, + * permissions will indicate the permission flags for the attribute. + */ + +Bool XNVCTRLQueryStringOperationAttributePermissions(Display *dpy, + unsigned int attribute, + NVCTRLAttributePermissionsRec *permissions); + +/* + * XNVCTRLSetGvoColorConversion - + * + * Sets the color conversion matrix, offset, and scale that should be + * used for GVO (Graphic to Video Out). + * + * The Color Space Conversion data is ordered like this: + * + * colorMatrix[0][0] // r.Y + * colorMatrix[0][1] // g.Y + * colorMatrix[0][2] // b.Y + * + * colorMatrix[1][0] // r.Cr + * colorMatrix[1][1] // g.Cr + * colorMatrix[1][2] // b.Cr + * + * colorMatrix[2][0] // r.Cb + * colorMatrix[2][1] // g.Cb + * colorMatrix[2][2] // b.Cb + * + * colorOffset[0] // Y + * colorOffset[1] // Cr + * colorOffset[2] // Cb + * + * colorScale[0] // Y + * colorScale[1] // Cr + * colorScale[2] // Cb + * + * where the data is used according to the following formulae: + * + * Y = colorOffset[0] + colorScale[0] * + * (R * colorMatrix[0][0] + + * G * colorMatrix[0][1] + + * B * colorMatrix[0][2]); + * + * Cr = colorOffset[1] + colorScale[1] * + * (R * colorMatrix[1][0] + + * G * colorMatrix[1][1] + + * B * colorMatrix[1][2]); + * + * Cb = colorOffset[2] + colorScale[2] * + * (R * colorMatrix[2][0] + + * G * colorMatrix[2][1] + + * B * colorMatrix[2][2]); + * + * Possible errors: + * BadMatch - The NVIDIA driver is not present on that screen. + * BadImplementation - GVO is not available on that screen. + */ + +void XNVCTRLSetGvoColorConversion(Display *dpy, + int screen, + float colorMatrix[3][3], + float colorOffset[3], + float colorScale[3]); + +/* + * XNVCTRLQueryGvoColorConversion - + * + * Retrieves the color conversion matrix and color offset + * that are currently being used for GVO (Graphic to Video Out). + * + * The values are ordered within the arrays according to the comments + * for XNVCTRLSetGvoColorConversion(). + * + * Possible errors: + * BadMatch - The NVIDIA driver is not present on that screen. + * BadImplementation - GVO is not available on that screen. + */ + +Bool XNVCTRLQueryGvoColorConversion(Display *dpy, + int screen, + float colorMatrix[3][3], + float colorOffset[3], + float colorScale[3]); + +/* + * XNVCTRLQueryBinaryData - + * + * Returns True if the attribute exists. Returns False otherwise. + * If XNVCTRLQueryBinaryData returns True, *ptr will point to an + * allocated block of memory containing the binary data attribute + * requested. It is the caller's responsibility to free the data + * when done. len will list the length of the binary data. + * + * Calling this function is equivalent to calling + * XNVCTRLQueryTargetBinaryData() with the target_type set to + * NV_CTRL_TARGET_TYPE_X_SCREEN and target_id set to 'screen'. + * + * Possible errors: + * BadValue - The screen doesn't exist. + * BadMatch - The NVIDIA driver is not present on that screen. + * BadAlloc - Insufficient resources to fulfill the request. + */ + +Bool XNVCTRLQueryBinaryData(Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + unsigned char **ptr, + int *len); + +/* + * XNVCTRLQueryTargetBinaryData - + * + * Returns True if the attribute exists. Returns False otherwise. + * If XNVCTRLQueryTargetBinaryData returns True, *ptr will point to an + * allocated block of memory containing the binary data attribute + * requested. It is the caller's responsibility to free the data + * when done. len will list the length of the binary data. + * + * Possible errors: + * BadValue - The target doesn't exist. + * BadMatch - The NVIDIA driver does not control the target. + * BadAlloc - Insufficient resources to fulfill the request. + */ + +Bool XNVCTRLQueryTargetBinaryData(Display *dpy, + int target_type, + int target_id, + unsigned int display_mask, + unsigned int attribute, + unsigned char **ptr, + int *len); + +/* + * XNVCTRLStringOperation - + * + * Takes a string as input and returns a Xmalloc'ed string as output. + * Returns True on success and False on failure. + */ + +Bool XNVCTRLStringOperation(Display *dpy, + int target_type, + int target_id, + unsigned int display_mask, + unsigned int attribute, + char *pIn, + char **ppOut); + +/* + * XNVCtrlSelectNotify - + * + * This enables/disables receiving of NV-CONTROL events. The type + * specifies the type of event to enable (currently, the only + * type that can be requested per-screen with XNVCtrlSelectNotify() + * is ATTRIBUTE_CHANGED_EVENT); onoff controls whether receiving this + * type of event should be enabled (True) or disabled (False). + * + * Returns True if successful, or False if the screen is not + * controlled by the NVIDIA driver. + */ + +Bool XNVCtrlSelectNotify(Display *dpy, int screen, int type, Bool onoff); + +/* + * XNVCtrlSelectTargetNotify - + * + * This enables/disables receiving of NV-CONTROL events that happen on + * the specified target. The notify_type specifies the type of event to + * enable (currently, the only type that can be requested per-target with + * XNVCtrlSelectTargetNotify() is TARGET_ATTRIBUTE_CHANGED_EVENT); onoff + * controls whether receiving this type of event should be enabled (True) + * or disabled (False). + * + * Returns True if successful, or False if the target is not + * controlled by the NVIDIA driver. + */ + +Bool XNVCtrlSelectTargetNotify(Display *dpy, + int target_type, + int target_id, + int notify_type, + Bool onoff); + +/* + * XNVCtrlEvent structure + */ + +typedef struct +{ + int type; + unsigned long serial; + Bool send_event; /* always FALSE, we don't allow send_events */ + Display *display; + Time time; + int screen; + unsigned int display_mask; + unsigned int attribute; + int value; +} XNVCtrlAttributeChangedEvent; + +typedef union +{ + int type; + XNVCtrlAttributeChangedEvent attribute_changed; + long pad[24]; +} XNVCtrlEvent; + +/* + * XNVCtrlEventTarget structure + */ + +typedef struct +{ + int type; + unsigned long serial; + Bool send_event; /* always FALSE, we don't allow send_events */ + Display *display; + Time time; + int target_type; + int target_id; + unsigned int display_mask; + unsigned int attribute; + int value; +} XNVCtrlAttributeChangedEventTarget; + +typedef union +{ + int type; + XNVCtrlAttributeChangedEventTarget attribute_changed; + long pad[24]; +} XNVCtrlEventTarget; + +/* + * XNVCtrlEventTargetAvailability structure + */ + +typedef struct +{ + int type; + unsigned long serial; + Bool send_event; /* always FALSE, we don't allow send_events */ + Display *display; + Time time; + int target_type; + int target_id; + unsigned int display_mask; + unsigned int attribute; + int value; + Bool availability; +} XNVCtrlAttributeChangedEventTargetAvailability; + +typedef union +{ + int type; + XNVCtrlAttributeChangedEventTargetAvailability attribute_changed; + long pad[24]; +} XNVCtrlEventTargetAvailability; + +/* + * XNVCtrlStringEventTarget structure + */ + +typedef struct +{ + int type; + unsigned long serial; + Bool send_event; /* always FALSE, we don't allow send_events */ + Display *display; + Time time; + int target_type; + int target_id; + unsigned int display_mask; + unsigned int attribute; +} XNVCtrlStringAttributeChangedEventTarget; + +typedef union +{ + int type; + XNVCtrlStringAttributeChangedEventTarget attribute_changed; + long pad[24]; +} XNVCtrlStringEventTarget; + +/* + * XNVCtrlBinaryEventTarget structure + */ + +typedef struct +{ + int type; + unsigned long serial; + Bool send_event; /* always FALSE, we don't allow send_events */ + Display *display; + Time time; + int target_type; + int target_id; + unsigned int display_mask; + unsigned int attribute; +} XNVCtrlBinaryAttributeChangedEventTarget; + +typedef union +{ + int type; + XNVCtrlBinaryAttributeChangedEventTarget attribute_changed; + long pad[24]; +} XNVCtrlBinaryEventTarget; + +#if defined __cplusplus +} /* extern "C" */ +#endif + +#endif /* __NVCTRLLIB_H */ diff --git a/src/3rdparty/angle/src/third_party/libXNVCtrl/README.angle b/src/3rdparty/angle/src/third_party/libXNVCtrl/README.angle new file mode 100644 index 0000000000..22b9bd0aac --- /dev/null +++ b/src/3rdparty/angle/src/third_party/libXNVCtrl/README.angle @@ -0,0 +1,14 @@ +Name: NVidia Control X Extension Library +Short Name: libXNVCtrl +URL: http://cgit.freedesktop.org/~aplattner/nvidia-settings/ +Version: unknown +Date: 2008 +License: MIT +Security Critical: no + +Description: +This package provides access to NVidia Control X Extension. It is used to determine the version of the NVIDIA driver in use. + +The current version is pulled from nvidia-settings-302.17. + +Local Modifications: diff --git a/src/3rdparty/angle/src/third_party/libXNVCtrl/nv_control.h b/src/3rdparty/angle/src/third_party/libXNVCtrl/nv_control.h new file mode 100644 index 0000000000..5023c9b58c --- /dev/null +++ b/src/3rdparty/angle/src/third_party/libXNVCtrl/nv_control.h @@ -0,0 +1,652 @@ +/* + * Copyright (c) 2008 NVIDIA, Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * + * NV-CONTROL Protocol Version History + * + * 1.0 - 1.5 NVIDIA Internal development versions + * 1.6 Initial public version + * 1.7 Added QueryBinaryData request + * 1.8 Added TargetTypes + * 1.9 Added QueryTargetCount request + * 1.10 Fixed target type/id byte ordering for compatibility with + * pre-1.8 NV-CONTROL clients + * 1.11 NVIDIA Internal development version + * 1.12 Added StringOperation request + * 1.13 NVIDIA Internal development version + * 1.14 Fixed an NV_CTRL_BINARY_DATA_MODELINES double scan modeline + * reporting bug (vsyncstart, vsyncend, and vtotal were incorrectly + * doubled) + * 1.15 Added AVAILABILITY_TARGET_ATTRIBUTE_CHANGED_EVENT + * 1.16 Added TARGET_STRING_ATTRIBUTE_CHANGED_EVENT + * 1.17 Added TARGET_BINARY_ATTRIBUTE_CHANGED_EVENT + * 1.18 Updated QueryTargetCount to return a count of 0, rather than + * BadMatch, if an unknown TargetType is specified + * 1.19 Added TargetType support for SetAttributeAndGetStatus and + * SetStringAttribute requests + * 1.20 Added COOLER TargetType + * 1.21 Added initial 64-bit integer attribute support (read-only) + * 1.22 Added X_nvCtrlQueryValidStringAttributeValues to check + * string attribute permissions. + * 1.23 Added SENSOR TargetType + * 1.24 Fixed a bug where SLI_MOSAIC_MODE_AVAILABLE attribute would + * report false positives via the GPU and X screen target types + * 1.25 Added 3D_VISION_PRO_TRANSCEIVER TargetType + * 1.26 Added XNVCTRLQueryXXXAttributePermissions. + * 1.27 Added DISPLAY TargetType + * 1.28 Added NV_CTRL_CURRENT_METAMODE_ID: clients should use this + * attribute to switch MetaModes, rather than pass the MetaMode ID + * through the RRSetScreenConfig protocol request. + */ + +#ifndef __NVCONTROL_H +#define __NVCONTROL_H + +#define NV_CONTROL_ERRORS 0 +#define NV_CONTROL_EVENTS 5 +#define NV_CONTROL_NAME "NV-CONTROL" + +#define NV_CONTROL_MAJOR 1 +#define NV_CONTROL_MINOR 28 + +#define X_nvCtrlQueryExtension 0 +#define X_nvCtrlIsNv 1 +#define X_nvCtrlQueryAttribute 2 +#define X_nvCtrlSetAttribute 3 +#define X_nvCtrlQueryStringAttribute 4 +#define X_nvCtrlQueryValidAttributeValues 5 +#define X_nvCtrlSelectNotify 6 +#define X_nvCtrlSetGvoColorConversionDeprecated 7 +#define X_nvCtrlQueryGvoColorConversionDeprecated 8 +#define X_nvCtrlSetStringAttribute 9 +/* STUB X_nvCtrlQueryDDCCILutSize 10 */ +/* STUB X_nvCtrlQueryDDCCISinglePointLutOperation 11 */ +/* STUB X_nvCtrlSetDDCCISinglePointLutOperation 12 */ +/* STUB X_nvCtrlQueryDDCCIBlockLutOperation 13 */ +/* STUB X_nvCtrlSetDDCCIBlockLutOperation 14 */ +/* STUB X_nvCtrlSetDDCCIRemoteProcedureCall 15 */ +/* STUB X_nvCtrlQueryDDCCIDisplayControllerType 16 */ +/* STUB X_nvCtrlQueryDDCCICapabilities 17 */ +/* STUB X_nvCtrlQueryDDCCITimingReport 18 */ +#define X_nvCtrlSetAttributeAndGetStatus 19 +#define X_nvCtrlQueryBinaryData 20 +#define X_nvCtrlSetGvoColorConversion 21 +#define X_nvCtrlQueryGvoColorConversion 22 +#define X_nvCtrlSelectTargetNotify 23 +#define X_nvCtrlQueryTargetCount 24 +#define X_nvCtrlStringOperation 25 +#define X_nvCtrlQueryValidAttributeValues64 26 +#define X_nvCtrlQueryAttribute64 27 +#define X_nvCtrlQueryValidStringAttributeValues 28 +#define X_nvCtrlQueryAttributePermissions 29 +#define X_nvCtrlQueryStringAttributePermissions 30 +#define X_nvCtrlQueryBinaryDataAttributePermissions 31 +#define X_nvCtrlQueryStringOperationAttributePermissions 32 + +#define X_nvCtrlLastRequest (X_nvCtrlQueryStringOperationAttributePermissions + 1) + +/* Define 32 bit floats */ +typedef float FLOAT32; +#ifndef F32 +#define F32 +#endif + +typedef struct +{ + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; +} xnvCtrlQueryExtensionReq; +#define sz_xnvCtrlQueryExtensionReq 4 + +typedef struct +{ + BYTE type; /* X_Reply */ + CARD8 padb1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 major B16; + CARD16 minor B16; + CARD32 padl4 B32; + CARD32 padl5 B32; + CARD32 padl6 B32; + CARD32 padl7 B32; + CARD32 padl8 B32; +} xnvCtrlQueryExtensionReply; +#define sz_xnvCtrlQueryExtensionReply 32 + +typedef struct +{ + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD32 screen B32; +} xnvCtrlIsNvReq; +#define sz_xnvCtrlIsNvReq 8 + +typedef struct +{ + BYTE type; /* X_Reply */ + CARD8 padb1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 isnv B32; + CARD32 padl4 B32; + CARD32 padl5 B32; + CARD32 padl6 B32; + CARD32 padl7 B32; + CARD32 padl8 B32; +} xnvCtrlIsNvReply; +#define sz_xnvCtrlIsNvReply 32 + +typedef struct +{ + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD32 target_type B32; +} xnvCtrlQueryTargetCountReq; +#define sz_xnvCtrlQueryTargetCountReq 8 + +typedef struct +{ + BYTE type; /* X_Reply */ + CARD8 padb1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 count B32; + CARD32 padl4 B32; + CARD32 padl5 B32; + CARD32 padl6 B32; + CARD32 padl7 B32; + CARD32 padl8 B32; +} xnvCtrlQueryTargetCountReply; +#define sz_xnvCtrlQueryTargetCountReply 32 + +typedef struct +{ + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD16 target_id B16; /* X screen number or GPU number */ + CARD16 target_type B16; /* X screen or GPU */ + CARD32 display_mask B32; + CARD32 attribute B32; +} xnvCtrlQueryAttributeReq; +#define sz_xnvCtrlQueryAttributeReq 16 + +typedef struct +{ + BYTE type; + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 flags B32; + INT32 value B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xnvCtrlQueryAttributeReply; +#define sz_xnvCtrlQueryAttributeReply 32 + +typedef struct +{ + BYTE type; + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 flags B32; + CARD32 pad3 B32; + int64_t value_64; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xnvCtrlQueryAttribute64Reply; +#define sz_xnvCtrlQueryAttribute64Reply 32 + +typedef struct +{ + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD16 target_id B16; + CARD16 target_type B16; + CARD32 display_mask B32; + CARD32 attribute B32; + INT32 value B32; +} xnvCtrlSetAttributeReq; +#define sz_xnvCtrlSetAttributeReq 20 + +typedef struct +{ + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD16 target_id B16; + CARD16 target_type B16; + CARD32 display_mask B32; + CARD32 attribute B32; + INT32 value B32; +} xnvCtrlSetAttributeAndGetStatusReq; +#define sz_xnvCtrlSetAttributeAndGetStatusReq 20 + +typedef struct +{ + BYTE type; + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 flags B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xnvCtrlSetAttributeAndGetStatusReply; +#define sz_xnvCtrlSetAttributeAndGetStatusReply 32 + +typedef struct +{ + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD16 target_id B16; /* X screen number or GPU number */ + CARD16 target_type B16; /* X screen or GPU */ + CARD32 display_mask B32; + CARD32 attribute B32; +} xnvCtrlQueryStringAttributeReq; +#define sz_xnvCtrlQueryStringAttributeReq 16 + +typedef struct +{ + BYTE type; + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 flags B32; + CARD32 n B32; /* Length of string */ + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xnvCtrlQueryStringAttributeReply; +#define sz_xnvCtrlQueryStringAttributeReply 32 + +typedef struct +{ + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD16 target_id B16; + CARD16 target_type B16; + CARD32 display_mask B32; + CARD32 attribute B32; + CARD32 num_bytes B32; +} xnvCtrlSetStringAttributeReq; +#define sz_xnvCtrlSetStringAttributeReq 20 + +typedef struct +{ + BYTE type; + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 flags B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xnvCtrlSetStringAttributeReply; +#define sz_xnvCtrlSetStringAttributeReply 32 + +typedef struct +{ + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD16 target_id B16; /* X screen number or GPU number */ + CARD16 target_type B16; /* X screen or GPU */ + CARD32 display_mask B32; + CARD32 attribute B32; +} xnvCtrlQueryValidAttributeValuesReq; +#define sz_xnvCtrlQueryValidAttributeValuesReq 16 + +typedef struct +{ + BYTE type; + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 flags B32; + INT32 attr_type B32; + INT32 min B32; + INT32 max B32; + CARD32 bits B32; + CARD32 perms B32; +} xnvCtrlQueryValidAttributeValuesReply; +#define sz_xnvCtrlQueryValidAttributeValuesReply 32 + +typedef struct +{ + BYTE type; + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 flags B32; + INT32 attr_type B32; + int64_t min_64; + int64_t max_64; + CARD64 bits_64; + CARD32 perms B32; + CARD32 pad1 B32; +} xnvCtrlQueryValidAttributeValues64Reply; +#define sz_xnvCtrlQueryValidAttributeValues64Reply 48 +#define sz_xnvCtrlQueryValidAttributeValues64Reply_extra ((48 - 32) >> 2) + +typedef struct +{ + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD32 attribute B32; +} xnvCtrlQueryAttributePermissionsReq; +#define sz_xnvCtrlQueryAttributePermissionsReq 8 + +typedef struct +{ + BYTE type; + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 flags B32; + INT32 attr_type B32; + CARD32 perms B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + CARD32 pad8 B32; +} xnvCtrlQueryAttributePermissionsReply; +#define sz_xnvCtrlQueryAttributePermissionsReply 32 + +/* Set GVO Color Conversion request (deprecated) */ +typedef struct +{ + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD32 screen B32; + FLOAT32 row1_col1 F32; + FLOAT32 row1_col2 F32; + FLOAT32 row1_col3 F32; + FLOAT32 row1_col4 F32; + FLOAT32 row2_col1 F32; + FLOAT32 row2_col2 F32; + FLOAT32 row2_col3 F32; + FLOAT32 row2_col4 F32; + FLOAT32 row3_col1 F32; + FLOAT32 row3_col2 F32; + FLOAT32 row3_col3 F32; + FLOAT32 row3_col4 F32; +} xnvCtrlSetGvoColorConversionDeprecatedReq; +#define sz_xnvCtrlSetGvoColorConversionDeprecatedReq 56 + +/* Query GVO Color Conversion request (deprecated) */ +typedef struct +{ + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD32 screen B32; +} xnvCtrlQueryGvoColorConversionDeprecatedReq; +#define sz_xnvCtrlQueryGvoColorConversionDeprecatedReq 8 + +/* Query GVO Color Conversion reply (deprecated) */ +typedef struct +{ + BYTE type; /* X_Reply */ + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + CARD32 pad8 B32; +} xnvCtrlQueryGvoColorConversionDeprecatedReply; +#define sz_xnvCtrlQueryGvoColorConversionDeprecatedReply 32 + +/* Set GVO Color Conversion request */ +typedef struct +{ + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD32 screen B32; + + FLOAT32 cscMatrix_y_r F32; + FLOAT32 cscMatrix_y_g F32; + FLOAT32 cscMatrix_y_b F32; + + FLOAT32 cscMatrix_cr_r F32; + FLOAT32 cscMatrix_cr_g F32; + FLOAT32 cscMatrix_cr_b F32; + + FLOAT32 cscMatrix_cb_r F32; + FLOAT32 cscMatrix_cb_g F32; + FLOAT32 cscMatrix_cb_b F32; + + FLOAT32 cscOffset_y F32; + FLOAT32 cscOffset_cr F32; + FLOAT32 cscOffset_cb F32; + + FLOAT32 cscScale_y F32; + FLOAT32 cscScale_cr F32; + FLOAT32 cscScale_cb F32; + +} xnvCtrlSetGvoColorConversionReq; +#define sz_xnvCtrlSetGvoColorConversionReq 68 + +/* Query GVO Color Conversion request */ +typedef struct +{ + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD32 screen B32; +} xnvCtrlQueryGvoColorConversionReq; +#define sz_xnvCtrlQueryGvoColorConversionReq 8 + +/* Query GVO Color Conversion reply */ +typedef struct +{ + BYTE type; /* X_Reply */ + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + CARD32 pad8 B32; +} xnvCtrlQueryGvoColorConversionReply; +#define sz_xnvCtrlQueryGvoColorConversionReply 32 + +typedef struct +{ + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD16 target_id B16; /* X screen number or GPU number */ + CARD16 target_type B16; /* X screen or GPU */ + CARD32 display_mask B32; + CARD32 attribute B32; +} xnvCtrlQueryBinaryDataReq; +#define sz_xnvCtrlQueryBinaryDataReq 16 + +typedef struct +{ + BYTE type; + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 flags B32; + CARD32 n B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xnvCtrlQueryBinaryDataReply; +#define sz_xnvCtrlQueryBinaryDataReply 32 + +typedef struct +{ + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD32 screen B32; + CARD16 notifyType B16; + CARD16 onoff B16; +} xnvCtrlSelectNotifyReq; +#define sz_xnvCtrlSelectNotifyReq 12 + +typedef struct +{ + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD16 target_id B16; /* X screen number or GPU number */ + CARD16 target_type B16; /* X screen or GPU */ + CARD32 display_mask B32; + CARD32 attribute B32; + CARD32 num_bytes B32; /* Length of string */ +} xnvCtrlStringOperationReq; +#define sz_xnvCtrlStringOperationReq 20 + +typedef struct +{ + BYTE type; /* X_Reply */ + CARD8 padb1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 ret B32; + CARD32 num_bytes B32; /* Length of string */ + CARD32 padl4 B32; + CARD32 padl5 B32; + CARD32 padl6 B32; + CARD32 padl7 B32; +} xnvCtrlStringOperationReply; +#define sz_xnvCtrlStringOperationReply 32 + +typedef struct +{ + union + { + struct + { + BYTE type; + BYTE detail; + CARD16 sequenceNumber B16; + } u; + struct + { + BYTE type; + BYTE detail; + CARD16 sequenceNumber B16; + CARD32 time B32; + CARD32 screen B32; + CARD32 display_mask B32; + CARD32 attribute B32; + CARD32 value B32; + CARD32 pad0 B32; + CARD32 pad1 B32; + } attribute_changed; + } u; +} xnvctrlEvent; + +/* + * Leave target_type before target_id for the + * xnvCtrlSelectTargetNotifyReq and xnvctrlEventTarget + * structures, even though other request protocol structures + * store target_id in the bottom 16-bits of the second DWORD of the + * structures. The event-related structures were added in version + * 1.8, and so there is no prior version with which to maintain + * compatibility. + */ +typedef struct +{ + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD16 target_type B16; /* Don't swap these */ + CARD16 target_id B16; + CARD16 notifyType B16; + CARD16 onoff B16; +} xnvCtrlSelectTargetNotifyReq; +#define sz_xnvCtrlSelectTargetNotifyReq 12 + +typedef struct +{ + union + { + struct + { + BYTE type; + BYTE detail; + CARD16 sequenceNumber B16; + } u; + struct + { + BYTE type; + BYTE detail; + CARD16 sequenceNumber B16; + CARD32 time B32; + CARD16 target_type B16; /* Don't swap these */ + CARD16 target_id B16; + CARD32 display_mask B32; + CARD32 attribute B32; + CARD32 value B32; + CARD32 pad0 B32; + CARD32 pad1 B32; + } attribute_changed; + struct + { + BYTE type; + BYTE detail; + CARD16 sequenceNumber B16; + CARD32 time B32; + CARD16 target_type B16; /* Don't swap these */ + CARD16 target_id B16; + CARD32 display_mask B32; + CARD32 attribute B32; + CARD32 value B32; + CARD8 availability; + CARD8 pad0; + CARD16 pad1 B16; + CARD32 pad2 B32; + } availability_changed; + } u; +} xnvctrlEventTarget; + +#endif /* __NVCONTROL_H */ diff --git a/src/3rdparty/angle/src/third_party/murmurhash/LICENSE b/src/3rdparty/angle/src/third_party/murmurhash/LICENSE deleted file mode 100644 index 6a385f0f07..0000000000 --- a/src/3rdparty/angle/src/third_party/murmurhash/LICENSE +++ /dev/null @@ -1,2 +0,0 @@ -// MurmurHash3 was written by Austin Appleby, and is placed in the public -// domain. The author hereby disclaims copyright to this source code. \ No newline at end of file diff --git a/src/3rdparty/angle/src/third_party/murmurhash/MurmurHash3.cpp b/src/3rdparty/angle/src/third_party/murmurhash/MurmurHash3.cpp deleted file mode 100644 index aa7982d3ee..0000000000 --- a/src/3rdparty/angle/src/third_party/murmurhash/MurmurHash3.cpp +++ /dev/null @@ -1,335 +0,0 @@ -//----------------------------------------------------------------------------- -// MurmurHash3 was written by Austin Appleby, and is placed in the public -// domain. The author hereby disclaims copyright to this source code. - -// Note - The x86 and x64 versions do _not_ produce the same results, as the -// algorithms are optimized for their respective platforms. You can still -// compile and run any of them on any platform, but your performance with the -// non-native version will be less than optimal. - -#include "MurmurHash3.h" - -//----------------------------------------------------------------------------- -// Platform-specific functions and macros - -// Microsoft Visual Studio - -#if defined(_MSC_VER) - -#define FORCE_INLINE __forceinline - -#include - -#define ROTL32(x,y) _rotl(x,y) -#define ROTL64(x,y) _rotl64(x,y) - -#define BIG_CONSTANT(x) (x) - -// Other compilers - -#else // defined(_MSC_VER) - -#define FORCE_INLINE inline __attribute__((always_inline)) - -inline uint32_t rotl32 ( uint32_t x, int8_t r ) -{ - return (x << r) | (x >> (32 - r)); -} - -inline uint64_t rotl64 ( uint64_t x, int8_t r ) -{ - return (x << r) | (x >> (64 - r)); -} - -#define ROTL32(x,y) rotl32(x,y) -#define ROTL64(x,y) rotl64(x,y) - -#define BIG_CONSTANT(x) (x##LLU) - -#endif // !defined(_MSC_VER) - -//----------------------------------------------------------------------------- -// Block read - if your platform needs to do endian-swapping or can only -// handle aligned reads, do the conversion here - -FORCE_INLINE uint32_t getblock32 ( const uint32_t * p, int i ) -{ - return p[i]; -} - -FORCE_INLINE uint64_t getblock64 ( const uint64_t * p, int i ) -{ - return p[i]; -} - -//----------------------------------------------------------------------------- -// Finalization mix - force all bits of a hash block to avalanche - -FORCE_INLINE uint32_t fmix32 ( uint32_t h ) -{ - h ^= h >> 16; - h *= 0x85ebca6b; - h ^= h >> 13; - h *= 0xc2b2ae35; - h ^= h >> 16; - - return h; -} - -//---------- - -FORCE_INLINE uint64_t fmix64 ( uint64_t k ) -{ - k ^= k >> 33; - k *= BIG_CONSTANT(0xff51afd7ed558ccd); - k ^= k >> 33; - k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53); - k ^= k >> 33; - - return k; -} - -//----------------------------------------------------------------------------- - -void MurmurHash3_x86_32 ( const void * key, int len, - uint32_t seed, void * out ) -{ - const uint8_t * data = (const uint8_t*)key; - const int nblocks = len / 4; - - uint32_t h1 = seed; - - const uint32_t c1 = 0xcc9e2d51; - const uint32_t c2 = 0x1b873593; - - //---------- - // body - - const uint32_t * blocks = (const uint32_t *)(data + nblocks*4); - - for(int i = -nblocks; i; i++) - { - uint32_t k1 = getblock32(blocks,i); - - k1 *= c1; - k1 = ROTL32(k1,15); - k1 *= c2; - - h1 ^= k1; - h1 = ROTL32(h1,13); - h1 = h1*5+0xe6546b64; - } - - //---------- - // tail - - const uint8_t * tail = (const uint8_t*)(data + nblocks*4); - - uint32_t k1 = 0; - - switch(len & 3) - { - case 3: k1 ^= tail[2] << 16; - case 2: k1 ^= tail[1] << 8; - case 1: k1 ^= tail[0]; - k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; - }; - - //---------- - // finalization - - h1 ^= len; - - h1 = fmix32(h1); - - *(uint32_t*)out = h1; -} - -//----------------------------------------------------------------------------- - -void MurmurHash3_x86_128 ( const void * key, const int len, - uint32_t seed, void * out ) -{ - const uint8_t * data = (const uint8_t*)key; - const int nblocks = len / 16; - - uint32_t h1 = seed; - uint32_t h2 = seed; - uint32_t h3 = seed; - uint32_t h4 = seed; - - const uint32_t c1 = 0x239b961b; - const uint32_t c2 = 0xab0e9789; - const uint32_t c3 = 0x38b34ae5; - const uint32_t c4 = 0xa1e38b93; - - //---------- - // body - - const uint32_t * blocks = (const uint32_t *)(data + nblocks*16); - - for(int i = -nblocks; i; i++) - { - uint32_t k1 = getblock32(blocks,i*4+0); - uint32_t k2 = getblock32(blocks,i*4+1); - uint32_t k3 = getblock32(blocks,i*4+2); - uint32_t k4 = getblock32(blocks,i*4+3); - - k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; - - h1 = ROTL32(h1,19); h1 += h2; h1 = h1*5+0x561ccd1b; - - k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2; - - h2 = ROTL32(h2,17); h2 += h3; h2 = h2*5+0x0bcaa747; - - k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3; - - h3 = ROTL32(h3,15); h3 += h4; h3 = h3*5+0x96cd1c35; - - k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4; - - h4 = ROTL32(h4,13); h4 += h1; h4 = h4*5+0x32ac3b17; - } - - //---------- - // tail - - const uint8_t * tail = (const uint8_t*)(data + nblocks*16); - - uint32_t k1 = 0; - uint32_t k2 = 0; - uint32_t k3 = 0; - uint32_t k4 = 0; - - switch(len & 15) - { - case 15: k4 ^= tail[14] << 16; - case 14: k4 ^= tail[13] << 8; - case 13: k4 ^= tail[12] << 0; - k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4; - - case 12: k3 ^= tail[11] << 24; - case 11: k3 ^= tail[10] << 16; - case 10: k3 ^= tail[ 9] << 8; - case 9: k3 ^= tail[ 8] << 0; - k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3; - - case 8: k2 ^= tail[ 7] << 24; - case 7: k2 ^= tail[ 6] << 16; - case 6: k2 ^= tail[ 5] << 8; - case 5: k2 ^= tail[ 4] << 0; - k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2; - - case 4: k1 ^= tail[ 3] << 24; - case 3: k1 ^= tail[ 2] << 16; - case 2: k1 ^= tail[ 1] << 8; - case 1: k1 ^= tail[ 0] << 0; - k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1; - }; - - //---------- - // finalization - - h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len; - - h1 += h2; h1 += h3; h1 += h4; - h2 += h1; h3 += h1; h4 += h1; - - h1 = fmix32(h1); - h2 = fmix32(h2); - h3 = fmix32(h3); - h4 = fmix32(h4); - - h1 += h2; h1 += h3; h1 += h4; - h2 += h1; h3 += h1; h4 += h1; - - ((uint32_t*)out)[0] = h1; - ((uint32_t*)out)[1] = h2; - ((uint32_t*)out)[2] = h3; - ((uint32_t*)out)[3] = h4; -} - -//----------------------------------------------------------------------------- - -void MurmurHash3_x64_128 ( const void * key, const int len, - const uint32_t seed, void * out ) -{ - const uint8_t * data = (const uint8_t*)key; - const int nblocks = len / 16; - - uint64_t h1 = seed; - uint64_t h2 = seed; - - const uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5); - const uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f); - - //---------- - // body - - const uint64_t * blocks = (const uint64_t *)(data); - - for(int i = 0; i < nblocks; i++) - { - uint64_t k1 = getblock64(blocks,i*2+0); - uint64_t k2 = getblock64(blocks,i*2+1); - - k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1; - - h1 = ROTL64(h1,27); h1 += h2; h1 = h1*5+0x52dce729; - - k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2; - - h2 = ROTL64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5; - } - - //---------- - // tail - - const uint8_t * tail = (const uint8_t*)(data + nblocks*16); - - uint64_t k1 = 0; - uint64_t k2 = 0; - - switch(len & 15) - { - case 15: k2 ^= ((uint64_t)tail[14]) << 48; - case 14: k2 ^= ((uint64_t)tail[13]) << 40; - case 13: k2 ^= ((uint64_t)tail[12]) << 32; - case 12: k2 ^= ((uint64_t)tail[11]) << 24; - case 11: k2 ^= ((uint64_t)tail[10]) << 16; - case 10: k2 ^= ((uint64_t)tail[ 9]) << 8; - case 9: k2 ^= ((uint64_t)tail[ 8]) << 0; - k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2; - - case 8: k1 ^= ((uint64_t)tail[ 7]) << 56; - case 7: k1 ^= ((uint64_t)tail[ 6]) << 48; - case 6: k1 ^= ((uint64_t)tail[ 5]) << 40; - case 5: k1 ^= ((uint64_t)tail[ 4]) << 32; - case 4: k1 ^= ((uint64_t)tail[ 3]) << 24; - case 3: k1 ^= ((uint64_t)tail[ 2]) << 16; - case 2: k1 ^= ((uint64_t)tail[ 1]) << 8; - case 1: k1 ^= ((uint64_t)tail[ 0]) << 0; - k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1; - }; - - //---------- - // finalization - - h1 ^= len; h2 ^= len; - - h1 += h2; - h2 += h1; - - h1 = fmix64(h1); - h2 = fmix64(h2); - - h1 += h2; - h2 += h1; - - ((uint64_t*)out)[0] = h1; - ((uint64_t*)out)[1] = h2; -} - -//----------------------------------------------------------------------------- - diff --git a/src/3rdparty/angle/src/third_party/murmurhash/MurmurHash3.h b/src/3rdparty/angle/src/third_party/murmurhash/MurmurHash3.h deleted file mode 100644 index e1c6d34976..0000000000 --- a/src/3rdparty/angle/src/third_party/murmurhash/MurmurHash3.h +++ /dev/null @@ -1,37 +0,0 @@ -//----------------------------------------------------------------------------- -// MurmurHash3 was written by Austin Appleby, and is placed in the public -// domain. The author hereby disclaims copyright to this source code. - -#ifndef _MURMURHASH3_H_ -#define _MURMURHASH3_H_ - -//----------------------------------------------------------------------------- -// Platform-specific functions and macros - -// Microsoft Visual Studio - -#if defined(_MSC_VER) && (_MSC_VER < 1600) - -typedef unsigned char uint8_t; -typedef unsigned int uint32_t; -typedef unsigned __int64 uint64_t; - -// Other compilers - -#else // defined(_MSC_VER) - -#include - -#endif // !defined(_MSC_VER) - -//----------------------------------------------------------------------------- - -void MurmurHash3_x86_32 ( const void * key, int len, uint32_t seed, void * out ); - -void MurmurHash3_x86_128 ( const void * key, int len, uint32_t seed, void * out ); - -void MurmurHash3_x64_128 ( const void * key, int len, uint32_t seed, void * out ); - -//----------------------------------------------------------------------------- - -#endif // _MURMURHASH3_H_ diff --git a/src/3rdparty/angle/src/third_party/systeminfo/SystemInfo.cpp b/src/3rdparty/angle/src/third_party/systeminfo/SystemInfo.cpp index fc05526681..97dfcaac51 100644 --- a/src/3rdparty/angle/src/third_party/systeminfo/SystemInfo.cpp +++ b/src/3rdparty/angle/src/third_party/systeminfo/SystemInfo.cpp @@ -26,7 +26,7 @@ #include #include "common/platform.h" -#if _WIN32_WINNT_WINBLUE && WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP +#if _WIN32_WINNT_WINBLUE #include #endif diff --git a/src/3rdparty/angle/src/third_party/trace_event/trace_event.h b/src/3rdparty/angle/src/third_party/trace_event/trace_event.h index 3c85d22efa..bdb8804428 100644 --- a/src/3rdparty/angle/src/third_party/trace_event/trace_event.h +++ b/src/3rdparty/angle/src/third_party/trace_event/trace_event.h @@ -690,27 +690,27 @@ static inline void setTraceValue(const std::string& arg, // store pointers to the internal c_str and pass through to the tracing API, the // arg values must live throughout these procedures. -static inline angle::Platform::TraceEventHandle addTraceEvent( - char phase, - const unsigned char* categoryEnabled, - const char* name, - unsigned long long id, - unsigned char flags) { +static inline angle::TraceEventHandle addTraceEvent(char phase, + const unsigned char *categoryEnabled, + const char *name, + unsigned long long id, + unsigned char flags) +{ return TRACE_EVENT_API_ADD_TRACE_EVENT( phase, categoryEnabled, name, id, zeroNumArgs, 0, 0, 0, flags); } -template -static inline angle::Platform::TraceEventHandle addTraceEvent( - char phase, - const unsigned char* categoryEnabled, - const char* name, - unsigned long long id, - unsigned char flags, - const char* arg1Name, - const ARG1_TYPE& arg1Val) { +template +static inline angle::TraceEventHandle addTraceEvent(char phase, + const unsigned char *categoryEnabled, + const char *name, + unsigned long long id, + unsigned char flags, + const char *arg1Name, + const ARG1_TYPE &arg1Val) +{ const int numArgs = 1; unsigned char argTypes[1]; unsigned long long argValues[1]; @@ -721,17 +721,17 @@ static inline angle::Platform::TraceEventHandle addTraceEvent( flags); } -template -static inline angle::Platform::TraceEventHandle addTraceEvent( - char phase, - const unsigned char* categoryEnabled, - const char* name, - unsigned long long id, - unsigned char flags, - const char* arg1Name, - const ARG1_TYPE& arg1Val, - const char* arg2Name, - const ARG2_TYPE& arg2Val) { +template +static inline angle::TraceEventHandle addTraceEvent(char phase, + const unsigned char *categoryEnabled, + const char *name, + unsigned long long id, + unsigned char flags, + const char *arg1Name, + const ARG1_TYPE &arg1Val, + const char *arg2Name, + const ARG2_TYPE &arg2Val) +{ const int numArgs = 2; const char* argNames[2] = { arg1Name, arg2Name }; unsigned char argTypes[2]; diff --git a/src/angle/patches/0001-ANGLE-Improve-Windows-Phone-Support.patch b/src/angle/patches/0001-ANGLE-Improve-Windows-Phone-Support.patch deleted file mode 100644 index e8f11b5172..0000000000 --- a/src/angle/patches/0001-ANGLE-Improve-Windows-Phone-Support.patch +++ /dev/null @@ -1,464 +0,0 @@ -From bbc3a5f89821030dd2772cd8015070a3da9ad57e Mon Sep 17 00:00:00 2001 -From: Oliver Wolff -Date: Mon, 29 Feb 2016 11:09:24 +0100 -Subject: [PATCH 1/7] ANGLE: Improve Windows Phone Support - -This contains compile fixes for Windows Phone as well as improved -orientation handling. - -Change-Id: I5011e9980957ff0797db179b36c3be9cac6df497 ---- - src/3rdparty/angle/src/common/platform.h | 2 ++ - .../renderer/d3d/d3d11/DebugAnnotator11.cpp | 2 +- - .../src/libANGLE/renderer/d3d/d3d11/NativeWindow.h | 4 +++ - .../src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp | 8 ++++- - .../libANGLE/renderer/d3d/d3d11/SwapChain11.cpp | 40 ++++++++++++++++++++++ - .../d3d/d3d11/winrt/CoreWindowNativeWindow.cpp | 33 ++++++++++++++++-- - .../d3d/d3d11/winrt/CoreWindowNativeWindow.h | 35 ++++++++++++++++++- - .../d3d/d3d11/winrt/InspectableNativeWindow.cpp | 12 +++++++ - .../d3d/d3d11/winrt/InspectableNativeWindow.h | 14 +++++++- - src/3rdparty/angle/src/libANGLE/validationEGL.cpp | 4 ++- - .../src/third_party/systeminfo/SystemInfo.cpp | 4 +-- - 11 files changed, 148 insertions(+), 10 deletions(-) - -diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h -index 56db297..4e3851c 100644 ---- a/src/3rdparty/angle/src/common/platform.h -+++ b/src/3rdparty/angle/src/common/platform.h -@@ -68,7 +68,9 @@ - # if defined(ANGLE_ENABLE_WINDOWS_STORE) - # include - # if defined(_DEBUG) -+# if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP - # include -+# endif - # include - # endif - # endif -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp -index f9d28e8..2e42859 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp -@@ -77,7 +77,7 @@ bool DebugAnnotator11::getStatus() - } - - return true; // Default if initializeDevice() failed --#elif defined(_DEBUG) -+#elif defined(_DEBUG) && (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) - static bool underCapture = true; - - // ID3DUserDefinedAnnotation::GetStatus doesn't work with the Graphics Diagnostics tools in -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h -index f28ce4f..1c94538 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h -@@ -54,6 +54,7 @@ namespace rx - class NativeWindow - { - public: -+ enum RotationFlags { RotateNone = 0, RotateLeft = 1, RotateRight = 2 }; - explicit NativeWindow(EGLNativeWindowType window, - const egl::Config *config, - bool directComposition); -@@ -62,6 +63,9 @@ class NativeWindow - bool initialize(); - bool getClientRect(LPRECT rect); - bool isIconic(); -+#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) -+ RotationFlags rotationFlags() const; -+#endif - static bool isValidNativeWindow(EGLNativeWindowType window); - - HRESULT createSwapChain(ID3D11Device* device, DXGIFactory* factory, -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp -index f7757df..03159bb 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp -@@ -10,7 +10,9 @@ - - #include - #include -+#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP - #include -+#endif - - #include "common/tls.h" - #include "common/utilities.h" -@@ -445,7 +447,11 @@ Renderer11::Renderer11(egl::Display *display) - } - } - -+#if defined(ANGLE_ENABLE_WINDOWS_STORE) -+ if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 9) -+#else - if (requestedMajorVersion == 9 && requestedMinorVersion == 3) -+#endif - { - mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_3); - } -@@ -946,12 +952,12 @@ egl::ConfigSet Renderer11::generateConfigs() const - config.bindToTextureRGBA = (colorBufferFormatInfo.format == GL_RGBA || - colorBufferFormatInfo.format == GL_BGRA_EXT); - config.colorBufferType = EGL_RGB_BUFFER; -- config.configCaveat = EGL_NONE; - config.configID = static_cast(configs.size() + 1); - // Can only support a conformant ES2 with feature level greater than 10.0. - config.conformant = (mRenderer11DeviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_0) - ? (EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT_KHR) - : 0; -+ config.configCaveat = config.conformant == EGL_NONE ? EGL_NON_CONFORMANT_CONFIG : EGL_NONE; - - // PresentPathFast may not be conformant - if (mPresentPathFastEnabled) -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp -index a56d3fa..9432a7f 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp -@@ -222,8 +222,14 @@ EGLint SwapChain11::resetOffscreenColorBuffer(int backbufferWidth, int backbuffe - const bool useSharedResource = !mNativeWindow.getNativeWindow() && mRenderer->getShareHandleSupport(); - - D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; -+#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) -+ const int textureLength = std::max(backbufferWidth, backbufferHeight); -+ offscreenTextureDesc.Width = textureLength; -+ offscreenTextureDesc.Height = textureLength; -+#else - offscreenTextureDesc.Width = backbufferWidth; - offscreenTextureDesc.Height = backbufferHeight; -+#endif - offscreenTextureDesc.Format = backbufferFormatInfo.texFormat; - offscreenTextureDesc.MipLevels = 1; - offscreenTextureDesc.ArraySize = 1; -@@ -336,8 +342,14 @@ EGLint SwapChain11::resetOffscreenDepthBuffer(int backbufferWidth, int backbuffe - d3d11::GetTextureFormatInfo(mDepthBufferFormat, mRenderer->getRenderer11DeviceCaps()); - - D3D11_TEXTURE2D_DESC depthStencilTextureDesc; -+#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) -+ const int textureLength = std::max(backbufferWidth, backbufferHeight); -+ depthStencilTextureDesc.Width = textureLength; -+ depthStencilTextureDesc.Height = textureLength; -+#else - depthStencilTextureDesc.Width = backbufferWidth; - depthStencilTextureDesc.Height = backbufferHeight; -+#endif - depthStencilTextureDesc.Format = depthBufferFormatInfo.texFormat; - depthStencilTextureDesc.MipLevels = 1; - depthStencilTextureDesc.ArraySize = 1; -@@ -422,6 +434,7 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) - return EGL_SUCCESS; - } - -+#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) - // Can only call resize if we have already created our swap buffer and resources - ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView && mBackBufferSRView); - -@@ -479,6 +492,12 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) - mFirstSwap = true; - - return resetOffscreenBuffers(backbufferWidth, backbufferHeight); -+#else -+ // Do nothing on Windows Phone apart from updating the internal buffer/width height -+ mWidth = backbufferWidth; -+ mHeight = backbufferHeight; -+ return EGL_SUCCESS; -+#endif - } - - DXGI_FORMAT SwapChain11::getSwapChainNativeFormat() const -@@ -704,6 +723,21 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, - float x2 = ((x + width) / float(mWidth)) * 2.0f - 1.0f; - float y2 = ((y + height) / float(mHeight)) * 2.0f - 1.0f; - -+#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) -+ const float dim = std::max(mWidth, mHeight); -+ float u1 = x / dim; -+ float v1 = y / dim; -+ float u2 = (x + width) / dim; -+ float v2 = (y + height) / dim; -+ -+ const NativeWindow::RotationFlags flags = mNativeWindow.rotationFlags(); -+ const bool rotateL = flags == NativeWindow::RotateLeft; -+ const bool rotateR = flags == NativeWindow::RotateRight; -+ d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, rotateL ? u2 : u1, rotateR ? v2 : v1); -+ d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, rotateR ? u2 : u1, rotateL ? v1 : v2); -+ d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, rotateR ? u1 : u2, rotateL ? v2 : v1); -+ d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, rotateL ? u1 : u2, rotateR ? v1 : v2); -+#else - float u1 = x / float(mWidth); - float v1 = y / float(mHeight); - float u2 = (x + width) / float(mWidth); -@@ -723,6 +757,7 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, - d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v2); - d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v1); - d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v2); -+#endif - - deviceContext->Unmap(mQuadVB, 0); - -@@ -752,8 +787,13 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, - D3D11_VIEWPORT viewport; - viewport.TopLeftX = 0; - viewport.TopLeftY = 0; -+#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) -+ viewport.Width = (rotateL || rotateR) ? mHeight : mWidth; -+ viewport.Height = (rotateL || rotateR) ? mWidth : mHeight; -+#else - viewport.Width = static_cast(mWidth); - viewport.Height = static_cast(mHeight); -+#endif - viewport.MinDepth = 0.0f; - viewport.MaxDepth = 1.0f; - deviceContext->RSSetViewports(1, &viewport); -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp -index 71f0e42..6a4795a 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp -@@ -8,8 +8,6 @@ - - #include "libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h" - --#include -- - using namespace ABI::Windows::Foundation::Collections; - - namespace rx -@@ -21,6 +19,7 @@ CoreWindowNativeWindow::~CoreWindowNativeWindow() - - bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet *propertySet) - { -+ mOrientationChangedEventToken.value = 0; - ComPtr props = propertySet; - ComPtr win = window; - SIZE swapChainSize = {}; -@@ -100,6 +99,16 @@ bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet - - if (SUCCEEDED(result)) - { -+ ComPtr displayInformation; -+ result = GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayInformation).Get(), &displayInformation); -+ if (SUCCEEDED(result)) -+ { -+ result = displayInformation->GetForCurrentView(&mDisplayInformation); -+ } -+ } -+ -+ if (SUCCEEDED(result)) -+ { - mNewClientRect = mClientRect; - mClientRectChanged = false; - return registerForSizeChangeEvents(); -@@ -117,6 +126,15 @@ bool CoreWindowNativeWindow::registerForSizeChangeEvents() - result = mCoreWindow->add_SizeChanged(sizeChangedHandler.Get(), &mSizeChangedEventToken); - } - -+#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) -+ ComPtr orientationChangedHandler; -+ result = sizeChangedHandler.As(&orientationChangedHandler); -+ if (SUCCEEDED(result)) -+ { -+ result = mDisplayInformation->add_OrientationChanged(orientationChangedHandler.Get(), &mOrientationChangedEventToken); -+ } -+#endif -+ - if (SUCCEEDED(result)) - { - return true; -@@ -131,7 +149,16 @@ void CoreWindowNativeWindow::unregisterForSizeChangeEvents() - { - (void)mCoreWindow->remove_SizeChanged(mSizeChangedEventToken); - } -+ -+#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) -+ if (mDisplayInformation) -+ { -+ (void)mDisplayInformation->remove_OrientationChanged(mOrientationChangedEventToken); -+ } -+#endif -+ - mSizeChangedEventToken.value = 0; -+ mOrientationChangedEventToken.value = 0; - } - - HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, -@@ -168,7 +195,7 @@ HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, - if (SUCCEEDED(result)) - { - --#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) -+#if 0 //(WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) // Qt: allow Windows Phone to resize, but don't modify the backing texture in the swap chain. - // Test if swapchain supports resize. On Windows Phone devices, this will return DXGI_ERROR_UNSUPPORTED. On - // other devices DXGI_ERROR_INVALID_CALL should be returned because the combination of flags passed - // (DXGI_SWAP_CHAIN_FLAG_NONPREROTATED | DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE) are invalid flag combinations. -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h -index 7747005..4de235a 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h -@@ -12,8 +12,10 @@ - #include "libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h" - - #include -+#include - - typedef ABI::Windows::Foundation::__FITypedEventHandler_2_Windows__CUI__CCore__CCoreWindow_Windows__CUI__CCore__CWindowSizeChangedEventArgs_t IWindowSizeChangedEventHandler; -+typedef ABI::Windows::Foundation::__FITypedEventHandler_2_Windows__CGraphics__CDisplay__CDisplayInformation_IInspectable_t IDisplayOrientationEventHandler; - - namespace rx - { -@@ -42,11 +44,13 @@ class CoreWindowNativeWindow : public InspectableNativeWindow, public std::enabl - private: - ComPtr mCoreWindow; - ComPtr> mPropertyMap; -+ ComPtr mDisplayInformation; -+ EventRegistrationToken mOrientationChangedEventToken; - }; - - [uuid(7F924F66-EBAE-40E5-A10B-B8F35E245190)] - class CoreWindowSizeChangedHandler : -- public Microsoft::WRL::RuntimeClass, IWindowSizeChangedEventHandler> -+ public Microsoft::WRL::RuntimeClass, IWindowSizeChangedEventHandler, IDisplayOrientationEventHandler> - { - public: - CoreWindowSizeChangedHandler() { } -@@ -78,6 +82,35 @@ class CoreWindowSizeChangedHandler : - return S_OK; - } - -+ IFACEMETHOD(Invoke)(ABI::Windows::Graphics::Display::IDisplayInformation *displayInformation, IInspectable *) -+ { -+ #if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) -+ NativeWindow::RotationFlags flags = NativeWindow::RotateNone; -+ ABI::Windows::Graphics::Display::DisplayOrientations orientation; -+ if (SUCCEEDED(displayInformation->get_CurrentOrientation(&orientation))) -+ { -+ switch (orientation) -+ { -+ case ABI::Windows::Graphics::Display::DisplayOrientations_Landscape: -+ flags = NativeWindow::RotateLeft; -+ break; -+ case ABI::Windows::Graphics::Display::DisplayOrientations_LandscapeFlipped: -+ flags = NativeWindow::RotateRight; -+ break; -+ default: -+ break; -+ } -+ } -+ std::shared_ptr host = mHost.lock(); -+ if (host) -+ { -+ host->setRotationFlags(flags); -+ } -+ #endif -+ return S_OK; -+ } -+ -+ - private: - std::weak_ptr mHost; - }; -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp -index 47a6dae..c9b203e 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp -@@ -80,6 +80,18 @@ bool NativeWindow::getClientRect(RECT *rect) - return false; - } - -+#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) -+NativeWindow::RotationFlags NativeWindow::rotationFlags() const -+{ -+ if (mImpl) -+ { -+ return mImpl->rotationFlags(); -+ } -+ -+ return NativeWindow::RotateNone; -+} -+#endif -+ - bool NativeWindow::isIconic() - { - return false; -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h -index 4b9cf80..70e5fe7 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h -@@ -36,7 +36,8 @@ class InspectableNativeWindow - mSwapChainScale(1.0f), - mClientRectChanged(false), - mClientRect({0,0,0,0}), -- mNewClientRect({0,0,0,0}) -+ mNewClientRect({0,0,0,0}), -+ mRotationFlags(NativeWindow::RotateNone) - { - mSizeChangedEventToken.value = 0; - } -@@ -94,6 +95,16 @@ class InspectableNativeWindow - } - } - -+ NativeWindow::RotationFlags rotationFlags() const -+ { -+ return mRotationFlags; -+ } -+ -+ void setRotationFlags(NativeWindow::RotationFlags flags) -+ { -+ mRotationFlags = flags; -+ } -+ - protected: - virtual HRESULT scaleSwapChain(const SIZE &windowSize, const RECT &clientRect) = 0; - -@@ -104,6 +115,7 @@ class InspectableNativeWindow - RECT mClientRect; - RECT mNewClientRect; - bool mClientRectChanged; -+ NativeWindow::RotationFlags mRotationFlags; - - EventRegistrationToken mSizeChangedEventToken; - }; -diff --git a/src/3rdparty/angle/src/libANGLE/validationEGL.cpp b/src/3rdparty/angle/src/libANGLE/validationEGL.cpp -index bff3c94..972f6a7 100644 ---- a/src/3rdparty/angle/src/libANGLE/validationEGL.cpp -+++ b/src/3rdparty/angle/src/libANGLE/validationEGL.cpp -@@ -269,7 +269,7 @@ Error ValidateCreateContext(Display *display, Config *configuration, gl::Context - return Error(EGL_BAD_CONFIG); - } - -- if (clientMajorVersion == 3 && !(configuration->conformant & EGL_OPENGL_ES3_BIT_KHR)) -+ if (clientMajorVersion == 3 && !(configuration->conformant & EGL_OPENGL_ES3_BIT_KHR) && !(configuration->configCaveat & EGL_NON_CONFORMANT_CONFIG)) - { - return Error(EGL_BAD_CONFIG); - } -@@ -496,6 +496,7 @@ Error ValidateCreatePbufferSurface(Display *display, Config *config, const Attri - return Error(EGL_BAD_MATCH); - } - -+#if !defined(ANGLE_ENABLE_WINDOWS_STORE) // On Windows Store, we know the originating texture came from D3D11, so bypass this check - const Caps &caps = display->getCaps(); - - EGLenum textureFormat = attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE); -@@ -519,6 +520,7 @@ Error ValidateCreatePbufferSurface(Display *display, Config *config, const Attri - { - return Error(EGL_BAD_MATCH); - } -+#endif - - return Error(EGL_SUCCESS); - } -diff --git a/src/3rdparty/angle/src/third_party/systeminfo/SystemInfo.cpp b/src/3rdparty/angle/src/third_party/systeminfo/SystemInfo.cpp -index 97dfcaa..e082895 100644 ---- a/src/3rdparty/angle/src/third_party/systeminfo/SystemInfo.cpp -+++ b/src/3rdparty/angle/src/third_party/systeminfo/SystemInfo.cpp -@@ -26,7 +26,7 @@ - #include - #include "common/platform.h" - --#if _WIN32_WINNT_WINBLUE -+#if _WIN32_WINNT_WINBLUE && WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP - #include - #endif - --- -2.7.0.windows.1 - diff --git a/src/angle/patches/0001-ANGLE-Use-pixel-sizes-in-the-XAML-swap-chain.patch b/src/angle/patches/0001-ANGLE-Use-pixel-sizes-in-the-XAML-swap-chain.patch new file mode 100644 index 0000000000..618ad08b4b --- /dev/null +++ b/src/angle/patches/0001-ANGLE-Use-pixel-sizes-in-the-XAML-swap-chain.patch @@ -0,0 +1,135 @@ +From b1f0b50c19ec17df554faa1335d2b989e262b831 Mon Sep 17 00:00:00 2001 +From: Oliver Wolff +Date: Wed, 22 Aug 2018 09:21:04 +0200 +Subject: [PATCH 1/8] ANGLE: Use pixel sizes in the XAML swap chain + +This is necessary for Qt applications, as they render to GL in physical +pixels. This is consistent with the CoreWindow swap chain behavior. + +In order to achieve proper scaling, the scale factor has to be initialized +properly in InspectableNativeWindow. + +This change only affects Windows Runtime targets. + +Change-Id: I92a365f33752ed49c960e390bbf89cc33ccc8004 +--- + .../d3d/d3d11/winrt/CoreWindowNativeWindow.cpp | 23 ------------------- + .../d3d/d3d11/winrt/CoreWindowNativeWindow.h | 2 -- + .../d3d/d3d11/winrt/InspectableNativeWindow.cpp | 26 +++++++++++++++++++--- + .../d3d/d3d11/winrt/InspectableNativeWindow.h | 7 +++++- + 4 files changed, 29 insertions(+), 29 deletions(-) + +diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp +index dd37ace87e..1ef90e7b09 100644 +--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp ++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp +@@ -205,27 +205,4 @@ HRESULT GetCoreWindowSizeInPixels(const ComPtr displayProperties; +- +- if (SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), displayProperties.GetAddressOf()))) +- { +- float dpi = 96.0f; +- if (SUCCEEDED(displayProperties->get_LogicalDpi(&dpi))) +- { +- return dpi; +- } +- } +- +- // Return 96 dpi as a default if display properties cannot be obtained. +- return 96.0f; +-} +- +-float ConvertDipsToPixels(float dips) +-{ +- static const float dipsPerInch = 96.0f; +- return dips * GetLogicalDpi() / dipsPerInch; +-} + } +diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h +index d43bf0ba5f..21855c2c3b 100644 +--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h ++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h +@@ -19,8 +19,6 @@ typedef ABI::Windows::Foundation::__FITypedEventHandler_2_Windows__CUI__CCore__C + + namespace rx + { +-float ConvertDipsToPixels(float dips); +- + class CoreWindowNativeWindow : public InspectableNativeWindow, public std::enable_shared_from_this + { + public: +diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp +index cc81521320..1bd796e58f 100644 +--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp ++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp +@@ -270,8 +270,28 @@ HRESULT GetOptionalSinglePropertyValue(const ComPtr(ConvertDipsToPixels(size.Width)), ++ static_cast(ConvertDipsToPixels(size.Height))}; ++} ++ ++float GetLogicalDpi() ++{ ++ ComPtr displayProperties; ++ float dpi = 96.0f; ++ ++ if (SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), displayProperties.GetAddressOf()))) ++ { ++ if (SUCCEEDED(displayProperties->get_LogicalDpi(&dpi))) ++ { ++ return dpi; ++ } ++ } ++ return dpi; ++} ++ ++float ConvertDipsToPixels(float dips) ++{ ++ static const float dipsPerInch = 96.0f; ++ return lround((dips * GetLogicalDpi() / dipsPerInch)); + } + } +diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h +index 3e67269f36..d81c3e5fb9 100644 +--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h ++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h +@@ -30,6 +30,9 @@ using namespace ABI::Windows::Foundation::Collections; + + namespace rx + { ++float ConvertDipsToPixels(float dips); ++float GetLogicalDpi(); ++ + class InspectableNativeWindow + { + public: +@@ -37,12 +40,14 @@ class InspectableNativeWindow + mSupportsSwapChainResize(true), + mSwapChainSizeSpecified(false), + mSwapChainScaleSpecified(false), +- mSwapChainScale(1.0f), + mClientRectChanged(false), + mClientRect({0,0,0,0}), + mNewClientRect({0,0,0,0}) + { + mSizeChangedEventToken.value = 0; ++ mSwapChainScale = 96.0f / GetLogicalDpi(); ++ if (mSwapChainScale != 1.0f) ++ mSwapChainScaleSpecified = true; + } + virtual ~InspectableNativeWindow(){} + +-- +2.15.0.windows.1 + diff --git a/src/angle/patches/0001-Fix-build-for-MinGW.patch b/src/angle/patches/0001-Fix-build-for-MinGW.patch new file mode 100644 index 0000000000..186acd39dc --- /dev/null +++ b/src/angle/patches/0001-Fix-build-for-MinGW.patch @@ -0,0 +1,26 @@ +From 75f877269a86aa111afbf816be14ef6c36ea6478 Mon Sep 17 00:00:00 2001 +From: Oliver Wolff +Date: Mon, 2 Jul 2018 12:56:39 +0200 +Subject: [PATCH] Fix build for MinGW + +SSE is not properly supported for Mingw yet. +--- + src/common/platform.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/srccommon/platform.h +index 0065fd2..47cd57b 100644 +--- a/src/3rdparty/angle/src/common/platform.h ++++ b/src/3rdparty/angle/src/common/platform.h +@@ -86,7 +86,7 @@ + #if defined(_MSC_VER) && !defined(_M_ARM) + #include + #define ANGLE_USE_SSE +-#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) ++#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) && !defined(__MINGW32__) + #include + #define ANGLE_USE_SSE + #endif +-- +2.10.2.windows.1 + diff --git a/src/angle/patches/0003-ANGLE-Add-support-for-querying-platform-device.patch b/src/angle/patches/0002-ANGLE-Add-support-for-querying-platform-device.patch similarity index 70% rename from src/angle/patches/0003-ANGLE-Add-support-for-querying-platform-device.patch rename to src/angle/patches/0002-ANGLE-Add-support-for-querying-platform-device.patch index ed0f7247cb..d548ce465f 100644 --- a/src/angle/patches/0003-ANGLE-Add-support-for-querying-platform-device.patch +++ b/src/angle/patches/0002-ANGLE-Add-support-for-querying-platform-device.patch @@ -1,7 +1,7 @@ -From 037550af14ce0ecebad96d637d7185b60d760b5d Mon Sep 17 00:00:00 2001 -From: Oliver Wolff -Date: Tue, 1 Mar 2016 13:31:08 +0100 -Subject: [PATCH 3/7] ANGLE: Add support for querying platform device +From 2f2aabec376cb749a7d0db9e7f754fbfd28b8a72 Mon Sep 17 00:00:00 2001 +From: Oliver Wolff +Date: Wed, 22 Aug 2018 12:58:13 +0200 +Subject: [PATCH 2/8] ANGLE: Add support for querying platform device The EGL_EXT_device_base extension allows for querying the platform device of the graphics hardware via eglQueryDisplayAttribEXT(). @@ -23,10 +23,10 @@ Change-Id: Ib3dfd3edc47dbcc02b07f71980ba785508f2ee57 4 files changed, 12 insertions(+) diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp -index 93f6990..0347828 100644 +index 8e78b71a36..ceb022d14c 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp -@@ -334,6 +334,10 @@ egl::Error SurfaceD3D::querySurfacePointerANGLE(EGLint attribute, void **value) +@@ -351,6 +351,10 @@ egl::Error SurfaceD3D::querySurfacePointerANGLE(EGLint attribute, void **value) { *value = mSwapChain->getKeyedMutex(); } @@ -36,24 +36,24 @@ index 93f6990..0347828 100644 + } else UNREACHABLE(); - return egl::Error(EGL_SUCCESS); + return egl::NoError(); diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SwapChainD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SwapChainD3D.h -index 1ef6611..171cab5 100644 +index 81c3d13da4..017737b878 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SwapChainD3D.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SwapChainD3D.h -@@ -41,6 +41,7 @@ class SwapChainD3D : angle::NonCopyable - virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval) = 0; - virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height) = 0; +@@ -58,6 +58,7 @@ class SwapChainD3D : angle::NonCopyable + EGLint width, + EGLint height) = 0; virtual void recreate() = 0; -+ virtual void *getDevice() { return NULL; } ++ virtual void *getDevice() { return nullptr; } virtual RenderTargetD3D *getColorRenderTarget() = 0; virtual RenderTargetD3D *getDepthStencilRenderTarget() = 0; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp -index 9432a7f..5a6f202 100644 +index 19bcaae776..05bb5d9863 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp -@@ -915,4 +915,9 @@ void SwapChain11::recreate() +@@ -1007,6 +1007,11 @@ void SwapChain11::recreate() // possibly should use this method instead of reset } @@ -62,20 +62,22 @@ index 9432a7f..5a6f202 100644 + return mRenderer->getDevice(); +} + - } + RenderTargetD3D *SwapChain11::getColorRenderTarget() + { + return &mColorRenderTarget; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h -index 583e29c..99198c6 100644 +index 5ce2af193d..eca068210b 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h -@@ -48,6 +48,8 @@ class SwapChain11 : public SwapChainD3D - EGLint getHeight() const { return mHeight; } - void *getKeyedMutex() override { return mKeyedMutex; } +@@ -61,6 +61,8 @@ class SwapChain11 final : public SwapChainD3D + void *getKeyedMutex() override; + EGLint getSamples() const { return mEGLSamples; } -+ virtual void *getDevice(); ++ void *getDevice() override; + + egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override; + private: - void release(); - void initPassThroughResources(); -- -2.7.0.windows.1 +2.15.0.windows.1 diff --git a/src/angle/patches/0002-ANGLE-Dynamically-load-D3D-compiler-from-a-list.patch b/src/angle/patches/0002-ANGLE-Dynamically-load-D3D-compiler-from-a-list.patch deleted file mode 100644 index 9503ae1090..0000000000 --- a/src/angle/patches/0002-ANGLE-Dynamically-load-D3D-compiler-from-a-list.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 7dd1de8a519324e6ec7dbfede1b446980cb5954f Mon Sep 17 00:00:00 2001 -From: Oliver Wolff -Date: Tue, 1 Mar 2016 13:28:02 +0100 -Subject: [PATCH 2/7] ANGLE: Dynamically load D3D compiler from a list - -If the default compiler cannot be found, load it from a list of DLL names, -including a non-versioned proxy DLL provided by Qt. On Desktop Windows, -the default compiler can also be specified by an environment variable, -QT_D3DCOMPILER_DLL. - -Change-Id: Ic6d6e37095b838b8a636b029b72467f156b850cb ---- - .../src/libANGLE/renderer/d3d/HLSLCompiler.cpp | 26 ++++++++++++++++++++++ - 1 file changed, 26 insertions(+) - -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp -index e8b1af3..0d298bb 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp -@@ -12,6 +12,10 @@ - #include "libANGLE/histogram_macros.h" - #include "third_party/trace_event/trace_event.h" - -+#ifndef QT_D3DCOMPILER_DLL -+#define QT_D3DCOMPILER_DLL D3DCOMPILER_DLL -+#endif -+ - #if ANGLE_APPEND_ASSEMBLY_TO_SHADER_DEBUG_INFO == ANGLE_ENABLED - namespace - { -@@ -128,6 +132,28 @@ gl::Error HLSLCompiler::initialize() - } - #endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES - -+ // Load the compiler DLL specified by the environment, or default to QT_D3DCOMPILER_DLL -+ const wchar_t *defaultCompiler = _wgetenv(L"QT_D3DCOMPILER_DLL"); -+ if (!defaultCompiler) -+ defaultCompiler = QT_D3DCOMPILER_DLL; -+ -+ const wchar_t *compilerDlls[] = { -+ defaultCompiler, -+ L"d3dcompiler_47.dll", -+ L"d3dcompiler_46.dll", -+ L"d3dcompiler_43.dll", -+ 0 -+ }; -+ -+ // Load the first available known compiler DLL -+ for (int i = 0; compilerDlls[i]; ++i) -+ { -+ mD3DCompilerModule = LoadLibrary(compilerDlls[i]); -+ if (mD3DCompilerModule) -+ break; -+ } -+ -+ - if (!mD3DCompilerModule) - { - // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with. --- -2.7.0.windows.1 - diff --git a/src/angle/patches/0002-ANGLE-Fix-build-for-ARM.patch b/src/angle/patches/0002-ANGLE-Fix-build-for-ARM.patch new file mode 100644 index 0000000000..04517a116e --- /dev/null +++ b/src/angle/patches/0002-ANGLE-Fix-build-for-ARM.patch @@ -0,0 +1,43 @@ +From 416fb93dae5009bb51da9f6720a95918a2c79e78 Mon Sep 17 00:00:00 2001 +From: Oliver Wolff +Date: Fri, 17 Aug 2018 09:54:15 +0200 +Subject: [PATCH] ANGLE: Fix build for ARM + +__popcnt is not available when building for ARM. This patch uses the +approach that is also used in Microsoft's ANGLE fork. + +Change-Id: I98bac36a3b36b0aa81f3b483d3d12cce9f6c5c87 +--- + src/3rdparty/angle/src/common/mathutil.h | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/src/3rdparty/angle/src/common/mathutil.h b/src/3rdparty/angle/src/common/mathutil.h +index ca6efc567f..372e432066 100644 +--- a/src/3rdparty/angle/src/common/mathutil.h ++++ b/src/3rdparty/angle/src/common/mathutil.h +@@ -884,6 +884,14 @@ inline uint32_t BitfieldReverse(uint32_t value) + + // Count the 1 bits. + #if defined(ANGLE_PLATFORM_WINDOWS) ++#if defined(_M_ARM) ++inline int BitCount(uint32_t bits) ++{ ++ bits = bits - ((bits >> 1) & 0x55555555); ++ bits = (bits & 0x33333333) + ((bits >> 2) & 0x33333333); ++ return (((bits + (bits >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24; ++} ++#else // _M_ARM + inline int BitCount(uint32_t bits) + { + return static_cast(__popcnt(bits)); +@@ -893,6 +901,7 @@ inline int BitCount(uint64_t bits) + { + return static_cast(__popcnt64(bits)); + } ++#endif // !_M_ARM + #endif // defined(ANGLE_IS_64_BIT_CPU) + #endif // defined(ANGLE_PLATFORM_WINDOWS) + +-- +2.15.0.windows.1 + diff --git a/src/angle/patches/0002-ANGLE-Fix-compilation-with-MinGW.patch b/src/angle/patches/0002-ANGLE-Fix-compilation-with-MinGW.patch deleted file mode 100644 index f42ff2141b..0000000000 --- a/src/angle/patches/0002-ANGLE-Fix-compilation-with-MinGW.patch +++ /dev/null @@ -1,892 +0,0 @@ -From c6b9e598384563a641efdff56fdbdb0d7a561ec4 Mon Sep 17 00:00:00 2001 -From: Oliver Wolff -Date: Thu, 10 Mar 2016 15:12:58 +0100 -Subject: [PATCH] ANGLE: Fix compilation with MinGW - -This adds definition guards for Direct3D 11 and DirectX SDK layers, which -are only available in very recent versions (4.9.2 rev 4) of MinGW builds. -It additionally adds a few missing includes needed for compilation. - -Change-Id: I254c208209c0071fae5efb6727f2b3cfd5542da6 ---- - src/3rdparty/angle/src/common/platform.h | 10 ++- - .../src/libANGLE/renderer/d3d/HLSLCompiler.cpp | 9 +++ - .../src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp | 6 ++ - .../src/libANGLE/renderer/d3d/d3d11/Clear11.cpp | 4 + - .../renderer/d3d/d3d11/DebugAnnotator11.cpp | 10 +++ - .../libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h | 2 + - .../libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp | 2 + - .../src/libANGLE/renderer/d3d/d3d11/Query11.cpp | 14 ++++++++++++++ - .../src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp | 32 +++++++- - .../src/libANGLE/renderer/d3d/d3d11/Renderer11.h | 4 + - .../libANGLE/renderer/d3d/d3d11/SwapChain11.cpp | 10 +++ - .../src/libANGLE/renderer/d3d/d3d11/SwapChain11.h | 2 + - .../renderer/d3d/d3d11/renderer11_utils.cpp | 92 ++++++++++++++++++++++ - .../renderer/d3d/d3d11/win32/NativeWindow.cpp | 8 ++ - .../src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp | 4 +- - src/3rdparty/angle/src/libEGL/libEGL_mingw32.def | 27 ++++--- - src/3rdparty/angle/src/libEGL/libEGLd_mingw32.def | 19 +++++ - .../angle/src/libGLESv2/libGLESv2_mingw32.def | 32 +++++++- - .../angle/src/libGLESv2/libGLESv2d_mingw32.def | 32 +++++++- - 19 files changed, 296 insertions(+), 21 deletions(-) - -diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h -index 4e3851c..be4cb94 100644 ---- a/src/3rdparty/angle/src/common/platform.h -+++ b/src/3rdparty/angle/src/common/platform.h -@@ -59,9 +59,17 @@ - # if defined(ANGLE_ENABLE_D3D11) - # include - # include --# include - # include -+# if defined(__MINGW32__) && !defined(__d3d11sdklayers_h__) -+# define ANGLE_MINGW32_COMPAT -+# endif -+# if defined(_MSC_VER) && _MSC_VER >= 1800 -+# define ANGLE_ENABLE_D3D11_1 -+# endif -+# if defined(ANGLE_ENABLE_D3D11_1) -+# include - # include -+# endif - # include - # endif - -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp -index 0d298bb..df0257e 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp -@@ -25,6 +25,15 @@ namespace - - #define CREATE_COMPILER_FLAG_INFO(flag) { flag, #flag } - -+#if defined(ANGLE_MINGW32_COMPAT) -+#ifndef D3DCOMPILE_RESERVED16 -+#define D3DCOMPILE_RESERVED16 0x10000 -+#endif -+#ifndef D3DCOMPILE_RESERVED17 -+#define D3DCOMPILE_RESERVED17 0x20000 -+#endif -+#endif -+ - struct CompilerFlagInfo - { - UINT mFlag; -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp -index 66e2d67..0d5dc08 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp -@@ -29,6 +29,12 @@ GLuint ReadIndexValueFromIndices(const uint8_t *data, size_t index) - typedef GLuint (*ReadIndexValueFunction)(const uint8_t *data, size_t index); - } - -+#if defined(ANGLE_MINGW32_COMPAT) -+typedef enum D3D11_MAP_FLAG { -+ D3D11_MAP_FLAG_DO_NOT_WAIT = 0x100000 -+} D3D11_MAP_FLAG; -+#endif -+ - namespace rx - { - PackPixelsParams::PackPixelsParams() -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp -index 03b28c2..cd95c65 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp -@@ -262,7 +262,9 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl - RenderTarget11* maskedClearDepthStencil = nullptr; - - ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); -+#if defined(ANGLE_ENABLE_D3D11_1) - ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported(); -+#endif - ID3D11Device *device = mRenderer->getDevice(); - - for (size_t colorAttachmentIndex = 0; colorAttachmentIndex < colorAttachments.size(); -@@ -347,6 +349,7 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl - clearValues[3] = (clearParams.colorFClearValue.alpha >= 0.5f) ? 1.0f : 0.0f; - } - -+#if defined(ANGLE_ENABLE_D3D11_1) - if (needScissoredClear) - { - // We shouldn't reach here if deviceContext1 is unavailable. -@@ -361,6 +364,7 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl - deviceContext1->ClearView(framebufferRTV, clearValues, &rect, 1); - } - else -+#endif - { - deviceContext->ClearRenderTargetView(framebufferRTV, clearValues); - } -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp -index 2e42859..1c35ab4 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp -@@ -27,7 +27,9 @@ DebugAnnotator11::~DebugAnnotator11() - { - if (mInitialized) - { -+#if defined(ANGLE_ENABLE_D3D11_1) - SafeRelease(mUserDefinedAnnotation); -+#endif - - #if !defined(ANGLE_ENABLE_WINDOWS_STORE) - FreeLibrary(mD3d11Module); -@@ -41,7 +43,9 @@ void DebugAnnotator11::beginEvent(const wchar_t *eventName) - - if (mUserDefinedAnnotation != nullptr) - { -+#if defined(ANGLE_ENABLE_D3D11_1) - mUserDefinedAnnotation->BeginEvent(eventName); -+#endif - } - } - -@@ -51,7 +55,9 @@ void DebugAnnotator11::endEvent() - - if (mUserDefinedAnnotation != nullptr) - { -+#if defined(ANGLE_ENABLE_D3D11_1) - mUserDefinedAnnotation->EndEvent(); -+#endif - } - } - -@@ -61,7 +67,9 @@ void DebugAnnotator11::setMarker(const wchar_t *markerName) - - if (mUserDefinedAnnotation != nullptr) - { -+#if defined(ANGLE_ENABLE_D3D11_1) - mUserDefinedAnnotation->SetMarker(markerName); -+#endif - } - } - -@@ -137,8 +145,10 @@ void DebugAnnotator11::initializeDevice() - ASSERT(SUCCEEDED(hr)); - if (SUCCEEDED(hr)) - { -+#if defined(ANGLE_ENABLE_D3D11_1) - mUserDefinedAnnotation = d3d11::DynamicCastComObject(context); - ASSERT(mUserDefinedAnnotation != nullptr); -+#endif - mInitialized = true; - } - -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h -index 9da4fa2..d1a0f7f 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h -@@ -11,6 +11,8 @@ - - #include "common/debug.h" - -+struct ID3DUserDefinedAnnotation; -+ - namespace rx - { - -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp -index beffa30..186a035 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp -@@ -140,6 +140,7 @@ gl::Error Framebuffer11::discard(size_t count, const GLenum *attachments) - - gl::Error Framebuffer11::invalidateBase(size_t count, const GLenum *attachments, bool useEXTBehavior) const - { -+#if defined(ANGLE_ENABLE_D3D11_1) - ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported(); - - if (!deviceContext1) -@@ -272,6 +273,7 @@ gl::Error Framebuffer11::invalidateBase(size_t count, const GLenum *attachments, - deviceContext1->DiscardView(stencilView); - } - } -+#endif // ANGLE_ENABLE_D3D11_1 - - return gl::Error(GL_NO_ERROR); - } -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp -index c015ff4..c0bed2b 100644 -index c015ff4..972c289 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp -@@ -13,6 +13,20 @@ - - #include - -+#if defined(ANGLE_MINGW32_COMPAT) -+typedef struct D3D11_QUERY_DATA_SO_STATISTICS { -+ UINT64 NumPrimitivesWritten; -+ UINT64 PrimitivesStorageNeeded; -+} D3D11_QUERY_DATA_SO_STATISTICS; -+#endif // ANGLE_MINGW32_COMPAT -+ -+#ifdef __MINGW32__ -+typedef struct D3D11_QUERY_DATA_TIMESTAMP_DISJOINT { -+ UINT64 Frequency; -+ BOOL Disjoint; -+} D3D11_QUERY_DATA_TIMESTAMP_DISJOINT; -+#endif // MINGW32 -+ - namespace rx - { - -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp -index ea84783..62badcc 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp -@@ -10,7 +10,7 @@ - - #include - #include --#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP -+#if !defined(ANGLE_MINGW32_COMPAT) && WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP - #include - #endif - -@@ -89,6 +89,7 @@ enum - MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 = 16 - }; - -+#if defined(ANGLE_ENABLE_D3D11_1) - void CalculateConstantBufferParams(GLintptr offset, GLsizeiptr size, UINT *outFirstConstant, UINT *outNumConstants) - { - // The offset must be aligned to 256 bytes (should have been enforced by glBindBufferRange). -@@ -105,6 +106,7 @@ void CalculateConstantBufferParams(GLintptr offset, GLsizeiptr size, UINT *outFi - // This behaviour is explictly allowed according to the documentation on ID3D11DeviceContext1::PSSetConstantBuffers1 - // https://msdn.microsoft.com/en-us/library/windows/desktop/hh404649%28v=vs.85%29.aspx - } -+#endif - - enum ANGLEFeatureLevel - { -@@ -369,8 +371,10 @@ Renderer11::Renderer11(egl::Display *display) - : RendererD3D(display), - mStateCache(this), - mStateManager(this), -- mLastHistogramUpdateTime(ANGLEPlatformCurrent()->monotonicallyIncreasingTime()), -- mDebug(nullptr) -+ mLastHistogramUpdateTime(ANGLEPlatformCurrent()->monotonicallyIncreasingTime()) -+#if !defined(ANGLE_MINGW32_COMPAT) -+ ,mDebug(nullptr) -+#endif - { - mVertexDataManager = NULL; - mIndexDataManager = NULL; -@@ -572,7 +576,9 @@ egl::Error Renderer11::initialize() - // Cast the DeviceContext to a DeviceContext1. - // This could fail on Windows 7 without the Platform Update. - // Don't error in this case- just don't use mDeviceContext1. -+#if defined(ANGLE_ENABLE_D3D11_1) - mDeviceContext1 = d3d11::DynamicCastComObject(mDeviceContext); -+#endif - - IDXGIDevice *dxgiDevice = NULL; - result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); -@@ -595,6 +601,7 @@ egl::Error Renderer11::initialize() - - SafeRelease(dxgiDevice); - -+#if defined(ANGLE_ENABLE_D3D11_1) - IDXGIAdapter2 *dxgiAdapter2 = d3d11::DynamicCastComObject(mDxgiAdapter); - - // On D3D_FEATURE_LEVEL_9_*, IDXGIAdapter::GetDesc returns "Software Adapter" for the description string. -@@ -618,11 +625,14 @@ egl::Error Renderer11::initialize() - } - } - else -+#endif - { - result = mDxgiAdapter->GetDesc(&mAdapterDescription); - } - -+#if defined(ANGLE_ENABLE_D3D11_1) - SafeRelease(dxgiAdapter2); -+#endif - - if (FAILED(result)) - { -@@ -644,6 +654,7 @@ egl::Error Renderer11::initialize() - } - } - -+#if !defined(ANGLE_MINGW32_COMPAT) - // Disable some spurious D3D11 debug warnings to prevent them from flooding the output log - #if defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG) - { -@@ -671,6 +682,7 @@ egl::Error Renderer11::initialize() - #if !defined(NDEBUG) - mDebug = d3d11::DynamicCastComObject(mDevice); - #endif -+#endif // !ANGLE_MINGW32_COMPAT - - initializeDevice(); - -@@ -859,6 +871,7 @@ void Renderer11::populateRenderer11DeviceCaps() - { - HRESULT hr = S_OK; - -+#if defined(ANGLE_ENABLE_D3D11_1) - if (mDeviceContext1) - { - D3D11_FEATURE_DATA_D3D11_OPTIONS d3d11Options; -@@ -869,6 +882,7 @@ void Renderer11::populateRenderer11DeviceCaps() - mRenderer11DeviceCaps.supportsConstantBufferOffsets = (d3d11Options.ConstantBufferOffsetting != FALSE); - } - } -+#endif - - hr = mDevice->CheckFormatSupport(DXGI_FORMAT_B5G6R5_UNORM, &(mRenderer11DeviceCaps.B5G6R5support)); - if (FAILED(hr)) -@@ -888,9 +902,11 @@ void Renderer11::populateRenderer11DeviceCaps() - mRenderer11DeviceCaps.B5G5R5A1support = 0; - } - -+#if defined(ANGLE_ENABLE_D3D11_1) - IDXGIAdapter2 *dxgiAdapter2 = d3d11::DynamicCastComObject(mDxgiAdapter); - mRenderer11DeviceCaps.supportsDXGI1_2 = (dxgiAdapter2 != nullptr); - SafeRelease(dxgiAdapter2); -+#endif - } - - egl::ConfigSet Renderer11::generateConfigs() const -@@ -1308,6 +1324,7 @@ gl::Error Renderer11::setUniformBuffers(const gl::Data &data, - mCurrentConstantBufferVSOffset[uniformBufferIndex] != uniformBufferOffset || - mCurrentConstantBufferVSSize[uniformBufferIndex] != uniformBufferSize) - { -+#if defined(ANGLE_ENABLE_D3D11_1) - if (mRenderer11DeviceCaps.supportsConstantBufferOffsets && uniformBufferSize != 0) - { - UINT firstConstant = 0, numConstants = 0; -@@ -1318,6 +1335,7 @@ gl::Error Renderer11::setUniformBuffers(const gl::Data &data, - 1, &constantBuffer, &firstConstant, &numConstants); - } - else -+#endif - { - mDeviceContext->VSSetConstantBuffers( - getReservedVertexUniformBuffers() + -@@ -1369,6 +1387,7 @@ gl::Error Renderer11::setUniformBuffers(const gl::Data &data, - mCurrentConstantBufferPSOffset[uniformBufferIndex] != uniformBufferOffset || - mCurrentConstantBufferPSSize[uniformBufferIndex] != uniformBufferSize) - { -+#if defined(ANGLE_ENABLE_D3D11_1) - if (mRenderer11DeviceCaps.supportsConstantBufferOffsets && uniformBufferSize != 0) - { - UINT firstConstant = 0, numConstants = 0; -@@ -1379,6 +1398,7 @@ gl::Error Renderer11::setUniformBuffers(const gl::Data &data, - 1, &constantBuffer, &firstConstant, &numConstants); - } - else -+#endif - { - mDeviceContext->PSSetConstantBuffers( - getReservedFragmentUniformBuffers() + -@@ -2448,7 +2468,9 @@ void Renderer11::release() - SafeRelease(mDxgiFactory); - SafeRelease(mDxgiAdapter); - -+#if defined(ANGLE_ENABLE_D3D11_1) - SafeRelease(mDeviceContext1); -+#endif - - if (mDeviceContext) - { -@@ -2458,7 +2480,9 @@ void Renderer11::release() - } - - SafeRelease(mDevice); -+#if !defined(ANGLE_MINGW32_COMPAT) - SafeRelease(mDebug); -+#endif - - if (mD3d11Module) - { -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h -index 62e9816..b4e7761 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.h -@@ -28,6 +28,8 @@ class FramebufferAttachment; - struct ImageIndex; - } - -+struct ID3D11DeviceContext1; -+ - namespace rx - { - -@@ -442,7 +444,9 @@ class Renderer11 : public RendererD3D - DXGI_ADAPTER_DESC mAdapterDescription; - char mDescription[128]; - DXGIFactory *mDxgiFactory; -+#if !defined(ANGLE_MINGW32_COMPAT) - ID3D11Debug *mDebug; -+#endif - - std::vector mScratchIndexDataBuffer; - -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp -index f669f56..f80f24b 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp -@@ -58,7 +58,9 @@ SwapChain11::SwapChain11(Renderer11 *renderer, - mPassThroughResourcesInit(false), - mFirstSwap(true), - mSwapChain(nullptr), -+#if defined(ANGLE_ENABLE_D3D11_1) - mSwapChain1(nullptr), -+#endif - mKeyedMutex(nullptr), - mBackBufferTexture(nullptr), - mBackBufferRTView(nullptr), -@@ -90,7 +92,9 @@ SwapChain11::~SwapChain11() - - void SwapChain11::release() - { -+#if defined(ANGLE_ENABLE_D3D11_1) - SafeRelease(mSwapChain1); -+#endif - SafeRelease(mSwapChain); - SafeRelease(mKeyedMutex); - SafeRelease(mBackBufferTexture); -@@ -533,7 +537,9 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap - - // Release specific resources to free up memory for the new render target, while the - // old render target still exists for the purpose of preserving its contents. -+#if defined(ANGLE_ENABLE_D3D11_1) - SafeRelease(mSwapChain1); -+#endif - SafeRelease(mSwapChain); - SafeRelease(mBackBufferTexture); - SafeRelease(mBackBufferRTView); -@@ -568,7 +574,9 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap - - if (mRenderer->getRenderer11DeviceCaps().supportsDXGI1_2) - { -+#if defined(ANGLE_ENABLE_D3D11_1) - mSwapChain1 = d3d11::DynamicCastComObject(mSwapChain); -+#endif - } - - result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture); -@@ -837,6 +845,7 @@ EGLint SwapChain11::present(EGLint x, EGLint y, EGLint width, EGLint height) - - HRESULT result = S_OK; - -+#if defined(ANGLE_ENABLE_D3D11_1) - // Use IDXGISwapChain1::Present1 with a dirty rect if DXGI 1.2 is available. - if (mSwapChain1 != nullptr) - { -@@ -855,6 +864,7 @@ EGLint SwapChain11::present(EGLint x, EGLint y, EGLint width, EGLint height) - } - } - else -+#endif - { - result = mSwapChain->Present(swapInterval, 0); - } -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h -index 99198c6..adcd07a 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h -@@ -75,7 +75,9 @@ class SwapChain11 : public SwapChainD3D - - bool mFirstSwap; - DXGISwapChain *mSwapChain; -+#if defined(ANGLE_ENABLE_D3D11_1) - IDXGISwapChain1 *mSwapChain1; -+#endif - IDXGIKeyedMutex *mKeyedMutex; - - ID3D11Texture2D *mBackBufferTexture; -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp -index d1f3ea0..a1175db 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp -@@ -23,6 +23,88 @@ - #include "libANGLE/renderer/d3d/FramebufferD3D.h" - #include "libANGLE/renderer/d3d/WorkaroundsD3D.h" - -+#ifndef D3D_FL9_1_DEFAULT_MAX_ANISOTROPY -+# define D3D_FL9_1_DEFAULT_MAX_ANISOTROPY 2 -+#endif -+#ifndef D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT -+# define D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT 1 -+#endif -+#ifndef D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT -+# define D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT 4 -+#endif -+#ifndef D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT -+# define D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT 65535 -+#endif -+#ifndef D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT -+# define D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT 1048575 -+#endif -+#ifndef D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION -+# define D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION 512 -+#endif -+#ifndef D3D_FL9_3_REQ_TEXTURECUBE_DIMENSION -+# define D3D_FL9_3_REQ_TEXTURECUBE_DIMENSION 4096 -+#endif -+#ifndef D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION -+# define D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION 2048 -+#endif -+#ifndef D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION -+# define D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION 256 -+#endif -+#ifndef D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION -+# define D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION 4096 -+#endif -+#ifndef D3D11_REQ_TEXTURECUBE_DIMENSION -+# define D3D11_REQ_TEXTURECUBE_DIMENSION 16384 -+#endif -+#ifndef D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION -+# define D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION 2048 -+#endif -+#ifndef D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION -+# define D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION 2048 -+#endif -+#ifndef D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP -+# define D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP 32 -+#endif -+#ifndef D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP -+# define D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP 32 -+#endif -+#ifndef D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT -+# define D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT 32 -+#endif -+#ifndef D3D11_STANDARD_VERTEX_ELEMENT_COUNT -+# define D3D11_STANDARD_VERTEX_ELEMENT_COUNT 32 -+#endif -+#ifndef D3D10_1_SO_BUFFER_SLOT_COUNT -+# define D3D10_1_SO_BUFFER_SLOT_COUNT 4 -+#endif -+#ifndef D3D11_SO_BUFFER_SLOT_COUNT -+# define D3D11_SO_BUFFER_SLOT_COUNT 4 -+#endif -+#ifndef D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT -+# define D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT 14 -+#endif -+#ifndef D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT -+# define D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT 16 -+#endif -+#ifndef D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE -+# define D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE -8 -+#endif -+#ifndef D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE -+# define D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE 7 -+#endif -+#ifndef D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT -+# define D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT 4096 -+#endif -+#ifndef D3D11_PS_INPUT_REGISTER_COUNT -+# define D3D11_PS_INPUT_REGISTER_COUNT 32 -+#endif -+#ifndef D3D10_1_VS_OUTPUT_REGISTER_COUNT -+# define D3D10_1_VS_OUTPUT_REGISTER_COUNT 32 -+#endif -+#if defined(ANGLE_MINGW32_COMPAT) -+static const IID WKPDID_D3DDebugObjectName = { 0x429b8c22, 0x9188, 0x4b0c, 0x87, 0x42, 0xac, 0xb0, 0xbf, 0x85, 0xc2, 0x00 }; -+#endif -+ - namespace rx - { - -@@ -601,7 +683,9 @@ static size_t GetMaximumCubeMapTextureSize(D3D_FEATURE_LEVEL featureLevel) - { - switch (featureLevel) - { -+#if defined(ANGLE_ENABLE_D3D11_1) - case D3D_FEATURE_LEVEL_11_1: -+#endif - case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURECUBE_DIMENSION; - - case D3D_FEATURE_LEVEL_10_1: -@@ -619,7 +703,9 @@ static size_t GetMaximum2DTextureArraySize(D3D_FEATURE_LEVEL featureLevel) - { - switch (featureLevel) - { -+#if defined(ANGLE_ENABLE_D3D11_1) - case D3D_FEATURE_LEVEL_11_1: -+#endif - case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; - - case D3D_FEATURE_LEVEL_10_1: -@@ -1266,7 +1352,9 @@ ANGLED3D11DeviceType GetDeviceType(ID3D11Device *device) - - IDXGIDevice *dxgiDevice = nullptr; - IDXGIAdapter *dxgiAdapter = nullptr; -+#if defined(ANGLE_ENABLE_D3D11_1) - IDXGIAdapter2 *dxgiAdapter2 = nullptr; -+#endif - - ANGLED3D11DeviceType retDeviceType = ANGLE_D3D11_DEVICE_TYPE_UNKNOWN; - -@@ -1277,6 +1365,7 @@ ANGLED3D11DeviceType GetDeviceType(ID3D11Device *device) - if (SUCCEEDED(hr)) - { - std::wstring adapterString; -+#if defined(ANGLE_ENABLE_D3D11_1) - HRESULT adapter2hr = - dxgiAdapter->QueryInterface(__uuidof(dxgiAdapter2), (void **)&dxgiAdapter2); - if (SUCCEEDED(adapter2hr)) -@@ -1289,6 +1378,7 @@ ANGLED3D11DeviceType GetDeviceType(ID3D11Device *device) - adapterString = std::wstring(adapterDesc2.Description); - } - else -+#endif - { - DXGI_ADAPTER_DESC adapterDesc; - dxgiAdapter->GetDesc(&adapterDesc); -@@ -1320,7 +1410,9 @@ ANGLED3D11DeviceType GetDeviceType(ID3D11Device *device) - - SafeRelease(dxgiDevice); - SafeRelease(dxgiAdapter); -+#if defined(ANGLE_ENABLE_D3D11_1) - SafeRelease(dxgiAdapter2); -+#endif - - return retDeviceType; - } -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp -index 123b481..cd63789 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp -@@ -12,7 +12,9 @@ - #include "common/debug.h" - - #include -+#if !defined(__MINGW32__) - #include -+#endif - - namespace rx - { -@@ -31,9 +33,11 @@ NativeWindow::NativeWindow(EGLNativeWindowType window, - - NativeWindow::~NativeWindow() - { -+#if !defined(__MINGW32__) - SafeRelease(mCompositionTarget); - SafeRelease(mDevice); - SafeRelease(mVisual); -+#endif - } - - bool NativeWindow::initialize() -@@ -66,6 +70,7 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory - return E_INVALIDARG; - } - -+#if !defined(__MINGW32__) - if (mDirectComposition) - { - HMODULE dcomp = ::GetModuleHandle(TEXT("dcomp.dll")); -@@ -171,6 +176,7 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory - SafeRelease(factory2); - return result; - } -+#endif // !__MINGW32__ - - DXGI_SWAP_CHAIN_DESC swapChainDesc = {}; - swapChainDesc.BufferCount = 1; -@@ -202,9 +208,11 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory - - void NativeWindow::commitChange() - { -+#if !defined(__MINGW32__) - if (mDevice) - { - mDevice->Commit(); - } -+#endif - } - } -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp -index cba74c1..6bb975b 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp -@@ -193,7 +193,7 @@ egl::Error Renderer9::initialize() - { - TRACE_EVENT0("gpu.angle", "D3d9Ex_QueryInterface"); - ASSERT(mD3d9Ex); -- mD3d9Ex->QueryInterface(__uuidof(IDirect3D9), reinterpret_cast(&mD3d9)); -+ mD3d9Ex->QueryInterface(IID_IDirect3D9, reinterpret_cast(&mD3d9)); - ASSERT(mD3d9); - } - else -@@ -301,7 +301,7 @@ egl::Error Renderer9::initialize() - if (mD3d9Ex) - { - TRACE_EVENT0("gpu.angle", "mDevice_QueryInterface"); -- result = mDevice->QueryInterface(__uuidof(IDirect3DDevice9Ex), (void**)&mDeviceEx); -+ result = mDevice->QueryInterface(IID_IDirect3DDevice9Ex, (void**)&mDeviceEx); - ASSERT(SUCCEEDED(result)); - } - -diff --git a/src/3rdparty/angle/src/libEGL/libEGL_mingw32.def b/src/3rdparty/angle/src/libEGL/libEGL_mingw32.def -index 6a771a5..c8f941a 100644 ---- a/src/3rdparty/angle/src/libEGL/libEGL_mingw32.def -+++ b/src/3rdparty/angle/src/libEGL/libEGL_mingw32.def -@@ -39,15 +39,22 @@ EXPORTS - eglGetPlatformDisplayEXT@12 @35 - eglQuerySurfacePointerANGLE@16 @36 - eglPostSubBufferNV@24 @37 -+ eglQueryDisplayAttribEXT@12 @48 -+ eglQueryDeviceAttribEXT@12 @49 -+ eglQueryDeviceStringEXT@8 @50 -+ eglCreateImageKHR@20 @51 -+ eglDestroyImageKHR@8 @52 -+ eglCreateDeviceANGLE@12 @53 -+ eglReleaseDeviceANGLE@4 @54 - - ; 1.5 entry points -- eglCreateSync @38 -- eglDestroySync @39 -- eglClientWaitSync @40 -- eglGetSyncAttrib @41 -- eglCreateImage @42 -- eglDestroyImage @43 -- eglGetPlatformDisplay @44 -- eglCreatePlatformWindowSurface @45 -- eglCreatePlatformPixmapSurface @46 -- eglWaitSync @47 -+ eglCreateSync@12 @38 -+ eglDestroySync@8 @39 -+ eglClientWaitSync@16 @40 -+ eglGetSyncAttrib@16 @41 -+ eglCreateImage@20 @42 -+ eglDestroyImage@8 @43 -+ eglGetPlatformDisplay@12 @44 -+ eglCreatePlatformWindowSurface@16 @45 -+ eglCreatePlatformPixmapSurface@16 @46 -+ eglWaitSync@12 @47 -diff --git a/src/3rdparty/angle/src/libEGL/libEGLd_mingw32.def b/src/3rdparty/angle/src/libEGL/libEGLd_mingw32.def -index ab0320d..a4a9d95 100644 ---- a/src/3rdparty/angle/src/libEGL/libEGLd_mingw32.def -+++ b/src/3rdparty/angle/src/libEGL/libEGLd_mingw32.def -@@ -39,3 +39,22 @@ EXPORTS - eglGetPlatformDisplayEXT@12 @35 - eglQuerySurfacePointerANGLE@16 @36 - eglPostSubBufferNV@24 @37 -+ eglQueryDisplayAttribEXT@12 @48 -+ eglQueryDeviceAttribEXT@12 @49 -+ eglQueryDeviceStringEXT@8 @50 -+ eglCreateImageKHR@20 @51 -+ eglDestroyImageKHR@8 @52 -+ eglCreateDeviceANGLE@12 @53 -+ eglReleaseDeviceANGLE@4 @54 -+ -+ ; 1.5 entry points -+ eglCreateSync@12 @38 -+ eglDestroySync@8 @39 -+ eglClientWaitSync@16 @40 -+ eglGetSyncAttrib@16 @41 -+ eglCreateImage@20 @42 -+ eglDestroyImage@8 @43 -+ eglGetPlatformDisplay@12 @44 -+ eglCreatePlatformWindowSurface@16 @45 -+ eglCreatePlatformPixmapSurface@16 @46 -+ eglWaitSync@12 @47 -diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def -index e02b85b..db17bb4 100644 ---- a/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def -+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2_mingw32.def -@@ -177,6 +177,31 @@ EXPORTS - glGetBufferPointervOES@12 @287 - glMapBufferRangeEXT@16 @288 - glFlushMappedBufferRangeEXT@12 @289 -+ glDiscardFramebufferEXT@12 @293 -+ glInsertEventMarkerEXT@8 @294 -+ glPushGroupMarkerEXT@8 @295 -+ glPopGroupMarkerEXT@0 @296 -+ glEGLImageTargetTexture2DOES@8 @297 -+ glEGLImageTargetRenderbufferStorageOES@8 @298 -+ glBindVertexArrayOES@4 @299 -+ glDeleteVertexArraysOES@8 @300 -+ glGenVertexArraysOES@8 @301 -+ glIsVertexArrayOES@4 @302 -+ glDebugMessageControlKHR@24 @303 -+ glDebugMessageInsertKHR@24 @304 -+ glDebugMessageCallbackKHR@8 @305 -+ glGetDebugMessageLogKHR@32 @306 -+ glPushDebugGroupKHR@16 @307 -+ glPopDebugGroupKHR@0 @308 -+ glObjectLabelKHR@16 @309 -+ glGetObjectLabelKHR@20 @310 -+ glObjectPtrLabelKHR@12 @311 -+ glGetObjectPtrLabelKHR@16 @312 -+ glGetPointervKHR@8 @313 -+ glQueryCounterEXT@8 @314 -+ glGetQueryObjectivEXT@12 @315 -+ glGetQueryObjecti64vEXT@12 @316 -+ glGetQueryObjectui64vEXT@12 @317 - - ; GLES 3.0 Functions - glReadBuffer@4 @180 -@@ -284,5 +309,8 @@ EXPORTS - glTexStorage3D@24 @282 - glGetInternalformativ@20 @283 - -- ; Setting up TRACE macro callbacks -- SetTraceFunctionPointers@8 @284 -+ ; ANGLE Platform Implementation -+ ANGLEPlatformCurrent@0 @290 -+ ANGLEPlatformInitialize@4 @291 -+ ANGLEPlatformShutdown@0 @292 -+ -\ No newline at end of file -diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def -index e2b2c33..5a4966f 100644 ---- a/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def -+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2d_mingw32.def -@@ -177,6 +177,31 @@ EXPORTS - glGetBufferPointervOES@12 @287 - glMapBufferRangeEXT@16 @288 - glFlushMappedBufferRangeEXT@12 @289 -+ glDiscardFramebufferEXT@12 @293 -+ glInsertEventMarkerEXT@8 @294 -+ glPushGroupMarkerEXT@8 @295 -+ glPopGroupMarkerEXT@0 @296 -+ glEGLImageTargetTexture2DOES@8 @297 -+ glEGLImageTargetRenderbufferStorageOES@8 @298 -+ glBindVertexArrayOES@4 @299 -+ glDeleteVertexArraysOES@8 @300 -+ glGenVertexArraysOES@8 @301 -+ glIsVertexArrayOES@4 @302 -+ glDebugMessageControlKHR@24 @303 -+ glDebugMessageInsertKHR@24 @304 -+ glDebugMessageCallbackKHR@8 @305 -+ glGetDebugMessageLogKHR@32 @306 -+ glPushDebugGroupKHR@16 @307 -+ glPopDebugGroupKHR@0 @308 -+ glObjectLabelKHR@16 @309 -+ glGetObjectLabelKHR@20 @310 -+ glObjectPtrLabelKHR@12 @311 -+ glGetObjectPtrLabelKHR@16 @312 -+ glGetPointervKHR@8 @313 -+ glQueryCounterEXT@8 @314 -+ glGetQueryObjectivEXT@12 @315 -+ glGetQueryObjecti64vEXT@12 @316 -+ glGetQueryObjectui64vEXT@12 @317 - - ; GLES 3.0 Functions - glReadBuffer@4 @180 -@@ -284,5 +309,8 @@ EXPORTS - glTexStorage3D@24 @282 - glGetInternalformativ@20 @283 - -- ; Setting up TRACE macro callbacks -- SetTraceFunctionPointers@8 @284 -+ ; ANGLE Platform Implementation -+ ANGLEPlatformCurrent@0 @290 -+ ANGLEPlatformInitialize@4 @291 -+ ANGLEPlatformShutdown@0 @292 -+ -\ No newline at end of file --- -2.7.0.windows.1 - diff --git a/src/angle/patches/0006-ANGLE-Fix-Windows-Store-D3D-Trim-and-Level-9-requirements.patch b/src/angle/patches/0003-ANGLE-Fix-Windows-Store-D3D-Trim-and-Level-9-require.patch similarity index 79% rename from src/angle/patches/0006-ANGLE-Fix-Windows-Store-D3D-Trim-and-Level-9-requirements.patch rename to src/angle/patches/0003-ANGLE-Fix-Windows-Store-D3D-Trim-and-Level-9-require.patch index eb0572f201..1f51619f18 100644 --- a/src/angle/patches/0006-ANGLE-Fix-Windows-Store-D3D-Trim-and-Level-9-requirements.patch +++ b/src/angle/patches/0003-ANGLE-Fix-Windows-Store-D3D-Trim-and-Level-9-require.patch @@ -1,7 +1,8 @@ -From b250c8e9c04cd1adccab7a6885273c9e6129131f Mon Sep 17 00:00:00 2001 -From: Oliver Wolff -Date: Tue, 1 Mar 2016 14:16:52 +0100 -Subject: [PATCH 6/7] ANGLE: Fix Windows Store D3D Trim and Level 9 requirements +From 9b37d0fa0e9eaab3d8bb1dcbba85c072302ee08c Mon Sep 17 00:00:00 2001 +From: Oliver Wolff +Date: Wed, 22 Aug 2018 13:01:10 +0200 +Subject: [PATCH 3/8] ANGLE: Fix Windows Store D3D Trim and Level 9 + requirements Due to additional validation not covered in previous patches, the Windows Store certification compatibility had regressed. These changes ensure that @@ -14,12 +15,12 @@ Change-Id: If8bc2f8cd4b2f84e1d92a1627951da2537212125 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp -index 03159bb..ea84783 100644 +index bd14f4de2a..f696e360ef 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp -@@ -453,7 +453,20 @@ Renderer11::Renderer11(egl::Display *display) +@@ -523,7 +523,20 @@ Renderer11::Renderer11(egl::Display *display) + if (requestedMajorVersion == 9 && requestedMinorVersion == 3) - #endif { - mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_3); + if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 3) @@ -38,12 +39,12 @@ index 03159bb..ea84783 100644 +#endif } - EGLint requestedDeviceType = attributes.get(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, + EGLint requestedDeviceType = static_cast(attributes.get( diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp b/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp -index e3c35d5..6c7e2ff 100644 +index b863817920..ee8cdb94dc 100644 --- a/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp +++ b/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp -@@ -50,6 +50,8 @@ EGLBoolean EGLAPIENTRY QuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surfa +@@ -54,6 +54,8 @@ EGLBoolean EGLAPIENTRY QuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surfa // validate the attribute parameter switch (attribute) { @@ -53,5 +54,5 @@ index e3c35d5..6c7e2ff 100644 if (!display->getExtensions().surfaceD3DTexture2DShareHandle) { -- -2.7.0.windows.1 +2.15.0.windows.1 diff --git a/src/angle/patches/0004-ANGLE-Allow-Windows-Phone-to-communicate-swap-region.patch b/src/angle/patches/0004-ANGLE-Allow-Windows-Phone-to-communicate-swap-region.patch deleted file mode 100644 index 4d7080e77d..0000000000 --- a/src/angle/patches/0004-ANGLE-Allow-Windows-Phone-to-communicate-swap-region.patch +++ /dev/null @@ -1,146 +0,0 @@ -From a0c84bec77dd2dab4dd87add17dd1f21e6d8087d Mon Sep 17 00:00:00 2001 -From: Oliver Wolff -Date: Tue, 1 Mar 2016 13:39:06 +0100 -Subject: [PATCH 4/7] ANGLE: Allow Windows Phone to communicate swap region - -eglPostSubBufferNV is used to communicate the size of the window, as -otherwise there is no way for the renderer to know if the last frame was -rendered in landscape or portrait, causing rendering glitches when the -orientation changes. The rotation flags are utilized in a few additional -places now to fix some corner cases where the rotation was not applied. - -This patch should be squashed into "ANGLE-Improve-Windows-Phone-Support" -during the next ANGLE rebase. - -Task-number: QTBUG-44333 -Task-number: QTBUG-43502 - -Change-Id: I2b35c41ed17004524f383350253a936e6bf85117 ---- - .../angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp | 2 ++ - .../libANGLE/renderer/d3d/d3d11/SwapChain11.cpp | 28 +++++++++++++--------- - .../d3d/d3d11/winrt/CoreWindowNativeWindow.cpp | 5 ++-- - .../angle/src/libGLESv2/entry_points_egl_ext.cpp | 2 ++ - 4 files changed, 24 insertions(+), 13 deletions(-) - -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp -index 0347828..3d27548 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp -@@ -211,6 +211,7 @@ egl::Error SurfaceD3D::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) - return egl::Error(EGL_SUCCESS); - } - -+#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (defined(ANGLE_ENABLE_WINDOWS_STORE) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) // Qt WP: eglPostSubBufferNV comes here - if (x + width > mWidth) - { - width = mWidth - x; -@@ -220,6 +221,7 @@ egl::Error SurfaceD3D::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) - { - height = mHeight - y; - } -+#endif - - if (width != 0 && height != 0) - { -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp -index 5a6f202..f669f56 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp -@@ -717,18 +717,18 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, - - d3d11::PositionTexCoordVertex *vertices = static_cast(mappedResource.pData); - -+#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) - // Create a quad in homogeneous coordinates -- float x1 = (x / float(mWidth)) * 2.0f - 1.0f; -- float y1 = (y / float(mHeight)) * 2.0f - 1.0f; -- float x2 = ((x + width) / float(mWidth)) * 2.0f - 1.0f; -- float y2 = ((y + height) / float(mHeight)) * 2.0f - 1.0f; -+ float x1 = -1.0f; -+ float y1 = -1.0f; -+ float x2 = 1.0f; -+ float y2 = 1.0f; - --#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) - const float dim = std::max(mWidth, mHeight); -- float u1 = x / dim; -- float v1 = y / dim; -- float u2 = (x + width) / dim; -- float v2 = (y + height) / dim; -+ float u1 = 0; -+ float v1 = 0; -+ float u2 = float(width) / dim; -+ float v2 = float(height) / dim; - - const NativeWindow::RotationFlags flags = mNativeWindow.rotationFlags(); - const bool rotateL = flags == NativeWindow::RotateLeft; -@@ -738,6 +738,12 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, - d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, rotateR ? u1 : u2, rotateL ? v2 : v1); - d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, rotateL ? u1 : u2, rotateR ? v1 : v2); - #else -+ // Create a quad in homogeneous coordinates -+ float x1 = (x / float(mWidth)) * 2.0f - 1.0f; -+ float y1 = (y / float(mHeight)) * 2.0f - 1.0f; -+ float x2 = ((x + width) / float(mWidth)) * 2.0f - 1.0f; -+ float y2 = ((y + height) / float(mHeight)) * 2.0f - 1.0f; -+ - float u1 = x / float(mWidth); - float v1 = y / float(mHeight); - float u2 = (x + width) / float(mWidth); -@@ -788,8 +794,8 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, - viewport.TopLeftX = 0; - viewport.TopLeftY = 0; - #if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) -- viewport.Width = (rotateL || rotateR) ? mHeight : mWidth; -- viewport.Height = (rotateL || rotateR) ? mWidth : mHeight; -+ viewport.Width = (rotateL || rotateR) ? height : width; -+ viewport.Height = (rotateL || rotateR) ? width : height; - #else - viewport.Width = static_cast(mWidth); - viewport.Height = static_cast(mHeight); -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp -index 6a4795a..b074e8c 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp -@@ -132,6 +132,7 @@ bool CoreWindowNativeWindow::registerForSizeChangeEvents() - if (SUCCEEDED(result)) - { - result = mDisplayInformation->add_OrientationChanged(orientationChangedHandler.Get(), &mOrientationChangedEventToken); -+ orientationChangedHandler->Invoke(mDisplayInformation.Get(), nullptr); - } - #endif - -@@ -175,8 +176,8 @@ HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, - } - - DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 }; -- swapChainDesc.Width = width; -- swapChainDesc.Height = height; -+ swapChainDesc.Width = mRotationFlags ? height : width; -+ swapChainDesc.Height = mRotationFlags ? width : height; - swapChainDesc.Format = format; - swapChainDesc.Stereo = FALSE; - swapChainDesc.SampleDesc.Count = 1; -diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp b/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp -index 7536b19..e3c35d5 100644 ---- a/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp -+++ b/src/3rdparty/angle/src/libGLESv2/entry_points_egl_ext.cpp -@@ -108,12 +108,14 @@ EGLBoolean EGLAPIENTRY PostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLin - return EGL_FALSE; - } - -+#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (defined(ANGLE_ENABLE_WINDOWS_STORE) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) // Qt WP: Allow this entry point as a workaround - if (!display->getExtensions().postSubBuffer) - { - // Spec is not clear about how this should be handled. - SetGlobalError(Error(EGL_SUCCESS)); - return EGL_TRUE; - } -+#endif - - error = eglSurface->postSubBuffer(x, y, width, height); - if (error.isError()) --- -2.7.0.windows.1 - diff --git a/src/angle/patches/0004-ANGLE-fix-usage-of-shared-handles-for-WinRT-applicat.patch b/src/angle/patches/0004-ANGLE-fix-usage-of-shared-handles-for-WinRT-applicat.patch new file mode 100644 index 0000000000..72a72f15be --- /dev/null +++ b/src/angle/patches/0004-ANGLE-fix-usage-of-shared-handles-for-WinRT-applicat.patch @@ -0,0 +1,37 @@ +From 67125df3f31dfad0feec81c49c2b317c6d418f4e Mon Sep 17 00:00:00 2001 +From: Oliver Wolff +Date: Wed, 22 Aug 2018 13:08:19 +0200 +Subject: [PATCH 4/8] ANGLE: fix usage of shared handles for WinRT applications + +The check is not relevant in Qt's context and was skipped before but +it sneaked back in with the latest ANGLE update. + +Change-Id: Ic44de5468a3254afd76ef4804d97d245676daeb1 +--- + src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp +index f696e360ef..cb4e51e42a 100644 +--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp ++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp +@@ -2270,6 +2270,8 @@ bool Renderer11::getShareHandleSupport() const + return false; + } + ++ // Qt: we don't care about the 9_3 limitation ++#if 0 + // Also disable share handles on Feature Level 9_3, since it doesn't support share handles on + // RGBA8 textures/swapchains. + if (mRenderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3) +@@ -2277,6 +2279,7 @@ bool Renderer11::getShareHandleSupport() const + mSupportsShareHandles = false; + return false; + } ++#endif + + // Find out which type of D3D11 device the Renderer11 is using + d3d11::ANGLED3D11DeviceType deviceType = getDeviceType(); +-- +2.15.0.windows.1 + diff --git a/src/angle/patches/0005-ANGLE-Fix-compilation-without-d3d11.patch b/src/angle/patches/0005-ANGLE-Fix-compilation-without-d3d11.patch deleted file mode 100644 index f32702dadf..0000000000 --- a/src/angle/patches/0005-ANGLE-Fix-compilation-without-d3d11.patch +++ /dev/null @@ -1,59 +0,0 @@ -From c224d27faf33fe2830b35eba22af0a637e1309cb Mon Sep 17 00:00:00 2001 -From: Oliver Wolff -Date: Tue, 1 Mar 2016 14:14:29 +0100 -Subject: [PATCH 5/7] ANGLE: Fix compilation without d3d11 - -Change-Id: I70ca8ef8ed205465a20c47756634ef6efc16ce85 ---- - src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h | 4 +++- - .../angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp | 2 ++ - 2 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h -index 1c94538..612b06b 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h -@@ -39,7 +39,7 @@ class InspectableNativeWindow; - using namespace Microsoft::WRL; - using namespace Microsoft::WRL::Wrappers; - --#else -+#elif defined(ANGLE_ENABLE_D3D11) - typedef IDXGISwapChain DXGISwapChain; - typedef IDXGIFactory DXGIFactory; - #endif -@@ -68,9 +68,11 @@ class NativeWindow - #endif - static bool isValidNativeWindow(EGLNativeWindowType window); - -+#if defined(ANGLE_ENABLE_D3D11) - HRESULT createSwapChain(ID3D11Device* device, DXGIFactory* factory, - DXGI_FORMAT format, UINT width, UINT height, - DXGISwapChain** swapChain); -+#endif - - inline EGLNativeWindowType getNativeWindow() const { return mWindow; } - -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp -index 05d7a46..d96fed7 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp -@@ -56,6 +56,7 @@ bool NativeWindow::isValidNativeWindow(EGLNativeWindowType window) - return IsWindow(window) == TRUE; - } - -+#if defined(ANGLE_ENABLE_D3D11) - HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory, - DXGI_FORMAT format, unsigned int width, unsigned int height, - DXGISwapChain** swapChain) -@@ -191,6 +192,7 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory - - return factory->CreateSwapChain(device, &swapChainDesc, swapChain); - } -+#endif - - void NativeWindow::commitChange() - { --- -2.7.0.windows.1 - diff --git a/src/angle/patches/0012-ANGLE-Fix-initialization-of-zero-sized-window.patch b/src/angle/patches/0005-ANGLE-Fix-initialization-of-zero-sized-window.patch similarity index 72% rename from src/angle/patches/0012-ANGLE-Fix-initialization-of-zero-sized-window.patch rename to src/angle/patches/0005-ANGLE-Fix-initialization-of-zero-sized-window.patch index fe65af7948..eb67278628 100644 --- a/src/angle/patches/0012-ANGLE-Fix-initialization-of-zero-sized-window.patch +++ b/src/angle/patches/0005-ANGLE-Fix-initialization-of-zero-sized-window.patch @@ -1,7 +1,7 @@ -From 79d2bac44cb2a0793c00886f0499422ab6ffa09c Mon Sep 17 00:00:00 2001 -From: Maurice Kalinowski -Date: Fri, 12 Aug 2016 08:11:16 +0200 -Subject: [PATCH] ANGLE: Fix initialization of zero-sized window +From 8e649097b0e11d8b975ba321f343142dd97889cb Mon Sep 17 00:00:00 2001 +From: Oliver Wolff +Date: Wed, 22 Aug 2018 13:12:07 +0200 +Subject: [PATCH 5/8] ANGLE: Fix initialization of zero-sized window The clientRect might be empty when creating a window of zero size. The side effect of a division by zero is that matrix transformation fails @@ -13,20 +13,20 @@ Change-Id: Idbaed72deadb7b87052ac27e194a40d1810e6f7a 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp -index d3ed35b..548b460 100644 +index c6d07fc888..3425fad95d 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp -@@ -322,8 +322,8 @@ HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, +@@ -324,8 +324,8 @@ HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const Size &windowSize, const RECT &clientRect) { -- Size renderScale = {windowSize.Width / clientRect.right, -- windowSize.Height / clientRect.bottom}; +- Size renderScale = {windowSize.Width / (float)clientRect.right, +- windowSize.Height / (float)clientRect.bottom}; + Size renderScale = {windowSize.Width / std::max(LONG(1), clientRect.right), + windowSize.Height / std::max(LONG(1), clientRect.bottom)}; // Setup a scale matrix for the swap chain DXGI_MATRIX_3X2_F scaleMatrix = {}; scaleMatrix._11 = renderScale.Width; -- -2.9.2.windows.1 +2.15.0.windows.1 diff --git a/src/angle/patches/0014-ANGLE-Fix-flickering-on-resize-when-D3D9-is-used.patch b/src/angle/patches/0006-ANGLE-Fix-flickering-on-resize-when-D3D9-is-used.patch similarity index 60% rename from src/angle/patches/0014-ANGLE-Fix-flickering-on-resize-when-D3D9-is-used.patch rename to src/angle/patches/0006-ANGLE-Fix-flickering-on-resize-when-D3D9-is-used.patch index e389219976..f515b0a072 100644 --- a/src/angle/patches/0014-ANGLE-Fix-flickering-on-resize-when-D3D9-is-used.patch +++ b/src/angle/patches/0006-ANGLE-Fix-flickering-on-resize-when-D3D9-is-used.patch @@ -1,7 +1,7 @@ -From 0a6fe2a93f451997d01e5e326846e0911d22622b Mon Sep 17 00:00:00 2001 +From 0fc1b9c7e87ab6cdb6bf7c81a1eee0a1d1f74e92 Mon Sep 17 00:00:00 2001 From: Oliver Wolff -Date: Wed, 31 May 2017 15:50:28 +0200 -Subject: [PATCH] ANGLE: Fix flickering on resize when D3D9 is used +Date: Wed, 22 Aug 2018 13:24:43 +0200 +Subject: [PATCH 6/8] ANGLE: Fix flickering on resize when D3D9 is used By reverting ANGLE change d3b84ab51db09de238459b0dff2e8420c09aabf3 we get rid of the flickering that happens on resize when D3D9 is @@ -11,61 +11,67 @@ context so it is safe to revert the change. Task-number: QTBUG-59893 Change-Id: I9306314b892612fbd1f7a058a2e606aedc0367bb --- - .../angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp | 87 ++++++++++++++++++++++ + .../angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp | 89 ++++++++++++++++++++++ .../angle/src/libANGLE/renderer/d3d/SurfaceD3D.h | 4 + - 2 files changed, 91 insertions(+) + 2 files changed, 93 insertions(+) diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp -index 3d27548..f567f47 100644 +index ceb022d14c..8d3f44f2ad 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.cpp -@@ -61,16 +61,19 @@ SurfaceD3D::SurfaceD3D(RendererD3D *renderer, - mDepthStencilFormat(config->depthStencilFormat), +@@ -38,6 +38,7 @@ SurfaceD3D::SurfaceD3D(const egl::SurfaceState &state, + mDepthStencilFormat(state.config->depthStencilFormat), mSwapChain(nullptr), mSwapIntervalDirty(true), + mWindowSubclassed(false), - mNativeWindow(window, config, directComposition == EGL_TRUE), - mWidth(width), - mHeight(height), - mSwapInterval(1), - mShareHandle(reinterpret_cast(shareHandle)) + mNativeWindow(renderer->createNativeWindow(window, state.config, attribs)), + mWidth(static_cast(attribs.get(EGL_WIDTH, 0))), + mHeight(static_cast(attribs.get(EGL_HEIGHT, 0))), +@@ -45,6 +46,7 @@ SurfaceD3D::SurfaceD3D(const egl::SurfaceState &state, + mShareHandle(0), + mD3DTexture(nullptr) { + subclassWindow(); - } + if (window != nullptr && !mFixedSize) + { + mWidth = -1; +@@ -72,6 +74,7 @@ SurfaceD3D::SurfaceD3D(const egl::SurfaceState &state, SurfaceD3D::~SurfaceD3D() { + unsubclassWindow(); releaseSwapChain(); - } - -@@ -243,6 +246,90 @@ egl::Error SurfaceD3D::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) - return egl::Error(EGL_SUCCESS); + SafeDelete(mNativeWindow); + SafeRelease(mD3DTexture); +@@ -256,6 +259,92 @@ egl::Error SurfaceD3D::swapRect(const gl::Context *context, + return egl::NoError(); } +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) +#define kSurfaceProperty _TEXT("Egl::SurfaceOwner") +#define kParentWndProc _TEXT("Egl::SurfaceParentWndProc") ++#define kDisplayProperty _TEXT("Egl::Display") + +static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) +{ -+ if (message == WM_SIZE) -+ { -+ SurfaceD3D* surf = reinterpret_cast(GetProp(hwnd, kSurfaceProperty)); -+ if(surf) -+ { -+ surf->checkForOutOfDateSwapChain(); -+ } -+ } -+ WNDPROC prevWndFunc = reinterpret_cast(GetProp(hwnd, kParentWndProc)); -+ return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam); ++ if (message == WM_SIZE) ++ { ++ SurfaceD3D* surf = reinterpret_cast(GetProp(hwnd, kSurfaceProperty)); ++ if(surf) ++ { ++ egl::Display *display = reinterpret_cast(GetProp(hwnd, kDisplayProperty)); ++ surf->checkForOutOfDateSwapChain(display->getProxyContext()); ++ } ++ } ++ WNDPROC prevWndFunc = reinterpret_cast(GetProp(hwnd, kParentWndProc)); ++ return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam); +} +#endif + +void SurfaceD3D::subclassWindow() +{ +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) -+ HWND window = mNativeWindow.getNativeWindow(); ++ HWND window = mNativeWindow->getNativeWindow(); + if (!window) + { + return; @@ -88,6 +94,7 @@ index 3d27548..f567f47 100644 + + SetProp(window, kSurfaceProperty, reinterpret_cast(this)); + SetProp(window, kParentWndProc, reinterpret_cast(oldWndProc)); ++ SetProp(window, kDisplayProperty, reinterpret_cast(mDisplay)); + mWindowSubclassed = true; +#endif +} @@ -100,7 +107,7 @@ index 3d27548..f567f47 100644 + } + +#if !defined(ANGLE_ENABLE_WINDOWS_STORE) -+ HWND window = mNativeWindow.getNativeWindow(); ++ HWND window = mNativeWindow->getNativeWindow(); + if (!window) + { + return; @@ -117,26 +124,27 @@ index 3d27548..f567f47 100644 + if(parentWndFunc) + { + LONG_PTR prevWndFunc = SetWindowLongPtr(window, GWLP_WNDPROC, parentWndFunc); -+ UNUSED_ASSERTION_VARIABLE(prevWndFunc); + ASSERT(prevWndFunc == reinterpret_cast(SurfaceWindowProc)); + } + + RemoveProp(window, kSurfaceProperty); + RemoveProp(window, kParentWndProc); ++ RemoveProp(window, kDisplayProperty); +#endif + mWindowSubclassed = false; +} + - bool SurfaceD3D::checkForOutOfDateSwapChain() ++ + egl::Error SurfaceD3D::checkForOutOfDateSwapChain(const gl::Context *context) { RECT client; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.h -index b925bfc..67d408d 100644 +index 4fd45a6dfd..01d2573244 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/SurfaceD3D.h @@ -82,6 +82,9 @@ class SurfaceD3D : public SurfaceImpl - egl::Error resetSwapChain(int backbufferWidth, int backbufferHeight); - egl::Error resizeSwapChain(int backbufferWidth, int backbufferHeight); + int backbufferWidth, + int backbufferHeight); + void subclassWindow(); + void unsubclassWindow(); @@ -148,10 +156,10 @@ index b925bfc..67d408d 100644 SwapChainD3D *mSwapChain; bool mSwapIntervalDirty; -+ bool mWindowSubclassed; // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking ++ bool mWindowSubclassed; // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking - NativeWindow mNativeWindow; // Handler for the Window that the surface is created for. + NativeWindowD3D *mNativeWindow; // Handler for the Window that the surface is created for. EGLint mWidth; -- -2.10.2.windows.1 +2.15.0.windows.1 diff --git a/src/angle/patches/0007-ANGLE-D3D11-Suppress-keyboard-handling-of-DXGI.patch b/src/angle/patches/0007-ANGLE-D3D11-Suppress-keyboard-handling-of-DXGI.patch deleted file mode 100644 index badd1d7201..0000000000 --- a/src/angle/patches/0007-ANGLE-D3D11-Suppress-keyboard-handling-of-DXGI.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 955357382b1bb02043ec744ef3b5929e29c4f8cc Mon Sep 17 00:00:00 2001 -From: Oliver Wolff -Date: Tue, 12 Apr 2016 14:44:26 +0200 -Subject: [PATCH 7/7] ANGLE/D3D11: Suppress keyboard handling of DXGI. - -Set the DXGI_MWA_NO_ALT_ENTER to suppress the Alt-Enter shortcut -causing the window to become full screen. - -Task-number: QTBUG-44904 -Change-Id: If24c32df69a5a47e29d14be8f2624abfac5cd634 ---- - .../src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp -index 7da7f31..da6460b 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp -@@ -171,6 +171,8 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory - HRESULT result = factory2->CreateSwapChainForHwnd(device, mWindow, &swapChainDesc, nullptr, nullptr, &swapChain1); - if (SUCCEEDED(result)) - { -+ const HRESULT makeWindowAssociationResult = factory->MakeWindowAssociation(mWindow, DXGI_MWA_NO_ALT_ENTER); -+ UNUSED_VARIABLE(makeWindowAssociationResult); - *swapChain = static_cast(swapChain1); - } - SafeRelease(factory2); -@@ -196,7 +198,13 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory - swapChainDesc.Windowed = TRUE; - swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; - -- return factory->CreateSwapChain(device, &swapChainDesc, swapChain);; -+ const HRESULT result = factory->CreateSwapChain(device, &swapChainDesc, swapChain); -+ if (SUCCEEDED(result)) -+ { -+ const HRESULT makeWindowAssociationResult = factory->MakeWindowAssociation(mWindow, DXGI_MWA_NO_ALT_ENTER); -+ UNUSED_VARIABLE(makeWindowAssociationResult); -+ } -+ return result; - } - #endif - --- -2.7.0.windows.1 - diff --git a/src/angle/patches/0016-ANGLE-Fix-resizing-of-windows.patch b/src/angle/patches/0007-ANGLE-Fix-resizing-of-windows.patch similarity index 64% rename from src/angle/patches/0016-ANGLE-Fix-resizing-of-windows.patch rename to src/angle/patches/0007-ANGLE-Fix-resizing-of-windows.patch index 7ba92052f2..2b4938be9b 100644 --- a/src/angle/patches/0016-ANGLE-Fix-resizing-of-windows.patch +++ b/src/angle/patches/0007-ANGLE-Fix-resizing-of-windows.patch @@ -1,7 +1,7 @@ -From 55821d34b2208e7858dbba5648760b83c66b58a5 Mon Sep 17 00:00:00 2001 +From f1568e10c2bd46450adebbd838bd32e4833a0a5c Mon Sep 17 00:00:00 2001 From: Oliver Wolff -Date: Mon, 29 Aug 2016 09:48:28 +0200 -Subject: [PATCH] ANGLE: Fix resizing of windows +Date: Wed, 22 Aug 2018 13:32:44 +0200 +Subject: [PATCH 7/8] ANGLE: Fix resizing of windows Use the correct height/width values when calculating the vector for resizing the window content and the @@ -10,14 +10,14 @@ new size as viewport size. Task-number: QTBUG-62475 Change-Id: I33a8dc1379a908e991b04bc31dfc6254a6d005c9 --- - .../libANGLE/renderer/d3d/d3d11/SwapChain11.cpp | 35 +++++++++++----------- - 1 file changed, 17 insertions(+), 18 deletions(-) + .../src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp | 19 +++++++++---------- + 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp -index 785a83cd77..fe72bc935d 100644 +index 05bb5d9863..dcfd06484d 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp -@@ -707,15 +706,15 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, +@@ -796,16 +796,15 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(const gl::Context *context, d3d11::PositionTexCoordVertex *vertices = static_cast(mappedResource.pData); // Create a quad in homogeneous coordinates @@ -25,33 +25,24 @@ index 785a83cd77..fe72bc935d 100644 - float y1 = (y / float(mHeight)) * 2.0f - 1.0f; - float x2 = ((x + width) / float(mWidth)) * 2.0f - 1.0f; - float y2 = ((y + height) / float(mHeight)) * 2.0f - 1.0f; -+ float x1 = (x / float(width)) * 2.0f - 1.0f; -+ float y1 = (y / float(height)) * 2.0f - 1.0f; -+ float x2 = ((x + width) / float(width)) * 2.0f - 1.0f; -+ float y2 = ((y + height) / float(height)) * 2.0f - 1.0f; - +- - float u1 = x / float(mWidth); - float v1 = y / float(mHeight); - float u2 = (x + width) / float(mWidth); - float v2 = (y + height) / float(mHeight); +- ++ float x1 = (x / float(width)) * 2.0f - 1.0f; ++ float y1 = (y / float(height)) * 2.0f - 1.0f; ++ float x2 = ((x + width) / float(width)) * 2.0f - 1.0f; ++ float y2 = ((y + height) / float(height)) * 2.0f - 1.0f; ++ + float u1 = x / float(width); + float v1 = y / float(height); + float u2 = (x + width) / float(width); + float v2 = (y + height) / float(height); - // Invert the quad vertices depending on the surface orientation. if ((mOrientation & EGL_SURFACE_ORIENTATION_INVERT_X_ANGLE) != 0) -@@ -760,8 +759,8 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, - D3D11_VIEWPORT viewport; - viewport.TopLeftX = 0; - viewport.TopLeftY = 0; -- viewport.Width = static_cast(mWidth); -- viewport.Height = static_cast(mHeight); -+ viewport.Width = static_cast(width); -+ viewport.Height = static_cast(height); - viewport.MinDepth = 0.0f; - viewport.MaxDepth = 1.0f; - deviceContext->RSSetViewports(1, &viewport); + { -- 2.15.0.windows.1 diff --git a/src/angle/patches/0008-ANGLE-Use-pixel-sizes-in-the-XAML-swap-chain.patch b/src/angle/patches/0008-ANGLE-Use-pixel-sizes-in-the-XAML-swap-chain.patch deleted file mode 100644 index 7f7517e554..0000000000 --- a/src/angle/patches/0008-ANGLE-Use-pixel-sizes-in-the-XAML-swap-chain.patch +++ /dev/null @@ -1,401 +0,0 @@ -From 7a3851e74393eb254826face20b8e9af74bbdf0b Mon Sep 17 00:00:00 2001 -From: Oliver Wolff -Date: Thu, 17 Mar 2016 15:46:56 +0100 -Subject: [PATCH] ANGLE: Use pixel sizes in the XAML swap chain - -This is necessary for Qt applications, as they render to GL in physical -pixels. This is consistent with the CoreWindow swap chain behavior. - -This includes a partial revert of "ANGLE: Improve Windows Phone Support" -as the modifications to SwapChain11 are incompatible with the XAML swap -chain. - -This change only affects Windows Runtime targets. - -Change-Id: I401ae81028a9dfdb9da37f51c60844467c476f76 ---- - .../libANGLE/renderer/d3d/d3d11/SwapChain11.cpp | 46 ---------------------- - .../d3d/d3d11/winrt/CoreWindowNativeWindow.cpp | 25 +----------- - .../d3d/d3d11/winrt/CoreWindowNativeWindow.h | 7 +--- - .../d3d/d3d11/winrt/InspectableNativeWindow.cpp | 20 ++++++++++ - .../d3d/d3d11/winrt/InspectableNativeWindow.h | 9 +++-- - .../d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp | 43 ++++++++++++-------- - .../d3d/d3d11/winrt/SwapChainPanelNativeWindow.h | 7 ++-- - 7 files changed, 58 insertions(+), 99 deletions(-) - -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp -index f80f24b..785a83c 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp -@@ -226,14 +226,8 @@ EGLint SwapChain11::resetOffscreenColorBuffer(int backbufferWidth, int backbuffe - const bool useSharedResource = !mNativeWindow.getNativeWindow() && mRenderer->getShareHandleSupport(); - - D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; --#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) -- const int textureLength = std::max(backbufferWidth, backbufferHeight); -- offscreenTextureDesc.Width = textureLength; -- offscreenTextureDesc.Height = textureLength; --#else - offscreenTextureDesc.Width = backbufferWidth; - offscreenTextureDesc.Height = backbufferHeight; --#endif - offscreenTextureDesc.Format = backbufferFormatInfo.texFormat; - offscreenTextureDesc.MipLevels = 1; - offscreenTextureDesc.ArraySize = 1; -@@ -346,14 +340,8 @@ EGLint SwapChain11::resetOffscreenDepthBuffer(int backbufferWidth, int backbuffe - d3d11::GetTextureFormatInfo(mDepthBufferFormat, mRenderer->getRenderer11DeviceCaps()); - - D3D11_TEXTURE2D_DESC depthStencilTextureDesc; --#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) -- const int textureLength = std::max(backbufferWidth, backbufferHeight); -- depthStencilTextureDesc.Width = textureLength; -- depthStencilTextureDesc.Height = textureLength; --#else - depthStencilTextureDesc.Width = backbufferWidth; - depthStencilTextureDesc.Height = backbufferHeight; --#endif - depthStencilTextureDesc.Format = depthBufferFormatInfo.texFormat; - depthStencilTextureDesc.MipLevels = 1; - depthStencilTextureDesc.ArraySize = 1; -@@ -438,7 +426,6 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) - return EGL_SUCCESS; - } - --#if !defined(ANGLE_ENABLE_WINDOWS_STORE) || (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) - // Can only call resize if we have already created our swap buffer and resources - ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView && mBackBufferSRView); - -@@ -496,12 +483,6 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) - mFirstSwap = true; - - return resetOffscreenBuffers(backbufferWidth, backbufferHeight); --#else -- // Do nothing on Windows Phone apart from updating the internal buffer/width height -- mWidth = backbufferWidth; -- mHeight = backbufferHeight; -- return EGL_SUCCESS; --#endif - } - - DXGI_FORMAT SwapChain11::getSwapChainNativeFormat() const -@@ -725,27 +706,6 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, - - d3d11::PositionTexCoordVertex *vertices = static_cast(mappedResource.pData); - --#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) -- // Create a quad in homogeneous coordinates -- float x1 = -1.0f; -- float y1 = -1.0f; -- float x2 = 1.0f; -- float y2 = 1.0f; -- -- const float dim = std::max(mWidth, mHeight); -- float u1 = 0; -- float v1 = 0; -- float u2 = float(width) / dim; -- float v2 = float(height) / dim; -- -- const NativeWindow::RotationFlags flags = mNativeWindow.rotationFlags(); -- const bool rotateL = flags == NativeWindow::RotateLeft; -- const bool rotateR = flags == NativeWindow::RotateRight; -- d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, rotateL ? u2 : u1, rotateR ? v2 : v1); -- d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, rotateR ? u2 : u1, rotateL ? v1 : v2); -- d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, rotateR ? u1 : u2, rotateL ? v2 : v1); -- d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, rotateL ? u1 : u2, rotateR ? v1 : v2); --#else - // Create a quad in homogeneous coordinates - float x1 = (x / float(mWidth)) * 2.0f - 1.0f; - float y1 = (y / float(mHeight)) * 2.0f - 1.0f; -@@ -771,7 +731,6 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, - d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v2); - d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v1); - d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v2); --#endif - - deviceContext->Unmap(mQuadVB, 0); - -@@ -801,13 +760,8 @@ EGLint SwapChain11::copyOffscreenToBackbuffer(EGLint x, EGLint y, EGLint width, - D3D11_VIEWPORT viewport; - viewport.TopLeftX = 0; - viewport.TopLeftY = 0; --#if defined(ANGLE_ENABLE_WINDOWS_STORE) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) -- viewport.Width = (rotateL || rotateR) ? height : width; -- viewport.Height = (rotateL || rotateR) ? width : height; --#else - viewport.Width = static_cast(mWidth); - viewport.Height = static_cast(mHeight); --#endif - viewport.MinDepth = 0.0f; - viewport.MaxDepth = 1.0f; - deviceContext->RSSetViewports(1, &viewport); -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp -index b074e8c..f401db6 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp -@@ -222,7 +222,7 @@ HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, - return result; - } - --inline HRESULT CoreWindowNativeWindow::scaleSwapChain(const SIZE &windowSize, const RECT &clientRect) -+inline HRESULT CoreWindowNativeWindow::scaleSwapChain(const Size &windowSize, const RECT &clientRect) - { - // We don't need to do any additional work to scale CoreWindow swapchains. - // Using DXGI_SCALING_STRETCH to create the swapchain above does all the necessary work. -@@ -240,27 +240,4 @@ HRESULT GetCoreWindowSizeInPixels(const ComPtr displayProperties; -- -- if (SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), displayProperties.GetAddressOf()))) -- { -- float dpi = 96.0f; -- if (SUCCEEDED(displayProperties->get_LogicalDpi(&dpi))) -- { -- return dpi; -- } -- } -- -- // Return 96 dpi as a default if display properties cannot be obtained. -- return 96.0f; --} -- --long ConvertDipsToPixels(float dips) --{ -- static const float dipsPerInch = 96.0f; -- return lround((dips * GetLogicalDpi() / dipsPerInch)); --} - } -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h -index 4de235a..fc1cd12 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h -@@ -19,8 +19,6 @@ typedef ABI::Windows::Foundation::__FITypedEventHandler_2_Windows__CGraphics__CD - - namespace rx - { --long ConvertDipsToPixels(float dips); -- - class CoreWindowNativeWindow : public InspectableNativeWindow, public std::enable_shared_from_this - { - public: -@@ -36,7 +34,7 @@ class CoreWindowNativeWindow : public InspectableNativeWindow, public std::enabl - DXGISwapChain **swapChain) override; - - protected: -- HRESULT scaleSwapChain(const SIZE &windowSize, const RECT &clientRect) override; -+ HRESULT scaleSwapChain(const Size &windowSize, const RECT &clientRect) override; - - bool registerForSizeChangeEvents(); - void unregisterForSizeChangeEvents(); -@@ -74,8 +72,7 @@ class CoreWindowSizeChangedHandler : - ABI::Windows::Foundation::Size windowSize; - if (SUCCEEDED(sizeChangedEventArgs->get_Size(&windowSize))) - { -- SIZE windowSizeInPixels = { ConvertDipsToPixels(windowSize.Width), ConvertDipsToPixels(windowSize.Height) }; -- host->setNewClientSize(windowSizeInPixels); -+ host->setNewClientSize(windowSize); - } - } - -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp -index c9b203e..aacfadd 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp -@@ -381,4 +381,24 @@ HRESULT GetOptionalSinglePropertyValue(const ComPtr displayProperties; -+ float dpi = 96.0f; -+ -+ if (SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), displayProperties.GetAddressOf()))) -+ { -+ if (SUCCEEDED(displayProperties->get_LogicalDpi(&dpi))) -+ { -+ return dpi; -+ } -+ } -+ return dpi; -+} -+ -+long ConvertDipsToPixels(float dips) -+{ -+ static const float dipsPerInch = 96.0f; -+ return lround((dips * GetLogicalDpi() / dipsPerInch)); -+} - } -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h -index 70e5fe7..cdbf40e 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h -@@ -26,6 +26,8 @@ using namespace ABI::Windows::Foundation::Collections; - - namespace rx - { -+long ConvertDipsToPixels(float dips); -+ - class InspectableNativeWindow - { - public: -@@ -65,7 +67,7 @@ class InspectableNativeWindow - } - - // setNewClientSize is used by the WinRT size change handler. It isn't used by the rest of ANGLE. -- void setNewClientSize(const SIZE &newWindowSize) -+ void setNewClientSize(const Size &newWindowSize) - { - // If the client doesn't support swapchain resizing then we should have already unregistered from size change handler - ASSERT(mSupportsSwapChainResize); -@@ -76,7 +78,8 @@ class InspectableNativeWindow - if (!mSwapChainSizeSpecified) - { - // We don't have to check if a swapchain scale was specified here; the default value is 1.0f which will have no effect. -- mNewClientRect = { 0, 0, static_cast(newWindowSize.cx * mSwapChainScale), static_cast(newWindowSize.cy * mSwapChainScale) }; -+ mNewClientRect = { 0, 0, ConvertDipsToPixels(newSize.Width), ConvertDipsToPixels(newSize.Height) }; - mClientRectChanged = true; - - // If a scale was specified, then now is the time to apply the scale matrix for the new swapchain size and window size -@@ -106,7 +109,7 @@ class InspectableNativeWindow - } - - protected: -- virtual HRESULT scaleSwapChain(const SIZE &windowSize, const RECT &clientRect) = 0; -+ virtual HRESULT scaleSwapChain(const Size &windowSize, const RECT &clientRect) = 0; - - bool mSupportsSwapChainResize; // Support for IDXGISwapChain::ResizeBuffers method - bool mSwapChainSizeSpecified; // If an EGLRenderSurfaceSizeProperty was specified -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp -index 1ed3645..d3ed35b 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp -@@ -171,12 +171,15 @@ bool SwapChainPanelNativeWindow::initialize(EGLNativeWindowType window, IPropert - { - SIZE swapChainPanelSize; - result = GetSwapChainPanelSize(mSwapChainPanel, mSwapChainPanelDispatcher, -- &swapChainPanelSize); -+ &swapChainPanelSize, &mSwapChainScale); -+ if (mSwapChainScale != 1.0f) -+ mSwapChainScaleSpecified = true; - - if (SUCCEEDED(result)) - { - // Update the client rect to account for any swapchain scale factor -- mClientRect = { 0, 0, static_cast(swapChainPanelSize.cx * mSwapChainScale), static_cast(swapChainPanelSize.cy * mSwapChainScale) }; -+ mClientRect = { 0, 0, static_cast(ConvertDipsToPixels(swapChainPanelSize.cx * mSwapChainScale)), -+ static_cast(ConvertDipsToPixels(swapChainPanelSize.cy * mSwapChainScale)) }; - } - } - } -@@ -269,7 +272,6 @@ HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, - - ComPtr newSwapChain; - ComPtr swapChainPanelNative; -- SIZE currentPanelSize = {}; - - HRESULT result = factory->CreateSwapChainForComposition(device, &swapChainDesc, nullptr, newSwapChain.ReleaseAndGetAddressOf()); - -@@ -304,24 +306,24 @@ HRESULT SwapChainPanelNativeWindow::createSwapChain(ID3D11Device *device, - { - if (mSwapChainSizeSpecified || mSwapChainScaleSpecified) - { -- result = GetSwapChainPanelSize(mSwapChainPanel, mSwapChainPanelDispatcher, -- ¤tPanelSize); -- -- // Scale the swapchain to fit inside the contents of the panel. -- if (SUCCEEDED(result)) -- { -- result = scaleSwapChain(currentPanelSize, mClientRect); -- } -+ ComPtr uiElement; -+ result = mSwapChainPanel.As(&uiElement); -+ ASSERT(SUCCEEDED(result)); -+ -+ Size currentSize; -+ result = uiElement->get_RenderSize(¤tSize); -+ ASSERT(SUCCEEDED(result)); -+ result = scaleSwapChain(currentSize, mClientRect); - } - } - - return result; - } - --HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const SIZE &windowSize, const RECT &clientRect) -+HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const Size &windowSize, const RECT &clientRect) - { -- Size renderScale = {(float)windowSize.cx / (float)clientRect.right, -- (float)windowSize.cy / (float)clientRect.bottom}; -+ Size renderScale = {windowSize.Width / clientRect.right, -+ windowSize.Height / clientRect.bottom}; - // Setup a scale matrix for the swap chain - DXGI_MATRIX_3X2_F scaleMatrix = {}; - scaleMatrix._11 = renderScale.Width; -@@ -340,7 +342,7 @@ HRESULT SwapChainPanelNativeWindow::scaleSwapChain(const SIZE &windowSize, const - HRESULT GetSwapChainPanelSize( - const ComPtr &swapChainPanel, - const ComPtr &dispatcher, -- SIZE *windowSize) -+ SIZE *windowSize, float *scaleFactor) - { - ComPtr uiElement; - Size renderSize = {0, 0}; -@@ -357,9 +359,16 @@ HRESULT GetSwapChainPanelSize( - - if (SUCCEEDED(result)) - { -- *windowSize = { lround(renderSize.Width), lround(renderSize.Height) }; -+ long width = ConvertDipsToPixels(renderSize.Width); -+ long height = ConvertDipsToPixels(renderSize.Height); -+ *windowSize = { width, height }; -+ -+ if (scaleFactor) -+ { -+ *scaleFactor = renderSize.Width / width; -+ } - } - - return result; - } --} -\ No newline at end of file -+} -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h -index 9cc051d..09d87ad 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h -@@ -28,7 +28,7 @@ class SwapChainPanelNativeWindow : public InspectableNativeWindow, public std::e - DXGISwapChain **swapChain) override; - - protected: -- HRESULT scaleSwapChain(const SIZE &windowSize, const RECT &clientRect) override; -+ HRESULT scaleSwapChain(const Size &windowSize, const RECT &clientRect) override; - - bool registerForSizeChangeEvents(); - void unregisterForSizeChangeEvents(); -@@ -72,8 +72,7 @@ class SwapChainPanelSizeChangedHandler : - HRESULT result = sizeChangedEventArgs->get_NewSize(&newSize); - if (SUCCEEDED(result)) - { -- SIZE windowSize = { lround(newSize.Width), lround(newSize.Height) }; -- host->setNewClientSize(windowSize); -+ host->setNewClientSize(newSize); - } - } - -@@ -87,6 +86,6 @@ class SwapChainPanelSizeChangedHandler : - HRESULT GetSwapChainPanelSize( - const ComPtr &swapChainPanel, - const ComPtr &dispatcher, -- SIZE *windowSize); -+ SIZE *windowSize, float *scaleFactor); - } - #endif // LIBANGLE_RENDERER_D3D_D3D11_WINRT_SWAPCHAINPANELNATIVEWINDOW_H_ --- -2.7.0.windows.1 - diff --git a/src/angle/patches/0008-ANGLE-winrt-Do-full-screen-update-if-the-the-window-.patch b/src/angle/patches/0008-ANGLE-winrt-Do-full-screen-update-if-the-the-window-.patch new file mode 100644 index 0000000000..d9b51fc411 --- /dev/null +++ b/src/angle/patches/0008-ANGLE-winrt-Do-full-screen-update-if-the-the-window-.patch @@ -0,0 +1,40 @@ +From 5a58c6c7d97f003aa4a34ae130697dc81cc8fdf8 Mon Sep 17 00:00:00 2001 +From: Oliver Wolff +Date: Wed, 22 Aug 2018 15:17:52 +0200 +Subject: [PATCH 8/8] ANGLE: winrt: Do full screen update if the the window + size is reduced + +We cannot do partial updates if the window size is reduced as this will +result in a "pDstBox is not a valid box for the destination subresource." +error. + +Change-Id: I9a8d91bca961f52e1aab1bec5321922cfc842fb3 +--- + .../src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp +index 8f76d16c30..b702450ded 100644 +--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp ++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp +@@ -664,9 +664,14 @@ gl::Error TextureStorage11::setData(const gl::Context *context, + // with compressed formats in the calling logic. + ASSERT(!internalFormatInfo.compressed); + +- const int width = destBox ? destBox->width : static_cast(image->getWidth()); +- const int height = destBox ? destBox->height : static_cast(image->getHeight()); +- const int depth = destBox ? destBox->depth : static_cast(image->getDepth()); ++ const int imageWidth = static_cast(image->getWidth()); ++ const int width = destBox ? destBox->width : imageWidth; ++ const int imageHeight = static_cast(image->getHeight()); ++ const int height = destBox ? destBox->height : imageHeight; ++ const int imageDepth = static_cast(image->getDepth()); ++ const int depth = destBox ? destBox->depth : imageDepth; ++ if (imageWidth < width || imageHeight < height || imageDepth < depth) ++ fullUpdate = true; + GLuint srcRowPitch = 0; + ANGLE_TRY_RESULT( + internalFormatInfo.computeRowPitch(type, width, unpack.alignment, unpack.rowLength), +-- +2.15.0.windows.1 + diff --git a/src/angle/patches/0009-ANGLE-glGetUniform-v-functions-to-work-properly.patch b/src/angle/patches/0009-ANGLE-glGetUniform-v-functions-to-work-properly.patch deleted file mode 100644 index b53e11038b..0000000000 --- a/src/angle/patches/0009-ANGLE-glGetUniform-v-functions-to-work-properly.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 2d4a7aec7957e507cbf0b4b8dcf68abb26667e33 Mon Sep 17 00:00:00 2001 -From: Miikka Heikkinen -Date: Mon, 9 May 2016 13:13:20 +0300 -Subject: [PATCH] Fix ANGLE glGetUniform*v functions to work properly array - uniforms - -glGetUniform*v functions are supposed to return just a single -array element, so returning the whole array is always incorrect. - -Task-number: QTBUG-53072 -Change-Id: I22f05d420082d4d9de06d975b3d0f5e64d3e0c41 ---- - src/3rdparty/angle/src/libANGLE/Program.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/3rdparty/angle/src/libANGLE/Program.cpp b/src/3rdparty/angle/src/libANGLE/Program.cpp -index 748ceae..69497c4 100644 ---- a/src/3rdparty/angle/src/libANGLE/Program.cpp -+++ b/src/3rdparty/angle/src/libANGLE/Program.cpp -@@ -2510,7 +2510,7 @@ void Program::getUniformInternal(GLint location, DestT *dataOut) const - return; - } - -- int components = VariableComponentCount(uniform.type) * uniform.elementCount(); -+ int components = VariableComponentCount(uniform.type); - - switch (componentType) - { --- -2.6.3.windows.1 - diff --git a/src/angle/patches/0009-Revert-Fix-scanForWantedComponents-not-ignoring-attr.patch b/src/angle/patches/0009-Revert-Fix-scanForWantedComponents-not-ignoring-attr.patch new file mode 100644 index 0000000000..f57f528ad8 --- /dev/null +++ b/src/angle/patches/0009-Revert-Fix-scanForWantedComponents-not-ignoring-attr.patch @@ -0,0 +1,67 @@ +From 2fb4d8087c4f324b7a3f2e21554374de7060e996 Mon Sep 17 00:00:00 2001 +From: Andre de la Rocha +Date: Tue, 11 Sep 2018 12:52:28 +0200 +Subject: [PATCH] Revert "Fix scanForWantedComponents not ignoring + attribute values of 0." + +This patch reverts commit 2648d9297f25a0d1fa2837f020975a45d4e8a8b9 as a +workaround for the "banding" artifacts we were seeing in Qt. Angle +returns a list of supported graphic formats or configurations, sorting +it in a way that the first one should be the one that fits better the +requested format. In Qt we use the first thing we receive in the list. +In the current Angle version, however, a fix has changed the way in +which the list is sorted. In the old version the first element would be +a 32-bit graphic format, while now it's a 16-bit one, resulting in the +"banding" artifacts. The workaround reverts back to the previous sorting +behavior. +--- + .../libANGLE/Config.cpp | 29 +++++++++++++++++------------ + 1 file changed, 17 insertions(+), 12 deletions(-) + +diff --git a/src/3rdparty/angle/src/libANGLE/Config.cpp b/src/3rdparty/angle/src/libANGLE/Config.cpp +index ccf64c8f8..4f14e73ef 100644 +--- a/src/3rdparty/angle/src/libANGLE/Config.cpp ++++ b/src/3rdparty/angle/src/libANGLE/Config.cpp +@@ -181,22 +181,27 @@ class ConfigSorter + } + + private: +- static bool wantsComponent(const AttributeMap &attributeMap, EGLAttrib component) ++ void scanForWantedComponents(const AttributeMap &attributeMap) + { + // [EGL 1.5] section 3.4.1.2 page 30 + // Sorting rule #3: by larger total number of color bits, not considering + // components that are 0 or don't-care. +- EGLAttrib value = attributeMap.get(component, 0); +- return value != 0 && value != EGL_DONT_CARE; +- } +- +- void scanForWantedComponents(const AttributeMap &attributeMap) +- { +- mWantRed = wantsComponent(attributeMap, EGL_RED_SIZE); +- mWantGreen = wantsComponent(attributeMap, EGL_GREEN_SIZE); +- mWantBlue = wantsComponent(attributeMap, EGL_BLUE_SIZE); +- mWantAlpha = wantsComponent(attributeMap, EGL_ALPHA_SIZE); +- mWantLuminance = wantsComponent(attributeMap, EGL_LUMINANCE_SIZE); ++ for (auto attribIter = attributeMap.begin(); attribIter != attributeMap.end(); attribIter++) ++ { ++ EGLAttrib attributeKey = attribIter->first; ++ EGLAttrib attributeValue = attribIter->second; ++ if (attributeKey != 0 && attributeValue != EGL_DONT_CARE) ++ { ++ switch (attributeKey) ++ { ++ case EGL_RED_SIZE: mWantRed = true; break; ++ case EGL_GREEN_SIZE: mWantGreen = true; break; ++ case EGL_BLUE_SIZE: mWantBlue = true; break; ++ case EGL_ALPHA_SIZE: mWantAlpha = true; break; ++ case EGL_LUMINANCE_SIZE: mWantLuminance = true; break; ++ } ++ } ++ } + } + + EGLint wantedComponentsSize(const Config &config) const +-- +2.14.1.windows.1 + diff --git a/src/angle/patches/0010-ANGLE-Disable-multisampling-to-avoid-crash-in-Qt-app.patch b/src/angle/patches/0010-ANGLE-Disable-multisampling-to-avoid-crash-in-Qt-app.patch new file mode 100644 index 0000000000..2fb65ce220 --- /dev/null +++ b/src/angle/patches/0010-ANGLE-Disable-multisampling-to-avoid-crash-in-Qt-app.patch @@ -0,0 +1,41 @@ +From d239cceef88fbbe4cf7479025f12934d9c3c83a5 Mon Sep 17 00:00:00 2001 +From: Andre de la Rocha +Date: Tue, 11 Sep 2018 12:57:23 +0200 +Subject: [PATCH] ANGLE: Disable multisampling to avoid crash in Qt + applications + +This patch adds a workaround for the crash that occurs with multisampling +enabled in some Qt applications (e.g., the 2dpainting example). The old +Angle release we were using lacked support for multisampling, so it was +ignored when requested. This current version seems to support it, but is +causing a crash in the D3D11 shaders, so this workaround disables that +support. +--- + .../libANGLE/renderer/d3d/d3d11/Renderer11.cpp | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp +index bd14f4de2..f487538a5 100644 +--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp ++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp +@@ -997,6 +997,8 @@ gl::SupportedSampleSet Renderer11::generateSampleSetForEGLConfig( + { + gl::SupportedSampleSet sampleCounts; + ++#if 0 // Qt: Disabling support for multisampling as it is causing a crash in the D3D11 shaders. ++ + // Generate a new set from the set intersection of sample counts between the color and depth + // format caps. + std::set_intersection(colorBufferFormatCaps.sampleCounts.begin(), +@@ -1017,6 +1019,8 @@ gl::SupportedSampleSet Renderer11::generateSampleSetForEGLConfig( + sampleCounts = depthStencilBufferFormatCaps.sampleCounts; + } + ++#endif ++ + // Always support 0 samples + sampleCounts.insert(0); + +-- +2.14.1.windows.1 + diff --git a/src/angle/patches/0010-ANGLE-fixed-usage-of-shared-handles-for-WinRT-WinPho.patch b/src/angle/patches/0010-ANGLE-fixed-usage-of-shared-handles-for-WinRT-WinPho.patch deleted file mode 100644 index 8f17018e6e..0000000000 --- a/src/angle/patches/0010-ANGLE-fixed-usage-of-shared-handles-for-WinRT-WinPho.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 5cacddc702624d64a4917a7a704dbbb92aeba53c Mon Sep 17 00:00:00 2001 -From: Oliver Wolff -Date: Thu, 19 May 2016 10:55:46 +0200 -Subject: [PATCH] ANGLE: fixed usage of shared handles for WinRT/WinPhone - applications - -Both checks are not relevant in Qt's context and were skipped before but -they sneaked back in with the latest ANGLE update. - -Change-Id: Ic44de5468a3254afd76ef4804d97d245676daeb1 ---- - src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp | 3 +++ - src/3rdparty/angle/src/libANGLE/validationEGL.cpp | 3 +++ - 2 files changed, 6 insertions(+) - -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp -index 62badcc..0173311 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp -@@ -2618,12 +2618,15 @@ bool Renderer11::getShareHandleSupport() const - return false; - } - -+ // Qt: we don't care about the 9_3 limitation -+#if 0 - // Also disable share handles on Feature Level 9_3, since it doesn't support share handles on RGBA8 textures/swapchains. - if (mRenderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3) - { - mSupportsShareHandles = false; - return false; - } -+#endif - - // Find out which type of D3D11 device the Renderer11 is using - d3d11::ANGLED3D11DeviceType deviceType = getDeviceType(); -diff --git a/src/3rdparty/angle/src/libANGLE/validationEGL.cpp b/src/3rdparty/angle/src/libANGLE/validationEGL.cpp -index 972f6a7..903f51b 100644 ---- a/src/3rdparty/angle/src/libANGLE/validationEGL.cpp -+++ b/src/3rdparty/angle/src/libANGLE/validationEGL.cpp -@@ -642,11 +642,14 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display, EGLenum buftype, E - return Error(EGL_BAD_ATTRIBUTE); - } - -+// On Windows Store, we know the originating texture came from D3D11, so bypass this check -+#if !defined(ANGLE_ENABLE_WINDOWS_STORE) - const Caps &caps = display->getCaps(); - if (textureFormat != EGL_NO_TEXTURE && !caps.textureNPOT && (!gl::isPow2(width) || !gl::isPow2(height))) - { - return Error(EGL_BAD_MATCH); - } -+#endif - } - - return Error(EGL_SUCCESS); --- -2.7.0.windows.1 - diff --git a/src/angle/patches/0011-ANGLE-Disable-support-for-shared-handles-in-warp-mod.patch b/src/angle/patches/0011-ANGLE-Disable-support-for-shared-handles-in-warp-mod.patch deleted file mode 100644 index 1c4ee1d513..0000000000 --- a/src/angle/patches/0011-ANGLE-Disable-support-for-shared-handles-in-warp-mod.patch +++ /dev/null @@ -1,44 +0,0 @@ -From db13a9cf7e41207660f080827983655864df802d Mon Sep 17 00:00:00 2001 -From: Oliver Wolff -Date: Wed, 11 May 2016 13:51:54 +0200 -Subject: [PATCH] ANGLE: Disable support for shared handles in warp mode on - Windows < 8 - -Shared handles are not supported on Windows 7 and below. If the -according flag is set CreateTexture2D will fail with E_OUTOFMEMORY. The -check already happens with newer ANGLE versions, which we use in 5.7 -but has to happen here as well. Otherwise Qt applications running on -Windows 7 and below will crash at startup. - -Change-Id: I8f539f16dce298611fb1ec7b2f6804d4a04d04e0 ---- - .../angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp -index 223e2b0..dd554f4 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp -@@ -2370,6 +2370,19 @@ unsigned int Renderer11::getReservedFragmentUniformBuffers() const - - bool Renderer11::getShareHandleSupport() const - { -+ if (mDriverType == D3D_DRIVER_TYPE_WARP) -+ { -+#if !defined(ANGLE_ENABLE_WINDOWS_STORE) -+ // Warp mode does not support shared handles in Windows versions below Windows 8 -+ OSVERSIONINFO result = { sizeof(OSVERSIONINFO), 0, 0, 0, 0, {'\0'}}; -+ if (GetVersionEx(&result) && -+ ((result.dwMajorVersion == 6 && result.dwMinorVersion < 2) || result.dwMajorVersion < 6)) -+ { -+ // WARP on Windows 7 doesn't support shared handles -+ return false; -+ } -+#endif // ANGLE_ENABLE_WINDOWS_STORE -+ } - // We only currently support share handles with BGRA surfaces, because - // chrome needs BGRA. Once chrome fixes this, we should always support them. - // PIX doesn't seem to support using share handles, so disable them. --- -2.7.0.windows.1 - diff --git a/src/angle/patches/0013-ANGLE-Fix-crash-with-ltcg-on-Visual-Studio-2015-Upda.patch b/src/angle/patches/0013-ANGLE-Fix-crash-with-ltcg-on-Visual-Studio-2015-Upda.patch deleted file mode 100644 index ee847d3d9a..0000000000 --- a/src/angle/patches/0013-ANGLE-Fix-crash-with-ltcg-on-Visual-Studio-2015-Upda.patch +++ /dev/null @@ -1,110 +0,0 @@ -From c30bdc7d961ff09d74117e038c1bb9f06ad49738 Mon Sep 17 00:00:00 2001 -From: Oliver Wolff -Date: Wed, 7 Jun 2017 10:07:43 +0200 -Subject: [PATCH] ANGLE: Fix crash with ltcg on Visual Studio 2015 Update 3 - -Release builds of applications that used Qt configured with "link time -code generation" crashed (memory access violation), when calling -GetInternalFormatInfo in Context::initCaps. - -It looks like this is a compiler problem that can be avoided by not -using a reference for the return value. - -Task-number: QTBUG-55718 -Change-Id: Ic1fb95d7b518a49859f41c819e860864387a8d3c ---- - src/3rdparty/angle/src/libANGLE/formatutils.cpp | 2 +- - src/3rdparty/angle/src/libANGLE/formatutils.h | 2 +- - src/3rdparty/angle/src/libANGLE/validationES3.cpp | 18 +++++++++--------- - 3 files changed, 11 insertions(+), 11 deletions(-) - -diff --git a/src/3rdparty/angle/src/libANGLE/formatutils.cpp b/src/3rdparty/angle/src/libANGLE/formatutils.cpp -index 3a4df12..f8b9a8b 100644 ---- a/src/3rdparty/angle/src/libANGLE/formatutils.cpp -+++ b/src/3rdparty/angle/src/libANGLE/formatutils.cpp -@@ -652,7 +652,7 @@ const Type &GetTypeInfo(GLenum type) - } - } - --const InternalFormat &GetInternalFormatInfo(GLenum internalFormat) -+const InternalFormat GetInternalFormatInfo(GLenum internalFormat) - { - const InternalFormatInfoMap &formatMap = GetInternalFormatMap(); - InternalFormatInfoMap::const_iterator iter = formatMap.find(internalFormat); -diff --git a/src/3rdparty/angle/src/libANGLE/formatutils.h b/src/3rdparty/angle/src/libANGLE/formatutils.h -index 6863e4d..2165e6b 100644 ---- a/src/3rdparty/angle/src/libANGLE/formatutils.h -+++ b/src/3rdparty/angle/src/libANGLE/formatutils.h -@@ -79,7 +79,7 @@ struct InternalFormat - GLint skipRows, - GLint skipPixels) const; - }; --const InternalFormat &GetInternalFormatInfo(GLenum internalFormat); -+const InternalFormat GetInternalFormatInfo(GLenum internalFormat); - - GLenum GetSizedInternalFormat(GLenum internalFormat, GLenum type); - -diff --git a/src/3rdparty/angle/src/libANGLE/validationES3.cpp b/src/3rdparty/angle/src/libANGLE/validationES3.cpp -index e08e5d2..2db64ec 100644 ---- a/src/3rdparty/angle/src/libANGLE/validationES3.cpp -+++ b/src/3rdparty/angle/src/libANGLE/validationES3.cpp -@@ -775,20 +775,20 @@ static bool IsValidES3CopyTexImageCombination(GLenum textureInternalFormat, GLen - // with the values of the source buffer's [channel sizes]. Table 3.17 is used if the - // FRAMEBUFFER_ATTACHMENT_ENCODING is LINEAR and table 3.18 is used if the FRAMEBUFFER_ATTACHMENT_ENCODING - // is SRGB. -- const InternalFormat *sourceEffectiveFormat = NULL; -+ InternalFormat sourceEffectiveFormat; - if (readBufferHandle != 0) - { - // Not the default framebuffer, therefore the read buffer must be a user-created texture or renderbuffer - if (framebufferInternalFormatInfo.pixelBytes > 0) - { -- sourceEffectiveFormat = &framebufferInternalFormatInfo; -+ sourceEffectiveFormat = framebufferInternalFormatInfo; - } - else - { - // Renderbuffers cannot be created with an unsized internal format, so this must be an unsized-format - // texture. We can use the same table we use when creating textures to get its effective sized format. - GLenum sizedInternalFormat = GetSizedInternalFormat(framebufferInternalFormatInfo.format, framebufferInternalFormatInfo.type); -- sourceEffectiveFormat = &GetInternalFormatInfo(sizedInternalFormat); -+ sourceEffectiveFormat = GetInternalFormatInfo(sizedInternalFormat); - } - } - else -@@ -800,7 +800,7 @@ static bool IsValidES3CopyTexImageCombination(GLenum textureInternalFormat, GLen - GLenum effectiveFormat; - if (GetEffectiveInternalFormat(framebufferInternalFormatInfo, textureInternalFormatInfo, &effectiveFormat)) - { -- sourceEffectiveFormat = &GetInternalFormatInfo(effectiveFormat); -+ sourceEffectiveFormat = GetInternalFormatInfo(effectiveFormat); - } - else - { -@@ -816,7 +816,7 @@ static bool IsValidES3CopyTexImageCombination(GLenum textureInternalFormat, GLen - (framebufferInternalFormatInfo.blueBits >= 1 && framebufferInternalFormatInfo.blueBits <= 8) && - (framebufferInternalFormatInfo.alphaBits >= 1 && framebufferInternalFormatInfo.alphaBits <= 8)) - { -- sourceEffectiveFormat = &GetInternalFormatInfo(GL_SRGB8_ALPHA8); -+ sourceEffectiveFormat = GetInternalFormatInfo(GL_SRGB8_ALPHA8); - } - else - { -@@ -834,10 +834,10 @@ static bool IsValidES3CopyTexImageCombination(GLenum textureInternalFormat, GLen - { - // Section 3.8.5 of the GLES 3.0.3 spec, pg 139, requires that, if the destination format is sized, - // component sizes of the source and destination formats must exactly match -- if (textureInternalFormatInfo.redBits != sourceEffectiveFormat->redBits || -- textureInternalFormatInfo.greenBits != sourceEffectiveFormat->greenBits || -- textureInternalFormatInfo.blueBits != sourceEffectiveFormat->blueBits || -- textureInternalFormatInfo.alphaBits != sourceEffectiveFormat->alphaBits) -+ if (textureInternalFormatInfo.redBits != sourceEffectiveFormat.redBits || -+ textureInternalFormatInfo.greenBits != sourceEffectiveFormat.greenBits || -+ textureInternalFormatInfo.blueBits != sourceEffectiveFormat.blueBits || -+ textureInternalFormatInfo.alphaBits != sourceEffectiveFormat.alphaBits) - { - return false; - } --- -2.5.3.windows.1 - diff --git a/src/angle/patches/0015-ANGLE-Use-ANGLE_D3D11_QDTD_AVAILABLE-to-check-struct-.patch b/src/angle/patches/0015-ANGLE-Use-ANGLE_D3D11_QDTD_AVAILABLE-to-check-struct-.patch deleted file mode 100644 index 9809fefd9d..0000000000 --- a/src/angle/patches/0015-ANGLE-Use-ANGLE_D3D11_QDTD_AVAILABLE-to-check-struct-.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 640361e72369d612270c6e59126019c917e33c9a Mon Sep 17 00:00:00 2001 -From: Oliver Wolff -Date: Fri, 28 Jul 2017 09:02:50 +0200 -Subject: [PATCH] ANGLE: Use ANGLE_D3D11_QDTD_AVAILABLE to check struct's - availability - -Checking mingw when defining the structure is not enough, as it is -available in recent versions of MinGW. The define that is used is set -depending on a configure test which works independently of the used -toolchain. - -Change-Id: Ia9cb48f3e673841101a93cbc8ea23aff9547f639 ---- - src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp -index 972c289..97c65e1 100644 ---- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp -+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Query11.cpp -@@ -20,7 +20,7 @@ typedef struct D3D11_QUERY_DATA_SO_STATISTICS { - } D3D11_QUERY_DATA_SO_STATISTICS; - #endif // ANGLE_MINGW32_COMPAT - --#ifdef __MINGW32__ -+#ifndef ANGLE_D3D11_QDTD_AVAILABLE - typedef struct D3D11_QUERY_DATA_TIMESTAMP_DISJOINT { - UINT64 Frequency; - BOOL Disjoint; --- -2.10.2.windows.1 - diff --git a/src/angle/patches/0017-Remove-usage-of-auto_ptr-in-MacroExpander.patch b/src/angle/patches/0017-Remove-usage-of-auto_ptr-in-MacroExpander.patch deleted file mode 100644 index 314a985bab..0000000000 --- a/src/angle/patches/0017-Remove-usage-of-auto_ptr-in-MacroExpander.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 946903d23ae361ddb05d2c0f64b339eb1694311b Mon Sep 17 00:00:00 2001 -From: Corentin Wallez -Date: Mon, 18 Apr 2016 17:30:07 -0400 -Subject: [PATCH] Remove usage of auto_ptr in MacroExpander - -BUG=angleproject:1269 - -Change-Id: I1fafa102b065f6da1797e8790ec3ed498d9d8b45 -Reviewed-on: https://chromium-review.googlesource.com/339379 -Reviewed-by: Jamie Madill -Commit-Queue: Corentin Wallez ---- - src/compiler/preprocessor/MacroExpander.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/compiler/preprocessor/MacroExpander.h b/src/compiler/preprocessor/MacroExpander.h -index 3cc860d75..dc870f626 100644 ---- a/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.h -+++ b/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.h -@@ -83,7 +83,7 @@ class MacroExpander : public Lexer - Diagnostics *mDiagnostics; - bool mParseDefined; - -- std::auto_ptr mReserveToken; -+ std::unique_ptr mReserveToken; - std::vector mContextStack; - }; - --- -2.15.0.windows.1 - diff --git a/src/angle/src/common/common.pri b/src/angle/src/common/common.pri index 8abdc24186..b64dbd3e36 100644 --- a/src/angle/src/common/common.pri +++ b/src/angle/src/common/common.pri @@ -10,7 +10,8 @@ include (../config.pri) INCLUDEPATH += \ $$ANGLE_DIR/src \ - $$ANGLE_DIR/include + $$ANGLE_DIR/include \ + $$ANGLE_DIR/src/common/third_party/base LIBS_PRIVATE = $$QMAKE_LIBS_GUI diff --git a/src/angle/src/common/gles_common.pri b/src/angle/src/common/gles_common.pri index 82d38a62e6..e32fd0ea01 100644 --- a/src/angle/src/common/gles_common.pri +++ b/src/angle/src/common/gles_common.pri @@ -1,7 +1,10 @@ CONFIG += simd no_batch object_parallel_to_source include(common.pri) -INCLUDEPATH += $$OUT_PWD/.. $$ANGLE_DIR/src/libANGLE +INCLUDEPATH += \ + $$OUT_PWD/.. \ + $$ANGLE_DIR \ + $$ANGLE_DIR/src/libANGLE # Remember to adapt src/gui/configure.* if the Direct X version changes. !winrt: \ @@ -30,10 +33,8 @@ qtConfig(angle_d3d11_qdtd): DEFINES += ANGLE_D3D11_QDTD_AVAILABLE HEADERS += \ $$ANGLE_DIR/src/common/mathutil.h \ - $$ANGLE_DIR/src/common/blocklayout.h \ - $$ANGLE_DIR/src/common/NativeWindow.h \ - $$ANGLE_DIR/src/common/shadervars.h \ $$ANGLE_DIR/src/common/utilities.h \ + $$ANGLE_DIR/src/common/version.h \ $$ANGLE_DIR/src/common/MemoryBuffer.h \ $$ANGLE_DIR/src/common/angleutils.h \ $$ANGLE_DIR/src/common/debug.h \ @@ -47,7 +48,6 @@ HEADERS += \ $$ANGLE_DIR/src/libANGLE/Config.h \ $$ANGLE_DIR/src/libANGLE/Constants.h \ $$ANGLE_DIR/src/libANGLE/Context.h \ - $$ANGLE_DIR/src/libANGLE/Data.h \ $$ANGLE_DIR/src/libANGLE/Debug.h \ $$ANGLE_DIR/src/libANGLE/Device.h \ $$ANGLE_DIR/src/libANGLE/Display.h \ @@ -81,21 +81,16 @@ HEADERS += \ $$ANGLE_DIR/src/libANGLE/VertexAttribute.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/BufferD3D.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/CompilerD3D.h \ - $$ANGLE_DIR/src/libANGLE/renderer/d3d/copyimage.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/DeviceD3D.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/DisplayD3D.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/DynamicHLSL.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/EGLImageD3D.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/formatutilsD3D.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/FramebufferD3D.h \ - $$ANGLE_DIR/src/libANGLE/renderer/d3d/generatemip.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/HLSLCompiler.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/ImageD3D.h \ - $$ANGLE_DIR/src/libANGLE/renderer/d3d/imageformats.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/IndexBuffer.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/IndexDataManager.h \ - $$ANGLE_DIR/src/libANGLE/renderer/d3d/loadimage.h \ - $$ANGLE_DIR/src/libANGLE/renderer/d3d/loadimage_etc.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/ProgramD3D.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/RenderbufferD3D.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/RendererD3D.h \ @@ -106,8 +101,6 @@ HEADERS += \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/SwapChainD3D.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/TextureD3D.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/TextureStorage.h \ - $$ANGLE_DIR/src/libANGLE/renderer/d3d/TransformFeedbackD3D.h \ - $$ANGLE_DIR/src/libANGLE/renderer/d3d/VaryingPacking.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/VertexBuffer.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/VertexDataManager.h \ $$ANGLE_DIR/src/libANGLE/renderer/BufferImpl.h \ @@ -115,21 +108,15 @@ HEADERS += \ $$ANGLE_DIR/src/libANGLE/renderer/DeviceImpl.h \ $$ANGLE_DIR/src/libANGLE/renderer/DisplayImpl.h \ $$ANGLE_DIR/src/libANGLE/renderer/FenceNVImpl.h \ - $$ANGLE_DIR/src/libANGLE/renderer/FenceSyncImpl.h \ $$ANGLE_DIR/src/libANGLE/renderer/FramebufferImpl.h \ - $$ANGLE_DIR/src/libANGLE/renderer/Image.h \ - $$ANGLE_DIR/src/libANGLE/renderer/ImplFactory.h \ $$ANGLE_DIR/src/libANGLE/renderer/ProgramImpl.h \ $$ANGLE_DIR/src/libANGLE/renderer/QueryImpl.h \ $$ANGLE_DIR/src/libANGLE/renderer/RenderbufferImpl.h \ - $$ANGLE_DIR/src/libANGLE/renderer/Renderer.h \ $$ANGLE_DIR/src/libANGLE/renderer/ShaderImpl.h \ $$ANGLE_DIR/src/libANGLE/renderer/SurfaceImpl.h \ $$ANGLE_DIR/src/libANGLE/renderer/TextureImpl.h \ $$ANGLE_DIR/src/libANGLE/renderer/TransformFeedbackImpl.h \ $$ANGLE_DIR/src/libANGLE/renderer/VertexArrayImpl.h \ - $$ANGLE_DIR/src/libANGLE/renderer/Workarounds.h \ - $$ANGLE_DIR/src/libANGLE/resource.h \ $$ANGLE_DIR/src/libANGLE/ResourceManager.h \ $$ANGLE_DIR/src/libANGLE/Sampler.h \ $$ANGLE_DIR/src/libANGLE/Shader.h \ @@ -142,16 +129,11 @@ HEADERS += \ $$ANGLE_DIR/src/libANGLE/validationES.h \ $$ANGLE_DIR/src/libANGLE/VertexArray.h \ $$ANGLE_DIR/src/libANGLE/VertexAttribute.h \ - $$ANGLE_DIR/src/libANGLE/vertexconversion.h \ $$ANGLE_DIR/src/libGLESv2/entry_points_egl.h \ $$ANGLE_DIR/src/libGLESv2/entry_points_egl_ext.h \ - $$ANGLE_DIR/src/libGLESv2/entry_points_gles_2_0.h \ $$ANGLE_DIR/src/libGLESv2/entry_points_gles_2_0_ext.h \ - $$ANGLE_DIR/src/libGLESv2/entry_points_gles_3_0.h \ - $$ANGLE_DIR/src/libGLESv2/entry_points_gles_3_0_ext.h \ $$ANGLE_DIR/src/libGLESv2/global_state.h \ - $$ANGLE_DIR/src/libGLESv2/resource.h \ - $$ANGLE_DIR/src/third_party/murmurhash/MurmurHash3.h + $$ANGLE_DIR/src/libGLESv2/resource.h SOURCES += \ $$ANGLE_DIR/src/common/mathutil.cpp \ @@ -161,7 +143,14 @@ SOURCES += \ $$ANGLE_DIR/src/common/debug.cpp \ $$ANGLE_DIR/src/common/event_tracer.cpp \ $$ANGLE_DIR/src/common/Float16ToFloat32.cpp \ - $$ANGLE_DIR/src/third_party/murmurhash/MurmurHash3.cpp \ + $$ANGLE_DIR/src/common/string_utils.cpp \ + $$ANGLE_DIR/src/common/uniform_type_info_autogen.cpp \ + $$ANGLE_DIR/src/common/third_party/smhasher/src/PMurHash.cpp \ + $$ANGLE_DIR/src/common/third_party/base/anglebase/sha1.cc \ + $$ANGLE_DIR/src/image_util/copyimage.cpp \ + $$ANGLE_DIR/src/image_util/imageformats.cpp \ + $$ANGLE_DIR/src/image_util/loadimage.cpp \ + $$ANGLE_DIR/src/image_util/loadimage_etc.cpp \ $$ANGLE_DIR/src/libANGLE/angletypes.cpp \ $$ANGLE_DIR/src/libANGLE/AttributeMap.cpp \ $$ANGLE_DIR/src/libANGLE/Buffer.cpp \ @@ -169,57 +158,75 @@ SOURCES += \ $$ANGLE_DIR/src/libANGLE/Compiler.cpp \ $$ANGLE_DIR/src/libANGLE/Config.cpp \ $$ANGLE_DIR/src/libANGLE/Context.cpp \ - $$ANGLE_DIR/src/libANGLE/Data.cpp \ + $$ANGLE_DIR/src/libANGLE/ContextState.cpp \ $$ANGLE_DIR/src/libANGLE/Debug.cpp \ $$ANGLE_DIR/src/libANGLE/Device.cpp \ $$ANGLE_DIR/src/libANGLE/Display.cpp \ $$ANGLE_DIR/src/libANGLE/Error.cpp \ + $$ANGLE_DIR/src/libANGLE/es3_copy_conversion_table_autogen.cpp \ $$ANGLE_DIR/src/libANGLE/Fence.cpp \ $$ANGLE_DIR/src/libANGLE/formatutils.cpp \ + $$ANGLE_DIR/src/libANGLE/format_map_autogen.cpp \ $$ANGLE_DIR/src/libANGLE/Framebuffer.cpp \ $$ANGLE_DIR/src/libANGLE/FramebufferAttachment.cpp \ $$ANGLE_DIR/src/libANGLE/HandleAllocator.cpp \ + $$ANGLE_DIR/src/libANGLE/HandleRangeAllocator.cpp \ $$ANGLE_DIR/src/libANGLE/Image.cpp \ $$ANGLE_DIR/src/libANGLE/ImageIndex.cpp \ $$ANGLE_DIR/src/libANGLE/IndexRangeCache.cpp \ + $$ANGLE_DIR/src/libANGLE/LoggingAnnotator.cpp \ + $$ANGLE_DIR/src/libANGLE/MemoryProgramCache.cpp \ + $$ANGLE_DIR/src/libANGLE/PackedGLEnums_autogen.cpp \ + $$ANGLE_DIR/src/libANGLE/params.cpp \ + $$ANGLE_DIR/src/libANGLE/Path.cpp \ $$ANGLE_DIR/src/libANGLE/Platform.cpp \ $$ANGLE_DIR/src/libANGLE/Program.cpp \ + $$ANGLE_DIR/src/libANGLE/ProgramLinkedResources.cpp \ + $$ANGLE_DIR/src/libANGLE/ProgramPipeline.cpp \ $$ANGLE_DIR/src/libANGLE/Query.cpp \ $$ANGLE_DIR/src/libANGLE/queryconversions.cpp \ + $$ANGLE_DIR/src/libANGLE/queryutils.cpp \ $$ANGLE_DIR/src/libANGLE/Renderbuffer.cpp \ $$ANGLE_DIR/src/libANGLE/ResourceManager.cpp \ $$ANGLE_DIR/src/libANGLE/Sampler.cpp \ $$ANGLE_DIR/src/libANGLE/Shader.cpp \ $$ANGLE_DIR/src/libANGLE/State.cpp \ + $$ANGLE_DIR/src/libANGLE/Stream.cpp \ $$ANGLE_DIR/src/libANGLE/Surface.cpp \ $$ANGLE_DIR/src/libANGLE/Texture.cpp \ + $$ANGLE_DIR/src/libANGLE/Thread.cpp \ $$ANGLE_DIR/src/libANGLE/TransformFeedback.cpp \ $$ANGLE_DIR/src/libANGLE/Uniform.cpp \ $$ANGLE_DIR/src/libANGLE/validationEGL.cpp \ $$ANGLE_DIR/src/libANGLE/validationES.cpp \ $$ANGLE_DIR/src/libANGLE/validationES2.cpp \ $$ANGLE_DIR/src/libANGLE/validationES3.cpp \ + $$ANGLE_DIR/src/libANGLE/validationES31.cpp \ + $$ANGLE_DIR/src/libANGLE/VaryingPacking.cpp \ $$ANGLE_DIR/src/libANGLE/VertexArray.cpp \ $$ANGLE_DIR/src/libANGLE/VertexAttribute.cpp \ + $$ANGLE_DIR/src/libANGLE/WorkerThread.cpp \ + $$ANGLE_DIR/src/libANGLE/renderer/ContextImpl.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/DeviceImpl.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/DisplayImpl.cpp \ - $$ANGLE_DIR/src/libANGLE/renderer/Renderer.cpp \ + $$ANGLE_DIR/src/libANGLE/renderer/driver_utils.cpp \ + $$ANGLE_DIR/src/libANGLE/renderer/Format_table_autogen.cpp \ + $$ANGLE_DIR/src/libANGLE/renderer/load_functions_table_autogen.cpp \ + $$ANGLE_DIR/src/libANGLE/renderer/renderer_utils.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/SurfaceImpl.cpp \ + $$ANGLE_DIR/src/libANGLE/renderer/TextureImpl.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/BufferD3D.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/CompilerD3D.cpp \ - $$ANGLE_DIR/src/libANGLE/renderer/d3d/copyimage.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/DeviceD3D.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/DisplayD3D.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/DynamicHLSL.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/EGLImageD3D.cpp \ - $$ANGLE_DIR/src/libANGLE/renderer/d3d/formatutilsD3D.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/FramebufferD3D.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/HLSLCompiler.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/ImageD3D.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/IndexBuffer.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/IndexDataManager.cpp \ - $$ANGLE_DIR/src/libANGLE/renderer/d3d/loadimage.cpp \ - $$ANGLE_DIR/src/libANGLE/renderer/d3d/loadimage_etc.cpp \ + $$ANGLE_DIR/src/libANGLE/renderer/d3d/NativeWindowD3D.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/ProgramD3D.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/RendererD3D.cpp \ @@ -227,22 +234,20 @@ SOURCES += \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/ShaderD3D.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/ShaderExecutableD3D.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/SurfaceD3D.cpp \ + $$ANGLE_DIR/src/libANGLE/renderer/d3d/SwapChainD3D.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/TextureD3D.cpp \ - $$ANGLE_DIR/src/libANGLE/renderer/d3d/TransformFeedbackD3D.cpp \ - $$ANGLE_DIR/src/libANGLE/renderer/d3d/VaryingPacking.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/VertexBuffer.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/VertexDataManager.cpp \ $$ANGLE_DIR/src/libGLESv2/entry_points_egl.cpp \ $$ANGLE_DIR/src/libGLESv2/entry_points_egl_ext.cpp \ - $$ANGLE_DIR/src/libGLESv2/entry_points_gles_2_0.cpp \ + $$ANGLE_DIR/src/libGLESv2/entry_points_gles_2_0_autogen.cpp \ + $$ANGLE_DIR/src/libGLESv2/proc_table_autogen.cpp \ $$ANGLE_DIR/src/libGLESv2/entry_points_gles_2_0_ext.cpp \ - $$ANGLE_DIR/src/libGLESv2/entry_points_gles_3_0.cpp \ - $$ANGLE_DIR/src/libGLESv2/entry_points_gles_3_0_ext.cpp \ + $$ANGLE_DIR/src/libGLESv2/entry_points_gles_3_0_autogen.cpp \ + $$ANGLE_DIR/src/libGLESv2/entry_points_gles_3_1_autogen.cpp \ $$ANGLE_DIR/src/libGLESv2/global_state.cpp \ $$ANGLE_DIR/src/libGLESv2/libGLESv2.cpp -SSE2_SOURCES += $$ANGLE_DIR/src/libANGLE/renderer/d3d/loadimageSSE2.cpp - angle_d3d11 { HEADERS += \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Blit11.h \ @@ -256,8 +261,7 @@ angle_d3d11 { $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Image11.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h \ - $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.h \ - $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/load_functions_table.h \ + $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/NativeWindow11.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Query11.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Renderer11.h \ @@ -267,7 +271,6 @@ angle_d3d11 { $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/StateManager11.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h \ - $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/swizzle_format_info.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Trim11.h \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h \ @@ -277,7 +280,9 @@ angle_d3d11 { $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp \ + $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Context11.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp \ + $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/dxgi_format_map_autogen.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/dxgi_support_table.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp \ @@ -285,21 +290,24 @@ angle_d3d11 { $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Image11.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp \ - $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/internal_format_initializer_table.cpp \ - $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/load_functions_table_autogen.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp \ + $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/ProgramPipeline11.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Query11.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp \ + $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp \ + $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/StreamProducerNV12.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp \ - $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/swizzle_format_info_autogen.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp \ + $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Trim11.cpp \ + $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/texture_format_table.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp \ + $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp } @@ -327,12 +335,14 @@ angle_d3d11 { SOURCES += \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp \ + $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/Context9.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/Image9.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp \ + $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/Query9.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp \ @@ -343,7 +353,7 @@ angle_d3d11 { $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp \ - $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp \ + $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.cpp \ $$ANGLE_DIR/src/third_party/systeminfo/SystemInfo.cpp } else { HEADERS += \ @@ -354,6 +364,7 @@ angle_d3d11 { SOURCES += \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp \ + $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/winrt/NativeWindow11WinRT.cpp \ $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp } @@ -367,9 +378,6 @@ BLITVS = $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.vs standardvs.input = BLITVS standardvs.type = vs_2_0 standardvs.output = standardvs.h -flipyvs.input = BLITVS -flipyvs.type = vs_2_0 -flipyvs.output = flipyvs.h BLITPS = $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.ps passthroughps.input = BLITPS @@ -378,9 +386,21 @@ passthroughps.output = passthroughps.h luminanceps.input = BLITPS luminanceps.type = ps_2_0 luminanceps.output = luminanceps.h +luminancepremultps.input = BLITPS +luminancepremultps.type = ps_2_0 +luminancepremultps.output = luminancepremultps.h +luminanceunmultps.input = BLITPS +luminanceunmultps.type = ps_2_0 +luminanceunmultps.output = luminanceunmultps.h componentmaskps.input = BLITPS componentmaskps.type = ps_2_0 componentmaskps.output = componentmaskps.h +componentmaskpremultps.input = BLITPS +componentmaskpremultps.type = ps_2_0 +componentmaskpremultps.output = componentmaskpremultps.h +componentmaskunmultps.input = BLITPS +componentmaskunmultps.type = ps_2_0 +componentmaskunmultps.output = componentmaskunmultps.h PASSTHROUGH2D = $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/shaders/Passthrough2D11.hlsl VS_Passthrough2D.input = PASSTHROUGH2D @@ -431,29 +451,104 @@ PS_PassthroughR2DUI.output = passthroughr2dui11ps.h PS_PassthroughR2DI.input = PASSTHROUGH2D PS_PassthroughR2DI.type = ps_4_0 PS_PassthroughR2DI.output = passthroughr2di11ps.h +PS_PassthroughA2D.input = PASSTHROUGH2D +PS_PassthroughA2D.type = ps_4_0_level_9_3 +PS_PassthroughA2D.output = passthrougha2d11ps.h +PS_PassthroughRGBA2DMS.input = PASSTHROUGH2D +PS_PassthroughRGBA2DMS.type = ps_4_1 +PS_PassthroughRGBA2DMS.output = passthroughrgba2dms11ps.h CLEAR = $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/shaders/Clear11.hlsl -VS_ClearFloat.input = CLEAR -VS_ClearFloat.type = vs_4_0_level_9_3 -VS_ClearFloat.output = clearfloat11vs.h +VS_Clear_FL9.input = CLEAR +VS_Clear_FL9.type = vs_4_0_level_9_3 +VS_Clear_FL9.output = clear11_fl9vs.h PS_ClearFloat_FL9.input = CLEAR PS_ClearFloat_FL9.type = ps_4_0_level_9_3 PS_ClearFloat_FL9.output = clearfloat11_fl9ps.h -PS_ClearFloat.input = CLEAR -PS_ClearFloat.type = ps_4_0 -PS_ClearFloat.output = clearfloat11ps.h -VS_ClearUint.input = CLEAR -VS_ClearUint.type = vs_4_0 -VS_ClearUint.output = clearuint11vs.h -PS_ClearUint.input = CLEAR -PS_ClearUint.type = ps_4_0 -PS_ClearUint.output = clearuint11ps.h -VS_ClearSint.input = CLEAR -VS_ClearSint.type = vs_4_0 -VS_ClearSint.output = clearsint11vs.h -PS_ClearSint.input = CLEAR -PS_ClearSint.type = ps_4_0 -PS_ClearSint.output = clearsint11ps.h +VS_Clear.input = CLEAR +VS_Clear.type = vs_4_0 +VS_Clear.output = clear11vs.h +VS_Multiview_Clear.input = CLEAR +VS_Multiview_Clear.type = vs_4_0 +VS_Multiview_Clear.output = clear11multiviewvs.h +GS_Multiview_Clear.input = CLEAR +GS_Multiview_Clear.type = gs_4_0 +GS_Multiview_Clear.output = clear11multiviewgs.h +PS_ClearDepth.input = CLEAR +PS_ClearDepth.type = ps_4_0 +PS_ClearDepth.output = cleardepth11ps.h +PS_ClearFloat1.input = CLEAR +PS_ClearFloat1.type = ps_4_0 +PS_ClearFloat1.output = clearfloat11ps1.h +PS_ClearFloat2.input = CLEAR +PS_ClearFloat2.type = ps_4_0 +PS_ClearFloat2.output = clearfloat11ps2.h +PS_ClearFloat3.input = CLEAR +PS_ClearFloat3.type = ps_4_0 +PS_ClearFloat3.output = clearfloat11ps3.h +PS_ClearFloat4.input = CLEAR +PS_ClearFloat4.type = ps_4_0 +PS_ClearFloat4.output = clearfloat11ps4.h +PS_ClearFloat5.input = CLEAR +PS_ClearFloat5.type = ps_4_0 +PS_ClearFloat5.output = clearfloat11ps5.h +PS_ClearFloat6.input = CLEAR +PS_ClearFloat6.type = ps_4_0 +PS_ClearFloat6.output = clearfloat11ps6.h +PS_ClearFloat7.input = CLEAR +PS_ClearFloat7.type = ps_4_0 +PS_ClearFloat7.output = clearfloat11ps7.h +PS_ClearFloat8.input = CLEAR +PS_ClearFloat8.type = ps_4_0 +PS_ClearFloat8.output = clearfloat11ps8.h +PS_ClearUint1.input = CLEAR +PS_ClearUint1.type = ps_4_0 +PS_ClearUint1.output = clearuint11ps1.h +PS_ClearUint2.input = CLEAR +PS_ClearUint2.type = ps_4_0 +PS_ClearUint2.output = clearuint11ps2.h +PS_ClearUint3.input = CLEAR +PS_ClearUint3.type = ps_4_0 +PS_ClearUint3.output = clearuint11ps3.h +PS_ClearUint4.input = CLEAR +PS_ClearUint4.type = ps_4_0 +PS_ClearUint4.output = clearuint11ps4.h +PS_ClearUint5.input = CLEAR +PS_ClearUint5.type = ps_4_0 +PS_ClearUint5.output = clearuint11ps5.h +PS_ClearUint6.input = CLEAR +PS_ClearUint6.type = ps_4_0 +PS_ClearUint6.output = clearuint11ps6.h +PS_ClearUint7.input = CLEAR +PS_ClearUint7.type = ps_4_0 +PS_ClearUint7.output = clearuint11ps7.h +PS_ClearUint8.input = CLEAR +PS_ClearUint8.type = ps_4_0 +PS_ClearUint8.output = clearuint11ps8.h +PS_ClearSint1.input = CLEAR +PS_ClearSint1.type = ps_4_0 +PS_ClearSint1.output = clearsint11ps1.h +PS_ClearSint2.input = CLEAR +PS_ClearSint2.type = ps_4_0 +PS_ClearSint2.output = clearsint11ps2.h +PS_ClearSint3.input = CLEAR +PS_ClearSint3.type = ps_4_0 +PS_ClearSint3.output = clearsint11ps3.h +PS_ClearSint4.input = CLEAR +PS_ClearSint4.type = ps_4_0 +PS_ClearSint4.output = clearsint11ps4.h +PS_ClearSint5.input = CLEAR +PS_ClearSint5.type = ps_4_0 +PS_ClearSint5.output = clearsint11ps5.h +PS_ClearSint6.input = CLEAR +PS_ClearSint6.type = ps_4_0 +PS_ClearSint6.output = clearsint11ps6.h +PS_ClearSint7.input = CLEAR +PS_ClearSint7.type = ps_4_0 +PS_ClearSint7.output = clearsint11ps7.h +PS_ClearSint8.input = CLEAR +PS_ClearSint8.type = ps_4_0 +PS_ClearSint8.output = clearsint11ps8.h PASSTHROUGH3D = $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/shaders/Passthrough3D11.hlsl VS_Passthrough3D.input = PASSTHROUGH3D @@ -551,15 +646,81 @@ PS_BufferToTexture_4UI.input = BUFFERTOTEXTURE PS_BufferToTexture_4UI.type = ps_4_0 PS_BufferToTexture_4UI.output = buffertotexture11_ps_4ui.h +MULTIPLYALPHA = $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/shaders/MultiplyAlpha.hlsl +PS_FtoF_PM_RGBA.input = MULTIPLYALPHA +PS_FtoF_PM_RGBA.type = ps_4_0 +PS_FtoF_PM_RGBA.output = multiplyalpha_ftof_pm_rgba_ps.h +PS_FtoF_UM_RGBA.input = MULTIPLYALPHA +PS_FtoF_UM_RGBA.type = ps_4_0 +PS_FtoF_UM_RGBA.output = multiplyalpha_ftof_um_rgba_ps.h +PS_FtoF_PM_RGB.input = MULTIPLYALPHA +PS_FtoF_PM_RGB.type = ps_4_0 +PS_FtoF_PM_RGB.output = multiplyalpha_ftof_pm_rgb_ps.h +PS_FtoF_UM_RGB.input = MULTIPLYALPHA +PS_FtoF_UM_RGB.type = ps_4_0 +PS_FtoF_UM_RGB.output = multiplyalpha_ftof_um_rgb_ps.h +PS_FtoU_PT_RGBA.input = MULTIPLYALPHA +PS_FtoU_PT_RGBA.type = ps_4_0 +PS_FtoU_PT_RGBA.output = multiplyalpha_ftou_pt_rgba_ps.h +PS_FtoU_PM_RGBA.input = MULTIPLYALPHA +PS_FtoU_PM_RGBA.type = ps_4_0 +PS_FtoU_PM_RGBA.output = multiplyalpha_ftou_pm_rgba_ps.h +PS_FtoU_UM_RGBA.input = MULTIPLYALPHA +PS_FtoU_UM_RGBA.type = ps_4_0 +PS_FtoU_UM_RGBA.output = multiplyalpha_ftou_um_rgba_ps.h +PS_FtoU_PT_RGB.input = MULTIPLYALPHA +PS_FtoU_PT_RGB.type = ps_4_0 +PS_FtoU_PT_RGB.output = multiplyalpha_ftou_pt_rgb_ps.h +PS_FtoU_PM_RGB.input = MULTIPLYALPHA +PS_FtoU_PM_RGB.type = ps_4_0 +PS_FtoU_PM_RGB.output = multiplyalpha_ftou_pm_rgb_ps.h +PS_FtoU_UM_RGB.input = MULTIPLYALPHA +PS_FtoU_UM_RGB.type = ps_4_0 +PS_FtoU_UM_RGB.output = multiplyalpha_ftou_um_rgb_ps.h +PS_FtoF_PM_LUMA.input = MULTIPLYALPHA +PS_FtoF_PM_LUMA.type = ps_4_0 +PS_FtoF_PM_LUMA.output = multiplyalpha_ftof_pm_luma_ps.h +PS_FtoF_UM_LUMA.input = MULTIPLYALPHA +PS_FtoF_UM_LUMA.type = ps_4_0 +PS_FtoF_UM_LUMA.output = multiplyalpha_ftof_um_luma_ps.h +PS_FtoF_PM_LUMAALPHA.input = MULTIPLYALPHA +PS_FtoF_PM_LUMAALPHA.type = ps_4_0 +PS_FtoF_PM_LUMAALPHA.output = multiplyalpha_ftof_pm_lumaalpha_ps.h +PS_FtoF_UM_LUMAALPHA.input = MULTIPLYALPHA +PS_FtoF_UM_LUMAALPHA.type = ps_4_0 +PS_FtoF_UM_LUMAALPHA.output = multiplyalpha_ftof_um_lumaalpha_ps.h + +RESOLVEDEPTHSTENCIL = \ + $$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/shaders/ResolveDepthStencil.hlsl +VS_ResolveDepthStencil.input = RESOLVEDEPTHSTENCIL +VS_ResolveDepthStencil.type = vs_4_1 +VS_ResolveDepthStencil.output = resolvedepthstencil11_vs.h +PS_ResolveDepth.input = RESOLVEDEPTHSTENCIL +PS_ResolveDepth.type = ps_4_1 +PS_ResolveDepth.output = resolvedepth11_ps.h +PS_ResolveDepthStencil.input = RESOLVEDEPTHSTENCIL +PS_ResolveDepthStencil.type = ps_4_1 +PS_ResolveDepthStencil.output = resolvedepthstencil11_ps.h +PS_ResolveStencil.input = RESOLVEDEPTHSTENCIL +PS_ResolveStencil.type = ps_4_1 +PS_ResolveStencil.output = resolvestencil11_ps.h + # D3D11 angle_d3d11: SHADERS = VS_Passthrough2D \ PS_PassthroughRGB2D PS_PassthroughRGB2DUI PS_PassthroughRGB2DI \ PS_PassthroughRGBA2D PS_PassthroughRGBA2DUI PS_PassthroughRGBA2DI \ PS_PassthroughRG2D PS_PassthroughRG2DUI PS_PassthroughRG2DI \ PS_PassthroughR2D PS_PassthroughR2DUI PS_PassthroughR2DI \ + PS_PassthroughA2D \ PS_PassthroughLum2D PS_PassthroughLumAlpha2D PS_PassthroughDepth2D \ - VS_ClearFloat VS_ClearUint VS_ClearSint \ - PS_ClearFloat PS_ClearFloat_FL9 PS_ClearUint PS_ClearSint \ + VS_Clear_FL9 PS_ClearFloat_FL9 VS_Clear VS_Multiview_Clear \ + GS_Multiview_Clear PS_ClearDepth \ + PS_ClearFloat1 PS_ClearFloat2 PS_ClearFloat3 PS_ClearFloat4 PS_ClearFloat5 \ + PS_ClearFloat6 PS_ClearFloat7 PS_ClearFloat8 \ + PS_ClearUint1 PS_ClearUint2 PS_ClearUint3 PS_ClearUint4 \ + PS_ClearUint5 PS_ClearUint6 PS_ClearUint7 PS_ClearUint8 \ + PS_ClearSint1 PS_ClearSint2 PS_ClearSint3 PS_ClearSint4 \ + PS_ClearSint5 PS_ClearSint6 PS_ClearSint7 PS_ClearSint8 \ VS_Passthrough3D GS_Passthrough3D \ PS_PassthroughRGBA3D PS_PassthroughRGBA3DUI PS_PassthroughRGBA3DI \ PS_PassthroughRGB3D PS_PassthroughRGB3DUI PS_PassthroughRGB3DI \ @@ -570,10 +731,22 @@ angle_d3d11: SHADERS = VS_Passthrough2D \ PS_SwizzleF3D PS_SwizzleI3D PS_SwizzleUI3D \ PS_SwizzleF2DArray PS_SwizzleI2DArray PS_SwizzleUI2DArray \ VS_BufferToTexture GS_BufferToTexture \ - PS_BufferToTexture_4F PS_BufferToTexture_4I PS_BufferToTexture_4UI + PS_BufferToTexture_4F PS_BufferToTexture_4I PS_BufferToTexture_4UI \ + PS_FtoF_PM_RGBA PS_FtoF_UM_RGBA PS_FtoF_PM_RGB PS_FtoF_UM_RGB \ + PS_FtoU_PT_RGBA PS_FtoU_PM_RGBA PS_FtoU_UM_RGBA \ + PS_FtoU_PT_RGB PS_FtoU_PM_RGB PS_FtoU_UM_RGB \ + PS_FtoF_PM_LUMA PS_FtoF_UM_LUMA \ + PS_FtoF_PM_LUMAALPHA PS_FtoF_UM_LUMAALPHA \ + VS_ResolveDepthStencil PS_ResolveDepth PS_ResolveDepthStencil PS_ResolveStencil + +# This shader causes an internal compiler error in mingw73. Re-enable it, when +# our mingw version can handle it. +!mingw: angle_d3d11: SHADERS += PS_PassthroughRGBA2DMS # D3D9 -!winrt: SHADERS += standardvs flipyvs passthroughps luminanceps componentmaskps +!winrt: SHADERS += standardvs passthroughps \ + luminanceps luminancepremultps luminanceunmultps \ + componentmaskps componentmaskpremultps componentmaskunmultps # Generate headers for (SHADER, SHADERS) { @@ -597,7 +770,6 @@ gles2_headers.files = \ gles2_headers.path = $$[QT_INSTALL_HEADERS]/QtANGLE/GLES2 gles3_headers.files = \ $$ANGLE_DIR/include/GLES3/gl3.h \ - $$ANGLE_DIR/include/GLES3/gl3ext.h \ $$ANGLE_DIR/include/GLES3/gl3platform.h gles3_headers.path = $$[QT_INSTALL_HEADERS]/QtANGLE/GLES3 INSTALLS += khr_headers gles2_headers diff --git a/src/angle/src/compiler/preprocessor/preprocessor.pro b/src/angle/src/compiler/preprocessor/preprocessor.pro index 9d0728a72d..66bc59a5ff 100644 --- a/src/angle/src/compiler/preprocessor/preprocessor.pro +++ b/src/angle/src/compiler/preprocessor/preprocessor.pro @@ -3,7 +3,10 @@ include($$OUT_PWD/../../../../gui/qtgui-config.pri) qtConfig(dynamicgl): CONFIG += not_installed include(../../config.pri) -INCLUDEPATH = $$ANGLE_DIR/src/compiler/preprocessor +INCLUDEPATH = \ + $$ANGLE_DIR/src \ + $$ANGLE_DIR/src/common/third_party/base \ + $$ANGLE_DIR/src/compiler/preprocessor DEFINES += _SECURE_SCL=0 @@ -20,12 +23,10 @@ HEADERS += \ $$ANGLE_DIR/src/compiler/preprocessor/DirectiveParser.h \ $$ANGLE_DIR/src/compiler/preprocessor/ExpressionParser.h \ $$ANGLE_DIR/src/compiler/preprocessor/Input.h \ - $$ANGLE_DIR/src/compiler/preprocessor/length_limits.h \ $$ANGLE_DIR/src/compiler/preprocessor/Lexer.h \ $$ANGLE_DIR/src/compiler/preprocessor/Macro.h \ $$ANGLE_DIR/src/compiler/preprocessor/MacroExpander.h \ $$ANGLE_DIR/src/compiler/preprocessor/numeric_lex.h \ - $$ANGLE_DIR/src/compiler/preprocessor/pp_utils.h \ $$ANGLE_DIR/src/compiler/preprocessor/Preprocessor.h \ $$ANGLE_DIR/src/compiler/preprocessor/SourceLocation.h \ $$ANGLE_DIR/src/compiler/preprocessor/Token.h \ diff --git a/src/angle/src/compiler/translator.pro b/src/angle/src/compiler/translator.pro index 398b9230cc..c1bf73bdc6 100644 --- a/src/angle/src/compiler/translator.pro +++ b/src/angle/src/compiler/translator.pro @@ -5,7 +5,8 @@ include(../config.pri) INCLUDEPATH += \ $$ANGLE_DIR/src \ - $$ANGLE_DIR/include + $$ANGLE_DIR/include \ + $$ANGLE_DIR/src/common/third_party/base DEFINES += _SECURE_SCL=0 _LIB ANGLE_TRANSLATOR_IMPLEMENTATION ANGLE_TRANSLATOR_STATIC ANGLE_ENABLE_HLSL @@ -13,11 +14,9 @@ FLEX_SOURCES = $$ANGLE_DIR/src/compiler/translator/glslang.l BISON_SOURCES = $$ANGLE_DIR/src/compiler/translator/glslang.y HEADERS += \ - $$ANGLE_DIR/include/GLSLANG/ResourceLimits.h \ $$ANGLE_DIR/include/GLSLANG/ShaderLang.h \ $$ANGLE_DIR/include/GLSLANG/ShaderVars.h \ $$ANGLE_DIR/src/common/angleutils.h \ - $$ANGLE_DIR/src/common/blocklayout.h \ $$ANGLE_DIR/src/common/debug.h \ $$ANGLE_DIR/src/common/platform.h \ $$ANGLE_DIR/src/common/tls.h \ @@ -35,27 +34,18 @@ HEADERS += \ $$ANGLE_DIR/src/compiler/translator/Common.h \ $$ANGLE_DIR/src/compiler/translator/Compiler.h \ $$ANGLE_DIR/src/compiler/translator/ConstantUnion.h \ - $$ANGLE_DIR/src/compiler/translator/depgraph/DependencyGraphBuilder.h \ - $$ANGLE_DIR/src/compiler/translator/depgraph/DependencyGraph.h \ - $$ANGLE_DIR/src/compiler/translator/depgraph/DependencyGraphOutput.h \ $$ANGLE_DIR/src/compiler/translator/Diagnostics.h \ $$ANGLE_DIR/src/compiler/translator/DirectiveHandler.h \ $$ANGLE_DIR/src/compiler/translator/ExtensionBehavior.h \ $$ANGLE_DIR/src/compiler/translator/EmulatePrecision.h \ $$ANGLE_DIR/src/compiler/translator/FlagStd140Structs.h \ - $$ANGLE_DIR/src/compiler/translator/ForLoopUnroll.h \ $$ANGLE_DIR/src/compiler/translator/HashNames.h \ $$ANGLE_DIR/src/compiler/translator/InfoSink.h \ $$ANGLE_DIR/src/compiler/translator/InitializeDll.h \ $$ANGLE_DIR/src/compiler/translator/Initialize.h \ - $$ANGLE_DIR/src/compiler/translator/InitializeParseContext.h \ $$ANGLE_DIR/src/compiler/translator/InitializeVariables.h \ - $$ANGLE_DIR/src/compiler/translator/intermediate.h \ $$ANGLE_DIR/src/compiler/translator/IntermNode.h \ - $$ANGLE_DIR/src/compiler/translator/LoopInfo.h \ - $$ANGLE_DIR/src/compiler/translator/MMap.h \ $$ANGLE_DIR/src/compiler/translator/NodeSearch.h \ - $$ANGLE_DIR/src/compiler/translator/osinclude.h \ $$ANGLE_DIR/src/compiler/translator/Operator.h \ $$ANGLE_DIR/src/compiler/translator/OutputESSL.h \ $$ANGLE_DIR/src/compiler/translator/OutputGLSLBase.h \ @@ -63,25 +53,20 @@ HEADERS += \ $$ANGLE_DIR/src/compiler/translator/OutputHLSL.h \ $$ANGLE_DIR/src/compiler/translator/ParseContext.h \ $$ANGLE_DIR/src/compiler/translator/PoolAlloc.h \ - $$ANGLE_DIR/src/compiler/translator/PruneEmptyDeclarations.h \ $$ANGLE_DIR/src/compiler/translator/Pragma.h \ $$ANGLE_DIR/src/compiler/translator/RegenerateStructNames.h \ $$ANGLE_DIR/src/compiler/translator/RemovePow.h \ $$ANGLE_DIR/src/compiler/translator/RemoveDynamicIndexing.h \ $$ANGLE_DIR/src/compiler/translator/RemoveSwitchFallThrough.h \ - $$ANGLE_DIR/src/compiler/translator/RenameFunction.h \ $$ANGLE_DIR/src/compiler/translator/RewriteDoWhile.h \ $$ANGLE_DIR/src/compiler/translator/RewriteElseBlocks.h \ $$ANGLE_DIR/src/compiler/translator/SeparateArrayInitialization.h \ $$ANGLE_DIR/src/compiler/translator/SeparateDeclarations.h \ $$ANGLE_DIR/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h \ $$ANGLE_DIR/src/compiler/translator/SearchSymbol.h \ - $$ANGLE_DIR/src/compiler/translator/ShHandle.h \ $$ANGLE_DIR/src/compiler/translator/SeparateExpressionsReturningArrays.h \ $$ANGLE_DIR/src/compiler/translator/StructureHLSL.h \ $$ANGLE_DIR/src/compiler/translator/SymbolTable.h \ - $$ANGLE_DIR/src/compiler/translator/timing/RestrictFragmentShaderTiming.h \ - $$ANGLE_DIR/src/compiler/translator/timing/RestrictVertexShaderTiming.h \ $$ANGLE_DIR/src/compiler/translator/TranslatorESSL.h \ $$ANGLE_DIR/src/compiler/translator/TranslatorGLSL.h \ $$ANGLE_DIR/src/compiler/translator/TranslatorHLSL.h \ @@ -95,7 +80,6 @@ HEADERS += \ $$ANGLE_DIR/src/compiler/translator/ValidateLimitations.h \ $$ANGLE_DIR/src/compiler/translator/ValidateOutputs.h \ $$ANGLE_DIR/src/compiler/translator/ValidateSwitch.h \ - $$ANGLE_DIR/src/compiler/translator/VariableInfo.h \ $$ANGLE_DIR/src/compiler/translator/VariablePacker.h \ $$ANGLE_DIR/src/compiler/translator/VersionGLSL.h \ $$ANGLE_DIR/src/third_party/compiler/ArrayBoundsClamper.h @@ -104,77 +88,108 @@ HEADERS += \ SOURCES += \ $$ANGLE_DIR/src/common/debug.cpp \ $$ANGLE_DIR/src/common/tls.cpp \ + $$ANGLE_DIR/src/compiler/translator/AddAndTrueToLoopCondition.cpp \ + $$ANGLE_DIR/src/compiler/translator/AddDefaultReturnStatements.cpp \ $$ANGLE_DIR/src/compiler/translator/ArrayReturnValueToOutParameter.cpp \ $$ANGLE_DIR/src/compiler/translator/ASTMetadataHLSL.cpp \ $$ANGLE_DIR/src/compiler/translator/blocklayout.cpp \ $$ANGLE_DIR/src/compiler/translator/blocklayoutHLSL.cpp \ + $$ANGLE_DIR/src/compiler/translator/BreakVariableAliasingInInnerLoops.cpp \ $$ANGLE_DIR/src/compiler/translator/BuiltInFunctionEmulator.cpp \ $$ANGLE_DIR/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp \ $$ANGLE_DIR/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp \ $$ANGLE_DIR/src/compiler/translator/Cache.cpp \ $$ANGLE_DIR/src/compiler/translator/CallDAG.cpp \ + $$ANGLE_DIR/src/compiler/translator/ClampPointSize.cpp \ $$ANGLE_DIR/src/compiler/translator/CodeGen.cpp \ + $$ANGLE_DIR/src/compiler/translator/CollectVariables.cpp \ $$ANGLE_DIR/src/compiler/translator/Compiler.cpp \ - $$ANGLE_DIR/src/compiler/translator/depgraph/DependencyGraph.cpp \ - $$ANGLE_DIR/src/compiler/translator/depgraph/DependencyGraphBuilder.cpp \ - $$ANGLE_DIR/src/compiler/translator/depgraph/DependencyGraphOutput.cpp \ - $$ANGLE_DIR/src/compiler/translator/depgraph/DependencyGraphTraverse.cpp \ + $$ANGLE_DIR/src/compiler/translator/ConstantUnion.cpp \ + $$ANGLE_DIR/src/compiler/translator/DeclareAndInitBuiltinsForInstancedMultiview.cpp \ + $$ANGLE_DIR/src/compiler/translator/DeferGlobalInitializers.cpp \ $$ANGLE_DIR/src/compiler/translator/Diagnostics.cpp \ $$ANGLE_DIR/src/compiler/translator/DirectiveHandler.cpp \ + $$ANGLE_DIR/src/compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp \ + $$ANGLE_DIR/src/compiler/translator/EmulateGLFragColorBroadcast.cpp \ $$ANGLE_DIR/src/compiler/translator/EmulatePrecision.cpp \ + $$ANGLE_DIR/src/compiler/translator/ExpandIntegerPowExpressions.cpp \ + $$ANGLE_DIR/src/compiler/translator/ExtensionBehavior.cpp \ + $$ANGLE_DIR/src/compiler/translator/ExtensionGLSL.cpp \ + $$ANGLE_DIR/src/compiler/translator/FindMain.cpp \ + $$ANGLE_DIR/src/compiler/translator/FindSymbolNode.cpp \ $$ANGLE_DIR/src/compiler/translator/FlagStd140Structs.cpp \ - $$ANGLE_DIR/src/compiler/translator/ForLoopUnroll.cpp \ + $$ANGLE_DIR/src/compiler/translator/HashNames.cpp \ + $$ANGLE_DIR/src/compiler/translator/ImageFunctionHLSL.cpp \ $$ANGLE_DIR/src/compiler/translator/InfoSink.cpp \ $$ANGLE_DIR/src/compiler/translator/Initialize.cpp \ $$ANGLE_DIR/src/compiler/translator/InitializeDll.cpp \ - $$ANGLE_DIR/src/compiler/translator/InitializeParseContext.cpp \ $$ANGLE_DIR/src/compiler/translator/InitializeVariables.cpp \ - $$ANGLE_DIR/src/compiler/translator/Intermediate.cpp \ $$ANGLE_DIR/src/compiler/translator/IntermNode.cpp \ - $$ANGLE_DIR/src/compiler/translator/intermOut.cpp \ + $$ANGLE_DIR/src/compiler/translator/IntermNodePatternMatcher.cpp \ + $$ANGLE_DIR/src/compiler/translator/IntermNode_util.cpp \ $$ANGLE_DIR/src/compiler/translator/IntermTraverse.cpp \ - $$ANGLE_DIR/src/compiler/translator/LoopInfo.cpp \ + $$ANGLE_DIR/src/compiler/translator/IsASTDepthBelowLimit.cpp \ $$ANGLE_DIR/src/compiler/translator/Operator.cpp \ $$ANGLE_DIR/src/compiler/translator/OutputESSL.cpp \ $$ANGLE_DIR/src/compiler/translator/OutputGLSL.cpp \ $$ANGLE_DIR/src/compiler/translator/OutputGLSLBase.cpp \ $$ANGLE_DIR/src/compiler/translator/OutputHLSL.cpp \ + $$ANGLE_DIR/src/compiler/translator/OutputTree.cpp \ + $$ANGLE_DIR/src/compiler/translator/OutputVulkanGLSL.cpp \ $$ANGLE_DIR/src/compiler/translator/ParseContext.cpp \ $$ANGLE_DIR/src/compiler/translator/PoolAlloc.cpp \ - $$ANGLE_DIR/src/compiler/translator/PruneEmptyDeclarations.cpp \ + $$ANGLE_DIR/src/compiler/translator/PruneNoOps.cpp \ + $$ANGLE_DIR/src/compiler/translator/QualifierTypes.cpp \ + $$ANGLE_DIR/src/compiler/translator/RecordConstantPrecision.cpp \ $$ANGLE_DIR/src/compiler/translator/RegenerateStructNames.cpp \ - $$ANGLE_DIR/src/compiler/translator/RemovePow.cpp \ + $$ANGLE_DIR/src/compiler/translator/RemoveArrayLengthMethod.cpp \ $$ANGLE_DIR/src/compiler/translator/RemoveDynamicIndexing.cpp \ + $$ANGLE_DIR/src/compiler/translator/RemoveEmptySwitchStatements.cpp \ + $$ANGLE_DIR/src/compiler/translator/RemoveInvariantDeclaration.cpp \ + $$ANGLE_DIR/src/compiler/translator/RemoveNoOpCasesFromEndOfSwitchStatements.cpp \ + $$ANGLE_DIR/src/compiler/translator/RemovePow.cpp \ $$ANGLE_DIR/src/compiler/translator/RemoveSwitchFallThrough.cpp \ + $$ANGLE_DIR/src/compiler/translator/RemoveUnreferencedVariables.cpp \ $$ANGLE_DIR/src/compiler/translator/RewriteDoWhile.cpp \ $$ANGLE_DIR/src/compiler/translator/RewriteElseBlocks.cpp \ - $$ANGLE_DIR/src/compiler/translator/SeparateArrayInitialization.cpp \ - $$ANGLE_DIR/src/compiler/translator/SeparateDeclarations.cpp \ + $$ANGLE_DIR/src/compiler/translator/RewriteTexelFetchOffset.cpp \ + $$ANGLE_DIR/src/compiler/translator/RewriteUnaryMinusOperatorFloat.cpp \ + $$ANGLE_DIR/src/compiler/translator/RewriteUnaryMinusOperatorInt.cpp \ + $$ANGLE_DIR/src/compiler/translator/RunAtTheEndOfShader.cpp \ $$ANGLE_DIR/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp \ $$ANGLE_DIR/src/compiler/translator/SearchSymbol.cpp \ + $$ANGLE_DIR/src/compiler/translator/SeparateArrayInitialization.cpp \ + $$ANGLE_DIR/src/compiler/translator/SeparateDeclarations.cpp \ + $$ANGLE_DIR/src/compiler/translator/SeparateExpressionsReturningArrays.cpp \ $$ANGLE_DIR/src/compiler/translator/ShaderLang.cpp \ $$ANGLE_DIR/src/compiler/translator/ShaderVars.cpp \ - $$ANGLE_DIR/src/compiler/translator/SeparateExpressionsReturningArrays.cpp \ + $$ANGLE_DIR/src/compiler/translator/SimplifyLoopConditions.cpp \ + $$ANGLE_DIR/src/compiler/translator/SplitSequenceOperator.cpp \ $$ANGLE_DIR/src/compiler/translator/StructureHLSL.cpp \ $$ANGLE_DIR/src/compiler/translator/SymbolTable.cpp \ - $$ANGLE_DIR/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp \ - $$ANGLE_DIR/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp \ + $$ANGLE_DIR/src/compiler/translator/SymbolUniqueId.cpp \ + $$ANGLE_DIR/src/compiler/translator/TextureFunctionHLSL.cpp \ $$ANGLE_DIR/src/compiler/translator/TranslatorESSL.cpp \ $$ANGLE_DIR/src/compiler/translator/TranslatorGLSL.cpp \ $$ANGLE_DIR/src/compiler/translator/TranslatorHLSL.cpp \ + $$ANGLE_DIR/src/compiler/translator/TranslatorVulkan.cpp \ $$ANGLE_DIR/src/compiler/translator/Types.cpp \ - $$ANGLE_DIR/src/compiler/translator/UnfoldShortCircuitToIf.cpp \ $$ANGLE_DIR/src/compiler/translator/UnfoldShortCircuitAST.cpp \ + $$ANGLE_DIR/src/compiler/translator/UnfoldShortCircuitToIf.cpp \ $$ANGLE_DIR/src/compiler/translator/UniformHLSL.cpp \ + $$ANGLE_DIR/src/compiler/translator/UseInterfaceBlockFields.cpp \ $$ANGLE_DIR/src/compiler/translator/UtilsHLSL.cpp \ $$ANGLE_DIR/src/compiler/translator/util.cpp \ $$ANGLE_DIR/src/compiler/translator/ValidateGlobalInitializer.cpp \ $$ANGLE_DIR/src/compiler/translator/ValidateLimitations.cpp \ + $$ANGLE_DIR/src/compiler/translator/ValidateMaxParameters.cpp \ $$ANGLE_DIR/src/compiler/translator/ValidateOutputs.cpp \ $$ANGLE_DIR/src/compiler/translator/ValidateSwitch.cpp \ - $$ANGLE_DIR/src/compiler/translator/VariableInfo.cpp \ $$ANGLE_DIR/src/compiler/translator/VariablePacker.cpp \ + $$ANGLE_DIR/src/compiler/translator/ValidateVaryingLocations.cpp \ $$ANGLE_DIR/src/compiler/translator/VersionGLSL.cpp \ + $$ANGLE_DIR/src/compiler/translator/VectorizeVectorScalarArithmetic.cpp \ + $$ANGLE_DIR/src/compiler/translator/WrapSwitchStatementsInBlocks.cpp \ $$ANGLE_DIR/src/third_party/compiler/ArrayBoundsClamper.cpp diff --git a/src/angle/src/config.pri b/src/angle/src/config.pri index 4beb095217..5c521281a6 100644 --- a/src/angle/src/config.pri +++ b/src/angle/src/config.pri @@ -55,7 +55,7 @@ CONFIG(debug, debug|release) { !isEmpty(BUILD_PASS): BUILDSUBDIR = $$lower($$BUILD_PASS)/ # c++11 is needed by MinGW to get support for unordered_map. -CONFIG += stl exceptions c++11 +CONFIG += stl exceptions c++11 c++14 INCLUDEPATH += . .. $$PWD/../include diff --git a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp index 228d03350a..ab746dfee8 100644 --- a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp +++ b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp @@ -2506,6 +2506,7 @@ void tst_QTableView::columnViewportPosition() view.horizontalScrollBar()->setValue(horizontalScrollValue); #ifdef Q_OS_WINRT + QEXPECT_FAIL("column 1, scroll per item, 1", "Fails on WinRT - QTBUG-68297", Abort); QEXPECT_FAIL("column 5, scroll per item, 5", "Fails on WinRT - QTBUG-68297", Abort); QEXPECT_FAIL("column 9, scroll per item, 5", "Fails on WinRT - QTBUG-68297", Abort); QEXPECT_FAIL("column 1, scroll per pixel 1", "Fails on WinRT - QTBUG-68297", Abort); From f5204067a02bd0c13500ea6e66bb9211701f96db Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Thu, 11 Oct 2018 14:36:31 +0200 Subject: [PATCH 0016/1650] qt_mac_createRolePalettes: fix the highlight color for ItemViewPalette role MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While this requires from us calling a deprecated method, a (non-deprecated) method we were using gives a wrong color which is too bright/saturated. Task-number: QTBUG-70676 Change-Id: Icebeb53e351caa646c533595ca1a886e5eb6b5b8 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoasystemsettings.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm index c1711e7cd4..672b0e4f25 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm +++ b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm @@ -202,7 +202,7 @@ QHash qt_mac_createRolePalettes() qt_mac_toQBrush([NSColor unemphasizedSelectedTextColor])); } else { baseColors = [NSColor controlAlternatingRowBackgroundColors]; - activeHighlightColor = [NSColor selectedControlColor]; + activeHighlightColor = [NSColor alternateSelectedControlColor]; pal.setBrush(QPalette::Inactive, QPalette::HighlightedText, pal.brush(QPalette::Active, QPalette::Text)); } From 3af4b59e8b59c7b658c925e1f644d31b89e39896 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Fri, 7 Sep 2018 13:48:34 +0200 Subject: [PATCH 0017/1650] glib dispatcher: rework userEventSourcePrepare() event source This is a better solution for fbb485d4f6985643b27da3cc6c5b5f960c32e74d. The existing solution was working fine, but it was exposing logic that is internal to QWindowSystemInterface and platform plugin interaction. Some platform plugins do event filtering at native event level - those that support QAbstractEventDispatcher::filterNativeEvent(). Other plugins rely on QWindowSystemInterface to do the filtering. Dispatchers should not care about this. The new logic rely on the fact that QWindowSystemInterfacePrivate::handleWindowSystemEvent calls QAbstractEventDispatcher::wakeUp(). The same way postEventSourcePrepare() rely on QCoreApplication::postEvent() to call QAbstractEventDispatcher::wakeUp(). Event sources run in the order they are attached, postEventSourcePrepare runs before userEventSourcePrepare(). We rely on that order to pass wakeUpCalled value. Change-Id: I0327f4f2398fd863fb2421b8033bb1df8d65f5af Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Thiago Macieira --- src/corelib/kernel/qeventdispatcher_glib.cpp | 4 ++-- src/corelib/kernel/qeventdispatcher_glib_p.h | 1 + .../eventdispatchers/qeventdispatcher_glib.cpp | 8 +++----- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_glib.cpp b/src/corelib/kernel/qeventdispatcher_glib.cpp index 4c780a9294..45c6e29e4b 100644 --- a/src/corelib/kernel/qeventdispatcher_glib.cpp +++ b/src/corelib/kernel/qeventdispatcher_glib.cpp @@ -260,8 +260,8 @@ static gboolean postEventSourcePrepare(GSource *s, gint *timeout) *timeout = canWait ? -1 : 0; GPostEventSource *source = reinterpret_cast(s); - return (!canWait - || (source->serialNumber.load() != source->lastSerialNumber)); + source->d->wakeUpCalled = source->serialNumber.load() != source->lastSerialNumber; + return !canWait || source->d->wakeUpCalled; } static gboolean postEventSourceCheck(GSource *source) diff --git a/src/corelib/kernel/qeventdispatcher_glib_p.h b/src/corelib/kernel/qeventdispatcher_glib_p.h index 799f23b14a..88ff316ee5 100644 --- a/src/corelib/kernel/qeventdispatcher_glib_p.h +++ b/src/corelib/kernel/qeventdispatcher_glib_p.h @@ -108,6 +108,7 @@ public: GSocketNotifierSource *socketNotifierSource; GTimerSource *timerSource; GIdleTimerSource *idleTimerSource; + bool wakeUpCalled = true; void runTimersOnceWithNormalPriority(); }; diff --git a/src/platformsupport/eventdispatchers/qeventdispatcher_glib.cpp b/src/platformsupport/eventdispatchers/qeventdispatcher_glib.cpp index dc4785071f..0ccbf01e80 100644 --- a/src/platformsupport/eventdispatchers/qeventdispatcher_glib.cpp +++ b/src/platformsupport/eventdispatchers/qeventdispatcher_glib.cpp @@ -52,17 +52,14 @@ struct GUserEventSource { GSource source; QPAEventDispatcherGlib *q; + QPAEventDispatcherGlibPrivate *d; }; static gboolean userEventSourcePrepare(GSource *source, gint *timeout) { Q_UNUSED(timeout) GUserEventSource *userEventSource = reinterpret_cast(source); - QPAEventDispatcherGlib *dispatcher = userEventSource->q; - if (dispatcher->m_flags & QEventLoop::ExcludeUserInputEvents) - return QWindowSystemInterface::nonUserInputEventsQueued(); - else - return QWindowSystemInterface::windowSystemEventsQueued() > 0; + return userEventSource->d->wakeUpCalled; } static gboolean userEventSourceCheck(GSource *source) @@ -94,6 +91,7 @@ QPAEventDispatcherGlibPrivate::QPAEventDispatcherGlibPrivate(GMainContext *conte userEventSource = reinterpret_cast(g_source_new(&userEventSourceFuncs, sizeof(GUserEventSource))); userEventSource->q = q; + userEventSource->d = this; g_source_set_can_recurse(&userEventSource->source, true); g_source_attach(&userEventSource->source, mainContext); } From a880780ff962dc31be24b508f811c1a2fd0b0f36 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Sun, 14 Oct 2018 19:46:20 +0200 Subject: [PATCH 0018/1650] Revert "XCB: Do not create instance of QPlatformIntegration for invalid displays" This reverts commit 67cc8fea106c35c7ca75bf476667d07b3bbf3257. I forgot about this patch and now it makes rebasing the local changes too time-consuming. Besides, 67cc8fea10 broke a build for -no-xcb-xlib. I will restore this patch, with adaptations to the new QXcb*Connection hierarchy. Task-number: QTBUG-68859 Change-Id: I938f32b5da22ce18f95d761f9b34e77fff923e24 Reviewed-by: Gatis Paeglis --- src/plugins/platforms/xcb/qxcbconnection.cpp | 56 +++++-------------- src/plugins/platforms/xcb/qxcbconnection.h | 17 ++---- src/plugins/platforms/xcb/qxcbintegration.cpp | 26 ++++++--- src/plugins/platforms/xcb/qxcbintegration.h | 1 - src/plugins/platforms/xcb/qxcbmain.cpp | 12 +--- 5 files changed, 40 insertions(+), 72 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 4e24c970b4..09b920a09e 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -525,59 +525,31 @@ void QXcbConnection::initializeScreens() } } -QXcbConnection *QXcbConnection::create(QXcbNativeInterface *nativeInterface, bool canGrabServer, - xcb_visualid_t defaultVisualId, - const char *displayNameIn) +QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, xcb_visualid_t defaultVisualId, const char *displayName) + : m_canGrabServer(canGrabServer) + , m_defaultVisualId(defaultVisualId) + , m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY")) + , m_nativeInterface(nativeInterface) { - const QByteArray displayName = displayNameIn ? QByteArray(displayNameIn) : qgetenv("DISPLAY"); - int primaryScreenNumber = 0; - void *xlibDisplay = nullptr; - xcb_connection_t *connection = nullptr; #if QT_CONFIG(xcb_xlib) - Display *dpy = XOpenDisplay(displayName.constData()); + Display *dpy = XOpenDisplay(m_displayName.constData()); if (dpy) { - primaryScreenNumber = DefaultScreen(dpy); - connection = XGetXCBConnection(dpy); + m_primaryScreenNumber = DefaultScreen(dpy); + m_connection = XGetXCBConnection(dpy); XSetEventQueueOwner(dpy, XCBOwnsEventQueue); XSetErrorHandler(nullErrorHandler); XSetIOErrorHandler(ioErrorHandler); - xlibDisplay = dpy; + m_xlib_display = dpy; } #else - connection = xcb_connect(displayName.constData(), &primaryScreenNumber); + m_connection = xcb_connect(m_displayName.constData(), &m_primaryScreenNumber); #endif // QT_CONFIG(xcb_xlib) - if (Q_UNLIKELY(connection == nullptr)) { - qWarning("QXcbConnection: Could not connect to display \"%s\"", displayName.constData()); - return nullptr; - } - if (Q_UNLIKELY(xcb_connection_has_error(connection))) { -#if QT_CONFIG(xcb_xlib) - XCloseDisplay(static_cast(xlibDisplay)); -#else - xcb_disconnect(connection); -#endif - qWarning("QXcbConnection: Errors occurred connecting to display \"%s\"", displayName.constData()); - return nullptr; - } - return new QXcbConnection(connection, primaryScreenNumber, nativeInterface, - canGrabServer, defaultVisualId, displayName, xlibDisplay); -} + if (Q_UNLIKELY(!m_connection || xcb_connection_has_error(m_connection))) { + qCWarning(lcQpaScreen, "QXcbConnection: Could not connect to display %s", m_displayName.constData()); + return; + } -QXcbConnection::QXcbConnection(xcb_connection_t *c, int primaryScreenNumber, - QXcbNativeInterface *nativeInterface, bool canGrabServer, - xcb_visualid_t defaultVisualId, const QByteArray &displayName, - void *xlibDisplay) - : m_connection(c) - , m_canGrabServer(canGrabServer) - , m_defaultVisualId(defaultVisualId) - , m_primaryScreenNumber(primaryScreenNumber) - , m_displayName(displayName) - , m_nativeInterface(nativeInterface) -#if QT_CONFIG(xcb_xlib) - , m_xlib_display(xlibDisplay) -#endif -{ m_reader = new QXcbEventReader(this); m_reader->start(); diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index db45031cf4..a97a1f1002 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -380,16 +380,9 @@ class Q_XCB_EXPORT QXcbConnection : public QObject { Q_OBJECT public: - explicit QXcbConnection(xcb_connection_t *c, int primaryScreenNumber, - QXcbNativeInterface *nativeInterface, bool canGrabServer, - xcb_visualid_t defaultVisualId, const QByteArray &displayName, - void *xlibDisplay = nullptr); - + QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, xcb_visualid_t defaultVisualId, const char *displayName = 0); ~QXcbConnection(); - static QXcbConnection *create(QXcbNativeInterface *nativeInterface, bool canGrabServer, - xcb_visualid_t defaultVisualId, const char *displayName = nullptr); - QXcbConnection *connection() const { return const_cast(this); } bool isConnected() const; @@ -648,21 +641,21 @@ private: static bool xi2GetValuatorValueIfSet(const void *event, int valuatorNum, double *value); #endif - xcb_connection_t *const m_connection; + xcb_connection_t *m_connection = nullptr; const xcb_setup_t *m_setup = nullptr; const bool m_canGrabServer; const xcb_visualid_t m_defaultVisualId; QList m_virtualDesktops; QList m_screens; - const int m_primaryScreenNumber; + int m_primaryScreenNumber = 0; xcb_atom_t m_allAtoms[QXcbAtom::NAtoms]; xcb_timestamp_t m_time = XCB_CURRENT_TIME; xcb_timestamp_t m_netWmUserTime = XCB_CURRENT_TIME; - const QByteArray m_displayName; + QByteArray m_displayName; QXcbKeyboard *m_keyboard = nullptr; #ifndef QT_NO_CLIPBOARD @@ -675,7 +668,7 @@ private: QXcbNativeInterface *m_nativeInterface = nullptr; #if QT_CONFIG(xcb_xlib) - void *const m_xlib_display; + void *m_xlib_display = nullptr; #endif QXcbEventReader *m_reader = nullptr; diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index db8dc09025..db8f816a86 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -192,15 +192,25 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char const int numParameters = parameters.size(); m_connections.reserve(1 + numParameters / 2); + auto conn = new QXcbConnection(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, displayName); + if (conn->isConnected()) + m_connections << conn; + else + delete conn; - if (QXcbConnection *defaultConnection = QXcbConnection::create(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, displayName)) { - m_connections.append(defaultConnection); - for (int i = 0; i < numParameters - 1; i += 2) { - qCDebug(lcQpaScreen) << "connecting to additional display: " << parameters.at(i) << parameters.at(i+1); - QString display = parameters.at(i) + QLatin1Char(':') + parameters.at(i+1); - if (QXcbConnection *connection = QXcbConnection::create(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, display.toLatin1().constData())) - m_connections.append(connection); - } + for (int i = 0; i < numParameters - 1; i += 2) { + qCDebug(lcQpaScreen) << "connecting to additional display: " << parameters.at(i) << parameters.at(i+1); + QString display = parameters.at(i) + QLatin1Char(':') + parameters.at(i+1); + conn = new QXcbConnection(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, display.toLatin1().constData()); + if (conn->isConnected()) + m_connections << conn; + else + delete conn; + } + + if (m_connections.isEmpty()) { + qCritical("Could not connect to any X display."); + exit(1); } m_fontDatabase.reset(new QGenericUnixFontDatabase()); diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h index a2de22d53d..69e49cb7f6 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.h +++ b/src/plugins/platforms/xcb/qxcbintegration.h @@ -103,7 +103,6 @@ public: QPlatformTheme *createPlatformTheme(const QString &name) const override; QVariant styleHint(StyleHint hint) const override; - bool hasDefaultConnection() const { return !m_connections.isEmpty(); } QXcbConnection *defaultConnection() const { return m_connections.first(); } QByteArray wmClass() const; diff --git a/src/plugins/platforms/xcb/qxcbmain.cpp b/src/plugins/platforms/xcb/qxcbmain.cpp index 539d033ca9..f8cb9a9269 100644 --- a/src/plugins/platforms/xcb/qxcbmain.cpp +++ b/src/plugins/platforms/xcb/qxcbmain.cpp @@ -52,16 +52,10 @@ public: QPlatformIntegration* QXcbIntegrationPlugin::create(const QString& system, const QStringList& parameters, int &argc, char **argv) { - if (!system.compare(QLatin1String("xcb"), Qt::CaseInsensitive)) { - QXcbIntegration *xcbIntegration = new QXcbIntegration(parameters, argc, argv); - if (!xcbIntegration->hasDefaultConnection()) { - delete xcbIntegration; - return nullptr; - } - return xcbIntegration; - } + if (!system.compare(QLatin1String("xcb"), Qt::CaseInsensitive)) + return new QXcbIntegration(parameters, argc, argv); - return nullptr; + return 0; } QT_END_NAMESPACE From 243c3044b647357ca6df79ac1497ae43de957d31 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Fri, 31 Aug 2018 13:03:47 +0200 Subject: [PATCH 0019/1650] xcb: lock-free event processing For details how this works refer to the documentation in the patch. The follow-up patches will switch to calling processXcbEvents() on every event loop iteration. With the existing code that would mean frequent locking of shared data (event queue). Acquiring a lock is fast, but lock contention isn't. To avoid potential problems, reimplement xcb event processing to be lock-free. Besides theoretical performance benefits, this definitally improves code readability in qxcbconnection.cpp. Thanks to Mikhail Svetkin for questioning the design of the existing code. Done-with: Mikhail Svetkin Change-Id: I935f2b6ca802580f5c80205aef7b2f9afc172d26 Reviewed-by: Mikhail Svetkin Reviewed-by: Thiago Macieira --- src/plugins/platforms/xcb/qxcbclipboard.cpp | 14 +- src/plugins/platforms/xcb/qxcbconnection.cpp | 290 +++------------ src/plugins/platforms/xcb/qxcbconnection.h | 85 +---- src/plugins/platforms/xcb/qxcbdrag.cpp | 4 +- src/plugins/platforms/xcb/qxcbeventqueue.cpp | 332 ++++++++++++++++++ src/plugins/platforms/xcb/qxcbeventqueue.h | 160 +++++++++ src/plugins/platforms/xcb/qxcbintegration.cpp | 3 +- src/plugins/platforms/xcb/qxcbkeyboard.cpp | 5 +- .../platforms/xcb/qxcbnativeinterface.cpp | 10 +- .../platforms/xcb/qxcbnativeinterface.h | 4 +- src/plugins/platforms/xcb/qxcbwindow.cpp | 35 +- src/plugins/platforms/xcb/xcb_qpa_lib.pro | 6 +- 12 files changed, 589 insertions(+), 359 deletions(-) create mode 100644 src/plugins/platforms/xcb/qxcbeventqueue.cpp create mode 100644 src/plugins/platforms/xcb/qxcbeventqueue.h diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp index 84831cdbe5..3fd14a659e 100644 --- a/src/plugins/platforms/xcb/qxcbclipboard.cpp +++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp @@ -807,18 +807,18 @@ xcb_generic_event_t *QXcbClipboard::waitForClipboardEvent(xcb_window_t window, i { QElapsedTimer timer; timer.start(); + QXcbEventQueue *queue = connection()->eventQueue(); do { - auto e = connection()->checkEvent([window, type](xcb_generic_event_t *event, int eventType) { + auto e = queue->peek([window, type](xcb_generic_event_t *event, int eventType) { if (eventType != type) return false; if (eventType == XCB_PROPERTY_NOTIFY) { auto propertyNotify = reinterpret_cast(event); - if (propertyNotify->window == window) - return true; - } else if (eventType == XCB_SELECTION_NOTIFY) { + return propertyNotify->window == window; + } + if (eventType == XCB_SELECTION_NOTIFY) { auto selectionNotify = reinterpret_cast(event); - if (selectionNotify->requestor == window) - return true; + return selectionNotify->requestor == window; } return false; }); @@ -833,7 +833,7 @@ xcb_generic_event_t *QXcbClipboard::waitForClipboardEvent(xcb_window_t window, i // process other clipboard events, since someone is probably requesting data from us auto clipboardAtom = atom(QXcbAtom::CLIPBOARD); - e = connection()->checkEvent([clipboardAtom](xcb_generic_event_t *event, int type) { + e = queue->peek([clipboardAtom](xcb_generic_event_t *event, int type) { xcb_atom_t selection = XCB_ATOM_NONE; if (type == XCB_SELECTION_REQUEST) selection = reinterpret_cast(event)->selection; diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 09b920a09e..4d3f62791c 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -57,6 +57,7 @@ #include "qxcbglintegration.h" #include "qxcbcursor.h" #include "qxcbbackingstore.h" +#include "qxcbeventqueue.h" #include #include @@ -97,6 +98,7 @@ Q_LOGGING_CATEGORY(lcQpaXInputDevices, "qt.qpa.input.devices") Q_LOGGING_CATEGORY(lcQpaXInputEvents, "qt.qpa.input.events") Q_LOGGING_CATEGORY(lcQpaScreen, "qt.qpa.screen") Q_LOGGING_CATEGORY(lcQpaEvents, "qt.qpa.events") +Q_LOGGING_CATEGORY(lcQpaEventReader, "qt.qpa.events.reader") Q_LOGGING_CATEGORY(lcQpaXcb, "qt.qpa.xcb") // for general (uncategorized) XCB logging Q_LOGGING_CATEGORY(lcQpaPeeker, "qt.qpa.peeker") Q_LOGGING_CATEGORY(lcQpaKeyboard, "qt.qpa.xkeyboard") @@ -550,8 +552,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra return; } - m_reader = new QXcbEventReader(this); - m_reader->start(); + m_eventQueue = new QXcbEventQueue(this); xcb_extension_t *extensions[] = { &xcb_shm_id, &xcb_xfixes_id, &xcb_randr_id, &xcb_shape_id, &xcb_sync_id, @@ -618,12 +619,8 @@ QXcbConnection::~QXcbConnection() #if QT_CONFIG(draganddrop) delete m_drag; #endif - if (m_reader && m_reader->isRunning()) { - sendConnectionEvent(QXcbAtom::_QT_CLOSE_CONNECTION); - m_reader->wait(); - } - - delete m_reader; + if (m_eventQueue) + delete m_eventQueue; QXcbIntegration *integration = QXcbIntegration::instance(); // Delete screens in reverse order to avoid crash in case of multiple screens @@ -1226,151 +1223,6 @@ void QXcbConnection::addPeekFunc(PeekFunc f) m_peekFuncs.append(f); } -qint32 QXcbConnection::generatePeekerId() -{ - qint32 peekerId = m_peekerIdSource++; - m_peekerToCachedIndex.insert(peekerId, 0); - return peekerId; -} - -bool QXcbConnection::removePeekerId(qint32 peekerId) -{ - if (!m_peekerToCachedIndex.contains(peekerId)) { - qCWarning(lcQpaXcb, "failed to remove unknown peeker id: %d", peekerId); - return false; - } - m_peekerToCachedIndex.remove(peekerId); - if (m_peekerToCachedIndex.isEmpty()) { - m_peekerIdSource = 0; // Once the hash becomes empty, we can start reusing IDs - m_peekerIndexCacheDirty = false; - } - return true; -} - -bool QXcbConnection::peekEventQueue(PeekerCallback peeker, void *peekerData, - PeekOptions option, qint32 peekerId) -{ - bool peekerIdProvided = peekerId != -1; - if (peekerIdProvided && !m_peekerToCachedIndex.contains(peekerId)) { - qCWarning(lcQpaXcb, "failed to find index for unknown peeker id: %d", peekerId); - return false; - } - - bool peekFromCachedIndex = option.testFlag(PeekOption::PeekFromCachedIndex); - if (peekFromCachedIndex && !peekerIdProvided) { - qCWarning(lcQpaXcb, "PeekOption::PeekFromCachedIndex requires peeker id"); - return false; - } - - if (peekerIdProvided && m_peekerIndexCacheDirty) { - // When the main event loop has flushed the buffered XCB events into the window - // system event queue, the cached indices are not valid anymore and need reset. - auto it = m_peekerToCachedIndex.begin(); - while (it != m_peekerToCachedIndex.constEnd()) { - (*it) = 0; - ++it; - } - m_peekerIndexCacheDirty = false; - } - - qint32 peekerIndex = peekFromCachedIndex ? m_peekerToCachedIndex.value(peekerId) : 0; - qint32 startingIndex = peekerIndex; - bool result = false; - m_mainEventLoopFlushedQueue = false; - - QXcbEventArray *eventqueue = m_reader->lock(); - - if (Q_UNLIKELY(lcQpaPeeker().isDebugEnabled())) { - qCDebug(lcQpaPeeker, "[%d] peeker index: %d | mode: %s | queue size: %d", peekerId, - peekerIndex, peekFromCachedIndex ? "cache" : "start", eventqueue->size()); - } - while (peekerIndex < eventqueue->size() && !result && !m_mainEventLoopFlushedQueue) { - xcb_generic_event_t *event = eventqueue->at(peekerIndex++); - if (!event) - continue; - if (Q_UNLIKELY(lcQpaPeeker().isDebugEnabled())) { - QString debug = QString((QLatin1String("[%1] peeking at index: %2"))) - .arg(peekerId).arg(peekerIndex - 1); - printXcbEvent(lcQpaPeeker(), debug.toLatin1(), event); - } - // A peeker may call QCoreApplication::processEvents(), which has two implications: - // 1) We need to make the lock available for QXcbConnection::processXcbEvents(), - // otherwise we will deadlock; - // 2) QXcbConnection::processXcbEvents() will flush the queue we are currently - // looping through; - m_reader->unlock(); - result = peeker(event, peekerData); - m_reader->lock(); - } - - m_reader->unlock(); - - if (peekerIdProvided && peekerIndex != startingIndex && !m_mainEventLoopFlushedQueue) { - auto it = m_peekerToCachedIndex.find(peekerId); - // Make sure that a peeker callback did not remove the peeker id - if (it != m_peekerToCachedIndex.constEnd()) - (*it) = peekerIndex; - } - - return result; -} - -QXcbEventReader::QXcbEventReader(QXcbConnection *connection) - : m_connection(connection) -{ -} - -void QXcbEventReader::start() -{ - connect(this, &QXcbEventReader::eventPending, m_connection, &QXcbConnection::processXcbEvents, Qt::QueuedConnection); - connect(this, &QXcbEventReader::finished, m_connection, &QXcbConnection::processXcbEvents); - QThread::start(); -} - -void QXcbEventReader::registerEventDispatcher(QAbstractEventDispatcher *dispatcher) -{ - // Flush the xcb connection before the event dispatcher is going to block. - connect(dispatcher, &QAbstractEventDispatcher::aboutToBlock, m_connection, &QXcbConnection::flush); -} - -void QXcbEventReader::run() -{ - xcb_generic_event_t *event; - while (m_connection && (event = xcb_wait_for_event(m_connection->xcb_connection()))) { - m_mutex.lock(); - addEvent(event); - while (m_connection && (event = xcb_poll_for_queued_event(m_connection->xcb_connection()))) - addEvent(event); - m_mutex.unlock(); - emit eventPending(); - } - - m_mutex.lock(); - for (int i = 0; i < m_events.size(); ++i) - free(m_events.at(i)); - m_events.clear(); - m_mutex.unlock(); -} - -void QXcbEventReader::addEvent(xcb_generic_event_t *event) -{ - if ((event->response_type & ~0x80) == XCB_CLIENT_MESSAGE - && (reinterpret_cast(event))->type == m_connection->atom(QXcbAtom::_QT_CLOSE_CONNECTION)) - m_connection = 0; - m_events << event; -} - -QXcbEventArray *QXcbEventReader::lock() -{ - m_mutex.lock(); - return &m_events; -} - -void QXcbEventReader::unlock() -{ - m_mutex.unlock(); -} - void QXcbConnection::setFocusWindow(QWindow *w) { m_focusWindow = w ? static_cast(w->handle()) : nullptr; @@ -1397,31 +1249,6 @@ void QXcbConnection::ungrabServer() xcb_ungrab_server(m_connection); } -void QXcbConnection::sendConnectionEvent(QXcbAtom::Atom a, uint id) -{ - xcb_client_message_event_t event; - memset(&event, 0, sizeof(event)); - - const xcb_window_t eventListener = xcb_generate_id(m_connection); - xcb_screen_iterator_t it = xcb_setup_roots_iterator(m_setup); - xcb_screen_t *screen = it.data; - xcb_create_window(m_connection, XCB_COPY_FROM_PARENT, - eventListener, screen->root, - 0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_ONLY, - screen->root_visual, 0, 0); - - event.response_type = XCB_CLIENT_MESSAGE; - event.format = 32; - event.sequence = 0; - event.window = eventListener; - event.type = atom(a); - event.data.data32[0] = id; - - xcb_send_event(xcb_connection(), false, eventListener, XCB_EVENT_MASK_NO_EVENT, reinterpret_cast(&event)); - xcb_destroy_window(m_connection, eventListener); - xcb_flush(xcb_connection()); -} - xcb_timestamp_t QXcbConnection::getTimestamp() { // send a dummy event to myself to get the timestamp from X server. @@ -1433,12 +1260,10 @@ xcb_timestamp_t QXcbConnection::getTimestamp() connection()->flush(); xcb_generic_event_t *event = nullptr; - // lets keep this inside a loop to avoid a possible race condition, where - // reader thread has not yet had the time to acquire the mutex in order - // to add the new set of events to its event queue + while (!event) { connection()->sync(); - event = checkEvent([window, dummyAtom](xcb_generic_event_t *event, int type) { + event = eventQueue()->peek([window, dummyAtom](xcb_generic_event_t *event, int type) { if (type != XCB_PROPERTY_NOTIFY) return false; auto propertyNotify = reinterpret_cast(event); @@ -1546,10 +1371,6 @@ static inline bool isXIType(xcb_generic_event_t *event, int opCode, uint16_t typ return e->event_type == type; } #endif -static inline bool isValid(xcb_generic_event_t *event) -{ - return event && (event->response_type & ~0x80); -} /*! \internal @@ -1563,22 +1384,18 @@ static inline bool isValid(xcb_generic_event_t *event) 3) Or add public API to Qt for disabling event compression QTBUG-44964 */ -bool QXcbConnection::compressEvent(xcb_generic_event_t *event, int currentIndex, QXcbEventArray *eventqueue) const +bool QXcbConnection::compressEvent(xcb_generic_event_t *event) const { uint responseType = event->response_type & ~0x80; - int nextIndex = currentIndex + 1; if (responseType == XCB_MOTION_NOTIFY) { // compress XCB_MOTION_NOTIFY notify events - for (int j = nextIndex; j < eventqueue->size(); ++j) { - xcb_generic_event_t *next = eventqueue->at(j); - if (!isValid(next)) - continue; - if (next->response_type == XCB_MOTION_NOTIFY) - return true; - } - return false; + return m_eventQueue->peek(QXcbEventQueue::PeekRetainMatch, + [](xcb_generic_event_t *, int type) { + return type == XCB_MOTION_NOTIFY; + }); } + #if QT_CONFIG(xcb_xinput) // compress XI_* events if (responseType == XCB_GE_GENERIC) { @@ -1588,50 +1405,44 @@ bool QXcbConnection::compressEvent(xcb_generic_event_t *event, int currentIndex, // compress XI_Motion if (isXIType(event, m_xiOpCode, XCB_INPUT_MOTION)) { #if QT_CONFIG(tabletevent) - auto *xdev = reinterpret_cast(event); + auto xdev = reinterpret_cast(event); if (!QCoreApplication::testAttribute(Qt::AA_CompressTabletEvents) && const_cast(this)->tabletDataForDevice(xdev->sourceid)) return false; #endif // QT_CONFIG(tabletevent) - for (int j = nextIndex; j < eventqueue->size(); ++j) { - xcb_generic_event_t *next = eventqueue->at(j); - if (!isValid(next)) - continue; - if (isXIType(next, m_xiOpCode, XCB_INPUT_MOTION)) - return true; - } - return false; + return m_eventQueue->peek(QXcbEventQueue::PeekRetainMatch, + [this](xcb_generic_event_t *next, int) { + return isXIType(next, m_xiOpCode, XCB_INPUT_MOTION); + }); } + // compress XI_TouchUpdate for the same touch point id if (isXIType(event, m_xiOpCode, XCB_INPUT_TOUCH_UPDATE)) { - auto *touchUpdateEvent = reinterpret_cast(event); + auto touchUpdateEvent = reinterpret_cast(event); uint32_t id = touchUpdateEvent->detail % INT_MAX; - for (int j = nextIndex; j < eventqueue->size(); ++j) { - xcb_generic_event_t *next = eventqueue->at(j); - if (!isValid(next)) - continue; - if (isXIType(next, m_xiOpCode, XCB_INPUT_TOUCH_UPDATE)) { - auto *touchUpdateNextEvent = reinterpret_cast(next); - if (id == touchUpdateNextEvent->detail % INT_MAX) - return true; - } - } - return false; + return m_eventQueue->peek(QXcbEventQueue::PeekRetainMatch, + [this, &id](xcb_generic_event_t *next, int) { + if (!isXIType(next, m_xiOpCode, XCB_INPUT_TOUCH_UPDATE)) + return false; + auto touchUpdateNextEvent = reinterpret_cast(next); + return id == touchUpdateNextEvent->detail % INT_MAX; + }); } + return false; } #endif + if (responseType == XCB_CONFIGURE_NOTIFY) { // compress multiple configure notify events for the same window - for (int j = nextIndex; j < eventqueue->size(); ++j) { - xcb_generic_event_t *next = eventqueue->at(j); - if (isValid(next) && next->response_type == XCB_CONFIGURE_NOTIFY - && reinterpret_cast(next)->event == reinterpret_cast(event)->event) - { - return true; - } - } - return false; + return m_eventQueue->peek(QXcbEventQueue::PeekRetainMatch, + [event](xcb_generic_event_t *next, int type) { + if (type != XCB_CONFIGURE_NOTIFY) + return false; + auto currentEvent = reinterpret_cast(event); + auto nextEvent = reinterpret_cast(next); + return currentEvent->event == nextEvent->event; + }); } return false; @@ -1645,22 +1456,17 @@ void QXcbConnection::processXcbEvents() exit(1); } - QXcbEventArray *eventqueue = m_reader->lock(); + m_eventQueue->flushBufferedEvents(); - for (int i = 0; i < eventqueue->size(); ++i) { - xcb_generic_event_t *event = eventqueue->at(i); - if (!event) - continue; + while (xcb_generic_event_t *event = m_eventQueue->takeFirst()) { QScopedPointer eventGuard(event); - (*eventqueue)[i] = 0; if (!(event->response_type & ~0x80)) { handleXcbError(reinterpret_cast(event)); continue; } - if (Q_LIKELY(QCoreApplication::testAttribute(Qt::AA_CompressHighFrequencyEvents)) && - compressEvent(event, i, eventqueue)) + compressEvent(event)) continue; #ifndef QT_NO_CLIPBOARD @@ -1679,21 +1485,19 @@ void QXcbConnection::processXcbEvents() m_peekFuncs.erase(std::remove_if(m_peekFuncs.begin(), m_peekFuncs.end(), isWaitingFor), m_peekFuncs.end()); - m_reader->unlock(); + handleXcbEvent(event); - m_reader->lock(); + + // The lock-based solution used to free the lock inside this loop, + // hence allowing for more events to arrive. ### Check if we want + // this flush here after QTBUG-70095 + m_eventQueue->flushBufferedEvents(); } - eventqueue->clear(); - - m_reader->unlock(); - - m_peekerIndexCacheDirty = m_mainEventLoopFlushedQueue = true; - // Indicate with a null event that the event the callbacks are waiting for // is not in the queue currently. for (PeekFunc f : qAsConst(m_peekFuncs)) - f(this, 0); + f(this, nullptr); m_peekFuncs.clear(); xcb_flush(xcb_connection()); diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index a97a1f1002..29a233496b 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -47,15 +47,14 @@ #include "qxcbexport.h" #include #include -#include #include -#include #include -#include #include #include #include +#include "qxcbeventqueue.h" + #include #include @@ -84,6 +83,7 @@ Q_DECLARE_LOGGING_CATEGORY(lcQpaXcb) Q_DECLARE_LOGGING_CATEGORY(lcQpaPeeker) Q_DECLARE_LOGGING_CATEGORY(lcQpaKeyboard) Q_DECLARE_LOGGING_CATEGORY(lcQpaXDnd) +Q_DECLARE_LOGGING_CATEGORY(lcQpaEventReader) class QXcbVirtualDesktop; class QXcbScreen; @@ -305,35 +305,6 @@ namespace QXcbAtom { }; } -typedef QVarLengthArray QXcbEventArray; - -class QXcbConnection; -class QXcbEventReader : public QThread -{ - Q_OBJECT -public: - QXcbEventReader(QXcbConnection *connection); - - void run() override; - - QXcbEventArray *lock(); - void unlock(); - - void start(); - - void registerEventDispatcher(QAbstractEventDispatcher *dispatcher); - -signals: - void eventPending(); - -private: - void addEvent(xcb_generic_event_t *event); - - QMutex m_mutex; - QXcbEventArray m_events; - QXcbConnection *m_connection; -}; - class QXcbWindowEventListener { public: @@ -375,7 +346,6 @@ private: QXcbWindow *m_window; }; -class QAbstractEventDispatcher; class Q_XCB_EXPORT QXcbConnection : public QObject { Q_OBJECT @@ -385,6 +355,7 @@ public: QXcbConnection *connection() const { return const_cast(this); } bool isConnected() const; + QXcbEventQueue *eventQueue() const { return m_eventQueue; } const QList &virtualDesktops() const { return m_virtualDesktops; } const QList &screens() const { return m_screens; } @@ -445,21 +416,9 @@ public: QXcbWindowEventListener *windowEventListenerFromId(xcb_window_t id); QXcbWindow *platformWindowFromId(xcb_window_t id); - template - inline xcb_generic_event_t *checkEvent(Functor &&filter, bool removeFromQueue = true); - typedef bool (*PeekFunc)(QXcbConnection *, xcb_generic_event_t *); void addPeekFunc(PeekFunc f); - // Peek at all queued events - qint32 generatePeekerId(); - bool removePeekerId(qint32 peekerId); - enum PeekOption { PeekDefault = 0, PeekFromCachedIndex = 1 }; // see qx11info_x11.h - Q_DECLARE_FLAGS(PeekOptions, PeekOption) - typedef bool (*PeekerCallback)(xcb_generic_event_t *event, void *peekerData); - bool peekEventQueue(PeekerCallback peeker, void *peekerData = nullptr, - PeekOptions option = PeekDefault, qint32 peekerId = -1); - inline xcb_timestamp_t time() const { return m_time; } inline void setTime(xcb_timestamp_t t) { if (t > m_time) m_time = t; } @@ -530,24 +489,20 @@ public: void abortSystemMoveResizeForTouch(); bool isTouchScreen(int id); #endif - QXcbEventReader *eventReader() const { return m_reader; } bool canGrab() const { return m_canGrabServer; } QXcbGlIntegration *glIntegration() const; + void flush() { xcb_flush(m_connection); } + protected: bool event(QEvent *e) override; -public slots: - void flush() { xcb_flush(m_connection); } - -private slots: void processXcbEvents(); private: void initializeAllAtoms(); - void sendConnectionEvent(QXcbAtom::Atom atom, uint id = 0); void initializeShm(); void initializeXFixes(); void initializeXRender(); @@ -567,7 +522,7 @@ private: xcb_randr_get_output_info_reply_t *outputInfo); void destroyScreen(QXcbScreen *screen); void initializeScreens(); - bool compressEvent(xcb_generic_event_t *event, int currentIndex, QXcbEventArray *eventqueue) const; + bool compressEvent(xcb_generic_event_t *event) const; bool m_xi2Enabled = false; #if QT_CONFIG(xcb_xinput) @@ -670,7 +625,7 @@ private: #if QT_CONFIG(xcb_xlib) void *m_xlib_display = nullptr; #endif - QXcbEventReader *m_reader = nullptr; + QXcbEventQueue *m_eventQueue = nullptr; #if QT_CONFIG(xcb_xinput) QHash m_touchDevices; @@ -722,11 +677,7 @@ private: xcb_window_t m_qtSelectionOwner = 0; - bool m_mainEventLoopFlushedQueue = false; - qint32 m_peekerIdSource = 0; - bool m_peekerIndexCacheDirty = false; - QHash m_peekerToCachedIndex; - friend class QXcbEventReader; + friend class QXcbEventQueue; QByteArray m_xdgCurrentDesktop; }; @@ -737,24 +688,6 @@ Q_DECLARE_TYPEINFO(QXcbConnection::TabletData, Q_MOVABLE_TYPE); #endif #endif -template -xcb_generic_event_t *QXcbConnection::checkEvent(Functor &&filter, bool removeFromQueue) -{ - QXcbEventArray *eventqueue = m_reader->lock(); - - for (int i = 0; i < eventqueue->size(); ++i) { - xcb_generic_event_t *event = eventqueue->at(i); - if (event && filter(event, event->response_type & ~0x80)) { - if (removeFromQueue) - (*eventqueue)[i] = nullptr; - m_reader->unlock(); - return event; - } - } - m_reader->unlock(); - return nullptr; -} - class QXcbConnectionGrabber { public: diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index 2b8e507f30..aa329d8cb7 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -794,7 +794,7 @@ void QXcbDrag::handlePosition(QPlatformWindow * w, const xcb_client_message_even { xcb_client_message_event_t *lastEvent = const_cast(event); ClientMessageScanner scanner(atom(QXcbAtom::XdndPosition)); - while (auto nextEvent = connection()->checkEvent(scanner)) { + while (auto nextEvent = connection()->eventQueue()->peek(scanner)) { if (lastEvent != event) free(lastEvent); lastEvent = reinterpret_cast(nextEvent); @@ -846,7 +846,7 @@ void QXcbDrag::handleStatus(const xcb_client_message_event_t *event) xcb_client_message_event_t *lastEvent = const_cast(event); xcb_generic_event_t *nextEvent; ClientMessageScanner scanner(atom(QXcbAtom::XdndStatus)); - while ((nextEvent = connection()->checkEvent(scanner))) { + while ((nextEvent = connection()->eventQueue()->peek(scanner))) { if (lastEvent != event) free(lastEvent); lastEvent = (xcb_client_message_event_t *)nextEvent; diff --git a/src/plugins/platforms/xcb/qxcbeventqueue.cpp b/src/plugins/platforms/xcb/qxcbeventqueue.cpp new file mode 100644 index 0000000000..e530928ccb --- /dev/null +++ b/src/plugins/platforms/xcb/qxcbeventqueue.cpp @@ -0,0 +1,332 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "qxcbeventqueue.h" +#include "qxcbconnection.h" + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +/*! + \class QXcbEventQueue + \internal + + Lock-free event passing: + + The lock-free solution uses a singly-linked list to pass events from the + reader thread to the main thread. An atomic operation is used to sync the + tail node of the list between threads. The reader thread takes special care + when accessing the tail node. It does not dequeue the last node and does not + access (read or write) the tail node's 'next' member. This lets the reader + add more items at the same time as the main thread is dequeuing nodes from + the head. A custom linked list implementation is used, because QLinkedList + does not have any thread-safety guarantees and the custom list is more + lightweight - no reference counting, back links, etc. + + Memory management: + + In a normally functioning application, XCB plugin won't buffer more than few + batches of events, couple events per batch. Instead of constantly calling + new / delete, we can create a pool of nodes that we reuse. The main thread + uses an atomic operation to sync how many nodes have been restored (available + for reuse). If at some point a user application will block the main thread + for a long time, we might run out of nodes in the pool. Then we create nodes + on a heap. These will be automatically "garbage collected" out of the linked + list, once the main thread stops blocking. +*/ + +QXcbEventQueue::QXcbEventQueue(QXcbConnection *connection) + : m_connection(connection) +{ + connect(this, &QXcbEventQueue::eventsPending, m_connection, &QXcbConnection::processXcbEvents, Qt::QueuedConnection); + connect(this, &QXcbEventQueue::finished, m_connection, &QXcbConnection::processXcbEvents); + + // Lets init the list with one node, so we don't have to check for + // this special case in various places. + m_head = m_flushedTail = qXcbEventNodeFactory(nullptr); + m_tail.store(m_head, std::memory_order_release); + + start(); +} + +QXcbEventQueue::~QXcbEventQueue() +{ + if (isRunning()) { + sendCloseConnectionEvent(); + wait(); + } + + while (xcb_generic_event_t *event = takeFirst()) + free(event); + + if (m_head && m_head->fromHeap) + delete m_head; // the deferred node + + qCDebug(lcQpaEventReader) << "nodes on heap:" << m_nodesOnHeap; +} + +void QXcbEventQueue::registerEventDispatcher(QAbstractEventDispatcher *dispatcher) +{ + // Flush the xcb connection before the event dispatcher is going to block. + connect(dispatcher, &QAbstractEventDispatcher::aboutToBlock, m_connection, &QXcbConnection::flush); +} + +xcb_generic_event_t *QXcbEventQueue::takeFirst() +{ + if (isEmpty()) + return nullptr; + + xcb_generic_event_t *event = nullptr; + do { + event = m_head->event; + if (m_head == m_flushedTail) { + // defer dequeuing until next successful flush of events + if (event) // check if not cleared already by some filter + m_head->event = nullptr; // if not, clear it + } else { + dequeueNode(); + if (!event) + continue; // consumed by filter or deferred node + } + } while (!isEmpty() && !event); + + m_queueModified = m_peekerIndexCacheDirty = true; + + return event; +} + +void QXcbEventQueue::dequeueNode() +{ + QXcbEventNode *node = m_head; + m_head = m_head->next; + if (node->fromHeap) + delete node; + else + m_nodesRestored.fetch_add(1, std::memory_order_release); +} + +void QXcbEventQueue::flushBufferedEvents() +{ + m_flushedTail = m_tail.load(std::memory_order_acquire); +} + +QXcbEventNode *QXcbEventQueue::qXcbEventNodeFactory(xcb_generic_event_t *event) +{ + static QXcbEventNode qXcbNodePool[PoolSize]; + + if (m_freeNodes == 0) // out of nodes, check if the main thread has released any + m_freeNodes = m_nodesRestored.exchange(0, std::memory_order_acquire); + + if (m_freeNodes) { + m_freeNodes--; + if (m_poolIndex == PoolSize) { + // wrap back to the beginning, we always take and restore nodes in-order + m_poolIndex = 0; + } + QXcbEventNode *node = &qXcbNodePool[m_poolIndex++]; + node->event = event; + node->next = nullptr; + return node; + } + + // the main thread is not flushing events and thus the pool has become empty + auto node = new QXcbEventNode(event); + node->fromHeap = true; + qCDebug(lcQpaEventReader) << "[heap] " << m_nodesOnHeap++; + return node; +} + +void QXcbEventQueue::run() +{ + xcb_generic_event_t *event = nullptr; + xcb_connection_t *connection = m_connection->xcb_connection(); + QXcbEventNode *tail = m_head; + + auto enqueueEvent = [&tail, this](xcb_generic_event_t *event) { + if (!isCloseConnectionEvent(event)) { + tail->next = qXcbEventNodeFactory(event); + tail = tail->next; + m_tail.store(tail, std::memory_order_release); + } + }; + + while (!m_closeConnectionDetected && (event = xcb_wait_for_event(connection))) { + enqueueEvent(event); + while (!m_closeConnectionDetected && (event = xcb_poll_for_queued_event(connection))) + enqueueEvent(event); + + emit eventsPending(); + } +} + +qint32 QXcbEventQueue::generatePeekerId() +{ + const qint32 peekerId = m_peekerIdSource++; + m_peekerToNode.insert(peekerId, nullptr); + return peekerId; +} + +bool QXcbEventQueue::removePeekerId(qint32 peekerId) +{ + const auto it = m_peekerToNode.find(peekerId); + if (it == m_peekerToNode.constEnd()) { + qCWarning(lcQpaXcb, "failed to remove unknown peeker id: %d", peekerId); + return false; + } + m_peekerToNode.erase(it); + if (m_peekerToNode.isEmpty()) { + m_peekerIdSource = 0; // Once the hash becomes empty, we can start reusing IDs + m_peekerIndexCacheDirty = false; + } + return true; +} + +bool QXcbEventQueue::peekEventQueue(PeekerCallback peeker, void *peekerData, + PeekOptions option, qint32 peekerId) +{ + const bool peekerIdProvided = peekerId != -1; + auto peekerToNodeIt = m_peekerToNode.find(peekerId); + + if (peekerIdProvided && peekerToNodeIt == m_peekerToNode.constEnd()) { + qCWarning(lcQpaXcb, "failed to find index for unknown peeker id: %d", peekerId); + return false; + } + + const bool useCache = option.testFlag(PeekOption::PeekFromCachedIndex); + if (useCache && !peekerIdProvided) { + qCWarning(lcQpaXcb, "PeekOption::PeekFromCachedIndex requires peeker id"); + return false; + } + + if (peekerIdProvided && m_peekerIndexCacheDirty) { + for (auto &node : m_peekerToNode) // reset cache + node = nullptr; + m_peekerIndexCacheDirty = false; + } + + flushBufferedEvents(); + if (isEmpty()) + return false; + + const auto startNode = [this, useCache, peekerToNodeIt]() -> QXcbEventNode * { + if (useCache) { + const QXcbEventNode *cachedNode = peekerToNodeIt.value(); + if (!cachedNode) + return m_head; // cache was reset + if (cachedNode == m_flushedTail) + return nullptr; // no new events since the last call + return cachedNode->next; + } + return m_head; + }(); + + if (!startNode) + return false; + + // A peeker may call QCoreApplication::processEvents(), which will cause + // QXcbConnection::processXcbEvents() to modify the queue we are currently + // looping through; + m_queueModified = false; + bool result = false; + + QXcbEventNode *node = startNode; + do { + xcb_generic_event_t *event = node->event; + if (event && peeker(event, peekerData)) { + result = true; + break; + } + if (node == m_flushedTail) + break; + node = node->next; + } while (!m_queueModified); + + // Update the cached index if the queue was not modified, and hence the + // cache is still valid. + if (peekerIdProvided && node != startNode && !m_queueModified) { + // Before updating, make sure that a peeker callback did not remove + // the peeker id. + peekerToNodeIt = m_peekerToNode.find(peekerId); + if (peekerToNodeIt != m_peekerToNode.constEnd()) + *peekerToNodeIt = node; // id still in the cache, update node + } + + return result; +} + +void QXcbEventQueue::sendCloseConnectionEvent() const +{ + // A hack to close XCB connection. Apparently XCB does not have any APIs for this? + xcb_client_message_event_t event; + memset(&event, 0, sizeof(event)); + + xcb_connection_t *c = m_connection->xcb_connection(); + const xcb_window_t window = xcb_generate_id(c); + xcb_screen_iterator_t it = xcb_setup_roots_iterator(m_connection->m_setup); + xcb_screen_t *screen = it.data; + xcb_create_window(c, XCB_COPY_FROM_PARENT, + window, screen->root, + 0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_ONLY, + screen->root_visual, 0, nullptr); + + event.response_type = XCB_CLIENT_MESSAGE; + event.format = 32; + event.sequence = 0; + event.window = window; + event.type = m_connection->atom(QXcbAtom::_QT_CLOSE_CONNECTION); + event.data.data32[0] = 0; + + xcb_send_event(c, false, window, XCB_EVENT_MASK_NO_EVENT, reinterpret_cast(&event)); + xcb_destroy_window(c, window); + xcb_flush(c); +} + +bool QXcbEventQueue::isCloseConnectionEvent(const xcb_generic_event_t *event) +{ + if (event && (event->response_type & ~0x80) == XCB_CLIENT_MESSAGE) { + auto clientMessage = reinterpret_cast(event); + if (clientMessage->type == m_connection->atom(QXcbAtom::_QT_CLOSE_CONNECTION)) + m_closeConnectionDetected = true; + } + return m_closeConnectionDetected; +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbeventqueue.h b/src/plugins/platforms/xcb/qxcbeventqueue.h new file mode 100644 index 0000000000..5b0d8bf3d6 --- /dev/null +++ b/src/plugins/platforms/xcb/qxcbeventqueue.h @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QXCBEVENTQUEUE_H +#define QXCBEVENTQUEUE_H + +#include +#include + +#include + +#include + +QT_BEGIN_NAMESPACE + +struct QXcbEventNode { + QXcbEventNode(xcb_generic_event_t *e = nullptr) + : event(e) { } + + xcb_generic_event_t *event; + QXcbEventNode *next = nullptr; + bool fromHeap = false; +}; + +class QXcbConnection; +class QAbstractEventDispatcher; + +class QXcbEventQueue : public QThread +{ + Q_OBJECT +public: + QXcbEventQueue(QXcbConnection *connection); + ~QXcbEventQueue(); + + enum { PoolSize = 100 }; // 2.4 kB with 100 nodes + + enum PeekOption { + PeekDefault = 0, // see qx11info_x11.h for docs + PeekFromCachedIndex = 1, + PeekRetainMatch = 2, + PeekRemoveMatch = 3, + PeekRemoveMatchContinue = 4 + }; + Q_DECLARE_FLAGS(PeekOptions, PeekOption) + + void run() override; + + void registerEventDispatcher(QAbstractEventDispatcher *dispatcher); + + bool isEmpty() const { return m_head == m_flushedTail && !m_head->event; } + xcb_generic_event_t *takeFirst(); + void flushBufferedEvents(); + + // ### peek() and peekEventQueue() could be unified. Note that peekEventQueue() + // is public API exposed via QX11Extras/QX11Info. + template + xcb_generic_event_t *peek(Peeker &&peeker) { + return peek(PeekRemoveMatch, std::forward(peeker)); + } + template + inline xcb_generic_event_t *peek(PeekOption config, Peeker &&peeker); + + qint32 generatePeekerId(); + bool removePeekerId(qint32 peekerId); + + using PeekerCallback = bool (*)(xcb_generic_event_t *event, void *peekerData); + bool peekEventQueue(PeekerCallback peeker, void *peekerData = nullptr, + PeekOptions option = PeekDefault, qint32 peekerId = -1); +signals: + void eventsPending(); + +private: + QXcbEventNode *qXcbEventNodeFactory(xcb_generic_event_t *event); + void dequeueNode(); + + void sendCloseConnectionEvent() const; + bool isCloseConnectionEvent(const xcb_generic_event_t *event); + + QXcbEventNode *m_head = nullptr; + QXcbEventNode *m_flushedTail = nullptr; + std::atomic m_tail { nullptr }; + std::atomic_uint m_nodesRestored { 0 }; + + QXcbConnection *m_connection = nullptr; + bool m_closeConnectionDetected = false; + + uint m_freeNodes = PoolSize; + uint m_poolIndex = 0; + + qint32 m_peekerIdSource = 0; + bool m_queueModified = false; + bool m_peekerIndexCacheDirty = false; + QHash m_peekerToNode; + + // debug stats + quint64 m_nodesOnHeap = 0; +}; + +template +xcb_generic_event_t *QXcbEventQueue::peek(PeekOption option, Peeker &&peeker) +{ + flushBufferedEvents(); + if (isEmpty()) + return nullptr; + + QXcbEventNode *node = m_head; + do { + xcb_generic_event_t *event = node->event; + if (event && peeker(event, event->response_type & ~0x80)) { + if (option == PeekRemoveMatch || option == PeekRemoveMatchContinue) + node->event = nullptr; + if (option != PeekRemoveMatchContinue) + return event; + } + if (node == m_flushedTail) + break; + node = node->next; + } while (true); + + return nullptr; +} + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index db8f816a86..b1a1ed93cd 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -46,6 +46,7 @@ #include "qxcbbackingstore.h" #include "qxcbnativeinterface.h" #include "qxcbclipboard.h" +#include "qxcbeventqueue.h" #if QT_CONFIG(draganddrop) #include "qxcbdrag.h" #endif @@ -344,7 +345,7 @@ QAbstractEventDispatcher *QXcbIntegration::createEventDispatcher() const { QAbstractEventDispatcher *dispatcher = createUnixEventDispatcher(); for (int i = 0; i < m_connections.size(); i++) - m_connections[i]->eventReader()->registerEventDispatcher(dispatcher); + m_connections[i]->eventQueue()->registerEventDispatcher(dispatcher); return dispatcher; } diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 20c169fc53..ad06f24c14 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -1541,7 +1541,8 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, } else { m_isAutoRepeat = false; // Look at the next event in the queue to see if we are auto-repeating. - connection()->checkEvent([this, time, code](xcb_generic_event_t *event, int type) { + connection()->eventQueue()->peek(QXcbEventQueue::PeekRetainMatch, + [this, time, code](xcb_generic_event_t *event, int type) { if (type == XCB_KEY_PRESS) { auto keyPress = reinterpret_cast(event); m_isAutoRepeat = keyPress->time == time && keyPress->detail == code; @@ -1549,7 +1550,7 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, m_autoRepeatCode = code; } return true; - }, false /* removeFromQueue */); + }); } bool filtered = false; diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index 98bedea48a..524af5a2a7 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -437,20 +437,20 @@ void QXcbNativeInterface::setAppUserTime(QScreen* screen, xcb_timestamp_t time) qint32 QXcbNativeInterface::generatePeekerId() { QXcbIntegration *integration = QXcbIntegration::instance(); - return integration->defaultConnection()->generatePeekerId(); + return integration->defaultConnection()->eventQueue()->generatePeekerId(); } bool QXcbNativeInterface::removePeekerId(qint32 peekerId) { QXcbIntegration *integration = QXcbIntegration::instance(); - return integration->defaultConnection()->removePeekerId(peekerId); + return integration->defaultConnection()->eventQueue()->removePeekerId(peekerId); } -bool QXcbNativeInterface::peekEventQueue(QXcbConnection::PeekerCallback peeker, void *peekerData, - QXcbConnection::PeekOptions option, qint32 peekerId) +bool QXcbNativeInterface::peekEventQueue(QXcbEventQueue::PeekerCallback peeker, void *peekerData, + QXcbEventQueue::PeekOptions option, qint32 peekerId) { QXcbIntegration *integration = QXcbIntegration::instance(); - return integration->defaultConnection()->peekEventQueue(peeker, peekerData, option, peekerId); + return integration->defaultConnection()->eventQueue()->peekEventQueue(peeker, peekerData, option, peekerId); } void QXcbNativeInterface::setStartupId(const char *data) diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h index d1f2747bea..4656f46be5 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.h +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h @@ -118,8 +118,8 @@ public: static qint32 generatePeekerId(); static bool removePeekerId(qint32 peekerId); - static bool peekEventQueue(QXcbConnection::PeekerCallback peeker, void *peekerData = nullptr, - QXcbConnection::PeekOptions option = QXcbConnection::PeekDefault, + static bool peekEventQueue(QXcbEventQueue::PeekerCallback peeker, void *peekerData = nullptr, + QXcbEventQueue::PeekOptions option = QXcbEventQueue::PeekDefault, qint32 peekerId = -1); Q_INVOKABLE QString dumpConnectionNativeWindows(const QXcbConnection *connection, WId root) const; diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 69fc6c2951..772309c6ae 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -1818,21 +1818,20 @@ void QXcbWindow::handleExposeEvent(const xcb_expose_event_t *event) m_exposeRegion |= rect; bool pending = true; - xcb_generic_event_t *e = nullptr; - do { // compress expose events - e = connection()->checkEvent([this, &pending](xcb_generic_event_t *event, int type) { - if (type != XCB_EXPOSE) - return false; - auto expose = reinterpret_cast(event); - if (expose->window != m_window) - return false; - if (expose->count == 0) - pending = false; - m_exposeRegion |= QRect(expose->x, expose->y, expose->width, expose->height); - return true; - }); - free(e); - } while (e); + + connection()->eventQueue()->peek(QXcbEventQueue::PeekRemoveMatchContinue, + [this, &pending](xcb_generic_event_t *event, int type) { + if (type != XCB_EXPOSE) + return false; + auto expose = reinterpret_cast(event); + if (expose->window != m_window) + return false; + if (expose->count == 0) + pending = false; + m_exposeRegion |= QRect(expose->x, expose->y, expose->width, expose->height); + free(expose); + return true; + }); // if count is non-zero there are more expose events pending if (event->count == 0 || !pending) { @@ -2152,13 +2151,11 @@ void QXcbWindow::handleLeaveNotifyEvent(int root_x, int root_y, return; // check if enter event is buffered - auto event = connection()->checkEvent([](xcb_generic_event_t *event, int type) { + auto event = connection()->eventQueue()->peek([](xcb_generic_event_t *event, int type) { if (type != XCB_ENTER_NOTIFY) return false; auto enter = reinterpret_cast(event); - if (ignoreEnterEvent(enter->mode, enter->detail)) - return false; - return true; + return !ignoreEnterEvent(enter->mode, enter->detail); }); auto enter = reinterpret_cast(event); QXcbWindow *enterWindow = enter ? connection()->platformWindowFromId(enter->event) : nullptr; diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro index 9390d04983..fbda8c39b9 100644 --- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro +++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro @@ -27,7 +27,8 @@ SOURCES = \ qxcbcursor.cpp \ qxcbimage.cpp \ qxcbxsettings.cpp \ - qxcbsystemtraytracker.cpp + qxcbsystemtraytracker.cpp \ + qxcbeventqueue.cpp HEADERS = \ qxcbclipboard.h \ @@ -45,7 +46,8 @@ HEADERS = \ qxcbimage.h \ qxcbxsettings.h \ qxcbsystemtraytracker.h \ - qxcbxkbcommon.h + qxcbxkbcommon.h \ + qxcbeventqueue.h qtConfig(draganddrop) { SOURCES += qxcbdrag.cpp From 502a6cc2537f2b26d5cce1caec7504cc89047db1 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Fri, 7 Sep 2018 15:06:27 +0200 Subject: [PATCH 0020/1650] xcb: localize handling of Qt::AA_Compress* flags Handle both of them inside the QXcbConnection::compressEvent(). Change-Id: Ibe7184ba5c5b636013145e887c817dca701345ad Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbconnection.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 4d3f62791c..c1f0b71414 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -1386,6 +1386,9 @@ static inline bool isXIType(xcb_generic_event_t *event, int opCode, uint16_t typ */ bool QXcbConnection::compressEvent(xcb_generic_event_t *event) const { + if (!QCoreApplication::testAttribute(Qt::AA_CompressHighFrequencyEvents)) + return false; + uint responseType = event->response_type & ~0x80; if (responseType == XCB_MOTION_NOTIFY) { @@ -1465,8 +1468,7 @@ void QXcbConnection::processXcbEvents() handleXcbError(reinterpret_cast(event)); continue; } - if (Q_LIKELY(QCoreApplication::testAttribute(Qt::AA_CompressHighFrequencyEvents)) && - compressEvent(event)) + if (compressEvent(event)) continue; #ifndef QT_NO_CLIPBOARD From 1192c463db34e3f69be4d9ef976246ce265143a3 Mon Sep 17 00:00:00 2001 From: Alexandra Cherdantseva Date: Fri, 7 Sep 2018 13:07:35 +0300 Subject: [PATCH 0021/1650] QImageWriter/QPNGHandler: Quality option should be CompressionRatio Wrong option was used to set zlib compression level for png setCompression with negative value uses default compression setCompression with value between 0-100 converts to zlib compression level 0-9 setCompression with positive value overrides Quality option Change-Id: Ic4b048a1e30d6940019c2a00a6c24d0c11e3f821 Reviewed-by: Alexandra Cherdantseva Reviewed-by: Eirik Aavitsland --- src/gui/image/qpnghandler.cpp | 50 ++++++++++++------- .../image/qimagereader/tst_qimagereader.cpp | 1 + .../image/qimagewriter/tst_qimagewriter.cpp | 1 + 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index 242d8cd63b..13129e214b 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -99,12 +99,13 @@ public: }; QPngHandlerPrivate(QPngHandler *qq) - : gamma(0.0), fileGamma(0.0), quality(2), png_ptr(0), info_ptr(0), end_info(0), state(Ready), q(qq) + : gamma(0.0), fileGamma(0.0), quality(50), compression(50), png_ptr(0), info_ptr(0), end_info(0), state(Ready), q(qq) { } float gamma; float fileGamma; - int quality; + int quality; // quality is used for backward compatibility, maps to compression + int compression; QString description; QSize scaledSize; QStringList readTexts; @@ -161,11 +162,11 @@ public: void setGamma(float); bool writeImage(const QImage& img, int x, int y); - bool writeImage(const QImage& img, volatile int quality, const QString &description, int x, int y); + bool writeImage(const QImage& img, volatile int compression_in, const QString &description, int x, int y); bool writeImage(const QImage& img) { return writeImage(img, 0, 0); } - bool writeImage(const QImage& img, int quality, const QString &description) - { return writeImage(img, quality, description, 0, 0); } + bool writeImage(const QImage& img, int compression, const QString &description) + { return writeImage(img, compression, description, 0, 0); } QIODevice* device() { return dev; } @@ -814,7 +815,7 @@ bool QPNGImageWriter::writeImage(const QImage& image, int off_x, int off_y) return writeImage(image, -1, QString(), off_x, off_y); } -bool QPNGImageWriter::writeImage(const QImage& image, volatile int quality_in, const QString &description, +bool QPNGImageWriter::writeImage(const QImage& image, volatile int compression_in, const QString &description, int off_x_in, int off_y_in) { QPoint offset = image.offset(); @@ -842,13 +843,13 @@ bool QPNGImageWriter::writeImage(const QImage& image, volatile int quality_in, c return false; } - int quality = quality_in; - if (quality >= 0) { - if (quality > 9) { - qWarning("PNG: Quality %d out of range", quality); - quality = 9; + int compression = compression_in; + if (compression >= 0) { + if (compression > 9) { + qWarning("PNG: Compression %d out of range", compression); + compression = 9; } - png_set_compression_level(png_ptr, quality); + png_set_compression_level(png_ptr, compression); } png_set_write_fn(png_ptr, (void*)this, qpiw_write_fn, qpiw_flush_fn); @@ -1067,15 +1068,21 @@ bool QPNGImageWriter::writeImage(const QImage& image, volatile int quality_in, c } static bool write_png_image(const QImage &image, QIODevice *device, - int quality, float gamma, const QString &description) + int compression, int quality, float gamma, const QString &description) { + // quality is used for backward compatibility, maps to compression + QPNGImageWriter writer(device); - if (quality >= 0) { - quality = qMin(quality, 100); - quality = (100-quality) * 9 / 91; // map [0,100] -> [9,0] - } + if (compression >= 0) + compression = qMin(compression, 100); + else if (quality >= 0) + compression = 100 - qMin(quality, 100); + + if (compression >= 0) + compression = (compression * 9) / 91; // map [0,100] -> [0,9] + writer.setGamma(gamma); - return writer.writeImage(image, quality, description); + return writer.writeImage(image, compression, description); } QPngHandler::QPngHandler() @@ -1122,7 +1129,7 @@ bool QPngHandler::read(QImage *image) bool QPngHandler::write(const QImage &image) { - return write_png_image(image, device(), d->quality, d->gamma, d->description); + return write_png_image(image, device(), d->compression, d->quality, d->gamma, d->description); } bool QPngHandler::supportsOption(ImageOption option) const @@ -1131,6 +1138,7 @@ bool QPngHandler::supportsOption(ImageOption option) const || option == Description || option == ImageFormat || option == Quality + || option == CompressionRatio || option == Size || option == ScaledSize; } @@ -1146,6 +1154,8 @@ QVariant QPngHandler::option(ImageOption option) const return d->gamma == 0.0 ? d->fileGamma : d->gamma; else if (option == Quality) return d->quality; + else if (option == CompressionRatio) + return d->compression; else if (option == Description) return d->description; else if (option == Size) @@ -1164,6 +1174,8 @@ void QPngHandler::setOption(ImageOption option, const QVariant &value) d->gamma = value.toFloat(); else if (option == Quality) d->quality = value.toInt(); + else if (option == CompressionRatio) + d->compression = value.toInt(); else if (option == Description) d->description = value.toString(); else if (option == ScaledSize) diff --git a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp index aa9a990fef..c2ec5b8925 100644 --- a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp +++ b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp @@ -1603,6 +1603,7 @@ void tst_QImageReader::supportsOption_data() << (QIntList() << QImageIOHandler::Gamma << QImageIOHandler::Description << QImageIOHandler::Quality + << QImageIOHandler::CompressionRatio << QImageIOHandler::Size << QImageIOHandler::ScaledSize); } diff --git a/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp b/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp index a53c2ddb5b..77851cd7d0 100644 --- a/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp +++ b/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp @@ -408,6 +408,7 @@ void tst_QImageWriter::supportsOption_data() << (QIntList() << QImageIOHandler::Gamma << QImageIOHandler::Description << QImageIOHandler::Quality + << QImageIOHandler::CompressionRatio << QImageIOHandler::Size << QImageIOHandler::ScaledSize); } From 8ec98fc2dc40237730f99af099dffe2920ef5bcc Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 13 Apr 2018 11:44:41 +0200 Subject: [PATCH 0022/1650] Fix launching with depth 30 XOrg Our fallback logic for inexact matches was not very good at accepting better suggestions. Change-Id: I40fb78bf583171105725156148e4a2245fb81354 Reviewed-by: Gatis Paeglis --- .../eglconvenience/qxlibeglintegration.cpp | 14 ++++---- .../glxconvenience/qglxconvenience.cpp | 33 +++++++++++++++++++ 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/platformsupport/eglconvenience/qxlibeglintegration.cpp b/src/platformsupport/eglconvenience/qxlibeglintegration.cpp index 565dbfb11b..ac743e1e38 100644 --- a/src/platformsupport/eglconvenience/qxlibeglintegration.cpp +++ b/src/platformsupport/eglconvenience/qxlibeglintegration.cpp @@ -91,21 +91,21 @@ VisualID QXlibEglIntegration::getCompatibleVisualId(Display *display, EGLDisplay int visualRedSize = qPopulationCount(chosenVisualInfo->red_mask); int visualGreenSize = qPopulationCount(chosenVisualInfo->green_mask); int visualBlueSize = qPopulationCount(chosenVisualInfo->blue_mask); - int visualAlphaSize = chosenVisualInfo->depth == 32 ? 8 : 0; + int visualAlphaSize = chosenVisualInfo->depth - visualRedSize - visualBlueSize - visualGreenSize; - const bool visualMatchesConfig = visualRedSize == configRedSize - && visualGreenSize == configGreenSize - && visualBlueSize == configBlueSize - && visualAlphaSize == configAlphaSize; + const bool visualMatchesConfig = visualRedSize >= configRedSize + && visualGreenSize >= configGreenSize + && visualBlueSize >= configBlueSize + && visualAlphaSize >= configAlphaSize; // In some cases EGL tends to suggest a 24-bit visual for 8888 // configs. In such a case we have to fall back to XGetVisualInfo. if (!visualMatchesConfig) { visualId = 0; qCDebug(lcXlibEglDebug, - "EGL suggested using X Visual ID %d (%d %d %d depth %d) for EGL config %d" + "EGL suggested using X Visual ID %d (%d %d %d %d depth %d) for EGL config %d" "(%d %d %d %d), but this is incompatible", - (int)visualId, visualRedSize, visualGreenSize, visualBlueSize, chosenVisualInfo->depth, + (int)visualId, visualRedSize, visualGreenSize, visualBlueSize, visualAlphaSize, chosenVisualInfo->depth, configId, configRedSize, configGreenSize, configBlueSize, configAlphaSize); } } else { diff --git a/src/platformsupport/glxconvenience/qglxconvenience.cpp b/src/platformsupport/glxconvenience/qglxconvenience.cpp index 8d2e58b57b..d7cc36627a 100644 --- a/src/platformsupport/glxconvenience/qglxconvenience.cpp +++ b/src/platformsupport/glxconvenience/qglxconvenience.cpp @@ -42,13 +42,18 @@ #include #include +#include +#include #include "qglxconvenience_p.h" +#include #include #include #include +Q_LOGGING_CATEGORY(lcGlx, "qt.glx") + enum { XFocusOut = FocusOut, XFocusIn = FocusIn, @@ -207,6 +212,7 @@ GLXFBConfig qglx_findConfig(Display *display, int screen , QSurfaceFormat format const int requestedBlue = qMax(0, format.blueBufferSize()); const int requestedAlpha = qMax(0, format.alphaBufferSize()); + GLXFBConfig compatibleCandidate = nullptr; for (int i = 0; i < confcount; i++) { GLXFBConfig candidate = configs[i]; @@ -226,6 +232,16 @@ GLXFBConfig qglx_findConfig(Display *display, int screen , QSurfaceFormat format const int actualBlue = qPopulationCount(visual->blue_mask); const int actualAlpha = visual->depth - actualRed - actualGreen - actualBlue; + if (requestedRed && actualRed < requestedRed) + continue; + if (requestedGreen && actualGreen < requestedGreen) + continue; + if (requestedBlue && actualBlue < requestedBlue) + continue; + if (requestedAlpha && actualAlpha < requestedAlpha) + continue; + compatibleCandidate = candidate; + if (requestedRed && actualRed != requestedRed) continue; if (requestedGreen && actualGreen != requestedGreen) @@ -237,6 +253,11 @@ GLXFBConfig qglx_findConfig(Display *display, int screen , QSurfaceFormat format return candidate; } + if (compatibleCandidate) { + qCDebug(lcGlx) << "qglx_findConfig: Found non-matching but compatible FBConfig"; + return compatibleCandidate; + } + qCWarning(lcGlx, "qglx_findConfig: Failed to finding matching FBConfig (%d %d %d %d)", requestedRed, requestedGreen, requestedBlue, requestedAlpha); } while (qglx_reduceFormat(&format)); return config; @@ -352,6 +373,18 @@ void qglx_surfaceFormatFromVisualInfo(QSurfaceFormat *format, Display *display, bool qglx_reduceFormat(QSurfaceFormat *format) { Q_ASSERT(format); + if (std::max(std::max(format->redBufferSize(), format->greenBufferSize()), format->blueBufferSize()) > 8) { + if (format->alphaBufferSize() > 2) { + // First try to match 10 10 10 2 + format->setAlphaBufferSize(2); + return true; + } + + format->setRedBufferSize(std::min(format->redBufferSize(), 8)); + format->setGreenBufferSize(std::min(format->greenBufferSize(), 8)); + format->setBlueBufferSize(std::min(format->blueBufferSize(), 8)); + return true; + } if (format->redBufferSize() > 1) { format->setRedBufferSize(1); From 72fc65784d6e37804027ead10eb27b317a6f5ca1 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Tue, 19 Jun 2018 22:40:56 +0200 Subject: [PATCH 0023/1650] QImageReader: add tracepoints for image loading Change-Id: I5fe25793eeda01a4fa1658091890af23f66b7089 Reviewed-by: Rafael Roquetto --- src/gui/image/qimagereader.cpp | 14 +++++++++++++- src/gui/qtgui.tracepoints | 3 +++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index 6d358984d6..0fb1d808e5 100644 --- a/src/gui/image/qimagereader.cpp +++ b/src/gui/image/qimagereader.cpp @@ -165,6 +165,7 @@ #endif #include +#include #include @@ -1250,7 +1251,18 @@ bool QImageReader::read(QImage *image) d->handler->setOption(QImageIOHandler::Quality, d->quality); // read the image - if (!d->handler->read(image)) { + if (Q_TRACE_ENABLED(QImageReader_read_before_reading)) { + QString fileName = QStringLiteral("unknown"); + if (QFile *file = qobject_cast(d->device)) + fileName = file->fileName(); + Q_TRACE(QImageReader_read_before_reading, this, fileName); + } + + const bool result = d->handler->read(image); + + Q_TRACE(QImageReader_read_after_reading, this, result); + + if (!result) { d->imageReaderError = InvalidDataError; d->errorString = QImageReader::tr("Unable to read image data"); return false; diff --git a/src/gui/qtgui.tracepoints b/src/gui/qtgui.tracepoints index 2c232a0af8..aed6c35c03 100644 --- a/src/gui/qtgui.tracepoints +++ b/src/gui/qtgui.tracepoints @@ -8,3 +8,6 @@ QFontDatabase_addApplicationFont(const QString &filename) QFontDatabase_load(const QString &family, int pointSize) QFontDatabase_loadEngine(const QString &family, int pointSize) QFontDatabasePrivate_addAppFont(const QString &fileName) + +QImageReader_read_before_reading(QImageReader *reader, const QString &filename) +QImageReader_read_after_reading(QImageReader *reader, bool result) From 52070f3a6c1bc65b9be9187c856291451d275d64 Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Thu, 9 Aug 2018 10:25:10 +1000 Subject: [PATCH 0024/1650] wasm: fix wasm shader compile This fixes qopenglwindow shader in the triangle Task-number: QTBUG-67338 Change-Id: I8552183bf9ca45e9b56760b340d014ddd34c21f4 Reviewed-by: Laszlo Agocs --- src/gui/opengl/qopenglengineshadermanager.cpp | 12 ++++++++++-- src/gui/opengl/qopengltextureglyphcache.cpp | 10 ++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/gui/opengl/qopenglengineshadermanager.cpp b/src/gui/opengl/qopenglengineshadermanager.cpp index b7bac2728a..1e5a10c99c 100644 --- a/src/gui/opengl/qopenglengineshadermanager.cpp +++ b/src/gui/opengl/qopenglengineshadermanager.cpp @@ -256,9 +256,13 @@ QOpenGLEngineSharedShaders::QOpenGLEngineSharedShaders(QOpenGLContext* context) QByteArray fragSource; // Compile up the simple shader: +#ifdef Q_OS_WASM + vertexSource.append(qShaderSnippets[PositionOnlyVertexShader]); + vertexSource.append(qShaderSnippets[MainVertexShader]); +#else vertexSource.append(qShaderSnippets[MainVertexShader]); vertexSource.append(qShaderSnippets[PositionOnlyVertexShader]); - +#endif fragSource.append(qShaderSnippets[MainFragmentShader]); fragSource.append(qShaderSnippets[ShockingPinkSrcFragmentShader]); @@ -384,9 +388,13 @@ QOpenGLEngineShaderProg *QOpenGLEngineSharedShaders::findProgramInCache(const QO fragSource.append(qShaderSnippets[prog.maskFragShader]); QByteArray vertexSource; +#ifdef Q_OS_WASM + vertexSource.append(qShaderSnippets[prog.positionVertexShader]); + vertexSource.append(qShaderSnippets[prog.mainVertexShader]); +#else vertexSource.append(qShaderSnippets[prog.mainVertexShader]); vertexSource.append(qShaderSnippets[prog.positionVertexShader]); - +#endif QScopedPointer shaderProgram(new QOpenGLShaderProgram); CachedShader shaderCache(fragSource, vertexSource); diff --git a/src/gui/opengl/qopengltextureglyphcache.cpp b/src/gui/opengl/qopengltextureglyphcache.cpp index 556d52ef99..e3cbba955d 100644 --- a/src/gui/opengl/qopengltextureglyphcache.cpp +++ b/src/gui/opengl/qopengltextureglyphcache.cpp @@ -344,15 +344,25 @@ void QOpenGLTextureGlyphCache::resizeTextureData(int width, int height) { QString source; +#ifdef Q_OS_WASM + source.append(QLatin1String(isCoreProfile ? qopenglslUntransformedPositionVertexShader_core : qopenglslUntransformedPositionVertexShader)); + source.append(QLatin1String(isCoreProfile ? qopenglslMainWithTexCoordsVertexShader_core : qopenglslMainWithTexCoordsVertexShader)); +#else source.append(QLatin1String(isCoreProfile ? qopenglslMainWithTexCoordsVertexShader_core : qopenglslMainWithTexCoordsVertexShader)); source.append(QLatin1String(isCoreProfile ? qopenglslUntransformedPositionVertexShader_core : qopenglslUntransformedPositionVertexShader)); +#endif m_blitProgram->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, source); } { QString source; +#ifdef Q_OS_WASM + source.append(QLatin1String(isCoreProfile ? qopenglslImageSrcFragmentShader_core : qopenglslImageSrcFragmentShader)); + source.append(QLatin1String(isCoreProfile ? qopenglslMainFragmentShader_core : qopenglslMainFragmentShader)); +#else source.append(QLatin1String(isCoreProfile ? qopenglslMainFragmentShader_core : qopenglslMainFragmentShader)); source.append(QLatin1String(isCoreProfile ? qopenglslImageSrcFragmentShader_core : qopenglslImageSrcFragmentShader)); +#endif m_blitProgram->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, source); } From 452246871660e17033ec5f0faab59f53273728e2 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Wed, 10 Oct 2018 15:32:43 +0200 Subject: [PATCH 0025/1650] qmake: Add support for CONFIG += c++17 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The correct name is c++1z. Anyhow, this is easy enough to get wrong, so make sure CONFIG += c++17 works as well. Task-number: QTBUG-67527 Change-Id: Iea26b18824b38b1b5170f85987cf5c750b8e10ab Reviewed-by: Oswald Buddenhagen Reviewed-by: Thiago Macieira Reviewed-by: André Hartmann --- mkspecs/features/default_post.prf | 2 ++ qmake/doc/src/qmake-manual.qdoc | 1 + 2 files changed, 3 insertions(+) diff --git a/mkspecs/features/default_post.prf b/mkspecs/features/default_post.prf index ad4a5f6365..fbf1f3b8df 100644 --- a/mkspecs/features/default_post.prf +++ b/mkspecs/features/default_post.prf @@ -113,6 +113,8 @@ breakpad { !isEmpty(QMAKE_STRIP):QMAKE_POST_LINK = $$QMAKE_POST_LINK$$escape_expand(\\n\\t)$$quote($$QMAKE_STRIP $$DEBUGFILENAME) } +c++17: CONFIG += c++1z + !c++11:!c++14:!c++1z { # Qt requires C++11 since 5.7, check if we need to force a compiler option QT_COMPILER_STDCXX_no_L = $$replace(QT_COMPILER_STDCXX, "L$", "") diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index 7fd9dd9623..0ded8b574a 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -973,6 +973,7 @@ \row \li c++1z \li C++17 support is enabled. This option has no effect if the compiler does not support C++17, or can't select the C++ standard. By default, support is disabled. + \row \li c++17 \li Same as c++1z. \row \li strict_c++ \li Disables support for C++ compiler extensions. By default, they are enabled. \row \li depend_includepath \li Appending the value of INCLUDEPATH to From 27f54076cd26f57ef815ba1e11fe25f35c5c7b20 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 30 Aug 2018 11:40:35 +0200 Subject: [PATCH 0026/1650] Automatically pick up dependencies.json file for qmlplugindump The dependencies.json file allows to tweak the list of imports the module is depending on, so that types implicitly imported are not listed twice. Task-number: QTBUG-70264 Change-Id: I7a3800e5ea713a8aaae0cddbf4e1607f92c41497 Reviewed-by: Oswald Buddenhagen Reviewed-by: Shawn Rutledge --- mkspecs/features/qml_plugin.prf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mkspecs/features/qml_plugin.prf b/mkspecs/features/qml_plugin.prf index 0786dbfd84..cd6377dcc6 100644 --- a/mkspecs/features/qml_plugin.prf +++ b/mkspecs/features/qml_plugin.prf @@ -110,6 +110,14 @@ load(qt_common) load(resolve_target) TARGETPATHBASE = $$replace(TARGETPATH, \\.\\d+\$, ) + + !qml1_target { + isEmpty(QMAKE_PLUGINDUMP_DEPENDENCIES_FILE):exists($$_PRO_FILE_PWD_/dependencies.json): \ + QMAKE_PLUGINDUMP_DEPENDENCIES_FILE = $$_PRO_FILE_PWD_/dependencies.json + !isEmpty(QMAKE_PLUGINDUMP_DEPENDENCIES_FILE): \ + QMAKE_QMLPLUGINDUMP_FLAGS += -dependencies $$shell_quote($$QMAKE_PLUGINDUMP_DEPENDENCIES_FILE) + } + qmltypes.target = qmltypes qmltypes.commands = $$QMLPLUGINDUMP -nonrelocatable $$QMAKE_QMLPLUGINDUMP_FLAGS $$replace(TARGETPATHBASE, /, .) $$IMPORT_VERSION > $$QMLTYPEFILE qmltypes.depends = $$QMAKE_RESOLVED_TARGET From 29351315115df46ec2ceec6a853ea40ea6c82246 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 3 Sep 2018 13:13:24 +0200 Subject: [PATCH 0027/1650] Fix attributions for wasm fonts Change-Id: I83251f49f62f502ac2cc21048e9d4e079cee5e99 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/3rdparty/wasm/DEJAVU-LICENSE | 187 ++++++++++++++++++++ src/3rdparty/wasm/{LICENSE => VERA-LICENSE} | 0 src/3rdparty/wasm/qt_attribution.json | 31 +++- 3 files changed, 209 insertions(+), 9 deletions(-) create mode 100644 src/3rdparty/wasm/DEJAVU-LICENSE rename src/3rdparty/wasm/{LICENSE => VERA-LICENSE} (100%) diff --git a/src/3rdparty/wasm/DEJAVU-LICENSE b/src/3rdparty/wasm/DEJAVU-LICENSE new file mode 100644 index 0000000000..df52c1709b --- /dev/null +++ b/src/3rdparty/wasm/DEJAVU-LICENSE @@ -0,0 +1,187 @@ +Fonts are (c) Bitstream (see below). DejaVu changes are in public domain. +Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below) + + +Bitstream Vera Fonts Copyright +------------------------------ + +Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is +a trademark of Bitstream, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of the fonts accompanying this license ("Fonts") and associated +documentation files (the "Font Software"), to reproduce and distribute the +Font Software, including without limitation the rights to use, copy, merge, +publish, distribute, and/or sell copies of the Font Software, and to permit +persons to whom the Font Software is furnished to do so, subject to the +following conditions: + +The above copyright and trademark notices and this permission notice shall +be included in all copies of one or more of the Font Software typefaces. + +The Font Software may be modified, altered, or added to, and in particular +the designs of glyphs or characters in the Fonts may be modified and +additional glyphs or characters may be added to the Fonts, only if the fonts +are renamed to names not containing either the words "Bitstream" or the word +"Vera". + +This License becomes null and void to the extent applicable to Fonts or Font +Software that has been modified and is distributed under the "Bitstream +Vera" names. + +The Font Software may be sold as part of a larger software package but no +copy of one or more of the Font Software typefaces may be sold by itself. + +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, +TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME +FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING +ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE +FONT SOFTWARE. + +Except as contained in this notice, the names of Gnome, the Gnome +Foundation, and Bitstream Inc., shall not be used in advertising or +otherwise to promote the sale, use or other dealings in this Font Software +without prior written authorization from the Gnome Foundation or Bitstream +Inc., respectively. For further information, contact: fonts at gnome dot +org. + +Arev Fonts Copyright +------------------------------ + +Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of the fonts accompanying this license ("Fonts") and +associated documentation files (the "Font Software"), to reproduce +and distribute the modifications to the Bitstream Vera Font Software, +including without limitation the rights to use, copy, merge, publish, +distribute, and/or sell copies of the Font Software, and to permit +persons to whom the Font Software is furnished to do so, subject to +the following conditions: + +The above copyright and trademark notices and this permission notice +shall be included in all copies of one or more of the Font Software +typefaces. + +The Font Software may be modified, altered, or added to, and in +particular the designs of glyphs or characters in the Fonts may be +modified and additional glyphs or characters may be added to the +Fonts, only if the fonts are renamed to names not containing either +the words "Tavmjong Bah" or the word "Arev". + +This License becomes null and void to the extent applicable to Fonts +or Font Software that has been modified and is distributed under the +"Tavmjong Bah Arev" names. + +The Font Software may be sold as part of a larger software package but +no copy of one or more of the Font Software typefaces may be sold by +itself. + +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL +TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +Except as contained in this notice, the name of Tavmjong Bah shall not +be used in advertising or otherwise to promote the sale, use or other +dealings in this Font Software without prior written authorization +from Tavmjong Bah. For further information, contact: tavmjong @ free +. fr. + +TeX Gyre DJV Math +----------------- +Fonts are (c) Bitstream (see below). DejaVu changes are in public domain. + +Math extensions done by B. Jackowski, P. Strzelczyk and P. Pianowski +(on behalf of TeX users groups) are in public domain. + +Letters imported from Euler Fraktur from AMSfonts are (c) American +Mathematical Society (see below). +Bitstream Vera Fonts Copyright +Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera +is a trademark of Bitstream, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of the fonts accompanying this license (“Fonts”) and associated +documentation +files (the “Font Software”), to reproduce and distribute the Font Software, +including without limitation the rights to use, copy, merge, publish, +distribute, +and/or sell copies of the Font Software, and to permit persons to whom +the Font Software is furnished to do so, subject to the following +conditions: + +The above copyright and trademark notices and this permission notice +shall be +included in all copies of one or more of the Font Software typefaces. + +The Font Software may be modified, altered, or added to, and in particular +the designs of glyphs or characters in the Fonts may be modified and +additional +glyphs or characters may be added to the Fonts, only if the fonts are +renamed +to names not containing either the words “Bitstream” or the word “Vera”. + +This License becomes null and void to the extent applicable to Fonts or +Font Software +that has been modified and is distributed under the “Bitstream Vera” +names. + +The Font Software may be sold as part of a larger software package but +no copy +of one or more of the Font Software typefaces may be sold by itself. + +THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, +TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME +FOUNDATION +BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, +SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN +ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR +INABILITY TO USE +THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. +Except as contained in this notice, the names of GNOME, the GNOME +Foundation, +and Bitstream Inc., shall not be used in advertising or otherwise to promote +the sale, use or other dealings in this Font Software without prior written +authorization from the GNOME Foundation or Bitstream Inc., respectively. +For further information, contact: fonts at gnome dot org. + +AMSFonts (v. 2.2) copyright + +The PostScript Type 1 implementation of the AMSFonts produced by and +previously distributed by Blue Sky Research and Y&Y, Inc. are now freely +available for general use. This has been accomplished through the +cooperation +of a consortium of scientific publishers with Blue Sky Research and Y&Y. +Members of this consortium include: + +Elsevier Science IBM Corporation Society for Industrial and Applied +Mathematics (SIAM) Springer-Verlag American Mathematical Society (AMS) + +In order to assure the authenticity of these fonts, copyright will be +held by +the American Mathematical Society. This is not meant to restrict in any way +the legitimate use of the fonts, such as (but not limited to) electronic +distribution of documents containing these fonts, inclusion of these fonts +into other public domain or commercial font collections or computer +applications, use of the outline data to create derivative fonts and/or +faces, etc. However, the AMS does require that the AMS copyright notice be +removed from any derivative versions of the fonts which have been altered in +any way. In addition, to ensure the fidelity of TeX documents using Computer +Modern fonts, Professor Donald Knuth, creator of the Computer Modern faces, +has requested that any alterations which yield different font metrics be +given a different name. + +$Id$ diff --git a/src/3rdparty/wasm/LICENSE b/src/3rdparty/wasm/VERA-LICENSE similarity index 100% rename from src/3rdparty/wasm/LICENSE rename to src/3rdparty/wasm/VERA-LICENSE diff --git a/src/3rdparty/wasm/qt_attribution.json b/src/3rdparty/wasm/qt_attribution.json index 2724008157..5d89e4adfa 100644 --- a/src/3rdparty/wasm/qt_attribution.json +++ b/src/3rdparty/wasm/qt_attribution.json @@ -1,20 +1,33 @@ +[ { "Id": "vera_font", - "Name": "Vera", - "QDocModule": "qtcore", + "Name": "Bitstream Vera Font", + "QDocModule": "qtgui", "QtUsage": "Used for WebAssembly platform.", + "Files": "Vera.ttf", + "Description": "Vera is a group typeface (font) with a liberal license.", - "License": "Bitstream", - "LicenseFile": "LICENSE", + "Homepage": "https://www.gnome.org/fonts/", + "Version": "1.10", + "DownloadLocation": "http://ftp.gnome.org/pub/GNOME/sources/ttf-bitstream-vera/1.10/ttf-bitstream-vera-1.10.tar.bz2", + "License": "Bitstream Vera Font License", + "LicenseId": "bitstream-vera", + "LicenseFile": "VERA-LICENSE", "Copyright": "Copyright (C) 2003 Bitstream,Inc" }, { "Id": "dejayvu", - "Name": "DejaVuSans", - "QDocModule": "qtcore", + "Name": "DejaVu Fonts", + "QDocModule": "qtgui", "QtUsage": "Used for WebAssembly platform.", + "Files": "DejaVuSans.ttf", + "Description": "The DejaVu fonts are a font family based on the Vera Fonts.", - "License": "Bitstream", - "LicenseFile": "LICENSE", - "Copyright": "Copyright (C) 2003 Bitstream,Inc" + "Homepage": "https://dejavu-fonts.github.io/", + "License": "Bitstream Vera Font License", + "LicenseFile": "DEJAVU-LICENSE", + "Copyright": "Copyright (C) 2003 Bitstream,Inc +Copyright (c) 2006 by Tavmjong Bah +(c) American Mathematical Society" } +] \ No newline at end of file From 0479379d2463ff44c54e774d41746fb1500cf481 Mon Sep 17 00:00:00 2001 From: Andre Hartmann Date: Tue, 9 Oct 2018 21:59:59 +0200 Subject: [PATCH 0028/1650] Fix docs for QStandardPaths::DesktopLocation Was broken by 1afe110b8fe6da51ec23736fa3a105013255f904 Change-Id: I63e000c663d227f8527ad5162c7662c5c011cf72 Reviewed-by: Thiago Macieira --- src/corelib/io/qstandardpaths.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp index b3a5bd797a..dbf650d5f6 100644 --- a/src/corelib/io/qstandardpaths.cpp +++ b/src/corelib/io/qstandardpaths.cpp @@ -94,7 +94,8 @@ QT_BEGIN_NAMESPACE Data interchange with other users is out of the scope of QStandardPaths. \value DesktopLocation Returns the user's desktop directory. This is a generic value. - On systems with no concept of a desktop. + On systems with no concept of a desktop, this is the same as + QStandardPaths::HomeLocation. \value DocumentsLocation Returns the directory containing user document files. This is a generic value. The returned path is never empty. \value FontsLocation Returns the directory containing user's fonts. This is a generic value. From f2f040ae1c4fe48bff68bb45b2e20308fa895c50 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Tue, 2 Oct 2018 12:36:04 +0200 Subject: [PATCH 0029/1650] Improve support for QImages in QDataStream read transactions QImage's operator>>(QDataStream&) did not set an error mode on the stream on read failures. That would break QDataStream transactions. Since the current QImage serialization cannot differentiate between truncated and corrupted data, we set the ReadPastEnd error as expected by the transaction system. Also specify the expected file format on decoding QImage from stream, to avoid all the format handlers' canRead() being invoked. This is necessary since some of them may call ungetChar(), which fails when the stream is in a transaction. Also add testing of this feature to the QDataStram transaction autotest. That required a slight rewrite of the fake sequential QIODevice subclass. The previous implementation had incorrect behavior of peek(), which is required by QImage decoders. Task-number: QTBUG-70875 Change-Id: If3f1ca7186ad1e6ca0e6e8ea81d2b2fbece6ea01 Reviewed-by: Alex Trotsenko Reviewed-by: Thiago Macieira --- src/gui/image/qimage.cpp | 4 +- .../qdatastream/tst_qdatastream.cpp | 41 +++++++++++-------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 636cacfb9c..421362dd9e 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -3750,7 +3750,9 @@ QDataStream &operator>>(QDataStream &s, QImage &image) return s; } } - image = QImageReader(s.device(), 0).read(); + image = QImageReader(s.device(), s.version() == 1 ? "bmp" : "png").read(); + if (image.isNull() && s.version() >= 5) + s.setStatus(QDataStream::ReadPastEnd); return s; } #endif // QT_NO_DATASTREAM diff --git a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp index c6faf8c7d5..011a0e1a85 100644 --- a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp +++ b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp @@ -2211,25 +2211,22 @@ void tst_QDataStream::setVersion() } } -class SequentialBuffer : public QBuffer +class SequentialBuffer : public QIODevice { public: - SequentialBuffer(QByteArray *data) : QBuffer(data) { offset = 0; } + SequentialBuffer(QByteArray *data) : QIODevice() { buf.setBuffer(data); } - bool isSequential() const { return true; } - bool seek(qint64 pos) { offset = pos; return QBuffer::seek(pos); } - qint64 pos() const { return qint64(offset); } + bool isSequential() const override { return true; } + bool open(OpenMode mode) override { return buf.open(mode) && QIODevice::open(mode | QIODevice::Unbuffered); } + void close() override { buf.close(); QIODevice::close(); } + qint64 bytesAvailable() const override { return QIODevice::bytesAvailable() + buf.bytesAvailable(); } protected: - qint64 readData(char *data, qint64 maxSize) - { - qint64 ret = QBuffer::readData(data, maxSize); - offset += ret; - return ret; - } + qint64 readData(char *data, qint64 maxSize) override { return buf.read(data, maxSize); } + qint64 writeData(const char *data, qint64 maxSize) override { return buf.write(data, maxSize); } private: - int offset; + QBuffer buf; }; void tst_QDataStream::skipRawData_data() @@ -3329,15 +3326,21 @@ void tst_QDataStream::transaction_data() QTest::addColumn("bData"); QTest::addColumn("fData"); QTest::addColumn("dData"); + QTest::addColumn("imgData"); QTest::addColumn("strData"); QTest::addColumn("rawData"); + QImage img1(open_xpm); + QImage img2; + QImage img3(50, 50, QImage::Format_ARGB32); + img3.fill(qRgba(12, 34, 56, 78)); + QTest::newRow("1") << qint8(1) << qint16(2) << qint32(3) << qint64(4) << true << 5.0f - << double(6.0) << QByteArray("Hello world!") << QByteArray("Qt rocks!"); + << double(6.0) << img1 << QByteArray("Hello world!") << QByteArray("Qt rocks!"); QTest::newRow("2") << qint8(1 << 6) << qint16(1 << 14) << qint32(1 << 30) << qint64Data(3) << false << 123.0f - << double(234.0) << stringData(5).toUtf8() << stringData(6).toUtf8(); + << double(234.0) << img2 << stringData(5).toUtf8() << stringData(6).toUtf8(); QTest::newRow("3") << qint8(-1) << qint16(-2) << qint32(-3) << qint64(-4) << true << -123.0f - << double(-234.0) << stringData(3).toUtf8() << stringData(4).toUtf8(); + << double(-234.0) << img3 << stringData(3).toUtf8() << stringData(4).toUtf8(); } void tst_QDataStream::transaction() @@ -3351,6 +3354,7 @@ void tst_QDataStream::transaction() QFETCH(bool, bData); QFETCH(float, fData); QFETCH(double, dData); + QFETCH(QImage, imgData); QFETCH(QByteArray, strData); QFETCH(QByteArray, rawData); @@ -3358,12 +3362,13 @@ void tst_QDataStream::transaction() QDataStream stream(&testBuffer, QIODevice::WriteOnly); stream << i8Data << i16Data << i32Data << i64Data - << bData << fData << dData << strData.constData(); + << bData << fData << dData << imgData << strData.constData(); stream.writeRawData(rawData.constData(), rawData.size()); } for (int splitPos = 0; splitPos <= testBuffer.size(); ++splitPos) { QByteArray readBuffer(testBuffer.left(splitPos)); + SequentialBuffer dev(&readBuffer); dev.open(QIODevice::ReadOnly); QDataStream stream(&dev); @@ -3375,12 +3380,13 @@ void tst_QDataStream::transaction() bool b; float f; double d; + QImage img; char *str; QByteArray raw(rawData.size(), 0); forever { stream.startTransaction(); - stream >> i8 >> i16 >> i32 >> i64 >> b >> f >> d >> str; + stream >> i8 >> i16 >> i32 >> i64 >> b >> f >> d >> img >> str; stream.readRawData(raw.data(), raw.size()); if (stream.commitTransaction()) @@ -3402,6 +3408,7 @@ void tst_QDataStream::transaction() QCOMPARE(b, bData); QCOMPARE(f, fData); QCOMPARE(d, dData); + QCOMPARE(img, imgData); QVERIFY(strData == str); delete [] str; QCOMPARE(raw, rawData); From 02a214442781bf112c1cc85d2470c6fcec8ed207 Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Wed, 10 Oct 2018 12:36:17 +0200 Subject: [PATCH 0030/1650] QToolTip: Don't crash if a tool tip is shown outside screen geometry In some cases, a tool tip may be shown outside screen geometry, i.e. if: - QToolTip::showText is invoked manually with a position outside. - In tst_QToolTip::setPalette if there is no screen at (0, 0). This might happen in a multi-monitor setups where one screen is taller than the other. - On Wayland windows are (by design) not allowed to know their position on the screen. This means that global positions can't be trusted. This started crashing when QDesktopWidget::screenGeometry(pos) was replaced with QGuiApplication::screenAt(pos)->geometry() because screenAt will return null if no screen is found, while screenGeometry defaulted to the primary screen. This reverts to the old behavior of falling back to the primary screen. This won't solve the issue completely for the Wayland case, but at least we will stop crashing. Change-Id: I42dd07cc21c2f9f0ea0d69f0c25bd46d8a2615a0 Reviewed-by: Filipe Azevedo Reviewed-by: Christian Ehrlicher Reviewed-by: Richard Moe Gustavsen --- src/widgets/kernel/qtooltip.cpp | 17 +++++++++++------ .../widgets/kernel/qtooltip/tst_qtooltip.cpp | 7 +++++++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp index 8c5573d3a3..2e6575c163 100644 --- a/src/widgets/kernel/qtooltip.cpp +++ b/src/widgets/kernel/qtooltip.cpp @@ -229,12 +229,17 @@ void QTipLabel::updateSize(const QPoint &pos) ++extra.rheight(); QSize sh = sizeHint(); if (wordWrap()) { - const QRect screenRect = QGuiApplication::screenAt(pos)->geometry(); - if (sh.width() > screenRect.width()) { - // Try to use widely accepted 75chars max length or 80% of the screen width else. - // See https://en.wikipedia.org/wiki/Line_length - sh.setWidth(qMin(fm.averageCharWidth() * 75, static_cast(screenRect.width() * .8))); - sh.setHeight(heightForWidth(sh.width())); + QScreen *screen = QGuiApplication::screenAt(pos); + if (!screen) + screen = QGuiApplication::primaryScreen(); + if (screen) { + const qreal screenWidth = screen->geometry().width(); + if (sh.width() > screenWidth) { + // Try to use widely accepted 75chars max length or 80% of the screen width else. + // See https://en.wikipedia.org/wiki/Line_length + sh.setWidth(qMin(fm.averageCharWidth() * 75, static_cast(screenWidth * .8))); + sh.setHeight(heightForWidth(sh.width())); + } } } resize(sh + extra); diff --git a/tests/auto/widgets/kernel/qtooltip/tst_qtooltip.cpp b/tests/auto/widgets/kernel/qtooltip/tst_qtooltip.cpp index e02573f8e8..3d609d0b9c 100644 --- a/tests/auto/widgets/kernel/qtooltip/tst_qtooltip.cpp +++ b/tests/auto/widgets/kernel/qtooltip/tst_qtooltip.cpp @@ -46,6 +46,7 @@ private slots: void whatsThis(); void setPalette(); void qtbug64550_stylesheet(); + void dontCrashOutsideScreenGeometry(); }; void tst_QToolTip::init() @@ -218,5 +219,11 @@ void tst_QToolTip::qtbug64550_stylesheet() msgSizeTooSmall(toolTipSize, boundingRect.size()).constData()); } +void tst_QToolTip::dontCrashOutsideScreenGeometry() { + QToolTip::showText(QPoint(-10000, -10000), "tip outside monitor", nullptr); + QTRY_VERIFY(QToolTip::isVisible()); + QToolTip::hideText(); +} + QTEST_MAIN(tst_QToolTip) #include "tst_qtooltip.moc" From 1f6bfc220774e9407fe88916843b76ed103cff72 Mon Sep 17 00:00:00 2001 From: Cristian Maureira-Fredes Date: Mon, 3 Sep 2018 14:02:13 +0200 Subject: [PATCH 0031/1650] Doc: Move literal code block to a separate file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to override this snippet for the documentation we generate for Qt for Python, and it is easier to have it on a separate file. Task-number: PYSIDE-801 Task-number: PYSIDE-691 Change-Id: Ideb5b6af25024279f167137d3b65660bb9c96a7e Reviewed-by: Topi Reiniö --- .../animation/qparallelanimationgroup.cpp | 8 +- src/corelib/animation/qpropertyanimation.cpp | 9 +- .../animation/qsequentialanimationgroup.cpp | 9 +- src/corelib/animation/qvariantanimation.cpp | 14 +- ...elib_animation_qparallelanimationgroup.cpp | 46 +++ ...c_corelib_animation_qpropertyanimation.cpp | 48 +++ ...ib_animation_qsequentialanimationgroup.cpp | 47 +++ ...rc_corelib_animation_qvariantanimation.cpp | 52 +++ .../code/src_corelib_global_qglobal.cpp | 61 +++ .../code/src_corelib_global_qlogging.cpp | 42 +++ .../code/src_corelib_global_qnumeric.cpp | 45 +++ ...corelib_global_qoperatingsystemversion.cpp | 50 +++ .../code/src_corelib_global_qrandom.cpp | 120 ++++++ .../snippets/code/src_corelib_io_qdebug.cpp | 84 +++++ .../code/src_corelib_io_qfileselector.cpp | 82 +++++ .../code/src_corelib_io_qloggingcategory.cpp | 57 +++ .../code/src_corelib_io_qtemporaryfile.cpp | 8 + .../doc/snippets/code/src_corelib_io_qurl.cpp | 86 +++++ .../code/src_corelib_io_qurlquery.cpp | 43 +++ .../src_corelib_kernel_qdeadlinetimer.cpp | 123 +++++++ .../code/src_corelib_kernel_qmetaobject.cpp | 19 + .../code/src_corelib_kernel_qobject.cpp | 13 + .../src_corelib_kernel_qtestsupport_core.cpp | 52 +++ .../src_corelib_mimetype_qmimedatabase.cpp | 15 + .../src_corelib_serialization_qcborstream.cpp | 347 ++++++++++++++++++ .../src_corelib_serialization_qcborvalue.cpp | 69 ++++ .../src_corelib_serialization_qdatastream.cpp | 48 +++ ...rc_corelib_serialization_qjsondocument.cpp | 54 +++ .../code/src_corelib_thread_qsemaphore.cpp | 29 ++ .../code/src_corelib_tools_qbytearray.cpp | 27 ++ .../src_corelib_tools_qbytearraymatcher.cpp | 46 +++ .../src_corelib_tools_qcontiguouscache.cpp | 59 +++ .../snippets/code/src_corelib_tools_qhash.cpp | 20 + .../snippets/code/src_corelib_tools_qrect.cpp | 10 + .../src_corelib_tools_qregularexpression.cpp | 8 + .../code/src_corelib_tools_qshareddata.cpp | 55 +++ .../code/src_corelib_tools_qsharedpointer.cpp | 146 ++++++++ .../code/src_corelib_tools_qstring.cpp | 18 + .../code/src_corelib_tools_qstringview.cpp | 51 +++ src/corelib/global/qglobal.cpp | 61 +-- src/corelib/global/qlogging.cpp | 4 +- src/corelib/global/qnumeric.cpp | 7 +- .../global/qoperatingsystemversion.cpp | 12 +- src/corelib/global/qrandom.cpp | 81 +--- src/corelib/io/qdebug.cpp | 46 +-- src/corelib/io/qfileselector.cpp | 44 +-- src/corelib/io/qloggingcategory.cpp | 19 +- src/corelib/io/qtemporaryfile.cpp | 8 +- src/corelib/io/qurl.cpp | 86 +---- src/corelib/io/qurlquery.cpp | 10 +- src/corelib/kernel/qdeadlinetimer.cpp | 85 +---- src/corelib/kernel/qmetaobject.cpp | 20 +- src/corelib/kernel/qobject.cpp | 13 +- src/corelib/kernel/qtestsupport_core.cpp | 14 +- src/corelib/mimetypes/qmimedatabase.cpp | 15 +- src/corelib/serialization/qcborstream.cpp | 309 ++-------------- src/corelib/serialization/qcborvalue.cpp | 31 +- src/corelib/serialization/qdatastream.cpp | 10 +- src/corelib/serialization/qjsondocument.cpp | 16 +- src/corelib/thread/qsemaphore.cpp | 29 +- src/corelib/tools/qbytearray.cpp | 27 +- src/corelib/tools/qbytearraymatcher.cpp | 8 +- src/corelib/tools/qcontiguouscache.cpp | 21 +- src/corelib/tools/qhash.cpp | 28 +- src/corelib/tools/qrect.cpp | 10 +- src/corelib/tools/qregularexpression.cpp | 8 +- src/corelib/tools/qshareddata.cpp | 17 +- src/corelib/tools/qsharedpointer.cpp | 108 +----- src/corelib/tools/qstring.cpp | 18 +- src/corelib/tools/qstringview.cpp | 13 +- src/gui/accessible/qaccessible.cpp | 18 +- .../code/src_gui_accessible_qaccessible.cpp | 18 + .../code/src_gui_math3d_qquaternion.cpp | 46 +++ .../code/src_gui_opengl_qopenglbuffer.cpp | 49 +++ .../code/src_gui_opengl_qopengldebug.cpp | 89 +++++ .../code/src_gui_opengl_qopenglfunctions.cpp | 101 +++++ .../code/src_gui_util_qdesktopservices.cpp | 28 ++ .../code/src_gui_vulkan_qvulkanfunctions.cpp | 59 +++ .../code/src_gui_vulkan_qvulkaninstance.cpp | 135 +++++++ .../code/src_gui_vulkan_qvulkanwindow.cpp | 121 ++++++ src/gui/math3d/qquaternion.cpp | 8 +- src/gui/opengl/qopenglbuffer.cpp | 11 +- src/gui/opengl/qopengldebug.cpp | 65 +--- src/gui/opengl/qopenglfunctions.cpp | 63 +--- src/gui/util/qdesktopservices.cpp | 28 +- src/gui/vulkan/qvulkanfunctions.cpp | 21 +- src/gui/vulkan/qvulkaninstance.cpp | 97 +---- src/gui/vulkan/qvulkanwindow.cpp | 83 +---- src/network/bearer/qnetworksession.cpp | 21 +- .../src_network_bearer_qnetworksession.cpp | 60 +++ .../src_network_kernel_qnetworkdatagram.cpp | 64 ++++ .../src_network_kernel_qnetworkinterface.cpp | 46 +++ ...work_ssl_qsslpresharedkeyauthenticator.cpp | 53 +++ src/network/kernel/qnetworkdatagram.cpp | 15 +- src/network/kernel/qnetworkinterface.cpp | 8 +- .../ssl/qsslpresharedkeyauthenticator.cpp | 19 +- .../snippets/code/src_opengl_qglbuffer.cpp | 49 +++ .../snippets/code/src_opengl_qglfunctions.cpp | 75 ++++ .../code/src_opengl_qgraphicsshadereffect.cpp | 84 +++++ src/opengl/qglbuffer.cpp | 11 +- src/opengl/qglfunctions.cpp | 37 +- src/opengl/qgraphicsshadereffect.cpp | 46 +-- .../src_plugins_platforms_qnx_qqnxwindow.cpp | 52 +++ src/plugins/platforms/qnx/qqnxwindow.cpp | 14 +- src/widgets/dialogs/qfiledialog.cpp | 12 +- .../code/src_gui_dialogs_qfiledialog.cpp | 4 + .../src_gui_graphicsview_qgraphicsitem.cpp | 15 + .../code/src_gui_kernel_qformlayout.cpp | 48 +++ .../code/src_widgets_util_qscroller.cpp | 49 +++ .../code/src_widgets_widgets_qmainwindow.cpp | 58 +++ src/widgets/graphicsview/qgraphicsitem.cpp | 16 +- src/widgets/kernel/qformlayout.cpp | 48 +-- src/widgets/util/qscroller.cpp | 11 +- src/widgets/widgets/qmainwindow.cpp | 21 +- 114 files changed, 3627 insertions(+), 1647 deletions(-) create mode 100644 src/corelib/doc/snippets/code/src_corelib_animation_qparallelanimationgroup.cpp create mode 100644 src/corelib/doc/snippets/code/src_corelib_animation_qpropertyanimation.cpp create mode 100644 src/corelib/doc/snippets/code/src_corelib_animation_qsequentialanimationgroup.cpp create mode 100644 src/corelib/doc/snippets/code/src_corelib_animation_qvariantanimation.cpp create mode 100644 src/corelib/doc/snippets/code/src_corelib_global_qlogging.cpp create mode 100644 src/corelib/doc/snippets/code/src_corelib_global_qnumeric.cpp create mode 100644 src/corelib/doc/snippets/code/src_corelib_global_qoperatingsystemversion.cpp create mode 100644 src/corelib/doc/snippets/code/src_corelib_global_qrandom.cpp create mode 100644 src/corelib/doc/snippets/code/src_corelib_io_qdebug.cpp create mode 100644 src/corelib/doc/snippets/code/src_corelib_io_qfileselector.cpp create mode 100644 src/corelib/doc/snippets/code/src_corelib_io_qloggingcategory.cpp create mode 100644 src/corelib/doc/snippets/code/src_corelib_io_qurlquery.cpp create mode 100644 src/corelib/doc/snippets/code/src_corelib_kernel_qdeadlinetimer.cpp create mode 100644 src/corelib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp create mode 100644 src/corelib/doc/snippets/code/src_corelib_serialization_qcborstream.cpp create mode 100644 src/corelib/doc/snippets/code/src_corelib_serialization_qcborvalue.cpp create mode 100644 src/corelib/doc/snippets/code/src_corelib_serialization_qdatastream.cpp create mode 100644 src/corelib/doc/snippets/code/src_corelib_serialization_qjsondocument.cpp create mode 100644 src/corelib/doc/snippets/code/src_corelib_tools_qbytearraymatcher.cpp create mode 100644 src/corelib/doc/snippets/code/src_corelib_tools_qcontiguouscache.cpp create mode 100644 src/corelib/doc/snippets/code/src_corelib_tools_qshareddata.cpp create mode 100644 src/corelib/doc/snippets/code/src_corelib_tools_qsharedpointer.cpp create mode 100644 src/corelib/doc/snippets/code/src_corelib_tools_qstringview.cpp create mode 100644 src/gui/doc/snippets/code/src_gui_math3d_qquaternion.cpp create mode 100644 src/gui/doc/snippets/code/src_gui_opengl_qopenglbuffer.cpp create mode 100644 src/gui/doc/snippets/code/src_gui_opengl_qopengldebug.cpp create mode 100644 src/gui/doc/snippets/code/src_gui_opengl_qopenglfunctions.cpp create mode 100644 src/gui/doc/snippets/code/src_gui_vulkan_qvulkanfunctions.cpp create mode 100644 src/gui/doc/snippets/code/src_gui_vulkan_qvulkaninstance.cpp create mode 100644 src/gui/doc/snippets/code/src_gui_vulkan_qvulkanwindow.cpp create mode 100644 src/network/doc/snippets/code/src_network_bearer_qnetworksession.cpp create mode 100644 src/network/doc/snippets/code/src_network_kernel_qnetworkdatagram.cpp create mode 100644 src/network/doc/snippets/code/src_network_kernel_qnetworkinterface.cpp create mode 100644 src/network/doc/snippets/code/src_network_ssl_qsslpresharedkeyauthenticator.cpp create mode 100644 src/opengl/doc/snippets/code/src_opengl_qglbuffer.cpp create mode 100644 src/opengl/doc/snippets/code/src_opengl_qglfunctions.cpp create mode 100644 src/opengl/doc/snippets/code/src_opengl_qgraphicsshadereffect.cpp create mode 100644 src/plugins/doc/snippets/code/src_plugins_platforms_qnx_qqnxwindow.cpp create mode 100644 src/widgets/doc/snippets/code/src_widgets_util_qscroller.cpp create mode 100644 src/widgets/doc/snippets/code/src_widgets_widgets_qmainwindow.cpp diff --git a/src/corelib/animation/qparallelanimationgroup.cpp b/src/corelib/animation/qparallelanimationgroup.cpp index e4dfc1bd6e..f3184d6e54 100644 --- a/src/corelib/animation/qparallelanimationgroup.cpp +++ b/src/corelib/animation/qparallelanimationgroup.cpp @@ -53,13 +53,7 @@ You can treat QParallelAnimationGroup as any other QAbstractAnimation, e.g., pause, resume, or add it to other animation groups. - \code - QParallelAnimationGroup *group = new QParallelAnimationGroup; - group->addAnimation(anim1); - group->addAnimation(anim2); - - group->start(); - \endcode + \snippet code/src_corelib_animation_qparallelanimationgroup.cpp 0 In this example, \c anim1 and \c anim2 are two \l{QPropertyAnimation}s that have already been set up. diff --git a/src/corelib/animation/qpropertyanimation.cpp b/src/corelib/animation/qpropertyanimation.cpp index 5ba2a1fa73..f616dc71f8 100644 --- a/src/corelib/animation/qpropertyanimation.cpp +++ b/src/corelib/animation/qpropertyanimation.cpp @@ -56,14 +56,7 @@ makes it possible to animate many of Qt's widgets. Let's look at an example: - \code - QPropertyAnimation *animation = new QPropertyAnimation(myWidget, "geometry"); - animation->setDuration(10000); - animation->setStartValue(QRect(0, 0, 100, 30)); - animation->setEndValue(QRect(250, 250, 100, 30)); - - animation->start(); - \endcode + \snippet code/src_corelib_animation_qpropertyanimation.cpp 0 The property name and the QObject instance of which property should be animated are passed to the constructor. You can then diff --git a/src/corelib/animation/qsequentialanimationgroup.cpp b/src/corelib/animation/qsequentialanimationgroup.cpp index f5f538337e..23725ae415 100644 --- a/src/corelib/animation/qsequentialanimationgroup.cpp +++ b/src/corelib/animation/qsequentialanimationgroup.cpp @@ -61,14 +61,7 @@ groups. You can also call addPause() or insertPause() to add a pause to a sequential animation group. - \code - QSequentialAnimationGroup *group = new QSequentialAnimationGroup; - - group->addAnimation(anim1); - group->addAnimation(anim2); - - group->start(); - \endcode + \snippet code/src_corelib_animation_qsequentialanimationgroup.cpp 0 In this example, \c anim1 and \c anim2 are two already set up \l{QPropertyAnimation}s. diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp index 3c90d71c7d..8711ec8a31 100644 --- a/src/corelib/animation/qvariantanimation.cpp +++ b/src/corelib/animation/qvariantanimation.cpp @@ -118,15 +118,7 @@ QT_BEGIN_NAMESPACE and the current progress. Example: - \code - QVariant myColorInterpolator(const QColor &start, const QColor &end, qreal progress) - { - ... - return QColor(...); - } - ... - qRegisterAnimationInterpolator(myColorInterpolator); - \endcode + \snippet code/src_corelib_animation_qvariantanimation.cpp 0 Another option is to reimplement interpolated(), which returns interpolation values for the value being interpolated. @@ -418,9 +410,7 @@ static QBasicMutex registeredInterpolatorsMutex; This is a typedef for a pointer to a function with the following signature: - \code - QVariant myInterpolator(const QVariant &from, const QVariant &to, qreal progress); - \endcode + \snippet code/src_corelib_animation_qvariantanimation.cpp 1 */ diff --git a/src/corelib/doc/snippets/code/src_corelib_animation_qparallelanimationgroup.cpp b/src/corelib/doc/snippets/code/src_corelib_animation_qparallelanimationgroup.cpp new file mode 100644 index 0000000000..3fc53bc58b --- /dev/null +++ b/src/corelib/doc/snippets/code/src_corelib_animation_qparallelanimationgroup.cpp @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QParallelAnimationGroup *group = new QParallelAnimationGroup; + group->addAnimation(anim1); + group->addAnimation(anim2); + + group->start(); +//! [0] diff --git a/src/corelib/doc/snippets/code/src_corelib_animation_qpropertyanimation.cpp b/src/corelib/doc/snippets/code/src_corelib_animation_qpropertyanimation.cpp new file mode 100644 index 0000000000..a6dbd909d7 --- /dev/null +++ b/src/corelib/doc/snippets/code/src_corelib_animation_qpropertyanimation.cpp @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +//! [0] + QPropertyAnimation *animation = new QPropertyAnimation(myWidget, "geometry"); + animation->setDuration(10000); + animation->setStartValue(QRect(0, 0, 100, 30)); + animation->setEndValue(QRect(250, 250, 100, 30)); + + animation->start(); +//! [0] diff --git a/src/corelib/doc/snippets/code/src_corelib_animation_qsequentialanimationgroup.cpp b/src/corelib/doc/snippets/code/src_corelib_animation_qsequentialanimationgroup.cpp new file mode 100644 index 0000000000..1f1363f127 --- /dev/null +++ b/src/corelib/doc/snippets/code/src_corelib_animation_qsequentialanimationgroup.cpp @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QSequentialAnimationGroup *group = new QSequentialAnimationGroup; + + group->addAnimation(anim1); + group->addAnimation(anim2); + + group->start(); +//! [0] diff --git a/src/corelib/doc/snippets/code/src_corelib_animation_qvariantanimation.cpp b/src/corelib/doc/snippets/code/src_corelib_animation_qvariantanimation.cpp new file mode 100644 index 0000000000..b462ff2d6a --- /dev/null +++ b/src/corelib/doc/snippets/code/src_corelib_animation_qvariantanimation.cpp @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QVariant myColorInterpolator(const QColor &start, const QColor &end, qreal progress) + { + ... + return QColor(...); + } + ... + qRegisterAnimationInterpolator(myColorInterpolator); +//! [0] + +//! [1] + QVariant myInterpolator(const QVariant &from, const QVariant &to, qreal progress); +//! [1] diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp index 9d029e5d4d..c73e782b76 100644 --- a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp @@ -725,3 +725,64 @@ bool readConfiguration(const QFile &file) #include #endif //! [qt-version-check] + +//! [is-empty] + qgetenv(varName).isEmpty() +//! [is-empty] + +//! [to-int] + qgetenv(varName).toInt(ok, 0) +//! [to-int] + +//! [is-null] + !qgetenv(varName).isNull() +//! [is-null] + +//! [as-const-0] + QString s = ...; + for (QChar ch : s) // detaches 's' (performs a deep-copy if 's' was shared) + process(ch); + for (QChar ch : qAsConst(s)) // ok, no detach attempt + process(ch); +//! [as-const-0] + +//! [as-const-1] + const QString s = ...; + for (QChar ch : s) // ok, no detach attempt on const objects + process(ch); +//! [as-const-1] + +//! [as-const-2] + for (QChar ch : funcReturningQString()) + process(ch); // OK, the returned object is kept alive for the loop's duration +//! [as-const-2] + +//! [as-const-3] + for (QChar ch : qAsConst(funcReturningQString())) + process(ch); // ERROR: ch is copied from deleted memory +//! [as-const-3] + +//! [as-const-4] + for (QChar ch : qAsConst(funcReturningQString())) + process(ch); // ERROR: ch is copied from deleted memory +//! [as-const-4] + +//! [qterminate] + try { expr; } catch(...) { qTerminate(); } +//! [qterminate] + +//! [qdecloverride] + // generate error if this doesn't actually override anything: + virtual void MyWidget::paintEvent(QPaintEvent*) Q_DECL_OVERRIDE; +//! [qdecloverride] + +//! [qdeclfinal-1] + // more-derived classes no longer permitted to override this: + virtual void MyWidget::paintEvent(QPaintEvent*) Q_DECL_FINAL; +//! [qdeclfinal-1] + +//! [qdeclfinal-2] + class QRect Q_DECL_FINAL { // cannot be derived from + // ... + }; +//! [qdeclfinal-2] diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qlogging.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qlogging.cpp new file mode 100644 index 0000000000..7b0b357cff --- /dev/null +++ b/src/corelib/doc/snippets/code/src_corelib_global_qlogging.cpp @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QT_MESSAGE_PATTERN="[%{time yyyyMMdd h:mm:ss.zzz t} %{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{file}:%{line} - %{message}" +//! [0] diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qnumeric.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qnumeric.cpp new file mode 100644 index 0000000000..5d64070b1b --- /dev/null +++ b/src/corelib/doc/snippets/code/src_corelib_global_qnumeric.cpp @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + if (qFloatDistance(a, b) < (1 << 7)) { // The last 7 bits are not + // significant + // precise enough + } +//! [0] diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qoperatingsystemversion.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qoperatingsystemversion.cpp new file mode 100644 index 0000000000..d9e927c55a --- /dev/null +++ b/src/corelib/doc/snippets/code/src_corelib_global_qoperatingsystemversion.cpp @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QOperatingSystemVersion::current() >= QOperatingSystemVersion(QOperatingSystemVersion::IOS, 9) +//! [0] + +//! [1] + auto current = QOperatingSystemVersion::current(); + if (current >= QOperatingSystemVersion::OSXYosemite || + current >= QOperatingSystemVersion(QOperatingSystemVersion::IOS, 8)) { + // returns true on macOS >= 10.10 and iOS >= 8.0, but false on macOS < 10.10 and iOS < 8.0 + } +//! [1] diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qrandom.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qrandom.cpp new file mode 100644 index 0000000000..b03e656b64 --- /dev/null +++ b/src/corelib/doc/snippets/code/src_corelib_global_qrandom.cpp @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2018 Intel Corporation. +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + quint32 value = QRandomGenerator::global()->generate(); +//! [0] + +//! [1] + QRandomGenerator prng1(1234), prng2(1234); + Q_ASSERT(prng1.generate() == prng2.generate()); + Q_ASSERT(prng1.generate64() == prng2.generate64()); +//! [1] + +//! [2] + int x = QRandomGenerator::global()->generate(); + int y = QRandomGenerator::global()->generate(); + int w = QRandomGenerator::global()->bounded(16384); + int h = QRandomGenerator::global()->bounded(16384); +//! [2] + +//! [3] + std::uniform_real_distribution dist(1, 2.5); + return dist(*QRandomGenerator::global()); +//! [3] + +//! [4] + std::seed_seq sseq(seedBuffer, seedBuffer + len); + QRandomGenerator generator(sseq); +//! [4] + +//! [5] + std::seed_seq sseq(begin, end); + QRandomGenerator generator(sseq); +//! [5] + +//! [6] + while (z--) + generator.generate(); +//! [6] + +//! [7] + std::generate(begin, end, [this]() { return generate(); }); +//! [7] + +//! [8] + std::generate(begin, end, []() { return QRandomGenerator::global()->generate64(); }); +//! [8] + +//! [9] + QVector vector; + vector.resize(16); + QRandomGenerator::fillRange(vector.data(), vector.size()); +//! [9] + +//! [10] + quint32 array[2]; + QRandomGenerator::fillRange(array); +//! [10] + +//! [11] + QRandomGenerator64 rd; + return std::generate_canonical::digits>(rd); +//! [11] + +//! [12] + return generateDouble() * highest; +//! [12] + +//! [13] + quint32 v = QRandomGenerator::bounded(256); +//! [13] + +//! [14] + quint32 v = QRandomGenerator::bounded(1000, 2000); +//! [14] + +//! [15] + return QColor::fromRgb(QRandomGenerator::global()->generate()); +//! [15] + +//! [16] + qint64 value = QRandomGenerator64::generate() & std::numeric_limits::max(); +//! [16] diff --git a/src/corelib/doc/snippets/code/src_corelib_io_qdebug.cpp b/src/corelib/doc/snippets/code/src_corelib_io_qdebug.cpp new file mode 100644 index 0000000000..4bbdc509ca --- /dev/null +++ b/src/corelib/doc/snippets/code/src_corelib_io_qdebug.cpp @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QString s; + + s = "a"; + qDebug().noquote() << s; // prints: a + qDebug() << s; // prints: "a" + + s = "\"a\r\n\""; + qDebug() << s; // prints: "\"a\r\n\"" + + s = "\033"; // escape character + qDebug() << s; // prints: "\u001B" + + s = "\u00AD"; // SOFT HYPHEN + qDebug() << s; // prints: "\u00AD" + + s = "\u00E1"; // LATIN SMALL LETTER A WITH ACUTE + qDebug() << s; // prints: "á" + + s = "a\u0301"; // "a" followed by COMBINING ACUTE ACCENT + qDebug() << s; // prints: "á"; + + s = "\u0430\u0301"; // CYRILLIC SMALL LETTER A followed by COMBINING ACUTE ACCENT + qDebug() << s; // prints: "а́" +//! [0] + +//! [1] + QByteArray ba; + + ba = "a"; + qDebug().noquote() << ba; // prints: a + qDebug() << ba; // prints: "a" + + ba = "\"a\r\n\""; + qDebug() << ba; // prints: "\"a\r\n\"" + + ba = "\033"; // escape character + qDebug() << ba; // prints: "\x1B" + + ba = "\xC3\xA1"; + qDebug() << ba; // prints: "\xC3\xA1" + + ba = QByteArray("a\0b", 3); + qDebug() << ba // prints: "\a\x00""b" +//! [1] diff --git a/src/corelib/doc/snippets/code/src_corelib_io_qfileselector.cpp b/src/corelib/doc/snippets/code/src_corelib_io_qfileselector.cpp new file mode 100644 index 0000000000..91c94eb762 --- /dev/null +++ b/src/corelib/doc/snippets/code/src_corelib_io_qfileselector.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWidgets module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QString defaultsBasePath = "data/"; + QString defaultsPath = defaultsBasePath + "defaults.conf"; + QString localizedPath = defaultsBasePath + + QString("%1/defaults.conf").arg(QLocale().name()); + if (QFile::exists(localizedPath)) + defaultsPath = localizedPath; + QFile defaults(defaultsPath); +//! [0] + +//! [1] + QString defaultsPath = "data/defaults.conf"; +#if defined(Q_OS_ANDROID) + defaultsPath = "data/android/defaults.conf"; +#elif defined(Q_OS_IOS) + defaultsPath = "data/ios/defaults.conf"; +#endif + QFile defaults(defaultsPath); +//! [1] + +//! [2] + QFileSelector selector; + QFile defaultsFile(selector.select("data/defaults.conf")); +//! [2] + +//! [3] + data/defaults.conf + data/+android/defaults.conf + data/+ios/+en_GB/defaults.conf +//! [3] + +//! [4] + images/background.png + images/+android/+en_GB/background.png +//! [4] + +//! [5] + images/background.png + images/+linux/background.png + images/+windows/background.png + images/+admin/background.png + images/+admin/+linux/background.png +//! [5] diff --git a/src/corelib/doc/snippets/code/src_corelib_io_qloggingcategory.cpp b/src/corelib/doc/snippets/code/src_corelib_io_qloggingcategory.cpp new file mode 100644 index 0000000000..20ae52a251 --- /dev/null +++ b/src/corelib/doc/snippets/code/src_corelib_io_qloggingcategory.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + [.] = true|false +//! [0] + +//! [1] + QLoggingCategory::setFilterRules("*.debug=false\n" + "driver.usb.debug=true"); +//! [1] + +//! [2] + [Rules] + *.debug=false + driver.usb.debug=true +//! [2] + +//! [3] + QT_LOGGING_RULES="*.debug=false;driver.usb.debug=true" +//! [3] diff --git a/src/corelib/doc/snippets/code/src_corelib_io_qtemporaryfile.cpp b/src/corelib/doc/snippets/code/src_corelib_io_qtemporaryfile.cpp index 127c7bd0d9..4e864b3dcd 100644 --- a/src/corelib/doc/snippets/code/src_corelib_io_qtemporaryfile.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_io_qtemporaryfile.cpp @@ -61,3 +61,11 @@ // as it goes out of scope. //! [0] } + +//! [1] + QFile f(":/resources/file.txt"); + QTemporaryFile::createNativeFile(f); // Returns a pointer to a temporary file + + QFile f("/users/qt/file.txt"); + QTemporaryFile::createNativeFile(f); // Returns 0 +//! [1] diff --git a/src/corelib/doc/snippets/code/src_corelib_io_qurl.cpp b/src/corelib/doc/snippets/code/src_corelib_io_qurl.cpp index b2a2282085..79af776ce4 100644 --- a/src/corelib/doc/snippets/code/src_corelib_io_qurl.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_io_qurl.cpp @@ -101,3 +101,89 @@ QUrl url("http://qt-project.org/support/file.html"); // url.adjusted(RemoveFilename) == "http://qt-project.org/support/" // url.fileName() == "file.html" //! [7] + +//! [8] + qDebug() << QUrl("main.qml").isRelative(); // true: no scheme + qDebug() << QUrl("qml/main.qml").isRelative(); // true: no scheme + qDebug() << QUrl("file:main.qml").isRelative(); // false: has "file" scheme + qDebug() << QUrl("file:qml/main.qml").isRelative(); // false: has "file" scheme +//! [8] + +//! [9] + // Absolute URL, relative path + QUrl url("file:file.txt"); + qDebug() << url.isRelative(); // false: has "file" scheme + qDebug() << QDir::isAbsolutePath(url.path()); // false: relative path + + // Relative URL, absolute path + url = QUrl("/home/user/file.txt"); + qDebug() << url.isRelative(); // true: has no scheme + qDebug() << QDir::isAbsolutePath(url.path()); // true: absolute path +//! [9] + +//! [10] + QUrl original("http://example.com/?q=a%2B%3Db%26c"); + QUrl copy(original); + copy.setQuery(copy.query(QUrl::FullyDecoded), QUrl::DecodedMode); + + qDebug() << original.toString(); // prints: http://example.com/?q=a%2B%3Db%26c + qDebug() << copy.toString(); // prints: http://example.com/?q=a+=b&c +//! [10] + +//! [11] + QUrl url; + url.setScheme("ftp"); +//! [11] + +//! [12] + qDebug() << QUrl("file:file.txt").path(); // "file.txt" + qDebug() << QUrl("/home/user/file.txt").path(); // "/home/user/file.txt" + qDebug() << QUrl("http://www.example.com/test/123").path(); // "/test/123" +//! [12] + +//! [13] + qDebug() << QUrl("/foo%FFbar").path(); +//! [13] + +//! [14] + qDebug() << QUrl("/foo+bar%2B").path(); // "/foo+bar+" +//! [14] + +//! [15] + const QUrl url("/tmp/Mambo %235%3F.mp3"); + qDebug() << url.path(QUrl::FullyDecoded); // "/tmp/Mambo #5?.mp3" + qDebug() << url.path(QUrl::PrettyDecoded); // "/tmp/Mambo #5?.mp3" + qDebug() << url.path(QUrl::FullyEncoded); // "/tmp/Mambo%20%235%3F.mp3" +//! [15] + +//! [16] + qDebug() << QUrl::fromLocalFile("file.txt"); // QUrl("file:file.txt") + qDebug() << QUrl::fromLocalFile("/home/user/file.txt"); // QUrl("file:///home/user/file.txt") + qDebug() << QUrl::fromLocalFile("file:file.txt"); // doesn't make sense; expects path, not url with scheme +//! [16] + +//! [17] + QUrl url = QUrl::fromLocalFile("file.txt"); + QUrl baseUrl = QUrl("file:/home/user/"); + // wrong: prints QUrl("file:file.txt"), as url already has a scheme + qDebug() << baseUrl.resolved(url); +//! [17] + +//! [18] + // correct: prints QUrl("file:///home/user/file.txt") + url.setScheme(QString()); + qDebug() << baseUrl.resolved(url); +//! [18] + +//! [19] + QUrl url = QUrl("file.txt"); + QUrl baseUrl = QUrl("file:/home/user/"); + // prints QUrl("file:///home/user/file.txt") + qDebug() << baseUrl.resolved(url); +//! [19] + +//! [20] + qDebug() << QUrl("file:file.txt").toLocalFile(); // "file:file.txt" + qDebug() << QUrl("file:/home/user/file.txt").toLocalFile(); // "file:///home/user/file.txt" + qDebug() << QUrl("file.txt").toLocalFile(); // ""; wasn't a local file as it had no scheme +//! [20] diff --git a/src/corelib/doc/snippets/code/src_corelib_io_qurlquery.cpp b/src/corelib/doc/snippets/code/src_corelib_io_qurlquery.cpp new file mode 100644 index 0000000000..da87bfd143 --- /dev/null +++ b/src/corelib/doc/snippets/code/src_corelib_io_qurlquery.cpp @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWidgets module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +sub-delims = "!" / "$" / "&" / "'" / "(" / ")" + / "*" / "+" / "," / ";" / "=" +//! [0] diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qdeadlinetimer.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qdeadlinetimer.cpp new file mode 100644 index 0000000000..eb291d7b18 --- /dev/null +++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qdeadlinetimer.cpp @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWidgets module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + void executeOperation(int msecs) + { + QDeadlineTimer deadline(msecs); + do { + if (readFromDevice(deadline.remainingTime()) + break; + waitForReadyRead(deadline); + } while (!deadline.hasExpired()); + } +//! [0] + +//! [1] + using namespace std::chrono; + using namespace std::chrono_literals; + + QDeadlineTimer deadline(30s); + device->waitForReadyRead(deadline); + if (deadline.remainingTime() > 300ms) + cleanup(); +//! [1] + +//! [2] + using namespace std::chrono; + using namespace std::chrono_literals; + auto now = steady_clock::now(); + QDeadlineTimer deadline(now + 1s); + Q_ASSERT(deadline == now + 1s); +//! [2] + +//! [3] + using namespace std::chrono_literals; + QDeadlineTimer deadline(250ms); +//! [3] + +//! [4] + using namespace std::chrono_literals; + deadline.setRemainingTime(250ms); +//! [4] + +//! [5] + mutex.tryLock(deadline.remainingTime()); +//! [5] + +//! [6] + qint64 realTimeLeft = deadline.deadline(); + if (realTimeLeft != (std::numeric_limits::max)()) { + realTimeLeft -= QDeadlineTimer::current().deadline(); + // or: + //QElapsedTimer timer; + //timer.start(); + //realTimeLeft -= timer.msecsSinceReference(); + } +//! [6] + +//! [7] + qint64 realTimeLeft = deadline.deadlineNSecs(); + if (realTimeLeft != std::numeric_limits::max()) + realTimeLeft -= QDeadlineTimer::current().deadlineNSecs(); +//! [7] + +//! [8] + return d1.deadlineNSecs() == d2.deadlineNSecs(); +//! [8] + +//! [9] + return d1.deadlineNSecs() != d2.deadlineNSecs(); +//! [9] + +//! [10] + return d1.deadlineNSecs() < d2.deadlineNSecs(); +//! [10] + +//! [11] + return d1.deadlineNSecs() <= d2.deadlineNSecs(); +//! [11] + +//! [12] + return d1.deadlineNSecs() > d2.deadlineNSecs(); +//! [12] + +//! [13] + return d1.deadlineNSecs() >= d2.deadlineNSecs(); +//! [13] diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qmetaobject.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qmetaobject.cpp index eda52cfacd..56d1fa5a63 100644 --- a/src/corelib/doc/snippets/code/src_corelib_kernel_qmetaobject.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qmetaobject.cpp @@ -147,4 +147,23 @@ method.invoke(obj, QMetaMethod destroyedSignal = QMetaMethod::fromSignal(&QObject::destroyed); //! [9] +//! [10] + // In the class MainWindow declaration + #ifndef Q_MOC_RUN + // define the tag text as empty, so the compiler doesn't see it + # define MY_CUSTOM_TAG + #endif + ... + private slots: + MY_CUSTOM_TAG void testFunc(); +//! [10] + +//! [11] + MainWindow win; + win.show(); + + int functionIndex = win.metaObject()->indexOfSlot("testFunc()"); + QMetaMethod mm = win.metaObject()->method(functionIndex); + qDebug() << mm.tag(); // prints MY_CUSTOM_TAG +//! [11] } diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp index 6451f46b36..1e31a5292f 100644 --- a/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp @@ -538,3 +538,16 @@ QString text = MyMagicClass::tr("Sim sala bim."); //! [explicit tr context] QString text = QScrollBar::tr("Page up"); //! [explicit tr context] + +//! [53] +{ +const QSignalBlocker blocker(someQObject); +// no signals here +} +//! [53] + +//! [54] +const bool wasBlocked = someQObject->blockSignals(true); +// no signals here +someQObject->blockSignals(wasBlocked); +//! [54] diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp new file mode 100644 index 0000000000..ed3e9bd0c0 --- /dev/null +++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtTest module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + MyObject obj; + obj.startup(); + QTest::qWaitFor([&]() { + return obj.isReady(); + }, 3000); +//! [0] + +//! [1] + int i = 0; + while (myNetworkServerNotResponding() && i++ < 50) + QTest::qWait(250); +//! [1] diff --git a/src/corelib/doc/snippets/code/src_corelib_mimetype_qmimedatabase.cpp b/src/corelib/doc/snippets/code/src_corelib_mimetype_qmimedatabase.cpp index c5874d83b8..3092e32f6f 100644 --- a/src/corelib/doc/snippets/code/src_corelib_mimetype_qmimedatabase.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_mimetype_qmimedatabase.cpp @@ -55,3 +55,18 @@ if (mime.inherits("text/plain")) { // The file is plain text, we can display it in a QTextEdit } //! [0] + +//! [1] +QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime/packages"), + QStandardPaths::LocateDirectory); +//! [1] + +//! [2] + + + + Qt qmake Profile + + + +//! [2] diff --git a/src/corelib/doc/snippets/code/src_corelib_serialization_qcborstream.cpp b/src/corelib/doc/snippets/code/src_corelib_serialization_qcborstream.cpp new file mode 100644 index 0000000000..dbe38aa4b5 --- /dev/null +++ b/src/corelib/doc/snippets/code/src_corelib_serialization_qcborstream.cpp @@ -0,0 +1,347 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWidgets module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QCborValue(QCborTag(2), QByteArray("\x01\0\0\0\0\0\0\0\0", 9)); +//! [0] + +//! [1] + writer.startMap(4); // 4 elements in the map + + writer.append(QLatin1String("label")); + writer.append(QLatin1String("journald")); + + writer.append(QLatin1String("autoDetect")); + writer.append(false); + + writer.append(QLatin1String("condition")); + writer.append(QLatin1String("libs.journald")); + + writer.append(QLatin1String("output")); + writer.startArray(1); + writer.append(QLatin1String("privateFeature")); + writer.endArray(); + + writer.endMap(); +//! [1] + +//! [2] + QFile f("output", QIODevice::WriteOnly); + QCborStreamWriter writer(&f); + writer.startMap(0); + writer.endMap(); +//! [2] + +//! [3] + QByteArray encodedNumber(qint64 value) + { + QByteArray ba; + QCborStreamWriter writer(&ba); + writer.append(value); + return ba; + } +//! [3] + +//! [4] + writer.append(0U); + writer.append(Q_UINT64_C(4294967296)); + writer.append(std::numeric_limits::max()); +//! [4] + +//! [5] + writer.append(0); + writer.append(-1); + writer.append(Q_INT64_C(4294967296)); + writer.append(std::numeric_limits::max()); +//! [5] + +//! [6] + writer.append(QCborNegativeInteger(1)); + writer.append(QCborNegativeInteger(Q_INT64_C(4294967296))); + writer.append(QCborNegativeInteger(-quint64(std::numeric_limits::min()))); +//! [6] + +//! [7] + void writeFile(QCborStreamWriter &writer, const QString &fileName) + { + QFile f(fileName); + if (f.open(QIODevice::ReadOnly)) + writer.append(f.readAll()); + } +//! [7] + +//! [8] + writer.append(QLatin1String("Hello, World")); +//! [8] + +//! [9] + void writeString(QCborStreamWriter &writer, const QString &str) + { + writer.append(str); + } +//! [9] + +//! [10] + void writeRxPattern(QCborStreamWriter &writer, const QRegularExpression &rx) + { + writer.append(QCborTag(36)); + writer.append(rx.pattern()); + } +//! [10] + +//! [11] + void writeCurrentTime(QCborStreamWriter &writer) + { + writer.append(QCborKnownTags::UnixTime_t); + writer.append(time(nullptr)); + } +//! [11] + +//! [12] + writer.append(QCborSimpleType::Null); + writer.append(QCborSimpleType(32)); +//! [12] + +//! [13] + void writeFloat(QCborStreamWriter &writer, float f) + { + qfloat16 f16 = f; + if (qIsNaN(f) || f16 == f) + writer.append(f16); + else + writer.append(f); + } +//! [13] + +//! [14] + void writeFloat(QCborStreamWriter &writer, double d) + { + float f = d; + if (qIsNaN(d) || d == f) + writer.append(f); + else + writer.append(d); + } +//! [14] + +//! [15] + void writeDouble(QCborStreamWriter &writer, double d) + { + float f; + if (qIsNaN(d)) { + writer.append(qfloat16(qQNaN())); + } else if (qIsInf(d)) { + writer.append(d < 0 ? -qInf() : qInf()); + } else if ((f = d) == d) { + qfloat16 f16 = f; + if (f16 == f) + writer.append(f16); + else + writer.append(f); + } else { + writer.append(d); + } + } +//! [15] + +//! [16] + writer.append(b ? QCborSimpleType::True : QCborSimpleType::False); +//! [16] + +//! [17] + writer.append(QCborSimpleType::Null); +//! [17] + +//! [18] + writer.append(QCborSimpleType::Null); +//! [18] + +//! [19] + writer.append(QCborSimpleType::Undefined); +//! [19] + +//! [20] + void appendList(QCborStreamWriter &writer, const QLinkedList &list) + { + writer.startArray(); + for (const QString &s : list) + writer.append(s); + writer.endArray(); + } +//! [20] + +//! [21] + void appendList(QCborStreamWriter &writer, const QStringList &list) + { + writer.startArray(list.size()); + for (const QString &s : list) + writer.append(s); + writer.endArray(); + } +//! [21] + +//! [22] + void appendMap(QCborStreamWriter &writer, const QLinkedList> &list) + { + writer.startMap(); + for (const auto pair : list) { + writer.append(pair.first) + writer.append(pair.second); + } + writer.endMap(); + } +//! [22] + +//! [23] + void appendMap(QCborStreamWriter &writer, const QMap &map) + { + writer.startMap(map.size()); + for (auto it = map.begin(); it != map.end(); ++it) { + writer.append(it.key()); + writer.append(it.value()); + } + writer.endMap(); + } +//! [23] + +//! [24] + void handleStream(QCborStreamReader &reader) + { + switch (reader.type()) + case QCborStreamReader::UnsignedInteger: + case QCborStreamReader::NegativeInteger: + case QCborStreamReader::SimpleType: + case QCborStreamReader::Float16: + case QCborStreamReader::Float: + case QCborStreamReader::Double: + handleFixedWidth(reader); + reader.next(); + break; + case QCborStreamReader::ByteArray: + case QCborStreamReader::String: + handleString(reader); + break; + case QCborStreamReader::Array: + case QCborStreamReader::Map: + reader.enterContainer(); + while (reader.lastError() == QCborError::NoError) + handleStream(reader); + if (reader.lastError() == QCborError::NoError) + reader.leaveContainer(); + } + } +//! [24] + +//! [25] + QVariantList populateFromCbor(QCborStreamReader &reader) + { + QVariantList list; + if (reader.isLengthKnown()) + list.reserve(reader.length()); + + reader.enterContainer(); + while (reader.lastError() == QCborError::NoError && reader.hasNext()) + list.append(readOneElement(reader)); + if (reader.lastError() == QCborError::NoError) + reader.leaveContainer(); + } +//! [25] + +//! [26] + QVariantMap populateFromCbor(QCborStreamReader &reader) + { + QVariantMap map; + if (reader.isLengthKnown()) + map.reserve(reader.length()); + + reader.enterContainer(); + while (reader.lastError() == QCborError::NoError && reader.hasNext()) { + QString key = readElementAsString(reader); + map.insert(key, readOneElement(reader)); + } + if (reader.lastError() == QCborError::NoError) + reader.leaveContainer(); + } +//! [26] + +//! [27] + QString decodeString(QCborStreamReader &reader) + { + QString result; + auto r = reader.readString(); + while (r.code == QCborStreamReader::Ok) { + result += r.data; + r = reader.readString(); + } + + if (r.code == QCborStreamReader::Error) { + // handle error condition + result.clear(); + } + return result; + } +//! [27] + +//! [28] + QBytearray decodeBytearray(QCborStreamReader &reader) + { + QBytearray result; + auto r = reader.readBytearray(); + while (r.code == QCborStreamReader::Ok) { + result += r.data; + r = reader.readByteArray(); + } + + if (r.code == QCborStreamReader::Error) { + // handle error condition + result.clear(); + } + return result; + } +//! [28] + +//! [29] + QCborStreamReader result; + do { + qsizetype size = reader.currentStringChunkSize(); + qsizetype oldsize = buffer.size(); + buffer.resize(oldsize + size); + result = reader.readStringChunk(buffer.data() + oldsize, size); + } while (result.status() == QCborStreamReader::Ok); +//! [29] diff --git a/src/corelib/doc/snippets/code/src_corelib_serialization_qcborvalue.cpp b/src/corelib/doc/snippets/code/src_corelib_serialization_qcborvalue.cpp new file mode 100644 index 0000000000..63f813cf69 --- /dev/null +++ b/src/corelib/doc/snippets/code/src_corelib_serialization_qcborvalue.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWidgets module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QCborValue(uuid) == QCborValue(QCborKnownTags::Uuid, uuid.toRfc4122()); +//! [0] + +//! [1] + QCborValue value(QCborSimpleType(12)); +//! [1] + +//! [2] + value.isSimpleType(QCborSimpleType(12)); +//! [2] + +//! [3] + QCborValue(QUrl("https://example.com")) == QCborValue(QCborKnownTags::Url, "https://example.com"); +//! [3] + +//! [4] + value.toMap().value(key); +//! [4] + +//! [5] + value.toMap().value(key); +//! [5] + +//! [6] + if (reader.isTag() && reader.toTag() == QCborKnownTags::Signature) + reader.next(); + + QCborValue contents = QCborValue::fromCbor(reader); +//! [6] diff --git a/src/corelib/doc/snippets/code/src_corelib_serialization_qdatastream.cpp b/src/corelib/doc/snippets/code/src_corelib_serialization_qdatastream.cpp new file mode 100644 index 0000000000..5caaa16727 --- /dev/null +++ b/src/corelib/doc/snippets/code/src_corelib_serialization_qdatastream.cpp @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QDataStream &operator<<(QDataStream &, const QXxx &); + QDataStream &operator>>(QDataStream &, QXxx &); +//! [0] + +//! [1] + QDataStream & operator<< (QDataStream& stream, const QImage& image); + QDataStream & operator>> (QDataStream& stream, QImage& image); +//! [1] diff --git a/src/corelib/doc/snippets/code/src_corelib_serialization_qjsondocument.cpp b/src/corelib/doc/snippets/code/src_corelib_serialization_qjsondocument.cpp new file mode 100644 index 0000000000..c4913b1740 --- /dev/null +++ b/src/corelib/doc/snippets/code/src_corelib_serialization_qjsondocument.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + { + "Array": [ + true, + 999, + "string" + ], + "Key": "Value", + "null": null + } +//! [0] + +//! [1] + {"Array":[true,999,"string"],"Key":"Value","null":null} +//! [1] diff --git a/src/corelib/doc/snippets/code/src_corelib_thread_qsemaphore.cpp b/src/corelib/doc/snippets/code/src_corelib_thread_qsemaphore.cpp index 2081e4fdd0..52105bce0b 100644 --- a/src/corelib/doc/snippets/code/src_corelib_thread_qsemaphore.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_thread_qsemaphore.cpp @@ -81,3 +81,32 @@ QSemaphore sem(5); // sem.available() == 5 sem.tryAcquire(250, 1000); // sem.available() == 5, waits 1000 milliseconds and returns false sem.tryAcquire(3, 30000); // sem.available() == 2, returns true without waiting //! [3] + +//! [4] +// ... do something that may throw or return early +sem.release(); +//! [4] + +//! [5] +const QSemaphoreReleaser releaser(sem); +// ... do something that may throw or early return +// implicitly calls sem.release() here and at every other return in between +//! [5] + +//! [6] +{ // some scope + QSemaphoreReleaser releaser; // does nothing + // ... + if (someCondition) { + releaser = QSemaphoreReleaser(sem); + // ... + } + // ... +} // conditionally calls sem.release(), depending on someCondition +//! [6] + +//! [7] +releaser.cancel(); // avoid releasing old semaphore() +releaser = QSemaphoreReleaser(sem, 42); +// now will call sem.release(42) when 'releaser' is destroyed +//! [7] diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp index bd7cdaa681..32fccbefbf 100644 --- a/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp @@ -470,6 +470,33 @@ ba4.size(); // Returns 6. ba4.constData(); // Returns "ca\0r\0t" without terminating \0. //! [48] +//! [49] +QByteArray ba("ab"); +ba.repeated(4); // returns "abababab" +//! [49] + +//! [50] +QByteArray macAddress = QByteArray::fromHex("123456abcdef"); +macAddress.toHex(':'); // returns "12:34:56:ab:cd:ef" +macAddress.toHex(0); // returns "123456abcdef" +//! [50] + +//! [51] +QByteArray text = QByteArray::fromPercentEncoding("Qt%20is%20great%33"); +text.data(); // returns "Qt is great!" +//! [51] + +//! [52] +QByteArray text = "{a fishy string?}"; +QByteArray ba = text.toPercentEncoding("{}", "s"); +qDebug(ba.constData()); +// prints "{a fi%73hy %73tring%3F}" +//! [52] + +//! [53] +QByteArray ba = QByteArrayLiteral("byte array contents"); +//! [53] + } diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qbytearraymatcher.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qbytearraymatcher.cpp new file mode 100644 index 0000000000..63fc1f91e7 --- /dev/null +++ b/src/corelib/doc/snippets/code/src_corelib_tools_qbytearraymatcher.cpp @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +static const auto matcher = qMakeStaticByteArrayMatcher("needle"); +//! [0] + +//! [1] +static const auto matcher = qMakeStaticByteArrayMatcher("needle"); +//! [1] diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qcontiguouscache.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qcontiguouscache.cpp new file mode 100644 index 0000000000..6bc9604243 --- /dev/null +++ b/src/corelib/doc/snippets/code/src_corelib_tools_qcontiguouscache.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +MyRecord record(int row) const +{ + Q_ASSERT(row >= 0 && row < count()); + + while (row > cache.lastIndex()) + cache.append(slowFetchRecord(cache.lastIndex()+1)); + while (row < cache.firstIndex()) + cache.prepend(slowFetchRecord(cache.firstIndex()-1)); + + return cache.at(row); +} +//! [0] + +//! [1] +QContiguousCache cache(10); +cache.insert(INT_MAX, 1); // cache contains one value and has valid indexes, INT_MAX to INT_MAX +cache.append(2); // cache contains two values but does not have valid indexes. +cache.normalizeIndexes(); // cache has two values, 1 and 2. New first index will be in the range of 0 to capacity(). +//! [1] diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qhash.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qhash.cpp index c7df6f6090..a3d2dd7f9e 100644 --- a/src/corelib/doc/snippets/code/src_corelib_tools_qhash.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_tools_qhash.cpp @@ -350,3 +350,23 @@ inline uint qHash(const std::unordered_set &key, uint seed = 0) return qHashRangeCommutative(key.begin(), key.end(), seed); } //! [qhashrangecommutative] + +//! [29] +qHash(qMakePair(key.first, key.second), seed); +//! [29] + +//! [30] +{0, 1, 2} +//! [30] + +//! [31] +{1, 2, 0} +//! [31] + +//! [32] +uint qHash(K key); +uint qHash(const K &key); + +uint qHash(K key, uint seed); +uint qHash(const K &key, uint seed); +//! [32] diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qrect.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qrect.cpp index 4bdaa4d657..a19dc086ac 100644 --- a/src/corelib/doc/snippets/code/src_corelib_tools_qrect.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_tools_qrect.cpp @@ -58,3 +58,13 @@ QRect r2(QPoint(100, 200), QSize(11, 16)); QRectF r1(100.0, 200.1, 11.2, 16.3); QRectF r2(QPointF(100.0, 200.1), QSizeF(11.2, 16.3)); //! [1] + +//! [2] +QRect r = {15, 51, 42, 24}; +r = r.transposed(); // r == {15, 51, 24, 42} +//! [2] + +//! [3] +QRectF r = {1.5, 5.1, 4.2, 2.4}; +r = r.transposed(); // r == {1.5, 5.1, 2.4, 4.2} +//! [3] diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qregularexpression.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qregularexpression.cpp index b5d8320bce..afdd9c3d25 100644 --- a/src/corelib/doc/snippets/code/src_corelib_tools_qregularexpression.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_tools_qregularexpression.cpp @@ -360,4 +360,12 @@ QString wildcard = QRegularExpression::wildcardToRegularExpression("*.jpeg"); //! [31] } +//! [32] + (?\d\d)-(?\d\d)-(?\d\d\d\d) (\w+) (?\w+) +//! [32] + +//! [33] + ("", "day", "month", "year", "", "name") +//! [33] + } diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qshareddata.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qshareddata.cpp new file mode 100644 index 0000000000..45e8b0a965 --- /dev/null +++ b/src/corelib/doc/snippets/code/src_corelib_tools_qshareddata.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + class EmployeeData; +//! [0] + +//! [1] + template<> + EmployeeData *QSharedDataPointer::clone() + { + return d->clone(); + } +//! [1] + +//! [2] + QExplicitlySharedDataPointer base(new Base); + QExplicitlySharedDataPointer derived(base); // !!! DANGER !!! +//! [2] diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qsharedpointer.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qsharedpointer.cpp new file mode 100644 index 0000000000..69061ce298 --- /dev/null +++ b/src/corelib/doc/snippets/code/src_corelib_tools_qsharedpointer.cpp @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + class Y: public QEnableSharedFromThis + { + public: + QSharedPointer f() + { + return sharedFromThis(); + } + }; + + int main() + { + QSharedPointer p(new Y()); + QSharedPointer y = p->f(); + Q_ASSERT(p == y); // p and q must share ownership + } +//! [0] + +//! [1] + class ScriptInterface : public QObject + { + Q_OBJECT + + // ... + + public slots: + void slotCalledByScript(Y *managedBySharedPointer) + { + QSharedPointer yPtr = managedBySharedPointer->sharedFromThis(); + // Some other code unrelated to scripts that expects a QSharedPointer ... + } + }; +//! [1] + +//! [2] + static void doDeleteLater(MyObject *obj) + { + obj->deleteLater(); + } + + void otherFunction() + { + QSharedPointer obj = + QSharedPointer(new MyObject, doDeleteLater); + + // continue using obj + obj.clear(); // calls obj->deleteLater(); + } +//! [2] + +//! [3] + QSharedPointer obj = + QSharedPointer(new MyObject, &QObject::deleteLater); +//! [3] + +//! [4] + if (sharedptr) { ... } +//! [4] + +//! [5] + if (!sharedptr) { ... } +//! [5] + +//! [6] + QSharedPointer other(t); this->swap(other); +//! [6] + +//! [7] + QSharedPointer other(t, deleter); this->swap(other); +//! [7] + +//! [8] + if (weakref) { ... } +//! [8] + +//! [9] + if (!weakref) { ... } +//! [9] + +//! [10] + qDebug("Tracking %p", weakref.data()); +//! [10] + +//! [11] + // this pointer cannot be used in another thread + // so other threads cannot delete it + QWeakPointer weakref = obtainReference(); + + Object *obj = weakref.data(); + if (obj) { + // if the pointer wasn't deleted yet, we know it can't get + // deleted by our own code here nor the functions we call + otherFunction(obj); + } +//! [11] + +//! [12] + QWeakPointer weakref; + + // ... + + QSharedPointer strong = weakref.toStrongRef(); + if (strong) + qDebug() << "The value is:" << *strong; + else + qDebug() << "The value has already been deleted"; +//! [12] diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qstring.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qstring.cpp index 9b3e89e5c4..4e79d1e27a 100644 --- a/src/corelib/doc/snippets/code/src_corelib_tools_qstring.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_tools_qstring.cpp @@ -102,3 +102,21 @@ QString plain = "#include " QString html = plain.toHtmlEscaped(); // html == "#include <QtCore>" //! [7] + +//! [8] +QString str("ab"); +str.repeated(4); // returns "abababab" +//! [8] + +//! [9] +// hasAttribute takes a QString argument +if (node.hasAttribute("http-contents-length")) //... +//! [9] + +//! [10] +if (node.hasAttribute(QStringLiteral(u"http-contents-length"))) //... +//! [10] + +//! [11] +if (attribute.name() == QLatin1String("http-contents-length")) //... +//! [11] diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qstringview.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qstringview.cpp new file mode 100644 index 0000000000..5dc153372c --- /dev/null +++ b/src/corelib/doc/snippets/code/src_corelib_tools_qstringview.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWidgets module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + void myfun1(QStringView sv); // preferred + void myfun2(const QStringView &sv); // compiles and works, but slower +//! [0] + +//! [1] + void fun(QChar ch) { fun(QStringView(&ch, 1)); } +//! [1] + +//! [2] + auto sv = QStringView(array, std::size(array)); // using C++17 std::size() +//! [2] diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index a369bbe490..5c1665fa00 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -3376,9 +3376,7 @@ QString qEnvironmentVariable(const char *varName) Returns whether the environment variable \a varName is empty. Equivalent to - \code - qgetenv(varName).isEmpty() - \endcode + \snippet code/src_corelib_global_qglobal.cpp is-empty except that it's potentially much faster, and can't throw exceptions. \sa qgetenv(), qEnvironmentVariable(), qEnvironmentVariableIsSet() @@ -3408,9 +3406,7 @@ bool qEnvironmentVariableIsEmpty(const char *varName) Q_DECL_NOEXCEPT on the success of the conversion. Equivalent to - \code - qgetenv(varName).toInt(ok, 0) - \endcode + \snippet code/src_corelib_global_qglobal.cpp to-int except that it's much faster, and can't throw exceptions. \note there's a limit on the length of the value, which is sufficient for @@ -3484,9 +3480,7 @@ int qEnvironmentVariableIntValue(const char *varName, bool *ok) Q_DECL_NOEXCEPT Returns whether the environment variable \a varName is set. Equivalent to - \code - !qgetenv(varName).isNull() - \endcode + \snippet code/src_corelib_global_qglobal.cpp is-null except that it's potentially much faster, and can't throw exceptions. \sa qgetenv(), qEnvironmentVariable(), qEnvironmentVariableIsEmpty() @@ -3662,37 +3656,21 @@ bool qunsetenv(const char *varName) Its main use in Qt is to prevent implicitly-shared Qt containers from detaching: - \code - QString s = ...; - for (QChar ch : s) // detaches 's' (performs a deep-copy if 's' was shared) - process(ch); - for (QChar ch : qAsConst(s)) // ok, no detach attempt - process(ch); - \endcode + \snippet code/src_corelib_global_qglobal.cpp as-const-0 Of course, in this case, you could (and probably should) have declared \c s as \c const in the first place: - \code - const QString s = ...; - for (QChar ch : s) // ok, no detach attempt on const objects - process(ch); - \endcode + \snippet code/src_corelib_global_qglobal.cpp as-const-1 but often that is not easily possible. It is important to note that qAsConst() does not copy its argument, it just performs a \c{const_cast(t)}. This is also the reason why it is designed to fail for rvalues: The returned reference would go stale too soon. So while this works (but detaches the returned object): - \code - for (QChar ch : funcReturningQString()) - process(ch); // OK, the returned object is kept alive for the loop's duration - \endcode + \snippet code/src_corelib_global_qglobal.cpp as-const-2 this would not: - \code - for (QChar ch : qAsConst(funcReturningQString())) - process(ch); // ERROR: ch is copied from deleted memory - \endcode + \snippet code/src_corelib_global_qglobal.cpp as-const-3 To prevent this construct from compiling (and failing at runtime), qAsConst() has a second, deleted, overload which binds to rvalues. @@ -3705,10 +3683,7 @@ bool qunsetenv(const char *varName) \overload This overload is deleted to prevent a dangling reference in code like - \code - for (QChar ch : qAsConst(funcReturningQString())) - process(ch); // ERROR: ch is copied from deleted memory - \endcode + \snippet code/src_corelib_global_qglobal.cpp as-const-4 */ /*! @@ -4642,9 +4617,7 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters) purpose. It either expands to \c expr (if Qt is compiled without exception support or the compiler supports C++11 noexcept semantics) or to - \code - try { expr; } catch(...) { qTerminate(); } - \endcode + \snippet code/src_corelib_global_qglobal.cpp qterminate otherwise. Since this macro expands to just \c expr if the compiler supports @@ -4714,10 +4687,7 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters) The macro goes at the end of the function, usually after the \c{const}, if any: - \code - // generate error if this doesn't actually override anything: - virtual void MyWidget::paintEvent(QPaintEvent*) Q_DECL_OVERRIDE; - \endcode + \snippet code/src_corelib_global_qglobal.cpp qdecloverride \sa Q_DECL_FINAL */ @@ -4739,18 +4709,11 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters) The macro goes at the end of the function, usually after the \c{const}, if any: - \code - // more-derived classes no longer permitted to override this: - virtual void MyWidget::paintEvent(QPaintEvent*) Q_DECL_FINAL; - \endcode + \snippet code/src_corelib_global_qglobal.cpp qdeclfinal-1 For classes, it goes in front of the \c{:} in the class definition, if any: - \code - class QRect Q_DECL_FINAL { // cannot be derived from - // ... - }; - \endcode + \snippet code/src_corelib_global_qglobal.cpp qdeclfinal-2 \sa Q_DECL_OVERRIDE */ diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index a9c5d17aad..396aee8696 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -2062,9 +2062,7 @@ void qErrnoWarning(int code, const char *msg, ...) is not the default one. Example: - \code - QT_MESSAGE_PATTERN="[%{time yyyyMMdd h:mm:ss.zzz t} %{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{file}:%{line} - %{message}" - \endcode + \snippet code/src_corelib_global_qlogging.cpp 0 The default \a pattern is "%{if-category}%{category}: %{endif}%{message}". diff --git a/src/corelib/global/qnumeric.cpp b/src/corelib/global/qnumeric.cpp index c03b139c9f..fc2b052edf 100644 --- a/src/corelib/global/qnumeric.cpp +++ b/src/corelib/global/qnumeric.cpp @@ -130,12 +130,7 @@ static inline quint32 f2i(float f) two 32-bit floating point numbers and all you need is an approximated 24-bit precision, you can use this function like this: - \code - if (qFloatDistance(a, b) < (1 << 7)) { // The last 7 bits are not - // significant - // precise enough - } - \endcode + \snippet code/src_corelib_global_qnumeric.cpp 0 \sa qFuzzyCompare() \since 5.2 diff --git a/src/corelib/global/qoperatingsystemversion.cpp b/src/corelib/global/qoperatingsystemversion.cpp index 2f8d339ca7..94dc261b41 100644 --- a/src/corelib/global/qoperatingsystemversion.cpp +++ b/src/corelib/global/qoperatingsystemversion.cpp @@ -106,20 +106,12 @@ QT_BEGIN_NAMESPACE major version number component of the object on the left hand side of the expression (10) is greater than that of the object on the right (9): - \code - QOperatingSystemVersion::current() >= QOperatingSystemVersion(QOperatingSystemVersion::IOS, 9) - \endcode + \snippet code/src_corelib_global_qoperatingsystemversion.cpp 0 This allows expressions for multiple operating systems to be joined with a logical OR operator and still work as expected. For example: - \code - auto current = QOperatingSystemVersion::current(); - if (current >= QOperatingSystemVersion::OSXYosemite || - current >= QOperatingSystemVersion(QOperatingSystemVersion::IOS, 8)) { - // returns true on macOS >= 10.10 and iOS >= 8.0, but false on macOS < 10.10 and iOS < 8.0 - } - \endcode + \snippet code/src_corelib_global_qoperatingsystemversion.cpp 1 A more naive comparison algorithm might incorrectly return true on all versions of macOS, including Mac OS 9. This behavior is achieved by overloading the comparison operators to return diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp index a7d4aa303a..23e5e499b2 100644 --- a/src/corelib/global/qrandom.cpp +++ b/src/corelib/global/qrandom.cpp @@ -510,9 +510,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel those. The most common way of generating new values is to call the generate(), generate64() or fillRange() functions. One would use it as: - \code - quint32 value = QRandomGenerator::global()->generate(); - \endcode + \snippet code/src_corelib_global_qrandom.cpp 0 Additionally, it provides a floating-point function generateDouble() that returns a number in the range [0, 1) (that is, inclusive of zero and @@ -525,11 +523,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel the numbers generated by the object will always be the same, as in the following example: - \code - QRandomGenerator prng1(1234), prng2(1234); - Q_ASSERT(prng1.generate() == prng2.generate()); - Q_ASSERT(prng1.generate64() == prng2.generate64()); - \endcode + \snippet code/src_corelib_global_qrandom.cpp 1 The seed data takes the form of one or more 32-bit words. The ideal seed size is approximately equal to the size of the QRandomGenerator class @@ -552,12 +546,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel For ease of use, QRandomGenerator provides a global object that can be easily used, as in the following example: - \code - int x = QRandomGenerator::global()->generate(); - int y = QRandomGenerator::global()->generate(); - int w = QRandomGenerator::global()->bounded(16384); - int h = QRandomGenerator::global()->bounded(16384); - \endcode + \snippet code/src_corelib_global_qrandom.cpp 2 \section1 System-wide random number generator @@ -645,10 +634,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel following code may be used to generate a floating-point number in the range [1, 2.5): - \code - std::uniform_real_distribution dist(1, 2.5); - return dist(*QRandomGenerator::global()); - \endcode + \snippet code/src_corelib_global_qrandom.cpp 3 \sa QRandomGenerator64, qrand() */ @@ -688,10 +674,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel with the same seed value will produce the same number sequence. This constructor is equivalent to: - \code - std::seed_seq sseq(seedBuffer, seedBuffer + len); - QRandomGenerator generator(sseq); - \endcode + \snippet code/src_corelib_global_qrandom.cpp 4 \sa seed(), securelySeeded() */ @@ -705,10 +688,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel with the same seed value will produce the same number sequence. This constructor is equivalent to: - \code - std::seed_seq sseq(begin, end); - QRandomGenerator generator(sseq); - \endcode + \snippet code/src_corelib_global_qrandom.cpp 5 \sa seed(), securelySeeded() */ @@ -828,10 +808,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel Discards the next \a z entries from the sequence. This method is equivalent to calling generate() \a z times and discarding the result, as in: - \code - while (z--) - generator.generate(); - \endcode + \snippet code/src_corelib_global_qrandom.cpp 6 */ /*! @@ -840,9 +817,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel Generates 32-bit quantities and stores them in the range between \a begin and \a end. This function is equivalent to (and is implemented as): - \code - std::generate(begin, end, [this]() { return generate(); }); - \endcode + \snippet code/src_corelib_global_qrandom.cpp 7 This function complies with the requirements for the function \l{http://en.cppreference.com/w/cpp/numeric/random/seed_seq/generate}{\c std::seed_seq::generate}, @@ -853,9 +828,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel 32 bits of data. Any other bits will be zero. To fill the range with 64 bit quantities, one can write: - \code - std::generate(begin, end, []() { return QRandomGenerator::global()->generate64(); }); - \endcode + \snippet code/src_corelib_global_qrandom.cpp 8 If the range refers to contiguous memory (such as an array or the data from a QVector), the fillRange() function may be used too. @@ -882,11 +855,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel For example, to fill a vector of 16 entries with random values, one may write: - \code - QVector vector; - vector.resize(16); - QRandomGenerator::fillRange(vector.data(), vector.size()); - \endcode + \snippet code/src_corelib_global_qrandom.cpp 9 \sa generate() */ @@ -901,10 +870,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel For example, to fill generate two 32-bit quantities, one may write: - \code - quint32 array[2]; - QRandomGenerator::fillRange(array); - \endcode + \snippet code/src_corelib_global_qrandom.cpp 10 It would have also been possible to make one call to generate64() and then split the two halves of the 64-bit value. @@ -919,10 +885,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel inclusive of zero and exclusive of 1). This function is equivalent to: - \code - QRandomGenerator64 rd; - return std::generate_canonical::digits>(rd); - \endcode + \snippet code/src_corelib_global_qrandom.cpp 11 The same may also be obtained by using \l{http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution}{\c std::uniform_real_distribution} @@ -937,9 +900,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel Generates one random double in the range between 0 (inclusive) and \a highest (exclusive). This function is equivalent to and is implemented as: - \code - return generateDouble() * highest; - \endcode + \snippet code/src_corelib_global_qrandom.cpp 12 \sa generateDouble(), bounded() */ @@ -956,9 +917,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel For example, to obtain a value between 0 and 255 (inclusive), one would write: - \code - quint32 v = QRandomGenerator::bounded(256); - \endcode + \snippet code/src_corelib_global_qrandom.cpp 13 Naturally, the same could also be obtained by masking the result of generate() to only the lower 8 bits. Either solution is as efficient. @@ -995,9 +954,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel For example, to obtain a value between 1000 (incl.) and 2000 (excl.), one would write: - \code - quint32 v = QRandomGenerator::bounded(1000, 2000); - \endcode + \snippet code/src_corelib_global_qrandom.cpp 14 Note that this function cannot be used to obtain values in the full 32-bit @@ -1053,9 +1010,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel For example, the following creates a random RGB color: - \code - return QColor::fromRgb(QRandomGenerator::global()->generate()); - \endcode + \snippet code/src_corelib_global_qrandom.cpp 15 Accesses to this object are thread-safe and it may therefore be used in any thread without locks. The object may also be copied and the sequence @@ -1123,9 +1078,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel set. If you wish to cast the returned value to qint64 and keep it positive, you should mask the sign bit off: - \code - qint64 value = QRandomGenerator64::generate() & std::numeric_limits::max(); - \endcode + \snippet code/src_corelib_global_qrandom.cpp 16 \sa QRandomGenerator, QRandomGenerator::generate64() */ diff --git a/src/corelib/io/qdebug.cpp b/src/corelib/io/qdebug.cpp index 2e825d2373..4d56d1a179 100644 --- a/src/corelib/io/qdebug.cpp +++ b/src/corelib/io/qdebug.cpp @@ -606,31 +606,7 @@ QDebug &QDebug::resetFormat() clean. Output examples: - \code - QString s; - - s = "a"; - qDebug().noquote() << s; // prints: a - qDebug() << s; // prints: "a" - - s = "\"a\r\n\""; - qDebug() << s; // prints: "\"a\r\n\"" - - s = "\033"; // escape character - qDebug() << s; // prints: "\u001B" - - s = "\u00AD"; // SOFT HYPHEN - qDebug() << s; // prints: "\u00AD" - - s = "\u00E1"; // LATIN SMALL LETTER A WITH ACUTE - qDebug() << s; // prints: "á" - - s = "a\u0301"; // "a" followed by COMBINING ACUTE ACCENT - qDebug() << s; // prints: "á"; - - s = "\u0430\u0301"; // CYRILLIC SMALL LETTER A followed by COMBINING ACUTE ACCENT - qDebug() << s; // prints: "а́" - \endcode + \snippet code/src_corelib_io_qdebug.cpp 0 */ /*! @@ -690,25 +666,7 @@ QDebug &QDebug::resetFormat() clean. Output examples: - \code - QByteArray ba; - - ba = "a"; - qDebug().noquote() << ba; // prints: a - qDebug() << ba; // prints: "a" - - ba = "\"a\r\n\""; - qDebug() << ba; // prints: "\"a\r\n\"" - - ba = "\033"; // escape character - qDebug() << ba; // prints: "\x1B" - - ba = "\xC3\xA1"; - qDebug() << ba; // prints: "\xC3\xA1" - - ba = QByteArray("a\0b", 3); - qDebug() << ba // prints: "\a\x00""b" - \endcode + \snippet code/src_corelib_io_qdebug.cpp 1 Note how QDebug needed to close and reopen the string in the way C and C++ languages concatenate string literals so that the letter 'b' is not diff --git a/src/corelib/io/qfileselector.cpp b/src/corelib/io/qfileselector.cpp index 0ba8b124f7..ce06c8e00b 100644 --- a/src/corelib/io/qfileselector.cpp +++ b/src/corelib/io/qfileselector.cpp @@ -81,27 +81,11 @@ QFileSelectorPrivate::QFileSelectorPrivate() Consider the following example usage, where you want to use different settings files on different locales. You might select code between locales like this: - \code - QString defaultsBasePath = "data/"; - QString defaultsPath = defaultsBasePath + "defaults.conf"; - QString localizedPath = defaultsBasePath - + QString("%1/defaults.conf").arg(QLocale().name()); - if (QFile::exists(localizedPath)) - defaultsPath = localizedPath; - QFile defaults(defaultsPath); - \endcode + \snippet code/src_corelib_io_qfileselector.cpp 0 Similarly, if you want to pick a different data file based on target platform, your code might look something like this: - \code - QString defaultsPath = "data/defaults.conf"; -#if defined(Q_OS_ANDROID) - defaultsPath = "data/android/defaults.conf"; -#elif defined(Q_OS_IOS) - defaultsPath = "data/ios/defaults.conf"; -#endif - QFile defaults(defaultsPath); - \endcode + \snippet code/src_corelib_io_qfileselector.cpp 1 QFileSelector provides a convenient alternative to writing such boilerplate code, and in the latter case it allows you to start using an platform-specific configuration without a recompile. @@ -109,27 +93,17 @@ QFileSelectorPrivate::QFileSelectorPrivate() selecting a different file only on certain combinations of platform and locale. For example, to select based on platform and/or locale, the code is as follows: - \code - QFileSelector selector; - QFile defaultsFile(selector.select("data/defaults.conf")); - \endcode + \snippet code/src_corelib_io_qfileselector.cpp 2 The files to be selected are placed in directories named with a \c'+' and a selector name. In the above example you could have the platform configurations selected by placing them in the following locations: - \code - data/defaults.conf - data/+android/defaults.conf - data/+ios/+en_GB/defaults.conf - \endcode + \snippet code/src_corelib_io_qfileselector.cpp 3 To find selected files, QFileSelector looks in the same directory as the base file. If there are any directories of the form + with an active selector, QFileSelector will prefer a file with the same file name from that directory over the base file. These directories can be nested to check against multiple selectors, for example: - \code - images/background.png - images/+android/+en_GB/background.png - \endcode + \snippet code/src_corelib_io_qfileselector.cpp 4 With those files available, you would select a different file on the android platform, but only if the locale was en_GB. @@ -178,13 +152,7 @@ QFileSelectorPrivate::QFileSelectorPrivate() credentials. The example is sorted so that the lowest matching file would be chosen if all selectors were present: - \code - images/background.png - images/+linux/background.png - images/+windows/background.png - images/+admin/background.png - images/+admin/+linux/background.png - \endcode + \snippet code/src_corelib_io_qfileselector.cpp 5 Because extra selectors are checked before platform the \c{+admin/background.png} will be chosen on Windows when the admin selector is set, and \c{+windows/background.png} will be chosen on diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp index aa84f56368..33253429a2 100644 --- a/src/corelib/io/qloggingcategory.cpp +++ b/src/corelib/io/qloggingcategory.cpp @@ -135,9 +135,7 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift) flexible way. Rules are specified in text, where every line must have the format - \code - [.] = true|false - \endcode + \snippet code/src_corelib_io_qloggingcategory.cpp 0 \c is the name of the category, potentially with \c{*} as a wildcard symbol as the first or last character (or at both positions). @@ -149,10 +147,7 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift) Rules can be set via \l setFilterRules(): - \code - QLoggingCategory::setFilterRules("*.debug=false\n" - "driver.usb.debug=true"); - \endcode + \snippet code/src_corelib_io_qloggingcategory.cpp 1 Since Qt 5.3, logging rules are also automatically loaded from the \c [Rules] section of a logging @@ -160,19 +155,13 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift) configuration directory, or explicitly set in a \c QT_LOGGING_CONF environment variable: - \code - [Rules] - *.debug=false - driver.usb.debug=true - \endcode + \snippet code/src_corelib_io_qloggingcategory.cpp 2 Since Qt 5.3, logging rules can also be specified in a \c QT_LOGGING_RULES environment variable. And since Qt 5.6, multiple rules can also be separated by semicolons: - \code - QT_LOGGING_RULES="*.debug=false;driver.usb.debug=true" - \endcode + \snippet code/src_corelib_io_qloggingcategory.cpp 3 Rules set by \l setFilterRules() take precedence over rules specified in the QtProject configuration directory, and can, in turn, be diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index 1983a22c65..7e3be9ef36 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -893,13 +893,7 @@ bool QTemporaryFile::rename(const QString &newName) For example: - \code - QFile f(":/resources/file.txt"); - QTemporaryFile::createNativeFile(f); // Returns a pointer to a temporary file - - QFile f("/users/qt/file.txt"); - QTemporaryFile::createNativeFile(f); // Returns 0 - \endcode + \snippet code/src_corelib_io_qtemporaryfile.cpp 1 \sa QFileInfo::isNativePath() */ diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index 15785b48e0..b324df53b2 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -116,27 +116,12 @@ Calling isRelative() will return whether or not the URL is relative. A relative URL has no \l {scheme}. For example: - \code - qDebug() << QUrl("main.qml").isRelative(); // true: no scheme - qDebug() << QUrl("qml/main.qml").isRelative(); // true: no scheme - qDebug() << QUrl("file:main.qml").isRelative(); // false: has "file" scheme - qDebug() << QUrl("file:qml/main.qml").isRelative(); // false: has "file" scheme - \endcode + \snippet code/src_corelib_io_qurl.cpp 8 Notice that a URL can be absolute while containing a relative path, and vice versa: - \code - // Absolute URL, relative path - QUrl url("file:file.txt"); - qDebug() << url.isRelative(); // false: has "file" scheme - qDebug() << QDir::isAbsolutePath(url.path()); // false: relative path - - // Relative URL, absolute path - url = QUrl("/home/user/file.txt"); - qDebug() << url.isRelative(); // true: has no scheme - qDebug() << QDir::isAbsolutePath(url.path()); // true: absolute path - \endcode + \snippet code/src_corelib_io_qurl.cpp 9 A relative URL can be resolved by passing it as an argument to resolved(), which returns an absolute URL. isParentOf() is used for determining whether @@ -369,14 +354,7 @@ The following example illustrates the problem: - \code - QUrl original("http://example.com/?q=a%2B%3Db%26c"); - QUrl copy(original); - copy.setQuery(copy.query(QUrl::FullyDecoded), QUrl::DecodedMode); - - qDebug() << original.toString(); // prints: http://example.com/?q=a%2B%3Db%26c - qDebug() << copy.toString(); // prints: http://example.com/?q=a+=b&c - \endcode + \snippet code/src_corelib_io_qurl.cpp 10 If the two URLs were used via HTTP GET, the interpretation by the web server would probably be different. In the first case, it would interpret @@ -1991,10 +1969,7 @@ void QUrl::setUrl(const QString &url, ParsingMode parsingMode) \image qurl-authority2.png To set the scheme, the following call is used: - \code - QUrl url; - url.setScheme("ftp"); - \endcode + \snippet code/src_corelib_io_qurl.cpp 11 The scheme can also be empty, in which case the URL is interpreted as relative. @@ -2569,11 +2544,7 @@ void QUrl::setPath(const QString &path, ParsingMode mode) /*! Returns the path of the URL. - \code - qDebug() << QUrl("file:file.txt").path(); // "file.txt" - qDebug() << QUrl("/home/user/file.txt").path(); // "/home/user/file.txt" - qDebug() << QUrl("http://www.example.com/test/123").path(); // "/test/123" - \endcode + \snippet code/src_corelib_io_qurl.cpp 12 The \a options argument controls how to format the path component. All values produce an unambiguous result. With QUrl::FullyDecoded, all @@ -2588,27 +2559,18 @@ void QUrl::setPath(const QString &path, ParsingMode mode) An example of data loss is when you have non-Unicode percent-encoded sequences and use FullyDecoded (the default): - \code - qDebug() << QUrl("/foo%FFbar").path(); - \endcode + \snippet code/src_corelib_io_qurl.cpp 13 In this example, there will be some level of data loss because the \c %FF cannot be converted. Data loss can also occur when the path contains sub-delimiters (such as \c +): - \code - qDebug() << QUrl("/foo+bar%2B").path(); // "/foo+bar+" - \endcode + \snippet code/src_corelib_io_qurl.cpp 14 Other decoding examples: - \code - const QUrl url("/tmp/Mambo %235%3F.mp3"); - qDebug() << url.path(QUrl::FullyDecoded); // "/tmp/Mambo #5?.mp3" - qDebug() << url.path(QUrl::PrettyDecoded); // "/tmp/Mambo #5?.mp3" - qDebug() << url.path(QUrl::FullyEncoded); // "/tmp/Mambo%20%235%3F.mp3" - \endcode + \snippet code/src_corelib_io_qurl.cpp 15 \sa setPath() */ @@ -3859,40 +3821,22 @@ bool QUrl::isDetached() const An empty \a localFile leads to an empty URL (since Qt 5.4). - \code - qDebug() << QUrl::fromLocalFile("file.txt"); // QUrl("file:file.txt") - qDebug() << QUrl::fromLocalFile("/home/user/file.txt"); // QUrl("file:///home/user/file.txt") - qDebug() << QUrl::fromLocalFile("file:file.txt"); // doesn't make sense; expects path, not url with scheme - \endcode + \snippet code/src_corelib_io_qurl.cpp 16 In the first line in snippet above, a file URL is constructed from a local, relative path. A file URL with a relative path only makes sense if there is a base URL to resolve it against. For example: - \code - QUrl url = QUrl::fromLocalFile("file.txt"); - QUrl baseUrl = QUrl("file:/home/user/"); - // wrong: prints QUrl("file:file.txt"), as url already has a scheme - qDebug() << baseUrl.resolved(url); - \endcode + \snippet code/src_corelib_io_qurl.cpp 17 To resolve such a URL, it's necessary to remove the scheme beforehand: - \code - // correct: prints QUrl("file:///home/user/file.txt") - url.setScheme(QString()); - qDebug() << baseUrl.resolved(url); - \endcode + \snippet code/src_corelib_io_qurl.cpp 18 For this reason, it is better to use a relative URL (that is, no scheme) for relative file paths: - \code - QUrl url = QUrl("file.txt"); - QUrl baseUrl = QUrl("file:/home/user/"); - // prints QUrl("file:///home/user/file.txt") - qDebug() << baseUrl.resolved(url); - \endcode + \snippet code/src_corelib_io_qurl.cpp 19 \sa toLocalFile(), isLocalFile(), QDir::toNativeSeparators() */ @@ -3938,11 +3882,7 @@ QUrl QUrl::fromLocalFile(const QString &localFile) returned value in the form found on SMB networks (for example, "//servername/path/to/file.txt"). - \code - qDebug() << QUrl("file:file.txt").toLocalFile(); // "file:file.txt" - qDebug() << QUrl("file:/home/user/file.txt").toLocalFile(); // "file:///home/user/file.txt" - qDebug() << QUrl("file.txt").toLocalFile(); // ""; wasn't a local file as it had no scheme - \endcode + \snippet code/src_corelib_io_qurl.cpp 20 Note: if the path component of this URL contains a non-UTF-8 binary sequence (such as %80), the behaviour of this function is undefined. diff --git a/src/corelib/io/qurlquery.cpp b/src/corelib/io/qurlquery.cpp index 231a26c211..97e7b8a4eb 100644 --- a/src/corelib/io/qurlquery.cpp +++ b/src/corelib/io/qurlquery.cpp @@ -129,10 +129,7 @@ QT_BEGIN_NAMESPACE Non-standard delimiters should be chosen from among what RFC 3986 calls "sub-delimiters". They are: - \code - sub-delims = "!" / "$" / "&" / "'" / "(" / ")" - / "*" / "+" / "," / ";" / "=" - \endcode + \snippet code/src_corelib_io_qurlquery.cpp 0 Use of other characters is not supported and may result in unexpected behaviour. QUrlQuery does not verify that you passed a valid delimiter. @@ -570,10 +567,7 @@ QString QUrlQuery::query(QUrl::ComponentFormattingOptions encoding) const \note Non-standard delimiters should be chosen from among what RFC 3986 calls "sub-delimiters". They are: - \code - sub-delims = "!" / "$" / "&" / "'" / "(" / ")" - / "*" / "+" / "," / ";" / "=" - \endcode + \snippet code/src_corelib_io_qurlquery.cpp 0 Use of other characters is not supported and may result in unexpected behaviour. This method does not verify that you passed a valid delimiter. diff --git a/src/corelib/kernel/qdeadlinetimer.cpp b/src/corelib/kernel/qdeadlinetimer.cpp index 66d0dce7e8..466056d513 100644 --- a/src/corelib/kernel/qdeadlinetimer.cpp +++ b/src/corelib/kernel/qdeadlinetimer.cpp @@ -75,17 +75,7 @@ Q_DECL_CONST_FUNCTION static inline QPair toSecsAndNSecs(qint64 QDeadlineTimer objects can be passed to functions being called to execute this operation so they know how long to still operate. - \code - void executeOperation(int msecs) - { - QDeadlineTimer deadline(msecs); - do { - if (readFromDevice(deadline.remainingTime()) - break; - waitForReadyRead(deadline); - } while (!deadline.hasExpired()); - } - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 0 Many QDeadlineTimer functions deal with time out values, which all are measured in milliseconds. There are two special values, the same as many @@ -125,15 +115,7 @@ Q_DECL_CONST_FUNCTION static inline QPair toSecsAndNSecs(qint64 \c{std::chrono::time_point} objects. In addition, it is fully compatible with the time literals from C++14, which allow one to write code as: - \code - using namespace std::chrono; - using namespace std::chrono_literals; - - QDeadlineTimer deadline(30s); - device->waitForReadyRead(deadline); - if (deadline.remainingTime() > 300ms) - cleanup(); - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 1 As can be seen in the example above, QDeadlineTimer offers a templated version of remainingTime() and deadline() that can be used to return @@ -145,13 +127,7 @@ Q_DECL_CONST_FUNCTION static inline QPair toSecsAndNSecs(qint64 Also note that, due to this conversion, the deadlines will not be precise, so the following code is not expected to compare equally: - \code - using namespace std::chrono; - using namespace std::chrono_literals; - auto now = steady_clock::now(); - QDeadlineTimer deadline(now + 1s); - Q_ASSERT(deadline == now + 1s); - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 2 \sa QTime, QTimer, QDeadlineTimer, Qt::TimerType */ @@ -246,10 +222,7 @@ QDeadlineTimer::QDeadlineTimer(qint64 msecs, Qt::TimerType type) Q_DECL_NOTHROW This constructor can be used with C++14's user-defined literals for time, such as in: - \code - using namespace std::chrono_literals; - QDeadlineTimer deadline(250ms); - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 3 For optimization purposes, if \a remaining is zero or negative, this function may skip obtaining the current time and may instead use a value @@ -339,10 +312,7 @@ void QDeadlineTimer::setPreciseRemainingTime(qint64 secs, qint64 nsecs, Qt::Time This function can be used with C++14's user-defined literals for time, such as in: - \code - using namespace std::chrono_literals; - deadline.setRemainingTime(250ms); - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 4 \note Qt detects the necessary C++14 compiler support by way of the feature test recommendations from @@ -415,9 +385,7 @@ void QDeadlineTimer::setTimerType(Qt::TimerType timerType) lock functions in \l QMutex, \l QWaitCondition, \l QSemaphore, or \l QReadWriteLock. For example: - \code - mutex.tryLock(deadline.remainingTime()); - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 5 \sa remainingTimeNSecs(), isForever(), hasExpired() */ @@ -469,16 +437,7 @@ qint64 QDeadlineTimer::rawRemainingTimeNSecs() const Q_DECL_NOTHROW overdue, by subtracting QDeadlineTimer::current() or QElapsedTimer::msecsSinceReference(), as in the following example: - \code - qint64 realTimeLeft = deadline.deadline(); - if (realTimeLeft != (std::numeric_limits::max)()) { - realTimeLeft -= QDeadlineTimer::current().deadline(); - // or: - //QElapsedTimer timer; - //timer.start(); - //realTimeLeft -= timer.msecsSinceReference(); - } - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 6 \note Timers that were created as expired have an indetermine time point in the past as their deadline, so the above calculation may not work. @@ -505,11 +464,7 @@ qint64 QDeadlineTimer::deadline() const Q_DECL_NOTHROW overdue, by subtracting QDeadlineTimer::current(), as in the following example: - \code - qint64 realTimeLeft = deadline.deadlineNSecs(); - if (realTimeLeft != std::numeric_limits::max()) - realTimeLeft -= QDeadlineTimer::current().deadlineNSecs(); - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 7 \note Timers that were created as expired have an indetermine time point in the past as their deadline, so the above calculation may not work. @@ -614,9 +569,7 @@ QDeadlineTimer QDeadlineTimer::addNSecs(QDeadlineTimer dt, qint64 nsecs) Q_DECL_ same, false otherwise. The timer type used to create the two deadlines is ignored. This function is equivalent to: - \code - return d1.deadlineNSecs() == d2.deadlineNSecs(); - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 8 \note comparing QDeadlineTimer objects with different timer types is not supported and may result in unpredictable behavior. @@ -630,9 +583,7 @@ QDeadlineTimer QDeadlineTimer::addNSecs(QDeadlineTimer dt, qint64 nsecs) Q_DECL_ diferent, false otherwise. The timer type used to create the two deadlines is ignored. This function is equivalent to: - \code - return d1.deadlineNSecs() != d2.deadlineNSecs(); - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 9 \note comparing QDeadlineTimer objects with different timer types is not supported and may result in unpredictable behavior. @@ -646,9 +597,7 @@ QDeadlineTimer QDeadlineTimer::addNSecs(QDeadlineTimer dt, qint64 nsecs) Q_DECL_ d2, false otherwise. The timer type used to create the two deadlines is ignored. This function is equivalent to: - \code - return d1.deadlineNSecs() < d2.deadlineNSecs(); - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 10 \note comparing QDeadlineTimer objects with different timer types is not supported and may result in unpredictable behavior. @@ -662,9 +611,7 @@ QDeadlineTimer QDeadlineTimer::addNSecs(QDeadlineTimer dt, qint64 nsecs) Q_DECL_ deadline in \a d2, false otherwise. The timer type used to create the two deadlines is ignored. This function is equivalent to: - \code - return d1.deadlineNSecs() <= d2.deadlineNSecs(); - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 11 \note comparing QDeadlineTimer objects with different timer types is not supported and may result in unpredictable behavior. @@ -678,9 +625,7 @@ QDeadlineTimer QDeadlineTimer::addNSecs(QDeadlineTimer dt, qint64 nsecs) Q_DECL_ d2, false otherwise. The timer type used to create the two deadlines is ignored. This function is equivalent to: - \code - return d1.deadlineNSecs() > d2.deadlineNSecs(); - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 12 \note comparing QDeadlineTimer objects with different timer types is not supported and may result in unpredictable behavior. @@ -694,9 +639,7 @@ QDeadlineTimer QDeadlineTimer::addNSecs(QDeadlineTimer dt, qint64 nsecs) Q_DECL_ deadline in \a d2, false otherwise. The timer type used to create the two deadlines is ignored. This function is equivalent to: - \code - return d1.deadlineNSecs() >= d2.deadlineNSecs(); - \endcode + \snippet code/src_corelib_kernel_qdeadlinetimer.cpp 13 \note comparing QDeadlineTimer objects with different timer types is not supported and may result in unpredictable behavior. diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index a6ee12ede1..ac911e287b 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -1996,27 +1996,11 @@ const char *QMetaMethod::typeName() const Tag information can be added in the following way in the function declaration: - \code - // In the class MainWindow declaration - #ifndef Q_MOC_RUN - // define the tag text as empty, so the compiler doesn't see it - # define MY_CUSTOM_TAG - #endif - ... - private slots: - MY_CUSTOM_TAG void testFunc(); - \endcode + \snippet code/src_corelib_kernel_qmetaobject.cpp 10 and the information can be accessed by using: - \code - MainWindow win; - win.show(); - - int functionIndex = win.metaObject()->indexOfSlot("testFunc()"); - QMetaMethod mm = win.metaObject()->method(functionIndex); - qDebug() << mm.tag(); // prints MY_CUSTOM_TAG - \endcode + \snippet code/src_corelib_kernel_qmetaobject.cpp 11 For the moment, \c moc will extract and record all tags, but it will not handle any of them specially. You can use the tags to annotate your methods diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 3cb8c45b41..07208b7f40 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -526,18 +526,9 @@ void QMetaCallEvent::placeMetaCall(QObject *object) constructor and in the destructor it resets the state to what it was before the constructor ran. - \code - { - const QSignalBlocker blocker(someQObject); - // no signals here - } - \endcode + \snippet code/src_corelib_kernel_qobject.cpp 53 is thus equivalent to - \code - const bool wasBlocked = someQObject->blockSignals(true); - // no signals here - someQObject->blockSignals(wasBlocked); - \endcode + \snippet code/src_corelib_kernel_qobject.cpp 54 except the code using QSignalBlocker is safe in the face of exceptions. diff --git a/src/corelib/kernel/qtestsupport_core.cpp b/src/corelib/kernel/qtestsupport_core.cpp index 240e5795db..d69551a227 100644 --- a/src/corelib/kernel/qtestsupport_core.cpp +++ b/src/corelib/kernel/qtestsupport_core.cpp @@ -68,13 +68,7 @@ Q_CORE_EXPORT void QTestPrivate::qSleep(int ms) Example: - \code - MyObject obj; - obj.startup(); - QTest::qWaitFor([&]() { - return obj.isReady(); - }, 3000); - \endcode + \snippet code/src_corelib_kernel_qtestsupport_core.cpp 0 The code above will wait for the object to become ready, for a maximum of three seconds. @@ -91,11 +85,7 @@ Q_CORE_EXPORT void QTestPrivate::qSleep(int ms) Example: - \code - int i = 0; - while (myNetworkServerNotResponding() && i++ < 50) - QTest::qWait(250); - \endcode + \snippet code/src_corelib_kernel_qtestsupport_core.cpp 1 The code above will wait until the network server is responding for a maximum of about 12.5 seconds. diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp index 10b5c8eafd..35ea579767 100644 --- a/src/corelib/mimetypes/qmimedatabase.cpp +++ b/src/corelib/mimetypes/qmimedatabase.cpp @@ -453,25 +453,14 @@ bool QMimeDatabasePrivate::inherits(const QString &mime, const QString &parent) Applications which want to define custom MIME types need to install an XML file into the locations searched for MIME definitions. These locations can be queried with - \code - QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime/packages"), - QStandardPaths::LocateDirectory); - \endcode + \snippet code/src_corelib_mimetype_qmimedatabase.cpp 1 On a typical Unix system, this will be /usr/share/mime/packages/, but it is also possible to extend the list of directories by setting the environment variable \c XDG_DATA_DIRS. For instance adding /opt/myapp/share to \c XDG_DATA_DIRS will result in /opt/myapp/share/mime/packages/ being searched for MIME definitions. Here is an example of MIME XML: - \code - - - - Qt qmake Profile - - - - \endcode + \snippet code/src_corelib_mimetype_qmimedatabase.cpp 2 For more details about the syntax of XML MIME definitions, including defining "magic" in order to detect MIME types based on data as well, read the diff --git a/src/corelib/serialization/qcborstream.cpp b/src/corelib/serialization/qcborstream.cpp index aed286a11f..22286188b8 100644 --- a/src/corelib/serialization/qcborstream.cpp +++ b/src/corelib/serialization/qcborstream.cpp @@ -197,9 +197,7 @@ QDebug operator<<(QDebug dbg, QCborSimpleType st) For example, the following creates a QCborValue containing a byte array tagged with a tag 2. - \code - QCborValue(QCborTag(2), QByteArray("\x01\0\0\0\0\0\0\0\0", 9)); - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 0 \sa QCborKnownTags, QCborStreamWriter::append(QCborTag), QCborStreamReader::isTag(), QCborStreamReader::toTag(), @@ -530,25 +528,7 @@ QString QCborError::toString() const } \enddiv - \code - writer.startMap(4); // 4 elements in the map - - writer.append(QLatin1String("label")); - writer.append(QLatin1String("journald")); - - writer.append(QLatin1String("autoDetect")); - writer.append(false); - - writer.append(QLatin1String("condition")); - writer.append(QLatin1String("libs.journald")); - - writer.append(QLatin1String("output")); - writer.startArray(1); - writer.append(QLatin1String("privateFeature")); - writer.endArray(); - - writer.endMap(); - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 1 \section1 CBOR support @@ -731,12 +711,7 @@ static CborError qt_cbor_encoder_write_callback(void *self, const void *data, si The following example writes an empty map to a file: - \code - QFile f("output", QIODevice::WriteOnly); - QCborStreamWriter writer(&f); - writer.startMap(0); - writer.endMap(); - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 2 QCborStreamWriter does not take ownership of \a device. @@ -755,15 +730,7 @@ QCborStreamWriter::QCborStreamWriter(QIODevice *device) The following example writes a number to a byte array then returns it. - \code - QByteArray encodedNumber(qint64 value) - { - QByteArray ba; - QCborStreamWriter writer(&ba); - writer.append(value); - return ba; - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 3 QCborStreamWriter does not take ownership of \a data. */ @@ -821,11 +788,7 @@ QIODevice *QCborStreamWriter::device() const Unsigned Integer value. In the following example, we write the values 0, 2\sup{32} and \c UINT64_MAX: - \code - writer.append(0U); - writer.append(Q_UINT64_C(4294967296)); - writer.append(std::numeric_limits::max()); - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 4 \sa QCborStreamReader::isUnsignedInteger(), QCborStreamReader::toUnsignedInteger() */ @@ -842,12 +805,7 @@ void QCborStreamWriter::append(quint64 u) sign of the parameter. In the following example, we write the values 0, -1, 2\sup{32} and \c INT64_MAX: - \code - writer.append(0); - writer.append(-1); - writer.append(Q_INT64_C(4294967296)); - writer.append(std::numeric_limits::max()); - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 5 \sa QCborStreamReader::isInteger(), QCborStreamReader::toInteger() */ @@ -865,11 +823,7 @@ void QCborStreamWriter::append(qint64 i) equivalent to 2\sup{64} (that is, -18,446,744,073,709,551,616). In the following example, we write the values -1, -2\sup{32} and INT64_MIN: - \code - writer.append(QCborNegativeInteger(1)); - writer.append(QCborNegativeInteger(Q_INT64_C(4294967296))); - writer.append(QCborNegativeInteger(-quint64(std::numeric_limits::min()))); - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 6 Note how this function can be used to encode numbers that cannot fit a standard computer's 64-bit signed integer like \l qint64. That is, if \a n @@ -895,14 +849,7 @@ void QCborStreamWriter::append(QCborNegativeInteger n) The following example will load and append the contents of a file to the stream: - \code - void writeFile(QCborStreamWriter &writer, const QString &fileName) - { - QFile f(fileName); - if (f.open(QIODevice::ReadOnly)) - writer.append(f.readAll()); - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 7 As the example shows, unlike JSON, CBOR requires no escaping for binary content. @@ -920,9 +867,7 @@ void QCborStreamWriter::append(QCborNegativeInteger n) The following example appends a simple string to the stream: - \code - writer.append(QLatin1String("Hello, World")); - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 8 \b{Performance note}: CBOR requires that all Text Strings be encoded in UTF-8, so this function will iterate over the characters in the string to @@ -955,12 +900,7 @@ void QCborStreamWriter::append(QLatin1String str) The following example writes an arbitrary QString to the stream: - \code - void writeString(QCborStreamWriter &writer, const QString &str) - { - writer.append(str); - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 9 \sa QCborStreamReader::isString(), QCborStreamReader::readString() */ @@ -979,13 +919,7 @@ void QCborStreamWriter::append(QStringView str) In the following example, we append a CBOR Tag 36 (Regular Expression) and a QRegularExpression's pattern to the stream: - \code - void writeRxPattern(QCborStreamWriter &writer, const QRegularExpression &rx) - { - writer.append(QCborTag(36)); - writer.append(rx.pattern()); - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 10 \sa QCborStreamReader::isTag(), QCborStreamReader::toTag() */ @@ -1005,13 +939,7 @@ void QCborStreamWriter::append(QCborTag tag) integer representing the current time to the stream, obtained using the \c time() function: - \code - void writeCurrentTime(QCborStreamWriter &writer) - { - writer.append(QCborKnownTags::UnixTime_t); - writer.append(time(nullptr)); - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 11 \sa QCborStreamReader::isTag(), QCborStreamReader::toTag() */ @@ -1023,10 +951,7 @@ void QCborStreamWriter::append(QCborTag tag) Type value. In the following example, we write the simple type for Null as well as for type 32, which Qt has no support for. - \code - writer.append(QCborSimpleType::Null); - writer.append(QCborSimpleType(32)); - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 12 \note Using Simple Types for which there is no specification can lead to validation errors by the remote receiver. In addition, simple type values 24 @@ -1047,16 +972,7 @@ void QCborStreamWriter::append(QCborSimpleType st) a C++ \tt float to \c qfloat16 if there's no loss of precision and append it, or instead append the \tt float. - \code - void writeFloat(QCborStreamWriter &writer, float f) - { - qfloat16 f16 = f; - if (qIsNaN(f) || f16 == f) - writer.append(f16); - else - writer.append(f); - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 13 \sa QCborStreamReader::isFloat16(), QCborStreamReader::toFloat16() */ @@ -1073,16 +989,7 @@ void QCborStreamWriter::append(qfloat16 f) a C++ \tt double to \tt float if there's no loss of precision and append it, or instead append the \tt double. - \code - void writeFloat(QCborStreamWriter &writer, double d) - { - float f = d; - if (qIsNaN(d) || d == f) - writer.append(f); - else - writer.append(d); - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 14 \sa QCborStreamReader::isFloat(), QCborStreamReader::toFloat() */ @@ -1104,25 +1011,7 @@ void QCborStreamWriter::append(float f) which is expected to be taken into account by the system FPU or floating point emulation directly. - \code - void writeDouble(QCborStreamWriter &writer, double d) - { - float f; - if (qIsNaN(d)) { - writer.append(qfloat16(qQNaN())); - } else if (qIsInf(d)) { - writer.append(d < 0 ? -qInf() : qInf()); - } else if ((f = d) == d) { - qfloat16 f16 = f; - if (f16 == f) - writer.append(f16); - else - writer.append(f); - } else { - writer.append(d); - } - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 15 Determining if a double can be converted to an integral with no loss of precision is left as an exercise to the reader. @@ -1200,9 +1089,7 @@ void QCborStreamWriter::appendTextString(const char *utf8, qsizetype len) value or a CBOR True value. This function is equivalent to (and implemented as): - \code - writer.append(b ? QCborSimpleType::True : QCborSimpleType::False); - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 16 \sa appendNull(), appendUndefined(), QCborStreamReader::isBool(), QCborStreamReader::toBool() @@ -1215,9 +1102,7 @@ void QCborStreamWriter::appendTextString(const char *utf8, qsizetype len) Appends a CBOR Null value to the stream. This function is equivalent to (and implemented as): The parameter is ignored. - \code - writer.append(QCborSimpleType::Null); - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 17 \sa appendNull(), append(QCborSimpleType), QCborStreamReader::isNull() */ @@ -1228,9 +1113,7 @@ void QCborStreamWriter::appendTextString(const char *utf8, qsizetype len) Appends a CBOR Null value to the stream. This function is equivalent to (and implemented as): - \code - writer.append(QCborSimpleType::Null); - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 18 \sa append(std::nullptr_t), append(QCborSimpleType), QCborStreamReader::isNull() */ @@ -1241,9 +1124,7 @@ void QCborStreamWriter::appendTextString(const char *utf8, qsizetype len) Appends a CBOR Undefined value to the stream. This function is equivalent to (and implemented as): - \code - writer.append(QCborSimpleType::Undefined); - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 19 \sa append(QCborSimpleType), QCborStreamReader::isUndefined() */ @@ -1260,15 +1141,7 @@ void QCborStreamWriter::appendTextString(const char *utf8, qsizetype len) The following example appends elements from the linked list of strings passed as input: - \code - void appendList(QCborStreamWriter &writer, const QLinkedList &list) - { - writer.startArray(); - for (const QString &s : list) - writer.append(s); - writer.endArray(); - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 20 \sa startArray(quint64), endArray(), startMap(), QCborStreamReader::isArray(), QCborStreamReader::isLengthKnown() @@ -1293,15 +1166,7 @@ void QCborStreamWriter::startArray() The following example appends all strings found in the \l QStringList passed as input: - \code - void appendList(QCborStreamWriter &writer, const QStringList &list) - { - writer.startArray(list.size()); - for (const QString &s : list) - writer.append(s); - writer.endArray(); - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 21 \b{Size limitations}: The parameter to this function is quint64, which would seem to allow up to 2\sup{64}-1 elements in the array. However, both @@ -1349,17 +1214,7 @@ bool QCborStreamWriter::endArray() The following example appends elements from the linked list of int and string pairs passed as input: - \code - void appendMap(QCborStreamWriter &writer, const QLinkedList> &list) - { - writer.startMap(); - for (const auto pair : list) { - writer.append(pair.first) - writer.append(pair.second); - } - writer.endMap(); - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 22 \sa startMap(quint64), endMap(), startArray(), QCborStreamReader::isMap(), QCborStreamReader::isLengthKnown() @@ -1384,17 +1239,7 @@ void QCborStreamWriter::startMap() The following example appends all strings found in the \l QMap passed as input: - \code - void appendMap(QCborStreamWriter &writer, const QMap &map) - { - writer.startMap(map.size()); - for (auto it = map.begin(); it != map.end(); ++it) { - writer.append(it.key()); - writer.append(it.value()); - } - writer.endMap(); - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 23 \b{Size limitations}: The parameter to this function is quint64, which would seem to allow up to 2\sup{64}-1 pairs in the map. However, both @@ -1475,33 +1320,7 @@ bool QCborStreamWriter::endMap() So a processor function typically looks like this: - \code - void handleStream(QCborStreamReader &reader) - { - switch (reader.type()) - case QCborStreamReader::UnsignedInteger: - case QCborStreamReader::NegativeInteger: - case QCborStreamReader::SimpleType: - case QCborStreamReader::Float16: - case QCborStreamReader::Float: - case QCborStreamReader::Double: - handleFixedWidth(reader); - reader.next(); - break; - case QCborStreamReader::ByteArray: - case QCborStreamReader::String: - handleString(reader); - break; - case QCborStreamReader::Array: - case QCborStreamReader::Map: - reader.enterContainer(); - while (reader.lastError() == QCborError::NoError) - handleStream(reader); - if (reader.lastError() == QCborError::NoError) - reader.leaveContainer(); - } - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 24 \section1 CBOR support @@ -1717,20 +1536,7 @@ bool QCborStreamWriter::endMap() The following example pre-allocates a QVariantList given the array's size for more efficient decoding: - \code - QVariantList populateFromCbor(QCborStreamReader &reader) - { - QVariantList list; - if (reader.isLengthKnown()) - list.reserve(reader.length()); - - reader.enterContainer(); - while (reader.lastError() == QCborError::NoError && reader.hasNext()) - list.append(readOneElement(reader)); - if (reader.lastError() == QCborError::NoError) - reader.leaveContainer(); - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 25 \note The code above does not validate that the length is a sensible value. If the input stream reports that the length is 1 billion elements, the above @@ -1754,22 +1560,7 @@ bool QCborStreamWriter::endMap() The following example pre-allocates a QVariantMap given the map's size for more efficient decoding: - \code - QVariantMap populateFromCbor(QCborStreamReader &reader) - { - QVariantMap map; - if (reader.isLengthKnown()) - map.reserve(reader.length()); - - reader.enterContainer(); - while (reader.lastError() == QCborError::NoError && reader.hasNext()) { - QString key = readElementAsString(reader); - map.insert(key, readOneElement(reader)); - } - if (reader.lastError() == QCborError::NoError) - reader.leaveContainer(); - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 26 The example above uses a function called \c readElementAsString to read the map's keys and obtain a string. That is because CBOR maps may contain any @@ -2702,23 +2493,7 @@ bool QCborStreamReader::leaveContainer() always loop around calling this function, even if isLengthKnown() has is true. The typical use of this function is as follows: - \code - QString decodeString(QCborStreamReader &reader) - { - QString result; - auto r = reader.readString(); - while (r.code == QCborStreamReader::Ok) { - result += r.data; - r = reader.readString(); - } - - if (r.code == QCborStreamReader::Error) { - // handle error condition - result.clear(); - } - return result; - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 27 This function does not perform any type conversions, including from integers or from byte arrays. Therefore, it may only be called if isString() returned @@ -2754,23 +2529,7 @@ QCborStreamReader::StringResult QCborStreamReader::_readString_helper() always loop around calling this function, even if isLengthKnown() has is true. The typical use of this function is as follows: - \code - QBytearray decodeBytearray(QCborStreamReader &reader) - { - QBytearray result; - auto r = reader.readBytearray(); - while (r.code == QCborStreamReader::Ok) { - result += r.data; - r = reader.readByteArray(); - } - - if (r.code == QCborStreamReader::Error) { - // handle error condition - result.clear(); - } - return result; - } - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 28 This function does not perform any type conversions, including from integers or from strings. Therefore, it may only be called if isByteArray() is true; @@ -2840,15 +2599,7 @@ qsizetype QCborStreamReader::_currentStringChunkSize() const This function is usually used alongside currentStringChunkSize() in a loop. For example: - \code - QCborStreamReader result; - do { - qsizetype size = reader.currentStringChunkSize(); - qsizetype oldsize = buffer.size(); - buffer.resize(oldsize + size); - result = reader.readStringChunk(buffer.data() + oldsize, size); - } while (result.status() == QCborStreamReader::Ok); - \endcode + \snippet code/src_corelib_serialization_qcborstream.cpp 29 Unlike readByteArray() and readString(), this function is not limited by implementation limits of QByteArray and QString. diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp index 81ea1ed3b2..5d97a6a06a 100644 --- a/src/corelib/serialization/qcborvalue.cpp +++ b/src/corelib/serialization/qcborvalue.cpp @@ -102,9 +102,7 @@ QT_BEGIN_NAMESPACE Qt types compare equal to the tag type of the same contents. In other words, the following expression is true: - \code - QCborValue(uuid) == QCborValue(QCborKnownTags::Uuid, uuid.toRfc4122()); - \endcode + \snippet code/src_corelib_serialization_qcborvalue.cpp 0 \section1 Undefined and null values @@ -429,9 +427,7 @@ QT_BEGIN_NAMESPACE This function can be used with simple types not defined in the API. For example, to create a QCborValue with simple type 12, one could write: - \code - QCborValue value(QCborSimpleType(12)); - \endcode + \snippet code/src_corelib_serialization_qcborvalue.cpp 1 Simple types should not be used until a specification for them has been published, since other implementations may not support them properly. @@ -702,9 +698,7 @@ QT_BEGIN_NAMESPACE any CBOR simple type, even those for which there is no enumeration in the API. For example, for the simple type of value 12, you could write: - \code - value.isSimpleType(QCborSimpleType(12)); - \endcode + \snippet code/src_corelib_serialization_qcborvalue.cpp 2 \sa QCborValue::QCborValue(QCborSimpleType), isSimpleType(), isFalse(), isTrue(), isNull, isUndefined(), toSimpleType() @@ -1163,9 +1157,7 @@ inline int QCborContainerPrivate::compareElement_helper(const QCborContainerPriv \l{Type}{Url} and \l{Type}{Url} and its equivalent tagged representation. So, for example, the following expression is true: - \code - QCborValue(QUrl("https://example.com")) == QCborValue(QCborKnownTags::Url, "https://example.com"); - \endcode + \snippet code/src_corelib_serialization_qcborvalue.cpp 3 Do note that Qt types like \l QUrl and \l QDateTime will normalize and otherwise modify their arguments. The expression above is true only because @@ -2047,9 +2039,7 @@ QCborMap QCborValue::toMap(const QCborMap &defaultValue) const This function is equivalent to: - \code - value.toMap().value(key); - \endcode + \snippet code/src_corelib_serialization_qcborvalue.cpp 4 \sa operator[](qint64), QCborMap::operator[], QCborMap::value(), QCborMap::find() @@ -2070,9 +2060,7 @@ const QCborValue QCborValue::operator[](const QString &key) const This function is equivalent to: - \code - value.toMap().value(key); - \endcode + \snippet code/src_corelib_serialization_qcborvalue.cpp 5 \sa operator[](qint64), QCborMap::operator[], QCborMap::value(), QCborMap::find() @@ -2113,12 +2101,7 @@ const QCborValue QCborValue::operator[](qint64 key) const QCborStreamReader. For example, the following code illustrates how to skip the CBOR signature tag from the beginning of a file: - \code - if (reader.isTag() && reader.toTag() == QCborKnownTags::Signature) - reader.next(); - - QCborValue contents = QCborValue::fromCbor(reader); - \endcode + \snippet code/src_corelib_serialization_qcborvalue.cpp 6 The returned value may be partially complete and indistinguishable from a valid QCborValue even if the decoding failed. To determine if there was an diff --git a/src/corelib/serialization/qdatastream.cpp b/src/corelib/serialization/qdatastream.cpp index c81da70e61..951f6c9736 100644 --- a/src/corelib/serialization/qdatastream.cpp +++ b/src/corelib/serialization/qdatastream.cpp @@ -170,18 +170,12 @@ QT_BEGIN_NAMESPACE will have appropriate stream operators declared as non-member of the class: - \code - QDataStream &operator<<(QDataStream &, const QXxx &); - QDataStream &operator>>(QDataStream &, QXxx &); - \endcode + \snippet code/src_corelib_serialization_qdatastream.cpp 0 For example, here are the stream operators declared as non-members of the QImage class: - \code - QDataStream & operator<< (QDataStream& stream, const QImage& image); - QDataStream & operator>> (QDataStream& stream, QImage& image); - \endcode + \snippet code/src_corelib_serialization_qdatastream.cpp 1 To see if your favorite Qt class has similar stream operators defined, check the \b {Related Non-Members} section of the diff --git a/src/corelib/serialization/qjsondocument.cpp b/src/corelib/serialization/qjsondocument.cpp index 5018f7c267..0cd86d3ded 100644 --- a/src/corelib/serialization/qjsondocument.cpp +++ b/src/corelib/serialization/qjsondocument.cpp @@ -350,22 +350,10 @@ QByteArray QJsonDocument::toJson() const when converting to a QJsonDocument using toJson(). \value Indented Defines human readable output as follows: - \code - { - "Array": [ - true, - 999, - "string" - ], - "Key": "Value", - "null": null - } - \endcode + \snippet code/src_corelib_serialization_qjsondocument.cpp 0 \value Compact Defines a compact output as follows: - \code - {"Array":[true,999,"string"],"Key":"Value","null":null} - \endcode + \snippet code/src_corelib_serialization_qjsondocument.cpp 1 */ /*! diff --git a/src/corelib/thread/qsemaphore.cpp b/src/corelib/thread/qsemaphore.cpp index bb578ff617..aa04fb10ff 100644 --- a/src/corelib/thread/qsemaphore.cpp +++ b/src/corelib/thread/qsemaphore.cpp @@ -515,10 +515,7 @@ bool QSemaphore::tryAcquire(int n, int timeout) You can use this to reliably release a semaphore to avoid dead-lock in the face of exceptions or early returns: - \code - // ... do something that may throw or return early - sem.release(); - \endcode + \snippet code/src_corelib_thread_qsemaphore.cpp 4 If an early return is taken or an exception is thrown before the \c{sem.release()} call is reached, the semaphore is not released, @@ -527,11 +524,7 @@ bool QSemaphore::tryAcquire(int n, int timeout) When using RAII instead: - \code - const QSemaphoreReleaser releaser(sem); - // ... do something that may throw or early return - // implicitly calls sem.release() here and at every other return in between - \endcode + \snippet code/src_corelib_thread_qsemaphore.cpp 5 this can no longer happen, because the compiler will make sure that the QSemaphoreReleaser destructor is always called, and therefore @@ -541,17 +534,7 @@ bool QSemaphore::tryAcquire(int n, int timeout) from functions to transfer responsibility for releasing a semaphore out of a function or a scope: - \code - { // some scope - QSemaphoreReleaser releaser; // does nothing - // ... - if (someCondition) { - releaser = QSemaphoreReleaser(sem); - // ... - } - // ... - } // conditionally calls sem.release(), depending on someCondition - \endcode + \snippet code/src_corelib_thread_qsemaphore.cpp 6 A QSemaphoreReleaser can be canceled by a call to cancel(). A canceled semaphore releaser will no longer call QSemaphore::release() in its @@ -635,11 +618,7 @@ bool QSemaphore::tryAcquire(int n, int timeout) To enable again, assign a new QSemaphoreReleaser: - \code - releaser.cancel(); // avoid releasing old semaphore() - releaser = QSemaphoreReleaser(sem, 42); - // now will call sem.release(42) when 'releaser' is destroyed - \endcode + \snippet code/src_corelib_thread_qsemaphore.cpp 7 */ diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index b53a60b9bf..8f2ad8c012 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -2655,10 +2655,7 @@ QList QByteArray::split(char sep) const Example: - \code - QByteArray ba("ab"); - ba.repeated(4); // returns "abababab" - \endcode + \snippet code/src_corelib_tools_qbytearray.cpp 49 */ QByteArray QByteArray::repeated(int times) const { @@ -4732,11 +4729,7 @@ QByteArray QByteArray::toHex() const If \a separator is not '\0', the separator character is inserted between the hex bytes. Example: - \code - QByteArray macAddress = QByteArray::fromHex("123456abcdef"); - macAddress.toHex(':'); // returns "12:34:56:ab:cd:ef" - macAddress.toHex(0); // returns "123456abcdef" - \endcode + \snippet code/src_corelib_tools_qbytearray.cpp 50 \sa fromHex() */ @@ -4812,10 +4805,7 @@ void q_fromPercentEncoding(QByteArray *ba) another (for instance, '_' or '='). For example: - \code - QByteArray text = QByteArray::fromPercentEncoding("Qt%20is%20great%33"); - text.data(); // returns "Qt is great!" - \endcode + \snippet code/src_corelib_tools_qbytearray.cpp 51 \note Given invalid input (such as a string containing the sequence "%G5", which is not a valid hexadecimal number) the output will be invalid as @@ -4937,12 +4927,7 @@ void q_normalizePercentEncoding(QByteArray *ba, const char *exclude) Example: - \code - QByteArray text = "{a fishy string?}"; - QByteArray ba = text.toPercentEncoding("{}", "s"); - qDebug(ba.constData()); - // prints "{a fi%73hy %73tring%3F}" - \endcode + \snippet code/src_corelib_tools_qbytearray.cpp 52 The hex encoding uses the numbers 0-9 and the uppercase letters A-F. @@ -5060,9 +5045,7 @@ QByteArray QByteArray::toPercentEncoding(const QByteArray &exclude, const QByteA For instance: - \code - QByteArray ba = QByteArrayLiteral("byte array contents"); - \endcode + \snippet code/src_corelib_tools_qbytearray.cpp 53 Using QByteArrayLiteral instead of a double quoted plain C++ string literal can significantly speed up creation of QByteArray instances from data known diff --git a/src/corelib/tools/qbytearraymatcher.cpp b/src/corelib/tools/qbytearraymatcher.cpp index a54afc5a9d..72f0e0519d 100644 --- a/src/corelib/tools/qbytearraymatcher.cpp +++ b/src/corelib/tools/qbytearraymatcher.cpp @@ -356,9 +356,7 @@ int qFindByteArray( value of that function in a \c{static const auto} variable, so you don't need to pass the \c{N} template parameter explicitly: - \code - static const auto matcher = qMakeStaticByteArrayMatcher("needle"); - \endcode + \snippet code/src_corelib_tools_qbytearraymatcher.cpp 0 Then call indexIn() on the QByteArray in which you want to search, just like with QByteArrayMatcher. @@ -430,9 +428,7 @@ int QStaticByteArrayMatcherBase::indexOfIn(const char *needle, uint nlen, const To take full advantage of this function, assign the result to an \c{auto} variable: - \code - static const auto matcher = qMakeStaticByteArrayMatcher("needle"); - \endcode + \snippet code/src_corelib_tools_qbytearraymatcher.cpp 1 */ diff --git a/src/corelib/tools/qcontiguouscache.cpp b/src/corelib/tools/qcontiguouscache.cpp index 2ded61c0be..64cbd7df4b 100644 --- a/src/corelib/tools/qcontiguouscache.cpp +++ b/src/corelib/tools/qcontiguouscache.cpp @@ -91,19 +91,7 @@ void QContiguousCacheData::freeData(QContiguousCacheData *data) The simplest way of using a contiguous cache is to use the append() and prepend(). -\code -MyRecord record(int row) const -{ - Q_ASSERT(row >= 0 && row < count()); - - while(row > cache.lastIndex()) - cache.append(slowFetchRecord(cache.lastIndex()+1)); - while(row < cache.firstIndex()) - cache.prepend(slowFetchRecord(cache.firstIndex()-1)); - - return cache.at(row); -} -\endcode + \snippet code/src_corelib_tools_qcontiguouscache.cpp 0 If the cache is full then the item at the opposite end of the cache from where the new item is appended or prepended will be removed. @@ -463,12 +451,7 @@ MyRecord record(int row) const It is provided so that index overflows can be corrected when using the cache as a circular buffer. - \code - QContiguousCache cache(10); - cache.insert(INT_MAX, 1); // cache contains one value and has valid indexes, INT_MAX to INT_MAX - cache.append(2); // cache contains two values but does not have valid indexes. - cache.normalizeIndexes(); // cache has two values, 1 and 2. New first index will be in the range of 0 to capacity(). - \endcode + \snippet code/src_corelib_tools_qcontiguouscache.cpp 1 \sa areIndexesValid(), append(), prepend() */ diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index 8d2616865e..32e9a4269c 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -755,9 +755,7 @@ void QHashData::checkSanity() Types \c T1 and \c T2 must be supported by qHash(). \note The return type of this function is \e{not} the same as that of - \code - qHash(qMakePair(key.first, key.second), seed); - \endcode + \snippet code/src_corelib_tools_qhash.cpp 29 The two functions use different hashing algorithms; due to binary compatibility constraints, we cannot change the QPair algorithm to match the std::pair one before Qt 6. */ @@ -773,14 +771,10 @@ void QHashData::checkSanity() The return value of this function depends on the order of elements in the range. That means that - \code - {0, 1, 2} - \endcode + \snippet code/src_corelib_tools_qhash.cpp 30 and - \code - {1, 2, 0} - \endcode + \snippet code/src_corelib_tools_qhash.cpp 31 hash to \b{different} values. If order does not matter, for example for hash tables, use qHashRangeCommutative() instead. If you are hashing raw @@ -812,14 +806,10 @@ void QHashData::checkSanity() The return value of this function does not depend on the order of elements in the range. That means that - \code - {0, 1, 2} - \endcode + \snippet code/src_corelib_tools_qhash.cpp 30 and - \code - {1, 2, 0} - \endcode + \snippet code/src_corelib_tools_qhash.cpp 31 hash to the \b{same} values. If order matters, for example, for vectors and arrays, use qHashRange() instead. If you are hashing raw @@ -1177,13 +1167,7 @@ uint qHash(long double key, uint seed) Q_DECL_NOTHROW For a key type \c{K}, the qHash function must have one of these signatures: - \code - uint qHash(K key); - uint qHash(const K &key); - - uint qHash(K key, uint seed); - uint qHash(const K &key, uint seed); - \endcode + \snippet code/src_corelib_tools_qhash.cpp 32 The two-arguments overloads take an unsigned integer that should be used to seed the calculation of the hash function. This seed is provided by QHash diff --git a/src/corelib/tools/qrect.cpp b/src/corelib/tools/qrect.cpp index ad1885e8ce..6e51deebea 100644 --- a/src/corelib/tools/qrect.cpp +++ b/src/corelib/tools/qrect.cpp @@ -713,10 +713,7 @@ QRect QRect::normalized() const Q_DECL_NOTHROW Returns a copy of the rectangle that has its width and height exchanged: - \code - QRect r = {15, 51, 42, 24}; - r = r.transposed(); // r == {15, 51, 24, 42} - \endcode + \snippet code/src_corelib_tools_qrect.cpp 2 \sa QSize::transposed() */ @@ -1863,10 +1860,7 @@ QRectF QRectF::normalized() const Q_DECL_NOTHROW Returns a copy of the rectangle that has its width and height exchanged: - \code - QRectF r = {1.5, 5.1, 4.2, 2.4}; - r = r.transposed(); // r == {1.5, 5.1, 2.4, 4.2} - \endcode + \snippet code/src_corelib_tools_qrect.cpp 3 \sa QSizeF::transposed() */ diff --git a/src/corelib/tools/qregularexpression.cpp b/src/corelib/tools/qregularexpression.cpp index 1026d4ab28..fec5f620fc 100644 --- a/src/corelib/tools/qregularexpression.cpp +++ b/src/corelib/tools/qregularexpression.cpp @@ -1560,15 +1560,11 @@ int QRegularExpression::captureCount() const For instance, given the regular expression - \code - (?\d\d)-(?\d\d)-(?\d\d\d\d) (\w+) (?\w+) - \endcode + \snippet code/src_corelib_tools_qregularexpression.cpp 32 namedCaptureGroups() will return the following list: - \code - ("", "day", "month", "year", "", "name") - \endcode + \snippet code/src_corelib_tools_qregularexpression.cpp 33 which corresponds to the fact that the capturing group #0 (corresponding to the whole match) has no name, the capturing group #1 has name "day", the diff --git a/src/corelib/tools/qshareddata.cpp b/src/corelib/tools/qshareddata.cpp index f95d75c4a8..bc4291e20f 100644 --- a/src/corelib/tools/qshareddata.cpp +++ b/src/corelib/tools/qshareddata.cpp @@ -142,9 +142,7 @@ QT_BEGIN_NAMESPACE would just predeclare the private subclass \c EmployeeData in \c {employee.h} this way: - \code - class EmployeeData; - \endcode + \snippet code/src_corelib_tools_qshareddata.cpp 0 If we had done it that way here, the copy constructor shown would be required. Since the copy constructor is trivial, you might as well @@ -396,13 +394,7 @@ QT_BEGIN_NAMESPACE a template-specialization of this function for your own type, like the example below: - \code - template<> - EmployeeData *QSharedDataPointer::clone() - { - return d->clone(); - } - \endcode + \snippet code/src_corelib_tools_qshareddata.cpp 1 In the example above, the template specialization for the clone() function calls the \e {EmployeeData::clone()} virtual function. A @@ -554,10 +546,7 @@ QT_BEGIN_NAMESPACE \warning relying on such \c{static_cast} is potentially dangerous, because it allows code like this to compile: - \code - QExplicitlySharedDataPointer base(new Base); - QExplicitlySharedDataPointer derived(base); // !!! DANGER !!! - \endcode + \snippet code/src_corelib_tools_qshareddata.cpp 2 Starting from Qt 5.4 the cast is disabled by default. It is possible to enable it back by defining the diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index 2d5fd2a00e..e58d3ab6bc 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -388,44 +388,14 @@ sharedFromThis() that return a QSharedPointer and QSharedPointer, depending on constness, to \c this: - \code - class Y: public QEnableSharedFromThis - { - public: - QSharedPointer f() - { - return sharedFromThis(); - } - }; - - int main() - { - QSharedPointer p(new Y()); - QSharedPointer y = p->f(); - Q_ASSERT(p == y); // p and q must share ownership - } - \endcode + \snippet code/src_corelib_tools_qsharedpointer.cpp 0 It is also possible to get a shared pointer from an object outside of the class itself. This is especially useful in code that provides an interface to scripts, where it is currently not possible to use shared pointers. For example: - \code - class ScriptInterface : public QObject - { - Q_OBJECT - - // ... - - public slots: - void slotCalledByScript(Y *managedBySharedPointer) - { - QSharedPointer yPtr = managedBySharedPointer->sharedFromThis(); - // Some other code unrelated to scripts that expects a QSharedPointer ... - } - }; - \endcode + \snippet code/src_corelib_tools_qsharedpointer.cpp 1 */ /*! @@ -466,30 +436,13 @@ when the strong reference count drops to 0. This is useful, for instance, for calling \l {QObject::}{deleteLater()} on a QObject instead: - \code - static void doDeleteLater(MyObject *obj) - { - obj->deleteLater(); - } - - void otherFunction() - { - QSharedPointer obj = - QSharedPointer(new MyObject, doDeleteLater); - - // continue using obj - obj.clear(); // calls obj->deleteLater(); - } - \endcode + \snippet code/src_corelib_tools_qsharedpointer.cpp 2 Note that the custom deleter function will be called with a pointer to type \c X, even if the QSharedPointer template parameter \c T is not the same. It is also possible to specify a member function directly, as in: - \code - QSharedPointer obj = - QSharedPointer(new MyObject, &QObject::deleteLater); - \endcode + \snippet code/src_corelib_tools_qsharedpointer.cpp 3 \sa clear() */ @@ -618,9 +571,7 @@ Returns \c true if this object is not null. This function is suitable for use in \tt if-constructs, like: - \code - if (sharedptr) { ... } - \endcode + \snippet code/src_corelib_tools_qsharedpointer.cpp 4 \sa isNull() */ @@ -631,9 +582,7 @@ Returns \c true if this object is null. This function is suitable for use in \tt if-constructs, like: - \code - if (!sharedptr) { ... } - \endcode + \snippet code/src_corelib_tools_qsharedpointer.cpp 5 \sa isNull() */ @@ -766,9 +715,7 @@ Resets this QSharedPointer object to point to \a t instead. Equivalent to: - \code - QSharedPointer other(t); this->swap(other); - \endcode + \snippet code/src_corelib_tools_qsharedpointer.cpp 6 */ /*! @@ -777,9 +724,7 @@ Resets this QSharedPointer object to point to \a t instead, with the Deleter \a deleter. Equivalent to: - \code - QSharedPointer other(t, deleter); this->swap(other); - \endcode + \snippet code/src_corelib_tools_qsharedpointer.cpp 7 */ /*! @@ -896,9 +841,7 @@ Returns \c true if this object is not null. This function is suitable for use in \tt if-constructs, like: - \code - if (weakref) { ... } - \endcode + \snippet code/src_corelib_tools_qsharedpointer.cpp 8 Note that, due to the nature of weak references, the pointer that QWeakPointer references can become null at any moment, so @@ -914,9 +857,7 @@ Returns \c true if this object is null. This function is suitable for use in \tt if-constructs, like: - \code - if (!weakref) { ... } - \endcode + \snippet code/src_corelib_tools_qsharedpointer.cpp 9 Note that, due to the nature of weak references, the pointer that QWeakPointer references can become null at any moment, so @@ -939,9 +880,7 @@ It is ok to obtain the value of the pointer and using that value itself, like for example in debugging statements: - \code - qDebug("Tracking %p", weakref.data()); - \endcode + \snippet code/src_corelib_tools_qsharedpointer.cpp 10 However, dereferencing the pointer is only allowed if you can guarantee by external means that the pointer does not get deleted. For example, @@ -950,18 +889,7 @@ If that is the case, then the following code is valid: - \code - // this pointer cannot be used in another thread - // so other threads cannot delete it - QWeakPointer weakref = obtainReference(); - - Object *obj = weakref.data(); - if (obj) { - // if the pointer wasn't deleted yet, we know it can't get - // deleted by our own code here nor the functions we call - otherFunction(obj); - } - \endcode + \snippet code/src_corelib_tools_qsharedpointer.cpp 11 Use this function with care. @@ -986,17 +914,7 @@ to a strong reference and, if it succeeded, it prints the value of the integer that was held: - \code - QWeakPointer weakref; - - // ... - - QSharedPointer strong = weakref.toStrongRef(); - if (strong) - qDebug() << "The value is:" << *strong; - else - qDebug() << "The value has already been deleted"; - \endcode + \snippet code/src_corelib_tools_qsharedpointer.cpp 12 \sa QSharedPointer::QSharedPointer() */ diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index b3ed62982e..5a2d6b228d 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -7966,10 +7966,7 @@ QVector QString::splitRef(const QRegularExpression &re, SplitBehavio Example: - \code - QString str("ab"); - str.repeated(4); // returns "abababab" - \endcode + \snippet code/src_corelib_tools_qstring.cpp 8 */ QString QString::repeated(int times) const { @@ -12096,10 +12093,7 @@ QString QString::toHtmlEscaped() const If you have code that looks like this: - \code - // hasAttribute takes a QString argument - if (node.hasAttribute("http-contents-length")) //... - \endcode + \snippet code/src_corelib_tools_qstring.cpp 9 then a temporary QString will be created to be passed as the \c{hasAttribute} function parameter. This can be quite expensive, as it involves a memory @@ -12108,9 +12102,7 @@ QString QString::toHtmlEscaped() const This cost can be avoided by using QStringLiteral instead: - \code - if (node.hasAttribute(QStringLiteral(u"http-contents-length"))) //... - \endcode + \snippet code/src_corelib_tools_qstring.cpp 10 In this case, QString's internal data will be generated at compile time; no conversion or allocation will occur at runtime. @@ -12125,9 +12117,7 @@ QString QString::toHtmlEscaped() const instance, QString::operator==() can compare to a QLatin1String directly: - \code - if (attribute.name() == QLatin1String("http-contents-length")) //... - \endcode + \snippet code/src_corelib_tools_qstring.cpp 11 \note Some compilers have bugs encoding strings containing characters outside the US-ASCII character set. Make sure you prefix your string with \c{u} in diff --git a/src/corelib/tools/qstringview.cpp b/src/corelib/tools/qstringview.cpp index ce8fdacafb..a7d9426fa6 100644 --- a/src/corelib/tools/qstringview.cpp +++ b/src/corelib/tools/qstringview.cpp @@ -74,19 +74,14 @@ QT_BEGIN_NAMESPACE string literal. QStringViews should be passed by value, not by reference-to-const: - \code - void myfun1(QStringView sv); // preferred - void myfun2(const QStringView &sv); // compiles and works, but slower - \endcode + \snippet code/src_corelib_tools_qstringview.cpp 0 If you want to give your users maximum freedom in what strings they can pass to your function, accompany the QStringView overload with overloads for \list \li \e QChar: this overload can delegate to the QStringView version: - \code - void fun(QChar ch) { fun(QStringView(&ch, 1)); } - \endcode + \snippet code/src_corelib_tools_qstringview.cpp 1 even though, for technical reasons, QStringView cannot provide a QChar constructor by itself. \li \e QString: if you store an unmodified copy of the string and thus would @@ -291,9 +286,7 @@ QT_BEGIN_NAMESPACE If you need the full array, use the constructor from pointer and size instead: - \code - auto sv = QStringView(array, std::size(array)); // using C++17 std::size() - \endcode + \snippet code/src_corelib_tools_qstringview.cpp 2 \a string must remain valid for the lifetime of this string view object. diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index 6b48f573b2..a3f53e149b 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -1309,14 +1309,7 @@ QColor QAccessibleInterface::backgroundColor() const For example to notify about a focus change when re-implementing QWidget::setFocus, the event could be used as follows: - \code - void MyWidget::setFocus(Qt::FocusReason reason) - { - // handle custom focus setting... - QAccessibleEvent event(f, QAccessible::Focus); - QAccessible::updateAccessibility(&event); - } - \endcode + \snippet code/src_gui_accessible_qaccessible.cpp 2 To enable in process screen readers, all events must be sent after the change has happened. */ @@ -1826,14 +1819,7 @@ void QAccessibleInterface::virtual_hook(int /*id*/, void * /*data*/) Qt's QLineEdit for example has its accessibility support implemented in QAccessibleLineEdit. - \code -void *QAccessibleLineEdit::interface_cast(QAccessible::InterfaceType t) -{ - if (t == QAccessible::TextInterface) - return static_cast(this); - return QAccessibleWidget::interface_cast(t); -} - \endcode + \snippet code/src_gui_accessible_qaccessible.cpp 3 \sa QAccessible::InterfaceType, QAccessibleTextInterface, QAccessibleValueInterface, QAccessibleActionInterface, diff --git a/src/gui/doc/snippets/code/src_gui_accessible_qaccessible.cpp b/src/gui/doc/snippets/code/src_gui_accessible_qaccessible.cpp index 98d40c94f9..2fd76d08c7 100644 --- a/src/gui/doc/snippets/code/src_gui_accessible_qaccessible.cpp +++ b/src/gui/doc/snippets/code/src_gui_accessible_qaccessible.cpp @@ -51,3 +51,21 @@ //! [1] typedef QAccessibleInterface* myFactoryFunction(const QString &key, QObject *); //! [1] + +//! [2] +void MyWidget::setFocus(Qt::FocusReason reason) +{ + // handle custom focus setting... + QAccessibleEvent event(f, QAccessible::Focus); + QAccessible::updateAccessibility(&event); +} +//! [2] + +//! [3] +void *QAccessibleLineEdit::interface_cast(QAccessible::InterfaceType t) +{ + if (t == QAccessible::TextInterface) + return static_cast(this); + return QAccessibleWidget::interface_cast(t); +} +//! [3] diff --git a/src/gui/doc/snippets/code/src_gui_math3d_qquaternion.cpp b/src/gui/doc/snippets/code/src_gui_math3d_qquaternion.cpp new file mode 100644 index 0000000000..b5cd00d5aa --- /dev/null +++ b/src/gui/doc/snippets/code/src_gui_math3d_qquaternion.cpp @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QVector3D result = q.rotatedVector(vector); +//! [0] + +//! [1] + QVector3D result = (q * QQuaternion(0, vector) * q.conjugated()).vector(); +//! [1] diff --git a/src/gui/doc/snippets/code/src_gui_opengl_qopenglbuffer.cpp b/src/gui/doc/snippets/code/src_gui_opengl_qopenglbuffer.cpp new file mode 100644 index 0000000000..4a4a6fe16d --- /dev/null +++ b/src/gui/doc/snippets/code/src_gui_opengl_qopenglbuffer.cpp @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QOpenGLBuffer buffer1(QOpenGLBuffer::IndexBuffer); + buffer1.create(); + + QOpenGLBuffer buffer2 = buffer1; +//! [0] + +//! [1] + QOpenGLBuffer::release(QOpenGLBuffer::VertexBuffer); +//! [1] diff --git a/src/gui/doc/snippets/code/src_gui_opengl_qopengldebug.cpp b/src/gui/doc/snippets/code/src_gui_opengl_qopengldebug.cpp new file mode 100644 index 0000000000..4ab84deb3e --- /dev/null +++ b/src/gui/doc/snippets/code/src_gui_opengl_qopengldebug.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWidgets module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + GLenum error = GL_NO_ERROR; + do { + error = glGetError(); + if (error != GL_NO_ERROR) + // handle the error + } while (error != GL_NO_ERROR); +//! [0] + +//! [1] + QSurfaceFormat format; + // asks for a OpenGL 3.2 debug context using the Core profile + format.setMajorVersion(3); + format.setMinorVersion(2); + format.setProfile(QSurfaceFormat::CoreProfile); + format.setOption(QSurfaceFormat::DebugContext); + + QOpenGLContext *context = new QOpenGLContext; + context->setFormat(format); + context->create(); +//! [1] + +//! [2] + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + QOpenGLDebugLogger *logger = new QOpenGLDebugLogger(this); + + logger->initialize(); // initializes in the current context, i.e. ctx +//! [2] + +//! [3] + ctx->hasExtension(QByteArrayLiteral("GL_KHR_debug")) +//! [3] + +//! [4] + const QList messages = logger->loggedMessages(); + for (const QOpenGLDebugMessage &message : messages) + qDebug() << message; +//! [4] + +//! [5] + connect(logger, &QOpenGLDebugLogger::messageLogged, receiver, &LogHandler::handleLoggedMessage); + logger->startLogging(); +//! [5] + +//! [6] + QOpenGLDebugMessage message = + QOpenGLDebugMessage::createApplicationMessage(QStringLiteral("Custom message")); + + logger->logMessage(message); +//! [6] diff --git a/src/gui/doc/snippets/code/src_gui_opengl_qopenglfunctions.cpp b/src/gui/doc/snippets/code/src_gui_opengl_qopenglfunctions.cpp new file mode 100644 index 0000000000..68a20dcb7c --- /dev/null +++ b/src/gui/doc/snippets/code/src_gui_opengl_qopenglfunctions.cpp @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + class MyGLWindow : public QWindow, protected QOpenGLFunctions + { + Q_OBJECT + public: + MyGLWindow(QScreen *screen = 0); + + protected: + void initializeGL(); + void paintGL(); + + QOpenGLContext *m_context; + }; + + MyGLWindow(QScreen *screen) + : QWindow(screen), QOpenGLWidget(parent) + { + setSurfaceType(OpenGLSurface); + create(); + + // Create an OpenGL context + m_context = new QOpenGLContext; + m_context->create(); + + // Setup scene and render it + initializeGL(); + paintGL(); + } + + void MyGLWindow::initializeGL() + { + m_context->makeCurrent(this); + initializeOpenGLFunctions(); + } +//! [0] + +//! [1] + void MyGLWindow::paintGL() + { + m_context->makeCurrent(this); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, textureId); + ... + m_context->swapBuffers(this); + m_context->doneCurrent(); + } +//! [1] + +//! [2] + QOpenGLFunctions glFuncs(QOpenGLContext::currentContext()); + glFuncs.glActiveTexture(GL_TEXTURE1); +//! [2] + +//! [3] + QOpenGLFunctions *glFuncs = QOpenGLContext::currentContext()->functions(); + glFuncs->glActiveTexture(GL_TEXTURE1); +//! [3] + +//! [4] + QOpenGLFunctions funcs(QOpenGLContext::currentContext()); + bool npot = funcs.hasOpenGLFeature(QOpenGLFunctions::NPOTTextures); +//! [4] diff --git a/src/gui/doc/snippets/code/src_gui_util_qdesktopservices.cpp b/src/gui/doc/snippets/code/src_gui_util_qdesktopservices.cpp index b48e9e8610..b9a8d8d90e 100644 --- a/src/gui/doc/snippets/code/src_gui_util_qdesktopservices.cpp +++ b/src/gui/doc/snippets/code/src_gui_util_qdesktopservices.cpp @@ -68,3 +68,31 @@ mailto:user@foo.com?subject=Test&body=Just a test //! [2] QDesktopServices::openUrl(QUrl("file:///C:/Documents and Settings/All Users/Desktop", QUrl::TolerantMode)); //! [2] + +//! [3] +LSApplicationQueriesSchemes + + https + +//! [3] + +//! [4] +CFBundleURLTypes + + + CFBundleURLSchemes + + myapp + + + +//! [4] + +//! [5] +QDesktopServices::storageLocation(QDesktopServices::DataLocation) +//! [5] + +//! [6] +QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + + "/data/organization/application" +//! [6] diff --git a/src/gui/doc/snippets/code/src_gui_vulkan_qvulkanfunctions.cpp b/src/gui/doc/snippets/code/src_gui_vulkan_qvulkanfunctions.cpp new file mode 100644 index 0000000000..77c5444df5 --- /dev/null +++ b/src/gui/doc/snippets/code/src_gui_vulkan_qvulkanfunctions.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + void Window::render() + { + QVulkanInstance *inst = vulkanInstance(); + QVulkanFunctions *f = inst->functions(); + ... + VkResult err = f->vkAllocateCommandBuffers(device, &cmdBufInfo, &cmdBuf); + ... + } +//! [0] + +//! [1] + void Window::render() + { + QVulkanInstance *inst = vulkanInstance(); + QVulkanDeviceFunctions *df = inst->deviceFunctions(device); + VkResult err = df->vkAllocateCommandBuffers(device, &cmdBufInfo, &cmdBuf); + ... + } +//! [1] diff --git a/src/gui/doc/snippets/code/src_gui_vulkan_qvulkaninstance.cpp b/src/gui/doc/snippets/code/src_gui_vulkan_qvulkaninstance.cpp new file mode 100644 index 0000000000..50afe7c0ff --- /dev/null +++ b/src/gui/doc/snippets/code/src_gui_vulkan_qvulkaninstance.cpp @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + int main(int argc, char **argv) + { + QGuiApplication app(argc, argv); + + QVulkanInstance inst; + if (!inst.create()) + return 1; + + ... + window->setVulkanInstance(&inst); + window->show(); + + return app.exec(); + } +//! [0] + +//! [1] + QVulkanInstance inst; + + // Enable validation layer, if supported. Messages go to qDebug by default. + inst.setLayers(QByteArrayList() << "VK_LAYER_LUNARG_standard_validation"); + + bool ok = inst.create(); + if (!ok) + ... // Vulkan not available + if (!inst.layers().contains("VK_LAYER_LUNARG_standard_validation")) + ... // validation layer not available +//! [1] + +//! [2] + QVulkanInstance inst; + + if (inst.supportedLayers().contains("VK_LAYER_LUNARG_standard_validation")) + ... + + bool ok = inst.create(); + ... +//! [2] + +//! [3] + class VulkanWindow : public QWindow + { + public: + VulkanWindow() { + setSurfaceType(VulkanSurface); + } + + void exposeEvent(QExposeEvent *) { + if (isExposed()) { + if (!m_initialized) { + m_initialized = true; + // initialize device, swapchain, etc. + QVulkanInstance *inst = vulkanInstance(); + QVulkanFunctions *f = inst->functions(); + uint32_t devCount = 0; + f->vkEnumeratePhysicalDevices(inst->vkInstance(), &devCount, nullptr); + ... + // build the first frame + render(); + } + } + } + + bool event(QEvent *e) { + if (e->type == QEvent::UpdateRequest) + render(); + return QWindow::event(e); + } + + void render() { + ... + requestUpdate(); // render continuously + } + + private: + bool m_initialized = false; + }; + + int main(int argc, char **argv) + { + QGuiApplication app(argc, argv); + + QVulkanInstance inst; + if (!inst.create()) { + qWarning("Vulkan not available"); + return 1; + } + + VulkanWindow window; + window.showMaximized(); + + return app.exec(); + + } +//! [3] diff --git a/src/gui/doc/snippets/code/src_gui_vulkan_qvulkanwindow.cpp b/src/gui/doc/snippets/code/src_gui_vulkan_qvulkanwindow.cpp new file mode 100644 index 0000000000..65eca4a77f --- /dev/null +++ b/src/gui/doc/snippets/code/src_gui_vulkan_qvulkanwindow.cpp @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + class VulkanRenderer : public QVulkanWindowRenderer + { + public: + VulkanRenderer(QVulkanWindow *w) : m_window(w) { } + + void initResources() override + { + m_devFuncs = m_window->vulkanInstance()->deviceFunctions(m_window->device()); + ... + } + void initSwapChainResources() override { ... } + void releaseSwapChainResources() override { ... } + void releaseResources() override { ... } + + void startNextFrame() override + { + VkCommandBuffer cmdBuf = m_window->currentCommandBuffer(); + ... + m_devFuncs->vkCmdBeginRenderPass(...); + ... + m_window->frameReady(); + } + + private: + QVulkanWindow *m_window; + QVulkanDeviceFunctions *m_devFuncs; + }; + + class VulkanWindow : public QVulkanWindow + { + public: + QVulkanWindowRenderer *createRenderer() override { + return new VulkanRenderer(this); + } + }; + + int main(int argc, char *argv[]) + { + QGuiApplication app(argc, argv); + + QVulkanInstance inst; + // enable the standard validation layers, when available + inst.setLayers(QByteArrayList() << "VK_LAYER_LUNARG_standard_validation"); + if (!inst.create()) + qFatal("Failed to create Vulkan instance: %d", inst.errorCode()); + + VulkanWindow w; + w.setVulkanInstance(&inst); + w.showMaximized(); + + return app.exec(); + } +//! [0] + +//! [1] + class Renderer { + ... + VkDescriptorBufferInfo m_uniformBufInfo[QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT]; + }; + + void Renderer::startNextFrame() + { + VkDescriptorBufferInfo &uniformBufInfo(m_uniformBufInfo[m_window->currentFrame()]); + ... + } +//! [1] + +//! [2] + class Renderer { + ... + VkDescriptorBufferInfo m_uniformBufInfo[QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT]; + }; + + void Renderer::startNextFrame() + { + const int count = m_window->concurrentFrameCount(); + for (int i = 0; i < count; ++i) + m_uniformBufInfo[i] = ... + ... + } +//! [2] diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp index fe1b0425a8..899ec12eb3 100644 --- a/src/gui/math3d/qquaternion.cpp +++ b/src/gui/math3d/qquaternion.cpp @@ -325,15 +325,11 @@ void QQuaternion::normalize() Rotates \a vector with this quaternion to produce a new vector in 3D space. The following code: - \code - QVector3D result = q.rotatedVector(vector); - \endcode + \snippet code/src_gui_math3d_qquaternion.cpp 0 is equivalent to the following: - \code - QVector3D result = (q * QQuaternion(0, vector) * q.conjugated()).vector(); - \endcode + \snippet code/src_gui_math3d_qquaternion.cpp 1 */ QVector3D QQuaternion::rotatedVector(const QVector3D& vector) const { diff --git a/src/gui/opengl/qopenglbuffer.cpp b/src/gui/opengl/qopenglbuffer.cpp index 000494244d..537097c09f 100644 --- a/src/gui/opengl/qopenglbuffer.cpp +++ b/src/gui/opengl/qopenglbuffer.cpp @@ -63,12 +63,7 @@ QT_BEGIN_NAMESPACE QOpenGLBuffer objects can be copied around as a reference to the underlying OpenGL buffer object: - \code - QOpenGLBuffer buffer1(QOpenGLBuffer::IndexBuffer); - buffer1.create(); - - QOpenGLBuffer buffer2 = buffer1; - \endcode + \snippet code/src_gui_opengl_qopenglbuffer.cpp 0 QOpenGLBuffer performs a shallow copy when objects are copied in this manner, but does not implement copy-on-write semantics. The original @@ -484,9 +479,7 @@ void QOpenGLBuffer::release() been bound to the context but wants to make sure that it is released. - \code - QOpenGLBuffer::release(QOpenGLBuffer::VertexBuffer); - \endcode + \snippet code/src_gui_opengl_qopenglbuffer.cpp 1 */ void QOpenGLBuffer::release(QOpenGLBuffer::Type type) { diff --git a/src/gui/opengl/qopengldebug.cpp b/src/gui/opengl/qopengldebug.cpp index 7072db5af4..2e628a2bd5 100644 --- a/src/gui/opengl/qopengldebug.cpp +++ b/src/gui/opengl/qopengldebug.cpp @@ -89,16 +89,7 @@ QT_BEGIN_NAMESPACE call. Moreover, OpenGL errors stack up, therefore glGetError should always be used in a loop like this: - \code - - GLenum error = GL_NO_ERROR; - do { - error = glGetError(); - if (error != GL_NO_ERROR) - // handle the error - } while (error != GL_NO_ERROR); - - \endcode + \snippet code/src_gui_opengl_qopengldebug.cpp 0 If you try to clear the error stack, make sure not just keep going until GL_NO_ERROR is returned but also break on GL_CONTEXT_LOST as that error @@ -125,20 +116,7 @@ QT_BEGIN_NAMESPACE to create a debug context from Qt, you must set the QSurfaceFormat::DebugContext format option on the QSurfaceFormat used to create the QOpenGLContext object: - \code - - QSurfaceFormat format; - // asks for a OpenGL 3.2 debug context using the Core profile - format.setMajorVersion(3); - format.setMinorVersion(2); - format.setProfile(QSurfaceFormat::CoreProfile); - format.setOption(QSurfaceFormat::DebugContext); - - QOpenGLContext *context = new QOpenGLContext; - context->setFormat(format); - context->create(); - - \endcode + \snippet code/src_gui_opengl_qopengldebug.cpp 1 Note that requesting a 3.2 OpenGL Core Profile is just for the example's purposes; this class is not tied to any specific OpenGL or OpenGL ES @@ -152,24 +130,13 @@ QT_BEGIN_NAMESPACE object), and like the other OpenGL functions in Qt you \e{must} initialize it before usage by calling initialize() whilst there is a current OpenGL context: - \code - - QOpenGLContext *ctx = QOpenGLContext::currentContext(); - QOpenGLDebugLogger *logger = new QOpenGLDebugLogger(this); - - logger->initialize(); // initializes in the current context, i.e. ctx - - \endcode + \snippet code/src_gui_opengl_qopengldebug.cpp 2 Note that the \c{GL_KHR_debug} extension \e{must} be available in the context in order to access the messages logged by OpenGL. You can check the presence of this extension by calling: - \code - - ctx->hasExtension(QByteArrayLiteral("GL_KHR_debug")) - - \endcode + \snippet code/src_gui_opengl_qopengldebug.cpp 3 where \c{ctx} is a valid QOpenGLContext. If the extension is not available, initialize() will return false. @@ -179,13 +146,7 @@ QT_BEGIN_NAMESPACE OpenGL implementations keep an internal log of debug messages. Messages stored in this log can be retrieved by using the loggedMessages() function: - \code - - const QList messages = logger->loggedMessages(); - for (const QOpenGLDebugMessage &message : messages) - qDebug() << message; - - \endcode + \snippet code/src_gui_opengl_qopengldebug.cpp 4 The internal log has a limited size; when it fills up, older messages will get discarded to make room for the new incoming messages. When you call @@ -203,12 +164,7 @@ QT_BEGIN_NAMESPACE you need to connect a suitable slot to the messageLogged() signal, and start logging by calling startLogging(): - \code - - connect(logger, &QOpenGLDebugLogger::messageLogged, receiver, &LogHandler::handleLoggedMessage); - logger->startLogging(); - - \endcode + \snippet code/src_gui_opengl_qopengldebug.cpp 5 Similarly, logging can be disabled at any time by calling the stopLogging() function. @@ -259,14 +215,7 @@ QT_BEGIN_NAMESPACE \l{QOpenGLDebugMessage::}{createThirdPartyMessage()}, and then inserting it into the log by calling logMessage(): - \code - - QOpenGLDebugMessage message = - QOpenGLDebugMessage::createApplicationMessage(QStringLiteral("Custom message")); - - logger->logMessage(message); - - \endcode + \snippet code/src_gui_opengl_qopengldebug.cpp 6 Note that OpenGL implementations have a vendor-specific limit to the length of the messages that can be inserted in the debug log. You can retrieve diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp index 4f48604a88..b4ff21f3fd 100644 --- a/src/gui/opengl/qopenglfunctions.cpp +++ b/src/gui/opengl/qopenglfunctions.cpp @@ -90,65 +90,18 @@ void CLASS::init(QOpenGLContext *context) \ that need it. The recommended way to use QOpenGLFunctions is by direct inheritance: - \code - class MyGLWindow : public QWindow, protected QOpenGLFunctions - { - Q_OBJECT - public: - MyGLWindow(QScreen *screen = 0); - - protected: - void initializeGL(); - void paintGL(); - - QOpenGLContext *m_context; - }; - - MyGLWindow(QScreen *screen) - : QWindow(screen), QOpenGLWidget(parent) - { - setSurfaceType(OpenGLSurface); - create(); - - // Create an OpenGL context - m_context = new QOpenGLContext; - m_context->create(); - - // Setup scene and render it - initializeGL(); - paintGL(); - } - - void MyGLWindow::initializeGL() - { - m_context->makeCurrent(this); - initializeOpenGLFunctions(); - } - \endcode + \snippet code/src_gui_opengl_qopenglfunctions.cpp 0 The \c{paintGL()} function can then use any of the OpenGL ES 2.0 functions without explicit resolution, such as glActiveTexture() in the following example: - \code - void MyGLWindow::paintGL() - { - m_context->makeCurrent(this); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, textureId); - ... - m_context->swapBuffers(this); - m_context->doneCurrent(); - } - \endcode + \snippet code/src_gui_opengl_qopenglfunctions.cpp 1 QOpenGLFunctions can also be used directly for ad-hoc invocation of OpenGL ES 2.0 functions on all platforms: - \code - QOpenGLFunctions glFuncs(QOpenGLContext::currentContext()); - glFuncs.glActiveTexture(GL_TEXTURE1); - \endcode + \snippet code/src_gui_opengl_qopenglfunctions.cpp 2 An alternative approach is to query the context's associated QOpenGLFunctions instance. This is somewhat faster than the previous @@ -157,10 +110,7 @@ void CLASS::init(QOpenGLContext *context) \ resolving happens only once for a given context, regardless of the number of QOpenGLFunctions instances initialized for it. - \code - QOpenGLFunctions *glFuncs = QOpenGLContext::currentContext()->functions(); - glFuncs->glActiveTexture(GL_TEXTURE1); - \endcode + \snippet code/src_gui_opengl_qopenglfunctions.cpp 3 QOpenGLFunctions provides wrappers for all OpenGL ES 2.0 functions, including the common subset of OpenGL 1.x and ES @@ -175,10 +125,7 @@ void CLASS::init(QOpenGLContext *context) \ feature. For example, the following checks if non power of two textures are available: - \code - QOpenGLFunctions funcs(QOpenGLContext::currentContext()); - bool npot = funcs.hasOpenGLFeature(QOpenGLFunctions::NPOTTextures); - \endcode + \snippet code/src_gui_opengl_qopenglfunctions.cpp 4 \sa QOpenGLContext, QSurfaceFormat */ diff --git a/src/gui/util/qdesktopservices.cpp b/src/gui/util/qdesktopservices.cpp index de9d087c21..b6eac91478 100644 --- a/src/gui/util/qdesktopservices.cpp +++ b/src/gui/util/qdesktopservices.cpp @@ -187,12 +187,7 @@ void QOpenUrlHandlerRegistry::handlerDestroyed(QObject *handler) \l{https://developer.apple.com/documentation/uikit/uiapplication/1622952-canopenurl}{canOpenURL(_:)}. For example, the following lines enable URLs with the HTTPS scheme: - \code - LSApplicationQueriesSchemes - - https - - \endcode + \snippet code/src_gui_util_qdesktopservices.cpp 3 \sa setUrlHandler() */ @@ -252,17 +247,7 @@ bool QDesktopServices::openUrl(const QUrl &url) To use this function for receiving data from other apps on iOS you also need to add the custom scheme to the \c CFBundleURLSchemes list in your Info.plist file: - \code - CFBundleURLTypes - - - CFBundleURLSchemes - - myapp - - - - \endcode + \snippet code/src_gui_util_qdesktopservices.cpp 4 For more information, see the Apple Developer Documentation for \l{https://developer.apple.com/documentation/uikit/core_app/allowing_apps_and_websites_to_link_to_your_content/communicating_with_other_apps_using_custom_urls?language=objc}{Communicating with Other Apps Using Custom URLs}. @@ -346,14 +331,9 @@ void QDesktopServices::unsetUrlHandler(const QString &scheme) wasn't called, while in Qt 5 it defaults to the name of the executable. Therefore, if you still need to access the Qt 4 path (for example for data migration to Qt 5), replace - \code - QDesktopServices::storageLocation(QDesktopServices::DataLocation) - \endcode + \snippet code/src_gui_util_qdesktopservices.cpp 5 with - \code - QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + - "/data/organization/application" - \endcode + \snippet code/src_gui_util_qdesktopservices.cpp 6 (assuming an organization name and an application name were set). */ diff --git a/src/gui/vulkan/qvulkanfunctions.cpp b/src/gui/vulkan/qvulkanfunctions.cpp index c5f9616d20..73dbeb9ab6 100644 --- a/src/gui/vulkan/qvulkanfunctions.cpp +++ b/src/gui/vulkan/qvulkanfunctions.cpp @@ -66,16 +66,7 @@ QT_BEGIN_NAMESPACE The typical usage is the following: - \code - void Window::render() - { - QVulkanInstance *inst = vulkanInstance(); - QVulkanFunctions *f = inst->functions(); - ... - VkResult err = f->vkAllocateCommandBuffers(device, &cmdBufInfo, &cmdBuf); - ... - } - \endcode + \snippet code/src_gui_vulkan_qvulkanfunctions.cpp 0 \note Windowing system interface (WSI) specifics and extensions are excluded. This class only covers core Vulkan commands, with the exception @@ -118,15 +109,7 @@ QT_BEGIN_NAMESPACE The typical usage is the following: - \code - void Window::render() - { - QVulkanInstance *inst = vulkanInstance(); - QVulkanDeviceFunctions *df = inst->deviceFunctions(device); - VkResult err = df->vkAllocateCommandBuffers(device, &cmdBufInfo, &cmdBuf); - ... - } - \endcode + \snippet code/src_gui_vulkan_qvulkanfunctions.cpp 1 The QVulkanDeviceFunctions object specific to the provided VkDevice is created when QVulkanInstance::deviceFunctions() is first called with the diff --git a/src/gui/vulkan/qvulkaninstance.cpp b/src/gui/vulkan/qvulkaninstance.cpp index 8236d9625a..000c2b8caa 100644 --- a/src/gui/vulkan/qvulkaninstance.cpp +++ b/src/gui/vulkan/qvulkaninstance.cpp @@ -97,22 +97,7 @@ QT_BEGIN_NAMESPACE calling QWindow::setVulkanInstance(). Thus a typical application pattern is the following: - \code - int main(int argc, char **argv) - { - QGuiApplication app(argc, argv); - - QVulkanInstance inst; - if (!inst.create()) - return 1; - - ... - window->setVulkanInstance(&inst); - window->show(); - - return app.exec(); - } - \endcode + \snippet code/src_gui_vulkan_qvulkaninstance.cpp 0 \section1 Configuration @@ -138,31 +123,12 @@ QT_BEGIN_NAMESPACE For example, to enable the standard validation layers, one could do the following: - \code - QVulkanInstance inst; - - // Enable validation layer, if supported. Messages go to qDebug by default. - inst.setLayers(QByteArrayList() << "VK_LAYER_LUNARG_standard_validation"); - - bool ok = inst.create(); - if (!ok) - ... // Vulkan not available - if (!inst.layers().contains("VK_LAYER_LUNARG_standard_validation")) - ... // validation layer not available - \endcode + \snippet code/src_gui_vulkan_qvulkaninstance.cpp 1 Or, alternatively, to make decisions before attempting to create a Vulkan instance: - \code - QVulkanInstance inst; - - if (inst.supportedLayers().contains("VK_LAYER_LUNARG_standard_validation")) - ... - - bool ok = inst.create(); - ... - \endcode + \snippet code/src_gui_vulkan_qvulkaninstance.cpp 2 \section1 Adopting an Existing Instance @@ -229,62 +195,7 @@ QT_BEGIN_NAMESPACE The following is the basic outline of creating a Vulkan-capable QWindow: - \code - class VulkanWindow : public QWindow - { - public: - VulkanWindow() { - setSurfaceType(VulkanSurface); - } - - void exposeEvent(QExposeEvent *) { - if (isExposed()) { - if (!m_initialized) { - m_initialized = true; - // initialize device, swapchain, etc. - QVulkanInstance *inst = vulkanInstance(); - QVulkanFunctions *f = inst->functions(); - uint32_t devCount = 0; - f->vkEnumeratePhysicalDevices(inst->vkInstance(), &devCount, nullptr); - ... - // build the first frame - render(); - } - } - } - - bool event(QEvent *e) { - if (e->type == QEvent::UpdateRequest) - render(); - return QWindow::event(e); - } - - void render() { - ... - requestUpdate(); // render continuously - } - - private: - bool m_initialized = false; - }; - - int main(int argc, char **argv) - { - QGuiApplication app(argc, argv); - - QVulkanInstance inst; - if (!inst.create()) { - qWarning("Vulkan not available"); - return 1; - } - - VulkanWindow window; - window.showMaximized(); - - return app.exec(); - - } - \endcode + \snippet code/src_gui_vulkan_qvulkaninstance.cpp 3 \note In addition to expose, a well-behaving window implementation will also have to take care of additional events like resize and diff --git a/src/gui/vulkan/qvulkanwindow.cpp b/src/gui/vulkan/qvulkanwindow.cpp index 2e65ab49c5..6d12377a60 100644 --- a/src/gui/vulkan/qvulkanwindow.cpp +++ b/src/gui/vulkan/qvulkanwindow.cpp @@ -74,60 +74,7 @@ Q_LOGGING_CATEGORY(lcGuiVk, "qt.vulkan") A typical application using QVulkanWindow may look like the following: - \code - class VulkanRenderer : public QVulkanWindowRenderer - { - public: - VulkanRenderer(QVulkanWindow *w) : m_window(w) { } - - void initResources() override - { - m_devFuncs = m_window->vulkanInstance()->deviceFunctions(m_window->device()); - ... - } - void initSwapChainResources() override { ... } - void releaseSwapChainResources() override { ... } - void releaseResources() override { ... } - - void startNextFrame() override - { - VkCommandBuffer cmdBuf = m_window->currentCommandBuffer(); - ... - m_devFuncs->vkCmdBeginRenderPass(...); - ... - m_window->frameReady(); - } - - private: - QVulkanWindow *m_window; - QVulkanDeviceFunctions *m_devFuncs; - }; - - class VulkanWindow : public QVulkanWindow - { - public: - QVulkanWindowRenderer *createRenderer() override { - return new VulkanRenderer(this); - } - }; - - int main(int argc, char *argv[]) - { - QGuiApplication app(argc, argv); - - QVulkanInstance inst; - // enable the standard validation layers, when available - inst.setLayers(QByteArrayList() << "VK_LAYER_LUNARG_standard_validation"); - if (!inst.create()) - qFatal("Failed to create Vulkan instance: %d", inst.errorCode()); - - VulkanWindow w; - w.setVulkanInstance(&inst); - w.showMaximized(); - - return app.exec(); - } - \endcode + \snippet code/src_gui_vulkan_qvulkanwindow.cpp 0 As it can be seen in the example, the main patterns in QVulkanWindow usage are: @@ -2439,18 +2386,7 @@ VkFramebuffer QVulkanWindow::currentFramebuffer() const concurrentFrameCount(). Such arrays can then be indexed by the value returned from this function. - \code - class Renderer { - ... - VkDescriptorBufferInfo m_uniformBufInfo[QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT]; - }; - - void Renderer::startNextFrame() - { - VkDescriptorBufferInfo &uniformBufInfo(m_uniformBufInfo[m_window->currentFrame()]); - ... - } - \endcode + \snippet code/src_gui_vulkan_qvulkanwindow.cpp 1 \note This function must only be called from within startNextFrame() and, in case of asynchronous command generation, up until the call to frameReady(). @@ -2477,20 +2413,7 @@ int QVulkanWindow::currentFrame() const \note The value is constant for the entire lifetime of the QVulkanWindow. - \code - class Renderer { - ... - VkDescriptorBufferInfo m_uniformBufInfo[QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT]; - }; - - void Renderer::startNextFrame() - { - const int count = m_window->concurrentFrameCount(); - for (int i = 0; i < count; ++i) - m_uniformBufInfo[i] = ... - ... - } - \endcode + \snippet code/src_gui_vulkan_qvulkanwindow.cpp 2 \sa currentFrame() */ diff --git a/src/network/bearer/qnetworksession.cpp b/src/network/bearer/qnetworksession.cpp index e5562e3a0b..471d322998 100644 --- a/src/network/bearer/qnetworksession.cpp +++ b/src/network/bearer/qnetworksession.cpp @@ -323,11 +323,7 @@ void QNetworkSession::open() The following example waits up to one second for the session to be opened: - \code - session->open(); - if (session->waitForOpened(1000)) - qDebug("Open!"); - \endcode + \snippet code/src_network_bearer_qnetworksession.cpp 0 If \a msecs is -1, this function will not time out. @@ -491,20 +487,7 @@ QString QNetworkSession::errorString() const The main purpose of this key is to determine which Internet access point is used if the session is based on a \l{QNetworkConfiguration::ServiceNetwork}{ServiceNetwork}. The following code snippet highlights the difference: - \code - QNetworkConfigurationManager mgr; - QNetworkConfiguration ap = mgr.defaultConfiguration(); - QNetworkSession *session = new QNetworkSession(ap); - ... //code activates session - - QString ident = session->sessionProperty("ActiveConfiguration").toString(); - if ( ap.type() == QNetworkConfiguration::ServiceNetwork ) { - Q_ASSERT( ap.identifier() != ident ); - Q_ASSERT( ap.children().contains( mgr.configurationFromIdentifier(ident) ) ); - } else if ( ap.type() == QNetworkConfiguration::InternetAccessPoint ) { - Q_ASSERT( ap.identifier() == ident ); - } - \endcode + \snippet code/src_network_bearer_qnetworksession.cpp 1 \row \li UserChoiceConfiguration \li If the session \l isOpen() and is bound to a QNetworkConfiguration of type diff --git a/src/network/doc/snippets/code/src_network_bearer_qnetworksession.cpp b/src/network/doc/snippets/code/src_network_bearer_qnetworksession.cpp new file mode 100644 index 0000000000..b88b6d1768 --- /dev/null +++ b/src/network/doc/snippets/code/src_network_bearer_qnetworksession.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + session->open(); + if (session->waitForOpened(1000)) + qDebug("Open!"); +//! [0] + +//! [1] + QNetworkConfigurationManager mgr; + QNetworkConfiguration ap = mgr.defaultConfiguration(); + QNetworkSession *session = new QNetworkSession(ap); + ... //code activates session + + QString ident = session->sessionProperty("ActiveConfiguration").toString(); + if ( ap.type() == QNetworkConfiguration::ServiceNetwork ) { + Q_ASSERT( ap.identifier() != ident ); + Q_ASSERT( ap.children().contains( mgr.configurationFromIdentifier(ident) ) ); + } else if ( ap.type() == QNetworkConfiguration::InternetAccessPoint ) { + Q_ASSERT( ap.identifier() == ident ); + } + \endcode +//! [1] diff --git a/src/network/doc/snippets/code/src_network_kernel_qnetworkdatagram.cpp b/src/network/doc/snippets/code/src_network_kernel_qnetworkdatagram.cpp new file mode 100644 index 0000000000..f81ca97681 --- /dev/null +++ b/src/network/doc/snippets/code/src_network_kernel_qnetworkdatagram.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + void Server::readPendingDatagrams() + { + while (udpSocket->hasPendingDatagrams()) { + QNetworkDatagram datagram = udpSocket->receiveDatagram(); + QByteArray replyData = processThePayload(datagram.data()); + udpSocket->writeDatagram(datagram.makeReply(replyData)); + } + } +//! [0] + +//! [1] + udpSocket->writeDatagram(std::move(datagram).makeReply(replyData)); +//! [1] diff --git a/src/network/doc/snippets/code/src_network_kernel_qnetworkinterface.cpp b/src/network/doc/snippets/code/src_network_kernel_qnetworkinterface.cpp new file mode 100644 index 0000000000..fc7fd7814a --- /dev/null +++ b/src/network/doc/snippets/code/src_network_kernel_qnetworkinterface.cpp @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QNetworkInterface::interfaceFromName(name).index() +//! [0] + +//! [1] + QNetworkInterface::interfaceFromIndex(index).name() +//! [1] diff --git a/src/network/doc/snippets/code/src_network_ssl_qsslpresharedkeyauthenticator.cpp b/src/network/doc/snippets/code/src_network_ssl_qsslpresharedkeyauthenticator.cpp new file mode 100644 index 0000000000..22e60840a3 --- /dev/null +++ b/src/network/doc/snippets/code/src_network_ssl_qsslpresharedkeyauthenticator.cpp @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + connect(socket, &QSslSocket::preSharedKeyAuthenticationRequired, + this, &AuthManager::handlePreSharedKeyAuthentication); +//! [0] + +//! [1] + void AuthManager::handlePreSharedKeyAuthentication(QSslPreSharedKeyAuthenticator *authenticator) + { + authenticator->setIdentity("My Qt App"); + + const QByteArray key = deriveKey(authenticator->identityHint(), passphrase); + authenticator->setPreSharedKey(key); + } +//! [1] diff --git a/src/network/kernel/qnetworkdatagram.cpp b/src/network/kernel/qnetworkdatagram.cpp index 50421fa7f5..c8c87d4549 100644 --- a/src/network/kernel/qnetworkdatagram.cpp +++ b/src/network/kernel/qnetworkdatagram.cpp @@ -450,16 +450,7 @@ void QNetworkDatagram::setData(const QByteArray &data) way of responding to a datagram back to the original sender. Example: - \code - void Server::readPendingDatagrams() - { - while (udpSocket->hasPendingDatagrams()) { - QNetworkDatagram datagram = udpSocket->receiveDatagram(); - QByteArray replyData = processThePayload(datagram.data()); - udpSocket->writeDatagram(datagram.makeReply(replyData)); - } - } - \endcode + \snippet code/src_network_kernel_qnetworkdatagram.cpp 0 This function is especially convenient since it will automatically copy parameters from this datagram to the new datagram as appropriate: @@ -491,9 +482,7 @@ void QNetworkDatagram::setData(const QByteArray &data) overloads, so it is a good idea to make sure this object is rvalue, if possible, before calling makeReply, so as to make better use of move semantics. To achieve that, the example above would use: - \code - udpSocket->writeDatagram(std::move(datagram).makeReply(replyData)); - \endcode + \snippet code/src_network_kernel_qnetworkdatagram.cpp 1 */ diff --git a/src/network/kernel/qnetworkinterface.cpp b/src/network/kernel/qnetworkinterface.cpp index 75a26848a6..d43dba3e0c 100644 --- a/src/network/kernel/qnetworkinterface.cpp +++ b/src/network/kernel/qnetworkinterface.cpp @@ -798,9 +798,7 @@ QList QNetworkInterface::addressEntries() const no interface with that name. This function should produce the same result as the following code, but will probably execute faster. - \code - QNetworkInterface::interfaceFromName(name).index() - \endcode + \snippet code/src_network_kernel_qnetworkinterface.cpp 0 \sa interfaceFromName(), interfaceNameFromIndex(), QNetworkDatagram::interfaceIndex() */ @@ -858,9 +856,7 @@ QNetworkInterface QNetworkInterface::interfaceFromIndex(int index) produce the same result as the following code, but will probably execute faster. - \code - QNetworkInterface::interfaceFromIndex(index).name() - \endcode + \snippet code/src_network_kernel_qnetworkinterface.cpp 1 \sa interfaceFromIndex(), interfaceIndexFromName(), QNetworkDatagram::interfaceIndex() */ diff --git a/src/network/ssl/qsslpresharedkeyauthenticator.cpp b/src/network/ssl/qsslpresharedkeyauthenticator.cpp index 8e1313493f..3bb2719026 100644 --- a/src/network/ssl/qsslpresharedkeyauthenticator.cpp +++ b/src/network/ssl/qsslpresharedkeyauthenticator.cpp @@ -83,28 +83,13 @@ QSslPreSharedKeyAuthenticatorPrivate::QSslPreSharedKeyAuthenticatorPrivate() completing the PSK handshake. The client application needs to connect a slot to the QSslSocket::preSharedKeyAuthenticationRequired() signal: - \code - - connect(socket, &QSslSocket::preSharedKeyAuthenticationRequired, - this, &AuthManager::handlePreSharedKeyAuthentication); - - \endcode + \snippet code/src_network_ssl_qsslpresharedkeyauthenticator.cpp 0 The signal carries a QSslPreSharedKeyAuthenticator object containing the identity hint the server sent to the client, and which must be filled with the corresponding client identity and the derived key: - \code - - void AuthManager::handlePreSharedKeyAuthentication(QSslPreSharedKeyAuthenticator *authenticator) - { - authenticator->setIdentity("My Qt App"); - - const QByteArray key = deriveKey(authenticator->identityHint(), passphrase); - authenticator->setPreSharedKey(key); - } - - \endcode + \snippet code/src_network_ssl_qsslpresharedkeyauthenticator.cpp 1 \note PSK ciphersuites are supported only when using OpenSSL 1.0.1 (or greater) as the SSL backend. diff --git a/src/opengl/doc/snippets/code/src_opengl_qglbuffer.cpp b/src/opengl/doc/snippets/code/src_opengl_qglbuffer.cpp new file mode 100644 index 0000000000..c9e49826ae --- /dev/null +++ b/src/opengl/doc/snippets/code/src_opengl_qglbuffer.cpp @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtOpenGL module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QGLBuffer buffer1(QGLBuffer::IndexBuffer); + buffer1.create(); + + QGLBuffer buffer2 = buffer1; +//! [0] + +//! [1] + QGLBuffer::release(QGLBuffer::VertexBuffer); +//! [1] diff --git a/src/opengl/doc/snippets/code/src_opengl_qglfunctions.cpp b/src/opengl/doc/snippets/code/src_opengl_qglfunctions.cpp new file mode 100644 index 0000000000..673186dca9 --- /dev/null +++ b/src/opengl/doc/snippets/code/src_opengl_qglfunctions.cpp @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtOpenGL module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + class MyGLWidget : public QGLWidget, protected QGLFunctions + { + Q_OBJECT + public: + MyGLWidget(QWidget *parent = 0) : QGLWidget(parent) {} + + protected: + void initializeGL(); + void paintGL(); + }; + + void MyGLWidget::initializeGL() + { + initializeGLFunctions(); + } +//! [0] + +//! [1] + void MyGLWidget::paintGL() + { + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, textureId); + ... + } +//! [1] + +//! [2] + QGLFunctions glFuncs(QGLContext::currentContext()); + glFuncs.glActiveTexture(GL_TEXTURE1); +//! [2] + +//! [3] + QGLFunctions funcs(QGLContext::currentContext()); + bool npot = funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures); +//! [3] diff --git a/src/opengl/doc/snippets/code/src_opengl_qgraphicsshadereffect.cpp b/src/opengl/doc/snippets/code/src_opengl_qgraphicsshadereffect.cpp new file mode 100644 index 0000000000..d53b73e837 --- /dev/null +++ b/src/opengl/doc/snippets/code/src_opengl_qgraphicsshadereffect.cpp @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtOpenGL module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + static char const colorizeShaderCode[] = + "uniform lowp vec4 effectColor;\n" + "lowp vec4 customShader(lowp sampler2D imageTexture, highp vec2 textureCoords) {\n" + " vec4 src = texture2D(imageTexture, textureCoords);\n" + " float gray = dot(src.rgb, vec3(0.212671, 0.715160, 0.072169));\n" + " vec4 colorize = 1.0-((1.0-gray)*(1.0-effectColor));\n" + " return vec4(colorize.rgb, src.a);\n" + "}"; +//! [0] + +//! [1] + class ColorizeEffect : public QGraphicsShaderEffect + { + Q_OBJECT + public: + ColorizeEffect(QObject *parent = 0) + : QGraphicsShaderEffect(parent), color(Qt::black) + { + setPixelShaderFragment(colorizeShaderCode); + } + + QColor effectColor() const { return color; } + void setEffectColor(const QColor& c) + { + color = c; + setUniformsDirty(); + } + + protected: + void setUniforms(QGLShaderProgram *program) + { + program->setUniformValue("effectColor", color); + } + + private: + QColor color; + }; +//! [1] + +//! [2] + lowp vec4 customShader(lowp sampler2D imageTexture, highp vec2 textureCoords) { + return texture2D(imageTexture, textureCoords); + } +//! [2] diff --git a/src/opengl/qglbuffer.cpp b/src/opengl/qglbuffer.cpp index 200ee2499e..bb9c2affbd 100644 --- a/src/opengl/qglbuffer.cpp +++ b/src/opengl/qglbuffer.cpp @@ -60,12 +60,7 @@ QT_BEGIN_NAMESPACE QGLBuffer objects can be copied around as a reference to the underlying GL buffer object: - \code - QGLBuffer buffer1(QGLBuffer::IndexBuffer); - buffer1.create(); - - QGLBuffer buffer2 = buffer1; - \endcode + \snippet code/src_opengl_qglbuffer.cpp 0 QGLBuffer performs a shallow copy when objects are copied in this manner, but does not implement copy-on-write semantics. The original @@ -474,9 +469,7 @@ void QGLBuffer::release() been bound to the context but wants to make sure that it is released. - \code - QGLBuffer::release(QGLBuffer::VertexBuffer); - \endcode + \snippet code/src_opengl_qglbuffer.cpp 1 */ void QGLBuffer::release(QGLBuffer::Type type) { diff --git a/src/opengl/qglfunctions.cpp b/src/opengl/qglfunctions.cpp index 07e1194342..7fe7102510 100644 --- a/src/opengl/qglfunctions.cpp +++ b/src/opengl/qglfunctions.cpp @@ -62,44 +62,18 @@ QT_BEGIN_NAMESPACE that need it. The recommended way to use QGLFunctions is by direct inheritance: - \code - class MyGLWidget : public QGLWidget, protected QGLFunctions - { - Q_OBJECT - public: - MyGLWidget(QWidget *parent = 0) : QGLWidget(parent) {} - - protected: - void initializeGL(); - void paintGL(); - }; - - void MyGLWidget::initializeGL() - { - initializeGLFunctions(); - } - \endcode + \snippet code/src_opengl_qglfunctions.cpp 0 The \c{paintGL()} function can then use any of the OpenGL ES 2.0 functions without explicit resolution, such as glActiveTexture() in the following example: - \code - void MyGLWidget::paintGL() - { - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, textureId); - ... - } - \endcode + \snippet code/src_opengl_qglfunctions.cpp 1 QGLFunctions can also be used directly for ad-hoc invocation of OpenGL ES 2.0 functions on all platforms: - \code - QGLFunctions glFuncs(QGLContext::currentContext()); - glFuncs.glActiveTexture(GL_TEXTURE1); - \endcode + \snippet code/src_opengl_qglfunctions.cpp 2 QGLFunctions provides wrappers for all OpenGL ES 2.0 functions, except those like \c{glDrawArrays()}, \c{glViewport()}, and @@ -114,10 +88,7 @@ QT_BEGIN_NAMESPACE feature. For example, the following checks if non power of two textures are available: - \code - QGLFunctions funcs(QGLContext::currentContext()); - bool npot = funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures); - \endcode + \snippet code/src_opengl_qglfunctions.cpp 3 \note This class has been deprecated in favor of QOpenGLFunctions. */ diff --git a/src/opengl/qgraphicsshadereffect.cpp b/src/opengl/qgraphicsshadereffect.cpp index cf3d307d71..97b83a6b3d 100644 --- a/src/opengl/qgraphicsshadereffect.cpp +++ b/src/opengl/qgraphicsshadereffect.cpp @@ -70,48 +70,12 @@ QT_BEGIN_NAMESPACE grayscale and then applies a colorize operation using the \c effectColor value: - \code - static char const colorizeShaderCode[] = - "uniform lowp vec4 effectColor;\n" - "lowp vec4 customShader(lowp sampler2D imageTexture, highp vec2 textureCoords) {\n" - " vec4 src = texture2D(imageTexture, textureCoords);\n" - " float gray = dot(src.rgb, vec3(0.212671, 0.715160, 0.072169));\n" - " vec4 colorize = 1.0-((1.0-gray)*(1.0-effectColor));\n" - " return vec4(colorize.rgb, src.a);\n" - "}"; - \endcode + \snippet code/src_opengl_qgraphicsshadereffect.cpp 0 To use this shader code, it is necessary to define a subclass of QGraphicsShaderEffect as follows: - \code - class ColorizeEffect : public QGraphicsShaderEffect - { - Q_OBJECT - public: - ColorizeEffect(QObject *parent = 0) - : QGraphicsShaderEffect(parent), color(Qt::black) - { - setPixelShaderFragment(colorizeShaderCode); - } - - QColor effectColor() const { return color; } - void setEffectColor(const QColor& c) - { - color = c; - setUniformsDirty(); - } - - protected: - void setUniforms(QGLShaderProgram *program) - { - program->setUniformValue("effectColor", color); - } - - private: - QColor color; - }; - \endcode + \snippet code/src_opengl_qgraphicsshadereffect.cpp 1 The setUniforms() function is called when the effect is about to be used for drawing to give the subclass the opportunity to @@ -216,11 +180,7 @@ QByteArray QGraphicsShaderEffect::pixelShaderFragment() const shader program. The following is the default pixel shader fragment, which draws a pixmap with no effect applied: - \code - lowp vec4 customShader(lowp sampler2D imageTexture, highp vec2 textureCoords) { - return texture2D(imageTexture, textureCoords); - } - \endcode + \snippet code/src_opengl_qgraphicsshadereffect.cpp 2 \sa pixelShaderFragment(), setUniforms() */ diff --git a/src/plugins/doc/snippets/code/src_plugins_platforms_qnx_qqnxwindow.cpp b/src/plugins/doc/snippets/code/src_plugins_platforms_qnx_qqnxwindow.cpp new file mode 100644 index 0000000000..ce82533c3e --- /dev/null +++ b/src/plugins/doc/snippets/code/src_plugins_platforms_qnx_qqnxwindow.cpp @@ -0,0 +1,52 @@ +/*************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QQuickView *view = new QQuickView(parent); + view->create(); + QGuiApplication::platformNativeInterface()->setWindowProperty(view->handle(), "qnxWindowGroup", + group); +//! [0] + +//! [1] + QQuickView *view = new QQuickView(parent); + view->create(); + QGuiApplication::platformNativeInterface()->setWindowProperty(view->handle(), "qnxWindowGroup", + QVariant()); +//! [1] diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index 5d9eaaa3ea..2096bc789e 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -132,22 +132,12 @@ DECLARE_DEBUG_VAR(statistics) setWindowProperty function of the native interface to set the \e qnxWindowGroup property to the desired value, for example: - \code - QQuickView *view = new QQuickView(parent); - view->create(); - QGuiApplication::platformNativeInterface()->setWindowProperty(view->handle(), "qnxWindowGroup", - group); - \endcode + \snippet code/src_plugins_platforms_qnx_qqnxwindow.cpp 0 To leave the current window group, one passes a null value for the property value, for example: - \code - QQuickView *view = new QQuickView(parent); - view->create(); - QGuiApplication::platformNativeInterface()->setWindowProperty(view->handle(), "qnxWindowGroup", - QVariant()); - \endcode + \snippet code/src_plugins_platforms_qnx_qqnxwindow.cpp 1 \section1 Window Id diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 870a833b34..282540dcd9 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -2109,9 +2109,7 @@ QString QFileDialog::labelText(DialogLabel label) const strings. If you want multiple filters, separate them with ';;', for example: - \code - "Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)" - \endcode + \snippet code/src_gui_dialogs_qfiledialog.cpp 14 The \a options argument holds various options about how to run the dialog, see the QFileDialog::Option enum for more information on the flags you can @@ -2224,9 +2222,7 @@ QUrl QFileDialog::getOpenFileUrl(QWidget *parent, \a selectedFilter and \a filter may be empty strings. If you need multiple filters, separate them with ';;', for instance: - \code - "Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)" - \endcode + \snippet code/src_gui_dialogs_qfiledialog.cpp 14 The dialog's caption is set to \a caption. If \a caption is not specified then a default caption will be used. @@ -2340,9 +2336,7 @@ QList QFileDialog::getOpenFileUrls(QWidget *parent, parameters \a dir, \a selectedFilter, and \a filter may be empty strings. Multiple filters are separated with ';;'. For instance: - \code - "Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)" - \endcode + \snippet code/src_gui_dialogs_qfiledialog.cpp 14 The \a options argument holds various options about how to run the dialog, see the QFileDialog::Option enum for more information on the flags you can diff --git a/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp b/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp index 58f0ae560f..06cca37111 100644 --- a/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp +++ b/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp @@ -140,3 +140,7 @@ QFileDialog dialog(this); dialog.setMimeTypeFilters(mimeTypeFilters); dialog.exec(); //! [13] + +//! [14] +"Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)" +//! [14] diff --git a/src/widgets/doc/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp b/src/widgets/doc/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp index 8d8c63db9e..ebca9d5368 100644 --- a/src/widgets/doc/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp +++ b/src/widgets/doc/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp @@ -271,3 +271,18 @@ QRect deviceRect = xform.mapRect(rect).toAlignedRect(); view->viewport()->scroll(dx, dy, deviceRect); //! [19] +//! [20] +item->setTransform(QTransform().rotate(angle), true); +//! [20] + +//! [21] +setTransform(QTransform::fromScale(sx, sy), true); +//! [21] + +//! [22] +setTransform(QTransform().shear(sh, sv), true); +//! [22] + +//! [23] +setTransform(QTransform::fromTranslate(dx, dy), true); +//! [23] diff --git a/src/widgets/doc/snippets/code/src_gui_kernel_qformlayout.cpp b/src/widgets/doc/snippets/code/src_gui_kernel_qformlayout.cpp index eadf753ded..a2ac780a82 100644 --- a/src/widgets/doc/snippets/code/src_gui_kernel_qformlayout.cpp +++ b/src/widgets/doc/snippets/code/src_gui_kernel_qformlayout.cpp @@ -84,3 +84,51 @@ formLayout->setFieldGrowthPolicy(QFormLayout::FieldsStayAtSizeHint); formLayout->setFormAlignment(Qt::AlignHCenter | Qt::AlignTop); formLayout->setLabelAlignment(Qt::AlignLeft); //! [2] + +//! [3] +QFormLayout *flay = ...; +QPointer le = new QLineEdit; +flay->insertRow(2, "User:", le); +// later: +flay->removeRow(2); // le == nullptr at this point +//! [3] + +//! [4] +QFormLayout *flay = ...; +QPointer le = new QLineEdit; +flay->insertRow(2, "User:", le); +// later: +flay->removeRow(le); // le == nullptr at this point +//! [4] + +//! [5] +QFormLayout *flay = ...; +QPointer vbl = new QVBoxLayout; +flay->insertRow(2, "User:", vbl); +// later: +flay->removeRow(layout); // vbl == nullptr at this point +//! [5] + +//! [6] +QFormLayout *flay = ...; +QPointer le = new QLineEdit; +flay->insertRow(2, "User:", le); +// later: +QFormLayout::TakeRowResult result = flay->takeRow(2); +//! [6] + +//! [7] +QFormLayout *flay = ...; +QPointer le = new QLineEdit; +flay->insertRow(2, "User:", le); +// later: +QFormLayout::TakeRowResult result = flay->takeRow(widget); +//! [7] + +//! [8] +QFormLayout *flay = ...; +QPointer vbl = new QVBoxLayout; +flay->insertRow(2, "User:", vbl); +// later: +QFormLayout::TakeRowResult result = flay->takeRow(widget); +//! [8] diff --git a/src/widgets/doc/snippets/code/src_widgets_util_qscroller.cpp b/src/widgets/doc/snippets/code/src_widgets_util_qscroller.cpp new file mode 100644 index 0000000000..2b3d825266 --- /dev/null +++ b/src/widgets/doc/snippets/code/src_widgets_util_qscroller.cpp @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWidgets module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QWidget *w = ...; + QScroller::grabGesture(w, QScroller::LeftMouseButtonGesture); +//! [0] + +//! [1] + QWidget *w = ...; + QScroller *scroller = QScroller::scroller(w); + scroller->scrollTo(QPointF(100, 100)); +//! [1] diff --git a/src/widgets/doc/snippets/code/src_widgets_widgets_qmainwindow.cpp b/src/widgets/doc/snippets/code/src_widgets_widgets_qmainwindow.cpp new file mode 100644 index 0000000000..8ebaaf3991 --- /dev/null +++ b/src/widgets/doc/snippets/code/src_widgets_widgets_qmainwindow.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWidgets module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + void MainWindow::createMenus() + { + fileMenu = menuBar()->addMenu(tr("&File")); + fileMenu->addAction(newAct); + fileMenu->addAction(openAct); + fileMenu->addAction(saveAct); +//! [0] + +//! [1] + void MainWindow::createToolBars() + { + fileToolBar = addToolBar(tr("File")); + fileToolBar->addAction(newAct); +//! [1] + +//! [2] + resizeDocks({blueWidget, yellowWidget}, {20 , 40}, Qt::Horizontal); +//! [2] diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp index a32f1388bf..e81eab4c46 100644 --- a/src/widgets/graphicsview/qgraphicsitem.cpp +++ b/src/widgets/graphicsview/qgraphicsitem.cpp @@ -4666,9 +4666,7 @@ void QGraphicsItem::resetTransform() Use - \code - item->setTransform(QTransform().rotate(angle), true); - \endcode + \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 20 instead. @@ -4689,9 +4687,7 @@ void QGraphicsItem::resetTransform() Use - \code - setTransform(QTransform::fromScale(sx, sy), true); - \endcode + \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 21 instead. @@ -4712,9 +4708,7 @@ void QGraphicsItem::resetTransform() Use - \code - setTransform(QTransform().shear(sh, sv), true); - \endcode + \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 22 instead. @@ -4730,9 +4724,7 @@ void QGraphicsItem::resetTransform() Use setPos() or setTransformOriginPoint() instead. For identical behavior, use - \code - setTransform(QTransform::fromTranslate(dx, dy), true); - \endcode + \snippet code/src_gui_graphicsview_qgraphicsitem.cpp 23 Translates the current item transformation by (\a dx, \a dy). diff --git a/src/widgets/kernel/qformlayout.cpp b/src/widgets/kernel/qformlayout.cpp index 595ff3eb6e..66e8858e21 100644 --- a/src/widgets/kernel/qformlayout.cpp +++ b/src/widgets/kernel/qformlayout.cpp @@ -1435,13 +1435,7 @@ static void clearAndDestroyQLayoutItem(QLayoutItem *item) up one row and the freed vertical space is redistributed amongst the remaining rows. You can use this function to undo a previous addRow() or insertRow(): - \code - QFormLayout *flay = ...; - QPointer le = new QLineEdit; - flay->insertRow(2, "User:", le); - // later: - flay->removeRow(2); // le == nullptr at this point - \endcode + \snippet code/src_gui_kernel_qformlayout.cpp 3 If you want to remove the row from the layout without deleting the widgets, use takeRow() instead. @@ -1467,13 +1461,7 @@ void QFormLayout::removeRow(int row) up one row and the freed vertical space is redistributed amongst the remaining rows. You can use this function to undo a previous addRow() or insertRow(): - \code - QFormLayout *flay = ...; - QPointer le = new QLineEdit; - flay->insertRow(2, "User:", le); - // later: - flay->removeRow(le); // le == nullptr at this point - \endcode + \snippet code/src_gui_kernel_qformlayout.cpp 4 If you want to remove the row from the layout without deleting the widgets, use takeRow() instead. @@ -1499,13 +1487,7 @@ void QFormLayout::removeRow(QWidget *widget) up one row and the freed vertical space is redistributed amongst the remaining rows. You can use this function to undo a previous addRow() or insertRow(): - \code - QFormLayout *flay = ...; - QPointer vbl = new QVBoxLayout; - flay->insertRow(2, "User:", vbl); - // later: - flay->removeRow(layout); // vbl == nullptr at this point - \endcode + \snippet code/src_gui_kernel_qformlayout.cpp 5 If you want to remove the row from the form layout without deleting the inserted layout, use takeRow() instead. @@ -1532,13 +1514,7 @@ void QFormLayout::removeRow(QLayout *layout) up one row and the freed vertical space is redistributed amongst the remaining rows. You can use this function to undo a previous addRow() or insertRow(): - \code - QFormLayout *flay = ...; - QPointer le = new QLineEdit; - flay->insertRow(2, "User:", le); - // later: - QFormLayout::TakeRowResult result = flay->takeRow(2); - \endcode + \snippet code/src_gui_kernel_qformlayout.cpp 6 If you want to remove the row from the layout and delete the widgets, use removeRow() instead. @@ -1583,13 +1559,7 @@ QFormLayout::TakeRowResult QFormLayout::takeRow(int row) After this call, rowCount() is decremented by one. All following rows are shifted up one row and the freed vertical space is redistributed amongst the remaining rows. - \code - QFormLayout *flay = ...; - QPointer le = new QLineEdit; - flay->insertRow(2, "User:", le); - // later: - QFormLayout::TakeRowResult result = flay->takeRow(widget); - \endcode + \snippet code/src_gui_kernel_qformlayout.cpp 7 If you want to remove the row from the layout and delete the widgets, use removeRow() instead. @@ -1628,13 +1598,7 @@ QFormLayout::TakeRowResult QFormLayout::takeRow(QWidget *widget) After this call, rowCount() is decremented by one. All following rows are shifted up one row and the freed vertical space is redistributed amongst the remaining rows. - \code - QFormLayout *flay = ...; - QPointer vbl = new QVBoxLayout; - flay->insertRow(2, "User:", vbl); - // later: - QFormLayout::TakeRowResult result = flay->takeRow(widget); - \endcode + \snippet code/src_gui_kernel_qformlayout.cpp 8 If you want to remove the row from the form layout and delete the inserted layout, use removeRow() instead. diff --git a/src/widgets/util/qscroller.cpp b/src/widgets/util/qscroller.cpp index 28504f5631..386fc0d103 100644 --- a/src/widgets/util/qscroller.cpp +++ b/src/widgets/util/qscroller.cpp @@ -249,18 +249,11 @@ private: scrolling speed and takes care of updates. QScroller can be triggered by a flick gesture - \code - QWidget *w = ...; - QScroller::grabGesture(w, QScroller::LeftMouseButtonGesture); - \endcode + \snippet code/src_widgets_util_qscroller.cpp 0 or directly like this: - \code - QWidget *w = ...; - QScroller *scroller = QScroller::scroller(w); - scroller->scrollTo(QPointF(100, 100)); - \endcode + \snippet code/src_widgets_util_qscroller.cpp 1 The scrolled QObjects receive a QScrollPrepareEvent whenever the scroller needs to update its geometry information and a QScrollEvent whenever the content of the object should diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp index aca38884a7..411b482c11 100644 --- a/src/widgets/widgets/qmainwindow.cpp +++ b/src/widgets/widgets/qmainwindow.cpp @@ -249,14 +249,7 @@ void QMainWindowPrivate::init() An example of how to create menus follows: - \code - void MainWindow::createMenus() - { - fileMenu = menuBar()->addMenu(tr("&File")); - fileMenu->addAction(newAct); - fileMenu->addAction(openAct); - fileMenu->addAction(saveAct); - \endcode + \snippet code/src_widgets_widgets_qmainwindow.cpp 0 The \c createPopupMenu() function creates popup menus when the main window receives context menu events. The default @@ -283,12 +276,7 @@ void QMainWindowPrivate::init() An example of toolbar creation follows: - \code - void MainWindow::createToolBars() - { - fileToolBar = addToolBar(tr("File")); - fileToolBar->addAction(newAct); - \endcode + \snippet code/src_widgets_widgets_qmainwindow.cpp 1 \section2 Creating Dock Widgets @@ -1227,9 +1215,8 @@ Qt::DockWidgetArea QMainWindow::dockWidgetArea(QDockWidget *dockwidget) const to the relative weight of the sizes. Example: - \code - resizeDocks({blueWidget, yellowWidget}, {20 , 40}, Qt::Horizontal); - \endcode + \snippet code/src_widgets_widgets_qmainwindow.cpp 2 + If the blue and the yellow widget are nested on the same level they will be resized such that the yellowWidget is twice as big as the blueWidget From 793a36258dd946d5c2d2a6c10c87c40e88e4736b Mon Sep 17 00:00:00 2001 From: Cristian Maureira-Fredes Date: Tue, 4 Sep 2018 22:26:47 +0200 Subject: [PATCH 0032/1650] Fix typo vice versa Change-Id: I639d6f9d2019998d91b52506afa2cbd861a0dbe4 Reviewed-by: Gabriel de Dietrich (DO NOT ADD TO REVIEWS) --- src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc | 2 +- src/widgets/widgets/qabstractspinbox.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc index be6a068d65..43f9dda49a 100644 --- a/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc +++ b/src/widgets/doc/src/widgets-and-layouts/stylesheet.qdoc @@ -520,7 +520,7 @@ user had manually called the corresponding QWidget::setPalette() and QWidget::setFont() methods on all of the QWidgets targeted by the style sheet. If this would have caused propagation in C++, it will cause - propagation in style sheets and visa versa. + propagation in style sheets and vice versa. \section1 Widgets Inside C++ Namespaces diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp index 1eafb73ba8..4e1aa51b4b 100644 --- a/src/widgets/widgets/qabstractspinbox.cpp +++ b/src/widgets/widgets/qabstractspinbox.cpp @@ -91,7 +91,7 @@ QT_BEGIN_NAMESPACE \li \l alignment: The alignment of the text in the QAbstractSpinBox. \li \l wrapping: Whether the QAbstractSpinBox wraps from the - minimum value to the maximum value and vica versa. + minimum value to the maximum value and vice versa. \endlist @@ -285,7 +285,7 @@ void QAbstractSpinBox::setSpecialValueText(const QString &specialValueText) \brief whether the spin box is circular. If wrapping is true stepping up from maximum() value will take you - to the minimum() value and vica versa. Wrapping only make sense if + to the minimum() value and vice versa. Wrapping only make sense if you have minimum() and maximum() values set. \snippet code/src_gui_widgets_qabstractspinbox.cpp 0 From 80b1cce0cfe5d8e527731b921fd5d0c1a007afd5 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Tue, 18 Sep 2018 21:51:57 +0200 Subject: [PATCH 0033/1650] xcb: call processXcbEvents() on every event loop iteration It is necessary for QTBUG-69687. The original code processes the xcb event queue only when new events have arrived, but if we want to do an event filtering that buffers some events and processes them later based on set/unset flags (e.g. QEventLoop::ExcludeUserInputEvents), we need to call processXcbEvents() on every event loop iteration, not only when new events have arrived from X server. The required functionality is implemented by having custom event dispatchers, instead of using the generic ones from QtGenericUnixDispatcher:: createUnixEventDispatcher() / eventdispatcher_support-private. This also enables for further customizations, as might be necessary by QTBUG-70095. Task-number: QTBUG-69687 Change-Id: I1f8b2400d26cccf17279d57bb4b678e40c615f33 Reviewed-by: Gatis Paeglis --- src/plugins/platforms/xcb/qxcbconnection.h | 3 +- .../platforms/xcb/qxcbeventdispatcher.cpp | 161 ++++++++++++++++++ .../platforms/xcb/qxcbeventdispatcher.h | 117 +++++++++++++ src/plugins/platforms/xcb/qxcbeventqueue.cpp | 4 +- src/plugins/platforms/xcb/qxcbintegration.cpp | 4 +- src/plugins/platforms/xcb/qxcbintegration.h | 1 - src/plugins/platforms/xcb/xcb_qpa_lib.pro | 10 +- 7 files changed, 289 insertions(+), 11 deletions(-) create mode 100644 src/plugins/platforms/xcb/qxcbeventdispatcher.cpp create mode 100644 src/plugins/platforms/xcb/qxcbeventdispatcher.h diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 29a233496b..3fb64f01a4 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -495,12 +495,11 @@ public: QXcbGlIntegration *glIntegration() const; void flush() { xcb_flush(m_connection); } + void processXcbEvents(); protected: bool event(QEvent *e) override; - void processXcbEvents(); - private: void initializeAllAtoms(); void initializeShm(); diff --git a/src/plugins/platforms/xcb/qxcbeventdispatcher.cpp b/src/plugins/platforms/xcb/qxcbeventdispatcher.cpp new file mode 100644 index 0000000000..252c1c62e3 --- /dev/null +++ b/src/plugins/platforms/xcb/qxcbeventdispatcher.cpp @@ -0,0 +1,161 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "qxcbeventdispatcher.h" +#include "qxcbconnection.h" + +#include + +#include + +QT_BEGIN_NAMESPACE + +QXcbUnixEventDispatcher::QXcbUnixEventDispatcher(QXcbConnection *connection, QObject *parent) + : QEventDispatcherUNIX(parent) + , m_connection(connection) +{ +} + +QXcbUnixEventDispatcher::~QXcbUnixEventDispatcher() +{ +} + +bool QXcbUnixEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) +{ + const bool didSendEvents = QEventDispatcherUNIX::processEvents(flags); + m_connection->processXcbEvents(); + // The following line should not be necessary after QTBUG-70095 + return QWindowSystemInterface::sendWindowSystemEvents(flags) || didSendEvents; +} + +bool QXcbUnixEventDispatcher::hasPendingEvents() +{ + extern uint qGlobalPostedEventsCount(); + return qGlobalPostedEventsCount() || QWindowSystemInterface::windowSystemEventsQueued(); +} + +void QXcbUnixEventDispatcher::flush() +{ + if (qApp) + qApp->sendPostedEvents(); +} + +#if QT_CONFIG(glib) +struct XcbEventSource +{ + GSource source; + QXcbGlibEventDispatcher *dispatcher; + QXcbGlibEventDispatcherPrivate *dispatcher_p; + QXcbConnection *connection = nullptr; +}; + +static gboolean xcbSourcePrepare(GSource *source, gint *timeout) +{ + Q_UNUSED(timeout) + auto xcbEventSource = reinterpret_cast(source); + return xcbEventSource->dispatcher_p->wakeUpCalled; +} + +static gboolean xcbSourceCheck(GSource *source) +{ + return xcbSourcePrepare(source, nullptr); +} + +static gboolean xcbSourceDispatch(GSource *source, GSourceFunc, gpointer) +{ + auto xcbEventSource = reinterpret_cast(source); + xcbEventSource->connection->processXcbEvents(); + // The following line should not be necessary after QTBUG-70095 + QWindowSystemInterface::sendWindowSystemEvents(xcbEventSource->dispatcher->flags()); + return true; +} + +QXcbGlibEventDispatcher::QXcbGlibEventDispatcher(QXcbConnection *connection, QObject *parent) + : QEventDispatcherGlib(*new QXcbGlibEventDispatcherPrivate(), parent) +{ + Q_D(QXcbGlibEventDispatcher); + + m_xcbEventSourceFuncs.prepare = xcbSourcePrepare; + m_xcbEventSourceFuncs.check = xcbSourceCheck; + m_xcbEventSourceFuncs.dispatch = xcbSourceDispatch; + m_xcbEventSourceFuncs.finalize = nullptr; + + m_xcbEventSource = reinterpret_cast( + g_source_new(&m_xcbEventSourceFuncs, sizeof(XcbEventSource))); + + m_xcbEventSource->dispatcher = this; + m_xcbEventSource->dispatcher_p = d_func(); + m_xcbEventSource->connection = connection; + + g_source_set_can_recurse(&m_xcbEventSource->source, true); + g_source_attach(&m_xcbEventSource->source, d->mainContext); +} + +QXcbGlibEventDispatcherPrivate::QXcbGlibEventDispatcherPrivate() +{ +} + +QXcbGlibEventDispatcher::~QXcbGlibEventDispatcher() +{ + g_source_destroy(&m_xcbEventSource->source); + g_source_unref(&m_xcbEventSource->source); +} + +bool QXcbGlibEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) +{ + m_flags = flags; + return QEventDispatcherGlib::processEvents(m_flags); +} + +#endif // QT_CONFIG(glib) + +QAbstractEventDispatcher *QXcbEventDispatcher::createEventDispatcher(QXcbConnection *connection) +{ +#if QT_CONFIG(glib) + if (qEnvironmentVariableIsEmpty("QT_NO_GLIB") && QEventDispatcherGlib::versionSupported()) { + qCDebug(lcQpaXcb, "using glib dispatcher"); + return new QXcbGlibEventDispatcher(connection); + } else +#endif + { + qCDebug(lcQpaXcb, "using unix dispatcher"); + return new QXcbUnixEventDispatcher(connection); + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbeventdispatcher.h b/src/plugins/platforms/xcb/qxcbeventdispatcher.h new file mode 100644 index 0000000000..6aadd63a70 --- /dev/null +++ b/src/plugins/platforms/xcb/qxcbeventdispatcher.h @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QXCBEVENTDISPATCHER_H +#define QXCBEVENTDISPATCHER_H + +#include +#include + +#include +#if QT_CONFIG(glib) +#include +#include +#endif + +QT_BEGIN_NAMESPACE + +class QXcbConnection; + +class QXcbUnixEventDispatcher : public QEventDispatcherUNIX +{ + Q_OBJECT +public: + explicit QXcbUnixEventDispatcher(QXcbConnection *connection, QObject *parent = nullptr); + ~QXcbUnixEventDispatcher(); + bool processEvents(QEventLoop::ProcessEventsFlags flags) override; + + // Maybe some user code depends on deprecated QUnixEventDispatcherQPA:: + // hasPendingEvents() / flush() implementation, so keep it around until + // Qt 6. These methods are deprecated in QAbstractEventDispatcher. + bool hasPendingEvents() override; // ### Qt 6 remove + void flush() override; // ### Qt 6 remove + +private: + QXcbConnection *m_connection; +}; + +#if QT_CONFIG(glib) + +struct XcbEventSource; +class QXcbGlibEventDispatcherPrivate; + +class QXcbGlibEventDispatcher : public QEventDispatcherGlib +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QXcbGlibEventDispatcher) + +public: + explicit QXcbGlibEventDispatcher(QXcbConnection *connection, QObject *parent = nullptr); + ~QXcbGlibEventDispatcher(); + + bool processEvents(QEventLoop::ProcessEventsFlags flags) override; + QEventLoop::ProcessEventsFlags flags() const { return m_flags; } + +private: + XcbEventSource *m_xcbEventSource; + GSourceFuncs m_xcbEventSourceFuncs; + QEventLoop::ProcessEventsFlags m_flags; +}; + +class QXcbGlibEventDispatcherPrivate : public QEventDispatcherGlibPrivate +{ + Q_DECLARE_PUBLIC(QXcbGlibEventDispatcher) + +public: + QXcbGlibEventDispatcherPrivate(); +}; + +#endif // QT_CONFIG(glib) + +class QXcbEventDispatcher +{ +public: + static QAbstractEventDispatcher *createEventDispatcher(QXcbConnection *connection); + +private: + QXcbConnection *m_connection; +}; + +QT_END_NAMESPACE + +#endif // QXCBEVENTDISPATCHER_H diff --git a/src/plugins/platforms/xcb/qxcbeventqueue.cpp b/src/plugins/platforms/xcb/qxcbeventqueue.cpp index e530928ccb..6d8b001faa 100644 --- a/src/plugins/platforms/xcb/qxcbeventqueue.cpp +++ b/src/plugins/platforms/xcb/qxcbeventqueue.cpp @@ -76,7 +76,6 @@ QT_BEGIN_NAMESPACE QXcbEventQueue::QXcbEventQueue(QXcbConnection *connection) : m_connection(connection) { - connect(this, &QXcbEventQueue::eventsPending, m_connection, &QXcbConnection::processXcbEvents, Qt::QueuedConnection); connect(this, &QXcbEventQueue::finished, m_connection, &QXcbConnection::processXcbEvents); // Lets init the list with one node, so we don't have to check for @@ -105,8 +104,7 @@ QXcbEventQueue::~QXcbEventQueue() void QXcbEventQueue::registerEventDispatcher(QAbstractEventDispatcher *dispatcher) { - // Flush the xcb connection before the event dispatcher is going to block. - connect(dispatcher, &QAbstractEventDispatcher::aboutToBlock, m_connection, &QXcbConnection::flush); + connect(this, &QXcbEventQueue::eventsPending, dispatcher, &QAbstractEventDispatcher::wakeUp, Qt::QueuedConnection); } xcb_generic_event_t *QXcbEventQueue::takeFirst() diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index b1a1ed93cd..8f6d35dc5b 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -47,6 +47,7 @@ #include "qxcbnativeinterface.h" #include "qxcbclipboard.h" #include "qxcbeventqueue.h" +#include "qxcbeventdispatcher.h" #if QT_CONFIG(draganddrop) #include "qxcbdrag.h" #endif @@ -58,7 +59,6 @@ #include -#include #include #include @@ -343,7 +343,7 @@ bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const QAbstractEventDispatcher *QXcbIntegration::createEventDispatcher() const { - QAbstractEventDispatcher *dispatcher = createUnixEventDispatcher(); + QAbstractEventDispatcher *dispatcher = QXcbEventDispatcher::createEventDispatcher(defaultConnection()); for (int i = 0; i < m_connections.size(); i++) m_connections[i]->eventQueue()->registerEventDispatcher(dispatcher); return dispatcher; diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h index 69e49cb7f6..a8dd6402f6 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.h +++ b/src/plugins/platforms/xcb/qxcbintegration.h @@ -53,7 +53,6 @@ QT_BEGIN_NAMESPACE class QXcbConnection; class QAbstractEventDispatcher; class QXcbNativeInterface; -class QXcbScreen; class Q_XCB_EXPORT QXcbIntegration : public QPlatformIntegration { diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro index fbda8c39b9..a747b25c88 100644 --- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro +++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro @@ -5,7 +5,7 @@ DEFINES += QT_NO_FOREACH QT += \ core-private gui-private \ service_support-private theme_support-private \ - eventdispatcher_support-private fontdatabase_support-private \ + fontdatabase_support-private \ edid_support-private qtHaveModule(linuxaccessibility_support-private): \ @@ -13,6 +13,8 @@ qtHaveModule(linuxaccessibility_support-private): \ qtConfig(vulkan): QT += vulkan_support-private +qtConfig(glib) : QMAKE_USE_PRIVATE += glib + SOURCES = \ qxcbclipboard.cpp \ qxcbconnection.cpp \ @@ -28,7 +30,8 @@ SOURCES = \ qxcbimage.cpp \ qxcbxsettings.cpp \ qxcbsystemtraytracker.cpp \ - qxcbeventqueue.cpp + qxcbeventqueue.cpp \ + qxcbeventdispatcher.cpp HEADERS = \ qxcbclipboard.h \ @@ -47,7 +50,8 @@ HEADERS = \ qxcbxsettings.h \ qxcbsystemtraytracker.h \ qxcbxkbcommon.h \ - qxcbeventqueue.h + qxcbeventqueue.h \ + qxcbeventdispatcher.h qtConfig(draganddrop) { SOURCES += qxcbdrag.cpp From 4aa86d38ef9cf852db987bc4d560746363a705b8 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Wed, 19 Sep 2018 09:50:05 +0200 Subject: [PATCH 0034/1650] xcb: utilize thread-safety of QAbstractEventDispatcher::wakeUp QAbstractEventDispatcher::wakeUp is a thread-safe method, using a queued connection to invoke it is wasteful. This type of connection involves allocating temporary QMetaCallEvent on a heap and locking of destination thread's post-event queue. In most use cases this is ok, and really convenient when target method is not thread-safe. But in this case the existing solution was suboptimal, especially because the events we are reading can be high frequency. The solution that we use here is lock-free. There can be only one time when it might need to wait for the lock, which is upon exiting the application. If we have entered the critical section in QXcbEventReader::run(), then the registered post routine (qAddPostRoutine) will block the QCoreApplication's dtor (this is where dispatcher is set to 0) until we exit the critical section. We also know when not to enter the critical section, in case dtor is already running. With this approach we might need to compete for the lock at most once, instead of whole application lifetime, which was the case with the existing code. Change-Id: If6737329c972347b0050d67658e28dbaa6f552e8 Reviewed-by: Thiago Macieira --- src/plugins/platforms/xcb/qxcbeventqueue.cpp | 27 ++++++++++++++----- src/plugins/platforms/xcb/qxcbeventqueue.h | 4 --- src/plugins/platforms/xcb/qxcbintegration.cpp | 5 +--- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbeventqueue.cpp b/src/plugins/platforms/xcb/qxcbeventqueue.cpp index 6d8b001faa..5bd4e7a68a 100644 --- a/src/plugins/platforms/xcb/qxcbeventqueue.cpp +++ b/src/plugins/platforms/xcb/qxcbeventqueue.cpp @@ -40,11 +40,16 @@ #include "qxcbconnection.h" #include +#include #include +#include #include QT_BEGIN_NAMESPACE +static QBasicMutex qAppExiting; +static bool dispatcherOwnerDestructing = false; + /*! \class QXcbEventQueue \internal @@ -78,6 +83,15 @@ QXcbEventQueue::QXcbEventQueue(QXcbConnection *connection) { connect(this, &QXcbEventQueue::finished, m_connection, &QXcbConnection::processXcbEvents); + // When running test cases in auto tests, static variables are preserved + // between test function runs, even if Q*Application object is destroyed. + // Reset to default value to account for this. + dispatcherOwnerDestructing = false; + qAddPostRoutine([]() { + QMutexLocker locker(&qAppExiting); + dispatcherOwnerDestructing = true; + }); + // Lets init the list with one node, so we don't have to check for // this special case in various places. m_head = m_flushedTail = qXcbEventNodeFactory(nullptr); @@ -102,11 +116,6 @@ QXcbEventQueue::~QXcbEventQueue() qCDebug(lcQpaEventReader) << "nodes on heap:" << m_nodesOnHeap; } -void QXcbEventQueue::registerEventDispatcher(QAbstractEventDispatcher *dispatcher) -{ - connect(this, &QXcbEventQueue::eventsPending, dispatcher, &QAbstractEventDispatcher::wakeUp, Qt::QueuedConnection); -} - xcb_generic_event_t *QXcbEventQueue::takeFirst() { if (isEmpty()) @@ -191,7 +200,13 @@ void QXcbEventQueue::run() while (!m_closeConnectionDetected && (event = xcb_poll_for_queued_event(connection))) enqueueEvent(event); - emit eventsPending(); + QMutexLocker locker(&qAppExiting); + if (!dispatcherOwnerDestructing) { + // This thread can run before a dispatcher has been created, + // so check if it is ready. + if (QCoreApplication::eventDispatcher()) + QCoreApplication::eventDispatcher()->wakeUp(); + } } } diff --git a/src/plugins/platforms/xcb/qxcbeventqueue.h b/src/plugins/platforms/xcb/qxcbeventqueue.h index 5b0d8bf3d6..bec2a6a201 100644 --- a/src/plugins/platforms/xcb/qxcbeventqueue.h +++ b/src/plugins/platforms/xcb/qxcbeventqueue.h @@ -80,8 +80,6 @@ public: void run() override; - void registerEventDispatcher(QAbstractEventDispatcher *dispatcher); - bool isEmpty() const { return m_head == m_flushedTail && !m_head->event; } xcb_generic_event_t *takeFirst(); void flushBufferedEvents(); @@ -101,8 +99,6 @@ public: using PeekerCallback = bool (*)(xcb_generic_event_t *event, void *peekerData); bool peekEventQueue(PeekerCallback peeker, void *peekerData = nullptr, PeekOptions option = PeekDefault, qint32 peekerId = -1); -signals: - void eventsPending(); private: QXcbEventNode *qXcbEventNodeFactory(xcb_generic_event_t *event); diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 8f6d35dc5b..d030b22fc8 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -343,10 +343,7 @@ bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const QAbstractEventDispatcher *QXcbIntegration::createEventDispatcher() const { - QAbstractEventDispatcher *dispatcher = QXcbEventDispatcher::createEventDispatcher(defaultConnection()); - for (int i = 0; i < m_connections.size(); i++) - m_connections[i]->eventQueue()->registerEventDispatcher(dispatcher); - return dispatcher; + return QXcbEventDispatcher::createEventDispatcher(defaultConnection()); } void QXcbIntegration::initialize() From 03b1380613d581863727a76db62dca974b55682b Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Tue, 7 Aug 2018 18:09:25 +0200 Subject: [PATCH 0035/1650] xcb: cleanup WM_HINTS handling - The only place where window flag Qt::WindowDoesNotAcceptFocus changes is inside QXcbWindow::setWindowFlags and from there we call updateDoesNotAcceptFocus(). The current code was redundantly calling xcb_wm_hints_set_input in various places. - Similar as above: call xcb_wm_hints_set_normal/iconic only where it can change. This hint depends on window state, so update it only from setWindowState(). Removed unnecessary call to setTransparentForMouseEvents(), which is already called few lines above from setWindowFlags(). Change-Id: I8da919b135a4dfda0c8c1dad51d85d3e706153ab Reviewed-by: Allan Sandfeld Jensen --- src/plugins/platforms/xcb/qxcbwindow.cpp | 36 +++++++++--------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 772309c6ae..f36bb5a51e 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -499,12 +499,10 @@ void QXcbWindow::create() clientMachine.size(), clientMachine.constData()); } + // Create WM_HINTS property on the window, so we can xcb_get_wm_hints*() + // from various setter functions for adjusting the hints. xcb_wm_hints_t hints; memset(&hints, 0, sizeof(hints)); - xcb_wm_hints_set_normal(&hints); - - xcb_wm_hints_set_input(&hints, !(window()->flags() & Qt::WindowDoesNotAcceptFocus)); - xcb_set_wm_hints(xcb_connection(), m_window, &hints); xcb_window_t leader = connection()->clientLeader(); @@ -532,9 +530,6 @@ void QXcbWindow::create() setWindowFlags(window()->flags()); setWindowTitle(window()->title()); - if (window()->flags() & Qt::WindowTransparentForInput) - setTransparentForMouseEvents(true); - #if QT_CONFIG(xcb_xlib) // force sync to read outstanding requests - see QTBUG-29106 XSync(static_cast(platformScreen->connection()->xlib_display()), false); @@ -739,20 +734,6 @@ void QXcbWindow::show() { if (window()->isTopLevel()) { - xcb_get_property_cookie_t cookie = xcb_get_wm_hints_unchecked(xcb_connection(), m_window); - - xcb_wm_hints_t hints; - xcb_get_wm_hints_reply(xcb_connection(), cookie, &hints, NULL); - - if (window()->windowStates() & Qt::WindowMinimized) - xcb_wm_hints_set_iconic(&hints); - else - xcb_wm_hints_set_normal(&hints); - - xcb_wm_hints_set_input(&hints, !(window()->flags() & Qt::WindowDoesNotAcceptFocus)); - - xcb_set_wm_hints(xcb_connection(), m_window, &hints); - // update WM_NORMAL_HINTS propagateSizeHints(); @@ -1230,6 +1211,16 @@ void QXcbWindow::setWindowState(Qt::WindowStates state) changeNetWmState(state & Qt::WindowFullScreen, atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN)); } + xcb_get_property_cookie_t cookie = xcb_get_wm_hints_unchecked(xcb_connection(), m_window); + xcb_wm_hints_t hints; + if (xcb_get_wm_hints_reply(xcb_connection(), cookie, &hints, nullptr)) { + if (state & Qt::WindowMinimized) + xcb_wm_hints_set_iconic(&hints); + else + xcb_wm_hints_set_normal(&hints); + xcb_set_wm_hints(xcb_connection(), m_window, &hints); + } + connection()->sync(); m_windowState = state; } @@ -1402,9 +1393,8 @@ void QXcbWindow::updateDoesNotAcceptFocus(bool doesNotAcceptFocus) xcb_get_property_cookie_t cookie = xcb_get_wm_hints_unchecked(xcb_connection(), m_window); xcb_wm_hints_t hints; - if (!xcb_get_wm_hints_reply(xcb_connection(), cookie, &hints, NULL)) { + if (!xcb_get_wm_hints_reply(xcb_connection(), cookie, &hints, nullptr)) return; - } xcb_wm_hints_set_input(&hints, !doesNotAcceptFocus); xcb_set_wm_hints(xcb_connection(), m_window, &hints); From 8727bbd800ec7128442c959d5e53ce0272e5819b Mon Sep 17 00:00:00 2001 From: Miguel Costa Date: Tue, 16 Oct 2018 00:59:39 +0200 Subject: [PATCH 0036/1650] Fix build failed with ANGLE Added eglext_angle.h and gl2ext_angle.h to the list of header files copied to include/QtANGLE during install. These two header files were introduced by the recent ANGLE update but were not added to the install. This was causing build failures when including the ANGLE headers (e.g. in qtmultimedia). Task-number: QTBUG-71158 Change-Id: If2f1a9ecfcdf509cccf2b3671adf575cc39892d4 Reviewed-by: Andre de la Rocha Reviewed-by: Oliver Wolff --- src/angle/src/common/gles_common.pri | 1 + src/angle/src/libEGL/libEGL.pro | 1 + sync.profile | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/angle/src/common/gles_common.pri b/src/angle/src/common/gles_common.pri index e32fd0ea01..fdd0e45971 100644 --- a/src/angle/src/common/gles_common.pri +++ b/src/angle/src/common/gles_common.pri @@ -766,6 +766,7 @@ khr_headers.path = $$[QT_INSTALL_HEADERS]/QtANGLE/KHR gles2_headers.files = \ $$ANGLE_DIR/include/GLES2/gl2.h \ $$ANGLE_DIR/include/GLES2/gl2ext.h \ + $$ANGLE_DIR/include/GLES2/gl2ext_angle.h \ $$ANGLE_DIR/include/GLES2/gl2platform.h gles2_headers.path = $$[QT_INSTALL_HEADERS]/QtANGLE/GLES2 gles3_headers.files = \ diff --git a/src/angle/src/libEGL/libEGL.pro b/src/angle/src/libEGL/libEGL.pro index 9e9c639002..889f39890e 100644 --- a/src/angle/src/libEGL/libEGL.pro +++ b/src/angle/src/libEGL/libEGL.pro @@ -21,6 +21,7 @@ SOURCES += \ egl_headers.files = \ $$ANGLE_DIR/include/EGL/egl.h \ $$ANGLE_DIR/include/EGL/eglext.h \ + $$ANGLE_DIR/include/EGL/eglext_angle.h \ $$ANGLE_DIR/include/EGL/eglplatform.h egl_headers.path = $$[QT_INSTALL_HEADERS]/QtANGLE/EGL INSTALLS += egl_headers diff --git a/sync.profile b/sync.profile index c674aab2f3..a6d0e2a4a7 100644 --- a/sync.profile +++ b/sync.profile @@ -80,7 +80,7 @@ ); @qpa_headers = ( qr/^(?!qplatformheaderhelper)qplatform/, qr/^qwindowsystem/ ); -my @angle_headers = ('egl.h', 'eglext.h', 'eglplatform.h', 'gl2.h', 'gl2ext.h', 'gl2platform.h', 'ShaderLang.h', 'khrplatform.h'); +my @angle_headers = ('egl.h', 'eglext.h', 'eglext_angle.h', 'eglplatform.h', 'gl2.h', 'gl2ext.h', 'gl2ext_angle.h', 'gl2platform.h', 'ShaderLang.h', 'khrplatform.h'); my @internal_zlib_headers = ( "crc32.h", "deflate.h", "gzguts.h", "inffast.h", "inffixed.h", "inflate.h", "inftrees.h", "trees.h", "zutil.h" ); my @zlib_headers = ( "zconf.h", "zlib.h" ); @ignore_headers = ( @internal_zlib_headers ); From dc3dd8c5dbf68ad0497faa57d12540088b661147 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 1 Oct 2018 09:38:46 +0200 Subject: [PATCH 0037/1650] Windows QPA: Add WM_INPUT to the list of input messages for event filtering Amends a0a22037cdacbf51a2db560ff902a5a341561b15. Task-number: QTBUG-67095 Change-Id: I32d2e78f9d9525d56c1d4477d69cf7b9d7f8e7a3 Reviewed-by: Miguel Costa --- src/plugins/platforms/windows/qwindowscontext.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 253aeb9d76..7f1b7077f7 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -960,6 +960,7 @@ static inline bool isInputMessage(UINT m) case WM_IME_STARTCOMPOSITION: case WM_IME_ENDCOMPOSITION: case WM_IME_COMPOSITION: + case WM_INPUT: case WM_TOUCH: case WM_MOUSEHOVER: case WM_MOUSELEAVE: From 298c00e530ebef613c355f9af4eb27c05fc4a52f Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Mon, 1 Oct 2018 12:44:55 +0200 Subject: [PATCH 0038/1650] Update bundled sqlite to 3.25.2 [ChangeLog][Third-Party Code] Sqlite was updated to version 3.25.2 Change-Id: I2d74ee924745a5e1edd6fe511777965313a4b77a Reviewed-by: Oliver Wolff --- src/3rdparty/sqlite.pri | 5 +- src/3rdparty/sqlite/sqlite3.c | 21391 +++++++++++++++++++++----------- src/3rdparty/sqlite/sqlite3.h | 293 +- 3 files changed, 14565 insertions(+), 7124 deletions(-) diff --git a/src/3rdparty/sqlite.pri b/src/3rdparty/sqlite.pri index 4f3326a817..cb8b888a6a 100644 --- a/src/3rdparty/sqlite.pri +++ b/src/3rdparty/sqlite.pri @@ -2,7 +2,10 @@ CONFIG(release, debug|release):DEFINES *= NDEBUG DEFINES += SQLITE_ENABLE_COLUMN_METADATA SQLITE_OMIT_LOAD_EXTENSION SQLITE_OMIT_COMPLETE SQLITE_ENABLE_FTS3 SQLITE_ENABLE_FTS3_PARENTHESIS SQLITE_ENABLE_FTS5 SQLITE_ENABLE_RTREE !contains(CONFIG, largefile):DEFINES += SQLITE_DISABLE_LFS qtConfig(posix_fallocate): DEFINES += HAVE_POSIX_FALLOCATE=1 -winrt: DEFINES += SQLITE_OS_WINRT +winrt { + DEFINES += SQLITE_OS_WINRT + QMAKE_CFLAGS += -Gy +} qnx: DEFINES += _QNX_SOURCE !win32:!winrt:!winphone: DEFINES += HAVE_USLEEP=1 integrity: QMAKE_CFLAGS += -include qplatformdefs.h diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c index ce4f343fdc..7b525c36bb 100644 --- a/src/3rdparty/sqlite/sqlite3.c +++ b/src/3rdparty/sqlite/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.24.0. By combining all the individual C code files into this +** version 3.25.2. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -55,6 +55,12 @@ #define CTIMEOPT_VAL_(opt) #opt #define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt) +/* Like CTIMEOPT_VAL, but especially for SQLITE_DEFAULT_LOOKASIDE. This +** option requires a separate macro because legal values contain a single +** comma. e.g. (-DSQLITE_DEFAULT_LOOKASIDE="100,100") */ +#define CTIMEOPT_VAL2_(opt1,opt2) #opt1 "," #opt2 +#define CTIMEOPT_VAL2(opt) CTIMEOPT_VAL2_(opt) + /* ** An array of names of all compile-time options. This array should ** be sorted A-Z. @@ -138,7 +144,7 @@ static const char * const sqlite3azCompileOpt[] = { "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE), #endif #ifdef SQLITE_DEFAULT_LOOKASIDE - "DEFAULT_LOOKASIDE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOOKASIDE), + "DEFAULT_LOOKASIDE=" CTIMEOPT_VAL2(SQLITE_DEFAULT_LOOKASIDE), #endif #if SQLITE_DEFAULT_MEMSTATUS "DEFAULT_MEMSTATUS", @@ -1150,9 +1156,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.24.0" -#define SQLITE_VERSION_NUMBER 3024000 -#define SQLITE_SOURCE_ID "2018-06-04 19:24:41 c7ee0833225bfd8c5ec2f9bf62b97c4e04d03bd9566366d5221ac8fb199a87ca" +#define SQLITE_VERSION "3.25.2" +#define SQLITE_VERSION_NUMBER 3025002 +#define SQLITE_SOURCE_ID "2018-09-25 19:08:10 fb90e7189ae6d62e77ba3a308ca5d683f90bbe633cf681865365b8e92792d1c7" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -1499,6 +1505,7 @@ SQLITE_API int sqlite3_exec( */ #define SQLITE_ERROR_MISSING_COLLSEQ (SQLITE_ERROR | (1<<8)) #define SQLITE_ERROR_RETRY (SQLITE_ERROR | (2<<8)) +#define SQLITE_ERROR_SNAPSHOT (SQLITE_ERROR | (3<<8)) #define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) #define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) #define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) @@ -1538,6 +1545,7 @@ SQLITE_API int sqlite3_exec( #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) #define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8)) +#define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) /* Not Used */ #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) #define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8)) #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) @@ -1913,7 +1921,8 @@ struct sqlite3_io_methods { **
  • [[SQLITE_FCNTL_PERSIST_WAL]] ** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the ** persistent [WAL | Write Ahead Log] setting. By default, the auxiliary -** write ahead log and shared memory files used for transaction control +** write ahead log ([WAL file]) and shared memory +** files used for transaction control ** are automatically deleted when the latest connection to the database ** closes. Setting persistent WAL mode causes those files to persist after ** close. Persisting the files is useful when other processes that do not @@ -2099,6 +2108,26 @@ struct sqlite3_io_methods { ** a file lock using the xLock or xShmLock methods of the VFS to wait ** for up to M milliseconds before failing, where M is the single ** unsigned integer parameter. +** +**
  • [[SQLITE_FCNTL_DATA_VERSION]] +** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to +** a database file. The argument is a pointer to a 32-bit unsigned integer. +** The "data version" for the pager is written into the pointer. The +** "data version" changes whenever any change occurs to the corresponding +** database file, either through SQL statements on the same database +** connection or through transactions committed by separate database +** connections possibly in other processes. The [sqlite3_total_changes()] +** interface can be used to find if any database on the connection has changed, +** but that interface responds to changes on TEMP as well as MAIN and does +** not provide a mechanism to detect changes to MAIN only. Also, the +** [sqlite3_total_changes()] interface responds to internal changes only and +** omits changes made by other database connections. The +** [PRAGMA data_version] command provide a mechanism to detect changes to +** a single attached database that occur due to other database connections, +** but omits changes implemented by the database connection on which it is +** called. This file control is the only mechanism to detect changes that +** happen either internally or externally and that are associated with +** a particular attached database. ** */ #define SQLITE_FCNTL_LOCKSTATE 1 @@ -2134,6 +2163,7 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32 #define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33 #define SQLITE_FCNTL_LOCK_TIMEOUT 34 +#define SQLITE_FCNTL_DATA_VERSION 35 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE @@ -3148,6 +3178,12 @@ struct sqlite3_mem_methods { ** with no schema and no content. The following process works even for ** a badly corrupted database file: **
      +**
    1. If the database connection is newly opened, make sure it has read the +** database schema by preparing then discarding some query against the +** database, or calling sqlite3_table_column_metadata(), ignoring any +** errors. This step is only necessary if the application desires to keep +** the database in WAL mode after the reset if it was in WAL mode before +** the reset. **
    2. sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0); **
    3. [sqlite3_exec](db, "[VACUUM]", 0, 0, 0); **
    4. sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0); @@ -3296,12 +3332,17 @@ SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64); ** program, the value returned reflects the number of rows modified by the ** previous INSERT, UPDATE or DELETE statement within the same trigger. ** -** See also the [sqlite3_total_changes()] interface, the -** [count_changes pragma], and the [changes() SQL function]. -** ** If a separate thread makes changes on the same database connection ** while [sqlite3_changes()] is running then the value returned ** is unpredictable and not meaningful. +** +** See also: +**
        +**
      • the [sqlite3_total_changes()] interface +**
      • the [count_changes pragma] +**
      • the [changes() SQL function] +**
      • the [data_version pragma] +**
      */ SQLITE_API int sqlite3_changes(sqlite3*); @@ -3319,13 +3360,26 @@ SQLITE_API int sqlite3_changes(sqlite3*); ** count, but those made as part of REPLACE constraint resolution are ** not. ^Changes to a view that are intercepted by INSTEAD OF triggers ** are not counted. -** -** See also the [sqlite3_changes()] interface, the -** [count_changes pragma], and the [total_changes() SQL function]. ** +** This the [sqlite3_total_changes(D)] interface only reports the number +** of rows that changed due to SQL statement run against database +** connection D. Any changes by other database connections are ignored. +** To detect changes against a database file from other database +** connections use the [PRAGMA data_version] command or the +** [SQLITE_FCNTL_DATA_VERSION] [file control]. +** ** If a separate thread makes changes on the same database connection ** while [sqlite3_total_changes()] is running then the value ** returned is unpredictable and not meaningful. +** +** See also: +**
        +**
      • the [sqlite3_changes()] interface +**
      • the [count_changes pragma] +**
      • the [changes() SQL function] +**
      • the [data_version pragma] +**
      • the [SQLITE_FCNTL_DATA_VERSION] [file control] +**
      */ SQLITE_API int sqlite3_total_changes(sqlite3*); @@ -4381,13 +4435,24 @@ SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int ** [database connection] D failed, then the sqlite3_errcode(D) interface ** returns the numeric [result code] or [extended result code] for that ** API call. -** If the most recent API call was successful, -** then the return value from sqlite3_errcode() is undefined. ** ^The sqlite3_extended_errcode() ** interface is the same except that it always returns the ** [extended result code] even when extended result codes are ** disabled. ** +** The values returned by sqlite3_errcode() and/or +** sqlite3_extended_errcode() might change with each API call. +** Except, there are some interfaces that are guaranteed to never +** change the value of the error code. The error-code preserving +** interfaces are: +** +**
        +**
      • sqlite3_errcode() +**
      • sqlite3_extended_errcode() +**
      • sqlite3_errmsg() +**
      • sqlite3_errmsg16() +**
      +** ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language ** text that describes the error, as either UTF-8 or UTF-16 respectively. ** ^(Memory to hold the error message string is managed internally. @@ -5541,11 +5606,25 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into ** [sqlite3_free()]. ** -** ^(If a memory allocation error occurs during the evaluation of any -** of these routines, a default value is returned. The default value -** is either the integer 0, the floating point number 0.0, or a NULL -** pointer. Subsequent calls to [sqlite3_errcode()] will return -** [SQLITE_NOMEM].)^ +** As long as the input parameters are correct, these routines will only +** fail if an out-of-memory error occurs during a format conversion. +** Only the following subset of interfaces are subject to out-of-memory +** errors: +** +**
        +**
      • sqlite3_column_blob() +**
      • sqlite3_column_text() +**
      • sqlite3_column_text16() +**
      • sqlite3_column_bytes() +**
      • sqlite3_column_bytes16() +**
      +** +** If an out-of-memory error occurs, then the return value from these +** routines is the same as if the column had contained an SQL NULL value. +** Valid SQL NULL returns can be distinguished from out-of-memory errors +** by invoking the [sqlite3_errcode()] immediately after the suspect +** return value is obtained and before any +** other SQLite interface is called on the same [database connection]. */ SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol); @@ -5622,11 +5701,13 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** ** ^These functions (collectively known as "function creation routines") ** are used to add SQL functions or aggregates or to redefine the behavior -** of existing SQL functions or aggregates. The only differences between -** these routines are the text encoding expected for -** the second parameter (the name of the function being created) -** and the presence or absence of a destructor callback for -** the application data pointer. +** of existing SQL functions or aggregates. The only differences between +** the three "sqlite3_create_function*" routines are the text encoding +** expected for the second parameter (the name of the function being +** created) and the presence or absence of a destructor callback for +** the application data pointer. Function sqlite3_create_window_function() +** is similar, but allows the user to supply the extra callback functions +** needed by [aggregate window functions]. ** ** ^The first parameter is the [database connection] to which the SQL ** function is to be added. ^If an application uses more than one database @@ -5672,7 +5753,8 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** ^(The fifth parameter is an arbitrary pointer. The implementation of the ** function can gain access to this pointer using [sqlite3_user_data()].)^ ** -** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are +** ^The sixth, seventh and eighth parameters passed to the three +** "sqlite3_create_function*" functions, xFunc, xStep and xFinal, are ** pointers to C-language functions that implement the SQL function or ** aggregate. ^A scalar SQL function requires an implementation of the xFunc ** callback only; NULL pointers must be passed as the xStep and xFinal @@ -5681,15 +5763,24 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** SQL function or aggregate, pass NULL pointers for all three function ** callbacks. ** -** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL, -** then it is destructor for the application data pointer. -** The destructor is invoked when the function is deleted, either by being -** overloaded or when the database connection closes.)^ -** ^The destructor is also invoked if the call to -** sqlite3_create_function_v2() fails. -** ^When the destructor callback of the tenth parameter is invoked, it -** is passed a single argument which is a copy of the application data -** pointer which was the fifth parameter to sqlite3_create_function_v2(). +** ^The sixth, seventh, eighth and ninth parameters (xStep, xFinal, xValue +** and xInverse) passed to sqlite3_create_window_function are pointers to +** C-language callbacks that implement the new function. xStep and xFinal +** must both be non-NULL. xValue and xInverse may either both be NULL, in +** which case a regular aggregate function is created, or must both be +** non-NULL, in which case the new function may be used as either an aggregate +** or aggregate window function. More details regarding the implementation +** of aggregate window functions are +** [user-defined window functions|available here]. +** +** ^(If the final parameter to sqlite3_create_function_v2() or +** sqlite3_create_window_function() is not NULL, then it is destructor for +** the application data pointer. The destructor is invoked when the function +** is deleted, either by being overloaded or when the database connection +** closes.)^ ^The destructor is also invoked if the call to +** sqlite3_create_function_v2() fails. ^When the destructor callback is +** invoked, it is passed a single argument which is a copy of the application +** data pointer which was the fifth parameter to sqlite3_create_function_v2(). ** ** ^It is permitted to register multiple implementations of the same ** functions with the same name but with either differing numbers of @@ -5742,6 +5833,18 @@ SQLITE_API int sqlite3_create_function_v2( void (*xFinal)(sqlite3_context*), void(*xDestroy)(void*) ); +SQLITE_API int sqlite3_create_window_function( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void (*xValue)(sqlite3_context*), + void (*xInverse)(sqlite3_context*,int,sqlite3_value**), + void(*xDestroy)(void*) +); /* ** CAPI3REF: Text Encodings @@ -5884,6 +5987,28 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6 ** ** These routines must be called from the same thread as ** the SQL function that supplied the [sqlite3_value*] parameters. +** +** As long as the input parameter is correct, these routines can only +** fail if an out-of-memory error occurs during a format conversion. +** Only the following subset of interfaces are subject to out-of-memory +** errors: +** +**
        +**
      • sqlite3_value_blob() +**
      • sqlite3_value_text() +**
      • sqlite3_value_text16() +**
      • sqlite3_value_text16le() +**
      • sqlite3_value_text16be() +**
      • sqlite3_value_bytes() +**
      • sqlite3_value_bytes16() +**
      +** +** If an out-of-memory error occurs, then the return value from these +** routines is the same as if the column had contained an SQL NULL value. +** Valid SQL NULL returns can be distinguished from out-of-memory errors +** by invoking the [sqlite3_errcode()] immediately after the suspect +** return value is obtained and before any +** other SQLite interface is called on the same [database connection]. */ SQLITE_API const void *sqlite3_value_blob(sqlite3_value*); SQLITE_API double sqlite3_value_double(sqlite3_value*); @@ -7350,6 +7475,7 @@ struct sqlite3_index_info { #define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70 #define SQLITE_INDEX_CONSTRAINT_ISNULL 71 #define SQLITE_INDEX_CONSTRAINT_IS 72 +#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150 /* ** CAPI3REF: Register A Virtual Table Implementation @@ -8026,6 +8152,7 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*); /* ** CAPI3REF: Low-Level Control Of Database Files ** METHOD: sqlite3 +** KEYWORDS: {file control} ** ** ^The [sqlite3_file_control()] interface makes a direct call to the ** xFileControl method for the [sqlite3_io_methods] object associated @@ -8040,11 +8167,18 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*); ** the xFileControl method. ^The return value of the xFileControl ** method becomes the return value of this routine. ** +** A few opcodes for [sqlite3_file_control()] are handled directly +** by the SQLite core and never invoke the +** sqlite3_io_methods.xFileControl method. ** ^The [SQLITE_FCNTL_FILE_POINTER] value for the op parameter causes ** a pointer to the underlying [sqlite3_file] object to be written into -** the space pointed to by the 4th parameter. ^The [SQLITE_FCNTL_FILE_POINTER] -** case is a short-circuit path which does not actually invoke the -** underlying sqlite3_io_methods.xFileControl method. +** the space pointed to by the 4th parameter. The +** [SQLITE_FCNTL_JOURNAL_POINTER] works similarly except that it returns +** the [sqlite3_file] object associated with the journal file instead of +** the main database. The [SQLITE_FCNTL_VFS_POINTER] opcode returns +** a pointer to the underlying [sqlite3_vfs] object for the file. +** The [SQLITE_FCNTL_DATA_VERSION] returns the data version counter +** from the pager. ** ** ^If the second parameter (zDbName) does not match the name of any ** open database file, then SQLITE_ERROR is returned. ^This error @@ -9863,7 +9997,6 @@ SQLITE_API int sqlite3_system_errno(sqlite3*); /* ** CAPI3REF: Database Snapshot ** KEYWORDS: {snapshot} {sqlite3_snapshot} -** EXPERIMENTAL ** ** An instance of the snapshot object records the state of a [WAL mode] ** database for some specific point in history. @@ -9880,11 +10013,6 @@ SQLITE_API int sqlite3_system_errno(sqlite3*); ** version of the database file so that it is possible to later open a new read ** transaction that sees that historical version of the database rather than ** the most recent version. -** -** The constructor for this object is [sqlite3_snapshot_get()]. The -** [sqlite3_snapshot_open()] method causes a fresh read transaction to refer -** to an historical snapshot (if possible). The destructor for -** sqlite3_snapshot objects is [sqlite3_snapshot_free()]. */ typedef struct sqlite3_snapshot { unsigned char hidden[48]; @@ -9892,7 +10020,7 @@ typedef struct sqlite3_snapshot { /* ** CAPI3REF: Record A Database Snapshot -** EXPERIMENTAL +** CONSTRUCTOR: sqlite3_snapshot ** ** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a ** new [sqlite3_snapshot] object that records the current state of @@ -9908,7 +10036,7 @@ typedef struct sqlite3_snapshot { ** in this case. ** **
        -**
      • The database handle must be in [autocommit mode]. +**
      • The database handle must not be in [autocommit mode]. ** **
      • Schema S of [database connection] D must be a [WAL mode] database. ** @@ -9931,7 +10059,7 @@ typedef struct sqlite3_snapshot { ** to avoid a memory leak. ** ** The [sqlite3_snapshot_get()] interface is only available when the -** SQLITE_ENABLE_SNAPSHOT compile-time option is used. +** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used. */ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get( sqlite3 *db, @@ -9941,24 +10069,35 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get( /* ** CAPI3REF: Start a read transaction on an historical snapshot -** EXPERIMENTAL +** METHOD: sqlite3_snapshot ** -** ^The [sqlite3_snapshot_open(D,S,P)] interface starts a -** read transaction for schema S of -** [database connection] D such that the read transaction -** refers to historical [snapshot] P, rather than the most -** recent change to the database. -** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success -** or an appropriate [error code] if it fails. +** ^The [sqlite3_snapshot_open(D,S,P)] interface either starts a new read +** transaction or upgrades an existing one for schema S of +** [database connection] D such that the read transaction refers to +** historical [snapshot] P, rather than the most recent change to the +** database. ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK +** on success or an appropriate [error code] if it fails. +** +** ^In order to succeed, the database connection must not be in +** [autocommit mode] when [sqlite3_snapshot_open(D,S,P)] is called. If there +** is already a read transaction open on schema S, then the database handle +** must have no active statements (SELECT statements that have been passed +** to sqlite3_step() but not sqlite3_reset() or sqlite3_finalize()). +** SQLITE_ERROR is returned if either of these conditions is violated, or +** if schema S does not exist, or if the snapshot object is invalid. +** +** ^A call to sqlite3_snapshot_open() will fail to open if the specified +** snapshot has been overwritten by a [checkpoint]. In this case +** SQLITE_ERROR_SNAPSHOT is returned. +** +** If there is already a read transaction open when this function is +** invoked, then the same read transaction remains open (on the same +** database snapshot) if SQLITE_ERROR, SQLITE_BUSY or SQLITE_ERROR_SNAPSHOT +** is returned. If another error code - for example SQLITE_PROTOCOL or an +** SQLITE_IOERR error code - is returned, then the final state of the +** read transaction is undefined. If SQLITE_OK is returned, then the +** read transaction is now open on database snapshot P. ** -** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be -** the first operation following the [BEGIN] that takes the schema S -** out of [autocommit mode]. -** ^In other words, schema S must not currently be in -** a transaction for [sqlite3_snapshot_open(D,S,P)] to work, but the -** database connection D must be out of [autocommit mode]. -** ^A [snapshot] will fail to open if it has been overwritten by a -** [checkpoint]. ** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the ** database connection D does not know that the database file for ** schema S is in [WAL mode]. A database connection might not know @@ -9969,7 +10108,7 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get( ** database connection in order to make it ready to use snapshots.) ** ** The [sqlite3_snapshot_open()] interface is only available when the -** SQLITE_ENABLE_SNAPSHOT compile-time option is used. +** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used. */ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open( sqlite3 *db, @@ -9979,20 +10118,20 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open( /* ** CAPI3REF: Destroy a snapshot -** EXPERIMENTAL +** DESTRUCTOR: sqlite3_snapshot ** ** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P. ** The application must eventually free every [sqlite3_snapshot] object ** using this routine to avoid a memory leak. ** ** The [sqlite3_snapshot_free()] interface is only available when the -** SQLITE_ENABLE_SNAPSHOT compile-time option is used. +** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used. */ SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*); /* ** CAPI3REF: Compare the ages of two snapshot handles. -** EXPERIMENTAL +** METHOD: sqlite3_snapshot ** ** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages ** of two valid snapshot handles. @@ -10011,6 +10150,9 @@ SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*); ** Otherwise, this API returns a negative value if P1 refers to an older ** snapshot than P2, zero if the two handles refer to the same database ** snapshot, and a positive value if P1 is a newer snapshot than P2. +** +** This interface is only available if SQLite is compiled with the +** [SQLITE_ENABLE_SNAPSHOT] option. */ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp( sqlite3_snapshot *p1, @@ -10019,23 +10161,26 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp( /* ** CAPI3REF: Recover snapshots from a wal file -** EXPERIMENTAL +** METHOD: sqlite3_snapshot ** -** If all connections disconnect from a database file but do not perform -** a checkpoint, the existing wal file is opened along with the database -** file the next time the database is opened. At this point it is only -** possible to successfully call sqlite3_snapshot_open() to open the most -** recent snapshot of the database (the one at the head of the wal file), -** even though the wal file may contain other valid snapshots for which -** clients have sqlite3_snapshot handles. +** If a [WAL file] remains on disk after all database connections close +** (either through the use of the [SQLITE_FCNTL_PERSIST_WAL] [file control] +** or because the last process to have the database opened exited without +** calling [sqlite3_close()]) and a new connection is subsequently opened +** on that database and [WAL file], the [sqlite3_snapshot_open()] interface +** will only be able to open the last transaction added to the WAL file +** even though the WAL file contains other valid transactions. ** -** This function attempts to scan the wal file associated with database zDb +** This function attempts to scan the WAL file associated with database zDb ** of database handle db and make all valid snapshots available to ** sqlite3_snapshot_open(). It is an error if there is already a read -** transaction open on the database, or if the database is not a wal mode +** transaction open on the database, or if the database is not a WAL mode ** database. ** ** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +** +** This interface is only available if SQLite is compiled with the +** [SQLITE_ENABLE_SNAPSHOT] option. */ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb); @@ -10146,7 +10291,7 @@ SQLITE_API int sqlite3_deserialize( ** in the P argument is held in memory obtained from [sqlite3_malloc64()] ** and that SQLite should take ownership of this memory and automatically ** free it when it has finished using it. Without this flag, the caller -** is resposible for freeing any dynamically allocated memory. +** is responsible for freeing any dynamically allocated memory. ** ** The SQLITE_DESERIALIZE_RESIZEABLE flag means that SQLite is allowed to ** grow the size of the database using calls to [sqlite3_realloc64()]. This @@ -12324,7 +12469,7 @@ struct Fts5ExtensionApi { ** This way, even if the tokenizer does not provide synonyms ** when tokenizing query text (it should not - to do would be ** inefficient), it doesn't matter if the user queries for -** 'first + place' or '1st + place', as there are entires in the +** 'first + place' or '1st + place', as there are entries in the ** FTS index corresponding to both forms of the first token. **
    ** @@ -12352,7 +12497,7 @@ struct Fts5ExtensionApi { ** extra data to the FTS index or require FTS5 to query for multiple terms, ** so it is efficient in terms of disk space and query speed. However, it ** does not support prefix queries very well. If, as suggested above, the -** token "first" is subsituted for "1st" by the tokenizer, then the query: +** token "first" is substituted for "1st" by the tokenizer, then the query: ** ** ** ... MATCH '1s*' @@ -13216,94 +13361,104 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); #define TK_REPLACE 73 #define TK_RESTRICT 74 #define TK_ROW 75 -#define TK_TRIGGER 76 -#define TK_VACUUM 77 -#define TK_VIEW 78 -#define TK_VIRTUAL 79 -#define TK_WITH 80 -#define TK_REINDEX 81 -#define TK_RENAME 82 -#define TK_CTIME_KW 83 -#define TK_ANY 84 -#define TK_BITAND 85 -#define TK_BITOR 86 -#define TK_LSHIFT 87 -#define TK_RSHIFT 88 -#define TK_PLUS 89 -#define TK_MINUS 90 -#define TK_STAR 91 -#define TK_SLASH 92 -#define TK_REM 93 -#define TK_CONCAT 94 -#define TK_COLLATE 95 -#define TK_BITNOT 96 -#define TK_ON 97 -#define TK_INDEXED 98 -#define TK_STRING 99 -#define TK_JOIN_KW 100 -#define TK_CONSTRAINT 101 -#define TK_DEFAULT 102 -#define TK_NULL 103 -#define TK_PRIMARY 104 -#define TK_UNIQUE 105 -#define TK_CHECK 106 -#define TK_REFERENCES 107 -#define TK_AUTOINCR 108 -#define TK_INSERT 109 -#define TK_DELETE 110 -#define TK_UPDATE 111 -#define TK_SET 112 -#define TK_DEFERRABLE 113 -#define TK_FOREIGN 114 -#define TK_DROP 115 -#define TK_UNION 116 -#define TK_ALL 117 -#define TK_EXCEPT 118 -#define TK_INTERSECT 119 -#define TK_SELECT 120 -#define TK_VALUES 121 -#define TK_DISTINCT 122 -#define TK_DOT 123 -#define TK_FROM 124 -#define TK_JOIN 125 -#define TK_USING 126 -#define TK_ORDER 127 -#define TK_GROUP 128 -#define TK_HAVING 129 -#define TK_LIMIT 130 -#define TK_WHERE 131 -#define TK_INTO 132 -#define TK_NOTHING 133 -#define TK_FLOAT 134 -#define TK_BLOB 135 -#define TK_INTEGER 136 -#define TK_VARIABLE 137 -#define TK_CASE 138 -#define TK_WHEN 139 -#define TK_THEN 140 -#define TK_ELSE 141 -#define TK_INDEX 142 -#define TK_ALTER 143 -#define TK_ADD 144 -#define TK_TRUEFALSE 145 -#define TK_ISNOT 146 -#define TK_FUNCTION 147 -#define TK_COLUMN 148 -#define TK_AGG_FUNCTION 149 -#define TK_AGG_COLUMN 150 -#define TK_UMINUS 151 -#define TK_UPLUS 152 -#define TK_TRUTH 153 -#define TK_REGISTER 154 -#define TK_VECTOR 155 -#define TK_SELECT_COLUMN 156 -#define TK_IF_NULL_ROW 157 -#define TK_ASTERISK 158 -#define TK_SPAN 159 -#define TK_END_OF_FILE 160 -#define TK_UNCLOSED_STRING 161 -#define TK_SPACE 162 -#define TK_ILLEGAL 163 +#define TK_ROWS 76 +#define TK_TRIGGER 77 +#define TK_VACUUM 78 +#define TK_VIEW 79 +#define TK_VIRTUAL 80 +#define TK_WITH 81 +#define TK_CURRENT 82 +#define TK_FOLLOWING 83 +#define TK_PARTITION 84 +#define TK_PRECEDING 85 +#define TK_RANGE 86 +#define TK_UNBOUNDED 87 +#define TK_REINDEX 88 +#define TK_RENAME 89 +#define TK_CTIME_KW 90 +#define TK_ANY 91 +#define TK_BITAND 92 +#define TK_BITOR 93 +#define TK_LSHIFT 94 +#define TK_RSHIFT 95 +#define TK_PLUS 96 +#define TK_MINUS 97 +#define TK_STAR 98 +#define TK_SLASH 99 +#define TK_REM 100 +#define TK_CONCAT 101 +#define TK_COLLATE 102 +#define TK_BITNOT 103 +#define TK_ON 104 +#define TK_INDEXED 105 +#define TK_STRING 106 +#define TK_JOIN_KW 107 +#define TK_CONSTRAINT 108 +#define TK_DEFAULT 109 +#define TK_NULL 110 +#define TK_PRIMARY 111 +#define TK_UNIQUE 112 +#define TK_CHECK 113 +#define TK_REFERENCES 114 +#define TK_AUTOINCR 115 +#define TK_INSERT 116 +#define TK_DELETE 117 +#define TK_UPDATE 118 +#define TK_SET 119 +#define TK_DEFERRABLE 120 +#define TK_FOREIGN 121 +#define TK_DROP 122 +#define TK_UNION 123 +#define TK_ALL 124 +#define TK_EXCEPT 125 +#define TK_INTERSECT 126 +#define TK_SELECT 127 +#define TK_VALUES 128 +#define TK_DISTINCT 129 +#define TK_DOT 130 +#define TK_FROM 131 +#define TK_JOIN 132 +#define TK_USING 133 +#define TK_ORDER 134 +#define TK_GROUP 135 +#define TK_HAVING 136 +#define TK_LIMIT 137 +#define TK_WHERE 138 +#define TK_INTO 139 +#define TK_NOTHING 140 +#define TK_FLOAT 141 +#define TK_BLOB 142 +#define TK_INTEGER 143 +#define TK_VARIABLE 144 +#define TK_CASE 145 +#define TK_WHEN 146 +#define TK_THEN 147 +#define TK_ELSE 148 +#define TK_INDEX 149 +#define TK_ALTER 150 +#define TK_ADD 151 +#define TK_WINDOW 152 +#define TK_OVER 153 +#define TK_FILTER 154 +#define TK_TRUEFALSE 155 +#define TK_ISNOT 156 +#define TK_FUNCTION 157 +#define TK_COLUMN 158 +#define TK_AGG_FUNCTION 159 +#define TK_AGG_COLUMN 160 +#define TK_UMINUS 161 +#define TK_UPLUS 162 +#define TK_TRUTH 163 +#define TK_REGISTER 164 +#define TK_VECTOR 165 +#define TK_SELECT_COLUMN 166 +#define TK_IF_NULL_ROW 167 +#define TK_ASTERISK 168 +#define TK_SPAN 169 +#define TK_END_OF_FILE 170 +#define TK_UNCLOSED_STRING 171 +#define TK_SPACE 172 +#define TK_ILLEGAL 173 /* The token codes above must all fit in 8 bits */ #define TKFLG_MASK 0xff @@ -13577,7 +13732,8 @@ typedef INT16_TYPE LogEst; # if defined(__SIZEOF_POINTER__) # define SQLITE_PTRSIZE __SIZEOF_POINTER__ # elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \ - defined(_M_ARM) || defined(__arm__) || defined(__x86) + defined(_M_ARM) || defined(__arm__) || defined(__x86) || \ + (defined(__TOS_AIX__) && !defined(__64BIT__)) # define SQLITE_PTRSIZE 4 # else # define SQLITE_PTRSIZE 8 @@ -13618,7 +13774,7 @@ typedef INT16_TYPE LogEst; # if defined(i386) || defined(__i386__) || defined(_M_IX86) || \ defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ - defined(__arm__) + defined(__arm__) || defined(_M_ARM64) # define SQLITE_BYTEORDER 1234 # elif defined(sparc) || defined(__ppc__) # define SQLITE_BYTEORDER 4321 @@ -13873,6 +14029,7 @@ typedef struct NameContext NameContext; typedef struct Parse Parse; typedef struct PreUpdate PreUpdate; typedef struct PrintfArguments PrintfArguments; +typedef struct RenameToken RenameToken; typedef struct RowSet RowSet; typedef struct Savepoint Savepoint; typedef struct Select Select; @@ -13893,8 +14050,35 @@ typedef struct VTable VTable; typedef struct VtabCtx VtabCtx; typedef struct Walker Walker; typedef struct WhereInfo WhereInfo; +typedef struct Window Window; typedef struct With With; + +/* +** The bitmask datatype defined below is used for various optimizations. +** +** Changing this from a 64-bit to a 32-bit type limits the number of +** tables in a join to 32 instead of 64. But it also reduces the size +** of the library by 738 bytes on ix86. +*/ +#ifdef SQLITE_BITMASK_TYPE + typedef SQLITE_BITMASK_TYPE Bitmask; +#else + typedef u64 Bitmask; +#endif + +/* +** The number of bits in a Bitmask. "BMS" means "BitMask Size". +*/ +#define BMS ((int)(sizeof(Bitmask)*8)) + +/* +** A bit in a Bitmask +*/ +#define MASKBIT(n) (((Bitmask)1)<<(n)) +#define MASKBIT32(n) (((unsigned int)1)<<(n)) +#define ALLBITS ((Bitmask)-1) + /* A VList object records a mapping between parameters/variables/wildcards ** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer ** variable number associated with that parameter. See the format description @@ -13990,7 +14174,7 @@ SQLITE_PRIVATE int sqlite3BtreeGetOptimalReserve(Btree*); SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p); SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *, int); SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *); -SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int); +SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int,int*); SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster); SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree*, int); SQLITE_PRIVATE int sqlite3BtreeCommit(Btree*); @@ -14213,6 +14397,9 @@ struct BtreePayload { SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload, int flags, int seekResult); SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor*, int *pRes); +#ifndef SQLITE_OMIT_WINDOWFUNC +SQLITE_PRIVATE void sqlite3BtreeSkipNext(BtCursor*); +#endif SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor*, int *pRes); SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int flags); SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*); @@ -14380,7 +14567,8 @@ struct VdbeOp { u64 cycles; /* Total time spent executing this instruction */ #endif #ifdef SQLITE_VDBE_COVERAGE - int iSrcLine; /* Source-code line that generated this opcode */ + u32 iSrcLine; /* Source-code line that generated this opcode + ** with flags in the upper 8 bits */ #endif }; typedef struct VdbeOp VdbeOp; @@ -14481,52 +14669,52 @@ typedef struct VdbeOpList VdbeOpList; #define OP_AutoCommit 1 #define OP_Transaction 2 #define OP_SorterNext 3 /* jump */ -#define OP_PrevIfOpen 4 /* jump */ -#define OP_NextIfOpen 5 /* jump */ -#define OP_Prev 6 /* jump */ -#define OP_Next 7 /* jump */ -#define OP_Checkpoint 8 -#define OP_JournalMode 9 -#define OP_Vacuum 10 -#define OP_VFilter 11 /* jump, synopsis: iplan=r[P3] zplan='P4' */ -#define OP_VUpdate 12 /* synopsis: data=r[P3@P2] */ -#define OP_Goto 13 /* jump */ -#define OP_Gosub 14 /* jump */ -#define OP_InitCoroutine 15 /* jump */ -#define OP_Yield 16 /* jump */ -#define OP_MustBeInt 17 /* jump */ -#define OP_Jump 18 /* jump */ +#define OP_Prev 4 /* jump */ +#define OP_Next 5 /* jump */ +#define OP_Checkpoint 6 +#define OP_JournalMode 7 +#define OP_Vacuum 8 +#define OP_VFilter 9 /* jump, synopsis: iplan=r[P3] zplan='P4' */ +#define OP_VUpdate 10 /* synopsis: data=r[P3@P2] */ +#define OP_Goto 11 /* jump */ +#define OP_Gosub 12 /* jump */ +#define OP_InitCoroutine 13 /* jump */ +#define OP_Yield 14 /* jump */ +#define OP_MustBeInt 15 /* jump */ +#define OP_Jump 16 /* jump */ +#define OP_Once 17 /* jump */ +#define OP_If 18 /* jump */ #define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */ -#define OP_Once 20 /* jump */ -#define OP_If 21 /* jump */ -#define OP_IfNot 22 /* jump */ -#define OP_IfNullRow 23 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */ -#define OP_SeekLT 24 /* jump, synopsis: key=r[P3@P4] */ -#define OP_SeekLE 25 /* jump, synopsis: key=r[P3@P4] */ -#define OP_SeekGE 26 /* jump, synopsis: key=r[P3@P4] */ -#define OP_SeekGT 27 /* jump, synopsis: key=r[P3@P4] */ -#define OP_NoConflict 28 /* jump, synopsis: key=r[P3@P4] */ -#define OP_NotFound 29 /* jump, synopsis: key=r[P3@P4] */ -#define OP_Found 30 /* jump, synopsis: key=r[P3@P4] */ -#define OP_SeekRowid 31 /* jump, synopsis: intkey=r[P3] */ -#define OP_NotExists 32 /* jump, synopsis: intkey=r[P3] */ -#define OP_Last 33 /* jump */ -#define OP_IfSmaller 34 /* jump */ -#define OP_SorterSort 35 /* jump */ -#define OP_Sort 36 /* jump */ -#define OP_Rewind 37 /* jump */ -#define OP_IdxLE 38 /* jump, synopsis: key=r[P3@P4] */ -#define OP_IdxGT 39 /* jump, synopsis: key=r[P3@P4] */ -#define OP_IdxLT 40 /* jump, synopsis: key=r[P3@P4] */ -#define OP_IdxGE 41 /* jump, synopsis: key=r[P3@P4] */ -#define OP_RowSetRead 42 /* jump, synopsis: r[P3]=rowset(P1) */ +#define OP_IfNot 20 /* jump */ +#define OP_IfNullRow 21 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */ +#define OP_SeekLT 22 /* jump, synopsis: key=r[P3@P4] */ +#define OP_SeekLE 23 /* jump, synopsis: key=r[P3@P4] */ +#define OP_SeekGE 24 /* jump, synopsis: key=r[P3@P4] */ +#define OP_SeekGT 25 /* jump, synopsis: key=r[P3@P4] */ +#define OP_IfNoHope 26 /* jump, synopsis: key=r[P3@P4] */ +#define OP_NoConflict 27 /* jump, synopsis: key=r[P3@P4] */ +#define OP_NotFound 28 /* jump, synopsis: key=r[P3@P4] */ +#define OP_Found 29 /* jump, synopsis: key=r[P3@P4] */ +#define OP_SeekRowid 30 /* jump, synopsis: intkey=r[P3] */ +#define OP_NotExists 31 /* jump, synopsis: intkey=r[P3] */ +#define OP_Last 32 /* jump */ +#define OP_IfSmaller 33 /* jump */ +#define OP_SorterSort 34 /* jump */ +#define OP_Sort 35 /* jump */ +#define OP_Rewind 36 /* jump */ +#define OP_IdxLE 37 /* jump, synopsis: key=r[P3@P4] */ +#define OP_IdxGT 38 /* jump, synopsis: key=r[P3@P4] */ +#define OP_IdxLT 39 /* jump, synopsis: key=r[P3@P4] */ +#define OP_IdxGE 40 /* jump, synopsis: key=r[P3@P4] */ +#define OP_RowSetRead 41 /* jump, synopsis: r[P3]=rowset(P1) */ +#define OP_RowSetTest 42 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ #define OP_Or 43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ #define OP_And 44 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ -#define OP_RowSetTest 45 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ -#define OP_Program 46 /* jump */ -#define OP_FkIfZero 47 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ -#define OP_IfPos 48 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ -#define OP_IfNotZero 49 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ +#define OP_Program 45 /* jump */ +#define OP_FkIfZero 46 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ +#define OP_IfPos 47 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ +#define OP_IfNotZero 48 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ +#define OP_DecrJumpZero 49 /* jump, synopsis: if (--r[P1])==0 goto P2 */ #define OP_IsNull 50 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ #define OP_NotNull 51 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ #define OP_Ne 52 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */ @@ -14536,119 +14724,121 @@ typedef struct VdbeOpList VdbeOpList; #define OP_Lt 56 /* jump, same as TK_LT, synopsis: IF r[P3]=r[P1] */ #define OP_ElseNotEq 58 /* jump, same as TK_ESCAPE */ -#define OP_DecrJumpZero 59 /* jump, synopsis: if (--r[P1])==0 goto P2 */ -#define OP_IncrVacuum 60 /* jump */ -#define OP_VNext 61 /* jump */ -#define OP_Init 62 /* jump, synopsis: Start at P2 */ -#define OP_Return 63 -#define OP_EndCoroutine 64 -#define OP_HaltIfNull 65 /* synopsis: if r[P3]=null halt */ -#define OP_Halt 66 -#define OP_Integer 67 /* synopsis: r[P2]=P1 */ -#define OP_Int64 68 /* synopsis: r[P2]=P4 */ -#define OP_String 69 /* synopsis: r[P2]='P4' (len=P1) */ -#define OP_Null 70 /* synopsis: r[P2..P3]=NULL */ -#define OP_SoftNull 71 /* synopsis: r[P1]=NULL */ -#define OP_Blob 72 /* synopsis: r[P2]=P4 (len=P1) */ -#define OP_Variable 73 /* synopsis: r[P2]=parameter(P1,P4) */ -#define OP_Move 74 /* synopsis: r[P2@P3]=r[P1@P3] */ -#define OP_Copy 75 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ -#define OP_SCopy 76 /* synopsis: r[P2]=r[P1] */ -#define OP_IntCopy 77 /* synopsis: r[P2]=r[P1] */ -#define OP_ResultRow 78 /* synopsis: output=r[P1@P2] */ -#define OP_CollSeq 79 -#define OP_AddImm 80 /* synopsis: r[P1]=r[P1]+P2 */ -#define OP_RealAffinity 81 -#define OP_Cast 82 /* synopsis: affinity(r[P1]) */ -#define OP_Permutation 83 -#define OP_Compare 84 /* synopsis: r[P1@P3] <-> r[P2@P3] */ -#define OP_BitAnd 85 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ -#define OP_BitOr 86 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ -#define OP_ShiftLeft 87 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */ -#define OP_Add 89 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ -#define OP_Subtract 90 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ -#define OP_Multiply 91 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ -#define OP_Divide 92 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ -#define OP_Remainder 93 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ -#define OP_Concat 94 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ -#define OP_IsTrue 95 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */ -#define OP_BitNot 96 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */ -#define OP_Offset 97 /* synopsis: r[P3] = sqlite_offset(P1) */ -#define OP_Column 98 /* synopsis: r[P3]=PX */ -#define OP_String8 99 /* same as TK_STRING, synopsis: r[P2]='P4' */ -#define OP_Affinity 100 /* synopsis: affinity(r[P1@P2]) */ -#define OP_MakeRecord 101 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ -#define OP_Count 102 /* synopsis: r[P2]=count() */ -#define OP_ReadCookie 103 -#define OP_SetCookie 104 -#define OP_ReopenIdx 105 /* synopsis: root=P2 iDb=P3 */ -#define OP_OpenRead 106 /* synopsis: root=P2 iDb=P3 */ -#define OP_OpenWrite 107 /* synopsis: root=P2 iDb=P3 */ -#define OP_OpenDup 108 -#define OP_OpenAutoindex 109 /* synopsis: nColumn=P2 */ -#define OP_OpenEphemeral 110 /* synopsis: nColumn=P2 */ -#define OP_SorterOpen 111 -#define OP_SequenceTest 112 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ -#define OP_OpenPseudo 113 /* synopsis: P3 columns in r[P2] */ -#define OP_Close 114 -#define OP_ColumnsUsed 115 -#define OP_Sequence 116 /* synopsis: r[P2]=cursor[P1].ctr++ */ -#define OP_NewRowid 117 /* synopsis: r[P2]=rowid */ -#define OP_Insert 118 /* synopsis: intkey=r[P3] data=r[P2] */ -#define OP_InsertInt 119 /* synopsis: intkey=P3 data=r[P2] */ -#define OP_Delete 120 -#define OP_ResetCount 121 -#define OP_SorterCompare 122 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ -#define OP_SorterData 123 /* synopsis: r[P2]=data */ -#define OP_RowData 124 /* synopsis: r[P2]=data */ -#define OP_Rowid 125 /* synopsis: r[P2]=rowid */ -#define OP_NullRow 126 -#define OP_SeekEnd 127 -#define OP_SorterInsert 128 /* synopsis: key=r[P2] */ -#define OP_IdxInsert 129 /* synopsis: key=r[P2] */ -#define OP_IdxDelete 130 /* synopsis: key=r[P2@P3] */ -#define OP_DeferredSeek 131 /* synopsis: Move P3 to P1.rowid if needed */ -#define OP_IdxRowid 132 /* synopsis: r[P2]=rowid */ -#define OP_Destroy 133 -#define OP_Real 134 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ -#define OP_Clear 135 -#define OP_ResetSorter 136 -#define OP_CreateBtree 137 /* synopsis: r[P2]=root iDb=P1 flags=P3 */ -#define OP_SqlExec 138 -#define OP_ParseSchema 139 -#define OP_LoadAnalysis 140 -#define OP_DropTable 141 -#define OP_DropIndex 142 -#define OP_DropTrigger 143 -#define OP_IntegrityCk 144 -#define OP_RowSetAdd 145 /* synopsis: rowset(P1)=r[P2] */ -#define OP_Param 146 -#define OP_FkCounter 147 /* synopsis: fkctr[P1]+=P2 */ -#define OP_MemMax 148 /* synopsis: r[P1]=max(r[P1],r[P2]) */ -#define OP_OffsetLimit 149 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ -#define OP_AggStep0 150 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -#define OP_AggStep 151 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -#define OP_AggFinal 152 /* synopsis: accum=r[P1] N=P2 */ -#define OP_Expire 153 -#define OP_TableLock 154 /* synopsis: iDb=P1 root=P2 write=P3 */ -#define OP_VBegin 155 -#define OP_VCreate 156 -#define OP_VDestroy 157 -#define OP_VOpen 158 -#define OP_VColumn 159 /* synopsis: r[P3]=vcolumn(P2) */ -#define OP_VRename 160 -#define OP_Pagecount 161 -#define OP_MaxPgcnt 162 -#define OP_PureFunc0 163 -#define OP_Function0 164 /* synopsis: r[P3]=func(r[P2@P5]) */ -#define OP_PureFunc 165 -#define OP_Function 166 /* synopsis: r[P3]=func(r[P2@P5]) */ -#define OP_Trace 167 -#define OP_CursorHint 168 -#define OP_Noop 169 -#define OP_Explain 170 -#define OP_Abortable 171 +#define OP_IncrVacuum 59 /* jump */ +#define OP_VNext 60 /* jump */ +#define OP_Init 61 /* jump, synopsis: Start at P2 */ +#define OP_PureFunc0 62 +#define OP_Function0 63 /* synopsis: r[P3]=func(r[P2@P5]) */ +#define OP_PureFunc 64 +#define OP_Function 65 /* synopsis: r[P3]=func(r[P2@P5]) */ +#define OP_Return 66 +#define OP_EndCoroutine 67 +#define OP_HaltIfNull 68 /* synopsis: if r[P3]=null halt */ +#define OP_Halt 69 +#define OP_Integer 70 /* synopsis: r[P2]=P1 */ +#define OP_Int64 71 /* synopsis: r[P2]=P4 */ +#define OP_String 72 /* synopsis: r[P2]='P4' (len=P1) */ +#define OP_Null 73 /* synopsis: r[P2..P3]=NULL */ +#define OP_SoftNull 74 /* synopsis: r[P1]=NULL */ +#define OP_Blob 75 /* synopsis: r[P2]=P4 (len=P1) */ +#define OP_Variable 76 /* synopsis: r[P2]=parameter(P1,P4) */ +#define OP_Move 77 /* synopsis: r[P2@P3]=r[P1@P3] */ +#define OP_Copy 78 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ +#define OP_SCopy 79 /* synopsis: r[P2]=r[P1] */ +#define OP_IntCopy 80 /* synopsis: r[P2]=r[P1] */ +#define OP_ResultRow 81 /* synopsis: output=r[P1@P2] */ +#define OP_CollSeq 82 +#define OP_AddImm 83 /* synopsis: r[P1]=r[P1]+P2 */ +#define OP_RealAffinity 84 +#define OP_Cast 85 /* synopsis: affinity(r[P1]) */ +#define OP_Permutation 86 +#define OP_Compare 87 /* synopsis: r[P1@P3] <-> r[P2@P3] */ +#define OP_IsTrue 88 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */ +#define OP_Offset 89 /* synopsis: r[P3] = sqlite_offset(P1) */ +#define OP_Column 90 /* synopsis: r[P3]=PX */ +#define OP_Affinity 91 /* synopsis: affinity(r[P1@P2]) */ +#define OP_BitAnd 92 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ +#define OP_BitOr 93 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ +#define OP_ShiftLeft 94 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */ +#define OP_Add 96 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ +#define OP_Subtract 97 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ +#define OP_Multiply 98 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ +#define OP_Divide 99 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ +#define OP_Remainder 100 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ +#define OP_Concat 101 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ +#define OP_MakeRecord 102 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ +#define OP_BitNot 103 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */ +#define OP_Count 104 /* synopsis: r[P2]=count() */ +#define OP_ReadCookie 105 +#define OP_String8 106 /* same as TK_STRING, synopsis: r[P2]='P4' */ +#define OP_SetCookie 107 +#define OP_ReopenIdx 108 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenRead 109 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenWrite 110 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenDup 111 +#define OP_OpenAutoindex 112 /* synopsis: nColumn=P2 */ +#define OP_OpenEphemeral 113 /* synopsis: nColumn=P2 */ +#define OP_SorterOpen 114 +#define OP_SequenceTest 115 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ +#define OP_OpenPseudo 116 /* synopsis: P3 columns in r[P2] */ +#define OP_Close 117 +#define OP_ColumnsUsed 118 +#define OP_SeekHit 119 /* synopsis: seekHit=P2 */ +#define OP_Sequence 120 /* synopsis: r[P2]=cursor[P1].ctr++ */ +#define OP_NewRowid 121 /* synopsis: r[P2]=rowid */ +#define OP_Insert 122 /* synopsis: intkey=r[P3] data=r[P2] */ +#define OP_InsertInt 123 /* synopsis: intkey=P3 data=r[P2] */ +#define OP_Delete 124 +#define OP_ResetCount 125 +#define OP_SorterCompare 126 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ +#define OP_SorterData 127 /* synopsis: r[P2]=data */ +#define OP_RowData 128 /* synopsis: r[P2]=data */ +#define OP_Rowid 129 /* synopsis: r[P2]=rowid */ +#define OP_NullRow 130 +#define OP_SeekEnd 131 +#define OP_SorterInsert 132 /* synopsis: key=r[P2] */ +#define OP_IdxInsert 133 /* synopsis: key=r[P2] */ +#define OP_IdxDelete 134 /* synopsis: key=r[P2@P3] */ +#define OP_DeferredSeek 135 /* synopsis: Move P3 to P1.rowid if needed */ +#define OP_IdxRowid 136 /* synopsis: r[P2]=rowid */ +#define OP_Destroy 137 +#define OP_Clear 138 +#define OP_ResetSorter 139 +#define OP_CreateBtree 140 /* synopsis: r[P2]=root iDb=P1 flags=P3 */ +#define OP_Real 141 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ +#define OP_SqlExec 142 +#define OP_ParseSchema 143 +#define OP_LoadAnalysis 144 +#define OP_DropTable 145 +#define OP_DropIndex 146 +#define OP_DropTrigger 147 +#define OP_IntegrityCk 148 +#define OP_RowSetAdd 149 /* synopsis: rowset(P1)=r[P2] */ +#define OP_Param 150 +#define OP_FkCounter 151 /* synopsis: fkctr[P1]+=P2 */ +#define OP_MemMax 152 /* synopsis: r[P1]=max(r[P1],r[P2]) */ +#define OP_OffsetLimit 153 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ +#define OP_AggInverse 154 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */ +#define OP_AggStep 155 /* synopsis: accum=r[P3] step(r[P2@P5]) */ +#define OP_AggStep1 156 /* synopsis: accum=r[P3] step(r[P2@P5]) */ +#define OP_AggValue 157 /* synopsis: r[P3]=value N=P2 */ +#define OP_AggFinal 158 /* synopsis: accum=r[P1] N=P2 */ +#define OP_Expire 159 +#define OP_TableLock 160 /* synopsis: iDb=P1 root=P2 write=P3 */ +#define OP_VBegin 161 +#define OP_VCreate 162 +#define OP_VDestroy 163 +#define OP_VOpen 164 +#define OP_VColumn 165 /* synopsis: r[P3]=vcolumn(P2) */ +#define OP_VRename 166 +#define OP_Pagecount 167 +#define OP_MaxPgcnt 168 +#define OP_Trace 169 +#define OP_CursorHint 170 +#define OP_Noop 171 +#define OP_Explain 172 +#define OP_Abortable 173 /* Properties such as "out2" or "jump" that are specified in ** comments following the "case" for each opcode in the vdbe.c @@ -14661,28 +14851,28 @@ typedef struct VdbeOpList VdbeOpList; #define OPFLG_OUT2 0x10 /* out2: P2 is an output */ #define OPFLG_OUT3 0x20 /* out3: P3 is an output */ #define OPFLG_INITIALIZER {\ -/* 0 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,\ -/* 8 */ 0x00, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01,\ -/* 16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0x03, 0x03, 0x01,\ +/* 0 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x10,\ +/* 8 */ 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03,\ +/* 16 */ 0x01, 0x01, 0x03, 0x12, 0x03, 0x01, 0x09, 0x09,\ /* 24 */ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,\ -/* 32 */ 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\ -/* 40 */ 0x01, 0x01, 0x23, 0x26, 0x26, 0x0b, 0x01, 0x01,\ +/* 32 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\ +/* 40 */ 0x01, 0x23, 0x0b, 0x26, 0x26, 0x01, 0x01, 0x03,\ /* 48 */ 0x03, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\ -/* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x01, 0x01, 0x01, 0x02,\ -/* 64 */ 0x02, 0x08, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00,\ -/* 72 */ 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\ -/* 80 */ 0x02, 0x02, 0x02, 0x00, 0x00, 0x26, 0x26, 0x26,\ -/* 88 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x12,\ -/* 96 */ 0x12, 0x20, 0x00, 0x10, 0x00, 0x00, 0x10, 0x10,\ -/* 104 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 112 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\ -/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\ -/* 128 */ 0x04, 0x04, 0x00, 0x00, 0x10, 0x10, 0x10, 0x00,\ -/* 136 */ 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 144 */ 0x00, 0x06, 0x10, 0x00, 0x04, 0x1a, 0x00, 0x00,\ -/* 152 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 160 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 168 */ 0x00, 0x00, 0x00, 0x00,} +/* 56 */ 0x0b, 0x0b, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,\ +/* 64 */ 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10, 0x10,\ +/* 72 */ 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10,\ +/* 80 */ 0x10, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,\ +/* 88 */ 0x12, 0x20, 0x00, 0x00, 0x26, 0x26, 0x26, 0x26,\ +/* 96 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x00, 0x12,\ +/* 104 */ 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 112 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 120 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 128 */ 0x00, 0x10, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00,\ +/* 136 */ 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\ +/* 144 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10, 0x00,\ +/* 152 */ 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 160 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\ +/* 168 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,} /* The sqlite3P2Values() routine is able to run faster if it knows ** the value of the largest JUMP opcode. The smaller the maximum @@ -14690,7 +14880,7 @@ typedef struct VdbeOpList VdbeOpList; ** generated this include file strives to group all JUMP opcodes ** together near the beginning of the list. */ -#define SQLITE_MX_JUMP_OPCODE 62 /* Maximum JUMP opcode */ +#define SQLITE_MX_JUMP_OPCODE 61 /* Maximum JUMP opcode */ /************** End of opcodes.h *********************************************/ /************** Continuing where we left off in vdbe.h ***********************/ @@ -14764,9 +14954,6 @@ SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3*,Vdbe*); SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,Parse*); SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int); -#ifdef SQLITE_COVERAGE_TEST -SQLITE_PRIVATE int sqlite3VdbeLabelHasBeenResolved(Vdbe*,int); -#endif SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*); #ifdef SQLITE_DEBUG SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *, int); @@ -14788,6 +14975,7 @@ SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int); SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); #endif SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); +SQLITE_PRIVATE int sqlite3BlobCompare(const Mem*, const Mem*); SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); @@ -14843,23 +15031,52 @@ SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe*, const char*, ...); ** ** VdbeCoverageNeverTaken(v) // Previous branch is never taken ** +** VdbeCoverageNeverNull(v) // Previous three-way branch is only +** // taken on the first two ways. The +** // NULL option is not possible +** +** VdbeCoverageEqNe(v) // Previous OP_Jump is only interested +** // in distingishing equal and not-equal. +** ** Every VDBE branch operation must be tagged with one of the macros above. ** If not, then when "make test" is run with -DSQLITE_VDBE_COVERAGE and ** -DSQLITE_DEBUG then an ALWAYS() will fail in the vdbeTakeBranch() ** routine in vdbe.c, alerting the developer to the missed tag. +** +** During testing, the test application will invoke +** sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE,...) to set a callback +** routine that is invoked as each bytecode branch is taken. The callback +** contains the sqlite3.c source line number ov the VdbeCoverage macro and +** flags to indicate whether or not the branch was taken. The test application +** is responsible for keeping track of this and reporting byte-code branches +** that are never taken. +** +** See the VdbeBranchTaken() macro and vdbeTakeBranch() function in the +** vdbe.c source file for additional information. */ #ifdef SQLITE_VDBE_COVERAGE SQLITE_PRIVATE void sqlite3VdbeSetLineNumber(Vdbe*,int); # define VdbeCoverage(v) sqlite3VdbeSetLineNumber(v,__LINE__) # define VdbeCoverageIf(v,x) if(x)sqlite3VdbeSetLineNumber(v,__LINE__) -# define VdbeCoverageAlwaysTaken(v) sqlite3VdbeSetLineNumber(v,2); -# define VdbeCoverageNeverTaken(v) sqlite3VdbeSetLineNumber(v,1); +# define VdbeCoverageAlwaysTaken(v) \ + sqlite3VdbeSetLineNumber(v,__LINE__|0x5000000); +# define VdbeCoverageNeverTaken(v) \ + sqlite3VdbeSetLineNumber(v,__LINE__|0x6000000); +# define VdbeCoverageNeverNull(v) \ + sqlite3VdbeSetLineNumber(v,__LINE__|0x4000000); +# define VdbeCoverageNeverNullIf(v,x) \ + if(x)sqlite3VdbeSetLineNumber(v,__LINE__|0x4000000); +# define VdbeCoverageEqNe(v) \ + sqlite3VdbeSetLineNumber(v,__LINE__|0x8000000); # define VDBE_OFFSET_LINENO(x) (__LINE__+x) #else # define VdbeCoverage(v) # define VdbeCoverageIf(v,x) # define VdbeCoverageAlwaysTaken(v) # define VdbeCoverageNeverTaken(v) +# define VdbeCoverageNeverNull(v) +# define VdbeCoverageNeverNullIf(v,x) +# define VdbeCoverageEqNe(v) # define VDBE_OFFSET_LINENO(x) 0 #endif @@ -14869,6 +15086,10 @@ SQLITE_PRIVATE void sqlite3VdbeScanStatus(Vdbe*, int, int, int, LogEst, const ch # define sqlite3VdbeScanStatus(a,b,c,d,e) #endif +#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) +SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, VdbeOp*); +#endif + #endif /* SQLITE_VDBE_H */ /************** End of vdbe.h ************************************************/ @@ -15063,6 +15284,8 @@ SQLITE_PRIVATE int sqlite3PagerUseWal(Pager *pPager, Pgno); SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot); SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot); SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager); +SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot); +SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager); # endif #else # define sqlite3PagerUseWal(x,y) 0 @@ -16046,6 +16269,7 @@ struct sqlite3 { #define SQLITE_EnableQPSG 0x00800000 /* Query Planner Stability Guarantee*/ #define SQLITE_TriggerEQP 0x01000000 /* Show trigger EXPLAIN QUERY PLAN */ #define SQLITE_ResetDatabase 0x02000000 /* Reset the database */ +#define SQLITE_LegacyAlter 0x04000000 /* Legacy ALTER TABLE behaviour */ /* Flags used only if debugging */ #ifdef SQLITE_DEBUG @@ -16070,7 +16294,7 @@ struct sqlite3 { ** selectively disable various optimizations. */ #define SQLITE_QueryFlattener 0x0001 /* Query flattening */ -#define SQLITE_ColumnCache 0x0002 /* Column cache */ + /* 0x0002 available for reuse */ #define SQLITE_GroupByOrder 0x0004 /* GROUPBY cover of ORDERBY */ #define SQLITE_FactorOutConst 0x0008 /* Constant factoring */ #define SQLITE_DistinctOpt 0x0010 /* DISTINCT using indexes */ @@ -16084,6 +16308,8 @@ struct sqlite3 { /* TH3 expects the Stat34 ^^^^^^ value to be 0x0800. Don't change it */ #define SQLITE_PushDown 0x1000 /* The push-down optimization */ #define SQLITE_SimplifyJoin 0x2000 /* Convert LEFT JOIN to JOIN */ +#define SQLITE_SkipScan 0x4000 /* Skip-scans */ +#define SQLITE_PropagateConst 0x8000 /* The constant propagation opt */ #define SQLITE_AllOpts 0xffff /* All optimizations */ /* @@ -16122,11 +16348,13 @@ struct sqlite3 { */ struct FuncDef { i8 nArg; /* Number of arguments. -1 means unlimited */ - u16 funcFlags; /* Some combination of SQLITE_FUNC_* */ + u32 funcFlags; /* Some combination of SQLITE_FUNC_* */ void *pUserData; /* User data parameter */ FuncDef *pNext; /* Next function with same name */ void (*xSFunc)(sqlite3_context*,int,sqlite3_value**); /* func or agg-step */ void (*xFinalize)(sqlite3_context*); /* Agg finalizer */ + void (*xValue)(sqlite3_context*); /* Current agg value */ + void (*xInverse)(sqlite3_context*,int,sqlite3_value**); /* inverse agg-step */ const char *zName; /* SQL name of the function. */ union { FuncDef *pHash; /* Next with a different name but the same hash */ @@ -16183,6 +16411,8 @@ struct FuncDestructor { ** single query - might change over time */ #define SQLITE_FUNC_AFFINITY 0x4000 /* Built-in affinity() function */ #define SQLITE_FUNC_OFFSET 0x8000 /* Built-in sqlite_offset() function */ +#define SQLITE_FUNC_WINDOW 0x10000 /* Built-in window-only function */ +#define SQLITE_FUNC_WINDOW_SIZE 0x20000 /* Requires partition size as arg. */ /* ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are @@ -16217,6 +16447,12 @@ struct FuncDestructor { ** are interpreted in the same way as the first 4 parameters to ** FUNCTION(). ** +** WFUNCTION(zName, nArg, iArg, xStep, xFinal, xValue, xInverse) +** Used to create an aggregate function definition implemented by +** the C functions xStep and xFinal. The first four parameters +** are interpreted in the same way as the first 4 parameters to +** FUNCTION(). +** ** LIKEFUNC(zName, nArg, pArg, flags) ** Used to create a scalar function definition of a function zName ** that accepts nArg arguments and is implemented by a call to C @@ -16227,31 +16463,35 @@ struct FuncDestructor { */ #define FUNCTION(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ - SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} } + SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } #define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ - SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} } + SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } #define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8, \ - 0, 0, xFunc, 0, #zName, {0} } + 0, 0, xFunc, 0, 0, 0, #zName, {0} } #define PURE_DATE(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \ - (void*)&sqlite3Config, 0, xFunc, 0, #zName, {0} } + (void*)&sqlite3Config, 0, xFunc, 0, 0, 0, #zName, {0} } #define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \ {nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\ - SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} } + SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } #define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \ {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ - pArg, 0, xFunc, 0, #zName, } + pArg, 0, xFunc, 0, 0, 0, #zName, } #define LIKEFUNC(zName, nArg, arg, flags) \ {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \ - (void *)arg, 0, likeFunc, 0, #zName, {0} } -#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \ + (void *)arg, 0, likeFunc, 0, 0, 0, #zName, {0} } +#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue) \ {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \ - SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName, {0}} + SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,0,#zName, {0}} #define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \ {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \ - SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName, {0}} + SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xFinal,0,#zName, {0}} + +#define WAGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue, xInverse, f) \ + {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|f, \ + SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,xInverse,#zName, {0}} /* ** All current savepoints are stored in a linked list starting at @@ -16737,6 +16977,7 @@ struct Index { tRowcnt *aiRowEst; /* Non-logarithmic stat1 data for this index */ tRowcnt nRowEst0; /* Non-logarithmic number of rows in the index */ #endif + Bitmask colNotIdxed; /* 0 for unindexed columns in pTab */ }; /* @@ -16775,9 +17016,11 @@ struct IndexSample { ** Each token coming out of the lexer is an instance of ** this structure. Tokens are also used as part of an expression. ** -** Note if Token.z==0 then Token.dyn and Token.n are undefined and -** may contain random values. Do not make any assumptions about Token.dyn -** and Token.n when Token.z==0. +** The memory that "z" points to is owned by other objects. Take care +** that the owner of the "z" string does not deallocate the string before +** the Token goes out of scope! Very often, the "z" points to some place +** in the middle of the Parse.zSql text. But it might also point to a +** static string. */ struct Token { const char *z; /* Text of the token. Not NULL-terminated! */ @@ -16952,6 +17195,9 @@ struct Expr { AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ Table *pTab; /* Table for TK_COLUMN expressions. Can be NULL ** for a column of an index on an expression */ +#ifndef SQLITE_OMIT_WINDOWFUNC + Window *pWin; /* Window definition for window functions */ +#endif }; /* @@ -16960,7 +17206,7 @@ struct Expr { #define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */ #define EP_Agg 0x000002 /* Contains one or more aggregate functions */ #define EP_HasFunc 0x000004 /* Contains one or more functions of any kind */ - /* 0x000008 // available for use */ +#define EP_FixedCol 0x000008 /* TK_Column with a known fixed value */ #define EP_Distinct 0x000010 /* Aggregate function with DISTINCT keyword */ #define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */ #define EP_DblQuoted 0x000040 /* token.z was originally in "..." */ @@ -17082,31 +17328,6 @@ struct IdList { int nId; /* Number of identifiers on the list */ }; -/* -** The bitmask datatype defined below is used for various optimizations. -** -** Changing this from a 64-bit to a 32-bit type limits the number of -** tables in a join to 32 instead of 64. But it also reduces the size -** of the library by 738 bytes on ix86. -*/ -#ifdef SQLITE_BITMASK_TYPE - typedef SQLITE_BITMASK_TYPE Bitmask; -#else - typedef u64 Bitmask; -#endif - -/* -** The number of bits in a Bitmask. "BMS" means "BitMask Size". -*/ -#define BMS ((int)(sizeof(Bitmask)*8)) - -/* -** A bit in a Bitmask -*/ -#define MASKBIT(n) (((Bitmask)1)<<(n)) -#define MASKBIT32(n) (((unsigned int)1)<<(n)) -#define ALLBITS ((Bitmask)-1) - /* ** The following structure describes the FROM clause of a SELECT statement. ** Each table or subquery in the FROM clause is a separate element of @@ -17238,6 +17459,7 @@ struct NameContext { int nRef; /* Number of names resolved by this context */ int nErr; /* Number of errors encountered while resolving names */ u16 ncFlags; /* Zero or more NC_* flags defined below */ + Select *pWinSelect; /* SELECT statement for any window functions */ }; /* @@ -17260,6 +17482,7 @@ struct NameContext { #define NC_UUpsert 0x0200 /* True if uNC.pUpsert is used */ #define NC_MinMaxAgg 0x1000 /* min/max aggregates seen. See note above */ #define NC_Complex 0x2000 /* True if a function or subquery seen */ +#define NC_AllowWin 0x4000 /* Window functions are allowed here */ /* ** An instance of the following object describes a single ON CONFLICT @@ -17314,9 +17537,7 @@ struct Select { LogEst nSelectRow; /* Estimated number of result rows */ u32 selFlags; /* Various SF_* values */ int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */ -#if SELECTTRACE_ENABLED - char zSelName[12]; /* Symbolic name of this SELECT use for debugging */ -#endif + u32 selId; /* Unique identifier number for this SELECT */ int addrOpenEphm[2]; /* OP_OpenEphem opcodes related to this select */ SrcList *pSrc; /* The FROM clause */ Expr *pWhere; /* The WHERE clause */ @@ -17327,6 +17548,10 @@ struct Select { Select *pNext; /* Next select to the left in a compound */ Expr *pLimit; /* LIMIT expression. NULL means not used. */ With *pWith; /* WITH clause attached to this select. Or NULL. */ +#ifndef SQLITE_OMIT_WINDOWFUNC + Window *pWin; /* List of window functions */ + Window *pWinDefn; /* List of named window definitions */ +#endif }; /* @@ -17470,13 +17695,6 @@ struct AutoincInfo { int regCtr; /* Memory register holding the rowid counter */ }; -/* -** Size of the column cache -*/ -#ifndef SQLITE_N_COLCACHE -# define SQLITE_N_COLCACHE 10 -#endif - /* ** At least one instance of the following structure is created for each ** trigger that may be fired while parsing an INSERT, UPDATE or DELETE @@ -17552,7 +17770,6 @@ struct Parse { u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */ u8 okConstFactor; /* OK to factor out constants */ u8 disableLookaside; /* Number of times lookaside has been disabled */ - u8 nColCache; /* Number of entries in aColCache[] */ int nRangeReg; /* Size of the temporary register block */ int iRangeReg; /* First register in temporary register block */ int nErr; /* Number of errors seen */ @@ -17562,8 +17779,6 @@ struct Parse { int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */ int iSelfTab; /* Table associated with an index on expr, or negative ** of the base register during check-constraint eval */ - int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */ - int iCacheCnt; /* Counter used to generate aColCache[].lru values */ int nLabel; /* Number of labels used */ int *aLabel; /* Space to hold the labels */ ExprList *pConstExpr;/* Constant expressions */ @@ -17573,9 +17788,7 @@ struct Parse { int regRowid; /* Register holding rowid of CREATE TABLE entry */ int regRoot; /* Register holding root page number for new objects */ int nMaxArg; /* Max args passed to user function by sub-program */ -#if SELECTTRACE_ENABLED - int nSelect; /* Number of SELECT statements seen */ -#endif + int nSelect; /* Number of SELECT stmts. Counter for Select.selId */ #ifndef SQLITE_OMIT_SHARED_CACHE int nTableLock; /* Number of locks in aTableLock */ TableLock *aTableLock; /* Required table locks for shared-cache mode */ @@ -17595,17 +17808,9 @@ struct Parse { ** Fields above must be initialized to zero. The fields that follow, ** down to the beginning of the recursive section, do not need to be ** initialized as they will be set before being used. The boundary is - ** determined by offsetof(Parse,aColCache). + ** determined by offsetof(Parse,aTempReg). **************************************************************************/ - struct yColCache { - int iTable; /* Table cursor number */ - i16 iColumn; /* Table column number */ - u8 tempReg; /* iReg is a temp register that needs to be freed */ - int iLevel; /* Nesting level */ - int iReg; /* Reg with value of this column. 0 means none. */ - int lru; /* Least recently used entry has the smallest value */ - } aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */ int aTempReg[8]; /* Holding area for temporary registers */ Token sNameToken; /* Token with unqualified schema object name */ @@ -17620,8 +17825,10 @@ struct Parse { ynVar nVar; /* Number of '?' variables seen in the SQL so far */ u8 iPkSortOrder; /* ASC or DESC for INTEGER PRIMARY KEY */ u8 explain; /* True if the EXPLAIN flag is found on the query */ +#if !(defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_OMIT_ALTERTABLE)) + u8 eParseMode; /* PARSE_MODE_XXX constant */ +#endif #ifndef SQLITE_OMIT_VIRTUALTABLE - u8 declareVtab; /* True if inside sqlite3_declare_vtab() */ int nVtabLock; /* Number of virtual tables to lock */ #endif int nHeight; /* Expression tree height of current sub-select */ @@ -17632,6 +17839,7 @@ struct Parse { Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */ const char *zTail; /* All SQL text past the last semicolon parsed */ Table *pNewTable; /* A table being constructed by CREATE TABLE */ + Index *pNewIndex; /* An index being constructed by CREATE INDEX */ Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */ const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */ #ifndef SQLITE_OMIT_VIRTUALTABLE @@ -17642,12 +17850,20 @@ struct Parse { TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */ With *pWith; /* Current WITH clause, or NULL */ With *pWithToFree; /* Free this WITH object at the end of the parse */ +#ifndef SQLITE_OMIT_ALTERTABLE + RenameToken *pRename; /* Tokens subject to renaming by ALTER TABLE */ +#endif }; +#define PARSE_MODE_NORMAL 0 +#define PARSE_MODE_DECLARE_VTAB 1 +#define PARSE_MODE_RENAME_COLUMN 2 +#define PARSE_MODE_RENAME_TABLE 3 + /* ** Sizes and pointers of various parts of the Parse object. */ -#define PARSE_HDR_SZ offsetof(Parse,aColCache) /* Recursive part w/o aColCache*/ +#define PARSE_HDR_SZ offsetof(Parse,aTempReg) /* Recursive part w/o aColCache*/ #define PARSE_RECURSE_SZ offsetof(Parse,sLastToken) /* Recursive part */ #define PARSE_TAIL_SZ (sizeof(Parse)-PARSE_RECURSE_SZ) /* Non-recursive part */ #define PARSE_TAIL(X) (((char*)(X))+PARSE_RECURSE_SZ) /* Pointer to tail */ @@ -17658,7 +17874,19 @@ struct Parse { #ifdef SQLITE_OMIT_VIRTUALTABLE #define IN_DECLARE_VTAB 0 #else - #define IN_DECLARE_VTAB (pParse->declareVtab) + #define IN_DECLARE_VTAB (pParse->eParseMode==PARSE_MODE_DECLARE_VTAB) +#endif + +#if defined(SQLITE_OMIT_ALTERTABLE) + #define IN_RENAME_OBJECT 0 +#else + #define IN_RENAME_OBJECT (pParse->eParseMode>=PARSE_MODE_RENAME_COLUMN) +#endif + +#if defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_OMIT_ALTERTABLE) + #define IN_SPECIAL_PARSE 0 +#else + #define IN_SPECIAL_PARSE (pParse->eParseMode!=PARSE_MODE_NORMAL) #endif /* @@ -17837,8 +18065,14 @@ typedef struct { char **pzErrMsg; /* Error message stored here */ int iDb; /* 0 for main database. 1 for TEMP, 2.. for ATTACHed */ int rc; /* Result code stored here */ + u32 mInitFlags; /* Flags controlling error messages */ } InitData; +/* +** Allowed values for mInitFlags +*/ +#define INITFLAG_AlterTable 0x0001 /* This is a reparse after ALTER TABLE */ + /* ** Structure containing global configuration data for the SQLite library. ** @@ -17889,7 +18123,7 @@ struct Sqlite3Config { /* The following callback (if not NULL) is invoked on every VDBE branch ** operation. Set the callback using SQLITE_TESTCTRL_VDBE_COVERAGE. */ - void (*xVdbeBranch)(void*,int iSrcLine,u8 eThis,u8 eMx); /* Callback */ + void (*xVdbeBranch)(void*,unsigned iSrcLine,u8 eThis,u8 eMx); /* Callback */ void *pVdbeBranchArg; /* 1st argument */ #endif #ifndef SQLITE_UNTESTABLE @@ -17940,6 +18174,9 @@ struct Walker { struct IdxExprTrans *pIdxTrans; /* Convert idxed expr to column */ ExprList *pGroupBy; /* GROUP BY clause */ Select *pSelect; /* HAVING to WHERE clause ctx */ + struct WindowRewrite *pRewrite; /* Window rewrite context */ + struct WhereConst *pConst; /* WHERE clause constants */ + struct RenameCtx *pRename; /* RENAME COLUMN context */ } u; }; @@ -17990,6 +18227,68 @@ struct TreeView { }; #endif /* SQLITE_DEBUG */ +/* +** This object is used in varioius ways, all related to window functions +** +** (1) A single instance of this structure is attached to the +** the Expr.pWin field for each window function in an expression tree. +** This object holds the information contained in the OVER clause, +** plus additional fields used during code generation. +** +** (2) All window functions in a single SELECT form a linked-list +** attached to Select.pWin. The Window.pFunc and Window.pExpr +** fields point back to the expression that is the window function. +** +** (3) The terms of the WINDOW clause of a SELECT are instances of this +** object on a linked list attached to Select.pWinDefn. +** +** The uses (1) and (2) are really the same Window object that just happens +** to be accessible in two different ways. Use (3) is are separate objects. +*/ +struct Window { + char *zName; /* Name of window (may be NULL) */ + ExprList *pPartition; /* PARTITION BY clause */ + ExprList *pOrderBy; /* ORDER BY clause */ + u8 eType; /* TK_RANGE or TK_ROWS */ + u8 eStart; /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */ + u8 eEnd; /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */ + Expr *pStart; /* Expression for " PRECEDING" */ + Expr *pEnd; /* Expression for " FOLLOWING" */ + Window *pNextWin; /* Next window function belonging to this SELECT */ + Expr *pFilter; /* The FILTER expression */ + FuncDef *pFunc; /* The function */ + int iEphCsr; /* Partition buffer or Peer buffer */ + int regAccum; + int regResult; + int csrApp; /* Function cursor (used by min/max) */ + int regApp; /* Function register (also used by min/max) */ + int regPart; /* First in a set of registers holding PARTITION BY + ** and ORDER BY values for the window */ + Expr *pOwner; /* Expression object this window is attached to */ + int nBufferCol; /* Number of columns in buffer table */ + int iArgCol; /* Offset of first argument for this function */ +}; + +#ifndef SQLITE_OMIT_WINDOWFUNC +SQLITE_PRIVATE void sqlite3WindowDelete(sqlite3*, Window*); +SQLITE_PRIVATE void sqlite3WindowListDelete(sqlite3 *db, Window *p); +SQLITE_PRIVATE Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*); +SQLITE_PRIVATE void sqlite3WindowAttach(Parse*, Expr*, Window*); +SQLITE_PRIVATE int sqlite3WindowCompare(Parse*, Window*, Window*); +SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse*, Window*); +SQLITE_PRIVATE void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int); +SQLITE_PRIVATE int sqlite3WindowRewrite(Parse*, Select*); +SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse*, struct SrcList_item*); +SQLITE_PRIVATE void sqlite3WindowUpdate(Parse*, Window*, Window*, FuncDef*); +SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p); +SQLITE_PRIVATE Window *sqlite3WindowListDup(sqlite3 *db, Window *p); +SQLITE_PRIVATE void sqlite3WindowFunctions(void); +#else +# define sqlite3WindowDelete(a,b) +# define sqlite3WindowFunctions() +# define sqlite3WindowAttach(a,b,c) +#endif + /* ** Assuming zIn points to the first byte of a UTF-8 character, ** advance zIn to point to the first byte of the next UTF-8 character. @@ -18077,9 +18376,7 @@ SQLITE_PRIVATE int sqlite3CorruptPgnoError(int,Pgno); # define sqlite3Tolower(x) tolower((unsigned char)(x)) # define sqlite3Isquote(x) ((x)=='"'||(x)=='\''||(x)=='['||(x)=='`') #endif -#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS SQLITE_PRIVATE int sqlite3IsIdChar(u8); -#endif /* ** Internal function prototypes @@ -18204,6 +18501,10 @@ SQLITE_PRIVATE void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, co SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*); SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8); SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView*, const With*, u8); +#ifndef SQLITE_OMIT_WINDOWFUNC +SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView*, const Window*, u8); +SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8); +#endif #endif @@ -18228,7 +18529,7 @@ SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*); SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*); SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*); SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*); -SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*); +SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int); SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*); SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); @@ -18240,6 +18541,7 @@ SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*); SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*); SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**); SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**); +SQLITE_PRIVATE int sqlite3InitOne(sqlite3*, int, char**, u32); SQLITE_PRIVATE void sqlite3Pragma(Parse*,Token*,Token*,Token*,int); #ifndef SQLITE_OMIT_VIRTUALTABLE SQLITE_PRIVATE Module *sqlite3PragmaVtabRegister(sqlite3*,const char *zName); @@ -18289,8 +18591,9 @@ SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec*); SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int,int*); #endif -SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3*, void*, unsigned int); -SQLITE_PRIVATE void sqlite3RowSetClear(RowSet*); +SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3*); +SQLITE_PRIVATE void sqlite3RowSetDelete(void*); +SQLITE_PRIVATE void sqlite3RowSetClear(void*); SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet*, i64); SQLITE_PRIVATE int sqlite3RowSetTest(RowSet*, int iBatch, i64); SQLITE_PRIVATE int sqlite3RowSetNext(RowSet*, i64*); @@ -18309,6 +18612,7 @@ SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask); SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int); SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int); SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*); +SQLITE_PRIVATE void sqlite3FreeIndex(sqlite3*, Index*); #ifndef SQLITE_OMIT_AUTOINCREMENT SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse); SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse); @@ -18318,7 +18622,7 @@ SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse); #endif SQLITE_PRIVATE void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int, Upsert*); SQLITE_PRIVATE void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*); -SQLITE_PRIVATE IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*); +SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse*, IdList*, Token*); SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*); SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(sqlite3*, SrcList*, int, int); SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(sqlite3*, SrcList*, Token*, Token*); @@ -18353,7 +18657,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*); SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo*); SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*); SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*); -SQLITE_PRIVATE int sqlite3WhereOrderedInnerLoop(WhereInfo*); +SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo*); SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo*); SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo*); SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo*); @@ -18363,15 +18667,8 @@ SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo*, int*); #define ONEPASS_MULTI 2 /* ONEPASS is valid for multiple rows */ SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int); SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); -SQLITE_PRIVATE void sqlite3ExprCodeGetColumnToReg(Parse*, Table*, int, int, int); SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int); -SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse*, int, int, int); -SQLITE_PRIVATE void sqlite3ExprCachePush(Parse*); -SQLITE_PRIVATE void sqlite3ExprCachePop(Parse*); -SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse*, int, int); -SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse*); -SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse*, int, int); SQLITE_PRIVATE void sqlite3ExprCode(Parse*, Expr*, int); SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, Expr*, int); SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse*, Expr*, int); @@ -18459,11 +18756,6 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int); SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int); SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*); SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int); -#if SELECTTRACE_ENABLED -SQLITE_PRIVATE void sqlite3SelectSetName(Select*,const char*); -#else -# define sqlite3SelectSetName(A,B) -#endif SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(FuncDef*,int); SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8); SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void); @@ -18492,12 +18784,12 @@ SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect(Parse *, Trigger *, Table *, i SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*); SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*, const char*,const char*); -SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(sqlite3*,Token*, IdList*, +SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(Parse*,Token*, IdList*, Select*,u8,Upsert*, const char*,const char*); -SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(sqlite3*,Token*,ExprList*, Expr*, u8, +SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(Parse*,Token*,ExprList*, Expr*, u8, const char*,const char*); -SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(sqlite3*,Token*, Expr*, +SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(Parse*,Token*, Expr*, const char*,const char*); SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3*, Trigger*); SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*); @@ -18612,6 +18904,7 @@ SQLITE_PRIVATE int sqlite3MemdbInit(void); SQLITE_PRIVATE const char *sqlite3ErrStr(int); SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse); SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); +SQLITE_PRIVATE int sqlite3IsBinary(const CollSeq*); SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr); @@ -18664,9 +18957,10 @@ SQLITE_PRIVATE void sqlite3RootPageMoved(sqlite3*, int, int, int); SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*); SQLITE_PRIVATE void sqlite3AlterFunctions(void); SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*); +SQLITE_PRIVATE void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*); SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *); SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...); -SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*); +SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*, int); SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr *, int, int); SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*); SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p); @@ -18679,6 +18973,10 @@ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int); SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *); SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *); +SQLITE_PRIVATE void *sqlite3RenameTokenMap(Parse*, void*, Token*); +SQLITE_PRIVATE void sqlite3RenameTokenRemap(Parse*, void *pTo, void *pFrom); +SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse*, Expr*); +SQLITE_PRIVATE void sqlite3RenameExprlistUnmap(Parse*, ExprList*); SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*); SQLITE_PRIVATE char sqlite3AffinityType(const char*, Column*); SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*); @@ -18697,12 +18995,17 @@ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int,int); SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo*); SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoRef(KeyInfo*); SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*); +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoFromExprList(Parse*, ExprList*, int, int); + #ifdef SQLITE_DEBUG SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo*); #endif SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, void (*)(sqlite3_context*,int,sqlite3_value **), - void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*), + void (*)(sqlite3_context*,int,sqlite3_value **), + void (*)(sqlite3_context*), + void (*)(sqlite3_context*), + void (*)(sqlite3_context*,int,sqlite3_value **), FuncDestructor *pDestructor ); SQLITE_PRIVATE void sqlite3NoopDestructor(void*); @@ -18743,6 +19046,7 @@ SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(u64), Parse*); SQLITE_PRIVATE void sqlite3ParserFree(void*, void(*)(void*)); #endif SQLITE_PRIVATE void sqlite3Parser(void*, int, Token); +SQLITE_PRIVATE int sqlite3ParserFallback(int); #ifdef YYTRACKMAXSTACKDEPTH SQLITE_PRIVATE int sqlite3ParserStackPeak(void*); #endif @@ -19443,6 +19747,7 @@ struct VdbeCursor { Bool isEphemeral:1; /* True for an ephemeral table */ Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */ Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */ + Bool seekHit:1; /* See the OP_SeekHit and OP_IfNoHope opcodes */ Btree *pBtx; /* Separate file holding temporary table */ i64 seqCount; /* Sequence counter */ int *aAltMap; /* Mapping from table to index column numbers */ @@ -19526,6 +19831,9 @@ struct VdbeFrame { void *token; /* Copy of SubProgram.token */ i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */ AuxData *pAuxData; /* Linked list of auxdata allocations */ +#if SQLITE_DEBUG + u32 iFrameMagic; /* magic number for sanity checking */ +#endif int nCursor; /* Number of entries in apCsr */ int pc; /* Program Counter in parent (calling) frame */ int nOp; /* Size of aOp array */ @@ -19536,6 +19844,13 @@ struct VdbeFrame { int nDbChange; /* Value of db->nChange */ }; +/* Magic number for sanity checking on VdbeFrame objects */ +#define SQLITE_FRAME_MAGIC 0x879fb71e + +/* +** Return a pointer to the array of registers allocated for use +** by a VdbeFrame. +*/ #define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))]) /* @@ -19550,8 +19865,6 @@ struct sqlite3_value { int nZero; /* Extra zero bytes when MEM_Zero and MEM_Blob set */ const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */ FuncDef *pDef; /* Used only when flags==MEM_Agg */ - RowSet *pRowSet; /* Used only when flags==MEM_RowSet */ - VdbeFrame *pFrame; /* Used when flags==MEM_Frame */ } u; u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */ u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */ @@ -19566,7 +19879,7 @@ struct sqlite3_value { void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */ #ifdef SQLITE_DEBUG Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */ - void *pFiller; /* So that sizeof(Mem) is a multiple of 8 */ + u16 mScopyFlags; /* flags value immediately after the shallow copy */ #endif }; @@ -19595,8 +19908,8 @@ struct sqlite3_value { #define MEM_Real 0x0008 /* Value is a real number */ #define MEM_Blob 0x0010 /* Value is a BLOB */ #define MEM_AffMask 0x001f /* Mask of affinity bits */ -#define MEM_RowSet 0x0020 /* Value is a RowSet object */ -#define MEM_Frame 0x0040 /* Value is a VdbeFrame object */ +/* Available 0x0020 */ +/* Available 0x0040 */ #define MEM_Undefined 0x0080 /* Value is undefined */ #define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */ #define MEM_TypeMask 0xc1ff /* Mask of type bits */ @@ -19623,7 +19936,7 @@ struct sqlite3_value { ** that needs to be deallocated to avoid a leak. */ #define VdbeMemDynamic(X) \ - (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0) + (((X)->flags&(MEM_Agg|MEM_Dyn))!=0) /* ** Clear any existing type flags from a Mem and replace them with f @@ -19743,9 +20056,9 @@ struct Vdbe { u8 errorAction; /* Recovery action to do in case of an error */ u8 minWriteFileFormat; /* Minimum file format for writable database files */ u8 prepFlags; /* SQLITE_PREPARE_* flags */ - bft expired:1; /* True if the VM needs to be recompiled */ - bft doingRerun:1; /* True if rerunning after an auto-reprepare */ + bft expired:2; /* 1: recompile VM immediately 2: when convenient */ bft explain:2; /* True if EXPLAIN present on SQL command */ + bft doingRerun:1; /* True if rerunning after an auto-reprepare */ bft changeCntOn:1; /* True to update the change-counter */ bft runOnlyOnce:1; /* Automatically expire on reset */ bft usesStmtJournal:1; /* True if uses a statement journal */ @@ -19806,9 +20119,6 @@ SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*); void sqliteVdbePopStack(Vdbe*,int); SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor**, int*); SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*); -#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) -SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*); -#endif SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32); SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8); SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int, u32*); @@ -19839,7 +20149,10 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetPointer(Mem*, void*, const char*, void(*)(v SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16); SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*); SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int); -SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem*); +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem*); +#endif +SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8); SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*); @@ -19853,11 +20166,18 @@ SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem*,u8,u8); SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*); SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p); SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*); +#ifndef SQLITE_OMIT_WINDOWFUNC +SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*); +#endif SQLITE_PRIVATE const char *sqlite3OpcodeName(int); SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n); SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int); -SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*); +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3VdbeFrameIsValid(VdbeFrame*); +#endif +SQLITE_PRIVATE void sqlite3VdbeFrameMemDel(void*); /* Destructor on Mem */ +SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*); /* Actually deletes the Frame */ SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *); #ifdef SQLITE_ENABLE_PREUPDATE_HOOK SQLITE_PRIVATE void sqlite3VdbePreUpdateHook(Vdbe*,VdbeCursor*,int,const char*,Table*,i64,int); @@ -21955,9 +22275,12 @@ SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){ ** Unregister a VFS so that it is no longer accessible. */ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){ -#if SQLITE_THREADSAFE - sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); + MUTEX_LOGIC(sqlite3_mutex *mutex;) +#ifndef SQLITE_OMIT_AUTOINIT + int rc = sqlite3_initialize(); + if( rc ) return rc; #endif + MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) sqlite3_mutex_enter(mutex); vfsUnlink(pVfs); sqlite3_mutex_leave(mutex); @@ -27288,7 +27611,12 @@ SQLITE_API void sqlite3_str_vappendf( if( bufpt==0 ){ bufpt = ""; }else if( xtype==etDYNSTRING ){ - if( pAccum->nChar==0 && pAccum->mxAlloc && width==0 && precision<0 ){ + if( pAccum->nChar==0 + && pAccum->mxAlloc + && width==0 + && precision<0 + && pAccum->accError==0 + ){ /* Special optimization for sqlite3_mprintf("%z..."): ** Extend an existing memory allocation rather than creating ** a new one. */ @@ -27986,21 +28314,13 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m sqlite3TreeViewPush(pView, 1); } do{ -#if SELECTTRACE_ENABLED sqlite3TreeViewLine(pView, - "SELECT%s%s (%s/%p) selFlags=0x%x nSelectRow=%d", + "SELECT%s%s (%u/%p) selFlags=0x%x nSelectRow=%d", ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""), ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), - p->zSelName, p, p->selFlags, + p->selId, p, p->selFlags, (int)p->nSelectRow ); -#else - sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p) selFlags=0x%x nSelectRow=%d", - ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""), - ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p, p->selFlags, - (int)p->nSelectRow - ); -#endif if( cnt++ ) sqlite3TreeViewPop(pView); if( p->pPrior ){ n = 1000; @@ -28012,8 +28332,23 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m if( p->pHaving ) n++; if( p->pOrderBy ) n++; if( p->pLimit ) n++; +#ifndef SQLITE_OMIT_WINDOWFUNC + if( p->pWin ) n++; + if( p->pWinDefn ) n++; +#endif } sqlite3TreeViewExprList(pView, p->pEList, (n--)>0, "result-set"); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( p->pWin ){ + Window *pX; + pView = sqlite3TreeViewPush(pView, (n--)>0); + sqlite3TreeViewLine(pView, "window-functions"); + for(pX=p->pWin; pX; pX=pX->pNextWin){ + sqlite3TreeViewWinFunc(pView, pX, pX->pNextWin!=0); + } + sqlite3TreeViewPop(pView); + } +#endif if( p->pSrc && p->pSrc->nSrc ){ int i; pView = sqlite3TreeViewPush(pView, (n--)>0); @@ -28063,6 +28398,16 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m sqlite3TreeViewExpr(pView, p->pHaving, 0); sqlite3TreeViewPop(pView); } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( p->pWinDefn ){ + Window *pX; + sqlite3TreeViewItem(pView, "WINDOW", (n--)>0); + for(pX=p->pWinDefn; pX; pX=pX->pNextWin){ + sqlite3TreeViewWindow(pView, pX, pX->pNextWin!=0); + } + sqlite3TreeViewPop(pView); + } +#endif if( p->pOrderBy ){ sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY"); } @@ -28090,6 +28435,83 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m sqlite3TreeViewPop(pView); } +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** Generate a description of starting or stopping bounds +*/ +SQLITE_PRIVATE void sqlite3TreeViewBound( + TreeView *pView, /* View context */ + u8 eBound, /* UNBOUNDED, CURRENT, PRECEDING, FOLLOWING */ + Expr *pExpr, /* Value for PRECEDING or FOLLOWING */ + u8 moreToFollow /* True if more to follow */ +){ + switch( eBound ){ + case TK_UNBOUNDED: { + sqlite3TreeViewItem(pView, "UNBOUNDED", moreToFollow); + sqlite3TreeViewPop(pView); + break; + } + case TK_CURRENT: { + sqlite3TreeViewItem(pView, "CURRENT", moreToFollow); + sqlite3TreeViewPop(pView); + break; + } + case TK_PRECEDING: { + sqlite3TreeViewItem(pView, "PRECEDING", moreToFollow); + sqlite3TreeViewExpr(pView, pExpr, 0); + sqlite3TreeViewPop(pView); + break; + } + case TK_FOLLOWING: { + sqlite3TreeViewItem(pView, "FOLLOWING", moreToFollow); + sqlite3TreeViewExpr(pView, pExpr, 0); + sqlite3TreeViewPop(pView); + break; + } + } +} +#endif /* SQLITE_OMIT_WINDOWFUNC */ + +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** Generate a human-readable explanation for a Window object +*/ +SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){ + pView = sqlite3TreeViewPush(pView, more); + if( pWin->zName ){ + sqlite3TreeViewLine(pView, "OVER %s", pWin->zName); + }else{ + sqlite3TreeViewLine(pView, "OVER"); + } + if( pWin->pPartition ){ + sqlite3TreeViewExprList(pView, pWin->pPartition, 1, "PARTITION-BY"); + } + if( pWin->pOrderBy ){ + sqlite3TreeViewExprList(pView, pWin->pOrderBy, 1, "ORDER-BY"); + } + if( pWin->eType ){ + sqlite3TreeViewItem(pView, pWin->eType==TK_RANGE ? "RANGE" : "ROWS", 0); + sqlite3TreeViewBound(pView, pWin->eStart, pWin->pStart, 1); + sqlite3TreeViewBound(pView, pWin->eEnd, pWin->pEnd, 0); + sqlite3TreeViewPop(pView); + } + sqlite3TreeViewPop(pView); +} +#endif /* SQLITE_OMIT_WINDOWFUNC */ + +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** Generate a human-readable explanation for a Window Function object +*/ +SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){ + pView = sqlite3TreeViewPush(pView, more); + sqlite3TreeViewLine(pView, "WINFUNC %s(%d)", + pWin->pFunc->zName, pWin->pFunc->nArg); + sqlite3TreeViewWindow(pView, pWin, 0); + sqlite3TreeViewPop(pView); +} +#endif /* SQLITE_OMIT_WINDOWFUNC */ + /* ** Generate a human-readable explanation of an expression tree. */ @@ -28127,6 +28549,9 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m sqlite3TreeViewLine(pView, "{%d:%d}%s", pExpr->iTable, pExpr->iColumn, zFlgs); } + if( ExprHasProperty(pExpr, EP_FixedCol) ){ + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); + } break; } case TK_INTEGER: { @@ -28240,10 +28665,17 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m case TK_AGG_FUNCTION: case TK_FUNCTION: { ExprList *pFarg; /* List of function arguments */ + Window *pWin; if( ExprHasProperty(pExpr, EP_TokenOnly) ){ pFarg = 0; + pWin = 0; }else{ pFarg = pExpr->x.pList; +#ifndef SQLITE_OMIT_WINDOWFUNC + pWin = pExpr->pWin; +#else + pWin = 0; +#endif } if( pExpr->op==TK_AGG_FUNCTION ){ sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q", @@ -28252,8 +28684,13 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m sqlite3TreeViewLine(pView, "FUNCTION %Q", pExpr->u.zToken); } if( pFarg ){ - sqlite3TreeViewExprList(pView, pFarg, 0, 0); + sqlite3TreeViewExprList(pView, pFarg, pWin!=0, 0); } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pWin ){ + sqlite3TreeViewWindow(pView, pWin, 0); + } +#endif break; } #ifndef SQLITE_OMIT_SUBQUERY @@ -31285,52 +31722,52 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 1 */ "AutoCommit" OpHelp(""), /* 2 */ "Transaction" OpHelp(""), /* 3 */ "SorterNext" OpHelp(""), - /* 4 */ "PrevIfOpen" OpHelp(""), - /* 5 */ "NextIfOpen" OpHelp(""), - /* 6 */ "Prev" OpHelp(""), - /* 7 */ "Next" OpHelp(""), - /* 8 */ "Checkpoint" OpHelp(""), - /* 9 */ "JournalMode" OpHelp(""), - /* 10 */ "Vacuum" OpHelp(""), - /* 11 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"), - /* 12 */ "VUpdate" OpHelp("data=r[P3@P2]"), - /* 13 */ "Goto" OpHelp(""), - /* 14 */ "Gosub" OpHelp(""), - /* 15 */ "InitCoroutine" OpHelp(""), - /* 16 */ "Yield" OpHelp(""), - /* 17 */ "MustBeInt" OpHelp(""), - /* 18 */ "Jump" OpHelp(""), + /* 4 */ "Prev" OpHelp(""), + /* 5 */ "Next" OpHelp(""), + /* 6 */ "Checkpoint" OpHelp(""), + /* 7 */ "JournalMode" OpHelp(""), + /* 8 */ "Vacuum" OpHelp(""), + /* 9 */ "VFilter" OpHelp("iplan=r[P3] zplan='P4'"), + /* 10 */ "VUpdate" OpHelp("data=r[P3@P2]"), + /* 11 */ "Goto" OpHelp(""), + /* 12 */ "Gosub" OpHelp(""), + /* 13 */ "InitCoroutine" OpHelp(""), + /* 14 */ "Yield" OpHelp(""), + /* 15 */ "MustBeInt" OpHelp(""), + /* 16 */ "Jump" OpHelp(""), + /* 17 */ "Once" OpHelp(""), + /* 18 */ "If" OpHelp(""), /* 19 */ "Not" OpHelp("r[P2]= !r[P1]"), - /* 20 */ "Once" OpHelp(""), - /* 21 */ "If" OpHelp(""), - /* 22 */ "IfNot" OpHelp(""), - /* 23 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"), - /* 24 */ "SeekLT" OpHelp("key=r[P3@P4]"), - /* 25 */ "SeekLE" OpHelp("key=r[P3@P4]"), - /* 26 */ "SeekGE" OpHelp("key=r[P3@P4]"), - /* 27 */ "SeekGT" OpHelp("key=r[P3@P4]"), - /* 28 */ "NoConflict" OpHelp("key=r[P3@P4]"), - /* 29 */ "NotFound" OpHelp("key=r[P3@P4]"), - /* 30 */ "Found" OpHelp("key=r[P3@P4]"), - /* 31 */ "SeekRowid" OpHelp("intkey=r[P3]"), - /* 32 */ "NotExists" OpHelp("intkey=r[P3]"), - /* 33 */ "Last" OpHelp(""), - /* 34 */ "IfSmaller" OpHelp(""), - /* 35 */ "SorterSort" OpHelp(""), - /* 36 */ "Sort" OpHelp(""), - /* 37 */ "Rewind" OpHelp(""), - /* 38 */ "IdxLE" OpHelp("key=r[P3@P4]"), - /* 39 */ "IdxGT" OpHelp("key=r[P3@P4]"), - /* 40 */ "IdxLT" OpHelp("key=r[P3@P4]"), - /* 41 */ "IdxGE" OpHelp("key=r[P3@P4]"), - /* 42 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), + /* 20 */ "IfNot" OpHelp(""), + /* 21 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"), + /* 22 */ "SeekLT" OpHelp("key=r[P3@P4]"), + /* 23 */ "SeekLE" OpHelp("key=r[P3@P4]"), + /* 24 */ "SeekGE" OpHelp("key=r[P3@P4]"), + /* 25 */ "SeekGT" OpHelp("key=r[P3@P4]"), + /* 26 */ "IfNoHope" OpHelp("key=r[P3@P4]"), + /* 27 */ "NoConflict" OpHelp("key=r[P3@P4]"), + /* 28 */ "NotFound" OpHelp("key=r[P3@P4]"), + /* 29 */ "Found" OpHelp("key=r[P3@P4]"), + /* 30 */ "SeekRowid" OpHelp("intkey=r[P3]"), + /* 31 */ "NotExists" OpHelp("intkey=r[P3]"), + /* 32 */ "Last" OpHelp(""), + /* 33 */ "IfSmaller" OpHelp(""), + /* 34 */ "SorterSort" OpHelp(""), + /* 35 */ "Sort" OpHelp(""), + /* 36 */ "Rewind" OpHelp(""), + /* 37 */ "IdxLE" OpHelp("key=r[P3@P4]"), + /* 38 */ "IdxGT" OpHelp("key=r[P3@P4]"), + /* 39 */ "IdxLT" OpHelp("key=r[P3@P4]"), + /* 40 */ "IdxGE" OpHelp("key=r[P3@P4]"), + /* 41 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), + /* 42 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), /* 43 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), /* 44 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), - /* 45 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), - /* 46 */ "Program" OpHelp(""), - /* 47 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), - /* 48 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), - /* 49 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), + /* 45 */ "Program" OpHelp(""), + /* 46 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), + /* 47 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), + /* 48 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), + /* 49 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), /* 50 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), /* 51 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), /* 52 */ "Ne" OpHelp("IF r[P3]!=r[P1]"), @@ -31340,119 +31777,121 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 56 */ "Lt" OpHelp("IF r[P3]=r[P1]"), /* 58 */ "ElseNotEq" OpHelp(""), - /* 59 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), - /* 60 */ "IncrVacuum" OpHelp(""), - /* 61 */ "VNext" OpHelp(""), - /* 62 */ "Init" OpHelp("Start at P2"), - /* 63 */ "Return" OpHelp(""), - /* 64 */ "EndCoroutine" OpHelp(""), - /* 65 */ "HaltIfNull" OpHelp("if r[P3]=null halt"), - /* 66 */ "Halt" OpHelp(""), - /* 67 */ "Integer" OpHelp("r[P2]=P1"), - /* 68 */ "Int64" OpHelp("r[P2]=P4"), - /* 69 */ "String" OpHelp("r[P2]='P4' (len=P1)"), - /* 70 */ "Null" OpHelp("r[P2..P3]=NULL"), - /* 71 */ "SoftNull" OpHelp("r[P1]=NULL"), - /* 72 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), - /* 73 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"), - /* 74 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), - /* 75 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), - /* 76 */ "SCopy" OpHelp("r[P2]=r[P1]"), - /* 77 */ "IntCopy" OpHelp("r[P2]=r[P1]"), - /* 78 */ "ResultRow" OpHelp("output=r[P1@P2]"), - /* 79 */ "CollSeq" OpHelp(""), - /* 80 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), - /* 81 */ "RealAffinity" OpHelp(""), - /* 82 */ "Cast" OpHelp("affinity(r[P1])"), - /* 83 */ "Permutation" OpHelp(""), - /* 84 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), - /* 85 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), - /* 86 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), - /* 87 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"), - /* 89 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), - /* 90 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), - /* 91 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), - /* 92 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), - /* 93 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), - /* 94 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), - /* 95 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"), - /* 96 */ "BitNot" OpHelp("r[P1]= ~r[P1]"), - /* 97 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"), - /* 98 */ "Column" OpHelp("r[P3]=PX"), - /* 99 */ "String8" OpHelp("r[P2]='P4'"), - /* 100 */ "Affinity" OpHelp("affinity(r[P1@P2])"), - /* 101 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), - /* 102 */ "Count" OpHelp("r[P2]=count()"), - /* 103 */ "ReadCookie" OpHelp(""), - /* 104 */ "SetCookie" OpHelp(""), - /* 105 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), - /* 106 */ "OpenRead" OpHelp("root=P2 iDb=P3"), - /* 107 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), - /* 108 */ "OpenDup" OpHelp(""), - /* 109 */ "OpenAutoindex" OpHelp("nColumn=P2"), - /* 110 */ "OpenEphemeral" OpHelp("nColumn=P2"), - /* 111 */ "SorterOpen" OpHelp(""), - /* 112 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), - /* 113 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), - /* 114 */ "Close" OpHelp(""), - /* 115 */ "ColumnsUsed" OpHelp(""), - /* 116 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), - /* 117 */ "NewRowid" OpHelp("r[P2]=rowid"), - /* 118 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), - /* 119 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"), - /* 120 */ "Delete" OpHelp(""), - /* 121 */ "ResetCount" OpHelp(""), - /* 122 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), - /* 123 */ "SorterData" OpHelp("r[P2]=data"), - /* 124 */ "RowData" OpHelp("r[P2]=data"), - /* 125 */ "Rowid" OpHelp("r[P2]=rowid"), - /* 126 */ "NullRow" OpHelp(""), - /* 127 */ "SeekEnd" OpHelp(""), - /* 128 */ "SorterInsert" OpHelp("key=r[P2]"), - /* 129 */ "IdxInsert" OpHelp("key=r[P2]"), - /* 130 */ "IdxDelete" OpHelp("key=r[P2@P3]"), - /* 131 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"), - /* 132 */ "IdxRowid" OpHelp("r[P2]=rowid"), - /* 133 */ "Destroy" OpHelp(""), - /* 134 */ "Real" OpHelp("r[P2]=P4"), - /* 135 */ "Clear" OpHelp(""), - /* 136 */ "ResetSorter" OpHelp(""), - /* 137 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"), - /* 138 */ "SqlExec" OpHelp(""), - /* 139 */ "ParseSchema" OpHelp(""), - /* 140 */ "LoadAnalysis" OpHelp(""), - /* 141 */ "DropTable" OpHelp(""), - /* 142 */ "DropIndex" OpHelp(""), - /* 143 */ "DropTrigger" OpHelp(""), - /* 144 */ "IntegrityCk" OpHelp(""), - /* 145 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), - /* 146 */ "Param" OpHelp(""), - /* 147 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), - /* 148 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), - /* 149 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), - /* 150 */ "AggStep0" OpHelp("accum=r[P3] step(r[P2@P5])"), - /* 151 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), - /* 152 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), - /* 153 */ "Expire" OpHelp(""), - /* 154 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), - /* 155 */ "VBegin" OpHelp(""), - /* 156 */ "VCreate" OpHelp(""), - /* 157 */ "VDestroy" OpHelp(""), - /* 158 */ "VOpen" OpHelp(""), - /* 159 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), - /* 160 */ "VRename" OpHelp(""), - /* 161 */ "Pagecount" OpHelp(""), - /* 162 */ "MaxPgcnt" OpHelp(""), - /* 163 */ "PureFunc0" OpHelp(""), - /* 164 */ "Function0" OpHelp("r[P3]=func(r[P2@P5])"), - /* 165 */ "PureFunc" OpHelp(""), - /* 166 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"), - /* 167 */ "Trace" OpHelp(""), - /* 168 */ "CursorHint" OpHelp(""), - /* 169 */ "Noop" OpHelp(""), - /* 170 */ "Explain" OpHelp(""), - /* 171 */ "Abortable" OpHelp(""), + /* 59 */ "IncrVacuum" OpHelp(""), + /* 60 */ "VNext" OpHelp(""), + /* 61 */ "Init" OpHelp("Start at P2"), + /* 62 */ "PureFunc0" OpHelp(""), + /* 63 */ "Function0" OpHelp("r[P3]=func(r[P2@P5])"), + /* 64 */ "PureFunc" OpHelp(""), + /* 65 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"), + /* 66 */ "Return" OpHelp(""), + /* 67 */ "EndCoroutine" OpHelp(""), + /* 68 */ "HaltIfNull" OpHelp("if r[P3]=null halt"), + /* 69 */ "Halt" OpHelp(""), + /* 70 */ "Integer" OpHelp("r[P2]=P1"), + /* 71 */ "Int64" OpHelp("r[P2]=P4"), + /* 72 */ "String" OpHelp("r[P2]='P4' (len=P1)"), + /* 73 */ "Null" OpHelp("r[P2..P3]=NULL"), + /* 74 */ "SoftNull" OpHelp("r[P1]=NULL"), + /* 75 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), + /* 76 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"), + /* 77 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), + /* 78 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), + /* 79 */ "SCopy" OpHelp("r[P2]=r[P1]"), + /* 80 */ "IntCopy" OpHelp("r[P2]=r[P1]"), + /* 81 */ "ResultRow" OpHelp("output=r[P1@P2]"), + /* 82 */ "CollSeq" OpHelp(""), + /* 83 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), + /* 84 */ "RealAffinity" OpHelp(""), + /* 85 */ "Cast" OpHelp("affinity(r[P1])"), + /* 86 */ "Permutation" OpHelp(""), + /* 87 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), + /* 88 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"), + /* 89 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"), + /* 90 */ "Column" OpHelp("r[P3]=PX"), + /* 91 */ "Affinity" OpHelp("affinity(r[P1@P2])"), + /* 92 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), + /* 93 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), + /* 94 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"), + /* 96 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), + /* 97 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), + /* 98 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), + /* 99 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), + /* 100 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), + /* 101 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), + /* 102 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), + /* 103 */ "BitNot" OpHelp("r[P2]= ~r[P1]"), + /* 104 */ "Count" OpHelp("r[P2]=count()"), + /* 105 */ "ReadCookie" OpHelp(""), + /* 106 */ "String8" OpHelp("r[P2]='P4'"), + /* 107 */ "SetCookie" OpHelp(""), + /* 108 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), + /* 109 */ "OpenRead" OpHelp("root=P2 iDb=P3"), + /* 110 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), + /* 111 */ "OpenDup" OpHelp(""), + /* 112 */ "OpenAutoindex" OpHelp("nColumn=P2"), + /* 113 */ "OpenEphemeral" OpHelp("nColumn=P2"), + /* 114 */ "SorterOpen" OpHelp(""), + /* 115 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), + /* 116 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), + /* 117 */ "Close" OpHelp(""), + /* 118 */ "ColumnsUsed" OpHelp(""), + /* 119 */ "SeekHit" OpHelp("seekHit=P2"), + /* 120 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), + /* 121 */ "NewRowid" OpHelp("r[P2]=rowid"), + /* 122 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), + /* 123 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"), + /* 124 */ "Delete" OpHelp(""), + /* 125 */ "ResetCount" OpHelp(""), + /* 126 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), + /* 127 */ "SorterData" OpHelp("r[P2]=data"), + /* 128 */ "RowData" OpHelp("r[P2]=data"), + /* 129 */ "Rowid" OpHelp("r[P2]=rowid"), + /* 130 */ "NullRow" OpHelp(""), + /* 131 */ "SeekEnd" OpHelp(""), + /* 132 */ "SorterInsert" OpHelp("key=r[P2]"), + /* 133 */ "IdxInsert" OpHelp("key=r[P2]"), + /* 134 */ "IdxDelete" OpHelp("key=r[P2@P3]"), + /* 135 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"), + /* 136 */ "IdxRowid" OpHelp("r[P2]=rowid"), + /* 137 */ "Destroy" OpHelp(""), + /* 138 */ "Clear" OpHelp(""), + /* 139 */ "ResetSorter" OpHelp(""), + /* 140 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"), + /* 141 */ "Real" OpHelp("r[P2]=P4"), + /* 142 */ "SqlExec" OpHelp(""), + /* 143 */ "ParseSchema" OpHelp(""), + /* 144 */ "LoadAnalysis" OpHelp(""), + /* 145 */ "DropTable" OpHelp(""), + /* 146 */ "DropIndex" OpHelp(""), + /* 147 */ "DropTrigger" OpHelp(""), + /* 148 */ "IntegrityCk" OpHelp(""), + /* 149 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), + /* 150 */ "Param" OpHelp(""), + /* 151 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), + /* 152 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), + /* 153 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), + /* 154 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"), + /* 155 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), + /* 156 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"), + /* 157 */ "AggValue" OpHelp("r[P3]=value N=P2"), + /* 158 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), + /* 159 */ "Expire" OpHelp(""), + /* 160 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), + /* 161 */ "VBegin" OpHelp(""), + /* 162 */ "VCreate" OpHelp(""), + /* 163 */ "VDestroy" OpHelp(""), + /* 164 */ "VOpen" OpHelp(""), + /* 165 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), + /* 166 */ "VRename" OpHelp(""), + /* 167 */ "Pagecount" OpHelp(""), + /* 168 */ "MaxPgcnt" OpHelp(""), + /* 169 */ "Trace" OpHelp(""), + /* 170 */ "CursorHint" OpHelp(""), + /* 171 */ "Noop" OpHelp(""), + /* 172 */ "Explain" OpHelp(""), + /* 173 */ "Abortable" OpHelp(""), }; return azName[i]; } @@ -32181,7 +32620,11 @@ static struct unix_syscall { #define osLstat ((int(*)(const char*,struct stat*))aSyscall[27].pCurrent) #if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) +# ifdef __ANDROID__ + { "ioctl", (sqlite3_syscall_ptr)(int(*)(int, int, ...))ioctl, 0 }, +# else { "ioctl", (sqlite3_syscall_ptr)ioctl, 0 }, +# endif #else { "ioctl", (sqlite3_syscall_ptr)0, 0 }, #endif @@ -32362,12 +32805,25 @@ static int robust_open(const char *z, int f, mode_t m){ ** unixEnterMutex() ** assert( unixMutexHeld() ); ** unixEnterLeave() +** +** To prevent deadlock, the global unixBigLock must must be acquired +** before the unixInodeInfo.pLockMutex mutex, if both are held. It is +** OK to get the pLockMutex without holding unixBigLock first, but if +** that happens, the unixBigLock mutex must not be acquired until after +** pLockMutex is released. +** +** OK: enter(unixBigLock), enter(pLockInfo) +** OK: enter(unixBigLock) +** OK: enter(pLockInfo) +** ERROR: enter(pLockInfo), enter(unixBigLock) */ static sqlite3_mutex *unixBigLock = 0; static void unixEnterMutex(void){ + assert( sqlite3_mutex_notheld(unixBigLock) ); /* Not a recursive mutex */ sqlite3_mutex_enter(unixBigLock); } static void unixLeaveMutex(void){ + assert( sqlite3_mutex_held(unixBigLock) ); sqlite3_mutex_leave(unixBigLock); } #ifdef SQLITE_DEBUG @@ -32768,16 +33224,34 @@ struct unixFileId { ** A single inode can have multiple file descriptors, so each unixFile ** structure contains a pointer to an instance of this object and this ** object keeps a count of the number of unixFile pointing to it. +** +** Mutex rules: +** +** (1) Only the pLockMutex mutex must be held in order to read or write +** any of the locking fields: +** nShared, nLock, eFileLock, bProcessLock, pUnused +** +** (2) When nRef>0, then the following fields are unchanging and can +** be read (but not written) without holding any mutex: +** fileId, pLockMutex +** +** (3) With the exceptions above, all the fields may only be read +** or written while holding the global unixBigLock mutex. +** +** Deadlock prevention: The global unixBigLock mutex may not +** be acquired while holding the pLockMutex mutex. If both unixBigLock +** and pLockMutex are needed, then unixBigLock must be acquired first. */ struct unixInodeInfo { struct unixFileId fileId; /* The lookup key */ - int nShared; /* Number of SHARED locks held */ - unsigned char eFileLock; /* One of SHARED_LOCK, RESERVED_LOCK etc. */ - unsigned char bProcessLock; /* An exclusive process lock is held */ + sqlite3_mutex *pLockMutex; /* Hold this mutex for... */ + int nShared; /* Number of SHARED locks held */ + int nLock; /* Number of outstanding file locks */ + unsigned char eFileLock; /* One of SHARED_LOCK, RESERVED_LOCK etc. */ + unsigned char bProcessLock; /* An exclusive process lock is held */ + UnixUnusedFd *pUnused; /* Unused file descriptors to close */ int nRef; /* Number of pointers to this structure */ unixShmNode *pShmNode; /* Shared memory associated with this inode */ - int nLock; /* Number of outstanding file locks */ - UnixUnusedFd *pUnused; /* Unused file descriptors to close */ unixInodeInfo *pNext; /* List of all unixInodeInfo objects */ unixInodeInfo *pPrev; /* .... doubly linked */ #if SQLITE_ENABLE_LOCKING_STYLE @@ -32793,7 +33267,21 @@ struct unixInodeInfo { ** A lists of all unixInodeInfo objects. */ static unixInodeInfo *inodeList = 0; /* All unixInodeInfo objects */ -static unsigned int nUnusedFd = 0; /* Total unused file descriptors */ + +#ifdef SQLITE_DEBUG +/* +** True if the inode mutex is held, or not. Used only within assert() +** to help verify correct mutex usage. +*/ +int unixFileMutexHeld(unixFile *pFile){ + assert( pFile->pInode ); + return sqlite3_mutex_held(pFile->pInode->pLockMutex); +} +int unixFileMutexNotheld(unixFile *pFile){ + assert( pFile->pInode ); + return sqlite3_mutex_notheld(pFile->pInode->pLockMutex); +} +#endif /* ** @@ -32899,11 +33387,11 @@ static void closePendingFds(unixFile *pFile){ unixInodeInfo *pInode = pFile->pInode; UnixUnusedFd *p; UnixUnusedFd *pNext; + assert( unixFileMutexHeld(pFile) ); for(p=pInode->pUnused; p; p=pNext){ pNext = p->pNext; robust_close(pFile, p->fd, __LINE__); sqlite3_free(p); - nUnusedFd--; } pInode->pUnused = 0; } @@ -32917,11 +33405,14 @@ static void closePendingFds(unixFile *pFile){ static void releaseInodeInfo(unixFile *pFile){ unixInodeInfo *pInode = pFile->pInode; assert( unixMutexHeld() ); + assert( unixFileMutexNotheld(pFile) ); if( ALWAYS(pInode) ){ pInode->nRef--; if( pInode->nRef==0 ){ assert( pInode->pShmNode==0 ); + sqlite3_mutex_enter(pInode->pLockMutex); closePendingFds(pFile); + sqlite3_mutex_leave(pInode->pLockMutex); if( pInode->pPrev ){ assert( pInode->pPrev->pNext==pInode ); pInode->pPrev->pNext = pInode->pNext; @@ -32933,10 +33424,10 @@ static void releaseInodeInfo(unixFile *pFile){ assert( pInode->pNext->pPrev==pInode ); pInode->pNext->pPrev = pInode->pPrev; } + sqlite3_mutex_free(pInode->pLockMutex); sqlite3_free(pInode); } } - assert( inodeList!=0 || nUnusedFd==0 ); } /* @@ -33006,7 +33497,6 @@ static int findInodeInfo( #else fileId.ino = (u64)statbuf.st_ino; #endif - assert( inodeList!=0 || nUnusedFd==0 ); pInode = inodeList; while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){ pInode = pInode->pNext; @@ -33018,6 +33508,13 @@ static int findInodeInfo( } memset(pInode, 0, sizeof(*pInode)); memcpy(&pInode->fileId, &fileId, sizeof(fileId)); + if( sqlite3GlobalConfig.bCoreMutex ){ + pInode->pLockMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( pInode->pLockMutex==0 ){ + sqlite3_free(pInode); + return SQLITE_NOMEM_BKPT; + } + } pInode->nRef = 1; pInode->pNext = inodeList; pInode->pPrev = 0; @@ -33096,7 +33593,7 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ assert( pFile ); assert( pFile->eFileLock<=SHARED_LOCK ); - unixEnterMutex(); /* Because pFile->pInode is shared across threads */ + sqlite3_mutex_enter(pFile->pInode->pLockMutex); /* Check if a thread in this process holds such a lock */ if( pFile->pInode->eFileLock>SHARED_LOCK ){ @@ -33121,7 +33618,7 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ } #endif - unixLeaveMutex(); + sqlite3_mutex_leave(pFile->pInode->pLockMutex); OSTRACE(("TEST WR-LOCK %d %d %d (unix)\n", pFile->h, rc, reserved)); *pResOut = reserved; @@ -33187,8 +33684,8 @@ static int osSetPosixAdvisoryLock( static int unixFileLock(unixFile *pFile, struct flock *pLock){ int rc; unixInodeInfo *pInode = pFile->pInode; - assert( unixMutexHeld() ); assert( pInode!=0 ); + assert( sqlite3_mutex_held(pInode->pLockMutex) ); if( (pFile->ctrlFlags & (UNIXFILE_EXCL|UNIXFILE_RDONLY))==UNIXFILE_EXCL ){ if( pInode->bProcessLock==0 ){ struct flock lock; @@ -33307,8 +33804,8 @@ static int unixLock(sqlite3_file *id, int eFileLock){ /* This mutex is needed because pFile->pInode is shared across threads */ - unixEnterMutex(); pInode = pFile->pInode; + sqlite3_mutex_enter(pInode->pLockMutex); /* If some thread using this PID has a lock via a different unixFile* ** handle that precludes the requested lock, return BUSY. @@ -33451,7 +33948,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){ } end_lock: - unixLeaveMutex(); + sqlite3_mutex_leave(pInode->pLockMutex); OSTRACE(("LOCK %d %s %s (unix)\n", pFile->h, azFileLock(eFileLock), rc==SQLITE_OK ? "ok" : "failed")); return rc; @@ -33464,11 +33961,11 @@ end_lock: static void setPendingFd(unixFile *pFile){ unixInodeInfo *pInode = pFile->pInode; UnixUnusedFd *p = pFile->pPreallocatedUnused; + assert( unixFileMutexHeld(pFile) ); p->pNext = pInode->pUnused; pInode->pUnused = p; pFile->h = -1; pFile->pPreallocatedUnused = 0; - nUnusedFd++; } /* @@ -33499,8 +33996,8 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ if( pFile->eFileLock<=eFileLock ){ return SQLITE_OK; } - unixEnterMutex(); pInode = pFile->pInode; + sqlite3_mutex_enter(pInode->pLockMutex); assert( pInode->nShared!=0 ); if( pFile->eFileLock>SHARED_LOCK ){ assert( pInode->eFileLock==pFile->eFileLock ); @@ -33626,14 +34123,14 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ */ pInode->nLock--; assert( pInode->nLock>=0 ); - if( pInode->nLock==0 ){ - closePendingFds(pFile); - } + if( pInode->nLock==0 ) closePendingFds(pFile); } end_unlock: - unixLeaveMutex(); - if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock; + sqlite3_mutex_leave(pInode->pLockMutex); + if( rc==SQLITE_OK ){ + pFile->eFileLock = eFileLock; + } return rc; } @@ -33704,15 +34201,20 @@ static int closeUnixFile(sqlite3_file *id){ static int unixClose(sqlite3_file *id){ int rc = SQLITE_OK; unixFile *pFile = (unixFile *)id; + unixInodeInfo *pInode = pFile->pInode; + + assert( pInode!=0 ); verifyDbFile(pFile); unixUnlock(id, NO_LOCK); + assert( unixFileMutexNotheld(pFile) ); unixEnterMutex(); /* unixFile.pInode is always valid here. Otherwise, a different close ** routine (e.g. nolockClose()) would be called instead. */ assert( pFile->pInode->nLock>0 || pFile->pInode->bProcessLock==0 ); - if( ALWAYS(pFile->pInode) && pFile->pInode->nLock ){ + sqlite3_mutex_enter(pInode->pLockMutex); + if( pInode->nLock ){ /* If there are outstanding locks, do not actually close the file just ** yet because that would clear those locks. Instead, add the file ** descriptor to pInode->pUnused list. It will be automatically closed @@ -33720,6 +34222,7 @@ static int unixClose(sqlite3_file *id){ */ setPendingFd(pFile); } + sqlite3_mutex_leave(pInode->pLockMutex); releaseInodeInfo(pFile); rc = closeUnixFile(id); unixLeaveMutex(); @@ -34317,6 +34820,7 @@ static int semXClose(sqlite3_file *id) { unixFile *pFile = (unixFile*)id; semXUnlock(id, NO_LOCK); assert( pFile ); + assert( unixFileMutexNotheld(pFile) ); unixEnterMutex(); releaseInodeInfo(pFile); unixLeaveMutex(); @@ -34431,8 +34935,7 @@ static int afpCheckReservedLock(sqlite3_file *id, int *pResOut){ *pResOut = 1; return SQLITE_OK; } - unixEnterMutex(); /* Because pFile->pInode is shared across threads */ - + sqlite3_mutex_enter(pFile->pInode->pLockMutex); /* Check if a thread in this process holds such a lock */ if( pFile->pInode->eFileLock>SHARED_LOCK ){ reserved = 1; @@ -34456,7 +34959,7 @@ static int afpCheckReservedLock(sqlite3_file *id, int *pResOut){ } } - unixLeaveMutex(); + sqlite3_mutex_leave(pFile->pInode->pLockMutex); OSTRACE(("TEST WR-LOCK %d %d %d (afp)\n", pFile->h, rc, reserved)); *pResOut = reserved; @@ -34519,8 +35022,8 @@ static int afpLock(sqlite3_file *id, int eFileLock){ /* This mutex is needed because pFile->pInode is shared across threads */ - unixEnterMutex(); pInode = pFile->pInode; + sqlite3_mutex_enter(pInode->pLockMutex); /* If some thread using this PID has a lock via a different unixFile* ** handle that precludes the requested lock, return BUSY. @@ -34656,7 +35159,7 @@ static int afpLock(sqlite3_file *id, int eFileLock){ } afp_end_lock: - unixLeaveMutex(); + sqlite3_mutex_leave(pInode->pLockMutex); OSTRACE(("LOCK %d %s %s (afp)\n", pFile->h, azFileLock(eFileLock), rc==SQLITE_OK ? "ok" : "failed")); return rc; @@ -34688,8 +35191,8 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) { if( pFile->eFileLock<=eFileLock ){ return SQLITE_OK; } - unixEnterMutex(); pInode = pFile->pInode; + sqlite3_mutex_enter(pInode->pLockMutex); assert( pInode->nShared!=0 ); if( pFile->eFileLock>SHARED_LOCK ){ assert( pInode->eFileLock==pFile->eFileLock ); @@ -34758,14 +35261,14 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) { if( rc==SQLITE_OK ){ pInode->nLock--; assert( pInode->nLock>=0 ); - if( pInode->nLock==0 ){ - closePendingFds(pFile); - } + if( pInode->nLock==0 ) closePendingFds(pFile); } } - unixLeaveMutex(); - if( rc==SQLITE_OK ) pFile->eFileLock = eFileLock; + sqlite3_mutex_leave(pInode->pLockMutex); + if( rc==SQLITE_OK ){ + pFile->eFileLock = eFileLock; + } return rc; } @@ -34777,14 +35280,20 @@ static int afpClose(sqlite3_file *id) { unixFile *pFile = (unixFile*)id; assert( id!=0 ); afpUnlock(id, NO_LOCK); + assert( unixFileMutexNotheld(pFile) ); unixEnterMutex(); - if( pFile->pInode && pFile->pInode->nLock ){ - /* If there are outstanding locks, do not actually close the file just - ** yet because that would clear those locks. Instead, add the file - ** descriptor to pInode->aPending. It will be automatically closed when - ** the last lock is cleared. - */ - setPendingFd(pFile); + if( pFile->pInode ){ + unixInodeInfo *pInode = pFile->pInode; + sqlite3_mutex_enter(pInode->pLockMutex); + if( pInode->nLock ){ + /* If there are outstanding locks, do not actually close the file just + ** yet because that would clear those locks. Instead, add the file + ** descriptor to pInode->aPending. It will be automatically closed when + ** the last lock is cleared. + */ + setPendingFd(pFile); + } + sqlite3_mutex_leave(pInode->pLockMutex); } releaseInodeInfo(pFile); sqlite3_free(pFile->lockingContext); @@ -36090,6 +36599,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ /* Check to see if a unixShmNode object already exists. Reuse an existing ** one if present. Create a new one if necessary. */ + assert( unixFileMutexNotheld(pDbFd) ); unixEnterMutex(); pInode = pDbFd->pInode; pShmNode = pInode->pShmNode; @@ -36472,6 +36982,9 @@ static void unixShmBarrier( ){ UNUSED_PARAMETER(fd); sqlite3MemoryBarrier(); /* compiler-defined memory barrier */ + assert( fd->pMethods->xLock==nolockLock + || unixFileMutexNotheld((unixFile*)fd) + ); unixEnterMutex(); /* Also mutex, for redundancy */ unixLeaveMutex(); } @@ -36513,6 +37026,7 @@ static int unixShmUnmap( /* If pShmNode->nRef has reached 0, then close the underlying ** shared-memory file, too */ + assert( unixFileMutexNotheld(pDbFd) ); unixEnterMutex(); assert( pShmNode->nRef>0 ); pShmNode->nRef--; @@ -36839,7 +37353,7 @@ IOMETHODS( IOMETHODS( nolockIoFinder, /* Finder function name */ nolockIoMethods, /* sqlite3_io_methods object name */ - 3, /* shared memory is disabled */ + 3, /* shared memory and mmap are enabled */ nolockClose, /* xClose method */ nolockLock, /* xLock method */ nolockUnlock, /* xUnlock method */ @@ -37335,7 +37849,7 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ ** ** Even if a subsequent open() call does succeed, the consequences of ** not searching for a reusable file descriptor are not dire. */ - if( nUnusedFd>0 && 0==osStat(zPath, &sStat) ){ + if( inodeList!=0 && 0==osStat(zPath, &sStat) ){ unixInodeInfo *pInode; pInode = inodeList; @@ -37345,12 +37859,14 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ } if( pInode ){ UnixUnusedFd **pp; + assert( sqlite3_mutex_notheld(pInode->pLockMutex) ); + sqlite3_mutex_enter(pInode->pLockMutex); for(pp=&pInode->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext)); pUnused = *pp; if( pUnused ){ - nUnusedFd--; *pp = pUnused->pNext; } + sqlite3_mutex_leave(pInode->pLockMutex); } } unixLeaveMutex(); @@ -42553,6 +43069,9 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ winFile *pFile = (winFile*)id; /* File handle object */ int rc = SQLITE_OK; /* Return code for this function */ DWORD lastErrno; +#if SQLITE_MAX_MMAP_SIZE>0 + sqlite3_int64 oldMmapSize; +#endif assert( pFile ); SimulateIOError(return SQLITE_IOERR_TRUNCATE); @@ -42568,6 +43087,15 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; } +#if SQLITE_MAX_MMAP_SIZE>0 + if( pFile->pMapRegion ){ + oldMmapSize = pFile->mmapSize; + }else{ + oldMmapSize = 0; + } + winUnmapfile(pFile); +#endif + /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */ if( winSeekFile(pFile, nByte) ){ rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, @@ -42580,12 +43108,12 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ } #if SQLITE_MAX_MMAP_SIZE>0 - /* If the file was truncated to a size smaller than the currently - ** mapped region, reduce the effective mapping size as well. SQLite will - ** use read() and write() to access data beyond this point from now on. - */ - if( pFile->pMapRegion && nBytemmapSize ){ - pFile->mmapSize = nByte; + if( rc==SQLITE_OK && oldMmapSize>0 ){ + if( oldMmapSize>nByte ){ + winMapfile(pFile, -1); + }else{ + winMapfile(pFile, oldMmapSize); + } } #endif @@ -45773,8 +46301,8 @@ SQLITE_API int sqlite3_os_end(void){ ** This file also implements interface sqlite3_serialize() and ** sqlite3_deserialize(). */ -#ifdef SQLITE_ENABLE_DESERIALIZE /* #include "sqliteInt.h" */ +#ifdef SQLITE_ENABLE_DESERIALIZE /* ** Forward declaration of objects used by this utility @@ -49022,30 +49550,23 @@ struct RowSet { #define ROWSET_NEXT 0x02 /* True if sqlite3RowSetNext() has been called */ /* -** Turn bulk memory into a RowSet object. N bytes of memory -** are available at pSpace. The db pointer is used as a memory context -** for any subsequent allocations that need to occur. -** Return a pointer to the new RowSet object. -** -** It must be the case that N is sufficient to make a Rowset. If not -** an assertion fault occurs. -** -** If N is larger than the minimum, use the surplus as an initial -** allocation of entries available to be filled. +** Allocate a RowSet object. Return NULL if a memory allocation +** error occurs. */ -SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int N){ - RowSet *p; - assert( N >= ROUND8(sizeof(*p)) ); - p = pSpace; - p->pChunk = 0; - p->db = db; - p->pEntry = 0; - p->pLast = 0; - p->pForest = 0; - p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p); - p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry)); - p->rsFlags = ROWSET_SORTED; - p->iBatch = 0; +SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db){ + RowSet *p = sqlite3DbMallocRawNN(db, sizeof(*p)); + if( p ){ + int N = sqlite3DbMallocSize(db, p); + p->pChunk = 0; + p->db = db; + p->pEntry = 0; + p->pLast = 0; + p->pForest = 0; + p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p); + p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry)); + p->rsFlags = ROWSET_SORTED; + p->iBatch = 0; + } return p; } @@ -49054,7 +49575,8 @@ SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int ** the RowSet has allocated over its lifetime. This routine is ** the destructor for the RowSet. */ -SQLITE_PRIVATE void sqlite3RowSetClear(RowSet *p){ +SQLITE_PRIVATE void sqlite3RowSetClear(void *pArg){ + RowSet *p = (RowSet*)pArg; struct RowSetChunk *pChunk, *pNextChunk; for(pChunk=p->pChunk; pChunk; pChunk = pNextChunk){ pNextChunk = pChunk->pNextChunk; @@ -49068,6 +49590,16 @@ SQLITE_PRIVATE void sqlite3RowSetClear(RowSet *p){ p->rsFlags = ROWSET_SORTED; } +/* +** Deallocate all chunks from a RowSet. This frees all memory that +** the RowSet has allocated over its lifetime. This routine is +** the destructor for the RowSet. +*/ +SQLITE_PRIVATE void sqlite3RowSetDelete(void *pArg){ + sqlite3RowSetClear(pArg); + sqlite3DbFree(((RowSet*)pArg)->db, pArg); +} + /* ** Allocate a new RowSetEntry object that is associated with the ** given RowSet. Return a pointer to the new and completely uninitialized @@ -49555,6 +50087,8 @@ SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal); SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot); SQLITE_PRIVATE void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot); SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal); +SQLITE_PRIVATE int sqlite3WalSnapshotCheck(Wal *pWal, sqlite3_snapshot *pSnapshot); +SQLITE_PRIVATE void sqlite3WalSnapshotUnlock(Wal *pWal); #endif #ifdef SQLITE_ENABLE_ZIPVFS @@ -50548,8 +51082,12 @@ static int assert_pager_state(Pager *p){ ** to "print *pPager" in gdb: ** ** (gdb) printf "%s", print_pager_state(pPager) +** +** This routine has external linkage in order to suppress compiler warnings +** about an unused function. It is enclosed within SQLITE_DEBUG and so does +** not appear in normal builds. */ -static char *print_pager_state(Pager *p){ +char *print_pager_state(Pager *p){ static char zRet[1024]; sqlite3_snprintf(1024, zRet, @@ -51315,7 +51853,6 @@ static void pager_reset(Pager *pPager){ ** Return the pPager->iDataVersion value */ SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager *pPager){ - assert( pPager->eState>PAGER_OPEN ); return pPager->iDataVersion; } @@ -55933,9 +56470,10 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne( ** backup in progress needs to be restarted. */ sqlite3BackupRestart(pPager->pBackup); }else{ + PgHdr *pList; if( pagerUseWal(pPager) ){ - PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache); PgHdr *pPageOne = 0; + pList = sqlite3PcacheDirtyList(pPager->pPCache); if( pList==0 ){ /* Must have at least one page for the WAL commit flag. ** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */ @@ -55956,14 +56494,14 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne( ** should be used. No rollback journal is created if batch-atomic-write ** is enabled. */ - sqlite3_file *fd = pPager->fd; #ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE - const int bBatch = zMaster==0 /* An SQLITE_IOCAP_BATCH_ATOMIC commit */ + sqlite3_file *fd = pPager->fd; + int bBatch = zMaster==0 /* An SQLITE_IOCAP_BATCH_ATOMIC commit */ && (sqlite3OsDeviceCharacteristics(fd) & SQLITE_IOCAP_BATCH_ATOMIC) && !pPager->noSync && sqlite3JournalIsInMemory(pPager->jfd); #else -# define bBatch 0 +# define bBatch 0 #endif #ifdef SQLITE_ENABLE_ATOMIC_WRITE @@ -56015,15 +56553,16 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne( } } } -#else +#else /* SQLITE_ENABLE_ATOMIC_WRITE */ #ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE if( zMaster ){ rc = sqlite3JournalCreate(pPager->jfd); if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + assert( bBatch==0 ); } #endif rc = pager_incr_changecounter(pPager, 0); -#endif +#endif /* !SQLITE_ENABLE_ATOMIC_WRITE */ if( rc!=SQLITE_OK ) goto commit_phase_one_exit; /* Write the master journal name into the journal file. If a master @@ -56047,24 +56586,36 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne( rc = syncJournal(pPager, 0); if( rc!=SQLITE_OK ) goto commit_phase_one_exit; + pList = sqlite3PcacheDirtyList(pPager->pPCache); +#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE if( bBatch ){ - /* The pager is now in DBMOD state. But regardless of what happens - ** next, attempting to play the journal back into the database would - ** be unsafe. Close it now to make sure that does not happen. */ - sqlite3OsClose(pPager->jfd); rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_BEGIN_ATOMIC_WRITE, 0); - if( rc!=SQLITE_OK ) goto commit_phase_one_exit; - } - rc = pager_write_pagelist(pPager,sqlite3PcacheDirtyList(pPager->pPCache)); - if( bBatch ){ if( rc==SQLITE_OK ){ - rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_COMMIT_ATOMIC_WRITE, 0); + rc = pager_write_pagelist(pPager, pList); + if( rc==SQLITE_OK ){ + rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_COMMIT_ATOMIC_WRITE, 0); + } + if( rc!=SQLITE_OK ){ + sqlite3OsFileControlHint(fd, SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE, 0); + } } - if( rc!=SQLITE_OK ){ - sqlite3OsFileControlHint(fd, SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE, 0); + + if( (rc&0xFF)==SQLITE_IOERR && rc!=SQLITE_IOERR_NOMEM ){ + rc = sqlite3JournalCreate(pPager->jfd); + if( rc!=SQLITE_OK ){ + sqlite3OsClose(pPager->jfd); + goto commit_phase_one_exit; + } + bBatch = 0; + }else{ + sqlite3OsClose(pPager->jfd); } } +#endif /* SQLITE_ENABLE_BATCH_ATOMIC_WRITE */ + if( bBatch==0 ){ + rc = pager_write_pagelist(pPager, pList); + } if( rc!=SQLITE_OK ){ assert( rc!=SQLITE_IOERR_BLOCKED ); goto commit_phase_one_exit; @@ -56816,13 +57367,6 @@ SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *pPager, int eMode){ SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){ u8 eOld = pPager->journalMode; /* Prior journalmode */ -#ifdef SQLITE_DEBUG - /* The print_pager_state() routine is intended to be used by the debugger - ** only. We invoke it once here to suppress a compiler warning. */ - print_pager_state(pPager); -#endif - - /* The eMode parameter is always valid */ assert( eMode==PAGER_JOURNALMODE_DELETE || eMode==PAGER_JOURNALMODE_TRUNCATE @@ -57191,6 +57735,38 @@ SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager){ } return rc; } + +/* +** The caller currently has a read transaction open on the database. +** If this is not a WAL database, SQLITE_ERROR is returned. Otherwise, +** this function takes a SHARED lock on the CHECKPOINTER slot and then +** checks if the snapshot passed as the second argument is still +** available. If so, SQLITE_OK is returned. +** +** If the snapshot is not available, SQLITE_ERROR is returned. Or, if +** the CHECKPOINTER lock cannot be obtained, SQLITE_BUSY. If any error +** occurs (any value other than SQLITE_OK is returned), the CHECKPOINTER +** lock is released before returning. +*/ +SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot){ + int rc; + if( pPager->pWal ){ + rc = sqlite3WalSnapshotCheck(pPager->pWal, pSnapshot); + }else{ + rc = SQLITE_ERROR; + } + return rc; +} + +/* +** Release a lock obtained by an earlier successful call to +** sqlite3PagerSnapshotCheck(). +*/ +SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager){ + assert( pPager->pWal ); + return sqlite3WalSnapshotUnlock(pPager->pWal); +} + #endif /* SQLITE_ENABLE_SNAPSHOT */ #endif /* !SQLITE_OMIT_WAL */ @@ -57472,6 +58048,18 @@ SQLITE_PRIVATE int sqlite3WalTrace = 0; # define WALTRACE(X) #endif +/* +** WAL mode depends on atomic aligned 32-bit loads and stores in a few +** places. The following macros try to make this explicit. +*/ +#if GCC_VESRION>=5004000 +# define AtomicLoad(PTR) __atomic_load_n((PTR),__ATOMIC_RELAXED) +# define AtomicStore(PTR,VAL) __atomic_store_n((PTR),(VAL),__ATOMIC_RELAXED) +#else +# define AtomicLoad(PTR) (*(PTR)) +# define AtomicStore(PTR,VAL) (*(PTR) = (VAL)) +#endif + /* ** The maximum (and only) versions of the wal and wal-index formats ** that may be interpreted by this version of SQLite. @@ -58094,48 +58682,51 @@ static int walNextHash(int iPriorHash){ return (iPriorHash+1)&(HASHTABLE_NSLOT-1); } +/* +** An instance of the WalHashLoc object is used to describe the location +** of a page hash table in the wal-index. This becomes the return value +** from walHashGet(). +*/ +typedef struct WalHashLoc WalHashLoc; +struct WalHashLoc { + volatile ht_slot *aHash; /* Start of the wal-index hash table */ + volatile u32 *aPgno; /* aPgno[1] is the page of first frame indexed */ + u32 iZero; /* One less than the frame number of first indexed*/ +}; + /* ** Return pointers to the hash table and page number array stored on ** page iHash of the wal-index. The wal-index is broken into 32KB pages ** numbered starting from 0. ** -** Set output variable *paHash to point to the start of the hash table -** in the wal-index file. Set *piZero to one less than the frame +** Set output variable pLoc->aHash to point to the start of the hash table +** in the wal-index file. Set pLoc->iZero to one less than the frame ** number of the first frame indexed by this hash table. If a ** slot in the hash table is set to N, it refers to frame number -** (*piZero+N) in the log. +** (pLoc->iZero+N) in the log. ** -** Finally, set *paPgno so that *paPgno[1] is the page number of the -** first frame indexed by the hash table, frame (*piZero+1). +** Finally, set pLoc->aPgno so that pLoc->aPgno[1] is the page number of the +** first frame indexed by the hash table, frame (pLoc->iZero+1). */ static int walHashGet( Wal *pWal, /* WAL handle */ int iHash, /* Find the iHash'th table */ - volatile ht_slot **paHash, /* OUT: Pointer to hash index */ - volatile u32 **paPgno, /* OUT: Pointer to page number array */ - u32 *piZero /* OUT: Frame associated with *paPgno[0] */ + WalHashLoc *pLoc /* OUT: Hash table location */ ){ int rc; /* Return code */ - volatile u32 *aPgno; - rc = walIndexPage(pWal, iHash, &aPgno); + rc = walIndexPage(pWal, iHash, &pLoc->aPgno); assert( rc==SQLITE_OK || iHash>0 ); if( rc==SQLITE_OK ){ - u32 iZero; - volatile ht_slot *aHash; - - aHash = (volatile ht_slot *)&aPgno[HASHTABLE_NPAGE]; + pLoc->aHash = (volatile ht_slot *)&pLoc->aPgno[HASHTABLE_NPAGE]; if( iHash==0 ){ - aPgno = &aPgno[WALINDEX_HDR_SIZE/sizeof(u32)]; - iZero = 0; + pLoc->aPgno = &pLoc->aPgno[WALINDEX_HDR_SIZE/sizeof(u32)]; + pLoc->iZero = 0; }else{ - iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE; + pLoc->iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE; } - - *paPgno = &aPgno[-1]; - *paHash = aHash; - *piZero = iZero; + pLoc->aPgno = &pLoc->aPgno[-1]; } return rc; } @@ -58181,9 +58772,7 @@ static u32 walFramePgno(Wal *pWal, u32 iFrame){ ** actually needed. */ static void walCleanupHash(Wal *pWal){ - volatile ht_slot *aHash = 0; /* Pointer to hash table to clear */ - volatile u32 *aPgno = 0; /* Page number array for hash table */ - u32 iZero = 0; /* frame == (aHash[x]+iZero) */ + WalHashLoc sLoc; /* Hash table location */ int iLimit = 0; /* Zero values greater than this */ int nByte; /* Number of bytes to zero in aPgno[] */ int i; /* Used to iterate through aHash[] */ @@ -58201,24 +58790,24 @@ static void walCleanupHash(Wal *pWal){ */ assert( pWal->nWiData>walFramePage(pWal->hdr.mxFrame) ); assert( pWal->apWiData[walFramePage(pWal->hdr.mxFrame)] ); - walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &aHash, &aPgno, &iZero); + walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &sLoc); /* Zero all hash-table entries that correspond to frame numbers greater ** than pWal->hdr.mxFrame. */ - iLimit = pWal->hdr.mxFrame - iZero; + iLimit = pWal->hdr.mxFrame - sLoc.iZero; assert( iLimit>0 ); for(i=0; iiLimit ){ - aHash[i] = 0; + if( sLoc.aHash[i]>iLimit ){ + sLoc.aHash[i] = 0; } } /* Zero the entries in the aPgno array that correspond to frames with ** frame numbers greater than pWal->hdr.mxFrame. */ - nByte = (int)((char *)aHash - (char *)&aPgno[iLimit+1]); - memset((void *)&aPgno[iLimit+1], 0, nByte); + nByte = (int)((char *)sLoc.aHash - (char *)&sLoc.aPgno[iLimit+1]); + memset((void *)&sLoc.aPgno[iLimit+1], 0, nByte); #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT /* Verify that the every entry in the mapping region is still reachable @@ -58228,10 +58817,10 @@ static void walCleanupHash(Wal *pWal){ int j; /* Loop counter */ int iKey; /* Hash key */ for(j=1; j<=iLimit; j++){ - for(iKey=walHash(aPgno[j]); aHash[iKey]; iKey=walNextHash(iKey)){ - if( aHash[iKey]==j ) break; + for(iKey=walHash(sLoc.aPgno[j]);sLoc.aHash[iKey];iKey=walNextHash(iKey)){ + if( sLoc.aHash[iKey]==j ) break; } - assert( aHash[iKey]==j ); + assert( sLoc.aHash[iKey]==j ); } } #endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */ @@ -58244,11 +58833,9 @@ static void walCleanupHash(Wal *pWal){ */ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){ int rc; /* Return code */ - u32 iZero = 0; /* One less than frame number of aPgno[1] */ - volatile u32 *aPgno = 0; /* Page number array */ - volatile ht_slot *aHash = 0; /* Hash table */ + WalHashLoc sLoc; /* Wal-index hash table location */ - rc = walHashGet(pWal, walFramePage(iFrame), &aHash, &aPgno, &iZero); + rc = walHashGet(pWal, walFramePage(iFrame), &sLoc); /* Assuming the wal-index file was successfully mapped, populate the ** page number array and hash table entry. @@ -58258,15 +58845,16 @@ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){ int idx; /* Value to write to hash-table slot */ int nCollide; /* Number of hash collisions */ - idx = iFrame - iZero; + idx = iFrame - sLoc.iZero; assert( idx <= HASHTABLE_NSLOT/2 + 1 ); /* If this is the first entry to be added to this hash-table, zero the ** entire hash table and aPgno[] array before proceeding. */ if( idx==1 ){ - int nByte = (int)((u8 *)&aHash[HASHTABLE_NSLOT] - (u8 *)&aPgno[1]); - memset((void*)&aPgno[1], 0, nByte); + int nByte = (int)((u8 *)&sLoc.aHash[HASHTABLE_NSLOT] + - (u8 *)&sLoc.aPgno[1]); + memset((void*)&sLoc.aPgno[1], 0, nByte); } /* If the entry in aPgno[] is already set, then the previous writer @@ -58275,18 +58863,18 @@ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){ ** Remove the remnants of that writers uncommitted transaction from ** the hash-table before writing any new entries. */ - if( aPgno[idx] ){ + if( sLoc.aPgno[idx] ){ walCleanupHash(pWal); - assert( !aPgno[idx] ); + assert( !sLoc.aPgno[idx] ); } /* Write the aPgno[] array entry and the hash-table slot. */ nCollide = idx; - for(iKey=walHash(iPage); aHash[iKey]; iKey=walNextHash(iKey)){ + for(iKey=walHash(iPage); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){ if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT; } - aPgno[idx] = iPage; - aHash[iKey] = (ht_slot)idx; + sLoc.aPgno[idx] = iPage; + sLoc.aHash[iKey] = (ht_slot)idx; #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT /* Verify that the number of entries in the hash table exactly equals @@ -58295,7 +58883,7 @@ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){ { int i; /* Loop counter */ int nEntry = 0; /* Number of entries in the hash table */ - for(i=0; iaSegment[p->nSegment])[iZero]; - iZero++; + aIndex = &((ht_slot *)&p->aSegment[p->nSegment])[sLoc.iZero]; + sLoc.iZero++; for(j=0; jaSegment[i].iZero = iZero; + walMergesort((u32 *)sLoc.aPgno, aTmp, aIndex, &nEntry); + p->aSegment[i].iZero = sLoc.iZero; p->aSegment[i].nEntry = nEntry; p->aSegment[i].aIndex = aIndex; - p->aSegment[i].aPgno = (u32 *)aPgno; + p->aSegment[i].aPgno = (u32 *)sLoc.aPgno; } } sqlite3_free(aTmp); @@ -59049,7 +59637,6 @@ static int walCheckpoint( if( pIter && (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0),1))==SQLITE_OK ){ - i64 nSize; /* Current size of database file */ u32 nBackfill = pInfo->nBackfill; pInfo->nBackfillAttempted = mxSafeFrame; @@ -59062,6 +59649,7 @@ static int walCheckpoint( */ if( rc==SQLITE_OK ){ i64 nReq = ((i64)mxPage * szPage); + i64 nSize; /* Current size of database file */ rc = sqlite3OsFileSize(pWal->pDbFd, &nSize); if( rc==SQLITE_OK && nSizepDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq); @@ -59769,7 +60357,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ } #endif for(i=1; iaReadMark[i]; + u32 thisMark = AtomicLoad(pInfo->aReadMark+i); if( mxReadMark<=thisMark && thisMark<=mxFrame ){ assert( thisMark!=READMARK_NOT_USED ); mxReadMark = thisMark; @@ -59782,7 +60370,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ for(i=1; iaReadMark[i] = mxFrame; + mxReadMark = AtomicStore(pInfo->aReadMark+i,mxFrame); mxI = i; walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); break; @@ -59834,9 +60422,9 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ ** we can guarantee that the checkpointer that set nBackfill could not ** see any pages past pWal->hdr.mxFrame, this problem does not come up. */ - pWal->minFrame = pInfo->nBackfill+1; + pWal->minFrame = AtomicLoad(&pInfo->nBackfill)+1; walShmBarrier(pWal); - if( pInfo->aReadMark[mxI]!=mxReadMark + if( AtomicLoad(pInfo->aReadMark+mxI)!=mxReadMark || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) ){ walUnlockShared(pWal, WAL_READ_LOCK(mxI)); @@ -59887,16 +60475,14 @@ SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal){ }else{ u32 i = pInfo->nBackfillAttempted; for(i=pInfo->nBackfillAttempted; i>pInfo->nBackfill; i--){ - volatile ht_slot *dummy; - volatile u32 *aPgno; /* Array of page numbers */ - u32 iZero; /* Frame corresponding to aPgno[0] */ + WalHashLoc sLoc; /* Hash table location */ u32 pgno; /* Page number in db file */ i64 iDbOff; /* Offset of db file entry */ i64 iWalOff; /* Offset of wal file entry */ - rc = walHashGet(pWal, walFramePage(i), &dummy, &aPgno, &iZero); + rc = walHashGet(pWal, walFramePage(i), &sLoc); if( rc!=SQLITE_OK ) break; - pgno = aPgno[i-iZero]; + pgno = sLoc.aPgno[i-sLoc.iZero]; iDbOff = (i64)(pgno-1) * szPage; if( iDbOff+szPage<=szDb ){ @@ -59937,7 +60523,7 @@ SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal){ ** ** If the database contents have changes since the previous read ** transaction, then *pChanged is set to 1 before returning. The -** Pager layer will use this to know that is cache is stale and +** Pager layer will use this to know that its cache is stale and ** needs to be flushed. */ SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ @@ -59999,7 +60585,7 @@ SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ /* Check that the wal file has not been wrapped. Assuming that it has ** not, also check that no checkpointer has attempted to checkpoint any ** frames beyond pSnapshot->mxFrame. If either of these conditions are - ** true, return SQLITE_BUSY_SNAPSHOT. Otherwise, overwrite pWal->hdr + ** true, return SQLITE_ERROR_SNAPSHOT. Otherwise, overwrite pWal->hdr ** with *pSnapshot and set *pChanged as appropriate for opening the ** snapshot. */ if( !memcmp(pSnapshot->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt)) @@ -60009,11 +60595,12 @@ SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ memcpy(&pWal->hdr, pSnapshot, sizeof(WalIndexHdr)); *pChanged = bChanged; }else{ - rc = SQLITE_BUSY_SNAPSHOT; + rc = SQLITE_ERROR_SNAPSHOT; } /* Release the shared CKPT lock obtained above. */ walUnlockShared(pWal, WAL_CKPT_LOCK); + pWal->minFrame = 1; } @@ -60097,21 +60684,20 @@ SQLITE_PRIVATE int sqlite3WalFindFrame( */ iMinHash = walFramePage(pWal->minFrame); for(iHash=walFramePage(iLast); iHash>=iMinHash; iHash--){ - volatile ht_slot *aHash; /* Pointer to hash table */ - volatile u32 *aPgno; /* Pointer to array of page numbers */ - u32 iZero; /* Frame number corresponding to aPgno[0] */ + WalHashLoc sLoc; /* Hash table location */ int iKey; /* Hash slot index */ int nCollide; /* Number of hash collisions remaining */ int rc; /* Error code */ - rc = walHashGet(pWal, iHash, &aHash, &aPgno, &iZero); + rc = walHashGet(pWal, iHash, &sLoc); if( rc!=SQLITE_OK ){ return rc; } nCollide = HASHTABLE_NSLOT; - for(iKey=walHash(pgno); aHash[iKey]; iKey=walNextHash(iKey)){ - u32 iFrame = aHash[iKey] + iZero; - if( iFrame<=iLast && iFrame>=pWal->minFrame && aPgno[aHash[iKey]]==pgno ){ + for(iKey=walHash(pgno); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){ + u32 iFrame = sLoc.aHash[iKey] + sLoc.iZero; + if( iFrame<=iLast && iFrame>=pWal->minFrame + && sLoc.aPgno[sLoc.aHash[iKey]]==pgno ){ assert( iFrame>iRead || CORRUPT_DB ); iRead = iFrame; } @@ -60986,6 +61572,43 @@ SQLITE_API int sqlite3_snapshot_cmp(sqlite3_snapshot *p1, sqlite3_snapshot *p2){ if( pHdr1->mxFrame>pHdr2->mxFrame ) return +1; return 0; } + +/* +** The caller currently has a read transaction open on the database. +** This function takes a SHARED lock on the CHECKPOINTER slot and then +** checks if the snapshot passed as the second argument is still +** available. If so, SQLITE_OK is returned. +** +** If the snapshot is not available, SQLITE_ERROR is returned. Or, if +** the CHECKPOINTER lock cannot be obtained, SQLITE_BUSY. If any error +** occurs (any value other than SQLITE_OK is returned), the CHECKPOINTER +** lock is released before returning. +*/ +SQLITE_PRIVATE int sqlite3WalSnapshotCheck(Wal *pWal, sqlite3_snapshot *pSnapshot){ + int rc; + rc = walLockShared(pWal, WAL_CKPT_LOCK); + if( rc==SQLITE_OK ){ + WalIndexHdr *pNew = (WalIndexHdr*)pSnapshot; + if( memcmp(pNew->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt)) + || pNew->mxFramenBackfillAttempted + ){ + rc = SQLITE_ERROR_SNAPSHOT; + walUnlockShared(pWal, WAL_CKPT_LOCK); + } + } + return rc; +} + +/* +** Release a lock obtained by an earlier successful call to +** sqlite3WalSnapshotCheck(). +*/ +SQLITE_PRIVATE void sqlite3WalSnapshotUnlock(Wal *pWal){ + assert( pWal ); + walUnlockShared(pWal, WAL_CKPT_LOCK); +} + + #endif /* SQLITE_ENABLE_SNAPSHOT */ #ifdef SQLITE_ENABLE_ZIPVFS @@ -65331,7 +65954,7 @@ SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p){ ** when A already has a read lock, we encourage A to give up and let B ** proceed. */ -SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ +SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){ BtShared *pBt = p->pBt; int rc = SQLITE_OK; @@ -65347,6 +65970,12 @@ SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ } assert( pBt->inTransaction==TRANS_WRITE || IfNotOmitAV(pBt->bDoTruncate)==0 ); + if( (p->db->flags & SQLITE_ResetDatabase) + && sqlite3PagerIsreadonly(pBt->pPager)==0 + ){ + pBt->btsFlags &= ~BTS_READ_ONLY; + } + /* Write transactions are not possible on a read-only database */ if( (pBt->btsFlags & BTS_READ_ONLY)!=0 && wrflag ){ rc = SQLITE_READONLY; @@ -65406,6 +66035,11 @@ SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ rc = sqlite3PagerBegin(pBt->pPager,wrflag>1,sqlite3TempInMemory(p->db)); if( rc==SQLITE_OK ){ rc = newDatabase(pBt); + }else if( rc==SQLITE_BUSY_SNAPSHOT && pBt->inTransaction==TRANS_NONE ){ + /* if there was no transaction opened when this function was + ** called and SQLITE_BUSY_SNAPSHOT is returned, change the error + ** code to SQLITE_BUSY. */ + rc = SQLITE_BUSY; } } } @@ -65457,14 +66091,18 @@ SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ } } - trans_begun: - if( rc==SQLITE_OK && wrflag ){ - /* This call makes sure that the pager has the correct number of - ** open savepoints. If the second parameter is greater than 0 and - ** the sub-journal is not already open, then it will be opened here. - */ - rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint); + if( rc==SQLITE_OK ){ + if( pSchemaVersion ){ + *pSchemaVersion = get4byte(&pBt->pPage1->aData[40]); + } + if( wrflag ){ + /* This call makes sure that the pager has the correct number of + ** open savepoints. If the second parameter is greater than 0 and + ** the sub-journal is not already open, then it will be opened here. + */ + rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint); + } } btreeIntegrity(p); @@ -67211,6 +67849,23 @@ SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ return rc; } +/* +** This function is a no-op if cursor pCur does not point to a valid row. +** Otherwise, if pCur is valid, configure it so that the next call to +** sqlite3BtreeNext() is a no-op. +*/ +#ifndef SQLITE_OMIT_WINDOWFUNC +SQLITE_PRIVATE void sqlite3BtreeSkipNext(BtCursor *pCur){ + /* We believe that the cursor must always be in the valid state when + ** this routine is called, but the proof is difficult, so we add an + ** ALWaYS() test just in case we are wrong. */ + if( ALWAYS(pCur->eState==CURSOR_VALID) ){ + pCur->eState = CURSOR_SKIPNEXT; + pCur->skipNext = 1; + } +} +#endif /* SQLITE_OMIT_WINDOWFUNC */ + /* Move the cursor to the last entry in the table. Return SQLITE_OK ** on success. Set *pRes to 0 if the cursor actually points to something ** or set *pRes to 1 if the table is empty. @@ -67615,7 +68270,16 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){ pPage = pCur->pPage; idx = ++pCur->ix; - assert( pPage->isInit ); + if( !pPage->isInit ){ + /* The only known way for this to happen is for there to be a + ** recursive SQL function that does a DELETE operation as part of a + ** SELECT which deletes content out from under an active cursor + ** in a corrupt database file where the table being DELETE-ed from + ** has pages in common with the table being queried. See TH3 + ** module cov1/btree78.test testcase 220 (2018-06-08) for an + ** example. */ + return SQLITE_CORRUPT_BKPT; + } /* If the database file is corrupt, it is possible for the value of idx ** to be invalid here. This can only occur if a second cursor modifies @@ -71327,8 +71991,7 @@ static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){ ** Also check that the page number is in bounds. */ static int checkRef(IntegrityCk *pCheck, Pgno iPage){ - if( iPage==0 ) return 1; - if( iPage>pCheck->nPage ){ + if( iPage>pCheck->nPage || iPage==0 ){ checkAppendMsg(pCheck, "invalid page number %d", iPage); return 1; } @@ -71383,17 +72046,12 @@ static void checkList( ){ int i; int expected = N; - int iFirst = iPage; - while( N-- > 0 && pCheck->mxErr ){ + int nErrAtStart = pCheck->nErr; + while( iPage!=0 && pCheck->mxErr ){ DbPage *pOvflPage; unsigned char *pOvflData; - if( iPage<1 ){ - checkAppendMsg(pCheck, - "%d of %d pages missing from overflow list starting at %d", - N+1, expected, iFirst); - break; - } if( checkRef(pCheck, iPage) ) break; + N--; if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage, 0) ){ checkAppendMsg(pCheck, "failed to get page %d", iPage); break; @@ -71437,10 +72095,12 @@ static void checkList( #endif iPage = get4byte(pOvflData); sqlite3PagerUnref(pOvflPage); - - if( isFreeList && N<(iPage!=0) ){ - checkAppendMsg(pCheck, "free-page count in header is too small"); - } + } + if( N && nErrAtStart==pCheck->nErr ){ + checkAppendMsg(pCheck, + "%s is %d but should be %d", + isFreeList ? "size" : "overflow list length", + expected-N, expected); } } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ @@ -71834,6 +72494,24 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck( /* Check all the tables. */ +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + int mx = 0; + int mxInHdr; + for(i=0; (int)ipPage1->aData[52]); + if( mx!=mxInHdr ){ + checkAppendMsg(&sCheck, + "max rootpage (%d) disagrees with header (%d)", + mx, mxInHdr + ); + } + }else if( get4byte(&pBt->pPage1->aData[64])!=0 ){ + checkAppendMsg(&sCheck, + "incremental_vacuum enabled with a max rootpage of zero" + ); + } +#endif testcase( pBt->db->flags & SQLITE_CellSizeCk ); pBt->db->flags &= ~SQLITE_CellSizeCk; for(i=0; (int)ibtsFlags &= ~BTS_NO_WAL; if( iVersion==1 ) pBt->btsFlags |= BTS_NO_WAL; - rc = sqlite3BtreeBeginTrans(pBtree, 0); + rc = sqlite3BtreeBeginTrans(pBtree, 0, 0); if( rc==SQLITE_OK ){ u8 *aData = pBt->pPage1->aData; if( aData[18]!=(u8)iVersion || aData[19]!=(u8)iVersion ){ - rc = sqlite3BtreeBeginTrans(pBtree, 2); + rc = sqlite3BtreeBeginTrans(pBtree, 2, 0); if( rc==SQLITE_OK ){ rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); if( rc==SQLITE_OK ){ @@ -72559,7 +73237,7 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ ** before this function exits. */ if( rc==SQLITE_OK && 0==sqlite3BtreeIsInReadTrans(p->pSrc) ){ - rc = sqlite3BtreeBeginTrans(p->pSrc, 0); + rc = sqlite3BtreeBeginTrans(p->pSrc, 0, 0); bCloseTrans = 1; } @@ -72575,10 +73253,10 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ /* Lock the destination database, if it is not locked already. */ if( SQLITE_OK==rc && p->bDestLocked==0 - && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2)) + && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2, + (int*)&p->iDestSchema)) ){ p->bDestLocked = 1; - sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema); } /* Do not allow backup if the destination database is in WAL mode @@ -73022,8 +73700,7 @@ SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){ if( p->flags & MEM_Null ){ /* Cannot be both MEM_Null and some other type */ - assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob - |MEM_RowSet|MEM_Frame|MEM_Agg))==0 ); + assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob|MEM_Agg))==0 ); /* If MEM_Null is set, then either the value is a pure NULL (the usual ** case) or it is a pointer set using sqlite3_bind_pointer() or @@ -73136,7 +73813,7 @@ SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ #ifndef SQLITE_OMIT_UTF16 int rc; #endif - assert( (pMem->flags&MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE || desiredEnc==SQLITE_UTF16BE ); if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){ @@ -73169,7 +73846,7 @@ SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ */ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ assert( sqlite3VdbeCheckMemInvariants(pMem) ); - assert( (pMem->flags&MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); testcase( pMem->db==0 ); /* If the bPreserve flag is set to true, then the memory cell must already @@ -73257,7 +73934,7 @@ static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){ */ SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - assert( (pMem->flags&MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); if( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ){ if( ExpandBlob(pMem) ) return SQLITE_NOMEM; if( pMem->szMalloc==0 || pMem->z!=pMem->zMalloc ){ @@ -73282,7 +73959,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){ int nByte; assert( pMem->flags & MEM_Zero ); assert( pMem->flags&MEM_Blob ); - assert( (pMem->flags&MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); /* Set nByte to the number of bytes required to store the expanded blob. */ @@ -73337,7 +74014,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){ assert( !(fg&MEM_Zero) ); assert( !(fg&(MEM_Str|MEM_Blob)) ); assert( fg&(MEM_Int|MEM_Real) ); - assert( (pMem->flags&MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); @@ -73395,6 +74072,35 @@ SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ return ctx.isError; } +/* +** Memory cell pAccum contains the context of an aggregate function. +** This routine calls the xValue method for that function and stores +** the results in memory cell pMem. +** +** SQLITE_ERROR is returned if xValue() reports an error. SQLITE_OK +** otherwise. +*/ +#ifndef SQLITE_OMIT_WINDOWFUNC +SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem *pAccum, Mem *pOut, FuncDef *pFunc){ + sqlite3_context ctx; + Mem t; + assert( pFunc!=0 ); + assert( pFunc->xValue!=0 ); + assert( (pAccum->flags & MEM_Null)!=0 || pFunc==pAccum->u.pDef ); + assert( pAccum->db==0 || sqlite3_mutex_held(pAccum->db->mutex) ); + memset(&ctx, 0, sizeof(ctx)); + memset(&t, 0, sizeof(t)); + t.flags = MEM_Null; + t.db = pAccum->db; + sqlite3VdbeMemSetNull(pOut); + ctx.pOut = pOut; + ctx.pMem = pAccum; + ctx.pFunc = pFunc; + pFunc->xValue(&ctx); + return ctx.isError; +} +#endif /* SQLITE_OMIT_WINDOWFUNC */ + /* ** If the memory cell contains a value that must be freed by ** invoking the external callback in Mem.xDel, then this routine @@ -73413,15 +74119,8 @@ static SQLITE_NOINLINE void vdbeMemClearExternAndSetNull(Mem *p){ testcase( p->flags & MEM_Dyn ); } if( p->flags&MEM_Dyn ){ - assert( (p->flags&MEM_RowSet)==0 ); assert( p->xDel!=SQLITE_DYNAMIC && p->xDel!=0 ); p->xDel((void *)p->z); - }else if( p->flags&MEM_RowSet ){ - sqlite3RowSetClear(p->u.pRowSet); - }else if( p->flags&MEM_Frame ){ - VdbeFrame *pFrame = p->u.pFrame; - pFrame->pParent = pFrame->v->pDelFrame; - pFrame->v->pDelFrame = pFrame; } p->flags = MEM_Null; } @@ -73569,7 +74268,7 @@ SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){ SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){ i64 ix; assert( pMem->flags & MEM_Real ); - assert( (pMem->flags & MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); @@ -73596,7 +74295,7 @@ SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){ */ SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem *pMem){ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - assert( (pMem->flags & MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); pMem->u.i = sqlite3VdbeIntValue(pMem); @@ -73814,26 +74513,36 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem *pMem, double val){ } #endif +#ifdef SQLITE_DEBUG +/* +** Return true if the Mem holds a RowSet object. This routine is intended +** for use inside of assert() statements. +*/ +SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem *pMem){ + return (pMem->flags&(MEM_Blob|MEM_Dyn))==(MEM_Blob|MEM_Dyn) + && pMem->xDel==sqlite3RowSetDelete; +} +#endif + /* ** Delete any previous value and set the value of pMem to be an ** empty boolean index. +** +** Return SQLITE_OK on success and SQLITE_NOMEM if a memory allocation +** error occurs. */ -SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem *pMem){ +SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem *pMem){ sqlite3 *db = pMem->db; + RowSet *p; assert( db!=0 ); - assert( (pMem->flags & MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); sqlite3VdbeMemRelease(pMem); - pMem->zMalloc = sqlite3DbMallocRawNN(db, 64); - if( db->mallocFailed ){ - pMem->flags = MEM_Null; - pMem->szMalloc = 0; - }else{ - assert( pMem->zMalloc ); - pMem->szMalloc = sqlite3DbMallocSize(db, pMem->zMalloc); - pMem->u.pRowSet = sqlite3RowSetInit(db, pMem->zMalloc, pMem->szMalloc); - assert( pMem->u.pRowSet!=0 ); - pMem->flags = MEM_RowSet; - } + p = sqlite3RowSetInit(db); + if( p==0 ) return SQLITE_NOMEM; + pMem->z = (char*)p; + pMem->flags = MEM_Blob|MEM_Dyn; + pMem->xDel = sqlite3RowSetDelete; + return SQLITE_OK; } /* @@ -73866,7 +74575,21 @@ SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ Mem *pX; for(i=0, pX=pVdbe->aMem; inMem; i++, pX++){ if( pX->pScopyFrom==pMem ){ - pX->flags |= MEM_Undefined; + /* If pX is marked as a shallow copy of pMem, then verify that + ** no significant changes have been made to pX since the OP_SCopy. + ** A significant change would indicated a missed call to this + ** function for pX. Minor changes, such as adding or removing a + ** dual type, are allowed, as long as the underlying value is the + ** same. */ + u16 mFlags = pMem->flags & pX->flags & pX->mScopyFlags; + assert( (mFlags&MEM_Int)==0 || pMem->u.i==pX->u.i ); + assert( (mFlags&MEM_Real)==0 || pMem->u.r==pX->u.r ); + assert( (mFlags&MEM_Str)==0 || (pMem->n==pX->n && pMem->z==pX->z) ); + assert( (mFlags&MEM_Blob)==0 || sqlite3BlobCompare(pMem,pX)==0 ); + + /* pMem is the register that is changing. But also mark pX as + ** undefined so that we can quickly detect the shallow-copy error */ + pX->flags = MEM_Undefined; pX->pScopyFrom = 0; } } @@ -73887,7 +74610,7 @@ static SQLITE_NOINLINE void vdbeClrCopy(Mem *pTo, const Mem *pFrom, int eType){ sqlite3VdbeMemShallowCopy(pTo, pFrom, eType); } SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){ - assert( (pFrom->flags & MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pFrom) ); assert( pTo->db==pFrom->db ); if( VdbeMemDynamic(pTo) ){ vdbeClrCopy(pTo,pFrom,srcType); return; } memcpy(pTo, pFrom, MEMCELLSIZE); @@ -73905,7 +74628,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int sr SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){ int rc = SQLITE_OK; - assert( (pFrom->flags & MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pFrom) ); if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo); memcpy(pTo, pFrom, MEMCELLSIZE); pTo->flags &= ~MEM_Dyn; @@ -73963,7 +74686,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr( u16 flags = 0; /* New value for pMem->flags */ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - assert( (pMem->flags & MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); /* If z is a NULL pointer, set pMem to contain an SQL NULL. */ if( !z ){ @@ -74085,7 +74808,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemFromBtree( /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert() ** that both the BtShared and database handle mutexes are held. */ - assert( (pMem->flags & MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); zData = (char *)sqlite3BtreePayloadFetch(pCur, &available); assert( zData!=0 ); @@ -74109,7 +74832,7 @@ static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){ assert( pVal!=0 ); assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) ); assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); - assert( (pVal->flags & MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pVal) ); assert( (pVal->flags & (MEM_Null))==0 ); if( pVal->flags & (MEM_Blob|MEM_Str) ){ if( ExpandBlob(pVal) ) return 0; @@ -74152,7 +74875,7 @@ SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){ if( !pVal ) return 0; assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) ); assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); - assert( (pVal->flags & MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pVal) ); if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){ assert( sqlite3VdbeMemConsistentDualRep(pVal) ); return pVal->z; @@ -74719,11 +75442,11 @@ SQLITE_PRIVATE int sqlite3Stat4Column( int iCol, /* Column to extract */ sqlite3_value **ppVal /* OUT: Extracted value */ ){ - u32 t; /* a column type code */ + u32 t = 0; /* a column type code */ int nHdr; /* Size of the header in the record */ int iHdr; /* Next unread header byte */ int iField; /* Next unread data byte */ - int szField; /* Size of the current data field */ + int szField = 0; /* Size of the current data field */ int i; /* Column index */ u8 *a = (u8*)pRec; /* Typecast byte array */ Mem *pMem = *ppVal; /* Write result into this Mem object */ @@ -75016,14 +75739,6 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ #endif #ifdef SQLITE_DEBUG if( p->db->flags & SQLITE_VdbeAddopTrace ){ - int jj, kk; - Parse *pParse = p->pParse; - for(jj=kk=0; jjnColCache; jj++){ - struct yColCache *x = pParse->aColCache + jj; - printf(" r[%d]={%d:%d}", x->iReg, x->iTable, x->iColumn); - kk++; - } - if( kk ) printf("\n"); sqlite3VdbePrintOp(0, i, &p->aOp[i]); test_addop_breakpoint(); } @@ -75147,7 +75862,7 @@ SQLITE_PRIVATE int sqlite3VdbeExplainParent(Parse *pParse){ SQLITE_PRIVATE void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){ if( pParse->explain==2 ){ char *zMsg; - Vdbe *v = pParse->pVdbe; + Vdbe *v; va_list ap; int iThis; va_start(ap, zFmt); @@ -75268,19 +75983,6 @@ SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){ } } -#ifdef SQLITE_COVERAGE_TEST -/* -** Return TRUE if and only if the label x has already been resolved. -** Return FALSE (zero) if label x is still unresolved. -** -** This routine is only used inside of testcase() macros, and so it -** only exists when measuring test coverage. -*/ -SQLITE_PRIVATE int sqlite3VdbeLabelHasBeenResolved(Vdbe *v, int x){ - return v->pParse->aLabel && v->pParse->aLabel[ADDR(x)]>=0; -} -#endif /* SQLITE_COVERAGE_TEST */ - /* ** Mark the VDBE as one that can only be run one time. */ @@ -75512,7 +76214,6 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ break; } case OP_Next: - case OP_NextIfOpen: case OP_SorterNext: { pOp->p4.xAdvance = sqlite3BtreeNext; pOp->p4type = P4_ADVANCE; @@ -75522,8 +76223,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ assert( pOp->p2>=0 ); break; } - case OP_Prev: - case OP_PrevIfOpen: { + case OP_Prev: { pOp->p4.xAdvance = sqlite3BtreePrevious; pOp->p4type = P4_ADVANCE; /* The code generator never codes any of these opcodes as a jump @@ -76438,7 +77138,7 @@ SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe *p){ /* ** Print a single opcode. This routine is used for debugging only. */ -SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){ +SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){ char *zP4; char zPtr[50]; char zCom[100]; @@ -76507,9 +77207,8 @@ static void releaseMemArray(Mem *p, int N){ */ testcase( p->flags & MEM_Agg ); testcase( p->flags & MEM_Dyn ); - testcase( p->flags & MEM_Frame ); - testcase( p->flags & MEM_RowSet ); - if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){ + testcase( p->xDel==sqlite3VdbeFrameMemDel ); + if( p->flags&(MEM_Agg|MEM_Dyn) ){ sqlite3VdbeMemRelease(p); }else if( p->szMalloc ){ sqlite3DbFreeNN(db, p->zMalloc); @@ -76521,6 +77220,35 @@ static void releaseMemArray(Mem *p, int N){ } } +#ifdef SQLITE_DEBUG +/* +** Verify that pFrame is a valid VdbeFrame pointer. Return true if it is +** and false if something is wrong. +** +** This routine is intended for use inside of assert() statements only. +*/ +SQLITE_PRIVATE int sqlite3VdbeFrameIsValid(VdbeFrame *pFrame){ + if( pFrame->iFrameMagic!=SQLITE_FRAME_MAGIC ) return 0; + return 1; +} +#endif + + +/* +** This is a destructor on a Mem object (which is really an sqlite3_value) +** that deletes the Frame object that is attached to it as a blob. +** +** This routine does not delete the Frame right away. It merely adds the +** frame to a list of frames to be deleted when the Vdbe halts. +*/ +SQLITE_PRIVATE void sqlite3VdbeFrameMemDel(void *pArg){ + VdbeFrame *pFrame = (VdbeFrame*)pArg; + assert( sqlite3VdbeFrameIsValid(pFrame) ); + pFrame->pParent = pFrame->v->pDelFrame; + pFrame->v->pDelFrame = pFrame; +} + + /* ** Delete a VdbeFrame object and its contents. VdbeFrame objects are ** allocated by the OP_Program opcode in sqlite3VdbeExec(). @@ -76529,6 +77257,7 @@ SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame *p){ int i; Mem *aMem = VdbeFrameMem(p); VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem]; + assert( sqlite3VdbeFrameIsValid(p) ); for(i=0; inChildCsr; i++){ sqlite3VdbeFreeCursor(p->v, apCsr[i]); } @@ -77825,7 +78554,7 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){ */ sqlite3VdbeHalt(p); - /* If the VDBE has be run even partially, then transfer the error code + /* If the VDBE has been run even partially, then transfer the error code ** and error message from the VDBE into the main database structure. But ** if the VDBE has just been set to run but has not actually executed any ** instructions yet, leave the main database error information unchanged. @@ -78737,7 +79466,7 @@ static int isAllZero(const char *z, int n){ ** is less than, equal to, or greater than the second, respectively. ** If one blob is a prefix of the other, then the shorter is the lessor. */ -static SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){ +SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){ int c; int n1 = pB1->n; int n2 = pB2->n; @@ -78807,7 +79536,7 @@ SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const C f1 = pMem1->flags; f2 = pMem2->flags; combined_flags = f1|f2; - assert( (combined_flags & MEM_RowSet)==0 ); + assert( !sqlite3VdbeMemIsRowSet(pMem1) && !sqlite3VdbeMemIsRowSet(pMem2) ); /* If one value is NULL, it is less than the other. If both values ** are NULL, return 0. @@ -78952,7 +79681,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( u32 idx1; /* Offset of first type in header */ int rc = 0; /* Return value */ Mem *pRhs = pPKey2->aMem; /* Next field of pPKey2 to compare */ - KeyInfo *pKeyInfo = pPKey2->pKeyInfo; + KeyInfo *pKeyInfo; const unsigned char *aKey1 = (const unsigned char *)pKey1; Mem mem1; @@ -79047,7 +79776,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( if( (d1+mem1.n) > (unsigned)nKey1 ){ pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; return 0; /* Corruption */ - }else if( pKeyInfo->aColl[i] ){ + }else if( (pKeyInfo = pPKey2->pKeyInfo)->aColl[i] ){ mem1.enc = pKeyInfo->enc; mem1.db = pKeyInfo->db; mem1.flags = MEM_Str; @@ -79098,7 +79827,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( } if( rc!=0 ){ - if( pKeyInfo->aSortOrder[i] ){ + if( pPKey2->pKeyInfo->aSortOrder[i] ){ rc = -rc; } assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, rc) ); @@ -79107,10 +79836,11 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( } i++; + if( i==pPKey2->nField ) break; pRhs++; d1 += sqlite3VdbeSerialTypeLen(serial_type); idx1 += sqlite3VarintLen(serial_type); - }while( idx1<(unsigned)szHdr1 && inField && d1<=(unsigned)nKey1 ); + }while( idx1<(unsigned)szHdr1 && d1<=(unsigned)nKey1 ); /* No memory allocation is ever used on mem1. Prove this using ** the following assert(). If the assert() fails, it indicates a @@ -79122,7 +79852,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( ** value. */ assert( CORRUPT_DB || vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, pPKey2->default_rc) - || pKeyInfo->db->mallocFailed + || pPKey2->pKeyInfo->db->mallocFailed ); pPKey2->eqSeen = 1; return pPKey2->default_rc; @@ -79448,7 +80178,7 @@ SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare( if( rc ){ return rc; } - *res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked); + *res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, pUnpacked, 0); sqlite3VdbeMemRelease(&m); return SQLITE_OK; } @@ -79480,11 +80210,19 @@ SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe *v){ ** programs obsolete. Removing user-defined functions or collating ** sequences, or changing an authorization function are the types of ** things that make prepared statements obsolete. +** +** If iCode is 1, then expiration is advisory. The statement should +** be reprepared before being restarted, but if it is already running +** it is allowed to run to completion. +** +** Internally, this function just sets the Vdbe.expired flag on all +** prepared statements. The flag is set to 1 for an immediate expiration +** and set to 2 for an advisory expiration. */ -SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3 *db){ +SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3 *db, int iCode){ Vdbe *p; for(p = db->pVdbe; p; p=p->pNext){ - p->expired = 1; + p->expired = iCode+1; } } @@ -80644,7 +81382,7 @@ static const Mem *columnNullValue(void){ /* .xDel = */ (void(*)(void*))0, #ifdef SQLITE_DEBUG /* .pScopyFrom = */ (Mem*)0, - /* .pFiller = */ (void*)0, + /* .mScopyFlags= */ 0, #endif }; return &nullMem; @@ -81954,32 +82692,56 @@ SQLITE_API int sqlite3_found_count = 0; ** feature is used for test suite validation only and does not appear an ** production builds. ** -** M is an integer, 2 or 3, that indices how many different ways the -** branch can go. It is usually 2. "I" is the direction the branch -** goes. 0 means falls through. 1 means branch is taken. 2 means the -** second alternative branch is taken. +** M is an integer between 2 and 4. 2 indicates a ordinary two-way +** branch (I=0 means fall through and I=1 means taken). 3 indicates +** a 3-way branch where the third way is when one of the operands is +** NULL. 4 indicates the OP_Jump instruction which has three destinations +** depending on whether the first operand is less than, equal to, or greater +** than the second. ** ** iSrcLine is the source code line (from the __LINE__ macro) that -** generated the VDBE instruction. This instrumentation assumes that all -** source code is in a single file (the amalgamation). Special values 1 -** and 2 for the iSrcLine parameter mean that this particular branch is -** always taken or never taken, respectively. +** generated the VDBE instruction combined with flag bits. The source +** code line number is in the lower 24 bits of iSrcLine and the upper +** 8 bytes are flags. The lower three bits of the flags indicate +** values for I that should never occur. For example, if the branch is +** always taken, the flags should be 0x05 since the fall-through and +** alternate branch are never taken. If a branch is never taken then +** flags should be 0x06 since only the fall-through approach is allowed. +** +** Bit 0x04 of the flags indicates an OP_Jump opcode that is only +** interested in equal or not-equal. In other words, I==0 and I==2 +** should be treated the same. +** +** Since only a line number is retained, not the filename, this macro +** only works for amalgamation builds. But that is ok, since these macros +** should be no-ops except for special builds used to measure test coverage. */ #if !defined(SQLITE_VDBE_COVERAGE) # define VdbeBranchTaken(I,M) #else # define VdbeBranchTaken(I,M) vdbeTakeBranch(pOp->iSrcLine,I,M) - static void vdbeTakeBranch(int iSrcLine, u8 I, u8 M){ - if( iSrcLine<=2 && ALWAYS(iSrcLine>0) ){ - M = iSrcLine; - /* Assert the truth of VdbeCoverageAlwaysTaken() and - ** VdbeCoverageNeverTaken() */ - assert( (M & I)==I ); - }else{ - if( sqlite3GlobalConfig.xVdbeBranch==0 ) return; /*NO_TEST*/ - sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg, - iSrcLine,I,M); + static void vdbeTakeBranch(u32 iSrcLine, u8 I, u8 M){ + u8 mNever; + assert( I<=2 ); /* 0: fall through, 1: taken, 2: alternate taken */ + assert( M<=4 ); /* 2: two-way branch, 3: three-way branch, 4: OP_Jump */ + assert( I> 24; + assert( (I & mNever)==0 ); + if( sqlite3GlobalConfig.xVdbeBranch==0 ) return; /*NO_TEST*/ + I |= mNever; + if( M==2 ) I |= 0x04; + if( M==4 ){ + I |= 0x08; + if( (mNever&0x08)!=0 && (I&0x05)!=0) I |= 0x05; /*NO_TEST*/ } + sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg, + iSrcLine&0xffffff, I, M); } #endif @@ -82310,7 +83072,7 @@ static void memTracePrint(Mem *p){ }else if( p->flags & MEM_Real ){ printf(" r:%g", p->u.r); #endif - }else if( p->flags & MEM_RowSet ){ + }else if( sqlite3VdbeMemIsRowSet(p) ){ printf(" (rowset)"); }else{ char zBuf[200]; @@ -83064,6 +83826,9 @@ case OP_Null: { /* out2 */ assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null; pOut->n = 0; +#ifdef SQLITE_DEBUG + pOut->uTemp = 0; +#endif while( cnt>0 ){ pOut++; memAboutToChange(p, pOut); @@ -83185,6 +83950,7 @@ case OP_Copy: { pOut = &aMem[pOp->p2]; assert( pOut!=pIn1 ); while( 1 ){ + memAboutToChange(p, pOut); sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); Deephemeralize(pOut); #ifdef SQLITE_DEBUG @@ -83217,7 +83983,8 @@ case OP_SCopy: { /* out2 */ assert( pOut!=pIn1 ); sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); #ifdef SQLITE_DEBUG - if( pOut->pScopyFrom==0 ) pOut->pScopyFrom = pIn1; + pOut->pScopyFrom = pIn1; + pOut->mScopyFlags = pIn1->flags; #endif break; } @@ -83851,7 +84618,12 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ if( (flags1 | flags3)&MEM_Str ){ if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ applyNumericAffinity(pIn1,0); - testcase( flags3!=pIn3->flags ); /* Possible if pIn1==pIn3 */ + assert( flags3==pIn3->flags ); + /* testcase( flags3!=pIn3->flags ); + ** this used to be possible with pIn1==pIn3, but not since + ** the column cache was removed. The following assignment + ** is essentially a no-op. But, it provides defense-in-depth + ** in case our analysis is incorrect, so it is left in. */ flags3 = pIn3->flags; } if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ @@ -84065,11 +84837,11 @@ case OP_Compare: { */ case OP_Jump: { /* jump */ if( iCompare<0 ){ - VdbeBranchTaken(0,3); pOp = &aOp[pOp->p1 - 1]; + VdbeBranchTaken(0,4); pOp = &aOp[pOp->p1 - 1]; }else if( iCompare==0 ){ - VdbeBranchTaken(1,3); pOp = &aOp[pOp->p2 - 1]; + VdbeBranchTaken(1,4); pOp = &aOp[pOp->p2 - 1]; }else{ - VdbeBranchTaken(2,3); pOp = &aOp[pOp->p3 - 1]; + VdbeBranchTaken(2,4); pOp = &aOp[pOp->p3 - 1]; } break; } @@ -84166,7 +84938,7 @@ case OP_Not: { /* same as TK_NOT, in1, out2 */ } /* Opcode: BitNot P1 P2 * * * -** Synopsis: r[P1]= ~r[P1] +** Synopsis: r[P2]= ~r[P1] ** ** Interpret the content of register P1 as an integer. Store the ** ones-complement of the P1 value into register P2. If P1 holds @@ -84981,7 +85753,7 @@ case OP_Savepoint: { } } if( isSchemaChange ){ - sqlite3ExpirePreparedStatements(db); + sqlite3ExpirePreparedStatements(db, 0); sqlite3ResetAllSchemasOfConnection(db); db->mDbFlags |= DBFLAG_SchemaChange; } @@ -85123,8 +85895,7 @@ case OP_AutoCommit: { */ case OP_Transaction: { Btree *pBt; - int iMeta; - int iGen; + int iMeta = 0; assert( p->bIsReader ); assert( p->readOnly==0 || pOp->p2==0 ); @@ -85137,7 +85908,7 @@ case OP_Transaction: { pBt = db->aDb[pOp->p1].pBt; if( pBt ){ - rc = sqlite3BtreeBeginTrans(pBt, pOp->p2); + rc = sqlite3BtreeBeginTrans(pBt, pOp->p2, &iMeta); testcase( rc==SQLITE_BUSY_SNAPSHOT ); testcase( rc==SQLITE_BUSY_RECOVERY ); if( rc!=SQLITE_OK ){ @@ -85170,19 +85941,17 @@ case OP_Transaction: { p->nStmtDefCons = db->nDeferredCons; p->nStmtDefImmCons = db->nDeferredImmCons; } - - /* Gather the schema version number for checking: + } + assert( pOp->p5==0 || pOp->p4type==P4_INT32 ); + if( pOp->p5 + && (iMeta!=pOp->p3 + || db->aDb[pOp->p1].pSchema->iGeneration!=pOp->p4.i) + ){ + /* ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema ** version is checked to ensure that the schema has not changed since the ** SQL statement was prepared. */ - sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta); - iGen = db->aDb[pOp->p1].pSchema->iGeneration; - }else{ - iGen = iMeta = 0; - } - assert( pOp->p5==0 || pOp->p4type==P4_INT32 ); - if( pOp->p5 && (iMeta!=pOp->p3 || iGen!=pOp->p4.i) ){ sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); /* If the schema-cookie from the database file matches the cookie @@ -85273,7 +86042,7 @@ case OP_SetCookie: { if( pOp->p1==1 ){ /* Invalidate all prepared statements whenever the TEMP database ** schema is changed. Ticket #1644 */ - sqlite3ExpirePreparedStatements(db); + sqlite3ExpirePreparedStatements(db, 0); p->expired = 0; } if( rc ) goto abort_due_to_error; @@ -85291,59 +86060,78 @@ case OP_SetCookie: { ** values need not be contiguous but all P1 values should be small integers. ** It is an error for P1 to be negative. ** -** If P5!=0 then use the content of register P2 as the root page, not -** the value of P2 itself. -** -** There will be a read lock on the database whenever there is an -** open cursor. If the database was unlocked prior to this instruction -** then a read lock is acquired as part of this instruction. A read -** lock allows other processes to read the database but prohibits -** any other process from modifying the database. The read lock is -** released when all cursors are closed. If this instruction attempts -** to get a read lock but fails, the script terminates with an -** SQLITE_BUSY error code. +** Allowed P5 bits: +**
      +**
    • 0x02 OPFLAG_SEEKEQ: This cursor will only be used for +** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT +** of OP_SeekLE/OP_IdxGT) +**
    ** ** The P4 value may be either an integer (P4_INT32) or a pointer to ** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo -** structure, then said structure defines the content and collating -** sequence of the index being opened. Otherwise, if P4 is an integer -** value, it is set to the number of columns in the table. +** object, then table being opened must be an [index b-tree] where the +** KeyInfo object defines the content and collating +** sequence of that index b-tree. Otherwise, if P4 is an integer +** value, then the table being opened must be a [table b-tree] with a +** number of columns no less than the value of P4. ** ** See also: OpenWrite, ReopenIdx */ /* Opcode: ReopenIdx P1 P2 P3 P4 P5 ** Synopsis: root=P2 iDb=P3 ** -** The ReopenIdx opcode works exactly like ReadOpen except that it first -** checks to see if the cursor on P1 is already open with a root page -** number of P2 and if it is this opcode becomes a no-op. In other words, +** The ReopenIdx opcode works like OP_OpenRead except that it first +** checks to see if the cursor on P1 is already open on the same +** b-tree and if it is this opcode becomes a no-op. In other words, ** if the cursor is already open, do not reopen it. ** -** The ReopenIdx opcode may only be used with P5==0 and with P4 being -** a P4_KEYINFO object. Furthermore, the P3 value must be the same as -** every other ReopenIdx or OpenRead for the same cursor number. +** The ReopenIdx opcode may only be used with P5==0 or P5==OPFLAG_SEEKEQ +** and with P4 being a P4_KEYINFO object. Furthermore, the P3 value must +** be the same as every other ReopenIdx or OpenRead for the same cursor +** number. ** -** See the OpenRead opcode documentation for additional information. +** Allowed P5 bits: +**
      +**
    • 0x02 OPFLAG_SEEKEQ: This cursor will only be used for +** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT +** of OP_SeekLE/OP_IdxGT) +**
    +** +** See also: OP_OpenRead, OP_OpenWrite */ /* Opcode: OpenWrite P1 P2 P3 P4 P5 ** Synopsis: root=P2 iDb=P3 ** ** Open a read/write cursor named P1 on the table or index whose root -** page is P2. Or if P5!=0 use the content of register P2 to find the -** root page. +** page is P2 (or whose root page is held in register P2 if the +** OPFLAG_P2ISREG bit is set in P5 - see below). ** ** The P4 value may be either an integer (P4_INT32) or a pointer to ** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo -** structure, then said structure defines the content and collating -** sequence of the index being opened. Otherwise, if P4 is an integer -** value, it is set to the number of columns in the table, or to the -** largest index of any column of the table that is actually used. +** object, then table being opened must be an [index b-tree] where the +** KeyInfo object defines the content and collating +** sequence of that index b-tree. Otherwise, if P4 is an integer +** value, then the table being opened must be a [table b-tree] with a +** number of columns no less than the value of P4. ** -** This instruction works just like OpenRead except that it opens the cursor -** in read/write mode. For a given table, there can be one or more read-only -** cursors or a single read/write cursor but not both. +** Allowed P5 bits: +**
      +**
    • 0x02 OPFLAG_SEEKEQ: This cursor will only be used for +** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT +** of OP_SeekLE/OP_IdxGT) +**
    • 0x08 OPFLAG_FORDELETE: This cursor is used only to seek +** and subsequently delete entries in an index btree. This is a +** hint to the storage engine that the storage engine is allowed to +** ignore. The hint is not used by the official SQLite b*tree storage +** engine, but is used by COMDB2. +**
    • 0x10 OPFLAG_P2ISREG: Use the content of register P2 +** as the root page, not the value of P2 itself. +**
    ** -** See also OpenRead. +** This instruction works like OpenRead except that it opens the cursor +** in read/write mode. +** +** See also: OP_OpenRead, OP_ReopenIdx */ case OP_ReopenIdx: { int nField; @@ -85372,7 +86160,7 @@ case OP_OpenWrite: assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx || p->readOnly==0 ); - if( p->expired ){ + if( p->expired==1 ){ rc = SQLITE_ABORT_ROLLBACK; goto abort_due_to_error; } @@ -85399,6 +86187,7 @@ case OP_OpenWrite: if( pOp->p5 & OPFLAG_P2ISREG ){ assert( p2>0 ); assert( p2<=(p->nMem+1 - p->nCursor) ); + assert( pOp->opcode==OP_OpenWrite ); pIn2 = &aMem[p2]; assert( memIsValid(pIn2) ); assert( (pIn2->flags & MEM_Int)!=0 ); @@ -85527,7 +86316,7 @@ case OP_OpenEphemeral: { rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx, BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags); if( rc==SQLITE_OK ){ - rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1); + rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1, 0); } if( rc==SQLITE_OK ){ /* If a transient index is required, create it by calling @@ -85754,10 +86543,10 @@ case OP_ColumnsUsed: { ** ** See also: Found, NotFound, SeekGt, SeekGe, SeekLt */ -case OP_SeekLT: /* jump, in3 */ -case OP_SeekLE: /* jump, in3 */ -case OP_SeekGE: /* jump, in3 */ -case OP_SeekGT: { /* jump, in3 */ +case OP_SeekLT: /* jump, in3, group */ +case OP_SeekLE: /* jump, in3, group */ +case OP_SeekGE: /* jump, in3, group */ +case OP_SeekGT: { /* jump, in3, group */ int res; /* Comparison result */ int oc; /* Opcode */ VdbeCursor *pC; /* The cursor to seek */ @@ -85935,6 +86724,25 @@ seek_not_found: break; } +/* Opcode: SeekHit P1 P2 * * * +** Synopsis: seekHit=P2 +** +** Set the seekHit flag on cursor P1 to the value in P2. +** The seekHit flag is used by the IfNoHope opcode. +** +** P1 must be a valid b-tree cursor. P2 must be a boolean value, +** either 0 or 1. +*/ +case OP_SeekHit: { + VdbeCursor *pC; + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + assert( pOp->p2==0 || pOp->p2==1 ); + pC->seekHit = pOp->p2 & 1; + break; +} + /* Opcode: Found P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** @@ -85969,7 +86777,34 @@ seek_not_found: ** advanced in either direction. In other words, the Next and Prev ** opcodes do not work after this operation. ** -** See also: Found, NotExists, NoConflict +** See also: Found, NotExists, NoConflict, IfNoHope +*/ +/* Opcode: IfNoHope P1 P2 P3 P4 * +** Synopsis: key=r[P3@P4] +** +** Register P3 is the first of P4 registers that form an unpacked +** record. +** +** Cursor P1 is on an index btree. If the seekHit flag is set on P1, then +** this opcode is a no-op. But if the seekHit flag of P1 is clear, then +** check to see if there is any entry in P1 that matches the +** prefix identified by P3 and P4. If no entry matches the prefix, +** jump to P2. Otherwise fall through. +** +** This opcode behaves like OP_NotFound if the seekHit +** flag is clear and it behaves like OP_Noop if the seekHit flag is set. +** +** This opcode is used in IN clause processing for a multi-column key. +** If an IN clause is attached to an element of the key other than the +** left-most element, and if there are no matches on the most recent +** seek over the whole key, then it might be that one of the key element +** to the left is prohibiting a match, and hence there is "no hope" of +** any match regardless of how many IN clause elements are checked. +** In such a case, we abandon the IN clause search early, using this +** opcode. The opcode name comes from the fact that the +** jump is taken if there is "no hope" of achieving a match. +** +** See also: NotFound, SeekHit */ /* Opcode: NoConflict P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] @@ -85994,6 +86829,14 @@ seek_not_found: ** ** See also: NotFound, Found, NotExists */ +case OP_IfNoHope: { /* jump, in3 */ + VdbeCursor *pC; + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + assert( pC!=0 ); + if( pC->seekHit ) break; + /* Fall through into OP_NotFound */ +} case OP_NoConflict: /* jump, in3 */ case OP_NotFound: /* jump, in3 */ case OP_Found: { /* jump, in3 */ @@ -86131,18 +86974,26 @@ case OP_SeekRowid: { /* jump, in3 */ pIn3 = &aMem[pOp->p3]; if( (pIn3->flags & MEM_Int)==0 ){ + /* Make sure pIn3->u.i contains a valid integer representation of + ** the key value, but do not change the datatype of the register, as + ** other parts of the perpared statement might be depending on the + ** current datatype. */ + u16 origFlags = pIn3->flags; + int isNotInt; applyAffinity(pIn3, SQLITE_AFF_NUMERIC, encoding); - if( (pIn3->flags & MEM_Int)==0 ) goto jump_to_p2; + isNotInt = (pIn3->flags & MEM_Int)==0; + pIn3->flags = origFlags; + if( isNotInt ) goto jump_to_p2; } /* Fall through into OP_NotExists */ case OP_NotExists: /* jump, in3 */ pIn3 = &aMem[pOp->p3]; - assert( pIn3->flags & MEM_Int ); + assert( (pIn3->flags & MEM_Int)!=0 || pOp->opcode==OP_SeekRowid ); assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); #ifdef SQLITE_DEBUG - pC->seekOp = 0; + pC->seekOp = OP_SeekRowid; #endif assert( pC->isTable ); assert( pC->eCurType==CURTYPE_BTREE ); @@ -86796,6 +87647,9 @@ case OP_NullRow: { assert( pC->uc.pCursor!=0 ); sqlite3BtreeClearCursor(pC->uc.pCursor); } +#ifdef SQLITE_DEBUG + if( pC->seekOp==0 ) pC->seekOp = OP_NullRow; +#endif break; } @@ -86914,7 +87768,7 @@ case OP_Sort: { /* jump */ p->aCounter[SQLITE_STMTSTATUS_SORT]++; /* Fall through into OP_Rewind */ } -/* Opcode: Rewind P1 P2 * * * +/* Opcode: Rewind P1 P2 * * P5 ** ** The next use of the Rowid or Column or Next instruction for P1 ** will refer to the first entry in the database table or index. @@ -86922,6 +87776,10 @@ case OP_Sort: { /* jump */ ** If the table or index is not empty, fall through to the following ** instruction. ** +** If P5 is non-zero and the table is not empty, then the "skip-next" +** flag is set on the cursor so that the next OP_Next instruction +** executed on it is a no-op. +** ** This opcode leaves the cursor configured to move in forward order, ** from the beginning toward the end. In other words, the cursor is ** configured to use Next, not Prev. @@ -86946,6 +87804,9 @@ case OP_Rewind: { /* jump */ pCrsr = pC->uc.pCursor; assert( pCrsr ); rc = sqlite3BtreeFirst(pCrsr, &res); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pOp->p5 ) sqlite3BtreeSkipNext(pCrsr); +#endif pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; } @@ -86982,12 +87843,7 @@ case OP_Rewind: { /* jump */ ** If P5 is positive and the jump is taken, then event counter ** number P5-1 in the prepared statement is incremented. ** -** See also: Prev, NextIfOpen -*/ -/* Opcode: NextIfOpen P1 P2 P3 P4 P5 -** -** This opcode works just like Next except that if cursor P1 is not -** open it behaves a no-op. +** See also: Prev */ /* Opcode: Prev P1 P2 P3 P4 P5 ** @@ -87015,11 +87871,6 @@ case OP_Rewind: { /* jump */ ** If P5 is positive and the jump is taken, then event counter ** number P5-1 in the prepared statement is incremented. */ -/* Opcode: PrevIfOpen P1 P2 P3 P4 P5 -** -** This opcode works just like Prev except that if cursor P1 is not -** open it behaves a no-op. -*/ /* Opcode: SorterNext P1 P2 * * P5 ** ** This opcode works just like OP_Next except that P1 must be a @@ -87034,10 +87885,6 @@ case OP_SorterNext: { /* jump */ assert( isSorter(pC) ); rc = sqlite3VdbeSorterNext(db, pC); goto next_tail; -case OP_PrevIfOpen: /* jump */ -case OP_NextIfOpen: /* jump */ - if( p->apCsr[pOp->p1]==0 ) break; - /* Fall through */ case OP_Prev: /* jump */ case OP_Next: /* jump */ assert( pOp->p1>=0 && pOp->p1nCursor ); @@ -87048,17 +87895,17 @@ case OP_Next: /* jump */ assert( pC->eCurType==CURTYPE_BTREE ); assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); - assert( pOp->opcode!=OP_NextIfOpen || pOp->p4.xAdvance==sqlite3BtreeNext ); - assert( pOp->opcode!=OP_PrevIfOpen || pOp->p4.xAdvance==sqlite3BtreePrevious); - /* The Next opcode is only used after SeekGT, SeekGE, and Rewind. + /* The Next opcode is only used after SeekGT, SeekGE, Rewind, and Found. ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */ - assert( pOp->opcode!=OP_Next || pOp->opcode!=OP_NextIfOpen + assert( pOp->opcode!=OP_Next || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE - || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found); - assert( pOp->opcode!=OP_Prev || pOp->opcode!=OP_PrevIfOpen + || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found + || pC->seekOp==OP_NullRow); + assert( pOp->opcode!=OP_Prev || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE - || pC->seekOp==OP_Last ); + || pC->seekOp==OP_Last + || pC->seekOp==OP_NullRow); rc = pOp->p4.xAdvance(pC->uc.pCursor, pOp->p3); next_tail: @@ -87341,7 +88188,13 @@ case OP_IdxGE: { /* jump */ } r.aMem = &aMem[pOp->p3]; #ifdef SQLITE_DEBUG - { int i; for(i=0; ip3+i, &aMem[pOp->p3+i]); + } + } #endif res = 0; /* Not needed. Only used to silence a warning. */ rc = sqlite3VdbeIdxKeyCompare(db, pC, &r, &res); @@ -87528,7 +88381,8 @@ case OP_SqlExec: { /* Opcode: ParseSchema P1 * * P4 * ** ** Read and parse all entries from the SQLITE_MASTER table of database P1 -** that match the WHERE clause P4. +** that match the WHERE clause P4. If P4 is a NULL pointer, then the +** entire schema for P1 is reparsed. ** ** This opcode invokes the parser to create a new virtual machine, ** then runs the new virtual machine. It is thus a re-entrant opcode. @@ -87552,11 +88406,22 @@ case OP_ParseSchema: { iDb = pOp->p1; assert( iDb>=0 && iDbnDb ); assert( DbHasProperty(db, iDb, DB_SchemaLoaded) ); - /* Used to be a conditional */ { + +#ifndef SQLITE_OMIT_ALTERTABLE + if( pOp->p4.z==0 ){ + sqlite3SchemaClear(db->aDb[iDb].pSchema); + db->mDbFlags &= ~DBFLAG_SchemaKnownOk; + rc = sqlite3InitOne(db, iDb, &p->zErrMsg, INITFLAG_AlterTable); + db->mDbFlags |= DBFLAG_SchemaChange; + p->expired = 0; + }else +#endif + { zMaster = MASTER_NAME; initData.db = db; initData.iDb = pOp->p1; initData.pzErrMsg = &p->zErrMsg; + initData.mInitFlags = 0; zSql = sqlite3MPrintf(db, "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid", db->aDb[iDb].zDbSName, zMaster, pOp->p4.z); @@ -87709,11 +88574,11 @@ case OP_RowSetAdd: { /* in1, in2 */ pIn1 = &aMem[pOp->p1]; pIn2 = &aMem[pOp->p2]; assert( (pIn2->flags & MEM_Int)!=0 ); - if( (pIn1->flags & MEM_RowSet)==0 ){ - sqlite3VdbeMemSetRowSet(pIn1); - if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem; + if( (pIn1->flags & MEM_Blob)==0 ){ + if( sqlite3VdbeMemSetRowSet(pIn1) ) goto no_mem; } - sqlite3RowSetInsert(pIn1->u.pRowSet, pIn2->u.i); + assert( sqlite3VdbeMemIsRowSet(pIn1) ); + sqlite3RowSetInsert((RowSet*)pIn1->z, pIn2->u.i); break; } @@ -87729,8 +88594,9 @@ case OP_RowSetRead: { /* jump, in1, out3 */ i64 val; pIn1 = &aMem[pOp->p1]; - if( (pIn1->flags & MEM_RowSet)==0 - || sqlite3RowSetNext(pIn1->u.pRowSet, &val)==0 + assert( (pIn1->flags & MEM_Blob)==0 || sqlite3VdbeMemIsRowSet(pIn1) ); + if( (pIn1->flags & MEM_Blob)==0 + || sqlite3RowSetNext((RowSet*)pIn1->z, &val)==0 ){ /* The boolean index is empty */ sqlite3VdbeMemSetNull(pIn1); @@ -87779,20 +88645,19 @@ case OP_RowSetTest: { /* jump, in1, in3 */ /* If there is anything other than a rowset object in memory cell P1, ** delete it now and initialize P1 with an empty rowset */ - if( (pIn1->flags & MEM_RowSet)==0 ){ - sqlite3VdbeMemSetRowSet(pIn1); - if( (pIn1->flags & MEM_RowSet)==0 ) goto no_mem; + if( (pIn1->flags & MEM_Blob)==0 ){ + if( sqlite3VdbeMemSetRowSet(pIn1) ) goto no_mem; } - + assert( sqlite3VdbeMemIsRowSet(pIn1) ); assert( pOp->p4type==P4_INT32 ); assert( iSet==-1 || iSet>=0 ); if( iSet ){ - exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i); + exists = sqlite3RowSetTest((RowSet*)pIn1->z, iSet, pIn3->u.i); VdbeBranchTaken(exists!=0,2); if( exists ) goto jump_to_p2; } if( iSet>=0 ){ - sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i); + sqlite3RowSetInsert((RowSet*)pIn1->z, pIn3->u.i); } break; } @@ -87856,7 +88721,7 @@ case OP_Program: { /* jump */ ** of the current program, and the memory required at runtime to execute ** the trigger program. If this trigger has been fired before, then pRt ** is already allocated. Otherwise, it must be initialized. */ - if( (pRt->flags&MEM_Frame)==0 ){ + if( (pRt->flags&MEM_Blob)==0 ){ /* SubProgram.nMem is set to the number of memory cells used by the ** program stored in SubProgram.aOp. As well as these, one memory ** cell is required for each cursor used by the program. Set local @@ -87874,8 +88739,10 @@ case OP_Program: { /* jump */ goto no_mem; } sqlite3VdbeMemRelease(pRt); - pRt->flags = MEM_Frame; - pRt->u.pFrame = pFrame; + pRt->flags = MEM_Blob|MEM_Dyn; + pRt->z = (char*)pFrame; + pRt->n = nByte; + pRt->xDel = sqlite3VdbeFrameMemDel; pFrame->v = p; pFrame->nChildMem = nMem; @@ -87891,6 +88758,9 @@ case OP_Program: { /* jump */ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS pFrame->anExec = p->anExec; #endif +#ifdef SQLITE_DEBUG + pFrame->iFrameMagic = SQLITE_FRAME_MAGIC; +#endif pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem]; for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){ @@ -87898,7 +88768,8 @@ case OP_Program: { /* jump */ pMem->db = db; } }else{ - pFrame = pRt->u.pFrame; + pFrame = (VdbeFrame*)pRt->z; + assert( pRt->xDel==sqlite3VdbeFrameMemDel ); assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem || (pProgram->nCsr==0 && pProgram->nMem+1==pFrame->nChildMem) ); assert( pProgram->nCsr==pFrame->nChildCsr ); @@ -88127,24 +88998,35 @@ case OP_DecrJumpZero: { /* jump, in1 */ } -/* Opcode: AggStep0 * P2 P3 P4 P5 +/* Opcode: AggStep * P2 P3 P4 P5 ** Synopsis: accum=r[P3] step(r[P2@P5]) ** -** Execute the step function for an aggregate. The -** function has P5 arguments. P4 is a pointer to the FuncDef -** structure that specifies the function. Register P3 is the +** Execute the xStep function for an aggregate. +** The function has P5 arguments. P4 is a pointer to the +** FuncDef structure that specifies the function. Register P3 is the ** accumulator. ** ** The P5 arguments are taken from register P2 and its ** successors. */ -/* Opcode: AggStep * P2 P3 P4 P5 +/* Opcode: AggInverse * P2 P3 P4 P5 +** Synopsis: accum=r[P3] inverse(r[P2@P5]) +** +** Execute the xInverse function for an aggregate. +** The function has P5 arguments. P4 is a pointer to the +** FuncDef structure that specifies the function. Register P3 is the +** accumulator. +** +** The P5 arguments are taken from register P2 and its +** successors. +*/ +/* Opcode: AggStep1 P1 P2 P3 P4 P5 ** Synopsis: accum=r[P3] step(r[P2@P5]) ** -** Execute the step function for an aggregate. The -** function has P5 arguments. P4 is a pointer to an sqlite3_context -** object that is used to run the function. Register P3 is -** as the accumulator. +** Execute the xStep (if P1==0) or xInverse (if P1!=0) function for an +** aggregate. The function has P5 arguments. P4 is a pointer to the +** FuncDef structure that specifies the function. Register P3 is the +** accumulator. ** ** The P5 arguments are taken from register P2 and its ** successors. @@ -88155,7 +89037,8 @@ case OP_DecrJumpZero: { /* jump, in1 */ ** sqlite3_context only happens once, instead of on each call to the ** step function. */ -case OP_AggStep0: { +case OP_AggInverse: +case OP_AggStep: { int n; sqlite3_context *pCtx; @@ -88178,10 +89061,14 @@ case OP_AggStep0: { pCtx->argc = n; pOp->p4type = P4_FUNCCTX; pOp->p4.pCtx = pCtx; - pOp->opcode = OP_AggStep; + + /* OP_AggInverse must have P1==1 and OP_AggStep must have P1==0 */ + assert( pOp->p1==(pOp->opcode==OP_AggInverse) ); + + pOp->opcode = OP_AggStep1; /* Fall through into OP_AggStep */ } -case OP_AggStep: { +case OP_AggStep1: { int i; sqlite3_context *pCtx; Mem *pMem; @@ -88190,6 +89077,17 @@ case OP_AggStep: { pCtx = pOp->p4.pCtx; pMem = &aMem[pOp->p3]; +#ifdef SQLITE_DEBUG + if( pOp->p1 ){ + /* This is an OP_AggInverse call. Verify that xStep has always + ** been called at least once prior to any xInverse call. */ + assert( pMem->uTemp==0x1122e0e3 ); + }else{ + /* This is an OP_AggStep call. Mark it as such. */ + pMem->uTemp = 0x1122e0e3; + } +#endif + /* If this function is inside of a trigger, the register array in aMem[] ** might change from one evaluation to the next. The next block of code ** checks to see if the register array has changed, and if so it @@ -88210,7 +89108,13 @@ case OP_AggStep: { assert( pCtx->pOut->flags==MEM_Null ); assert( pCtx->isError==0 ); assert( pCtx->skipFlag==0 ); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pOp->p1 ){ + (pCtx->pFunc->xInverse)(pCtx,pCtx->argc,pCtx->argv); + }else +#endif (pCtx->pFunc->xSFunc)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */ + if( pCtx->isError ){ if( pCtx->isError>0 ){ sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut)); @@ -88235,22 +89139,46 @@ case OP_AggStep: { /* Opcode: AggFinal P1 P2 * P4 * ** Synopsis: accum=r[P1] N=P2 ** -** Execute the finalizer function for an aggregate. P1 is -** the memory location that is the accumulator for the aggregate. +** P1 is the memory location that is the accumulator for an aggregate +** or window function. Execute the finalizer function +** for an aggregate and store the result in P1. ** ** P2 is the number of arguments that the step function takes and ** P4 is a pointer to the FuncDef for this function. The P2 ** argument is not used by this opcode. It is only there to disambiguate ** functions that can take varying numbers of arguments. The -** P4 argument is only needed for the degenerate case where +** P4 argument is only needed for the case where ** the step function was not previously called. */ +/* Opcode: AggValue * P2 P3 P4 * +** Synopsis: r[P3]=value N=P2 +** +** Invoke the xValue() function and store the result in register P3. +** +** P2 is the number of arguments that the step function takes and +** P4 is a pointer to the FuncDef for this function. The P2 +** argument is not used by this opcode. It is only there to disambiguate +** functions that can take varying numbers of arguments. The +** P4 argument is only needed for the case where +** the step function was not previously called. +*/ +case OP_AggValue: case OP_AggFinal: { Mem *pMem; assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); + assert( pOp->p3==0 || pOp->opcode==OP_AggValue ); pMem = &aMem[pOp->p1]; assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); - rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pOp->p3 ){ + rc = sqlite3VdbeMemAggValue(pMem, &aMem[pOp->p3], pOp->p4.pFunc); + pMem = &aMem[pOp->p3]; + }else +#endif + { + rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc); + } + if( rc ){ sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem)); goto abort_due_to_error; @@ -88445,7 +89373,7 @@ case OP_IncrVacuum: { /* jump */ } #endif -/* Opcode: Expire P1 * * * * +/* Opcode: Expire P1 P2 * * * ** ** Cause precompiled statements to expire. When an expired statement ** is executed using sqlite3_step() it will either automatically @@ -88454,12 +89382,19 @@ case OP_IncrVacuum: { /* jump */ ** ** If P1 is 0, then all SQL statements become expired. If P1 is non-zero, ** then only the currently executing statement is expired. +** +** If P2 is 0, then SQL statements are expired immediately. If P2 is 1, +** then running SQL statements are allowed to continue to run to completion. +** The P2==1 case occurs when a CREATE INDEX or similar schema change happens +** that might help the statement run faster but which does not affect the +** correctness of operation. */ case OP_Expire: { + assert( pOp->p2==0 || pOp->p2==1 ); if( !pOp->p1 ){ - sqlite3ExpirePreparedStatements(db); + sqlite3ExpirePreparedStatements(db, pOp->p2); }else{ - p->expired = 1; + p->expired = pOp->p2+1; } break; } @@ -88783,7 +89718,10 @@ case OP_VNext: { /* jump */ case OP_VRename: { sqlite3_vtab *pVtab; Mem *pName; - + int isLegacy; + + isLegacy = (db->flags & SQLITE_LegacyAlter); + db->flags |= SQLITE_LegacyAlter; pVtab = pOp->p4.pVtab->pVtab; pName = &aMem[pOp->p1]; assert( pVtab->pModule->xRename ); @@ -88797,6 +89735,7 @@ case OP_VRename: { rc = sqlite3VdbeChangeEncoding(pName, SQLITE_UTF8); if( rc ) goto abort_due_to_error; rc = pVtab->pModule->xRename(pVtab, pName->z); + if( isLegacy==0 ) db->flags &= ~SQLITE_LegacyAlter; sqlite3VtabImportErrmsg(p, pVtab); p->expired = 0; if( rc ) goto abort_due_to_error; @@ -88845,6 +89784,7 @@ case OP_VUpdate: { || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace ); assert( p->readOnly==0 ); + if( db->mallocFailed ) goto no_mem; sqlite3VdbeIncrWriteCounter(p, 0); pVtab = pOp->p4.pVtab->pVtab; if( pVtab==0 || NEVER(pVtab->pModule==0) ){ @@ -88966,8 +89906,8 @@ case OP_MaxPgcnt: { /* out2 */ ** ** See also: Function0, AggStep, AggFinal */ -case OP_PureFunc0: -case OP_Function0: { +case OP_PureFunc0: /* group */ +case OP_Function0: { /* group */ int n; sqlite3_context *pCtx; @@ -88991,8 +89931,8 @@ case OP_Function0: { pOp->opcode += 2; /* Fall through into OP_Function */ } -case OP_PureFunc: -case OP_Function: { +case OP_PureFunc: /* group */ +case OP_Function: { /* group */ int i; sqlite3_context *pCtx; @@ -91917,7 +92857,11 @@ static int vdbeMergeEngineInit( ){ int rc = SQLITE_OK; /* Return code */ int i; /* For looping over PmaReader objects */ - int nTree = pMerger->nTree; + int nTree; /* Number of subtrees to merge */ + + /* Failure to allocate the merge would have been detected prior to + ** invoking this routine */ + assert( pMerger!=0 ); /* eMode is always INCRINIT_NORMAL in single-threaded mode */ assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL ); @@ -91926,6 +92870,7 @@ static int vdbeMergeEngineInit( assert( pMerger->pTask==0 ); pMerger->pTask = pTask; + nTree = pMerger->nTree; for(i=0; i0 && eMode==INCRINIT_ROOT ){ /* PmaReaders should be normally initialized in order, as if they are @@ -93054,6 +93999,14 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){ }else if( pExpr->x.pList ){ if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort; } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( !ExprHasProperty(pExpr, EP_Reduced) && pExpr->pWin ){ + Window *pWin = pExpr->pWin; + if( sqlite3WalkExprList(pWalker, pWin->pPartition) ) return WRC_Abort; + if( sqlite3WalkExprList(pWalker, pWin->pOrderBy) ) return WRC_Abort; + if( sqlite3WalkExpr(pWalker, pWin->pFilter) ) return WRC_Abort; + } +#endif } break; } @@ -93426,6 +94379,9 @@ static int lookupName( if( sqlite3StrICmp(zTabName, zTab)!=0 ){ continue; } + if( IN_RENAME_OBJECT && pItem->zAlias ){ + sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->pTab); + } } if( 0==(cntTab++) ){ pMatch = pItem; @@ -93511,9 +94467,15 @@ static int lookupName( #ifndef SQLITE_OMIT_UPSERT if( pExpr->iTable==2 ){ testcase( iCol==(-1) ); - pExpr->iTable = pNC->uNC.pUpsert->regData + iCol; - eNewExprOp = TK_REGISTER; - ExprSetProperty(pExpr, EP_Alias); + if( IN_RENAME_OBJECT ){ + pExpr->iColumn = iCol; + pExpr->pTab = pTab; + eNewExprOp = TK_COLUMN; + }else{ + pExpr->iTable = pNC->uNC.pUpsert->regData + iCol; + eNewExprOp = TK_REGISTER; + ExprSetProperty(pExpr, EP_Alias); + } }else #endif /* SQLITE_OMIT_UPSERT */ { @@ -93598,6 +94560,9 @@ static int lookupName( cnt = 1; pMatch = 0; assert( zTab==0 && zDb==0 ); + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, 0, (void*)pExpr); + } goto lookupname_end; } } @@ -93825,17 +94790,24 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ zTable = 0; zColumn = pExpr->u.zToken; }else{ + Expr *pLeft = pExpr->pLeft; notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr); pRight = pExpr->pRight; if( pRight->op==TK_ID ){ zDb = 0; - zTable = pExpr->pLeft->u.zToken; - zColumn = pRight->u.zToken; }else{ assert( pRight->op==TK_DOT ); - zDb = pExpr->pLeft->u.zToken; - zTable = pRight->pLeft->u.zToken; - zColumn = pRight->pRight->u.zToken; + zDb = pLeft->u.zToken; + pLeft = pRight->pLeft; + pRight = pRight->pRight; + } + zTable = pLeft->u.zToken; + zColumn = pRight->u.zToken; + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight); + } + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, (void*)&pExpr->pTab, (void*)pLeft); } } return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr); @@ -93918,40 +94890,95 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ NC_IdxExpr|NC_PartIdx); } } - if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){ - sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId); - pNC->nErr++; - is_agg = 0; - }else if( no_such_func && pParse->db->init.busy==0 -#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION - && pParse->explain==0 + + if( 0==IN_RENAME_OBJECT ){ +#ifndef SQLITE_OMIT_WINDOWFUNC + assert( is_agg==0 || (pDef->funcFlags & SQLITE_FUNC_MINMAX) + || (pDef->xValue==0 && pDef->xInverse==0) + || (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize) + ); + if( pDef && pDef->xValue==0 && pExpr->pWin ){ + sqlite3ErrorMsg(pParse, + "%.*s() may not be used as a window function", nId, zId + ); + pNC->nErr++; + }else if( + (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) + || (is_agg && (pDef->funcFlags & SQLITE_FUNC_WINDOW) && !pExpr->pWin) + || (is_agg && pExpr->pWin && (pNC->ncFlags & NC_AllowWin)==0) + ){ + const char *zType; + if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->pWin ){ + zType = "window"; + }else{ + zType = "aggregate"; + } + sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()",zType,nId,zId); + pNC->nErr++; + is_agg = 0; + } +#else + if( (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) ){ + sqlite3ErrorMsg(pParse,"misuse of aggregate function %.*s()",nId,zId); + pNC->nErr++; + is_agg = 0; + } #endif - ){ - sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId); - pNC->nErr++; - }else if( wrong_num_args ){ - sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()", - nId, zId); - pNC->nErr++; + else if( no_such_func && pParse->db->init.busy==0 +#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION + && pParse->explain==0 +#endif + ){ + sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId); + pNC->nErr++; + }else if( wrong_num_args ){ + sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()", + nId, zId); + pNC->nErr++; + } + if( is_agg ){ +#ifndef SQLITE_OMIT_WINDOWFUNC + pNC->ncFlags &= ~(pExpr->pWin ? NC_AllowWin : NC_AllowAgg); +#else + pNC->ncFlags &= ~NC_AllowAgg; +#endif + } } - if( is_agg ) pNC->ncFlags &= ~NC_AllowAgg; sqlite3WalkExprList(pWalker, pList); if( is_agg ){ - NameContext *pNC2 = pNC; - pExpr->op = TK_AGG_FUNCTION; - pExpr->op2 = 0; - while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){ - pExpr->op2++; - pNC2 = pNC2->pNext; - } - assert( pDef!=0 ); - if( pNC2 ){ - assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg ); - testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 ); - pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pExpr->pWin ){ + Select *pSel = pNC->pWinSelect; + sqlite3WalkExprList(pWalker, pExpr->pWin->pPartition); + sqlite3WalkExprList(pWalker, pExpr->pWin->pOrderBy); + sqlite3WalkExpr(pWalker, pExpr->pWin->pFilter); + sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->pWin, pDef); + if( 0==pSel->pWin + || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->pWin) + ){ + pExpr->pWin->pNextWin = pSel->pWin; + pSel->pWin = pExpr->pWin; + } + pNC->ncFlags |= NC_AllowWin; + }else +#endif /* SQLITE_OMIT_WINDOWFUNC */ + { + NameContext *pNC2 = pNC; + pExpr->op = TK_AGG_FUNCTION; + pExpr->op2 = 0; + while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){ + pExpr->op2++; + pNC2 = pNC2->pNext; + } + assert( pDef!=0 ); + if( pNC2 ){ + assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg ); + testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 ); + pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX); + } + pNC->ncFlags |= NC_AllowAgg; } - pNC->ncFlags |= NC_AllowAgg; } /* FIX ME: Compute pExpr->affinity based on the expected return ** type of the function @@ -94352,6 +95379,19 @@ static int resolveOrderGroupBy( } for(j=0; jpEList->nExpr; j++){ if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){ +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pE->pWin ){ + /* Since this window function is being changed into a reference + ** to the same window function the result set, remove the instance + ** of this window function from the Select.pWin list. */ + Window **pp; + for(pp=&pSelect->pWin; *pp; pp=&(*pp)->pNextWin){ + if( *pp==pE->pWin ){ + *pp = (*pp)->pNextWin; + } + } + } +#endif pItem->u.x.iOrderByCol = j+1; } } @@ -94408,6 +95448,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ */ memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; + sNC.pWinSelect = p; if( sqlite3ResolveExprNames(&sNC, p->pLimit) ){ return WRC_Abort; } @@ -94456,12 +95497,13 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ /* Set up the local name-context to pass to sqlite3ResolveExprNames() to ** resolve the result-set expression list. */ - sNC.ncFlags = NC_AllowAgg; + sNC.ncFlags = NC_AllowAgg|NC_AllowWin; sNC.pSrcList = p->pSrc; sNC.pNext = pOuterNC; /* Resolve names in the result set. */ if( sqlite3ResolveExprListNames(&sNC, p->pEList) ) return WRC_Abort; + sNC.ncFlags &= ~NC_AllowWin; /* If there are no aggregate functions in the result-set, and no GROUP BY ** expression, do not allow aggregates in any of the other expressions. @@ -94510,7 +95552,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ ** outer queries */ sNC.pNext = 0; - sNC.ncFlags |= NC_AllowAgg; + sNC.ncFlags |= NC_AllowAgg|NC_AllowWin; /* If this is a converted compound query, move the ORDER BY clause from ** the sub-query back to the parent query. At this point each term @@ -94541,6 +95583,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ if( db->mallocFailed ){ return WRC_Abort; } + sNC.ncFlags &= ~NC_AllowWin; /* Resolve the GROUP BY clause. At the same time, make sure ** the GROUP BY clause does not contain aggregate functions. @@ -94889,14 +95932,6 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ while( p ){ int op = p->op; if( p->flags & EP_Generic ) break; - if( op==TK_CAST || op==TK_UPLUS ){ - p = p->pLeft; - continue; - } - if( op==TK_COLLATE || (op==TK_REGISTER && p->op2==TK_COLLATE) ){ - pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken); - break; - } if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER || op==TK_TRIGGER) && p->pTab!=0 @@ -94910,6 +95945,14 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ } break; } + if( op==TK_CAST || op==TK_UPLUS ){ + p = p->pLeft; + continue; + } + if( op==TK_COLLATE || (op==TK_REGISTER && p->op2==TK_COLLATE) ){ + pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken); + break; + } if( p->flags & EP_Collate ){ if( p->pLeft && (p->pLeft->flags & EP_Collate)!=0 ){ p = p->pLeft; @@ -95329,7 +96372,6 @@ static void codeVectorCompare( Expr *pL, *pR; int r1, r2; assert( i>=0 && i0 ) sqlite3ExprCachePush(pParse); r1 = exprVectorRegister(pParse, pLeft, i, regLeft, &pL, ®Free1); r2 = exprVectorRegister(pParse, pRight, i, regRight, &pR, ®Free2); codeCompare(pParse, pL, pR, opx, r1, r2, dest, p5); @@ -95341,7 +96383,6 @@ static void codeVectorCompare( testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne); sqlite3ReleaseTempReg(pParse, regFree1); sqlite3ReleaseTempReg(pParse, regFree2); - if( i>0 ) sqlite3ExprCachePop(pParse); if( i==nLeft-1 ){ break; } @@ -95689,7 +96730,12 @@ SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3 *db, Expr *pLeft, Expr *pRight){ ** Construct a new expression node for a function with multiple ** arguments. */ -SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){ +SQLITE_PRIVATE Expr *sqlite3ExprFunction( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* Argument list */ + Token *pToken, /* Name of the function */ + int eDistinct /* SF_Distinct or SF_ALL or 0 */ +){ Expr *pNew; sqlite3 *db = pParse->db; assert( pToken ); @@ -95698,10 +96744,14 @@ SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token * sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */ return 0; } + if( pList && pList->nExpr > pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){ + sqlite3ErrorMsg(pParse, "too many arguments on function %T", pToken); + } pNew->x.pList = pList; ExprSetProperty(pNew, EP_HasFunc); assert( !ExprHasProperty(pNew, EP_xIsSelect) ); sqlite3ExprSetHeightAndFlags(pParse, pNew); + if( eDistinct==SF_Distinct ) ExprSetProperty(pNew, EP_Distinct); return pNew; } @@ -95811,6 +96861,9 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ }else{ sqlite3ExprListDelete(db, p->x.pList); } + if( !ExprHasProperty(p, EP_Reduced) ){ + sqlite3WindowDelete(db, p->pWin); + } } if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken); if( !ExprHasProperty(p, EP_Static) ){ @@ -95859,7 +96912,7 @@ static int exprStructSize(Expr *p){ ** Note that with flags==EXPRDUP_REDUCE, this routines works on full-size ** (unreduced) Expr objects as they or originally constructed by the parser. ** During expression analysis, extra information is computed and moved into -** later parts of teh Expr object and that extra information might get chopped +** later parts of the Expr object and that extra information might get chopped ** off if the expression is reduced. Note also that it does not work to ** make an EXPRDUP_REDUCE copy of a reduced expression. It is only legal ** to reduce a pristine expression tree from the parser. The implementation @@ -95871,7 +96924,11 @@ static int dupedExprStructSize(Expr *p, int flags){ assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */ assert( EXPR_FULLSIZE<=0xfff ); assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 ); - if( 0==flags || p->op==TK_SELECT_COLUMN ){ + if( 0==flags || p->op==TK_SELECT_COLUMN +#ifndef SQLITE_OMIT_WINDOWFUNC + || p->pWin +#endif + ){ nSize = EXPR_FULLSIZE; }else{ assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); @@ -95999,18 +97056,22 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ } /* Fill in pNew->pLeft and pNew->pRight. */ + zAlloc += dupedExprNodeSize(p, dupFlags); if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){ - zAlloc += dupedExprNodeSize(p, dupFlags); if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){ pNew->pLeft = p->pLeft ? exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0; pNew->pRight = p->pRight ? exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0; } - if( pzBuffer ){ - *pzBuffer = zAlloc; - } }else{ +#ifndef SQLITE_OMIT_WINDOWFUNC + if( ExprHasProperty(p, EP_Reduced|EP_TokenOnly) ){ + pNew->pWin = 0; + }else{ + pNew->pWin = sqlite3WindowDup(db, pNew, p->pWin); + } +#endif /* SQLITE_OMIT_WINDOWFUNC */ if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){ if( pNew->op==TK_SELECT_COLUMN ){ pNew->pLeft = p->pLeft; @@ -96022,6 +97083,9 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ pNew->pRight = sqlite3ExprDup(db, p->pRight, 0); } } + if( pzBuffer ){ + *pzBuffer = zAlloc; + } } return pNew; } @@ -96217,7 +97281,11 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){ pNew->addrOpenEphm[1] = -1; pNew->nSelectRow = p->nSelectRow; pNew->pWith = withDup(db, p->pWith); - sqlite3SelectSetName(pNew, p->zSelName); +#ifndef SQLITE_OMIT_WINDOWFUNC + pNew->pWin = 0; + pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn); +#endif + pNew->selId = p->selId; *pp = pNew; pp = &pNew->pPrior; pNext = pNew; @@ -96389,6 +97457,9 @@ SQLITE_PRIVATE void sqlite3ExprListSetName( assert( pItem->zName==0 ); pItem->zName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n); if( dequote ) sqlite3Dequote(pItem->zName); + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenMap(pParse, (void*)pItem->zName, pName); + } } } @@ -96569,6 +97640,9 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ testcase( pExpr->op==TK_COLUMN ); testcase( pExpr->op==TK_AGG_FUNCTION ); testcase( pExpr->op==TK_AGG_COLUMN ); + if( ExprHasProperty(pExpr, EP_FixedCol) && pWalker->eCode!=2 ){ + return WRC_Continue; + } if( pWalker->eCode==3 && pExpr->iTable==pWalker->u.iCur ){ return WRC_Continue; } @@ -96624,10 +97698,17 @@ SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr *p){ } /* -** Walk an expression tree. Return non-zero if the expression is constant -** that does no originate from the ON or USING clauses of a join. -** Return 0 if it involves variables or function calls or terms from -** an ON or USING clause. +** Walk an expression tree. Return non-zero if +** +** (1) the expression is constant, and +** (2) the expression does originate in the ON or USING clause +** of a LEFT JOIN, and +** (3) the expression does not contain any EP_FixedCol TK_COLUMN +** operands created by the constant propagation optimization. +** +** When this routine returns true, it indicates that the expression +** can be added to the pParse->pConstExpr list and evaluated once when +** the prepared statement starts up. See sqlite3ExprCodeAtInit(). */ SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr *p){ return exprIsConst(p, 2, 0); @@ -96657,7 +97738,7 @@ static int exprNodeIsConstantOrGroupBy(Walker *pWalker, Expr *pExpr){ Expr *p = pGroupBy->a[i].pExpr; if( sqlite3ExprCompare(0, pExpr, p, -1)<2 ){ CollSeq *pColl = sqlite3ExprNNCollSeq(pWalker->pParse, p); - if( sqlite3_stricmp("BINARY", pColl->zName)==0 ){ + if( sqlite3IsBinary(pColl) ){ return WRC_Prune; } } @@ -97079,7 +98160,8 @@ SQLITE_PRIVATE int sqlite3FindInIndex( sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); eType = IN_INDEX_ROWID; - + ExplainQueryPlan((pParse, 0, + "USING ROWID SEARCH ON TABLE %s FOR IN-OPERATOR",pTab->zName)); sqlite3VdbeJumpHere(v, iAddr); }else{ Index *pIdx; /* Iterator variable */ @@ -97338,7 +98420,6 @@ SQLITE_PRIVATE int sqlite3CodeSubselect( int rReg = 0; /* Register storing resulting */ Vdbe *v = sqlite3GetVdbe(pParse); if( NEVER(v==0) ) return 0; - sqlite3ExprCachePush(pParse); /* The evaluation of the IN/EXISTS/SELECT must be repeated every time it ** is encountered if any of the following is true: @@ -97474,7 +98555,6 @@ SQLITE_PRIVATE int sqlite3CodeSubselect( sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3); }else{ sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1); - sqlite3ExprCacheAffinityChange(pParse, r3, 1); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pExpr->iTable, r2, r3, 1); } } @@ -97555,7 +98635,6 @@ SQLITE_PRIVATE int sqlite3CodeSubselect( if( jmpIfDynamic>=0 ){ sqlite3VdbeJumpHere(v, jmpIfDynamic); } - sqlite3ExprCachePop(pParse); return rReg; } @@ -97674,7 +98753,6 @@ static void sqlite3ExprCodeIN( ** aiMap[] array contains a mapping from the original LHS field order to ** the field order that matches the RHS index. */ - sqlite3ExprCachePush(pParse); rLhsOrig = exprCodeVector(pParse, pLeft, &iDummy); for(i=0; idb, aiMap); @@ -97901,145 +98978,6 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ } } -/* -** Erase column-cache entry number i -*/ -static void cacheEntryClear(Parse *pParse, int i){ - if( pParse->aColCache[i].tempReg ){ - if( pParse->nTempRegaTempReg) ){ - pParse->aTempReg[pParse->nTempReg++] = pParse->aColCache[i].iReg; - } - } - pParse->nColCache--; - if( inColCache ){ - pParse->aColCache[i] = pParse->aColCache[pParse->nColCache]; - } -} - - -/* -** Record in the column cache that a particular column from a -** particular table is stored in a particular register. -*/ -SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int iReg){ - int i; - int minLru; - int idxLru; - struct yColCache *p; - - /* Unless an error has occurred, register numbers are always positive. */ - assert( iReg>0 || pParse->nErr || pParse->db->mallocFailed ); - assert( iCol>=-1 && iCol<32768 ); /* Finite column numbers */ - - /* The SQLITE_ColumnCache flag disables the column cache. This is used - ** for testing only - to verify that SQLite always gets the same answer - ** with and without the column cache. - */ - if( OptimizationDisabled(pParse->db, SQLITE_ColumnCache) ) return; - - /* First replace any existing entry. - ** - ** Actually, the way the column cache is currently used, we are guaranteed - ** that the object will never already be in cache. Verify this guarantee. - */ -#ifndef NDEBUG - for(i=0, p=pParse->aColCache; inColCache; i++, p++){ - assert( p->iTable!=iTab || p->iColumn!=iCol ); - } -#endif - - /* If the cache is already full, delete the least recently used entry */ - if( pParse->nColCache>=SQLITE_N_COLCACHE ){ - minLru = 0x7fffffff; - idxLru = -1; - for(i=0, p=pParse->aColCache; ilrulru; - } - } - p = &pParse->aColCache[idxLru]; - }else{ - p = &pParse->aColCache[pParse->nColCache++]; - } - - /* Add the new entry to the end of the cache */ - p->iLevel = pParse->iCacheLevel; - p->iTable = iTab; - p->iColumn = iCol; - p->iReg = iReg; - p->tempReg = 0; - p->lru = pParse->iCacheCnt++; -} - -/* -** Indicate that registers between iReg..iReg+nReg-1 are being overwritten. -** Purge the range of registers from the column cache. -*/ -SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){ - int i = 0; - while( inColCache ){ - struct yColCache *p = &pParse->aColCache[i]; - if( p->iReg >= iReg && p->iReg < iReg+nReg ){ - cacheEntryClear(pParse, i); - }else{ - i++; - } - } -} - -/* -** Remember the current column cache context. Any new entries added -** added to the column cache after this call are removed when the -** corresponding pop occurs. -*/ -SQLITE_PRIVATE void sqlite3ExprCachePush(Parse *pParse){ - pParse->iCacheLevel++; -#ifdef SQLITE_DEBUG - if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ - printf("PUSH to %d\n", pParse->iCacheLevel); - } -#endif -} - -/* -** Remove from the column cache any entries that were added since the -** the previous sqlite3ExprCachePush operation. In other words, restore -** the cache to the state it was in prior the most recent Push. -*/ -SQLITE_PRIVATE void sqlite3ExprCachePop(Parse *pParse){ - int i = 0; - assert( pParse->iCacheLevel>=1 ); - pParse->iCacheLevel--; -#ifdef SQLITE_DEBUG - if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ - printf("POP to %d\n", pParse->iCacheLevel); - } -#endif - while( inColCache ){ - if( pParse->aColCache[i].iLevel>pParse->iCacheLevel ){ - cacheEntryClear(pParse, i); - }else{ - i++; - } - } -} - -/* -** When a cached column is reused, make sure that its register is -** no longer available as a temp register. ticket #3879: that same -** register might be in the cache in multiple places, so be sure to -** get them all. -*/ -static void sqlite3ExprCachePinRegister(Parse *pParse, int iReg){ - int i; - struct yColCache *p; - for(i=0, p=pParse->aColCache; inColCache; i++, p++){ - if( p->iReg==iReg ){ - p->tempReg = 0; - } - } -} /* Generate code that will load into register regOut a value that is ** appropriate for the iIdxCol-th column of index pIdx. @@ -98095,12 +99033,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable( /* ** Generate code that will extract the iColumn-th column from -** table pTab and store the column value in a register. -** -** An effort is made to store the column value in register iReg. This -** is not garanteeed for GetColumn() - the result can be stored in -** any register. But the result is guaranteed to land in register iReg -** for GetColumnToReg(). +** table pTab and store the column value in register iReg. ** ** There must be an open cursor to pTab in iTable when this routine ** is called. If iColumn<0 then code is generated that extracts the rowid. @@ -98114,96 +99047,23 @@ SQLITE_PRIVATE int sqlite3ExprCodeGetColumn( u8 p5 /* P5 value for OP_Column + FLAGS */ ){ Vdbe *v = pParse->pVdbe; - int i; - struct yColCache *p; - - for(i=0, p=pParse->aColCache; inColCache; i++, p++){ - if( p->iTable==iTable && p->iColumn==iColumn ){ - p->lru = pParse->iCacheCnt++; - sqlite3ExprCachePinRegister(pParse, p->iReg); - return p->iReg; - } - } assert( v!=0 ); sqlite3ExprCodeGetColumnOfTable(v, pTab, iTable, iColumn, iReg); if( p5 ){ sqlite3VdbeChangeP5(v, p5); - }else{ - sqlite3ExprCacheStore(pParse, iTable, iColumn, iReg); } return iReg; } -SQLITE_PRIVATE void sqlite3ExprCodeGetColumnToReg( - Parse *pParse, /* Parsing and code generating context */ - Table *pTab, /* Description of the table we are reading from */ - int iColumn, /* Index of the table column */ - int iTable, /* The cursor pointing to the table */ - int iReg /* Store results here */ -){ - int r1 = sqlite3ExprCodeGetColumn(pParse, pTab, iColumn, iTable, iReg, 0); - if( r1!=iReg ) sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, r1, iReg); -} - - -/* -** Clear all column cache entries. -*/ -SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse *pParse){ - int i; - -#ifdef SQLITE_DEBUG - if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ - printf("CLEAR\n"); - } -#endif - for(i=0; inColCache; i++){ - if( pParse->aColCache[i].tempReg - && pParse->nTempRegaTempReg) - ){ - pParse->aTempReg[pParse->nTempReg++] = pParse->aColCache[i].iReg; - } - } - pParse->nColCache = 0; -} - -/* -** Record the fact that an affinity change has occurred on iCount -** registers starting with iStart. -*/ -SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse *pParse, int iStart, int iCount){ - sqlite3ExprCacheRemove(pParse, iStart, iCount); -} /* ** Generate code to move content from registers iFrom...iFrom+nReg-1 -** over to iTo..iTo+nReg-1. Keep the column cache up-to-date. +** over to iTo..iTo+nReg-1. */ SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){ assert( iFrom>=iTo+nReg || iFrom+nReg<=iTo ); sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg); - sqlite3ExprCacheRemove(pParse, iFrom, nReg); } -#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) -/* -** Return true if any register in the range iFrom..iTo (inclusive) -** is used as part of the column cache. -** -** This routine is used within assert() and testcase() macros only -** and does not appear in a normal build. -*/ -static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){ - int i; - struct yColCache *p; - for(i=0, p=pParse->aColCache; inColCache; i++, p++){ - int r = p->iReg; - if( r>=iFrom && r<=iTo ) return 1; /*NO_TEST*/ - } - return 0; -} -#endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */ - - /* ** Convert a scalar expression node to a TK_REGISTER referencing ** register iReg. The caller must ensure that iReg already contains @@ -98301,6 +99161,28 @@ expr_code_doover: } case TK_COLUMN: { int iTab = pExpr->iTable; + if( ExprHasProperty(pExpr, EP_FixedCol) ){ + /* This COLUMN expression is really a constant due to WHERE clause + ** constraints, and that constant is coded by the pExpr->pLeft + ** expresssion. However, make sure the constant has the correct + ** datatype by applying the Affinity of the table column to the + ** constant. + */ + int iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target); + int aff = sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn); + if( aff!=SQLITE_AFF_BLOB ){ + static const char zAff[] = "B\000C\000D\000E"; + assert( SQLITE_AFF_BLOB=='A' ); + assert( SQLITE_AFF_TEXT=='B' ); + if( iReg!=target ){ + sqlite3VdbeAddOp2(v, OP_SCopy, iReg, target); + iReg = target; + } + sqlite3VdbeAddOp4(v, OP_Affinity, iReg, 1, 0, + &zAff[(aff-'B')*2], P4_STATIC); + } + return iReg; + } if( iTab<0 ){ if( pParse->iSelfTab<0 ){ /* Generating CHECK constraints or inserting into partial index */ @@ -98381,8 +99263,6 @@ expr_code_doover: } sqlite3VdbeAddOp2(v, OP_Cast, target, sqlite3AffinityType(pExpr->u.zToken, 0)); - testcase( usedAsColumnCache(pParse, inReg, inReg) ); - sqlite3ExprCacheAffinityChange(pParse, inReg, 1); return inReg; } #endif /* SQLITE_OMIT_CAST */ @@ -98526,6 +99406,12 @@ expr_code_doover: u8 enc = ENC(db); /* The text encoding used by this database */ CollSeq *pColl = 0; /* A collating sequence */ +#ifndef SQLITE_OMIT_WINDOWFUNC + if( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) && pExpr->pWin ){ + return pExpr->pWin->regResult; + } +#endif + if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){ /* SQL functions can be expensive. So try to move constant functions ** out of the inner loop, even if that means an extra OP_Copy. */ @@ -98562,10 +99448,7 @@ expr_code_doover: for(i=1; ia[i].pExpr, target); - sqlite3ExprCachePop(pParse); } sqlite3VdbeResolveLabel(v, endCoalesce); break; @@ -98631,10 +99514,8 @@ expr_code_doover: } } - sqlite3ExprCachePush(pParse); /* Ticket 2ea2425d34be */ sqlite3ExprCodeExprList(pParse, pFarg, r1, 0, SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR); - sqlite3ExprCachePop(pParse); /* Ticket 2ea2425d34be */ }else{ r1 = 0; } @@ -98651,7 +99532,7 @@ expr_code_doover: ** "glob(B,A). We want to use the A in "A glob B" to test ** for function overloading. But we use the B term in "glob(B,A)". */ - if( nFarg>=2 && (pExpr->flags & EP_InfixFunc) ){ + if( nFarg>=2 && ExprHasProperty(pExpr, EP_InfixFunc) ){ pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[1].pExpr); }else if( nFarg>0 ){ pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr); @@ -98807,9 +99688,7 @@ expr_code_doover: case TK_IF_NULL_ROW: { int addrINR; addrINR = sqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable); - sqlite3ExprCachePush(pParse); inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); - sqlite3ExprCachePop(pParse); sqlite3VdbeJumpHere(v, addrINR); sqlite3VdbeChangeP3(v, addrINR, inReg); break; @@ -98846,7 +99725,6 @@ expr_code_doover: Expr opCompare; /* The X==Ei expression */ Expr *pX; /* The X expression */ Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */ - VVA_ONLY( int iCacheLevel = pParse->iCacheLevel; ) assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList ); assert(pExpr->x.pList->nExpr > 0); @@ -98870,7 +99748,6 @@ expr_code_doover: regFree1 = 0; } for(i=0; iop==TK_COLUMN ); sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target); sqlite3VdbeGoto(v, endLabel); - sqlite3ExprCachePop(pParse); sqlite3VdbeResolveLabel(v, nextCase); } if( (nExpr&1)!=0 ){ - sqlite3ExprCachePush(pParse); sqlite3ExprCode(pParse, pEList->a[nExpr-1].pExpr, target); - sqlite3ExprCachePop(pParse); }else{ sqlite3VdbeAddOp2(v, OP_Null, 0, target); } - assert( pParse->db->mallocFailed || pParse->nErr>0 - || pParse->iCacheLevel==iCacheLevel ); sqlite3VdbeResolveLabel(v, endLabel); break; } @@ -99044,7 +99916,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){ ** might choose to code the expression at initialization time. */ SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){ - if( pParse->okConstFactor && sqlite3ExprIsConstant(pExpr) ){ + if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pExpr) ){ sqlite3ExprCodeAtInit(pParse, pExpr, target); }else{ sqlite3ExprCode(pParse, pExpr, target); @@ -99126,7 +99998,9 @@ SQLITE_PRIVATE int sqlite3ExprCodeExprList( }else{ sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i); } - }else if( (flags & SQLITE_ECEL_FACTOR)!=0 && sqlite3ExprIsConstant(pExpr) ){ + }else if( (flags & SQLITE_ECEL_FACTOR)!=0 + && sqlite3ExprIsConstantNotJoin(pExpr) + ){ sqlite3ExprCodeAtInit(pParse, pExpr, target+i); }else{ int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i); @@ -99252,18 +100126,14 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int int d2 = sqlite3VdbeMakeLabel(v); testcase( jumpIfNull==0 ); sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL); - sqlite3ExprCachePush(pParse); sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); sqlite3VdbeResolveLabel(v, d2); - sqlite3ExprCachePop(pParse); break; } case TK_OR: { testcase( jumpIfNull==0 ); sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); - sqlite3ExprCachePush(pParse); sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); - sqlite3ExprCachePop(pParse); break; } case TK_NOT: { @@ -99422,19 +100292,15 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int case TK_AND: { testcase( jumpIfNull==0 ); sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); - sqlite3ExprCachePush(pParse); sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); - sqlite3ExprCachePop(pParse); break; } case TK_OR: { int d2 = sqlite3VdbeMakeLabel(v); testcase( jumpIfNull==0 ); sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL); - sqlite3ExprCachePush(pParse); sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); sqlite3VdbeResolveLabel(v, d2); - sqlite3ExprCachePop(pParse); break; } case TK_NOT: { @@ -99656,7 +100522,8 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTa if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2; if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){ if( combinedFlags & EP_xIsSelect ) return 2; - if( sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2; + if( (combinedFlags & EP_FixedCol)==0 + && sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2; if( sqlite3ExprCompare(pParse, pA->pRight, pB->pRight, iTab) ) return 2; if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2; assert( (combinedFlags & EP_Reduced)==0 ); @@ -99665,6 +100532,21 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTa if( pA->iTable!=pB->iTable && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2; } +#ifndef SQLITE_OMIT_WINDOWFUNC + /* Justification for the assert(): + ** window functions have p->op==TK_FUNCTION but aggregate functions + ** have p->op==TK_AGG_FUNCTION. So any comparison between an aggregate + ** function and a window function should have failed before reaching + ** this point. And, it is not possible to have a window function and + ** a scalar function with the same name and number of arguments. So + ** if we reach this point, either A and B both window functions or + ** neither are a window functions. */ + assert( (pA->pWin==0)==(pB->pWin==0) ); + + if( pA->pWin!=0 ){ + if( sqlite3WindowCompare(pParse,pA->pWin,pB->pWin)!=0 ) return 2; + } +#endif } return 0; } @@ -99755,18 +100637,15 @@ SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Parse *pParse, Expr *pE1, Expr *pE2, i /* ** This is the Expr node callback for sqlite3ExprImpliesNotNullRow(). ** If the expression node requires that the table at pWalker->iCur -** have a non-NULL column, then set pWalker->eCode to 1 and abort. +** have one or more non-NULL column, then set pWalker->eCode to 1 and abort. +** +** This routine controls an optimization. False positives (setting +** pWalker->eCode to 1 when it should not be) are deadly, but false-negatives +** (never setting pWalker->eCode) is a harmless missed optimization. */ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ - /* This routine is only called for WHERE clause expressions and so it - ** cannot have any TK_AGG_COLUMN entries because those are only found - ** in HAVING clauses. We can get a TK_AGG_FUNCTION in a WHERE clause, - ** but that is an illegal construct and the query will be rejected at - ** a later stage of processing, so the TK_AGG_FUNCTION case does not - ** need to be considered here. */ - assert( pExpr->op!=TK_AGG_COLUMN ); + testcase( pExpr->op==TK_AGG_COLUMN ); testcase( pExpr->op==TK_AGG_FUNCTION ); - if( ExprHasProperty(pExpr, EP_FromJoin) ) return WRC_Prune; switch( pExpr->op ){ case TK_ISNOT: @@ -100186,21 +101065,9 @@ SQLITE_PRIVATE int sqlite3GetTempReg(Parse *pParse){ /* ** Deallocate a register, making available for reuse for some other ** purpose. -** -** If a register is currently being used by the column cache, then -** the deallocation is deferred until the column cache line that uses -** the register becomes stale. */ SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){ if( iReg && pParse->nTempRegaTempReg) ){ - int i; - struct yColCache *p; - for(i=0, p=pParse->aColCache; inColCache; i++, p++){ - if( p->iReg==iReg ){ - p->tempReg = 1; - return; - } - } pParse->aTempReg[pParse->nTempReg++] = iReg; } } @@ -100214,7 +101081,6 @@ SQLITE_PRIVATE int sqlite3GetTempRange(Parse *pParse, int nReg){ i = pParse->iRangeReg; n = pParse->nRangeReg; if( nReg<=n ){ - assert( !usedAsColumnCache(pParse, i, i+n-1) ); pParse->iRangeReg += nReg; pParse->nRangeReg -= nReg; }else{ @@ -100228,7 +101094,6 @@ SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){ sqlite3ReleaseTempReg(pParse, iReg); return; } - sqlite3ExprCacheRemove(pParse, iReg, nReg); if( nReg>pParse->nRangeReg ){ pParse->nRangeReg = nReg; pParse->iRangeReg = iReg; @@ -100290,352 +101155,6 @@ SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse *pParse, int iFirst, int iLast){ */ #ifndef SQLITE_OMIT_ALTERTABLE - -/* -** This function is used by SQL generated to implement the -** ALTER TABLE command. The first argument is the text of a CREATE TABLE or -** CREATE INDEX command. The second is a table name. The table name in -** the CREATE TABLE or CREATE INDEX statement is replaced with the third -** argument and the result returned. Examples: -** -** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def') -** -> 'CREATE TABLE def(a, b, c)' -** -** sqlite_rename_table('CREATE INDEX i ON abc(a)', 'def') -** -> 'CREATE INDEX i ON def(a, b, c)' -*/ -static void renameTableFunc( - sqlite3_context *context, - int NotUsed, - sqlite3_value **argv -){ - unsigned char const *zSql = sqlite3_value_text(argv[0]); - unsigned char const *zTableName = sqlite3_value_text(argv[1]); - - int token; - Token tname; - unsigned char const *zCsr = zSql; - int len = 0; - char *zRet; - - sqlite3 *db = sqlite3_context_db_handle(context); - - UNUSED_PARAMETER(NotUsed); - - /* The principle used to locate the table name in the CREATE TABLE - ** statement is that the table name is the first non-space token that - ** is immediately followed by a TK_LP or TK_USING token. - */ - if( zSql ){ - do { - if( !*zCsr ){ - /* Ran out of input before finding an opening bracket. Return NULL. */ - return; - } - - /* Store the token that zCsr points to in tname. */ - tname.z = (char*)zCsr; - tname.n = len; - - /* Advance zCsr to the next token. Store that token type in 'token', - ** and its length in 'len' (to be used next iteration of this loop). - */ - do { - zCsr += len; - len = sqlite3GetToken(zCsr, &token); - } while( token==TK_SPACE ); - assert( len>0 ); - } while( token!=TK_LP && token!=TK_USING ); - - zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql), - zSql, zTableName, tname.z+tname.n); - sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC); - } -} - -/* -** This C function implements an SQL user function that is used by SQL code -** generated by the ALTER TABLE ... RENAME command to modify the definition -** of any foreign key constraints that use the table being renamed as the -** parent table. It is passed three arguments: -** -** 1) The complete text of the CREATE TABLE statement being modified, -** 2) The old name of the table being renamed, and -** 3) The new name of the table being renamed. -** -** It returns the new CREATE TABLE statement. For example: -** -** sqlite_rename_parent('CREATE TABLE t1(a REFERENCES t2)', 't2', 't3') -** -> 'CREATE TABLE t1(a REFERENCES t3)' -*/ -#ifndef SQLITE_OMIT_FOREIGN_KEY -static void renameParentFunc( - sqlite3_context *context, - int NotUsed, - sqlite3_value **argv -){ - sqlite3 *db = sqlite3_context_db_handle(context); - char *zOutput = 0; - char *zResult; - unsigned char const *zInput = sqlite3_value_text(argv[0]); - unsigned char const *zOld = sqlite3_value_text(argv[1]); - unsigned char const *zNew = sqlite3_value_text(argv[2]); - - unsigned const char *z; /* Pointer to token */ - int n; /* Length of token z */ - int token; /* Type of token */ - - UNUSED_PARAMETER(NotUsed); - if( zInput==0 || zOld==0 ) return; - for(z=zInput; *z; z=z+n){ - n = sqlite3GetToken(z, &token); - if( token==TK_REFERENCES ){ - char *zParent; - do { - z += n; - n = sqlite3GetToken(z, &token); - }while( token==TK_SPACE ); - - if( token==TK_ILLEGAL ) break; - zParent = sqlite3DbStrNDup(db, (const char *)z, n); - if( zParent==0 ) break; - sqlite3Dequote(zParent); - if( 0==sqlite3StrICmp((const char *)zOld, zParent) ){ - char *zOut = sqlite3MPrintf(db, "%s%.*s\"%w\"", - (zOutput?zOutput:""), (int)(z-zInput), zInput, (const char *)zNew - ); - sqlite3DbFree(db, zOutput); - zOutput = zOut; - zInput = &z[n]; - } - sqlite3DbFree(db, zParent); - } - } - - zResult = sqlite3MPrintf(db, "%s%s", (zOutput?zOutput:""), zInput), - sqlite3_result_text(context, zResult, -1, SQLITE_DYNAMIC); - sqlite3DbFree(db, zOutput); -} -#endif - -#ifndef SQLITE_OMIT_TRIGGER -/* This function is used by SQL generated to implement the -** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER -** statement. The second is a table name. The table name in the CREATE -** TRIGGER statement is replaced with the third argument and the result -** returned. This is analagous to renameTableFunc() above, except for CREATE -** TRIGGER, not CREATE INDEX and CREATE TABLE. -*/ -static void renameTriggerFunc( - sqlite3_context *context, - int NotUsed, - sqlite3_value **argv -){ - unsigned char const *zSql = sqlite3_value_text(argv[0]); - unsigned char const *zTableName = sqlite3_value_text(argv[1]); - - int token; - Token tname; - int dist = 3; - unsigned char const *zCsr = zSql; - int len = 0; - char *zRet; - sqlite3 *db = sqlite3_context_db_handle(context); - - UNUSED_PARAMETER(NotUsed); - - /* The principle used to locate the table name in the CREATE TRIGGER - ** statement is that the table name is the first token that is immediately - ** preceded by either TK_ON or TK_DOT and immediately followed by one - ** of TK_WHEN, TK_BEGIN or TK_FOR. - */ - if( zSql ){ - do { - - if( !*zCsr ){ - /* Ran out of input before finding the table name. Return NULL. */ - return; - } - - /* Store the token that zCsr points to in tname. */ - tname.z = (char*)zCsr; - tname.n = len; - - /* Advance zCsr to the next token. Store that token type in 'token', - ** and its length in 'len' (to be used next iteration of this loop). - */ - do { - zCsr += len; - len = sqlite3GetToken(zCsr, &token); - }while( token==TK_SPACE ); - assert( len>0 ); - - /* Variable 'dist' stores the number of tokens read since the most - ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN - ** token is read and 'dist' equals 2, the condition stated above - ** to be met. - ** - ** Note that ON cannot be a database, table or column name, so - ** there is no need to worry about syntax like - ** "CREATE TRIGGER ... ON ON.ON BEGIN ..." etc. - */ - dist++; - if( token==TK_DOT || token==TK_ON ){ - dist = 0; - } - } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) ); - - /* Variable tname now contains the token that is the old table-name - ** in the CREATE TRIGGER statement. - */ - zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql), - zSql, zTableName, tname.z+tname.n); - sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC); - } -} -#endif /* !SQLITE_OMIT_TRIGGER */ - -/* -** Register built-in functions used to help implement ALTER TABLE -*/ -SQLITE_PRIVATE void sqlite3AlterFunctions(void){ - static FuncDef aAlterTableFuncs[] = { - FUNCTION(sqlite_rename_table, 2, 0, 0, renameTableFunc), -#ifndef SQLITE_OMIT_TRIGGER - FUNCTION(sqlite_rename_trigger, 2, 0, 0, renameTriggerFunc), -#endif -#ifndef SQLITE_OMIT_FOREIGN_KEY - FUNCTION(sqlite_rename_parent, 3, 0, 0, renameParentFunc), -#endif - }; - sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs)); -} - -/* -** This function is used to create the text of expressions of the form: -** -** name= OR name= OR ... -** -** If argument zWhere is NULL, then a pointer string containing the text -** "name=" is returned, where is the quoted version -** of the string passed as argument zConstant. The returned buffer is -** allocated using sqlite3DbMalloc(). It is the responsibility of the -** caller to ensure that it is eventually freed. -** -** If argument zWhere is not NULL, then the string returned is -** " OR name=", where is the contents of zWhere. -** In this case zWhere is passed to sqlite3DbFree() before returning. -** -*/ -static char *whereOrName(sqlite3 *db, char *zWhere, char *zConstant){ - char *zNew; - if( !zWhere ){ - zNew = sqlite3MPrintf(db, "name=%Q", zConstant); - }else{ - zNew = sqlite3MPrintf(db, "%s OR name=%Q", zWhere, zConstant); - sqlite3DbFree(db, zWhere); - } - return zNew; -} - -#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) -/* -** Generate the text of a WHERE expression which can be used to select all -** tables that have foreign key constraints that refer to table pTab (i.e. -** constraints for which pTab is the parent table) from the sqlite_master -** table. -*/ -static char *whereForeignKeys(Parse *pParse, Table *pTab){ - FKey *p; - char *zWhere = 0; - for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ - zWhere = whereOrName(pParse->db, zWhere, p->pFrom->zName); - } - return zWhere; -} -#endif - -/* -** Generate the text of a WHERE expression which can be used to select all -** temporary triggers on table pTab from the sqlite_temp_master table. If -** table pTab has no temporary triggers, or is itself stored in the -** temporary database, NULL is returned. -*/ -static char *whereTempTriggers(Parse *pParse, Table *pTab){ - Trigger *pTrig; - char *zWhere = 0; - const Schema *pTempSchema = pParse->db->aDb[1].pSchema; /* Temp db schema */ - - /* If the table is not located in the temp-db (in which case NULL is - ** returned, loop through the tables list of triggers. For each trigger - ** that is not part of the temp-db schema, add a clause to the WHERE - ** expression being built up in zWhere. - */ - if( pTab->pSchema!=pTempSchema ){ - sqlite3 *db = pParse->db; - for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){ - if( pTrig->pSchema==pTempSchema ){ - zWhere = whereOrName(db, zWhere, pTrig->zName); - } - } - } - if( zWhere ){ - char *zNew = sqlite3MPrintf(pParse->db, "type='trigger' AND (%s)", zWhere); - sqlite3DbFree(pParse->db, zWhere); - zWhere = zNew; - } - return zWhere; -} - -/* -** Generate code to drop and reload the internal representation of table -** pTab from the database, including triggers and temporary triggers. -** Argument zName is the name of the table in the database schema at -** the time the generated code is executed. This can be different from -** pTab->zName if this function is being called to code part of an -** "ALTER TABLE RENAME TO" statement. -*/ -static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){ - Vdbe *v; - char *zWhere; - int iDb; /* Index of database containing pTab */ -#ifndef SQLITE_OMIT_TRIGGER - Trigger *pTrig; -#endif - - v = sqlite3GetVdbe(pParse); - if( NEVER(v==0) ) return; - assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); - iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - assert( iDb>=0 ); - -#ifndef SQLITE_OMIT_TRIGGER - /* Drop any table triggers from the internal schema. */ - for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){ - int iTrigDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema); - assert( iTrigDb==iDb || iTrigDb==1 ); - sqlite3VdbeAddOp4(v, OP_DropTrigger, iTrigDb, 0, 0, pTrig->zName, 0); - } -#endif - - /* Drop the table and index from the internal schema. */ - sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0); - - /* Reload the table, index and permanent trigger schemas. */ - zWhere = sqlite3MPrintf(pParse->db, "tbl_name=%Q", zName); - if( !zWhere ) return; - sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere); - -#ifndef SQLITE_OMIT_TRIGGER - /* Now, if the table is not stored in the temp database, reload any temp - ** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined. - */ - if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){ - sqlite3VdbeAddParseSchemaOp(v, 1, zWhere); - } -#endif -} - /* ** Parameter zName is the name of a table that is about to be altered ** (either with ALTER TABLE ... RENAME TO or ALTER TABLE ... ADD COLUMN). @@ -100652,6 +101171,49 @@ static int isSystemTable(Parse *pParse, const char *zName){ return 0; } +/* +** Generate code to verify that the schemas of database zDb and, if +** bTemp is not true, database "temp", can still be parsed. This is +** called at the end of the generation of an ALTER TABLE ... RENAME ... +** statement to ensure that the operation has not rendered any schema +** objects unusable. +*/ +static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){ + sqlite3NestedParse(pParse, + "SELECT 1 " + "FROM \"%w\".%s " + "WHERE name NOT LIKE 'sqlite_%%'" + " AND sql NOT LIKE 'create virtual%%'" + " AND sqlite_rename_test(%Q, sql, type, name, %d)=NULL ", + zDb, MASTER_NAME, + zDb, bTemp + ); + + if( bTemp==0 ){ + sqlite3NestedParse(pParse, + "SELECT 1 " + "FROM temp.%s " + "WHERE name NOT LIKE 'sqlite_%%'" + " AND sql NOT LIKE 'create virtual%%'" + " AND sqlite_rename_test(%Q, sql, type, name, 1)=NULL ", + MASTER_NAME, zDb + ); + } +} + +/* +** Generate code to reload the schema for database iDb. And, if iDb!=1, for +** the temp database as well. +*/ +static void renameReloadSchema(Parse *pParse, int iDb){ + Vdbe *v = pParse->pVdbe; + if( v ){ + sqlite3ChangeCookie(pParse, iDb); + sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, iDb, 0); + if( iDb!=1 ) sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, 1, 0); + } +} + /* ** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" ** command. @@ -100669,9 +101231,6 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( int nTabName; /* Number of UTF-8 characters in zTabName */ const char *zTabName; /* Original name of the table */ Vdbe *v; -#ifndef SQLITE_OMIT_TRIGGER - char *zWhere = 0; /* Where clause to locate temp triggers */ -#endif VTable *pVTab = 0; /* Non-zero if this is a v-tab with an xRename() */ u32 savedDbFlags; /* Saved value of db->mDbFlags */ @@ -100744,8 +101303,63 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( if( v==0 ){ goto exit_rename_table; } - sqlite3BeginWriteOperation(pParse, pVTab!=0, iDb); - sqlite3ChangeCookie(pParse, iDb); + + /* figure out how many UTF-8 characters are in zName */ + zTabName = pTab->zName; + nTabName = sqlite3Utf8CharLen(zTabName, -1); + + /* Rewrite all CREATE TABLE, INDEX, TRIGGER or VIEW statements in + ** the schema to use the new table name. */ + sqlite3NestedParse(pParse, + "UPDATE \"%w\".%s SET " + "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) " + "WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)" + "AND name NOT LIKE 'sqlite_%%'" + , zDb, MASTER_NAME, zDb, zTabName, zName, (iDb==1), zTabName + ); + + /* Update the tbl_name and name columns of the sqlite_master table + ** as required. */ + sqlite3NestedParse(pParse, + "UPDATE %Q.%s SET " + "tbl_name = %Q, " + "name = CASE " + "WHEN type='table' THEN %Q " + "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN " + "'sqlite_autoindex_' || %Q || substr(name,%d+18) " + "ELSE name END " + "WHERE tbl_name=%Q COLLATE nocase AND " + "(type='table' OR type='index' OR type='trigger');", + zDb, MASTER_NAME, + zName, zName, zName, + nTabName, zTabName + ); + +#ifndef SQLITE_OMIT_AUTOINCREMENT + /* If the sqlite_sequence table exists in this database, then update + ** it with the new table name. + */ + if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){ + sqlite3NestedParse(pParse, + "UPDATE \"%w\".sqlite_sequence set name = %Q WHERE name = %Q", + zDb, zName, pTab->zName); + } +#endif + + /* If the table being renamed is not itself part of the temp database, + ** edit view and trigger definitions within the temp database + ** as required. */ + if( iDb!=1 ){ + sqlite3NestedParse(pParse, + "UPDATE sqlite_temp_master SET " + "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, 1), " + "tbl_name = " + "CASE WHEN tbl_name=%Q COLLATE nocase AND " + " sqlite_rename_test(%Q, sql, type, name, 1) " + "THEN %Q ELSE tbl_name END " + "WHERE type IN ('view', 'trigger')" + , zDb, zTabName, zName, zTabName, zDb, zName); + } /* If this is a virtual table, invoke the xRename() function if ** one is defined. The xRename() callback will modify the names @@ -100761,90 +101375,8 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( } #endif - /* figure out how many UTF-8 characters are in zName */ - zTabName = pTab->zName; - nTabName = sqlite3Utf8CharLen(zTabName, -1); - -#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) - if( db->flags&SQLITE_ForeignKeys ){ - /* If foreign-key support is enabled, rewrite the CREATE TABLE - ** statements corresponding to all child tables of foreign key constraints - ** for which the renamed table is the parent table. */ - if( (zWhere=whereForeignKeys(pParse, pTab))!=0 ){ - sqlite3NestedParse(pParse, - "UPDATE \"%w\".%s SET " - "sql = sqlite_rename_parent(sql, %Q, %Q) " - "WHERE %s;", zDb, MASTER_NAME, zTabName, zName, zWhere); - sqlite3DbFree(db, zWhere); - } - } -#endif - - /* Modify the sqlite_master table to use the new table name. */ - sqlite3NestedParse(pParse, - "UPDATE %Q.%s SET " -#ifdef SQLITE_OMIT_TRIGGER - "sql = sqlite_rename_table(sql, %Q), " -#else - "sql = CASE " - "WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)" - "ELSE sqlite_rename_table(sql, %Q) END, " -#endif - "tbl_name = %Q, " - "name = CASE " - "WHEN type='table' THEN %Q " - "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN " - "'sqlite_autoindex_' || %Q || substr(name,%d+18) " - "ELSE name END " - "WHERE tbl_name=%Q COLLATE nocase AND " - "(type='table' OR type='index' OR type='trigger');", - zDb, MASTER_NAME, zName, zName, zName, -#ifndef SQLITE_OMIT_TRIGGER - zName, -#endif - zName, nTabName, zTabName - ); - -#ifndef SQLITE_OMIT_AUTOINCREMENT - /* If the sqlite_sequence table exists in this database, then update - ** it with the new table name. - */ - if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){ - sqlite3NestedParse(pParse, - "UPDATE \"%w\".sqlite_sequence set name = %Q WHERE name = %Q", - zDb, zName, pTab->zName); - } -#endif - -#ifndef SQLITE_OMIT_TRIGGER - /* If there are TEMP triggers on this table, modify the sqlite_temp_master - ** table. Don't do this if the table being ALTERed is itself located in - ** the temp database. - */ - if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){ - sqlite3NestedParse(pParse, - "UPDATE sqlite_temp_master SET " - "sql = sqlite_rename_trigger(sql, %Q), " - "tbl_name = %Q " - "WHERE %s;", zName, zName, zWhere); - sqlite3DbFree(db, zWhere); - } -#endif - -#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) - if( db->flags&SQLITE_ForeignKeys ){ - FKey *p; - for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ - Table *pFrom = p->pFrom; - if( pFrom!=pTab ){ - reloadTableSchema(pParse, p->pFrom, pFrom->zName); - } - } - } -#endif - - /* Drop and reload the internal table schema. */ - reloadTableSchema(pParse, pTab, zName); + renameReloadSchema(pParse, iDb); + renameTestSchema(pParse, zDb, iDb==1); exit_rename_table: sqlite3SrcListDelete(db, pSrc); @@ -100870,12 +101402,11 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ Column *pCol; /* The new column */ Expr *pDflt; /* Default value for the new column */ sqlite3 *db; /* The database connection; */ - Vdbe *v = pParse->pVdbe; /* The prepared statement under construction */ + Vdbe *v; /* The prepared statement under construction */ int r1; /* Temporary registers */ db = pParse->db; if( pParse->nErr || db->mallocFailed ) return; - assert( v!=0 ); pNew = pParse->pNewTable; assert( pNew ); @@ -100970,17 +101501,20 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ ** from less than 3 to 4, as that will corrupt any preexisting DESC ** index. */ - r1 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT); - sqlite3VdbeUsesBtree(v, iDb); - sqlite3VdbeAddOp2(v, OP_AddImm, r1, -2); - sqlite3VdbeAddOp2(v, OP_IfPos, r1, sqlite3VdbeCurrentAddr(v)+2); - VdbeCoverage(v); - sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3); - sqlite3ReleaseTempReg(pParse, r1); + v = sqlite3GetVdbe(pParse); + if( v ){ + r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT); + sqlite3VdbeUsesBtree(v, iDb); + sqlite3VdbeAddOp2(v, OP_AddImm, r1, -2); + sqlite3VdbeAddOp2(v, OP_IfPos, r1, sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3); + sqlite3ReleaseTempReg(pParse, r1); + } - /* Reload the schema of the modified table. */ - reloadTableSchema(pParse, pTab, pTab->zName); + /* Reload the table definition */ + renameReloadSchema(pParse, iDb); } /* @@ -101001,7 +101535,6 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ Table *pNew; Table *pTab; - Vdbe *v; int iDb; int i; int nAlloc; @@ -101065,16 +101598,1142 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ pNew->addColOffset = pTab->addColOffset; pNew->nTabRef = 1; - /* Begin a transaction and increment the schema cookie. */ - sqlite3BeginWriteOperation(pParse, 0, iDb); - v = sqlite3GetVdbe(pParse); - if( !v ) goto exit_begin_add_column; - sqlite3ChangeCookie(pParse, iDb); - exit_begin_add_column: sqlite3SrcListDelete(db, pSrc); return; } + +/* +** Parameter pTab is the subject of an ALTER TABLE ... RENAME COLUMN +** command. This function checks if the table is a view or virtual +** table (columns of views or virtual tables may not be renamed). If so, +** it loads an error message into pParse and returns non-zero. +** +** Or, if pTab is not a view or virtual table, zero is returned. +*/ +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) +static int isRealTable(Parse *pParse, Table *pTab){ + const char *zType = 0; +#ifndef SQLITE_OMIT_VIEW + if( pTab->pSelect ){ + zType = "view"; + } +#endif +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + zType = "virtual table"; + } +#endif + if( zType ){ + sqlite3ErrorMsg( + pParse, "cannot rename columns of %s \"%s\"", zType, pTab->zName + ); + return 1; + } + return 0; +} +#else /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */ +# define isRealTable(x,y) (0) +#endif + +/* +** Handles the following parser reduction: +** +** cmd ::= ALTER TABLE pSrc RENAME COLUMN pOld TO pNew +*/ +SQLITE_PRIVATE void sqlite3AlterRenameColumn( + Parse *pParse, /* Parsing context */ + SrcList *pSrc, /* Table being altered. pSrc->nSrc==1 */ + Token *pOld, /* Name of column being changed */ + Token *pNew /* New column name */ +){ + sqlite3 *db = pParse->db; /* Database connection */ + Table *pTab; /* Table being updated */ + int iCol; /* Index of column being renamed */ + char *zOld = 0; /* Old column name */ + char *zNew = 0; /* New column name */ + const char *zDb; /* Name of schema containing the table */ + int iSchema; /* Index of the schema */ + int bQuote; /* True to quote the new name */ + + /* Locate the table to be altered */ + pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); + if( !pTab ) goto exit_rename_column; + + /* Cannot alter a system table */ + if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ) goto exit_rename_column; + if( SQLITE_OK!=isRealTable(pParse, pTab) ) goto exit_rename_column; + + /* Which schema holds the table to be altered */ + iSchema = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iSchema>=0 ); + zDb = db->aDb[iSchema].zDbSName; + +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Invoke the authorization callback. */ + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ + goto exit_rename_column; + } +#endif + + /* Make sure the old name really is a column name in the table to be + ** altered. Set iCol to be the index of the column being renamed */ + zOld = sqlite3NameFromToken(db, pOld); + if( !zOld ) goto exit_rename_column; + for(iCol=0; iColnCol; iCol++){ + if( 0==sqlite3StrICmp(pTab->aCol[iCol].zName, zOld) ) break; + } + if( iCol==pTab->nCol ){ + sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zOld); + goto exit_rename_column; + } + + /* Do the rename operation using a recursive UPDATE statement that + ** uses the sqlite_rename_column() SQL function to compute the new + ** CREATE statement text for the sqlite_master table. + */ + zNew = sqlite3NameFromToken(db, pNew); + if( !zNew ) goto exit_rename_column; + assert( pNew->n>0 ); + bQuote = sqlite3Isquote(pNew->z[0]); + sqlite3NestedParse(pParse, + "UPDATE \"%w\".%s SET " + "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) " + "WHERE name NOT LIKE 'sqlite_%%' AND (type != 'index' OR tbl_name = %Q)" + " AND sql NOT LIKE 'create virtual%%'", + zDb, MASTER_NAME, + zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1, + pTab->zName + ); + + sqlite3NestedParse(pParse, + "UPDATE temp.%s SET " + "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, 1) " + "WHERE type IN ('trigger', 'view')", + MASTER_NAME, + zDb, pTab->zName, iCol, zNew, bQuote + ); + + /* Drop and reload the database schema. */ + renameReloadSchema(pParse, iSchema); + renameTestSchema(pParse, zDb, iSchema==1); + + exit_rename_column: + sqlite3SrcListDelete(db, pSrc); + sqlite3DbFree(db, zOld); + sqlite3DbFree(db, zNew); + return; +} + +/* +** Each RenameToken object maps an element of the parse tree into +** the token that generated that element. The parse tree element +** might be one of: +** +** * A pointer to an Expr that represents an ID +** * The name of a table column in Column.zName +** +** A list of RenameToken objects can be constructed during parsing. +** Each new object is created by sqlite3RenameTokenMap(). +** As the parse tree is transformed, the sqlite3RenameTokenRemap() +** routine is used to keep the mapping current. +** +** After the parse finishes, renameTokenFind() routine can be used +** to look up the actual token value that created some element in +** the parse tree. +*/ +struct RenameToken { + void *p; /* Parse tree element created by token t */ + Token t; /* The token that created parse tree element p */ + RenameToken *pNext; /* Next is a list of all RenameToken objects */ +}; + +/* +** The context of an ALTER TABLE RENAME COLUMN operation that gets passed +** down into the Walker. +*/ +typedef struct RenameCtx RenameCtx; +struct RenameCtx { + RenameToken *pList; /* List of tokens to overwrite */ + int nList; /* Number of tokens in pList */ + int iCol; /* Index of column being renamed */ + Table *pTab; /* Table being ALTERed */ + const char *zOld; /* Old column name */ +}; + +#ifdef SQLITE_DEBUG +/* +** This function is only for debugging. It performs two tasks: +** +** 1. Checks that pointer pPtr does not already appear in the +** rename-token list. +** +** 2. Dereferences each pointer in the rename-token list. +** +** The second is most effective when debugging under valgrind or +** address-sanitizer or similar. If any of these pointers no longer +** point to valid objects, an exception is raised by the memory-checking +** tool. +** +** The point of this is to prevent comparisons of invalid pointer values. +** Even though this always seems to work, it is undefined according to the +** C standard. Example of undefined comparison: +** +** sqlite3_free(x); +** if( x==y ) ... +** +** Technically, as x no longer points into a valid object or to the byte +** following a valid object, it may not be used in comparison operations. +*/ +static void renameTokenCheckAll(Parse *pParse, void *pPtr){ + if( pParse->nErr==0 && pParse->db->mallocFailed==0 ){ + RenameToken *p; + u8 i = 0; + for(p=pParse->pRename; p; p=p->pNext){ + if( p->p ){ + assert( p->p!=pPtr ); + i += *(u8*)(p->p); + } + } + } +} +#else +# define renameTokenCheckAll(x,y) +#endif + +/* +** Add a new RenameToken object mapping parse tree element pPtr into +** token *pToken to the Parse object currently under construction. +** +** Return a copy of pPtr. +*/ +SQLITE_PRIVATE void *sqlite3RenameTokenMap(Parse *pParse, void *pPtr, Token *pToken){ + RenameToken *pNew; + assert( pPtr || pParse->db->mallocFailed ); + renameTokenCheckAll(pParse, pPtr); + pNew = sqlite3DbMallocZero(pParse->db, sizeof(RenameToken)); + if( pNew ){ + pNew->p = pPtr; + pNew->t = *pToken; + pNew->pNext = pParse->pRename; + pParse->pRename = pNew; + } + + return pPtr; +} + +/* +** It is assumed that there is already a RenameToken object associated +** with parse tree element pFrom. This function remaps the associated token +** to parse tree element pTo. +*/ +SQLITE_PRIVATE void sqlite3RenameTokenRemap(Parse *pParse, void *pTo, void *pFrom){ + RenameToken *p; + renameTokenCheckAll(pParse, pTo); + for(p=pParse->pRename; p; p=p->pNext){ + if( p->p==pFrom ){ + p->p = pTo; + break; + } + } +} + +/* +** Walker callback used by sqlite3RenameExprUnmap(). +*/ +static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){ + Parse *pParse = pWalker->pParse; + sqlite3RenameTokenRemap(pParse, 0, (void*)pExpr); + return WRC_Continue; +} + +/* +** Remove all nodes that are part of expression pExpr from the rename list. +*/ +SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse *pParse, Expr *pExpr){ + Walker sWalker; + memset(&sWalker, 0, sizeof(Walker)); + sWalker.pParse = pParse; + sWalker.xExprCallback = renameUnmapExprCb; + sqlite3WalkExpr(&sWalker, pExpr); +} + +/* +** Remove all nodes that are part of expression-list pEList from the +** rename list. +*/ +SQLITE_PRIVATE void sqlite3RenameExprlistUnmap(Parse *pParse, ExprList *pEList){ + if( pEList ){ + int i; + Walker sWalker; + memset(&sWalker, 0, sizeof(Walker)); + sWalker.pParse = pParse; + sWalker.xExprCallback = renameUnmapExprCb; + sqlite3WalkExprList(&sWalker, pEList); + for(i=0; inExpr; i++){ + sqlite3RenameTokenRemap(pParse, 0, (void*)pEList->a[i].zName); + } + } +} + +/* +** Free the list of RenameToken objects given in the second argument +*/ +static void renameTokenFree(sqlite3 *db, RenameToken *pToken){ + RenameToken *pNext; + RenameToken *p; + for(p=pToken; p; p=pNext){ + pNext = p->pNext; + sqlite3DbFree(db, p); + } +} + +/* +** Search the Parse object passed as the first argument for a RenameToken +** object associated with parse tree element pPtr. If found, remove it +** from the Parse object and add it to the list maintained by the +** RenameCtx object passed as the second argument. +*/ +static void renameTokenFind(Parse *pParse, struct RenameCtx *pCtx, void *pPtr){ + RenameToken **pp; + assert( pPtr!=0 ); + for(pp=&pParse->pRename; (*pp); pp=&(*pp)->pNext){ + if( (*pp)->p==pPtr ){ + RenameToken *pToken = *pp; + *pp = pToken->pNext; + pToken->pNext = pCtx->pList; + pCtx->pList = pToken; + pCtx->nList++; + break; + } + } +} + +/* +** This is a Walker select callback. It does nothing. It is only required +** because without a dummy callback, sqlite3WalkExpr() and similar do not +** descend into sub-select statements. +*/ +static int renameColumnSelectCb(Walker *pWalker, Select *p){ + UNUSED_PARAMETER(pWalker); + UNUSED_PARAMETER(p); + return WRC_Continue; +} + +/* +** This is a Walker expression callback. +** +** For every TK_COLUMN node in the expression tree, search to see +** if the column being references is the column being renamed by an +** ALTER TABLE statement. If it is, then attach its associated +** RenameToken object to the list of RenameToken objects being +** constructed in RenameCtx object at pWalker->u.pRename. +*/ +static int renameColumnExprCb(Walker *pWalker, Expr *pExpr){ + RenameCtx *p = pWalker->u.pRename; + if( pExpr->op==TK_TRIGGER + && pExpr->iColumn==p->iCol + && pWalker->pParse->pTriggerTab==p->pTab + ){ + renameTokenFind(pWalker->pParse, p, (void*)pExpr); + }else if( pExpr->op==TK_COLUMN + && pExpr->iColumn==p->iCol + && p->pTab==pExpr->pTab + ){ + renameTokenFind(pWalker->pParse, p, (void*)pExpr); + } + return WRC_Continue; +} + +/* +** The RenameCtx contains a list of tokens that reference a column that +** is being renamed by an ALTER TABLE statement. Return the "last" +** RenameToken in the RenameCtx and remove that RenameToken from the +** RenameContext. "Last" means the last RenameToken encountered when +** the input SQL is parsed from left to right. Repeated calls to this routine +** return all column name tokens in the order that they are encountered +** in the SQL statement. +*/ +static RenameToken *renameColumnTokenNext(RenameCtx *pCtx){ + RenameToken *pBest = pCtx->pList; + RenameToken *pToken; + RenameToken **pp; + + for(pToken=pBest->pNext; pToken; pToken=pToken->pNext){ + if( pToken->t.z>pBest->t.z ) pBest = pToken; + } + for(pp=&pCtx->pList; *pp!=pBest; pp=&(*pp)->pNext); + *pp = pBest->pNext; + + return pBest; +} + +/* +** An error occured while parsing or otherwise processing a database +** object (either pParse->pNewTable, pNewIndex or pNewTrigger) as part of an +** ALTER TABLE RENAME COLUMN program. The error message emitted by the +** sub-routine is currently stored in pParse->zErrMsg. This function +** adds context to the error message and then stores it in pCtx. +*/ +static void renameColumnParseError( + sqlite3_context *pCtx, + int bPost, + sqlite3_value *pType, + sqlite3_value *pObject, + Parse *pParse +){ + const char *zT = (const char*)sqlite3_value_text(pType); + const char *zN = (const char*)sqlite3_value_text(pObject); + char *zErr; + + zErr = sqlite3_mprintf("error in %s %s%s: %s", + zT, zN, (bPost ? " after rename" : ""), + pParse->zErrMsg + ); + sqlite3_result_error(pCtx, zErr, -1); + sqlite3_free(zErr); +} + +/* +** For each name in the the expression-list pEList (i.e. each +** pEList->a[i].zName) that matches the string in zOld, extract the +** corresponding rename-token from Parse object pParse and add it +** to the RenameCtx pCtx. +*/ +static void renameColumnElistNames( + Parse *pParse, + RenameCtx *pCtx, + ExprList *pEList, + const char *zOld +){ + if( pEList ){ + int i; + for(i=0; inExpr; i++){ + char *zName = pEList->a[i].zName; + if( 0==sqlite3_stricmp(zName, zOld) ){ + renameTokenFind(pParse, pCtx, (void*)zName); + } + } + } +} + +/* +** For each name in the the id-list pIdList (i.e. each pIdList->a[i].zName) +** that matches the string in zOld, extract the corresponding rename-token +** from Parse object pParse and add it to the RenameCtx pCtx. +*/ +static void renameColumnIdlistNames( + Parse *pParse, + RenameCtx *pCtx, + IdList *pIdList, + const char *zOld +){ + if( pIdList ){ + int i; + for(i=0; inId; i++){ + char *zName = pIdList->a[i].zName; + if( 0==sqlite3_stricmp(zName, zOld) ){ + renameTokenFind(pParse, pCtx, (void*)zName); + } + } + } +} + +/* +** Parse the SQL statement zSql using Parse object (*p). The Parse object +** is initialized by this function before it is used. +*/ +static int renameParseSql( + Parse *p, /* Memory to use for Parse object */ + const char *zDb, /* Name of schema SQL belongs to */ + int bTable, /* 1 -> RENAME TABLE, 0 -> RENAME COLUMN */ + sqlite3 *db, /* Database handle */ + const char *zSql, /* SQL to parse */ + int bTemp /* True if SQL is from temp schema */ +){ + int rc; + char *zErr = 0; + + db->init.iDb = bTemp ? 1 : sqlite3FindDbName(db, zDb); + + /* Parse the SQL statement passed as the first argument. If no error + ** occurs and the parse does not result in a new table, index or + ** trigger object, the database must be corrupt. */ + memset(p, 0, sizeof(Parse)); + p->eParseMode = (bTable ? PARSE_MODE_RENAME_TABLE : PARSE_MODE_RENAME_COLUMN); + p->db = db; + p->nQueryLoop = 1; + rc = sqlite3RunParser(p, zSql, &zErr); + assert( p->zErrMsg==0 ); + assert( rc!=SQLITE_OK || zErr==0 ); + assert( (0!=p->pNewTable) + (0!=p->pNewIndex) + (0!=p->pNewTrigger)<2 ); + p->zErrMsg = zErr; + if( db->mallocFailed ) rc = SQLITE_NOMEM; + if( rc==SQLITE_OK + && p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0 + ){ + rc = SQLITE_CORRUPT_BKPT; + } + +#ifdef SQLITE_DEBUG + /* Ensure that all mappings in the Parse.pRename list really do map to + ** a part of the input string. */ + if( rc==SQLITE_OK ){ + int nSql = sqlite3Strlen30(zSql); + RenameToken *pToken; + for(pToken=p->pRename; pToken; pToken=pToken->pNext){ + assert( pToken->t.z>=zSql && &pToken->t.z[pToken->t.n]<=&zSql[nSql] ); + } + } +#endif + + db->init.iDb = 0; + return rc; +} + +/* +** This function edits SQL statement zSql, replacing each token identified +** by the linked list pRename with the text of zNew. If argument bQuote is +** true, then zNew is always quoted first. If no error occurs, the result +** is loaded into context object pCtx as the result. +** +** Or, if an error occurs (i.e. an OOM condition), an error is left in +** pCtx and an SQLite error code returned. +*/ +static int renameEditSql( + sqlite3_context *pCtx, /* Return result here */ + RenameCtx *pRename, /* Rename context */ + const char *zSql, /* SQL statement to edit */ + const char *zNew, /* New token text */ + int bQuote /* True to always quote token */ +){ + int nNew = sqlite3Strlen30(zNew); + int nSql = sqlite3Strlen30(zSql); + sqlite3 *db = sqlite3_context_db_handle(pCtx); + int rc = SQLITE_OK; + char *zQuot; + char *zOut; + int nQuot; + + /* Set zQuot to point to a buffer containing a quoted copy of the + ** identifier zNew. If the corresponding identifier in the original + ** ALTER TABLE statement was quoted (bQuote==1), then set zNew to + ** point to zQuot so that all substitutions are made using the + ** quoted version of the new column name. */ + zQuot = sqlite3MPrintf(db, "\"%w\"", zNew); + if( zQuot==0 ){ + return SQLITE_NOMEM; + }else{ + nQuot = sqlite3Strlen30(zQuot); + } + if( bQuote ){ + zNew = zQuot; + nNew = nQuot; + } + + /* At this point pRename->pList contains a list of RenameToken objects + ** corresponding to all tokens in the input SQL that must be replaced + ** with the new column name. All that remains is to construct and + ** return the edited SQL string. */ + assert( nQuot>=nNew ); + zOut = sqlite3DbMallocZero(db, nSql + pRename->nList*nQuot + 1); + if( zOut ){ + int nOut = nSql; + memcpy(zOut, zSql, nSql); + while( pRename->pList ){ + int iOff; /* Offset of token to replace in zOut */ + RenameToken *pBest = renameColumnTokenNext(pRename); + + u32 nReplace; + const char *zReplace; + if( sqlite3IsIdChar(*pBest->t.z) ){ + nReplace = nNew; + zReplace = zNew; + }else{ + nReplace = nQuot; + zReplace = zQuot; + } + + iOff = pBest->t.z - zSql; + if( pBest->t.n!=nReplace ){ + memmove(&zOut[iOff + nReplace], &zOut[iOff + pBest->t.n], + nOut - (iOff + pBest->t.n) + ); + nOut += nReplace - pBest->t.n; + zOut[nOut] = '\0'; + } + memcpy(&zOut[iOff], zReplace, nReplace); + sqlite3DbFree(db, pBest); + } + + sqlite3_result_text(pCtx, zOut, -1, SQLITE_TRANSIENT); + sqlite3DbFree(db, zOut); + }else{ + rc = SQLITE_NOMEM; + } + + sqlite3_free(zQuot); + return rc; +} + +/* +** Resolve all symbols in the trigger at pParse->pNewTrigger, assuming +** it was read from the schema of database zDb. Return SQLITE_OK if +** successful. Otherwise, return an SQLite error code and leave an error +** message in the Parse object. +*/ +static int renameResolveTrigger(Parse *pParse, const char *zDb){ + sqlite3 *db = pParse->db; + Trigger *pNew = pParse->pNewTrigger; + TriggerStep *pStep; + NameContext sNC; + int rc = SQLITE_OK; + + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + assert( pNew->pTabSchema ); + pParse->pTriggerTab = sqlite3FindTable(db, pNew->table, + db->aDb[sqlite3SchemaToIndex(db, pNew->pTabSchema)].zDbSName + ); + pParse->eTriggerOp = pNew->op; + + /* Resolve symbols in WHEN clause */ + if( pNew->pWhen ){ + rc = sqlite3ResolveExprNames(&sNC, pNew->pWhen); + } + + for(pStep=pNew->step_list; rc==SQLITE_OK && pStep; pStep=pStep->pNext){ + if( pStep->pSelect ){ + sqlite3SelectPrep(pParse, pStep->pSelect, &sNC); + if( pParse->nErr ) rc = pParse->rc; + } + if( rc==SQLITE_OK && pStep->zTarget ){ + Table *pTarget = sqlite3LocateTable(pParse, 0, pStep->zTarget, zDb); + if( pTarget==0 ){ + rc = SQLITE_ERROR; + }else if( SQLITE_OK==(rc = sqlite3ViewGetColumnNames(pParse, pTarget)) ){ + SrcList sSrc; + memset(&sSrc, 0, sizeof(sSrc)); + sSrc.nSrc = 1; + sSrc.a[0].zName = pStep->zTarget; + sSrc.a[0].pTab = pTarget; + sNC.pSrcList = &sSrc; + if( pStep->pWhere ){ + rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere); + } + if( rc==SQLITE_OK ){ + rc = sqlite3ResolveExprListNames(&sNC, pStep->pExprList); + } + assert( !pStep->pUpsert || (!pStep->pWhere && !pStep->pExprList) ); + if( pStep->pUpsert ){ + Upsert *pUpsert = pStep->pUpsert; + assert( rc==SQLITE_OK ); + pUpsert->pUpsertSrc = &sSrc; + sNC.uNC.pUpsert = pUpsert; + sNC.ncFlags = NC_UUpsert; + rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget); + if( rc==SQLITE_OK ){ + ExprList *pUpsertSet = pUpsert->pUpsertSet; + rc = sqlite3ResolveExprListNames(&sNC, pUpsertSet); + } + if( rc==SQLITE_OK ){ + rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertWhere); + } + if( rc==SQLITE_OK ){ + rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere); + } + sNC.ncFlags = 0; + } + } + } + } + return rc; +} + +/* +** Invoke sqlite3WalkExpr() or sqlite3WalkSelect() on all Select or Expr +** objects that are part of the trigger passed as the second argument. +*/ +static void renameWalkTrigger(Walker *pWalker, Trigger *pTrigger){ + TriggerStep *pStep; + + /* Find tokens to edit in WHEN clause */ + sqlite3WalkExpr(pWalker, pTrigger->pWhen); + + /* Find tokens to edit in trigger steps */ + for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){ + sqlite3WalkSelect(pWalker, pStep->pSelect); + sqlite3WalkExpr(pWalker, pStep->pWhere); + sqlite3WalkExprList(pWalker, pStep->pExprList); + if( pStep->pUpsert ){ + Upsert *pUpsert = pStep->pUpsert; + sqlite3WalkExprList(pWalker, pUpsert->pUpsertTarget); + sqlite3WalkExprList(pWalker, pUpsert->pUpsertSet); + sqlite3WalkExpr(pWalker, pUpsert->pUpsertWhere); + sqlite3WalkExpr(pWalker, pUpsert->pUpsertTargetWhere); + } + } +} + +/* +** Free the contents of Parse object (*pParse). Do not free the memory +** occupied by the Parse object itself. +*/ +static void renameParseCleanup(Parse *pParse){ + sqlite3 *db = pParse->db; + if( pParse->pVdbe ){ + sqlite3VdbeFinalize(pParse->pVdbe); + } + sqlite3DeleteTable(db, pParse->pNewTable); + if( pParse->pNewIndex ) sqlite3FreeIndex(db, pParse->pNewIndex); + sqlite3DeleteTrigger(db, pParse->pNewTrigger); + sqlite3DbFree(db, pParse->zErrMsg); + renameTokenFree(db, pParse->pRename); + sqlite3ParserReset(pParse); +} + +/* +** SQL function: +** +** sqlite_rename_column(zSql, iCol, bQuote, zNew, zTable, zOld) +** +** 0. zSql: SQL statement to rewrite +** 1. type: Type of object ("table", "view" etc.) +** 2. object: Name of object +** 3. Database: Database name (e.g. "main") +** 4. Table: Table name +** 5. iCol: Index of column to rename +** 6. zNew: New column name +** 7. bQuote: Non-zero if the new column name should be quoted. +** 8. bTemp: True if zSql comes from temp schema +** +** Do a column rename operation on the CREATE statement given in zSql. +** The iCol-th column (left-most is 0) of table zTable is renamed from zCol +** into zNew. The name should be quoted if bQuote is true. +** +** This function is used internally by the ALTER TABLE RENAME COLUMN command. +** Though accessible to application code, it is not intended for use by +** applications. The existance of this function, and the way it works, +** is subject to change without notice. +** +** If any of the parameters are out-of-bounds, then simply return NULL. +** An out-of-bounds parameter can only occur when the application calls +** this function directly. The parameters will always be well-formed when +** this routine is invoked by the bytecode for a legitimate ALTER TABLE +** statement. +*/ +static void renameColumnFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + RenameCtx sCtx; + const char *zSql = (const char*)sqlite3_value_text(argv[0]); + const char *zDb = (const char*)sqlite3_value_text(argv[3]); + const char *zTable = (const char*)sqlite3_value_text(argv[4]); + int iCol = sqlite3_value_int(argv[5]); + const char *zNew = (const char*)sqlite3_value_text(argv[6]); + int bQuote = sqlite3_value_int(argv[7]); + int bTemp = sqlite3_value_int(argv[8]); + const char *zOld; + int rc; + Parse sParse; + Walker sWalker; + Index *pIdx; + int i; + Table *pTab; +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth = db->xAuth; +#endif + + UNUSED_PARAMETER(NotUsed); + if( zSql==0 ) return; + if( zTable==0 ) return; + if( zNew==0 ) return; + if( iCol<0 ) return; + sqlite3BtreeEnterAll(db); + pTab = sqlite3FindTable(db, zTable, zDb); + if( pTab==0 || iCol>=pTab->nCol ){ + sqlite3BtreeLeaveAll(db); + return; + } + zOld = pTab->aCol[iCol].zName; + memset(&sCtx, 0, sizeof(sCtx)); + sCtx.iCol = ((iCol==pTab->iPKey) ? -1 : iCol); + +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = 0; +#endif + rc = renameParseSql(&sParse, zDb, 0, db, zSql, bTemp); + + /* Find tokens that need to be replaced. */ + memset(&sWalker, 0, sizeof(Walker)); + sWalker.pParse = &sParse; + sWalker.xExprCallback = renameColumnExprCb; + sWalker.xSelectCallback = renameColumnSelectCb; + sWalker.u.pRename = &sCtx; + + sCtx.pTab = pTab; + if( rc!=SQLITE_OK ) goto renameColumnFunc_done; + if( sParse.pNewTable ){ + Select *pSelect = sParse.pNewTable->pSelect; + if( pSelect ){ + sParse.rc = SQLITE_OK; + sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, 0); + rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc); + if( rc==SQLITE_OK ){ + sqlite3WalkSelect(&sWalker, pSelect); + } + if( rc!=SQLITE_OK ) goto renameColumnFunc_done; + }else{ + /* A regular table */ + int bFKOnly = sqlite3_stricmp(zTable, sParse.pNewTable->zName); + FKey *pFKey; + assert( sParse.pNewTable->pSelect==0 ); + sCtx.pTab = sParse.pNewTable; + if( bFKOnly==0 ){ + renameTokenFind( + &sParse, &sCtx, (void*)sParse.pNewTable->aCol[iCol].zName + ); + if( sCtx.iCol<0 ){ + renameTokenFind(&sParse, &sCtx, (void*)&sParse.pNewTable->iPKey); + } + sqlite3WalkExprList(&sWalker, sParse.pNewTable->pCheck); + for(pIdx=sParse.pNewTable->pIndex; pIdx; pIdx=pIdx->pNext){ + sqlite3WalkExprList(&sWalker, pIdx->aColExpr); + } + } + + for(pFKey=sParse.pNewTable->pFKey; pFKey; pFKey=pFKey->pNextFrom){ + for(i=0; inCol; i++){ + if( bFKOnly==0 && pFKey->aCol[i].iFrom==iCol ){ + renameTokenFind(&sParse, &sCtx, (void*)&pFKey->aCol[i]); + } + if( 0==sqlite3_stricmp(pFKey->zTo, zTable) + && 0==sqlite3_stricmp(pFKey->aCol[i].zCol, zOld) + ){ + renameTokenFind(&sParse, &sCtx, (void*)pFKey->aCol[i].zCol); + } + } + } + } + }else if( sParse.pNewIndex ){ + sqlite3WalkExprList(&sWalker, sParse.pNewIndex->aColExpr); + sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere); + }else{ + /* A trigger */ + TriggerStep *pStep; + rc = renameResolveTrigger(&sParse, (bTemp ? 0 : zDb)); + if( rc!=SQLITE_OK ) goto renameColumnFunc_done; + + for(pStep=sParse.pNewTrigger->step_list; pStep; pStep=pStep->pNext){ + if( pStep->zTarget ){ + Table *pTarget = sqlite3LocateTable(&sParse, 0, pStep->zTarget, zDb); + if( pTarget==pTab ){ + if( pStep->pUpsert ){ + ExprList *pUpsertSet = pStep->pUpsert->pUpsertSet; + renameColumnElistNames(&sParse, &sCtx, pUpsertSet, zOld); + } + renameColumnIdlistNames(&sParse, &sCtx, pStep->pIdList, zOld); + renameColumnElistNames(&sParse, &sCtx, pStep->pExprList, zOld); + } + } + } + + + /* Find tokens to edit in UPDATE OF clause */ + if( sParse.pTriggerTab==pTab ){ + renameColumnIdlistNames(&sParse, &sCtx,sParse.pNewTrigger->pColumns,zOld); + } + + /* Find tokens to edit in various expressions and selects */ + renameWalkTrigger(&sWalker, sParse.pNewTrigger); + } + + assert( rc==SQLITE_OK ); + rc = renameEditSql(context, &sCtx, zSql, zNew, bQuote); + +renameColumnFunc_done: + if( rc!=SQLITE_OK ){ + if( sParse.zErrMsg ){ + renameColumnParseError(context, 0, argv[1], argv[2], &sParse); + }else{ + sqlite3_result_error_code(context, rc); + } + } + + renameParseCleanup(&sParse); + renameTokenFree(db, sCtx.pList); +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; +#endif + sqlite3BtreeLeaveAll(db); +} + +/* +** Walker expression callback used by "RENAME TABLE". +*/ +static int renameTableExprCb(Walker *pWalker, Expr *pExpr){ + RenameCtx *p = pWalker->u.pRename; + if( pExpr->op==TK_COLUMN && p->pTab==pExpr->pTab ){ + renameTokenFind(pWalker->pParse, p, (void*)&pExpr->pTab); + } + return WRC_Continue; +} + +/* +** Walker select callback used by "RENAME TABLE". +*/ +static int renameTableSelectCb(Walker *pWalker, Select *pSelect){ + int i; + RenameCtx *p = pWalker->u.pRename; + SrcList *pSrc = pSelect->pSrc; + for(i=0; inSrc; i++){ + struct SrcList_item *pItem = &pSrc->a[i]; + if( pItem->pTab==p->pTab ){ + renameTokenFind(pWalker->pParse, p, pItem->zName); + } + } + + return WRC_Continue; +} + + +/* +** This C function implements an SQL user function that is used by SQL code +** generated by the ALTER TABLE ... RENAME command to modify the definition +** of any foreign key constraints that use the table being renamed as the +** parent table. It is passed three arguments: +** +** 0: The database containing the table being renamed. +** 1. type: Type of object ("table", "view" etc.) +** 2. object: Name of object +** 3: The complete text of the schema statement being modified, +** 4: The old name of the table being renamed, and +** 5: The new name of the table being renamed. +** 6: True if the schema statement comes from the temp db. +** +** It returns the new schema statement. For example: +** +** sqlite_rename_table('main', 'CREATE TABLE t1(a REFERENCES t2)','t2','t3',0) +** -> 'CREATE TABLE t1(a REFERENCES t3)' +*/ +static void renameTableFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + const char *zDb = (const char*)sqlite3_value_text(argv[0]); + const char *zInput = (const char*)sqlite3_value_text(argv[3]); + const char *zOld = (const char*)sqlite3_value_text(argv[4]); + const char *zNew = (const char*)sqlite3_value_text(argv[5]); + int bTemp = sqlite3_value_int(argv[6]); + UNUSED_PARAMETER(NotUsed); + + if( zInput && zOld && zNew ){ + Parse sParse; + int rc; + int bQuote = 1; + RenameCtx sCtx; + Walker sWalker; + +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth = db->xAuth; + db->xAuth = 0; +#endif + + sqlite3BtreeEnterAll(db); + + memset(&sCtx, 0, sizeof(RenameCtx)); + sCtx.pTab = sqlite3FindTable(db, zOld, zDb); + memset(&sWalker, 0, sizeof(Walker)); + sWalker.pParse = &sParse; + sWalker.xExprCallback = renameTableExprCb; + sWalker.xSelectCallback = renameTableSelectCb; + sWalker.u.pRename = &sCtx; + + rc = renameParseSql(&sParse, zDb, 1, db, zInput, bTemp); + + if( rc==SQLITE_OK ){ + int isLegacy = (db->flags & SQLITE_LegacyAlter); + if( sParse.pNewTable ){ + Table *pTab = sParse.pNewTable; + + if( pTab->pSelect ){ + if( isLegacy==0 ){ + NameContext sNC; + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = &sParse; + + sqlite3SelectPrep(&sParse, pTab->pSelect, &sNC); + if( sParse.nErr ) rc = sParse.rc; + sqlite3WalkSelect(&sWalker, pTab->pSelect); + } + }else{ + /* Modify any FK definitions to point to the new table. */ +#ifndef SQLITE_OMIT_FOREIGN_KEY + if( db->flags & SQLITE_ForeignKeys ){ + FKey *pFKey; + for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){ + if( sqlite3_stricmp(pFKey->zTo, zOld)==0 ){ + renameTokenFind(&sParse, &sCtx, (void*)pFKey->zTo); + } + } + } +#endif + + /* If this is the table being altered, fix any table refs in CHECK + ** expressions. Also update the name that appears right after the + ** "CREATE [VIRTUAL] TABLE" bit. */ + if( sqlite3_stricmp(zOld, pTab->zName)==0 ){ + sCtx.pTab = pTab; + if( isLegacy==0 ){ + sqlite3WalkExprList(&sWalker, pTab->pCheck); + } + renameTokenFind(&sParse, &sCtx, pTab->zName); + } + } + } + + else if( sParse.pNewIndex ){ + renameTokenFind(&sParse, &sCtx, sParse.pNewIndex->zName); + if( isLegacy==0 ){ + sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere); + } + } + +#ifndef SQLITE_OMIT_TRIGGER + else{ + Trigger *pTrigger = sParse.pNewTrigger; + TriggerStep *pStep; + if( 0==sqlite3_stricmp(sParse.pNewTrigger->table, zOld) + && sCtx.pTab->pSchema==pTrigger->pTabSchema + ){ + renameTokenFind(&sParse, &sCtx, sParse.pNewTrigger->table); + } + + if( isLegacy==0 ){ + rc = renameResolveTrigger(&sParse, bTemp ? 0 : zDb); + if( rc==SQLITE_OK ){ + renameWalkTrigger(&sWalker, pTrigger); + for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){ + if( pStep->zTarget && 0==sqlite3_stricmp(pStep->zTarget, zOld) ){ + renameTokenFind(&sParse, &sCtx, pStep->zTarget); + } + } + } + } + } +#endif + } + + if( rc==SQLITE_OK ){ + rc = renameEditSql(context, &sCtx, zInput, zNew, bQuote); + } + if( rc!=SQLITE_OK ){ + if( sParse.zErrMsg ){ + renameColumnParseError(context, 0, argv[1], argv[2], &sParse); + }else{ + sqlite3_result_error_code(context, rc); + } + } + + renameParseCleanup(&sParse); + renameTokenFree(db, sCtx.pList); + sqlite3BtreeLeaveAll(db); +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; +#endif + } + + return; +} + +/* +** An SQL user function that checks that there are no parse or symbol +** resolution problems in a CREATE TRIGGER|TABLE|VIEW|INDEX statement. +** After an ALTER TABLE .. RENAME operation is performed and the schema +** reloaded, this function is called on each SQL statement in the schema +** to ensure that it is still usable. +** +** 0: Database name ("main", "temp" etc.). +** 1: SQL statement. +** 2: Object type ("view", "table", "trigger" or "index"). +** 3: Object name. +** 4: True if object is from temp schema. +** +** Unless it finds an error, this function normally returns NULL. However, it +** returns integer value 1 if: +** +** * the SQL argument creates a trigger, and +** * the table that the trigger is attached to is in database zDb. +*/ +static void renameTableTest( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + char const *zDb = (const char*)sqlite3_value_text(argv[0]); + char const *zInput = (const char*)sqlite3_value_text(argv[1]); + int bTemp = sqlite3_value_int(argv[4]); + int isLegacy = (db->flags & SQLITE_LegacyAlter); + +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth = db->xAuth; + db->xAuth = 0; +#endif + + UNUSED_PARAMETER(NotUsed); + if( zDb && zInput ){ + int rc; + Parse sParse; + rc = renameParseSql(&sParse, zDb, 1, db, zInput, bTemp); + if( rc==SQLITE_OK ){ + if( isLegacy==0 && sParse.pNewTable && sParse.pNewTable->pSelect ){ + NameContext sNC; + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = &sParse; + sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, &sNC); + if( sParse.nErr ) rc = sParse.rc; + } + + else if( sParse.pNewTrigger ){ + if( isLegacy==0 ){ + rc = renameResolveTrigger(&sParse, bTemp ? 0 : zDb); + } + if( rc==SQLITE_OK ){ + int i1 = sqlite3SchemaToIndex(db, sParse.pNewTrigger->pTabSchema); + int i2 = sqlite3FindDbName(db, zDb); + if( i1==i2 ) sqlite3_result_int(context, 1); + } + } + } + + if( rc!=SQLITE_OK ){ + renameColumnParseError(context, 1, argv[2], argv[3], &sParse); + } + renameParseCleanup(&sParse); + } + +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; +#endif +} + +/* +** Register built-in functions used to help implement ALTER TABLE +*/ +SQLITE_PRIVATE void sqlite3AlterFunctions(void){ + static FuncDef aAlterTableFuncs[] = { + FUNCTION(sqlite_rename_column, 9, 0, 0, renameColumnFunc), + FUNCTION(sqlite_rename_table, 7, 0, 0, renameTableFunc), + FUNCTION(sqlite_rename_test, 5, 0, 0, renameTableTest), + }; + sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs)); +} #endif /* SQLITE_ALTER_TABLE */ /************** End of alter.c ***********************************************/ @@ -101566,6 +103225,7 @@ static const FuncDef statInitFuncdef = { 0, /* pNext */ statInit, /* xSFunc */ 0, /* xFinalize */ + 0, 0, /* xValue, xInverse */ "stat_init", /* zName */ {0} }; @@ -101882,6 +103542,7 @@ static const FuncDef statPushFuncdef = { 0, /* pNext */ statPush, /* xSFunc */ 0, /* xFinalize */ + 0, 0, /* xValue, xInverse */ "stat_push", /* zName */ {0} }; @@ -102033,6 +103694,7 @@ static const FuncDef statGetFuncdef = { 0, /* pNext */ statGet, /* xSFunc */ 0, /* xFinalize */ + 0, 0, /* xValue, xInverse */ "stat_get", /* zName */ {0} }; @@ -102352,10 +104014,7 @@ static void analyzeOneTable( callStatGet(v, regStat4, STAT_GET_NLT, regLt); callStatGet(v, regStat4, STAT_GET_NDLT, regDLt); sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0); - /* We know that the regSampleRowid row exists because it was read by - ** the previous loop. Thus the not-found jump of seekOp will never - ** be taken */ - VdbeCoverageNeverTaken(v); + VdbeCoverage(v); #ifdef SQLITE_ENABLE_STAT3 sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, 0, regSample); #else @@ -102995,7 +104654,7 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ /* Load the statistics from the sqlite_stat4 table. */ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 - if( rc==SQLITE_OK && OptimizationEnabled(db, SQLITE_Stat34) ){ + if( rc==SQLITE_OK ){ db->lookaside.bDisable++; rc = loadStat4(db, sInfo.zDatabase); db->lookaside.bDisable--; @@ -103434,6 +105093,7 @@ SQLITE_PRIVATE void sqlite3Detach(Parse *pParse, Expr *pDbname){ 0, /* pNext */ detachFunc, /* xSFunc */ 0, /* xFinalize */ + 0, 0, /* xValue, xInverse */ "sqlite_detach", /* zName */ {0} }; @@ -103453,6 +105113,7 @@ SQLITE_PRIVATE void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *p 0, /* pNext */ attachFunc, /* xSFunc */ 0, /* xFinalize */ + 0, 0, /* xValue, xInverse */ "sqlite_attach", /* zName */ {0} }; @@ -103725,7 +105386,7 @@ SQLITE_API int sqlite3_set_authorizer( sqlite3_mutex_enter(db->mutex); db->xAuth = (sqlite3_xauth)xAuth; db->pAuthArg = pArg; - sqlite3ExpirePreparedStatements(db); + sqlite3ExpirePreparedStatements(db, 0); sqlite3_mutex_leave(db->mutex); return SQLITE_OK; } @@ -103854,7 +105515,7 @@ SQLITE_PRIVATE int sqlite3AuthCheck( /* Don't do any authorization checks if the database is initialising ** or if the parser is being invoked from within sqlite3_declare_vtab. */ - if( db->init.busy || IN_DECLARE_VTAB ){ + if( db->init.busy || IN_SPECIAL_PARSE ){ return SQLITE_OK; } @@ -104146,7 +105807,6 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ /* Get the VDBE program ready for execution */ if( v && pParse->nErr==0 && !db->mallocFailed ){ - assert( pParse->iCacheLevel==0 ); /* Disables and re-enables match */ /* A minimum of one cursor is required if autoincrement is used * See ticket [a696379c1f08866] */ if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1; @@ -104361,7 +106021,7 @@ SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const cha /* ** Reclaim the memory used by an index */ -static void freeIndex(sqlite3 *db, Index *p){ +SQLITE_PRIVATE void sqlite3FreeIndex(sqlite3 *db, Index *p){ #ifndef SQLITE_OMIT_ANALYZE sqlite3DeleteIndexSamples(db, p); #endif @@ -104401,7 +106061,7 @@ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char p->pNext = pIndex->pNext; } } - freeIndex(db, pIndex); + sqlite3FreeIndex(db, pIndex); } db->mDbFlags |= DBFLAG_SchemaChange; } @@ -104547,7 +106207,7 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){ assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); assert( pOld==pIndex || pOld==0 ); } - freeIndex(db, pIndex); + sqlite3FreeIndex(db, pIndex); } /* Delete any foreign keys attached to this table. */ @@ -104705,7 +106365,7 @@ SQLITE_PRIVATE int sqlite3TwoPartName( return -1; } }else{ - assert( db->init.iDb==0 || db->init.busy + assert( db->init.iDb==0 || db->init.busy || IN_RENAME_OBJECT || (db->mDbFlags & DBFLAG_Vacuum)!=0); iDb = db->init.iDb; *pUnqual = pName1; @@ -104800,6 +106460,9 @@ SQLITE_PRIVATE void sqlite3StartTable( } if( !OMIT_TEMPDB && isTemp ) iDb = 1; zName = sqlite3NameFromToken(db, pName); + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenMap(pParse, (void*)zName, pName); + } } pParse->sNameToken = *pName; if( zName==0 ) return; @@ -104835,7 +106498,7 @@ SQLITE_PRIVATE void sqlite3StartTable( ** and types will be used, so there is no need to test for namespace ** collisions. */ - if( !IN_DECLARE_VTAB ){ + if( !IN_SPECIAL_PARSE ){ char *zDb = db->aDb[iDb].zDbSName; if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto begin_table_error; @@ -104994,6 +106657,7 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ } z = sqlite3DbMallocRaw(db, pName->n + pType->n + 2); if( z==0 ) return; + if( IN_RENAME_OBJECT ) sqlite3RenameTokenMap(pParse, (void*)z, pName); memcpy(z, pName->z, pName->n); z[pName->n] = 0; sqlite3Dequote(z); @@ -105200,6 +106864,9 @@ SQLITE_PRIVATE void sqlite3AddDefaultValue( sqlite3DbFree(db, x.u.zToken); } } + if( IN_RENAME_OBJECT ){ + sqlite3RenameExprUnmap(pParse, pExpr); + } sqlite3ExprDelete(db, pExpr); } @@ -105291,6 +106958,9 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey( && sqlite3StrICmp(sqlite3ColumnType(pCol,""), "INTEGER")==0 && sortOrder!=SQLITE_SO_DESC ){ + if( IN_RENAME_OBJECT && pList ){ + sqlite3RenameTokenRemap(pParse, &pTab->iPKey, pList->a[0].pExpr); + } pTab->iPKey = iCol; pTab->keyConf = (u8)onError; assert( autoInc==0 || autoInc==1 ); @@ -105616,6 +107286,31 @@ static int hasColumn(const i16 *aiCol, int nCol, int x){ return 0; } +/* Recompute the colNotIdxed field of the Index. +** +** colNotIdxed is a bitmask that has a 0 bit representing each indexed +** columns that are within the first 63 columns of the table. The +** high-order bit of colNotIdxed is always 1. All unindexed columns +** of the table have a 1. +** +** The colNotIdxed mask is AND-ed with the SrcList.a[].colUsed mask +** to determine if the index is covering index. +*/ +static void recomputeColumnsNotIndexed(Index *pIdx){ + Bitmask m = 0; + int j; + for(j=pIdx->nColumn-1; j>=0; j--){ + int x = pIdx->aiColumn[j]; + if( x>=0 ){ + testcase( x==BMS-1 ); + testcase( x==BMS-2 ); + if( xcolNotIdxed = ~m; + assert( (pIdx->colNotIdxed>>63)==1 ); +} + /* ** This routine runs at the end of parsing a CREATE TABLE statement that ** has a WITHOUT ROWID clause. The job of this routine is to convert both @@ -105658,10 +107353,6 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ } } - /* The remaining transformations only apply to b-tree tables, not to - ** virtual tables */ - if( IN_DECLARE_VTAB ) return; - /* Convert the P3 operand of the OP_CreateBtree opcode from BTREE_INTKEY ** into BTREE_BLOBKEY. */ @@ -105684,7 +107375,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ assert( pParse->pNewTable==pTab ); sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0, SQLITE_IDXTYPE_PRIMARYKEY); - if( db->mallocFailed ) return; + if( db->mallocFailed || pParse->nErr ) return; pPk = sqlite3PrimaryKeyIndex(pTab); pTab->iPKey = -1; }else{ @@ -105764,6 +107455,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ }else{ pPk->nColumn = pTab->nCol; } + recomputeColumnsNotIndexed(pPk); } /* @@ -106067,7 +107759,12 @@ SQLITE_PRIVATE void sqlite3CreateView( ** allocated rather than point to the input string - which means that ** they will persist after the current sqlite3_exec() call returns. */ - p->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); + if( IN_RENAME_OBJECT ){ + p->pSelect = pSelect; + pSelect = 0; + }else{ + p->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); + } p->pCheck = sqlite3ExprListDup(db, pCNames, EXPRDUP_REDUCE); if( db->mallocFailed ) goto create_view_fail; @@ -106092,6 +107789,9 @@ SQLITE_PRIVATE void sqlite3CreateView( create_view_fail: sqlite3SelectDelete(db, pSelect); + if( IN_RENAME_OBJECT ){ + sqlite3RenameExprlistUnmap(pParse, pCNames); + } sqlite3ExprListDelete(db, pCNames); return; } @@ -106165,6 +107865,10 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ assert( pTable->pSelect ); pSel = sqlite3SelectDup(db, pTable->pSelect, 0); if( pSel ){ +#ifndef SQLITE_OMIT_ALTERTABLE + u8 eParseMode = pParse->eParseMode; + pParse->eParseMode = PARSE_MODE_NORMAL; +#endif n = pParse->nTab; sqlite3SrcListAssignCursors(pParse, pSel->pSrc); pTable->nCol = -1; @@ -106210,10 +107914,18 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ sqlite3DeleteTable(db, pSelTab); sqlite3SelectDelete(db, pSel); db->lookaside.bDisable--; +#ifndef SQLITE_OMIT_ALTERTABLE + pParse->eParseMode = eParseMode; +#endif } else { nErr++; } pTable->pSchema->schemaFlags |= DB_UnresetViews; + if( db->mallocFailed ){ + sqlite3DeleteColumnNames(db, pTable); + pTable->aCol = 0; + pTable->nCol = 0; + } #endif /* SQLITE_OMIT_VIEW */ return nErr; } @@ -106552,8 +108264,10 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, v = sqlite3GetVdbe(pParse); if( v ){ sqlite3BeginWriteOperation(pParse, 1, iDb); - sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName); - sqlite3FkDropTable(pParse, pName, pTab); + if( !isView ){ + sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName); + sqlite3FkDropTable(pParse, pName, pTab); + } sqlite3CodeDropTable(pParse, pTab, iDb, isView); } @@ -106628,6 +108342,9 @@ SQLITE_PRIVATE void sqlite3CreateForeignKey( pFKey->pNextFrom = p->pFKey; z = (char*)&pFKey->aCol[nCol]; pFKey->zTo = z; + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenMap(pParse, (void*)z, pTo); + } memcpy(z, pTo->z, pTo->n); z[pTo->n] = 0; sqlite3Dequote(z); @@ -106650,12 +108367,18 @@ SQLITE_PRIVATE void sqlite3CreateForeignKey( pFromCol->a[i].zName); goto fk_end; } + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, &pFKey->aCol[i], pFromCol->a[i].zName); + } } } if( pToCol ){ for(i=0; ia[i].zName); pFKey->aCol[i].zCol = z; + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, z, pToCol->a[i].zName); + } memcpy(z, pToCol->a[i].zName, n); z[n] = 0; z += n+1; @@ -106988,21 +108711,23 @@ SQLITE_PRIVATE void sqlite3CreateIndex( if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto exit_create_index; } - if( !db->init.busy ){ - if( sqlite3FindTable(db, zName, 0)!=0 ){ - sqlite3ErrorMsg(pParse, "there is already a table named %s", zName); + if( !IN_RENAME_OBJECT ){ + if( !db->init.busy ){ + if( sqlite3FindTable(db, zName, 0)!=0 ){ + sqlite3ErrorMsg(pParse, "there is already a table named %s", zName); + goto exit_create_index; + } + } + if( sqlite3FindIndex(db, zName, pDb->zDbSName)!=0 ){ + if( !ifNotExist ){ + sqlite3ErrorMsg(pParse, "index %s already exists", zName); + }else{ + assert( !db->init.busy ); + sqlite3CodeVerifySchema(pParse, iDb); + } goto exit_create_index; } } - if( sqlite3FindIndex(db, zName, pDb->zDbSName)!=0 ){ - if( !ifNotExist ){ - sqlite3ErrorMsg(pParse, "index %s already exists", zName); - }else{ - assert( !db->init.busy ); - sqlite3CodeVerifySchema(pParse, iDb); - } - goto exit_create_index; - } }else{ int n; Index *pLoop; @@ -107017,13 +108742,13 @@ SQLITE_PRIVATE void sqlite3CreateIndex( ** The following statement converts "sqlite3_autoindex..." into ** "sqlite3_butoindex..." in order to make the names distinct. ** The "vtab_err.test" test demonstrates the need of this statement. */ - if( IN_DECLARE_VTAB ) zName[7]++; + if( IN_SPECIAL_PARSE ) zName[7]++; } /* Check for authorization to create an index. */ #ifndef SQLITE_OMIT_AUTHORIZATION - { + if( !IN_RENAME_OBJECT ){ const char *zDb = pDb->zDbSName; if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){ goto exit_create_index; @@ -107110,7 +108835,12 @@ SQLITE_PRIVATE void sqlite3CreateIndex( ** TODO: Issue a warning if the table primary key is used as part of the ** index key. */ - for(i=0, pListItem=pList->a; inExpr; i++, pListItem++){ + pListItem = pList->a; + if( IN_RENAME_OBJECT ){ + pIndex->aColExpr = pList; + pList = 0; + } + for(i=0; inKeyCol; i++, pListItem++){ Expr *pCExpr; /* The i-th index expression */ int requestedSortOrder; /* ASC or DESC on the i-th expression */ const char *zColl; /* Collation sequence name */ @@ -107126,12 +108856,8 @@ SQLITE_PRIVATE void sqlite3CreateIndex( goto exit_create_index; } if( pIndex->aColExpr==0 ){ - ExprList *pCopy = sqlite3ExprListDup(db, pList, 0); - pIndex->aColExpr = pCopy; - if( !db->mallocFailed ){ - assert( pCopy!=0 ); - pListItem = &pCopy->a[i]; - } + pIndex->aColExpr = pList; + pList = 0; } j = XN_EXPR; pIndex->aiColumn[i] = XN_EXPR; @@ -107197,6 +108923,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex( ** it as a covering index */ assert( HasRowid(pTab) || pTab->iPKey<0 || sqlite3ColumnOfIndex(pIndex, pTab->iPKey)>=0 ); + recomputeColumnsNotIndexed(pIndex); if( pTblName!=0 && pIndex->nColumn>=pTab->nCol ){ pIndex->isCovering = 1; for(j=0; jnCol; j++){ @@ -107269,98 +108996,101 @@ SQLITE_PRIVATE void sqlite3CreateIndex( } } - /* Link the new Index structure to its table and to the other - ** in-memory database structures. - */ - assert( pParse->nErr==0 ); - if( db->init.busy ){ - Index *p; - assert( !IN_DECLARE_VTAB ); - assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); - p = sqlite3HashInsert(&pIndex->pSchema->idxHash, - pIndex->zName, pIndex); - if( p ){ - assert( p==pIndex ); /* Malloc must have failed */ - sqlite3OomFault(db); - goto exit_create_index; - } - db->mDbFlags |= DBFLAG_SchemaChange; - if( pTblName!=0 ){ - pIndex->tnum = db->init.newTnum; - } - } + if( !IN_RENAME_OBJECT ){ - /* If this is the initial CREATE INDEX statement (or CREATE TABLE if the - ** index is an implied index for a UNIQUE or PRIMARY KEY constraint) then - ** emit code to allocate the index rootpage on disk and make an entry for - ** the index in the sqlite_master table and populate the index with - ** content. But, do not do this if we are simply reading the sqlite_master - ** table to parse the schema, or if this index is the PRIMARY KEY index - ** of a WITHOUT ROWID table. - ** - ** If pTblName==0 it means this index is generated as an implied PRIMARY KEY - ** or UNIQUE index in a CREATE TABLE statement. Since the table - ** has just been created, it contains no data and the index initialization - ** step can be skipped. - */ - else if( HasRowid(pTab) || pTblName!=0 ){ - Vdbe *v; - char *zStmt; - int iMem = ++pParse->nMem; - - v = sqlite3GetVdbe(pParse); - if( v==0 ) goto exit_create_index; - - sqlite3BeginWriteOperation(pParse, 1, iDb); - - /* Create the rootpage for the index using CreateIndex. But before - ** doing so, code a Noop instruction and store its address in - ** Index.tnum. This is required in case this index is actually a - ** PRIMARY KEY and the table is actually a WITHOUT ROWID table. In - ** that case the convertToWithoutRowidTable() routine will replace - ** the Noop with a Goto to jump over the VDBE code generated below. */ - pIndex->tnum = sqlite3VdbeAddOp0(v, OP_Noop); - sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, iMem, BTREE_BLOBKEY); - - /* Gather the complete text of the CREATE INDEX statement into - ** the zStmt variable + /* Link the new Index structure to its table and to the other + ** in-memory database structures. */ - if( pStart ){ - int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n; - if( pName->z[n-1]==';' ) n--; - /* A named index with an explicit CREATE INDEX statement */ - zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s", - onError==OE_None ? "" : " UNIQUE", n, pName->z); - }else{ - /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */ - /* zStmt = sqlite3MPrintf(""); */ - zStmt = 0; + assert( pParse->nErr==0 ); + if( db->init.busy ){ + Index *p; + assert( !IN_SPECIAL_PARSE ); + assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); + p = sqlite3HashInsert(&pIndex->pSchema->idxHash, + pIndex->zName, pIndex); + if( p ){ + assert( p==pIndex ); /* Malloc must have failed */ + sqlite3OomFault(db); + goto exit_create_index; + } + db->mDbFlags |= DBFLAG_SchemaChange; + if( pTblName!=0 ){ + pIndex->tnum = db->init.newTnum; + } } - /* Add an entry in sqlite_master for this index + /* If this is the initial CREATE INDEX statement (or CREATE TABLE if the + ** index is an implied index for a UNIQUE or PRIMARY KEY constraint) then + ** emit code to allocate the index rootpage on disk and make an entry for + ** the index in the sqlite_master table and populate the index with + ** content. But, do not do this if we are simply reading the sqlite_master + ** table to parse the schema, or if this index is the PRIMARY KEY index + ** of a WITHOUT ROWID table. + ** + ** If pTblName==0 it means this index is generated as an implied PRIMARY KEY + ** or UNIQUE index in a CREATE TABLE statement. Since the table + ** has just been created, it contains no data and the index initialization + ** step can be skipped. */ - sqlite3NestedParse(pParse, - "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);", - db->aDb[iDb].zDbSName, MASTER_NAME, - pIndex->zName, - pTab->zName, - iMem, - zStmt - ); - sqlite3DbFree(db, zStmt); + else if( HasRowid(pTab) || pTblName!=0 ){ + Vdbe *v; + char *zStmt; + int iMem = ++pParse->nMem; - /* Fill the index with data and reparse the schema. Code an OP_Expire - ** to invalidate all pre-compiled statements. - */ - if( pTblName ){ - sqlite3RefillIndex(pParse, pIndex, iMem); - sqlite3ChangeCookie(pParse, iDb); - sqlite3VdbeAddParseSchemaOp(v, iDb, - sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName)); - sqlite3VdbeAddOp0(v, OP_Expire); + v = sqlite3GetVdbe(pParse); + if( v==0 ) goto exit_create_index; + + sqlite3BeginWriteOperation(pParse, 1, iDb); + + /* Create the rootpage for the index using CreateIndex. But before + ** doing so, code a Noop instruction and store its address in + ** Index.tnum. This is required in case this index is actually a + ** PRIMARY KEY and the table is actually a WITHOUT ROWID table. In + ** that case the convertToWithoutRowidTable() routine will replace + ** the Noop with a Goto to jump over the VDBE code generated below. */ + pIndex->tnum = sqlite3VdbeAddOp0(v, OP_Noop); + sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, iMem, BTREE_BLOBKEY); + + /* Gather the complete text of the CREATE INDEX statement into + ** the zStmt variable + */ + if( pStart ){ + int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n; + if( pName->z[n-1]==';' ) n--; + /* A named index with an explicit CREATE INDEX statement */ + zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s", + onError==OE_None ? "" : " UNIQUE", n, pName->z); + }else{ + /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */ + /* zStmt = sqlite3MPrintf(""); */ + zStmt = 0; + } + + /* Add an entry in sqlite_master for this index + */ + sqlite3NestedParse(pParse, + "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);", + db->aDb[iDb].zDbSName, MASTER_NAME, + pIndex->zName, + pTab->zName, + iMem, + zStmt + ); + sqlite3DbFree(db, zStmt); + + /* Fill the index with data and reparse the schema. Code an OP_Expire + ** to invalidate all pre-compiled statements. + */ + if( pTblName ){ + sqlite3RefillIndex(pParse, pIndex, iMem); + sqlite3ChangeCookie(pParse, iDb); + sqlite3VdbeAddParseSchemaOp(v, iDb, + sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName)); + sqlite3VdbeAddOp2(v, OP_Expire, 0, 1); + } + + sqlite3VdbeJumpHere(v, pIndex->tnum); } - - sqlite3VdbeJumpHere(v, pIndex->tnum); } /* When adding an index to the list of indices for a table, make @@ -107384,10 +109114,15 @@ SQLITE_PRIVATE void sqlite3CreateIndex( } pIndex = 0; } + else if( IN_RENAME_OBJECT ){ + assert( pParse->pNewIndex==0 ); + pParse->pNewIndex = pIndex; + pIndex = 0; + } /* Clean up before exiting */ exit_create_index: - if( pIndex ) freeIndex(db, pIndex); + if( pIndex ) sqlite3FreeIndex(db, pIndex); sqlite3ExprDelete(db, pPIWhere); sqlite3ExprListDelete(db, pList); sqlite3SrcListDelete(db, pTblName); @@ -107556,7 +109291,8 @@ SQLITE_PRIVATE void *sqlite3ArrayAllocate( ** ** A new IdList is returned, or NULL if malloc() fails. */ -SQLITE_PRIVATE IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pToken){ +SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse *pParse, IdList *pList, Token *pToken){ + sqlite3 *db = pParse->db; int i; if( pList==0 ){ pList = sqlite3DbMallocZero(db, sizeof(IdList) ); @@ -107574,6 +109310,9 @@ SQLITE_PRIVATE IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pT return 0; } pList->a[i].zName = sqlite3NameFromToken(db, pToken); + if( IN_RENAME_OBJECT && pList->a[i].zName ){ + sqlite3RenameTokenMap(pParse, (void*)pList->a[i].zName, pToken); + } return pList; } @@ -107820,6 +109559,12 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm( } assert( p->nSrc>0 ); pItem = &p->a[p->nSrc-1]; + assert( (pTable==0)==(pDatabase==0) ); + assert( pItem->zName==0 || pDatabase!=0 ); + if( IN_RENAME_OBJECT && pItem->zName ){ + Token *pToken = (ALWAYS(pDatabase) && pDatabase->z) ? pDatabase : pTable; + sqlite3RenameTokenMap(pParse, pItem->zName, pToken); + } assert( pAlias!=0 ); if( pAlias->n ){ pItem->zAlias = sqlite3NameFromToken(db, pAlias); @@ -109373,9 +111118,8 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( } iKey = iPk; }else{ - iKey = pParse->nMem + 1; - iKey = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iTabCur, iKey, 0); - if( iKey>pParse->nMem ) pParse->nMem = iKey; + iKey = ++pParse->nMem; + sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, -1, iKey); } if( eOnePass!=ONEPASS_OFF ){ @@ -109808,7 +111552,6 @@ SQLITE_PRIVATE int sqlite3GenerateIndexKey( if( pIdx->pPartIdxWhere ){ *piPartIdxLabel = sqlite3VdbeMakeLabel(v); pParse->iSelfTab = iDataCur + 1; - sqlite3ExprCachePush(pParse); sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, SQLITE_JUMPIFNULL); pParse->iSelfTab = 0; @@ -109855,7 +111598,6 @@ SQLITE_PRIVATE int sqlite3GenerateIndexKey( SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){ if( iLabel ){ sqlite3VdbeResolveLabel(pParse->pVdbe, iLabel); - sqlite3ExprCachePop(pParse); } } @@ -111368,7 +113110,7 @@ static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){ i64 v = sqlite3_value_int64(argv[0]); p->rSum += v; if( (p->approx|p->overflow)==0 && sqlite3AddInt64(&p->iSum, v) ){ - p->overflow = 1; + p->approx = p->overflow = 1; } }else{ p->rSum += sqlite3_value_double(argv[0]); @@ -111376,6 +113118,32 @@ static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){ } } } +#ifndef SQLITE_OMIT_WINDOWFUNC +static void sumInverse(sqlite3_context *context, int argc, sqlite3_value**argv){ + SumCtx *p; + int type; + assert( argc==1 ); + UNUSED_PARAMETER(argc); + p = sqlite3_aggregate_context(context, sizeof(*p)); + type = sqlite3_value_numeric_type(argv[0]); + /* p is always non-NULL because sumStep() will have been called first + ** to initialize it */ + if( ALWAYS(p) && type!=SQLITE_NULL ){ + assert( p->cnt>0 ); + p->cnt--; + assert( type==SQLITE_INTEGER || p->approx ); + if( type==SQLITE_INTEGER && p->approx==0 ){ + i64 v = sqlite3_value_int64(argv[0]); + p->rSum -= v; + p->iSum -= v; + }else{ + p->rSum -= sqlite3_value_double(argv[0]); + } + } +} +#else +# define sumInverse 0 +#endif /* SQLITE_OMIT_WINDOWFUNC */ static void sumFinalize(sqlite3_context *context){ SumCtx *p; p = sqlite3_aggregate_context(context, 0); @@ -111410,6 +113178,9 @@ static void totalFinalize(sqlite3_context *context){ typedef struct CountCtx CountCtx; struct CountCtx { i64 n; +#ifdef SQLITE_DEBUG + int bInverse; /* True if xInverse() ever called */ +#endif }; /* @@ -111427,7 +113198,7 @@ static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){ ** sure it still operates correctly, verify that its count agrees with our ** internal count when using count(*) and when the total count can be ** expressed as a 32-bit integer. */ - assert( argc==1 || p==0 || p->n>0x7fffffff + assert( argc==1 || p==0 || p->n>0x7fffffff || p->bInverse || p->n==sqlite3_aggregate_count(context) ); #endif } @@ -111436,6 +113207,21 @@ static void countFinalize(sqlite3_context *context){ p = sqlite3_aggregate_context(context, 0); sqlite3_result_int64(context, p ? p->n : 0); } +#ifndef SQLITE_OMIT_WINDOWFUNC +static void countInverse(sqlite3_context *ctx, int argc, sqlite3_value **argv){ + CountCtx *p; + p = sqlite3_aggregate_context(ctx, sizeof(*p)); + /* p is always non-NULL since countStep() will have been called first */ + if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && ALWAYS(p) ){ + p->n--; +#ifdef SQLITE_DEBUG + p->bInverse = 1; +#endif + } +} +#else +# define countInverse 0 +#endif /* SQLITE_OMIT_WINDOWFUNC */ /* ** Routines to implement min() and max() aggregate functions. @@ -111452,7 +113238,7 @@ static void minmaxStep( pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest)); if( !pBest ) return; - if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ + if( sqlite3_value_type(pArg)==SQLITE_NULL ){ if( pBest->flags ) sqlite3SkipAccumulatorLoad(context); }else if( pBest->flags ){ int max; @@ -111478,16 +113264,26 @@ static void minmaxStep( sqlite3VdbeMemCopy(pBest, pArg); } } -static void minMaxFinalize(sqlite3_context *context){ +static void minMaxValueFinalize(sqlite3_context *context, int bValue){ sqlite3_value *pRes; pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0); if( pRes ){ if( pRes->flags ){ sqlite3_result_value(context, pRes); } - sqlite3VdbeMemRelease(pRes); + if( bValue==0 ) sqlite3VdbeMemRelease(pRes); } } +#ifndef SQLITE_OMIT_WINDOWFUNC +static void minMaxValue(sqlite3_context *context){ + minMaxValueFinalize(context, 1); +} +#else +# define minMaxValue 0 +#endif /* SQLITE_OMIT_WINDOWFUNC */ +static void minMaxFinalize(sqlite3_context *context){ + minMaxValueFinalize(context, 0); +} /* ** group_concat(EXPR, ?SEPARATOR?) @@ -111524,6 +113320,38 @@ static void groupConcatStep( if( zVal ) sqlite3_str_append(pAccum, zVal, nVal); } } +#ifndef SQLITE_OMIT_WINDOWFUNC +static void groupConcatInverse( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int n; + StrAccum *pAccum; + assert( argc==1 || argc==2 ); + if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; + pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum)); + /* pAccum is always non-NULL since groupConcatStep() will have always + ** run frist to initialize it */ + if( ALWAYS(pAccum) ){ + n = sqlite3_value_bytes(argv[0]); + if( argc==2 ){ + n += sqlite3_value_bytes(argv[1]); + }else{ + n++; + } + if( n>=(int)pAccum->nChar ){ + pAccum->nChar = 0; + }else{ + pAccum->nChar -= n; + memmove(pAccum->zText, &pAccum->zText[n], pAccum->nChar); + } + if( pAccum->nChar==0 ) pAccum->mxAlloc = 0; + } +} +#else +# define groupConcatInverse 0 +#endif /* SQLITE_OMIT_WINDOWFUNC */ static void groupConcatFinalize(sqlite3_context *context){ StrAccum *pAccum; pAccum = sqlite3_aggregate_context(context, 0); @@ -111538,6 +113366,24 @@ static void groupConcatFinalize(sqlite3_context *context){ } } } +#ifndef SQLITE_OMIT_WINDOWFUNC +static void groupConcatValue(sqlite3_context *context){ + sqlite3_str *pAccum; + pAccum = (sqlite3_str*)sqlite3_aggregate_context(context, 0); + if( pAccum ){ + if( pAccum->accError==SQLITE_TOOBIG ){ + sqlite3_result_error_toobig(context); + }else if( pAccum->accError==SQLITE_NOMEM ){ + sqlite3_result_error_nomem(context); + }else{ + const char *zText = sqlite3_str_value(pAccum); + sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT); + } + } +} +#else +# define groupConcatValue 0 +#endif /* SQLITE_OMIT_WINDOWFUNC */ /* ** This routine does per-connection function registration. Most @@ -111575,10 +113421,10 @@ SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive) }else{ pInfo = (struct compareInfo*)&likeInfoNorm; } - sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0); - sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0); + sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0); + sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0); sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8, - (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0); + (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0, 0, 0); setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE); setLikeOptFlag(db, "like", caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE); @@ -111687,11 +113533,11 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ FUNCTION(trim, 2, 3, 0, trimFunc ), FUNCTION(min, -1, 0, 1, minmaxFunc ), FUNCTION(min, 0, 0, 1, 0 ), - AGGREGATE2(min, 1, 0, 1, minmaxStep, minMaxFinalize, + WAGGREGATE(min, 1, 0, 1, minmaxStep, minMaxFinalize, minMaxValue, 0, SQLITE_FUNC_MINMAX ), FUNCTION(max, -1, 1, 1, minmaxFunc ), FUNCTION(max, 0, 1, 1, 0 ), - AGGREGATE2(max, 1, 1, 1, minmaxStep, minMaxFinalize, + WAGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize, minMaxValue, 0, SQLITE_FUNC_MINMAX ), FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF), FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH), @@ -111722,14 +113568,17 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ), FUNCTION(substr, 2, 0, 0, substrFunc ), FUNCTION(substr, 3, 0, 0, substrFunc ), - AGGREGATE(sum, 1, 0, 0, sumStep, sumFinalize ), - AGGREGATE(total, 1, 0, 0, sumStep, totalFinalize ), - AGGREGATE(avg, 1, 0, 0, sumStep, avgFinalize ), - AGGREGATE2(count, 0, 0, 0, countStep, countFinalize, - SQLITE_FUNC_COUNT ), - AGGREGATE(count, 1, 0, 0, countStep, countFinalize ), - AGGREGATE(group_concat, 1, 0, 0, groupConcatStep, groupConcatFinalize), - AGGREGATE(group_concat, 2, 0, 0, groupConcatStep, groupConcatFinalize), + WAGGREGATE(sum, 1,0,0, sumStep, sumFinalize, sumFinalize, sumInverse, 0), + WAGGREGATE(total, 1,0,0, sumStep,totalFinalize,totalFinalize,sumInverse, 0), + WAGGREGATE(avg, 1,0,0, sumStep, avgFinalize, avgFinalize, sumInverse, 0), + WAGGREGATE(count, 0,0,0, countStep, + countFinalize, countFinalize, countInverse, SQLITE_FUNC_COUNT ), + WAGGREGATE(count, 1,0,0, countStep, + countFinalize, countFinalize, countInverse, 0 ), + WAGGREGATE(group_concat, 1, 0, 0, groupConcatStep, + groupConcatFinalize, groupConcatValue, groupConcatInverse, 0), + WAGGREGATE(group_concat, 2, 0, 0, groupConcatStep, + groupConcatFinalize, groupConcatValue, groupConcatInverse, 0), LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), #ifdef SQLITE_CASE_SENSITIVE_LIKE @@ -111749,6 +113598,7 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ #ifndef SQLITE_OMIT_ALTERTABLE sqlite3AlterFunctions(); #endif + sqlite3WindowFunctions(); #if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4) sqlite3AnalyzeFunctions(); #endif @@ -112486,11 +114336,12 @@ static void fkTriggerDelete(sqlite3 *dbMem, Trigger *p){ */ SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){ sqlite3 *db = pParse->db; - if( (db->flags&SQLITE_ForeignKeys) && !IsVirtual(pTab) && !pTab->pSelect ){ + if( (db->flags&SQLITE_ForeignKeys) && !IsVirtual(pTab) ){ int iSkip = 0; Vdbe *v = sqlite3GetVdbe(pParse); assert( v ); /* VDBE has already been allocated */ + assert( pTab->pSelect==0 ); /* Not a view */ if( sqlite3FkReferences(pTab)==0 ){ /* Search for a deferred foreign key constraint for which this table ** is the child table. If one cannot be found, return without @@ -114385,44 +116236,6 @@ static int checkConstraintUnchanged(Expr *pExpr, int *aiChng, int chngRowid){ return !w.eCode; } -/* -** An instance of the ConstraintAddr object remembers the byte-code addresses -** for sections of the constraint checks that deal with uniqueness constraints -** on the rowid and on the upsert constraint. -** -** This information is passed into checkReorderConstraintChecks() to insert -** some OP_Goto operations so that the rowid and upsert constraints occur -** in the correct order relative to other constraints. -*/ -typedef struct ConstraintAddr ConstraintAddr; -struct ConstraintAddr { - int ipkTop; /* Subroutine for rowid constraint check */ - int upsertTop; /* Label for upsert constraint check subroutine */ - int upsertTop2; /* Copy of upsertTop not cleared by the call */ - int upsertBtm; /* upsert constraint returns to this label */ - int ipkBtm; /* Return opcode rowid constraint check */ -}; - -/* -** Generate any OP_Goto operations needed to cause constraints to be -** run that haven't already been run. -*/ -static void reorderConstraintChecks(Vdbe *v, ConstraintAddr *p){ - if( p->upsertTop ){ - testcase( sqlite3VdbeLabelHasBeenResolved(v, p->upsertTop) ); - sqlite3VdbeGoto(v, p->upsertTop); - VdbeComment((v, "call upsert subroutine")); - sqlite3VdbeResolveLabel(v, p->upsertBtm); - p->upsertTop = 0; - } - if( p->ipkTop ){ - sqlite3VdbeGoto(v, p->ipkTop); - VdbeComment((v, "call rowid unique-check subroutine")); - sqlite3VdbeJumpHere(v, p->ipkBtm); - p->ipkTop = 0; - } -} - /* ** Generate code to do constraint checks prior to an INSERT or an UPDATE ** on table pTab. @@ -114532,11 +116345,13 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( int addr1; /* Address of jump instruction */ int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */ int nPkField; /* Number of fields in PRIMARY KEY. 1 for ROWID tables */ - ConstraintAddr sAddr;/* Address information for constraint reordering */ Index *pUpIdx = 0; /* Index to which to apply the upsert */ u8 isUpdate; /* True if this is an UPDATE operation */ u8 bAffinityDone = 0; /* True if the OP_Affinity operation has been run */ int upsertBypass = 0; /* Address of Goto to bypass upsert subroutine */ + int upsertJump = 0; /* Address of Goto that jumps into upsert subroutine */ + int ipkTop = 0; /* Top of the IPK uniqueness check */ + int ipkBottom = 0; /* OP_Goto at the end of the IPK uniqueness check */ isUpdate = regOldData!=0; db = pParse->db; @@ -114544,7 +116359,6 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( assert( v!=0 ); assert( pTab->pSelect==0 ); /* This table is not a VIEW */ nCol = pTab->nCol; - memset(&sAddr, 0, sizeof(sAddr)); /* pPk is the PRIMARY KEY index for WITHOUT ROWID tables and NULL for ** normal rowid tables. nPkField is the number of key fields in the @@ -114648,8 +116462,8 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( /* UNIQUE and PRIMARY KEY constraints should be handled in the following ** order: ** - ** (1) OE_Abort, OE_Fail, OE_Rollback, OE_Ignore - ** (2) OE_Update + ** (1) OE_Update + ** (2) OE_Abort, OE_Fail, OE_Rollback, OE_Ignore ** (3) OE_Replace ** ** OE_Fail and OE_Ignore must happen before any changes are made. @@ -114658,6 +116472,11 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( ** could happen in any order, but they are grouped up front for ** convenience. ** + ** 2018-08-14: Ticket https://www.sqlite.org/src/info/908f001483982c43 + ** The order of constraints used to have OE_Update as (2) and OE_Abort + ** and so forth as (1). But apparently PostgreSQL checks the OE_Update + ** constraint before any others, so it had to be moved. + ** ** Constraint checking code is generated in this order: ** (A) The rowid constraint ** (B) Unique index constraints that do not have OE_Replace as their @@ -114677,11 +116496,10 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( overrideError = OE_Ignore; pUpsert = 0; }else if( (pUpIdx = pUpsert->pUpsertIdx)!=0 ){ - /* If the constraint-target is on some column other than - ** then ROWID, then we might need to move the UPSERT around - ** so that it occurs in the correct order. */ - sAddr.upsertTop = sAddr.upsertTop2 = sqlite3VdbeMakeLabel(v); - sAddr.upsertBtm = sqlite3VdbeMakeLabel(v); + /* If the constraint-target uniqueness check must be run first. + ** Jump to that uniqueness check now */ + upsertJump = sqlite3VdbeAddOp0(v, OP_Goto); + VdbeComment((v, "UPSERT constraint goes first")); } } @@ -114713,16 +116531,12 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( ** to defer the running of the rowid conflict checking until after ** the UNIQUE constraints have run. */ - assert( OE_Update>OE_Replace ); - assert( OE_Ignore=OE_Replace - && (pUpsert || onError!=overrideError) - && pTab->pIndex + if( onError==OE_Replace /* IPK rule is REPLACE */ + && onError!=overrideError /* Rules for other contraints are different */ + && pTab->pIndex /* There exist other constraints */ ){ - sAddr.ipkTop = sqlite3VdbeAddOp0(v, OP_Goto)+1; + ipkTop = sqlite3VdbeAddOp0(v, OP_Goto)+1; + VdbeComment((v, "defer IPK REPLACE until last")); } if( isUpdate ){ @@ -114817,9 +116631,9 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( } } sqlite3VdbeResolveLabel(v, addrRowidOk); - if( sAddr.ipkTop ){ - sAddr.ipkBtm = sqlite3VdbeAddOp0(v, OP_Goto); - sqlite3VdbeJumpHere(v, sAddr.ipkTop-1); + if( ipkTop ){ + ipkBottom = sqlite3VdbeAddOp0(v, OP_Goto); + sqlite3VdbeJumpHere(v, ipkTop-1); } } @@ -114838,18 +116652,18 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( if( aRegIdx[ix]==0 ) continue; /* Skip indices that do not change */ if( pUpIdx==pIdx ){ - addrUniqueOk = sAddr.upsertBtm; + addrUniqueOk = upsertJump+1; upsertBypass = sqlite3VdbeGoto(v, 0); VdbeComment((v, "Skip upsert subroutine")); - sqlite3VdbeResolveLabel(v, sAddr.upsertTop2); + sqlite3VdbeJumpHere(v, upsertJump); }else{ addrUniqueOk = sqlite3VdbeMakeLabel(v); } - VdbeNoopComment((v, "uniqueness check for %s", pIdx->zName)); - if( bAffinityDone==0 ){ + if( bAffinityDone==0 && (pUpIdx==0 || pUpIdx==pIdx) ){ sqlite3TableAffinity(v, pTab, regNewData+1); bAffinityDone = 1; } + VdbeNoopComment((v, "uniqueness check for %s", pIdx->zName)); iThisCur = iIdxCur+ix; @@ -114920,15 +116734,6 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( } } - /* Invoke subroutines to handle IPK replace and upsert prior to running - ** the first REPLACE constraint check. */ - if( onError==OE_Replace ){ - testcase( sAddr.ipkTop ); - testcase( sAddr.upsertTop - && sqlite3VdbeLabelHasBeenResolved(v,sAddr.upsertTop) ); - reorderConstraintChecks(v, &sAddr); - } - /* Collision detection may be omitted if all of the following are true: ** (1) The conflict resolution algorithm is REPLACE ** (2) The table is a WITHOUT ROWID table @@ -114949,7 +116754,6 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( } /* Check to see if the new index entry will be unique */ - sqlite3ExprCachePush(pParse); sqlite3VdbeVerifyAbortable(v, onError); sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk, regIdx, pIdx->nKeyCol); VdbeCoverage(v); @@ -115051,19 +116855,21 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( } } if( pUpIdx==pIdx ){ + sqlite3VdbeGoto(v, upsertJump+1); sqlite3VdbeJumpHere(v, upsertBypass); }else{ sqlite3VdbeResolveLabel(v, addrUniqueOk); } - sqlite3ExprCachePop(pParse); if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField); - } - testcase( sAddr.ipkTop!=0 ); - testcase( sAddr.upsertTop - && sqlite3VdbeLabelHasBeenResolved(v,sAddr.upsertTop) ); - reorderConstraintChecks(v, &sAddr); - + + /* If the IPK constraint is a REPLACE, run it last */ + if( ipkTop ){ + sqlite3VdbeGoto(v, ipkTop+1); + VdbeComment((v, "Do IPK REPLACE")); + sqlite3VdbeJumpHere(v, ipkBottom); + } + *pbMayReplace = seenReplace; VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace)); } @@ -115159,7 +116965,6 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion( sqlite3SetMakeRecordP5(v, pTab); if( !bAffinityDone ){ sqlite3TableAffinity(v, pTab, 0); - sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol); } if( pParse->nested ){ pik_flags = 0; @@ -116135,6 +117940,12 @@ struct sqlite3_api_routines { int (*str_errcode)(sqlite3_str*); int (*str_length)(sqlite3_str*); char *(*str_value)(sqlite3_str*); + int (*create_window_function)(sqlite3*,const char*,int,int,void*, + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void (*xValue)(sqlite3_context*), + void (*xInv)(sqlite3_context*,int,sqlite3_value**), + void(*xDestroy)(void*)); }; /* @@ -116420,6 +118231,8 @@ typedef int (*sqlite3_loadext_entry)( #define sqlite3_str_errcode sqlite3_api->str_errcode #define sqlite3_str_length sqlite3_api->str_length #define sqlite3_str_value sqlite3_api->str_value +/* Version 3.25.0 and later */ +#define sqlite3_create_window_function sqlite3_api->create_window_function #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) @@ -116873,7 +118686,9 @@ static const sqlite3_api_routines sqlite3Apis = { sqlite3_str_reset, sqlite3_str_errcode, sqlite3_str_length, - sqlite3_str_value + sqlite3_str_value, + /* Version 3.25.0 and later */ + sqlite3_create_window_function }; /* @@ -117668,6 +119483,11 @@ static const PragmaName aPragmaName[] = { /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) + {/* zName: */ "legacy_alter_table", + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, + /* ColNames: */ 0, 0, + /* iArg: */ SQLITE_LegacyAlter }, {/* zName: */ "legacy_file_format", /* ePragTyp: */ PragTyp_FLAG, /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, @@ -117921,7 +119741,7 @@ static const PragmaName aPragmaName[] = { /* iArg: */ SQLITE_WriteSchema }, #endif }; -/* Number of pragmas: 60 on by default, 77 total. */ +/* Number of pragmas: 61 on by default, 78 total. */ /************** End of pragma.h **********************************************/ /************** Continuing where we left off in pragma.c *********************/ @@ -119446,7 +121266,6 @@ SQLITE_PRIVATE void sqlite3Pragma( if( pTab->tnum<1 ) continue; /* Skip VIEWs or VIRTUAL TABLEs */ pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); - sqlite3ExprCacheClear(pParse); sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0, 1, 0, &iDataCur, &iIdxCur); /* reg[7] counts the number of entries in the table. @@ -119460,6 +121279,11 @@ SQLITE_PRIVATE void sqlite3Pragma( assert( sqlite3NoTempsInRange(pParse,1,7+j) ); sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v); loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1); + if( !isQuick ){ + /* Sanity check on record header decoding */ + sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nCol-1, 3); + sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); + } /* Verify that all NOT NULL columns really are NOT NULL */ for(j=0; jnCol; j++){ char *zErr; @@ -119484,7 +121308,6 @@ SQLITE_PRIVATE void sqlite3Pragma( char *zErr; int k; pParse->iSelfTab = iDataCur + 1; - sqlite3ExprCachePush(pParse); for(k=pCheck->nExpr-1; k>0; k--){ sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0); } @@ -119497,14 +121320,10 @@ SQLITE_PRIVATE void sqlite3Pragma( sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); integrityCheckResultRow(v); sqlite3VdbeResolveLabel(v, addrCkOk); - sqlite3ExprCachePop(pParse); } sqlite3ExprListDelete(db, pCheck); } if( !isQuick ){ /* Omit the remaining tests for quick_check */ - /* Sanity check on record header decoding */ - sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nCol-1, 3); - sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); /* Validate index entries for the current row */ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ int jmp2, jmp3, jmp4, jmp5; @@ -120119,7 +121938,6 @@ static int pragmaVtabConnect( } if( i==0 ){ sqlite3_str_appendf(&acc, "(\"%s\"", pPragma->zName); - cSep = ','; i++; } j = 0; @@ -120412,15 +122230,23 @@ static void corruptSchema( const char *zExtra /* Error information */ ){ sqlite3 *db = pData->db; - if( !db->mallocFailed && (db->flags & SQLITE_WriteSchema)==0 ){ + if( db->mallocFailed ){ + pData->rc = SQLITE_NOMEM_BKPT; + }else if( pData->pzErrMsg[0]!=0 ){ + /* A error message has already been generated. Do not overwrite it */ + }else if( pData->mInitFlags & INITFLAG_AlterTable ){ + *pData->pzErrMsg = sqlite3DbStrDup(db, zExtra); + pData->rc = SQLITE_ERROR; + }else if( db->flags & SQLITE_WriteSchema ){ + pData->rc = SQLITE_CORRUPT_BKPT; + }else{ char *z; if( zObj==0 ) zObj = "?"; z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj); if( zExtra && zExtra[0] ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra); - sqlite3DbFree(db, *pData->pzErrMsg); *pData->pzErrMsg = z; + pData->rc = SQLITE_CORRUPT_BKPT; } - pData->rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_CORRUPT_BKPT; } /* @@ -120472,7 +122298,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char rc = db->errCode; assert( (rc&0xFF)==(rcp&0xFF) ); db->init.iDb = saved_iDb; - assert( saved_iDb==0 || (db->mDbFlags & DBFLAG_Vacuum)!=0 ); + /* assert( saved_iDb==0 || (db->mDbFlags & DBFLAG_Vacuum)!=0 ); */ if( SQLITE_OK!=rc ){ if( db->init.orphanTrigger ){ assert( iDb==1 ); @@ -120519,7 +122345,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char ** auxiliary databases. Return one of the SQLITE_ error codes to ** indicate success or failure. */ -static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ +SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){ int rc; int i; #ifndef SQLITE_OMIT_DEPRECATED @@ -120554,6 +122380,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ initData.iDb = iDb; initData.rc = SQLITE_OK; initData.pzErrMsg = pzErrMsg; + initData.mInitFlags = mFlags; sqlite3InitCallback(&initData, 3, (char **)azArg, 0); if( initData.rc ){ rc = initData.rc; @@ -120575,7 +122402,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ ** will be closed before this function returns. */ sqlite3BtreeEnter(pDb->pBt); if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){ - rc = sqlite3BtreeBeginTrans(pDb->pBt, 0); + rc = sqlite3BtreeBeginTrans(pDb->pBt, 0, 0); if( rc!=SQLITE_OK ){ sqlite3SetString(pzErrMsg, db, sqlite3ErrStr(rc)); goto initone_error_out; @@ -120760,14 +122587,14 @@ SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){ assert( db->nDb>0 ); /* Do the main schema first */ if( !DbHasProperty(db, 0, DB_SchemaLoaded) ){ - rc = sqlite3InitOne(db, 0, pzErrMsg); + rc = sqlite3InitOne(db, 0, pzErrMsg, 0); if( rc ) return rc; } /* All other schemas after the main schema. The "temp" schema must be last */ for(i=db->nDb-1; i>0; i--){ assert( i==1 || sqlite3BtreeHoldsMutex(db->aDb[i].pBt) ); if( !DbHasProperty(db, i, DB_SchemaLoaded) ){ - rc = sqlite3InitOne(db, i, pzErrMsg); + rc = sqlite3InitOne(db, i, pzErrMsg, 0); if( rc ) return rc; } } @@ -120820,7 +122647,7 @@ static void schemaIsValid(Parse *pParse){ ** on the b-tree database, open one now. If a transaction is opened, it ** will be closed immediately after reading the meta-value. */ if( !sqlite3BtreeIsInReadTrans(pBt) ){ - rc = sqlite3BtreeBeginTrans(pBt, 0); + rc = sqlite3BtreeBeginTrans(pBt, 0, 0); if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ sqlite3OomFault(db); } @@ -121317,7 +123144,7 @@ SQLITE_API int sqlite3_prepare16_v3( /***/ int sqlite3SelectTrace = 0; # define SELECTTRACE(K,P,S,X) \ if(sqlite3SelectTrace&(K)) \ - sqlite3DebugPrintf("%s/%d/%p: ",(S)->zSelName,(P)->addrExplain,(S)),\ + sqlite3DebugPrintf("%u/%d/%p: ",(S)->selId,(P)->addrExplain,(S)),\ sqlite3DebugPrintf X #else # define SELECTTRACE(K,P,S,X) @@ -121364,8 +123191,8 @@ struct SortCtx { int labelBkOut; /* Start label for the block-output subroutine */ int addrSortIndex; /* Address of the OP_SorterOpen or OP_OpenEphemeral */ int labelDone; /* Jump here when done, ex: LIMIT reached */ + int labelOBLopt; /* Jump here when sorter is full */ u8 sortFlags; /* Zero or more SORTFLAG_* bits */ - u8 bOrderedInnerLoop; /* ORDER BY correctly sorts the inner loop */ #ifdef SQLITE_ENABLE_SORTER_REFERENCES u8 nDefer; /* Number of valid entries in aDefer[] */ struct DeferredCsr { @@ -121392,6 +123219,11 @@ static void clearSelect(sqlite3 *db, Select *p, int bFree){ sqlite3ExprDelete(db, p->pHaving); sqlite3ExprListDelete(db, p->pOrderBy); sqlite3ExprDelete(db, p->pLimit); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( OK_IF_ALWAYS_TRUE(p->pWinDefn) ){ + sqlite3WindowListDelete(db, p->pWinDefn); + } +#endif if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith); if( bFree ) sqlite3DbFreeNN(db, p); p = pPrior; @@ -121442,9 +123274,7 @@ SQLITE_PRIVATE Select *sqlite3SelectNew( pNew->selFlags = selFlags; pNew->iLimit = 0; pNew->iOffset = 0; -#if SELECTTRACE_ENABLED - pNew->zSelName[0] = 0; -#endif + pNew->selId = ++pParse->nSelect; pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; pNew->nSelectRow = 0; @@ -121458,6 +123288,10 @@ SQLITE_PRIVATE Select *sqlite3SelectNew( pNew->pNext = 0; pNew->pLimit = pLimit; pNew->pWith = 0; +#ifndef SQLITE_OMIT_WINDOWFUNC + pNew->pWin = 0; + pNew->pWinDefn = 0; +#endif if( pParse->db->mallocFailed ) { clearSelect(pParse->db, pNew, pNew!=&standin); pNew = 0; @@ -121468,17 +123302,6 @@ SQLITE_PRIVATE Select *sqlite3SelectNew( return pNew; } -#if SELECTTRACE_ENABLED -/* -** Set the name of a Select object -*/ -SQLITE_PRIVATE void sqlite3SelectSetName(Select *p, const char *zName){ - if( p && zName ){ - sqlite3_snprintf(sizeof(p->zSelName), p->zSelName, "%s", zName); - } -} -#endif - /* ** Delete the given Select structure and all of its substructures. @@ -121825,14 +123648,6 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ return 0; } -/* Forward reference */ -static KeyInfo *keyInfoFromExprList( - Parse *pParse, /* Parsing context */ - ExprList *pList, /* Form the KeyInfo object from this ExprList */ - int iStart, /* Begin with this column of pList */ - int nExtra /* Add this many extra columns to the end */ -); - /* ** An instance of this object holds information (beyond pParse and pSelect) ** needed to load the next result row that is to be added to the sorter. @@ -121974,7 +123789,7 @@ static void pushOntoSorter( memset(pKI->aSortOrder, 0, pKI->nKeyField); /* Makes OP_Jump testable */ sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO); testcase( pKI->nAllField > pKI->nKeyField+2 ); - pOp->p4.pKeyInfo = keyInfoFromExprList(pParse, pSort->pOrderBy, nOBSat, + pOp->p4.pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pSort->pOrderBy,nOBSat, pKI->nAllField-pKI->nKeyField-1); addrJmp = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v); @@ -122001,10 +123816,10 @@ static void pushOntoSorter( ** than LIMIT+OFFSET items in the sorter. ** ** If the new record does not need to be inserted into the sorter, - ** jump to the next iteration of the loop. Or, if the - ** pSort->bOrderedInnerLoop flag is set to indicate that the inner - ** loop delivers items in sorted order, jump to the next iteration - ** of the outer loop. + ** jump to the next iteration of the loop. If the pSort->labelOBLopt + ** value is not zero, then it is a label of where to jump. Otherwise, + ** just bypass the row insert logic. See the header comment on the + ** sqlite3WhereOrderByLimitOptLabel() function for additional info. */ int iCsr = pSort->iECursor; sqlite3VdbeAddOp2(v, OP_IfNotZero, iLimit, sqlite3VdbeCurrentAddr(v)+4); @@ -122026,9 +123841,8 @@ static void pushOntoSorter( sqlite3VdbeAddOp4Int(v, op, pSort->iECursor, regRecord, regBase+nOBSat, nBase-nOBSat); if( iSkip ){ - assert( pSort->bOrderedInnerLoop==0 || pSort->bOrderedInnerLoop==1 ); sqlite3VdbeChangeP2(v, iSkip, - sqlite3VdbeCurrentAddr(v) + pSort->bOrderedInnerLoop); + pSort->labelOBLopt ? pSort->labelOBLopt : sqlite3VdbeCurrentAddr(v)); } } @@ -122457,7 +124271,6 @@ static void selectInnerLoop( assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol ); sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol, r1, pDest->zAffSdst, nResultCol); - sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol); sqlite3ReleaseTempReg(pParse, r1); } @@ -122501,7 +124314,6 @@ static void selectInnerLoop( sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); }else{ sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nResultCol); - sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol); } break; } @@ -122644,7 +124456,7 @@ SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo *p){ return p->nRef==1; } ** function is responsible for seeing that this structure is eventually ** freed. */ -static KeyInfo *keyInfoFromExprList( +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoFromExprList( Parse *pParse, /* Parsing context */ ExprList *pList, /* Form the KeyInfo object from this ExprList */ int iStart, /* Begin with this column of pList */ @@ -122858,7 +124670,6 @@ static void generateSortTail( assert( nColumn==sqlite3Strlen30(pDest->zAffSdst) ); sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, nColumn, regRowid, pDest->zAffSdst, nColumn); - sqlite3ExprCacheAffinityChange(pParse, regRow, nColumn); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, regRowid, regRow, nColumn); break; } @@ -122873,7 +124684,6 @@ static void generateSortTail( testcase( eDest==SRT_Coroutine ); if( eDest==SRT_Output ){ sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iSdst, nColumn); - sqlite3ExprCacheAffinityChange(pParse, pDest->iSdst, nColumn); }else{ sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); } @@ -123474,7 +125284,6 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ ** The current implementation interprets "LIMIT 0" to mean ** no rows. */ - sqlite3ExprCacheClear(pParse); if( pLimit ){ assert( pLimit->op==TK_LIMIT ); assert( pLimit->pLeft!=0 ); @@ -124260,7 +126069,6 @@ static int generateOutputSubroutine( r1 = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1, pDest->zAffSdst, pIn->nSdst); - sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1, pIn->iSdst, pIn->nSdst); sqlite3ReleaseTempReg(pParse, r1); @@ -124303,7 +126111,6 @@ static int generateOutputSubroutine( default: { assert( pDest->eDest==SRT_Output ); sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iSdst, pIn->nSdst); - sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst); break; } } @@ -124758,7 +126565,7 @@ static Expr *substExpr( Expr *pCopy = pSubst->pEList->a[pExpr->iColumn].pExpr; Expr ifNullRow; assert( pSubst->pEList!=0 && pExpr->iColumnpEList->nExpr ); - assert( pExpr->pLeft==0 && pExpr->pRight==0 ); + assert( pExpr->pRight==0 ); if( sqlite3ExprIsVector(pCopy) ){ sqlite3VectorErrorMsg(pSubst->pParse, pCopy); }else{ @@ -124972,6 +126779,10 @@ static void substSelect( ** "SELECT x FROM (SELECT max(y), x FROM t1)" would not necessarily ** return the value X for which Y was maximal.) ** +** (25) If either the subquery or the parent query contains a window +** function in the select list or ORDER BY clause, flattening +** is not attempted. +** ** ** In this routine, the "p" parameter is a pointer to the outer query. ** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query @@ -125015,6 +126826,10 @@ static int flattenSubquery( pSub = pSubitem->pSelect; assert( pSub!=0 ); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( p->pWin || pSub->pWin ) return 0; /* Restriction (25) */ +#endif + pSubSrc = pSub->pSrc; assert( pSubSrc ); /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants, @@ -125125,8 +126940,8 @@ static int flattenSubquery( assert( (p->selFlags & SF_Recursive)==0 || pSub->pPrior==0 ); /***** If we reach this point, flattening is permitted. *****/ - SELECTTRACE(1,pParse,p,("flatten %s.%p from term %d\n", - pSub->zSelName, pSub, iFrom)); + SELECTTRACE(1,pParse,p,("flatten %u.%p from term %d\n", + pSub->selId, pSub, iFrom)); /* Authorize the subquery */ pParse->zAuthContext = pSubitem->zName; @@ -125177,7 +126992,6 @@ static int flattenSubquery( p->pPrior = 0; p->pLimit = 0; pNew = sqlite3SelectDup(db, p, 0); - sqlite3SelectSetName(pNew, pSub->zSelName); p->pLimit = pLimit; p->pOrderBy = pOrderBy; p->pSrc = pSrc; @@ -125190,7 +127004,7 @@ static int flattenSubquery( pNew->pNext = p; p->pPrior = pNew; SELECTTRACE(2,pParse,p,("compound-subquery flattener" - " creates %s.%p as peer\n",pNew->zSelName, pNew)); + " creates %u as peer\n",pNew->selId)); } if( db->mallocFailed ) return 1; } @@ -125375,7 +127189,168 @@ static int flattenSubquery( } #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ +/* +** A structure to keep track of all of the column values that fixed to +** a known value due to WHERE clause constraints of the form COLUMN=VALUE. +*/ +typedef struct WhereConst WhereConst; +struct WhereConst { + Parse *pParse; /* Parsing context */ + int nConst; /* Number for COLUMN=CONSTANT terms */ + int nChng; /* Number of times a constant is propagated */ + Expr **apExpr; /* [i*2] is COLUMN and [i*2+1] is VALUE */ +}; +/* +** Add a new entry to the pConst object +*/ +static void constInsert( + WhereConst *pConst, + Expr *pColumn, + Expr *pValue +){ + + pConst->nConst++; + pConst->apExpr = sqlite3DbReallocOrFree(pConst->pParse->db, pConst->apExpr, + pConst->nConst*2*sizeof(Expr*)); + if( pConst->apExpr==0 ){ + pConst->nConst = 0; + }else{ + if( ExprHasProperty(pValue, EP_FixedCol) ) pValue = pValue->pLeft; + pConst->apExpr[pConst->nConst*2-2] = pColumn; + pConst->apExpr[pConst->nConst*2-1] = pValue; + } +} + +/* +** Find all terms of COLUMN=VALUE or VALUE=COLUMN in pExpr where VALUE +** is a constant expression and where the term must be true because it +** is part of the AND-connected terms of the expression. For each term +** found, add it to the pConst structure. +*/ +static void findConstInWhere(WhereConst *pConst, Expr *pExpr){ + Expr *pRight, *pLeft; + if( pExpr==0 ) return; + if( ExprHasProperty(pExpr, EP_FromJoin) ) return; + if( pExpr->op==TK_AND ){ + findConstInWhere(pConst, pExpr->pRight); + findConstInWhere(pConst, pExpr->pLeft); + return; + } + if( pExpr->op!=TK_EQ ) return; + pRight = pExpr->pRight; + pLeft = pExpr->pLeft; + assert( pRight!=0 ); + assert( pLeft!=0 ); + if( pRight->op==TK_COLUMN + && !ExprHasProperty(pRight, EP_FixedCol) + && sqlite3ExprIsConstant(pLeft) + && sqlite3IsBinary(sqlite3BinaryCompareCollSeq(pConst->pParse,pLeft,pRight)) + ){ + constInsert(pConst, pRight, pLeft); + }else + if( pLeft->op==TK_COLUMN + && !ExprHasProperty(pLeft, EP_FixedCol) + && sqlite3ExprIsConstant(pRight) + && sqlite3IsBinary(sqlite3BinaryCompareCollSeq(pConst->pParse,pLeft,pRight)) + ){ + constInsert(pConst, pLeft, pRight); + } +} + +/* +** This is a Walker expression callback. pExpr is a candidate expression +** to be replaced by a value. If pExpr is equivalent to one of the +** columns named in pWalker->u.pConst, then overwrite it with its +** corresponding value. +*/ +static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){ + int i; + WhereConst *pConst; + if( pExpr->op!=TK_COLUMN ) return WRC_Continue; + if( ExprHasProperty(pExpr, EP_FixedCol) ) return WRC_Continue; + pConst = pWalker->u.pConst; + for(i=0; inConst; i++){ + Expr *pColumn = pConst->apExpr[i*2]; + if( pColumn==pExpr ) continue; + if( pColumn->iTable!=pExpr->iTable ) continue; + if( pColumn->iColumn!=pExpr->iColumn ) continue; + /* A match is found. Add the EP_FixedCol property */ + pConst->nChng++; + ExprClearProperty(pExpr, EP_Leaf); + ExprSetProperty(pExpr, EP_FixedCol); + assert( pExpr->pLeft==0 ); + pExpr->pLeft = sqlite3ExprDup(pConst->pParse->db, pConst->apExpr[i*2+1], 0); + break; + } + return WRC_Prune; +} + +/* +** The WHERE-clause constant propagation optimization. +** +** If the WHERE clause contains terms of the form COLUMN=CONSTANT or +** CONSTANT=COLUMN that must be tree (in other words, if the terms top-level +** AND-connected terms that are not part of a ON clause from a LEFT JOIN) +** then throughout the query replace all other occurrences of COLUMN +** with CONSTANT within the WHERE clause. +** +** For example, the query: +** +** SELECT * FROM t1, t2, t3 WHERE t1.a=39 AND t2.b=t1.a AND t3.c=t2.b +** +** Is transformed into +** +** SELECT * FROM t1, t2, t3 WHERE t1.a=39 AND t2.b=39 AND t3.c=39 +** +** Return true if any transformations where made and false if not. +** +** Implementation note: Constant propagation is tricky due to affinity +** and collating sequence interactions. Consider this example: +** +** CREATE TABLE t1(a INT,b TEXT); +** INSERT INTO t1 VALUES(123,'0123'); +** SELECT * FROM t1 WHERE a=123 AND b=a; +** SELECT * FROM t1 WHERE a=123 AND b=123; +** +** The two SELECT statements above should return different answers. b=a +** is alway true because the comparison uses numeric affinity, but b=123 +** is false because it uses text affinity and '0123' is not the same as '123'. +** To work around this, the expression tree is not actually changed from +** "b=a" to "b=123" but rather the "a" in "b=a" is tagged with EP_FixedCol +** and the "123" value is hung off of the pLeft pointer. Code generator +** routines know to generate the constant "123" instead of looking up the +** column value. Also, to avoid collation problems, this optimization is +** only attempted if the "a=123" term uses the default BINARY collation. +*/ +static int propagateConstants( + Parse *pParse, /* The parsing context */ + Select *p /* The query in which to propagate constants */ +){ + WhereConst x; + Walker w; + int nChng = 0; + x.pParse = pParse; + do{ + x.nConst = 0; + x.nChng = 0; + x.apExpr = 0; + findConstInWhere(&x, p->pWhere); + if( x.nConst ){ + memset(&w, 0, sizeof(w)); + w.pParse = pParse; + w.xExprCallback = propagateConstantExprRewrite; + w.xSelectCallback = sqlite3SelectWalkNoop; + w.xSelectCallback2 = 0; + w.walkerDepth = 0; + w.u.pConst = &x; + sqlite3WalkExpr(&w, p->pWhere); + sqlite3DbFree(x.pParse->db, x.apExpr); + nChng += x.nChng; + } + }while( x.nChng ); + return nChng; +} #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) /* @@ -125405,7 +127380,7 @@ static int flattenSubquery( ** (2) The inner query is the recursive part of a common table expression. ** ** (3) The inner query has a LIMIT clause (since the changes to the WHERE -** close would change the meaning of the LIMIT). +** clause would change the meaning of the LIMIT). ** ** (4) The inner query is the right operand of a LEFT JOIN and the ** expression to be pushed down does not come from the ON clause @@ -125424,6 +127399,10 @@ static int flattenSubquery( ** But if the (b2=2) term were to be pushed down into the bb subquery, ** then the (1,1,NULL) row would be suppressed. ** +** (6) The inner query features one or more window-functions (since +** changes to the WHERE clause of the inner query could change the +** window over which window functions are calculated). +** ** Return 0 if no changes are made and non-zero if one or more WHERE clause ** terms are duplicated into the subquery. */ @@ -125439,6 +127418,10 @@ static int pushDownWhereTerms( if( pWhere==0 ) return 0; if( pSubq->selFlags & SF_Recursive ) return 0; /* restriction (2) */ +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pSubq->pWin ) return 0; /* restriction (6) */ +#endif + #ifdef SQLITE_DEBUG /* Only the first term of a compound can have a WITH clause. But make ** sure no other terms are marked SF_Recursive in case something changes @@ -125884,6 +127867,35 @@ static void selectPopWith(Walker *pWalker, Select *p){ #define selectPopWith 0 #endif +/* +** The SrcList_item structure passed as the second argument represents a +** sub-query in the FROM clause of a SELECT statement. This function +** allocates and populates the SrcList_item.pTab object. If successful, +** SQLITE_OK is returned. Otherwise, if an OOM error is encountered, +** SQLITE_NOMEM. +*/ +SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, struct SrcList_item *pFrom){ + Select *pSel = pFrom->pSelect; + Table *pTab; + + assert( pSel ); + pFrom->pTab = pTab = sqlite3DbMallocZero(pParse->db, sizeof(Table)); + if( pTab==0 ) return SQLITE_NOMEM; + pTab->nTabRef = 1; + if( pFrom->zAlias ){ + pTab->zName = sqlite3DbStrDup(pParse->db, pFrom->zAlias); + }else{ + pTab->zName = sqlite3MPrintf(pParse->db, "subquery_%u", pSel->selId); + } + while( pSel->pPrior ){ pSel = pSel->pPrior; } + sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol); + pTab->iPKey = -1; + pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); + pTab->tabFlags |= TF_Ephemeral; + + return SQLITE_OK; +} + /* ** This routine is a Walker callback for "expanding" a SELECT statement. ** "Expanding" means to do the following: @@ -125956,19 +127968,7 @@ static int selectExpander(Walker *pWalker, Select *p){ assert( pSel!=0 ); assert( pFrom->pTab==0 ); if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort; - pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); - if( pTab==0 ) return WRC_Abort; - pTab->nTabRef = 1; - if( pFrom->zAlias ){ - pTab->zName = sqlite3DbStrDup(db, pFrom->zAlias); - }else{ - pTab->zName = sqlite3MPrintf(db, "subquery_%p", (void*)pTab); - } - while( pSel->pPrior ){ pSel = pSel->pPrior; } - sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol); - pTab->iPKey = -1; - pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); - pTab->tabFlags |= TF_Ephemeral; + if( sqlite3ExpandSubquery(pParse, pFrom) ) return WRC_Abort; #endif }else{ /* An ordinary table or view name in the FROM clause */ @@ -125991,7 +127991,6 @@ static int selectExpander(Walker *pWalker, Select *p){ if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; assert( pFrom->pSelect==0 ); pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0); - sqlite3SelectSetName(pFrom->pSelect, pTab->zName); nCol = pTab->nCol; pTab->nCol = -1; sqlite3WalkSelect(pWalker, pFrom->pSelect); @@ -126269,7 +128268,7 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ struct SrcList_item *pFrom; assert( p->selFlags & SF_Resolved ); - assert( (p->selFlags & SF_HasTypeInfo)==0 ); + if( p->selFlags & SF_HasTypeInfo ) return; p->selFlags |= SF_HasTypeInfo; pParse = pWalker->pParse; pTabList = p->pSrc; @@ -126372,7 +128371,7 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ "argument"); pFunc->iDistinct = -1; }else{ - KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList, 0, 0); + KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pE->x.pList,0,0); sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0, (char*)pKeyInfo, P4_KEYINFO); } @@ -126396,11 +128395,17 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ } } + /* ** Update the accumulator memory cells for an aggregate based on ** the current cursor position. +** +** If regAcc is non-zero and there are no min() or max() aggregates +** in pAggInfo, then only populate the pAggInfo->nAccumulator accumulator +** registers i register regAcc contains 0. The caller will take care +** of setting and clearing regAcc. */ -static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ +static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){ Vdbe *v = pParse->pVdbe; int i; int regHit = 0; @@ -126443,36 +128448,24 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem; sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ); } - sqlite3VdbeAddOp3(v, OP_AggStep0, 0, regAgg, pF->iMem); + sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, pF->iMem); sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); sqlite3VdbeChangeP5(v, (u8)nArg); - sqlite3ExprCacheAffinityChange(pParse, regAgg, nArg); sqlite3ReleaseTempRange(pParse, regAgg, nArg); if( addrNext ){ sqlite3VdbeResolveLabel(v, addrNext); - sqlite3ExprCacheClear(pParse); } } - - /* Before populating the accumulator registers, clear the column cache. - ** Otherwise, if any of the required column values are already present - ** in registers, sqlite3ExprCode() may use OP_SCopy to copy the value - ** to pC->iMem. But by the time the value is used, the original register - ** may have been used, invalidating the underlying buffer holding the - ** text or blob value. See ticket [883034dcb5]. - ** - ** Another solution would be to change the OP_SCopy used to copy cached - ** values to an OP_Copy. - */ + if( regHit==0 && pAggInfo->nAccumulator ){ + regHit = regAcc; + } if( regHit ){ addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v); } - sqlite3ExprCacheClear(pParse); for(i=0, pC=pAggInfo->aCol; inAccumulator; i++, pC++){ sqlite3ExprCode(pParse, pC->pExpr, pC->iMem); } pAggInfo->directMode = 0; - sqlite3ExprCacheClear(pParse); if( addrHitTest ){ sqlite3VdbeJumpHere(v, addrHitTest); } @@ -126602,6 +128595,7 @@ static struct SrcList_item *isSelfJoinView( ** The transformation only works if all of the following are true: ** ** * The subquery is a UNION ALL of two or more terms +** * The subquery does not have a LIMIT clause ** * There is no WHERE or GROUP BY or HAVING clauses on the subqueries ** * The outer query is a simple count(*) ** @@ -126625,6 +128619,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ do{ if( pSub->op!=TK_ALL && pSub->pPrior ) return 0; /* Must be UNION ALL */ if( pSub->pWhere ) return 0; /* No WHERE clause */ + if( pSub->pLimit ) return 0; /* No LIMIT clause */ if( pSub->selFlags & SF_Aggregate ) return 0; /* Not an aggregate */ pSub = pSub->pPrior; /* Repeat over compound */ }while( pSub ); @@ -126737,14 +128732,10 @@ SQLITE_PRIVATE int sqlite3Select( p->selFlags &= ~SF_Distinct; } sqlite3SelectPrep(pParse, p, 0); - memset(&sSort, 0, sizeof(sSort)); - sSort.pOrderBy = p->pOrderBy; - pTabList = p->pSrc; if( pParse->nErr || db->mallocFailed ){ goto select_end; } assert( p->pEList!=0 ); - isAgg = (p->selFlags & SF_Aggregate)!=0; #if SELECTTRACE_ENABLED if( sqlite3SelectTrace & 0x104 ){ SELECTTRACE(0x104,pParse,p, ("after name resolution:\n")); @@ -126756,6 +128747,22 @@ SQLITE_PRIVATE int sqlite3Select( generateColumnNames(pParse, p); } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( sqlite3WindowRewrite(pParse, p) ){ + goto select_end; + } +#if SELECTTRACE_ENABLED + if( sqlite3SelectTrace & 0x108 ){ + SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif +#endif /* SQLITE_OMIT_WINDOWFUNC */ + pTabList = p->pSrc; + isAgg = (p->selFlags & SF_Aggregate)!=0; + memset(&sSort, 0, sizeof(sSort)); + sSort.pOrderBy = p->pOrderBy; + /* Try to various optimizations (flattening subqueries, and strength ** reduction of join operators) in the FROM clause up into the main query */ @@ -126855,6 +128862,35 @@ SQLITE_PRIVATE int sqlite3Select( } #endif + /* Do the WHERE-clause constant propagation optimization if this is + ** a join. No need to speed time on this operation for non-join queries + ** as the equivalent optimization will be handled by query planner in + ** sqlite3WhereBegin(). + */ + if( pTabList->nSrc>1 + && OptimizationEnabled(db, SQLITE_PropagateConst) + && propagateConstants(pParse, p) + ){ +#if SELECTTRACE_ENABLED + if( sqlite3SelectTrace & 0x100 ){ + SELECTTRACE(0x100,pParse,p,("After constant propagation:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif + }else{ + SELECTTRACE(0x100,pParse,p,("Constant propagation not helpful\n")); + } + +#ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION + if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView) + && countOfViewOptimization(pParse, p) + ){ + if( db->mallocFailed ) goto select_end; + pEList = p->pEList; + pTabList = p->pSrc; + } +#endif + /* For each term in the FROM clause, do two things: ** (1) Authorized unreferenced tables ** (2) Generate code for all sub-queries @@ -126928,7 +128964,8 @@ SQLITE_PRIVATE int sqlite3Select( ){ #if SELECTTRACE_ENABLED if( sqlite3SelectTrace & 0x100 ){ - SELECTTRACE(0x100,pParse,p,("After WHERE-clause push-down:\n")); + SELECTTRACE(0x100,pParse,p, + ("After WHERE-clause push-down into subquery %d:\n", pSub->selId)); sqlite3TreeViewSelect(0, p, 0); } #endif @@ -126962,7 +128999,7 @@ SQLITE_PRIVATE int sqlite3Select( VdbeComment((v, "%s", pItem->pTab->zName)); pItem->addrFillSub = addrTop; sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn); - ExplainQueryPlan((pParse, 1, "CO-ROUTINE 0x%p", pSub)); + ExplainQueryPlan((pParse, 1, "CO-ROUTINE %u", pSub->selId)); sqlite3Select(pParse, pSub, &dest); pItem->pTab->nRowLogEst = pSub->nSelectRow; pItem->fg.viaCoroutine = 1; @@ -127001,7 +129038,7 @@ SQLITE_PRIVATE int sqlite3Select( pSub->nSelectRow = pPrior->pSelect->nSelectRow; }else{ sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); - ExplainQueryPlan((pParse, 1, "MATERIALIZE 0x%p", pSub)); + ExplainQueryPlan((pParse, 1, "MATERIALIZE %u", pSub->selId)); sqlite3Select(pParse, pSub, &dest); } pItem->pTab->nRowLogEst = pSub->nSelectRow; @@ -127032,16 +129069,6 @@ SQLITE_PRIVATE int sqlite3Select( } #endif -#ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION - if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView) - && countOfViewOptimization(pParse, p) - ){ - if( db->mallocFailed ) goto select_end; - pEList = p->pEList; - pTabList = p->pSrc; - } -#endif - /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and ** if the select-list is the same as the ORDER BY list, then this query ** can be rewritten as a GROUP BY. In other words, this: @@ -127085,7 +129112,8 @@ SQLITE_PRIVATE int sqlite3Select( */ if( sSort.pOrderBy ){ KeyInfo *pKeyInfo; - pKeyInfo = keyInfoFromExprList(pParse, sSort.pOrderBy, 0, pEList->nExpr); + pKeyInfo = sqlite3KeyInfoFromExprList( + pParse, sSort.pOrderBy, 0, pEList->nExpr); sSort.iECursor = pParse->nTab++; sSort.addrSortIndex = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, @@ -127119,9 +129147,9 @@ SQLITE_PRIVATE int sqlite3Select( if( p->selFlags & SF_Distinct ){ sDistinct.tabTnct = pParse->nTab++; sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, - sDistinct.tabTnct, 0, 0, - (char*)keyInfoFromExprList(pParse, p->pEList,0,0), - P4_KEYINFO); + sDistinct.tabTnct, 0, 0, + (char*)sqlite3KeyInfoFromExprList(pParse, p->pEList,0,0), + P4_KEYINFO); sqlite3VdbeChangeP5(v, BTREE_UNORDERED); sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED; }else{ @@ -127130,9 +129158,16 @@ SQLITE_PRIVATE int sqlite3Select( if( !isAgg && pGroupBy==0 ){ /* No aggregate functions and no GROUP BY clause */ - u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0); + u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0) + | (p->selFlags & SF_FixedLimit); +#ifndef SQLITE_OMIT_WINDOWFUNC + Window *pWin = p->pWin; /* Master window object (or NULL) */ + if( pWin ){ + sqlite3WindowCodeInit(pParse, pWin); + } +#endif assert( WHERE_USE_LIMIT==SF_FixedLimit ); - wctrlFlags |= p->selFlags & SF_FixedLimit; + /* Begin the database scan. */ SELECTTRACE(1,pParse,p,("WhereBegin\n")); @@ -127147,7 +129182,7 @@ SQLITE_PRIVATE int sqlite3Select( } if( sSort.pOrderBy ){ sSort.nOBSat = sqlite3WhereIsOrdered(pWInfo); - sSort.bOrderedInnerLoop = sqlite3WhereOrderedInnerLoop(pWInfo); + sSort.labelOBLopt = sqlite3WhereOrderByLimitOptLabel(pWInfo); if( sSort.nOBSat==sSort.pOrderBy->nExpr ){ sSort.pOrderBy = 0; } @@ -127161,15 +129196,37 @@ SQLITE_PRIVATE int sqlite3Select( sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex); } - /* Use the standard inner loop. */ assert( p->pEList==pEList ); - selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest, - sqlite3WhereContinueLabel(pWInfo), - sqlite3WhereBreakLabel(pWInfo)); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pWin ){ + int addrGosub = sqlite3VdbeMakeLabel(v); + int iCont = sqlite3VdbeMakeLabel(v); + int iBreak = sqlite3VdbeMakeLabel(v); + int regGosub = ++pParse->nMem; - /* End the database scan loop. - */ - sqlite3WhereEnd(pWInfo); + sqlite3WindowCodeStep(pParse, p, pWInfo, regGosub, addrGosub); + + sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak); + sqlite3VdbeResolveLabel(v, addrGosub); + VdbeNoopComment((v, "inner-loop subroutine")); + sSort.labelOBLopt = 0; + selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest, iCont, iBreak); + sqlite3VdbeResolveLabel(v, iCont); + sqlite3VdbeAddOp1(v, OP_Return, regGosub); + VdbeComment((v, "end inner-loop subroutine")); + sqlite3VdbeResolveLabel(v, iBreak); + }else +#endif /* SQLITE_OMIT_WINDOWFUNC */ + { + /* Use the standard inner loop. */ + selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest, + sqlite3WhereContinueLabel(pWInfo), + sqlite3WhereBreakLabel(pWInfo)); + + /* End the database scan loop. + */ + sqlite3WhereEnd(pWInfo); + } }else{ /* This case when there exist aggregate functions or a GROUP BY clause ** or both */ @@ -127298,7 +129355,7 @@ SQLITE_PRIVATE int sqlite3Select( ** will be converted into a Noop. */ sAggInfo.sortingIdx = pParse->nTab++; - pKeyInfo = keyInfoFromExprList(pParse, pGroupBy, 0, sAggInfo.nColumn); + pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pGroupBy,0,sAggInfo.nColumn); addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen, sAggInfo.sortingIdx, sAggInfo.nSortingColumn, 0, (char*)pKeyInfo, P4_KEYINFO); @@ -127317,8 +129374,6 @@ SQLITE_PRIVATE int sqlite3Select( pParse->nMem += pGroupBy->nExpr; sqlite3VdbeAddOp2(v, OP_Integer, 0, iAbortFlag); VdbeComment((v, "clear abort flag")); - sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag); - VdbeComment((v, "indicate accumulator empty")); sqlite3VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1); /* Begin a loop that will extract all source rows in GROUP BY order. @@ -127364,15 +129419,14 @@ SQLITE_PRIVATE int sqlite3Select( } } regBase = sqlite3GetTempRange(pParse, nCol); - sqlite3ExprCacheClear(pParse); sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0); j = nGroupBy; for(i=0; iiSorterColumn>=j ){ int r1 = j + regBase; - sqlite3ExprCodeGetColumnToReg(pParse, - pCol->pTab, pCol->iColumn, pCol->iTable, r1); + sqlite3ExprCodeGetColumnOfTable(v, + pCol->pTab, pCol->iTable, pCol->iColumn, r1); j++; } } @@ -127388,8 +129442,6 @@ SQLITE_PRIVATE int sqlite3Select( sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd); VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v); sAggInfo.useSortingIdx = 1; - sqlite3ExprCacheClear(pParse); - } /* If the index or temporary table used by the GROUP BY sort @@ -127412,7 +129464,6 @@ SQLITE_PRIVATE int sqlite3Select( ** from the previous row currently stored in a0, a1, a2... */ addrTopOfLoop = sqlite3VdbeCurrentAddr(v); - sqlite3ExprCacheClear(pParse); if( groupBySort ){ sqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx, sortOut, sortPTab); @@ -127451,7 +129502,7 @@ SQLITE_PRIVATE int sqlite3Select( ** the current row */ sqlite3VdbeJumpHere(v, addr1); - updateAccumulator(pParse, &sAggInfo); + updateAccumulator(pParse, iUseFlag, &sAggInfo); sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag); VdbeComment((v, "indicate data in accumulator")); @@ -127503,6 +129554,8 @@ SQLITE_PRIVATE int sqlite3Select( */ sqlite3VdbeResolveLabel(v, addrReset); resetAccumulator(pParse, &sAggInfo); + sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag); + VdbeComment((v, "indicate accumulator empty")); sqlite3VdbeAddOp1(v, OP_Return, regReset); } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */ @@ -127568,6 +129621,23 @@ SQLITE_PRIVATE int sqlite3Select( }else #endif /* SQLITE_OMIT_BTREECOUNT */ { + int regAcc = 0; /* "populate accumulators" flag */ + + /* If there are accumulator registers but no min() or max() functions, + ** allocate register regAcc. Register regAcc will contain 0 the first + ** time the inner loop runs, and 1 thereafter. The code generated + ** by updateAccumulator() only updates the accumulator registers if + ** regAcc contains 0. */ + if( sAggInfo.nAccumulator ){ + for(i=0; ifuncFlags&SQLITE_FUNC_NEEDCOLL ) break; + } + if( i==sAggInfo.nFunc ){ + regAcc = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Integer, 0, regAcc); + } + } + /* This case runs if the aggregate has no GROUP BY clause. The ** processing is much simpler since there is only a single row ** of output. @@ -127589,7 +129659,8 @@ SQLITE_PRIVATE int sqlite3Select( if( pWInfo==0 ){ goto select_end; } - updateAccumulator(pParse, &sAggInfo); + updateAccumulator(pParse, regAcc, &sAggInfo); + if( regAcc ) sqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc); if( sqlite3WhereIsOrdered(pWInfo)>0 ){ sqlite3VdbeGoto(v, sqlite3WhereBreakLabel(pWInfo)); VdbeComment((v, "%s() by index", @@ -128033,14 +130104,16 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( goto trigger_cleanup; } assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){ - if( !noErr ){ - sqlite3ErrorMsg(pParse, "trigger %T already exists", pName); - }else{ - assert( !db->init.busy ); - sqlite3CodeVerifySchema(pParse, iDb); + if( !IN_RENAME_OBJECT ){ + if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){ + if( !noErr ){ + sqlite3ErrorMsg(pParse, "trigger %T already exists", pName); + }else{ + assert( !db->init.busy ); + sqlite3CodeVerifySchema(pParse, iDb); + } + goto trigger_cleanup; } - goto trigger_cleanup; } /* Do not create a trigger on a system table */ @@ -128064,7 +130137,7 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( } #ifndef SQLITE_OMIT_AUTHORIZATION - { + if( !IN_RENAME_OBJECT ){ int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); int code = SQLITE_CREATE_TRIGGER; const char *zDb = db->aDb[iTabDb].zDbSName; @@ -128098,8 +130171,15 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( pTrigger->pTabSchema = pTab->pSchema; pTrigger->op = (u8)op; pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER; - pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); - pTrigger->pColumns = sqlite3IdListDup(db, pColumns); + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, pTrigger->table, pTableName->a[0].zName); + pTrigger->pWhen = pWhen; + pWhen = 0; + }else{ + pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); + } + pTrigger->pColumns = pColumns; + pColumns = 0; assert( pParse->pNewTrigger==0 ); pParse->pNewTrigger = pTrigger; @@ -128148,6 +130228,14 @@ SQLITE_PRIVATE void sqlite3FinishTrigger( goto triggerfinish_cleanup; } +#ifndef SQLITE_OMIT_ALTERTABLE + if( IN_RENAME_OBJECT ){ + assert( !db->init.busy ); + pParse->pNewTrigger = pTrig; + pTrig = 0; + }else +#endif + /* if we are not initializing, ** build the sqlite_master entry */ @@ -128189,7 +130277,7 @@ SQLITE_PRIVATE void sqlite3FinishTrigger( triggerfinish_cleanup: sqlite3DeleteTrigger(db, pTrig); - assert( !pParse->pNewTrigger ); + assert( IN_RENAME_OBJECT || !pParse->pNewTrigger ); sqlite3DeleteTriggerStep(db, pStepList); } @@ -128236,12 +130324,13 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep( ** If an OOM error occurs, NULL is returned and db->mallocFailed is set. */ static TriggerStep *triggerStepAllocate( - sqlite3 *db, /* Database connection */ + Parse *pParse, /* Parser context */ u8 op, /* Trigger opcode */ Token *pName, /* The target name */ const char *zStart, /* Start of SQL text */ const char *zEnd /* End of SQL text */ ){ + sqlite3 *db = pParse->db; TriggerStep *pTriggerStep; pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1); @@ -128252,6 +130341,9 @@ static TriggerStep *triggerStepAllocate( pTriggerStep->zTarget = z; pTriggerStep->op = op; pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd); + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenMap(pParse, pTriggerStep->zTarget, pName); + } } return pTriggerStep; } @@ -128264,7 +130356,7 @@ static TriggerStep *triggerStepAllocate( ** body of a trigger. */ SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep( - sqlite3 *db, /* The database connection */ + Parse *pParse, /* Parser */ Token *pTableName, /* Name of the table into which we insert */ IdList *pColumn, /* List of columns in pTableName to insert into */ Select *pSelect, /* A SELECT statement that supplies values */ @@ -128273,13 +130365,19 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep( const char *zStart, /* Start of SQL text */ const char *zEnd /* End of SQL text */ ){ + sqlite3 *db = pParse->db; TriggerStep *pTriggerStep; assert(pSelect != 0 || db->mallocFailed); - pTriggerStep = triggerStepAllocate(db, TK_INSERT, pTableName, zStart, zEnd); + pTriggerStep = triggerStepAllocate(pParse, TK_INSERT, pTableName,zStart,zEnd); if( pTriggerStep ){ - pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); + if( IN_RENAME_OBJECT ){ + pTriggerStep->pSelect = pSelect; + pSelect = 0; + }else{ + pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); + } pTriggerStep->pIdList = pColumn; pTriggerStep->pUpsert = pUpsert; pTriggerStep->orconf = orconf; @@ -128300,7 +130398,7 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep( ** sees an UPDATE statement inside the body of a CREATE TRIGGER. */ SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep( - sqlite3 *db, /* The database connection */ + Parse *pParse, /* Parser */ Token *pTableName, /* Name of the table to be updated */ ExprList *pEList, /* The SET clause: list of column and new values */ Expr *pWhere, /* The WHERE clause */ @@ -128308,12 +130406,20 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep( const char *zStart, /* Start of SQL text */ const char *zEnd /* End of SQL text */ ){ + sqlite3 *db = pParse->db; TriggerStep *pTriggerStep; - pTriggerStep = triggerStepAllocate(db, TK_UPDATE, pTableName, zStart, zEnd); + pTriggerStep = triggerStepAllocate(pParse, TK_UPDATE, pTableName,zStart,zEnd); if( pTriggerStep ){ - pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE); - pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); + if( IN_RENAME_OBJECT ){ + pTriggerStep->pExprList = pEList; + pTriggerStep->pWhere = pWhere; + pEList = 0; + pWhere = 0; + }else{ + pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE); + pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); + } pTriggerStep->orconf = orconf; } sqlite3ExprListDelete(db, pEList); @@ -128327,17 +130433,23 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep( ** sees a DELETE statement inside the body of a CREATE TRIGGER. */ SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep( - sqlite3 *db, /* Database connection */ + Parse *pParse, /* Parser */ Token *pTableName, /* The table from which rows are deleted */ Expr *pWhere, /* The WHERE clause */ const char *zStart, /* Start of SQL text */ const char *zEnd /* End of SQL text */ ){ + sqlite3 *db = pParse->db; TriggerStep *pTriggerStep; - pTriggerStep = triggerStepAllocate(db, TK_DELETE, pTableName, zStart, zEnd); + pTriggerStep = triggerStepAllocate(pParse, TK_DELETE, pTableName,zStart,zEnd); if( pTriggerStep ){ - pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); + if( IN_RENAME_OBJECT ){ + pTriggerStep->pWhere = pWhere; + pWhere = 0; + }else{ + pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); + } pTriggerStep->orconf = OE_Default; } sqlite3ExprDelete(db, pWhere); @@ -129522,7 +131634,7 @@ SQLITE_PRIVATE void sqlite3Update( if( !isView && aiCurOnePass[0]!=iDataCur && aiCurOnePass[1]!=iDataCur ){ assert( pPk ); sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey,nKey); - VdbeCoverageNeverTaken(v); + VdbeCoverage(v); } if( eOnePass!=ONEPASS_SINGLE ){ labelContinue = sqlite3VdbeMakeLabel(v); @@ -129609,13 +131721,7 @@ SQLITE_PRIVATE void sqlite3Update( */ testcase( i==31 ); testcase( i==32 ); - sqlite3ExprCodeGetColumnToReg(pParse, pTab, i, iDataCur, regNew+i); - if( tmask & TRIGGER_BEFORE ){ - /* This value will be recomputed in After-BEFORE-trigger-reload-loop - ** below, so make sure that it is not cached and reused. - ** Ticket d85fffd6ffe856092ed8daefa811b1e399706b28. */ - sqlite3ExprCacheRemove(pParse, regNew+i, 1); - } + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i); }else{ sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i); } @@ -130152,10 +132258,12 @@ SQLITE_PRIVATE void sqlite3UpsertDoUpdate( Vdbe *v = pParse->pVdbe; sqlite3 *db = pParse->db; SrcList *pSrc; /* FROM clause for the UPDATE */ - int iDataCur = pUpsert->iDataCur; + int iDataCur; assert( v!=0 ); + assert( pUpsert!=0 ); VdbeNoopComment((v, "Begin DO UPDATE of UPSERT")); + iDataCur = pUpsert->iDataCur; if( pIdx && iCur!=iDataCur ){ if( HasRowid(pTab) ){ int regRowid = sqlite3GetTempReg(pParse); @@ -130425,7 +132533,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){ */ rc = execSql(db, pzErrMsg, "BEGIN"); if( rc!=SQLITE_OK ) goto end_of_vacuum; - rc = sqlite3BtreeBeginTrans(pMain, 2); + rc = sqlite3BtreeBeginTrans(pMain, 2, 0); if( rc!=SQLITE_OK ) goto end_of_vacuum; /* Do not attempt to change the page size for a WAL database */ @@ -130843,7 +132951,7 @@ SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3 *db){ assert( sqlite3_mutex_held(db->mutex) ); if( p ){ - sqlite3ExpirePreparedStatements(db); + sqlite3ExpirePreparedStatements(db, 0); do { VTable *pNext = p->pNext; sqlite3VtabUnlock(p); @@ -131339,7 +133447,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ assert( IsVirtual(pTab) ); memset(&sParse, 0, sizeof(sParse)); - sParse.declareVtab = 1; + sParse.eParseMode = PARSE_MODE_DECLARE_VTAB; sParse.db = db; sParse.nQueryLoop = 1; if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable, &zErr) @@ -131380,7 +133488,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ sqlite3DbFree(db, zErr); rc = SQLITE_ERROR; } - sParse.declareVtab = 0; + sParse.eParseMode = PARSE_MODE_NORMAL; if( sParse.pVdbe ){ sqlite3VdbeFinalize(sParse.pVdbe); @@ -131934,6 +134042,8 @@ struct WhereLevel { struct InLoop { int iCur; /* The VDBE cursor used by this IN operator */ int addrInTop; /* Top of the IN loop */ + int iBase; /* Base register of multi-key index record */ + int nPrefix; /* Number of prior entires in the key */ u8 eEndLoopOp; /* IN Loop terminator. OP_Next or OP_Prev */ } *aInLoop; /* Information about each nested IN operator */ } in; /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */ @@ -132172,6 +134282,7 @@ struct WhereClause { WhereInfo *pWInfo; /* WHERE clause processing context */ WhereClause *pOuter; /* Outer conjunction */ u8 op; /* Split operator. TK_AND or TK_OR */ + u8 hasOr; /* True if any a[].eOperator is WO_OR */ int nTerm; /* Number of terms */ int nSlot; /* Number of entries in a[] */ WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */ @@ -132345,6 +134456,7 @@ SQLITE_PRIVATE void sqlite3WhereClauseInit(WhereClause*,WhereInfo*); SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause*); SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause*,Expr*,u8); SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*); +SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet*, Expr*); SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*); SQLITE_PRIVATE void sqlite3WhereExprAnalyze(SrcList*, WhereClause*); SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*); @@ -132407,6 +134519,7 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereC #define WHERE_SKIPSCAN 0x00008000 /* Uses the skip-scan algorithm */ #define WHERE_UNQ_WANTED 0x00010000 /* WHERE_ONEROW would have been helpful*/ #define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */ +#define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */ /************** End of whereInt.h ********************************************/ /************** Continuing where we left off in wherecode.c ******************/ @@ -132541,7 +134654,7 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH); sqlite3_str_appendall(&str, isSearch ? "SEARCH" : "SCAN"); if( pItem->pSelect ){ - sqlite3_str_appendf(&str, " SUBQUERY 0x%p", pItem->pSelect); + sqlite3_str_appendf(&str, " SUBQUERY %u", pItem->pSelect->selId); }else{ sqlite3_str_appendf(&str, " TABLE %s", pItem->zName); } @@ -132738,7 +134851,6 @@ static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){ /* Code the OP_Affinity opcode if there is anything left to do. */ if( n>0 ){ sqlite3VdbeAddOp4(v, OP_Affinity, base, n, 0, zAff, n); - sqlite3ExprCacheAffinityChange(pParse, base, n); } } @@ -132982,7 +135094,14 @@ static int codeEqualityTerm( sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v); if( i==iEq ){ pIn->iCur = iTab; - pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen; + pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next; + if( iEq>0 && (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ){ + pIn->iBase = iReg - i; + pIn->nPrefix = i; + pLoop->wsFlags |= WHERE_IN_EARLYOUT; + }else{ + pIn->nPrefix = 0; + } }else{ pIn->eEndLoopOp = OP_Noop; } @@ -133269,11 +135388,8 @@ static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){ struct CCurHint *pHint = pWalker->u.pCCurHint; if( pExpr->op==TK_COLUMN ){ if( pExpr->iTable!=pHint->iTabCur ){ - Vdbe *v = pWalker->pParse->pVdbe; int reg = ++pWalker->pParse->nMem; /* Register for column value */ - sqlite3ExprCodeGetColumnOfTable( - v, pExpr->pTab, pExpr->iTable, pExpr->iColumn, reg - ); + sqlite3ExprCode(pWalker->pParse, pExpr, reg); pExpr->op = TK_REGISTER; pExpr->iTable = reg; }else if( pHint->pIdx!=0 ){ @@ -133626,7 +135742,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub); pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk); VdbeCoverage(v); - VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName)); + VdbeComment((v, "next row of %s", pTabItem->pTab->zName)); pLevel->op = OP_Goto; }else @@ -133640,7 +135756,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( int nConstraint = pLoop->nLTerm; int iIn; /* Counter for IN constraints */ - sqlite3ExprCachePush(pParse); iReg = sqlite3GetTempRange(pParse, nConstraint+2); addrNotFound = pLevel->addrBrk; for(j=0; jaddrNxt; sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg); VdbeCoverage(v); - sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1); - sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); - VdbeComment((v, "pk")); pLevel->op = OP_Noop; }else if( (pLoop->wsFlags & WHERE_IPK)!=0 && (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0 @@ -133809,7 +135920,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( VdbeCoverageIf(v, pX->op==TK_LE); VdbeCoverageIf(v, pX->op==TK_LT); VdbeCoverageIf(v, pX->op==TK_GE); - sqlite3ExprCacheAffinityChange(pParse, r1, 1); sqlite3ReleaseTempReg(pParse, rTemp); }else{ sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrHalt); @@ -133844,7 +135954,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( if( testOp!=OP_Noop ){ iRowidReg = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg); - sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg); VdbeCoverageIf(v, testOp==OP_Le); VdbeCoverageIf(v, testOp==OP_Lt); @@ -134049,6 +136158,9 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( ** above has already left the cursor sitting on the correct row, ** so no further seeking is needed */ }else{ + if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){ + sqlite3VdbeAddOp1(v, OP_SeekHit, iIdxCur); + } op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev]; assert( op!=0 ); sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); @@ -134067,7 +136179,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( nConstraint = nEq; if( pRangeEnd ){ Expr *pRight = pRangeEnd->pExpr->pRight; - sqlite3ExprCacheRemove(pParse, regBase+nEq, 1); codeExprOrVector(pParse, pRight, regBase+nEq, nTop); whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd); if( (pRangeEnd->wtFlags & TERM_VNULL)==0 @@ -134092,7 +136203,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( } }else if( bStopAtNull ){ sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); - sqlite3ExprCacheRemove(pParse, regBase+nEq, 1); endEq = 0; nConstraint++; } @@ -134112,6 +136222,10 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); } + if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){ + sqlite3VdbeAddOp2(v, OP_SeekHit, iIdxCur, 1); + } + /* Seek the table cursor, if required */ if( omitTable ){ /* pIdx is a covering index. No need to access the main table. */ @@ -134122,7 +136236,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( )){ iRowidReg = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg); - sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, iRowidReg); VdbeCoverage(v); }else{ @@ -134357,23 +136470,23 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( ** row will be skipped in subsequent sub-WHERE clauses. */ if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ - int r; int iSet = ((ii==pOrWc->nTerm-1)?-1:ii); if( HasRowid(pTab) ){ - r = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, regRowid, 0); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, regRowid); jmp1 = sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, 0, - r,iSet); + regRowid, iSet); VdbeCoverage(v); }else{ Index *pPk = sqlite3PrimaryKeyIndex(pTab); int nPk = pPk->nKeyCol; int iPk; + int r; /* Read the PK into an array of temp registers. */ r = sqlite3GetTempRange(pParse, nPk); for(iPk=0; iPkaiColumn[iPk]; - sqlite3ExprCodeGetColumnToReg(pParse, pTab, iCol, iCur, r+iPk); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol, r+iPk); } /* Check if the temp table already contains this key. If so, @@ -134606,7 +136719,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( pLevel->addrFirst = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin); VdbeComment((v, "record LEFT JOIN hit")); - sqlite3ExprCacheClear(pParse); for(pTerm=pWC->a, j=0; jnTerm; j++, pTerm++){ testcase( pTerm->wtFlags & TERM_VIRTUAL ); testcase( pTerm->wtFlags & TERM_CODED ); @@ -134822,18 +136934,18 @@ static int isLikeOrGlob( int *pisComplete, /* True if the only wildcard is % in the last character */ int *pnoCase /* True if uppercase is equivalent to lowercase */ ){ - const u8 *z = 0; /* String on RHS of LIKE operator */ + const u8 *z = 0; /* String on RHS of LIKE operator */ Expr *pRight, *pLeft; /* Right and left size of LIKE operator */ ExprList *pList; /* List of operands to the LIKE operator */ - int c; /* One character in z[] */ + u8 c; /* One character in z[] */ int cnt; /* Number of non-wildcard prefix characters */ - char wc[4]; /* Wildcard characters */ + u8 wc[4]; /* Wildcard characters */ sqlite3 *db = pParse->db; /* Database connection */ sqlite3_value *pVal = 0; int op; /* Opcode of pRight */ int rc; /* Result code to return */ - if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, wc) ){ + if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, (char*)wc) ){ return 0; } #ifdef SQLITE_EBCDIC @@ -134858,23 +136970,6 @@ static int isLikeOrGlob( } if( z ){ - /* If the RHS begins with a digit or a minus sign, then the LHS must - ** be an ordinary column (not a virtual table column) with TEXT affinity. - ** Otherwise the LHS might be numeric and "lhs >= rhs" would be false - ** even though "lhs LIKE rhs" is true. But if the RHS does not start - ** with a digit or '-', then "lhs LIKE rhs" will always be false if - ** the LHS is numeric and so the optimization still works. - */ - if( sqlite3Isdigit(z[0]) || z[0]=='-' ){ - if( pLeft->op!=TK_COLUMN - || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT - || IsVirtual(pLeft->pTab) /* Value might be numeric */ - ){ - sqlite3ValueFree(pVal); - return 0; - } - } - /* Count the number of prefix characters prior to the first wildcard */ cnt = 0; while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){ @@ -134884,11 +136979,13 @@ static int isLikeOrGlob( /* The optimization is possible only if (1) the pattern does not begin ** with a wildcard and if (2) the non-wildcard prefix does not end with - ** an (illegal 0xff) character. The second condition is necessary so + ** an (illegal 0xff) character, or (3) the pattern does not consist of + ** a single escape character. The second condition is necessary so ** that we can increment the prefix key to find an upper bound for the - ** range search. - */ - if( cnt!=0 && 255!=(u8)z[cnt-1] ){ + ** range search. The third is because the caller assumes that the pattern + ** consists of at least one character after all escapes have been + ** removed. */ + if( cnt!=0 && 255!=(u8)z[cnt-1] && (cnt>1 || z[0]!=wc[3]) ){ Expr *pPrefix; /* A "complete" match if the pattern ends with "*" or "%" */ @@ -134905,6 +137002,32 @@ static int isLikeOrGlob( zNew[iTo++] = zNew[iFrom]; } zNew[iTo] = 0; + + /* If the RHS begins with a digit or a minus sign, then the LHS must be + ** an ordinary column (not a virtual table column) with TEXT affinity. + ** Otherwise the LHS might be numeric and "lhs >= rhs" would be false + ** even though "lhs LIKE rhs" is true. But if the RHS does not start + ** with a digit or '-', then "lhs LIKE rhs" will always be false if + ** the LHS is numeric and so the optimization still works. + ** + ** 2018-09-10 ticket c94369cae9b561b1f996d0054bfab11389f9d033 + ** The RHS pattern must not be '/%' because the termination condition + ** will then become "x<'0'" and if the affinity is numeric, will then + ** be converted into "x<0", which is incorrect. + */ + if( sqlite3Isdigit(zNew[0]) + || zNew[0]=='-' + || (zNew[0]+1=='0' && iTo==1) + ){ + if( pLeft->op!=TK_COLUMN + || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT + || IsVirtual(pLeft->pTab) /* Value might be numeric */ + ){ + sqlite3ExprDelete(db, pPrefix); + sqlite3ValueFree(pVal); + return 0; + } + } } *ppPrefix = pPrefix; @@ -134966,6 +137089,7 @@ static int isLikeOrGlob( ** If the expression matches none of the patterns above, return 0. */ static int isAuxiliaryVtabOperator( + sqlite3 *db, /* Parsing context */ Expr *pExpr, /* Test this expression */ unsigned char *peOp2, /* OUT: 0 for MATCH, or else an op2 value */ Expr **ppLeft, /* Column expression to left of MATCH/op2 */ @@ -134989,16 +137113,54 @@ static int isAuxiliaryVtabOperator( if( pList==0 || pList->nExpr!=2 ){ return 0; } + + /* Built-in operators MATCH, GLOB, LIKE, and REGEXP attach to a + ** virtual table on their second argument, which is the same as + ** the left-hand side operand in their in-fix form. + ** + ** vtab_column MATCH expression + ** MATCH(expression,vtab_column) + */ pCol = pList->a[1].pExpr; - if( pCol->op!=TK_COLUMN || !IsVirtual(pCol->pTab) ){ - return 0; + if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){ + for(i=0; iu.zToken, aOp[i].zOp)==0 ){ + *peOp2 = aOp[i].eOp2; + *ppRight = pList->a[0].pExpr; + *ppLeft = pCol; + return 1; + } + } } - for(i=0; iu.zToken, aOp[i].zOp)==0 ){ - *peOp2 = aOp[i].eOp2; - *ppRight = pList->a[0].pExpr; - *ppLeft = pCol; - return 1; + + /* We can also match against the first column of overloaded + ** functions where xFindFunction returns a value of at least + ** SQLITE_INDEX_CONSTRAINT_FUNCTION. + ** + ** OVERLOADED(vtab_column,expression) + ** + ** Historically, xFindFunction expected to see lower-case function + ** names. But for this use case, xFindFunction is expected to deal + ** with function names in an arbitrary case. + */ + pCol = pList->a[0].pExpr; + if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){ + sqlite3_vtab *pVtab; + sqlite3_module *pMod; + void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**); + void *pNotUsed; + pVtab = sqlite3GetVTable(db, pCol->pTab)->pVtab; + assert( pVtab!=0 ); + assert( pVtab->pModule!=0 ); + pMod = (sqlite3_module *)pVtab->pModule; + if( pMod->xFindFunction!=0 ){ + i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed); + if( i>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){ + *peOp2 = i; + *ppRight = pList->a[1].pExpr; + *ppLeft = pCol; + return 1; + } } } }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){ @@ -135300,7 +137462,12 @@ static void exprAnalyzeOrTerm( ** empty. */ pOrInfo->indexable = indexable; - pTerm->eOperator = indexable==0 ? 0 : WO_OR; + if( indexable ){ + pTerm->eOperator = WO_OR; + pWC->hasOr = 1; + }else{ + pTerm->eOperator = WO_OR; + } /* For a two-way OR, attempt to implementation case 2. */ @@ -135441,7 +137608,7 @@ static void exprAnalyzeOrTerm( idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC); testcase( idxNew==0 ); exprAnalyze(pSrc, pWC, idxNew); - pTerm = &pWC->a[idxTerm]; + /* pTerm = &pWC->a[idxTerm]; // would be needed if pTerm where used again */ markTermAsChild(pWC, idxNew, idxTerm); }else{ sqlite3ExprListDelete(db, pList); @@ -135480,7 +137647,7 @@ static int termIsEquivalence(Parse *pParse, Expr *pExpr){ return 0; } pColl = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight); - if( pColl==0 || sqlite3StrICmp(pColl->zName, "BINARY")==0 ) return 1; + if( sqlite3IsBinary(pColl) ) return 1; return sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight); } @@ -135639,7 +137806,7 @@ static void exprAnalyze( pTerm->prereqRight = sqlite3WhereExprUsage(pMaskSet, pExpr->pRight); } pMaskSet->bVarSelect = 0; - prereqAll = sqlite3WhereExprUsage(pMaskSet, pExpr); + prereqAll = sqlite3WhereExprUsageNN(pMaskSet, pExpr); if( pMaskSet->bVarSelect ) pTerm->wtFlags |= TERM_VARSELECT; if( ExprHasProperty(pExpr, EP_FromJoin) ){ Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->iRightJoinTable); @@ -135821,7 +137988,7 @@ static void exprAnalyze( } *pC = c + 1; } - zCollSeqName = noCase ? "NOCASE" : "BINARY"; + zCollSeqName = noCase ? "NOCASE" : sqlite3StrBINARY; pNewExpr1 = sqlite3ExprDup(db, pLeft, 0); pNewExpr1 = sqlite3PExpr(pParse, TK_GE, sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName), @@ -135858,7 +138025,7 @@ static void exprAnalyze( */ if( pWC->op==TK_AND ){ Expr *pRight = 0, *pLeft = 0; - int res = isAuxiliaryVtabOperator(pExpr, &eOp2, &pLeft, &pRight); + int res = isAuxiliaryVtabOperator(db, pExpr, &eOp2, &pLeft, &pRight); while( res-- > 0 ){ int idxNew; WhereTerm *pNewTerm; @@ -136032,6 +138199,7 @@ SQLITE_PRIVATE void sqlite3WhereClauseInit( WhereInfo *pWInfo /* The WHERE processing context */ ){ pWC->pWInfo = pWInfo; + pWC->hasOr = 0; pWC->pOuter = 0; pWC->nTerm = 0; pWC->nSlot = ArraySize(pWC->aStatic); @@ -136068,17 +138236,18 @@ SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause *pWC){ ** a bitmask indicating which tables are used in that expression ** tree. */ -SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){ +SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet *pMaskSet, Expr *p){ Bitmask mask; - if( p==0 ) return 0; - if( p->op==TK_COLUMN ){ + if( p->op==TK_COLUMN && !ExprHasProperty(p, EP_FixedCol) ){ return sqlite3WhereGetMask(pMaskSet, p->iTable); + }else if( ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){ + assert( p->op!=TK_IF_NULL_ROW ); + return 0; } mask = (p->op==TK_IF_NULL_ROW) ? sqlite3WhereGetMask(pMaskSet, p->iTable) : 0; - assert( !ExprHasProperty(p, EP_TokenOnly) ); - if( p->pLeft ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft); + if( p->pLeft ) mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pLeft); if( p->pRight ){ - mask |= sqlite3WhereExprUsage(pMaskSet, p->pRight); + mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pRight); assert( p->x.pList==0 ); }else if( ExprHasProperty(p, EP_xIsSelect) ){ if( ExprHasProperty(p, EP_VarSelect) ) pMaskSet->bVarSelect = 1; @@ -136088,6 +138257,9 @@ SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){ } return mask; } +SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){ + return p ? sqlite3WhereExprUsageNN(pMaskSet,p) : 0; +} SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet *pMaskSet, ExprList *pList){ int i; Bitmask mask = 0; @@ -136229,15 +138401,38 @@ SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo *pWInfo){ } /* -** Return TRUE if the innermost loop of the WHERE clause implementation -** returns rows in ORDER BY order for complete run of the inner loop. +** In the ORDER BY LIMIT optimization, if the inner-most loop is known +** to emit rows in increasing order, and if the last row emitted by the +** inner-most loop did not fit within the sorter, then we can skip all +** subsequent rows for the current iteration of the inner loop (because they +** will not fit in the sorter either) and continue with the second inner +** loop - the loop immediately outside the inner-most. ** -** Across multiple iterations of outer loops, the output rows need not be -** sorted. As long as rows are sorted for just the innermost loop, this -** routine can return TRUE. +** When a row does not fit in the sorter (because the sorter already +** holds LIMIT+OFFSET rows that are smaller), then a jump is made to the +** label returned by this function. +** +** If the ORDER BY LIMIT optimization applies, the jump destination should +** be the continuation for the second-inner-most loop. If the ORDER BY +** LIMIT optimization does not apply, then the jump destination should +** be the continuation for the inner-most loop. +** +** It is always safe for this routine to return the continuation of the +** inner-most loop, in the sense that a correct answer will result. +** Returning the continuation the second inner loop is an optimization +** that might make the code run a little faster, but should not change +** the final answer. */ -SQLITE_PRIVATE int sqlite3WhereOrderedInnerLoop(WhereInfo *pWInfo){ - return pWInfo->bOrderedInnerLoop; +SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo *pWInfo){ + WhereLevel *pInner; + if( !pWInfo->bOrderedInnerLoop ){ + /* The ORDER BY LIMIT optimization does not apply. Jump to the + ** continuation of the inner-most loop. */ + return pWInfo->iContinue; + } + pInner = &pWInfo->a[pWInfo->nLevel-1]; + assert( pInner->addrNxt!=0 ); + return pInner->addrNxt; } /* @@ -136964,7 +139159,6 @@ static void constructAutomaticIndex( VdbeComment((v, "for %s", pTable->zName)); /* Fill the automatic index with content */ - sqlite3ExprCachePush(pParse); pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom]; if( pTabItem->fg.viaCoroutine ){ int regYield = pTabItem->regReturn; @@ -136972,7 +139166,7 @@ static void constructAutomaticIndex( sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub); addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield); VdbeCoverage(v); - VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName)); + VdbeComment((v, "next row of %s", pTabItem->pTab->zName)); }else{ addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v); } @@ -137001,7 +139195,6 @@ static void constructAutomaticIndex( sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX); sqlite3VdbeJumpHere(v, addrTop); sqlite3ReleaseTempReg(pParse, regRecord); - sqlite3ExprCachePop(pParse); /* Jump here when skipping the initialization */ sqlite3VdbeJumpHere(v, addrInit); @@ -137107,6 +139300,20 @@ static sqlite3_index_info *allocateIndexInfo( testcase( pTerm->eOperator & WO_ALL ); if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue; if( pTerm->wtFlags & TERM_VNULL ) continue; + if( (pSrc->fg.jointype & JT_LEFT)!=0 + && !ExprHasProperty(pTerm->pExpr, EP_FromJoin) + && (pTerm->eOperator & (WO_IS|WO_ISNULL)) + ){ + /* An "IS" term in the WHERE clause where the virtual table is the rhs + ** of a LEFT JOIN. Do not pass this term to the virtual table + ** implementation, as this can lead to incorrect results from SQL such + ** as: + ** + ** "LEFT JOIN vtab WHERE vtab.col IS NULL" */ + testcase( pTerm->eOperator & WO_ISNULL ); + testcase( pTerm->eOperator & WO_IS ); + continue; + } assert( pTerm->u.leftColumn>=(-1) ); pIdxCons[j].iColumn = pTerm->u.leftColumn; pIdxCons[j].iTermOffset = i; @@ -137598,7 +139805,9 @@ static int whereRangeScanEst( Index *p = pLoop->u.btree.pIndex; int nEq = pLoop->u.btree.nEq; - if( p->nSample>0 && nEqnSampleCol ){ + if( p->nSample>0 && nEqnSampleCol + && OptimizationEnabled(pParse->db, SQLITE_Stat34) + ){ if( nEq==pBuilder->nRecValid ){ UnpackedRecord *pRec = pBuilder->pRec; tRowcnt a[2]; @@ -138613,7 +140822,6 @@ static int whereLoopAddBtreeIndex( if( eOp & WO_IN ){ Expr *pExpr = pTerm->pExpr; - pNew->wsFlags |= WHERE_COLUMN_IN; if( ExprHasProperty(pExpr, EP_xIsSelect) ){ /* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */ int i; @@ -138633,6 +140841,42 @@ static int whereLoopAddBtreeIndex( assert( nIn>0 ); /* RHS always has 2 or more terms... The parser ** changes "x IN (?)" into "x=?". */ } + if( pProbe->hasStat1 ){ + LogEst M, logK, safetyMargin; + /* Let: + ** N = the total number of rows in the table + ** K = the number of entries on the RHS of the IN operator + ** M = the number of rows in the table that match terms to the + ** to the left in the same index. If the IN operator is on + ** the left-most index column, M==N. + ** + ** Given the definitions above, it is better to omit the IN operator + ** from the index lookup and instead do a scan of the M elements, + ** testing each scanned row against the IN operator separately, if: + ** + ** M*log(K) < K*log(N) + ** + ** Our estimates for M, K, and N might be inaccurate, so we build in + ** a safety margin of 2 (LogEst: 10) that favors using the IN operator + ** with the index, as using an index has better worst-case behavior. + ** If we do not have real sqlite_stat1 data, always prefer to use + ** the index. + */ + M = pProbe->aiRowLogEst[saved_nEq]; + logK = estLog(nIn); + safetyMargin = 10; /* TUNING: extra weight for indexed IN */ + if( M + logK + safetyMargin < nIn + rLogSize ){ + WHERETRACE(0x40, + ("Scan preferred over IN operator on column %d of \"%s\" (%d<%d)\n", + saved_nEq, pProbe->zName, M+logK+10, nIn+rLogSize)); + continue; + }else{ + WHERETRACE(0x40, + ("IN operator preferred on column %d of \"%s\" (%d>=%d)\n", + saved_nEq, pProbe->zName, M+logK+10, nIn+rLogSize)); + } + } + pNew->wsFlags |= WHERE_COLUMN_IN; }else if( eOp & (WO_EQ|WO_IS) ){ int iCol = pProbe->aiColumn[saved_nEq]; pNew->wsFlags |= WHERE_COLUMN_EQ; @@ -138711,6 +140955,7 @@ static int whereLoopAddBtreeIndex( && pProbe->nSample && pNew->u.btree.nEq<=pProbe->nSampleCol && ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect)) + && OptimizationEnabled(db, SQLITE_Stat34) ){ Expr *pExpr = pTerm->pExpr; if( (eOp & (WO_EQ|WO_ISNULL|WO_IS))!=0 ){ @@ -138799,6 +141044,7 @@ static int whereLoopAddBtreeIndex( if( saved_nEq==saved_nSkip && saved_nEq+1nKeyCol && pProbe->noSkipScan==0 + && OptimizationEnabled(db, SQLITE_SkipScan) && pProbe->aiRowLogEst[saved_nEq+1]>=42 /* TUNING: Minimum for skip-scan */ && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK ){ @@ -138862,24 +141108,6 @@ static int indexMightHelpWithOrderBy( return 0; } -/* -** Return a bitmask where 1s indicate that the corresponding column of -** the table is used by an index. Only the first 63 columns are considered. -*/ -static Bitmask columnsInIndex(Index *pIdx){ - Bitmask m = 0; - int j; - for(j=pIdx->nColumn-1; j>=0; j--){ - int x = pIdx->aiColumn[j]; - if( x>=0 ){ - testcase( x==BMS-1 ); - testcase( x==BMS-2 ); - if( xwsFlags = WHERE_IDX_ONLY | WHERE_INDEXED; m = 0; }else{ - m = pSrc->colUsed & ~columnsInIndex(pProbe); + m = pSrc->colUsed & pProbe->colNotIdxed; pNew->wsFlags = (m==0) ? (WHERE_IDX_ONLY|WHERE_INDEXED) : WHERE_INDEXED; } @@ -139346,7 +141574,7 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int if( pX->pLeft ){ pC = sqlite3BinaryCompareCollSeq(pHidden->pParse, pX->pLeft, pX->pRight); } - zRet = (pC ? pC->zName : "BINARY"); + zRet = (pC ? pC->zName : sqlite3StrBINARY); } return zRet; } @@ -139662,7 +141890,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ { rc = whereLoopAddBtree(pBuilder, mPrereq); } - if( rc==SQLITE_OK ){ + if( rc==SQLITE_OK && pBuilder->pWC->hasOr ){ rc = whereLoopAddOr(pBuilder, mPrereq, mUnusable); } mPrior |= pNew->maskSelf; @@ -140197,7 +142425,11 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ pWInfo, nRowEst, nOrderBy, isOrdered ); } - rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]); + /* TUNING: Add a small extra penalty (5) to sorting as an + ** extra encouragment to the query planner to select a plan + ** where the rows emerge in the correct order without any sorting + ** required. */ + rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]) + 5; WHERETRACE(0x002, ("---- sort cost=%-3d (%d/%d) increases cost %3d to %-3d\n", @@ -140387,6 +142619,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; } } + pWInfo->bOrderedInnerLoop = 0; if( pWInfo->pOrderBy ){ if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){ if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){ @@ -140498,7 +142731,7 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){ } if( j!=pIdx->nKeyCol ) continue; pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW|WHERE_INDEXED; - if( pIdx->isCovering || (pItem->colUsed & ~columnsInIndex(pIdx))==0 ){ + if( pIdx->isCovering || (pItem->colUsed & pIdx->colNotIdxed)==0 ){ pLoop->wsFlags |= WHERE_IDX_ONLY; } pLoop->nLTerm = j; @@ -141178,6 +143411,26 @@ whereBeginError: return 0; } +/* +** Part of sqlite3WhereEnd() will rewrite opcodes to reference the +** index rather than the main table. In SQLITE_DEBUG mode, we want +** to trace those changes if PRAGMA vdbe_addoptrace=on. This routine +** does that. +*/ +#ifndef SQLITE_DEBUG +# define OpcodeRewriteTrace(D,K,P) /* no-op */ +#else +# define OpcodeRewriteTrace(D,K,P) sqlite3WhereOpcodeRewriteTrace(D,K,P) + static void sqlite3WhereOpcodeRewriteTrace( + sqlite3 *db, + int pc, + VdbeOp *pOp + ){ + if( (db->flags & SQLITE_VdbeAddopTrace)==0 ) return; + sqlite3VdbePrintOp(0, pc, pOp); + } +#endif + /* ** Generate the end of the WHERE loop. See comments on ** sqlite3WhereBegin() for additional information. @@ -141194,7 +143447,6 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ /* Generate loop termination code. */ VdbeModuleComment((v, "End WHERE-core")); - sqlite3ExprCacheClear(pParse); for(i=pWInfo->nLevel-1; i>=0; i--){ int addr; pLevel = &pWInfo->a[i]; @@ -141245,10 +143497,17 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){ sqlite3VdbeJumpHere(v, pIn->addrInTop+1); if( pIn->eEndLoopOp!=OP_Noop ){ + if( pIn->nPrefix ){ + assert( pLoop->wsFlags & WHERE_IN_EARLYOUT ); + sqlite3VdbeAddOp4Int(v, OP_IfNoHope, pLevel->iIdxCur, + sqlite3VdbeCurrentAddr(v)+2, + pIn->iBase, pIn->nPrefix); + VdbeCoverage(v); + } sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop); VdbeCoverage(v); - VdbeCoverageIf(v, pIn->eEndLoopOp==OP_PrevIfOpen); - VdbeCoverageIf(v, pIn->eEndLoopOp==OP_NextIfOpen); + VdbeCoverageIf(v, pIn->eEndLoopOp==OP_Prev); + VdbeCoverageIf(v, pIn->eEndLoopOp==OP_Next); } sqlite3VdbeJumpHere(v, pIn->addrInTop-1); } @@ -141339,6 +143598,11 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ ){ last = sqlite3VdbeCurrentAddr(v); k = pLevel->addrBody; +#ifdef SQLITE_DEBUG + if( db->flags & SQLITE_VdbeAddopTrace ){ + printf("TRANSLATE opcodes in range %d..%d\n", k, last-1); + } +#endif pOp = sqlite3VdbeGetOp(v, k); for(; kp1!=pLevel->iTabCur ) continue; @@ -141358,16 +143622,22 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ if( x>=0 ){ pOp->p2 = x; pOp->p1 = pLevel->iIdxCur; + OpcodeRewriteTrace(db, k, pOp); } assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0 || pWInfo->eOnePass ); }else if( pOp->opcode==OP_Rowid ){ pOp->p1 = pLevel->iIdxCur; pOp->opcode = OP_IdxRowid; + OpcodeRewriteTrace(db, k, pOp); }else if( pOp->opcode==OP_IfNullRow ){ pOp->p1 = pLevel->iIdxCur; + OpcodeRewriteTrace(db, k, pOp); } } +#ifdef SQLITE_DEBUG + if( db->flags & SQLITE_VdbeAddopTrace ) printf("TRANSLATE complete\n"); +#endif } } @@ -141379,6 +143649,2261 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ } /************** End of where.c ***********************************************/ +/************** Begin file window.c ******************************************/ +/* +** 2018 May 08 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +*/ +/* #include "sqliteInt.h" */ + +#ifndef SQLITE_OMIT_WINDOWFUNC + +/* +** SELECT REWRITING +** +** Any SELECT statement that contains one or more window functions in +** either the select list or ORDER BY clause (the only two places window +** functions may be used) is transformed by function sqlite3WindowRewrite() +** in order to support window function processing. For example, with the +** schema: +** +** CREATE TABLE t1(a, b, c, d, e, f, g); +** +** the statement: +** +** SELECT a+1, max(b) OVER (PARTITION BY c ORDER BY d) FROM t1 ORDER BY e; +** +** is transformed to: +** +** SELECT a+1, max(b) OVER (PARTITION BY c ORDER BY d) FROM ( +** SELECT a, e, c, d, b FROM t1 ORDER BY c, d +** ) ORDER BY e; +** +** The flattening optimization is disabled when processing this transformed +** SELECT statement. This allows the implementation of the window function +** (in this case max()) to process rows sorted in order of (c, d), which +** makes things easier for obvious reasons. More generally: +** +** * FROM, WHERE, GROUP BY and HAVING clauses are all moved to +** the sub-query. +** +** * ORDER BY, LIMIT and OFFSET remain part of the parent query. +** +** * Terminals from each of the expression trees that make up the +** select-list and ORDER BY expressions in the parent query are +** selected by the sub-query. For the purposes of the transformation, +** terminals are column references and aggregate functions. +** +** If there is more than one window function in the SELECT that uses +** the same window declaration (the OVER bit), then a single scan may +** be used to process more than one window function. For example: +** +** SELECT max(b) OVER (PARTITION BY c ORDER BY d), +** min(e) OVER (PARTITION BY c ORDER BY d) +** FROM t1; +** +** is transformed in the same way as the example above. However: +** +** SELECT max(b) OVER (PARTITION BY c ORDER BY d), +** min(e) OVER (PARTITION BY a ORDER BY b) +** FROM t1; +** +** Must be transformed to: +** +** SELECT max(b) OVER (PARTITION BY c ORDER BY d) FROM ( +** SELECT e, min(e) OVER (PARTITION BY a ORDER BY b), c, d, b FROM +** SELECT a, e, c, d, b FROM t1 ORDER BY a, b +** ) ORDER BY c, d +** ) ORDER BY e; +** +** so that both min() and max() may process rows in the order defined by +** their respective window declarations. +** +** INTERFACE WITH SELECT.C +** +** When processing the rewritten SELECT statement, code in select.c calls +** sqlite3WhereBegin() to begin iterating through the results of the +** sub-query, which is always implemented as a co-routine. It then calls +** sqlite3WindowCodeStep() to process rows and finish the scan by calling +** sqlite3WhereEnd(). +** +** sqlite3WindowCodeStep() generates VM code so that, for each row returned +** by the sub-query a sub-routine (OP_Gosub) coded by select.c is invoked. +** When the sub-routine is invoked: +** +** * The results of all window-functions for the row are stored +** in the associated Window.regResult registers. +** +** * The required terminal values are stored in the current row of +** temp table Window.iEphCsr. +** +** In some cases, depending on the window frame and the specific window +** functions invoked, sqlite3WindowCodeStep() caches each entire partition +** in a temp table before returning any rows. In other cases it does not. +** This detail is encapsulated within this file, the code generated by +** select.c is the same in either case. +** +** BUILT-IN WINDOW FUNCTIONS +** +** This implementation features the following built-in window functions: +** +** row_number() +** rank() +** dense_rank() +** percent_rank() +** cume_dist() +** ntile(N) +** lead(expr [, offset [, default]]) +** lag(expr [, offset [, default]]) +** first_value(expr) +** last_value(expr) +** nth_value(expr, N) +** +** These are the same built-in window functions supported by Postgres. +** Although the behaviour of aggregate window functions (functions that +** can be used as either aggregates or window funtions) allows them to +** be implemented using an API, built-in window functions are much more +** esoteric. Additionally, some window functions (e.g. nth_value()) +** may only be implemented by caching the entire partition in memory. +** As such, some built-in window functions use the same API as aggregate +** window functions and some are implemented directly using VDBE +** instructions. Additionally, for those functions that use the API, the +** window frame is sometimes modified before the SELECT statement is +** rewritten. For example, regardless of the specified window frame, the +** row_number() function always uses: +** +** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +** +** See sqlite3WindowUpdate() for details. +** +** As well as some of the built-in window functions, aggregate window +** functions min() and max() are implemented using VDBE instructions if +** the start of the window frame is declared as anything other than +** UNBOUNDED PRECEDING. +*/ + +/* +** Implementation of built-in window function row_number(). Assumes that the +** window frame has been coerced to: +** +** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +*/ +static void row_numberStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ) (*p)++; + UNUSED_PARAMETER(nArg); + UNUSED_PARAMETER(apArg); +} +static void row_numberValueFunc(sqlite3_context *pCtx){ + i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + sqlite3_result_int64(pCtx, (p ? *p : 0)); +} + +/* +** Context object type used by rank(), dense_rank(), percent_rank() and +** cume_dist(). +*/ +struct CallCount { + i64 nValue; + i64 nStep; + i64 nTotal; +}; + +/* +** Implementation of built-in window function dense_rank(). Assumes that +** the window frame has been set to: +** +** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +*/ +static void dense_rankStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct CallCount *p; + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ) p->nStep = 1; + UNUSED_PARAMETER(nArg); + UNUSED_PARAMETER(apArg); +} +static void dense_rankValueFunc(sqlite3_context *pCtx){ + struct CallCount *p; + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + if( p->nStep ){ + p->nValue++; + p->nStep = 0; + } + sqlite3_result_int64(pCtx, p->nValue); + } +} + +/* +** Implementation of built-in window function rank(). Assumes that +** the window frame has been set to: +** +** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +*/ +static void rankStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct CallCount *p; + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + p->nStep++; + if( p->nValue==0 ){ + p->nValue = p->nStep; + } + } + UNUSED_PARAMETER(nArg); + UNUSED_PARAMETER(apArg); +} +static void rankValueFunc(sqlite3_context *pCtx){ + struct CallCount *p; + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + sqlite3_result_int64(pCtx, p->nValue); + p->nValue = 0; + } +} + +/* +** Implementation of built-in window function percent_rank(). Assumes that +** the window frame has been set to: +** +** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +*/ +static void percent_rankStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct CallCount *p; + UNUSED_PARAMETER(nArg); assert( nArg==1 ); + + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + if( p->nTotal==0 ){ + p->nTotal = sqlite3_value_int64(apArg[0]); + } + p->nStep++; + if( p->nValue==0 ){ + p->nValue = p->nStep; + } + } +} +static void percent_rankValueFunc(sqlite3_context *pCtx){ + struct CallCount *p; + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + if( p->nTotal>1 ){ + double r = (double)(p->nValue-1) / (double)(p->nTotal-1); + sqlite3_result_double(pCtx, r); + }else{ + sqlite3_result_double(pCtx, 0.0); + } + p->nValue = 0; + } +} + +/* +** Implementation of built-in window function cume_dist(). Assumes that +** the window frame has been set to: +** +** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +*/ +static void cume_distStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct CallCount *p; + assert( nArg==1 ); UNUSED_PARAMETER(nArg); + + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + if( p->nTotal==0 ){ + p->nTotal = sqlite3_value_int64(apArg[0]); + } + p->nStep++; + } +} +static void cume_distValueFunc(sqlite3_context *pCtx){ + struct CallCount *p; + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p && p->nTotal ){ + double r = (double)(p->nStep) / (double)(p->nTotal); + sqlite3_result_double(pCtx, r); + } +} + +/* +** Context object for ntile() window function. +*/ +struct NtileCtx { + i64 nTotal; /* Total rows in partition */ + i64 nParam; /* Parameter passed to ntile(N) */ + i64 iRow; /* Current row */ +}; + +/* +** Implementation of ntile(). This assumes that the window frame has +** been coerced to: +** +** ROWS UNBOUNDED PRECEDING AND CURRENT ROW +*/ +static void ntileStepFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct NtileCtx *p; + assert( nArg==2 ); UNUSED_PARAMETER(nArg); + p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p ){ + if( p->nTotal==0 ){ + p->nParam = sqlite3_value_int64(apArg[0]); + p->nTotal = sqlite3_value_int64(apArg[1]); + if( p->nParam<=0 ){ + sqlite3_result_error( + pCtx, "argument of ntile must be a positive integer", -1 + ); + } + } + p->iRow++; + } +} +static void ntileValueFunc(sqlite3_context *pCtx){ + struct NtileCtx *p; + p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p && p->nParam>0 ){ + int nSize = (p->nTotal / p->nParam); + if( nSize==0 ){ + sqlite3_result_int64(pCtx, p->iRow); + }else{ + i64 nLarge = p->nTotal - p->nParam*nSize; + i64 iSmall = nLarge*(nSize+1); + i64 iRow = p->iRow-1; + + assert( (nLarge*(nSize+1) + (p->nParam-nLarge)*nSize)==p->nTotal ); + + if( iRowpVal); + p->pVal = sqlite3_value_dup(apArg[0]); + if( p->pVal==0 ){ + sqlite3_result_error_nomem(pCtx); + }else{ + p->nVal++; + } + } +} +static void last_valueInvFunc( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **apArg +){ + struct LastValueCtx *p; + UNUSED_PARAMETER(nArg); + UNUSED_PARAMETER(apArg); + p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( ALWAYS(p) ){ + p->nVal--; + if( p->nVal==0 ){ + sqlite3_value_free(p->pVal); + p->pVal = 0; + } + } +} +static void last_valueValueFunc(sqlite3_context *pCtx){ + struct LastValueCtx *p; + p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p && p->pVal ){ + sqlite3_result_value(pCtx, p->pVal); + } +} +static void last_valueFinalizeFunc(sqlite3_context *pCtx){ + struct LastValueCtx *p; + p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p && p->pVal ){ + sqlite3_result_value(pCtx, p->pVal); + sqlite3_value_free(p->pVal); + p->pVal = 0; + } +} + +/* +** Static names for the built-in window function names. These static +** names are used, rather than string literals, so that FuncDef objects +** can be associated with a particular window function by direct +** comparison of the zName pointer. Example: +** +** if( pFuncDef->zName==row_valueName ){ ... } +*/ +static const char row_numberName[] = "row_number"; +static const char dense_rankName[] = "dense_rank"; +static const char rankName[] = "rank"; +static const char percent_rankName[] = "percent_rank"; +static const char cume_distName[] = "cume_dist"; +static const char ntileName[] = "ntile"; +static const char last_valueName[] = "last_value"; +static const char nth_valueName[] = "nth_value"; +static const char first_valueName[] = "first_value"; +static const char leadName[] = "lead"; +static const char lagName[] = "lag"; + +/* +** No-op implementations of xStep() and xFinalize(). Used as place-holders +** for built-in window functions that never call those interfaces. +** +** The noopValueFunc() is called but is expected to do nothing. The +** noopStepFunc() is never called, and so it is marked with NO_TEST to +** let the test coverage routine know not to expect this function to be +** invoked. +*/ +static void noopStepFunc( /*NO_TEST*/ + sqlite3_context *p, /*NO_TEST*/ + int n, /*NO_TEST*/ + sqlite3_value **a /*NO_TEST*/ +){ /*NO_TEST*/ + UNUSED_PARAMETER(p); /*NO_TEST*/ + UNUSED_PARAMETER(n); /*NO_TEST*/ + UNUSED_PARAMETER(a); /*NO_TEST*/ + assert(0); /*NO_TEST*/ +} /*NO_TEST*/ +static void noopValueFunc(sqlite3_context *p){ UNUSED_PARAMETER(p); /*no-op*/ } + +/* Window functions that use all window interfaces: xStep, xFinal, +** xValue, and xInverse */ +#define WINDOWFUNCALL(name,nArg,extra) { \ + nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \ + name ## StepFunc, name ## FinalizeFunc, name ## ValueFunc, \ + name ## InvFunc, name ## Name, {0} \ +} + +/* Window functions that are implemented using bytecode and thus have +** no-op routines for their methods */ +#define WINDOWFUNCNOOP(name,nArg,extra) { \ + nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \ + noopStepFunc, noopValueFunc, noopValueFunc, \ + noopStepFunc, name ## Name, {0} \ +} + +/* Window functions that use all window interfaces: xStep, the +** same routine for xFinalize and xValue and which never call +** xInverse. */ +#define WINDOWFUNCX(name,nArg,extra) { \ + nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \ + name ## StepFunc, name ## ValueFunc, name ## ValueFunc, \ + noopStepFunc, name ## Name, {0} \ +} + + +/* +** Register those built-in window functions that are not also aggregates. +*/ +SQLITE_PRIVATE void sqlite3WindowFunctions(void){ + static FuncDef aWindowFuncs[] = { + WINDOWFUNCX(row_number, 0, 0), + WINDOWFUNCX(dense_rank, 0, 0), + WINDOWFUNCX(rank, 0, 0), + WINDOWFUNCX(percent_rank, 0, SQLITE_FUNC_WINDOW_SIZE), + WINDOWFUNCX(cume_dist, 0, SQLITE_FUNC_WINDOW_SIZE), + WINDOWFUNCX(ntile, 1, SQLITE_FUNC_WINDOW_SIZE), + WINDOWFUNCALL(last_value, 1, 0), + WINDOWFUNCNOOP(nth_value, 2, 0), + WINDOWFUNCNOOP(first_value, 1, 0), + WINDOWFUNCNOOP(lead, 1, 0), + WINDOWFUNCNOOP(lead, 2, 0), + WINDOWFUNCNOOP(lead, 3, 0), + WINDOWFUNCNOOP(lag, 1, 0), + WINDOWFUNCNOOP(lag, 2, 0), + WINDOWFUNCNOOP(lag, 3, 0), + }; + sqlite3InsertBuiltinFuncs(aWindowFuncs, ArraySize(aWindowFuncs)); +} + +/* +** This function is called immediately after resolving the function name +** for a window function within a SELECT statement. Argument pList is a +** linked list of WINDOW definitions for the current SELECT statement. +** Argument pFunc is the function definition just resolved and pWin +** is the Window object representing the associated OVER clause. This +** function updates the contents of pWin as follows: +** +** * If the OVER clause refered to a named window (as in "max(x) OVER win"), +** search list pList for a matching WINDOW definition, and update pWin +** accordingly. If no such WINDOW clause can be found, leave an error +** in pParse. +** +** * If the function is a built-in window function that requires the +** window to be coerced (see "BUILT-IN WINDOW FUNCTIONS" at the top +** of this file), pWin is updated here. +*/ +SQLITE_PRIVATE void sqlite3WindowUpdate( + Parse *pParse, + Window *pList, /* List of named windows for this SELECT */ + Window *pWin, /* Window frame to update */ + FuncDef *pFunc /* Window function definition */ +){ + if( pWin->zName && pWin->eType==0 ){ + Window *p; + for(p=pList; p; p=p->pNextWin){ + if( sqlite3StrICmp(p->zName, pWin->zName)==0 ) break; + } + if( p==0 ){ + sqlite3ErrorMsg(pParse, "no such window: %s", pWin->zName); + return; + } + pWin->pPartition = sqlite3ExprListDup(pParse->db, p->pPartition, 0); + pWin->pOrderBy = sqlite3ExprListDup(pParse->db, p->pOrderBy, 0); + pWin->pStart = sqlite3ExprDup(pParse->db, p->pStart, 0); + pWin->pEnd = sqlite3ExprDup(pParse->db, p->pEnd, 0); + pWin->eStart = p->eStart; + pWin->eEnd = p->eEnd; + pWin->eType = p->eType; + } + if( pFunc->funcFlags & SQLITE_FUNC_WINDOW ){ + sqlite3 *db = pParse->db; + if( pWin->pFilter ){ + sqlite3ErrorMsg(pParse, + "FILTER clause may only be used with aggregate window functions" + ); + }else + if( pFunc->zName==row_numberName || pFunc->zName==ntileName ){ + sqlite3ExprDelete(db, pWin->pStart); + sqlite3ExprDelete(db, pWin->pEnd); + pWin->pStart = pWin->pEnd = 0; + pWin->eType = TK_ROWS; + pWin->eStart = TK_UNBOUNDED; + pWin->eEnd = TK_CURRENT; + }else + + if( pFunc->zName==dense_rankName || pFunc->zName==rankName + || pFunc->zName==percent_rankName || pFunc->zName==cume_distName + ){ + sqlite3ExprDelete(db, pWin->pStart); + sqlite3ExprDelete(db, pWin->pEnd); + pWin->pStart = pWin->pEnd = 0; + pWin->eType = TK_RANGE; + pWin->eStart = TK_UNBOUNDED; + pWin->eEnd = TK_CURRENT; + } + } + pWin->pFunc = pFunc; +} + +/* +** Context object passed through sqlite3WalkExprList() to +** selectWindowRewriteExprCb() by selectWindowRewriteEList(). +*/ +typedef struct WindowRewrite WindowRewrite; +struct WindowRewrite { + Window *pWin; + SrcList *pSrc; + ExprList *pSub; + Select *pSubSelect; /* Current sub-select, if any */ +}; + +/* +** Callback function used by selectWindowRewriteEList(). If necessary, +** this function appends to the output expression-list and updates +** expression (*ppExpr) in place. +*/ +static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){ + struct WindowRewrite *p = pWalker->u.pRewrite; + Parse *pParse = pWalker->pParse; + + /* If this function is being called from within a scalar sub-select + ** that used by the SELECT statement being processed, only process + ** TK_COLUMN expressions that refer to it (the outer SELECT). Do + ** not process aggregates or window functions at all, as they belong + ** to the scalar sub-select. */ + if( p->pSubSelect ){ + if( pExpr->op!=TK_COLUMN ){ + return WRC_Continue; + }else{ + int nSrc = p->pSrc->nSrc; + int i; + for(i=0; iiTable==p->pSrc->a[i].iCursor ) break; + } + if( i==nSrc ) return WRC_Continue; + } + } + + switch( pExpr->op ){ + + case TK_FUNCTION: + if( pExpr->pWin==0 ){ + break; + }else{ + Window *pWin; + for(pWin=p->pWin; pWin; pWin=pWin->pNextWin){ + if( pExpr->pWin==pWin ){ + assert( pWin->pOwner==pExpr ); + return WRC_Prune; + } + } + } + /* Fall through. */ + + case TK_AGG_FUNCTION: + case TK_COLUMN: { + Expr *pDup = sqlite3ExprDup(pParse->db, pExpr, 0); + p->pSub = sqlite3ExprListAppend(pParse, p->pSub, pDup); + if( p->pSub ){ + assert( ExprHasProperty(pExpr, EP_Static)==0 ); + ExprSetProperty(pExpr, EP_Static); + sqlite3ExprDelete(pParse->db, pExpr); + ExprClearProperty(pExpr, EP_Static); + memset(pExpr, 0, sizeof(Expr)); + + pExpr->op = TK_COLUMN; + pExpr->iColumn = p->pSub->nExpr-1; + pExpr->iTable = p->pWin->iEphCsr; + } + + break; + } + + default: /* no-op */ + break; + } + + return WRC_Continue; +} +static int selectWindowRewriteSelectCb(Walker *pWalker, Select *pSelect){ + struct WindowRewrite *p = pWalker->u.pRewrite; + Select *pSave = p->pSubSelect; + if( pSave==pSelect ){ + return WRC_Continue; + }else{ + p->pSubSelect = pSelect; + sqlite3WalkSelect(pWalker, pSelect); + p->pSubSelect = pSave; + } + return WRC_Prune; +} + + +/* +** Iterate through each expression in expression-list pEList. For each: +** +** * TK_COLUMN, +** * aggregate function, or +** * window function with a Window object that is not a member of the +** Window list passed as the second argument (pWin). +** +** Append the node to output expression-list (*ppSub). And replace it +** with a TK_COLUMN that reads the (N-1)th element of table +** pWin->iEphCsr, where N is the number of elements in (*ppSub) after +** appending the new one. +*/ +static void selectWindowRewriteEList( + Parse *pParse, + Window *pWin, + SrcList *pSrc, + ExprList *pEList, /* Rewrite expressions in this list */ + ExprList **ppSub /* IN/OUT: Sub-select expression-list */ +){ + Walker sWalker; + WindowRewrite sRewrite; + + memset(&sWalker, 0, sizeof(Walker)); + memset(&sRewrite, 0, sizeof(WindowRewrite)); + + sRewrite.pSub = *ppSub; + sRewrite.pWin = pWin; + sRewrite.pSrc = pSrc; + + sWalker.pParse = pParse; + sWalker.xExprCallback = selectWindowRewriteExprCb; + sWalker.xSelectCallback = selectWindowRewriteSelectCb; + sWalker.u.pRewrite = &sRewrite; + + (void)sqlite3WalkExprList(&sWalker, pEList); + + *ppSub = sRewrite.pSub; +} + +/* +** Append a copy of each expression in expression-list pAppend to +** expression list pList. Return a pointer to the result list. +*/ +static ExprList *exprListAppendList( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* List to which to append. Might be NULL */ + ExprList *pAppend /* List of values to append. Might be NULL */ +){ + if( pAppend ){ + int i; + int nInit = pList ? pList->nExpr : 0; + for(i=0; inExpr; i++){ + Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0); + pList = sqlite3ExprListAppend(pParse, pList, pDup); + if( pList ) pList->a[nInit+i].sortOrder = pAppend->a[i].sortOrder; + } + } + return pList; +} + +/* +** If the SELECT statement passed as the second argument does not invoke +** any SQL window functions, this function is a no-op. Otherwise, it +** rewrites the SELECT statement so that window function xStep functions +** are invoked in the correct order as described under "SELECT REWRITING" +** at the top of this file. +*/ +SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ + int rc = SQLITE_OK; + if( p->pWin ){ + Vdbe *v = sqlite3GetVdbe(pParse); + sqlite3 *db = pParse->db; + Select *pSub = 0; /* The subquery */ + SrcList *pSrc = p->pSrc; + Expr *pWhere = p->pWhere; + ExprList *pGroupBy = p->pGroupBy; + Expr *pHaving = p->pHaving; + ExprList *pSort = 0; + + ExprList *pSublist = 0; /* Expression list for sub-query */ + Window *pMWin = p->pWin; /* Master window object */ + Window *pWin; /* Window object iterator */ + + p->pSrc = 0; + p->pWhere = 0; + p->pGroupBy = 0; + p->pHaving = 0; + + /* Create the ORDER BY clause for the sub-select. This is the concatenation + ** of the window PARTITION and ORDER BY clauses. Then, if this makes it + ** redundant, remove the ORDER BY from the parent SELECT. */ + pSort = sqlite3ExprListDup(db, pMWin->pPartition, 0); + pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy); + if( pSort && p->pOrderBy ){ + if( sqlite3ExprListCompare(pSort, p->pOrderBy, -1)==0 ){ + sqlite3ExprListDelete(db, p->pOrderBy); + p->pOrderBy = 0; + } + } + + /* Assign a cursor number for the ephemeral table used to buffer rows. + ** The OpenEphemeral instruction is coded later, after it is known how + ** many columns the table will have. */ + pMWin->iEphCsr = pParse->nTab++; + + selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, &pSublist); + selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, &pSublist); + pMWin->nBufferCol = (pSublist ? pSublist->nExpr : 0); + + /* Append the PARTITION BY and ORDER BY expressions to the to the + ** sub-select expression list. They are required to figure out where + ** boundaries for partitions and sets of peer rows lie. */ + pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition); + pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy); + + /* Append the arguments passed to each window function to the + ** sub-select expression list. Also allocate two registers for each + ** window function - one for the accumulator, another for interim + ** results. */ + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + pWin->iArgCol = (pSublist ? pSublist->nExpr : 0); + pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList); + if( pWin->pFilter ){ + Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0); + pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter); + } + pWin->regAccum = ++pParse->nMem; + pWin->regResult = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); + } + + /* If there is no ORDER BY or PARTITION BY clause, and the window + ** function accepts zero arguments, and there are no other columns + ** selected (e.g. "SELECT row_number() OVER () FROM t1"), it is possible + ** that pSublist is still NULL here. Add a constant expression here to + ** keep everything legal in this case. + */ + if( pSublist==0 ){ + pSublist = sqlite3ExprListAppend(pParse, 0, + sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0) + ); + } + + pSub = sqlite3SelectNew( + pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0 + ); + p->pSrc = sqlite3SrcListAppend(db, 0, 0, 0); + assert( p->pSrc || db->mallocFailed ); + if( p->pSrc ){ + p->pSrc->a[0].pSelect = pSub; + sqlite3SrcListAssignCursors(pParse, p->pSrc); + if( sqlite3ExpandSubquery(pParse, &p->pSrc->a[0]) ){ + rc = SQLITE_NOMEM; + }else{ + pSub->selFlags |= SF_Expanded; + p->selFlags &= ~SF_Aggregate; + sqlite3SelectPrep(pParse, pSub, 0); + } + + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, pSublist->nExpr); + }else{ + sqlite3SelectDelete(db, pSub); + } + if( db->mallocFailed ) rc = SQLITE_NOMEM; + } + + return rc; +} + +/* +** Free the Window object passed as the second argument. +*/ +SQLITE_PRIVATE void sqlite3WindowDelete(sqlite3 *db, Window *p){ + if( p ){ + sqlite3ExprDelete(db, p->pFilter); + sqlite3ExprListDelete(db, p->pPartition); + sqlite3ExprListDelete(db, p->pOrderBy); + sqlite3ExprDelete(db, p->pEnd); + sqlite3ExprDelete(db, p->pStart); + sqlite3DbFree(db, p->zName); + sqlite3DbFree(db, p); + } +} + +/* +** Free the linked list of Window objects starting at the second argument. +*/ +SQLITE_PRIVATE void sqlite3WindowListDelete(sqlite3 *db, Window *p){ + while( p ){ + Window *pNext = p->pNextWin; + sqlite3WindowDelete(db, p); + p = pNext; + } +} + +/* +** The argument expression is an PRECEDING or FOLLOWING offset. The +** value should be a non-negative integer. If the value is not a +** constant, change it to NULL. The fact that it is then a non-negative +** integer will be caught later. But it is important not to leave +** variable values in the expression tree. +*/ +static Expr *sqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){ + if( 0==sqlite3ExprIsConstant(pExpr) ){ + sqlite3ExprDelete(pParse->db, pExpr); + pExpr = sqlite3ExprAlloc(pParse->db, TK_NULL, 0, 0); + } + return pExpr; +} + +/* +** Allocate and return a new Window object describing a Window Definition. +*/ +SQLITE_PRIVATE Window *sqlite3WindowAlloc( + Parse *pParse, /* Parsing context */ + int eType, /* Frame type. TK_RANGE or TK_ROWS */ + int eStart, /* Start type: CURRENT, PRECEDING, FOLLOWING, UNBOUNDED */ + Expr *pStart, /* Start window size if TK_PRECEDING or FOLLOWING */ + int eEnd, /* End type: CURRENT, FOLLOWING, TK_UNBOUNDED, PRECEDING */ + Expr *pEnd /* End window size if TK_FOLLOWING or PRECEDING */ +){ + Window *pWin = 0; + + /* Parser assures the following: */ + assert( eType==TK_RANGE || eType==TK_ROWS ); + assert( eStart==TK_CURRENT || eStart==TK_PRECEDING + || eStart==TK_UNBOUNDED || eStart==TK_FOLLOWING ); + assert( eEnd==TK_CURRENT || eEnd==TK_FOLLOWING + || eEnd==TK_UNBOUNDED || eEnd==TK_PRECEDING ); + assert( (eStart==TK_PRECEDING || eStart==TK_FOLLOWING)==(pStart!=0) ); + assert( (eEnd==TK_FOLLOWING || eEnd==TK_PRECEDING)==(pEnd!=0) ); + + + /* If a frame is declared "RANGE" (not "ROWS"), then it may not use + ** either " PRECEDING" or " FOLLOWING". + */ + if( eType==TK_RANGE && (pStart!=0 || pEnd!=0) ){ + sqlite3ErrorMsg(pParse, "RANGE must use only UNBOUNDED or CURRENT ROW"); + goto windowAllocErr; + } + + /* Additionally, the + ** starting boundary type may not occur earlier in the following list than + ** the ending boundary type: + ** + ** UNBOUNDED PRECEDING + ** PRECEDING + ** CURRENT ROW + ** FOLLOWING + ** UNBOUNDED FOLLOWING + ** + ** The parser ensures that "UNBOUNDED PRECEDING" cannot be used as an ending + ** boundary, and than "UNBOUNDED FOLLOWING" cannot be used as a starting + ** frame boundary. + */ + if( (eStart==TK_CURRENT && eEnd==TK_PRECEDING) + || (eStart==TK_FOLLOWING && (eEnd==TK_PRECEDING || eEnd==TK_CURRENT)) + ){ + sqlite3ErrorMsg(pParse, "unsupported frame delimiter for ROWS"); + goto windowAllocErr; + } + + pWin = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); + if( pWin==0 ) goto windowAllocErr; + pWin->eType = eType; + pWin->eStart = eStart; + pWin->eEnd = eEnd; + pWin->pEnd = sqlite3WindowOffsetExpr(pParse, pEnd); + pWin->pStart = sqlite3WindowOffsetExpr(pParse, pStart); + return pWin; + +windowAllocErr: + sqlite3ExprDelete(pParse->db, pEnd); + sqlite3ExprDelete(pParse->db, pStart); + return 0; +} + +/* +** Attach window object pWin to expression p. +*/ +SQLITE_PRIVATE void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){ + if( p ){ + /* This routine is only called for the parser. If pWin was not + ** allocated due to an OOM, then the parser would fail before ever + ** invoking this routine */ + if( ALWAYS(pWin) ){ + p->pWin = pWin; + pWin->pOwner = p; + if( p->flags & EP_Distinct ){ + sqlite3ErrorMsg(pParse, + "DISTINCT is not supported for window functions"); + } + } + }else{ + sqlite3WindowDelete(pParse->db, pWin); + } +} + +/* +** Return 0 if the two window objects are identical, or non-zero otherwise. +** Identical window objects can be processed in a single scan. +*/ +SQLITE_PRIVATE int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2){ + if( p1->eType!=p2->eType ) return 1; + if( p1->eStart!=p2->eStart ) return 1; + if( p1->eEnd!=p2->eEnd ) return 1; + if( sqlite3ExprCompare(pParse, p1->pStart, p2->pStart, -1) ) return 1; + if( sqlite3ExprCompare(pParse, p1->pEnd, p2->pEnd, -1) ) return 1; + if( sqlite3ExprListCompare(p1->pPartition, p2->pPartition, -1) ) return 1; + if( sqlite3ExprListCompare(p1->pOrderBy, p2->pOrderBy, -1) ) return 1; + return 0; +} + + +/* +** This is called by code in select.c before it calls sqlite3WhereBegin() +** to begin iterating through the sub-query results. It is used to allocate +** and initialize registers and cursors used by sqlite3WindowCodeStep(). +*/ +SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse *pParse, Window *pMWin){ + Window *pWin; + Vdbe *v = sqlite3GetVdbe(pParse); + int nPart = (pMWin->pPartition ? pMWin->pPartition->nExpr : 0); + nPart += (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0); + if( nPart ){ + pMWin->regPart = pParse->nMem+1; + pParse->nMem += nPart; + sqlite3VdbeAddOp3(v, OP_Null, 0, pMWin->regPart, pMWin->regPart+nPart-1); + } + + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + FuncDef *p = pWin->pFunc; + if( (p->funcFlags & SQLITE_FUNC_MINMAX) && pWin->eStart!=TK_UNBOUNDED ){ + /* The inline versions of min() and max() require a single ephemeral + ** table and 3 registers. The registers are used as follows: + ** + ** regApp+0: slot to copy min()/max() argument to for MakeRecord + ** regApp+1: integer value used to ensure keys are unique + ** regApp+2: output of MakeRecord + */ + ExprList *pList = pWin->pOwner->x.pList; + KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0); + pWin->csrApp = pParse->nTab++; + pWin->regApp = pParse->nMem+1; + pParse->nMem += 3; + if( pKeyInfo && pWin->pFunc->zName[1]=='i' ){ + assert( pKeyInfo->aSortOrder[0]==0 ); + pKeyInfo->aSortOrder[0] = 1; + } + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2); + sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1); + } + else if( p->zName==nth_valueName || p->zName==first_valueName ){ + /* Allocate two registers at pWin->regApp. These will be used to + ** store the start and end index of the current frame. */ + assert( pMWin->iEphCsr ); + pWin->regApp = pParse->nMem+1; + pWin->csrApp = pParse->nTab++; + pParse->nMem += 2; + sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr); + } + else if( p->zName==leadName || p->zName==lagName ){ + assert( pMWin->iEphCsr ); + pWin->csrApp = pParse->nTab++; + sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr); + } + } +} + +/* +** A "PRECEDING " (eCond==0) or "FOLLOWING " (eCond==1) or the +** value of the second argument to nth_value() (eCond==2) has just been +** evaluated and the result left in register reg. This function generates VM +** code to check that the value is a non-negative integer and throws an +** exception if it is not. +*/ +static void windowCheckIntValue(Parse *pParse, int reg, int eCond){ + static const char *azErr[] = { + "frame starting offset must be a non-negative integer", + "frame ending offset must be a non-negative integer", + "second argument to nth_value must be a positive integer" + }; + static int aOp[] = { OP_Ge, OP_Ge, OP_Gt }; + Vdbe *v = sqlite3GetVdbe(pParse); + int regZero = sqlite3GetTempReg(pParse); + assert( eCond==0 || eCond==1 || eCond==2 ); + sqlite3VdbeAddOp2(v, OP_Integer, 0, regZero); + sqlite3VdbeAddOp2(v, OP_MustBeInt, reg, sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverageIf(v, eCond==0); + VdbeCoverageIf(v, eCond==1); + VdbeCoverageIf(v, eCond==2); + sqlite3VdbeAddOp3(v, aOp[eCond], regZero, sqlite3VdbeCurrentAddr(v)+2, reg); + VdbeCoverageNeverNullIf(v, eCond==0); + VdbeCoverageNeverNullIf(v, eCond==1); + VdbeCoverageNeverNullIf(v, eCond==2); + sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_ERROR, OE_Abort); + sqlite3VdbeAppendP4(v, (void*)azErr[eCond], P4_STATIC); + sqlite3ReleaseTempReg(pParse, regZero); +} + +/* +** Return the number of arguments passed to the window-function associated +** with the object passed as the only argument to this function. +*/ +static int windowArgCount(Window *pWin){ + ExprList *pList = pWin->pOwner->x.pList; + return (pList ? pList->nExpr : 0); +} + +/* +** Generate VM code to invoke either xStep() (if bInverse is 0) or +** xInverse (if bInverse is non-zero) for each window function in the +** linked list starting at pMWin. Or, for built-in window functions +** that do not use the standard function API, generate the required +** inline VM code. +** +** If argument csr is greater than or equal to 0, then argument reg is +** the first register in an array of registers guaranteed to be large +** enough to hold the array of arguments for each function. In this case +** the arguments are extracted from the current row of csr into the +** array of registers before invoking OP_AggStep or OP_AggInverse +** +** Or, if csr is less than zero, then the array of registers at reg is +** already populated with all columns from the current row of the sub-query. +** +** If argument regPartSize is non-zero, then it is a register containing the +** number of rows in the current partition. +*/ +static void windowAggStep( + Parse *pParse, + Window *pMWin, /* Linked list of window functions */ + int csr, /* Read arguments from this cursor */ + int bInverse, /* True to invoke xInverse instead of xStep */ + int reg, /* Array of registers */ + int regPartSize /* Register containing size of partition */ +){ + Vdbe *v = sqlite3GetVdbe(pParse); + Window *pWin; + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + int flags = pWin->pFunc->funcFlags; + int regArg; + int nArg = windowArgCount(pWin); + + if( csr>=0 ){ + int i; + for(i=0; iiArgCol+i, reg+i); + } + regArg = reg; + if( flags & SQLITE_FUNC_WINDOW_SIZE ){ + if( nArg==0 ){ + regArg = regPartSize; + }else{ + sqlite3VdbeAddOp2(v, OP_SCopy, regPartSize, reg+nArg); + } + nArg++; + } + }else{ + assert( !(flags & SQLITE_FUNC_WINDOW_SIZE) ); + regArg = reg + pWin->iArgCol; + } + + if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX) + && pWin->eStart!=TK_UNBOUNDED + ){ + int addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regArg); + VdbeCoverage(v); + if( bInverse==0 ){ + sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1, 1); + sqlite3VdbeAddOp2(v, OP_SCopy, regArg, pWin->regApp); + sqlite3VdbeAddOp3(v, OP_MakeRecord, pWin->regApp, 2, pWin->regApp+2); + sqlite3VdbeAddOp2(v, OP_IdxInsert, pWin->csrApp, pWin->regApp+2); + }else{ + sqlite3VdbeAddOp4Int(v, OP_SeekGE, pWin->csrApp, 0, regArg, 1); + VdbeCoverageNeverTaken(v); + sqlite3VdbeAddOp1(v, OP_Delete, pWin->csrApp); + sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); + } + sqlite3VdbeJumpHere(v, addrIsNull); + }else if( pWin->regApp ){ + assert( pWin->pFunc->zName==nth_valueName + || pWin->pFunc->zName==first_valueName + ); + assert( bInverse==0 || bInverse==1 ); + sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1); + }else if( pWin->pFunc->zName==leadName + || pWin->pFunc->zName==lagName + ){ + /* no-op */ + }else{ + int addrIf = 0; + if( pWin->pFilter ){ + int regTmp; + assert( nArg==0 || nArg==pWin->pOwner->x.pList->nExpr ); + assert( nArg || pWin->pOwner->x.pList==0 ); + if( csr>0 ){ + regTmp = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp); + }else{ + regTmp = regArg + nArg; + } + addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1); + VdbeCoverage(v); + if( csr>0 ){ + sqlite3ReleaseTempReg(pParse, regTmp); + } + } + if( pWin->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ + CollSeq *pColl; + assert( nArg>0 ); + pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr); + sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ); + } + sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep, + bInverse, regArg, pWin->regAccum); + sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, (u8)nArg); + if( addrIf ) sqlite3VdbeJumpHere(v, addrIf); + } + } +} + +/* +** Generate VM code to invoke either xValue() (bFinal==0) or xFinalize() +** (bFinal==1) for each window function in the linked list starting at +** pMWin. Or, for built-in window-functions that do not use the standard +** API, generate the equivalent VM code. +*/ +static void windowAggFinal(Parse *pParse, Window *pMWin, int bFinal){ + Vdbe *v = sqlite3GetVdbe(pParse); + Window *pWin; + + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX) + && pWin->eStart!=TK_UNBOUNDED + ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult); + sqlite3VdbeAddOp1(v, OP_Last, pWin->csrApp); + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_Column, pWin->csrApp, 0, pWin->regResult); + sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); + if( bFinal ){ + sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp); + } + }else if( pWin->regApp ){ + }else{ + if( bFinal ){ + sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, windowArgCount(pWin)); + sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF); + sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult); + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); + }else{ + sqlite3VdbeAddOp3(v, OP_AggValue, pWin->regAccum, windowArgCount(pWin), + pWin->regResult); + sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF); + } + } + } +} + +/* +** This function generates VM code to invoke the sub-routine at address +** lblFlushPart once for each partition with the entire partition cached in +** the Window.iEphCsr temp table. +*/ +static void windowPartitionCache( + Parse *pParse, + Select *p, /* The rewritten SELECT statement */ + WhereInfo *pWInfo, /* WhereInfo to call WhereEnd() on */ + int regFlushPart, /* Register to use with Gosub lblFlushPart */ + int lblFlushPart, /* Subroutine to Gosub to */ + int *pRegSize /* OUT: Register containing partition size */ +){ + Window *pMWin = p->pWin; + Vdbe *v = sqlite3GetVdbe(pParse); + int iSubCsr = p->pSrc->a[0].iCursor; + int nSub = p->pSrc->a[0].pTab->nCol; + int k; + + int reg = pParse->nMem+1; + int regRecord = reg+nSub; + int regRowid = regRecord+1; + + *pRegSize = regRowid; + pParse->nMem += nSub + 2; + + /* Load the column values for the row returned by the sub-select + ** into an array of registers starting at reg. */ + for(k=0; kpPartition ){ + int addr; + ExprList *pPart = pMWin->pPartition; + int nPart = pPart->nExpr; + int regNewPart = reg + pMWin->nBufferCol; + KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0); + + addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart,nPart); + sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO); + sqlite3VdbeAddOp3(v, OP_Jump, addr+2, addr+4, addr+2); + VdbeCoverageEqNe(v); + sqlite3VdbeAddOp3(v, OP_Copy, regNewPart, pMWin->regPart, nPart-1); + sqlite3VdbeAddOp2(v, OP_Gosub, regFlushPart, lblFlushPart); + VdbeComment((v, "call flush_partition")); + } + + /* Buffer the current row in the ephemeral table. */ + sqlite3VdbeAddOp2(v, OP_NewRowid, pMWin->iEphCsr, regRowid); + sqlite3VdbeAddOp3(v, OP_Insert, pMWin->iEphCsr, regRecord, regRowid); + + /* End of the input loop */ + sqlite3WhereEnd(pWInfo); + + /* Invoke "flush_partition" to deal with the final (or only) partition */ + sqlite3VdbeAddOp2(v, OP_Gosub, regFlushPart, lblFlushPart); + VdbeComment((v, "call flush_partition")); +} + +/* +** Invoke the sub-routine at regGosub (generated by code in select.c) to +** return the current row of Window.iEphCsr. If all window functions are +** aggregate window functions that use the standard API, a single +** OP_Gosub instruction is all that this routine generates. Extra VM code +** for per-row processing is only generated for the following built-in window +** functions: +** +** nth_value() +** first_value() +** lag() +** lead() +*/ +static void windowReturnOneRow( + Parse *pParse, + Window *pMWin, + int regGosub, + int addrGosub +){ + Vdbe *v = sqlite3GetVdbe(pParse); + Window *pWin; + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + FuncDef *pFunc = pWin->pFunc; + if( pFunc->zName==nth_valueName + || pFunc->zName==first_valueName + ){ + int csr = pWin->csrApp; + int lbl = sqlite3VdbeMakeLabel(v); + int tmpReg = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult); + + if( pFunc->zName==nth_valueName ){ + sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+1,tmpReg); + windowCheckIntValue(pParse, tmpReg, 2); + }else{ + sqlite3VdbeAddOp2(v, OP_Integer, 1, tmpReg); + } + sqlite3VdbeAddOp3(v, OP_Add, tmpReg, pWin->regApp, tmpReg); + sqlite3VdbeAddOp3(v, OP_Gt, pWin->regApp+1, lbl, tmpReg); + VdbeCoverageNeverNull(v); + sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, 0, tmpReg); + VdbeCoverageNeverTaken(v); + sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult); + sqlite3VdbeResolveLabel(v, lbl); + sqlite3ReleaseTempReg(pParse, tmpReg); + } + else if( pFunc->zName==leadName || pFunc->zName==lagName ){ + int nArg = pWin->pOwner->x.pList->nExpr; + int iEph = pMWin->iEphCsr; + int csr = pWin->csrApp; + int lbl = sqlite3VdbeMakeLabel(v); + int tmpReg = sqlite3GetTempReg(pParse); + + if( nArg<3 ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult); + }else{ + sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+2, pWin->regResult); + } + sqlite3VdbeAddOp2(v, OP_Rowid, iEph, tmpReg); + if( nArg<2 ){ + int val = (pFunc->zName==leadName ? 1 : -1); + sqlite3VdbeAddOp2(v, OP_AddImm, tmpReg, val); + }else{ + int op = (pFunc->zName==leadName ? OP_Add : OP_Subtract); + int tmpReg2 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+1, tmpReg2); + sqlite3VdbeAddOp3(v, op, tmpReg2, tmpReg, tmpReg); + sqlite3ReleaseTempReg(pParse, tmpReg2); + } + + sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, lbl, tmpReg); + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult); + sqlite3VdbeResolveLabel(v, lbl); + sqlite3ReleaseTempReg(pParse, tmpReg); + } + } + sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub); +} + +/* +** Invoke the code generated by windowReturnOneRow() and, optionally, the +** xInverse() function for each window function, for one or more rows +** from the Window.iEphCsr temp table. This routine generates VM code +** similar to: +** +** while( regCtr>0 ){ +** regCtr--; +** windowReturnOneRow() +** if( bInverse ){ +** AggInverse +** } +** Next (Window.iEphCsr) +** } +*/ +static void windowReturnRows( + Parse *pParse, + Window *pMWin, /* List of window functions */ + int regCtr, /* Register containing number of rows */ + int regGosub, /* Register for Gosub addrGosub */ + int addrGosub, /* Address of sub-routine for ReturnOneRow */ + int regInvArg, /* Array of registers for xInverse args */ + int regInvSize /* Register containing size of partition */ +){ + int addr; + Vdbe *v = sqlite3GetVdbe(pParse); + windowAggFinal(pParse, pMWin, 0); + addr = sqlite3VdbeAddOp3(v, OP_IfPos, regCtr, sqlite3VdbeCurrentAddr(v)+2 ,1); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); + windowReturnOneRow(pParse, pMWin, regGosub, addrGosub); + if( regInvArg ){ + windowAggStep(pParse, pMWin, pMWin->iEphCsr, 1, regInvArg, regInvSize); + } + sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, addr); + VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr+1); /* The OP_Goto */ +} + +/* +** Generate code to set the accumulator register for each window function +** in the linked list passed as the second argument to NULL. And perform +** any equivalent initialization required by any built-in window functions +** in the list. +*/ +static int windowInitAccum(Parse *pParse, Window *pMWin){ + Vdbe *v = sqlite3GetVdbe(pParse); + int regArg; + int nArg = 0; + Window *pWin; + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + FuncDef *pFunc = pWin->pFunc; + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); + nArg = MAX(nArg, windowArgCount(pWin)); + if( pFunc->zName==nth_valueName + || pFunc->zName==first_valueName + ){ + sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1); + } + + if( (pFunc->funcFlags & SQLITE_FUNC_MINMAX) && pWin->csrApp ){ + assert( pWin->eStart!=TK_UNBOUNDED ); + sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1); + } + } + regArg = pParse->nMem+1; + pParse->nMem += nArg; + return regArg; +} + + +/* +** This function does the work of sqlite3WindowCodeStep() for all "ROWS" +** window frame types except for "BETWEEN UNBOUNDED PRECEDING AND CURRENT +** ROW". Pseudo-code for each follows. +** +** ROWS BETWEEN PRECEDING AND FOLLOWING +** +** ... +** if( new partition ){ +** Gosub flush_partition +** } +** Insert (record in eph-table) +** sqlite3WhereEnd() +** Gosub flush_partition +** +** flush_partition: +** Once { +** OpenDup (iEphCsr -> csrStart) +** OpenDup (iEphCsr -> csrEnd) +** } +** regStart = // PRECEDING expression +** regEnd = // FOLLOWING expression +** if( regStart<0 || regEnd<0 ){ error! } +** Rewind (csr,csrStart,csrEnd) // if EOF goto flush_partition_done +** Next(csrEnd) // if EOF skip Aggstep +** Aggstep (csrEnd) +** if( (regEnd--)<=0 ){ +** AggFinal (xValue) +** Gosub addrGosub +** Next(csr) // if EOF goto flush_partition_done +** if( (regStart--)<=0 ){ +** AggInverse (csrStart) +** Next(csrStart) +** } +** } +** flush_partition_done: +** ResetSorter (csr) +** Return +** +** ROWS BETWEEN PRECEDING AND CURRENT ROW +** ROWS BETWEEN CURRENT ROW AND FOLLOWING +** ROWS BETWEEN UNBOUNDED PRECEDING AND FOLLOWING +** +** These are similar to the above. For "CURRENT ROW", intialize the +** register to 0. For "UNBOUNDED PRECEDING" to infinity. +** +** ROWS BETWEEN PRECEDING AND UNBOUNDED FOLLOWING +** ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING +** +** Rewind (csr,csrStart,csrEnd) // if EOF goto flush_partition_done +** while( 1 ){ +** Next(csrEnd) // Exit while(1) at EOF +** Aggstep (csrEnd) +** } +** while( 1 ){ +** AggFinal (xValue) +** Gosub addrGosub +** Next(csr) // if EOF goto flush_partition_done +** if( (regStart--)<=0 ){ +** AggInverse (csrStart) +** Next(csrStart) +** } +** } +** +** For the "CURRENT ROW AND UNBOUNDED FOLLOWING" case, the final if() +** condition is always true (as if regStart were initialized to 0). +** +** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING +** +** This is the only RANGE case handled by this routine. It modifies the +** second while( 1 ) loop in "ROWS BETWEEN CURRENT ... UNBOUNDED..." to +** be: +** +** while( 1 ){ +** AggFinal (xValue) +** while( 1 ){ +** regPeer++ +** Gosub addrGosub +** Next(csr) // if EOF goto flush_partition_done +** if( new peer ) break; +** } +** while( (regPeer--)>0 ){ +** AggInverse (csrStart) +** Next(csrStart) +** } +** } +** +** ROWS BETWEEN FOLLOWING AND FOLLOWING +** +** regEnd = regEnd - regStart +** Rewind (csr,csrStart,csrEnd) // if EOF goto flush_partition_done +** Aggstep (csrEnd) +** Next(csrEnd) // if EOF fall-through +** if( (regEnd--)<=0 ){ +** if( (regStart--)<=0 ){ +** AggFinal (xValue) +** Gosub addrGosub +** Next(csr) // if EOF goto flush_partition_done +** } +** AggInverse (csrStart) +** Next (csrStart) +** } +** +** ROWS BETWEEN PRECEDING AND PRECEDING +** +** Replace the bit after "Rewind" in the above with: +** +** if( (regEnd--)<=0 ){ +** AggStep (csrEnd) +** Next (csrEnd) +** } +** AggFinal (xValue) +** Gosub addrGosub +** Next(csr) // if EOF goto flush_partition_done +** if( (regStart--)<=0 ){ +** AggInverse (csr2) +** Next (csr2) +** } +** +*/ +static void windowCodeRowExprStep( + Parse *pParse, + Select *p, + WhereInfo *pWInfo, + int regGosub, + int addrGosub +){ + Window *pMWin = p->pWin; + Vdbe *v = sqlite3GetVdbe(pParse); + int regFlushPart; /* Register for "Gosub flush_partition" */ + int lblFlushPart; /* Label for "Gosub flush_partition" */ + int lblFlushDone; /* Label for "Gosub flush_partition_done" */ + + int regArg; + int addr; + int csrStart = pParse->nTab++; + int csrEnd = pParse->nTab++; + int regStart; /* Value of PRECEDING */ + int regEnd; /* Value of FOLLOWING */ + int addrGoto; + int addrTop; + int addrIfPos1 = 0; + int addrIfPos2 = 0; + int regSize = 0; + + assert( pMWin->eStart==TK_PRECEDING + || pMWin->eStart==TK_CURRENT + || pMWin->eStart==TK_FOLLOWING + || pMWin->eStart==TK_UNBOUNDED + ); + assert( pMWin->eEnd==TK_FOLLOWING + || pMWin->eEnd==TK_CURRENT + || pMWin->eEnd==TK_UNBOUNDED + || pMWin->eEnd==TK_PRECEDING + ); + + /* Allocate register and label for the "flush_partition" sub-routine. */ + regFlushPart = ++pParse->nMem; + lblFlushPart = sqlite3VdbeMakeLabel(v); + lblFlushDone = sqlite3VdbeMakeLabel(v); + + regStart = ++pParse->nMem; + regEnd = ++pParse->nMem; + + windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, ®Size); + + addrGoto = sqlite3VdbeAddOp0(v, OP_Goto); + + /* Start of "flush_partition" */ + sqlite3VdbeResolveLabel(v, lblFlushPart); + sqlite3VdbeAddOp2(v, OP_Once, 0, sqlite3VdbeCurrentAddr(v)+3); + VdbeCoverage(v); + VdbeComment((v, "Flush_partition subroutine")); + sqlite3VdbeAddOp2(v, OP_OpenDup, csrStart, pMWin->iEphCsr); + sqlite3VdbeAddOp2(v, OP_OpenDup, csrEnd, pMWin->iEphCsr); + + /* If either regStart or regEnd are not non-negative integers, throw + ** an exception. */ + if( pMWin->pStart ){ + sqlite3ExprCode(pParse, pMWin->pStart, regStart); + windowCheckIntValue(pParse, regStart, 0); + } + if( pMWin->pEnd ){ + sqlite3ExprCode(pParse, pMWin->pEnd, regEnd); + windowCheckIntValue(pParse, regEnd, 1); + } + + /* If this is "ROWS FOLLOWING AND ROWS FOLLOWING", do: + ** + ** if( regEndpEnd && pMWin->eStart==TK_FOLLOWING ){ + assert( pMWin->pStart!=0 ); + assert( pMWin->eEnd==TK_FOLLOWING ); + sqlite3VdbeAddOp3(v, OP_Ge, regStart, sqlite3VdbeCurrentAddr(v)+2, regEnd); + VdbeCoverageNeverNull(v); + sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart); + sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regEnd); + } + + if( pMWin->pStart && pMWin->eEnd==TK_PRECEDING ){ + assert( pMWin->pEnd!=0 ); + assert( pMWin->eStart==TK_PRECEDING ); + sqlite3VdbeAddOp3(v, OP_Le, regStart, sqlite3VdbeCurrentAddr(v)+3, regEnd); + VdbeCoverageNeverNull(v); + sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart); + sqlite3VdbeAddOp2(v, OP_Copy, regSize, regEnd); + } + + /* Initialize the accumulator register for each window function to NULL */ + regArg = windowInitAccum(pParse, pMWin); + + sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr, lblFlushDone); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Rewind, csrStart, lblFlushDone); + VdbeCoverageNeverTaken(v); + sqlite3VdbeChangeP5(v, 1); + sqlite3VdbeAddOp2(v, OP_Rewind, csrEnd, lblFlushDone); + VdbeCoverageNeverTaken(v); + sqlite3VdbeChangeP5(v, 1); + + /* Invoke AggStep function for each window function using the row that + ** csrEnd currently points to. Or, if csrEnd is already at EOF, + ** do nothing. */ + addrTop = sqlite3VdbeCurrentAddr(v); + if( pMWin->eEnd==TK_PRECEDING ){ + addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1); + VdbeCoverage(v); + } + sqlite3VdbeAddOp2(v, OP_Next, csrEnd, sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); + addr = sqlite3VdbeAddOp0(v, OP_Goto); + windowAggStep(pParse, pMWin, csrEnd, 0, regArg, regSize); + if( pMWin->eEnd==TK_UNBOUNDED ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop); + sqlite3VdbeJumpHere(v, addr); + addrTop = sqlite3VdbeCurrentAddr(v); + }else{ + sqlite3VdbeJumpHere(v, addr); + if( pMWin->eEnd==TK_PRECEDING ){ + sqlite3VdbeJumpHere(v, addrIfPos1); + } + } + + if( pMWin->eEnd==TK_FOLLOWING ){ + addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1); + VdbeCoverage(v); + } + if( pMWin->eStart==TK_FOLLOWING ){ + addrIfPos2 = sqlite3VdbeAddOp3(v, OP_IfPos, regStart, 0 , 1); + VdbeCoverage(v); + } + windowAggFinal(pParse, pMWin, 0); + windowReturnOneRow(pParse, pMWin, regGosub, addrGosub); + sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Goto, 0, lblFlushDone); + if( pMWin->eStart==TK_FOLLOWING ){ + sqlite3VdbeJumpHere(v, addrIfPos2); + } + + if( pMWin->eStart==TK_CURRENT + || pMWin->eStart==TK_PRECEDING + || pMWin->eStart==TK_FOLLOWING + ){ + int lblSkipInverse = sqlite3VdbeMakeLabel(v);; + if( pMWin->eStart==TK_PRECEDING ){ + sqlite3VdbeAddOp3(v, OP_IfPos, regStart, lblSkipInverse, 1); + VdbeCoverage(v); + } + if( pMWin->eStart==TK_FOLLOWING ){ + sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Goto, 0, lblSkipInverse); + }else{ + sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+1); + VdbeCoverageAlwaysTaken(v); + } + windowAggStep(pParse, pMWin, csrStart, 1, regArg, regSize); + sqlite3VdbeResolveLabel(v, lblSkipInverse); + } + if( pMWin->eEnd==TK_FOLLOWING ){ + sqlite3VdbeJumpHere(v, addrIfPos1); + } + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop); + + /* flush_partition_done: */ + sqlite3VdbeResolveLabel(v, lblFlushDone); + sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr); + sqlite3VdbeAddOp1(v, OP_Return, regFlushPart); + VdbeComment((v, "end flush_partition subroutine")); + + /* Jump to here to skip over flush_partition */ + sqlite3VdbeJumpHere(v, addrGoto); +} + +/* +** This function does the work of sqlite3WindowCodeStep() for cases that +** would normally be handled by windowCodeDefaultStep() when there are +** one or more built-in window-functions that require the entire partition +** to be cached in a temp table before any rows can be returned. Additionally. +** "RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING" is always handled by +** this function. +** +** Pseudo-code corresponding to the VM code generated by this function +** for each type of window follows. +** +** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +** +** flush_partition: +** Once { +** OpenDup (iEphCsr -> csrLead) +** } +** Integer ctr 0 +** foreach row (csrLead){ +** if( new peer ){ +** AggFinal (xValue) +** for(i=0; i csrLead) +** } +** foreach row (csrLead) { +** AggStep (csrLead) +** } +** foreach row (iEphCsr) { +** Gosub addrGosub +** } +** +** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING +** +** flush_partition: +** Once { +** OpenDup (iEphCsr -> csrLead) +** } +** foreach row (csrLead){ +** AggStep (csrLead) +** } +** Rewind (csrLead) +** Integer ctr 0 +** foreach row (csrLead){ +** if( new peer ){ +** AggFinal (xValue) +** for(i=0; ipWin; + Vdbe *v = sqlite3GetVdbe(pParse); + int k; + int addr; + ExprList *pPart = pMWin->pPartition; + ExprList *pOrderBy = pMWin->pOrderBy; + int nPeer = pOrderBy ? pOrderBy->nExpr : 0; + int regNewPeer; + + int addrGoto; /* Address of Goto used to jump flush_par.. */ + int addrNext; /* Jump here for next iteration of loop */ + int regFlushPart; + int lblFlushPart; + int csrLead; + int regCtr; + int regArg; /* Register array to martial function args */ + int regSize; + int lblEmpty; + int bReverse = pMWin->pOrderBy && pMWin->eStart==TK_CURRENT + && pMWin->eEnd==TK_UNBOUNDED; + + assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT) + || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED) + || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT) + || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED) + ); + + lblEmpty = sqlite3VdbeMakeLabel(v); + regNewPeer = pParse->nMem+1; + pParse->nMem += nPeer; + + /* Allocate register and label for the "flush_partition" sub-routine. */ + regFlushPart = ++pParse->nMem; + lblFlushPart = sqlite3VdbeMakeLabel(v); + + csrLead = pParse->nTab++; + regCtr = ++pParse->nMem; + + windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, ®Size); + addrGoto = sqlite3VdbeAddOp0(v, OP_Goto); + + /* Start of "flush_partition" */ + sqlite3VdbeResolveLabel(v, lblFlushPart); + sqlite3VdbeAddOp2(v, OP_Once, 0, sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_OpenDup, csrLead, pMWin->iEphCsr); + + /* Initialize the accumulator register for each window function to NULL */ + regArg = windowInitAccum(pParse, pMWin); + + sqlite3VdbeAddOp2(v, OP_Integer, 0, regCtr); + sqlite3VdbeAddOp2(v, OP_Rewind, csrLead, lblEmpty); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr, lblEmpty); + VdbeCoverageNeverTaken(v); + + if( bReverse ){ + int addr2 = sqlite3VdbeCurrentAddr(v); + windowAggStep(pParse, pMWin, csrLead, 0, regArg, regSize); + sqlite3VdbeAddOp2(v, OP_Next, csrLead, addr2); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Rewind, csrLead, lblEmpty); + VdbeCoverageNeverTaken(v); + } + addrNext = sqlite3VdbeCurrentAddr(v); + + if( pOrderBy && (pMWin->eEnd==TK_CURRENT || pMWin->eStart==TK_CURRENT) ){ + int bCurrent = (pMWin->eStart==TK_CURRENT); + int addrJump = 0; /* Address of OP_Jump below */ + if( pMWin->eType==TK_RANGE ){ + int iOff = pMWin->nBufferCol + (pPart ? pPart->nExpr : 0); + int regPeer = pMWin->regPart + (pPart ? pPart->nExpr : 0); + KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0); + for(k=0; kiEphCsr); + sqlite3VdbeAddOp1(v, OP_Return, regFlushPart); + + /* Jump to here to skip over flush_partition */ + sqlite3VdbeJumpHere(v, addrGoto); +} + + +/* +** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +** +** ... +** if( new partition ){ +** AggFinal (xFinalize) +** Gosub addrGosub +** ResetSorter eph-table +** } +** else if( new peer ){ +** AggFinal (xValue) +** Gosub addrGosub +** ResetSorter eph-table +** } +** AggStep +** Insert (record into eph-table) +** sqlite3WhereEnd() +** AggFinal (xFinalize) +** Gosub addrGosub +** +** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING +** +** As above, except take no action for a "new peer". Invoke +** the sub-routine once only for each partition. +** +** RANGE BETWEEN CURRENT ROW AND CURRENT ROW +** +** As above, except that the "new peer" condition is handled in the +** same way as "new partition" (so there is no "else if" block). +** +** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +** +** As above, except assume every row is a "new peer". +*/ +static void windowCodeDefaultStep( + Parse *pParse, + Select *p, + WhereInfo *pWInfo, + int regGosub, + int addrGosub +){ + Window *pMWin = p->pWin; + Vdbe *v = sqlite3GetVdbe(pParse); + int k; + int iSubCsr = p->pSrc->a[0].iCursor; + int nSub = p->pSrc->a[0].pTab->nCol; + int reg = pParse->nMem+1; + int regRecord = reg+nSub; + int regRowid = regRecord+1; + int addr; + ExprList *pPart = pMWin->pPartition; + ExprList *pOrderBy = pMWin->pOrderBy; + + assert( pMWin->eType==TK_RANGE + || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT) + ); + + assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT) + || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED) + || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT) + || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED && !pOrderBy) + ); + + if( pMWin->eEnd==TK_UNBOUNDED ){ + pOrderBy = 0; + } + + pParse->nMem += nSub + 2; + + /* Load the individual column values of the row returned by + ** the sub-select into an array of registers. */ + for(k=0; knExpr : 0); + int addrGoto = 0; + int addrJump = 0; + int nPeer = (pOrderBy ? pOrderBy->nExpr : 0); + + if( pPart ){ + int regNewPart = reg + pMWin->nBufferCol; + KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0); + addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart,nPart); + sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO); + addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2); + VdbeCoverageEqNe(v); + windowAggFinal(pParse, pMWin, 1); + if( pOrderBy ){ + addrGoto = sqlite3VdbeAddOp0(v, OP_Goto); + } + } + + if( pOrderBy ){ + int regNewPeer = reg + pMWin->nBufferCol + nPart; + int regPeer = pMWin->regPart + nPart; + + if( addrJump ) sqlite3VdbeJumpHere(v, addrJump); + if( pMWin->eType==TK_RANGE ){ + KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0); + addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPeer, regPeer, nPeer); + sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO); + addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2); + VdbeCoverage(v); + }else{ + addrJump = 0; + } + windowAggFinal(pParse, pMWin, pMWin->eStart==TK_CURRENT); + if( addrGoto ) sqlite3VdbeJumpHere(v, addrGoto); + } + + sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr,sqlite3VdbeCurrentAddr(v)+3); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub); + sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)-1); + VdbeCoverage(v); + + sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr); + sqlite3VdbeAddOp3( + v, OP_Copy, reg+pMWin->nBufferCol, pMWin->regPart, nPart+nPeer-1 + ); + + if( addrJump ) sqlite3VdbeJumpHere(v, addrJump); + } + + /* Invoke step function for window functions */ + windowAggStep(pParse, pMWin, -1, 0, reg, 0); + + /* Buffer the current row in the ephemeral table. */ + if( pMWin->nBufferCol>0 ){ + sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, pMWin->nBufferCol, regRecord); + }else{ + sqlite3VdbeAddOp2(v, OP_Blob, 0, regRecord); + sqlite3VdbeAppendP4(v, (void*)"", 0); + } + sqlite3VdbeAddOp2(v, OP_NewRowid, pMWin->iEphCsr, regRowid); + sqlite3VdbeAddOp3(v, OP_Insert, pMWin->iEphCsr, regRecord, regRowid); + + /* End the database scan loop. */ + sqlite3WhereEnd(pWInfo); + + windowAggFinal(pParse, pMWin, 1); + sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr,sqlite3VdbeCurrentAddr(v)+3); + VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub); + sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)-1); + VdbeCoverage(v); +} + +/* +** Allocate and return a duplicate of the Window object indicated by the +** third argument. Set the Window.pOwner field of the new object to +** pOwner. +*/ +SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){ + Window *pNew = 0; + if( p ){ + pNew = sqlite3DbMallocZero(db, sizeof(Window)); + if( pNew ){ + pNew->zName = sqlite3DbStrDup(db, p->zName); + pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0); + pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0); + pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0); + pNew->eType = p->eType; + pNew->eEnd = p->eEnd; + pNew->eStart = p->eStart; + pNew->pStart = sqlite3ExprDup(db, p->pStart, 0); + pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0); + pNew->pOwner = pOwner; + } + } + return pNew; +} + +/* +** Return a copy of the linked list of Window objects passed as the +** second argument. +*/ +SQLITE_PRIVATE Window *sqlite3WindowListDup(sqlite3 *db, Window *p){ + Window *pWin; + Window *pRet = 0; + Window **pp = &pRet; + + for(pWin=p; pWin; pWin=pWin->pNextWin){ + *pp = sqlite3WindowDup(db, 0, pWin); + if( *pp==0 ) break; + pp = &((*pp)->pNextWin); + } + + return pRet; +} + +/* +** sqlite3WhereBegin() has already been called for the SELECT statement +** passed as the second argument when this function is invoked. It generates +** code to populate the Window.regResult register for each window function and +** invoke the sub-routine at instruction addrGosub once for each row. +** This function calls sqlite3WhereEnd() before returning. +*/ +SQLITE_PRIVATE void sqlite3WindowCodeStep( + Parse *pParse, /* Parse context */ + Select *p, /* Rewritten SELECT statement */ + WhereInfo *pWInfo, /* Context returned by sqlite3WhereBegin() */ + int regGosub, /* Register for OP_Gosub */ + int addrGosub /* OP_Gosub here to return each row */ +){ + Window *pMWin = p->pWin; + + /* There are three different functions that may be used to do the work + ** of this one, depending on the window frame and the specific built-in + ** window functions used (if any). + ** + ** windowCodeRowExprStep() handles all "ROWS" window frames, except for: + ** + ** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW + ** + ** The exception is because windowCodeRowExprStep() implements all window + ** frame types by caching the entire partition in a temp table, and + ** "ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW" is easy enough to + ** implement without such a cache. + ** + ** windowCodeCacheStep() is used for: + ** + ** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING + ** + ** It is also used for anything not handled by windowCodeRowExprStep() + ** that invokes a built-in window function that requires the entire + ** partition to be cached in a temp table before any rows are returned + ** (e.g. nth_value() or percent_rank()). + ** + ** Finally, assuming there is no built-in window function that requires + ** the partition to be cached, windowCodeDefaultStep() is used for: + ** + ** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW + ** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING + ** RANGE BETWEEN CURRENT ROW AND CURRENT ROW + ** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW + ** + ** windowCodeDefaultStep() is the only one of the three functions that + ** does not cache each partition in a temp table before beginning to + ** return rows. + */ + if( pMWin->eType==TK_ROWS + && (pMWin->eStart!=TK_UNBOUNDED||pMWin->eEnd!=TK_CURRENT||!pMWin->pOrderBy) + ){ + VdbeModuleComment((pParse->pVdbe, "Begin RowExprStep()")); + windowCodeRowExprStep(pParse, p, pWInfo, regGosub, addrGosub); + }else{ + Window *pWin; + int bCache = 0; /* True to use CacheStep() */ + + if( pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED ){ + bCache = 1; + }else{ + for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ + FuncDef *pFunc = pWin->pFunc; + if( (pFunc->funcFlags & SQLITE_FUNC_WINDOW_SIZE) + || (pFunc->zName==nth_valueName) + || (pFunc->zName==first_valueName) + || (pFunc->zName==leadName) + || (pFunc->zName==lagName) + ){ + bCache = 1; + break; + } + } + } + + /* Otherwise, call windowCodeDefaultStep(). */ + if( bCache ){ + VdbeModuleComment((pParse->pVdbe, "Begin CacheStep()")); + windowCodeCacheStep(pParse, p, pWInfo, regGosub, addrGosub); + }else{ + VdbeModuleComment((pParse->pVdbe, "Begin DefaultStep()")); + windowCodeDefaultStep(pParse, p, pWInfo, regGosub, addrGosub); + } + } +} + +#endif /* SQLITE_OMIT_WINDOWFUNC */ + +/************** End of window.c **********************************************/ /************** Begin file parse.c *******************************************/ /* ** 2000-05-29 @@ -141456,6 +145981,8 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ */ struct TrigEvent { int a; IdList * b; }; +struct FrameBound { int eType; Expr *pExpr; }; + /* ** Disable lookaside memory allocation for objects that might be ** shared across database connections. @@ -141496,10 +146023,21 @@ static void disableLookaside(Parse *pParse){ static Expr *tokenExpr(Parse *pParse, int op, Token t){ Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1); if( p ){ - memset(p, 0, sizeof(Expr)); + /* memset(p, 0, sizeof(Expr)); */ p->op = (u8)op; + p->affinity = 0; p->flags = EP_Leaf; p->iAgg = -1; + p->pLeft = p->pRight = 0; + p->x.pList = 0; + p->pAggInfo = 0; + p->pTab = 0; + p->op2 = 0; + p->iTable = 0; + p->iColumn = 0; +#ifndef SQLITE_OMIT_WINDOWFUNC + p->pWin = 0; +#endif p->u.zToken = (char*)&p[1]; memcpy(p->u.zToken, t.z, t.n); p->u.zToken[t.n] = 0; @@ -141510,15 +146048,19 @@ static void disableLookaside(Parse *pParse){ #if SQLITE_MAX_EXPR_DEPTH>0 p->nHeight = 1; #endif + if( IN_RENAME_OBJECT ){ + return (Expr*)sqlite3RenameTokenMap(pParse, (void*)p, &t); + } } return p; } + /* A routine to convert a binary TK_IS or TK_ISNOT expression into a ** unary TK_ISNULL or TK_NOTNULL expression. */ static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){ sqlite3 *db = pParse->db; - if( pA && pY && pY->op==TK_NULL ){ + if( pA && pY && pY->op==TK_NULL && !IN_RENAME_OBJECT ){ pA->op = (u8)op; sqlite3ExprDelete(db, pA->pRight); pA->pRight = 0; @@ -141609,26 +146151,28 @@ static void disableLookaside(Parse *pParse){ # define INTERFACE 1 #endif /************* Begin control #defines *****************************************/ -#define YYCODETYPE unsigned char -#define YYNOCODE 255 +#define YYCODETYPE unsigned short int +#define YYNOCODE 277 #define YYACTIONTYPE unsigned short int -#define YYWILDCARD 84 +#define YYWILDCARD 91 #define sqlite3ParserTOKENTYPE Token typedef union { int yyinit; sqlite3ParserTOKENTYPE yy0; - const char* yy36; - TriggerStep* yy47; - With* yy91; - struct {int value; int mask;} yy107; - Expr* yy182; - Upsert* yy198; - ExprList* yy232; - struct TrigEvent yy300; - Select* yy399; - SrcList* yy427; - int yy502; - IdList* yy510; + Expr* yy18; + struct TrigEvent yy34; + IdList* yy48; + int yy70; + struct {int value; int mask;} yy111; + struct FrameBound yy119; + SrcList* yy135; + TriggerStep* yy207; + Window* yy327; + Upsert* yy340; + const char* yy392; + ExprList* yy420; + With* yy449; + Select* yy489; } YYMINORTYPE; #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 @@ -141644,18 +146188,19 @@ typedef union { #define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse; #define sqlite3ParserCTX_STORE yypParser->pParse=pParse; #define YYFALLBACK 1 -#define YYNSTATE 490 -#define YYNRULE 341 -#define YYNTOKEN 145 -#define YY_MAX_SHIFT 489 -#define YY_MIN_SHIFTREDUCE 705 -#define YY_MAX_SHIFTREDUCE 1045 -#define YY_ERROR_ACTION 1046 -#define YY_ACCEPT_ACTION 1047 -#define YY_NO_ACTION 1048 -#define YY_MIN_REDUCE 1049 -#define YY_MAX_REDUCE 1389 +#define YYNSTATE 521 +#define YYNRULE 367 +#define YYNTOKEN 155 +#define YY_MAX_SHIFT 520 +#define YY_MIN_SHIFTREDUCE 756 +#define YY_MAX_SHIFTREDUCE 1122 +#define YY_ERROR_ACTION 1123 +#define YY_ACCEPT_ACTION 1124 +#define YY_NO_ACTION 1125 +#define YY_MIN_REDUCE 1126 +#define YY_MAX_REDUCE 1492 /************* End control #defines *******************************************/ +#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) /* Define the yytestcase() macro to be a no-op if is not already defined ** otherwise. @@ -141720,503 +146265,568 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (1657) +#define YY_ACTTAB_COUNT (2009) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 349, 99, 96, 185, 99, 96, 185, 233, 1047, 1, - /* 10 */ 1, 489, 2, 1051, 484, 477, 477, 477, 260, 351, - /* 20 */ 121, 1310, 1120, 1120, 1178, 1115, 1094, 1128, 380, 380, - /* 30 */ 380, 835, 454, 410, 1115, 59, 59, 1357, 425, 836, - /* 40 */ 710, 711, 712, 106, 107, 97, 1023, 1023, 900, 903, - /* 50 */ 892, 892, 104, 104, 105, 105, 105, 105, 346, 238, - /* 60 */ 238, 99, 96, 185, 238, 238, 889, 889, 901, 904, - /* 70 */ 460, 481, 351, 99, 96, 185, 481, 347, 1177, 82, - /* 80 */ 388, 214, 182, 23, 194, 103, 103, 103, 103, 102, - /* 90 */ 102, 101, 101, 101, 100, 381, 106, 107, 97, 1023, - /* 100 */ 1023, 900, 903, 892, 892, 104, 104, 105, 105, 105, - /* 110 */ 105, 10, 385, 484, 24, 484, 1333, 489, 2, 1051, - /* 120 */ 335, 1043, 108, 893, 260, 351, 121, 99, 96, 185, - /* 130 */ 100, 381, 386, 1128, 59, 59, 59, 59, 103, 103, - /* 140 */ 103, 103, 102, 102, 101, 101, 101, 100, 381, 106, - /* 150 */ 107, 97, 1023, 1023, 900, 903, 892, 892, 104, 104, - /* 160 */ 105, 105, 105, 105, 360, 238, 238, 170, 170, 467, - /* 170 */ 455, 467, 464, 67, 381, 329, 169, 481, 351, 343, - /* 180 */ 338, 400, 1044, 68, 101, 101, 101, 100, 381, 393, - /* 190 */ 194, 103, 103, 103, 103, 102, 102, 101, 101, 101, - /* 200 */ 100, 381, 106, 107, 97, 1023, 1023, 900, 903, 892, - /* 210 */ 892, 104, 104, 105, 105, 105, 105, 483, 385, 103, - /* 220 */ 103, 103, 103, 102, 102, 101, 101, 101, 100, 381, - /* 230 */ 268, 351, 946, 946, 422, 296, 102, 102, 101, 101, - /* 240 */ 101, 100, 381, 861, 103, 103, 103, 103, 102, 102, - /* 250 */ 101, 101, 101, 100, 381, 106, 107, 97, 1023, 1023, - /* 260 */ 900, 903, 892, 892, 104, 104, 105, 105, 105, 105, - /* 270 */ 484, 983, 1383, 206, 1353, 1383, 438, 435, 434, 281, - /* 280 */ 396, 269, 1089, 941, 351, 1002, 433, 861, 743, 401, - /* 290 */ 282, 57, 57, 482, 145, 791, 791, 103, 103, 103, - /* 300 */ 103, 102, 102, 101, 101, 101, 100, 381, 106, 107, - /* 310 */ 97, 1023, 1023, 900, 903, 892, 892, 104, 104, 105, - /* 320 */ 105, 105, 105, 281, 1002, 1003, 1004, 206, 879, 319, - /* 330 */ 438, 435, 434, 981, 259, 474, 360, 351, 1118, 1118, - /* 340 */ 433, 736, 379, 378, 872, 1002, 1356, 322, 871, 766, - /* 350 */ 103, 103, 103, 103, 102, 102, 101, 101, 101, 100, - /* 360 */ 381, 106, 107, 97, 1023, 1023, 900, 903, 892, 892, - /* 370 */ 104, 104, 105, 105, 105, 105, 484, 801, 484, 871, - /* 380 */ 871, 873, 401, 282, 1002, 1003, 1004, 1030, 360, 1030, - /* 390 */ 351, 983, 1384, 213, 880, 1384, 145, 59, 59, 59, - /* 400 */ 59, 1002, 244, 103, 103, 103, 103, 102, 102, 101, - /* 410 */ 101, 101, 100, 381, 106, 107, 97, 1023, 1023, 900, - /* 420 */ 903, 892, 892, 104, 104, 105, 105, 105, 105, 274, - /* 430 */ 484, 110, 467, 479, 467, 444, 259, 474, 232, 232, - /* 440 */ 1002, 1003, 1004, 351, 210, 335, 982, 866, 1385, 336, - /* 450 */ 481, 59, 59, 981, 245, 307, 103, 103, 103, 103, - /* 460 */ 102, 102, 101, 101, 101, 100, 381, 106, 107, 97, - /* 470 */ 1023, 1023, 900, 903, 892, 892, 104, 104, 105, 105, - /* 480 */ 105, 105, 453, 459, 484, 408, 377, 259, 474, 271, - /* 490 */ 183, 273, 209, 208, 207, 356, 351, 307, 178, 177, - /* 500 */ 127, 1006, 1098, 14, 14, 43, 43, 1044, 425, 103, - /* 510 */ 103, 103, 103, 102, 102, 101, 101, 101, 100, 381, - /* 520 */ 106, 107, 97, 1023, 1023, 900, 903, 892, 892, 104, - /* 530 */ 104, 105, 105, 105, 105, 294, 1132, 408, 160, 484, - /* 540 */ 408, 1006, 129, 962, 1209, 239, 239, 481, 307, 425, - /* 550 */ 1309, 1097, 351, 235, 243, 272, 820, 481, 963, 425, - /* 560 */ 11, 11, 103, 103, 103, 103, 102, 102, 101, 101, - /* 570 */ 101, 100, 381, 964, 362, 1002, 106, 107, 97, 1023, - /* 580 */ 1023, 900, 903, 892, 892, 104, 104, 105, 105, 105, - /* 590 */ 105, 1275, 161, 126, 777, 289, 1209, 292, 1072, 357, - /* 600 */ 1209, 1127, 476, 357, 778, 425, 247, 425, 351, 248, - /* 610 */ 414, 364, 414, 171, 1002, 1003, 1004, 84, 103, 103, - /* 620 */ 103, 103, 102, 102, 101, 101, 101, 100, 381, 1002, - /* 630 */ 184, 484, 106, 107, 97, 1023, 1023, 900, 903, 892, - /* 640 */ 892, 104, 104, 105, 105, 105, 105, 1123, 1209, 287, - /* 650 */ 484, 1209, 11, 11, 179, 820, 259, 474, 307, 237, - /* 660 */ 182, 351, 321, 365, 414, 308, 367, 366, 1002, 1003, - /* 670 */ 1004, 44, 44, 87, 103, 103, 103, 103, 102, 102, - /* 680 */ 101, 101, 101, 100, 381, 106, 107, 97, 1023, 1023, - /* 690 */ 900, 903, 892, 892, 104, 104, 105, 105, 105, 105, - /* 700 */ 246, 368, 280, 128, 10, 358, 146, 796, 835, 258, - /* 710 */ 1020, 88, 795, 86, 351, 421, 836, 943, 376, 348, - /* 720 */ 191, 943, 1318, 267, 308, 279, 456, 103, 103, 103, - /* 730 */ 103, 102, 102, 101, 101, 101, 100, 381, 106, 95, - /* 740 */ 97, 1023, 1023, 900, 903, 892, 892, 104, 104, 105, - /* 750 */ 105, 105, 105, 420, 249, 238, 238, 238, 238, 79, - /* 760 */ 375, 125, 305, 29, 262, 978, 351, 481, 337, 481, - /* 770 */ 756, 755, 304, 278, 415, 15, 81, 940, 1126, 940, - /* 780 */ 103, 103, 103, 103, 102, 102, 101, 101, 101, 100, - /* 790 */ 381, 107, 97, 1023, 1023, 900, 903, 892, 892, 104, - /* 800 */ 104, 105, 105, 105, 105, 457, 263, 484, 174, 484, - /* 810 */ 238, 238, 863, 407, 402, 216, 216, 351, 409, 193, - /* 820 */ 283, 216, 481, 81, 763, 764, 266, 5, 13, 13, - /* 830 */ 34, 34, 103, 103, 103, 103, 102, 102, 101, 101, - /* 840 */ 101, 100, 381, 97, 1023, 1023, 900, 903, 892, 892, - /* 850 */ 104, 104, 105, 105, 105, 105, 93, 475, 1002, 4, - /* 860 */ 403, 1002, 340, 431, 1002, 297, 212, 1277, 81, 746, - /* 870 */ 1163, 152, 926, 478, 166, 212, 757, 829, 930, 939, - /* 880 */ 216, 939, 858, 103, 103, 103, 103, 102, 102, 101, - /* 890 */ 101, 101, 100, 381, 238, 238, 382, 1002, 1003, 1004, - /* 900 */ 1002, 1003, 1004, 1002, 1003, 1004, 481, 439, 472, 746, - /* 910 */ 105, 105, 105, 105, 98, 758, 1162, 145, 930, 412, - /* 920 */ 879, 406, 793, 81, 395, 89, 90, 91, 105, 105, - /* 930 */ 105, 105, 1323, 92, 484, 382, 486, 485, 240, 275, - /* 940 */ 871, 103, 103, 103, 103, 102, 102, 101, 101, 101, - /* 950 */ 100, 381, 1096, 371, 355, 45, 45, 259, 474, 103, - /* 960 */ 103, 103, 103, 102, 102, 101, 101, 101, 100, 381, - /* 970 */ 1150, 871, 871, 873, 874, 21, 1332, 991, 384, 730, - /* 980 */ 722, 242, 123, 1298, 124, 875, 333, 333, 332, 227, - /* 990 */ 330, 991, 384, 719, 256, 242, 484, 391, 413, 1297, - /* 1000 */ 333, 333, 332, 227, 330, 748, 187, 719, 265, 470, - /* 1010 */ 1279, 1002, 484, 417, 391, 390, 264, 11, 11, 284, - /* 1020 */ 187, 732, 265, 93, 475, 875, 4, 1279, 1281, 419, - /* 1030 */ 264, 369, 416, 11, 11, 1159, 288, 484, 399, 1346, - /* 1040 */ 478, 379, 378, 291, 484, 293, 189, 250, 295, 1027, - /* 1050 */ 1002, 1003, 1004, 190, 1029, 1111, 140, 188, 11, 11, - /* 1060 */ 189, 732, 1028, 382, 923, 46, 46, 190, 1095, 230, - /* 1070 */ 140, 188, 462, 93, 475, 472, 4, 300, 309, 391, - /* 1080 */ 373, 6, 1069, 217, 739, 310, 1030, 879, 1030, 1171, - /* 1090 */ 478, 352, 1279, 90, 91, 800, 259, 474, 1208, 484, - /* 1100 */ 92, 1268, 382, 486, 485, 352, 1002, 871, 879, 426, - /* 1110 */ 259, 474, 172, 382, 238, 238, 1146, 170, 1021, 389, - /* 1120 */ 47, 47, 1157, 739, 872, 472, 481, 469, 871, 350, - /* 1130 */ 1214, 83, 475, 389, 4, 1078, 1071, 879, 871, 871, - /* 1140 */ 873, 874, 21, 90, 91, 1002, 1003, 1004, 478, 251, - /* 1150 */ 92, 251, 382, 486, 485, 443, 370, 871, 1021, 871, - /* 1160 */ 871, 873, 224, 241, 306, 441, 301, 440, 211, 1060, - /* 1170 */ 820, 382, 822, 447, 299, 1059, 484, 1061, 1143, 962, - /* 1180 */ 430, 796, 484, 472, 1340, 312, 795, 465, 871, 871, - /* 1190 */ 873, 874, 21, 314, 963, 879, 316, 59, 59, 1002, - /* 1200 */ 9, 90, 91, 48, 48, 238, 238, 210, 92, 964, - /* 1210 */ 382, 486, 485, 176, 334, 871, 242, 481, 1193, 238, - /* 1220 */ 238, 333, 333, 332, 227, 330, 394, 270, 719, 277, - /* 1230 */ 471, 481, 467, 466, 484, 145, 217, 1201, 1002, 1003, - /* 1240 */ 1004, 187, 3, 265, 184, 445, 871, 871, 873, 874, - /* 1250 */ 21, 264, 1337, 450, 1051, 39, 39, 392, 356, 260, - /* 1260 */ 342, 121, 468, 411, 436, 821, 180, 1094, 1128, 820, - /* 1270 */ 303, 1021, 1272, 1271, 299, 259, 474, 238, 238, 1002, - /* 1280 */ 473, 189, 484, 318, 327, 238, 238, 484, 190, 481, - /* 1290 */ 446, 140, 188, 1343, 238, 238, 1038, 481, 148, 175, - /* 1300 */ 238, 238, 484, 49, 49, 219, 481, 484, 35, 35, - /* 1310 */ 1317, 1021, 481, 484, 1035, 484, 1315, 484, 1002, 1003, - /* 1320 */ 1004, 484, 66, 36, 36, 194, 352, 484, 38, 38, - /* 1330 */ 484, 259, 474, 69, 50, 50, 51, 51, 52, 52, - /* 1340 */ 359, 484, 12, 12, 484, 1198, 484, 158, 53, 53, - /* 1350 */ 405, 112, 112, 385, 389, 484, 26, 484, 143, 484, - /* 1360 */ 150, 484, 54, 54, 397, 40, 40, 55, 55, 484, - /* 1370 */ 79, 484, 153, 1190, 484, 154, 56, 56, 41, 41, - /* 1380 */ 58, 58, 133, 133, 484, 398, 484, 429, 484, 155, - /* 1390 */ 134, 134, 135, 135, 484, 63, 63, 484, 341, 484, - /* 1400 */ 339, 484, 196, 484, 156, 42, 42, 113, 113, 60, - /* 1410 */ 60, 484, 404, 484, 27, 114, 114, 1204, 115, 115, - /* 1420 */ 111, 111, 132, 132, 131, 131, 1266, 418, 484, 162, - /* 1430 */ 484, 200, 119, 119, 118, 118, 484, 74, 424, 484, - /* 1440 */ 1286, 484, 231, 484, 202, 484, 167, 286, 427, 116, - /* 1450 */ 116, 117, 117, 290, 203, 442, 1062, 62, 62, 204, - /* 1460 */ 64, 64, 61, 61, 33, 33, 37, 37, 344, 372, - /* 1470 */ 1114, 1105, 748, 1113, 374, 1112, 254, 458, 1086, 255, - /* 1480 */ 345, 1085, 302, 1084, 1355, 78, 1154, 311, 1104, 449, - /* 1490 */ 452, 1155, 1153, 218, 7, 313, 315, 320, 1152, 85, - /* 1500 */ 1252, 317, 109, 80, 463, 225, 461, 1068, 25, 487, - /* 1510 */ 997, 323, 257, 226, 229, 228, 1136, 324, 325, 326, - /* 1520 */ 488, 136, 1057, 1052, 1302, 1303, 1301, 706, 1300, 137, - /* 1530 */ 122, 138, 383, 173, 1082, 261, 186, 252, 1081, 65, - /* 1540 */ 387, 120, 938, 936, 855, 353, 149, 1079, 139, 151, - /* 1550 */ 192, 780, 195, 276, 952, 157, 141, 361, 70, 363, - /* 1560 */ 859, 159, 71, 72, 142, 73, 955, 354, 147, 197, - /* 1570 */ 198, 951, 130, 16, 199, 285, 216, 1032, 201, 423, - /* 1580 */ 164, 944, 163, 28, 721, 428, 304, 165, 205, 759, - /* 1590 */ 75, 432, 298, 17, 18, 437, 76, 253, 878, 144, - /* 1600 */ 877, 906, 77, 986, 30, 448, 987, 31, 451, 181, - /* 1610 */ 234, 236, 168, 828, 823, 89, 910, 921, 81, 907, - /* 1620 */ 215, 905, 909, 961, 960, 19, 221, 20, 220, 22, - /* 1630 */ 32, 331, 876, 731, 94, 790, 794, 8, 992, 222, - /* 1640 */ 480, 328, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, - /* 1650 */ 223, 1048, 1048, 1048, 1048, 1348, 1347, + /* 0 */ 368, 105, 102, 197, 105, 102, 197, 515, 1124, 1, + /* 10 */ 1, 520, 2, 1128, 515, 1192, 1171, 1456, 275, 370, + /* 20 */ 127, 1389, 1197, 1197, 1192, 1166, 178, 1205, 64, 64, + /* 30 */ 477, 887, 322, 428, 348, 37, 37, 808, 362, 888, + /* 40 */ 509, 509, 509, 112, 113, 103, 1100, 1100, 953, 956, + /* 50 */ 946, 946, 110, 110, 111, 111, 111, 111, 365, 252, + /* 60 */ 252, 515, 252, 252, 497, 515, 309, 515, 459, 515, + /* 70 */ 1079, 491, 512, 478, 6, 512, 809, 134, 498, 228, + /* 80 */ 194, 428, 37, 37, 515, 208, 64, 64, 64, 64, + /* 90 */ 13, 13, 109, 109, 109, 109, 108, 108, 107, 107, + /* 100 */ 107, 106, 401, 258, 381, 13, 13, 398, 397, 428, + /* 110 */ 252, 252, 370, 476, 405, 1104, 1079, 1080, 1081, 386, + /* 120 */ 1106, 390, 497, 512, 497, 1423, 1419, 304, 1105, 307, + /* 130 */ 1256, 496, 370, 499, 16, 16, 112, 113, 103, 1100, + /* 140 */ 1100, 953, 956, 946, 946, 110, 110, 111, 111, 111, + /* 150 */ 111, 262, 1107, 495, 1107, 401, 112, 113, 103, 1100, + /* 160 */ 1100, 953, 956, 946, 946, 110, 110, 111, 111, 111, + /* 170 */ 111, 129, 1425, 343, 1420, 339, 1059, 492, 1057, 263, + /* 180 */ 73, 105, 102, 197, 994, 109, 109, 109, 109, 108, + /* 190 */ 108, 107, 107, 107, 106, 401, 370, 111, 111, 111, + /* 200 */ 111, 104, 492, 89, 1432, 109, 109, 109, 109, 108, + /* 210 */ 108, 107, 107, 107, 106, 401, 111, 111, 111, 111, + /* 220 */ 112, 113, 103, 1100, 1100, 953, 956, 946, 946, 110, + /* 230 */ 110, 111, 111, 111, 111, 109, 109, 109, 109, 108, + /* 240 */ 108, 107, 107, 107, 106, 401, 114, 108, 108, 107, + /* 250 */ 107, 107, 106, 401, 109, 109, 109, 109, 108, 108, + /* 260 */ 107, 107, 107, 106, 401, 152, 399, 399, 399, 109, + /* 270 */ 109, 109, 109, 108, 108, 107, 107, 107, 106, 401, + /* 280 */ 178, 493, 1412, 434, 1037, 1486, 1079, 515, 1486, 370, + /* 290 */ 421, 297, 357, 412, 74, 1079, 109, 109, 109, 109, + /* 300 */ 108, 108, 107, 107, 107, 106, 401, 1413, 37, 37, + /* 310 */ 1431, 274, 506, 112, 113, 103, 1100, 1100, 953, 956, + /* 320 */ 946, 946, 110, 110, 111, 111, 111, 111, 1436, 520, + /* 330 */ 2, 1128, 1079, 1080, 1081, 430, 275, 1079, 127, 366, + /* 340 */ 933, 1079, 1080, 1081, 220, 1205, 913, 458, 455, 454, + /* 350 */ 392, 167, 515, 1035, 152, 445, 924, 453, 152, 874, + /* 360 */ 923, 289, 109, 109, 109, 109, 108, 108, 107, 107, + /* 370 */ 107, 106, 401, 13, 13, 261, 853, 252, 252, 227, + /* 380 */ 106, 401, 370, 1079, 1080, 1081, 311, 388, 1079, 296, + /* 390 */ 512, 923, 923, 925, 231, 323, 1255, 1388, 1423, 490, + /* 400 */ 274, 506, 12, 208, 274, 506, 112, 113, 103, 1100, + /* 410 */ 1100, 953, 956, 946, 946, 110, 110, 111, 111, 111, + /* 420 */ 111, 1440, 286, 1128, 288, 1079, 1097, 247, 275, 1098, + /* 430 */ 127, 387, 405, 389, 1079, 1080, 1081, 1205, 159, 238, + /* 440 */ 255, 321, 461, 316, 460, 225, 790, 105, 102, 197, + /* 450 */ 513, 314, 842, 842, 445, 109, 109, 109, 109, 108, + /* 460 */ 108, 107, 107, 107, 106, 401, 515, 514, 515, 252, + /* 470 */ 252, 1079, 1080, 1081, 435, 370, 1098, 933, 1460, 794, + /* 480 */ 274, 506, 512, 105, 102, 197, 336, 63, 63, 64, + /* 490 */ 64, 27, 790, 924, 287, 208, 1354, 923, 515, 112, + /* 500 */ 113, 103, 1100, 1100, 953, 956, 946, 946, 110, 110, + /* 510 */ 111, 111, 111, 111, 107, 107, 107, 106, 401, 49, + /* 520 */ 49, 515, 28, 1079, 405, 497, 421, 297, 923, 923, + /* 530 */ 925, 186, 468, 1079, 467, 999, 999, 442, 515, 1079, + /* 540 */ 334, 515, 45, 45, 1083, 342, 173, 168, 109, 109, + /* 550 */ 109, 109, 108, 108, 107, 107, 107, 106, 401, 13, + /* 560 */ 13, 205, 13, 13, 252, 252, 1195, 1195, 370, 1079, + /* 570 */ 1080, 1081, 787, 265, 5, 359, 494, 512, 469, 1079, + /* 580 */ 1080, 1081, 398, 397, 1079, 1079, 1080, 1081, 3, 282, + /* 590 */ 1079, 1083, 112, 113, 103, 1100, 1100, 953, 956, 946, + /* 600 */ 946, 110, 110, 111, 111, 111, 111, 252, 252, 1015, + /* 610 */ 220, 1079, 873, 458, 455, 454, 943, 943, 954, 957, + /* 620 */ 512, 252, 252, 453, 1016, 1079, 445, 1107, 1209, 1107, + /* 630 */ 1079, 1080, 1081, 515, 512, 426, 1079, 1080, 1081, 1017, + /* 640 */ 512, 109, 109, 109, 109, 108, 108, 107, 107, 107, + /* 650 */ 106, 401, 1052, 515, 50, 50, 515, 1079, 1080, 1081, + /* 660 */ 828, 370, 1051, 379, 411, 1064, 1358, 207, 408, 773, + /* 670 */ 829, 1079, 1080, 1081, 64, 64, 322, 64, 64, 1302, + /* 680 */ 947, 411, 410, 1358, 1360, 112, 113, 103, 1100, 1100, + /* 690 */ 953, 956, 946, 946, 110, 110, 111, 111, 111, 111, + /* 700 */ 294, 482, 515, 1037, 1487, 515, 434, 1487, 354, 1120, + /* 710 */ 483, 996, 913, 485, 466, 996, 132, 178, 33, 450, + /* 720 */ 1203, 136, 406, 64, 64, 479, 64, 64, 419, 369, + /* 730 */ 283, 1146, 252, 252, 109, 109, 109, 109, 108, 108, + /* 740 */ 107, 107, 107, 106, 401, 512, 224, 440, 411, 266, + /* 750 */ 1358, 266, 252, 252, 370, 296, 416, 284, 934, 396, + /* 760 */ 976, 470, 400, 252, 252, 512, 9, 473, 231, 500, + /* 770 */ 354, 1036, 1035, 1488, 355, 374, 512, 1121, 112, 113, + /* 780 */ 103, 1100, 1100, 953, 956, 946, 946, 110, 110, 111, + /* 790 */ 111, 111, 111, 252, 252, 1015, 515, 1347, 295, 252, + /* 800 */ 252, 252, 252, 1098, 375, 249, 512, 445, 872, 322, + /* 810 */ 1016, 480, 512, 195, 512, 434, 273, 15, 15, 515, + /* 820 */ 314, 515, 95, 515, 93, 1017, 367, 109, 109, 109, + /* 830 */ 109, 108, 108, 107, 107, 107, 106, 401, 515, 1121, + /* 840 */ 39, 39, 51, 51, 52, 52, 503, 370, 515, 1204, + /* 850 */ 1098, 918, 439, 341, 133, 436, 223, 222, 221, 53, + /* 860 */ 53, 322, 1400, 761, 762, 763, 515, 370, 88, 54, + /* 870 */ 54, 112, 113, 103, 1100, 1100, 953, 956, 946, 946, + /* 880 */ 110, 110, 111, 111, 111, 111, 407, 55, 55, 196, + /* 890 */ 515, 112, 113, 103, 1100, 1100, 953, 956, 946, 946, + /* 900 */ 110, 110, 111, 111, 111, 111, 135, 264, 1149, 376, + /* 910 */ 515, 40, 40, 515, 872, 515, 993, 515, 993, 116, + /* 920 */ 109, 109, 109, 109, 108, 108, 107, 107, 107, 106, + /* 930 */ 401, 41, 41, 515, 43, 43, 44, 44, 56, 56, + /* 940 */ 109, 109, 109, 109, 108, 108, 107, 107, 107, 106, + /* 950 */ 401, 515, 379, 515, 57, 57, 515, 799, 515, 379, + /* 960 */ 515, 445, 200, 515, 323, 515, 1397, 515, 1459, 515, + /* 970 */ 1287, 817, 58, 58, 14, 14, 515, 59, 59, 118, + /* 980 */ 118, 60, 60, 515, 46, 46, 61, 61, 62, 62, + /* 990 */ 47, 47, 515, 190, 189, 91, 515, 140, 140, 515, + /* 1000 */ 394, 515, 277, 1200, 141, 141, 515, 1115, 515, 992, + /* 1010 */ 515, 992, 515, 69, 69, 370, 278, 48, 48, 259, + /* 1020 */ 65, 65, 119, 119, 246, 246, 260, 66, 66, 120, + /* 1030 */ 120, 121, 121, 117, 117, 370, 515, 512, 383, 112, + /* 1040 */ 113, 103, 1100, 1100, 953, 956, 946, 946, 110, 110, + /* 1050 */ 111, 111, 111, 111, 515, 872, 515, 139, 139, 112, + /* 1060 */ 113, 103, 1100, 1100, 953, 956, 946, 946, 110, 110, + /* 1070 */ 111, 111, 111, 111, 1287, 138, 138, 125, 125, 515, + /* 1080 */ 12, 515, 281, 1287, 515, 445, 131, 1287, 109, 109, + /* 1090 */ 109, 109, 108, 108, 107, 107, 107, 106, 401, 515, + /* 1100 */ 124, 124, 122, 122, 515, 123, 123, 515, 109, 109, + /* 1110 */ 109, 109, 108, 108, 107, 107, 107, 106, 401, 515, + /* 1120 */ 68, 68, 463, 783, 515, 70, 70, 302, 67, 67, + /* 1130 */ 1032, 253, 253, 356, 1287, 191, 196, 1433, 465, 1301, + /* 1140 */ 38, 38, 384, 94, 512, 42, 42, 177, 848, 274, + /* 1150 */ 506, 385, 420, 847, 1356, 441, 508, 376, 377, 153, + /* 1160 */ 423, 872, 432, 370, 224, 251, 194, 887, 182, 293, + /* 1170 */ 783, 848, 88, 254, 466, 888, 847, 915, 807, 806, + /* 1180 */ 230, 1241, 910, 370, 17, 413, 797, 112, 113, 103, + /* 1190 */ 1100, 1100, 953, 956, 946, 946, 110, 110, 111, 111, + /* 1200 */ 111, 111, 395, 814, 815, 1175, 983, 112, 101, 103, + /* 1210 */ 1100, 1100, 953, 956, 946, 946, 110, 110, 111, 111, + /* 1220 */ 111, 111, 375, 422, 427, 429, 298, 230, 230, 88, + /* 1230 */ 1240, 451, 312, 797, 226, 88, 109, 109, 109, 109, + /* 1240 */ 108, 108, 107, 107, 107, 106, 401, 86, 433, 979, + /* 1250 */ 927, 881, 226, 983, 230, 415, 109, 109, 109, 109, + /* 1260 */ 108, 108, 107, 107, 107, 106, 401, 320, 845, 781, + /* 1270 */ 846, 100, 130, 100, 1403, 290, 370, 319, 1377, 1376, + /* 1280 */ 437, 1449, 299, 1237, 303, 306, 308, 310, 1188, 1174, + /* 1290 */ 1173, 1172, 315, 324, 325, 1228, 370, 927, 1249, 271, + /* 1300 */ 1286, 113, 103, 1100, 1100, 953, 956, 946, 946, 110, + /* 1310 */ 110, 111, 111, 111, 111, 1224, 1235, 502, 501, 1292, + /* 1320 */ 1221, 1155, 103, 1100, 1100, 953, 956, 946, 946, 110, + /* 1330 */ 110, 111, 111, 111, 111, 1148, 1137, 1136, 1138, 1443, + /* 1340 */ 446, 244, 184, 98, 507, 188, 4, 353, 327, 109, + /* 1350 */ 109, 109, 109, 108, 108, 107, 107, 107, 106, 401, + /* 1360 */ 510, 329, 331, 199, 414, 456, 292, 285, 318, 109, + /* 1370 */ 109, 109, 109, 108, 108, 107, 107, 107, 106, 401, + /* 1380 */ 11, 1271, 1279, 402, 361, 192, 1171, 1351, 431, 505, + /* 1390 */ 346, 1350, 333, 98, 507, 504, 4, 187, 1446, 1115, + /* 1400 */ 233, 1396, 155, 1394, 1112, 152, 72, 75, 378, 425, + /* 1410 */ 510, 165, 149, 157, 933, 1276, 86, 30, 1268, 417, + /* 1420 */ 96, 96, 8, 160, 161, 162, 163, 97, 418, 402, + /* 1430 */ 517, 516, 449, 402, 923, 210, 358, 424, 1282, 438, + /* 1440 */ 169, 214, 360, 1345, 80, 504, 31, 444, 1365, 301, + /* 1450 */ 245, 274, 506, 216, 174, 305, 488, 447, 217, 462, + /* 1460 */ 1139, 487, 218, 363, 933, 923, 923, 925, 926, 24, + /* 1470 */ 96, 96, 1191, 1190, 1189, 391, 1182, 97, 1163, 402, + /* 1480 */ 517, 516, 799, 364, 923, 1162, 317, 1161, 98, 507, + /* 1490 */ 1181, 4, 1458, 472, 393, 269, 270, 475, 481, 1232, + /* 1500 */ 85, 1233, 326, 328, 232, 510, 495, 1231, 330, 98, + /* 1510 */ 507, 1230, 4, 486, 335, 923, 923, 925, 926, 24, + /* 1520 */ 1435, 1068, 404, 181, 336, 256, 510, 115, 402, 332, + /* 1530 */ 352, 352, 351, 241, 349, 1214, 1414, 770, 338, 10, + /* 1540 */ 504, 340, 272, 92, 1331, 1213, 87, 183, 484, 402, + /* 1550 */ 201, 488, 280, 239, 344, 345, 489, 1145, 29, 933, + /* 1560 */ 279, 504, 1074, 518, 240, 96, 96, 242, 243, 519, + /* 1570 */ 1134, 1129, 97, 154, 402, 517, 516, 372, 373, 923, + /* 1580 */ 933, 142, 143, 128, 1381, 267, 96, 96, 852, 757, + /* 1590 */ 203, 144, 403, 97, 1382, 402, 517, 516, 204, 1380, + /* 1600 */ 923, 146, 1379, 1159, 1158, 71, 1156, 276, 202, 185, + /* 1610 */ 923, 923, 925, 926, 24, 198, 257, 126, 991, 989, + /* 1620 */ 907, 98, 507, 156, 4, 145, 158, 206, 831, 209, + /* 1630 */ 291, 923, 923, 925, 926, 24, 1005, 911, 510, 164, + /* 1640 */ 147, 380, 371, 382, 166, 76, 77, 274, 506, 148, + /* 1650 */ 78, 79, 1008, 211, 212, 1004, 137, 213, 18, 300, + /* 1660 */ 230, 402, 997, 1109, 443, 215, 32, 170, 171, 772, + /* 1670 */ 409, 448, 319, 504, 219, 172, 452, 81, 19, 457, + /* 1680 */ 313, 20, 82, 268, 488, 150, 810, 179, 83, 487, + /* 1690 */ 464, 151, 933, 180, 959, 84, 1040, 34, 96, 96, + /* 1700 */ 471, 1041, 35, 474, 193, 97, 248, 402, 517, 516, + /* 1710 */ 1068, 404, 923, 250, 256, 880, 229, 175, 875, 352, + /* 1720 */ 352, 351, 241, 349, 100, 21, 770, 22, 1054, 1056, + /* 1730 */ 7, 98, 507, 1045, 4, 337, 1058, 23, 974, 201, + /* 1740 */ 176, 280, 88, 923, 923, 925, 926, 24, 510, 279, + /* 1750 */ 960, 958, 962, 1014, 963, 1013, 235, 234, 25, 36, + /* 1760 */ 99, 90, 507, 928, 4, 511, 350, 782, 26, 841, + /* 1770 */ 236, 402, 347, 1069, 237, 1125, 1125, 1451, 510, 203, + /* 1780 */ 1450, 1125, 1125, 504, 1125, 1125, 1125, 204, 1125, 1125, + /* 1790 */ 146, 1125, 1125, 1125, 1125, 1125, 1125, 202, 1125, 1125, + /* 1800 */ 1125, 402, 933, 1125, 1125, 1125, 1125, 1125, 96, 96, + /* 1810 */ 1125, 1125, 1125, 504, 1125, 97, 1125, 402, 517, 516, + /* 1820 */ 1125, 1125, 923, 1125, 1125, 1125, 1125, 1125, 1125, 1125, + /* 1830 */ 1125, 371, 933, 1125, 1125, 1125, 274, 506, 96, 96, + /* 1840 */ 1125, 1125, 1125, 1125, 1125, 97, 1125, 402, 517, 516, + /* 1850 */ 1125, 1125, 923, 923, 923, 925, 926, 24, 1125, 409, + /* 1860 */ 1125, 1125, 1125, 256, 1125, 1125, 1125, 1125, 352, 352, + /* 1870 */ 351, 241, 349, 1125, 1125, 770, 1125, 1125, 1125, 1125, + /* 1880 */ 1125, 1125, 1125, 923, 923, 925, 926, 24, 201, 1125, + /* 1890 */ 280, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 279, 1125, + /* 1900 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, + /* 1910 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, + /* 1920 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 203, 1125, + /* 1930 */ 1125, 1125, 1125, 1125, 1125, 1125, 204, 1125, 1125, 146, + /* 1940 */ 1125, 1125, 1125, 1125, 1125, 1125, 202, 1125, 1125, 1125, + /* 1950 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, + /* 1960 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, + /* 1970 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, + /* 1980 */ 371, 1125, 1125, 1125, 1125, 274, 506, 1125, 1125, 1125, + /* 1990 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, + /* 2000 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 409, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 174, 226, 227, 228, 226, 227, 228, 172, 145, 146, - /* 10 */ 147, 148, 149, 150, 153, 169, 170, 171, 155, 19, - /* 20 */ 157, 246, 192, 193, 177, 181, 182, 164, 169, 170, - /* 30 */ 171, 31, 164, 153, 190, 174, 175, 187, 153, 39, - /* 40 */ 7, 8, 9, 43, 44, 45, 46, 47, 48, 49, - /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 174, 196, - /* 60 */ 197, 226, 227, 228, 196, 197, 46, 47, 48, 49, - /* 70 */ 209, 208, 19, 226, 227, 228, 208, 174, 177, 26, - /* 80 */ 195, 213, 214, 22, 221, 85, 86, 87, 88, 89, - /* 90 */ 90, 91, 92, 93, 94, 95, 43, 44, 45, 46, - /* 100 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 110 */ 57, 172, 249, 153, 53, 153, 147, 148, 149, 150, - /* 120 */ 22, 23, 69, 103, 155, 19, 157, 226, 227, 228, - /* 130 */ 94, 95, 247, 164, 174, 175, 174, 175, 85, 86, - /* 140 */ 87, 88, 89, 90, 91, 92, 93, 94, 95, 43, - /* 150 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - /* 160 */ 54, 55, 56, 57, 153, 196, 197, 153, 153, 209, - /* 170 */ 210, 209, 210, 67, 95, 161, 237, 208, 19, 165, - /* 180 */ 165, 242, 84, 24, 91, 92, 93, 94, 95, 223, - /* 190 */ 221, 85, 86, 87, 88, 89, 90, 91, 92, 93, - /* 200 */ 94, 95, 43, 44, 45, 46, 47, 48, 49, 50, - /* 210 */ 51, 52, 53, 54, 55, 56, 57, 153, 249, 85, - /* 220 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - /* 230 */ 219, 19, 109, 110, 111, 23, 89, 90, 91, 92, - /* 240 */ 93, 94, 95, 73, 85, 86, 87, 88, 89, 90, - /* 250 */ 91, 92, 93, 94, 95, 43, 44, 45, 46, 47, - /* 260 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 270 */ 153, 22, 23, 101, 173, 26, 104, 105, 106, 109, - /* 280 */ 110, 111, 181, 11, 19, 59, 114, 73, 23, 110, - /* 290 */ 111, 174, 175, 116, 80, 118, 119, 85, 86, 87, - /* 300 */ 88, 89, 90, 91, 92, 93, 94, 95, 43, 44, - /* 310 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - /* 320 */ 55, 56, 57, 109, 98, 99, 100, 101, 83, 153, - /* 330 */ 104, 105, 106, 84, 120, 121, 153, 19, 192, 193, - /* 340 */ 114, 23, 89, 90, 99, 59, 23, 230, 103, 26, - /* 350 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, - /* 360 */ 95, 43, 44, 45, 46, 47, 48, 49, 50, 51, - /* 370 */ 52, 53, 54, 55, 56, 57, 153, 91, 153, 134, - /* 380 */ 135, 136, 110, 111, 98, 99, 100, 134, 153, 136, - /* 390 */ 19, 22, 23, 26, 23, 26, 80, 174, 175, 174, - /* 400 */ 175, 59, 219, 85, 86, 87, 88, 89, 90, 91, - /* 410 */ 92, 93, 94, 95, 43, 44, 45, 46, 47, 48, - /* 420 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 16, - /* 430 */ 153, 22, 209, 210, 209, 210, 120, 121, 196, 197, - /* 440 */ 98, 99, 100, 19, 46, 22, 23, 23, 252, 253, - /* 450 */ 208, 174, 175, 84, 219, 153, 85, 86, 87, 88, - /* 460 */ 89, 90, 91, 92, 93, 94, 95, 43, 44, 45, - /* 470 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - /* 480 */ 56, 57, 153, 153, 153, 153, 209, 120, 121, 76, - /* 490 */ 153, 78, 109, 110, 111, 97, 19, 153, 89, 90, - /* 500 */ 198, 59, 183, 174, 175, 174, 175, 84, 153, 85, - /* 510 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - /* 520 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 530 */ 53, 54, 55, 56, 57, 16, 197, 153, 22, 153, - /* 540 */ 153, 99, 198, 12, 153, 196, 197, 208, 153, 153, - /* 550 */ 195, 183, 19, 23, 222, 142, 26, 208, 27, 153, - /* 560 */ 174, 175, 85, 86, 87, 88, 89, 90, 91, 92, - /* 570 */ 93, 94, 95, 42, 188, 59, 43, 44, 45, 46, - /* 580 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 590 */ 57, 195, 22, 198, 63, 76, 153, 78, 167, 168, - /* 600 */ 153, 195, 167, 168, 73, 153, 222, 153, 19, 222, - /* 610 */ 153, 220, 153, 24, 98, 99, 100, 140, 85, 86, - /* 620 */ 87, 88, 89, 90, 91, 92, 93, 94, 95, 59, - /* 630 */ 100, 153, 43, 44, 45, 46, 47, 48, 49, 50, - /* 640 */ 51, 52, 53, 54, 55, 56, 57, 195, 153, 195, - /* 650 */ 153, 153, 174, 175, 26, 125, 120, 121, 153, 213, - /* 660 */ 214, 19, 153, 220, 153, 153, 188, 220, 98, 99, - /* 670 */ 100, 174, 175, 140, 85, 86, 87, 88, 89, 90, - /* 680 */ 91, 92, 93, 94, 95, 43, 44, 45, 46, 47, + /* 0 */ 184, 238, 239, 240, 238, 239, 240, 163, 155, 156, + /* 10 */ 157, 158, 159, 160, 163, 191, 192, 183, 165, 19, + /* 20 */ 167, 258, 202, 203, 200, 191, 163, 174, 184, 185, + /* 30 */ 174, 31, 163, 163, 171, 184, 185, 35, 175, 39, + /* 40 */ 179, 180, 181, 43, 44, 45, 46, 47, 48, 49, + /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 184, 206, + /* 60 */ 207, 163, 206, 207, 220, 163, 16, 163, 66, 163, + /* 70 */ 59, 270, 219, 229, 273, 219, 74, 208, 174, 223, + /* 80 */ 224, 163, 184, 185, 163, 232, 184, 185, 184, 185, + /* 90 */ 184, 185, 92, 93, 94, 95, 96, 97, 98, 99, + /* 100 */ 100, 101, 102, 233, 198, 184, 185, 96, 97, 163, + /* 110 */ 206, 207, 19, 163, 261, 104, 105, 106, 107, 198, + /* 120 */ 109, 119, 220, 219, 220, 274, 275, 77, 117, 79, + /* 130 */ 187, 229, 19, 229, 184, 185, 43, 44, 45, 46, + /* 140 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 150 */ 57, 233, 141, 134, 143, 102, 43, 44, 45, 46, + /* 160 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 170 */ 57, 152, 274, 216, 276, 218, 83, 163, 85, 233, + /* 180 */ 67, 238, 239, 240, 11, 92, 93, 94, 95, 96, + /* 190 */ 97, 98, 99, 100, 101, 102, 19, 54, 55, 56, + /* 200 */ 57, 58, 163, 26, 163, 92, 93, 94, 95, 96, + /* 210 */ 97, 98, 99, 100, 101, 102, 54, 55, 56, 57, + /* 220 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + /* 230 */ 53, 54, 55, 56, 57, 92, 93, 94, 95, 96, + /* 240 */ 97, 98, 99, 100, 101, 102, 69, 96, 97, 98, + /* 250 */ 99, 100, 101, 102, 92, 93, 94, 95, 96, 97, + /* 260 */ 98, 99, 100, 101, 102, 81, 179, 180, 181, 92, + /* 270 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + /* 280 */ 163, 267, 268, 163, 22, 23, 59, 163, 26, 19, + /* 290 */ 117, 118, 175, 109, 24, 59, 92, 93, 94, 95, + /* 300 */ 96, 97, 98, 99, 100, 101, 102, 268, 184, 185, + /* 310 */ 269, 127, 128, 43, 44, 45, 46, 47, 48, 49, + /* 320 */ 50, 51, 52, 53, 54, 55, 56, 57, 157, 158, + /* 330 */ 159, 160, 105, 106, 107, 163, 165, 59, 167, 184, + /* 340 */ 90, 105, 106, 107, 108, 174, 73, 111, 112, 113, + /* 350 */ 19, 22, 163, 91, 81, 163, 106, 121, 81, 132, + /* 360 */ 110, 16, 92, 93, 94, 95, 96, 97, 98, 99, + /* 370 */ 100, 101, 102, 184, 185, 255, 98, 206, 207, 26, + /* 380 */ 101, 102, 19, 105, 106, 107, 23, 198, 59, 116, + /* 390 */ 219, 141, 142, 143, 24, 163, 187, 205, 274, 275, + /* 400 */ 127, 128, 182, 232, 127, 128, 43, 44, 45, 46, + /* 410 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 420 */ 57, 158, 77, 160, 79, 59, 26, 182, 165, 59, + /* 430 */ 167, 199, 261, 102, 105, 106, 107, 174, 72, 108, + /* 440 */ 109, 110, 111, 112, 113, 114, 59, 238, 239, 240, + /* 450 */ 123, 120, 125, 126, 163, 92, 93, 94, 95, 96, + /* 460 */ 97, 98, 99, 100, 101, 102, 163, 163, 163, 206, + /* 470 */ 207, 105, 106, 107, 254, 19, 106, 90, 197, 23, + /* 480 */ 127, 128, 219, 238, 239, 240, 22, 184, 185, 184, + /* 490 */ 185, 22, 105, 106, 149, 232, 205, 110, 163, 43, + /* 500 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + /* 510 */ 54, 55, 56, 57, 98, 99, 100, 101, 102, 184, + /* 520 */ 185, 163, 53, 59, 261, 220, 117, 118, 141, 142, + /* 530 */ 143, 131, 174, 59, 229, 116, 117, 118, 163, 59, + /* 540 */ 163, 163, 184, 185, 59, 242, 72, 22, 92, 93, + /* 550 */ 94, 95, 96, 97, 98, 99, 100, 101, 102, 184, + /* 560 */ 185, 24, 184, 185, 206, 207, 202, 203, 19, 105, + /* 570 */ 106, 107, 23, 198, 22, 174, 198, 219, 220, 105, + /* 580 */ 106, 107, 96, 97, 59, 105, 106, 107, 22, 174, + /* 590 */ 59, 106, 43, 44, 45, 46, 47, 48, 49, 50, + /* 600 */ 51, 52, 53, 54, 55, 56, 57, 206, 207, 12, + /* 610 */ 108, 59, 132, 111, 112, 113, 46, 47, 48, 49, + /* 620 */ 219, 206, 207, 121, 27, 59, 163, 141, 207, 143, + /* 630 */ 105, 106, 107, 163, 219, 234, 105, 106, 107, 42, + /* 640 */ 219, 92, 93, 94, 95, 96, 97, 98, 99, 100, + /* 650 */ 101, 102, 76, 163, 184, 185, 163, 105, 106, 107, + /* 660 */ 63, 19, 86, 163, 163, 23, 163, 130, 205, 21, + /* 670 */ 73, 105, 106, 107, 184, 185, 163, 184, 185, 237, + /* 680 */ 110, 180, 181, 180, 181, 43, 44, 45, 46, 47, /* 690 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 700 */ 243, 189, 243, 198, 172, 250, 251, 117, 31, 201, - /* 710 */ 26, 139, 122, 141, 19, 220, 39, 29, 220, 211, - /* 720 */ 24, 33, 153, 164, 153, 164, 19, 85, 86, 87, - /* 730 */ 88, 89, 90, 91, 92, 93, 94, 95, 43, 44, - /* 740 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - /* 750 */ 55, 56, 57, 65, 243, 196, 197, 196, 197, 131, - /* 760 */ 189, 22, 103, 24, 153, 23, 19, 208, 26, 208, - /* 770 */ 102, 103, 113, 23, 242, 22, 26, 134, 164, 136, - /* 780 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, - /* 790 */ 95, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 800 */ 53, 54, 55, 56, 57, 98, 153, 153, 124, 153, - /* 810 */ 196, 197, 23, 23, 61, 26, 26, 19, 23, 123, - /* 820 */ 23, 26, 208, 26, 7, 8, 153, 22, 174, 175, - /* 830 */ 174, 175, 85, 86, 87, 88, 89, 90, 91, 92, - /* 840 */ 93, 94, 95, 45, 46, 47, 48, 49, 50, 51, - /* 850 */ 52, 53, 54, 55, 56, 57, 19, 20, 59, 22, - /* 860 */ 111, 59, 164, 23, 59, 23, 26, 153, 26, 59, - /* 870 */ 153, 72, 23, 36, 72, 26, 35, 23, 59, 134, - /* 880 */ 26, 136, 133, 85, 86, 87, 88, 89, 90, 91, - /* 890 */ 92, 93, 94, 95, 196, 197, 59, 98, 99, 100, - /* 900 */ 98, 99, 100, 98, 99, 100, 208, 66, 71, 99, - /* 910 */ 54, 55, 56, 57, 58, 74, 153, 80, 99, 19, - /* 920 */ 83, 223, 23, 26, 153, 26, 89, 90, 54, 55, - /* 930 */ 56, 57, 153, 96, 153, 98, 99, 100, 22, 153, - /* 940 */ 103, 85, 86, 87, 88, 89, 90, 91, 92, 93, - /* 950 */ 94, 95, 183, 112, 158, 174, 175, 120, 121, 85, - /* 960 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - /* 970 */ 215, 134, 135, 136, 137, 138, 0, 1, 2, 23, - /* 980 */ 21, 5, 26, 153, 22, 59, 10, 11, 12, 13, - /* 990 */ 14, 1, 2, 17, 212, 5, 153, 153, 98, 153, - /* 1000 */ 10, 11, 12, 13, 14, 108, 30, 17, 32, 193, - /* 1010 */ 153, 59, 153, 153, 170, 171, 40, 174, 175, 153, - /* 1020 */ 30, 59, 32, 19, 20, 99, 22, 170, 171, 233, - /* 1030 */ 40, 188, 236, 174, 175, 153, 153, 153, 79, 123, - /* 1040 */ 36, 89, 90, 153, 153, 153, 70, 188, 153, 97, - /* 1050 */ 98, 99, 100, 77, 102, 153, 80, 81, 174, 175, - /* 1060 */ 70, 99, 110, 59, 105, 174, 175, 77, 153, 238, - /* 1070 */ 80, 81, 188, 19, 20, 71, 22, 153, 153, 235, - /* 1080 */ 19, 22, 164, 24, 59, 153, 134, 83, 136, 153, - /* 1090 */ 36, 115, 235, 89, 90, 91, 120, 121, 153, 153, - /* 1100 */ 96, 142, 98, 99, 100, 115, 59, 103, 83, 239, - /* 1110 */ 120, 121, 199, 59, 196, 197, 153, 153, 59, 143, - /* 1120 */ 174, 175, 153, 98, 99, 71, 208, 153, 103, 165, - /* 1130 */ 153, 19, 20, 143, 22, 153, 153, 83, 134, 135, - /* 1140 */ 136, 137, 138, 89, 90, 98, 99, 100, 36, 185, - /* 1150 */ 96, 187, 98, 99, 100, 91, 95, 103, 99, 134, - /* 1160 */ 135, 136, 101, 102, 103, 104, 105, 106, 107, 153, - /* 1170 */ 26, 59, 125, 164, 113, 153, 153, 153, 212, 12, - /* 1180 */ 19, 117, 153, 71, 153, 212, 122, 164, 134, 135, - /* 1190 */ 136, 137, 138, 212, 27, 83, 212, 174, 175, 59, - /* 1200 */ 200, 89, 90, 174, 175, 196, 197, 46, 96, 42, - /* 1210 */ 98, 99, 100, 172, 151, 103, 5, 208, 203, 196, - /* 1220 */ 197, 10, 11, 12, 13, 14, 216, 216, 17, 244, - /* 1230 */ 63, 208, 209, 210, 153, 80, 24, 203, 98, 99, - /* 1240 */ 100, 30, 22, 32, 100, 164, 134, 135, 136, 137, - /* 1250 */ 138, 40, 148, 164, 150, 174, 175, 102, 97, 155, - /* 1260 */ 203, 157, 164, 244, 178, 125, 186, 182, 164, 125, - /* 1270 */ 177, 59, 177, 177, 113, 120, 121, 196, 197, 59, - /* 1280 */ 232, 70, 153, 216, 202, 196, 197, 153, 77, 208, - /* 1290 */ 209, 80, 81, 156, 196, 197, 60, 208, 248, 200, - /* 1300 */ 196, 197, 153, 174, 175, 123, 208, 153, 174, 175, - /* 1310 */ 160, 99, 208, 153, 38, 153, 160, 153, 98, 99, - /* 1320 */ 100, 153, 245, 174, 175, 221, 115, 153, 174, 175, - /* 1330 */ 153, 120, 121, 245, 174, 175, 174, 175, 174, 175, - /* 1340 */ 160, 153, 174, 175, 153, 225, 153, 22, 174, 175, - /* 1350 */ 97, 174, 175, 249, 143, 153, 224, 153, 43, 153, - /* 1360 */ 191, 153, 174, 175, 18, 174, 175, 174, 175, 153, - /* 1370 */ 131, 153, 194, 203, 153, 194, 174, 175, 174, 175, - /* 1380 */ 174, 175, 174, 175, 153, 160, 153, 18, 153, 194, - /* 1390 */ 174, 175, 174, 175, 153, 174, 175, 153, 225, 153, - /* 1400 */ 203, 153, 159, 153, 194, 174, 175, 174, 175, 174, - /* 1410 */ 175, 153, 203, 153, 224, 174, 175, 191, 174, 175, - /* 1420 */ 174, 175, 174, 175, 174, 175, 203, 160, 153, 191, - /* 1430 */ 153, 159, 174, 175, 174, 175, 153, 139, 62, 153, - /* 1440 */ 241, 153, 160, 153, 159, 153, 22, 240, 179, 174, - /* 1450 */ 175, 174, 175, 160, 159, 97, 160, 174, 175, 159, - /* 1460 */ 174, 175, 174, 175, 174, 175, 174, 175, 179, 64, - /* 1470 */ 176, 184, 108, 176, 95, 176, 234, 126, 176, 234, - /* 1480 */ 179, 178, 176, 176, 176, 97, 218, 217, 184, 179, - /* 1490 */ 179, 218, 218, 160, 22, 217, 217, 160, 218, 139, - /* 1500 */ 229, 217, 130, 129, 127, 25, 128, 163, 26, 162, - /* 1510 */ 13, 206, 231, 154, 6, 154, 207, 205, 204, 203, - /* 1520 */ 152, 166, 152, 152, 172, 172, 172, 4, 172, 166, - /* 1530 */ 180, 166, 3, 22, 172, 144, 15, 180, 172, 172, - /* 1540 */ 82, 16, 23, 23, 121, 254, 132, 172, 112, 124, - /* 1550 */ 24, 20, 126, 16, 1, 124, 112, 61, 53, 37, - /* 1560 */ 133, 132, 53, 53, 112, 53, 98, 254, 251, 34, - /* 1570 */ 123, 1, 5, 22, 97, 142, 26, 75, 123, 41, - /* 1580 */ 97, 68, 68, 24, 20, 19, 113, 22, 107, 28, - /* 1590 */ 22, 67, 23, 22, 22, 67, 22, 67, 23, 37, - /* 1600 */ 23, 23, 26, 23, 22, 24, 23, 22, 24, 123, - /* 1610 */ 23, 23, 22, 98, 125, 26, 11, 23, 26, 23, - /* 1620 */ 34, 23, 23, 23, 23, 34, 22, 34, 26, 22, - /* 1630 */ 22, 15, 23, 23, 22, 117, 23, 22, 1, 123, - /* 1640 */ 26, 23, 255, 255, 255, 255, 255, 255, 255, 255, - /* 1650 */ 123, 255, 255, 255, 255, 123, 123, 255, 255, 255, - /* 1660 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - /* 1670 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - /* 1680 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - /* 1690 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - /* 1700 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - /* 1710 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - /* 1720 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - /* 1730 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - /* 1740 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - /* 1750 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - /* 1760 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - /* 1770 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - /* 1780 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - /* 1790 */ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - /* 1800 */ 255, 255, + /* 700 */ 174, 163, 163, 22, 23, 163, 163, 26, 22, 23, + /* 710 */ 220, 29, 73, 220, 272, 33, 22, 163, 24, 19, + /* 720 */ 174, 208, 259, 184, 185, 19, 184, 185, 80, 175, + /* 730 */ 230, 174, 206, 207, 92, 93, 94, 95, 96, 97, + /* 740 */ 98, 99, 100, 101, 102, 219, 46, 65, 247, 195, + /* 750 */ 247, 197, 206, 207, 19, 116, 117, 118, 23, 220, + /* 760 */ 112, 174, 220, 206, 207, 219, 22, 174, 24, 174, + /* 770 */ 22, 23, 91, 264, 265, 168, 219, 91, 43, 44, + /* 780 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + /* 790 */ 55, 56, 57, 206, 207, 12, 163, 149, 255, 206, + /* 800 */ 207, 206, 207, 59, 104, 23, 219, 163, 26, 163, + /* 810 */ 27, 105, 219, 163, 219, 163, 211, 184, 185, 163, + /* 820 */ 120, 163, 146, 163, 148, 42, 221, 92, 93, 94, + /* 830 */ 95, 96, 97, 98, 99, 100, 101, 102, 163, 91, + /* 840 */ 184, 185, 184, 185, 184, 185, 63, 19, 163, 205, + /* 850 */ 106, 23, 245, 163, 208, 248, 116, 117, 118, 184, + /* 860 */ 185, 163, 163, 7, 8, 9, 163, 19, 26, 184, + /* 870 */ 185, 43, 44, 45, 46, 47, 48, 49, 50, 51, + /* 880 */ 52, 53, 54, 55, 56, 57, 163, 184, 185, 107, + /* 890 */ 163, 43, 44, 45, 46, 47, 48, 49, 50, 51, + /* 900 */ 52, 53, 54, 55, 56, 57, 208, 255, 177, 178, + /* 910 */ 163, 184, 185, 163, 132, 163, 141, 163, 143, 22, + /* 920 */ 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + /* 930 */ 102, 184, 185, 163, 184, 185, 184, 185, 184, 185, + /* 940 */ 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + /* 950 */ 102, 163, 163, 163, 184, 185, 163, 115, 163, 163, + /* 960 */ 163, 163, 15, 163, 163, 163, 163, 163, 23, 163, + /* 970 */ 163, 26, 184, 185, 184, 185, 163, 184, 185, 184, + /* 980 */ 185, 184, 185, 163, 184, 185, 184, 185, 184, 185, + /* 990 */ 184, 185, 163, 96, 97, 147, 163, 184, 185, 163, + /* 1000 */ 199, 163, 163, 205, 184, 185, 163, 60, 163, 141, + /* 1010 */ 163, 143, 163, 184, 185, 19, 163, 184, 185, 230, + /* 1020 */ 184, 185, 184, 185, 206, 207, 230, 184, 185, 184, + /* 1030 */ 185, 184, 185, 184, 185, 19, 163, 219, 231, 43, + /* 1040 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + /* 1050 */ 54, 55, 56, 57, 163, 26, 163, 184, 185, 43, + /* 1060 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + /* 1070 */ 54, 55, 56, 57, 163, 184, 185, 184, 185, 163, + /* 1080 */ 182, 163, 163, 163, 163, 163, 22, 163, 92, 93, + /* 1090 */ 94, 95, 96, 97, 98, 99, 100, 101, 102, 163, + /* 1100 */ 184, 185, 184, 185, 163, 184, 185, 163, 92, 93, + /* 1110 */ 94, 95, 96, 97, 98, 99, 100, 101, 102, 163, + /* 1120 */ 184, 185, 98, 59, 163, 184, 185, 205, 184, 185, + /* 1130 */ 23, 206, 207, 26, 163, 26, 107, 153, 154, 237, + /* 1140 */ 184, 185, 231, 147, 219, 184, 185, 249, 124, 127, + /* 1150 */ 128, 231, 254, 129, 163, 231, 177, 178, 262, 263, + /* 1160 */ 118, 132, 19, 19, 46, 223, 224, 31, 24, 23, + /* 1170 */ 106, 124, 26, 22, 272, 39, 129, 23, 109, 110, + /* 1180 */ 26, 163, 140, 19, 22, 234, 59, 43, 44, 45, + /* 1190 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + /* 1200 */ 56, 57, 231, 7, 8, 193, 59, 43, 44, 45, + /* 1210 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + /* 1220 */ 56, 57, 104, 61, 23, 23, 23, 26, 26, 26, + /* 1230 */ 163, 23, 23, 106, 26, 26, 92, 93, 94, 95, + /* 1240 */ 96, 97, 98, 99, 100, 101, 102, 138, 105, 23, + /* 1250 */ 59, 23, 26, 106, 26, 163, 92, 93, 94, 95, + /* 1260 */ 96, 97, 98, 99, 100, 101, 102, 110, 23, 23, + /* 1270 */ 23, 26, 26, 26, 163, 163, 19, 120, 163, 163, + /* 1280 */ 163, 130, 163, 163, 163, 163, 163, 163, 163, 193, + /* 1290 */ 193, 163, 163, 163, 163, 225, 19, 106, 163, 222, + /* 1300 */ 163, 44, 45, 46, 47, 48, 49, 50, 51, 52, + /* 1310 */ 53, 54, 55, 56, 57, 163, 163, 203, 163, 163, + /* 1320 */ 222, 163, 45, 46, 47, 48, 49, 50, 51, 52, + /* 1330 */ 53, 54, 55, 56, 57, 163, 163, 163, 163, 163, + /* 1340 */ 251, 250, 209, 19, 20, 182, 22, 161, 222, 92, + /* 1350 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + /* 1360 */ 36, 222, 222, 260, 226, 188, 256, 226, 187, 92, + /* 1370 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + /* 1380 */ 210, 213, 213, 59, 213, 196, 192, 187, 256, 244, + /* 1390 */ 212, 187, 226, 19, 20, 71, 22, 210, 166, 60, + /* 1400 */ 130, 170, 260, 170, 38, 81, 257, 257, 170, 104, + /* 1410 */ 36, 22, 43, 201, 90, 236, 138, 235, 213, 18, + /* 1420 */ 96, 97, 48, 204, 204, 204, 204, 103, 170, 105, + /* 1430 */ 106, 107, 18, 59, 110, 169, 213, 213, 201, 170, + /* 1440 */ 201, 169, 236, 213, 146, 71, 235, 62, 253, 252, + /* 1450 */ 170, 127, 128, 169, 22, 170, 82, 189, 169, 104, + /* 1460 */ 170, 87, 169, 189, 90, 141, 142, 143, 144, 145, + /* 1470 */ 96, 97, 186, 186, 186, 64, 194, 103, 186, 105, + /* 1480 */ 106, 107, 115, 189, 110, 188, 186, 186, 19, 20, + /* 1490 */ 194, 22, 186, 189, 102, 246, 246, 189, 133, 228, + /* 1500 */ 104, 228, 227, 227, 170, 36, 134, 228, 227, 19, + /* 1510 */ 20, 228, 22, 84, 271, 141, 142, 143, 144, 145, + /* 1520 */ 0, 1, 2, 216, 22, 5, 36, 137, 59, 227, + /* 1530 */ 10, 11, 12, 13, 14, 217, 269, 17, 216, 22, + /* 1540 */ 71, 170, 243, 146, 241, 217, 136, 215, 135, 59, + /* 1550 */ 30, 82, 32, 25, 214, 213, 87, 173, 26, 90, + /* 1560 */ 40, 71, 13, 172, 164, 96, 97, 164, 6, 162, + /* 1570 */ 162, 162, 103, 263, 105, 106, 107, 266, 266, 110, + /* 1580 */ 90, 176, 176, 190, 182, 190, 96, 97, 98, 4, + /* 1590 */ 70, 176, 3, 103, 182, 105, 106, 107, 78, 182, + /* 1600 */ 110, 81, 182, 182, 182, 182, 182, 151, 88, 22, + /* 1610 */ 141, 142, 143, 144, 145, 15, 89, 16, 23, 23, + /* 1620 */ 128, 19, 20, 139, 22, 119, 131, 24, 20, 133, + /* 1630 */ 16, 141, 142, 143, 144, 145, 1, 140, 36, 131, + /* 1640 */ 119, 61, 122, 37, 139, 53, 53, 127, 128, 119, + /* 1650 */ 53, 53, 105, 34, 130, 1, 5, 104, 22, 149, + /* 1660 */ 26, 59, 68, 75, 41, 130, 24, 68, 104, 20, + /* 1670 */ 150, 19, 120, 71, 114, 22, 67, 22, 22, 67, + /* 1680 */ 23, 22, 22, 67, 82, 37, 28, 23, 138, 87, + /* 1690 */ 22, 153, 90, 23, 23, 26, 23, 22, 96, 97, + /* 1700 */ 24, 23, 22, 24, 130, 103, 23, 105, 106, 107, + /* 1710 */ 1, 2, 110, 23, 5, 105, 34, 22, 132, 10, + /* 1720 */ 11, 12, 13, 14, 26, 34, 17, 34, 85, 83, + /* 1730 */ 44, 19, 20, 23, 22, 24, 75, 34, 23, 30, + /* 1740 */ 26, 32, 26, 141, 142, 143, 144, 145, 36, 40, + /* 1750 */ 23, 23, 23, 23, 11, 23, 22, 26, 22, 22, + /* 1760 */ 22, 19, 20, 23, 22, 26, 15, 23, 22, 124, + /* 1770 */ 130, 59, 23, 1, 130, 277, 277, 130, 36, 70, + /* 1780 */ 130, 277, 277, 71, 277, 277, 277, 78, 277, 277, + /* 1790 */ 81, 277, 277, 277, 277, 277, 277, 88, 277, 277, + /* 1800 */ 277, 59, 90, 277, 277, 277, 277, 277, 96, 97, + /* 1810 */ 277, 277, 277, 71, 277, 103, 277, 105, 106, 107, + /* 1820 */ 277, 277, 110, 277, 277, 277, 277, 277, 277, 277, + /* 1830 */ 277, 122, 90, 277, 277, 277, 127, 128, 96, 97, + /* 1840 */ 277, 277, 277, 277, 277, 103, 277, 105, 106, 107, + /* 1850 */ 277, 277, 110, 141, 142, 143, 144, 145, 277, 150, + /* 1860 */ 277, 277, 277, 5, 277, 277, 277, 277, 10, 11, + /* 1870 */ 12, 13, 14, 277, 277, 17, 277, 277, 277, 277, + /* 1880 */ 277, 277, 277, 141, 142, 143, 144, 145, 30, 277, + /* 1890 */ 32, 277, 277, 277, 277, 277, 277, 277, 40, 277, + /* 1900 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + /* 1910 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + /* 1920 */ 277, 277, 277, 277, 277, 277, 277, 277, 70, 277, + /* 1930 */ 277, 277, 277, 277, 277, 277, 78, 277, 277, 81, + /* 1940 */ 277, 277, 277, 277, 277, 277, 88, 277, 277, 277, + /* 1950 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + /* 1960 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + /* 1970 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + /* 1980 */ 122, 277, 277, 277, 277, 127, 128, 277, 277, 277, + /* 1990 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + /* 2000 */ 277, 277, 277, 277, 277, 277, 277, 277, 150, 277, + /* 2010 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, }; -#define YY_SHIFT_COUNT (489) +#define YY_SHIFT_COUNT (520) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (1637) +#define YY_SHIFT_MAX (1858) static const unsigned short int yy_shift_ofst[] = { - /* 0 */ 990, 976, 1211, 837, 837, 316, 1054, 1054, 1054, 1054, - /* 10 */ 214, 0, 0, 106, 642, 1054, 1054, 1054, 1054, 1054, - /* 20 */ 1054, 1054, 1054, 952, 952, 226, 1155, 316, 316, 316, - /* 30 */ 316, 316, 316, 53, 159, 212, 265, 318, 371, 424, - /* 40 */ 477, 533, 589, 642, 642, 642, 642, 642, 642, 642, - /* 50 */ 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - /* 60 */ 695, 642, 747, 798, 798, 1004, 1054, 1054, 1054, 1054, - /* 70 */ 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, - /* 80 */ 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, - /* 90 */ 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1112, 1054, 1054, - /* 100 */ 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, - /* 110 */ 1054, 856, 874, 874, 874, 874, 874, 134, 147, 93, - /* 120 */ 342, 959, 1161, 253, 253, 342, 367, 367, 367, 367, - /* 130 */ 179, 36, 79, 1657, 1657, 1657, 1061, 1061, 1061, 516, - /* 140 */ 799, 516, 516, 531, 531, 802, 249, 369, 342, 342, - /* 150 */ 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, - /* 160 */ 342, 342, 342, 342, 342, 342, 342, 342, 342, 272, - /* 170 */ 442, 442, 536, 1657, 1657, 1657, 1025, 245, 245, 570, - /* 180 */ 172, 286, 805, 1047, 1140, 1220, 342, 342, 342, 342, - /* 190 */ 342, 342, 342, 342, 170, 342, 342, 342, 342, 342, - /* 200 */ 342, 342, 342, 342, 342, 342, 342, 841, 841, 841, - /* 210 */ 342, 342, 342, 342, 530, 342, 342, 342, 1059, 342, - /* 220 */ 342, 1167, 342, 342, 342, 342, 342, 342, 342, 342, - /* 230 */ 123, 688, 177, 1212, 1212, 1212, 1212, 1144, 177, 177, - /* 240 */ 1064, 409, 33, 628, 707, 707, 900, 628, 628, 900, - /* 250 */ 897, 323, 398, 677, 677, 677, 707, 572, 684, 590, - /* 260 */ 739, 1236, 1182, 1182, 1276, 1276, 1182, 1253, 1325, 1315, - /* 270 */ 1239, 1346, 1346, 1346, 1346, 1182, 1369, 1239, 1239, 1253, - /* 280 */ 1325, 1315, 1315, 1239, 1182, 1369, 1298, 1376, 1182, 1369, - /* 290 */ 1424, 1182, 1369, 1182, 1369, 1424, 1358, 1358, 1358, 1405, - /* 300 */ 1424, 1358, 1364, 1358, 1405, 1358, 1358, 1424, 1379, 1379, - /* 310 */ 1424, 1351, 1388, 1351, 1388, 1351, 1388, 1351, 1388, 1182, - /* 320 */ 1472, 1182, 1360, 1372, 1377, 1374, 1378, 1239, 1480, 1482, - /* 330 */ 1497, 1497, 1508, 1508, 1508, 1657, 1657, 1657, 1657, 1657, - /* 340 */ 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, - /* 350 */ 1657, 20, 413, 98, 423, 519, 383, 962, 742, 61, - /* 360 */ 696, 749, 750, 753, 789, 790, 795, 797, 840, 842, - /* 370 */ 810, 668, 817, 659, 819, 849, 854, 899, 643, 745, - /* 380 */ 956, 926, 916, 1523, 1529, 1511, 1391, 1521, 1458, 1525, - /* 390 */ 1519, 1520, 1423, 1414, 1436, 1526, 1425, 1531, 1426, 1537, - /* 400 */ 1553, 1431, 1427, 1444, 1496, 1522, 1429, 1505, 1509, 1510, - /* 410 */ 1512, 1452, 1468, 1535, 1447, 1570, 1567, 1551, 1477, 1433, - /* 420 */ 1513, 1550, 1514, 1502, 1538, 1455, 1483, 1559, 1564, 1566, - /* 430 */ 1473, 1481, 1565, 1524, 1568, 1571, 1569, 1572, 1528, 1561, - /* 440 */ 1574, 1530, 1562, 1575, 1577, 1578, 1576, 1580, 1582, 1581, - /* 450 */ 1583, 1585, 1584, 1486, 1587, 1588, 1515, 1586, 1590, 1489, - /* 460 */ 1589, 1591, 1592, 1593, 1594, 1596, 1598, 1589, 1599, 1600, - /* 470 */ 1602, 1601, 1604, 1605, 1607, 1608, 1609, 1610, 1612, 1613, - /* 480 */ 1615, 1614, 1518, 1516, 1527, 1532, 1533, 1618, 1616, 1637, + /* 0 */ 1709, 1520, 1858, 1324, 1324, 277, 1374, 1469, 1602, 1712, + /* 10 */ 1712, 1712, 273, 0, 0, 113, 1016, 1712, 1712, 1712, + /* 20 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 11, 11, 236, + /* 30 */ 184, 277, 277, 277, 277, 277, 277, 93, 177, 270, + /* 40 */ 363, 456, 549, 642, 735, 828, 848, 996, 1144, 1016, + /* 50 */ 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, + /* 60 */ 1016, 1016, 1016, 1016, 1016, 1016, 1164, 1016, 1257, 1277, + /* 70 */ 1277, 1490, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, + /* 80 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, + /* 90 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, + /* 100 */ 1712, 1712, 1712, 1742, 1712, 1712, 1712, 1712, 1712, 1712, + /* 110 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 143, 162, 162, + /* 120 */ 162, 162, 162, 204, 151, 416, 531, 648, 700, 531, + /* 130 */ 486, 486, 531, 353, 353, 353, 353, 409, 279, 53, + /* 140 */ 2009, 2009, 331, 331, 331, 329, 366, 329, 329, 597, + /* 150 */ 597, 464, 474, 262, 681, 531, 531, 531, 531, 531, + /* 160 */ 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, + /* 170 */ 531, 531, 531, 531, 531, 531, 531, 173, 485, 984, + /* 180 */ 984, 576, 485, 19, 1022, 2009, 2009, 2009, 387, 250, + /* 190 */ 250, 525, 502, 278, 552, 227, 480, 566, 531, 531, + /* 200 */ 531, 531, 531, 531, 531, 531, 531, 531, 639, 531, + /* 210 */ 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, + /* 220 */ 531, 2, 2, 2, 531, 531, 531, 531, 782, 531, + /* 230 */ 531, 531, 744, 531, 531, 783, 531, 531, 531, 531, + /* 240 */ 531, 531, 531, 531, 419, 682, 327, 370, 370, 370, + /* 250 */ 370, 1029, 327, 327, 1024, 897, 856, 947, 1109, 706, + /* 260 */ 706, 1143, 1109, 1109, 1143, 842, 945, 1118, 1136, 1136, + /* 270 */ 1136, 706, 676, 400, 1047, 694, 1339, 1270, 1270, 1366, + /* 280 */ 1366, 1270, 1305, 1389, 1369, 1278, 1401, 1401, 1401, 1401, + /* 290 */ 1270, 1414, 1278, 1278, 1305, 1389, 1369, 1369, 1278, 1270, + /* 300 */ 1414, 1298, 1385, 1270, 1414, 1432, 1270, 1414, 1270, 1414, + /* 310 */ 1432, 1355, 1355, 1355, 1411, 1432, 1355, 1367, 1355, 1411, + /* 320 */ 1355, 1355, 1432, 1392, 1392, 1432, 1365, 1396, 1365, 1396, + /* 330 */ 1365, 1396, 1365, 1396, 1270, 1372, 1429, 1502, 1390, 1372, + /* 340 */ 1517, 1270, 1397, 1390, 1410, 1413, 1278, 1528, 1532, 1549, + /* 350 */ 1549, 1562, 1562, 1562, 2009, 2009, 2009, 2009, 2009, 2009, + /* 360 */ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, + /* 370 */ 570, 345, 686, 748, 50, 740, 1064, 1107, 469, 537, + /* 380 */ 1042, 1146, 1162, 1154, 1201, 1202, 1203, 1208, 1209, 1127, + /* 390 */ 1069, 1196, 1157, 1147, 1226, 1228, 1245, 775, 868, 1246, + /* 400 */ 1247, 1191, 1151, 1585, 1589, 1587, 1456, 1600, 1527, 1601, + /* 410 */ 1595, 1596, 1492, 1484, 1506, 1603, 1495, 1608, 1496, 1614, + /* 420 */ 1635, 1508, 1497, 1521, 1580, 1606, 1505, 1592, 1593, 1597, + /* 430 */ 1598, 1530, 1547, 1619, 1524, 1654, 1651, 1636, 1553, 1510, + /* 440 */ 1594, 1634, 1599, 1588, 1623, 1535, 1564, 1642, 1649, 1652, + /* 450 */ 1552, 1560, 1653, 1609, 1655, 1656, 1657, 1659, 1612, 1658, + /* 460 */ 1660, 1616, 1648, 1664, 1550, 1668, 1538, 1670, 1671, 1669, + /* 470 */ 1673, 1675, 1676, 1678, 1680, 1679, 1574, 1683, 1690, 1610, + /* 480 */ 1682, 1695, 1586, 1698, 1691, 1698, 1693, 1643, 1661, 1646, + /* 490 */ 1686, 1710, 1711, 1714, 1716, 1703, 1715, 1698, 1727, 1728, + /* 500 */ 1729, 1730, 1731, 1732, 1734, 1743, 1736, 1737, 1740, 1744, + /* 510 */ 1738, 1746, 1739, 1645, 1640, 1644, 1647, 1650, 1749, 1751, + /* 520 */ 1772, }; -#define YY_REDUCE_COUNT (350) -#define YY_REDUCE_MIN (-225) -#define YY_REDUCE_MAX (1375) +#define YY_REDUCE_COUNT (369) +#define YY_REDUCE_MIN (-237) +#define YY_REDUCE_MAX (1424) static const short yy_reduce_ofst[] = { - /* 0 */ -137, -31, 1104, 1023, 1081, -132, -40, -38, 223, 225, - /* 10 */ 698, -153, -99, -225, -165, 386, 478, 843, 859, -139, - /* 20 */ 884, 117, 277, 844, 857, 964, 559, 561, 614, 918, - /* 30 */ 1009, 1089, 1098, -222, -222, -222, -222, -222, -222, -222, - /* 40 */ -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, - /* 50 */ -222, -222, -222, -222, -222, -222, -222, -222, -222, -222, - /* 60 */ -222, -222, -222, -222, -222, 329, 331, 497, 654, 656, - /* 70 */ 781, 891, 946, 1029, 1129, 1134, 1149, 1154, 1160, 1162, - /* 80 */ 1164, 1168, 1174, 1177, 1188, 1191, 1193, 1202, 1204, 1206, - /* 90 */ 1208, 1216, 1218, 1221, 1231, 1233, 1235, 1241, 1244, 1246, - /* 100 */ 1248, 1250, 1258, 1260, 1275, 1277, 1283, 1286, 1288, 1290, - /* 110 */ 1292, -222, -222, -222, -222, -222, -222, -222, -222, -222, - /* 120 */ -115, 796, -156, -154, -141, 14, 242, 349, 242, 349, - /* 130 */ -61, -222, -222, -222, -222, -222, 101, 101, 101, 332, - /* 140 */ 302, 384, 387, -170, 146, 344, 196, 196, 15, 11, - /* 150 */ 183, 235, 395, 355, 396, 406, 452, 457, 391, 459, - /* 160 */ 443, 447, 511, 495, 454, 512, 505, 571, 498, 532, - /* 170 */ 431, 435, 339, 455, 446, 508, -174, -116, -97, -120, - /* 180 */ -150, 64, 176, 330, 337, 509, 569, 611, 653, 673, - /* 190 */ 714, 717, 763, 771, -34, 779, 786, 830, 846, 860, - /* 200 */ 866, 882, 883, 890, 892, 895, 902, 319, 368, 769, - /* 210 */ 915, 924, 925, 932, 755, 936, 945, 963, 782, 969, - /* 220 */ 974, 816, 977, 64, 982, 983, 1016, 1022, 1024, 1031, - /* 230 */ 870, 831, 913, 966, 973, 981, 984, 755, 913, 913, - /* 240 */ 1000, 1041, 1063, 1015, 1010, 1011, 985, 1034, 1057, 1019, - /* 250 */ 1086, 1080, 1085, 1093, 1095, 1096, 1067, 1048, 1082, 1099, - /* 260 */ 1137, 1050, 1150, 1156, 1077, 1088, 1180, 1120, 1132, 1169, - /* 270 */ 1170, 1178, 1181, 1195, 1210, 1225, 1243, 1197, 1209, 1173, - /* 280 */ 1190, 1226, 1238, 1223, 1267, 1272, 1199, 1207, 1282, 1285, - /* 290 */ 1269, 1293, 1295, 1296, 1300, 1289, 1294, 1297, 1299, 1287, - /* 300 */ 1301, 1302, 1303, 1306, 1304, 1307, 1308, 1310, 1242, 1245, - /* 310 */ 1311, 1268, 1270, 1273, 1278, 1274, 1279, 1280, 1284, 1333, - /* 320 */ 1271, 1337, 1281, 1309, 1305, 1312, 1314, 1316, 1344, 1347, - /* 330 */ 1359, 1361, 1368, 1370, 1371, 1291, 1313, 1317, 1355, 1352, - /* 340 */ 1353, 1354, 1356, 1363, 1350, 1357, 1362, 1366, 1367, 1375, - /* 350 */ 1365, + /* 0 */ -147, 171, 263, -96, 358, -144, -149, -102, 124, -156, + /* 10 */ -98, 305, 401, -57, 209, -237, 245, -94, -79, 189, + /* 20 */ 375, 490, 493, 378, 303, 539, 542, 501, 503, 554, + /* 30 */ 415, 526, 546, 557, 587, 593, 595, -234, -234, -234, + /* 40 */ -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, + /* 50 */ -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, + /* 60 */ -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, + /* 70 */ -234, -50, 335, 470, 633, 656, 658, 660, 675, 685, + /* 80 */ 703, 727, 747, 750, 752, 754, 770, 788, 790, 793, + /* 90 */ 795, 797, 800, 802, 804, 806, 813, 820, 829, 833, + /* 100 */ 836, 838, 843, 845, 847, 849, 873, 891, 893, 916, + /* 110 */ 918, 921, 936, 941, 944, 956, 961, -234, -234, -234, + /* 120 */ -234, -234, -234, -234, -234, -234, 463, 607, -176, 14, + /* 130 */ -139, 87, -137, 818, 925, 818, 925, 898, -234, -234, + /* 140 */ -234, -234, -166, -166, -166, -130, -131, -82, -54, -180, + /* 150 */ 364, 41, 513, 509, 509, 117, 500, 789, 796, 646, + /* 160 */ 192, 291, 644, 798, 120, 807, 543, 911, 920, 652, + /* 170 */ 924, 922, 232, 698, 801, 971, 39, 220, 731, 442, + /* 180 */ 902, -199, 979, -43, 421, 896, 942, 605, -184, -126, + /* 190 */ 155, 172, 281, 304, 377, 538, 650, 690, 699, 723, + /* 200 */ 803, 839, 853, 919, 991, 1018, 1067, 1092, 951, 1111, + /* 210 */ 1112, 1115, 1116, 1117, 1119, 1120, 1121, 1122, 1123, 1124, + /* 220 */ 1125, 1012, 1096, 1097, 1128, 1129, 1130, 1131, 1070, 1135, + /* 230 */ 1137, 1152, 1077, 1153, 1155, 1114, 1156, 304, 1158, 1172, + /* 240 */ 1173, 1174, 1175, 1176, 1089, 1091, 1133, 1098, 1126, 1139, + /* 250 */ 1140, 1070, 1133, 1133, 1170, 1163, 1186, 1103, 1168, 1138, + /* 260 */ 1141, 1110, 1169, 1171, 1132, 1177, 1189, 1194, 1181, 1200, + /* 270 */ 1204, 1166, 1145, 1178, 1187, 1232, 1142, 1231, 1233, 1149, + /* 280 */ 1150, 1238, 1179, 1182, 1212, 1205, 1219, 1220, 1221, 1222, + /* 290 */ 1258, 1266, 1223, 1224, 1206, 1211, 1237, 1239, 1230, 1269, + /* 300 */ 1272, 1195, 1197, 1280, 1284, 1268, 1285, 1289, 1290, 1293, + /* 310 */ 1274, 1286, 1287, 1288, 1282, 1294, 1292, 1297, 1300, 1296, + /* 320 */ 1301, 1306, 1304, 1249, 1250, 1308, 1271, 1275, 1273, 1276, + /* 330 */ 1279, 1281, 1283, 1302, 1334, 1307, 1243, 1267, 1318, 1322, + /* 340 */ 1303, 1371, 1299, 1328, 1332, 1340, 1342, 1384, 1391, 1400, + /* 350 */ 1403, 1407, 1408, 1409, 1311, 1312, 1310, 1405, 1402, 1412, + /* 360 */ 1417, 1420, 1406, 1393, 1395, 1421, 1422, 1423, 1424, 1415, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 1389, 1389, 1389, 1261, 1046, 1151, 1261, 1261, 1261, 1261, - /* 10 */ 1046, 1181, 1181, 1312, 1077, 1046, 1046, 1046, 1046, 1046, - /* 20 */ 1046, 1260, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, - /* 30 */ 1046, 1046, 1046, 1187, 1046, 1046, 1046, 1046, 1262, 1263, - /* 40 */ 1046, 1046, 1046, 1311, 1313, 1197, 1196, 1195, 1194, 1294, - /* 50 */ 1168, 1192, 1185, 1189, 1256, 1257, 1255, 1259, 1262, 1263, - /* 60 */ 1046, 1188, 1226, 1240, 1225, 1046, 1046, 1046, 1046, 1046, - /* 70 */ 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, - /* 80 */ 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, - /* 90 */ 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, - /* 100 */ 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, - /* 110 */ 1046, 1234, 1239, 1246, 1238, 1235, 1228, 1227, 1229, 1230, - /* 120 */ 1046, 1067, 1116, 1046, 1046, 1046, 1329, 1328, 1046, 1046, - /* 130 */ 1077, 1231, 1232, 1243, 1242, 1241, 1319, 1345, 1344, 1046, - /* 140 */ 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, - /* 150 */ 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, - /* 160 */ 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1077, - /* 170 */ 1073, 1073, 1046, 1324, 1151, 1142, 1046, 1046, 1046, 1046, - /* 180 */ 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1316, 1314, 1046, - /* 190 */ 1276, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, - /* 200 */ 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, - /* 210 */ 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1147, 1046, - /* 220 */ 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1339, - /* 230 */ 1046, 1289, 1130, 1147, 1147, 1147, 1147, 1149, 1131, 1129, - /* 240 */ 1141, 1077, 1053, 1191, 1170, 1170, 1378, 1191, 1191, 1378, - /* 250 */ 1091, 1359, 1088, 1181, 1181, 1181, 1170, 1258, 1148, 1141, - /* 260 */ 1046, 1381, 1156, 1156, 1380, 1380, 1156, 1200, 1206, 1119, - /* 270 */ 1191, 1125, 1125, 1125, 1125, 1156, 1064, 1191, 1191, 1200, - /* 280 */ 1206, 1119, 1119, 1191, 1156, 1064, 1293, 1375, 1156, 1064, - /* 290 */ 1269, 1156, 1064, 1156, 1064, 1269, 1117, 1117, 1117, 1106, - /* 300 */ 1269, 1117, 1091, 1117, 1106, 1117, 1117, 1269, 1273, 1273, - /* 310 */ 1269, 1174, 1169, 1174, 1169, 1174, 1169, 1174, 1169, 1156, - /* 320 */ 1264, 1156, 1046, 1186, 1175, 1184, 1182, 1191, 1070, 1109, - /* 330 */ 1342, 1342, 1338, 1338, 1338, 1386, 1386, 1324, 1354, 1077, - /* 340 */ 1077, 1077, 1077, 1354, 1093, 1093, 1077, 1077, 1077, 1077, - /* 350 */ 1354, 1046, 1046, 1046, 1046, 1046, 1046, 1349, 1046, 1278, - /* 360 */ 1160, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, - /* 370 */ 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, - /* 380 */ 1046, 1046, 1211, 1046, 1049, 1321, 1046, 1046, 1320, 1046, - /* 390 */ 1046, 1046, 1046, 1046, 1046, 1161, 1046, 1046, 1046, 1046, - /* 400 */ 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, - /* 410 */ 1046, 1046, 1046, 1046, 1377, 1046, 1046, 1046, 1046, 1046, - /* 420 */ 1046, 1292, 1291, 1046, 1046, 1158, 1046, 1046, 1046, 1046, - /* 430 */ 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, - /* 440 */ 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, - /* 450 */ 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, - /* 460 */ 1183, 1046, 1176, 1046, 1046, 1046, 1046, 1368, 1046, 1046, - /* 470 */ 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, - /* 480 */ 1046, 1363, 1133, 1213, 1046, 1212, 1216, 1046, 1058, 1046, + /* 0 */ 1492, 1492, 1492, 1340, 1123, 1229, 1123, 1123, 1123, 1340, + /* 10 */ 1340, 1340, 1123, 1259, 1259, 1391, 1154, 1123, 1123, 1123, + /* 20 */ 1123, 1123, 1123, 1123, 1339, 1123, 1123, 1123, 1123, 1123, + /* 30 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1265, 1123, + /* 40 */ 1123, 1123, 1123, 1123, 1341, 1342, 1123, 1123, 1123, 1390, + /* 50 */ 1392, 1275, 1274, 1273, 1272, 1373, 1246, 1270, 1263, 1267, + /* 60 */ 1335, 1336, 1334, 1338, 1342, 1341, 1123, 1266, 1306, 1320, + /* 70 */ 1305, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + /* 80 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + /* 90 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + /* 100 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + /* 110 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1314, 1319, 1325, + /* 120 */ 1318, 1315, 1308, 1307, 1309, 1310, 1123, 1144, 1193, 1123, + /* 130 */ 1123, 1123, 1123, 1409, 1408, 1123, 1123, 1154, 1311, 1312, + /* 140 */ 1322, 1321, 1398, 1448, 1447, 1123, 1123, 1123, 1123, 1123, + /* 150 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + /* 160 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + /* 170 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1154, 1150, 1300, + /* 180 */ 1299, 1418, 1150, 1253, 1123, 1404, 1229, 1220, 1123, 1123, + /* 190 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + /* 200 */ 1123, 1395, 1393, 1123, 1355, 1123, 1123, 1123, 1123, 1123, + /* 210 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + /* 220 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + /* 230 */ 1123, 1123, 1225, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + /* 240 */ 1123, 1123, 1123, 1442, 1123, 1368, 1207, 1225, 1225, 1225, + /* 250 */ 1225, 1227, 1208, 1206, 1219, 1154, 1130, 1484, 1269, 1248, + /* 260 */ 1248, 1481, 1269, 1269, 1481, 1168, 1462, 1165, 1259, 1259, + /* 270 */ 1259, 1248, 1337, 1226, 1219, 1123, 1484, 1234, 1234, 1483, + /* 280 */ 1483, 1234, 1278, 1284, 1196, 1269, 1202, 1202, 1202, 1202, + /* 290 */ 1234, 1141, 1269, 1269, 1278, 1284, 1196, 1196, 1269, 1234, + /* 300 */ 1141, 1372, 1478, 1234, 1141, 1348, 1234, 1141, 1234, 1141, + /* 310 */ 1348, 1194, 1194, 1194, 1183, 1348, 1194, 1168, 1194, 1183, + /* 320 */ 1194, 1194, 1348, 1352, 1352, 1348, 1252, 1247, 1252, 1247, + /* 330 */ 1252, 1247, 1252, 1247, 1234, 1253, 1417, 1123, 1264, 1253, + /* 340 */ 1343, 1234, 1123, 1264, 1262, 1260, 1269, 1147, 1186, 1445, + /* 350 */ 1445, 1441, 1441, 1441, 1489, 1489, 1404, 1457, 1154, 1154, + /* 360 */ 1154, 1154, 1457, 1170, 1170, 1154, 1154, 1154, 1154, 1457, + /* 370 */ 1123, 1123, 1123, 1123, 1123, 1123, 1452, 1123, 1357, 1238, + /* 380 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + /* 390 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + /* 400 */ 1123, 1123, 1289, 1123, 1126, 1401, 1123, 1123, 1399, 1123, + /* 410 */ 1123, 1123, 1123, 1123, 1123, 1239, 1123, 1123, 1123, 1123, + /* 420 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + /* 430 */ 1123, 1123, 1123, 1123, 1480, 1123, 1123, 1123, 1123, 1123, + /* 440 */ 1123, 1371, 1370, 1123, 1123, 1236, 1123, 1123, 1123, 1123, + /* 450 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + /* 460 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + /* 470 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + /* 480 */ 1123, 1123, 1123, 1261, 1123, 1416, 1123, 1123, 1123, 1123, + /* 490 */ 1123, 1123, 1123, 1430, 1254, 1123, 1123, 1471, 1123, 1123, + /* 500 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + /* 510 */ 1123, 1123, 1466, 1210, 1291, 1123, 1290, 1294, 1123, 1135, + /* 520 */ 1123, }; /********** End of lemon-generated parsing tables *****************************/ @@ -142312,11 +146922,18 @@ static const YYCODETYPE yyFallback[] = { 59, /* REPLACE => ID */ 59, /* RESTRICT => ID */ 59, /* ROW => ID */ + 59, /* ROWS => ID */ 59, /* TRIGGER => ID */ 59, /* VACUUM => ID */ 59, /* VIEW => ID */ 59, /* VIRTUAL => ID */ 59, /* WITH => ID */ + 59, /* CURRENT => ID */ + 59, /* FOLLOWING => ID */ + 59, /* PARTITION => ID */ + 59, /* PRECEDING => ID */ + 59, /* RANGE => ID */ + 59, /* UNBOUNDED => ID */ 59, /* REINDEX => ID */ 59, /* RENAME => ID */ 59, /* CTIME_KW => ID */ @@ -142483,185 +147100,207 @@ static const char *const yyTokenName[] = { /* 73 */ "REPLACE", /* 74 */ "RESTRICT", /* 75 */ "ROW", - /* 76 */ "TRIGGER", - /* 77 */ "VACUUM", - /* 78 */ "VIEW", - /* 79 */ "VIRTUAL", - /* 80 */ "WITH", - /* 81 */ "REINDEX", - /* 82 */ "RENAME", - /* 83 */ "CTIME_KW", - /* 84 */ "ANY", - /* 85 */ "BITAND", - /* 86 */ "BITOR", - /* 87 */ "LSHIFT", - /* 88 */ "RSHIFT", - /* 89 */ "PLUS", - /* 90 */ "MINUS", - /* 91 */ "STAR", - /* 92 */ "SLASH", - /* 93 */ "REM", - /* 94 */ "CONCAT", - /* 95 */ "COLLATE", - /* 96 */ "BITNOT", - /* 97 */ "ON", - /* 98 */ "INDEXED", - /* 99 */ "STRING", - /* 100 */ "JOIN_KW", - /* 101 */ "CONSTRAINT", - /* 102 */ "DEFAULT", - /* 103 */ "NULL", - /* 104 */ "PRIMARY", - /* 105 */ "UNIQUE", - /* 106 */ "CHECK", - /* 107 */ "REFERENCES", - /* 108 */ "AUTOINCR", - /* 109 */ "INSERT", - /* 110 */ "DELETE", - /* 111 */ "UPDATE", - /* 112 */ "SET", - /* 113 */ "DEFERRABLE", - /* 114 */ "FOREIGN", - /* 115 */ "DROP", - /* 116 */ "UNION", - /* 117 */ "ALL", - /* 118 */ "EXCEPT", - /* 119 */ "INTERSECT", - /* 120 */ "SELECT", - /* 121 */ "VALUES", - /* 122 */ "DISTINCT", - /* 123 */ "DOT", - /* 124 */ "FROM", - /* 125 */ "JOIN", - /* 126 */ "USING", - /* 127 */ "ORDER", - /* 128 */ "GROUP", - /* 129 */ "HAVING", - /* 130 */ "LIMIT", - /* 131 */ "WHERE", - /* 132 */ "INTO", - /* 133 */ "NOTHING", - /* 134 */ "FLOAT", - /* 135 */ "BLOB", - /* 136 */ "INTEGER", - /* 137 */ "VARIABLE", - /* 138 */ "CASE", - /* 139 */ "WHEN", - /* 140 */ "THEN", - /* 141 */ "ELSE", - /* 142 */ "INDEX", - /* 143 */ "ALTER", - /* 144 */ "ADD", - /* 145 */ "input", - /* 146 */ "cmdlist", - /* 147 */ "ecmd", - /* 148 */ "cmdx", - /* 149 */ "explain", - /* 150 */ "cmd", - /* 151 */ "transtype", - /* 152 */ "trans_opt", - /* 153 */ "nm", - /* 154 */ "savepoint_opt", - /* 155 */ "create_table", - /* 156 */ "create_table_args", - /* 157 */ "createkw", - /* 158 */ "temp", - /* 159 */ "ifnotexists", - /* 160 */ "dbnm", - /* 161 */ "columnlist", - /* 162 */ "conslist_opt", - /* 163 */ "table_options", - /* 164 */ "select", - /* 165 */ "columnname", - /* 166 */ "carglist", - /* 167 */ "typetoken", - /* 168 */ "typename", - /* 169 */ "signed", - /* 170 */ "plus_num", - /* 171 */ "minus_num", - /* 172 */ "scanpt", - /* 173 */ "ccons", - /* 174 */ "term", - /* 175 */ "expr", - /* 176 */ "onconf", - /* 177 */ "sortorder", - /* 178 */ "autoinc", - /* 179 */ "eidlist_opt", - /* 180 */ "refargs", - /* 181 */ "defer_subclause", - /* 182 */ "refarg", - /* 183 */ "refact", - /* 184 */ "init_deferred_pred_opt", - /* 185 */ "conslist", - /* 186 */ "tconscomma", - /* 187 */ "tcons", - /* 188 */ "sortlist", - /* 189 */ "eidlist", - /* 190 */ "defer_subclause_opt", - /* 191 */ "orconf", - /* 192 */ "resolvetype", - /* 193 */ "raisetype", - /* 194 */ "ifexists", - /* 195 */ "fullname", - /* 196 */ "selectnowith", - /* 197 */ "oneselect", - /* 198 */ "wqlist", - /* 199 */ "multiselect_op", - /* 200 */ "distinct", - /* 201 */ "selcollist", - /* 202 */ "from", - /* 203 */ "where_opt", - /* 204 */ "groupby_opt", - /* 205 */ "having_opt", - /* 206 */ "orderby_opt", - /* 207 */ "limit_opt", - /* 208 */ "values", - /* 209 */ "nexprlist", - /* 210 */ "exprlist", - /* 211 */ "sclp", - /* 212 */ "as", - /* 213 */ "seltablist", - /* 214 */ "stl_prefix", - /* 215 */ "joinop", - /* 216 */ "indexed_opt", - /* 217 */ "on_opt", - /* 218 */ "using_opt", - /* 219 */ "xfullname", - /* 220 */ "idlist", - /* 221 */ "with", - /* 222 */ "setlist", - /* 223 */ "insert_cmd", - /* 224 */ "idlist_opt", - /* 225 */ "upsert", - /* 226 */ "likeop", - /* 227 */ "between_op", - /* 228 */ "in_op", - /* 229 */ "paren_exprlist", - /* 230 */ "case_operand", - /* 231 */ "case_exprlist", - /* 232 */ "case_else", - /* 233 */ "uniqueflag", - /* 234 */ "collate", - /* 235 */ "nmnum", - /* 236 */ "trigger_decl", - /* 237 */ "trigger_cmd_list", - /* 238 */ "trigger_time", - /* 239 */ "trigger_event", - /* 240 */ "foreach_clause", - /* 241 */ "when_clause", - /* 242 */ "trigger_cmd", - /* 243 */ "trnm", - /* 244 */ "tridxby", - /* 245 */ "database_kw_opt", - /* 246 */ "key_opt", - /* 247 */ "add_column_fullname", - /* 248 */ "kwcolumn_opt", - /* 249 */ "create_vtab", - /* 250 */ "vtabarglist", - /* 251 */ "vtabarg", - /* 252 */ "vtabargtoken", - /* 253 */ "lp", - /* 254 */ "anylist", + /* 76 */ "ROWS", + /* 77 */ "TRIGGER", + /* 78 */ "VACUUM", + /* 79 */ "VIEW", + /* 80 */ "VIRTUAL", + /* 81 */ "WITH", + /* 82 */ "CURRENT", + /* 83 */ "FOLLOWING", + /* 84 */ "PARTITION", + /* 85 */ "PRECEDING", + /* 86 */ "RANGE", + /* 87 */ "UNBOUNDED", + /* 88 */ "REINDEX", + /* 89 */ "RENAME", + /* 90 */ "CTIME_KW", + /* 91 */ "ANY", + /* 92 */ "BITAND", + /* 93 */ "BITOR", + /* 94 */ "LSHIFT", + /* 95 */ "RSHIFT", + /* 96 */ "PLUS", + /* 97 */ "MINUS", + /* 98 */ "STAR", + /* 99 */ "SLASH", + /* 100 */ "REM", + /* 101 */ "CONCAT", + /* 102 */ "COLLATE", + /* 103 */ "BITNOT", + /* 104 */ "ON", + /* 105 */ "INDEXED", + /* 106 */ "STRING", + /* 107 */ "JOIN_KW", + /* 108 */ "CONSTRAINT", + /* 109 */ "DEFAULT", + /* 110 */ "NULL", + /* 111 */ "PRIMARY", + /* 112 */ "UNIQUE", + /* 113 */ "CHECK", + /* 114 */ "REFERENCES", + /* 115 */ "AUTOINCR", + /* 116 */ "INSERT", + /* 117 */ "DELETE", + /* 118 */ "UPDATE", + /* 119 */ "SET", + /* 120 */ "DEFERRABLE", + /* 121 */ "FOREIGN", + /* 122 */ "DROP", + /* 123 */ "UNION", + /* 124 */ "ALL", + /* 125 */ "EXCEPT", + /* 126 */ "INTERSECT", + /* 127 */ "SELECT", + /* 128 */ "VALUES", + /* 129 */ "DISTINCT", + /* 130 */ "DOT", + /* 131 */ "FROM", + /* 132 */ "JOIN", + /* 133 */ "USING", + /* 134 */ "ORDER", + /* 135 */ "GROUP", + /* 136 */ "HAVING", + /* 137 */ "LIMIT", + /* 138 */ "WHERE", + /* 139 */ "INTO", + /* 140 */ "NOTHING", + /* 141 */ "FLOAT", + /* 142 */ "BLOB", + /* 143 */ "INTEGER", + /* 144 */ "VARIABLE", + /* 145 */ "CASE", + /* 146 */ "WHEN", + /* 147 */ "THEN", + /* 148 */ "ELSE", + /* 149 */ "INDEX", + /* 150 */ "ALTER", + /* 151 */ "ADD", + /* 152 */ "WINDOW", + /* 153 */ "OVER", + /* 154 */ "FILTER", + /* 155 */ "input", + /* 156 */ "cmdlist", + /* 157 */ "ecmd", + /* 158 */ "cmdx", + /* 159 */ "explain", + /* 160 */ "cmd", + /* 161 */ "transtype", + /* 162 */ "trans_opt", + /* 163 */ "nm", + /* 164 */ "savepoint_opt", + /* 165 */ "create_table", + /* 166 */ "create_table_args", + /* 167 */ "createkw", + /* 168 */ "temp", + /* 169 */ "ifnotexists", + /* 170 */ "dbnm", + /* 171 */ "columnlist", + /* 172 */ "conslist_opt", + /* 173 */ "table_options", + /* 174 */ "select", + /* 175 */ "columnname", + /* 176 */ "carglist", + /* 177 */ "typetoken", + /* 178 */ "typename", + /* 179 */ "signed", + /* 180 */ "plus_num", + /* 181 */ "minus_num", + /* 182 */ "scanpt", + /* 183 */ "ccons", + /* 184 */ "term", + /* 185 */ "expr", + /* 186 */ "onconf", + /* 187 */ "sortorder", + /* 188 */ "autoinc", + /* 189 */ "eidlist_opt", + /* 190 */ "refargs", + /* 191 */ "defer_subclause", + /* 192 */ "refarg", + /* 193 */ "refact", + /* 194 */ "init_deferred_pred_opt", + /* 195 */ "conslist", + /* 196 */ "tconscomma", + /* 197 */ "tcons", + /* 198 */ "sortlist", + /* 199 */ "eidlist", + /* 200 */ "defer_subclause_opt", + /* 201 */ "orconf", + /* 202 */ "resolvetype", + /* 203 */ "raisetype", + /* 204 */ "ifexists", + /* 205 */ "fullname", + /* 206 */ "selectnowith", + /* 207 */ "oneselect", + /* 208 */ "wqlist", + /* 209 */ "multiselect_op", + /* 210 */ "distinct", + /* 211 */ "selcollist", + /* 212 */ "from", + /* 213 */ "where_opt", + /* 214 */ "groupby_opt", + /* 215 */ "having_opt", + /* 216 */ "orderby_opt", + /* 217 */ "limit_opt", + /* 218 */ "window_clause", + /* 219 */ "values", + /* 220 */ "nexprlist", + /* 221 */ "sclp", + /* 222 */ "as", + /* 223 */ "seltablist", + /* 224 */ "stl_prefix", + /* 225 */ "joinop", + /* 226 */ "indexed_opt", + /* 227 */ "on_opt", + /* 228 */ "using_opt", + /* 229 */ "exprlist", + /* 230 */ "xfullname", + /* 231 */ "idlist", + /* 232 */ "with", + /* 233 */ "setlist", + /* 234 */ "insert_cmd", + /* 235 */ "idlist_opt", + /* 236 */ "upsert", + /* 237 */ "over_clause", + /* 238 */ "likeop", + /* 239 */ "between_op", + /* 240 */ "in_op", + /* 241 */ "paren_exprlist", + /* 242 */ "case_operand", + /* 243 */ "case_exprlist", + /* 244 */ "case_else", + /* 245 */ "uniqueflag", + /* 246 */ "collate", + /* 247 */ "nmnum", + /* 248 */ "trigger_decl", + /* 249 */ "trigger_cmd_list", + /* 250 */ "trigger_time", + /* 251 */ "trigger_event", + /* 252 */ "foreach_clause", + /* 253 */ "when_clause", + /* 254 */ "trigger_cmd", + /* 255 */ "trnm", + /* 256 */ "tridxby", + /* 257 */ "database_kw_opt", + /* 258 */ "key_opt", + /* 259 */ "add_column_fullname", + /* 260 */ "kwcolumn_opt", + /* 261 */ "create_vtab", + /* 262 */ "vtabarglist", + /* 263 */ "vtabarg", + /* 264 */ "vtabargtoken", + /* 265 */ "lp", + /* 266 */ "anylist", + /* 267 */ "windowdefn_list", + /* 268 */ "windowdefn", + /* 269 */ "window", + /* 270 */ "frame_opt", + /* 271 */ "part_opt", + /* 272 */ "filter_opt", + /* 273 */ "range_or_rows", + /* 274 */ "frame_bound", + /* 275 */ "frame_bound_s", + /* 276 */ "frame_bound_e", }; #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ @@ -142757,259 +147396,285 @@ static const char *const yyRuleName[] = { /* 85 */ "multiselect_op ::= UNION ALL", /* 86 */ "multiselect_op ::= EXCEPT|INTERSECT", /* 87 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt", - /* 88 */ "values ::= VALUES LP nexprlist RP", - /* 89 */ "values ::= values COMMA LP exprlist RP", - /* 90 */ "distinct ::= DISTINCT", - /* 91 */ "distinct ::= ALL", - /* 92 */ "distinct ::=", - /* 93 */ "sclp ::=", - /* 94 */ "selcollist ::= sclp scanpt expr scanpt as", - /* 95 */ "selcollist ::= sclp scanpt STAR", - /* 96 */ "selcollist ::= sclp scanpt nm DOT STAR", - /* 97 */ "as ::= AS nm", - /* 98 */ "as ::=", - /* 99 */ "from ::=", - /* 100 */ "from ::= FROM seltablist", - /* 101 */ "stl_prefix ::= seltablist joinop", - /* 102 */ "stl_prefix ::=", - /* 103 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt", - /* 104 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt", - /* 105 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt", - /* 106 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt", - /* 107 */ "dbnm ::=", - /* 108 */ "dbnm ::= DOT nm", - /* 109 */ "fullname ::= nm", - /* 110 */ "fullname ::= nm DOT nm", - /* 111 */ "xfullname ::= nm", - /* 112 */ "xfullname ::= nm DOT nm", - /* 113 */ "xfullname ::= nm DOT nm AS nm", - /* 114 */ "xfullname ::= nm AS nm", - /* 115 */ "joinop ::= COMMA|JOIN", - /* 116 */ "joinop ::= JOIN_KW JOIN", - /* 117 */ "joinop ::= JOIN_KW nm JOIN", - /* 118 */ "joinop ::= JOIN_KW nm nm JOIN", - /* 119 */ "on_opt ::= ON expr", - /* 120 */ "on_opt ::=", - /* 121 */ "indexed_opt ::=", - /* 122 */ "indexed_opt ::= INDEXED BY nm", - /* 123 */ "indexed_opt ::= NOT INDEXED", - /* 124 */ "using_opt ::= USING LP idlist RP", - /* 125 */ "using_opt ::=", - /* 126 */ "orderby_opt ::=", - /* 127 */ "orderby_opt ::= ORDER BY sortlist", - /* 128 */ "sortlist ::= sortlist COMMA expr sortorder", - /* 129 */ "sortlist ::= expr sortorder", - /* 130 */ "sortorder ::= ASC", - /* 131 */ "sortorder ::= DESC", - /* 132 */ "sortorder ::=", - /* 133 */ "groupby_opt ::=", - /* 134 */ "groupby_opt ::= GROUP BY nexprlist", - /* 135 */ "having_opt ::=", - /* 136 */ "having_opt ::= HAVING expr", - /* 137 */ "limit_opt ::=", - /* 138 */ "limit_opt ::= LIMIT expr", - /* 139 */ "limit_opt ::= LIMIT expr OFFSET expr", - /* 140 */ "limit_opt ::= LIMIT expr COMMA expr", - /* 141 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt", - /* 142 */ "where_opt ::=", - /* 143 */ "where_opt ::= WHERE expr", - /* 144 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt", - /* 145 */ "setlist ::= setlist COMMA nm EQ expr", - /* 146 */ "setlist ::= setlist COMMA LP idlist RP EQ expr", - /* 147 */ "setlist ::= nm EQ expr", - /* 148 */ "setlist ::= LP idlist RP EQ expr", - /* 149 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert", - /* 150 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES", - /* 151 */ "upsert ::=", - /* 152 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt", - /* 153 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING", - /* 154 */ "upsert ::= ON CONFLICT DO NOTHING", - /* 155 */ "insert_cmd ::= INSERT orconf", - /* 156 */ "insert_cmd ::= REPLACE", - /* 157 */ "idlist_opt ::=", - /* 158 */ "idlist_opt ::= LP idlist RP", - /* 159 */ "idlist ::= idlist COMMA nm", - /* 160 */ "idlist ::= nm", - /* 161 */ "expr ::= LP expr RP", - /* 162 */ "expr ::= ID|INDEXED", - /* 163 */ "expr ::= JOIN_KW", - /* 164 */ "expr ::= nm DOT nm", - /* 165 */ "expr ::= nm DOT nm DOT nm", - /* 166 */ "term ::= NULL|FLOAT|BLOB", - /* 167 */ "term ::= STRING", - /* 168 */ "term ::= INTEGER", - /* 169 */ "expr ::= VARIABLE", - /* 170 */ "expr ::= expr COLLATE ID|STRING", - /* 171 */ "expr ::= CAST LP expr AS typetoken RP", - /* 172 */ "expr ::= ID|INDEXED LP distinct exprlist RP", - /* 173 */ "expr ::= ID|INDEXED LP STAR RP", - /* 174 */ "term ::= CTIME_KW", - /* 175 */ "expr ::= LP nexprlist COMMA expr RP", - /* 176 */ "expr ::= expr AND expr", - /* 177 */ "expr ::= expr OR expr", - /* 178 */ "expr ::= expr LT|GT|GE|LE expr", - /* 179 */ "expr ::= expr EQ|NE expr", - /* 180 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", - /* 181 */ "expr ::= expr PLUS|MINUS expr", - /* 182 */ "expr ::= expr STAR|SLASH|REM expr", - /* 183 */ "expr ::= expr CONCAT expr", - /* 184 */ "likeop ::= NOT LIKE_KW|MATCH", - /* 185 */ "expr ::= expr likeop expr", - /* 186 */ "expr ::= expr likeop expr ESCAPE expr", - /* 187 */ "expr ::= expr ISNULL|NOTNULL", - /* 188 */ "expr ::= expr NOT NULL", - /* 189 */ "expr ::= expr IS expr", - /* 190 */ "expr ::= expr IS NOT expr", - /* 191 */ "expr ::= NOT expr", - /* 192 */ "expr ::= BITNOT expr", - /* 193 */ "expr ::= MINUS expr", - /* 194 */ "expr ::= PLUS expr", - /* 195 */ "between_op ::= BETWEEN", - /* 196 */ "between_op ::= NOT BETWEEN", - /* 197 */ "expr ::= expr between_op expr AND expr", - /* 198 */ "in_op ::= IN", - /* 199 */ "in_op ::= NOT IN", - /* 200 */ "expr ::= expr in_op LP exprlist RP", - /* 201 */ "expr ::= LP select RP", - /* 202 */ "expr ::= expr in_op LP select RP", - /* 203 */ "expr ::= expr in_op nm dbnm paren_exprlist", - /* 204 */ "expr ::= EXISTS LP select RP", - /* 205 */ "expr ::= CASE case_operand case_exprlist case_else END", - /* 206 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", - /* 207 */ "case_exprlist ::= WHEN expr THEN expr", - /* 208 */ "case_else ::= ELSE expr", - /* 209 */ "case_else ::=", - /* 210 */ "case_operand ::= expr", - /* 211 */ "case_operand ::=", - /* 212 */ "exprlist ::=", - /* 213 */ "nexprlist ::= nexprlist COMMA expr", - /* 214 */ "nexprlist ::= expr", - /* 215 */ "paren_exprlist ::=", - /* 216 */ "paren_exprlist ::= LP exprlist RP", - /* 217 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", - /* 218 */ "uniqueflag ::= UNIQUE", - /* 219 */ "uniqueflag ::=", - /* 220 */ "eidlist_opt ::=", - /* 221 */ "eidlist_opt ::= LP eidlist RP", - /* 222 */ "eidlist ::= eidlist COMMA nm collate sortorder", - /* 223 */ "eidlist ::= nm collate sortorder", - /* 224 */ "collate ::=", - /* 225 */ "collate ::= COLLATE ID|STRING", - /* 226 */ "cmd ::= DROP INDEX ifexists fullname", - /* 227 */ "cmd ::= VACUUM", - /* 228 */ "cmd ::= VACUUM nm", - /* 229 */ "cmd ::= PRAGMA nm dbnm", - /* 230 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", - /* 231 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", - /* 232 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", - /* 233 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", - /* 234 */ "plus_num ::= PLUS INTEGER|FLOAT", - /* 235 */ "minus_num ::= MINUS INTEGER|FLOAT", - /* 236 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", - /* 237 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", - /* 238 */ "trigger_time ::= BEFORE|AFTER", - /* 239 */ "trigger_time ::= INSTEAD OF", - /* 240 */ "trigger_time ::=", - /* 241 */ "trigger_event ::= DELETE|INSERT", - /* 242 */ "trigger_event ::= UPDATE", - /* 243 */ "trigger_event ::= UPDATE OF idlist", - /* 244 */ "when_clause ::=", - /* 245 */ "when_clause ::= WHEN expr", - /* 246 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", - /* 247 */ "trigger_cmd_list ::= trigger_cmd SEMI", - /* 248 */ "trnm ::= nm DOT nm", - /* 249 */ "tridxby ::= INDEXED BY nm", - /* 250 */ "tridxby ::= NOT INDEXED", - /* 251 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt", - /* 252 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", - /* 253 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", - /* 254 */ "trigger_cmd ::= scanpt select scanpt", - /* 255 */ "expr ::= RAISE LP IGNORE RP", - /* 256 */ "expr ::= RAISE LP raisetype COMMA nm RP", - /* 257 */ "raisetype ::= ROLLBACK", - /* 258 */ "raisetype ::= ABORT", - /* 259 */ "raisetype ::= FAIL", - /* 260 */ "cmd ::= DROP TRIGGER ifexists fullname", - /* 261 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", - /* 262 */ "cmd ::= DETACH database_kw_opt expr", - /* 263 */ "key_opt ::=", - /* 264 */ "key_opt ::= KEY expr", - /* 265 */ "cmd ::= REINDEX", - /* 266 */ "cmd ::= REINDEX nm dbnm", - /* 267 */ "cmd ::= ANALYZE", - /* 268 */ "cmd ::= ANALYZE nm dbnm", - /* 269 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", - /* 270 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", - /* 271 */ "add_column_fullname ::= fullname", - /* 272 */ "cmd ::= create_vtab", - /* 273 */ "cmd ::= create_vtab LP vtabarglist RP", - /* 274 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", - /* 275 */ "vtabarg ::=", - /* 276 */ "vtabargtoken ::= ANY", - /* 277 */ "vtabargtoken ::= lp anylist RP", - /* 278 */ "lp ::= LP", - /* 279 */ "with ::= WITH wqlist", - /* 280 */ "with ::= WITH RECURSIVE wqlist", - /* 281 */ "wqlist ::= nm eidlist_opt AS LP select RP", - /* 282 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP", - /* 283 */ "input ::= cmdlist", - /* 284 */ "cmdlist ::= cmdlist ecmd", - /* 285 */ "cmdlist ::= ecmd", - /* 286 */ "ecmd ::= SEMI", - /* 287 */ "ecmd ::= cmdx SEMI", - /* 288 */ "ecmd ::= explain cmdx", - /* 289 */ "trans_opt ::=", - /* 290 */ "trans_opt ::= TRANSACTION", - /* 291 */ "trans_opt ::= TRANSACTION nm", - /* 292 */ "savepoint_opt ::= SAVEPOINT", - /* 293 */ "savepoint_opt ::=", - /* 294 */ "cmd ::= create_table create_table_args", - /* 295 */ "columnlist ::= columnlist COMMA columnname carglist", - /* 296 */ "columnlist ::= columnname carglist", - /* 297 */ "nm ::= ID|INDEXED", - /* 298 */ "nm ::= STRING", - /* 299 */ "nm ::= JOIN_KW", - /* 300 */ "typetoken ::= typename", - /* 301 */ "typename ::= ID|STRING", - /* 302 */ "signed ::= plus_num", - /* 303 */ "signed ::= minus_num", - /* 304 */ "carglist ::= carglist ccons", - /* 305 */ "carglist ::=", - /* 306 */ "ccons ::= NULL onconf", - /* 307 */ "conslist_opt ::= COMMA conslist", - /* 308 */ "conslist ::= conslist tconscomma tcons", - /* 309 */ "conslist ::= tcons", - /* 310 */ "tconscomma ::=", - /* 311 */ "defer_subclause_opt ::= defer_subclause", - /* 312 */ "resolvetype ::= raisetype", - /* 313 */ "selectnowith ::= oneselect", - /* 314 */ "oneselect ::= values", - /* 315 */ "sclp ::= selcollist COMMA", - /* 316 */ "as ::= ID|STRING", - /* 317 */ "expr ::= term", - /* 318 */ "likeop ::= LIKE_KW|MATCH", - /* 319 */ "exprlist ::= nexprlist", - /* 320 */ "nmnum ::= plus_num", - /* 321 */ "nmnum ::= nm", - /* 322 */ "nmnum ::= ON", - /* 323 */ "nmnum ::= DELETE", - /* 324 */ "nmnum ::= DEFAULT", - /* 325 */ "plus_num ::= INTEGER|FLOAT", - /* 326 */ "foreach_clause ::=", - /* 327 */ "foreach_clause ::= FOR EACH ROW", - /* 328 */ "trnm ::= nm", - /* 329 */ "tridxby ::=", - /* 330 */ "database_kw_opt ::= DATABASE", - /* 331 */ "database_kw_opt ::=", - /* 332 */ "kwcolumn_opt ::=", - /* 333 */ "kwcolumn_opt ::= COLUMNKW", - /* 334 */ "vtabarglist ::= vtabarg", - /* 335 */ "vtabarglist ::= vtabarglist COMMA vtabarg", - /* 336 */ "vtabarg ::= vtabarg vtabargtoken", - /* 337 */ "anylist ::=", - /* 338 */ "anylist ::= anylist LP anylist RP", - /* 339 */ "anylist ::= anylist ANY", - /* 340 */ "with ::=", + /* 88 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt", + /* 89 */ "values ::= VALUES LP nexprlist RP", + /* 90 */ "values ::= values COMMA LP nexprlist RP", + /* 91 */ "distinct ::= DISTINCT", + /* 92 */ "distinct ::= ALL", + /* 93 */ "distinct ::=", + /* 94 */ "sclp ::=", + /* 95 */ "selcollist ::= sclp scanpt expr scanpt as", + /* 96 */ "selcollist ::= sclp scanpt STAR", + /* 97 */ "selcollist ::= sclp scanpt nm DOT STAR", + /* 98 */ "as ::= AS nm", + /* 99 */ "as ::=", + /* 100 */ "from ::=", + /* 101 */ "from ::= FROM seltablist", + /* 102 */ "stl_prefix ::= seltablist joinop", + /* 103 */ "stl_prefix ::=", + /* 104 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt", + /* 105 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt", + /* 106 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt", + /* 107 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt", + /* 108 */ "dbnm ::=", + /* 109 */ "dbnm ::= DOT nm", + /* 110 */ "fullname ::= nm", + /* 111 */ "fullname ::= nm DOT nm", + /* 112 */ "xfullname ::= nm", + /* 113 */ "xfullname ::= nm DOT nm", + /* 114 */ "xfullname ::= nm DOT nm AS nm", + /* 115 */ "xfullname ::= nm AS nm", + /* 116 */ "joinop ::= COMMA|JOIN", + /* 117 */ "joinop ::= JOIN_KW JOIN", + /* 118 */ "joinop ::= JOIN_KW nm JOIN", + /* 119 */ "joinop ::= JOIN_KW nm nm JOIN", + /* 120 */ "on_opt ::= ON expr", + /* 121 */ "on_opt ::=", + /* 122 */ "indexed_opt ::=", + /* 123 */ "indexed_opt ::= INDEXED BY nm", + /* 124 */ "indexed_opt ::= NOT INDEXED", + /* 125 */ "using_opt ::= USING LP idlist RP", + /* 126 */ "using_opt ::=", + /* 127 */ "orderby_opt ::=", + /* 128 */ "orderby_opt ::= ORDER BY sortlist", + /* 129 */ "sortlist ::= sortlist COMMA expr sortorder", + /* 130 */ "sortlist ::= expr sortorder", + /* 131 */ "sortorder ::= ASC", + /* 132 */ "sortorder ::= DESC", + /* 133 */ "sortorder ::=", + /* 134 */ "groupby_opt ::=", + /* 135 */ "groupby_opt ::= GROUP BY nexprlist", + /* 136 */ "having_opt ::=", + /* 137 */ "having_opt ::= HAVING expr", + /* 138 */ "limit_opt ::=", + /* 139 */ "limit_opt ::= LIMIT expr", + /* 140 */ "limit_opt ::= LIMIT expr OFFSET expr", + /* 141 */ "limit_opt ::= LIMIT expr COMMA expr", + /* 142 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt", + /* 143 */ "where_opt ::=", + /* 144 */ "where_opt ::= WHERE expr", + /* 145 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt", + /* 146 */ "setlist ::= setlist COMMA nm EQ expr", + /* 147 */ "setlist ::= setlist COMMA LP idlist RP EQ expr", + /* 148 */ "setlist ::= nm EQ expr", + /* 149 */ "setlist ::= LP idlist RP EQ expr", + /* 150 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert", + /* 151 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES", + /* 152 */ "upsert ::=", + /* 153 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt", + /* 154 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING", + /* 155 */ "upsert ::= ON CONFLICT DO NOTHING", + /* 156 */ "insert_cmd ::= INSERT orconf", + /* 157 */ "insert_cmd ::= REPLACE", + /* 158 */ "idlist_opt ::=", + /* 159 */ "idlist_opt ::= LP idlist RP", + /* 160 */ "idlist ::= idlist COMMA nm", + /* 161 */ "idlist ::= nm", + /* 162 */ "expr ::= LP expr RP", + /* 163 */ "expr ::= ID|INDEXED", + /* 164 */ "expr ::= JOIN_KW", + /* 165 */ "expr ::= nm DOT nm", + /* 166 */ "expr ::= nm DOT nm DOT nm", + /* 167 */ "term ::= NULL|FLOAT|BLOB", + /* 168 */ "term ::= STRING", + /* 169 */ "term ::= INTEGER", + /* 170 */ "expr ::= VARIABLE", + /* 171 */ "expr ::= expr COLLATE ID|STRING", + /* 172 */ "expr ::= CAST LP expr AS typetoken RP", + /* 173 */ "expr ::= ID|INDEXED LP distinct exprlist RP", + /* 174 */ "expr ::= ID|INDEXED LP STAR RP", + /* 175 */ "expr ::= ID|INDEXED LP distinct exprlist RP over_clause", + /* 176 */ "expr ::= ID|INDEXED LP STAR RP over_clause", + /* 177 */ "term ::= CTIME_KW", + /* 178 */ "expr ::= LP nexprlist COMMA expr RP", + /* 179 */ "expr ::= expr AND expr", + /* 180 */ "expr ::= expr OR expr", + /* 181 */ "expr ::= expr LT|GT|GE|LE expr", + /* 182 */ "expr ::= expr EQ|NE expr", + /* 183 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", + /* 184 */ "expr ::= expr PLUS|MINUS expr", + /* 185 */ "expr ::= expr STAR|SLASH|REM expr", + /* 186 */ "expr ::= expr CONCAT expr", + /* 187 */ "likeop ::= NOT LIKE_KW|MATCH", + /* 188 */ "expr ::= expr likeop expr", + /* 189 */ "expr ::= expr likeop expr ESCAPE expr", + /* 190 */ "expr ::= expr ISNULL|NOTNULL", + /* 191 */ "expr ::= expr NOT NULL", + /* 192 */ "expr ::= expr IS expr", + /* 193 */ "expr ::= expr IS NOT expr", + /* 194 */ "expr ::= NOT expr", + /* 195 */ "expr ::= BITNOT expr", + /* 196 */ "expr ::= PLUS|MINUS expr", + /* 197 */ "between_op ::= BETWEEN", + /* 198 */ "between_op ::= NOT BETWEEN", + /* 199 */ "expr ::= expr between_op expr AND expr", + /* 200 */ "in_op ::= IN", + /* 201 */ "in_op ::= NOT IN", + /* 202 */ "expr ::= expr in_op LP exprlist RP", + /* 203 */ "expr ::= LP select RP", + /* 204 */ "expr ::= expr in_op LP select RP", + /* 205 */ "expr ::= expr in_op nm dbnm paren_exprlist", + /* 206 */ "expr ::= EXISTS LP select RP", + /* 207 */ "expr ::= CASE case_operand case_exprlist case_else END", + /* 208 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", + /* 209 */ "case_exprlist ::= WHEN expr THEN expr", + /* 210 */ "case_else ::= ELSE expr", + /* 211 */ "case_else ::=", + /* 212 */ "case_operand ::= expr", + /* 213 */ "case_operand ::=", + /* 214 */ "exprlist ::=", + /* 215 */ "nexprlist ::= nexprlist COMMA expr", + /* 216 */ "nexprlist ::= expr", + /* 217 */ "paren_exprlist ::=", + /* 218 */ "paren_exprlist ::= LP exprlist RP", + /* 219 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", + /* 220 */ "uniqueflag ::= UNIQUE", + /* 221 */ "uniqueflag ::=", + /* 222 */ "eidlist_opt ::=", + /* 223 */ "eidlist_opt ::= LP eidlist RP", + /* 224 */ "eidlist ::= eidlist COMMA nm collate sortorder", + /* 225 */ "eidlist ::= nm collate sortorder", + /* 226 */ "collate ::=", + /* 227 */ "collate ::= COLLATE ID|STRING", + /* 228 */ "cmd ::= DROP INDEX ifexists fullname", + /* 229 */ "cmd ::= VACUUM", + /* 230 */ "cmd ::= VACUUM nm", + /* 231 */ "cmd ::= PRAGMA nm dbnm", + /* 232 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", + /* 233 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", + /* 234 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", + /* 235 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", + /* 236 */ "plus_num ::= PLUS INTEGER|FLOAT", + /* 237 */ "minus_num ::= MINUS INTEGER|FLOAT", + /* 238 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", + /* 239 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", + /* 240 */ "trigger_time ::= BEFORE|AFTER", + /* 241 */ "trigger_time ::= INSTEAD OF", + /* 242 */ "trigger_time ::=", + /* 243 */ "trigger_event ::= DELETE|INSERT", + /* 244 */ "trigger_event ::= UPDATE", + /* 245 */ "trigger_event ::= UPDATE OF idlist", + /* 246 */ "when_clause ::=", + /* 247 */ "when_clause ::= WHEN expr", + /* 248 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", + /* 249 */ "trigger_cmd_list ::= trigger_cmd SEMI", + /* 250 */ "trnm ::= nm DOT nm", + /* 251 */ "tridxby ::= INDEXED BY nm", + /* 252 */ "tridxby ::= NOT INDEXED", + /* 253 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt", + /* 254 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", + /* 255 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", + /* 256 */ "trigger_cmd ::= scanpt select scanpt", + /* 257 */ "expr ::= RAISE LP IGNORE RP", + /* 258 */ "expr ::= RAISE LP raisetype COMMA nm RP", + /* 259 */ "raisetype ::= ROLLBACK", + /* 260 */ "raisetype ::= ABORT", + /* 261 */ "raisetype ::= FAIL", + /* 262 */ "cmd ::= DROP TRIGGER ifexists fullname", + /* 263 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", + /* 264 */ "cmd ::= DETACH database_kw_opt expr", + /* 265 */ "key_opt ::=", + /* 266 */ "key_opt ::= KEY expr", + /* 267 */ "cmd ::= REINDEX", + /* 268 */ "cmd ::= REINDEX nm dbnm", + /* 269 */ "cmd ::= ANALYZE", + /* 270 */ "cmd ::= ANALYZE nm dbnm", + /* 271 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", + /* 272 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", + /* 273 */ "add_column_fullname ::= fullname", + /* 274 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", + /* 275 */ "cmd ::= create_vtab", + /* 276 */ "cmd ::= create_vtab LP vtabarglist RP", + /* 277 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", + /* 278 */ "vtabarg ::=", + /* 279 */ "vtabargtoken ::= ANY", + /* 280 */ "vtabargtoken ::= lp anylist RP", + /* 281 */ "lp ::= LP", + /* 282 */ "with ::= WITH wqlist", + /* 283 */ "with ::= WITH RECURSIVE wqlist", + /* 284 */ "wqlist ::= nm eidlist_opt AS LP select RP", + /* 285 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP", + /* 286 */ "windowdefn_list ::= windowdefn", + /* 287 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", + /* 288 */ "windowdefn ::= nm AS window", + /* 289 */ "window ::= LP part_opt orderby_opt frame_opt RP", + /* 290 */ "part_opt ::= PARTITION BY nexprlist", + /* 291 */ "part_opt ::=", + /* 292 */ "frame_opt ::=", + /* 293 */ "frame_opt ::= range_or_rows frame_bound_s", + /* 294 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e", + /* 295 */ "range_or_rows ::= RANGE", + /* 296 */ "range_or_rows ::= ROWS", + /* 297 */ "frame_bound_s ::= frame_bound", + /* 298 */ "frame_bound_s ::= UNBOUNDED PRECEDING", + /* 299 */ "frame_bound_e ::= frame_bound", + /* 300 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", + /* 301 */ "frame_bound ::= expr PRECEDING", + /* 302 */ "frame_bound ::= CURRENT ROW", + /* 303 */ "frame_bound ::= expr FOLLOWING", + /* 304 */ "window_clause ::= WINDOW windowdefn_list", + /* 305 */ "over_clause ::= filter_opt OVER window", + /* 306 */ "over_clause ::= filter_opt OVER nm", + /* 307 */ "filter_opt ::=", + /* 308 */ "filter_opt ::= FILTER LP WHERE expr RP", + /* 309 */ "input ::= cmdlist", + /* 310 */ "cmdlist ::= cmdlist ecmd", + /* 311 */ "cmdlist ::= ecmd", + /* 312 */ "ecmd ::= SEMI", + /* 313 */ "ecmd ::= cmdx SEMI", + /* 314 */ "ecmd ::= explain cmdx", + /* 315 */ "trans_opt ::=", + /* 316 */ "trans_opt ::= TRANSACTION", + /* 317 */ "trans_opt ::= TRANSACTION nm", + /* 318 */ "savepoint_opt ::= SAVEPOINT", + /* 319 */ "savepoint_opt ::=", + /* 320 */ "cmd ::= create_table create_table_args", + /* 321 */ "columnlist ::= columnlist COMMA columnname carglist", + /* 322 */ "columnlist ::= columnname carglist", + /* 323 */ "nm ::= ID|INDEXED", + /* 324 */ "nm ::= STRING", + /* 325 */ "nm ::= JOIN_KW", + /* 326 */ "typetoken ::= typename", + /* 327 */ "typename ::= ID|STRING", + /* 328 */ "signed ::= plus_num", + /* 329 */ "signed ::= minus_num", + /* 330 */ "carglist ::= carglist ccons", + /* 331 */ "carglist ::=", + /* 332 */ "ccons ::= NULL onconf", + /* 333 */ "conslist_opt ::= COMMA conslist", + /* 334 */ "conslist ::= conslist tconscomma tcons", + /* 335 */ "conslist ::= tcons", + /* 336 */ "tconscomma ::=", + /* 337 */ "defer_subclause_opt ::= defer_subclause", + /* 338 */ "resolvetype ::= raisetype", + /* 339 */ "selectnowith ::= oneselect", + /* 340 */ "oneselect ::= values", + /* 341 */ "sclp ::= selcollist COMMA", + /* 342 */ "as ::= ID|STRING", + /* 343 */ "expr ::= term", + /* 344 */ "likeop ::= LIKE_KW|MATCH", + /* 345 */ "exprlist ::= nexprlist", + /* 346 */ "nmnum ::= plus_num", + /* 347 */ "nmnum ::= nm", + /* 348 */ "nmnum ::= ON", + /* 349 */ "nmnum ::= DELETE", + /* 350 */ "nmnum ::= DEFAULT", + /* 351 */ "plus_num ::= INTEGER|FLOAT", + /* 352 */ "foreach_clause ::=", + /* 353 */ "foreach_clause ::= FOR EACH ROW", + /* 354 */ "trnm ::= nm", + /* 355 */ "tridxby ::=", + /* 356 */ "database_kw_opt ::= DATABASE", + /* 357 */ "database_kw_opt ::=", + /* 358 */ "kwcolumn_opt ::=", + /* 359 */ "kwcolumn_opt ::= COLUMNKW", + /* 360 */ "vtabarglist ::= vtabarg", + /* 361 */ "vtabarglist ::= vtabarglist COMMA vtabarg", + /* 362 */ "vtabarg ::= vtabarg vtabargtoken", + /* 363 */ "anylist ::=", + /* 364 */ "anylist ::= anylist LP anylist RP", + /* 365 */ "anylist ::= anylist ANY", + /* 366 */ "with ::=", }; #endif /* NDEBUG */ @@ -143135,73 +147800,96 @@ static void yy_destructor( ** inside the C code. */ /********* Begin destructor definitions ***************************************/ - case 164: /* select */ - case 196: /* selectnowith */ - case 197: /* oneselect */ - case 208: /* values */ + case 174: /* select */ + case 206: /* selectnowith */ + case 207: /* oneselect */ + case 219: /* values */ { -sqlite3SelectDelete(pParse->db, (yypminor->yy399)); +sqlite3SelectDelete(pParse->db, (yypminor->yy489)); } break; - case 174: /* term */ - case 175: /* expr */ - case 203: /* where_opt */ - case 205: /* having_opt */ - case 217: /* on_opt */ - case 230: /* case_operand */ - case 232: /* case_else */ - case 241: /* when_clause */ - case 246: /* key_opt */ + case 184: /* term */ + case 185: /* expr */ + case 213: /* where_opt */ + case 215: /* having_opt */ + case 227: /* on_opt */ + case 242: /* case_operand */ + case 244: /* case_else */ + case 253: /* when_clause */ + case 258: /* key_opt */ + case 272: /* filter_opt */ { -sqlite3ExprDelete(pParse->db, (yypminor->yy182)); +sqlite3ExprDelete(pParse->db, (yypminor->yy18)); } break; - case 179: /* eidlist_opt */ - case 188: /* sortlist */ - case 189: /* eidlist */ - case 201: /* selcollist */ - case 204: /* groupby_opt */ - case 206: /* orderby_opt */ - case 209: /* nexprlist */ - case 210: /* exprlist */ - case 211: /* sclp */ - case 222: /* setlist */ - case 229: /* paren_exprlist */ - case 231: /* case_exprlist */ + case 189: /* eidlist_opt */ + case 198: /* sortlist */ + case 199: /* eidlist */ + case 211: /* selcollist */ + case 214: /* groupby_opt */ + case 216: /* orderby_opt */ + case 220: /* nexprlist */ + case 221: /* sclp */ + case 229: /* exprlist */ + case 233: /* setlist */ + case 241: /* paren_exprlist */ + case 243: /* case_exprlist */ + case 271: /* part_opt */ { -sqlite3ExprListDelete(pParse->db, (yypminor->yy232)); +sqlite3ExprListDelete(pParse->db, (yypminor->yy420)); } break; - case 195: /* fullname */ - case 202: /* from */ - case 213: /* seltablist */ - case 214: /* stl_prefix */ - case 219: /* xfullname */ + case 205: /* fullname */ + case 212: /* from */ + case 223: /* seltablist */ + case 224: /* stl_prefix */ + case 230: /* xfullname */ { -sqlite3SrcListDelete(pParse->db, (yypminor->yy427)); +sqlite3SrcListDelete(pParse->db, (yypminor->yy135)); } break; - case 198: /* wqlist */ + case 208: /* wqlist */ { -sqlite3WithDelete(pParse->db, (yypminor->yy91)); +sqlite3WithDelete(pParse->db, (yypminor->yy449)); } break; - case 218: /* using_opt */ - case 220: /* idlist */ - case 224: /* idlist_opt */ + case 218: /* window_clause */ + case 267: /* windowdefn_list */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy510)); +sqlite3WindowListDelete(pParse->db, (yypminor->yy327)); } break; - case 237: /* trigger_cmd_list */ - case 242: /* trigger_cmd */ + case 228: /* using_opt */ + case 231: /* idlist */ + case 235: /* idlist_opt */ { -sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy47)); +sqlite3IdListDelete(pParse->db, (yypminor->yy48)); } break; - case 239: /* trigger_event */ + case 237: /* over_clause */ + case 268: /* windowdefn */ + case 269: /* window */ + case 270: /* frame_opt */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy300).b); +sqlite3WindowDelete(pParse->db, (yypminor->yy327)); +} + break; + case 249: /* trigger_cmd_list */ + case 254: /* trigger_cmd */ +{ +sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy207)); +} + break; + case 251: /* trigger_event */ +{ +sqlite3IdListDelete(pParse->db, (yypminor->yy34).b); +} + break; + case 274: /* frame_bound */ + case 275: /* frame_bound_s */ + case 276: /* frame_bound_e */ +{ +sqlite3ExprDelete(pParse->db, (yypminor->yy119).pExpr); } break; /********* End destructor definitions *****************************************/ @@ -143327,11 +148015,11 @@ static YYACTIONTYPE yy_find_shift_action( do{ i = yy_shift_ofst[stateno]; assert( i>=0 ); - assert( i+YYNTOKEN<=(int)sizeof(yy_lookahead)/sizeof(yy_lookahead[0]) ); + /* assert( i+YYNTOKEN<=(int)YY_NLOOKAHEAD ); */ assert( iLookAhead!=YYNOCODE ); assert( iLookAhead < YYNTOKEN ); i += iLookAhead; - if( yy_lookahead[i]!=iLookAhead ){ + if( i>=YY_NLOOKAHEAD || yy_lookahead[i]!=iLookAhead ){ #ifdef YYFALLBACK YYCODETYPE iFallback; /* Fallback token */ if( iLookAhead=YY_ACTTAB_COUNT j0 ){ #ifndef NDEBUG @@ -143381,7 +148070,7 @@ static YYACTIONTYPE yy_find_shift_action( ** Find the appropriate action for a parser given the non-terminal ** look-ahead token iLookAhead. */ -static int yy_find_reduce_action( +static YYACTIONTYPE yy_find_reduce_action( YYACTIONTYPE stateno, /* Current state number */ YYCODETYPE iLookAhead /* The look-ahead token */ ){ @@ -143499,347 +148188,373 @@ static const struct { YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ signed char nrhs; /* Negative of the number of RHS symbols in the rule */ } yyRuleInfo[] = { - { 149, -1 }, /* (0) explain ::= EXPLAIN */ - { 149, -3 }, /* (1) explain ::= EXPLAIN QUERY PLAN */ - { 148, -1 }, /* (2) cmdx ::= cmd */ - { 150, -3 }, /* (3) cmd ::= BEGIN transtype trans_opt */ - { 151, 0 }, /* (4) transtype ::= */ - { 151, -1 }, /* (5) transtype ::= DEFERRED */ - { 151, -1 }, /* (6) transtype ::= IMMEDIATE */ - { 151, -1 }, /* (7) transtype ::= EXCLUSIVE */ - { 150, -2 }, /* (8) cmd ::= COMMIT|END trans_opt */ - { 150, -2 }, /* (9) cmd ::= ROLLBACK trans_opt */ - { 150, -2 }, /* (10) cmd ::= SAVEPOINT nm */ - { 150, -3 }, /* (11) cmd ::= RELEASE savepoint_opt nm */ - { 150, -5 }, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ - { 155, -6 }, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */ - { 157, -1 }, /* (14) createkw ::= CREATE */ - { 159, 0 }, /* (15) ifnotexists ::= */ - { 159, -3 }, /* (16) ifnotexists ::= IF NOT EXISTS */ - { 158, -1 }, /* (17) temp ::= TEMP */ - { 158, 0 }, /* (18) temp ::= */ - { 156, -5 }, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_options */ - { 156, -2 }, /* (20) create_table_args ::= AS select */ - { 163, 0 }, /* (21) table_options ::= */ - { 163, -2 }, /* (22) table_options ::= WITHOUT nm */ - { 165, -2 }, /* (23) columnname ::= nm typetoken */ - { 167, 0 }, /* (24) typetoken ::= */ - { 167, -4 }, /* (25) typetoken ::= typename LP signed RP */ - { 167, -6 }, /* (26) typetoken ::= typename LP signed COMMA signed RP */ - { 168, -2 }, /* (27) typename ::= typename ID|STRING */ - { 172, 0 }, /* (28) scanpt ::= */ - { 173, -2 }, /* (29) ccons ::= CONSTRAINT nm */ - { 173, -4 }, /* (30) ccons ::= DEFAULT scanpt term scanpt */ - { 173, -4 }, /* (31) ccons ::= DEFAULT LP expr RP */ - { 173, -4 }, /* (32) ccons ::= DEFAULT PLUS term scanpt */ - { 173, -4 }, /* (33) ccons ::= DEFAULT MINUS term scanpt */ - { 173, -3 }, /* (34) ccons ::= DEFAULT scanpt ID|INDEXED */ - { 173, -3 }, /* (35) ccons ::= NOT NULL onconf */ - { 173, -5 }, /* (36) ccons ::= PRIMARY KEY sortorder onconf autoinc */ - { 173, -2 }, /* (37) ccons ::= UNIQUE onconf */ - { 173, -4 }, /* (38) ccons ::= CHECK LP expr RP */ - { 173, -4 }, /* (39) ccons ::= REFERENCES nm eidlist_opt refargs */ - { 173, -1 }, /* (40) ccons ::= defer_subclause */ - { 173, -2 }, /* (41) ccons ::= COLLATE ID|STRING */ - { 178, 0 }, /* (42) autoinc ::= */ - { 178, -1 }, /* (43) autoinc ::= AUTOINCR */ - { 180, 0 }, /* (44) refargs ::= */ - { 180, -2 }, /* (45) refargs ::= refargs refarg */ - { 182, -2 }, /* (46) refarg ::= MATCH nm */ - { 182, -3 }, /* (47) refarg ::= ON INSERT refact */ - { 182, -3 }, /* (48) refarg ::= ON DELETE refact */ - { 182, -3 }, /* (49) refarg ::= ON UPDATE refact */ - { 183, -2 }, /* (50) refact ::= SET NULL */ - { 183, -2 }, /* (51) refact ::= SET DEFAULT */ - { 183, -1 }, /* (52) refact ::= CASCADE */ - { 183, -1 }, /* (53) refact ::= RESTRICT */ - { 183, -2 }, /* (54) refact ::= NO ACTION */ - { 181, -3 }, /* (55) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ - { 181, -2 }, /* (56) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ - { 184, 0 }, /* (57) init_deferred_pred_opt ::= */ - { 184, -2 }, /* (58) init_deferred_pred_opt ::= INITIALLY DEFERRED */ - { 184, -2 }, /* (59) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ - { 162, 0 }, /* (60) conslist_opt ::= */ - { 186, -1 }, /* (61) tconscomma ::= COMMA */ - { 187, -2 }, /* (62) tcons ::= CONSTRAINT nm */ - { 187, -7 }, /* (63) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ - { 187, -5 }, /* (64) tcons ::= UNIQUE LP sortlist RP onconf */ - { 187, -5 }, /* (65) tcons ::= CHECK LP expr RP onconf */ - { 187, -10 }, /* (66) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ - { 190, 0 }, /* (67) defer_subclause_opt ::= */ - { 176, 0 }, /* (68) onconf ::= */ - { 176, -3 }, /* (69) onconf ::= ON CONFLICT resolvetype */ - { 191, 0 }, /* (70) orconf ::= */ - { 191, -2 }, /* (71) orconf ::= OR resolvetype */ - { 192, -1 }, /* (72) resolvetype ::= IGNORE */ - { 192, -1 }, /* (73) resolvetype ::= REPLACE */ - { 150, -4 }, /* (74) cmd ::= DROP TABLE ifexists fullname */ - { 194, -2 }, /* (75) ifexists ::= IF EXISTS */ - { 194, 0 }, /* (76) ifexists ::= */ - { 150, -9 }, /* (77) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ - { 150, -4 }, /* (78) cmd ::= DROP VIEW ifexists fullname */ - { 150, -1 }, /* (79) cmd ::= select */ - { 164, -3 }, /* (80) select ::= WITH wqlist selectnowith */ - { 164, -4 }, /* (81) select ::= WITH RECURSIVE wqlist selectnowith */ - { 164, -1 }, /* (82) select ::= selectnowith */ - { 196, -3 }, /* (83) selectnowith ::= selectnowith multiselect_op oneselect */ - { 199, -1 }, /* (84) multiselect_op ::= UNION */ - { 199, -2 }, /* (85) multiselect_op ::= UNION ALL */ - { 199, -1 }, /* (86) multiselect_op ::= EXCEPT|INTERSECT */ - { 197, -9 }, /* (87) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ - { 208, -4 }, /* (88) values ::= VALUES LP nexprlist RP */ - { 208, -5 }, /* (89) values ::= values COMMA LP exprlist RP */ - { 200, -1 }, /* (90) distinct ::= DISTINCT */ - { 200, -1 }, /* (91) distinct ::= ALL */ - { 200, 0 }, /* (92) distinct ::= */ - { 211, 0 }, /* (93) sclp ::= */ - { 201, -5 }, /* (94) selcollist ::= sclp scanpt expr scanpt as */ - { 201, -3 }, /* (95) selcollist ::= sclp scanpt STAR */ - { 201, -5 }, /* (96) selcollist ::= sclp scanpt nm DOT STAR */ - { 212, -2 }, /* (97) as ::= AS nm */ - { 212, 0 }, /* (98) as ::= */ - { 202, 0 }, /* (99) from ::= */ - { 202, -2 }, /* (100) from ::= FROM seltablist */ - { 214, -2 }, /* (101) stl_prefix ::= seltablist joinop */ - { 214, 0 }, /* (102) stl_prefix ::= */ - { 213, -7 }, /* (103) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ - { 213, -9 }, /* (104) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ - { 213, -7 }, /* (105) seltablist ::= stl_prefix LP select RP as on_opt using_opt */ - { 213, -7 }, /* (106) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ - { 160, 0 }, /* (107) dbnm ::= */ - { 160, -2 }, /* (108) dbnm ::= DOT nm */ - { 195, -1 }, /* (109) fullname ::= nm */ - { 195, -3 }, /* (110) fullname ::= nm DOT nm */ - { 219, -1 }, /* (111) xfullname ::= nm */ - { 219, -3 }, /* (112) xfullname ::= nm DOT nm */ - { 219, -5 }, /* (113) xfullname ::= nm DOT nm AS nm */ - { 219, -3 }, /* (114) xfullname ::= nm AS nm */ - { 215, -1 }, /* (115) joinop ::= COMMA|JOIN */ - { 215, -2 }, /* (116) joinop ::= JOIN_KW JOIN */ - { 215, -3 }, /* (117) joinop ::= JOIN_KW nm JOIN */ - { 215, -4 }, /* (118) joinop ::= JOIN_KW nm nm JOIN */ - { 217, -2 }, /* (119) on_opt ::= ON expr */ - { 217, 0 }, /* (120) on_opt ::= */ - { 216, 0 }, /* (121) indexed_opt ::= */ - { 216, -3 }, /* (122) indexed_opt ::= INDEXED BY nm */ - { 216, -2 }, /* (123) indexed_opt ::= NOT INDEXED */ - { 218, -4 }, /* (124) using_opt ::= USING LP idlist RP */ - { 218, 0 }, /* (125) using_opt ::= */ - { 206, 0 }, /* (126) orderby_opt ::= */ - { 206, -3 }, /* (127) orderby_opt ::= ORDER BY sortlist */ - { 188, -4 }, /* (128) sortlist ::= sortlist COMMA expr sortorder */ - { 188, -2 }, /* (129) sortlist ::= expr sortorder */ - { 177, -1 }, /* (130) sortorder ::= ASC */ - { 177, -1 }, /* (131) sortorder ::= DESC */ - { 177, 0 }, /* (132) sortorder ::= */ - { 204, 0 }, /* (133) groupby_opt ::= */ - { 204, -3 }, /* (134) groupby_opt ::= GROUP BY nexprlist */ - { 205, 0 }, /* (135) having_opt ::= */ - { 205, -2 }, /* (136) having_opt ::= HAVING expr */ - { 207, 0 }, /* (137) limit_opt ::= */ - { 207, -2 }, /* (138) limit_opt ::= LIMIT expr */ - { 207, -4 }, /* (139) limit_opt ::= LIMIT expr OFFSET expr */ - { 207, -4 }, /* (140) limit_opt ::= LIMIT expr COMMA expr */ - { 150, -6 }, /* (141) cmd ::= with DELETE FROM xfullname indexed_opt where_opt */ - { 203, 0 }, /* (142) where_opt ::= */ - { 203, -2 }, /* (143) where_opt ::= WHERE expr */ - { 150, -8 }, /* (144) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */ - { 222, -5 }, /* (145) setlist ::= setlist COMMA nm EQ expr */ - { 222, -7 }, /* (146) setlist ::= setlist COMMA LP idlist RP EQ expr */ - { 222, -3 }, /* (147) setlist ::= nm EQ expr */ - { 222, -5 }, /* (148) setlist ::= LP idlist RP EQ expr */ - { 150, -7 }, /* (149) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ - { 150, -7 }, /* (150) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */ - { 225, 0 }, /* (151) upsert ::= */ - { 225, -11 }, /* (152) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */ - { 225, -8 }, /* (153) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */ - { 225, -4 }, /* (154) upsert ::= ON CONFLICT DO NOTHING */ - { 223, -2 }, /* (155) insert_cmd ::= INSERT orconf */ - { 223, -1 }, /* (156) insert_cmd ::= REPLACE */ - { 224, 0 }, /* (157) idlist_opt ::= */ - { 224, -3 }, /* (158) idlist_opt ::= LP idlist RP */ - { 220, -3 }, /* (159) idlist ::= idlist COMMA nm */ - { 220, -1 }, /* (160) idlist ::= nm */ - { 175, -3 }, /* (161) expr ::= LP expr RP */ - { 175, -1 }, /* (162) expr ::= ID|INDEXED */ - { 175, -1 }, /* (163) expr ::= JOIN_KW */ - { 175, -3 }, /* (164) expr ::= nm DOT nm */ - { 175, -5 }, /* (165) expr ::= nm DOT nm DOT nm */ - { 174, -1 }, /* (166) term ::= NULL|FLOAT|BLOB */ - { 174, -1 }, /* (167) term ::= STRING */ - { 174, -1 }, /* (168) term ::= INTEGER */ - { 175, -1 }, /* (169) expr ::= VARIABLE */ - { 175, -3 }, /* (170) expr ::= expr COLLATE ID|STRING */ - { 175, -6 }, /* (171) expr ::= CAST LP expr AS typetoken RP */ - { 175, -5 }, /* (172) expr ::= ID|INDEXED LP distinct exprlist RP */ - { 175, -4 }, /* (173) expr ::= ID|INDEXED LP STAR RP */ - { 174, -1 }, /* (174) term ::= CTIME_KW */ - { 175, -5 }, /* (175) expr ::= LP nexprlist COMMA expr RP */ - { 175, -3 }, /* (176) expr ::= expr AND expr */ - { 175, -3 }, /* (177) expr ::= expr OR expr */ - { 175, -3 }, /* (178) expr ::= expr LT|GT|GE|LE expr */ - { 175, -3 }, /* (179) expr ::= expr EQ|NE expr */ - { 175, -3 }, /* (180) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ - { 175, -3 }, /* (181) expr ::= expr PLUS|MINUS expr */ - { 175, -3 }, /* (182) expr ::= expr STAR|SLASH|REM expr */ - { 175, -3 }, /* (183) expr ::= expr CONCAT expr */ - { 226, -2 }, /* (184) likeop ::= NOT LIKE_KW|MATCH */ - { 175, -3 }, /* (185) expr ::= expr likeop expr */ - { 175, -5 }, /* (186) expr ::= expr likeop expr ESCAPE expr */ - { 175, -2 }, /* (187) expr ::= expr ISNULL|NOTNULL */ - { 175, -3 }, /* (188) expr ::= expr NOT NULL */ - { 175, -3 }, /* (189) expr ::= expr IS expr */ - { 175, -4 }, /* (190) expr ::= expr IS NOT expr */ - { 175, -2 }, /* (191) expr ::= NOT expr */ - { 175, -2 }, /* (192) expr ::= BITNOT expr */ - { 175, -2 }, /* (193) expr ::= MINUS expr */ - { 175, -2 }, /* (194) expr ::= PLUS expr */ - { 227, -1 }, /* (195) between_op ::= BETWEEN */ - { 227, -2 }, /* (196) between_op ::= NOT BETWEEN */ - { 175, -5 }, /* (197) expr ::= expr between_op expr AND expr */ - { 228, -1 }, /* (198) in_op ::= IN */ - { 228, -2 }, /* (199) in_op ::= NOT IN */ - { 175, -5 }, /* (200) expr ::= expr in_op LP exprlist RP */ - { 175, -3 }, /* (201) expr ::= LP select RP */ - { 175, -5 }, /* (202) expr ::= expr in_op LP select RP */ - { 175, -5 }, /* (203) expr ::= expr in_op nm dbnm paren_exprlist */ - { 175, -4 }, /* (204) expr ::= EXISTS LP select RP */ - { 175, -5 }, /* (205) expr ::= CASE case_operand case_exprlist case_else END */ - { 231, -5 }, /* (206) case_exprlist ::= case_exprlist WHEN expr THEN expr */ - { 231, -4 }, /* (207) case_exprlist ::= WHEN expr THEN expr */ - { 232, -2 }, /* (208) case_else ::= ELSE expr */ - { 232, 0 }, /* (209) case_else ::= */ - { 230, -1 }, /* (210) case_operand ::= expr */ - { 230, 0 }, /* (211) case_operand ::= */ - { 210, 0 }, /* (212) exprlist ::= */ - { 209, -3 }, /* (213) nexprlist ::= nexprlist COMMA expr */ - { 209, -1 }, /* (214) nexprlist ::= expr */ - { 229, 0 }, /* (215) paren_exprlist ::= */ - { 229, -3 }, /* (216) paren_exprlist ::= LP exprlist RP */ - { 150, -12 }, /* (217) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ - { 233, -1 }, /* (218) uniqueflag ::= UNIQUE */ - { 233, 0 }, /* (219) uniqueflag ::= */ - { 179, 0 }, /* (220) eidlist_opt ::= */ - { 179, -3 }, /* (221) eidlist_opt ::= LP eidlist RP */ - { 189, -5 }, /* (222) eidlist ::= eidlist COMMA nm collate sortorder */ - { 189, -3 }, /* (223) eidlist ::= nm collate sortorder */ - { 234, 0 }, /* (224) collate ::= */ - { 234, -2 }, /* (225) collate ::= COLLATE ID|STRING */ - { 150, -4 }, /* (226) cmd ::= DROP INDEX ifexists fullname */ - { 150, -1 }, /* (227) cmd ::= VACUUM */ - { 150, -2 }, /* (228) cmd ::= VACUUM nm */ - { 150, -3 }, /* (229) cmd ::= PRAGMA nm dbnm */ - { 150, -5 }, /* (230) cmd ::= PRAGMA nm dbnm EQ nmnum */ - { 150, -6 }, /* (231) cmd ::= PRAGMA nm dbnm LP nmnum RP */ - { 150, -5 }, /* (232) cmd ::= PRAGMA nm dbnm EQ minus_num */ - { 150, -6 }, /* (233) cmd ::= PRAGMA nm dbnm LP minus_num RP */ - { 170, -2 }, /* (234) plus_num ::= PLUS INTEGER|FLOAT */ - { 171, -2 }, /* (235) minus_num ::= MINUS INTEGER|FLOAT */ - { 150, -5 }, /* (236) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ - { 236, -11 }, /* (237) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ - { 238, -1 }, /* (238) trigger_time ::= BEFORE|AFTER */ - { 238, -2 }, /* (239) trigger_time ::= INSTEAD OF */ - { 238, 0 }, /* (240) trigger_time ::= */ - { 239, -1 }, /* (241) trigger_event ::= DELETE|INSERT */ - { 239, -1 }, /* (242) trigger_event ::= UPDATE */ - { 239, -3 }, /* (243) trigger_event ::= UPDATE OF idlist */ - { 241, 0 }, /* (244) when_clause ::= */ - { 241, -2 }, /* (245) when_clause ::= WHEN expr */ - { 237, -3 }, /* (246) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ - { 237, -2 }, /* (247) trigger_cmd_list ::= trigger_cmd SEMI */ - { 243, -3 }, /* (248) trnm ::= nm DOT nm */ - { 244, -3 }, /* (249) tridxby ::= INDEXED BY nm */ - { 244, -2 }, /* (250) tridxby ::= NOT INDEXED */ - { 242, -8 }, /* (251) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */ - { 242, -8 }, /* (252) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ - { 242, -6 }, /* (253) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ - { 242, -3 }, /* (254) trigger_cmd ::= scanpt select scanpt */ - { 175, -4 }, /* (255) expr ::= RAISE LP IGNORE RP */ - { 175, -6 }, /* (256) expr ::= RAISE LP raisetype COMMA nm RP */ - { 193, -1 }, /* (257) raisetype ::= ROLLBACK */ - { 193, -1 }, /* (258) raisetype ::= ABORT */ - { 193, -1 }, /* (259) raisetype ::= FAIL */ - { 150, -4 }, /* (260) cmd ::= DROP TRIGGER ifexists fullname */ - { 150, -6 }, /* (261) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ - { 150, -3 }, /* (262) cmd ::= DETACH database_kw_opt expr */ - { 246, 0 }, /* (263) key_opt ::= */ - { 246, -2 }, /* (264) key_opt ::= KEY expr */ - { 150, -1 }, /* (265) cmd ::= REINDEX */ - { 150, -3 }, /* (266) cmd ::= REINDEX nm dbnm */ - { 150, -1 }, /* (267) cmd ::= ANALYZE */ - { 150, -3 }, /* (268) cmd ::= ANALYZE nm dbnm */ - { 150, -6 }, /* (269) cmd ::= ALTER TABLE fullname RENAME TO nm */ - { 150, -7 }, /* (270) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ - { 247, -1 }, /* (271) add_column_fullname ::= fullname */ - { 150, -1 }, /* (272) cmd ::= create_vtab */ - { 150, -4 }, /* (273) cmd ::= create_vtab LP vtabarglist RP */ - { 249, -8 }, /* (274) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ - { 251, 0 }, /* (275) vtabarg ::= */ - { 252, -1 }, /* (276) vtabargtoken ::= ANY */ - { 252, -3 }, /* (277) vtabargtoken ::= lp anylist RP */ - { 253, -1 }, /* (278) lp ::= LP */ - { 221, -2 }, /* (279) with ::= WITH wqlist */ - { 221, -3 }, /* (280) with ::= WITH RECURSIVE wqlist */ - { 198, -6 }, /* (281) wqlist ::= nm eidlist_opt AS LP select RP */ - { 198, -8 }, /* (282) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */ - { 145, -1 }, /* (283) input ::= cmdlist */ - { 146, -2 }, /* (284) cmdlist ::= cmdlist ecmd */ - { 146, -1 }, /* (285) cmdlist ::= ecmd */ - { 147, -1 }, /* (286) ecmd ::= SEMI */ - { 147, -2 }, /* (287) ecmd ::= cmdx SEMI */ - { 147, -2 }, /* (288) ecmd ::= explain cmdx */ - { 152, 0 }, /* (289) trans_opt ::= */ - { 152, -1 }, /* (290) trans_opt ::= TRANSACTION */ - { 152, -2 }, /* (291) trans_opt ::= TRANSACTION nm */ - { 154, -1 }, /* (292) savepoint_opt ::= SAVEPOINT */ - { 154, 0 }, /* (293) savepoint_opt ::= */ - { 150, -2 }, /* (294) cmd ::= create_table create_table_args */ - { 161, -4 }, /* (295) columnlist ::= columnlist COMMA columnname carglist */ - { 161, -2 }, /* (296) columnlist ::= columnname carglist */ - { 153, -1 }, /* (297) nm ::= ID|INDEXED */ - { 153, -1 }, /* (298) nm ::= STRING */ - { 153, -1 }, /* (299) nm ::= JOIN_KW */ - { 167, -1 }, /* (300) typetoken ::= typename */ - { 168, -1 }, /* (301) typename ::= ID|STRING */ - { 169, -1 }, /* (302) signed ::= plus_num */ - { 169, -1 }, /* (303) signed ::= minus_num */ - { 166, -2 }, /* (304) carglist ::= carglist ccons */ - { 166, 0 }, /* (305) carglist ::= */ - { 173, -2 }, /* (306) ccons ::= NULL onconf */ - { 162, -2 }, /* (307) conslist_opt ::= COMMA conslist */ - { 185, -3 }, /* (308) conslist ::= conslist tconscomma tcons */ - { 185, -1 }, /* (309) conslist ::= tcons */ - { 186, 0 }, /* (310) tconscomma ::= */ - { 190, -1 }, /* (311) defer_subclause_opt ::= defer_subclause */ - { 192, -1 }, /* (312) resolvetype ::= raisetype */ - { 196, -1 }, /* (313) selectnowith ::= oneselect */ - { 197, -1 }, /* (314) oneselect ::= values */ - { 211, -2 }, /* (315) sclp ::= selcollist COMMA */ - { 212, -1 }, /* (316) as ::= ID|STRING */ - { 175, -1 }, /* (317) expr ::= term */ - { 226, -1 }, /* (318) likeop ::= LIKE_KW|MATCH */ - { 210, -1 }, /* (319) exprlist ::= nexprlist */ - { 235, -1 }, /* (320) nmnum ::= plus_num */ - { 235, -1 }, /* (321) nmnum ::= nm */ - { 235, -1 }, /* (322) nmnum ::= ON */ - { 235, -1 }, /* (323) nmnum ::= DELETE */ - { 235, -1 }, /* (324) nmnum ::= DEFAULT */ - { 170, -1 }, /* (325) plus_num ::= INTEGER|FLOAT */ - { 240, 0 }, /* (326) foreach_clause ::= */ - { 240, -3 }, /* (327) foreach_clause ::= FOR EACH ROW */ - { 243, -1 }, /* (328) trnm ::= nm */ - { 244, 0 }, /* (329) tridxby ::= */ - { 245, -1 }, /* (330) database_kw_opt ::= DATABASE */ - { 245, 0 }, /* (331) database_kw_opt ::= */ - { 248, 0 }, /* (332) kwcolumn_opt ::= */ - { 248, -1 }, /* (333) kwcolumn_opt ::= COLUMNKW */ - { 250, -1 }, /* (334) vtabarglist ::= vtabarg */ - { 250, -3 }, /* (335) vtabarglist ::= vtabarglist COMMA vtabarg */ - { 251, -2 }, /* (336) vtabarg ::= vtabarg vtabargtoken */ - { 254, 0 }, /* (337) anylist ::= */ - { 254, -4 }, /* (338) anylist ::= anylist LP anylist RP */ - { 254, -2 }, /* (339) anylist ::= anylist ANY */ - { 221, 0 }, /* (340) with ::= */ + { 159, -1 }, /* (0) explain ::= EXPLAIN */ + { 159, -3 }, /* (1) explain ::= EXPLAIN QUERY PLAN */ + { 158, -1 }, /* (2) cmdx ::= cmd */ + { 160, -3 }, /* (3) cmd ::= BEGIN transtype trans_opt */ + { 161, 0 }, /* (4) transtype ::= */ + { 161, -1 }, /* (5) transtype ::= DEFERRED */ + { 161, -1 }, /* (6) transtype ::= IMMEDIATE */ + { 161, -1 }, /* (7) transtype ::= EXCLUSIVE */ + { 160, -2 }, /* (8) cmd ::= COMMIT|END trans_opt */ + { 160, -2 }, /* (9) cmd ::= ROLLBACK trans_opt */ + { 160, -2 }, /* (10) cmd ::= SAVEPOINT nm */ + { 160, -3 }, /* (11) cmd ::= RELEASE savepoint_opt nm */ + { 160, -5 }, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ + { 165, -6 }, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */ + { 167, -1 }, /* (14) createkw ::= CREATE */ + { 169, 0 }, /* (15) ifnotexists ::= */ + { 169, -3 }, /* (16) ifnotexists ::= IF NOT EXISTS */ + { 168, -1 }, /* (17) temp ::= TEMP */ + { 168, 0 }, /* (18) temp ::= */ + { 166, -5 }, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_options */ + { 166, -2 }, /* (20) create_table_args ::= AS select */ + { 173, 0 }, /* (21) table_options ::= */ + { 173, -2 }, /* (22) table_options ::= WITHOUT nm */ + { 175, -2 }, /* (23) columnname ::= nm typetoken */ + { 177, 0 }, /* (24) typetoken ::= */ + { 177, -4 }, /* (25) typetoken ::= typename LP signed RP */ + { 177, -6 }, /* (26) typetoken ::= typename LP signed COMMA signed RP */ + { 178, -2 }, /* (27) typename ::= typename ID|STRING */ + { 182, 0 }, /* (28) scanpt ::= */ + { 183, -2 }, /* (29) ccons ::= CONSTRAINT nm */ + { 183, -4 }, /* (30) ccons ::= DEFAULT scanpt term scanpt */ + { 183, -4 }, /* (31) ccons ::= DEFAULT LP expr RP */ + { 183, -4 }, /* (32) ccons ::= DEFAULT PLUS term scanpt */ + { 183, -4 }, /* (33) ccons ::= DEFAULT MINUS term scanpt */ + { 183, -3 }, /* (34) ccons ::= DEFAULT scanpt ID|INDEXED */ + { 183, -3 }, /* (35) ccons ::= NOT NULL onconf */ + { 183, -5 }, /* (36) ccons ::= PRIMARY KEY sortorder onconf autoinc */ + { 183, -2 }, /* (37) ccons ::= UNIQUE onconf */ + { 183, -4 }, /* (38) ccons ::= CHECK LP expr RP */ + { 183, -4 }, /* (39) ccons ::= REFERENCES nm eidlist_opt refargs */ + { 183, -1 }, /* (40) ccons ::= defer_subclause */ + { 183, -2 }, /* (41) ccons ::= COLLATE ID|STRING */ + { 188, 0 }, /* (42) autoinc ::= */ + { 188, -1 }, /* (43) autoinc ::= AUTOINCR */ + { 190, 0 }, /* (44) refargs ::= */ + { 190, -2 }, /* (45) refargs ::= refargs refarg */ + { 192, -2 }, /* (46) refarg ::= MATCH nm */ + { 192, -3 }, /* (47) refarg ::= ON INSERT refact */ + { 192, -3 }, /* (48) refarg ::= ON DELETE refact */ + { 192, -3 }, /* (49) refarg ::= ON UPDATE refact */ + { 193, -2 }, /* (50) refact ::= SET NULL */ + { 193, -2 }, /* (51) refact ::= SET DEFAULT */ + { 193, -1 }, /* (52) refact ::= CASCADE */ + { 193, -1 }, /* (53) refact ::= RESTRICT */ + { 193, -2 }, /* (54) refact ::= NO ACTION */ + { 191, -3 }, /* (55) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ + { 191, -2 }, /* (56) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ + { 194, 0 }, /* (57) init_deferred_pred_opt ::= */ + { 194, -2 }, /* (58) init_deferred_pred_opt ::= INITIALLY DEFERRED */ + { 194, -2 }, /* (59) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ + { 172, 0 }, /* (60) conslist_opt ::= */ + { 196, -1 }, /* (61) tconscomma ::= COMMA */ + { 197, -2 }, /* (62) tcons ::= CONSTRAINT nm */ + { 197, -7 }, /* (63) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ + { 197, -5 }, /* (64) tcons ::= UNIQUE LP sortlist RP onconf */ + { 197, -5 }, /* (65) tcons ::= CHECK LP expr RP onconf */ + { 197, -10 }, /* (66) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ + { 200, 0 }, /* (67) defer_subclause_opt ::= */ + { 186, 0 }, /* (68) onconf ::= */ + { 186, -3 }, /* (69) onconf ::= ON CONFLICT resolvetype */ + { 201, 0 }, /* (70) orconf ::= */ + { 201, -2 }, /* (71) orconf ::= OR resolvetype */ + { 202, -1 }, /* (72) resolvetype ::= IGNORE */ + { 202, -1 }, /* (73) resolvetype ::= REPLACE */ + { 160, -4 }, /* (74) cmd ::= DROP TABLE ifexists fullname */ + { 204, -2 }, /* (75) ifexists ::= IF EXISTS */ + { 204, 0 }, /* (76) ifexists ::= */ + { 160, -9 }, /* (77) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ + { 160, -4 }, /* (78) cmd ::= DROP VIEW ifexists fullname */ + { 160, -1 }, /* (79) cmd ::= select */ + { 174, -3 }, /* (80) select ::= WITH wqlist selectnowith */ + { 174, -4 }, /* (81) select ::= WITH RECURSIVE wqlist selectnowith */ + { 174, -1 }, /* (82) select ::= selectnowith */ + { 206, -3 }, /* (83) selectnowith ::= selectnowith multiselect_op oneselect */ + { 209, -1 }, /* (84) multiselect_op ::= UNION */ + { 209, -2 }, /* (85) multiselect_op ::= UNION ALL */ + { 209, -1 }, /* (86) multiselect_op ::= EXCEPT|INTERSECT */ + { 207, -9 }, /* (87) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ + { 207, -10 }, /* (88) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ + { 219, -4 }, /* (89) values ::= VALUES LP nexprlist RP */ + { 219, -5 }, /* (90) values ::= values COMMA LP nexprlist RP */ + { 210, -1 }, /* (91) distinct ::= DISTINCT */ + { 210, -1 }, /* (92) distinct ::= ALL */ + { 210, 0 }, /* (93) distinct ::= */ + { 221, 0 }, /* (94) sclp ::= */ + { 211, -5 }, /* (95) selcollist ::= sclp scanpt expr scanpt as */ + { 211, -3 }, /* (96) selcollist ::= sclp scanpt STAR */ + { 211, -5 }, /* (97) selcollist ::= sclp scanpt nm DOT STAR */ + { 222, -2 }, /* (98) as ::= AS nm */ + { 222, 0 }, /* (99) as ::= */ + { 212, 0 }, /* (100) from ::= */ + { 212, -2 }, /* (101) from ::= FROM seltablist */ + { 224, -2 }, /* (102) stl_prefix ::= seltablist joinop */ + { 224, 0 }, /* (103) stl_prefix ::= */ + { 223, -7 }, /* (104) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ + { 223, -9 }, /* (105) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ + { 223, -7 }, /* (106) seltablist ::= stl_prefix LP select RP as on_opt using_opt */ + { 223, -7 }, /* (107) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ + { 170, 0 }, /* (108) dbnm ::= */ + { 170, -2 }, /* (109) dbnm ::= DOT nm */ + { 205, -1 }, /* (110) fullname ::= nm */ + { 205, -3 }, /* (111) fullname ::= nm DOT nm */ + { 230, -1 }, /* (112) xfullname ::= nm */ + { 230, -3 }, /* (113) xfullname ::= nm DOT nm */ + { 230, -5 }, /* (114) xfullname ::= nm DOT nm AS nm */ + { 230, -3 }, /* (115) xfullname ::= nm AS nm */ + { 225, -1 }, /* (116) joinop ::= COMMA|JOIN */ + { 225, -2 }, /* (117) joinop ::= JOIN_KW JOIN */ + { 225, -3 }, /* (118) joinop ::= JOIN_KW nm JOIN */ + { 225, -4 }, /* (119) joinop ::= JOIN_KW nm nm JOIN */ + { 227, -2 }, /* (120) on_opt ::= ON expr */ + { 227, 0 }, /* (121) on_opt ::= */ + { 226, 0 }, /* (122) indexed_opt ::= */ + { 226, -3 }, /* (123) indexed_opt ::= INDEXED BY nm */ + { 226, -2 }, /* (124) indexed_opt ::= NOT INDEXED */ + { 228, -4 }, /* (125) using_opt ::= USING LP idlist RP */ + { 228, 0 }, /* (126) using_opt ::= */ + { 216, 0 }, /* (127) orderby_opt ::= */ + { 216, -3 }, /* (128) orderby_opt ::= ORDER BY sortlist */ + { 198, -4 }, /* (129) sortlist ::= sortlist COMMA expr sortorder */ + { 198, -2 }, /* (130) sortlist ::= expr sortorder */ + { 187, -1 }, /* (131) sortorder ::= ASC */ + { 187, -1 }, /* (132) sortorder ::= DESC */ + { 187, 0 }, /* (133) sortorder ::= */ + { 214, 0 }, /* (134) groupby_opt ::= */ + { 214, -3 }, /* (135) groupby_opt ::= GROUP BY nexprlist */ + { 215, 0 }, /* (136) having_opt ::= */ + { 215, -2 }, /* (137) having_opt ::= HAVING expr */ + { 217, 0 }, /* (138) limit_opt ::= */ + { 217, -2 }, /* (139) limit_opt ::= LIMIT expr */ + { 217, -4 }, /* (140) limit_opt ::= LIMIT expr OFFSET expr */ + { 217, -4 }, /* (141) limit_opt ::= LIMIT expr COMMA expr */ + { 160, -6 }, /* (142) cmd ::= with DELETE FROM xfullname indexed_opt where_opt */ + { 213, 0 }, /* (143) where_opt ::= */ + { 213, -2 }, /* (144) where_opt ::= WHERE expr */ + { 160, -8 }, /* (145) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */ + { 233, -5 }, /* (146) setlist ::= setlist COMMA nm EQ expr */ + { 233, -7 }, /* (147) setlist ::= setlist COMMA LP idlist RP EQ expr */ + { 233, -3 }, /* (148) setlist ::= nm EQ expr */ + { 233, -5 }, /* (149) setlist ::= LP idlist RP EQ expr */ + { 160, -7 }, /* (150) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + { 160, -7 }, /* (151) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */ + { 236, 0 }, /* (152) upsert ::= */ + { 236, -11 }, /* (153) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */ + { 236, -8 }, /* (154) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */ + { 236, -4 }, /* (155) upsert ::= ON CONFLICT DO NOTHING */ + { 234, -2 }, /* (156) insert_cmd ::= INSERT orconf */ + { 234, -1 }, /* (157) insert_cmd ::= REPLACE */ + { 235, 0 }, /* (158) idlist_opt ::= */ + { 235, -3 }, /* (159) idlist_opt ::= LP idlist RP */ + { 231, -3 }, /* (160) idlist ::= idlist COMMA nm */ + { 231, -1 }, /* (161) idlist ::= nm */ + { 185, -3 }, /* (162) expr ::= LP expr RP */ + { 185, -1 }, /* (163) expr ::= ID|INDEXED */ + { 185, -1 }, /* (164) expr ::= JOIN_KW */ + { 185, -3 }, /* (165) expr ::= nm DOT nm */ + { 185, -5 }, /* (166) expr ::= nm DOT nm DOT nm */ + { 184, -1 }, /* (167) term ::= NULL|FLOAT|BLOB */ + { 184, -1 }, /* (168) term ::= STRING */ + { 184, -1 }, /* (169) term ::= INTEGER */ + { 185, -1 }, /* (170) expr ::= VARIABLE */ + { 185, -3 }, /* (171) expr ::= expr COLLATE ID|STRING */ + { 185, -6 }, /* (172) expr ::= CAST LP expr AS typetoken RP */ + { 185, -5 }, /* (173) expr ::= ID|INDEXED LP distinct exprlist RP */ + { 185, -4 }, /* (174) expr ::= ID|INDEXED LP STAR RP */ + { 185, -6 }, /* (175) expr ::= ID|INDEXED LP distinct exprlist RP over_clause */ + { 185, -5 }, /* (176) expr ::= ID|INDEXED LP STAR RP over_clause */ + { 184, -1 }, /* (177) term ::= CTIME_KW */ + { 185, -5 }, /* (178) expr ::= LP nexprlist COMMA expr RP */ + { 185, -3 }, /* (179) expr ::= expr AND expr */ + { 185, -3 }, /* (180) expr ::= expr OR expr */ + { 185, -3 }, /* (181) expr ::= expr LT|GT|GE|LE expr */ + { 185, -3 }, /* (182) expr ::= expr EQ|NE expr */ + { 185, -3 }, /* (183) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ + { 185, -3 }, /* (184) expr ::= expr PLUS|MINUS expr */ + { 185, -3 }, /* (185) expr ::= expr STAR|SLASH|REM expr */ + { 185, -3 }, /* (186) expr ::= expr CONCAT expr */ + { 238, -2 }, /* (187) likeop ::= NOT LIKE_KW|MATCH */ + { 185, -3 }, /* (188) expr ::= expr likeop expr */ + { 185, -5 }, /* (189) expr ::= expr likeop expr ESCAPE expr */ + { 185, -2 }, /* (190) expr ::= expr ISNULL|NOTNULL */ + { 185, -3 }, /* (191) expr ::= expr NOT NULL */ + { 185, -3 }, /* (192) expr ::= expr IS expr */ + { 185, -4 }, /* (193) expr ::= expr IS NOT expr */ + { 185, -2 }, /* (194) expr ::= NOT expr */ + { 185, -2 }, /* (195) expr ::= BITNOT expr */ + { 185, -2 }, /* (196) expr ::= PLUS|MINUS expr */ + { 239, -1 }, /* (197) between_op ::= BETWEEN */ + { 239, -2 }, /* (198) between_op ::= NOT BETWEEN */ + { 185, -5 }, /* (199) expr ::= expr between_op expr AND expr */ + { 240, -1 }, /* (200) in_op ::= IN */ + { 240, -2 }, /* (201) in_op ::= NOT IN */ + { 185, -5 }, /* (202) expr ::= expr in_op LP exprlist RP */ + { 185, -3 }, /* (203) expr ::= LP select RP */ + { 185, -5 }, /* (204) expr ::= expr in_op LP select RP */ + { 185, -5 }, /* (205) expr ::= expr in_op nm dbnm paren_exprlist */ + { 185, -4 }, /* (206) expr ::= EXISTS LP select RP */ + { 185, -5 }, /* (207) expr ::= CASE case_operand case_exprlist case_else END */ + { 243, -5 }, /* (208) case_exprlist ::= case_exprlist WHEN expr THEN expr */ + { 243, -4 }, /* (209) case_exprlist ::= WHEN expr THEN expr */ + { 244, -2 }, /* (210) case_else ::= ELSE expr */ + { 244, 0 }, /* (211) case_else ::= */ + { 242, -1 }, /* (212) case_operand ::= expr */ + { 242, 0 }, /* (213) case_operand ::= */ + { 229, 0 }, /* (214) exprlist ::= */ + { 220, -3 }, /* (215) nexprlist ::= nexprlist COMMA expr */ + { 220, -1 }, /* (216) nexprlist ::= expr */ + { 241, 0 }, /* (217) paren_exprlist ::= */ + { 241, -3 }, /* (218) paren_exprlist ::= LP exprlist RP */ + { 160, -12 }, /* (219) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + { 245, -1 }, /* (220) uniqueflag ::= UNIQUE */ + { 245, 0 }, /* (221) uniqueflag ::= */ + { 189, 0 }, /* (222) eidlist_opt ::= */ + { 189, -3 }, /* (223) eidlist_opt ::= LP eidlist RP */ + { 199, -5 }, /* (224) eidlist ::= eidlist COMMA nm collate sortorder */ + { 199, -3 }, /* (225) eidlist ::= nm collate sortorder */ + { 246, 0 }, /* (226) collate ::= */ + { 246, -2 }, /* (227) collate ::= COLLATE ID|STRING */ + { 160, -4 }, /* (228) cmd ::= DROP INDEX ifexists fullname */ + { 160, -1 }, /* (229) cmd ::= VACUUM */ + { 160, -2 }, /* (230) cmd ::= VACUUM nm */ + { 160, -3 }, /* (231) cmd ::= PRAGMA nm dbnm */ + { 160, -5 }, /* (232) cmd ::= PRAGMA nm dbnm EQ nmnum */ + { 160, -6 }, /* (233) cmd ::= PRAGMA nm dbnm LP nmnum RP */ + { 160, -5 }, /* (234) cmd ::= PRAGMA nm dbnm EQ minus_num */ + { 160, -6 }, /* (235) cmd ::= PRAGMA nm dbnm LP minus_num RP */ + { 180, -2 }, /* (236) plus_num ::= PLUS INTEGER|FLOAT */ + { 181, -2 }, /* (237) minus_num ::= MINUS INTEGER|FLOAT */ + { 160, -5 }, /* (238) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + { 248, -11 }, /* (239) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + { 250, -1 }, /* (240) trigger_time ::= BEFORE|AFTER */ + { 250, -2 }, /* (241) trigger_time ::= INSTEAD OF */ + { 250, 0 }, /* (242) trigger_time ::= */ + { 251, -1 }, /* (243) trigger_event ::= DELETE|INSERT */ + { 251, -1 }, /* (244) trigger_event ::= UPDATE */ + { 251, -3 }, /* (245) trigger_event ::= UPDATE OF idlist */ + { 253, 0 }, /* (246) when_clause ::= */ + { 253, -2 }, /* (247) when_clause ::= WHEN expr */ + { 249, -3 }, /* (248) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + { 249, -2 }, /* (249) trigger_cmd_list ::= trigger_cmd SEMI */ + { 255, -3 }, /* (250) trnm ::= nm DOT nm */ + { 256, -3 }, /* (251) tridxby ::= INDEXED BY nm */ + { 256, -2 }, /* (252) tridxby ::= NOT INDEXED */ + { 254, -8 }, /* (253) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */ + { 254, -8 }, /* (254) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + { 254, -6 }, /* (255) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + { 254, -3 }, /* (256) trigger_cmd ::= scanpt select scanpt */ + { 185, -4 }, /* (257) expr ::= RAISE LP IGNORE RP */ + { 185, -6 }, /* (258) expr ::= RAISE LP raisetype COMMA nm RP */ + { 203, -1 }, /* (259) raisetype ::= ROLLBACK */ + { 203, -1 }, /* (260) raisetype ::= ABORT */ + { 203, -1 }, /* (261) raisetype ::= FAIL */ + { 160, -4 }, /* (262) cmd ::= DROP TRIGGER ifexists fullname */ + { 160, -6 }, /* (263) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + { 160, -3 }, /* (264) cmd ::= DETACH database_kw_opt expr */ + { 258, 0 }, /* (265) key_opt ::= */ + { 258, -2 }, /* (266) key_opt ::= KEY expr */ + { 160, -1 }, /* (267) cmd ::= REINDEX */ + { 160, -3 }, /* (268) cmd ::= REINDEX nm dbnm */ + { 160, -1 }, /* (269) cmd ::= ANALYZE */ + { 160, -3 }, /* (270) cmd ::= ANALYZE nm dbnm */ + { 160, -6 }, /* (271) cmd ::= ALTER TABLE fullname RENAME TO nm */ + { 160, -7 }, /* (272) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + { 259, -1 }, /* (273) add_column_fullname ::= fullname */ + { 160, -8 }, /* (274) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + { 160, -1 }, /* (275) cmd ::= create_vtab */ + { 160, -4 }, /* (276) cmd ::= create_vtab LP vtabarglist RP */ + { 261, -8 }, /* (277) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + { 263, 0 }, /* (278) vtabarg ::= */ + { 264, -1 }, /* (279) vtabargtoken ::= ANY */ + { 264, -3 }, /* (280) vtabargtoken ::= lp anylist RP */ + { 265, -1 }, /* (281) lp ::= LP */ + { 232, -2 }, /* (282) with ::= WITH wqlist */ + { 232, -3 }, /* (283) with ::= WITH RECURSIVE wqlist */ + { 208, -6 }, /* (284) wqlist ::= nm eidlist_opt AS LP select RP */ + { 208, -8 }, /* (285) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */ + { 267, -1 }, /* (286) windowdefn_list ::= windowdefn */ + { 267, -3 }, /* (287) windowdefn_list ::= windowdefn_list COMMA windowdefn */ + { 268, -3 }, /* (288) windowdefn ::= nm AS window */ + { 269, -5 }, /* (289) window ::= LP part_opt orderby_opt frame_opt RP */ + { 271, -3 }, /* (290) part_opt ::= PARTITION BY nexprlist */ + { 271, 0 }, /* (291) part_opt ::= */ + { 270, 0 }, /* (292) frame_opt ::= */ + { 270, -2 }, /* (293) frame_opt ::= range_or_rows frame_bound_s */ + { 270, -5 }, /* (294) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e */ + { 273, -1 }, /* (295) range_or_rows ::= RANGE */ + { 273, -1 }, /* (296) range_or_rows ::= ROWS */ + { 275, -1 }, /* (297) frame_bound_s ::= frame_bound */ + { 275, -2 }, /* (298) frame_bound_s ::= UNBOUNDED PRECEDING */ + { 276, -1 }, /* (299) frame_bound_e ::= frame_bound */ + { 276, -2 }, /* (300) frame_bound_e ::= UNBOUNDED FOLLOWING */ + { 274, -2 }, /* (301) frame_bound ::= expr PRECEDING */ + { 274, -2 }, /* (302) frame_bound ::= CURRENT ROW */ + { 274, -2 }, /* (303) frame_bound ::= expr FOLLOWING */ + { 218, -2 }, /* (304) window_clause ::= WINDOW windowdefn_list */ + { 237, -3 }, /* (305) over_clause ::= filter_opt OVER window */ + { 237, -3 }, /* (306) over_clause ::= filter_opt OVER nm */ + { 272, 0 }, /* (307) filter_opt ::= */ + { 272, -5 }, /* (308) filter_opt ::= FILTER LP WHERE expr RP */ + { 155, -1 }, /* (309) input ::= cmdlist */ + { 156, -2 }, /* (310) cmdlist ::= cmdlist ecmd */ + { 156, -1 }, /* (311) cmdlist ::= ecmd */ + { 157, -1 }, /* (312) ecmd ::= SEMI */ + { 157, -2 }, /* (313) ecmd ::= cmdx SEMI */ + { 157, -2 }, /* (314) ecmd ::= explain cmdx */ + { 162, 0 }, /* (315) trans_opt ::= */ + { 162, -1 }, /* (316) trans_opt ::= TRANSACTION */ + { 162, -2 }, /* (317) trans_opt ::= TRANSACTION nm */ + { 164, -1 }, /* (318) savepoint_opt ::= SAVEPOINT */ + { 164, 0 }, /* (319) savepoint_opt ::= */ + { 160, -2 }, /* (320) cmd ::= create_table create_table_args */ + { 171, -4 }, /* (321) columnlist ::= columnlist COMMA columnname carglist */ + { 171, -2 }, /* (322) columnlist ::= columnname carglist */ + { 163, -1 }, /* (323) nm ::= ID|INDEXED */ + { 163, -1 }, /* (324) nm ::= STRING */ + { 163, -1 }, /* (325) nm ::= JOIN_KW */ + { 177, -1 }, /* (326) typetoken ::= typename */ + { 178, -1 }, /* (327) typename ::= ID|STRING */ + { 179, -1 }, /* (328) signed ::= plus_num */ + { 179, -1 }, /* (329) signed ::= minus_num */ + { 176, -2 }, /* (330) carglist ::= carglist ccons */ + { 176, 0 }, /* (331) carglist ::= */ + { 183, -2 }, /* (332) ccons ::= NULL onconf */ + { 172, -2 }, /* (333) conslist_opt ::= COMMA conslist */ + { 195, -3 }, /* (334) conslist ::= conslist tconscomma tcons */ + { 195, -1 }, /* (335) conslist ::= tcons */ + { 196, 0 }, /* (336) tconscomma ::= */ + { 200, -1 }, /* (337) defer_subclause_opt ::= defer_subclause */ + { 202, -1 }, /* (338) resolvetype ::= raisetype */ + { 206, -1 }, /* (339) selectnowith ::= oneselect */ + { 207, -1 }, /* (340) oneselect ::= values */ + { 221, -2 }, /* (341) sclp ::= selcollist COMMA */ + { 222, -1 }, /* (342) as ::= ID|STRING */ + { 185, -1 }, /* (343) expr ::= term */ + { 238, -1 }, /* (344) likeop ::= LIKE_KW|MATCH */ + { 229, -1 }, /* (345) exprlist ::= nexprlist */ + { 247, -1 }, /* (346) nmnum ::= plus_num */ + { 247, -1 }, /* (347) nmnum ::= nm */ + { 247, -1 }, /* (348) nmnum ::= ON */ + { 247, -1 }, /* (349) nmnum ::= DELETE */ + { 247, -1 }, /* (350) nmnum ::= DEFAULT */ + { 180, -1 }, /* (351) plus_num ::= INTEGER|FLOAT */ + { 252, 0 }, /* (352) foreach_clause ::= */ + { 252, -3 }, /* (353) foreach_clause ::= FOR EACH ROW */ + { 255, -1 }, /* (354) trnm ::= nm */ + { 256, 0 }, /* (355) tridxby ::= */ + { 257, -1 }, /* (356) database_kw_opt ::= DATABASE */ + { 257, 0 }, /* (357) database_kw_opt ::= */ + { 260, 0 }, /* (358) kwcolumn_opt ::= */ + { 260, -1 }, /* (359) kwcolumn_opt ::= COLUMNKW */ + { 262, -1 }, /* (360) vtabarglist ::= vtabarg */ + { 262, -3 }, /* (361) vtabarglist ::= vtabarglist COMMA vtabarg */ + { 263, -2 }, /* (362) vtabarg ::= vtabarg vtabargtoken */ + { 266, 0 }, /* (363) anylist ::= */ + { 266, -4 }, /* (364) anylist ::= anylist LP anylist RP */ + { 266, -2 }, /* (365) anylist ::= anylist ANY */ + { 232, 0 }, /* (366) with ::= */ }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -143862,7 +148577,7 @@ static YYACTIONTYPE yy_reduce( sqlite3ParserCTX_PDECL /* %extra_context */ ){ int yygoto; /* The next state */ - int yyact; /* The next action */ + YYACTIONTYPE yyact; /* The next action */ yyStackEntry *yymsp; /* The top of the parser's stack */ int yysize; /* Amount to pop the stack */ sqlite3ParserARG_FETCH @@ -143936,15 +148651,15 @@ static YYACTIONTYPE yy_reduce( { sqlite3FinishCoding(pParse); } break; case 3: /* cmd ::= BEGIN transtype trans_opt */ -{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy502);} +{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy70);} break; case 4: /* transtype ::= */ -{yymsp[1].minor.yy502 = TK_DEFERRED;} +{yymsp[1].minor.yy70 = TK_DEFERRED;} break; case 5: /* transtype ::= DEFERRED */ case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6); case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7); -{yymsp[0].minor.yy502 = yymsp[0].major; /*A-overwrites-X*/} +{yymsp[0].minor.yy70 = yymsp[0].major; /*A-overwrites-X*/} break; case 8: /* cmd ::= COMMIT|END trans_opt */ case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9); @@ -143967,7 +148682,7 @@ static YYACTIONTYPE yy_reduce( break; case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */ { - sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy502,0,0,yymsp[-2].minor.yy502); + sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy70,0,0,yymsp[-2].minor.yy70); } break; case 14: /* createkw ::= CREATE */ @@ -143980,34 +148695,34 @@ static YYACTIONTYPE yy_reduce( case 57: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==57); case 67: /* defer_subclause_opt ::= */ yytestcase(yyruleno==67); case 76: /* ifexists ::= */ yytestcase(yyruleno==76); - case 92: /* distinct ::= */ yytestcase(yyruleno==92); - case 224: /* collate ::= */ yytestcase(yyruleno==224); -{yymsp[1].minor.yy502 = 0;} + case 93: /* distinct ::= */ yytestcase(yyruleno==93); + case 226: /* collate ::= */ yytestcase(yyruleno==226); +{yymsp[1].minor.yy70 = 0;} break; case 16: /* ifnotexists ::= IF NOT EXISTS */ -{yymsp[-2].minor.yy502 = 1;} +{yymsp[-2].minor.yy70 = 1;} break; case 17: /* temp ::= TEMP */ case 43: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==43); -{yymsp[0].minor.yy502 = 1;} +{yymsp[0].minor.yy70 = 1;} break; case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_options */ { - sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy502,0); + sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy70,0); } break; case 20: /* create_table_args ::= AS select */ { - sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy399); - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy399); + sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy489); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy489); } break; case 22: /* table_options ::= WITHOUT nm */ { if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){ - yymsp[-1].minor.yy502 = TF_WithoutRowid | TF_NoVisibleRowid; + yymsp[-1].minor.yy70 = TF_WithoutRowid | TF_NoVisibleRowid; }else{ - yymsp[-1].minor.yy502 = 0; + yymsp[-1].minor.yy70 = 0; sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); } } @@ -144017,7 +148732,7 @@ static YYACTIONTYPE yy_reduce( break; case 24: /* typetoken ::= */ case 60: /* conslist_opt ::= */ yytestcase(yyruleno==60); - case 98: /* as ::= */ yytestcase(yyruleno==98); + case 99: /* as ::= */ yytestcase(yyruleno==99); {yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = 0;} break; case 25: /* typetoken ::= typename LP signed RP */ @@ -144036,7 +148751,7 @@ static YYACTIONTYPE yy_reduce( case 28: /* scanpt ::= */ { assert( yyLookahead!=YYNOCODE ); - yymsp[1].minor.yy36 = yyLookaheadToken.z; + yymsp[1].minor.yy392 = yyLookaheadToken.z; } break; case 29: /* ccons ::= CONSTRAINT nm */ @@ -144044,18 +148759,18 @@ static YYACTIONTYPE yy_reduce( {pParse->constraintName = yymsp[0].minor.yy0;} break; case 30: /* ccons ::= DEFAULT scanpt term scanpt */ -{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy182,yymsp[-2].minor.yy36,yymsp[0].minor.yy36);} +{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy18,yymsp[-2].minor.yy392,yymsp[0].minor.yy392);} break; case 31: /* ccons ::= DEFAULT LP expr RP */ -{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy182,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);} +{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy18,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);} break; case 32: /* ccons ::= DEFAULT PLUS term scanpt */ -{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy182,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy36);} +{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy18,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy392);} break; case 33: /* ccons ::= DEFAULT MINUS term scanpt */ { - Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[-1].minor.yy182, 0); - sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy36); + Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[-1].minor.yy18, 0); + sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy392); } break; case 34: /* ccons ::= DEFAULT scanpt ID|INDEXED */ @@ -144065,174 +148780,174 @@ static YYACTIONTYPE yy_reduce( sqlite3ExprIdToTrueFalse(p); testcase( p->op==TK_TRUEFALSE && sqlite3ExprTruthValue(p) ); } - sqlite3AddDefaultValue(pParse,p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.z+yymsp[0].minor.yy0.n); + sqlite3AddDefaultValue(pParse,p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.z+yymsp[0].minor.yy0.n); } break; case 35: /* ccons ::= NOT NULL onconf */ -{sqlite3AddNotNull(pParse, yymsp[0].minor.yy502);} +{sqlite3AddNotNull(pParse, yymsp[0].minor.yy70);} break; case 36: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */ -{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy502,yymsp[0].minor.yy502,yymsp[-2].minor.yy502);} +{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy70,yymsp[0].minor.yy70,yymsp[-2].minor.yy70);} break; case 37: /* ccons ::= UNIQUE onconf */ -{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy502,0,0,0,0, +{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy70,0,0,0,0, SQLITE_IDXTYPE_UNIQUE);} break; case 38: /* ccons ::= CHECK LP expr RP */ -{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy182);} +{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy18);} break; case 39: /* ccons ::= REFERENCES nm eidlist_opt refargs */ -{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy232,yymsp[0].minor.yy502);} +{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy420,yymsp[0].minor.yy70);} break; case 40: /* ccons ::= defer_subclause */ -{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy502);} +{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy70);} break; case 41: /* ccons ::= COLLATE ID|STRING */ {sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);} break; case 44: /* refargs ::= */ -{ yymsp[1].minor.yy502 = OE_None*0x0101; /* EV: R-19803-45884 */} +{ yymsp[1].minor.yy70 = OE_None*0x0101; /* EV: R-19803-45884 */} break; case 45: /* refargs ::= refargs refarg */ -{ yymsp[-1].minor.yy502 = (yymsp[-1].minor.yy502 & ~yymsp[0].minor.yy107.mask) | yymsp[0].minor.yy107.value; } +{ yymsp[-1].minor.yy70 = (yymsp[-1].minor.yy70 & ~yymsp[0].minor.yy111.mask) | yymsp[0].minor.yy111.value; } break; case 46: /* refarg ::= MATCH nm */ -{ yymsp[-1].minor.yy107.value = 0; yymsp[-1].minor.yy107.mask = 0x000000; } +{ yymsp[-1].minor.yy111.value = 0; yymsp[-1].minor.yy111.mask = 0x000000; } break; case 47: /* refarg ::= ON INSERT refact */ -{ yymsp[-2].minor.yy107.value = 0; yymsp[-2].minor.yy107.mask = 0x000000; } +{ yymsp[-2].minor.yy111.value = 0; yymsp[-2].minor.yy111.mask = 0x000000; } break; case 48: /* refarg ::= ON DELETE refact */ -{ yymsp[-2].minor.yy107.value = yymsp[0].minor.yy502; yymsp[-2].minor.yy107.mask = 0x0000ff; } +{ yymsp[-2].minor.yy111.value = yymsp[0].minor.yy70; yymsp[-2].minor.yy111.mask = 0x0000ff; } break; case 49: /* refarg ::= ON UPDATE refact */ -{ yymsp[-2].minor.yy107.value = yymsp[0].minor.yy502<<8; yymsp[-2].minor.yy107.mask = 0x00ff00; } +{ yymsp[-2].minor.yy111.value = yymsp[0].minor.yy70<<8; yymsp[-2].minor.yy111.mask = 0x00ff00; } break; case 50: /* refact ::= SET NULL */ -{ yymsp[-1].minor.yy502 = OE_SetNull; /* EV: R-33326-45252 */} +{ yymsp[-1].minor.yy70 = OE_SetNull; /* EV: R-33326-45252 */} break; case 51: /* refact ::= SET DEFAULT */ -{ yymsp[-1].minor.yy502 = OE_SetDflt; /* EV: R-33326-45252 */} +{ yymsp[-1].minor.yy70 = OE_SetDflt; /* EV: R-33326-45252 */} break; case 52: /* refact ::= CASCADE */ -{ yymsp[0].minor.yy502 = OE_Cascade; /* EV: R-33326-45252 */} +{ yymsp[0].minor.yy70 = OE_Cascade; /* EV: R-33326-45252 */} break; case 53: /* refact ::= RESTRICT */ -{ yymsp[0].minor.yy502 = OE_Restrict; /* EV: R-33326-45252 */} +{ yymsp[0].minor.yy70 = OE_Restrict; /* EV: R-33326-45252 */} break; case 54: /* refact ::= NO ACTION */ -{ yymsp[-1].minor.yy502 = OE_None; /* EV: R-33326-45252 */} +{ yymsp[-1].minor.yy70 = OE_None; /* EV: R-33326-45252 */} break; case 55: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ -{yymsp[-2].minor.yy502 = 0;} +{yymsp[-2].minor.yy70 = 0;} break; case 56: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ case 71: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==71); - case 155: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==155); -{yymsp[-1].minor.yy502 = yymsp[0].minor.yy502;} + case 156: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==156); +{yymsp[-1].minor.yy70 = yymsp[0].minor.yy70;} break; case 58: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ case 75: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==75); - case 196: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==196); - case 199: /* in_op ::= NOT IN */ yytestcase(yyruleno==199); - case 225: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==225); -{yymsp[-1].minor.yy502 = 1;} + case 198: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==198); + case 201: /* in_op ::= NOT IN */ yytestcase(yyruleno==201); + case 227: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==227); +{yymsp[-1].minor.yy70 = 1;} break; case 59: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ -{yymsp[-1].minor.yy502 = 0;} +{yymsp[-1].minor.yy70 = 0;} break; case 61: /* tconscomma ::= COMMA */ {pParse->constraintName.n = 0;} break; case 63: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ -{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy232,yymsp[0].minor.yy502,yymsp[-2].minor.yy502,0);} +{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy420,yymsp[0].minor.yy70,yymsp[-2].minor.yy70,0);} break; case 64: /* tcons ::= UNIQUE LP sortlist RP onconf */ -{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy232,yymsp[0].minor.yy502,0,0,0,0, +{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy420,yymsp[0].minor.yy70,0,0,0,0, SQLITE_IDXTYPE_UNIQUE);} break; case 65: /* tcons ::= CHECK LP expr RP onconf */ -{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy182);} +{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy18);} break; case 66: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ { - sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy232, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy232, yymsp[-1].minor.yy502); - sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy502); + sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy420, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy420, yymsp[-1].minor.yy70); + sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy70); } break; case 68: /* onconf ::= */ case 70: /* orconf ::= */ yytestcase(yyruleno==70); -{yymsp[1].minor.yy502 = OE_Default;} +{yymsp[1].minor.yy70 = OE_Default;} break; case 69: /* onconf ::= ON CONFLICT resolvetype */ -{yymsp[-2].minor.yy502 = yymsp[0].minor.yy502;} +{yymsp[-2].minor.yy70 = yymsp[0].minor.yy70;} break; case 72: /* resolvetype ::= IGNORE */ -{yymsp[0].minor.yy502 = OE_Ignore;} +{yymsp[0].minor.yy70 = OE_Ignore;} break; case 73: /* resolvetype ::= REPLACE */ - case 156: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==156); -{yymsp[0].minor.yy502 = OE_Replace;} + case 157: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==157); +{yymsp[0].minor.yy70 = OE_Replace;} break; case 74: /* cmd ::= DROP TABLE ifexists fullname */ { - sqlite3DropTable(pParse, yymsp[0].minor.yy427, 0, yymsp[-1].minor.yy502); + sqlite3DropTable(pParse, yymsp[0].minor.yy135, 0, yymsp[-1].minor.yy70); } break; case 77: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ { - sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy232, yymsp[0].minor.yy399, yymsp[-7].minor.yy502, yymsp[-5].minor.yy502); + sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy420, yymsp[0].minor.yy489, yymsp[-7].minor.yy70, yymsp[-5].minor.yy70); } break; case 78: /* cmd ::= DROP VIEW ifexists fullname */ { - sqlite3DropTable(pParse, yymsp[0].minor.yy427, 1, yymsp[-1].minor.yy502); + sqlite3DropTable(pParse, yymsp[0].minor.yy135, 1, yymsp[-1].minor.yy70); } break; case 79: /* cmd ::= select */ { SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0}; - sqlite3Select(pParse, yymsp[0].minor.yy399, &dest); - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy399); + sqlite3Select(pParse, yymsp[0].minor.yy489, &dest); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy489); } break; case 80: /* select ::= WITH wqlist selectnowith */ { - Select *p = yymsp[0].minor.yy399; + Select *p = yymsp[0].minor.yy489; if( p ){ - p->pWith = yymsp[-1].minor.yy91; + p->pWith = yymsp[-1].minor.yy449; parserDoubleLinkSelect(pParse, p); }else{ - sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy91); + sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy449); } - yymsp[-2].minor.yy399 = p; + yymsp[-2].minor.yy489 = p; } break; case 81: /* select ::= WITH RECURSIVE wqlist selectnowith */ { - Select *p = yymsp[0].minor.yy399; + Select *p = yymsp[0].minor.yy489; if( p ){ - p->pWith = yymsp[-1].minor.yy91; + p->pWith = yymsp[-1].minor.yy449; parserDoubleLinkSelect(pParse, p); }else{ - sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy91); + sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy449); } - yymsp[-3].minor.yy399 = p; + yymsp[-3].minor.yy489 = p; } break; case 82: /* select ::= selectnowith */ { - Select *p = yymsp[0].minor.yy399; + Select *p = yymsp[0].minor.yy489; if( p ){ parserDoubleLinkSelect(pParse, p); } - yymsp[0].minor.yy399 = p; /*A-overwrites-X*/ + yymsp[0].minor.yy489 = p; /*A-overwrites-X*/ } break; case 83: /* selectnowith ::= selectnowith multiselect_op oneselect */ { - Select *pRhs = yymsp[0].minor.yy399; - Select *pLhs = yymsp[-2].minor.yy399; + Select *pRhs = yymsp[0].minor.yy489; + Select *pLhs = yymsp[-2].minor.yy489; if( pRhs && pRhs->pPrior ){ SrcList *pFrom; Token x; @@ -144242,378 +148957,382 @@ static YYACTIONTYPE yy_reduce( pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0); } if( pRhs ){ - pRhs->op = (u8)yymsp[-1].minor.yy502; + pRhs->op = (u8)yymsp[-1].minor.yy70; pRhs->pPrior = pLhs; if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue; pRhs->selFlags &= ~SF_MultiValue; - if( yymsp[-1].minor.yy502!=TK_ALL ) pParse->hasCompound = 1; + if( yymsp[-1].minor.yy70!=TK_ALL ) pParse->hasCompound = 1; }else{ sqlite3SelectDelete(pParse->db, pLhs); } - yymsp[-2].minor.yy399 = pRhs; + yymsp[-2].minor.yy489 = pRhs; } break; case 84: /* multiselect_op ::= UNION */ case 86: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==86); -{yymsp[0].minor.yy502 = yymsp[0].major; /*A-overwrites-OP*/} +{yymsp[0].minor.yy70 = yymsp[0].major; /*A-overwrites-OP*/} break; case 85: /* multiselect_op ::= UNION ALL */ -{yymsp[-1].minor.yy502 = TK_ALL;} +{yymsp[-1].minor.yy70 = TK_ALL;} break; case 87: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ { -#if SELECTTRACE_ENABLED - Token s = yymsp[-8].minor.yy0; /*A-overwrites-S*/ -#endif - yymsp[-8].minor.yy399 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy232,yymsp[-5].minor.yy427,yymsp[-4].minor.yy182,yymsp[-3].minor.yy232,yymsp[-2].minor.yy182,yymsp[-1].minor.yy232,yymsp[-7].minor.yy502,yymsp[0].minor.yy182); -#if SELECTTRACE_ENABLED - /* Populate the Select.zSelName[] string that is used to help with - ** query planner debugging, to differentiate between multiple Select - ** objects in a complex query. - ** - ** If the SELECT keyword is immediately followed by a C-style comment - ** then extract the first few alphanumeric characters from within that - ** comment to be the zSelName value. Otherwise, the label is #N where - ** is an integer that is incremented with each SELECT statement seen. - */ - if( yymsp[-8].minor.yy399!=0 ){ - const char *z = s.z+6; - int i; - sqlite3_snprintf(sizeof(yymsp[-8].minor.yy399->zSelName), yymsp[-8].minor.yy399->zSelName,"#%d",++pParse->nSelect); - while( z[0]==' ' ) z++; - if( z[0]=='/' && z[1]=='*' ){ - z += 2; - while( z[0]==' ' ) z++; - for(i=0; sqlite3Isalnum(z[i]); i++){} - sqlite3_snprintf(sizeof(yymsp[-8].minor.yy399->zSelName), yymsp[-8].minor.yy399->zSelName, "%.*s", i, z); - } + yymsp[-8].minor.yy489 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy420,yymsp[-5].minor.yy135,yymsp[-4].minor.yy18,yymsp[-3].minor.yy420,yymsp[-2].minor.yy18,yymsp[-1].minor.yy420,yymsp[-7].minor.yy70,yymsp[0].minor.yy18); +} + break; + case 88: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ +{ + yymsp[-9].minor.yy489 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy420,yymsp[-6].minor.yy135,yymsp[-5].minor.yy18,yymsp[-4].minor.yy420,yymsp[-3].minor.yy18,yymsp[-1].minor.yy420,yymsp[-8].minor.yy70,yymsp[0].minor.yy18); + if( yymsp[-9].minor.yy489 ){ + yymsp[-9].minor.yy489->pWinDefn = yymsp[-2].minor.yy327; + }else{ + sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy327); } -#endif /* SELECTRACE_ENABLED */ } break; - case 88: /* values ::= VALUES LP nexprlist RP */ + case 89: /* values ::= VALUES LP nexprlist RP */ { - yymsp[-3].minor.yy399 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy232,0,0,0,0,0,SF_Values,0); + yymsp[-3].minor.yy489 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy420,0,0,0,0,0,SF_Values,0); } break; - case 89: /* values ::= values COMMA LP exprlist RP */ + case 90: /* values ::= values COMMA LP nexprlist RP */ { - Select *pRight, *pLeft = yymsp[-4].minor.yy399; - pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy232,0,0,0,0,0,SF_Values|SF_MultiValue,0); + Select *pRight, *pLeft = yymsp[-4].minor.yy489; + pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy420,0,0,0,0,0,SF_Values|SF_MultiValue,0); if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue; if( pRight ){ pRight->op = TK_ALL; pRight->pPrior = pLeft; - yymsp[-4].minor.yy399 = pRight; + yymsp[-4].minor.yy489 = pRight; }else{ - yymsp[-4].minor.yy399 = pLeft; + yymsp[-4].minor.yy489 = pLeft; } } break; - case 90: /* distinct ::= DISTINCT */ -{yymsp[0].minor.yy502 = SF_Distinct;} + case 91: /* distinct ::= DISTINCT */ +{yymsp[0].minor.yy70 = SF_Distinct;} break; - case 91: /* distinct ::= ALL */ -{yymsp[0].minor.yy502 = SF_All;} + case 92: /* distinct ::= ALL */ +{yymsp[0].minor.yy70 = SF_All;} break; - case 93: /* sclp ::= */ - case 126: /* orderby_opt ::= */ yytestcase(yyruleno==126); - case 133: /* groupby_opt ::= */ yytestcase(yyruleno==133); - case 212: /* exprlist ::= */ yytestcase(yyruleno==212); - case 215: /* paren_exprlist ::= */ yytestcase(yyruleno==215); - case 220: /* eidlist_opt ::= */ yytestcase(yyruleno==220); -{yymsp[1].minor.yy232 = 0;} + case 94: /* sclp ::= */ + case 127: /* orderby_opt ::= */ yytestcase(yyruleno==127); + case 134: /* groupby_opt ::= */ yytestcase(yyruleno==134); + case 214: /* exprlist ::= */ yytestcase(yyruleno==214); + case 217: /* paren_exprlist ::= */ yytestcase(yyruleno==217); + case 222: /* eidlist_opt ::= */ yytestcase(yyruleno==222); +{yymsp[1].minor.yy420 = 0;} break; - case 94: /* selcollist ::= sclp scanpt expr scanpt as */ + case 95: /* selcollist ::= sclp scanpt expr scanpt as */ { - yymsp[-4].minor.yy232 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy232, yymsp[-2].minor.yy182); - if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy232, &yymsp[0].minor.yy0, 1); - sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy232,yymsp[-3].minor.yy36,yymsp[-1].minor.yy36); + yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy420, yymsp[-2].minor.yy18); + if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy420, &yymsp[0].minor.yy0, 1); + sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy420,yymsp[-3].minor.yy392,yymsp[-1].minor.yy392); } break; - case 95: /* selcollist ::= sclp scanpt STAR */ + case 96: /* selcollist ::= sclp scanpt STAR */ { Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0); - yymsp[-2].minor.yy232 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy232, p); + yymsp[-2].minor.yy420 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy420, p); } break; - case 96: /* selcollist ::= sclp scanpt nm DOT STAR */ + case 97: /* selcollist ::= sclp scanpt nm DOT STAR */ { Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0); Expr *pLeft = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); - yymsp[-4].minor.yy232 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy232, pDot); + yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy420, pDot); } break; - case 97: /* as ::= AS nm */ - case 108: /* dbnm ::= DOT nm */ yytestcase(yyruleno==108); - case 234: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==234); - case 235: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==235); + case 98: /* as ::= AS nm */ + case 109: /* dbnm ::= DOT nm */ yytestcase(yyruleno==109); + case 236: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==236); + case 237: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==237); {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;} break; - case 99: /* from ::= */ -{yymsp[1].minor.yy427 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy427));} + case 100: /* from ::= */ +{yymsp[1].minor.yy135 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy135));} break; - case 100: /* from ::= FROM seltablist */ + case 101: /* from ::= FROM seltablist */ { - yymsp[-1].minor.yy427 = yymsp[0].minor.yy427; - sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy427); + yymsp[-1].minor.yy135 = yymsp[0].minor.yy135; + sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy135); } break; - case 101: /* stl_prefix ::= seltablist joinop */ + case 102: /* stl_prefix ::= seltablist joinop */ { - if( ALWAYS(yymsp[-1].minor.yy427 && yymsp[-1].minor.yy427->nSrc>0) ) yymsp[-1].minor.yy427->a[yymsp[-1].minor.yy427->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy502; + if( ALWAYS(yymsp[-1].minor.yy135 && yymsp[-1].minor.yy135->nSrc>0) ) yymsp[-1].minor.yy135->a[yymsp[-1].minor.yy135->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy70; } break; - case 102: /* stl_prefix ::= */ -{yymsp[1].minor.yy427 = 0;} + case 103: /* stl_prefix ::= */ +{yymsp[1].minor.yy135 = 0;} break; - case 103: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ + case 104: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ { - yymsp[-6].minor.yy427 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy427,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy182,yymsp[0].minor.yy510); - sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy427, &yymsp[-2].minor.yy0); + yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy18,yymsp[0].minor.yy48); + sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy135, &yymsp[-2].minor.yy0); } break; - case 104: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ + case 105: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ { - yymsp[-8].minor.yy427 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy427,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy182,yymsp[0].minor.yy510); - sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy427, yymsp[-4].minor.yy232); + yymsp[-8].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy135,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy18,yymsp[0].minor.yy48); + sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy135, yymsp[-4].minor.yy420); } break; - case 105: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */ + case 106: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */ { - yymsp[-6].minor.yy427 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy427,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy399,yymsp[-1].minor.yy182,yymsp[0].minor.yy510); + yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy489,yymsp[-1].minor.yy18,yymsp[0].minor.yy48); } break; - case 106: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ + case 107: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ { - if( yymsp[-6].minor.yy427==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy182==0 && yymsp[0].minor.yy510==0 ){ - yymsp[-6].minor.yy427 = yymsp[-4].minor.yy427; - }else if( yymsp[-4].minor.yy427->nSrc==1 ){ - yymsp[-6].minor.yy427 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy427,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy182,yymsp[0].minor.yy510); - if( yymsp[-6].minor.yy427 ){ - struct SrcList_item *pNew = &yymsp[-6].minor.yy427->a[yymsp[-6].minor.yy427->nSrc-1]; - struct SrcList_item *pOld = yymsp[-4].minor.yy427->a; + if( yymsp[-6].minor.yy135==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy18==0 && yymsp[0].minor.yy48==0 ){ + yymsp[-6].minor.yy135 = yymsp[-4].minor.yy135; + }else if( yymsp[-4].minor.yy135->nSrc==1 ){ + yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy18,yymsp[0].minor.yy48); + if( yymsp[-6].minor.yy135 ){ + struct SrcList_item *pNew = &yymsp[-6].minor.yy135->a[yymsp[-6].minor.yy135->nSrc-1]; + struct SrcList_item *pOld = yymsp[-4].minor.yy135->a; pNew->zName = pOld->zName; pNew->zDatabase = pOld->zDatabase; pNew->pSelect = pOld->pSelect; pOld->zName = pOld->zDatabase = 0; pOld->pSelect = 0; } - sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy427); + sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy135); }else{ Select *pSubquery; - sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy427); - pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy427,0,0,0,0,SF_NestedFrom,0); - yymsp[-6].minor.yy427 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy427,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy182,yymsp[0].minor.yy510); + sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy135); + pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy135,0,0,0,0,SF_NestedFrom,0); + yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy18,yymsp[0].minor.yy48); } } break; - case 107: /* dbnm ::= */ - case 121: /* indexed_opt ::= */ yytestcase(yyruleno==121); + case 108: /* dbnm ::= */ + case 122: /* indexed_opt ::= */ yytestcase(yyruleno==122); {yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;} break; - case 109: /* fullname ::= nm */ - case 111: /* xfullname ::= nm */ yytestcase(yyruleno==111); -{yymsp[0].minor.yy427 = sqlite3SrcListAppend(pParse->db,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/} - break; - case 110: /* fullname ::= nm DOT nm */ - case 112: /* xfullname ::= nm DOT nm */ yytestcase(yyruleno==112); -{yymsp[-2].minor.yy427 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} - break; - case 113: /* xfullname ::= nm DOT nm AS nm */ + case 110: /* fullname ::= nm */ { - yymsp[-4].minor.yy427 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/ - if( yymsp[-4].minor.yy427 ) yymsp[-4].minor.yy427->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); + yylhsminor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[0].minor.yy0,0); + if( IN_RENAME_OBJECT && yylhsminor.yy135 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy135->a[0].zName, &yymsp[0].minor.yy0); +} + yymsp[0].minor.yy135 = yylhsminor.yy135; + break; + case 111: /* fullname ::= nm DOT nm */ +{ + yylhsminor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); + if( IN_RENAME_OBJECT && yylhsminor.yy135 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy135->a[0].zName, &yymsp[0].minor.yy0); +} + yymsp[-2].minor.yy135 = yylhsminor.yy135; + break; + case 112: /* xfullname ::= nm */ +{yymsp[0].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/} + break; + case 113: /* xfullname ::= nm DOT nm */ +{yymsp[-2].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} + break; + case 114: /* xfullname ::= nm DOT nm AS nm */ +{ + yymsp[-4].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/ + if( yymsp[-4].minor.yy135 ) yymsp[-4].minor.yy135->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); } break; - case 114: /* xfullname ::= nm AS nm */ + case 115: /* xfullname ::= nm AS nm */ { - yymsp[-2].minor.yy427 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/ - if( yymsp[-2].minor.yy427 ) yymsp[-2].minor.yy427->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); + yymsp[-2].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/ + if( yymsp[-2].minor.yy135 ) yymsp[-2].minor.yy135->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); } break; - case 115: /* joinop ::= COMMA|JOIN */ -{ yymsp[0].minor.yy502 = JT_INNER; } + case 116: /* joinop ::= COMMA|JOIN */ +{ yymsp[0].minor.yy70 = JT_INNER; } break; - case 116: /* joinop ::= JOIN_KW JOIN */ -{yymsp[-1].minor.yy502 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} + case 117: /* joinop ::= JOIN_KW JOIN */ +{yymsp[-1].minor.yy70 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} break; - case 117: /* joinop ::= JOIN_KW nm JOIN */ -{yymsp[-2].minor.yy502 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} + case 118: /* joinop ::= JOIN_KW nm JOIN */ +{yymsp[-2].minor.yy70 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} break; - case 118: /* joinop ::= JOIN_KW nm nm JOIN */ -{yymsp[-3].minor.yy502 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} + case 119: /* joinop ::= JOIN_KW nm nm JOIN */ +{yymsp[-3].minor.yy70 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} break; - case 119: /* on_opt ::= ON expr */ - case 136: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==136); - case 143: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==143); - case 208: /* case_else ::= ELSE expr */ yytestcase(yyruleno==208); -{yymsp[-1].minor.yy182 = yymsp[0].minor.yy182;} + case 120: /* on_opt ::= ON expr */ + case 137: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==137); + case 144: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==144); + case 210: /* case_else ::= ELSE expr */ yytestcase(yyruleno==210); +{yymsp[-1].minor.yy18 = yymsp[0].minor.yy18;} break; - case 120: /* on_opt ::= */ - case 135: /* having_opt ::= */ yytestcase(yyruleno==135); - case 137: /* limit_opt ::= */ yytestcase(yyruleno==137); - case 142: /* where_opt ::= */ yytestcase(yyruleno==142); - case 209: /* case_else ::= */ yytestcase(yyruleno==209); - case 211: /* case_operand ::= */ yytestcase(yyruleno==211); -{yymsp[1].minor.yy182 = 0;} + case 121: /* on_opt ::= */ + case 136: /* having_opt ::= */ yytestcase(yyruleno==136); + case 138: /* limit_opt ::= */ yytestcase(yyruleno==138); + case 143: /* where_opt ::= */ yytestcase(yyruleno==143); + case 211: /* case_else ::= */ yytestcase(yyruleno==211); + case 213: /* case_operand ::= */ yytestcase(yyruleno==213); +{yymsp[1].minor.yy18 = 0;} break; - case 122: /* indexed_opt ::= INDEXED BY nm */ + case 123: /* indexed_opt ::= INDEXED BY nm */ {yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;} break; - case 123: /* indexed_opt ::= NOT INDEXED */ + case 124: /* indexed_opt ::= NOT INDEXED */ {yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;} break; - case 124: /* using_opt ::= USING LP idlist RP */ -{yymsp[-3].minor.yy510 = yymsp[-1].minor.yy510;} + case 125: /* using_opt ::= USING LP idlist RP */ +{yymsp[-3].minor.yy48 = yymsp[-1].minor.yy48;} break; - case 125: /* using_opt ::= */ - case 157: /* idlist_opt ::= */ yytestcase(yyruleno==157); -{yymsp[1].minor.yy510 = 0;} + case 126: /* using_opt ::= */ + case 158: /* idlist_opt ::= */ yytestcase(yyruleno==158); +{yymsp[1].minor.yy48 = 0;} break; - case 127: /* orderby_opt ::= ORDER BY sortlist */ - case 134: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==134); -{yymsp[-2].minor.yy232 = yymsp[0].minor.yy232;} + case 128: /* orderby_opt ::= ORDER BY sortlist */ + case 135: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==135); +{yymsp[-2].minor.yy420 = yymsp[0].minor.yy420;} break; - case 128: /* sortlist ::= sortlist COMMA expr sortorder */ + case 129: /* sortlist ::= sortlist COMMA expr sortorder */ { - yymsp[-3].minor.yy232 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy232,yymsp[-1].minor.yy182); - sqlite3ExprListSetSortOrder(yymsp[-3].minor.yy232,yymsp[0].minor.yy502); + yymsp[-3].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy420,yymsp[-1].minor.yy18); + sqlite3ExprListSetSortOrder(yymsp[-3].minor.yy420,yymsp[0].minor.yy70); } break; - case 129: /* sortlist ::= expr sortorder */ + case 130: /* sortlist ::= expr sortorder */ { - yymsp[-1].minor.yy232 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy182); /*A-overwrites-Y*/ - sqlite3ExprListSetSortOrder(yymsp[-1].minor.yy232,yymsp[0].minor.yy502); + yymsp[-1].minor.yy420 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy18); /*A-overwrites-Y*/ + sqlite3ExprListSetSortOrder(yymsp[-1].minor.yy420,yymsp[0].minor.yy70); } break; - case 130: /* sortorder ::= ASC */ -{yymsp[0].minor.yy502 = SQLITE_SO_ASC;} + case 131: /* sortorder ::= ASC */ +{yymsp[0].minor.yy70 = SQLITE_SO_ASC;} break; - case 131: /* sortorder ::= DESC */ -{yymsp[0].minor.yy502 = SQLITE_SO_DESC;} + case 132: /* sortorder ::= DESC */ +{yymsp[0].minor.yy70 = SQLITE_SO_DESC;} break; - case 132: /* sortorder ::= */ -{yymsp[1].minor.yy502 = SQLITE_SO_UNDEFINED;} + case 133: /* sortorder ::= */ +{yymsp[1].minor.yy70 = SQLITE_SO_UNDEFINED;} break; - case 138: /* limit_opt ::= LIMIT expr */ -{yymsp[-1].minor.yy182 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy182,0);} + case 139: /* limit_opt ::= LIMIT expr */ +{yymsp[-1].minor.yy18 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy18,0);} break; - case 139: /* limit_opt ::= LIMIT expr OFFSET expr */ -{yymsp[-3].minor.yy182 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy182,yymsp[0].minor.yy182);} + case 140: /* limit_opt ::= LIMIT expr OFFSET expr */ +{yymsp[-3].minor.yy18 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy18,yymsp[0].minor.yy18);} break; - case 140: /* limit_opt ::= LIMIT expr COMMA expr */ -{yymsp[-3].minor.yy182 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy182,yymsp[-2].minor.yy182);} + case 141: /* limit_opt ::= LIMIT expr COMMA expr */ +{yymsp[-3].minor.yy18 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy18,yymsp[-2].minor.yy18);} break; - case 141: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt */ + case 142: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt */ { - sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy427, &yymsp[-1].minor.yy0); - sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy427,yymsp[0].minor.yy182,0,0); + sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy135, &yymsp[-1].minor.yy0); + sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy135,yymsp[0].minor.yy18,0,0); } break; - case 144: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */ + case 145: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */ { - sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy427, &yymsp[-3].minor.yy0); - sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy232,"set list"); - sqlite3Update(pParse,yymsp[-4].minor.yy427,yymsp[-1].minor.yy232,yymsp[0].minor.yy182,yymsp[-5].minor.yy502,0,0,0); + sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy135, &yymsp[-3].minor.yy0); + sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy420,"set list"); + sqlite3Update(pParse,yymsp[-4].minor.yy135,yymsp[-1].minor.yy420,yymsp[0].minor.yy18,yymsp[-5].minor.yy70,0,0,0); } break; - case 145: /* setlist ::= setlist COMMA nm EQ expr */ + case 146: /* setlist ::= setlist COMMA nm EQ expr */ { - yymsp[-4].minor.yy232 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy232, yymsp[0].minor.yy182); - sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy232, &yymsp[-2].minor.yy0, 1); + yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy420, yymsp[0].minor.yy18); + sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy420, &yymsp[-2].minor.yy0, 1); } break; - case 146: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ + case 147: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ { - yymsp[-6].minor.yy232 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy232, yymsp[-3].minor.yy510, yymsp[0].minor.yy182); + yymsp[-6].minor.yy420 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy420, yymsp[-3].minor.yy48, yymsp[0].minor.yy18); } break; - case 147: /* setlist ::= nm EQ expr */ + case 148: /* setlist ::= nm EQ expr */ { - yylhsminor.yy232 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy182); - sqlite3ExprListSetName(pParse, yylhsminor.yy232, &yymsp[-2].minor.yy0, 1); + yylhsminor.yy420 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy18); + sqlite3ExprListSetName(pParse, yylhsminor.yy420, &yymsp[-2].minor.yy0, 1); } - yymsp[-2].minor.yy232 = yylhsminor.yy232; + yymsp[-2].minor.yy420 = yylhsminor.yy420; break; - case 148: /* setlist ::= LP idlist RP EQ expr */ + case 149: /* setlist ::= LP idlist RP EQ expr */ { - yymsp[-4].minor.yy232 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy510, yymsp[0].minor.yy182); + yymsp[-4].minor.yy420 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy48, yymsp[0].minor.yy18); } break; - case 149: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + case 150: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ { - sqlite3Insert(pParse, yymsp[-3].minor.yy427, yymsp[-1].minor.yy399, yymsp[-2].minor.yy510, yymsp[-5].minor.yy502, yymsp[0].minor.yy198); + sqlite3Insert(pParse, yymsp[-3].minor.yy135, yymsp[-1].minor.yy489, yymsp[-2].minor.yy48, yymsp[-5].minor.yy70, yymsp[0].minor.yy340); } break; - case 150: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */ + case 151: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */ { - sqlite3Insert(pParse, yymsp[-3].minor.yy427, 0, yymsp[-2].minor.yy510, yymsp[-5].minor.yy502, 0); + sqlite3Insert(pParse, yymsp[-3].minor.yy135, 0, yymsp[-2].minor.yy48, yymsp[-5].minor.yy70, 0); } break; - case 151: /* upsert ::= */ -{ yymsp[1].minor.yy198 = 0; } + case 152: /* upsert ::= */ +{ yymsp[1].minor.yy340 = 0; } break; - case 152: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */ -{ yymsp[-10].minor.yy198 = sqlite3UpsertNew(pParse->db,yymsp[-7].minor.yy232,yymsp[-5].minor.yy182,yymsp[-1].minor.yy232,yymsp[0].minor.yy182);} + case 153: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */ +{ yymsp[-10].minor.yy340 = sqlite3UpsertNew(pParse->db,yymsp[-7].minor.yy420,yymsp[-5].minor.yy18,yymsp[-1].minor.yy420,yymsp[0].minor.yy18);} break; - case 153: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */ -{ yymsp[-7].minor.yy198 = sqlite3UpsertNew(pParse->db,yymsp[-4].minor.yy232,yymsp[-2].minor.yy182,0,0); } + case 154: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */ +{ yymsp[-7].minor.yy340 = sqlite3UpsertNew(pParse->db,yymsp[-4].minor.yy420,yymsp[-2].minor.yy18,0,0); } break; - case 154: /* upsert ::= ON CONFLICT DO NOTHING */ -{ yymsp[-3].minor.yy198 = sqlite3UpsertNew(pParse->db,0,0,0,0); } + case 155: /* upsert ::= ON CONFLICT DO NOTHING */ +{ yymsp[-3].minor.yy340 = sqlite3UpsertNew(pParse->db,0,0,0,0); } break; - case 158: /* idlist_opt ::= LP idlist RP */ -{yymsp[-2].minor.yy510 = yymsp[-1].minor.yy510;} + case 159: /* idlist_opt ::= LP idlist RP */ +{yymsp[-2].minor.yy48 = yymsp[-1].minor.yy48;} break; - case 159: /* idlist ::= idlist COMMA nm */ -{yymsp[-2].minor.yy510 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy510,&yymsp[0].minor.yy0);} + case 160: /* idlist ::= idlist COMMA nm */ +{yymsp[-2].minor.yy48 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy48,&yymsp[0].minor.yy0);} break; - case 160: /* idlist ::= nm */ -{yymsp[0].minor.yy510 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} + case 161: /* idlist ::= nm */ +{yymsp[0].minor.yy48 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} break; - case 161: /* expr ::= LP expr RP */ -{yymsp[-2].minor.yy182 = yymsp[-1].minor.yy182;} + case 162: /* expr ::= LP expr RP */ +{yymsp[-2].minor.yy18 = yymsp[-1].minor.yy18;} break; - case 162: /* expr ::= ID|INDEXED */ - case 163: /* expr ::= JOIN_KW */ yytestcase(yyruleno==163); -{yymsp[0].minor.yy182=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} + case 163: /* expr ::= ID|INDEXED */ + case 164: /* expr ::= JOIN_KW */ yytestcase(yyruleno==164); +{yymsp[0].minor.yy18=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} break; - case 164: /* expr ::= nm DOT nm */ + case 165: /* expr ::= nm DOT nm */ { Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1); - yylhsminor.yy182 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[0].minor.yy0); + sqlite3RenameTokenMap(pParse, (void*)temp1, &yymsp[-2].minor.yy0); + } + yylhsminor.yy18 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); } - yymsp[-2].minor.yy182 = yylhsminor.yy182; + yymsp[-2].minor.yy18 = yylhsminor.yy18; break; - case 165: /* expr ::= nm DOT nm DOT nm */ + case 166: /* expr ::= nm DOT nm DOT nm */ { Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-4].minor.yy0, 1); Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); Expr *temp3 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1); Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3); - yylhsminor.yy182 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenMap(pParse, (void*)temp3, &yymsp[0].minor.yy0); + sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[-2].minor.yy0); + } + yylhsminor.yy18 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); } - yymsp[-4].minor.yy182 = yylhsminor.yy182; + yymsp[-4].minor.yy18 = yylhsminor.yy18; break; - case 166: /* term ::= NULL|FLOAT|BLOB */ - case 167: /* term ::= STRING */ yytestcase(yyruleno==167); -{yymsp[0].minor.yy182=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} + case 167: /* term ::= NULL|FLOAT|BLOB */ + case 168: /* term ::= STRING */ yytestcase(yyruleno==168); +{yymsp[0].minor.yy18=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} break; - case 168: /* term ::= INTEGER */ + case 169: /* term ::= INTEGER */ { - yylhsminor.yy182 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); + yylhsminor.yy18 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); } - yymsp[0].minor.yy182 = yylhsminor.yy182; + yymsp[0].minor.yy18 = yylhsminor.yy18; break; - case 169: /* expr ::= VARIABLE */ + case 170: /* expr ::= VARIABLE */ { if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){ u32 n = yymsp[0].minor.yy0.n; - yymsp[0].minor.yy182 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); - sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy182, n); + yymsp[0].minor.yy18 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); + sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy18, n); }else{ /* When doing a nested parse, one can include terms in an expression ** that look like this: #1 #2 ... These terms refer to registers @@ -144622,146 +149341,154 @@ static YYACTIONTYPE yy_reduce( assert( t.n>=2 ); if( pParse->nested==0 ){ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t); - yymsp[0].minor.yy182 = 0; + yymsp[0].minor.yy18 = 0; }else{ - yymsp[0].minor.yy182 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); - if( yymsp[0].minor.yy182 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy182->iTable); + yymsp[0].minor.yy18 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); + if( yymsp[0].minor.yy18 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy18->iTable); } } } break; - case 170: /* expr ::= expr COLLATE ID|STRING */ + case 171: /* expr ::= expr COLLATE ID|STRING */ { - yymsp[-2].minor.yy182 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy182, &yymsp[0].minor.yy0, 1); + yymsp[-2].minor.yy18 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy18, &yymsp[0].minor.yy0, 1); } break; - case 171: /* expr ::= CAST LP expr AS typetoken RP */ + case 172: /* expr ::= CAST LP expr AS typetoken RP */ { - yymsp[-5].minor.yy182 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); - sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy182, yymsp[-3].minor.yy182, 0); + yymsp[-5].minor.yy18 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); + sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy18, yymsp[-3].minor.yy18, 0); } break; - case 172: /* expr ::= ID|INDEXED LP distinct exprlist RP */ + case 173: /* expr ::= ID|INDEXED LP distinct exprlist RP */ { - if( yymsp[-1].minor.yy232 && yymsp[-1].minor.yy232->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){ - sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0); - } - yylhsminor.yy182 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy232, &yymsp[-4].minor.yy0); - if( yymsp[-2].minor.yy502==SF_Distinct && yylhsminor.yy182 ){ - yylhsminor.yy182->flags |= EP_Distinct; - } + yylhsminor.yy18 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy420, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy70); } - yymsp[-4].minor.yy182 = yylhsminor.yy182; + yymsp[-4].minor.yy18 = yylhsminor.yy18; break; - case 173: /* expr ::= ID|INDEXED LP STAR RP */ + case 174: /* expr ::= ID|INDEXED LP STAR RP */ { - yylhsminor.yy182 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0); + yylhsminor.yy18 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); } - yymsp[-3].minor.yy182 = yylhsminor.yy182; + yymsp[-3].minor.yy18 = yylhsminor.yy18; break; - case 174: /* term ::= CTIME_KW */ + case 175: /* expr ::= ID|INDEXED LP distinct exprlist RP over_clause */ { - yylhsminor.yy182 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0); + yylhsminor.yy18 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy420, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy70); + sqlite3WindowAttach(pParse, yylhsminor.yy18, yymsp[0].minor.yy327); } - yymsp[0].minor.yy182 = yylhsminor.yy182; + yymsp[-5].minor.yy18 = yylhsminor.yy18; break; - case 175: /* expr ::= LP nexprlist COMMA expr RP */ + case 176: /* expr ::= ID|INDEXED LP STAR RP over_clause */ { - ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy232, yymsp[-1].minor.yy182); - yymsp[-4].minor.yy182 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); - if( yymsp[-4].minor.yy182 ){ - yymsp[-4].minor.yy182->x.pList = pList; + yylhsminor.yy18 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); + sqlite3WindowAttach(pParse, yylhsminor.yy18, yymsp[0].minor.yy327); +} + yymsp[-4].minor.yy18 = yylhsminor.yy18; + break; + case 177: /* term ::= CTIME_KW */ +{ + yylhsminor.yy18 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); +} + yymsp[0].minor.yy18 = yylhsminor.yy18; + break; + case 178: /* expr ::= LP nexprlist COMMA expr RP */ +{ + ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy420, yymsp[-1].minor.yy18); + yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); + if( yymsp[-4].minor.yy18 ){ + yymsp[-4].minor.yy18->x.pList = pList; }else{ sqlite3ExprListDelete(pParse->db, pList); } } break; - case 176: /* expr ::= expr AND expr */ - case 177: /* expr ::= expr OR expr */ yytestcase(yyruleno==177); - case 178: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==178); - case 179: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==179); - case 180: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==180); - case 181: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==181); - case 182: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==182); - case 183: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==183); -{yymsp[-2].minor.yy182=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy182,yymsp[0].minor.yy182);} + case 179: /* expr ::= expr AND expr */ + case 180: /* expr ::= expr OR expr */ yytestcase(yyruleno==180); + case 181: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==181); + case 182: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==182); + case 183: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==183); + case 184: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==184); + case 185: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==185); + case 186: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==186); +{yymsp[-2].minor.yy18=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy18,yymsp[0].minor.yy18);} break; - case 184: /* likeop ::= NOT LIKE_KW|MATCH */ + case 187: /* likeop ::= NOT LIKE_KW|MATCH */ {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/} break; - case 185: /* expr ::= expr likeop expr */ + case 188: /* expr ::= expr likeop expr */ { ExprList *pList; int bNot = yymsp[-1].minor.yy0.n & 0x80000000; yymsp[-1].minor.yy0.n &= 0x7fffffff; - pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy182); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy182); - yymsp[-2].minor.yy182 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0); - if( bNot ) yymsp[-2].minor.yy182 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy182, 0); - if( yymsp[-2].minor.yy182 ) yymsp[-2].minor.yy182->flags |= EP_InfixFunc; + pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy18); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy18); + yymsp[-2].minor.yy18 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); + if( bNot ) yymsp[-2].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy18, 0); + if( yymsp[-2].minor.yy18 ) yymsp[-2].minor.yy18->flags |= EP_InfixFunc; } break; - case 186: /* expr ::= expr likeop expr ESCAPE expr */ + case 189: /* expr ::= expr likeop expr ESCAPE expr */ { ExprList *pList; int bNot = yymsp[-3].minor.yy0.n & 0x80000000; yymsp[-3].minor.yy0.n &= 0x7fffffff; - pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy182); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy182); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy182); - yymsp[-4].minor.yy182 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0); - if( bNot ) yymsp[-4].minor.yy182 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy182, 0); - if( yymsp[-4].minor.yy182 ) yymsp[-4].minor.yy182->flags |= EP_InfixFunc; + pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy18); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy18); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy18); + yymsp[-4].minor.yy18 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); + if( bNot ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0); + if( yymsp[-4].minor.yy18 ) yymsp[-4].minor.yy18->flags |= EP_InfixFunc; } break; - case 187: /* expr ::= expr ISNULL|NOTNULL */ -{yymsp[-1].minor.yy182 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy182,0);} + case 190: /* expr ::= expr ISNULL|NOTNULL */ +{yymsp[-1].minor.yy18 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy18,0);} break; - case 188: /* expr ::= expr NOT NULL */ -{yymsp[-2].minor.yy182 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy182,0);} + case 191: /* expr ::= expr NOT NULL */ +{yymsp[-2].minor.yy18 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy18,0);} break; - case 189: /* expr ::= expr IS expr */ + case 192: /* expr ::= expr IS expr */ { - yymsp[-2].minor.yy182 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy182,yymsp[0].minor.yy182); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy182, yymsp[-2].minor.yy182, TK_ISNULL); + yymsp[-2].minor.yy18 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy18,yymsp[0].minor.yy18); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy18, yymsp[-2].minor.yy18, TK_ISNULL); } break; - case 190: /* expr ::= expr IS NOT expr */ + case 193: /* expr ::= expr IS NOT expr */ { - yymsp[-3].minor.yy182 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy182,yymsp[0].minor.yy182); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy182, yymsp[-3].minor.yy182, TK_NOTNULL); + yymsp[-3].minor.yy18 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy18,yymsp[0].minor.yy18); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy18, yymsp[-3].minor.yy18, TK_NOTNULL); } break; - case 191: /* expr ::= NOT expr */ - case 192: /* expr ::= BITNOT expr */ yytestcase(yyruleno==192); -{yymsp[-1].minor.yy182 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy182, 0);/*A-overwrites-B*/} + case 194: /* expr ::= NOT expr */ + case 195: /* expr ::= BITNOT expr */ yytestcase(yyruleno==195); +{yymsp[-1].minor.yy18 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy18, 0);/*A-overwrites-B*/} break; - case 193: /* expr ::= MINUS expr */ -{yymsp[-1].minor.yy182 = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy182, 0);} - break; - case 194: /* expr ::= PLUS expr */ -{yymsp[-1].minor.yy182 = sqlite3PExpr(pParse, TK_UPLUS, yymsp[0].minor.yy182, 0);} - break; - case 195: /* between_op ::= BETWEEN */ - case 198: /* in_op ::= IN */ yytestcase(yyruleno==198); -{yymsp[0].minor.yy502 = 0;} - break; - case 197: /* expr ::= expr between_op expr AND expr */ + case 196: /* expr ::= PLUS|MINUS expr */ { - ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy182); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy182); - yymsp[-4].minor.yy182 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy182, 0); - if( yymsp[-4].minor.yy182 ){ - yymsp[-4].minor.yy182->x.pList = pList; + yymsp[-1].minor.yy18 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy18, 0); + /*A-overwrites-B*/ +} + break; + case 197: /* between_op ::= BETWEEN */ + case 200: /* in_op ::= IN */ yytestcase(yyruleno==200); +{yymsp[0].minor.yy70 = 0;} + break; + case 199: /* expr ::= expr between_op expr AND expr */ +{ + ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy18); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy18); + yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy18, 0); + if( yymsp[-4].minor.yy18 ){ + yymsp[-4].minor.yy18->x.pList = pList; }else{ sqlite3ExprListDelete(pParse->db, pList); } - if( yymsp[-3].minor.yy502 ) yymsp[-4].minor.yy182 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy182, 0); + if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0); } break; - case 200: /* expr ::= expr in_op LP exprlist RP */ + case 202: /* expr ::= expr in_op LP exprlist RP */ { - if( yymsp[-1].minor.yy232==0 ){ + if( yymsp[-1].minor.yy420==0 ){ /* Expressions of the form ** ** expr1 IN () @@ -144770,9 +149497,9 @@ static YYACTIONTYPE yy_reduce( ** simplify to constants 0 (false) and 1 (true), respectively, ** regardless of the value of expr1. */ - sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy182); - yymsp[-4].minor.yy182 = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[yymsp[-3].minor.yy502],1); - }else if( yymsp[-1].minor.yy232->nExpr==1 ){ + sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy18); + yymsp[-4].minor.yy18 = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[yymsp[-3].minor.yy70],1); + }else if( yymsp[-1].minor.yy420->nExpr==1 ){ /* Expressions of the form: ** ** expr1 IN (?1) @@ -144789,195 +149516,199 @@ static YYACTIONTYPE yy_reduce( ** affinity or the collating sequence to use for comparison. Otherwise, ** the semantics would be subtly different from IN or NOT IN. */ - Expr *pRHS = yymsp[-1].minor.yy232->a[0].pExpr; - yymsp[-1].minor.yy232->a[0].pExpr = 0; - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy232); + Expr *pRHS = yymsp[-1].minor.yy420->a[0].pExpr; + yymsp[-1].minor.yy420->a[0].pExpr = 0; + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy420); /* pRHS cannot be NULL because a malloc error would have been detected ** before now and control would have never reached this point */ if( ALWAYS(pRHS) ){ pRHS->flags &= ~EP_Collate; pRHS->flags |= EP_Generic; } - yymsp[-4].minor.yy182 = sqlite3PExpr(pParse, yymsp[-3].minor.yy502 ? TK_NE : TK_EQ, yymsp[-4].minor.yy182, pRHS); + yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, yymsp[-3].minor.yy70 ? TK_NE : TK_EQ, yymsp[-4].minor.yy18, pRHS); }else{ - yymsp[-4].minor.yy182 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy182, 0); - if( yymsp[-4].minor.yy182 ){ - yymsp[-4].minor.yy182->x.pList = yymsp[-1].minor.yy232; - sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy182); + yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy18, 0); + if( yymsp[-4].minor.yy18 ){ + yymsp[-4].minor.yy18->x.pList = yymsp[-1].minor.yy420; + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy18); }else{ - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy232); + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy420); } - if( yymsp[-3].minor.yy502 ) yymsp[-4].minor.yy182 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy182, 0); + if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0); } } break; - case 201: /* expr ::= LP select RP */ + case 203: /* expr ::= LP select RP */ { - yymsp[-2].minor.yy182 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); - sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy182, yymsp[-1].minor.yy399); + yymsp[-2].minor.yy18 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); + sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy18, yymsp[-1].minor.yy489); } break; - case 202: /* expr ::= expr in_op LP select RP */ + case 204: /* expr ::= expr in_op LP select RP */ { - yymsp[-4].minor.yy182 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy182, 0); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy182, yymsp[-1].minor.yy399); - if( yymsp[-3].minor.yy502 ) yymsp[-4].minor.yy182 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy182, 0); + yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy18, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy18, yymsp[-1].minor.yy489); + if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0); } break; - case 203: /* expr ::= expr in_op nm dbnm paren_exprlist */ + case 205: /* expr ::= expr in_op nm dbnm paren_exprlist */ { SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0); - if( yymsp[0].minor.yy232 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy232); - yymsp[-4].minor.yy182 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy182, 0); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy182, pSelect); - if( yymsp[-3].minor.yy502 ) yymsp[-4].minor.yy182 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy182, 0); + if( yymsp[0].minor.yy420 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy420); + yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy18, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy18, pSelect); + if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0); } break; - case 204: /* expr ::= EXISTS LP select RP */ + case 206: /* expr ::= EXISTS LP select RP */ { Expr *p; - p = yymsp[-3].minor.yy182 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); - sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy399); + p = yymsp[-3].minor.yy18 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); + sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy489); } break; - case 205: /* expr ::= CASE case_operand case_exprlist case_else END */ + case 207: /* expr ::= CASE case_operand case_exprlist case_else END */ { - yymsp[-4].minor.yy182 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy182, 0); - if( yymsp[-4].minor.yy182 ){ - yymsp[-4].minor.yy182->x.pList = yymsp[-1].minor.yy182 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy232,yymsp[-1].minor.yy182) : yymsp[-2].minor.yy232; - sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy182); + yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy18, 0); + if( yymsp[-4].minor.yy18 ){ + yymsp[-4].minor.yy18->x.pList = yymsp[-1].minor.yy18 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy420,yymsp[-1].minor.yy18) : yymsp[-2].minor.yy420; + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy18); }else{ - sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy232); - sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy182); + sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy420); + sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy18); } } break; - case 206: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ + case 208: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ { - yymsp[-4].minor.yy232 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy232, yymsp[-2].minor.yy182); - yymsp[-4].minor.yy232 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy232, yymsp[0].minor.yy182); + yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy420, yymsp[-2].minor.yy18); + yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy420, yymsp[0].minor.yy18); } break; - case 207: /* case_exprlist ::= WHEN expr THEN expr */ + case 209: /* case_exprlist ::= WHEN expr THEN expr */ { - yymsp[-3].minor.yy232 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy182); - yymsp[-3].minor.yy232 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy232, yymsp[0].minor.yy182); + yymsp[-3].minor.yy420 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy18); + yymsp[-3].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy420, yymsp[0].minor.yy18); } break; - case 210: /* case_operand ::= expr */ -{yymsp[0].minor.yy182 = yymsp[0].minor.yy182; /*A-overwrites-X*/} + case 212: /* case_operand ::= expr */ +{yymsp[0].minor.yy18 = yymsp[0].minor.yy18; /*A-overwrites-X*/} break; - case 213: /* nexprlist ::= nexprlist COMMA expr */ -{yymsp[-2].minor.yy232 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy232,yymsp[0].minor.yy182);} + case 215: /* nexprlist ::= nexprlist COMMA expr */ +{yymsp[-2].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy420,yymsp[0].minor.yy18);} break; - case 214: /* nexprlist ::= expr */ -{yymsp[0].minor.yy232 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy182); /*A-overwrites-Y*/} + case 216: /* nexprlist ::= expr */ +{yymsp[0].minor.yy420 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy18); /*A-overwrites-Y*/} break; - case 216: /* paren_exprlist ::= LP exprlist RP */ - case 221: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==221); -{yymsp[-2].minor.yy232 = yymsp[-1].minor.yy232;} + case 218: /* paren_exprlist ::= LP exprlist RP */ + case 223: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==223); +{yymsp[-2].minor.yy420 = yymsp[-1].minor.yy420;} break; - case 217: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + case 219: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ { sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, - sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy232, yymsp[-10].minor.yy502, - &yymsp[-11].minor.yy0, yymsp[0].minor.yy182, SQLITE_SO_ASC, yymsp[-8].minor.yy502, SQLITE_IDXTYPE_APPDEF); + sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy420, yymsp[-10].minor.yy70, + &yymsp[-11].minor.yy0, yymsp[0].minor.yy18, SQLITE_SO_ASC, yymsp[-8].minor.yy70, SQLITE_IDXTYPE_APPDEF); + if( IN_RENAME_OBJECT && pParse->pNewIndex ){ + sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0); + } } break; - case 218: /* uniqueflag ::= UNIQUE */ - case 258: /* raisetype ::= ABORT */ yytestcase(yyruleno==258); -{yymsp[0].minor.yy502 = OE_Abort;} + case 220: /* uniqueflag ::= UNIQUE */ + case 260: /* raisetype ::= ABORT */ yytestcase(yyruleno==260); +{yymsp[0].minor.yy70 = OE_Abort;} break; - case 219: /* uniqueflag ::= */ -{yymsp[1].minor.yy502 = OE_None;} + case 221: /* uniqueflag ::= */ +{yymsp[1].minor.yy70 = OE_None;} break; - case 222: /* eidlist ::= eidlist COMMA nm collate sortorder */ + case 224: /* eidlist ::= eidlist COMMA nm collate sortorder */ { - yymsp[-4].minor.yy232 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy232, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy502, yymsp[0].minor.yy502); + yymsp[-4].minor.yy420 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy420, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy70, yymsp[0].minor.yy70); } break; - case 223: /* eidlist ::= nm collate sortorder */ + case 225: /* eidlist ::= nm collate sortorder */ { - yymsp[-2].minor.yy232 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy502, yymsp[0].minor.yy502); /*A-overwrites-Y*/ + yymsp[-2].minor.yy420 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy70, yymsp[0].minor.yy70); /*A-overwrites-Y*/ } break; - case 226: /* cmd ::= DROP INDEX ifexists fullname */ -{sqlite3DropIndex(pParse, yymsp[0].minor.yy427, yymsp[-1].minor.yy502);} + case 228: /* cmd ::= DROP INDEX ifexists fullname */ +{sqlite3DropIndex(pParse, yymsp[0].minor.yy135, yymsp[-1].minor.yy70);} break; - case 227: /* cmd ::= VACUUM */ + case 229: /* cmd ::= VACUUM */ {sqlite3Vacuum(pParse,0);} break; - case 228: /* cmd ::= VACUUM nm */ + case 230: /* cmd ::= VACUUM nm */ {sqlite3Vacuum(pParse,&yymsp[0].minor.yy0);} break; - case 229: /* cmd ::= PRAGMA nm dbnm */ + case 231: /* cmd ::= PRAGMA nm dbnm */ {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} break; - case 230: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ + case 232: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);} break; - case 231: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ + case 233: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);} break; - case 232: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ + case 234: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);} break; - case 233: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ + case 235: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);} break; - case 236: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + case 238: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ { Token all; all.z = yymsp[-3].minor.yy0.z; all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n; - sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy47, &all); + sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy207, &all); } break; - case 237: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + case 239: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ { - sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy502, yymsp[-4].minor.yy300.a, yymsp[-4].minor.yy300.b, yymsp[-2].minor.yy427, yymsp[0].minor.yy182, yymsp[-10].minor.yy502, yymsp[-8].minor.yy502); + sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy70, yymsp[-4].minor.yy34.a, yymsp[-4].minor.yy34.b, yymsp[-2].minor.yy135, yymsp[0].minor.yy18, yymsp[-10].minor.yy70, yymsp[-8].minor.yy70); yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/ } break; - case 238: /* trigger_time ::= BEFORE|AFTER */ -{ yymsp[0].minor.yy502 = yymsp[0].major; /*A-overwrites-X*/ } + case 240: /* trigger_time ::= BEFORE|AFTER */ +{ yymsp[0].minor.yy70 = yymsp[0].major; /*A-overwrites-X*/ } break; - case 239: /* trigger_time ::= INSTEAD OF */ -{ yymsp[-1].minor.yy502 = TK_INSTEAD;} + case 241: /* trigger_time ::= INSTEAD OF */ +{ yymsp[-1].minor.yy70 = TK_INSTEAD;} break; - case 240: /* trigger_time ::= */ -{ yymsp[1].minor.yy502 = TK_BEFORE; } + case 242: /* trigger_time ::= */ +{ yymsp[1].minor.yy70 = TK_BEFORE; } break; - case 241: /* trigger_event ::= DELETE|INSERT */ - case 242: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==242); -{yymsp[0].minor.yy300.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy300.b = 0;} + case 243: /* trigger_event ::= DELETE|INSERT */ + case 244: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==244); +{yymsp[0].minor.yy34.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy34.b = 0;} break; - case 243: /* trigger_event ::= UPDATE OF idlist */ -{yymsp[-2].minor.yy300.a = TK_UPDATE; yymsp[-2].minor.yy300.b = yymsp[0].minor.yy510;} + case 245: /* trigger_event ::= UPDATE OF idlist */ +{yymsp[-2].minor.yy34.a = TK_UPDATE; yymsp[-2].minor.yy34.b = yymsp[0].minor.yy48;} break; - case 244: /* when_clause ::= */ - case 263: /* key_opt ::= */ yytestcase(yyruleno==263); -{ yymsp[1].minor.yy182 = 0; } + case 246: /* when_clause ::= */ + case 265: /* key_opt ::= */ yytestcase(yyruleno==265); + case 307: /* filter_opt ::= */ yytestcase(yyruleno==307); +{ yymsp[1].minor.yy18 = 0; } break; - case 245: /* when_clause ::= WHEN expr */ - case 264: /* key_opt ::= KEY expr */ yytestcase(yyruleno==264); -{ yymsp[-1].minor.yy182 = yymsp[0].minor.yy182; } + case 247: /* when_clause ::= WHEN expr */ + case 266: /* key_opt ::= KEY expr */ yytestcase(yyruleno==266); +{ yymsp[-1].minor.yy18 = yymsp[0].minor.yy18; } break; - case 246: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + case 248: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ { - assert( yymsp[-2].minor.yy47!=0 ); - yymsp[-2].minor.yy47->pLast->pNext = yymsp[-1].minor.yy47; - yymsp[-2].minor.yy47->pLast = yymsp[-1].minor.yy47; + assert( yymsp[-2].minor.yy207!=0 ); + yymsp[-2].minor.yy207->pLast->pNext = yymsp[-1].minor.yy207; + yymsp[-2].minor.yy207->pLast = yymsp[-1].minor.yy207; } break; - case 247: /* trigger_cmd_list ::= trigger_cmd SEMI */ + case 249: /* trigger_cmd_list ::= trigger_cmd SEMI */ { - assert( yymsp[-1].minor.yy47!=0 ); - yymsp[-1].minor.yy47->pLast = yymsp[-1].minor.yy47; + assert( yymsp[-1].minor.yy207!=0 ); + yymsp[-1].minor.yy207->pLast = yymsp[-1].minor.yy207; } break; - case 248: /* trnm ::= nm DOT nm */ + case 250: /* trnm ::= nm DOT nm */ { yymsp[-2].minor.yy0 = yymsp[0].minor.yy0; sqlite3ErrorMsg(pParse, @@ -144985,196 +149716,306 @@ static YYACTIONTYPE yy_reduce( "statements within triggers"); } break; - case 249: /* tridxby ::= INDEXED BY nm */ + case 251: /* tridxby ::= INDEXED BY nm */ { sqlite3ErrorMsg(pParse, "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 250: /* tridxby ::= NOT INDEXED */ + case 252: /* tridxby ::= NOT INDEXED */ { sqlite3ErrorMsg(pParse, "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 251: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */ -{yylhsminor.yy47 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-5].minor.yy0, yymsp[-2].minor.yy232, yymsp[-1].minor.yy182, yymsp[-6].minor.yy502, yymsp[-7].minor.yy0.z, yymsp[0].minor.yy36);} - yymsp[-7].minor.yy47 = yylhsminor.yy47; + case 253: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */ +{yylhsminor.yy207 = sqlite3TriggerUpdateStep(pParse, &yymsp[-5].minor.yy0, yymsp[-2].minor.yy420, yymsp[-1].minor.yy18, yymsp[-6].minor.yy70, yymsp[-7].minor.yy0.z, yymsp[0].minor.yy392);} + yymsp[-7].minor.yy207 = yylhsminor.yy207; break; - case 252: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + case 254: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ { - yylhsminor.yy47 = sqlite3TriggerInsertStep(pParse->db,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy510,yymsp[-2].minor.yy399,yymsp[-6].minor.yy502,yymsp[-1].minor.yy198,yymsp[-7].minor.yy36,yymsp[0].minor.yy36);/*yylhsminor.yy47-overwrites-yymsp[-6].minor.yy502*/ + yylhsminor.yy207 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy48,yymsp[-2].minor.yy489,yymsp[-6].minor.yy70,yymsp[-1].minor.yy340,yymsp[-7].minor.yy392,yymsp[0].minor.yy392);/*yylhsminor.yy207-overwrites-yymsp[-6].minor.yy70*/ } - yymsp[-7].minor.yy47 = yylhsminor.yy47; + yymsp[-7].minor.yy207 = yylhsminor.yy207; break; - case 253: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ -{yylhsminor.yy47 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy182, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy36);} - yymsp[-5].minor.yy47 = yylhsminor.yy47; + case 255: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ +{yylhsminor.yy207 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy18, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy392);} + yymsp[-5].minor.yy207 = yylhsminor.yy207; break; - case 254: /* trigger_cmd ::= scanpt select scanpt */ -{yylhsminor.yy47 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy399, yymsp[-2].minor.yy36, yymsp[0].minor.yy36); /*yylhsminor.yy47-overwrites-yymsp[-1].minor.yy399*/} - yymsp[-2].minor.yy47 = yylhsminor.yy47; + case 256: /* trigger_cmd ::= scanpt select scanpt */ +{yylhsminor.yy207 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy489, yymsp[-2].minor.yy392, yymsp[0].minor.yy392); /*yylhsminor.yy207-overwrites-yymsp[-1].minor.yy489*/} + yymsp[-2].minor.yy207 = yylhsminor.yy207; break; - case 255: /* expr ::= RAISE LP IGNORE RP */ + case 257: /* expr ::= RAISE LP IGNORE RP */ { - yymsp[-3].minor.yy182 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); - if( yymsp[-3].minor.yy182 ){ - yymsp[-3].minor.yy182->affinity = OE_Ignore; + yymsp[-3].minor.yy18 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); + if( yymsp[-3].minor.yy18 ){ + yymsp[-3].minor.yy18->affinity = OE_Ignore; } } break; - case 256: /* expr ::= RAISE LP raisetype COMMA nm RP */ + case 258: /* expr ::= RAISE LP raisetype COMMA nm RP */ { - yymsp[-5].minor.yy182 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); - if( yymsp[-5].minor.yy182 ) { - yymsp[-5].minor.yy182->affinity = (char)yymsp[-3].minor.yy502; + yymsp[-5].minor.yy18 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); + if( yymsp[-5].minor.yy18 ) { + yymsp[-5].minor.yy18->affinity = (char)yymsp[-3].minor.yy70; } } break; - case 257: /* raisetype ::= ROLLBACK */ -{yymsp[0].minor.yy502 = OE_Rollback;} + case 259: /* raisetype ::= ROLLBACK */ +{yymsp[0].minor.yy70 = OE_Rollback;} break; - case 259: /* raisetype ::= FAIL */ -{yymsp[0].minor.yy502 = OE_Fail;} + case 261: /* raisetype ::= FAIL */ +{yymsp[0].minor.yy70 = OE_Fail;} break; - case 260: /* cmd ::= DROP TRIGGER ifexists fullname */ + case 262: /* cmd ::= DROP TRIGGER ifexists fullname */ { - sqlite3DropTrigger(pParse,yymsp[0].minor.yy427,yymsp[-1].minor.yy502); + sqlite3DropTrigger(pParse,yymsp[0].minor.yy135,yymsp[-1].minor.yy70); } break; - case 261: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + case 263: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ { - sqlite3Attach(pParse, yymsp[-3].minor.yy182, yymsp[-1].minor.yy182, yymsp[0].minor.yy182); + sqlite3Attach(pParse, yymsp[-3].minor.yy18, yymsp[-1].minor.yy18, yymsp[0].minor.yy18); } break; - case 262: /* cmd ::= DETACH database_kw_opt expr */ + case 264: /* cmd ::= DETACH database_kw_opt expr */ { - sqlite3Detach(pParse, yymsp[0].minor.yy182); + sqlite3Detach(pParse, yymsp[0].minor.yy18); } break; - case 265: /* cmd ::= REINDEX */ + case 267: /* cmd ::= REINDEX */ {sqlite3Reindex(pParse, 0, 0);} break; - case 266: /* cmd ::= REINDEX nm dbnm */ + case 268: /* cmd ::= REINDEX nm dbnm */ {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 267: /* cmd ::= ANALYZE */ + case 269: /* cmd ::= ANALYZE */ {sqlite3Analyze(pParse, 0, 0);} break; - case 268: /* cmd ::= ANALYZE nm dbnm */ + case 270: /* cmd ::= ANALYZE nm dbnm */ {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 269: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ + case 271: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ { - sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy427,&yymsp[0].minor.yy0); + sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy135,&yymsp[0].minor.yy0); } break; - case 270: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + case 272: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ { yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n; sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0); } break; - case 271: /* add_column_fullname ::= fullname */ + case 273: /* add_column_fullname ::= fullname */ { disableLookaside(pParse); - sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy427); + sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy135); } break; - case 272: /* cmd ::= create_vtab */ + case 274: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ +{ + sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy135, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); +} + break; + case 275: /* cmd ::= create_vtab */ {sqlite3VtabFinishParse(pParse,0);} break; - case 273: /* cmd ::= create_vtab LP vtabarglist RP */ + case 276: /* cmd ::= create_vtab LP vtabarglist RP */ {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} break; - case 274: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + case 277: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ { - sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy502); + sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy70); } break; - case 275: /* vtabarg ::= */ + case 278: /* vtabarg ::= */ {sqlite3VtabArgInit(pParse);} break; - case 276: /* vtabargtoken ::= ANY */ - case 277: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==277); - case 278: /* lp ::= LP */ yytestcase(yyruleno==278); + case 279: /* vtabargtoken ::= ANY */ + case 280: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==280); + case 281: /* lp ::= LP */ yytestcase(yyruleno==281); {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} break; - case 279: /* with ::= WITH wqlist */ - case 280: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==280); -{ sqlite3WithPush(pParse, yymsp[0].minor.yy91, 1); } + case 282: /* with ::= WITH wqlist */ + case 283: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==283); +{ sqlite3WithPush(pParse, yymsp[0].minor.yy449, 1); } break; - case 281: /* wqlist ::= nm eidlist_opt AS LP select RP */ + case 284: /* wqlist ::= nm eidlist_opt AS LP select RP */ { - yymsp[-5].minor.yy91 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy232, yymsp[-1].minor.yy399); /*A-overwrites-X*/ + yymsp[-5].minor.yy449 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy420, yymsp[-1].minor.yy489); /*A-overwrites-X*/ } break; - case 282: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */ + case 285: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */ { - yymsp[-7].minor.yy91 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy91, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy232, yymsp[-1].minor.yy399); + yymsp[-7].minor.yy449 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy449, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy420, yymsp[-1].minor.yy489); } break; + case 286: /* windowdefn_list ::= windowdefn */ +{ yylhsminor.yy327 = yymsp[0].minor.yy327; } + yymsp[0].minor.yy327 = yylhsminor.yy327; + break; + case 287: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ +{ + assert( yymsp[0].minor.yy327!=0 ); + yymsp[0].minor.yy327->pNextWin = yymsp[-2].minor.yy327; + yylhsminor.yy327 = yymsp[0].minor.yy327; +} + yymsp[-2].minor.yy327 = yylhsminor.yy327; + break; + case 288: /* windowdefn ::= nm AS window */ +{ + if( ALWAYS(yymsp[0].minor.yy327) ){ + yymsp[0].minor.yy327->zName = sqlite3DbStrNDup(pParse->db, yymsp[-2].minor.yy0.z, yymsp[-2].minor.yy0.n); + } + yylhsminor.yy327 = yymsp[0].minor.yy327; +} + yymsp[-2].minor.yy327 = yylhsminor.yy327; + break; + case 289: /* window ::= LP part_opt orderby_opt frame_opt RP */ +{ + yymsp[-4].minor.yy327 = yymsp[-1].minor.yy327; + if( ALWAYS(yymsp[-4].minor.yy327) ){ + yymsp[-4].minor.yy327->pPartition = yymsp[-3].minor.yy420; + yymsp[-4].minor.yy327->pOrderBy = yymsp[-2].minor.yy420; + } +} + break; + case 290: /* part_opt ::= PARTITION BY nexprlist */ +{ yymsp[-2].minor.yy420 = yymsp[0].minor.yy420; } + break; + case 291: /* part_opt ::= */ +{ yymsp[1].minor.yy420 = 0; } + break; + case 292: /* frame_opt ::= */ +{ + yymsp[1].minor.yy327 = sqlite3WindowAlloc(pParse, TK_RANGE, TK_UNBOUNDED, 0, TK_CURRENT, 0); +} + break; + case 293: /* frame_opt ::= range_or_rows frame_bound_s */ +{ + yylhsminor.yy327 = sqlite3WindowAlloc(pParse, yymsp[-1].minor.yy70, yymsp[0].minor.yy119.eType, yymsp[0].minor.yy119.pExpr, TK_CURRENT, 0); +} + yymsp[-1].minor.yy327 = yylhsminor.yy327; + break; + case 294: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e */ +{ + yylhsminor.yy327 = sqlite3WindowAlloc(pParse, yymsp[-4].minor.yy70, yymsp[-2].minor.yy119.eType, yymsp[-2].minor.yy119.pExpr, yymsp[0].minor.yy119.eType, yymsp[0].minor.yy119.pExpr); +} + yymsp[-4].minor.yy327 = yylhsminor.yy327; + break; + case 295: /* range_or_rows ::= RANGE */ +{ yymsp[0].minor.yy70 = TK_RANGE; } + break; + case 296: /* range_or_rows ::= ROWS */ +{ yymsp[0].minor.yy70 = TK_ROWS; } + break; + case 297: /* frame_bound_s ::= frame_bound */ + case 299: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==299); +{ yylhsminor.yy119 = yymsp[0].minor.yy119; } + yymsp[0].minor.yy119 = yylhsminor.yy119; + break; + case 298: /* frame_bound_s ::= UNBOUNDED PRECEDING */ + case 300: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==300); +{yymsp[-1].minor.yy119.eType = TK_UNBOUNDED; yymsp[-1].minor.yy119.pExpr = 0;} + break; + case 301: /* frame_bound ::= expr PRECEDING */ +{ yylhsminor.yy119.eType = TK_PRECEDING; yylhsminor.yy119.pExpr = yymsp[-1].minor.yy18; } + yymsp[-1].minor.yy119 = yylhsminor.yy119; + break; + case 302: /* frame_bound ::= CURRENT ROW */ +{ yymsp[-1].minor.yy119.eType = TK_CURRENT ; yymsp[-1].minor.yy119.pExpr = 0; } + break; + case 303: /* frame_bound ::= expr FOLLOWING */ +{ yylhsminor.yy119.eType = TK_FOLLOWING; yylhsminor.yy119.pExpr = yymsp[-1].minor.yy18; } + yymsp[-1].minor.yy119 = yylhsminor.yy119; + break; + case 304: /* window_clause ::= WINDOW windowdefn_list */ +{ yymsp[-1].minor.yy327 = yymsp[0].minor.yy327; } + break; + case 305: /* over_clause ::= filter_opt OVER window */ +{ + yylhsminor.yy327 = yymsp[0].minor.yy327; + assert( yylhsminor.yy327!=0 ); + yylhsminor.yy327->pFilter = yymsp[-2].minor.yy18; +} + yymsp[-2].minor.yy327 = yylhsminor.yy327; + break; + case 306: /* over_clause ::= filter_opt OVER nm */ +{ + yylhsminor.yy327 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); + if( yylhsminor.yy327 ){ + yylhsminor.yy327->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n); + yylhsminor.yy327->pFilter = yymsp[-2].minor.yy18; + }else{ + sqlite3ExprDelete(pParse->db, yymsp[-2].minor.yy18); + } +} + yymsp[-2].minor.yy327 = yylhsminor.yy327; + break; + case 308: /* filter_opt ::= FILTER LP WHERE expr RP */ +{ yymsp[-4].minor.yy18 = yymsp[-1].minor.yy18; } + break; default: - /* (283) input ::= cmdlist */ yytestcase(yyruleno==283); - /* (284) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==284); - /* (285) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=285); - /* (286) ecmd ::= SEMI */ yytestcase(yyruleno==286); - /* (287) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==287); - /* (288) ecmd ::= explain cmdx */ yytestcase(yyruleno==288); - /* (289) trans_opt ::= */ yytestcase(yyruleno==289); - /* (290) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==290); - /* (291) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==291); - /* (292) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==292); - /* (293) savepoint_opt ::= */ yytestcase(yyruleno==293); - /* (294) cmd ::= create_table create_table_args */ yytestcase(yyruleno==294); - /* (295) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==295); - /* (296) columnlist ::= columnname carglist */ yytestcase(yyruleno==296); - /* (297) nm ::= ID|INDEXED */ yytestcase(yyruleno==297); - /* (298) nm ::= STRING */ yytestcase(yyruleno==298); - /* (299) nm ::= JOIN_KW */ yytestcase(yyruleno==299); - /* (300) typetoken ::= typename */ yytestcase(yyruleno==300); - /* (301) typename ::= ID|STRING */ yytestcase(yyruleno==301); - /* (302) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=302); - /* (303) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=303); - /* (304) carglist ::= carglist ccons */ yytestcase(yyruleno==304); - /* (305) carglist ::= */ yytestcase(yyruleno==305); - /* (306) ccons ::= NULL onconf */ yytestcase(yyruleno==306); - /* (307) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==307); - /* (308) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==308); - /* (309) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=309); - /* (310) tconscomma ::= */ yytestcase(yyruleno==310); - /* (311) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=311); - /* (312) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=312); - /* (313) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=313); - /* (314) oneselect ::= values */ yytestcase(yyruleno==314); - /* (315) sclp ::= selcollist COMMA */ yytestcase(yyruleno==315); - /* (316) as ::= ID|STRING */ yytestcase(yyruleno==316); - /* (317) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=317); - /* (318) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==318); - /* (319) exprlist ::= nexprlist */ yytestcase(yyruleno==319); - /* (320) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=320); - /* (321) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=321); - /* (322) nmnum ::= ON */ yytestcase(yyruleno==322); - /* (323) nmnum ::= DELETE */ yytestcase(yyruleno==323); - /* (324) nmnum ::= DEFAULT */ yytestcase(yyruleno==324); - /* (325) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==325); - /* (326) foreach_clause ::= */ yytestcase(yyruleno==326); - /* (327) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==327); - /* (328) trnm ::= nm */ yytestcase(yyruleno==328); - /* (329) tridxby ::= */ yytestcase(yyruleno==329); - /* (330) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==330); - /* (331) database_kw_opt ::= */ yytestcase(yyruleno==331); - /* (332) kwcolumn_opt ::= */ yytestcase(yyruleno==332); - /* (333) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==333); - /* (334) vtabarglist ::= vtabarg */ yytestcase(yyruleno==334); - /* (335) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==335); - /* (336) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==336); - /* (337) anylist ::= */ yytestcase(yyruleno==337); - /* (338) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==338); - /* (339) anylist ::= anylist ANY */ yytestcase(yyruleno==339); - /* (340) with ::= */ yytestcase(yyruleno==340); + /* (309) input ::= cmdlist */ yytestcase(yyruleno==309); + /* (310) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==310); + /* (311) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=311); + /* (312) ecmd ::= SEMI */ yytestcase(yyruleno==312); + /* (313) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==313); + /* (314) ecmd ::= explain cmdx */ yytestcase(yyruleno==314); + /* (315) trans_opt ::= */ yytestcase(yyruleno==315); + /* (316) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==316); + /* (317) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==317); + /* (318) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==318); + /* (319) savepoint_opt ::= */ yytestcase(yyruleno==319); + /* (320) cmd ::= create_table create_table_args */ yytestcase(yyruleno==320); + /* (321) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==321); + /* (322) columnlist ::= columnname carglist */ yytestcase(yyruleno==322); + /* (323) nm ::= ID|INDEXED */ yytestcase(yyruleno==323); + /* (324) nm ::= STRING */ yytestcase(yyruleno==324); + /* (325) nm ::= JOIN_KW */ yytestcase(yyruleno==325); + /* (326) typetoken ::= typename */ yytestcase(yyruleno==326); + /* (327) typename ::= ID|STRING */ yytestcase(yyruleno==327); + /* (328) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=328); + /* (329) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=329); + /* (330) carglist ::= carglist ccons */ yytestcase(yyruleno==330); + /* (331) carglist ::= */ yytestcase(yyruleno==331); + /* (332) ccons ::= NULL onconf */ yytestcase(yyruleno==332); + /* (333) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==333); + /* (334) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==334); + /* (335) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=335); + /* (336) tconscomma ::= */ yytestcase(yyruleno==336); + /* (337) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=337); + /* (338) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=338); + /* (339) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=339); + /* (340) oneselect ::= values */ yytestcase(yyruleno==340); + /* (341) sclp ::= selcollist COMMA */ yytestcase(yyruleno==341); + /* (342) as ::= ID|STRING */ yytestcase(yyruleno==342); + /* (343) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=343); + /* (344) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==344); + /* (345) exprlist ::= nexprlist */ yytestcase(yyruleno==345); + /* (346) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=346); + /* (347) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=347); + /* (348) nmnum ::= ON */ yytestcase(yyruleno==348); + /* (349) nmnum ::= DELETE */ yytestcase(yyruleno==349); + /* (350) nmnum ::= DEFAULT */ yytestcase(yyruleno==350); + /* (351) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==351); + /* (352) foreach_clause ::= */ yytestcase(yyruleno==352); + /* (353) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==353); + /* (354) trnm ::= nm */ yytestcase(yyruleno==354); + /* (355) tridxby ::= */ yytestcase(yyruleno==355); + /* (356) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==356); + /* (357) database_kw_opt ::= */ yytestcase(yyruleno==357); + /* (358) kwcolumn_opt ::= */ yytestcase(yyruleno==358); + /* (359) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==359); + /* (360) vtabarglist ::= vtabarg */ yytestcase(yyruleno==360); + /* (361) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==361); + /* (362) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==362); + /* (363) anylist ::= */ yytestcase(yyruleno==363); + /* (364) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==364); + /* (365) anylist ::= anylist ANY */ yytestcase(yyruleno==365); + /* (366) with ::= */ yytestcase(yyruleno==366); break; /********** End reduce actions ************************************************/ }; @@ -145328,12 +150169,12 @@ SQLITE_PRIVATE void sqlite3Parser( do{ assert( yyact==yypParser->yytos->stateno ); - yyact = yy_find_shift_action(yymajor,yyact); + yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact); if( yyact >= YY_MIN_REDUCE ){ yyact = yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor, yyminor sqlite3ParserCTX_PARAM); }else if( yyact <= YY_MAX_SHIFTREDUCE ){ - yy_shift(yypParser,yyact,yymajor,yyminor); + yy_shift(yypParser,yyact,(YYCODETYPE)yymajor,yyminor); #ifndef YYNOERRORRECOVERY yypParser->yyerrcnt--; #endif @@ -145461,6 +150302,21 @@ SQLITE_PRIVATE void sqlite3Parser( return; } +/* +** Return the fallback token corresponding to canonical token iToken, or +** 0 if iToken has no fallback. +*/ +SQLITE_PRIVATE int sqlite3ParserFallback(int iToken){ +#ifdef YYFALLBACK + if( iToken<(int)(sizeof(yyFallback)/sizeof(yyFallback[0])) ){ + return yyFallback[iToken]; + } +#else + (void)iToken; +#endif + return 0; +} + /************** End of parse.c ***********************************************/ /************** Begin file tokenize.c ****************************************/ /* @@ -145519,11 +150375,12 @@ SQLITE_PRIVATE void sqlite3Parser( #define CC_TILDA 25 /* '~' */ #define CC_DOT 26 /* '.' */ #define CC_ILLEGAL 27 /* Illegal character */ +#define CC_NUL 28 /* 0x00 */ static const unsigned char aiClass[] = { #ifdef SQLITE_ASCII /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */ -/* 0x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 7, 7, 27, 7, 7, 27, 27, +/* 0x */ 28, 27, 27, 27, 27, 27, 27, 27, 27, 7, 7, 27, 7, 7, 27, 27, /* 1x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, /* 2x */ 7, 15, 8, 5, 4, 22, 24, 8, 17, 18, 21, 20, 23, 11, 26, 16, /* 3x */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 19, 12, 14, 13, 6, @@ -145622,19 +150479,20 @@ const unsigned char ebcdicToAscii[] = { ** is substantially reduced. This is important for embedded applications ** on platforms with limited memory. */ -/* Hash score: 185 */ -/* zKWText[] encodes 845 bytes of keyword text in 561 bytes */ +/* Hash score: 208 */ +/* zKWText[] encodes 923 bytes of keyword text in 614 bytes */ /* REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECT */ /* ABLEFTHENDEFERRABLELSEXCEPTRANSACTIONATURALTERAISEXCLUSIVE */ /* XISTSAVEPOINTERSECTRIGGEREFERENCESCONSTRAINTOFFSETEMPORARY */ -/* UNIQUERYWITHOUTERELEASEATTACHAVINGROUPDATEBEGINNERECURSIVE */ -/* BETWEENOTHINGLOBYCASCADELETECASECOLLATECREATECURRENT_DATE */ -/* DETACHIMMEDIATEJOINSERTLIKEMATCHPLANALYZEPRAGMABORTVALUES */ -/* VIRTUALIMITWHENOTNULLWHERENAMEAFTEREPLACEANDEFAULT */ -/* AUTOINCREMENTCASTCOLUMNCOMMITCONFLICTCROSSCURRENT_TIMESTAMP */ -/* RIMARYDEFERREDISTINCTDORDERESTRICTDROPFAILFROMFULLIFISNULL */ -/* RIGHTROLLBACKROWUNIONUSINGVACUUMVIEWINITIALLY */ -static const char zKWText[560] = { +/* UNIQUERYWITHOUTERELEASEATTACHAVINGROUPDATEBEGINNERANGEBETWEEN */ +/* OTHINGLOBYCASCADELETECASECOLLATECREATECURRENT_DATEDETACH */ +/* IMMEDIATEJOINSERTLIKEMATCHPLANALYZEPRAGMABORTVALUESVIRTUALIMIT */ +/* WHENOTNULLWHERECURSIVEAFTERENAMEANDEFAULTAUTOINCREMENTCAST */ +/* COLUMNCOMMITCONFLICTCROSSCURRENT_TIMESTAMPARTITIONDEFERRED */ +/* ISTINCTDROPRECEDINGFAILFILTEREPLACEFOLLOWINGFROMFULLIFISNULL */ +/* ORDERESTRICTOVERIGHTROLLBACKROWSUNBOUNDEDUNIONUSINGVACUUMVIEW */ +/* INDOWINITIALLYPRIMARY */ +static const char zKWText[613] = { 'R','E','I','N','D','E','X','E','D','E','S','C','A','P','E','A','C','H', 'E','C','K','E','Y','B','E','F','O','R','E','I','G','N','O','R','E','G', 'E','X','P','L','A','I','N','S','T','E','A','D','D','A','T','A','B','A', @@ -145647,84 +150505,90 @@ static const char zKWText[560] = { 'O','F','F','S','E','T','E','M','P','O','R','A','R','Y','U','N','I','Q', 'U','E','R','Y','W','I','T','H','O','U','T','E','R','E','L','E','A','S', 'E','A','T','T','A','C','H','A','V','I','N','G','R','O','U','P','D','A', - 'T','E','B','E','G','I','N','N','E','R','E','C','U','R','S','I','V','E', - 'B','E','T','W','E','E','N','O','T','H','I','N','G','L','O','B','Y','C', - 'A','S','C','A','D','E','L','E','T','E','C','A','S','E','C','O','L','L', - 'A','T','E','C','R','E','A','T','E','C','U','R','R','E','N','T','_','D', - 'A','T','E','D','E','T','A','C','H','I','M','M','E','D','I','A','T','E', - 'J','O','I','N','S','E','R','T','L','I','K','E','M','A','T','C','H','P', - 'L','A','N','A','L','Y','Z','E','P','R','A','G','M','A','B','O','R','T', - 'V','A','L','U','E','S','V','I','R','T','U','A','L','I','M','I','T','W', - 'H','E','N','O','T','N','U','L','L','W','H','E','R','E','N','A','M','E', - 'A','F','T','E','R','E','P','L','A','C','E','A','N','D','E','F','A','U', - 'L','T','A','U','T','O','I','N','C','R','E','M','E','N','T','C','A','S', - 'T','C','O','L','U','M','N','C','O','M','M','I','T','C','O','N','F','L', - 'I','C','T','C','R','O','S','S','C','U','R','R','E','N','T','_','T','I', - 'M','E','S','T','A','M','P','R','I','M','A','R','Y','D','E','F','E','R', - 'R','E','D','I','S','T','I','N','C','T','D','O','R','D','E','R','E','S', - 'T','R','I','C','T','D','R','O','P','F','A','I','L','F','R','O','M','F', - 'U','L','L','I','F','I','S','N','U','L','L','R','I','G','H','T','R','O', - 'L','L','B','A','C','K','R','O','W','U','N','I','O','N','U','S','I','N', - 'G','V','A','C','U','U','M','V','I','E','W','I','N','I','T','I','A','L', - 'L','Y', + 'T','E','B','E','G','I','N','N','E','R','A','N','G','E','B','E','T','W', + 'E','E','N','O','T','H','I','N','G','L','O','B','Y','C','A','S','C','A', + 'D','E','L','E','T','E','C','A','S','E','C','O','L','L','A','T','E','C', + 'R','E','A','T','E','C','U','R','R','E','N','T','_','D','A','T','E','D', + 'E','T','A','C','H','I','M','M','E','D','I','A','T','E','J','O','I','N', + 'S','E','R','T','L','I','K','E','M','A','T','C','H','P','L','A','N','A', + 'L','Y','Z','E','P','R','A','G','M','A','B','O','R','T','V','A','L','U', + 'E','S','V','I','R','T','U','A','L','I','M','I','T','W','H','E','N','O', + 'T','N','U','L','L','W','H','E','R','E','C','U','R','S','I','V','E','A', + 'F','T','E','R','E','N','A','M','E','A','N','D','E','F','A','U','L','T', + 'A','U','T','O','I','N','C','R','E','M','E','N','T','C','A','S','T','C', + 'O','L','U','M','N','C','O','M','M','I','T','C','O','N','F','L','I','C', + 'T','C','R','O','S','S','C','U','R','R','E','N','T','_','T','I','M','E', + 'S','T','A','M','P','A','R','T','I','T','I','O','N','D','E','F','E','R', + 'R','E','D','I','S','T','I','N','C','T','D','R','O','P','R','E','C','E', + 'D','I','N','G','F','A','I','L','F','I','L','T','E','R','E','P','L','A', + 'C','E','F','O','L','L','O','W','I','N','G','F','R','O','M','F','U','L', + 'L','I','F','I','S','N','U','L','L','O','R','D','E','R','E','S','T','R', + 'I','C','T','O','V','E','R','I','G','H','T','R','O','L','L','B','A','C', + 'K','R','O','W','S','U','N','B','O','U','N','D','E','D','U','N','I','O', + 'N','U','S','I','N','G','V','A','C','U','U','M','V','I','E','W','I','N', + 'D','O','W','I','N','I','T','I','A','L','L','Y','P','R','I','M','A','R', + 'Y', }; /* aKWHash[i] is the hash value for the i-th keyword */ static const unsigned char aKWHash[127] = { - 74, 108, 119, 72, 0, 45, 0, 0, 81, 0, 76, 61, 0, - 42, 12, 77, 15, 0, 118, 84, 54, 116, 0, 19, 0, 0, - 123, 0, 121, 111, 0, 22, 96, 0, 9, 0, 0, 68, 69, - 0, 67, 6, 0, 48, 93, 105, 0, 120, 104, 0, 0, 44, - 0, 106, 24, 0, 17, 0, 124, 53, 23, 0, 5, 62, 25, - 99, 0, 0, 126, 112, 60, 125, 57, 28, 55, 0, 94, 0, - 103, 26, 0, 102, 0, 0, 0, 98, 95, 100, 91, 115, 14, - 39, 114, 0, 80, 0, 109, 92, 90, 32, 0, 122, 79, 117, - 86, 46, 83, 0, 0, 97, 40, 59, 110, 0, 36, 0, 0, - 29, 0, 89, 87, 88, 0, 20, 85, 0, 56, + 74, 109, 124, 72, 106, 45, 0, 0, 81, 0, 76, 61, 0, + 42, 12, 77, 15, 0, 123, 84, 54, 118, 125, 19, 0, 0, + 130, 0, 128, 121, 0, 22, 96, 0, 9, 0, 0, 115, 69, + 0, 67, 6, 0, 48, 93, 136, 0, 126, 104, 0, 0, 44, + 0, 107, 24, 0, 17, 0, 131, 53, 23, 0, 5, 62, 132, + 99, 0, 0, 135, 110, 60, 134, 57, 113, 55, 0, 94, 0, + 103, 26, 0, 102, 0, 0, 0, 98, 95, 100, 105, 117, 14, + 39, 116, 0, 80, 0, 133, 114, 92, 59, 0, 129, 79, 119, + 86, 46, 83, 0, 0, 97, 40, 122, 120, 0, 127, 0, 0, + 29, 0, 89, 87, 88, 0, 20, 85, 111, 56, }; /* aKWNext[] forms the hash collision chain. If aKWHash[i]==0 ** then the i-th keyword has no more hash collisions. Otherwise, ** the next keyword with the same hash is aKWHash[i]-1. */ -static const unsigned char aKWNext[126] = { +static const unsigned char aKWNext[136] = { 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 21, 0, 0, 0, 0, 0, 50, - 0, 43, 3, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 43, 3, 47, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 65, 0, 41, 0, 38, 0, 0, 0, - 0, 0, 49, 75, 0, 0, 30, 0, 58, 0, 0, 63, 31, - 52, 16, 34, 10, 0, 0, 0, 0, 0, 0, 0, 11, 70, - 78, 0, 8, 0, 18, 51, 0, 107, 101, 0, 113, 0, 73, - 27, 37, 71, 82, 0, 35, 66, 0, 0, + 0, 0, 49, 75, 0, 0, 30, 0, 58, 0, 0, 0, 31, + 63, 16, 34, 10, 0, 0, 0, 0, 0, 0, 0, 11, 70, + 91, 0, 0, 8, 0, 108, 0, 101, 28, 52, 68, 0, 112, + 0, 73, 51, 0, 90, 27, 37, 0, 71, 36, 82, 0, 35, + 66, 25, 18, 0, 0, 78, }; /* aKWLen[i] is the length (in bytes) of the i-th keyword */ -static const unsigned char aKWLen[126] = { +static const unsigned char aKWLen[136] = { 7, 7, 5, 4, 6, 4, 5, 3, 6, 7, 3, 6, 6, 7, 7, 3, 8, 2, 6, 5, 4, 4, 3, 10, 4, 6, 11, 6, 2, 7, 5, 5, 9, 6, 9, 9, 7, 10, 10, 4, 6, 2, 3, 9, 4, 2, 6, 5, 7, 4, 5, 7, - 6, 6, 5, 6, 5, 5, 9, 7, 7, 4, 2, 7, 3, + 6, 6, 5, 6, 5, 5, 5, 7, 7, 4, 2, 7, 3, 6, 4, 7, 6, 12, 6, 9, 4, 6, 4, 5, 4, 7, - 6, 5, 6, 7, 5, 4, 7, 3, 2, 4, 5, 6, 5, - 7, 3, 7, 13, 2, 2, 4, 6, 6, 8, 5, 17, 12, - 7, 8, 8, 2, 2, 5, 8, 4, 4, 4, 4, 2, 6, - 5, 8, 3, 5, 5, 6, 4, 9, 3, + 6, 5, 6, 7, 5, 4, 7, 3, 2, 4, 5, 9, 5, + 6, 3, 7, 13, 2, 2, 4, 6, 6, 8, 5, 17, 12, + 7, 9, 8, 8, 2, 4, 9, 4, 6, 7, 9, 4, 4, + 2, 6, 5, 8, 4, 5, 8, 4, 3, 9, 5, 5, 6, + 4, 6, 2, 9, 3, 7, }; /* aKWOffset[i] is the index into zKWText[] of the start of ** the text for the i-th keyword. */ -static const unsigned short int aKWOffset[126] = { +static const unsigned short int aKWOffset[136] = { 0, 2, 2, 8, 9, 14, 16, 20, 23, 25, 25, 29, 33, 36, 41, 46, 48, 53, 54, 59, 62, 65, 67, 69, 78, 81, 86, 91, 95, 96, 101, 105, 109, 117, 122, 128, 136, 142, 152, 159, 162, 162, 165, 167, 167, 171, 176, 179, 184, 184, 188, 192, - 199, 204, 209, 212, 218, 221, 225, 234, 240, 246, 249, 251, 252, - 256, 262, 266, 273, 279, 291, 297, 306, 308, 314, 318, 323, 325, - 332, 337, 342, 348, 354, 359, 362, 362, 362, 365, 369, 372, 378, - 382, 389, 391, 398, 400, 402, 411, 415, 421, 427, 435, 440, 440, - 456, 463, 470, 471, 478, 479, 483, 491, 495, 499, 503, 507, 509, - 515, 520, 528, 531, 536, 541, 547, 551, 556, + 199, 204, 209, 212, 218, 221, 225, 230, 236, 242, 245, 247, 248, + 252, 258, 262, 269, 275, 287, 293, 302, 304, 310, 314, 319, 321, + 328, 333, 338, 344, 350, 355, 358, 358, 358, 361, 365, 368, 377, + 381, 387, 389, 396, 398, 400, 409, 413, 419, 425, 433, 438, 438, + 438, 454, 463, 470, 471, 478, 481, 490, 494, 499, 506, 515, 519, + 523, 525, 531, 535, 543, 546, 551, 559, 559, 563, 572, 577, 582, + 588, 591, 594, 597, 602, 606, }; /* aKWCode[i] is the parser symbol code for the i-th keyword */ -static const unsigned char aKWCode[126] = { +static const unsigned char aKWCode[136] = { TK_REINDEX, TK_INDEXED, TK_INDEX, TK_DESC, TK_ESCAPE, TK_EACH, TK_CHECK, TK_KEY, TK_BEFORE, TK_FOREIGN, TK_FOR, TK_IGNORE, TK_LIKE_KW, TK_EXPLAIN, TK_INSTEAD, @@ -145736,21 +150600,23 @@ static const unsigned char aKWCode[126] = { TK_OFFSET, TK_OF, TK_SET, TK_TEMP, TK_TEMP, TK_OR, TK_UNIQUE, TK_QUERY, TK_WITHOUT, TK_WITH, TK_JOIN_KW, TK_RELEASE, TK_ATTACH, TK_HAVING, TK_GROUP, - TK_UPDATE, TK_BEGIN, TK_JOIN_KW, TK_RECURSIVE, TK_BETWEEN, + TK_UPDATE, TK_BEGIN, TK_JOIN_KW, TK_RANGE, TK_BETWEEN, TK_NOTHING, TK_LIKE_KW, TK_BY, TK_CASCADE, TK_ASC, TK_DELETE, TK_CASE, TK_COLLATE, TK_CREATE, TK_CTIME_KW, TK_DETACH, TK_IMMEDIATE, TK_JOIN, TK_INSERT, TK_LIKE_KW, TK_MATCH, TK_PLAN, TK_ANALYZE, TK_PRAGMA, TK_ABORT, TK_VALUES, TK_VIRTUAL, TK_LIMIT, TK_WHEN, TK_NOTNULL, - TK_NOT, TK_NO, TK_NULL, TK_WHERE, TK_RENAME, - TK_AFTER, TK_REPLACE, TK_AND, TK_DEFAULT, TK_AUTOINCR, + TK_NOT, TK_NO, TK_NULL, TK_WHERE, TK_RECURSIVE, + TK_AFTER, TK_RENAME, TK_AND, TK_DEFAULT, TK_AUTOINCR, TK_TO, TK_IN, TK_CAST, TK_COLUMNKW, TK_COMMIT, - TK_CONFLICT, TK_JOIN_KW, TK_CTIME_KW, TK_CTIME_KW, TK_PRIMARY, - TK_DEFERRED, TK_DISTINCT, TK_IS, TK_DO, TK_ORDER, - TK_RESTRICT, TK_DROP, TK_FAIL, TK_FROM, TK_JOIN_KW, - TK_IF, TK_ISNULL, TK_JOIN_KW, TK_ROLLBACK, TK_ROW, - TK_UNION, TK_USING, TK_VACUUM, TK_VIEW, TK_INITIALLY, - TK_ALL, + TK_CONFLICT, TK_JOIN_KW, TK_CTIME_KW, TK_CTIME_KW, TK_CURRENT, + TK_PARTITION, TK_DEFERRED, TK_DISTINCT, TK_IS, TK_DROP, + TK_PRECEDING, TK_FAIL, TK_FILTER, TK_REPLACE, TK_FOLLOWING, + TK_FROM, TK_JOIN_KW, TK_IF, TK_ISNULL, TK_ORDER, + TK_RESTRICT, TK_OVER, TK_JOIN_KW, TK_ROLLBACK, TK_ROWS, + TK_ROW, TK_UNBOUNDED, TK_UNION, TK_USING, TK_VACUUM, + TK_VIEW, TK_WINDOW, TK_DO, TK_INITIALLY, TK_ALL, + TK_PRIMARY, }; /* Check to see if z[0..n-1] is a keyword. If it is, write the ** parser symbol code for that keyword into *pType. Always @@ -145829,7 +150695,7 @@ static int keywordCode(const char *z, int n, int *pType){ testcase( i==55 ); /* UPDATE */ testcase( i==56 ); /* BEGIN */ testcase( i==57 ); /* INNER */ - testcase( i==58 ); /* RECURSIVE */ + testcase( i==58 ); /* RANGE */ testcase( i==59 ); /* BETWEEN */ testcase( i==60 ); /* NOTHING */ testcase( i==61 ); /* GLOB */ @@ -145860,9 +150726,9 @@ static int keywordCode(const char *z, int n, int *pType){ testcase( i==86 ); /* NO */ testcase( i==87 ); /* NULL */ testcase( i==88 ); /* WHERE */ - testcase( i==89 ); /* RENAME */ + testcase( i==89 ); /* RECURSIVE */ testcase( i==90 ); /* AFTER */ - testcase( i==91 ); /* REPLACE */ + testcase( i==91 ); /* RENAME */ testcase( i==92 ); /* AND */ testcase( i==93 ); /* DEFAULT */ testcase( i==94 ); /* AUTOINCREMENT */ @@ -145875,28 +150741,38 @@ static int keywordCode(const char *z, int n, int *pType){ testcase( i==101 ); /* CROSS */ testcase( i==102 ); /* CURRENT_TIMESTAMP */ testcase( i==103 ); /* CURRENT_TIME */ - testcase( i==104 ); /* PRIMARY */ - testcase( i==105 ); /* DEFERRED */ - testcase( i==106 ); /* DISTINCT */ - testcase( i==107 ); /* IS */ - testcase( i==108 ); /* DO */ - testcase( i==109 ); /* ORDER */ - testcase( i==110 ); /* RESTRICT */ - testcase( i==111 ); /* DROP */ - testcase( i==112 ); /* FAIL */ - testcase( i==113 ); /* FROM */ - testcase( i==114 ); /* FULL */ - testcase( i==115 ); /* IF */ - testcase( i==116 ); /* ISNULL */ - testcase( i==117 ); /* RIGHT */ - testcase( i==118 ); /* ROLLBACK */ - testcase( i==119 ); /* ROW */ - testcase( i==120 ); /* UNION */ - testcase( i==121 ); /* USING */ - testcase( i==122 ); /* VACUUM */ - testcase( i==123 ); /* VIEW */ - testcase( i==124 ); /* INITIALLY */ - testcase( i==125 ); /* ALL */ + testcase( i==104 ); /* CURRENT */ + testcase( i==105 ); /* PARTITION */ + testcase( i==106 ); /* DEFERRED */ + testcase( i==107 ); /* DISTINCT */ + testcase( i==108 ); /* IS */ + testcase( i==109 ); /* DROP */ + testcase( i==110 ); /* PRECEDING */ + testcase( i==111 ); /* FAIL */ + testcase( i==112 ); /* FILTER */ + testcase( i==113 ); /* REPLACE */ + testcase( i==114 ); /* FOLLOWING */ + testcase( i==115 ); /* FROM */ + testcase( i==116 ); /* FULL */ + testcase( i==117 ); /* IF */ + testcase( i==118 ); /* ISNULL */ + testcase( i==119 ); /* ORDER */ + testcase( i==120 ); /* RESTRICT */ + testcase( i==121 ); /* OVER */ + testcase( i==122 ); /* RIGHT */ + testcase( i==123 ); /* ROLLBACK */ + testcase( i==124 ); /* ROWS */ + testcase( i==125 ); /* ROW */ + testcase( i==126 ); /* UNBOUNDED */ + testcase( i==127 ); /* UNION */ + testcase( i==128 ); /* USING */ + testcase( i==129 ); /* VACUUM */ + testcase( i==130 ); /* VIEW */ + testcase( i==131 ); /* WINDOW */ + testcase( i==132 ); /* DO */ + testcase( i==133 ); /* INITIALLY */ + testcase( i==134 ); /* ALL */ + testcase( i==135 ); /* PRIMARY */ *pType = aKWCode[i]; break; } @@ -145908,7 +150784,7 @@ SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char *z, int n){ keywordCode((char*)z, n, &id); return id; } -#define SQLITE_N_KEYWORD 126 +#define SQLITE_N_KEYWORD 136 SQLITE_API int sqlite3_keyword_name(int i,const char **pzName,int *pnName){ if( i<0 || i>=SQLITE_N_KEYWORD ) return SQLITE_ERROR; *pzName = zKWText + aKWOffset[i]; @@ -145962,11 +150838,85 @@ SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[] = { #define IdChar(C) (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40])) #endif -/* Make the IdChar function accessible from ctime.c */ -#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS +/* Make the IdChar function accessible from ctime.c and alter.c */ SQLITE_PRIVATE int sqlite3IsIdChar(u8 c){ return IdChar(c); } -#endif +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** Return the id of the next token in string (*pz). Before returning, set +** (*pz) to point to the byte following the parsed token. +*/ +static int getToken(const unsigned char **pz){ + const unsigned char *z = *pz; + int t; /* Token type to return */ + do { + z += sqlite3GetToken(z, &t); + }while( t==TK_SPACE ); + if( t==TK_ID + || t==TK_STRING + || t==TK_JOIN_KW + || t==TK_WINDOW + || t==TK_OVER + || sqlite3ParserFallback(t)==TK_ID + ){ + t = TK_ID; + } + *pz = z; + return t; +} + +/* +** The following three functions are called immediately after the tokenizer +** reads the keywords WINDOW, OVER and FILTER, respectively, to determine +** whether the token should be treated as a keyword or an SQL identifier. +** This cannot be handled by the usual lemon %fallback method, due to +** the ambiguity in some constructions. e.g. +** +** SELECT sum(x) OVER ... +** +** In the above, "OVER" might be a keyword, or it might be an alias for the +** sum(x) expression. If a "%fallback ID OVER" directive were added to +** grammar, then SQLite would always treat "OVER" as an alias, making it +** impossible to call a window-function without a FILTER clause. +** +** WINDOW is treated as a keyword if: +** +** * the following token is an identifier, or a keyword that can fallback +** to being an identifier, and +** * the token after than one is TK_AS. +** +** OVER is a keyword if: +** +** * the previous token was TK_RP, and +** * the next token is either TK_LP or an identifier. +** +** FILTER is a keyword if: +** +** * the previous token was TK_RP, and +** * the next token is TK_LP. +*/ +static int analyzeWindowKeyword(const unsigned char *z){ + int t; + t = getToken(&z); + if( t!=TK_ID ) return TK_ID; + t = getToken(&z); + if( t!=TK_AS ) return TK_ID; + return TK_WINDOW; +} +static int analyzeOverKeyword(const unsigned char *z, int lastToken){ + if( lastToken==TK_RP ){ + int t = getToken(&z); + if( t==TK_LP || t==TK_ID ) return TK_OVER; + } + return TK_ID; +} +static int analyzeFilterKeyword(const unsigned char *z, int lastToken){ + if( lastToken==TK_RP && getToken(&z)==TK_LP ){ + return TK_FILTER; + } + return TK_ID; +} +#endif /* SQLITE_OMIT_WINDOWFUNC */ /* ** Return the length (in bytes) of the token that begins at z[0]. @@ -146235,6 +151185,10 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ i = 1; break; } + case CC_NUL: { + *tokenType = TK_ILLEGAL; + return 0; + } default: { *tokenType = TK_ILLEGAL; return 1; @@ -146288,47 +151242,64 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr assert( pParse->nVar==0 ); assert( pParse->pVList==0 ); while( 1 ){ - if( zSql[0]!=0 ){ - n = sqlite3GetToken((u8*)zSql, &tokenType); - mxSqlLen -= n; - if( mxSqlLen<0 ){ - pParse->rc = SQLITE_TOOBIG; - break; - } - }else{ - /* Upon reaching the end of input, call the parser two more times - ** with tokens TK_SEMI and 0, in that order. */ - if( lastTokenParsed==TK_SEMI ){ - tokenType = 0; - }else if( lastTokenParsed==0 ){ - break; - }else{ - tokenType = TK_SEMI; - } - n = 0; + n = sqlite3GetToken((u8*)zSql, &tokenType); + mxSqlLen -= n; + if( mxSqlLen<0 ){ + pParse->rc = SQLITE_TOOBIG; + break; } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( tokenType>=TK_WINDOW ){ + assert( tokenType==TK_SPACE || tokenType==TK_OVER || tokenType==TK_FILTER + || tokenType==TK_ILLEGAL || tokenType==TK_WINDOW + ); +#else if( tokenType>=TK_SPACE ){ assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL ); +#endif /* SQLITE_OMIT_WINDOWFUNC */ if( db->u1.isInterrupted ){ pParse->rc = SQLITE_INTERRUPT; break; } - if( tokenType==TK_ILLEGAL ){ + if( tokenType==TK_SPACE ){ + zSql += n; + continue; + } + if( zSql[0]==0 ){ + /* Upon reaching the end of input, call the parser two more times + ** with tokens TK_SEMI and 0, in that order. */ + if( lastTokenParsed==TK_SEMI ){ + tokenType = 0; + }else if( lastTokenParsed==0 ){ + break; + }else{ + tokenType = TK_SEMI; + } + n = 0; +#ifndef SQLITE_OMIT_WINDOWFUNC + }else if( tokenType==TK_WINDOW ){ + assert( n==6 ); + tokenType = analyzeWindowKeyword((const u8*)&zSql[6]); + }else if( tokenType==TK_OVER ){ + assert( n==4 ); + tokenType = analyzeOverKeyword((const u8*)&zSql[4], lastTokenParsed); + }else if( tokenType==TK_FILTER ){ + assert( n==6 ); + tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed); +#endif /* SQLITE_OMIT_WINDOWFUNC */ + }else{ sqlite3ErrorMsg(pParse, "unrecognized token: \"%.*s\"", n, zSql); break; } - zSql += n; - }else{ - pParse->sLastToken.z = zSql; - pParse->sLastToken.n = n; - sqlite3Parser(pEngine, tokenType, pParse->sLastToken); - lastTokenParsed = tokenType; - zSql += n; - if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break; } + pParse->sLastToken.z = zSql; + pParse->sLastToken.n = n; + sqlite3Parser(pEngine, tokenType, pParse->sLastToken); + lastTokenParsed = tokenType; + zSql += n; + if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break; } assert( nErr==0 ); - pParse->zTail = zSql; #ifdef YYTRACKMAXSTACKDEPTH sqlite3_mutex_enter(sqlite3MallocMutex()); sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK, @@ -146350,10 +151321,12 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr assert( pzErrMsg!=0 ); if( pParse->zErrMsg ){ *pzErrMsg = pParse->zErrMsg; - sqlite3_log(pParse->rc, "%s", *pzErrMsg); + sqlite3_log(pParse->rc, "%s in \"%s\"", + *pzErrMsg, pParse->zTail); pParse->zErrMsg = 0; nErr++; } + pParse->zTail = zSql; if( pParse->pVdbe && pParse->nErr>0 && pParse->nested==0 ){ sqlite3VdbeDelete(pParse->pVdbe); pParse->pVdbe = 0; @@ -146369,16 +151342,18 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr sqlite3_free(pParse->apVtabLock); #endif - if( !IN_DECLARE_VTAB ){ + if( !IN_SPECIAL_PARSE ){ /* If the pParse->declareVtab flag is set, do not delete any table ** structure built up in pParse->pNewTable. The calling code (see vtab.c) ** will take responsibility for freeing the Table structure. */ sqlite3DeleteTable(db, pParse->pNewTable); } + if( !IN_RENAME_OBJECT ){ + sqlite3DeleteTrigger(db, pParse->pNewTrigger); + } if( pParse->pWithToFree ) sqlite3WithDelete(db, pParse->pWithToFree); - sqlite3DeleteTrigger(db, pParse->pNewTrigger); sqlite3DbFree(db, pParse->pVList); while( pParse->pAinc ){ AutoincInfo *p = pParse->pAinc; @@ -147635,7 +152610,7 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){ db->flags &= ~aFlagOp[i].mask; } if( oldFlags!=db->flags ){ - sqlite3ExpirePreparedStatements(db); + sqlite3ExpirePreparedStatements(db, 0); } if( pRes ){ *pRes = (db->flags & aFlagOp[i].mask)!=0; @@ -147696,6 +152671,15 @@ static int binCollFunc( return rc; } +/* +** Return true if CollSeq is the default built-in BINARY. +*/ +SQLITE_PRIVATE int sqlite3IsBinary(const CollSeq *p){ + assert( p==0 || p->xCmp!=binCollFunc || p->pUser!=0 + || strcmp(p->zName,"BINARY")==0 ); + return p==0 || (p->xCmp==binCollFunc && p->pUser==0); +} + /* ** Another built-in collating sequence: NOCASE. ** @@ -147817,7 +152801,7 @@ static void disconnectAllVtab(sqlite3 *db){ sqlite3BtreeEnterAll(db); for(i=0; inDb; i++){ Schema *pSchema = db->aDb[i].pSchema; - if( db->aDb[i].pSchema ){ + if( pSchema ){ for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){ Table *pTab = (Table *)sqliteHashData(p); if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab); @@ -148077,8 +153061,8 @@ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){ sqlite3VtabRollback(db); sqlite3EndBenignMalloc(); - if( (db->mDbFlags&DBFLAG_SchemaChange)!=0 && db->init.busy==0 ){ - sqlite3ExpirePreparedStatements(db); + if( schemaChange ){ + sqlite3ExpirePreparedStatements(db, 0); sqlite3ResetAllSchemasOfConnection(db); } sqlite3BtreeLeaveAll(db); @@ -148106,6 +153090,7 @@ SQLITE_PRIVATE const char *sqlite3ErrName(int rc){ switch( rc ){ case SQLITE_OK: zName = "SQLITE_OK"; break; case SQLITE_ERROR: zName = "SQLITE_ERROR"; break; + case SQLITE_ERROR_SNAPSHOT: zName = "SQLITE_ERROR_SNAPSHOT"; break; case SQLITE_INTERNAL: zName = "SQLITE_INTERNAL"; break; case SQLITE_PERM: zName = "SQLITE_PERM"; break; case SQLITE_ABORT: zName = "SQLITE_ABORT"; break; @@ -148469,6 +153454,8 @@ SQLITE_PRIVATE int sqlite3CreateFunc( void (*xSFunc)(sqlite3_context*,int,sqlite3_value **), void (*xStep)(sqlite3_context*,int,sqlite3_value **), void (*xFinal)(sqlite3_context*), + void (*xValue)(sqlite3_context*), + void (*xInverse)(sqlite3_context*,int,sqlite3_value **), FuncDestructor *pDestructor ){ FuncDef *p; @@ -148476,12 +153463,14 @@ SQLITE_PRIVATE int sqlite3CreateFunc( int extraFlags; assert( sqlite3_mutex_held(db->mutex) ); - if( zFunctionName==0 || - (xSFunc && (xFinal || xStep)) || - (!xSFunc && (xFinal && !xStep)) || - (!xSFunc && (!xFinal && xStep)) || - (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) || - (255<(nName = sqlite3Strlen30( zFunctionName))) ){ + assert( xValue==0 || xSFunc==0 ); + if( zFunctionName==0 /* Must have a valid name */ + || (xSFunc!=0 && xFinal!=0) /* Not both xSFunc and xFinal */ + || ((xFinal==0)!=(xStep==0)) /* Both or neither of xFinal and xStep */ + || ((xValue==0)!=(xInverse==0)) /* Both or neither of xValue, xInverse */ + || (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) + || (255<(nName = sqlite3Strlen30( zFunctionName))) + ){ return SQLITE_MISUSE_BKPT; } @@ -148502,10 +153491,10 @@ SQLITE_PRIVATE int sqlite3CreateFunc( }else if( enc==SQLITE_ANY ){ int rc; rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8|extraFlags, - pUserData, xSFunc, xStep, xFinal, pDestructor); + pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor); if( rc==SQLITE_OK ){ rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE|extraFlags, - pUserData, xSFunc, xStep, xFinal, pDestructor); + pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor); } if( rc!=SQLITE_OK ){ return rc; @@ -148522,14 +153511,14 @@ SQLITE_PRIVATE int sqlite3CreateFunc( ** operation to continue but invalidate all precompiled statements. */ p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 0); - if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==enc && p->nArg==nArg ){ + if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==(u32)enc && p->nArg==nArg ){ if( db->nVdbeActive ){ sqlite3ErrorWithMsg(db, SQLITE_BUSY, "unable to delete/modify user-function due to active statements"); assert( !db->mallocFailed ); return SQLITE_BUSY; }else{ - sqlite3ExpirePreparedStatements(db); + sqlite3ExpirePreparedStatements(db, 0); } } @@ -148551,38 +153540,32 @@ SQLITE_PRIVATE int sqlite3CreateFunc( testcase( p->funcFlags & SQLITE_DETERMINISTIC ); p->xSFunc = xSFunc ? xSFunc : xStep; p->xFinalize = xFinal; + p->xValue = xValue; + p->xInverse = xInverse; p->pUserData = pUserData; p->nArg = (u16)nArg; return SQLITE_OK; } /* -** Create new user functions. +** Worker function used by utf-8 APIs that create new functions: +** +** sqlite3_create_function() +** sqlite3_create_function_v2() +** sqlite3_create_window_function() */ -SQLITE_API int sqlite3_create_function( +static int createFunctionApi( sqlite3 *db, const char *zFunc, int nArg, int enc, void *p, - void (*xSFunc)(sqlite3_context*,int,sqlite3_value **), - void (*xStep)(sqlite3_context*,int,sqlite3_value **), - void (*xFinal)(sqlite3_context*) -){ - return sqlite3_create_function_v2(db, zFunc, nArg, enc, p, xSFunc, xStep, - xFinal, 0); -} - -SQLITE_API int sqlite3_create_function_v2( - sqlite3 *db, - const char *zFunc, - int nArg, - int enc, - void *p, - void (*xSFunc)(sqlite3_context*,int,sqlite3_value **), - void (*xStep)(sqlite3_context*,int,sqlite3_value **), + void (*xSFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*), - void (*xDestroy)(void *) + void (*xValue)(sqlite3_context*), + void (*xInverse)(sqlite3_context*,int,sqlite3_value**), + void(*xDestroy)(void*) ){ int rc = SQLITE_ERROR; FuncDestructor *pArg = 0; @@ -148604,7 +153587,9 @@ SQLITE_API int sqlite3_create_function_v2( pArg->xDestroy = xDestroy; pArg->pUserData = p; } - rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, xSFunc, xStep, xFinal, pArg); + rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, + xSFunc, xStep, xFinal, xValue, xInverse, pArg + ); if( pArg && pArg->nRef==0 ){ assert( rc!=SQLITE_OK ); xDestroy(p); @@ -148617,6 +153602,52 @@ SQLITE_API int sqlite3_create_function_v2( return rc; } +/* +** Create new user functions. +*/ +SQLITE_API int sqlite3_create_function( + sqlite3 *db, + const char *zFunc, + int nArg, + int enc, + void *p, + void (*xSFunc)(sqlite3_context*,int,sqlite3_value **), + void (*xStep)(sqlite3_context*,int,sqlite3_value **), + void (*xFinal)(sqlite3_context*) +){ + return createFunctionApi(db, zFunc, nArg, enc, p, xSFunc, xStep, + xFinal, 0, 0, 0); +} +SQLITE_API int sqlite3_create_function_v2( + sqlite3 *db, + const char *zFunc, + int nArg, + int enc, + void *p, + void (*xSFunc)(sqlite3_context*,int,sqlite3_value **), + void (*xStep)(sqlite3_context*,int,sqlite3_value **), + void (*xFinal)(sqlite3_context*), + void (*xDestroy)(void *) +){ + return createFunctionApi(db, zFunc, nArg, enc, p, xSFunc, xStep, + xFinal, 0, 0, xDestroy); +} +SQLITE_API int sqlite3_create_window_function( + sqlite3 *db, + const char *zFunc, + int nArg, + int enc, + void *p, + void (*xStep)(sqlite3_context*,int,sqlite3_value **), + void (*xFinal)(sqlite3_context*), + void (*xValue)(sqlite3_context*), + void (*xInverse)(sqlite3_context*,int,sqlite3_value **), + void (*xDestroy)(void *) +){ + return createFunctionApi(db, zFunc, nArg, enc, p, 0, xStep, + xFinal, xValue, xInverse, xDestroy); +} + #ifndef SQLITE_OMIT_UTF16 SQLITE_API int sqlite3_create_function16( sqlite3 *db, @@ -148637,7 +153668,7 @@ SQLITE_API int sqlite3_create_function16( sqlite3_mutex_enter(db->mutex); assert( !db->mallocFailed ); zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE); - rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xSFunc,xStep,xFinal,0); + rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xSFunc,xStep,xFinal,0,0,0); sqlite3DbFree(db, zFunc8); rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); @@ -149262,7 +154293,7 @@ static int createCollation( "unable to delete/modify collation sequence due to active statements"); return SQLITE_BUSY; } - sqlite3ExpirePreparedStatements(db); + sqlite3ExpirePreparedStatements(db, 0); /* If collation sequence pColl was created directly by a call to ** sqlite3_create_collation, and not generated by synthCollSeq(), @@ -149751,6 +154782,7 @@ static int openDatabase( db->nDb = 2; db->magic = SQLITE_MAGIC_BUSY; db->aDb = db->aDbStatic; + db->lookaside.bDisable = 1; assert( sizeof(db->aLimit)==sizeof(aHardLimit) ); memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); @@ -150451,6 +155483,9 @@ SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, vo }else if( op==SQLITE_FCNTL_JOURNAL_POINTER ){ *(sqlite3_file**)pArg = sqlite3PagerJrnlFile(pPager); rc = SQLITE_OK; + }else if( op==SQLITE_FCNTL_DATA_VERSION ){ + *(unsigned int*)pArg = sqlite3PagerDataVersion(pPager); + rc = SQLITE_OK; }else{ rc = sqlite3OsFileControl(fd, op, pArg); } @@ -150714,7 +155749,8 @@ SQLITE_API int sqlite3_test_control(int op, ...){ */ case SQLITE_TESTCTRL_VDBE_COVERAGE: { #ifdef SQLITE_VDBE_COVERAGE - typedef void (*branch_callback)(void*,int,u8,u8); + typedef void (*branch_callback)(void*,unsigned int, + unsigned char,unsigned char); sqlite3GlobalConfig.xVdbeBranch = va_arg(ap,branch_callback); sqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*); #endif @@ -150901,7 +155937,7 @@ SQLITE_API int sqlite3_snapshot_get( if( iDb==0 || iDb>1 ){ Btree *pBt = db->aDb[iDb].pBt; if( 0==sqlite3BtreeIsInTrans(pBt) ){ - rc = sqlite3BtreeBeginTrans(pBt, 0); + rc = sqlite3BtreeBeginTrans(pBt, 0, 0); if( rc==SQLITE_OK ){ rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot); } @@ -150936,11 +155972,29 @@ SQLITE_API int sqlite3_snapshot_open( iDb = sqlite3FindDbName(db, zDb); if( iDb==0 || iDb>1 ){ Btree *pBt = db->aDb[iDb].pBt; - if( 0==sqlite3BtreeIsInReadTrans(pBt) ){ - rc = sqlite3PagerSnapshotOpen(sqlite3BtreePager(pBt), pSnapshot); + if( sqlite3BtreeIsInTrans(pBt)==0 ){ + Pager *pPager = sqlite3BtreePager(pBt); + int bUnlock = 0; + if( sqlite3BtreeIsInReadTrans(pBt) ){ + if( db->nVdbeActive==0 ){ + rc = sqlite3PagerSnapshotCheck(pPager, pSnapshot); + if( rc==SQLITE_OK ){ + bUnlock = 1; + rc = sqlite3BtreeCommit(pBt); + } + } + }else{ + rc = SQLITE_OK; + } if( rc==SQLITE_OK ){ - rc = sqlite3BtreeBeginTrans(pBt, 0); - sqlite3PagerSnapshotOpen(sqlite3BtreePager(pBt), 0); + rc = sqlite3PagerSnapshotOpen(pPager, pSnapshot); + } + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeBeginTrans(pBt, 0, 0); + sqlite3PagerSnapshotOpen(pPager, 0); + } + if( bUnlock ){ + sqlite3PagerSnapshotUnlock(pPager); } } } @@ -150971,7 +156025,7 @@ SQLITE_API int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb){ if( iDb==0 || iDb>1 ){ Btree *pBt = db->aDb[iDb].pBt; if( 0==sqlite3BtreeIsInReadTrans(pBt) ){ - rc = sqlite3BtreeBeginTrans(pBt, 0); + rc = sqlite3BtreeBeginTrans(pBt, 0, 0); if( rc==SQLITE_OK ){ rc = sqlite3PagerSnapshotRecover(sqlite3BtreePager(pBt)); sqlite3BtreeCommit(pBt); @@ -156094,7 +161148,7 @@ static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ int rc = SQLITE_OK; UNUSED_PARAMETER(iSavepoint); assert( ((Fts3Table *)pVtab)->inTransaction ); - assert( ((Fts3Table *)pVtab)->mxSavepoint < iSavepoint ); + assert( ((Fts3Table *)pVtab)->mxSavepoint <= iSavepoint ); TESTONLY( ((Fts3Table *)pVtab)->mxSavepoint = iSavepoint ); if( ((Fts3Table *)pVtab)->bIgnoreSavepoint==0 ){ rc = fts3SyncMethod(pVtab); @@ -170517,6 +175571,2526 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){ #endif /* !defined(SQLITE_DISABLE_FTS3_UNICODE) */ /************** End of fts3_unicode2.c ***************************************/ +/************** Begin file json1.c *******************************************/ +/* +** 2015-08-12 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This SQLite extension implements JSON functions. The interface is +** modeled after MySQL JSON functions: +** +** https://dev.mysql.com/doc/refman/5.7/en/json.html +** +** For the time being, all JSON is stored as pure text. (We might add +** a JSONB type in the future which stores a binary encoding of JSON in +** a BLOB, but there is no support for JSONB in the current implementation. +** This implementation parses JSON text at 250 MB/s, so it is hard to see +** how JSONB might improve on that.) +*/ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1) +#if !defined(SQLITEINT_H) +/* #include "sqlite3ext.h" */ +#endif +SQLITE_EXTENSION_INIT1 +/* #include */ +/* #include */ +/* #include */ +/* #include */ + +/* Mark a function parameter as unused, to suppress nuisance compiler +** warnings. */ +#ifndef UNUSED_PARAM +# define UNUSED_PARAM(X) (void)(X) +#endif + +#ifndef LARGEST_INT64 +# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32)) +# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64) +#endif + +/* +** Versions of isspace(), isalnum() and isdigit() to which it is safe +** to pass signed char values. +*/ +#ifdef sqlite3Isdigit + /* Use the SQLite core versions if this routine is part of the + ** SQLite amalgamation */ +# define safe_isdigit(x) sqlite3Isdigit(x) +# define safe_isalnum(x) sqlite3Isalnum(x) +# define safe_isxdigit(x) sqlite3Isxdigit(x) +#else + /* Use the standard library for separate compilation */ +#include /* amalgamator: keep */ +# define safe_isdigit(x) isdigit((unsigned char)(x)) +# define safe_isalnum(x) isalnum((unsigned char)(x)) +# define safe_isxdigit(x) isxdigit((unsigned char)(x)) +#endif + +/* +** Growing our own isspace() routine this way is twice as fast as +** the library isspace() function, resulting in a 7% overall performance +** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). +*/ +static const char jsonIsSpace[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; +#define safe_isspace(x) (jsonIsSpace[(unsigned char)x]) + +#ifndef SQLITE_AMALGAMATION + /* Unsigned integer types. These are already defined in the sqliteInt.h, + ** but the definitions need to be repeated for separate compilation. */ + typedef sqlite3_uint64 u64; + typedef unsigned int u32; + typedef unsigned short int u16; + typedef unsigned char u8; +#endif + +/* Objects */ +typedef struct JsonString JsonString; +typedef struct JsonNode JsonNode; +typedef struct JsonParse JsonParse; + +/* An instance of this object represents a JSON string +** under construction. Really, this is a generic string accumulator +** that can be and is used to create strings other than JSON. +*/ +struct JsonString { + sqlite3_context *pCtx; /* Function context - put error messages here */ + char *zBuf; /* Append JSON content here */ + u64 nAlloc; /* Bytes of storage available in zBuf[] */ + u64 nUsed; /* Bytes of zBuf[] currently used */ + u8 bStatic; /* True if zBuf is static space */ + u8 bErr; /* True if an error has been encountered */ + char zSpace[100]; /* Initial static space */ +}; + +/* JSON type values +*/ +#define JSON_NULL 0 +#define JSON_TRUE 1 +#define JSON_FALSE 2 +#define JSON_INT 3 +#define JSON_REAL 4 +#define JSON_STRING 5 +#define JSON_ARRAY 6 +#define JSON_OBJECT 7 + +/* The "subtype" set for JSON values */ +#define JSON_SUBTYPE 74 /* Ascii for "J" */ + +/* +** Names of the various JSON types: +*/ +static const char * const jsonType[] = { + "null", "true", "false", "integer", "real", "text", "array", "object" +}; + +/* Bit values for the JsonNode.jnFlag field +*/ +#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */ +#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */ +#define JNODE_REMOVE 0x04 /* Do not output */ +#define JNODE_REPLACE 0x08 /* Replace with JsonNode.u.iReplace */ +#define JNODE_PATCH 0x10 /* Patch with JsonNode.u.pPatch */ +#define JNODE_APPEND 0x20 /* More ARRAY/OBJECT entries at u.iAppend */ +#define JNODE_LABEL 0x40 /* Is a label of an object */ + + +/* A single node of parsed JSON +*/ +struct JsonNode { + u8 eType; /* One of the JSON_ type values */ + u8 jnFlags; /* JNODE flags */ + u32 n; /* Bytes of content, or number of sub-nodes */ + union { + const char *zJContent; /* Content for INT, REAL, and STRING */ + u32 iAppend; /* More terms for ARRAY and OBJECT */ + u32 iKey; /* Key for ARRAY objects in json_tree() */ + u32 iReplace; /* Replacement content for JNODE_REPLACE */ + JsonNode *pPatch; /* Node chain of patch for JNODE_PATCH */ + } u; +}; + +/* A completely parsed JSON string +*/ +struct JsonParse { + u32 nNode; /* Number of slots of aNode[] used */ + u32 nAlloc; /* Number of slots of aNode[] allocated */ + JsonNode *aNode; /* Array of nodes containing the parse */ + const char *zJson; /* Original JSON string */ + u32 *aUp; /* Index of parent of each node */ + u8 oom; /* Set to true if out of memory */ + u8 nErr; /* Number of errors seen */ + u16 iDepth; /* Nesting depth */ + int nJson; /* Length of the zJson string in bytes */ + u32 iHold; /* Replace cache line with the lowest iHold value */ +}; + +/* +** Maximum nesting depth of JSON for this implementation. +** +** This limit is needed to avoid a stack overflow in the recursive +** descent parser. A depth of 2000 is far deeper than any sane JSON +** should go. +*/ +#define JSON_MAX_DEPTH 2000 + +/************************************************************************** +** Utility routines for dealing with JsonString objects +**************************************************************************/ + +/* Set the JsonString object to an empty string +*/ +static void jsonZero(JsonString *p){ + p->zBuf = p->zSpace; + p->nAlloc = sizeof(p->zSpace); + p->nUsed = 0; + p->bStatic = 1; +} + +/* Initialize the JsonString object +*/ +static void jsonInit(JsonString *p, sqlite3_context *pCtx){ + p->pCtx = pCtx; + p->bErr = 0; + jsonZero(p); +} + + +/* Free all allocated memory and reset the JsonString object back to its +** initial state. +*/ +static void jsonReset(JsonString *p){ + if( !p->bStatic ) sqlite3_free(p->zBuf); + jsonZero(p); +} + + +/* Report an out-of-memory (OOM) condition +*/ +static void jsonOom(JsonString *p){ + p->bErr = 1; + sqlite3_result_error_nomem(p->pCtx); + jsonReset(p); +} + +/* Enlarge pJson->zBuf so that it can hold at least N more bytes. +** Return zero on success. Return non-zero on an OOM error +*/ +static int jsonGrow(JsonString *p, u32 N){ + u64 nTotal = NnAlloc ? p->nAlloc*2 : p->nAlloc+N+10; + char *zNew; + if( p->bStatic ){ + if( p->bErr ) return 1; + zNew = sqlite3_malloc64(nTotal); + if( zNew==0 ){ + jsonOom(p); + return SQLITE_NOMEM; + } + memcpy(zNew, p->zBuf, (size_t)p->nUsed); + p->zBuf = zNew; + p->bStatic = 0; + }else{ + zNew = sqlite3_realloc64(p->zBuf, nTotal); + if( zNew==0 ){ + jsonOom(p); + return SQLITE_NOMEM; + } + p->zBuf = zNew; + } + p->nAlloc = nTotal; + return SQLITE_OK; +} + +/* Append N bytes from zIn onto the end of the JsonString string. +*/ +static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){ + if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return; + memcpy(p->zBuf+p->nUsed, zIn, N); + p->nUsed += N; +} + +/* Append formatted text (not to exceed N bytes) to the JsonString. +*/ +static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){ + va_list ap; + if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return; + va_start(ap, zFormat); + sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap); + va_end(ap); + p->nUsed += (int)strlen(p->zBuf+p->nUsed); +} + +/* Append a single character +*/ +static void jsonAppendChar(JsonString *p, char c){ + if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return; + p->zBuf[p->nUsed++] = c; +} + +/* Append a comma separator to the output buffer, if the previous +** character is not '[' or '{'. +*/ +static void jsonAppendSeparator(JsonString *p){ + char c; + if( p->nUsed==0 ) return; + c = p->zBuf[p->nUsed-1]; + if( c!='[' && c!='{' ) jsonAppendChar(p, ','); +} + +/* Append the N-byte string in zIn to the end of the JsonString string +** under construction. Enclose the string in "..." and escape +** any double-quotes or backslash characters contained within the +** string. +*/ +static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ + u32 i; + if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return; + p->zBuf[p->nUsed++] = '"'; + for(i=0; inUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return; + p->zBuf[p->nUsed++] = '\\'; + }else if( c<=0x1f ){ + static const char aSpecial[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + assert( sizeof(aSpecial)==32 ); + assert( aSpecial['\b']=='b' ); + assert( aSpecial['\f']=='f' ); + assert( aSpecial['\n']=='n' ); + assert( aSpecial['\r']=='r' ); + assert( aSpecial['\t']=='t' ); + if( aSpecial[c] ){ + c = aSpecial[c]; + goto json_simple_escape; + } + if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return; + p->zBuf[p->nUsed++] = '\\'; + p->zBuf[p->nUsed++] = 'u'; + p->zBuf[p->nUsed++] = '0'; + p->zBuf[p->nUsed++] = '0'; + p->zBuf[p->nUsed++] = '0' + (c>>4); + c = "0123456789abcdef"[c&0xf]; + } + p->zBuf[p->nUsed++] = c; + } + p->zBuf[p->nUsed++] = '"'; + assert( p->nUsednAlloc ); +} + +/* +** Append a function parameter value to the JSON string under +** construction. +*/ +static void jsonAppendValue( + JsonString *p, /* Append to this JSON string */ + sqlite3_value *pValue /* Value to append */ +){ + switch( sqlite3_value_type(pValue) ){ + case SQLITE_NULL: { + jsonAppendRaw(p, "null", 4); + break; + } + case SQLITE_INTEGER: + case SQLITE_FLOAT: { + const char *z = (const char*)sqlite3_value_text(pValue); + u32 n = (u32)sqlite3_value_bytes(pValue); + jsonAppendRaw(p, z, n); + break; + } + case SQLITE_TEXT: { + const char *z = (const char*)sqlite3_value_text(pValue); + u32 n = (u32)sqlite3_value_bytes(pValue); + if( sqlite3_value_subtype(pValue)==JSON_SUBTYPE ){ + jsonAppendRaw(p, z, n); + }else{ + jsonAppendString(p, z, n); + } + break; + } + default: { + if( p->bErr==0 ){ + sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1); + p->bErr = 2; + jsonReset(p); + } + break; + } + } +} + + +/* Make the JSON in p the result of the SQL function. +*/ +static void jsonResult(JsonString *p){ + if( p->bErr==0 ){ + sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, + p->bStatic ? SQLITE_TRANSIENT : sqlite3_free, + SQLITE_UTF8); + jsonZero(p); + } + assert( p->bStatic ); +} + +/************************************************************************** +** Utility routines for dealing with JsonNode and JsonParse objects +**************************************************************************/ + +/* +** Return the number of consecutive JsonNode slots need to represent +** the parsed JSON at pNode. The minimum answer is 1. For ARRAY and +** OBJECT types, the number might be larger. +** +** Appended elements are not counted. The value returned is the number +** by which the JsonNode counter should increment in order to go to the +** next peer value. +*/ +static u32 jsonNodeSize(JsonNode *pNode){ + return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1; +} + +/* +** Reclaim all memory allocated by a JsonParse object. But do not +** delete the JsonParse object itself. +*/ +static void jsonParseReset(JsonParse *pParse){ + sqlite3_free(pParse->aNode); + pParse->aNode = 0; + pParse->nNode = 0; + pParse->nAlloc = 0; + sqlite3_free(pParse->aUp); + pParse->aUp = 0; +} + +/* +** Free a JsonParse object that was obtained from sqlite3_malloc(). +*/ +static void jsonParseFree(JsonParse *pParse){ + jsonParseReset(pParse); + sqlite3_free(pParse); +} + +/* +** Convert the JsonNode pNode into a pure JSON string and +** append to pOut. Subsubstructure is also included. Return +** the number of JsonNode objects that are encoded. +*/ +static void jsonRenderNode( + JsonNode *pNode, /* The node to render */ + JsonString *pOut, /* Write JSON here */ + sqlite3_value **aReplace /* Replacement values */ +){ + if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){ + if( pNode->jnFlags & JNODE_REPLACE ){ + jsonAppendValue(pOut, aReplace[pNode->u.iReplace]); + return; + } + pNode = pNode->u.pPatch; + } + switch( pNode->eType ){ + default: { + assert( pNode->eType==JSON_NULL ); + jsonAppendRaw(pOut, "null", 4); + break; + } + case JSON_TRUE: { + jsonAppendRaw(pOut, "true", 4); + break; + } + case JSON_FALSE: { + jsonAppendRaw(pOut, "false", 5); + break; + } + case JSON_STRING: { + if( pNode->jnFlags & JNODE_RAW ){ + jsonAppendString(pOut, pNode->u.zJContent, pNode->n); + break; + } + /* Fall through into the next case */ + } + case JSON_REAL: + case JSON_INT: { + jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n); + break; + } + case JSON_ARRAY: { + u32 j = 1; + jsonAppendChar(pOut, '['); + for(;;){ + while( j<=pNode->n ){ + if( (pNode[j].jnFlags & JNODE_REMOVE)==0 ){ + jsonAppendSeparator(pOut); + jsonRenderNode(&pNode[j], pOut, aReplace); + } + j += jsonNodeSize(&pNode[j]); + } + if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; + pNode = &pNode[pNode->u.iAppend]; + j = 1; + } + jsonAppendChar(pOut, ']'); + break; + } + case JSON_OBJECT: { + u32 j = 1; + jsonAppendChar(pOut, '{'); + for(;;){ + while( j<=pNode->n ){ + if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){ + jsonAppendSeparator(pOut); + jsonRenderNode(&pNode[j], pOut, aReplace); + jsonAppendChar(pOut, ':'); + jsonRenderNode(&pNode[j+1], pOut, aReplace); + } + j += 1 + jsonNodeSize(&pNode[j+1]); + } + if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; + pNode = &pNode[pNode->u.iAppend]; + j = 1; + } + jsonAppendChar(pOut, '}'); + break; + } + } +} + +/* +** Return a JsonNode and all its descendents as a JSON string. +*/ +static void jsonReturnJson( + JsonNode *pNode, /* Node to return */ + sqlite3_context *pCtx, /* Return value for this function */ + sqlite3_value **aReplace /* Array of replacement values */ +){ + JsonString s; + jsonInit(&s, pCtx); + jsonRenderNode(pNode, &s, aReplace); + jsonResult(&s); + sqlite3_result_subtype(pCtx, JSON_SUBTYPE); +} + +/* +** Make the JsonNode the return value of the function. +*/ +static void jsonReturn( + JsonNode *pNode, /* Node to return */ + sqlite3_context *pCtx, /* Return value for this function */ + sqlite3_value **aReplace /* Array of replacement values */ +){ + switch( pNode->eType ){ + default: { + assert( pNode->eType==JSON_NULL ); + sqlite3_result_null(pCtx); + break; + } + case JSON_TRUE: { + sqlite3_result_int(pCtx, 1); + break; + } + case JSON_FALSE: { + sqlite3_result_int(pCtx, 0); + break; + } + case JSON_INT: { + sqlite3_int64 i = 0; + const char *z = pNode->u.zJContent; + if( z[0]=='-' ){ z++; } + while( z[0]>='0' && z[0]<='9' ){ + unsigned v = *(z++) - '0'; + if( i>=LARGEST_INT64/10 ){ + if( i>LARGEST_INT64/10 ) goto int_as_real; + if( z[0]>='0' && z[0]<='9' ) goto int_as_real; + if( v==9 ) goto int_as_real; + if( v==8 ){ + if( pNode->u.zJContent[0]=='-' ){ + sqlite3_result_int64(pCtx, SMALLEST_INT64); + goto int_done; + }else{ + goto int_as_real; + } + } + } + i = i*10 + v; + } + if( pNode->u.zJContent[0]=='-' ){ i = -i; } + sqlite3_result_int64(pCtx, i); + int_done: + break; + int_as_real: /* fall through to real */; + } + case JSON_REAL: { + double r; +#ifdef SQLITE_AMALGAMATION + const char *z = pNode->u.zJContent; + sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8); +#else + r = strtod(pNode->u.zJContent, 0); +#endif + sqlite3_result_double(pCtx, r); + break; + } + case JSON_STRING: { +#if 0 /* Never happens because JNODE_RAW is only set by json_set(), + ** json_insert() and json_replace() and those routines do not + ** call jsonReturn() */ + if( pNode->jnFlags & JNODE_RAW ){ + sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n, + SQLITE_TRANSIENT); + }else +#endif + assert( (pNode->jnFlags & JNODE_RAW)==0 ); + if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){ + /* JSON formatted without any backslash-escapes */ + sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2, + SQLITE_TRANSIENT); + }else{ + /* Translate JSON formatted string into raw text */ + u32 i; + u32 n = pNode->n; + const char *z = pNode->u.zJContent; + char *zOut; + u32 j; + zOut = sqlite3_malloc( n+1 ); + if( zOut==0 ){ + sqlite3_result_error_nomem(pCtx); + break; + } + for(i=1, j=0; i>6)); + zOut[j++] = 0x80 | (v&0x3f); + }else{ + zOut[j++] = (char)(0xe0 | (v>>12)); + zOut[j++] = 0x80 | ((v>>6)&0x3f); + zOut[j++] = 0x80 | (v&0x3f); + } + }else{ + if( c=='b' ){ + c = '\b'; + }else if( c=='f' ){ + c = '\f'; + }else if( c=='n' ){ + c = '\n'; + }else if( c=='r' ){ + c = '\r'; + }else if( c=='t' ){ + c = '\t'; + } + zOut[j++] = c; + } + } + } + zOut[j] = 0; + sqlite3_result_text(pCtx, zOut, j, sqlite3_free); + } + break; + } + case JSON_ARRAY: + case JSON_OBJECT: { + jsonReturnJson(pNode, pCtx, aReplace); + break; + } + } +} + +/* Forward reference */ +static int jsonParseAddNode(JsonParse*,u32,u32,const char*); + +/* +** A macro to hint to the compiler that a function should not be +** inlined. +*/ +#if defined(__GNUC__) +# define JSON_NOINLINE __attribute__((noinline)) +#elif defined(_MSC_VER) && _MSC_VER>=1310 +# define JSON_NOINLINE __declspec(noinline) +#else +# define JSON_NOINLINE +#endif + + +static JSON_NOINLINE int jsonParseAddNodeExpand( + JsonParse *pParse, /* Append the node to this object */ + u32 eType, /* Node type */ + u32 n, /* Content size or sub-node count */ + const char *zContent /* Content */ +){ + u32 nNew; + JsonNode *pNew; + assert( pParse->nNode>=pParse->nAlloc ); + if( pParse->oom ) return -1; + nNew = pParse->nAlloc*2 + 10; + pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew); + if( pNew==0 ){ + pParse->oom = 1; + return -1; + } + pParse->nAlloc = nNew; + pParse->aNode = pNew; + assert( pParse->nNodenAlloc ); + return jsonParseAddNode(pParse, eType, n, zContent); +} + +/* +** Create a new JsonNode instance based on the arguments and append that +** instance to the JsonParse. Return the index in pParse->aNode[] of the +** new node, or -1 if a memory allocation fails. +*/ +static int jsonParseAddNode( + JsonParse *pParse, /* Append the node to this object */ + u32 eType, /* Node type */ + u32 n, /* Content size or sub-node count */ + const char *zContent /* Content */ +){ + JsonNode *p; + if( pParse->nNode>=pParse->nAlloc ){ + return jsonParseAddNodeExpand(pParse, eType, n, zContent); + } + p = &pParse->aNode[pParse->nNode]; + p->eType = (u8)eType; + p->jnFlags = 0; + p->n = n; + p->u.zJContent = zContent; + return pParse->nNode++; +} + +/* +** Return true if z[] begins with 4 (or more) hexadecimal digits +*/ +static int jsonIs4Hex(const char *z){ + int i; + for(i=0; i<4; i++) if( !safe_isxdigit(z[i]) ) return 0; + return 1; +} + +/* +** Parse a single JSON value which begins at pParse->zJson[i]. Return the +** index of the first character past the end of the value parsed. +** +** Return negative for a syntax error. Special cases: return -2 if the +** first non-whitespace character is '}' and return -3 if the first +** non-whitespace character is ']'. +*/ +static int jsonParseValue(JsonParse *pParse, u32 i){ + char c; + u32 j; + int iThis; + int x; + JsonNode *pNode; + const char *z = pParse->zJson; + while( safe_isspace(z[i]) ){ i++; } + if( (c = z[i])=='{' ){ + /* Parse object */ + iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); + if( iThis<0 ) return -1; + for(j=i+1;;j++){ + while( safe_isspace(z[j]) ){ j++; } + if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1; + x = jsonParseValue(pParse, j); + if( x<0 ){ + pParse->iDepth--; + if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1; + return -1; + } + if( pParse->oom ) return -1; + pNode = &pParse->aNode[pParse->nNode-1]; + if( pNode->eType!=JSON_STRING ) return -1; + pNode->jnFlags |= JNODE_LABEL; + j = x; + while( safe_isspace(z[j]) ){ j++; } + if( z[j]!=':' ) return -1; + j++; + x = jsonParseValue(pParse, j); + pParse->iDepth--; + if( x<0 ) return -1; + j = x; + while( safe_isspace(z[j]) ){ j++; } + c = z[j]; + if( c==',' ) continue; + if( c!='}' ) return -1; + break; + } + pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; + return j+1; + }else if( c=='[' ){ + /* Parse array */ + iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); + if( iThis<0 ) return -1; + for(j=i+1;;j++){ + while( safe_isspace(z[j]) ){ j++; } + if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1; + x = jsonParseValue(pParse, j); + pParse->iDepth--; + if( x<0 ){ + if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1; + return -1; + } + j = x; + while( safe_isspace(z[j]) ){ j++; } + c = z[j]; + if( c==',' ) continue; + if( c!=']' ) return -1; + break; + } + pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; + return j+1; + }else if( c=='"' ){ + /* Parse string */ + u8 jnFlags = 0; + j = i+1; + for(;;){ + c = z[j]; + if( (c & ~0x1f)==0 ){ + /* Control characters are not allowed in strings */ + return -1; + } + if( c=='\\' ){ + c = z[++j]; + if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f' + || c=='n' || c=='r' || c=='t' + || (c=='u' && jsonIs4Hex(z+j+1)) ){ + jnFlags = JNODE_ESCAPE; + }else{ + return -1; + } + }else if( c=='"' ){ + break; + } + j++; + } + jsonParseAddNode(pParse, JSON_STRING, j+1-i, &z[i]); + if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags; + return j+1; + }else if( c=='n' + && strncmp(z+i,"null",4)==0 + && !safe_isalnum(z[i+4]) ){ + jsonParseAddNode(pParse, JSON_NULL, 0, 0); + return i+4; + }else if( c=='t' + && strncmp(z+i,"true",4)==0 + && !safe_isalnum(z[i+4]) ){ + jsonParseAddNode(pParse, JSON_TRUE, 0, 0); + return i+4; + }else if( c=='f' + && strncmp(z+i,"false",5)==0 + && !safe_isalnum(z[i+5]) ){ + jsonParseAddNode(pParse, JSON_FALSE, 0, 0); + return i+5; + }else if( c=='-' || (c>='0' && c<='9') ){ + /* Parse number */ + u8 seenDP = 0; + u8 seenE = 0; + assert( '-' < '0' ); + if( c<='0' ){ + j = c=='-' ? i+1 : i; + if( z[j]=='0' && z[j+1]>='0' && z[j+1]<='9' ) return -1; + } + j = i+1; + for(;; j++){ + c = z[j]; + if( c>='0' && c<='9' ) continue; + if( c=='.' ){ + if( z[j-1]=='-' ) return -1; + if( seenDP ) return -1; + seenDP = 1; + continue; + } + if( c=='e' || c=='E' ){ + if( z[j-1]<'0' ) return -1; + if( seenE ) return -1; + seenDP = seenE = 1; + c = z[j+1]; + if( c=='+' || c=='-' ){ + j++; + c = z[j+1]; + } + if( c<'0' || c>'9' ) return -1; + continue; + } + break; + } + if( z[j-1]<'0' ) return -1; + jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT, + j - i, &z[i]); + return j; + }else if( c=='}' ){ + return -2; /* End of {...} */ + }else if( c==']' ){ + return -3; /* End of [...] */ + }else if( c==0 ){ + return 0; /* End of file */ + }else{ + return -1; /* Syntax error */ + } +} + +/* +** Parse a complete JSON string. Return 0 on success or non-zero if there +** are any errors. If an error occurs, free all memory associated with +** pParse. +** +** pParse is uninitialized when this routine is called. +*/ +static int jsonParse( + JsonParse *pParse, /* Initialize and fill this JsonParse object */ + sqlite3_context *pCtx, /* Report errors here */ + const char *zJson /* Input JSON text to be parsed */ +){ + int i; + memset(pParse, 0, sizeof(*pParse)); + if( zJson==0 ) return 1; + pParse->zJson = zJson; + i = jsonParseValue(pParse, 0); + if( pParse->oom ) i = -1; + if( i>0 ){ + assert( pParse->iDepth==0 ); + while( safe_isspace(zJson[i]) ) i++; + if( zJson[i] ) i = -1; + } + if( i<=0 ){ + if( pCtx!=0 ){ + if( pParse->oom ){ + sqlite3_result_error_nomem(pCtx); + }else{ + sqlite3_result_error(pCtx, "malformed JSON", -1); + } + } + jsonParseReset(pParse); + return 1; + } + return 0; +} + +/* Mark node i of pParse as being a child of iParent. Call recursively +** to fill in all the descendants of node i. +*/ +static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){ + JsonNode *pNode = &pParse->aNode[i]; + u32 j; + pParse->aUp[i] = iParent; + switch( pNode->eType ){ + case JSON_ARRAY: { + for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){ + jsonParseFillInParentage(pParse, i+j, i); + } + break; + } + case JSON_OBJECT: { + for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){ + pParse->aUp[i+j] = i; + jsonParseFillInParentage(pParse, i+j+1, i); + } + break; + } + default: { + break; + } + } +} + +/* +** Compute the parentage of all nodes in a completed parse. +*/ +static int jsonParseFindParents(JsonParse *pParse){ + u32 *aUp; + assert( pParse->aUp==0 ); + aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode ); + if( aUp==0 ){ + pParse->oom = 1; + return SQLITE_NOMEM; + } + jsonParseFillInParentage(pParse, 0, 0); + return SQLITE_OK; +} + +/* +** Magic number used for the JSON parse cache in sqlite3_get_auxdata() +*/ +#define JSON_CACHE_ID (-429938) /* First cache entry */ +#define JSON_CACHE_SZ 4 /* Max number of cache entries */ + +/* +** Obtain a complete parse of the JSON found in the first argument +** of the argv array. Use the sqlite3_get_auxdata() cache for this +** parse if it is available. If the cache is not available or if it +** is no longer valid, parse the JSON again and return the new parse, +** and also register the new parse so that it will be available for +** future sqlite3_get_auxdata() calls. +*/ +static JsonParse *jsonParseCached( + sqlite3_context *pCtx, + sqlite3_value **argv, + sqlite3_context *pErrCtx +){ + const char *zJson = (const char*)sqlite3_value_text(argv[0]); + int nJson = sqlite3_value_bytes(argv[0]); + JsonParse *p; + JsonParse *pMatch = 0; + int iKey; + int iMinKey = 0; + u32 iMinHold = 0xffffffff; + u32 iMaxHold = 0; + if( zJson==0 ) return 0; + for(iKey=0; iKeynJson==nJson + && memcmp(p->zJson,zJson,nJson)==0 + ){ + p->nErr = 0; + pMatch = p; + }else if( p->iHoldiHold; + iMinKey = iKey; + } + if( p->iHold>iMaxHold ){ + iMaxHold = p->iHold; + } + } + if( pMatch ){ + pMatch->nErr = 0; + pMatch->iHold = iMaxHold+1; + return pMatch; + } + p = sqlite3_malloc( sizeof(*p) + nJson + 1 ); + if( p==0 ){ + sqlite3_result_error_nomem(pCtx); + return 0; + } + memset(p, 0, sizeof(*p)); + p->zJson = (char*)&p[1]; + memcpy((char*)p->zJson, zJson, nJson+1); + if( jsonParse(p, pErrCtx, p->zJson) ){ + sqlite3_free(p); + return 0; + } + p->nJson = nJson; + p->iHold = iMaxHold+1; + sqlite3_set_auxdata(pCtx, JSON_CACHE_ID+iMinKey, p, + (void(*)(void*))jsonParseFree); + return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iMinKey); +} + +/* +** Compare the OBJECT label at pNode against zKey,nKey. Return true on +** a match. +*/ +static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){ + if( pNode->jnFlags & JNODE_RAW ){ + if( pNode->n!=nKey ) return 0; + return strncmp(pNode->u.zJContent, zKey, nKey)==0; + }else{ + if( pNode->n!=nKey+2 ) return 0; + return strncmp(pNode->u.zJContent+1, zKey, nKey)==0; + } +} + +/* forward declaration */ +static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**); + +/* +** Search along zPath to find the node specified. Return a pointer +** to that node, or NULL if zPath is malformed or if there is no such +** node. +** +** If pApnd!=0, then try to append new nodes to complete zPath if it is +** possible to do so and if no existing node corresponds to zPath. If +** new nodes are appended *pApnd is set to 1. +*/ +static JsonNode *jsonLookupStep( + JsonParse *pParse, /* The JSON to search */ + u32 iRoot, /* Begin the search at this node */ + const char *zPath, /* The path to search */ + int *pApnd, /* Append nodes to complete path if not NULL */ + const char **pzErr /* Make *pzErr point to any syntax error in zPath */ +){ + u32 i, j, nKey; + const char *zKey; + JsonNode *pRoot = &pParse->aNode[iRoot]; + if( zPath[0]==0 ) return pRoot; + if( zPath[0]=='.' ){ + if( pRoot->eType!=JSON_OBJECT ) return 0; + zPath++; + if( zPath[0]=='"' ){ + zKey = zPath + 1; + for(i=1; zPath[i] && zPath[i]!='"'; i++){} + nKey = i-1; + if( zPath[i] ){ + i++; + }else{ + *pzErr = zPath; + return 0; + } + }else{ + zKey = zPath; + for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){} + nKey = i; + } + if( nKey==0 ){ + *pzErr = zPath; + return 0; + } + j = 1; + for(;;){ + while( j<=pRoot->n ){ + if( jsonLabelCompare(pRoot+j, zKey, nKey) ){ + return jsonLookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr); + } + j++; + j += jsonNodeSize(&pRoot[j]); + } + if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; + iRoot += pRoot->u.iAppend; + pRoot = &pParse->aNode[iRoot]; + j = 1; + } + if( pApnd ){ + u32 iStart, iLabel; + JsonNode *pNode; + iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0); + iLabel = jsonParseAddNode(pParse, JSON_STRING, i, zPath); + zPath += i; + pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr); + if( pParse->oom ) return 0; + if( pNode ){ + pRoot = &pParse->aNode[iRoot]; + pRoot->u.iAppend = iStart - iRoot; + pRoot->jnFlags |= JNODE_APPEND; + pParse->aNode[iLabel].jnFlags |= JNODE_RAW; + } + return pNode; + } + }else if( zPath[0]=='[' && safe_isdigit(zPath[1]) ){ + if( pRoot->eType!=JSON_ARRAY ) return 0; + i = 0; + j = 1; + while( safe_isdigit(zPath[j]) ){ + i = i*10 + zPath[j] - '0'; + j++; + } + if( zPath[j]!=']' ){ + *pzErr = zPath; + return 0; + } + zPath += j + 1; + j = 1; + for(;;){ + while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){ + if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--; + j += jsonNodeSize(&pRoot[j]); + } + if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; + iRoot += pRoot->u.iAppend; + pRoot = &pParse->aNode[iRoot]; + j = 1; + } + if( j<=pRoot->n ){ + return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr); + } + if( i==0 && pApnd ){ + u32 iStart; + JsonNode *pNode; + iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0); + pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr); + if( pParse->oom ) return 0; + if( pNode ){ + pRoot = &pParse->aNode[iRoot]; + pRoot->u.iAppend = iStart - iRoot; + pRoot->jnFlags |= JNODE_APPEND; + } + return pNode; + } + }else{ + *pzErr = zPath; + } + return 0; +} + +/* +** Append content to pParse that will complete zPath. Return a pointer +** to the inserted node, or return NULL if the append fails. +*/ +static JsonNode *jsonLookupAppend( + JsonParse *pParse, /* Append content to the JSON parse */ + const char *zPath, /* Description of content to append */ + int *pApnd, /* Set this flag to 1 */ + const char **pzErr /* Make this point to any syntax error */ +){ + *pApnd = 1; + if( zPath[0]==0 ){ + jsonParseAddNode(pParse, JSON_NULL, 0, 0); + return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1]; + } + if( zPath[0]=='.' ){ + jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); + }else if( strncmp(zPath,"[0]",3)==0 ){ + jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); + }else{ + return 0; + } + if( pParse->oom ) return 0; + return jsonLookupStep(pParse, pParse->nNode-1, zPath, pApnd, pzErr); +} + +/* +** Return the text of a syntax error message on a JSON path. Space is +** obtained from sqlite3_malloc(). +*/ +static char *jsonPathSyntaxError(const char *zErr){ + return sqlite3_mprintf("JSON path error near '%q'", zErr); +} + +/* +** Do a node lookup using zPath. Return a pointer to the node on success. +** Return NULL if not found or if there is an error. +** +** On an error, write an error message into pCtx and increment the +** pParse->nErr counter. +** +** If pApnd!=NULL then try to append missing nodes and set *pApnd = 1 if +** nodes are appended. +*/ +static JsonNode *jsonLookup( + JsonParse *pParse, /* The JSON to search */ + const char *zPath, /* The path to search */ + int *pApnd, /* Append nodes to complete path if not NULL */ + sqlite3_context *pCtx /* Report errors here, if not NULL */ +){ + const char *zErr = 0; + JsonNode *pNode = 0; + char *zMsg; + + if( zPath==0 ) return 0; + if( zPath[0]!='$' ){ + zErr = zPath; + goto lookup_err; + } + zPath++; + pNode = jsonLookupStep(pParse, 0, zPath, pApnd, &zErr); + if( zErr==0 ) return pNode; + +lookup_err: + pParse->nErr++; + assert( zErr!=0 && pCtx!=0 ); + zMsg = jsonPathSyntaxError(zErr); + if( zMsg ){ + sqlite3_result_error(pCtx, zMsg, -1); + sqlite3_free(zMsg); + }else{ + sqlite3_result_error_nomem(pCtx); + } + return 0; +} + + +/* +** Report the wrong number of arguments for json_insert(), json_replace() +** or json_set(). +*/ +static void jsonWrongNumArgs( + sqlite3_context *pCtx, + const char *zFuncName +){ + char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments", + zFuncName); + sqlite3_result_error(pCtx, zMsg, -1); + sqlite3_free(zMsg); +} + +/* +** Mark all NULL entries in the Object passed in as JNODE_REMOVE. +*/ +static void jsonRemoveAllNulls(JsonNode *pNode){ + int i, n; + assert( pNode->eType==JSON_OBJECT ); + n = pNode->n; + for(i=2; i<=n; i += jsonNodeSize(&pNode[i])+1){ + switch( pNode[i].eType ){ + case JSON_NULL: + pNode[i].jnFlags |= JNODE_REMOVE; + break; + case JSON_OBJECT: + jsonRemoveAllNulls(&pNode[i]); + break; + } + } +} + + +/**************************************************************************** +** SQL functions used for testing and debugging +****************************************************************************/ + +#ifdef SQLITE_DEBUG +/* +** The json_parse(JSON) function returns a string which describes +** a parse of the JSON provided. Or it returns NULL if JSON is not +** well-formed. +*/ +static void jsonParseFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonString s; /* Output string - not real JSON */ + JsonParse x; /* The parse */ + u32 i; + + assert( argc==1 ); + if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; + jsonParseFindParents(&x); + jsonInit(&s, ctx); + for(i=0; inNode ); + if( argc==2 ){ + const char *zPath = (const char*)sqlite3_value_text(argv[1]); + pNode = jsonLookup(p, zPath, 0, ctx); + }else{ + pNode = p->aNode; + } + if( pNode==0 ){ + return; + } + if( pNode->eType==JSON_ARRAY ){ + assert( (pNode->jnFlags & JNODE_APPEND)==0 ); + for(i=1; i<=pNode->n; n++){ + i += jsonNodeSize(&pNode[i]); + } + } + sqlite3_result_int64(ctx, n); +} + +/* +** json_extract(JSON, PATH, ...) +** +** Return the element described by PATH. Return NULL if there is no +** PATH element. If there are multiple PATHs, then return a JSON array +** with the result from each path. Throw an error if the JSON or any PATH +** is malformed. +*/ +static void jsonExtractFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonParse *p; /* The parse */ + JsonNode *pNode; + const char *zPath; + JsonString jx; + int i; + + if( argc<2 ) return; + p = jsonParseCached(ctx, argv, ctx); + if( p==0 ) return; + jsonInit(&jx, ctx); + jsonAppendChar(&jx, '['); + for(i=1; inErr ) break; + if( argc>2 ){ + jsonAppendSeparator(&jx); + if( pNode ){ + jsonRenderNode(pNode, &jx, 0); + }else{ + jsonAppendRaw(&jx, "null", 4); + } + }else if( pNode ){ + jsonReturn(pNode, ctx, 0); + } + } + if( argc>2 && i==argc ){ + jsonAppendChar(&jx, ']'); + jsonResult(&jx); + sqlite3_result_subtype(ctx, JSON_SUBTYPE); + } + jsonReset(&jx); +} + +/* This is the RFC 7396 MergePatch algorithm. +*/ +static JsonNode *jsonMergePatch( + JsonParse *pParse, /* The JSON parser that contains the TARGET */ + u32 iTarget, /* Node of the TARGET in pParse */ + JsonNode *pPatch /* The PATCH */ +){ + u32 i, j; + u32 iRoot; + JsonNode *pTarget; + if( pPatch->eType!=JSON_OBJECT ){ + return pPatch; + } + assert( iTarget>=0 && iTargetnNode ); + pTarget = &pParse->aNode[iTarget]; + assert( (pPatch->jnFlags & JNODE_APPEND)==0 ); + if( pTarget->eType!=JSON_OBJECT ){ + jsonRemoveAllNulls(pPatch); + return pPatch; + } + iRoot = iTarget; + for(i=1; in; i += jsonNodeSize(&pPatch[i+1])+1){ + u32 nKey; + const char *zKey; + assert( pPatch[i].eType==JSON_STRING ); + assert( pPatch[i].jnFlags & JNODE_LABEL ); + nKey = pPatch[i].n; + zKey = pPatch[i].u.zJContent; + assert( (pPatch[i].jnFlags & JNODE_RAW)==0 ); + for(j=1; jn; j += jsonNodeSize(&pTarget[j+1])+1 ){ + assert( pTarget[j].eType==JSON_STRING ); + assert( pTarget[j].jnFlags & JNODE_LABEL ); + assert( (pPatch[i].jnFlags & JNODE_RAW)==0 ); + if( pTarget[j].n==nKey && strncmp(pTarget[j].u.zJContent,zKey,nKey)==0 ){ + if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH) ) break; + if( pPatch[i+1].eType==JSON_NULL ){ + pTarget[j+1].jnFlags |= JNODE_REMOVE; + }else{ + JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]); + if( pNew==0 ) return 0; + pTarget = &pParse->aNode[iTarget]; + if( pNew!=&pTarget[j+1] ){ + pTarget[j+1].u.pPatch = pNew; + pTarget[j+1].jnFlags |= JNODE_PATCH; + } + } + break; + } + } + if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){ + int iStart, iPatch; + iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0); + jsonParseAddNode(pParse, JSON_STRING, nKey, zKey); + iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0); + if( pParse->oom ) return 0; + jsonRemoveAllNulls(pPatch); + pTarget = &pParse->aNode[iTarget]; + pParse->aNode[iRoot].jnFlags |= JNODE_APPEND; + pParse->aNode[iRoot].u.iAppend = iStart - iRoot; + iRoot = iStart; + pParse->aNode[iPatch].jnFlags |= JNODE_PATCH; + pParse->aNode[iPatch].u.pPatch = &pPatch[i+1]; + } + } + return pTarget; +} + +/* +** Implementation of the json_mergepatch(JSON1,JSON2) function. Return a JSON +** object that is the result of running the RFC 7396 MergePatch() algorithm +** on the two arguments. +*/ +static void jsonPatchFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonParse x; /* The JSON that is being patched */ + JsonParse y; /* The patch */ + JsonNode *pResult; /* The result of the merge */ + + UNUSED_PARAM(argc); + if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; + if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){ + jsonParseReset(&x); + return; + } + pResult = jsonMergePatch(&x, 0, y.aNode); + assert( pResult!=0 || x.oom ); + if( pResult ){ + jsonReturnJson(pResult, ctx, 0); + }else{ + sqlite3_result_error_nomem(ctx); + } + jsonParseReset(&x); + jsonParseReset(&y); +} + + +/* +** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON +** object that contains all name/value given in arguments. Or if any name +** is not a string or if any value is a BLOB, throw an error. +*/ +static void jsonObjectFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + int i; + JsonString jx; + const char *z; + u32 n; + + if( argc&1 ){ + sqlite3_result_error(ctx, "json_object() requires an even number " + "of arguments", -1); + return; + } + jsonInit(&jx, ctx); + jsonAppendChar(&jx, '{'); + for(i=0; ijnFlags |= JNODE_REMOVE; + } + if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){ + jsonReturnJson(x.aNode, ctx, 0); + } +remove_done: + jsonParseReset(&x); +} + +/* +** json_replace(JSON, PATH, VALUE, ...) +** +** Replace the value at PATH with VALUE. If PATH does not already exist, +** this routine is a no-op. If JSON or PATH is malformed, throw an error. +*/ +static void jsonReplaceFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonParse x; /* The parse */ + JsonNode *pNode; + const char *zPath; + u32 i; + + if( argc<1 ) return; + if( (argc&1)==0 ) { + jsonWrongNumArgs(ctx, "replace"); + return; + } + if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; + assert( x.nNode ); + for(i=1; i<(u32)argc; i+=2){ + zPath = (const char*)sqlite3_value_text(argv[i]); + pNode = jsonLookup(&x, zPath, 0, ctx); + if( x.nErr ) goto replace_err; + if( pNode ){ + pNode->jnFlags |= (u8)JNODE_REPLACE; + pNode->u.iReplace = i + 1; + } + } + if( x.aNode[0].jnFlags & JNODE_REPLACE ){ + sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); + }else{ + jsonReturnJson(x.aNode, ctx, argv); + } +replace_err: + jsonParseReset(&x); +} + +/* +** json_set(JSON, PATH, VALUE, ...) +** +** Set the value at PATH to VALUE. Create the PATH if it does not already +** exist. Overwrite existing values that do exist. +** If JSON or PATH is malformed, throw an error. +** +** json_insert(JSON, PATH, VALUE, ...) +** +** Create PATH and initialize it to VALUE. If PATH already exists, this +** routine is a no-op. If JSON or PATH is malformed, throw an error. +*/ +static void jsonSetFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonParse x; /* The parse */ + JsonNode *pNode; + const char *zPath; + u32 i; + int bApnd; + int bIsSet = *(int*)sqlite3_user_data(ctx); + + if( argc<1 ) return; + if( (argc&1)==0 ) { + jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert"); + return; + } + if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; + assert( x.nNode ); + for(i=1; i<(u32)argc; i+=2){ + zPath = (const char*)sqlite3_value_text(argv[i]); + bApnd = 0; + pNode = jsonLookup(&x, zPath, &bApnd, ctx); + if( x.oom ){ + sqlite3_result_error_nomem(ctx); + goto jsonSetDone; + }else if( x.nErr ){ + goto jsonSetDone; + }else if( pNode && (bApnd || bIsSet) ){ + pNode->jnFlags |= (u8)JNODE_REPLACE; + pNode->u.iReplace = i + 1; + } + } + if( x.aNode[0].jnFlags & JNODE_REPLACE ){ + sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); + }else{ + jsonReturnJson(x.aNode, ctx, argv); + } +jsonSetDone: + jsonParseReset(&x); +} + +/* +** json_type(JSON) +** json_type(JSON, PATH) +** +** Return the top-level "type" of a JSON string. Throw an error if +** either the JSON or PATH inputs are not well-formed. +*/ +static void jsonTypeFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonParse *p; /* The parse */ + const char *zPath; + JsonNode *pNode; + + p = jsonParseCached(ctx, argv, ctx); + if( p==0 ) return; + if( argc==2 ){ + zPath = (const char*)sqlite3_value_text(argv[1]); + pNode = jsonLookup(p, zPath, 0, ctx); + }else{ + pNode = p->aNode; + } + if( pNode ){ + sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC); + } +} + +/* +** json_valid(JSON) +** +** Return 1 if JSON is a well-formed JSON string according to RFC-7159. +** Return 0 otherwise. +*/ +static void jsonValidFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonParse *p; /* The parse */ + UNUSED_PARAM(argc); + p = jsonParseCached(ctx, argv, 0); + sqlite3_result_int(ctx, p!=0); +} + + +/**************************************************************************** +** Aggregate SQL function implementations +****************************************************************************/ +/* +** json_group_array(VALUE) +** +** Return a JSON array composed of all values in the aggregate. +*/ +static void jsonArrayStep( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonString *pStr; + UNUSED_PARAM(argc); + pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); + if( pStr ){ + if( pStr->zBuf==0 ){ + jsonInit(pStr, ctx); + jsonAppendChar(pStr, '['); + }else{ + jsonAppendChar(pStr, ','); + pStr->pCtx = ctx; + } + jsonAppendValue(pStr, argv[0]); + } +} +static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){ + JsonString *pStr; + pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); + if( pStr ){ + pStr->pCtx = ctx; + jsonAppendChar(pStr, ']'); + if( pStr->bErr ){ + if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); + assert( pStr->bStatic ); + }else if( isFinal ){ + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, + pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); + pStr->bStatic = 1; + }else{ + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); + pStr->nUsed--; + } + }else{ + sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC); + } + sqlite3_result_subtype(ctx, JSON_SUBTYPE); +} +static void jsonArrayValue(sqlite3_context *ctx){ + jsonArrayCompute(ctx, 0); +} +static void jsonArrayFinal(sqlite3_context *ctx){ + jsonArrayCompute(ctx, 1); +} + +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** This method works for both json_group_array() and json_group_object(). +** It works by removing the first element of the group by searching forward +** to the first comma (",") that is not within a string and deleting all +** text through that comma. +*/ +static void jsonGroupInverse( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + int i; + int inStr = 0; + char *z; + JsonString *pStr; + UNUSED_PARAM(argc); + UNUSED_PARAM(argv); + pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); +#ifdef NEVER + /* pStr is always non-NULL since jsonArrayStep() or jsonObjectStep() will + ** always have been called to initalize it */ + if( NEVER(!pStr) ) return; +#endif + z = pStr->zBuf; + for(i=1; z[i]!=',' || inStr; i++){ + assert( inUsed ); + if( z[i]=='"' ){ + inStr = !inStr; + }else if( z[i]=='\\' ){ + i++; + } + } + pStr->nUsed -= i; + memmove(&z[1], &z[i+1], (size_t)pStr->nUsed-1); +} +#else +# define jsonGroupInverse 0 +#endif + + +/* +** json_group_obj(NAME,VALUE) +** +** Return a JSON object composed of all names and values in the aggregate. +*/ +static void jsonObjectStep( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + JsonString *pStr; + const char *z; + u32 n; + UNUSED_PARAM(argc); + pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); + if( pStr ){ + if( pStr->zBuf==0 ){ + jsonInit(pStr, ctx); + jsonAppendChar(pStr, '{'); + }else{ + jsonAppendChar(pStr, ','); + pStr->pCtx = ctx; + } + z = (const char*)sqlite3_value_text(argv[0]); + n = (u32)sqlite3_value_bytes(argv[0]); + jsonAppendString(pStr, z, n); + jsonAppendChar(pStr, ':'); + jsonAppendValue(pStr, argv[1]); + } +} +static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ + JsonString *pStr; + pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); + if( pStr ){ + jsonAppendChar(pStr, '}'); + if( pStr->bErr ){ + if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); + assert( pStr->bStatic ); + }else if( isFinal ){ + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, + pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); + pStr->bStatic = 1; + }else{ + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); + pStr->nUsed--; + } + }else{ + sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC); + } + sqlite3_result_subtype(ctx, JSON_SUBTYPE); +} +static void jsonObjectValue(sqlite3_context *ctx){ + jsonObjectCompute(ctx, 0); +} +static void jsonObjectFinal(sqlite3_context *ctx){ + jsonObjectCompute(ctx, 1); +} + + + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/**************************************************************************** +** The json_each virtual table +****************************************************************************/ +typedef struct JsonEachCursor JsonEachCursor; +struct JsonEachCursor { + sqlite3_vtab_cursor base; /* Base class - must be first */ + u32 iRowid; /* The rowid */ + u32 iBegin; /* The first node of the scan */ + u32 i; /* Index in sParse.aNode[] of current row */ + u32 iEnd; /* EOF when i equals or exceeds this value */ + u8 eType; /* Type of top-level element */ + u8 bRecursive; /* True for json_tree(). False for json_each() */ + char *zJson; /* Input JSON */ + char *zRoot; /* Path by which to filter zJson */ + JsonParse sParse; /* Parse of the input JSON */ +}; + +/* Constructor for the json_each virtual table */ +static int jsonEachConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + sqlite3_vtab *pNew; + int rc; + +/* Column numbers */ +#define JEACH_KEY 0 +#define JEACH_VALUE 1 +#define JEACH_TYPE 2 +#define JEACH_ATOM 3 +#define JEACH_ID 4 +#define JEACH_PARENT 5 +#define JEACH_FULLKEY 6 +#define JEACH_PATH 7 +#define JEACH_JSON 8 +#define JEACH_ROOT 9 + + UNUSED_PARAM(pzErr); + UNUSED_PARAM(argv); + UNUSED_PARAM(argc); + UNUSED_PARAM(pAux); + rc = sqlite3_declare_vtab(db, + "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path," + "json HIDDEN,root HIDDEN)"); + if( rc==SQLITE_OK ){ + pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); + if( pNew==0 ) return SQLITE_NOMEM; + memset(pNew, 0, sizeof(*pNew)); + } + return rc; +} + +/* destructor for json_each virtual table */ +static int jsonEachDisconnect(sqlite3_vtab *pVtab){ + sqlite3_free(pVtab); + return SQLITE_OK; +} + +/* constructor for a JsonEachCursor object for json_each(). */ +static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ + JsonEachCursor *pCur; + + UNUSED_PARAM(p); + pCur = sqlite3_malloc( sizeof(*pCur) ); + if( pCur==0 ) return SQLITE_NOMEM; + memset(pCur, 0, sizeof(*pCur)); + *ppCursor = &pCur->base; + return SQLITE_OK; +} + +/* constructor for a JsonEachCursor object for json_tree(). */ +static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ + int rc = jsonEachOpenEach(p, ppCursor); + if( rc==SQLITE_OK ){ + JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor; + pCur->bRecursive = 1; + } + return rc; +} + +/* Reset a JsonEachCursor back to its original state. Free any memory +** held. */ +static void jsonEachCursorReset(JsonEachCursor *p){ + sqlite3_free(p->zJson); + sqlite3_free(p->zRoot); + jsonParseReset(&p->sParse); + p->iRowid = 0; + p->i = 0; + p->iEnd = 0; + p->eType = 0; + p->zJson = 0; + p->zRoot = 0; +} + +/* Destructor for a jsonEachCursor object */ +static int jsonEachClose(sqlite3_vtab_cursor *cur){ + JsonEachCursor *p = (JsonEachCursor*)cur; + jsonEachCursorReset(p); + sqlite3_free(cur); + return SQLITE_OK; +} + +/* Return TRUE if the jsonEachCursor object has been advanced off the end +** of the JSON object */ +static int jsonEachEof(sqlite3_vtab_cursor *cur){ + JsonEachCursor *p = (JsonEachCursor*)cur; + return p->i >= p->iEnd; +} + +/* Advance the cursor to the next element for json_tree() */ +static int jsonEachNext(sqlite3_vtab_cursor *cur){ + JsonEachCursor *p = (JsonEachCursor*)cur; + if( p->bRecursive ){ + if( p->sParse.aNode[p->i].jnFlags & JNODE_LABEL ) p->i++; + p->i++; + p->iRowid++; + if( p->iiEnd ){ + u32 iUp = p->sParse.aUp[p->i]; + JsonNode *pUp = &p->sParse.aNode[iUp]; + p->eType = pUp->eType; + if( pUp->eType==JSON_ARRAY ){ + if( iUp==p->i-1 ){ + pUp->u.iKey = 0; + }else{ + pUp->u.iKey++; + } + } + } + }else{ + switch( p->eType ){ + case JSON_ARRAY: { + p->i += jsonNodeSize(&p->sParse.aNode[p->i]); + p->iRowid++; + break; + } + case JSON_OBJECT: { + p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]); + p->iRowid++; + break; + } + default: { + p->i = p->iEnd; + break; + } + } + } + return SQLITE_OK; +} + +/* Append the name of the path for element i to pStr +*/ +static void jsonEachComputePath( + JsonEachCursor *p, /* The cursor */ + JsonString *pStr, /* Write the path here */ + u32 i /* Path to this element */ +){ + JsonNode *pNode, *pUp; + u32 iUp; + if( i==0 ){ + jsonAppendChar(pStr, '$'); + return; + } + iUp = p->sParse.aUp[i]; + jsonEachComputePath(p, pStr, iUp); + pNode = &p->sParse.aNode[i]; + pUp = &p->sParse.aNode[iUp]; + if( pUp->eType==JSON_ARRAY ){ + jsonPrintf(30, pStr, "[%d]", pUp->u.iKey); + }else{ + assert( pUp->eType==JSON_OBJECT ); + if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--; + assert( pNode->eType==JSON_STRING ); + assert( pNode->jnFlags & JNODE_LABEL ); + jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1); + } +} + +/* Return the value of a column */ +static int jsonEachColumn( + sqlite3_vtab_cursor *cur, /* The cursor */ + sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ + int i /* Which column to return */ +){ + JsonEachCursor *p = (JsonEachCursor*)cur; + JsonNode *pThis = &p->sParse.aNode[p->i]; + switch( i ){ + case JEACH_KEY: { + if( p->i==0 ) break; + if( p->eType==JSON_OBJECT ){ + jsonReturn(pThis, ctx, 0); + }else if( p->eType==JSON_ARRAY ){ + u32 iKey; + if( p->bRecursive ){ + if( p->iRowid==0 ) break; + iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey; + }else{ + iKey = p->iRowid; + } + sqlite3_result_int64(ctx, (sqlite3_int64)iKey); + } + break; + } + case JEACH_VALUE: { + if( pThis->jnFlags & JNODE_LABEL ) pThis++; + jsonReturn(pThis, ctx, 0); + break; + } + case JEACH_TYPE: { + if( pThis->jnFlags & JNODE_LABEL ) pThis++; + sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC); + break; + } + case JEACH_ATOM: { + if( pThis->jnFlags & JNODE_LABEL ) pThis++; + if( pThis->eType>=JSON_ARRAY ) break; + jsonReturn(pThis, ctx, 0); + break; + } + case JEACH_ID: { + sqlite3_result_int64(ctx, + (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0)); + break; + } + case JEACH_PARENT: { + if( p->i>p->iBegin && p->bRecursive ){ + sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]); + } + break; + } + case JEACH_FULLKEY: { + JsonString x; + jsonInit(&x, ctx); + if( p->bRecursive ){ + jsonEachComputePath(p, &x, p->i); + }else{ + if( p->zRoot ){ + jsonAppendRaw(&x, p->zRoot, (int)strlen(p->zRoot)); + }else{ + jsonAppendChar(&x, '$'); + } + if( p->eType==JSON_ARRAY ){ + jsonPrintf(30, &x, "[%d]", p->iRowid); + }else if( p->eType==JSON_OBJECT ){ + jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1); + } + } + jsonResult(&x); + break; + } + case JEACH_PATH: { + if( p->bRecursive ){ + JsonString x; + jsonInit(&x, ctx); + jsonEachComputePath(p, &x, p->sParse.aUp[p->i]); + jsonResult(&x); + break; + } + /* For json_each() path and root are the same so fall through + ** into the root case */ + } + default: { + const char *zRoot = p->zRoot; + if( zRoot==0 ) zRoot = "$"; + sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC); + break; + } + case JEACH_JSON: { + assert( i==JEACH_JSON ); + sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC); + break; + } + } + return SQLITE_OK; +} + +/* Return the current rowid value */ +static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ + JsonEachCursor *p = (JsonEachCursor*)cur; + *pRowid = p->iRowid; + return SQLITE_OK; +} + +/* The query strategy is to look for an equality constraint on the json +** column. Without such a constraint, the table cannot operate. idxNum is +** 1 if the constraint is found, 3 if the constraint and zRoot are found, +** and 0 otherwise. +*/ +static int jsonEachBestIndex( + sqlite3_vtab *tab, + sqlite3_index_info *pIdxInfo +){ + int i; + int jsonIdx = -1; + int rootIdx = -1; + const struct sqlite3_index_constraint *pConstraint; + + UNUSED_PARAM(tab); + pConstraint = pIdxInfo->aConstraint; + for(i=0; inConstraint; i++, pConstraint++){ + if( pConstraint->usable==0 ) continue; + if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; + switch( pConstraint->iColumn ){ + case JEACH_JSON: jsonIdx = i; break; + case JEACH_ROOT: rootIdx = i; break; + default: /* no-op */ break; + } + } + if( jsonIdx<0 ){ + pIdxInfo->idxNum = 0; + pIdxInfo->estimatedCost = 1e99; + }else{ + pIdxInfo->estimatedCost = 1.0; + pIdxInfo->aConstraintUsage[jsonIdx].argvIndex = 1; + pIdxInfo->aConstraintUsage[jsonIdx].omit = 1; + if( rootIdx<0 ){ + pIdxInfo->idxNum = 1; + }else{ + pIdxInfo->aConstraintUsage[rootIdx].argvIndex = 2; + pIdxInfo->aConstraintUsage[rootIdx].omit = 1; + pIdxInfo->idxNum = 3; + } + } + return SQLITE_OK; +} + +/* Start a search on a new JSON string */ +static int jsonEachFilter( + sqlite3_vtab_cursor *cur, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + JsonEachCursor *p = (JsonEachCursor*)cur; + const char *z; + const char *zRoot = 0; + sqlite3_int64 n; + + UNUSED_PARAM(idxStr); + UNUSED_PARAM(argc); + jsonEachCursorReset(p); + if( idxNum==0 ) return SQLITE_OK; + z = (const char*)sqlite3_value_text(argv[0]); + if( z==0 ) return SQLITE_OK; + n = sqlite3_value_bytes(argv[0]); + p->zJson = sqlite3_malloc64( n+1 ); + if( p->zJson==0 ) return SQLITE_NOMEM; + memcpy(p->zJson, z, (size_t)n+1); + if( jsonParse(&p->sParse, 0, p->zJson) ){ + int rc = SQLITE_NOMEM; + if( p->sParse.oom==0 ){ + sqlite3_free(cur->pVtab->zErrMsg); + cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON"); + if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR; + } + jsonEachCursorReset(p); + return rc; + }else if( p->bRecursive && jsonParseFindParents(&p->sParse) ){ + jsonEachCursorReset(p); + return SQLITE_NOMEM; + }else{ + JsonNode *pNode = 0; + if( idxNum==3 ){ + const char *zErr = 0; + zRoot = (const char*)sqlite3_value_text(argv[1]); + if( zRoot==0 ) return SQLITE_OK; + n = sqlite3_value_bytes(argv[1]); + p->zRoot = sqlite3_malloc64( n+1 ); + if( p->zRoot==0 ) return SQLITE_NOMEM; + memcpy(p->zRoot, zRoot, (size_t)n+1); + if( zRoot[0]!='$' ){ + zErr = zRoot; + }else{ + pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr); + } + if( zErr ){ + sqlite3_free(cur->pVtab->zErrMsg); + cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr); + jsonEachCursorReset(p); + return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; + }else if( pNode==0 ){ + return SQLITE_OK; + } + }else{ + pNode = p->sParse.aNode; + } + p->iBegin = p->i = (int)(pNode - p->sParse.aNode); + p->eType = pNode->eType; + if( p->eType>=JSON_ARRAY ){ + pNode->u.iKey = 0; + p->iEnd = p->i + pNode->n + 1; + if( p->bRecursive ){ + p->eType = p->sParse.aNode[p->sParse.aUp[p->i]].eType; + if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){ + p->i--; + } + }else{ + p->i++; + } + }else{ + p->iEnd = p->i+1; + } + } + return SQLITE_OK; +} + +/* The methods of the json_each virtual table */ +static sqlite3_module jsonEachModule = { + 0, /* iVersion */ + 0, /* xCreate */ + jsonEachConnect, /* xConnect */ + jsonEachBestIndex, /* xBestIndex */ + jsonEachDisconnect, /* xDisconnect */ + 0, /* xDestroy */ + jsonEachOpenEach, /* xOpen - open a cursor */ + jsonEachClose, /* xClose - close a cursor */ + jsonEachFilter, /* xFilter - configure scan constraints */ + jsonEachNext, /* xNext - advance a cursor */ + jsonEachEof, /* xEof - check for end of scan */ + jsonEachColumn, /* xColumn - read data */ + jsonEachRowid, /* xRowid - read data */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0 /* xRollbackTo */ +}; + +/* The methods of the json_tree virtual table. */ +static sqlite3_module jsonTreeModule = { + 0, /* iVersion */ + 0, /* xCreate */ + jsonEachConnect, /* xConnect */ + jsonEachBestIndex, /* xBestIndex */ + jsonEachDisconnect, /* xDisconnect */ + 0, /* xDestroy */ + jsonEachOpenTree, /* xOpen - open a cursor */ + jsonEachClose, /* xClose - close a cursor */ + jsonEachFilter, /* xFilter - configure scan constraints */ + jsonEachNext, /* xNext - advance a cursor */ + jsonEachEof, /* xEof - check for end of scan */ + jsonEachColumn, /* xColumn - read data */ + jsonEachRowid, /* xRowid - read data */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0 /* xRollbackTo */ +}; +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +/**************************************************************************** +** The following routines are the only publically visible identifiers in this +** file. Call the following routines in order to register the various SQL +** functions and the virtual table implemented by this file. +****************************************************************************/ + +SQLITE_PRIVATE int sqlite3Json1Init(sqlite3 *db){ + int rc = SQLITE_OK; + unsigned int i; + static const struct { + const char *zName; + int nArg; + int flag; + void (*xFunc)(sqlite3_context*,int,sqlite3_value**); + } aFunc[] = { + { "json", 1, 0, jsonRemoveFunc }, + { "json_array", -1, 0, jsonArrayFunc }, + { "json_array_length", 1, 0, jsonArrayLengthFunc }, + { "json_array_length", 2, 0, jsonArrayLengthFunc }, + { "json_extract", -1, 0, jsonExtractFunc }, + { "json_insert", -1, 0, jsonSetFunc }, + { "json_object", -1, 0, jsonObjectFunc }, + { "json_patch", 2, 0, jsonPatchFunc }, + { "json_quote", 1, 0, jsonQuoteFunc }, + { "json_remove", -1, 0, jsonRemoveFunc }, + { "json_replace", -1, 0, jsonReplaceFunc }, + { "json_set", -1, 1, jsonSetFunc }, + { "json_type", 1, 0, jsonTypeFunc }, + { "json_type", 2, 0, jsonTypeFunc }, + { "json_valid", 1, 0, jsonValidFunc }, + +#if SQLITE_DEBUG + /* DEBUG and TESTING functions */ + { "json_parse", 1, 0, jsonParseFunc }, + { "json_test1", 1, 0, jsonTest1Func }, +#endif + }; + static const struct { + const char *zName; + int nArg; + void (*xStep)(sqlite3_context*,int,sqlite3_value**); + void (*xFinal)(sqlite3_context*); + void (*xValue)(sqlite3_context*); + } aAgg[] = { + { "json_group_array", 1, + jsonArrayStep, jsonArrayFinal, jsonArrayValue }, + { "json_group_object", 2, + jsonObjectStep, jsonObjectFinal, jsonObjectValue }, + }; +#ifndef SQLITE_OMIT_VIRTUALTABLE + static const struct { + const char *zName; + sqlite3_module *pModule; + } aMod[] = { + { "json_each", &jsonEachModule }, + { "json_tree", &jsonTreeModule }, + }; +#endif + for(i=0; ipWriteRowid, 1); sqlite3_bind_null(pRtree->pWriteRowid, 2); @@ -173700,7 +181275,7 @@ static int rtreeUpdate( /* Figure out the rowid of the new row. */ if( bHaveRowid==0 ){ - rc = newRowid(pRtree, &cell.iRowid); + rc = rtreeNewRowid(pRtree, &cell.iRowid); } *pRowid = cell.iRowid; @@ -173792,7 +181367,7 @@ static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){ */ static int rtreeSavepoint(sqlite3_vtab *pVtab, int iSavepoint){ Rtree *pRtree = (Rtree *)pVtab; - int iwt = pRtree->inWrTrans; + u8 iwt = pRtree->inWrTrans; UNUSED_PARAMETER(iSavepoint); pRtree->inWrTrans = 0; nodeBlobReset(pRtree); @@ -173973,7 +181548,11 @@ static int rtreeSqlInit( sqlite3_str_appendf(p, "UPDATE \"%w\".\"%w_rowid\"SET ", zDb, zPrefix); for(ii=0; iinAux; ii++){ if( ii ) sqlite3_str_append(p, ",", 1); - sqlite3_str_appendf(p,"a%d=?%d",ii,ii+2); + if( iinAuxNotNull ){ + sqlite3_str_appendf(p,"a%d=coalesce(?%d,a%d)",ii,ii+2,ii); + }else{ + sqlite3_str_appendf(p,"a%d=?%d",ii,ii+2); + } } sqlite3_str_appendf(p, " WHERE rowid=?1"); zSql = sqlite3_str_finish(p); @@ -174742,6 +182321,1673 @@ static void rtreecheck( } } +/* Conditionally include the geopoly code */ +#ifdef SQLITE_ENABLE_GEOPOLY +/************** Include geopoly.c in the middle of rtree.c *******************/ +/************** Begin file geopoly.c *****************************************/ +/* +** 2018-05-25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file implements an alternative R-Tree virtual table that +** uses polygons to express the boundaries of 2-dimensional objects. +** +** This file is #include-ed onto the end of "rtree.c" so that it has +** access to all of the R-Tree internals. +*/ +/* #include */ + +/* Enable -DGEOPOLY_ENABLE_DEBUG for debugging facilities */ +#ifdef GEOPOLY_ENABLE_DEBUG + static int geo_debug = 0; +# define GEODEBUG(X) if(geo_debug)printf X +#else +# define GEODEBUG(X) +#endif + +#ifndef JSON_NULL /* The following stuff repeats things found in json1 */ +/* +** Versions of isspace(), isalnum() and isdigit() to which it is safe +** to pass signed char values. +*/ +#ifdef sqlite3Isdigit + /* Use the SQLite core versions if this routine is part of the + ** SQLite amalgamation */ +# define safe_isdigit(x) sqlite3Isdigit(x) +# define safe_isalnum(x) sqlite3Isalnum(x) +# define safe_isxdigit(x) sqlite3Isxdigit(x) +#else + /* Use the standard library for separate compilation */ +#include /* amalgamator: keep */ +# define safe_isdigit(x) isdigit((unsigned char)(x)) +# define safe_isalnum(x) isalnum((unsigned char)(x)) +# define safe_isxdigit(x) isxdigit((unsigned char)(x)) +#endif + +/* +** Growing our own isspace() routine this way is twice as fast as +** the library isspace() function. +*/ +static const char geopolyIsSpace[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; +#define safe_isspace(x) (geopolyIsSpace[(unsigned char)x]) +#endif /* JSON NULL - back to original code */ + +/* Compiler and version */ +#ifndef GCC_VERSION +#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC) +# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__) +#else +# define GCC_VERSION 0 +#endif +#endif +#ifndef MSVC_VERSION +#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC) +# define MSVC_VERSION _MSC_VER +#else +# define MSVC_VERSION 0 +#endif +#endif + +/* Datatype for coordinates +*/ +typedef float GeoCoord; + +/* +** Internal representation of a polygon. +** +** The polygon consists of a sequence of vertexes. There is a line +** segment between each pair of vertexes, and one final segment from +** the last vertex back to the first. (This differs from the GeoJSON +** standard in which the final vertex is a repeat of the first.) +** +** The polygon follows the right-hand rule. The area to the right of +** each segment is "outside" and the area to the left is "inside". +** +** The on-disk representation consists of a 4-byte header followed by +** the values. The 4-byte header is: +** +** encoding (1 byte) 0=big-endian, 1=little-endian +** nvertex (3 bytes) Number of vertexes as a big-endian integer +*/ +typedef struct GeoPoly GeoPoly; +struct GeoPoly { + int nVertex; /* Number of vertexes */ + unsigned char hdr[4]; /* Header for on-disk representation */ + GeoCoord a[2]; /* 2*nVertex values. X (longitude) first, then Y */ +}; + +/* +** State of a parse of a GeoJSON input. +*/ +typedef struct GeoParse GeoParse; +struct GeoParse { + const unsigned char *z; /* Unparsed input */ + int nVertex; /* Number of vertexes in a[] */ + int nAlloc; /* Space allocated to a[] */ + int nErr; /* Number of errors encountered */ + GeoCoord *a; /* Array of vertexes. From sqlite3_malloc64() */ +}; + +/* Do a 4-byte byte swap */ +static void geopolySwab32(unsigned char *a){ + unsigned char t = a[0]; + a[0] = a[3]; + a[3] = t; + t = a[1]; + a[1] = a[2]; + a[2] = t; +} + +/* Skip whitespace. Return the next non-whitespace character. */ +static char geopolySkipSpace(GeoParse *p){ + while( p->z[0] && safe_isspace(p->z[0]) ) p->z++; + return p->z[0]; +} + +/* Parse out a number. Write the value into *pVal if pVal!=0. +** return non-zero on success and zero if the next token is not a number. +*/ +static int geopolyParseNumber(GeoParse *p, GeoCoord *pVal){ + char c = geopolySkipSpace(p); + const unsigned char *z = p->z; + int j = 0; + int seenDP = 0; + int seenE = 0; + if( c=='-' ){ + j = 1; + c = z[j]; + } + if( c=='0' && z[j+1]>='0' && z[j+1]<='9' ) return 0; + for(;; j++){ + c = z[j]; + if( c>='0' && c<='9' ) continue; + if( c=='.' ){ + if( z[j-1]=='-' ) return 0; + if( seenDP ) return 0; + seenDP = 1; + continue; + } + if( c=='e' || c=='E' ){ + if( z[j-1]<'0' ) return 0; + if( seenE ) return -1; + seenDP = seenE = 1; + c = z[j+1]; + if( c=='+' || c=='-' ){ + j++; + c = z[j+1]; + } + if( c<'0' || c>'9' ) return 0; + continue; + } + break; + } + if( z[j-1]<'0' ) return 0; + if( pVal ) *pVal = (GeoCoord)atof((const char*)p->z); + p->z += j; + return 1; +} + +/* +** If the input is a well-formed JSON array of coordinates with at least +** four coordinates and where each coordinate is itself a two-value array, +** then convert the JSON into a GeoPoly object and return a pointer to +** that object. +** +** If any error occurs, return NULL. +*/ +static GeoPoly *geopolyParseJson(const unsigned char *z, int *pRc){ + GeoParse s; + int rc = SQLITE_OK; + memset(&s, 0, sizeof(s)); + s.z = z; + if( geopolySkipSpace(&s)=='[' ){ + s.z++; + while( geopolySkipSpace(&s)=='[' ){ + int ii = 0; + char c; + s.z++; + if( s.nVertex>=s.nAlloc ){ + GeoCoord *aNew; + s.nAlloc = s.nAlloc*2 + 16; + aNew = sqlite3_realloc64(s.a, s.nAlloc*sizeof(GeoCoord)*2 ); + if( aNew==0 ){ + rc = SQLITE_NOMEM; + s.nErr++; + break; + } + s.a = aNew; + } + while( geopolyParseNumber(&s, ii<=1 ? &s.a[s.nVertex*2+ii] : 0) ){ + ii++; + if( ii==2 ) s.nVertex++; + c = geopolySkipSpace(&s); + s.z++; + if( c==',' ) continue; + if( c==']' && ii>=2 ) break; + s.nErr++; + rc = SQLITE_ERROR; + goto parse_json_err; + } + if( geopolySkipSpace(&s)==',' ){ + s.z++; + continue; + } + break; + } + if( geopolySkipSpace(&s)==']' + && s.nVertex>=4 + && s.a[0]==s.a[s.nVertex*2-2] + && s.a[1]==s.a[s.nVertex*2-1] + && (s.z++, geopolySkipSpace(&s)==0) + ){ + int nByte; + GeoPoly *pOut; + int x = 1; + s.nVertex--; /* Remove the redundant vertex at the end */ + nByte = sizeof(GeoPoly) * s.nVertex*2*sizeof(GeoCoord); + pOut = sqlite3_malloc64( nByte ); + x = 1; + if( pOut==0 ) goto parse_json_err; + pOut->nVertex = s.nVertex; + memcpy(pOut->a, s.a, s.nVertex*2*sizeof(GeoCoord)); + pOut->hdr[0] = *(unsigned char*)&x; + pOut->hdr[1] = (s.nVertex>>16)&0xff; + pOut->hdr[2] = (s.nVertex>>8)&0xff; + pOut->hdr[3] = s.nVertex&0xff; + sqlite3_free(s.a); + if( pRc ) *pRc = SQLITE_OK; + return pOut; + }else{ + s.nErr++; + rc = SQLITE_ERROR; + } + } +parse_json_err: + if( pRc ) *pRc = rc; + sqlite3_free(s.a); + return 0; +} + +/* +** Given a function parameter, try to interpret it as a polygon, either +** in the binary format or JSON text. Compute a GeoPoly object and +** return a pointer to that object. Or if the input is not a well-formed +** polygon, put an error message in sqlite3_context and return NULL. +*/ +static GeoPoly *geopolyFuncParam( + sqlite3_context *pCtx, /* Context for error messages */ + sqlite3_value *pVal, /* The value to decode */ + int *pRc /* Write error here */ +){ + GeoPoly *p = 0; + int nByte; + if( sqlite3_value_type(pVal)==SQLITE_BLOB + && (nByte = sqlite3_value_bytes(pVal))>=(4+6*sizeof(GeoCoord)) + ){ + const unsigned char *a = sqlite3_value_blob(pVal); + int nVertex; + nVertex = (a[1]<<16) + (a[2]<<8) + a[3]; + if( (a[0]==0 || a[0]==1) + && (nVertex*2*sizeof(GeoCoord) + 4)==(unsigned int)nByte + ){ + p = sqlite3_malloc64( sizeof(*p) + (nVertex-1)*2*sizeof(GeoCoord) ); + if( p==0 ){ + if( pRc ) *pRc = SQLITE_NOMEM; + if( pCtx ) sqlite3_result_error_nomem(pCtx); + }else{ + int x = 1; + p->nVertex = nVertex; + memcpy(p->hdr, a, nByte); + if( a[0] != *(unsigned char*)&x ){ + int ii; + for(ii=0; iia[ii]); + } + p->hdr[0] ^= 1; + } + } + } + if( pRc ) *pRc = SQLITE_OK; + return p; + }else if( sqlite3_value_type(pVal)==SQLITE_TEXT ){ + const unsigned char *zJson = sqlite3_value_text(pVal); + if( zJson==0 ){ + if( pRc ) *pRc = SQLITE_NOMEM; + return 0; + } + return geopolyParseJson(zJson, pRc); + }else{ + if( pRc ) *pRc = SQLITE_ERROR; + return 0; + } +} + +/* +** Implementation of the geopoly_blob(X) function. +** +** If the input is a well-formed Geopoly BLOB or JSON string +** then return the BLOB representation of the polygon. Otherwise +** return NULL. +*/ +static void geopolyBlobFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p = geopolyFuncParam(context, argv[0], 0); + if( p ){ + sqlite3_result_blob(context, p->hdr, + 4+8*p->nVertex, SQLITE_TRANSIENT); + sqlite3_free(p); + } +} + +/* +** SQL function: geopoly_json(X) +** +** Interpret X as a polygon and render it as a JSON array +** of coordinates. Or, if X is not a valid polygon, return NULL. +*/ +static void geopolyJsonFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p = geopolyFuncParam(context, argv[0], 0); + if( p ){ + sqlite3 *db = sqlite3_context_db_handle(context); + sqlite3_str *x = sqlite3_str_new(db); + int i; + sqlite3_str_append(x, "[", 1); + for(i=0; inVertex; i++){ + sqlite3_str_appendf(x, "[%!g,%!g],", p->a[i*2], p->a[i*2+1]); + } + sqlite3_str_appendf(x, "[%!g,%!g]]", p->a[0], p->a[1]); + sqlite3_result_text(context, sqlite3_str_finish(x), -1, sqlite3_free); + sqlite3_free(p); + } +} + +/* +** SQL function: geopoly_svg(X, ....) +** +** Interpret X as a polygon and render it as a SVG . +** Additional arguments are added as attributes to the . +*/ +static void geopolySvgFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p = geopolyFuncParam(context, argv[0], 0); + if( p ){ + sqlite3 *db = sqlite3_context_db_handle(context); + sqlite3_str *x = sqlite3_str_new(db); + int i; + char cSep = '\''; + sqlite3_str_appendf(x, "a[i*2], p->a[i*2+1]); + cSep = ' '; + } + sqlite3_str_appendf(x, " %g,%g'", p->a[0], p->a[1]); + for(i=1; i"); + sqlite3_result_text(context, sqlite3_str_finish(x), -1, sqlite3_free); + sqlite3_free(p); + } +} + +/* +** SQL Function: geopoly_xform(poly, A, B, C, D, E, F) +** +** Transform and/or translate a polygon as follows: +** +** x1 = A*x0 + B*y0 + E +** y1 = C*x0 + D*y0 + F +** +** For a translation: +** +** geopoly_xform(poly, 1, 0, 0, 1, x-offset, y-offset) +** +** Rotate by R around the point (0,0): +** +** geopoly_xform(poly, cos(R), sin(R), -sin(R), cos(R), 0, 0) +*/ +static void geopolyXformFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p = geopolyFuncParam(context, argv[0], 0); + double A = sqlite3_value_double(argv[1]); + double B = sqlite3_value_double(argv[2]); + double C = sqlite3_value_double(argv[3]); + double D = sqlite3_value_double(argv[4]); + double E = sqlite3_value_double(argv[5]); + double F = sqlite3_value_double(argv[6]); + GeoCoord x1, y1, x0, y0; + int ii; + if( p ){ + for(ii=0; iinVertex; ii++){ + x0 = p->a[ii*2]; + y0 = p->a[ii*2+1]; + x1 = (GeoCoord)(A*x0 + B*y0 + E); + y1 = (GeoCoord)(C*x0 + D*y0 + F); + p->a[ii*2] = x1; + p->a[ii*2+1] = y1; + } + sqlite3_result_blob(context, p->hdr, + 4+8*p->nVertex, SQLITE_TRANSIENT); + sqlite3_free(p); + } +} + +/* +** Implementation of the geopoly_area(X) function. +** +** If the input is a well-formed Geopoly BLOB then return the area +** enclosed by the polygon. If the polygon circulates clockwise instead +** of counterclockwise (as it should) then return the negative of the +** enclosed area. Otherwise return NULL. +*/ +static void geopolyAreaFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p = geopolyFuncParam(context, argv[0], 0); + if( p ){ + double rArea = 0.0; + int ii; + for(ii=0; iinVertex-1; ii++){ + rArea += (p->a[ii*2] - p->a[ii*2+2]) /* (x0 - x1) */ + * (p->a[ii*2+1] + p->a[ii*2+3]) /* (y0 + y1) */ + * 0.5; + } + rArea += (p->a[ii*2] - p->a[0]) /* (xN - x0) */ + * (p->a[ii*2+1] + p->a[1]) /* (yN + y0) */ + * 0.5; + sqlite3_result_double(context, rArea); + sqlite3_free(p); + } +} + +/* +** If pPoly is a polygon, compute its bounding box. Then: +** +** (1) if aCoord!=0 store the bounding box in aCoord, returning NULL +** (2) otherwise, compute a GeoPoly for the bounding box and return the +** new GeoPoly +** +** If pPoly is NULL but aCoord is not NULL, then compute a new GeoPoly from +** the bounding box in aCoord and return a pointer to that GeoPoly. +*/ +static GeoPoly *geopolyBBox( + sqlite3_context *context, /* For recording the error */ + sqlite3_value *pPoly, /* The polygon */ + RtreeCoord *aCoord, /* Results here */ + int *pRc /* Error code here */ +){ + GeoPoly *pOut = 0; + GeoPoly *p; + float mnX, mxX, mnY, mxY; + if( pPoly==0 && aCoord!=0 ){ + p = 0; + mnX = aCoord[0].f; + mxX = aCoord[1].f; + mnY = aCoord[2].f; + mxY = aCoord[3].f; + goto geopolyBboxFill; + }else{ + p = geopolyFuncParam(context, pPoly, pRc); + } + if( p ){ + int ii; + mnX = mxX = p->a[0]; + mnY = mxY = p->a[1]; + for(ii=1; iinVertex; ii++){ + double r = p->a[ii*2]; + if( rmxX ) mxX = (float)r; + r = p->a[ii*2+1]; + if( rmxY ) mxY = (float)r; + } + if( pRc ) *pRc = SQLITE_OK; + if( aCoord==0 ){ + geopolyBboxFill: + pOut = sqlite3_realloc(p, sizeof(GeoPoly)+sizeof(GeoCoord)*6); + if( pOut==0 ){ + sqlite3_free(p); + if( context ) sqlite3_result_error_nomem(context); + if( pRc ) *pRc = SQLITE_NOMEM; + return 0; + } + pOut->nVertex = 4; + ii = 1; + pOut->hdr[0] = *(unsigned char*)ⅈ + pOut->hdr[1] = 0; + pOut->hdr[2] = 0; + pOut->hdr[3] = 4; + pOut->a[0] = mnX; + pOut->a[1] = mnY; + pOut->a[2] = mxX; + pOut->a[3] = mnY; + pOut->a[4] = mxX; + pOut->a[5] = mxY; + pOut->a[6] = mnX; + pOut->a[7] = mxY; + }else{ + sqlite3_free(p); + aCoord[0].f = mnX; + aCoord[1].f = mxX; + aCoord[2].f = mnY; + aCoord[3].f = mxY; + } + } + return pOut; +} + +/* +** Implementation of the geopoly_bbox(X) SQL function. +*/ +static void geopolyBBoxFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p = geopolyBBox(context, argv[0], 0, 0); + if( p ){ + sqlite3_result_blob(context, p->hdr, + 4+8*p->nVertex, SQLITE_TRANSIENT); + sqlite3_free(p); + } +} + +/* +** State vector for the geopoly_group_bbox() aggregate function. +*/ +typedef struct GeoBBox GeoBBox; +struct GeoBBox { + int isInit; + RtreeCoord a[4]; +}; + + +/* +** Implementation of the geopoly_group_bbox(X) aggregate SQL function. +*/ +static void geopolyBBoxStep( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + RtreeCoord a[4]; + int rc = SQLITE_OK; + (void)geopolyBBox(context, argv[0], a, &rc); + if( rc==SQLITE_OK ){ + GeoBBox *pBBox; + pBBox = (GeoBBox*)sqlite3_aggregate_context(context, sizeof(*pBBox)); + if( pBBox==0 ) return; + if( pBBox->isInit==0 ){ + pBBox->isInit = 1; + memcpy(pBBox->a, a, sizeof(RtreeCoord)*4); + }else{ + if( a[0].f < pBBox->a[0].f ) pBBox->a[0] = a[0]; + if( a[1].f > pBBox->a[1].f ) pBBox->a[1] = a[1]; + if( a[2].f < pBBox->a[2].f ) pBBox->a[2] = a[2]; + if( a[3].f > pBBox->a[3].f ) pBBox->a[3] = a[3]; + } + } +} +static void geopolyBBoxFinal( + sqlite3_context *context +){ + GeoPoly *p; + GeoBBox *pBBox; + pBBox = (GeoBBox*)sqlite3_aggregate_context(context, 0); + if( pBBox==0 ) return; + p = geopolyBBox(context, 0, pBBox->a, 0); + if( p ){ + sqlite3_result_blob(context, p->hdr, + 4+8*p->nVertex, SQLITE_TRANSIENT); + sqlite3_free(p); + } +} + + +/* +** Determine if point (x0,y0) is beneath line segment (x1,y1)->(x2,y2). +** Returns: +** +** +2 x0,y0 is on the line segement +** +** +1 x0,y0 is beneath line segment +** +** 0 x0,y0 is not on or beneath the line segment or the line segment +** is vertical and x0,y0 is not on the line segment +** +** The left-most coordinate min(x1,x2) is not considered to be part of +** the line segment for the purposes of this analysis. +*/ +static int pointBeneathLine( + double x0, double y0, + double x1, double y1, + double x2, double y2 +){ + double y; + if( x0==x1 && y0==y1 ) return 2; + if( x1x2 ) return 0; + }else if( x1>x2 ){ + if( x0<=x2 || x0>x1 ) return 0; + }else{ + /* Vertical line segment */ + if( x0!=x1 ) return 0; + if( y0y1 && y0>y2 ) return 0; + return 2; + } + y = y1 + (y2-y1)*(x0-x1)/(x2-x1); + if( y0==y ) return 2; + if( y0nVertex-1; ii++){ + v = pointBeneathLine(x0,y0,p1->a[ii*2],p1->a[ii*2+1], + p1->a[ii*2+2],p1->a[ii*2+3]); + if( v==2 ) break; + cnt += v; + } + if( v!=2 ){ + v = pointBeneathLine(x0,y0,p1->a[ii*2],p1->a[ii*2+1], + p1->a[0],p1->a[1]); + } + if( v==2 ){ + sqlite3_result_int(context, 1); + }else if( ((v+cnt)&1)==0 ){ + sqlite3_result_int(context, 0); + }else{ + sqlite3_result_int(context, 2); + } + sqlite3_free(p1); +} + +/* Forward declaration */ +static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2); + +/* +** SQL function: geopoly_within(P1,P2) +** +** Return +2 if P1 and P2 are the same polygon +** Return +1 if P2 is contained within P1 +** Return 0 if any part of P2 is on the outside of P1 +** +*/ +static void geopolyWithinFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0); + GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0); + if( p1 && p2 ){ + int x = geopolyOverlap(p1, p2); + if( x<0 ){ + sqlite3_result_error_nomem(context); + }else{ + sqlite3_result_int(context, x==2 ? 1 : x==4 ? 2 : 0); + } + } + sqlite3_free(p1); + sqlite3_free(p2); +} + +/* Objects used by the overlap algorihm. */ +typedef struct GeoEvent GeoEvent; +typedef struct GeoSegment GeoSegment; +typedef struct GeoOverlap GeoOverlap; +struct GeoEvent { + double x; /* X coordinate at which event occurs */ + int eType; /* 0 for ADD, 1 for REMOVE */ + GeoSegment *pSeg; /* The segment to be added or removed */ + GeoEvent *pNext; /* Next event in the sorted list */ +}; +struct GeoSegment { + double C, B; /* y = C*x + B */ + double y; /* Current y value */ + float y0; /* Initial y value */ + unsigned char side; /* 1 for p1, 2 for p2 */ + unsigned int idx; /* Which segment within the side */ + GeoSegment *pNext; /* Next segment in a list sorted by y */ +}; +struct GeoOverlap { + GeoEvent *aEvent; /* Array of all events */ + GeoSegment *aSegment; /* Array of all segments */ + int nEvent; /* Number of events */ + int nSegment; /* Number of segments */ +}; + +/* +** Add a single segment and its associated events. +*/ +static void geopolyAddOneSegment( + GeoOverlap *p, + GeoCoord x0, + GeoCoord y0, + GeoCoord x1, + GeoCoord y1, + unsigned char side, + unsigned int idx +){ + GeoSegment *pSeg; + GeoEvent *pEvent; + if( x0==x1 ) return; /* Ignore vertical segments */ + if( x0>x1 ){ + GeoCoord t = x0; + x0 = x1; + x1 = t; + t = y0; + y0 = y1; + y1 = t; + } + pSeg = p->aSegment + p->nSegment; + p->nSegment++; + pSeg->C = (y1-y0)/(x1-x0); + pSeg->B = y1 - x1*pSeg->C; + pSeg->y0 = y0; + pSeg->side = side; + pSeg->idx = idx; + pEvent = p->aEvent + p->nEvent; + p->nEvent++; + pEvent->x = x0; + pEvent->eType = 0; + pEvent->pSeg = pSeg; + pEvent = p->aEvent + p->nEvent; + p->nEvent++; + pEvent->x = x1; + pEvent->eType = 1; + pEvent->pSeg = pSeg; +} + + + +/* +** Insert all segments and events for polygon pPoly. +*/ +static void geopolyAddSegments( + GeoOverlap *p, /* Add segments to this Overlap object */ + GeoPoly *pPoly, /* Take all segments from this polygon */ + unsigned char side /* The side of pPoly */ +){ + unsigned int i; + GeoCoord *x; + for(i=0; i<(unsigned)pPoly->nVertex-1; i++){ + x = pPoly->a + (i*2); + geopolyAddOneSegment(p, x[0], x[1], x[2], x[3], side, i); + } + x = pPoly->a + (i*2); + geopolyAddOneSegment(p, x[0], x[1], pPoly->a[0], pPoly->a[1], side, i); +} + +/* +** Merge two lists of sorted events by X coordinate +*/ +static GeoEvent *geopolyEventMerge(GeoEvent *pLeft, GeoEvent *pRight){ + GeoEvent head, *pLast; + head.pNext = 0; + pLast = &head; + while( pRight && pLeft ){ + if( pRight->x <= pLeft->x ){ + pLast->pNext = pRight; + pLast = pRight; + pRight = pRight->pNext; + }else{ + pLast->pNext = pLeft; + pLast = pLeft; + pLeft = pLeft->pNext; + } + } + pLast->pNext = pRight ? pRight : pLeft; + return head.pNext; +} + +/* +** Sort an array of nEvent event objects into a list. +*/ +static GeoEvent *geopolySortEventsByX(GeoEvent *aEvent, int nEvent){ + int mx = 0; + int i, j; + GeoEvent *p; + GeoEvent *a[50]; + for(i=0; ipNext = 0; + for(j=0; j=mx ) mx = j+1; + } + p = 0; + for(i=0; iy - pLeft->y; + if( r==0.0 ) r = pRight->C - pLeft->C; + if( r<0.0 ){ + pLast->pNext = pRight; + pLast = pRight; + pRight = pRight->pNext; + }else{ + pLast->pNext = pLeft; + pLast = pLeft; + pLeft = pLeft->pNext; + } + } + pLast->pNext = pRight ? pRight : pLeft; + return head.pNext; +} + +/* +** Sort a list of GeoSegments in order of increasing Y and in the event of +** a tie, increasing C (slope). +*/ +static GeoSegment *geopolySortSegmentsByYAndC(GeoSegment *pList){ + int mx = 0; + int i; + GeoSegment *p; + GeoSegment *a[50]; + while( pList ){ + p = pList; + pList = pList->pNext; + p->pNext = 0; + for(i=0; i=mx ) mx = i+1; + } + p = 0; + for(i=0; inVertex + p2->nVertex + 2; + GeoOverlap *p; + int nByte; + GeoEvent *pThisEvent; + double rX; + int rc = 0; + int needSort = 0; + GeoSegment *pActive = 0; + GeoSegment *pSeg; + unsigned char aOverlap[4]; + + nByte = sizeof(GeoEvent)*nVertex*2 + + sizeof(GeoSegment)*nVertex + + sizeof(GeoOverlap); + p = sqlite3_malloc( nByte ); + if( p==0 ) return -1; + p->aEvent = (GeoEvent*)&p[1]; + p->aSegment = (GeoSegment*)&p->aEvent[nVertex*2]; + p->nEvent = p->nSegment = 0; + geopolyAddSegments(p, p1, 1); + geopolyAddSegments(p, p2, 2); + pThisEvent = geopolySortEventsByX(p->aEvent, p->nEvent); + rX = pThisEvent->x==0.0 ? -1.0 : 0.0; + memset(aOverlap, 0, sizeof(aOverlap)); + while( pThisEvent ){ + if( pThisEvent->x!=rX ){ + GeoSegment *pPrev = 0; + int iMask = 0; + GEODEBUG(("Distinct X: %g\n", pThisEvent->x)); + rX = pThisEvent->x; + if( needSort ){ + GEODEBUG(("SORT\n")); + pActive = geopolySortSegmentsByYAndC(pActive); + needSort = 0; + } + for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){ + if( pPrev ){ + if( pPrev->y!=pSeg->y ){ + GEODEBUG(("MASK: %d\n", iMask)); + aOverlap[iMask] = 1; + } + } + iMask ^= pSeg->side; + pPrev = pSeg; + } + pPrev = 0; + for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){ + double y = pSeg->C*rX + pSeg->B; + GEODEBUG(("Segment %d.%d %g->%g\n", pSeg->side, pSeg->idx, pSeg->y, y)); + pSeg->y = y; + if( pPrev ){ + if( pPrev->y>pSeg->y && pPrev->side!=pSeg->side ){ + rc = 1; + GEODEBUG(("Crossing: %d.%d and %d.%d\n", + pPrev->side, pPrev->idx, + pSeg->side, pSeg->idx)); + goto geopolyOverlapDone; + }else if( pPrev->y!=pSeg->y ){ + GEODEBUG(("MASK: %d\n", iMask)); + aOverlap[iMask] = 1; + } + } + iMask ^= pSeg->side; + pPrev = pSeg; + } + } + GEODEBUG(("%s %d.%d C=%g B=%g\n", + pThisEvent->eType ? "RM " : "ADD", + pThisEvent->pSeg->side, pThisEvent->pSeg->idx, + pThisEvent->pSeg->C, + pThisEvent->pSeg->B)); + if( pThisEvent->eType==0 ){ + /* Add a segment */ + pSeg = pThisEvent->pSeg; + pSeg->y = pSeg->y0; + pSeg->pNext = pActive; + pActive = pSeg; + needSort = 1; + }else{ + /* Remove a segment */ + if( pActive==pThisEvent->pSeg ){ + pActive = pActive->pNext; + }else{ + for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){ + if( pSeg->pNext==pThisEvent->pSeg ){ + pSeg->pNext = pSeg->pNext->pNext; + break; + } + } + } + } + pThisEvent = pThisEvent->pNext; + } + if( aOverlap[3]==0 ){ + rc = 0; + }else if( aOverlap[1]!=0 && aOverlap[2]==0 ){ + rc = 3; + }else if( aOverlap[1]==0 && aOverlap[2]!=0 ){ + rc = 2; + }else if( aOverlap[1]==0 && aOverlap[2]==0 ){ + rc = 4; + }else{ + rc = 1; + } + +geopolyOverlapDone: + sqlite3_free(p); + return rc; +} + +/* +** SQL function: geopoly_overlap(P1,P2) +** +** Determine whether or not P1 and P2 overlap. Return value: +** +** 0 The two polygons are disjoint +** 1 They overlap +** 2 P1 is completely contained within P2 +** 3 P2 is completely contained within P1 +** 4 P1 and P2 are the same polygon +** NULL Either P1 or P2 or both are not valid polygons +*/ +static void geopolyOverlapFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0); + GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0); + if( p1 && p2 ){ + int x = geopolyOverlap(p1, p2); + if( x<0 ){ + sqlite3_result_error_nomem(context); + }else{ + sqlite3_result_int(context, x); + } + } + sqlite3_free(p1); + sqlite3_free(p2); +} + +/* +** Enable or disable debugging output +*/ +static void geopolyDebugFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ +#ifdef GEOPOLY_ENABLE_DEBUG + geo_debug = sqlite3_value_int(argv[0]); +#endif +} + +/* +** This function is the implementation of both the xConnect and xCreate +** methods of the geopoly virtual table. +** +** argv[0] -> module name +** argv[1] -> database name +** argv[2] -> table name +** argv[...] -> column names... +*/ +static int geopolyInit( + sqlite3 *db, /* Database connection */ + void *pAux, /* One of the RTREE_COORD_* constants */ + int argc, const char *const*argv, /* Parameters to CREATE TABLE statement */ + sqlite3_vtab **ppVtab, /* OUT: New virtual table */ + char **pzErr, /* OUT: Error message, if any */ + int isCreate /* True for xCreate, false for xConnect */ +){ + int rc = SQLITE_OK; + Rtree *pRtree; + int nDb; /* Length of string argv[1] */ + int nName; /* Length of string argv[2] */ + sqlite3_str *pSql; + char *zSql; + int ii; + + sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); + + /* Allocate the sqlite3_vtab structure */ + nDb = (int)strlen(argv[1]); + nName = (int)strlen(argv[2]); + pRtree = (Rtree *)sqlite3_malloc(sizeof(Rtree)+nDb+nName+2); + if( !pRtree ){ + return SQLITE_NOMEM; + } + memset(pRtree, 0, sizeof(Rtree)+nDb+nName+2); + pRtree->nBusy = 1; + pRtree->base.pModule = &rtreeModule; + pRtree->zDb = (char *)&pRtree[1]; + pRtree->zName = &pRtree->zDb[nDb+1]; + pRtree->eCoordType = RTREE_COORD_REAL32; + pRtree->nDim = 2; + pRtree->nDim2 = 4; + memcpy(pRtree->zDb, argv[1], nDb); + memcpy(pRtree->zName, argv[2], nName); + + + /* Create/Connect to the underlying relational database schema. If + ** that is successful, call sqlite3_declare_vtab() to configure + ** the r-tree table schema. + */ + pSql = sqlite3_str_new(db); + sqlite3_str_appendf(pSql, "CREATE TABLE x(_shape"); + pRtree->nAux = 1; /* Add one for _shape */ + pRtree->nAuxNotNull = 1; /* The _shape column is always not-null */ + for(ii=3; iinAux++; + sqlite3_str_appendf(pSql, ",%s", argv[ii]); + } + sqlite3_str_appendf(pSql, ");"); + zSql = sqlite3_str_finish(pSql); + if( !zSql ){ + rc = SQLITE_NOMEM; + }else if( SQLITE_OK!=(rc = sqlite3_declare_vtab(db, zSql)) ){ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + } + sqlite3_free(zSql); + if( rc ) goto geopolyInit_fail; + pRtree->nBytesPerCell = 8 + pRtree->nDim2*4; + + /* Figure out the node size to use. */ + rc = getNodeSize(db, pRtree, isCreate, pzErr); + if( rc ) goto geopolyInit_fail; + rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate); + if( rc ){ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + goto geopolyInit_fail; + } + + *ppVtab = (sqlite3_vtab *)pRtree; + return SQLITE_OK; + +geopolyInit_fail: + if( rc==SQLITE_OK ) rc = SQLITE_ERROR; + assert( *ppVtab==0 ); + assert( pRtree->nBusy==1 ); + rtreeRelease(pRtree); + return rc; +} + + +/* +** GEOPOLY virtual table module xCreate method. +*/ +static int geopolyCreate( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + return geopolyInit(db, pAux, argc, argv, ppVtab, pzErr, 1); +} + +/* +** GEOPOLY virtual table module xConnect method. +*/ +static int geopolyConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + return geopolyInit(db, pAux, argc, argv, ppVtab, pzErr, 0); +} + + +/* +** GEOPOLY virtual table module xFilter method. +** +** Query plans: +** +** 1 rowid lookup +** 2 search for objects overlapping the same bounding box +** that contains polygon argv[0] +** 3 search for objects overlapping the same bounding box +** that contains polygon argv[0] +** 4 full table scan +*/ +static int geopolyFilter( + sqlite3_vtab_cursor *pVtabCursor, /* The cursor to initialize */ + int idxNum, /* Query plan */ + const char *idxStr, /* Not Used */ + int argc, sqlite3_value **argv /* Parameters to the query plan */ +){ + Rtree *pRtree = (Rtree *)pVtabCursor->pVtab; + RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; + RtreeNode *pRoot = 0; + int rc = SQLITE_OK; + int iCell = 0; + sqlite3_stmt *pStmt; + + rtreeReference(pRtree); + + /* Reset the cursor to the same state as rtreeOpen() leaves it in. */ + freeCursorConstraints(pCsr); + sqlite3_free(pCsr->aPoint); + pStmt = pCsr->pReadAux; + memset(pCsr, 0, sizeof(RtreeCursor)); + pCsr->base.pVtab = (sqlite3_vtab*)pRtree; + pCsr->pReadAux = pStmt; + + pCsr->iStrategy = idxNum; + if( idxNum==1 ){ + /* Special case - lookup by rowid. */ + RtreeNode *pLeaf; /* Leaf on which the required cell resides */ + RtreeSearchPoint *p; /* Search point for the leaf */ + i64 iRowid = sqlite3_value_int64(argv[0]); + i64 iNode = 0; + rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode); + if( rc==SQLITE_OK && pLeaf!=0 ){ + p = rtreeSearchPointNew(pCsr, RTREE_ZERO, 0); + assert( p!=0 ); /* Always returns pCsr->sPoint */ + pCsr->aNode[0] = pLeaf; + p->id = iNode; + p->eWithin = PARTLY_WITHIN; + rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &iCell); + p->iCell = (u8)iCell; + RTREE_QUEUE_TRACE(pCsr, "PUSH-F1:"); + }else{ + pCsr->atEOF = 1; + } + }else{ + /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array + ** with the configured constraints. + */ + rc = nodeAcquire(pRtree, 1, 0, &pRoot); + if( rc==SQLITE_OK && idxNum<=3 ){ + RtreeCoord bbox[4]; + RtreeConstraint *p; + assert( argc==1 ); + geopolyBBox(0, argv[0], bbox, &rc); + if( rc ){ + goto geopoly_filter_end; + } + pCsr->aConstraint = p = sqlite3_malloc(sizeof(RtreeConstraint)*4); + pCsr->nConstraint = 4; + if( p==0 ){ + rc = SQLITE_NOMEM; + }else{ + memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*4); + memset(pCsr->anQueue, 0, sizeof(u32)*(pRtree->iDepth + 1)); + if( idxNum==2 ){ + /* Overlap query */ + p->op = 'B'; + p->iCoord = 0; + p->u.rValue = bbox[1].f; + p++; + p->op = 'D'; + p->iCoord = 1; + p->u.rValue = bbox[0].f; + p++; + p->op = 'B'; + p->iCoord = 2; + p->u.rValue = bbox[3].f; + p++; + p->op = 'D'; + p->iCoord = 3; + p->u.rValue = bbox[2].f; + }else{ + /* Within query */ + p->op = 'D'; + p->iCoord = 0; + p->u.rValue = bbox[0].f; + p++; + p->op = 'B'; + p->iCoord = 1; + p->u.rValue = bbox[1].f; + p++; + p->op = 'D'; + p->iCoord = 2; + p->u.rValue = bbox[2].f; + p++; + p->op = 'B'; + p->iCoord = 3; + p->u.rValue = bbox[3].f; + } + } + } + if( rc==SQLITE_OK ){ + RtreeSearchPoint *pNew; + pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, (u8)(pRtree->iDepth+1)); + if( pNew==0 ){ + rc = SQLITE_NOMEM; + goto geopoly_filter_end; + } + pNew->id = 1; + pNew->iCell = 0; + pNew->eWithin = PARTLY_WITHIN; + assert( pCsr->bPoint==1 ); + pCsr->aNode[0] = pRoot; + pRoot = 0; + RTREE_QUEUE_TRACE(pCsr, "PUSH-Fm:"); + rc = rtreeStepToLeaf(pCsr); + } + } + +geopoly_filter_end: + nodeRelease(pRtree, pRoot); + rtreeRelease(pRtree); + return rc; +} + +/* +** Rtree virtual table module xBestIndex method. There are three +** table scan strategies to choose from (in order from most to +** least desirable): +** +** idxNum idxStr Strategy +** ------------------------------------------------ +** 1 "rowid" Direct lookup by rowid. +** 2 "rtree" R-tree overlap query using geopoly_overlap() +** 3 "rtree" R-tree within query using geopoly_within() +** 4 "fullscan" full-table scan. +** ------------------------------------------------ +*/ +static int geopolyBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ + int ii; + int iRowidTerm = -1; + int iFuncTerm = -1; + int idxNum = 0; + + for(ii=0; iinConstraint; ii++){ + struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii]; + if( !p->usable ) continue; + if( p->iColumn<0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){ + iRowidTerm = ii; + break; + } + if( p->iColumn==0 && p->op>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){ + /* p->op==SQLITE_INDEX_CONSTRAINT_FUNCTION for geopoly_overlap() + ** p->op==(SQLITE_INDEX_CONTRAINT_FUNCTION+1) for geopoly_within(). + ** See geopolyFindFunction() */ + iFuncTerm = ii; + idxNum = p->op - SQLITE_INDEX_CONSTRAINT_FUNCTION + 2; + } + } + + if( iRowidTerm>=0 ){ + pIdxInfo->idxNum = 1; + pIdxInfo->idxStr = "rowid"; + pIdxInfo->aConstraintUsage[iRowidTerm].argvIndex = 1; + pIdxInfo->aConstraintUsage[iRowidTerm].omit = 1; + pIdxInfo->estimatedCost = 30.0; + pIdxInfo->estimatedRows = 1; + pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE; + return SQLITE_OK; + } + if( iFuncTerm>=0 ){ + pIdxInfo->idxNum = idxNum; + pIdxInfo->idxStr = "rtree"; + pIdxInfo->aConstraintUsage[iFuncTerm].argvIndex = 1; + pIdxInfo->aConstraintUsage[iFuncTerm].omit = 0; + pIdxInfo->estimatedCost = 300.0; + pIdxInfo->estimatedRows = 10; + return SQLITE_OK; + } + pIdxInfo->idxNum = 4; + pIdxInfo->idxStr = "fullscan"; + pIdxInfo->estimatedCost = 3000000.0; + pIdxInfo->estimatedRows = 100000; + return SQLITE_OK; +} + + +/* +** GEOPOLY virtual table module xColumn method. +*/ +static int geopolyColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ + Rtree *pRtree = (Rtree *)cur->pVtab; + RtreeCursor *pCsr = (RtreeCursor *)cur; + RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr); + int rc = SQLITE_OK; + RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); + + if( rc ) return rc; + if( p==0 ) return SQLITE_OK; + if( i==0 && sqlite3_vtab_nochange(ctx) ) return SQLITE_OK; + if( i<=pRtree->nAux ){ + if( !pCsr->bAuxValid ){ + if( pCsr->pReadAux==0 ){ + rc = sqlite3_prepare_v3(pRtree->db, pRtree->zReadAuxSql, -1, 0, + &pCsr->pReadAux, 0); + if( rc ) return rc; + } + sqlite3_bind_int64(pCsr->pReadAux, 1, + nodeGetRowid(pRtree, pNode, p->iCell)); + rc = sqlite3_step(pCsr->pReadAux); + if( rc==SQLITE_ROW ){ + pCsr->bAuxValid = 1; + }else{ + sqlite3_reset(pCsr->pReadAux); + if( rc==SQLITE_DONE ) rc = SQLITE_OK; + return rc; + } + } + sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pReadAux, i+2)); + } + return SQLITE_OK; +} + + +/* +** The xUpdate method for GEOPOLY module virtual tables. +** +** For DELETE: +** +** argv[0] = the rowid to be deleted +** +** For INSERT: +** +** argv[0] = SQL NULL +** argv[1] = rowid to insert, or an SQL NULL to select automatically +** argv[2] = _shape column +** argv[3] = first application-defined column.... +** +** For UPDATE: +** +** argv[0] = rowid to modify. Never NULL +** argv[1] = rowid after the change. Never NULL +** argv[2] = new value for _shape +** argv[3] = new value for first application-defined column.... +*/ +static int geopolyUpdate( + sqlite3_vtab *pVtab, + int nData, + sqlite3_value **aData, + sqlite_int64 *pRowid +){ + Rtree *pRtree = (Rtree *)pVtab; + int rc = SQLITE_OK; + RtreeCell cell; /* New cell to insert if nData>1 */ + i64 oldRowid; /* The old rowid */ + int oldRowidValid; /* True if oldRowid is valid */ + i64 newRowid; /* The new rowid */ + int newRowidValid; /* True if newRowid is valid */ + int coordChange = 0; /* Change in coordinates */ + + if( pRtree->nNodeRef ){ + /* Unable to write to the btree while another cursor is reading from it, + ** since the write might do a rebalance which would disrupt the read + ** cursor. */ + return SQLITE_LOCKED_VTAB; + } + rtreeReference(pRtree); + assert(nData>=1); + + oldRowidValid = sqlite3_value_type(aData[0])!=SQLITE_NULL;; + oldRowid = oldRowidValid ? sqlite3_value_int64(aData[0]) : 0; + newRowidValid = nData>1 && sqlite3_value_type(aData[1])!=SQLITE_NULL; + newRowid = newRowidValid ? sqlite3_value_int64(aData[1]) : 0; + cell.iRowid = newRowid; + + if( nData>1 /* not a DELETE */ + && (!oldRowidValid /* INSERT */ + || !sqlite3_value_nochange(aData[2]) /* UPDATE _shape */ + || oldRowid!=newRowid) /* Rowid change */ + ){ + geopolyBBox(0, aData[2], cell.aCoord, &rc); + if( rc ){ + if( rc==SQLITE_ERROR ){ + pVtab->zErrMsg = + sqlite3_mprintf("_shape does not contain a valid polygon"); + } + goto geopoly_update_end; + } + coordChange = 1; + + /* If a rowid value was supplied, check if it is already present in + ** the table. If so, the constraint has failed. */ + if( newRowidValid && (!oldRowidValid || oldRowid!=newRowid) ){ + int steprc; + sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid); + steprc = sqlite3_step(pRtree->pReadRowid); + rc = sqlite3_reset(pRtree->pReadRowid); + if( SQLITE_ROW==steprc ){ + if( sqlite3_vtab_on_conflict(pRtree->db)==SQLITE_REPLACE ){ + rc = rtreeDeleteRowid(pRtree, cell.iRowid); + }else{ + rc = rtreeConstraintError(pRtree, 0); + } + } + } + } + + /* If aData[0] is not an SQL NULL value, it is the rowid of a + ** record to delete from the r-tree table. The following block does + ** just that. + */ + if( rc==SQLITE_OK && (nData==1 || (coordChange && oldRowidValid)) ){ + rc = rtreeDeleteRowid(pRtree, oldRowid); + } + + /* If the aData[] array contains more than one element, elements + ** (aData[2]..aData[argc-1]) contain a new record to insert into + ** the r-tree structure. + */ + if( rc==SQLITE_OK && nData>1 && coordChange ){ + /* Insert the new record into the r-tree */ + RtreeNode *pLeaf = 0; + if( !newRowidValid ){ + rc = rtreeNewRowid(pRtree, &cell.iRowid); + } + *pRowid = cell.iRowid; + if( rc==SQLITE_OK ){ + rc = ChooseLeaf(pRtree, &cell, 0, &pLeaf); + } + if( rc==SQLITE_OK ){ + int rc2; + pRtree->iReinsertHeight = -1; + rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0); + rc2 = nodeRelease(pRtree, pLeaf); + if( rc==SQLITE_OK ){ + rc = rc2; + } + } + } + + /* Change the data */ + if( rc==SQLITE_OK && nData>1 ){ + sqlite3_stmt *pUp = pRtree->pWriteAux; + int jj; + int nChange = 0; + sqlite3_bind_int64(pUp, 1, cell.iRowid); + assert( pRtree->nAux>=1 ); + if( sqlite3_value_nochange(aData[2]) ){ + sqlite3_bind_null(pUp, 2); + }else{ + sqlite3_bind_value(pUp, 2, aData[2]); + nChange = 1; + } + for(jj=1; jjnAux; jj++){ + nChange++; + sqlite3_bind_value(pUp, jj+2, aData[jj+2]); + } + if( nChange ){ + sqlite3_step(pUp); + rc = sqlite3_reset(pUp); + } + } + +geopoly_update_end: + rtreeRelease(pRtree); + return rc; +} + +/* +** Report that geopoly_overlap() is an overloaded function suitable +** for use in xBestIndex. +*/ +static int geopolyFindFunction( + sqlite3_vtab *pVtab, + int nArg, + const char *zName, + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), + void **ppArg +){ + if( sqlite3_stricmp(zName, "geopoly_overlap")==0 ){ + *pxFunc = geopolyOverlapFunc; + *ppArg = 0; + return SQLITE_INDEX_CONSTRAINT_FUNCTION; + } + if( sqlite3_stricmp(zName, "geopoly_within")==0 ){ + *pxFunc = geopolyWithinFunc; + *ppArg = 0; + return SQLITE_INDEX_CONSTRAINT_FUNCTION+1; + } + return 0; +} + + +static sqlite3_module geopolyModule = { + 2, /* iVersion */ + geopolyCreate, /* xCreate - create a table */ + geopolyConnect, /* xConnect - connect to an existing table */ + geopolyBestIndex, /* xBestIndex - Determine search strategy */ + rtreeDisconnect, /* xDisconnect - Disconnect from a table */ + rtreeDestroy, /* xDestroy - Drop a table */ + rtreeOpen, /* xOpen - open a cursor */ + rtreeClose, /* xClose - close a cursor */ + geopolyFilter, /* xFilter - configure scan constraints */ + rtreeNext, /* xNext - advance a cursor */ + rtreeEof, /* xEof */ + geopolyColumn, /* xColumn - read data */ + rtreeRowid, /* xRowid - read data */ + geopolyUpdate, /* xUpdate - write data */ + rtreeBeginTransaction, /* xBegin - begin transaction */ + rtreeEndTransaction, /* xSync - sync transaction */ + rtreeEndTransaction, /* xCommit - commit transaction */ + rtreeEndTransaction, /* xRollback - rollback transaction */ + geopolyFindFunction, /* xFindFunction - function overloading */ + rtreeRename, /* xRename - rename the table */ + rtreeSavepoint, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ +}; + +static int sqlite3_geopoly_init(sqlite3 *db){ + int rc = SQLITE_OK; + static const struct { + void (*xFunc)(sqlite3_context*,int,sqlite3_value**); + int nArg; + const char *zName; + } aFunc[] = { + { geopolyAreaFunc, 1, "geopoly_area" }, + { geopolyBlobFunc, 1, "geopoly_blob" }, + { geopolyJsonFunc, 1, "geopoly_json" }, + { geopolySvgFunc, -1, "geopoly_svg" }, + { geopolyWithinFunc, 2, "geopoly_within" }, + { geopolyContainsPointFunc, 3, "geopoly_contains_point" }, + { geopolyOverlapFunc, 2, "geopoly_overlap" }, + { geopolyDebugFunc, 1, "geopoly_debug" }, + { geopolyBBoxFunc, 1, "geopoly_bbox" }, + { geopolyXformFunc, 7, "geopoly_xform" }, + }; + static const struct { + void (*xStep)(sqlite3_context*,int,sqlite3_value**); + void (*xFinal)(sqlite3_context*); + const char *zName; + } aAgg[] = { + { geopolyBBoxStep, geopolyBBoxFinal, "geopoly_group_bbox" }, + }; + int i; + for(i=0; inDb; i++){ Btree *pBt = db->aDb[i].pBt; - if( pBt ) sqlite3BtreeBeginTrans(pBt, 1); + if( pBt ) sqlite3BtreeBeginTrans(pBt, 1, 0); } return SQLITE_OK; } @@ -187733,2436 +196984,6 @@ SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p){ #endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */ /************** End of sqlite3session.c **************************************/ -/************** Begin file json1.c *******************************************/ -/* -** 2015-08-12 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This SQLite extension implements JSON functions. The interface is -** modeled after MySQL JSON functions: -** -** https://dev.mysql.com/doc/refman/5.7/en/json.html -** -** For the time being, all JSON is stored as pure text. (We might add -** a JSONB type in the future which stores a binary encoding of JSON in -** a BLOB, but there is no support for JSONB in the current implementation. -** This implementation parses JSON text at 250 MB/s, so it is hard to see -** how JSONB might improve on that.) -*/ -#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1) -#if !defined(SQLITEINT_H) -/* #include "sqlite3ext.h" */ -#endif -SQLITE_EXTENSION_INIT1 -/* #include */ -/* #include */ -/* #include */ -/* #include */ - -/* Mark a function parameter as unused, to suppress nuisance compiler -** warnings. */ -#ifndef UNUSED_PARAM -# define UNUSED_PARAM(X) (void)(X) -#endif - -#ifndef LARGEST_INT64 -# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32)) -# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64) -#endif - -/* -** Versions of isspace(), isalnum() and isdigit() to which it is safe -** to pass signed char values. -*/ -#ifdef sqlite3Isdigit - /* Use the SQLite core versions if this routine is part of the - ** SQLite amalgamation */ -# define safe_isdigit(x) sqlite3Isdigit(x) -# define safe_isalnum(x) sqlite3Isalnum(x) -# define safe_isxdigit(x) sqlite3Isxdigit(x) -#else - /* Use the standard library for separate compilation */ -#include /* amalgamator: keep */ -# define safe_isdigit(x) isdigit((unsigned char)(x)) -# define safe_isalnum(x) isalnum((unsigned char)(x)) -# define safe_isxdigit(x) isxdigit((unsigned char)(x)) -#endif - -/* -** Growing our own isspace() routine this way is twice as fast as -** the library isspace() function, resulting in a 7% overall performance -** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). -*/ -static const char jsonIsSpace[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; -#define safe_isspace(x) (jsonIsSpace[(unsigned char)x]) - -#ifndef SQLITE_AMALGAMATION - /* Unsigned integer types. These are already defined in the sqliteInt.h, - ** but the definitions need to be repeated for separate compilation. */ - typedef sqlite3_uint64 u64; - typedef unsigned int u32; - typedef unsigned short int u16; - typedef unsigned char u8; -#endif - -/* Objects */ -typedef struct JsonString JsonString; -typedef struct JsonNode JsonNode; -typedef struct JsonParse JsonParse; - -/* An instance of this object represents a JSON string -** under construction. Really, this is a generic string accumulator -** that can be and is used to create strings other than JSON. -*/ -struct JsonString { - sqlite3_context *pCtx; /* Function context - put error messages here */ - char *zBuf; /* Append JSON content here */ - u64 nAlloc; /* Bytes of storage available in zBuf[] */ - u64 nUsed; /* Bytes of zBuf[] currently used */ - u8 bStatic; /* True if zBuf is static space */ - u8 bErr; /* True if an error has been encountered */ - char zSpace[100]; /* Initial static space */ -}; - -/* JSON type values -*/ -#define JSON_NULL 0 -#define JSON_TRUE 1 -#define JSON_FALSE 2 -#define JSON_INT 3 -#define JSON_REAL 4 -#define JSON_STRING 5 -#define JSON_ARRAY 6 -#define JSON_OBJECT 7 - -/* The "subtype" set for JSON values */ -#define JSON_SUBTYPE 74 /* Ascii for "J" */ - -/* -** Names of the various JSON types: -*/ -static const char * const jsonType[] = { - "null", "true", "false", "integer", "real", "text", "array", "object" -}; - -/* Bit values for the JsonNode.jnFlag field -*/ -#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */ -#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */ -#define JNODE_REMOVE 0x04 /* Do not output */ -#define JNODE_REPLACE 0x08 /* Replace with JsonNode.u.iReplace */ -#define JNODE_PATCH 0x10 /* Patch with JsonNode.u.pPatch */ -#define JNODE_APPEND 0x20 /* More ARRAY/OBJECT entries at u.iAppend */ -#define JNODE_LABEL 0x40 /* Is a label of an object */ - - -/* A single node of parsed JSON -*/ -struct JsonNode { - u8 eType; /* One of the JSON_ type values */ - u8 jnFlags; /* JNODE flags */ - u32 n; /* Bytes of content, or number of sub-nodes */ - union { - const char *zJContent; /* Content for INT, REAL, and STRING */ - u32 iAppend; /* More terms for ARRAY and OBJECT */ - u32 iKey; /* Key for ARRAY objects in json_tree() */ - u32 iReplace; /* Replacement content for JNODE_REPLACE */ - JsonNode *pPatch; /* Node chain of patch for JNODE_PATCH */ - } u; -}; - -/* A completely parsed JSON string -*/ -struct JsonParse { - u32 nNode; /* Number of slots of aNode[] used */ - u32 nAlloc; /* Number of slots of aNode[] allocated */ - JsonNode *aNode; /* Array of nodes containing the parse */ - const char *zJson; /* Original JSON string */ - u32 *aUp; /* Index of parent of each node */ - u8 oom; /* Set to true if out of memory */ - u8 nErr; /* Number of errors seen */ - u16 iDepth; /* Nesting depth */ - int nJson; /* Length of the zJson string in bytes */ -}; - -/* -** Maximum nesting depth of JSON for this implementation. -** -** This limit is needed to avoid a stack overflow in the recursive -** descent parser. A depth of 2000 is far deeper than any sane JSON -** should go. -*/ -#define JSON_MAX_DEPTH 2000 - -/************************************************************************** -** Utility routines for dealing with JsonString objects -**************************************************************************/ - -/* Set the JsonString object to an empty string -*/ -static void jsonZero(JsonString *p){ - p->zBuf = p->zSpace; - p->nAlloc = sizeof(p->zSpace); - p->nUsed = 0; - p->bStatic = 1; -} - -/* Initialize the JsonString object -*/ -static void jsonInit(JsonString *p, sqlite3_context *pCtx){ - p->pCtx = pCtx; - p->bErr = 0; - jsonZero(p); -} - - -/* Free all allocated memory and reset the JsonString object back to its -** initial state. -*/ -static void jsonReset(JsonString *p){ - if( !p->bStatic ) sqlite3_free(p->zBuf); - jsonZero(p); -} - - -/* Report an out-of-memory (OOM) condition -*/ -static void jsonOom(JsonString *p){ - p->bErr = 1; - sqlite3_result_error_nomem(p->pCtx); - jsonReset(p); -} - -/* Enlarge pJson->zBuf so that it can hold at least N more bytes. -** Return zero on success. Return non-zero on an OOM error -*/ -static int jsonGrow(JsonString *p, u32 N){ - u64 nTotal = NnAlloc ? p->nAlloc*2 : p->nAlloc+N+10; - char *zNew; - if( p->bStatic ){ - if( p->bErr ) return 1; - zNew = sqlite3_malloc64(nTotal); - if( zNew==0 ){ - jsonOom(p); - return SQLITE_NOMEM; - } - memcpy(zNew, p->zBuf, (size_t)p->nUsed); - p->zBuf = zNew; - p->bStatic = 0; - }else{ - zNew = sqlite3_realloc64(p->zBuf, nTotal); - if( zNew==0 ){ - jsonOom(p); - return SQLITE_NOMEM; - } - p->zBuf = zNew; - } - p->nAlloc = nTotal; - return SQLITE_OK; -} - -/* Append N bytes from zIn onto the end of the JsonString string. -*/ -static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){ - if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return; - memcpy(p->zBuf+p->nUsed, zIn, N); - p->nUsed += N; -} - -/* Append formatted text (not to exceed N bytes) to the JsonString. -*/ -static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){ - va_list ap; - if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return; - va_start(ap, zFormat); - sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap); - va_end(ap); - p->nUsed += (int)strlen(p->zBuf+p->nUsed); -} - -/* Append a single character -*/ -static void jsonAppendChar(JsonString *p, char c){ - if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return; - p->zBuf[p->nUsed++] = c; -} - -/* Append a comma separator to the output buffer, if the previous -** character is not '[' or '{'. -*/ -static void jsonAppendSeparator(JsonString *p){ - char c; - if( p->nUsed==0 ) return; - c = p->zBuf[p->nUsed-1]; - if( c!='[' && c!='{' ) jsonAppendChar(p, ','); -} - -/* Append the N-byte string in zIn to the end of the JsonString string -** under construction. Enclose the string in "..." and escape -** any double-quotes or backslash characters contained within the -** string. -*/ -static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ - u32 i; - if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return; - p->zBuf[p->nUsed++] = '"'; - for(i=0; inUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return; - p->zBuf[p->nUsed++] = '\\'; - }else if( c<=0x1f ){ - static const char aSpecial[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - assert( sizeof(aSpecial)==32 ); - assert( aSpecial['\b']=='b' ); - assert( aSpecial['\f']=='f' ); - assert( aSpecial['\n']=='n' ); - assert( aSpecial['\r']=='r' ); - assert( aSpecial['\t']=='t' ); - if( aSpecial[c] ){ - c = aSpecial[c]; - goto json_simple_escape; - } - if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return; - p->zBuf[p->nUsed++] = '\\'; - p->zBuf[p->nUsed++] = 'u'; - p->zBuf[p->nUsed++] = '0'; - p->zBuf[p->nUsed++] = '0'; - p->zBuf[p->nUsed++] = '0' + (c>>4); - c = "0123456789abcdef"[c&0xf]; - } - p->zBuf[p->nUsed++] = c; - } - p->zBuf[p->nUsed++] = '"'; - assert( p->nUsednAlloc ); -} - -/* -** Append a function parameter value to the JSON string under -** construction. -*/ -static void jsonAppendValue( - JsonString *p, /* Append to this JSON string */ - sqlite3_value *pValue /* Value to append */ -){ - switch( sqlite3_value_type(pValue) ){ - case SQLITE_NULL: { - jsonAppendRaw(p, "null", 4); - break; - } - case SQLITE_INTEGER: - case SQLITE_FLOAT: { - const char *z = (const char*)sqlite3_value_text(pValue); - u32 n = (u32)sqlite3_value_bytes(pValue); - jsonAppendRaw(p, z, n); - break; - } - case SQLITE_TEXT: { - const char *z = (const char*)sqlite3_value_text(pValue); - u32 n = (u32)sqlite3_value_bytes(pValue); - if( sqlite3_value_subtype(pValue)==JSON_SUBTYPE ){ - jsonAppendRaw(p, z, n); - }else{ - jsonAppendString(p, z, n); - } - break; - } - default: { - if( p->bErr==0 ){ - sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1); - p->bErr = 2; - jsonReset(p); - } - break; - } - } -} - - -/* Make the JSON in p the result of the SQL function. -*/ -static void jsonResult(JsonString *p){ - if( p->bErr==0 ){ - sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, - p->bStatic ? SQLITE_TRANSIENT : sqlite3_free, - SQLITE_UTF8); - jsonZero(p); - } - assert( p->bStatic ); -} - -/************************************************************************** -** Utility routines for dealing with JsonNode and JsonParse objects -**************************************************************************/ - -/* -** Return the number of consecutive JsonNode slots need to represent -** the parsed JSON at pNode. The minimum answer is 1. For ARRAY and -** OBJECT types, the number might be larger. -** -** Appended elements are not counted. The value returned is the number -** by which the JsonNode counter should increment in order to go to the -** next peer value. -*/ -static u32 jsonNodeSize(JsonNode *pNode){ - return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1; -} - -/* -** Reclaim all memory allocated by a JsonParse object. But do not -** delete the JsonParse object itself. -*/ -static void jsonParseReset(JsonParse *pParse){ - sqlite3_free(pParse->aNode); - pParse->aNode = 0; - pParse->nNode = 0; - pParse->nAlloc = 0; - sqlite3_free(pParse->aUp); - pParse->aUp = 0; -} - -/* -** Free a JsonParse object that was obtained from sqlite3_malloc(). -*/ -static void jsonParseFree(JsonParse *pParse){ - jsonParseReset(pParse); - sqlite3_free(pParse); -} - -/* -** Convert the JsonNode pNode into a pure JSON string and -** append to pOut. Subsubstructure is also included. Return -** the number of JsonNode objects that are encoded. -*/ -static void jsonRenderNode( - JsonNode *pNode, /* The node to render */ - JsonString *pOut, /* Write JSON here */ - sqlite3_value **aReplace /* Replacement values */ -){ - if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){ - if( pNode->jnFlags & JNODE_REPLACE ){ - jsonAppendValue(pOut, aReplace[pNode->u.iReplace]); - return; - } - pNode = pNode->u.pPatch; - } - switch( pNode->eType ){ - default: { - assert( pNode->eType==JSON_NULL ); - jsonAppendRaw(pOut, "null", 4); - break; - } - case JSON_TRUE: { - jsonAppendRaw(pOut, "true", 4); - break; - } - case JSON_FALSE: { - jsonAppendRaw(pOut, "false", 5); - break; - } - case JSON_STRING: { - if( pNode->jnFlags & JNODE_RAW ){ - jsonAppendString(pOut, pNode->u.zJContent, pNode->n); - break; - } - /* Fall through into the next case */ - } - case JSON_REAL: - case JSON_INT: { - jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n); - break; - } - case JSON_ARRAY: { - u32 j = 1; - jsonAppendChar(pOut, '['); - for(;;){ - while( j<=pNode->n ){ - if( (pNode[j].jnFlags & JNODE_REMOVE)==0 ){ - jsonAppendSeparator(pOut); - jsonRenderNode(&pNode[j], pOut, aReplace); - } - j += jsonNodeSize(&pNode[j]); - } - if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; - pNode = &pNode[pNode->u.iAppend]; - j = 1; - } - jsonAppendChar(pOut, ']'); - break; - } - case JSON_OBJECT: { - u32 j = 1; - jsonAppendChar(pOut, '{'); - for(;;){ - while( j<=pNode->n ){ - if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){ - jsonAppendSeparator(pOut); - jsonRenderNode(&pNode[j], pOut, aReplace); - jsonAppendChar(pOut, ':'); - jsonRenderNode(&pNode[j+1], pOut, aReplace); - } - j += 1 + jsonNodeSize(&pNode[j+1]); - } - if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; - pNode = &pNode[pNode->u.iAppend]; - j = 1; - } - jsonAppendChar(pOut, '}'); - break; - } - } -} - -/* -** Return a JsonNode and all its descendents as a JSON string. -*/ -static void jsonReturnJson( - JsonNode *pNode, /* Node to return */ - sqlite3_context *pCtx, /* Return value for this function */ - sqlite3_value **aReplace /* Array of replacement values */ -){ - JsonString s; - jsonInit(&s, pCtx); - jsonRenderNode(pNode, &s, aReplace); - jsonResult(&s); - sqlite3_result_subtype(pCtx, JSON_SUBTYPE); -} - -/* -** Make the JsonNode the return value of the function. -*/ -static void jsonReturn( - JsonNode *pNode, /* Node to return */ - sqlite3_context *pCtx, /* Return value for this function */ - sqlite3_value **aReplace /* Array of replacement values */ -){ - switch( pNode->eType ){ - default: { - assert( pNode->eType==JSON_NULL ); - sqlite3_result_null(pCtx); - break; - } - case JSON_TRUE: { - sqlite3_result_int(pCtx, 1); - break; - } - case JSON_FALSE: { - sqlite3_result_int(pCtx, 0); - break; - } - case JSON_INT: { - sqlite3_int64 i = 0; - const char *z = pNode->u.zJContent; - if( z[0]=='-' ){ z++; } - while( z[0]>='0' && z[0]<='9' ){ - unsigned v = *(z++) - '0'; - if( i>=LARGEST_INT64/10 ){ - if( i>LARGEST_INT64/10 ) goto int_as_real; - if( z[0]>='0' && z[0]<='9' ) goto int_as_real; - if( v==9 ) goto int_as_real; - if( v==8 ){ - if( pNode->u.zJContent[0]=='-' ){ - sqlite3_result_int64(pCtx, SMALLEST_INT64); - goto int_done; - }else{ - goto int_as_real; - } - } - } - i = i*10 + v; - } - if( pNode->u.zJContent[0]=='-' ){ i = -i; } - sqlite3_result_int64(pCtx, i); - int_done: - break; - int_as_real: /* fall through to real */; - } - case JSON_REAL: { - double r; -#ifdef SQLITE_AMALGAMATION - const char *z = pNode->u.zJContent; - sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8); -#else - r = strtod(pNode->u.zJContent, 0); -#endif - sqlite3_result_double(pCtx, r); - break; - } - case JSON_STRING: { -#if 0 /* Never happens because JNODE_RAW is only set by json_set(), - ** json_insert() and json_replace() and those routines do not - ** call jsonReturn() */ - if( pNode->jnFlags & JNODE_RAW ){ - sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n, - SQLITE_TRANSIENT); - }else -#endif - assert( (pNode->jnFlags & JNODE_RAW)==0 ); - if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){ - /* JSON formatted without any backslash-escapes */ - sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2, - SQLITE_TRANSIENT); - }else{ - /* Translate JSON formatted string into raw text */ - u32 i; - u32 n = pNode->n; - const char *z = pNode->u.zJContent; - char *zOut; - u32 j; - zOut = sqlite3_malloc( n+1 ); - if( zOut==0 ){ - sqlite3_result_error_nomem(pCtx); - break; - } - for(i=1, j=0; i>6)); - zOut[j++] = 0x80 | (v&0x3f); - }else{ - zOut[j++] = (char)(0xe0 | (v>>12)); - zOut[j++] = 0x80 | ((v>>6)&0x3f); - zOut[j++] = 0x80 | (v&0x3f); - } - }else{ - if( c=='b' ){ - c = '\b'; - }else if( c=='f' ){ - c = '\f'; - }else if( c=='n' ){ - c = '\n'; - }else if( c=='r' ){ - c = '\r'; - }else if( c=='t' ){ - c = '\t'; - } - zOut[j++] = c; - } - } - } - zOut[j] = 0; - sqlite3_result_text(pCtx, zOut, j, sqlite3_free); - } - break; - } - case JSON_ARRAY: - case JSON_OBJECT: { - jsonReturnJson(pNode, pCtx, aReplace); - break; - } - } -} - -/* Forward reference */ -static int jsonParseAddNode(JsonParse*,u32,u32,const char*); - -/* -** A macro to hint to the compiler that a function should not be -** inlined. -*/ -#if defined(__GNUC__) -# define JSON_NOINLINE __attribute__((noinline)) -#elif defined(_MSC_VER) && _MSC_VER>=1310 -# define JSON_NOINLINE __declspec(noinline) -#else -# define JSON_NOINLINE -#endif - - -static JSON_NOINLINE int jsonParseAddNodeExpand( - JsonParse *pParse, /* Append the node to this object */ - u32 eType, /* Node type */ - u32 n, /* Content size or sub-node count */ - const char *zContent /* Content */ -){ - u32 nNew; - JsonNode *pNew; - assert( pParse->nNode>=pParse->nAlloc ); - if( pParse->oom ) return -1; - nNew = pParse->nAlloc*2 + 10; - pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew); - if( pNew==0 ){ - pParse->oom = 1; - return -1; - } - pParse->nAlloc = nNew; - pParse->aNode = pNew; - assert( pParse->nNodenAlloc ); - return jsonParseAddNode(pParse, eType, n, zContent); -} - -/* -** Create a new JsonNode instance based on the arguments and append that -** instance to the JsonParse. Return the index in pParse->aNode[] of the -** new node, or -1 if a memory allocation fails. -*/ -static int jsonParseAddNode( - JsonParse *pParse, /* Append the node to this object */ - u32 eType, /* Node type */ - u32 n, /* Content size or sub-node count */ - const char *zContent /* Content */ -){ - JsonNode *p; - if( pParse->nNode>=pParse->nAlloc ){ - return jsonParseAddNodeExpand(pParse, eType, n, zContent); - } - p = &pParse->aNode[pParse->nNode]; - p->eType = (u8)eType; - p->jnFlags = 0; - p->n = n; - p->u.zJContent = zContent; - return pParse->nNode++; -} - -/* -** Return true if z[] begins with 4 (or more) hexadecimal digits -*/ -static int jsonIs4Hex(const char *z){ - int i; - for(i=0; i<4; i++) if( !safe_isxdigit(z[i]) ) return 0; - return 1; -} - -/* -** Parse a single JSON value which begins at pParse->zJson[i]. Return the -** index of the first character past the end of the value parsed. -** -** Return negative for a syntax error. Special cases: return -2 if the -** first non-whitespace character is '}' and return -3 if the first -** non-whitespace character is ']'. -*/ -static int jsonParseValue(JsonParse *pParse, u32 i){ - char c; - u32 j; - int iThis; - int x; - JsonNode *pNode; - const char *z = pParse->zJson; - while( safe_isspace(z[i]) ){ i++; } - if( (c = z[i])=='{' ){ - /* Parse object */ - iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); - if( iThis<0 ) return -1; - for(j=i+1;;j++){ - while( safe_isspace(z[j]) ){ j++; } - if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1; - x = jsonParseValue(pParse, j); - if( x<0 ){ - pParse->iDepth--; - if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1; - return -1; - } - if( pParse->oom ) return -1; - pNode = &pParse->aNode[pParse->nNode-1]; - if( pNode->eType!=JSON_STRING ) return -1; - pNode->jnFlags |= JNODE_LABEL; - j = x; - while( safe_isspace(z[j]) ){ j++; } - if( z[j]!=':' ) return -1; - j++; - x = jsonParseValue(pParse, j); - pParse->iDepth--; - if( x<0 ) return -1; - j = x; - while( safe_isspace(z[j]) ){ j++; } - c = z[j]; - if( c==',' ) continue; - if( c!='}' ) return -1; - break; - } - pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; - return j+1; - }else if( c=='[' ){ - /* Parse array */ - iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); - if( iThis<0 ) return -1; - for(j=i+1;;j++){ - while( safe_isspace(z[j]) ){ j++; } - if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1; - x = jsonParseValue(pParse, j); - pParse->iDepth--; - if( x<0 ){ - if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1; - return -1; - } - j = x; - while( safe_isspace(z[j]) ){ j++; } - c = z[j]; - if( c==',' ) continue; - if( c!=']' ) return -1; - break; - } - pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; - return j+1; - }else if( c=='"' ){ - /* Parse string */ - u8 jnFlags = 0; - j = i+1; - for(;;){ - c = z[j]; - if( (c & ~0x1f)==0 ){ - /* Control characters are not allowed in strings */ - return -1; - } - if( c=='\\' ){ - c = z[++j]; - if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f' - || c=='n' || c=='r' || c=='t' - || (c=='u' && jsonIs4Hex(z+j+1)) ){ - jnFlags = JNODE_ESCAPE; - }else{ - return -1; - } - }else if( c=='"' ){ - break; - } - j++; - } - jsonParseAddNode(pParse, JSON_STRING, j+1-i, &z[i]); - if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags; - return j+1; - }else if( c=='n' - && strncmp(z+i,"null",4)==0 - && !safe_isalnum(z[i+4]) ){ - jsonParseAddNode(pParse, JSON_NULL, 0, 0); - return i+4; - }else if( c=='t' - && strncmp(z+i,"true",4)==0 - && !safe_isalnum(z[i+4]) ){ - jsonParseAddNode(pParse, JSON_TRUE, 0, 0); - return i+4; - }else if( c=='f' - && strncmp(z+i,"false",5)==0 - && !safe_isalnum(z[i+5]) ){ - jsonParseAddNode(pParse, JSON_FALSE, 0, 0); - return i+5; - }else if( c=='-' || (c>='0' && c<='9') ){ - /* Parse number */ - u8 seenDP = 0; - u8 seenE = 0; - assert( '-' < '0' ); - if( c<='0' ){ - j = c=='-' ? i+1 : i; - if( z[j]=='0' && z[j+1]>='0' && z[j+1]<='9' ) return -1; - } - j = i+1; - for(;; j++){ - c = z[j]; - if( c>='0' && c<='9' ) continue; - if( c=='.' ){ - if( z[j-1]=='-' ) return -1; - if( seenDP ) return -1; - seenDP = 1; - continue; - } - if( c=='e' || c=='E' ){ - if( z[j-1]<'0' ) return -1; - if( seenE ) return -1; - seenDP = seenE = 1; - c = z[j+1]; - if( c=='+' || c=='-' ){ - j++; - c = z[j+1]; - } - if( c<'0' || c>'9' ) return -1; - continue; - } - break; - } - if( z[j-1]<'0' ) return -1; - jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT, - j - i, &z[i]); - return j; - }else if( c=='}' ){ - return -2; /* End of {...} */ - }else if( c==']' ){ - return -3; /* End of [...] */ - }else if( c==0 ){ - return 0; /* End of file */ - }else{ - return -1; /* Syntax error */ - } -} - -/* -** Parse a complete JSON string. Return 0 on success or non-zero if there -** are any errors. If an error occurs, free all memory associated with -** pParse. -** -** pParse is uninitialized when this routine is called. -*/ -static int jsonParse( - JsonParse *pParse, /* Initialize and fill this JsonParse object */ - sqlite3_context *pCtx, /* Report errors here */ - const char *zJson /* Input JSON text to be parsed */ -){ - int i; - memset(pParse, 0, sizeof(*pParse)); - if( zJson==0 ) return 1; - pParse->zJson = zJson; - i = jsonParseValue(pParse, 0); - if( pParse->oom ) i = -1; - if( i>0 ){ - assert( pParse->iDepth==0 ); - while( safe_isspace(zJson[i]) ) i++; - if( zJson[i] ) i = -1; - } - if( i<=0 ){ - if( pCtx!=0 ){ - if( pParse->oom ){ - sqlite3_result_error_nomem(pCtx); - }else{ - sqlite3_result_error(pCtx, "malformed JSON", -1); - } - } - jsonParseReset(pParse); - return 1; - } - return 0; -} - -/* Mark node i of pParse as being a child of iParent. Call recursively -** to fill in all the descendants of node i. -*/ -static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){ - JsonNode *pNode = &pParse->aNode[i]; - u32 j; - pParse->aUp[i] = iParent; - switch( pNode->eType ){ - case JSON_ARRAY: { - for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){ - jsonParseFillInParentage(pParse, i+j, i); - } - break; - } - case JSON_OBJECT: { - for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){ - pParse->aUp[i+j] = i; - jsonParseFillInParentage(pParse, i+j+1, i); - } - break; - } - default: { - break; - } - } -} - -/* -** Compute the parentage of all nodes in a completed parse. -*/ -static int jsonParseFindParents(JsonParse *pParse){ - u32 *aUp; - assert( pParse->aUp==0 ); - aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode ); - if( aUp==0 ){ - pParse->oom = 1; - return SQLITE_NOMEM; - } - jsonParseFillInParentage(pParse, 0, 0); - return SQLITE_OK; -} - -/* -** Magic number used for the JSON parse cache in sqlite3_get_auxdata() -*/ -#define JSON_CACHE_ID (-429938) - -/* -** Obtain a complete parse of the JSON found in the first argument -** of the argv array. Use the sqlite3_get_auxdata() cache for this -** parse if it is available. If the cache is not available or if it -** is no longer valid, parse the JSON again and return the new parse, -** and also register the new parse so that it will be available for -** future sqlite3_get_auxdata() calls. -*/ -static JsonParse *jsonParseCached( - sqlite3_context *pCtx, - sqlite3_value **argv -){ - const char *zJson = (const char*)sqlite3_value_text(argv[0]); - int nJson = sqlite3_value_bytes(argv[0]); - JsonParse *p; - if( zJson==0 ) return 0; - p = (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID); - if( p && p->nJson==nJson && memcmp(p->zJson,zJson,nJson)==0 ){ - p->nErr = 0; - return p; /* The cached entry matches, so return it */ - } - p = sqlite3_malloc( sizeof(*p) + nJson + 1 ); - if( p==0 ){ - sqlite3_result_error_nomem(pCtx); - return 0; - } - memset(p, 0, sizeof(*p)); - p->zJson = (char*)&p[1]; - memcpy((char*)p->zJson, zJson, nJson+1); - if( jsonParse(p, pCtx, p->zJson) ){ - sqlite3_free(p); - return 0; - } - p->nJson = nJson; - sqlite3_set_auxdata(pCtx, JSON_CACHE_ID, p, (void(*)(void*))jsonParseFree); - return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID); -} - -/* -** Compare the OBJECT label at pNode against zKey,nKey. Return true on -** a match. -*/ -static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){ - if( pNode->jnFlags & JNODE_RAW ){ - if( pNode->n!=nKey ) return 0; - return strncmp(pNode->u.zJContent, zKey, nKey)==0; - }else{ - if( pNode->n!=nKey+2 ) return 0; - return strncmp(pNode->u.zJContent+1, zKey, nKey)==0; - } -} - -/* forward declaration */ -static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**); - -/* -** Search along zPath to find the node specified. Return a pointer -** to that node, or NULL if zPath is malformed or if there is no such -** node. -** -** If pApnd!=0, then try to append new nodes to complete zPath if it is -** possible to do so and if no existing node corresponds to zPath. If -** new nodes are appended *pApnd is set to 1. -*/ -static JsonNode *jsonLookupStep( - JsonParse *pParse, /* The JSON to search */ - u32 iRoot, /* Begin the search at this node */ - const char *zPath, /* The path to search */ - int *pApnd, /* Append nodes to complete path if not NULL */ - const char **pzErr /* Make *pzErr point to any syntax error in zPath */ -){ - u32 i, j, nKey; - const char *zKey; - JsonNode *pRoot = &pParse->aNode[iRoot]; - if( zPath[0]==0 ) return pRoot; - if( zPath[0]=='.' ){ - if( pRoot->eType!=JSON_OBJECT ) return 0; - zPath++; - if( zPath[0]=='"' ){ - zKey = zPath + 1; - for(i=1; zPath[i] && zPath[i]!='"'; i++){} - nKey = i-1; - if( zPath[i] ){ - i++; - }else{ - *pzErr = zPath; - return 0; - } - }else{ - zKey = zPath; - for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){} - nKey = i; - } - if( nKey==0 ){ - *pzErr = zPath; - return 0; - } - j = 1; - for(;;){ - while( j<=pRoot->n ){ - if( jsonLabelCompare(pRoot+j, zKey, nKey) ){ - return jsonLookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr); - } - j++; - j += jsonNodeSize(&pRoot[j]); - } - if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; - iRoot += pRoot->u.iAppend; - pRoot = &pParse->aNode[iRoot]; - j = 1; - } - if( pApnd ){ - u32 iStart, iLabel; - JsonNode *pNode; - iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0); - iLabel = jsonParseAddNode(pParse, JSON_STRING, i, zPath); - zPath += i; - pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr); - if( pParse->oom ) return 0; - if( pNode ){ - pRoot = &pParse->aNode[iRoot]; - pRoot->u.iAppend = iStart - iRoot; - pRoot->jnFlags |= JNODE_APPEND; - pParse->aNode[iLabel].jnFlags |= JNODE_RAW; - } - return pNode; - } - }else if( zPath[0]=='[' && safe_isdigit(zPath[1]) ){ - if( pRoot->eType!=JSON_ARRAY ) return 0; - i = 0; - j = 1; - while( safe_isdigit(zPath[j]) ){ - i = i*10 + zPath[j] - '0'; - j++; - } - if( zPath[j]!=']' ){ - *pzErr = zPath; - return 0; - } - zPath += j + 1; - j = 1; - for(;;){ - while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){ - if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--; - j += jsonNodeSize(&pRoot[j]); - } - if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; - iRoot += pRoot->u.iAppend; - pRoot = &pParse->aNode[iRoot]; - j = 1; - } - if( j<=pRoot->n ){ - return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr); - } - if( i==0 && pApnd ){ - u32 iStart; - JsonNode *pNode; - iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0); - pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr); - if( pParse->oom ) return 0; - if( pNode ){ - pRoot = &pParse->aNode[iRoot]; - pRoot->u.iAppend = iStart - iRoot; - pRoot->jnFlags |= JNODE_APPEND; - } - return pNode; - } - }else{ - *pzErr = zPath; - } - return 0; -} - -/* -** Append content to pParse that will complete zPath. Return a pointer -** to the inserted node, or return NULL if the append fails. -*/ -static JsonNode *jsonLookupAppend( - JsonParse *pParse, /* Append content to the JSON parse */ - const char *zPath, /* Description of content to append */ - int *pApnd, /* Set this flag to 1 */ - const char **pzErr /* Make this point to any syntax error */ -){ - *pApnd = 1; - if( zPath[0]==0 ){ - jsonParseAddNode(pParse, JSON_NULL, 0, 0); - return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1]; - } - if( zPath[0]=='.' ){ - jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); - }else if( strncmp(zPath,"[0]",3)==0 ){ - jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); - }else{ - return 0; - } - if( pParse->oom ) return 0; - return jsonLookupStep(pParse, pParse->nNode-1, zPath, pApnd, pzErr); -} - -/* -** Return the text of a syntax error message on a JSON path. Space is -** obtained from sqlite3_malloc(). -*/ -static char *jsonPathSyntaxError(const char *zErr){ - return sqlite3_mprintf("JSON path error near '%q'", zErr); -} - -/* -** Do a node lookup using zPath. Return a pointer to the node on success. -** Return NULL if not found or if there is an error. -** -** On an error, write an error message into pCtx and increment the -** pParse->nErr counter. -** -** If pApnd!=NULL then try to append missing nodes and set *pApnd = 1 if -** nodes are appended. -*/ -static JsonNode *jsonLookup( - JsonParse *pParse, /* The JSON to search */ - const char *zPath, /* The path to search */ - int *pApnd, /* Append nodes to complete path if not NULL */ - sqlite3_context *pCtx /* Report errors here, if not NULL */ -){ - const char *zErr = 0; - JsonNode *pNode = 0; - char *zMsg; - - if( zPath==0 ) return 0; - if( zPath[0]!='$' ){ - zErr = zPath; - goto lookup_err; - } - zPath++; - pNode = jsonLookupStep(pParse, 0, zPath, pApnd, &zErr); - if( zErr==0 ) return pNode; - -lookup_err: - pParse->nErr++; - assert( zErr!=0 && pCtx!=0 ); - zMsg = jsonPathSyntaxError(zErr); - if( zMsg ){ - sqlite3_result_error(pCtx, zMsg, -1); - sqlite3_free(zMsg); - }else{ - sqlite3_result_error_nomem(pCtx); - } - return 0; -} - - -/* -** Report the wrong number of arguments for json_insert(), json_replace() -** or json_set(). -*/ -static void jsonWrongNumArgs( - sqlite3_context *pCtx, - const char *zFuncName -){ - char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments", - zFuncName); - sqlite3_result_error(pCtx, zMsg, -1); - sqlite3_free(zMsg); -} - -/* -** Mark all NULL entries in the Object passed in as JNODE_REMOVE. -*/ -static void jsonRemoveAllNulls(JsonNode *pNode){ - int i, n; - assert( pNode->eType==JSON_OBJECT ); - n = pNode->n; - for(i=2; i<=n; i += jsonNodeSize(&pNode[i])+1){ - switch( pNode[i].eType ){ - case JSON_NULL: - pNode[i].jnFlags |= JNODE_REMOVE; - break; - case JSON_OBJECT: - jsonRemoveAllNulls(&pNode[i]); - break; - } - } -} - - -/**************************************************************************** -** SQL functions used for testing and debugging -****************************************************************************/ - -#ifdef SQLITE_DEBUG -/* -** The json_parse(JSON) function returns a string which describes -** a parse of the JSON provided. Or it returns NULL if JSON is not -** well-formed. -*/ -static void jsonParseFunc( - sqlite3_context *ctx, - int argc, - sqlite3_value **argv -){ - JsonString s; /* Output string - not real JSON */ - JsonParse x; /* The parse */ - u32 i; - - assert( argc==1 ); - if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; - jsonParseFindParents(&x); - jsonInit(&s, ctx); - for(i=0; inNode ); - if( argc==2 ){ - const char *zPath = (const char*)sqlite3_value_text(argv[1]); - pNode = jsonLookup(p, zPath, 0, ctx); - }else{ - pNode = p->aNode; - } - if( pNode==0 ){ - return; - } - if( pNode->eType==JSON_ARRAY ){ - assert( (pNode->jnFlags & JNODE_APPEND)==0 ); - for(i=1; i<=pNode->n; n++){ - i += jsonNodeSize(&pNode[i]); - } - } - sqlite3_result_int64(ctx, n); -} - -/* -** json_extract(JSON, PATH, ...) -** -** Return the element described by PATH. Return NULL if there is no -** PATH element. If there are multiple PATHs, then return a JSON array -** with the result from each path. Throw an error if the JSON or any PATH -** is malformed. -*/ -static void jsonExtractFunc( - sqlite3_context *ctx, - int argc, - sqlite3_value **argv -){ - JsonParse *p; /* The parse */ - JsonNode *pNode; - const char *zPath; - JsonString jx; - int i; - - if( argc<2 ) return; - p = jsonParseCached(ctx, argv); - if( p==0 ) return; - jsonInit(&jx, ctx); - jsonAppendChar(&jx, '['); - for(i=1; inErr ) break; - if( argc>2 ){ - jsonAppendSeparator(&jx); - if( pNode ){ - jsonRenderNode(pNode, &jx, 0); - }else{ - jsonAppendRaw(&jx, "null", 4); - } - }else if( pNode ){ - jsonReturn(pNode, ctx, 0); - } - } - if( argc>2 && i==argc ){ - jsonAppendChar(&jx, ']'); - jsonResult(&jx); - sqlite3_result_subtype(ctx, JSON_SUBTYPE); - } - jsonReset(&jx); -} - -/* This is the RFC 7396 MergePatch algorithm. -*/ -static JsonNode *jsonMergePatch( - JsonParse *pParse, /* The JSON parser that contains the TARGET */ - u32 iTarget, /* Node of the TARGET in pParse */ - JsonNode *pPatch /* The PATCH */ -){ - u32 i, j; - u32 iRoot; - JsonNode *pTarget; - if( pPatch->eType!=JSON_OBJECT ){ - return pPatch; - } - assert( iTarget>=0 && iTargetnNode ); - pTarget = &pParse->aNode[iTarget]; - assert( (pPatch->jnFlags & JNODE_APPEND)==0 ); - if( pTarget->eType!=JSON_OBJECT ){ - jsonRemoveAllNulls(pPatch); - return pPatch; - } - iRoot = iTarget; - for(i=1; in; i += jsonNodeSize(&pPatch[i+1])+1){ - u32 nKey; - const char *zKey; - assert( pPatch[i].eType==JSON_STRING ); - assert( pPatch[i].jnFlags & JNODE_LABEL ); - nKey = pPatch[i].n; - zKey = pPatch[i].u.zJContent; - assert( (pPatch[i].jnFlags & JNODE_RAW)==0 ); - for(j=1; jn; j += jsonNodeSize(&pTarget[j+1])+1 ){ - assert( pTarget[j].eType==JSON_STRING ); - assert( pTarget[j].jnFlags & JNODE_LABEL ); - assert( (pPatch[i].jnFlags & JNODE_RAW)==0 ); - if( pTarget[j].n==nKey && strncmp(pTarget[j].u.zJContent,zKey,nKey)==0 ){ - if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH) ) break; - if( pPatch[i+1].eType==JSON_NULL ){ - pTarget[j+1].jnFlags |= JNODE_REMOVE; - }else{ - JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]); - if( pNew==0 ) return 0; - pTarget = &pParse->aNode[iTarget]; - if( pNew!=&pTarget[j+1] ){ - pTarget[j+1].u.pPatch = pNew; - pTarget[j+1].jnFlags |= JNODE_PATCH; - } - } - break; - } - } - if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){ - int iStart, iPatch; - iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0); - jsonParseAddNode(pParse, JSON_STRING, nKey, zKey); - iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0); - if( pParse->oom ) return 0; - jsonRemoveAllNulls(pPatch); - pTarget = &pParse->aNode[iTarget]; - pParse->aNode[iRoot].jnFlags |= JNODE_APPEND; - pParse->aNode[iRoot].u.iAppend = iStart - iRoot; - iRoot = iStart; - pParse->aNode[iPatch].jnFlags |= JNODE_PATCH; - pParse->aNode[iPatch].u.pPatch = &pPatch[i+1]; - } - } - return pTarget; -} - -/* -** Implementation of the json_mergepatch(JSON1,JSON2) function. Return a JSON -** object that is the result of running the RFC 7396 MergePatch() algorithm -** on the two arguments. -*/ -static void jsonPatchFunc( - sqlite3_context *ctx, - int argc, - sqlite3_value **argv -){ - JsonParse x; /* The JSON that is being patched */ - JsonParse y; /* The patch */ - JsonNode *pResult; /* The result of the merge */ - - UNUSED_PARAM(argc); - if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; - if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){ - jsonParseReset(&x); - return; - } - pResult = jsonMergePatch(&x, 0, y.aNode); - assert( pResult!=0 || x.oom ); - if( pResult ){ - jsonReturnJson(pResult, ctx, 0); - }else{ - sqlite3_result_error_nomem(ctx); - } - jsonParseReset(&x); - jsonParseReset(&y); -} - - -/* -** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON -** object that contains all name/value given in arguments. Or if any name -** is not a string or if any value is a BLOB, throw an error. -*/ -static void jsonObjectFunc( - sqlite3_context *ctx, - int argc, - sqlite3_value **argv -){ - int i; - JsonString jx; - const char *z; - u32 n; - - if( argc&1 ){ - sqlite3_result_error(ctx, "json_object() requires an even number " - "of arguments", -1); - return; - } - jsonInit(&jx, ctx); - jsonAppendChar(&jx, '{'); - for(i=0; ijnFlags |= JNODE_REMOVE; - } - if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){ - jsonReturnJson(x.aNode, ctx, 0); - } -remove_done: - jsonParseReset(&x); -} - -/* -** json_replace(JSON, PATH, VALUE, ...) -** -** Replace the value at PATH with VALUE. If PATH does not already exist, -** this routine is a no-op. If JSON or PATH is malformed, throw an error. -*/ -static void jsonReplaceFunc( - sqlite3_context *ctx, - int argc, - sqlite3_value **argv -){ - JsonParse x; /* The parse */ - JsonNode *pNode; - const char *zPath; - u32 i; - - if( argc<1 ) return; - if( (argc&1)==0 ) { - jsonWrongNumArgs(ctx, "replace"); - return; - } - if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; - assert( x.nNode ); - for(i=1; i<(u32)argc; i+=2){ - zPath = (const char*)sqlite3_value_text(argv[i]); - pNode = jsonLookup(&x, zPath, 0, ctx); - if( x.nErr ) goto replace_err; - if( pNode ){ - pNode->jnFlags |= (u8)JNODE_REPLACE; - pNode->u.iReplace = i + 1; - } - } - if( x.aNode[0].jnFlags & JNODE_REPLACE ){ - sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); - }else{ - jsonReturnJson(x.aNode, ctx, argv); - } -replace_err: - jsonParseReset(&x); -} - -/* -** json_set(JSON, PATH, VALUE, ...) -** -** Set the value at PATH to VALUE. Create the PATH if it does not already -** exist. Overwrite existing values that do exist. -** If JSON or PATH is malformed, throw an error. -** -** json_insert(JSON, PATH, VALUE, ...) -** -** Create PATH and initialize it to VALUE. If PATH already exists, this -** routine is a no-op. If JSON or PATH is malformed, throw an error. -*/ -static void jsonSetFunc( - sqlite3_context *ctx, - int argc, - sqlite3_value **argv -){ - JsonParse x; /* The parse */ - JsonNode *pNode; - const char *zPath; - u32 i; - int bApnd; - int bIsSet = *(int*)sqlite3_user_data(ctx); - - if( argc<1 ) return; - if( (argc&1)==0 ) { - jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert"); - return; - } - if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; - assert( x.nNode ); - for(i=1; i<(u32)argc; i+=2){ - zPath = (const char*)sqlite3_value_text(argv[i]); - bApnd = 0; - pNode = jsonLookup(&x, zPath, &bApnd, ctx); - if( x.oom ){ - sqlite3_result_error_nomem(ctx); - goto jsonSetDone; - }else if( x.nErr ){ - goto jsonSetDone; - }else if( pNode && (bApnd || bIsSet) ){ - pNode->jnFlags |= (u8)JNODE_REPLACE; - pNode->u.iReplace = i + 1; - } - } - if( x.aNode[0].jnFlags & JNODE_REPLACE ){ - sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); - }else{ - jsonReturnJson(x.aNode, ctx, argv); - } -jsonSetDone: - jsonParseReset(&x); -} - -/* -** json_type(JSON) -** json_type(JSON, PATH) -** -** Return the top-level "type" of a JSON string. Throw an error if -** either the JSON or PATH inputs are not well-formed. -*/ -static void jsonTypeFunc( - sqlite3_context *ctx, - int argc, - sqlite3_value **argv -){ - JsonParse x; /* The parse */ - const char *zPath; - JsonNode *pNode; - - if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; - assert( x.nNode ); - if( argc==2 ){ - zPath = (const char*)sqlite3_value_text(argv[1]); - pNode = jsonLookup(&x, zPath, 0, ctx); - }else{ - pNode = x.aNode; - } - if( pNode ){ - sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC); - } - jsonParseReset(&x); -} - -/* -** json_valid(JSON) -** -** Return 1 if JSON is a well-formed JSON string according to RFC-7159. -** Return 0 otherwise. -*/ -static void jsonValidFunc( - sqlite3_context *ctx, - int argc, - sqlite3_value **argv -){ - JsonParse x; /* The parse */ - int rc = 0; - - UNUSED_PARAM(argc); - if( jsonParse(&x, 0, (const char*)sqlite3_value_text(argv[0]))==0 ){ - rc = 1; - } - jsonParseReset(&x); - sqlite3_result_int(ctx, rc); -} - - -/**************************************************************************** -** Aggregate SQL function implementations -****************************************************************************/ -/* -** json_group_array(VALUE) -** -** Return a JSON array composed of all values in the aggregate. -*/ -static void jsonArrayStep( - sqlite3_context *ctx, - int argc, - sqlite3_value **argv -){ - JsonString *pStr; - UNUSED_PARAM(argc); - pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); - if( pStr ){ - if( pStr->zBuf==0 ){ - jsonInit(pStr, ctx); - jsonAppendChar(pStr, '['); - }else{ - jsonAppendChar(pStr, ','); - pStr->pCtx = ctx; - } - jsonAppendValue(pStr, argv[0]); - } -} -static void jsonArrayFinal(sqlite3_context *ctx){ - JsonString *pStr; - pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); - if( pStr ){ - pStr->pCtx = ctx; - jsonAppendChar(pStr, ']'); - if( pStr->bErr ){ - if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); - assert( pStr->bStatic ); - }else{ - sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed, - pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); - pStr->bStatic = 1; - } - }else{ - sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC); - } - sqlite3_result_subtype(ctx, JSON_SUBTYPE); -} - -/* -** json_group_obj(NAME,VALUE) -** -** Return a JSON object composed of all names and values in the aggregate. -*/ -static void jsonObjectStep( - sqlite3_context *ctx, - int argc, - sqlite3_value **argv -){ - JsonString *pStr; - const char *z; - u32 n; - UNUSED_PARAM(argc); - pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); - if( pStr ){ - if( pStr->zBuf==0 ){ - jsonInit(pStr, ctx); - jsonAppendChar(pStr, '{'); - }else{ - jsonAppendChar(pStr, ','); - pStr->pCtx = ctx; - } - z = (const char*)sqlite3_value_text(argv[0]); - n = (u32)sqlite3_value_bytes(argv[0]); - jsonAppendString(pStr, z, n); - jsonAppendChar(pStr, ':'); - jsonAppendValue(pStr, argv[1]); - } -} -static void jsonObjectFinal(sqlite3_context *ctx){ - JsonString *pStr; - pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); - if( pStr ){ - jsonAppendChar(pStr, '}'); - if( pStr->bErr ){ - if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); - assert( pStr->bStatic ); - }else{ - sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed, - pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); - pStr->bStatic = 1; - } - }else{ - sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC); - } - sqlite3_result_subtype(ctx, JSON_SUBTYPE); -} - - -#ifndef SQLITE_OMIT_VIRTUALTABLE -/**************************************************************************** -** The json_each virtual table -****************************************************************************/ -typedef struct JsonEachCursor JsonEachCursor; -struct JsonEachCursor { - sqlite3_vtab_cursor base; /* Base class - must be first */ - u32 iRowid; /* The rowid */ - u32 iBegin; /* The first node of the scan */ - u32 i; /* Index in sParse.aNode[] of current row */ - u32 iEnd; /* EOF when i equals or exceeds this value */ - u8 eType; /* Type of top-level element */ - u8 bRecursive; /* True for json_tree(). False for json_each() */ - char *zJson; /* Input JSON */ - char *zRoot; /* Path by which to filter zJson */ - JsonParse sParse; /* Parse of the input JSON */ -}; - -/* Constructor for the json_each virtual table */ -static int jsonEachConnect( - sqlite3 *db, - void *pAux, - int argc, const char *const*argv, - sqlite3_vtab **ppVtab, - char **pzErr -){ - sqlite3_vtab *pNew; - int rc; - -/* Column numbers */ -#define JEACH_KEY 0 -#define JEACH_VALUE 1 -#define JEACH_TYPE 2 -#define JEACH_ATOM 3 -#define JEACH_ID 4 -#define JEACH_PARENT 5 -#define JEACH_FULLKEY 6 -#define JEACH_PATH 7 -#define JEACH_JSON 8 -#define JEACH_ROOT 9 - - UNUSED_PARAM(pzErr); - UNUSED_PARAM(argv); - UNUSED_PARAM(argc); - UNUSED_PARAM(pAux); - rc = sqlite3_declare_vtab(db, - "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path," - "json HIDDEN,root HIDDEN)"); - if( rc==SQLITE_OK ){ - pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); - if( pNew==0 ) return SQLITE_NOMEM; - memset(pNew, 0, sizeof(*pNew)); - } - return rc; -} - -/* destructor for json_each virtual table */ -static int jsonEachDisconnect(sqlite3_vtab *pVtab){ - sqlite3_free(pVtab); - return SQLITE_OK; -} - -/* constructor for a JsonEachCursor object for json_each(). */ -static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ - JsonEachCursor *pCur; - - UNUSED_PARAM(p); - pCur = sqlite3_malloc( sizeof(*pCur) ); - if( pCur==0 ) return SQLITE_NOMEM; - memset(pCur, 0, sizeof(*pCur)); - *ppCursor = &pCur->base; - return SQLITE_OK; -} - -/* constructor for a JsonEachCursor object for json_tree(). */ -static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ - int rc = jsonEachOpenEach(p, ppCursor); - if( rc==SQLITE_OK ){ - JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor; - pCur->bRecursive = 1; - } - return rc; -} - -/* Reset a JsonEachCursor back to its original state. Free any memory -** held. */ -static void jsonEachCursorReset(JsonEachCursor *p){ - sqlite3_free(p->zJson); - sqlite3_free(p->zRoot); - jsonParseReset(&p->sParse); - p->iRowid = 0; - p->i = 0; - p->iEnd = 0; - p->eType = 0; - p->zJson = 0; - p->zRoot = 0; -} - -/* Destructor for a jsonEachCursor object */ -static int jsonEachClose(sqlite3_vtab_cursor *cur){ - JsonEachCursor *p = (JsonEachCursor*)cur; - jsonEachCursorReset(p); - sqlite3_free(cur); - return SQLITE_OK; -} - -/* Return TRUE if the jsonEachCursor object has been advanced off the end -** of the JSON object */ -static int jsonEachEof(sqlite3_vtab_cursor *cur){ - JsonEachCursor *p = (JsonEachCursor*)cur; - return p->i >= p->iEnd; -} - -/* Advance the cursor to the next element for json_tree() */ -static int jsonEachNext(sqlite3_vtab_cursor *cur){ - JsonEachCursor *p = (JsonEachCursor*)cur; - if( p->bRecursive ){ - if( p->sParse.aNode[p->i].jnFlags & JNODE_LABEL ) p->i++; - p->i++; - p->iRowid++; - if( p->iiEnd ){ - u32 iUp = p->sParse.aUp[p->i]; - JsonNode *pUp = &p->sParse.aNode[iUp]; - p->eType = pUp->eType; - if( pUp->eType==JSON_ARRAY ){ - if( iUp==p->i-1 ){ - pUp->u.iKey = 0; - }else{ - pUp->u.iKey++; - } - } - } - }else{ - switch( p->eType ){ - case JSON_ARRAY: { - p->i += jsonNodeSize(&p->sParse.aNode[p->i]); - p->iRowid++; - break; - } - case JSON_OBJECT: { - p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]); - p->iRowid++; - break; - } - default: { - p->i = p->iEnd; - break; - } - } - } - return SQLITE_OK; -} - -/* Append the name of the path for element i to pStr -*/ -static void jsonEachComputePath( - JsonEachCursor *p, /* The cursor */ - JsonString *pStr, /* Write the path here */ - u32 i /* Path to this element */ -){ - JsonNode *pNode, *pUp; - u32 iUp; - if( i==0 ){ - jsonAppendChar(pStr, '$'); - return; - } - iUp = p->sParse.aUp[i]; - jsonEachComputePath(p, pStr, iUp); - pNode = &p->sParse.aNode[i]; - pUp = &p->sParse.aNode[iUp]; - if( pUp->eType==JSON_ARRAY ){ - jsonPrintf(30, pStr, "[%d]", pUp->u.iKey); - }else{ - assert( pUp->eType==JSON_OBJECT ); - if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--; - assert( pNode->eType==JSON_STRING ); - assert( pNode->jnFlags & JNODE_LABEL ); - jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1); - } -} - -/* Return the value of a column */ -static int jsonEachColumn( - sqlite3_vtab_cursor *cur, /* The cursor */ - sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ - int i /* Which column to return */ -){ - JsonEachCursor *p = (JsonEachCursor*)cur; - JsonNode *pThis = &p->sParse.aNode[p->i]; - switch( i ){ - case JEACH_KEY: { - if( p->i==0 ) break; - if( p->eType==JSON_OBJECT ){ - jsonReturn(pThis, ctx, 0); - }else if( p->eType==JSON_ARRAY ){ - u32 iKey; - if( p->bRecursive ){ - if( p->iRowid==0 ) break; - iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey; - }else{ - iKey = p->iRowid; - } - sqlite3_result_int64(ctx, (sqlite3_int64)iKey); - } - break; - } - case JEACH_VALUE: { - if( pThis->jnFlags & JNODE_LABEL ) pThis++; - jsonReturn(pThis, ctx, 0); - break; - } - case JEACH_TYPE: { - if( pThis->jnFlags & JNODE_LABEL ) pThis++; - sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC); - break; - } - case JEACH_ATOM: { - if( pThis->jnFlags & JNODE_LABEL ) pThis++; - if( pThis->eType>=JSON_ARRAY ) break; - jsonReturn(pThis, ctx, 0); - break; - } - case JEACH_ID: { - sqlite3_result_int64(ctx, - (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0)); - break; - } - case JEACH_PARENT: { - if( p->i>p->iBegin && p->bRecursive ){ - sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]); - } - break; - } - case JEACH_FULLKEY: { - JsonString x; - jsonInit(&x, ctx); - if( p->bRecursive ){ - jsonEachComputePath(p, &x, p->i); - }else{ - if( p->zRoot ){ - jsonAppendRaw(&x, p->zRoot, (int)strlen(p->zRoot)); - }else{ - jsonAppendChar(&x, '$'); - } - if( p->eType==JSON_ARRAY ){ - jsonPrintf(30, &x, "[%d]", p->iRowid); - }else if( p->eType==JSON_OBJECT ){ - jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1); - } - } - jsonResult(&x); - break; - } - case JEACH_PATH: { - if( p->bRecursive ){ - JsonString x; - jsonInit(&x, ctx); - jsonEachComputePath(p, &x, p->sParse.aUp[p->i]); - jsonResult(&x); - break; - } - /* For json_each() path and root are the same so fall through - ** into the root case */ - } - default: { - const char *zRoot = p->zRoot; - if( zRoot==0 ) zRoot = "$"; - sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC); - break; - } - case JEACH_JSON: { - assert( i==JEACH_JSON ); - sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC); - break; - } - } - return SQLITE_OK; -} - -/* Return the current rowid value */ -static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ - JsonEachCursor *p = (JsonEachCursor*)cur; - *pRowid = p->iRowid; - return SQLITE_OK; -} - -/* The query strategy is to look for an equality constraint on the json -** column. Without such a constraint, the table cannot operate. idxNum is -** 1 if the constraint is found, 3 if the constraint and zRoot are found, -** and 0 otherwise. -*/ -static int jsonEachBestIndex( - sqlite3_vtab *tab, - sqlite3_index_info *pIdxInfo -){ - int i; - int jsonIdx = -1; - int rootIdx = -1; - const struct sqlite3_index_constraint *pConstraint; - - UNUSED_PARAM(tab); - pConstraint = pIdxInfo->aConstraint; - for(i=0; inConstraint; i++, pConstraint++){ - if( pConstraint->usable==0 ) continue; - if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; - switch( pConstraint->iColumn ){ - case JEACH_JSON: jsonIdx = i; break; - case JEACH_ROOT: rootIdx = i; break; - default: /* no-op */ break; - } - } - if( jsonIdx<0 ){ - pIdxInfo->idxNum = 0; - pIdxInfo->estimatedCost = 1e99; - }else{ - pIdxInfo->estimatedCost = 1.0; - pIdxInfo->aConstraintUsage[jsonIdx].argvIndex = 1; - pIdxInfo->aConstraintUsage[jsonIdx].omit = 1; - if( rootIdx<0 ){ - pIdxInfo->idxNum = 1; - }else{ - pIdxInfo->aConstraintUsage[rootIdx].argvIndex = 2; - pIdxInfo->aConstraintUsage[rootIdx].omit = 1; - pIdxInfo->idxNum = 3; - } - } - return SQLITE_OK; -} - -/* Start a search on a new JSON string */ -static int jsonEachFilter( - sqlite3_vtab_cursor *cur, - int idxNum, const char *idxStr, - int argc, sqlite3_value **argv -){ - JsonEachCursor *p = (JsonEachCursor*)cur; - const char *z; - const char *zRoot = 0; - sqlite3_int64 n; - - UNUSED_PARAM(idxStr); - UNUSED_PARAM(argc); - jsonEachCursorReset(p); - if( idxNum==0 ) return SQLITE_OK; - z = (const char*)sqlite3_value_text(argv[0]); - if( z==0 ) return SQLITE_OK; - n = sqlite3_value_bytes(argv[0]); - p->zJson = sqlite3_malloc64( n+1 ); - if( p->zJson==0 ) return SQLITE_NOMEM; - memcpy(p->zJson, z, (size_t)n+1); - if( jsonParse(&p->sParse, 0, p->zJson) ){ - int rc = SQLITE_NOMEM; - if( p->sParse.oom==0 ){ - sqlite3_free(cur->pVtab->zErrMsg); - cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON"); - if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR; - } - jsonEachCursorReset(p); - return rc; - }else if( p->bRecursive && jsonParseFindParents(&p->sParse) ){ - jsonEachCursorReset(p); - return SQLITE_NOMEM; - }else{ - JsonNode *pNode = 0; - if( idxNum==3 ){ - const char *zErr = 0; - zRoot = (const char*)sqlite3_value_text(argv[1]); - if( zRoot==0 ) return SQLITE_OK; - n = sqlite3_value_bytes(argv[1]); - p->zRoot = sqlite3_malloc64( n+1 ); - if( p->zRoot==0 ) return SQLITE_NOMEM; - memcpy(p->zRoot, zRoot, (size_t)n+1); - if( zRoot[0]!='$' ){ - zErr = zRoot; - }else{ - pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr); - } - if( zErr ){ - sqlite3_free(cur->pVtab->zErrMsg); - cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr); - jsonEachCursorReset(p); - return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; - }else if( pNode==0 ){ - return SQLITE_OK; - } - }else{ - pNode = p->sParse.aNode; - } - p->iBegin = p->i = (int)(pNode - p->sParse.aNode); - p->eType = pNode->eType; - if( p->eType>=JSON_ARRAY ){ - pNode->u.iKey = 0; - p->iEnd = p->i + pNode->n + 1; - if( p->bRecursive ){ - p->eType = p->sParse.aNode[p->sParse.aUp[p->i]].eType; - if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){ - p->i--; - } - }else{ - p->i++; - } - }else{ - p->iEnd = p->i+1; - } - } - return SQLITE_OK; -} - -/* The methods of the json_each virtual table */ -static sqlite3_module jsonEachModule = { - 0, /* iVersion */ - 0, /* xCreate */ - jsonEachConnect, /* xConnect */ - jsonEachBestIndex, /* xBestIndex */ - jsonEachDisconnect, /* xDisconnect */ - 0, /* xDestroy */ - jsonEachOpenEach, /* xOpen - open a cursor */ - jsonEachClose, /* xClose - close a cursor */ - jsonEachFilter, /* xFilter - configure scan constraints */ - jsonEachNext, /* xNext - advance a cursor */ - jsonEachEof, /* xEof - check for end of scan */ - jsonEachColumn, /* xColumn - read data */ - jsonEachRowid, /* xRowid - read data */ - 0, /* xUpdate */ - 0, /* xBegin */ - 0, /* xSync */ - 0, /* xCommit */ - 0, /* xRollback */ - 0, /* xFindMethod */ - 0, /* xRename */ - 0, /* xSavepoint */ - 0, /* xRelease */ - 0 /* xRollbackTo */ -}; - -/* The methods of the json_tree virtual table. */ -static sqlite3_module jsonTreeModule = { - 0, /* iVersion */ - 0, /* xCreate */ - jsonEachConnect, /* xConnect */ - jsonEachBestIndex, /* xBestIndex */ - jsonEachDisconnect, /* xDisconnect */ - 0, /* xDestroy */ - jsonEachOpenTree, /* xOpen - open a cursor */ - jsonEachClose, /* xClose - close a cursor */ - jsonEachFilter, /* xFilter - configure scan constraints */ - jsonEachNext, /* xNext - advance a cursor */ - jsonEachEof, /* xEof - check for end of scan */ - jsonEachColumn, /* xColumn - read data */ - jsonEachRowid, /* xRowid - read data */ - 0, /* xUpdate */ - 0, /* xBegin */ - 0, /* xSync */ - 0, /* xCommit */ - 0, /* xRollback */ - 0, /* xFindMethod */ - 0, /* xRename */ - 0, /* xSavepoint */ - 0, /* xRelease */ - 0 /* xRollbackTo */ -}; -#endif /* SQLITE_OMIT_VIRTUALTABLE */ - -/**************************************************************************** -** The following routines are the only publically visible identifiers in this -** file. Call the following routines in order to register the various SQL -** functions and the virtual table implemented by this file. -****************************************************************************/ - -SQLITE_PRIVATE int sqlite3Json1Init(sqlite3 *db){ - int rc = SQLITE_OK; - unsigned int i; - static const struct { - const char *zName; - int nArg; - int flag; - void (*xFunc)(sqlite3_context*,int,sqlite3_value**); - } aFunc[] = { - { "json", 1, 0, jsonRemoveFunc }, - { "json_array", -1, 0, jsonArrayFunc }, - { "json_array_length", 1, 0, jsonArrayLengthFunc }, - { "json_array_length", 2, 0, jsonArrayLengthFunc }, - { "json_extract", -1, 0, jsonExtractFunc }, - { "json_insert", -1, 0, jsonSetFunc }, - { "json_object", -1, 0, jsonObjectFunc }, - { "json_patch", 2, 0, jsonPatchFunc }, - { "json_quote", 1, 0, jsonQuoteFunc }, - { "json_remove", -1, 0, jsonRemoveFunc }, - { "json_replace", -1, 0, jsonReplaceFunc }, - { "json_set", -1, 1, jsonSetFunc }, - { "json_type", 1, 0, jsonTypeFunc }, - { "json_type", 2, 0, jsonTypeFunc }, - { "json_valid", 1, 0, jsonValidFunc }, - -#if SQLITE_DEBUG - /* DEBUG and TESTING functions */ - { "json_parse", 1, 0, jsonParseFunc }, - { "json_test1", 1, 0, jsonTest1Func }, -#endif - }; - static const struct { - const char *zName; - int nArg; - void (*xStep)(sqlite3_context*,int,sqlite3_value**); - void (*xFinal)(sqlite3_context*); - } aAgg[] = { - { "json_group_array", 1, jsonArrayStep, jsonArrayFinal }, - { "json_group_object", 2, jsonObjectStep, jsonObjectFinal }, - }; -#ifndef SQLITE_OMIT_VIRTUALTABLE - static const struct { - const char *zName; - sqlite3_module *pModule; - } aMod[] = { - { "json_each", &jsonEachModule }, - { "json_tree", &jsonTreeModule }, - }; -#endif - for(i=0; i ** @@ -190649,7 +197470,7 @@ struct Fts5ExtensionApi { ** extra data to the FTS index or require FTS5 to query for multiple terms, ** so it is efficient in terms of disk space and query speed. However, it ** does not support prefix queries very well. If, as suggested above, the -** token "first" is subsituted for "1st" by the tokenizer, then the query: +** token "first" is substituted for "1st" by the tokenizer, then the query: ** ** ** ... MATCH '1s*' @@ -191541,9 +198362,12 @@ static int sqlite3Fts5VocabInit(Fts5Global*, sqlite3*); /************************************************************************** ** Interface to automatically generated code in fts5_unicode2.c. */ -static int sqlite3Fts5UnicodeIsalnum(int c); static int sqlite3Fts5UnicodeIsdiacritic(int c); static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic); + +static int sqlite3Fts5UnicodeCatParse(const char*, u8*); +static int sqlite3Fts5UnicodeCategory(int iCode); +static void sqlite3Fts5UnicodeAscii(u8*, u8*); /* ** End of interface to code in fts5_unicode2.c. **************************************************************************/ @@ -191719,6 +198543,7 @@ typedef union { #define fts5YY_MIN_REDUCE 83 #define fts5YY_MAX_REDUCE 110 /************* End control #defines *******************************************/ +#define fts5YY_NLOOKAHEAD ((int)(sizeof(fts5yy_lookahead)/sizeof(fts5yy_lookahead[0]))) /* Define the fts5yytestcase() macro to be a no-op if is not already defined ** otherwise. @@ -192278,11 +199103,11 @@ static fts5YYACTIONTYPE fts5yy_find_shift_action( do{ i = fts5yy_shift_ofst[stateno]; assert( i>=0 ); - assert( i+fts5YYNFTS5TOKEN<=(int)sizeof(fts5yy_lookahead)/sizeof(fts5yy_lookahead[0]) ); + /* assert( i+fts5YYNFTS5TOKEN<=(int)fts5YY_NLOOKAHEAD ); */ assert( iLookAhead!=fts5YYNOCODE ); assert( iLookAhead < fts5YYNFTS5TOKEN ); i += iLookAhead; - if( fts5yy_lookahead[i]!=iLookAhead ){ + if( i>=fts5YY_NLOOKAHEAD || fts5yy_lookahead[i]!=iLookAhead ){ #ifdef fts5YYFALLBACK fts5YYCODETYPE iFallback; /* Fallback token */ if( iLookAhead=fts5YY_ACTTAB_COUNT j0 ){ #ifndef NDEBUG @@ -192332,7 +199158,7 @@ static fts5YYACTIONTYPE fts5yy_find_shift_action( ** Find the appropriate action for a parser given the non-terminal ** look-ahead token iLookAhead. */ -static int fts5yy_find_reduce_action( +static fts5YYACTIONTYPE fts5yy_find_reduce_action( fts5YYACTIONTYPE stateno, /* Current state number */ fts5YYCODETYPE iLookAhead /* The look-ahead token */ ){ @@ -192500,7 +199326,7 @@ static fts5YYACTIONTYPE fts5yy_reduce( sqlite3Fts5ParserCTX_PDECL /* %extra_context */ ){ int fts5yygoto; /* The next state */ - int fts5yyact; /* The next action */ + fts5YYACTIONTYPE fts5yyact; /* The next action */ fts5yyStackEntry *fts5yymsp; /* The top of the parser's stack */ int fts5yysize; /* Amount to pop the stack */ sqlite3Fts5ParserARG_FETCH @@ -192856,12 +199682,12 @@ static void sqlite3Fts5Parser( do{ assert( fts5yyact==fts5yypParser->fts5yytos->stateno ); - fts5yyact = fts5yy_find_shift_action(fts5yymajor,fts5yyact); + fts5yyact = fts5yy_find_shift_action((fts5YYCODETYPE)fts5yymajor,fts5yyact); if( fts5yyact >= fts5YY_MIN_REDUCE ){ fts5yyact = fts5yy_reduce(fts5yypParser,fts5yyact-fts5YY_MIN_REDUCE,fts5yymajor, fts5yyminor sqlite3Fts5ParserCTX_PARAM); }else if( fts5yyact <= fts5YY_MAX_SHIFTREDUCE ){ - fts5yy_shift(fts5yypParser,fts5yyact,fts5yymajor,fts5yyminor); + fts5yy_shift(fts5yypParser,fts5yyact,(fts5YYCODETYPE)fts5yymajor,fts5yyminor); #ifndef fts5YYNOERRORRECOVERY fts5yypParser->fts5yyerrcnt--; #endif @@ -192989,6 +199815,21 @@ static void sqlite3Fts5Parser( return; } +/* +** Return the fallback token corresponding to canonical token iToken, or +** 0 if iToken has no fallback. +*/ +static int sqlite3Fts5ParserFallback(int iToken){ +#ifdef fts5YYFALLBACK + if( iToken<(int)(sizeof(fts5yyFallback)/sizeof(fts5yyFallback[0])) ){ + return fts5yyFallback[iToken]; + } +#else + (void)iToken; +#endif + return 0; +} + /* ** 2014 May 31 ** @@ -195099,6 +201940,7 @@ static void sqlite3Fts5Parser(void*, int, Fts5Token, Fts5Parse*); /* #include */ static void sqlite3Fts5ParserTrace(FILE*, char*); #endif +static int sqlite3Fts5ParserFallback(int); struct Fts5Expr { @@ -197603,14 +204445,19 @@ static void fts5ExprIsAlnum( sqlite3_value **apVal /* Function arguments */ ){ int iCode; + u8 aArr[32]; if( nArg!=1 ){ sqlite3_result_error(pCtx, "wrong number of arguments to function fts5_isalnum", -1 ); return; } + memset(aArr, 0, sizeof(aArr)); + sqlite3Fts5UnicodeCatParse("L*", aArr); + sqlite3Fts5UnicodeCatParse("N*", aArr); + sqlite3Fts5UnicodeCatParse("Co", aArr); iCode = sqlite3_value_int(apVal[0]); - sqlite3_result_int(pCtx, sqlite3Fts5UnicodeIsalnum(iCode)); + sqlite3_result_int(pCtx, aArr[sqlite3Fts5UnicodeCategory(iCode)]); } static void fts5ExprFold( @@ -197654,10 +204501,12 @@ static int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){ rc = sqlite3_create_function(db, p->z, -1, SQLITE_UTF8, pCtx, p->x, 0, 0); } - /* Avoid a warning indicating that sqlite3Fts5ParserTrace() is unused */ + /* Avoid warnings indicating that sqlite3Fts5ParserTrace() and + ** sqlite3Fts5ParserFallback() are unused */ #ifndef NDEBUG (void)sqlite3Fts5ParserTrace; #endif + (void)sqlite3Fts5ParserFallback; return rc; } @@ -203705,7 +210554,10 @@ static int sqlite3Fts5IndexCharlenToBytelen( for(i=0; i=nByte ) return 0; /* Input contains fewer than nChar chars */ if( (unsigned char)p[n++]>=0xc0 ){ - while( (p[n] & 0xc0)==0x80 ) n++; + while( (p[n] & 0xc0)==0x80 ){ + n++; + if( n>=nByte ) break; + } } } return n; @@ -205230,7 +212082,7 @@ static void fts5CheckTransactionState(Fts5Table *p, int op, int iSavepoint){ case FTS5_SAVEPOINT: assert( p->ts.eState==1 ); assert( iSavepoint>=0 ); - assert( iSavepoint>p->ts.iSavepoint ); + assert( iSavepoint>=p->ts.iSavepoint ); p->ts.iSavepoint = iSavepoint; break; @@ -206155,6 +213007,13 @@ static int fts5FilterMethod( assert( nVal==0 && pMatch==0 && bOrderByRank==0 && bDesc==0 ); assert( pCsr->iLastRowid==LARGEST_INT64 ); assert( pCsr->iFirstRowid==SMALLEST_INT64 ); + if( pTab->pSortCsr->bDesc ){ + pCsr->iLastRowid = pTab->pSortCsr->iFirstRowid; + pCsr->iFirstRowid = pTab->pSortCsr->iLastRowid; + }else{ + pCsr->iLastRowid = pTab->pSortCsr->iLastRowid; + pCsr->iFirstRowid = pTab->pSortCsr->iFirstRowid; + } pCsr->ePlan = FTS5_PLAN_SOURCE; pCsr->pExpr = pTab->pSortCsr->pExpr; rc = fts5CursorFirst(pTab, pCsr, bDesc); @@ -207585,7 +214444,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2018-06-04 19:24:41 c7ee0833225bfd8c5ec2f9bf62b97c4e04d03bd9566366d5221ac8fb199a87ca", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2018-09-25 19:08:10 fb90e7189ae6d62e77ba3a308ca5d683f90bbe633cf681865365b8e92792d1c7", -1, SQLITE_TRANSIENT); } static int fts5Init(sqlite3 *db){ @@ -209073,6 +215932,8 @@ struct Unicode61Tokenizer { int bRemoveDiacritic; /* True if remove_diacritics=1 is set */ int nException; int *aiException; + + unsigned char aCategory[32]; /* True for token char categories */ }; static int fts5UnicodeAddExceptions( @@ -209097,7 +215958,7 @@ static int fts5UnicodeAddExceptions( if( iCode<128 ){ p->aTokenChar[iCode] = (unsigned char)bTokenChars; }else{ - bToken = sqlite3Fts5UnicodeIsalnum(iCode); + bToken = p->aCategory[sqlite3Fts5UnicodeCategory(iCode)]; assert( (bToken==0 || bToken==1) ); assert( (bTokenChars==0 || bTokenChars==1) ); if( bToken!=bTokenChars && sqlite3Fts5UnicodeIsdiacritic(iCode)==0 ){ @@ -209158,6 +216019,21 @@ static void fts5UnicodeDelete(Fts5Tokenizer *pTok){ return; } +static int unicodeSetCategories(Unicode61Tokenizer *p, const char *zCat){ + const char *z = zCat; + + while( *z ){ + while( *z==' ' || *z=='\t' ) z++; + if( *z && sqlite3Fts5UnicodeCatParse(z, p->aCategory) ){ + return SQLITE_ERROR; + } + while( *z!=' ' && *z!='\t' && *z!='\0' ) z++; + } + + sqlite3Fts5UnicodeAscii(p->aCategory, p->aTokenChar); + return SQLITE_OK; +} + /* ** Create a "unicode61" tokenizer. */ @@ -209176,15 +216052,28 @@ static int fts5UnicodeCreate( }else{ p = (Unicode61Tokenizer*)sqlite3_malloc(sizeof(Unicode61Tokenizer)); if( p ){ + const char *zCat = "L* N* Co"; int i; memset(p, 0, sizeof(Unicode61Tokenizer)); - memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar)); + p->bRemoveDiacritic = 1; p->nFold = 64; p->aFold = sqlite3_malloc(p->nFold * sizeof(char)); if( p->aFold==0 ){ rc = SQLITE_NOMEM; } + + /* Search for a "categories" argument */ + for(i=0; rc==SQLITE_OK && iaCategory[sqlite3Fts5UnicodeCategory(iCode)] + ^ fts5UnicodeIsException(p, iCode) + ); } static int fts5UnicodeTokenize( @@ -210097,135 +216992,6 @@ static int sqlite3Fts5TokenizerInit(fts5_api *pApi){ /* #include */ -/* -** Return true if the argument corresponds to a unicode codepoint -** classified as either a letter or a number. Otherwise false. -** -** The results are undefined if the value passed to this function -** is less than zero. -*/ -static int sqlite3Fts5UnicodeIsalnum(int c){ - /* Each unsigned integer in the following array corresponds to a contiguous - ** range of unicode codepoints that are not either letters or numbers (i.e. - ** codepoints for which this function should return 0). - ** - ** The most significant 22 bits in each 32-bit value contain the first - ** codepoint in the range. The least significant 10 bits are used to store - ** the size of the range (always at least 1). In other words, the value - ** ((C<<22) + N) represents a range of N codepoints starting with codepoint - ** C. It is not possible to represent a range larger than 1023 codepoints - ** using this format. - */ - static const unsigned int aEntry[] = { - 0x00000030, 0x0000E807, 0x00016C06, 0x0001EC2F, 0x0002AC07, - 0x0002D001, 0x0002D803, 0x0002EC01, 0x0002FC01, 0x00035C01, - 0x0003DC01, 0x000B0804, 0x000B480E, 0x000B9407, 0x000BB401, - 0x000BBC81, 0x000DD401, 0x000DF801, 0x000E1002, 0x000E1C01, - 0x000FD801, 0x00120808, 0x00156806, 0x00162402, 0x00163C01, - 0x00164437, 0x0017CC02, 0x00180005, 0x00181816, 0x00187802, - 0x00192C15, 0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F, - 0x001B9C07, 0x001BF402, 0x001C000E, 0x001C3C01, 0x001C4401, - 0x001CC01B, 0x001E980B, 0x001FAC09, 0x001FD804, 0x00205804, - 0x00206C09, 0x00209403, 0x0020A405, 0x0020C00F, 0x00216403, - 0x00217801, 0x0023901B, 0x00240004, 0x0024E803, 0x0024F812, - 0x00254407, 0x00258804, 0x0025C001, 0x00260403, 0x0026F001, - 0x0026F807, 0x00271C02, 0x00272C03, 0x00275C01, 0x00278802, - 0x0027C802, 0x0027E802, 0x00280403, 0x0028F001, 0x0028F805, - 0x00291C02, 0x00292C03, 0x00294401, 0x0029C002, 0x0029D401, - 0x002A0403, 0x002AF001, 0x002AF808, 0x002B1C03, 0x002B2C03, - 0x002B8802, 0x002BC002, 0x002C0403, 0x002CF001, 0x002CF807, - 0x002D1C02, 0x002D2C03, 0x002D5802, 0x002D8802, 0x002DC001, - 0x002E0801, 0x002EF805, 0x002F1803, 0x002F2804, 0x002F5C01, - 0x002FCC08, 0x00300403, 0x0030F807, 0x00311803, 0x00312804, - 0x00315402, 0x00318802, 0x0031FC01, 0x00320802, 0x0032F001, - 0x0032F807, 0x00331803, 0x00332804, 0x00335402, 0x00338802, - 0x00340802, 0x0034F807, 0x00351803, 0x00352804, 0x00355C01, - 0x00358802, 0x0035E401, 0x00360802, 0x00372801, 0x00373C06, - 0x00375801, 0x00376008, 0x0037C803, 0x0038C401, 0x0038D007, - 0x0038FC01, 0x00391C09, 0x00396802, 0x003AC401, 0x003AD006, - 0x003AEC02, 0x003B2006, 0x003C041F, 0x003CD00C, 0x003DC417, - 0x003E340B, 0x003E6424, 0x003EF80F, 0x003F380D, 0x0040AC14, - 0x00412806, 0x00415804, 0x00417803, 0x00418803, 0x00419C07, - 0x0041C404, 0x0042080C, 0x00423C01, 0x00426806, 0x0043EC01, - 0x004D740C, 0x004E400A, 0x00500001, 0x0059B402, 0x005A0001, - 0x005A6C02, 0x005BAC03, 0x005C4803, 0x005CC805, 0x005D4802, - 0x005DC802, 0x005ED023, 0x005F6004, 0x005F7401, 0x0060000F, - 0x0062A401, 0x0064800C, 0x0064C00C, 0x00650001, 0x00651002, - 0x0066C011, 0x00672002, 0x00677822, 0x00685C05, 0x00687802, - 0x0069540A, 0x0069801D, 0x0069FC01, 0x006A8007, 0x006AA006, - 0x006C0005, 0x006CD011, 0x006D6823, 0x006E0003, 0x006E840D, - 0x006F980E, 0x006FF004, 0x00709014, 0x0070EC05, 0x0071F802, - 0x00730008, 0x00734019, 0x0073B401, 0x0073C803, 0x00770027, - 0x0077F004, 0x007EF401, 0x007EFC03, 0x007F3403, 0x007F7403, - 0x007FB403, 0x007FF402, 0x00800065, 0x0081A806, 0x0081E805, - 0x00822805, 0x0082801A, 0x00834021, 0x00840002, 0x00840C04, - 0x00842002, 0x00845001, 0x00845803, 0x00847806, 0x00849401, - 0x00849C01, 0x0084A401, 0x0084B801, 0x0084E802, 0x00850005, - 0x00852804, 0x00853C01, 0x00864264, 0x00900027, 0x0091000B, - 0x0092704E, 0x00940200, 0x009C0475, 0x009E53B9, 0x00AD400A, - 0x00B39406, 0x00B3BC03, 0x00B3E404, 0x00B3F802, 0x00B5C001, - 0x00B5FC01, 0x00B7804F, 0x00B8C00C, 0x00BA001A, 0x00BA6C59, - 0x00BC00D6, 0x00BFC00C, 0x00C00005, 0x00C02019, 0x00C0A807, - 0x00C0D802, 0x00C0F403, 0x00C26404, 0x00C28001, 0x00C3EC01, - 0x00C64002, 0x00C6580A, 0x00C70024, 0x00C8001F, 0x00C8A81E, - 0x00C94001, 0x00C98020, 0x00CA2827, 0x00CB003F, 0x00CC0100, - 0x01370040, 0x02924037, 0x0293F802, 0x02983403, 0x0299BC10, - 0x029A7C01, 0x029BC008, 0x029C0017, 0x029C8002, 0x029E2402, - 0x02A00801, 0x02A01801, 0x02A02C01, 0x02A08C09, 0x02A0D804, - 0x02A1D004, 0x02A20002, 0x02A2D011, 0x02A33802, 0x02A38012, - 0x02A3E003, 0x02A4980A, 0x02A51C0D, 0x02A57C01, 0x02A60004, - 0x02A6CC1B, 0x02A77802, 0x02A8A40E, 0x02A90C01, 0x02A93002, - 0x02A97004, 0x02A9DC03, 0x02A9EC01, 0x02AAC001, 0x02AAC803, - 0x02AADC02, 0x02AAF802, 0x02AB0401, 0x02AB7802, 0x02ABAC07, - 0x02ABD402, 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02, - 0x037FFC01, 0x03EC7801, 0x03ECA401, 0x03EEC810, 0x03F4F802, - 0x03F7F002, 0x03F8001A, 0x03F88007, 0x03F8C023, 0x03F95013, - 0x03F9A004, 0x03FBFC01, 0x03FC040F, 0x03FC6807, 0x03FCEC06, - 0x03FD6C0B, 0x03FF8007, 0x03FFA007, 0x03FFE405, 0x04040003, - 0x0404DC09, 0x0405E411, 0x0406400C, 0x0407402E, 0x040E7C01, - 0x040F4001, 0x04215C01, 0x04247C01, 0x0424FC01, 0x04280403, - 0x04281402, 0x04283004, 0x0428E003, 0x0428FC01, 0x04294009, - 0x0429FC01, 0x042CE407, 0x04400003, 0x0440E016, 0x04420003, - 0x0442C012, 0x04440003, 0x04449C0E, 0x04450004, 0x04460003, - 0x0446CC0E, 0x04471404, 0x045AAC0D, 0x0491C004, 0x05BD442E, - 0x05BE3C04, 0x074000F6, 0x07440027, 0x0744A4B5, 0x07480046, - 0x074C0057, 0x075B0401, 0x075B6C01, 0x075BEC01, 0x075C5401, - 0x075CD401, 0x075D3C01, 0x075DBC01, 0x075E2401, 0x075EA401, - 0x075F0C01, 0x07BBC002, 0x07C0002C, 0x07C0C064, 0x07C2800F, - 0x07C2C40E, 0x07C3040F, 0x07C3440F, 0x07C4401F, 0x07C4C03C, - 0x07C5C02B, 0x07C7981D, 0x07C8402B, 0x07C90009, 0x07C94002, - 0x07CC0021, 0x07CCC006, 0x07CCDC46, 0x07CE0014, 0x07CE8025, - 0x07CF1805, 0x07CF8011, 0x07D0003F, 0x07D10001, 0x07D108B6, - 0x07D3E404, 0x07D4003E, 0x07D50004, 0x07D54018, 0x07D7EC46, - 0x07D9140B, 0x07DA0046, 0x07DC0074, 0x38000401, 0x38008060, - 0x380400F0, - }; - static const unsigned int aAscii[4] = { - 0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001, - }; - - if( (unsigned int)c<128 ){ - return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 ); - }else if( (unsigned int)c<(1<<22) ){ - unsigned int key = (((unsigned int)c)<<10) | 0x000003FF; - int iRes = 0; - int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1; - int iLo = 0; - while( iHi>=iLo ){ - int iTest = (iHi + iLo) / 2; - if( key >= aEntry[iTest] ){ - iRes = iTest; - iLo = iTest+1; - }else{ - iHi = iTest-1; - } - } - assert( aEntry[0]=aEntry[iRes] ); - return (((unsigned int)c) >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF))); - } - return 1; -} /* @@ -210438,6 +217204,539 @@ static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic){ return ret; } + +#if 0 +static int sqlite3Fts5UnicodeNCat(void) { + return 32; +} +#endif + +static int sqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){ + aArray[0] = 1; + switch( zCat[0] ){ + case 'C': + switch( zCat[1] ){ + case 'c': aArray[1] = 1; break; + case 'f': aArray[2] = 1; break; + case 'n': aArray[3] = 1; break; + case 's': aArray[4] = 1; break; + case 'o': aArray[31] = 1; break; + case '*': + aArray[1] = 1; + aArray[2] = 1; + aArray[3] = 1; + aArray[4] = 1; + aArray[31] = 1; + break; + default: return 1; } + break; + + case 'L': + switch( zCat[1] ){ + case 'l': aArray[5] = 1; break; + case 'm': aArray[6] = 1; break; + case 'o': aArray[7] = 1; break; + case 't': aArray[8] = 1; break; + case 'u': aArray[9] = 1; break; + case 'C': aArray[30] = 1; break; + case '*': + aArray[5] = 1; + aArray[6] = 1; + aArray[7] = 1; + aArray[8] = 1; + aArray[9] = 1; + aArray[30] = 1; + break; + default: return 1; } + break; + + case 'M': + switch( zCat[1] ){ + case 'c': aArray[10] = 1; break; + case 'e': aArray[11] = 1; break; + case 'n': aArray[12] = 1; break; + case '*': + aArray[10] = 1; + aArray[11] = 1; + aArray[12] = 1; + break; + default: return 1; } + break; + + case 'N': + switch( zCat[1] ){ + case 'd': aArray[13] = 1; break; + case 'l': aArray[14] = 1; break; + case 'o': aArray[15] = 1; break; + case '*': + aArray[13] = 1; + aArray[14] = 1; + aArray[15] = 1; + break; + default: return 1; } + break; + + case 'P': + switch( zCat[1] ){ + case 'c': aArray[16] = 1; break; + case 'd': aArray[17] = 1; break; + case 'e': aArray[18] = 1; break; + case 'f': aArray[19] = 1; break; + case 'i': aArray[20] = 1; break; + case 'o': aArray[21] = 1; break; + case 's': aArray[22] = 1; break; + case '*': + aArray[16] = 1; + aArray[17] = 1; + aArray[18] = 1; + aArray[19] = 1; + aArray[20] = 1; + aArray[21] = 1; + aArray[22] = 1; + break; + default: return 1; } + break; + + case 'S': + switch( zCat[1] ){ + case 'c': aArray[23] = 1; break; + case 'k': aArray[24] = 1; break; + case 'm': aArray[25] = 1; break; + case 'o': aArray[26] = 1; break; + case '*': + aArray[23] = 1; + aArray[24] = 1; + aArray[25] = 1; + aArray[26] = 1; + break; + default: return 1; } + break; + + case 'Z': + switch( zCat[1] ){ + case 'l': aArray[27] = 1; break; + case 'p': aArray[28] = 1; break; + case 's': aArray[29] = 1; break; + case '*': + aArray[27] = 1; + aArray[28] = 1; + aArray[29] = 1; + break; + default: return 1; } + break; + + } + return 0; +} + +static u16 aFts5UnicodeBlock[] = { + 0, 1471, 1753, 1760, 1760, 1760, 1760, 1760, 1760, 1760, + 1760, 1760, 1760, 1760, 1760, 1763, 1765, + }; +static u16 aFts5UnicodeMap[] = { + 0, 32, 33, 36, 37, 40, 41, 42, 43, 44, + 45, 46, 48, 58, 60, 63, 65, 91, 92, 93, + 94, 95, 96, 97, 123, 124, 125, 126, 127, 160, + 161, 162, 166, 167, 168, 169, 170, 171, 172, 173, + 174, 175, 176, 177, 178, 180, 181, 182, 184, 185, + 186, 187, 188, 191, 192, 215, 216, 223, 247, 248, + 256, 312, 313, 329, 330, 377, 383, 385, 387, 388, + 391, 394, 396, 398, 402, 403, 405, 406, 409, 412, + 414, 415, 417, 418, 423, 427, 428, 431, 434, 436, + 437, 440, 442, 443, 444, 446, 448, 452, 453, 454, + 455, 456, 457, 458, 459, 460, 461, 477, 478, 496, + 497, 498, 499, 500, 503, 505, 506, 564, 570, 572, + 573, 575, 577, 580, 583, 584, 592, 660, 661, 688, + 706, 710, 722, 736, 741, 748, 749, 750, 751, 768, + 880, 884, 885, 886, 890, 891, 894, 900, 902, 903, + 904, 908, 910, 912, 913, 931, 940, 975, 977, 978, + 981, 984, 1008, 1012, 1014, 1015, 1018, 1020, 1021, 1072, + 1120, 1154, 1155, 1160, 1162, 1217, 1231, 1232, 1329, 1369, + 1370, 1377, 1417, 1418, 1423, 1425, 1470, 1471, 1472, 1473, + 1475, 1476, 1478, 1479, 1488, 1520, 1523, 1536, 1542, 1545, + 1547, 1548, 1550, 1552, 1563, 1566, 1568, 1600, 1601, 1611, + 1632, 1642, 1646, 1648, 1649, 1748, 1749, 1750, 1757, 1758, + 1759, 1765, 1767, 1769, 1770, 1774, 1776, 1786, 1789, 1791, + 1792, 1807, 1808, 1809, 1810, 1840, 1869, 1958, 1969, 1984, + 1994, 2027, 2036, 2038, 2039, 2042, 2048, 2070, 2074, 2075, + 2084, 2085, 2088, 2089, 2096, 2112, 2137, 2142, 2208, 2210, + 2276, 2304, 2307, 2308, 2362, 2363, 2364, 2365, 2366, 2369, + 2377, 2381, 2382, 2384, 2385, 2392, 2402, 2404, 2406, 2416, + 2417, 2418, 2425, 2433, 2434, 2437, 2447, 2451, 2474, 2482, + 2486, 2492, 2493, 2494, 2497, 2503, 2507, 2509, 2510, 2519, + 2524, 2527, 2530, 2534, 2544, 2546, 2548, 2554, 2555, 2561, + 2563, 2565, 2575, 2579, 2602, 2610, 2613, 2616, 2620, 2622, + 2625, 2631, 2635, 2641, 2649, 2654, 2662, 2672, 2674, 2677, + 2689, 2691, 2693, 2703, 2707, 2730, 2738, 2741, 2748, 2749, + 2750, 2753, 2759, 2761, 2763, 2765, 2768, 2784, 2786, 2790, + 2800, 2801, 2817, 2818, 2821, 2831, 2835, 2858, 2866, 2869, + 2876, 2877, 2878, 2879, 2880, 2881, 2887, 2891, 2893, 2902, + 2903, 2908, 2911, 2914, 2918, 2928, 2929, 2930, 2946, 2947, + 2949, 2958, 2962, 2969, 2972, 2974, 2979, 2984, 2990, 3006, + 3008, 3009, 3014, 3018, 3021, 3024, 3031, 3046, 3056, 3059, + 3065, 3066, 3073, 3077, 3086, 3090, 3114, 3125, 3133, 3134, + 3137, 3142, 3146, 3157, 3160, 3168, 3170, 3174, 3192, 3199, + 3202, 3205, 3214, 3218, 3242, 3253, 3260, 3261, 3262, 3263, + 3264, 3270, 3271, 3274, 3276, 3285, 3294, 3296, 3298, 3302, + 3313, 3330, 3333, 3342, 3346, 3389, 3390, 3393, 3398, 3402, + 3405, 3406, 3415, 3424, 3426, 3430, 3440, 3449, 3450, 3458, + 3461, 3482, 3507, 3517, 3520, 3530, 3535, 3538, 3542, 3544, + 3570, 3572, 3585, 3633, 3634, 3636, 3647, 3648, 3654, 3655, + 3663, 3664, 3674, 3713, 3716, 3719, 3722, 3725, 3732, 3737, + 3745, 3749, 3751, 3754, 3757, 3761, 3762, 3764, 3771, 3773, + 3776, 3782, 3784, 3792, 3804, 3840, 3841, 3844, 3859, 3860, + 3861, 3864, 3866, 3872, 3882, 3892, 3893, 3894, 3895, 3896, + 3897, 3898, 3899, 3900, 3901, 3902, 3904, 3913, 3953, 3967, + 3968, 3973, 3974, 3976, 3981, 3993, 4030, 4038, 4039, 4046, + 4048, 4053, 4057, 4096, 4139, 4141, 4145, 4146, 4152, 4153, + 4155, 4157, 4159, 4160, 4170, 4176, 4182, 4184, 4186, 4190, + 4193, 4194, 4197, 4199, 4206, 4209, 4213, 4226, 4227, 4229, + 4231, 4237, 4238, 4239, 4240, 4250, 4253, 4254, 4256, 4295, + 4301, 4304, 4347, 4348, 4349, 4682, 4688, 4696, 4698, 4704, + 4746, 4752, 4786, 4792, 4800, 4802, 4808, 4824, 4882, 4888, + 4957, 4960, 4969, 4992, 5008, 5024, 5120, 5121, 5741, 5743, + 5760, 5761, 5787, 5788, 5792, 5867, 5870, 5888, 5902, 5906, + 5920, 5938, 5941, 5952, 5970, 5984, 5998, 6002, 6016, 6068, + 6070, 6071, 6078, 6086, 6087, 6089, 6100, 6103, 6104, 6107, + 6108, 6109, 6112, 6128, 6144, 6150, 6151, 6155, 6158, 6160, + 6176, 6211, 6212, 6272, 6313, 6314, 6320, 6400, 6432, 6435, + 6439, 6441, 6448, 6450, 6451, 6457, 6464, 6468, 6470, 6480, + 6512, 6528, 6576, 6593, 6600, 6608, 6618, 6622, 6656, 6679, + 6681, 6686, 6688, 6741, 6742, 6743, 6744, 6752, 6753, 6754, + 6755, 6757, 6765, 6771, 6783, 6784, 6800, 6816, 6823, 6824, + 6912, 6916, 6917, 6964, 6965, 6966, 6971, 6972, 6973, 6978, + 6979, 6981, 6992, 7002, 7009, 7019, 7028, 7040, 7042, 7043, + 7073, 7074, 7078, 7080, 7082, 7083, 7084, 7086, 7088, 7098, + 7142, 7143, 7144, 7146, 7149, 7150, 7151, 7154, 7164, 7168, + 7204, 7212, 7220, 7222, 7227, 7232, 7245, 7248, 7258, 7288, + 7294, 7360, 7376, 7379, 7380, 7393, 7394, 7401, 7405, 7406, + 7410, 7412, 7413, 7424, 7468, 7531, 7544, 7545, 7579, 7616, + 7676, 7680, 7830, 7838, 7936, 7944, 7952, 7960, 7968, 7976, + 7984, 7992, 8000, 8008, 8016, 8025, 8027, 8029, 8031, 8033, + 8040, 8048, 8064, 8072, 8080, 8088, 8096, 8104, 8112, 8118, + 8120, 8124, 8125, 8126, 8127, 8130, 8134, 8136, 8140, 8141, + 8144, 8150, 8152, 8157, 8160, 8168, 8173, 8178, 8182, 8184, + 8188, 8189, 8192, 8203, 8208, 8214, 8216, 8217, 8218, 8219, + 8221, 8222, 8223, 8224, 8232, 8233, 8234, 8239, 8240, 8249, + 8250, 8251, 8255, 8257, 8260, 8261, 8262, 8263, 8274, 8275, + 8276, 8277, 8287, 8288, 8298, 8304, 8305, 8308, 8314, 8317, + 8318, 8319, 8320, 8330, 8333, 8334, 8336, 8352, 8400, 8413, + 8417, 8418, 8421, 8448, 8450, 8451, 8455, 8456, 8458, 8459, + 8462, 8464, 8467, 8468, 8469, 8470, 8472, 8473, 8478, 8484, + 8485, 8486, 8487, 8488, 8489, 8490, 8494, 8495, 8496, 8500, + 8501, 8505, 8506, 8508, 8510, 8512, 8517, 8519, 8522, 8523, + 8524, 8526, 8527, 8528, 8544, 8579, 8581, 8585, 8592, 8597, + 8602, 8604, 8608, 8609, 8611, 8612, 8614, 8615, 8622, 8623, + 8654, 8656, 8658, 8659, 8660, 8661, 8692, 8960, 8968, 8972, + 8992, 8994, 9001, 9002, 9003, 9084, 9085, 9115, 9140, 9180, + 9186, 9216, 9280, 9312, 9372, 9450, 9472, 9655, 9656, 9665, + 9666, 9720, 9728, 9839, 9840, 9985, 10088, 10089, 10090, 10091, + 10092, 10093, 10094, 10095, 10096, 10097, 10098, 10099, 10100, 10101, + 10102, 10132, 10176, 10181, 10182, 10183, 10214, 10215, 10216, 10217, + 10218, 10219, 10220, 10221, 10222, 10223, 10224, 10240, 10496, 10627, + 10628, 10629, 10630, 10631, 10632, 10633, 10634, 10635, 10636, 10637, + 10638, 10639, 10640, 10641, 10642, 10643, 10644, 10645, 10646, 10647, + 10648, 10649, 10712, 10713, 10714, 10715, 10716, 10748, 10749, 10750, + 11008, 11056, 11077, 11079, 11088, 11264, 11312, 11360, 11363, 11365, + 11367, 11374, 11377, 11378, 11380, 11381, 11383, 11388, 11390, 11393, + 11394, 11492, 11493, 11499, 11503, 11506, 11513, 11517, 11518, 11520, + 11559, 11565, 11568, 11631, 11632, 11647, 11648, 11680, 11688, 11696, + 11704, 11712, 11720, 11728, 11736, 11744, 11776, 11778, 11779, 11780, + 11781, 11782, 11785, 11786, 11787, 11788, 11789, 11790, 11799, 11800, + 11802, 11803, 11804, 11805, 11806, 11808, 11809, 11810, 11811, 11812, + 11813, 11814, 11815, 11816, 11817, 11818, 11823, 11824, 11834, 11904, + 11931, 12032, 12272, 12288, 12289, 12292, 12293, 12294, 12295, 12296, + 12297, 12298, 12299, 12300, 12301, 12302, 12303, 12304, 12305, 12306, + 12308, 12309, 12310, 12311, 12312, 12313, 12314, 12315, 12316, 12317, + 12318, 12320, 12321, 12330, 12334, 12336, 12337, 12342, 12344, 12347, + 12348, 12349, 12350, 12353, 12441, 12443, 12445, 12447, 12448, 12449, + 12539, 12540, 12543, 12549, 12593, 12688, 12690, 12694, 12704, 12736, + 12784, 12800, 12832, 12842, 12872, 12880, 12881, 12896, 12928, 12938, + 12977, 12992, 13056, 13312, 19893, 19904, 19968, 40908, 40960, 40981, + 40982, 42128, 42192, 42232, 42238, 42240, 42508, 42509, 42512, 42528, + 42538, 42560, 42606, 42607, 42608, 42611, 42612, 42622, 42623, 42624, + 42655, 42656, 42726, 42736, 42738, 42752, 42775, 42784, 42786, 42800, + 42802, 42864, 42865, 42873, 42878, 42888, 42889, 42891, 42896, 42912, + 43000, 43002, 43003, 43010, 43011, 43014, 43015, 43019, 43020, 43043, + 43045, 43047, 43048, 43056, 43062, 43064, 43065, 43072, 43124, 43136, + 43138, 43188, 43204, 43214, 43216, 43232, 43250, 43256, 43259, 43264, + 43274, 43302, 43310, 43312, 43335, 43346, 43359, 43360, 43392, 43395, + 43396, 43443, 43444, 43446, 43450, 43452, 43453, 43457, 43471, 43472, + 43486, 43520, 43561, 43567, 43569, 43571, 43573, 43584, 43587, 43588, + 43596, 43597, 43600, 43612, 43616, 43632, 43633, 43639, 43642, 43643, + 43648, 43696, 43697, 43698, 43701, 43703, 43705, 43710, 43712, 43713, + 43714, 43739, 43741, 43742, 43744, 43755, 43756, 43758, 43760, 43762, + 43763, 43765, 43766, 43777, 43785, 43793, 43808, 43816, 43968, 44003, + 44005, 44006, 44008, 44009, 44011, 44012, 44013, 44016, 44032, 55203, + 55216, 55243, 55296, 56191, 56319, 57343, 57344, 63743, 63744, 64112, + 64256, 64275, 64285, 64286, 64287, 64297, 64298, 64312, 64318, 64320, + 64323, 64326, 64434, 64467, 64830, 64831, 64848, 64914, 65008, 65020, + 65021, 65024, 65040, 65047, 65048, 65049, 65056, 65072, 65073, 65075, + 65077, 65078, 65079, 65080, 65081, 65082, 65083, 65084, 65085, 65086, + 65087, 65088, 65089, 65090, 65091, 65092, 65093, 65095, 65096, 65097, + 65101, 65104, 65108, 65112, 65113, 65114, 65115, 65116, 65117, 65118, + 65119, 65122, 65123, 65124, 65128, 65129, 65130, 65136, 65142, 65279, + 65281, 65284, 65285, 65288, 65289, 65290, 65291, 65292, 65293, 65294, + 65296, 65306, 65308, 65311, 65313, 65339, 65340, 65341, 65342, 65343, + 65344, 65345, 65371, 65372, 65373, 65374, 65375, 65376, 65377, 65378, + 65379, 65380, 65382, 65392, 65393, 65438, 65440, 65474, 65482, 65490, + 65498, 65504, 65506, 65507, 65508, 65509, 65512, 65513, 65517, 65529, + 65532, 0, 13, 40, 60, 63, 80, 128, 256, 263, + 311, 320, 373, 377, 394, 400, 464, 509, 640, 672, + 768, 800, 816, 833, 834, 842, 896, 927, 928, 968, + 976, 977, 1024, 1064, 1104, 1184, 2048, 2056, 2058, 2103, + 2108, 2111, 2135, 2136, 2304, 2326, 2335, 2336, 2367, 2432, + 2494, 2560, 2561, 2565, 2572, 2576, 2581, 2585, 2616, 2623, + 2624, 2640, 2656, 2685, 2687, 2816, 2873, 2880, 2904, 2912, + 2936, 3072, 3680, 4096, 4097, 4098, 4099, 4152, 4167, 4178, + 4198, 4224, 4226, 4227, 4272, 4275, 4279, 4281, 4283, 4285, + 4286, 4304, 4336, 4352, 4355, 4391, 4396, 4397, 4406, 4416, + 4480, 4482, 4483, 4531, 4534, 4543, 4545, 4549, 4560, 5760, + 5803, 5804, 5805, 5806, 5808, 5814, 5815, 5824, 8192, 9216, + 9328, 12288, 26624, 28416, 28496, 28497, 28559, 28563, 45056, 53248, + 53504, 53545, 53605, 53607, 53610, 53613, 53619, 53627, 53635, 53637, + 53644, 53674, 53678, 53760, 53826, 53829, 54016, 54112, 54272, 54298, + 54324, 54350, 54358, 54376, 54402, 54428, 54430, 54434, 54437, 54441, + 54446, 54454, 54459, 54461, 54469, 54480, 54506, 54532, 54535, 54541, + 54550, 54558, 54584, 54587, 54592, 54598, 54602, 54610, 54636, 54662, + 54688, 54714, 54740, 54766, 54792, 54818, 54844, 54870, 54896, 54922, + 54952, 54977, 54978, 55003, 55004, 55010, 55035, 55036, 55061, 55062, + 55068, 55093, 55094, 55119, 55120, 55126, 55151, 55152, 55177, 55178, + 55184, 55209, 55210, 55235, 55236, 55242, 55246, 60928, 60933, 60961, + 60964, 60967, 60969, 60980, 60985, 60987, 60994, 60999, 61001, 61003, + 61005, 61009, 61012, 61015, 61017, 61019, 61021, 61023, 61025, 61028, + 61031, 61036, 61044, 61049, 61054, 61056, 61067, 61089, 61093, 61099, + 61168, 61440, 61488, 61600, 61617, 61633, 61649, 61696, 61712, 61744, + 61808, 61926, 61968, 62016, 62032, 62208, 62256, 62263, 62336, 62368, + 62406, 62432, 62464, 62528, 62530, 62713, 62720, 62784, 62800, 62971, + 63045, 63104, 63232, 0, 42710, 42752, 46900, 46912, 47133, 63488, + 1, 32, 256, 0, 65533, + }; +static u16 aFts5UnicodeData[] = { + 1025, 61, 117, 55, 117, 54, 50, 53, 57, 53, + 49, 85, 333, 85, 121, 85, 841, 54, 53, 50, + 56, 48, 56, 837, 54, 57, 50, 57, 1057, 61, + 53, 151, 58, 53, 56, 58, 39, 52, 57, 34, + 58, 56, 58, 57, 79, 56, 37, 85, 56, 47, + 39, 51, 111, 53, 745, 57, 233, 773, 57, 261, + 1822, 37, 542, 37, 1534, 222, 69, 73, 37, 126, + 126, 73, 69, 137, 37, 73, 37, 105, 101, 73, + 37, 73, 37, 190, 158, 37, 126, 126, 73, 37, + 126, 94, 37, 39, 94, 69, 135, 41, 40, 37, + 41, 40, 37, 41, 40, 37, 542, 37, 606, 37, + 41, 40, 37, 126, 73, 37, 1886, 197, 73, 37, + 73, 69, 126, 105, 37, 286, 2181, 39, 869, 582, + 152, 390, 472, 166, 248, 38, 56, 38, 568, 3596, + 158, 38, 56, 94, 38, 101, 53, 88, 41, 53, + 105, 41, 73, 37, 553, 297, 1125, 94, 37, 105, + 101, 798, 133, 94, 57, 126, 94, 37, 1641, 1541, + 1118, 58, 172, 75, 1790, 478, 37, 2846, 1225, 38, + 213, 1253, 53, 49, 55, 1452, 49, 44, 53, 76, + 53, 76, 53, 44, 871, 103, 85, 162, 121, 85, + 55, 85, 90, 364, 53, 85, 1031, 38, 327, 684, + 333, 149, 71, 44, 3175, 53, 39, 236, 34, 58, + 204, 70, 76, 58, 140, 71, 333, 103, 90, 39, + 469, 34, 39, 44, 967, 876, 2855, 364, 39, 333, + 1063, 300, 70, 58, 117, 38, 711, 140, 38, 300, + 38, 108, 38, 172, 501, 807, 108, 53, 39, 359, + 876, 108, 42, 1735, 44, 42, 44, 39, 106, 268, + 138, 44, 74, 39, 236, 327, 76, 85, 333, 53, + 38, 199, 231, 44, 74, 263, 71, 711, 231, 39, + 135, 44, 39, 106, 140, 74, 74, 44, 39, 42, + 71, 103, 76, 333, 71, 87, 207, 58, 55, 76, + 42, 199, 71, 711, 231, 71, 71, 71, 44, 106, + 76, 76, 108, 44, 135, 39, 333, 76, 103, 44, + 76, 42, 295, 103, 711, 231, 71, 167, 44, 39, + 106, 172, 76, 42, 74, 44, 39, 71, 76, 333, + 53, 55, 44, 74, 263, 71, 711, 231, 71, 167, + 44, 39, 42, 44, 42, 140, 74, 74, 44, 44, + 42, 71, 103, 76, 333, 58, 39, 207, 44, 39, + 199, 103, 135, 71, 39, 71, 71, 103, 391, 74, + 44, 74, 106, 106, 44, 39, 42, 333, 111, 218, + 55, 58, 106, 263, 103, 743, 327, 167, 39, 108, + 138, 108, 140, 76, 71, 71, 76, 333, 239, 58, + 74, 263, 103, 743, 327, 167, 44, 39, 42, 44, + 170, 44, 74, 74, 76, 74, 39, 71, 76, 333, + 71, 74, 263, 103, 1319, 39, 106, 140, 106, 106, + 44, 39, 42, 71, 76, 333, 207, 58, 199, 74, + 583, 775, 295, 39, 231, 44, 106, 108, 44, 266, + 74, 53, 1543, 44, 71, 236, 55, 199, 38, 268, + 53, 333, 85, 71, 39, 71, 39, 39, 135, 231, + 103, 39, 39, 71, 135, 44, 71, 204, 76, 39, + 167, 38, 204, 333, 135, 39, 122, 501, 58, 53, + 122, 76, 218, 333, 335, 58, 44, 58, 44, 58, + 44, 54, 50, 54, 50, 74, 263, 1159, 460, 42, + 172, 53, 76, 167, 364, 1164, 282, 44, 218, 90, + 181, 154, 85, 1383, 74, 140, 42, 204, 42, 76, + 74, 76, 39, 333, 213, 199, 74, 76, 135, 108, + 39, 106, 71, 234, 103, 140, 423, 44, 74, 76, + 202, 44, 39, 42, 333, 106, 44, 90, 1225, 41, + 41, 1383, 53, 38, 10631, 135, 231, 39, 135, 1319, + 135, 1063, 135, 231, 39, 135, 487, 1831, 135, 2151, + 108, 309, 655, 519, 346, 2727, 49, 19847, 85, 551, + 61, 839, 54, 50, 2407, 117, 110, 423, 135, 108, + 583, 108, 85, 583, 76, 423, 103, 76, 1671, 76, + 42, 236, 266, 44, 74, 364, 117, 38, 117, 55, + 39, 44, 333, 335, 213, 49, 149, 108, 61, 333, + 1127, 38, 1671, 1319, 44, 39, 2247, 935, 108, 138, + 76, 106, 74, 44, 202, 108, 58, 85, 333, 967, + 167, 1415, 554, 231, 74, 333, 47, 1114, 743, 76, + 106, 85, 1703, 42, 44, 42, 236, 44, 42, 44, + 74, 268, 202, 332, 44, 333, 333, 245, 38, 213, + 140, 42, 1511, 44, 42, 172, 42, 44, 170, 44, + 74, 231, 333, 245, 346, 300, 314, 76, 42, 967, + 42, 140, 74, 76, 42, 44, 74, 71, 333, 1415, + 44, 42, 76, 106, 44, 42, 108, 74, 149, 1159, + 266, 268, 74, 76, 181, 333, 103, 333, 967, 198, + 85, 277, 108, 53, 428, 42, 236, 135, 44, 135, + 74, 44, 71, 1413, 2022, 421, 38, 1093, 1190, 1260, + 140, 4830, 261, 3166, 261, 265, 197, 201, 261, 265, + 261, 265, 197, 201, 261, 41, 41, 41, 94, 229, + 265, 453, 261, 264, 261, 264, 261, 264, 165, 69, + 137, 40, 56, 37, 120, 101, 69, 137, 40, 120, + 133, 69, 137, 120, 261, 169, 120, 101, 69, 137, + 40, 88, 381, 162, 209, 85, 52, 51, 54, 84, + 51, 54, 52, 277, 59, 60, 162, 61, 309, 52, + 51, 149, 80, 117, 57, 54, 50, 373, 57, 53, + 48, 341, 61, 162, 194, 47, 38, 207, 121, 54, + 50, 38, 335, 121, 54, 50, 422, 855, 428, 139, + 44, 107, 396, 90, 41, 154, 41, 90, 37, 105, + 69, 105, 37, 58, 41, 90, 57, 169, 218, 41, + 58, 41, 58, 41, 58, 137, 58, 37, 137, 37, + 135, 37, 90, 69, 73, 185, 94, 101, 58, 57, + 90, 37, 58, 527, 1134, 94, 142, 47, 185, 186, + 89, 154, 57, 90, 57, 90, 57, 250, 57, 1018, + 89, 90, 57, 58, 57, 1018, 8601, 282, 153, 666, + 89, 250, 54, 50, 2618, 57, 986, 825, 1306, 217, + 602, 1274, 378, 1935, 2522, 719, 5882, 57, 314, 57, + 1754, 281, 3578, 57, 4634, 3322, 54, 50, 54, 50, + 54, 50, 54, 50, 54, 50, 54, 50, 54, 50, + 975, 1434, 185, 54, 50, 1017, 54, 50, 54, 50, + 54, 50, 54, 50, 54, 50, 537, 8218, 4217, 54, + 50, 54, 50, 54, 50, 54, 50, 54, 50, 54, + 50, 54, 50, 54, 50, 54, 50, 54, 50, 54, + 50, 2041, 54, 50, 54, 50, 1049, 54, 50, 8281, + 1562, 697, 90, 217, 346, 1513, 1509, 126, 73, 69, + 254, 105, 37, 94, 37, 94, 165, 70, 105, 37, + 3166, 37, 218, 158, 108, 94, 149, 47, 85, 1221, + 37, 37, 1799, 38, 53, 44, 743, 231, 231, 231, + 231, 231, 231, 231, 231, 1036, 85, 52, 51, 52, + 51, 117, 52, 51, 53, 52, 51, 309, 49, 85, + 49, 53, 52, 51, 85, 52, 51, 54, 50, 54, + 50, 54, 50, 54, 50, 181, 38, 341, 81, 858, + 2874, 6874, 410, 61, 117, 58, 38, 39, 46, 54, + 50, 54, 50, 54, 50, 54, 50, 54, 50, 90, + 54, 50, 54, 50, 54, 50, 54, 50, 49, 54, + 82, 58, 302, 140, 74, 49, 166, 90, 110, 38, + 39, 53, 90, 2759, 76, 88, 70, 39, 49, 2887, + 53, 102, 39, 1319, 3015, 90, 143, 346, 871, 1178, + 519, 1018, 335, 986, 271, 58, 495, 1050, 335, 1274, + 495, 2042, 8218, 39, 39, 2074, 39, 39, 679, 38, + 36583, 1786, 1287, 198, 85, 8583, 38, 117, 519, 333, + 71, 1502, 39, 44, 107, 53, 332, 53, 38, 798, + 44, 2247, 334, 76, 213, 760, 294, 88, 478, 69, + 2014, 38, 261, 190, 350, 38, 88, 158, 158, 382, + 70, 37, 231, 44, 103, 44, 135, 44, 743, 74, + 76, 42, 154, 207, 90, 55, 58, 1671, 149, 74, + 1607, 522, 44, 85, 333, 588, 199, 117, 39, 333, + 903, 268, 85, 743, 364, 74, 53, 935, 108, 42, + 1511, 44, 74, 140, 74, 44, 138, 437, 38, 333, + 85, 1319, 204, 74, 76, 74, 76, 103, 44, 263, + 44, 42, 333, 149, 519, 38, 199, 122, 39, 42, + 1543, 44, 39, 108, 71, 76, 167, 76, 39, 44, + 39, 71, 38, 85, 359, 42, 76, 74, 85, 39, + 70, 42, 44, 199, 199, 199, 231, 231, 1127, 74, + 44, 74, 44, 74, 53, 42, 44, 333, 39, 39, + 743, 1575, 36, 68, 68, 36, 63, 63, 11719, 3399, + 229, 165, 39, 44, 327, 57, 423, 167, 39, 71, + 71, 3463, 536, 11623, 54, 50, 2055, 1735, 391, 55, + 58, 524, 245, 54, 50, 53, 236, 53, 81, 80, + 54, 50, 54, 50, 54, 50, 54, 50, 54, 50, + 54, 50, 54, 50, 54, 50, 85, 54, 50, 149, + 112, 117, 149, 49, 54, 50, 54, 50, 54, 50, + 117, 57, 49, 121, 53, 55, 85, 167, 4327, 34, + 117, 55, 117, 54, 50, 53, 57, 53, 49, 85, + 333, 85, 121, 85, 841, 54, 53, 50, 56, 48, + 56, 837, 54, 57, 50, 57, 54, 50, 53, 54, + 50, 85, 327, 38, 1447, 70, 999, 199, 199, 199, + 103, 87, 57, 56, 58, 87, 58, 153, 90, 98, + 90, 391, 839, 615, 71, 487, 455, 3943, 117, 1455, + 314, 1710, 143, 570, 47, 410, 1466, 44, 935, 1575, + 999, 143, 551, 46, 263, 46, 967, 53, 1159, 263, + 53, 174, 1289, 1285, 2503, 333, 199, 39, 1415, 71, + 39, 743, 53, 271, 711, 207, 53, 839, 53, 1799, + 71, 39, 108, 76, 140, 135, 103, 871, 108, 44, + 271, 309, 935, 79, 53, 1735, 245, 711, 271, 615, + 271, 2343, 1007, 42, 44, 42, 1703, 492, 245, 655, + 333, 76, 42, 1447, 106, 140, 74, 76, 85, 34, + 149, 807, 333, 108, 1159, 172, 42, 268, 333, 149, + 76, 42, 1543, 106, 300, 74, 135, 149, 333, 1383, + 44, 42, 44, 74, 204, 42, 44, 333, 28135, 3182, + 149, 34279, 18215, 2215, 39, 1482, 140, 422, 71, 7898, + 1274, 1946, 74, 108, 122, 202, 258, 268, 90, 236, + 986, 140, 1562, 2138, 108, 58, 2810, 591, 841, 837, + 841, 229, 581, 841, 837, 41, 73, 41, 73, 137, + 265, 133, 37, 229, 357, 841, 837, 73, 137, 265, + 233, 837, 73, 137, 169, 41, 233, 837, 841, 837, + 841, 837, 841, 837, 841, 837, 841, 837, 841, 901, + 809, 57, 805, 57, 197, 809, 57, 805, 57, 197, + 809, 57, 805, 57, 197, 809, 57, 805, 57, 197, + 809, 57, 805, 57, 197, 94, 1613, 135, 871, 71, + 39, 39, 327, 135, 39, 39, 39, 39, 39, 39, + 103, 71, 39, 39, 39, 39, 39, 39, 71, 39, + 135, 231, 135, 135, 39, 327, 551, 103, 167, 551, + 89, 1434, 3226, 506, 474, 506, 506, 367, 1018, 1946, + 1402, 954, 1402, 314, 90, 1082, 218, 2266, 666, 1210, + 186, 570, 2042, 58, 5850, 154, 2010, 154, 794, 2266, + 378, 2266, 3738, 39, 39, 39, 39, 39, 39, 17351, + 34, 3074, 7692, 63, 63, + }; + +static int sqlite3Fts5UnicodeCategory(int iCode) { + int iRes = -1; + int iHi; + int iLo; + int ret; + u16 iKey; + + if( iCode>=(1<<20) ){ + return 0; + } + iLo = aFts5UnicodeBlock[(iCode>>16)]; + iHi = aFts5UnicodeBlock[1+(iCode>>16)]; + iKey = (iCode & 0xFFFF); + while( iHi>iLo ){ + int iTest = (iHi + iLo) / 2; + assert( iTest>=iLo && iTest=aFts5UnicodeMap[iTest] ){ + iRes = iTest; + iLo = iTest+1; + }else{ + iHi = iTest; + } + } + + if( iRes<0 ) return 0; + if( iKey>=(aFts5UnicodeMap[iRes]+(aFts5UnicodeData[iRes]>>5)) ) return 0; + ret = aFts5UnicodeData[iRes] & 0x1F; + if( ret!=30 ) return ret; + return ((iKey - aFts5UnicodeMap[iRes]) & 0x01) ? 5 : 9; +} + +static void sqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){ + int i = 0; + int iTbl = 0; + while( i<128 ){ + int bToken = aArray[ aFts5UnicodeData[iTbl] & 0x1F ]; + int n = (aFts5UnicodeData[iTbl] >> 5) + i; + for(; i<128 && i[[SQLITE_FCNTL_PERSIST_WAL]] ** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the ** persistent [WAL | Write Ahead Log] setting. By default, the auxiliary -** write ahead log and shared memory files used for transaction control +** write ahead log ([WAL file]) and shared memory +** files used for transaction control ** are automatically deleted when the latest connection to the database ** closes. Setting persistent WAL mode causes those files to persist after ** close. Persisting the files is useful when other processes that do not @@ -1072,6 +1075,26 @@ struct sqlite3_io_methods { ** a file lock using the xLock or xShmLock methods of the VFS to wait ** for up to M milliseconds before failing, where M is the single ** unsigned integer parameter. +** +**
  • [[SQLITE_FCNTL_DATA_VERSION]] +** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to +** a database file. The argument is a pointer to a 32-bit unsigned integer. +** The "data version" for the pager is written into the pointer. The +** "data version" changes whenever any change occurs to the corresponding +** database file, either through SQL statements on the same database +** connection or through transactions committed by separate database +** connections possibly in other processes. The [sqlite3_total_changes()] +** interface can be used to find if any database on the connection has changed, +** but that interface responds to changes on TEMP as well as MAIN and does +** not provide a mechanism to detect changes to MAIN only. Also, the +** [sqlite3_total_changes()] interface responds to internal changes only and +** omits changes made by other database connections. The +** [PRAGMA data_version] command provide a mechanism to detect changes to +** a single attached database that occur due to other database connections, +** but omits changes implemented by the database connection on which it is +** called. This file control is the only mechanism to detect changes that +** happen either internally or externally and that are associated with +** a particular attached database. ** */ #define SQLITE_FCNTL_LOCKSTATE 1 @@ -1107,6 +1130,7 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32 #define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33 #define SQLITE_FCNTL_LOCK_TIMEOUT 34 +#define SQLITE_FCNTL_DATA_VERSION 35 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE @@ -2121,6 +2145,12 @@ struct sqlite3_mem_methods { ** with no schema and no content. The following process works even for ** a badly corrupted database file: **
      +**
    1. If the database connection is newly opened, make sure it has read the +** database schema by preparing then discarding some query against the +** database, or calling sqlite3_table_column_metadata(), ignoring any +** errors. This step is only necessary if the application desires to keep +** the database in WAL mode after the reset if it was in WAL mode before +** the reset. **
    2. sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0); **
    3. [sqlite3_exec](db, "[VACUUM]", 0, 0, 0); **
    4. sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0); @@ -2269,12 +2299,17 @@ SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64); ** program, the value returned reflects the number of rows modified by the ** previous INSERT, UPDATE or DELETE statement within the same trigger. ** -** See also the [sqlite3_total_changes()] interface, the -** [count_changes pragma], and the [changes() SQL function]. -** ** If a separate thread makes changes on the same database connection ** while [sqlite3_changes()] is running then the value returned ** is unpredictable and not meaningful. +** +** See also: +**
        +**
      • the [sqlite3_total_changes()] interface +**
      • the [count_changes pragma] +**
      • the [changes() SQL function] +**
      • the [data_version pragma] +**
      */ SQLITE_API int sqlite3_changes(sqlite3*); @@ -2292,13 +2327,26 @@ SQLITE_API int sqlite3_changes(sqlite3*); ** count, but those made as part of REPLACE constraint resolution are ** not. ^Changes to a view that are intercepted by INSTEAD OF triggers ** are not counted. -** -** See also the [sqlite3_changes()] interface, the -** [count_changes pragma], and the [total_changes() SQL function]. ** +** This the [sqlite3_total_changes(D)] interface only reports the number +** of rows that changed due to SQL statement run against database +** connection D. Any changes by other database connections are ignored. +** To detect changes against a database file from other database +** connections use the [PRAGMA data_version] command or the +** [SQLITE_FCNTL_DATA_VERSION] [file control]. +** ** If a separate thread makes changes on the same database connection ** while [sqlite3_total_changes()] is running then the value ** returned is unpredictable and not meaningful. +** +** See also: +**
        +**
      • the [sqlite3_changes()] interface +**
      • the [count_changes pragma] +**
      • the [changes() SQL function] +**
      • the [data_version pragma] +**
      • the [SQLITE_FCNTL_DATA_VERSION] [file control] +**
      */ SQLITE_API int sqlite3_total_changes(sqlite3*); @@ -3354,13 +3402,24 @@ SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int ** [database connection] D failed, then the sqlite3_errcode(D) interface ** returns the numeric [result code] or [extended result code] for that ** API call. -** If the most recent API call was successful, -** then the return value from sqlite3_errcode() is undefined. ** ^The sqlite3_extended_errcode() ** interface is the same except that it always returns the ** [extended result code] even when extended result codes are ** disabled. ** +** The values returned by sqlite3_errcode() and/or +** sqlite3_extended_errcode() might change with each API call. +** Except, there are some interfaces that are guaranteed to never +** change the value of the error code. The error-code preserving +** interfaces are: +** +**
        +**
      • sqlite3_errcode() +**
      • sqlite3_extended_errcode() +**
      • sqlite3_errmsg() +**
      • sqlite3_errmsg16() +**
      +** ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language ** text that describes the error, as either UTF-8 or UTF-16 respectively. ** ^(Memory to hold the error message string is managed internally. @@ -4514,11 +4573,25 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into ** [sqlite3_free()]. ** -** ^(If a memory allocation error occurs during the evaluation of any -** of these routines, a default value is returned. The default value -** is either the integer 0, the floating point number 0.0, or a NULL -** pointer. Subsequent calls to [sqlite3_errcode()] will return -** [SQLITE_NOMEM].)^ +** As long as the input parameters are correct, these routines will only +** fail if an out-of-memory error occurs during a format conversion. +** Only the following subset of interfaces are subject to out-of-memory +** errors: +** +**
        +**
      • sqlite3_column_blob() +**
      • sqlite3_column_text() +**
      • sqlite3_column_text16() +**
      • sqlite3_column_bytes() +**
      • sqlite3_column_bytes16() +**
      +** +** If an out-of-memory error occurs, then the return value from these +** routines is the same as if the column had contained an SQL NULL value. +** Valid SQL NULL returns can be distinguished from out-of-memory errors +** by invoking the [sqlite3_errcode()] immediately after the suspect +** return value is obtained and before any +** other SQLite interface is called on the same [database connection]. */ SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol); @@ -4595,11 +4668,13 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** ** ^These functions (collectively known as "function creation routines") ** are used to add SQL functions or aggregates or to redefine the behavior -** of existing SQL functions or aggregates. The only differences between -** these routines are the text encoding expected for -** the second parameter (the name of the function being created) -** and the presence or absence of a destructor callback for -** the application data pointer. +** of existing SQL functions or aggregates. The only differences between +** the three "sqlite3_create_function*" routines are the text encoding +** expected for the second parameter (the name of the function being +** created) and the presence or absence of a destructor callback for +** the application data pointer. Function sqlite3_create_window_function() +** is similar, but allows the user to supply the extra callback functions +** needed by [aggregate window functions]. ** ** ^The first parameter is the [database connection] to which the SQL ** function is to be added. ^If an application uses more than one database @@ -4645,7 +4720,8 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** ^(The fifth parameter is an arbitrary pointer. The implementation of the ** function can gain access to this pointer using [sqlite3_user_data()].)^ ** -** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are +** ^The sixth, seventh and eighth parameters passed to the three +** "sqlite3_create_function*" functions, xFunc, xStep and xFinal, are ** pointers to C-language functions that implement the SQL function or ** aggregate. ^A scalar SQL function requires an implementation of the xFunc ** callback only; NULL pointers must be passed as the xStep and xFinal @@ -4654,15 +4730,24 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** SQL function or aggregate, pass NULL pointers for all three function ** callbacks. ** -** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL, -** then it is destructor for the application data pointer. -** The destructor is invoked when the function is deleted, either by being -** overloaded or when the database connection closes.)^ -** ^The destructor is also invoked if the call to -** sqlite3_create_function_v2() fails. -** ^When the destructor callback of the tenth parameter is invoked, it -** is passed a single argument which is a copy of the application data -** pointer which was the fifth parameter to sqlite3_create_function_v2(). +** ^The sixth, seventh, eighth and ninth parameters (xStep, xFinal, xValue +** and xInverse) passed to sqlite3_create_window_function are pointers to +** C-language callbacks that implement the new function. xStep and xFinal +** must both be non-NULL. xValue and xInverse may either both be NULL, in +** which case a regular aggregate function is created, or must both be +** non-NULL, in which case the new function may be used as either an aggregate +** or aggregate window function. More details regarding the implementation +** of aggregate window functions are +** [user-defined window functions|available here]. +** +** ^(If the final parameter to sqlite3_create_function_v2() or +** sqlite3_create_window_function() is not NULL, then it is destructor for +** the application data pointer. The destructor is invoked when the function +** is deleted, either by being overloaded or when the database connection +** closes.)^ ^The destructor is also invoked if the call to +** sqlite3_create_function_v2() fails. ^When the destructor callback is +** invoked, it is passed a single argument which is a copy of the application +** data pointer which was the fifth parameter to sqlite3_create_function_v2(). ** ** ^It is permitted to register multiple implementations of the same ** functions with the same name but with either differing numbers of @@ -4715,6 +4800,18 @@ SQLITE_API int sqlite3_create_function_v2( void (*xFinal)(sqlite3_context*), void(*xDestroy)(void*) ); +SQLITE_API int sqlite3_create_window_function( + sqlite3 *db, + const char *zFunctionName, + int nArg, + int eTextRep, + void *pApp, + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void (*xValue)(sqlite3_context*), + void (*xInverse)(sqlite3_context*,int,sqlite3_value**), + void(*xDestroy)(void*) +); /* ** CAPI3REF: Text Encodings @@ -4857,6 +4954,28 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6 ** ** These routines must be called from the same thread as ** the SQL function that supplied the [sqlite3_value*] parameters. +** +** As long as the input parameter is correct, these routines can only +** fail if an out-of-memory error occurs during a format conversion. +** Only the following subset of interfaces are subject to out-of-memory +** errors: +** +**
        +**
      • sqlite3_value_blob() +**
      • sqlite3_value_text() +**
      • sqlite3_value_text16() +**
      • sqlite3_value_text16le() +**
      • sqlite3_value_text16be() +**
      • sqlite3_value_bytes() +**
      • sqlite3_value_bytes16() +**
      +** +** If an out-of-memory error occurs, then the return value from these +** routines is the same as if the column had contained an SQL NULL value. +** Valid SQL NULL returns can be distinguished from out-of-memory errors +** by invoking the [sqlite3_errcode()] immediately after the suspect +** return value is obtained and before any +** other SQLite interface is called on the same [database connection]. */ SQLITE_API const void *sqlite3_value_blob(sqlite3_value*); SQLITE_API double sqlite3_value_double(sqlite3_value*); @@ -6323,6 +6442,7 @@ struct sqlite3_index_info { #define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70 #define SQLITE_INDEX_CONSTRAINT_ISNULL 71 #define SQLITE_INDEX_CONSTRAINT_IS 72 +#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150 /* ** CAPI3REF: Register A Virtual Table Implementation @@ -6999,6 +7119,7 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*); /* ** CAPI3REF: Low-Level Control Of Database Files ** METHOD: sqlite3 +** KEYWORDS: {file control} ** ** ^The [sqlite3_file_control()] interface makes a direct call to the ** xFileControl method for the [sqlite3_io_methods] object associated @@ -7013,11 +7134,18 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*); ** the xFileControl method. ^The return value of the xFileControl ** method becomes the return value of this routine. ** +** A few opcodes for [sqlite3_file_control()] are handled directly +** by the SQLite core and never invoke the +** sqlite3_io_methods.xFileControl method. ** ^The [SQLITE_FCNTL_FILE_POINTER] value for the op parameter causes ** a pointer to the underlying [sqlite3_file] object to be written into -** the space pointed to by the 4th parameter. ^The [SQLITE_FCNTL_FILE_POINTER] -** case is a short-circuit path which does not actually invoke the -** underlying sqlite3_io_methods.xFileControl method. +** the space pointed to by the 4th parameter. The +** [SQLITE_FCNTL_JOURNAL_POINTER] works similarly except that it returns +** the [sqlite3_file] object associated with the journal file instead of +** the main database. The [SQLITE_FCNTL_VFS_POINTER] opcode returns +** a pointer to the underlying [sqlite3_vfs] object for the file. +** The [SQLITE_FCNTL_DATA_VERSION] returns the data version counter +** from the pager. ** ** ^If the second parameter (zDbName) does not match the name of any ** open database file, then SQLITE_ERROR is returned. ^This error @@ -8836,7 +8964,6 @@ SQLITE_API int sqlite3_system_errno(sqlite3*); /* ** CAPI3REF: Database Snapshot ** KEYWORDS: {snapshot} {sqlite3_snapshot} -** EXPERIMENTAL ** ** An instance of the snapshot object records the state of a [WAL mode] ** database for some specific point in history. @@ -8853,11 +8980,6 @@ SQLITE_API int sqlite3_system_errno(sqlite3*); ** version of the database file so that it is possible to later open a new read ** transaction that sees that historical version of the database rather than ** the most recent version. -** -** The constructor for this object is [sqlite3_snapshot_get()]. The -** [sqlite3_snapshot_open()] method causes a fresh read transaction to refer -** to an historical snapshot (if possible). The destructor for -** sqlite3_snapshot objects is [sqlite3_snapshot_free()]. */ typedef struct sqlite3_snapshot { unsigned char hidden[48]; @@ -8865,7 +8987,7 @@ typedef struct sqlite3_snapshot { /* ** CAPI3REF: Record A Database Snapshot -** EXPERIMENTAL +** CONSTRUCTOR: sqlite3_snapshot ** ** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a ** new [sqlite3_snapshot] object that records the current state of @@ -8881,7 +9003,7 @@ typedef struct sqlite3_snapshot { ** in this case. ** **
        -**
      • The database handle must be in [autocommit mode]. +**
      • The database handle must not be in [autocommit mode]. ** **
      • Schema S of [database connection] D must be a [WAL mode] database. ** @@ -8904,7 +9026,7 @@ typedef struct sqlite3_snapshot { ** to avoid a memory leak. ** ** The [sqlite3_snapshot_get()] interface is only available when the -** SQLITE_ENABLE_SNAPSHOT compile-time option is used. +** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used. */ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get( sqlite3 *db, @@ -8914,24 +9036,35 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get( /* ** CAPI3REF: Start a read transaction on an historical snapshot -** EXPERIMENTAL +** METHOD: sqlite3_snapshot ** -** ^The [sqlite3_snapshot_open(D,S,P)] interface starts a -** read transaction for schema S of -** [database connection] D such that the read transaction -** refers to historical [snapshot] P, rather than the most -** recent change to the database. -** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success -** or an appropriate [error code] if it fails. +** ^The [sqlite3_snapshot_open(D,S,P)] interface either starts a new read +** transaction or upgrades an existing one for schema S of +** [database connection] D such that the read transaction refers to +** historical [snapshot] P, rather than the most recent change to the +** database. ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK +** on success or an appropriate [error code] if it fails. +** +** ^In order to succeed, the database connection must not be in +** [autocommit mode] when [sqlite3_snapshot_open(D,S,P)] is called. If there +** is already a read transaction open on schema S, then the database handle +** must have no active statements (SELECT statements that have been passed +** to sqlite3_step() but not sqlite3_reset() or sqlite3_finalize()). +** SQLITE_ERROR is returned if either of these conditions is violated, or +** if schema S does not exist, or if the snapshot object is invalid. +** +** ^A call to sqlite3_snapshot_open() will fail to open if the specified +** snapshot has been overwritten by a [checkpoint]. In this case +** SQLITE_ERROR_SNAPSHOT is returned. +** +** If there is already a read transaction open when this function is +** invoked, then the same read transaction remains open (on the same +** database snapshot) if SQLITE_ERROR, SQLITE_BUSY or SQLITE_ERROR_SNAPSHOT +** is returned. If another error code - for example SQLITE_PROTOCOL or an +** SQLITE_IOERR error code - is returned, then the final state of the +** read transaction is undefined. If SQLITE_OK is returned, then the +** read transaction is now open on database snapshot P. ** -** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be -** the first operation following the [BEGIN] that takes the schema S -** out of [autocommit mode]. -** ^In other words, schema S must not currently be in -** a transaction for [sqlite3_snapshot_open(D,S,P)] to work, but the -** database connection D must be out of [autocommit mode]. -** ^A [snapshot] will fail to open if it has been overwritten by a -** [checkpoint]. ** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the ** database connection D does not know that the database file for ** schema S is in [WAL mode]. A database connection might not know @@ -8942,7 +9075,7 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get( ** database connection in order to make it ready to use snapshots.) ** ** The [sqlite3_snapshot_open()] interface is only available when the -** SQLITE_ENABLE_SNAPSHOT compile-time option is used. +** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used. */ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open( sqlite3 *db, @@ -8952,20 +9085,20 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open( /* ** CAPI3REF: Destroy a snapshot -** EXPERIMENTAL +** DESTRUCTOR: sqlite3_snapshot ** ** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P. ** The application must eventually free every [sqlite3_snapshot] object ** using this routine to avoid a memory leak. ** ** The [sqlite3_snapshot_free()] interface is only available when the -** SQLITE_ENABLE_SNAPSHOT compile-time option is used. +** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used. */ SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*); /* ** CAPI3REF: Compare the ages of two snapshot handles. -** EXPERIMENTAL +** METHOD: sqlite3_snapshot ** ** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages ** of two valid snapshot handles. @@ -8984,6 +9117,9 @@ SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*); ** Otherwise, this API returns a negative value if P1 refers to an older ** snapshot than P2, zero if the two handles refer to the same database ** snapshot, and a positive value if P1 is a newer snapshot than P2. +** +** This interface is only available if SQLite is compiled with the +** [SQLITE_ENABLE_SNAPSHOT] option. */ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp( sqlite3_snapshot *p1, @@ -8992,23 +9128,26 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp( /* ** CAPI3REF: Recover snapshots from a wal file -** EXPERIMENTAL +** METHOD: sqlite3_snapshot ** -** If all connections disconnect from a database file but do not perform -** a checkpoint, the existing wal file is opened along with the database -** file the next time the database is opened. At this point it is only -** possible to successfully call sqlite3_snapshot_open() to open the most -** recent snapshot of the database (the one at the head of the wal file), -** even though the wal file may contain other valid snapshots for which -** clients have sqlite3_snapshot handles. +** If a [WAL file] remains on disk after all database connections close +** (either through the use of the [SQLITE_FCNTL_PERSIST_WAL] [file control] +** or because the last process to have the database opened exited without +** calling [sqlite3_close()]) and a new connection is subsequently opened +** on that database and [WAL file], the [sqlite3_snapshot_open()] interface +** will only be able to open the last transaction added to the WAL file +** even though the WAL file contains other valid transactions. ** -** This function attempts to scan the wal file associated with database zDb +** This function attempts to scan the WAL file associated with database zDb ** of database handle db and make all valid snapshots available to ** sqlite3_snapshot_open(). It is an error if there is already a read -** transaction open on the database, or if the database is not a wal mode +** transaction open on the database, or if the database is not a WAL mode ** database. ** ** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +** +** This interface is only available if SQLite is compiled with the +** [SQLITE_ENABLE_SNAPSHOT] option. */ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb); @@ -9119,7 +9258,7 @@ SQLITE_API int sqlite3_deserialize( ** in the P argument is held in memory obtained from [sqlite3_malloc64()] ** and that SQLite should take ownership of this memory and automatically ** free it when it has finished using it. Without this flag, the caller -** is resposible for freeing any dynamically allocated memory. +** is responsible for freeing any dynamically allocated memory. ** ** The SQLITE_DESERIALIZE_RESIZEABLE flag means that SQLite is allowed to ** grow the size of the database using calls to [sqlite3_realloc64()]. This @@ -11297,7 +11436,7 @@ struct Fts5ExtensionApi { ** This way, even if the tokenizer does not provide synonyms ** when tokenizing query text (it should not - to do would be ** inefficient), it doesn't matter if the user queries for -** 'first + place' or '1st + place', as there are entires in the +** 'first + place' or '1st + place', as there are entries in the ** FTS index corresponding to both forms of the first token. **
    ** @@ -11325,7 +11464,7 @@ struct Fts5ExtensionApi { ** extra data to the FTS index or require FTS5 to query for multiple terms, ** so it is efficient in terms of disk space and query speed. However, it ** does not support prefix queries very well. If, as suggested above, the -** token "first" is subsituted for "1st" by the tokenizer, then the query: +** token "first" is substituted for "1st" by the tokenizer, then the query: ** ** ** ... MATCH '1s*' From 2b1913a7cb0a117b81903741357b38a429613b32 Mon Sep 17 00:00:00 2001 From: Paul Wicking Date: Tue, 9 Oct 2018 12:21:36 +0200 Subject: [PATCH 0039/1650] Doc: Clarify that BC does not apply to Qt Test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-17531 Change-Id: I59c02f456a16a48391247fdf7010358ad013c0ac Reviewed-by: Topi Reiniö Reviewed-by: Liang Qi --- src/testlib/doc/src/qttest-index.qdoc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/testlib/doc/src/qttest-index.qdoc b/src/testlib/doc/src/qttest-index.qdoc index 8c817b3653..6e4f954034 100644 --- a/src/testlib/doc/src/qttest-index.qdoc +++ b/src/testlib/doc/src/qttest-index.qdoc @@ -35,6 +35,11 @@ and the \l QAbstractItemModelTester allows for non-destructive testing of item models. + \note There is no binary compatibility guarantee for the Qt Test module. + This means that an application that uses Qt Test is only guaranteed + to work with the Qt version it was developed against. However, source + compatibility is guaranteed. + \section1 Getting Started To enable Qt Test in a project, add this directive into the C++ files: From c89d0f9d532a2719118614b9fa9b8efffbe12f2f Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 26 Sep 2018 13:15:19 +0200 Subject: [PATCH 0040/1650] QNetworkAccessManager: defer call to _q_networkSessionStateChanged MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also, call it only if the state really changes. If we stay disconnected the whole time, there is no point in trying to create the session over and over. Change-Id: Ic3a92dd0575bed1a23ae36a944cc51b9741fb64a Fixes: QTBUG-49760 Reviewed-by: Jesus Fernandez Reviewed-by: Mårten Nordheim Reviewed-by: Timur Pocheptsov --- src/network/access/qnetworkaccessmanager.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 263469ce38..1f0d2f92e2 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -1848,6 +1848,7 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co if (config.isValid()) newSession = QSharedNetworkSessionManager::getSession(config); + QNetworkSession::State oldState = QNetworkSession::Invalid; if (networkSessionStrongRef) { //do nothing if new and old session are the same if (networkSessionStrongRef == newSession) @@ -1859,6 +1860,7 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co q, SLOT(_q_networkSessionStateChanged(QNetworkSession::State))); QObject::disconnect(networkSessionStrongRef.data(), SIGNAL(error(QNetworkSession::SessionError)), q, SLOT(_q_networkSessionFailed(QNetworkSession::SessionError))); + oldState = networkSessionStrongRef->state(); } //switch to new session (null if config was invalid) @@ -1884,7 +1886,11 @@ void QNetworkAccessManagerPrivate::createSession(const QNetworkConfiguration &co QObject::connect(networkSessionStrongRef.data(), SIGNAL(error(QNetworkSession::SessionError)), q, SLOT(_q_networkSessionFailed(QNetworkSession::SessionError))); - _q_networkSessionStateChanged(networkSessionStrongRef->state()); + const QNetworkSession::State newState = networkSessionStrongRef->state(); + if (newState != oldState) { + QMetaObject::invokeMethod(q, "_q_networkSessionStateChanged", Qt::QueuedConnection, + Q_ARG(QNetworkSession::State, newState)); + } } void QNetworkAccessManagerPrivate::_q_networkSessionClosed() From fc4b0769a5d65960eea959730d5cd20d3496d40b Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Fri, 12 Oct 2018 11:45:13 +0200 Subject: [PATCH 0041/1650] Fix pdf printing in static builds The pdf engine uses a resource file, but Q_INIT_RESOURCE() was lacking. Task-number: QTBUG-71070 Change-Id: I685961b3f2eea0ffe6b5313c72d504a8ad9a98e5 Reviewed-by: Lars Knoll --- src/gui/painting/qpdf.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index e58f9cee4c..8a0020bd2d 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -71,6 +71,11 @@ static const bool do_compress = true; // Can't use it though, as gs generates completely wrong images if this is true. static const bool interpolateImages = false; +static void initResources() +{ + Q_INIT_RESOURCE(qpdf); +} + QT_BEGIN_NAMESPACE inline QPaintEngine::PaintEngineFeatures qt_pdf_decide_features() @@ -1445,6 +1450,7 @@ QPdfEnginePrivate::QPdfEnginePrivate() grayscale(false), m_pageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF(10, 10, 10, 10)) { + initResources(); resolution = 1200; currentObject = 1; currentPage = 0; From dd8a66daa497f0547f2fcddc0ee1e722d13ab98b Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Wed, 19 Sep 2018 11:14:10 +0200 Subject: [PATCH 0042/1650] xcb: rework connection error handling This patch reworks 0b1ce5db9e04b4c28713e87306fcea020c3e428b. Just by looking at the source code it was unclear why is this signal-and-slot connection necessary. It doesn't do anything on normal exit - at the time we call dtor of this class, QCoreApplication::instance() already is nullptr, which means that no further event processing happens and we never get this signal. Without digging into git history it may appear that the goal was to process the remaining events on application exit, which would be a questionable code by itself. Change-Id: I202d11584901e3b52254d8e3c347aece17844b72 Reviewed-by: Allan Sandfeld Jensen --- src/plugins/platforms/xcb/qxcbeventqueue.cpp | 27 +++++++++++++------- src/plugins/platforms/xcb/qxcbeventqueue.h | 1 + 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbeventqueue.cpp b/src/plugins/platforms/xcb/qxcbeventqueue.cpp index 5bd4e7a68a..d7d70536a0 100644 --- a/src/plugins/platforms/xcb/qxcbeventqueue.cpp +++ b/src/plugins/platforms/xcb/qxcbeventqueue.cpp @@ -81,8 +81,6 @@ static bool dispatcherOwnerDestructing = false; QXcbEventQueue::QXcbEventQueue(QXcbConnection *connection) : m_connection(connection) { - connect(this, &QXcbEventQueue::finished, m_connection, &QXcbConnection::processXcbEvents); - // When running test cases in auto tests, static variables are preserved // between test function runs, even if Q*Application object is destroyed. // Reset to default value to account for this. @@ -199,14 +197,25 @@ void QXcbEventQueue::run() enqueueEvent(event); while (!m_closeConnectionDetected && (event = xcb_poll_for_queued_event(connection))) enqueueEvent(event); + wakeUpDispatcher(); + } - QMutexLocker locker(&qAppExiting); - if (!dispatcherOwnerDestructing) { - // This thread can run before a dispatcher has been created, - // so check if it is ready. - if (QCoreApplication::eventDispatcher()) - QCoreApplication::eventDispatcher()->wakeUp(); - } + if (!m_closeConnectionDetected) { + // Connection was terminated not by us. Wake up dispatcher, which will + // call processXcbEvents(), where we handle the connection errors via + // xcb_connection_has_error(). + wakeUpDispatcher(); + } +} + +void QXcbEventQueue::wakeUpDispatcher() +{ + QMutexLocker locker(&qAppExiting); + if (!dispatcherOwnerDestructing) { + // This thread can run before a dispatcher has been created, + // so check if it is ready. + if (QCoreApplication::eventDispatcher()) + QCoreApplication::eventDispatcher()->wakeUp(); } } diff --git a/src/plugins/platforms/xcb/qxcbeventqueue.h b/src/plugins/platforms/xcb/qxcbeventqueue.h index bec2a6a201..0096437dba 100644 --- a/src/plugins/platforms/xcb/qxcbeventqueue.h +++ b/src/plugins/platforms/xcb/qxcbeventqueue.h @@ -83,6 +83,7 @@ public: bool isEmpty() const { return m_head == m_flushedTail && !m_head->event; } xcb_generic_event_t *takeFirst(); void flushBufferedEvents(); + void wakeUpDispatcher(); // ### peek() and peekEventQueue() could be unified. Note that peekEventQueue() // is public API exposed via QX11Extras/QX11Info. From 00ae1e6b7bf6efa5f5e57d37844e44d521604fb6 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Wed, 19 Sep 2018 11:40:31 +0200 Subject: [PATCH 0043/1650] xcb: respect QEventLoop::ExcludeUserInputEvents in native event handlers This was a regression from Qt 4. Before this patch, we supported filtering events only at QWindowSystemInterface level, but to properly support filtering in QAbstractEventDispatcher::filterNativeEvent, we have to filter the events earlier. Now it is possible to enable/disable this feature for platforms that support native event filtering. The mapping of which events are user input events were taken from QWindowSystemInterfacePrivate::EventType. Task-number: QTBUG-69687 Change-Id: I9a5fb9f999451c47abcdc83fdcc129b5eeb55447 Reviewed-by: Paul Wicking Reviewed-by: Allan Sandfeld Jensen --- src/gui/kernel/qwindowsysteminterface.cpp | 29 ++++++++-- src/gui/kernel/qwindowsysteminterface.h | 1 + src/gui/kernel/qwindowsysteminterface_p.h | 1 + src/plugins/platforms/xcb/qxcbconnection.cpp | 54 ++++++++++++++++--- src/plugins/platforms/xcb/qxcbconnection.h | 4 +- .../platforms/xcb/qxcbeventdispatcher.cpp | 7 +-- src/plugins/platforms/xcb/qxcbeventqueue.cpp | 29 ++++++++++ src/plugins/platforms/xcb/qxcbeventqueue.h | 5 ++ src/plugins/platforms/xcb/qxcbintegration.cpp | 2 + src/widgets/kernel/qwidget.cpp | 14 +++-- 10 files changed, 126 insertions(+), 20 deletions(-) diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index 07ece5689e..67e1283462 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -57,6 +57,7 @@ QT_BEGIN_NAMESPACE QElapsedTimer QWindowSystemInterfacePrivate::eventTime; bool QWindowSystemInterfacePrivate::synchronousWindowSystemEvents = false; +bool QWindowSystemInterfacePrivate::platformFiltersEvents = false; bool QWindowSystemInterfacePrivate::TabletEvent::platformSynthesizesMouse = true; QWaitCondition QWindowSystemInterfacePrivate::eventsFlushed; QMutex QWindowSystemInterfacePrivate::flushEventMutex; @@ -1047,10 +1048,15 @@ bool QWindowSystemInterface::sendWindowSystemEvents(QEventLoop::ProcessEventsFla int nevents = 0; while (QWindowSystemInterfacePrivate::windowSystemEventsQueued()) { - QWindowSystemInterfacePrivate::WindowSystemEvent *event = - (flags & QEventLoop::ExcludeUserInputEvents) ? - QWindowSystemInterfacePrivate::getNonUserInputWindowSystemEvent() : - QWindowSystemInterfacePrivate::getWindowSystemEvent(); + QWindowSystemInterfacePrivate::WindowSystemEvent *event = nullptr; + + if (QWindowSystemInterfacePrivate::platformFiltersEvents) { + event = QWindowSystemInterfacePrivate::getWindowSystemEvent(); + } else { + event = flags & QEventLoop::ExcludeUserInputEvents ? + QWindowSystemInterfacePrivate::getNonUserInputWindowSystemEvent() : + QWindowSystemInterfacePrivate::getWindowSystemEvent(); + } if (!event) break; @@ -1089,6 +1095,21 @@ bool QWindowSystemInterface::nonUserInputEventsQueued() return QWindowSystemInterfacePrivate::nonUserInputEventsQueued(); } +/*! + Platforms that implement UserInputEvent filtering at native event level must + set this property to \c true. The default is \c false, which means that event + filtering logic is handled by QWindowSystemInterface. Doing the filtering in + platform plugins is necessary when supporting AbstractEventDispatcher::filterNativeEvent(), + which should respect flags that were passed to event dispatcher's processEvents() + call. + + \since 5.12 +*/ +void QWindowSystemInterface::setPlatformFiltersEvents(bool enable) +{ + QWindowSystemInterfacePrivate::platformFiltersEvents = enable; +} + // --------------------- QtTestLib support --------------------- // The following functions are used by testlib, and need to be synchronous to avoid diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h index 6bf6ee645c..1dde9130ac 100644 --- a/src/gui/kernel/qwindowsysteminterface.h +++ b/src/gui/kernel/qwindowsysteminterface.h @@ -292,6 +292,7 @@ public: static void deferredFlushWindowSystemEvents(QEventLoop::ProcessEventsFlags flags); static int windowSystemEventsQueued(); static bool nonUserInputEventsQueued(); + static void setPlatformFiltersEvents(bool enable); }; #ifndef QT_NO_DEBUG_STREAM diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h index 492f559f22..9cb4e191cc 100644 --- a/src/gui/kernel/qwindowsysteminterface_p.h +++ b/src/gui/kernel/qwindowsysteminterface_p.h @@ -525,6 +525,7 @@ public: public: static QElapsedTimer eventTime; static bool synchronousWindowSystemEvents; + static bool platformFiltersEvents; static QWaitCondition eventsFlushed; static QMutex flushEventMutex; diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index c1f0b71414..a4294956c1 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -1020,11 +1020,10 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) printXcbEvent(lcQpaEvents(), "Event", event); long result = 0; // Used only by MS Windows - QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance(); - bool handledByNativeEventFilter = dispatcher && dispatcher->filterNativeEvent( - m_nativeInterface->nativeEventType(), event, &result); - if (handledByNativeEventFilter) - return; + if (QAbstractEventDispatcher *dispatcher = QAbstractEventDispatcher::instance()) { + if (dispatcher->filterNativeEvent(m_nativeInterface->nativeEventType(), event, &result)) + return; + } uint response_type = event->response_type & ~0x80; @@ -1451,7 +1450,47 @@ bool QXcbConnection::compressEvent(xcb_generic_event_t *event) const return false; } -void QXcbConnection::processXcbEvents() +bool QXcbConnection::isUserInputEvent(xcb_generic_event_t *event) const +{ + auto eventType = event->response_type & ~0x80; + bool isInputEvent = eventType == XCB_BUTTON_PRESS || + eventType == XCB_BUTTON_RELEASE || + eventType == XCB_KEY_PRESS || + eventType == XCB_KEY_RELEASE || + eventType == XCB_MOTION_NOTIFY || + eventType == XCB_ENTER_NOTIFY || + eventType == XCB_LEAVE_NOTIFY; + if (isInputEvent) + return true; + +#if QT_CONFIG(xcb_xinput) + if (connection()->hasXInput2()) { + isInputEvent = isXIType(event, m_xiOpCode, XCB_INPUT_BUTTON_PRESS) || + isXIType(event, m_xiOpCode, XCB_INPUT_BUTTON_RELEASE) || + isXIType(event, m_xiOpCode, XCB_INPUT_MOTION) || + isXIType(event, m_xiOpCode, XCB_INPUT_TOUCH_BEGIN) || + isXIType(event, m_xiOpCode, XCB_INPUT_TOUCH_UPDATE) || + isXIType(event, m_xiOpCode, XCB_INPUT_TOUCH_END) || + isXIType(event, m_xiOpCode, XCB_INPUT_ENTER) || + isXIType(event, m_xiOpCode, XCB_INPUT_LEAVE) || + // wacom driver's way of reporting tool proximity + isXIType(event, m_xiOpCode, XCB_INPUT_PROPERTY); + } + if (isInputEvent) + return true; +#endif + + if (eventType == XCB_CLIENT_MESSAGE) { + auto clientMessage = reinterpret_cast(event); + if (clientMessage->format == 32 && clientMessage->type == atom(QXcbAtom::WM_PROTOCOLS)) + if (clientMessage->data.data32[0] == atom(QXcbAtom::WM_DELETE_WINDOW)) + isInputEvent = true; + } + + return isInputEvent; +} + +void QXcbConnection::processXcbEvents(QEventLoop::ProcessEventsFlags flags) { int connection_error = xcb_connection_has_error(xcb_connection()); if (connection_error) { @@ -1461,13 +1500,14 @@ void QXcbConnection::processXcbEvents() m_eventQueue->flushBufferedEvents(); - while (xcb_generic_event_t *event = m_eventQueue->takeFirst()) { + while (xcb_generic_event_t *event = m_eventQueue->takeFirst(flags)) { QScopedPointer eventGuard(event); if (!(event->response_type & ~0x80)) { handleXcbError(reinterpret_cast(event)); continue; } + if (compressEvent(event)) continue; diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 3fb64f01a4..96591c7994 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -475,6 +475,8 @@ public: Qt::MouseButtons queryMouseButtons() const; Qt::KeyboardModifiers queryKeyboardModifiers() const; + bool isUserInputEvent(xcb_generic_event_t *event) const; + #if QT_CONFIG(xcb_xinput) void xi2SelectStateEvents(); void xi2SelectDeviceEvents(xcb_window_t window); @@ -495,7 +497,7 @@ public: QXcbGlIntegration *glIntegration() const; void flush() { xcb_flush(m_connection); } - void processXcbEvents(); + void processXcbEvents(QEventLoop::ProcessEventsFlags flags); protected: bool event(QEvent *e) override; diff --git a/src/plugins/platforms/xcb/qxcbeventdispatcher.cpp b/src/plugins/platforms/xcb/qxcbeventdispatcher.cpp index 252c1c62e3..3cb2a5b5ef 100644 --- a/src/plugins/platforms/xcb/qxcbeventdispatcher.cpp +++ b/src/plugins/platforms/xcb/qxcbeventdispatcher.cpp @@ -58,7 +58,7 @@ QXcbUnixEventDispatcher::~QXcbUnixEventDispatcher() bool QXcbUnixEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) { const bool didSendEvents = QEventDispatcherUNIX::processEvents(flags); - m_connection->processXcbEvents(); + m_connection->processXcbEvents(flags); // The following line should not be necessary after QTBUG-70095 return QWindowSystemInterface::sendWindowSystemEvents(flags) || didSendEvents; } @@ -99,9 +99,10 @@ static gboolean xcbSourceCheck(GSource *source) static gboolean xcbSourceDispatch(GSource *source, GSourceFunc, gpointer) { auto xcbEventSource = reinterpret_cast(source); - xcbEventSource->connection->processXcbEvents(); + QEventLoop::ProcessEventsFlags flags = xcbEventSource->dispatcher->flags(); + xcbEventSource->connection->processXcbEvents(flags); // The following line should not be necessary after QTBUG-70095 - QWindowSystemInterface::sendWindowSystemEvents(xcbEventSource->dispatcher->flags()); + QWindowSystemInterface::sendWindowSystemEvents(flags); return true; } diff --git a/src/plugins/platforms/xcb/qxcbeventqueue.cpp b/src/plugins/platforms/xcb/qxcbeventqueue.cpp index d7d70536a0..20589fc550 100644 --- a/src/plugins/platforms/xcb/qxcbeventqueue.cpp +++ b/src/plugins/platforms/xcb/qxcbeventqueue.cpp @@ -114,6 +114,35 @@ QXcbEventQueue::~QXcbEventQueue() qCDebug(lcQpaEventReader) << "nodes on heap:" << m_nodesOnHeap; } +xcb_generic_event_t *QXcbEventQueue::takeFirst(QEventLoop::ProcessEventsFlags flags) +{ + // This is the level at which we were moving excluded user input events into + // separate queue in Qt 4 (see qeventdispatcher_x11.cpp). In this case + // QXcbEventQueue represents Xlib's internal event queue. In Qt 4, Xlib's + // event queue peeking APIs would not see these events anymore, the same way + // our peeking functions do not consider m_inputEvents. This design is + // intentional to keep the same behavior. We could do filtering directly on + // QXcbEventQueue, without the m_inputEvents, but it is not clear if it is + // needed by anyone who peeks at the native event queue. + + bool excludeUserInputEvents = flags.testFlag(QEventLoop::ExcludeUserInputEvents); + if (excludeUserInputEvents) { + xcb_generic_event_t *event = nullptr; + while ((event = takeFirst())) { + if (m_connection->isUserInputEvent(event)) { + m_inputEvents << event; + continue; + } + break; + } + return event; + } + + if (!m_inputEvents.isEmpty()) + return m_inputEvents.takeFirst(); + return takeFirst(); +} + xcb_generic_event_t *QXcbEventQueue::takeFirst() { if (isEmpty()) diff --git a/src/plugins/platforms/xcb/qxcbeventqueue.h b/src/plugins/platforms/xcb/qxcbeventqueue.h index 0096437dba..235f2824be 100644 --- a/src/plugins/platforms/xcb/qxcbeventqueue.h +++ b/src/plugins/platforms/xcb/qxcbeventqueue.h @@ -41,6 +41,8 @@ #include #include +#include +#include #include @@ -81,6 +83,7 @@ public: void run() override; bool isEmpty() const { return m_head == m_flushedTail && !m_head->event; } + xcb_generic_event_t *takeFirst(QEventLoop::ProcessEventsFlags flags); xcb_generic_event_t *takeFirst(); void flushBufferedEvents(); void wakeUpDispatcher(); @@ -124,6 +127,8 @@ private: bool m_peekerIndexCacheDirty = false; QHash m_peekerToNode; + QVector m_inputEvents; + // debug stats quint64 m_nodesOnHeap = 0; }; diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index d030b22fc8..9a7d193767 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -137,6 +137,8 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char m_instance = this; qApp->setAttribute(Qt::AA_CompressHighFrequencyEvents, true); + QWindowSystemInterface::setPlatformFiltersEvents(true); + qRegisterMetaType(); #if QT_CONFIG(xcb_xlib) XInitThreads(); diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 6753c35cfc..30e34c419e 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -10096,20 +10096,24 @@ void QWidget::hideEvent(QHideEvent *) which are passed in the \a message parameter. In your reimplementation of this function, if you want to stop the - event being handled by Qt, return true and set \a result. - If you return false, this native event is passed back to Qt, - which translates the event into a Qt event and sends it to the widget. + event being handled by Qt, return true and set \a result. The \a result + parameter has meaning only on Windows. If you return false, this native + event is passed back to Qt, which translates the event into a Qt event + and sends it to the widget. - \note Events are only delivered to this event handler if the widget is - has a native Window handle. + \note Events are only delivered to this event handler if the widget + has a native window handle. \note This function superseedes the event filter functions x11Event(), winEvent() and macEvent() of Qt 4. + \sa QAbstractNativeEventFilter + \table \header \li Platform \li Event Type Identifier \li Message Type \li Result Type \row \li Windows \li "windows_generic_MSG" \li MSG * \li LRESULT \row \li macOS \li "NSEvent" \li NSEvent * \li + \row \li XCB \li "xcb_generic_event_t" \li xcb_generic_event_t * \li \endtable */ From 402efef57bb6a04ad778d3139100becc2cba31eb Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 8 Oct 2018 10:10:07 +0200 Subject: [PATCH 0044/1650] Don't drop update requests when closing and reopening windows Before commit 4d15f393a76cfcc4d54f311884fedac5bf0f72ee update requests were handled by a timer on QWindow. Therefore they survived the closing and re-opening of platform windows. Now, as the timer was moved to QPlatformWindow, it gets reset when you close the QWindow, and any pending update requests are lost. However, we do set the updateRequestPending variable on QWindow when requesting an update. Therefore, we can also restore the update timer on the platform window when creating it. Change-Id: I23b00f24a46706beac7d1455edd8a5623db46b22 Fixes: QTBUG-70957 Reviewed-by: Tim Jenssen Reviewed-by: Thomas Hartmann Reviewed-by: Laszlo Agocs --- src/gui/kernel/qwindow.cpp | 3 +++ tests/auto/gui/kernel/qwindow/tst_qwindow.cpp | 23 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 3d7d22959d..bc2d6e6a17 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -546,6 +546,9 @@ void QWindowPrivate::create(bool recursive, WId nativeHandle) QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceCreated); QGuiApplication::sendEvent(q, &e); + + if (updateRequestPending) + platformWindow->requestUpdate(); } void QWindowPrivate::clearFocusObject() diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp index 7c24bbaadd..9415908383 100644 --- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -114,6 +115,7 @@ private slots: void cleanup(); void testBlockingWindowShownAfterModalDialog(); void generatedMouseMove(); + void keepPendingUpdateRequests(); private: QPoint m_availableTopLeft; @@ -2451,6 +2453,27 @@ void tst_QWindow::generatedMouseMove() QVERIFY(w.mouseMovedCount == 5); } +void tst_QWindow::keepPendingUpdateRequests() +{ + QRect geometry(m_availableTopLeft + QPoint(80, 80), m_testWindowSize); + + Window window; + window.setGeometry(geometry); + window.show(); + QCoreApplication::processEvents(); + QTRY_VERIFY(window.isExposed()); + + window.requestUpdate(); + window.close(); + window.setVisible(true); + + QPlatformWindow *platformWindow = window.handle(); + QVERIFY(platformWindow); + + QVERIFY(platformWindow->hasPendingUpdateRequest()); + QTRY_VERIFY(!platformWindow->hasPendingUpdateRequest()); +} + #include QTEST_MAIN(tst_QWindow) From e0b1c39bed0a70445529ec249688ff1ac5f3a199 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 9 Oct 2018 10:22:25 +0200 Subject: [PATCH 0045/1650] Drop cached shaders when arch is different According to reports Intel on Windows gets confused when feeding program binaries retrieved from x86 and x64 builds into each other. Task-number: QTBUG-64697 Change-Id: Ia7748f532ad06942a92c6fbfc4c9d1ad16bc785a Reviewed-by: Andy Shaw Reviewed-by: Friedemann Kleint Reviewed-by: Andy Nichols --- src/gui/opengl/qopenglprogrambinarycache.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/gui/opengl/qopenglprogrambinarycache.cpp b/src/gui/opengl/qopenglprogrambinarycache.cpp index 0f03101329..c96021a969 100644 --- a/src/gui/opengl/qopenglprogrambinarycache.cpp +++ b/src/gui/opengl/qopenglprogrambinarycache.cpp @@ -63,7 +63,7 @@ Q_DECLARE_LOGGING_CATEGORY(DBG_SHADER_CACHE) #endif const quint32 BINSHADER_MAGIC = 0x5174; -const quint32 BINSHADER_VERSION = 0x2; +const quint32 BINSHADER_VERSION = 0x3; const quint32 BINSHADER_QTVERSION = QT_VERSION; namespace { @@ -120,7 +120,7 @@ QString QOpenGLProgramBinaryCache::cacheFileName(const QByteArray &cacheKey) con return m_cacheDir + QString::fromUtf8(cacheKey); } -#define BASE_HEADER_SIZE (int(3 * sizeof(quint32))) +#define BASE_HEADER_SIZE (int(4 * sizeof(quint32))) #define FULL_HEADER_SIZE(stringsSize) (BASE_HEADER_SIZE + 12 + stringsSize + 8) #define PADDING_SIZE(fullHeaderSize) (((fullHeaderSize + 3) & ~3) - fullHeaderSize) @@ -159,6 +159,10 @@ bool QOpenGLProgramBinaryCache::verifyHeader(const QByteArray &buf) const qCDebug(DBG_SHADER_CACHE, "Qt version does not match"); return false; } + if (readUInt(&p) != sizeof(quintptr)) { + qCDebug(DBG_SHADER_CACHE, "Architecture does not match"); + return false; + } return true; } @@ -371,6 +375,7 @@ void QOpenGLProgramBinaryCache::save(const QByteArray &cacheKey, uint programId) writeUInt(&p, BINSHADER_MAGIC); writeUInt(&p, BINSHADER_VERSION); writeUInt(&p, BINSHADER_QTVERSION); + writeUInt(&p, sizeof(quintptr)); writeStr(&p, info.glvendor); writeStr(&p, info.glrenderer); From 1cd2955173e2248b92f44c9d52d81447ff87906c Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 15 Oct 2018 14:57:59 +0200 Subject: [PATCH 0046/1650] Fix enum passed to QFontDatabase::findFont The script taken here is a QChar::Script, not a QFontDatabase::WritingSystem. This means it was passing QChar::Unknown. Change-Id: I919ae7187ba277346a7719116a94776dce24dd84 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfontdatabase.h | 4 ++-- src/gui/text/qfontengine.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/text/qfontdatabase.h b/src/gui/text/qfontdatabase.h index e6aef493bd..80b092f177 100644 --- a/src/gui/text/qfontdatabase.h +++ b/src/gui/text/qfontdatabase.h @@ -160,8 +160,8 @@ private: static void createDatabase(); static void parseFontName(const QString &name, QString &foundry, QString &family); static QString resolveFontFamilyAlias(const QString &family); - static QFontEngine *findFont(const QFontDef &request, int script); - static void load(const QFontPrivate *d, int script); + static QFontEngine *findFont(const QFontDef &request, int script /* QChar::Script */); + static void load(const QFontPrivate *d, int script /* QChar::Script */); friend struct QFontDef; friend class QFontPrivate; diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 3b64ee0136..80fd288c04 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -1849,7 +1849,7 @@ QFontEngine *QFontEngineMulti::loadEngine(int at) // info about the actual script of the characters may have been discarded, // so we do not check for writing system support, but instead just load // the family indiscriminately. - if (QFontEngine *engine = QFontDatabase::findFont(request, QFontDatabase::Any)) { + if (QFontEngine *engine = QFontDatabase::findFont(request, QChar::Script_Common)) { engine->fontDef.weight = request.weight; if (request.style > QFont::StyleNormal) engine->fontDef.style = request.style; From a174b3df4411f5534789d11a1c2aa310095a02f9 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Mon, 10 Sep 2018 14:27:27 +0200 Subject: [PATCH 0047/1650] Fix wrong keyword in configure.json 'description' is used only once in all configure.json files, so I assume that was meant to be 'purpose'. Change-Id: I66e9d9196c27d2f2131c2d57ea03895e8f5ce754 Reviewed-by: Simon Hausmann Reviewed-by: Oswald Buddenhagen --- src/gui/configure.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/configure.json b/src/gui/configure.json index 4741ed345a..0332631ec8 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -1577,7 +1577,7 @@ }, "multiprocess": { "label": "Multi process", - "description": "Provides support for detecting the desktop environment, launching external processes and opening URLs.", + "purpose": "Provides support for detecting the desktop environment, launching external processes and opening URLs.", "section": "Utilities", "condition": "!config.integrity", "output": [ "privateFeature" ] From a517eb24faa7f62a18722ecef39571b51e82b63d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 16 Oct 2018 10:47:22 +0200 Subject: [PATCH 0048/1650] uic: Ignore obsolete pixmap functions After qtbase/550d2a0a15c9403894448ab83863e71bbac2d349, pixmap functions are used for icons as well which can cause compile errors for old UI files that still use them. Task-number: QTBUG-8563 Change-Id: I61bd4b9c1bf774e071a35c5806657054a77ff4d0 Reviewed-by: Jarek Kobus Reviewed-by: Andy Shaw --- src/tools/uic/uic.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/tools/uic/uic.cpp b/src/tools/uic/uic.cpp index 957a50b1d5..f275aaeb29 100644 --- a/src/tools/uic/uic.cpp +++ b/src/tools/uic/uic.cpp @@ -247,8 +247,12 @@ bool Uic::write(DomUI *ui) } pixFunction = ui->elementPixmapFunction(); - if (pixFunction == QLatin1String("QPixmap::fromMimeSource")) - pixFunction = QLatin1String("qPixmapFromMimeSource"); + if (pixFunction == QLatin1String("QPixmap::fromMimeSource") + || pixFunction == QLatin1String("qPixmapFromMimeSource")) { + fprintf(stderr, "%s: Warning: Obsolete pixmap function '%s' specified in the UI file.\n", + qPrintable(opt.messagePrefix()), qPrintable(pixFunction)); + pixFunction.clear(); + } info.acceptUI(ui); cWidgetsInfo.acceptUI(ui); From 3a9776689cad1b7e692e6253009dc5efb8034be0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 5 Oct 2018 12:59:41 +0200 Subject: [PATCH 0049/1650] doc: Update online HTML header URLs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I2109f1a3113a724bfb6bc5a03b4c7b2d67f7e48c Reviewed-by: Topi Reiniö Reviewed-by: Paul Wicking --- doc/global/html-header-online.qdocconf | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/global/html-header-online.qdocconf b/doc/global/html-header-online.qdocconf index 02b7375d32..ce69b57739 100644 --- a/doc/global/html-header-online.qdocconf +++ b/doc/global/html-header-online.qdocconf @@ -27,11 +27,13 @@ qhp.extraFiles += style/online.css \ HTML.headerstyles = \ " \n" \ - " \n" + " \n" HTML.headerscripts = \ " \n" \ - " \n" \ + " \n" \ + " \n" \ + " \n" \ " \n" \ " \n" \ " \n" \ + "\n" \ + "
    \n" \ + "
    \n" \ + "
    \n" \ + " \n" \ "
    \n" \ - "
    \n" \ - "
    \n" \ - " \n" \ - "
    \n" \ - " \n" \ - "
    \n" \ - " Menu\n" \ - "
    \n" \ - " \n" \ - " \n" \ - " \n" \ - " \n" \ - "
    \n" \ - "
    \n" \ - "
    \n" \ - "
    \n" \ - "

    \n" \ - "
    \n" \ - "

    \n" \ + " \n" \ "
    \n" \ "
    \n" \ "\n" \ From 2624676b5731a9d93a1e46429d2c597f1e4bae38 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 2 Oct 2018 14:02:01 +0200 Subject: [PATCH 0068/1650] qmake: Remove the extra space before -MT Removing the extra space before -MT ensures that the vcxproj generator gets valid input. Change-Id: Iccf88c5fc4473db406d714b646185a4fb60a3418 Reviewed-by: Oswald Buddenhagen --- mkspecs/features/static_runtime.prf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/static_runtime.prf b/mkspecs/features/static_runtime.prf index 3275e6e2e2..1af3236189 100644 --- a/mkspecs/features/static_runtime.prf +++ b/mkspecs/features/static_runtime.prf @@ -1,7 +1,7 @@ msvc { # -MD becomes -MT, -MDd becomes -MTd - QMAKE_CFLAGS ~= s,^-MD(d?)$, -MT\1,g - QMAKE_CXXFLAGS ~= s,^-MD(d?)$, -MT\1,g + QMAKE_CFLAGS ~= s,^-MD(d?)$,-MT\1,g + QMAKE_CXXFLAGS ~= s,^-MD(d?)$,-MT\1,g } else: mingw { QMAKE_LFLAGS += -static } From 0aa27af8014f5344d604b3f4eaa5f0a2fb2b44e5 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 16 Oct 2018 13:19:24 +0200 Subject: [PATCH 0069/1650] Windows QPA: Add helper function to obtain DPI-dependent metrics on Windows 10 Use newly introduced SystemParametersInfoForDpi() API with some convenience overloads. Task-number: QTBUG-4362 Change-Id: I4c41c700007bf7cc4fd5868356e3145c136704c0 Reviewed-by: Oliver Wolff --- .../platforms/windows/qwindowscontext.cpp | 40 +++++++++++++++++++ .../platforms/windows/qwindowscontext.h | 14 +++++++ .../platforms/windows/qwindowstheme.cpp | 4 +- 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 4959ed952d..1f80ac5872 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -213,6 +213,7 @@ void QWindowsUser32DLL::init() enableNonClientDpiScaling = (EnableNonClientDpiScaling)library.resolve("EnableNonClientDpiScaling"); getWindowDpiAwarenessContext = (GetWindowDpiAwarenessContext)library.resolve("GetWindowDpiAwarenessContext"); getAwarenessFromDpiAwarenessContext = (GetAwarenessFromDpiAwarenessContext)library.resolve("GetAwarenessFromDpiAwarenessContext"); + systemParametersInfoForDpi = (SystemParametersInfoForDpi)library.resolve("SystemParametersInfoForDpi"); } } @@ -916,6 +917,45 @@ QByteArray QWindowsContext::comErrorString(HRESULT hr) return result; } +bool QWindowsContext::systemParametersInfo(unsigned action, unsigned param, void *out, + unsigned dpi) +{ + const BOOL result = QWindowsContext::user32dll.systemParametersInfoForDpi != nullptr && dpi != 0 + ? QWindowsContext::user32dll.systemParametersInfoForDpi(action, param, out, 0, dpi) + : SystemParametersInfo(action, param, out, 0); + return result == TRUE; +} + +bool QWindowsContext::systemParametersInfoForScreen(unsigned action, unsigned param, void *out, + const QPlatformScreen *screen) +{ + return systemParametersInfo(action, param, out, screen ? screen->logicalDpi().first : 0); +} + +bool QWindowsContext::systemParametersInfoForWindow(unsigned action, unsigned param, void *out, + const QPlatformWindow *win) +{ + return systemParametersInfoForScreen(action, param, out, win ? win->screen() : nullptr); +} + +bool QWindowsContext::nonClientMetrics(NONCLIENTMETRICS *ncm, unsigned dpi) +{ + memset(ncm, 0, sizeof(NONCLIENTMETRICS)); + ncm->cbSize = sizeof(NONCLIENTMETRICS); + return systemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm->cbSize, ncm, dpi); +} + +bool QWindowsContext::nonClientMetricsForScreen(NONCLIENTMETRICS *ncm, + const QPlatformScreen *screen) +{ + return nonClientMetrics(ncm, screen ? screen->logicalDpi().first : 0); +} + +bool QWindowsContext::nonClientMetricsForWindow(NONCLIENTMETRICS *ncm, const QPlatformWindow *win) +{ + return nonClientMetricsForScreen(ncm, win ? win->screen() : nullptr); +} + static inline QWindowsInputContext *windowsInputContext() { return qobject_cast(QWindowsIntegration::instance()->inputContext()); diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h index 19e9c26130..fd6c72668c 100644 --- a/src/plugins/platforms/windows/qwindowscontext.h +++ b/src/plugins/platforms/windows/qwindowscontext.h @@ -70,6 +70,7 @@ Q_DECLARE_LOGGING_CATEGORY(lcQpaTrayIcon) class QWindow; class QPlatformScreen; +class QPlatformWindow; class QWindowsMenuBar; class QWindowsScreenManager; class QWindowsTabletSupport; @@ -104,6 +105,7 @@ struct QWindowsUser32DLL typedef BOOL (WINAPI *EnableNonClientDpiScaling)(HWND); typedef int (WINAPI *GetWindowDpiAwarenessContext)(HWND); typedef int (WINAPI *GetAwarenessFromDpiAwarenessContext)(int); + typedef BOOL (WINAPI *SystemParametersInfoForDpi)(UINT, UINT, PVOID, UINT, UINT); // Windows pointer functions (Windows 8 or later). EnableMouseInPointer enableMouseInPointer = nullptr; @@ -132,6 +134,7 @@ struct QWindowsUser32DLL EnableNonClientDpiScaling enableNonClientDpiScaling = nullptr; GetWindowDpiAwarenessContext getWindowDpiAwarenessContext = nullptr; GetAwarenessFromDpiAwarenessContext getAwarenessFromDpiAwarenessContext = nullptr; + SystemParametersInfoForDpi systemParametersInfoForDpi = nullptr; }; // Shell scaling library (Windows 8.1 onwards) @@ -237,6 +240,17 @@ public: bool asyncExpose() const; void setAsyncExpose(bool value); + static bool systemParametersInfo(unsigned action, unsigned param, void *out, unsigned dpi = 0); + static bool systemParametersInfoForScreen(unsigned action, unsigned param, void *out, + const QPlatformScreen *screen = nullptr); + static bool systemParametersInfoForWindow(unsigned action, unsigned param, void *out, + const QPlatformWindow *win = nullptr); + static bool nonClientMetrics(NONCLIENTMETRICS *ncm, unsigned dpi = 0); + static bool nonClientMetricsForScreen(NONCLIENTMETRICS *ncm, + const QPlatformScreen *screen = nullptr); + static bool nonClientMetricsForWindow(NONCLIENTMETRICS *ncm, + const QPlatformWindow *win = nullptr); + static DWORD readAdvancedExplorerSettings(const wchar_t *subKey, DWORD defaultValue); QTouchDevice *touchDevice() const; diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index d01a7b0a8a..4b70e915a8 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -507,9 +507,7 @@ void QWindowsTheme::refreshFonts() if (!QGuiApplication::desktopSettingsAware()) return; NONCLIENTMETRICS ncm; - ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT); - SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize , &ncm, 0); - + QWindowsContext::nonClientMetrics(&ncm); const QFont menuFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfMenuFont); const QFont messageBoxFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfMessageFont); const QFont statusFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfStatusFont); From 6764e7b020a04b7c6433691d47bc77fea5737625 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 15 Oct 2018 13:52:40 +0200 Subject: [PATCH 0070/1650] Remove empty function QWidgetPrivate::registerDropSite() Apparently it is a left-over from Qt 4. Task-number: QTBUG-70240 Change-Id: I6b882728defef1ab78331b03e76459a7419cd386 Reviewed-by: Richard Moe Gustavsen --- src/widgets/kernel/qwidget.cpp | 9 --------- src/widgets/kernel/qwidget_p.h | 1 - 2 files changed, 10 deletions(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 30e34c419e..8c680560d4 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1580,9 +1580,6 @@ QWidget::~QWidget() d->gestureContext.clear(); #endif - // force acceptDrops false before winId is destroyed. - d->registerDropSite(false); - #ifndef QT_NO_ACTION // remove all actions from this widget for (int i = 0; i < d->actions.size(); ++i) { @@ -3463,11 +3460,6 @@ void QWidget::setAcceptDrops(bool on) } -void QWidgetPrivate::registerDropSite(bool on) -{ - Q_UNUSED(on); -} - /*! Disables widget input events if \a disable is true; otherwise enables input events. @@ -11207,7 +11199,6 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) break; } case Qt::WA_DropSiteRegistered: { - d->registerDropSite(on); for (int i = 0; i < d->children.size(); ++i) { QWidget *w = qobject_cast(d->children.at(i)); if (w && !w->isWindow() && !w->testAttribute(Qt::WA_AcceptDrops) && w->testAttribute(Qt::WA_DropSiteRegistered) != on) diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 20c4a682ed..c2fc27a9ad 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -483,7 +483,6 @@ public: void _q_showIfNotHidden(); void setEnabled_helper(bool); - void registerDropSite(bool); static void adjustFlags(Qt::WindowFlags &flags, QWidget *w = 0); void updateFrameStrut(); From 7f60940fbedef17984e283da41eae94f29fef428 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 17 Oct 2018 07:59:25 -0700 Subject: [PATCH 0071/1650] Re-disable statx() on Android Commit b7887f9b4faad2227691a2af589e9d7680d6ae08 removed this explicit disabling because it shouldn't be needed anymore. Turns out it was, as new Android SDK do include modern Linux headers and those define the structs and constants needed for statx(). Repeat of 8eb3944dac81b8c51d7bac7784204d457551b50c. Task-number: QTBUG-64490 Fixes: QTBUG-71200 Change-Id: If7e743cf8476463880ccfffd155e6d5c2b5a3da9 Reviewed-by: Simon Hausmann Reviewed-by: BogDan Vatra --- src/corelib/io/qfilesystemengine_unix.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 40e8f82a80..964dcebeb2 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -97,6 +97,13 @@ extern "C" NSString *NSTemporaryDirectory(); #endif #endif +#if defined(Q_OS_ANDROID) +// statx() is disabled on Android because quite a few systems +// come with sandboxes that kill applications that make system calls outside a +// whitelist and several Android vendors can't be bothered to update the list. +# undef STATX_BASIC_STATS +#endif + #ifndef STATX_ALL struct statx { mode_t stx_mode; }; // dummy #endif From 5ac2b9ef5904d8130f6de1ad758b5140784045d4 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 15 Oct 2018 14:52:47 +0200 Subject: [PATCH 0072/1650] Windows QPA: Fix maximizing windows without title bar Extends the code from qtbase/0d6612af65161f6e659af6985bb2c0b76accb856 to cover the case of windows without title bar, too. Fixes: QTBUG-4362 Task-number: QTBUG-8361 Change-Id: I5cff8814174069922936f3fcfbb3aef154c7a7e7 Reviewed-by: Oliver Wolff --- .../platforms/windows/qwindowswindow.cpp | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 9c31409644..f340f16679 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -2416,6 +2416,13 @@ void QWindowsWindow::setFrameStrutEventsEnabled(bool enabled) } } +static int getBorderWidth(const QPlatformScreen *screen) +{ + NONCLIENTMETRICS ncm; + QWindowsContext::nonClientMetricsForScreen(&ncm, screen); + return ncm.iBorderWidth + ncm.iPaddedBorderWidth + 2; +} + void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const { // We don't apply the min/max size hint as we change the dpi, because we did not adjust the @@ -2425,10 +2432,11 @@ void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const hint.applyToMinMaxInfo(m_data.hwnd, mmi); } - if ((testFlag(WithinMaximize) || (window()->windowStates() & Qt::WindowMinimized)) - && (m_data.flags & Qt::FramelessWindowHint)) { - // This block fixes QTBUG-8361: Frameless windows shouldn't cover the - // taskbar when maximized + // This block fixes QTBUG-8361, QTBUG-4362: Frameless/title-less windows shouldn't cover the + // taskbar when maximized + if ((testFlag(WithinMaximize) || window()->windowStates().testFlag(Qt::WindowMinimized)) + && (m_data.flags.testFlag(Qt::FramelessWindowHint) + || (m_data.flags.testFlag(Qt::CustomizeWindowHint) && !m_data.flags.testFlag(Qt::WindowTitleHint)))) { const QScreen *screen = window()->screen(); // Documentation of MINMAXINFO states that it will only work for the primary screen @@ -2442,6 +2450,14 @@ void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const // If you have the taskbar on top, or on the left you don't want it at (0,0): mmi->ptMaxPosition.x = availableGeometry.x(); mmi->ptMaxPosition.y = availableGeometry.y(); + if (!m_data.flags.testFlag(Qt::FramelessWindowHint)) { + const int borderWidth = getBorderWidth(screen->handle()); + mmi->ptMaxSize.x += borderWidth * 2; + mmi->ptMaxSize.y += borderWidth * 2; + mmi->ptMaxTrackSize = mmi->ptMaxSize; + mmi->ptMaxPosition.x -= borderWidth; + mmi->ptMaxPosition.y -= borderWidth; + } } else if (!screen){ qWarning("window()->screen() returned a null screen"); } From 6599c1f75832cc9286a3bf88c6b179d006dbb96e Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Wed, 17 Oct 2018 16:22:11 +0200 Subject: [PATCH 0073/1650] QPicture: fix crash for malformed picture A file with the correct QPicture magic bytes, but shorter than a full QPicture file header, could cause the header decoder to access memory out of bounds. Add a size check to avoid. As a driveby, generally harden the parsing against malformed files. [ChangeLog][QtGui][QPicture] Fix crash reading malformed picture file Task-number: QTBUG-71208 Change-Id: I86eb1f915ca9b3a4b91c7433036d76ed6061e2f0 Reviewed-by: Lars Knoll --- src/gui/image/qpicture.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp index 7aa221948e..7eede5ee26 100644 --- a/src/gui/image/qpicture.cpp +++ b/src/gui/image/qpicture.cpp @@ -636,7 +636,7 @@ bool QPicture::exec(QPainter *painter, QDataStream &s, int nrecords) if (d->formatMajor <= 5) { s >> ia >> i_8; painter->drawPolygon(ia, i_8 ? Qt::WindingFill : Qt::OddEvenFill); - a.clear(); + ia.clear(); } else { s >> a >> i_8; painter->drawPolygon(a, i_8 ? Qt::WindingFill : Qt::OddEvenFill); @@ -647,10 +647,10 @@ bool QPicture::exec(QPainter *painter, QDataStream &s, int nrecords) s >> ia; QPainterPath path; Q_ASSERT(ia.size() == 4); - path.moveTo(ia.at(0)); - path.cubicTo(ia.at(1), ia.at(2), ia.at(3)); + path.moveTo(ia.value(0)); + path.cubicTo(ia.value(1), ia.value(2), ia.value(3)); painter->strokePath(path, painter->pen()); - a.clear(); + ia.clear(); } break; case QPicturePrivate::PdcDrawText: @@ -730,7 +730,7 @@ bool QPicture::exec(QPainter *painter, QDataStream &s, int nrecords) int index; s >> r >> index >> sr; Q_ASSERT(index < d->pixmap_list.size()); - pixmap = d->pixmap_list.at(index); + pixmap = d->pixmap_list.value(index); } else { s >> r >> pixmap >> sr; } @@ -744,7 +744,7 @@ bool QPicture::exec(QPainter *painter, QDataStream &s, int nrecords) int index; s >> r >> index >> p; Q_ASSERT(index < d->pixmap_list.size()); - pixmap = d->pixmap_list.at(index); + pixmap = d->pixmap_list.value(index); } else { s >> r >> pixmap >> p; } @@ -765,7 +765,7 @@ bool QPicture::exec(QPainter *painter, QDataStream &s, int nrecords) int index; s >> r >> index >> sr >> ul; Q_ASSERT(index < d->image_list.size()); - image = d->image_list.at(index); + image = d->image_list.value(index); } else { s >> r >> image >> sr >> ul; } @@ -817,7 +817,7 @@ bool QPicture::exec(QPainter *painter, QDataStream &s, int nrecords) int index; s >> index; Q_ASSERT(index < d->pen_list.size()); - pen = d->pen_list.at(index); + pen = d->pen_list.value(index); } else { s >> pen; } @@ -828,7 +828,7 @@ bool QPicture::exec(QPainter *painter, QDataStream &s, int nrecords) int index; s >> index; Q_ASSERT(index < d->brush_list.size()); - brush = d->brush_list.at(index); + brush = d->brush_list.value(index); } else { s >> brush; } @@ -910,7 +910,7 @@ bool QPicture::exec(QPainter *painter, QDataStream &s, int nrecords) break; default: qWarning("QPicture::play: Invalid command %d", c); - if (len) // skip unknown command + if (len > 0) // skip unknown command s.device()->seek(s.device()->pos()+len); } #if defined(QT_DEBUG) @@ -1075,7 +1075,8 @@ bool QPicturePrivate::checkFormat() char mf_id[4]; // picture header tag s.readRawData(mf_id, 4); // read actual tag - if (memcmp(mf_id, qt_mfhdr_tag, 4) != 0) { // wrong header id + int bufSize = pictb.buffer().size(); + if (memcmp(mf_id, qt_mfhdr_tag, 4) != 0 || bufSize < 12) { // wrong header id or size qWarning("QPicturePaintEngine::checkFormat: Incorrect header"); pictb.close(); return false; From 96218681f22588b93999626684ec73717207bb39 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Sun, 14 Oct 2018 20:26:38 +0200 Subject: [PATCH 0074/1650] Restore "Do not create instance of QPlatformIntegration for invalid displays" This patch is amended version of 67cc8fea106c35c7ca75bf476667d07b3bbf3257, which was temporary reverted to simplify integration of conflicting patches. What was amended: - Dropped the factory interface. It is sufficiently clean to check for QXcbConnection::isConnected(). Task-number: QTBUG-68859 Change-Id: I810897b3ea20e356fc4d62e6f01231fd287962dc Reviewed-by: Johan Helsing Reviewed-by: Friedemann Kleint --- src/plugins/platforms/xcb/qxcbintegration.cpp | 20 +++++++++---------- src/plugins/platforms/xcb/qxcbintegration.h | 1 + src/plugins/platforms/xcb/qxcbmain.cpp | 12 ++++++++--- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 9a7d193767..ed9e87a036 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -195,14 +195,17 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char const int numParameters = parameters.size(); m_connections.reserve(1 + numParameters / 2); - auto conn = new QXcbConnection(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, displayName); - if (conn->isConnected()) - m_connections << conn; - else - delete conn; + auto conn = new QXcbConnection(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, displayName); + if (!conn->isConnected()) { + delete conn; + return; + } + m_connections << conn; + + // ### Qt 6 (QTBUG-52408) remove this multi-connection code path for (int i = 0; i < numParameters - 1; i += 2) { - qCDebug(lcQpaScreen) << "connecting to additional display: " << parameters.at(i) << parameters.at(i+1); + qCDebug(lcQpaXcb) << "connecting to additional display: " << parameters.at(i) << parameters.at(i+1); QString display = parameters.at(i) + QLatin1Char(':') + parameters.at(i+1); conn = new QXcbConnection(m_nativeInterface.data(), m_canGrab, m_defaultVisualId, display.toLatin1().constData()); if (conn->isConnected()) @@ -211,11 +214,6 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, int &argc, char delete conn; } - if (m_connections.isEmpty()) { - qCritical("Could not connect to any X display."); - exit(1); - } - m_fontDatabase.reset(new QGenericUnixFontDatabase()); #if QT_CONFIG(xcb_native_painting) diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h index a8dd6402f6..f13e232291 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.h +++ b/src/plugins/platforms/xcb/qxcbintegration.h @@ -102,6 +102,7 @@ public: QPlatformTheme *createPlatformTheme(const QString &name) const override; QVariant styleHint(StyleHint hint) const override; + bool hasDefaultConnection() const { return !m_connections.isEmpty(); } QXcbConnection *defaultConnection() const { return m_connections.first(); } QByteArray wmClass() const; diff --git a/src/plugins/platforms/xcb/qxcbmain.cpp b/src/plugins/platforms/xcb/qxcbmain.cpp index f8cb9a9269..c1e37f3704 100644 --- a/src/plugins/platforms/xcb/qxcbmain.cpp +++ b/src/plugins/platforms/xcb/qxcbmain.cpp @@ -52,10 +52,16 @@ public: QPlatformIntegration* QXcbIntegrationPlugin::create(const QString& system, const QStringList& parameters, int &argc, char **argv) { - if (!system.compare(QLatin1String("xcb"), Qt::CaseInsensitive)) - return new QXcbIntegration(parameters, argc, argv); + if (!system.compare(QLatin1String("xcb"), Qt::CaseInsensitive)) { + auto xcbIntegration = new QXcbIntegration(parameters, argc, argv); + if (!xcbIntegration->hasDefaultConnection()) { + delete xcbIntegration; + return nullptr; + } + return xcbIntegration; + } - return 0; + return nullptr; } QT_END_NAMESPACE From 57b09b903e015bb192c2d1a0a1eb0fa308483c9c Mon Sep 17 00:00:00 2001 From: Kirill Burtsev Date: Fri, 12 Oct 2018 17:40:09 +0200 Subject: [PATCH 0075/1650] Fix QString latin1 conversion and comparison for -optimize-size build Change-Id: I5f0ae946151e9733cbe21cb24387636ba68bc177 Reviewed-by: Edward Welbourne --- src/corelib/tools/qstring.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 5a2d6b228d..c89635cfdb 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -711,9 +711,15 @@ static void qt_to_latin1_internal(uchar *dst, const ushort *src, qsizetype lengt } length = length % 4; +# else + length = length % 16; +# endif // optimize size + + // advance dst, src for tail processing dst += offset; src += offset; +# if !defined(__OPTIMIZE_SIZE__) return UnrollTailLoop<3>::exec(length, [=](int i) { if (Checked) dst[i] = (src[i]>0xff) ? '?' : (uchar) src[i]; @@ -1072,11 +1078,13 @@ static int ucstrncmp(const QChar *a, const uchar *c, size_t l) // still matched offset += 4; } +# endif // optimize size // reset uc and c uc += offset; c += offset; +# if !defined(__OPTIMIZE_SIZE__) const auto lambda = [=](size_t i) { return uc[i] - ushort(c[i]); }; return UnrollTailLoop::exec(e - uc, 0, lambda, lambda); # endif From 83d56811ec95dc27d095da0fb55632ea46e4bea3 Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Tue, 16 Oct 2018 15:06:04 +0200 Subject: [PATCH 0076/1650] Windows QPA: Fix Drag&Drop from touchscreen/pen The Drag&Drop functionality had stopped working with touchscreen/pen after the WM_POINTER-based input handling was added. The Drag&Drop functionality internally uses the DoDragDrop() WIN32 call which, according to Microsoft docs, is not supported for invocation inside handlers for touch/pen messages, and should be invoked in handlers for mouse messages that are synthesized by the OS afterwards. The result was that when DoDragDrop (which is a blocking function with its own event loop) was called it would hang ignoring all touch/pen messages until a mouse/touchpad message arrived. This change implements a workaround for this issue by enqueuing Qt touch/pen events that would be generated inside the pointer message handler, and that could start a Drag&Drop operation, and only producing them after the OS sends the associated mouse messages. Task-number: QTBUG-70887 Change-Id: Id45e0ecc70358ba250de9b3268856781ed21c9dd Reviewed-by: Friedemann Kleint --- .../platforms/windows/qwindowsdrag.cpp | 4 + src/plugins/platforms/windows/qwindowsdrag.h | 2 + .../windows/qwindowspointerhandler.cpp | 149 ++++++++++++++++-- 3 files changed, 145 insertions(+), 10 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp index b7d225cb00..ee82b2f022 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.cpp +++ b/src/plugins/platforms/windows/qwindowsdrag.cpp @@ -652,6 +652,7 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState, */ bool QWindowsDrag::m_canceled = false; +bool QWindowsDrag::m_dragging = false; QWindowsDrag::QWindowsDrag() = default; @@ -699,7 +700,10 @@ Qt::DropAction QWindowsDrag::drag(QDrag *drag) const DWORD allowedEffects = translateToWinDragEffects(possibleActions); qCDebug(lcQpaMime) << '>' << __FUNCTION__ << "possible Actions=0x" << hex << int(possibleActions) << "effects=0x" << allowedEffects << dec; + // Indicate message handlers we are in DoDragDrop() event loop. + QWindowsDrag::m_dragging = true; const HRESULT r = DoDragDrop(dropDataObject, windowDropSource, allowedEffects, &resultEffect); + QWindowsDrag::m_dragging = false; const DWORD reportedPerformedEffect = dropDataObject->reportedPerformedEffect(); if (r == DRAGDROP_S_DROP) { if (reportedPerformedEffect == DROPEFFECT_MOVE && resultEffect != DROPEFFECT_MOVE) { diff --git a/src/plugins/platforms/windows/qwindowsdrag.h b/src/plugins/platforms/windows/qwindowsdrag.h index f116e50cbf..5f30c59882 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.h +++ b/src/plugins/platforms/windows/qwindowsdrag.h @@ -92,6 +92,7 @@ public: static QWindowsDrag *instance(); void cancelDrag() override { QWindowsDrag::m_canceled = true; } static bool isCanceled() { return QWindowsDrag::m_canceled; } + static bool isDragging() { return QWindowsDrag::m_dragging; } IDataObject *dropDataObject() const { return m_dropDataObject; } void setDropDataObject(IDataObject *dataObject) { m_dropDataObject = dataObject; } @@ -102,6 +103,7 @@ public: private: static bool m_canceled; + static bool m_dragging; QWindowsDropMimeData m_dropData; IDataObject *m_dropDataObject = nullptr; diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp index c5acc38e7c..09eadb247a 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp @@ -50,6 +50,9 @@ #include "qwindowswindow.h" #include "qwindowsintegration.h" #include "qwindowsscreen.h" +#if QT_CONFIG(draganddrop) +# include "qwindowsdrag.h" +#endif #include #include @@ -60,6 +63,7 @@ #include #include #include +#include #include @@ -75,6 +79,111 @@ enum { QT_PT_TOUCHPAD = 5, // MinGW is missing PT_TOUCHPAD }; +struct PointerTouchEventInfo { + QPointer window; + QList points; + Qt::KeyboardModifiers modifiers; +}; + +struct PointerTabletEventInfo { + QPointer window; + QPointF local; + QPointF global; + int device; + int pointerType; + Qt::MouseButtons buttons; + qreal pressure; + int xTilt; + int yTilt; + qreal tangentialPressure; + qreal rotation; + int z; + qint64 uid; + Qt::KeyboardModifiers modifiers; +}; + +static QQueue touchEventQueue; +static QQueue tabletEventQueue; + +static void enqueueTouchEvent(QWindow *window, + const QList &points, + Qt::KeyboardModifiers modifiers) +{ + PointerTouchEventInfo eventInfo; + eventInfo.window = window; + eventInfo.points = points; + eventInfo.modifiers = modifiers; + touchEventQueue.enqueue(eventInfo); +} + +static void enqueueTabletEvent(QWindow *window, const QPointF &local, const QPointF &global, + int device, int pointerType, Qt::MouseButtons buttons, qreal pressure, + int xTilt, int yTilt, qreal tangentialPressure, qreal rotation, + int z, qint64 uid, Qt::KeyboardModifiers modifiers) +{ + PointerTabletEventInfo eventInfo; + eventInfo.window = window; + eventInfo.local = local; + eventInfo.global = global; + eventInfo.device = device; + eventInfo.pointerType = pointerType; + eventInfo.buttons = buttons; + eventInfo.pressure = pressure; + eventInfo.xTilt = xTilt; + eventInfo.yTilt = yTilt; + eventInfo.tangentialPressure = tangentialPressure; + eventInfo.rotation = rotation; + eventInfo.z = z; + eventInfo.uid = uid; + eventInfo.modifiers = modifiers; + tabletEventQueue.enqueue(eventInfo); +} + +static void flushTouchEvents(QTouchDevice *touchDevice) +{ + while (!touchEventQueue.isEmpty()) { + PointerTouchEventInfo eventInfo = touchEventQueue.dequeue(); + if (eventInfo.window) { + QWindowSystemInterface::handleTouchEvent(eventInfo.window, + touchDevice, + eventInfo.points, + eventInfo.modifiers); + } + } +} + +static void flushTabletEvents() +{ + while (!tabletEventQueue.isEmpty()) { + PointerTabletEventInfo eventInfo = tabletEventQueue.dequeue(); + if (eventInfo.window) { + QWindowSystemInterface::handleTabletEvent(eventInfo.window, + eventInfo.local, + eventInfo.global, + eventInfo.device, + eventInfo.pointerType, + eventInfo.buttons, + eventInfo.pressure, + eventInfo.xTilt, + eventInfo.yTilt, + eventInfo.tangentialPressure, + eventInfo.rotation, + eventInfo.z, + eventInfo.uid, + eventInfo.modifiers); + } + } +} + +static bool draggingActive() +{ +#if QT_CONFIG(draganddrop) + return QWindowsDrag::isDragging(); +#else + return false; +#endif +} + bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result) { *result = 0; @@ -426,6 +535,9 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd, if (et & QtWindows::NonClientEventFlag) return false; // Let DefWindowProc() handle Non Client messages. + if (draggingActive()) + return false; // Let DoDragDrop() loop handle it. + if (count < 1) return false; @@ -452,6 +564,8 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd, QList touchPoints; + bool primaryPointer = false; + if (QWindowsContext::verbose > 1) qCDebug(lcQpaEvents).noquote().nospace() << showbase << __FUNCTION__ @@ -494,16 +608,23 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd, touchPoint.state = stationaryTouchPoint ? Qt::TouchPointStationary : Qt::TouchPointMoved; m_lastTouchPositions.insert(touchPoint.id, touchPoint.normalPosition); } + if (touchInfo[i].pointerInfo.pointerFlags & POINTER_FLAG_PRIMARY) + primaryPointer = true; + touchPoints.append(touchPoint); // Avoid getting repeated messages for this frame if there are multiple pointerIds QWindowsContext::user32dll.skipPointerFrameMessages(touchInfo[i].pointerInfo.pointerId); } - - QWindowSystemInterface::handleTouchEvent(window, m_touchDevice, touchPoints, - QWindowsKeyMapper::queryKeyboardModifiers()); - - return true; + if (primaryPointer) { + // Postpone event delivery to avoid hanging inside DoDragDrop(). + // Only the primary pointer will generate mouse messages. + enqueueTouchEvent(window, touchPoints, QWindowsKeyMapper::queryKeyboardModifiers()); + } else { + QWindowSystemInterface::handleTouchEvent(window, m_touchDevice, touchPoints, + QWindowsKeyMapper::queryKeyboardModifiers()); + } + return false; // Allow mouse messages to be generated. } bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, @@ -512,6 +633,9 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin if (et & QtWindows::NonClientEventFlag) return false; // Let DefWindowProc() handle Non Client messages. + if (draggingActive()) + return false; // Let DoDragDrop() loop handle it. + POINTER_PEN_INFO *penInfo = static_cast(vPenInfo); RECT pRect, dRect; @@ -592,20 +716,25 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin } const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers(); - QWindowSystemInterface::handleTabletEvent(target, localPos, hiResGlobalPos, device, type, mouseButtons, - pressure, xTilt, yTilt, tangentialPressure, rotation, z, - pointerId, keyModifiers); - break; + // Postpone event delivery to avoid hanging inside DoDragDrop(). + enqueueTabletEvent(target, localPos, hiResGlobalPos, device, type, mouseButtons, + pressure, xTilt, yTilt, tangentialPressure, rotation, z, + pointerId, keyModifiers); + return false; // Allow mouse messages to be generated. } } return true; } -// SetCursorPos()/TrackMouseEvent() will generate old-style WM_MOUSE messages. Handle them here. +// Process old-style mouse messages here. bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result) { Q_UNUSED(et); + // Generate enqueued events. + flushTouchEvents(m_touchDevice); + flushTabletEvents(); + *result = 0; if (msg.message != WM_MOUSELEAVE && msg.message != WM_MOUSEMOVE) return false; From 34633627bab55ced39872fac3c1909769aef12da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 3 Oct 2018 14:08:10 +0200 Subject: [PATCH 0077/1650] wasm: force static builds This removes the need for specifying "-static" on the configure line. Shared builds are on the roadmap (QTBUG-63925), but not currently supported. Change-Id: I7f72ac702bc77304abfa6a962cb1139c25fb5e35 Reviewed-by: Oswald Buddenhagen --- configure.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.json b/configure.json index 3702c24f63..949e9b6f7b 100644 --- a/configure.json +++ b/configure.json @@ -582,7 +582,7 @@ "shared": { "label": "Building shared libraries", "autoDetect": "!config.uikit", - "condition": "!config.integrity", + "condition": "!config.integrity && !config.wasm", "output": [ "shared", "publicFeature", From 94a829689efdd33562e2aeb78e8a408b5c1c10a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 3 Oct 2018 15:04:32 +0200 Subject: [PATCH 0078/1650] wasm: disable thread configure option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This removes the need for “-no-feature thread”. Thread support will be added at later point in time, see QTBUG-64625. Change-Id: I4d1dedd527aa83d6033bf108f5f34e759517b954 Reviewed-by: Lorn Potter Reviewed-by: Oswald Buddenhagen --- configure.json | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.json b/configure.json index 949e9b6f7b..522bd34e9b 100644 --- a/configure.json +++ b/configure.json @@ -1119,6 +1119,7 @@ "label": "Thread support", "purpose": "Provides QThread and related classes.", "section": "Kernel", + "condition": "!config.wasm", "output": [ "publicFeature" ] }, "future": { From b88eaa255a4646446e0842f3d8f732b39d09a65f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 17 Oct 2018 11:42:22 +0200 Subject: [PATCH 0079/1650] macOS: Use correct text background color MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 582d221b29bbf introduced a regression where the default Base color is no longer white in light mode, for some use cases like querying QApplication::palette() and when using style sheets. [NSColor windowBackgroundColor] is not the correct color for QPalette:Base, [NSColor textBackgroundColor] is, except for the Disabled state which uses windowBackgroundColor to get a grayed-out look. This also changes the dark mode Base color slightly, from RGB(0.196, 0.196, 0.196) to RGB(0.118, 0.118, 0.118). Task-number: QTBUG-70966 Change-Id: I1ff494a09980ff2d04b2e2c43ee0bcc8e26ba9e7 Fixes: QTBUG-70966 Reviewed-by: Tor Arne Vestbø Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qcocoasystemsettings.mm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm index 672b0e4f25..aef2c6cf48 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm +++ b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm @@ -75,8 +75,9 @@ QPalette * qt_mac_createSystemPalette() palette->setBrush(QPalette::Disabled, QPalette::Text, dark); palette->setBrush(QPalette::Disabled, QPalette::ButtonText, dark); palette->setBrush(QPalette::Disabled, QPalette::Base, backgroundBrush); - palette->setBrush(QPalette::Active, QPalette::Base, backgroundBrush); - palette->setBrush(QPalette::Inactive, QPalette::Base, backgroundBrush); + QBrush textBackgroundBrush = qt_mac_toQBrush([NSColor textBackgroundColor]); + palette->setBrush(QPalette::Active, QPalette::Base, textBackgroundBrush); + palette->setBrush(QPalette::Inactive, QPalette::Base, textBackgroundBrush); palette->setColor(QPalette::Disabled, QPalette::Dark, QColor(191, 191, 191)); palette->setColor(QPalette::Active, QPalette::Dark, QColor(191, 191, 191)); palette->setColor(QPalette::Inactive, QPalette::Dark, QColor(191, 191, 191)); From 44eeeb8e816fbdcd77ad734cfe7a7ec28da1c5ed Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Mon, 1 Oct 2018 12:24:08 +0200 Subject: [PATCH 0080/1650] Upgrade PCRE2 to 10.32 [ChangeLog][Third-Party Code] PCRE2 was updated to version 10.32. Change-Id: Id3bf7df0003f626cd1135d0508a5a489ff02f1e5 Reviewed-by: Edward Welbourne --- src/3rdparty/pcre2/LICENCE | 14 +- src/3rdparty/pcre2/qt_attribution.json | 6 +- src/3rdparty/pcre2/src/pcre2.h | 30 +- src/3rdparty/pcre2/src/pcre2_auto_possess.c | 7 +- src/3rdparty/pcre2/src/pcre2_chartables.c | 46 +- src/3rdparty/pcre2/src/pcre2_compile.c | 336 +- src/3rdparty/pcre2/src/pcre2_dfa_match.c | 271 +- src/3rdparty/pcre2/src/pcre2_error.c | 15 +- src/3rdparty/pcre2/src/pcre2_extuni.c | 8 +- src/3rdparty/pcre2/src/pcre2_find_bracket.c | 3 +- src/3rdparty/pcre2/src/pcre2_internal.h | 131 +- src/3rdparty/pcre2/src/pcre2_intmodedep.h | 17 + src/3rdparty/pcre2/src/pcre2_jit_compile.c | 37 +- src/3rdparty/pcre2/src/pcre2_maketables.c | 9 +- src/3rdparty/pcre2/src/pcre2_match.c | 54 +- src/3rdparty/pcre2/src/pcre2_pattern_info.c | 3 +- src/3rdparty/pcre2/src/pcre2_serialize.c | 22 +- src/3rdparty/pcre2/src/pcre2_string_utils.c | 38 +- src/3rdparty/pcre2/src/pcre2_study.c | 6 +- src/3rdparty/pcre2/src/pcre2_substitute.c | 47 +- src/3rdparty/pcre2/src/pcre2_tables.c | 378 +- src/3rdparty/pcre2/src/pcre2_ucd.c | 6751 +++++++++-------- src/3rdparty/pcre2/src/pcre2_ucp.h | 48 +- .../pcre2/src/sljit/sljitConfigInternal.h | 29 +- .../pcre2/src/sljit/sljitExecAllocator.c | 9 +- src/3rdparty/pcre2/src/sljit/sljitLir.c | 10 +- src/3rdparty/pcre2/src/sljit/sljitLir.h | 20 +- .../pcre2/src/sljit/sljitNativeARM_64.c | 250 +- .../pcre2/src/sljit/sljitNativeARM_T2_32.c | 112 +- .../pcre2/src/sljit/sljitNativeMIPS_32.c | 4 +- .../pcre2/src/sljit/sljitNativeMIPS_64.c | 4 +- .../pcre2/src/sljit/sljitNativeMIPS_common.c | 48 +- .../pcre2/src/sljit/sljitNativeX86_32.c | 79 +- .../pcre2/src/sljit/sljitNativeX86_64.c | 120 +- .../pcre2/src/sljit/sljitNativeX86_common.c | 17 - 35 files changed, 4902 insertions(+), 4077 deletions(-) diff --git a/src/3rdparty/pcre2/LICENCE b/src/3rdparty/pcre2/LICENCE index bfe3c8d528..b0f8804fff 100644 --- a/src/3rdparty/pcre2/LICENCE +++ b/src/3rdparty/pcre2/LICENCE @@ -4,11 +4,11 @@ PCRE2 LICENCE PCRE2 is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. -Release 10 of PCRE2 is distributed under the terms of the "BSD" licence, as -specified below, with one exemption for certain binary redistributions. The -documentation for PCRE2, supplied in the "doc" directory, is distributed under -the same terms as the software itself. The data in the testdata directory is -not copyrighted and is in the public domain. +Releases 10.00 and above of PCRE2 are distributed under the terms of the "BSD" +licence, as specified below, with one exemption for certain binary +redistributions. The documentation for PCRE2, supplied in the "doc" directory, +is distributed under the same terms as the software itself. The data in the +testdata directory is not copyrighted and is in the public domain. The basic library functions are written in C and are freestanding. Also included in the distribution is a just-in-time compiler that can be used to @@ -35,7 +35,7 @@ PCRE2 JUST-IN-TIME COMPILATION SUPPORT Written by: Zoltan Herczeg Email local part: hzmester -Emain domain: freemail.hu +Email domain: freemail.hu Copyright(c) 2010-2018 Zoltan Herczeg All rights reserved. @@ -46,7 +46,7 @@ STACK-LESS JUST-IN-TIME COMPILER Written by: Zoltan Herczeg Email local part: hzmester -Emain domain: freemail.hu +Email domain: freemail.hu Copyright(c) 2009-2018 Zoltan Herczeg All rights reserved. diff --git a/src/3rdparty/pcre2/qt_attribution.json b/src/3rdparty/pcre2/qt_attribution.json index 4b635cafee..828c4e8314 100644 --- a/src/3rdparty/pcre2/qt_attribution.json +++ b/src/3rdparty/pcre2/qt_attribution.json @@ -7,7 +7,7 @@ "Description": "The PCRE library is a set of functions that implement regular expression pattern matching using the same syntax and semantics as Perl 5.", "Homepage": "http://www.pcre.org/", - "Version": "10.31", + "Version": "10.32", "DownloadLocation": "https://ftp.pcre.org/pub/pcre/pcre2-10.31.tar.bz2", "License": "BSD 3-clause \"New\" or \"Revised\" License", "LicenseId": "BSD-3-Clause", @@ -26,7 +26,7 @@ Copyright (c) 2013-2013 Tilera Corporation (jiwang@tilera.com)" "Path": "src/sljit", "Description": "The PCRE library is a set of functions that implement regular expression pattern matching using the same syntax and semantics as Perl 5.", "Homepage": "http://www.pcre.org/", - "Version": "10.31", + "Version": "10.32", "DownloadLocation": "https://ftp.pcre.org/pub/pcre/pcre2-10.31.tar.bz2", "License": "BSD 2-clause \"Simplified\" License", "LicenseId": "BSD-2-Clause", @@ -34,4 +34,4 @@ Copyright (c) 2013-2013 Tilera Corporation (jiwang@tilera.com)" "Copyright": "Copyright (c) Zoltan Herczeg Copyright 2013-2013 Tilera Corporation(jiwang@tilera.com)" } -] \ No newline at end of file +] diff --git a/src/3rdparty/pcre2/src/pcre2.h b/src/3rdparty/pcre2/src/pcre2.h index fffcc307d0..3d2feb7a6b 100644 --- a/src/3rdparty/pcre2/src/pcre2.h +++ b/src/3rdparty/pcre2/src/pcre2.h @@ -5,7 +5,7 @@ /* This is the public header file for the PCRE library, second API, to be #included by applications that call PCRE2 functions. - Copyright (c) 2016-2017 University of Cambridge + Copyright (c) 2016-2018 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -41,10 +41,16 @@ POSSIBILITY OF SUCH DAMAGE. /* The current PCRE version information. */ -#define PCRE2_MAJOR 10 -#define PCRE2_MINOR 31 -#define PCRE2_PRERELEASE -#define PCRE2_DATE 2018-02-12 +#define PCRE2_MAJOR 10 +#define PCRE2_MINOR 32 +#define PCRE2_PRERELEASE +#define PCRE2_DATE 2018-09-10 + +/* For the benefit of systems without stdint.h, an alternative is to use +inttypes.h. The existence of these headers is checked by configure or CMake. */ + +#define PCRE2_HAVE_STDINT_H 1 +#define PCRE2_HAVE_INTTYPES_H 1 /* When an application links to a PCRE DLL in Windows, the symbols that are imported have to be identified as such. When building PCRE2, the appropriate @@ -81,12 +87,18 @@ set, we ensure here that it has no effect. */ #define PCRE2_CALL_CONVENTION #endif -/* Have to include limits.h, stdlib.h and stdint.h to ensure that size_t and -uint8_t, UCHAR_MAX, etc are defined. */ +/* Have to include limits.h, stdlib.h and stdint.h (or inttypes.h) to ensure +that size_t and uint8_t, UCHAR_MAX, etc are defined. If the system has neither +header, the relevant values must be provided by some other means. */ #include #include + +#if PCRE2_HAVE_STDINT_H #include +#elif PCRE2_HAVE_INTTYPES_H +#include +#endif /* Allow for C++ users compiling this directly. */ @@ -269,6 +281,7 @@ pcre2_pattern_convert(). */ #define PCRE2_ERROR_INTERNAL_UNKNOWN_NEWLINE 156 #define PCRE2_ERROR_BACKSLASH_G_SYNTAX 157 #define PCRE2_ERROR_PARENS_QUERY_R_MISSING_CLOSING 158 +/* Error 159 is obsolete and should now never occur */ #define PCRE2_ERROR_VERB_ARGUMENT_NOT_ALLOWED 159 #define PCRE2_ERROR_VERB_UNKNOWN 160 #define PCRE2_ERROR_SUBPATTERN_NUMBER_TOO_BIG 161 @@ -303,6 +316,8 @@ pcre2_pattern_convert(). */ #define PCRE2_ERROR_INTERNAL_BAD_CODE_IN_SKIP 190 #define PCRE2_ERROR_NO_SURROGATES_IN_UTF16 191 #define PCRE2_ERROR_BAD_LITERAL_OPTIONS 192 +#define PCRE2_ERROR_SUPPORTED_ONLY_IN_UNICODE 193 +#define PCRE2_ERROR_INVALID_HYPHEN_IN_OPTIONS 194 /* "Expected" matching error codes: no match and partial match. */ @@ -387,6 +402,7 @@ released, the numbers must not be changed. */ #define PCRE2_ERROR_BADSERIALIZEDDATA (-62) #define PCRE2_ERROR_HEAPLIMIT (-63) #define PCRE2_ERROR_CONVERT_SYNTAX (-64) +#define PCRE2_ERROR_INTERNAL_DUPMATCH (-65) /* Request types for pcre2_pattern_info() */ diff --git a/src/3rdparty/pcre2/src/pcre2_auto_possess.c b/src/3rdparty/pcre2/src/pcre2_auto_possess.c index 23275a2e39..2ce152e952 100644 --- a/src/3rdparty/pcre2/src/pcre2_auto_possess.c +++ b/src/3rdparty/pcre2/src/pcre2_auto_possess.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2017 University of Cambridge + New API code Copyright (c) 2016-2018 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -505,7 +505,7 @@ Arguments: utf TRUE in UTF mode cb compile data block base_list the data list of the base opcode - base_end the end of the data list + base_end the end of the base opcode rec_limit points to recursion depth counter Returns: TRUE if the auto-possessification is possible @@ -730,7 +730,7 @@ for(;;) if ((*xclass_flags & XCL_MAP) == 0) { /* No bits are set for characters < 256. */ - if (list[1] == 0) return TRUE; + if (list[1] == 0) return (*xclass_flags & XCL_NOT) == 0; /* Might be an empty repeat. */ continue; } @@ -1235,6 +1235,7 @@ for (;;) #endif case OP_MARK: + case OP_COMMIT_ARG: case OP_PRUNE_ARG: case OP_SKIP_ARG: case OP_THEN_ARG: diff --git a/src/3rdparty/pcre2/src/pcre2_chartables.c b/src/3rdparty/pcre2/src/pcre2_chartables.c index 203cb1a4ab..4046500c00 100644 --- a/src/3rdparty/pcre2/src/pcre2_chartables.c +++ b/src/3rdparty/pcre2/src/pcre2_chartables.c @@ -2,23 +2,24 @@ * Perl-Compatible Regular Expressions * *************************************************/ -/* This file contains character tables that are used when no external tables -are passed to PCRE2 by the application that calls it. The tables are used only -for characters whose code values are less than 256. +/* This file was automatically written by the dftables auxiliary +program. It contains character tables that are used when no external +tables are passed to PCRE2 by the application that calls it. The tables +are used only for characters whose code values are less than 256. */ -This is a default version of the tables that assumes ASCII encoding. A program -called dftables (which is distributed with PCRE2) can be used to build -alternative versions of this file. This is necessary if you are running in an -EBCDIC environment, or if you want to default to a different encoding, for -example ISO-8859-1. When dftables is run, it creates these tables in the -current locale. If PCRE2 is configured with --enable-rebuild-chartables, this -happens automatically. +/*The dftables program (which is distributed with PCRE2) can be used to +build alternative versions of this file. This is necessary if you are +running in an EBCDIC environment, or if you want to default to a different +encoding, for example ISO-8859-1. When dftables is run, it creates these +tables in the current locale. This happens automatically if PCRE2 is +configured with --enable-rebuild-chartables. */ -The following #includes are present because without them gcc 4.x may remove the -array definition from the final binary if PCRE2 is built into a static library -and dead code stripping is activated. This leads to link errors. Pulling in the -header ensures that the array gets flagged as "someone outside this compilation -unit might reference this" and so it will always be supplied to the linker. */ +/* The following #include is present because without it gcc 4.x may remove +the array definition from the final binary if PCRE2 is built into a static +library and dead code stripping is activated. This leads to link errors. +Pulling in the header ensures that the array gets flagged as "someone +outside this compilation unit might reference this" and so it will always +be supplied to the linker. */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -101,7 +102,7 @@ const uint8_t PRIV(default_tables)[] = { /* This table contains bit maps for various character classes. Each map is 32 bytes long and the bits run from the least significant end of each byte. The classes that have their own maps are: space, xdigit, digit, upper, lower, word, -graph, print, punct, and cntrl. Other classes are built from combinations. */ +graph print, punct, and cntrl. Other classes are built from combinations. */ 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, @@ -159,25 +160,24 @@ graph, print, punct, and cntrl. Other classes are built from combinations. */ 0x04 decimal digit 0x08 hexadecimal digit 0x10 alphanumeric or '_' - 0x80 regular expression metacharacter or binary zero */ - 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ 0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00, /* 8- 15 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ - 0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */ - 0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /* ( - / */ + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - ' */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ( - / */ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */ - 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /* 8 - ? */ + 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x00, /* 8 - ? */ 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* @ - G */ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */ - 0x12,0x12,0x12,0x80,0x80,0x00,0x80,0x10, /* X - _ */ + 0x12,0x12,0x12,0x00,0x00,0x00,0x00,0x10, /* X - _ */ 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* ` - g */ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* h - o */ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* p - w */ - 0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /* x -127 */ + 0x12,0x12,0x12,0x00,0x00,0x00,0x00,0x00, /* x -127 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */ diff --git a/src/3rdparty/pcre2/src/pcre2_compile.c b/src/3rdparty/pcre2/src/pcre2_compile.c index 87530fb584..6bb1de3610 100644 --- a/src/3rdparty/pcre2/src/pcre2_compile.c +++ b/src/3rdparty/pcre2/src/pcre2_compile.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2017 University of Cambridge + New API code Copyright (c) 2016-2018 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -63,8 +63,8 @@ POSSIBILITY OF SUCH DAMAGE. /* Other debugging code can be enabled by these defines. */ -// #define DEBUG_SHOW_CAPTURES -// #define DEBUG_SHOW_PARSED +/* #define DEBUG_SHOW_CAPTURES */ +/* #define DEBUG_SHOW_PARSED */ /* There are a few things that vary with different code unit sizes. Handle them by defining macros in order to minimize #if usage. */ @@ -250,34 +250,35 @@ is present where expected in a conditional group. */ #define META_LOOKBEHINDNOT 0x80250000u /* (? 0 => must have an argument */ { 4, META_MARK, +1 }, - { 6, META_ACCEPT, -1 }, /* < 0 => must not have an argument */ - { 6, META_COMMIT, -1 }, + { 6, META_ACCEPT, -1 }, /* < 0 => Optional argument, convert to pre-MARK */ { 1, META_FAIL, -1 }, { 4, META_FAIL, -1 }, - { 5, META_PRUNE, 0 }, /* Argument is optional; bump META code if found */ + { 6, META_COMMIT, 0 }, + { 5, META_PRUNE, 0 }, /* Optional argument; bump META code if found */ { 4, META_SKIP, 0 }, { 4, META_THEN, 0 } }; @@ -610,8 +612,8 @@ static const int verbcount = sizeof(verbs)/sizeof(verbitem); /* Verb opcodes, indexed by their META code offset from META_MARK. */ static const uint32_t verbops[] = { - OP_MARK, OP_ACCEPT, OP_COMMIT, OP_FAIL, OP_PRUNE, OP_PRUNE_ARG, OP_SKIP, - OP_SKIP_ARG, OP_THEN, OP_THEN_ARG }; + OP_MARK, OP_ACCEPT, OP_FAIL, OP_COMMIT, OP_COMMIT_ARG, OP_PRUNE, + OP_PRUNE_ARG, OP_SKIP, OP_SKIP_ARG, OP_THEN, OP_THEN_ARG }; /* Offsets from OP_STAR for case-independent and negative repeat opcodes. */ @@ -729,7 +731,7 @@ enum { ERR0 = COMPILE_ERROR_BASE, ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69, ERR70, ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERR78, ERR79, ERR80, ERR81, ERR82, ERR83, ERR84, ERR85, ERR86, ERR87, ERR88, ERR89, ERR90, - ERR91, ERR92}; + ERR91, ERR92, ERR93, ERR94 }; /* This is a table of start-of-pattern options such as (*UTF) and settings such as (*LIMIT_MATCH=nnnn) and (*CRLF). For completeness and backward @@ -976,8 +978,8 @@ for (;;) case META_POSIX_NEG: fprintf(stderr, "META_POSIX_NEG %d", *pptr++); break; case META_ACCEPT: fprintf(stderr, "META (*ACCEPT)"); break; - case META_COMMIT: fprintf(stderr, "META (*COMMIT)"); break; case META_FAIL: fprintf(stderr, "META (*FAIL)"); break; + case META_COMMIT: fprintf(stderr, "META (*COMMIT)"); break; case META_PRUNE: fprintf(stderr, "META (*PRUNE)"); break; case META_SKIP: fprintf(stderr, "META (*SKIP)"); break; case META_THEN: fprintf(stderr, "META (*THEN)"); break; @@ -1067,6 +1069,10 @@ for (;;) fprintf(stderr, "META (*MARK:"); goto SHOWARG; + case META_COMMIT_ARG: + fprintf(stderr, "META (*COMMIT:"); + goto SHOWARG; + case META_PRUNE_ARG: fprintf(stderr, "META (*PRUNE:"); goto SHOWARG; @@ -1435,6 +1441,48 @@ else if ((i = escapes[c - ESCAPES_FIRST]) != 0) escape = -i; /* Else return a special escape */ if (cb != NULL && (escape == ESC_P || escape == ESC_p || escape == ESC_X)) cb->external_flags |= PCRE2_HASBKPORX; /* Note \P, \p, or \X */ + + /* Perl supports \N{name} for character names and \N{U+dddd} for numerical + Unicode code points, as well as plain \N for "not newline". PCRE does not + support \N{name}. However, it does support quantification such as \N{2,3}, + so if \N{ is not followed by U+dddd we check for a quantifier. */ + + if (escape == ESC_N && ptr < ptrend && *ptr == CHAR_LEFT_CURLY_BRACKET) + { + PCRE2_SPTR p = ptr + 1; + + /* \N{U+ can be handled by the \x{ code. However, this construction is + not valid in EBCDIC environments because it specifies a Unicode + character, not a codepoint in the local code. For example \N{U+0041} + must be "A" in all environments. Also, in Perl, \N{U+ forces Unicode + casing semantics for the entire pattern, so allow it only in UTF (i.e. + Unicode) mode. */ + + if (ptrend - p > 1 && *p == CHAR_U && p[1] == CHAR_PLUS) + { +#ifdef EBCDIC + *errorcodeptr = ERR93; +#else + if (utf) + { + ptr = p + 1; + escape = 0; /* Not a fancy escape after all */ + goto COME_FROM_NU; + } + else *errorcodeptr = ERR93; +#endif + } + + /* Give an error if what follows is not a quantifier, but don't override + an error set by the quantifier reader (e.g. number overflow). */ + + else + { + if (!read_repeat_counts(&p, ptrend, NULL, NULL, errorcodeptr) && + *errorcodeptr == 0) + *errorcodeptr = ERR37; + } + } } } @@ -1462,6 +1510,7 @@ else /* A number of Perl escapes are not handled by PCRE. We give an explicit error. */ + case CHAR_F: case CHAR_l: case CHAR_L: *errorcodeptr = ERR37; @@ -1719,6 +1768,9 @@ else { if (ptr < ptrend && *ptr == CHAR_LEFT_CURLY_BRACKET) { +#ifndef EBCDIC + COME_FROM_NU: +#endif if (++ptr >= ptrend || *ptr == CHAR_RIGHT_CURLY_BRACKET) { *errorcodeptr = ERR78; @@ -1852,19 +1904,6 @@ else } } -/* Perl supports \N{name} for character names, as well as plain \N for "not -newline". PCRE does not support \N{name}. However, it does support -quantification such as \N{2,3}. */ - -if (escape == ESC_N && ptr < ptrend && *ptr == CHAR_LEFT_CURLY_BRACKET && - ptrend - ptr > 2) - { - PCRE2_SPTR p = ptr + 1; - if (!read_repeat_counts(&p, ptrend, NULL, NULL, errorcodeptr) && - *errorcodeptr == 0) - *errorcodeptr = ERR37; - } - /* Set the pointer to the next character before returning. */ *ptrptr = ptr; @@ -2251,11 +2290,14 @@ typedef struct nest_save { #define NSF_RESET 0x0001u #define NSF_CONDASSERT 0x0002u -/* Of the options that are changeable within the pattern, these are tracked -during parsing. The rest are used from META_OPTIONS items when compiling. */ +/* Options that are changeable within the pattern must be tracked during +parsing. Some (e.g. PCRE2_EXTENDED) are implemented entirely during parsing, +but all must be tracked so that META_OPTIONS items set the correct values for +the main compiling phase. */ -#define PARSE_TRACKED_OPTIONS \ - (PCRE2_DUPNAMES|PCRE2_EXTENDED|PCRE2_EXTENDED_MORE|PCRE2_NO_AUTO_CAPTURE) +#define PARSE_TRACKED_OPTIONS (PCRE2_CASELESS|PCRE2_DOTALL|PCRE2_DUPNAMES| \ + PCRE2_EXTENDED|PCRE2_EXTENDED_MORE|PCRE2_MULTILINE|PCRE2_NO_AUTO_CAPTURE| \ + PCRE2_UNGREEDY) /* States used for analyzing ranges in character classes. The two OK values must be last. */ @@ -2290,6 +2332,7 @@ uint32_t *previous_callout = NULL; uint32_t *parsed_pattern = cb->parsed_pattern; uint32_t *parsed_pattern_end = cb->parsed_pattern_end; uint32_t meta_quantifier = 0; +uint32_t add_after_mark = 0; uint16_t nest_depth = 0; int after_manual_callout = 0; int expect_cond_assert = 0; @@ -2434,11 +2477,17 @@ while (ptr < ptrend) /* EITHER: not both options set */ ((options & (PCRE2_EXTENDED | PCRE2_ALT_VERBNAMES)) != (PCRE2_EXTENDED | PCRE2_ALT_VERBNAMES)) || - /* OR: character > 255 */ - c > 255 || - /* OR: not a # comment or white space */ - (c != CHAR_NUMBER_SIGN && (cb->ctypes[c] & ctype_space) == 0) - )) +#ifdef SUPPORT_UNICODE + /* OR: character > 255 AND not Unicode Pattern White Space */ + (c > 255 && (c|1) != 0x200f && (c|1) != 0x2029) || +#endif + /* OR: not a # comment or isspace() white space */ + (c < 256 && c != CHAR_NUMBER_SIGN && (cb->ctypes[c] & ctype_space) == 0 +#ifdef SUPPORT_UNICODE + /* and not CHAR_NEL when Unicode is supported */ + && c != CHAR_NEL +#endif + ))) { PCRE2_SIZE verbnamelength; @@ -2461,6 +2510,16 @@ while (ptr < ptrend) goto FAILED; } *verblengthptr = (uint32_t)verbnamelength; + + /* If this name was on a verb such as (*ACCEPT) which does not continue, + a (*MARK) was generated for the name. We now add the original verb as the + next item. */ + + if (add_after_mark != 0) + { + *parsed_pattern++ = add_after_mark; + add_after_mark = 0; + } break; case CHAR_BACKSLASH: @@ -2510,11 +2569,18 @@ while (ptr < ptrend) /* Skip over whitespace and # comments in extended mode. Note that c is a character, not a code unit, so we must not use MAX_255 to test its size - because MAX_255 tests code units and is assumed TRUE in 8-bit mode. */ + because MAX_255 tests code units and is assumed TRUE in 8-bit mode. The + whitespace characters are those designated as "Pattern White Space" by + Unicode, which are the isspace() characters plus CHAR_NEL (newline), which is + U+0085 in Unicode, plus U+200E, U+200F, U+2028, and U+2029. These are a + subset of space characters that match \h and \v. */ if ((options & PCRE2_EXTENDED) != 0) { if (c < 256 && (cb->ctypes[c] & ctype_space) != 0) continue; +#ifdef SUPPORT_UNICODE + if (c == CHAR_NEL || (c|1) == 0x200f || (c|1) == 0x2029) continue; +#endif if (c == CHAR_NUMBER_SIGN) { while (ptr < ptrend) @@ -3206,7 +3272,6 @@ while (ptr < ptrend) tempptr = ptr; escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, options, TRUE, cb); - if (errorcode != 0) { CLASS_ESCAPE_FAILED: @@ -3454,13 +3519,25 @@ while (ptr < ptrend) if (*ptr++ == CHAR_COLON) /* Skip past : or ) */ { - if (verbs[i].has_arg < 0) /* Argument is forbidden */ + /* Some optional arguments can be treated as a preceding (*MARK) */ + + if (verbs[i].has_arg < 0) { - errorcode = ERR59; - goto FAILED; + add_after_mark = verbs[i].meta; + *parsed_pattern++ = META_MARK; } - *parsed_pattern++ = verbs[i].meta + - ((verbs[i].meta != META_MARK)? 0x00010000u:0); + + /* The remaining verbs with arguments (except *MARK) need a different + opcode. */ + + else + { + *parsed_pattern++ = verbs[i].meta + + ((verbs[i].meta != META_MARK)? 0x00010000u:0); + } + + /* Set up for reading the name in the main loop. */ + verblengthptr = parsed_pattern++; verbnamestart = ptr; inverbname = TRUE; @@ -3521,17 +3598,39 @@ while (ptr < ptrend) else { + BOOL hyphenok = TRUE; + uint32_t oldoptions = options; + top_nest->reset_group = 0; top_nest->max_group = 0; set = unset = 0; optset = &set; + /* ^ at the start unsets imnsx and disables the subsequent use of - */ + + if (ptr < ptrend && *ptr == CHAR_CIRCUMFLEX_ACCENT) + { + options &= ~(PCRE2_CASELESS|PCRE2_MULTILINE|PCRE2_NO_AUTO_CAPTURE| + PCRE2_DOTALL|PCRE2_EXTENDED|PCRE2_EXTENDED_MORE); + hyphenok = FALSE; + ptr++; + } + while (ptr < ptrend && *ptr != CHAR_RIGHT_PARENTHESIS && *ptr != CHAR_COLON) { switch (*ptr++) { - case CHAR_MINUS: optset = &unset; break; + case CHAR_MINUS: + if (!hyphenok) + { + errorcode = ERR94; + ptr--; /* Correct the offset */ + goto FAILED; + } + optset = &unset; + hyphenok = FALSE; + break; case CHAR_J: /* Record that it changed in the external options */ *optset |= PCRE2_DUPNAMES; @@ -3591,7 +3690,7 @@ while (ptr < ptrend) /* If nothing changed, no need to record. */ - if (set != 0 || unset != 0) + if (options != oldoptions) { *parsed_pattern++ = META_OPTIONS; *parsed_pattern++ = options; @@ -3896,9 +3995,8 @@ while (ptr < ptrend) if (*ptr == CHAR_DOT) { if (++ptr >= ptrend || !IS_DIGIT(*ptr)) goto BAD_VERSION_CONDITION; - if (!read_number(&ptr, ptrend, -1, 99 , ERR79, &minor, &errorcode)) - goto FAILED; - if (minor < 10) minor *= 10; + minor = (*ptr++ - CHAR_0) * 10; + if (IS_DIGIT(*ptr)) minor += *ptr++ - CHAR_0; if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS) goto BAD_VERSION_CONDITION; } @@ -4261,11 +4359,11 @@ goto FAILED; /************************************************* -* Find first significant op code * +* Find first significant opcode * *************************************************/ /* This is called by several functions that scan a compiled expression looking -for a fixed first character, or an anchoring op code etc. It skips over things +for a fixed first character, or an anchoring opcode etc. It skips over things that do not influence this. For some calls, it makes sense to skip negative forward and all backward assertions, and also the \b assertion; for others it does not. @@ -5472,7 +5570,7 @@ for (;; pptr++) set xclass = TRUE. Then, in the pre-compile phase, accumulate the length of the extra data and reset the pointer. This is so that very large classes that contain a zillion wide characters or Unicode property tests - do not overwrite the work space (which is on the stack). */ + do not overwrite the workspace (which is on the stack). */ if (class_uchardata > class_uchardata_base) { @@ -5563,7 +5661,7 @@ for (;; pptr++) if (class_has_8bitchar > 0) { *code++ |= XCL_MAP; - memmove(code + (32 / sizeof(PCRE2_UCHAR)), code, + (void)memmove(code + (32 / sizeof(PCRE2_UCHAR)), code, CU2BYTES(class_uchardata - code)); if (negate_class && !xclass_has_prop) for (i = 0; i < 32; i++) classbits[i] = ~classbits[i]; @@ -5655,6 +5753,7 @@ for (;; pptr++) cb->had_pruneorskip = TRUE; /* Fall through */ case META_MARK: + case META_COMMIT_ARG: VERB_ARG: *code++ = verbops[(meta - META_MARK) >> 16]; /* The length is in characters. */ @@ -6509,7 +6608,7 @@ for (;; pptr++) /* Wrap the recursion call in OP_BRA brackets. */ - memmove(previous + 1 + LINK_SIZE, previous, CU2BYTES(1 + LINK_SIZE)); + (void)memmove(previous + 1 + LINK_SIZE, previous, CU2BYTES(1 + LINK_SIZE)); op_previous = *previous = OP_BRA; PUT(previous, 1, 2 + 2*LINK_SIZE); previous[2 + 2*LINK_SIZE] = OP_KET; @@ -6589,7 +6688,7 @@ for (;; pptr++) if (repeat_max <= 1 || repeat_max == REPEAT_UNLIMITED) { - memmove(previous + 1, previous, CU2BYTES(len)); + (void)memmove(previous + 1, previous, CU2BYTES(len)); code++; if (repeat_max == 0) { @@ -6610,7 +6709,7 @@ for (;; pptr++) else { int linkoffset; - memmove(previous + 2 + LINK_SIZE, previous, CU2BYTES(len)); + (void)memmove(previous + 2 + LINK_SIZE, previous, CU2BYTES(len)); code += 2 + LINK_SIZE; *previous++ = OP_BRAZERO + repeat_type; *previous++ = OP_BRA; @@ -6811,7 +6910,7 @@ for (;; pptr++) if (*bracode == OP_COND || *bracode == OP_SCOND) { int nlen = (int)(code - bracode); - memmove(bracode + 1 + LINK_SIZE, bracode, CU2BYTES(nlen)); + (void)memmove(bracode + 1 + LINK_SIZE, bracode, CU2BYTES(nlen)); code += 1 + LINK_SIZE; nlen += 1 + LINK_SIZE; *bracode = (*bracode == OP_COND)? OP_BRAPOS : OP_SBRAPOS; @@ -7082,7 +7181,7 @@ for (;; pptr++) else { - memmove(tempcode + 1 + LINK_SIZE, tempcode, CU2BYTES(len)); + (void)memmove(tempcode + 1 + LINK_SIZE, tempcode, CU2BYTES(len)); code += 1 + LINK_SIZE; len += 1 + LINK_SIZE; tempcode[0] = OP_ONCE; @@ -7460,7 +7559,7 @@ length of the BRA and KET and any extra code units that are required at the beginning. We accumulate in a local variable to save frequent testing of lengthptr for NULL. We cannot do this by looking at the value of 'code' at the start and end of each alternative, because compiled items are discarded during -the pre-compile phase so that the work space is not exceeded. */ +the pre-compile phase so that the workspace is not exceeded. */ length = 2 + 2*LINK_SIZE + skipunits; @@ -7622,7 +7721,7 @@ for (;;) { if (cb->open_caps->flag) { - memmove(start_bracket + 1 + LINK_SIZE, start_bracket, + (void)memmove(start_bracket + 1 + LINK_SIZE, start_bracket, CU2BYTES(code - start_bracket)); *start_bracket = OP_ONCE; code += 1 + LINK_SIZE; @@ -7765,10 +7864,11 @@ do { if (!is_anchored(scode, bracket_map, cb, atomcount, TRUE)) return FALSE; } - /* Condition */ + /* Condition. If there is no second branch, it can't be anchored. */ - else if (op == OP_COND) + else if (op == OP_COND || op == OP_SCOND) { + if (scode[GET(scode,1)] != OP_ALT) return FALSE; if (!is_anchored(scode, bracket_map, cb, atomcount, inassert)) return FALSE; } @@ -8003,6 +8103,7 @@ for (;;) break; case OP_MARK: + case OP_COMMIT_ARG: case OP_PRUNE_ARG: case OP_SKIP_ARG: case OP_THEN_ARG: @@ -8221,7 +8322,7 @@ for (i = 0; i < tablecount; i++) if (crc < 0) { - memmove(slot + cb->name_entry_size, slot, + (void)memmove(slot + cb->name_entry_size, slot, CU2BYTES((tablecount - i) * cb->name_entry_size)); break; } @@ -8311,6 +8412,7 @@ for (;; pptr++) break; case META_MARK: /* Add the length of the name. */ + case META_COMMIT_ARG: case META_PRUNE_ARG: case META_SKIP_ARG: case META_THEN_ARG: @@ -8501,6 +8603,7 @@ for (;; pptr++) goto EXIT; case META_MARK: + case META_COMMIT_ARG: case META_PRUNE_ARG: case META_SKIP_ARG: case META_THEN_ARG: @@ -8572,6 +8675,32 @@ for (;; pptr++) case META_LOOKAHEADNOT: pptr = parsed_skip(pptr + 1, PSKIP_KET); if (pptr == NULL) goto PARSED_SKIP_FAILED; + + /* Also ignore any qualifiers that follow a lookahead assertion. */ + + switch (pptr[1]) + { + case META_ASTERISK: + case META_ASTERISK_PLUS: + case META_ASTERISK_QUERY: + case META_PLUS: + case META_PLUS_PLUS: + case META_PLUS_QUERY: + case META_QUERY: + case META_QUERY_PLUS: + case META_QUERY_QUERY: + pptr++; + break; + + case META_MINMAX: + case META_MINMAX_PLUS: + case META_MINMAX_QUERY: + pptr += 3; + break; + + default: + break; + } break; /* Lookbehinds can be ignored, but must themselves be checked. */ @@ -8942,6 +9071,7 @@ for (pptr = cb->parsed_pattern; *pptr != META_END; pptr++) break; case META_MARK: + case META_COMMIT_ARG: case META_PRUNE_ARG: case META_SKIP_ARG: case META_THEN_ARG: diff --git a/src/3rdparty/pcre2/src/pcre2_dfa_match.c b/src/3rdparty/pcre2/src/pcre2_dfa_match.c index c6184ff5e9..9b43237da7 100644 --- a/src/3rdparty/pcre2/src/pcre2_dfa_match.c +++ b/src/3rdparty/pcre2/src/pcre2_dfa_match.c @@ -181,7 +181,8 @@ static const uint8_t coptable[] = { 0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */ 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */ - 0, 0, 0, 0, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */ + 0, 0, /* COMMIT, COMMIT_ARG */ + 0, 0, 0, /* FAIL, ACCEPT, ASSERT_ACCEPT */ 0, 0, 0 /* CLOSE, SKIPZERO, DEFINE */ }; @@ -254,7 +255,8 @@ static const uint8_t poptable[] = { 0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ 0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */ 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */ - 0, 0, 0, 0, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */ + 0, 0, /* COMMIT, COMMIT_ARG */ + 0, 0, 0, /* FAIL, ACCEPT, ASSERT_ACCEPT */ 0, 0, 0 /* CLOSE, SKIPZERO, DEFINE */ }; @@ -292,6 +294,35 @@ typedef struct stateblock { #define INTS_PER_STATEBLOCK (int)(sizeof(stateblock)/sizeof(int)) +/* Before version 10.32 the recursive calls of internal_dfa_match() were passed +local working space and output vectors that were created on the stack. This has +caused issues for some patterns, especially in small-stack environments such as +Windows. A new scheme is now in use which sets up a vector on the stack, but if +this is too small, heap memory is used, up to the heap_limit. The main +parameters are all numbers of ints because the workspace is a vector of ints. + +The size of the starting stack vector, DFA_START_RWS_SIZE, is in bytes, and is +defined in pcre2_internal.h so as to be available to pcre2test when it is +finding the minimum heap requirement for a match. */ + +#define OVEC_UNIT (sizeof(PCRE2_SIZE)/sizeof(int)) + +#define RWS_BASE_SIZE (DFA_START_RWS_SIZE/sizeof(int)) /* Stack vector */ +#define RWS_RSIZE 1000 /* Work size for recursion */ +#define RWS_OVEC_RSIZE (1000*OVEC_UNIT) /* Ovector for recursion */ +#define RWS_OVEC_OSIZE (2*OVEC_UNIT) /* Ovector in other cases */ + +/* This structure is at the start of each workspace block. */ + +typedef struct RWS_anchor { + struct RWS_anchor *next; + unsigned int size; /* Number of ints */ + unsigned int free; /* Number of ints */ +} RWS_anchor; + +#define RWS_ANCHOR_SIZE (sizeof(RWS_anchor)/sizeof(int)) + + /************************************************* * Process a callout * @@ -353,6 +384,61 @@ return (mb->callout)(cb, mb->callout_data); +/************************************************* +* Expand local workspace memory * +*************************************************/ + +/* This function is called when internal_dfa_match() is about to be called +recursively and there is insufficient working space left in the current +workspace block. If there's an existing next block, use it; otherwise get a new +block unless the heap limit is reached. + +Arguments: + rwsptr pointer to block pointer (updated) + ovecsize space needed for an ovector + mb the match block + +Returns: 0 rwsptr has been updated + !0 an error code +*/ + +static int +more_workspace(RWS_anchor **rwsptr, unsigned int ovecsize, dfa_match_block *mb) +{ +RWS_anchor *rws = *rwsptr; +RWS_anchor *new; + +if (rws->next != NULL) + { + new = rws->next; + } + +/* All sizes are in units of sizeof(int), except for mb->heaplimit, which is in +kibibytes. */ + +else + { + unsigned int newsize = rws->size * 2; + unsigned int heapleft = (unsigned int) + (((1024/sizeof(int))*mb->heap_limit - mb->heap_used)); + if (newsize > heapleft) newsize = heapleft; + if (newsize < RWS_RSIZE + ovecsize + RWS_ANCHOR_SIZE) + return PCRE2_ERROR_HEAPLIMIT; + new = mb->memctl.malloc(newsize*sizeof(int), mb->memctl.memory_data); + if (new == NULL) return PCRE2_ERROR_NOMEMORY; + mb->heap_used += newsize; + new->next = NULL; + new->size = newsize; + rws->next = new; + } + +new->free = new->size - RWS_ANCHOR_SIZE; +*rwsptr = new; +return 0; +} + + + /************************************************* * Match a Regular Expression - DFA engine * *************************************************/ @@ -431,7 +517,8 @@ internal_dfa_match( uint32_t offsetcount, int *workspace, int wscount, - uint32_t rlevel) + uint32_t rlevel, + int *RWS) { stateblock *active_states, *new_states, *temp_states; stateblock *next_active_state, *next_new_state; @@ -788,7 +875,7 @@ for (;;) else if (match_count > 0 && ++match_count * 2 > (int)offsetcount) match_count = 0; count = ((match_count == 0)? (int)offsetcount : match_count * 2) - 2; - if (count > 0) memmove(offsets + 2, offsets, + if (count > 0) (void)memmove(offsets + 2, offsets, (size_t)count * sizeof(PCRE2_SIZE)); if (offsetcount >= 2) { @@ -2587,10 +2674,22 @@ for (;;) case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: { - PCRE2_SPTR endasscode = code + GET(code, 1); - PCRE2_SIZE local_offsets[2]; int rc; - int local_workspace[1000]; + int *local_workspace; + PCRE2_SIZE *local_offsets; + PCRE2_SPTR endasscode = code + GET(code, 1); + RWS_anchor *rws = (RWS_anchor *)RWS; + + if (rws->free < RWS_RSIZE + RWS_OVEC_OSIZE) + { + rc = more_workspace(&rws, RWS_OVEC_OSIZE, mb); + if (rc != 0) return rc; + RWS = (int *)rws; + } + + local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free); + local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE; + rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE; while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1); @@ -2600,10 +2699,13 @@ for (;;) ptr, /* where we currently are */ (PCRE2_SIZE)(ptr - start_subject), /* start offset */ local_offsets, /* offset vector */ - sizeof(local_offsets)/sizeof(PCRE2_SIZE), /* size of same */ + RWS_OVEC_OSIZE/OVEC_UNIT, /* size of same */ local_workspace, /* workspace vector */ - sizeof(local_workspace)/sizeof(int), /* size of same */ - rlevel); /* function recursion level */ + RWS_RSIZE, /* size of same */ + rlevel, /* function recursion level */ + RWS); /* recursion workspace */ + + rws->free += RWS_RSIZE + RWS_OVEC_OSIZE; if (rc < 0 && rc != PCRE2_ERROR_NOMATCH) return rc; if ((rc >= 0) == (codevalue == OP_ASSERT || codevalue == OP_ASSERTBACK)) @@ -2615,8 +2717,6 @@ for (;;) case OP_COND: case OP_SCOND: { - PCRE2_SIZE local_offsets[1000]; - int local_workspace[1000]; int codelink = (int)GET(code, 1); PCRE2_UCHAR condcode; @@ -2673,8 +2773,22 @@ for (;;) else { int rc; + int *local_workspace; + PCRE2_SIZE *local_offsets; PCRE2_SPTR asscode = code + LINK_SIZE + 1; PCRE2_SPTR endasscode = asscode + GET(asscode, 1); + RWS_anchor *rws = (RWS_anchor *)RWS; + + if (rws->free < RWS_RSIZE + RWS_OVEC_OSIZE) + { + rc = more_workspace(&rws, RWS_OVEC_OSIZE, mb); + if (rc != 0) return rc; + RWS = (int *)rws; + } + + local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free); + local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE; + rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE; while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1); @@ -2684,10 +2798,13 @@ for (;;) ptr, /* where we currently are */ (PCRE2_SIZE)(ptr - start_subject), /* start offset */ local_offsets, /* offset vector */ - sizeof(local_offsets)/sizeof(PCRE2_SIZE), /* size of same */ + RWS_OVEC_OSIZE/OVEC_UNIT, /* size of same */ local_workspace, /* workspace vector */ - sizeof(local_workspace)/sizeof(int), /* size of same */ - rlevel); /* function recursion level */ + RWS_RSIZE, /* size of same */ + rlevel, /* function recursion level */ + RWS); /* recursion workspace */ + + rws->free += RWS_RSIZE + RWS_OVEC_OSIZE; if (rc < 0 && rc != PCRE2_ERROR_NOMATCH) return rc; if ((rc >= 0) == @@ -2702,13 +2819,25 @@ for (;;) /*-----------------------------------------------------------------*/ case OP_RECURSE: { + int rc; + int *local_workspace; + PCRE2_SIZE *local_offsets; + RWS_anchor *rws = (RWS_anchor *)RWS; dfa_recursion_info *ri; - PCRE2_SIZE local_offsets[1000]; - int local_workspace[1000]; PCRE2_SPTR callpat = start_code + GET(code, 1); uint32_t recno = (callpat == mb->start_code)? 0 : GET2(callpat, 1 + LINK_SIZE); - int rc; + + if (rws->free < RWS_RSIZE + RWS_OVEC_RSIZE) + { + rc = more_workspace(&rws, RWS_OVEC_RSIZE, mb); + if (rc != 0) return rc; + RWS = (int *)rws; + } + + local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free); + local_workspace = ((int *)local_offsets) + RWS_OVEC_RSIZE; + rws->free -= RWS_RSIZE + RWS_OVEC_RSIZE; /* Check for repeating a recursion without advancing the subject pointer. This should catch convoluted mutual recursions. (Some simple @@ -2732,11 +2861,13 @@ for (;;) ptr, /* where we currently are */ (PCRE2_SIZE)(ptr - start_subject), /* start offset */ local_offsets, /* offset vector */ - sizeof(local_offsets)/sizeof(PCRE2_SIZE), /* size of same */ + RWS_OVEC_RSIZE/OVEC_UNIT, /* size of same */ local_workspace, /* workspace vector */ - sizeof(local_workspace)/sizeof(int), /* size of same */ - rlevel); /* function recursion level */ + RWS_RSIZE, /* size of same */ + rlevel, /* function recursion level */ + RWS); /* recursion workspace */ + rws->free += RWS_RSIZE + RWS_OVEC_RSIZE; mb->recursive = new_recursive.prevrec; /* Done this recursion */ /* Ran out of internal offsets */ @@ -2782,10 +2913,25 @@ for (;;) case OP_SCBRAPOS: case OP_BRAPOSZERO: { + int rc; + int *local_workspace; + PCRE2_SIZE *local_offsets; PCRE2_SIZE charcount, matched_count; PCRE2_SPTR local_ptr = ptr; + RWS_anchor *rws = (RWS_anchor *)RWS; BOOL allow_zero; + if (rws->free < RWS_RSIZE + RWS_OVEC_OSIZE) + { + rc = more_workspace(&rws, RWS_OVEC_OSIZE, mb); + if (rc != 0) return rc; + RWS = (int *)rws; + } + + local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free); + local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE; + rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE; + if (codevalue == OP_BRAPOSZERO) { allow_zero = TRUE; @@ -2798,19 +2944,17 @@ for (;;) for (matched_count = 0;; matched_count++) { - PCRE2_SIZE local_offsets[2]; - int local_workspace[1000]; - - int rc = internal_dfa_match( + rc = internal_dfa_match( mb, /* fixed match data */ code, /* this subexpression's code */ local_ptr, /* where we currently are */ (PCRE2_SIZE)(ptr - start_subject), /* start offset */ local_offsets, /* offset vector */ - sizeof(local_offsets)/sizeof(PCRE2_SIZE), /* size of same */ + RWS_OVEC_OSIZE/OVEC_UNIT, /* size of same */ local_workspace, /* workspace vector */ - sizeof(local_workspace)/sizeof(int), /* size of same */ - rlevel); /* function recursion level */ + RWS_RSIZE, /* size of same */ + rlevel, /* function recursion level */ + RWS); /* recursion workspace */ /* Failed to match */ @@ -2827,6 +2971,8 @@ for (;;) local_ptr += charcount; /* Advance temporary position ptr */ } + rws->free += RWS_RSIZE + RWS_OVEC_OSIZE; + /* At this point we have matched the subpattern matched_count times, and local_ptr is pointing to the character after the end of the last match. */ @@ -2869,19 +3015,35 @@ for (;;) /*-----------------------------------------------------------------*/ case OP_ONCE: { - PCRE2_SIZE local_offsets[2]; - int local_workspace[1000]; + int rc; + int *local_workspace; + PCRE2_SIZE *local_offsets; + RWS_anchor *rws = (RWS_anchor *)RWS; - int rc = internal_dfa_match( + if (rws->free < RWS_RSIZE + RWS_OVEC_OSIZE) + { + rc = more_workspace(&rws, RWS_OVEC_OSIZE, mb); + if (rc != 0) return rc; + RWS = (int *)rws; + } + + local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free); + local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE; + rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE; + + rc = internal_dfa_match( mb, /* fixed match data */ code, /* this subexpression's code */ ptr, /* where we currently are */ (PCRE2_SIZE)(ptr - start_subject), /* start offset */ local_offsets, /* offset vector */ - sizeof(local_offsets)/sizeof(PCRE2_SIZE), /* size of same */ + RWS_OVEC_OSIZE/OVEC_UNIT, /* size of same */ local_workspace, /* workspace vector */ - sizeof(local_workspace)/sizeof(int), /* size of same */ - rlevel); /* function recursion level */ + RWS_RSIZE, /* size of same */ + rlevel, /* function recursion level */ + RWS); /* recursion workspace */ + + rws->free += RWS_RSIZE + RWS_OVEC_OSIZE; if (rc >= 0) { @@ -3063,6 +3225,7 @@ pcre2_dfa_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length, PCRE2_SIZE start_offset, uint32_t options, pcre2_match_data *match_data, pcre2_match_context *mcontext, int *workspace, PCRE2_SIZE wscount) { +int rc; const pcre2_real_code *re = (const pcre2_real_code *)code; PCRE2_SPTR start_match; @@ -3071,9 +3234,9 @@ PCRE2_SPTR bumpalong_limit; PCRE2_SPTR req_cu_ptr; BOOL utf, anchored, startline, firstline; - BOOL has_first_cu = FALSE; BOOL has_req_cu = FALSE; + PCRE2_UCHAR first_cu = 0; PCRE2_UCHAR first_cu2 = 0; PCRE2_UCHAR req_cu = 0; @@ -3088,6 +3251,17 @@ pcre2_callout_block cb; dfa_match_block actual_match_block; dfa_match_block *mb = &actual_match_block; +/* Set up a starting block of memory for use during recursive calls to +internal_dfa_match(). By putting this on the stack, it minimizes resource use +in the case when it is not needed. If this is too small, more memory is +obtained from the heap. At the start of each block is an anchor structure.*/ + +int base_recursion_workspace[RWS_BASE_SIZE]; +RWS_anchor *rws = (RWS_anchor *)base_recursion_workspace; +rws->next = NULL; +rws->size = RWS_BASE_SIZE; +rws->free = RWS_BASE_SIZE - RWS_ANCHOR_SIZE; + /* A length equal to PCRE2_ZERO_TERMINATED implies a zero-terminated subject string. */ @@ -3184,6 +3358,7 @@ if (mcontext == NULL) mb->memctl = re->memctl; mb->match_limit = PRIV(default_match_context).match_limit; mb->match_limit_depth = PRIV(default_match_context).depth_limit; + mb->heap_limit = PRIV(default_match_context).heap_limit; } else { @@ -3198,6 +3373,7 @@ else mb->memctl = mcontext->memctl; mb->match_limit = mcontext->match_limit; mb->match_limit_depth = mcontext->depth_limit; + mb->heap_limit = mcontext->heap_limit; } if (mb->match_limit > re->limit_match) @@ -3206,6 +3382,9 @@ if (mb->match_limit > re->limit_match) if (mb->match_limit_depth > re->limit_depth) mb->match_limit_depth = re->limit_depth; +if (mb->heap_limit > re->limit_heap) + mb->heap_limit = re->limit_heap; + mb->start_code = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code)) + re->name_count * re->name_entry_size; mb->tables = re->tables; @@ -3215,6 +3394,7 @@ mb->start_offset = start_offset; mb->moptions = options; mb->poptions = re->overall_options; mb->match_call_count = 0; +mb->heap_used = 0; /* Process the \R and newline settings. */ @@ -3351,8 +3531,6 @@ a match. */ for (;;) { - int rc; - /* ----------------- Start of match optimizations ---------------- */ /* There are some optimizations that avoid running the match if a known @@ -3544,7 +3722,7 @@ for (;;) in characters, we treat it as code units to avoid spending too much time in this optimization. */ - if (end_subject - start_match < re->minlength) return PCRE2_ERROR_NOMATCH; + if (end_subject - start_match < re->minlength) goto NOMATCH_EXIT; /* If req_cu is set, we know that that code unit must appear in the subject for the match to succeed. If the first code unit is set, req_cu @@ -3621,7 +3799,8 @@ for (;;) (uint32_t)match_data->oveccount * 2, /* actual size of same */ workspace, /* workspace vector */ (int)wscount, /* size of same */ - 0); /* function recurse level */ + 0, /* function recurse level */ + base_recursion_workspace); /* initial workspace for recursion */ /* Anything other than "no match" means we are done, always; otherwise, carry on only if not anchored. */ @@ -3637,7 +3816,7 @@ for (;;) match_data->rightchar = (PCRE2_SIZE)( mb->last_used_ptr - subject); match_data->startchar = (PCRE2_SIZE)(start_match - subject); match_data->rc = rc; - return rc; + goto EXIT; } /* Advance to the next subject character unless we are at the end of a line @@ -3668,8 +3847,18 @@ for (;;) } /* "Bumpalong" loop */ +NOMATCH_EXIT: +rc = PCRE2_ERROR_NOMATCH; -return PCRE2_ERROR_NOMATCH; +EXIT: +while (rws->next != NULL) + { + RWS_anchor *next = rws->next; + rws->next = next->next; + mb->memctl.free(next, mb->memctl.memory_data); + } + +return rc; } /* End of pcre2_dfa_match.c */ diff --git a/src/3rdparty/pcre2/src/pcre2_error.c b/src/3rdparty/pcre2/src/pcre2_error.c index d98cae9963..4b3b3f1bc0 100644 --- a/src/3rdparty/pcre2/src/pcre2_error.c +++ b/src/3rdparty/pcre2/src/pcre2_error.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2017 University of Cambridge + New API code Copyright (c) 2016-2018 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -107,7 +107,7 @@ static const unsigned char compile_error_texts[] = /* 35 */ "lookbehind is too complicated\0" "\\C is not allowed in a lookbehind assertion in UTF-" XSTRING(PCRE2_CODE_UNIT_WIDTH) " mode\0" - "PCRE does not support \\L, \\l, \\N{name}, \\U, or \\u\0" + "PCRE2 does not support \\F, \\L, \\l, \\N{name}, \\U, or \\u\0" "number after (?C is greater than 255\0" "closing parenthesis for (?C expected\0" /* 40 */ @@ -133,7 +133,8 @@ static const unsigned char compile_error_texts[] = "internal error: unknown newline setting\0" "\\g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number\0" "(?R (recursive pattern call) must be followed by a closing parenthesis\0" - "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)\0" + /* "an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)\0" */ + "obsolete error (should not occur)\0" /* Was the above */ /* 60 */ "(*VERB) not recognized or malformed\0" "group number is too big\0" @@ -160,7 +161,7 @@ static const unsigned char compile_error_texts[] = "using UCP is disabled by the application\0" "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)\0" "character code point value in \\u.... sequence is too large\0" - "digits missing in \\x{} or \\o{}\0" + "digits missing in \\x{} or \\o{} or \\N{U+}\0" "syntax error or number too big in (?(VERSION condition\0" /* 80 */ "internal error: unknown opcode in auto_possessify()\0" @@ -178,6 +179,8 @@ static const unsigned char compile_error_texts[] = "internal error: bad code value in parsed_skip()\0" "PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES is not allowed in UTF-16 mode\0" "invalid option bits with PCRE2_LITERAL\0" + "\\N{U+dddd} is supported only in Unicode (UTF) mode\0" + "invalid hyphen in option setting\0" ; /* Match-time and UTF error texts are in the same format. */ @@ -255,11 +258,13 @@ static const unsigned char match_error_texts[] = "expected closing curly bracket in replacement string\0" "bad substitution in replacement string\0" /* 60 */ - "match with end before start is not supported\0" + "match with end before start or start moved backwards is not supported\0" "too many replacements (more than INT_MAX)\0" "bad serialized data\0" "heap limit exceeded\0" "invalid syntax\0" + /* 65 */ + "internal error - duplicate substitution match\0" ; diff --git a/src/3rdparty/pcre2/src/pcre2_extuni.c b/src/3rdparty/pcre2/src/pcre2_extuni.c index 11a0bfbdd6..237211abf7 100644 --- a/src/3rdparty/pcre2/src/pcre2_extuni.c +++ b/src/3rdparty/pcre2/src/pcre2_extuni.c @@ -129,11 +129,11 @@ while (eptr < end_subject) if ((ricount & 1) != 0) break; /* Grapheme break required */ } - /* If Extend follows E_Base[_GAZ] do not update lgb; this allows - any number of Extend before a following E_Modifier. */ + /* If Extend or ZWJ follows Extended_Pictographic, do not update lgb; this + allows any number of them before a following Extended_Pictographic. */ - if (rgb != ucp_gbExtend || - (lgb != ucp_gbE_Base && lgb != ucp_gbE_Base_GAZ)) + if ((rgb != ucp_gbExtend && rgb != ucp_gbZWJ) || + lgb != ucp_gbExtended_Pictographic) lgb = rgb; eptr += len; diff --git a/src/3rdparty/pcre2/src/pcre2_find_bracket.c b/src/3rdparty/pcre2/src/pcre2_find_bracket.c index 357385a11c..70baa1394f 100644 --- a/src/3rdparty/pcre2/src/pcre2_find_bracket.c +++ b/src/3rdparty/pcre2/src/pcre2_find_bracket.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge + New API code Copyright (c) 2016-2018 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -131,6 +131,7 @@ for (;;) break; case OP_MARK: + case OP_COMMIT_ARG: case OP_PRUNE_ARG: case OP_SKIP_ARG: case OP_THEN_ARG: diff --git a/src/3rdparty/pcre2/src/pcre2_internal.h b/src/3rdparty/pcre2/src/pcre2_internal.h index 3db9d604f4..8750f2f174 100644 --- a/src/3rdparty/pcre2/src/pcre2_internal.h +++ b/src/3rdparty/pcre2/src/pcre2_internal.h @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2017 University of Cambridge + New API code Copyright (c) 2016-2018 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -165,6 +165,16 @@ by "configure". */ #define INT64_OR_DOUBLE double #endif +/* External (in the C sense) functions and tables that are private to the +libraries are always referenced using the PRIV macro. This makes it possible +for pcre2test.c to include some of the source files from the libraries using a +different PRIV definition to avoid name clashes. It also makes it clear in the +code that a non-static object is being referenced. */ + +#ifndef PRIV +#define PRIV(name) _pcre2_##name +#endif + /* When compiling for use with the Virtual Pascal compiler, these functions need to have their names changed. PCRE2 must be compiled with the -DVPCOMPAT option on the command line. */ @@ -178,50 +188,15 @@ option on the command line. */ #define memset(s,c,n) _memset(s,c,n) #else /* VPCOMPAT */ -/* To cope with SunOS4 and other systems that lack memmove() but have bcopy(), -define a macro for memmove() if HAVE_MEMMOVE is false, provided that HAVE_BCOPY -is set. Otherwise, include an emulating function for those systems that have -neither (there some non-Unix environments where this is the case). */ +/* Otherwise, to cope with SunOS4 and other systems that lack memmove(), define +a macro that calls an emulating function. */ #ifndef HAVE_MEMMOVE -#undef memmove /* some systems may have a macro */ -#ifdef HAVE_BCOPY -#define memmove(a, b, c) bcopy(b, a, c) -#else /* HAVE_BCOPY */ -static void * -pcre2_memmove(void *d, const void *s, size_t n) -{ -size_t i; -unsigned char *dest = (unsigned char *)d; -const unsigned char *src = (const unsigned char *)s; -if (dest > src) - { - dest += n; - src += n; - for (i = 0; i < n; ++i) *(--dest) = *(--src); - return (void *)dest; - } -else - { - for (i = 0; i < n; ++i) *dest++ = *src++; - return (void *)(dest - n); - } -} -#define memmove(a, b, c) pcre2_memmove(a, b, c) -#endif /* not HAVE_BCOPY */ +#undef memmove /* Some systems may have a macro */ +#define memmove(a, b, c) PRIV(memmove)(a, b, c) #endif /* not HAVE_MEMMOVE */ #endif /* not VPCOMPAT */ -/* External (in the C sense) functions and tables that are private to the -libraries are always referenced using the PRIV macro. This makes it possible -for pcre2test.c to include some of the source files from the libraries using a -different PRIV definition to avoid name clashes. It also makes it clear in the -code that a non-static object is being referenced. */ - -#ifndef PRIV -#define PRIV(name) _pcre2_##name -#endif - /* This is an unsigned int value that no UTF character can ever have, as Unicode doesn't go beyond 0x0010ffff. */ @@ -247,12 +222,17 @@ not rely on this. */ pcre2_match() is allocated on the system stack, of this size (bytes). The size must be a multiple of sizeof(PCRE2_SPTR) in all environments, so making it a multiple of 8 is best. Typical frame sizes are a few hundred bytes (it depends -on the number of capturing parentheses) so 20K handles quite a few frames. A +on the number of capturing parentheses) so 20KiB handles quite a few frames. A larger vector on the heap is obtained for patterns that need more frames. The maximum size of this can be limited. */ #define START_FRAMES_SIZE 20480 +/* Similarly, for DFA matching, an initial internal workspace vector is +allocated on the stack. */ + +#define DFA_START_RWS_SIZE 30720 + /* Define the default BSR convention. */ #ifdef BSR_ANYCRLF @@ -585,14 +565,15 @@ these tables. */ #define cbit_cntrl 288 /* [:cntrl:] */ #define cbit_length 320 /* Length of the cbits table */ -/* Bit definitions for entries in the ctypes table. */ +/* Bit definitions for entries in the ctypes table. Do not change these values +without checking pcre2_jit_compile.c, which has an assertion to ensure that +ctype_word has the value 16. */ #define ctype_space 0x01 #define ctype_letter 0x02 #define ctype_digit 0x04 -#define ctype_xdigit 0x08 +#define ctype_xdigit 0x08 /* not actually used any more */ #define ctype_word 0x10 /* alphanumeric or '_' */ -#define ctype_meta 0x80 /* regexp meta char or zero (end pattern) */ /* Offsets of the various tables from the base tables pointer, and total length of the tables. */ @@ -1267,36 +1248,6 @@ contain characters with values greater than 255. */ #define XCL_PROP 3 /* Unicode property (2-byte property code follows) */ #define XCL_NOTPROP 4 /* Unicode inverted property (ditto) */ -/* Escape items that are just an encoding of a particular data value. These -appear in the escapes[] table in pcre2_compile.c as positive numbers. */ - -#ifndef ESC_a -#define ESC_a CHAR_BEL -#endif - -#ifndef ESC_e -#define ESC_e CHAR_ESC -#endif - -#ifndef ESC_f -#define ESC_f CHAR_FF -#endif - -#ifndef ESC_n -#define ESC_n CHAR_LF -#endif - -#ifndef ESC_r -#define ESC_r CHAR_CR -#endif - -/* We can't officially use ESC_t because it is a POSIX reserved identifier -(presumably because of all the others like size_t). */ - -#ifndef ESC_tee -#define ESC_tee CHAR_HT -#endif - /* These are escaped items that aren't just an encoding of a particular data value such as \n. They must have non-zero values, as check_escape() returns 0 for a data character. In the escapes[] table in pcre2_compile.c their values @@ -1578,23 +1529,26 @@ enum { OP_THEN, /* 155 */ OP_THEN_ARG, /* 156 same, but with argument */ OP_COMMIT, /* 157 */ + OP_COMMIT_ARG, /* 158 same, but with argument */ - /* These are forced failure and success verbs */ + /* These are forced failure and success verbs. FAIL and ACCEPT do accept an + argument, but these cases can be compiled as, for example, (*MARK:X)(*FAIL) + without the need for a special opcode. */ - OP_FAIL, /* 158 */ - OP_ACCEPT, /* 159 */ - OP_ASSERT_ACCEPT, /* 160 Used inside assertions */ - OP_CLOSE, /* 161 Used before OP_ACCEPT to close open captures */ + OP_FAIL, /* 159 */ + OP_ACCEPT, /* 160 */ + OP_ASSERT_ACCEPT, /* 161 Used inside assertions */ + OP_CLOSE, /* 162 Used before OP_ACCEPT to close open captures */ /* This is used to skip a subpattern with a {0} quantifier */ - OP_SKIPZERO, /* 162 */ + OP_SKIPZERO, /* 163 */ /* This is used to identify a DEFINE group during compilation so that it can be checked for having only one branch. It is changed to OP_FALSE before compilation finishes. */ - OP_DEFINE, /* 163 */ + OP_DEFINE, /* 164 */ /* This is not an opcode, but is used to check that tables indexed by opcode are the correct length, in order to catch updating errors - there have been @@ -1650,7 +1604,7 @@ some cases doesn't actually use these names at all). */ "Cond false", "Cond true", \ "Brazero", "Braminzero", "Braposzero", \ "*MARK", "*PRUNE", "*PRUNE", "*SKIP", "*SKIP", \ - "*THEN", "*THEN", "*COMMIT", "*FAIL", \ + "*THEN", "*THEN", "*COMMIT", "*COMMIT", "*FAIL", \ "*ACCEPT", "*ASSERT_ACCEPT", \ "Close", "Skip zero", "Define" @@ -1742,7 +1696,8 @@ in UTF-8 mode. The code that uses this table must know about such things. */ 3, 1, 3, /* MARK, PRUNE, PRUNE_ARG */ \ 1, 3, /* SKIP, SKIP_ARG */ \ 1, 3, /* THEN, THEN_ARG */ \ - 1, 1, 1, 1, /* COMMIT, FAIL, ACCEPT, ASSERT_ACCEPT */ \ + 1, 3, /* COMMIT, COMMIT_ARG */ \ + 1, 1, 1, /* FAIL, ACCEPT, ASSERT_ACCEPT */ \ 1+IMM2_SIZE, 1, /* CLOSE, SKIPZERO */ \ 1 /* DEFINE */ @@ -1896,7 +1851,7 @@ extern const ucd_record PRIV(ucd_records)[]; #if PCRE2_CODE_UNIT_WIDTH == 32 extern const ucd_record PRIV(dummy_ucd_record)[]; #endif -extern const uint8_t PRIV(ucd_stage1)[]; +extern const uint16_t PRIV(ucd_stage1)[]; extern const uint16_t PRIV(ucd_stage2)[]; extern const uint32_t PRIV(ucp_gbtable)[]; extern const uint32_t PRIV(ucp_gentype)[]; @@ -1976,6 +1931,14 @@ extern int _pcre2_valid_utf(PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE *); extern BOOL _pcre2_was_newline(PCRE2_SPTR, uint32_t, PCRE2_SPTR, uint32_t *, BOOL); extern BOOL _pcre2_xclass(uint32_t, PCRE2_SPTR, BOOL); + +/* This function is needed only when memmove() is not available. */ + +#if !defined(VPCOMPAT) && !defined(HAVE_MEMMOVE) +#define _pcre2_memmove PCRE2_SUFFIX(_pcre2_memmove) +extern void * _pcre2_memmove(void *, const void *, size_t); +#endif + #endif /* PCRE2_CODE_UNIT_WIDTH */ #endif /* PCRE2_INTERNAL_H_IDEMPOTENT_GUARD */ diff --git a/src/3rdparty/pcre2/src/pcre2_intmodedep.h b/src/3rdparty/pcre2/src/pcre2_intmodedep.h index c4c4c3adb9..62626d0a8a 100644 --- a/src/3rdparty/pcre2/src/pcre2_intmodedep.h +++ b/src/3rdparty/pcre2/src/pcre2_intmodedep.h @@ -793,11 +793,23 @@ typedef struct heapframe { uint8_t return_id; /* Where to go on in internal "return" */ uint8_t op; /* Processing opcode */ + /* At this point, the structure is 16-bit aligned. On most architectures + the alignment requirement for a pointer will ensure that the eptr field below + is 32-bit or 64-bit aligned. However, on m68k it is fine to have a pointer + that is 16-bit aligned. We must therefore ensure that what comes between here + and eptr is an odd multiple of 16 bits so as to get back into 32-bit + alignment. This happens naturally when PCRE2_UCHAR is 8 bits wide, but needs + fudges in the other cases. In the 32-bit case the padding comes first so that + the occu field itself is 32-bit aligned. Without the padding, this structure + is no longer a multiple of PCRE2_SIZE on m68k, and the check below fails. */ + #if PCRE2_CODE_UNIT_WIDTH == 8 PCRE2_UCHAR occu[6]; /* Used for other case code units */ #elif PCRE2_CODE_UNIT_WIDTH == 16 PCRE2_UCHAR occu[2]; /* Used for other case code units */ + uint8_t unused[2]; /* Ensure 32-bit alignment (see above) */ #else + uint8_t unused[2]; /* Ensure 32-bit alignment (see above) */ PCRE2_UCHAR occu[1]; /* Used for other case code units */ #endif @@ -818,6 +830,9 @@ typedef struct heapframe { PCRE2_SIZE ovector[131072]; /* Must be last in the structure */ } heapframe; +/* This typedef is a check that the size of the heapframe structure is a +multiple of PCRE2_SIZE. See various comments above. */ + typedef char check_heapframe_size[ ((sizeof(heapframe) % sizeof(PCRE2_SIZE)) == 0)? (+1):(-1)]; @@ -881,6 +896,8 @@ typedef struct dfa_match_block { PCRE2_SPTR last_used_ptr; /* Latest consulted character */ const uint8_t *tables; /* Character tables */ PCRE2_SIZE start_offset; /* The start offset value */ + PCRE2_SIZE heap_limit; /* As it says */ + PCRE2_SIZE heap_used; /* As it says */ uint32_t match_limit; /* As it says */ uint32_t match_limit_depth; /* As it says */ uint32_t match_call_count; /* Number of calls of internal function */ diff --git a/src/3rdparty/pcre2/src/pcre2_jit_compile.c b/src/3rdparty/pcre2/src/pcre2_jit_compile.c index 80ed1c4ca6..32e985b793 100644 --- a/src/3rdparty/pcre2/src/pcre2_jit_compile.c +++ b/src/3rdparty/pcre2/src/pcre2_jit_compile.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2017 University of Cambridge + New API code Copyright (c) 2016-2018 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -839,6 +839,7 @@ switch(*cc) #endif case OP_MARK: + case OP_COMMIT_ARG: case OP_PRUNE_ARG: case OP_SKIP_ARG: case OP_THEN_ARG: @@ -939,6 +940,7 @@ while (cc < ccend) common->control_head_ptr = 1; /* Fall through. */ + case OP_COMMIT_ARG: case OP_PRUNE_ARG: case OP_MARK: if (common->mark_ptr == 0) @@ -1553,6 +1555,7 @@ while (cc < ccend) break; case OP_MARK: + case OP_COMMIT_ARG: case OP_PRUNE_ARG: case OP_THEN_ARG: SLJIT_ASSERT(common->mark_ptr != 0); @@ -1733,6 +1736,7 @@ while (cc < ccend) break; case OP_MARK: + case OP_COMMIT_ARG: case OP_PRUNE_ARG: case OP_THEN_ARG: SLJIT_ASSERT(common->mark_ptr != 0); @@ -2041,6 +2045,7 @@ while (cc < ccend) break; case OP_MARK: + case OP_COMMIT_ARG: case OP_PRUNE_ARG: case OP_THEN_ARG: SLJIT_ASSERT(common->mark_ptr != 0); @@ -2428,6 +2433,7 @@ while (cc < ccend) break; case OP_MARK: + case OP_COMMIT_ARG: case OP_PRUNE_ARG: case OP_THEN_ARG: SLJIT_ASSERT(common->mark_ptr != 0); @@ -3666,7 +3672,8 @@ if (!common->utf) #endif OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); -OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1)); +OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); +OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1)); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK); OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); @@ -5894,6 +5901,8 @@ for (i = 0; i < 32; i++) } } +if (len == 0) return FALSE; /* Should never occur, but stops analyzers complaining. */ + i = 0; j = 0; @@ -6627,7 +6636,8 @@ if (needstype || needsscript) #endif OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); - OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1)); + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1)); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK); OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); @@ -7254,10 +7264,11 @@ while (cc < end_subject) if ((ricount & 1) != 0) break; /* Grapheme break required */ } - /* If Extend follows E_Base[_GAZ] do not update lgb; this allows - any number of Extend before a following E_Modifier. */ + /* If Extend or ZWJ follows Extended_Pictographic, do not update lgb; this + allows any number of them before a following Extended_Pictographic. */ - if (rgb != ucp_gbExtend || (lgb != ucp_gbE_Base && lgb != ucp_gbE_Base_GAZ)) + if ((rgb != ucp_gbExtend && rgb != ucp_gbZWJ) || + lgb != ucp_gbExtended_Pictographic) lgb = rgb; prevcc = cc; @@ -7309,10 +7320,11 @@ while (cc < end_subject) if ((ricount & 1) != 0) break; /* Grapheme break required */ } - /* If Extend follows E_Base[_GAZ] do not update lgb; this allows - any number of Extend before a following E_Modifier. */ + /* If Extend or ZWJ follows Extended_Pictographic, do not update lgb; this + allows any number of them before a following Extended_Pictographic. */ - if (rgb != ucp_gbExtend || (lgb != ucp_gbE_Base && lgb != ucp_gbE_Base_GAZ)) + if ((rgb != ucp_gbExtend && rgb != ucp_gbZWJ) || + lgb != ucp_gbExtended_Pictographic) lgb = rgb; cc++; @@ -10346,7 +10358,8 @@ backtrack_common *backtrack; PCRE2_UCHAR opcode = *cc; PCRE2_SPTR ccend = cc + 1; -if (opcode == OP_PRUNE_ARG || opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG) +if (opcode == OP_COMMIT_ARG || opcode == OP_PRUNE_ARG || + opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG) ccend += 2 + cc[1]; PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL); @@ -10358,7 +10371,7 @@ if (opcode == OP_SKIP) return ccend; } -if (opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG) +if (opcode == OP_COMMIT_ARG || opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG) { OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2)); @@ -10677,6 +10690,7 @@ while (cc < ccend) case OP_THEN: case OP_THEN_ARG: case OP_COMMIT: + case OP_COMMIT_ARG: cc = compile_control_verb_matchingpath(common, cc, parent); break; @@ -11751,6 +11765,7 @@ while (current) break; case OP_COMMIT: + case OP_COMMIT_ARG: if (!common->local_quit_available) OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_NOMATCH); if (common->quit_label == NULL) diff --git a/src/3rdparty/pcre2/src/pcre2_maketables.c b/src/3rdparty/pcre2/src/pcre2_maketables.c index 2c7ae84d86..537edba8c3 100644 --- a/src/3rdparty/pcre2/src/pcre2_maketables.c +++ b/src/3rdparty/pcre2/src/pcre2_maketables.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge + New API code Copyright (c) 2016-2018 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -141,13 +141,6 @@ for (i = 0; i < 256; i++) if (isdigit(i)) x += ctype_digit; if (isxdigit(i)) x += ctype_xdigit; if (isalnum(i) || i == '_') x += ctype_word; - - /* Note: strchr includes the terminating zero in the characters it considers. - In this instance, that is ok because we want binary zero to be flagged as a - meta-character, which in this sense is any character that terminates a run - of data characters. */ - - if (strchr("\\*+?{^.$|()[", i) != 0) x += ctype_meta; *p++ = x; } diff --git a/src/3rdparty/pcre2/src/pcre2_match.c b/src/3rdparty/pcre2/src/pcre2_match.c index 79cc93f918..8741e1432d 100644 --- a/src/3rdparty/pcre2/src/pcre2_match.c +++ b/src/3rdparty/pcre2/src/pcre2_match.c @@ -43,11 +43,11 @@ POSSIBILITY OF SUCH DAMAGE. #include "config.h" #endif -/* These defines enables debugging code */ +/* These defines enable debugging code */ -//#define DEBUG_FRAMES_DISPLAY -//#define DEBUG_SHOW_OPS -//#define DEBUG_SHOW_RMATCH +/* #define DEBUG_FRAMES_DISPLAY */ +/* #define DEBUG_SHOW_OPS */ +/* #define DEBUG_SHOW_RMATCH */ #ifdef DEBUG_FRAME_DISPLAY #include @@ -149,7 +149,7 @@ changed, the code at RETURN_SWITCH below must be updated in sync. */ enum { RM1=1, RM2, RM3, RM4, RM5, RM6, RM7, RM8, RM9, RM10, RM11, RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20, RM21, RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30, - RM31, RM32, RM33, RM34, RM35 }; + RM31, RM32, RM33, RM34, RM35, RM36 }; #ifdef SUPPORT_WIDE_CHARS enum { RM100=100, RM101 }; @@ -770,7 +770,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); /* ===================================================================== */ /* Real or forced end of the pattern, assertion, or recursion. In an assertion ACCEPT, update the last used pointer and remember the current - frame so that the captures can be fished out of it. */ + frame so that the captures and mark can be fished out of it. */ case OP_ASSERT_ACCEPT: if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr; @@ -1776,7 +1776,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); /* ===================================================================== */ - /* Match a bit-mapped character class, possibly repeatedly. These op codes + /* Match a bit-mapped character class, possibly repeatedly. These opcodes are used when all the characters in the class have values in the range 0-255, and either the matching is caseful, or the characters are in the range 0-127 when UTF processing is enabled. The only difference between @@ -1962,11 +1962,15 @@ fprintf(stderr, "++ op=%d\n", *Fecode); if (reptype == REPTYPE_POS) continue; /* No backtracking */ + /* After \C in UTF mode, Lstart_eptr might be in the middle of a + Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't + go too far. */ + for (;;) { RMATCH(Fecode, RM201); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (Feptr-- == Lstart_eptr) break; /* Tried at original position */ + if (Feptr-- <= Lstart_eptr) break; /* Tried at original position */ BACKCHAR(Feptr); } } @@ -2126,11 +2130,15 @@ fprintf(stderr, "++ op=%d\n", *Fecode); if (reptype == REPTYPE_POS) continue; /* No backtracking */ + /* After \C in UTF mode, Lstart_eptr might be in the middle of a + Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't + go too far. */ + for(;;) { RMATCH(Fecode, RM101); if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (Feptr-- == Lstart_eptr) break; /* Tried at original position */ + if (Feptr-- <= Lstart_eptr) break; /* Tried at original position */ #ifdef SUPPORT_UNICODE if (utf) BACKCHAR(Feptr); #endif @@ -2456,7 +2464,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); /* ===================================================================== */ /* Match a single character type repeatedly. Note that the property type - does not need to be in a stack frame as it not used within an RMATCH() + does not need to be in a stack frame as it is not used within an RMATCH() loop. */ #define Lstart_eptr F->temp_sptr[0] @@ -4002,8 +4010,8 @@ fprintf(stderr, "++ op=%d\n", *Fecode); if (reptype == REPTYPE_POS) continue; /* No backtracking */ /* After \C in UTF mode, Lstart_eptr might be in the middle of a - Unicode character. Use <= pp to ensure backtracking doesn't go too far. - */ + Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't + go too far. */ for(;;) { @@ -4135,7 +4143,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); } break; - /* The "byte" (i.e. "code unit") case is the same as non-UTF */ + /* The "byte" (i.e. "code unit") case is the same as non-UTF */ case OP_ANYBYTE: fc = Lmax - Lmin; @@ -5111,7 +5119,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); /* Positive assertions are like other groups except that PCRE doesn't allow the effect of (*THEN) to escape beyond an assertion; it is therefore treated as NOMATCH. (*ACCEPT) is treated as successful assertion, with its - captures retained. Any other return is an error. */ + captures and mark retained. Any other return is an error. */ #define Lframe_type F->temp_32[0] @@ -5128,6 +5136,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); (char *)assert_accept_frame + offsetof(heapframe, ovector), assert_accept_frame->offset_top * sizeof(PCRE2_SIZE)); Foffset_top = assert_accept_frame->offset_top; + Fmark = assert_accept_frame->mark; break; } if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc); @@ -5416,7 +5425,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); Feptr -= number; } - /* Save the earliest consulted character, then skip to next op code */ + /* Save the earliest consulted character, then skip to next opcode */ if (Feptr < mb->start_used_ptr) mb->start_used_ptr = Feptr; Fecode += 1 + LINK_SIZE; @@ -5501,7 +5510,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); frame so that it points to the final branch. */ case OP_ONCE: - Fback_frame = ((char *)F - (char *)P) + frame_size; + Fback_frame = ((char *)F - (char *)P); for (;;) { uint32_t y = GET(P->ecode,1); @@ -5829,6 +5838,13 @@ fprintf(stderr, "++ op=%d\n", *Fecode); mb->verb_current_recurse = Fcurrent_recurse; RRETURN(MATCH_COMMIT); + case OP_COMMIT_ARG: + Fmark = mb->nomatch_mark = Fecode + 2; + RMATCH(Fecode + PRIV(OP_lengths)[*Fecode] + Fecode[1], RM36); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + mb->verb_current_recurse = Fcurrent_recurse; + RRETURN(MATCH_COMMIT); + case OP_PRUNE: RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM14); if (rrc != MATCH_NOMATCH) RRETURN(rrc); @@ -5921,7 +5937,7 @@ in rrc. */ RETURN_SWITCH: if (Frdepth == 0) return rrc; /* Exit from the top level */ -F = (heapframe *)((char *)F - Fback_frame); /* Back track */ +F = (heapframe *)((char *)F - Fback_frame); /* Backtrack */ mb->cb->callout_flags |= PCRE2_CALLOUT_BACKTRACK; /* Note for callouts */ #ifdef DEBUG_SHOW_RMATCH @@ -5934,7 +5950,7 @@ switch (Freturn_id) LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(16) LBL(17) LBL(18) LBL(19) LBL(20) LBL(21) LBL(22) LBL(23) LBL(24) LBL(25) LBL(26) LBL(27) LBL(28) LBL(29) LBL(30) LBL(31) LBL(32) - LBL(33) LBL(34) LBL(35) + LBL(33) LBL(34) LBL(35) LBL(36) #ifdef SUPPORT_WIDE_CHARS LBL(100) LBL(101) @@ -6275,7 +6291,7 @@ mb->match_limit_depth = (mcontext->depth_limit < re->limit_depth)? /* If a pattern has very many capturing parentheses, the frame size may be very large. Ensure that there are at least 10 available frames by getting an initial vector on the heap if necessary, except when the heap limit prevents this. Get -fewer if possible. (The heap limit is in kilobytes.) */ +fewer if possible. (The heap limit is in kibibytes.) */ if (frame_size <= START_FRAMES_SIZE/10) { diff --git a/src/3rdparty/pcre2/src/pcre2_pattern_info.c b/src/3rdparty/pcre2/src/pcre2_pattern_info.c index 906e9198f5..a29f5eff67 100644 --- a/src/3rdparty/pcre2/src/pcre2_pattern_info.c +++ b/src/3rdparty/pcre2/src/pcre2_pattern_info.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2017 University of Cambridge + New API code Copyright (c) 2016-2018 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -390,6 +390,7 @@ while (TRUE) #endif case OP_MARK: + case OP_COMMIT_ARG: case OP_PRUNE_ARG: case OP_SKIP_ARG: case OP_THEN_ARG: diff --git a/src/3rdparty/pcre2/src/pcre2_serialize.c b/src/3rdparty/pcre2/src/pcre2_serialize.c index d2cc603cbb..cec1a035d1 100644 --- a/src/3rdparty/pcre2/src/pcre2_serialize.c +++ b/src/3rdparty/pcre2/src/pcre2_serialize.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2017 University of Cambridge + New API code Copyright (c) 2016-2018 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -127,7 +127,25 @@ dst_bytes += tables_length; for (i = 0; i < number_of_codes; i++) { re = (const pcre2_real_code *)(codes[i]); - memcpy(dst_bytes, (char *)re, re->blocksize); + (void)memcpy(dst_bytes, (char *)re, re->blocksize); + + /* Certain fields in the compiled code block are re-set during + deserialization. In order to ensure that the serialized data stream is always + the same for the same pattern, set them to zero here. We can't assume the + copy of the pattern is correctly aligned for accessing the fields as part of + a structure. Note the use of sizeof(void *) in the second of these, to + specify the size of a pointer. If sizeof(uint8_t *) is used (tables is a + pointer to uint8_t), gcc gives a warning because the first argument is also a + pointer to uint8_t. Casting the first argument to (void *) can stop this, but + it didn't stop Coverity giving the same complaint. */ + + (void)memset(dst_bytes + offsetof(pcre2_real_code, memctl), 0, + sizeof(pcre2_memctl)); + (void)memset(dst_bytes + offsetof(pcre2_real_code, tables), 0, + sizeof(void *)); + (void)memset(dst_bytes + offsetof(pcre2_real_code, executable_jit), 0, + sizeof(void *)); + dst_bytes += re->blocksize; } diff --git a/src/3rdparty/pcre2/src/pcre2_string_utils.c b/src/3rdparty/pcre2/src/pcre2_string_utils.c index 2a1f282629..d6be01acf5 100644 --- a/src/3rdparty/pcre2/src/pcre2_string_utils.c +++ b/src/3rdparty/pcre2/src/pcre2_string_utils.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge + New API code Copyright (c) 2018 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -50,6 +50,42 @@ functions work only on 8-bit data. */ #include "pcre2_internal.h" +/************************************************* +* Emulated memmove() for systems without it * +*************************************************/ + +/* This function can make use of bcopy() if it is available. Otherwise do it by +steam, as there some non-Unix environments that lack both memmove() and +bcopy(). */ + +#if !defined(VPCOMPAT) && !defined(HAVE_MEMMOVE) +void * +PRIV(memmove)(void *d, const void *s, size_t n) +{ +#ifdef HAVE_BCOPY +bcopy(s, d, n); +return d; +#else +size_t i; +unsigned char *dest = (unsigned char *)d; +const unsigned char *src = (const unsigned char *)s; +if (dest > src) + { + dest += n; + src += n; + for (i = 0; i < n; ++i) *(--dest) = *(--src); + return (void *)dest; + } +else + { + for (i = 0; i < n; ++i) *dest++ = *src++; + return (void *)(dest - n); + } +#endif /* not HAVE_BCOPY */ +} +#endif /* not VPCOMPAT && not HAVE_MEMMOVE */ + + /************************************************* * Compare two zero-terminated PCRE2 strings * *************************************************/ diff --git a/src/3rdparty/pcre2/src/pcre2_study.c b/src/3rdparty/pcre2/src/pcre2_study.c index b92686759d..acbf98b41b 100644 --- a/src/3rdparty/pcre2/src/pcre2_study.c +++ b/src/3rdparty/pcre2/src/pcre2_study.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2017 University of Cambridge + New API code Copyright (c) 2016-2018 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -707,6 +707,7 @@ for (;;) /* Skip these, but we need to add in the name length. */ case OP_MARK: + case OP_COMMIT_ARG: case OP_PRUNE_ARG: case OP_SKIP_ARG: case OP_THEN_ARG: @@ -956,6 +957,7 @@ do case OP_CIRCM: case OP_CLOSE: case OP_COMMIT: + case OP_COMMIT_ARG: case OP_COND: case OP_CREF: case OP_FALSE: @@ -1274,7 +1276,7 @@ do break; /* Single character types set the bits and stop. Note that if PCRE2_UCP - is set, we do not see these op codes because \d etc are converted to + is set, we do not see these opcodes because \d etc are converted to properties. Therefore, these apply in the case when only characters less than 256 are recognized to match the types. */ diff --git a/src/3rdparty/pcre2/src/pcre2_substitute.c b/src/3rdparty/pcre2/src/pcre2_substitute.c index 8da951fc6e..ab8d10908a 100644 --- a/src/3rdparty/pcre2/src/pcre2_substitute.c +++ b/src/3rdparty/pcre2/src/pcre2_substitute.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016 University of Cambridge + New API code Copyright (c) 2016-2018 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -238,10 +238,12 @@ PCRE2_SPTR repend; PCRE2_SIZE extra_needed = 0; PCRE2_SIZE buff_offset, buff_length, lengthleft, fraglength; PCRE2_SIZE *ovector; +PCRE2_SIZE ovecsave[3]; buff_offset = 0; lengthleft = buff_length = *blength; *blength = PCRE2_UNSET; +ovecsave[0] = ovecsave[1] = ovecsave[2] = PCRE2_UNSET; /* Partial matching is not valid. */ @@ -361,13 +363,33 @@ do } /* Handle a successful match. Matches that use \K to end before they start - are not supported. */ - - if (ovector[1] < ovector[0]) + or start before the current point in the subject are not supported. */ + + if (ovector[1] < ovector[0] || ovector[0] < start_offset) { rc = PCRE2_ERROR_BADSUBSPATTERN; goto EXIT; } + + /* Check for the same match as previous. This is legitimate after matching an + empty string that starts after the initial match offset. We have tried again + at the match point in case the pattern is one like /(?<=\G.)/ which can never + match at its starting point, so running the match achieves the bumpalong. If + we do get the same (null) match at the original match point, it isn't such a + pattern, so we now do the empty string magic. In all other cases, a repeat + match should never occur. */ + + if (ovecsave[0] == ovector[0] && ovecsave[1] == ovector[1]) + { + if (ovector[0] == ovector[1] && ovecsave[2] != start_offset) + { + goptions = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED; + ovecsave[2] = start_offset; + continue; /* Back to the top of the loop */ + } + rc = PCRE2_ERROR_INTERNAL_DUPMATCH; + goto EXIT; + } /* Count substitutions with a paranoid check for integer overflow; surely no real call to this function would ever hit this! */ @@ -799,13 +821,18 @@ do } /* End handling a literal code unit */ } /* End of loop for scanning the replacement. */ - /* The replacement has been copied to the output. Update the start offset to - point to the rest of the subject string. If we matched an empty string, - do the magic for global matches. */ - - start_offset = ovector[1]; - goptions = (ovector[0] != ovector[1])? 0 : + /* The replacement has been copied to the output. Save the details of this + match. See above for how this data is used. If we matched an empty string, do + the magic for global matches. Finally, update the start offset to point to + the rest of the subject string. */ + + ovecsave[0] = ovector[0]; + ovecsave[1] = ovector[1]; + ovecsave[2] = start_offset; + + goptions = (ovector[0] != ovector[1] || ovector[0] > start_offset)? 0 : PCRE2_ANCHORED|PCRE2_NOTEMPTY_ATSTART; + start_offset = ovector[1]; } while ((suboptions & PCRE2_SUBSTITUTE_GLOBAL) != 0); /* Repeat "do" loop */ /* Copy the rest of the subject. */ diff --git a/src/3rdparty/pcre2/src/pcre2_tables.c b/src/3rdparty/pcre2/src/pcre2_tables.c index 9f8dc293aa..83d6f9de55 100644 --- a/src/3rdparty/pcre2/src/pcre2_tables.c +++ b/src/3rdparty/pcre2/src/pcre2_tables.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2017 University of Cambridge + New API code Copyright (c) 2016-2018 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -137,9 +137,10 @@ const uint32_t PRIV(ucp_gentype)[] = { /* This table encodes the rules for finding the end of an extended grapheme cluster. Every code point has a grapheme break property which is one of the -ucp_gbXX values defined in pcre2_ucp.h. The 2-dimensional table is indexed by -the properties of two adjacent code points. The left property selects a word -from the table, and the right property selects a bit from that word like this: +ucp_gbXX values defined in pcre2_ucp.h. These changed between Unicode versions +10 and 11. The 2-dimensional table is indexed by the properties of two adjacent +code points. The left property selects a word from the table, and the right +property selects a bit from that word like this: PRIV(ucp_gbtable)[left-property] & (1 << right-property) @@ -166,49 +167,41 @@ are implementing). 6. Do not break after Prepend characters. -7. Do not break within emoji modifier sequences (E_Base or E_Base_GAZ followed - by E_Modifier). Extend characters are allowed before the modifier; this - cannot be represented in this table, the code has to deal with it. +7. Do not break within emoji modifier sequences or emoji zwj sequences. That + is, do not break between characters with the Extended_Pictographic property. + Extend and ZWJ characters are allowed between the characters; this cannot be + represented in this table, the code has to deal with it. -8. Do not break within emoji zwj sequences (ZWJ followed by Glue_After_Zwj or - E_Base_GAZ). - -9. Do not break within emoji flag sequences. That is, do not break between +8. Do not break within emoji flag sequences. That is, do not break between regional indicator (RI) symbols if there are an odd number of RI characters before the break point. This table encodes "join RI characters"; the code has to deal with checking for previous adjoining RIs. -10. Otherwise, break everywhere. +9. Otherwise, break everywhere. */ #define ESZ (1<= 7 && defined(_M_ARMT)) || defined(__thumb2__) +#define SLJIT_CONFIG_ARM_THUMB2 1 +#elif (defined(_M_ARM) && _M_ARM >= 7) +#define SLJIT_CONFIG_ARM_V7 1 #elif defined(_ARM_) #define SLJIT_CONFIG_ARM_V5 1 +#elif defined(_M_ARM64) || defined(__aarch64__) +#define SLJIT_CONFIG_ARM_64 1 #else #define SLJIT_CONFIG_X86_32 1 #endif -#endif /* !WIN32 */ +#endif /* !_WIN32 */ #endif /* SLJIT_CONFIG_AUTO */ #if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) @@ -324,6 +330,11 @@ sparc_cache_flush((from), (to)) #define SLJIT_CACHE_FLUSH_OWN_IMPL 1 +#elif defined _WIN32 + +#define SLJIT_CACHE_FLUSH(from, to) \ + FlushInstructionCache(GetCurrentProcess(), (char*)(from), (char*)(to) - (char*)(from)) + #else /* Calls __ARM_NR_cacheflush on ARM-Linux. */ @@ -371,12 +382,18 @@ typedef int sljit_sw; #define SLJIT_64BIT_ARCHITECTURE 1 #define SLJIT_WORD_SHIFT 3 #ifdef _WIN32 +#ifdef __GNUC__ +/* These types do not require windows.h */ +typedef unsigned long long sljit_uw; +typedef long long sljit_sw; +#else typedef unsigned __int64 sljit_uw; typedef __int64 sljit_sw; -#else +#endif +#else /* !_WIN32 */ typedef unsigned long int sljit_uw; typedef long int sljit_sw; -#endif +#endif /* _WIN32 */ #endif typedef sljit_uw sljit_p; @@ -590,7 +607,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr); #define SLJIT_NUMBER_OF_REGISTERS 26 #define SLJIT_NUMBER_OF_SAVED_REGISTERS 10 -#define SLJIT_LOCALS_OFFSET_BASE (2 * sizeof(sljit_sw)) +#define SLJIT_LOCALS_OFFSET_BASE 0 #elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) diff --git a/src/3rdparty/pcre2/src/sljit/sljitExecAllocator.c b/src/3rdparty/pcre2/src/sljit/sljitExecAllocator.c index f5009788f6..7c18578618 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitExecAllocator.c +++ b/src/3rdparty/pcre2/src/sljit/sljitExecAllocator.c @@ -99,7 +99,14 @@ static SLJIT_INLINE void* alloc_chunk(sljit_uw size) void *retval; #ifdef MAP_ANON - retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0); + + int flags = MAP_PRIVATE | MAP_ANON; + +#ifdef MAP_JIT + flags |= MAP_JIT; +#endif + + retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, flags, -1, 0); #else if (dev_zero < 0) { if (open_dev_zero()) diff --git a/src/3rdparty/pcre2/src/sljit/sljitLir.c b/src/3rdparty/pcre2/src/sljit/sljitLir.c index 5e435f0154..5bdddc10cf 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitLir.c +++ b/src/3rdparty/pcre2/src/sljit/sljitLir.c @@ -26,6 +26,13 @@ #include "sljitLir.h" +#ifdef _WIN32 + +/* For SLJIT_CACHE_FLUSH, which can expand to FlushInstructionCache. */ +#include + +#endif /* _WIN32 */ + #if !(defined SLJIT_STD_MACROS_DEFINED && SLJIT_STD_MACROS_DEFINED) /* These libraries are needed for the macros below. */ @@ -2178,7 +2185,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil #endif -#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) +#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \ + && !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset) { diff --git a/src/3rdparty/pcre2/src/sljit/sljitLir.h b/src/3rdparty/pcre2/src/sljit/sljitLir.h index 920f6d4f78..e71890cf7b 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitLir.h +++ b/src/3rdparty/pcre2/src/sljit/sljitLir.h @@ -138,7 +138,7 @@ of sljitConfigInternal.h */ be specified as scratch registers and the fifth one as saved register on the CPU above and any user code which requires four scratch registers can run unmodified. The SLJIT compiler automatically saves - the content of the two extra scrath register on the stack. Scratch + the content of the two extra scratch register on the stack. Scratch registers can also be preserved by saving their value on the stack but this needs to be done manually. @@ -746,7 +746,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler be mixed. The only exception is SLJIT_MOV32 and SLJIT_MOVU32 whose source register can hold any 32 or 64 bit value, and it is converted to a 32 bit compatible format first. This conversion is free (no instructions are - emitted) on most CPUs. A 32 bit value can also be coverted to a 64 bit + emitted) on most CPUs. A 32 bit value can also be converted to a 64 bit value by SLJIT_MOV_S32 (sign extension) or SLJIT_MOV_U32 (zero extension). Note: memory addressing always uses 64 bit values on 64 bit systems so @@ -773,8 +773,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler */ #define SLJIT_F32_OP SLJIT_I32_OP -/* Many CPUs (x86, ARM, PPC) has status flags which can be set according - to the result of an operation. Other CPUs (MIPS) does not have status +/* Many CPUs (x86, ARM, PPC) have status flags which can be set according + to the result of an operation. Other CPUs (MIPS) do not have status flags, and results must be stored in registers. To cover both architecture types efficiently only two flags are defined by SLJIT: @@ -810,14 +810,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler Using these flags can reduce the number of emitted instructions. E.g. a fast loop can be implemented by decreasing a counter register and set the - zero flag to jump back if the counter register is not reached zero. + zero flag to jump back if the counter register has not reached zero. Motivation: although CPUs can set a large number of flags, usually their values are ignored or only one of them is used. Emulating a large number of flags on systems without flag register is complicated so SLJIT instructions must specify the flag they want to use and only that flag will be emulated. The last arithmetic instruction can be repeated if - multiple flags needs to be checked. + multiple flags need to be checked. */ /* Set Zero status flag. */ @@ -884,7 +884,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile /* Starting index of opcodes for sljit_emit_op1. */ #define SLJIT_OP1_BASE 32 -/* The MOV instruction transfer data from source to destination. +/* The MOV instruction transfers data from source to destination. MOV instruction suffixes: @@ -1156,7 +1156,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi #define SLJIT_FAST_CALL 25 /* Called function must be declared with the SLJIT_FUNC attribute. */ #define SLJIT_CALL 26 - /* Called function must be decalred with cdecl attribute. + /* Called function must be declared with cdecl attribute. This is the default attribute for C functions. */ #define SLJIT_CALL_CDECL 27 @@ -1210,7 +1210,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sl /* Set the destination address of the jump to this label. */ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target); -/* Emit an indirect jump or fast call. Both direct and indirect form +/* Emit an indirect jump or fast call. Direct form: set src to SLJIT_IMM() and srcw to the address Indirect form: any other valid addressing mode type must be between SLJIT_JUMP and SLJIT_FAST_CALL @@ -1274,7 +1274,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil #define SLJIT_MEM_POST 0x1000 /* Emit a single memory load or store with update instruction. When the - requested instruction from is not supported by the CPU, it returns + requested instruction form is not supported by the CPU, it returns with SLJIT_ERR_UNSUPPORTED instead of emulating the instruction. This allows specializing tight loops based on the supported instruction forms (see SLJIT_MEM_SUPP flag). diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeARM_64.c b/src/3rdparty/pcre2/src/sljit/sljitNativeARM_64.c index 8a437bd6a0..27af741487 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeARM_64.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeARM_64.c @@ -37,14 +37,14 @@ typedef sljit_u32 sljit_ins; #define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) #define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) #define TMP_LR (SLJIT_NUMBER_OF_REGISTERS + 4) -#define TMP_SP (SLJIT_NUMBER_OF_REGISTERS + 5) +#define TMP_FP (SLJIT_NUMBER_OF_REGISTERS + 5) #define TMP_FREG1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) #define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) /* r18 - platform register, currently not used */ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 8] = { - 31, 0, 1, 2, 3, 4, 5, 6, 7, 11, 12, 13, 14, 15, 16, 17, 8, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 29, 9, 10, 30, 31 + 31, 0, 1, 2, 3, 4, 5, 6, 7, 11, 12, 13, 14, 15, 16, 17, 8, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 31, 9, 10, 30, 29 }; static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { @@ -68,6 +68,7 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define ADC 0x9a000000 #define ADD 0x8b000000 +#define ADDE 0x8b200000 #define ADDI 0x91000000 #define AND 0x8a000000 #define ANDI 0x92000000 @@ -96,7 +97,8 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define FSUB 0x1e603800 #define LDRI 0xf9400000 #define LDP 0xa9400000 -#define LDP_PST 0xa8c00000 +#define LDP_PRE 0xa9c00000 +#define LDR_PRE 0xf8400c00 #define LSLV 0x9ac02000 #define LSRV 0x9ac02400 #define MADD 0x9b000000 @@ -873,73 +875,51 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); - saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 0); - local_size += saved_regs_size + SLJIT_LOCALS_OFFSET; - local_size = (local_size + 15) & ~0xf; - compiler->local_size = local_size; + saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 2); + if (saved_regs_size & 0x8) + saved_regs_size += sizeof(sljit_sw); - if (local_size <= (63 * sizeof(sljit_sw))) { - FAIL_IF(push_inst(compiler, STP_PRE | 29 | RT2(TMP_LR) - | RN(TMP_SP) | ((-(local_size >> 3) & 0x7f) << 15))); - FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_SP) | (0 << 10))); - offs = (local_size - saved_regs_size) << (15 - 3); - } else { - offs = 0 << 15; - if (saved_regs_size & 0x8) { - offs = 1 << 15; - saved_regs_size += sizeof(sljit_sw); - } - local_size -= saved_regs_size + SLJIT_LOCALS_OFFSET; - if (saved_regs_size > 0) - FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10))); - } + local_size = (local_size + 15) & ~0xf; + compiler->local_size = local_size + saved_regs_size; + + FAIL_IF(push_inst(compiler, STP_PRE | RT(TMP_FP) | RT2(TMP_LR) + | RN(SLJIT_SP) | ((-(saved_regs_size >> 3) & 0x7f) << 15))); + +#ifdef _WIN32 + if (local_size >= 4096) + FAIL_IF(push_inst(compiler, SUBI | RD(TMP_REG1) | RN(SLJIT_SP) | (1 << 10) | (1 << 22))); + else if (local_size > 256) + FAIL_IF(push_inst(compiler, SUBI | RD(TMP_REG1) | RN(SLJIT_SP) | (local_size << 10))); +#endif tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; prev = -1; + offs = 2 << 15; for (i = SLJIT_S0; i >= tmp; i--) { if (prev == -1) { - if (!(offs & (1 << 15))) { - prev = i; - continue; - } - FAIL_IF(push_inst(compiler, STRI | RT(i) | RN(TMP_SP) | (offs >> 5))); - offs += 1 << 15; + prev = i; continue; } - FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(TMP_SP) | offs)); + FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(SLJIT_SP) | offs)); offs += 2 << 15; prev = -1; } for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { if (prev == -1) { - if (!(offs & (1 << 15))) { - prev = i; - continue; - } - FAIL_IF(push_inst(compiler, STRI | RT(i) | RN(TMP_SP) | (offs >> 5))); - offs += 1 << 15; + prev = i; continue; } - FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(TMP_SP) | offs)); + FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(SLJIT_SP) | offs)); offs += 2 << 15; prev = -1; } - SLJIT_ASSERT(prev == -1); + if (prev != -1) + FAIL_IF(push_inst(compiler, STRI | RT(prev) | RN(SLJIT_SP) | (offs >> 5))); - if (compiler->local_size > (63 * sizeof(sljit_sw))) { - /* The local_size is already adjusted by the saved registers. */ - if (local_size > 0xfff) { - FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | ((local_size >> 12) << 10) | (1 << 22))); - local_size &= 0xfff; - } - if (local_size) - FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (local_size << 10))); - FAIL_IF(push_inst(compiler, STP_PRE | 29 | RT2(TMP_LR) - | RN(TMP_SP) | ((-(16 >> 3) & 0x7f) << 15))); - FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_SP) | (0 << 10))); - } + + FAIL_IF(push_inst(compiler, ADDI | RD(TMP_FP) | RN(SLJIT_SP) | (0 << 10))); args = get_arg_count(arg_types); @@ -950,6 +930,64 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi if (args >= 3) FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S2) | RN(TMP_ZERO) | RM(SLJIT_R2))); +#ifdef _WIN32 + if (local_size >= 4096) { + if (local_size < 4 * 4096) { + /* No need for a loop. */ + if (local_size >= 2 * 4096) { + FAIL_IF(push_inst(compiler, LDRI | RT(TMP_ZERO) | RN(TMP_REG1))); + FAIL_IF(push_inst(compiler, SUBI | RD(TMP_REG1) | RN(TMP_REG1) | (1 << 10) | (1 << 22))); + local_size -= 4096; + } + + if (local_size >= 2 * 4096) { + FAIL_IF(push_inst(compiler, LDRI | RT(TMP_ZERO) | RN(TMP_REG1))); + FAIL_IF(push_inst(compiler, SUBI | RD(TMP_REG1) | RN(TMP_REG1) | (1 << 10) | (1 << 22))); + local_size -= 4096; + } + + FAIL_IF(push_inst(compiler, LDRI | RT(TMP_ZERO) | RN(TMP_REG1))); + local_size -= 4096; + } + else { + FAIL_IF(push_inst(compiler, MOVZ | RD(TMP_REG2) | (((local_size >> 12) - 1) << 5))); + FAIL_IF(push_inst(compiler, LDRI | RT(TMP_ZERO) | RN(TMP_REG1))); + FAIL_IF(push_inst(compiler, SUBI | RD(TMP_REG1) | RN(TMP_REG1) | (1 << 10) | (1 << 22))); + FAIL_IF(push_inst(compiler, SUBI | (1 << 29) | RD(TMP_REG2) | RN(TMP_REG2) | (1 << 10))); + FAIL_IF(push_inst(compiler, B_CC | ((((sljit_ins) -3) & 0x7ffff) << 5) | 0x1 /* not-equal */)); + FAIL_IF(push_inst(compiler, LDRI | RT(TMP_ZERO) | RN(TMP_REG1))); + + local_size &= 0xfff; + } + + if (local_size > 256) { + FAIL_IF(push_inst(compiler, SUBI | RD(TMP_REG1) | RN(TMP_REG1) | (local_size << 10))); + FAIL_IF(push_inst(compiler, LDRI | RT(TMP_ZERO) | RN(TMP_REG1))); + } + else if (local_size > 0) + FAIL_IF(push_inst(compiler, LDR_PRE | RT(TMP_ZERO) | RN(TMP_REG1) | ((-local_size & 0x1ff) << 12))); + + FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_REG1) | (0 << 10))); + } + else if (local_size > 256) { + FAIL_IF(push_inst(compiler, LDRI | RT(TMP_ZERO) | RN(TMP_REG1))); + FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(TMP_REG1) | (0 << 10))); + } + else if (local_size > 0) + FAIL_IF(push_inst(compiler, LDR_PRE | RT(TMP_ZERO) | RN(SLJIT_SP) | ((-local_size & 0x1ff) << 12))); + +#else /* !_WIN32 */ + + /* The local_size does not include saved registers size. */ + if (local_size > 0xfff) { + FAIL_IF(push_inst(compiler, SUBI | RD(SLJIT_SP) | RN(SLJIT_SP) | ((local_size >> 12) << 10) | (1 << 22))); + local_size &= 0xfff; + } + if (local_size != 0) + FAIL_IF(push_inst(compiler, SUBI | RD(SLJIT_SP) | RN(SLJIT_SP) | (local_size << 10))); + +#endif /* _WIN32 */ + return SLJIT_SUCCESS; } @@ -957,13 +995,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *comp sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { + sljit_s32 saved_regs_size; + CHECK_ERROR(); CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); - local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 0) + SLJIT_LOCALS_OFFSET; - local_size = (local_size + 15) & ~0xf; - compiler->local_size = local_size; + saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 2); + if (saved_regs_size & 0x8) + saved_regs_size += sizeof(sljit_sw); + + compiler->local_size = saved_regs_size + ((local_size + 15) & ~0xf); return SLJIT_SUCCESS; } @@ -977,71 +1019,59 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *comp FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); - local_size = compiler->local_size; + saved_regs_size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 2); + if (saved_regs_size & 0x8) + saved_regs_size += sizeof(sljit_sw); - saved_regs_size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 0); - if (local_size <= (63 * sizeof(sljit_sw))) - offs = (local_size - saved_regs_size) << (15 - 3); + local_size = compiler->local_size - saved_regs_size; + + /* Load LR as early as possible. */ + if (local_size == 0) + FAIL_IF(push_inst(compiler, LDP | RT(TMP_FP) | RT2(TMP_LR) | RN(SLJIT_SP))); + else if (local_size < 63 * sizeof(sljit_sw)) { + FAIL_IF(push_inst(compiler, LDP_PRE | RT(TMP_FP) | RT2(TMP_LR) + | RN(SLJIT_SP) | (local_size << (15 - 3)))); + } else { - FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR) - | RN(TMP_SP) | (((16 >> 3) & 0x7f) << 15))); - offs = 0 << 15; - if (saved_regs_size & 0x8) { - offs = 1 << 15; - saved_regs_size += sizeof(sljit_sw); - } - local_size -= saved_regs_size + SLJIT_LOCALS_OFFSET; if (local_size > 0xfff) { - FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | ((local_size >> 12) << 10) | (1 << 22))); + FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(SLJIT_SP) | ((local_size >> 12) << 10) | (1 << 22))); local_size &= 0xfff; } if (local_size) - FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | (local_size << 10))); + FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(SLJIT_SP) | (local_size << 10))); + + FAIL_IF(push_inst(compiler, LDP | RT(TMP_FP) | RT2(TMP_LR) | RN(SLJIT_SP))); } tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG; prev = -1; + offs = 2 << 15; for (i = SLJIT_S0; i >= tmp; i--) { if (prev == -1) { - if (!(offs & (1 << 15))) { - prev = i; - continue; - } - FAIL_IF(push_inst(compiler, LDRI | RT(i) | RN(TMP_SP) | (offs >> 5))); - offs += 1 << 15; + prev = i; continue; } - FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(TMP_SP) | offs)); + FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(SLJIT_SP) | offs)); offs += 2 << 15; prev = -1; } for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { if (prev == -1) { - if (!(offs & (1 << 15))) { - prev = i; - continue; - } - FAIL_IF(push_inst(compiler, LDRI | RT(i) | RN(TMP_SP) | (offs >> 5))); - offs += 1 << 15; + prev = i; continue; } - FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(TMP_SP) | offs)); + FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(SLJIT_SP) | offs)); offs += 2 << 15; prev = -1; } - SLJIT_ASSERT(prev == -1); + if (prev != -1) + FAIL_IF(push_inst(compiler, LDRI | RT(prev) | RN(SLJIT_SP) | (offs >> 5))); - if (compiler->local_size <= (63 * sizeof(sljit_sw))) { - FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR) - | RN(TMP_SP) | (((local_size >> 3) & 0x7f) << 15))); - } else if (saved_regs_size > 0) { - FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10))); - } - - FAIL_IF(push_inst(compiler, RET | RN(TMP_LR))); - return SLJIT_SUCCESS; + /* These two can be executed in parallel. */ + FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RN(SLJIT_SP) | (saved_regs_size << 10))); + return push_inst(compiler, RET | RN(TMP_LR)); } /* --------------------------------------------------------------------- */ @@ -1856,6 +1886,46 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil return push_inst(compiler, inst | VT(freg) | RN(mem & REG_MASK) | ((memw & 0x1ff) << 12)); } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset) +{ + sljit_s32 dst_reg; + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_get_local_base(compiler, dst, dstw, offset)); + + SLJIT_ASSERT (SLJIT_LOCALS_OFFSET_BASE == 0); + + dst_reg = FAST_IS_REG(dst) ? dst : TMP_REG1; + + if (offset <= 0xffffff && offset >= -0xffffff) { + ins = ADDI; + if (offset < 0) { + offset = -offset; + ins = SUBI; + } + + if (offset <= 0xfff) + FAIL_IF(push_inst(compiler, ins | RD(dst_reg) | RN(SLJIT_SP) | (offset << 10))); + else { + FAIL_IF(push_inst(compiler, ins | RD(dst_reg) | RN(SLJIT_SP) | ((offset & 0xfff000) >> (12 - 10)) | (1 << 22))); + + offset &= 0xfff; + if (offset != 0) + FAIL_IF(push_inst(compiler, ins | RD(dst_reg) | RN(dst_reg) | (offset << 10))); + } + } + else { + FAIL_IF(load_immediate (compiler, dst_reg, offset)); + /* Add extended register form. */ + FAIL_IF(push_inst(compiler, ADDE | (0x3 << 13) | RD(dst_reg) | RN(SLJIT_SP) | RM(dst_reg))); + } + + if (SLJIT_UNLIKELY(dst & SLJIT_MEM)) + return emit_op_mem(compiler, WORD_SIZE | STORE, dst_reg, dst, dstw, TMP_REG1); + return SLJIT_SUCCESS; +} + SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { struct sljit_const *const_; diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c b/src/3rdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c index 75e7a38b5f..d7024b6d7d 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c @@ -110,6 +110,7 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define ASRSI 0x1000 #define ASR_W 0xfa40f000 #define ASR_WI 0xea4f0020 +#define BCC 0xd000 #define BICI 0xf0200000 #define BKPT 0xbe00 #define BLX 0x4780 @@ -125,6 +126,7 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define EORS 0x4040 #define EOR_W 0xea800000 #define IT 0xbf00 +#define LDRI 0xf8500800 #define LSLS 0x4080 #define LSLSI 0x0000 #define LSL_W 0xfa00f000 @@ -158,6 +160,7 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define SBCI 0xf1600000 #define SBCS 0x4180 #define SBC_W 0xeb600000 +#define SDIV 0xfb90f0f0 #define SMULL 0xfb800000 #define STR_SP 0x9000 #define SUBS 0x1a00 @@ -172,6 +175,7 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define SXTH 0xb200 #define SXTH_W 0xfa0ff080 #define TST 0x4200 +#define UDIV 0xfbb0f0f0 #define UMULL 0xfba00000 #define UXTB 0xb2c0 #define UXTB_W 0xfa5ff080 @@ -339,8 +343,8 @@ static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump, sljit_sw /* Really complex instruction form for branches. */ s = (diff >> 23) & 0x1; - j1 = (~(diff >> 21) ^ s) & 0x1; - j2 = (~(diff >> 22) ^ s) & 0x1; + j1 = (~(diff >> 22) ^ s) & 0x1; + j2 = (~(diff >> 21) ^ s) & 0x1; jump_inst[0] = 0xf000 | (s << 10) | COPY_BITS(diff, 11, 0, 10); jump_inst[1] = (j1 << 13) | (j2 << 11) | (diff & 0x7ff); @@ -520,6 +524,8 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst, { sljit_uw tmp; + /* MOVS cannot be used since it destroy flags. */ + if (imm >= 0x10000) { tmp = get_imm(imm); if (tmp != INVALID_IMM) @@ -1032,6 +1038,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi { sljit_s32 args, size, i, tmp; sljit_ins push = 0; +#ifdef _WIN32 + sljit_uw imm; +#endif CHECK_ERROR(); CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); @@ -1052,12 +1061,25 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1); local_size = ((size + local_size + 7) & ~7) - size; compiler->local_size = local_size; + +#ifdef _WIN32 + if (local_size >= 256) { + if (local_size > 4096) + imm = get_imm(4096); + else + imm = get_imm(local_size & ~0xff); + + SLJIT_ASSERT(imm != INVALID_IMM); + FAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(SLJIT_SP) | imm)); + } +#else if (local_size > 0) { if (local_size <= (127 << 2)) FAIL_IF(push_inst16(compiler, SUB_SP | (local_size >> 2))); else FAIL_IF(emit_op_imm(compiler, SLJIT_SUB | ARG2_IMM, SLJIT_SP, SLJIT_SP, local_size)); } +#endif args = get_arg_count(arg_types); @@ -1068,6 +1090,61 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi if (args >= 3) FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_S2, SLJIT_R2))); +#ifdef _WIN32 + if (local_size >= 256) { + if (local_size > 4096) { + imm = get_imm(4096); + SLJIT_ASSERT(imm != INVALID_IMM); + + if (local_size < 4 * 4096) { + if (local_size > 2 * 4096) { + FAIL_IF(push_inst32(compiler, LDRI | 0x400 | RT4(TMP_REG2) | RN4(TMP_REG1))); + FAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(TMP_REG1) | imm)); + local_size -= 4096; + } + + if (local_size > 2 * 4096) { + FAIL_IF(push_inst32(compiler, LDRI | 0x400 | RT4(TMP_REG2) | RN4(TMP_REG1))); + FAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(TMP_REG1) | imm)); + local_size -= 4096; + } + + FAIL_IF(push_inst32(compiler, LDRI | 0x400 | RT4(TMP_REG2) | RN4(TMP_REG1))); + local_size -= 4096; + + SLJIT_ASSERT(local_size > 0); + } + else { + FAIL_IF(load_immediate(compiler, SLJIT_R3, (local_size >> 12) - 1)); + FAIL_IF(push_inst32(compiler, LDRI | 0x400 | RT4(TMP_REG2) | RN4(TMP_REG1))); + FAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(TMP_REG1) | imm)); + SLJIT_ASSERT(reg_map[SLJIT_R3] < 7); + FAIL_IF(push_inst16(compiler, SUBSI8 | RDN3(SLJIT_R3) | 1)); + FAIL_IF(push_inst16(compiler, BCC | (0x1 << 8) /* not-equal */ | (-7 & 0xff))); + + local_size &= 0xfff; + + if (local_size != 0) + FAIL_IF(push_inst32(compiler, LDRI | 0x400 | RT4(TMP_REG2) | RN4(TMP_REG1))); + } + + if (local_size >= 256) { + imm = get_imm(local_size & ~0xff); + SLJIT_ASSERT(imm != INVALID_IMM); + + FAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(TMP_REG1) | imm)); + } + } + + local_size &= 0xff; + FAIL_IF(push_inst32(compiler, LDRI | 0x400 | (local_size > 0 ? 0x100 : 0) | RT4(TMP_REG2) | RN4(TMP_REG1) | local_size)); + + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SP, TMP_REG1))); + } + else if (local_size > 0) + FAIL_IF(push_inst32(compiler, LDRI | 0x500 | RT4(TMP_REG1) | RN4(SLJIT_SP) | local_size)); +#endif + return SLJIT_SUCCESS; } @@ -1119,11 +1196,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *comp /* Operators */ /* --------------------------------------------------------------------- */ +#if !(defined __ARM_FEATURE_IDIV) && !(defined __ARM_ARCH_EXT_IDIV__) + #ifdef __cplusplus extern "C" { #endif -#if defined(__GNUC__) +#ifdef _WIN32 +extern unsigned long long __rt_udiv(unsigned int denominator, unsigned int numerator); +extern long long __rt_sdiv(int denominator, int numerator); +#elif defined(__GNUC__) extern unsigned int __aeabi_uidivmod(unsigned int numerator, int unsigned denominator); extern int __aeabi_idivmod(int numerator, int denominator); #else @@ -1134,10 +1216,14 @@ extern int __aeabi_idivmod(int numerator, int denominator); } #endif +#endif /* !__ARM_FEATURE_IDIV && !__ARM_ARCH_EXT_IDIV__ */ + SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { +#if !(defined __ARM_FEATURE_IDIV) && !(defined __ARM_ARCH_EXT_IDIV__) sljit_sw saved_reg_list[3]; sljit_sw saved_reg_count; +#endif CHECK_ERROR(); CHECK(check_sljit_emit_op0(compiler, op)); @@ -1155,6 +1241,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile | (reg_map[SLJIT_R0] << 12) | (reg_map[SLJIT_R0] << 16) | reg_map[SLJIT_R1]); +#if (defined __ARM_FEATURE_IDIV) || (defined __ARM_ARCH_EXT_IDIV__) + case SLJIT_DIVMOD_UW: + case SLJIT_DIVMOD_SW: + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG1, SLJIT_R0))); + FAIL_IF(push_inst32(compiler, (op == SLJIT_DIVMOD_UW ? UDIV : SDIV) | RD4(SLJIT_R0) | RN4(SLJIT_R0) | RM4(SLJIT_R1))); + FAIL_IF(push_inst32(compiler, MUL | RD4(SLJIT_R1) | RN4(SLJIT_R0) | RM4(SLJIT_R1))); + return push_inst32(compiler, SUB_W | RD4(SLJIT_R1) | RN4(TMP_REG1) | RM4(SLJIT_R1)); + case SLJIT_DIV_UW: + case SLJIT_DIV_SW: + return push_inst32(compiler, (op == SLJIT_DIV_UW ? UDIV : SDIV) | RD4(SLJIT_R0) | RN4(SLJIT_R0) | RM4(SLJIT_R1)); +#else /* !__ARM_FEATURE_IDIV && !__ARM_ARCH_EXT_IDIV__ */ case SLJIT_DIVMOD_UW: case SLJIT_DIVMOD_SW: case SLJIT_DIV_UW: @@ -1183,7 +1280,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile } } -#if defined(__GNUC__) +#ifdef _WIN32 + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG1, SLJIT_R0))); + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_R0, SLJIT_R1))); + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_R1, TMP_REG1))); + FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM, + ((op | 0x2) == SLJIT_DIV_UW ? SLJIT_FUNC_OFFSET(__rt_udiv) : SLJIT_FUNC_OFFSET(__rt_sdiv)))); +#elif defined(__GNUC__) FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM, ((op | 0x2) == SLJIT_DIV_UW ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod)))); #else @@ -1203,6 +1306,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile | (saved_reg_list[0] << 12) /* ldr rX, [sp], #8/16 */); } return SLJIT_SUCCESS; +#endif /* __ARM_FEATURE_IDIV || __ARM_ARCH_EXT_IDIV__ */ } return SLJIT_SUCCESS; diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_32.c b/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_32.c index 9f9e157a05..094c9923bc 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_32.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_32.c @@ -448,7 +448,7 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t sljit_ins ins = NOP; sljit_u8 offsets[4]; - SLJIT_ASSERT(reg_map[TMP_REG3] == 4 && freg_map[TMP_FREG1] == 12); + SLJIT_ASSERT(reg_map[TMP_REG1] == 4 && freg_map[TMP_FREG1] == 12); arg_types >>= SLJIT_DEF_SHIFT; @@ -516,7 +516,7 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t else if (arg_count != word_arg_count) ins = ADDU | S(word_arg_count) | TA(0) | DA(4 + (offsets[arg_count - 1] >> 2)); else if (arg_count == 1) - ins = ADDU | S(SLJIT_R0) | TA(0) | D(TMP_REG3); + ins = ADDU | S(SLJIT_R0) | TA(0) | DA(4); arg_count--; word_arg_count--; diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_64.c b/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_64.c index ff6f048659..f841aef5dd 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_64.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_64.c @@ -547,7 +547,7 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t sljit_ins prev_ins = NOP; sljit_ins ins = NOP; - SLJIT_ASSERT(reg_map[TMP_REG3] == 4 && freg_map[TMP_FREG1] == 12); + SLJIT_ASSERT(reg_map[TMP_REG1] == 4 && freg_map[TMP_FREG1] == 12); arg_types >>= SLJIT_DEF_SHIFT; @@ -591,7 +591,7 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t if (arg_count != word_arg_count) ins = DADDU | S(word_arg_count) | TA(0) | D(arg_count); else if (arg_count == 1) - ins = DADDU | S(SLJIT_R0) | TA(0) | D(TMP_REG3); + ins = DADDU | S(SLJIT_R0) | TA(0) | DA(4); arg_count--; word_arg_count--; break; diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_common.c b/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_common.c index e108433f70..894e21304b 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_common.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_common.c @@ -57,14 +57,14 @@ typedef sljit_u32 sljit_ins; #define RETURN_ADDR_REG 31 /* Flags are kept in volatile registers. */ -#define EQUAL_FLAG 31 +#define EQUAL_FLAG 3 #define OTHER_FLAG 1 #define TMP_FREG1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) #define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { - 0, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 23, 22, 21, 20, 19, 18, 17, 16, 29, 3, 25, 4 + 0, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 23, 22, 21, 20, 19, 18, 17, 16, 29, 4, 25, 31 }; #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) @@ -612,16 +612,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi /* Frequent case. */ FAIL_IF(push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(-local_size), DR(SLJIT_SP))); base = S(SLJIT_SP); + offs = local_size - (sljit_sw)sizeof(sljit_sw); } else { - FAIL_IF(load_immediate(compiler, DR(TMP_REG1), local_size)); + FAIL_IF(load_immediate(compiler, DR(OTHER_FLAG), local_size)); FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | TA(0) | D(TMP_REG2), DR(TMP_REG2))); - FAIL_IF(push_inst(compiler, SUBU_W | S(SLJIT_SP) | T(TMP_REG1) | D(SLJIT_SP), DR(SLJIT_SP))); + FAIL_IF(push_inst(compiler, SUBU_W | S(SLJIT_SP) | T(OTHER_FLAG) | D(SLJIT_SP), DR(SLJIT_SP))); base = S(TMP_REG2); local_size = 0; + offs = -(sljit_sw)sizeof(sljit_sw); } - offs = local_size - (sljit_sw)(sizeof(sljit_sw)); FAIL_IF(push_inst(compiler, STACK_STORE | base | TA(RETURN_ADDR_REG) | IMM(offs), MOVABLE_INS)); tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; @@ -805,7 +806,8 @@ static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sl if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) { tmp_ar = reg_ar; delay_slot = reg_ar; - } else { + } + else { tmp_ar = DR(TMP_REG1); delay_slot = MOVABLE_INS; } @@ -881,11 +883,39 @@ static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sl static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw) { + sljit_s32 tmp_ar, base, delay_slot; + if (getput_arg_fast(compiler, flags, reg_ar, arg, argw)) return compiler->error; - compiler->cache_arg = 0; - compiler->cache_argw = 0; - return getput_arg(compiler, flags, reg_ar, arg, argw, 0, 0); + + if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) { + tmp_ar = reg_ar; + delay_slot = reg_ar; + } + else { + tmp_ar = DR(TMP_REG1); + delay_slot = MOVABLE_INS; + } + base = arg & REG_MASK; + + if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { + argw &= 0x3; + + if (SLJIT_UNLIKELY(argw)) { + FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | DA(tmp_ar) | SH_IMM(argw), tmp_ar)); + FAIL_IF(push_inst(compiler, ADDU_W | S(base) | TA(tmp_ar) | DA(tmp_ar), tmp_ar)); + } + else + FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(OFFS_REG(arg)) | DA(tmp_ar), tmp_ar)); + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot); + } + + FAIL_IF(load_immediate(compiler, tmp_ar, argw)); + + if (base != 0) + FAIL_IF(push_inst(compiler, ADDU_W | S(base) | TA(tmp_ar) | DA(tmp_ar), tmp_ar)); + + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot); } static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w) diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeX86_32.c b/src/3rdparty/pcre2/src/sljit/sljitNativeX86_32.c index 8a83e273a4..074e64b9f2 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeX86_32.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeX86_32.c @@ -123,34 +123,38 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) if (args > 0) { - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[SLJIT_S0] << 3) | reg_map[SLJIT_R2]; + inst[0] = MOV_r_rm; + inst[1] = MOD_REG | (reg_map[SLJIT_S0] << 3) | reg_map[SLJIT_R2]; + inst += 2; } if (args > 1) { - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[SLJIT_S1] << 3) | reg_map[SLJIT_R1]; + inst[0] = MOV_r_rm; + inst[1] = MOD_REG | (reg_map[SLJIT_S1] << 3) | reg_map[SLJIT_R1]; + inst += 2; } if (args > 2) { - *inst++ = MOV_r_rm; - *inst++ = MOD_DISP8 | (reg_map[SLJIT_S2] << 3) | 0x4 /* esp */; - *inst++ = 0x24; - *inst++ = sizeof(sljit_sw) * (3 + 2); /* saveds >= 3 as well. */ + inst[0] = MOV_r_rm; + inst[1] = MOD_DISP8 | (reg_map[SLJIT_S2] << 3) | 0x4 /* esp */; + inst[2] = 0x24; + inst[3] = sizeof(sljit_sw) * (3 + 2); /* saveds >= 3 as well. */ } #else if (args > 0) { - *inst++ = MOV_r_rm; - *inst++ = MOD_DISP8 | (reg_map[SLJIT_S0] << 3) | reg_map[TMP_REG1]; - *inst++ = sizeof(sljit_sw) * 2; + inst[0] = MOV_r_rm; + inst[1] = MOD_DISP8 | (reg_map[SLJIT_S0] << 3) | reg_map[TMP_REG1]; + inst[2] = sizeof(sljit_sw) * 2; + inst += 3; } if (args > 1) { - *inst++ = MOV_r_rm; - *inst++ = MOD_DISP8 | (reg_map[SLJIT_S1] << 3) | reg_map[TMP_REG1]; - *inst++ = sizeof(sljit_sw) * 3; + inst[0] = MOV_r_rm; + inst[1] = MOD_DISP8 | (reg_map[SLJIT_S1] << 3) | reg_map[TMP_REG1]; + inst[2] = sizeof(sljit_sw) * 3; + inst += 3; } if (args > 2) { - *inst++ = MOV_r_rm; - *inst++ = MOD_DISP8 | (reg_map[SLJIT_S2] << 3) | reg_map[TMP_REG1]; - *inst++ = sizeof(sljit_sw) * 4; + inst[0] = MOV_r_rm; + inst[1] = MOD_DISP8 | (reg_map[SLJIT_S2] << 3) | reg_map[TMP_REG1]; + inst[2] = sizeof(sljit_sw) * 4; } #endif @@ -170,17 +174,36 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi compiler->local_size = local_size; #ifdef _WIN32 - if (local_size > 1024) { -#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) - FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_R0], local_size)); -#else - /* Space for a single argument. This amount is excluded when the stack is allocated below. */ - local_size -= sizeof(sljit_sw); - FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_R0], local_size)); - FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB), - SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, sizeof(sljit_sw))); -#endif - FAIL_IF(sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARG1(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack))); + if (local_size > 0) { + if (local_size <= 4 * 4096) { + if (local_size > 4096) + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -4096); + if (local_size > 2 * 4096) + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -4096 * 2); + if (local_size > 3 * 4096) + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -4096 * 3); + } + else { + EMIT_MOV(compiler, SLJIT_R0, 0, SLJIT_SP, 0); + EMIT_MOV(compiler, SLJIT_R1, 0, SLJIT_IMM, (local_size - 1) >> 12); + + SLJIT_ASSERT (reg_map[SLJIT_R0] == 0); + + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_R0), -4096); + FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB), + SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_IMM, 4096)); + FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB), + SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1)); + + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!inst); + + INC_SIZE(2); + inst[0] = JNE_i8; + inst[1] = (sljit_s8) -16; + } + + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -local_size); } #endif diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeX86_64.c b/src/3rdparty/pcre2/src/sljit/sljitNativeX86_64.c index 635ebd087c..8506565614 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeX86_64.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeX86_64.c @@ -83,6 +83,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size)); set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); + compiler->mode32 = 0; + #ifdef _WIN64 /* Two/four register slots for parameters plus space for xmm6 register if needed. */ if (fscratches >= 6 || fsaveds >= 1) @@ -126,35 +128,39 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi #ifndef _WIN64 if (args > 0) { - *inst++ = REX_W; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[SLJIT_S0] << 3) | 0x7 /* rdi */; + inst[0] = REX_W; + inst[1] = MOV_r_rm; + inst[2] = MOD_REG | (reg_map[SLJIT_S0] << 3) | 0x7 /* rdi */; + inst += 3; } if (args > 1) { - *inst++ = REX_W | REX_R; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_lmap[SLJIT_S1] << 3) | 0x6 /* rsi */; + inst[0] = REX_W | REX_R; + inst[1] = MOV_r_rm; + inst[2] = MOD_REG | (reg_lmap[SLJIT_S1] << 3) | 0x6 /* rsi */; + inst += 3; } if (args > 2) { - *inst++ = REX_W | REX_R; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_lmap[SLJIT_S2] << 3) | 0x2 /* rdx */; + inst[0] = REX_W | REX_R; + inst[1] = MOV_r_rm; + inst[2] = MOD_REG | (reg_lmap[SLJIT_S2] << 3) | 0x2 /* rdx */; } #else if (args > 0) { - *inst++ = REX_W; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[SLJIT_S0] << 3) | 0x1 /* rcx */; + inst[0] = REX_W; + inst[1] = MOV_r_rm; + inst[2] = MOD_REG | (reg_map[SLJIT_S0] << 3) | 0x1 /* rcx */; + inst += 3; } if (args > 1) { - *inst++ = REX_W; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[SLJIT_S1] << 3) | 0x2 /* rdx */; + inst[0] = REX_W; + inst[1] = MOV_r_rm; + inst[2] = MOD_REG | (reg_map[SLJIT_S1] << 3) | 0x2 /* rdx */; + inst += 3; } if (args > 2) { - *inst++ = REX_W | REX_B; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[SLJIT_S2] << 3) | 0x0 /* r8 */; + inst[0] = REX_W | REX_B; + inst[1] = MOV_r_rm; + inst[2] = MOD_REG | (reg_map[SLJIT_S2] << 3) | 0x0 /* r8 */; } #endif } @@ -163,58 +169,42 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi compiler->local_size = local_size; #ifdef _WIN64 - if (local_size > 1024) { - /* Allocate stack for the callback, which grows the stack. */ - inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 + (3 + sizeof(sljit_s32))); - FAIL_IF(!inst); - INC_SIZE(4 + (3 + sizeof(sljit_s32))); - *inst++ = REX_W; - *inst++ = GROUP_BINARY_83; - *inst++ = MOD_REG | SUB | reg_map[SLJIT_SP]; - /* Allocated size for registers must be divisible by 8. */ - SLJIT_ASSERT(!(saved_register_size & 0x7)); - /* Aligned to 16 byte. */ - if (saved_register_size & 0x8) { - *inst++ = 5 * sizeof(sljit_sw); - local_size -= 5 * sizeof(sljit_sw); - } else { - *inst++ = 4 * sizeof(sljit_sw); - local_size -= 4 * sizeof(sljit_sw); + if (local_size > 0) { + if (local_size <= 4 * 4096) { + if (local_size > 4096) + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -4096); + if (local_size > 2 * 4096) + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -4096 * 2); + if (local_size > 3 * 4096) + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -4096 * 3); } - /* Second instruction */ - SLJIT_ASSERT(reg_map[SLJIT_R0] < 8); - *inst++ = REX_W; - *inst++ = MOV_rm_i32; - *inst++ = MOD_REG | reg_lmap[SLJIT_R0]; - sljit_unaligned_store_s32(inst, local_size); -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ - || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - compiler->skip_checks = 1; -#endif - FAIL_IF(sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARG1(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack))); + else { + EMIT_MOV(compiler, SLJIT_R0, 0, SLJIT_SP, 0); + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, (local_size - 1) >> 12); + + SLJIT_ASSERT (reg_map[SLJIT_R0] == 0); + + EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_MEM1(SLJIT_R0), -4096); + FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB), + SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_IMM, 4096)); + FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB), + TMP_REG1, 0, TMP_REG1, 0, SLJIT_IMM, 1)); + + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!inst); + + INC_SIZE(2); + inst[0] = JNE_i8; + inst[1] = (sljit_s8) -19; + } + + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -local_size); } #endif if (local_size > 0) { - if (local_size <= 127) { - inst = (sljit_u8*)ensure_buf(compiler, 1 + 4); - FAIL_IF(!inst); - INC_SIZE(4); - *inst++ = REX_W; - *inst++ = GROUP_BINARY_83; - *inst++ = MOD_REG | SUB | reg_map[SLJIT_SP]; - *inst++ = local_size; - } - else { - inst = (sljit_u8*)ensure_buf(compiler, 1 + 7); - FAIL_IF(!inst); - INC_SIZE(7); - *inst++ = REX_W; - *inst++ = GROUP_BINARY_81; - *inst++ = MOD_REG | SUB | reg_map[SLJIT_SP]; - sljit_unaligned_store_s32(inst, local_size); - inst += sizeof(sljit_s32); - } + FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB), + SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, local_size)); } #ifdef _WIN64 diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeX86_common.c b/src/3rdparty/pcre2/src/sljit/sljitNativeX86_common.c index ab7b36adb2..6f02ee3e8b 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeX86_common.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeX86_common.c @@ -669,23 +669,6 @@ static SLJIT_INLINE sljit_s32 emit_sse2_store(struct sljit_compiler *compiler, static SLJIT_INLINE sljit_s32 emit_sse2_load(struct sljit_compiler *compiler, sljit_s32 single, sljit_s32 dst, sljit_s32 src, sljit_sw srcw); -#ifdef _WIN32 -#include - -static void SLJIT_FUNC sljit_grow_stack(sljit_sw local_size) -{ - /* Workaround for calling the internal _chkstk() function on Windows. - This function touches all 4k pages belongs to the requested stack space, - which size is passed in local_size. This is necessary on Windows where - the stack can only grow in 4k steps. However, this function just burn - CPU cycles if the stack is large enough. However, you don't know it in - advance, so it must always be called. I think this is a bad design in - general even if it has some reasons. */ - *(volatile sljit_s32*)alloca(local_size) = 0; -} - -#endif - #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) #include "sljitNativeX86_32.c" #else From 948f8ce2ecb2d6d2713279311d6090268321f0fb Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 28 Aug 2018 17:51:51 -0700 Subject: [PATCH 0081/1650] QWinEventNotifier: fix crash on application shutdown The event dispatcher can be null already but we may have outstanding QWinEventNotifier objects (like in a QProcess). Patch-By: Tamas Karpati Task-number: QTBUG-70214 Change-Id: I5e432e273def425ea334fffd154f34abfd6cb11a Reviewed-by: Friedemann Kleint --- src/corelib/kernel/qwineventnotifier.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/corelib/kernel/qwineventnotifier.cpp b/src/corelib/kernel/qwineventnotifier.cpp index 24de491326..fe086acb5d 100644 --- a/src/corelib/kernel/qwineventnotifier.cpp +++ b/src/corelib/kernel/qwineventnotifier.cpp @@ -256,6 +256,14 @@ static void CALLBACK wfsoCallback(void *context, BOOLEAN /*ignore*/) { QWinEventNotifierPrivate *nd = reinterpret_cast(context); QAbstractEventDispatcher *eventDispatcher = nd->threadData->eventDispatcher.load(); + + // Happens when Q(Core)Application is destroyed before QWinEventNotifier. + // https://bugreports.qt.io/browse/QTBUG-70214 + if (!eventDispatcher) { // perhaps application is shutting down + qWarning("QWinEventNotifier: no event dispatcher, application shutting down? Cannot deliver event."); + return; + } + QEventDispatcherWin32Private *edp = QEventDispatcherWin32Private::get( static_cast(eventDispatcher)); ++nd->signaledCount; From 5760545ebb5961015e1d2d19a3713ff1d08f91e5 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Thu, 18 Oct 2018 10:39:18 +0200 Subject: [PATCH 0082/1650] QCocoaMenuItem: ignore font hints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Native applications do not use custom fonts in menus, so we should avoid it - our own example app 'menus' demonstrates the problem. To quote Gabriel: Although the Mac HIG don't say that you shouldn't, and there's even a API to do it (which we're obviously not using properly), the truth is that nobody does it. Simply put, it looks wrong on Mac (although it's arguable whether it looks good or bad regardless of the platform). Task-number: QTBUG-29654 Change-Id: Iffd08ad63d419164102b2e738cdf1ebda1967a05 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoamenuitem.h | 1 - src/plugins/platforms/cocoa/qcocoamenuitem.mm | 18 ++---------------- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.h b/src/plugins/platforms/cocoa/qcocoamenuitem.h index 20fc741fb8..c842b08d52 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.h +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.h @@ -119,7 +119,6 @@ private: QString m_text; QIcon m_icon; QPointer m_menu; - QFont m_font; MenuRole m_role; MenuRole m_detectedRole; #ifndef QT_NO_SHORTCUT diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index 21faa6d985..e54b6284e5 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -173,7 +173,7 @@ void QCocoaMenuItem::setIsSeparator(bool isSeparator) void QCocoaMenuItem::setFont(const QFont &font) { - m_font = font; + Q_UNUSED(font) } void QCocoaMenuItem::setRole(MenuRole role) @@ -319,21 +319,7 @@ NSMenuItem *QCocoaMenuItem::sync() text += QLatin1String(" (") + accel.toString(QKeySequence::NativeText) + QLatin1String(")"); #endif - QString finalString = QPlatformTheme::removeMnemonics(text); - bool useAttributedTitle = false; - // Cocoa Font and title - if (m_font.resolve()) { - NSFont *customMenuFont = [NSFont fontWithName:m_font.family().toNSString() - size:m_font.pointSize()]; - if (customMenuFont) { - NSAttributedString *str = [[[NSAttributedString alloc] initWithString:finalString.toNSString() - attributes:@{NSFontAttributeName: customMenuFont}] autorelease]; - m_native.attributedTitle = str; - useAttributedTitle = true; - } - } - if (!useAttributedTitle) - m_native.title = finalString.toNSString(); + m_native.title = QPlatformTheme::removeMnemonics(text).toNSString(); #ifndef QT_NO_SHORTCUT if (accel.count() == 1) { From ef567c3b67c360dc87971f317c929c5c0b159c8b Mon Sep 17 00:00:00 2001 From: Mikhail Svetkin Date: Tue, 16 Oct 2018 14:51:58 +0200 Subject: [PATCH 0083/1650] qedidparser: Fix a condition typo '\040' is 32 and '\176' is 126. The condition is always false "if (buffer[i] < '\040' || buffer[i] > '\176')" Task-number: QTBUG-71156 Change-Id: Ic3d6eae5b8ddb56742315af7e78b58bea2393d7a Reviewed-by: Laszlo Agocs --- src/platformsupport/edid/qedidparser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platformsupport/edid/qedidparser.cpp b/src/platformsupport/edid/qedidparser.cpp index ccaa50704c..06c8852825 100644 --- a/src/platformsupport/edid/qedidparser.cpp +++ b/src/platformsupport/edid/qedidparser.cpp @@ -166,7 +166,7 @@ QString QEdidParser::parseEdidString(const quint8 *data) // Replace non-printable characters with dash for (int i = 0; i < buffer.count(); ++i) { - if (buffer[i] < '\040' && buffer[i] > '\176') + if (buffer[i] < '\040' || buffer[i] > '\176') buffer[i] = '-'; } From b98b49ba00afd0e40847237ce2f2b5b51ca9ed59 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 12 Oct 2018 16:06:55 +0200 Subject: [PATCH 0084/1650] Fix re-running of cmake when a qrc file changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 2af127763194c13c3f7ccce507c94eb2de6dbefe renamed out_depends to _out_depends inside qt5_add_resources but the old (empty) variable was used with add_custom_command. Change-Id: I8005674992b4538bd82375a4f1f70484bc0f0ae5 Reviewed-by: André Klitzing Reviewed-by: Lars Knoll --- src/corelib/Qt5CoreMacros.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/Qt5CoreMacros.cmake b/src/corelib/Qt5CoreMacros.cmake index 581c99ed58..620795d2cf 100644 --- a/src/corelib/Qt5CoreMacros.cmake +++ b/src/corelib/Qt5CoreMacros.cmake @@ -285,7 +285,7 @@ function(QT5_ADD_RESOURCES outfiles ) COMMAND ${Qt5Core_RCC_EXECUTABLE} ARGS ${rcc_options} --name ${outfilename} --output ${outfile} ${infile} MAIN_DEPENDENCY ${infile} - DEPENDS ${_rc_depends} "${out_depends}" VERBATIM) + DEPENDS ${_rc_depends} "${_out_depends}" VERBATIM) set_source_files_properties(${outfile} PROPERTIES SKIP_AUTOMOC ON) set_source_files_properties(${outfile} PROPERTIES SKIP_AUTOUIC ON) list(APPEND ${outfiles} ${outfile}) From c14103be50529f3d00cf1ecadafc0f8156ba7680 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 18 Oct 2018 15:30:14 +0200 Subject: [PATCH 0085/1650] Update dbus header and document its provenance There's been one minor change in a struct and some minor re-ordering of other things within their files (reflected here to simplify future checks); and qt_attribution.json didn't document enough details to ensure reliable review. Task-number: QTBUG-70011 Change-Id: Iccff9cfd899e58cb42837c4628acacd7877c5b01 Reviewed-by: Volker Hilsheimer --- src/dbus/dbus_minimal_p.h | 7 ++++--- src/dbus/qt_attribution.json | 3 +++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/dbus/dbus_minimal_p.h b/src/dbus/dbus_minimal_p.h index b52b0153e4..869c02b59d 100644 --- a/src/dbus/dbus_minimal_p.h +++ b/src/dbus/dbus_minimal_p.h @@ -218,7 +218,7 @@ struct DBusMessageIter int dummy10; /**< Don't use this */ int dummy11; /**< Don't use this */ int pad1; /**< Don't use this */ - int pad2; /**< Don't use this */ + void *pad2; /**< Don't use this */ /* Was int; changed to void* at 1.10.8 */ void *pad3; /**< Don't use this */ }; @@ -251,6 +251,7 @@ struct DBusMessageIter #define DBUS_TYPE_SIGNATURE_AS_STRING "g" #define DBUS_TYPE_UNIX_FD ((int) 'h') #define DBUS_TYPE_UNIX_FD_AS_STRING "h" + #define DBUS_TYPE_ARRAY ((int) 'a') #define DBUS_TYPE_ARRAY_AS_STRING "a" #define DBUS_TYPE_VARIANT ((int) 'v') @@ -270,14 +271,14 @@ struct DBusMessageIter #define DBUS_DICT_ENTRY_END_CHAR ((int) '}') #define DBUS_DICT_ENTRY_END_CHAR_AS_STRING "}" +#define DBUS_MAXIMUM_NAME_LENGTH 255 + #define DBUS_MESSAGE_TYPE_INVALID 0 #define DBUS_MESSAGE_TYPE_METHOD_CALL 1 #define DBUS_MESSAGE_TYPE_METHOD_RETURN 2 #define DBUS_MESSAGE_TYPE_ERROR 3 #define DBUS_MESSAGE_TYPE_SIGNAL 4 -#define DBUS_MAXIMUM_NAME_LENGTH 255 - #define DBUS_INTROSPECT_1_0_XML_NAMESPACE "http://www.freedesktop.org/standards/dbus" #define DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" #define DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd" diff --git a/src/dbus/qt_attribution.json b/src/dbus/qt_attribution.json index 52636ba89b..69d946ba5c 100644 --- a/src/dbus/qt_attribution.json +++ b/src/dbus/qt_attribution.json @@ -6,9 +6,12 @@ "Description": "D-Bus is a message bus system, a simple way for applications to talk to one another.", "Homepage": "https://www.freedesktop.org/wiki/Software/dbus/", + "Version": "Minimal supported is 1.2, compatible up to ...", + "Version": "1.12", "LicenseId": "AFL-2.1 OR GPL-2.0-or-later", "License": "Academic Free License v2.1, or GNU General Public License v2.0 or later", "LicenseFile": "LIBDBUS-1-LICENSE.txt", + "Files": "Fragments from various upstream files, see comments in ...", "Files": "dbus_minimal_p.h", "Copyright": "Copyright (C) 2002, 2003 CodeFactory AB Copyright (C) 2004, 2005 Red Hat, Inc." From c18a91b0dc5e82c0624758a6300f561e36b968fc Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sun, 16 Sep 2018 21:45:55 +0200 Subject: [PATCH 0086/1650] QTableWidget: fix cellChanged signal emitted by takeItem() QTableWidget::takeItem() emitted cellChanged with row and column set to -1. The internal functions searched for item after it was reset to nullptr and therefore it was not found. Since the modified cell is known because it's passed to the takeItem function, the correct row/column can be retrieved from there. Task-number: QTBUG-70478 Change-Id: I5ff5991c49f3200efe95fde4c7d0d28e19be7ebf Reviewed-by: Richard Moe Gustavsen --- src/widgets/itemviews/qtablewidget.cpp | 2 +- .../widgets/itemviews/qtablewidget/tst_qtablewidget.cpp | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/widgets/itemviews/qtablewidget.cpp b/src/widgets/itemviews/qtablewidget.cpp index 11925af7a0..2d539e10ba 100644 --- a/src/widgets/itemviews/qtablewidget.cpp +++ b/src/widgets/itemviews/qtablewidget.cpp @@ -225,7 +225,7 @@ QTableWidgetItem *QTableModel::takeItem(int row, int column) itm->view = 0; itm->d->id = -1; tableItems[i] = 0; - QModelIndex ind = index(itm); + const QModelIndex ind = index(row, column); emit dataChanged(ind, ind); } return itm; diff --git a/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp b/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp index 208ce27c8f..4155ff1ec6 100644 --- a/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp +++ b/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp @@ -362,11 +362,18 @@ void tst_QTableWidget::takeItem() for (int c = 0; c < testWidget->columnCount(); ++c) QCOMPARE(testWidget->item(r, c)->text(), QString::number(r * c + c)); + QSignalSpy spy(testWidget, &QTableWidget::cellChanged); QTableWidgetItem *item = testWidget->takeItem(row, column); QCOMPARE(!!item, expectItem); if (expectItem) { QCOMPARE(item->text(), QString::number(row * column + column)); delete item; + + QTRY_COMPARE(spy.count(), 1); + const QList arguments = spy.takeFirst(); + QCOMPARE(arguments.size(), 2); + QCOMPARE(arguments.at(0).toInt(), row); + QCOMPARE(arguments.at(1).toInt(), column); } QVERIFY(!testWidget->takeItem(row, column)); } From 0b4ab214db5f0368b33d4cfdfcaadf137070b7a8 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Thu, 18 Oct 2018 16:26:59 +0200 Subject: [PATCH 0087/1650] Fix a regression in qmacstyle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit square/flat button had an erroneous size adjustment, resulting in a wrong highlighted area. This button is anyway nothing like a real control on macOS - they don't have 'flat' button which highlights when pressed. Anyway, now our flat button looks more like AppKit's 'square' button when pressed. Task-number: QTBUG-69533 Change-Id: I9643c1d4a25329c3f3c2148cc1821922655d9a8b Reviewed-by: Tor Arne Vestbø --- src/plugins/styles/mac/qmacstyle_mac.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index 2a21673054..1aab0309c9 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -1468,8 +1468,8 @@ QRectF QMacStylePrivate::CocoaControl::adjustedControlFrame(const QRectF &rect) QRectF frameRect; const auto frameSize = defaultFrameSize(); if (type == QMacStylePrivate::Button_SquareButton) { - frameRect = rect.adjusted(3, 1, -3, -5) - .adjusted(focusRingWidth, focusRingWidth, -focusRingWidth, -focusRingWidth); + frameRect = rect.adjusted(3, 1, -3, -1) + .adjusted(focusRingWidth, focusRingWidth, -focusRingWidth, -focusRingWidth); } else if (type == QMacStylePrivate::Button_PushButton) { // Start from the style option's top-left corner. frameRect = QRectF(rect.topLeft(), From 3c4f94b7cb3f319f24fda6502e49bdd199c0f77d Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Fri, 12 Oct 2018 15:45:27 +0200 Subject: [PATCH 0088/1650] QMacStyle: fix group box for macOS Mojave MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change is based on a patch started by Gabriel. It works around the apparently noop (on macOS Mojave, light theme) -drawRect: call on NSBox, replacing it with -displayRectIgnoringOpacity:inContext:. Unfortunately, this turns out to be extremely slow with dark theme, so we have to resort to a custom version of NSBox/-drawRect: which calls its super's -drawRect: and look more or less correct. Task-number: QTBUG-69650 Change-Id: I5a614d7cd8002b378c6c3804663b6559e227f628 Reviewed-by: Richard Moe Gustavsen Reviewed-by: Morten Johan Sørvig --- src/plugins/styles/mac/qmacstyle_mac.mm | 69 +++++++++++++++++++--- src/plugins/styles/mac/qmacstyle_mac_p_p.h | 1 + 2 files changed, 63 insertions(+), 7 deletions(-) diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index 1aab0309c9..94d048ca7e 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -238,6 +238,33 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QVerticalSplitView); } @end +// See render code in drawPrimitive(PE_FrameTabWidget) +@interface QT_MANGLE_NAMESPACE(QDarkNSBox) : NSBox +@end + +QT_NAMESPACE_ALIAS_OBJC_CLASS(QDarkNSBox); + +@implementation QDarkNSBox +- (instancetype)init +{ + if ((self = [super init])) { + self.title = @""; + self.titlePosition = NSNoTitle; + self.boxType = NSBoxCustom; + self.cornerRadius = 3; + self.borderColor = [NSColor.controlColor colorWithAlphaComponent:0.1]; + self.fillColor = [NSColor.darkGrayColor colorWithAlphaComponent:0.2]; + } + + return self; +} + +- (void)drawRect:(NSRect)rect +{ + [super drawRect:rect]; +} +@end + QT_BEGIN_NAMESPACE // The following constants are used for adjusting the size @@ -1704,18 +1731,28 @@ NSView *QMacStylePrivate::cocoaControl(CocoaControl widget) const || widget.size == QStyleHelper::SizeDefault) return nil; + if (widget.type == Box) { + if (__builtin_available(macOS 10.14, *)) { + if (qt_mac_applicationIsInDarkMode()) { + // See render code in drawPrimitive(PE_FrameTabWidget) + widget.type = Box_Dark; + } + } + } + NSView *bv = cocoaControls.value(widget, nil); if (!bv) { switch (widget.type) { case Box: { - NSBox *bc = [[NSBox alloc] init]; - bc.title = @""; - bc.titlePosition = NSNoTitle; - bc.boxType = NSBoxPrimary; - bc.borderType = NSBezelBorder; - bv = bc; + NSBox *box = [[NSBox alloc] init]; + bv = box; + box.title = @""; + box.titlePosition = NSNoTitle; break; } + case Box_Dark: + bv = [[QDarkNSBox alloc] init]; + break; case Button_CheckBox: case Button_Disclosure: case Button_PushButton: @@ -2922,10 +2959,28 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai { const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::Box, QStyleHelper::SizeLarge); auto *box = static_cast(d->cocoaControl(cw)); + // FIXME Since macOS 10.14, simply calling drawRect: won't display anything anymore. + // The AppKit team is aware of this and has proposed a couple of solutions. + // The first solution was to call displayRectIgnoringOpacity:inContext: instead. + // However, it doesn't seem to work on 10.13. More importantly, dark mode on 10.14 + // is extremely slow. Light mode works fine. + // The second solution is to subclass NSBox and reimplement a trivial drawRect: which + // would only call super. This works without any issue on 10.13, but a double border + // shows on 10.14 in both light and dark modes. + // The code below picks what works on each version and mode. On 10.13 and earlier, we + // simply call drawRect: on a regular NSBox. On 10.14, we call displayRectIgnoringOpacity: + // inContext:, but only in light mode. In dark mode, we use a custom NSBox subclass, + // QDarkNSBox, of type NSBoxCustom. Its appearance is close enough to the real thing so + // we can use this for now. d->drawNSViewInRect(box, opt->rect, p, ^(CGContextRef ctx, const CGRect &rect) { CGContextTranslateCTM(ctx, 0, rect.origin.y + rect.size.height); CGContextScaleCTM(ctx, 1, -1); - [box drawRect:rect]; + if (QOperatingSystemVersion::current() < QOperatingSystemVersion::MacOSMojave + || [box isMemberOfClass:QDarkNSBox.class]) { + [box drawRect:rect]; + } else { + [box displayRectIgnoringOpacity:box.bounds inContext:NSGraphicsContext.currentContext]; + } }); break; } diff --git a/src/plugins/styles/mac/qmacstyle_mac_p_p.h b/src/plugins/styles/mac/qmacstyle_mac_p_p.h index 8c712e838a..dd99cf4bb5 100644 --- a/src/plugins/styles/mac/qmacstyle_mac_p_p.h +++ b/src/plugins/styles/mac/qmacstyle_mac_p_p.h @@ -187,6 +187,7 @@ public: enum CocoaControlType { NoControl, // For when there's no such a control in Cocoa Box, // QGroupBox + Box_Dark, // FIXME See render code in drawPrimitive(PE_FrameTabWidget) Button_CheckBox, Button_Disclosure, // Disclosure triangle, like in QTreeView Button_PopupButton, // Non-editable QComboBox From 2708c6c11d685ab25c12d558961d924c9a4533d2 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Mon, 1 Oct 2018 13:43:44 +0200 Subject: [PATCH 0089/1650] OpenSSL: force the "1.0.0" soname when loading OpenSSL 1.0 Some Linux distributions patch OpenSSL's soname, making builds on such distributions not deployable elsewhere. The problem is that the code loading OpenSSL symbols would attempt to use the soname of the build machine, and therefore not finding the OpenSSL libraries on the deploy system. The binary builds of Qt for Linux are affected by this problem, as they build under RHEL7.4 which changes to soname of OpenSSL to a non-standard string. This makes the binary builds not pick up OpenSSL 1.0 from the machine where the build gets installed on. Given that in the pre-1.1 versions only the 1.0 series is supported, bump the minimum requirement of Qt to that. The 1.0.x releases (up to 1.0.2, at the time of this writing) have kept binary compatibility, and advertise a soname of "1.0.0", which is used by most distributions. So, if loading of OpenSSL with the build-time soname fails, try to load them with the "1.0.0" hardcoded soname. [ChangeLog][QtNetwork][SSL] OpenSSL >= 1.0 is now required to build Qt with OpenSSL support. Task-number: QTBUG-68156 Change-Id: Ieff1561a3c1d278b511f09fef06580f034f188c6 Reviewed-by: Timur Pocheptsov --- config.tests/openssl/openssl.cpp | 4 ++-- src/network/doc/src/ssl.qdoc | 5 ++-- .../ssl/qsslsocket_openssl_symbols.cpp | 23 +++++++++++++++++++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/config.tests/openssl/openssl.cpp b/config.tests/openssl/openssl.cpp index d33b62389c..9188fb008f 100644 --- a/config.tests/openssl/openssl.cpp +++ b/config.tests/openssl/openssl.cpp @@ -39,8 +39,8 @@ #include -#if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER-0 < 0x0090700fL -# error "OpenSSL >= 0.9.7 is required" +#if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER-0 < 0x10000000L +# error "OpenSSL >= 1.0.0 is required" #endif #include diff --git a/src/network/doc/src/ssl.qdoc b/src/network/doc/src/ssl.qdoc index e4948c393c..58589f8479 100644 --- a/src/network/doc/src/ssl.qdoc +++ b/src/network/doc/src/ssl.qdoc @@ -36,9 +36,8 @@ the Secure Sockets Layer (SSL) protocol, using the \l{OpenSSL Toolkit} to perform encryption and protocol handling. - From Qt version 5.2 onwards, the officially supported version for OpenSSL - is 1.0.0 or later. Versions >= 0.9.7 and < 1.0.0 might work, but are not - guaranteed to work. + From Qt version 5.6 onwards, the officially supported version for OpenSSL + is 1.0.0 or later. \annotatedlist ssl diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index 466eba0bd0..59c93677dd 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -771,6 +771,17 @@ static QPair loadOpenSsl() // reason, we will search a few common paths (see findAllLibSsl() above) in hopes // we find one that works. // + // If that fails, for OpenSSL 1.0 we also try a fallback -- just look up + // libssl.so with a hardcoded soname. The reason is QTBUG-68156: the binary + // builds of Qt happen (at the time of this writing) on RHEL machines, + // which change SHLIB_VERSION_NUMBER to a non-portable string. When running + // those binaries on the target systems, this code won't pick up + // libssl.so.MODIFIED_SHLIB_VERSION_NUMBER because it doesn't exist there. + // Given that the only 1.0 supported release (at the time of this writing) + // is 1.0.2, with soname "1.0.0", give that a try too. Note that we mandate + // OpenSSL >= 1.0.0 with a configure-time check, and OpenSSL has kept binary + // compatibility between 1.0.0 and 1.0.2. + // // It is important, however, to try the canonical name and the unversioned name // without going through the loop. By not specifying a path, we let the system // dlopen(3) function determine it for us. This will include any DT_RUNPATH or @@ -791,6 +802,18 @@ static QPair loadOpenSsl() libssl->unload(); libcrypto->unload(); } + +#if !QT_CONFIG(opensslv11) + // first-and-half attempt: for OpenSSL 1.0 try to load an hardcoded soname. + libssl->setFileNameAndVersion(QLatin1String("ssl"), QLatin1String("1.0.0")); + libcrypto->setFileNameAndVersion(QLatin1String("crypto"), QLatin1String("1.0.0")); + if (libcrypto->load() && libssl->load()) { + return pair; + } else { + libssl->unload(); + libcrypto->unload(); + } +#endif #endif #ifndef Q_OS_DARWIN From 10b8ed816d0dff4321d5a8b0723a8090b2058678 Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Wed, 17 Oct 2018 15:06:47 +1000 Subject: [PATCH 0090/1650] wasm: fix wheel scroll logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-71180 Fixes: QTBUG-71180 Change-Id: If442da096b847fdf69f3b24615e99c2ca988fb79 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/wasm/qwasmeventtranslator.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp index cc48c15b64..23251fd610 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp @@ -50,7 +50,7 @@ using namespace emscripten; // the existing switching code in QtGui, but for now do it here. static bool g_usePlatformMacCtrlMetaSwitching = false; -bool g_useNaturalScrolling = false; +bool g_useNaturalScrolling = true; // natural scrolling is default on linux/windows void setNaturalScrolling(bool use) { g_useNaturalScrolling = use; @@ -98,7 +98,7 @@ QWasmEventTranslator::QWasmEventTranslator(QObject *parent) g_usePlatformMacCtrlMetaSwitching = (platform == MacOSPlatform); if (platform == MacOSPlatform) { - g_useNaturalScrolling = true; //make this default on macOS + g_useNaturalScrolling = false; // make this !default on macOS EM_ASM( if (window.safari !== undefined) {//this only works on safari Module["canvas"].addEventListener('wheel', mouseWheelEvent); @@ -492,6 +492,9 @@ int QWasmEventTranslator::wheel_cb(int eventType, const EmscriptenWheelEvent *wh if (wheelEvent->deltaX != 0) pixelDelta.setX(wheelEvent->deltaX * scrollFactor); QWindowSystemInterface::handleWheelEvent(window2, timestamp, localPoint, globalPoint, QPoint(), pixelDelta, modifiers); + + QWasmEventDispatcher::maintainTimers(); + return 1; } From cea2b5510c28d1057018007d65589fecee62b0d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCri=20Valdmann?= Date: Fri, 19 Oct 2018 12:39:12 +0200 Subject: [PATCH 0091/1650] Fix building tests with -no-gui Change-Id: I37307080e5adc334fcfcdd2fee650d675228a746 Reviewed-by: Oswald Buddenhagen --- mkspecs/features/ctest_testcase_common.prf | 4 ++-- tests/auto/corelib/itemmodels/itemmodels.pro | 4 ++-- tests/auto/other/other.pro | 4 ++-- tests/auto/testlib/selftests/selftests.pri | 6 ++++-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/mkspecs/features/ctest_testcase_common.prf b/mkspecs/features/ctest_testcase_common.prf index 0d5ff5f89c..63e31f5415 100644 --- a/mkspecs/features/ctest_testcase_common.prf +++ b/mkspecs/features/ctest_testcase_common.prf @@ -48,8 +48,8 @@ for (dep, dependentmodules): \ dependentmodules = $$join(mod_deps, ";") QT_FOR_CONFIG += gui-private -qtConfig(angle): CMAKE_GL_DEFINES = -DQT_WITH_ANGLE=True -!qtConfig(egl): CMAKE_GL_DEFINES += -DNO_EGL=True +qtHaveModule(gui):qtConfig(angle): CMAKE_GL_DEFINES = -DQT_WITH_ANGLE=True +qtHaveModule(gui):!qtConfig(egl): CMAKE_GL_DEFINES += -DNO_EGL=True CMAKE_MODULE_VERSIONS = CMAKE_MODULES_UNDER_TEST = diff --git a/tests/auto/corelib/itemmodels/itemmodels.pro b/tests/auto/corelib/itemmodels/itemmodels.pro index bcb6e604f8..cca350ad43 100644 --- a/tests/auto/corelib/itemmodels/itemmodels.pro +++ b/tests/auto/corelib/itemmodels/itemmodels.pro @@ -1,9 +1,9 @@ TEMPLATE=subdirs -SUBDIRS = qabstractitemmodel \ - qstringlistmodel \ +SUBDIRS = qstringlistmodel qtHaveModule(gui): SUBDIRS += \ + qabstractitemmodel \ qabstractproxymodel \ qidentityproxymodel \ qitemselectionmodel \ diff --git a/tests/auto/other/other.pro b/tests/auto/other/other.pro index 61a464356c..d70c895dec 100644 --- a/tests/auto/other/other.pro +++ b/tests/auto/other/other.pro @@ -48,9 +48,9 @@ cross_compile: SUBDIRS -= \ atwrapper \ compiler -winrt|!qtConfig(accessibility): SUBDIRS -= qaccessibility +winrt|!qtHaveModule(gui)|!qtConfig(accessibility): SUBDIRS -= qaccessibility -!qtConfig(accessibility-atspi-bridge): SUBDIRS -= qaccessibilitylinux +!qtHaveModule(gui)|!qtConfig(accessibility-atspi-bridge): SUBDIRS -= qaccessibilitylinux !qtConfig(process): SUBDIRS -= qprocess_and_guieventloop diff --git a/tests/auto/testlib/selftests/selftests.pri b/tests/auto/testlib/selftests/selftests.pri index 498d1653c0..05ed6d9905 100644 --- a/tests/auto/testlib/selftests/selftests.pri +++ b/tests/auto/testlib/selftests/selftests.pri @@ -27,10 +27,8 @@ SUBPROGRAMS = \ findtestdata \ float \ globaldata \ - keyboard \ longstring \ maxwarnings \ - mouse \ multiexec \ pairdiagnostics \ printdatatags \ @@ -52,5 +50,9 @@ SUBPROGRAMS = \ warnings \ xunit +qtHaveModule(gui): SUBPROGRAMS += \ + keyboard \ + mouse + INCLUDEPATH += ../../../../shared/ HEADERS += ../../../../shared/emulationdetector.h From 5d61fd8c22b569b3127491e8e42bd9e646e3144a Mon Sep 17 00:00:00 2001 From: Ivan Komissarov Date: Sat, 20 Oct 2018 17:34:54 +0200 Subject: [PATCH 0092/1650] qfilesystemengine: add missed Q_CHECK_PTR There might be dereferencing of a potential null pointer Task-number: QTBUG-71156 Change-Id: I202d314d001917a2de0500caf762d2b54ff517cb Reviewed-by: Thiago Macieira Reviewed-by: Mikhail Svetkin --- src/corelib/io/qfilesystemengine_win.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 74081b4ffa..a796fd005a 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -204,10 +204,12 @@ GlobalSid::GlobalSid() ::GetTokenInformation(token, TokenUser, 0, 0, &retsize); if (retsize) { void *tokenBuffer = malloc(retsize); + Q_CHECK_PTR(tokenBuffer); if (::GetTokenInformation(token, TokenUser, tokenBuffer, retsize, &retsize)) { PSID tokenSid = reinterpret_cast(tokenBuffer)->User.Sid; DWORD sidLen = ::GetLengthSid(tokenSid); currentUserSID = reinterpret_cast(malloc(sidLen)); + Q_CHECK_PTR(currentUserSID); if (::CopySid(sidLen, currentUserSID, tokenSid)) BuildTrusteeWithSid(¤tUserTrusteeW, currentUserSID); } @@ -294,6 +296,7 @@ static QString readSymLink(const QFileSystemEntry &link) if (handle != INVALID_HANDLE_VALUE) { DWORD bufsize = MAXIMUM_REPARSE_DATA_BUFFER_SIZE; REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER*)malloc(bufsize); + Q_CHECK_PTR(rdb); DWORD retsize = 0; if (::DeviceIoControl(handle, FSCTL_GET_REPARSE_POINT, 0, 0, rdb, bufsize, &retsize, 0)) { if (rdb->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) { From e631e900fd0cd7467b1dccb5fa401afdcd1e41a8 Mon Sep 17 00:00:00 2001 From: Ivan Komissarov Date: Sat, 20 Oct 2018 17:12:22 +0200 Subject: [PATCH 0093/1650] itemviews: Fix a condition typo 'QAbstractItemView::NoSelection' named constant with the value of 0 was used in the bitwise operation Task-number: QTBUG-71156 Change-Id: I2d5099f9ed03cc42061508cc78282412a09825cb Reviewed-by: Mikhail Svetkin Reviewed-by: Christian Ehrlicher Reviewed-by: Samuel Gaist --- src/widgets/accessible/itemviews.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/accessible/itemviews.cpp b/src/widgets/accessible/itemviews.cpp index 159d61d683..51cfaa7f5e 100644 --- a/src/widgets/accessible/itemviews.cpp +++ b/src/widgets/accessible/itemviews.cpp @@ -973,7 +973,7 @@ void QAccessibleTableCell::unselectCell() { QAbstractItemView::SelectionMode selectionMode = view->selectionMode(); - if (!m_index.isValid() || (selectionMode & QAbstractItemView::NoSelection)) + if (!m_index.isValid() || (selectionMode == QAbstractItemView::NoSelection)) return; QAccessibleTableInterface *cellTable = table()->tableInterface(); From c6c31b14a73674459eb5e762bb7487900b8c4b36 Mon Sep 17 00:00:00 2001 From: Ivan Komissarov Date: Sat, 20 Oct 2018 17:28:18 +0200 Subject: [PATCH 0094/1650] qjson: add missed Q_CHECK_PTR There might be dereferencing of a potential null pointer 'h' Task-number: QTBUG-71156 Change-Id: I63c34f8cba3e358f109d70ff9b34199c31895202 Reviewed-by: Thiago Macieira Reviewed-by: Mikhail Svetkin --- src/corelib/serialization/qjson.cpp | 1 + src/corelib/serialization/qjsonparser.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/corelib/serialization/qjson.cpp b/src/corelib/serialization/qjson.cpp index b82923fe0c..d74ffb2a20 100644 --- a/src/corelib/serialization/qjson.cpp +++ b/src/corelib/serialization/qjson.cpp @@ -70,6 +70,7 @@ void Data::compact() int size = sizeof(Base) + reserve + base->length*sizeof(offset); int alloc = sizeof(Header) + size; Header *h = (Header *) malloc(alloc); + Q_CHECK_PTR(h); h->tag = QJsonDocument::BinaryFormatTag; h->version = 1; Base *b = h->root(); diff --git a/src/corelib/serialization/qjsonparser.cpp b/src/corelib/serialization/qjsonparser.cpp index 39738b90a8..bfba95520e 100644 --- a/src/corelib/serialization/qjsonparser.cpp +++ b/src/corelib/serialization/qjsonparser.cpp @@ -304,6 +304,7 @@ QJsonDocument Parser::parse(QJsonParseError *error) // allocate some space dataLength = qMax(end - json, (ptrdiff_t) 256); data = (char *)malloc(dataLength); + Q_CHECK_PTR(data); // fill in Header data QJsonPrivate::Header *h = (QJsonPrivate::Header *)data; From ef02dd14cddf42ff8bfcf70d38098defe47fa739 Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Tue, 16 Oct 2018 12:39:19 +0300 Subject: [PATCH 0095/1650] QMovie: use rvalue more Change-Id: Idf052436190bf225662ff6c1d4b7b8e3c0c84685 Reviewed-by: Friedemann Kleint Reviewed-by: Edward Welbourne --- src/gui/image/qmovie.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/image/qmovie.cpp b/src/gui/image/qmovie.cpp index 010760de4c..7d17b7d5ef 100644 --- a/src/gui/image/qmovie.cpp +++ b/src/gui/image/qmovie.cpp @@ -379,7 +379,7 @@ QFrameInfo QMoviePrivate::infoForFrame(int frameNumber) } if (frameNumber > greatestFrameNumber) greatestFrameNumber = frameNumber; - QPixmap aPixmap = QPixmap::fromImage(anImage); + QPixmap aPixmap = QPixmap::fromImage(std::move(anImage)); int aDelay = reader->nextImageDelay(); return QFrameInfo(aPixmap, aDelay); } else if (frameNumber != 0) { @@ -405,7 +405,7 @@ QFrameInfo QMoviePrivate::infoForFrame(int frameNumber) return QFrameInfo(); // Invalid } greatestFrameNumber = i; - QPixmap aPixmap = QPixmap::fromImage(anImage); + QPixmap aPixmap = QPixmap::fromImage(std::move(anImage)); int aDelay = reader->nextImageDelay(); QFrameInfo info(aPixmap, aDelay); // Cache it! From 1a6a78171adaaf2f4bb7f4668533ccc2c06f6db4 Mon Sep 17 00:00:00 2001 From: Ivan Komissarov Date: Sat, 20 Oct 2018 17:06:14 +0200 Subject: [PATCH 0096/1650] qdir: Fix a condition typo A part of conditional expression is always false: if "c > 'z'" Task-number: QTBUG-71156 Change-Id: I6ee20c45d80e476d97e59167c481b157e4a233d0 Reviewed-by: Mikhail Svetkin Reviewed-by: Thiago Macieira --- src/corelib/io/qdir.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 39422c3401..75fd0f8e0a 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -74,7 +74,7 @@ static QString driveSpec(const QString &path) if (path.size() < 2) return QString(); char c = path.at(0).toLatin1(); - if (c < 'a' && c > 'z' && c < 'A' && c > 'Z') + if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z')) return QString(); if (path.at(1).toLatin1() != ':') return QString(); From 07f79a8029674f47b92a04646df6dfa9cedf894f Mon Sep 17 00:00:00 2001 From: Ivan Komissarov Date: Sun, 21 Oct 2018 12:10:53 +0200 Subject: [PATCH 0097/1650] qimagescale: Get rid of the memset call There is no need to call a memset as long as class is initialized with new and default-constructor will initialize values. Change-Id: I02f9ec524e32cb72713f6b5e37b60f3dec72fb28 Reviewed-by: Giuseppe D'Angelo Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qimagescale.cpp | 1 - src/gui/painting/qimagescale_p.h | 9 +++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/gui/painting/qimagescale.cpp b/src/gui/painting/qimagescale.cpp index 96da5e029c..8a5274bd37 100644 --- a/src/gui/painting/qimagescale.cpp +++ b/src/gui/painting/qimagescale.cpp @@ -239,7 +239,6 @@ static QImageScaleInfo* QImageScale::qimageCalcScaleInfo(const QImage &img, isi = new QImageScaleInfo; if (!isi) return 0; - memset(isi, 0, sizeof(QImageScaleInfo)); isi->xup_yup = (qAbs(dw) >= sw) + ((qAbs(dh) >= sh) << 1); diff --git a/src/gui/painting/qimagescale_p.h b/src/gui/painting/qimagescale_p.h index 415623a575..244d681718 100644 --- a/src/gui/painting/qimagescale_p.h +++ b/src/gui/painting/qimagescale_p.h @@ -61,10 +61,11 @@ QImage qSmoothScaleImage(const QImage &img, int w, int h); namespace QImageScale { struct QImageScaleInfo { - int *xpoints; - const unsigned int **ypoints; - int *xapoints, *yapoints; - int xup_yup; + int *xpoints{nullptr}; + const unsigned int **ypoints{nullptr}; + int *xapoints{nullptr}; + int *yapoints{nullptr}; + int xup_yup{0}; }; } From 1c614d07fbb3ec190b7ed3fc5eb24a200f282c0f Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Thu, 18 Oct 2018 15:58:24 +0200 Subject: [PATCH 0098/1650] tst_QAccessibilityLinux make state checking more convenient MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I96274ab0a0f5d942746de0166df47936e2390c65 Reviewed-by: Jan Arve Sæther --- .../tst_qaccessibilitylinux.cpp | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp b/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp index 2575f22309..0472a78729 100644 --- a/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp +++ b/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp @@ -211,6 +211,27 @@ void tst_QAccessibilityLinux::registerDbus() mainWindow = getInterface(window, "org.a11y.atspi.Accessible"); } +quint64 getAtspiState(QDBusInterface *interface) +{ + QDBusMessage msg = interface->call(QDBus::Block, "GetState"); + const QDBusArgument arg = msg.arguments().at(0).value(); + quint32 state1 = 0; + quint64 state2 = 0; + arg.beginArray(); + arg >> state1; + arg >> state2; + arg.endArray(); + + state2 = state2 << 32; + return state2 | state1; +} + +bool hasState(QDBusInterface *interface, AtspiStateType state) +{ + quint64 intState = quint64(1) << state; + return getAtspiState(interface) & intState; +} + #define ROOTPATH "/org/a11y/atspi/accessible" void tst_QAccessibilityLinux::testLabel() @@ -471,21 +492,6 @@ void tst_QAccessibilityLinux::testSlider() m_window->clearChildren(); } -quint64 getAtspiState(QDBusInterface *interface) -{ - QDBusMessage msg = interface->call(QDBus::Block, "GetState"); - const QDBusArgument arg = msg.arguments().at(0).value(); - quint32 state1 = 0; - quint64 state2 = 0; - arg.beginArray(); - arg >> state1; - arg >> state2; - arg.endArray(); - - state2 = state2 << 32; - return state2 | state1; -} - void tst_QAccessibilityLinux::testFocus() { QLineEdit *lineEdit1 = new QLineEdit(m_window); @@ -508,15 +514,14 @@ void tst_QAccessibilityLinux::testFocus() QDBusInterface *componentInterfaceLineEdit2 = getInterface(children.at(1), "org.a11y.atspi.Component"); QVERIFY(componentInterfaceLineEdit2->isValid()); - quint64 focusedState = quint64(1) << ATSPI_STATE_FOCUSED; - QVERIFY(getAtspiState(accessibleInterfaceLineEdit1) & focusedState); - QVERIFY(!(getAtspiState(accessibleInterfaceLineEdit2) & focusedState)); + QVERIFY(hasState(accessibleInterfaceLineEdit1, ATSPI_STATE_FOCUSED)); + QVERIFY(!hasState(accessibleInterfaceLineEdit2, ATSPI_STATE_FOCUSED)); QDBusMessage focusReply = componentInterfaceLineEdit2->call(QDBus::Block, "GrabFocus"); QVERIFY(focusReply.arguments().at(0).toBool()); QVERIFY(lineEdit2->hasFocus()); - QVERIFY(!(getAtspiState(accessibleInterfaceLineEdit1) & focusedState)); - QVERIFY(getAtspiState(accessibleInterfaceLineEdit2) & focusedState); + QVERIFY(!hasState(accessibleInterfaceLineEdit1, ATSPI_STATE_FOCUSED)); + QVERIFY(hasState(accessibleInterfaceLineEdit2, ATSPI_STATE_FOCUSED)); m_window->clearChildren(); delete accessibleInterfaceLineEdit1; delete accessibleInterfaceLineEdit2; From a87f85dbf9bd1ea90936bd9a4609229edb15c264 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Thu, 18 Oct 2018 16:02:19 +0200 Subject: [PATCH 0099/1650] Linux Accessibility: Fix expandable state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The state was forgotten from the translation layer, this is important for tree views. Fixes: QTBUG-71223 Change-Id: Ief4004fe455889f9d5a7eb018bf34d37c36a6bd9 Reviewed-by: Jan Arve Sæther --- .../linuxaccessibility/constant_mappings.cpp | 2 ++ .../other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/src/platformsupport/linuxaccessibility/constant_mappings.cpp b/src/platformsupport/linuxaccessibility/constant_mappings.cpp index de4a68dc5b..ef2b3429d2 100644 --- a/src/platformsupport/linuxaccessibility/constant_mappings.cpp +++ b/src/platformsupport/linuxaccessibility/constant_mappings.cpp @@ -83,6 +83,8 @@ quint64 spiStatesFromQState(QAccessible::State state) // if (state.HotTracked) if (state.defaultButton) setSpiStateBit(&spiState, ATSPI_STATE_IS_DEFAULT); + if (state.expandable) + setSpiStateBit(&spiState, ATSPI_STATE_EXPANDABLE); if (state.expanded) setSpiStateBit(&spiState, ATSPI_STATE_EXPANDED); if (state.collapsed) diff --git a/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp b/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp index 0472a78729..47d24ce171 100644 --- a/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp +++ b/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp @@ -374,13 +374,21 @@ void tst_QAccessibilityLinux::testTreeWidget() QDBusInterface *cell3 = getInterface(tableChildren.at(2), "org.a11y.atspi.Accessible"); QCOMPARE(cell3->property("Name").toString(), QLatin1String("0.0")); + QVERIFY(!hasState(cell3, ATSPI_STATE_EXPANDABLE)); + QVERIFY(!hasState(cell3, ATSPI_STATE_EXPANDED)); QDBusInterface *cell4 = getInterface(tableChildren.at(3), "org.a11y.atspi.Accessible"); QCOMPARE(cell4->property("Name").toString(), QLatin1String("0.1")); + QDBusInterface *dbus_top2 = getInterface(tableChildren.at(4), "org.a11y.atspi.Accessible"); + QCOMPARE(dbus_top2->property("Name").toString(), QLatin1String("1.0")); + QVERIFY(hasState(dbus_top2, ATSPI_STATE_EXPANDABLE)); + QVERIFY(!hasState(dbus_top2, ATSPI_STATE_EXPANDED)); + tree->expandItem(top2); tableChildren = getChildren(treeIface); QCOMPARE(tableChildren.size(), 8); + QVERIFY(hasState(dbus_top2, ATSPI_STATE_EXPANDED)); QDBusInterface *cell5 = getInterface(tableChildren.at(6), "org.a11y.atspi.Accessible"); QCOMPARE(cell5->property("Name").toString(), QLatin1String("1.0 0.0")); From 0cb44e2cfb11033cdb7e3b73a25f1ec394b08d6e Mon Sep 17 00:00:00 2001 From: Arnaud Bienner Date: Fri, 19 Oct 2018 14:50:59 +0200 Subject: [PATCH 0100/1650] Fix stylesheet example for QLineEdit:read-only code example Change-Id: I987a4129968e9af74e21a2d855c4576a9caada73 Reviewed-by: Friedemann Kleint --- src/widgets/doc/snippets/code/doc_src_stylesheet.qdoc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/widgets/doc/snippets/code/doc_src_stylesheet.qdoc b/src/widgets/doc/snippets/code/doc_src_stylesheet.qdoc index bf727dd380..9af04f6b4c 100644 --- a/src/widgets/doc/snippets/code/doc_src_stylesheet.qdoc +++ b/src/widgets/doc/snippets/code/doc_src_stylesheet.qdoc @@ -954,6 +954,7 @@ QLineEdit[echoMode="2"] { //! [119] QLineEdit:read-only { background: lightblue; +} //! [119] From 1bb8627f8f1dea546f766a37888fe331381fa333 Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Thu, 6 Sep 2018 17:16:44 +0200 Subject: [PATCH 0101/1650] Extend PDF engine to allow the generation of PDFs with huge pages Qt's PDF engine previously supported only the PDF v1.4 standard, which only allows pages of up to 200x200in (about 5x5m). This patch optionally enables the generation of PDF v1.6-compliant files that allow the redefinition of user space units, so that pages of up to 381x381km are now possible. By default, generated files are compliant to v1.4 spec. v1.6 compliance must be enabled by, e.g., calling QPrinter::setPdfVersion() with QPrinter::PdfVersion_1_6. PDF v1.6-compliant files require Adobe Reader 7.0 or newer (also worked with the built-in viewers in current versions of Chrome, Firefox and Edge). Task-number: QTBUG-69386 Change-Id: I21708e0d465d5d7d9e46ff06dd04acfe1dfb0858 Reviewed-by: Friedemann Kleint Reviewed-by: Andy Shaw Reviewed-by: Oliver Wolff --- src/gui/painting/qpagedpaintdevice.cpp | 3 +- src/gui/painting/qpagedpaintdevice.h | 2 +- src/gui/painting/qpdf.cpp | 41 +++++++++++++++++++++----- src/gui/painting/qpdf_p.h | 4 ++- src/gui/painting/qpdfwriter.cpp | 8 ++++- src/printsupport/kernel/qprinter.cpp | 7 ++++- 6 files changed, 53 insertions(+), 12 deletions(-) diff --git a/src/gui/painting/qpagedpaintdevice.cpp b/src/gui/painting/qpagedpaintdevice.cpp index 613a686848..72b2834470 100644 --- a/src/gui/painting/qpagedpaintdevice.cpp +++ b/src/gui/painting/qpagedpaintdevice.cpp @@ -290,7 +290,8 @@ QPagedPaintDevicePrivate *QPagedPaintDevice::dd() \value PdfVersion_A1b A PDF/A-1b compatible document is produced. - \since 5.10 + \value PdfVersion_1_6 A PDF 1.6 compatible document is produced. + This value was added in Qt 5.12. */ /*! diff --git a/src/gui/painting/qpagedpaintdevice.h b/src/gui/painting/qpagedpaintdevice.h index c8957edab8..1c37c17fa3 100644 --- a/src/gui/painting/qpagedpaintdevice.h +++ b/src/gui/painting/qpagedpaintdevice.h @@ -213,7 +213,7 @@ public: Envelope10 = Comm10E }; - enum PdfVersion { PdfVersion_1_4, PdfVersion_A1b }; + enum PdfVersion { PdfVersion_1_4, PdfVersion_A1b, PdfVersion_1_6 }; // ### Qt6 Make these virtual bool setPageLayout(const QPageLayout &pageLayout); diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index 5220c24020..b410e9b900 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -1547,7 +1547,14 @@ void QPdfEnginePrivate::writeHeader() { addXrefEntry(0,false); - xprintf("%%PDF-1.4\n"); + static const QHash mapping { + {QPdfEngine::Version_1_4, "1.4"}, + {QPdfEngine::Version_A1b, "1.4"}, + {QPdfEngine::Version_1_6, "1.6"} + }; + const char *verStr = mapping.value(pdfVersion, "1.4"); + + xprintf("%%PDF-%s\n", verStr); xprintf("%%\303\242\303\243\n"); writeInfo(); @@ -1880,6 +1887,19 @@ void QPdfEnginePrivate::embedFont(QFontSubset *font) } } +qreal QPdfEnginePrivate::calcUserUnit() const +{ + // PDF standards < 1.6 support max 200x200in pages (no UserUnit) + if (pdfVersion < QPdfEngine::Version_1_6) + return 1.0; + + const int maxLen = qMax(currentPage->pageSize.width(), currentPage->pageSize.height()); + if (maxLen <= 14400) + return 1.0; // for pages up to 200x200in (14400x14400 units) use default scaling + + // for larger pages, rescale units so we can have up to 381x381km + return qMin(maxLen / 14400.0, 75000.0); +} void QPdfEnginePrivate::writeFonts() { @@ -1902,6 +1922,8 @@ void QPdfEnginePrivate::writePage() uint resources = requestObject(); uint annots = requestObject(); + qreal userUnit = calcUserUnit(); + addXrefEntry(pages.constLast()); xprintf("<<\n" "/Type /Page\n" @@ -1909,12 +1931,16 @@ void QPdfEnginePrivate::writePage() "/Contents %d 0 R\n" "/Resources %d 0 R\n" "/Annots %d 0 R\n" - "/MediaBox [0 0 %d %d]\n" - ">>\n" - "endobj\n", + "/MediaBox [0 0 %f %f]\n", pageRoot, pageStream, resources, annots, // make sure we use the pagesize from when we started the page, since the user may have changed it - currentPage->pageSize.width(), currentPage->pageSize.height()); + currentPage->pageSize.width() / userUnit, currentPage->pageSize.height() / userUnit); + + if (pdfVersion >= QPdfEngine::Version_1_6) + xprintf("/UserUnit %f\n", userUnit); + + xprintf(">>\n" + "endobj\n"); addXrefEntry(resources); xprintf("<<\n" @@ -2983,8 +3009,9 @@ void QPdfEnginePrivate::drawTextItem(const QPointF &p, const QTextItemInt &ti) QTransform QPdfEnginePrivate::pageMatrix() const { - qreal scale = 72./resolution; - QTransform tmp(scale, 0.0, 0.0, -scale, 0.0, m_pageLayout.fullRectPoints().height()); + qreal userUnit = calcUserUnit(); + qreal scale = 72. / userUnit / resolution; + QTransform tmp(scale, 0.0, 0.0, -scale, 0.0, m_pageLayout.fullRectPoints().height() / userUnit); if (m_pageLayout.mode() != QPageLayout::FullPageMode) { QRect r = m_pageLayout.paintRectPixels(resolution); tmp.translate(r.left(), r.top()); diff --git a/src/gui/painting/qpdf_p.h b/src/gui/painting/qpdf_p.h index 5a909f2ede..e2526de67d 100644 --- a/src/gui/painting/qpdf_p.h +++ b/src/gui/painting/qpdf_p.h @@ -171,7 +171,8 @@ public: enum PdfVersion { Version_1_4, - Version_A1b + Version_A1b, + Version_1_6 }; QPdfEngine(); @@ -300,6 +301,7 @@ private: void writePageRoot(); void writeFonts(); void embedFont(QFontSubset *font); + qreal calcUserUnit() const; QVector xrefPositions; QDataStream* stream; diff --git a/src/gui/painting/qpdfwriter.cpp b/src/gui/painting/qpdfwriter.cpp index e6c5cabd7f..6c85d65538 100644 --- a/src/gui/painting/qpdfwriter.cpp +++ b/src/gui/painting/qpdfwriter.cpp @@ -170,11 +170,17 @@ void QPdfWriter::setPdfVersion(PdfVersion version) { Q_D(QPdfWriter); + static const QHash engineMapping { + {QPdfWriter::PdfVersion_1_4, QPdfEngine::Version_1_4}, + {QPdfWriter::PdfVersion_A1b, QPdfEngine::Version_A1b}, + {QPdfWriter::PdfVersion_1_6, QPdfEngine::Version_1_6} + }; + if (d->pdfVersion == version) return; d->pdfVersion = version; - d->engine->setPdfVersion(d->pdfVersion == QPdfWriter::PdfVersion_1_4 ? QPdfEngine::Version_1_4 : QPdfEngine::Version_A1b); + d->engine->setPdfVersion(engineMapping.value(version, QPdfEngine::Version_1_4)); } /*! diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp index ed4292ff3d..829a13863b 100644 --- a/src/printsupport/kernel/qprinter.cpp +++ b/src/printsupport/kernel/qprinter.cpp @@ -149,7 +149,12 @@ void QPrinterPrivate::initEngines(QPrinter::OutputFormat format, const QPrinterI printEngine = ps->createNativePrintEngine(printerMode, printerName); paintEngine = ps->createPaintEngine(printEngine, printerMode); } else { - const auto pdfEngineVersion = (pdfVersion == QPrinter::PdfVersion_1_4 ? QPdfEngine::Version_1_4 : QPdfEngine::Version_A1b); + static const QHash engineMapping { + {QPrinter::PdfVersion_1_4, QPdfEngine::Version_1_4}, + {QPrinter::PdfVersion_A1b, QPdfEngine::Version_A1b}, + {QPrinter::PdfVersion_1_6, QPdfEngine::Version_1_6} + }; + const auto pdfEngineVersion = engineMapping.value(pdfVersion, QPdfEngine::Version_1_4); QPdfPrintEngine *pdfEngine = new QPdfPrintEngine(printerMode, pdfEngineVersion); paintEngine = pdfEngine; printEngine = pdfEngine; From 903666a6027cec25010a99c05824df14ce26e7bf Mon Sep 17 00:00:00 2001 From: Ivan Komissarov Date: Sun, 21 Oct 2018 12:18:25 +0200 Subject: [PATCH 0102/1650] qtriangulator: Remove a bunch of dead code There is no sense in testing the 'm_array' pointer against null, as the memory was allocated using the 'new' operator. The exception will be generated in the case of memory allocation error. Task-number: QTBUG-71156 Change-Id: Ib76d16d38d2b0b0c4c9fae3d8d5bdd86af0d08ff Reviewed-by: Thiago Macieira --- src/gui/painting/qtriangulator.cpp | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/src/gui/painting/qtriangulator.cpp b/src/gui/painting/qtriangulator.cpp index 6d57eba123..9be3eeaffd 100644 --- a/src/gui/painting/qtriangulator.cpp +++ b/src/gui/painting/qtriangulator.cpp @@ -472,7 +472,7 @@ class QInt64Set { public: inline QInt64Set(int capacity = 64); - inline ~QInt64Set() {if (m_array) delete[] m_array;} + inline ~QInt64Set() {delete[] m_array;} inline bool isValid() const {return m_array;} void insert(quint64 key); bool contains(quint64 key) const; @@ -493,10 +493,7 @@ inline QInt64Set::QInt64Set(int capacity) { m_capacity = primeForCount(capacity); m_array = new quint64[m_capacity]; - if (m_array) - clear(); - else - m_capacity = 0; + clear(); } bool QInt64Set::rehash(int capacity) @@ -506,28 +503,19 @@ bool QInt64Set::rehash(int capacity) m_capacity = capacity; m_array = new quint64[m_capacity]; - if (m_array) { - clear(); - if (oldArray) { - for (int i = 0; i < oldCapacity; ++i) { - if (oldArray[i] != UNUSED) - insert(oldArray[i]); - } - delete[] oldArray; - } - return true; - } else { - m_capacity = oldCapacity; - m_array = oldArray; - return false; + clear(); + for (int i = 0; i < oldCapacity; ++i) { + if (oldArray[i] != UNUSED) + insert(oldArray[i]); } + delete[] oldArray; + return true; } void QInt64Set::insert(quint64 key) { if (m_count > 3 * m_capacity / 4) rehash(primeForCount(2 * m_capacity)); - Q_ASSERT_X(m_array, "QInt64Hash::insert", "Hash set not allocated."); int index = int(key % m_capacity); for (int i = 0; i < m_capacity; ++i) { index += i; @@ -546,7 +534,6 @@ void QInt64Set::insert(quint64 key) bool QInt64Set::contains(quint64 key) const { - Q_ASSERT_X(m_array, "QInt64Hash::contains", "Hash set not allocated."); int index = int(key % m_capacity); for (int i = 0; i < m_capacity; ++i) { index += i; @@ -562,7 +549,6 @@ bool QInt64Set::contains(quint64 key) const inline void QInt64Set::clear() { - Q_ASSERT_X(m_array, "QInt64Hash::clear", "Hash set not allocated."); for (int i = 0; i < m_capacity; ++i) m_array[i] = UNUSED; m_count = 0; From c0538857358e57c1551f7d10c07a9bb80d848cd7 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 19 Oct 2018 08:19:04 +0200 Subject: [PATCH 0103/1650] Windows/QPA: Fix receiving mouse clicks after double clicks in QQuickWidget The Qt QPA does not handle native double clicks as such; change the plugin not to send them. For Ink, remove the doubleclick detection. For the old code path, map them to Press. Fixes: QTBUG-70999 Change-Id: I54b858f9e146bf325a861554d5ef74143db7d2b7 Reviewed-by: Oliver Wolff --- .../windows/qwindowsmousehandler.cpp | 16 ++++++------ .../windows/qwindowspointerhandler.cpp | 26 ++----------------- 2 files changed, 10 insertions(+), 32 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp index c1c275144f..fcdd179a31 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp +++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp @@ -207,26 +207,26 @@ static inline MouseEvent eventFromMsg(const MSG &msg) return {QEvent::MouseButtonPress, Qt::LeftButton}; case WM_LBUTTONUP: return {QEvent::MouseButtonRelease, Qt::LeftButton}; - case WM_LBUTTONDBLCLK: - return {QEvent::MouseButtonDblClick, Qt::LeftButton}; + case WM_LBUTTONDBLCLK: // Qt QPA does not handle double clicks, send as press + return {QEvent::MouseButtonPress, Qt::LeftButton}; case WM_MBUTTONDOWN: return {QEvent::MouseButtonPress, Qt::MidButton}; case WM_MBUTTONUP: return {QEvent::MouseButtonRelease, Qt::MidButton}; case WM_MBUTTONDBLCLK: - return {QEvent::MouseButtonDblClick, Qt::MidButton}; + return {QEvent::MouseButtonPress, Qt::MidButton}; case WM_RBUTTONDOWN: return {QEvent::MouseButtonPress, Qt::RightButton}; case WM_RBUTTONUP: return {QEvent::MouseButtonRelease, Qt::RightButton}; case WM_RBUTTONDBLCLK: - return {QEvent::MouseButtonDblClick, Qt::RightButton}; + return {QEvent::MouseButtonPress, Qt::RightButton}; case WM_XBUTTONDOWN: return {QEvent::MouseButtonPress, extraButton(msg.wParam)}; case WM_XBUTTONUP: return {QEvent::MouseButtonRelease, extraButton(msg.wParam)}; case WM_XBUTTONDBLCLK: - return {QEvent::MouseButtonDblClick, extraButton(msg.wParam)}; + return {QEvent::MouseButtonPress, extraButton(msg.wParam)}; case WM_NCMOUSEMOVE: return {QEvent::NonClientAreaMouseMove, Qt::NoButton}; case WM_NCLBUTTONDOWN: @@ -234,19 +234,19 @@ static inline MouseEvent eventFromMsg(const MSG &msg) case WM_NCLBUTTONUP: return {QEvent::NonClientAreaMouseButtonRelease, Qt::LeftButton}; case WM_NCLBUTTONDBLCLK: - return {QEvent::NonClientAreaMouseButtonDblClick, Qt::LeftButton}; + return {QEvent::NonClientAreaMouseButtonPress, Qt::LeftButton}; case WM_NCMBUTTONDOWN: return {QEvent::NonClientAreaMouseButtonPress, Qt::MidButton}; case WM_NCMBUTTONUP: return {QEvent::NonClientAreaMouseButtonRelease, Qt::MidButton}; case WM_NCMBUTTONDBLCLK: - return {QEvent::NonClientAreaMouseButtonDblClick, Qt::MidButton}; + return {QEvent::NonClientAreaMouseButtonPress, Qt::MidButton}; case WM_NCRBUTTONDOWN: return {QEvent::NonClientAreaMouseButtonPress, Qt::RightButton}; case WM_NCRBUTTONUP: return {QEvent::NonClientAreaMouseButtonRelease, Qt::RightButton}; case WM_NCRBUTTONDBLCLK: - return {QEvent::NonClientAreaMouseButtonDblClick, Qt::RightButton}; + return {QEvent::NonClientAreaMouseButtonPress, Qt::RightButton}; default: // WM_MOUSELEAVE break; } diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp index 09eadb247a..21dc0cd577 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp @@ -280,7 +280,7 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q return false; } -static void getMouseEventInfo(UINT message, POINTER_BUTTON_CHANGE_TYPE changeType, QPoint globalPos, QEvent::Type *eventType, Qt::MouseButton *mouseButton) +static void getMouseEventInfo(UINT message, POINTER_BUTTON_CHANGE_TYPE changeType, QEvent::Type *eventType, Qt::MouseButton *mouseButton) { static const QHash buttonMapping { {POINTER_CHANGE_FIRSTBUTTON_DOWN, Qt::LeftButton}, @@ -334,28 +334,6 @@ static void getMouseEventInfo(UINT message, POINTER_BUTTON_CHANGE_TYPE changeTyp } *mouseButton = buttonMapping.value(changeType, Qt::NoButton); - - // Pointer messages lack a double click indicator. Check if this is the case here. - if (*eventType == QEvent::MouseButtonPress || - *eventType == QEvent::NonClientAreaMouseButtonPress) { - static LONG lastTime = 0; - static Qt::MouseButton lastButton = Qt::NoButton; - static QEvent::Type lastEvent = QEvent::None; - static QPoint lastPos; - LONG messageTime = GetMessageTime(); - if (*mouseButton == lastButton - && *eventType == lastEvent - && messageTime - lastTime < (LONG)GetDoubleClickTime() - && qAbs(globalPos.x() - lastPos.x()) < GetSystemMetrics(SM_CXDOUBLECLK) - && qAbs(globalPos.y() - lastPos.y()) < GetSystemMetrics(SM_CYDOUBLECLK)) { - *eventType = nonClient ? QEvent::NonClientAreaMouseButtonDblClick : - QEvent::MouseButtonDblClick; - } - lastTime = messageTime; - lastButton = *mouseButton; - lastEvent = *eventType; - lastPos = globalPos; - } } static QWindow *getWindowUnderPointer(QWindow *window, QPoint globalPos) @@ -467,7 +445,7 @@ bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND h QEvent::Type eventType; Qt::MouseButton button; - getMouseEventInfo(msg.message, pointerInfo->ButtonChangeType, globalPos, &eventType, &button); + getMouseEventInfo(msg.message, pointerInfo->ButtonChangeType, &eventType, &button); if (et & QtWindows::NonClientEventFlag) { QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, mouseButtons, button, eventType, From ebfad73b4e44fe6db8059200da105b4b87888718 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 22 Oct 2018 16:29:29 +0200 Subject: [PATCH 0104/1650] macOS: Fix NSOpenGLContext view association check The expression "m_context.view = view" always evaluates to the view, so the check was flawed. Change-Id: Icef4ba5244975ccd78a151c7d40c53b2364c6148 Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qcocoaglcontext.mm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index 1e1b3907ed..1cd77a22e4 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -414,7 +414,8 @@ bool QCocoaGLContext::setDrawable(QPlatformSurface *surface) // have the same effect as an update. // Now we are ready to associate the view with the context - if ((m_context.view = view) != view) { + m_context.view = view; + if (m_context.view != view) { qCInfo(lcQpaOpenGLContext) << "Failed to set" << view << "as drawable for" << m_context; m_updateObservers.clear(); return false; From 72bedd49bfb02ba7c7abf2a1a4c6cd165ebcd447 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Br=C3=BCning?= Date: Tue, 16 Oct 2018 18:17:56 +0200 Subject: [PATCH 0105/1650] [cocoa] Disable offline renderers for dual AMD FirePro GPU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The AMD FirePro dual gpus on the Mac Pro have a problem with offline renderers in Chromium. Therefore, Chromium and thus Qt WebEngine disable this option via the pixel format attributes. The Qt Cocoa plugin on the other hand enables it in the recent versions, causing context creation in Qt WebEngine to fail when run on a Mac Pro with dual AMD FirePro gpus due to incompatible context options. This patch uses the environment variable QT_MAC_PRO_WEBENGINE_WORKAROUND which is set by Qt WebEngine upon application startup if the application is running on a late 2013 Mac Pro. It should typically not be set from anywhere else. [ChangeLog] Offline renderers will be disabled when the application is using Qt WebEngine and running on one of the late 2013 Mac Pro models. Fixes: QTBUG-70062 Change-Id: I0b0831efb6f4073ebd37672040aaed6370853fc0 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoaglcontext.mm | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index 7ffe0003d3..76f8a7bb02 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -456,7 +456,13 @@ NSOpenGLPixelFormat *QCocoaGLContext::createNSOpenGLPixelFormat(const QSurfaceFo if (format.stereo()) attrs << NSOpenGLPFAStereo; - attrs << NSOpenGLPFAAllowOfflineRenderers; + //Workaround for problems with Chromium and offline renderers on the lat 2013 MacPros. + //FIXME: Think if this could be solved via QSurfaceFormat in the future. + static bool offlineRenderersAllowed = qEnvironmentVariableIsEmpty("QT_MAC_PRO_WEBENGINE_WORKAROUND"); + if (offlineRenderersAllowed) { + // Allow rendering on GPUs without a connected display + attrs << NSOpenGLPFAAllowOfflineRenderers; + } QByteArray useLayer = qgetenv("QT_MAC_WANTS_LAYER"); if (!useLayer.isEmpty() && useLayer.toInt() > 0) { From 509d566ec0f257f7f1a723096b57a718d43d5002 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 18 Oct 2018 22:13:29 +0200 Subject: [PATCH 0106/1650] Don't block mouse events if the window is a Tooltip type If a tooltip was shown on an application modal dialog then it would end up blocking mouse events to the dialog while the tooltip was visible. Since tooltips are special in this case, they should not cause mouse events to be blocked. Fixes: QTBUG-65599 Change-Id: Ibf1729ca4942f5854e4f9687c5586382e23c1c31 Reviewed-by: Richard Moe Gustavsen --- src/gui/kernel/qguiapplication.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 193712a7a7..06d1fcae53 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -792,7 +792,8 @@ static void updateBlockedStatusRecursion(QWindow *window, bool shouldBeBlocked) void QGuiApplicationPrivate::updateBlockedStatus(QWindow *window) { bool shouldBeBlocked = false; - if (!QWindowPrivate::get(window)->isPopup() && !self->modalWindowList.isEmpty()) + const bool popupType = (window->type() == Qt::ToolTip) || (window->type() == Qt::Popup); + if (!popupType && !self->modalWindowList.isEmpty()) shouldBeBlocked = self->isWindowBlocked(window); updateBlockedStatusRecursion(window, shouldBeBlocked); } From 38afa46c47f4401cd5fe8ce6eb93978d5287cfbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 19 Oct 2018 14:35:40 +0200 Subject: [PATCH 0107/1650] macOS: Only detect changes to the SDK version within the same developer dir We want to inform the user when they have upgraded their Xcode version and hence have a new SDK version, which requires a complete rebuild. Explicit changes to the Xcode selection (be it via xcode-select or $DEVELOPER_DIR) do not affect the existing build directory, so we must record the Xcode selection inside the build to avoid false triggering. Change-Id: I7d13da1232226712a4951e8a360cf4b634c6fa2f Reviewed-by: Oswald Buddenhagen --- mkspecs/features/mac/default_post.prf | 2 +- mkspecs/features/mac/sdk.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/mac/default_post.prf b/mkspecs/features/mac/default_post.prf index 353fda41e6..6ea667c1a5 100644 --- a/mkspecs/features/mac/default_post.prf +++ b/mkspecs/features/mac/default_post.prf @@ -3,7 +3,7 @@ load(default_post) contains(TEMPLATE, .*app) { !macx-xcode { # Detect changes to the platform SDK - QMAKE_EXTRA_VARIABLES += QMAKE_MAC_SDK QMAKE_MAC_SDK_VERSION + QMAKE_EXTRA_VARIABLES += QMAKE_MAC_SDK QMAKE_MAC_SDK_VERSION QMAKE_XCODE_DEVELOPER_PATH QMAKE_EXTRA_INCLUDES += $$shell_quote($$PWD/sdk.mk) } diff --git a/mkspecs/features/mac/sdk.mk b/mkspecs/features/mac/sdk.mk index a7c8268da5..c0266f2139 100644 --- a/mkspecs/features/mac/sdk.mk +++ b/mkspecs/features/mac/sdk.mk @@ -1,4 +1,4 @@ -CURRENT_MAC_SDK_VERSION := $(shell /usr/bin/xcrun --sdk $(EXPORT_QMAKE_MAC_SDK) -show-sdk-version) +CURRENT_MAC_SDK_VERSION := $(shell DEVELOPER_DIR=$(EXPORT_QMAKE_XCODE_DEVELOPER_PATH) /usr/bin/xcrun --sdk $(EXPORT_QMAKE_MAC_SDK) -show-sdk-version) ifneq ($(CURRENT_MAC_SDK_VERSION),$(EXPORT_QMAKE_MAC_SDK_VERSION)) $(info The platform SDK has been changed from version $(EXPORT_QMAKE_MAC_SDK_VERSION) to version $(CURRENT_MAC_SDK_VERSION).) From e524724f9dc6f64f6f94b842682c751dcd07225f Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Mon, 15 Oct 2018 09:51:12 +0200 Subject: [PATCH 0108/1650] tst_qfilesystemmodel: Do not use nested calls of auto test functions Calling rowCount inside another auto test function yields unexpected results, if rowCount fails. Without a check for QTest::currentTestFailed the failure will not stop the calling function and other functions like rowsInserted and rowsRemoved might happily continue even though their requirements are not met. That caused a crash on winrt under certain circumstances. In addition to that TRY_WAIT now does not only wait for the given amount of time, but also gives feedback about its result. Before this change TRY_WAIT was basically useless, as it gave no indication about its success/failure. Fixes: QTBUG-71121 Change-Id: Ibd3f233a0b913db799814be97c4274d510643c74 Reviewed-by: Friedemann Kleint --- .../qfilesystemmodel/tst_qfilesystemmodel.cpp | 79 +++++++++++++------ 1 file changed, 56 insertions(+), 23 deletions(-) diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp index d8a680881a..9ee5292fcb 100644 --- a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp +++ b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp @@ -51,10 +51,15 @@ // Will try to wait for the condition while allowing event processing // for a maximum of 5 seconds. -#define TRY_WAIT(expr) \ +#define TRY_WAIT(expr, timedOut) \ do { \ + *timedOut = true; \ const int step = 50; \ - for (int __i = 0; __i < 5000 && !(expr); __i+=step) { \ + for (int __i = 0; __i < 5000; __i += step) { \ + if (expr) { \ + *timedOut = false; \ + break; \ + } \ QTest::qWait(step); \ } \ } while(0) @@ -123,6 +128,8 @@ private slots: protected: bool createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount = 0, const QStringList &intial_dirs = QStringList()); + QModelIndex prepareTestModelRoot(const QString &test_path, QSignalSpy **spy2 = nullptr, + QSignalSpy **spy3 = nullptr); private: QFileSystemModel *model; @@ -306,7 +313,11 @@ void tst_QFileSystemModel::iconProvider() bool tst_QFileSystemModel::createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount, const QStringList &initial_dirs) { //qDebug() << (model->rowCount(model->index(test_path))) << existingFileCount << initial_files; - TRY_WAIT((model->rowCount(model->index(test_path)) == existingFileCount)); + bool timedOut = false; + TRY_WAIT((model->rowCount(model->index(test_path)) == existingFileCount), &timedOut); + if (timedOut) + return false; + for (int i = 0; i < initial_dirs.count(); ++i) { QDir dir(test_path); if (!dir.exists()) { @@ -363,23 +374,45 @@ bool tst_QFileSystemModel::createFiles(const QString &test_path, const QStringLi return true; } -void tst_QFileSystemModel::rowCount() +QModelIndex tst_QFileSystemModel::prepareTestModelRoot(const QString &test_path, QSignalSpy **spy2, + QSignalSpy **spy3) { - QString tmp = flatDirTestPath; - QVERIFY(createFiles(tmp, QStringList())); + if (model->rowCount(model->index(test_path)) != 0) + return QModelIndex(); - QSignalSpy spy2(model, SIGNAL(rowsInserted(QModelIndex,int,int))); - QSignalSpy spy3(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int))); + if (spy2) + *spy2 = new QSignalSpy(model, &QFileSystemModel::rowsInserted); + if (spy3) + *spy3 = new QSignalSpy(model, &QFileSystemModel::rowsAboutToBeInserted); - QStringList files = QStringList() << "b" << "d" << "f" << "h" << "j" << ".a" << ".c" << ".e" << ".g"; + QStringList files = { "b", "d", "f", "h", "j", ".a", ".c", ".e", ".g" }; QString l = "b,d,f,h,j,.a,.c,.e,.g"; - QVERIFY(createFiles(tmp, files)); + if (!createFiles(test_path, files)) + return QModelIndex(); - QModelIndex root = model->setRootPath(tmp); - QTRY_COMPARE(model->rowCount(root), 5); - QVERIFY(spy2.count() > 0); - QVERIFY(spy3.count() > 0); + QModelIndex root = model->setRootPath(test_path); + if (!root.isValid()) + return QModelIndex(); + + bool timedOut = false; + TRY_WAIT(model->rowCount(root) == 5, &timedOut); + if (timedOut) + return QModelIndex(); + + return root; +} + +void tst_QFileSystemModel::rowCount() +{ + const QString tmp = flatDirTestPath; + QSignalSpy *spy2 = nullptr; + QSignalSpy *spy3 = nullptr; + QModelIndex root = prepareTestModelRoot(flatDirTestPath, &spy2, &spy3); + QVERIFY(root.isValid()); + + QVERIFY(spy2 && spy2->count() > 0); + QVERIFY(spy3 && spy3->count() > 0); } void tst_QFileSystemModel::rowsInserted_data() @@ -401,9 +434,9 @@ static inline QString lastEntry(const QModelIndex &root) void tst_QFileSystemModel::rowsInserted() { - QString tmp = flatDirTestPath; - rowCount(); - QModelIndex root = model->index(model->rootPath()); + const QString tmp = flatDirTestPath; + QModelIndex root = prepareTestModelRoot(tmp); + QVERIFY(root.isValid()); QFETCH(int, ascending); QFETCH(int, count); @@ -454,9 +487,9 @@ void tst_QFileSystemModel::rowsRemoved_data() void tst_QFileSystemModel::rowsRemoved() { - QString tmp = flatDirTestPath; - rowCount(); - QModelIndex root = model->index(model->rootPath()); + const QString tmp = flatDirTestPath; + QModelIndex root = prepareTestModelRoot(tmp); + QVERIFY(root.isValid()); QFETCH(int, count); QFETCH(int, ascending); @@ -509,9 +542,9 @@ void tst_QFileSystemModel::dataChanged() { QSKIP("This can't be tested right now since we don't watch files, only directories."); - QString tmp = flatDirTestPath; - rowCount(); - QModelIndex root = model->index(model->rootPath()); + const QString tmp = flatDirTestPath; + QModelIndex root = prepareTestModelRoot(tmp); + QVERIFY(root.isValid()); QFETCH(int, count); QFETCH(int, assending); From 013cf4aeb3e705165614715fcda59c22f58cc5b0 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Fri, 19 Oct 2018 07:37:23 +0200 Subject: [PATCH 0109/1650] angle: Add additional information to qt_attribution.json Task-number: QTBUG-71112 Change-Id: If1b81589f295657597a9dfa3671128a927cbe488 Reviewed-by: Andre de la Rocha Reviewed-by: Edward Welbourne --- src/3rdparty/angle/qt_attribution.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/3rdparty/angle/qt_attribution.json b/src/3rdparty/angle/qt_attribution.json index e35e1f0eb9..b10343d945 100644 --- a/src/3rdparty/angle/qt_attribution.json +++ b/src/3rdparty/angle/qt_attribution.json @@ -5,6 +5,10 @@ "QDocModule": "qtgui", "QtUsage": "Used on Windows to implement OpenGL ES on top of DirectX. Configure with -no-opengl, or -opengl desktop to exclude.", + "Description": "The ANGLE library translates OpenGL ES API calls to hardware-supported APIs.", + "Homepage": "http://angleproject.org/", + "Version": "chromium/3280", + "License": "BSD 3-clause \"New\" or \"Revised\" License", "LicenseId": "BSD-3-Clause", "LicenseFile": "LICENSE", From 88fe7c8cad0bb8e9aee1373c7a7a24d1e4be24ca Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Wed, 24 Oct 2018 14:22:43 +0200 Subject: [PATCH 0110/1650] Windows QPA: Fix 2-finger scroll not working with some touchpads It seems some touchpads only send legacy WM_MOUSEWHEEL/WM_MOUSEHWHEEL messages for 2-finger scrolling, instead of WM_POINTERWHEEL/ WM_POINTERHWHEEL, even after EnableMouseInPointer(TRUE), in spite of sending the expected pointer messages for normal pointer movement/taps. This change adds a workaround to handle legacy wheel messages even when in pointer mode. Task-number: QTBUG-71257 Change-Id: Ib360051147c4521751a5b91d90fa7657496777fa Reviewed-by: Oliver Wolff Reviewed-by: Friedemann Kleint --- .../windows/qwindowspointerhandler.cpp | 43 +++++++++++++++---- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp index 21dc0cd577..2b6c696979 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp @@ -484,6 +484,9 @@ bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND h case WM_POINTERHWHEEL: case WM_POINTERWHEEL: { + if (!isValidWheelReceiver(window)) + return true; + int delta = GET_WHEEL_DELTA_WPARAM(msg.wParam); // Qt horizontal wheel rotation orientation is opposite to the one in WM_POINTERHWHEEL @@ -493,8 +496,7 @@ bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND h const QPoint angleDelta = (msg.message == WM_POINTERHWHEEL || (keyModifiers & Qt::AltModifier)) ? QPoint(delta, 0) : QPoint(0, delta); - if (isValidWheelReceiver(window)) - QWindowSystemInterface::handleWheelEvent(window, localPos, globalPos, QPoint(), angleDelta, keyModifiers); + QWindowSystemInterface::handleWheelEvent(window, localPos, globalPos, QPoint(), angleDelta, keyModifiers); return true; } case WM_POINTERLEAVE: @@ -508,7 +510,6 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd, MSG msg, PVOID vTouchInfo, quint32 count) { Q_UNUSED(hwnd); - Q_UNUSED(et); if (et & QtWindows::NonClientEventFlag) return false; // Let DefWindowProc() handle Non Client messages. @@ -707,21 +708,46 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin // Process old-style mouse messages here. bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result) { - Q_UNUSED(et); - // Generate enqueued events. flushTouchEvents(m_touchDevice); flushTabletEvents(); *result = 0; - if (msg.message != WM_MOUSELEAVE && msg.message != WM_MOUSEMOVE) + if (et != QtWindows::MouseWheelEvent && msg.message != WM_MOUSELEAVE && msg.message != WM_MOUSEMOVE) return false; - const QPoint localPos(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam)); - const QPoint globalPos = QWindowsGeometryHint::mapToGlobal(hwnd, localPos); + const QPoint eventPos(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam)); + QPoint localPos; + QPoint globalPos; + if ((et == QtWindows::MouseWheelEvent) || (et & QtWindows::NonClientEventFlag)) { + globalPos = eventPos; + localPos = QWindowsGeometryHint::mapFromGlobal(hwnd, eventPos); + } else { + localPos = eventPos; + globalPos = QWindowsGeometryHint::mapToGlobal(hwnd, eventPos); + } + const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers(); QWindowsWindow *platformWindow = static_cast(window->handle()); + if (et == QtWindows::MouseWheelEvent) { + + if (!isValidWheelReceiver(window)) + return true; + + int delta = GET_WHEEL_DELTA_WPARAM(msg.wParam); + + // Qt horizontal wheel rotation orientation is opposite to the one in WM_MOUSEHWHEEL + if (msg.message == WM_MOUSEHWHEEL) + delta = -delta; + + const QPoint angleDelta = (msg.message == WM_MOUSEHWHEEL || (keyModifiers & Qt::AltModifier)) ? + QPoint(delta, 0) : QPoint(0, delta); + + QWindowSystemInterface::handleWheelEvent(window, localPos, globalPos, QPoint(), angleDelta, keyModifiers); + return true; + } + if (msg.message == WM_MOUSELEAVE) { if (window == m_currentWindow) { QWindowSystemInterface::handleLeaveEvent(window); @@ -762,7 +788,6 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtW m_windowUnderPointer = currentWindowUnderPointer; } - const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers(); const Qt::MouseButtons mouseButtons = queryMouseButtons(); if (!discardEvent) From 8e1c8076282f87a8d19f73feb1bb5baf068de1e1 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Wed, 24 Oct 2018 11:11:21 +0200 Subject: [PATCH 0111/1650] xcb: fix unresponsive mouse clicks after VT switch This patch amends d67214302f269242ae3d8d2b962fd91ec42c979e. The issue was caused by mistakenly interchanging m_hasXRender <-> m_hasXRandr. Also renamed selectXRandrEvents() -> xrandrSelectEvents() to be more consistent with xi2Select*() API. And moved the xrandrSelectEvents() to QXcbConnection ctor for the same reason. Fixes: QTBUG-71305 Change-Id: I26f9bac3ae1f997f53134eb97f3569fb6d3c13fe Reviewed-by: Allan Sandfeld Jensen --- src/plugins/platforms/xcb/qxcbconnection.cpp | 3 +++ src/plugins/platforms/xcb/qxcbconnection.h | 2 +- src/plugins/platforms/xcb/qxcbconnection_basic.cpp | 4 ++-- src/plugins/platforms/xcb/qxcbconnection_screens.cpp | 6 ++---- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 9e857ea2ff..45f096a13a 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -105,6 +105,9 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra m_xdgCurrentDesktop = qgetenv("XDG_CURRENT_DESKTOP").toLower(); + if (hasXRandr()) + xrandrSelectEvents(); + initializeScreens(); #if QT_CONFIG(xcb_xinput) diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 49e79ec3fd..5d53b97d37 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -250,7 +250,7 @@ protected: bool event(QEvent *e) override; private: - void selectXRandrEvents(); + void xrandrSelectEvents(); QXcbScreen* findScreenForCrtc(xcb_window_t rootWindow, xcb_randr_crtc_t crtc) const; QXcbScreen* findScreenForOutput(xcb_window_t rootWindow, xcb_randr_output_t output) const; QXcbVirtualDesktop* virtualDesktopForRootWindow(xcb_window_t rootWindow) const; diff --git a/src/plugins/platforms/xcb/qxcbconnection_basic.cpp b/src/plugins/platforms/xcb/qxcbconnection_basic.cpp index 7bed3c8937..b8335d1240 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_basic.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_basic.cpp @@ -308,7 +308,7 @@ void QXcbBasicConnection::initializeXRandr() return; } - m_hasXRender = true; + m_hasXRandr = true; m_xrenderVersion.first = xrenderQuery->major_version; m_xrenderVersion.second = xrenderQuery->minor_version; #endif @@ -358,7 +358,7 @@ void QXcbBasicConnection::initializeXRender() return; } - m_hasXRandr = true; + m_hasXRender = true; m_xrandrFirstEvent = reply->first_event; } diff --git a/src/plugins/platforms/xcb/qxcbconnection_screens.cpp b/src/plugins/platforms/xcb/qxcbconnection_screens.cpp index 4c380bf39f..fe9e0be86d 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_screens.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_screens.cpp @@ -46,7 +46,7 @@ #include -void QXcbConnection::selectXRandrEvents() +void QXcbConnection::xrandrSelectEvents() { xcb_screen_iterator_t rootIter = xcb_setup_roots_iterator(setup()); for (; rootIter.rem; xcb_screen_next(&rootIter)) { @@ -270,8 +270,6 @@ void QXcbConnection::destroyScreen(QXcbScreen *screen) void QXcbConnection::initializeScreens() { - selectXRandrEvents(); - xcb_screen_iterator_t it = xcb_setup_roots_iterator(setup()); int xcbScreenNumber = 0; // screen number in the xcb sense QXcbScreen *primaryScreen = nullptr; @@ -284,7 +282,7 @@ void QXcbConnection::initializeScreens() QXcbVirtualDesktop *virtualDesktop = new QXcbVirtualDesktop(this, xcbScreen, xcbScreenNumber); m_virtualDesktops.append(virtualDesktop); QList siblings; - if (hasXRender()) { + if (hasXRandr()) { // RRGetScreenResourcesCurrent is fast but it may return nothing if the // configuration is not initialized wrt to the hardware. We should call // RRGetScreenResources in this case. From 95ba049f8787258ccb28eeda72d1fac71f90e6f6 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Tue, 23 Oct 2018 11:18:22 +0200 Subject: [PATCH 0112/1650] Remove QSKIP and bring the test back to business MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit on macOS, where it was skipped but where it now seems to be stable/work. Task-number: QTBUG-39983 Change-Id: I100a57f23b43074ebacc012be247d92acc6ae336 Reviewed-by: Mårten Nordheim Reviewed-by: Edward Welbourne --- tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp b/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp index fed05698fd..da5327594c 100644 --- a/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp +++ b/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp @@ -209,9 +209,6 @@ void tst_QIODevice::read_QByteArray() //-------------------------------------------------------------------- void tst_QIODevice::unget() { -#if defined(Q_OS_MAC) - QSKIP("The unget network test is unstable on Mac. See QTBUG-39983."); -#endif QBuffer buffer; buffer.open(QBuffer::ReadWrite); buffer.write("ZXCV"); From 321f11db53422fe797c881cafa36ee44406d803c Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Tue, 23 Oct 2018 11:37:07 +0200 Subject: [PATCH 0113/1650] tst_QLocalSocket::processConnections: remove QSKIP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit on macOS, the test seems to be stable nowadays. Task-number: QTBUG-39986 Change-Id: I18430c3feb27a5bee5474e1eb95f7d89b25f00a9 Reviewed-by: Edward Welbourne Reviewed-by: Mårten Nordheim --- tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp index 779d55a77a..45ab275510 100644 --- a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp +++ b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp @@ -962,9 +962,6 @@ void tst_QLocalSocket::processConnection() #if !QT_CONFIG(process) QSKIP("No qprocess support", SkipAll); #else -#ifdef Q_OS_MAC - QSKIP("The processConnection test is unstable on Mac. See QTBUG-39986."); -#endif #ifdef Q_OS_WIN const QString exeSuffix = QStringLiteral(".exe"); From b10ee45546e152e08b2494bd45eb22426e9d2dc9 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Tue, 23 Oct 2018 15:42:24 +0200 Subject: [PATCH 0114/1650] tst_qeventdispatcher: remove macOS from the BLACKLIST MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit the test is stable in Qt 5.12. Task-number: QTBUG-60993 Change-Id: I0c366567121688d9518e90b5e8f9ec1b4006b7b9 Reviewed-by: Mårten Nordheim Reviewed-by: Edward Welbourne --- tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST b/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST index fb7e025b7c..b1590a5ccf 100644 --- a/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST +++ b/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST @@ -1,7 +1,5 @@ [sendPostedEvents] windows -osx [registerTimer] windows -osx winrt From ae57e271e8d37c05cede83ada594b0f58d388a58 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 24 Oct 2018 17:13:57 +0200 Subject: [PATCH 0115/1650] Fix out of bounds memory access when setting motif window hint properties Commit b4bd5f9df3e69da707513ba544537c80a8564fb4 removed two members from the mwm hints structure but told xcb_change_property that the structure has still five members when it had been reduced to three. This lead to xcb_change_property accessing memory out of bounds. As identified by Gatis, the safest option to avoid the access is to add the two members again. Other window managers may be expecting their presence in the window property. Change-Id: Id4f0c9536cd317c35f2c6ebd1ac9ccc6f72de6a5 Reviewed-by: Gatis Paeglis Reviewed-by: Mikhail Svetkin --- src/plugins/platforms/xcb/qxcbwindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index e56f6b13d8..70aab77a51 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -904,6 +904,8 @@ void QXcbWindow::doFocusOut() struct QtMotifWmHints { quint32 flags, functions, decorations; + qint32 input_mode; // unused + quint32 status; // unused }; enum { From d2e0e416d4444ccf3c208d6770e32ff0fb04b543 Mon Sep 17 00:00:00 2001 From: Kirill Burtsev Date: Tue, 23 Oct 2018 18:04:18 +0200 Subject: [PATCH 0116/1650] Fix leaking QTabletEventPrivate instance Fixes: QTBUG-52279 Change-Id: I4f40fc9d3ce938b4c821f10cacd21e6f652a2227 Reviewed-by: Shawn Rutledge --- src/gui/kernel/qevent.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 4207697c01..94fc342e2a 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -2494,6 +2494,7 @@ QTabletEvent::QTabletEvent(Type type, const QPointF &pos, const QPointF &globalP */ QTabletEvent::~QTabletEvent() { + delete static_cast(mExtra); } /*! From 269172037db11d6e62bcef2d5c7491af9244f203 Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Thu, 18 Oct 2018 10:20:42 +1000 Subject: [PATCH 0117/1650] wasm: use maintainTimers instead of processEvents for touch callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: If39cdeedef60a47c0ba1afbab6adf1668bf5d0d6 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/wasm/qwasmeventtranslator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp index 23251fd610..a3fdcd1025 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp @@ -546,7 +546,7 @@ int QWasmEventTranslator::touchCallback(int eventType, const EmscriptenTouchEven else QWindowSystemInterface::handleTouchCancelEvent(window2, wasmEventTranslator->getTimestamp(), wasmEventTranslator->touchDevice, keyModifier); - QCoreApplication::processEvents(); + QWasmEventDispatcher::maintainTimers(); return 1; } From 199b67f11c7c5b9ae0aaf60f3e7ea20dafc21ce4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 18 Oct 2018 18:00:40 +0200 Subject: [PATCH 0118/1650] macOS: Log Qt and macOS version information at startup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SDK and deployment target versions are helpful to know when diagnosing issues. Change-Id: I85026bd9c1d706a923e8953837bd59bf9ed0266f Reviewed-by: Tor Arne Vestbø Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qcocoahelpers.h | 31 +++++++ src/plugins/platforms/cocoa/qcocoahelpers.mm | 82 +++++++++++++++++++ .../platforms/cocoa/qcocoaintegration.mm | 28 +++++++ 3 files changed, 141 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h index 953bf331bb..69aa7937b6 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.h +++ b/src/plugins/platforms/cocoa/qcocoahelpers.h @@ -52,6 +52,7 @@ // #include "qt_mac_p.h" #include +#include #include #include @@ -60,6 +61,8 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSView)); +struct mach_header; + QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(lcQpaWindow) @@ -173,6 +176,34 @@ T qt_mac_resolveOption(const T &fallback, QWindow *window, const QByteArray &pro return fallback; } +// ------------------------------------------------------------------------- + +#if !defined(Q_PROCESSOR_X86_64) +#error "32-bit builds are not supported" +#endif + +class QMacVersion +{ +public: + enum VersionTarget { + ApplicationBinary, + QtLibraries + }; + + static QOperatingSystemVersion buildSDK(VersionTarget target = ApplicationBinary); + static QOperatingSystemVersion deploymentTarget(VersionTarget target = ApplicationBinary); + static QOperatingSystemVersion currentRuntime(); + +private: + QMacVersion() = default; + using VersionTuple = QPair; + static VersionTuple versionsForImage(const mach_header *machHeader); + static VersionTuple applicationVersion(); + static VersionTuple libraryVersion(); +}; + +// ------------------------------------------------------------------------- + QT_END_NAMESPACE // @compatibility_alias doesn't work with protocols diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index 0f5ddfa49a..36841c77ab 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -55,6 +55,9 @@ #include +#include +#include + QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcQpaWindow, "qt.qpa.window"); @@ -368,6 +371,85 @@ QString qt_mac_removeAmpersandEscapes(QString s) return QPlatformTheme::removeMnemonics(s).trimmed(); } +// ------------------------------------------------------------------------- + +#if !defined(Q_PROCESSOR_X86_64) +#error "32-bit builds are not supported" +#endif + +QOperatingSystemVersion QMacVersion::buildSDK(VersionTarget target) +{ + switch (target) { + case ApplicationBinary: return applicationVersion().second; + case QtLibraries: return libraryVersion().second; + } + Q_UNREACHABLE(); +} + +QOperatingSystemVersion QMacVersion::deploymentTarget(VersionTarget target) +{ + switch (target) { + case ApplicationBinary: return applicationVersion().first; + case QtLibraries: return libraryVersion().first; + } + Q_UNREACHABLE(); +} + +QOperatingSystemVersion QMacVersion::currentRuntime() +{ + return QOperatingSystemVersion::current(); +} + +QMacVersion::VersionTuple QMacVersion::versionsForImage(const mach_header *machHeader) +{ + auto commandCursor = uintptr_t(machHeader) + sizeof(mach_header_64); + for (uint32_t i = 0; i < machHeader->ncmds; ++i) { + load_command *loadCommand = reinterpret_cast(commandCursor); + if (loadCommand->cmd == LC_VERSION_MIN_MACOSX) { + auto versionCommand = reinterpret_cast(loadCommand); + uint32_t dt = versionCommand->version; // Deployment target + uint32_t sdk = versionCommand->sdk; // Build SDK + return qMakePair( + QOperatingSystemVersion(QOperatingSystemVersion::MacOS, + dt >> 16 & 0xffff, dt >> 8 & 0xff, dt & 0xff), + QOperatingSystemVersion(QOperatingSystemVersion::MacOS, + sdk >> 16 & 0xffff, sdk >> 8 & 0xff, sdk & 0xff) + ); + } + commandCursor += loadCommand->cmdsize; + } + Q_ASSERT_X(false, "QCocoaIntegration", "Could not find version-min load command"); + Q_UNREACHABLE(); +} + +QMacVersion::VersionTuple QMacVersion::applicationVersion() +{ + static VersionTuple version = []() { + const mach_header *executableHeader = nullptr; + for (uint32_t i = 0; i < _dyld_image_count(); ++i) { + auto header = _dyld_get_image_header(i); + if (header->filetype == MH_EXECUTE) { + executableHeader = header; + break; + } + } + Q_ASSERT_X(executableHeader, "QCocoaIntegration", "Failed to resolve Mach-O header of executable"); + return versionsForImage(executableHeader); + }(); + return version; +} + +QMacVersion::VersionTuple QMacVersion::libraryVersion() +{ + static VersionTuple version = []() { + Dl_info cocoaPluginImage; + dladdr((const void *)&QMacVersion::libraryVersion, &cocoaPluginImage); + Q_ASSERT_X(cocoaPluginImage.dli_fbase, "QCocoaIntegration", "Failed to resolve Mach-O header of Cocoa plugin"); + return versionsForImage(static_cast(cocoaPluginImage.dli_fbase)); + }(); + return version; +} + QT_END_NAMESPACE /*! \internal diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 612290c9bd..936fecf8de 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -79,6 +79,32 @@ static void initResources() QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcQpa, "qt.qpa", QtWarningMsg); + +static void logVersionInformation() +{ + if (!lcQpa().isInfoEnabled()) + return; + + auto osVersion = QMacVersion::currentRuntime(); + auto qtBuildSDK = QMacVersion::buildSDK(QMacVersion::QtLibraries); + auto qtDeploymentTarget = QMacVersion::deploymentTarget(QMacVersion::QtLibraries); + auto appBuildSDK = QMacVersion::buildSDK(QMacVersion::ApplicationBinary); + auto appDeploymentTarget = QMacVersion::deploymentTarget(QMacVersion::ApplicationBinary); + + qCInfo(lcQpa, "Loading macOS (Cocoa) platform plugin for Qt " QT_VERSION_STR ", running on macOS %d.%d.%d\n\n" \ + " Component SDK version Deployment target \n" \ + " ------------- ------------- -------------------\n" \ + " Qt " QT_VERSION_STR " %d.%d.%d %d.%d.%d\n" \ + " Application %d.%d.%d %d.%d.%d\n", + osVersion.majorVersion(), osVersion.minorVersion(), osVersion.microVersion(), + qtBuildSDK.majorVersion(), qtBuildSDK.minorVersion(), qtBuildSDK.microVersion(), + qtDeploymentTarget.majorVersion(), qtDeploymentTarget.minorVersion(), qtDeploymentTarget.microVersion(), + appBuildSDK.majorVersion(), appBuildSDK.minorVersion(), appBuildSDK.microVersion(), + appDeploymentTarget.majorVersion(), appDeploymentTarget.minorVersion(), appDeploymentTarget.microVersion()); +} + + class QCoreTextFontEngine; class QFontEngineFT; @@ -112,6 +138,8 @@ QCocoaIntegration::QCocoaIntegration(const QStringList ¶mList) , mServices(new QCocoaServices) , mKeyboardMapper(new QCocoaKeyMapper) { + logVersionInformation(); + if (mInstance) qWarning("Creating multiple Cocoa platform integrations is not supported"); mInstance = this; From 9cd527bc1f384926985d63c741641316a66f17a4 Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Fri, 7 Sep 2018 19:16:23 +0200 Subject: [PATCH 0119/1650] Add support for generating PDFs with losslessly encoded images This patch adds the QPainter::LosslessImageRendering flag to QPainter::RenderHints and allows QPdfEngine to recognize it and encode images using a lossless data compression algorithm provided by zlib instead of using lossy JPEG compression, which can produce artifacts with some images. Task-number: QTBUG-54809 Change-Id: If9e2bc64da3bf3afcd5d6c74f0ee82336ef05a19 Reviewed-by: Lars Knoll --- src/gui/painting/qpainter.cpp | 7 +++++++ src/gui/painting/qpainter.h | 3 ++- src/gui/painting/qpdf.cpp | 15 ++++++++++----- src/gui/painting/qpdf_p.h | 2 +- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index b70b29e54e..df2f5e11d3 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -1437,6 +1437,13 @@ void QPainterPrivate::updateState(QPainterState *newState) by slightly less than half a pixel. Also will treat default constructed pens as cosmetic. Potentially useful when porting a Qt 4 application to Qt 5. + \value LosslessImageRendering Use a lossless image rendering, whenever possible. + Currently, this hint is only used when QPainter is employed to output a PDF + file through QPrinter or QPdfWriter, where drawImage()/drawPixmap() calls + will encode images using a lossless compression algorithm instead of lossy + JPEG compression. + This value was added in Qt 5.13. + \sa renderHints(), setRenderHint(), {QPainter#Rendering Quality}{Rendering Quality}, {Concentric Circles Example} diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h index 482f5fb63d..87c4899f0b 100644 --- a/src/gui/painting/qpainter.h +++ b/src/gui/painting/qpainter.h @@ -91,7 +91,8 @@ public: SmoothPixmapTransform = 0x04, HighQualityAntialiasing = 0x08, NonCosmeticDefaultPen = 0x10, - Qt4CompatiblePainting = 0x20 + Qt4CompatiblePainting = 0x20, + LosslessImageRendering = 0x40, }; Q_FLAG(RenderHint) diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index 4fd0d3c8fe..26737e3da1 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -944,7 +944,8 @@ void QPdfEngine::drawPixmap (const QRectF &rectangle, const QPixmap &pixmap, con QPixmap pm = sourceRect != pixmap.rect() ? pixmap.copy(sourceRect) : pixmap; QImage image = pm.toImage(); bool bitmap = true; - const int object = d->addImage(image, &bitmap, pm.cacheKey()); + const bool lossless = painter()->testRenderHint(QPainter::LosslessImageRendering); + const int object = d->addImage(image, &bitmap, lossless, pm.cacheKey()); if (object < 0) return; @@ -972,7 +973,8 @@ void QPdfEngine::drawImage(const QRectF &rectangle, const QImage &image, const Q QRect sourceRect = sr.toRect(); QImage im = sourceRect != image.rect() ? image.copy(sourceRect) : image; bool bitmap = true; - const int object = d->addImage(im, &bitmap, im.cacheKey()); + const bool lossless = painter()->testRenderHint(QPainter::LosslessImageRendering); + const int object = d->addImage(im, &bitmap, lossless, im.cacheKey()); if (object < 0) return; @@ -2578,6 +2580,8 @@ int QPdfEnginePrivate::addConstantAlphaObject(int brushAlpha, int penAlpha) int QPdfEnginePrivate::addBrushPattern(const QTransform &m, bool *specifyColor, int *gStateObject) { + Q_Q(QPdfEngine); + int paintType = 2; // Uncolored tiling int w = 8; int h = 8; @@ -2607,7 +2611,8 @@ int QPdfEnginePrivate::addBrushPattern(const QTransform &m, bool *specifyColor, return 0; QImage image = brush.textureImage(); bool bitmap = true; - imageObject = addImage(image, &bitmap, image.cacheKey()); + const bool lossless = q->painter()->testRenderHint(QPainter::LosslessImageRendering); + imageObject = addImage(image, &bitmap, lossless, image.cacheKey()); if (imageObject != -1) { QImage::Format f = image.format(); if (f != QImage::Format_MonoLSB && f != QImage::Format_Mono) { @@ -2669,7 +2674,7 @@ static inline bool is_monochrome(const QVector &colorTable) /*! * Adds an image to the pdf and return the pdf-object id. Returns -1 if adding the image failed. */ -int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_no) +int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, bool lossless, qint64 serial_no) { if (img.isNull()) return -1; @@ -2730,7 +2735,7 @@ int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_n bool hasAlpha = false; bool hasMask = false; - if (QImageWriter::supportedImageFormats().contains("jpeg") && !grayscale) { + if (QImageWriter::supportedImageFormats().contains("jpeg") && !grayscale && !lossless) { QBuffer buffer(&imageData); QImageWriter writer(&buffer, "jpeg"); writer.setQuality(94); diff --git a/src/gui/painting/qpdf_p.h b/src/gui/painting/qpdf_p.h index 5a909f2ede..4868f064c7 100644 --- a/src/gui/painting/qpdf_p.h +++ b/src/gui/painting/qpdf_p.h @@ -241,7 +241,7 @@ public: void writeHeader(); void writeTail(); - int addImage(const QImage &image, bool *bitmap, qint64 serial_no); + int addImage(const QImage &image, bool *bitmap, bool lossless, qint64 serial_no); int addConstantAlphaObject(int brushAlpha, int penAlpha = 255); int addBrushPattern(const QTransform &matrix, bool *specifyColor, int *gStateObject); From d555327a57cb1419fbc19c7dd0b12f6c845598a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 19 Oct 2018 14:16:04 +0200 Subject: [PATCH 0120/1650] macOS: Explicitly define lower bound for supported SDK version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to support apps building against the 10.13 SDK, so that they can opt out of dark mode and layer-backing. This does not mean we can't require 10.14 to build Qt itself, but doing so should not require the app to also build against the 10.14 SDK. Change-Id: I53bd0fc8bf56c0be6614acec14d5173589e2620f Reviewed-by: Timur Pocheptsov Reviewed-by: Oswald Buddenhagen Reviewed-by: Tor Arne Vestbø --- mkspecs/common/macx.conf | 3 ++- mkspecs/features/mac/default_post.prf | 15 +++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/mkspecs/common/macx.conf b/mkspecs/common/macx.conf index d61ad33351..889027ada5 100644 --- a/mkspecs/common/macx.conf +++ b/mkspecs/common/macx.conf @@ -7,7 +7,8 @@ QMAKE_MAC_SDK = macosx QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.12 QMAKE_APPLE_DEVICE_ARCHS = x86_64 -QT_MAC_SDK_VERSION_TESTED_WITH = 10.14 +QT_MAC_SDK_VERSION_MIN = 10.13 +QT_MAC_SDK_VERSION_MAX = 10.14 device.sdk = macosx device.target = device diff --git a/mkspecs/features/mac/default_post.prf b/mkspecs/features/mac/default_post.prf index ae17f076a3..5d3ab7ed6e 100644 --- a/mkspecs/features/mac/default_post.prf +++ b/mkspecs/features/mac/default_post.prf @@ -9,19 +9,22 @@ contains(TEMPLATE, .*app) { # Detect incompatible SDK versions - !versionAtLeast(QMAKE_MAC_SDK_VERSION, $$QT_MAC_SDK_VERSION): \ - warning("Qt requires at least version $$QT_MAC_SDK_VERSION of the platform SDK," \ + isEmpty(QT_MAC_SDK_VERSION_MIN): \ + QT_MAC_SDK_VERSION_MIN = $$QT_MAC_SDK_VERSION + + !versionAtLeast(QMAKE_MAC_SDK_VERSION, $$QT_MAC_SDK_VERSION_MIN): \ + warning("Qt requires at least version $$QT_MAC_SDK_VERSION_MIN of the platform SDK," \ "you're using $${QMAKE_MAC_SDK_VERSION}. Please upgrade.") - !isEmpty(QT_MAC_SDK_VERSION_TESTED_WITH) { + !isEmpty(QT_MAC_SDK_VERSION_MAX) { # For Qt developers only !isEmpty($$list($$(QT_MAC_SDK_NO_VERSION_CHECK))): \ CONFIG += sdk_no_version_check QMAKE_MAC_SDK_MAJOR_MINOR_VERSION = $$replace(QMAKE_MAC_SDK_VERSION, "(\d+)(\.\d+)(\.\d+)?", \1\2) - !sdk_no_version_check:!versionAtMost(QMAKE_MAC_SDK_MAJOR_MINOR_VERSION, $$QT_MAC_SDK_VERSION_TESTED_WITH) { - warning("Qt has only been tested with version $$QT_MAC_SDK_VERSION_TESTED_WITH"\ + !sdk_no_version_check:!versionAtMost(QMAKE_MAC_SDK_MAJOR_MINOR_VERSION, $$QT_MAC_SDK_VERSION_MAX) { + warning("Qt has only been tested with version $$QT_MAC_SDK_VERSION_MAX"\ "of the platform SDK, you're using $${QMAKE_MAC_SDK_MAJOR_MINOR_VERSION}.") warning("This is an unsupported configuration. You may experience build issues," \ "and by using") @@ -29,7 +32,7 @@ contains(TEMPLATE, .*app) { "that Qt has not been prepared for.") warning("Please downgrade the SDK you use to build your app to version" \ - "$$QT_MAC_SDK_VERSION_TESTED_WITH, or configure") + "$$QT_MAC_SDK_VERSION_MAX, or configure") warning("with CONFIG+=sdk_no_version_check when running qmake" \ "to silence this warning.") } From acf5c37046944d6483cfc68b3d877b015292d415 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 22 Oct 2018 19:29:32 +0200 Subject: [PATCH 0121/1650] macOS: Add local auto-release pool during updating of window flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prevents no-longer used QNSWindows from staying around (closed and invisible, but alive), due to being auto-released when there is no pool in place (during main(), before exec). Change-Id: I4eb63c7140290ffe6bded8a76732354c846ed579 Reviewed-by: Timur Pocheptsov Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoawindow.mm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 98e48a8b70..a28bdd628b 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -541,6 +541,12 @@ void QCocoaWindow::setWindowZoomButton(Qt::WindowFlags flags) void QCocoaWindow::setWindowFlags(Qt::WindowFlags flags) { + // Updating the window flags may affect the window's theme frame, which + // in the process retains and then autoreleases the NSWindow. To make + // sure this doesn't leave lingering releases when there is no pool in + // place (e.g. during main(), before exec), we add one locally here. + QMacAutoReleasePool pool; + if (!isContentView()) return; From 95476bfcf64aa9cb43775ebfe3410ce9565de4d5 Mon Sep 17 00:00:00 2001 From: Ivan Komissarov Date: Mon, 22 Oct 2018 19:08:57 +0200 Subject: [PATCH 0122/1650] qendian: Fix float conversions Since Qt 5.10, qTo/FromBig/LittleEndian stopped working. It may be confusing, but big endian floats do exist, so not to break old code, we should support them. Change-Id: I21cdbc7f48ec030ce3d82f1cd1aad212f0fe5dd0 Reviewed-by: Thiago Macieira --- src/corelib/global/qendian.h | 26 ++++++++++++ .../corelib/global/qtendian/tst_qtendian.cpp | 40 +++++++++++++++++-- 2 files changed, 63 insertions(+), 3 deletions(-) diff --git a/src/corelib/global/qendian.h b/src/corelib/global/qendian.h index 1cc8a823d9..0e67a1ab8e 100644 --- a/src/corelib/global/qendian.h +++ b/src/corelib/global/qendian.h @@ -41,6 +41,7 @@ #ifndef QENDIAN_H #define QENDIAN_H +#include #include // include stdlib.h and hope that it defines __GLIBC__ for glibc-based systems @@ -151,6 +152,31 @@ template <> inline Q_DECL_CONSTEXPR qint8 qbswap(qint8 source) return source; } +// floating specializations +template +Float qbswapFloatHelper(Float source) +{ + // memcpy call in qFromUnaligned is recognized by optimizer as a correct way of type prunning + auto temp = qFromUnaligned::Unsigned>(&source); + temp = qbswap(temp); + return qFromUnaligned(&temp); +} + +template <> inline qfloat16 qbswap(qfloat16 source) +{ + return qbswapFloatHelper(source); +} + +template <> inline float qbswap(float source) +{ + return qbswapFloatHelper(source); +} + +template <> inline double qbswap(double source) +{ + return qbswapFloatHelper(source); +} + /* * qbswap(const T src, const void *dest); * Changes the byte order of \a src from big endian to little endian or vice versa diff --git a/tests/auto/corelib/global/qtendian/tst_qtendian.cpp b/tests/auto/corelib/global/qtendian/tst_qtendian.cpp index 7043969c2f..2345bb39c1 100644 --- a/tests/auto/corelib/global/qtendian/tst_qtendian.cpp +++ b/tests/auto/corelib/global/qtendian/tst_qtendian.cpp @@ -64,6 +64,9 @@ struct TestData quint16 data16; quint8 data8; + float dataFloat; + double dataDouble; + quint8 reserved; }; @@ -72,6 +75,7 @@ template <> quint8 getData(const TestData &d) { return d.data8; } template <> quint16 getData(const TestData &d) { return d.data16; } template <> quint32 getData(const TestData &d) { return d.data32; } template <> quint64 getData(const TestData &d) { return d.data64; } +template <> float getData(const TestData &d) { return d.dataFloat; } union RawTestData { @@ -79,9 +83,39 @@ union RawTestData TestData data; }; -static const TestData inNativeEndian = { Q_UINT64_C(0x0123456789abcdef), 0x00c0ffee, 0xcafe, 0xcf, '\0' }; -static const RawTestData inBigEndian = { "\x01\x23\x45\x67\x89\xab\xcd\xef" "\x00\xc0\xff\xee" "\xca\xfe" "\xcf" }; -static const RawTestData inLittleEndian = { "\xef\xcd\xab\x89\x67\x45\x23\x01" "\xee\xff\xc0\x00" "\xfe\xca" "\xcf" }; +template +Float int2Float(typename QIntegerForSizeof::Unsigned i) +{ + Float result = 0; + memcpy(reinterpret_cast(&result), reinterpret_cast(&i), sizeof (Float)); + return result; +} + +static const TestData inNativeEndian = { + Q_UINT64_C(0x0123456789abcdef), + 0x00c0ffee, + 0xcafe, + 0xcf, + int2Float(0x00c0ffeeU), + int2Float(Q_UINT64_C(0x0123456789abcdef)), + '\0' +}; +static const RawTestData inBigEndian = { + "\x01\x23\x45\x67\x89\xab\xcd\xef" + "\x00\xc0\xff\xee" + "\xca\xfe" + "\xcf" + "\x00\xc0\xff\xee" + "\x01\x23\x45\x67\x89\xab\xcd\xef" +}; +static const RawTestData inLittleEndian = { + "\xef\xcd\xab\x89\x67\x45\x23\x01" + "\xee\xff\xc0\x00" + "\xfe\xca" + "\xcf" + "\xee\xff\xc0\x00" + "\xef\xcd\xab\x89\x67\x45\x23\x01" +}; #define EXPAND_ENDIAN_TEST(endian) \ do { \ From d02fed67814a3cb8f28a4f0ec61e075858fce238 Mon Sep 17 00:00:00 2001 From: Rafael Roquetto Date: Mon, 1 Oct 2018 09:16:28 +1000 Subject: [PATCH 0123/1650] macOS: restore hidden popup windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to to explicitly unhide popup windows that were previously explicitly hidden by applicationWillHide, so that their visibility will be effectively restored when the application is unhidden (otherwise the windows are gone forever even though their internal visibility is set to true). Change-Id: I4dbd209b07f769cc815851b40c41db0739ca2dc9 Task-number: QTBUG-71014 Reviewed-by: Timur Pocheptsov Reviewed-by: Edward Welbourne Reviewed-by: Tor Arne Vestbø --- .../cocoa/qcocoaapplicationdelegate.mm | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm index 221a8b0866..44ab16d300 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm +++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm @@ -86,6 +86,7 @@ #include #include "qt_mac_p.h" #include +#include QT_USE_NAMESPACE @@ -93,6 +94,7 @@ QT_USE_NAMESPACE bool startedQuit; NSObject *reflectionDelegate; bool inLaunch; + QWindowList hiddenWindows; } + (instancetype)sharedDelegate @@ -322,12 +324,28 @@ QT_USE_NAMESPACE // fact that the application itself is hidden, which will cause a problem when // the application is made visible again. const QWindowList topLevelWindows = QGuiApplication::topLevelWindows(); - for (QWindow *topLevelWindow : qAsConst(topLevelWindows)) { - if ((topLevelWindow->type() & Qt::Popup) == Qt::Popup && topLevelWindow->isVisible()) + for (QWindow *topLevelWindow : topLevelWindows) { + if ((topLevelWindow->type() & Qt::Popup) == Qt::Popup && topLevelWindow->isVisible()) { topLevelWindow->hide(); + + if ((topLevelWindow->type() & Qt::Tool) == Qt::Tool) + hiddenWindows << topLevelWindow; + } } } +- (void)applicationDidUnhide:(NSNotification *)notification +{ + if (reflectionDelegate + && [reflectionDelegate respondsToSelector:@selector(applicationDidUnhide:)]) + [reflectionDelegate applicationDidUnhide:notification]; + + for (QWindow *window : qAsConst(hiddenWindows)) + window->show(); + + hiddenWindows.clear(); +} + - (void)applicationDidBecomeActive:(NSNotification *)notification { if (reflectionDelegate From e02d758c9509de31aafc82d53296f1acdab55151 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 22 Oct 2018 21:22:05 +0200 Subject: [PATCH 0124/1650] macOS: Treat explicitly set Qt::SubWindows as not needing a NSWindow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We used to have logic that explicitly marked a QWindow as "embedded", but we now resolve this dynamically based on whether or not we have a parent window owned by Qt or not. As part of this refactoring the fix for QTBUG-63443 in ac35f9c44c got lost. We restore the behavior by treating Qt::SubWindow as a reason not to create a NSWindow for a view. This flag is set by QMenuPrivate::moveWidgetToPlatformItem already. Fixes: QTBUG-63443 Change-Id: I12bff546eefcb8f6c9ca43b1b879773d129a28f9 Reviewed-by: Morten Johan Sørvig Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoawindow.mm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index a28bdd628b..1ce671941d 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1378,11 +1378,14 @@ void QCocoaWindow::recreateWindowIfNeeded() if (m_windowModality != window()->modality()) recreateReason |= WindowModalityChanged; - const bool shouldBeContentView = !parentWindow && !isEmbeddedView; + Qt::WindowType type = window()->type(); + + const bool shouldBeContentView = !parentWindow + && !((type & Qt::SubWindow) == Qt::SubWindow) + && !isEmbeddedView; if (isContentView() != shouldBeContentView) recreateReason |= ContentViewChanged; - Qt::WindowType type = window()->type(); const bool isPanel = isContentView() && [m_view.window isKindOfClass:[QNSPanel class]]; const bool shouldBePanel = shouldBeContentView && ((type & Qt::Popup) == Qt::Popup || (type & Qt::Dialog) == Qt::Dialog); From d4e937a6280f34bc1cce8c8cea3806a741312fbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Tue, 25 Sep 2018 18:45:10 +0200 Subject: [PATCH 0125/1650] xcb: Don't get initial screen rotation "xcb_randr_get_screen_info" can be slow and in some configurations can cause short mouse cursor freezes (which will happen on Qt application startup). Initial screen rotation was used only to not handle possible redundant screen change event. Fixes: QTBUG-70760 Change-Id: I9f01325a045d2c82c4dd2fce91a18a34e54a4bcd Reviewed-by: Gatis Paeglis --- src/plugins/platforms/xcb/qxcbscreen.cpp | 7 ------- src/plugins/platforms/xcb/qxcbscreen.h | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index 7f2793b2b7..a696e2a311 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -118,13 +118,6 @@ QXcbVirtualDesktop::QXcbVirtualDesktop(QXcbConnection *connection, xcb_screen_t xcb_depth_next(&depth_iterator); } - - if (connection->hasXRandr()) { - xcb_connection_t *conn = connection->xcb_connection(); - auto screen_info = Q_XCB_REPLY(xcb_randr_get_screen_info, conn, screen->root); - if (screen_info) - m_rotation = screen_info->rotation; - } } QXcbVirtualDesktop::~QXcbVirtualDesktop() diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h index 6438669e7a..792aca4b06 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.h +++ b/src/plugins/platforms/xcb/qxcbscreen.h @@ -220,7 +220,7 @@ private: xcb_randr_crtc_t m_crtc; xcb_randr_mode_t m_mode = XCB_NONE; bool m_primary = false; - uint8_t m_rotation = XCB_RANDR_ROTATION_ROTATE_0; + uint8_t m_rotation = 0; QString m_outputName; QSizeF m_outputSizeMillimeters; From 58d2180dfac2e279b7fae89d467b16d82d80eb7e Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Sun, 28 Oct 2018 11:33:29 +0100 Subject: [PATCH 0126/1650] Add since 5.11 markers to two QFile enums Change-Id: Iaa015046cdcece10c28437da40fcd6cdc9d55eb3 Reviewed-by: Thiago Macieira --- src/corelib/io/qiodevice.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index 5dd5f8031e..86e21f0a66 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -333,7 +333,7 @@ QIODevicePrivate::~QIODevicePrivate() allowed. This flag currently only affects QFile. Other classes might use this flag in the future, but until then using this flag with any classes other than QFile may - result in undefined behavior. + result in undefined behavior. (since Qt 5.11) \value ExistingOnly Fail if the file to be opened does not exist. This flag must be specified alongside ReadOnly, WriteOnly, or ReadWrite. Note that using this flag with ReadOnly alone @@ -341,7 +341,7 @@ QIODevicePrivate::~QIODevicePrivate() not exist. This flag currently only affects QFile. Other classes might use this flag in the future, but until then using this flag with any classes other than QFile may - result in undefined behavior. + result in undefined behavior. (since Qt 5.11) Certain flags, such as \c Unbuffered and \c Truncate, are meaningless when used with some subclasses. Some of these From 3b8075de3b3c842311c157476a85d2cf9ddff403 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 25 Oct 2018 16:32:13 -0700 Subject: [PATCH 0127/1650] Fix deleting of QSharedPointer internals in case QPointer loses the race MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QPointer uses QWeakPointer / QSharedPointer internals in QObject and has the code to make sure two threads won't stomp on each other if both try to create a QPointer for the same QObject at the same time. The threading code was fine, but had a mistake in the clean up code for the loser thread: the QtSharedPointer::ExternalRefCountData destructor has a Q_ASSERT for the state of the reference counts. So we need to set the state correctly before calling the destructor. But we don't want to do it in case the Q_ASSERT compiled to nothing. So we use a hack that violates the Second Rule of Q_ASSERTs: don't do something with side-effects. This way, we can insert code that will only be compiled if Q_ASSERTs do something, without having to duplicate the preprocessor conditions from qglobal.h. Fixes: QTBUG-71412 Change-Id: I1bd327aeaf73421a8ec5fffd1560fdfc8b73b70c Reviewed-by: Romain Pokrzywka Reviewed-by: Jędrzej Nowacki --- src/corelib/tools/qsharedpointer.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index 2d5fd2a00e..65616e2abb 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -1466,6 +1466,9 @@ QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::ge x->strongref.store(-1); x->weakref.store(2); // the QWeakPointer that called us plus the QObject itself if (!d->sharedRefcount.testAndSetRelease(0, x)) { + // ~ExternalRefCountData has a Q_ASSERT, so we use this trick to + // only execute this if Q_ASSERTs are enabled + Q_ASSERT((x->weakref.store(0), true)); delete x; x = d->sharedRefcount.loadAcquire(); x->weakref.ref(); From fc1ab49cd75608f257fb9aa577fed490c5a8e551 Mon Sep 17 00:00:00 2001 From: Joni Poikelin Date: Wed, 24 Oct 2018 10:28:23 +0300 Subject: [PATCH 0128/1650] Fix leak in QContiguousCache::setCapacity Fixes: QTBUG-52125 Change-Id: Id0073e73279d049cf3f89ef6ea3a5ca1027efb0d Reviewed-by: Thiago Macieira --- src/corelib/tools/qcontiguouscache.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h index faa7263d6b..fdb9c6d19a 100644 --- a/src/corelib/tools/qcontiguouscache.h +++ b/src/corelib/tools/qcontiguouscache.h @@ -217,6 +217,7 @@ void QContiguousCache::setCapacity(int asize) detach(); union { QContiguousCacheData *d; QContiguousCacheTypedData *p; } x; x.d = allocateData(asize); + x.d->ref.store(1); x.d->alloc = asize; x.d->count = qMin(d->count, asize); x.d->offset = d->offset + d->count - x.d->count; From 56410a51cc897e3b38a0794019ebf196b1eb22d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 7 Sep 2018 11:28:17 +0200 Subject: [PATCH 0129/1650] Clarify behavior of QCoreApplication::processEvents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The overload that takes a maxtime (now duration) was buggy, but we can't change its behavior, so instead we clarify what it actually does. Change-Id: I8a04fbaea5847c95b6ec6e73396304ab4debd35b Reviewed-by: Paul Wicking Reviewed-by: Edward Welbourne Reviewed-by: Tor Arne Vestbø --- src/corelib/kernel/qcoreapplication.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 463e30e1c3..965d65fb5d 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -1266,7 +1266,11 @@ bool QCoreApplication::closingDown() \l{QCoreApplication::sendPostedEvents()}{sendPostedEvents()} from within that local loop. - Calling this function processes events only for the calling thread. + Calling this function processes events only for the calling thread, + and returns after all available events have been processed. Available + events are events queued before the function call. This means that + events that are posted while the function runs will be queued until + a later round of event processing. \threadsafe @@ -1283,7 +1287,7 @@ void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags) /*! \overload processEvents() - Processes pending events for the calling thread for \a maxtime + Processes pending events for the calling thread for \a ms milliseconds or until there are no more events to process, whichever is shorter. @@ -1292,11 +1296,14 @@ void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags) Calling this function processes events only for the calling thread. + \note Unlike the \l{QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags)}{processEvents()} + overload, this function also processes events that are posted while the function runs. + \threadsafe \sa exec(), QTimer, QEventLoop::processEvents() */ -void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int maxtime) +void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int ms) { // ### Qt 6: consider splitting this method into a public and a private // one, so that a user-invoked processEvents can be detected @@ -1307,7 +1314,7 @@ void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int m QElapsedTimer start; start.start(); while (data->eventDispatcher.load()->processEvents(flags & ~QEventLoop::WaitForMoreEvents)) { - if (start.elapsed() > maxtime) + if (start.elapsed() > ms) break; } } From 1b9af84c1bb66770f607e157991375f7cb7ae0fb Mon Sep 17 00:00:00 2001 From: Andy Nichols Date: Tue, 23 Oct 2018 11:41:19 +0200 Subject: [PATCH 0130/1650] Don't create an offscreen surface when not on the GUI thread When we try to gracefully destroy a QOpenGLVertexArrayObject it is not possible to create an QOffscreenSurface from a thread that is not the GUI thread. In this case we just need to bail out instead. The side effect that was seen previously was that there would be a warning and a deadlock on Windows when closing QQuickWindows that contained a QQuickPaintedItem backed by a FrameBufferObject render target (which would be using the OpenGL paint engine) when using the threaded render loop. Task-number: QTBUG-70148 Change-Id: I4a20d74d9af850bb90d243212ad9f65c3fc9e616 Reviewed-by: Laszlo Agocs --- src/gui/opengl/qopenglvertexarrayobject.cpp | 33 +++++++++++++-------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/gui/opengl/qopenglvertexarrayobject.cpp b/src/gui/opengl/qopenglvertexarrayobject.cpp index 0262538250..f0837aff96 100644 --- a/src/gui/opengl/qopenglvertexarrayobject.cpp +++ b/src/gui/opengl/qopenglvertexarrayobject.cpp @@ -40,8 +40,10 @@ #include "qopenglvertexarrayobject.h" #include +#include #include #include +#include #include #include @@ -204,18 +206,25 @@ void QOpenGLVertexArrayObjectPrivate::destroy() if (context && context != ctx) { oldContext = ctx; oldContextSurface = ctx ? ctx->surface() : 0; - // Cannot just make the current surface current again with another context. - // The format may be incompatible and some platforms (iOS) may impose - // restrictions on using a window with different contexts. Create an - // offscreen surface (a pbuffer or a hidden window) instead to be safe. - offscreenSurface.reset(new QOffscreenSurface); - offscreenSurface->setFormat(context->format()); - offscreenSurface->create(); - if (context->makeCurrent(offscreenSurface.data())) { - ctx = context; - } else { - qWarning("QOpenGLVertexArrayObject::destroy() failed to make VAO's context current"); + // Before going through the effort of creating an offscreen surface + // check that we are on the GUI thread because otherwise many platforms + // will not able to create that offscreen surface. + if (QThread::currentThread() != qGuiApp->thread()) { ctx = 0; + } else { + // Cannot just make the current surface current again with another context. + // The format may be incompatible and some platforms (iOS) may impose + // restrictions on using a window with different contexts. Create an + // offscreen surface (a pbuffer or a hidden window) instead to be safe. + offscreenSurface.reset(new QOffscreenSurface); + offscreenSurface->setFormat(context->format()); + offscreenSurface->create(); + if (context->makeCurrent(offscreenSurface.data())) { + ctx = context; + } else { + qWarning("QOpenGLVertexArrayObject::destroy() failed to make VAO's context current"); + ctx = 0; + } } } @@ -224,7 +233,7 @@ void QOpenGLVertexArrayObjectPrivate::destroy() context = 0; } - if (vao) { + if (vao && ctx) { switch (vaoFuncsType) { #ifndef QT_OPENGL_ES_2 case Core_3_2: From 1864748136c5ef9e6e435f201f2485bfeb7ada0f Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Fri, 19 Oct 2018 12:29:51 +0200 Subject: [PATCH 0131/1650] doc: Let qdoc parse qdtls.h even without dtls This update removes the requirement for dtls to be present when qdoc runs so that qdoc can parse qdtls.h. _#ifndef Q_CLANG_QDOC QT_REQUIRE_CONFIG(dtls); _#endif Change-Id: I69ba5e378bebe86f93830d14e3956eb0d677508e Reviewed-by: Martin Smith --- src/network/ssl/qdtls.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/network/ssl/qdtls.h b/src/network/ssl/qdtls.h index 8505b00d5e..d057eadf19 100644 --- a/src/network/ssl/qdtls.h +++ b/src/network/ssl/qdtls.h @@ -48,7 +48,9 @@ #include #include +#ifndef Q_CLANG_QDOC QT_REQUIRE_CONFIG(dtls); +#endif QT_BEGIN_NAMESPACE From 7087a68fbf42799eb2d11bc072b63033ae58e8b4 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Fri, 19 Oct 2018 17:10:41 +0200 Subject: [PATCH 0132/1650] doc: Add \since 6.0 to future functions qdoc needs to know that a qdoc comment should not be part of the documentation until a future version. In this case, some new functions were declared to become active in Qt 6.0, but qdoc had no way of detecting this and reported errors about them incorrectly. Adding \since 6.0 to the qdoc comments for these functions allows qdoc to ignore them without printing the errors. It is also not allowed to document static functions declared in .cpp files, because these functions are not in the public API. The qdoc comment marker was removed from the comments for a few such static functions. Change-Id: I55ce0e8fb823b1dcf498d5a2436ddb20ad0a7527 Reviewed-by: Martin Smith --- src/corelib/itemmodels/qabstractproxymodel.cpp | 1 + src/corelib/itemmodels/qstringlistmodel.cpp | 1 + src/corelib/tools/qbytearray.cpp | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/corelib/itemmodels/qabstractproxymodel.cpp b/src/corelib/itemmodels/qabstractproxymodel.cpp index 095ab6fc71..118e808a3c 100644 --- a/src/corelib/itemmodels/qabstractproxymodel.cpp +++ b/src/corelib/itemmodels/qabstractproxymodel.cpp @@ -316,6 +316,7 @@ bool QAbstractProxyModel::setHeaderData(int section, Qt::Orientation orientation #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) /*! \reimp + \since 6.0 */ bool QAbstractProxyModel::clearItemData(const QModelIndex &index) { diff --git a/src/corelib/itemmodels/qstringlistmodel.cpp b/src/corelib/itemmodels/qstringlistmodel.cpp index 3cc0bee8ef..cc7a885641 100644 --- a/src/corelib/itemmodels/qstringlistmodel.cpp +++ b/src/corelib/itemmodels/qstringlistmodel.cpp @@ -230,6 +230,7 @@ bool QStringListModel::setData(const QModelIndex &index, const QVariant &value, #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) /*! \reimp + \since 6.0 */ bool QStringListModel::clearItemData(const QModelIndex &index) { diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 03dd1e63cd..1d8621ad5a 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -3076,7 +3076,7 @@ bool QByteArray::endsWith(const char *str) const return qstrncmp(d->data() + d->size - len, str, len) == 0; } -/*! +/* Returns true if \a c is an uppercase Latin1 letter. \note The multiplication sign 0xD7 and the sz ligature 0xDF are not treated as uppercase Latin1. @@ -3112,7 +3112,7 @@ bool QByteArray::isUpper() const return true; } -/*! +/* Returns true if \a c is an lowercase Latin1 letter. \note The division sign 0xF7 is not treated as lowercase Latin1, but the small y dieresis 0xFF is. From eb056ee233c80376a837beba8f712a0f1068dae3 Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Thu, 25 Oct 2018 18:18:57 +0200 Subject: [PATCH 0133/1650] Fix painter opacity being ignored when rendering to PDF The opacity set on a QPainter was being ignored for drawImage()/drawPixmap() calls when rendering to a PDF file through QPdfWriter/QPrinter. This change fixes it for PDF files v1.4 (default version) or v1.6. For PDF/A-1b files, opacity will remain ignored to ensure compliance with the specification. Task-number: QTBUG-70752 Change-Id: I4280e898698e0367dfb4c6ac2cd14ca2bf98850e Reviewed-by: Oliver Wolff Reviewed-by: Lars Knoll Reviewed-by: Friedemann Kleint --- src/gui/painting/qpdf.cpp | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index b410e9b900..e69726b617 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -953,7 +953,18 @@ void QPdfEngine::drawPixmap (const QRectF &rectangle, const QPixmap &pixmap, con if (object < 0) return; - *d->currentPage << "q\n/GSa gs\n"; + *d->currentPage << "q\n"; + + if ((d->pdfVersion != QPdfEngine::Version_A1b) && (d->opacity != 1.0)) { + int stateObject = d->addConstantAlphaObject(qRound(255 * d->opacity), qRound(255 * d->opacity)); + if (stateObject) + *d->currentPage << "/GState" << stateObject << "gs\n"; + else + *d->currentPage << "/GSa gs\n"; + } else { + *d->currentPage << "/GSa gs\n"; + } + *d->currentPage << QPdf::generateMatrix(QTransform(rectangle.width() / sr.width(), 0, 0, rectangle.height() / sr.height(), rectangle.x(), rectangle.y()) * (d->simplePen ? QTransform() : d->stroker.matrix)); @@ -981,7 +992,18 @@ void QPdfEngine::drawImage(const QRectF &rectangle, const QImage &image, const Q if (object < 0) return; - *d->currentPage << "q\n/GSa gs\n"; + *d->currentPage << "q\n"; + + if ((d->pdfVersion != QPdfEngine::Version_A1b) && (d->opacity != 1.0)) { + int stateObject = d->addConstantAlphaObject(qRound(255 * d->opacity), qRound(255 * d->opacity)); + if (stateObject) + *d->currentPage << "/GState" << stateObject << "gs\n"; + else + *d->currentPage << "/GSa gs\n"; + } else { + *d->currentPage << "/GSa gs\n"; + } + *d->currentPage << QPdf::generateMatrix(QTransform(rectangle.width() / sr.width(), 0, 0, rectangle.height() / sr.height(), rectangle.x(), rectangle.y()) * (d->simplePen ? QTransform() : d->stroker.matrix)); From b75babc6ae3f0fd48d6f09f1feab7b517d078cb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 22 Oct 2018 19:00:31 +0200 Subject: [PATCH 0134/1650] QGLWidget: Prevent premature platform window creation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Passing Qt::MSWindowsOwnDC along with the window flags to the QWidget constructor results in creating a native window as part of the base class initialization. By deferring the window creation to later in the QGLWidget construction, the meta object reflects the actual class. Change-Id: I51343c767057d6841331614b93ad860fe99d65e3 Reviewed-by: Simon Hausmann Reviewed-by: Tor Arne Vestbø --- src/opengl/qgl.cpp | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index e136ddcff2..666cc19bbe 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -3880,12 +3880,9 @@ void QGLContext::doneCurrent() */ QGLWidget::QGLWidget(QWidget *parent, const QGLWidget* shareWidget, Qt::WindowFlags f) - : QWidget(*(new QGLWidgetPrivate), parent, f | Qt::MSWindowsOwnDC) + : QWidget(*(new QGLWidgetPrivate), parent, f) { Q_D(QGLWidget); - setAttribute(Qt::WA_PaintOnScreen); - setAttribute(Qt::WA_NoSystemBackground); - setAutoFillBackground(true); // for compatibility d->init(new QGLContext(QGLFormat::defaultFormat(), this), shareWidget); } @@ -3893,12 +3890,9 @@ QGLWidget::QGLWidget(QWidget *parent, const QGLWidget* shareWidget, Qt::WindowFl \internal */ QGLWidget::QGLWidget(QGLWidgetPrivate &dd, const QGLFormat &format, QWidget *parent, const QGLWidget *shareWidget, Qt::WindowFlags f) - : QWidget(dd, parent, f | Qt::MSWindowsOwnDC) + : QWidget(dd, parent, f) { Q_D(QGLWidget); - setAttribute(Qt::WA_PaintOnScreen); - setAttribute(Qt::WA_NoSystemBackground); - setAutoFillBackground(true); // for compatibility d->init(new QGLContext(format, this), shareWidget); } @@ -3935,12 +3929,9 @@ QGLWidget::QGLWidget(QGLWidgetPrivate &dd, const QGLFormat &format, QWidget *par QGLWidget::QGLWidget(const QGLFormat &format, QWidget *parent, const QGLWidget* shareWidget, Qt::WindowFlags f) - : QWidget(*(new QGLWidgetPrivate), parent, f | Qt::MSWindowsOwnDC) + : QWidget(*(new QGLWidgetPrivate), parent, f) { Q_D(QGLWidget); - setAttribute(Qt::WA_PaintOnScreen); - setAttribute(Qt::WA_NoSystemBackground); - setAutoFillBackground(true); // for compatibility d->init(new QGLContext(format, this), shareWidget); } @@ -3971,12 +3962,9 @@ QGLWidget::QGLWidget(const QGLFormat &format, QWidget *parent, const QGLWidget* */ QGLWidget::QGLWidget(QGLContext *context, QWidget *parent, const QGLWidget *shareWidget, Qt::WindowFlags f) - : QWidget(*(new QGLWidgetPrivate), parent, f | Qt::MSWindowsOwnDC) + : QWidget(*(new QGLWidgetPrivate), parent, f) { Q_D(QGLWidget); - setAttribute(Qt::WA_PaintOnScreen); - setAttribute(Qt::WA_NoSystemBackground); - setAutoFillBackground(true); // for compatibility d->init(context, shareWidget); } @@ -5169,6 +5157,15 @@ QPaintEngine *QGLWidget::paintEngine() const void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget *shareWidget) { + Q_Q(QGLWidget); + q->setAttribute(Qt::WA_PaintOnScreen); + q->setAttribute(Qt::WA_NoSystemBackground); + q->setAutoFillBackground(true); // for compatibility + + mustHaveWindowHandle = 1; + q->setAttribute(Qt::WA_NativeWindow); + q->setWindowFlag(Qt::MSWindowsOwnDC); + initContext(context, shareWidget); } From 102a919b734440df85617f1e3a8ba43c612839d5 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Mon, 29 Oct 2018 18:32:04 +0100 Subject: [PATCH 0135/1650] Generate documentation .tags files for all of the docs This allows others to link to QtDBus and the other libraries/tools using doxygen. Fixes: QTBUG-60933 Change-Id: I026895a432a328f224c40cf231ad12d109dc648f Reviewed-by: Paul Wicking Reviewed-by: Venugopal Shivashankar Reviewed-by: Martin Smith --- qmake/doc/qmake.qdocconf | 2 ++ src/dbus/doc/qtdbus.qdocconf | 2 ++ src/opengl/doc/qtopengl.qdocconf | 2 ++ src/platformheaders/doc/qtplatformheaders.qdocconf | 2 ++ 4 files changed, 8 insertions(+) diff --git a/qmake/doc/qmake.qdocconf b/qmake/doc/qmake.qdocconf index 3493a697f4..cf8f911372 100644 --- a/qmake/doc/qmake.qdocconf +++ b/qmake/doc/qmake.qdocconf @@ -25,6 +25,8 @@ sources = src/qmake-manual.qdoc imagedirs = images exampledirs = snippets +tagfile = qmake.tags + depends += \ activeqt \ qt3d \ diff --git a/src/dbus/doc/qtdbus.qdocconf b/src/dbus/doc/qtdbus.qdocconf index 69eaa0eec3..4ff7242b25 100644 --- a/src/dbus/doc/qtdbus.qdocconf +++ b/src/dbus/doc/qtdbus.qdocconf @@ -21,6 +21,8 @@ excludedirs += ../../../examples/widgets/doc examplesinstallpath = dbus +tagfile = qtdbus.tags + depends += qtdoc qtcore # The following parameters are for creating a qhp file, the qhelpgenerator diff --git a/src/opengl/doc/qtopengl.qdocconf b/src/opengl/doc/qtopengl.qdocconf index 6ff6cae2cb..2d38a5d2af 100644 --- a/src/opengl/doc/qtopengl.qdocconf +++ b/src/opengl/doc/qtopengl.qdocconf @@ -23,6 +23,8 @@ depends += qtdoc qtcore qtgui qtwidgets qmake examplesinstallpath = opengl +tagfile = qtopengl.tags + # The following parameters are for creating a qhp file, the qhelpgenerator # program can convert the qhp file into a qch file which can be opened in # Qt Assistant and/or Qt Creator. diff --git a/src/platformheaders/doc/qtplatformheaders.qdocconf b/src/platformheaders/doc/qtplatformheaders.qdocconf index 1ff6fe7a21..9a034e7671 100644 --- a/src/platformheaders/doc/qtplatformheaders.qdocconf +++ b/src/platformheaders/doc/qtplatformheaders.qdocconf @@ -35,5 +35,7 @@ sourcedirs += .. exampledirs += snippets imagedirs += images +tagfile = qtplatformheaders.tags + navigation.landingpage = "Qt Platform Headers" navigation.cppclassespage = "Qt Platform Headers C++ Classes" From c4a93281a75b50c1b8c9a5fe0007bd44509100e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Fri, 5 Oct 2018 09:27:38 +0200 Subject: [PATCH 0136/1650] Add change log about source incompatibility in moc output "Use std::addressof for taking an address instead of operator& in moc" (5b99f3a34fef527beb8767eb12657f81ee65b969) introduced a dependency to std memory header. That change exposed code that was including the moc output from within a namespace. That was never supported nor valid, but it used to compile. The problem was not detected earlier because both other includes where already included to support QObject itself and therefore inside the moc output their header guards were disabling their content. Task-number: QTBUG-68191 Task-number: QTBUG-70907 Change-Id: I18462ed17d748a114fe2e5b6bf9aeb56ee26e2db Reviewed-by: Frederik Gladhorn Reviewed-by: Timur Pocheptsov Reviewed-by: Edward Welbourne Reviewed-by: Thiago Macieira --- dist/changes-5.13.0 | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 dist/changes-5.13.0 diff --git a/dist/changes-5.13.0 b/dist/changes-5.13.0 new file mode 100644 index 0000000000..c6db991931 --- /dev/null +++ b/dist/changes-5.13.0 @@ -0,0 +1,7 @@ +**************************************************************************** +* Important Source Incompatible Changes * +**************************************************************************** + + - Moc generated files include the standard header file now. + A side effect of this is that code including the Moc output from within + a namespace will fail to compile. From 22788194f93eeec53cd82380a5e0448579ea0930 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Mon, 24 Sep 2018 20:11:46 +0200 Subject: [PATCH 0137/1650] Gui: Q_GADGET is missing in qlayoutpolicy_p.h Change-Id: I1244c507da7e4afeb16093112f52b191fd16fb0d Reviewed-by: Simon Hausmann --- src/gui/util/qlayoutpolicy_p.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/util/qlayoutpolicy_p.h b/src/gui/util/qlayoutpolicy_p.h index a729a57e8b..993bf71472 100644 --- a/src/gui/util/qlayoutpolicy_p.h +++ b/src/gui/util/qlayoutpolicy_p.h @@ -66,6 +66,7 @@ class QVariant; class Q_GUI_EXPORT QLayoutPolicy { + Q_GADGET Q_ENUMS(Policy) public: From 0330b967f20bc265b9799418ce8e0b6faf929a62 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 29 Oct 2018 12:21:38 +0100 Subject: [PATCH 0138/1650] Simplify the Q_FOREACH macro when using C++17 This way there is only one for loop, which is more optimizer friendly Change-Id: Iaa02026627d5259c3eea1ff5664e8f22664eef73 Reviewed-by: Thiago Macieira --- src/corelib/global/qglobal.h | 11 ++++- tests/auto/corelib/global/qglobal/qglobal.pro | 1 + .../corelib/global/qglobal/tst_qglobal.cpp | 40 +++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index f56629faa1..8680742c94 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1005,6 +1005,15 @@ QForeachContainer::type> qMakeForeachContainer(T &&t) } } + +#if __cplusplus >= 201703L +// Use C++17 if statement with initializer. User's code ends up in a else so +// scoping of different ifs is not broken +#define Q_FOREACH(variable, container) \ +for (auto _container_ = QtPrivate::qMakeForeachContainer(container); \ + _container_.i != _container_.e; ++_container_.i) \ + if (variable = *_container_.i; false) {} else +#else // Explanation of the control word: // - it's initialized to 1 // - that means both the inner and outer loops start @@ -1019,7 +1028,7 @@ for (auto _container_ = QtPrivate::qMakeForeachContainer(container); \ _container_.control && _container_.i != _container_.e; \ ++_container_.i, _container_.control ^= 1) \ for (variable = *_container_.i; _container_.control; _container_.control = 0) - +#endif #endif // QT_NO_FOREACH #define Q_FOREVER for(;;) diff --git a/tests/auto/corelib/global/qglobal/qglobal.pro b/tests/auto/corelib/global/qglobal/qglobal.pro index a40cb9a288..b105769430 100644 --- a/tests/auto/corelib/global/qglobal/qglobal.pro +++ b/tests/auto/corelib/global/qglobal/qglobal.pro @@ -2,3 +2,4 @@ CONFIG += testcase TARGET = tst_qglobal QT = core testlib SOURCES = tst_qglobal.cpp qglobal.c +contains(QT_CONFIG, c++1z): CONFIG += c++1z diff --git a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp index 78b954f373..56da047147 100644 --- a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp +++ b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp @@ -126,6 +126,46 @@ void tst_QGlobal::for_each() QCOMPARE(i, counter++); } QCOMPARE(counter, list.count()); + + // Should also work with an existing variable + int local; + counter = 0; + foreach (local, list) { + QCOMPARE(local, counter++); + } + QCOMPARE(counter, list.count()); + QCOMPARE(local, counter - 1); + + // Test the macro does not mess if/else conditions + counter = 0; + if (true) + foreach (int i, list) + QCOMPARE(i, counter++); + else + QFAIL("If/Else mismatch"); + QCOMPARE(counter, list.count()); + + counter = 0; + if (false) + foreach (int i, list) + if (i) QFAIL("If/Else mismatch"); + else QFAIL("If/Else mismatch"); + else + foreach (int i, list) + if (false) { } + else QCOMPARE(i, counter++); + QCOMPARE(counter, list.count()); + + // break and continue + counter = 0; + foreach (int i, list) { + if (i == 0) + continue; + QCOMPARE(i, (counter++) + 1); + if (i == 3) + break; + } + QCOMPARE(counter, 3); } void tst_QGlobal::qassert() From aa0e3d02d5a6a646594b04c753ebc1655e44a141 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Thu, 25 Oct 2018 13:21:44 +0200 Subject: [PATCH 0139/1650] winrt: Use SwitchToThread instead of Sleep(0) UWP also supports SwitchToThread. The usage of Sleep(0) was a leftover that was forgotten when porting to desktop Window's approach of handling threads. Change-Id: I5e3d6fb3eefe07407b910cc6a6b45781d320e151 Reviewed-by: Friedemann Kleint Reviewed-by: Simon Hausmann Reviewed-by: Thiago Macieira --- src/corelib/thread/qthread_win.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp index e04d27d7b6..e56fe2c6ae 100644 --- a/src/corelib/thread/qthread_win.cpp +++ b/src/corelib/thread/qthread_win.cpp @@ -465,11 +465,7 @@ int QThread::idealThreadCount() Q_DECL_NOTHROW void QThread::yieldCurrentThread() { -#if !defined(Q_OS_WINRT) SwitchToThread(); -#else - ::Sleep(0); -#endif } #endif // QT_CONFIG(thread) From 7e7514482fb2086fda100439a34b5b4ef627d329 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Thu, 25 Oct 2018 15:28:40 +0200 Subject: [PATCH 0140/1650] winrt: Skip a test row of tst_QRegularExpression::threadSafety PCRE2 does not support JIT on winrt. This test row takes a long time (30 seconds here) without JIT and thus might cause test timeouts in COIN when run on winrt. Change-Id: I79d9f6be16dbe16594ae2bf51f353acd06b3d2fe Reviewed-by: Simon Hausmann --- .../tools/qregularexpression/tst_qregularexpression.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp b/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp index f520e9742a..18098f16bf 100644 --- a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp +++ b/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp @@ -2108,12 +2108,16 @@ void tst_QRegularExpression::threadSafety_data() QTest::addRow("pattern%d", ++i) << "ab.*cd" << subject; } + // pcre2 does not support JIT for winrt. As this test row takes a long time without JIT we skip + // it for winrt as it might time out in COIN. +#ifndef Q_OS_WINRT { QString subject = "ab"; subject.append(QString(512*1024, QLatin1Char('x'))); subject.append("c"); QTest::addRow("pattern%d", ++i) << "ab.*cd" << subject; } +#endif // Q_OS_WINRT { QString subject = "ab"; From 7f54ea714ed62f3b4fb88dedbee9357bf6a26d26 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 23 Oct 2018 11:15:00 +0200 Subject: [PATCH 0141/1650] QtCore/Windows: Add pointer messages to the debug operator for MSG Task-number: QTBUG-71257 Change-Id: I53a4cee7b84b4075342cc016bb3382f473c27788 Reviewed-by: Andre de la Rocha --- src/corelib/kernel/qcoreapplication_win.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp index 0109e2c658..0c57ad34b9 100644 --- a/src/corelib/kernel/qcoreapplication_win.cpp +++ b/src/corelib/kernel/qcoreapplication_win.cpp @@ -417,6 +417,23 @@ static const char *findWMstr(uint msg) { 0x0232, "WM_EXITSIZEMOVE" }, { 0x0233, "WM_DROPFILES" }, { 0x0234, "WM_MDIREFRESHMENU" }, + { 0x0241, "WM_NCPOINTERUPDATE"}, + { 0x0242, "WM_NCPOINTERDOWN"}, + { 0x0243, "WM_NCPOINTERUP"}, + { 0x0245, "WM_POINTERUPDATE"}, + { 0x0246, "WM_POINTERDOWN"}, + { 0x0247, "WM_POINTERUP"}, + { 0x0249, "WM_POINTERENTER"}, + { 0x024A, "WM_POINTERLEAVE"}, + { 0x0248, "WM_POINTERACTIVATE"}, + { 0x024C, "WM_POINTERCAPTURECHANGED"}, + { 0x024D, "WM_TOUCHHITTESTING"}, + { 0x024E, "WM_POINTERWHEEL"}, + { 0x024F, "WM_POINTERHWHEEL"}, + { 0x0250, "DM_POINTERHITTEST"}, + { 0x0251, "WM_POINTERROUTEDTO"}, + { 0x0252, "WM_POINTERROUTEDAWAY"}, + { 0x0253, "WM_POINTERROUTEDRELEASED"}, { 0x0281, "WM_IME_SETCONTEXT" }, { 0x0282, "WM_IME_NOTIFY" }, { 0x0283, "WM_IME_CONTROL" }, From 497f43c90f7160c1b198d829eab21c8c010fc7f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCri=20Valdmann?= Date: Wed, 24 Oct 2018 12:46:04 +0200 Subject: [PATCH 0142/1650] tst_QCborValue: Disable support for spaceship operator Spaceship operator was disabled for QCborValue, but not the test. Change-Id: Icb91da689f62ef6de9f4fa926346505c5e50e9eb Reviewed-by: Thiago Macieira --- tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp index 38b26e7de4..4b753eab6b 100644 --- a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp +++ b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp @@ -330,7 +330,7 @@ void tst_QCborValue::copyCompare() QCOMPARE(v, other); QVERIFY(!(v != other)); QVERIFY(!(v < other)); -#if QT_HAS_INCLUDE() +#if 0 && QT_HAS_INCLUDE() QVERIFY(v <= other); QVERIFY(v >= other); QVERIFY(!(v > other)); From 4c37b64411f60d2667963db8e7d42459cad663e6 Mon Sep 17 00:00:00 2001 From: Jan Grulich Date: Thu, 18 Oct 2018 10:02:48 +0200 Subject: [PATCH 0143/1650] Add terminating character when sending byte arrays in FileChooser portal Terminating character is needed for gtk portal backend, which is not able to contruct a string without it and thus not able to pre-select a file or a directory in file dialog. Change-Id: I5b40fb1ce584936fc92e93f38dc8559890852d99 Reviewed-by: Thiago Macieira --- .../xdgdesktopportal/qxdgdesktopportalfiledialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp index cda267d24b..5e94d1558e 100644 --- a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp +++ b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp @@ -181,10 +181,10 @@ void QXdgDesktopPortalFileDialog::openPortal() if (d->saveFile) { if (!d->directory.isEmpty()) - options.insert(QLatin1String("current_folder"), d->directory.toLatin1()); + options.insert(QLatin1String("current_folder"), d->directory.toLatin1().append('\0')); if (!d->selectedFiles.isEmpty()) - options.insert(QLatin1String("current_file"), d->selectedFiles.first().toLatin1()); + options.insert(QLatin1String("current_file"), d->selectedFiles.first().toLatin1().append('\0')); } // Insert filters From a952fd7d5b03ce1968ec58871fbb8b3600895900 Mon Sep 17 00:00:00 2001 From: Kari Oikarinen Date: Wed, 26 Sep 2018 10:29:14 +0300 Subject: [PATCH 0144/1650] QObject: Fix isSignalConnected() when signals have been disconnected MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bitmap cache for the first 64 signals being connected was only set when the connection is added. It was never unset when the connection was removed. Internal use of the connectedSignals bitmap is not hurt by it occasionally saying a signal is connected even though it is not, since the purpose of those checks is avoiding expensive operations that are not necessary if nothing is connected to the signal. However, the public API using this cache meant that it also never spotted signals being disconnected. This was not documented. Fix the behavior by only using the cache if it is up to date. If it is not, use a slower path that gives the correct answer. To avoid making disconnections and QObject destructions slower, the cache is only updated to unset disconnected signals when new signal connections are added. No extra work is done in the common case where signals are only removed in the end of the QObject's lifetime. Fixes: QTBUG-32340 Change-Id: Ieb6e498060157153cec60d9c8f1c33056993fda1 Reviewed-by: Ville Voutilainen Reviewed-by: Thiago Macieira Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Jędrzej Nowacki --- src/corelib/kernel/qobject.cpp | 34 ++++++++---- .../corelib/kernel/qobject/tst_qobject.cpp | 53 +++++++++++++++++++ 2 files changed, 76 insertions(+), 11 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 07208b7f40..deab51cfd0 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -421,6 +421,7 @@ void QObjectPrivate::cleanConnectionLists() { if (connectionLists->dirty && !connectionLists->inUse) { // remove broken connections + bool allConnected = false; for (int signal = -1; signal < connectionLists->count(); ++signal) { QObjectPrivate::ConnectionList &connectionList = (*connectionLists)[signal]; @@ -432,11 +433,13 @@ void QObjectPrivate::cleanConnectionLists() QObjectPrivate::Connection **prev = &connectionList.first; QObjectPrivate::Connection *c = *prev; + bool connected = false; // whether the signal is still connected somewhere while (c) { if (c->receiver) { last = c; prev = &c->nextConnectionList; c = *prev; + connected = true; } else { QObjectPrivate::Connection *next = c->nextConnectionList; *prev = next; @@ -448,6 +451,14 @@ void QObjectPrivate::cleanConnectionLists() // Correct the connection list's last pointer. // As conectionList.last could equal last, this could be a noop connectionList.last = last; + + if (!allConnected && !connected && signal >= 0 + && size_t(signal) < sizeof(connectedSignals) * 8) { + // This signal is no longer connected + connectedSignals[signal >> 5] &= ~(1 << (signal & 0x1f)); + } else if (signal == -1) { + allConnected = connected; + } } connectionLists->dirty = false; } @@ -2501,19 +2512,20 @@ bool QObject::isSignalConnected(const QMetaMethod &signal) const signalIndex += QMetaObjectPrivate::signalOffset(signal.mobj); - if (signalIndex < sizeof(d->connectedSignals) * 8) + QMutexLocker locker(signalSlotLock(this)); + if (!d->connectionLists) + return false; + + if (signalIndex < sizeof(d->connectedSignals) * 8 && !d->connectionLists->dirty) return d->isSignalConnected(signalIndex); - QMutexLocker locker(signalSlotLock(this)); - if (d->connectionLists) { - if (signalIndex < uint(d->connectionLists->count())) { - const QObjectPrivate::Connection *c = - d->connectionLists->at(signalIndex).first; - while (c) { - if (c->receiver) - return true; - c = c->nextConnectionList; - } + if (signalIndex < uint(d->connectionLists->count())) { + const QObjectPrivate::Connection *c = + d->connectionLists->at(signalIndex).first; + while (c) { + if (c->receiver) + return true; + c = c->nextConnectionList; } } return false; diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 68c6ece583..effc82261b 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -103,6 +103,7 @@ private slots: void deleteQObjectWhenDeletingEvent(); void overloads(); void isSignalConnected(); + void isSignalConnectedAfterDisconnection(); void qMetaObjectConnect(); void qMetaObjectDisconnectOne(); void sameName(); @@ -3835,6 +3836,58 @@ void tst_QObject::isSignalConnected() QVERIFY(!o.isSignalConnected(QMetaMethod())); } +void tst_QObject::isSignalConnectedAfterDisconnection() +{ + ManySignals o; + const QMetaObject *meta = o.metaObject(); + + const QMetaMethod sig00 = meta->method(meta->indexOfSignal("sig00()")); + QVERIFY(!o.isSignalConnected(sig00)); + QObject::connect(&o, &ManySignals::sig00, qt_noop); + QVERIFY(o.isSignalConnected(sig00)); + QVERIFY(QObject::disconnect(&o, &ManySignals::sig00, 0, 0)); + QVERIFY(!o.isSignalConnected(sig00)); + + const QMetaMethod sig69 = meta->method(meta->indexOfSignal("sig69()")); + QVERIFY(!o.isSignalConnected(sig69)); + QObject::connect(&o, &ManySignals::sig69, qt_noop); + QVERIFY(o.isSignalConnected(sig69)); + QVERIFY(QObject::disconnect(&o, &ManySignals::sig69, 0, 0)); + QVERIFY(!o.isSignalConnected(sig69)); + + { + ManySignals o2; + QObject::connect(&o, &ManySignals::sig00, &o2, &ManySignals::sig00); + QVERIFY(o.isSignalConnected(sig00)); + // o2 is destructed + } + QVERIFY(!o.isSignalConnected(sig00)); + + const QMetaMethod sig01 = meta->method(meta->indexOfSignal("sig01()")); + QObject::connect(&o, &ManySignals::sig00, qt_noop); + QObject::connect(&o, &ManySignals::sig01, qt_noop); + QObject::connect(&o, &ManySignals::sig69, qt_noop); + QVERIFY(o.isSignalConnected(sig00)); + QVERIFY(o.isSignalConnected(sig01)); + QVERIFY(o.isSignalConnected(sig69)); + QVERIFY(QObject::disconnect(&o, &ManySignals::sig69, 0, 0)); + QVERIFY(o.isSignalConnected(sig00)); + QVERIFY(o.isSignalConnected(sig01)); + QVERIFY(!o.isSignalConnected(sig69)); + QVERIFY(QObject::disconnect(&o, &ManySignals::sig00, 0, 0)); + QVERIFY(!o.isSignalConnected(sig00)); + QVERIFY(o.isSignalConnected(sig01)); + QVERIFY(!o.isSignalConnected(sig69)); + QObject::connect(&o, &ManySignals::sig69, qt_noop); + QVERIFY(!o.isSignalConnected(sig00)); + QVERIFY(o.isSignalConnected(sig01)); + QVERIFY(o.isSignalConnected(sig69)); + QVERIFY(QObject::disconnect(&o, &ManySignals::sig01, 0, 0)); + QVERIFY(!o.isSignalConnected(sig00)); + QVERIFY(!o.isSignalConnected(sig01)); + QVERIFY(o.isSignalConnected(sig69)); +} + void tst_QObject::qMetaObjectConnect() { SenderObject *s = new SenderObject; From deee147acaf1009eca439b0e959025971aab0c90 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 29 Oct 2018 10:55:36 +0100 Subject: [PATCH 0145/1650] Fix doc Change-Id: I75386b948763bbe784fc36abe7e69696bc04219d Reviewed-by: Leena Miettinen --- src/gui/painting/qrgba64.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qrgba64.qdoc b/src/gui/painting/qrgba64.qdoc index 26c78a5dcd..3ee8a355e6 100644 --- a/src/gui/painting/qrgba64.qdoc +++ b/src/gui/painting/qrgba64.qdoc @@ -35,7 +35,7 @@ QRgba64 is a 64-bit data-structure containing four 16-bit color channels: Red, green, blue and alpha. - QRgba64 can be used a replacement for QRgb when higher precision is needed. In particular a + QRgba64 can be used as a replacement for QRgb when higher precision is needed. In particular a premultiplied QRgba64 can operate on unpremultiplied QRgb without loss of precision except for alpha 0. From f25c68646226fe19e98887ad43a7e12e0d87734b Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Fri, 26 Oct 2018 15:56:39 +0200 Subject: [PATCH 0146/1650] xcb: remove leftover function It was forgotten in 4050ee6ac7da0e5e7414c699c3cd4e26193c653d Change-Id: Icace56161b8ae372dba105f82da0d1c1b69542c1 Reviewed-by: Gatis Paeglis --- src/plugins/platforms/xcb/qxcbwindow.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 6667f45343..d2ca9fe0b9 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -207,7 +207,6 @@ protected: void setTransparentForMouseEvents(bool transparent); void updateDoesNotAcceptFocus(bool doesNotAcceptFocus); - QRect windowToWmGeometry(QRect r) const; void sendXEmbedMessage(xcb_window_t window, quint32 message, quint32 detail = 0, quint32 data1 = 0, quint32 data2 = 0); void handleXEmbedMessage(const xcb_client_message_event_t *event); From f5c0a19077989b5ac14071ecd095e29f62d05602 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Wed, 17 Oct 2018 17:28:55 +0200 Subject: [PATCH 0147/1650] xcb: move clipboard code out of QXcbConnection::processXcbEvents ... to QXcbConnection::handleXcbEvent(), which is where it belongs. This patch amends bc6f5b3ff61f4b1dea14084349702f2895feda66 (Sep, 2013). And some other design cleanups. Change-Id: Iefa0793c58de16a59d2294f38311e1e8dfa3035b Reviewed-by: Allan Sandfeld Jensen --- src/plugins/platforms/xcb/qxcbclipboard.cpp | 196 ++++++++----------- src/plugins/platforms/xcb/qxcbclipboard.h | 41 +++- src/plugins/platforms/xcb/qxcbconnection.cpp | 13 +- src/plugins/platforms/xcb/qxcbconnection.h | 1 + 4 files changed, 121 insertions(+), 130 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp index 3fd14a659e..9c7559d514 100644 --- a/src/plugins/platforms/xcb/qxcbclipboard.cpp +++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp @@ -153,114 +153,71 @@ private: QByteArray format_atoms; }; -namespace { -class INCRTransaction; -typedef QMap TransactionMap; -static TransactionMap *transactions = 0; - -//#define INCR_DEBUG - -class INCRTransaction : public QObject +QXcbClipboardTransaction::QXcbClipboardTransaction(QXcbClipboard *clipboard, xcb_window_t w, + xcb_atom_t p, QByteArray d, xcb_atom_t t, int f) + : m_clipboard(clipboard), m_window(w), m_property(p), m_data(d), m_target(t), m_format(f) { - Q_OBJECT -public: - INCRTransaction(QXcbConnection *c, xcb_window_t w, xcb_atom_t p, - QByteArray d, uint i, xcb_atom_t t, int f, int to) : - conn(c), win(w), property(p), data(d), increment(i), - target(t), format(f), timeout(to), offset(0) - { - const quint32 values[] = { XCB_EVENT_MASK_PROPERTY_CHANGE }; - xcb_change_window_attributes(conn->xcb_connection(), win, + const quint32 values[] = { XCB_EVENT_MASK_PROPERTY_CHANGE }; + xcb_change_window_attributes(m_clipboard->xcb_connection(), m_window, + XCB_CW_EVENT_MASK, values); + + m_abortTimerId = startTimer(m_clipboard->clipboardTimeout()); +} + +QXcbClipboardTransaction::~QXcbClipboardTransaction() +{ + if (m_abortTimerId) + killTimer(m_abortTimerId); + m_abortTimerId = 0; + m_clipboard->removeTransaction(m_window); +} + +bool QXcbClipboardTransaction::updateIncrementalProperty(const xcb_property_notify_event_t *event) +{ + if (event->atom != m_property || event->state != XCB_PROPERTY_DELETE) + return false; + + // restart the timer + if (m_abortTimerId) + killTimer(m_abortTimerId); + m_abortTimerId = startTimer(m_clipboard->clipboardTimeout()); + + uint bytes_left = uint(m_data.size()) - m_offset; + if (bytes_left > 0) { + int increment = m_clipboard->increment(); + uint bytes_to_send = qMin(uint(increment), bytes_left); + + qCDebug(lcQpaClipboard, "sending %d bytes, %d remaining, transaction: %p)", + bytes_to_send, bytes_left - bytes_to_send, this); + + uint32_t dataSize = bytes_to_send / (m_format / 8); + xcb_change_property(m_clipboard->xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, + m_property, m_target, m_format, dataSize, m_data.constData() + m_offset); + m_offset += bytes_to_send; + } else { + qCDebug(lcQpaClipboard, "transaction %p completed", this); + + xcb_change_property(m_clipboard->xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, + m_property, m_target, m_format, 0, nullptr); + + const quint32 values[] = { XCB_EVENT_MASK_NO_EVENT }; + xcb_change_window_attributes(m_clipboard->xcb_connection(), m_window, XCB_CW_EVENT_MASK, values); - if (!transactions) { -#ifdef INCR_DEBUG - qDebug("INCRTransaction: creating the TransactionMap"); -#endif - transactions = new TransactionMap; - conn->clipboard()->setProcessIncr(true); - } - transactions->insert(win, this); - abort_timer = startTimer(timeout); + delete this; // self destroy } + return true; +} - ~INCRTransaction() - { - if (abort_timer) - killTimer(abort_timer); - abort_timer = 0; - transactions->remove(win); - if (transactions->isEmpty()) { -#ifdef INCR_DEBUG - qDebug("INCRTransaction: no more INCR transactions left in the TransactionMap"); -#endif - delete transactions; - transactions = 0; - conn->clipboard()->setProcessIncr(false); - } + +void QXcbClipboardTransaction::timerEvent(QTimerEvent *ev) +{ + if (ev->timerId() == m_abortTimerId) { + // this can happen when the X client we are sending data + // to decides to exit (normally or abnormally) + qCDebug(lcQpaClipboard, "timed out while sending data to %p", this); + delete this; // self destroy } - - void updateIncrProperty(xcb_property_notify_event_t *event, bool &accepted) - { - xcb_connection_t *c = conn->xcb_connection(); - if (event->atom == property && event->state == XCB_PROPERTY_DELETE) { - accepted = true; - // restart the timer - if (abort_timer) - killTimer(abort_timer); - abort_timer = startTimer(timeout); - - unsigned int bytes_left = data.size() - offset; - if (bytes_left > 0) { - unsigned int bytes_to_send = qMin(increment, bytes_left); -#ifdef INCR_DEBUG - qDebug("INCRTransaction: sending %d bytes, %d remaining (INCR transaction %p)", - bytes_to_send, bytes_left - bytes_to_send, this); -#endif - int dataSize = bytes_to_send / (format / 8); - xcb_change_property(c, XCB_PROP_MODE_REPLACE, win, property, - target, format, dataSize, data.constData() + offset); - offset += bytes_to_send; - } else { -#ifdef INCR_DEBUG - qDebug("INCRTransaction: INCR transaction %p completed", this); -#endif - xcb_change_property(c, XCB_PROP_MODE_REPLACE, win, property, - target, format, 0, (const void *)0); - const quint32 values[] = { XCB_EVENT_MASK_NO_EVENT }; - xcb_change_window_attributes(conn->xcb_connection(), win, - XCB_CW_EVENT_MASK, values); - // self destroy - delete this; - } - } - } - -protected: - void timerEvent(QTimerEvent *ev) override - { - if (ev->timerId() == abort_timer) { - // this can happen when the X client we are sending data - // to decides to exit (normally or abnormally) -#ifdef INCR_DEBUG - qDebug("INCRTransaction: Timed out while sending data to %p", this); -#endif - delete this; - } - } - -private: - QXcbConnection *conn; - xcb_window_t win; - xcb_atom_t property; - QByteArray data; - uint increment; - xcb_atom_t target; - int format; - int timeout; - uint offset; - int abort_timer; -}; -} // unnamed namespace +} const int QXcbClipboard::clipboard_timeout = 5000; @@ -282,6 +239,9 @@ QXcbClipboard::QXcbClipboard(QXcbConnection *c) xcb_xfixes_select_selection_input_checked(xcb_connection(), m_owner, XCB_ATOM_PRIMARY, mask); xcb_xfixes_select_selection_input_checked(xcb_connection(), m_owner, atom(QXcbAtom::CLIPBOARD), mask); } + + // change property protocol request is 24 bytes + m_increment = (xcb_get_maximum_request_length(xcb_connection()) * 4) - 24; } QXcbClipboard::~QXcbClipboard() @@ -313,16 +273,17 @@ QXcbClipboard::~QXcbClipboard() delete m_clientClipboard[QClipboard::Selection]; } -void QXcbClipboard::incrTransactionPeeker(xcb_generic_event_t *ge, bool &accepted) +bool QXcbClipboard::handlePropertyNotify(const xcb_generic_event_t *event) { - uint response_type = ge->response_type & ~0x80; - if (response_type == XCB_PROPERTY_NOTIFY) { - xcb_property_notify_event_t *event = (xcb_property_notify_event_t *)ge; - TransactionMap::Iterator it = transactions->find(event->window); - if (it != transactions->end()) { - (*it)->updateIncrProperty(event, accepted); - } - } + if (m_transactions.isEmpty() || event->response_type != XCB_PROPERTY_NOTIFY) + return false; + + auto propertyNotify = reinterpret_cast(event); + TransactionMap::Iterator it = m_transactions.find(propertyNotify->window); + if (it == m_transactions.constEnd()) + return false; + + return (*it)->updateIncrementalProperty(propertyNotify); } xcb_window_t QXcbClipboard::getSelectionOwner(xcb_atom_t atom) const @@ -522,19 +483,18 @@ xcb_atom_t QXcbClipboard::sendSelection(QMimeData *d, xcb_atom_t target, xcb_win // This 'bool' can be removed once there is a proper fix for QTBUG-32853 if (m_clipboard_closing) allow_incr = false; - // X_ChangeProperty protocol request is 24 bytes - const int increment = (xcb_get_maximum_request_length(xcb_connection()) * 4) - 24; - if (data.size() > increment && allow_incr) { + + if (data.size() > m_increment && allow_incr) { long bytes = data.size(); xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, window, property, atom(QXcbAtom::INCR), 32, 1, (const void *)&bytes); - new INCRTransaction(connection(), window, property, data, increment, - atomFormat, dataFormat, clipboard_timeout); + auto transaction = new QXcbClipboardTransaction(this, window, property, data, atomFormat, dataFormat); + m_transactions.insert(window, transaction); return property; } // make sure we can perform the XChangeProperty in a single request - if (data.size() > increment) + if (data.size() > m_increment) return XCB_NONE; // ### perhaps use several XChangeProperty calls w/ PropModeAppend? int dataSize = data.size() / (dataFormat / 8); // use a single request to transfer data diff --git a/src/plugins/platforms/xcb/qxcbclipboard.h b/src/plugins/platforms/xcb/qxcbclipboard.h index abab42a613..26d3b3b395 100644 --- a/src/plugins/platforms/xcb/qxcbclipboard.h +++ b/src/plugins/platforms/xcb/qxcbclipboard.h @@ -45,14 +45,41 @@ #include #include +#include + QT_BEGIN_NAMESPACE #ifndef QT_NO_CLIPBOARD class QXcbConnection; class QXcbScreen; +class QXcbClipboard; class QXcbClipboardMime; +class QXcbClipboardTransaction : public QObject +{ + Q_OBJECT +public: + QXcbClipboardTransaction(QXcbClipboard *clipboard, xcb_window_t w, xcb_atom_t p, + QByteArray d, xcb_atom_t t, int f); + ~QXcbClipboardTransaction(); + + bool updateIncrementalProperty(const xcb_property_notify_event_t *event); + +protected: + void timerEvent(QTimerEvent *ev) override; + +private: + QXcbClipboard *m_clipboard; + xcb_window_t m_window; + xcb_atom_t m_property; + QByteArray m_data; + xcb_atom_t m_target; + uint8_t m_format; + uint m_offset = 0; + int m_abortTimerId = 0; +}; + class QXcbClipboard : public QXcbObject, public QPlatformClipboard { public: @@ -81,13 +108,16 @@ public: QByteArray getDataInFormat(xcb_atom_t modeAtom, xcb_atom_t fmtatom); - void setProcessIncr(bool process) { m_incr_active = process; } - bool processIncr() { return m_incr_active; } - void incrTransactionPeeker(xcb_generic_event_t *ge, bool &accepted); + bool handlePropertyNotify(const xcb_generic_event_t *event); xcb_window_t getSelectionOwner(xcb_atom_t atom) const; QByteArray getSelection(xcb_atom_t selection, xcb_atom_t target, xcb_atom_t property, xcb_timestamp_t t = 0); + int increment() const { return m_increment; } + int clipboardTimeout() const { return clipboard_timeout; } + + void removeTransaction(xcb_window_t window) { m_transactions.remove(window); } + private: xcb_generic_event_t *waitForClipboardEvent(xcb_window_t window, int type, bool checkManager = false); @@ -107,9 +137,12 @@ private: static const int clipboard_timeout; - bool m_incr_active = false; + int m_increment = 0; bool m_clipboard_closing = false; xcb_timestamp_t m_incr_receive_time = 0; + + using TransactionMap = QMap; + TransactionMap m_transactions; }; #endif // QT_NO_CLIPBOARD diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 45f096a13a..37ee980924 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -84,6 +84,7 @@ Q_LOGGING_CATEGORY(lcQpaEvents, "qt.qpa.events") Q_LOGGING_CATEGORY(lcQpaEventReader, "qt.qpa.events.reader") Q_LOGGING_CATEGORY(lcQpaPeeker, "qt.qpa.peeker") Q_LOGGING_CATEGORY(lcQpaKeyboard, "qt.qpa.xkeyboard") +Q_LOGGING_CATEGORY(lcQpaClipboard, "qt.qpa.clipboard") Q_LOGGING_CATEGORY(lcQpaXDnd, "qt.qpa.xdnd") // this event type was added in libxcb 1.10, @@ -651,6 +652,10 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) break; case XCB_PROPERTY_NOTIFY: { +#ifndef QT_NO_CLIPBOARD + if (m_clipboard->handlePropertyNotify(event)) + break; +#endif auto propertyNotify = reinterpret_cast(event); if (propertyNotify->atom == atom(QXcbAtom::_NET_WORKAREA)) { QXcbVirtualDesktop *virtualDesktop = virtualDesktopForRootWindow(propertyNotify->window); @@ -1010,14 +1015,6 @@ void QXcbConnection::processXcbEvents(QEventLoop::ProcessEventsFlags flags) if (compressEvent(event)) continue; -#ifndef QT_NO_CLIPBOARD - bool accepted = false; - if (clipboard()->processIncr()) - clipboard()->incrTransactionPeeker(event, accepted); - if (accepted) - continue; -#endif - auto isWaitingFor = [=](PeekFunc peekFunc) { // These callbacks return true if the event is what they were // waiting for, remove them from the list in that case. diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 5d53b97d37..47036ca257 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -68,6 +68,7 @@ Q_DECLARE_LOGGING_CATEGORY(lcQpaScreen) Q_DECLARE_LOGGING_CATEGORY(lcQpaEvents) Q_DECLARE_LOGGING_CATEGORY(lcQpaPeeker) Q_DECLARE_LOGGING_CATEGORY(lcQpaKeyboard) +Q_DECLARE_LOGGING_CATEGORY(lcQpaClipboard) Q_DECLARE_LOGGING_CATEGORY(lcQpaXDnd) Q_DECLARE_LOGGING_CATEGORY(lcQpaEventReader) From cc9645f11b46aaad36658d62d38a5e44a5ba5ae5 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Wed, 29 Aug 2018 22:18:42 +0200 Subject: [PATCH 0148/1650] configure: Add switch for adding coverage info Change-Id: If6f3d4f29233206ef911f48e63872d28bf7b8e71 Reviewed-by: Oswald Buddenhagen --- config_help.txt | 3 +++ configure.json | 22 ++++++++++++++++++++++ configure.pri | 15 +++++++++++++++ mkspecs/common/clang.conf | 4 ++++ mkspecs/features/coverage.prf | 7 +++++++ 5 files changed, 51 insertions(+) create mode 100644 mkspecs/features/coverage.prf diff --git a/config_help.txt b/config_help.txt index 5b32eb183f..f8da33d4ec 100644 --- a/config_help.txt +++ b/config_help.txt @@ -135,6 +135,9 @@ Build options: for example, -sanitize address cannot be combined with -sanitize thread. + -coverage {trace-pc-guard} + Add code coverage instrumentation (Clang only) + -c++std .... Select C++ standard [c++1z/c++14/c++11] (Not supported with MSVC) diff --git a/configure.json b/configure.json index 522bd34e9b..d6568b9a7f 100644 --- a/configure.json +++ b/configure.json @@ -67,6 +67,7 @@ "commercial": "void", "compile-examples": { "type": "boolean", "name": "compile_examples" }, "confirm-license": "void", + "coverage": "coverage", "dbus": { "type": "optionalString", "values": [ "no", "yes", "linked", "runtime" ] }, "dbus-linked": { "type": "void", "name": "dbus", "value": "linked" }, "dbus-runtime": { "type": "void", "name": "dbus", "value": "runtime" }, @@ -791,6 +792,16 @@ "condition": "features.sanitize_address || features.sanitize_thread || features.sanitize_memory || features.sanitize_undefined", "output": [ "sanitizer", "publicConfig" ] }, + "coverage_trace_pc_guard": { + "label": "trace-pc-guard", + "autoDetect": false, + "output": [ "publicConfig" ] + }, + "coverage": { + "label": "Code Coverage Instrumentation", + "condition": "features.coverage_trace_pc_guard", + "output": [ "publicConfig" ] + }, "GNUmake": { "label": "GNU make", "autoDetect": false, @@ -1268,6 +1279,11 @@ Qt can be built in release mode with separate debug information, so "type": "error", "condition": "(features.rpath || features.rpath_dir) && var.QMAKE_LFLAGS_RPATH == ''", "message": "This platform does not support RPATH" + }, + { + "type": "error", + "condition": "features.coverage && !config.clang", + "message": "Command line option -coverage is only supported with clang compilers." } ], @@ -1401,6 +1417,12 @@ Configure with '-qreal float' to create a build that is binary-compatible with 5 "condition": "features.sanitizer", "entries": [ "sanitize_address", "sanitize_thread", "sanitize_memory", "sanitize_undefined" ] }, + { + "message": "Code Coverage Instrumentation", + "type": "firstAvailableFeature", + "args": "coverage_trace_pc_guard", + "condition": "features.coverage" + }, { "message": "Build parts", "type": "buildParts" diff --git a/configure.pri b/configure.pri index 64ed6b9ed8..3f3d2da571 100644 --- a/configure.pri +++ b/configure.pri @@ -58,6 +58,21 @@ defineTest(qtConfCommandline_sanitize) { } } +defineTest(qtConfCommandline_coverage) { + arg = $${1} + val = $${2} + isEmpty(val): val = $$qtConfGetNextCommandlineArg() + !contains(val, "^-.*"):!isEmpty(val) { + equals(val, "trace-pc-guard") { + qtConfCommandlineSetInput("coverage_trace_pc_guard", "yes") + } else { + qtConfAddError("Invalid argument $$val to command line parameter $$arg") + } + } else { + qtConfAddError("Missing argument to command line parameter $$arg") + } +} + # callbacks defineReplace(qtConfFunc_crossCompile) { diff --git a/mkspecs/common/clang.conf b/mkspecs/common/clang.conf index 5800aaa5b4..dacd1539cf 100644 --- a/mkspecs/common/clang.conf +++ b/mkspecs/common/clang.conf @@ -44,3 +44,7 @@ QMAKE_LFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG QMAKE_AR_LTCG = llvm-ar cqs QMAKE_NM_LTCG = llvm-nm -P QMAKE_RANLIB_LTCG = true # No need to run, since llvm-ar has "s" + +QMAKE_CFLAGS_COVERAGE_TRACE_PC_GUARD = -fsanitize-coverage=trace-pc-guard +QMAKE_CXXFLAGS_COVERAGE_TRACE_PC_GUARD = -fsanitize-coverage=trace-pc-guard +QMAKE_LFLAGS_COVERAGE_TRACE_PC_GUARD = -fsanitize-coverage=trace-pc-guard diff --git a/mkspecs/features/coverage.prf b/mkspecs/features/coverage.prf new file mode 100644 index 0000000000..b8b37e1b80 --- /dev/null +++ b/mkspecs/features/coverage.prf @@ -0,0 +1,7 @@ +# Coverage flags + +coverage_trace_pc_guard { + QMAKE_CFLAGS += $$QMAKE_CFLAGS_COVERAGE_TRACE_PC_GUARD + QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_COVERAGE_TRACE_PC_GUARD + QMAKE_LFLAGS += $$QMAKE_LFLAGS_COVERAGE_TRACE_PC_GUARD +} From c9d18d4a9c9d1243a267316e2a702f9ba69de2fd Mon Sep 17 00:00:00 2001 From: Samuli Piippo Date: Wed, 31 Oct 2018 10:03:09 +0200 Subject: [PATCH 0149/1650] eglfs_kms: initialize m_deviceListener If QT_QPA_EGLFS_HIDECURSOR was enabled, m_deviceListener was never initialized, which caused segfault in the destructor. Task-number: QTBUG-71507 Change-Id: Id8b17f5312073249cd12995317213fd746753521 Reviewed-by: Laszlo Agocs --- .../eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp index 9bd7fee1fb..4d0cf0c47e 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.cpp @@ -71,6 +71,7 @@ QEglFSKmsGbmCursor::QEglFSKmsGbmCursor(QEglFSKmsGbmScreen *screen) , m_bo(nullptr) , m_cursorImage(0, 0, 0, 0, 0, 0) , m_state(CursorPendingVisible) + , m_deviceListener(nullptr) { QByteArray hideCursorVal = qgetenv("QT_QPA_EGLFS_HIDECURSOR"); if (!hideCursorVal.isEmpty() && hideCursorVal.toInt()) { From b1ef104866f78ae5bbc1214ae524bad4120ef0e2 Mon Sep 17 00:00:00 2001 From: Heikki Halmet Date: Wed, 31 Oct 2018 09:18:14 +0200 Subject: [PATCH 0150/1650] Blacklist tst_QWindow::exposeEventOnShrink_QTBUG54040 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ib87d2820c4dbdf93778997b6df11cc7d8e63cf04 Reviewed-by: Tony Sarajärvi --- tests/auto/gui/kernel/qwindow/BLACKLIST | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/gui/kernel/qwindow/BLACKLIST b/tests/auto/gui/kernel/qwindow/BLACKLIST index e9a0d44ba7..f54865b841 100644 --- a/tests/auto/gui/kernel/qwindow/BLACKLIST +++ b/tests/auto/gui/kernel/qwindow/BLACKLIST @@ -40,6 +40,7 @@ android [exposeEventOnShrink_QTBUG54040] # QTBUG-69155 android +opensuse [initialSize] # QTBUG-69159 android From 7aad54262927da7f0223ed9ba970e8bba9f4900d Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Wed, 31 Oct 2018 19:50:29 +0300 Subject: [PATCH 0151/1650] Notepad example: Get rid of auto-connection slots MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Their correctness is not checked at compile time and even object renames can break code. Change-Id: I99273a28743a79a76c00e6db0ed4cd6d7eba8bf2 Reviewed-by: Topi Reiniö --- .../widgets/tutorials/gettingstartedqt.qdoc | 14 ++--- .../widgets/tutorials/notepad/notepad.cpp | 57 ++++++++++++------- examples/widgets/tutorials/notepad/notepad.h | 32 +++++------ 3 files changed, 60 insertions(+), 43 deletions(-) diff --git a/examples/widgets/tutorials/gettingstartedqt.qdoc b/examples/widgets/tutorials/gettingstartedqt.qdoc index bbe1dd1a8d..32e8845c05 100644 --- a/examples/widgets/tutorials/gettingstartedqt.qdoc +++ b/examples/widgets/tutorials/gettingstartedqt.qdoc @@ -390,10 +390,10 @@ action concerned. When the QAction has been dragged to the toolbar, clicking the icon will launch the associated slot. - Complete the method \c on_actionNew_triggered(): + Complete the method \c newDocument(): \quotefromfile tutorials/notepad/notepad.cpp - \skipto on_actionNew_triggered() + \skipto newDocument() \printuntil } \c current_file is a global variable containing the file presently @@ -411,10 +411,10 @@ In \c notepad.ui, right click on \c actionOpen and select \c {Go to slot} - Complete method \c on_actionOpen_triggered(). + Complete method \c open(). \quotefromfile tutorials/notepad/notepad.cpp - \skipto on_actionOpen_triggered() + \skipto open() \printuntil file.close \printuntil } @@ -436,7 +436,7 @@ \l {Opening a file}, by right clicking on \c actionSave, and selecting \c {Go to Slot}. - \skipto Notepad::on_actionSave_triggered + \skipto Notepad::save \printuntil file.close \printuntil } @@ -449,7 +449,7 @@ \section2 Saving a file with \c {Save as} - \skipto Notepad::on_actionSave_as_triggered + \skipto Notepad::saveAs \printuntil file.close \printuntil } @@ -475,7 +475,7 @@ \section2 Select a Font - \skipto Notepad::on_actionFont_triggered + \skipto Notepad::selectFont \printuntil ui->textEdit->setFont \printline } diff --git a/examples/widgets/tutorials/notepad/notepad.cpp b/examples/widgets/tutorials/notepad/notepad.cpp index d0e600e852..2ccd6501a1 100644 --- a/examples/widgets/tutorials/notepad/notepad.cpp +++ b/examples/widgets/tutorials/notepad/notepad.cpp @@ -74,6 +74,23 @@ Notepad::Notepad(QWidget *parent) : ui->setupUi(this); this->setCentralWidget(ui->textEdit); + connect(ui->actionNew, &QAction::triggered, this, &Notepad::newDocument); + connect(ui->actionOpen, &QAction::triggered, this, &Notepad::open); + connect(ui->actionSave, &QAction::triggered, this, &Notepad::save); + connect(ui->actionSave_as, &QAction::triggered, this, &Notepad::saveAs); + connect(ui->actionPrint, &QAction::triggered, this, &Notepad::print); + connect(ui->actionExit, &QAction::triggered, this, &Notepad::exit); + connect(ui->actionCopy, &QAction::triggered, this, &Notepad::copy); + connect(ui->actionCut, &QAction::triggered, this, &Notepad::cut); + connect(ui->actionPaste, &QAction::triggered, this, &Notepad::paste); + connect(ui->actionUndo, &QAction::triggered, this, &Notepad::undo); + connect(ui->actionRedo, &QAction::triggered, this, &Notepad::redo); + connect(ui->actionFont, &QAction::triggered, this, &Notepad::selectFont); + connect(ui->actionBold, &QAction::triggered, this, &Notepad::setFontBold); + connect(ui->actionUnderline, &QAction::triggered, this, &Notepad::setFontUnderline); + connect(ui->actionItalic, &QAction::triggered, this, &Notepad::setFontItalic); + connect(ui->actionAbout, &QAction::triggered, this, &Notepad::about); + // Disable menu actions for unavailable features #if !QT_CONFIG(printer) ui->actionPrint->setEnabled(false); @@ -91,13 +108,13 @@ Notepad::~Notepad() delete ui; } -void Notepad::on_actionNew_triggered() +void Notepad::newDocument() { currentFile.clear(); ui->textEdit->setText(QString()); } -void Notepad::on_actionOpen_triggered() +void Notepad::open() { QString fileName = QFileDialog::getOpenFileName(this, "Open the file"); QFile file(fileName); @@ -113,7 +130,7 @@ void Notepad::on_actionOpen_triggered() file.close(); } -void Notepad::on_actionSave_triggered() +void Notepad::save() { QString fileName; // If we don't have a filename from before, get one. @@ -135,7 +152,7 @@ void Notepad::on_actionSave_triggered() file.close(); } -void Notepad::on_actionSave_as_triggered() +void Notepad::saveAs() { QString fileName = QFileDialog::getSaveFileName(this, "Save as"); QFile file(fileName); @@ -152,7 +169,7 @@ void Notepad::on_actionSave_as_triggered() file.close(); } -void Notepad::on_actionPrint_triggered() +void Notepad::print() { #if QT_CONFIG(printer) QPrinter printDev; @@ -165,43 +182,43 @@ void Notepad::on_actionPrint_triggered() #endif // QT_CONFIG(printer) } -void Notepad::on_actionExit_triggered() +void Notepad::exit() { QCoreApplication::quit(); } -void Notepad::on_actionCopy_triggered() +void Notepad::copy() { #if QT_CONFIG(clipboard) ui->textEdit->copy(); #endif } -void Notepad::on_actionCut_triggered() +void Notepad::cut() { #if QT_CONFIG(clipboard) ui->textEdit->cut(); #endif } -void Notepad::on_actionPaste_triggered() +void Notepad::paste() { #if QT_CONFIG(clipboard) ui->textEdit->paste(); #endif } -void Notepad::on_actionUndo_triggered() +void Notepad::undo() { ui->textEdit->undo(); } -void Notepad::on_actionRedo_triggered() +void Notepad::redo() { ui->textEdit->redo(); } -void Notepad::on_actionFont_triggered() +void Notepad::selectFont() { bool fontSelected; QFont font = QFontDialog::getFont(&fontSelected, this); @@ -209,23 +226,23 @@ void Notepad::on_actionFont_triggered() ui->textEdit->setFont(font); } -void Notepad::on_actionUnderline_triggered() +void Notepad::setFontUnderline(bool underline) { - ui->textEdit->setFontUnderline(ui->actionUnderline->isChecked()); + ui->textEdit->setFontUnderline(underline); } -void Notepad::on_actionItalic_triggered() +void Notepad::setFontItalic(bool italic) { - ui->textEdit->setFontItalic(ui->actionItalic->isChecked()); + ui->textEdit->setFontItalic(italic); } -void Notepad::on_actionBold_triggered() +void Notepad::setFontBold(bool bold) { - ui->actionBold->isChecked() ? ui->textEdit->setFontWeight(QFont::Bold) : - ui->textEdit->setFontWeight(QFont::Normal); + bold ? ui->textEdit->setFontWeight(QFont::Bold) : + ui->textEdit->setFontWeight(QFont::Normal); } -void Notepad::on_actionAbout_triggered() +void Notepad::about() { QMessageBox::about(this, tr("About MDI"), tr("The Notepad example demonstrates how to code a basic " diff --git a/examples/widgets/tutorials/notepad/notepad.h b/examples/widgets/tutorials/notepad/notepad.h index 288ab4e373..9580ab8071 100644 --- a/examples/widgets/tutorials/notepad/notepad.h +++ b/examples/widgets/tutorials/notepad/notepad.h @@ -79,37 +79,37 @@ public: //! [5] private slots: - void on_actionNew_triggered(); + void newDocument(); - void on_actionOpen_triggered(); + void open(); - void on_actionSave_triggered(); + void save(); - void on_actionSave_as_triggered(); + void saveAs(); - void on_actionPrint_triggered(); + void print(); - void on_actionExit_triggered(); + void exit(); - void on_actionCopy_triggered(); + void copy(); - void on_actionCut_triggered(); + void cut(); - void on_actionPaste_triggered(); + void paste(); - void on_actionUndo_triggered(); + void undo(); - void on_actionRedo_triggered(); + void redo(); - void on_actionFont_triggered(); + void selectFont(); - void on_actionBold_triggered(); + void setFontBold(bool bold); - void on_actionUnderline_triggered(); + void setFontUnderline(bool underline); - void on_actionItalic_triggered(); + void setFontItalic(bool italic); - void on_actionAbout_triggered(); + void about(); //! [6] private: From ae0843eca0e7102390ceec43236cfe8c5724d278 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 25 Oct 2018 13:48:34 +0200 Subject: [PATCH 0152/1650] Tablet example: Fix warning about switch/fallthrough Add Q_FALLTHROUGH(), fixing: tabletcanvas.cpp:222:55: warning: this statement may fall through [-Wimplicit-fallthrough=] Change-Id: I573f4add56774218e28a7c5f1dac09c5402333c0 Reviewed-by: Shawn Rutledge --- examples/widgets/widgets/tablet/tabletcanvas.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/widgets/widgets/tablet/tabletcanvas.cpp b/examples/widgets/widgets/tablet/tabletcanvas.cpp index bfcc84e182..dc56702142 100644 --- a/examples/widgets/widgets/tablet/tabletcanvas.cpp +++ b/examples/widgets/widgets/tablet/tabletcanvas.cpp @@ -224,7 +224,7 @@ void TabletCanvas::paintPixmap(QPainter &painter, QTabletEvent *event) qWarning() << error; #endif } - // FALL-THROUGH + Q_FALLTHROUGH(); case QTabletEvent::Stylus: painter.setPen(m_pen); painter.drawLine(lastPoint.pos, event->posF()); From 779a73762de6addb2a2e3fee5b98d00d64101b92 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Fri, 14 Sep 2018 14:59:21 +0200 Subject: [PATCH 0153/1650] Fully support operator[] on QCborValue and QCborValueRef Added operator[] to QCborValueRef and mutating operator[] both there and in QCborValue. If the value (referenced) is not a container, it is replaced with a map and a reference into the result is returned. If the value is an array and the key is a string, negative, or more than 0xffff, the array is first converted to a map. Change-Id: Ibbc9e480fb25eb3d05547c8a1b99e762b2a68b68 Reviewed-by: Thiago Macieira --- src/corelib/serialization/qcborarray.h | 1 + src/corelib/serialization/qcbormap.h | 5 +- src/corelib/serialization/qcborvalue.cpp | 454 +++++++++++++++++- src/corelib/serialization/qcborvalue.h | 12 + .../qcborvalue/tst_qcborvalue.cpp | 59 ++- 5 files changed, 519 insertions(+), 12 deletions(-) diff --git a/src/corelib/serialization/qcborarray.h b/src/corelib/serialization/qcborarray.h index d96342cfa6..e06544f245 100644 --- a/src/corelib/serialization/qcborarray.h +++ b/src/corelib/serialization/qcborarray.h @@ -272,6 +272,7 @@ private: void detach(qsizetype reserve = 0); friend QCborValue; + friend QCborValueRef; explicit QCborArray(QCborContainerPrivate &dd) noexcept; QExplicitlySharedDataPointer d; }; diff --git a/src/corelib/serialization/qcbormap.h b/src/corelib/serialization/qcbormap.h index 0eb163a0a8..15a3bcdcef 100644 --- a/src/corelib/serialization/qcbormap.h +++ b/src/corelib/serialization/qcbormap.h @@ -118,6 +118,8 @@ public: QCborValueRef item; // points to the value friend class Iterator; friend class QCborMap; + friend class QCborValue; + friend class QCborValueRef; ConstIterator(QCborContainerPrivate *dd, qsizetype ii) : item(dd, ii) {} public: typedef std::random_access_iterator_tag iterator_category; @@ -323,9 +325,10 @@ public: QJsonObject toJsonObject() const; private: + friend class QCborValue; + friend class QCborValueRef; void detach(qsizetype reserve = 0); - friend QCborValue; explicit QCborMap(QCborContainerPrivate &dd) noexcept; QExplicitlySharedDataPointer d; }; diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp index 170ad588d1..2e2bac3f65 100644 --- a/src/corelib/serialization/qcborvalue.cpp +++ b/src/corelib/serialization/qcborvalue.cpp @@ -128,10 +128,11 @@ QT_BEGIN_NAMESPACE Such values are completely valid and may appear in CBOR streams, unlike JSON content and QJsonValue's undefined bit. But like QJsonValue's - Undefined, it is returned by QCborArray::value() when out of range or - QCborMap::operator[] when the key is not found in the container. It is not - possible to tell such a case apart from the value of Undefined, so if that - is required, check the QCborArray size and use the QCborMap iterator API. + Undefined, it is returned by a CBOR container's value() or read-only + operator[] for invalid look-ups (index out of range for QCborArray, or key + not found for QCborMap). It is not possible to tell such a case apart from + the value of Undefined, so if that is required, check the QCborArray size + and use the QCborMap iterator API. \section1 Simple types @@ -457,7 +458,7 @@ QT_BEGIN_NAMESPACE \fn QCborValue::QCborValue(QCborValue &&other) \overload - Moves the contents of the \a other CBorValue object into this one and frees + Moves the contents of the \a other QCborValue object into this one and frees the resources of this one. */ @@ -465,7 +466,7 @@ QT_BEGIN_NAMESPACE \fn QCborValue &&QCborValue::operator=(QCborValue &&other) \overload - Moves the contents of the \a other CBorValue object into this one and frees + Moves the contents of the \a other QCborValue object into this one and frees the resources of this one. Returns a reference to this object. */ @@ -2107,15 +2108,16 @@ const QCborValue QCborValue::operator[](QLatin1String key) const } /*! + \overload + If this QCborValue is a QCborMap, searches elements for the value whose key - matches \a key. If this is an array, returns the element whose index is \a - key. If there's no matching value in the array or map, or if this + matches \a key. If this is a QCborArray, returns the element whose index is + \a key. If there's no matching value in the array or map, or if this QCborValue object is not an array or map, returns the undefined value. \sa operator[], QCborMap::operator[], QCborMap::value(), QCborMap::find(), QCborArray::operator[], QCborArray::at() */ - const QCborValue QCborValue::operator[](qint64 key) const { if (isMap()) @@ -2125,6 +2127,191 @@ const QCborValue QCborValue::operator[](qint64 key) const return QCborValue(); } +/*! + \internal + */ +static Q_DECL_COLD_FUNCTION QCborMap arrayAsMap(const QCborArray &array) +{ + if (array.size()) + qWarning("Using CBOR array as map forced conversion"); + QCborMap map; + for (qsizetype i = array.size(); i-- > 0; ) { + QCborValue entry = array.at(i); + // Ignore padding entries that may have been added to grow the array + // when inserting past its end: + if (!entry.isInvalid()) + map[i] = entry; + } + return map; +} + +/*! + \internal + */ +static QCborContainerPrivate *maybeDetach(QCborContainerPrivate *container, qsizetype size) +{ + auto replace = QCborContainerPrivate::detach(container, size); + Q_ASSERT(replace); + if (replace != container) { + if (container) + container->deref(); + replace->ref.ref(); + } + return replace; +} + +/*! + \internal + */ +static QCborContainerPrivate *maybeGrow(QCborContainerPrivate *container, qsizetype index) +{ + auto replace = QCborContainerPrivate::grow(container, index); + Q_ASSERT(replace); + if (replace != container) { + if (container) + container->deref(); + replace->ref.ref(); + } + if (replace->elements.size() == index) + replace->append(Undefined()); + else + Q_ASSERT(replace->elements.size() > index); + return replace; +} + +/*! + Returns a QCborValueRef that can be used to read or modify the entry in + this, as a map, with the given \a key. When this QCborValue is a QCborMap, + this function is equivalent to the matching operator[] on that map. + + Before returning the reference: if this QCborValue was an array, it is first + converted to a map (so that \c{map[i]} is \c{array[i]} for each index, \c i, + with valid \c{array[i]}); otherwise, if it was not a map it will be + over-written with an empty map. + + \sa operator[](qint64), QCborMap::operator[], QCborMap::value(), + QCborMap::find() + */ +QCborValueRef QCborValue::operator[](const QString &key) +{ + if (!isMap()) + *this = QCborValue(isArray() ? arrayAsMap(toArray()) : QCborMap()); + + const qsizetype size = container ? container->elements.size() : 0; + qsizetype index = size + 1; + bool found = false; + if (container) { + QCborMap proxy(*container); + auto it = proxy.constFind(key); + if (it < proxy.constEnd()) { + found = true; + index = it.item.i; + } + } + + container = maybeDetach(container, size + (found ? 0 : 2)); + Q_ASSERT(container); + if (!found) { + container->append(key); + container->append(QCborValue()); + } + Q_ASSERT(index & 1 && !(container->elements.size() & 1)); + Q_ASSERT(index < container->elements.size()); + return { container, index }; +} + +/*! + \overload + + Returns a QCborValueRef that can be used to read or modify the entry in + this, as a map, with the given \a key. When this QCborValue is a QCborMap, + this function is equivalent to the matching operator[] on that map. + + Before returning the reference: if this QCborValue was an array, it is first + converted to a map (so that \c{map[i]} is \c{array[i]} for each index, \c i, + with valid \c{array[i]}); otherwise, if it was not a map it will be + over-written with an empty map. + + \sa operator[](qint64), QCborMap::operator[], QCborMap::value(), + QCborMap::find() + */ +QCborValueRef QCborValue::operator[](QLatin1String key) +{ + if (!isMap()) + *this = QCborValue(isArray() ? arrayAsMap(toArray()) : QCborMap()); + + const qsizetype size = container ? container->elements.size() : 0; + qsizetype index = size + 1; + bool found = false; + if (container) { + QCborMap proxy(*container); + auto it = proxy.constFind(key); + if (it < proxy.constEnd()) { + found = true; + index = it.item.i; + } + } + + container = maybeDetach(container, size + (found ? 0 : 2)); + Q_ASSERT(container); + if (!found) { + container->append(key); + container->append(QCborValue()); + } + Q_ASSERT(index & 1 && !(container->elements.size() & 1)); + Q_ASSERT(index < container->elements.size()); + return { container, index }; +} + +/*! + \overload + + Returns a QCborValueRef that can be used to read or modify the entry in + this, as a map or array, with the given \a key. When this QCborValue is a + QCborMap or, for 0 <= key < 0x10000, a QCborArray, this function is + equivalent to the matching operator[] on that map or array. + + Before returning the reference: if this QCborValue was an array but the key + is out of range, the array is first converted to a map (so that \c{map[i]} + is \c{array[i]} for each index, \c i, with valid \c{array[i]}); otherwise, + if it was not a map it will be over-written with an empty map. + + \sa operator[], QCborMap::operator[], QCborMap::value(), + QCborMap::find(), QCborArray::operator[], QCborArray::at() + */ +QCborValueRef QCborValue::operator[](qint64 key) +{ + if (isArray() && key >= 0 && key < 0x10000) { + container = maybeGrow(container, key); + return { container, qsizetype(key) }; + } + if (!isMap()) + *this = QCborValue(isArray() ? arrayAsMap(toArray()) : QCborMap()); + + const qsizetype size = container ? container->elements.size() : 0; + Q_ASSERT(!(size & 1)); + qsizetype index = size + 1; + bool found = false; + if (container) { + QCborMap proxy(*container); + auto it = proxy.constFind(key); + if (it < proxy.constEnd()) { + found = true; + index = it.item.i; + } + } + + container = maybeDetach(container, size + (found ? 0 : 2)); + Q_ASSERT(container); + if (!found) { + container->append(key); + container->append(QCborValue()); + } + Q_ASSERT(index & 1 && !(container->elements.size() & 1)); + Q_ASSERT(index < container->elements.size()); + return { container, index }; +} + /*! Decodes one item from the CBOR stream found in \a reader and returns the equivalent representation. This function is recursive: if the item is a map @@ -2389,6 +2576,255 @@ QCborValue::Type QCborValueRef::concreteType(QCborValueRef self) noexcept return self.d->elements.at(self.i).type; } +/*! + If this QCborValueRef refers to a QCborMap, searches elements for the value + whose key matches \a key. If there's no key matching \a key in the map or if + this QCborValueRef object is not a map, returns the undefined value. + + This function is equivalent to: + + \code + value.toMap().value(key); + \endcode + + \sa operator[](qint64), QCborMap::operator[], QCborMap::value(), + QCborMap::find() + */ +const QCborValue QCborValueRef::operator[](const QString &key) const +{ + const QCborValue item = d->valueAt(i); + return item[key]; +} + +/*! + \overload + + If this QCborValueRef refers to a QCborMap, searches elements for the value + whose key matches \a key. If there's no key matching \a key in the map or if + this QCborValueRef object is not a map, returns the undefined value. + + This function is equivalent to: + + \code + value.toMap().value(key); + \endcode + + \sa operator[](qint64), QCborMap::operator[], QCborMap::value(), + QCborMap::find() + */ +const QCborValue QCborValueRef::operator[](QLatin1String key) const +{ + const QCborValue item = d->valueAt(i); + return item[key]; +} + +/*! + \overload + + If this QCborValueRef refers to a QCborMap, searches elements for the value + whose key matches \a key. If this is a QCborArray, returns the element whose + index is \a key. If there's no matching value in the array or map, or if + this QCborValueRef object is not an array or map, returns the undefined + value. + + \sa operator[], QCborMap::operator[], QCborMap::value(), + QCborMap::find(), QCborArray::operator[], QCborArray::at() + */ +const QCborValue QCborValueRef::operator[](qint64 key) const +{ + const QCborValue item = d->valueAt(i); + return item[key]; +} + +/*! + Returns a QCborValueRef that can be used to read or modify the entry in + this, as a map, with the given \a key. When this QCborValueRef refers to a + QCborMap, this function is equivalent to the matching operator[] on that + map. + + Before returning the reference: if the QCborValue referenced was an array, + it is first converted to a map (so that \c{map[i]} is \c{array[i]} for each + index, \c i, with valid \c{array[i]}); otherwise, if it was not a map it + will be over-written with an empty map. + + \sa operator[](qint64), QCborMap::operator[], QCborMap::value(), + QCborMap::find() + */ +QCborValueRef QCborValueRef::operator[](const QString &key) +{ + auto &e = d->elements[i]; + qsizetype size = 0; + if (e.flags & QtCbor::Element::IsContainer) { + if (e.container) { + if (e.type == QCborValue::Array) { + QCborValue repack = QCborValue(arrayAsMap(QCborArray(*e.container))); + qSwap(e.container, repack.container); + } else if (e.type != QCborValue::Map) { + e.container->deref(); + e.container = nullptr; + } + } + e.type = QCborValue::Map; + if (e.container) + size = e.container->elements.size(); + } else { + // Stomp any prior e.value, replace with a map (that we'll grow) + e.container = nullptr; + e.type = QCborValue::Map; + e.flags = QtCbor::Element::IsContainer; + } + + qsizetype index = size + 1; + bool found = false; + if (e.container) { + QCborMap proxy(*e.container); + auto it = proxy.constFind(key); + if (it < proxy.constEnd()) { + found = true; + index = it.item.i; + } + } + + e.container = maybeDetach(e.container, size + (found ? 0 : 2)); + Q_ASSERT(e.container); + if (!found) { + e.container->append(key); + e.container->append(QCborValue()); + } + Q_ASSERT(index & 1 && !(e.container->elements.size() & 1)); + Q_ASSERT(index < e.container->elements.size()); + return { e.container, index }; +} + +/*! + \overload + + Returns a QCborValueRef that can be used to read or modify the entry in + this, as a map, with the given \a key. When this QCborValue is a QCborMap, + this function is equivalent to the matching operator[] on that map. + + Before returning the reference: if the QCborValue referenced was an array, + it is first converted to a map (so that \c{map[i]} is \c{array[i]} for each + index, \c i, with valid \c{array[i]}); otherwise, if it was not a map it + will be over-written with an empty map. + + \sa operator[](qint64), QCborMap::operator[], QCborMap::value(), + QCborMap::find() + */ +QCborValueRef QCborValueRef::operator[](QLatin1String key) +{ + auto &e = d->elements[i]; + qsizetype size = 0; + if (e.flags & QtCbor::Element::IsContainer) { + if (e.container) { + if (e.type == QCborValue::Array) { + QCborValue repack = QCborValue(arrayAsMap(QCborArray(*e.container))); + qSwap(e.container, repack.container); + } else if (e.type != QCborValue::Map) { + e.container->deref(); + e.container = nullptr; + } + } + e.type = QCborValue::Map; + if (e.container) + size = e.container->elements.size(); + } else { + // Stomp any prior e.value, replace with a map (that we'll grow) + e.container = nullptr; + e.type = QCborValue::Map; + e.flags = QtCbor::Element::IsContainer; + } + + qsizetype index = size + 1; + bool found = false; + if (e.container) { + QCborMap proxy(*e.container); + auto it = proxy.constFind(key); + if (it < proxy.constEnd()) { + found = true; + index = it.item.i; + } + } + + e.container = maybeDetach(e.container, size + (found ? 0 : 2)); + Q_ASSERT(e.container); + if (!found) { + e.container->append(key); + e.container->append(QCborValue()); + } + Q_ASSERT(index & 1 && !(e.container->elements.size() & 1)); + Q_ASSERT(index < e.container->elements.size()); + return { e.container, index }; +} + +/*! + \overload + + Returns a QCborValueRef that can be used to read or modify the entry in + this, as a map or array, with the given \a key. When this QCborValue is a + QCborMap or, for 0 <= key < 0x10000, a QCborArray, this function is + equivalent to the matching operator[] on that map or array. + + Before returning the reference: if the QCborValue referenced was an array + but the key is out of range, the array is first converted to a map (so that + \c{map[i]} is \c{array[i]} for each index, \c i, with valid \c{array[i]}); + otherwise, if it was not a map it will be over-written with an empty map. + + \sa operator[], QCborMap::operator[], QCborMap::value(), + QCborMap::find(), QCborArray::operator[], QCborArray::at() + */ +QCborValueRef QCborValueRef::operator[](qint64 key) +{ + auto &e = d->elements[i]; + if (e.type == QCborValue::Array && key >= 0 && key < 0x10000) { + e.container = maybeGrow(e.container, key); + return { e.container, qsizetype(key) }; + } + qsizetype size = 0; + if (e.flags & QtCbor::Element::IsContainer) { + if (e.container) { + if (e.type == QCborValue::Array) { + QCborValue repack = QCborValue(arrayAsMap(QCborArray(*e.container))); + qSwap(e.container, repack.container); + } else if (e.type != QCborValue::Map) { + e.container->deref(); + e.container = nullptr; + } + } + e.type = QCborValue::Map; + if (e.container) + size = e.container->elements.size(); + } else { + // Stomp any prior e.value, replace with a map (that we'll grow) + e.container = nullptr; + e.type = QCborValue::Map; + e.flags = QtCbor::Element::IsContainer; + } + Q_ASSERT(!(size & 1)); + + qsizetype index = size + 1; + bool found = false; + if (e.container) { + QCborMap proxy(*e.container); + auto it = proxy.constFind(key); + if (it < proxy.constEnd()) { + found = true; + index = it.item.i; + } + } + + e.container = maybeDetach(e.container, size + (found ? 0 : 2)); + Q_ASSERT(e.container); + if (!found) { + e.container->append(key); + e.container->append(QCborValue()); + } + Q_ASSERT(index & 1 && !(e.container->elements.size() & 1)); + Q_ASSERT(index < e.container->elements.size()); + return { e.container, index }; +} + + inline QCborArray::QCborArray(QCborContainerPrivate &dd) noexcept : d(&dd) { diff --git a/src/corelib/serialization/qcborvalue.h b/src/corelib/serialization/qcborvalue.h index 5c7f9a3791..1088558074 100644 --- a/src/corelib/serialization/qcborvalue.h +++ b/src/corelib/serialization/qcborvalue.h @@ -77,6 +77,7 @@ struct QCborParserError QString errorString() const { return error.toString(); } }; +class QCborValueRef; class QCborContainerPrivate; class Q_CORE_EXPORT QCborValue { @@ -246,6 +247,9 @@ public: const QCborValue operator[](const QString &key) const; const QCborValue operator[](QLatin1String key) const; const QCborValue operator[](qint64 key) const; + QCborValueRef operator[](qint64 key); + QCborValueRef operator[](QLatin1String key); + QCborValueRef operator[](const QString & key); int compare(const QCborValue &other) const; #if 0 && QT_HAS_INCLUDE() @@ -387,6 +391,13 @@ public: QCborMap toMap() const; QCborMap toMap(const QCborMap &m) const; + const QCborValue operator[](const QString &key) const; + const QCborValue operator[](QLatin1String key) const; + const QCborValue operator[](qint64 key) const; + QCborValueRef operator[](qint64 key); + QCborValueRef operator[](QLatin1String key); + QCborValueRef operator[](const QString & key); + int compare(const QCborValue &other) const { return concrete().compare(other); } #if 0 && QT_HAS_INCLUDE() @@ -417,6 +428,7 @@ public: { return concrete().toDiagnosticNotation(opt); } private: + friend class QCborValue; friend class QCborArray; friend class QCborMap; friend class QCborContainerPrivate; diff --git a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp index c609aa6621..f69ce4120d 100644 --- a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp +++ b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp @@ -384,11 +384,17 @@ void tst_QCborValue::arrayDefaultInitialization() QVERIFY(v.isArray()); QVERIFY(!v.isMap()); QVERIFY(!v.isTag()); - QVERIFY(v[0].isUndefined()); QCborArray a2 = v.toArray(); QVERIFY(a2.isEmpty()); QCOMPARE(a2, a); + auto front = v[0]; + QVERIFY(front.isUndefined()); + front = 1; + QCOMPARE(v[0], 1); + QVERIFY(a2.isEmpty()); + a2 = v.toArray(); + QCOMPARE(a2.size(), 1); } void tst_QCborValue::mapDefaultInitialization() @@ -425,7 +431,7 @@ void tst_QCborValue::mapDefaultInitialization() QVERIFY(m == QCborMap{}); QVERIFY(QCborMap{} == m); - QCborValue v(m); + const QCborValue v(m); QVERIFY(v.isMap()); QVERIFY(!v.isArray()); QVERIFY(!v.isTag()); @@ -727,6 +733,31 @@ void tst_QCborValue::arrayMutation() QCOMPARE(a.at(1), QCborValue(-1)); QCOMPARE(a2.at(1), QCborValue(nullptr)); QCOMPARE(++it, end); + + // Array accessed via value: + QCborValue val(a); + val[2] = QCborArray{2, 3, 5, 7}; + QCOMPARE(a.size(), 2); // Unchanged + QVERIFY(val.isArray()); + QCOMPARE(val.toArray().size(), 3); + val[2][4] = 17; + QVERIFY(val.isArray()); + QVERIFY(val[2].isArray()); + QCOMPARE(val[2].toArray().size(), 5); + QCOMPARE(val[2][4], 17); + QCOMPARE(val.toArray().size(), 3); + val[3] = 42; + QVERIFY(val.isArray()); + QCOMPARE(val.toArray().size(), 4); + QCOMPARE(val[3], 42); + + // Coerce to map on string key: + const QLatin1String any("any"); + val[any] = any; + QVERIFY(val.isMap()); + QCOMPARE(val.toMap().size(), 5); + QVERIFY(val[2].isArray()); + QCOMPARE(val[2].toArray().size(), 5); } void tst_QCborValue::mapMutation() @@ -782,6 +813,30 @@ void tst_QCborValue::mapMutation() QCOMPARE((m.end() - 1)->toInteger(), -1); QVERIFY((m2.end() - 1)->isNull()); QCOMPARE(++it, end); + + // Map accessed via value: + QCborValue val(m); + val[7] = QCborMap({{0, 2}, {1, 3}, {2, 5}}); + QCOMPARE(m.size(), 2); // Unchanged + QVERIFY(val.isMap()); + QCOMPARE(val.toMap().size(), 3); + val[7][3] = 11; + QVERIFY(val.isMap()); + QVERIFY(val[7].isMap()); + QCOMPARE(val[7].toMap().size(), 4); + val[14] = 42; + QVERIFY(val.isMap()); + QCOMPARE(val.toMap().size(), 4); + + const QLatin1String any("any"); + const QString hello(QStringLiteral("Hello World")); + val[any][3][hello] = any; + QVERIFY(val.isMap()); + QCOMPARE(val.toMap().size(), 5); + QVERIFY(val[any].isMap()); + QCOMPARE(val[any].toMap().size(), 1); + QVERIFY(val[any][3].isMap()); + QCOMPARE(val[any][3].toMap().size(), 1); } void tst_QCborValue::arrayPrepend() From 30101884a6f3ab2f3d4d11426373eca3fca10652 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 17 Oct 2018 19:32:54 +0200 Subject: [PATCH 0154/1650] Simplify tst_Selftests::compareLine by handling the trivial case first MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the two lines have identical texts, the comparison returns true. So don't complicate various other conditions on the way there with filtering out that case; deal with it first so they don't need to. Change-Id: Iebd230704ce5f53d12d5afa64aab30f83bb9d407 Reviewed-by: Jędrzej Nowacki --- tests/auto/testlib/selftests/tst_selftests.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/auto/testlib/selftests/tst_selftests.cpp b/tests/auto/testlib/selftests/tst_selftests.cpp index c5f847562e..2d3cfaf176 100644 --- a/tests/auto/testlib/selftests/tst_selftests.cpp +++ b/tests/auto/testlib/selftests/tst_selftests.cpp @@ -893,16 +893,19 @@ bool tst_Selftests::compareLine(const QString &logger, const QString &subdir, const QString &actualLine, const QString &expectedLine, QString *errorMessage) const { - if (subdir == QLatin1String("assert") && actualLine.contains(QLatin1String("ASSERT: ")) - && expectedLine.contains(QLatin1String("ASSERT: ")) && actualLine != expectedLine) { + if (actualLine == expectedLine) + return true; + + if (subdir == QLatin1String("assert") + && actualLine.contains(QLatin1String("ASSERT: ")) + && expectedLine.contains(QLatin1String("ASSERT: "))) { // Q_ASSERT uses __FILE__, the exact contents of which are // undefined. If have we something that looks like a Q_ASSERT and we // were expecting to see a Q_ASSERT, we'll skip the line. return true; } - if (expectedLine.startsWith(QLatin1String("FAIL! : tst_Exception::throwException() Caught unhandled exce")) - && actualLine != expectedLine) { + if (expectedLine.startsWith(QLatin1String("FAIL! : tst_Exception::throwException() Caught unhandled exce"))) { // On some platforms we compile without RTTI, and as a result we never throw an exception if (actualLine.simplified() != QLatin1String("tst_Exception::throwException()")) { *errorMessage = QString::fromLatin1("'%1' != 'tst_Exception::throwException()'").arg(actualLine); @@ -941,9 +944,6 @@ bool tst_Selftests::compareLine(const QString &logger, const QString &subdir, if (actualLine.startsWith(QLatin1String("Totals:")) && expectedLine.startsWith(QLatin1String("Totals:"))) return true; - if (actualLine == expectedLine) - return true; - *errorMessage = msgMismatch(actualLine, expectedLine); return false; } From b22e50acda53d32f5df12a8567a0c5f206e203ad Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 15 Oct 2018 19:48:13 +0200 Subject: [PATCH 0155/1650] generate_expected_output.py: match tst_selftest's test environments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The testlib selftest sets various things in the environment for crashing tests; the generator for its expected output should set the same things, as they affect what output is produced. Change-Id: Iec2ed59982ea1043582573530c33619d8e8ed08e Reviewed-by: Jędrzej Nowacki --- .../selftests/generate_expected_output.py | 23 +++++++++++++++++-- .../auto/testlib/selftests/tst_selftests.cpp | 3 +++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/tests/auto/testlib/selftests/generate_expected_output.py b/tests/auto/testlib/selftests/generate_expected_output.py index 1996416e8c..3c5f922c75 100755 --- a/tests/auto/testlib/selftests/generate_expected_output.py +++ b/tests/auto/testlib/selftests/generate_expected_output.py @@ -223,6 +223,7 @@ del re def generateTestData(testname, clean, formats = ('xml', 'txt', 'xunitxml', 'lightxml', 'teamcity', 'tap'), + # Make sure this matches tst_Selftests::runSubTest_data(): extraArgs = { "commandlinedata": "fiveTablePasses fiveTablePasses:fiveTablePasses_data1 -v2", "benchlibcallgrind": "-callgrind", @@ -236,7 +237,15 @@ def generateTestData(testname, clean, "silent": "-silent", "verbose1": "-v1", "verbose2": "-v2", - }): + }, + # Make sure this matches tst_Selftests::doRunSubTest(): + extraEnv = { + "crashes": { "QTEST_DISABLE_CORE_DUMP": "1", "QTEST_DISABLE_STACK_DUMP": "1" }, + }, + # These are actually *other* crashers, beside those in extraEnv; + # must match tst_Selftests::runSubTest_data(): + crashers = ("assert", "blacklisted", "crashedterminate", + "exceptionthrow", "fetchbogus", "silent")): """Run one test and save its cleaned results. Required arguments are the name of the test directory (the binary @@ -248,6 +257,16 @@ def generateTestData(testname, clean, if not os.path.isfile(path): print("Warning: directory", testname, "contains no test executable") return + env = None + try: + env = extraEnv[testname] + except KeyError: + if env in crashers: + env = extraEnv["crashes"] + if env: + data = os.environ.copy() + data.update(env) + env = data print(" running", testname) for format in formats: @@ -255,7 +274,7 @@ def generateTestData(testname, clean, if testname in extraArgs: cmd += extraArgs[testname].split() - data = subprocess.Popen(cmd, stdout=subprocess.PIPE, + data = subprocess.Popen(cmd, stdout=subprocess.PIPE, env=env, universal_newlines=True).communicate()[0] with open('expected_' + testname + '.' + format, 'w') as out: out.write('\n'.join(clean(data))) # write() appends a newline, too diff --git a/tests/auto/testlib/selftests/tst_selftests.cpp b/tests/auto/testlib/selftests/tst_selftests.cpp index 2d3cfaf176..008cce6218 100644 --- a/tests/auto/testlib/selftests/tst_selftests.cpp +++ b/tests/auto/testlib/selftests/tst_selftests.cpp @@ -520,6 +520,7 @@ void tst_Selftests::runSubTest_data() foreach (QString const& subtest, tests) { QStringList arguments = loggerSet.arguments; + // Keep in sync with generateTestData()'s extraArgs in generate_expected_output.py: if (subtest == "commandlinedata") { arguments << QString("fiveTablePasses fiveTablePasses:fiveTablePasses_data1 -v2").split(' '); } @@ -612,6 +613,7 @@ void tst_Selftests::runSubTest_data() if (loggerSet.name.contains("teamcity") && subtest.startsWith("benchlib")) continue; // Skip benchmark for TeamCity logger + // Keep in sync with generateTestData()'s crashers in generate_expected_output.py: const bool crashes = subtest == QLatin1String("assert") || subtest == QLatin1String("exceptionthrow") || subtest == QLatin1String("fetchbogus") || subtest == QLatin1String("crashedterminate") || subtest == QLatin1String("crashes") || subtest == QLatin1String("silent") @@ -687,6 +689,7 @@ void tst_Selftests::doRunSubTest(QString const& subdir, QStringList const& logge QProcess proc; QProcessEnvironment environment = processEnvironment(); + // Keep in sync with generateTestData()'s extraEnv in generate_expected_output.py: if (crashes) { environment.insert("QTEST_DISABLE_CORE_DUMP", "1"); environment.insert("QTEST_DISABLE_STACK_DUMP", "1"); From e089989bac6d241bb8dd88c88cb71668de09b25c Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 18 Oct 2018 09:27:52 +0200 Subject: [PATCH 0156/1650] Dedent a block of code in a namespace for consistency with the rest of the block MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I98920db658547f5301d31ffdc9efb6fdd6f6fc5a Reviewed-by: Jędrzej Nowacki --- src/testlib/qtestcase.cpp | 98 +++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index ea147f1b0f..be93ee4ea0 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -282,74 +282,74 @@ namespace QTestPrivate namespace QTest { - class WatchDog; +class WatchDog; - static QObject *currentTestObject = 0; - static QString mainSourcePath; +static QObject *currentTestObject = 0; +static QString mainSourcePath; #if defined(Q_OS_MACOS) - bool macNeedsActivate = false; - IOPMAssertionID powerID; +bool macNeedsActivate = false; +IOPMAssertionID powerID; #endif - class TestMethods { - Q_DISABLE_COPY(TestMethods) +class TestMethods { + Q_DISABLE_COPY(TestMethods) public: - typedef std::vector MetaMethods; + typedef std::vector MetaMethods; - explicit TestMethods(const QObject *o, const MetaMethods &m = MetaMethods()); + explicit TestMethods(const QObject *o, const MetaMethods &m = MetaMethods()); - void invokeTests(QObject *testObject) const; + void invokeTests(QObject *testObject) const; - static QMetaMethod findMethod(const QObject *obj, const char *signature); + static QMetaMethod findMethod(const QObject *obj, const char *signature); - private: - bool invokeTest(int index, const char *data, WatchDog *watchDog) const; - void invokeTestOnData(int index) const; +private: + bool invokeTest(int index, const char *data, WatchDog *watchDog) const; + void invokeTestOnData(int index) const; - QMetaMethod m_initTestCaseMethod; // might not exist, check isValid(). - QMetaMethod m_initTestCaseDataMethod; - QMetaMethod m_cleanupTestCaseMethod; - QMetaMethod m_initMethod; - QMetaMethod m_cleanupMethod; + QMetaMethod m_initTestCaseMethod; // might not exist, check isValid(). + QMetaMethod m_initTestCaseDataMethod; + QMetaMethod m_cleanupTestCaseMethod; + QMetaMethod m_initMethod; + QMetaMethod m_cleanupMethod; - MetaMethods m_methods; - }; + MetaMethods m_methods; +}; - TestMethods::TestMethods(const QObject *o, const MetaMethods &m) - : m_initTestCaseMethod(TestMethods::findMethod(o, "initTestCase()")) - , m_initTestCaseDataMethod(TestMethods::findMethod(o, "initTestCase_data()")) - , m_cleanupTestCaseMethod(TestMethods::findMethod(o, "cleanupTestCase()")) - , m_initMethod(TestMethods::findMethod(o, "init()")) - , m_cleanupMethod(TestMethods::findMethod(o, "cleanup()")) - , m_methods(m) - { - if (m.empty()) { - const QMetaObject *metaObject = o->metaObject(); - const int count = metaObject->methodCount(); - m_methods.reserve(count); - for (int i = 0; i < count; ++i) { - const QMetaMethod me = metaObject->method(i); - if (isValidSlot(me)) - m_methods.push_back(me); - } +TestMethods::TestMethods(const QObject *o, const MetaMethods &m) + : m_initTestCaseMethod(TestMethods::findMethod(o, "initTestCase()")) + , m_initTestCaseDataMethod(TestMethods::findMethod(o, "initTestCase_data()")) + , m_cleanupTestCaseMethod(TestMethods::findMethod(o, "cleanupTestCase()")) + , m_initMethod(TestMethods::findMethod(o, "init()")) + , m_cleanupMethod(TestMethods::findMethod(o, "cleanup()")) + , m_methods(m) +{ + if (m.empty()) { + const QMetaObject *metaObject = o->metaObject(); + const int count = metaObject->methodCount(); + m_methods.reserve(count); + for (int i = 0; i < count; ++i) { + const QMetaMethod me = metaObject->method(i); + if (isValidSlot(me)) + m_methods.push_back(me); } } +} - QMetaMethod TestMethods::findMethod(const QObject *obj, const char *signature) - { - const QMetaObject *metaObject = obj->metaObject(); - const int funcIndex = metaObject->indexOfMethod(signature); - return funcIndex >= 0 ? metaObject->method(funcIndex) : QMetaMethod(); - } +QMetaMethod TestMethods::findMethod(const QObject *obj, const char *signature) +{ + const QMetaObject *metaObject = obj->metaObject(); + const int funcIndex = metaObject->indexOfMethod(signature); + return funcIndex >= 0 ? metaObject->method(funcIndex) : QMetaMethod(); +} - static int keyDelay = -1; - static int mouseDelay = -1; - static int eventDelay = -1; +static int keyDelay = -1; +static int mouseDelay = -1; +static int eventDelay = -1; #if QT_CONFIG(thread) - static int timeout = -1; +static int timeout = -1; #endif - static bool noCrashHandler = false; +static bool noCrashHandler = false; /*! \internal Invoke a method of the object without generating warning if the method does not exist From 35bba2cac5fb13ab07d2bfd3fee1d9284e8620b5 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 18 Oct 2018 10:22:32 +0200 Subject: [PATCH 0157/1650] More const; don't take mutable char *argv[] where const is all we need MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QTest::qtest_qParseArgs() takes a needlessly mutable parameter. This needs transient legacy version until qtdeclarative is converted to use the const-qualified variant. Change-Id: I19fad25423f6f1ea7d5fac537815f4f633ac4405 Reviewed-by: Jędrzej Nowacki --- src/testlib/qtestcase.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index be93ee4ea0..f21c2c9fde 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -496,7 +496,7 @@ static void qPrintDataTags(FILE *stream) } } -static int qToInt(char *str) +static int qToInt(const char *str) { char *pEnd; int l = (int)strtol(str, &pEnd, 10); @@ -507,7 +507,7 @@ static int qToInt(char *str) return l; } -Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml) +Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, const char *const argv[], bool qml) { QTestLog::LogMode logFormat = QTestLog::Plain; const char *logFilename = 0; @@ -845,6 +845,11 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml) QTestLog::addLogger(logFormat, logFilename); } +// Temporary, backwards compatibility, until qtdeclarative's use of it is converted +Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml) { + qtest_qParseArgs(argc, const_cast(argv), qml); +} + QBenchmarkResult qMedian(const QVector &container) { const int count = container.count(); From f00b72f133665be30280e8e5d844824ce072d6e9 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Fri, 12 Oct 2018 17:47:43 +0200 Subject: [PATCH 0158/1650] Remove some unused code from QTestCoreList MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A count(T *list) was declared but not defined; and the plain count() that was defined isn't called by anything. It's in a private header, so can be removed without harm. Task-number: QTPM-1385 Change-Id: I1ac580d57996895a4123b4f55fa984e9c8001ecb Reviewed-by: Jędrzej Nowacki --- src/testlib/qtestcorelist_p.h | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/testlib/qtestcorelist_p.h b/src/testlib/qtestcorelist_p.h index 5943695876..4d080f6758 100644 --- a/src/testlib/qtestcorelist_p.h +++ b/src/testlib/qtestcorelist_p.h @@ -66,9 +66,6 @@ class QTestCoreList void addToList(T **list); T *nextElement(); T *previousElement(); - int count(T *list); - int count(); - private: T *next; T *prev; @@ -121,20 +118,6 @@ T *QTestCoreList::previousElement() return prev; } -template -int QTestCoreList::count() -{ - int numOfElements = 0; - T *it = next; - - while (it) { - ++numOfElements; - it = it->nextElement(); - } - - return numOfElements; -} - QT_END_NAMESPACE #endif From 33d7f76f0e847d7e0fb00dd6056e7bba45b8b1e7 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 11 Oct 2018 15:11:38 +0200 Subject: [PATCH 0159/1650] Tweak a selftest blacklist to exercise more of the blacklisting code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the process, corrected an inaccurate XFAIL message (an XPASS is normally an error, unless blacklisting ignores it so turns it into a BPASS). Added the missing .tap file to its expected output. Documented the similarity to the silent/ selftest. Task-number: QTPM-1385 Change-Id: Id74a1353d54af2f3bfe2c764e33c1f051958ab21 Reviewed-by: Jędrzej Nowacki --- .../testlib/selftests/blacklisted/BLACKLIST | 14 ++++-- .../selftests/blacklisted/tst_blacklisted.cpp | 5 ++- .../selftests/expected_blacklisted.lightxml | 2 +- .../selftests/expected_blacklisted.tap | 43 +++++++++++++++++++ .../selftests/expected_blacklisted.teamcity | 2 +- .../selftests/expected_blacklisted.txt | 2 +- .../selftests/expected_blacklisted.xml | 2 +- .../selftests/expected_blacklisted.xunitxml | 4 +- 8 files changed, 63 insertions(+), 11 deletions(-) create mode 100644 tests/auto/testlib/selftests/expected_blacklisted.tap diff --git a/tests/auto/testlib/selftests/blacklisted/BLACKLIST b/tests/auto/testlib/selftests/blacklisted/BLACKLIST index 36b7699cbd..a923c11416 100644 --- a/tests/auto/testlib/selftests/blacklisted/BLACKLIST +++ b/tests/auto/testlib/selftests/blacklisted/BLACKLIST @@ -1,12 +1,20 @@ -[pass] +obscure # no such platform; is ignored * + +[pass] +!* + [skip] * + [fail] * -[xpass] -* + [xfail] * + +[xpass] +* + [messages] * diff --git a/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp b/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp index 8578752e22..90520385ec 100644 --- a/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp +++ b/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp @@ -45,7 +45,8 @@ private slots: void messages(); }; -// All the tests below have been blacklisted in blacklisted/BLACKLIST +// All the tests below except pass() have been blacklisted in blacklisted/BLACKLIST +// Contrast with ../silent/, for the same tests without blacklisting but with -silent void tst_Blacklisted::pass() { @@ -64,7 +65,7 @@ void tst_Blacklisted::fail() void tst_Blacklisted::xfail() { - QEXPECT_FAIL("", "This test should XFAIL then BFAIL", Abort); + QEXPECT_FAIL("", "This test should XFAIL then BPASS", Abort); QVERIFY(false); } diff --git a/tests/auto/testlib/selftests/expected_blacklisted.lightxml b/tests/auto/testlib/selftests/expected_blacklisted.lightxml index 4193628e7c..98d7a38ca9 100644 --- a/tests/auto/testlib/selftests/expected_blacklisted.lightxml +++ b/tests/auto/testlib/selftests/expected_blacklisted.lightxml @@ -25,7 +25,7 @@ - + diff --git a/tests/auto/testlib/selftests/expected_blacklisted.tap b/tests/auto/testlib/selftests/expected_blacklisted.tap new file mode 100644 index 0000000000..f26155ded0 --- /dev/null +++ b/tests/auto/testlib/selftests/expected_blacklisted.tap @@ -0,0 +1,43 @@ +TAP version 13 +# tst_Blacklisted +ok 1 - initTestCase() +ok 2 - pass() # TODO +ok 3 - skip() # SKIP This test should SKIP +not ok 4 - fail() # TODO 'false' returned FALSE. (This test should BFAIL) + --- + type: QVERIFY + message: This test should BFAIL + wanted: true (false) + found: false (false) + expected: true (false) + actual: false (false) + at: tst_Blacklisted::fail() (qtbase/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp:63) + file: qtbase/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp + line: 63 + ... +not ok 5 - xfail() # TODO This test should XFAIL then BPASS + --- + at: tst_Blacklisted::xfail() (qtbase/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp:69) + file: qtbase/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp + line: 69 + ... +ok 5 - xfail() # TODO +ok 6 - xpass() # TODO 'true' returned TRUE unexpectedly. (This test should XPASS, blacklist ignored for XPASS) +# This is a warning that should not appear in silent test output +# This is an internal testlib warning that should not appear in silent test output +# This is a debug message that should not appear in silent test output +# This is a critical message that should not appear in silent test output +# This is an info message that should not appear in silent test output +# This is an internal testlib info message that should not appear in silent test output +# This is a fatal error message that should still appear in silent test output +not ok 7 - messages() # TODO Received a fatal error. + --- + # Received a fatal error. + at: tst_Blacklisted::messages() (Unknown file:0) + file: Unknown file + line: 0 + ... +1..7 +# tests 7 +# pass 1 +# fail 1 diff --git a/tests/auto/testlib/selftests/expected_blacklisted.teamcity b/tests/auto/testlib/selftests/expected_blacklisted.teamcity index 8180a7ce76..df58208fb3 100644 --- a/tests/auto/testlib/selftests/expected_blacklisted.teamcity +++ b/tests/auto/testlib/selftests/expected_blacklisted.teamcity @@ -7,7 +7,7 @@ ##teamcity[testStarted name='fail()' flowId='tst_Blacklisted'] ##teamcity[testFinished name='fail()' flowId='tst_Blacklisted'] ##teamcity[testStarted name='xfail()' flowId='tst_Blacklisted'] -##teamcity[testStdOut name='xfail()' out='XFAIL |[Loc: qtbase/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp(0)|]: This test should XFAIL then BFAIL' flowId='tst_Blacklisted'] +##teamcity[testStdOut name='xfail()' out='XFAIL |[Loc: qtbase/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp(0)|]: This test should XFAIL then BPASS' flowId='tst_Blacklisted'] ##teamcity[testFinished name='xfail()' flowId='tst_Blacklisted'] ##teamcity[testStarted name='xpass()' flowId='tst_Blacklisted'] ##teamcity[testFailed name='xpass()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp(0)|]' details='|'true|' returned TRUE unexpectedly. (This test should XPASS, blacklist ignored for XPASS)' flowId='tst_Blacklisted'] diff --git a/tests/auto/testlib/selftests/expected_blacklisted.txt b/tests/auto/testlib/selftests/expected_blacklisted.txt index 6fa2403b59..3cfe40eb12 100644 --- a/tests/auto/testlib/selftests/expected_blacklisted.txt +++ b/tests/auto/testlib/selftests/expected_blacklisted.txt @@ -6,7 +6,7 @@ SKIP : tst_Blacklisted::skip() This test should SKIP Loc: [qtbase/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp(0)] BFAIL : tst_Blacklisted::fail() 'false' returned FALSE. (This test should BFAIL) Loc: [qtbase/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp(0)] -XFAIL : tst_Blacklisted::xfail() This test should XFAIL then BFAIL +XFAIL : tst_Blacklisted::xfail() This test should XFAIL then BPASS Loc: [qtbase/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp(0)] BPASS : tst_Blacklisted::xfail() XPASS : tst_Blacklisted::xpass() 'true' returned TRUE unexpectedly. (This test should XPASS, blacklist ignored for XPASS) diff --git a/tests/auto/testlib/selftests/expected_blacklisted.xml b/tests/auto/testlib/selftests/expected_blacklisted.xml index 443bc6b199..f0387bae00 100644 --- a/tests/auto/testlib/selftests/expected_blacklisted.xml +++ b/tests/auto/testlib/selftests/expected_blacklisted.xml @@ -27,7 +27,7 @@ - + diff --git a/tests/auto/testlib/selftests/expected_blacklisted.xunitxml b/tests/auto/testlib/selftests/expected_blacklisted.xunitxml index 2752bc18b4..e2d0cd009b 100644 --- a/tests/auto/testlib/selftests/expected_blacklisted.xunitxml +++ b/tests/auto/testlib/selftests/expected_blacklisted.xunitxml @@ -12,7 +12,7 @@ - + @@ -28,7 +28,7 @@ - + From c03803b9b37572b79a73dc33eb9f1efc9254d9da Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 24 Oct 2018 16:07:24 +0200 Subject: [PATCH 0160/1650] Clean up some array dereferncing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use array dereferencing notation ptr[expr] rather than the more verbose and less readable *(ptr + expr). Change-Id: Ie98986e7f622aa1a94f3f14bc362ed65767f9d92 Reviewed-by: Jędrzej Nowacki --- src/testlib/qtestcase.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index f21c2c9fde..59ea4c194c 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -811,9 +811,9 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, const char *const argv[], bool // we load the QML files. So just store the data for now. int colon = -1; int offset; - for (offset = 0; *(argv[i]+offset); ++offset) { - if (*(argv[i]+offset) == ':') { - if (*(argv[i]+offset+1) == ':') { + for (offset = 0; argv[i][offset]; ++offset) { + if (argv[i][offset] == ':') { + if (argv[i][offset + 1] == ':') { // "::" is used as a test name separator. // e.g. "ClickTests::test_click:row1". ++offset; From eafad93c3da9fae0e0445393a5a8d90348ae2e13 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 31 Oct 2018 15:15:02 +0100 Subject: [PATCH 0161/1650] Make util/lexgen/ mention itself in its auto-gen line In the process, update the README's e-mail address for Simon and mention all recognized command-line options in the usage message. The generated CSS scanner was also out of sync with our source, so update it. Also fixed handling of FileHeader to cope with running from a shadow build by handling paths relative to __FILE__; and revised the CSS3 config to use the same copyright header as was already in use by the existing generated file. Change-Id: I918ff84dbdc95d0478fd6aa4ea74e9a221d1a476 Reviewed-by: Simon Hausmann --- src/gui/text/qcssscanner.cpp | 1013 ++++++++++++++-------------- util/lexgen/README | 3 +- util/lexgen/css3-simplified.lexgen | 2 +- util/lexgen/generator.cpp | 15 +- util/lexgen/main.cpp | 2 +- 5 files changed, 518 insertions(+), 517 deletions(-) diff --git a/src/gui/text/qcssscanner.cpp b/src/gui/text/qcssscanner.cpp index 33dc01c8bc..d48cbb71d7 100644 --- a/src/gui/text/qcssscanner.cpp +++ b/src/gui/text/qcssscanner.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -37,7 +37,7 @@ ** ****************************************************************************/ -// auto generated. DO NOT EDIT. +// auto generated by qtbase/util/lexgen/. DO NOT EDIT. class QCssScanner_Generated { public: @@ -75,23 +75,23 @@ int QCssScanner_Generated::lex() // initial state ch = next(); if (ch.unicode() >= 9 && ch.unicode() <= 10) - goto state_1; + goto state_4; if (ch.unicode() >= 12 && ch.unicode() <= 13) - goto state_1; + goto state_4; if (ch.unicode() == 32) - goto state_1; + goto state_4; if (ch.unicode() == 33) { token = QCss::EXCLAMATION_SYM; goto found; } if (ch.unicode() == 34) - goto state_3; + goto state_2; if (ch.unicode() == 35) - goto state_4; + goto state_1; if (ch.unicode() == 36) - goto state_5; - if (ch.unicode() == 39) goto state_6; + if (ch.unicode() == 39) + goto state_5; if (ch.unicode() == 40) { token = QCss::LPAREN; goto found; @@ -101,17 +101,17 @@ int QCssScanner_Generated::lex() goto found; } if (ch.unicode() == 42) - goto state_9; + goto state_8; if (ch.unicode() == 43) - goto state_10; + goto state_7; if (ch.unicode() == 44) - goto state_11; - if (ch.unicode() == 45) - goto state_12; - if (ch.unicode() == 46) - goto state_13; - if (ch.unicode() == 47) goto state_14; + if (ch.unicode() == 45) + goto state_13; + if (ch.unicode() == 46) + goto state_12; + if (ch.unicode() == 47) + goto state_11; if (ch.unicode() >= 48 && ch.unicode() <= 57) goto state_15; if (ch.unicode() == 58) { @@ -123,64 +123,56 @@ int QCssScanner_Generated::lex() goto found; } if (ch.unicode() == 60) - goto state_18; + goto state_20; if (ch.unicode() == 61) { token = QCss::EQUAL; goto found; } if (ch.unicode() == 62) - goto state_20; + goto state_18; if (ch.unicode() == 64) - goto state_21; + goto state_26; if (ch.unicode() == 91) { token = QCss::LBRACKET; goto found; } if (ch.unicode() == 92) - goto state_23; + goto state_30; if (ch.unicode() == 93) { token = QCss::RBRACKET; goto found; } if (ch.unicode() == 94) - goto state_25; - if (ch.unicode() == 95) - goto state_26; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_26; - if (ch.unicode() == 123) - goto state_27; - if (ch.unicode() == 124) goto state_28; + if (ch.unicode() == 95) + goto state_21; + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) + goto state_21; + if (ch.unicode() == 123) + goto state_22; + if (ch.unicode() == 124) + goto state_25; if (ch.unicode() == 125) { token = QCss::RBRACE; goto found; } if (ch.unicode() == 126) - goto state_30; + goto state_23; goto out; state_1: - lastAcceptingPos = pos; - token = QCss::S; ch = next(); - if (ch.unicode() >= 9 && ch.unicode() <= 10) + if (ch.unicode() == 45) goto state_31; - if (ch.unicode() >= 12 && ch.unicode() <= 13) + if (ch.unicode() >= 48 && ch.unicode() <= 57) goto state_31; - if (ch.unicode() == 32) - goto state_31; - if (ch.unicode() == 43) - goto state_10; - if (ch.unicode() == 44) - goto state_11; - if (ch.unicode() == 62) - goto state_20; - if (ch.unicode() == 123) - goto state_27; - if (ch.unicode() == 126) + if (ch.unicode() == 92) goto state_32; + if (ch.unicode() == 95) + goto state_31; + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) + goto state_31; goto out; - state_3: + state_2: lastAcceptingPos = pos; token = QCss::INVALID; ch = next(); @@ -204,49 +196,61 @@ int QCssScanner_Generated::lex() goto state_33; goto out; state_4: + lastAcceptingPos = pos; + token = QCss::S; ch = next(); - if (ch.unicode() == 45) + if (ch.unicode() >= 9 && ch.unicode() <= 10) goto state_36; - if (ch.unicode() >= 48 && ch.unicode() <= 57) + if (ch.unicode() >= 12 && ch.unicode() <= 13) goto state_36; - if (ch.unicode() == 92) + if (ch.unicode() == 32) + goto state_36; + if (ch.unicode() == 43) + goto state_7; + if (ch.unicode() == 44) + goto state_14; + if (ch.unicode() == 62) + goto state_18; + if (ch.unicode() == 123) + goto state_22; + if (ch.unicode() == 126) goto state_37; - if (ch.unicode() == 95) - goto state_36; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_36; goto out; state_5: + lastAcceptingPos = pos; + token = QCss::INVALID; + ch = next(); + if (ch.unicode() >= 1 && ch.unicode() <= 9) + goto state_38; + if (ch.unicode() == 11) + goto state_38; + if (ch.unicode() >= 14 && ch.unicode() <= 38) + goto state_38; + if (ch.unicode() == 39) + goto state_39; + if (ch.unicode() >= 40 && ch.unicode() <= 91) + goto state_38; + if (ch.unicode() == 92) + goto state_40; + if (ch.unicode() >= 93 && ch.unicode() <= 96) + goto state_38; + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) + goto state_38; + if (ch.unicode() >= 123) + goto state_38; + goto out; + state_6: ch = next(); if (ch.unicode() == 61) { token = QCss::ENDSWITH; goto found; } goto out; - state_6: + state_7: lastAcceptingPos = pos; - token = QCss::INVALID; - ch = next(); - if (ch.unicode() >= 1 && ch.unicode() <= 9) - goto state_39; - if (ch.unicode() == 11) - goto state_39; - if (ch.unicode() >= 14 && ch.unicode() <= 38) - goto state_39; - if (ch.unicode() == 39) - goto state_40; - if (ch.unicode() >= 40 && ch.unicode() <= 91) - goto state_39; - if (ch.unicode() == 92) - goto state_41; - if (ch.unicode() >= 93 && ch.unicode() <= 96) - goto state_39; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_39; - if (ch.unicode() >= 123) - goto state_39; + token = QCss::PLUS; goto out; - state_9: + state_8: lastAcceptingPos = pos; token = QCss::STAR; ch = next(); @@ -255,35 +259,7 @@ int QCssScanner_Generated::lex() goto found; } goto out; - state_10: - lastAcceptingPos = pos; - token = QCss::PLUS; - goto out; state_11: - lastAcceptingPos = pos; - token = QCss::COMMA; - goto out; - state_12: - lastAcceptingPos = pos; - token = QCss::MINUS; - ch = next(); - if (ch.unicode() == 45) - goto state_43; - if (ch.unicode() == 92) - goto state_23; - if (ch.unicode() == 95) - goto state_26; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_26; - goto out; - state_13: - lastAcceptingPos = pos; - token = QCss::DOT; - ch = next(); - if (ch.unicode() >= 48 && ch.unicode() <= 57) - goto state_44; - goto out; - state_14: lastAcceptingPos = pos; token = QCss::SLASH; ch = next(); @@ -292,6 +268,30 @@ int QCssScanner_Generated::lex() goto found; } goto out; + state_12: + lastAcceptingPos = pos; + token = QCss::DOT; + ch = next(); + if (ch.unicode() >= 48 && ch.unicode() <= 57) + goto state_44; + goto out; + state_13: + lastAcceptingPos = pos; + token = QCss::MINUS; + ch = next(); + if (ch.unicode() == 45) + goto state_45; + if (ch.unicode() == 92) + goto state_30; + if (ch.unicode() == 95) + goto state_21; + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) + goto state_21; + goto out; + state_14: + lastAcceptingPos = pos; + token = QCss::COMMA; + goto out; state_15: lastAcceptingPos = pos; token = QCss::NUMBER; @@ -299,89 +299,49 @@ int QCssScanner_Generated::lex() if (ch.unicode() == 37) goto state_46; if (ch.unicode() == 45) - goto state_47; - if (ch.unicode() == 46) goto state_48; + if (ch.unicode() == 46) + goto state_47; if (ch.unicode() >= 48 && ch.unicode() <= 57) goto state_49; if (ch.unicode() == 92) - goto state_50; + goto state_51; if (ch.unicode() == 95) - goto state_51; + goto state_50; if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_51; + goto state_50; goto out; state_18: + lastAcceptingPos = pos; + token = QCss::GREATER; + goto out; + state_20: ch = next(); if (ch.unicode() == 33) goto state_52; goto out; - state_20: - lastAcceptingPos = pos; - token = QCss::GREATER; - goto out; state_21: - ch = next(); - if (ch.unicode() == 45) - goto state_53; - if (ch.unicode() == 92) - goto state_54; - if (ch.unicode() == 95) - goto state_55; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_55; - goto out; - state_23: - ch = next(); - if (ch.unicode() >= 1 && ch.unicode() <= 9) - goto state_56; - if (ch.unicode() == 11) - goto state_56; - if (ch.unicode() >= 14 && ch.unicode() <= 47) - goto state_56; - if (ch.unicode() >= 58 && ch.unicode() <= 96) - goto state_56; - if (ch.unicode() >= 103) - goto state_56; - goto out; - state_25: - ch = next(); - if (ch.unicode() == 61) { - token = QCss::BEGINSWITH; - goto found; - } - goto out; - state_26: lastAcceptingPos = pos; token = QCss::IDENT; ch = next(); if (ch.unicode() == 40) - goto state_58; + goto state_53; if (ch.unicode() == 45) - goto state_59; + goto state_54; if (ch.unicode() >= 48 && ch.unicode() <= 57) - goto state_59; + goto state_54; if (ch.unicode() == 92) - goto state_60; + goto state_55; if (ch.unicode() == 95) - goto state_59; + goto state_54; if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_59; + goto state_54; goto out; - state_27: + state_22: lastAcceptingPos = pos; token = QCss::LBRACE; goto out; - state_28: - lastAcceptingPos = pos; - token = QCss::OR; - ch = next(); - if (ch.unicode() == 61) { - token = QCss::DASHMATCH; - goto found; - } - goto out; - state_30: + state_23: lastAcceptingPos = pos; token = QCss::TILDE; ch = next(); @@ -390,30 +350,73 @@ int QCssScanner_Generated::lex() goto found; } goto out; + state_25: + lastAcceptingPos = pos; + token = QCss::OR; + ch = next(); + if (ch.unicode() == 61) { + token = QCss::DASHMATCH; + goto found; + } + goto out; + state_26: + ch = next(); + if (ch.unicode() == 45) + goto state_58; + if (ch.unicode() == 92) + goto state_60; + if (ch.unicode() == 95) + goto state_59; + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) + goto state_59; + goto out; + state_28: + ch = next(); + if (ch.unicode() == 61) { + token = QCss::BEGINSWITH; + goto found; + } + goto out; + state_30: + ch = next(); + if (ch.unicode() >= 1 && ch.unicode() <= 9) + goto state_62; + if (ch.unicode() == 11) + goto state_62; + if (ch.unicode() >= 14 && ch.unicode() <= 47) + goto state_62; + if (ch.unicode() >= 58 && ch.unicode() <= 96) + goto state_62; + if (ch.unicode() >= 103) + goto state_62; + goto out; state_31: lastAcceptingPos = pos; - token = QCss::S; + token = QCss::HASH; ch = next(); - if (ch.unicode() >= 9 && ch.unicode() <= 10) - goto state_31; - if (ch.unicode() >= 12 && ch.unicode() <= 13) - goto state_31; - if (ch.unicode() == 32) - goto state_31; - if (ch.unicode() == 43) - goto state_10; - if (ch.unicode() == 44) - goto state_11; - if (ch.unicode() == 62) - goto state_20; - if (ch.unicode() == 123) - goto state_27; - if (ch.unicode() == 126) - goto state_32; + if (ch.unicode() == 45) + goto state_63; + if (ch.unicode() >= 48 && ch.unicode() <= 57) + goto state_63; + if (ch.unicode() == 92) + goto state_64; + if (ch.unicode() == 95) + goto state_63; + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) + goto state_63; goto out; state_32: - lastAcceptingPos = pos; - token = QCss::TILDE; + ch = next(); + if (ch.unicode() >= 1 && ch.unicode() <= 9) + goto state_65; + if (ch.unicode() == 11) + goto state_65; + if (ch.unicode() >= 14 && ch.unicode() <= 47) + goto state_65; + if (ch.unicode() >= 58 && ch.unicode() <= 96) + goto state_65; + if (ch.unicode() >= 103) + goto state_65; goto out; state_33: lastAcceptingPos = pos; @@ -445,78 +448,75 @@ int QCssScanner_Generated::lex() state_35: ch = next(); if (ch.unicode() >= 1 && ch.unicode() <= 9) - goto state_63; - if (ch.unicode() == 10) - goto state_64; - if (ch.unicode() == 11) - goto state_63; - if (ch.unicode() == 12) - goto state_65; - if (ch.unicode() == 13) goto state_66; + if (ch.unicode() == 10) + goto state_67; + if (ch.unicode() == 11) + goto state_66; + if (ch.unicode() == 12) + goto state_69; + if (ch.unicode() == 13) + goto state_68; if (ch.unicode() >= 14 && ch.unicode() <= 47) - goto state_63; + goto state_66; if (ch.unicode() >= 58 && ch.unicode() <= 96) - goto state_63; + goto state_66; if (ch.unicode() >= 103) - goto state_63; + goto state_66; goto out; state_36: lastAcceptingPos = pos; - token = QCss::HASH; + token = QCss::S; ch = next(); - if (ch.unicode() == 45) - goto state_67; - if (ch.unicode() >= 48 && ch.unicode() <= 57) - goto state_67; - if (ch.unicode() == 92) - goto state_68; - if (ch.unicode() == 95) - goto state_67; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_67; + if (ch.unicode() >= 9 && ch.unicode() <= 10) + goto state_36; + if (ch.unicode() >= 12 && ch.unicode() <= 13) + goto state_36; + if (ch.unicode() == 32) + goto state_36; + if (ch.unicode() == 43) + goto state_7; + if (ch.unicode() == 44) + goto state_14; + if (ch.unicode() == 62) + goto state_18; + if (ch.unicode() == 123) + goto state_22; + if (ch.unicode() == 126) + goto state_37; goto out; state_37: - ch = next(); - if (ch.unicode() >= 1 && ch.unicode() <= 9) - goto state_69; - if (ch.unicode() == 11) - goto state_69; - if (ch.unicode() >= 14 && ch.unicode() <= 47) - goto state_69; - if (ch.unicode() >= 58 && ch.unicode() <= 96) - goto state_69; - if (ch.unicode() >= 103) - goto state_69; + lastAcceptingPos = pos; + token = QCss::TILDE; goto out; - state_39: + state_38: lastAcceptingPos = pos; token = QCss::INVALID; ch = next(); if (ch.unicode() >= 1 && ch.unicode() <= 9) - goto state_39; + goto state_38; if (ch.unicode() == 11) - goto state_39; + goto state_38; if (ch.unicode() >= 14 && ch.unicode() <= 38) - goto state_39; + goto state_38; if (ch.unicode() == 39) - goto state_40; + goto state_39; if (ch.unicode() >= 40 && ch.unicode() <= 91) - goto state_39; + goto state_38; if (ch.unicode() == 92) - goto state_41; + goto state_40; if (ch.unicode() >= 93 && ch.unicode() <= 96) - goto state_39; + goto state_38; if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_39; + goto state_38; if (ch.unicode() >= 123) - goto state_39; + goto state_38; goto out; - state_40: + state_39: lastAcceptingPos = pos; token = QCss::STRING; goto out; - state_41: + state_40: ch = next(); if (ch.unicode() >= 1 && ch.unicode() <= 9) goto state_70; @@ -525,9 +525,9 @@ int QCssScanner_Generated::lex() if (ch.unicode() == 11) goto state_70; if (ch.unicode() == 12) - goto state_72; - if (ch.unicode() == 13) goto state_73; + if (ch.unicode() == 13) + goto state_72; if (ch.unicode() >= 14 && ch.unicode() <= 47) goto state_70; if (ch.unicode() >= 58 && ch.unicode() <= 96) @@ -535,13 +535,6 @@ int QCssScanner_Generated::lex() if (ch.unicode() >= 103) goto state_70; goto out; - state_43: - ch = next(); - if (ch.unicode() == 62) { - token = QCss::CDC; - goto found; - } - goto out; state_44: lastAcceptingPos = pos; token = QCss::NUMBER; @@ -549,15 +542,22 @@ int QCssScanner_Generated::lex() if (ch.unicode() == 37) goto state_46; if (ch.unicode() == 45) - goto state_47; + goto state_48; if (ch.unicode() >= 48 && ch.unicode() <= 57) - goto state_75; + goto state_74; if (ch.unicode() == 92) - goto state_50; + goto state_51; if (ch.unicode() == 95) - goto state_51; + goto state_50; if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_51; + goto state_50; + goto out; + state_45: + ch = next(); + if (ch.unicode() == 62) { + token = QCss::CDC; + goto found; + } goto out; state_46: lastAcceptingPos = pos; @@ -565,17 +565,17 @@ int QCssScanner_Generated::lex() goto out; state_47: ch = next(); - if (ch.unicode() == 92) - goto state_50; - if (ch.unicode() == 95) - goto state_51; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_51; + if (ch.unicode() >= 48 && ch.unicode() <= 57) + goto state_44; goto out; state_48: ch = next(); - if (ch.unicode() >= 48 && ch.unicode() <= 57) - goto state_44; + if (ch.unicode() == 92) + goto state_51; + if (ch.unicode() == 95) + goto state_50; + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) + goto state_50; goto out; state_49: lastAcceptingPos = pos; @@ -584,45 +584,45 @@ int QCssScanner_Generated::lex() if (ch.unicode() == 37) goto state_46; if (ch.unicode() == 45) - goto state_47; - if (ch.unicode() == 46) goto state_48; + if (ch.unicode() == 46) + goto state_47; if (ch.unicode() >= 48 && ch.unicode() <= 57) goto state_49; if (ch.unicode() == 92) - goto state_50; + goto state_51; if (ch.unicode() == 95) - goto state_51; + goto state_50; if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_51; + goto state_50; goto out; state_50: - ch = next(); - if (ch.unicode() >= 1 && ch.unicode() <= 9) - goto state_76; - if (ch.unicode() == 11) - goto state_76; - if (ch.unicode() >= 14 && ch.unicode() <= 47) - goto state_76; - if (ch.unicode() >= 58 && ch.unicode() <= 96) - goto state_76; - if (ch.unicode() >= 103) - goto state_76; - goto out; - state_51: lastAcceptingPos = pos; token = QCss::LENGTH; ch = next(); if (ch.unicode() == 45) - goto state_77; + goto state_76; if (ch.unicode() >= 48 && ch.unicode() <= 57) - goto state_77; + goto state_76; if (ch.unicode() == 92) - goto state_78; + goto state_77; if (ch.unicode() == 95) - goto state_77; + goto state_76; if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_77; + goto state_76; + goto out; + state_51: + ch = next(); + if (ch.unicode() >= 1 && ch.unicode() <= 9) + goto state_78; + if (ch.unicode() == 11) + goto state_78; + if (ch.unicode() >= 14 && ch.unicode() <= 47) + goto state_78; + if (ch.unicode() >= 58 && ch.unicode() <= 96) + goto state_78; + if (ch.unicode() >= 103) + goto state_78; goto out; state_52: ch = next(); @@ -630,15 +630,27 @@ int QCssScanner_Generated::lex() goto state_79; goto out; state_53: - ch = next(); - if (ch.unicode() == 92) - goto state_54; - if (ch.unicode() == 95) - goto state_55; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_55; + lastAcceptingPos = pos; + token = QCss::FUNCTION; goto out; state_54: + lastAcceptingPos = pos; + token = QCss::IDENT; + ch = next(); + if (ch.unicode() == 40) + goto state_53; + if (ch.unicode() == 45) + goto state_54; + if (ch.unicode() >= 48 && ch.unicode() <= 57) + goto state_54; + if (ch.unicode() == 92) + goto state_55; + if (ch.unicode() == 95) + goto state_54; + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) + goto state_54; + goto out; + state_55: ch = next(); if (ch.unicode() >= 1 && ch.unicode() <= 9) goto state_80; @@ -651,7 +663,16 @@ int QCssScanner_Generated::lex() if (ch.unicode() >= 103) goto state_80; goto out; - state_55: + state_58: + ch = next(); + if (ch.unicode() == 92) + goto state_60; + if (ch.unicode() == 95) + goto state_59; + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) + goto state_59; + goto out; + state_59: lastAcceptingPos = pos; token = QCss::ATKEYWORD_SYM; ch = next(); @@ -666,44 +687,6 @@ int QCssScanner_Generated::lex() if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) goto state_81; goto out; - state_56: - lastAcceptingPos = pos; - token = QCss::IDENT; - ch = next(); - if (ch.unicode() == 40) - goto state_58; - if (ch.unicode() == 45) - goto state_59; - if (ch.unicode() >= 48 && ch.unicode() <= 57) - goto state_59; - if (ch.unicode() == 92) - goto state_60; - if (ch.unicode() == 95) - goto state_59; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_59; - goto out; - state_58: - lastAcceptingPos = pos; - token = QCss::FUNCTION; - goto out; - state_59: - lastAcceptingPos = pos; - token = QCss::IDENT; - ch = next(); - if (ch.unicode() == 40) - goto state_58; - if (ch.unicode() == 45) - goto state_59; - if (ch.unicode() >= 48 && ch.unicode() <= 57) - goto state_59; - if (ch.unicode() == 92) - goto state_60; - if (ch.unicode() == 95) - goto state_59; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_59; - goto out; state_60: ch = next(); if (ch.unicode() >= 1 && ch.unicode() <= 9) @@ -717,74 +700,65 @@ int QCssScanner_Generated::lex() if (ch.unicode() >= 103) goto state_83; goto out; + state_62: + lastAcceptingPos = pos; + token = QCss::IDENT; + ch = next(); + if (ch.unicode() == 40) + goto state_53; + if (ch.unicode() == 45) + goto state_54; + if (ch.unicode() >= 48 && ch.unicode() <= 57) + goto state_54; + if (ch.unicode() == 92) + goto state_55; + if (ch.unicode() == 95) + goto state_54; + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) + goto state_54; + goto out; state_63: lastAcceptingPos = pos; - token = QCss::INVALID; + token = QCss::HASH; ch = next(); - if (ch.unicode() >= 1 && ch.unicode() <= 9) - goto state_33; - if (ch.unicode() == 11) - goto state_33; - if (ch.unicode() >= 14 && ch.unicode() <= 33) - goto state_33; - if (ch.unicode() == 34) - goto state_34; - if (ch.unicode() >= 35 && ch.unicode() <= 91) - goto state_33; + if (ch.unicode() == 45) + goto state_63; + if (ch.unicode() >= 48 && ch.unicode() <= 57) + goto state_63; if (ch.unicode() == 92) - goto state_35; - if (ch.unicode() >= 93 && ch.unicode() <= 96) - goto state_33; + goto state_64; + if (ch.unicode() == 95) + goto state_63; if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_33; - if (ch.unicode() >= 123) - goto state_33; + goto state_63; goto out; state_64: - lastAcceptingPos = pos; - token = QCss::INVALID; ch = next(); if (ch.unicode() >= 1 && ch.unicode() <= 9) - goto state_33; + goto state_84; if (ch.unicode() == 11) - goto state_33; - if (ch.unicode() >= 14 && ch.unicode() <= 33) - goto state_33; - if (ch.unicode() == 34) - goto state_34; - if (ch.unicode() >= 35 && ch.unicode() <= 91) - goto state_33; - if (ch.unicode() == 92) - goto state_35; - if (ch.unicode() >= 93 && ch.unicode() <= 96) - goto state_33; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_33; - if (ch.unicode() >= 123) - goto state_33; + goto state_84; + if (ch.unicode() >= 14 && ch.unicode() <= 47) + goto state_84; + if (ch.unicode() >= 58 && ch.unicode() <= 96) + goto state_84; + if (ch.unicode() >= 103) + goto state_84; goto out; state_65: lastAcceptingPos = pos; - token = QCss::INVALID; + token = QCss::HASH; ch = next(); - if (ch.unicode() >= 1 && ch.unicode() <= 9) - goto state_33; - if (ch.unicode() == 11) - goto state_33; - if (ch.unicode() >= 14 && ch.unicode() <= 33) - goto state_33; - if (ch.unicode() == 34) - goto state_34; - if (ch.unicode() >= 35 && ch.unicode() <= 91) - goto state_33; + if (ch.unicode() == 45) + goto state_63; + if (ch.unicode() >= 48 && ch.unicode() <= 57) + goto state_63; if (ch.unicode() == 92) - goto state_35; - if (ch.unicode() >= 93 && ch.unicode() <= 96) - goto state_33; + goto state_64; + if (ch.unicode() == 95) + goto state_63; if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_33; - if (ch.unicode() >= 123) - goto state_33; + goto state_63; goto out; state_66: lastAcceptingPos = pos; @@ -792,8 +766,6 @@ int QCssScanner_Generated::lex() ch = next(); if (ch.unicode() >= 1 && ch.unicode() <= 9) goto state_33; - if (ch.unicode() == 10) - goto state_84; if (ch.unicode() == 11) goto state_33; if (ch.unicode() >= 14 && ch.unicode() <= 33) @@ -813,189 +785,202 @@ int QCssScanner_Generated::lex() goto out; state_67: lastAcceptingPos = pos; - token = QCss::HASH; - ch = next(); - if (ch.unicode() == 45) - goto state_67; - if (ch.unicode() >= 48 && ch.unicode() <= 57) - goto state_67; - if (ch.unicode() == 92) - goto state_68; - if (ch.unicode() == 95) - goto state_67; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_67; - goto out; - state_68: + token = QCss::INVALID; ch = next(); if (ch.unicode() >= 1 && ch.unicode() <= 9) + goto state_33; + if (ch.unicode() == 11) + goto state_33; + if (ch.unicode() >= 14 && ch.unicode() <= 33) + goto state_33; + if (ch.unicode() == 34) + goto state_34; + if (ch.unicode() >= 35 && ch.unicode() <= 91) + goto state_33; + if (ch.unicode() == 92) + goto state_35; + if (ch.unicode() >= 93 && ch.unicode() <= 96) + goto state_33; + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) + goto state_33; + if (ch.unicode() >= 123) + goto state_33; + goto out; + state_68: + lastAcceptingPos = pos; + token = QCss::INVALID; + ch = next(); + if (ch.unicode() >= 1 && ch.unicode() <= 9) + goto state_33; + if (ch.unicode() == 10) goto state_85; if (ch.unicode() == 11) - goto state_85; - if (ch.unicode() >= 14 && ch.unicode() <= 47) - goto state_85; - if (ch.unicode() >= 58 && ch.unicode() <= 96) - goto state_85; - if (ch.unicode() >= 103) - goto state_85; + goto state_33; + if (ch.unicode() >= 14 && ch.unicode() <= 33) + goto state_33; + if (ch.unicode() == 34) + goto state_34; + if (ch.unicode() >= 35 && ch.unicode() <= 91) + goto state_33; + if (ch.unicode() == 92) + goto state_35; + if (ch.unicode() >= 93 && ch.unicode() <= 96) + goto state_33; + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) + goto state_33; + if (ch.unicode() >= 123) + goto state_33; goto out; state_69: lastAcceptingPos = pos; - token = QCss::HASH; + token = QCss::INVALID; ch = next(); - if (ch.unicode() == 45) - goto state_67; - if (ch.unicode() >= 48 && ch.unicode() <= 57) - goto state_67; + if (ch.unicode() >= 1 && ch.unicode() <= 9) + goto state_33; + if (ch.unicode() == 11) + goto state_33; + if (ch.unicode() >= 14 && ch.unicode() <= 33) + goto state_33; + if (ch.unicode() == 34) + goto state_34; + if (ch.unicode() >= 35 && ch.unicode() <= 91) + goto state_33; if (ch.unicode() == 92) - goto state_68; - if (ch.unicode() == 95) - goto state_67; + goto state_35; + if (ch.unicode() >= 93 && ch.unicode() <= 96) + goto state_33; if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_67; + goto state_33; + if (ch.unicode() >= 123) + goto state_33; goto out; state_70: lastAcceptingPos = pos; token = QCss::INVALID; ch = next(); if (ch.unicode() >= 1 && ch.unicode() <= 9) - goto state_39; + goto state_38; if (ch.unicode() == 11) - goto state_39; + goto state_38; if (ch.unicode() >= 14 && ch.unicode() <= 38) - goto state_39; + goto state_38; if (ch.unicode() == 39) - goto state_40; + goto state_39; if (ch.unicode() >= 40 && ch.unicode() <= 91) - goto state_39; + goto state_38; if (ch.unicode() == 92) - goto state_41; + goto state_40; if (ch.unicode() >= 93 && ch.unicode() <= 96) - goto state_39; + goto state_38; if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_39; + goto state_38; if (ch.unicode() >= 123) - goto state_39; + goto state_38; goto out; state_71: lastAcceptingPos = pos; token = QCss::INVALID; ch = next(); if (ch.unicode() >= 1 && ch.unicode() <= 9) - goto state_39; + goto state_38; if (ch.unicode() == 11) - goto state_39; + goto state_38; if (ch.unicode() >= 14 && ch.unicode() <= 38) - goto state_39; + goto state_38; if (ch.unicode() == 39) - goto state_40; + goto state_39; if (ch.unicode() >= 40 && ch.unicode() <= 91) - goto state_39; + goto state_38; if (ch.unicode() == 92) - goto state_41; + goto state_40; if (ch.unicode() >= 93 && ch.unicode() <= 96) - goto state_39; + goto state_38; if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_39; + goto state_38; if (ch.unicode() >= 123) - goto state_39; + goto state_38; goto out; state_72: lastAcceptingPos = pos; token = QCss::INVALID; ch = next(); if (ch.unicode() >= 1 && ch.unicode() <= 9) - goto state_39; + goto state_38; + if (ch.unicode() == 10) + goto state_86; if (ch.unicode() == 11) - goto state_39; + goto state_38; if (ch.unicode() >= 14 && ch.unicode() <= 38) - goto state_39; + goto state_38; if (ch.unicode() == 39) - goto state_40; + goto state_39; if (ch.unicode() >= 40 && ch.unicode() <= 91) - goto state_39; + goto state_38; if (ch.unicode() == 92) - goto state_41; + goto state_40; if (ch.unicode() >= 93 && ch.unicode() <= 96) - goto state_39; + goto state_38; if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_39; + goto state_38; if (ch.unicode() >= 123) - goto state_39; + goto state_38; goto out; state_73: lastAcceptingPos = pos; token = QCss::INVALID; ch = next(); if (ch.unicode() >= 1 && ch.unicode() <= 9) - goto state_39; - if (ch.unicode() == 10) - goto state_86; + goto state_38; if (ch.unicode() == 11) - goto state_39; + goto state_38; if (ch.unicode() >= 14 && ch.unicode() <= 38) - goto state_39; + goto state_38; if (ch.unicode() == 39) - goto state_40; + goto state_39; if (ch.unicode() >= 40 && ch.unicode() <= 91) - goto state_39; + goto state_38; if (ch.unicode() == 92) - goto state_41; + goto state_40; if (ch.unicode() >= 93 && ch.unicode() <= 96) - goto state_39; + goto state_38; if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_39; + goto state_38; if (ch.unicode() >= 123) - goto state_39; + goto state_38; goto out; - state_75: + state_74: lastAcceptingPos = pos; token = QCss::NUMBER; ch = next(); if (ch.unicode() == 37) goto state_46; if (ch.unicode() == 45) - goto state_47; + goto state_48; if (ch.unicode() >= 48 && ch.unicode() <= 57) - goto state_75; + goto state_74; if (ch.unicode() == 92) - goto state_50; + goto state_51; if (ch.unicode() == 95) - goto state_51; + goto state_50; if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_51; + goto state_50; goto out; state_76: lastAcceptingPos = pos; token = QCss::LENGTH; ch = next(); if (ch.unicode() == 45) - goto state_77; + goto state_76; if (ch.unicode() >= 48 && ch.unicode() <= 57) - goto state_77; + goto state_76; if (ch.unicode() == 92) - goto state_78; + goto state_77; if (ch.unicode() == 95) - goto state_77; + goto state_76; if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_77; + goto state_76; goto out; state_77: - lastAcceptingPos = pos; - token = QCss::LENGTH; - ch = next(); - if (ch.unicode() == 45) - goto state_77; - if (ch.unicode() >= 48 && ch.unicode() <= 57) - goto state_77; - if (ch.unicode() == 92) - goto state_78; - if (ch.unicode() == 95) - goto state_77; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_77; - goto out; - state_78: ch = next(); if (ch.unicode() >= 1 && ch.unicode() <= 9) goto state_87; @@ -1008,6 +993,21 @@ int QCssScanner_Generated::lex() if (ch.unicode() >= 103) goto state_87; goto out; + state_78: + lastAcceptingPos = pos; + token = QCss::LENGTH; + ch = next(); + if (ch.unicode() == 45) + goto state_76; + if (ch.unicode() >= 48 && ch.unicode() <= 57) + goto state_76; + if (ch.unicode() == 92) + goto state_77; + if (ch.unicode() == 95) + goto state_76; + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) + goto state_76; + goto out; state_79: ch = next(); if (ch.unicode() == 45) { @@ -1017,18 +1017,20 @@ int QCssScanner_Generated::lex() goto out; state_80: lastAcceptingPos = pos; - token = QCss::ATKEYWORD_SYM; + token = QCss::IDENT; ch = next(); + if (ch.unicode() == 40) + goto state_53; if (ch.unicode() == 45) - goto state_81; + goto state_54; if (ch.unicode() >= 48 && ch.unicode() <= 57) - goto state_81; + goto state_54; if (ch.unicode() == 92) - goto state_82; + goto state_55; if (ch.unicode() == 95) - goto state_81; + goto state_54; if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_81; + goto state_54; goto out; state_81: lastAcceptingPos = pos; @@ -1060,22 +1062,35 @@ int QCssScanner_Generated::lex() goto out; state_83: lastAcceptingPos = pos; - token = QCss::IDENT; + token = QCss::ATKEYWORD_SYM; ch = next(); - if (ch.unicode() == 40) - goto state_58; if (ch.unicode() == 45) - goto state_59; + goto state_81; if (ch.unicode() >= 48 && ch.unicode() <= 57) - goto state_59; + goto state_81; if (ch.unicode() == 92) - goto state_60; + goto state_82; if (ch.unicode() == 95) - goto state_59; + goto state_81; if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_59; + goto state_81; goto out; state_84: + lastAcceptingPos = pos; + token = QCss::HASH; + ch = next(); + if (ch.unicode() == 45) + goto state_63; + if (ch.unicode() >= 48 && ch.unicode() <= 57) + goto state_63; + if (ch.unicode() == 92) + goto state_64; + if (ch.unicode() == 95) + goto state_63; + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) + goto state_63; + goto out; + state_85: lastAcceptingPos = pos; token = QCss::INVALID; ch = next(); @@ -1098,58 +1113,43 @@ int QCssScanner_Generated::lex() if (ch.unicode() >= 123) goto state_33; goto out; - state_85: - lastAcceptingPos = pos; - token = QCss::HASH; - ch = next(); - if (ch.unicode() == 45) - goto state_67; - if (ch.unicode() >= 48 && ch.unicode() <= 57) - goto state_67; - if (ch.unicode() == 92) - goto state_68; - if (ch.unicode() == 95) - goto state_67; - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_67; - goto out; state_86: lastAcceptingPos = pos; token = QCss::INVALID; ch = next(); if (ch.unicode() >= 1 && ch.unicode() <= 9) - goto state_39; + goto state_38; if (ch.unicode() == 11) - goto state_39; + goto state_38; if (ch.unicode() >= 14 && ch.unicode() <= 38) - goto state_39; + goto state_38; if (ch.unicode() == 39) - goto state_40; + goto state_39; if (ch.unicode() >= 40 && ch.unicode() <= 91) - goto state_39; + goto state_38; if (ch.unicode() == 92) - goto state_41; + goto state_40; if (ch.unicode() >= 93 && ch.unicode() <= 96) - goto state_39; + goto state_38; if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_39; + goto state_38; if (ch.unicode() >= 123) - goto state_39; + goto state_38; goto out; state_87: lastAcceptingPos = pos; token = QCss::LENGTH; ch = next(); if (ch.unicode() == 45) - goto state_77; + goto state_76; if (ch.unicode() >= 48 && ch.unicode() <= 57) - goto state_77; + goto state_76; if (ch.unicode() == 92) - goto state_78; + goto state_77; if (ch.unicode() == 95) - goto state_77; + goto state_76; if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256) - goto state_77; + goto state_76; goto out; state_89: lastAcceptingPos = pos; @@ -1176,4 +1176,3 @@ int QCssScanner_Generated::lex() } return token; } - diff --git a/util/lexgen/README b/util/lexgen/README index 435c7f31ee..005b77b81c 100644 --- a/util/lexgen/README +++ b/util/lexgen/README @@ -11,6 +11,5 @@ you want. But I like that it generates code that operates on QChar and friends. Use at your own risk ;-) - -- -Simon Hausmann +Simon Hausmann diff --git a/util/lexgen/css3-simplified.lexgen b/util/lexgen/css3-simplified.lexgen index 99463d524e..d86a4786be 100644 --- a/util/lexgen/css3-simplified.lexgen +++ b/util/lexgen/css3-simplified.lexgen @@ -5,7 +5,7 @@ classname = QCssScanner_Generated [Code Generator Options] MapToCode[a-z] = (ch.unicode() >= 'a' && ch.unicode() <= 'z') || (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || ch.unicode() >= 256 TokenPrefix = QCss:: -FileHeader = ../../src/tools/moc/util/licenseheader.txt +FileHeader = ../../header.LGPL [Macros] escape = \\[^\r\n\f0-9a-f] diff --git a/util/lexgen/generator.cpp b/util/lexgen/generator.cpp index edd2b603e7..481d586e73 100644 --- a/util/lexgen/generator.cpp +++ b/util/lexgen/generator.cpp @@ -29,6 +29,7 @@ #include "generator.h" #include +#include void Function::printDeclaration(CodeBlock &block, const QString &funcNamePrefix) const { @@ -505,14 +506,16 @@ QString Generator::generate() klass.addMember(Class::PublicMember, lexFunc); QString header; - QFile headerFile(headerFileName); - if (!headerFileName.isEmpty() - && headerFile.exists() - && headerFile.open(QIODevice::ReadOnly)) { - header = QString::fromUtf8(headerFile.readAll()); + if (!headerFileName.isEmpty()) { + QString self(QDir::fromNativeSeparators(QStringLiteral(__FILE__))); + int lastSep = self.lastIndexOf(QChar('/')); + QDir here(lastSep < 0 ? QStringLiteral(".") : self.left(lastSep)); + QFile headerFile(QDir::cleanPath(here.filePath(headerFileName))); + if (headerFile.exists() && headerFile.open(QIODevice::ReadOnly)) + header = QString::fromUtf8(headerFile.readAll()); } - header += QLatin1String("// auto generated. DO NOT EDIT.\n"); + header += QLatin1String("// auto generated by qtbase/util/lexgen/. DO NOT EDIT.\n"); return header + klass.declaration() + klass.definition(); } diff --git a/util/lexgen/main.cpp b/util/lexgen/main.cpp index 22b99b633c..517629f4c1 100644 --- a/util/lexgen/main.cpp +++ b/util/lexgen/main.cpp @@ -256,7 +256,7 @@ int main(int argc, char **argv) } if (ruleFile.isEmpty()) { - qWarning("usage: lexgen [-test rulefile"); + qWarning("usage: lexgen [-debug] [-cache] [-test] rulefile"); qWarning(" "); qWarning(" the -test option will cause lexgen to interpret standard input"); qWarning(" according to the specified rules and print out pairs of token and"); From d28c241ca1451812fafc0c761587abfa44405914 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Thu, 9 Aug 2018 14:08:04 +0200 Subject: [PATCH 0162/1650] xcb: cleanup _NET_WM_STATE handling Use function name overloading for all of _NET_WM_STATE setters for a mapped window, instead of few similar sounding functions, where all do the same thing. For an unmapped window rename updateNetWmStateBeforeMap() -> setNetWmStateOnUnmappedWindow(). Merge setNetWmStates(NetWmStates) into setNetWmStateOnUnmappedWindow() and add a comment explaining why it does what it does, as it was not obvious. Internally there are 2 variants: a) When a window is already mapped, to change the window state we send XCB_CLIENT_MESSAGE(_NET_WM_STATE) messages to the root window as per EWMH spec. The Window Manager MUST keep this property updated to reflect the current state of the window. If this variant of the overload is called while a window is not mapped yet, it does nothing. WM would ignore this message anyway. The state change is not lost, it will be set later and that is where the second variant comes in. b) On an unmapped window we can set _NET_WM_STATE by using setNetWmStateOnUnmappedWindow(). This function will read QWindow properties and set all of them via one xcb_change_property(_NET_WM_STATE) call. We do this inside QXcbWindow::show(), where we know that QWindow state properties won't change anymore until it gets mapped. Once it is mapped, we use the other variant. This patch doesn't change any functionality, just makes the code easier to follow. Change-Id: I4f4703a35de083fcfd398112eabd0a5aec358e51 Reviewed-by: Frederik Gladhorn --- src/plugins/platforms/xcb/qxcbwindow.cpp | 182 ++++++++++++----------- src/plugins/platforms/xcb/qxcbwindow.h | 11 +- 2 files changed, 100 insertions(+), 93 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index e56f6b13d8..f553c286f9 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -755,7 +755,7 @@ void QXcbWindow::show() xcb_delete_property(xcb_connection(), m_window, XCB_ATOM_WM_TRANSIENT_FOR); // update _NET_WM_STATE - updateNetWmStateBeforeMap(); + setNetWmStateOnUnmappedWindow(); } // QWidget-attribute Qt::WA_ShowWithoutActivating. @@ -961,46 +961,6 @@ QXcbWindow::NetWmStates QXcbWindow::netWmStates() return result; } -void QXcbWindow::setNetWmStates(NetWmStates states) -{ - QVector atoms; - - auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(), - 0, m_window, atom(QXcbAtom::_NET_WM_STATE), - XCB_ATOM_ATOM, 0, 1024); - if (reply && reply->format == 32 && reply->type == XCB_ATOM_ATOM && reply->value_len > 0) { - const xcb_atom_t *data = static_cast(xcb_get_property_value(reply.get())); - atoms.resize(reply->value_len); - memcpy((void *)&atoms.first(), (void *)data, reply->value_len * sizeof(xcb_atom_t)); - } - - if (states & NetWmStateAbove && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_ABOVE))) - atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_ABOVE)); - if (states & NetWmStateBelow && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_BELOW))) - atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_BELOW)); - if (states & NetWmStateFullScreen && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN))) - atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN)); - if (states & NetWmStateMaximizedHorz && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ))) - atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ)); - if (states & NetWmStateMaximizedVert && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT))) - atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT)); - if (states & NetWmStateModal && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MODAL))) - atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MODAL)); - if (states & NetWmStateStaysOnTop && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP))) - atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP)); - if (states & NetWmStateDemandsAttention && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION))) - atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION)); - - if (atoms.isEmpty()) { - xcb_delete_property(xcb_connection(), m_window, atom(QXcbAtom::_NET_WM_STATE)); - } else { - xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, - atom(QXcbAtom::_NET_WM_STATE), XCB_ATOM_ATOM, 32, - atoms.count(), atoms.constData()); - } - xcb_flush(xcb_connection()); -} - void QXcbWindow::setWindowFlags(Qt::WindowFlags flags) { Qt::WindowType type = static_cast(int(flags & Qt::WindowType_Mask)); @@ -1027,7 +987,7 @@ void QXcbWindow::setWindowFlags(Qt::WindowFlags flags) } setWmWindowType(wmWindowTypes, flags); - setNetWmStateWindowFlags(flags); + setNetWmState(flags); setMotifWmHints(flags); setTransparentForMouseEvents(flags & Qt::WindowTransparentForInput); @@ -1111,7 +1071,7 @@ void QXcbWindow::setMotifWmHints(Qt::WindowFlags flags) } } -void QXcbWindow::changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two) +void QXcbWindow::setNetWmState(bool set, xcb_atom_t one, xcb_atom_t two) { xcb_client_message_event_t event; @@ -1131,6 +1091,96 @@ void QXcbWindow::changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two) (const char *)&event); } +void QXcbWindow::setNetWmState(Qt::WindowStates state) +{ + if ((m_windowState ^ state) & Qt::WindowMaximized) { + setNetWmState(state & Qt::WindowMaximized, + atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ), + atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT)); + } + + if ((m_windowState ^ state) & Qt::WindowFullScreen) + setNetWmState(state & Qt::WindowFullScreen, atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN)); +} + +void QXcbWindow::setNetWmState(Qt::WindowFlags flags) +{ + setNetWmState(flags & Qt::WindowStaysOnTopHint, + atom(QXcbAtom::_NET_WM_STATE_ABOVE), + atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP)); + setNetWmState(flags & Qt::WindowStaysOnBottomHint, atom(QXcbAtom::_NET_WM_STATE_BELOW)); +} + +void QXcbWindow::setNetWmStateOnUnmappedWindow() +{ + if (Q_UNLIKELY(m_mapped)) + qCWarning(lcQpaXcb()) << "internal error: " << Q_FUNC_INFO << "called on mapped window"; + + NetWmStates states(0); + const Qt::WindowFlags flags = window()->flags(); + if (flags & Qt::WindowStaysOnTopHint) { + states |= NetWmStateAbove; + states |= NetWmStateStaysOnTop; + } else if (flags & Qt::WindowStaysOnBottomHint) { + states |= NetWmStateBelow; + } + + if (window()->windowStates() & Qt::WindowFullScreen) + states |= NetWmStateFullScreen; + + if (window()->windowStates() & Qt::WindowMaximized) { + states |= NetWmStateMaximizedHorz; + states |= NetWmStateMaximizedVert; + } + + if (window()->modality() != Qt::NonModal) + states |= NetWmStateModal; + + // According to EWMH: + // "The Window Manager should remove _NET_WM_STATE whenever a window is withdrawn". + // Which means that we don't have to read this property before changing it on a withdrawn + // window. But there are situations where users want to adjust this property as well + // (e4cea305ed2ba3c9f580bf9d16c59a1048af0e8a), so instead of overwriting the property + // we first read it and then merge our hints with the existing values, allowing a user + // to set custom hints. + + QVector atoms; + auto reply = Q_XCB_REPLY_UNCHECKED(xcb_get_property, xcb_connection(), + 0, m_window, atom(QXcbAtom::_NET_WM_STATE), + XCB_ATOM_ATOM, 0, 1024); + if (reply && reply->format == 32 && reply->type == XCB_ATOM_ATOM && reply->value_len > 0) { + const xcb_atom_t *data = static_cast(xcb_get_property_value(reply.get())); + atoms.resize(reply->value_len); + memcpy((void *)&atoms.first(), (void *)data, reply->value_len * sizeof(xcb_atom_t)); + } + + if (states & NetWmStateAbove && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_ABOVE))) + atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_ABOVE)); + if (states & NetWmStateBelow && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_BELOW))) + atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_BELOW)); + if (states & NetWmStateFullScreen && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN))) + atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN)); + if (states & NetWmStateMaximizedHorz && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ))) + atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ)); + if (states & NetWmStateMaximizedVert && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT))) + atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT)); + if (states & NetWmStateModal && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MODAL))) + atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MODAL)); + if (states & NetWmStateStaysOnTop && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP))) + atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP)); + if (states & NetWmStateDemandsAttention && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION))) + atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION)); + + if (atoms.isEmpty()) { + xcb_delete_property(xcb_connection(), m_window, atom(QXcbAtom::_NET_WM_STATE)); + } else { + xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, + atom(QXcbAtom::_NET_WM_STATE), XCB_ATOM_ATOM, 32, + atoms.count(), atoms.constData()); + } + xcb_flush(xcb_connection()); +} + void QXcbWindow::setWindowState(Qt::WindowStates state) { if (state == m_windowState) @@ -1158,14 +1208,7 @@ void QXcbWindow::setWindowState(Qt::WindowStates state) m_minimized = true; } - if ((m_windowState ^ state) & Qt::WindowMaximized) { - changeNetWmState(state & Qt::WindowMaximized, atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ), - atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT)); - } - - if ((m_windowState ^ state) & Qt::WindowFullScreen) { - changeNetWmState(state & Qt::WindowFullScreen, atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN)); - } + setNetWmState(state); xcb_get_property_cookie_t cookie = xcb_get_wm_hints_unchecked(xcb_connection(), m_window); xcb_wm_hints_t hints; @@ -1181,41 +1224,6 @@ void QXcbWindow::setWindowState(Qt::WindowStates state) m_windowState = state; } -void QXcbWindow::updateNetWmStateBeforeMap() -{ - NetWmStates states(0); - - const Qt::WindowFlags flags = window()->flags(); - if (flags & Qt::WindowStaysOnTopHint) { - states |= NetWmStateAbove; - states |= NetWmStateStaysOnTop; - } else if (flags & Qt::WindowStaysOnBottomHint) { - states |= NetWmStateBelow; - } - - if (window()->windowStates() & Qt::WindowFullScreen) - states |= NetWmStateFullScreen; - - if (window()->windowStates() & Qt::WindowMaximized) { - states |= NetWmStateMaximizedHorz; - states |= NetWmStateMaximizedVert; - } - - if (window()->modality() != Qt::NonModal) - states |= NetWmStateModal; - - setNetWmStates(states); -} - -void QXcbWindow::setNetWmStateWindowFlags(Qt::WindowFlags flags) -{ - changeNetWmState(flags & Qt::WindowStaysOnTopHint, - atom(QXcbAtom::_NET_WM_STATE_ABOVE), - atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP)); - changeNetWmState(flags & Qt::WindowStaysOnBottomHint, - atom(QXcbAtom::_NET_WM_STATE_BELOW)); -} - void QXcbWindow::updateNetWmUserTime(xcb_timestamp_t timestamp) { xcb_window_t wid = m_window; @@ -2588,7 +2596,7 @@ void QXcbWindow::setAlertState(bool enabled) m_alertState = enabled; - changeNetWmState(enabled, atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION)); + setNetWmState(enabled, atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION)); } uint QXcbWindow::visualId() const diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index d2ca9fe0b9..f98cd8a74d 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -193,17 +193,16 @@ protected: void setImageFormatForVisual(const xcb_visualtype_t *visual); QXcbScreen *parentScreen(); - QXcbScreen *initialScreen() const; - void changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two = 0); + + void setNetWmState(bool set, xcb_atom_t one, xcb_atom_t two = 0); + void setNetWmState(Qt::WindowFlags flags); + void setNetWmState(Qt::WindowStates state); + void setNetWmStateOnUnmappedWindow(); NetWmStates netWmStates(); - void setNetWmStates(NetWmStates); void setMotifWmHints(Qt::WindowFlags flags); - void setNetWmStateWindowFlags(Qt::WindowFlags flags); - void updateNetWmStateBeforeMap(); - void setTransparentForMouseEvents(bool transparent); void updateDoesNotAcceptFocus(bool doesNotAcceptFocus); From 00674a1643422de2e56ac23c89174c0ead83eb18 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 25 Sep 2018 15:02:58 +0200 Subject: [PATCH 0163/1650] Treat shorts as int in QVariant::canConvert() Follow the pattern of char and float, and treat shorts as a more generic type in QVariant::canConvert() Task-number: QTBUG-60914 Change-Id: Ib1cc7941ee47cb0fc0098f22f98a03cd6f6b63fe Reviewed-by: Thiago Macieira --- src/corelib/kernel/qvariant.cpp | 12 +++++++++--- tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp | 8 ++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 0b4c3f387f..6541b97595 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -3523,13 +3523,19 @@ bool QVariant::canConvert(int targetTypeId) const } // TODO Reimplement this function, currently it works but it is a historical mess. - uint currentType = ((d.type == QMetaType::Float) ? QVariant::Double : d.type); + uint currentType = d.type; if (currentType == QMetaType::SChar || currentType == QMetaType::Char) currentType = QMetaType::UInt; if (targetTypeId == QMetaType::SChar || currentType == QMetaType::Char) targetTypeId = QMetaType::UInt; - if (uint(targetTypeId) == uint(QMetaType::Float)) targetTypeId = QVariant::Double; - + if (currentType == QMetaType::Short || currentType == QMetaType::UShort) + currentType = QMetaType::Int; + if (targetTypeId == QMetaType::Short || currentType == QMetaType::UShort) + targetTypeId = QMetaType::Int; + if (currentType == QMetaType::Float) + currentType = QMetaType::Double; + if (targetTypeId == QMetaType::Float) + targetTypeId = QMetaType::Double; if (currentType == uint(targetTypeId)) return true; diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 0780fb9172..4da34c407e 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -525,6 +525,12 @@ void tst_QVariant::canConvert_data() var = QVariant::fromValue(-1); QTest::newRow("SChar") << var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << N << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y; + var = QVariant((short)-3); + QTest::newRow("Short") + << var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << Y << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y; + var = QVariant((ushort)7); + QTest::newRow("UShort") + << var << N << N << Y << N << Y << N << N << N << N << Y << N << N << Y << N << Y << N << Y << N << N << N << N << N << N << N << N << N << Y << N << N << Y << Y; var = QVariant::fromValue(QJsonValue(QStringLiteral("hello"))); QTest::newRow("JsonValue") << var << N << N << Y << N << N << N << N << N << N << Y << N << N << Y << N << N << Y << Y << Y << N << N << N << N << N << N << N << N << Y << N << N << Y << Y; @@ -563,6 +569,8 @@ void tst_QVariant::toInt_data() QTest::newRow( "char" ) << QVariant::fromValue('a') << int('a') << true; signed char signedChar = -13; QTest::newRow( "signed char" ) << QVariant::fromValue(signedChar) << -13 << true; + QTest::newRow( "short" ) << QVariant::fromValue(short(-7)) << int(-7) << true; + QTest::newRow( "ushort" ) << QVariant::fromValue(ushort(30000)) << 30000 << true; QTest::newRow( "double" ) << QVariant( 3.1415927 ) << 3 << true; QTest::newRow( "float" ) << QVariant( 3.1415927f ) << 3 << true; QTest::newRow( "uint" ) << QVariant( 123u ) << 123 << true; From c6af950bfd79182eb21438fa63096d4509f90404 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 23 Oct 2018 16:11:10 +0200 Subject: [PATCH 0164/1650] QtCore/Windows: Output unknown messages in hex in the debug operator for MSG Task-number: QTBUG-71257 Change-Id: I89335799529e8c518113925d402571a8f7ada244 Reviewed-by: Andre de la Rocha --- src/corelib/kernel/qcoreapplication_win.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp index 0c57ad34b9..b373267fcb 100644 --- a/src/corelib/kernel/qcoreapplication_win.cpp +++ b/src/corelib/kernel/qcoreapplication_win.cpp @@ -717,7 +717,7 @@ QString decodeMSG(const MSG& msg) else if (const char *wmmsgC = findWMstr(msg.message)) message = QString::fromLatin1(wmmsgC); else - message = QString::fromLatin1("WM_(%1)").arg(msg.message); // Unknown WM_, so use number + message = QString::fromLatin1("WM_(0x%1)").arg(msg.message, 0, 16); // Unknown WM_, so use number // Yes, we want to give the WM_ names 20 chars of space before showing the // decoded message, since some of the common messages are quite long, and From 235ea594ad80b3ebb019b536b19dd041706b937e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 22 Oct 2018 14:06:33 +0200 Subject: [PATCH 0165/1650] uic: Remove remains of old Java generator Preparing the use of the option for Python. Task-number: PYSIDE-797 Change-Id: Ia1267b227ceac7f9dcbcfde6ed7c1480ef790f2a Reviewed-by: Jarek Kobus --- src/tools/uic/cpp/cpp.pri | 2 - src/tools/uic/driver.cpp | 11 +---- src/tools/uic/main.cpp | 1 - src/tools/uic/option.h | 12 ----- src/tools/uic/uic.cpp | 92 +++++---------------------------------- src/tools/uic/uic.h | 8 ---- 6 files changed, 13 insertions(+), 113 deletions(-) diff --git a/src/tools/uic/cpp/cpp.pri b/src/tools/uic/cpp/cpp.pri index a6b6188117..786b0e97a5 100644 --- a/src/tools/uic/cpp/cpp.pri +++ b/src/tools/uic/cpp/cpp.pri @@ -1,7 +1,5 @@ INCLUDEPATH += $$PWD $$QT_BUILD_TREE/src/tools/uic -DEFINES += QT_UIC_CPP_GENERATOR - # Input HEADERS += $$PWD/cppwritedeclaration.h \ $$PWD/cppwriteincludes.h \ diff --git a/src/tools/uic/driver.cpp b/src/tools/uic/driver.cpp index 6b3a6f8f69..91a48815fd 100644 --- a/src/tools/uic/driver.cpp +++ b/src/tools/uic/driver.cpp @@ -256,18 +256,11 @@ bool Driver::uic(const QString &fileName, DomUI *ui, QTextStream *out) m_output = out != 0 ? out : &m_stdout; Uic tool(this); - bool rtn = false; -#ifdef QT_UIC_CPP_GENERATOR - rtn = tool.write(ui); -#else - Q_UNUSED(ui); - fprintf(stderr, "uic: option to generate cpp code not compiled in [%s:%d]\n", - __FILE__, __LINE__); -#endif + const bool result = tool.write(ui); m_output = oldOutput; - return rtn; + return result; } bool Driver::uic(const QString &fileName, QTextStream *out) diff --git a/src/tools/uic/main.cpp b/src/tools/uic/main.cpp index 0e30bac28e..ec7ed63af7 100644 --- a/src/tools/uic/main.cpp +++ b/src/tools/uic/main.cpp @@ -115,7 +115,6 @@ int runUic(int argc, char *argv[]) driver.option().postfix = parser.value(postfixOption); driver.option().translateFunction = parser.value(translateOption); driver.option().includeFile = parser.value(includeOption); - driver.option().generator = (parser.value(generatorOption).toLower() == QLatin1String("java")) ? Option::JavaGenerator : Option::CppGenerator; if (parser.isSet(noStringLiteralOption)) fprintf(stderr, "The -s, --no-stringliteral option is deprecated and it won't take any effect.\n"); diff --git a/src/tools/uic/option.h b/src/tools/uic/option.h index a5b14abc5f..4fc442e94a 100644 --- a/src/tools/uic/option.h +++ b/src/tools/uic/option.h @@ -36,12 +36,6 @@ QT_BEGIN_NAMESPACE struct Option { - enum Generator - { - CppGenerator, - JavaGenerator - }; - unsigned int headerProtection : 1; unsigned int copyrightHeader : 1; unsigned int generateImplemetation : 1; @@ -51,7 +45,6 @@ struct Option unsigned int limitXPM_LineLength : 1; unsigned int implicitIncludes: 1; unsigned int idBased: 1; - Generator generator; QString inputFile; QString outputFile; @@ -61,10 +54,6 @@ struct Option QString postfix; QString translateFunction; QString includeFile; -#ifdef QT_UIC_JAVA_GENERATOR - QString javaPackage; - QString javaOutputDirectory; -#endif Option() : headerProtection(1), @@ -76,7 +65,6 @@ struct Option limitXPM_LineLength(0), implicitIncludes(1), idBased(0), - generator(CppGenerator), prefix(QLatin1String("Ui_")) { indent.fill(QLatin1Char(' '), 4); } diff --git a/src/tools/uic/uic.cpp b/src/tools/uic/uic.cpp index f275aaeb29..a5b331192f 100644 --- a/src/tools/uic/uic.cpp +++ b/src/tools/uic/uic.cpp @@ -33,18 +33,12 @@ #include "treewalker.h" #include "validator.h" -#ifdef QT_UIC_CPP_GENERATOR #include "cppwriteincludes.h" #include "cppwritedeclaration.h" -#endif - -#ifdef QT_UIC_JAVA_GENERATOR -#include "javawriteincludes.h" -#include "javawritedeclaration.h" -#endif #include #include +#include #include QT_BEGIN_NAMESPACE @@ -172,65 +166,33 @@ DomUI *Uic::parseUiFile(QXmlStreamReader &reader) bool Uic::write(QIODevice *in) { - if (option().generator == Option::JavaGenerator) { - // the Java generator ignores header protection - opt.headerProtection = false; - } - - DomUI *ui = 0; + QScopedPointer ui; { QXmlStreamReader reader; reader.setDevice(in); - ui = parseUiFile(reader); - - if (!ui) - return false; + ui.reset(parseUiFile(reader)); } + if (ui.isNull()) + return false; + double version = ui->attributeVersion().toDouble(); if (version < 4.0) { - delete ui; - fprintf(stderr, "uic: File generated with too old version of Qt Designer\n"); return false; } - QString language = ui->attributeLanguage(); + const QString &language = ui->attributeLanguage(); driver()->setUseIdBasedTranslations(ui->attributeIdbasedtr()); - bool rtn = false; - - if (option().generator == Option::JavaGenerator) { -#ifdef QT_UIC_JAVA_GENERATOR - if (language.toLower() != QLatin1String("jambi")) { - fprintf(stderr, "uic: File is not a 'jambi' form\n"); - delete ui; - return false; - } - rtn = jwrite (ui); -#else - fprintf(stderr, "uic: option to generate java code not compiled in\n"); -#endif - } else { -#ifdef QT_UIC_CPP_GENERATOR - if (!language.isEmpty() && language.toLower() != QLatin1String("c++")) { - fprintf(stderr, "uic: File is not a 'c++' ui file, language=%s\n", qPrintable(language)); - delete ui; - return false; - } - - rtn = write (ui); -#else - fprintf(stderr, "uic: option to generate cpp code not compiled in\n"); -#endif + if (!language.isEmpty() && language.compare(QLatin1String("c++"), Qt::CaseInsensitive) != 0) { + fprintf(stderr, "uic: File is not a \"c++\" ui file, language=%s\n", qPrintable(language)); + return false; } - delete ui; - - return rtn; + return write(ui.data()); } -#ifdef QT_UIC_CPP_GENERATOR bool Uic::write(DomUI *ui) { using namespace CPP; @@ -267,37 +229,6 @@ bool Uic::write(DomUI *ui) return true; } -#endif - -#ifdef QT_UIC_JAVA_GENERATOR -bool Uic::jwrite(DomUI *ui) -{ - using namespace Java; - - if (!ui || !ui->elementWidget()) - return false; - - if (opt.copyrightHeader) - writeCopyrightHeader(ui); - - pixFunction = ui->elementPixmapFunction(); - if (pixFunction == QLatin1String("QPixmap::fromMimeSource")) - pixFunction = QLatin1String("qPixmapFromMimeSource"); - - externalPix = ui->elementImages() == 0; - - info.acceptUI(ui); - cWidgetsInfo.acceptUI(ui); - WriteIncludes(this).acceptUI(ui); - - Validator(this).acceptUI(ui); - WriteDeclaration(this).acceptUI(ui); - - return true; -} -#endif - -#ifdef QT_UIC_CPP_GENERATOR void Uic::writeHeaderProtectionStart() { @@ -311,7 +242,6 @@ void Uic::writeHeaderProtectionEnd() QString h = drv->headerFileName(); out << "#endif // " << h << "\n"; } -#endif bool Uic::isMainWindow(const QString &className) const { diff --git a/src/tools/uic/uic.h b/src/tools/uic/uic.h index 1c229bc516..4c961aa0a5 100644 --- a/src/tools/uic/uic.h +++ b/src/tools/uic/uic.h @@ -83,13 +83,7 @@ public: bool write(QIODevice *in); -#ifdef QT_UIC_JAVA_GENERATOR - bool jwrite(DomUI *ui); -#endif - -#ifdef QT_UIC_CPP_GENERATOR bool write(DomUI *ui); -#endif bool isMainWindow(const QString &className) const; bool isToolBar(const QString &className) const; @@ -105,11 +99,9 @@ private: void writeCopyrightHeader(DomUI *ui); DomUI *parseUiFile(QXmlStreamReader &reader); -#ifdef QT_UIC_CPP_GENERATOR // header protection void writeHeaderProtectionStart(); void writeHeaderProtectionEnd(); -#endif private: Driver *drv; From e3a552a130fc09725c8adda3548d297fc96e058a Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 17 Oct 2018 14:59:08 +0200 Subject: [PATCH 0166/1650] QtPlatformSupport/macOS: Remove superfluous freetype inclusion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit freetype is included depending on configuration by the top level .pro file. Fix build warning: Makefile:1361: warning: ignoring old commands for target `.obj/qfontengine_ft.o' Change-Id: I0a0f111a841b368196633bbc0f9c698197f64bb2 Reviewed-by: Tor Arne Vestbø --- src/platformsupport/fontdatabases/mac/coretext.pri | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/platformsupport/fontdatabases/mac/coretext.pri b/src/platformsupport/fontdatabases/mac/coretext.pri index af75aa3281..95b9926e65 100644 --- a/src/platformsupport/fontdatabases/mac/coretext.pri +++ b/src/platformsupport/fontdatabases/mac/coretext.pri @@ -1,12 +1,6 @@ HEADERS += $$PWD/qcoretextfontdatabase_p.h $$PWD/qfontengine_coretext_p.h OBJECTIVE_SOURCES += $$PWD/qfontengine_coretext.mm $$PWD/qcoretextfontdatabase.mm -qtConfig(freetype) { - QMAKE_USE_PRIVATE += freetype - HEADERS += freetype/qfontengine_ft_p.h - SOURCES += freetype/qfontengine_ft.cpp -} - LIBS_PRIVATE += \ -framework CoreFoundation \ -framework CoreGraphics \ From 611423099667d2dc18e6fb63967cbbfd8a65829c Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Tue, 30 Oct 2018 10:43:51 +0100 Subject: [PATCH 0167/1650] Fix supportsSsl() to make it more consistent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Attempts to use QSslSocket and its OpenSSL 1.1 back-end with OpenSSL 1.1.1 in a very peculiar way (for some reason the reporter calls OPENSSL_no_config()) combined with a bug in OpenSSL 1.1.1 resulted in a QSslSocket dead-locking in initialization. This was happening because supportsSsl() first reported false (OpenSSL internally fails to initialize after OPENSSL_no_config()), but we have s_libraryLoaded set to true too early, thus the first supportsSsl() returns false, the second - true. Move setting of s_libraryLoaded later so that we don't claim to support OpenSSL when an earlier ensureLibraryLoaded() attempt failed. Task-number: QTBUG-70956 Task-number: QTBUG-71446 Change-Id: I8ad8763d357c84fc38c62e2ce914366367c2b445 Reviewed-by: Edward Welbourne Reviewed-by: Mårten Nordheim --- src/network/ssl/qsslsocket_openssl.cpp | 5 +++++ src/network/ssl/qsslsocket_openssl11.cpp | 4 ++-- src/network/ssl/qsslsocket_opensslpre11.cpp | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 64501a75e8..37bb3e4933 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -474,7 +474,12 @@ void QSslSocketPrivate::resetDefaultCiphers() #else SSL_CTX *myCtx = q_SSL_CTX_new(q_SSLv23_client_method()); #endif + // Note, we assert, not just silently return/bail out early: + // this should never happen and problems with OpenSSL's initialization + // must be caught before this (see supportsSsl()). + Q_ASSERT(myCtx); SSL *mySsl = q_SSL_new(myCtx); + Q_ASSERT(mySsl); QList ciphers; QList defaultCiphers; diff --git a/src/network/ssl/qsslsocket_openssl11.cpp b/src/network/ssl/qsslsocket_openssl11.cpp index cbbf403672..2a2667bd48 100644 --- a/src/network/ssl/qsslsocket_openssl11.cpp +++ b/src/network/ssl/qsslsocket_openssl11.cpp @@ -88,8 +88,6 @@ bool QSslSocketPrivate::ensureLibraryLoaded() const QMutexLocker locker(qt_opensslInitMutex); if (!s_libraryLoaded) { - s_libraryLoaded = true; - // Initialize OpenSSL. if (q_OPENSSL_init_ssl(0, nullptr) != 1) return false; @@ -105,6 +103,8 @@ bool QSslSocketPrivate::ensureLibraryLoaded() qWarning("Random number generator not seeded, disabling SSL support"); return false; } + + s_libraryLoaded = true; } return true; } diff --git a/src/network/ssl/qsslsocket_opensslpre11.cpp b/src/network/ssl/qsslsocket_opensslpre11.cpp index 062e03f4e6..bc4fd9dc85 100644 --- a/src/network/ssl/qsslsocket_opensslpre11.cpp +++ b/src/network/ssl/qsslsocket_opensslpre11.cpp @@ -215,8 +215,6 @@ bool QSslSocketPrivate::ensureLibraryLoaded() QMutexLocker locker(openssl_locks()->initLock()); if (!s_libraryLoaded) { - s_libraryLoaded = true; - // Initialize OpenSSL. q_CRYPTO_set_id_callback(id_function); q_CRYPTO_set_locking_callback(locking_function); @@ -235,6 +233,8 @@ bool QSslSocketPrivate::ensureLibraryLoaded() qWarning("Random number generator not seeded, disabling SSL support"); return false; } + + s_libraryLoaded = true; } return true; } From d84a7a812818065f97e015e50f66f6dad8c9a978 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Mon, 1 Oct 2018 16:24:44 +0200 Subject: [PATCH 0168/1650] QTreeView: add expandRecursively() to expand all items below an index QTreeView only had functions to either expand all items or until a given depth. What was missing is to expand all subitems for an index programmatically which is added with this patch. [ChangeLog][QtWidgets][QTreeView] Added expandRecursively() to expand all items below a given index Fixes: QTBUG-10482 Change-Id: I8fc4d50b0b7e90245840c99a0188f13c0670253a Reviewed-by: Samuel Gaist Reviewed-by: Richard Moe Gustavsen Reviewed-by: Shawn Rutledge --- src/widgets/itemviews/qtreeview.cpp | 62 +++++++--- src/widgets/itemviews/qtreeview.h | 1 + .../itemviews/qtreeview/tst_qtreeview.cpp | 110 +++++++++++++----- 3 files changed, 125 insertions(+), 48 deletions(-) diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index 60da0eb6c3..743832b214 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -1985,21 +1985,7 @@ void QTreeView::keyPressEvent(QKeyEvent *event) if (d->isIndexValid(current) && d->model && d->itemsExpandable) { switch (event->key()) { case Qt::Key_Asterisk: { - // do layouting only once after expanding is done - d->doDelayedItemsLayout(); - QStack parents; - parents.push(current); - while (!parents.isEmpty()) { - QModelIndex parent = parents.pop(); - for (int row = 0; row < d->model->rowCount(parent); ++row) { - QModelIndex child = d->model->index(row, 0, parent); - if (!d->isIndexValid(child)) - break; - parents.push(child); - expand(child); - } - } - expand(current); + expandRecursively(current); break; } case Qt::Key_Plus: expand(current); @@ -2694,7 +2680,7 @@ QSize QTreeView::viewportSizeHint() const \since 4.2 Expands all expandable items. - Warning: if the model contains a large number of items, + \warning: if the model contains a large number of items, this function will take some time to execute. \sa collapseAll(), expand(), collapse(), setExpanded() @@ -2709,6 +2695,50 @@ void QTreeView::expandAll() d->viewport->update(); } +/*! + \since 5.13 + Expands the item at the given \a index and all its children to the + given \a depth. The \a depth is relative to the given \a index. + A \a depth of -1 will expand all children, a \a depth of 0 will + only expand the given \a index. + + \warning: if the model contains a large number of items, + this function will take some time to execute. + + \sa expandAll() +*/ +void QTreeView::expandRecursively(const QModelIndex &index, int depth) +{ + Q_D(QTreeView); + + if (depth < -1) + return; + // do layouting only once after expanding is done + d->doDelayedItemsLayout(); + expand(index); + if (depth == 0) + return; + QStack> parents; + parents.push({index, 0}); + while (!parents.isEmpty()) { + const QPair elem = parents.pop(); + const QModelIndex &parent = elem.first; + const int curDepth = elem.second; + const int rowCount = d->model->rowCount(parent); + for (int row = 0; row < rowCount; ++row) { + const QModelIndex child = d->model->index(row, 0, parent); + if (!d->isIndexValid(child)) + break; + if (depth == -1 || curDepth + 1 < depth) + parents.push({child, curDepth + 1}); + if (d->isIndexExpanded(child)) + continue; + if (d->storeExpanded(child)) + emit expanded(child); + } + } +} + /*! \since 4.2 diff --git a/src/widgets/itemviews/qtreeview.h b/src/widgets/itemviews/qtreeview.h index 33dbf1c1ce..ee65cf4265 100644 --- a/src/widgets/itemviews/qtreeview.h +++ b/src/widgets/itemviews/qtreeview.h @@ -160,6 +160,7 @@ public Q_SLOTS: void resizeColumnToContents(int column); void sortByColumn(int column); void expandAll(); + void expandRecursively(const QModelIndex &index, int depth = -1); void collapseAll(); void expandToDepth(int depth); diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index f4a73b8b4a..b8c36f9b21 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -1647,50 +1647,96 @@ void tst_QTreeView::expandAndCollapse() } } +static void checkExpandState(const QAbstractItemModel &model, const QTreeView &view, + const QModelIndex &startIdx, bool bIsExpanded, int *count) +{ + *count = 0; + QStack parents; + parents.push(startIdx); + if (startIdx.isValid()) { + QCOMPARE(view.isExpanded(startIdx), bIsExpanded); + *count += 1; + } + while (!parents.isEmpty()) { + const QModelIndex p = parents.pop(); + const int rows = model.rowCount(p); + for (int r = 0; r < rows; ++r) { + const QModelIndex c = model.index(r, 0, p); + QCOMPARE(view.isExpanded(c), bIsExpanded); + parents.push(c); + } + *count += rows; + } +} + void tst_QTreeView::expandAndCollapseAll() { - QtTestModel model(3, 2); - model.levels = 2; + QStandardItemModel model; + // QtTestModel has a broken parent/child handling which will break the test + for (int i1 = 0; i1 < 3; ++i1) { + QStandardItem *s1 = new QStandardItem; + s1->setText(QString::number(i1)); + model.appendRow(s1); + for (int i2 = 0; i2 < 3; ++i2) { + QStandardItem *s2 = new QStandardItem; + s2->setText(QStringLiteral("%1 - %2").arg(i1).arg(i2)); + s1->appendRow(s2); + for (int i3 = 0; i3 < 3; ++i3) { + QStandardItem *s3 = new QStandardItem; + s3->setText(QStringLiteral("%1 - %2 - %3").arg(i1).arg(i2).arg(i3)); + s2->appendRow(s3); + } + } + } QTreeView view; view.setUniformRowHeights(true); view.setModel(&model); + view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); - QSignalSpy expandedSpy(&view, SIGNAL(expanded(QModelIndex))); - QSignalSpy collapsedSpy(&view, SIGNAL(collapsed(QModelIndex))); + QSignalSpy expandedSpy(&view, &QTreeView::expanded); + QSignalSpy collapsedSpy(&view, &QTreeView::collapsed); + int count; view.expandAll(); - view.show(); - + checkExpandState(model, view, QModelIndex(), true, &count); QCOMPARE(collapsedSpy.count(), 0); + QCOMPARE(expandedSpy.count(), 39); // == 3 (first) + 9 (second) + 27 (third level) + QCOMPARE(count, 39); - QStack parents; - parents.push(QModelIndex()); - int count = 0; - while (!parents.isEmpty()) { - QModelIndex p = parents.pop(); - int rows = model.rowCount(p); - for (int r = 0; r < rows; ++r) - QVERIFY(view.isExpanded(model.index(r, 0, p))); - count += rows; - for (int r = 0; r < rows; ++r) - parents.push(model.index(r, 0, p)); - } - QCOMPARE(expandedSpy.count(), 12); // == (3+1)*(2+1) from QtTestModel model(3, 2); - + collapsedSpy.clear(); + expandedSpy.clear(); view.collapseAll(); + checkExpandState(model, view, QModelIndex(), false, &count); + QCOMPARE(collapsedSpy.count(), 39); + QCOMPARE(expandedSpy.count(), 0); + QCOMPARE(count, 39); - parents.push(QModelIndex()); - count = 0; - while (!parents.isEmpty()) { - QModelIndex p = parents.pop(); - int rows = model.rowCount(p); - for (int r = 0; r < rows; ++r) - QVERIFY(!view.isExpanded(model.index(r, 0, p))); - count += rows; - for (int r = 0; r < rows; ++r) - parents.push(model.index(r, 0, p)); - } - QCOMPARE(collapsedSpy.count(), 12); + collapsedSpy.clear(); + expandedSpy.clear(); + view.expandRecursively(model.index(0, 0)); + QCOMPARE(expandedSpy.count(), 13); // 1 + 3 + 9 + + checkExpandState(model, view, model.index(0, 0), true, &count); + QCOMPARE(count, 13); + checkExpandState(model, view, model.index(1, 0), false, &count); + QCOMPARE(count, 13); + checkExpandState(model, view, model.index(2, 0), false, &count); + QCOMPARE(count, 13); + + expandedSpy.clear(); + view.collapseAll(); + view.expandRecursively(model.index(0, 0), 1); + QCOMPARE(expandedSpy.count(), 4); // 1 + 3 + view.expandRecursively(model.index(0, 0), 2); + QCOMPARE(expandedSpy.count(), 13); // (1 + 3) + 9 + + checkExpandState(model, view, model.index(0, 0), true, &count); + QCOMPARE(count, 13); + checkExpandState(model, view, model.index(1, 0), false, &count); + QCOMPARE(count, 13); + checkExpandState(model, view, model.index(2, 0), false, &count); + QCOMPARE(count, 13); } void tst_QTreeView::expandWithNoChildren() From d0f909f8dbdd8594b0d950822f0e7ab8728da513 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 26 Oct 2018 20:38:58 +0200 Subject: [PATCH 0169/1650] QTreeView/TableView: explicitly mark sortByColumn(int) as deprecated QTreeView/TableView::sortByColumn(int) was deprecated a long time ago but never got removed. Therefore mark it with QT_DEPRECATED_SINCE(5, 13) so we can remove it with Qt6. Also sync the handling of the sort order changes in QTableView with the one from QTreeView. Change-Id: I0371d9a9c21116edaa9125835827f1a200075d36 Reviewed-by: Luca Beldi Reviewed-by: Richard Moe Gustavsen --- src/widgets/itemviews/qtableview.cpp | 35 ++++++++++++++----- src/widgets/itemviews/qtableview.h | 6 +++- src/widgets/itemviews/qtableview_p.h | 1 + src/widgets/itemviews/qtreeview.cpp | 12 +++++-- src/widgets/itemviews/qtreeview.h | 5 ++- .../tst_qabstractitemmodeltester.cpp | 2 +- .../itemviews/qtreeview/tst_qtreeview.cpp | 6 ++-- 7 files changed, 50 insertions(+), 17 deletions(-) diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp index 32bbef07e9..dac8174a2a 100644 --- a/src/widgets/itemviews/qtableview.cpp +++ b/src/widgets/itemviews/qtableview.cpp @@ -902,6 +902,15 @@ void QTableViewPrivate::_q_updateSpanRemovedColumns(const QModelIndex &parent, i spans.updateRemovedColumns(start, end); } +/*! + \internal + Sort the model when the header sort indicator changed +*/ +void QTableViewPrivate::_q_sortIndicatorChanged(int column, Qt::SortOrder order) +{ + model->sort(column, order); +} + /*! \internal Draws a table cell. @@ -2573,25 +2582,27 @@ void QTableView::setColumnHidden(int column, bool hide) void QTableView::setSortingEnabled(bool enable) { Q_D(QTableView); - d->sortingEnabled = enable; horizontalHeader()->setSortIndicatorShown(enable); if (enable) { disconnect(d->horizontalHeader, SIGNAL(sectionEntered(int)), this, SLOT(_q_selectColumn(int))); disconnect(horizontalHeader(), SIGNAL(sectionPressed(int)), this, SLOT(selectColumn(int))); - connect(horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), - this, SLOT(sortByColumn(int)), Qt::UniqueConnection); + //sortByColumn has to be called before we connect or set the sortingEnabled flag + // because otherwise it will not call sort on the model. sortByColumn(horizontalHeader()->sortIndicatorSection(), horizontalHeader()->sortIndicatorOrder()); + connect(horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), + this, SLOT(_q_sortIndicatorChanged(int,Qt::SortOrder)), Qt::UniqueConnection); } else { connect(d->horizontalHeader, SIGNAL(sectionEntered(int)), this, SLOT(_q_selectColumn(int)), Qt::UniqueConnection); connect(horizontalHeader(), SIGNAL(sectionPressed(int)), this, SLOT(selectColumn(int)), Qt::UniqueConnection); disconnect(horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), - this, SLOT(sortByColumn(int))); + this, SLOT(_q_sortIndicatorChanged(int,Qt::SortOrder))); } + d->sortingEnabled = enable; } bool QTableView::isSortingEnabled() const @@ -3120,19 +3131,21 @@ void QTableView::resizeColumnsToContents() d->horizontalHeader->resizeSections(QHeaderView::ResizeToContents); } +#if QT_DEPRECATED_SINCE(5, 13) /*! \obsolete \overload + This function is deprecated. Use + sortByColumn(int column, Qt::SortOrder order) instead. Sorts the model by the values in the given \a column. */ void QTableView::sortByColumn(int column) { Q_D(QTableView); - if (column == -1) - return; - d->model->sort(column, d->horizontalHeader->sortIndicatorOrder()); + sortByColumn(column, d->horizontalHeader->sortIndicatorOrder()); } +#endif /*! \since 4.2 @@ -3144,8 +3157,14 @@ void QTableView::sortByColumn(int column) void QTableView::sortByColumn(int column, Qt::SortOrder order) { Q_D(QTableView); + if (column < 0) + return; + // If sorting is enabled it will emit a signal connected to + // _q_sortIndicatorChanged, which then actually sorts d->horizontalHeader->setSortIndicator(column, order); - sortByColumn(column); + // If sorting is not enabled, force to sort now + if (!d->sortingEnabled) + d->model->sort(column, order); } /*! diff --git a/src/widgets/itemviews/qtableview.h b/src/widgets/itemviews/qtableview.h index 60c2f34103..3275c09f88 100644 --- a/src/widgets/itemviews/qtableview.h +++ b/src/widgets/itemviews/qtableview.h @@ -118,7 +118,6 @@ public: int columnSpan(int row, int column) const; void clearSpans(); - void sortByColumn(int column, Qt::SortOrder order); public Q_SLOTS: void selectRow(int row); @@ -131,7 +130,11 @@ public Q_SLOTS: void resizeRowsToContents(); void resizeColumnToContents(int column); void resizeColumnsToContents(); +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X ("Use QTableView::sortByColumn(int column, Qt::SortOrder order) instead") void sortByColumn(int column); +#endif + void sortByColumn(int column, Qt::SortOrder order); void setShowGrid(bool show); protected Q_SLOTS: @@ -188,6 +191,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_updateSpanInsertedColumns(QModelIndex,int,int)) Q_PRIVATE_SLOT(d_func(), void _q_updateSpanRemovedRows(QModelIndex,int,int)) Q_PRIVATE_SLOT(d_func(), void _q_updateSpanRemovedColumns(QModelIndex,int,int)) + Q_PRIVATE_SLOT(d_func(), void _q_sortIndicatorChanged(int column, Qt::SortOrder order)) }; QT_END_NAMESPACE diff --git a/src/widgets/itemviews/qtableview_p.h b/src/widgets/itemviews/qtableview_p.h index 805787597c..520fd9a3af 100644 --- a/src/widgets/itemviews/qtableview_p.h +++ b/src/widgets/itemviews/qtableview_p.h @@ -257,6 +257,7 @@ public: void _q_updateSpanInsertedColumns(const QModelIndex &parent, int start, int end); void _q_updateSpanRemovedRows(const QModelIndex &parent, int start, int end); void _q_updateSpanRemovedColumns(const QModelIndex &parent, int start, int end); + void _q_sortIndicatorChanged(int column, Qt::SortOrder order); }; QT_END_NAMESPACE diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index 743832b214..e7196c9d5d 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -2598,10 +2598,13 @@ void QTreeView::resizeColumnToContents(int column) d->header->resizeSection(column, qMax(contents, header)); } +#if QT_DEPRECATED_SINCE(5, 13) /*! \obsolete \overload + This function is deprecated. Use + sortByColumn(int column, Qt::SortOrder order) instead. Sorts the model by the values in the given \a column. */ void QTreeView::sortByColumn(int column) @@ -2609,6 +2612,7 @@ void QTreeView::sortByColumn(int column) Q_D(QTreeView); sortByColumn(column, d->header->sortIndicatorOrder()); } +#endif /*! \since 4.2 @@ -2624,10 +2628,12 @@ void QTreeView::sortByColumn(int column) void QTreeView::sortByColumn(int column, Qt::SortOrder order) { Q_D(QTreeView); - - //If sorting is enabled will emit a signal connected to _q_sortIndicatorChanged, which then actually sorts + if (column < 0) + return; + // If sorting is enabled it will emit a signal connected to + // _q_sortIndicatorChanged, which then actually sorts d->header->setSortIndicator(column, order); - //If sorting is not enabled, force to sort now. + // If sorting is not enabled, force to sort now if (!d->sortingEnabled) d->model->sort(column, order); } diff --git a/src/widgets/itemviews/qtreeview.h b/src/widgets/itemviews/qtreeview.h index ee65cf4265..e9cc1beedb 100644 --- a/src/widgets/itemviews/qtreeview.h +++ b/src/widgets/itemviews/qtreeview.h @@ -143,7 +143,6 @@ public: void doItemsLayout() override; void reset() override; - void sortByColumn(int column, Qt::SortOrder order); void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles = QVector()) override; void selectAll() override; @@ -158,7 +157,11 @@ public Q_SLOTS: void expand(const QModelIndex &index); void collapse(const QModelIndex &index); void resizeColumnToContents(int column); +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X ("Use QTreeeView::sortByColumn(int column, Qt::SortOrder order) instead") void sortByColumn(int column); +#endif + void sortByColumn(int column, Qt::SortOrder order); void expandAll(); void expandRecursively(const QModelIndex &index, int depth = -1); void collapseAll(); diff --git a/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp b/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp index 0593ae74bf..d37d332939 100644 --- a/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp +++ b/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp @@ -81,7 +81,7 @@ void tst_QAbstractItemModelTester::treeWidgetModel() new QTreeWidgetItem(parent, QStringList("child")); widget.setItemHidden(parent, true); - widget.sortByColumn(0); + widget.sortByColumn(0, Qt::AscendingOrder); } void tst_QAbstractItemModelTester::standardItemModel() diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index b8c36f9b21..6b732973b9 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -2792,7 +2792,7 @@ void tst_QTreeView::sortByColumn() view.setSortingEnabled(sortingEnabled); view.setModel(&model); - view.sortByColumn(1); + view.sortByColumn(1, Qt::DescendingOrder); QCOMPARE(view.header()->sortIndicatorSection(), 1); QCOMPARE(view.model()->data(view.model()->index(0,1)).toString(), QString::fromLatin1("h")); QCOMPARE(view.model()->data(view.model()->index(1,1)).toString(), QString::fromLatin1("g")); @@ -3102,7 +3102,7 @@ void tst_QTreeView::evilModel() view.resizeColumnToContents(1); model.change(); - view.sortByColumn(1); + view.sortByColumn(1, Qt::DescendingOrder); model.change(); view.selectAll(); @@ -3946,7 +3946,7 @@ void tst_QTreeView::task254234_proxySort() model.setItem(2,1,new QStandardItem("h")); model.setItem(3,1,new QStandardItem("f")); - view.sortByColumn(1); + view.sortByColumn(1, Qt::DescendingOrder); view.setSortingEnabled(true); QSortFilterProxyModel proxy; From a5a1f338aa0077b5e29bdf774ad4183f1c8c59d9 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 26 Oct 2018 21:27:04 +0200 Subject: [PATCH 0170/1650] QTableWidget: mark isItemSelected/setItemSelected() as deprecated QTableWidget::isItemSelected/setItemSelected() are deprecated for a long time but not marked as such. Therefore explicitly mark them as deprecated so they can get removed with Qt6. Change-Id: I77fffe2786751306115c3f5da0ef98ff84e35b1a Reviewed-by: Richard Moe Gustavsen --- src/widgets/itemviews/qtablewidget.cpp | 67 ++++++++++++------- src/widgets/itemviews/qtablewidget.h | 14 ++-- .../qtablewidget/tst_qtablewidget.cpp | 6 +- 3 files changed, 52 insertions(+), 35 deletions(-) diff --git a/src/widgets/itemviews/qtablewidget.cpp b/src/widgets/itemviews/qtablewidget.cpp index bf4d5d46ff..26006fc6c5 100644 --- a/src/widgets/itemviews/qtablewidget.cpp +++ b/src/widgets/itemviews/qtablewidget.cpp @@ -1054,24 +1054,6 @@ QTableWidgetSelectionRange::~QTableWidgetSelectionRange() \sa row() */ -/*! - \fn void QTableWidgetItem::setSelected(bool select) - \since 4.2 - - Sets the selected state of the item to \a select. - - \sa isSelected() -*/ - -/*! - \fn bool QTableWidgetItem::isSelected() const - \since 4.2 - - Returns \c true if the item is selected, otherwise returns \c false. - - \sa setSelected() -*/ - /*! \fn QSize QTableWidgetItem::sizeHint() const \since 4.1 @@ -1108,6 +1090,44 @@ QTableWidgetSelectionRange::~QTableWidgetSelectionRange() Returns the table widget that contains the item. */ +/*! + \fn bool QTableWidgetItem::isSelected() const + \since 4.2 + + Returns \c true if the item is selected, otherwise returns \c false. + + \sa setSelected() +*/ +bool QTableWidgetItem::isSelected() const +{ + if (!view || !view->selectionModel()) + return false; + const QTableModel *model = qobject_cast(view->model()); + if (!model) + return false; + const QModelIndex index = model->index(this); + return view->selectionModel()->isSelected(index); +} + +/*! + \fn void QTableWidgetItem::setSelected(bool select) + \since 4.2 + + Sets the selected state of the item to \a select. + + \sa isSelected() +*/ +void QTableWidgetItem::setSelected(bool select) +{ + if (!view || !view->selectionModel()) + return; + const QTableModel *model = qobject_cast(view->model()); + if (!model) + return; + const QModelIndex index = model->index(this); + view->selectionModel()->select(index, select ? QItemSelectionModel::Select : QItemSelectionModel::Deselect); +} + /*! \fn Qt::ItemFlags QTableWidgetItem::flags() const @@ -2323,6 +2343,7 @@ void QTableWidget::setCellWidget(int row, int column, QWidget *widget) QAbstractItemView::setIndexWidget(index, widget); } +#if QT_DEPRECATED_SINCE(5, 13) /*! Returns \c true if the \a item is selected, otherwise returns \c false. @@ -2333,9 +2354,7 @@ void QTableWidget::setCellWidget(int row, int column, QWidget *widget) bool QTableWidget::isItemSelected(const QTableWidgetItem *item) const { - Q_D(const QTableWidget); - QModelIndex index = d->tableModel()->index(item); - return selectionModel()->isSelected(index); + return ((item && item->tableWidget() == this) ? item->isSelected() : false); } /*! @@ -2347,10 +2366,10 @@ bool QTableWidget::isItemSelected(const QTableWidgetItem *item) const */ void QTableWidget::setItemSelected(const QTableWidgetItem *item, bool select) { - Q_D(QTableWidget); - QModelIndex index = d->tableModel()->index(item); - selectionModel()->select(index, select ? QItemSelectionModel::Select : QItemSelectionModel::Deselect); + if (item && item->tableWidget() == this) + const_cast(item)->setSelected(select); } +#endif /*! Selects or deselects the \a range depending on \a select. diff --git a/src/widgets/itemviews/qtablewidget.h b/src/widgets/itemviews/qtablewidget.h index be629264f8..2ddc24d30b 100644 --- a/src/widgets/itemviews/qtablewidget.h +++ b/src/widgets/itemviews/qtablewidget.h @@ -92,8 +92,8 @@ public: inline int row() const; inline int column() const; - inline void setSelected(bool select); - inline bool isSelected() const; + void setSelected(bool select); + bool isSelected() const; inline Qt::ItemFlags flags() const { return itemFlags; } void setFlags(Qt::ItemFlags flags); @@ -276,8 +276,12 @@ public: void setCellWidget(int row, int column, QWidget *widget); inline void removeCellWidget(int row, int column); +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X ("Use QTableWidgetItem::isSelected() instead") bool isItemSelected(const QTableWidgetItem *item) const; + QT_DEPRECATED_X ("Use QTableWidgetItem::setSelected() instead") void setItemSelected(const QTableWidgetItem *item, bool select); +#endif void setRangeSelected(const QTableWidgetSelectionRange &range, bool select); QList selectedRanges() const; @@ -383,12 +387,6 @@ inline int QTableWidgetItem::row() const inline int QTableWidgetItem::column() const { return (view ? view->column(this) : -1); } -inline void QTableWidgetItem::setSelected(bool aselect) -{ if (view) view->setItemSelected(this, aselect); } - -inline bool QTableWidgetItem::isSelected() const -{ return (view ? view->isItemSelected(this) : false); } - QT_END_NAMESPACE #endif // QTABLEWIDGET_H diff --git a/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp b/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp index 5f013a28d0..2e8f262c85 100644 --- a/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp +++ b/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp @@ -196,10 +196,10 @@ void tst_QTableWidget::clear() { QTableWidgetItem *item = new QTableWidgetItem("foo"); testWidget->setItem(0, 0, item); - testWidget->setItemSelected(item, true); + item->setSelected(true); QVERIFY(testWidget->item(0, 0) == item); - QVERIFY(testWidget->isItemSelected(item)); + QVERIFY(item->isSelected()); QPointer bla = new QObjectTableItem(); @@ -583,7 +583,7 @@ void tst_QTableWidget::selectedItems() continue; QTableWidgetItem *item = testWidget->item(row, column); - if (item && testWidget->isItemSelected(item)) + if (item && item->isSelected()) QVERIFY(selectedItems.contains(item)); } } From 8b7a4b8dd8ffd4c55fd013179242ecd42441d6a9 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sat, 27 Oct 2018 20:26:56 +0200 Subject: [PATCH 0171/1650] QLocale: add const version of formattedDataSize QLocale::formattedDataSize() was not marked const when it was added although the function is const. Add a const overload and mark the non-const version as deprecated and remove it with Qt6 Fixes: QTBUG-71445 Change-Id: I56d051d9928b5e00cdaca7a874c543fed27a888d Reviewed-by: Luca Beldi Reviewed-by: Edward Welbourne Reviewed-by: Thiago Macieira Reviewed-by: Shawn Rutledge --- src/corelib/tools/qlocale.cpp | 15 ++++++++++++++- src/corelib/tools/qlocale.h | 3 +++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 38bd195fba..4d5924a03e 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -3881,6 +3881,19 @@ QString QLocale::toCurrencyString(double value, const QString &symbol, int preci \sa formattedDataSize() */ +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +/*! + \obsolete + + Use the const version instead. +*/ +QString QLocale::formattedDataSize(qint64 bytes, int precision, DataSizeFormats format) +{ + const auto *that = this; + return that->formattedDataSize(bytes, precision, format); +} +#endif + /*! \since 5.10 @@ -3897,7 +3910,7 @@ QString QLocale::toCurrencyString(double value, const QString &symbol, int preci whereas \c DataSizeSIFormat uses the older SI quantifiers k, M, etc., and \c DataSizeTraditionalFormat abuses them. */ -QString QLocale::formattedDataSize(qint64 bytes, int precision, DataSizeFormats format) +QString QLocale::formattedDataSize(qint64 bytes, int precision, DataSizeFormats format) const { int power, base = 1000; if (!bytes) { diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h index af0eb2929e..1fbd96c6d5 100644 --- a/src/corelib/tools/qlocale.h +++ b/src/corelib/tools/qlocale.h @@ -1066,7 +1066,10 @@ public: { return toCurrencyString(double(i), symbol, precision); } #endif +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QString formattedDataSize(qint64 bytes, int precision = 2, DataSizeFormats format = DataSizeIecFormat); +#endif + QString formattedDataSize(qint64 bytes, int precision = 2, DataSizeFormats format = DataSizeIecFormat) const; QStringList uiLanguages() const; From 8637235e855ef9ad88aa56404a1d16387610e227 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sat, 20 Oct 2018 20:25:06 +0200 Subject: [PATCH 0172/1650] QColorDialog: use customColorCount() instead hardcoded value A hardcoded value of 16 was used in QColorDialogPrivate::_q_addCustom() instead QColorDialogOptions::customColorCount() Fixes: QTBUG-58425 Change-Id: I7ae9881abd5926e0c6b118d5c84c3f259c545d35 Reviewed-by: Samuel Gaist Reviewed-by: Richard Moe Gustavsen --- src/widgets/dialogs/qcolordialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp index 4aa680af61..be60ea60b0 100644 --- a/src/widgets/dialogs/qcolordialog.cpp +++ b/src/widgets/dialogs/qcolordialog.cpp @@ -1851,7 +1851,7 @@ void QColorDialogPrivate::_q_addCustom() QColorDialogOptions::setCustomColor(nextCust, cs->currentColor()); if (custom) custom->update(); - nextCust = (nextCust+1) % 16; + nextCust = (nextCust+1) % QColorDialogOptions::customColorCount(); } void QColorDialogPrivate::retranslateStrings() From e3c84b6da1cbef7ed779ba5eec6ae3ed8e4e5d59 Mon Sep 17 00:00:00 2001 From: Gary Wang Date: Tue, 23 Oct 2018 14:17:29 +0800 Subject: [PATCH 0173/1650] QMimeType: Use default key as fallback for comment() property When QMimeProvider parses the shared mime database xml files, it will read the element for mime comment and treat the `xml:lang` attribute as locale language string. When no `xml:lang` attr is provided, QMimeProvider will read the value and treat it as a en_US locale string as the default key. When we call QMimeType::comment(), it will try to get the locale comment string with the default language (QLocale().name()), once it can't find a matched result, it should return the default key (which QMimeProvider set it as en_US locale before) as fallback. Task-number: QTBUG-71314 Change-Id: I444f8159d6f19dfef6338cd79312f608d8f13394 Reviewed-by: David Faure --- src/corelib/mimetypes/qmimeprovider.cpp | 2 +- src/corelib/mimetypes/qmimetype.cpp | 1 + src/corelib/mimetypes/qmimetypeparser.cpp | 4 ++-- .../mimetypes/qmimedatabase/tst_qmimedatabase.cpp | 14 ++++++++++++++ 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp index c4a8458243..aac51184a4 100644 --- a/src/corelib/mimetypes/qmimeprovider.cpp +++ b/src/corelib/mimetypes/qmimeprovider.cpp @@ -502,7 +502,7 @@ void QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data) QString lang = xml.attributes().value(QLatin1String("xml:lang")).toString(); const QString text = xml.readElementText(); if (lang.isEmpty()) { - lang = QLatin1String("en_US"); + lang = QLatin1String("default"); // no locale attribute provided, treat it as default. } data.localeComments.insert(lang, text); continue; // we called readElementText, so we're at the EndElement already. diff --git a/src/corelib/mimetypes/qmimetype.cpp b/src/corelib/mimetypes/qmimetype.cpp index 50b8eae5c3..55c7de0c87 100644 --- a/src/corelib/mimetypes/qmimetype.cpp +++ b/src/corelib/mimetypes/qmimetype.cpp @@ -258,6 +258,7 @@ QString QMimeType::comment() const QStringList languageList; languageList << QLocale().name(); languageList << QLocale().uiLanguages(); + languageList << QLatin1String("default"); // use the default locale if possible. for (const QString &language : qAsConst(languageList)) { const QString lang = language == QLatin1String("C") ? QLatin1String("en_US") : language; const QString comm = d->localeComments.value(lang); diff --git a/src/corelib/mimetypes/qmimetypeparser.cpp b/src/corelib/mimetypes/qmimetypeparser.cpp index 7ff695bbc3..d10575cfe9 100644 --- a/src/corelib/mimetypes/qmimetypeparser.cpp +++ b/src/corelib/mimetypes/qmimetypeparser.cpp @@ -248,11 +248,11 @@ bool QMimeTypeParserBase::parse(QIODevice *dev, const QString &fileName, QString } break; case ParseComment: { - // comments have locale attributes. We want the default, English one + // comments have locale attributes. QString locale = atts.value(QLatin1String(localeAttributeC)).toString(); const QString comment = reader.readElementText(); if (locale.isEmpty()) - locale = QString::fromLatin1("en_US"); + locale = QString::fromLatin1("default"); data.localeComments.insert(locale, comment); } break; diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp index 597d51e7e0..9df52887f7 100644 --- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp +++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp @@ -992,6 +992,20 @@ void tst_QMimeDatabase::installNewGlobalMimeType() const QString fooTestFile2 = QLatin1String(RESOURCE_PREFIX "magic-and-hierarchy2.foo"); QCOMPARE(db.mimeTypeForFile(fooTestFile2).name(), QString::fromLatin1("application/vnd.qnx.bar-descriptor")); + // Test if we can use the default comment + { + struct RestoreLocale + { + ~RestoreLocale() { QLocale::setDefault(QLocale::c()); } + } restoreLocale; + + QLocale::setDefault(QLocale("zh_CN")); + QMimeType suseymp = db.mimeTypeForName("text/x-suse-ymp"); + QVERIFY(suseymp.isValid()); + QCOMPARE(suseymp.comment(), + QString::fromLatin1("YaST Meta Package")); + } + // Now test removing the mimetype definitions again for (int i = 0; i < m_additionalMimeFileNames.size(); ++i) QFile::remove(destDir + m_additionalMimeFileNames.at(i)); From 2b682972c2266e52b1510080a56b574e9ffd4db0 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sun, 23 Sep 2018 17:21:21 +0200 Subject: [PATCH 0174/1650] QSqlQuery: add another testcase for bindBool() tst_QSqlQuery::bindBool() did not check if the bool is correctly bound as part of the WHERE statement. Add a new test to query for the bool column and check if there is exactly one row returned. Fixes: QTBUG-38891 Change-Id: I0bd1ceb1b30e50f67f44f5b06d68683195b78b29 Reviewed-by: Andy Shaw --- tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp index 4ce1009c90..c4cf2e752f 100644 --- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp @@ -633,13 +633,20 @@ void tst_QSqlQuery::bindBool() QVERIFY_SQL(q, exec()); } - QVERIFY_SQL(q, exec("SELECT id, flag FROM " + tableName)); + QVERIFY_SQL(q, exec("SELECT id, flag FROM " + tableName + " ORDER BY id")); for (int i = 0; i < 2; ++i) { bool flag = i; QVERIFY_SQL(q, next()); QCOMPARE(q.value(0).toInt(), i); QCOMPARE(q.value(1).toBool(), flag); } + QVERIFY_SQL(q, prepare("SELECT flag FROM " + tableName + " WHERE flag = :filter")); + const bool filter = true; + q.bindValue(":filter", filter); + QVERIFY_SQL(q, exec()); + QVERIFY_SQL(q, next()); + QCOMPARE(q.value(0).toBool(), filter); + QFAIL_SQL(q, next()); QVERIFY_SQL(q, exec("DROP TABLE " + tableName)); } From 3fbf8fbc85143e713946ece3036b7303b8268f05 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Fri, 19 Oct 2018 16:17:44 +0200 Subject: [PATCH 0175/1650] Update to CLDR v34 This only updates data on languages already present in 5.12; once it has merged up to dev, the scripts need to be run again to pick up a few more languages and possibly add any more new languages present in v34. Change some tests to match changes in en_AU's abbreviated day and month names. [ChangeLog][ThirdParty][CLDR] Update locale data to CLDR v34. Task-number: QTBUG-71144 Change-Id: I68402b5e7e9d3dba669b8ba31b9a8abd86675c6e Reviewed-by: Lars Knoll --- src/corelib/tools/qlocale.qdoc | 2 +- src/corelib/tools/qlocale_data_p.h | 8434 +++++++++-------- src/corelib/tools/qlocale_p.h | 7 +- src/corelib/tools/qt_attribution.json | 3 +- .../qdatetimeedit/tst_qdatetimeedit.cpp | 16 +- 5 files changed, 4285 insertions(+), 4177 deletions(-) diff --git a/src/corelib/tools/qlocale.qdoc b/src/corelib/tools/qlocale.qdoc index 5c0a9b63e5..76ca909d83 100644 --- a/src/corelib/tools/qlocale.qdoc +++ b/src/corelib/tools/qlocale.qdoc @@ -92,7 +92,7 @@ \note For the current keyboard input locale take a look at QInputMethod::locale(). - QLocale's data is based on Common Locale Data Repository v33.1. + QLocale's data is based on Common Locale Data Repository v34. \sa QString::arg(), QString::toInt(), QString::toDouble(), QInputMethod::locale() diff --git a/src/corelib/tools/qlocale_data_p.h b/src/corelib/tools/qlocale_data_p.h index aeeec2b085..507afdcecd 100644 --- a/src/corelib/tools/qlocale_data_p.h +++ b/src/corelib/tools/qlocale_data_p.h @@ -77,8 +77,8 @@ static const int ImperialMeasurementSystemsCount = // GENERATED PART STARTS HERE /* - This part of the file was generated on 2018-08-13 from the - Common Locale Data Repository v33.1 + This part of the file was generated on 2018-10-19 from the + Common Locale Data Repository v34 http://www.unicode.org/cldr/ @@ -218,7 +218,7 @@ static const QLocaleId likely_subtags[] = { { 50, 0, 0 }, { 50, 7, 98 }, // hu -> hu_Latn_HU { 9, 0, 0 }, { 9, 10, 11 }, // hy -> hy_Armn_AM { 223, 0, 0 }, { 223, 7, 148 }, // hz -> hz_Latn_NA - { 53, 0, 0 }, { 53, 7, 74 }, // ia -> ia_Latn_FR + { 53, 0, 0 }, { 53, 7, 260 }, // ia -> ia_Latn_001 { 52, 0, 0 }, { 52, 7, 101 }, // id -> id_Latn_ID { 149, 0, 0 }, { 149, 7, 157 }, // ig -> ig_Latn_NG { 168, 0, 0 }, { 168, 34, 44 }, // ii -> ii_Yiii_CN @@ -1007,112 +1007,112 @@ static const quint16 locale_index[] = { 0, // Sundanese 384, // Swahili 388, // Swedish - 0, // Sardinian - 391, // Tajik - 392, // Tamil - 396, // Tatar - 397, // Telugu - 398, // Thai - 399, // Tibetan - 401, // Tigrinya - 403, // Tongan - 404, // Tsonga - 405, // Turkish - 407, // Turkmen + 391, // Sardinian + 392, // Tajik + 393, // Tamil + 397, // Tatar + 398, // Telugu + 399, // Thai + 400, // Tibetan + 402, // Tigrinya + 404, // Tongan + 405, // Tsonga + 406, // Turkish + 408, // Turkmen 0, // Tahitian - 408, // Uighur - 409, // Ukrainian - 410, // Urdu - 412, // Uzbek - 415, // Vietnamese - 416, // Volapuk - 417, // Welsh - 418, // Wolof - 419, // Xhosa - 420, // Yiddish - 421, // Yoruba + 409, // Uighur + 410, // Ukrainian + 411, // Urdu + 413, // Uzbek + 416, // Vietnamese + 417, // Volapuk + 418, // Welsh + 419, // Wolof + 420, // Xhosa + 421, // Yiddish + 422, // Yoruba 0, // Zhuang - 423, // Zulu - 424, // Norwegian Nynorsk - 425, // Bosnian - 427, // Divehi - 428, // Manx - 429, // Cornish - 430, // Akan - 431, // Konkani - 432, // Ga - 433, // Igbo - 434, // Kamba - 435, // Syriac - 436, // Blin - 437, // Geez + 424, // Zulu + 425, // Norwegian Nynorsk + 426, // Bosnian + 428, // Divehi + 429, // Manx + 430, // Cornish + 431, // Akan + 432, // Konkani + 433, // Ga + 434, // Igbo + 435, // Kamba + 436, // Syriac + 437, // Blin + 438, // Geez 0, // Koro - 438, // Sidamo - 439, // Atsam - 440, // Tigre - 441, // Jju - 442, // Friulian - 443, // Venda - 444, // Ewe - 446, // Walamo - 447, // Hawaiian - 448, // Tyap - 449, // Nyanja - 450, // Filipino - 451, // Swiss German - 454, // Sichuan Yi - 455, // Kpelle - 456, // Low German - 458, // South Ndebele - 459, // Northern Sotho - 460, // Northern Sami - 463, // Taroko - 464, // Gusii - 465, // Taita - 466, // Fulah - 470, // Kikuyu - 471, // Samburu - 472, // Sena - 473, // North Ndebele - 474, // Rombo - 475, // Tachelhit - 477, // Kabyle - 478, // Nyankole - 479, // Bena - 480, // Vunjo - 481, // Bambara - 483, // Embu - 484, // Cherokee - 485, // Morisyen - 486, // Makonde - 487, // Langi - 488, // Ganda - 489, // Bemba - 490, // Kabuverdianu - 491, // Meru - 492, // Kalenjin - 493, // Nama - 494, // Machame - 495, // Colognian - 496, // Masai - 498, // Soga - 499, // Luyia - 500, // Asu - 501, // Teso - 503, // Saho - 504, // Koyra Chiini - 505, // Rwa - 506, // Luo - 507, // Chiga - 508, // Central Morocco Tamazight - 509, // Koyraboro Senni - 510, // Shambala - 511, // Bodo + 439, // Sidamo + 440, // Atsam + 441, // Tigre + 442, // Jju + 443, // Friulian + 444, // Venda + 445, // Ewe + 447, // Walamo + 448, // Hawaiian + 449, // Tyap + 450, // Nyanja + 451, // Filipino + 452, // Swiss German + 455, // Sichuan Yi + 456, // Kpelle + 457, // Low German + 459, // South Ndebele + 460, // Northern Sotho + 461, // Northern Sami + 464, // Taroko + 465, // Gusii + 466, // Taita + 467, // Fulah + 480, // Kikuyu + 481, // Samburu + 482, // Sena + 483, // North Ndebele + 484, // Rombo + 485, // Tachelhit + 487, // Kabyle + 488, // Nyankole + 489, // Bena + 490, // Vunjo + 491, // Bambara + 493, // Embu + 494, // Cherokee + 495, // Morisyen + 496, // Makonde + 497, // Langi + 498, // Ganda + 499, // Bemba + 500, // Kabuverdianu + 501, // Meru + 502, // Kalenjin + 503, // Nama + 504, // Machame + 505, // Colognian + 506, // Masai + 508, // Soga + 509, // Luyia + 510, // Asu + 511, // Teso + 513, // Saho + 514, // Koyra Chiini + 515, // Rwa + 516, // Luo + 517, // Chiga + 518, // Central Morocco Tamazight + 519, // Koyraboro Senni + 520, // Shambala + 521, // Bodo 0, // Avaric 0, // Chamorro - 512, // Chechen - 513, // Church - 514, // Chuvash + 522, // Chechen + 523, // Church + 524, // Chuvash 0, // Cree 0, // Haitian 0, // Herero @@ -1122,37 +1122,37 @@ static const quint16 locale_index[] = { 0, // Kongo 0, // Kwanyama 0, // Limburgish - 515, // Luba Katanga - 516, // Luxembourgish + 525, // Luba Katanga + 526, // Luxembourgish 0, // Navaho 0, // Ndonga 0, // Ojibwa 0, // Pali - 517, // Walloon - 518, // Aghem - 519, // Basaa - 520, // Zarma - 521, // Duala - 522, // Jola Fonyi - 523, // Ewondo - 524, // Bafia - 525, // Makhuwa Meetto - 526, // Mundang - 527, // Kwasio - 528, // Nuer - 529, // Sakha - 530, // Sangu + 527, // Walloon + 528, // Aghem + 529, // Basaa + 530, // Zarma + 531, // Duala + 532, // Jola Fonyi + 533, // Ewondo + 534, // Bafia + 535, // Makhuwa Meetto + 536, // Mundang + 537, // Kwasio + 538, // Nuer + 539, // Sakha + 540, // Sangu 0, // Congo Swahili - 531, // Tasawaq - 532, // Vai - 534, // Walser - 535, // Yangben + 541, // Tasawaq + 542, // Vai + 544, // Walser + 545, // Yangben 0, // Avestan - 536, // Asturian - 537, // Ngomba - 538, // Kako - 539, // Meta - 540, // Ngiemboon + 546, // Asturian + 547, // Ngomba + 548, // Kako + 549, // Meta + 550, // Ngiemboon 0, // Aragonese 0, // Akkadian 0, // Ancient Egyptian @@ -1182,7 +1182,7 @@ static const quint16 locale_index[] = { 0, // Lycian 0, // Lydian 0, // Mandingo - 541, // Manipuri + 551, // Manipuri 0, // Meroitic 0, // Northern Thai 0, // Old Irish @@ -1201,26 +1201,26 @@ static const quint16 locale_index[] = { 0, // Sora 0, // Sylheti 0, // Tagbanwa - 542, // Tai Dam + 552, // Tai Dam 0, // Tai Nua 0, // Ugaritic - 543, // Akoose - 544, // Lakota - 545, // Standard Moroccan Tamazight - 546, // Mapuche - 547, // Central Kurdish - 549, // Lower Sorbian - 550, // Upper Sorbian - 551, // Kenyang - 552, // Mohawk - 553, // Nko - 554, // Prussian - 555, // Kiche - 556, // Southern Sami - 557, // Lule Sami - 558, // Inari Sami - 559, // Skolt Sami - 560, // Warlpiri + 553, // Akoose + 554, // Lakota + 555, // Standard Moroccan Tamazight + 556, // Mapuche + 557, // Central Kurdish + 559, // Lower Sorbian + 560, // Upper Sorbian + 561, // Kenyang + 562, // Mohawk + 563, // Nko + 564, // Prussian + 565, // Kiche + 566, // Southern Sami + 567, // Lule Sami + 568, // Inari Sami + 569, // Skolt Sami + 570, // Warlpiri 0, // Manichaean Middle Persian 0, // Mende 0, // Ancient North Arabian @@ -1238,10 +1238,10 @@ static const quint16 locale_index[] = { 0, // Bhojpuri 0, // Hieroglyphic Luwian 0, // Literary Chinese - 561, // Mazanderani + 571, // Mazanderani 0, // Mru 0, // Newari - 562, // Northern Luri + 572, // Northern Luri 0, // Palauan 0, // Papiamento 0, // Saraiki @@ -1249,7 +1249,7 @@ static const quint16 locale_index[] = { 0, // Tok Pisin 0, // Tuvalu 0, // Uncoded Languages - 564, // Cantonese + 574, // Cantonese 0, // Osage 0, // Tangut 0 // trailing 0 @@ -1261,568 +1261,578 @@ static const QLocaleData locale_data[] = { { 3, 7, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 35,18 , 18,7 , 25,12 , 185,48 , 233,111 , 134,24 , 185,48 , 233,111 , 134,24 , 113,28 , 141,55 , 85,14 , 113,28 , 141,55 , 85,14 , 2,2 , 2,2 , 45,4 , 5,17 , 22,23 , {69,84,66}, 0,2 , 7,24 , 4,4 , 4,0 , 0,6 , 6,10 , 2, 1, 7, 6, 7 }, // Oromo/Latin/Ethiopia { 3, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 35,18 , 37,5 , 8,10 , 185,48 , 233,111 , 344,24 , 185,48 , 233,111 , 134,24 , 113,28 , 141,55 , 196,14 , 113,28 , 141,55 , 196,14 , 2,2 , 2,2 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 0,7 , 4,4 , 4,0 , 0,6 , 16,8 , 2, 1, 7, 6, 7 }, // Oromo/Latin/Kenya { 4, 7, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,84,66}, 0,0 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Afar/Latin/Ethiopia - { 5, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 53,10 , 80,18 , 37,5 , 8,10 , 416,59 , 475,92 , 134,24 , 416,59 , 475,92 , 134,24 , 210,28 , 238,58 , 296,14 , 210,28 , 238,58 , 296,14 , 4,3 , 4,3 , 49,5 , 5,17 , 22,23 , {90,65,82}, 5,1 , 31,67 , 4,4 , 4,0 , 24,9 , 33,11 , 2, 1, 7, 6, 7 }, // Afrikaans/Latin/South Africa - { 5, 7, 148, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 53,10 , 98,16 , 37,5 , 8,10 , 416,59 , 475,92 , 134,24 , 416,59 , 475,92 , 134,24 , 210,28 , 238,58 , 296,14 , 210,28 , 238,58 , 296,14 , 4,3 , 4,3 , 49,5 , 5,17 , 22,23 , {78,65,68}, 6,1 , 98,55 , 4,4 , 4,0 , 24,9 , 44,7 , 2, 1, 1, 6, 7 }, // Afrikaans/Latin/Namibia - { 6, 7, 2, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 14,9 , 14,9 , 114,6 , 10,17 , 18,7 , 42,13 , 567,50 , 617,78 , 695,27 , 722,50 , 772,78 , 850,27 , 310,28 , 338,58 , 396,15 , 310,28 , 411,58 , 396,15 , 7,11 , 7,10 , 54,4 , 5,17 , 22,23 , {65,76,76}, 7,4 , 153,45 , 13,5 , 4,0 , 51,5 , 56,8 , 0, 0, 1, 6, 7 }, // Albanian/Latin/Albania - { 6, 7, 127, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 14,9 , 14,9 , 114,6 , 10,17 , 37,5 , 8,10 , 567,50 , 617,78 , 695,27 , 722,50 , 772,78 , 850,27 , 310,28 , 338,58 , 396,15 , 310,28 , 411,58 , 396,15 , 7,11 , 7,10 , 54,4 , 5,17 , 22,23 , {77,75,68}, 11,3 , 198,54 , 13,5 , 4,0 , 51,5 , 64,8 , 2, 1, 1, 6, 7 }, // Albanian/Latin/Macedonia - { 6, 7, 257, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 14,9 , 14,9 , 114,6 , 10,17 , 37,5 , 8,10 , 567,50 , 617,78 , 695,27 , 722,50 , 772,78 , 850,27 , 310,28 , 338,58 , 396,15 , 310,28 , 411,58 , 396,15 , 7,11 , 7,10 , 54,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 252,21 , 13,5 , 4,0 , 51,5 , 72,6 , 2, 1, 1, 6, 7 }, // Albanian/Latin/Kosovo - { 7, 14, 69, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 23,6 , 23,6 , 29,9 , 38,8 , 120,10 , 130,17 , 18,7 , 25,12 , 877,46 , 923,61 , 984,24 , 877,46 , 923,61 , 984,24 , 469,27 , 496,28 , 524,14 , 469,27 , 496,28 , 524,14 , 18,3 , 17,4 , 58,3 , 61,23 , 22,23 , {69,84,66}, 15,2 , 273,34 , 4,4 , 4,0 , 78,4 , 82,5 , 2, 1, 7, 6, 7 }, // Amharic/Ethiopic/Ethiopia - { 8, 1, 64, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {69,71,80}, 17,5 , 307,81 , 13,5 , 4,0 , 87,7 , 94,3 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Egypt - { 8, 1, 3, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1107,71 , 1107,71 , 1178,24 , 1107,71 , 1107,71 , 1178,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {68,90,68}, 22,5 , 388,102 , 13,5 , 4,0 , 87,7 , 97,7 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Algeria - { 8, 1, 17, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {66,72,68}, 27,5 , 490,91 , 13,5 , 4,0 , 87,7 , 104,7 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Bahrain - { 8, 1, 42, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {88,65,70}, 32,4 , 581,112 , 13,5 , 4,0 , 87,7 , 111,4 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Chad - { 8, 1, 48, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 37,5 , 8,10 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {75,77,70}, 36,2 , 693,105 , 13,5 , 4,0 , 87,7 , 115,9 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Comoros - { 8, 1, 59, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {68,74,70}, 38,3 , 798,84 , 13,5 , 4,0 , 87,7 , 124,6 , 0, 0, 6, 6, 7 }, // Arabic/Arabic/Djibouti - { 8, 1, 67, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {69,82,78}, 41,3 , 882,91 , 13,5 , 4,0 , 87,7 , 130,7 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/Eritrea - { 8, 1, 103, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1202,92 , 1202,92 , 1294,24 , 1318,92 , 1202,92 , 1294,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {73,81,68}, 44,5 , 973,84 , 13,5 , 4,0 , 87,7 , 137,6 , 0, 0, 6, 5, 6 }, // Arabic/Arabic/Iraq - { 8, 1, 105, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 55,4 , 59,9 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {73,76,83}, 49,1 , 1057,133 , 13,5 , 4,0 , 87,7 , 143,7 , 2, 1, 7, 5, 6 }, // Arabic/Arabic/Israel - { 8, 1, 109, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1202,92 , 1202,92 , 1294,24 , 1202,92 , 1202,92 , 1294,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {74,79,68}, 50,5 , 1190,84 , 13,5 , 4,0 , 87,7 , 150,6 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Jordan - { 8, 1, 115, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {75,87,68}, 55,5 , 1274,84 , 13,5 , 4,0 , 87,7 , 156,6 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Kuwait - { 8, 1, 119, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1202,92 , 1202,92 , 1294,24 , 1202,92 , 1202,92 , 1294,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {76,66,80}, 60,5 , 1358,84 , 13,5 , 4,0 , 87,7 , 162,5 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Lebanon - { 8, 1, 122, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {76,89,68}, 65,5 , 1442,88 , 13,5 , 4,0 , 87,7 , 167,5 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Libya - { 8, 1, 136, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1410,72 , 1410,72 , 1482,24 , 1410,72 , 1410,72 , 1482,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {77,82,85}, 0,0 , 1530,112 , 13,5 , 4,0 , 87,7 , 172,9 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/Mauritania - { 8, 1, 145, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 37,5 , 8,10 , 1506,70 , 1506,70 , 1576,24 , 1506,70 , 1506,70 , 1576,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {77,65,68}, 70,5 , 1642,87 , 13,5 , 4,0 , 87,7 , 181,6 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Morocco - { 8, 1, 162, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {79,77,82}, 75,5 , 1729,77 , 13,5 , 4,0 , 87,7 , 187,5 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Oman - { 8, 1, 165, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1202,92 , 1202,92 , 1294,24 , 1202,92 , 1202,92 , 1294,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {73,76,83}, 49,1 , 1057,133 , 13,5 , 4,0 , 87,7 , 192,18 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/Palestinian Territories - { 8, 1, 175, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {81,65,82}, 80,5 , 1806,70 , 13,5 , 4,0 , 87,7 , 210,3 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Qatar - { 8, 1, 186, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {83,65,82}, 85,5 , 1876,77 , 13,5 , 4,0 , 87,7 , 213,24 , 2, 1, 7, 5, 6 }, // Arabic/Arabic/Saudi Arabia - { 8, 1, 194, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {83,79,83}, 90,1 , 1953,77 , 13,5 , 4,0 , 87,7 , 237,7 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Somalia - { 8, 1, 201, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {83,68,71}, 91,4 , 2030,91 , 13,5 , 4,0 , 87,7 , 244,7 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Sudan - { 8, 1, 207, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1202,92 , 1202,92 , 1294,24 , 1202,92 , 1202,92 , 1294,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {83,89,80}, 95,5 , 2121,77 , 13,5 , 4,0 , 87,7 , 251,5 , 0, 0, 6, 5, 6 }, // Arabic/Arabic/Syria - { 8, 1, 216, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1107,71 , 1107,71 , 1178,24 , 1107,71 , 1107,71 , 1178,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {84,78,68}, 100,5 , 2198,95 , 13,5 , 4,0 , 87,7 , 256,4 , 3, 0, 7, 5, 6 }, // Arabic/Arabic/Tunisia - { 8, 1, 223, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {65,69,68}, 105,5 , 2293,91 , 13,5 , 4,0 , 87,7 , 260,24 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/United Arab Emirates - { 8, 1, 236, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {77,65,68}, 70,5 , 1642,87 , 13,5 , 4,0 , 87,7 , 284,15 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/Western Sahara - { 8, 1, 237, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {89,69,82}, 110,5 , 2384,70 , 13,5 , 4,0 , 87,7 , 299,5 , 0, 0, 7, 5, 6 }, // Arabic/Arabic/Yemen - { 8, 1, 254, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {83,83,80}, 115,1 , 2454,132 , 13,5 , 4,0 , 87,7 , 304,12 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/South Sudan - { 8, 1, 260, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 147,10 , 157,17 , 18,7 , 25,12 , 1008,75 , 1008,75 , 1083,24 , 1008,75 , 1008,75 , 1083,24 , 538,52 , 538,52 , 590,14 , 538,52 , 538,52 , 590,14 , 21,1 , 21,1 , 84,4 , 88,41 , 22,23 , {0,0,0}, 0,0 , 2586,0 , 13,5 , 4,0 , 316,23 , 339,6 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/World - { 9, 10, 11, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 65,7 , 65,7 , 174,8 , 182,20 , 37,5 , 8,10 , 1600,48 , 1648,94 , 1742,24 , 1600,48 , 1766,106 , 1742,24 , 604,28 , 632,62 , 694,14 , 604,28 , 632,62 , 694,14 , 22,2 , 22,2 , 129,6 , 135,17 , 22,23 , {65,77,68}, 116,1 , 2586,46 , 13,5 , 4,0 , 345,7 , 352,8 , 0, 0, 1, 6, 7 }, // Armenian/Armenian/Armenia - { 10, 11, 100, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 72,9 , 72,9 , 202,8 , 210,18 , 68,7 , 75,12 , 1872,64 , 1936,89 , 2025,24 , 1872,64 , 1936,89 , 2025,24 , 708,32 , 740,58 , 798,14 , 708,32 , 740,58 , 798,14 , 24,9 , 24,7 , 152,4 , 156,37 , 22,23 , {73,78,82}, 117,1 , 2632,43 , 8,5 , 4,0 , 360,7 , 367,4 , 2, 1, 7, 7, 7 }, // Assamese/Bengali/India - { 12, 7, 15, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 81,8 , 81,8 , 174,8 , 228,17 , 37,5 , 8,10 , 2049,48 , 2097,77 , 158,27 , 2049,48 , 2174,77 , 158,27 , 812,27 , 839,67 , 99,14 , 812,27 , 839,67 , 99,14 , 0,2 , 0,2 , 193,4 , 5,17 , 22,23 , {65,90,78}, 118,1 , 2675,58 , 8,5 , 4,0 , 371,10 , 381,10 , 2, 1, 1, 6, 7 }, // Azerbaijani/Latin/Azerbaijan + { 5, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 53,10 , 80,17 , 37,5 , 8,10 , 416,59 , 475,92 , 134,24 , 416,59 , 475,92 , 134,24 , 210,28 , 238,58 , 296,14 , 210,28 , 238,58 , 296,14 , 4,3 , 4,3 , 49,5 , 5,17 , 22,23 , {90,65,82}, 5,1 , 31,67 , 4,4 , 4,0 , 24,9 , 33,11 , 2, 1, 7, 6, 7 }, // Afrikaans/Latin/South Africa + { 5, 7, 148, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 53,10 , 97,16 , 37,5 , 8,10 , 416,59 , 475,92 , 134,24 , 416,59 , 475,92 , 134,24 , 210,28 , 238,58 , 296,14 , 210,28 , 238,58 , 296,14 , 4,3 , 4,3 , 49,5 , 5,17 , 22,23 , {78,65,68}, 6,1 , 98,55 , 4,4 , 4,0 , 24,9 , 44,7 , 2, 1, 1, 6, 7 }, // Afrikaans/Latin/Namibia + { 6, 7, 2, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 14,9 , 14,9 , 113,6 , 10,17 , 18,7 , 42,13 , 567,50 , 617,78 , 695,27 , 567,50 , 617,78 , 695,27 , 310,28 , 338,58 , 396,15 , 411,28 , 338,58 , 396,15 , 7,11 , 7,10 , 54,4 , 5,17 , 22,23 , {65,76,76}, 7,4 , 153,45 , 13,5 , 4,0 , 51,5 , 56,8 , 0, 0, 1, 6, 7 }, // Albanian/Latin/Albania + { 6, 7, 127, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 14,9 , 14,9 , 113,6 , 10,17 , 37,5 , 8,10 , 567,50 , 617,78 , 695,27 , 567,50 , 617,78 , 695,27 , 310,28 , 338,58 , 396,15 , 411,28 , 338,58 , 396,15 , 7,11 , 7,10 , 54,4 , 5,17 , 22,23 , {77,75,68}, 11,3 , 198,54 , 13,5 , 4,0 , 51,5 , 64,8 , 2, 1, 1, 6, 7 }, // Albanian/Latin/Macedonia + { 6, 7, 257, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 14,9 , 14,9 , 113,6 , 10,17 , 37,5 , 8,10 , 567,50 , 617,78 , 695,27 , 567,50 , 617,78 , 695,27 , 310,28 , 338,58 , 396,15 , 411,28 , 338,58 , 396,15 , 7,11 , 7,10 , 54,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 252,21 , 13,5 , 4,0 , 51,5 , 72,6 , 2, 1, 1, 6, 7 }, // Albanian/Latin/Kosovo + { 7, 14, 69, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 23,6 , 23,6 , 29,9 , 38,8 , 119,10 , 63,17 , 18,7 , 25,12 , 722,46 , 768,61 , 829,24 , 722,46 , 768,61 , 829,24 , 439,27 , 466,28 , 494,14 , 439,27 , 466,28 , 494,14 , 18,3 , 17,4 , 58,3 , 61,23 , 22,23 , {69,84,66}, 15,2 , 273,34 , 4,4 , 4,0 , 78,4 , 82,5 , 2, 1, 7, 6, 7 }, // Amharic/Ethiopic/Ethiopia + { 8, 1, 64, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 18,7 , 25,12 , 853,75 , 853,75 , 928,24 , 853,75 , 853,75 , 928,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {69,71,80}, 17,5 , 307,81 , 13,5 , 4,0 , 87,7 , 94,3 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Egypt + { 8, 1, 3, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 18,7 , 25,12 , 952,71 , 952,71 , 1023,24 , 952,71 , 952,71 , 1023,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {68,90,68}, 22,5 , 388,102 , 13,5 , 4,0 , 87,7 , 97,7 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Algeria + { 8, 1, 17, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 18,7 , 25,12 , 853,75 , 853,75 , 928,24 , 853,75 , 853,75 , 928,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {66,72,68}, 27,5 , 490,91 , 13,5 , 4,0 , 87,7 , 104,7 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Bahrain + { 8, 1, 42, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 18,7 , 25,12 , 853,75 , 853,75 , 928,24 , 853,75 , 853,75 , 928,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {88,65,70}, 32,4 , 581,112 , 13,5 , 4,0 , 87,7 , 111,4 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Chad + { 8, 1, 48, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 37,5 , 8,10 , 853,75 , 853,75 , 928,24 , 853,75 , 853,75 , 928,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {75,77,70}, 36,2 , 693,105 , 13,5 , 4,0 , 87,7 , 115,9 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Comoros + { 8, 1, 59, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 18,7 , 25,12 , 853,75 , 853,75 , 928,24 , 853,75 , 853,75 , 928,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {68,74,70}, 38,3 , 798,84 , 13,5 , 4,0 , 87,7 , 124,6 , 0, 0, 6, 6, 7 }, // Arabic/Arabic/Djibouti + { 8, 1, 67, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 18,7 , 25,12 , 853,75 , 853,75 , 928,24 , 853,75 , 853,75 , 928,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {69,82,78}, 41,3 , 882,91 , 13,5 , 4,0 , 87,7 , 130,7 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/Eritrea + { 8, 1, 103, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 18,7 , 25,12 , 1047,92 , 1047,92 , 1139,24 , 1163,92 , 1047,92 , 1139,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {73,81,68}, 44,5 , 973,84 , 13,5 , 4,0 , 87,7 , 137,6 , 0, 0, 6, 5, 6 }, // Arabic/Arabic/Iraq + { 8, 1, 105, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 55,4 , 59,9 , 853,75 , 853,75 , 928,24 , 853,75 , 853,75 , 928,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {73,76,83}, 49,1 , 1057,133 , 13,5 , 4,0 , 87,7 , 143,7 , 2, 1, 7, 5, 6 }, // Arabic/Arabic/Israel + { 8, 1, 109, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 18,7 , 25,12 , 1047,92 , 1047,92 , 1139,24 , 1047,92 , 1047,92 , 1139,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {74,79,68}, 50,5 , 1190,84 , 13,5 , 4,0 , 87,7 , 150,6 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Jordan + { 8, 1, 115, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 18,7 , 25,12 , 853,75 , 853,75 , 928,24 , 853,75 , 853,75 , 928,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {75,87,68}, 55,5 , 1274,84 , 13,5 , 4,0 , 87,7 , 156,6 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Kuwait + { 8, 1, 119, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 18,7 , 25,12 , 1047,92 , 1047,92 , 1139,24 , 1047,92 , 1047,92 , 1139,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {76,66,80}, 60,5 , 1358,84 , 13,5 , 4,0 , 87,7 , 162,5 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Lebanon + { 8, 1, 122, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 18,7 , 25,12 , 853,75 , 853,75 , 928,24 , 853,75 , 853,75 , 928,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {76,89,68}, 65,5 , 1442,88 , 13,5 , 4,0 , 87,7 , 167,5 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Libya + { 8, 1, 136, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 18,7 , 25,12 , 1255,72 , 1255,72 , 1327,24 , 1255,72 , 1255,72 , 1327,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {77,82,85}, 70,4 , 1530,112 , 13,5 , 4,0 , 87,7 , 172,9 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/Mauritania + { 8, 1, 145, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 37,5 , 8,10 , 1351,70 , 1351,70 , 1421,24 , 1351,70 , 1351,70 , 1421,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {77,65,68}, 74,5 , 1642,87 , 13,5 , 4,0 , 87,7 , 181,6 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/Morocco + { 8, 1, 162, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 18,7 , 25,12 , 853,75 , 853,75 , 928,24 , 853,75 , 853,75 , 928,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {79,77,82}, 79,5 , 1729,77 , 13,5 , 4,0 , 87,7 , 187,5 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Oman + { 8, 1, 165, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 18,7 , 25,12 , 1047,92 , 1047,92 , 1139,24 , 1047,92 , 1047,92 , 1139,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {73,76,83}, 49,1 , 1057,133 , 13,5 , 4,0 , 87,7 , 192,18 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/Palestinian Territories + { 8, 1, 175, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 18,7 , 25,12 , 853,75 , 853,75 , 928,24 , 853,75 , 853,75 , 928,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {81,65,82}, 84,5 , 1806,70 , 13,5 , 4,0 , 87,7 , 210,3 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Qatar + { 8, 1, 186, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 18,7 , 25,12 , 853,75 , 853,75 , 928,24 , 853,75 , 853,75 , 928,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {83,65,82}, 89,5 , 1876,77 , 13,5 , 4,0 , 87,7 , 213,24 , 2, 1, 7, 5, 6 }, // Arabic/Arabic/Saudi Arabia + { 8, 1, 194, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 18,7 , 25,12 , 853,75 , 853,75 , 928,24 , 853,75 , 853,75 , 928,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {83,79,83}, 94,1 , 1953,77 , 13,5 , 4,0 , 87,7 , 237,7 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Somalia + { 8, 1, 201, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 18,7 , 25,12 , 853,75 , 853,75 , 928,24 , 853,75 , 853,75 , 928,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {83,68,71}, 95,4 , 2030,91 , 13,5 , 4,0 , 87,7 , 244,7 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Sudan + { 8, 1, 207, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 18,7 , 25,12 , 1047,92 , 1047,92 , 1139,24 , 1047,92 , 1047,92 , 1139,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {83,89,80}, 99,5 , 2121,77 , 13,5 , 4,0 , 87,7 , 251,5 , 0, 0, 6, 5, 6 }, // Arabic/Arabic/Syria + { 8, 1, 216, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 18,7 , 25,12 , 952,71 , 952,71 , 1023,24 , 952,71 , 952,71 , 1023,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {84,78,68}, 104,5 , 2198,95 , 13,5 , 4,0 , 87,7 , 256,4 , 3, 0, 1, 6, 7 }, // Arabic/Arabic/Tunisia + { 8, 1, 223, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 18,7 , 25,12 , 853,75 , 853,75 , 928,24 , 853,75 , 853,75 , 928,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {65,69,68}, 109,5 , 2293,91 , 13,5 , 4,0 , 87,7 , 260,24 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/United Arab Emirates + { 8, 1, 236, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 18,7 , 25,12 , 853,75 , 853,75 , 928,24 , 853,75 , 853,75 , 928,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {77,65,68}, 74,5 , 1642,87 , 13,5 , 4,0 , 87,7 , 284,15 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/Western Sahara + { 8, 1, 237, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 18,7 , 25,12 , 853,75 , 853,75 , 928,24 , 853,75 , 853,75 , 928,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {89,69,82}, 114,5 , 2384,70 , 13,5 , 4,0 , 87,7 , 299,5 , 0, 0, 7, 5, 6 }, // Arabic/Arabic/Yemen + { 8, 1, 254, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 18,7 , 25,12 , 853,75 , 853,75 , 928,24 , 853,75 , 853,75 , 928,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {83,83,80}, 119,1 , 2454,132 , 13,5 , 4,0 , 87,7 , 304,12 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/South Sudan + { 8, 1, 260, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,7 , 59,6 , 129,10 , 139,17 , 18,7 , 25,12 , 853,75 , 853,75 , 928,24 , 853,75 , 853,75 , 928,24 , 508,52 , 508,52 , 560,14 , 508,52 , 508,52 , 560,14 , 21,1 , 21,1 , 84,4 , 88,47 , 22,23 , {0,0,0}, 0,0 , 2586,0 , 13,5 , 4,0 , 316,23 , 339,6 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/World + { 9, 10, 11, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 65,7 , 65,7 , 156,8 , 164,20 , 37,5 , 8,10 , 1445,48 , 1493,94 , 1587,24 , 1445,48 , 1611,106 , 1587,24 , 574,28 , 602,62 , 664,14 , 574,28 , 602,62 , 664,14 , 0,2 , 0,2 , 135,6 , 141,17 , 22,23 , {65,77,68}, 120,1 , 2586,46 , 13,5 , 4,0 , 345,7 , 352,8 , 2, 0, 1, 6, 7 }, // Armenian/Armenian/Armenia + { 10, 11, 100, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 72,9 , 72,9 , 184,8 , 192,18 , 68,7 , 75,12 , 1717,64 , 1781,89 , 1870,24 , 1717,64 , 1781,89 , 1870,24 , 678,32 , 710,58 , 768,14 , 678,32 , 710,58 , 768,14 , 22,9 , 22,7 , 158,4 , 162,37 , 22,23 , {73,78,82}, 121,1 , 2632,43 , 8,5 , 4,0 , 360,7 , 367,4 , 2, 1, 7, 7, 7 }, // Assamese/Bengali/India + { 12, 7, 15, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 81,8 , 81,8 , 156,8 , 210,17 , 37,5 , 8,10 , 1894,48 , 1942,77 , 158,27 , 1894,48 , 2019,77 , 158,27 , 782,27 , 809,67 , 99,14 , 782,27 , 809,67 , 99,14 , 0,2 , 0,2 , 199,4 , 5,17 , 22,23 , {65,90,78}, 122,1 , 2675,58 , 13,5 , 4,0 , 371,10 , 381,10 , 2, 1, 1, 6, 7 }, // Azerbaijani/Latin/Azerbaijan { 12, 1, 102, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,82,82}, 0,0 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 6, 5, 5 }, // Azerbaijani/Arabic/Iran - { 12, 2, 15, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 174,8 , 228,17 , 37,5 , 8,10 , 2251,48 , 2299,77 , 158,27 , 2251,48 , 2376,77 , 158,27 , 906,27 , 933,67 , 99,14 , 906,27 , 933,67 , 99,14 , 33,2 , 31,2 , 45,4 , 5,17 , 22,23 , {65,90,78}, 118,1 , 2733,12 , 8,5 , 4,0 , 391,10 , 401,10 , 2, 1, 1, 6, 7 }, // Azerbaijani/Cyrillic/Azerbaijan - { 13, 2, 178, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {82,85,66}, 119,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Bashkir/Cyrillic/Russia - { 14, 7, 197, 44, 46, 59, 37, 48, 8722, 43, 101, 8220, 8221, 8220, 8221, 0,6 , 0,6 , 89,9 , 89,9 , 245,6 , 251,36 , 37,5 , 87,12 , 2453,60 , 2513,93 , 2606,24 , 2453,60 , 2630,93 , 2606,24 , 1000,28 , 1028,68 , 1096,14 , 1000,28 , 1110,68 , 1096,14 , 0,2 , 0,2 , 197,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 2745,20 , 13,5 , 4,0 , 411,7 , 418,8 , 2, 1, 1, 6, 7 }, // Basque/Latin/Spain - { 15, 11, 18, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 98,9 , 98,9 , 287,6 , 210,18 , 18,7 , 25,12 , 2723,90 , 2723,90 , 2813,33 , 2846,77 , 2723,90 , 2813,33 , 1178,37 , 1215,58 , 1273,18 , 1178,37 , 1291,58 , 1273,18 , 0,2 , 0,2 , 152,4 , 5,17 , 22,23 , {66,68,84}, 120,1 , 2765,49 , 0,4 , 4,0 , 426,5 , 431,8 , 2, 1, 7, 6, 7 }, // Bengali/Bengali/Bangladesh - { 15, 11, 100, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 98,9 , 98,9 , 287,6 , 210,18 , 18,7 , 25,12 , 2723,90 , 2723,90 , 2813,33 , 2846,77 , 2723,90 , 2813,33 , 1178,37 , 1215,58 , 1273,18 , 1178,37 , 1291,58 , 1273,18 , 0,2 , 0,2 , 152,4 , 5,17 , 22,23 , {73,78,82}, 117,1 , 2814,43 , 0,4 , 4,0 , 426,5 , 439,4 , 2, 1, 7, 7, 7 }, // Bengali/Bengali/India - { 16, 31, 25, 46, 44, 59, 37, 3872, 45, 43, 101, 8220, 8221, 8216, 8217, 107,9 , 107,9 , 107,9 , 107,9 , 53,10 , 293,30 , 99,22 , 121,27 , 2923,63 , 2986,191 , 3177,27 , 3204,27 , 3231,132 , 3363,27 , 1349,34 , 1383,79 , 1462,27 , 1349,34 , 1383,79 , 1462,27 , 35,5 , 33,6 , 45,4 , 5,17 , 22,23 , {66,84,78}, 121,3 , 2857,15 , 4,4 , 4,0 , 443,6 , 449,5 , 2, 1, 7, 6, 7 }, // Dzongkha/Tibetan/Bhutan - { 19, 7, 74, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 98,16 , 37,5 , 8,10 , 3390,63 , 3453,78 , 3531,36 , 3390,63 , 3453,78 , 3531,36 , 1489,33 , 1522,43 , 1565,18 , 1489,33 , 1522,43 , 1565,18 , 40,4 , 39,4 , 204,7 , 211,17 , 228,23 , {69,85,82}, 14,1 , 2872,36 , 13,5 , 4,0 , 454,9 , 463,5 , 2, 1, 1, 6, 7 }, // Breton/Latin/France - { 20, 2, 33, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8222, 8220, 0,6 , 0,6 , 116,7 , 116,7 , 323,12 , 335,22 , 148,9 , 157,14 , 3567,49 , 3616,82 , 3698,24 , 3567,49 , 3616,82 , 3698,24 , 1583,21 , 1604,55 , 1659,14 , 1583,21 , 1604,55 , 1659,14 , 44,6 , 43,6 , 251,7 , 5,17 , 22,23 , {66,71,78}, 124,3 , 2908,47 , 13,5 , 4,0 , 468,9 , 477,8 , 2, 1, 1, 6, 7 }, // Bulgarian/Cyrillic/Bulgaria - { 21, 25, 147, 46, 44, 4170, 37, 4160, 45, 43, 101, 8220, 8221, 8216, 8217, 123,5 , 123,5 , 128,10 , 128,10 , 357,8 , 365,18 , 171,6 , 177,10 , 3722,43 , 3765,88 , 3853,24 , 3722,43 , 3765,88 , 3853,24 , 1673,54 , 1673,54 , 1727,14 , 1673,54 , 1673,54 , 1727,14 , 50,5 , 49,3 , 258,5 , 5,17 , 22,23 , {77,77,75}, 127,1 , 2955,29 , 13,5 , 4,0 , 485,6 , 485,6 , 0, 0, 7, 6, 7 }, // Burmese/Myanmar/Myanmar - { 22, 2, 20, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 138,7 , 138,7 , 383,7 , 335,22 , 37,5 , 187,11 , 3877,48 , 3925,95 , 4020,24 , 4044,48 , 4092,98 , 4020,24 , 1741,21 , 1762,56 , 1818,14 , 1741,21 , 1762,56 , 1818,14 , 0,2 , 0,2 , 263,5 , 268,17 , 22,23 , {66,89,78}, 0,2 , 2984,89 , 13,5 , 4,0 , 491,10 , 501,8 , 2, 0, 1, 6, 7 }, // Belarusian/Cyrillic/Belarus - { 23, 20, 36, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 145,9 , 154,9 , 287,6 , 98,16 , 18,7 , 25,12 , 4190,71 , 4190,71 , 4261,24 , 4190,71 , 4190,71 , 4261,24 , 1832,47 , 1832,47 , 1879,14 , 1832,47 , 1832,47 , 1879,14 , 0,2 , 0,2 , 285,2 , 5,17 , 22,23 , {75,72,82}, 128,1 , 3073,29 , 0,4 , 4,0 , 509,5 , 514,7 , 2, 1, 7, 6, 7 }, // Khmer/Khmer/Cambodia - { 24, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 163,7 , 163,7 , 287,6 , 390,22 , 55,4 , 59,9 , 4285,60 , 4345,82 , 4427,36 , 4463,93 , 4556,115 , 4427,36 , 1893,28 , 1921,60 , 1981,21 , 1893,28 , 1921,60 , 1981,21 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 521,6 , 527,7 , 2, 1, 1, 6, 7 }, // Catalan/Latin/Spain - { 24, 7, 5, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 163,7 , 163,7 , 287,6 , 390,22 , 55,4 , 59,9 , 4285,60 , 4345,82 , 4427,36 , 4463,93 , 4556,115 , 4427,36 , 1893,28 , 1921,60 , 1981,21 , 1893,28 , 1921,60 , 1981,21 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 521,6 , 534,7 , 2, 1, 1, 6, 7 }, // Catalan/Latin/Andorra - { 24, 7, 74, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 163,7 , 163,7 , 287,6 , 390,22 , 55,4 , 59,9 , 4285,60 , 4345,82 , 4427,36 , 4463,93 , 4556,115 , 4427,36 , 1893,28 , 1921,60 , 1981,21 , 1893,28 , 1921,60 , 1981,21 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 521,6 , 541,6 , 2, 1, 1, 6, 7 }, // Catalan/Latin/France - { 24, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 163,7 , 163,7 , 287,6 , 390,22 , 55,4 , 59,9 , 4285,60 , 4345,82 , 4427,36 , 4463,93 , 4556,115 , 4427,36 , 1893,28 , 1921,60 , 1981,21 , 1893,28 , 1921,60 , 1981,21 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 521,6 , 547,6 , 2, 1, 1, 6, 7 }, // Catalan/Latin/Italy - { 25, 5, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 170,5 , 170,5 , 175,5 , 175,5 , 412,8 , 420,13 , 198,6 , 204,11 , 4671,39 , 4710,38 , 158,27 , 4671,39 , 4710,38 , 158,27 , 2002,21 , 2023,28 , 2051,14 , 2002,21 , 2023,28 , 2051,14 , 60,2 , 57,2 , 287,2 , 289,21 , 22,23 , {67,78,89}, 129,1 , 3122,13 , 4,4 , 4,0 , 553,4 , 557,2 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/China - { 25, 5, 97, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 170,5 , 170,5 , 175,5 , 175,5 , 287,6 , 420,13 , 198,6 , 204,11 , 4671,39 , 4710,38 , 158,27 , 4671,39 , 4710,38 , 158,27 , 2002,21 , 2023,28 , 2051,14 , 2002,21 , 2023,28 , 2051,14 , 60,2 , 57,2 , 287,2 , 289,21 , 22,23 , {72,75,68}, 130,3 , 3135,11 , 4,4 , 4,0 , 553,4 , 559,9 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/Hong Kong - { 25, 5, 126, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 170,5 , 170,5 , 175,5 , 175,5 , 287,6 , 420,13 , 198,6 , 204,11 , 4671,39 , 4710,38 , 158,27 , 4671,39 , 4710,38 , 158,27 , 2002,21 , 2023,28 , 2051,14 , 2002,21 , 2023,28 , 2051,14 , 60,2 , 57,2 , 287,2 , 289,21 , 22,23 , {77,79,80}, 133,4 , 3146,13 , 4,4 , 4,0 , 553,4 , 568,9 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/Macau - { 25, 5, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 170,5 , 170,5 , 175,5 , 175,5 , 27,8 , 420,13 , 198,6 , 204,11 , 4671,39 , 4710,38 , 158,27 , 4671,39 , 4710,38 , 158,27 , 2002,21 , 2023,28 , 2051,14 , 2002,21 , 2023,28 , 2051,14 , 60,2 , 57,2 , 287,2 , 289,21 , 22,23 , {83,71,68}, 6,1 , 3159,15 , 4,4 , 4,0 , 553,4 , 577,3 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/Singapore - { 25, 6, 97, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 170,5 , 170,5 , 180,5 , 180,5 , 433,8 , 420,13 , 198,6 , 215,13 , 4671,39 , 4671,39 , 158,27 , 4671,39 , 4671,39 , 158,27 , 2065,21 , 2023,28 , 2051,14 , 2065,21 , 2023,28 , 2051,14 , 60,2 , 57,2 , 310,3 , 5,17 , 22,23 , {72,75,68}, 130,3 , 3135,11 , 18,5 , 4,0 , 580,4 , 584,9 , 2, 1, 7, 6, 7 }, // Chinese/Traditional Han/Hong Kong - { 25, 6, 126, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 170,5 , 170,5 , 180,5 , 180,5 , 433,8 , 420,13 , 198,6 , 215,13 , 4671,39 , 4671,39 , 158,27 , 4671,39 , 4671,39 , 158,27 , 2065,21 , 2023,28 , 2051,14 , 2065,21 , 2023,28 , 2051,14 , 60,2 , 57,2 , 310,3 , 5,17 , 22,23 , {77,79,80}, 133,4 , 3174,13 , 18,5 , 4,0 , 580,4 , 593,9 , 2, 1, 7, 6, 7 }, // Chinese/Traditional Han/Macau - { 25, 6, 208, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 170,5 , 170,5 , 175,5 , 175,5 , 412,8 , 441,14 , 198,6 , 215,13 , 4671,39 , 4671,39 , 158,27 , 4671,39 , 4671,39 , 158,27 , 2065,21 , 2023,28 , 2051,14 , 2065,21 , 2023,28 , 2051,14 , 60,2 , 57,2 , 45,4 , 5,17 , 22,23 , {84,87,68}, 6,1 , 3187,13 , 4,4 , 4,0 , 580,4 , 602,2 , 2, 0, 7, 6, 7 }, // Chinese/Traditional Han/Taiwan + { 12, 2, 15, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 156,8 , 210,17 , 37,5 , 8,10 , 2096,48 , 2144,77 , 158,27 , 2096,48 , 2221,77 , 158,27 , 876,27 , 903,67 , 99,14 , 876,27 , 903,67 , 99,14 , 31,2 , 29,2 , 45,4 , 5,17 , 22,23 , {65,90,78}, 122,1 , 2733,12 , 13,5 , 4,0 , 391,10 , 401,10 , 2, 1, 1, 6, 7 }, // Azerbaijani/Cyrillic/Azerbaijan + { 13, 2, 178, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {82,85,66}, 123,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Bashkir/Cyrillic/Russia + { 14, 7, 197, 44, 46, 59, 37, 48, 8722, 43, 101, 8220, 8221, 8220, 8221, 0,6 , 0,6 , 89,9 , 89,9 , 227,6 , 233,36 , 37,5 , 87,12 , 2298,60 , 2358,93 , 2451,24 , 2298,60 , 2358,93 , 2451,24 , 970,28 , 998,68 , 1066,14 , 970,28 , 998,68 , 1066,14 , 0,2 , 0,2 , 203,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 2745,20 , 13,5 , 4,0 , 411,7 , 418,8 , 2, 1, 1, 6, 7 }, // Basque/Latin/Spain + { 15, 11, 18, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 98,9 , 98,9 , 269,6 , 192,18 , 18,7 , 25,12 , 2475,90 , 2475,90 , 2565,33 , 2598,77 , 2475,90 , 2565,33 , 1080,37 , 1117,58 , 1175,18 , 1080,37 , 1117,58 , 1175,18 , 0,2 , 0,2 , 158,4 , 5,17 , 22,23 , {66,68,84}, 124,1 , 2765,49 , 0,4 , 4,0 , 426,5 , 431,8 , 2, 1, 7, 6, 7 }, // Bengali/Bengali/Bangladesh + { 15, 11, 100, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 98,9 , 98,9 , 269,6 , 192,18 , 18,7 , 25,12 , 2475,90 , 2475,90 , 2565,33 , 2598,77 , 2475,90 , 2565,33 , 1080,37 , 1117,58 , 1175,18 , 1080,37 , 1117,58 , 1175,18 , 0,2 , 0,2 , 158,4 , 5,17 , 22,23 , {73,78,82}, 121,1 , 2814,43 , 0,4 , 4,0 , 426,5 , 439,4 , 2, 1, 7, 7, 7 }, // Bengali/Bengali/India + { 16, 31, 25, 46, 44, 59, 37, 3872, 45, 43, 101, 8220, 8221, 8216, 8217, 107,9 , 107,9 , 107,9 , 107,9 , 53,10 , 275,30 , 99,22 , 121,27 , 2675,63 , 2738,191 , 2929,27 , 2956,27 , 2983,132 , 3115,27 , 1193,34 , 1227,79 , 1306,27 , 1193,34 , 1227,79 , 1306,27 , 33,5 , 31,6 , 45,4 , 5,17 , 22,23 , {66,84,78}, 125,3 , 2857,15 , 4,4 , 4,0 , 443,6 , 449,5 , 2, 1, 7, 6, 7 }, // Dzongkha/Tibetan/Bhutan + { 19, 7, 74, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 97,16 , 37,5 , 8,10 , 3142,63 , 3205,78 , 3283,36 , 3142,63 , 3205,78 , 3283,36 , 1333,33 , 1366,43 , 1409,18 , 1333,33 , 1366,43 , 1409,18 , 38,4 , 37,4 , 210,7 , 217,17 , 22,23 , {69,85,82}, 14,1 , 2872,36 , 13,5 , 4,0 , 454,9 , 463,5 , 2, 1, 1, 6, 7 }, // Breton/Latin/France + { 20, 2, 33, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8222, 8220, 0,6 , 0,6 , 116,7 , 116,7 , 305,12 , 317,22 , 148,9 , 157,14 , 3319,49 , 3368,82 , 3450,24 , 3319,49 , 3368,82 , 3450,24 , 1427,21 , 1448,55 , 1503,14 , 1427,21 , 1448,55 , 1503,14 , 42,6 , 41,6 , 234,7 , 5,17 , 22,23 , {66,71,78}, 128,3 , 2908,47 , 13,5 , 4,0 , 468,9 , 477,8 , 2, 1, 1, 6, 7 }, // Bulgarian/Cyrillic/Bulgaria + { 21, 25, 147, 46, 44, 4170, 37, 4160, 45, 43, 101, 8220, 8221, 8216, 8217, 123,5 , 123,5 , 128,10 , 128,10 , 339,8 , 347,18 , 171,6 , 177,10 , 3474,43 , 3517,88 , 3605,24 , 3474,43 , 3517,88 , 3605,24 , 1517,54 , 1517,54 , 1571,14 , 1517,54 , 1517,54 , 1571,14 , 48,5 , 47,3 , 241,5 , 5,17 , 22,23 , {77,77,75}, 131,1 , 2955,29 , 13,5 , 4,0 , 485,6 , 485,6 , 0, 0, 7, 6, 7 }, // Burmese/Myanmar/Myanmar + { 22, 2, 20, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 138,7 , 138,7 , 365,7 , 317,22 , 37,5 , 187,11 , 3629,48 , 3677,95 , 3772,24 , 3796,48 , 3844,98 , 3772,24 , 1585,21 , 1606,56 , 1662,14 , 1585,21 , 1606,56 , 1662,14 , 0,2 , 0,2 , 246,5 , 251,17 , 22,23 , {66,89,78}, 0,2 , 2984,89 , 13,5 , 4,0 , 491,10 , 501,8 , 2, 0, 1, 6, 7 }, // Belarusian/Cyrillic/Belarus + { 23, 20, 36, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 145,9 , 154,9 , 269,6 , 97,16 , 18,7 , 25,12 , 3942,71 , 3942,71 , 4013,24 , 3942,71 , 3942,71 , 4013,24 , 1676,40 , 1716,46 , 1762,14 , 1676,40 , 1776,47 , 1762,14 , 0,2 , 0,2 , 268,2 , 5,17 , 22,23 , {75,72,82}, 132,1 , 3073,29 , 0,4 , 4,0 , 509,5 , 514,7 , 2, 1, 7, 6, 7 }, // Khmer/Khmer/Cambodia + { 24, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 163,7 , 163,7 , 269,6 , 372,22 , 55,4 , 59,9 , 4037,60 , 4097,82 , 4179,36 , 4215,93 , 4308,115 , 4179,36 , 1823,28 , 1851,60 , 1911,21 , 1823,28 , 1851,60 , 1911,21 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 521,6 , 527,7 , 2, 1, 1, 6, 7 }, // Catalan/Latin/Spain + { 24, 7, 5, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 163,7 , 163,7 , 269,6 , 372,22 , 55,4 , 59,9 , 4037,60 , 4097,82 , 4179,36 , 4215,93 , 4308,115 , 4179,36 , 1823,28 , 1851,60 , 1911,21 , 1823,28 , 1851,60 , 1911,21 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 521,6 , 534,7 , 2, 1, 1, 6, 7 }, // Catalan/Latin/Andorra + { 24, 7, 74, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 163,7 , 163,7 , 269,6 , 372,22 , 55,4 , 59,9 , 4037,60 , 4097,82 , 4179,36 , 4215,93 , 4308,115 , 4179,36 , 1823,28 , 1851,60 , 1911,21 , 1823,28 , 1851,60 , 1911,21 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 521,6 , 541,6 , 2, 1, 1, 6, 7 }, // Catalan/Latin/France + { 24, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 163,7 , 163,7 , 269,6 , 372,22 , 55,4 , 59,9 , 4037,60 , 4097,82 , 4179,36 , 4215,93 , 4308,115 , 4179,36 , 1823,28 , 1851,60 , 1911,21 , 1823,28 , 1851,60 , 1911,21 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 521,6 , 547,6 , 2, 1, 1, 6, 7 }, // Catalan/Latin/Italy + { 25, 5, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 170,5 , 170,5 , 175,5 , 175,5 , 394,8 , 402,13 , 198,6 , 204,11 , 4423,39 , 4462,38 , 158,27 , 4423,39 , 4462,38 , 158,27 , 1932,21 , 1953,28 , 1981,14 , 1932,21 , 1953,28 , 1981,14 , 58,2 , 55,2 , 270,2 , 272,21 , 22,23 , {67,78,89}, 133,1 , 3122,13 , 4,4 , 4,0 , 553,4 , 557,2 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/China + { 25, 5, 97, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 170,5 , 170,5 , 175,5 , 175,5 , 269,6 , 402,13 , 198,6 , 204,11 , 4423,39 , 4462,38 , 158,27 , 4423,39 , 4462,38 , 158,27 , 1932,21 , 1953,28 , 1981,14 , 1932,21 , 1953,28 , 1981,14 , 58,2 , 55,2 , 270,2 , 272,21 , 22,23 , {72,75,68}, 134,3 , 3135,11 , 4,4 , 4,0 , 553,4 , 559,9 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/Hong Kong + { 25, 5, 126, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 170,5 , 170,5 , 175,5 , 175,5 , 269,6 , 402,13 , 198,6 , 204,11 , 4423,39 , 4462,38 , 158,27 , 4423,39 , 4462,38 , 158,27 , 1932,21 , 1953,28 , 1981,14 , 1932,21 , 1953,28 , 1981,14 , 58,2 , 55,2 , 270,2 , 272,21 , 22,23 , {77,79,80}, 137,4 , 3146,13 , 4,4 , 4,0 , 553,4 , 568,9 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/Macau + { 25, 5, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 170,5 , 170,5 , 175,5 , 175,5 , 27,8 , 402,13 , 198,6 , 204,11 , 4423,39 , 4462,38 , 158,27 , 4423,39 , 4462,38 , 158,27 , 1932,21 , 1953,28 , 1981,14 , 1932,21 , 1953,28 , 1981,14 , 58,2 , 55,2 , 270,2 , 272,21 , 22,23 , {83,71,68}, 6,1 , 3159,15 , 4,4 , 4,0 , 553,4 , 577,3 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/Singapore + { 25, 6, 97, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 170,5 , 170,5 , 180,5 , 180,5 , 415,8 , 402,13 , 198,6 , 215,13 , 4423,39 , 4423,39 , 158,27 , 4423,39 , 4423,39 , 158,27 , 1995,21 , 1953,28 , 1981,14 , 1995,21 , 1953,28 , 1981,14 , 58,2 , 55,2 , 293,3 , 5,17 , 22,23 , {72,75,68}, 134,3 , 3135,11 , 18,5 , 4,0 , 580,4 , 584,9 , 2, 1, 7, 6, 7 }, // Chinese/Traditional Han/Hong Kong + { 25, 6, 126, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 170,5 , 170,5 , 180,5 , 180,5 , 415,8 , 402,13 , 198,6 , 215,13 , 4423,39 , 4423,39 , 158,27 , 4423,39 , 4423,39 , 158,27 , 1995,21 , 1953,28 , 1981,14 , 1995,21 , 1953,28 , 1981,14 , 58,2 , 55,2 , 293,3 , 5,17 , 22,23 , {77,79,80}, 137,4 , 3174,13 , 18,5 , 4,0 , 580,4 , 593,9 , 2, 1, 7, 6, 7 }, // Chinese/Traditional Han/Macau + { 25, 6, 208, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 170,5 , 170,5 , 175,5 , 175,5 , 394,8 , 423,14 , 198,6 , 215,13 , 4423,39 , 4423,39 , 158,27 , 4423,39 , 4423,39 , 158,27 , 1995,21 , 1953,28 , 1981,14 , 1995,21 , 1953,28 , 1981,14 , 58,2 , 55,2 , 45,4 , 5,17 , 22,23 , {84,87,68}, 6,1 , 3187,13 , 4,4 , 4,0 , 580,4 , 602,2 , 2, 0, 7, 6, 7 }, // Chinese/Traditional Han/Taiwan { 26, 7, 74, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Corsican/Latin/France - { 27, 7, 54, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 163,7 , 163,7 , 455,13 , 468,19 , 37,5 , 87,12 , 4748,49 , 4797,94 , 4891,39 , 4748,49 , 4930,98 , 4891,39 , 2086,28 , 2114,58 , 2172,14 , 2086,28 , 2114,58 , 2186,14 , 0,2 , 0,2 , 313,7 , 5,17 , 22,23 , {72,82,75}, 137,3 , 3200,60 , 13,5 , 4,0 , 604,8 , 612,8 , 2, 1, 1, 6, 7 }, // Croatian/Latin/Croatia - { 27, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 163,7 , 163,7 , 487,9 , 468,19 , 37,5 , 87,12 , 4748,49 , 4797,94 , 4891,39 , 4748,49 , 4930,98 , 4891,39 , 2086,28 , 2114,58 , 2186,14 , 2086,28 , 2114,58 , 2186,14 , 0,2 , 0,2 , 313,7 , 5,17 , 22,23 , {66,65,77}, 140,2 , 3260,85 , 13,5 , 4,0 , 604,8 , 620,19 , 2, 1, 1, 6, 7 }, // Croatian/Latin/Bosnia And Herzegowina - { 28, 7, 57, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 185,7 , 185,7 , 174,8 , 496,17 , 55,4 , 59,9 , 5028,48 , 5076,82 , 158,27 , 5028,48 , 5158,84 , 158,27 , 2200,21 , 2221,49 , 2270,14 , 2200,21 , 2221,49 , 2270,14 , 62,4 , 59,4 , 320,5 , 5,17 , 22,23 , {67,90,75}, 142,2 , 3345,68 , 13,5 , 4,0 , 639,7 , 646,5 , 2, 0, 1, 6, 7 }, // Czech/Latin/Czech Republic - { 29, 7, 58, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 192,8 , 192,8 , 120,10 , 513,23 , 228,5 , 233,10 , 5242,59 , 5301,84 , 134,24 , 5242,59 , 5301,84 , 134,24 , 2284,28 , 2312,51 , 2363,14 , 2377,35 , 2312,51 , 2363,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {68,75,75}, 144,3 , 3413,42 , 13,5 , 4,0 , 651,5 , 656,7 , 2, 0, 1, 6, 7 }, // Danish/Latin/Denmark - { 29, 7, 86, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 192,8 , 192,8 , 120,10 , 513,23 , 228,5 , 233,10 , 5242,59 , 5301,84 , 134,24 , 5242,59 , 5301,84 , 134,24 , 2284,28 , 2312,51 , 2363,14 , 2377,35 , 2312,51 , 2363,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {68,75,75}, 144,3 , 3413,42 , 13,5 , 4,0 , 651,5 , 663,8 , 2, 0, 1, 6, 7 }, // Danish/Latin/Greenland - { 30, 7, 151, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 357,8 , 98,16 , 37,5 , 8,10 , 5385,59 , 5444,88 , 134,24 , 5385,59 , 5444,88 , 134,24 , 2412,21 , 2433,59 , 2492,14 , 2412,21 , 2433,59 , 2492,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3455,19 , 13,5 , 4,0 , 671,10 , 681,9 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Netherlands - { 30, 7, 12, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 357,8 , 98,16 , 37,5 , 8,10 , 5385,59 , 5444,88 , 134,24 , 5385,59 , 5444,88 , 134,24 , 2412,21 , 2433,59 , 2492,14 , 2412,21 , 2433,59 , 2492,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {65,87,71}, 147,4 , 3474,55 , 13,5 , 4,0 , 671,10 , 690,5 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Aruba - { 30, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 536,7 , 98,16 , 37,5 , 8,10 , 5385,59 , 5444,88 , 134,24 , 5385,59 , 5444,88 , 134,24 , 2412,21 , 2433,59 , 2492,14 , 2412,21 , 2433,59 , 2492,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3455,19 , 13,5 , 4,0 , 671,10 , 695,6 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Belgium - { 30, 7, 152, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 357,8 , 98,16 , 37,5 , 8,10 , 5385,59 , 5444,88 , 134,24 , 5385,59 , 5444,88 , 134,24 , 2412,21 , 2433,59 , 2492,14 , 2412,21 , 2433,59 , 2492,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {65,78,71}, 151,4 , 3529,97 , 13,5 , 4,0 , 671,10 , 701,7 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Cura Sao - { 30, 7, 202, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 357,8 , 98,16 , 37,5 , 8,10 , 5385,59 , 5444,88 , 134,24 , 5385,59 , 5444,88 , 134,24 , 2412,21 , 2433,59 , 2492,14 , 2412,21 , 2433,59 , 2492,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {83,82,68}, 6,1 , 3626,58 , 13,5 , 4,0 , 671,10 , 708,8 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Suriname - { 30, 7, 255, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 357,8 , 98,16 , 37,5 , 8,10 , 5385,59 , 5444,88 , 134,24 , 5385,59 , 5444,88 , 134,24 , 2412,21 , 2433,59 , 2492,14 , 2412,21 , 2433,59 , 2492,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3684,61 , 13,5 , 4,0 , 671,10 , 716,19 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Bonaire - { 30, 7, 256, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 357,8 , 98,16 , 37,5 , 8,10 , 5385,59 , 5444,88 , 134,24 , 5385,59 , 5444,88 , 134,24 , 2412,21 , 2433,59 , 2492,14 , 2412,21 , 2433,59 , 2492,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {65,78,71}, 151,4 , 3529,97 , 13,5 , 4,0 , 671,10 , 735,12 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Sint Maarten - { 31, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 543,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3745,35 , 4,4 , 4,0 , 747,16 , 763,13 , 2, 1, 7, 6, 7 }, // English/Latin/United States - { 31, 3, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,83,68}, 155,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // English/Deseret/United States - { 31, 7, 4, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 543,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3745,35 , 4,4 , 4,0 , 776,7 , 783,14 , 2, 1, 7, 6, 7 }, // English/Latin/American Samoa - { 31, 7, 7, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3780,71 , 4,4 , 4,0 , 776,7 , 797,8 , 2, 1, 1, 6, 7 }, // English/Latin/Anguilla - { 31, 7, 9, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3780,71 , 4,4 , 4,0 , 776,7 , 805,17 , 2, 1, 7, 6, 7 }, // English/Latin/Antigua And Barbuda - { 31, 7, 13, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 210,9 , 210,9 , 287,6 , 10,17 , 18,7 , 25,12 , 5532,59 , 48,86 , 134,24 , 5532,59 , 48,86 , 134,24 , 2506,35 , 28,57 , 2541,25 , 2506,35 , 28,57 , 2541,25 , 70,2 , 67,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3851,59 , 4,4 , 4,0 , 822,18 , 840,9 , 2, 1, 7, 6, 7 }, // English/Latin/Australia - { 31, 7, 14, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 8,5 , 4,0 , 776,7 , 849,7 , 2, 1, 1, 6, 7 }, // English/Latin/Austria - { 31, 7, 16, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {66,83,68}, 6,1 , 3930,53 , 4,4 , 4,0 , 776,7 , 856,7 , 2, 1, 7, 6, 7 }, // English/Latin/Bahamas - { 31, 7, 19, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {66,66,68}, 6,1 , 3983,56 , 4,4 , 4,0 , 776,7 , 863,8 , 2, 1, 1, 6, 7 }, // English/Latin/Barbados - { 31, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 27,8 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 13,5 , 4,0 , 776,7 , 871,7 , 2, 1, 1, 6, 7 }, // English/Latin/Belgium - { 31, 7, 22, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 27,8 , 80,18 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {66,90,68}, 6,1 , 4039,47 , 4,4 , 4,0 , 776,7 , 878,6 , 2, 1, 7, 6, 7 }, // English/Latin/Belize - { 31, 7, 24, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {66,77,68}, 6,1 , 4086,53 , 4,4 , 4,0 , 776,7 , 884,7 , 2, 1, 1, 6, 7 }, // English/Latin/Bermuda - { 31, 7, 28, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 27,8 , 80,18 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {66,87,80}, 158,1 , 4139,50 , 4,4 , 4,0 , 776,7 , 891,8 , 2, 1, 7, 6, 7 }, // English/Latin/Botswana - { 31, 7, 31, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 155,3 , 3745,35 , 4,4 , 4,0 , 776,7 , 899,30 , 2, 1, 1, 6, 7 }, // English/Latin/British Indian Ocean Territory - { 31, 7, 35, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 543,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {66,73,70}, 159,3 , 4189,53 , 4,4 , 4,0 , 776,7 , 929,7 , 0, 0, 1, 6, 7 }, // English/Latin/Burundi - { 31, 7, 37, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {88,65,70}, 32,4 , 4242,83 , 4,4 , 4,0 , 776,7 , 936,8 , 0, 0, 1, 6, 7 }, // English/Latin/Cameroon - { 31, 7, 38, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 53,10 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 5532,59 , 48,86 , 134,24 , 2506,35 , 28,57 , 85,14 , 2506,35 , 28,57 , 85,14 , 66,4 , 63,4 , 0,5 , 5,17 , 22,23 , {67,65,68}, 6,1 , 4325,53 , 4,4 , 4,0 , 944,16 , 960,6 , 2, 0, 7, 6, 7 }, // English/Latin/Canada - { 31, 7, 40, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {75,89,68}, 6,1 , 4378,71 , 4,4 , 4,0 , 776,7 , 966,14 , 2, 1, 1, 6, 7 }, // English/Latin/Cayman Islands - { 31, 7, 45, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3851,59 , 4,4 , 4,0 , 776,7 , 980,16 , 2, 1, 1, 6, 7 }, // English/Latin/Christmas Island - { 31, 7, 46, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3851,59 , 4,4 , 4,0 , 776,7 , 996,23 , 2, 1, 1, 6, 7 }, // English/Latin/Cocos Islands - { 31, 7, 51, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {78,90,68}, 6,1 , 4449,62 , 4,4 , 4,0 , 776,7 , 1019,12 , 2, 1, 1, 6, 7 }, // English/Latin/Cook Islands - { 31, 7, 56, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 4,4 , 4,0 , 776,7 , 1031,6 , 2, 1, 1, 6, 7 }, // English/Latin/Cyprus - { 31, 7, 58, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 228,5 , 233,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {68,75,75}, 144,3 , 4511,44 , 13,5 , 4,0 , 776,7 , 1037,7 , 2, 0, 1, 6, 7 }, // English/Latin/Denmark - { 31, 7, 60, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3780,71 , 4,4 , 4,0 , 776,7 , 1044,8 , 2, 1, 7, 6, 7 }, // English/Latin/Dominica - { 31, 7, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {69,82,78}, 41,3 , 4555,50 , 4,4 , 4,0 , 776,7 , 1052,7 , 2, 1, 1, 6, 7 }, // English/Latin/Eritrea - { 31, 7, 70, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {70,75,80}, 115,1 , 4605,74 , 4,4 , 4,0 , 776,7 , 1059,16 , 2, 1, 1, 6, 7 }, // English/Latin/Falkland Islands - { 31, 7, 72, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {70,74,68}, 6,1 , 4679,47 , 4,4 , 4,0 , 776,7 , 1075,4 , 2, 1, 1, 6, 7 }, // English/Latin/Fiji - { 31, 7, 73, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 243,4 , 247,9 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 13,5 , 4,0 , 776,7 , 1079,7 , 2, 1, 1, 6, 7 }, // English/Latin/Finland - { 31, 7, 75, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {71,66,80}, 115,1 , 4726,32 , 4,4 , 4,0 , 776,7 , 1086,8 , 2, 1, 1, 6, 7 }, // English/Latin/Guernsey - { 31, 7, 80, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {71,77,68}, 162,1 , 4758,50 , 4,4 , 4,0 , 776,7 , 1094,6 , 2, 1, 1, 6, 7 }, // English/Latin/Gambia - { 31, 7, 82, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 13,5 , 4,0 , 776,7 , 1100,7 , 2, 1, 1, 6, 7 }, // English/Latin/Germany - { 31, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {71,72,83}, 163,3 , 4808,47 , 4,4 , 4,0 , 776,7 , 1107,5 , 2, 1, 1, 6, 7 }, // English/Latin/Ghana - { 31, 7, 84, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {71,73,80}, 115,1 , 4855,53 , 4,4 , 4,0 , 776,7 , 1112,9 , 2, 1, 1, 6, 7 }, // English/Latin/Gibraltar - { 31, 7, 87, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3780,71 , 4,4 , 4,0 , 776,7 , 1121,7 , 2, 1, 1, 6, 7 }, // English/Latin/Grenada - { 31, 7, 89, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 543,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3745,35 , 4,4 , 4,0 , 776,7 , 1128,4 , 2, 1, 7, 6, 7 }, // English/Latin/Guam - { 31, 7, 93, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {71,89,68}, 6,1 , 4908,56 , 4,4 , 4,0 , 776,7 , 1132,6 , 0, 0, 1, 6, 7 }, // English/Latin/Guyana - { 31, 7, 97, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 433,8 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {72,75,68}, 130,3 , 4964,56 , 4,4 , 4,0 , 776,7 , 1138,19 , 2, 1, 7, 6, 7 }, // English/Latin/Hong Kong - { 31, 7, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 27,8 , 210,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {73,78,82}, 117,1 , 5020,44 , 8,5 , 4,0 , 776,7 , 1157,5 , 2, 1, 7, 7, 7 }, // English/Latin/India - { 31, 7, 104, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 98,16 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 66,4 , 63,4 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 4,4 , 4,0 , 776,7 , 1162,7 , 2, 1, 7, 6, 7 }, // English/Latin/Ireland - { 31, 7, 105, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 55,4 , 59,9 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {73,76,83}, 49,1 , 5064,62 , 4,4 , 4,0 , 776,7 , 1169,6 , 2, 1, 7, 5, 6 }, // English/Latin/Israel - { 31, 7, 107, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 287,6 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {74,77,68}, 6,1 , 5126,53 , 4,4 , 4,0 , 776,7 , 1175,7 , 2, 1, 7, 6, 7 }, // English/Latin/Jamaica - { 31, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {75,69,83}, 2,3 , 5179,53 , 4,4 , 4,0 , 776,7 , 1182,5 , 2, 1, 7, 6, 7 }, // English/Latin/Kenya - { 31, 7, 112, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3851,59 , 4,4 , 4,0 , 776,7 , 1187,8 , 2, 1, 1, 6, 7 }, // English/Latin/Kiribati - { 31, 7, 120, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {90,65,82}, 5,1 , 5232,61 , 4,4 , 4,0 , 776,7 , 1195,7 , 2, 1, 1, 6, 7 }, // English/Latin/Lesotho - { 31, 7, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {76,82,68}, 6,1 , 5293,53 , 4,4 , 4,0 , 776,7 , 1202,7 , 2, 1, 1, 6, 7 }, // English/Latin/Liberia - { 31, 7, 126, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {77,79,80}, 133,4 , 5346,53 , 4,4 , 4,0 , 776,7 , 1209,15 , 2, 1, 7, 6, 7 }, // English/Latin/Macau - { 31, 7, 128, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {77,71,65}, 166,2 , 5399,54 , 4,4 , 4,0 , 776,7 , 1224,10 , 0, 0, 1, 6, 7 }, // English/Latin/Madagascar - { 31, 7, 129, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {77,87,75}, 168,2 , 5453,53 , 4,4 , 4,0 , 776,7 , 1234,6 , 2, 1, 1, 6, 7 }, // English/Latin/Malawi - { 31, 7, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {77,89,82}, 170,2 , 5506,59 , 4,4 , 4,0 , 776,7 , 1240,8 , 2, 1, 1, 6, 7 }, // English/Latin/Malaysia - { 31, 7, 133, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 4,4 , 4,0 , 776,7 , 1248,5 , 2, 1, 7, 6, 7 }, // English/Latin/Malta - { 31, 7, 134, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 543,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3745,35 , 4,4 , 4,0 , 776,7 , 1253,16 , 2, 1, 7, 6, 7 }, // English/Latin/Marshall Islands - { 31, 7, 137, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {77,85,82}, 172,2 , 5565,53 , 4,4 , 4,0 , 776,7 , 1269,9 , 0, 0, 1, 6, 7 }, // English/Latin/Mauritius - { 31, 7, 140, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 155,3 , 3745,35 , 4,4 , 4,0 , 776,7 , 1278,10 , 2, 1, 1, 6, 7 }, // English/Latin/Micronesia - { 31, 7, 144, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3780,71 , 4,4 , 4,0 , 776,7 , 1288,10 , 2, 1, 1, 6, 7 }, // English/Latin/Montserrat - { 31, 7, 148, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {78,65,68}, 6,1 , 5618,53 , 4,4 , 4,0 , 776,7 , 1298,7 , 2, 1, 1, 6, 7 }, // English/Latin/Namibia - { 31, 7, 149, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3851,59 , 4,4 , 4,0 , 776,7 , 1305,5 , 2, 1, 1, 6, 7 }, // English/Latin/Nauru - { 31, 7, 151, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 8,5 , 23,6 , 776,7 , 1310,11 , 2, 1, 1, 6, 7 }, // English/Latin/Netherlands - { 31, 7, 154, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 536,7 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {78,90,68}, 6,1 , 4449,62 , 4,4 , 4,0 , 776,7 , 1321,11 , 2, 1, 1, 6, 7 }, // English/Latin/New Zealand - { 31, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {78,71,78}, 174,1 , 5671,50 , 4,4 , 4,0 , 776,7 , 1332,7 , 2, 1, 1, 6, 7 }, // English/Latin/Nigeria - { 31, 7, 158, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {78,90,68}, 6,1 , 4449,62 , 4,4 , 4,0 , 776,7 , 1339,4 , 2, 1, 1, 6, 7 }, // English/Latin/Niue - { 31, 7, 159, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3851,59 , 4,4 , 4,0 , 776,7 , 1343,14 , 2, 1, 1, 6, 7 }, // English/Latin/Norfolk Island - { 31, 7, 160, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 543,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3745,35 , 4,4 , 4,0 , 776,7 , 1357,24 , 2, 1, 1, 6, 7 }, // English/Latin/Northern Mariana Islands - { 31, 7, 163, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {80,75,82}, 172,2 , 5721,53 , 4,4 , 4,0 , 776,7 , 1381,8 , 0, 0, 7, 6, 7 }, // English/Latin/Pakistan - { 31, 7, 164, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 155,3 , 3745,35 , 4,4 , 4,0 , 776,7 , 1389,5 , 2, 1, 1, 6, 7 }, // English/Latin/Palau - { 31, 7, 167, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {80,71,75}, 127,1 , 5774,73 , 4,4 , 4,0 , 776,7 , 1394,16 , 2, 1, 1, 6, 7 }, // English/Latin/Papua New Guinea - { 31, 7, 170, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {80,72,80}, 175,1 , 5847,53 , 4,4 , 4,0 , 776,7 , 1410,11 , 2, 1, 7, 6, 7 }, // English/Latin/Philippines - { 31, 7, 171, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {78,90,68}, 6,1 , 4449,62 , 4,4 , 4,0 , 776,7 , 1421,16 , 2, 1, 1, 6, 7 }, // English/Latin/Pitcairn - { 31, 7, 174, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 543,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3745,35 , 4,4 , 4,0 , 776,7 , 1437,11 , 2, 1, 7, 6, 7 }, // English/Latin/Puerto Rico - { 31, 7, 179, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {82,87,70}, 176,2 , 5900,47 , 4,4 , 4,0 , 776,7 , 1448,6 , 0, 0, 1, 6, 7 }, // English/Latin/Rwanda - { 31, 7, 180, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3780,71 , 4,4 , 4,0 , 776,7 , 1454,17 , 2, 1, 1, 6, 7 }, // English/Latin/Saint Kitts And Nevis - { 31, 7, 181, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3780,71 , 4,4 , 4,0 , 776,7 , 1471,9 , 2, 1, 1, 6, 7 }, // English/Latin/Saint Lucia - { 31, 7, 182, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3780,71 , 4,4 , 4,0 , 776,7 , 1480,24 , 2, 1, 1, 6, 7 }, // English/Latin/Saint Vincent And The Grenadines - { 31, 7, 183, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {87,83,84}, 178,3 , 5947,40 , 4,4 , 4,0 , 776,7 , 1504,5 , 2, 1, 7, 6, 7 }, // English/Latin/Samoa - { 31, 7, 188, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {83,67,82}, 181,2 , 5987,59 , 4,4 , 4,0 , 776,7 , 1509,10 , 2, 1, 1, 6, 7 }, // English/Latin/Seychelles - { 31, 7, 189, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {83,76,76}, 183,2 , 6046,68 , 4,4 , 4,0 , 776,7 , 1519,12 , 0, 0, 1, 6, 7 }, // English/Latin/Sierra Leone - { 31, 7, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 287,6 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {83,71,68}, 6,1 , 6114,56 , 4,4 , 4,0 , 776,7 , 1531,9 , 2, 1, 7, 6, 7 }, // English/Latin/Singapore - { 31, 7, 192, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 13,5 , 29,7 , 776,7 , 1540,8 , 2, 1, 1, 6, 7 }, // English/Latin/Slovenia - { 31, 7, 193, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {83,66,68}, 6,1 , 6170,74 , 4,4 , 4,0 , 776,7 , 1548,15 , 2, 1, 1, 6, 7 }, // English/Latin/Solomon Islands - { 31, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 549,10 , 80,18 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {90,65,82}, 5,1 , 5232,61 , 4,4 , 4,0 , 776,7 , 1563,12 , 2, 1, 7, 6, 7 }, // English/Latin/South Africa - { 31, 7, 199, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {83,72,80}, 115,1 , 6244,56 , 4,4 , 4,0 , 776,7 , 1575,10 , 2, 1, 1, 6, 7 }, // English/Latin/Saint Helena - { 31, 7, 201, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {83,68,71}, 0,0 , 6300,50 , 4,4 , 4,0 , 776,7 , 1585,5 , 2, 1, 6, 5, 6 }, // English/Latin/Sudan - { 31, 7, 204, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {83,90,76}, 185,1 , 6350,53 , 4,4 , 4,0 , 776,7 , 1590,9 , 2, 1, 1, 6, 7 }, // English/Latin/Swaziland - { 31, 7, 205, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 53,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {83,69,75}, 186,2 , 6403,47 , 13,5 , 4,0 , 776,7 , 1599,6 , 2, 0, 1, 6, 7 }, // English/Latin/Sweden - { 31, 7, 206, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {67,72,70}, 0,0 , 6450,41 , 8,5 , 36,5 , 776,7 , 1605,11 , 2, 0, 1, 6, 7 }, // English/Latin/Switzerland - { 31, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {84,90,83}, 188,3 , 6491,62 , 4,4 , 4,0 , 776,7 , 1616,8 , 0, 0, 1, 6, 7 }, // English/Latin/Tanzania - { 31, 7, 213, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {78,90,68}, 6,1 , 4449,62 , 4,4 , 4,0 , 776,7 , 1624,7 , 2, 1, 1, 6, 7 }, // English/Latin/Tokelau - { 31, 7, 214, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {84,79,80}, 191,2 , 6553,49 , 4,4 , 4,0 , 776,7 , 1631,5 , 2, 1, 1, 6, 7 }, // English/Latin/Tonga - { 31, 7, 215, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {84,84,68}, 6,1 , 6602,80 , 4,4 , 4,0 , 776,7 , 1636,17 , 2, 1, 7, 6, 7 }, // English/Latin/Trinidad And Tobago - { 31, 7, 219, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 155,3 , 3745,35 , 4,4 , 4,0 , 776,7 , 1653,22 , 2, 1, 1, 6, 7 }, // English/Latin/Turks And Caicos Islands - { 31, 7, 220, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3851,59 , 4,4 , 4,0 , 776,7 , 1675,6 , 2, 1, 1, 6, 7 }, // English/Latin/Tuvalu - { 31, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,71,88}, 193,3 , 6682,56 , 4,4 , 4,0 , 776,7 , 1681,6 , 0, 0, 1, 6, 7 }, // English/Latin/Uganda - { 31, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 210,9 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 70,2 , 67,2 , 0,5 , 5,17 , 22,23 , {71,66,80}, 115,1 , 6738,47 , 4,4 , 4,0 , 1687,15 , 1702,14 , 2, 1, 1, 6, 7 }, // English/Latin/United Kingdom - { 31, 7, 226, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 543,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3745,35 , 4,4 , 4,0 , 776,7 , 1716,21 , 2, 1, 7, 6, 7 }, // English/Latin/United States Minor Outlying Islands - { 31, 7, 229, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {86,85,86}, 196,2 , 6785,44 , 4,4 , 4,0 , 776,7 , 1737,7 , 0, 0, 1, 6, 7 }, // English/Latin/Vanuatu - { 31, 7, 233, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 155,3 , 3745,35 , 4,4 , 4,0 , 776,7 , 1744,22 , 2, 1, 1, 6, 7 }, // English/Latin/British Virgin Islands - { 31, 7, 234, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 543,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3745,35 , 4,4 , 4,0 , 776,7 , 1766,19 , 2, 1, 7, 6, 7 }, // English/Latin/United States Virgin Islands - { 31, 7, 239, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {90,77,87}, 127,1 , 6829,50 , 4,4 , 4,0 , 776,7 , 1785,6 , 2, 1, 1, 6, 7 }, // English/Latin/Zambia - { 31, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 433,8 , 80,18 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 155,3 , 3745,35 , 4,4 , 4,0 , 776,7 , 1791,8 , 2, 1, 7, 6, 7 }, // English/Latin/Zimbabwe - { 31, 7, 249, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 155,3 , 3745,35 , 4,4 , 4,0 , 776,7 , 1799,12 , 2, 1, 1, 6, 7 }, // English/Latin/Diego Garcia - { 31, 7, 251, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {71,66,80}, 115,1 , 4726,32 , 4,4 , 4,0 , 776,7 , 1811,11 , 2, 1, 1, 6, 7 }, // English/Latin/Isle Of Man - { 31, 7, 252, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {71,66,80}, 115,1 , 4726,32 , 4,4 , 4,0 , 776,7 , 1822,6 , 2, 1, 1, 6, 7 }, // English/Latin/Jersey - { 31, 7, 254, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {83,83,80}, 115,1 , 6879,68 , 4,4 , 4,0 , 776,7 , 1828,11 , 2, 1, 1, 6, 7 }, // English/Latin/South Sudan - { 31, 7, 256, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {65,78,71}, 151,4 , 6947,95 , 4,4 , 4,0 , 776,7 , 1839,12 , 2, 1, 1, 6, 7 }, // English/Latin/Sint Maarten - { 31, 7, 260, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {0,0,0}, 0,0 , 2586,0 , 4,4 , 4,0 , 776,7 , 1851,5 , 2, 1, 1, 6, 7 }, // English/Latin/World - { 31, 7, 261, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 120,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {0,0,0}, 0,0 , 2586,0 , 13,5 , 4,0 , 776,7 , 1856,6 , 2, 1, 1, 6, 7 }, // English/Latin/Europe - { 32, 7, 260, 44, 160, 59, 37, 48, 8722, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 219,9 , 219,9 , 559,8 , 567,26 , 37,5 , 256,25 , 5591,48 , 5639,91 , 134,24 , 5591,48 , 5639,91 , 134,24 , 2566,21 , 2587,51 , 2638,14 , 2566,21 , 2587,51 , 2638,14 , 72,3 , 69,3 , 325,6 , 5,17 , 22,23 , {0,0,0}, 0,0 , 2586,0 , 41,6 , 4,0 , 1862,9 , 0,0 , 2, 1, 1, 6, 7 }, // Esperanto/Latin/World - { 33, 7, 68, 44, 160, 59, 37, 48, 8722, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 228,8 , 228,8 , 174,8 , 593,18 , 37,5 , 8,10 , 5730,59 , 5789,91 , 5880,24 , 5730,59 , 5789,91 , 5880,24 , 2652,14 , 2666,63 , 2652,14 , 2652,14 , 2666,63 , 2652,14 , 0,2 , 0,2 , 331,6 , 5,17 , 22,23 , {69,85,82}, 14,1 , 7042,20 , 13,5 , 4,0 , 1871,5 , 1876,5 , 2, 1, 1, 6, 7 }, // Estonian/Latin/Estonia - { 34, 7, 71, 44, 46, 59, 37, 48, 8722, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 192,8 , 192,8 , 174,8 , 593,18 , 37,5 , 8,10 , 5904,48 , 5952,83 , 134,24 , 6035,59 , 5952,83 , 134,24 , 2729,28 , 2757,74 , 2831,14 , 2845,35 , 2757,74 , 2831,14 , 0,2 , 0,2 , 337,3 , 340,17 , 22,23 , {68,75,75}, 186,2 , 7062,43 , 13,5 , 4,0 , 1881,8 , 1889,7 , 2, 0, 1, 6, 7 }, // Faroese/Latin/Faroe Islands - { 34, 7, 58, 44, 46, 59, 37, 48, 8722, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 192,8 , 192,8 , 174,8 , 593,18 , 37,5 , 8,10 , 5904,48 , 5952,83 , 134,24 , 6035,59 , 5952,83 , 134,24 , 2729,28 , 2757,74 , 2831,14 , 2845,35 , 2757,74 , 2831,14 , 0,2 , 0,2 , 337,3 , 340,17 , 22,23 , {68,75,75}, 144,3 , 7062,43 , 13,5 , 4,0 , 1881,8 , 656,7 , 2, 0, 1, 6, 7 }, // Faroese/Latin/Denmark - { 36, 7, 73, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 228,8 , 228,8 , 611,8 , 496,17 , 243,4 , 247,9 , 6094,69 , 6163,105 , 6268,24 , 6292,93 , 6385,129 , 6268,24 , 2880,21 , 2901,67 , 2968,14 , 2880,21 , 2982,81 , 2968,14 , 75,3 , 72,3 , 357,5 , 362,17 , 379,23 , {69,85,82}, 14,1 , 7105,20 , 13,5 , 4,0 , 1896,5 , 1901,5 , 2, 1, 1, 6, 7 }, // Finnish/Latin/Finland - { 37, 7, 74, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 1914,6 , 2, 1, 1, 6, 7 }, // French/Latin/France - { 37, 7, 3, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 18,7 , 25,12 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {68,90,68}, 198,2 , 7125,51 , 13,5 , 4,0 , 1906,8 , 1920,7 , 2, 1, 6, 5, 6 }, // French/Latin/Algeria - { 37, 7, 21, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 536,7 , 98,16 , 37,5 , 281,23 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 1927,8 , 2, 1, 1, 6, 7 }, // French/Latin/Belgium - { 37, 7, 23, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,79,70}, 200,3 , 7176,59 , 13,5 , 4,0 , 1906,8 , 1935,5 , 0, 0, 1, 6, 7 }, // French/Latin/Benin - { 37, 7, 34, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,79,70}, 200,3 , 7176,59 , 13,5 , 4,0 , 1906,8 , 1940,12 , 0, 0, 1, 6, 7 }, // French/Latin/Burkina Faso - { 37, 7, 35, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {66,73,70}, 159,3 , 7235,53 , 13,5 , 4,0 , 1906,8 , 929,7 , 0, 0, 1, 6, 7 }, // French/Latin/Burundi - { 37, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 78,5 , 75,4 , 402,6 , 211,17 , 228,23 , {88,65,70}, 32,4 , 7288,56 , 13,5 , 4,0 , 1906,8 , 1952,8 , 0, 0, 1, 6, 7 }, // French/Latin/Cameroon - { 37, 7, 38, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8221, 8220, 0,6 , 0,6 , 236,8 , 236,8 , 559,8 , 98,16 , 304,9 , 313,24 , 6662,64 , 6577,85 , 134,24 , 6662,64 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 66,4 , 63,4 , 402,6 , 211,17 , 228,23 , {67,65,68}, 6,1 , 7344,54 , 47,6 , 4,0 , 1960,17 , 960,6 , 2, 0, 7, 6, 7 }, // French/Latin/Canada - { 37, 7, 41, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,65,70}, 32,4 , 7288,56 , 13,5 , 4,0 , 1906,8 , 1977,25 , 0, 0, 1, 6, 7 }, // French/Latin/Central African Republic - { 37, 7, 42, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 18,7 , 25,12 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,65,70}, 32,4 , 7288,56 , 13,5 , 4,0 , 1906,8 , 2002,5 , 0, 0, 1, 6, 7 }, // French/Latin/Chad - { 37, 7, 48, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {75,77,70}, 36,2 , 7398,51 , 13,5 , 4,0 , 1906,8 , 2007,7 , 0, 0, 1, 6, 7 }, // French/Latin/Comoros - { 37, 7, 49, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {67,68,70}, 203,2 , 7449,53 , 13,5 , 4,0 , 1906,8 , 2014,14 , 2, 1, 1, 6, 7 }, // French/Latin/Congo Kinshasa - { 37, 7, 50, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,65,70}, 32,4 , 7288,56 , 13,5 , 4,0 , 1906,8 , 2028,17 , 0, 0, 1, 6, 7 }, // French/Latin/Congo Brazzaville - { 37, 7, 53, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,79,70}, 200,3 , 7176,59 , 13,5 , 4,0 , 1906,8 , 2045,13 , 0, 0, 1, 6, 7 }, // French/Latin/Ivory Coast - { 37, 7, 59, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 18,7 , 25,12 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {68,74,70}, 38,3 , 7502,57 , 13,5 , 4,0 , 1906,8 , 2058,8 , 0, 0, 6, 6, 7 }, // French/Latin/Djibouti - { 37, 7, 66, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,65,70}, 32,4 , 7288,56 , 13,5 , 4,0 , 1906,8 , 2066,18 , 0, 0, 1, 6, 7 }, // French/Latin/Equatorial Guinea - { 37, 7, 76, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2084,16 , 2, 1, 1, 6, 7 }, // French/Latin/French Guiana - { 37, 7, 77, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,80,70}, 205,4 , 7559,35 , 13,5 , 4,0 , 1906,8 , 2100,19 , 0, 0, 1, 6, 7 }, // French/Latin/French Polynesia - { 37, 7, 79, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,65,70}, 32,4 , 7288,56 , 13,5 , 4,0 , 1906,8 , 2119,5 , 0, 0, 1, 6, 7 }, // French/Latin/Gabon - { 37, 7, 88, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2124,10 , 2, 1, 1, 6, 7 }, // French/Latin/Guadeloupe - { 37, 7, 91, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {71,78,70}, 209,2 , 7594,48 , 13,5 , 4,0 , 1906,8 , 2134,6 , 0, 0, 1, 6, 7 }, // French/Latin/Guinea - { 37, 7, 94, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {72,84,71}, 211,1 , 7642,57 , 13,5 , 4,0 , 1906,8 , 2140,5 , 2, 1, 1, 6, 7 }, // French/Latin/Haiti - { 37, 7, 125, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2145,10 , 2, 1, 1, 6, 7 }, // French/Latin/Luxembourg - { 37, 7, 128, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {77,71,65}, 166,2 , 7699,54 , 13,5 , 4,0 , 1906,8 , 1224,10 , 0, 0, 1, 6, 7 }, // French/Latin/Madagascar - { 37, 7, 132, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,79,70}, 200,3 , 7176,59 , 13,5 , 4,0 , 1906,8 , 2155,4 , 0, 0, 1, 6, 7 }, // French/Latin/Mali - { 37, 7, 135, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2159,10 , 2, 1, 1, 6, 7 }, // French/Latin/Martinique - { 37, 7, 136, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 18,7 , 25,12 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {77,82,85}, 212,2 , 7753,66 , 13,5 , 4,0 , 1906,8 , 2169,10 , 2, 1, 1, 6, 7 }, // French/Latin/Mauritania - { 37, 7, 137, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {77,85,82}, 172,2 , 7819,63 , 13,5 , 4,0 , 1906,8 , 2179,7 , 0, 0, 1, 6, 7 }, // French/Latin/Mauritius - { 37, 7, 138, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2186,7 , 2, 1, 1, 6, 7 }, // French/Latin/Mayotte - { 37, 7, 142, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2193,6 , 2, 1, 1, 6, 7 }, // French/Latin/Monaco - { 37, 7, 145, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6726,61 , 6577,85 , 134,24 , 6726,61 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 66,4 , 63,4 , 402,6 , 211,17 , 228,23 , {77,65,68}, 214,3 , 7882,54 , 13,5 , 4,0 , 1906,8 , 2199,5 , 2, 1, 6, 5, 6 }, // French/Latin/Morocco - { 37, 7, 153, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,80,70}, 205,4 , 7559,35 , 13,5 , 4,0 , 1906,8 , 2204,18 , 0, 0, 1, 6, 7 }, // French/Latin/New Caledonia - { 37, 7, 156, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,79,70}, 200,3 , 7176,59 , 13,5 , 4,0 , 1906,8 , 2222,5 , 0, 0, 1, 6, 7 }, // French/Latin/Niger - { 37, 7, 176, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2227,10 , 2, 1, 1, 6, 7 }, // French/Latin/Reunion - { 37, 7, 179, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {82,87,70}, 176,2 , 7936,50 , 13,5 , 4,0 , 1906,8 , 1448,6 , 0, 0, 1, 6, 7 }, // French/Latin/Rwanda - { 37, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,79,70}, 200,3 , 7176,59 , 13,5 , 4,0 , 1906,8 , 2237,7 , 0, 0, 1, 6, 7 }, // French/Latin/Senegal - { 37, 7, 188, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {83,67,82}, 181,2 , 7986,71 , 13,5 , 4,0 , 1906,8 , 1509,10 , 2, 1, 1, 6, 7 }, // French/Latin/Seychelles - { 37, 7, 200, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2244,24 , 2, 1, 1, 6, 7 }, // French/Latin/Saint Pierre And Miquelon - { 37, 7, 206, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 236,8 , 236,8 , 174,8 , 10,17 , 37,5 , 337,14 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {67,72,70}, 217,3 , 8057,45 , 13,5 , 53,6 , 2268,15 , 2283,6 , 2, 0, 1, 6, 7 }, // French/Latin/Switzerland - { 37, 7, 207, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 18,7 , 25,12 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {83,89,80}, 220,2 , 8102,51 , 13,5 , 4,0 , 1906,8 , 2289,5 , 0, 0, 6, 5, 6 }, // French/Latin/Syria - { 37, 7, 212, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,79,70}, 200,3 , 7176,59 , 13,5 , 4,0 , 1906,8 , 2294,4 , 0, 0, 1, 6, 7 }, // French/Latin/Togo - { 37, 7, 216, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 18,7 , 25,12 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {84,78,68}, 222,2 , 8153,51 , 13,5 , 4,0 , 1906,8 , 2298,7 , 3, 0, 7, 5, 6 }, // French/Latin/Tunisia - { 37, 7, 229, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 18,7 , 25,12 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {86,85,86}, 196,2 , 8204,51 , 13,5 , 4,0 , 1906,8 , 1737,7 , 0, 0, 1, 6, 7 }, // French/Latin/Vanuatu - { 37, 7, 235, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {88,80,70}, 205,4 , 7559,35 , 13,5 , 4,0 , 1906,8 , 2305,16 , 0, 0, 1, 6, 7 }, // French/Latin/Wallis And Futuna Islands - { 37, 7, 244, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2321,16 , 2, 1, 1, 6, 7 }, // French/Latin/Saint Barthelemy - { 37, 7, 245, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 120,10 , 98,16 , 37,5 , 8,10 , 6514,63 , 6577,85 , 134,24 , 6514,63 , 6577,85 , 134,24 , 3063,35 , 3098,52 , 3150,14 , 3063,35 , 3098,52 , 3150,14 , 0,2 , 0,2 , 402,6 , 211,17 , 228,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2337,12 , 2, 1, 1, 6, 7 }, // French/Latin/Saint Martin - { 38, 7, 151, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 357,8 , 98,16 , 37,5 , 8,10 , 6787,48 , 6835,95 , 134,24 , 6787,48 , 6835,95 , 134,24 , 3164,21 , 3185,54 , 85,14 , 3164,21 , 3185,54 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3455,19 , 8,5 , 59,6 , 2349,5 , 2354,8 , 2, 1, 1, 6, 7 }, // Western Frisian/Latin/Netherlands - { 39, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 244,10 , 244,10 , 120,10 , 619,21 , 37,5 , 8,10 , 6930,61 , 6991,142 , 7133,24 , 6930,61 , 7157,167 , 7133,24 , 3239,28 , 3267,69 , 3336,14 , 3239,28 , 3267,69 , 3336,14 , 83,1 , 79,1 , 408,6 , 5,17 , 22,23 , {71,66,80}, 115,1 , 8255,86 , 4,4 , 4,0 , 2362,8 , 2370,22 , 2, 1, 1, 6, 7 }, // Gaelic/Latin/United Kingdom - { 40, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 640,27 , 37,5 , 8,10 , 7324,60 , 7384,87 , 7471,24 , 7495,60 , 7555,87 , 7642,36 , 3350,35 , 3385,49 , 3434,14 , 3448,35 , 3483,49 , 3532,21 , 66,4 , 63,4 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 13,5 , 4,0 , 2392,6 , 2398,6 , 2, 1, 1, 6, 7 }, // Galician/Latin/Spain - { 41, 15, 81, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 171, 187, 0,6 , 0,6 , 261,8 , 261,8 , 174,8 , 667,19 , 37,5 , 8,10 , 7678,48 , 7726,99 , 7825,24 , 7678,48 , 7726,99 , 7825,24 , 3553,28 , 3581,62 , 3643,14 , 3553,28 , 3581,62 , 3643,14 , 0,2 , 0,2 , 414,5 , 419,33 , 22,23 , {71,69,76}, 224,1 , 8341,43 , 13,5 , 4,0 , 2404,7 , 2411,10 , 2, 1, 1, 6, 7 }, // Georgian/Georgian/Georgia - { 42, 7, 82, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 269,9 , 269,9 , 174,8 , 593,18 , 37,5 , 8,10 , 7849,48 , 7897,83 , 134,24 , 7980,59 , 7897,83 , 134,24 , 3657,21 , 3678,60 , 3738,14 , 3752,28 , 3678,60 , 3738,14 , 0,2 , 0,2 , 452,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8384,19 , 13,5 , 4,0 , 2421,7 , 2428,11 , 2, 1, 1, 6, 7 }, // German/Latin/Germany - { 42, 7, 14, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 269,9 , 269,9 , 174,8 , 593,18 , 37,5 , 8,10 , 8039,48 , 8087,83 , 134,24 , 8170,59 , 8087,83 , 134,24 , 3657,21 , 3678,60 , 3738,14 , 3752,28 , 3678,60 , 3738,14 , 0,2 , 0,2 , 452,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8384,19 , 8,5 , 4,0 , 2439,24 , 2463,10 , 2, 1, 1, 6, 7 }, // German/Latin/Austria - { 42, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 269,9 , 269,9 , 174,8 , 593,18 , 37,5 , 8,10 , 7849,48 , 7897,83 , 134,24 , 7980,59 , 7897,83 , 134,24 , 3657,21 , 3678,60 , 3738,14 , 3752,28 , 3678,60 , 3738,14 , 0,2 , 0,2 , 452,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8384,19 , 13,5 , 4,0 , 2421,7 , 2473,7 , 2, 1, 1, 6, 7 }, // German/Latin/Belgium - { 42, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 269,9 , 269,9 , 174,8 , 593,18 , 37,5 , 8,10 , 8039,48 , 8087,83 , 134,24 , 8170,59 , 8087,83 , 134,24 , 3657,21 , 3678,60 , 3738,14 , 3752,28 , 3678,60 , 3738,14 , 0,2 , 0,2 , 452,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8384,19 , 13,5 , 4,0 , 2421,7 , 2480,7 , 2, 1, 1, 6, 7 }, // German/Latin/Italy - { 42, 7, 123, 46, 8217, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 269,9 , 269,9 , 174,8 , 593,18 , 37,5 , 8,10 , 7849,48 , 7897,83 , 134,24 , 7980,59 , 7897,83 , 134,24 , 3657,21 , 3678,60 , 3738,14 , 3752,28 , 3678,60 , 3738,14 , 0,2 , 0,2 , 452,5 , 5,17 , 22,23 , {67,72,70}, 217,3 , 8403,58 , 8,5 , 4,0 , 2421,7 , 2487,13 , 2, 0, 1, 6, 7 }, // German/Latin/Liechtenstein - { 42, 7, 125, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 269,9 , 269,9 , 174,8 , 593,18 , 37,5 , 8,10 , 7849,48 , 7897,83 , 134,24 , 7980,59 , 7897,83 , 134,24 , 3657,21 , 3678,60 , 3738,14 , 3752,28 , 3678,60 , 3738,14 , 0,2 , 0,2 , 452,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8384,19 , 13,5 , 4,0 , 2421,7 , 2500,9 , 2, 1, 1, 6, 7 }, // German/Latin/Luxembourg - { 42, 7, 206, 46, 8217, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 269,9 , 269,9 , 174,8 , 593,18 , 37,5 , 8,10 , 7849,48 , 7897,83 , 134,24 , 7980,59 , 7897,83 , 134,24 , 3657,21 , 3678,60 , 3738,14 , 3752,28 , 3678,60 , 3738,14 , 0,2 , 0,2 , 452,5 , 5,17 , 22,23 , {67,72,70}, 217,3 , 8403,58 , 8,5 , 36,5 , 2509,21 , 2530,7 , 2, 0, 1, 6, 7 }, // German/Latin/Switzerland - { 43, 16, 85, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 278,9 , 278,9 , 287,6 , 10,17 , 18,7 , 25,12 , 8229,50 , 8279,115 , 8394,24 , 8418,50 , 8468,115 , 8394,24 , 3780,28 , 3808,55 , 3863,14 , 3780,28 , 3808,55 , 3863,14 , 84,4 , 80,4 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8461,19 , 13,5 , 4,0 , 2537,8 , 2545,6 , 2, 1, 1, 6, 7 }, // Greek/Greek/Greece - { 43, 16, 56, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 278,9 , 278,9 , 287,6 , 10,17 , 18,7 , 25,12 , 8229,50 , 8279,115 , 8394,24 , 8418,50 , 8468,115 , 8394,24 , 3780,28 , 3808,55 , 3863,14 , 3780,28 , 3808,55 , 3863,14 , 84,4 , 80,4 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8461,19 , 13,5 , 4,0 , 2537,8 , 2551,6 , 2, 1, 1, 6, 7 }, // Greek/Greek/Cyprus - { 44, 7, 86, 44, 46, 59, 37, 48, 8722, 43, 101, 187, 171, 8250, 8249, 0,6 , 0,6 , 287,11 , 287,11 , 53,10 , 686,17 , 228,5 , 233,10 , 8583,48 , 8631,96 , 134,24 , 8583,48 , 8631,96 , 134,24 , 3877,28 , 3905,98 , 4003,14 , 3877,28 , 3905,98 , 4003,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {68,75,75}, 144,3 , 8480,62 , 4,4 , 65,5 , 2557,11 , 2568,16 , 2, 0, 1, 6, 7 }, // Greenlandic/Latin/Greenland - { 45, 7, 168, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {80,89,71}, 225,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 7, 6, 7 }, // Guarani/Latin/Paraguay - { 46, 17, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 298,9 , 298,9 , 287,6 , 210,18 , 351,8 , 359,13 , 8727,67 , 8794,87 , 8881,31 , 8727,67 , 8794,87 , 8881,31 , 4017,32 , 4049,53 , 4102,19 , 4017,32 , 4049,53 , 4102,19 , 0,2 , 0,2 , 457,4 , 5,17 , 22,23 , {73,78,82}, 117,1 , 8542,46 , 4,4 , 4,0 , 2584,7 , 2591,4 , 2, 1, 7, 7, 7 }, // Gujarati/Gujarati/India - { 47, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 210,18 , 37,5 , 8,10 , 8912,48 , 8960,85 , 9045,24 , 8912,48 , 8960,85 , 9045,24 , 4121,28 , 4149,52 , 4201,14 , 4121,28 , 4149,52 , 4201,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {78,71,78}, 174,1 , 8588,12 , 8,5 , 4,0 , 2595,5 , 2600,8 , 2, 1, 1, 6, 7 }, // Hausa/Latin/Nigeria - { 47, 1, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {78,71,78}, 174,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Hausa/Arabic/Nigeria - { 47, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 210,18 , 37,5 , 8,10 , 8912,48 , 8960,85 , 9045,24 , 8912,48 , 8960,85 , 9045,24 , 4121,28 , 4149,52 , 4201,14 , 4121,28 , 4149,52 , 4201,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {71,72,83}, 163,3 , 0,7 , 8,5 , 4,0 , 2595,5 , 2608,4 , 2, 1, 1, 6, 7 }, // Hausa/Latin/Ghana - { 47, 7, 156, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 210,18 , 37,5 , 8,10 , 8912,48 , 8960,85 , 9045,24 , 8912,48 , 8960,85 , 9045,24 , 4121,28 , 4149,52 , 4201,14 , 4121,28 , 4149,52 , 4201,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,79,70}, 200,3 , 8600,36 , 8,5 , 4,0 , 2595,5 , 2612,5 , 0, 0, 1, 6, 7 }, // Hausa/Latin/Niger - { 48, 18, 105, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 307,6 , 307,6 , 611,8 , 703,18 , 55,4 , 59,9 , 9069,58 , 9127,72 , 158,27 , 9069,58 , 9127,72 , 158,27 , 4215,46 , 4261,65 , 4326,21 , 4215,46 , 4261,65 , 4326,21 , 88,6 , 84,5 , 461,4 , 5,17 , 22,23 , {73,76,83}, 49,1 , 8636,54 , 70,6 , 76,8 , 2617,5 , 2622,5 , 2, 1, 7, 5, 6 }, // Hebrew/Hebrew/Israel - { 49, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 313,9 , 322,8 , 287,6 , 10,17 , 18,7 , 25,12 , 9199,59 , 9258,73 , 9331,30 , 9199,59 , 9258,73 , 9331,30 , 4347,32 , 4379,53 , 4432,19 , 4347,32 , 4379,53 , 4432,19 , 94,9 , 89,7 , 465,4 , 5,17 , 22,23 , {73,78,82}, 117,1 , 8690,42 , 4,4 , 4,0 , 2627,6 , 2633,4 , 2, 1, 7, 7, 7 }, // Hindi/Devanagari/India - { 50, 7, 98, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 187, 171, 0,6 , 0,6 , 330,8 , 330,8 , 721,13 , 734,19 , 55,4 , 59,9 , 9361,64 , 9425,98 , 9523,25 , 9361,64 , 9425,98 , 9523,25 , 4451,19 , 4470,52 , 4522,17 , 4451,19 , 4470,52 , 4522,17 , 103,3 , 96,3 , 469,4 , 5,17 , 22,23 , {72,85,70}, 226,2 , 8732,46 , 13,5 , 4,0 , 2637,6 , 2643,12 , 2, 0, 1, 6, 7 }, // Hungarian/Latin/Hungary - { 51, 7, 99, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 192,8 , 192,8 , 611,8 , 593,18 , 37,5 , 8,10 , 9548,59 , 9607,82 , 9689,24 , 9548,59 , 9607,82 , 9689,24 , 4539,35 , 4574,81 , 4655,14 , 4539,35 , 4574,81 , 4655,14 , 106,4 , 99,4 , 473,4 , 5,17 , 22,23 , {73,83,75}, 228,3 , 8778,49 , 13,5 , 4,0 , 2655,8 , 2663,6 , 0, 0, 1, 6, 7 }, // Icelandic/Latin/Iceland - { 52, 7, 101, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 338,10 , 348,9 , 27,8 , 80,18 , 228,5 , 233,10 , 9713,48 , 9761,87 , 134,24 , 9713,48 , 9761,87 , 134,24 , 4669,28 , 4697,43 , 4740,14 , 4669,28 , 4697,43 , 4740,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,68,82}, 231,2 , 8827,39 , 4,4 , 4,0 , 2669,9 , 2669,9 , 0, 0, 7, 6, 7 }, // Indonesian/Latin/Indonesia - { 53, 7, 74, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Interlingua/Latin/France - { 55, 44, 38, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,65,68}, 233,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 0, 7, 6, 7 }, // Inuktitut/Canadian Aboriginal/Canada - { 55, 7, 38, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,65,68}, 233,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 0, 7, 6, 7 }, // Inuktitut/Latin/Canada - { 57, 7, 104, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 357,11 , 244,10 , 120,10 , 98,16 , 37,5 , 8,10 , 9848,62 , 9910,107 , 10017,24 , 9848,62 , 9910,107 , 10017,24 , 4754,37 , 4791,75 , 4866,14 , 4754,37 , 4791,75 , 4866,14 , 110,4 , 103,4 , 477,6 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8866,31 , 4,4 , 4,0 , 2678,7 , 2685,4 , 2, 1, 7, 6, 7 }, // Irish/Latin/Ireland - { 58, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 98,16 , 37,5 , 8,10 , 10041,48 , 10089,94 , 10183,24 , 10041,48 , 10089,94 , 10183,24 , 4880,28 , 4908,57 , 4965,14 , 4880,28 , 4908,57 , 4965,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8897,19 , 13,5 , 4,0 , 2689,8 , 2697,6 , 2, 1, 1, 6, 7 }, // Italian/Latin/Italy - { 58, 7, 184, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 98,16 , 37,5 , 8,10 , 10041,48 , 10089,94 , 10183,24 , 10041,48 , 10089,94 , 10183,24 , 4880,28 , 4908,57 , 4965,14 , 4880,28 , 4908,57 , 4965,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8897,19 , 13,5 , 4,0 , 2689,8 , 2703,10 , 2, 1, 1, 6, 7 }, // Italian/Latin/San Marino - { 58, 7, 206, 46, 8217, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 254,7 , 254,7 , 174,8 , 10,17 , 37,5 , 8,10 , 10041,48 , 10089,94 , 10183,24 , 10041,48 , 10089,94 , 10183,24 , 4880,28 , 4908,57 , 4965,14 , 4880,28 , 4908,57 , 4965,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,72,70}, 217,3 , 8916,53 , 8,5 , 36,5 , 2689,8 , 2713,8 , 2, 0, 1, 6, 7 }, // Italian/Latin/Switzerland - { 58, 7, 230, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 98,16 , 37,5 , 8,10 , 10041,48 , 10089,94 , 10183,24 , 10041,48 , 10089,94 , 10183,24 , 4880,28 , 4908,57 , 4965,14 , 4880,28 , 4908,57 , 4965,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8897,19 , 13,5 , 4,0 , 2689,8 , 2721,18 , 2, 1, 1, 6, 7 }, // Italian/Latin/Vatican City State - { 59, 19, 108, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 170,5 , 170,5 , 170,5 , 170,5 , 549,10 , 420,13 , 55,4 , 372,10 , 4671,39 , 4671,39 , 158,27 , 4671,39 , 4671,39 , 158,27 , 4979,14 , 4993,28 , 4979,14 , 4979,14 , 4993,28 , 4979,14 , 114,2 , 107,2 , 483,3 , 340,17 , 22,23 , {74,80,89}, 129,1 , 8969,11 , 4,4 , 4,0 , 2739,3 , 2742,2 , 0, 0, 7, 6, 7 }, // Japanese/Japanese/Japan - { 60, 7, 101, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,68,82}, 231,2 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 7, 6, 7 }, // Javanese/Latin/Indonesia - { 61, 21, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 368,12 , 380,11 , 287,6 , 35,18 , 351,8 , 359,13 , 10207,63 , 10270,87 , 10357,31 , 10388,69 , 10270,87 , 10357,31 , 5021,33 , 5054,54 , 5108,20 , 5021,33 , 5054,54 , 5108,20 , 116,9 , 109,7 , 486,8 , 494,33 , 22,23 , {73,78,82}, 117,1 , 8980,49 , 4,4 , 4,0 , 2744,5 , 2749,4 , 2, 1, 7, 7, 7 }, // Kannada/Kannada/India - { 62, 1, 100, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 543,6 , 35,18 , 18,7 , 25,12 , 10457,72 , 10457,72 , 10529,24 , 10457,72 , 10457,72 , 10529,24 , 5128,54 , 5182,56 , 5238,14 , 5128,54 , 5182,56 , 5238,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,78,82}, 117,1 , 9029,23 , 8,5 , 4,0 , 2753,5 , 2758,10 , 2, 1, 7, 7, 7 }, // Kashmiri/Arabic/India - { 63, 2, 110, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 391,10 , 174,8 , 753,22 , 37,5 , 8,10 , 10553,60 , 10613,83 , 10696,24 , 10720,60 , 10780,83 , 10696,24 , 5252,21 , 5273,56 , 5329,14 , 5252,21 , 5343,56 , 5329,14 , 0,2 , 0,2 , 527,4 , 531,17 , 548,23 , {75,90,84}, 236,1 , 9052,58 , 13,5 , 4,0 , 2768,10 , 2778,9 , 2, 1, 1, 6, 7 }, // Kazakh/Cyrillic/Kazakhstan - { 64, 7, 179, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 10863,60 , 10923,101 , 158,27 , 10863,60 , 10923,101 , 158,27 , 5399,35 , 5434,84 , 85,14 , 5399,35 , 5434,84 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {82,87,70}, 176,2 , 0,7 , 8,5 , 4,0 , 2787,11 , 2798,8 , 0, 0, 1, 6, 7 }, // Kinyarwanda/Latin/Rwanda - { 65, 2, 116, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 401,10 , 401,10 , 287,6 , 775,23 , 37,5 , 8,10 , 11024,48 , 11072,80 , 11152,24 , 11176,59 , 11235,80 , 11152,24 , 5518,38 , 5556,57 , 5613,14 , 5518,38 , 5556,57 , 5613,14 , 125,5 , 116,14 , 527,4 , 571,17 , 22,23 , {75,71,83}, 237,3 , 9110,52 , 13,5 , 4,0 , 2806,8 , 2814,10 , 2, 1, 1, 6, 7 }, // Kirghiz/Cyrillic/Kyrgyzstan - { 66, 22, 114, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 411,7 , 411,7 , 798,9 , 807,16 , 382,7 , 389,13 , 11315,39 , 11315,39 , 11315,39 , 11315,39 , 11315,39 , 11315,39 , 5627,14 , 5641,28 , 5627,14 , 5627,14 , 5641,28 , 5627,14 , 130,2 , 130,2 , 588,3 , 5,17 , 22,23 , {75,82,87}, 240,1 , 9162,19 , 4,4 , 4,0 , 2824,3 , 2827,4 , 0, 0, 7, 6, 7 }, // Korean/Korean/South Korea - { 66, 22, 113, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 411,7 , 411,7 , 798,9 , 807,16 , 382,7 , 389,13 , 11315,39 , 11315,39 , 11315,39 , 11315,39 , 11315,39 , 11315,39 , 5627,14 , 5641,28 , 5627,14 , 5627,14 , 5641,28 , 5627,14 , 130,2 , 130,2 , 588,3 , 5,17 , 22,23 , {75,80,87}, 241,3 , 9181,39 , 4,4 , 4,0 , 2824,3 , 2831,11 , 0, 0, 1, 6, 7 }, // Korean/Korean/North Korea - { 67, 7, 217, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {84,82,89}, 244,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Kurdish/Latin/Turkey - { 68, 7, 35, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 11354,60 , 11414,106 , 158,27 , 11354,60 , 11414,106 , 158,27 , 5669,34 , 5703,89 , 85,14 , 5669,34 , 5703,89 , 85,14 , 132,5 , 132,5 , 45,4 , 5,17 , 22,23 , {66,73,70}, 159,3 , 9220,27 , 0,4 , 4,0 , 2842,8 , 2850,8 , 0, 0, 1, 6, 7 }, // Rundi/Latin/Burundi - { 69, 23, 117, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 418,9 , 433,8 , 823,19 , 55,4 , 402,24 , 11520,61 , 11581,75 , 158,27 , 11520,61 , 11581,75 , 158,27 , 5792,36 , 5828,57 , 5885,17 , 5792,36 , 5828,57 , 5885,17 , 137,8 , 137,8 , 45,4 , 5,17 , 22,23 , {76,65,75}, 245,1 , 9247,21 , 4,4 , 36,5 , 2858,3 , 2858,3 , 0, 0, 7, 6, 7 }, // Lao/Lao/Laos - { 71, 7, 118, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 427,8 , 427,8 , 174,8 , 842,26 , 37,5 , 8,10 , 11656,65 , 11721,101 , 134,24 , 11656,65 , 11721,101 , 134,24 , 5902,51 , 5953,72 , 6025,14 , 6039,51 , 6090,72 , 6025,14 , 145,14 , 145,11 , 591,5 , 340,17 , 22,23 , {69,85,82}, 14,1 , 9268,23 , 13,5 , 4,0 , 2861,8 , 2869,7 , 2, 1, 1, 6, 7 }, // Latvian/Latin/Latvia - { 72, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 435,9 , 435,9 , 433,8 , 98,16 , 37,5 , 8,10 , 11822,48 , 11870,203 , 12073,24 , 11822,48 , 11870,203 , 12073,24 , 6162,28 , 6190,100 , 6290,14 , 6162,28 , 6190,100 , 6290,14 , 159,8 , 156,6 , 45,4 , 5,17 , 22,23 , {67,68,70}, 203,2 , 9291,23 , 13,5 , 4,0 , 2876,7 , 2883,30 , 2, 1, 1, 6, 7 }, // Lingala/Latin/Congo Kinshasa - { 72, 7, 6, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 435,9 , 435,9 , 433,8 , 98,16 , 37,5 , 8,10 , 11822,48 , 11870,203 , 12073,24 , 11822,48 , 11870,203 , 12073,24 , 6162,28 , 6190,100 , 6290,14 , 6162,28 , 6190,100 , 6290,14 , 159,8 , 156,6 , 45,4 , 5,17 , 22,23 , {65,79,65}, 246,2 , 9314,23 , 13,5 , 4,0 , 2876,7 , 2913,6 , 2, 1, 1, 6, 7 }, // Lingala/Latin/Angola - { 72, 7, 41, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 435,9 , 435,9 , 433,8 , 98,16 , 37,5 , 8,10 , 11822,48 , 11870,203 , 12073,24 , 11822,48 , 11870,203 , 12073,24 , 6162,28 , 6190,100 , 6290,14 , 6162,28 , 6190,100 , 6290,14 , 159,8 , 156,6 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 9337,23 , 13,5 , 4,0 , 2876,7 , 2919,26 , 0, 0, 1, 6, 7 }, // Lingala/Latin/Central African Republic - { 72, 7, 50, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 435,9 , 435,9 , 433,8 , 98,16 , 37,5 , 8,10 , 11822,48 , 11870,203 , 12073,24 , 11822,48 , 11870,203 , 12073,24 , 6162,28 , 6190,100 , 6290,14 , 6162,28 , 6190,100 , 6290,14 , 159,8 , 156,6 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 9337,23 , 13,5 , 4,0 , 2876,7 , 2945,5 , 0, 0, 1, 6, 7 }, // Lingala/Latin/Congo Brazzaville - { 73, 7, 124, 44, 160, 59, 37, 48, 8722, 43, 101, 8222, 8220, 8222, 8220, 0,6 , 0,6 , 444,8 , 444,8 , 53,10 , 868,27 , 37,5 , 8,10 , 12097,70 , 12167,96 , 12263,24 , 12097,70 , 12287,98 , 12263,24 , 6304,21 , 6325,89 , 6414,14 , 6304,21 , 6325,89 , 6414,14 , 167,9 , 162,6 , 596,6 , 5,17 , 22,23 , {69,85,82}, 14,1 , 9360,30 , 13,5 , 4,0 , 2950,8 , 2958,7 , 2, 1, 1, 6, 7 }, // Lithuanian/Latin/Lithuania - { 74, 2, 127, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 116,7 , 116,7 , 895,7 , 80,18 , 37,5 , 8,10 , 12385,61 , 12446,85 , 12531,24 , 12385,61 , 12446,85 , 12531,24 , 6428,35 , 6463,54 , 1659,14 , 6517,34 , 6463,54 , 1659,14 , 176,10 , 168,8 , 602,5 , 5,17 , 22,23 , {77,75,68}, 248,3 , 9390,56 , 13,5 , 4,0 , 2965,10 , 2975,10 , 2, 1, 1, 6, 7 }, // Macedonian/Cyrillic/Macedonia - { 75, 7, 128, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 98,16 , 37,5 , 8,10 , 12555,48 , 12603,92 , 134,24 , 12555,48 , 12603,92 , 134,24 , 6551,34 , 6585,60 , 6645,14 , 6551,34 , 6585,60 , 6645,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {77,71,65}, 166,2 , 9446,13 , 8,5 , 4,0 , 2985,8 , 2993,12 , 0, 0, 1, 6, 7 }, // Malagasy/Latin/Madagascar - { 76, 7, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 348,9 , 348,9 , 536,7 , 10,17 , 18,7 , 25,12 , 12695,48 , 12743,82 , 12825,24 , 12695,48 , 12743,82 , 12825,24 , 6659,28 , 6687,43 , 6730,14 , 6659,28 , 6687,43 , 6730,14 , 186,2 , 176,3 , 607,4 , 5,17 , 22,23 , {77,89,82}, 170,2 , 9459,39 , 4,4 , 4,0 , 3005,6 , 1240,8 , 2, 1, 1, 6, 7 }, // Malay/Latin/Malaysia - { 76, 1, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {77,89,82}, 170,2 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Malay/Arabic/Malaysia - { 76, 7, 32, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 348,9 , 348,9 , 536,7 , 902,12 , 18,7 , 25,12 , 12695,48 , 12743,82 , 12825,24 , 12695,48 , 12743,82 , 12825,24 , 6659,28 , 6687,43 , 6730,14 , 6659,28 , 6687,43 , 6730,14 , 186,2 , 176,3 , 607,4 , 5,17 , 22,23 , {66,78,68}, 6,1 , 9498,31 , 8,5 , 4,0 , 3005,6 , 3011,6 , 2, 1, 1, 6, 7 }, // Malay/Latin/Brunei - { 76, 7, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 348,9 , 348,9 , 536,7 , 10,17 , 18,7 , 25,12 , 12695,48 , 12743,82 , 12825,24 , 12695,48 , 12743,82 , 12825,24 , 6659,28 , 6687,43 , 6730,14 , 6659,28 , 6687,43 , 6730,14 , 186,2 , 176,3 , 607,4 , 5,17 , 22,23 , {83,71,68}, 6,1 , 9529,37 , 4,4 , 4,0 , 3005,6 , 3017,9 , 2, 1, 7, 6, 7 }, // Malay/Latin/Singapore - { 77, 24, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 452,13 , 465,12 , 287,6 , 914,18 , 18,7 , 25,12 , 12849,62 , 12911,88 , 12999,32 , 12849,62 , 12911,88 , 12999,32 , 6744,41 , 6785,77 , 6862,22 , 6744,41 , 6884,76 , 6960,21 , 0,2 , 0,2 , 611,6 , 617,31 , 22,23 , {73,78,82}, 117,1 , 9566,40 , 4,4 , 4,0 , 3026,6 , 3032,6 , 2, 1, 7, 7, 7 }, // Malayalam/Malayalam/India - { 78, 7, 133, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 477,8 , 485,7 , 120,10 , 932,23 , 37,5 , 8,10 , 13031,48 , 13079,86 , 13165,36 , 13031,48 , 13079,86 , 13201,24 , 6981,28 , 7009,63 , 7072,21 , 6981,28 , 7009,63 , 7093,20 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 9606,27 , 4,4 , 4,0 , 3038,5 , 1248,5 , 2, 1, 7, 6, 7 }, // Maltese/Latin/Malta - { 79, 7, 154, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {78,90,68}, 251,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Maori/Latin/New Zealand - { 80, 13, 100, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 492,9 , 492,9 , 287,6 , 210,18 , 18,7 , 25,12 , 13225,66 , 13291,86 , 13377,32 , 13225,66 , 13291,86 , 13377,32 , 7113,32 , 7145,53 , 4432,19 , 7113,32 , 7145,53 , 4432,19 , 188,5 , 179,4 , 465,4 , 5,17 , 22,23 , {73,78,82}, 117,1 , 9633,43 , 4,4 , 4,0 , 3043,5 , 2633,4 , 2, 1, 7, 7, 7 }, // Marathi/Devanagari/India - { 82, 2, 143, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 955,10 , 965,16 , 37,5 , 87,12 , 13409,99 , 13508,190 , 13698,38 , 13409,99 , 13508,190 , 13698,38 , 7198,21 , 7219,43 , 7198,21 , 7198,21 , 7219,43 , 7198,21 , 193,3 , 183,3 , 527,4 , 571,17 , 22,23 , {77,78,84}, 254,1 , 9676,25 , 8,5 , 4,0 , 3048,6 , 3054,6 , 0, 0, 1, 6, 7 }, // Mongolian/Cyrillic/Mongolia - { 82, 8, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,78,89}, 255,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Mongolian/Mongolian/China - { 84, 13, 150, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 501,5 , 0,6 , 506,7 , 506,7 , 245,6 , 63,17 , 37,5 , 8,10 , 13736,85 , 13736,85 , 13821,53 , 13736,85 , 13736,85 , 13874,52 , 7262,33 , 7295,54 , 7349,18 , 7262,33 , 7295,54 , 7349,18 , 94,9 , 89,7 , 465,4 , 5,17 , 22,23 , {78,80,82}, 258,4 , 9701,49 , 8,5 , 4,0 , 3060,6 , 3066,5 , 2, 1, 7, 6, 7 }, // Nepali/Devanagari/Nepal - { 84, 13, 100, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 501,5 , 0,6 , 506,7 , 506,7 , 245,6 , 63,17 , 18,7 , 25,12 , 13736,85 , 13736,85 , 13821,53 , 13736,85 , 13736,85 , 13874,52 , 7262,33 , 7295,54 , 7349,18 , 7262,33 , 7295,54 , 7349,18 , 94,9 , 89,7 , 465,4 , 5,17 , 22,23 , {73,78,82}, 117,1 , 9750,49 , 8,5 , 4,0 , 3060,6 , 2633,4 , 2, 1, 7, 7, 7 }, // Nepali/Devanagari/India - { 85, 7, 161, 44, 160, 59, 37, 48, 8722, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 192,8 , 192,8 , 981,10 , 496,17 , 37,5 , 8,10 , 5904,48 , 13926,83 , 134,24 , 6035,59 , 13926,83 , 134,24 , 2377,35 , 2312,51 , 2363,14 , 2377,35 , 2312,51 , 2363,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {78,79,75}, 186,2 , 9799,44 , 8,5 , 4,0 , 3071,12 , 3083,5 , 2, 0, 1, 6, 7 }, // Norwegian Bokmal/Latin/Norway - { 85, 7, 203, 44, 160, 59, 37, 48, 8722, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 192,8 , 192,8 , 981,10 , 496,17 , 37,5 , 8,10 , 5904,48 , 13926,83 , 134,24 , 6035,59 , 13926,83 , 134,24 , 2377,35 , 2312,51 , 2363,14 , 2377,35 , 2312,51 , 2363,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {78,79,75}, 186,2 , 9799,44 , 8,5 , 4,0 , 3071,12 , 3088,21 , 2, 0, 1, 6, 7 }, // Norwegian Bokmal/Latin/Svalbard And Jan Mayen Islands + { 27, 7, 54, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 163,7 , 163,7 , 437,13 , 450,19 , 37,5 , 87,12 , 4500,49 , 4549,94 , 4643,39 , 4500,49 , 4682,98 , 4643,39 , 2016,28 , 2044,58 , 2102,14 , 2016,28 , 2044,58 , 2116,14 , 0,2 , 0,2 , 296,7 , 5,17 , 22,23 , {72,82,75}, 141,3 , 3200,60 , 13,5 , 4,0 , 604,8 , 612,8 , 2, 1, 1, 6, 7 }, // Croatian/Latin/Croatia + { 27, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 163,7 , 163,7 , 469,9 , 450,19 , 37,5 , 87,12 , 4500,49 , 4549,94 , 4643,39 , 4500,49 , 4682,98 , 4643,39 , 2016,28 , 2044,58 , 2116,14 , 2016,28 , 2044,58 , 2116,14 , 0,2 , 0,2 , 296,7 , 5,17 , 22,23 , {66,65,77}, 144,2 , 3260,85 , 13,5 , 4,0 , 604,8 , 620,19 , 2, 1, 1, 6, 7 }, // Croatian/Latin/Bosnia And Herzegowina + { 28, 7, 57, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 185,7 , 185,7 , 156,8 , 478,17 , 55,4 , 59,9 , 4780,48 , 4828,82 , 158,27 , 4780,48 , 4910,84 , 158,27 , 2130,21 , 2151,49 , 2200,14 , 2130,21 , 2151,49 , 2200,14 , 60,4 , 57,4 , 303,5 , 5,17 , 22,23 , {67,90,75}, 146,2 , 3345,68 , 13,5 , 4,0 , 639,7 , 646,5 , 2, 0, 1, 6, 7 }, // Czech/Latin/Czech Republic + { 29, 7, 58, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 192,8 , 192,8 , 495,10 , 505,23 , 228,5 , 233,10 , 4994,59 , 5053,84 , 134,24 , 4994,59 , 5053,84 , 134,24 , 2214,28 , 2242,51 , 2293,14 , 2307,35 , 2242,51 , 2293,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {68,75,75}, 148,3 , 3413,42 , 13,5 , 4,0 , 651,5 , 656,7 , 2, 0, 1, 6, 7 }, // Danish/Latin/Denmark + { 29, 7, 86, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 192,8 , 192,8 , 495,10 , 505,23 , 228,5 , 233,10 , 4994,59 , 5053,84 , 134,24 , 4994,59 , 5053,84 , 134,24 , 2214,28 , 2242,51 , 2293,14 , 2307,35 , 2242,51 , 2293,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {68,75,75}, 148,3 , 3413,42 , 13,5 , 4,0 , 651,5 , 663,8 , 2, 0, 1, 6, 7 }, // Danish/Latin/Greenland + { 30, 7, 151, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 528,10 , 97,16 , 37,5 , 8,10 , 5137,59 , 5196,88 , 134,24 , 5137,59 , 5196,88 , 134,24 , 2342,21 , 2363,59 , 2422,14 , 2342,21 , 2363,59 , 2422,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3455,19 , 13,5 , 4,0 , 671,10 , 681,9 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Netherlands + { 30, 7, 12, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 528,10 , 97,16 , 37,5 , 8,10 , 5137,59 , 5196,88 , 134,24 , 5137,59 , 5196,88 , 134,24 , 2342,21 , 2363,59 , 2422,14 , 2342,21 , 2363,59 , 2422,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {65,87,71}, 151,4 , 3474,55 , 13,5 , 4,0 , 671,10 , 690,5 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Aruba + { 30, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 538,9 , 97,16 , 37,5 , 8,10 , 5137,59 , 5196,88 , 134,24 , 5137,59 , 5196,88 , 134,24 , 2342,21 , 2363,59 , 2422,14 , 2342,21 , 2363,59 , 2422,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3455,19 , 8,5 , 4,0 , 671,10 , 695,6 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Belgium + { 30, 7, 152, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 528,10 , 97,16 , 37,5 , 8,10 , 5137,59 , 5196,88 , 134,24 , 5137,59 , 5196,88 , 134,24 , 2342,21 , 2363,59 , 2422,14 , 2342,21 , 2363,59 , 2422,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {65,78,71}, 155,4 , 3529,97 , 13,5 , 4,0 , 671,10 , 701,7 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Cura Sao + { 30, 7, 202, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 528,10 , 97,16 , 37,5 , 8,10 , 5137,59 , 5196,88 , 134,24 , 5137,59 , 5196,88 , 134,24 , 2342,21 , 2363,59 , 2422,14 , 2342,21 , 2363,59 , 2422,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {83,82,68}, 6,1 , 3626,58 , 13,5 , 4,0 , 671,10 , 708,8 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Suriname + { 30, 7, 255, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 528,10 , 97,16 , 37,5 , 8,10 , 5137,59 , 5196,88 , 134,24 , 5137,59 , 5196,88 , 134,24 , 2342,21 , 2363,59 , 2422,14 , 2342,21 , 2363,59 , 2422,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3684,61 , 13,5 , 4,0 , 671,10 , 716,19 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Bonaire + { 30, 7, 256, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 6,8 , 6,8 , 528,10 , 97,16 , 37,5 , 8,10 , 5137,59 , 5196,88 , 134,24 , 5137,59 , 5196,88 , 134,24 , 2342,21 , 2363,59 , 2422,14 , 2342,21 , 2363,59 , 2422,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {65,78,71}, 155,4 , 3529,97 , 13,5 , 4,0 , 671,10 , 735,12 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Sint Maarten + { 31, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 547,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3745,35 , 4,4 , 4,0 , 747,16 , 763,13 , 2, 1, 7, 6, 7 }, // English/Latin/United States + { 31, 3, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,83,68}, 159,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // English/Deseret/United States + { 31, 7, 4, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 547,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3745,35 , 4,4 , 4,0 , 776,7 , 783,14 , 2, 1, 7, 6, 7 }, // English/Latin/American Samoa + { 31, 7, 7, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3780,71 , 4,4 , 4,0 , 776,7 , 797,8 , 2, 1, 1, 6, 7 }, // English/Latin/Anguilla + { 31, 7, 9, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3780,71 , 4,4 , 4,0 , 776,7 , 805,17 , 2, 1, 7, 6, 7 }, // English/Latin/Antigua And Barbuda + { 31, 7, 13, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 210,9 , 210,9 , 269,6 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 2436,25 , 0,28 , 28,57 , 2436,25 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3851,59 , 4,4 , 4,0 , 822,18 , 840,9 , 2, 1, 7, 6, 7 }, // English/Latin/Australia + { 31, 7, 14, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 8,5 , 4,0 , 776,7 , 849,7 , 2, 1, 1, 6, 7 }, // English/Latin/Austria + { 31, 7, 16, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {66,83,68}, 6,1 , 3930,53 , 4,4 , 4,0 , 776,7 , 856,7 , 2, 1, 7, 6, 7 }, // English/Latin/Bahamas + { 31, 7, 19, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {66,66,68}, 6,1 , 3983,56 , 4,4 , 4,0 , 776,7 , 863,8 , 2, 1, 1, 6, 7 }, // English/Latin/Barbados + { 31, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 27,8 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 13,5 , 4,0 , 776,7 , 871,7 , 2, 1, 1, 6, 7 }, // English/Latin/Belgium + { 31, 7, 22, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 27,8 , 553,18 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {66,90,68}, 6,1 , 4039,47 , 4,4 , 4,0 , 776,7 , 878,6 , 2, 1, 7, 6, 7 }, // English/Latin/Belize + { 31, 7, 24, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {66,77,68}, 6,1 , 4086,53 , 4,4 , 4,0 , 776,7 , 884,7 , 2, 1, 1, 6, 7 }, // English/Latin/Bermuda + { 31, 7, 28, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 27,8 , 553,18 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {66,87,80}, 162,1 , 4139,50 , 4,4 , 4,0 , 776,7 , 891,8 , 2, 1, 7, 6, 7 }, // English/Latin/Botswana + { 31, 7, 31, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 159,3 , 3745,35 , 4,4 , 4,0 , 776,7 , 899,30 , 2, 1, 1, 6, 7 }, // English/Latin/British Indian Ocean Territory + { 31, 7, 35, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 547,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {66,73,70}, 163,3 , 4189,53 , 4,4 , 4,0 , 776,7 , 929,7 , 0, 0, 1, 6, 7 }, // English/Latin/Burundi + { 31, 7, 37, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {88,65,70}, 32,4 , 4242,83 , 4,4 , 4,0 , 776,7 , 936,8 , 0, 0, 1, 6, 7 }, // English/Latin/Cameroon + { 31, 7, 38, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 53,10 , 35,18 , 18,7 , 25,12 , 5284,59 , 48,86 , 134,24 , 5284,59 , 48,86 , 134,24 , 2461,35 , 28,57 , 85,14 , 2461,35 , 28,57 , 85,14 , 64,4 , 61,4 , 0,5 , 5,17 , 22,23 , {67,65,68}, 6,1 , 4325,53 , 4,4 , 4,0 , 944,16 , 960,6 , 2, 0, 7, 6, 7 }, // English/Latin/Canada + { 31, 7, 40, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {75,89,68}, 6,1 , 4378,71 , 4,4 , 4,0 , 776,7 , 966,14 , 2, 1, 1, 6, 7 }, // English/Latin/Cayman Islands + { 31, 7, 45, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3851,59 , 4,4 , 4,0 , 776,7 , 980,16 , 2, 1, 1, 6, 7 }, // English/Latin/Christmas Island + { 31, 7, 46, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3851,59 , 4,4 , 4,0 , 776,7 , 996,23 , 2, 1, 1, 6, 7 }, // English/Latin/Cocos Islands + { 31, 7, 51, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {78,90,68}, 6,1 , 4449,62 , 4,4 , 4,0 , 776,7 , 1019,12 , 2, 1, 1, 6, 7 }, // English/Latin/Cook Islands + { 31, 7, 56, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 4,4 , 4,0 , 776,7 , 1031,6 , 2, 1, 1, 6, 7 }, // English/Latin/Cyprus + { 31, 7, 58, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 228,5 , 233,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {68,75,75}, 148,3 , 4511,44 , 13,5 , 4,0 , 776,7 , 1037,7 , 2, 0, 1, 6, 7 }, // English/Latin/Denmark + { 31, 7, 60, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3780,71 , 4,4 , 4,0 , 776,7 , 1044,8 , 2, 1, 7, 6, 7 }, // English/Latin/Dominica + { 31, 7, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {69,82,78}, 41,3 , 4555,50 , 4,4 , 4,0 , 776,7 , 1052,7 , 2, 1, 1, 6, 7 }, // English/Latin/Eritrea + { 31, 7, 70, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {70,75,80}, 119,1 , 4605,74 , 4,4 , 4,0 , 776,7 , 1059,16 , 2, 1, 1, 6, 7 }, // English/Latin/Falkland Islands + { 31, 7, 72, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {70,74,68}, 6,1 , 4679,47 , 4,4 , 4,0 , 776,7 , 1075,4 , 2, 1, 1, 6, 7 }, // English/Latin/Fiji + { 31, 7, 73, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 243,4 , 247,9 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 13,5 , 4,0 , 776,7 , 1079,7 , 2, 1, 1, 6, 7 }, // English/Latin/Finland + { 31, 7, 75, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {71,66,80}, 119,1 , 4726,32 , 4,4 , 4,0 , 776,7 , 1086,8 , 2, 1, 1, 6, 7 }, // English/Latin/Guernsey + { 31, 7, 80, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {71,77,68}, 166,1 , 4758,50 , 4,4 , 4,0 , 776,7 , 1094,6 , 2, 1, 1, 6, 7 }, // English/Latin/Gambia + { 31, 7, 82, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 13,5 , 4,0 , 776,7 , 1100,7 , 2, 1, 1, 6, 7 }, // English/Latin/Germany + { 31, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {71,72,83}, 167,3 , 4808,47 , 4,4 , 4,0 , 776,7 , 1107,5 , 2, 1, 1, 6, 7 }, // English/Latin/Ghana + { 31, 7, 84, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {71,73,80}, 119,1 , 4855,53 , 4,4 , 4,0 , 776,7 , 1112,9 , 2, 1, 1, 6, 7 }, // English/Latin/Gibraltar + { 31, 7, 87, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3780,71 , 4,4 , 4,0 , 776,7 , 1121,7 , 2, 1, 1, 6, 7 }, // English/Latin/Grenada + { 31, 7, 89, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 547,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3745,35 , 4,4 , 4,0 , 776,7 , 1128,4 , 2, 1, 7, 6, 7 }, // English/Latin/Guam + { 31, 7, 93, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {71,89,68}, 6,1 , 4908,56 , 4,4 , 4,0 , 776,7 , 1132,6 , 2, 0, 1, 6, 7 }, // English/Latin/Guyana + { 31, 7, 97, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 415,8 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {72,75,68}, 134,3 , 4964,56 , 4,4 , 4,0 , 776,7 , 1138,19 , 2, 1, 7, 6, 7 }, // English/Latin/Hong Kong + { 31, 7, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 27,8 , 192,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {73,78,82}, 121,1 , 5020,44 , 8,5 , 4,0 , 776,7 , 1157,5 , 2, 1, 7, 7, 7 }, // English/Latin/India + { 31, 7, 104, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 97,16 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 64,4 , 61,4 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 4,4 , 4,0 , 776,7 , 1162,7 , 2, 1, 1, 6, 7 }, // English/Latin/Ireland + { 31, 7, 105, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 55,4 , 59,9 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {73,76,83}, 49,1 , 5064,62 , 4,4 , 4,0 , 776,7 , 1169,6 , 2, 1, 7, 5, 6 }, // English/Latin/Israel + { 31, 7, 107, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 269,6 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {74,77,68}, 6,1 , 5126,53 , 4,4 , 4,0 , 776,7 , 1175,7 , 2, 1, 7, 6, 7 }, // English/Latin/Jamaica + { 31, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {75,69,83}, 2,3 , 5179,53 , 4,4 , 4,0 , 776,7 , 1182,5 , 2, 1, 7, 6, 7 }, // English/Latin/Kenya + { 31, 7, 112, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3851,59 , 4,4 , 4,0 , 776,7 , 1187,8 , 2, 1, 1, 6, 7 }, // English/Latin/Kiribati + { 31, 7, 120, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {90,65,82}, 5,1 , 5232,61 , 4,4 , 4,0 , 776,7 , 1195,7 , 2, 1, 1, 6, 7 }, // English/Latin/Lesotho + { 31, 7, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {76,82,68}, 6,1 , 5293,53 , 4,4 , 4,0 , 776,7 , 1202,7 , 2, 1, 1, 6, 7 }, // English/Latin/Liberia + { 31, 7, 126, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {77,79,80}, 137,4 , 5346,53 , 4,4 , 4,0 , 776,7 , 1209,15 , 2, 1, 7, 6, 7 }, // English/Latin/Macau + { 31, 7, 128, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {77,71,65}, 170,2 , 5399,54 , 4,4 , 4,0 , 776,7 , 1224,10 , 0, 0, 1, 6, 7 }, // English/Latin/Madagascar + { 31, 7, 129, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {77,87,75}, 172,2 , 5453,53 , 4,4 , 4,0 , 776,7 , 1234,6 , 2, 1, 1, 6, 7 }, // English/Latin/Malawi + { 31, 7, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {77,89,82}, 174,2 , 5506,59 , 4,4 , 4,0 , 776,7 , 1240,8 , 2, 1, 1, 6, 7 }, // English/Latin/Malaysia + { 31, 7, 133, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 4,4 , 4,0 , 776,7 , 1248,5 , 2, 1, 7, 6, 7 }, // English/Latin/Malta + { 31, 7, 134, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 547,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3745,35 , 4,4 , 4,0 , 776,7 , 1253,16 , 2, 1, 7, 6, 7 }, // English/Latin/Marshall Islands + { 31, 7, 137, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {77,85,82}, 176,2 , 5565,53 , 4,4 , 4,0 , 776,7 , 1269,9 , 2, 0, 1, 6, 7 }, // English/Latin/Mauritius + { 31, 7, 140, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 159,3 , 3745,35 , 4,4 , 4,0 , 776,7 , 1278,10 , 2, 1, 1, 6, 7 }, // English/Latin/Micronesia + { 31, 7, 144, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3780,71 , 4,4 , 4,0 , 776,7 , 1288,10 , 2, 1, 1, 6, 7 }, // English/Latin/Montserrat + { 31, 7, 148, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {78,65,68}, 6,1 , 5618,53 , 4,4 , 4,0 , 776,7 , 1298,7 , 2, 1, 1, 6, 7 }, // English/Latin/Namibia + { 31, 7, 149, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3851,59 , 4,4 , 4,0 , 776,7 , 1305,5 , 2, 1, 1, 6, 7 }, // English/Latin/Nauru + { 31, 7, 151, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 8,5 , 23,6 , 776,7 , 1310,11 , 2, 1, 1, 6, 7 }, // English/Latin/Netherlands + { 31, 7, 154, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 571,7 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {78,90,68}, 6,1 , 4449,62 , 4,4 , 4,0 , 776,7 , 1321,11 , 2, 1, 1, 6, 7 }, // English/Latin/New Zealand + { 31, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {78,71,78}, 178,1 , 5671,50 , 4,4 , 4,0 , 776,7 , 1332,7 , 2, 1, 1, 6, 7 }, // English/Latin/Nigeria + { 31, 7, 158, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {78,90,68}, 6,1 , 4449,62 , 4,4 , 4,0 , 776,7 , 1339,4 , 2, 1, 1, 6, 7 }, // English/Latin/Niue + { 31, 7, 159, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3851,59 , 4,4 , 4,0 , 776,7 , 1343,14 , 2, 1, 1, 6, 7 }, // English/Latin/Norfolk Island + { 31, 7, 160, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 547,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3745,35 , 4,4 , 4,0 , 776,7 , 1357,24 , 2, 1, 1, 6, 7 }, // English/Latin/Northern Mariana Islands + { 31, 7, 163, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {80,75,82}, 176,2 , 5721,53 , 4,4 , 4,0 , 776,7 , 1381,8 , 2, 0, 7, 6, 7 }, // English/Latin/Pakistan + { 31, 7, 164, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 159,3 , 3745,35 , 4,4 , 4,0 , 776,7 , 1389,5 , 2, 1, 1, 6, 7 }, // English/Latin/Palau + { 31, 7, 167, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {80,71,75}, 131,1 , 5774,73 , 4,4 , 4,0 , 776,7 , 1394,16 , 2, 1, 1, 6, 7 }, // English/Latin/Papua New Guinea + { 31, 7, 170, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {80,72,80}, 179,1 , 5847,53 , 4,4 , 4,0 , 776,7 , 1410,11 , 2, 1, 7, 6, 7 }, // English/Latin/Philippines + { 31, 7, 171, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {78,90,68}, 6,1 , 4449,62 , 4,4 , 4,0 , 776,7 , 1421,16 , 2, 1, 1, 6, 7 }, // English/Latin/Pitcairn + { 31, 7, 174, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 547,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3745,35 , 4,4 , 4,0 , 776,7 , 1437,11 , 2, 1, 7, 6, 7 }, // English/Latin/Puerto Rico + { 31, 7, 179, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {82,87,70}, 180,2 , 5900,47 , 4,4 , 4,0 , 776,7 , 1448,6 , 0, 0, 1, 6, 7 }, // English/Latin/Rwanda + { 31, 7, 180, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3780,71 , 4,4 , 4,0 , 776,7 , 1454,17 , 2, 1, 1, 6, 7 }, // English/Latin/Saint Kitts And Nevis + { 31, 7, 181, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3780,71 , 4,4 , 4,0 , 776,7 , 1471,9 , 2, 1, 1, 6, 7 }, // English/Latin/Saint Lucia + { 31, 7, 182, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {88,67,68}, 6,1 , 3780,71 , 4,4 , 4,0 , 776,7 , 1480,24 , 2, 1, 1, 6, 7 }, // English/Latin/Saint Vincent And The Grenadines + { 31, 7, 183, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {87,83,84}, 182,3 , 5947,40 , 4,4 , 4,0 , 776,7 , 1504,5 , 2, 1, 7, 6, 7 }, // English/Latin/Samoa + { 31, 7, 188, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {83,67,82}, 185,2 , 5987,59 , 4,4 , 4,0 , 776,7 , 1509,10 , 2, 1, 1, 6, 7 }, // English/Latin/Seychelles + { 31, 7, 189, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {83,76,76}, 187,2 , 6046,68 , 4,4 , 4,0 , 776,7 , 1519,12 , 0, 0, 1, 6, 7 }, // English/Latin/Sierra Leone + { 31, 7, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 269,6 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {83,71,68}, 6,1 , 6114,56 , 4,4 , 4,0 , 776,7 , 1531,9 , 2, 1, 7, 6, 7 }, // English/Latin/Singapore + { 31, 7, 192, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 13,5 , 29,7 , 776,7 , 1540,8 , 2, 1, 1, 6, 7 }, // English/Latin/Slovenia + { 31, 7, 193, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {83,66,68}, 6,1 , 6170,74 , 4,4 , 4,0 , 776,7 , 1548,15 , 2, 1, 1, 6, 7 }, // English/Latin/Solomon Islands + { 31, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 578,10 , 553,18 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {90,65,82}, 5,1 , 5232,61 , 4,4 , 4,0 , 776,7 , 1563,12 , 2, 1, 7, 6, 7 }, // English/Latin/South Africa + { 31, 7, 199, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {83,72,80}, 119,1 , 6244,56 , 4,4 , 4,0 , 776,7 , 1575,10 , 2, 1, 1, 6, 7 }, // English/Latin/Saint Helena + { 31, 7, 201, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {83,68,71}, 0,0 , 6300,50 , 4,4 , 4,0 , 776,7 , 1585,5 , 2, 1, 6, 5, 6 }, // English/Latin/Sudan + { 31, 7, 204, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {83,90,76}, 189,1 , 6350,53 , 4,4 , 4,0 , 776,7 , 1590,9 , 2, 1, 1, 6, 7 }, // English/Latin/Swaziland + { 31, 7, 205, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 53,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {83,69,75}, 190,2 , 6403,47 , 13,5 , 4,0 , 776,7 , 1599,6 , 2, 0, 1, 6, 7 }, // English/Latin/Sweden + { 31, 7, 206, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {67,72,70}, 0,0 , 6450,41 , 8,5 , 36,5 , 776,7 , 1605,11 , 2, 0, 1, 6, 7 }, // English/Latin/Switzerland + { 31, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {84,90,83}, 192,3 , 6491,62 , 4,4 , 4,0 , 776,7 , 1616,8 , 2, 0, 1, 6, 7 }, // English/Latin/Tanzania + { 31, 7, 213, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {78,90,68}, 6,1 , 4449,62 , 4,4 , 4,0 , 776,7 , 1624,7 , 2, 1, 1, 6, 7 }, // English/Latin/Tokelau + { 31, 7, 214, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {84,79,80}, 195,2 , 6553,49 , 4,4 , 4,0 , 776,7 , 1631,5 , 2, 1, 1, 6, 7 }, // English/Latin/Tonga + { 31, 7, 215, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {84,84,68}, 6,1 , 6602,80 , 4,4 , 4,0 , 776,7 , 1636,17 , 2, 1, 7, 6, 7 }, // English/Latin/Trinidad And Tobago + { 31, 7, 219, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 159,3 , 3745,35 , 4,4 , 4,0 , 776,7 , 1653,22 , 2, 1, 1, 6, 7 }, // English/Latin/Turks And Caicos Islands + { 31, 7, 220, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {65,85,68}, 6,1 , 3851,59 , 4,4 , 4,0 , 776,7 , 1675,6 , 2, 1, 1, 6, 7 }, // English/Latin/Tuvalu + { 31, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {85,71,88}, 197,3 , 6682,56 , 4,4 , 4,0 , 776,7 , 1681,6 , 0, 0, 1, 6, 7 }, // English/Latin/Uganda + { 31, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 210,9 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {71,66,80}, 119,1 , 6738,47 , 4,4 , 4,0 , 1687,15 , 1702,14 , 2, 1, 1, 6, 7 }, // English/Latin/United Kingdom + { 31, 7, 226, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 547,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3745,35 , 4,4 , 4,0 , 776,7 , 1716,21 , 2, 1, 7, 6, 7 }, // English/Latin/United States Minor Outlying Islands + { 31, 7, 229, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {86,85,86}, 200,2 , 6785,44 , 4,4 , 4,0 , 776,7 , 1737,7 , 0, 0, 1, 6, 7 }, // English/Latin/Vanuatu + { 31, 7, 233, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 159,3 , 3745,35 , 4,4 , 4,0 , 776,7 , 1744,22 , 2, 1, 1, 6, 7 }, // English/Latin/British Virgin Islands + { 31, 7, 234, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 547,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 3745,35 , 4,4 , 4,0 , 776,7 , 1766,19 , 2, 1, 7, 6, 7 }, // English/Latin/United States Virgin Islands + { 31, 7, 239, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {90,77,87}, 131,1 , 6829,50 , 4,4 , 4,0 , 776,7 , 1785,6 , 2, 1, 1, 6, 7 }, // English/Latin/Zambia + { 31, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 415,8 , 553,18 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 159,3 , 3745,35 , 4,4 , 4,0 , 776,7 , 1791,8 , 2, 1, 7, 6, 7 }, // English/Latin/Zimbabwe + { 31, 7, 249, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {85,83,68}, 159,3 , 3745,35 , 4,4 , 4,0 , 776,7 , 1799,12 , 2, 1, 1, 6, 7 }, // English/Latin/Diego Garcia + { 31, 7, 251, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {71,66,80}, 119,1 , 4726,32 , 4,4 , 4,0 , 776,7 , 1811,11 , 2, 1, 1, 6, 7 }, // English/Latin/Isle Of Man + { 31, 7, 252, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {71,66,80}, 119,1 , 4726,32 , 4,4 , 4,0 , 776,7 , 1822,6 , 2, 1, 1, 6, 7 }, // English/Latin/Jersey + { 31, 7, 254, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {83,83,80}, 119,1 , 6879,68 , 4,4 , 4,0 , 776,7 , 1828,11 , 2, 1, 1, 6, 7 }, // English/Latin/South Sudan + { 31, 7, 256, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {65,78,71}, 155,4 , 6947,95 , 4,4 , 4,0 , 776,7 , 1839,12 , 2, 1, 1, 6, 7 }, // English/Latin/Sint Maarten + { 31, 7, 260, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {0,0,0}, 0,0 , 2586,0 , 4,4 , 4,0 , 776,7 , 1851,5 , 2, 1, 1, 6, 7 }, // English/Latin/World + { 31, 7, 261, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 200,10 , 210,9 , 119,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 68,2 , 65,2 , 0,5 , 5,17 , 22,23 , {0,0,0}, 0,0 , 2586,0 , 13,5 , 4,0 , 776,7 , 1856,6 , 2, 1, 1, 6, 7 }, // English/Latin/Europe + { 32, 7, 260, 44, 160, 59, 37, 48, 8722, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 219,9 , 219,9 , 588,8 , 596,26 , 37,5 , 256,25 , 5343,48 , 5391,91 , 134,24 , 5343,48 , 5391,91 , 134,24 , 2496,21 , 2517,51 , 2568,14 , 2496,21 , 2517,51 , 2568,14 , 70,3 , 67,3 , 308,6 , 5,17 , 22,23 , {0,0,0}, 0,0 , 2586,0 , 41,6 , 4,0 , 1862,9 , 0,0 , 2, 1, 1, 6, 7 }, // Esperanto/Latin/World + { 33, 7, 68, 44, 160, 59, 37, 48, 8722, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 228,8 , 228,8 , 156,8 , 622,18 , 37,5 , 8,10 , 5482,59 , 5541,91 , 5632,24 , 5482,59 , 5541,91 , 5632,24 , 2582,14 , 2596,63 , 2582,14 , 2582,14 , 2596,63 , 2582,14 , 0,2 , 0,2 , 314,6 , 5,17 , 22,23 , {69,85,82}, 14,1 , 7042,20 , 13,5 , 4,0 , 1871,5 , 1876,5 , 2, 1, 1, 6, 7 }, // Estonian/Latin/Estonia + { 34, 7, 71, 44, 46, 59, 37, 48, 8722, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 192,8 , 192,8 , 156,8 , 622,18 , 37,5 , 8,10 , 5656,48 , 5704,83 , 134,24 , 5787,59 , 5704,83 , 134,24 , 2659,28 , 2687,74 , 2761,14 , 2775,35 , 2687,74 , 2761,14 , 0,2 , 0,2 , 320,3 , 323,17 , 22,23 , {68,75,75}, 190,2 , 7062,43 , 13,5 , 4,0 , 1881,8 , 1889,7 , 2, 0, 1, 6, 7 }, // Faroese/Latin/Faroe Islands + { 34, 7, 58, 44, 46, 59, 37, 48, 8722, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 192,8 , 192,8 , 156,8 , 622,18 , 37,5 , 8,10 , 5656,48 , 5704,83 , 134,24 , 5787,59 , 5704,83 , 134,24 , 2659,28 , 2687,74 , 2761,14 , 2775,35 , 2687,74 , 2761,14 , 0,2 , 0,2 , 320,3 , 323,17 , 22,23 , {68,75,75}, 148,3 , 7062,43 , 13,5 , 4,0 , 1881,8 , 656,7 , 2, 0, 1, 6, 7 }, // Faroese/Latin/Denmark + { 36, 7, 73, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 228,8 , 228,8 , 640,8 , 478,17 , 243,4 , 247,9 , 5846,69 , 5915,105 , 6020,24 , 6044,93 , 6137,129 , 6020,24 , 2810,21 , 2831,67 , 2898,14 , 2810,21 , 2912,81 , 2898,14 , 73,3 , 70,3 , 340,5 , 345,17 , 362,23 , {69,85,82}, 14,1 , 7105,20 , 13,5 , 4,0 , 1896,5 , 1901,5 , 2, 1, 1, 6, 7 }, // Finnish/Latin/Finland + { 37, 7, 74, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 1914,6 , 2, 1, 1, 6, 7 }, // French/Latin/France + { 37, 7, 3, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 18,7 , 25,12 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {68,90,68}, 202,2 , 7125,51 , 13,5 , 4,0 , 1906,8 , 1920,7 , 2, 1, 6, 5, 6 }, // French/Latin/Algeria + { 37, 7, 21, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 571,7 , 97,16 , 37,5 , 281,23 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 1927,8 , 2, 1, 1, 6, 7 }, // French/Latin/Belgium + { 37, 7, 23, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {88,79,70}, 204,3 , 7176,59 , 13,5 , 4,0 , 1906,8 , 1935,5 , 0, 0, 1, 6, 7 }, // French/Latin/Benin + { 37, 7, 34, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {88,79,70}, 204,3 , 7176,59 , 13,5 , 4,0 , 1906,8 , 1940,12 , 0, 0, 1, 6, 7 }, // French/Latin/Burkina Faso + { 37, 7, 35, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {66,73,70}, 163,3 , 7235,53 , 13,5 , 4,0 , 1906,8 , 929,7 , 0, 0, 1, 6, 7 }, // French/Latin/Burundi + { 37, 7, 37, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 76,5 , 73,4 , 385,6 , 391,17 , 408,23 , {88,65,70}, 32,4 , 7288,56 , 13,5 , 4,0 , 1906,8 , 1952,8 , 0, 0, 1, 6, 7 }, // French/Latin/Cameroon + { 37, 7, 38, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8221, 8220, 0,6 , 0,6 , 236,8 , 236,8 , 588,8 , 97,16 , 304,9 , 313,24 , 6414,64 , 6329,85 , 134,24 , 6414,64 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 64,4 , 61,4 , 385,6 , 391,17 , 408,23 , {67,65,68}, 6,1 , 7344,54 , 47,6 , 4,0 , 1960,17 , 960,6 , 2, 0, 7, 6, 7 }, // French/Latin/Canada + { 37, 7, 41, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {88,65,70}, 32,4 , 7288,56 , 13,5 , 4,0 , 1906,8 , 1977,25 , 0, 0, 1, 6, 7 }, // French/Latin/Central African Republic + { 37, 7, 42, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 18,7 , 25,12 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {88,65,70}, 32,4 , 7288,56 , 13,5 , 4,0 , 1906,8 , 2002,5 , 0, 0, 1, 6, 7 }, // French/Latin/Chad + { 37, 7, 48, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {75,77,70}, 36,2 , 7398,51 , 13,5 , 4,0 , 1906,8 , 2007,7 , 0, 0, 1, 6, 7 }, // French/Latin/Comoros + { 37, 7, 49, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {67,68,70}, 207,2 , 7449,53 , 13,5 , 4,0 , 1906,8 , 2014,14 , 2, 1, 1, 6, 7 }, // French/Latin/Congo Kinshasa + { 37, 7, 50, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {88,65,70}, 32,4 , 7288,56 , 13,5 , 4,0 , 1906,8 , 2028,17 , 0, 0, 1, 6, 7 }, // French/Latin/Congo Brazzaville + { 37, 7, 53, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {88,79,70}, 204,3 , 7176,59 , 13,5 , 4,0 , 1906,8 , 2045,13 , 0, 0, 1, 6, 7 }, // French/Latin/Ivory Coast + { 37, 7, 59, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 18,7 , 25,12 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {68,74,70}, 38,3 , 7502,57 , 13,5 , 4,0 , 1906,8 , 2058,8 , 0, 0, 6, 6, 7 }, // French/Latin/Djibouti + { 37, 7, 66, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {88,65,70}, 32,4 , 7288,56 , 13,5 , 4,0 , 1906,8 , 2066,18 , 0, 0, 1, 6, 7 }, // French/Latin/Equatorial Guinea + { 37, 7, 76, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2084,16 , 2, 1, 1, 6, 7 }, // French/Latin/French Guiana + { 37, 7, 77, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {88,80,70}, 209,4 , 7559,35 , 13,5 , 4,0 , 1906,8 , 2100,19 , 0, 0, 1, 6, 7 }, // French/Latin/French Polynesia + { 37, 7, 79, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {88,65,70}, 32,4 , 7288,56 , 13,5 , 4,0 , 1906,8 , 2119,5 , 0, 0, 1, 6, 7 }, // French/Latin/Gabon + { 37, 7, 88, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2124,10 , 2, 1, 1, 6, 7 }, // French/Latin/Guadeloupe + { 37, 7, 91, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {71,78,70}, 213,2 , 7594,48 , 13,5 , 4,0 , 1906,8 , 2134,6 , 0, 0, 1, 6, 7 }, // French/Latin/Guinea + { 37, 7, 94, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {72,84,71}, 215,1 , 7642,57 , 13,5 , 4,0 , 1906,8 , 2140,5 , 2, 1, 1, 6, 7 }, // French/Latin/Haiti + { 37, 7, 125, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2145,10 , 2, 1, 1, 6, 7 }, // French/Latin/Luxembourg + { 37, 7, 128, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {77,71,65}, 170,2 , 7699,54 , 13,5 , 4,0 , 1906,8 , 1224,10 , 0, 0, 1, 6, 7 }, // French/Latin/Madagascar + { 37, 7, 132, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {88,79,70}, 204,3 , 7176,59 , 13,5 , 4,0 , 1906,8 , 2155,4 , 0, 0, 1, 6, 7 }, // French/Latin/Mali + { 37, 7, 135, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2159,10 , 2, 1, 1, 6, 7 }, // French/Latin/Martinique + { 37, 7, 136, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 18,7 , 25,12 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {77,82,85}, 216,2 , 7753,66 , 13,5 , 4,0 , 1906,8 , 2169,10 , 2, 1, 1, 6, 7 }, // French/Latin/Mauritania + { 37, 7, 137, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {77,85,82}, 176,2 , 7819,63 , 13,5 , 4,0 , 1906,8 , 2179,7 , 2, 0, 1, 6, 7 }, // French/Latin/Mauritius + { 37, 7, 138, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2186,7 , 2, 1, 1, 6, 7 }, // French/Latin/Mayotte + { 37, 7, 142, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2193,6 , 2, 1, 1, 6, 7 }, // French/Latin/Monaco + { 37, 7, 145, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6478,61 , 6329,85 , 134,24 , 6478,61 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 64,4 , 61,4 , 385,6 , 391,17 , 408,23 , {77,65,68}, 218,3 , 7882,54 , 13,5 , 4,0 , 1906,8 , 2199,5 , 2, 1, 1, 6, 7 }, // French/Latin/Morocco + { 37, 7, 153, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {88,80,70}, 209,4 , 7559,35 , 13,5 , 4,0 , 1906,8 , 2204,18 , 0, 0, 1, 6, 7 }, // French/Latin/New Caledonia + { 37, 7, 156, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {88,79,70}, 204,3 , 7176,59 , 13,5 , 4,0 , 1906,8 , 2222,5 , 0, 0, 1, 6, 7 }, // French/Latin/Niger + { 37, 7, 176, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2227,10 , 2, 1, 1, 6, 7 }, // French/Latin/Reunion + { 37, 7, 179, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {82,87,70}, 180,2 , 7936,50 , 13,5 , 4,0 , 1906,8 , 1448,6 , 0, 0, 1, 6, 7 }, // French/Latin/Rwanda + { 37, 7, 187, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {88,79,70}, 204,3 , 7176,59 , 13,5 , 4,0 , 1906,8 , 2237,7 , 0, 0, 1, 6, 7 }, // French/Latin/Senegal + { 37, 7, 188, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {83,67,82}, 185,2 , 7986,71 , 13,5 , 4,0 , 1906,8 , 1509,10 , 2, 1, 1, 6, 7 }, // French/Latin/Seychelles + { 37, 7, 200, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2244,24 , 2, 1, 1, 6, 7 }, // French/Latin/Saint Pierre And Miquelon + { 37, 7, 206, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 236,8 , 236,8 , 156,8 , 10,17 , 37,5 , 337,14 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {67,72,70}, 221,3 , 8057,45 , 13,5 , 53,6 , 2268,15 , 2283,6 , 2, 0, 1, 6, 7 }, // French/Latin/Switzerland + { 37, 7, 207, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 18,7 , 25,12 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {83,89,80}, 224,2 , 8102,51 , 13,5 , 4,0 , 1906,8 , 2289,5 , 0, 0, 6, 5, 6 }, // French/Latin/Syria + { 37, 7, 212, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {88,79,70}, 204,3 , 7176,59 , 13,5 , 4,0 , 1906,8 , 2294,4 , 0, 0, 1, 6, 7 }, // French/Latin/Togo + { 37, 7, 216, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 18,7 , 25,12 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {84,78,68}, 226,2 , 8153,51 , 13,5 , 4,0 , 1906,8 , 2298,7 , 3, 0, 1, 6, 7 }, // French/Latin/Tunisia + { 37, 7, 229, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 18,7 , 25,12 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {86,85,86}, 200,2 , 8204,51 , 13,5 , 4,0 , 1906,8 , 1737,7 , 0, 0, 1, 6, 7 }, // French/Latin/Vanuatu + { 37, 7, 235, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {88,80,70}, 209,4 , 7559,35 , 13,5 , 4,0 , 1906,8 , 2305,16 , 0, 0, 1, 6, 7 }, // French/Latin/Wallis And Futuna Islands + { 37, 7, 244, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2321,16 , 2, 1, 1, 6, 7 }, // French/Latin/Saint Barthelemy + { 37, 7, 245, 44, 8239, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 236,8 , 236,8 , 119,10 , 97,16 , 37,5 , 8,10 , 6266,63 , 6329,85 , 134,24 , 6266,63 , 6329,85 , 134,24 , 2993,35 , 3028,52 , 3080,14 , 2993,35 , 3028,52 , 3080,14 , 0,2 , 0,2 , 385,6 , 391,17 , 408,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 1906,8 , 2337,12 , 2, 1, 1, 6, 7 }, // French/Latin/Saint Martin + { 38, 7, 151, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 339,8 , 97,16 , 37,5 , 8,10 , 6539,48 , 6587,95 , 134,24 , 6539,48 , 6587,95 , 134,24 , 3094,21 , 3115,54 , 85,14 , 3094,21 , 3115,54 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3455,19 , 8,5 , 59,6 , 2349,5 , 2354,8 , 2, 1, 1, 6, 7 }, // Western Frisian/Latin/Netherlands + { 39, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 244,10 , 244,10 , 119,10 , 648,21 , 37,5 , 8,10 , 6682,61 , 6743,142 , 6885,24 , 6682,61 , 6909,167 , 6885,24 , 3169,28 , 3197,69 , 3266,14 , 3169,28 , 3197,69 , 3266,14 , 81,1 , 77,1 , 431,6 , 5,17 , 22,23 , {71,66,80}, 119,1 , 8255,86 , 4,4 , 4,0 , 2362,8 , 2370,22 , 2, 1, 1, 6, 7 }, // Gaelic/Latin/United Kingdom + { 40, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 669,27 , 37,5 , 8,10 , 7076,60 , 7136,87 , 7223,24 , 7247,60 , 7307,87 , 7394,36 , 3280,35 , 3315,49 , 3364,14 , 3378,35 , 3413,49 , 3462,21 , 64,4 , 61,4 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3910,20 , 13,5 , 4,0 , 2392,6 , 2398,6 , 2, 1, 1, 6, 7 }, // Galician/Latin/Spain + { 41, 15, 81, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 171, 187, 0,6 , 0,6 , 261,8 , 261,8 , 156,8 , 696,19 , 37,5 , 8,10 , 7430,48 , 7478,99 , 7577,24 , 7430,48 , 7478,99 , 7577,24 , 3483,28 , 3511,62 , 3573,14 , 3483,28 , 3511,62 , 3573,14 , 0,2 , 0,2 , 437,5 , 442,37 , 22,23 , {71,69,76}, 228,1 , 8341,43 , 13,5 , 4,0 , 2404,7 , 2411,10 , 2, 1, 1, 6, 7 }, // Georgian/Georgian/Georgia + { 42, 7, 82, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 269,9 , 269,9 , 156,8 , 622,18 , 37,5 , 8,10 , 7601,48 , 7649,83 , 134,24 , 7732,60 , 7649,83 , 134,24 , 3587,21 , 3608,60 , 3668,14 , 3682,28 , 3608,60 , 3668,14 , 0,2 , 0,2 , 479,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8384,19 , 13,5 , 4,0 , 2421,7 , 2428,11 , 2, 1, 1, 6, 7 }, // German/Latin/Germany + { 42, 7, 14, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 269,9 , 269,9 , 156,8 , 622,18 , 37,5 , 8,10 , 7792,48 , 7840,83 , 134,24 , 7923,59 , 7840,83 , 134,24 , 3587,21 , 3608,60 , 3668,14 , 3682,28 , 3608,60 , 3668,14 , 0,2 , 0,2 , 479,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8384,19 , 8,5 , 4,0 , 2439,24 , 2463,10 , 2, 1, 1, 6, 7 }, // German/Latin/Austria + { 42, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 269,9 , 269,9 , 156,8 , 622,18 , 37,5 , 8,10 , 7601,48 , 7649,83 , 134,24 , 7732,60 , 7649,83 , 134,24 , 3587,21 , 3608,60 , 3668,14 , 3682,28 , 3608,60 , 3668,14 , 0,2 , 0,2 , 479,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8384,19 , 13,5 , 4,0 , 2421,7 , 2473,7 , 2, 1, 1, 6, 7 }, // German/Latin/Belgium + { 42, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 269,9 , 269,9 , 156,8 , 622,18 , 37,5 , 8,10 , 7792,48 , 7840,83 , 134,24 , 7923,59 , 7840,83 , 134,24 , 3587,21 , 3608,60 , 3668,14 , 3682,28 , 3608,60 , 3668,14 , 0,2 , 0,2 , 479,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8384,19 , 13,5 , 4,0 , 2421,7 , 2480,7 , 2, 1, 1, 6, 7 }, // German/Latin/Italy + { 42, 7, 123, 46, 8217, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 269,9 , 269,9 , 156,8 , 622,18 , 37,5 , 8,10 , 7601,48 , 7649,83 , 134,24 , 7732,60 , 7649,83 , 134,24 , 3587,21 , 3608,60 , 3668,14 , 3682,28 , 3608,60 , 3668,14 , 0,2 , 0,2 , 479,5 , 5,17 , 22,23 , {67,72,70}, 221,3 , 8403,58 , 8,5 , 4,0 , 2421,7 , 2487,13 , 2, 0, 1, 6, 7 }, // German/Latin/Liechtenstein + { 42, 7, 125, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 269,9 , 269,9 , 156,8 , 622,18 , 37,5 , 8,10 , 7601,48 , 7649,83 , 134,24 , 7732,60 , 7649,83 , 134,24 , 3587,21 , 3608,60 , 3668,14 , 3682,28 , 3608,60 , 3668,14 , 0,2 , 0,2 , 479,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8384,19 , 13,5 , 4,0 , 2421,7 , 2500,9 , 2, 1, 1, 6, 7 }, // German/Latin/Luxembourg + { 42, 7, 206, 46, 8217, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 269,9 , 269,9 , 156,8 , 622,18 , 37,5 , 8,10 , 7601,48 , 7649,83 , 134,24 , 7732,60 , 7649,83 , 134,24 , 3587,21 , 3608,60 , 3668,14 , 3682,28 , 3608,60 , 3668,14 , 0,2 , 0,2 , 479,5 , 5,17 , 22,23 , {67,72,70}, 221,3 , 8403,58 , 8,5 , 36,5 , 2509,21 , 2530,7 , 2, 0, 1, 6, 7 }, // German/Latin/Switzerland + { 43, 16, 85, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 278,9 , 278,9 , 269,6 , 10,17 , 18,7 , 25,12 , 7982,50 , 8032,115 , 8147,24 , 8171,50 , 8221,115 , 8147,24 , 3710,28 , 3738,55 , 3793,14 , 3710,28 , 3738,55 , 3793,14 , 82,4 , 78,4 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8461,19 , 13,5 , 4,0 , 2537,8 , 2545,6 , 2, 1, 1, 6, 7 }, // Greek/Greek/Greece + { 43, 16, 56, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 278,9 , 278,9 , 269,6 , 10,17 , 18,7 , 25,12 , 7982,50 , 8032,115 , 8147,24 , 8171,50 , 8221,115 , 8147,24 , 3710,28 , 3738,55 , 3793,14 , 3710,28 , 3738,55 , 3793,14 , 82,4 , 78,4 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8461,19 , 13,5 , 4,0 , 2537,8 , 2551,6 , 2, 1, 1, 6, 7 }, // Greek/Greek/Cyprus + { 44, 7, 86, 44, 46, 59, 37, 48, 8722, 43, 101, 187, 171, 8250, 8249, 0,6 , 0,6 , 287,11 , 287,11 , 53,10 , 80,17 , 228,5 , 233,10 , 8336,48 , 8384,96 , 134,24 , 8336,48 , 8384,96 , 134,24 , 3807,28 , 3835,98 , 3933,14 , 3807,28 , 3835,98 , 3933,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {68,75,75}, 148,3 , 8480,62 , 4,4 , 65,5 , 2557,11 , 2568,16 , 2, 0, 1, 6, 7 }, // Greenlandic/Latin/Greenland + { 45, 7, 168, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {80,89,71}, 229,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 7, 6, 7 }, // Guarani/Latin/Paraguay + { 46, 17, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 298,9 , 298,9 , 269,6 , 192,18 , 351,8 , 359,13 , 8480,67 , 8547,87 , 8634,31 , 8480,67 , 8547,87 , 8634,31 , 3947,32 , 3979,53 , 4032,19 , 3947,32 , 3979,53 , 4032,19 , 0,2 , 0,2 , 484,4 , 488,19 , 22,23 , {73,78,82}, 121,1 , 8542,46 , 4,4 , 4,0 , 2584,7 , 2591,4 , 2, 1, 7, 7, 7 }, // Gujarati/Gujarati/India + { 47, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 269,6 , 192,18 , 37,5 , 8,10 , 8665,48 , 8713,85 , 8798,24 , 8665,48 , 8713,85 , 8798,24 , 4051,28 , 4079,52 , 4131,14 , 4051,28 , 4079,52 , 4131,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {78,71,78}, 178,1 , 8588,12 , 8,5 , 4,0 , 2595,5 , 2600,8 , 2, 1, 1, 6, 7 }, // Hausa/Latin/Nigeria + { 47, 1, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {78,71,78}, 178,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Hausa/Arabic/Nigeria + { 47, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 269,6 , 192,18 , 37,5 , 8,10 , 8665,48 , 8713,85 , 8798,24 , 8665,48 , 8713,85 , 8798,24 , 4051,28 , 4079,52 , 4131,14 , 4051,28 , 4079,52 , 4131,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {71,72,83}, 167,3 , 0,7 , 8,5 , 4,0 , 2595,5 , 2608,4 , 2, 1, 1, 6, 7 }, // Hausa/Latin/Ghana + { 47, 7, 156, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 269,6 , 192,18 , 37,5 , 8,10 , 8665,48 , 8713,85 , 8798,24 , 8665,48 , 8713,85 , 8798,24 , 4051,28 , 4079,52 , 4131,14 , 4051,28 , 4079,52 , 4131,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,79,70}, 204,3 , 8600,36 , 8,5 , 4,0 , 2595,5 , 2612,5 , 0, 0, 1, 6, 7 }, // Hausa/Latin/Niger + { 48, 18, 105, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 307,6 , 307,6 , 640,8 , 715,18 , 55,4 , 59,9 , 8822,58 , 8880,72 , 158,27 , 8822,58 , 8880,72 , 158,27 , 4145,46 , 4191,65 , 4256,21 , 4145,46 , 4191,65 , 4256,21 , 86,6 , 82,5 , 507,4 , 5,17 , 22,23 , {73,76,83}, 49,1 , 8636,54 , 70,6 , 76,8 , 2617,5 , 2622,5 , 2, 1, 7, 5, 6 }, // Hebrew/Hebrew/Israel + { 49, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 313,9 , 322,8 , 269,6 , 10,17 , 18,7 , 25,12 , 8952,59 , 9011,73 , 9084,30 , 8952,59 , 9011,73 , 9084,30 , 4277,32 , 4309,53 , 4362,19 , 4277,32 , 4309,53 , 4362,19 , 92,9 , 87,7 , 511,4 , 5,17 , 22,23 , {73,78,82}, 121,1 , 8690,42 , 4,4 , 4,0 , 2627,6 , 2633,4 , 2, 1, 7, 7, 7 }, // Hindi/Devanagari/India + { 50, 7, 98, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 187, 171, 0,6 , 0,6 , 330,8 , 330,8 , 733,13 , 746,19 , 55,4 , 59,9 , 9114,64 , 9178,98 , 9276,25 , 9114,64 , 9178,98 , 9276,25 , 4381,19 , 4400,52 , 4452,17 , 4381,19 , 4400,52 , 4452,17 , 101,3 , 94,3 , 515,4 , 5,17 , 22,23 , {72,85,70}, 230,2 , 8732,46 , 13,5 , 4,0 , 2637,6 , 2643,12 , 2, 0, 1, 6, 7 }, // Hungarian/Latin/Hungary + { 51, 7, 99, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 192,8 , 192,8 , 640,8 , 622,18 , 37,5 , 8,10 , 9301,59 , 9360,82 , 9442,24 , 9301,59 , 9360,82 , 9442,24 , 4469,35 , 4504,81 , 4585,14 , 4469,35 , 4504,81 , 4585,14 , 104,4 , 97,4 , 519,4 , 5,17 , 22,23 , {73,83,75}, 232,3 , 8778,49 , 13,5 , 4,0 , 2655,8 , 2663,6 , 0, 0, 1, 6, 7 }, // Icelandic/Latin/Iceland + { 52, 7, 101, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 338,10 , 348,9 , 27,8 , 553,18 , 228,5 , 233,10 , 9466,48 , 9514,87 , 134,24 , 9466,48 , 9514,87 , 134,24 , 4599,28 , 4627,43 , 4670,14 , 4599,28 , 4627,43 , 4670,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,68,82}, 235,2 , 8827,39 , 4,4 , 4,0 , 2669,9 , 2669,9 , 2, 0, 7, 6, 7 }, // Indonesian/Latin/Indonesia + { 53, 7, 260, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 528,10 , 765,26 , 37,5 , 8,10 , 9601,48 , 9649,93 , 158,27 , 9601,48 , 9649,93 , 9742,24 , 4684,28 , 4712,57 , 4769,14 , 4684,28 , 4712,57 , 4769,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {0,0,0}, 0,0 , 2586,0 , 8,5 , 4,0 , 2678,11 , 2689,5 , 2, 1, 1, 6, 7 }, // Interlingua/Latin/World + { 55, 44, 38, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,65,68}, 237,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 0, 7, 6, 7 }, // Inuktitut/Canadian Aboriginal/Canada + { 55, 7, 38, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,65,68}, 237,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 0, 7, 6, 7 }, // Inuktitut/Latin/Canada + { 57, 7, 104, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 357,11 , 244,10 , 119,10 , 97,16 , 37,5 , 8,10 , 9766,62 , 9828,107 , 9935,24 , 9766,62 , 9828,107 , 9935,24 , 4783,37 , 4820,75 , 4895,14 , 4783,37 , 4820,75 , 4895,14 , 108,4 , 101,4 , 523,6 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8866,31 , 4,4 , 4,0 , 2694,7 , 2701,4 , 2, 1, 1, 6, 7 }, // Irish/Latin/Ireland + { 58, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 97,16 , 37,5 , 8,10 , 9959,48 , 10007,94 , 10101,24 , 9959,48 , 10007,94 , 10101,24 , 4909,28 , 4937,57 , 4994,14 , 4909,28 , 4937,57 , 4994,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8897,19 , 13,5 , 4,0 , 2705,8 , 2713,6 , 2, 1, 1, 6, 7 }, // Italian/Latin/Italy + { 58, 7, 184, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 97,16 , 37,5 , 8,10 , 9959,48 , 10007,94 , 10101,24 , 9959,48 , 10007,94 , 10101,24 , 4909,28 , 4937,57 , 4994,14 , 4909,28 , 4937,57 , 4994,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8897,19 , 13,5 , 4,0 , 2705,8 , 2719,10 , 2, 1, 1, 6, 7 }, // Italian/Latin/San Marino + { 58, 7, 206, 46, 8217, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 254,7 , 254,7 , 156,8 , 10,17 , 37,5 , 8,10 , 9959,48 , 10007,94 , 10101,24 , 9959,48 , 10007,94 , 10101,24 , 4909,28 , 4937,57 , 4994,14 , 4909,28 , 4937,57 , 4994,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,72,70}, 221,3 , 8916,53 , 8,5 , 36,5 , 2705,8 , 2729,8 , 2, 0, 1, 6, 7 }, // Italian/Latin/Switzerland + { 58, 7, 230, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 97,16 , 37,5 , 8,10 , 9959,48 , 10007,94 , 10101,24 , 9959,48 , 10007,94 , 10101,24 , 4909,28 , 4937,57 , 4994,14 , 4909,28 , 4937,57 , 4994,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8897,19 , 13,5 , 4,0 , 2705,8 , 2737,18 , 2, 1, 1, 6, 7 }, // Italian/Latin/Vatican City State + { 59, 19, 108, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 170,5 , 170,5 , 170,5 , 170,5 , 578,10 , 402,13 , 55,4 , 372,10 , 4423,39 , 4423,39 , 158,27 , 4423,39 , 4423,39 , 158,27 , 5008,14 , 5022,28 , 5008,14 , 5008,14 , 5022,28 , 5008,14 , 112,2 , 105,2 , 529,3 , 323,17 , 22,23 , {74,80,89}, 133,1 , 8969,11 , 4,4 , 4,0 , 2755,3 , 2758,2 , 0, 0, 7, 6, 7 }, // Japanese/Japanese/Japan + { 60, 7, 101, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 368,10 , 378,9 , 528,10 , 10,17 , 37,5 , 8,10 , 10125,48 , 9514,87 , 134,24 , 10125,48 , 9514,87 , 134,24 , 5050,28 , 5078,41 , 5119,14 , 5050,28 , 5078,41 , 5119,14 , 114,4 , 107,5 , 532,4 , 5,17 , 22,23 , {73,68,82}, 235,2 , 8827,39 , 8,5 , 4,0 , 2760,4 , 2764,9 , 2, 0, 7, 6, 7 }, // Javanese/Latin/Indonesia + { 61, 21, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 387,12 , 399,11 , 269,6 , 35,18 , 351,8 , 359,13 , 10173,63 , 10236,87 , 10323,31 , 10354,69 , 10236,87 , 10323,31 , 5133,33 , 5166,54 , 5220,20 , 5133,33 , 5166,54 , 5220,20 , 118,9 , 112,7 , 536,8 , 544,35 , 22,23 , {73,78,82}, 121,1 , 8980,49 , 4,4 , 4,0 , 2773,5 , 2778,4 , 2, 1, 7, 7, 7 }, // Kannada/Kannada/India + { 62, 1, 100, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 547,6 , 35,18 , 18,7 , 25,12 , 10423,72 , 10423,72 , 10495,24 , 10423,72 , 10423,72 , 10495,24 , 5240,54 , 5294,56 , 5350,14 , 5240,54 , 5294,56 , 5350,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,78,82}, 121,1 , 9029,23 , 8,5 , 4,0 , 2782,5 , 2787,10 , 2, 1, 7, 7, 7 }, // Kashmiri/Arabic/India + { 63, 2, 110, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 410,10 , 156,8 , 791,22 , 37,5 , 8,10 , 10519,60 , 10579,83 , 10662,24 , 10519,60 , 10686,83 , 10662,24 , 5364,21 , 5385,56 , 5441,14 , 5364,21 , 5385,56 , 5441,14 , 0,2 , 0,2 , 579,4 , 583,17 , 600,23 , {75,90,84}, 240,1 , 9052,58 , 13,5 , 4,0 , 2797,10 , 2807,9 , 2, 1, 1, 6, 7 }, // Kazakh/Cyrillic/Kazakhstan + { 64, 7, 179, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 10769,60 , 10829,101 , 158,27 , 10769,60 , 10829,101 , 158,27 , 5455,35 , 5490,84 , 85,14 , 5455,35 , 5490,84 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {82,87,70}, 180,2 , 0,7 , 8,5 , 4,0 , 2816,11 , 2827,8 , 0, 0, 1, 6, 7 }, // Kinyarwanda/Latin/Rwanda + { 65, 2, 116, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 420,10 , 420,10 , 269,6 , 813,23 , 37,5 , 8,10 , 10930,48 , 10978,80 , 11058,24 , 11082,59 , 11141,80 , 11058,24 , 5574,38 , 5612,57 , 5669,14 , 5574,38 , 5612,57 , 5669,14 , 127,5 , 119,14 , 579,4 , 623,18 , 22,23 , {75,71,83}, 241,3 , 9110,52 , 13,5 , 4,0 , 2835,8 , 2843,10 , 2, 1, 1, 6, 7 }, // Kirghiz/Cyrillic/Kyrgyzstan + { 66, 22, 114, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 430,7 , 430,7 , 836,9 , 845,16 , 382,7 , 389,13 , 11221,39 , 11221,39 , 11221,39 , 11221,39 , 11221,39 , 11221,39 , 5683,14 , 5697,28 , 5683,14 , 5683,14 , 5697,28 , 5683,14 , 132,2 , 133,2 , 641,3 , 5,17 , 22,23 , {75,82,87}, 244,1 , 9162,19 , 4,4 , 4,0 , 2853,3 , 2856,4 , 0, 0, 7, 6, 7 }, // Korean/Korean/South Korea + { 66, 22, 113, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 430,7 , 430,7 , 836,9 , 845,16 , 382,7 , 389,13 , 11221,39 , 11221,39 , 11221,39 , 11221,39 , 11221,39 , 11221,39 , 5683,14 , 5697,28 , 5683,14 , 5683,14 , 5697,28 , 5683,14 , 132,2 , 133,2 , 641,3 , 5,17 , 22,23 , {75,80,87}, 245,3 , 9181,39 , 4,4 , 4,0 , 2853,3 , 2860,11 , 0, 0, 1, 6, 7 }, // Korean/Korean/North Korea + { 67, 7, 217, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 437,7 , 437,7 , 53,10 , 63,17 , 37,5 , 8,10 , 11260,48 , 11308,88 , 11396,24 , 11260,48 , 11420,101 , 11396,24 , 5725,20 , 5745,42 , 5787,14 , 5725,20 , 5745,42 , 5787,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {84,82,89}, 248,1 , 0,7 , 13,5 , 4,0 , 2871,5 , 2876,7 , 2, 1, 1, 6, 7 }, // Kurdish/Latin/Turkey + { 68, 7, 35, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 11521,60 , 11581,106 , 158,27 , 11521,60 , 11581,106 , 158,27 , 5801,34 , 5835,89 , 85,14 , 5801,34 , 5835,89 , 85,14 , 134,5 , 135,5 , 45,4 , 5,17 , 22,23 , {66,73,70}, 163,3 , 9220,27 , 0,4 , 4,0 , 2883,8 , 2891,8 , 0, 0, 1, 6, 7 }, // Rundi/Latin/Burundi + { 69, 23, 117, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 444,9 , 415,8 , 861,19 , 55,4 , 402,24 , 11687,61 , 11748,75 , 158,27 , 11687,61 , 11748,75 , 158,27 , 5924,36 , 5960,57 , 6017,17 , 5924,36 , 5960,57 , 6017,17 , 139,8 , 140,8 , 45,4 , 5,17 , 22,23 , {76,65,75}, 249,1 , 9247,21 , 4,4 , 36,5 , 2899,3 , 2899,3 , 0, 0, 7, 6, 7 }, // Lao/Lao/Laos + { 71, 7, 118, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 453,8 , 453,8 , 156,8 , 880,26 , 37,5 , 8,10 , 11823,65 , 11888,101 , 134,24 , 11823,65 , 11888,101 , 134,24 , 6034,51 , 6085,72 , 6157,14 , 6171,51 , 6222,72 , 6157,14 , 147,14 , 148,11 , 644,5 , 323,17 , 22,23 , {69,85,82}, 14,1 , 9268,23 , 13,5 , 4,0 , 2902,8 , 2910,7 , 2, 1, 1, 6, 7 }, // Latvian/Latin/Latvia + { 72, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 461,9 , 461,9 , 415,8 , 97,16 , 37,5 , 8,10 , 11989,48 , 12037,203 , 12240,24 , 11989,48 , 12037,203 , 12240,24 , 6294,28 , 6322,100 , 6422,14 , 6294,28 , 6322,100 , 6422,14 , 161,8 , 159,6 , 45,4 , 5,17 , 22,23 , {67,68,70}, 207,2 , 9291,23 , 13,5 , 4,0 , 2917,7 , 2924,30 , 2, 1, 1, 6, 7 }, // Lingala/Latin/Congo Kinshasa + { 72, 7, 6, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 461,9 , 461,9 , 415,8 , 97,16 , 37,5 , 8,10 , 11989,48 , 12037,203 , 12240,24 , 11989,48 , 12037,203 , 12240,24 , 6294,28 , 6322,100 , 6422,14 , 6294,28 , 6322,100 , 6422,14 , 161,8 , 159,6 , 45,4 , 5,17 , 22,23 , {65,79,65}, 250,2 , 9314,23 , 13,5 , 4,0 , 2917,7 , 2954,6 , 2, 1, 1, 6, 7 }, // Lingala/Latin/Angola + { 72, 7, 41, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 461,9 , 461,9 , 415,8 , 97,16 , 37,5 , 8,10 , 11989,48 , 12037,203 , 12240,24 , 11989,48 , 12037,203 , 12240,24 , 6294,28 , 6322,100 , 6422,14 , 6294,28 , 6322,100 , 6422,14 , 161,8 , 159,6 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 9337,23 , 13,5 , 4,0 , 2917,7 , 2960,26 , 0, 0, 1, 6, 7 }, // Lingala/Latin/Central African Republic + { 72, 7, 50, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 461,9 , 461,9 , 415,8 , 97,16 , 37,5 , 8,10 , 11989,48 , 12037,203 , 12240,24 , 11989,48 , 12037,203 , 12240,24 , 6294,28 , 6322,100 , 6422,14 , 6294,28 , 6322,100 , 6422,14 , 161,8 , 159,6 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 9337,23 , 13,5 , 4,0 , 2917,7 , 2986,5 , 0, 0, 1, 6, 7 }, // Lingala/Latin/Congo Brazzaville + { 73, 7, 124, 44, 160, 59, 37, 48, 8722, 43, 101, 8222, 8220, 8222, 8220, 0,6 , 0,6 , 470,8 , 470,8 , 53,10 , 906,27 , 37,5 , 8,10 , 12264,70 , 12334,96 , 12430,24 , 12264,70 , 12454,98 , 12430,24 , 6436,21 , 6457,89 , 6546,14 , 6436,21 , 6457,89 , 6546,14 , 169,9 , 165,6 , 649,6 , 5,17 , 22,23 , {69,85,82}, 14,1 , 9360,30 , 13,5 , 4,0 , 2991,8 , 2999,7 , 2, 1, 1, 6, 7 }, // Lithuanian/Latin/Lithuania + { 74, 2, 127, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 116,7 , 116,7 , 933,7 , 553,18 , 37,5 , 8,10 , 12552,61 , 12613,85 , 12698,24 , 12552,61 , 12613,85 , 12698,24 , 6560,35 , 6595,54 , 1503,14 , 6649,34 , 6595,54 , 1503,14 , 178,10 , 171,8 , 655,5 , 5,17 , 22,23 , {77,75,68}, 252,3 , 9390,56 , 13,5 , 4,0 , 3006,10 , 3016,10 , 2, 1, 1, 6, 7 }, // Macedonian/Cyrillic/Macedonia + { 75, 7, 128, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 97,16 , 37,5 , 8,10 , 12722,48 , 12770,92 , 134,24 , 12722,48 , 12770,92 , 134,24 , 6683,34 , 6717,60 , 6777,14 , 6683,34 , 6717,60 , 6777,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {77,71,65}, 170,2 , 9446,13 , 8,5 , 4,0 , 3026,8 , 3034,12 , 0, 0, 1, 6, 7 }, // Malagasy/Latin/Madagascar + { 76, 7, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 348,9 , 348,9 , 571,7 , 10,17 , 18,7 , 25,12 , 12862,48 , 12910,82 , 12992,24 , 12862,48 , 12910,82 , 12992,24 , 6791,28 , 6819,43 , 6862,14 , 6791,28 , 6819,43 , 6862,14 , 188,2 , 179,3 , 660,4 , 5,17 , 22,23 , {77,89,82}, 174,2 , 9459,39 , 4,4 , 4,0 , 3046,6 , 1240,8 , 2, 1, 1, 6, 7 }, // Malay/Latin/Malaysia + { 76, 1, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {77,89,82}, 174,2 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Malay/Arabic/Malaysia + { 76, 7, 32, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 348,9 , 348,9 , 571,7 , 940,12 , 18,7 , 25,12 , 12862,48 , 12910,82 , 12992,24 , 12862,48 , 12910,82 , 12992,24 , 6791,28 , 6819,43 , 6862,14 , 6791,28 , 6819,43 , 6862,14 , 188,2 , 179,3 , 660,4 , 5,17 , 22,23 , {66,78,68}, 6,1 , 9498,31 , 8,5 , 4,0 , 3046,6 , 3052,6 , 2, 1, 1, 6, 7 }, // Malay/Latin/Brunei + { 76, 7, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 348,9 , 348,9 , 571,7 , 10,17 , 18,7 , 25,12 , 12862,48 , 12910,82 , 12992,24 , 12862,48 , 12910,82 , 12992,24 , 6791,28 , 6819,43 , 6862,14 , 6791,28 , 6819,43 , 6862,14 , 188,2 , 179,3 , 660,4 , 5,17 , 22,23 , {83,71,68}, 6,1 , 9529,37 , 4,4 , 4,0 , 3046,6 , 3058,9 , 2, 1, 7, 6, 7 }, // Malay/Latin/Singapore + { 77, 24, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 478,13 , 491,12 , 269,6 , 952,18 , 18,7 , 25,12 , 13016,62 , 13078,88 , 13166,32 , 13016,62 , 13078,88 , 13166,32 , 6876,41 , 6917,77 , 6994,22 , 6876,41 , 7016,76 , 7092,21 , 0,2 , 0,2 , 664,6 , 670,31 , 22,23 , {73,78,82}, 121,1 , 9566,40 , 4,4 , 4,0 , 3067,6 , 3073,6 , 2, 1, 7, 7, 7 }, // Malayalam/Malayalam/India + { 78, 7, 133, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 503,8 , 511,7 , 119,10 , 970,23 , 37,5 , 8,10 , 13198,48 , 13246,86 , 13332,36 , 13198,48 , 13246,86 , 13368,24 , 7113,28 , 7141,63 , 7204,21 , 7113,28 , 7141,63 , 7225,20 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 9606,27 , 4,4 , 4,0 , 3079,5 , 1248,5 , 2, 1, 7, 6, 7 }, // Maltese/Latin/Malta + { 79, 7, 154, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 426,4 , 25,12 , 13392,59 , 13451,133 , 13584,24 , 13392,59 , 13451,133 , 13584,24 , 7245,27 , 7272,47 , 7319,14 , 7245,27 , 7272,47 , 7319,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {78,90,68}, 6,1 , 9633,41 , 8,5 , 4,0 , 3084,5 , 3089,8 , 2, 1, 1, 6, 7 }, // Maori/Latin/New Zealand + { 80, 13, 100, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 518,9 , 518,9 , 269,6 , 192,18 , 18,7 , 25,12 , 13608,66 , 13674,86 , 13760,32 , 13608,66 , 13674,86 , 13760,32 , 7333,32 , 7365,53 , 4362,19 , 7333,32 , 7365,53 , 4362,19 , 190,5 , 182,4 , 511,4 , 5,17 , 22,23 , {73,78,82}, 121,1 , 9674,43 , 4,4 , 4,0 , 3097,5 , 2633,4 , 2, 1, 7, 7, 7 }, // Marathi/Devanagari/India + { 82, 2, 143, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 993,10 , 1003,16 , 37,5 , 87,12 , 13792,99 , 13891,192 , 14083,38 , 13792,99 , 14121,192 , 14083,38 , 7418,21 , 7439,43 , 7418,21 , 7418,21 , 7482,43 , 7418,21 , 195,4 , 186,4 , 579,4 , 701,17 , 22,23 , {77,78,84}, 255,1 , 9717,25 , 8,5 , 4,0 , 3102,6 , 3108,6 , 2, 0, 1, 6, 7 }, // Mongolian/Cyrillic/Mongolia + { 82, 8, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,78,89}, 256,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Mongolian/Mongolian/China + { 84, 13, 150, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 527,5 , 0,6 , 532,7 , 532,7 , 227,6 , 63,17 , 37,5 , 8,10 , 14313,85 , 14313,85 , 14398,53 , 14313,85 , 14313,85 , 14451,52 , 7525,33 , 7558,54 , 7612,18 , 7525,33 , 7558,54 , 7612,18 , 92,9 , 87,7 , 511,4 , 718,19 , 22,23 , {78,80,82}, 259,4 , 9742,49 , 8,5 , 4,0 , 3114,6 , 3120,5 , 2, 1, 7, 6, 7 }, // Nepali/Devanagari/Nepal + { 84, 13, 100, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 527,5 , 0,6 , 532,7 , 532,7 , 227,6 , 63,17 , 18,7 , 25,12 , 14313,85 , 14313,85 , 14398,53 , 14313,85 , 14313,85 , 14451,52 , 7525,33 , 7558,54 , 7612,18 , 7525,33 , 7558,54 , 7612,18 , 92,9 , 87,7 , 511,4 , 718,19 , 22,23 , {73,78,82}, 121,1 , 9791,49 , 8,5 , 4,0 , 3114,6 , 2633,4 , 2, 1, 7, 7, 7 }, // Nepali/Devanagari/India + { 85, 7, 161, 44, 160, 59, 37, 48, 8722, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 192,8 , 192,8 , 495,10 , 478,17 , 37,5 , 8,10 , 5656,48 , 14503,83 , 134,24 , 5787,59 , 14503,83 , 134,24 , 2307,35 , 2242,51 , 2293,14 , 2307,35 , 2242,51 , 2293,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {78,79,75}, 190,2 , 9840,44 , 8,5 , 4,0 , 3125,12 , 3137,5 , 2, 0, 1, 6, 7 }, // Norwegian Bokmal/Latin/Norway + { 85, 7, 203, 44, 160, 59, 37, 48, 8722, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 192,8 , 192,8 , 495,10 , 478,17 , 37,5 , 8,10 , 5656,48 , 14503,83 , 134,24 , 5787,59 , 14503,83 , 134,24 , 2307,35 , 2242,51 , 2293,14 , 2307,35 , 2242,51 , 2293,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {78,79,75}, 190,2 , 9840,44 , 8,5 , 4,0 , 3125,12 , 3142,21 , 2, 0, 1, 6, 7 }, // Norwegian Bokmal/Latin/Svalbard And Jan Mayen Islands { 86, 7, 74, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Occitan/Latin/France - { 87, 26, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 513,8 , 521,7 , 543,6 , 35,18 , 18,7 , 25,12 , 14009,86 , 14009,86 , 14095,32 , 14009,86 , 14009,86 , 14095,32 , 7367,33 , 7400,54 , 7454,18 , 7367,33 , 7400,54 , 7454,18 , 0,2 , 0,2 , 648,5 , 5,17 , 22,23 , {73,78,82}, 117,1 , 9843,43 , 8,5 , 4,0 , 3109,5 , 3114,4 , 2, 1, 7, 7, 7 }, // Oriya/Oriya/India - { 88, 1, 1, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 46,6 , 46,6 , 528,9 , 537,8 , 412,8 , 991,20 , 55,4 , 426,11 , 14127,68 , 14195,69 , 158,27 , 14264,69 , 14264,69 , 14333,24 , 7472,39 , 7472,39 , 85,14 , 7472,39 , 7472,39 , 85,14 , 196,4 , 186,4 , 0,5 , 5,17 , 22,23 , {65,70,78}, 262,1 , 9886,25 , 13,5 , 4,0 , 3118,4 , 3122,9 , 0, 0, 6, 4, 5 }, // Pashto/Arabic/Afghanistan - { 89, 1, 102, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 171, 187, 8249, 8250, 545,7 , 545,7 , 552,8 , 560,7 , 412,8 , 98,16 , 55,4 , 426,11 , 14357,70 , 14357,70 , 14427,24 , 14451,74 , 14451,74 , 14427,24 , 7511,49 , 7511,49 , 7560,14 , 7511,49 , 7511,49 , 7560,14 , 200,9 , 190,8 , 653,4 , 657,39 , 22,23 , {73,82,82}, 263,4 , 9911,37 , 84,5 , 4,0 , 3131,5 , 3136,5 , 0, 0, 6, 5, 5 }, // Persian/Arabic/Iran - { 89, 1, 1, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 171, 187, 8249, 8250, 545,7 , 545,7 , 552,8 , 560,7 , 412,8 , 98,16 , 55,4 , 426,11 , 14525,68 , 14525,68 , 14333,24 , 14593,62 , 14525,68 , 14333,24 , 7511,49 , 7511,49 , 7560,14 , 7511,49 , 7511,49 , 7560,14 , 200,9 , 190,8 , 653,4 , 657,39 , 22,23 , {65,70,78}, 262,1 , 9948,55 , 8,5 , 4,0 , 3141,3 , 3122,9 , 0, 0, 6, 4, 5 }, // Persian/Arabic/Afghanistan - { 90, 7, 172, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 163,7 , 163,7 , 981,10 , 10,17 , 37,5 , 8,10 , 14655,48 , 14703,97 , 14800,24 , 14655,48 , 14824,99 , 14923,24 , 7574,34 , 7608,59 , 7667,14 , 7574,34 , 7608,59 , 7681,14 , 0,2 , 0,2 , 320,5 , 5,17 , 22,23 , {80,76,78}, 267,2 , 10003,77 , 13,5 , 4,0 , 3144,6 , 3150,6 , 2, 1, 1, 6, 7 }, // Polish/Latin/Poland - { 91, 7, 30, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 254,7 , 254,7 , 120,10 , 640,27 , 37,5 , 8,10 , 14947,48 , 14995,89 , 134,24 , 14947,48 , 14995,89 , 134,24 , 7695,28 , 7723,79 , 7802,14 , 7695,28 , 7723,79 , 7802,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {66,82,76}, 269,2 , 10080,54 , 8,5 , 4,0 , 3156,9 , 3165,6 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Brazil - { 91, 7, 6, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 640,27 , 37,5 , 8,10 , 14947,48 , 14995,89 , 134,24 , 14947,48 , 14995,89 , 134,24 , 7816,49 , 7723,79 , 7802,14 , 7816,49 , 7723,79 , 7802,14 , 209,8 , 198,8 , 0,5 , 5,17 , 22,23 , {65,79,65}, 246,2 , 10134,54 , 13,5 , 4,0 , 3156,9 , 3171,6 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Angola - { 91, 7, 39, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 640,27 , 37,5 , 8,10 , 14947,48 , 14995,89 , 134,24 , 14947,48 , 14995,89 , 134,24 , 7816,49 , 7723,79 , 7802,14 , 7816,49 , 7723,79 , 7802,14 , 209,8 , 198,8 , 0,5 , 5,17 , 22,23 , {67,86,69}, 271,1 , 10188,69 , 13,5 , 4,0 , 3156,9 , 3177,10 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Cape Verde - { 91, 7, 62, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 640,27 , 37,5 , 8,10 , 14947,48 , 14995,89 , 134,24 , 14947,48 , 14995,89 , 134,24 , 7816,49 , 7723,79 , 7802,14 , 7816,49 , 7723,79 , 7802,14 , 209,8 , 198,8 , 0,5 , 5,17 , 22,23 , {85,83,68}, 155,3 , 10257,81 , 13,5 , 4,0 , 3156,9 , 3187,11 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/East Timor - { 91, 7, 66, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 640,27 , 37,5 , 8,10 , 14947,48 , 14995,89 , 134,24 , 14947,48 , 14995,89 , 134,24 , 7816,49 , 7723,79 , 7802,14 , 7816,49 , 7723,79 , 7802,14 , 209,8 , 198,8 , 0,5 , 5,17 , 22,23 , {88,65,70}, 32,4 , 10338,59 , 13,5 , 4,0 , 3156,9 , 3198,16 , 0, 0, 1, 6, 7 }, // Portuguese/Latin/Equatorial Guinea - { 91, 7, 92, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 640,27 , 37,5 , 8,10 , 14947,48 , 14995,89 , 134,24 , 14947,48 , 14995,89 , 134,24 , 7816,49 , 7723,79 , 7802,14 , 7816,49 , 7723,79 , 7802,14 , 209,8 , 198,8 , 0,5 , 5,17 , 22,23 , {88,79,70}, 200,3 , 10397,62 , 13,5 , 4,0 , 3156,9 , 3214,12 , 0, 0, 1, 6, 7 }, // Portuguese/Latin/Guinea Bissau - { 91, 7, 125, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 640,27 , 37,5 , 8,10 , 14947,48 , 14995,89 , 134,24 , 14947,48 , 14995,89 , 134,24 , 7816,49 , 7723,79 , 7802,14 , 7816,49 , 7723,79 , 7802,14 , 209,8 , 198,8 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 3156,9 , 3226,10 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Luxembourg - { 91, 7, 126, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 640,27 , 18,7 , 25,12 , 14947,48 , 14995,89 , 134,24 , 14947,48 , 14995,89 , 134,24 , 7816,49 , 7723,79 , 7802,14 , 7816,49 , 7723,79 , 7802,14 , 209,8 , 198,8 , 0,5 , 5,17 , 22,23 , {77,79,80}, 133,4 , 10459,53 , 13,5 , 4,0 , 3156,9 , 3236,19 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Macau - { 91, 7, 146, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 640,27 , 37,5 , 8,10 , 14947,48 , 14995,89 , 134,24 , 14947,48 , 14995,89 , 134,24 , 7816,49 , 7723,79 , 7802,14 , 7816,49 , 7723,79 , 7802,14 , 209,8 , 198,8 , 0,5 , 5,17 , 22,23 , {77,90,78}, 272,3 , 10512,72 , 13,5 , 4,0 , 3156,9 , 3255,10 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Mozambique - { 91, 7, 173, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 640,27 , 37,5 , 8,10 , 14947,48 , 14995,89 , 134,24 , 14947,48 , 14995,89 , 134,24 , 7816,49 , 7723,79 , 7802,14 , 7816,49 , 7723,79 , 7802,14 , 209,8 , 198,8 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 3265,17 , 3282,8 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Portugal - { 91, 7, 185, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 640,27 , 37,5 , 8,10 , 14947,48 , 14995,89 , 134,24 , 14947,48 , 14995,89 , 134,24 , 7816,49 , 7723,79 , 7802,14 , 7816,49 , 7723,79 , 7802,14 , 209,8 , 198,8 , 0,5 , 5,17 , 22,23 , {83,84,78}, 275,2 , 10584,104 , 13,5 , 4,0 , 3156,9 , 3290,19 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Sao Tome And Principe - { 91, 7, 206, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 640,27 , 37,5 , 8,10 , 14947,48 , 14995,89 , 134,24 , 14947,48 , 14995,89 , 134,24 , 7816,49 , 7723,79 , 7802,14 , 7816,49 , 7723,79 , 7802,14 , 209,8 , 198,8 , 0,5 , 5,17 , 22,23 , {67,72,70}, 217,3 , 10688,45 , 13,5 , 4,0 , 3156,9 , 3309,5 , 2, 0, 1, 6, 7 }, // Portuguese/Latin/Switzerland - { 92, 4, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 567,9 , 567,9 , 287,6 , 10,17 , 18,7 , 25,12 , 15084,50 , 15134,68 , 15202,28 , 15084,50 , 15134,68 , 15202,28 , 7865,36 , 7901,57 , 7958,23 , 7865,36 , 7901,57 , 7958,23 , 217,6 , 206,6 , 696,4 , 5,17 , 22,23 , {73,78,82}, 117,1 , 10733,39 , 4,4 , 4,0 , 3314,6 , 3320,4 , 2, 1, 7, 7, 7 }, // Punjabi/Gurmukhi/India - { 92, 1, 163, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 80,18 , 18,7 , 25,12 , 15230,67 , 15230,67 , 158,27 , 15230,67 , 15230,67 , 158,27 , 7981,37 , 7981,37 , 85,14 , 7981,37 , 7981,37 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {80,75,82}, 277,1 , 10772,13 , 41,6 , 4,0 , 3324,6 , 3330,7 , 0, 0, 7, 6, 7 }, // Punjabi/Arabic/Pakistan - { 93, 7, 169, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 210,18 , 37,5 , 8,10 , 15297,48 , 15345,88 , 158,27 , 15297,48 , 15345,88 , 158,27 , 8018,28 , 8046,53 , 8099,14 , 8018,28 , 8046,53 , 8099,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {80,69,78}, 278,2 , 0,7 , 8,5 , 4,0 , 3337,8 , 3345,4 , 2, 1, 7, 6, 7 }, // Quechua/Latin/Peru - { 93, 7, 26, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 210,18 , 37,5 , 8,10 , 15297,48 , 15345,88 , 158,27 , 15297,48 , 15345,88 , 158,27 , 8018,28 , 8046,53 , 8099,14 , 8018,28 , 8046,53 , 8099,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {66,79,66}, 280,2 , 0,7 , 8,5 , 4,0 , 3337,8 , 3349,7 , 2, 1, 1, 6, 7 }, // Quechua/Latin/Bolivia - { 93, 7, 63, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 210,18 , 37,5 , 8,10 , 15297,48 , 15345,88 , 158,27 , 15297,48 , 15345,88 , 158,27 , 8018,28 , 8046,53 , 8099,14 , 8018,28 , 8046,53 , 8099,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {85,83,68}, 6,1 , 0,7 , 8,5 , 4,0 , 3337,8 , 3356,7 , 2, 1, 1, 6, 7 }, // Quechua/Latin/Ecuador - { 94, 7, 206, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 357,8 , 1011,28 , 37,5 , 8,10 , 15433,67 , 15500,92 , 15592,24 , 15433,67 , 15500,92 , 15592,24 , 8113,23 , 8136,56 , 8192,14 , 8113,23 , 8136,56 , 8192,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,72,70}, 217,3 , 10785,46 , 13,5 , 4,0 , 3363,9 , 3372,6 , 2, 0, 1, 6, 7 }, // Romansh/Latin/Switzerland - { 95, 7, 177, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 576,8 , 576,8 , 981,10 , 10,17 , 37,5 , 8,10 , 15616,60 , 15676,98 , 15774,24 , 15616,60 , 15676,98 , 15774,24 , 8206,34 , 8240,48 , 3150,14 , 8206,34 , 8240,48 , 3150,14 , 66,4 , 63,4 , 700,4 , 5,17 , 22,23 , {82,79,78}, 282,3 , 10831,57 , 13,5 , 4,0 , 3378,6 , 3384,7 , 2, 1, 1, 6, 7 }, // Romanian/Latin/Romania - { 95, 7, 141, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 576,8 , 576,8 , 981,10 , 10,17 , 37,5 , 8,10 , 15616,60 , 15676,98 , 15774,24 , 15616,60 , 15676,98 , 15774,24 , 8288,28 , 8240,48 , 8316,16 , 8288,28 , 8240,48 , 8316,16 , 66,4 , 63,4 , 700,4 , 5,17 , 22,23 , {77,68,76}, 285,1 , 10888,69 , 13,5 , 4,0 , 3378,6 , 3391,17 , 2, 1, 1, 6, 7 }, // Romanian/Latin/Moldova - { 96, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 116,7 , 116,7 , 981,10 , 335,22 , 55,4 , 59,9 , 15798,62 , 11235,80 , 11152,24 , 15860,62 , 15922,82 , 11152,24 , 8332,21 , 8353,62 , 8415,14 , 8332,21 , 8353,62 , 8332,21 , 0,2 , 0,2 , 263,5 , 571,17 , 22,23 , {82,85,66}, 119,1 , 10957,89 , 13,5 , 4,0 , 3408,7 , 3415,6 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Russia - { 96, 2, 20, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 116,7 , 116,7 , 981,10 , 335,22 , 55,4 , 59,9 , 15798,62 , 11235,80 , 11152,24 , 15860,62 , 15922,82 , 11152,24 , 8332,21 , 8353,62 , 8415,14 , 8332,21 , 8353,62 , 8332,21 , 0,2 , 0,2 , 263,5 , 571,17 , 22,23 , {66,89,78}, 0,2 , 11046,94 , 13,5 , 4,0 , 3408,7 , 501,8 , 2, 0, 1, 6, 7 }, // Russian/Cyrillic/Belarus - { 96, 2, 110, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 116,7 , 116,7 , 981,10 , 335,22 , 55,4 , 59,9 , 15798,62 , 11235,80 , 11152,24 , 15860,62 , 15922,82 , 11152,24 , 8332,21 , 8353,62 , 8415,14 , 8332,21 , 8353,62 , 8332,21 , 0,2 , 0,2 , 263,5 , 571,17 , 22,23 , {75,90,84}, 236,1 , 11140,83 , 13,5 , 4,0 , 3408,7 , 3421,9 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Kazakhstan - { 96, 2, 116, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 116,7 , 116,7 , 981,10 , 335,22 , 55,4 , 59,9 , 15798,62 , 11235,80 , 11152,24 , 15860,62 , 15922,82 , 11152,24 , 8332,21 , 8353,62 , 8415,14 , 8332,21 , 8353,62 , 8332,21 , 0,2 , 0,2 , 263,5 , 571,17 , 22,23 , {75,71,83}, 237,3 , 11223,82 , 13,5 , 4,0 , 3408,7 , 3430,8 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Kyrgyzstan - { 96, 2, 141, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 116,7 , 116,7 , 981,10 , 335,22 , 55,4 , 59,9 , 15798,62 , 11235,80 , 11152,24 , 15860,62 , 15922,82 , 11152,24 , 8332,21 , 8353,62 , 8415,14 , 8332,21 , 8353,62 , 8332,21 , 0,2 , 0,2 , 263,5 , 571,17 , 22,23 , {77,68,76}, 285,1 , 11305,79 , 13,5 , 4,0 , 3408,7 , 3438,7 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Moldova - { 96, 2, 222, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 116,7 , 116,7 , 981,10 , 335,22 , 37,5 , 8,10 , 15798,62 , 11235,80 , 11152,24 , 15860,62 , 15922,82 , 11152,24 , 8332,21 , 8353,62 , 8415,14 , 8332,21 , 8353,62 , 8332,21 , 0,2 , 0,2 , 263,5 , 571,17 , 22,23 , {85,65,72}, 286,1 , 11384,92 , 13,5 , 4,0 , 3408,7 , 3445,7 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Ukraine - { 98, 7, 41, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 16004,48 , 16052,91 , 16143,24 , 16004,48 , 16052,91 , 16143,24 , 8429,28 , 8457,66 , 8523,14 , 8429,28 , 8457,66 , 8523,14 , 223,2 , 212,2 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 11476,25 , 4,4 , 36,5 , 3452,5 , 3457,22 , 0, 0, 1, 6, 7 }, // Sango/Latin/Central African Republic - { 99, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,78,82}, 117,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 7, 7 }, // Sanskrit/Devanagari/India - { 100, 2, 243, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 116,7 , 116,7 , 1039,7 , 1046,20 , 37,5 , 8,10 , 16167,48 , 16215,81 , 12531,24 , 16167,48 , 16215,81 , 12531,24 , 8537,28 , 8565,52 , 8617,14 , 8537,28 , 8565,52 , 8617,14 , 225,9 , 214,8 , 704,7 , 5,17 , 22,23 , {82,83,68}, 287,3 , 11501,58 , 13,5 , 4,0 , 3479,6 , 3485,6 , 0, 0, 1, 6, 7 }, // Serbian/Cyrillic/Serbia - { 100, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 163,7 , 163,7 , 1039,7 , 1046,20 , 37,5 , 8,10 , 16296,58 , 16354,81 , 16435,24 , 16296,58 , 16354,81 , 16435,24 , 8631,33 , 8664,57 , 2172,14 , 8631,33 , 8664,57 , 2172,14 , 234,11 , 222,8 , 313,7 , 5,17 , 22,23 , {66,65,77}, 140,2 , 11559,174 , 13,5 , 4,0 , 3491,6 , 620,19 , 2, 1, 1, 6, 7 }, // Serbian/Latin/Bosnia And Herzegowina - { 100, 7, 242, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 163,7 , 163,7 , 1039,7 , 1046,20 , 37,5 , 8,10 , 16296,58 , 16354,81 , 16435,24 , 16296,58 , 16354,81 , 16435,24 , 8631,33 , 8664,57 , 2172,14 , 8631,33 , 8664,57 , 2172,14 , 234,11 , 222,8 , 313,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 11733,23 , 13,5 , 4,0 , 3491,6 , 3497,9 , 2, 1, 1, 6, 7 }, // Serbian/Latin/Montenegro - { 100, 7, 243, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 163,7 , 163,7 , 1039,7 , 1046,20 , 37,5 , 8,10 , 16459,48 , 16354,81 , 16435,24 , 16459,48 , 16354,81 , 16435,24 , 8721,28 , 8749,54 , 2172,14 , 8721,28 , 8749,54 , 2172,14 , 245,9 , 222,8 , 313,7 , 5,17 , 22,23 , {82,83,68}, 287,3 , 11756,58 , 13,5 , 4,0 , 3491,6 , 3506,6 , 0, 0, 1, 6, 7 }, // Serbian/Latin/Serbia - { 100, 2, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 116,7 , 116,7 , 1039,7 , 1046,20 , 37,5 , 8,10 , 16507,58 , 16215,81 , 12531,24 , 16507,58 , 16215,81 , 12531,24 , 8803,33 , 8836,55 , 8617,14 , 8803,33 , 8836,55 , 8617,14 , 254,11 , 214,8 , 704,7 , 5,17 , 22,23 , {66,65,77}, 290,2 , 11814,174 , 13,5 , 4,0 , 3479,6 , 3512,19 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/Bosnia And Herzegowina - { 100, 2, 242, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 116,7 , 116,7 , 1039,7 , 1046,20 , 37,5 , 8,10 , 16507,58 , 16215,81 , 12531,24 , 16507,58 , 16215,81 , 12531,24 , 8803,33 , 8836,55 , 8617,14 , 8803,33 , 8836,55 , 8617,14 , 254,11 , 214,8 , 704,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 11988,23 , 13,5 , 4,0 , 3479,6 , 3531,9 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/Montenegro - { 100, 2, 257, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 116,7 , 116,7 , 1039,7 , 1046,20 , 37,5 , 8,10 , 16507,58 , 16215,81 , 12531,24 , 16507,58 , 16215,81 , 12531,24 , 8803,33 , 8565,52 , 8617,14 , 8803,33 , 8565,52 , 8617,14 , 225,9 , 214,8 , 704,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 11988,23 , 13,5 , 4,0 , 3479,6 , 3540,6 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/Kosovo - { 100, 7, 257, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 163,7 , 163,7 , 1039,7 , 1046,20 , 37,5 , 8,10 , 16296,58 , 16354,81 , 16435,24 , 16296,58 , 16354,81 , 16435,24 , 8631,33 , 8749,54 , 2172,14 , 8631,33 , 8749,54 , 2172,14 , 245,9 , 222,8 , 313,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 11733,23 , 13,5 , 4,0 , 3491,6 , 3546,6 , 2, 1, 1, 6, 7 }, // Serbian/Latin/Kosovo - { 101, 2, 81, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 584,9 , 584,9 , 174,8 , 1066,23 , 37,5 , 8,10 , 16565,63 , 16628,82 , 11152,24 , 16710,60 , 16770,86 , 11152,24 , 8891,28 , 8919,61 , 8980,14 , 8994,28 , 9022,61 , 8980,14 , 265,15 , 230,15 , 45,4 , 5,17 , 22,23 , {71,69,76}, 224,1 , 12011,17 , 8,5 , 4,0 , 3552,4 , 3556,11 , 2, 1, 1, 6, 7 }, // Ossetic/Cyrillic/Georgia - { 101, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 584,9 , 584,9 , 174,8 , 1066,23 , 37,5 , 8,10 , 16565,63 , 16628,82 , 11152,24 , 16710,60 , 16770,86 , 11152,24 , 8891,28 , 8919,61 , 8980,14 , 8994,28 , 9022,61 , 8980,14 , 265,15 , 230,15 , 45,4 , 5,17 , 22,23 , {82,85,66}, 119,1 , 12028,17 , 8,5 , 4,0 , 3552,4 , 3567,6 , 2, 1, 1, 6, 7 }, // Ossetic/Cyrillic/Russia + { 87, 26, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 539,8 , 547,7 , 547,6 , 35,18 , 18,7 , 25,12 , 14586,86 , 14586,86 , 14672,32 , 14586,86 , 14586,86 , 14672,32 , 7630,33 , 7663,54 , 7717,18 , 7630,33 , 7663,54 , 7717,18 , 0,2 , 0,2 , 737,5 , 5,17 , 22,23 , {73,78,82}, 121,1 , 9884,43 , 4,4 , 4,0 , 3163,5 , 3168,4 , 2, 1, 7, 7, 7 }, // Oriya/Oriya/India + { 88, 1, 1, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 46,6 , 46,6 , 554,9 , 563,8 , 394,8 , 1019,20 , 55,4 , 430,11 , 14704,68 , 14772,69 , 158,27 , 14841,69 , 14841,69 , 14910,24 , 7735,39 , 7735,39 , 85,14 , 7735,39 , 7735,39 , 85,14 , 199,4 , 190,4 , 742,5 , 5,17 , 22,23 , {65,70,78}, 263,1 , 9927,25 , 13,5 , 4,0 , 3172,4 , 3176,9 , 0, 0, 6, 4, 5 }, // Pashto/Arabic/Afghanistan + { 89, 1, 102, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 171, 187, 8249, 8250, 571,7 , 571,7 , 578,8 , 586,7 , 394,8 , 97,16 , 55,4 , 430,11 , 14934,70 , 14934,70 , 15004,24 , 15028,74 , 15028,74 , 15004,24 , 7774,49 , 7774,49 , 7823,14 , 7774,49 , 7774,49 , 7823,14 , 203,9 , 194,8 , 747,4 , 751,44 , 22,23 , {73,82,82}, 264,4 , 9952,37 , 84,5 , 4,0 , 3185,5 , 3190,5 , 0, 0, 6, 5, 5 }, // Persian/Arabic/Iran + { 89, 1, 1, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 171, 187, 8249, 8250, 571,7 , 571,7 , 578,8 , 586,7 , 394,8 , 97,16 , 55,4 , 430,11 , 15102,68 , 15102,68 , 14910,24 , 15170,62 , 15102,68 , 14910,24 , 7774,49 , 7774,49 , 7823,14 , 7774,49 , 7774,49 , 7823,14 , 203,9 , 194,8 , 747,4 , 751,44 , 22,23 , {65,70,78}, 263,1 , 9989,55 , 8,5 , 4,0 , 3195,3 , 3176,9 , 0, 0, 6, 4, 5 }, // Persian/Arabic/Afghanistan + { 90, 7, 172, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 163,7 , 163,7 , 495,10 , 10,17 , 37,5 , 8,10 , 15232,48 , 15280,97 , 15377,24 , 15232,48 , 15401,99 , 15500,24 , 7837,34 , 7871,59 , 7930,14 , 7837,34 , 7871,59 , 7944,14 , 0,2 , 0,2 , 303,5 , 5,17 , 22,23 , {80,76,78}, 268,2 , 10044,77 , 13,5 , 4,0 , 3198,6 , 3204,6 , 2, 1, 1, 6, 7 }, // Polish/Latin/Poland + { 91, 7, 30, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 254,7 , 254,7 , 119,10 , 669,27 , 37,5 , 8,10 , 15524,48 , 15572,89 , 134,24 , 15524,48 , 15572,89 , 134,24 , 7958,28 , 7986,79 , 8065,14 , 7958,28 , 7986,79 , 8065,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {66,82,76}, 270,2 , 10121,54 , 8,5 , 4,0 , 3210,9 , 3219,6 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Brazil + { 91, 7, 6, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 669,27 , 37,5 , 8,10 , 15524,48 , 15572,89 , 134,24 , 15524,48 , 15572,89 , 134,24 , 8079,49 , 7986,79 , 8065,14 , 8079,49 , 7986,79 , 8065,14 , 212,8 , 202,8 , 0,5 , 5,17 , 22,23 , {65,79,65}, 250,2 , 10175,54 , 13,5 , 4,0 , 3210,9 , 3225,6 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Angola + { 91, 7, 39, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 669,27 , 37,5 , 8,10 , 15524,48 , 15572,89 , 134,24 , 15524,48 , 15572,89 , 134,24 , 8079,49 , 7986,79 , 8065,14 , 8079,49 , 7986,79 , 8065,14 , 212,8 , 202,8 , 0,5 , 5,17 , 22,23 , {67,86,69}, 272,1 , 10229,69 , 13,5 , 4,0 , 3210,9 , 3231,10 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Cape Verde + { 91, 7, 62, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 669,27 , 37,5 , 8,10 , 15524,48 , 15572,89 , 134,24 , 15524,48 , 15572,89 , 134,24 , 8079,49 , 7986,79 , 8065,14 , 8079,49 , 7986,79 , 8065,14 , 212,8 , 202,8 , 0,5 , 5,17 , 22,23 , {85,83,68}, 159,3 , 10298,81 , 13,5 , 4,0 , 3210,9 , 3241,11 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/East Timor + { 91, 7, 66, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 669,27 , 37,5 , 8,10 , 15524,48 , 15572,89 , 134,24 , 15524,48 , 15572,89 , 134,24 , 8079,49 , 7986,79 , 8065,14 , 8079,49 , 7986,79 , 8065,14 , 212,8 , 202,8 , 0,5 , 5,17 , 22,23 , {88,65,70}, 32,4 , 10379,59 , 13,5 , 4,0 , 3210,9 , 3252,16 , 0, 0, 1, 6, 7 }, // Portuguese/Latin/Equatorial Guinea + { 91, 7, 92, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 669,27 , 37,5 , 8,10 , 15524,48 , 15572,89 , 134,24 , 15524,48 , 15572,89 , 134,24 , 8079,49 , 7986,79 , 8065,14 , 8079,49 , 7986,79 , 8065,14 , 212,8 , 202,8 , 0,5 , 5,17 , 22,23 , {88,79,70}, 204,3 , 10438,62 , 13,5 , 4,0 , 3210,9 , 3268,12 , 0, 0, 1, 6, 7 }, // Portuguese/Latin/Guinea Bissau + { 91, 7, 125, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 669,27 , 37,5 , 8,10 , 15524,48 , 15572,89 , 134,24 , 15524,48 , 15572,89 , 134,24 , 8079,49 , 7986,79 , 8065,14 , 8079,49 , 7986,79 , 8065,14 , 212,8 , 202,8 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 3210,9 , 3280,10 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Luxembourg + { 91, 7, 126, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 669,27 , 18,7 , 25,12 , 15524,48 , 15572,89 , 134,24 , 15524,48 , 15572,89 , 134,24 , 8079,49 , 7986,79 , 8065,14 , 8079,49 , 7986,79 , 8065,14 , 212,8 , 202,8 , 0,5 , 5,17 , 22,23 , {77,79,80}, 137,4 , 10500,53 , 13,5 , 4,0 , 3210,9 , 3290,19 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Macau + { 91, 7, 146, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 669,27 , 37,5 , 8,10 , 15524,48 , 15572,89 , 134,24 , 15524,48 , 15572,89 , 134,24 , 8079,49 , 7986,79 , 8065,14 , 8079,49 , 7986,79 , 8065,14 , 212,8 , 202,8 , 0,5 , 5,17 , 22,23 , {77,90,78}, 273,3 , 10553,66 , 13,5 , 4,0 , 3210,9 , 3309,10 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Mozambique + { 91, 7, 173, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 669,27 , 37,5 , 8,10 , 15524,48 , 15572,89 , 134,24 , 15524,48 , 15572,89 , 134,24 , 8079,49 , 7986,79 , 8065,14 , 8079,49 , 7986,79 , 8065,14 , 212,8 , 202,8 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 3319,17 , 3336,8 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Portugal + { 91, 7, 185, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 669,27 , 37,5 , 8,10 , 15524,48 , 15572,89 , 134,24 , 15524,48 , 15572,89 , 134,24 , 8079,49 , 7986,79 , 8065,14 , 8079,49 , 7986,79 , 8065,14 , 212,8 , 202,8 , 0,5 , 5,17 , 22,23 , {83,84,78}, 276,2 , 10619,92 , 13,5 , 4,0 , 3210,9 , 3344,19 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Sao Tome And Principe + { 91, 7, 206, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 669,27 , 37,5 , 8,10 , 15524,48 , 15572,89 , 134,24 , 15524,48 , 15572,89 , 134,24 , 8079,49 , 7986,79 , 8065,14 , 8079,49 , 7986,79 , 8065,14 , 212,8 , 202,8 , 0,5 , 5,17 , 22,23 , {67,72,70}, 221,3 , 10711,45 , 13,5 , 4,0 , 3210,9 , 3363,5 , 2, 0, 1, 6, 7 }, // Portuguese/Latin/Switzerland + { 92, 4, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 593,9 , 593,9 , 269,6 , 10,17 , 18,7 , 25,12 , 15661,50 , 15711,68 , 15779,28 , 15661,50 , 15711,68 , 15779,28 , 8128,36 , 8164,57 , 8221,23 , 8128,36 , 8164,57 , 8221,23 , 220,6 , 210,6 , 795,4 , 5,17 , 22,23 , {73,78,82}, 121,1 , 10756,39 , 4,4 , 4,0 , 3368,6 , 3374,4 , 2, 1, 7, 7, 7 }, // Punjabi/Gurmukhi/India + { 92, 1, 163, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 553,18 , 18,7 , 25,12 , 15807,67 , 15807,67 , 158,27 , 15807,67 , 15807,67 , 158,27 , 8244,37 , 8244,37 , 85,14 , 8244,37 , 8244,37 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {80,75,82}, 278,1 , 10795,13 , 41,6 , 4,0 , 3378,6 , 3384,7 , 2, 0, 7, 6, 7 }, // Punjabi/Arabic/Pakistan + { 93, 7, 169, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 192,18 , 37,5 , 8,10 , 15874,48 , 15922,88 , 158,27 , 15874,48 , 15922,88 , 158,27 , 8281,28 , 8309,53 , 8362,14 , 8281,28 , 8309,53 , 8362,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {80,69,78}, 279,2 , 0,7 , 8,5 , 4,0 , 3391,8 , 3399,4 , 2, 1, 7, 6, 7 }, // Quechua/Latin/Peru + { 93, 7, 26, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 192,18 , 37,5 , 8,10 , 15874,48 , 15922,88 , 158,27 , 15874,48 , 15922,88 , 158,27 , 8281,28 , 8309,53 , 8362,14 , 8281,28 , 8309,53 , 8362,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {66,79,66}, 281,2 , 0,7 , 8,5 , 4,0 , 3391,8 , 3403,7 , 2, 1, 1, 6, 7 }, // Quechua/Latin/Bolivia + { 93, 7, 63, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 192,18 , 37,5 , 8,10 , 15874,48 , 15922,88 , 158,27 , 15874,48 , 15922,88 , 158,27 , 8281,28 , 8309,53 , 8362,14 , 8281,28 , 8309,53 , 8362,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {85,83,68}, 6,1 , 0,7 , 8,5 , 4,0 , 3391,8 , 3410,7 , 2, 1, 1, 6, 7 }, // Quechua/Latin/Ecuador + { 94, 7, 206, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 339,8 , 1039,28 , 37,5 , 8,10 , 16010,67 , 16077,92 , 16169,24 , 16010,67 , 16077,92 , 16169,24 , 8376,23 , 8399,56 , 8455,14 , 8376,23 , 8399,56 , 8455,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,72,70}, 221,3 , 10808,46 , 13,5 , 4,0 , 3417,9 , 3426,6 , 2, 0, 1, 6, 7 }, // Romansh/Latin/Switzerland + { 95, 7, 177, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 602,8 , 602,8 , 495,10 , 10,17 , 37,5 , 8,10 , 16193,60 , 16253,98 , 16351,24 , 16193,60 , 16253,98 , 16351,24 , 8469,34 , 8503,48 , 3080,14 , 8469,34 , 8503,48 , 3080,14 , 64,4 , 61,4 , 799,4 , 5,17 , 22,23 , {82,79,78}, 283,3 , 10854,57 , 13,5 , 4,0 , 3432,6 , 3438,7 , 2, 1, 1, 6, 7 }, // Romanian/Latin/Romania + { 95, 7, 141, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 602,8 , 602,8 , 495,10 , 10,17 , 37,5 , 8,10 , 16193,60 , 16253,98 , 16351,24 , 16193,60 , 16253,98 , 16351,24 , 8551,28 , 8503,48 , 8579,16 , 8551,28 , 8503,48 , 8579,16 , 64,4 , 61,4 , 799,4 , 5,17 , 22,23 , {77,68,76}, 286,1 , 10911,69 , 13,5 , 4,0 , 3432,6 , 3445,17 , 2, 1, 1, 6, 7 }, // Romanian/Latin/Moldova + { 96, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 116,7 , 116,7 , 495,10 , 317,22 , 37,5 , 8,10 , 16375,62 , 11141,80 , 11058,24 , 16437,62 , 16499,82 , 11058,24 , 8595,21 , 8616,62 , 8678,14 , 8595,21 , 8616,62 , 8595,21 , 0,2 , 0,2 , 246,5 , 701,17 , 22,23 , {82,85,66}, 123,1 , 10980,89 , 13,5 , 4,0 , 3462,7 , 3469,6 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Russia + { 96, 2, 20, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 116,7 , 116,7 , 495,10 , 317,22 , 37,5 , 8,10 , 16375,62 , 11141,80 , 11058,24 , 16437,62 , 16499,82 , 11058,24 , 8595,21 , 8616,62 , 8678,14 , 8595,21 , 8616,62 , 8595,21 , 0,2 , 0,2 , 246,5 , 701,17 , 22,23 , {66,89,78}, 0,2 , 11069,94 , 13,5 , 4,0 , 3462,7 , 501,8 , 2, 0, 1, 6, 7 }, // Russian/Cyrillic/Belarus + { 96, 2, 110, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 116,7 , 116,7 , 495,10 , 317,22 , 37,5 , 8,10 , 16375,62 , 11141,80 , 11058,24 , 16437,62 , 16499,82 , 11058,24 , 8595,21 , 8616,62 , 8678,14 , 8595,21 , 8616,62 , 8595,21 , 0,2 , 0,2 , 246,5 , 701,17 , 22,23 , {75,90,84}, 240,1 , 11163,83 , 13,5 , 4,0 , 3462,7 , 3475,9 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Kazakhstan + { 96, 2, 116, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 116,7 , 116,7 , 495,10 , 317,22 , 37,5 , 8,10 , 16375,62 , 11141,80 , 11058,24 , 16437,62 , 16499,82 , 11058,24 , 8595,21 , 8616,62 , 8678,14 , 8595,21 , 8616,62 , 8595,21 , 0,2 , 0,2 , 246,5 , 701,17 , 22,23 , {75,71,83}, 241,3 , 11246,82 , 13,5 , 4,0 , 3462,7 , 3484,8 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Kyrgyzstan + { 96, 2, 141, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 116,7 , 116,7 , 495,10 , 317,22 , 37,5 , 8,10 , 16375,62 , 11141,80 , 11058,24 , 16437,62 , 16499,82 , 11058,24 , 8595,21 , 8616,62 , 8678,14 , 8595,21 , 8616,62 , 8595,21 , 0,2 , 0,2 , 246,5 , 701,17 , 22,23 , {77,68,76}, 286,1 , 11328,79 , 13,5 , 4,0 , 3462,7 , 3492,7 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Moldova + { 96, 2, 222, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 116,7 , 116,7 , 495,10 , 317,22 , 37,5 , 8,10 , 16375,62 , 11141,80 , 11058,24 , 16437,62 , 16499,82 , 11058,24 , 8595,21 , 8616,62 , 8678,14 , 8595,21 , 8616,62 , 8595,21 , 0,2 , 0,2 , 246,5 , 701,17 , 22,23 , {85,65,72}, 287,1 , 11407,92 , 13,5 , 4,0 , 3462,7 , 3499,7 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Ukraine + { 98, 7, 41, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 16581,48 , 16629,91 , 16720,24 , 16581,48 , 16629,91 , 16720,24 , 8692,28 , 8720,66 , 8786,14 , 8692,28 , 8720,66 , 8786,14 , 226,2 , 216,2 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 11499,25 , 4,4 , 36,5 , 3506,5 , 3511,22 , 0, 0, 1, 6, 7 }, // Sango/Latin/Central African Republic + { 99, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,78,82}, 121,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 7, 7 }, // Sanskrit/Devanagari/India + { 100, 2, 243, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 116,7 , 116,7 , 1067,7 , 1074,20 , 37,5 , 8,10 , 16744,48 , 16792,81 , 12698,24 , 16744,48 , 16792,81 , 12698,24 , 8800,28 , 8828,52 , 8880,14 , 8800,28 , 8828,52 , 8880,14 , 228,9 , 218,8 , 803,7 , 5,17 , 22,23 , {82,83,68}, 288,3 , 11524,58 , 13,5 , 4,0 , 3533,6 , 3539,6 , 0, 0, 1, 6, 7 }, // Serbian/Cyrillic/Serbia + { 100, 2, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 116,7 , 116,7 , 1067,7 , 1074,20 , 37,5 , 8,10 , 16873,50 , 16792,81 , 12698,24 , 16744,48 , 16792,81 , 12698,24 , 8894,26 , 8920,55 , 8880,14 , 8894,26 , 8920,55 , 8880,14 , 237,11 , 218,8 , 803,7 , 5,17 , 22,23 , {66,65,77}, 291,2 , 11582,174 , 13,5 , 4,0 , 3533,6 , 3545,19 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/Bosnia And Herzegowina + { 100, 2, 242, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 116,7 , 116,7 , 1067,7 , 1074,20 , 37,5 , 8,10 , 16923,58 , 16792,81 , 12698,24 , 16923,58 , 16792,81 , 12698,24 , 8975,33 , 8920,55 , 8880,14 , 8975,33 , 8920,55 , 8880,14 , 237,11 , 218,8 , 803,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 11756,23 , 13,5 , 4,0 , 3533,6 , 3564,9 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/Montenegro + { 100, 2, 257, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 116,7 , 116,7 , 1067,7 , 1074,20 , 37,5 , 8,10 , 16923,58 , 16792,81 , 12698,24 , 16923,58 , 16792,81 , 12698,24 , 8975,33 , 8828,52 , 8880,14 , 8975,33 , 8828,52 , 8880,14 , 228,9 , 218,8 , 803,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 11756,23 , 13,5 , 4,0 , 3533,6 , 3573,6 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/Kosovo + { 100, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 163,7 , 163,7 , 1067,7 , 1074,20 , 37,5 , 8,10 , 16981,50 , 17031,81 , 9742,24 , 17112,48 , 17031,81 , 9742,24 , 9008,26 , 9034,57 , 2102,14 , 9008,26 , 9034,57 , 2102,14 , 248,11 , 226,8 , 296,7 , 5,17 , 22,23 , {66,65,77}, 144,2 , 11779,174 , 13,5 , 4,0 , 3579,6 , 620,19 , 2, 1, 1, 6, 7 }, // Serbian/Latin/Bosnia And Herzegowina + { 100, 7, 242, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 163,7 , 163,7 , 1067,7 , 1074,20 , 37,5 , 8,10 , 17160,58 , 17031,81 , 9742,24 , 17160,58 , 17031,81 , 9742,24 , 9091,33 , 9034,57 , 2102,14 , 9091,33 , 9034,57 , 2102,14 , 248,11 , 226,8 , 296,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 11953,23 , 13,5 , 4,0 , 3579,6 , 3585,9 , 2, 1, 1, 6, 7 }, // Serbian/Latin/Montenegro + { 100, 7, 243, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 163,7 , 163,7 , 1067,7 , 1074,20 , 37,5 , 8,10 , 17112,48 , 17031,81 , 9742,24 , 17112,48 , 17031,81 , 9742,24 , 9124,28 , 9152,54 , 2102,14 , 9124,28 , 9152,54 , 2102,14 , 259,9 , 226,8 , 296,7 , 5,17 , 22,23 , {82,83,68}, 288,3 , 11976,58 , 13,5 , 4,0 , 3579,6 , 3594,6 , 0, 0, 1, 6, 7 }, // Serbian/Latin/Serbia + { 100, 7, 257, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8216, 8216, 0,6 , 0,6 , 163,7 , 163,7 , 1067,7 , 1074,20 , 37,5 , 8,10 , 17160,58 , 17031,81 , 9742,24 , 17160,58 , 17031,81 , 9742,24 , 9091,33 , 9152,54 , 2102,14 , 9091,33 , 9152,54 , 2102,14 , 259,9 , 226,8 , 296,7 , 5,17 , 22,23 , {69,85,82}, 14,1 , 11953,23 , 13,5 , 4,0 , 3579,6 , 3600,6 , 2, 1, 1, 6, 7 }, // Serbian/Latin/Kosovo + { 101, 2, 81, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 610,9 , 610,9 , 156,8 , 1094,23 , 37,5 , 8,10 , 17218,63 , 17281,82 , 11058,24 , 17363,60 , 17423,86 , 11058,24 , 9206,28 , 9234,61 , 9295,14 , 9309,28 , 9337,61 , 9295,14 , 268,15 , 234,15 , 45,4 , 5,17 , 22,23 , {71,69,76}, 228,1 , 12034,17 , 8,5 , 4,0 , 3606,4 , 3610,11 , 2, 1, 1, 6, 7 }, // Ossetic/Cyrillic/Georgia + { 101, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 610,9 , 610,9 , 156,8 , 1094,23 , 37,5 , 8,10 , 17218,63 , 17281,82 , 11058,24 , 17363,60 , 17423,86 , 11058,24 , 9206,28 , 9234,61 , 9295,14 , 9309,28 , 9337,61 , 9295,14 , 268,15 , 234,15 , 45,4 , 5,17 , 22,23 , {82,85,66}, 123,1 , 12051,17 , 8,5 , 4,0 , 3606,4 , 3621,6 , 2, 1, 1, 6, 7 }, // Ossetic/Cyrillic/Russia { 102, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {90,65,82}, 5,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Southern Sotho/Latin/South Africa { 103, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {90,65,82}, 5,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Tswana/Latin/South Africa - { 104, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 16856,48 , 16904,100 , 17004,24 , 16856,48 , 16904,100 , 17004,24 , 9083,28 , 9111,55 , 9166,14 , 9083,28 , 9111,55 , 9166,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,83,68}, 155,3 , 12045,22 , 4,4 , 4,0 , 3573,8 , 1791,8 , 2, 1, 7, 6, 7 }, // Shona/Latin/Zimbabwe - { 105, 1, 163, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 18,7 , 25,12 , 17028,72 , 17028,72 , 158,27 , 17028,72 , 17028,72 , 158,27 , 9180,35 , 9180,35 , 9215,21 , 9180,35 , 9180,35 , 9236,31 , 280,11 , 245,11 , 711,6 , 717,52 , 22,23 , {80,75,82}, 172,2 , 12067,43 , 8,5 , 4,0 , 3581,4 , 3585,7 , 0, 0, 7, 6, 7 }, // Sindhi/Arabic/Pakistan - { 106, 32, 198, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 593,9 , 602,8 , 53,10 , 63,17 , 228,5 , 233,10 , 17100,59 , 17159,96 , 17255,32 , 17287,61 , 17159,96 , 17255,32 , 9267,39 , 9306,62 , 9368,19 , 9267,39 , 9306,62 , 9368,19 , 291,5 , 256,4 , 769,5 , 774,37 , 22,23 , {76,75,82}, 292,3 , 12110,58 , 4,4 , 4,0 , 3592,5 , 3597,11 , 2, 1, 1, 6, 7 }, // Sinhala/Sinhala/Sri Lanka + { 104, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 17509,48 , 17557,100 , 17657,24 , 17509,48 , 17557,100 , 17657,24 , 9398,28 , 9426,55 , 9481,14 , 9398,28 , 9426,55 , 9481,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,83,68}, 159,3 , 12068,22 , 4,4 , 4,0 , 3627,8 , 1791,8 , 2, 1, 7, 6, 7 }, // Shona/Latin/Zimbabwe + { 105, 1, 163, 1643, 1644, 1563, 37, 1632, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 619,8 , 627,7 , 53,10 , 63,17 , 18,7 , 25,12 , 17681,72 , 17681,72 , 134,24 , 17681,72 , 17681,72 , 134,24 , 9495,35 , 9495,35 , 9530,31 , 9495,35 , 9495,35 , 9530,31 , 283,11 , 249,11 , 810,6 , 816,61 , 22,23 , {80,75,82}, 176,2 , 12090,43 , 8,5 , 4,0 , 3635,4 , 3639,7 , 2, 0, 7, 6, 7 }, // Sindhi/Arabic/Pakistan + { 106, 32, 198, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 634,9 , 643,8 , 53,10 , 63,17 , 228,5 , 233,10 , 17753,59 , 17812,96 , 17908,32 , 17940,61 , 17812,96 , 17908,32 , 9561,39 , 9600,62 , 9662,19 , 9561,39 , 9600,62 , 9662,19 , 294,5 , 260,4 , 877,5 , 882,42 , 22,23 , {76,75,82}, 293,3 , 12133,58 , 4,4 , 4,0 , 3646,5 , 3651,11 , 2, 1, 1, 6, 7 }, // Sinhala/Sinhala/Sri Lanka { 107, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {90,65,82}, 5,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Swati/Latin/South Africa - { 108, 7, 191, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 185,7 , 610,7 , 1089,10 , 496,17 , 55,4 , 59,9 , 17348,48 , 17396,82 , 16435,24 , 17348,48 , 17478,89 , 16435,24 , 9387,21 , 9408,52 , 9460,14 , 9387,21 , 9408,52 , 9460,14 , 0,2 , 0,2 , 320,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 12168,26 , 13,5 , 4,0 , 3608,10 , 3618,9 , 2, 1, 1, 6, 7 }, // Slovak/Latin/Slovakia - { 109, 7, 192, 44, 46, 59, 37, 48, 8722, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 617,8 , 617,8 , 1099,9 , 1108,19 , 37,5 , 8,10 , 17567,59 , 17626,86 , 16435,24 , 17567,59 , 17626,86 , 16435,24 , 9474,35 , 9509,52 , 9561,14 , 9474,35 , 9509,52 , 9561,14 , 62,4 , 260,4 , 54,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 12194,28 , 13,5 , 4,0 , 3627,11 , 3638,9 , 2, 1, 1, 6, 7 }, // Slovenian/Latin/Slovenia - { 110, 7, 194, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1127,19 , 18,7 , 25,12 , 17712,48 , 17760,189 , 17949,24 , 17712,48 , 17760,189 , 17949,24 , 9575,28 , 9603,47 , 9650,15 , 9575,28 , 9603,47 , 9650,15 , 296,3 , 264,3 , 45,4 , 5,17 , 22,23 , {83,79,83}, 90,1 , 12222,22 , 4,4 , 4,0 , 3647,8 , 3655,10 , 0, 0, 1, 6, 7 }, // Somali/Latin/Somalia - { 110, 7, 59, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1127,19 , 18,7 , 25,12 , 17712,48 , 17760,189 , 17949,24 , 17712,48 , 17760,189 , 17949,24 , 9575,28 , 9603,47 , 9650,15 , 9575,28 , 9603,47 , 9650,15 , 296,3 , 264,3 , 45,4 , 5,17 , 22,23 , {68,74,70}, 38,3 , 12244,21 , 4,4 , 4,0 , 3647,8 , 3665,7 , 0, 0, 6, 6, 7 }, // Somali/Latin/Djibouti - { 110, 7, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1127,19 , 18,7 , 25,12 , 17712,48 , 17760,189 , 17949,24 , 17712,48 , 17760,189 , 17949,24 , 9575,28 , 9603,47 , 9650,15 , 9575,28 , 9603,47 , 9650,15 , 296,3 , 264,3 , 45,4 , 5,17 , 22,23 , {69,84,66}, 0,2 , 12265,22 , 4,4 , 4,0 , 3647,8 , 3672,8 , 2, 1, 7, 6, 7 }, // Somali/Latin/Ethiopia - { 110, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1127,19 , 37,5 , 8,10 , 17712,48 , 17760,189 , 17949,24 , 17712,48 , 17760,189 , 17949,24 , 9575,28 , 9603,47 , 9650,15 , 9575,28 , 9603,47 , 9650,15 , 296,3 , 264,3 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 0,7 , 4,4 , 4,0 , 3647,8 , 3680,7 , 2, 1, 7, 6, 7 }, // Somali/Latin/Kenya - { 111, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 55,4 , 426,11 , 17973,61 , 18034,89 , 18123,24 , 17973,61 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 8099,14 , 9665,35 , 9700,53 , 8099,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 3687,17 , 2398,6 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Spain - { 111, 7, 10, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 37,5 , 8,10 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 3150,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {65,82,83}, 6,1 , 12287,51 , 8,5 , 4,0 , 3704,7 , 3711,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Argentina - { 111, 7, 22, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 37,5 , 8,10 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 66,4 , 63,4 , 0,5 , 5,17 , 22,23 , {66,90,68}, 6,1 , 12338,52 , 4,4 , 4,0 , 3704,7 , 3720,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Belize - { 111, 7, 26, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 37,5 , 8,10 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {66,79,66}, 280,2 , 12390,35 , 4,4 , 4,0 , 3704,7 , 3349,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Bolivia - { 111, 7, 30, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 37,5 , 8,10 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 66,4 , 63,4 , 0,5 , 5,17 , 22,23 , {66,82,76}, 269,2 , 12425,52 , 4,4 , 4,0 , 3704,7 , 3165,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Brazil - { 111, 7, 43, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 357,8 , 640,27 , 37,5 , 8,10 , 17973,61 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {67,76,80}, 6,1 , 12477,45 , 4,4 , 36,5 , 3704,7 , 3726,5 , 0, 0, 1, 6, 7 }, // Spanish/Latin/Chile - { 111, 7, 47, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 536,7 , 640,27 , 18,7 , 25,12 , 17973,61 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 9753,14 , 9665,35 , 9700,53 , 3150,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {67,79,80}, 6,1 , 12522,54 , 8,5 , 4,0 , 3704,7 , 3731,8 , 0, 0, 7, 6, 7 }, // Spanish/Latin/Colombia - { 111, 7, 52, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 37,5 , 8,10 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {67,82,67}, 295,1 , 12576,67 , 4,4 , 4,0 , 3704,7 , 3739,10 , 2, 0, 1, 6, 7 }, // Spanish/Latin/Costa Rica - { 111, 7, 55, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 37,5 , 8,10 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 66,4 , 63,4 , 0,5 , 5,17 , 22,23 , {67,85,80}, 6,1 , 12643,42 , 4,4 , 4,0 , 3704,7 , 3749,4 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Cuba - { 111, 7, 61, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 18,7 , 25,12 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 3150,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {68,79,80}, 296,3 , 12685,54 , 4,4 , 89,6 , 3704,7 , 3753,20 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Dominican Republic - { 111, 7, 63, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 37,5 , 8,10 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 12739,70 , 4,4 , 36,5 , 3704,7 , 3356,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Ecuador - { 111, 7, 65, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 37,5 , 8,10 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 12739,70 , 4,4 , 4,0 , 3704,7 , 3773,11 , 2, 1, 7, 6, 7 }, // Spanish/Latin/El Salvador - { 111, 7, 66, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 55,4 , 426,11 , 17973,61 , 18034,89 , 18123,24 , 17973,61 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 8099,14 , 9665,35 , 9700,53 , 8099,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {88,65,70}, 32,4 , 12809,92 , 4,4 , 4,0 , 3704,7 , 3784,17 , 0, 0, 1, 6, 7 }, // Spanish/Latin/Equatorial Guinea - { 111, 7, 90, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 536,7 , 640,27 , 37,5 , 8,10 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {71,84,81}, 299,1 , 12901,30 , 18,5 , 4,0 , 3704,7 , 3801,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Guatemala - { 111, 7, 96, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 1146,27 , 37,5 , 8,10 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {72,78,76}, 285,1 , 12931,60 , 4,4 , 4,0 , 3704,7 , 3810,8 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Honduras - { 111, 7, 139, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 625,7 , 625,7 , 27,8 , 640,27 , 55,4 , 59,9 , 18147,60 , 18034,89 , 18123,24 , 18207,48 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 3150,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {77,88,78}, 6,1 , 12991,48 , 47,6 , 4,0 , 3818,17 , 3835,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Mexico - { 111, 7, 155, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 37,5 , 8,10 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {78,73,79}, 300,2 , 13039,69 , 4,4 , 4,0 , 3704,7 , 3841,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Nicaragua - { 111, 7, 166, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 1173,8 , 640,27 , 18,7 , 25,12 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {80,65,66}, 302,3 , 13108,54 , 4,4 , 4,0 , 3704,7 , 3850,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Panama - { 111, 7, 168, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 37,5 , 8,10 , 17973,61 , 18034,89 , 18123,24 , 17973,61 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {80,89,71}, 305,3 , 13162,61 , 8,5 , 23,6 , 3704,7 , 3856,8 , 0, 0, 7, 6, 7 }, // Spanish/Latin/Paraguay - { 111, 7, 169, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 536,7 , 640,27 , 37,5 , 8,10 , 18255,60 , 15345,88 , 18123,24 , 18315,60 , 18375,88 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {80,69,78}, 278,2 , 13223,43 , 4,4 , 4,0 , 3704,7 , 3345,4 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Peru - { 111, 7, 170, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 18,7 , 25,12 , 17973,61 , 18034,89 , 18123,24 , 17973,61 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 8099,14 , 9665,35 , 9700,53 , 8099,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {80,72,80}, 175,1 , 13266,48 , 13,5 , 4,0 , 3704,7 , 3864,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Philippines - { 111, 7, 174, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 1173,8 , 640,27 , 18,7 , 25,12 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 12739,70 , 4,4 , 4,0 , 3704,7 , 1437,11 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Puerto Rico - { 111, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 625,7 , 625,7 , 433,8 , 640,27 , 18,7 , 25,12 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 3150,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 12739,70 , 95,7 , 4,0 , 3704,7 , 3873,14 , 2, 1, 7, 6, 7 }, // Spanish/Latin/United States - { 111, 7, 227, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 37,5 , 8,10 , 18255,60 , 15345,88 , 18123,24 , 18315,60 , 18375,88 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {85,89,85}, 6,1 , 13314,48 , 8,5 , 4,0 , 3704,7 , 3887,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Uruguay - { 111, 7, 231, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 18,7 , 25,12 , 17973,61 , 18034,89 , 18123,24 , 17973,61 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {86,69,70}, 308,3 , 13362,64 , 4,4 , 36,5 , 3704,7 , 3894,9 , 2, 0, 7, 6, 7 }, // Spanish/Latin/Venezuela - { 111, 7, 238, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 55,4 , 426,11 , 17973,61 , 18034,89 , 18123,24 , 17973,61 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 8099,14 , 9665,35 , 9700,53 , 8099,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 3704,7 , 3903,8 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Canary Islands - { 111, 7, 246, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 37,5 , 8,10 , 18147,60 , 18034,89 , 18123,24 , 18147,60 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 3150,14 , 9665,35 , 9700,53 , 9753,14 , 66,4 , 63,4 , 0,5 , 5,17 , 22,23 , {0,0,0}, 0,0 , 2586,0 , 4,4 , 4,0 , 3911,23 , 3934,13 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Latin America - { 111, 7, 250, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 640,27 , 55,4 , 426,11 , 17973,61 , 18034,89 , 18123,24 , 17973,61 , 18034,89 , 18123,24 , 9665,35 , 9700,53 , 8099,14 , 9665,35 , 9700,53 , 8099,14 , 55,5 , 52,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 3704,7 , 3947,15 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Ceuta And Melilla - { 113, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 632,8 , 632,8 , 120,10 , 10,17 , 37,5 , 8,10 , 18463,48 , 18511,84 , 134,24 , 18463,48 , 18511,84 , 134,24 , 9767,60 , 9767,60 , 85,14 , 9767,60 , 9767,60 , 85,14 , 0,2 , 0,2 , 591,5 , 811,47 , 22,23 , {84,90,83}, 188,3 , 13426,67 , 4,4 , 4,0 , 3962,9 , 1616,8 , 0, 0, 1, 6, 7 }, // Swahili/Latin/Tanzania - { 113, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 632,8 , 632,8 , 120,10 , 10,17 , 37,5 , 8,10 , 18463,48 , 18511,84 , 134,24 , 18463,48 , 18511,84 , 134,24 , 9767,60 , 9767,60 , 85,14 , 9767,60 , 9767,60 , 85,14 , 0,2 , 0,2 , 591,5 , 811,47 , 22,23 , {67,68,70}, 203,2 , 13493,55 , 4,4 , 4,0 , 3971,8 , 3979,32 , 2, 1, 1, 6, 7 }, // Swahili/Latin/Congo Kinshasa - { 113, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 632,8 , 632,8 , 120,10 , 10,17 , 37,5 , 8,10 , 18463,48 , 18511,84 , 134,24 , 18463,48 , 18511,84 , 134,24 , 9767,60 , 9767,60 , 85,14 , 9767,60 , 9767,60 , 85,14 , 0,2 , 0,2 , 591,5 , 811,47 , 22,23 , {75,69,83}, 2,3 , 13548,58 , 4,4 , 4,0 , 3962,9 , 1182,5 , 2, 1, 7, 6, 7 }, // Swahili/Latin/Kenya - { 113, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 632,8 , 632,8 , 120,10 , 10,17 , 37,5 , 8,10 , 18463,48 , 18511,84 , 134,24 , 18463,48 , 18511,84 , 134,24 , 9767,60 , 9767,60 , 85,14 , 9767,60 , 9767,60 , 85,14 , 0,2 , 0,2 , 591,5 , 811,47 , 22,23 , {85,71,88}, 193,3 , 13606,61 , 4,4 , 4,0 , 3962,9 , 1681,6 , 0, 0, 1, 6, 7 }, // Swahili/Latin/Uganda - { 114, 7, 205, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 640,9 , 640,9 , 53,10 , 98,16 , 37,5 , 437,16 , 18595,59 , 18654,86 , 134,24 , 18595,59 , 18654,86 , 134,24 , 9827,29 , 9856,50 , 2363,14 , 9827,29 , 9856,50 , 2363,14 , 299,2 , 267,2 , 45,4 , 5,17 , 22,23 , {83,69,75}, 186,2 , 13667,45 , 13,5 , 4,0 , 4011,7 , 4018,7 , 2, 0, 1, 6, 7 }, // Swedish/Latin/Sweden - { 114, 7, 73, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 640,9 , 640,9 , 1181,10 , 98,16 , 37,5 , 437,16 , 18595,59 , 18654,86 , 134,24 , 18595,59 , 18654,86 , 134,24 , 9827,29 , 9856,50 , 2363,14 , 9827,29 , 9856,50 , 2363,14 , 299,2 , 267,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8897,19 , 13,5 , 4,0 , 4011,7 , 1079,7 , 2, 1, 1, 6, 7 }, // Swedish/Latin/Finland - { 114, 7, 248, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 640,9 , 640,9 , 53,10 , 98,16 , 37,5 , 437,16 , 18595,59 , 18654,86 , 134,24 , 18595,59 , 18654,86 , 134,24 , 9827,29 , 9856,50 , 2363,14 , 9827,29 , 9856,50 , 2363,14 , 299,2 , 267,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8897,19 , 13,5 , 4,0 , 4011,7 , 4025,5 , 2, 1, 1, 6, 7 }, // Swedish/Latin/Aland Islands - { 116, 2, 209, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 80,18 , 37,5 , 8,10 , 11024,48 , 18740,71 , 11152,24 , 11024,48 , 18740,71 , 11152,24 , 9906,28 , 9934,55 , 9989,14 , 9906,28 , 9934,55 , 9989,14 , 301,7 , 269,7 , 45,4 , 5,17 , 22,23 , {84,74,83}, 311,4 , 13712,19 , 13,5 , 4,0 , 4030,6 , 4036,10 , 2, 1, 1, 6, 7 }, // Tajik/Cyrillic/Tajikistan - { 117, 27, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 649,13 , 649,13 , 287,6 , 210,18 , 382,7 , 453,12 , 18811,58 , 18869,86 , 18955,31 , 18811,58 , 18869,86 , 18955,31 , 10003,39 , 10042,49 , 10091,20 , 10003,39 , 10042,49 , 10091,20 , 308,8 , 276,8 , 858,7 , 5,17 , 22,23 , {73,78,82}, 117,1 , 13731,49 , 8,5 , 4,0 , 4046,5 , 4051,7 , 2, 1, 7, 7, 7 }, // Tamil/Tamil/India - { 117, 27, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 649,13 , 649,13 , 287,6 , 210,18 , 382,7 , 453,12 , 18811,58 , 18869,86 , 18955,31 , 18811,58 , 18869,86 , 18955,31 , 10003,39 , 10042,49 , 10091,20 , 10003,39 , 10042,49 , 10091,20 , 308,8 , 276,8 , 858,7 , 5,17 , 22,23 , {77,89,82}, 170,2 , 13780,61 , 8,5 , 4,0 , 4046,5 , 4058,7 , 2, 1, 1, 6, 7 }, // Tamil/Tamil/Malaysia - { 117, 27, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 649,13 , 649,13 , 287,6 , 210,18 , 382,7 , 453,12 , 18811,58 , 18869,86 , 18955,31 , 18811,58 , 18869,86 , 18955,31 , 10003,39 , 10042,49 , 10091,20 , 10003,39 , 10042,49 , 10091,20 , 308,8 , 276,8 , 858,7 , 5,17 , 22,23 , {83,71,68}, 6,1 , 13841,61 , 8,5 , 4,0 , 4046,5 , 4065,11 , 2, 1, 7, 6, 7 }, // Tamil/Tamil/Singapore - { 117, 27, 198, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 649,13 , 649,13 , 287,6 , 210,18 , 37,5 , 8,10 , 18811,58 , 18869,86 , 18955,31 , 18811,58 , 18869,86 , 18955,31 , 10003,39 , 10042,49 , 10091,20 , 10003,39 , 10042,49 , 10091,20 , 308,8 , 276,8 , 858,7 , 5,17 , 22,23 , {76,75,82}, 315,3 , 13902,49 , 8,5 , 4,0 , 4046,5 , 4076,6 , 2, 1, 1, 6, 7 }, // Tamil/Tamil/Sri Lanka - { 118, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 662,9 , 662,9 , 981,10 , 1191,23 , 55,4 , 59,9 , 18986,62 , 19048,81 , 158,27 , 18986,62 , 19048,81 , 158,27 , 10111,36 , 10147,56 , 10203,14 , 10111,36 , 10147,56 , 10203,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {82,85,66}, 119,1 , 13951,21 , 0,4 , 4,0 , 4082,5 , 3415,6 , 2, 1, 1, 6, 7 }, // Tatar/Cyrillic/Russia - { 119, 28, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 671,11 , 671,11 , 357,8 , 1214,18 , 18,7 , 25,12 , 19129,62 , 19191,86 , 19277,31 , 19129,62 , 19191,86 , 19277,31 , 10217,32 , 10249,60 , 10309,18 , 10217,32 , 10249,60 , 10309,18 , 0,2 , 0,2 , 865,7 , 872,27 , 22,23 , {73,78,82}, 117,1 , 13972,26 , 4,4 , 4,0 , 4087,6 , 4093,8 , 2, 1, 7, 7, 7 }, // Telugu/Telugu/India - { 120, 30, 211, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 123,5 , 123,5 , 682,8 , 690,7 , 287,6 , 1232,19 , 37,5 , 465,28 , 19308,63 , 19371,98 , 19308,63 , 19308,63 , 19371,98 , 19308,63 , 10327,23 , 10350,68 , 10418,16 , 10327,23 , 10350,68 , 10418,16 , 316,10 , 284,10 , 899,4 , 5,17 , 22,23 , {84,72,66}, 318,3 , 13998,16 , 4,4 , 4,0 , 4101,3 , 4101,3 , 2, 1, 7, 6, 7 }, // Thai/Thai/Thailand - { 121, 31, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 1251,23 , 18,7 , 25,12 , 2923,63 , 19469,159 , 158,27 , 2923,63 , 19628,147 , 158,27 , 10434,51 , 10485,79 , 10564,27 , 10434,51 , 10485,79 , 10564,27 , 326,7 , 294,8 , 45,4 , 5,17 , 22,23 , {67,78,89}, 321,1 , 14014,13 , 8,5 , 4,0 , 4104,8 , 4112,6 , 2, 1, 7, 6, 7 }, // Tibetan/Tibetan/China - { 121, 31, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 1251,23 , 18,7 , 25,12 , 2923,63 , 19469,159 , 158,27 , 2923,63 , 19628,147 , 158,27 , 10434,51 , 10485,79 , 10564,27 , 10434,51 , 10485,79 , 10564,27 , 326,7 , 294,8 , 45,4 , 5,17 , 22,23 , {73,78,82}, 117,1 , 14027,19 , 8,5 , 4,0 , 4104,8 , 4118,7 , 2, 1, 7, 7, 7 }, // Tibetan/Tibetan/India - { 122, 14, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1274,23 , 18,7 , 25,12 , 19775,36 , 19811,54 , 19865,24 , 19775,36 , 19811,54 , 19865,24 , 10591,21 , 10612,29 , 10641,14 , 10591,21 , 10655,29 , 10684,14 , 333,7 , 302,7 , 45,4 , 5,17 , 22,23 , {69,84,66}, 0,2 , 14046,16 , 4,4 , 4,0 , 4125,4 , 82,5 , 2, 1, 7, 6, 7 }, // Tigrinya/Ethiopic/Ethiopia - { 122, 14, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1274,23 , 18,7 , 25,12 , 19775,36 , 19811,54 , 19865,24 , 19775,36 , 19811,54 , 19865,24 , 10591,21 , 10612,29 , 10684,14 , 10591,21 , 10655,29 , 10684,14 , 333,7 , 302,7 , 45,4 , 5,17 , 22,23 , {69,82,78}, 41,3 , 0,7 , 4,4 , 4,0 , 4125,4 , 4129,4 , 2, 1, 1, 6, 7 }, // Tigrinya/Ethiopic/Eritrea - { 123, 7, 214, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 697,8 , 697,8 , 697,8 , 697,8 , 287,6 , 98,16 , 18,7 , 25,12 , 19889,51 , 19940,87 , 20027,24 , 19889,51 , 19940,87 , 20027,24 , 10698,29 , 10727,60 , 10787,14 , 10698,29 , 10727,60 , 10787,14 , 340,10 , 309,6 , 903,5 , 908,59 , 967,65 , {84,79,80}, 191,2 , 14062,41 , 13,5 , 4,0 , 4133,13 , 1631,5 , 2, 1, 1, 6, 7 }, // Tongan/Latin/Tonga + { 108, 7, 191, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 185,7 , 651,7 , 1117,10 , 478,17 , 55,4 , 59,9 , 18001,48 , 18049,82 , 9742,24 , 18001,48 , 18131,89 , 9742,24 , 9681,21 , 9702,52 , 9754,14 , 9681,21 , 9702,52 , 9754,14 , 0,2 , 0,2 , 303,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 12191,26 , 13,5 , 4,0 , 3662,10 , 3672,9 , 2, 1, 1, 6, 7 }, // Slovak/Latin/Slovakia + { 109, 7, 192, 44, 46, 59, 37, 48, 8722, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 658,8 , 658,8 , 1127,9 , 1136,19 , 37,5 , 8,10 , 18220,59 , 18279,86 , 9742,24 , 18220,59 , 18279,86 , 9742,24 , 9768,35 , 9803,52 , 9855,14 , 9768,35 , 9803,52 , 9855,14 , 60,4 , 264,4 , 54,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 12217,28 , 13,5 , 4,0 , 3681,11 , 3692,9 , 2, 1, 1, 6, 7 }, // Slovenian/Latin/Slovenia + { 110, 7, 194, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 666,9 , 666,9 , 27,8 , 1155,19 , 18,7 , 25,12 , 18365,52 , 18417,92 , 18509,24 , 18533,68 , 18601,189 , 18790,24 , 9869,28 , 9897,47 , 9944,15 , 9869,28 , 9897,47 , 9944,15 , 299,3 , 268,3 , 924,4 , 5,17 , 22,23 , {83,79,83}, 94,1 , 12245,27 , 4,4 , 4,0 , 3701,8 , 3709,10 , 0, 0, 1, 6, 7 }, // Somali/Latin/Somalia + { 110, 7, 59, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 666,9 , 666,9 , 27,8 , 1155,19 , 18,7 , 25,12 , 18365,52 , 18417,92 , 18509,24 , 18533,68 , 18601,189 , 18790,24 , 9869,28 , 9897,47 , 9944,15 , 9869,28 , 9897,47 , 9944,15 , 299,3 , 268,3 , 924,4 , 5,17 , 22,23 , {68,74,70}, 38,3 , 12272,49 , 4,4 , 4,0 , 3701,8 , 3719,7 , 0, 0, 6, 6, 7 }, // Somali/Latin/Djibouti + { 110, 7, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 666,9 , 666,9 , 27,8 , 1155,19 , 18,7 , 25,12 , 18365,52 , 18417,92 , 18509,24 , 18533,68 , 18601,189 , 18790,24 , 9869,28 , 9897,47 , 9944,15 , 9869,28 , 9897,47 , 9944,15 , 299,3 , 268,3 , 924,4 , 5,17 , 22,23 , {69,84,66}, 0,2 , 12321,22 , 4,4 , 4,0 , 3701,8 , 3726,8 , 2, 1, 7, 6, 7 }, // Somali/Latin/Ethiopia + { 110, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 666,9 , 666,9 , 27,8 , 1155,19 , 37,5 , 8,10 , 18365,52 , 18417,92 , 18509,24 , 18533,68 , 18601,189 , 18790,24 , 9869,28 , 9897,47 , 9944,15 , 9869,28 , 9897,47 , 9944,15 , 299,3 , 268,3 , 924,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 12343,50 , 4,4 , 4,0 , 3701,8 , 1182,5 , 2, 1, 7, 6, 7 }, // Somali/Latin/Kenya + { 111, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 675,7 , 675,7 , 269,6 , 669,27 , 55,4 , 430,11 , 18814,61 , 18875,89 , 18964,24 , 18814,61 , 18875,89 , 18964,24 , 9959,35 , 9994,53 , 8362,14 , 9959,35 , 9994,53 , 8362,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 3734,17 , 2398,6 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Spain + { 111, 7, 10, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 675,7 , 675,7 , 269,6 , 669,27 , 37,5 , 8,10 , 18988,60 , 18875,89 , 18964,24 , 18988,60 , 18875,89 , 18964,24 , 9959,35 , 9994,53 , 3080,14 , 9959,35 , 9994,53 , 3080,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {65,82,83}, 6,1 , 12393,51 , 8,5 , 4,0 , 3751,7 , 3758,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Argentina + { 111, 7, 22, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 675,7 , 675,7 , 269,6 , 669,27 , 37,5 , 8,10 , 18988,60 , 18875,89 , 18964,24 , 18988,60 , 18875,89 , 18964,24 , 9959,35 , 9994,53 , 3080,14 , 9959,35 , 9994,53 , 4769,14 , 64,4 , 61,4 , 0,5 , 5,17 , 22,23 , {66,90,68}, 6,1 , 12444,52 , 4,4 , 4,0 , 3751,7 , 3767,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Belize + { 111, 7, 26, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 675,7 , 675,7 , 269,6 , 669,27 , 37,5 , 8,10 , 18988,60 , 18875,89 , 18964,24 , 18988,60 , 18875,89 , 18964,24 , 9959,35 , 9994,53 , 3080,14 , 9959,35 , 9994,53 , 4769,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {66,79,66}, 281,2 , 12496,35 , 4,4 , 4,0 , 3751,7 , 3403,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Bolivia + { 111, 7, 30, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 675,7 , 675,7 , 269,6 , 669,27 , 37,5 , 8,10 , 18988,60 , 18875,89 , 18964,24 , 18988,60 , 18875,89 , 18964,24 , 9959,35 , 9994,53 , 3080,14 , 9959,35 , 9994,53 , 4769,14 , 64,4 , 61,4 , 0,5 , 5,17 , 22,23 , {66,82,76}, 270,2 , 12531,52 , 4,4 , 4,0 , 3751,7 , 3219,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Brazil + { 111, 7, 43, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 675,7 , 675,7 , 339,8 , 669,27 , 37,5 , 8,10 , 18814,61 , 18875,89 , 18964,24 , 18988,60 , 18875,89 , 18964,24 , 9959,35 , 9994,53 , 3080,14 , 9959,35 , 9994,53 , 4769,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {67,76,80}, 6,1 , 12583,45 , 4,4 , 36,5 , 3751,7 , 3773,5 , 0, 0, 1, 6, 7 }, // Spanish/Latin/Chile + { 111, 7, 47, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 675,7 , 675,7 , 571,7 , 669,27 , 18,7 , 25,12 , 18814,61 , 18875,89 , 18964,24 , 18988,60 , 18875,89 , 18964,24 , 9959,35 , 9994,53 , 4769,14 , 9959,35 , 9994,53 , 3080,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {67,79,80}, 6,1 , 12628,54 , 8,5 , 4,0 , 3751,7 , 3778,8 , 2, 0, 7, 6, 7 }, // Spanish/Latin/Colombia + { 111, 7, 52, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 675,7 , 675,7 , 269,6 , 669,27 , 37,5 , 8,10 , 18988,60 , 18875,89 , 18964,24 , 18988,60 , 18875,89 , 18964,24 , 9959,35 , 9994,53 , 3080,14 , 9959,35 , 9994,53 , 4769,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {67,82,67}, 296,1 , 12682,67 , 4,4 , 4,0 , 3751,7 , 3786,10 , 2, 0, 1, 6, 7 }, // Spanish/Latin/Costa Rica + { 111, 7, 55, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 675,7 , 675,7 , 269,6 , 669,27 , 37,5 , 8,10 , 18988,60 , 18875,89 , 18964,24 , 18988,60 , 18875,89 , 18964,24 , 9959,35 , 9994,53 , 3080,14 , 9959,35 , 9994,53 , 4769,14 , 64,4 , 61,4 , 0,5 , 5,17 , 22,23 , {67,85,80}, 6,1 , 12749,42 , 4,4 , 4,0 , 3751,7 , 3796,4 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Cuba + { 111, 7, 61, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 675,7 , 675,7 , 269,6 , 669,27 , 18,7 , 25,12 , 18988,60 , 18875,89 , 18964,24 , 18988,60 , 18875,89 , 18964,24 , 9959,35 , 9994,53 , 3080,14 , 9959,35 , 9994,53 , 3080,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {68,79,80}, 297,3 , 12791,54 , 4,4 , 89,6 , 3751,7 , 3800,20 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Dominican Republic + { 111, 7, 63, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 675,7 , 675,7 , 269,6 , 669,27 , 37,5 , 8,10 , 18988,60 , 18875,89 , 18964,24 , 18988,60 , 18875,89 , 18964,24 , 9959,35 , 9994,53 , 3080,14 , 9959,35 , 9994,53 , 4769,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 12845,70 , 4,4 , 36,5 , 3751,7 , 3410,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Ecuador + { 111, 7, 65, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 675,7 , 675,7 , 269,6 , 669,27 , 37,5 , 8,10 , 18988,60 , 18875,89 , 18964,24 , 18988,60 , 18875,89 , 18964,24 , 9959,35 , 9994,53 , 3080,14 , 9959,35 , 9994,53 , 4769,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 12845,70 , 4,4 , 4,0 , 3751,7 , 3820,11 , 2, 1, 7, 6, 7 }, // Spanish/Latin/El Salvador + { 111, 7, 66, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 675,7 , 675,7 , 269,6 , 669,27 , 55,4 , 430,11 , 18814,61 , 18875,89 , 18964,24 , 18814,61 , 18875,89 , 18964,24 , 9959,35 , 9994,53 , 8362,14 , 9959,35 , 9994,53 , 8362,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {88,65,70}, 32,4 , 12915,92 , 4,4 , 4,0 , 3751,7 , 3831,17 , 0, 0, 1, 6, 7 }, // Spanish/Latin/Equatorial Guinea + { 111, 7, 90, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 675,7 , 675,7 , 571,7 , 669,27 , 37,5 , 8,10 , 18988,60 , 18875,89 , 18964,24 , 18988,60 , 18875,89 , 18964,24 , 9959,35 , 9994,53 , 3080,14 , 9959,35 , 9994,53 , 4769,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {71,84,81}, 300,1 , 13007,30 , 18,5 , 4,0 , 3751,7 , 3848,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Guatemala + { 111, 7, 96, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 675,7 , 675,7 , 269,6 , 1174,27 , 37,5 , 8,10 , 18988,60 , 18875,89 , 18964,24 , 18988,60 , 18875,89 , 18964,24 , 9959,35 , 9994,53 , 3080,14 , 9959,35 , 9994,53 , 4769,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {72,78,76}, 286,1 , 13037,60 , 4,4 , 4,0 , 3751,7 , 3857,8 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Honduras + { 111, 7, 139, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 675,7 , 675,7 , 27,8 , 669,27 , 55,4 , 59,9 , 18988,60 , 18875,89 , 18964,24 , 19048,48 , 18875,89 , 18964,24 , 9959,35 , 9994,53 , 3080,14 , 9959,35 , 9994,53 , 3080,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {77,88,78}, 6,1 , 13097,48 , 47,6 , 4,0 , 3865,17 , 3882,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Mexico + { 111, 7, 155, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 675,7 , 675,7 , 269,6 , 669,27 , 37,5 , 8,10 , 18988,60 , 18875,89 , 18964,24 , 18988,60 , 18875,89 , 18964,24 , 9959,35 , 9994,53 , 3080,14 , 9959,35 , 9994,53 , 4769,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {78,73,79}, 301,2 , 13145,69 , 4,4 , 4,0 , 3751,7 , 3888,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Nicaragua + { 111, 7, 166, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 675,7 , 675,7 , 1201,8 , 669,27 , 18,7 , 25,12 , 18988,60 , 18875,89 , 18964,24 , 18988,60 , 18875,89 , 18964,24 , 9959,35 , 9994,53 , 3080,14 , 9959,35 , 9994,53 , 4769,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {80,65,66}, 303,3 , 13214,54 , 4,4 , 4,0 , 3751,7 , 3897,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Panama + { 111, 7, 168, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 675,7 , 675,7 , 269,6 , 669,27 , 37,5 , 8,10 , 18814,61 , 18875,89 , 18964,24 , 18814,61 , 18875,89 , 18964,24 , 9959,35 , 9994,53 , 3080,14 , 9959,35 , 9994,53 , 4769,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {80,89,71}, 306,3 , 13268,61 , 8,5 , 23,6 , 3751,7 , 3903,8 , 0, 0, 7, 6, 7 }, // Spanish/Latin/Paraguay + { 111, 7, 169, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 675,7 , 675,7 , 571,7 , 669,27 , 37,5 , 8,10 , 19096,60 , 15922,88 , 18964,24 , 19156,60 , 19216,88 , 18964,24 , 9959,35 , 9994,53 , 3080,14 , 9959,35 , 9994,53 , 4769,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {80,69,78}, 279,2 , 13329,43 , 4,4 , 4,0 , 3751,7 , 3399,4 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Peru + { 111, 7, 170, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 675,7 , 675,7 , 269,6 , 669,27 , 18,7 , 25,12 , 18814,61 , 18875,89 , 18964,24 , 18814,61 , 18875,89 , 18964,24 , 9959,35 , 9994,53 , 8362,14 , 9959,35 , 9994,53 , 8362,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {80,72,80}, 179,1 , 13372,48 , 13,5 , 4,0 , 3751,7 , 3911,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Philippines + { 111, 7, 174, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 675,7 , 675,7 , 1201,8 , 669,27 , 18,7 , 25,12 , 18988,60 , 18875,89 , 18964,24 , 18988,60 , 18875,89 , 18964,24 , 9959,35 , 9994,53 , 3080,14 , 9959,35 , 9994,53 , 4769,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 12845,70 , 4,4 , 4,0 , 3751,7 , 1437,11 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Puerto Rico + { 111, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 675,7 , 675,7 , 415,8 , 669,27 , 18,7 , 25,12 , 18988,60 , 18875,89 , 18964,24 , 18988,60 , 18875,89 , 18964,24 , 9959,35 , 9994,53 , 3080,14 , 9959,35 , 9994,53 , 3080,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {85,83,68}, 6,1 , 12845,70 , 95,7 , 4,0 , 3751,7 , 3920,14 , 2, 1, 7, 6, 7 }, // Spanish/Latin/United States + { 111, 7, 227, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 675,7 , 675,7 , 269,6 , 669,27 , 37,5 , 8,10 , 19096,60 , 15922,88 , 18964,24 , 19156,60 , 19216,88 , 18964,24 , 9959,35 , 9994,53 , 3080,14 , 9959,35 , 9994,53 , 4769,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {85,89,85}, 6,1 , 13420,48 , 8,5 , 4,0 , 3751,7 , 3934,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Uruguay + { 111, 7, 231, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 675,7 , 675,7 , 269,6 , 669,27 , 18,7 , 25,12 , 18814,61 , 18875,89 , 18964,24 , 18814,61 , 18875,89 , 18964,24 , 9959,35 , 9994,53 , 3080,14 , 9959,35 , 9994,53 , 4769,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {86,69,83}, 309,4 , 13468,58 , 4,4 , 36,5 , 3751,7 , 3941,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Venezuela + { 111, 7, 238, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 675,7 , 675,7 , 269,6 , 669,27 , 55,4 , 430,11 , 18814,61 , 18875,89 , 18964,24 , 18814,61 , 18875,89 , 18964,24 , 9959,35 , 9994,53 , 8362,14 , 9959,35 , 9994,53 , 8362,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 3751,7 , 3950,8 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Canary Islands + { 111, 7, 246, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 675,7 , 675,7 , 269,6 , 669,27 , 37,5 , 8,10 , 18988,60 , 18875,89 , 18964,24 , 18988,60 , 18875,89 , 18964,24 , 9959,35 , 9994,53 , 3080,14 , 9959,35 , 9994,53 , 4769,14 , 64,4 , 61,4 , 0,5 , 5,17 , 22,23 , {0,0,0}, 0,0 , 2586,0 , 4,4 , 4,0 , 3958,23 , 3981,13 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Latin America + { 111, 7, 250, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 675,7 , 675,7 , 269,6 , 669,27 , 55,4 , 430,11 , 18814,61 , 18875,89 , 18964,24 , 18814,61 , 18875,89 , 18964,24 , 9959,35 , 9994,53 , 8362,14 , 9959,35 , 9994,53 , 8362,14 , 53,5 , 50,5 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 3751,7 , 3994,15 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Ceuta And Melilla + { 113, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 682,8 , 682,8 , 119,10 , 10,17 , 37,5 , 8,10 , 19304,48 , 19352,84 , 134,24 , 19304,48 , 19352,84 , 134,24 , 10047,60 , 10047,60 , 85,14 , 10047,60 , 10047,60 , 85,14 , 0,2 , 0,2 , 644,5 , 928,51 , 22,23 , {84,90,83}, 192,3 , 13526,67 , 8,5 , 4,0 , 4009,9 , 1616,8 , 2, 0, 1, 6, 7 }, // Swahili/Latin/Tanzania + { 113, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 682,8 , 682,8 , 119,10 , 10,17 , 37,5 , 8,10 , 19304,48 , 19352,84 , 134,24 , 19304,48 , 19352,84 , 134,24 , 10047,60 , 10047,60 , 85,14 , 10047,60 , 10047,60 , 85,14 , 0,2 , 0,2 , 644,5 , 928,51 , 22,23 , {67,68,70}, 207,2 , 13593,55 , 8,5 , 4,0 , 4009,9 , 4018,32 , 2, 1, 1, 6, 7 }, // Swahili/Latin/Congo Kinshasa + { 113, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 682,8 , 682,8 , 119,10 , 10,17 , 37,5 , 8,10 , 19304,48 , 19352,84 , 134,24 , 19304,48 , 19352,84 , 134,24 , 10047,60 , 10047,60 , 85,14 , 10047,60 , 10047,60 , 85,14 , 0,2 , 0,2 , 644,5 , 928,51 , 22,23 , {75,69,83}, 2,3 , 13648,58 , 8,5 , 4,0 , 4009,9 , 1182,5 , 2, 1, 7, 6, 7 }, // Swahili/Latin/Kenya + { 113, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 682,8 , 682,8 , 119,10 , 10,17 , 37,5 , 8,10 , 19304,48 , 19352,84 , 134,24 , 19304,48 , 19352,84 , 134,24 , 10047,60 , 10047,60 , 85,14 , 10047,60 , 10047,60 , 85,14 , 0,2 , 0,2 , 644,5 , 928,51 , 22,23 , {85,71,88}, 197,3 , 13706,61 , 8,5 , 4,0 , 4009,9 , 1681,6 , 0, 0, 1, 6, 7 }, // Swahili/Latin/Uganda + { 114, 7, 205, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 690,9 , 690,9 , 53,10 , 97,16 , 37,5 , 441,16 , 19436,59 , 19495,86 , 134,24 , 19436,59 , 19495,86 , 134,24 , 10107,29 , 10136,50 , 2293,14 , 10107,29 , 10136,50 , 2293,14 , 302,2 , 271,2 , 45,4 , 5,17 , 22,23 , {83,69,75}, 190,2 , 13767,45 , 13,5 , 4,0 , 4050,7 , 4057,7 , 2, 0, 1, 6, 7 }, // Swedish/Latin/Sweden + { 114, 7, 73, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 690,9 , 690,9 , 528,10 , 97,16 , 37,5 , 441,16 , 19436,59 , 19495,86 , 134,24 , 19436,59 , 19495,86 , 134,24 , 10107,29 , 10136,50 , 2293,14 , 10107,29 , 10136,50 , 2293,14 , 302,2 , 271,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8897,19 , 13,5 , 4,0 , 4050,7 , 1079,7 , 2, 1, 1, 6, 7 }, // Swedish/Latin/Finland + { 114, 7, 248, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 690,9 , 690,9 , 53,10 , 97,16 , 37,5 , 441,16 , 19436,59 , 19495,86 , 134,24 , 19436,59 , 19495,86 , 134,24 , 10107,29 , 10136,50 , 2293,14 , 10107,29 , 10136,50 , 2293,14 , 302,2 , 271,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8897,19 , 13,5 , 4,0 , 4050,7 , 4064,5 , 2, 1, 1, 6, 7 }, // Swedish/Latin/Aland Islands + { 115, 7, 106, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Sardinian/Latin/Italy + { 116, 2, 209, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 553,18 , 37,5 , 8,10 , 10930,48 , 19581,71 , 11058,24 , 10930,48 , 19581,71 , 11058,24 , 10186,28 , 10214,55 , 10269,14 , 10186,28 , 10214,55 , 10269,14 , 304,7 , 273,7 , 45,4 , 5,17 , 22,23 , {84,74,83}, 313,4 , 13812,19 , 13,5 , 4,0 , 4069,6 , 4075,10 , 2, 1, 1, 6, 7 }, // Tajik/Cyrillic/Tajikistan + { 117, 27, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 699,13 , 699,13 , 269,6 , 192,18 , 382,7 , 457,12 , 19652,58 , 19710,86 , 19796,31 , 19652,58 , 19710,86 , 19796,31 , 10283,39 , 10322,49 , 10371,20 , 10283,39 , 10322,49 , 10371,20 , 311,8 , 280,8 , 979,7 , 5,17 , 22,23 , {73,78,82}, 121,1 , 13831,49 , 8,5 , 4,0 , 4085,5 , 4090,7 , 2, 1, 7, 7, 7 }, // Tamil/Tamil/India + { 117, 27, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 699,13 , 699,13 , 269,6 , 192,18 , 382,7 , 457,12 , 19652,58 , 19710,86 , 19796,31 , 19652,58 , 19710,86 , 19796,31 , 10283,39 , 10322,49 , 10371,20 , 10283,39 , 10322,49 , 10371,20 , 311,8 , 280,8 , 979,7 , 5,17 , 22,23 , {77,89,82}, 174,2 , 13880,61 , 8,5 , 4,0 , 4085,5 , 4097,7 , 2, 1, 1, 6, 7 }, // Tamil/Tamil/Malaysia + { 117, 27, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 699,13 , 699,13 , 269,6 , 192,18 , 382,7 , 457,12 , 19652,58 , 19710,86 , 19796,31 , 19652,58 , 19710,86 , 19796,31 , 10283,39 , 10322,49 , 10371,20 , 10283,39 , 10322,49 , 10371,20 , 311,8 , 280,8 , 979,7 , 5,17 , 22,23 , {83,71,68}, 6,1 , 13941,61 , 8,5 , 4,0 , 4085,5 , 4104,11 , 2, 1, 7, 6, 7 }, // Tamil/Tamil/Singapore + { 117, 27, 198, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 699,13 , 699,13 , 269,6 , 192,18 , 37,5 , 8,10 , 19652,58 , 19710,86 , 19796,31 , 19652,58 , 19710,86 , 19796,31 , 10283,39 , 10322,49 , 10371,20 , 10283,39 , 10322,49 , 10371,20 , 311,8 , 280,8 , 979,7 , 5,17 , 22,23 , {76,75,82}, 317,3 , 14002,49 , 8,5 , 4,0 , 4085,5 , 4115,6 , 2, 1, 1, 6, 7 }, // Tamil/Tamil/Sri Lanka + { 118, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 712,9 , 712,9 , 495,10 , 1209,23 , 55,4 , 59,9 , 19827,62 , 19889,81 , 158,27 , 19827,62 , 19889,81 , 158,27 , 10391,36 , 10427,56 , 10483,14 , 10391,36 , 10427,56 , 10483,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {82,85,66}, 123,1 , 14051,21 , 0,4 , 4,0 , 4121,5 , 3469,6 , 2, 1, 1, 6, 7 }, // Tatar/Cyrillic/Russia + { 119, 28, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 721,11 , 721,11 , 339,8 , 1232,18 , 18,7 , 25,12 , 19970,62 , 20032,86 , 20118,31 , 19970,62 , 20032,86 , 20118,31 , 10497,32 , 10529,60 , 10589,18 , 10497,32 , 10529,60 , 10589,18 , 0,2 , 0,2 , 986,7 , 993,29 , 22,23 , {73,78,82}, 121,1 , 14072,26 , 4,4 , 4,0 , 4126,6 , 4132,8 , 2, 1, 7, 7, 7 }, // Telugu/Telugu/India + { 120, 30, 211, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 123,5 , 123,5 , 732,8 , 740,7 , 269,6 , 1250,19 , 37,5 , 469,28 , 20149,63 , 20212,98 , 20149,63 , 20149,63 , 20212,98 , 20149,63 , 10607,23 , 10630,68 , 10698,16 , 10607,23 , 10630,68 , 10698,16 , 319,10 , 288,10 , 1022,4 , 5,17 , 22,23 , {84,72,66}, 320,1 , 14098,16 , 4,4 , 4,0 , 4140,3 , 4140,3 , 2, 1, 7, 6, 7 }, // Thai/Thai/Thailand + { 121, 31, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 1269,23 , 18,7 , 25,12 , 2675,63 , 20310,159 , 158,27 , 2675,63 , 20469,147 , 158,27 , 10714,51 , 10765,79 , 10844,27 , 10714,51 , 10765,79 , 10844,27 , 329,7 , 298,8 , 45,4 , 5,17 , 22,23 , {67,78,89}, 321,1 , 14114,13 , 8,5 , 4,0 , 4143,8 , 4151,6 , 2, 1, 7, 6, 7 }, // Tibetan/Tibetan/China + { 121, 31, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 1269,23 , 18,7 , 25,12 , 2675,63 , 20310,159 , 158,27 , 2675,63 , 20469,147 , 158,27 , 10714,51 , 10765,79 , 10844,27 , 10714,51 , 10765,79 , 10844,27 , 329,7 , 298,8 , 45,4 , 5,17 , 22,23 , {73,78,82}, 121,1 , 14127,19 , 8,5 , 4,0 , 4143,8 , 4157,7 , 2, 1, 7, 7, 7 }, // Tibetan/Tibetan/India + { 122, 14, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1292,23 , 18,7 , 25,12 , 20616,36 , 20652,54 , 20706,24 , 20616,36 , 20652,54 , 20706,24 , 10871,21 , 10892,29 , 10921,14 , 10871,21 , 10892,29 , 10935,14 , 336,7 , 306,7 , 45,4 , 5,17 , 22,23 , {69,84,66}, 0,2 , 14146,16 , 4,4 , 4,0 , 4164,4 , 82,5 , 2, 1, 7, 6, 7 }, // Tigrinya/Ethiopic/Ethiopia + { 122, 14, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1292,23 , 18,7 , 25,12 , 20616,36 , 20652,54 , 20706,24 , 20616,36 , 20652,54 , 20706,24 , 10871,21 , 10892,29 , 10935,14 , 10871,21 , 10892,29 , 10935,14 , 336,7 , 306,7 , 45,4 , 5,17 , 22,23 , {69,82,78}, 41,3 , 0,7 , 4,4 , 4,0 , 4164,4 , 4168,4 , 2, 1, 1, 6, 7 }, // Tigrinya/Ethiopic/Eritrea + { 123, 7, 214, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 747,8 , 747,8 , 747,8 , 747,8 , 269,6 , 97,16 , 18,7 , 25,12 , 20730,51 , 20781,87 , 20868,24 , 20730,51 , 20781,87 , 20868,24 , 10949,29 , 10978,60 , 11038,14 , 10949,29 , 10978,60 , 11038,14 , 343,10 , 313,6 , 1026,5 , 1031,59 , 1090,65 , {84,79,80}, 195,2 , 14162,41 , 13,5 , 4,0 , 4172,13 , 1631,5 , 2, 1, 1, 6, 7 }, // Tongan/Latin/Tonga { 124, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {90,65,82}, 5,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Tsonga/Latin/South Africa - { 125, 7, 217, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 705,8 , 705,8 , 1297,9 , 1306,16 , 37,5 , 8,10 , 20051,48 , 20099,75 , 20174,24 , 20051,48 , 20099,75 , 20174,24 , 10801,28 , 10829,54 , 10883,14 , 10801,28 , 10829,54 , 10883,14 , 350,2 , 315,2 , 193,4 , 5,17 , 22,23 , {84,82,89}, 244,1 , 14103,40 , 4,4 , 4,0 , 4146,6 , 4152,7 , 2, 1, 1, 6, 7 }, // Turkish/Latin/Turkey - { 125, 7, 56, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 705,8 , 705,8 , 1297,9 , 1306,16 , 18,7 , 25,12 , 20051,48 , 20099,75 , 20174,24 , 20051,48 , 20099,75 , 20174,24 , 10801,28 , 10829,54 , 10883,14 , 10801,28 , 10829,54 , 10883,14 , 350,2 , 315,2 , 193,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8384,19 , 4,4 , 4,0 , 4146,6 , 4159,6 , 2, 1, 1, 6, 7 }, // Turkish/Latin/Cyprus - { 126, 7, 218, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8220, 8221, 0,6 , 0,6 , 713,8 , 713,8 , 981,10 , 1306,16 , 37,5 , 8,10 , 20198,51 , 20249,77 , 20326,24 , 20350,51 , 20401,77 , 20326,24 , 10897,28 , 10925,54 , 10979,14 , 10993,28 , 11021,54 , 10979,14 , 352,13 , 317,14 , 1032,4 , 5,17 , 22,23 , {84,77,84}, 322,3 , 14143,49 , 13,5 , 4,0 , 4165,12 , 4177,12 , 2, 1, 1, 6, 7 }, // Turkmen/Latin/Turkmenistan - { 128, 1, 44, 46, 44, 59, 37, 48, 45, 43, 101, 187, 171, 8250, 8249, 0,6 , 0,6 , 200,10 , 210,9 , 53,10 , 1322,17 , 18,7 , 25,12 , 20478,84 , 20478,84 , 158,27 , 20478,84 , 20478,84 , 158,27 , 11075,21 , 11096,55 , 11151,14 , 11075,21 , 11096,55 , 11151,14 , 365,12 , 331,12 , 45,4 , 5,17 , 22,23 , {67,78,89}, 129,1 , 14192,40 , 4,4 , 4,0 , 4189,8 , 4197,5 , 2, 1, 7, 6, 7 }, // Uighur/Arabic/China - { 129, 2, 222, 44, 160, 59, 37, 48, 45, 43, 1077, 171, 187, 8222, 8220, 0,6 , 0,6 , 138,7 , 138,7 , 174,8 , 1339,22 , 37,5 , 8,10 , 20562,48 , 20610,95 , 20705,24 , 20729,67 , 20796,87 , 20883,24 , 1583,21 , 11165,56 , 11221,14 , 1583,21 , 11165,56 , 11221,14 , 377,2 , 343,2 , 1036,5 , 571,17 , 22,23 , {85,65,72}, 286,1 , 14232,49 , 13,5 , 4,0 , 4202,10 , 4212,7 , 2, 1, 1, 6, 7 }, // Ukrainian/Cyrillic/Ukraine - { 130, 1, 163, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 721,10 , 731,9 , 287,6 , 1361,18 , 18,7 , 25,12 , 20907,68 , 20907,68 , 134,24 , 20907,68 , 20907,68 , 134,24 , 11235,36 , 11235,36 , 85,14 , 11235,36 , 11235,36 , 85,14 , 0,2 , 0,2 , 1041,4 , 5,17 , 22,23 , {80,75,82}, 172,2 , 14281,49 , 4,4 , 4,0 , 4219,4 , 3330,7 , 0, 0, 7, 6, 7 }, // Urdu/Arabic/Pakistan - { 130, 1, 100, 1643, 1644, 59, 37, 1776, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 740,6 , 740,6 , 287,6 , 1361,18 , 18,7 , 25,12 , 20907,68 , 20907,68 , 134,24 , 20907,68 , 20907,68 , 134,24 , 11235,36 , 11235,36 , 85,14 , 11235,36 , 11235,36 , 85,14 , 0,2 , 0,2 , 1041,4 , 5,17 , 22,23 , {73,78,82}, 117,1 , 14330,42 , 8,5 , 4,0 , 4219,4 , 4223,5 , 2, 1, 7, 7, 7 }, // Urdu/Arabic/India - { 131, 7, 228, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8217, 8216, 0,6 , 0,6 , 746,8 , 746,8 , 27,8 , 1379,18 , 37,5 , 426,11 , 20975,48 , 21023,75 , 21098,24 , 21122,48 , 21170,75 , 21098,24 , 11271,32 , 11303,61 , 11364,14 , 11271,32 , 11303,61 , 11364,14 , 379,2 , 345,2 , 193,4 , 340,17 , 22,23 , {85,90,83}, 325,4 , 14372,58 , 13,5 , 4,0 , 4228,6 , 4234,11 , 0, 0, 1, 6, 7 }, // Uzbek/Latin/Uzbekistan - { 131, 1, 1, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 412,8 , 1397,33 , 55,4 , 426,11 , 21245,47 , 14525,68 , 158,27 , 21245,47 , 14525,68 , 158,27 , 11378,21 , 7511,49 , 85,14 , 11378,21 , 7511,49 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {65,70,78}, 262,1 , 14430,13 , 13,5 , 4,0 , 4245,6 , 3122,9 , 0, 0, 6, 4, 5 }, // Uzbek/Arabic/Afghanistan - { 131, 2, 228, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 667,19 , 37,5 , 87,12 , 11024,48 , 18740,71 , 11152,24 , 21292,48 , 21340,71 , 11152,24 , 11399,28 , 11427,53 , 11480,14 , 11494,28 , 11522,53 , 11480,14 , 381,2 , 347,2 , 45,4 , 5,17 , 22,23 , {85,90,83}, 329,3 , 14443,49 , 13,5 , 4,0 , 4251,7 , 4258,10 , 0, 0, 1, 6, 7 }, // Uzbek/Cyrillic/Uzbekistan - { 132, 7, 232, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 754,8 , 754,8 , 120,10 , 210,18 , 37,5 , 8,10 , 21411,75 , 21486,99 , 158,27 , 21585,75 , 21660,99 , 158,27 , 11575,33 , 11608,55 , 11663,21 , 11575,33 , 11608,55 , 11663,21 , 383,2 , 349,2 , 45,4 , 5,17 , 22,23 , {86,78,68}, 332,1 , 14492,33 , 13,5 , 4,0 , 4268,10 , 4278,8 , 0, 0, 1, 6, 7 }, // Vietnamese/Latin/Vietnam - { 133, 7, 260, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 1430,23 , 37,5 , 8,10 , 21759,48 , 21807,74 , 21881,24 , 21905,48 , 21807,74 , 21881,24 , 11684,21 , 11705,43 , 11748,14 , 11762,28 , 11705,43 , 11748,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {0,0,0}, 0,0 , 2586,0 , 8,5 , 4,0 , 4286,7 , 0,0 , 2, 1, 1, 6, 7 }, // Volapuk/Latin/World - { 134, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 762,11 , 773,10 , 27,8 , 10,17 , 37,5 , 8,10 , 21953,52 , 22005,87 , 22092,26 , 22118,59 , 22005,87 , 22092,26 , 11790,29 , 11819,77 , 11896,15 , 11911,30 , 11819,77 , 11896,15 , 385,2 , 351,2 , 1045,7 , 5,17 , 22,23 , {71,66,80}, 115,1 , 14525,92 , 4,4 , 4,0 , 4293,7 , 4300,16 , 2, 1, 1, 6, 7 }, // Welsh/Latin/United Kingdom - { 135, 7, 187, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 1181,10 , 1453,17 , 37,5 , 8,10 , 22177,47 , 22224,84 , 158,27 , 22177,47 , 22224,84 , 158,27 , 11941,28 , 11969,50 , 11941,28 , 11941,28 , 11969,50 , 11941,28 , 387,3 , 353,3 , 45,4 , 5,17 , 22,23 , {88,79,70}, 200,3 , 14617,65 , 8,5 , 4,0 , 4316,5 , 4321,8 , 0, 0, 1, 6, 7 }, // Wolof/Latin/Senegal - { 136, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {90,65,82}, 5,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Xhosa/Latin/South Africa - { 137, 18, 260, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 783,9 , 783,9 , 27,8 , 1470,19 , 37,5 , 8,10 , 22308,58 , 22366,92 , 158,27 , 22366,92 , 22366,92 , 158,27 , 12019,54 , 12019,54 , 85,14 , 12019,54 , 12019,54 , 85,14 , 390,11 , 356,10 , 45,4 , 5,17 , 22,23 , {0,0,0}, 0,0 , 2586,0 , 41,6 , 4,0 , 4329,6 , 4335,5 , 2, 1, 1, 6, 7 }, // Yiddish/Hebrew/World - { 138, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 22458,73 , 22531,121 , 158,27 , 22458,73 , 22531,121 , 158,27 , 12073,44 , 12117,69 , 85,14 , 12073,44 , 12117,69 , 85,14 , 401,5 , 366,5 , 45,4 , 5,17 , 22,23 , {78,71,78}, 174,1 , 14682,34 , 4,4 , 4,0 , 4340,10 , 4350,18 , 2, 1, 1, 6, 7 }, // Yoruba/Latin/Nigeria - { 138, 7, 23, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 22652,74 , 22726,134 , 158,27 , 22652,74 , 22726,134 , 158,27 , 12186,44 , 12230,69 , 85,14 , 12186,44 , 12230,69 , 85,14 , 406,5 , 371,5 , 45,4 , 5,17 , 22,23 , {88,79,70}, 200,3 , 14716,34 , 4,4 , 4,0 , 4340,10 , 4368,16 , 0, 0, 1, 6, 7 }, // Yoruba/Latin/Benin - { 140, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 792,9 , 801,8 , 543,6 , 35,18 , 37,5 , 8,10 , 22860,48 , 22908,91 , 134,24 , 22860,48 , 22908,91 , 22999,24 , 12299,28 , 12327,74 , 12401,14 , 12299,28 , 12327,74 , 12401,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {90,65,82}, 5,1 , 14750,67 , 4,4 , 4,0 , 4384,7 , 4391,17 , 2, 1, 7, 6, 7 }, // Zulu/Latin/South Africa - { 141, 7, 161, 44, 160, 59, 37, 48, 8722, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 192,8 , 192,8 , 981,10 , 496,17 , 37,5 , 437,16 , 5904,48 , 13926,83 , 134,24 , 23023,59 , 13926,83 , 134,24 , 12415,28 , 12443,51 , 2363,14 , 12494,28 , 12443,51 , 2363,14 , 411,9 , 376,11 , 45,4 , 5,17 , 22,23 , {78,79,75}, 186,2 , 9799,44 , 13,5 , 4,0 , 4408,7 , 4415,5 , 2, 0, 1, 6, 7 }, // Norwegian Nynorsk/Latin/Norway - { 142, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8221, 8216, 8217, 0,6 , 0,6 , 163,7 , 163,7 , 1039,7 , 468,19 , 37,5 , 8,10 , 16459,48 , 23082,83 , 16435,24 , 16459,48 , 23082,83 , 16435,24 , 2086,28 , 2114,58 , 2172,14 , 2086,28 , 2114,58 , 2186,14 , 420,10 , 387,7 , 313,7 , 5,17 , 22,23 , {66,65,77}, 140,2 , 14817,170 , 13,5 , 4,0 , 4420,8 , 620,19 , 2, 1, 1, 6, 7 }, // Bosnian/Latin/Bosnia And Herzegowina - { 142, 2, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 116,7 , 116,7 , 1039,7 , 1046,20 , 37,5 , 8,10 , 23165,48 , 23213,83 , 12531,24 , 23165,48 , 23213,83 , 12531,24 , 12522,28 , 12550,56 , 8617,14 , 12522,28 , 12550,56 , 8617,14 , 225,9 , 394,7 , 45,4 , 5,17 , 22,23 , {66,65,77}, 290,2 , 14987,151 , 13,5 , 4,0 , 4428,8 , 3512,19 , 2, 1, 1, 6, 7 }, // Bosnian/Cyrillic/Bosnia And Herzegowina + { 125, 7, 217, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 755,8 , 755,8 , 1315,9 , 1324,16 , 37,5 , 8,10 , 20892,48 , 20940,75 , 21015,24 , 20892,48 , 20940,75 , 21015,24 , 11052,28 , 11080,54 , 11134,14 , 11052,28 , 11080,54 , 11134,14 , 353,2 , 319,2 , 199,4 , 5,17 , 22,23 , {84,82,89}, 248,1 , 14203,40 , 4,4 , 4,0 , 4185,6 , 4191,7 , 2, 1, 1, 6, 7 }, // Turkish/Latin/Turkey + { 125, 7, 56, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 755,8 , 755,8 , 1315,9 , 1324,16 , 18,7 , 25,12 , 20892,48 , 20940,75 , 21015,24 , 20892,48 , 20940,75 , 21015,24 , 11052,28 , 11080,54 , 11134,14 , 11052,28 , 11080,54 , 11134,14 , 353,2 , 319,2 , 199,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8384,19 , 4,4 , 4,0 , 4185,6 , 4198,6 , 2, 1, 1, 6, 7 }, // Turkish/Latin/Cyprus + { 126, 7, 218, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8220, 8221, 0,6 , 0,6 , 763,8 , 763,8 , 495,10 , 1324,16 , 37,5 , 8,10 , 21039,50 , 21089,77 , 21166,24 , 21190,51 , 21241,77 , 21166,24 , 11148,28 , 11176,54 , 11230,14 , 11244,28 , 11272,54 , 11230,14 , 355,13 , 321,14 , 1155,4 , 5,17 , 22,23 , {84,77,84}, 322,3 , 14243,49 , 13,5 , 4,0 , 4204,12 , 4216,12 , 2, 1, 1, 6, 7 }, // Turkmen/Latin/Turkmenistan + { 128, 1, 44, 46, 44, 59, 37, 48, 45, 43, 101, 187, 171, 8250, 8249, 0,6 , 0,6 , 200,10 , 210,9 , 53,10 , 1340,17 , 18,7 , 25,12 , 21318,84 , 21318,84 , 158,27 , 21318,84 , 21318,84 , 158,27 , 11326,21 , 11347,55 , 11402,14 , 11326,21 , 11347,55 , 11402,14 , 368,12 , 335,12 , 45,4 , 5,17 , 22,23 , {67,78,89}, 133,1 , 14292,40 , 4,4 , 4,0 , 4228,8 , 4236,5 , 2, 1, 7, 6, 7 }, // Uighur/Arabic/China + { 129, 2, 222, 44, 160, 59, 37, 48, 45, 43, 1077, 171, 187, 8222, 8220, 0,6 , 0,6 , 138,7 , 138,7 , 156,8 , 1357,22 , 37,5 , 8,10 , 21402,48 , 21450,95 , 21545,24 , 21569,67 , 21636,87 , 21723,24 , 1427,21 , 11416,56 , 11472,14 , 1427,21 , 11416,56 , 11472,14 , 380,2 , 347,2 , 1159,5 , 701,17 , 22,23 , {85,65,72}, 287,1 , 14332,49 , 13,5 , 4,0 , 4241,10 , 4251,7 , 2, 1, 1, 6, 7 }, // Ukrainian/Cyrillic/Ukraine + { 130, 1, 163, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 771,10 , 781,9 , 269,6 , 1379,18 , 18,7 , 25,12 , 21747,68 , 21747,68 , 134,24 , 21747,68 , 21747,68 , 134,24 , 11486,36 , 11486,36 , 85,14 , 11486,36 , 11486,36 , 85,14 , 0,2 , 0,2 , 1164,4 , 1168,20 , 22,23 , {80,75,82}, 176,2 , 14381,49 , 4,4 , 4,0 , 4258,4 , 3384,7 , 2, 0, 7, 6, 7 }, // Urdu/Arabic/Pakistan + { 130, 1, 100, 1643, 1644, 59, 37, 1776, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 790,6 , 790,6 , 269,6 , 1379,18 , 18,7 , 25,12 , 21747,68 , 21747,68 , 134,24 , 21747,68 , 21747,68 , 134,24 , 11486,36 , 11486,36 , 85,14 , 11486,36 , 11486,36 , 85,14 , 0,2 , 0,2 , 1164,4 , 1168,20 , 22,23 , {73,78,82}, 121,1 , 14430,42 , 8,5 , 4,0 , 4258,4 , 4262,5 , 2, 1, 7, 7, 7 }, // Urdu/Arabic/India + { 131, 7, 228, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8217, 8216, 0,6 , 0,6 , 796,8 , 796,8 , 27,8 , 1397,18 , 37,5 , 430,11 , 21815,48 , 21863,75 , 21938,24 , 21962,48 , 22010,75 , 21938,24 , 11522,32 , 11554,61 , 11615,14 , 11522,32 , 11554,61 , 11615,14 , 382,2 , 349,2 , 199,4 , 323,17 , 22,23 , {85,90,83}, 325,4 , 14472,58 , 13,5 , 4,0 , 4267,6 , 4273,11 , 2, 0, 1, 6, 7 }, // Uzbek/Latin/Uzbekistan + { 131, 1, 1, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 394,8 , 1415,33 , 55,4 , 430,11 , 22085,47 , 15102,68 , 158,27 , 22085,47 , 15102,68 , 158,27 , 11629,21 , 7774,49 , 85,14 , 11629,21 , 7774,49 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {65,70,78}, 263,1 , 14530,13 , 13,5 , 4,0 , 4284,6 , 3176,9 , 0, 0, 6, 4, 5 }, // Uzbek/Arabic/Afghanistan + { 131, 2, 228, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 696,19 , 37,5 , 87,12 , 22132,48 , 22180,71 , 11058,24 , 22132,48 , 22180,71 , 11058,24 , 11650,28 , 11678,53 , 11731,14 , 11650,28 , 11678,53 , 11731,14 , 384,2 , 351,2 , 45,4 , 5,17 , 22,23 , {85,90,83}, 329,3 , 14543,49 , 13,5 , 4,0 , 4290,7 , 4297,10 , 2, 0, 1, 6, 7 }, // Uzbek/Cyrillic/Uzbekistan + { 132, 7, 232, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 804,8 , 804,8 , 119,10 , 192,18 , 37,5 , 8,10 , 22251,75 , 22326,99 , 158,27 , 22425,75 , 22500,99 , 158,27 , 11745,33 , 11778,55 , 11833,21 , 11745,33 , 11778,55 , 11833,21 , 386,2 , 353,2 , 45,4 , 5,17 , 22,23 , {86,78,68}, 332,1 , 14592,33 , 13,5 , 4,0 , 4307,10 , 4317,8 , 0, 0, 1, 6, 7 }, // Vietnamese/Latin/Vietnam + { 133, 7, 260, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 1448,23 , 37,5 , 8,10 , 22599,48 , 22647,74 , 22721,24 , 22745,48 , 22647,74 , 22721,24 , 11854,21 , 11875,43 , 11918,14 , 11932,28 , 11875,43 , 11918,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {0,0,0}, 0,0 , 2586,0 , 8,5 , 4,0 , 4325,7 , 0,0 , 2, 1, 1, 6, 7 }, // Volapuk/Latin/World + { 134, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 812,11 , 823,10 , 27,8 , 10,17 , 37,5 , 8,10 , 22793,52 , 22845,87 , 22932,26 , 22958,59 , 22845,87 , 22932,26 , 11960,29 , 11989,77 , 12066,15 , 12081,30 , 11989,77 , 12066,15 , 388,2 , 355,2 , 1188,7 , 5,17 , 22,23 , {71,66,80}, 119,1 , 14625,92 , 4,4 , 4,0 , 4332,7 , 4339,16 , 2, 1, 1, 6, 7 }, // Welsh/Latin/United Kingdom + { 135, 7, 187, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 528,10 , 1471,17 , 37,5 , 8,10 , 23017,47 , 23064,84 , 158,27 , 23017,47 , 23064,84 , 158,27 , 12111,28 , 12139,50 , 12111,28 , 12111,28 , 12139,50 , 12111,28 , 390,3 , 357,3 , 45,4 , 5,17 , 22,23 , {88,79,70}, 204,3 , 14717,65 , 8,5 , 4,0 , 4355,5 , 4360,8 , 0, 0, 1, 6, 7 }, // Wolof/Latin/Senegal + { 136, 7, 195, 46, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 23148,48 , 23196,91 , 158,27 , 23148,48 , 23196,91 , 158,27 , 12189,28 , 12217,61 , 85,14 , 12189,28 , 12217,61 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {90,65,82}, 5,1 , 14782,79 , 4,4 , 4,0 , 4368,8 , 4376,15 , 2, 1, 7, 6, 7 }, // Xhosa/Latin/South Africa + { 137, 18, 260, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 833,9 , 833,9 , 27,8 , 1488,19 , 37,5 , 8,10 , 23287,58 , 23345,92 , 158,27 , 23345,92 , 23345,92 , 158,27 , 12278,54 , 12278,54 , 85,14 , 12278,54 , 12278,54 , 85,14 , 393,11 , 360,10 , 45,4 , 5,17 , 22,23 , {0,0,0}, 0,0 , 2586,0 , 41,6 , 4,0 , 4391,6 , 4397,5 , 2, 1, 1, 6, 7 }, // Yiddish/Hebrew/World + { 138, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 23437,73 , 23510,121 , 158,27 , 23437,73 , 23510,121 , 158,27 , 12332,44 , 12376,69 , 85,14 , 12332,44 , 12376,69 , 85,14 , 404,5 , 370,5 , 45,4 , 5,17 , 22,23 , {78,71,78}, 178,1 , 14861,34 , 4,4 , 4,0 , 4402,10 , 4412,18 , 2, 1, 1, 6, 7 }, // Yoruba/Latin/Nigeria + { 138, 7, 23, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 23631,74 , 23705,134 , 158,27 , 23631,74 , 23705,134 , 158,27 , 12445,44 , 12489,69 , 85,14 , 12445,44 , 12489,69 , 85,14 , 409,5 , 375,5 , 45,4 , 5,17 , 22,23 , {88,79,70}, 204,3 , 14895,34 , 4,4 , 4,0 , 4402,10 , 4430,16 , 0, 0, 1, 6, 7 }, // Yoruba/Latin/Benin + { 140, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 842,9 , 851,8 , 547,6 , 35,18 , 37,5 , 8,10 , 23839,48 , 23887,91 , 134,24 , 23839,48 , 23887,91 , 23978,24 , 12558,28 , 12586,74 , 12660,14 , 12558,28 , 12586,74 , 12660,14 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {90,65,82}, 5,1 , 14929,67 , 4,4 , 4,0 , 4446,7 , 4453,17 , 2, 1, 7, 6, 7 }, // Zulu/Latin/South Africa + { 141, 7, 161, 44, 160, 59, 37, 48, 8722, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 192,8 , 192,8 , 495,10 , 478,17 , 37,5 , 441,16 , 5656,48 , 14503,83 , 134,24 , 24002,59 , 14503,83 , 134,24 , 12674,28 , 12702,51 , 2293,14 , 12753,28 , 12702,51 , 2293,14 , 414,9 , 380,11 , 45,4 , 5,17 , 22,23 , {78,79,75}, 190,2 , 9840,44 , 13,5 , 4,0 , 4470,7 , 4477,5 , 2, 0, 1, 6, 7 }, // Norwegian Nynorsk/Latin/Norway + { 142, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8221, 8216, 8217, 0,6 , 0,6 , 163,7 , 163,7 , 1507,11 , 450,19 , 37,5 , 8,10 , 8336,48 , 24061,83 , 9742,24 , 8336,48 , 24061,83 , 9742,24 , 2016,28 , 2044,58 , 2102,14 , 2016,28 , 2044,58 , 2116,14 , 423,10 , 391,7 , 296,7 , 5,17 , 22,23 , {66,65,77}, 144,2 , 14996,170 , 13,5 , 4,0 , 4482,8 , 620,19 , 2, 1, 1, 6, 7 }, // Bosnian/Latin/Bosnia And Herzegowina + { 142, 2, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 116,7 , 116,7 , 1067,7 , 1074,20 , 37,5 , 8,10 , 24144,48 , 24192,83 , 12698,24 , 24144,48 , 24192,83 , 12698,24 , 12781,28 , 12809,56 , 8880,14 , 12781,28 , 12809,56 , 8880,14 , 228,9 , 398,7 , 45,4 , 5,17 , 22,23 , {66,65,77}, 291,2 , 15166,151 , 13,5 , 4,0 , 4490,8 , 3545,19 , 2, 1, 1, 6, 7 }, // Bosnian/Cyrillic/Bosnia And Herzegowina { 143, 29, 131, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {77,86,82}, 0,0 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 5, 6, 7 }, // Divehi/Thaana/Maldives - { 144, 7, 251, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 686,17 , 37,5 , 8,10 , 23296,102 , 23398,140 , 158,27 , 23296,102 , 23398,140 , 158,27 , 12606,30 , 12636,57 , 85,14 , 12606,30 , 12636,57 , 85,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {71,66,80}, 115,1 , 0,7 , 4,4 , 4,0 , 4436,5 , 4441,12 , 2, 1, 1, 6, 7 }, // Manx/Latin/Isle Of Man - { 145, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 98,16 , 37,5 , 8,10 , 23538,46 , 23584,130 , 158,27 , 23538,46 , 23584,130 , 158,27 , 12693,28 , 12721,61 , 85,14 , 12693,28 , 12721,61 , 85,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {71,66,80}, 115,1 , 0,7 , 4,4 , 4,0 , 4453,8 , 4461,14 , 2, 1, 1, 6, 7 }, // Cornish/Latin/United Kingdom - { 146, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 1489,8 , 1497,18 , 18,7 , 25,12 , 23714,48 , 23762,192 , 158,27 , 23714,48 , 23762,192 , 158,27 , 12782,28 , 12810,49 , 12859,14 , 12782,28 , 12810,49 , 12859,14 , 430,2 , 401,2 , 45,4 , 5,17 , 22,23 , {71,72,83}, 163,3 , 15138,17 , 4,4 , 4,0 , 4475,4 , 4479,5 , 2, 1, 1, 6, 7 }, // Akan/Latin/Ghana - { 147, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 1515,6 , 98,16 , 18,7 , 25,12 , 23954,88 , 23954,88 , 158,27 , 23954,88 , 23954,88 , 158,27 , 12873,49 , 12873,49 , 12922,20 , 12873,49 , 12873,49 , 12922,20 , 188,5 , 403,5 , 45,4 , 5,17 , 22,23 , {73,78,82}, 117,1 , 15155,13 , 8,5 , 4,0 , 4484,6 , 2633,4 , 2, 1, 7, 7, 7 }, // Konkani/Devanagari/India + { 144, 7, 251, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 80,17 , 37,5 , 8,10 , 24275,102 , 24377,140 , 158,27 , 24275,102 , 24377,140 , 158,27 , 12865,30 , 12895,57 , 85,14 , 12865,30 , 12895,57 , 85,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {71,66,80}, 119,1 , 0,7 , 4,4 , 4,0 , 4498,5 , 4503,12 , 2, 1, 1, 6, 7 }, // Manx/Latin/Isle Of Man + { 145, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 97,16 , 37,5 , 8,10 , 24517,46 , 24563,130 , 158,27 , 24517,46 , 24563,130 , 158,27 , 12952,28 , 12980,61 , 85,14 , 12952,28 , 12980,61 , 85,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {71,66,80}, 119,1 , 0,7 , 4,4 , 4,0 , 4515,8 , 4523,14 , 2, 1, 1, 6, 7 }, // Cornish/Latin/United Kingdom + { 146, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 1518,8 , 1526,18 , 18,7 , 25,12 , 24693,48 , 24741,192 , 158,27 , 24693,48 , 24741,192 , 158,27 , 13041,28 , 13069,49 , 13118,14 , 13041,28 , 13069,49 , 13118,14 , 433,2 , 405,2 , 45,4 , 5,17 , 22,23 , {71,72,83}, 167,3 , 15317,17 , 4,4 , 4,0 , 4537,4 , 4541,5 , 2, 1, 1, 6, 7 }, // Akan/Latin/Ghana + { 147, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 1544,6 , 97,16 , 18,7 , 25,12 , 24933,88 , 24933,88 , 158,27 , 24933,88 , 24933,88 , 158,27 , 13132,49 , 13132,49 , 13181,20 , 13132,49 , 13132,49 , 13181,20 , 190,5 , 407,5 , 45,4 , 5,17 , 22,23 , {73,78,82}, 121,1 , 15334,13 , 8,5 , 4,0 , 4546,6 , 2633,4 , 2, 1, 7, 7, 7 }, // Konkani/Devanagari/India { 148, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {71,72,83}, 0,0 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Ga/Latin/Ghana - { 149, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 24042,48 , 24090,86 , 158,27 , 24042,48 , 24090,86 , 158,27 , 12942,29 , 12971,57 , 85,14 , 12942,29 , 12971,57 , 85,14 , 40,4 , 408,4 , 45,4 , 5,17 , 22,23 , {78,71,78}, 174,1 , 15168,12 , 4,4 , 4,0 , 4490,4 , 4494,8 , 2, 1, 1, 6, 7 }, // Igbo/Latin/Nigeria - { 150, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 24176,48 , 24224,189 , 24413,24 , 24176,48 , 24224,189 , 24413,24 , 13028,28 , 13056,74 , 13130,14 , 13028,28 , 13056,74 , 13130,14 , 432,9 , 412,7 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15180,23 , 4,4 , 4,0 , 4502,7 , 1182,5 , 2, 1, 7, 6, 7 }, // Kamba/Latin/Kenya + { 149, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 25021,48 , 25069,86 , 158,27 , 25021,48 , 25069,86 , 158,27 , 13201,29 , 13230,57 , 85,14 , 13201,29 , 13230,57 , 85,14 , 38,4 , 412,4 , 45,4 , 5,17 , 22,23 , {78,71,78}, 178,1 , 15347,12 , 4,4 , 4,0 , 4552,4 , 4556,8 , 2, 1, 1, 6, 7 }, // Igbo/Latin/Nigeria + { 150, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 25155,48 , 25203,189 , 25392,24 , 25155,48 , 25203,189 , 25392,24 , 13287,28 , 13315,74 , 13389,14 , 13287,28 , 13315,74 , 13389,14 , 435,9 , 416,7 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15359,23 , 4,4 , 4,0 , 4564,7 , 1182,5 , 2, 1, 7, 6, 7 }, // Kamba/Latin/Kenya { 151, 33, 103, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,81,68}, 0,0 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 6, 5, 6 }, // Syriac/Syriac/Iraq { 152, 14, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,82,78}, 0,0 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Blin/Ethiopic/Eritrea { 153, 14, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,84,66}, 0,0 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Geez/Ethiopic/Ethiopia { 155, 7, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,84,66}, 0,0 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Sidamo/Latin/Ethiopia - { 156, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {78,71,78}, 174,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Atsam/Latin/Nigeria + { 156, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {78,71,78}, 178,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Atsam/Latin/Nigeria { 157, 14, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,82,78}, 0,0 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Tigre/Ethiopic/Eritrea - { 158, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {78,71,78}, 174,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Jju/Latin/Nigeria - { 159, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 1521,27 , 37,5 , 8,10 , 24437,48 , 24485,77 , 24562,24 , 24437,48 , 24485,77 , 24562,24 , 13144,28 , 13172,50 , 3150,14 , 13144,28 , 13172,50 , 3150,14 , 441,2 , 419,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 8,5 , 4,0 , 4509,6 , 4515,6 , 2, 1, 1, 6, 7 }, // Friulian/Latin/Italy + { 158, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {78,71,78}, 178,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Jju/Latin/Nigeria + { 159, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 254,7 , 254,7 , 27,8 , 1550,27 , 37,5 , 8,10 , 25416,48 , 25464,77 , 25541,24 , 25416,48 , 25464,77 , 25541,24 , 13403,28 , 13431,50 , 3080,14 , 13403,28 , 13431,50 , 3080,14 , 444,2 , 423,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 8,5 , 4,0 , 4571,6 , 4577,6 , 2, 1, 1, 6, 7 }, // Friulian/Latin/Italy { 160, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {90,65,82}, 5,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Venda/Latin/South Africa - { 161, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 809,11 , 820,10 , 543,6 , 1548,23 , 493,12 , 505,17 , 24586,48 , 24634,87 , 24721,24 , 24586,48 , 24634,87 , 24721,24 , 13222,28 , 13250,44 , 13294,14 , 13222,28 , 13250,44 , 13294,14 , 443,3 , 421,5 , 45,4 , 5,17 , 22,23 , {71,72,83}, 163,3 , 15203,37 , 4,4 , 4,0 , 4521,6 , 4527,12 , 2, 1, 1, 6, 7 }, // Ewe/Latin/Ghana - { 161, 7, 212, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 809,11 , 820,10 , 543,6 , 1548,23 , 37,5 , 8,10 , 24586,48 , 24634,87 , 24721,24 , 24586,48 , 24634,87 , 24721,24 , 13222,28 , 13250,44 , 13294,14 , 13222,28 , 13250,44 , 13294,14 , 443,3 , 421,5 , 45,4 , 5,17 , 22,23 , {88,79,70}, 200,3 , 15240,106 , 4,4 , 4,0 , 4521,6 , 4539,11 , 0, 0, 1, 6, 7 }, // Ewe/Latin/Togo + { 161, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 859,11 , 870,10 , 547,6 , 1577,23 , 497,12 , 509,17 , 25565,48 , 25613,87 , 25700,24 , 25565,48 , 25613,87 , 25700,24 , 13481,28 , 13509,44 , 13553,14 , 13481,28 , 13509,44 , 13553,14 , 446,3 , 425,5 , 45,4 , 5,17 , 22,23 , {71,72,83}, 167,3 , 15382,37 , 4,4 , 4,0 , 4583,6 , 4589,12 , 2, 1, 1, 6, 7 }, // Ewe/Latin/Ghana + { 161, 7, 212, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 859,11 , 870,10 , 547,6 , 1577,23 , 37,5 , 8,10 , 25565,48 , 25613,87 , 25700,24 , 25565,48 , 25613,87 , 25700,24 , 13481,28 , 13509,44 , 13553,14 , 13481,28 , 13509,44 , 13553,14 , 446,3 , 425,5 , 45,4 , 5,17 , 22,23 , {88,79,70}, 204,3 , 15419,106 , 4,4 , 4,0 , 4583,6 , 4601,11 , 0, 0, 1, 6, 7 }, // Ewe/Latin/Togo { 162, 14, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,84,66}, 0,0 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Walamo/Ethiopic/Ethiopia - { 163, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 10,17 , 18,7 , 25,12 , 24745,59 , 24804,95 , 158,27 , 24745,59 , 24804,95 , 158,27 , 13308,21 , 13329,57 , 85,14 , 13308,21 , 13329,57 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,83,68}, 6,1 , 0,7 , 4,4 , 4,0 , 4550,14 , 4564,19 , 2, 1, 7, 6, 7 }, // Hawaiian/Latin/United States - { 164, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {78,71,78}, 174,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Tyap/Latin/Nigeria + { 163, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 269,6 , 10,17 , 18,7 , 25,12 , 25724,59 , 25783,95 , 158,27 , 25724,59 , 25783,95 , 158,27 , 13567,21 , 13588,57 , 85,14 , 13567,21 , 13588,57 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,83,68}, 6,1 , 0,7 , 4,4 , 4,0 , 4612,14 , 4626,19 , 2, 1, 7, 6, 7 }, // Hawaiian/Latin/United States + { 164, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {78,71,78}, 178,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Tyap/Latin/Nigeria { 165, 7, 129, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {77,87,75}, 0,0 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Nyanja/Latin/Malawi - { 166, 7, 170, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 830,9 , 839,8 , 543,6 , 35,18 , 18,7 , 25,12 , 24899,48 , 24947,88 , 25035,38 , 24899,48 , 24947,88 , 24899,48 , 13386,28 , 13414,55 , 13386,28 , 13386,28 , 13414,55 , 13386,28 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {80,72,80}, 175,1 , 15346,58 , 4,4 , 4,0 , 4583,8 , 4591,9 , 2, 1, 7, 6, 7 }, // Filipino/Latin/Philippines - { 167, 7, 206, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 269,9 , 269,9 , 174,8 , 593,18 , 37,5 , 8,10 , 7849,48 , 25073,86 , 134,24 , 7849,48 , 25073,86 , 134,24 , 13469,28 , 13497,63 , 3738,14 , 13469,28 , 13497,63 , 3738,14 , 446,12 , 426,11 , 45,4 , 5,17 , 22,23 , {67,72,70}, 217,3 , 15404,55 , 13,5 , 4,0 , 4600,16 , 4616,7 , 2, 0, 1, 6, 7 }, // Swiss German/Latin/Switzerland - { 167, 7, 74, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 269,9 , 269,9 , 174,8 , 593,18 , 37,5 , 8,10 , 7849,48 , 25073,86 , 134,24 , 7849,48 , 25073,86 , 134,24 , 13469,28 , 13497,63 , 3738,14 , 13469,28 , 13497,63 , 3738,14 , 446,12 , 426,11 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8384,19 , 13,5 , 4,0 , 4600,16 , 4623,10 , 2, 1, 1, 6, 7 }, // Swiss German/Latin/France - { 167, 7, 123, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 269,9 , 269,9 , 174,8 , 593,18 , 37,5 , 8,10 , 7849,48 , 25073,86 , 134,24 , 7849,48 , 25073,86 , 134,24 , 13469,28 , 13497,63 , 3738,14 , 13469,28 , 13497,63 , 3738,14 , 446,12 , 426,11 , 45,4 , 5,17 , 22,23 , {67,72,70}, 217,3 , 15404,55 , 13,5 , 4,0 , 4600,16 , 4633,13 , 2, 0, 1, 6, 7 }, // Swiss German/Latin/Liechtenstein - { 168, 34, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 18,7 , 25,12 , 25159,38 , 25159,38 , 158,27 , 25159,38 , 25159,38 , 158,27 , 13560,21 , 13581,28 , 13609,14 , 13560,21 , 13581,28 , 13609,14 , 458,2 , 437,2 , 45,4 , 5,17 , 22,23 , {67,78,89}, 321,1 , 0,7 , 8,5 , 4,0 , 4646,3 , 4649,2 , 2, 1, 7, 6, 7 }, // Sichuan Yi/Yi/China + { 166, 7, 170, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 880,9 , 889,8 , 547,6 , 35,18 , 18,7 , 25,12 , 25878,48 , 25926,88 , 26014,38 , 25878,48 , 25926,88 , 25878,48 , 13645,28 , 13673,55 , 13645,28 , 13645,28 , 13673,55 , 13645,28 , 0,2 , 0,2 , 0,5 , 5,17 , 22,23 , {80,72,80}, 179,1 , 15525,58 , 4,4 , 4,0 , 4645,8 , 4653,9 , 2, 1, 7, 6, 7 }, // Filipino/Latin/Philippines + { 167, 7, 206, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 269,9 , 269,9 , 156,8 , 622,18 , 37,5 , 8,10 , 7601,48 , 26052,86 , 134,24 , 7601,48 , 26052,86 , 134,24 , 13728,28 , 13756,63 , 3668,14 , 13728,28 , 13756,63 , 3668,14 , 449,12 , 430,11 , 45,4 , 5,17 , 22,23 , {67,72,70}, 221,3 , 15583,55 , 13,5 , 4,0 , 4662,16 , 4678,7 , 2, 0, 1, 6, 7 }, // Swiss German/Latin/Switzerland + { 167, 7, 74, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 269,9 , 269,9 , 156,8 , 622,18 , 37,5 , 8,10 , 7601,48 , 26052,86 , 134,24 , 7601,48 , 26052,86 , 134,24 , 13728,28 , 13756,63 , 3668,14 , 13728,28 , 13756,63 , 3668,14 , 449,12 , 430,11 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8384,19 , 13,5 , 4,0 , 4662,16 , 4685,10 , 2, 1, 1, 6, 7 }, // Swiss German/Latin/France + { 167, 7, 123, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 269,9 , 269,9 , 156,8 , 622,18 , 37,5 , 8,10 , 7601,48 , 26052,86 , 134,24 , 7601,48 , 26052,86 , 134,24 , 13728,28 , 13756,63 , 3668,14 , 13728,28 , 13756,63 , 3668,14 , 449,12 , 430,11 , 45,4 , 5,17 , 22,23 , {67,72,70}, 221,3 , 15583,55 , 13,5 , 4,0 , 4662,16 , 4695,13 , 2, 0, 1, 6, 7 }, // Swiss German/Latin/Liechtenstein + { 168, 34, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 18,7 , 25,12 , 26138,38 , 26138,38 , 158,27 , 26138,38 , 26138,38 , 158,27 , 13819,21 , 13840,28 , 13868,14 , 13819,21 , 13840,28 , 13868,14 , 461,2 , 441,2 , 45,4 , 5,17 , 22,23 , {67,78,89}, 321,1 , 0,7 , 8,5 , 4,0 , 4708,3 , 4711,2 , 2, 1, 7, 6, 7 }, // Sichuan Yi/Yi/China { 169, 7, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {76,82,68}, 6,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Kpelle/Latin/Liberia - { 170, 7, 82, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 427,8 , 427,8 , 383,7 , 1571,23 , 522,10 , 532,19 , 7980,59 , 25197,85 , 134,24 , 7980,59 , 25197,85 , 134,24 , 13623,28 , 13651,65 , 3738,14 , 13623,28 , 13651,65 , 3738,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 15459,15 , 13,5 , 4,0 , 4651,14 , 4665,11 , 2, 1, 1, 6, 7 }, // Low German/Latin/Germany - { 170, 7, 151, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 427,8 , 427,8 , 383,7 , 1571,23 , 522,10 , 532,19 , 7980,59 , 25197,85 , 134,24 , 7980,59 , 25197,85 , 134,24 , 13623,28 , 13651,65 , 3738,14 , 13623,28 , 13651,65 , 3738,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 15459,15 , 13,5 , 4,0 , 4651,14 , 4676,12 , 2, 1, 1, 6, 7 }, // Low German/Latin/Netherlands + { 170, 7, 82, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 453,8 , 453,8 , 365,7 , 1600,23 , 526,10 , 536,19 , 26176,59 , 26235,85 , 134,24 , 26176,59 , 26235,85 , 134,24 , 13882,28 , 13910,65 , 3668,14 , 13882,28 , 13910,65 , 3668,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 15638,15 , 13,5 , 4,0 , 4713,14 , 4727,11 , 2, 1, 1, 6, 7 }, // Low German/Latin/Germany + { 170, 7, 151, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 453,8 , 453,8 , 365,7 , 1600,23 , 526,10 , 536,19 , 26176,59 , 26235,85 , 134,24 , 26176,59 , 26235,85 , 134,24 , 13882,28 , 13910,65 , 3668,14 , 13882,28 , 13910,65 , 3668,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 15638,15 , 13,5 , 4,0 , 4713,14 , 4738,12 , 2, 1, 1, 6, 7 }, // Low German/Latin/Netherlands { 171, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {90,65,82}, 5,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // South Ndebele/Latin/South Africa { 172, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {90,65,82}, 5,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Northern Sotho/Latin/South Africa - { 173, 7, 161, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 228,8 , 228,8 , 53,10 , 63,17 , 37,5 , 8,10 , 25282,59 , 25341,145 , 25486,24 , 25282,59 , 25341,145 , 25486,24 , 13716,33 , 13749,75 , 13824,14 , 13716,33 , 13749,75 , 13824,14 , 460,11 , 439,13 , 45,4 , 5,17 , 22,23 , {78,79,75}, 186,2 , 15474,63 , 13,5 , 4,0 , 4688,15 , 4703,5 , 2, 0, 1, 6, 7 }, // Northern Sami/Latin/Norway - { 173, 7, 73, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 228,8 , 228,8 , 981,10 , 98,16 , 37,5 , 8,10 , 25510,60 , 25341,145 , 25486,24 , 25510,60 , 25341,145 , 25486,24 , 13838,21 , 13859,70 , 13929,14 , 13838,21 , 13859,70 , 13929,14 , 471,2 , 452,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 15537,23 , 13,5 , 4,0 , 4688,15 , 4708,6 , 2, 1, 1, 6, 7 }, // Northern Sami/Latin/Finland - { 173, 7, 205, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 228,8 , 228,8 , 53,10 , 63,17 , 37,5 , 8,10 , 25282,59 , 25341,145 , 25486,24 , 25282,59 , 25341,145 , 25486,24 , 13716,33 , 13749,75 , 13824,14 , 13716,33 , 13749,75 , 13824,14 , 460,11 , 439,13 , 45,4 , 5,17 , 22,23 , {83,69,75}, 186,2 , 15560,63 , 13,5 , 4,0 , 4688,15 , 4714,6 , 2, 0, 1, 6, 7 }, // Northern Sami/Latin/Sweden + { 173, 7, 161, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 228,8 , 228,8 , 53,10 , 63,17 , 37,5 , 8,10 , 26320,59 , 26379,145 , 26524,24 , 26320,59 , 26379,145 , 26524,24 , 13975,33 , 14008,75 , 14083,14 , 13975,33 , 14008,75 , 14083,14 , 463,11 , 443,13 , 45,4 , 5,17 , 22,23 , {78,79,75}, 190,2 , 15653,63 , 13,5 , 4,0 , 4750,15 , 4765,5 , 2, 0, 1, 6, 7 }, // Northern Sami/Latin/Norway + { 173, 7, 73, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 228,8 , 228,8 , 495,10 , 97,16 , 37,5 , 8,10 , 26548,60 , 26379,145 , 26524,24 , 26548,60 , 26379,145 , 26524,24 , 14097,21 , 14118,70 , 14188,14 , 14097,21 , 14118,70 , 14188,14 , 474,2 , 456,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 15716,23 , 13,5 , 4,0 , 4750,15 , 4770,6 , 2, 1, 1, 6, 7 }, // Northern Sami/Latin/Finland + { 173, 7, 205, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 228,8 , 228,8 , 53,10 , 63,17 , 37,5 , 8,10 , 26320,59 , 26379,145 , 26524,24 , 26320,59 , 26379,145 , 26524,24 , 13975,33 , 14008,75 , 14083,14 , 13975,33 , 14008,75 , 14083,14 , 463,11 , 443,13 , 45,4 , 5,17 , 22,23 , {83,69,75}, 190,2 , 15739,63 , 13,5 , 4,0 , 4750,15 , 4776,6 , 2, 0, 1, 6, 7 }, // Northern Sami/Latin/Sweden { 174, 7, 208, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {84,87,68}, 333,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 0, 7, 6, 7 }, // Taroko/Latin/Taiwan - { 175, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 25570,48 , 25618,88 , 25706,24 , 25570,48 , 25618,88 , 25706,24 , 13943,28 , 13971,62 , 14033,14 , 13943,28 , 13971,62 , 14033,14 , 473,6 , 454,3 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15623,24 , 4,4 , 4,0 , 4720,8 , 1182,5 , 2, 1, 7, 6, 7 }, // Gusii/Latin/Kenya - { 176, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 25730,48 , 25778,221 , 25999,24 , 25730,48 , 25778,221 , 25999,24 , 14047,28 , 14075,105 , 14180,14 , 14047,28 , 14075,105 , 14180,14 , 479,10 , 457,10 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15623,24 , 4,4 , 4,0 , 4728,7 , 1182,5 , 2, 1, 7, 6, 7 }, // Taita/Latin/Kenya - { 177, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 26023,48 , 26071,77 , 26148,24 , 26023,48 , 26071,77 , 26148,24 , 14194,28 , 14222,59 , 14281,14 , 14194,28 , 14222,59 , 14281,14 , 489,6 , 467,7 , 45,4 , 5,17 , 22,23 , {88,79,70}, 200,3 , 15647,26 , 13,5 , 4,0 , 4735,6 , 4321,8 , 0, 0, 1, 6, 7 }, // Fulah/Latin/Senegal - { 177, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 26023,48 , 26071,77 , 26148,24 , 26023,48 , 26071,77 , 26148,24 , 14194,28 , 14222,59 , 14281,14 , 14194,28 , 14222,59 , 14281,14 , 489,6 , 467,7 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 15673,25 , 13,5 , 4,0 , 4735,6 , 4741,8 , 0, 0, 1, 6, 7 }, // Fulah/Latin/Cameroon - { 177, 7, 91, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 26023,48 , 26071,77 , 26148,24 , 26023,48 , 26071,77 , 26148,24 , 14194,28 , 14222,59 , 14281,14 , 14194,28 , 14222,59 , 14281,14 , 489,6 , 467,7 , 45,4 , 5,17 , 22,23 , {71,78,70}, 209,2 , 0,7 , 13,5 , 4,0 , 4735,6 , 4749,4 , 0, 0, 1, 6, 7 }, // Fulah/Latin/Guinea - { 177, 7, 136, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 18,7 , 25,12 , 26023,48 , 26071,77 , 26148,24 , 26023,48 , 26071,77 , 26148,24 , 14194,28 , 14222,59 , 14281,14 , 14194,28 , 14222,59 , 14281,14 , 489,6 , 467,7 , 45,4 , 5,17 , 22,23 , {77,82,85}, 212,2 , 15698,22 , 13,5 , 4,0 , 4735,6 , 4753,8 , 2, 1, 1, 6, 7 }, // Fulah/Latin/Mauritania - { 178, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 26172,48 , 26220,185 , 26405,24 , 26172,48 , 26220,185 , 26405,24 , 14295,28 , 14323,63 , 14386,14 , 14295,28 , 14323,63 , 14386,14 , 495,6 , 474,8 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15720,23 , 4,4 , 4,0 , 4761,6 , 1182,5 , 2, 1, 7, 6, 7 }, // Kikuyu/Latin/Kenya - { 179, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 26429,48 , 26477,173 , 26650,24 , 26429,48 , 26477,173 , 26650,24 , 14400,28 , 14428,105 , 14533,14 , 14400,28 , 14428,105 , 14533,14 , 501,7 , 482,5 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15743,25 , 4,4 , 4,0 , 4767,8 , 1182,5 , 2, 1, 7, 6, 7 }, // Samburu/Latin/Kenya - { 180, 7, 146, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 640,27 , 37,5 , 8,10 , 26674,48 , 26722,88 , 134,24 , 26674,48 , 26722,88 , 134,24 , 14547,28 , 14575,55 , 14630,14 , 14547,28 , 14575,55 , 14630,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {77,90,78}, 272,3 , 15768,28 , 0,4 , 4,0 , 4775,4 , 3255,10 , 2, 1, 7, 6, 7 }, // Sena/Latin/Mozambique - { 181, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 26810,52 , 26862,112 , 26974,24 , 26810,52 , 26862,112 , 26974,24 , 14644,28 , 14672,50 , 14722,14 , 14644,28 , 14672,50 , 14722,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,83,68}, 155,3 , 15796,24 , 4,4 , 4,0 , 4779,10 , 1791,8 , 2, 1, 7, 6, 7 }, // North Ndebele/Latin/Zimbabwe - { 182, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 26998,39 , 27037,194 , 27231,24 , 26998,39 , 27037,194 , 27231,24 , 14736,29 , 14765,65 , 14830,14 , 14736,29 , 14765,65 , 14830,14 , 508,8 , 487,7 , 45,4 , 5,17 , 22,23 , {84,90,83}, 188,3 , 15820,25 , 4,4 , 4,0 , 4789,9 , 1616,8 , 0, 0, 1, 6, 7 }, // Rombo/Latin/Tanzania - { 183, 9, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 27255,48 , 27303,81 , 27384,24 , 27255,48 , 27303,81 , 27384,24 , 14844,30 , 14874,47 , 85,14 , 14844,30 , 14874,47 , 85,14 , 516,6 , 494,8 , 45,4 , 5,17 , 22,23 , {77,65,68}, 0,0 , 15845,21 , 0,4 , 4,0 , 4798,7 , 4805,6 , 2, 1, 6, 5, 6 }, // Tachelhit/Tifinagh/Morocco - { 183, 7, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 27408,48 , 27456,81 , 27537,24 , 27408,48 , 27456,81 , 27537,24 , 14921,30 , 14951,48 , 85,14 , 14921,30 , 14951,48 , 85,14 , 522,6 , 502,8 , 45,4 , 5,17 , 22,23 , {77,65,68}, 0,0 , 15866,21 , 0,4 , 4,0 , 4811,10 , 4821,6 , 2, 1, 6, 5, 6 }, // Tachelhit/Latin/Morocco - { 184, 7, 3, 44, 160, 59, 37, 48, 45, 43, 122, 171, 187, 8220, 8221, 0,6 , 0,6 , 847,12 , 859,11 , 433,8 , 98,16 , 18,7 , 25,12 , 27561,48 , 27609,82 , 27691,24 , 27715,48 , 27763,84 , 27847,24 , 14999,28 , 15027,34 , 15061,14 , 15075,30 , 15105,51 , 15156,14 , 528,7 , 510,9 , 1052,7 , 1059,23 , 1082,29 , {68,90,68}, 198,2 , 15887,53 , 0,4 , 4,0 , 4827,9 , 4836,8 , 2, 1, 6, 5, 6 }, // Kabyle/Latin/Algeria - { 185, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 27871,48 , 27919,152 , 134,24 , 27871,48 , 27919,152 , 134,24 , 15170,28 , 15198,74 , 15272,14 , 15170,28 , 15198,74 , 15272,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,71,88}, 193,3 , 15940,26 , 4,4 , 4,0 , 4844,10 , 1681,6 , 0, 0, 1, 6, 7 }, // Nyankole/Latin/Uganda - { 186, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 28071,48 , 28119,254 , 28373,24 , 28071,48 , 28119,254 , 28373,24 , 15286,28 , 15314,82 , 15396,14 , 15286,28 , 15314,82 , 15396,14 , 535,7 , 519,7 , 45,4 , 5,17 , 22,23 , {84,90,83}, 188,3 , 15966,29 , 0,4 , 4,0 , 4854,6 , 4860,10 , 0, 0, 1, 6, 7 }, // Bena/Latin/Tanzania - { 187, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 18463,48 , 28397,87 , 134,24 , 18463,48 , 28397,87 , 134,24 , 15410,28 , 15438,62 , 15500,14 , 15410,28 , 15438,62 , 15500,14 , 542,5 , 526,9 , 45,4 , 5,17 , 22,23 , {84,90,83}, 188,3 , 15995,27 , 4,4 , 4,0 , 4870,8 , 1616,8 , 0, 0, 1, 6, 7 }, // Vunjo/Latin/Tanzania - { 188, 7, 132, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 28484,47 , 28531,92 , 28623,24 , 28484,47 , 28531,92 , 28623,24 , 15514,28 , 15542,44 , 15586,14 , 15514,28 , 15542,44 , 15586,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,79,70}, 200,3 , 16022,24 , 4,4 , 4,0 , 4878,9 , 2155,4 , 0, 0, 1, 6, 7 }, // Bambara/Latin/Mali - { 188, 75, 132, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,79,70}, 200,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 1, 6, 7 }, // Bambara/Nko/Mali - { 189, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 28647,48 , 28695,207 , 28902,24 , 28647,48 , 28695,207 , 28902,24 , 15600,28 , 15628,64 , 15692,14 , 15600,28 , 15628,64 , 15692,14 , 547,2 , 535,2 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15623,24 , 4,4 , 4,0 , 4887,6 , 1182,5 , 2, 1, 7, 6, 7 }, // Embu/Latin/Kenya - { 190, 12, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 870,8 , 870,8 , 543,6 , 35,18 , 18,7 , 25,12 , 28926,36 , 28962,58 , 29020,24 , 28926,36 , 28962,58 , 29020,24 , 15706,28 , 15734,49 , 15783,14 , 15706,28 , 15734,49 , 15783,14 , 549,3 , 537,6 , 1111,6 , 5,17 , 22,23 , {85,83,68}, 6,1 , 16046,25 , 4,4 , 4,0 , 4893,3 , 4896,15 , 2, 1, 7, 6, 7 }, // Cherokee/Cherokee/United States - { 191, 7, 137, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 29044,47 , 29091,68 , 29159,24 , 29044,47 , 29091,68 , 29159,24 , 15797,27 , 15824,48 , 15872,14 , 15797,27 , 15824,48 , 15872,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {77,85,82}, 172,2 , 16071,21 , 41,6 , 4,0 , 4911,14 , 4925,5 , 0, 0, 1, 6, 7 }, // Morisyen/Latin/Mauritius - { 192, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 18463,48 , 29183,264 , 134,24 , 18463,48 , 29183,264 , 134,24 , 15886,28 , 15914,133 , 14830,14 , 15886,28 , 15914,133 , 14830,14 , 552,4 , 543,5 , 45,4 , 5,17 , 22,23 , {84,90,83}, 188,3 , 15995,27 , 4,4 , 4,0 , 4930,10 , 1616,8 , 0, 0, 1, 6, 7 }, // Makonde/Latin/Tanzania - { 193, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 29447,83 , 29530,111 , 29641,24 , 29447,83 , 29530,111 , 29641,24 , 16047,36 , 16083,63 , 16146,14 , 16047,36 , 16083,63 , 16146,14 , 556,3 , 548,3 , 45,4 , 5,17 , 22,23 , {84,90,83}, 188,3 , 16092,29 , 41,6 , 4,0 , 4940,8 , 4948,9 , 0, 0, 1, 6, 7 }, // Langi/Latin/Tanzania - { 194, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 29665,48 , 29713,97 , 134,24 , 29665,48 , 29713,97 , 134,24 , 16160,28 , 16188,66 , 16254,14 , 16160,28 , 16188,66 , 16254,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,71,88}, 193,3 , 16121,26 , 0,4 , 4,0 , 4957,7 , 4964,7 , 0, 0, 1, 6, 7 }, // Ganda/Latin/Uganda - { 195, 7, 239, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 18,7 , 25,12 , 29810,48 , 29858,83 , 29941,24 , 29810,48 , 29858,83 , 29941,24 , 16268,80 , 16268,80 , 85,14 , 16268,80 , 16268,80 , 85,14 , 559,8 , 551,7 , 45,4 , 5,17 , 22,23 , {90,77,87}, 127,1 , 0,7 , 4,4 , 4,0 , 4971,9 , 1785,6 , 2, 1, 1, 6, 7 }, // Bemba/Latin/Zambia - { 196, 7, 39, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 163,7 , 163,7 , 433,8 , 1594,27 , 37,5 , 8,10 , 29965,48 , 30013,85 , 134,24 , 29965,48 , 30013,85 , 134,24 , 16348,28 , 16376,73 , 16449,14 , 16348,28 , 16463,73 , 16449,14 , 70,2 , 67,2 , 45,4 , 340,17 , 22,23 , {67,86,69}, 271,1 , 16147,43 , 13,5 , 4,0 , 4980,12 , 4992,10 , 2, 1, 1, 6, 7 }, // Kabuverdianu/Latin/Cape Verde - { 197, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 30098,48 , 30146,86 , 30232,24 , 30098,48 , 30146,86 , 30232,24 , 16536,28 , 16564,51 , 16615,14 , 16536,28 , 16564,51 , 16615,14 , 567,2 , 558,2 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15623,24 , 4,4 , 4,0 , 5002,6 , 1182,5 , 2, 1, 7, 6, 7 }, // Meru/Latin/Kenya - { 198, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 30256,49 , 30305,121 , 30426,24 , 30256,49 , 30305,121 , 30426,24 , 16629,28 , 16657,53 , 16710,14 , 16629,28 , 16657,53 , 16710,14 , 569,6 , 560,10 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 16190,26 , 4,4 , 4,0 , 5008,8 , 5016,12 , 2, 1, 7, 6, 7 }, // Kalenjin/Latin/Kenya - { 199, 7, 148, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 18,7 , 25,12 , 0,48 , 30450,136 , 134,24 , 0,48 , 30450,136 , 134,24 , 16724,23 , 16747,92 , 16839,14 , 16724,23 , 16747,92 , 16839,14 , 575,7 , 570,5 , 45,4 , 5,17 , 22,23 , {78,65,68}, 6,1 , 16216,22 , 4,4 , 4,0 , 5028,13 , 5041,8 , 2, 1, 1, 6, 7 }, // Nama/Latin/Namibia - { 200, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 18463,48 , 28397,87 , 134,24 , 18463,48 , 28397,87 , 134,24 , 15410,28 , 15438,62 , 15500,14 , 15410,28 , 15438,62 , 15500,14 , 542,5 , 526,9 , 45,4 , 5,17 , 22,23 , {84,90,83}, 188,3 , 15995,27 , 4,4 , 4,0 , 5049,9 , 1616,8 , 0, 0, 1, 6, 7 }, // Machame/Latin/Tanzania - { 201, 7, 82, 44, 160, 59, 37, 48, 8722, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 427,8 , 427,8 , 1089,10 , 1621,23 , 37,5 , 8,10 , 30586,59 , 30645,87 , 12825,24 , 30732,48 , 30645,87 , 12825,24 , 16853,28 , 16881,72 , 3738,14 , 16853,28 , 16881,72 , 3738,14 , 582,16 , 575,16 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 16238,11 , 13,5 , 4,0 , 5058,6 , 5064,11 , 2, 1, 1, 6, 7 }, // Colognian/Latin/Germany - { 202, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 30780,51 , 30831,132 , 158,27 , 30780,51 , 30831,132 , 158,27 , 15410,28 , 16953,58 , 14830,14 , 15410,28 , 16953,58 , 14830,14 , 598,9 , 591,6 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 16249,25 , 4,4 , 4,0 , 5075,3 , 1182,5 , 2, 1, 7, 6, 7 }, // Masai/Latin/Kenya - { 202, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 30780,51 , 30831,132 , 158,27 , 30780,51 , 30831,132 , 158,27 , 15410,28 , 16953,58 , 14830,14 , 15410,28 , 16953,58 , 14830,14 , 598,9 , 591,6 , 45,4 , 5,17 , 22,23 , {84,90,83}, 188,3 , 16274,28 , 4,4 , 4,0 , 5075,3 , 5078,8 , 0, 0, 1, 6, 7 }, // Masai/Latin/Tanzania - { 203, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 29665,48 , 29713,97 , 134,24 , 29665,48 , 29713,97 , 134,24 , 17011,35 , 17046,65 , 17111,14 , 17011,35 , 17046,65 , 17111,14 , 607,6 , 597,6 , 45,4 , 5,17 , 22,23 , {85,71,88}, 193,3 , 16121,26 , 13,5 , 4,0 , 5086,7 , 4964,7 , 0, 0, 1, 6, 7 }, // Soga/Latin/Uganda - { 204, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 30963,48 , 18511,84 , 134,24 , 30963,48 , 18511,84 , 134,24 , 17125,21 , 17146,75 , 85,14 , 17125,21 , 17146,75 , 85,14 , 66,4 , 63,4 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 16302,23 , 4,4 , 102,6 , 5093,7 , 1182,5 , 2, 1, 7, 6, 7 }, // Luyia/Latin/Kenya - { 205, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 31011,48 , 18511,84 , 134,24 , 31011,48 , 18511,84 , 134,24 , 17221,28 , 9767,60 , 15500,14 , 17221,28 , 9767,60 , 15500,14 , 613,9 , 603,8 , 45,4 , 5,17 , 22,23 , {84,90,83}, 188,3 , 16325,28 , 13,5 , 4,0 , 5100,6 , 5106,8 , 0, 0, 1, 6, 7 }, // Asu/Latin/Tanzania - { 206, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 31059,48 , 31107,94 , 31201,24 , 31059,48 , 31107,94 , 31201,24 , 17249,28 , 17277,69 , 17346,14 , 17249,28 , 17277,69 , 17346,14 , 622,9 , 611,6 , 45,4 , 5,17 , 22,23 , {85,71,88}, 193,3 , 16353,28 , 4,4 , 4,0 , 5114,6 , 1681,6 , 0, 0, 1, 6, 7 }, // Teso/Latin/Uganda - { 206, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 31059,48 , 31107,94 , 31201,24 , 31059,48 , 31107,94 , 31201,24 , 17249,28 , 17277,69 , 17346,14 , 17249,28 , 17277,69 , 17346,14 , 622,9 , 611,6 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 16381,27 , 4,4 , 4,0 , 5114,6 , 5120,5 , 2, 1, 7, 6, 7 }, // Teso/Latin/Kenya + { 175, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 26608,48 , 26656,88 , 26744,24 , 26608,48 , 26656,88 , 26744,24 , 14202,28 , 14230,62 , 14292,14 , 14202,28 , 14230,62 , 14292,14 , 476,6 , 458,3 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15802,24 , 4,4 , 4,0 , 4782,8 , 1182,5 , 2, 1, 7, 6, 7 }, // Gusii/Latin/Kenya + { 176, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 26768,48 , 26816,221 , 27037,24 , 26768,48 , 26816,221 , 27037,24 , 14306,28 , 14334,105 , 14439,14 , 14306,28 , 14334,105 , 14439,14 , 482,10 , 461,10 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15802,24 , 4,4 , 4,0 , 4790,7 , 1182,5 , 2, 1, 7, 6, 7 }, // Taita/Latin/Kenya + { 177, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 27061,48 , 27109,77 , 27186,24 , 27061,48 , 27109,77 , 27186,24 , 14453,28 , 14481,59 , 14540,14 , 14453,28 , 14481,59 , 14540,14 , 492,6 , 471,7 , 45,4 , 5,17 , 22,23 , {88,79,70}, 204,3 , 15826,26 , 13,5 , 4,0 , 4797,6 , 4360,8 , 0, 0, 1, 6, 7 }, // Fulah/Latin/Senegal + { 177, 7, 34, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 27061,48 , 27109,77 , 27186,24 , 27061,48 , 27109,77 , 27186,24 , 14453,28 , 14481,59 , 14540,14 , 14453,28 , 14481,59 , 14540,14 , 492,6 , 471,7 , 45,4 , 5,17 , 22,23 , {88,79,70}, 204,3 , 15826,26 , 13,5 , 4,0 , 4797,6 , 4803,14 , 0, 0, 1, 6, 7 }, // Fulah/Latin/Burkina Faso + { 177, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 27061,48 , 27109,77 , 27186,24 , 27061,48 , 27109,77 , 27186,24 , 14453,28 , 14481,59 , 14540,14 , 14453,28 , 14481,59 , 14540,14 , 492,6 , 471,7 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 15852,25 , 13,5 , 4,0 , 4797,6 , 4817,8 , 0, 0, 1, 6, 7 }, // Fulah/Latin/Cameroon + { 177, 7, 80, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 27061,48 , 27109,77 , 27186,24 , 27061,48 , 27109,77 , 27186,24 , 14453,28 , 14481,59 , 14540,14 , 14453,28 , 14481,59 , 14540,14 , 492,6 , 471,7 , 45,4 , 5,17 , 22,23 , {71,77,68}, 166,1 , 15877,20 , 13,5 , 4,0 , 4797,6 , 4825,6 , 2, 1, 1, 6, 7 }, // Fulah/Latin/Gambia + { 177, 7, 83, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 27061,48 , 27109,77 , 27186,24 , 27061,48 , 27109,77 , 27186,24 , 14453,28 , 14481,59 , 14540,14 , 14453,28 , 14481,59 , 14540,14 , 492,6 , 471,7 , 45,4 , 5,17 , 22,23 , {71,72,83}, 167,3 , 0,7 , 13,5 , 4,0 , 4797,6 , 4831,5 , 2, 1, 1, 6, 7 }, // Fulah/Latin/Ghana + { 177, 7, 91, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 27061,48 , 27109,77 , 27186,24 , 27061,48 , 27109,77 , 27186,24 , 14453,28 , 14481,59 , 14540,14 , 14453,28 , 14481,59 , 14540,14 , 492,6 , 471,7 , 45,4 , 5,17 , 22,23 , {71,78,70}, 213,2 , 0,7 , 13,5 , 4,0 , 4797,6 , 4836,4 , 0, 0, 1, 6, 7 }, // Fulah/Latin/Guinea + { 177, 7, 92, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 27061,48 , 27109,77 , 27186,24 , 27061,48 , 27109,77 , 27186,24 , 14453,28 , 14481,59 , 14540,14 , 14453,28 , 14481,59 , 14540,14 , 492,6 , 471,7 , 45,4 , 5,17 , 22,23 , {88,79,70}, 204,3 , 15826,26 , 13,5 , 4,0 , 4797,6 , 4840,12 , 0, 0, 1, 6, 7 }, // Fulah/Latin/Guinea Bissau + { 177, 7, 121, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 27061,48 , 27109,77 , 27186,24 , 27061,48 , 27109,77 , 27186,24 , 14453,28 , 14481,59 , 14540,14 , 14453,28 , 14481,59 , 14540,14 , 492,6 , 471,7 , 45,4 , 5,17 , 22,23 , {76,82,68}, 6,1 , 15897,23 , 13,5 , 4,0 , 4797,6 , 4852,9 , 2, 1, 1, 6, 7 }, // Fulah/Latin/Liberia + { 177, 7, 136, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 18,7 , 25,12 , 27061,48 , 27109,77 , 27186,24 , 27061,48 , 27109,77 , 27186,24 , 14453,28 , 14481,59 , 14540,14 , 14453,28 , 14481,59 , 14540,14 , 492,6 , 471,7 , 45,4 , 5,17 , 22,23 , {77,82,85}, 216,2 , 15920,22 , 13,5 , 4,0 , 4797,6 , 4861,8 , 2, 1, 1, 6, 7 }, // Fulah/Latin/Mauritania + { 177, 7, 156, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 27061,48 , 27109,77 , 27186,24 , 27061,48 , 27109,77 , 27186,24 , 14453,28 , 14481,59 , 14540,14 , 14453,28 , 14481,59 , 14540,14 , 492,6 , 471,7 , 45,4 , 5,17 , 22,23 , {88,79,70}, 204,3 , 15826,26 , 13,5 , 4,0 , 4797,6 , 4869,6 , 0, 0, 1, 6, 7 }, // Fulah/Latin/Niger + { 177, 7, 157, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 27061,48 , 27109,77 , 27186,24 , 27061,48 , 27109,77 , 27186,24 , 14453,28 , 14481,59 , 14540,14 , 14453,28 , 14481,59 , 14540,14 , 492,6 , 471,7 , 45,4 , 5,17 , 22,23 , {78,71,78}, 178,1 , 15942,23 , 13,5 , 4,0 , 4797,6 , 4875,9 , 2, 1, 1, 6, 7 }, // Fulah/Latin/Nigeria + { 177, 7, 189, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 27061,48 , 27109,77 , 27186,24 , 27061,48 , 27109,77 , 27186,24 , 14453,28 , 14481,59 , 14540,14 , 14453,28 , 14481,59 , 14540,14 , 492,6 , 471,7 , 45,4 , 5,17 , 22,23 , {83,76,76}, 187,2 , 15965,25 , 13,5 , 4,0 , 4797,6 , 4884,11 , 0, 0, 1, 6, 7 }, // Fulah/Latin/Sierra Leone + { 177, 134, 91, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {71,78,70}, 213,2 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 1, 6, 7 }, // Fulah/Adlam/Guinea + { 178, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 27210,48 , 27258,185 , 27443,24 , 27210,48 , 27258,185 , 27443,24 , 14554,28 , 14582,63 , 14645,14 , 14554,28 , 14582,63 , 14645,14 , 498,6 , 478,8 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15990,23 , 4,4 , 4,0 , 4895,6 , 1182,5 , 2, 1, 7, 6, 7 }, // Kikuyu/Latin/Kenya + { 179, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 27467,48 , 27515,173 , 27688,24 , 27467,48 , 27515,173 , 27688,24 , 14659,28 , 14687,105 , 14792,14 , 14659,28 , 14687,105 , 14792,14 , 504,7 , 486,5 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 16013,25 , 4,4 , 4,0 , 4901,8 , 1182,5 , 2, 1, 7, 6, 7 }, // Samburu/Latin/Kenya + { 180, 7, 146, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 669,27 , 37,5 , 8,10 , 27712,48 , 27760,88 , 134,24 , 27712,48 , 27760,88 , 134,24 , 14806,28 , 14834,55 , 14889,14 , 14806,28 , 14834,55 , 14889,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {77,90,78}, 273,3 , 16038,28 , 0,4 , 4,0 , 4909,4 , 3309,10 , 2, 1, 7, 6, 7 }, // Sena/Latin/Mozambique + { 181, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 27848,52 , 27900,112 , 28012,24 , 27848,52 , 27900,112 , 28012,24 , 14903,28 , 14931,50 , 14981,14 , 14903,28 , 14931,50 , 14981,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,83,68}, 159,3 , 16066,24 , 4,4 , 4,0 , 4913,10 , 1791,8 , 2, 1, 7, 6, 7 }, // North Ndebele/Latin/Zimbabwe + { 182, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 28036,39 , 28075,194 , 28269,24 , 28036,39 , 28075,194 , 28269,24 , 14995,29 , 15024,65 , 15089,14 , 14995,29 , 15024,65 , 15089,14 , 511,8 , 491,7 , 45,4 , 5,17 , 22,23 , {84,90,83}, 192,3 , 16090,25 , 4,4 , 4,0 , 4923,9 , 1616,8 , 2, 0, 1, 6, 7 }, // Rombo/Latin/Tanzania + { 183, 9, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 28293,48 , 28341,81 , 28422,24 , 28293,48 , 28341,81 , 28422,24 , 15103,30 , 15133,47 , 85,14 , 15103,30 , 15133,47 , 85,14 , 519,6 , 498,8 , 45,4 , 5,17 , 22,23 , {77,65,68}, 0,0 , 16115,21 , 0,4 , 4,0 , 4932,7 , 4939,6 , 2, 1, 1, 6, 7 }, // Tachelhit/Tifinagh/Morocco + { 183, 7, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 28446,48 , 28494,81 , 28575,24 , 28446,48 , 28494,81 , 28575,24 , 15180,30 , 15210,48 , 85,14 , 15180,30 , 15210,48 , 85,14 , 525,6 , 506,8 , 45,4 , 5,17 , 22,23 , {77,65,68}, 0,0 , 16136,21 , 0,4 , 4,0 , 4945,10 , 4955,6 , 2, 1, 1, 6, 7 }, // Tachelhit/Latin/Morocco + { 184, 7, 3, 44, 160, 59, 37, 48, 45, 43, 122, 171, 187, 8220, 8221, 0,6 , 0,6 , 897,12 , 909,11 , 415,8 , 97,16 , 18,7 , 25,12 , 28599,48 , 28647,82 , 28729,24 , 28753,48 , 28801,84 , 28885,24 , 15258,28 , 15286,34 , 15320,14 , 15334,30 , 15364,51 , 15415,14 , 531,7 , 514,9 , 1195,7 , 1202,21 , 22,23 , {68,90,68}, 202,2 , 16157,53 , 0,4 , 4,0 , 4961,9 , 4970,8 , 2, 1, 6, 5, 6 }, // Kabyle/Latin/Algeria + { 185, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 28909,48 , 28957,152 , 134,24 , 28909,48 , 28957,152 , 134,24 , 15429,28 , 15457,74 , 15531,14 , 15429,28 , 15457,74 , 15531,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,71,88}, 197,3 , 16210,26 , 4,4 , 4,0 , 4978,10 , 1681,6 , 0, 0, 1, 6, 7 }, // Nyankole/Latin/Uganda + { 186, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 29109,48 , 29157,254 , 29411,24 , 29109,48 , 29157,254 , 29411,24 , 15545,28 , 15573,82 , 15655,14 , 15545,28 , 15573,82 , 15655,14 , 538,7 , 523,7 , 45,4 , 5,17 , 22,23 , {84,90,83}, 192,3 , 16236,29 , 0,4 , 4,0 , 4988,6 , 4994,10 , 2, 0, 1, 6, 7 }, // Bena/Latin/Tanzania + { 187, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 19304,48 , 29435,87 , 134,24 , 19304,48 , 29435,87 , 134,24 , 15669,28 , 15697,62 , 15759,14 , 15669,28 , 15697,62 , 15759,14 , 545,5 , 530,9 , 45,4 , 5,17 , 22,23 , {84,90,83}, 192,3 , 16265,27 , 4,4 , 4,0 , 5004,8 , 1616,8 , 2, 0, 1, 6, 7 }, // Vunjo/Latin/Tanzania + { 188, 7, 132, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 29522,47 , 29569,92 , 29661,24 , 29522,47 , 29569,92 , 29661,24 , 15773,28 , 15801,44 , 15845,14 , 15773,28 , 15801,44 , 15845,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,79,70}, 204,3 , 16292,24 , 4,4 , 4,0 , 5012,9 , 2155,4 , 0, 0, 1, 6, 7 }, // Bambara/Latin/Mali + { 188, 75, 132, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,79,70}, 204,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 1, 6, 7 }, // Bambara/Nko/Mali + { 189, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 29685,48 , 29733,207 , 29940,24 , 29685,48 , 29733,207 , 29940,24 , 15859,28 , 15887,64 , 15951,14 , 15859,28 , 15887,64 , 15951,14 , 550,2 , 539,2 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15802,24 , 4,4 , 4,0 , 5021,6 , 1182,5 , 2, 1, 7, 6, 7 }, // Embu/Latin/Kenya + { 190, 12, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 920,9 , 929,8 , 547,6 , 35,18 , 18,7 , 25,12 , 29964,36 , 30000,58 , 30058,24 , 29964,36 , 30000,58 , 30058,24 , 15965,28 , 15993,49 , 16042,14 , 15965,28 , 15993,49 , 16042,14 , 552,3 , 541,6 , 1223,6 , 5,17 , 22,23 , {85,83,68}, 6,1 , 16316,25 , 4,4 , 4,0 , 5027,3 , 5030,15 , 2, 1, 7, 6, 7 }, // Cherokee/Cherokee/United States + { 191, 7, 137, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 30082,47 , 30129,68 , 30197,24 , 30082,47 , 30129,68 , 30197,24 , 16056,27 , 16083,48 , 16131,14 , 16056,27 , 16083,48 , 16131,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {77,85,82}, 176,2 , 16341,21 , 41,6 , 4,0 , 5045,14 , 5059,5 , 2, 0, 1, 6, 7 }, // Morisyen/Latin/Mauritius + { 192, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 19304,48 , 30221,264 , 134,24 , 19304,48 , 30221,264 , 134,24 , 16145,28 , 16173,133 , 15089,14 , 16145,28 , 16173,133 , 15089,14 , 555,4 , 547,5 , 45,4 , 5,17 , 22,23 , {84,90,83}, 192,3 , 16265,27 , 4,4 , 4,0 , 5064,10 , 1616,8 , 2, 0, 1, 6, 7 }, // Makonde/Latin/Tanzania + { 193, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 30485,83 , 30568,111 , 30679,24 , 30485,83 , 30568,111 , 30679,24 , 16306,36 , 16342,63 , 16405,14 , 16306,36 , 16342,63 , 16405,14 , 559,3 , 552,3 , 45,4 , 5,17 , 22,23 , {84,90,83}, 192,3 , 16362,29 , 41,6 , 4,0 , 5074,8 , 5082,9 , 2, 0, 1, 6, 7 }, // Langi/Latin/Tanzania + { 194, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 30703,48 , 30751,97 , 134,24 , 30703,48 , 30751,97 , 134,24 , 16419,28 , 16447,66 , 16513,14 , 16419,28 , 16447,66 , 16513,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,71,88}, 197,3 , 16391,26 , 0,4 , 4,0 , 5091,7 , 5098,7 , 0, 0, 1, 6, 7 }, // Ganda/Latin/Uganda + { 195, 7, 239, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 18,7 , 25,12 , 30848,48 , 30896,83 , 30979,24 , 30848,48 , 30896,83 , 30979,24 , 16527,80 , 16527,80 , 85,14 , 16527,80 , 16527,80 , 85,14 , 562,8 , 555,7 , 45,4 , 5,17 , 22,23 , {90,77,87}, 131,1 , 0,7 , 4,4 , 4,0 , 5105,9 , 1785,6 , 2, 1, 1, 6, 7 }, // Bemba/Latin/Zambia + { 196, 7, 39, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 163,7 , 163,7 , 415,8 , 1623,27 , 37,5 , 8,10 , 31003,48 , 31051,85 , 134,24 , 31003,48 , 31051,85 , 134,24 , 16607,28 , 16635,73 , 16708,14 , 16607,28 , 16722,73 , 16708,14 , 68,2 , 65,2 , 45,4 , 323,17 , 22,23 , {67,86,69}, 272,1 , 16417,43 , 13,5 , 4,0 , 5114,12 , 5126,10 , 2, 1, 1, 6, 7 }, // Kabuverdianu/Latin/Cape Verde + { 197, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 31136,48 , 31184,86 , 31270,24 , 31136,48 , 31184,86 , 31270,24 , 16795,28 , 16823,51 , 16874,14 , 16795,28 , 16823,51 , 16874,14 , 570,2 , 562,2 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 15802,24 , 4,4 , 4,0 , 5136,6 , 1182,5 , 2, 1, 7, 6, 7 }, // Meru/Latin/Kenya + { 198, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 31294,49 , 31343,121 , 31464,24 , 31294,49 , 31343,121 , 31464,24 , 16888,28 , 16916,53 , 16969,14 , 16888,28 , 16916,53 , 16969,14 , 572,6 , 564,10 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 16460,26 , 4,4 , 4,0 , 5142,8 , 5150,12 , 2, 1, 7, 6, 7 }, // Kalenjin/Latin/Kenya + { 199, 7, 148, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 18,7 , 25,12 , 0,48 , 31488,136 , 134,24 , 0,48 , 31488,136 , 134,24 , 16983,23 , 17006,92 , 17098,14 , 16983,23 , 17006,92 , 17098,14 , 578,7 , 574,5 , 45,4 , 5,17 , 22,23 , {78,65,68}, 6,1 , 16486,22 , 4,4 , 4,0 , 5162,13 , 5175,8 , 2, 1, 1, 6, 7 }, // Nama/Latin/Namibia + { 200, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 19304,48 , 29435,87 , 134,24 , 19304,48 , 29435,87 , 134,24 , 15669,28 , 15697,62 , 15759,14 , 15669,28 , 15697,62 , 15759,14 , 545,5 , 530,9 , 45,4 , 5,17 , 22,23 , {84,90,83}, 192,3 , 16265,27 , 4,4 , 4,0 , 5183,9 , 1616,8 , 2, 0, 1, 6, 7 }, // Machame/Latin/Tanzania + { 201, 7, 82, 44, 160, 59, 37, 48, 8722, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 453,8 , 453,8 , 1117,10 , 1650,23 , 37,5 , 8,10 , 31624,59 , 31683,87 , 12992,24 , 31770,48 , 31683,87 , 12992,24 , 17112,28 , 17140,72 , 3668,14 , 17112,28 , 17140,72 , 3668,14 , 585,16 , 579,16 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 16508,11 , 13,5 , 4,0 , 5192,6 , 5198,11 , 2, 1, 1, 6, 7 }, // Colognian/Latin/Germany + { 202, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 31818,51 , 31869,132 , 158,27 , 31818,51 , 31869,132 , 158,27 , 15669,28 , 17212,58 , 15089,14 , 15669,28 , 17212,58 , 15089,14 , 601,9 , 595,6 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 16519,25 , 4,4 , 4,0 , 5209,3 , 1182,5 , 2, 1, 7, 6, 7 }, // Masai/Latin/Kenya + { 202, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 31818,51 , 31869,132 , 158,27 , 31818,51 , 31869,132 , 158,27 , 15669,28 , 17212,58 , 15089,14 , 15669,28 , 17212,58 , 15089,14 , 601,9 , 595,6 , 45,4 , 5,17 , 22,23 , {84,90,83}, 192,3 , 16544,28 , 4,4 , 4,0 , 5209,3 , 5212,8 , 2, 0, 1, 6, 7 }, // Masai/Latin/Tanzania + { 203, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 30703,48 , 30751,97 , 134,24 , 30703,48 , 30751,97 , 134,24 , 17270,35 , 17305,65 , 17370,14 , 17270,35 , 17305,65 , 17370,14 , 610,6 , 601,6 , 45,4 , 5,17 , 22,23 , {85,71,88}, 197,3 , 16391,26 , 13,5 , 4,0 , 5220,7 , 5098,7 , 0, 0, 1, 6, 7 }, // Soga/Latin/Uganda + { 204, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 32001,48 , 19352,84 , 134,24 , 32001,48 , 19352,84 , 134,24 , 17384,21 , 17405,75 , 85,14 , 17384,21 , 17405,75 , 85,14 , 64,4 , 61,4 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 16572,23 , 4,4 , 102,6 , 5227,7 , 1182,5 , 2, 1, 7, 6, 7 }, // Luyia/Latin/Kenya + { 205, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 32049,48 , 19352,84 , 134,24 , 32049,48 , 19352,84 , 134,24 , 17480,28 , 10047,60 , 15759,14 , 17480,28 , 10047,60 , 15759,14 , 616,9 , 607,8 , 45,4 , 5,17 , 22,23 , {84,90,83}, 192,3 , 16595,28 , 13,5 , 4,0 , 5234,6 , 5240,8 , 2, 0, 1, 6, 7 }, // Asu/Latin/Tanzania + { 206, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 32097,48 , 32145,94 , 32239,24 , 32097,48 , 32145,94 , 32239,24 , 17508,28 , 17536,69 , 17605,14 , 17508,28 , 17536,69 , 17605,14 , 625,9 , 615,6 , 45,4 , 5,17 , 22,23 , {85,71,88}, 197,3 , 16623,28 , 4,4 , 4,0 , 5248,6 , 1681,6 , 0, 0, 1, 6, 7 }, // Teso/Latin/Uganda + { 206, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 32097,48 , 32145,94 , 32239,24 , 32097,48 , 32145,94 , 32239,24 , 17508,28 , 17536,69 , 17605,14 , 17508,28 , 17536,69 , 17605,14 , 625,9 , 615,6 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 16651,27 , 4,4 , 4,0 , 5248,6 , 5254,5 , 2, 1, 7, 6, 7 }, // Teso/Latin/Kenya { 207, 7, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,82,78}, 0,0 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Saho/Latin/Eritrea - { 208, 7, 132, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 31225,46 , 31271,88 , 31359,24 , 31225,46 , 31271,88 , 31359,24 , 17360,28 , 17388,53 , 17441,14 , 17360,28 , 17388,53 , 17441,14 , 631,6 , 617,6 , 45,4 , 5,17 , 22,23 , {88,79,70}, 200,3 , 16408,23 , 0,4 , 4,0 , 5125,11 , 5136,5 , 0, 0, 1, 6, 7 }, // Koyra Chiini/Latin/Mali - { 209, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 18463,48 , 28397,87 , 134,24 , 18463,48 , 28397,87 , 134,24 , 15410,28 , 15438,62 , 15500,14 , 15410,28 , 15438,62 , 15500,14 , 542,5 , 526,9 , 45,4 , 5,17 , 22,23 , {84,90,83}, 188,3 , 15995,27 , 0,4 , 4,0 , 5141,6 , 1616,8 , 0, 0, 1, 6, 7 }, // Rwa/Latin/Tanzania - { 210, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 31383,48 , 31431,186 , 31617,24 , 31383,48 , 31431,186 , 31617,24 , 17455,28 , 17483,69 , 17552,14 , 17455,28 , 17483,69 , 17552,14 , 637,2 , 623,2 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 16431,23 , 0,4 , 4,0 , 5147,6 , 1182,5 , 2, 1, 7, 6, 7 }, // Luo/Latin/Kenya - { 211, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 27871,48 , 27919,152 , 134,24 , 27871,48 , 27919,152 , 134,24 , 15170,28 , 15198,74 , 15272,14 , 15170,28 , 15198,74 , 15272,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,71,88}, 193,3 , 15940,26 , 4,4 , 4,0 , 5153,6 , 1681,6 , 0, 0, 1, 6, 7 }, // Chiga/Latin/Uganda - { 212, 7, 145, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 31641,48 , 31689,86 , 31775,24 , 31641,48 , 31689,86 , 31775,24 , 17566,28 , 17594,48 , 17642,14 , 17566,28 , 17594,48 , 17642,14 , 639,9 , 625,10 , 45,4 , 5,17 , 22,23 , {77,65,68}, 0,0 , 16454,22 , 13,5 , 4,0 , 5159,17 , 5176,6 , 2, 1, 6, 5, 6 }, // Central Morocco Tamazight/Latin/Morocco - { 213, 7, 132, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 31225,46 , 31271,88 , 31359,24 , 31225,46 , 31271,88 , 31359,24 , 17656,28 , 17684,54 , 17441,14 , 17656,28 , 17684,54 , 17441,14 , 631,6 , 617,6 , 45,4 , 5,17 , 22,23 , {88,79,70}, 200,3 , 16408,23 , 0,4 , 4,0 , 5182,15 , 5136,5 , 0, 0, 1, 6, 7 }, // Koyraboro Senni/Latin/Mali - { 214, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 18463,48 , 31799,84 , 134,24 , 18463,48 , 31799,84 , 134,24 , 17738,28 , 17766,63 , 17829,14 , 17738,28 , 17766,63 , 17829,14 , 648,5 , 635,8 , 45,4 , 5,17 , 22,23 , {84,90,83}, 188,3 , 16476,27 , 0,4 , 4,0 , 5197,9 , 1616,8 , 0, 0, 1, 6, 7 }, // Shambala/Latin/Tanzania - { 215, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 543,6 , 35,18 , 18,7 , 25,12 , 31883,88 , 31883,88 , 31971,31 , 31883,88 , 31883,88 , 31971,31 , 17843,33 , 17876,54 , 17930,19 , 17843,33 , 17876,54 , 17930,19 , 653,3 , 643,6 , 45,4 , 5,17 , 22,23 , {73,78,82}, 117,1 , 16503,10 , 8,5 , 4,0 , 5206,4 , 2633,4 , 2, 1, 7, 7, 7 }, // Bodo/Devanagari/India - { 218, 2, 178, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 21292,48 , 11235,80 , 11152,24 , 21292,48 , 11235,80 , 11152,24 , 17949,25 , 17974,45 , 18019,17 , 17949,25 , 17974,45 , 17949,25 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {82,85,66}, 119,1 , 16513,43 , 13,5 , 4,0 , 5210,7 , 5217,5 , 2, 1, 1, 6, 7 }, // Chechen/Cyrillic/Russia - { 219, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 878,8 , 878,8 , 955,10 , 1644,23 , 37,5 , 8,10 , 32002,65 , 32067,117 , 32184,30 , 32002,65 , 32214,117 , 32184,30 , 18036,37 , 18073,68 , 11221,14 , 18036,37 , 18073,68 , 11221,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {82,85,66}, 119,1 , 16556,44 , 13,5 , 4,0 , 5222,19 , 5241,7 , 2, 1, 1, 6, 7 }, // Church/Cyrillic/Russia - { 220, 2, 178, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {82,85,66}, 119,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Chuvash/Cyrillic/Russia - { 230, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 32331,49 , 32380,99 , 32479,24 , 32331,49 , 32380,99 , 32479,24 , 18141,28 , 18169,50 , 18219,14 , 18141,28 , 18169,50 , 18219,14 , 656,5 , 649,6 , 45,4 , 5,17 , 22,23 , {67,68,70}, 203,2 , 16600,24 , 0,4 , 4,0 , 5248,8 , 5256,16 , 2, 1, 1, 6, 7 }, // Luba Katanga/Latin/Congo Kinshasa - { 231, 7, 125, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 886,10 , 886,10 , 174,8 , 593,18 , 37,5 , 8,10 , 32503,48 , 32551,85 , 134,24 , 32636,59 , 32551,85 , 134,24 , 18233,28 , 18261,65 , 3738,14 , 18326,35 , 18261,65 , 3738,14 , 661,5 , 655,8 , 452,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8384,19 , 13,5 , 4,0 , 5272,14 , 5286,10 , 2, 1, 1, 6, 7 }, // Luxembourgish/Latin/Luxembourg + { 208, 7, 132, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 32263,46 , 32309,88 , 32397,24 , 32263,46 , 32309,88 , 32397,24 , 17619,28 , 17647,53 , 17700,14 , 17619,28 , 17647,53 , 17700,14 , 634,6 , 621,6 , 45,4 , 5,17 , 22,23 , {88,79,70}, 204,3 , 16678,23 , 0,4 , 4,0 , 5259,11 , 5270,5 , 0, 0, 1, 6, 7 }, // Koyra Chiini/Latin/Mali + { 209, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 19304,48 , 29435,87 , 134,24 , 19304,48 , 29435,87 , 134,24 , 15669,28 , 15697,62 , 15759,14 , 15669,28 , 15697,62 , 15759,14 , 545,5 , 530,9 , 45,4 , 5,17 , 22,23 , {84,90,83}, 192,3 , 16265,27 , 0,4 , 4,0 , 5275,6 , 1616,8 , 2, 0, 1, 6, 7 }, // Rwa/Latin/Tanzania + { 210, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 32421,48 , 32469,186 , 32655,24 , 32421,48 , 32469,186 , 32655,24 , 17714,28 , 17742,69 , 17811,14 , 17714,28 , 17742,69 , 17811,14 , 640,2 , 627,2 , 45,4 , 5,17 , 22,23 , {75,69,83}, 2,3 , 16701,23 , 0,4 , 4,0 , 5281,6 , 1182,5 , 2, 1, 7, 6, 7 }, // Luo/Latin/Kenya + { 211, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 28909,48 , 28957,152 , 134,24 , 28909,48 , 28957,152 , 134,24 , 15429,28 , 15457,74 , 15531,14 , 15429,28 , 15457,74 , 15531,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,71,88}, 197,3 , 16210,26 , 4,4 , 4,0 , 5287,6 , 1681,6 , 0, 0, 1, 6, 7 }, // Chiga/Latin/Uganda + { 212, 7, 145, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 32679,48 , 32727,86 , 32813,24 , 32679,48 , 32727,86 , 32813,24 , 17825,28 , 17853,48 , 17901,14 , 17825,28 , 17853,48 , 17901,14 , 642,9 , 629,10 , 45,4 , 5,17 , 22,23 , {77,65,68}, 0,0 , 16724,22 , 13,5 , 4,0 , 5293,17 , 5310,6 , 2, 1, 1, 6, 7 }, // Central Morocco Tamazight/Latin/Morocco + { 213, 7, 132, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 32263,46 , 32309,88 , 32397,24 , 32263,46 , 32309,88 , 32397,24 , 17915,28 , 17943,54 , 17700,14 , 17915,28 , 17943,54 , 17700,14 , 634,6 , 621,6 , 45,4 , 5,17 , 22,23 , {88,79,70}, 204,3 , 16678,23 , 0,4 , 4,0 , 5316,15 , 5270,5 , 0, 0, 1, 6, 7 }, // Koyraboro Senni/Latin/Mali + { 214, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 19304,48 , 32837,84 , 134,24 , 19304,48 , 32837,84 , 134,24 , 17997,28 , 18025,63 , 18088,14 , 17997,28 , 18025,63 , 18088,14 , 651,5 , 639,8 , 45,4 , 5,17 , 22,23 , {84,90,83}, 192,3 , 16746,27 , 0,4 , 4,0 , 5331,9 , 1616,8 , 2, 0, 1, 6, 7 }, // Shambala/Latin/Tanzania + { 215, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 547,6 , 35,18 , 18,7 , 25,12 , 32921,88 , 32921,88 , 33009,31 , 32921,88 , 32921,88 , 33009,31 , 18102,33 , 18135,54 , 18189,19 , 18102,33 , 18135,54 , 18189,19 , 656,3 , 647,6 , 45,4 , 5,17 , 22,23 , {73,78,82}, 121,1 , 16773,10 , 8,5 , 4,0 , 5340,4 , 2633,4 , 2, 1, 7, 7, 7 }, // Bodo/Devanagari/India + { 218, 2, 178, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 22132,48 , 11141,80 , 11058,24 , 22132,48 , 11141,80 , 11058,24 , 18208,25 , 18233,45 , 18278,17 , 18208,25 , 18233,45 , 18208,25 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {82,85,66}, 123,1 , 16783,43 , 13,5 , 4,0 , 5344,7 , 5351,5 , 2, 1, 1, 6, 7 }, // Chechen/Cyrillic/Russia + { 219, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 937,8 , 937,8 , 993,10 , 1673,23 , 37,5 , 8,10 , 33040,65 , 33105,117 , 33222,30 , 33040,65 , 33252,117 , 33222,30 , 18295,37 , 18332,68 , 11472,14 , 18295,37 , 18332,68 , 11472,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {82,85,66}, 123,1 , 16826,44 , 13,5 , 4,0 , 5356,19 , 5375,7 , 2, 1, 1, 6, 7 }, // Church/Cyrillic/Russia + { 220, 2, 178, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {82,85,66}, 123,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Chuvash/Cyrillic/Russia + { 230, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 33369,49 , 33418,99 , 33517,24 , 33369,49 , 33418,99 , 33517,24 , 18400,28 , 18428,50 , 18478,14 , 18400,28 , 18428,50 , 18478,14 , 659,5 , 653,6 , 45,4 , 5,17 , 22,23 , {67,68,70}, 207,2 , 16870,24 , 0,4 , 4,0 , 5382,8 , 5390,16 , 2, 1, 1, 6, 7 }, // Luba Katanga/Latin/Congo Kinshasa + { 231, 7, 125, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 945,10 , 945,10 , 156,8 , 622,18 , 37,5 , 8,10 , 33541,48 , 33589,85 , 134,24 , 33674,59 , 33589,85 , 134,24 , 18492,28 , 18520,65 , 3668,14 , 18585,35 , 18520,65 , 3668,14 , 664,5 , 659,8 , 479,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 8384,19 , 13,5 , 4,0 , 5406,14 , 5420,10 , 2, 1, 1, 6, 7 }, // Luxembourgish/Latin/Luxembourg { 236, 7, 21, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Walloon/Latin/Belgium - { 237, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 32695,48 , 32743,195 , 32938,24 , 32695,48 , 32743,195 , 32938,24 , 18361,28 , 18389,72 , 18461,14 , 18361,28 , 18389,72 , 18461,14 , 666,3 , 663,3 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16624,21 , 0,4 , 4,0 , 5296,5 , 5301,7 , 0, 0, 1, 6, 7 }, // Aghem/Latin/Cameroon - { 238, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 32962,48 , 33010,90 , 33100,24 , 32962,48 , 33010,90 , 33100,24 , 18475,28 , 18503,70 , 18573,14 , 18475,28 , 18503,70 , 18573,14 , 669,10 , 666,9 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16645,22 , 13,5 , 4,0 , 5308,5 , 5313,8 , 0, 0, 1, 6, 7 }, // Basaa/Latin/Cameroon - { 239, 7, 156, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 31225,46 , 31271,88 , 31359,24 , 31225,46 , 31271,88 , 31359,24 , 17656,28 , 18587,53 , 18640,14 , 17656,28 , 18587,53 , 18640,14 , 679,8 , 675,10 , 45,4 , 5,17 , 22,23 , {88,79,70}, 200,3 , 16408,23 , 0,4 , 4,0 , 5321,10 , 5331,5 , 0, 0, 1, 6, 7 }, // Zarma/Latin/Niger - { 240, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 33124,49 , 33173,99 , 33272,24 , 33124,49 , 33173,99 , 33272,24 , 18654,28 , 18682,45 , 18727,14 , 18654,28 , 18682,45 , 18727,14 , 687,5 , 685,6 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 0,7 , 13,5 , 4,0 , 5336,5 , 1952,8 , 0, 0, 1, 6, 7 }, // Duala/Latin/Cameroon - { 241, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 33296,36 , 33332,82 , 33414,24 , 33296,36 , 33332,82 , 33414,24 , 18741,28 , 18769,50 , 18819,14 , 18741,28 , 18769,50 , 18819,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,79,70}, 200,3 , 16667,23 , 13,5 , 4,0 , 5341,5 , 5346,7 , 0, 0, 1, 6, 7 }, // Jola Fonyi/Latin/Senegal - { 242, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 33438,50 , 33488,141 , 33629,24 , 33438,50 , 33488,141 , 33629,24 , 18833,30 , 18863,85 , 18948,14 , 18833,30 , 18863,85 , 18948,14 , 692,7 , 691,9 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16690,23 , 13,5 , 4,0 , 5353,6 , 5359,7 , 0, 0, 1, 6, 7 }, // Ewondo/Latin/Cameroon - { 243, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 33653,39 , 33692,191 , 158,27 , 33653,39 , 33692,191 , 158,27 , 18962,29 , 18991,45 , 19036,14 , 18962,29 , 18991,45 , 19036,14 , 699,6 , 700,7 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16713,11 , 13,5 , 4,0 , 5366,5 , 5371,7 , 0, 0, 1, 6, 7 }, // Bafia/Latin/Cameroon - { 244, 7, 146, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 33883,48 , 33931,213 , 34144,24 , 33883,48 , 33931,213 , 34144,24 , 19050,28 , 19078,59 , 19137,14 , 19050,28 , 19078,59 , 19137,14 , 705,8 , 707,10 , 45,4 , 5,17 , 22,23 , {77,90,78}, 272,3 , 0,7 , 41,6 , 4,0 , 5378,5 , 5383,10 , 2, 1, 7, 6, 7 }, // Makhuwa Meetto/Latin/Mozambique - { 245, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 34168,48 , 34216,139 , 34355,24 , 34168,48 , 34216,139 , 34355,24 , 19151,28 , 19179,74 , 19253,14 , 19151,28 , 19179,74 , 19253,14 , 713,5 , 717,5 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16724,17 , 4,4 , 4,0 , 5393,6 , 5399,7 , 0, 0, 1, 6, 7 }, // Mundang/Latin/Cameroon - { 246, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 34379,51 , 34430,143 , 158,27 , 34379,51 , 34430,143 , 158,27 , 19267,30 , 19297,89 , 19386,14 , 19267,30 , 19297,89 , 19386,14 , 718,4 , 722,4 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16741,20 , 13,5 , 4,0 , 5406,6 , 5412,7 , 0, 0, 1, 6, 7 }, // Kwasio/Latin/Cameroon - { 247, 7, 254, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 1667,9 , 98,16 , 18,7 , 551,12 , 34573,54 , 34627,96 , 34723,24 , 34573,54 , 34627,96 , 34723,24 , 19400,38 , 19438,79 , 19517,14 , 19400,38 , 19438,79 , 19517,14 , 722,2 , 726,2 , 45,4 , 5,17 , 22,23 , {83,83,80}, 115,1 , 0,7 , 4,4 , 4,0 , 5419,9 , 0,0 , 2, 1, 1, 6, 7 }, // Nuer/Latin/South Sudan - { 248, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 896,11 , 896,11 , 245,6 , 1676,30 , 37,5 , 8,10 , 34747,50 , 34797,116 , 34913,24 , 34747,50 , 34937,121 , 34913,24 , 19531,21 , 19552,71 , 19623,14 , 19531,21 , 19552,71 , 19623,14 , 724,2 , 728,2 , 1117,5 , 1122,17 , 22,23 , {82,85,66}, 119,1 , 16761,47 , 13,5 , 4,0 , 5428,9 , 5437,9 , 2, 1, 1, 6, 7 }, // Sakha/Cyrillic/Russia - { 249, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 37,5 , 8,10 , 35058,48 , 35106,117 , 158,27 , 35058,48 , 35106,117 , 158,27 , 19637,28 , 19665,60 , 19725,14 , 19637,28 , 19665,60 , 19725,14 , 726,9 , 730,9 , 45,4 , 5,17 , 22,23 , {84,90,83}, 188,3 , 16808,25 , 0,4 , 4,0 , 5446,9 , 5455,9 , 0, 0, 1, 6, 7 }, // Sangu/Latin/Tanzania - { 251, 7, 156, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 31225,46 , 31271,88 , 31359,24 , 31225,46 , 31271,88 , 31359,24 , 17656,28 , 17684,54 , 17441,14 , 17656,28 , 17684,54 , 17441,14 , 679,8 , 675,10 , 45,4 , 5,17 , 22,23 , {88,79,70}, 200,3 , 16408,23 , 0,4 , 4,0 , 5464,13 , 5331,5 , 0, 0, 1, 6, 7 }, // Tasawaq/Latin/Niger - { 252, 35, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 18,7 , 25,12 , 35223,38 , 35261,61 , 158,27 , 35223,38 , 35261,61 , 158,27 , 19739,30 , 19739,30 , 85,14 , 19739,30 , 19739,30 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {76,82,68}, 6,1 , 16833,15 , 4,4 , 4,0 , 5477,2 , 5479,4 , 2, 1, 1, 6, 7 }, // Vai/Vai/Liberia - { 252, 7, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 120,10 , 10,17 , 18,7 , 25,12 , 35322,81 , 35322,81 , 158,27 , 35322,81 , 35322,81 , 158,27 , 19769,48 , 19769,48 , 85,14 , 19769,48 , 19769,48 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {76,82,68}, 6,1 , 16848,20 , 4,4 , 4,0 , 5483,3 , 5486,8 , 2, 1, 1, 6, 7 }, // Vai/Latin/Liberia - { 253, 7, 206, 44, 8217, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 269,9 , 269,9 , 53,10 , 593,18 , 37,5 , 8,10 , 35403,48 , 35451,99 , 35550,24 , 35403,48 , 35451,99 , 35550,24 , 19817,28 , 19845,53 , 19898,14 , 19817,28 , 19845,53 , 19898,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,72,70}, 0,0 , 0,7 , 41,6 , 4,0 , 5494,6 , 5500,6 , 2, 0, 1, 6, 7 }, // Walser/Latin/Switzerland - { 254, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 35574,51 , 35625,191 , 158,27 , 35574,51 , 35625,191 , 158,27 , 19912,21 , 19933,71 , 20004,14 , 19912,21 , 19933,71 , 20004,14 , 735,8 , 739,8 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 0,7 , 13,5 , 4,0 , 5506,6 , 5512,7 , 0, 0, 1, 6, 7 }, // Yangben/Latin/Cameroon - { 256, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 625,7 , 625,7 , 287,6 , 390,22 , 37,5 , 8,10 , 35816,48 , 35864,85 , 35949,24 , 35973,48 , 36021,117 , 35949,24 , 20018,28 , 20046,54 , 3434,14 , 20018,28 , 20046,54 , 3434,14 , 743,12 , 747,11 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 5519,9 , 2398,6 , 2, 1, 1, 6, 7 }, // Asturian/Latin/Spain - { 257, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 907,11 , 907,11 , 918,16 , 934,9 , 53,10 , 1497,18 , 37,5 , 8,10 , 36138,174 , 36138,174 , 158,27 , 36138,174 , 36138,174 , 158,27 , 20100,60 , 20100,60 , 20160,25 , 20100,60 , 20100,60 , 20160,25 , 755,8 , 758,13 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16868,12 , 8,5 , 4,0 , 5528,5 , 5533,7 , 0, 0, 1, 6, 7 }, // Ngomba/Latin/Cameroon - { 258, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 1706,10 , 686,17 , 37,5 , 8,10 , 36312,102 , 36312,102 , 158,27 , 36312,102 , 36312,102 , 158,27 , 20185,54 , 20185,54 , 20239,21 , 20185,54 , 20185,54 , 20239,21 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16880,16 , 41,6 , 4,0 , 5540,4 , 5544,7 , 0, 0, 1, 6, 7 }, // Kako/Latin/Cameroon - { 259, 7, 37, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 1497,18 , 37,5 , 8,10 , 36414,137 , 36551,142 , 36693,36 , 36414,137 , 36551,142 , 36693,36 , 20260,49 , 20260,49 , 20309,21 , 20260,49 , 20260,49 , 20309,21 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16896,12 , 8,5 , 4,0 , 5551,5 , 5556,7 , 0, 0, 1, 6, 7 }, // Meta/Latin/Cameroon - { 260, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1716,32 , 37,5 , 8,10 , 36729,165 , 36729,165 , 158,27 , 36729,165 , 36729,165 , 158,27 , 20330,111 , 20330,111 , 85,14 , 20330,111 , 20330,111 , 85,14 , 763,9 , 771,8 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16908,16 , 8,5 , 4,0 , 5563,16 , 5579,7 , 0, 0, 1, 6, 7 }, // Ngiemboon/Latin/Cameroon - { 290, 11, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,78,82}, 117,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 7, 7 }, // Manipuri/Bengali/India + { 237, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 33733,48 , 33781,195 , 33976,24 , 33733,48 , 33781,195 , 33976,24 , 18620,28 , 18648,72 , 18720,14 , 18620,28 , 18648,72 , 18720,14 , 669,3 , 667,3 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16894,21 , 0,4 , 4,0 , 5430,5 , 5435,7 , 0, 0, 1, 6, 7 }, // Aghem/Latin/Cameroon + { 238, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 34000,48 , 34048,90 , 34138,24 , 34000,48 , 34048,90 , 34138,24 , 18734,28 , 18762,70 , 18832,14 , 18734,28 , 18762,70 , 18832,14 , 672,10 , 670,9 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16915,22 , 13,5 , 4,0 , 5442,5 , 5447,8 , 0, 0, 1, 6, 7 }, // Basaa/Latin/Cameroon + { 239, 7, 156, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 32263,46 , 32309,88 , 32397,24 , 32263,46 , 32309,88 , 32397,24 , 17915,28 , 18846,53 , 18899,14 , 17915,28 , 18846,53 , 18899,14 , 682,8 , 679,10 , 45,4 , 5,17 , 22,23 , {88,79,70}, 204,3 , 16678,23 , 0,4 , 4,0 , 5455,10 , 5465,5 , 0, 0, 1, 6, 7 }, // Zarma/Latin/Niger + { 240, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 34162,49 , 34211,99 , 34310,24 , 34162,49 , 34211,99 , 34310,24 , 18913,28 , 18941,45 , 18986,14 , 18913,28 , 18941,45 , 18986,14 , 690,5 , 689,6 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 0,7 , 13,5 , 4,0 , 5470,5 , 1952,8 , 0, 0, 1, 6, 7 }, // Duala/Latin/Cameroon + { 241, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 34334,36 , 34370,82 , 34452,24 , 34334,36 , 34370,82 , 34452,24 , 19000,28 , 19028,50 , 19078,14 , 19000,28 , 19028,50 , 19078,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,79,70}, 204,3 , 16937,23 , 13,5 , 4,0 , 5475,5 , 5480,7 , 0, 0, 1, 6, 7 }, // Jola Fonyi/Latin/Senegal + { 242, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 34476,50 , 34526,141 , 34667,24 , 34476,50 , 34526,141 , 34667,24 , 19092,30 , 19122,85 , 19207,14 , 19092,30 , 19122,85 , 19207,14 , 695,7 , 695,9 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16960,23 , 13,5 , 4,0 , 5487,6 , 5493,7 , 0, 0, 1, 6, 7 }, // Ewondo/Latin/Cameroon + { 243, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 34691,39 , 34730,191 , 158,27 , 34691,39 , 34730,191 , 158,27 , 19221,29 , 19250,45 , 19295,14 , 19221,29 , 19250,45 , 19295,14 , 702,6 , 704,7 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16983,11 , 13,5 , 4,0 , 5500,5 , 5505,7 , 0, 0, 1, 6, 7 }, // Bafia/Latin/Cameroon + { 244, 7, 146, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 34921,48 , 34969,213 , 35182,24 , 34921,48 , 34969,213 , 35182,24 , 19309,28 , 19337,59 , 19396,14 , 19309,28 , 19337,59 , 19396,14 , 708,8 , 711,10 , 45,4 , 5,17 , 22,23 , {77,90,78}, 273,3 , 0,7 , 41,6 , 4,0 , 5512,5 , 5517,10 , 2, 1, 7, 6, 7 }, // Makhuwa Meetto/Latin/Mozambique + { 245, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 35206,48 , 35254,139 , 35393,24 , 35206,48 , 35254,139 , 35393,24 , 19410,28 , 19438,74 , 19512,14 , 19410,28 , 19438,74 , 19512,14 , 716,5 , 721,5 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 16994,17 , 4,4 , 4,0 , 5527,6 , 5533,7 , 0, 0, 1, 6, 7 }, // Mundang/Latin/Cameroon + { 246, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 35417,51 , 35468,143 , 158,27 , 35417,51 , 35468,143 , 158,27 , 19526,30 , 19556,89 , 19645,14 , 19526,30 , 19556,89 , 19645,14 , 721,4 , 726,4 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 17011,20 , 13,5 , 4,0 , 5540,6 , 5546,7 , 0, 0, 1, 6, 7 }, // Kwasio/Latin/Cameroon + { 247, 7, 254, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 538,9 , 97,16 , 18,7 , 555,12 , 35611,54 , 35665,96 , 35761,24 , 35611,54 , 35665,96 , 35761,24 , 19659,38 , 19697,79 , 19776,14 , 19659,38 , 19697,79 , 19776,14 , 725,2 , 730,2 , 45,4 , 5,17 , 22,23 , {83,83,80}, 119,1 , 0,7 , 4,4 , 4,0 , 5553,9 , 0,0 , 2, 1, 1, 6, 7 }, // Nuer/Latin/South Sudan + { 248, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 955,11 , 955,11 , 227,6 , 1696,30 , 37,5 , 8,10 , 35785,50 , 35835,116 , 35951,24 , 35785,50 , 35975,121 , 35951,24 , 19790,21 , 19811,71 , 19882,14 , 19790,21 , 19811,71 , 19882,14 , 727,2 , 732,2 , 1229,5 , 1234,17 , 22,23 , {82,85,66}, 123,1 , 17031,47 , 13,5 , 4,0 , 5562,9 , 5571,9 , 2, 1, 1, 6, 7 }, // Sakha/Cyrillic/Russia + { 249, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 37,5 , 8,10 , 36096,48 , 36144,117 , 158,27 , 36096,48 , 36144,117 , 158,27 , 19896,28 , 19924,60 , 19984,14 , 19896,28 , 19924,60 , 19984,14 , 729,9 , 734,9 , 45,4 , 5,17 , 22,23 , {84,90,83}, 192,3 , 17078,25 , 0,4 , 4,0 , 5580,9 , 5589,9 , 2, 0, 1, 6, 7 }, // Sangu/Latin/Tanzania + { 251, 7, 156, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 32263,46 , 32309,88 , 32397,24 , 32263,46 , 32309,88 , 32397,24 , 17915,28 , 17943,54 , 17700,14 , 17915,28 , 17943,54 , 17700,14 , 682,8 , 679,10 , 45,4 , 5,17 , 22,23 , {88,79,70}, 204,3 , 16678,23 , 0,4 , 4,0 , 5598,13 , 5465,5 , 0, 0, 1, 6, 7 }, // Tasawaq/Latin/Niger + { 252, 35, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 18,7 , 25,12 , 36261,38 , 36299,61 , 158,27 , 36261,38 , 36299,61 , 158,27 , 19998,30 , 19998,30 , 85,14 , 19998,30 , 19998,30 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {76,82,68}, 6,1 , 17103,15 , 4,4 , 4,0 , 5611,2 , 5613,4 , 2, 1, 1, 6, 7 }, // Vai/Vai/Liberia + { 252, 7, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 119,10 , 10,17 , 18,7 , 25,12 , 36360,81 , 36360,81 , 158,27 , 36360,81 , 36360,81 , 158,27 , 20028,48 , 20028,48 , 85,14 , 20028,48 , 20028,48 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {76,82,68}, 6,1 , 17118,20 , 4,4 , 4,0 , 5617,3 , 5620,8 , 2, 1, 1, 6, 7 }, // Vai/Latin/Liberia + { 253, 7, 206, 44, 8217, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 269,9 , 269,9 , 53,10 , 622,18 , 37,5 , 8,10 , 36441,48 , 36489,99 , 36588,24 , 36441,48 , 36489,99 , 36588,24 , 20076,28 , 20104,53 , 20157,14 , 20076,28 , 20104,53 , 20157,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,72,70}, 0,0 , 0,7 , 41,6 , 4,0 , 5628,6 , 5634,6 , 2, 0, 1, 6, 7 }, // Walser/Latin/Switzerland + { 254, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 36612,51 , 36663,191 , 158,27 , 36612,51 , 36663,191 , 158,27 , 20171,21 , 20192,71 , 20263,14 , 20171,21 , 20192,71 , 20263,14 , 738,8 , 743,8 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 0,7 , 13,5 , 4,0 , 5640,6 , 5646,7 , 0, 0, 1, 6, 7 }, // Yangben/Latin/Cameroon + { 256, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 675,7 , 675,7 , 269,6 , 372,22 , 37,5 , 8,10 , 36854,48 , 36902,85 , 36987,24 , 37011,48 , 37059,117 , 36987,24 , 20277,28 , 20305,54 , 3364,14 , 20277,28 , 20305,54 , 3364,14 , 746,12 , 751,11 , 0,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 3102,20 , 13,5 , 4,0 , 5653,9 , 2398,6 , 2, 1, 1, 6, 7 }, // Asturian/Latin/Spain + { 257, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 966,11 , 966,11 , 977,16 , 993,9 , 53,10 , 1526,18 , 37,5 , 8,10 , 37176,174 , 37176,174 , 158,27 , 37176,174 , 37176,174 , 158,27 , 20359,60 , 20359,60 , 20419,25 , 20359,60 , 20359,60 , 20419,25 , 758,8 , 762,13 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 17138,12 , 8,5 , 4,0 , 5662,5 , 5667,7 , 0, 0, 1, 6, 7 }, // Ngomba/Latin/Cameroon + { 258, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 1726,10 , 80,17 , 37,5 , 8,10 , 37350,102 , 37350,102 , 158,27 , 37350,102 , 37350,102 , 158,27 , 20444,54 , 20444,54 , 20498,21 , 20444,54 , 20444,54 , 20498,21 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 17150,16 , 41,6 , 4,0 , 5674,4 , 5678,7 , 0, 0, 1, 6, 7 }, // Kako/Latin/Cameroon + { 259, 7, 37, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 1526,18 , 37,5 , 8,10 , 37452,137 , 37589,142 , 37731,36 , 37452,137 , 37589,142 , 37731,36 , 20519,49 , 20519,49 , 20568,21 , 20519,49 , 20519,49 , 20568,21 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 17166,12 , 8,5 , 4,0 , 5685,5 , 5690,7 , 0, 0, 1, 6, 7 }, // Meta/Latin/Cameroon + { 260, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1736,32 , 37,5 , 8,10 , 37767,165 , 37767,165 , 158,27 , 37767,165 , 37767,165 , 158,27 , 20589,111 , 20589,111 , 85,14 , 20589,111 , 20589,111 , 85,14 , 766,9 , 775,8 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 17178,16 , 8,5 , 4,0 , 5697,16 , 5713,7 , 0, 0, 1, 6, 7 }, // Ngiemboon/Latin/Cameroon + { 290, 11, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,78,82}, 121,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 7, 7 }, // Manipuri/Bengali/India { 309, 100, 232, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {86,78,68}, 332,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 1, 6, 7 }, // Tai Dam/Tai Viet/Vietnam { 312, 7, 37, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 1, 6, 7 }, // Akoose/Latin/Cameroon - { 313, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 543,6 , 35,18 , 18,7 , 25,12 , 36894,180 , 36894,180 , 158,27 , 36894,180 , 36894,180 , 158,27 , 20441,87 , 20441,87 , 85,14 , 20441,87 , 20441,87 , 20528,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,83,68}, 6,1 , 0,7 , 41,6 , 4,0 , 5586,12 , 5598,22 , 2, 1, 7, 6, 7 }, // Lakota/Latin/United States - { 314, 9, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 433,8 , 98,16 , 37,5 , 8,10 , 27255,48 , 27303,81 , 27384,24 , 27255,48 , 27303,81 , 27384,24 , 14844,30 , 20542,48 , 85,14 , 14844,30 , 20542,48 , 85,14 , 516,6 , 494,8 , 45,4 , 5,17 , 22,23 , {77,65,68}, 0,0 , 15845,21 , 0,4 , 4,0 , 5620,8 , 4805,6 , 2, 1, 6, 5, 6 }, // Standard Moroccan Tamazight/Tifinagh/Morocco + { 313, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 547,6 , 35,18 , 18,7 , 25,12 , 37932,180 , 37932,180 , 158,27 , 37932,180 , 37932,180 , 158,27 , 20700,87 , 20700,87 , 85,14 , 20700,87 , 20700,87 , 20787,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {85,83,68}, 6,1 , 0,7 , 41,6 , 4,0 , 5720,12 , 5732,22 , 2, 1, 7, 6, 7 }, // Lakota/Latin/United States + { 314, 9, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 415,8 , 97,16 , 37,5 , 8,10 , 28293,48 , 28341,81 , 28422,24 , 28293,48 , 28341,81 , 28422,24 , 15103,30 , 20801,48 , 85,14 , 15103,30 , 20801,48 , 85,14 , 519,6 , 498,8 , 45,4 , 5,17 , 22,23 , {77,65,68}, 0,0 , 16115,21 , 0,4 , 4,0 , 5754,8 , 4939,6 , 2, 1, 1, 6, 7 }, // Standard Moroccan Tamazight/Tifinagh/Morocco { 315, 7, 43, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,76,80}, 6,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 1, 6, 7 }, // Mapuche/Latin/Chile - { 316, 1, 103, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 18,7 , 25,12 , 37074,105 , 37074,105 , 37179,24 , 37074,105 , 37074,105 , 37179,24 , 20590,58 , 20590,58 , 20648,14 , 20590,58 , 20590,58 , 20648,14 , 772,3 , 779,3 , 45,4 , 5,17 , 22,23 , {73,81,68}, 44,5 , 16924,20 , 13,5 , 4,0 , 5628,14 , 5642,5 , 0, 0, 6, 5, 6 }, // Central Kurdish/Arabic/Iraq - { 316, 1, 102, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 37074,105 , 37074,105 , 37179,24 , 37074,105 , 37074,105 , 37179,24 , 20590,58 , 20590,58 , 20648,14 , 20590,58 , 20590,58 , 20648,14 , 772,3 , 779,3 , 45,4 , 5,17 , 22,23 , {73,82,82}, 0,0 , 16944,19 , 13,5 , 4,0 , 5628,14 , 5647,5 , 0, 0, 6, 5, 5 }, // Central Kurdish/Arabic/Iran - { 317, 7, 82, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 185,7 , 185,7 , 114,6 , 593,18 , 55,4 , 59,9 , 37203,48 , 37251,85 , 16435,24 , 37336,60 , 37396,93 , 16435,24 , 20662,28 , 20690,53 , 20743,14 , 20662,28 , 20690,53 , 20743,14 , 775,9 , 782,10 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 16963,27 , 13,5 , 4,0 , 5652,14 , 5666,6 , 2, 1, 1, 6, 7 }, // Lower Sorbian/Latin/Germany - { 318, 7, 82, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 185,7 , 185,7 , 114,6 , 593,18 , 563,12 , 59,9 , 37489,48 , 37537,86 , 16435,24 , 37623,60 , 37683,93 , 16435,24 , 20757,28 , 20785,53 , 20838,14 , 20757,28 , 20785,53 , 20838,14 , 775,9 , 792,9 , 1139,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 16990,29 , 13,5 , 4,0 , 5672,15 , 5687,6 , 2, 1, 1, 6, 7 }, // Upper Sorbian/Latin/Germany + { 316, 1, 103, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 18,7 , 25,12 , 38112,105 , 38112,105 , 38217,24 , 38112,105 , 38112,105 , 38217,24 , 20849,58 , 20849,58 , 20907,14 , 20849,58 , 20849,58 , 20907,14 , 775,3 , 783,3 , 45,4 , 5,17 , 22,23 , {73,81,68}, 44,5 , 17194,20 , 13,5 , 4,0 , 5762,14 , 5776,5 , 0, 0, 6, 5, 6 }, // Central Kurdish/Arabic/Iraq + { 316, 1, 102, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 38112,105 , 38112,105 , 38217,24 , 38112,105 , 38112,105 , 38217,24 , 20849,58 , 20849,58 , 20907,14 , 20849,58 , 20849,58 , 20907,14 , 775,3 , 783,3 , 45,4 , 5,17 , 22,23 , {73,82,82}, 0,0 , 17214,19 , 13,5 , 4,0 , 5762,14 , 5781,5 , 0, 0, 6, 5, 5 }, // Central Kurdish/Arabic/Iran + { 317, 7, 82, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 185,7 , 185,7 , 113,6 , 622,18 , 55,4 , 59,9 , 38241,48 , 38289,85 , 9742,24 , 38374,60 , 38434,93 , 9742,24 , 20921,28 , 20949,53 , 21002,14 , 20921,28 , 20949,53 , 21002,14 , 778,9 , 786,10 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 17233,27 , 13,5 , 4,0 , 5786,14 , 5800,6 , 2, 1, 1, 6, 7 }, // Lower Sorbian/Latin/Germany + { 318, 7, 82, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 185,7 , 185,7 , 113,6 , 622,18 , 567,12 , 59,9 , 38527,48 , 38575,86 , 9742,24 , 38661,60 , 38721,93 , 9742,24 , 21016,28 , 21044,53 , 21097,14 , 21016,28 , 21044,53 , 21097,14 , 778,9 , 796,9 , 1251,5 , 5,17 , 22,23 , {69,85,82}, 14,1 , 17260,29 , 13,5 , 4,0 , 5806,15 , 5821,6 , 2, 1, 1, 6, 7 }, // Upper Sorbian/Latin/Germany { 319, 7, 37, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {88,65,70}, 32,4 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 1, 6, 7 }, // Kenyang/Latin/Cameroon - { 320, 7, 38, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,65,68}, 233,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 0, 7, 6, 7 }, // Mohawk/Latin/Canada - { 321, 75, 91, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {71,78,70}, 209,2 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 1, 6, 7 }, // Nko/Nko/Guinea - { 322, 7, 260, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8222, 8220, 0,6 , 0,6 , 943,8 , 943,8 , 174,8 , 1748,27 , 37,5 , 8,10 , 37776,48 , 37824,91 , 37915,24 , 37776,48 , 37824,91 , 37915,24 , 20852,28 , 20880,69 , 20949,14 , 20852,28 , 20880,69 , 20949,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {0,0,0}, 0,0 , 2586,0 , 13,5 , 4,0 , 5693,9 , 5702,6 , 2, 1, 1, 6, 7 }, // Prussian/Latin/World - { 323, 7, 90, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {71,84,81}, 299,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Kiche/Latin/Guatemala - { 324, 7, 205, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {83,69,75}, 186,2 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 0, 1, 6, 7 }, // Southern Sami/Latin/Sweden - { 325, 7, 205, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {83,69,75}, 186,2 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 0, 1, 6, 7 }, // Lule Sami/Latin/Sweden - { 326, 7, 73, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 611,8 , 1775,18 , 243,4 , 247,9 , 37939,77 , 38016,140 , 38156,25 , 37939,77 , 38016,140 , 38156,25 , 20963,28 , 20991,70 , 85,14 , 20963,28 , 21061,73 , 21134,14 , 784,3 , 801,3 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 17019,11 , 13,5 , 4,0 , 5708,11 , 5719,5 , 2, 1, 1, 6, 7 }, // Inari Sami/Latin/Finland + { 320, 7, 38, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {67,65,68}, 237,3 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 0, 7, 6, 7 }, // Mohawk/Latin/Canada + { 321, 75, 91, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {71,78,70}, 213,2 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 0, 0, 1, 6, 7 }, // Nko/Nko/Guinea + { 322, 7, 260, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8222, 8220, 0,6 , 0,6 , 1002,8 , 1002,8 , 156,8 , 1768,27 , 37,5 , 8,10 , 38814,48 , 38862,91 , 38953,24 , 38814,48 , 38862,91 , 38953,24 , 21111,28 , 21139,69 , 21208,14 , 21111,28 , 21139,69 , 21208,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {0,0,0}, 0,0 , 2586,0 , 13,5 , 4,0 , 5827,9 , 5836,6 , 2, 1, 1, 6, 7 }, // Prussian/Latin/World + { 323, 7, 90, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {71,84,81}, 300,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Kiche/Latin/Guatemala + { 324, 7, 205, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {83,69,75}, 190,2 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 0, 1, 6, 7 }, // Southern Sami/Latin/Sweden + { 325, 7, 205, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {83,69,75}, 190,2 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 0, 1, 6, 7 }, // Lule Sami/Latin/Sweden + { 326, 7, 73, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 640,8 , 1795,18 , 243,4 , 247,9 , 38977,77 , 39054,140 , 39194,25 , 38977,77 , 39054,140 , 39194,25 , 21222,28 , 21250,70 , 85,14 , 21222,28 , 21320,73 , 21393,14 , 787,3 , 805,3 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 17289,11 , 13,5 , 4,0 , 5842,11 , 5853,5 , 2, 1, 1, 6, 7 }, // Inari Sami/Latin/Finland { 327, 7, 73, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {69,85,82}, 14,1 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 1, 6, 7 }, // Skolt Sami/Latin/Finland { 328, 7, 13, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 368,48 , 368,48 , 158,27 , 368,48 , 368,48 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {65,85,68}, 336,2 , 0,7 , 8,5 , 4,0 , 0,0 , 0,0 , 2, 1, 7, 6, 7 }, // Warlpiri/Latin/Australia - { 346, 1, 102, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 14357,70 , 14357,70 , 158,27 , 14357,70 , 14357,70 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 653,4 , 657,39 , 22,23 , {73,82,82}, 338,3 , 17030,27 , 8,5 , 4,0 , 5724,7 , 3136,5 , 0, 0, 6, 5, 5 }, // Mazanderani/Arabic/Iran - { 349, 1, 102, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 38181,77 , 38181,77 , 158,27 , 38181,77 , 38181,77 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,82,82}, 0,0 , 0,7 , 8,5 , 4,0 , 5731,11 , 0,0 , 0, 0, 6, 5, 5 }, // Northern Luri/Arabic/Iran - { 349, 1, 103, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 18,7 , 25,12 , 38181,77 , 38181,77 , 158,27 , 38181,77 , 38181,77 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,81,68}, 44,5 , 0,7 , 8,5 , 4,0 , 5731,11 , 0,0 , 0, 0, 6, 5, 6 }, // Northern Luri/Arabic/Iraq - { 357, 6, 97, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 170,5 , 170,5 , 951,5 , 951,5 , 412,8 , 441,14 , 198,6 , 215,13 , 4671,39 , 4671,39 , 158,27 , 4671,39 , 4671,39 , 158,27 , 2023,28 , 2023,28 , 2051,14 , 2023,28 , 2023,28 , 2051,14 , 60,2 , 57,2 , 45,4 , 5,17 , 22,23 , {72,75,68}, 130,3 , 17057,11 , 4,4 , 4,0 , 5742,2 , 5744,14 , 2, 1, 7, 6, 7 }, // Cantonese/Traditional Han/Hong Kong - { 357, 5, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 170,5 , 170,5 , 951,5 , 951,5 , 412,8 , 420,13 , 198,6 , 204,11 , 4671,39 , 4710,38 , 158,27 , 4671,39 , 4710,38 , 158,27 , 2002,21 , 2023,28 , 2051,14 , 2002,21 , 2023,28 , 2051,14 , 60,2 , 57,2 , 45,4 , 5,17 , 22,23 , {67,78,89}, 129,1 , 3122,13 , 4,4 , 4,0 , 5758,2 , 5760,7 , 2, 1, 7, 6, 7 }, // Cantonese/Simplified Han/China + { 346, 1, 102, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 14934,70 , 14934,70 , 158,27 , 14934,70 , 14934,70 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 747,4 , 1256,39 , 22,23 , {73,82,82}, 338,3 , 17300,27 , 8,5 , 4,0 , 5858,7 , 3190,5 , 0, 0, 6, 5, 5 }, // Mazanderani/Arabic/Iran + { 349, 1, 102, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 37,5 , 8,10 , 39219,77 , 39219,77 , 158,27 , 39219,77 , 39219,77 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,82,82}, 0,0 , 0,7 , 8,5 , 4,0 , 5865,11 , 0,0 , 0, 0, 6, 5, 5 }, // Northern Luri/Arabic/Iran + { 349, 1, 103, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 53,10 , 63,17 , 18,7 , 25,12 , 39219,77 , 39219,77 , 158,27 , 39219,77 , 39219,77 , 158,27 , 0,28 , 0,28 , 85,14 , 0,28 , 0,28 , 85,14 , 0,2 , 0,2 , 45,4 , 5,17 , 22,23 , {73,81,68}, 44,5 , 0,7 , 8,5 , 4,0 , 5865,11 , 0,0 , 0, 0, 6, 5, 6 }, // Northern Luri/Arabic/Iraq + { 357, 6, 97, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 170,5 , 170,5 , 1010,5 , 1010,5 , 394,8 , 423,14 , 198,6 , 215,13 , 4423,39 , 4423,39 , 158,27 , 4423,39 , 4423,39 , 158,27 , 1953,28 , 1953,28 , 1981,14 , 1953,28 , 1953,28 , 1981,14 , 58,2 , 55,2 , 45,4 , 5,17 , 22,23 , {72,75,68}, 134,3 , 17327,11 , 4,4 , 4,0 , 5876,2 , 5878,14 , 2, 1, 7, 6, 7 }, // Cantonese/Traditional Han/Hong Kong + { 357, 5, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 170,5 , 170,5 , 1010,5 , 1010,5 , 394,8 , 402,13 , 198,6 , 204,11 , 4423,39 , 4462,38 , 158,27 , 4423,39 , 4462,38 , 158,27 , 1932,21 , 1953,28 , 1981,14 , 1932,21 , 1953,28 , 1981,14 , 58,2 , 55,2 , 45,4 , 5,17 , 22,23 , {67,78,89}, 133,1 , 3122,13 , 4,4 , 4,0 , 5892,2 , 5894,7 , 2, 1, 7, 6, 7 }, // Cantonese/Simplified Han/China { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, {0,0,0}, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0, 0, 0, 0, 0 } // trailing 0s }; @@ -1845,36 +1855,39 @@ static const ushort list_pattern_part_data[] = { 0x20, 0xa85, 0xaa8, 0xac7, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x5d5, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x914, 0x930, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x914, 0x930, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xe9, 0x73, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x64, 0x61, 0x6e, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x64, 0x61, 0x6e, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, -0x20, 0x61, 0x67, 0x75, 0x73, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0xcae, 0xca4, 0xccd, 0xca4, 0xcc1, 0x20, 0x25, 0x32, -0x25, 0x31, 0x20, 0xcae, 0xca4, 0xccd, 0xca4, 0xcc1, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x436, 0x4d9, 0x43d, 0x435, 0x20, 0x25, -0x32, 0x25, 0x31, 0x20, 0x436, 0x430, 0x43d, 0x430, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xbc0f, 0x20, 0x25, 0x32, 0x25, 0x31, -0x20, 0xec1, 0xea5, 0xeb0, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x75, 0x6e, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x6d, 0x70, -0xe9, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x69, 0x72, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x25, 0x32, 0x20, 0xd0e, -0xd28, 0xd4d, 0xd28, 0xd3f, 0xd35, 0x25, 0x31, 0x20, 0xd15, 0xd42, 0xd1f, 0xd3e, 0xd24, 0xd46, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, -0x20, 0x75, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x75, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x906, 0x923, 0x93f, 0x20, 0x25, -0x32, 0x25, 0x31, 0x2c, 0x25, 0x32, 0x25, 0x31, 0x20, 0x930, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0xb13, 0x20, 0x25, -0x32, 0x25, 0x31, 0x20, 0xb13, 0x20, 0x25, 0x32, 0x25, 0x31, 0x60c, 0x20, 0x627, 0x648, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, -0x627, 0x648, 0x20, 0x25, 0x32, 0x25, 0x31, 0x60c, 0x200f, 0x20, 0x25, 0x32, 0x25, 0x31, 0x60c, 0x20, 0x648, 0x20, 0x25, 0x32, -0x25, 0x31, 0x20, 0x648, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xa05, 0xa24, 0xa47, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x219, -0x69, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x4d5, 0x43c, 0x4d5, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0xdc3, 0xdc4, 0x20, -0x25, 0x32, 0x25, 0x31, 0x20, 0xdc3, 0xdc4, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x61, 0xa0, 0x25, 0x32, 0x25, 0x31, 0x20, -0x69, 0x6e, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x79, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x6e, 0x61, 0x20, 0x25, 0x32, -0x25, 0x31, 0x20, 0x6f, 0x63, 0x68, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xbae, 0xbb1, 0xbcd, 0xbb1, 0xbc1, 0xbae, 0xbcd, 0x20, -0x25, 0x32, 0x25, 0x31, 0x20, 0x4bb, 0x4d9, 0x43c, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xc2e, 0xc30, 0xc3f, 0xc2f, 0xc41, 0x20, -0x25, 0x32, 0x25, 0x31, 0x20, 0xe41, 0xe25, 0xe30, 0x25, 0x32, 0x25, 0x31, 0xe41, 0xe25, 0xe30, 0x25, 0x32, 0x25, 0x31, 0x20, -0x6d, 0x6f, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x76, 0x65, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x77, 0x65, 0x20, 0x25, -0x32, 0x25, 0x31, 0x60c, 0x20, 0x627, 0x648, 0x631, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x627, 0x648, 0x631, 0x20, 0x25, 0x32, -0x25, 0x32, 0x60c, 0x20, 0x25, 0x31, 0x25, 0x31, 0x20, 0x76, 0x61, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x76, 0xe0, 0x20, -0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x61, 0x28, 0x63, 0x29, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x61, 0x28, 0x63, 0x29, -0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x5d0, 0x5d5, 0x5df, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x6e, 0x65, 0x2d, 0x25, -0x32, 0x25, 0x31, 0x20, 0x6e, 0x65, 0x2d, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x6b, 0x70, 0x6c, 0x65, 0x20, 0x25, 0x32, -0x25, 0x31, 0x20, 0x6b, 0x70, 0x6c, 0x65, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x61, 0x74, 0x20, 0x25, 0x32, 0x25, -0x31, 0x20, 0x61, 0x74, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x61, 0x6b, 0x6b, 0x65, 0x64, 0x20, 0x25, 0x32, 0x25, -0x31, 0x20, 0x61, 0x6b, 0x6b, 0x65, 0x64, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x13a0, 0x13b4, 0x20, 0x25, 0x32, 0x25, 0x31, -0x20, 0x438, 0x486, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x61, 0x28, 0x6e, 0x29, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x443, -0x43e, 0x43d, 0x43d, 0x430, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x14b, 0x301, 0x67, 0x25b, 0x20, 0x25, 0x32, 0x25, 0x31, -0x2c, 0x20, 0x1e3f, 0x62, 0x25b, 0x6e, 0x20, 0x14b, 0x301, 0x67, 0x25b, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x70, 0x254, 0x70, -0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x62, 0x65, 0x20, 0x25, 0x32, 0x25, 0x31, 0x540c, 0x25, 0x32 +0x20, 0x61, 0x67, 0x75, 0x73, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x6c, 0x61, 0x6e, 0x20, 0x25, 0x32, 0x25, 0x31, +0x20, 0x6c, 0x61, 0x6e, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0xcae, 0xca4, 0xccd, 0xca4, 0xcc1, 0x20, 0x25, 0x32, 0x25, +0x31, 0x20, 0xcae, 0xca4, 0xccd, 0xca4, 0xcc1, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x436, 0x4d9, 0x43d, 0x435, 0x20, 0x25, 0x32, +0x25, 0x31, 0x20, 0x436, 0x430, 0x43d, 0x430, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xbc0f, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, +0xfb, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xec1, 0xea5, 0xeb0, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x75, 0x6e, 0x20, 0x25, +0x32, 0x25, 0x31, 0x20, 0x6d, 0x70, 0xe9, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x69, 0x72, 0x20, 0x25, 0x32, 0x25, 0x31, +0x2c, 0x20, 0x25, 0x32, 0x20, 0xd0e, 0xd28, 0xd4d, 0xd28, 0xd3f, 0xd35, 0x25, 0x31, 0x20, 0xd15, 0xd42, 0xd1f, 0xd3e, 0xd24, 0xd46, +0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x75, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x75, 0x20, 0x25, 0x32, 0x25, 0x31, +0x20, 0x906, 0x923, 0x93f, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x25, 0x32, 0x25, 0x31, 0x20, 0x930, 0x20, 0x25, 0x32, 0x25, +0x31, 0x2c, 0x20, 0xb13, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xb13, 0x20, 0x25, 0x32, 0x25, 0x31, 0x60c, 0x20, 0x627, 0x648, +0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x627, 0x648, 0x20, 0x25, 0x32, 0x25, 0x31, 0x60c, 0x200f, 0x20, 0x25, 0x32, 0x25, 0x31, +0x60c, 0x20, 0x648, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x648, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xa05, 0xa24, 0xa47, 0x20, +0x25, 0x32, 0x25, 0x31, 0x20, 0x219, 0x69, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x4d5, 0x43c, 0x4d5, 0x20, 0x25, 0x32, 0x25, +0x31, 0x60c, 0x20, 0x6fd, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x6fd, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0xdc3, 0xdc4, +0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xdc3, 0xdc4, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x61, 0xa0, 0x25, 0x32, 0x25, 0x31, +0x20, 0x69, 0x6e, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x69, 0x79, 0x6f, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x79, 0x20, +0x25, 0x32, 0x25, 0x31, 0x20, 0x6e, 0x61, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x6f, 0x63, 0x68, 0x20, 0x25, 0x32, 0x25, +0x31, 0x20, 0xbae, 0xbb1, 0xbcd, 0xbb1, 0xbc1, 0xbae, 0xbcd, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x4bb, 0x4d9, 0x43c, 0x20, 0x25, +0x32, 0x25, 0x31, 0x20, 0xc2e, 0xc30, 0xc3f, 0xc2f, 0xc41, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xe41, 0xe25, 0xe30, 0x25, 0x32, +0x25, 0x31, 0xe41, 0xe25, 0xe30, 0x25, 0x32, 0x25, 0x31, 0x20, 0x6d, 0x6f, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x76, 0x65, +0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x77, 0x65, 0x20, 0x25, 0x32, 0x25, 0x31, 0x60c, 0x20, 0x627, 0x648, 0x631, 0x20, 0x25, +0x32, 0x25, 0x31, 0x20, 0x627, 0x648, 0x631, 0x20, 0x25, 0x32, 0x25, 0x32, 0x60c, 0x20, 0x25, 0x31, 0x25, 0x31, 0x20, 0x76, +0x61, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x76, 0xe0, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x61, 0x28, 0x63, 0x29, +0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x61, 0x28, 0x63, 0x29, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x5d0, 0x5d5, 0x5df, 0x20, +0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x6e, 0x65, 0x2d, 0x25, 0x32, 0x25, 0x31, 0x20, 0x6e, 0x65, 0x2d, 0x25, 0x32, 0x25, +0x31, 0x2c, 0x20, 0x6b, 0x70, 0x6c, 0x65, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x6b, 0x70, 0x6c, 0x65, 0x20, 0x25, 0x32, +0x25, 0x31, 0x2c, 0x20, 0x61, 0x74, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x61, 0x74, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, +0x20, 0x61, 0x6b, 0x6b, 0x65, 0x64, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x61, 0x6b, 0x6b, 0x65, 0x64, 0x20, 0x25, 0x32, +0x25, 0x31, 0x2c, 0x20, 0x13a0, 0x13b4, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x13a0, 0x13b4, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, +0x438, 0x486, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x61, 0x28, 0x6e, 0x29, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x443, 0x43e, +0x43d, 0x43d, 0x430, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x14b, 0x301, 0x67, 0x25b, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, +0x20, 0x1e3f, 0x62, 0x25b, 0x6e, 0x20, 0x14b, 0x301, 0x67, 0x25b, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x70, 0x254, 0x70, 0x20, +0x25, 0x32, 0x25, 0x31, 0x20, 0x62, 0x65, 0x20, 0x25, 0x32, 0x25, 0x31, 0x540c, 0x25, 0x32 }; static const ushort date_format_data[] = { @@ -1882,86 +1895,87 @@ static const ushort date_format_data[] = { 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x2f, 0x4d, 0x4d, 0x2f, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2d, 0x4d, 0x4d, 0x2d, 0x64, 0x64, 0x79, 0x79, 0x79, 0x79, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, -0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, -0x64, 0x64, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2e, 0x4d, 0x2e, 0x79, 0x79, -0x64, 0x64, 0x2f, 0x4d, 0x4d, 0x2f, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x1363, 0x64, 0x20, 0x4d, 0x4d, -0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x200f, 0x2f, 0x4d, 0x200f, 0x2f, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, -0x64, 0x60c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x2e, 0x4d, 0x4d, 0x2e, -0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x20, 0x569, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x2c, 0x20, 0x64, 0x64, -0x64, 0x64, 0x64, 0x2d, 0x4d, 0x2d, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d, -0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x2c, -0x20, 0x64, 0x64, 0x64, 0x64, 0x79, 0x79, 0x2f, 0x4d, 0x2f, 0x64, 0x79, 0x79, 0x79, 0x79, 0x28, 0x27, 0x65, 0x27, 0x29, -0x27, 0x6b, 0x6f, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x27, 0x72, 0x65, 0x6e, 0x27, 0x20, 0x64, 0x28, 0x27, 0x61, 0x27, -0x29, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2f, 0x4d, 0x2f, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0xf66, -0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf63, 0xf7c, 0xf0b, 0x79, 0x79, 0x79, 0x79, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0xf5a, 0xf7a, 0xf66, -0xf0b, 0x64, 0x64, 0x64, 0x2e, 0x4d, 0x4d, 0x2e, 0x79, 0x79, 0x20, 0x27, 0x433, 0x27, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, -0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x433, 0x27, 0x2e, 0x64, 0x64, 0x2d, -0x4d, 0x4d, 0x2d, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x104a, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x104a, 0x20, 0x64, -0x64, 0x64, 0x64, 0x64, 0x2e, 0x4d, 0x4d, 0x2e, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d, -0x4d, 0x4d, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2f, 0x4d, 0x2f, 0x64, -0x79, 0x79, 0x79, 0x79, 0x5e74, 0x4d, 0x6708, 0x64, 0x65e5, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2f, 0x4d, 0x2f, 0x79, 0x79, 0x79, -0x79, 0x79, 0x79, 0x79, 0x79, 0x5e74, 0x4d, 0x6708, 0x64, 0x65e5, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2e, 0x20, 0x4d, -0x4d, 0x2e, 0x20, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, -0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x64, 0x2e, 0x20, 0x4d, 0x2e, 0x20, 0x79, 0x79, 0x2e, 0x64, 0x64, 0x64, 0x64, -0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x27, 0x64, -0x65, 0x6e, 0x27, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2f, 0x4d, 0x4d, -0x2f, 0x79, 0x79, 0x4d, 0x2f, 0x64, 0x2f, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2f, 0x4d, 0x4d, 0x2f, 0x64, 0x64, 0x79, -0x79, 0x2d, 0x4d, 0x4d, 0x2d, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x2d, 0x27, 0x61, 0x27, 0x20, 0x27, -0x64, 0x65, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, -0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2e, 0x4d, 0x2e, 0x79, 0x79, 0x79, 0x79, 0x64, -0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x27, 0x6d, 0x68, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, -0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64, -0x65, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, -0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, -0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x5d1, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, -0x79, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x20, 0x4d, 0x4d, 0x2e, 0x20, 0x64, 0x64, 0x2e, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x20, -0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x2e, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x436, -0x27, 0x2e, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x79, 0x79, 0x79, 0x79, 0x2d, -0x27, 0x436, 0x27, 0x2e, 0x2c, 0x20, 0x64, 0x2d, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x79, 0x79, -0x2e, 0x20, 0x4d, 0x2e, 0x20, 0x64, 0x2e, 0x79, 0x79, 0x79, 0x79, 0xb144, 0x20, 0x4d, 0xc6d4, 0x20, 0x64, 0xc77c, 0x20, 0x64, -0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x20, 0xe97, 0xeb5, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, -0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x20, 0x27, 0x67, 0x61, 0x64, 0x61, 0x27, -0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x6d, 0x27, 0x2e, 0x20, 0x4d, 0x4d, -0x4d, 0x4d, 0x20, 0x64, 0x20, 0x27, 0x64, 0x27, 0x2e, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2e, 0x4d, 0x2e, -0x79, 0x79, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2c, 0x20, -0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, -0x27, 0x74, 0x61, 0x27, 0x2019, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2e, -0x4d, 0x4d, 0x2e, 0x64, 0x64, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x4d, 0x4d, 0x2e, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x64, -0x64, 0x64, 0x64, 0x2e, 0x4d, 0x4d, 0x2e, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x62f, 0x20, 0x79, 0x79, -0x79, 0x79, 0x20, 0x62f, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x27, 0x69, 0x6c, -0x73, 0x27, 0x20, 0x64, 0x20, 0x27, 0x64, 0x61, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, -0x2e, 0x4d, 0x2e, 0x79, 0x79, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, -0x20, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, -0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x430, 0x437, 0x27, 0x64, 0x2e, 0x20, 0x4d, 0x2e, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, -0x2e, 0x20, 0x4d, 0x4d, 0x2e, 0x20, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x2e, 0x20, 0x4d, 0x4d, -0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x64, -0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x64, 0x64, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x4d, -0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x4d, 0x4d, 0x2f, 0x64, 0x64, 0x2f, 0x79, -0x79, 0x64, 0x64, 0x2d, 0x4d, 0x4d, 0x2d, 0x79, 0x79, 0x79, 0x79, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x79, -0x79, 0x79, 0x79, 0x20, 0x27, 0x435, 0x43b, 0x27, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x4d, 0x4d, 0x4d, -0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0xe17, 0xe35, 0xe48, 0x20, -0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, -0xf60, 0xf72, 0xf0b, 0xf5a, 0xf7a, 0xf66, 0xf0b, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x1363, 0x20, -0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x1218, 0x12d3, 0x120d, 0x1272, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2e, 0x4d, -0x4d, 0x2e, 0x79, 0x79, 0x79, 0x79, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x64, 0x64, -0x64, 0x64, 0x79, 0x79, 0x79, 0x79, 0x20, 0x64, 0x2d, 0x4d, 0x4d, 0x4d, 0x4d, 0x60c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, -0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x440, 0x27, -0x2e, 0x64, 0x64, 0x64, 0x64, 0x60c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x60c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, -0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x2d, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, -0x79, 0x20, 0x646, 0x686, 0x6cc, 0x20, 0x6cc, 0x6cc, 0x644, 0x20, 0x64, 0x20, 0x646, 0x686, 0x6cc, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, -0x20, 0x64, 0x64, 0x64, 0x64, 0x20, 0x6a9, 0x648, 0x646, 0x6cc, 0x79, 0x79, 0x79, 0x79, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x27, -0x61, 0x27, 0x20, 0x27, 0x64, 0x27, 0x2e, 0x20, 0x64, 0x27, 0x69, 0x64, 0x27, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, -0x20, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x5d8, 0x5df, 0x20, -0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2f, 0x4d, 0x4d, 0x2f, 0x64, 0x64, 0x64, 0x64, 0x64, -0x64, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x64, 0x64, 0x2d, 0x4d, 0x2d, 0x79, -0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x64, 0x20, 0x27, 0x64, 0x69, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64, -0x61, 0x6c, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, -0x20, 0x27, 0x6c, 0x69, 0x61, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x27, 0x64, 0x65, -0x27, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, -0x64, 0x20, 0x27, 0x64, 0x69, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64, 0x69, 0x27, 0x20, 0x79, 0x79, 0x79, -0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x27, 0x64, 0xe4, 0x27, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, -0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x43b, 0x27, -0x2e, 0x20, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x64, 0x2f, 0x4d, 0x4d, 0x2f, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, +0x64, 0x64, 0x64, 0x64, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, +0x64, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2e, 0x4d, 0x2e, 0x79, 0x79, 0x64, +0x64, 0x2f, 0x4d, 0x4d, 0x2f, 0x79, 0x79, 0x79, 0x79, 0x64, 0x200f, 0x2f, 0x4d, 0x200f, 0x2f, 0x79, 0x79, 0x79, 0x79, 0x64, +0x64, 0x64, 0x64, 0x60c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x2e, 0x4d, +0x4d, 0x2e, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x20, 0x569, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x2c, 0x20, +0x64, 0x64, 0x64, 0x64, 0x64, 0x2d, 0x4d, 0x2d, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, +0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, +0x79, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x79, 0x79, 0x2f, 0x4d, 0x2f, 0x64, 0x79, 0x79, 0x79, 0x79, 0x28, 0x27, 0x65, +0x27, 0x29, 0x27, 0x6b, 0x6f, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x27, 0x72, 0x65, 0x6e, 0x27, 0x20, 0x64, 0x28, 0x27, +0x61, 0x27, 0x29, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2f, 0x4d, 0x2f, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, +0x20, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf63, 0xf7c, 0xf0b, 0x79, 0x79, 0x79, 0x79, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0xf5a, +0xf7a, 0xf66, 0xf0b, 0x64, 0x64, 0x64, 0x2e, 0x4d, 0x4d, 0x2e, 0x79, 0x79, 0x20, 0x27, 0x433, 0x27, 0x2e, 0x64, 0x64, 0x64, +0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x433, 0x27, 0x2e, 0x64, +0x64, 0x2d, 0x4d, 0x4d, 0x2d, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x104a, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x104a, +0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2e, 0x4d, 0x4d, 0x2e, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, +0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2f, 0x4d, +0x2f, 0x64, 0x79, 0x79, 0x79, 0x79, 0x5e74, 0x4d, 0x6708, 0x64, 0x65e5, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2f, 0x4d, 0x2f, 0x79, +0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x5e74, 0x4d, 0x6708, 0x64, 0x65e5, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2e, +0x20, 0x4d, 0x4d, 0x2e, 0x20, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x2e, 0x20, 0x4d, +0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x64, 0x2e, 0x20, 0x4d, 0x2e, 0x20, 0x79, 0x79, 0x2e, 0x64, 0x64, +0x64, 0x64, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x2e, 0x4d, 0x4d, +0x2e, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x27, 0x64, 0x65, 0x6e, 0x27, 0x20, 0x64, 0x2e, 0x20, 0x4d, +0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x2d, 0x4d, 0x4d, 0x2d, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2f, +0x4d, 0x4d, 0x2f, 0x79, 0x79, 0x79, 0x79, 0x4d, 0x2f, 0x64, 0x2f, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, +0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2f, 0x4d, 0x4d, 0x2f, 0x79, 0x79, 0x79, 0x79, +0x79, 0x79, 0x2f, 0x4d, 0x4d, 0x2f, 0x64, 0x64, 0x79, 0x79, 0x2d, 0x4d, 0x4d, 0x2d, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, +0x2c, 0x20, 0x64, 0x2d, 0x27, 0x61, 0x27, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, +0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, +0x64, 0x2e, 0x4d, 0x2e, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x27, 0x6d, 0x68, 0x27, 0x20, +0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x27, 0x64, 0x65, +0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, +0x2c, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, +0x20, 0x64, 0x20, 0x5d1, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x20, 0x4d, +0x4d, 0x2e, 0x20, 0x64, 0x64, 0x2e, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x2e, 0x2c, +0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x20, 0x27, 0x6c, 0x65, 0x27, 0x20, 0x64, 0x20, 0x27, 0x64, 0x65, +0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x436, 0x27, 0x2e, +0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x79, 0x79, 0x79, 0x79, 0x2d, 0x27, 0x436, +0x27, 0x2e, 0x2c, 0x20, 0x64, 0x2d, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x79, 0x79, 0x2e, 0x20, +0x4d, 0x2e, 0x20, 0x64, 0x2e, 0x79, 0x79, 0x79, 0x79, 0xb144, 0x20, 0x4d, 0xc6d4, 0x20, 0x64, 0xc77c, 0x20, 0x64, 0x64, 0x64, +0x64, 0x64, 0x64, 0x64, 0x64, 0x20, 0xe97, 0xeb5, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, +0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x20, 0x27, 0x67, 0x61, 0x64, 0x61, 0x27, 0x20, 0x64, +0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x6d, 0x27, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, +0x20, 0x64, 0x20, 0x27, 0x64, 0x27, 0x2e, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2e, 0x4d, 0x2e, 0x79, 0x79, +0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2c, 0x20, 0x4d, 0x4d, +0x4d, 0x4d, 0x20, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x27, 0x74, +0x61, 0x27, 0x2019, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x4d, 0x4d, +0x2e, 0x64, 0x64, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x4d, 0x4d, 0x2e, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, +0x64, 0x64, 0x64, 0x20, 0x62f, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x62f, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x64, +0x64, 0x64, 0x64, 0x2c, 0x20, 0x27, 0x69, 0x6c, 0x73, 0x27, 0x20, 0x64, 0x20, 0x27, 0x64, 0x61, 0x27, 0x20, 0x4d, 0x4d, +0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2e, 0x4d, 0x2e, 0x79, 0x79, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, +0x64, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, +0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x430, 0x437, 0x27, 0x64, 0x2e, 0x20, +0x4d, 0x2e, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x2e, 0x20, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, +0x2c, 0x20, 0x64, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, +0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x64, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x64, +0x64, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x79, 0x79, 0x79, +0x79, 0x4d, 0x4d, 0x2f, 0x64, 0x64, 0x2f, 0x79, 0x79, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, +0x79, 0x20, 0x27, 0x435, 0x43b, 0x27, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, +0x79, 0x79, 0x79, 0x79, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0xe17, 0xe35, 0xe48, 0x20, 0x64, 0x20, +0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0xf60, 0xf72, +0xf0b, 0xf5a, 0xf7a, 0xf66, 0xf0b, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x1363, 0x20, 0x64, 0x64, +0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x1218, 0x12d3, 0x120d, 0x1272, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2e, 0x4d, 0x4d, 0x2e, +0x79, 0x79, 0x79, 0x79, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x64, 0x64, 0x64, 0x64, +0x79, 0x79, 0x79, 0x79, 0x20, 0x64, 0x2d, 0x4d, 0x4d, 0x4d, 0x4d, 0x60c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, +0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x440, 0x27, 0x2e, 0x64, +0x64, 0x64, 0x64, 0x60c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x60c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, +0x64, 0x2c, 0x20, 0x64, 0x2d, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x20, +0x646, 0x686, 0x6cc, 0x20, 0x6cc, 0x6cc, 0x644, 0x20, 0x64, 0x20, 0x646, 0x686, 0x6cc, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, +0x64, 0x64, 0x64, 0x20, 0x6a9, 0x648, 0x646, 0x6cc, 0x79, 0x79, 0x79, 0x79, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x27, 0x61, 0x27, +0x20, 0x27, 0x64, 0x27, 0x2e, 0x20, 0x64, 0x27, 0x69, 0x64, 0x27, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, +0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x5d8, 0x5df, 0x20, 0x4d, 0x4d, +0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2e, 0x20, 0x4d, 0x2e, 0x20, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x79, 0x79, +0x2f, 0x4d, 0x4d, 0x2f, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x4d, 0x4d, 0x4d, +0x4d, 0x20, 0x64, 0x64, 0x64, 0x2d, 0x4d, 0x2d, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x64, 0x20, 0x27, 0x64, 0x69, +0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64, 0x61, 0x6c, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, +0x64, 0x2c, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x20, 0x27, 0x6c, 0x69, 0x61, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, +0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, +0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x27, 0x64, 0x69, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, +0x20, 0x27, 0x64, 0x69, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x27, 0x64, 0xe4, 0x27, +0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, +0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x43b, 0x27, 0x2e, 0x20, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x441, 0x44b, 0x43b, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x20, 0x27, 0x43a, 0x4af, 0x43d, 0x44d, 0x27, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2f, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x2c, 0x20, 0x27, 0x6c, 0x79, 0x25b, 0x27, 0x30c, 0x2bc, 0x20, 0x64, 0x20, 0x27, 0x6e, 0x61, 0x27, 0x20, 0x4d, 0x4d, @@ -1992,14 +2006,14 @@ static const ushort time_format_data[] = { 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x41, 0x50, 0x20, 0x74, 0x48, 0x6642, 0x6d, 0x6d, 0x5206, 0x73, 0x73, 0x79d2, 0x20, 0x74, 0x41, 0x50, 0x20, 0x68, 0x3a, 0x6d, 0x6d, 0x41, 0x50, 0x20, 0x68, 0xc2dc, 0x20, 0x6d, 0xbd84, 0x20, 0x73, 0xcd08, 0x20, 0x74, 0x48, 0x20, 0xec2, 0xea1, 0xe87, 0x20, 0x6d, 0x20, 0xe99, 0xeb2, 0xe97, 0xeb5, 0x20, 0x73, 0x73, 0x20, 0xea7, 0xeb4, -0xe99, 0xeb2, 0xe97, 0xeb5, 0x20, 0x74, 0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x28, 0x74, 0x29, 0x27, 0x6b, 0x6c, -0x27, 0x2e, 0x20, 0x48, 0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x74, 0x41, 0x50, 0x20, 0x68, 0x3a, 0x6d, 0x6d, -0x3a, 0x73, 0x73, 0x20, 0x74, 0x48, 0x20, 0xe19, 0xe32, 0xe2c, 0xe34, 0xe01, 0xe32, 0x20, 0x6d, 0x6d, 0x20, 0xe19, 0xe32, 0xe17, -0xe35, 0x20, 0x73, 0x73, 0x20, 0xe27, 0xe34, 0xe19, 0xe32, 0xe17, 0xe35, 0x20, 0x74, 0x41, 0x50, 0x20, 0x27, 0x67, 0x61, 0x27, -0x20, 0x68, 0x3a, 0x6d, 0x6d, 0x41, 0x50, 0x20, 0x27, 0x67, 0x61, 0x27, 0x20, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, -0x20, 0x74, 0x27, 0x4b, 0x6c, 0x27, 0x2e, 0x20, 0x48, 0x2e, 0x6d, 0x6d, 0x27, 0x4b, 0x6c, 0x6f, 0x63, 0x6b, 0x27, 0x20, -0x48, 0x2e, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x28, 0x74, 0x29, 0x74, 0x20, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, -0x20, 0x41, 0x50, 0x48, 0x3a, 0x6d, 0x6d, 0x20, 0x27, 0x68, 0x6f, 0x64, 0x17a, 0x27, 0x2e +0xe99, 0xeb2, 0xe97, 0xeb5, 0x20, 0x74, 0x68, 0x3a, 0x6d, 0x6d, 0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x28, 0x74, +0x29, 0x27, 0x6b, 0x6c, 0x27, 0x2e, 0x20, 0x48, 0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x74, 0x41, 0x50, 0x20, +0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x74, 0x48, 0x20, 0xe19, 0xe32, 0xe2c, 0xe34, 0xe01, 0xe32, 0x20, 0x6d, 0x6d, +0x20, 0xe19, 0xe32, 0xe17, 0xe35, 0x20, 0x73, 0x73, 0x20, 0xe27, 0xe34, 0xe19, 0xe32, 0xe17, 0xe35, 0x20, 0x74, 0x41, 0x50, 0x20, +0x27, 0x67, 0x61, 0x27, 0x20, 0x68, 0x3a, 0x6d, 0x6d, 0x41, 0x50, 0x20, 0x27, 0x67, 0x61, 0x27, 0x20, 0x68, 0x3a, 0x6d, +0x6d, 0x3a, 0x73, 0x73, 0x20, 0x74, 0x27, 0x4b, 0x6c, 0x27, 0x2e, 0x20, 0x48, 0x2e, 0x6d, 0x6d, 0x27, 0x4b, 0x6c, 0x6f, +0x63, 0x6b, 0x27, 0x20, 0x48, 0x2e, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x28, 0x74, 0x29, 0x74, 0x20, 0x68, 0x3a, 0x6d, +0x6d, 0x3a, 0x73, 0x73, 0x20, 0x41, 0x50, 0x48, 0x3a, 0x6d, 0x6d, 0x20, 0x27, 0x68, 0x6f, 0x64, 0x17a, 0x27, 0x2e }; static const ushort months_data[] = { @@ -2031,989 +2045,1031 @@ static const ushort months_data[] = { 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x65, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x65, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x75, 0x73, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, -0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x53, 0x68, 0x6b, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x50, -0x72, 0x69, 0x3b, 0x4d, 0x61, 0x6a, 0x3b, 0x51, 0x65, 0x72, 0x3b, 0x4b, 0x6f, 0x72, 0x72, 0x3b, 0x47, 0x75, 0x73, 0x68, -0x3b, 0x53, 0x68, 0x74, 0x3b, 0x54, 0x65, 0x74, 0x3b, 0x4e, 0xeb, 0x6e, 0x3b, 0x44, 0x68, 0x6a, 0x3b, 0x4a, 0x61, 0x6e, -0x61, 0x72, 0x3b, 0x53, 0x68, 0x6b, 0x75, 0x72, 0x74, 0x3b, 0x4d, 0x61, 0x72, 0x73, 0x3b, 0x50, 0x72, 0x69, 0x6c, 0x6c, -0x3b, 0x4d, 0x61, 0x6a, 0x3b, 0x51, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x72, 0x3b, 0x4b, 0x6f, 0x72, 0x72, 0x69, 0x6b, 0x3b, -0x47, 0x75, 0x73, 0x68, 0x74, 0x3b, 0x53, 0x68, 0x74, 0x61, 0x74, 0x6f, 0x72, 0x3b, 0x54, 0x65, 0x74, 0x6f, 0x72, 0x3b, -0x4e, 0xeb, 0x6e, 0x74, 0x6f, 0x72, 0x3b, 0x44, 0x68, 0x6a, 0x65, 0x74, 0x6f, 0x72, 0x3b, 0x4a, 0x3b, 0x53, 0x68, 0x3b, -0x4d, 0x3b, 0x50, 0x3b, 0x4d, 0x3b, 0x51, 0x3b, 0x4b, 0x3b, 0x47, 0x3b, 0x53, 0x68, 0x3b, 0x54, 0x3b, 0x4e, 0x3b, 0x44, -0x68, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x73, 0x68, 0x6b, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x70, 0x72, 0x69, 0x3b, 0x6d, 0x61, -0x6a, 0x3b, 0x71, 0x65, 0x72, 0x3b, 0x6b, 0x6f, 0x72, 0x72, 0x3b, 0x67, 0x75, 0x73, 0x68, 0x3b, 0x73, 0x68, 0x74, 0x3b, -0x74, 0x65, 0x74, 0x3b, 0x6e, 0xeb, 0x6e, 0x3b, 0x64, 0x68, 0x6a, 0x3b, 0x6a, 0x61, 0x6e, 0x61, 0x72, 0x3b, 0x73, 0x68, -0x6b, 0x75, 0x72, 0x74, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x70, 0x72, 0x69, 0x6c, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, -0x71, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x72, 0x3b, 0x6b, 0x6f, 0x72, 0x72, 0x69, 0x6b, 0x3b, 0x67, 0x75, 0x73, 0x68, 0x74, -0x3b, 0x73, 0x68, 0x74, 0x61, 0x74, 0x6f, 0x72, 0x3b, 0x74, 0x65, 0x74, 0x6f, 0x72, 0x3b, 0x6e, 0xeb, 0x6e, 0x74, 0x6f, -0x72, 0x3b, 0x64, 0x68, 0x6a, 0x65, 0x74, 0x6f, 0x72, 0x3b, 0x6a, 0x3b, 0x73, 0x68, 0x3b, 0x6d, 0x3b, 0x70, 0x3b, 0x6d, -0x3b, 0x71, 0x3b, 0x6b, 0x3b, 0x67, 0x3b, 0x73, 0x68, 0x3b, 0x74, 0x3b, 0x6e, 0x3b, 0x64, 0x68, 0x3b, 0x1303, 0x1295, 0x12e9, -0x3b, 0x134c, 0x1265, 0x1229, 0x3b, 0x121b, 0x122d, 0x127d, 0x3b, 0x12a4, 0x1355, 0x122a, 0x3b, 0x121c, 0x12ed, 0x3b, 0x1301, 0x1295, 0x3b, 0x1301, -0x120b, 0x12ed, 0x3b, 0x12a6, 0x1308, 0x1235, 0x3b, 0x1234, 0x1355, 0x1274, 0x3b, 0x12a6, 0x12ad, 0x1276, 0x3b, 0x1296, 0x126c, 0x121d, 0x3b, 0x12f2, -0x1234, 0x121d, 0x3b, 0x1303, 0x1295, 0x12e9, 0x12c8, 0x122a, 0x3b, 0x134c, 0x1265, 0x1229, 0x12c8, 0x122a, 0x3b, 0x121b, 0x122d, 0x127d, 0x3b, 0x12a4, -0x1355, 0x122a, 0x120d, 0x3b, 0x121c, 0x12ed, 0x3b, 0x1301, 0x1295, 0x3b, 0x1301, 0x120b, 0x12ed, 0x3b, 0x12a6, 0x1308, 0x1235, 0x1275, 0x3b, 0x1234, -0x1355, 0x1274, 0x121d, 0x1260, 0x122d, 0x3b, 0x12a6, 0x12ad, 0x1276, 0x1260, 0x122d, 0x3b, 0x1296, 0x126c, 0x121d, 0x1260, 0x122d, 0x3b, 0x12f2, 0x1234, -0x121d, 0x1260, 0x122d, 0x3b, 0x1303, 0x3b, 0x134c, 0x3b, 0x121b, 0x3b, 0x12a4, 0x3b, 0x121c, 0x3b, 0x1301, 0x3b, 0x1301, 0x3b, 0x12a6, 0x3b, -0x1234, 0x3b, 0x12a6, 0x3b, 0x1296, 0x3b, 0x12f2, 0x3b, 0x64a, 0x646, 0x627, 0x64a, 0x631, 0x3b, 0x641, 0x628, 0x631, 0x627, 0x64a, 0x631, -0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x623, 0x628, 0x631, 0x64a, 0x644, 0x3b, 0x645, 0x627, 0x64a, 0x648, 0x3b, 0x64a, 0x648, 0x646, -0x64a, 0x648, 0x3b, 0x64a, 0x648, 0x644, 0x64a, 0x648, 0x3b, 0x623, 0x63a, 0x633, 0x637, 0x633, 0x3b, 0x633, 0x628, 0x62a, 0x645, 0x628, +0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x73, 0x68, 0x6b, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x70, +0x72, 0x69, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x71, 0x65, 0x72, 0x3b, 0x6b, 0x6f, 0x72, 0x72, 0x3b, 0x67, 0x75, 0x73, 0x68, +0x3b, 0x73, 0x68, 0x74, 0x3b, 0x74, 0x65, 0x74, 0x3b, 0x6e, 0xeb, 0x6e, 0x3b, 0x64, 0x68, 0x6a, 0x3b, 0x6a, 0x61, 0x6e, +0x61, 0x72, 0x3b, 0x73, 0x68, 0x6b, 0x75, 0x72, 0x74, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x70, 0x72, 0x69, 0x6c, 0x6c, +0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x71, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x72, 0x3b, 0x6b, 0x6f, 0x72, 0x72, 0x69, 0x6b, 0x3b, +0x67, 0x75, 0x73, 0x68, 0x74, 0x3b, 0x73, 0x68, 0x74, 0x61, 0x74, 0x6f, 0x72, 0x3b, 0x74, 0x65, 0x74, 0x6f, 0x72, 0x3b, +0x6e, 0xeb, 0x6e, 0x74, 0x6f, 0x72, 0x3b, 0x64, 0x68, 0x6a, 0x65, 0x74, 0x6f, 0x72, 0x3b, 0x6a, 0x3b, 0x73, 0x68, 0x3b, +0x6d, 0x3b, 0x70, 0x3b, 0x6d, 0x3b, 0x71, 0x3b, 0x6b, 0x3b, 0x67, 0x3b, 0x73, 0x68, 0x3b, 0x74, 0x3b, 0x6e, 0x3b, 0x64, +0x68, 0x3b, 0x1303, 0x1295, 0x12e9, 0x3b, 0x134c, 0x1265, 0x1229, 0x3b, 0x121b, 0x122d, 0x127d, 0x3b, 0x12a4, 0x1355, 0x122a, 0x3b, 0x121c, 0x12ed, +0x3b, 0x1301, 0x1295, 0x3b, 0x1301, 0x120b, 0x12ed, 0x3b, 0x12a6, 0x1308, 0x1235, 0x3b, 0x1234, 0x1355, 0x1274, 0x3b, 0x12a6, 0x12ad, 0x1276, 0x3b, +0x1296, 0x126c, 0x121d, 0x3b, 0x12f2, 0x1234, 0x121d, 0x3b, 0x1303, 0x1295, 0x12e9, 0x12c8, 0x122a, 0x3b, 0x134c, 0x1265, 0x1229, 0x12c8, 0x122a, 0x3b, +0x121b, 0x122d, 0x127d, 0x3b, 0x12a4, 0x1355, 0x122a, 0x120d, 0x3b, 0x121c, 0x12ed, 0x3b, 0x1301, 0x1295, 0x3b, 0x1301, 0x120b, 0x12ed, 0x3b, 0x12a6, +0x1308, 0x1235, 0x1275, 0x3b, 0x1234, 0x1355, 0x1274, 0x121d, 0x1260, 0x122d, 0x3b, 0x12a6, 0x12ad, 0x1276, 0x1260, 0x122d, 0x3b, 0x1296, 0x126c, 0x121d, +0x1260, 0x122d, 0x3b, 0x12f2, 0x1234, 0x121d, 0x1260, 0x122d, 0x3b, 0x1303, 0x3b, 0x134c, 0x3b, 0x121b, 0x3b, 0x12a4, 0x3b, 0x121c, 0x3b, 0x1301, +0x3b, 0x1301, 0x3b, 0x12a6, 0x3b, 0x1234, 0x3b, 0x12a6, 0x3b, 0x1296, 0x3b, 0x12f2, 0x3b, 0x64a, 0x646, 0x627, 0x64a, 0x631, 0x3b, 0x641, +0x628, 0x631, 0x627, 0x64a, 0x631, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x623, 0x628, 0x631, 0x64a, 0x644, 0x3b, 0x645, 0x627, 0x64a, +0x648, 0x3b, 0x64a, 0x648, 0x646, 0x64a, 0x648, 0x3b, 0x64a, 0x648, 0x644, 0x64a, 0x648, 0x3b, 0x623, 0x63a, 0x633, 0x637, 0x633, 0x3b, +0x633, 0x628, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x623, 0x643, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x641, 0x645, 0x628, 0x631, +0x3b, 0x62f, 0x64a, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x64a, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x623, 0x3b, 0x648, 0x3b, 0x646, 0x3b, +0x644, 0x3b, 0x63a, 0x3b, 0x633, 0x3b, 0x643, 0x3b, 0x628, 0x3b, 0x62f, 0x3b, 0x62c, 0x627, 0x646, 0x641, 0x64a, 0x3b, 0x641, 0x64a, +0x641, 0x631, 0x64a, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x623, 0x641, 0x631, 0x64a, 0x644, 0x3b, 0x645, 0x627, 0x64a, 0x3b, 0x62c, +0x648, 0x627, 0x646, 0x3b, 0x62c, 0x648, 0x64a, 0x644, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x62a, 0x3b, 0x633, 0x628, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x623, 0x643, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x641, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x64a, 0x633, 0x645, -0x628, 0x631, 0x3b, 0x64a, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x623, 0x3b, 0x648, 0x3b, 0x646, 0x3b, 0x644, 0x3b, 0x63a, 0x3b, 0x633, -0x3b, 0x643, 0x3b, 0x628, 0x3b, 0x62f, 0x3b, 0x62c, 0x627, 0x646, 0x641, 0x64a, 0x3b, 0x641, 0x64a, 0x641, 0x631, 0x64a, 0x3b, 0x645, -0x627, 0x631, 0x633, 0x3b, 0x623, 0x641, 0x631, 0x64a, 0x644, 0x3b, 0x645, 0x627, 0x64a, 0x3b, 0x62c, 0x648, 0x627, 0x646, 0x3b, 0x62c, -0x648, 0x64a, 0x644, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x62a, 0x3b, 0x633, 0x628, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x623, 0x643, 0x62a, -0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x641, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x64a, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x62c, 0x3b, -0x641, 0x3b, 0x645, 0x3b, 0x623, 0x3b, 0x645, 0x3b, 0x62c, 0x3b, 0x62c, 0x3b, 0x623, 0x3b, 0x633, 0x3b, 0x623, 0x3b, 0x646, 0x3b, -0x62f, 0x3b, 0x643, 0x627, 0x646, 0x648, 0x646, 0x20, 0x627, 0x644, 0x62b, 0x627, 0x646, 0x64a, 0x3b, 0x634, 0x628, 0x627, 0x637, 0x3b, -0x622, 0x630, 0x627, 0x631, 0x3b, 0x646, 0x64a, 0x633, 0x627, 0x646, 0x3b, 0x623, 0x64a, 0x627, 0x631, 0x3b, 0x62d, 0x632, 0x64a, 0x631, -0x627, 0x646, 0x3b, 0x62a, 0x645, 0x648, 0x632, 0x3b, 0x622, 0x628, 0x3b, 0x623, 0x64a, 0x644, 0x648, 0x644, 0x3b, 0x62a, 0x634, 0x631, -0x64a, 0x646, 0x20, 0x627, 0x644, 0x623, 0x648, 0x644, 0x3b, 0x62a, 0x634, 0x631, 0x64a, 0x646, 0x20, 0x627, 0x644, 0x62b, 0x627, 0x646, -0x64a, 0x3b, 0x643, 0x627, 0x646, 0x648, 0x646, 0x20, 0x627, 0x644, 0x623, 0x648, 0x644, 0x3b, 0x643, 0x3b, 0x634, 0x3b, 0x622, 0x3b, -0x646, 0x3b, 0x623, 0x3b, 0x62d, 0x3b, 0x62a, 0x3b, 0x622, 0x3b, 0x623, 0x3b, 0x62a, 0x3b, 0x62a, 0x3b, 0x643, 0x3b, 0x643, 0x627, -0x646, 0x648, 0x646, 0x20, 0x627, 0x644, 0x62b, 0x627, 0x646, 0x64a, 0x3b, 0x634, 0x628, 0x627, 0x637, 0x3b, 0x622, 0x630, 0x627, 0x631, -0x3b, 0x646, 0x64a, 0x633, 0x627, 0x646, 0x3b, 0x623, 0x64a, 0x627, 0x631, 0x3b, 0x62d, 0x632, 0x64a, 0x631, 0x627, 0x646, 0x3b, 0x62a, -0x645, 0x648, 0x632, 0x3b, 0x622, 0x628, 0x3b, 0x623, 0x64a, 0x644, 0x648, 0x644, 0x3b, 0x62a, 0x634, 0x631, 0x64a, 0x646, 0xa0, 0x627, -0x644, 0x623, 0x648, 0x644, 0x3b, 0x62a, 0x634, 0x631, 0x64a, 0x646, 0x20, 0x627, 0x644, 0x62b, 0x627, 0x646, 0x64a, 0x3b, 0x643, 0x627, -0x646, 0x648, 0x646, 0x20, 0x627, 0x644, 0x623, 0x648, 0x644, 0x3b, 0x64a, 0x646, 0x627, 0x64a, 0x631, 0x3b, 0x641, 0x628, 0x631, 0x627, -0x64a, 0x631, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x625, 0x628, 0x631, 0x64a, 0x644, 0x3b, 0x645, 0x627, 0x64a, 0x648, 0x3b, 0x64a, -0x648, 0x646, 0x64a, 0x648, 0x3b, 0x64a, 0x648, 0x644, 0x64a, 0x648, 0x3b, 0x623, 0x63a, 0x634, 0x62a, 0x3b, 0x634, 0x62a, 0x645, 0x628, -0x631, 0x3b, 0x623, 0x643, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x641, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x62c, 0x645, 0x628, -0x631, 0x3b, 0x64a, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x625, 0x3b, 0x648, 0x3b, 0x646, 0x3b, 0x644, 0x3b, 0x63a, 0x3b, 0x634, 0x3b, -0x643, 0x3b, 0x628, 0x3b, 0x62f, 0x3b, 0x64a, 0x646, 0x627, 0x64a, 0x631, 0x3b, 0x641, 0x628, 0x631, 0x627, 0x64a, 0x631, 0x3b, 0x645, -0x627, 0x631, 0x633, 0x3b, 0x623, 0x628, 0x631, 0x64a, 0x644, 0x3b, 0x645, 0x627, 0x64a, 0x3b, 0x64a, 0x648, 0x646, 0x64a, 0x648, 0x3b, -0x64a, 0x648, 0x644, 0x64a, 0x648, 0x632, 0x3b, 0x63a, 0x634, 0x62a, 0x3b, 0x634, 0x62a, 0x646, 0x628, 0x631, 0x3b, 0x623, 0x643, 0x62a, -0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x646, 0x628, 0x631, 0x3b, 0x62f, 0x62c, 0x646, 0x628, 0x631, 0x3b, 0x64a, 0x3b, 0x641, 0x3b, -0x645, 0x3b, 0x623, 0x3b, 0x645, 0x3b, 0x646, 0x3b, 0x644, 0x3b, 0x63a, 0x3b, 0x634, 0x3b, 0x643, 0x3b, 0x628, 0x3b, 0x62f, 0x3b, -0x570, 0x576, 0x57e, 0x3b, 0x583, 0x57f, 0x57e, 0x3b, 0x574, 0x580, 0x57f, 0x3b, 0x561, 0x57a, 0x580, 0x3b, 0x574, 0x575, 0x57d, 0x3b, -0x570, 0x576, 0x57d, 0x3b, 0x570, 0x56c, 0x57d, 0x3b, 0x585, 0x563, 0x57d, 0x3b, 0x57d, 0x565, 0x57a, 0x3b, 0x570, 0x578, 0x56f, 0x3b, -0x576, 0x578, 0x575, 0x3b, 0x564, 0x565, 0x56f, 0x3b, 0x570, 0x578, 0x582, 0x576, 0x57e, 0x561, 0x580, 0x3b, 0x583, 0x565, 0x57f, 0x580, -0x57e, 0x561, 0x580, 0x3b, 0x574, 0x561, 0x580, 0x57f, 0x3b, 0x561, 0x57a, 0x580, 0x56b, 0x56c, 0x3b, 0x574, 0x561, 0x575, 0x56b, 0x57d, -0x3b, 0x570, 0x578, 0x582, 0x576, 0x56b, 0x57d, 0x3b, 0x570, 0x578, 0x582, 0x56c, 0x56b, 0x57d, 0x3b, 0x585, 0x563, 0x578, 0x57d, 0x57f, -0x578, 0x57d, 0x3b, 0x57d, 0x565, 0x57a, 0x57f, 0x565, 0x574, 0x562, 0x565, 0x580, 0x3b, 0x570, 0x578, 0x56f, 0x57f, 0x565, 0x574, 0x562, -0x565, 0x580, 0x3b, 0x576, 0x578, 0x575, 0x565, 0x574, 0x562, 0x565, 0x580, 0x3b, 0x564, 0x565, 0x56f, 0x57f, 0x565, 0x574, 0x562, 0x565, -0x580, 0x3b, 0x540, 0x3b, 0x553, 0x3b, 0x544, 0x3b, 0x531, 0x3b, 0x544, 0x3b, 0x540, 0x3b, 0x540, 0x3b, 0x555, 0x3b, 0x54d, 0x3b, -0x540, 0x3b, 0x546, 0x3b, 0x534, 0x3b, 0x570, 0x578, 0x582, 0x576, 0x57e, 0x561, 0x580, 0x56b, 0x3b, 0x583, 0x565, 0x57f, 0x580, 0x57e, -0x561, 0x580, 0x56b, 0x3b, 0x574, 0x561, 0x580, 0x57f, 0x56b, 0x3b, 0x561, 0x57a, 0x580, 0x56b, 0x56c, 0x56b, 0x3b, 0x574, 0x561, 0x575, -0x56b, 0x57d, 0x56b, 0x3b, 0x570, 0x578, 0x582, 0x576, 0x56b, 0x57d, 0x56b, 0x3b, 0x570, 0x578, 0x582, 0x56c, 0x56b, 0x57d, 0x56b, 0x3b, -0x585, 0x563, 0x578, 0x57d, 0x57f, 0x578, 0x57d, 0x56b, 0x3b, 0x57d, 0x565, 0x57a, 0x57f, 0x565, 0x574, 0x562, 0x565, 0x580, 0x56b, 0x3b, -0x570, 0x578, 0x56f, 0x57f, 0x565, 0x574, 0x562, 0x565, 0x580, 0x56b, 0x3b, 0x576, 0x578, 0x575, 0x565, 0x574, 0x562, 0x565, 0x580, 0x56b, -0x3b, 0x564, 0x565, 0x56f, 0x57f, 0x565, 0x574, 0x562, 0x565, 0x580, 0x56b, 0x3b, 0x99c, 0x9be, 0x9a8, 0x9c1, 0x3b, 0x9ab, 0x9c7, 0x9ac, -0x9cd, 0x9f0, 0x9c1, 0x3b, 0x9ae, 0x9be, 0x9f0, 0x9cd, 0x99a, 0x3b, 0x98f, 0x9aa, 0x9cd, 0x9f0, 0x9bf, 0x9b2, 0x3b, 0x9ae, 0x9c7, 0x2019, -0x3b, 0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1, 0x9b2, 0x9be, 0x987, 0x3b, 0x986, 0x997, 0x3b, 0x99b, 0x9c7, 0x9aa, 0x9cd, 0x9a4, 0x9c7, -0x3b, 0x985, 0x995, 0x9cd, 0x99f, 0x9cb, 0x3b, 0x9a8, 0x9f1, 0x9c7, 0x3b, 0x9a1, 0x9bf, 0x99a, 0x9c7, 0x3b, 0x99c, 0x9be, 0x9a8, 0x9c1, -0x9f1, 0x9be, 0x9f0, 0x9c0, 0x3b, 0x9ab, 0x9c7, 0x9ac, 0x9cd, 0x9f0, 0x9c1, 0x9f1, 0x9be, 0x9f0, 0x9c0, 0x3b, 0x9ae, 0x9be, 0x9f0, 0x9cd, -0x99a, 0x3b, 0x98f, 0x9aa, 0x9cd, 0x9f0, 0x9bf, 0x9b2, 0x3b, 0x9ae, 0x9c7, 0x2019, 0x3b, 0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1, 0x9b2, -0x9be, 0x987, 0x3b, 0x986, 0x997, 0x9b7, 0x9cd, 0x99f, 0x3b, 0x99b, 0x9c7, 0x9aa, 0x9cd, 0x9a4, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9f0, 0x3b, -0x985, 0x995, 0x9cd, 0x99f, 0x9cb, 0x9ac, 0x9f0, 0x3b, 0x9a8, 0x9f1, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9f0, 0x3b, 0x9a1, 0x9bf, 0x99a, 0x9c7, -0x9ae, 0x9cd, 0x9ac, 0x9f0, 0x3b, 0x99c, 0x3b, 0x9ab, 0x3b, 0x9ae, 0x3b, 0x98f, 0x3b, 0x9ae, 0x3b, 0x99c, 0x3b, 0x99c, 0x3b, 0x986, -0x3b, 0x99b, 0x3b, 0x985, 0x3b, 0x9a8, 0x3b, 0x9a1, 0x3b, 0x79, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x76, 0x3b, 0x6d, 0x61, 0x72, -0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x69, 0x79, 0x6e, 0x3b, 0x69, 0x79, 0x6c, 0x3b, 0x61, 0x76, 0x71, -0x3b, 0x73, 0x65, 0x6e, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x79, 0x3b, 0x64, 0x65, 0x6b, 0x3b, 0x59, 0x61, 0x6e, -0x76, 0x61, 0x72, 0x3b, 0x46, 0x65, 0x76, 0x72, 0x61, 0x6c, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x3b, 0x41, 0x70, 0x72, 0x65, -0x6c, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x130, 0x79, 0x75, 0x6e, 0x3b, 0x130, 0x79, 0x75, 0x6c, 0x3b, 0x41, 0x76, 0x71, 0x75, -0x73, 0x74, 0x3b, 0x53, 0x65, 0x6e, 0x74, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x79, 0x61, 0x62, 0x72, 0x3b, -0x4e, 0x6f, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x44, 0x65, 0x6b, 0x61, 0x62, 0x72, 0x3b, 0x79, 0x61, 0x6e, 0x76, 0x61, 0x72, -0x3b, 0x66, 0x65, 0x76, 0x72, 0x61, 0x6c, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x65, 0x6c, 0x3b, 0x6d, -0x61, 0x79, 0x3b, 0x69, 0x79, 0x75, 0x6e, 0x3b, 0x69, 0x79, 0x75, 0x6c, 0x3b, 0x61, 0x76, 0x71, 0x75, 0x73, 0x74, 0x3b, -0x73, 0x65, 0x6e, 0x74, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x6e, 0x6f, 0x79, -0x61, 0x62, 0x72, 0x3b, 0x64, 0x65, 0x6b, 0x61, 0x62, 0x72, 0x3b, 0x458, 0x430, 0x43d, 0x3b, 0x444, 0x435, 0x432, 0x3b, 0x43c, -0x430, 0x440, 0x3b, 0x430, 0x43f, 0x440, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x438, 0x458, 0x43d, 0x3b, 0x438, 0x458, 0x43b, 0x3b, 0x430, -0x432, 0x433, 0x3b, 0x441, 0x435, 0x43d, 0x3b, 0x43e, 0x43a, 0x442, 0x3b, 0x43d, 0x43e, 0x458, 0x3b, 0x434, 0x435, 0x43a, 0x3b, 0x408, -0x430, 0x43d, 0x432, 0x430, 0x440, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x3b, 0x41c, 0x430, 0x440, 0x442, 0x3b, 0x410, 0x43f, -0x440, 0x435, 0x43b, 0x3b, 0x41c, 0x430, 0x439, 0x3b, 0x418, 0x458, 0x443, 0x43d, 0x3b, 0x418, 0x458, 0x443, 0x43b, 0x3b, 0x410, 0x432, -0x433, 0x443, 0x441, 0x442, 0x3b, 0x421, 0x435, 0x43d, 0x442, 0x458, 0x430, 0x431, 0x440, 0x3b, 0x41e, 0x43a, 0x442, 0x458, 0x430, 0x431, -0x440, 0x3b, 0x41d, 0x43e, 0x458, 0x430, 0x431, 0x440, 0x3b, 0x414, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x3b, 0x458, 0x430, 0x43d, 0x432, -0x430, 0x440, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x435, 0x43b, -0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x438, 0x458, 0x443, 0x43d, 0x3b, 0x438, 0x458, 0x443, 0x43b, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, -0x442, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x458, 0x430, 0x431, 0x440, 0x3b, 0x43e, 0x43a, 0x442, 0x458, 0x430, 0x431, 0x440, 0x3b, 0x43d, -0x43e, 0x458, 0x430, 0x431, 0x440, 0x3b, 0x434, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x3b, 0x75, 0x72, 0x74, 0x2e, 0x3b, 0x6f, 0x74, -0x73, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x69, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x2e, 0x3b, 0x65, 0x6b, -0x61, 0x2e, 0x3b, 0x75, 0x7a, 0x74, 0x2e, 0x3b, 0x61, 0x62, 0x75, 0x2e, 0x3b, 0x69, 0x72, 0x61, 0x2e, 0x3b, 0x75, 0x72, -0x72, 0x2e, 0x3b, 0x61, 0x7a, 0x61, 0x2e, 0x3b, 0x61, 0x62, 0x65, 0x2e, 0x3b, 0x75, 0x72, 0x74, 0x61, 0x72, 0x72, 0x69, -0x6c, 0x61, 0x3b, 0x4f, 0x74, 0x73, 0x61, 0x69, 0x6c, 0x61, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x78, 0x6f, 0x61, 0x3b, 0x41, -0x70, 0x69, 0x72, 0x69, 0x6c, 0x61, 0x3b, 0x4d, 0x61, 0x69, 0x61, 0x74, 0x7a, 0x61, 0x3b, 0x45, 0x6b, 0x61, 0x69, 0x6e, -0x61, 0x3b, 0x55, 0x7a, 0x74, 0x61, 0x69, 0x6c, 0x61, 0x3b, 0x41, 0x62, 0x75, 0x7a, 0x74, 0x75, 0x61, 0x3b, 0x49, 0x72, -0x61, 0x69, 0x6c, 0x61, 0x3b, 0x55, 0x72, 0x72, 0x69, 0x61, 0x3b, 0x41, 0x7a, 0x61, 0x72, 0x6f, 0x61, 0x3b, 0x41, 0x62, -0x65, 0x6e, 0x64, 0x75, 0x61, 0x3b, 0x55, 0x3b, 0x4f, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x55, 0x3b, -0x41, 0x3b, 0x49, 0x3b, 0x55, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x75, 0x72, 0x74, 0x61, 0x72, 0x72, 0x69, 0x6c, 0x61, 0x3b, -0x6f, 0x74, 0x73, 0x61, 0x69, 0x6c, 0x61, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x78, 0x6f, 0x61, 0x3b, 0x61, 0x70, 0x69, 0x72, -0x69, 0x6c, 0x61, 0x3b, 0x6d, 0x61, 0x69, 0x61, 0x74, 0x7a, 0x61, 0x3b, 0x65, 0x6b, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x75, -0x7a, 0x74, 0x61, 0x69, 0x6c, 0x61, 0x3b, 0x61, 0x62, 0x75, 0x7a, 0x74, 0x75, 0x61, 0x3b, 0x69, 0x72, 0x61, 0x69, 0x6c, -0x61, 0x3b, 0x75, 0x72, 0x72, 0x69, 0x61, 0x3b, 0x61, 0x7a, 0x61, 0x72, 0x6f, 0x61, 0x3b, 0x61, 0x62, 0x65, 0x6e, 0x64, -0x75, 0x61, 0x3b, 0x99c, 0x9be, 0x9a8, 0x9c1, 0x9af, 0x9bc, 0x9be, 0x9b0, 0x9c0, 0x3b, 0x9ab, 0x9c7, 0x9ac, 0x9cd, 0x9b0, 0x9c1, 0x9af, -0x9bc, 0x9be, 0x9b0, 0x9c0, 0x3b, 0x9ae, 0x9be, 0x9b0, 0x9cd, 0x99a, 0x3b, 0x98f, 0x9aa, 0x9cd, 0x9b0, 0x9bf, 0x9b2, 0x3b, 0x9ae, 0x9c7, -0x3b, 0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1, 0x9b2, 0x9be, 0x987, 0x3b, 0x986, 0x997, 0x9b8, 0x9cd, 0x99f, 0x3b, 0x9b8, 0x9c7, 0x9aa, -0x9cd, 0x99f, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9b0, 0x3b, 0x985, 0x995, 0x9cd, 0x99f, 0x9cb, 0x9ac, 0x9b0, 0x3b, 0x9a8, 0x9ad, 0x9c7, 0x9ae, -0x9cd, 0x9ac, 0x9b0, 0x3b, 0x9a1, 0x9bf, 0x9b8, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9b0, 0x3b, 0x99c, 0x9be, 0x3b, 0x9ab, 0x9c7, 0x3b, 0x9ae, -0x9be, 0x3b, 0x98f, 0x3b, 0x9ae, 0x9c7, 0x3b, 0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1, 0x3b, 0x986, 0x3b, 0x9b8, 0x9c7, 0x3b, 0x985, -0x3b, 0x9a8, 0x3b, 0x9a1, 0x9bf, 0x3b, 0x99c, 0x9be, 0x9a8, 0x9c1, 0x3b, 0x9ab, 0x9c7, 0x9ac, 0x3b, 0x9ae, 0x9be, 0x9b0, 0x9cd, 0x99a, -0x3b, 0x98f, 0x9aa, 0x9cd, 0x9b0, 0x9bf, 0x9b2, 0x3b, 0x9ae, 0x9c7, 0x3b, 0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1, 0x9b2, 0x9be, 0x987, -0x3b, 0x986, 0x997, 0x9b8, 0x9cd, 0x99f, 0x3b, 0x9b8, 0x9c7, 0x9aa, 0x9cd, 0x99f, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9b0, 0x3b, 0x985, 0x995, -0x9cd, 0x99f, 0x9cb, 0x9ac, 0x9b0, 0x3b, 0x9a8, 0x9ad, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9b0, 0x3b, 0x9a1, 0x9bf, 0x9b8, 0x9c7, 0x9ae, 0x9cd, -0x9ac, 0x9b0, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf21, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf22, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf23, 0x3b, 0xf5f, 0xfb3, -0xf0b, 0xf24, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf25, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf26, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf27, 0x3b, 0xf5f, 0xfb3, -0xf0b, 0xf28, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf29, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf21, 0xf20, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf21, 0xf21, 0x3b, -0xf5f, 0xfb3, 0xf0b, 0xf21, 0xf22, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xf44, 0xf54, 0xf0b, 0x3b, 0xf66, -0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, -0xf5f, 0xfb3, 0xf0b, 0xf42, 0xf66, 0xf74, 0xf58, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, -0xf5e, 0xf72, 0xf0b, 0xf54, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf63, 0xf94, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, -0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xfb2, 0xf74, 0xf42, 0xf0b, 0xf54, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, -0xfb3, 0xf0b, 0xf56, 0xf51, 0xf74, 0xf53, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf62, -0xf92, 0xfb1, 0xf51, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xf42, 0xf74, 0xf0b, 0xf54, -0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, -0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf45, 0xf72, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, -0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf21, 0x3b, 0xf22, -0x3b, 0xf23, 0x3b, 0xf24, 0x3b, 0xf25, 0x3b, 0xf26, 0x3b, 0xf27, 0x3b, 0xf28, 0x3b, 0xf29, 0x3b, 0xf21, 0xf20, 0x3b, 0xf21, 0xf21, -0x3b, 0xf21, 0xf22, 0x3b, 0xf21, 0x3b, 0xf22, 0x3b, 0xf23, 0x3b, 0xf24, 0x3b, 0xf25, 0x3b, 0xf26, 0x3b, 0xf27, 0x3b, 0xf28, 0x3b, -0xf29, 0x3b, 0xf21, 0xf20, 0x3b, 0xf21, 0xf21, 0x3b, 0x31, 0x32, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xf44, 0xf54, 0xf0b, 0x3b, 0xf5f, -0xfb3, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf42, 0xf66, 0xf74, 0xf58, 0xf0b, 0xf54, 0xf0b, -0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf5e, 0xf72, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf63, 0xf94, 0xf0b, 0xf54, 0xf0b, 0x3b, -0xf5f, 0xfb3, 0xf0b, 0xf51, 0xfb2, 0xf74, 0xf42, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf51, 0xf74, 0xf53, 0xf0b, 0xf54, 0xf0b, -0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf62, 0xf92, 0xfb1, 0xf51, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xf42, 0xf74, 0xf0b, -0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, -0xf42, 0xf45, 0xf72, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, -0xf54, 0xf0b, 0x3b, 0xf21, 0x3b, 0xf22, 0x3b, 0xf23, 0x3b, 0x34, 0x3b, 0xf25, 0x3b, 0xf26, 0x3b, 0xf27, 0x3b, 0xf28, 0x3b, 0x39, -0x3b, 0xf21, 0xf20, 0x3b, 0xf21, 0xf21, 0x3b, 0xf21, 0xf22, 0x3b, 0x47, 0x65, 0x6e, 0x2e, 0x3b, 0x43, 0x2bc, 0x68, 0x77, 0x65, -0x2e, 0x3b, 0x4d, 0x65, 0x75, 0x72, 0x2e, 0x3b, 0x45, 0x62, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x65, 0x3b, 0x4d, 0x65, 0x7a, -0x68, 0x2e, 0x3b, 0x47, 0x6f, 0x75, 0x65, 0x2e, 0x3b, 0x45, 0x6f, 0x73, 0x74, 0x3b, 0x47, 0x77, 0x65, 0x6e, 0x2e, 0x3b, -0x48, 0x65, 0x72, 0x65, 0x3b, 0x44, 0x75, 0x3b, 0x4b, 0x7a, 0x75, 0x2e, 0x3b, 0x47, 0x65, 0x6e, 0x76, 0x65, 0x72, 0x3b, -0x43, 0x2bc, 0x68, 0x77, 0x65, 0x76, 0x72, 0x65, 0x72, 0x3b, 0x4d, 0x65, 0x75, 0x72, 0x7a, 0x68, 0x3b, 0x45, 0x62, 0x72, -0x65, 0x6c, 0x3b, 0x4d, 0x61, 0x65, 0x3b, 0x4d, 0x65, 0x7a, 0x68, 0x65, 0x76, 0x65, 0x6e, 0x3b, 0x47, 0x6f, 0x75, 0x65, -0x72, 0x65, 0x3b, 0x45, 0x6f, 0x73, 0x74, 0x3b, 0x47, 0x77, 0x65, 0x6e, 0x67, 0x6f, 0x6c, 0x6f, 0x3b, 0x48, 0x65, 0x72, -0x65, 0x3b, 0x44, 0x75, 0x3b, 0x4b, 0x65, 0x72, 0x7a, 0x75, 0x3b, 0x30, 0x31, 0x3b, 0x30, 0x32, 0x3b, 0x30, 0x33, 0x3b, -0x30, 0x34, 0x3b, 0x30, 0x35, 0x3b, 0x30, 0x36, 0x3b, 0x30, 0x37, 0x3b, 0x30, 0x38, 0x3b, 0x30, 0x39, 0x3b, 0x31, 0x30, -0x3b, 0x31, 0x31, 0x3b, 0x31, 0x32, 0x3b, 0x44f, 0x43d, 0x443, 0x3b, 0x444, 0x435, 0x432, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, -0x430, 0x43f, 0x440, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x44e, 0x43d, 0x438, 0x3b, 0x44e, 0x43b, 0x438, 0x3b, 0x430, 0x432, 0x433, 0x3b, -0x441, 0x435, 0x43f, 0x3b, 0x43e, 0x43a, 0x442, 0x3b, 0x43d, 0x43e, 0x435, 0x3b, 0x434, 0x435, 0x43a, 0x3b, 0x44f, 0x43d, 0x443, 0x430, -0x440, 0x438, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x443, 0x430, 0x440, 0x438, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, -0x438, 0x43b, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x44e, 0x43d, 0x438, 0x3b, 0x44e, 0x43b, 0x438, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, -0x442, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x435, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x43c, 0x432, 0x440, 0x438, -0x3b, 0x43d, 0x43e, 0x435, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x434, 0x435, 0x43a, 0x435, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x44f, 0x3b, -0x444, 0x3b, 0x43c, 0x3b, 0x430, 0x3b, 0x43c, 0x3b, 0x44e, 0x3b, 0x44e, 0x3b, 0x430, 0x3b, 0x441, 0x3b, 0x43e, 0x3b, 0x43d, 0x3b, -0x434, 0x3b, 0x1007, 0x1014, 0x103a, 0x3b, 0x1016, 0x1031, 0x3b, 0x1019, 0x1010, 0x103a, 0x3b, 0x1027, 0x3b, 0x1019, 0x1031, 0x3b, 0x1007, 0x103d, -0x1014, 0x103a, 0x3b, 0x1007, 0x1030, 0x3b, 0x1029, 0x3b, 0x1005, 0x1000, 0x103a, 0x3b, 0x1021, 0x1031, 0x102c, 0x1000, 0x103a, 0x3b, 0x1014, 0x102d, -0x102f, 0x3b, 0x1012, 0x102e, 0x3b, 0x1007, 0x1014, 0x103a, 0x1014, 0x101d, 0x102b, 0x101b, 0x102e, 0x3b, 0x1016, 0x1031, 0x1016, 0x1031, 0x102c, 0x103a, -0x101d, 0x102b, 0x101b, 0x102e, 0x3b, 0x1019, 0x1010, 0x103a, 0x3b, 0x1027, 0x1015, 0x103c, 0x102e, 0x3b, 0x1019, 0x1031, 0x3b, 0x1007, 0x103d, 0x1014, -0x103a, 0x3b, 0x1007, 0x1030, 0x101c, 0x102d, 0x102f, 0x1004, 0x103a, 0x3b, 0x1029, 0x1002, 0x102f, 0x1010, 0x103a, 0x3b, 0x1005, 0x1000, 0x103a, 0x1010, -0x1004, 0x103a, 0x1018, 0x102c, 0x3b, 0x1021, 0x1031, 0x102c, 0x1000, 0x103a, 0x1010, 0x102d, 0x102f, 0x1018, 0x102c, 0x3b, 0x1014, 0x102d, 0x102f, 0x101d, -0x1004, 0x103a, 0x1018, 0x102c, 0x3b, 0x1012, 0x102e, 0x1007, 0x1004, 0x103a, 0x1018, 0x102c, 0x3b, 0x1007, 0x3b, 0x1016, 0x3b, 0x1019, 0x3b, 0x1027, -0x3b, 0x1019, 0x3b, 0x1007, 0x3b, 0x1007, 0x3b, 0x1029, 0x3b, 0x1005, 0x3b, 0x1021, 0x3b, 0x1014, 0x3b, 0x1012, 0x3b, 0x441, 0x442, 0x443, -0x3b, 0x43b, 0x44e, 0x442, 0x3b, 0x441, 0x430, 0x43a, 0x3b, 0x43a, 0x440, 0x430, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x447, 0x44d, 0x440, -0x3b, 0x43b, 0x456, 0x43f, 0x3b, 0x436, 0x43d, 0x456, 0x3b, 0x432, 0x435, 0x440, 0x3b, 0x43a, 0x430, 0x441, 0x3b, 0x43b, 0x456, 0x441, -0x3b, 0x441, 0x43d, 0x435, 0x3b, 0x441, 0x442, 0x443, 0x434, 0x437, 0x435, 0x43d, 0x44c, 0x3b, 0x43b, 0x44e, 0x442, 0x44b, 0x3b, 0x441, -0x430, 0x43a, 0x430, 0x432, 0x456, 0x43a, 0x3b, 0x43a, 0x440, 0x430, 0x441, 0x430, 0x432, 0x456, 0x43a, 0x3b, 0x43c, 0x430, 0x439, 0x3b, -0x447, 0x44d, 0x440, 0x432, 0x435, 0x43d, 0x44c, 0x3b, 0x43b, 0x456, 0x43f, 0x435, 0x43d, 0x44c, 0x3b, 0x436, 0x43d, 0x456, 0x432, 0x435, -0x43d, 0x44c, 0x3b, 0x432, 0x435, 0x440, 0x430, 0x441, 0x435, 0x43d, 0x44c, 0x3b, 0x43a, 0x430, 0x441, 0x442, 0x440, 0x44b, 0x447, 0x43d, -0x456, 0x43a, 0x3b, 0x43b, 0x456, 0x441, 0x442, 0x430, 0x43f, 0x430, 0x434, 0x3b, 0x441, 0x43d, 0x435, 0x436, 0x430, 0x43d, 0x44c, 0x3b, -0x441, 0x3b, 0x43b, 0x3b, 0x441, 0x3b, 0x43a, 0x3b, 0x43c, 0x3b, 0x447, 0x3b, 0x43b, 0x3b, 0x436, 0x3b, 0x432, 0x3b, 0x43a, 0x3b, -0x43b, 0x3b, 0x441, 0x3b, 0x441, 0x442, 0x443, 0x3b, 0x43b, 0x44e, 0x442, 0x3b, 0x441, 0x430, 0x43a, 0x3b, 0x43a, 0x440, 0x430, 0x3b, -0x43c, 0x430, 0x44f, 0x3b, 0x447, 0x44d, 0x440, 0x3b, 0x43b, 0x456, 0x43f, 0x3b, 0x436, 0x43d, 0x456, 0x3b, 0x432, 0x435, 0x440, 0x3b, -0x43a, 0x430, 0x441, 0x3b, 0x43b, 0x456, 0x441, 0x3b, 0x441, 0x43d, 0x435, 0x3b, 0x441, 0x442, 0x443, 0x434, 0x437, 0x435, 0x43d, 0x44f, -0x3b, 0x43b, 0x44e, 0x442, 0x430, 0x433, 0x430, 0x3b, 0x441, 0x430, 0x43a, 0x430, 0x432, 0x456, 0x43a, 0x430, 0x3b, 0x43a, 0x440, 0x430, -0x441, 0x430, 0x432, 0x456, 0x43a, 0x430, 0x3b, 0x43c, 0x430, 0x44f, 0x3b, 0x447, 0x44d, 0x440, 0x432, 0x435, 0x43d, 0x44f, 0x3b, 0x43b, -0x456, 0x43f, 0x435, 0x43d, 0x44f, 0x3b, 0x436, 0x43d, 0x456, 0x45e, 0x43d, 0x44f, 0x3b, 0x432, 0x435, 0x440, 0x430, 0x441, 0x43d, 0x44f, -0x3b, 0x43a, 0x430, 0x441, 0x442, 0x440, 0x44b, 0x447, 0x43d, 0x456, 0x43a, 0x430, 0x3b, 0x43b, 0x456, 0x441, 0x442, 0x430, 0x43f, 0x430, -0x434, 0x430, 0x3b, 0x441, 0x43d, 0x435, 0x436, 0x43d, 0x44f, 0x3b, 0x1798, 0x1780, 0x179a, 0x17b6, 0x3b, 0x1780, 0x17bb, 0x1798, 0x17d2, 0x1797, -0x17c8, 0x3b, 0x1798, 0x17b8, 0x1793, 0x17b6, 0x3b, 0x1798, 0x17c1, 0x179f, 0x17b6, 0x3b, 0x17a7, 0x179f, 0x1797, 0x17b6, 0x3b, 0x1798, 0x17b7, 0x1790, -0x17bb, 0x1793, 0x17b6, 0x3b, 0x1780, 0x1780, 0x17d2, 0x1780, 0x178a, 0x17b6, 0x3b, 0x179f, 0x17b8, 0x17a0, 0x17b6, 0x3b, 0x1780, 0x1789, 0x17d2, 0x1789, -0x17b6, 0x3b, 0x178f, 0x17bb, 0x179b, 0x17b6, 0x3b, 0x179c, 0x17b7, 0x1785, 0x17d2, 0x1786, 0x17b7, 0x1780, 0x17b6, 0x3b, 0x1792, 0x17d2, 0x1793, 0x17bc, -0x3b, 0x1798, 0x3b, 0x1780, 0x3b, 0x1798, 0x3b, 0x1798, 0x3b, 0x17a7, 0x3b, 0x1798, 0x3b, 0x1780, 0x3b, 0x179f, 0x3b, 0x1780, 0x3b, 0x178f, -0x3b, 0x179c, 0x3b, 0x1792, 0x3b, 0x67, 0x65, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0xe7, -0x3b, 0x61, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x67, 0x3b, 0x6a, 0x75, 0x6e, 0x79, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, -0x3b, 0x61, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, -0x64, 0x65, 0x73, 0x2e, 0x3b, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x65, 0x72, 0x3b, 0x6d, 0x61, -0x72, 0xe7, 0x3b, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x67, 0x3b, 0x6a, 0x75, 0x6e, 0x79, 0x3b, 0x6a, -0x75, 0x6c, 0x69, 0x6f, 0x6c, 0x3b, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x65, -0x3b, 0x6f, 0x63, 0x74, 0x75, 0x62, 0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x65, -0x73, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x47, 0x4e, 0x3b, 0x46, 0x42, 0x3b, 0x4d, 0xc7, 0x3b, 0x41, 0x42, 0x3b, 0x4d, -0x47, 0x3b, 0x4a, 0x4e, 0x3b, 0x4a, 0x4c, 0x3b, 0x41, 0x47, 0x3b, 0x53, 0x54, 0x3b, 0x4f, 0x43, 0x3b, 0x4e, 0x56, 0x3b, -0x44, 0x53, 0x3b, 0x64, 0x65, 0x20, 0x67, 0x65, 0x6e, 0x2e, 0x3b, 0x64, 0x65, 0x20, 0x66, 0x65, 0x62, 0x72, 0x2e, 0x3b, -0x64, 0x65, 0x20, 0x6d, 0x61, 0x72, 0xe7, 0x3b, 0x64, 0x2019, 0x61, 0x62, 0x72, 0x2e, 0x3b, 0x64, 0x65, 0x20, 0x6d, 0x61, -0x69, 0x67, 0x3b, 0x64, 0x65, 0x20, 0x6a, 0x75, 0x6e, 0x79, 0x3b, 0x64, 0x65, 0x20, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x64, -0x2019, 0x61, 0x67, 0x2e, 0x3b, 0x64, 0x65, 0x20, 0x73, 0x65, 0x74, 0x2e, 0x3b, 0x64, 0x2019, 0x6f, 0x63, 0x74, 0x2e, 0x3b, -0x64, 0x65, 0x20, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x20, 0x64, 0x65, 0x73, 0x2e, 0x3b, 0x64, 0x65, 0x20, 0x67, -0x65, 0x6e, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x20, 0x66, 0x65, 0x62, 0x72, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x20, 0x6d, 0x61, -0x72, 0xe7, 0x3b, 0x64, 0x2019, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x64, 0x65, 0x20, 0x6d, 0x61, 0x69, 0x67, 0x3b, 0x64, -0x65, 0x20, 0x6a, 0x75, 0x6e, 0x79, 0x3b, 0x64, 0x65, 0x20, 0x6a, 0x75, 0x6c, 0x69, 0x6f, 0x6c, 0x3b, 0x64, 0x2019, 0x61, -0x67, 0x6f, 0x73, 0x74, 0x3b, 0x64, 0x65, 0x20, 0x73, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x2019, 0x6f, -0x63, 0x74, 0x75, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x65, 0x20, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, -0x65, 0x20, 0x64, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x31, 0x6708, 0x3b, 0x32, 0x6708, 0x3b, 0x33, 0x6708, 0x3b, -0x34, 0x6708, 0x3b, 0x35, 0x6708, 0x3b, 0x36, 0x6708, 0x3b, 0x37, 0x6708, 0x3b, 0x38, 0x6708, 0x3b, 0x39, 0x6708, 0x3b, 0x31, 0x30, -0x6708, 0x3b, 0x31, 0x31, 0x6708, 0x3b, 0x31, 0x32, 0x6708, 0x3b, 0x4e00, 0x6708, 0x3b, 0x4e8c, 0x6708, 0x3b, 0x4e09, 0x6708, 0x3b, 0x56db, -0x6708, 0x3b, 0x4e94, 0x6708, 0x3b, 0x516d, 0x6708, 0x3b, 0x4e03, 0x6708, 0x3b, 0x516b, 0x6708, 0x3b, 0x4e5d, 0x6708, 0x3b, 0x5341, 0x6708, 0x3b, -0x5341, 0x4e00, 0x6708, 0x3b, 0x5341, 0x4e8c, 0x6708, 0x3b, 0x73, 0x69, 0x6a, 0x3b, 0x76, 0x65, 0x6c, 0x6a, 0x3b, 0x6f, 0x17e, 0x75, -0x3b, 0x74, 0x72, 0x61, 0x3b, 0x73, 0x76, 0x69, 0x3b, 0x6c, 0x69, 0x70, 0x3b, 0x73, 0x72, 0x70, 0x3b, 0x6b, 0x6f, 0x6c, -0x3b, 0x72, 0x75, 0x6a, 0x3b, 0x6c, 0x69, 0x73, 0x3b, 0x73, 0x74, 0x75, 0x3b, 0x70, 0x72, 0x6f, 0x3b, 0x73, 0x69, 0x6a, -0x65, 0x10d, 0x61, 0x6e, 0x6a, 0x3b, 0x76, 0x65, 0x6c, 0x6a, 0x61, 0x10d, 0x61, 0x3b, 0x6f, 0x17e, 0x75, 0x6a, 0x61, 0x6b, -0x3b, 0x74, 0x72, 0x61, 0x76, 0x61, 0x6e, 0x6a, 0x3b, 0x73, 0x76, 0x69, 0x62, 0x61, 0x6e, 0x6a, 0x3b, 0x6c, 0x69, 0x70, -0x61, 0x6e, 0x6a, 0x3b, 0x73, 0x72, 0x70, 0x61, 0x6e, 0x6a, 0x3b, 0x6b, 0x6f, 0x6c, 0x6f, 0x76, 0x6f, 0x7a, 0x3b, 0x72, -0x75, 0x6a, 0x61, 0x6e, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x3b, 0x73, 0x74, 0x75, 0x64, 0x65, 0x6e, -0x69, 0x3b, 0x70, 0x72, 0x6f, 0x73, 0x69, 0x6e, 0x61, 0x63, 0x3b, 0x31, 0x2e, 0x3b, 0x32, 0x2e, 0x3b, 0x33, 0x2e, 0x3b, -0x34, 0x2e, 0x3b, 0x35, 0x2e, 0x3b, 0x36, 0x2e, 0x3b, 0x37, 0x2e, 0x3b, 0x38, 0x2e, 0x3b, 0x39, 0x2e, 0x3b, 0x31, 0x30, -0x2e, 0x3b, 0x31, 0x31, 0x2e, 0x3b, 0x31, 0x32, 0x2e, 0x3b, 0x73, 0x69, 0x6a, 0x65, 0x10d, 0x6e, 0x6a, 0x61, 0x3b, 0x76, -0x65, 0x6c, 0x6a, 0x61, 0x10d, 0x65, 0x3b, 0x6f, 0x17e, 0x75, 0x6a, 0x6b, 0x61, 0x3b, 0x74, 0x72, 0x61, 0x76, 0x6e, 0x6a, -0x61, 0x3b, 0x73, 0x76, 0x69, 0x62, 0x6e, 0x6a, 0x61, 0x3b, 0x6c, 0x69, 0x70, 0x6e, 0x6a, 0x61, 0x3b, 0x73, 0x72, 0x70, -0x6e, 0x6a, 0x61, 0x3b, 0x6b, 0x6f, 0x6c, 0x6f, 0x76, 0x6f, 0x7a, 0x61, 0x3b, 0x72, 0x75, 0x6a, 0x6e, 0x61, 0x3b, 0x6c, -0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x61, 0x3b, 0x73, 0x74, 0x75, 0x64, 0x65, 0x6e, 0x6f, 0x67, 0x61, 0x3b, 0x70, -0x72, 0x6f, 0x73, 0x69, 0x6e, 0x63, 0x61, 0x3b, 0x6c, 0x65, 0x64, 0x3b, 0xfa, 0x6e, 0x6f, 0x3b, 0x62, 0x159, 0x65, 0x3b, -0x64, 0x75, 0x62, 0x3b, 0x6b, 0x76, 0x11b, 0x3b, 0x10d, 0x76, 0x6e, 0x3b, 0x10d, 0x76, 0x63, 0x3b, 0x73, 0x72, 0x70, 0x3b, -0x7a, 0xe1, 0x159, 0x3b, 0x159, 0xed, 0x6a, 0x3b, 0x6c, 0x69, 0x73, 0x3b, 0x70, 0x72, 0x6f, 0x3b, 0x6c, 0x65, 0x64, 0x65, -0x6e, 0x3b, 0xfa, 0x6e, 0x6f, 0x72, 0x3b, 0x62, 0x159, 0x65, 0x7a, 0x65, 0x6e, 0x3b, 0x64, 0x75, 0x62, 0x65, 0x6e, 0x3b, -0x6b, 0x76, 0x11b, 0x74, 0x65, 0x6e, 0x3b, 0x10d, 0x65, 0x72, 0x76, 0x65, 0x6e, 0x3b, 0x10d, 0x65, 0x72, 0x76, 0x65, 0x6e, -0x65, 0x63, 0x3b, 0x73, 0x72, 0x70, 0x65, 0x6e, 0x3b, 0x7a, 0xe1, 0x159, 0xed, 0x3b, 0x159, 0xed, 0x6a, 0x65, 0x6e, 0x3b, -0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x3b, 0x70, 0x72, 0x6f, 0x73, 0x69, 0x6e, 0x65, 0x63, 0x3b, 0x6c, 0x65, -0x64, 0x6e, 0x61, 0x3b, 0xfa, 0x6e, 0x6f, 0x72, 0x61, 0x3b, 0x62, 0x159, 0x65, 0x7a, 0x6e, 0x61, 0x3b, 0x64, 0x75, 0x62, -0x6e, 0x61, 0x3b, 0x6b, 0x76, 0x11b, 0x74, 0x6e, 0x61, 0x3b, 0x10d, 0x65, 0x72, 0x76, 0x6e, 0x61, 0x3b, 0x10d, 0x65, 0x72, -0x76, 0x65, 0x6e, 0x63, 0x65, 0x3b, 0x73, 0x72, 0x70, 0x6e, 0x61, 0x3b, 0x7a, 0xe1, 0x159, 0xed, 0x3b, 0x159, 0xed, 0x6a, -0x6e, 0x61, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x75, 0x3b, 0x70, 0x72, 0x6f, 0x73, 0x69, 0x6e, 0x63, -0x65, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x72, -0x2e, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x75, 0x67, 0x2e, -0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, -0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x74, -0x73, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, -0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, -0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, -0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x72, 0x74, 0x2e, 0x3b, -0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x65, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, -0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, -0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, -0x3b, 0x6d, 0x61, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x65, 0x69, 0x3b, 0x6a, 0x75, 0x6e, -0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x75, 0x73, 0x3b, 0x73, 0x65, 0x70, 0x74, -0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, -0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x61, 0x6e, 0x2e, 0x3b, 0x46, 0x65, 0x62, -0x2e, 0x3b, 0x4d, 0x61, 0x72, 0x2e, 0x3b, 0x41, 0x70, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x4a, 0x75, 0x6e, 0x2e, -0x3b, 0x4a, 0x75, 0x6c, 0x2e, 0x3b, 0x41, 0x75, 0x67, 0x2e, 0x3b, 0x53, 0x65, 0x70, 0x2e, 0x3b, 0x4f, 0x63, 0x74, 0x2e, -0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, -0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, -0x16d, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x6a, -0x61, 0x6e, 0x75, 0x61, 0x72, 0x6f, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x74, -0x6f, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x6f, 0x3b, 0x6d, 0x61, 0x6a, 0x6f, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x6f, 0x3b, -0x6a, 0x75, 0x6c, 0x69, 0x6f, 0x3b, 0x61, 0x16d, 0x67, 0x75, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, -0x62, 0x72, 0x6f, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x72, 0x6f, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x6f, -0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x6a, 0x61, 0x61, 0x6e, 0x3b, 0x76, 0x65, 0x65, 0x62, 0x72, -0x3b, 0x6d, 0xe4, 0x72, 0x74, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x75, 0x6e, 0x69, -0x3b, 0x6a, 0x75, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, -0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x74, 0x73, 0x3b, 0x6a, 0x61, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x76, 0x65, 0x65, -0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0xe4, 0x72, 0x74, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x6c, 0x3b, 0x6d, -0x61, 0x69, 0x3b, 0x6a, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, -0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x6f, 0x62, 0x65, 0x72, -0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x74, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, -0x4a, 0x3b, 0x56, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, -0x4e, 0x3b, 0x44, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, -0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x75, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, -0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x73, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, -0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0xed, 0x6c, 0x3b, 0x6d, 0x61, -0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, -0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, -0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, -0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, -0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, -0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x73, 0x2e, 0x3b, 0x74, 0x61, 0x6d, 0x6d, 0x69, 0x3b, -0x68, 0x65, 0x6c, 0x6d, 0x69, 0x3b, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x73, 0x3b, 0x68, 0x75, 0x68, 0x74, 0x69, 0x3b, 0x74, -0x6f, 0x75, 0x6b, 0x6f, 0x3b, 0x6b, 0x65, 0x73, 0xe4, 0x3b, 0x68, 0x65, 0x69, 0x6e, 0xe4, 0x3b, 0x65, 0x6c, 0x6f, 0x3b, -0x73, 0x79, 0x79, 0x73, 0x3b, 0x6c, 0x6f, 0x6b, 0x61, 0x3b, 0x6d, 0x61, 0x72, 0x72, 0x61, 0x73, 0x3b, 0x6a, 0x6f, 0x75, -0x6c, 0x75, 0x3b, 0x74, 0x61, 0x6d, 0x6d, 0x69, 0x6b, 0x75, 0x75, 0x3b, 0x68, 0x65, 0x6c, 0x6d, 0x69, 0x6b, 0x75, 0x75, -0x3b, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x73, 0x6b, 0x75, 0x75, 0x3b, 0x68, 0x75, 0x68, 0x74, 0x69, 0x6b, 0x75, 0x75, 0x3b, -0x74, 0x6f, 0x75, 0x6b, 0x6f, 0x6b, 0x75, 0x75, 0x3b, 0x6b, 0x65, 0x73, 0xe4, 0x6b, 0x75, 0x75, 0x3b, 0x68, 0x65, 0x69, -0x6e, 0xe4, 0x6b, 0x75, 0x75, 0x3b, 0x65, 0x6c, 0x6f, 0x6b, 0x75, 0x75, 0x3b, 0x73, 0x79, 0x79, 0x73, 0x6b, 0x75, 0x75, -0x3b, 0x6c, 0x6f, 0x6b, 0x61, 0x6b, 0x75, 0x75, 0x3b, 0x6d, 0x61, 0x72, 0x72, 0x61, 0x73, 0x6b, 0x75, 0x75, 0x3b, 0x6a, -0x6f, 0x75, 0x6c, 0x75, 0x6b, 0x75, 0x75, 0x3b, 0x54, 0x3b, 0x48, 0x3b, 0x4d, 0x3b, 0x48, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, -0x48, 0x3b, 0x45, 0x3b, 0x53, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x74, 0x61, 0x6d, 0x6d, 0x69, 0x6b, 0x2e, 0x3b, -0x68, 0x65, 0x6c, 0x6d, 0x69, 0x6b, 0x2e, 0x3b, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x73, 0x6b, 0x2e, 0x3b, 0x68, 0x75, 0x68, -0x74, 0x69, 0x6b, 0x2e, 0x3b, 0x74, 0x6f, 0x75, 0x6b, 0x6f, 0x6b, 0x2e, 0x3b, 0x6b, 0x65, 0x73, 0xe4, 0x6b, 0x2e, 0x3b, -0x68, 0x65, 0x69, 0x6e, 0xe4, 0x6b, 0x2e, 0x3b, 0x65, 0x6c, 0x6f, 0x6b, 0x2e, 0x3b, 0x73, 0x79, 0x79, 0x73, 0x6b, 0x2e, -0x3b, 0x6c, 0x6f, 0x6b, 0x61, 0x6b, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x72, 0x61, 0x73, 0x6b, 0x2e, 0x3b, 0x6a, 0x6f, 0x75, -0x6c, 0x75, 0x6b, 0x2e, 0x3b, 0x74, 0x61, 0x6d, 0x6d, 0x69, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x68, 0x65, 0x6c, 0x6d, -0x69, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x73, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x68, -0x75, 0x68, 0x74, 0x69, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x74, 0x6f, 0x75, 0x6b, 0x6f, 0x6b, 0x75, 0x75, 0x74, 0x61, -0x3b, 0x6b, 0x65, 0x73, 0xe4, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x68, 0x65, 0x69, 0x6e, 0xe4, 0x6b, 0x75, 0x75, 0x74, -0x61, 0x3b, 0x65, 0x6c, 0x6f, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x73, 0x79, 0x79, 0x73, 0x6b, 0x75, 0x75, 0x74, 0x61, -0x3b, 0x6c, 0x6f, 0x6b, 0x61, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x6d, 0x61, 0x72, 0x72, 0x61, 0x73, 0x6b, 0x75, 0x75, -0x74, 0x61, 0x3b, 0x6a, 0x6f, 0x75, 0x6c, 0x75, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x6a, 0x61, 0x6e, 0x76, 0x2e, 0x3b, -0x66, 0xe9, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b, -0x6a, 0x75, 0x69, 0x6e, 0x3b, 0x6a, 0x75, 0x69, 0x6c, 0x2e, 0x3b, 0x61, 0x6f, 0xfb, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, -0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0xe9, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, -0x76, 0x69, 0x65, 0x72, 0x3b, 0x66, 0xe9, 0x76, 0x72, 0x69, 0x65, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x76, -0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x69, 0x6e, 0x3b, 0x6a, 0x75, 0x69, 0x6c, 0x6c, 0x65, 0x74, -0x3b, 0x61, 0x6f, 0xfb, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x6f, -0x62, 0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0xe9, 0x63, 0x65, 0x6d, 0x62, 0x72, -0x65, 0x3b, 0x6a, 0x61, 0x6e, 0x76, 0x2e, 0x3b, 0x66, 0xe9, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, -0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x69, 0x6e, 0x3b, 0x6a, 0x75, 0x69, 0x6c, 0x6c, 0x2e, 0x3b, -0x61, 0x6f, 0xfb, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, -0x3b, 0x64, 0xe9, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0xe9, 0x76, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, -0x3b, 0x61, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x69, 0x2e, 0x3b, 0x6a, 0x75, 0x69, 0x6c, 0x2e, -0x3b, 0x61, 0x6f, 0xfb, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, -0x2e, 0x3b, 0x64, 0xe9, 0x63, 0x2e, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x72, 0x74, 0x3b, 0x41, -0x70, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x75, 0x67, 0x3b, 0x53, -0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x6e, 0x65, -0x77, 0x61, 0x72, 0x69, 0x73, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x65, 0x77, 0x61, 0x72, 0x69, 0x73, 0x3b, 0x4d, 0x61, 0x61, -0x72, 0x74, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x61, 0x69, 0x65, 0x3b, 0x4a, 0x75, 0x6e, 0x79, 0x3b, -0x4a, 0x75, 0x6c, 0x79, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x75, 0x73, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x69, 0x6d, -0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x69, 0x6d, 0x62, 0x65, 0x72, -0x3b, 0x44, 0x65, 0x73, 0x69, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x46, 0x61, 0x6f, 0x69, 0x3b, 0x47, 0x65, 0x61, 0x72, 0x72, -0x3b, 0x4d, 0xe0, 0x72, 0x74, 0x3b, 0x47, 0x69, 0x62, 0x6c, 0x3b, 0x43, 0xe8, 0x69, 0x74, 0x3b, 0xd2, 0x67, 0x6d, 0x68, -0x3b, 0x49, 0x75, 0x63, 0x68, 0x3b, 0x4c, 0xf9, 0x6e, 0x61, 0x3b, 0x53, 0x75, 0x6c, 0x74, 0x3b, 0x44, 0xe0, 0x6d, 0x68, -0x3b, 0x53, 0x61, 0x6d, 0x68, 0x3b, 0x44, 0xf9, 0x62, 0x68, 0x3b, 0x41, 0x6d, 0x20, 0x46, 0x61, 0x6f, 0x69, 0x6c, 0x6c, -0x65, 0x61, 0x63, 0x68, 0x3b, 0x41, 0x6e, 0x20, 0x47, 0x65, 0x61, 0x72, 0x72, 0x61, 0x6e, 0x3b, 0x41, 0x6d, 0x20, 0x4d, -0xe0, 0x72, 0x74, 0x3b, 0x41, 0x6e, 0x20, 0x47, 0x69, 0x62, 0x6c, 0x65, 0x61, 0x6e, 0x3b, 0x41, 0x6e, 0x20, 0x43, 0xe8, -0x69, 0x74, 0x65, 0x61, 0x6e, 0x3b, 0x41, 0x6e, 0x20, 0x74, 0x2d, 0xd2, 0x67, 0x6d, 0x68, 0x69, 0x6f, 0x73, 0x3b, 0x41, -0x6e, 0x20, 0x74, 0x2d, 0x49, 0x75, 0x63, 0x68, 0x61, 0x72, 0x3b, 0x41, 0x6e, 0x20, 0x4c, 0xf9, 0x6e, 0x61, 0x73, 0x74, -0x61, 0x6c, 0x3b, 0x41, 0x6e, 0x20, 0x74, 0x2d, 0x53, 0x75, 0x6c, 0x74, 0x61, 0x69, 0x6e, 0x3b, 0x41, 0x6e, 0x20, 0x44, -0xe0, 0x6d, 0x68, 0x61, 0x69, 0x72, 0x3b, 0x41, 0x6e, 0x20, 0x74, 0x2d, 0x53, 0x61, 0x6d, 0x68, 0x61, 0x69, 0x6e, 0x3b, -0x41, 0x6e, 0x20, 0x44, 0xf9, 0x62, 0x68, 0x6c, 0x61, 0x63, 0x68, 0x64, 0x3b, 0x46, 0x3b, 0x47, 0x3b, 0x4d, 0x3b, 0x47, -0x3b, 0x43, 0x3b, 0xd2, 0x3b, 0x49, 0x3b, 0x4c, 0x3b, 0x53, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x44, 0x3b, 0x64, 0x68, 0x65, -0x6e, 0x20, 0x46, 0x68, 0x61, 0x6f, 0x69, 0x6c, 0x6c, 0x65, 0x61, 0x63, 0x68, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x47, -0x68, 0x65, 0x61, 0x72, 0x72, 0x61, 0x6e, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x4d, 0x68, 0xe0, 0x72, 0x74, 0x3b, 0x64, -0x68, 0x65, 0x6e, 0x20, 0x47, 0x68, 0x69, 0x62, 0x6c, 0x65, 0x61, 0x6e, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x43, 0x68, -0xe8, 0x69, 0x74, 0x65, 0x61, 0x6e, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0xd2, 0x67, 0x6d, 0x68, 0x69, 0x6f, 0x73, 0x3b, -0x64, 0x68, 0x65, 0x6e, 0x20, 0x49, 0x75, 0x63, 0x68, 0x61, 0x72, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x4c, 0xf9, 0x6e, -0x61, 0x73, 0x74, 0x61, 0x6c, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x2d, 0x53, 0x75, 0x6c, 0x74, 0x61, 0x69, 0x6e, -0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x44, 0xe0, 0x6d, 0x68, 0x61, 0x69, 0x72, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x74, -0x2d, 0x53, 0x61, 0x6d, 0x68, 0x61, 0x69, 0x6e, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x44, 0xf9, 0x62, 0x68, 0x6c, 0x61, -0x63, 0x68, 0x64, 0x3b, 0x58, 0x61, 0x6e, 0x2e, 0x3b, 0x46, 0x65, 0x62, 0x2e, 0x3b, 0x4d, 0x61, 0x72, 0x2e, 0x3b, 0x41, -0x62, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x69, 0x6f, 0x3b, 0x58, 0x75, 0xf1, 0x6f, 0x3b, 0x58, 0x75, 0x6c, 0x2e, 0x3b, 0x41, -0x67, 0x6f, 0x2e, 0x3b, 0x53, 0x65, 0x74, 0x2e, 0x3b, 0x4f, 0x75, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, -0x65, 0x63, 0x2e, 0x3b, 0x58, 0x61, 0x6e, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x65, 0x69, 0x72, 0x6f, -0x3b, 0x4d, 0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x6f, 0x3b, 0x58, 0x75, -0xf1, 0x6f, 0x3b, 0x58, 0x75, 0x6c, 0x6c, 0x6f, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x65, -0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x4f, 0x75, 0x74, 0x75, 0x62, 0x72, 0x6f, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, -0x6f, 0x3b, 0x44, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x58, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, -0x3b, 0x58, 0x3b, 0x58, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x78, 0x61, 0x6e, 0x2e, 0x3b, -0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x6f, 0x3b, -0x78, 0x75, 0xf1, 0x6f, 0x3b, 0x78, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x67, 0x6f, 0x2e, 0x3b, 0x73, 0x65, 0x74, 0x2e, 0x3b, -0x6f, 0x75, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x78, 0x61, 0x6e, 0x65, 0x69, -0x72, 0x6f, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x61, 0x62, -0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x6f, 0x3b, 0x78, 0x75, 0xf1, 0x6f, 0x3b, 0x78, 0x75, 0x6c, 0x6c, 0x6f, 0x3b, -0x61, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x6f, 0x75, 0x74, 0x75, +0x628, 0x631, 0x3b, 0x62c, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x623, 0x3b, 0x645, 0x3b, 0x62c, 0x3b, 0x62c, 0x3b, 0x623, 0x3b, 0x633, +0x3b, 0x623, 0x3b, 0x646, 0x3b, 0x62f, 0x3b, 0x643, 0x627, 0x646, 0x648, 0x646, 0x20, 0x627, 0x644, 0x62b, 0x627, 0x646, 0x64a, 0x3b, +0x634, 0x628, 0x627, 0x637, 0x3b, 0x622, 0x630, 0x627, 0x631, 0x3b, 0x646, 0x64a, 0x633, 0x627, 0x646, 0x3b, 0x623, 0x64a, 0x627, 0x631, +0x3b, 0x62d, 0x632, 0x64a, 0x631, 0x627, 0x646, 0x3b, 0x62a, 0x645, 0x648, 0x632, 0x3b, 0x622, 0x628, 0x3b, 0x623, 0x64a, 0x644, 0x648, +0x644, 0x3b, 0x62a, 0x634, 0x631, 0x64a, 0x646, 0x20, 0x627, 0x644, 0x623, 0x648, 0x644, 0x3b, 0x62a, 0x634, 0x631, 0x64a, 0x646, 0x20, +0x627, 0x644, 0x62b, 0x627, 0x646, 0x64a, 0x3b, 0x643, 0x627, 0x646, 0x648, 0x646, 0x20, 0x627, 0x644, 0x623, 0x648, 0x644, 0x3b, 0x643, +0x3b, 0x634, 0x3b, 0x622, 0x3b, 0x646, 0x3b, 0x623, 0x3b, 0x62d, 0x3b, 0x62a, 0x3b, 0x622, 0x3b, 0x623, 0x3b, 0x62a, 0x3b, 0x62a, +0x3b, 0x643, 0x3b, 0x643, 0x627, 0x646, 0x648, 0x646, 0x20, 0x627, 0x644, 0x62b, 0x627, 0x646, 0x64a, 0x3b, 0x634, 0x628, 0x627, 0x637, +0x3b, 0x622, 0x630, 0x627, 0x631, 0x3b, 0x646, 0x64a, 0x633, 0x627, 0x646, 0x3b, 0x623, 0x64a, 0x627, 0x631, 0x3b, 0x62d, 0x632, 0x64a, +0x631, 0x627, 0x646, 0x3b, 0x62a, 0x645, 0x648, 0x632, 0x3b, 0x622, 0x628, 0x3b, 0x623, 0x64a, 0x644, 0x648, 0x644, 0x3b, 0x62a, 0x634, +0x631, 0x64a, 0x646, 0xa0, 0x627, 0x644, 0x623, 0x648, 0x644, 0x3b, 0x62a, 0x634, 0x631, 0x64a, 0x646, 0x20, 0x627, 0x644, 0x62b, 0x627, +0x646, 0x64a, 0x3b, 0x643, 0x627, 0x646, 0x648, 0x646, 0x20, 0x627, 0x644, 0x623, 0x648, 0x644, 0x3b, 0x64a, 0x646, 0x627, 0x64a, 0x631, +0x3b, 0x641, 0x628, 0x631, 0x627, 0x64a, 0x631, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x625, 0x628, 0x631, 0x64a, 0x644, 0x3b, 0x645, +0x627, 0x64a, 0x648, 0x3b, 0x64a, 0x648, 0x646, 0x64a, 0x648, 0x3b, 0x64a, 0x648, 0x644, 0x64a, 0x648, 0x3b, 0x623, 0x63a, 0x634, 0x62a, +0x3b, 0x634, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x623, 0x643, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x641, 0x645, 0x628, 0x631, +0x3b, 0x62f, 0x62c, 0x645, 0x628, 0x631, 0x3b, 0x64a, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x625, 0x3b, 0x648, 0x3b, 0x646, 0x3b, 0x644, +0x3b, 0x63a, 0x3b, 0x634, 0x3b, 0x643, 0x3b, 0x628, 0x3b, 0x62f, 0x3b, 0x64a, 0x646, 0x627, 0x64a, 0x631, 0x3b, 0x641, 0x628, 0x631, +0x627, 0x64a, 0x631, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x623, 0x628, 0x631, 0x64a, 0x644, 0x3b, 0x645, 0x627, 0x64a, 0x3b, 0x64a, +0x648, 0x646, 0x64a, 0x648, 0x3b, 0x64a, 0x648, 0x644, 0x64a, 0x648, 0x632, 0x3b, 0x63a, 0x634, 0x62a, 0x3b, 0x634, 0x62a, 0x646, 0x628, +0x631, 0x3b, 0x623, 0x643, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x646, 0x628, 0x631, 0x3b, 0x62f, 0x62c, 0x646, 0x628, 0x631, +0x3b, 0x64a, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x623, 0x3b, 0x645, 0x3b, 0x646, 0x3b, 0x644, 0x3b, 0x63a, 0x3b, 0x634, 0x3b, 0x643, +0x3b, 0x628, 0x3b, 0x62f, 0x3b, 0x570, 0x576, 0x57e, 0x3b, 0x583, 0x57f, 0x57e, 0x3b, 0x574, 0x580, 0x57f, 0x3b, 0x561, 0x57a, 0x580, +0x3b, 0x574, 0x575, 0x57d, 0x3b, 0x570, 0x576, 0x57d, 0x3b, 0x570, 0x56c, 0x57d, 0x3b, 0x585, 0x563, 0x57d, 0x3b, 0x57d, 0x565, 0x57a, +0x3b, 0x570, 0x578, 0x56f, 0x3b, 0x576, 0x578, 0x575, 0x3b, 0x564, 0x565, 0x56f, 0x3b, 0x570, 0x578, 0x582, 0x576, 0x57e, 0x561, 0x580, +0x3b, 0x583, 0x565, 0x57f, 0x580, 0x57e, 0x561, 0x580, 0x3b, 0x574, 0x561, 0x580, 0x57f, 0x3b, 0x561, 0x57a, 0x580, 0x56b, 0x56c, 0x3b, +0x574, 0x561, 0x575, 0x56b, 0x57d, 0x3b, 0x570, 0x578, 0x582, 0x576, 0x56b, 0x57d, 0x3b, 0x570, 0x578, 0x582, 0x56c, 0x56b, 0x57d, 0x3b, +0x585, 0x563, 0x578, 0x57d, 0x57f, 0x578, 0x57d, 0x3b, 0x57d, 0x565, 0x57a, 0x57f, 0x565, 0x574, 0x562, 0x565, 0x580, 0x3b, 0x570, 0x578, +0x56f, 0x57f, 0x565, 0x574, 0x562, 0x565, 0x580, 0x3b, 0x576, 0x578, 0x575, 0x565, 0x574, 0x562, 0x565, 0x580, 0x3b, 0x564, 0x565, 0x56f, +0x57f, 0x565, 0x574, 0x562, 0x565, 0x580, 0x3b, 0x540, 0x3b, 0x553, 0x3b, 0x544, 0x3b, 0x531, 0x3b, 0x544, 0x3b, 0x540, 0x3b, 0x540, +0x3b, 0x555, 0x3b, 0x54d, 0x3b, 0x540, 0x3b, 0x546, 0x3b, 0x534, 0x3b, 0x570, 0x578, 0x582, 0x576, 0x57e, 0x561, 0x580, 0x56b, 0x3b, +0x583, 0x565, 0x57f, 0x580, 0x57e, 0x561, 0x580, 0x56b, 0x3b, 0x574, 0x561, 0x580, 0x57f, 0x56b, 0x3b, 0x561, 0x57a, 0x580, 0x56b, 0x56c, +0x56b, 0x3b, 0x574, 0x561, 0x575, 0x56b, 0x57d, 0x56b, 0x3b, 0x570, 0x578, 0x582, 0x576, 0x56b, 0x57d, 0x56b, 0x3b, 0x570, 0x578, 0x582, +0x56c, 0x56b, 0x57d, 0x56b, 0x3b, 0x585, 0x563, 0x578, 0x57d, 0x57f, 0x578, 0x57d, 0x56b, 0x3b, 0x57d, 0x565, 0x57a, 0x57f, 0x565, 0x574, +0x562, 0x565, 0x580, 0x56b, 0x3b, 0x570, 0x578, 0x56f, 0x57f, 0x565, 0x574, 0x562, 0x565, 0x580, 0x56b, 0x3b, 0x576, 0x578, 0x575, 0x565, +0x574, 0x562, 0x565, 0x580, 0x56b, 0x3b, 0x564, 0x565, 0x56f, 0x57f, 0x565, 0x574, 0x562, 0x565, 0x580, 0x56b, 0x3b, 0x99c, 0x9be, 0x9a8, +0x9c1, 0x3b, 0x9ab, 0x9c7, 0x9ac, 0x9cd, 0x9f0, 0x9c1, 0x3b, 0x9ae, 0x9be, 0x9f0, 0x9cd, 0x99a, 0x3b, 0x98f, 0x9aa, 0x9cd, 0x9f0, 0x9bf, +0x9b2, 0x3b, 0x9ae, 0x9c7, 0x2019, 0x3b, 0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1, 0x9b2, 0x9be, 0x987, 0x3b, 0x986, 0x997, 0x3b, 0x99b, +0x9c7, 0x9aa, 0x9cd, 0x9a4, 0x9c7, 0x3b, 0x985, 0x995, 0x9cd, 0x99f, 0x9cb, 0x3b, 0x9a8, 0x9f1, 0x9c7, 0x3b, 0x9a1, 0x9bf, 0x99a, 0x9c7, +0x3b, 0x99c, 0x9be, 0x9a8, 0x9c1, 0x9f1, 0x9be, 0x9f0, 0x9c0, 0x3b, 0x9ab, 0x9c7, 0x9ac, 0x9cd, 0x9f0, 0x9c1, 0x9f1, 0x9be, 0x9f0, 0x9c0, +0x3b, 0x9ae, 0x9be, 0x9f0, 0x9cd, 0x99a, 0x3b, 0x98f, 0x9aa, 0x9cd, 0x9f0, 0x9bf, 0x9b2, 0x3b, 0x9ae, 0x9c7, 0x2019, 0x3b, 0x99c, 0x9c1, +0x9a8, 0x3b, 0x99c, 0x9c1, 0x9b2, 0x9be, 0x987, 0x3b, 0x986, 0x997, 0x9b7, 0x9cd, 0x99f, 0x3b, 0x99b, 0x9c7, 0x9aa, 0x9cd, 0x9a4, 0x9c7, +0x9ae, 0x9cd, 0x9ac, 0x9f0, 0x3b, 0x985, 0x995, 0x9cd, 0x99f, 0x9cb, 0x9ac, 0x9f0, 0x3b, 0x9a8, 0x9f1, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9f0, +0x3b, 0x9a1, 0x9bf, 0x99a, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9f0, 0x3b, 0x99c, 0x3b, 0x9ab, 0x3b, 0x9ae, 0x3b, 0x98f, 0x3b, 0x9ae, 0x3b, +0x99c, 0x3b, 0x99c, 0x3b, 0x986, 0x3b, 0x99b, 0x3b, 0x985, 0x3b, 0x9a8, 0x3b, 0x9a1, 0x3b, 0x79, 0x61, 0x6e, 0x3b, 0x66, 0x65, +0x76, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x69, 0x79, 0x6e, 0x3b, 0x69, 0x79, +0x6c, 0x3b, 0x61, 0x76, 0x71, 0x3b, 0x73, 0x65, 0x6e, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x79, 0x3b, 0x64, 0x65, +0x6b, 0x3b, 0x59, 0x61, 0x6e, 0x76, 0x61, 0x72, 0x3b, 0x46, 0x65, 0x76, 0x72, 0x61, 0x6c, 0x3b, 0x4d, 0x61, 0x72, 0x74, +0x3b, 0x41, 0x70, 0x72, 0x65, 0x6c, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x130, 0x79, 0x75, 0x6e, 0x3b, 0x130, 0x79, 0x75, 0x6c, +0x3b, 0x41, 0x76, 0x71, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x6e, 0x74, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x4f, 0x6b, 0x74, +0x79, 0x61, 0x62, 0x72, 0x3b, 0x4e, 0x6f, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x44, 0x65, 0x6b, 0x61, 0x62, 0x72, 0x3b, 0x79, +0x61, 0x6e, 0x76, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x76, 0x72, 0x61, 0x6c, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, +0x72, 0x65, 0x6c, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x69, 0x79, 0x75, 0x6e, 0x3b, 0x69, 0x79, 0x75, 0x6c, 0x3b, 0x61, 0x76, +0x71, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x6e, 0x74, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x79, 0x61, 0x62, +0x72, 0x3b, 0x6e, 0x6f, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x64, 0x65, 0x6b, 0x61, 0x62, 0x72, 0x3b, 0x458, 0x430, 0x43d, 0x3b, +0x444, 0x435, 0x432, 0x3b, 0x43c, 0x430, 0x440, 0x3b, 0x430, 0x43f, 0x440, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x438, 0x458, 0x43d, 0x3b, +0x438, 0x458, 0x43b, 0x3b, 0x430, 0x432, 0x433, 0x3b, 0x441, 0x435, 0x43d, 0x3b, 0x43e, 0x43a, 0x442, 0x3b, 0x43d, 0x43e, 0x458, 0x3b, +0x434, 0x435, 0x43a, 0x3b, 0x408, 0x430, 0x43d, 0x432, 0x430, 0x440, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x3b, 0x41c, 0x430, +0x440, 0x442, 0x3b, 0x410, 0x43f, 0x440, 0x435, 0x43b, 0x3b, 0x41c, 0x430, 0x439, 0x3b, 0x418, 0x458, 0x443, 0x43d, 0x3b, 0x418, 0x458, +0x443, 0x43b, 0x3b, 0x410, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x421, 0x435, 0x43d, 0x442, 0x458, 0x430, 0x431, 0x440, 0x3b, 0x41e, +0x43a, 0x442, 0x458, 0x430, 0x431, 0x440, 0x3b, 0x41d, 0x43e, 0x458, 0x430, 0x431, 0x440, 0x3b, 0x414, 0x435, 0x43a, 0x430, 0x431, 0x440, +0x3b, 0x458, 0x430, 0x43d, 0x432, 0x430, 0x440, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, +0x430, 0x43f, 0x440, 0x435, 0x43b, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x438, 0x458, 0x443, 0x43d, 0x3b, 0x438, 0x458, 0x443, 0x43b, 0x3b, +0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x458, 0x430, 0x431, 0x440, 0x3b, 0x43e, 0x43a, 0x442, 0x458, +0x430, 0x431, 0x440, 0x3b, 0x43d, 0x43e, 0x458, 0x430, 0x431, 0x440, 0x3b, 0x434, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x3b, 0x75, 0x72, +0x74, 0x2e, 0x3b, 0x6f, 0x74, 0x73, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x69, 0x2e, 0x3b, 0x6d, 0x61, +0x69, 0x2e, 0x3b, 0x65, 0x6b, 0x61, 0x2e, 0x3b, 0x75, 0x7a, 0x74, 0x2e, 0x3b, 0x61, 0x62, 0x75, 0x2e, 0x3b, 0x69, 0x72, +0x61, 0x2e, 0x3b, 0x75, 0x72, 0x72, 0x2e, 0x3b, 0x61, 0x7a, 0x61, 0x2e, 0x3b, 0x61, 0x62, 0x65, 0x2e, 0x3b, 0x75, 0x72, +0x74, 0x61, 0x72, 0x72, 0x69, 0x6c, 0x61, 0x3b, 0x6f, 0x74, 0x73, 0x61, 0x69, 0x6c, 0x61, 0x3b, 0x6d, 0x61, 0x72, 0x74, +0x78, 0x6f, 0x61, 0x3b, 0x61, 0x70, 0x69, 0x72, 0x69, 0x6c, 0x61, 0x3b, 0x6d, 0x61, 0x69, 0x61, 0x74, 0x7a, 0x61, 0x3b, +0x65, 0x6b, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x75, 0x7a, 0x74, 0x61, 0x69, 0x6c, 0x61, 0x3b, 0x61, 0x62, 0x75, 0x7a, 0x74, +0x75, 0x61, 0x3b, 0x69, 0x72, 0x61, 0x69, 0x6c, 0x61, 0x3b, 0x75, 0x72, 0x72, 0x69, 0x61, 0x3b, 0x61, 0x7a, 0x61, 0x72, +0x6f, 0x61, 0x3b, 0x61, 0x62, 0x65, 0x6e, 0x64, 0x75, 0x61, 0x3b, 0x55, 0x3b, 0x4f, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, +0x3b, 0x45, 0x3b, 0x55, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x55, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x99c, 0x9be, 0x9a8, 0x9c1, 0x9af, +0x9bc, 0x9be, 0x9b0, 0x9c0, 0x3b, 0x9ab, 0x9c7, 0x9ac, 0x9cd, 0x9b0, 0x9c1, 0x9af, 0x9bc, 0x9be, 0x9b0, 0x9c0, 0x3b, 0x9ae, 0x9be, 0x9b0, +0x9cd, 0x99a, 0x3b, 0x98f, 0x9aa, 0x9cd, 0x9b0, 0x9bf, 0x9b2, 0x3b, 0x9ae, 0x9c7, 0x3b, 0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1, 0x9b2, +0x9be, 0x987, 0x3b, 0x986, 0x997, 0x9b8, 0x9cd, 0x99f, 0x3b, 0x9b8, 0x9c7, 0x9aa, 0x9cd, 0x99f, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9b0, 0x3b, +0x985, 0x995, 0x9cd, 0x99f, 0x9cb, 0x9ac, 0x9b0, 0x3b, 0x9a8, 0x9ad, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9b0, 0x3b, 0x9a1, 0x9bf, 0x9b8, 0x9c7, +0x9ae, 0x9cd, 0x9ac, 0x9b0, 0x3b, 0x99c, 0x9be, 0x3b, 0x9ab, 0x9c7, 0x3b, 0x9ae, 0x9be, 0x3b, 0x98f, 0x3b, 0x9ae, 0x9c7, 0x3b, 0x99c, +0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1, 0x3b, 0x986, 0x3b, 0x9b8, 0x9c7, 0x3b, 0x985, 0x3b, 0x9a8, 0x3b, 0x9a1, 0x9bf, 0x3b, 0x99c, 0x9be, +0x9a8, 0x9c1, 0x3b, 0x9ab, 0x9c7, 0x9ac, 0x3b, 0x9ae, 0x9be, 0x9b0, 0x9cd, 0x99a, 0x3b, 0x98f, 0x9aa, 0x9cd, 0x9b0, 0x9bf, 0x9b2, 0x3b, +0x9ae, 0x9c7, 0x3b, 0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1, 0x9b2, 0x9be, 0x987, 0x3b, 0x986, 0x997, 0x9b8, 0x9cd, 0x99f, 0x3b, 0x9b8, +0x9c7, 0x9aa, 0x9cd, 0x99f, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9b0, 0x3b, 0x985, 0x995, 0x9cd, 0x99f, 0x9cb, 0x9ac, 0x9b0, 0x3b, 0x9a8, 0x9ad, +0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9b0, 0x3b, 0x9a1, 0x9bf, 0x9b8, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9b0, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf21, 0x3b, +0xf5f, 0xfb3, 0xf0b, 0xf22, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf23, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf24, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf25, 0x3b, +0xf5f, 0xfb3, 0xf0b, 0xf26, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf27, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf28, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf29, 0x3b, +0xf5f, 0xfb3, 0xf0b, 0xf21, 0xf20, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf21, 0xf21, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf21, 0xf22, 0x3b, 0xf66, 0xfa4, +0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xf44, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf42, +0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf42, 0xf66, 0xf74, 0xf58, 0xf0b, +0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf5e, 0xf72, 0xf0b, 0xf54, 0x3b, 0xf66, 0xfa4, 0xfb1, +0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf63, 0xf94, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf51, +0xfb2, 0xf74, 0xf42, 0xf0b, 0xf54, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf51, 0xf74, 0xf53, 0xf0b, 0xf54, +0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf62, 0xf92, 0xfb1, 0xf51, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, +0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xf42, 0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, +0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, +0xf0b, 0xf42, 0xf45, 0xf72, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, +0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf21, 0x3b, 0xf22, 0x3b, 0xf23, 0x3b, 0xf24, 0x3b, 0xf25, 0x3b, 0xf26, +0x3b, 0xf27, 0x3b, 0xf28, 0x3b, 0xf29, 0x3b, 0xf21, 0xf20, 0x3b, 0xf21, 0xf21, 0x3b, 0xf21, 0xf22, 0x3b, 0xf21, 0x3b, 0xf22, 0x3b, +0xf23, 0x3b, 0xf24, 0x3b, 0xf25, 0x3b, 0xf26, 0x3b, 0xf27, 0x3b, 0xf28, 0x3b, 0xf29, 0x3b, 0xf21, 0xf20, 0x3b, 0xf21, 0xf21, 0x3b, +0x31, 0x32, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xf44, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, +0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf42, 0xf66, 0xf74, 0xf58, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf5e, 0xf72, 0xf0b, +0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf63, 0xf94, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xfb2, 0xf74, 0xf42, 0xf0b, +0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf51, 0xf74, 0xf53, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf62, 0xf92, 0xfb1, +0xf51, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xf42, 0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, +0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf45, 0xf72, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, +0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf21, 0x3b, 0xf22, 0x3b, 0xf23, +0x3b, 0x34, 0x3b, 0xf25, 0x3b, 0xf26, 0x3b, 0xf27, 0x3b, 0xf28, 0x3b, 0x39, 0x3b, 0xf21, 0xf20, 0x3b, 0xf21, 0xf21, 0x3b, 0xf21, +0xf22, 0x3b, 0x47, 0x65, 0x6e, 0x2e, 0x3b, 0x43, 0x2bc, 0x68, 0x77, 0x65, 0x2e, 0x3b, 0x4d, 0x65, 0x75, 0x72, 0x2e, 0x3b, +0x45, 0x62, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x65, 0x3b, 0x4d, 0x65, 0x7a, 0x68, 0x2e, 0x3b, 0x47, 0x6f, 0x75, 0x65, 0x2e, +0x3b, 0x45, 0x6f, 0x73, 0x74, 0x3b, 0x47, 0x77, 0x65, 0x6e, 0x2e, 0x3b, 0x48, 0x65, 0x72, 0x65, 0x3b, 0x44, 0x75, 0x3b, +0x4b, 0x7a, 0x75, 0x2e, 0x3b, 0x47, 0x65, 0x6e, 0x76, 0x65, 0x72, 0x3b, 0x43, 0x2bc, 0x68, 0x77, 0x65, 0x76, 0x72, 0x65, +0x72, 0x3b, 0x4d, 0x65, 0x75, 0x72, 0x7a, 0x68, 0x3b, 0x45, 0x62, 0x72, 0x65, 0x6c, 0x3b, 0x4d, 0x61, 0x65, 0x3b, 0x4d, +0x65, 0x7a, 0x68, 0x65, 0x76, 0x65, 0x6e, 0x3b, 0x47, 0x6f, 0x75, 0x65, 0x72, 0x65, 0x3b, 0x45, 0x6f, 0x73, 0x74, 0x3b, +0x47, 0x77, 0x65, 0x6e, 0x67, 0x6f, 0x6c, 0x6f, 0x3b, 0x48, 0x65, 0x72, 0x65, 0x3b, 0x44, 0x75, 0x3b, 0x4b, 0x65, 0x72, +0x7a, 0x75, 0x3b, 0x30, 0x31, 0x3b, 0x30, 0x32, 0x3b, 0x30, 0x33, 0x3b, 0x30, 0x34, 0x3b, 0x30, 0x35, 0x3b, 0x30, 0x36, +0x3b, 0x30, 0x37, 0x3b, 0x30, 0x38, 0x3b, 0x30, 0x39, 0x3b, 0x31, 0x30, 0x3b, 0x31, 0x31, 0x3b, 0x31, 0x32, 0x3b, 0x44f, +0x43d, 0x443, 0x3b, 0x444, 0x435, 0x432, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x3b, 0x43c, 0x430, 0x439, 0x3b, +0x44e, 0x43d, 0x438, 0x3b, 0x44e, 0x43b, 0x438, 0x3b, 0x430, 0x432, 0x433, 0x3b, 0x441, 0x435, 0x43f, 0x3b, 0x43e, 0x43a, 0x442, 0x3b, +0x43d, 0x43e, 0x435, 0x3b, 0x434, 0x435, 0x43a, 0x3b, 0x44f, 0x43d, 0x443, 0x430, 0x440, 0x438, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x443, +0x430, 0x440, 0x438, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x44e, +0x43d, 0x438, 0x3b, 0x44e, 0x43b, 0x438, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x435, 0x43c, +0x432, 0x440, 0x438, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x43d, 0x43e, 0x435, 0x43c, 0x432, 0x440, 0x438, +0x3b, 0x434, 0x435, 0x43a, 0x435, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x44f, 0x3b, 0x444, 0x3b, 0x43c, 0x3b, 0x430, 0x3b, 0x43c, 0x3b, +0x44e, 0x3b, 0x44e, 0x3b, 0x430, 0x3b, 0x441, 0x3b, 0x43e, 0x3b, 0x43d, 0x3b, 0x434, 0x3b, 0x1007, 0x1014, 0x103a, 0x3b, 0x1016, 0x1031, +0x3b, 0x1019, 0x1010, 0x103a, 0x3b, 0x1027, 0x3b, 0x1019, 0x1031, 0x3b, 0x1007, 0x103d, 0x1014, 0x103a, 0x3b, 0x1007, 0x1030, 0x3b, 0x1029, 0x3b, +0x1005, 0x1000, 0x103a, 0x3b, 0x1021, 0x1031, 0x102c, 0x1000, 0x103a, 0x3b, 0x1014, 0x102d, 0x102f, 0x3b, 0x1012, 0x102e, 0x3b, 0x1007, 0x1014, 0x103a, +0x1014, 0x101d, 0x102b, 0x101b, 0x102e, 0x3b, 0x1016, 0x1031, 0x1016, 0x1031, 0x102c, 0x103a, 0x101d, 0x102b, 0x101b, 0x102e, 0x3b, 0x1019, 0x1010, 0x103a, +0x3b, 0x1027, 0x1015, 0x103c, 0x102e, 0x3b, 0x1019, 0x1031, 0x3b, 0x1007, 0x103d, 0x1014, 0x103a, 0x3b, 0x1007, 0x1030, 0x101c, 0x102d, 0x102f, 0x1004, +0x103a, 0x3b, 0x1029, 0x1002, 0x102f, 0x1010, 0x103a, 0x3b, 0x1005, 0x1000, 0x103a, 0x1010, 0x1004, 0x103a, 0x1018, 0x102c, 0x3b, 0x1021, 0x1031, 0x102c, +0x1000, 0x103a, 0x1010, 0x102d, 0x102f, 0x1018, 0x102c, 0x3b, 0x1014, 0x102d, 0x102f, 0x101d, 0x1004, 0x103a, 0x1018, 0x102c, 0x3b, 0x1012, 0x102e, 0x1007, +0x1004, 0x103a, 0x1018, 0x102c, 0x3b, 0x1007, 0x3b, 0x1016, 0x3b, 0x1019, 0x3b, 0x1027, 0x3b, 0x1019, 0x3b, 0x1007, 0x3b, 0x1007, 0x3b, 0x1029, +0x3b, 0x1005, 0x3b, 0x1021, 0x3b, 0x1014, 0x3b, 0x1012, 0x3b, 0x441, 0x442, 0x443, 0x3b, 0x43b, 0x44e, 0x442, 0x3b, 0x441, 0x430, 0x43a, +0x3b, 0x43a, 0x440, 0x430, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x447, 0x44d, 0x440, 0x3b, 0x43b, 0x456, 0x43f, 0x3b, 0x436, 0x43d, 0x456, +0x3b, 0x432, 0x435, 0x440, 0x3b, 0x43a, 0x430, 0x441, 0x3b, 0x43b, 0x456, 0x441, 0x3b, 0x441, 0x43d, 0x435, 0x3b, 0x441, 0x442, 0x443, +0x434, 0x437, 0x435, 0x43d, 0x44c, 0x3b, 0x43b, 0x44e, 0x442, 0x44b, 0x3b, 0x441, 0x430, 0x43a, 0x430, 0x432, 0x456, 0x43a, 0x3b, 0x43a, +0x440, 0x430, 0x441, 0x430, 0x432, 0x456, 0x43a, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x447, 0x44d, 0x440, 0x432, 0x435, 0x43d, 0x44c, 0x3b, +0x43b, 0x456, 0x43f, 0x435, 0x43d, 0x44c, 0x3b, 0x436, 0x43d, 0x456, 0x432, 0x435, 0x43d, 0x44c, 0x3b, 0x432, 0x435, 0x440, 0x430, 0x441, +0x435, 0x43d, 0x44c, 0x3b, 0x43a, 0x430, 0x441, 0x442, 0x440, 0x44b, 0x447, 0x43d, 0x456, 0x43a, 0x3b, 0x43b, 0x456, 0x441, 0x442, 0x430, +0x43f, 0x430, 0x434, 0x3b, 0x441, 0x43d, 0x435, 0x436, 0x430, 0x43d, 0x44c, 0x3b, 0x441, 0x3b, 0x43b, 0x3b, 0x441, 0x3b, 0x43a, 0x3b, +0x43c, 0x3b, 0x447, 0x3b, 0x43b, 0x3b, 0x436, 0x3b, 0x432, 0x3b, 0x43a, 0x3b, 0x43b, 0x3b, 0x441, 0x3b, 0x441, 0x442, 0x443, 0x3b, +0x43b, 0x44e, 0x442, 0x3b, 0x441, 0x430, 0x43a, 0x3b, 0x43a, 0x440, 0x430, 0x3b, 0x43c, 0x430, 0x44f, 0x3b, 0x447, 0x44d, 0x440, 0x3b, +0x43b, 0x456, 0x43f, 0x3b, 0x436, 0x43d, 0x456, 0x3b, 0x432, 0x435, 0x440, 0x3b, 0x43a, 0x430, 0x441, 0x3b, 0x43b, 0x456, 0x441, 0x3b, +0x441, 0x43d, 0x435, 0x3b, 0x441, 0x442, 0x443, 0x434, 0x437, 0x435, 0x43d, 0x44f, 0x3b, 0x43b, 0x44e, 0x442, 0x430, 0x433, 0x430, 0x3b, +0x441, 0x430, 0x43a, 0x430, 0x432, 0x456, 0x43a, 0x430, 0x3b, 0x43a, 0x440, 0x430, 0x441, 0x430, 0x432, 0x456, 0x43a, 0x430, 0x3b, 0x43c, +0x430, 0x44f, 0x3b, 0x447, 0x44d, 0x440, 0x432, 0x435, 0x43d, 0x44f, 0x3b, 0x43b, 0x456, 0x43f, 0x435, 0x43d, 0x44f, 0x3b, 0x436, 0x43d, +0x456, 0x45e, 0x43d, 0x44f, 0x3b, 0x432, 0x435, 0x440, 0x430, 0x441, 0x43d, 0x44f, 0x3b, 0x43a, 0x430, 0x441, 0x442, 0x440, 0x44b, 0x447, +0x43d, 0x456, 0x43a, 0x430, 0x3b, 0x43b, 0x456, 0x441, 0x442, 0x430, 0x43f, 0x430, 0x434, 0x430, 0x3b, 0x441, 0x43d, 0x435, 0x436, 0x43d, +0x44f, 0x3b, 0x1798, 0x1780, 0x179a, 0x17b6, 0x3b, 0x1780, 0x17bb, 0x1798, 0x17d2, 0x1797, 0x17c8, 0x3b, 0x1798, 0x17b8, 0x1793, 0x17b6, 0x3b, 0x1798, +0x17c1, 0x179f, 0x17b6, 0x3b, 0x17a7, 0x179f, 0x1797, 0x17b6, 0x3b, 0x1798, 0x17b7, 0x1790, 0x17bb, 0x1793, 0x17b6, 0x3b, 0x1780, 0x1780, 0x17d2, 0x1780, +0x178a, 0x17b6, 0x3b, 0x179f, 0x17b8, 0x17a0, 0x17b6, 0x3b, 0x1780, 0x1789, 0x17d2, 0x1789, 0x17b6, 0x3b, 0x178f, 0x17bb, 0x179b, 0x17b6, 0x3b, 0x179c, +0x17b7, 0x1785, 0x17d2, 0x1786, 0x17b7, 0x1780, 0x17b6, 0x3b, 0x1792, 0x17d2, 0x1793, 0x17bc, 0x3b, 0x1798, 0x3b, 0x1780, 0x3b, 0x1798, 0x3b, 0x1798, +0x3b, 0x17a7, 0x3b, 0x1798, 0x3b, 0x1780, 0x3b, 0x179f, 0x3b, 0x1780, 0x3b, 0x178f, 0x3b, 0x179c, 0x3b, 0x1792, 0x3b, 0x67, 0x65, 0x6e, +0x2e, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0xe7, 0x3b, 0x61, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, +0x69, 0x67, 0x3b, 0x6a, 0x75, 0x6e, 0x79, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x74, +0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x73, 0x2e, 0x3b, 0x67, 0x65, 0x6e, +0x65, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x65, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0xe7, 0x3b, 0x61, 0x62, 0x72, 0x69, 0x6c, +0x3b, 0x6d, 0x61, 0x69, 0x67, 0x3b, 0x6a, 0x75, 0x6e, 0x79, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x6f, 0x6c, 0x3b, 0x61, 0x67, +0x6f, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x75, 0x62, 0x72, 0x65, +0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x47, +0x4e, 0x3b, 0x46, 0x42, 0x3b, 0x4d, 0xc7, 0x3b, 0x41, 0x42, 0x3b, 0x4d, 0x47, 0x3b, 0x4a, 0x4e, 0x3b, 0x4a, 0x4c, 0x3b, +0x41, 0x47, 0x3b, 0x53, 0x54, 0x3b, 0x4f, 0x43, 0x3b, 0x4e, 0x56, 0x3b, 0x44, 0x53, 0x3b, 0x64, 0x65, 0x20, 0x67, 0x65, +0x6e, 0x2e, 0x3b, 0x64, 0x65, 0x20, 0x66, 0x65, 0x62, 0x72, 0x2e, 0x3b, 0x64, 0x65, 0x20, 0x6d, 0x61, 0x72, 0xe7, 0x3b, +0x64, 0x2019, 0x61, 0x62, 0x72, 0x2e, 0x3b, 0x64, 0x65, 0x20, 0x6d, 0x61, 0x69, 0x67, 0x3b, 0x64, 0x65, 0x20, 0x6a, 0x75, +0x6e, 0x79, 0x3b, 0x64, 0x65, 0x20, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x64, 0x2019, 0x61, 0x67, 0x2e, 0x3b, 0x64, 0x65, 0x20, +0x73, 0x65, 0x74, 0x2e, 0x3b, 0x64, 0x2019, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x64, 0x65, 0x20, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, +0x64, 0x65, 0x20, 0x64, 0x65, 0x73, 0x2e, 0x3b, 0x64, 0x65, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x20, +0x66, 0x65, 0x62, 0x72, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x20, 0x6d, 0x61, 0x72, 0xe7, 0x3b, 0x64, 0x2019, 0x61, 0x62, 0x72, +0x69, 0x6c, 0x3b, 0x64, 0x65, 0x20, 0x6d, 0x61, 0x69, 0x67, 0x3b, 0x64, 0x65, 0x20, 0x6a, 0x75, 0x6e, 0x79, 0x3b, 0x64, +0x65, 0x20, 0x6a, 0x75, 0x6c, 0x69, 0x6f, 0x6c, 0x3b, 0x64, 0x2019, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x3b, 0x64, 0x65, 0x20, +0x73, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x2019, 0x6f, 0x63, 0x74, 0x75, 0x62, 0x72, 0x65, 0x3b, 0x64, +0x65, 0x20, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x65, 0x20, 0x64, 0x65, 0x73, 0x65, 0x6d, 0x62, +0x72, 0x65, 0x3b, 0x31, 0x6708, 0x3b, 0x32, 0x6708, 0x3b, 0x33, 0x6708, 0x3b, 0x34, 0x6708, 0x3b, 0x35, 0x6708, 0x3b, 0x36, 0x6708, +0x3b, 0x37, 0x6708, 0x3b, 0x38, 0x6708, 0x3b, 0x39, 0x6708, 0x3b, 0x31, 0x30, 0x6708, 0x3b, 0x31, 0x31, 0x6708, 0x3b, 0x31, 0x32, +0x6708, 0x3b, 0x4e00, 0x6708, 0x3b, 0x4e8c, 0x6708, 0x3b, 0x4e09, 0x6708, 0x3b, 0x56db, 0x6708, 0x3b, 0x4e94, 0x6708, 0x3b, 0x516d, 0x6708, 0x3b, +0x4e03, 0x6708, 0x3b, 0x516b, 0x6708, 0x3b, 0x4e5d, 0x6708, 0x3b, 0x5341, 0x6708, 0x3b, 0x5341, 0x4e00, 0x6708, 0x3b, 0x5341, 0x4e8c, 0x6708, 0x3b, +0x73, 0x69, 0x6a, 0x3b, 0x76, 0x65, 0x6c, 0x6a, 0x3b, 0x6f, 0x17e, 0x75, 0x3b, 0x74, 0x72, 0x61, 0x3b, 0x73, 0x76, 0x69, +0x3b, 0x6c, 0x69, 0x70, 0x3b, 0x73, 0x72, 0x70, 0x3b, 0x6b, 0x6f, 0x6c, 0x3b, 0x72, 0x75, 0x6a, 0x3b, 0x6c, 0x69, 0x73, +0x3b, 0x73, 0x74, 0x75, 0x3b, 0x70, 0x72, 0x6f, 0x3b, 0x73, 0x69, 0x6a, 0x65, 0x10d, 0x61, 0x6e, 0x6a, 0x3b, 0x76, 0x65, +0x6c, 0x6a, 0x61, 0x10d, 0x61, 0x3b, 0x6f, 0x17e, 0x75, 0x6a, 0x61, 0x6b, 0x3b, 0x74, 0x72, 0x61, 0x76, 0x61, 0x6e, 0x6a, +0x3b, 0x73, 0x76, 0x69, 0x62, 0x61, 0x6e, 0x6a, 0x3b, 0x6c, 0x69, 0x70, 0x61, 0x6e, 0x6a, 0x3b, 0x73, 0x72, 0x70, 0x61, +0x6e, 0x6a, 0x3b, 0x6b, 0x6f, 0x6c, 0x6f, 0x76, 0x6f, 0x7a, 0x3b, 0x72, 0x75, 0x6a, 0x61, 0x6e, 0x3b, 0x6c, 0x69, 0x73, +0x74, 0x6f, 0x70, 0x61, 0x64, 0x3b, 0x73, 0x74, 0x75, 0x64, 0x65, 0x6e, 0x69, 0x3b, 0x70, 0x72, 0x6f, 0x73, 0x69, 0x6e, +0x61, 0x63, 0x3b, 0x31, 0x2e, 0x3b, 0x32, 0x2e, 0x3b, 0x33, 0x2e, 0x3b, 0x34, 0x2e, 0x3b, 0x35, 0x2e, 0x3b, 0x36, 0x2e, +0x3b, 0x37, 0x2e, 0x3b, 0x38, 0x2e, 0x3b, 0x39, 0x2e, 0x3b, 0x31, 0x30, 0x2e, 0x3b, 0x31, 0x31, 0x2e, 0x3b, 0x31, 0x32, +0x2e, 0x3b, 0x73, 0x69, 0x6a, 0x65, 0x10d, 0x6e, 0x6a, 0x61, 0x3b, 0x76, 0x65, 0x6c, 0x6a, 0x61, 0x10d, 0x65, 0x3b, 0x6f, +0x17e, 0x75, 0x6a, 0x6b, 0x61, 0x3b, 0x74, 0x72, 0x61, 0x76, 0x6e, 0x6a, 0x61, 0x3b, 0x73, 0x76, 0x69, 0x62, 0x6e, 0x6a, +0x61, 0x3b, 0x6c, 0x69, 0x70, 0x6e, 0x6a, 0x61, 0x3b, 0x73, 0x72, 0x70, 0x6e, 0x6a, 0x61, 0x3b, 0x6b, 0x6f, 0x6c, 0x6f, +0x76, 0x6f, 0x7a, 0x61, 0x3b, 0x72, 0x75, 0x6a, 0x6e, 0x61, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x61, +0x3b, 0x73, 0x74, 0x75, 0x64, 0x65, 0x6e, 0x6f, 0x67, 0x61, 0x3b, 0x70, 0x72, 0x6f, 0x73, 0x69, 0x6e, 0x63, 0x61, 0x3b, +0x6c, 0x65, 0x64, 0x3b, 0xfa, 0x6e, 0x6f, 0x3b, 0x62, 0x159, 0x65, 0x3b, 0x64, 0x75, 0x62, 0x3b, 0x6b, 0x76, 0x11b, 0x3b, +0x10d, 0x76, 0x6e, 0x3b, 0x10d, 0x76, 0x63, 0x3b, 0x73, 0x72, 0x70, 0x3b, 0x7a, 0xe1, 0x159, 0x3b, 0x159, 0xed, 0x6a, 0x3b, +0x6c, 0x69, 0x73, 0x3b, 0x70, 0x72, 0x6f, 0x3b, 0x6c, 0x65, 0x64, 0x65, 0x6e, 0x3b, 0xfa, 0x6e, 0x6f, 0x72, 0x3b, 0x62, +0x159, 0x65, 0x7a, 0x65, 0x6e, 0x3b, 0x64, 0x75, 0x62, 0x65, 0x6e, 0x3b, 0x6b, 0x76, 0x11b, 0x74, 0x65, 0x6e, 0x3b, 0x10d, +0x65, 0x72, 0x76, 0x65, 0x6e, 0x3b, 0x10d, 0x65, 0x72, 0x76, 0x65, 0x6e, 0x65, 0x63, 0x3b, 0x73, 0x72, 0x70, 0x65, 0x6e, +0x3b, 0x7a, 0xe1, 0x159, 0xed, 0x3b, 0x159, 0xed, 0x6a, 0x65, 0x6e, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, +0x3b, 0x70, 0x72, 0x6f, 0x73, 0x69, 0x6e, 0x65, 0x63, 0x3b, 0x6c, 0x65, 0x64, 0x6e, 0x61, 0x3b, 0xfa, 0x6e, 0x6f, 0x72, +0x61, 0x3b, 0x62, 0x159, 0x65, 0x7a, 0x6e, 0x61, 0x3b, 0x64, 0x75, 0x62, 0x6e, 0x61, 0x3b, 0x6b, 0x76, 0x11b, 0x74, 0x6e, +0x61, 0x3b, 0x10d, 0x65, 0x72, 0x76, 0x6e, 0x61, 0x3b, 0x10d, 0x65, 0x72, 0x76, 0x65, 0x6e, 0x63, 0x65, 0x3b, 0x73, 0x72, +0x70, 0x6e, 0x61, 0x3b, 0x7a, 0xe1, 0x159, 0xed, 0x3b, 0x159, 0xed, 0x6a, 0x6e, 0x61, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, +0x70, 0x61, 0x64, 0x75, 0x3b, 0x70, 0x72, 0x6f, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, +0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, +0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b, +0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, +0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, +0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, +0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, +0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6a, 0x61, 0x6e, +0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x72, 0x74, 0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x65, 0x69, +0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, +0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, +0x61, 0x72, 0x69, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x6d, 0x61, 0x61, 0x72, 0x74, 0x3b, 0x61, +0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x65, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, +0x75, 0x67, 0x75, 0x73, 0x74, 0x75, 0x73, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, +0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, +0x62, 0x65, 0x72, 0x3b, 0x4a, 0x61, 0x6e, 0x2e, 0x3b, 0x46, 0x65, 0x62, 0x2e, 0x3b, 0x4d, 0x61, 0x72, 0x2e, 0x3b, 0x41, +0x70, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x4a, 0x75, 0x6e, 0x2e, 0x3b, 0x4a, 0x75, 0x6c, 0x2e, 0x3b, 0x41, 0x75, +0x67, 0x2e, 0x3b, 0x53, 0x65, 0x70, 0x2e, 0x3b, 0x4f, 0x63, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x65, +0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, +0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x16d, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, +0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x6f, 0x3b, 0x66, +0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x6f, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x6f, +0x3b, 0x6d, 0x61, 0x6a, 0x6f, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x6f, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x6f, 0x3b, 0x61, 0x16d, +0x67, 0x75, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x72, 0x6f, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, -0x6f, 0x3b, 0x78, 0x2e, 0x3b, 0x66, 0x2e, 0x3b, 0x6d, 0x2e, 0x3b, 0x61, 0x2e, 0x3b, 0x6d, 0x2e, 0x3b, 0x78, 0x2e, 0x3b, -0x78, 0x2e, 0x3b, 0x61, 0x2e, 0x3b, 0x73, 0x2e, 0x3b, 0x6f, 0x2e, 0x3b, 0x6e, 0x2e, 0x3b, 0x64, 0x2e, 0x3b, 0x10d8, 0x10d0, -0x10dc, 0x3b, 0x10d7, 0x10d4, 0x10d1, 0x3b, 0x10db, 0x10d0, 0x10e0, 0x3b, 0x10d0, 0x10de, 0x10e0, 0x3b, 0x10db, 0x10d0, 0x10d8, 0x3b, 0x10d8, 0x10d5, -0x10dc, 0x3b, 0x10d8, 0x10d5, 0x10da, 0x3b, 0x10d0, 0x10d2, 0x10d5, 0x3b, 0x10e1, 0x10d4, 0x10e5, 0x3b, 0x10dd, 0x10e5, 0x10e2, 0x3b, 0x10dc, 0x10dd, -0x10d4, 0x3b, 0x10d3, 0x10d4, 0x10d9, 0x3b, 0x10d8, 0x10d0, 0x10dc, 0x10d5, 0x10d0, 0x10e0, 0x10d8, 0x3b, 0x10d7, 0x10d4, 0x10d1, 0x10d4, 0x10e0, 0x10d5, -0x10d0, 0x10da, 0x10d8, 0x3b, 0x10db, 0x10d0, 0x10e0, 0x10e2, 0x10d8, 0x3b, 0x10d0, 0x10de, 0x10e0, 0x10d8, 0x10da, 0x10d8, 0x3b, 0x10db, 0x10d0, 0x10d8, -0x10e1, 0x10d8, 0x3b, 0x10d8, 0x10d5, 0x10dc, 0x10d8, 0x10e1, 0x10d8, 0x3b, 0x10d8, 0x10d5, 0x10da, 0x10d8, 0x10e1, 0x10d8, 0x3b, 0x10d0, 0x10d2, 0x10d5, -0x10d8, 0x10e1, 0x10e2, 0x10dd, 0x3b, 0x10e1, 0x10d4, 0x10e5, 0x10e2, 0x10d4, 0x10db, 0x10d1, 0x10d4, 0x10e0, 0x10d8, 0x3b, 0x10dd, 0x10e5, 0x10e2, 0x10dd, -0x10db, 0x10d1, 0x10d4, 0x10e0, 0x10d8, 0x3b, 0x10dc, 0x10dd, 0x10d4, 0x10db, 0x10d1, 0x10d4, 0x10e0, 0x10d8, 0x3b, 0x10d3, 0x10d4, 0x10d9, 0x10d4, 0x10db, -0x10d1, 0x10d4, 0x10e0, 0x10d8, 0x3b, 0x10d8, 0x3b, 0x10d7, 0x3b, 0x10db, 0x3b, 0x10d0, 0x3b, 0x10db, 0x3b, 0x10d8, 0x3b, 0x10d8, 0x3b, 0x10d0, -0x3b, 0x10e1, 0x3b, 0x10dd, 0x3b, 0x10dc, 0x3b, 0x10d3, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0xe4, 0x72, -0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x75, 0x67, -0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x7a, 0x3b, 0x4a, 0x61, 0x6e, -0x75, 0x61, 0x72, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41, 0x70, 0x72, -0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, -0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, -0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x7a, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, -0x4a, 0x61, 0x6e, 0x2e, 0x3b, 0x46, 0x65, 0x62, 0x2e, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x2e, 0x3b, -0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x2e, 0x3b, 0x53, -0x65, 0x70, 0x2e, 0x3b, 0x4f, 0x6b, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x65, 0x7a, 0x2e, 0x3b, 0x4a, -0xe4, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0xe4, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, +0x6f, 0x3b, 0x6a, 0x61, 0x61, 0x6e, 0x3b, 0x76, 0x65, 0x65, 0x62, 0x72, 0x3b, 0x6d, 0xe4, 0x72, 0x74, 0x73, 0x3b, 0x61, +0x70, 0x72, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x75, 0x6c, 0x69, 0x3b, 0x61, +0x75, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x74, 0x73, +0x3b, 0x6a, 0x61, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x76, 0x65, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0xe4, +0x72, 0x74, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x75, 0x6e, 0x69, +0x3b, 0x6a, 0x75, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, +0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, +0x72, 0x3b, 0x64, 0x65, 0x74, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x3b, 0x56, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, +0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, +0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, +0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x75, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, +0x64, 0x65, 0x73, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, +0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0xed, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, +0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, +0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, +0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, +0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, +0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, +0x3b, 0x64, 0x65, 0x73, 0x2e, 0x3b, 0x74, 0x61, 0x6d, 0x6d, 0x69, 0x3b, 0x68, 0x65, 0x6c, 0x6d, 0x69, 0x3b, 0x6d, 0x61, +0x61, 0x6c, 0x69, 0x73, 0x3b, 0x68, 0x75, 0x68, 0x74, 0x69, 0x3b, 0x74, 0x6f, 0x75, 0x6b, 0x6f, 0x3b, 0x6b, 0x65, 0x73, +0xe4, 0x3b, 0x68, 0x65, 0x69, 0x6e, 0xe4, 0x3b, 0x65, 0x6c, 0x6f, 0x3b, 0x73, 0x79, 0x79, 0x73, 0x3b, 0x6c, 0x6f, 0x6b, +0x61, 0x3b, 0x6d, 0x61, 0x72, 0x72, 0x61, 0x73, 0x3b, 0x6a, 0x6f, 0x75, 0x6c, 0x75, 0x3b, 0x74, 0x61, 0x6d, 0x6d, 0x69, +0x6b, 0x75, 0x75, 0x3b, 0x68, 0x65, 0x6c, 0x6d, 0x69, 0x6b, 0x75, 0x75, 0x3b, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x73, 0x6b, +0x75, 0x75, 0x3b, 0x68, 0x75, 0x68, 0x74, 0x69, 0x6b, 0x75, 0x75, 0x3b, 0x74, 0x6f, 0x75, 0x6b, 0x6f, 0x6b, 0x75, 0x75, +0x3b, 0x6b, 0x65, 0x73, 0xe4, 0x6b, 0x75, 0x75, 0x3b, 0x68, 0x65, 0x69, 0x6e, 0xe4, 0x6b, 0x75, 0x75, 0x3b, 0x65, 0x6c, +0x6f, 0x6b, 0x75, 0x75, 0x3b, 0x73, 0x79, 0x79, 0x73, 0x6b, 0x75, 0x75, 0x3b, 0x6c, 0x6f, 0x6b, 0x61, 0x6b, 0x75, 0x75, +0x3b, 0x6d, 0x61, 0x72, 0x72, 0x61, 0x73, 0x6b, 0x75, 0x75, 0x3b, 0x6a, 0x6f, 0x75, 0x6c, 0x75, 0x6b, 0x75, 0x75, 0x3b, +0x54, 0x3b, 0x48, 0x3b, 0x4d, 0x3b, 0x48, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x48, 0x3b, 0x45, 0x3b, 0x53, 0x3b, 0x4c, 0x3b, +0x4d, 0x3b, 0x4a, 0x3b, 0x74, 0x61, 0x6d, 0x6d, 0x69, 0x6b, 0x2e, 0x3b, 0x68, 0x65, 0x6c, 0x6d, 0x69, 0x6b, 0x2e, 0x3b, +0x6d, 0x61, 0x61, 0x6c, 0x69, 0x73, 0x6b, 0x2e, 0x3b, 0x68, 0x75, 0x68, 0x74, 0x69, 0x6b, 0x2e, 0x3b, 0x74, 0x6f, 0x75, +0x6b, 0x6f, 0x6b, 0x2e, 0x3b, 0x6b, 0x65, 0x73, 0xe4, 0x6b, 0x2e, 0x3b, 0x68, 0x65, 0x69, 0x6e, 0xe4, 0x6b, 0x2e, 0x3b, +0x65, 0x6c, 0x6f, 0x6b, 0x2e, 0x3b, 0x73, 0x79, 0x79, 0x73, 0x6b, 0x2e, 0x3b, 0x6c, 0x6f, 0x6b, 0x61, 0x6b, 0x2e, 0x3b, +0x6d, 0x61, 0x72, 0x72, 0x61, 0x73, 0x6b, 0x2e, 0x3b, 0x6a, 0x6f, 0x75, 0x6c, 0x75, 0x6b, 0x2e, 0x3b, 0x74, 0x61, 0x6d, +0x6d, 0x69, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x68, 0x65, 0x6c, 0x6d, 0x69, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x6d, +0x61, 0x61, 0x6c, 0x69, 0x73, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x68, 0x75, 0x68, 0x74, 0x69, 0x6b, 0x75, 0x75, 0x74, +0x61, 0x3b, 0x74, 0x6f, 0x75, 0x6b, 0x6f, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x6b, 0x65, 0x73, 0xe4, 0x6b, 0x75, 0x75, +0x74, 0x61, 0x3b, 0x68, 0x65, 0x69, 0x6e, 0xe4, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x65, 0x6c, 0x6f, 0x6b, 0x75, 0x75, +0x74, 0x61, 0x3b, 0x73, 0x79, 0x79, 0x73, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x6c, 0x6f, 0x6b, 0x61, 0x6b, 0x75, 0x75, +0x74, 0x61, 0x3b, 0x6d, 0x61, 0x72, 0x72, 0x61, 0x73, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x6a, 0x6f, 0x75, 0x6c, 0x75, +0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x6a, 0x61, 0x6e, 0x76, 0x2e, 0x3b, 0x66, 0xe9, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, +0x72, 0x73, 0x3b, 0x61, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x69, 0x6e, 0x3b, 0x6a, 0x75, 0x69, +0x6c, 0x2e, 0x3b, 0x61, 0x6f, 0xfb, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, +0x6f, 0x76, 0x2e, 0x3b, 0x64, 0xe9, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x76, 0x69, 0x65, 0x72, 0x3b, 0x66, 0xe9, 0x76, +0x72, 0x69, 0x65, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x76, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x3b, +0x6a, 0x75, 0x69, 0x6e, 0x3b, 0x6a, 0x75, 0x69, 0x6c, 0x6c, 0x65, 0x74, 0x3b, 0x61, 0x6f, 0xfb, 0x74, 0x3b, 0x73, 0x65, +0x70, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x6f, 0x62, 0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x65, +0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0xe9, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6a, 0x61, 0x6e, 0x76, 0x2e, 0x3b, +0x66, 0xe9, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b, +0x6a, 0x75, 0x69, 0x6e, 0x3b, 0x6a, 0x75, 0x69, 0x6c, 0x6c, 0x2e, 0x3b, 0x61, 0x6f, 0xfb, 0x74, 0x3b, 0x73, 0x65, 0x70, +0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0xe9, 0x63, 0x2e, 0x3b, 0x6a, 0x61, +0x6e, 0x2e, 0x3b, 0x66, 0xe9, 0x76, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, +0x69, 0x3b, 0x6a, 0x75, 0x69, 0x2e, 0x3b, 0x6a, 0x75, 0x69, 0x6c, 0x2e, 0x3b, 0x61, 0x6f, 0xfb, 0x74, 0x3b, 0x73, 0x65, +0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0xe9, 0x63, 0x2e, 0x3b, 0x4a, +0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x72, 0x74, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x75, 0x67, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, -0x6f, 0x76, 0x3b, 0x44, 0x65, 0x7a, 0x3b, 0x4a, 0xe4, 0x6e, 0x6e, 0x65, 0x72, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, -0x72, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, -0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, -0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, -0x3b, 0x44, 0x65, 0x7a, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0xe4, 0x6e, 0x2e, 0x3b, 0x46, 0x65, 0x62, 0x2e, 0x3b, -0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, -0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x2e, 0x3b, 0x53, 0x65, 0x70, 0x2e, 0x3b, 0x4f, 0x6b, 0x74, 0x2e, 0x3b, 0x4e, -0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x65, 0x7a, 0x2e, 0x3b, 0x399, 0x3b1, 0x3bd, 0x3b, 0x3a6, 0x3b5, 0x3b2, 0x3b, 0x39c, 0x3ac, 0x3c1, -0x3b, 0x391, 0x3c0, 0x3c1, 0x3b, 0x39c, 0x3ac, 0x3b9, 0x3b, 0x399, 0x3bf, 0x3cd, 0x3bd, 0x3b, 0x399, 0x3bf, 0x3cd, 0x3bb, 0x3b, 0x391, -0x3cd, 0x3b3, 0x3b, 0x3a3, 0x3b5, 0x3c0, 0x3b, 0x39f, 0x3ba, 0x3c4, 0x3b, 0x39d, 0x3bf, 0x3ad, 0x3b, 0x394, 0x3b5, 0x3ba, 0x3b, 0x399, -0x3b1, 0x3bd, 0x3bf, 0x3c5, 0x3ac, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x3a6, 0x3b5, 0x3b2, 0x3c1, 0x3bf, 0x3c5, 0x3ac, 0x3c1, 0x3b9, 0x3bf, -0x3c2, 0x3b, 0x39c, 0x3ac, 0x3c1, 0x3c4, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x391, 0x3c0, 0x3c1, 0x3af, 0x3bb, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x39c, -0x3ac, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x399, 0x3bf, 0x3cd, 0x3bd, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x399, 0x3bf, 0x3cd, 0x3bb, 0x3b9, 0x3bf, 0x3c2, -0x3b, 0x391, 0x3cd, 0x3b3, 0x3bf, 0x3c5, 0x3c3, 0x3c4, 0x3bf, 0x3c2, 0x3b, 0x3a3, 0x3b5, 0x3c0, 0x3c4, 0x3ad, 0x3bc, 0x3b2, 0x3c1, 0x3b9, -0x3bf, 0x3c2, 0x3b, 0x39f, 0x3ba, 0x3c4, 0x3ce, 0x3b2, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x39d, 0x3bf, 0x3ad, 0x3bc, 0x3b2, 0x3c1, 0x3b9, -0x3bf, 0x3c2, 0x3b, 0x394, 0x3b5, 0x3ba, 0x3ad, 0x3bc, 0x3b2, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x399, 0x3b, 0x3a6, 0x3b, 0x39c, 0x3b, -0x391, 0x3b, 0x39c, 0x3b, 0x399, 0x3b, 0x399, 0x3b, 0x391, 0x3b, 0x3a3, 0x3b, 0x39f, 0x3b, 0x39d, 0x3b, 0x394, 0x3b, 0x399, 0x3b1, -0x3bd, 0x3b, 0x3a6, 0x3b5, 0x3b2, 0x3b, 0x39c, 0x3b1, 0x3c1, 0x3b, 0x391, 0x3c0, 0x3c1, 0x3b, 0x39c, 0x3b1, 0x390, 0x3b, 0x399, 0x3bf, -0x3c5, 0x3bd, 0x3b, 0x399, 0x3bf, 0x3c5, 0x3bb, 0x3b, 0x391, 0x3c5, 0x3b3, 0x3b, 0x3a3, 0x3b5, 0x3c0, 0x3b, 0x39f, 0x3ba, 0x3c4, 0x3b, -0x39d, 0x3bf, 0x3b5, 0x3b, 0x394, 0x3b5, 0x3ba, 0x3b, 0x399, 0x3b1, 0x3bd, 0x3bf, 0x3c5, 0x3b1, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x3a6, -0x3b5, 0x3b2, 0x3c1, 0x3bf, 0x3c5, 0x3b1, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x39c, 0x3b1, 0x3c1, 0x3c4, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x391, -0x3c0, 0x3c1, 0x3b9, 0x3bb, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x39c, 0x3b1, 0x390, 0x3bf, 0x3c5, 0x3b, 0x399, 0x3bf, 0x3c5, 0x3bd, 0x3af, 0x3bf, -0x3c5, 0x3b, 0x399, 0x3bf, 0x3c5, 0x3bb, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x391, 0x3c5, 0x3b3, 0x3bf, 0x3cd, 0x3c3, 0x3c4, 0x3bf, 0x3c5, 0x3b, -0x3a3, 0x3b5, 0x3c0, 0x3c4, 0x3b5, 0x3bc, 0x3b2, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x39f, 0x3ba, 0x3c4, 0x3c9, 0x3b2, 0x3c1, 0x3af, 0x3bf, -0x3c5, 0x3b, 0x39d, 0x3bf, 0x3b5, 0x3bc, 0x3b2, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x394, 0x3b5, 0x3ba, 0x3b5, 0x3bc, 0x3b2, 0x3c1, 0x3af, -0x3bf, 0x3c5, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, -0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x75, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, -0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x66, -0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x73, 0x69, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, -0x69, 0x3b, 0x6d, 0x61, 0x6a, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, -0x75, 0x73, 0x74, 0x75, 0x73, 0x69, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x69, 0x3b, 0x6f, 0x6b, -0x74, 0x6f, 0x62, 0x65, 0x72, 0x69, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x69, 0x3b, 0x64, 0x65, 0x63, -0x65, 0x6d, 0x62, 0x65, 0x72, 0x69, 0x3b, 0xa9c, 0xabe, 0xaa8, 0xacd, 0xaaf, 0xac1, 0x3b, 0xaab, 0xac7, 0xaac, 0xacd, 0xab0, 0xac1, -0x3b, 0xaae, 0xabe, 0xab0, 0xacd, 0xa9a, 0x3b, 0xa8f, 0xaaa, 0xacd, 0xab0, 0xabf, 0xab2, 0x3b, 0xaae, 0xac7, 0x3b, 0xa9c, 0xac2, 0xaa8, -0x3b, 0xa9c, 0xac1, 0xab2, 0xabe, 0xa88, 0x3b, 0xa91, 0xa97, 0xab8, 0xacd, 0xa9f, 0x3b, 0xab8, 0xaaa, 0xacd, 0xa9f, 0xac7, 0x3b, 0xa91, -0xa95, 0xacd, 0xa9f, 0xacb, 0x3b, 0xaa8, 0xab5, 0xac7, 0x3b, 0xaa1, 0xabf, 0xab8, 0xac7, 0x3b, 0xa9c, 0xabe, 0xaa8, 0xacd, 0xaaf, 0xac1, -0xa86, 0xab0, 0xac0, 0x3b, 0xaab, 0xac7, 0xaac, 0xacd, 0xab0, 0xac1, 0xa86, 0xab0, 0xac0, 0x3b, 0xaae, 0xabe, 0xab0, 0xacd, 0xa9a, 0x3b, +0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x6e, 0x65, 0x77, 0x61, 0x72, 0x69, 0x73, 0x3b, 0x46, 0x65, +0x62, 0x72, 0x65, 0x77, 0x61, 0x72, 0x69, 0x73, 0x3b, 0x4d, 0x61, 0x61, 0x72, 0x74, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, +0x3b, 0x4d, 0x61, 0x61, 0x69, 0x65, 0x3b, 0x4a, 0x75, 0x6e, 0x79, 0x3b, 0x4a, 0x75, 0x6c, 0x79, 0x3b, 0x41, 0x75, 0x67, +0x75, 0x73, 0x74, 0x75, 0x73, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x69, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, +0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x69, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x73, 0x69, 0x6d, 0x62, 0x65, +0x72, 0x3b, 0x46, 0x61, 0x6f, 0x69, 0x3b, 0x47, 0x65, 0x61, 0x72, 0x72, 0x3b, 0x4d, 0xe0, 0x72, 0x74, 0x3b, 0x47, 0x69, +0x62, 0x6c, 0x3b, 0x43, 0xe8, 0x69, 0x74, 0x3b, 0xd2, 0x67, 0x6d, 0x68, 0x3b, 0x49, 0x75, 0x63, 0x68, 0x3b, 0x4c, 0xf9, +0x6e, 0x61, 0x3b, 0x53, 0x75, 0x6c, 0x74, 0x3b, 0x44, 0xe0, 0x6d, 0x68, 0x3b, 0x53, 0x61, 0x6d, 0x68, 0x3b, 0x44, 0xf9, +0x62, 0x68, 0x3b, 0x41, 0x6d, 0x20, 0x46, 0x61, 0x6f, 0x69, 0x6c, 0x6c, 0x65, 0x61, 0x63, 0x68, 0x3b, 0x41, 0x6e, 0x20, +0x47, 0x65, 0x61, 0x72, 0x72, 0x61, 0x6e, 0x3b, 0x41, 0x6d, 0x20, 0x4d, 0xe0, 0x72, 0x74, 0x3b, 0x41, 0x6e, 0x20, 0x47, +0x69, 0x62, 0x6c, 0x65, 0x61, 0x6e, 0x3b, 0x41, 0x6e, 0x20, 0x43, 0xe8, 0x69, 0x74, 0x65, 0x61, 0x6e, 0x3b, 0x41, 0x6e, +0x20, 0x74, 0x2d, 0xd2, 0x67, 0x6d, 0x68, 0x69, 0x6f, 0x73, 0x3b, 0x41, 0x6e, 0x20, 0x74, 0x2d, 0x49, 0x75, 0x63, 0x68, +0x61, 0x72, 0x3b, 0x41, 0x6e, 0x20, 0x4c, 0xf9, 0x6e, 0x61, 0x73, 0x74, 0x61, 0x6c, 0x3b, 0x41, 0x6e, 0x20, 0x74, 0x2d, +0x53, 0x75, 0x6c, 0x74, 0x61, 0x69, 0x6e, 0x3b, 0x41, 0x6e, 0x20, 0x44, 0xe0, 0x6d, 0x68, 0x61, 0x69, 0x72, 0x3b, 0x41, +0x6e, 0x20, 0x74, 0x2d, 0x53, 0x61, 0x6d, 0x68, 0x61, 0x69, 0x6e, 0x3b, 0x41, 0x6e, 0x20, 0x44, 0xf9, 0x62, 0x68, 0x6c, +0x61, 0x63, 0x68, 0x64, 0x3b, 0x46, 0x3b, 0x47, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x43, 0x3b, 0xd2, 0x3b, 0x49, 0x3b, 0x4c, +0x3b, 0x53, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x44, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x46, 0x68, 0x61, 0x6f, 0x69, 0x6c, +0x6c, 0x65, 0x61, 0x63, 0x68, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x47, 0x68, 0x65, 0x61, 0x72, 0x72, 0x61, 0x6e, 0x3b, +0x64, 0x68, 0x65, 0x6e, 0x20, 0x4d, 0x68, 0xe0, 0x72, 0x74, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x47, 0x68, 0x69, 0x62, +0x6c, 0x65, 0x61, 0x6e, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x43, 0x68, 0xe8, 0x69, 0x74, 0x65, 0x61, 0x6e, 0x3b, 0x64, +0x68, 0x65, 0x6e, 0x20, 0xd2, 0x67, 0x6d, 0x68, 0x69, 0x6f, 0x73, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x49, 0x75, 0x63, +0x68, 0x61, 0x72, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x4c, 0xf9, 0x6e, 0x61, 0x73, 0x74, 0x61, 0x6c, 0x3b, 0x64, 0x68, +0x65, 0x6e, 0x20, 0x74, 0x2d, 0x53, 0x75, 0x6c, 0x74, 0x61, 0x69, 0x6e, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x44, 0xe0, +0x6d, 0x68, 0x61, 0x69, 0x72, 0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x74, 0x2d, 0x53, 0x61, 0x6d, 0x68, 0x61, 0x69, 0x6e, +0x3b, 0x64, 0x68, 0x65, 0x6e, 0x20, 0x44, 0xf9, 0x62, 0x68, 0x6c, 0x61, 0x63, 0x68, 0x64, 0x3b, 0x58, 0x61, 0x6e, 0x2e, +0x3b, 0x46, 0x65, 0x62, 0x2e, 0x3b, 0x4d, 0x61, 0x72, 0x2e, 0x3b, 0x41, 0x62, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x69, 0x6f, +0x3b, 0x58, 0x75, 0xf1, 0x6f, 0x3b, 0x58, 0x75, 0x6c, 0x2e, 0x3b, 0x41, 0x67, 0x6f, 0x2e, 0x3b, 0x53, 0x65, 0x74, 0x2e, +0x3b, 0x4f, 0x75, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x65, 0x63, 0x2e, 0x3b, 0x58, 0x61, 0x6e, 0x65, +0x69, 0x72, 0x6f, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x4d, 0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x41, +0x62, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x6f, 0x3b, 0x58, 0x75, 0xf1, 0x6f, 0x3b, 0x58, 0x75, 0x6c, 0x6c, 0x6f, +0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x4f, 0x75, 0x74, +0x75, 0x62, 0x72, 0x6f, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x44, 0x65, 0x63, 0x65, 0x6d, 0x62, +0x72, 0x6f, 0x3b, 0x58, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x58, 0x3b, 0x58, 0x3b, 0x41, 0x3b, 0x53, +0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x78, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, +0x2e, 0x3b, 0x61, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x6f, 0x3b, 0x78, 0x75, 0xf1, 0x6f, 0x3b, 0x78, 0x75, 0x6c, +0x2e, 0x3b, 0x61, 0x67, 0x6f, 0x2e, 0x3b, 0x73, 0x65, 0x74, 0x2e, 0x3b, 0x6f, 0x75, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, +0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x78, 0x61, 0x6e, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x65, +0x69, 0x72, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x6f, +0x3b, 0x78, 0x75, 0xf1, 0x6f, 0x3b, 0x78, 0x75, 0x6c, 0x6c, 0x6f, 0x3b, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x73, +0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x6f, 0x75, 0x74, 0x75, 0x62, 0x72, 0x6f, 0x3b, 0x6e, 0x6f, 0x76, 0x65, +0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x78, 0x2e, 0x3b, 0x66, 0x2e, 0x3b, +0x6d, 0x2e, 0x3b, 0x61, 0x2e, 0x3b, 0x6d, 0x2e, 0x3b, 0x78, 0x2e, 0x3b, 0x78, 0x2e, 0x3b, 0x61, 0x2e, 0x3b, 0x73, 0x2e, +0x3b, 0x6f, 0x2e, 0x3b, 0x6e, 0x2e, 0x3b, 0x64, 0x2e, 0x3b, 0x10d8, 0x10d0, 0x10dc, 0x3b, 0x10d7, 0x10d4, 0x10d1, 0x3b, 0x10db, 0x10d0, +0x10e0, 0x3b, 0x10d0, 0x10de, 0x10e0, 0x3b, 0x10db, 0x10d0, 0x10d8, 0x3b, 0x10d8, 0x10d5, 0x10dc, 0x3b, 0x10d8, 0x10d5, 0x10da, 0x3b, 0x10d0, 0x10d2, +0x10d5, 0x3b, 0x10e1, 0x10d4, 0x10e5, 0x3b, 0x10dd, 0x10e5, 0x10e2, 0x3b, 0x10dc, 0x10dd, 0x10d4, 0x3b, 0x10d3, 0x10d4, 0x10d9, 0x3b, 0x10d8, 0x10d0, +0x10dc, 0x10d5, 0x10d0, 0x10e0, 0x10d8, 0x3b, 0x10d7, 0x10d4, 0x10d1, 0x10d4, 0x10e0, 0x10d5, 0x10d0, 0x10da, 0x10d8, 0x3b, 0x10db, 0x10d0, 0x10e0, 0x10e2, +0x10d8, 0x3b, 0x10d0, 0x10de, 0x10e0, 0x10d8, 0x10da, 0x10d8, 0x3b, 0x10db, 0x10d0, 0x10d8, 0x10e1, 0x10d8, 0x3b, 0x10d8, 0x10d5, 0x10dc, 0x10d8, 0x10e1, +0x10d8, 0x3b, 0x10d8, 0x10d5, 0x10da, 0x10d8, 0x10e1, 0x10d8, 0x3b, 0x10d0, 0x10d2, 0x10d5, 0x10d8, 0x10e1, 0x10e2, 0x10dd, 0x3b, 0x10e1, 0x10d4, 0x10e5, +0x10e2, 0x10d4, 0x10db, 0x10d1, 0x10d4, 0x10e0, 0x10d8, 0x3b, 0x10dd, 0x10e5, 0x10e2, 0x10dd, 0x10db, 0x10d1, 0x10d4, 0x10e0, 0x10d8, 0x3b, 0x10dc, 0x10dd, +0x10d4, 0x10db, 0x10d1, 0x10d4, 0x10e0, 0x10d8, 0x3b, 0x10d3, 0x10d4, 0x10d9, 0x10d4, 0x10db, 0x10d1, 0x10d4, 0x10e0, 0x10d8, 0x3b, 0x10d8, 0x3b, 0x10d7, +0x3b, 0x10db, 0x3b, 0x10d0, 0x3b, 0x10db, 0x3b, 0x10d8, 0x3b, 0x10d8, 0x3b, 0x10d0, 0x3b, 0x10e1, 0x3b, 0x10dd, 0x3b, 0x10dc, 0x3b, 0x10d3, +0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0xe4, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0x69, +0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x75, 0x67, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, +0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x7a, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x46, 0x65, 0x62, 0x72, +0x75, 0x61, 0x72, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, +0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, +0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, +0x65, 0x72, 0x3b, 0x44, 0x65, 0x7a, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x61, 0x6e, 0x2e, 0x3b, 0x46, 0x65, 0x62, +0x2e, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, +0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x2e, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x4f, 0x6b, 0x74, +0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x65, 0x7a, 0x2e, 0x3b, 0x4a, 0xe4, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, +0x4d, 0xe4, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, +0x41, 0x75, 0x67, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x7a, 0x3b, +0x4a, 0xe4, 0x6e, 0x6e, 0x65, 0x72, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x3b, +0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, +0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, +0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x7a, 0x65, 0x6d, 0x62, +0x65, 0x72, 0x3b, 0x4a, 0xe4, 0x6e, 0x2e, 0x3b, 0x46, 0x65, 0x62, 0x2e, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41, 0x70, +0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, +0x2e, 0x3b, 0x53, 0x65, 0x70, 0x2e, 0x3b, 0x4f, 0x6b, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x65, 0x7a, +0x2e, 0x3b, 0x399, 0x3b1, 0x3bd, 0x3b, 0x3a6, 0x3b5, 0x3b2, 0x3b, 0x39c, 0x3ac, 0x3c1, 0x3b, 0x391, 0x3c0, 0x3c1, 0x3b, 0x39c, 0x3ac, +0x3b9, 0x3b, 0x399, 0x3bf, 0x3cd, 0x3bd, 0x3b, 0x399, 0x3bf, 0x3cd, 0x3bb, 0x3b, 0x391, 0x3cd, 0x3b3, 0x3b, 0x3a3, 0x3b5, 0x3c0, 0x3b, +0x39f, 0x3ba, 0x3c4, 0x3b, 0x39d, 0x3bf, 0x3ad, 0x3b, 0x394, 0x3b5, 0x3ba, 0x3b, 0x399, 0x3b1, 0x3bd, 0x3bf, 0x3c5, 0x3ac, 0x3c1, 0x3b9, +0x3bf, 0x3c2, 0x3b, 0x3a6, 0x3b5, 0x3b2, 0x3c1, 0x3bf, 0x3c5, 0x3ac, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x39c, 0x3ac, 0x3c1, 0x3c4, 0x3b9, +0x3bf, 0x3c2, 0x3b, 0x391, 0x3c0, 0x3c1, 0x3af, 0x3bb, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x39c, 0x3ac, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x399, 0x3bf, +0x3cd, 0x3bd, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x399, 0x3bf, 0x3cd, 0x3bb, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x391, 0x3cd, 0x3b3, 0x3bf, 0x3c5, 0x3c3, +0x3c4, 0x3bf, 0x3c2, 0x3b, 0x3a3, 0x3b5, 0x3c0, 0x3c4, 0x3ad, 0x3bc, 0x3b2, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x39f, 0x3ba, 0x3c4, 0x3ce, +0x3b2, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x39d, 0x3bf, 0x3ad, 0x3bc, 0x3b2, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x394, 0x3b5, 0x3ba, 0x3ad, +0x3bc, 0x3b2, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x399, 0x3b, 0x3a6, 0x3b, 0x39c, 0x3b, 0x391, 0x3b, 0x39c, 0x3b, 0x399, 0x3b, 0x399, +0x3b, 0x391, 0x3b, 0x3a3, 0x3b, 0x39f, 0x3b, 0x39d, 0x3b, 0x394, 0x3b, 0x399, 0x3b1, 0x3bd, 0x3b, 0x3a6, 0x3b5, 0x3b2, 0x3b, 0x39c, +0x3b1, 0x3c1, 0x3b, 0x391, 0x3c0, 0x3c1, 0x3b, 0x39c, 0x3b1, 0x390, 0x3b, 0x399, 0x3bf, 0x3c5, 0x3bd, 0x3b, 0x399, 0x3bf, 0x3c5, 0x3bb, +0x3b, 0x391, 0x3c5, 0x3b3, 0x3b, 0x3a3, 0x3b5, 0x3c0, 0x3b, 0x39f, 0x3ba, 0x3c4, 0x3b, 0x39d, 0x3bf, 0x3b5, 0x3b, 0x394, 0x3b5, 0x3ba, +0x3b, 0x399, 0x3b1, 0x3bd, 0x3bf, 0x3c5, 0x3b1, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x3a6, 0x3b5, 0x3b2, 0x3c1, 0x3bf, 0x3c5, 0x3b1, 0x3c1, +0x3af, 0x3bf, 0x3c5, 0x3b, 0x39c, 0x3b1, 0x3c1, 0x3c4, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x391, 0x3c0, 0x3c1, 0x3b9, 0x3bb, 0x3af, 0x3bf, 0x3c5, +0x3b, 0x39c, 0x3b1, 0x390, 0x3bf, 0x3c5, 0x3b, 0x399, 0x3bf, 0x3c5, 0x3bd, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x399, 0x3bf, 0x3c5, 0x3bb, 0x3af, +0x3bf, 0x3c5, 0x3b, 0x391, 0x3c5, 0x3b3, 0x3bf, 0x3cd, 0x3c3, 0x3c4, 0x3bf, 0x3c5, 0x3b, 0x3a3, 0x3b5, 0x3c0, 0x3c4, 0x3b5, 0x3bc, 0x3b2, +0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x39f, 0x3ba, 0x3c4, 0x3c9, 0x3b2, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x39d, 0x3bf, 0x3b5, 0x3bc, 0x3b2, +0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x394, 0x3b5, 0x3ba, 0x3b5, 0x3bc, 0x3b2, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, +0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, +0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x75, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, +0x64, 0x65, 0x63, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, +0x3b, 0x6d, 0x61, 0x72, 0x74, 0x73, 0x69, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x69, 0x3b, 0x6d, 0x61, 0x6a, 0x69, 0x3b, +0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x75, 0x73, 0x69, 0x3b, +0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x69, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x69, 0x3b, +0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x69, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x69, 0x3b, +0xa9c, 0xabe, 0xaa8, 0xacd, 0xaaf, 0xac1, 0x3b, 0xaab, 0xac7, 0xaac, 0xacd, 0xab0, 0xac1, 0x3b, 0xaae, 0xabe, 0xab0, 0xacd, 0xa9a, 0x3b, 0xa8f, 0xaaa, 0xacd, 0xab0, 0xabf, 0xab2, 0x3b, 0xaae, 0xac7, 0x3b, 0xa9c, 0xac2, 0xaa8, 0x3b, 0xa9c, 0xac1, 0xab2, 0xabe, 0xa88, 0x3b, -0xa91, 0xa97, 0xab8, 0xacd, 0xa9f, 0x3b, 0xab8, 0xaaa, 0xacd, 0xa9f, 0xac7, 0xaae, 0xacd, 0xaac, 0xab0, 0x3b, 0xa91, 0xa95, 0xacd, 0xa9f, -0xacb, 0xaac, 0xab0, 0x3b, 0xaa8, 0xab5, 0xac7, 0xaae, 0xacd, 0xaac, 0xab0, 0x3b, 0xaa1, 0xabf, 0xab8, 0xac7, 0xaae, 0xacd, 0xaac, 0xab0, -0x3b, 0xa9c, 0xabe, 0x3b, 0xaab, 0xac7, 0x3b, 0xaae, 0xabe, 0x3b, 0xa8f, 0x3b, 0xaae, 0xac7, 0x3b, 0xa9c, 0xac2, 0x3b, 0xa9c, 0xac1, -0x3b, 0xa91, 0x3b, 0xab8, 0x3b, 0xa91, 0x3b, 0xaa8, 0x3b, 0xaa1, 0xabf, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x61, 0x62, 0x3b, -0x4d, 0x61, 0x72, 0x3b, 0x41, 0x66, 0x69, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x59, 0x75, 0x6e, 0x3b, 0x59, 0x75, 0x6c, 0x3b, -0x41, 0x67, 0x75, 0x3b, 0x53, 0x61, 0x74, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x75, 0x77, 0x3b, 0x44, 0x69, 0x73, 0x3b, -0x4a, 0x61, 0x6e, 0x61, 0x69, 0x72, 0x75, 0x3b, 0x46, 0x61, 0x62, 0x75, 0x72, 0x61, 0x69, 0x72, 0x75, 0x3b, 0x4d, 0x61, -0x72, 0x69, 0x73, 0x3b, 0x41, 0x66, 0x69, 0x72, 0x69, 0x6c, 0x75, 0x3b, 0x4d, 0x61, 0x79, 0x75, 0x3b, 0x59, 0x75, 0x6e, -0x69, 0x3b, 0x59, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x67, 0x75, 0x73, 0x74, 0x61, 0x3b, 0x53, 0x61, 0x74, 0x75, 0x6d, 0x62, -0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x75, 0x77, 0x61, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, -0x61, 0x6d, 0x62, 0x61, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x59, 0x3b, 0x59, 0x3b, 0x41, -0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x5d9, 0x5e0, 0x5d5, 0x5f3, 0x3b, 0x5e4, 0x5d1, 0x5e8, 0x5f3, 0x3b, 0x5de, -0x5e8, 0x5e5, 0x3b, 0x5d0, 0x5e4, 0x5e8, 0x5f3, 0x3b, 0x5de, 0x5d0, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5e0, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dc, -0x5d9, 0x3b, 0x5d0, 0x5d5, 0x5d2, 0x5f3, 0x3b, 0x5e1, 0x5e4, 0x5d8, 0x5f3, 0x3b, 0x5d0, 0x5d5, 0x5e7, 0x5f3, 0x3b, 0x5e0, 0x5d5, 0x5d1, -0x5f3, 0x3b, 0x5d3, 0x5e6, 0x5de, 0x5f3, 0x3b, 0x5d9, 0x5e0, 0x5d5, 0x5d0, 0x5e8, 0x3b, 0x5e4, 0x5d1, 0x5e8, 0x5d5, 0x5d0, 0x5e8, 0x3b, -0x5de, 0x5e8, 0x5e5, 0x3b, 0x5d0, 0x5e4, 0x5e8, 0x5d9, 0x5dc, 0x3b, 0x5de, 0x5d0, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5e0, 0x5d9, 0x3b, 0x5d9, -0x5d5, 0x5dc, 0x5d9, 0x3b, 0x5d0, 0x5d5, 0x5d2, 0x5d5, 0x5e1, 0x5d8, 0x3b, 0x5e1, 0x5e4, 0x5d8, 0x5de, 0x5d1, 0x5e8, 0x3b, 0x5d0, 0x5d5, -0x5e7, 0x5d8, 0x5d5, 0x5d1, 0x5e8, 0x3b, 0x5e0, 0x5d5, 0x5d1, 0x5de, 0x5d1, 0x5e8, 0x3b, 0x5d3, 0x5e6, 0x5de, 0x5d1, 0x5e8, 0x3b, 0x91c, -0x928, 0x970, 0x3b, 0x92b, 0x93c, 0x930, 0x970, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x905, 0x92a, 0x94d, 0x930, 0x948, 0x932, -0x3b, 0x92e, 0x908, 0x3b, 0x91c, 0x942, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x970, 0x3b, 0x905, 0x917, 0x970, 0x3b, 0x938, 0x93f, 0x924, -0x970, 0x3b, 0x905, 0x915, 0x94d, 0x924, 0x942, 0x970, 0x3b, 0x928, 0x935, 0x970, 0x3b, 0x926, 0x93f, 0x938, 0x970, 0x3b, 0x91c, 0x928, -0x935, 0x930, 0x940, 0x3b, 0x92b, 0x93c, 0x930, 0x935, 0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x905, 0x92a, 0x94d, -0x930, 0x948, 0x932, 0x3b, 0x92e, 0x908, 0x3b, 0x91c, 0x942, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x93e, 0x908, 0x3b, 0x905, 0x917, 0x938, -0x94d, 0x924, 0x3b, 0x938, 0x93f, 0x924, 0x902, 0x92c, 0x930, 0x3b, 0x905, 0x915, 0x94d, 0x924, 0x942, 0x92c, 0x930, 0x3b, 0x928, 0x935, -0x902, 0x92c, 0x930, 0x3b, 0x926, 0x93f, 0x938, 0x902, 0x92c, 0x930, 0x3b, 0x91c, 0x3b, 0x92b, 0x93c, 0x3b, 0x92e, 0x93e, 0x3b, 0x905, -0x3b, 0x92e, 0x3b, 0x91c, 0x942, 0x3b, 0x91c, 0x941, 0x3b, 0x905, 0x3b, 0x938, 0x93f, 0x3b, 0x905, 0x3b, 0x928, 0x3b, 0x926, 0x93f, -0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0xe1, 0x72, 0x63, 0x2e, 0x3b, 0xe1, 0x70, -0x72, 0x2e, 0x3b, 0x6d, 0xe1, 0x6a, 0x2e, 0x3b, 0x6a, 0xfa, 0x6e, 0x2e, 0x3b, 0x6a, 0xfa, 0x6c, 0x2e, 0x3b, 0x61, 0x75, -0x67, 0x2e, 0x3b, 0x73, 0x7a, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, -0x64, 0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0xe1, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0xe1, 0x72, 0x3b, -0x6d, 0xe1, 0x72, 0x63, 0x69, 0x75, 0x73, 0x3b, 0xe1, 0x70, 0x72, 0x69, 0x6c, 0x69, 0x73, 0x3b, 0x6d, 0xe1, 0x6a, 0x75, -0x73, 0x3b, 0x6a, 0xfa, 0x6e, 0x69, 0x75, 0x73, 0x3b, 0x6a, 0xfa, 0x6c, 0x69, 0x75, 0x73, 0x3b, 0x61, 0x75, 0x67, 0x75, -0x73, 0x7a, 0x74, 0x75, 0x73, 0x3b, 0x73, 0x7a, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, -0xf3, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, -0x65, 0x72, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0xc1, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x53, -0x7a, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, -0x72, 0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0xed, 0x3b, 0x6a, 0xfa, 0x6e, 0x2e, 0x3b, 0x6a, 0xfa, 0x6c, -0x2e, 0x3b, 0xe1, 0x67, 0xfa, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0xf3, 0x76, -0x2e, 0x3b, 0x64, 0x65, 0x73, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0xfa, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0xfa, 0x61, -0x72, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0xed, 0x6c, 0x3b, 0x6d, 0x61, 0xed, 0x3b, 0x6a, 0xfa, 0x6e, -0xed, 0x3b, 0x6a, 0xfa, 0x6c, 0xed, 0x3b, 0xe1, 0x67, 0xfa, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, -0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0xf3, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0xf3, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, -0x64, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, -0x3b, 0x4a, 0x3b, 0xc1, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, -0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, -0x3b, 0x41, 0x67, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, -0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, -0x72, 0x65, 0x74, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, -0x75, 0x6c, 0x69, 0x3b, 0x41, 0x67, 0x75, 0x73, 0x74, 0x75, 0x73, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, -0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, -0x65, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x45, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x61, 0x62, 0x68, 0x3b, 0x4d, 0xe1, -0x72, 0x74, 0x61, 0x3b, 0x41, 0x69, 0x62, 0x3b, 0x42, 0x65, 0x61, 0x6c, 0x3b, 0x4d, 0x65, 0x69, 0x74, 0x68, 0x3b, 0x49, -0xfa, 0x69, 0x6c, 0x3b, 0x4c, 0xfa, 0x6e, 0x3b, 0x4d, 0x46, 0xf3, 0x6d, 0x68, 0x3b, 0x44, 0x46, 0xf3, 0x6d, 0x68, 0x3b, -0x53, 0x61, 0x6d, 0x68, 0x3b, 0x4e, 0x6f, 0x6c, 0x6c, 0x3b, 0x45, 0x61, 0x6e, 0xe1, 0x69, 0x72, 0x3b, 0x46, 0x65, 0x61, -0x62, 0x68, 0x72, 0x61, 0x3b, 0x4d, 0xe1, 0x72, 0x74, 0x61, 0x3b, 0x41, 0x69, 0x62, 0x72, 0x65, 0xe1, 0x6e, 0x3b, 0x42, -0x65, 0x61, 0x6c, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x3b, 0x4d, 0x65, 0x69, 0x74, 0x68, 0x65, 0x61, 0x6d, 0x68, 0x3b, 0x49, -0xfa, 0x69, 0x6c, 0x3b, 0x4c, 0xfa, 0x6e, 0x61, 0x73, 0x61, 0x3b, 0x4d, 0x65, 0xe1, 0x6e, 0x20, 0x46, 0xf3, 0x6d, 0x68, -0x61, 0x69, 0x72, 0x3b, 0x44, 0x65, 0x69, 0x72, 0x65, 0x61, 0x64, 0x68, 0x20, 0x46, 0xf3, 0x6d, 0x68, 0x61, 0x69, 0x72, -0x3b, 0x53, 0x61, 0x6d, 0x68, 0x61, 0x69, 0x6e, 0x3b, 0x4e, 0x6f, 0x6c, 0x6c, 0x61, 0x69, 0x67, 0x3b, 0x45, 0x3b, 0x46, -0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x42, 0x3b, 0x4d, 0x3b, 0x49, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x4e, -0x3b, 0x67, 0x65, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x67, -0x3b, 0x67, 0x69, 0x75, 0x3b, 0x6c, 0x75, 0x67, 0x3b, 0x61, 0x67, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x3b, 0x6f, 0x74, 0x74, -0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x69, 0x63, 0x3b, 0x67, 0x65, 0x6e, 0x6e, 0x61, 0x69, 0x6f, 0x3b, 0x66, 0x65, 0x62, -0x62, 0x72, 0x61, 0x69, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x65, 0x3b, 0x6d, -0x61, 0x67, 0x67, 0x69, 0x6f, 0x3b, 0x67, 0x69, 0x75, 0x67, 0x6e, 0x6f, 0x3b, 0x6c, 0x75, 0x67, 0x6c, 0x69, 0x6f, 0x3b, -0x61, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x74, 0x74, -0x6f, 0x62, 0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x69, 0x63, 0x65, 0x6d, 0x62, -0x72, 0x65, 0x3b, 0x47, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x4c, 0x3b, 0x41, 0x3b, 0x53, -0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0xc9c, 0xca8, 0x3b, 0xcab, 0xcc6, 0xcac, 0xccd, 0xcb0, 0x3b, 0xcae, 0xcbe, 0xcb0, 0xccd, -0xc9a, 0xccd, 0x3b, 0xc8f, 0xcaa, 0xccd, 0xcb0, 0xcbf, 0x3b, 0xcae, 0xcc7, 0x3b, 0xc9c, 0xcc2, 0xca8, 0xccd, 0x3b, 0xc9c, 0xcc1, 0xcb2, -0xcc8, 0x3b, 0xc86, 0xc97, 0x3b, 0xcb8, 0xcc6, 0xcaa, 0xccd, 0xc9f, 0xcc6, 0xc82, 0x3b, 0xc85, 0xc95, 0xccd, 0xc9f, 0xccb, 0x3b, 0xca8, -0xcb5, 0xcc6, 0xc82, 0x3b, 0xca1, 0xcbf, 0xcb8, 0xcc6, 0xc82, 0x3b, 0xc9c, 0xca8, 0xcb5, 0xcb0, 0xcbf, 0x3b, 0xcab, 0xcc6, 0xcac, 0xccd, -0xcb0, 0xcb5, 0xcb0, 0xcbf, 0x3b, 0xcae, 0xcbe, 0xcb0, 0xccd, 0xc9a, 0xccd, 0x3b, 0xc8f, 0xcaa, 0xccd, 0xcb0, 0xcbf, 0xcb2, 0xccd, 0x3b, -0xcae, 0xcc7, 0x3b, 0xc9c, 0xcc2, 0xca8, 0xccd, 0x3b, 0xc9c, 0xcc1, 0xcb2, 0xcc8, 0x3b, 0xc86, 0xc97, 0xcb8, 0xccd, 0xc9f, 0xccd, 0x3b, -0xcb8, 0xcc6, 0xcaa, 0xccd, 0xc9f, 0xcc6, 0xc82, 0xcac, 0xcb0, 0xccd, 0x3b, 0xc85, 0xc95, 0xccd, 0xc9f, 0xccb, 0xcac, 0xcb0, 0xccd, 0x3b, -0xca8, 0xcb5, 0xcc6, 0xc82, 0xcac, 0xcb0, 0xccd, 0x3b, 0xca1, 0xcbf, 0xcb8, 0xcc6, 0xc82, 0xcac, 0xcb0, 0xccd, 0x3b, 0xc9c, 0x3b, 0xcab, -0xcc6, 0x3b, 0xcae, 0xcbe, 0x3b, 0xc8f, 0x3b, 0xcae, 0xcc7, 0x3b, 0xc9c, 0xcc2, 0x3b, 0xc9c, 0xcc1, 0x3b, 0xc86, 0x3b, 0xcb8, 0xcc6, -0x3b, 0xc85, 0x3b, 0xca8, 0x3b, 0xca1, 0xcbf, 0x3b, 0xc9c, 0xca8, 0xcb5, 0xcb0, 0xcbf, 0x3b, 0xcab, 0xcc6, 0xcac, 0xccd, 0xcb0, 0xcb5, -0xcb0, 0xcbf, 0x3b, 0xcae, 0xcbe, 0xcb0, 0xccd, 0xc9a, 0xccd, 0x3b, 0xc8f, 0xcaa, 0xccd, 0xcb0, 0xcbf, 0x3b, 0xcae, 0xcc7, 0x3b, 0xc9c, -0xcc2, 0xca8, 0xccd, 0x3b, 0xc9c, 0xcc1, 0xcb2, 0xcc8, 0x3b, 0xc86, 0xc97, 0x3b, 0xcb8, 0xcc6, 0xcaa, 0xccd, 0xc9f, 0xcc6, 0xc82, 0x3b, -0xc85, 0xc95, 0xccd, 0xc9f, 0xccb, 0x3b, 0xca8, 0xcb5, 0xcc6, 0xc82, 0x3b, 0xca1, 0xcbf, 0xcb8, 0xcc6, 0xc82, 0x3b, 0x62c, 0x646, 0x624, -0x631, 0x6cc, 0x3b, 0x641, 0x631, 0x624, 0x631, 0x6cc, 0x3b, 0x645, 0x627, 0x631, 0x655, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, -0x3b, 0x645, 0x6cc, 0x654, 0x3b, 0x62c, 0x648, 0x657, 0x646, 0x3b, 0x62c, 0x648, 0x657, 0x644, 0x627, 0x6cc, 0x6cc, 0x3b, 0x627, 0x6af, -0x633, 0x62a, 0x3b, 0x633, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648, 0x657, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, -0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x62c, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x627, 0x3b, 0x645, 0x3b, 0x62c, -0x3b, 0x62c, 0x3b, 0x627, 0x3b, 0x633, 0x3b, 0x633, 0x3b, 0x627, 0x3b, 0x646, 0x3b, 0x49a, 0x430, 0x4a3, 0x2e, 0x3b, 0x410, 0x49b, -0x43f, 0x2e, 0x3b, 0x41d, 0x430, 0x443, 0x2e, 0x3b, 0x421, 0x4d9, 0x443, 0x2e, 0x3b, 0x41c, 0x430, 0x43c, 0x2e, 0x3b, 0x41c, 0x430, -0x443, 0x2e, 0x3b, 0x428, 0x456, 0x43b, 0x2e, 0x3b, 0x422, 0x430, 0x43c, 0x2e, 0x3b, 0x49a, 0x44b, 0x440, 0x2e, 0x3b, 0x49a, 0x430, -0x437, 0x2e, 0x3b, 0x49a, 0x430, 0x440, 0x2e, 0x3b, 0x416, 0x435, 0x43b, 0x2e, 0x3b, 0x49a, 0x430, 0x4a3, 0x442, 0x430, 0x440, 0x3b, -0x410, 0x49b, 0x43f, 0x430, 0x43d, 0x3b, 0x41d, 0x430, 0x443, 0x440, 0x44b, 0x437, 0x3b, 0x421, 0x4d9, 0x443, 0x456, 0x440, 0x3b, 0x41c, -0x430, 0x43c, 0x44b, 0x440, 0x3b, 0x41c, 0x430, 0x443, 0x441, 0x44b, 0x43c, 0x3b, 0x428, 0x456, 0x43b, 0x434, 0x435, 0x3b, 0x422, 0x430, -0x43c, 0x44b, 0x437, 0x3b, 0x49a, 0x44b, 0x440, 0x43a, 0x4af, 0x439, 0x435, 0x43a, 0x3b, 0x49a, 0x430, 0x437, 0x430, 0x43d, 0x3b, 0x49a, -0x430, 0x440, 0x430, 0x448, 0x430, 0x3b, 0x416, 0x435, 0x43b, 0x442, 0x43e, 0x49b, 0x441, 0x430, 0x43d, 0x3b, 0x49a, 0x3b, 0x410, 0x3b, -0x41d, 0x3b, 0x421, 0x3b, 0x41c, 0x3b, 0x41c, 0x3b, 0x428, 0x3b, 0x422, 0x3b, 0x49a, 0x3b, 0x49a, 0x3b, 0x49a, 0x3b, 0x416, 0x3b, -0x49b, 0x430, 0x4a3, 0x2e, 0x3b, 0x430, 0x49b, 0x43f, 0x2e, 0x3b, 0x43d, 0x430, 0x443, 0x2e, 0x3b, 0x441, 0x4d9, 0x443, 0x2e, 0x3b, -0x43c, 0x430, 0x43c, 0x2e, 0x3b, 0x43c, 0x430, 0x443, 0x2e, 0x3b, 0x448, 0x456, 0x43b, 0x2e, 0x3b, 0x442, 0x430, 0x43c, 0x2e, 0x3b, -0x49b, 0x44b, 0x440, 0x2e, 0x3b, 0x49b, 0x430, 0x437, 0x2e, 0x3b, 0x49b, 0x430, 0x440, 0x2e, 0x3b, 0x436, 0x435, 0x43b, 0x2e, 0x3b, -0x49b, 0x430, 0x4a3, 0x442, 0x430, 0x440, 0x3b, 0x430, 0x49b, 0x43f, 0x430, 0x43d, 0x3b, 0x43d, 0x430, 0x443, 0x440, 0x44b, 0x437, 0x3b, -0x441, 0x4d9, 0x443, 0x456, 0x440, 0x3b, 0x43c, 0x430, 0x43c, 0x44b, 0x440, 0x3b, 0x43c, 0x430, 0x443, 0x441, 0x44b, 0x43c, 0x3b, 0x448, -0x456, 0x43b, 0x434, 0x435, 0x3b, 0x442, 0x430, 0x43c, 0x44b, 0x437, 0x3b, 0x49b, 0x44b, 0x440, 0x43a, 0x4af, 0x439, 0x435, 0x43a, 0x3b, -0x49b, 0x430, 0x437, 0x430, 0x43d, 0x3b, 0x49b, 0x430, 0x440, 0x430, 0x448, 0x430, 0x3b, 0x436, 0x435, 0x43b, 0x442, 0x43e, 0x49b, 0x441, -0x430, 0x43d, 0x3b, 0x6d, 0x75, 0x74, 0x2e, 0x3b, 0x67, 0x61, 0x73, 0x2e, 0x3b, 0x77, 0x65, 0x72, 0x2e, 0x3b, 0x6d, 0x61, -0x74, 0x2e, 0x3b, 0x67, 0x69, 0x63, 0x2e, 0x3b, 0x6b, 0x61, 0x6d, 0x2e, 0x3b, 0x6e, 0x79, 0x61, 0x2e, 0x3b, 0x6b, 0x61, -0x6e, 0x2e, 0x3b, 0x6e, 0x7a, 0x65, 0x2e, 0x3b, 0x75, 0x6b, 0x77, 0x2e, 0x3b, 0x75, 0x67, 0x75, 0x2e, 0x3b, 0x75, 0x6b, -0x75, 0x2e, 0x3b, 0x4d, 0x75, 0x74, 0x61, 0x72, 0x61, 0x6d, 0x61, 0x3b, 0x47, 0x61, 0x73, 0x68, 0x79, 0x61, 0x6e, 0x74, -0x61, 0x72, 0x65, 0x3b, 0x57, 0x65, 0x72, 0x75, 0x72, 0x77, 0x65, 0x3b, 0x4d, 0x61, 0x74, 0x61, 0x3b, 0x47, 0x69, 0x63, -0x75, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x3b, 0x4b, 0x61, 0x6d, 0x65, 0x6e, 0x61, 0x3b, 0x4e, 0x79, 0x61, 0x6b, 0x61, 0x6e, -0x67, 0x61, 0x3b, 0x4b, 0x61, 0x6e, 0x61, 0x6d, 0x61, 0x3b, 0x4e, 0x7a, 0x65, 0x6c, 0x69, 0x3b, 0x55, 0x6b, 0x77, 0x61, -0x6b, 0x69, 0x72, 0x61, 0x3b, 0x55, 0x67, 0x75, 0x73, 0x68, 0x79, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x55, 0x6b, 0x75, 0x62, -0x6f, 0x7a, 0x61, 0x3b, 0x42f, 0x43d, 0x432, 0x3b, 0x424, 0x435, 0x432, 0x3b, 0x41c, 0x430, 0x440, 0x3b, 0x410, 0x43f, 0x440, 0x3b, -0x41c, 0x430, 0x439, 0x3b, 0x418, 0x44e, 0x43d, 0x3b, 0x418, 0x44e, 0x43b, 0x3b, 0x410, 0x432, 0x433, 0x3b, 0x421, 0x435, 0x43d, 0x3b, -0x41e, 0x43a, 0x442, 0x3b, 0x41d, 0x43e, 0x44f, 0x3b, 0x414, 0x435, 0x43a, 0x3b, 0x42f, 0x43d, 0x432, 0x430, 0x440, 0x44c, 0x3b, 0x424, -0x435, 0x432, 0x440, 0x430, 0x43b, 0x44c, 0x3b, 0x41c, 0x430, 0x440, 0x442, 0x3b, 0x410, 0x43f, 0x440, 0x435, 0x43b, 0x44c, 0x3b, 0x41c, -0x430, 0x439, 0x3b, 0x418, 0x44e, 0x43d, 0x44c, 0x3b, 0x418, 0x44e, 0x43b, 0x44c, 0x3b, 0x410, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, -0x421, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x41e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x41d, 0x43e, 0x44f, -0x431, 0x440, 0x44c, 0x3b, 0x414, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x44c, 0x3b, 0x42f, 0x3b, 0x424, 0x3b, 0x41c, 0x3b, 0x410, 0x3b, -0x41c, 0x3b, 0x418, 0x3b, 0x418, 0x3b, 0x410, 0x3b, 0x421, 0x3b, 0x41e, 0x3b, 0x41d, 0x3b, 0x414, 0x3b, 0x44f, 0x43d, 0x432, 0x2e, -0x3b, 0x444, 0x435, 0x432, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x2e, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x439, 0x3b, -0x438, 0x44e, 0x43d, 0x2e, 0x3b, 0x438, 0x44e, 0x43b, 0x2e, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43d, 0x2e, 0x3b, -0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x44f, 0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x2e, 0x3b, 0x44f, 0x43d, 0x432, 0x430, 0x440, -0x44c, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x44c, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x435, 0x43b, -0x44c, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x438, 0x44e, 0x43d, 0x44c, 0x3b, 0x438, 0x44e, 0x43b, 0x44c, 0x3b, 0x430, 0x432, 0x433, 0x443, -0x441, 0x442, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x43e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, -0x43d, 0x43e, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x434, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x44c, 0x3b, 0x31, 0xc6d4, 0x3b, 0x32, 0xc6d4, -0x3b, 0x33, 0xc6d4, 0x3b, 0x34, 0xc6d4, 0x3b, 0x35, 0xc6d4, 0x3b, 0x36, 0xc6d4, 0x3b, 0x37, 0xc6d4, 0x3b, 0x38, 0xc6d4, 0x3b, 0x39, -0xc6d4, 0x3b, 0x31, 0x30, 0xc6d4, 0x3b, 0x31, 0x31, 0xc6d4, 0x3b, 0x31, 0x32, 0xc6d4, 0x3b, 0x4d, 0x75, 0x74, 0x2e, 0x3b, 0x47, -0x61, 0x73, 0x2e, 0x3b, 0x57, 0x65, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x74, 0x2e, 0x3b, 0x47, 0x69, 0x63, 0x2e, 0x3b, 0x4b, -0x61, 0x6d, 0x2e, 0x3b, 0x4e, 0x79, 0x61, 0x2e, 0x3b, 0x4b, 0x61, 0x6e, 0x2e, 0x3b, 0x4e, 0x7a, 0x65, 0x2e, 0x3b, 0x55, -0x6b, 0x77, 0x2e, 0x3b, 0x55, 0x67, 0x75, 0x2e, 0x3b, 0x55, 0x6b, 0x75, 0x2e, 0x3b, 0x4e, 0x7a, 0x65, 0x72, 0x6f, 0x3b, -0x52, 0x75, 0x68, 0x75, 0x68, 0x75, 0x6d, 0x61, 0x3b, 0x4e, 0x74, 0x77, 0x61, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x3b, 0x4e, -0x64, 0x61, 0x6d, 0x75, 0x6b, 0x69, 0x7a, 0x61, 0x3b, 0x52, 0x75, 0x73, 0x61, 0x6d, 0x61, 0x3b, 0x52, 0x75, 0x68, 0x65, -0x73, 0x68, 0x69, 0x3b, 0x4d, 0x75, 0x6b, 0x61, 0x6b, 0x61, 0x72, 0x6f, 0x3b, 0x4e, 0x79, 0x61, 0x6e, 0x64, 0x61, 0x67, -0x61, 0x72, 0x6f, 0x3b, 0x4e, 0x79, 0x61, 0x6b, 0x61, 0x6e, 0x67, 0x61, 0x3b, 0x47, 0x69, 0x74, 0x75, 0x67, 0x75, 0x74, -0x75, 0x3b, 0x4d, 0x75, 0x6e, 0x79, 0x6f, 0x6e, 0x79, 0x6f, 0x3b, 0x4b, 0x69, 0x67, 0x61, 0x72, 0x61, 0x6d, 0x61, 0x3b, -0xea1, 0x2e, 0xe81, 0x2e, 0x3b, 0xe81, 0x2e, 0xe9e, 0x2e, 0x3b, 0xea1, 0x2e, 0xe99, 0x2e, 0x3b, 0xea1, 0x2e, 0xeaa, 0x2e, 0x3b, -0xe9e, 0x2e, 0xe9e, 0x2e, 0x3b, 0xea1, 0xeb4, 0x2e, 0xe96, 0x2e, 0x3b, 0xe81, 0x2e, 0xea5, 0x2e, 0x3b, 0xeaa, 0x2e, 0xeab, 0x2e, -0x3b, 0xe81, 0x2e, 0xe8d, 0x2e, 0x3b, 0xe95, 0x2e, 0xea5, 0x2e, 0x3b, 0xe9e, 0x2e, 0xe88, 0x2e, 0x3b, 0xe97, 0x2e, 0xea7, 0x2e, -0x3b, 0xea1, 0xeb1, 0xe87, 0xe81, 0xead, 0xe99, 0x3b, 0xe81, 0xeb8, 0xea1, 0xe9e, 0xeb2, 0x3b, 0xea1, 0xeb5, 0xe99, 0xeb2, 0x3b, 0xec0, -0xea1, 0xeaa, 0xeb2, 0x3b, 0xe9e, 0xeb6, 0xe94, 0xeaa, 0xeb0, 0xe9e, 0xeb2, 0x3b, 0xea1, 0xeb4, 0xe96, 0xeb8, 0xe99, 0xeb2, 0x3b, 0xe81, -0xecd, 0xea5, 0xeb0, 0xe81, 0xebb, 0xe94, 0x3b, 0xeaa, 0xeb4, 0xe87, 0xeab, 0xeb2, 0x3b, 0xe81, 0xeb1, 0xe99, 0xe8d, 0xeb2, 0x3b, 0xe95, -0xeb8, 0xea5, 0xeb2, 0x3b, 0xe9e, 0xeb0, 0xe88, 0xeb4, 0xe81, 0x3b, 0xe97, 0xeb1, 0xe99, 0xea7, 0xeb2, 0x3b, 0x6a, 0x61, 0x6e, 0x76, -0x2e, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, -0x61, 0x69, 0x6a, 0x73, 0x3b, 0x6a, 0x16b, 0x6e, 0x2e, 0x3b, 0x6a, 0x16b, 0x6c, 0x2e, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, -0x73, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, -0x3b, 0x6a, 0x61, 0x6e, 0x76, 0x101, 0x72, 0x69, 0x73, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x101, 0x72, 0x69, 0x73, 0x3b, -0x6d, 0x61, 0x72, 0x74, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x12b, 0x6c, 0x69, 0x73, 0x3b, 0x6d, 0x61, 0x69, 0x6a, 0x73, 0x3b, -0x6a, 0x16b, 0x6e, 0x69, 0x6a, 0x73, 0x3b, 0x6a, 0x16b, 0x6c, 0x69, 0x6a, 0x73, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, -0x73, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x73, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x72, 0x69, -0x73, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x73, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x69, -0x73, 0x3b, 0x79, 0x61, 0x6e, 0x3b, 0x66, 0x62, 0x6c, 0x3b, 0x6d, 0x73, 0x69, 0x3b, 0x61, 0x70, 0x6c, 0x3b, 0x6d, 0x61, -0x69, 0x3b, 0x79, 0x75, 0x6e, 0x3b, 0x79, 0x75, 0x6c, 0x3b, 0x61, 0x67, 0x74, 0x3b, 0x73, 0x74, 0x62, 0x3b, 0x254, 0x74, -0x62, 0x3b, 0x6e, 0x76, 0x62, 0x3b, 0x64, 0x73, 0x62, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x79, -0x61, 0x6d, 0x62, 0x6f, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x62, 0x61, 0x6c, 0xe9, -0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x73, 0xe1, 0x74, 0x6f, 0x3b, 0x73, 0xe1, 0x6e, -0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x6e, 0x65, 0x69, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, -0x20, 0x6d, 0xed, 0x74, 0xe1, 0x6e, 0x6f, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0x6f, 0x74, -0xf3, 0x62, 0xe1, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6e, 0x73, 0x61, 0x6d, 0x62, 0x6f, 0x3b, -0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0x77, 0x61, 0x6d, 0x62, 0x65, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, -0xe1, 0x20, 0x79, 0x61, 0x20, 0x6c, 0x69, 0x62, 0x77, 0x61, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, -0x7a, 0xf3, 0x6d, 0x69, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x7a, 0xf3, 0x6d, 0x69, 0x20, 0x6e, -0x61, 0x20, 0x6d, 0x254, 0x30c, 0x6b, 0x254, 0x301, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x7a, 0xf3, -0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0xed, 0x62, 0x61, 0x6c, 0xe9, 0x3b, 0x79, 0x3b, 0x66, 0x3b, 0x6d, 0x3b, 0x61, -0x3b, 0x6d, 0x3b, 0x79, 0x3b, 0x79, 0x3b, 0x61, 0x3b, 0x73, 0x3b, 0x254, 0x3b, 0x6e, 0x3b, 0x64, 0x3b, 0x73, 0x61, 0x75, -0x73, 0x2e, 0x3b, 0x76, 0x61, 0x73, 0x2e, 0x3b, 0x6b, 0x6f, 0x76, 0x2e, 0x3b, 0x62, 0x61, 0x6c, 0x2e, 0x3b, 0x67, 0x65, -0x67, 0x2e, 0x3b, 0x62, 0x69, 0x72, 0x17e, 0x2e, 0x3b, 0x6c, 0x69, 0x65, 0x70, 0x2e, 0x3b, 0x72, 0x75, 0x67, 0x70, 0x2e, -0x3b, 0x72, 0x75, 0x67, 0x73, 0x2e, 0x3b, 0x73, 0x70, 0x61, 0x6c, 0x2e, 0x3b, 0x6c, 0x61, 0x70, 0x6b, 0x72, 0x2e, 0x3b, -0x67, 0x72, 0x75, 0x6f, 0x64, 0x2e, 0x3b, 0x73, 0x61, 0x75, 0x73, 0x69, 0x73, 0x3b, 0x76, 0x61, 0x73, 0x61, 0x72, 0x69, -0x73, 0x3b, 0x6b, 0x6f, 0x76, 0x61, 0x73, 0x3b, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x69, 0x73, 0x3b, 0x67, 0x65, 0x67, -0x75, 0x17e, 0x117, 0x3b, 0x62, 0x69, 0x72, 0x17e, 0x65, 0x6c, 0x69, 0x73, 0x3b, 0x6c, 0x69, 0x65, 0x70, 0x61, 0x3b, 0x72, -0x75, 0x67, 0x70, 0x6a, 0x16b, 0x74, 0x69, 0x73, 0x3b, 0x72, 0x75, 0x67, 0x73, 0x117, 0x6a, 0x69, 0x73, 0x3b, 0x73, 0x70, -0x61, 0x6c, 0x69, 0x73, 0x3b, 0x6c, 0x61, 0x70, 0x6b, 0x72, 0x69, 0x74, 0x69, 0x73, 0x3b, 0x67, 0x72, 0x75, 0x6f, 0x64, -0x69, 0x73, 0x3b, 0x53, 0x3b, 0x56, 0x3b, 0x4b, 0x3b, 0x42, 0x3b, 0x47, 0x3b, 0x42, 0x3b, 0x4c, 0x3b, 0x52, 0x3b, 0x52, -0x3b, 0x53, 0x3b, 0x4c, 0x3b, 0x47, 0x3b, 0x73, 0x61, 0x75, 0x73, 0x69, 0x6f, 0x3b, 0x76, 0x61, 0x73, 0x61, 0x72, 0x69, -0x6f, 0x3b, 0x6b, 0x6f, 0x76, 0x6f, 0x3b, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x17e, 0x69, 0x6f, 0x3b, 0x67, 0x65, 0x67, -0x75, 0x17e, 0x117, 0x73, 0x3b, 0x62, 0x69, 0x72, 0x17e, 0x65, 0x6c, 0x69, 0x6f, 0x3b, 0x6c, 0x69, 0x65, 0x70, 0x6f, 0x73, -0x3b, 0x72, 0x75, 0x67, 0x70, 0x6a, 0x16b, 0x10d, 0x69, 0x6f, 0x3b, 0x72, 0x75, 0x67, 0x73, 0x117, 0x6a, 0x6f, 0x3b, 0x73, -0x70, 0x61, 0x6c, 0x69, 0x6f, 0x3b, 0x6c, 0x61, 0x70, 0x6b, 0x72, 0x69, 0x10d, 0x69, 0x6f, 0x3b, 0x67, 0x72, 0x75, 0x6f, -0x64, 0x17e, 0x69, 0x6f, 0x3b, 0x458, 0x430, 0x43d, 0x2e, 0x3b, 0x444, 0x435, 0x432, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x2e, 0x3b, -0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x2e, 0x3b, 0x458, 0x443, 0x43b, 0x2e, 0x3b, 0x430, -0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x435, 0x43c, 0x2e, -0x3b, 0x434, 0x435, 0x43a, 0x2e, 0x3b, 0x458, 0x430, 0x43d, 0x443, 0x430, 0x440, 0x438, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x443, 0x430, -0x440, 0x438, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, -0x43d, 0x438, 0x3b, 0x458, 0x443, 0x43b, 0x438, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x435, -0x43c, 0x432, 0x440, 0x438, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x43d, 0x43e, 0x435, 0x43c, 0x432, 0x440, -0x438, 0x3b, 0x434, 0x435, 0x43a, 0x435, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x458, 0x3b, 0x444, 0x3b, 0x43c, 0x3b, 0x430, 0x3b, 0x43c, -0x3b, 0x458, 0x3b, 0x458, 0x3b, 0x430, 0x3b, 0x441, 0x3b, 0x43e, 0x3b, 0x43d, 0x3b, 0x434, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, -0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x79, 0x3b, 0x4a, 0x6f, 0x6e, 0x3b, 0x4a, -0x6f, 0x6c, 0x3b, 0x41, 0x6f, 0x67, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, -0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x6f, 0x61, 0x72, 0x79, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x6f, 0x61, 0x72, 0x79, 0x3b, -0x4d, 0x61, 0x72, 0x74, 0x73, 0x61, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x79, 0x3b, 0x4d, 0x65, 0x79, 0x3b, 0x4a, 0x6f, -0x6e, 0x61, 0x3b, 0x4a, 0x6f, 0x6c, 0x61, 0x79, 0x3b, 0x41, 0x6f, 0x67, 0x6f, 0x73, 0x69, 0x74, 0x72, 0x61, 0x3b, 0x53, -0x65, 0x70, 0x74, 0x61, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x72, 0x61, 0x3b, 0x4e, 0x6f, 0x76, -0x61, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x44, 0x65, 0x73, 0x61, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, -0x65, 0x62, 0x3b, 0x4d, 0x61, 0x63, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, -0x75, 0x6c, 0x3b, 0x4f, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, -0x69, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, -0x4d, 0x61, 0x63, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, -0x6c, 0x61, 0x69, 0x3b, 0x4f, 0x67, 0x6f, 0x73, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, -0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x69, 0x73, 0x65, -0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x4f, -0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0xd1c, 0xd28, 0xd41, 0x3b, 0xd2b, 0xd46, 0xd2c, 0xd4d, 0xd30, 0xd41, 0x3b, -0xd2e, 0xd3e, 0xd7c, 0x3b, 0xd0f, 0xd2a, 0xd4d, 0xd30, 0xd3f, 0x3b, 0xd2e, 0xd47, 0xd2f, 0xd4d, 0x3b, 0xd1c, 0xd42, 0xd7a, 0x3b, 0xd1c, -0xd42, 0xd32, 0xd48, 0x3b, 0xd13, 0xd17, 0x3b, 0xd38, 0xd46, 0xd2a, 0xd4d, 0xd31, 0xd4d, 0xd31, 0xd02, 0x3b, 0xd12, 0xd15, 0xd4d, 0xd1f, -0xd4b, 0x3b, 0xd28, 0xd35, 0xd02, 0x3b, 0xd21, 0xd3f, 0xd38, 0xd02, 0x3b, 0xd1c, 0xd28, 0xd41, 0xd35, 0xd30, 0xd3f, 0x3b, 0xd2b, 0xd46, -0xd2c, 0xd4d, 0xd30, 0xd41, 0xd35, 0xd30, 0xd3f, 0x3b, 0xd2e, 0xd3e, 0xd7c, 0xd1a, 0xd4d, 0xd1a, 0xd4d, 0x3b, 0xd0f, 0xd2a, 0xd4d, 0xd30, -0xd3f, 0xd7d, 0x3b, 0xd2e, 0xd47, 0xd2f, 0xd4d, 0x3b, 0xd1c, 0xd42, 0xd7a, 0x3b, 0xd1c, 0xd42, 0xd32, 0xd48, 0x3b, 0xd13, 0xd17, 0xd38, -0xd4d, 0xd31, 0xd4d, 0xd31, 0xd4d, 0x3b, 0xd38, 0xd46, 0xd2a, 0xd4d, 0xd31, 0xd4d, 0xd31, 0xd02, 0xd2c, 0xd7c, 0x3b, 0xd12, 0xd15, 0xd4d, -0x200c, 0xd1f, 0xd4b, 0xd2c, 0xd7c, 0x3b, 0xd28, 0xd35, 0xd02, 0xd2c, 0xd7c, 0x3b, 0xd21, 0xd3f, 0xd38, 0xd02, 0xd2c, 0xd7c, 0x3b, 0xd1c, -0x3b, 0xd2b, 0xd46, 0x3b, 0xd2e, 0xd3e, 0x3b, 0xd0f, 0x3b, 0xd2e, 0xd46, 0x3b, 0xd1c, 0xd42, 0xd7a, 0x3b, 0xd1c, 0xd42, 0x3b, 0xd13, -0x3b, 0xd38, 0xd46, 0x3b, 0xd12, 0x3b, 0xd28, 0x3b, 0xd21, 0xd3f, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x72, 0x61, 0x3b, 0x4d, -0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x6a, 0x3b, 0x120, 0x75, 0x6e, 0x3b, 0x4c, 0x75, 0x6c, 0x3b, 0x41, -0x77, 0x77, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x74, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x10b, 0x3b, 0x4a, -0x61, 0x6e, 0x6e, 0x61, 0x72, 0x3b, 0x46, 0x72, 0x61, 0x72, 0x3b, 0x4d, 0x61, 0x72, 0x7a, 0x75, 0x3b, 0x41, 0x70, 0x72, -0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x6a, 0x6a, 0x75, 0x3b, 0x120, 0x75, 0x6e, 0x6a, 0x75, 0x3b, 0x4c, 0x75, 0x6c, 0x6a, 0x75, -0x3b, 0x41, 0x77, 0x77, 0x69, 0x73, 0x73, 0x75, 0x3b, 0x53, 0x65, 0x74, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x75, 0x3b, 0x4f, -0x74, 0x74, 0x75, 0x62, 0x72, 0x75, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x75, 0x3b, 0x44, 0x69, 0x10b, 0x65, -0x6d, 0x62, 0x72, 0x75, 0x3b, 0x4a, 0x6e, 0x3b, 0x46, 0x72, 0x3b, 0x4d, 0x7a, 0x3b, 0x41, 0x70, 0x3b, 0x4d, 0x6a, 0x3b, -0x120, 0x6e, 0x3b, 0x4c, 0x6a, 0x3b, 0x41, 0x77, 0x3b, 0x53, 0x74, 0x3b, 0x4f, 0x62, 0x3b, 0x4e, 0x76, 0x3b, 0x44, 0x10b, -0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x120, 0x3b, 0x4c, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, -0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x91c, 0x93e, 0x928, 0x947, 0x3b, 0x92b, 0x947, 0x92c, 0x94d, 0x930, 0x941, 0x3b, 0x92e, 0x93e, 0x930, -0x94d, 0x91a, 0x3b, 0x90f, 0x92a, 0x94d, 0x930, 0x93f, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x942, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x948, -0x3b, 0x911, 0x917, 0x3b, 0x938, 0x92a, 0x94d, 0x91f, 0x947, 0x902, 0x3b, 0x911, 0x915, 0x94d, 0x91f, 0x94b, 0x3b, 0x928, 0x94b, 0x935, -0x94d, 0x939, 0x947, 0x902, 0x3b, 0x921, 0x93f, 0x938, 0x947, 0x902, 0x3b, 0x91c, 0x93e, 0x928, 0x947, 0x935, 0x93e, 0x930, 0x940, 0x3b, -0x92b, 0x947, 0x92c, 0x94d, 0x930, 0x941, 0x935, 0x93e, 0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x90f, 0x92a, 0x94d, -0x930, 0x93f, 0x932, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x942, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x948, 0x3b, 0x911, 0x917, 0x938, 0x94d, -0x91f, 0x3b, 0x938, 0x92a, 0x94d, 0x91f, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x911, 0x915, 0x94d, 0x91f, 0x94b, 0x92c, 0x930, 0x3b, 0x928, -0x94b, 0x935, 0x94d, 0x939, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x921, 0x93f, 0x938, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x91c, 0x93e, 0x3b, -0x92b, 0x947, 0x3b, 0x92e, 0x93e, 0x3b, 0x90f, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x942, 0x3b, 0x91c, 0x941, 0x3b, 0x911, 0x3b, 0x938, -0x3b, 0x911, 0x3b, 0x928, 0x94b, 0x3b, 0x921, 0x93f, 0x3b, 0x31, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x32, 0x2d, 0x440, -0x20, 0x441, 0x430, 0x440, 0x3b, 0x33, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x34, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, -0x3b, 0x35, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x36, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x37, 0x2d, 0x440, -0x20, 0x441, 0x430, 0x440, 0x3b, 0x38, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x39, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, -0x3b, 0x31, 0x30, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x31, 0x31, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x31, -0x32, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x41d, 0x44d, 0x433, 0x434, 0x4af, 0x433, 0x44d, 0x44d, 0x440, 0x20, 0x441, 0x430, -0x440, 0x3b, 0x425, 0x43e, 0x451, 0x440, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x413, 0x443, 0x440, -0x430, 0x432, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x414, 0x4e9, 0x440, 0x4e9, 0x432, 0x434, 0x4af, -0x433, 0x44d, 0x44d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x422, 0x430, 0x432, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, -0x430, 0x440, 0x3b, 0x417, 0x443, 0x440, 0x433, 0x430, 0x430, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, -0x414, 0x43e, 0x43b, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x41d, 0x430, 0x439, 0x43c, 0x434, 0x443, -0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x415, 0x441, 0x434, 0x4af, 0x433, 0x44d, 0x44d, 0x440, 0x20, 0x441, 0x430, -0x440, 0x3b, 0x410, 0x440, 0x430, 0x432, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x410, 0x440, 0x432, -0x430, 0x43d, 0x20, 0x43d, 0x44d, 0x433, 0x434, 0x4af, 0x433, 0x44d, 0x44d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x410, 0x440, 0x432, -0x430, 0x43d, 0x20, 0x445, 0x43e, 0x451, 0x440, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x49, 0x3b, -0x49, 0x49, 0x3b, 0x49, 0x49, 0x49, 0x3b, 0x49, 0x56, 0x3b, 0x56, 0x3b, 0x56, 0x49, 0x3b, 0x56, 0x49, 0x49, 0x3b, 0x56, -0x49, 0x49, 0x49, 0x3b, 0x49, 0x58, 0x3b, 0x58, 0x3b, 0x58, 0x49, 0x3b, 0x58, 0x49, 0x49, 0x3b, 0x91c, 0x928, 0x935, 0x930, -0x940, 0x3b, 0x92b, 0x947, 0x92c, 0x94d, 0x930, 0x941, 0x905, 0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x905, 0x92a, -0x94d, 0x930, 0x93f, 0x932, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x941, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x93e, 0x908, 0x3b, 0x905, 0x917, -0x938, 0x94d, 0x91f, 0x3b, 0x938, 0x947, 0x92a, 0x94d, 0x91f, 0x947, 0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x905, 0x915, 0x94d, 0x91f, 0x94b, -0x92c, 0x930, 0x3b, 0x928, 0x94b, 0x92d, 0x947, 0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x921, 0x93f, 0x938, 0x947, 0x92e, 0x94d, 0x92c, 0x930, -0x3b, 0x91c, 0x928, 0x3b, 0x92b, 0x947, 0x947, 0x92c, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x905, 0x92a, 0x94d, 0x930, 0x3b, -0x92e, 0x947, 0x3b, 0x91c, 0x941, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x3b, 0x905, 0x917, 0x3b, 0x938, 0x947, 0x92a, 0x3b, 0x905, 0x915, -0x94d, 0x91f, 0x94b, 0x3b, 0x928, 0x94b, 0x92d, 0x947, 0x3b, 0x921, 0x93f, 0x938, 0x947, 0x3b, 0x91c, 0x928, 0x3b, 0x92b, 0x947, 0x92c, -0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x905, 0x92a, 0x94d, 0x930, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x941, 0x928, 0x3b, 0x91c, -0x941, 0x932, 0x3b, 0x905, 0x917, 0x3b, 0x938, 0x947, 0x92a, 0x3b, 0x905, 0x915, 0x94d, 0x91f, 0x94b, 0x3b, 0x928, 0x94b, 0x92d, 0x947, -0x3b, 0x921, 0x93f, 0x938, 0x947, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, -0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x69, -0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, -0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, -0x64, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0xb1c, 0xb3e, 0xb28, 0xb41, 0xb06, 0xb30, 0xb40, 0x3b, 0xb2b, 0xb47, 0xb2c, -0xb43, 0xb06, 0xb30, 0xb40, 0x3b, 0xb2e, 0xb3e, 0xb30, 0xb4d, 0xb1a, 0xb4d, 0xb1a, 0x3b, 0xb05, 0xb2a, 0xb4d, 0xb30, 0xb47, 0xb32, 0x3b, -0xb2e, 0xb07, 0x3b, 0xb1c, 0xb41, 0xb28, 0x3b, 0xb1c, 0xb41, 0xb32, 0xb3e, 0xb07, 0x3b, 0xb05, 0xb17, 0xb37, 0xb4d, 0xb1f, 0x3b, 0xb38, -0xb47, 0xb2a, 0xb4d, 0xb1f, 0xb47, 0xb2e, 0xb4d, 0xb2c, 0xb30, 0x3b, 0xb05, 0xb15, 0xb4d, 0xb1f, 0xb4b, 0xb2c, 0xb30, 0x3b, 0xb28, 0xb2d, -0xb47, 0xb2e, 0xb4d, 0xb2c, 0xb30, 0x3b, 0xb21, 0xb3f, 0xb38, 0xb47, 0xb2e, 0xb4d, 0xb2c, 0xb30, 0x3b, 0xb1c, 0xb3e, 0x3b, 0xb2b, 0xb47, -0x3b, 0xb2e, 0xb3e, 0x3b, 0xb05, 0x3b, 0xb2e, 0xb07, 0x3b, 0xb1c, 0xb41, 0x3b, 0xb1c, 0xb41, 0x3b, 0xb05, 0x3b, 0xb38, 0xb47, 0x3b, -0xb05, 0x3b, 0xb28, 0x3b, 0xb21, 0xb3f, 0x3b, 0x62c, 0x646, 0x648, 0x631, 0x64a, 0x3b, 0x641, 0x628, 0x631, 0x648, 0x631, 0x64a, 0x3b, -0x645, 0x627, 0x631, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x6cd, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648, -0x644, 0x627, 0x6cc, 0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x67e, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648, -0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x62c, 0x646, 0x648, 0x631, 0x64a, -0x3b, 0x641, 0x6d0, 0x628, 0x631, 0x648, 0x631, 0x64a, 0x3b, 0x645, 0x627, 0x631, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, -0x645, 0x6cd, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648, 0x644, 0x627, 0x6cc, 0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x67e, -0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, -0x645, 0x628, 0x631, 0x3b, 0x62c, 0x646, 0x648, 0x631, 0x64a, 0x3b, 0x641, 0x628, 0x631, 0x648, 0x631, 0x64a, 0x3b, 0x645, 0x627, 0x631, +0xa91, 0xa97, 0xab8, 0xacd, 0xa9f, 0x3b, 0xab8, 0xaaa, 0xacd, 0xa9f, 0xac7, 0x3b, 0xa91, 0xa95, 0xacd, 0xa9f, 0xacb, 0x3b, 0xaa8, 0xab5, +0xac7, 0x3b, 0xaa1, 0xabf, 0xab8, 0xac7, 0x3b, 0xa9c, 0xabe, 0xaa8, 0xacd, 0xaaf, 0xac1, 0xa86, 0xab0, 0xac0, 0x3b, 0xaab, 0xac7, 0xaac, +0xacd, 0xab0, 0xac1, 0xa86, 0xab0, 0xac0, 0x3b, 0xaae, 0xabe, 0xab0, 0xacd, 0xa9a, 0x3b, 0xa8f, 0xaaa, 0xacd, 0xab0, 0xabf, 0xab2, 0x3b, +0xaae, 0xac7, 0x3b, 0xa9c, 0xac2, 0xaa8, 0x3b, 0xa9c, 0xac1, 0xab2, 0xabe, 0xa88, 0x3b, 0xa91, 0xa97, 0xab8, 0xacd, 0xa9f, 0x3b, 0xab8, +0xaaa, 0xacd, 0xa9f, 0xac7, 0xaae, 0xacd, 0xaac, 0xab0, 0x3b, 0xa91, 0xa95, 0xacd, 0xa9f, 0xacb, 0xaac, 0xab0, 0x3b, 0xaa8, 0xab5, 0xac7, +0xaae, 0xacd, 0xaac, 0xab0, 0x3b, 0xaa1, 0xabf, 0xab8, 0xac7, 0xaae, 0xacd, 0xaac, 0xab0, 0x3b, 0xa9c, 0xabe, 0x3b, 0xaab, 0xac7, 0x3b, +0xaae, 0xabe, 0x3b, 0xa8f, 0x3b, 0xaae, 0xac7, 0x3b, 0xa9c, 0xac2, 0x3b, 0xa9c, 0xac1, 0x3b, 0xa91, 0x3b, 0xab8, 0x3b, 0xa91, 0x3b, +0xaa8, 0x3b, 0xaa1, 0xabf, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x61, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x66, 0x69, +0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x59, 0x75, 0x6e, 0x3b, 0x59, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x75, 0x3b, 0x53, 0x61, 0x74, +0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x75, 0x77, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x61, 0x69, 0x72, 0x75, +0x3b, 0x46, 0x61, 0x62, 0x75, 0x72, 0x61, 0x69, 0x72, 0x75, 0x3b, 0x4d, 0x61, 0x72, 0x69, 0x73, 0x3b, 0x41, 0x66, 0x69, +0x72, 0x69, 0x6c, 0x75, 0x3b, 0x4d, 0x61, 0x79, 0x75, 0x3b, 0x59, 0x75, 0x6e, 0x69, 0x3b, 0x59, 0x75, 0x6c, 0x69, 0x3b, +0x41, 0x67, 0x75, 0x73, 0x74, 0x61, 0x3b, 0x53, 0x61, 0x74, 0x75, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, +0x61, 0x3b, 0x4e, 0x75, 0x77, 0x61, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, 0x61, 0x6d, 0x62, 0x61, 0x3b, 0x4a, 0x3b, +0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x59, 0x3b, 0x59, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, +0x44, 0x3b, 0x5d9, 0x5e0, 0x5d5, 0x5f3, 0x3b, 0x5e4, 0x5d1, 0x5e8, 0x5f3, 0x3b, 0x5de, 0x5e8, 0x5e5, 0x3b, 0x5d0, 0x5e4, 0x5e8, 0x5f3, +0x3b, 0x5de, 0x5d0, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5e0, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dc, 0x5d9, 0x3b, 0x5d0, 0x5d5, 0x5d2, 0x5f3, 0x3b, +0x5e1, 0x5e4, 0x5d8, 0x5f3, 0x3b, 0x5d0, 0x5d5, 0x5e7, 0x5f3, 0x3b, 0x5e0, 0x5d5, 0x5d1, 0x5f3, 0x3b, 0x5d3, 0x5e6, 0x5de, 0x5f3, 0x3b, +0x5d9, 0x5e0, 0x5d5, 0x5d0, 0x5e8, 0x3b, 0x5e4, 0x5d1, 0x5e8, 0x5d5, 0x5d0, 0x5e8, 0x3b, 0x5de, 0x5e8, 0x5e5, 0x3b, 0x5d0, 0x5e4, 0x5e8, +0x5d9, 0x5dc, 0x3b, 0x5de, 0x5d0, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5e0, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dc, 0x5d9, 0x3b, 0x5d0, 0x5d5, 0x5d2, +0x5d5, 0x5e1, 0x5d8, 0x3b, 0x5e1, 0x5e4, 0x5d8, 0x5de, 0x5d1, 0x5e8, 0x3b, 0x5d0, 0x5d5, 0x5e7, 0x5d8, 0x5d5, 0x5d1, 0x5e8, 0x3b, 0x5e0, +0x5d5, 0x5d1, 0x5de, 0x5d1, 0x5e8, 0x3b, 0x5d3, 0x5e6, 0x5de, 0x5d1, 0x5e8, 0x3b, 0x91c, 0x928, 0x970, 0x3b, 0x92b, 0x93c, 0x930, 0x970, +0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x905, 0x92a, 0x94d, 0x930, 0x948, 0x932, 0x3b, 0x92e, 0x908, 0x3b, 0x91c, 0x942, 0x928, +0x3b, 0x91c, 0x941, 0x932, 0x970, 0x3b, 0x905, 0x917, 0x970, 0x3b, 0x938, 0x93f, 0x924, 0x970, 0x3b, 0x905, 0x915, 0x94d, 0x924, 0x942, +0x970, 0x3b, 0x928, 0x935, 0x970, 0x3b, 0x926, 0x93f, 0x938, 0x970, 0x3b, 0x91c, 0x928, 0x935, 0x930, 0x940, 0x3b, 0x92b, 0x93c, 0x930, +0x935, 0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x905, 0x92a, 0x94d, 0x930, 0x948, 0x932, 0x3b, 0x92e, 0x908, 0x3b, +0x91c, 0x942, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x93e, 0x908, 0x3b, 0x905, 0x917, 0x938, 0x94d, 0x924, 0x3b, 0x938, 0x93f, 0x924, 0x902, +0x92c, 0x930, 0x3b, 0x905, 0x915, 0x94d, 0x924, 0x942, 0x92c, 0x930, 0x3b, 0x928, 0x935, 0x902, 0x92c, 0x930, 0x3b, 0x926, 0x93f, 0x938, +0x902, 0x92c, 0x930, 0x3b, 0x91c, 0x3b, 0x92b, 0x93c, 0x3b, 0x92e, 0x93e, 0x3b, 0x905, 0x3b, 0x92e, 0x3b, 0x91c, 0x942, 0x3b, 0x91c, +0x941, 0x3b, 0x905, 0x3b, 0x938, 0x93f, 0x3b, 0x905, 0x3b, 0x928, 0x3b, 0x926, 0x93f, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, +0x65, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0xe1, 0x72, 0x63, 0x2e, 0x3b, 0xe1, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0xe1, 0x6a, 0x2e, +0x3b, 0x6a, 0xfa, 0x6e, 0x2e, 0x3b, 0x6a, 0xfa, 0x6c, 0x2e, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x7a, 0x65, 0x70, +0x74, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, +0x6e, 0x75, 0xe1, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0xe1, 0x72, 0x3b, 0x6d, 0xe1, 0x72, 0x63, 0x69, 0x75, 0x73, +0x3b, 0xe1, 0x70, 0x72, 0x69, 0x6c, 0x69, 0x73, 0x3b, 0x6d, 0xe1, 0x6a, 0x75, 0x73, 0x3b, 0x6a, 0xfa, 0x6e, 0x69, 0x75, +0x73, 0x3b, 0x6a, 0xfa, 0x6c, 0x69, 0x75, 0x73, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x7a, 0x74, 0x75, 0x73, 0x3b, 0x73, +0x7a, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0xf3, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, +0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, +0x4d, 0x3b, 0xc1, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x53, 0x7a, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, +0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, +0x3b, 0x6d, 0x61, 0xed, 0x3b, 0x6a, 0xfa, 0x6e, 0x2e, 0x3b, 0x6a, 0xfa, 0x6c, 0x2e, 0x3b, 0xe1, 0x67, 0xfa, 0x2e, 0x3b, +0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0xf3, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x73, 0x2e, 0x3b, +0x6a, 0x61, 0x6e, 0xfa, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0xfa, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, +0x61, 0x70, 0x72, 0xed, 0x6c, 0x3b, 0x6d, 0x61, 0xed, 0x3b, 0x6a, 0xfa, 0x6e, 0xed, 0x3b, 0x6a, 0xfa, 0x6c, 0xed, 0x3b, +0xe1, 0x67, 0xfa, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0xf3, +0x62, 0x65, 0x72, 0x3b, 0x6e, 0xf3, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x65, +0x72, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0xc1, 0x3b, 0x53, 0x3b, +0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, +0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x75, 0x3b, 0x53, 0x65, +0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, +0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x72, 0x65, 0x74, 0x3b, 0x41, 0x70, 0x72, +0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x67, 0x75, +0x73, 0x74, 0x75, 0x73, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, +0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, +0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x69, +0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x75, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x63, 0x74, +0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x6f, 0x3b, 0x66, 0x65, +0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x69, 0x6f, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, +0x3b, 0x6d, 0x61, 0x69, 0x6f, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x6f, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x6f, 0x3b, 0x61, 0x75, +0x67, 0x75, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x6f, +0x62, 0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, +0x65, 0x3b, 0x6a, 0x3b, 0x66, 0x3b, 0x6d, 0x3b, 0x61, 0x3b, 0x6d, 0x3b, 0x6a, 0x3b, 0x6a, 0x3b, 0x61, 0x3b, 0x73, 0x3b, +0x6f, 0x3b, 0x6e, 0x3b, 0x64, 0x3b, 0x45, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x61, 0x62, 0x68, 0x3b, 0x4d, 0xe1, 0x72, 0x74, +0x61, 0x3b, 0x41, 0x69, 0x62, 0x3b, 0x42, 0x65, 0x61, 0x6c, 0x3b, 0x4d, 0x65, 0x69, 0x74, 0x68, 0x3b, 0x49, 0xfa, 0x69, +0x6c, 0x3b, 0x4c, 0xfa, 0x6e, 0x3b, 0x4d, 0x46, 0xf3, 0x6d, 0x68, 0x3b, 0x44, 0x46, 0xf3, 0x6d, 0x68, 0x3b, 0x53, 0x61, +0x6d, 0x68, 0x3b, 0x4e, 0x6f, 0x6c, 0x6c, 0x3b, 0x45, 0x61, 0x6e, 0xe1, 0x69, 0x72, 0x3b, 0x46, 0x65, 0x61, 0x62, 0x68, +0x72, 0x61, 0x3b, 0x4d, 0xe1, 0x72, 0x74, 0x61, 0x3b, 0x41, 0x69, 0x62, 0x72, 0x65, 0xe1, 0x6e, 0x3b, 0x42, 0x65, 0x61, +0x6c, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x3b, 0x4d, 0x65, 0x69, 0x74, 0x68, 0x65, 0x61, 0x6d, 0x68, 0x3b, 0x49, 0xfa, 0x69, +0x6c, 0x3b, 0x4c, 0xfa, 0x6e, 0x61, 0x73, 0x61, 0x3b, 0x4d, 0x65, 0xe1, 0x6e, 0x20, 0x46, 0xf3, 0x6d, 0x68, 0x61, 0x69, +0x72, 0x3b, 0x44, 0x65, 0x69, 0x72, 0x65, 0x61, 0x64, 0x68, 0x20, 0x46, 0xf3, 0x6d, 0x68, 0x61, 0x69, 0x72, 0x3b, 0x53, +0x61, 0x6d, 0x68, 0x61, 0x69, 0x6e, 0x3b, 0x4e, 0x6f, 0x6c, 0x6c, 0x61, 0x69, 0x67, 0x3b, 0x45, 0x3b, 0x46, 0x3b, 0x4d, +0x3b, 0x41, 0x3b, 0x42, 0x3b, 0x4d, 0x3b, 0x49, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x4e, 0x3b, 0x67, +0x65, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x67, 0x3b, 0x67, +0x69, 0x75, 0x3b, 0x6c, 0x75, 0x67, 0x3b, 0x61, 0x67, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x3b, 0x6f, 0x74, 0x74, 0x3b, 0x6e, +0x6f, 0x76, 0x3b, 0x64, 0x69, 0x63, 0x3b, 0x67, 0x65, 0x6e, 0x6e, 0x61, 0x69, 0x6f, 0x3b, 0x66, 0x65, 0x62, 0x62, 0x72, +0x61, 0x69, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x65, 0x3b, 0x6d, 0x61, 0x67, +0x67, 0x69, 0x6f, 0x3b, 0x67, 0x69, 0x75, 0x67, 0x6e, 0x6f, 0x3b, 0x6c, 0x75, 0x67, 0x6c, 0x69, 0x6f, 0x3b, 0x61, 0x67, +0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x74, 0x74, 0x6f, 0x62, +0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x69, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x65, +0x3b, 0x47, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x4c, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, +0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, +0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x74, 0x3b, 0x53, 0x65, 0x70, +0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, 0x3b, 0xc9c, 0xca8, 0x3b, 0xcab, 0xcc6, 0xcac, 0xccd, +0xcb0, 0x3b, 0xcae, 0xcbe, 0xcb0, 0xccd, 0xc9a, 0xccd, 0x3b, 0xc8f, 0xcaa, 0xccd, 0xcb0, 0xcbf, 0x3b, 0xcae, 0xcc7, 0x3b, 0xc9c, 0xcc2, +0xca8, 0xccd, 0x3b, 0xc9c, 0xcc1, 0xcb2, 0xcc8, 0x3b, 0xc86, 0xc97, 0x3b, 0xcb8, 0xcc6, 0xcaa, 0xccd, 0xc9f, 0xcc6, 0xc82, 0x3b, 0xc85, +0xc95, 0xccd, 0xc9f, 0xccb, 0x3b, 0xca8, 0xcb5, 0xcc6, 0xc82, 0x3b, 0xca1, 0xcbf, 0xcb8, 0xcc6, 0xc82, 0x3b, 0xc9c, 0xca8, 0xcb5, 0xcb0, +0xcbf, 0x3b, 0xcab, 0xcc6, 0xcac, 0xccd, 0xcb0, 0xcb5, 0xcb0, 0xcbf, 0x3b, 0xcae, 0xcbe, 0xcb0, 0xccd, 0xc9a, 0xccd, 0x3b, 0xc8f, 0xcaa, +0xccd, 0xcb0, 0xcbf, 0xcb2, 0xccd, 0x3b, 0xcae, 0xcc7, 0x3b, 0xc9c, 0xcc2, 0xca8, 0xccd, 0x3b, 0xc9c, 0xcc1, 0xcb2, 0xcc8, 0x3b, 0xc86, +0xc97, 0xcb8, 0xccd, 0xc9f, 0xccd, 0x3b, 0xcb8, 0xcc6, 0xcaa, 0xccd, 0xc9f, 0xcc6, 0xc82, 0xcac, 0xcb0, 0xccd, 0x3b, 0xc85, 0xc95, 0xccd, +0xc9f, 0xccb, 0xcac, 0xcb0, 0xccd, 0x3b, 0xca8, 0xcb5, 0xcc6, 0xc82, 0xcac, 0xcb0, 0xccd, 0x3b, 0xca1, 0xcbf, 0xcb8, 0xcc6, 0xc82, 0xcac, +0xcb0, 0xccd, 0x3b, 0xc9c, 0x3b, 0xcab, 0xcc6, 0x3b, 0xcae, 0xcbe, 0x3b, 0xc8f, 0x3b, 0xcae, 0xcc7, 0x3b, 0xc9c, 0xcc2, 0x3b, 0xc9c, +0xcc1, 0x3b, 0xc86, 0x3b, 0xcb8, 0xcc6, 0x3b, 0xc85, 0x3b, 0xca8, 0x3b, 0xca1, 0xcbf, 0x3b, 0xc9c, 0xca8, 0xcb5, 0xcb0, 0xcbf, 0x3b, +0xcab, 0xcc6, 0xcac, 0xccd, 0xcb0, 0xcb5, 0xcb0, 0xcbf, 0x3b, 0xcae, 0xcbe, 0xcb0, 0xccd, 0xc9a, 0xccd, 0x3b, 0xc8f, 0xcaa, 0xccd, 0xcb0, +0xcbf, 0x3b, 0xcae, 0xcc7, 0x3b, 0xc9c, 0xcc2, 0xca8, 0xccd, 0x3b, 0xc9c, 0xcc1, 0xcb2, 0xcc8, 0x3b, 0xc86, 0xc97, 0x3b, 0xcb8, 0xcc6, +0xcaa, 0xccd, 0xc9f, 0xcc6, 0xc82, 0x3b, 0xc85, 0xc95, 0xccd, 0xc9f, 0xccb, 0x3b, 0xca8, 0xcb5, 0xcc6, 0xc82, 0x3b, 0xca1, 0xcbf, 0xcb8, +0xcc6, 0xc82, 0x3b, 0x62c, 0x646, 0x624, 0x631, 0x6cc, 0x3b, 0x641, 0x631, 0x624, 0x631, 0x6cc, 0x3b, 0x645, 0x627, 0x631, 0x655, 0x686, +0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x6cc, 0x654, 0x3b, 0x62c, 0x648, 0x657, 0x646, 0x3b, 0x62c, 0x648, 0x657, 0x644, +0x627, 0x6cc, 0x6cc, 0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648, 0x657, +0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x62c, 0x3b, 0x641, 0x3b, 0x645, +0x3b, 0x627, 0x3b, 0x645, 0x3b, 0x62c, 0x3b, 0x62c, 0x3b, 0x627, 0x3b, 0x633, 0x3b, 0x633, 0x3b, 0x627, 0x3b, 0x646, 0x3b, 0x49b, +0x430, 0x4a3, 0x2e, 0x3b, 0x430, 0x49b, 0x43f, 0x2e, 0x3b, 0x43d, 0x430, 0x443, 0x2e, 0x3b, 0x441, 0x4d9, 0x443, 0x2e, 0x3b, 0x43c, +0x430, 0x43c, 0x2e, 0x3b, 0x43c, 0x430, 0x443, 0x2e, 0x3b, 0x448, 0x456, 0x43b, 0x2e, 0x3b, 0x442, 0x430, 0x43c, 0x2e, 0x3b, 0x49b, +0x44b, 0x440, 0x2e, 0x3b, 0x49b, 0x430, 0x437, 0x2e, 0x3b, 0x49b, 0x430, 0x440, 0x2e, 0x3b, 0x436, 0x435, 0x43b, 0x2e, 0x3b, 0x49a, +0x430, 0x4a3, 0x442, 0x430, 0x440, 0x3b, 0x410, 0x49b, 0x43f, 0x430, 0x43d, 0x3b, 0x41d, 0x430, 0x443, 0x440, 0x44b, 0x437, 0x3b, 0x421, +0x4d9, 0x443, 0x456, 0x440, 0x3b, 0x41c, 0x430, 0x43c, 0x44b, 0x440, 0x3b, 0x41c, 0x430, 0x443, 0x441, 0x44b, 0x43c, 0x3b, 0x428, 0x456, +0x43b, 0x434, 0x435, 0x3b, 0x422, 0x430, 0x43c, 0x44b, 0x437, 0x3b, 0x49a, 0x44b, 0x440, 0x43a, 0x4af, 0x439, 0x435, 0x43a, 0x3b, 0x49a, +0x430, 0x437, 0x430, 0x43d, 0x3b, 0x49a, 0x430, 0x440, 0x430, 0x448, 0x430, 0x3b, 0x416, 0x435, 0x43b, 0x442, 0x43e, 0x49b, 0x441, 0x430, +0x43d, 0x3b, 0x49a, 0x3b, 0x410, 0x3b, 0x41d, 0x3b, 0x421, 0x3b, 0x41c, 0x3b, 0x41c, 0x3b, 0x428, 0x3b, 0x422, 0x3b, 0x49a, 0x3b, +0x49a, 0x3b, 0x49a, 0x3b, 0x416, 0x3b, 0x49b, 0x430, 0x4a3, 0x442, 0x430, 0x440, 0x3b, 0x430, 0x49b, 0x43f, 0x430, 0x43d, 0x3b, 0x43d, +0x430, 0x443, 0x440, 0x44b, 0x437, 0x3b, 0x441, 0x4d9, 0x443, 0x456, 0x440, 0x3b, 0x43c, 0x430, 0x43c, 0x44b, 0x440, 0x3b, 0x43c, 0x430, +0x443, 0x441, 0x44b, 0x43c, 0x3b, 0x448, 0x456, 0x43b, 0x434, 0x435, 0x3b, 0x442, 0x430, 0x43c, 0x44b, 0x437, 0x3b, 0x49b, 0x44b, 0x440, +0x43a, 0x4af, 0x439, 0x435, 0x43a, 0x3b, 0x49b, 0x430, 0x437, 0x430, 0x43d, 0x3b, 0x49b, 0x430, 0x440, 0x430, 0x448, 0x430, 0x3b, 0x436, +0x435, 0x43b, 0x442, 0x43e, 0x49b, 0x441, 0x430, 0x43d, 0x3b, 0x6d, 0x75, 0x74, 0x2e, 0x3b, 0x67, 0x61, 0x73, 0x2e, 0x3b, 0x77, +0x65, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x74, 0x2e, 0x3b, 0x67, 0x69, 0x63, 0x2e, 0x3b, 0x6b, 0x61, 0x6d, 0x2e, 0x3b, 0x6e, +0x79, 0x61, 0x2e, 0x3b, 0x6b, 0x61, 0x6e, 0x2e, 0x3b, 0x6e, 0x7a, 0x65, 0x2e, 0x3b, 0x75, 0x6b, 0x77, 0x2e, 0x3b, 0x75, +0x67, 0x75, 0x2e, 0x3b, 0x75, 0x6b, 0x75, 0x2e, 0x3b, 0x4d, 0x75, 0x74, 0x61, 0x72, 0x61, 0x6d, 0x61, 0x3b, 0x47, 0x61, +0x73, 0x68, 0x79, 0x61, 0x6e, 0x74, 0x61, 0x72, 0x65, 0x3b, 0x57, 0x65, 0x72, 0x75, 0x72, 0x77, 0x65, 0x3b, 0x4d, 0x61, +0x74, 0x61, 0x3b, 0x47, 0x69, 0x63, 0x75, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x3b, 0x4b, 0x61, 0x6d, 0x65, 0x6e, 0x61, 0x3b, +0x4e, 0x79, 0x61, 0x6b, 0x61, 0x6e, 0x67, 0x61, 0x3b, 0x4b, 0x61, 0x6e, 0x61, 0x6d, 0x61, 0x3b, 0x4e, 0x7a, 0x65, 0x6c, +0x69, 0x3b, 0x55, 0x6b, 0x77, 0x61, 0x6b, 0x69, 0x72, 0x61, 0x3b, 0x55, 0x67, 0x75, 0x73, 0x68, 0x79, 0x69, 0x6e, 0x67, +0x6f, 0x3b, 0x55, 0x6b, 0x75, 0x62, 0x6f, 0x7a, 0x61, 0x3b, 0x42f, 0x43d, 0x432, 0x3b, 0x424, 0x435, 0x432, 0x3b, 0x41c, 0x430, +0x440, 0x3b, 0x410, 0x43f, 0x440, 0x3b, 0x41c, 0x430, 0x439, 0x3b, 0x418, 0x44e, 0x43d, 0x3b, 0x418, 0x44e, 0x43b, 0x3b, 0x410, 0x432, +0x433, 0x3b, 0x421, 0x435, 0x43d, 0x3b, 0x41e, 0x43a, 0x442, 0x3b, 0x41d, 0x43e, 0x44f, 0x3b, 0x414, 0x435, 0x43a, 0x3b, 0x42f, 0x43d, +0x432, 0x430, 0x440, 0x44c, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x44c, 0x3b, 0x41c, 0x430, 0x440, 0x442, 0x3b, 0x410, 0x43f, +0x440, 0x435, 0x43b, 0x44c, 0x3b, 0x41c, 0x430, 0x439, 0x3b, 0x418, 0x44e, 0x43d, 0x44c, 0x3b, 0x418, 0x44e, 0x43b, 0x44c, 0x3b, 0x410, +0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x421, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x41e, 0x43a, 0x442, 0x44f, 0x431, +0x440, 0x44c, 0x3b, 0x41d, 0x43e, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x414, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x44c, 0x3b, 0x42f, 0x3b, +0x424, 0x3b, 0x41c, 0x3b, 0x410, 0x3b, 0x41c, 0x3b, 0x418, 0x3b, 0x418, 0x3b, 0x410, 0x3b, 0x421, 0x3b, 0x41e, 0x3b, 0x41d, 0x3b, +0x414, 0x3b, 0x44f, 0x43d, 0x432, 0x2e, 0x3b, 0x444, 0x435, 0x432, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x2e, 0x3b, 0x430, 0x43f, 0x440, +0x2e, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x438, 0x44e, 0x43d, 0x2e, 0x3b, 0x438, 0x44e, 0x43b, 0x2e, 0x3b, 0x430, 0x432, 0x433, 0x2e, +0x3b, 0x441, 0x435, 0x43d, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x44f, 0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x2e, +0x3b, 0x44f, 0x43d, 0x432, 0x430, 0x440, 0x44c, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x44c, 0x3b, 0x43c, 0x430, 0x440, 0x442, +0x3b, 0x430, 0x43f, 0x440, 0x435, 0x43b, 0x44c, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x438, 0x44e, 0x43d, 0x44c, 0x3b, 0x438, 0x44e, 0x43b, +0x44c, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x43e, 0x43a, +0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x434, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x44c, +0x3b, 0x31, 0xc6d4, 0x3b, 0x32, 0xc6d4, 0x3b, 0x33, 0xc6d4, 0x3b, 0x34, 0xc6d4, 0x3b, 0x35, 0xc6d4, 0x3b, 0x36, 0xc6d4, 0x3b, 0x37, +0xc6d4, 0x3b, 0x38, 0xc6d4, 0x3b, 0x39, 0xc6d4, 0x3b, 0x31, 0x30, 0xc6d4, 0x3b, 0x31, 0x31, 0xc6d4, 0x3b, 0x31, 0x32, 0xc6d4, 0x3b, +0x72, 0xea, 0x62, 0x3b, 0x72, 0x65, 0x15f, 0x3b, 0x61, 0x64, 0x61, 0x3b, 0x61, 0x76, 0x72, 0x3b, 0x67, 0x75, 0x6c, 0x3b, +0x70, 0xfb, 0x15f, 0x3b, 0x74, 0xee, 0x72, 0x3b, 0x67, 0x65, 0x6c, 0x3b, 0x72, 0x65, 0x7a, 0x3b, 0x6b, 0x65, 0x77, 0x3b, +0x73, 0x65, 0x72, 0x3b, 0x62, 0x65, 0x72, 0x3b, 0x72, 0xea, 0x62, 0x65, 0x6e, 0x64, 0x61, 0x6e, 0x3b, 0x72, 0x65, 0x15f, +0x65, 0x6d, 0xee, 0x3b, 0x61, 0x64, 0x61, 0x72, 0x3b, 0x61, 0x76, 0x72, 0xea, 0x6c, 0x3b, 0x67, 0x75, 0x6c, 0x61, 0x6e, +0x3b, 0x70, 0xfb, 0x15f, 0x70, 0x65, 0x72, 0x3b, 0x74, 0xee, 0x72, 0x6d, 0x65, 0x68, 0x3b, 0x67, 0x65, 0x6c, 0x61, 0x77, +0xea, 0x6a, 0x3b, 0x72, 0x65, 0x7a, 0x62, 0x65, 0x72, 0x3b, 0x6b, 0x65, 0x77, 0xe7, 0xea, 0x72, 0x3b, 0x73, 0x65, 0x72, +0x6d, 0x61, 0x77, 0x65, 0x7a, 0x3b, 0x62, 0x65, 0x72, 0x66, 0x61, 0x6e, 0x62, 0x61, 0x72, 0x3b, 0x52, 0x3b, 0x52, 0x3b, +0x41, 0x3b, 0x41, 0x3b, 0x47, 0x3b, 0x50, 0x3b, 0x54, 0x3b, 0x47, 0x3b, 0x52, 0x3b, 0x4b, 0x3b, 0x53, 0x3b, 0x42, 0x3b, +0x72, 0xea, 0x62, 0x65, 0x6e, 0x64, 0x61, 0x6e, 0xea, 0x3b, 0x72, 0x65, 0x15f, 0x65, 0x6d, 0x69, 0x79, 0xea, 0x3b, 0x61, +0x64, 0x61, 0x72, 0xea, 0x3b, 0x61, 0x76, 0x72, 0xea, 0x6c, 0xea, 0x3b, 0x67, 0x75, 0x6c, 0x61, 0x6e, 0xea, 0x3b, 0x70, +0xfb, 0x15f, 0x70, 0x65, 0x72, 0xea, 0x3b, 0x74, 0xee, 0x72, 0x6d, 0x65, 0x68, 0xea, 0x3b, 0x67, 0x65, 0x6c, 0x61, 0x77, +0xea, 0x6a, 0xea, 0x3b, 0x72, 0x65, 0x7a, 0x62, 0x65, 0x72, 0xea, 0x3b, 0x6b, 0x65, 0x77, 0xe7, 0xea, 0x72, 0xea, 0x3b, +0x73, 0x65, 0x72, 0x6d, 0x61, 0x77, 0x65, 0x7a, 0xea, 0x3b, 0x62, 0x65, 0x72, 0x66, 0x61, 0x6e, 0x62, 0x61, 0x72, 0xea, +0x3b, 0x4d, 0x75, 0x74, 0x2e, 0x3b, 0x47, 0x61, 0x73, 0x2e, 0x3b, 0x57, 0x65, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x74, 0x2e, +0x3b, 0x47, 0x69, 0x63, 0x2e, 0x3b, 0x4b, 0x61, 0x6d, 0x2e, 0x3b, 0x4e, 0x79, 0x61, 0x2e, 0x3b, 0x4b, 0x61, 0x6e, 0x2e, +0x3b, 0x4e, 0x7a, 0x65, 0x2e, 0x3b, 0x55, 0x6b, 0x77, 0x2e, 0x3b, 0x55, 0x67, 0x75, 0x2e, 0x3b, 0x55, 0x6b, 0x75, 0x2e, +0x3b, 0x4e, 0x7a, 0x65, 0x72, 0x6f, 0x3b, 0x52, 0x75, 0x68, 0x75, 0x68, 0x75, 0x6d, 0x61, 0x3b, 0x4e, 0x74, 0x77, 0x61, +0x72, 0x61, 0x6e, 0x74, 0x65, 0x3b, 0x4e, 0x64, 0x61, 0x6d, 0x75, 0x6b, 0x69, 0x7a, 0x61, 0x3b, 0x52, 0x75, 0x73, 0x61, +0x6d, 0x61, 0x3b, 0x52, 0x75, 0x68, 0x65, 0x73, 0x68, 0x69, 0x3b, 0x4d, 0x75, 0x6b, 0x61, 0x6b, 0x61, 0x72, 0x6f, 0x3b, +0x4e, 0x79, 0x61, 0x6e, 0x64, 0x61, 0x67, 0x61, 0x72, 0x6f, 0x3b, 0x4e, 0x79, 0x61, 0x6b, 0x61, 0x6e, 0x67, 0x61, 0x3b, +0x47, 0x69, 0x74, 0x75, 0x67, 0x75, 0x74, 0x75, 0x3b, 0x4d, 0x75, 0x6e, 0x79, 0x6f, 0x6e, 0x79, 0x6f, 0x3b, 0x4b, 0x69, +0x67, 0x61, 0x72, 0x61, 0x6d, 0x61, 0x3b, 0xea1, 0x2e, 0xe81, 0x2e, 0x3b, 0xe81, 0x2e, 0xe9e, 0x2e, 0x3b, 0xea1, 0x2e, 0xe99, +0x2e, 0x3b, 0xea1, 0x2e, 0xeaa, 0x2e, 0x3b, 0xe9e, 0x2e, 0xe9e, 0x2e, 0x3b, 0xea1, 0xeb4, 0x2e, 0xe96, 0x2e, 0x3b, 0xe81, 0x2e, +0xea5, 0x2e, 0x3b, 0xeaa, 0x2e, 0xeab, 0x2e, 0x3b, 0xe81, 0x2e, 0xe8d, 0x2e, 0x3b, 0xe95, 0x2e, 0xea5, 0x2e, 0x3b, 0xe9e, 0x2e, +0xe88, 0x2e, 0x3b, 0xe97, 0x2e, 0xea7, 0x2e, 0x3b, 0xea1, 0xeb1, 0xe87, 0xe81, 0xead, 0xe99, 0x3b, 0xe81, 0xeb8, 0xea1, 0xe9e, 0xeb2, +0x3b, 0xea1, 0xeb5, 0xe99, 0xeb2, 0x3b, 0xec0, 0xea1, 0xeaa, 0xeb2, 0x3b, 0xe9e, 0xeb6, 0xe94, 0xeaa, 0xeb0, 0xe9e, 0xeb2, 0x3b, 0xea1, +0xeb4, 0xe96, 0xeb8, 0xe99, 0xeb2, 0x3b, 0xe81, 0xecd, 0xea5, 0xeb0, 0xe81, 0xebb, 0xe94, 0x3b, 0xeaa, 0xeb4, 0xe87, 0xeab, 0xeb2, 0x3b, +0xe81, 0xeb1, 0xe99, 0xe8d, 0xeb2, 0x3b, 0xe95, 0xeb8, 0xea5, 0xeb2, 0x3b, 0xe9e, 0xeb0, 0xe88, 0xeb4, 0xe81, 0x3b, 0xe97, 0xeb1, 0xe99, +0xea7, 0xeb2, 0x3b, 0x6a, 0x61, 0x6e, 0x76, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x73, +0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x6a, 0x73, 0x3b, 0x6a, 0x16b, 0x6e, 0x2e, 0x3b, 0x6a, 0x16b, 0x6c, +0x2e, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, +0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x76, 0x101, 0x72, 0x69, 0x73, 0x3b, 0x66, 0x65, 0x62, +0x72, 0x75, 0x101, 0x72, 0x69, 0x73, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x12b, 0x6c, 0x69, 0x73, +0x3b, 0x6d, 0x61, 0x69, 0x6a, 0x73, 0x3b, 0x6a, 0x16b, 0x6e, 0x69, 0x6a, 0x73, 0x3b, 0x6a, 0x16b, 0x6c, 0x69, 0x6a, 0x73, +0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x73, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x73, 0x3b, +0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x72, 0x69, 0x73, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x73, 0x3b, 0x64, +0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x73, 0x3b, 0x79, 0x61, 0x6e, 0x3b, 0x66, 0x62, 0x6c, 0x3b, 0x6d, 0x73, 0x69, +0x3b, 0x61, 0x70, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x79, 0x75, 0x6e, 0x3b, 0x79, 0x75, 0x6c, 0x3b, 0x61, 0x67, 0x74, +0x3b, 0x73, 0x74, 0x62, 0x3b, 0x254, 0x74, 0x62, 0x3b, 0x6e, 0x76, 0x62, 0x3b, 0x64, 0x73, 0x62, 0x3b, 0x73, 0xe1, 0x6e, +0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x79, 0x61, 0x6d, 0x62, 0x6f, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, +0x20, 0x6d, 0xed, 0x62, 0x61, 0x6c, 0xe9, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x73, +0xe1, 0x74, 0x6f, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x6e, 0x65, 0x69, 0x3b, 0x73, +0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x74, 0xe1, 0x6e, 0x6f, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, +0x20, 0x79, 0x61, 0x20, 0x6d, 0x6f, 0x74, 0xf3, 0x62, 0xe1, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, +0x6e, 0x73, 0x61, 0x6d, 0x62, 0x6f, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0x77, 0x61, 0x6d, +0x62, 0x65, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6c, 0x69, 0x62, 0x77, 0x61, 0x3b, 0x73, 0xe1, +0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x7a, 0xf3, 0x6d, 0x69, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, +0x20, 0x7a, 0xf3, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x254, 0x30c, 0x6b, 0x254, 0x301, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, +0xe1, 0x20, 0x79, 0x61, 0x20, 0x7a, 0xf3, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0xed, 0x62, 0x61, 0x6c, 0xe9, 0x3b, +0x79, 0x3b, 0x66, 0x3b, 0x6d, 0x3b, 0x61, 0x3b, 0x6d, 0x3b, 0x79, 0x3b, 0x79, 0x3b, 0x61, 0x3b, 0x73, 0x3b, 0x254, 0x3b, +0x6e, 0x3b, 0x64, 0x3b, 0x73, 0x61, 0x75, 0x73, 0x2e, 0x3b, 0x76, 0x61, 0x73, 0x2e, 0x3b, 0x6b, 0x6f, 0x76, 0x2e, 0x3b, +0x62, 0x61, 0x6c, 0x2e, 0x3b, 0x67, 0x65, 0x67, 0x2e, 0x3b, 0x62, 0x69, 0x72, 0x17e, 0x2e, 0x3b, 0x6c, 0x69, 0x65, 0x70, +0x2e, 0x3b, 0x72, 0x75, 0x67, 0x70, 0x2e, 0x3b, 0x72, 0x75, 0x67, 0x73, 0x2e, 0x3b, 0x73, 0x70, 0x61, 0x6c, 0x2e, 0x3b, +0x6c, 0x61, 0x70, 0x6b, 0x72, 0x2e, 0x3b, 0x67, 0x72, 0x75, 0x6f, 0x64, 0x2e, 0x3b, 0x73, 0x61, 0x75, 0x73, 0x69, 0x73, +0x3b, 0x76, 0x61, 0x73, 0x61, 0x72, 0x69, 0x73, 0x3b, 0x6b, 0x6f, 0x76, 0x61, 0x73, 0x3b, 0x62, 0x61, 0x6c, 0x61, 0x6e, +0x64, 0x69, 0x73, 0x3b, 0x67, 0x65, 0x67, 0x75, 0x17e, 0x117, 0x3b, 0x62, 0x69, 0x72, 0x17e, 0x65, 0x6c, 0x69, 0x73, 0x3b, +0x6c, 0x69, 0x65, 0x70, 0x61, 0x3b, 0x72, 0x75, 0x67, 0x70, 0x6a, 0x16b, 0x74, 0x69, 0x73, 0x3b, 0x72, 0x75, 0x67, 0x73, +0x117, 0x6a, 0x69, 0x73, 0x3b, 0x73, 0x70, 0x61, 0x6c, 0x69, 0x73, 0x3b, 0x6c, 0x61, 0x70, 0x6b, 0x72, 0x69, 0x74, 0x69, +0x73, 0x3b, 0x67, 0x72, 0x75, 0x6f, 0x64, 0x69, 0x73, 0x3b, 0x53, 0x3b, 0x56, 0x3b, 0x4b, 0x3b, 0x42, 0x3b, 0x47, 0x3b, +0x42, 0x3b, 0x4c, 0x3b, 0x52, 0x3b, 0x52, 0x3b, 0x53, 0x3b, 0x4c, 0x3b, 0x47, 0x3b, 0x73, 0x61, 0x75, 0x73, 0x69, 0x6f, +0x3b, 0x76, 0x61, 0x73, 0x61, 0x72, 0x69, 0x6f, 0x3b, 0x6b, 0x6f, 0x76, 0x6f, 0x3b, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x64, +0x17e, 0x69, 0x6f, 0x3b, 0x67, 0x65, 0x67, 0x75, 0x17e, 0x117, 0x73, 0x3b, 0x62, 0x69, 0x72, 0x17e, 0x65, 0x6c, 0x69, 0x6f, +0x3b, 0x6c, 0x69, 0x65, 0x70, 0x6f, 0x73, 0x3b, 0x72, 0x75, 0x67, 0x70, 0x6a, 0x16b, 0x10d, 0x69, 0x6f, 0x3b, 0x72, 0x75, +0x67, 0x73, 0x117, 0x6a, 0x6f, 0x3b, 0x73, 0x70, 0x61, 0x6c, 0x69, 0x6f, 0x3b, 0x6c, 0x61, 0x70, 0x6b, 0x72, 0x69, 0x10d, +0x69, 0x6f, 0x3b, 0x67, 0x72, 0x75, 0x6f, 0x64, 0x17e, 0x69, 0x6f, 0x3b, 0x458, 0x430, 0x43d, 0x2e, 0x3b, 0x444, 0x435, 0x432, +0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x2e, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x2e, +0x3b, 0x458, 0x443, 0x43b, 0x2e, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, +0x2e, 0x3b, 0x43d, 0x43e, 0x435, 0x43c, 0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x2e, 0x3b, 0x458, 0x430, 0x43d, 0x443, 0x430, 0x440, 0x438, +0x3b, 0x444, 0x435, 0x432, 0x440, 0x443, 0x430, 0x440, 0x438, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b, +0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x438, 0x3b, 0x458, 0x443, 0x43b, 0x438, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, +0x442, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x435, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x43c, 0x432, 0x440, 0x438, +0x3b, 0x43d, 0x43e, 0x435, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x434, 0x435, 0x43a, 0x435, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x458, 0x3b, +0x444, 0x3b, 0x43c, 0x3b, 0x430, 0x3b, 0x43c, 0x3b, 0x458, 0x3b, 0x458, 0x3b, 0x430, 0x3b, 0x441, 0x3b, 0x43e, 0x3b, 0x43d, 0x3b, +0x434, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, +0x79, 0x3b, 0x4a, 0x6f, 0x6e, 0x3b, 0x4a, 0x6f, 0x6c, 0x3b, 0x41, 0x6f, 0x67, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, +0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x6f, 0x61, 0x72, 0x79, 0x3b, 0x46, 0x65, +0x62, 0x72, 0x6f, 0x61, 0x72, 0x79, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x73, 0x61, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x79, +0x3b, 0x4d, 0x65, 0x79, 0x3b, 0x4a, 0x6f, 0x6e, 0x61, 0x3b, 0x4a, 0x6f, 0x6c, 0x61, 0x79, 0x3b, 0x41, 0x6f, 0x67, 0x6f, +0x73, 0x69, 0x74, 0x72, 0x61, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x61, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, +0x62, 0x72, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x61, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x44, 0x65, 0x73, 0x61, 0x6d, 0x62, 0x72, +0x61, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x63, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, +0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x4f, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, +0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, +0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x69, +0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x4f, 0x67, 0x6f, 0x73, 0x3b, 0x53, 0x65, 0x70, 0x74, +0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, +0x65, 0x72, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, +0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x4f, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0xd1c, 0xd28, 0xd41, 0x3b, +0xd2b, 0xd46, 0xd2c, 0xd4d, 0xd30, 0xd41, 0x3b, 0xd2e, 0xd3e, 0xd7c, 0x3b, 0xd0f, 0xd2a, 0xd4d, 0xd30, 0xd3f, 0x3b, 0xd2e, 0xd47, 0xd2f, +0xd4d, 0x3b, 0xd1c, 0xd42, 0xd7a, 0x3b, 0xd1c, 0xd42, 0xd32, 0xd48, 0x3b, 0xd13, 0xd17, 0x3b, 0xd38, 0xd46, 0xd2a, 0xd4d, 0xd31, 0xd4d, +0xd31, 0xd02, 0x3b, 0xd12, 0xd15, 0xd4d, 0xd1f, 0xd4b, 0x3b, 0xd28, 0xd35, 0xd02, 0x3b, 0xd21, 0xd3f, 0xd38, 0xd02, 0x3b, 0xd1c, 0xd28, +0xd41, 0xd35, 0xd30, 0xd3f, 0x3b, 0xd2b, 0xd46, 0xd2c, 0xd4d, 0xd30, 0xd41, 0xd35, 0xd30, 0xd3f, 0x3b, 0xd2e, 0xd3e, 0xd7c, 0xd1a, 0xd4d, +0xd1a, 0xd4d, 0x3b, 0xd0f, 0xd2a, 0xd4d, 0xd30, 0xd3f, 0xd7d, 0x3b, 0xd2e, 0xd47, 0xd2f, 0xd4d, 0x3b, 0xd1c, 0xd42, 0xd7a, 0x3b, 0xd1c, +0xd42, 0xd32, 0xd48, 0x3b, 0xd13, 0xd17, 0xd38, 0xd4d, 0xd31, 0xd4d, 0xd31, 0xd4d, 0x3b, 0xd38, 0xd46, 0xd2a, 0xd4d, 0xd31, 0xd4d, 0xd31, +0xd02, 0xd2c, 0xd7c, 0x3b, 0xd12, 0xd15, 0xd4d, 0x200c, 0xd1f, 0xd4b, 0xd2c, 0xd7c, 0x3b, 0xd28, 0xd35, 0xd02, 0xd2c, 0xd7c, 0x3b, 0xd21, +0xd3f, 0xd38, 0xd02, 0xd2c, 0xd7c, 0x3b, 0xd1c, 0x3b, 0xd2b, 0xd46, 0x3b, 0xd2e, 0xd3e, 0x3b, 0xd0f, 0x3b, 0xd2e, 0xd46, 0x3b, 0xd1c, +0xd42, 0xd7a, 0x3b, 0xd1c, 0xd42, 0x3b, 0xd13, 0x3b, 0xd38, 0xd46, 0x3b, 0xd12, 0x3b, 0xd28, 0x3b, 0xd21, 0xd3f, 0x3b, 0x4a, 0x61, +0x6e, 0x3b, 0x46, 0x72, 0x61, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x6a, 0x3b, 0x120, 0x75, +0x6e, 0x3b, 0x4c, 0x75, 0x6c, 0x3b, 0x41, 0x77, 0x77, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x74, 0x74, 0x3b, 0x4e, 0x6f, +0x76, 0x3b, 0x44, 0x69, 0x10b, 0x3b, 0x4a, 0x61, 0x6e, 0x6e, 0x61, 0x72, 0x3b, 0x46, 0x72, 0x61, 0x72, 0x3b, 0x4d, 0x61, +0x72, 0x7a, 0x75, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x6a, 0x6a, 0x75, 0x3b, 0x120, 0x75, 0x6e, 0x6a, +0x75, 0x3b, 0x4c, 0x75, 0x6c, 0x6a, 0x75, 0x3b, 0x41, 0x77, 0x77, 0x69, 0x73, 0x73, 0x75, 0x3b, 0x53, 0x65, 0x74, 0x74, +0x65, 0x6d, 0x62, 0x72, 0x75, 0x3b, 0x4f, 0x74, 0x74, 0x75, 0x62, 0x72, 0x75, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, +0x72, 0x75, 0x3b, 0x44, 0x69, 0x10b, 0x65, 0x6d, 0x62, 0x72, 0x75, 0x3b, 0x4a, 0x6e, 0x3b, 0x46, 0x72, 0x3b, 0x4d, 0x7a, +0x3b, 0x41, 0x70, 0x3b, 0x4d, 0x6a, 0x3b, 0x120, 0x6e, 0x3b, 0x4c, 0x6a, 0x3b, 0x41, 0x77, 0x3b, 0x53, 0x74, 0x3b, 0x4f, +0x62, 0x3b, 0x4e, 0x76, 0x3b, 0x44, 0x10b, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x120, 0x3b, +0x4c, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4b, 0x6f, 0x68, 0x69, 0x3b, 0x48, 0x75, 0x69, +0x3b, 0x50, 0x6f, 0x75, 0x3b, 0x50, 0x61, 0x65, 0x3b, 0x48, 0x61, 0x72, 0x61, 0x3b, 0x50, 0x69, 0x70, 0x69, 0x3b, 0x48, +0x14d, 0x6e, 0x67, 0x6f, 0x3b, 0x48, 0x65, 0x72, 0x65, 0x3b, 0x4d, 0x61, 0x68, 0x75, 0x3b, 0x4e, 0x75, 0x6b, 0x75, 0x3b, +0x52, 0x61, 0x6e, 0x67, 0x69, 0x3b, 0x48, 0x61, 0x6b, 0x69, 0x3b, 0x4b, 0x6f, 0x68, 0x69, 0x74, 0x101, 0x74, 0x65, 0x61, +0x3b, 0x48, 0x75, 0x69, 0x74, 0x61, 0x6e, 0x67, 0x75, 0x72, 0x75, 0x3b, 0x50, 0x6f, 0x75, 0x74, 0x16b, 0x74, 0x65, 0x72, +0x61, 0x6e, 0x67, 0x69, 0x3b, 0x50, 0x61, 0x65, 0x6e, 0x67, 0x61, 0x77, 0x68, 0x101, 0x77, 0x68, 0x101, 0x3b, 0x48, 0x61, +0x72, 0x61, 0x74, 0x75, 0x61, 0x3b, 0x50, 0x69, 0x70, 0x69, 0x72, 0x69, 0x3b, 0x48, 0x14d, 0x6e, 0x67, 0x6f, 0x6e, 0x67, +0x6f, 0x69, 0x3b, 0x48, 0x65, 0x72, 0x65, 0x74, 0x75, 0x72, 0x69, 0x6b, 0x14d, 0x6b, 0x101, 0x3b, 0x4d, 0x61, 0x68, 0x75, +0x72, 0x75, 0x3b, 0x57, 0x68, 0x69, 0x72, 0x69, 0x6e, 0x67, 0x61, 0x2d, 0x101, 0x2d, 0x6e, 0x75, 0x6b, 0x75, 0x3b, 0x57, +0x68, 0x69, 0x72, 0x69, 0x6e, 0x67, 0x61, 0x2d, 0x101, 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x69, 0x3b, 0x48, 0x61, 0x6b, 0x69, +0x68, 0x65, 0x61, 0x3b, 0x4b, 0x3b, 0x48, 0x3b, 0x50, 0x3b, 0x50, 0x3b, 0x48, 0x3b, 0x50, 0x3b, 0x48, 0x3b, 0x48, 0x3b, +0x4d, 0x3b, 0x4e, 0x3b, 0x52, 0x3b, 0x48, 0x3b, 0x91c, 0x93e, 0x928, 0x947, 0x3b, 0x92b, 0x947, 0x92c, 0x94d, 0x930, 0x941, 0x3b, +0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x90f, 0x92a, 0x94d, 0x930, 0x93f, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x942, 0x928, 0x3b, 0x91c, +0x941, 0x932, 0x948, 0x3b, 0x911, 0x917, 0x3b, 0x938, 0x92a, 0x94d, 0x91f, 0x947, 0x902, 0x3b, 0x911, 0x915, 0x94d, 0x91f, 0x94b, 0x3b, +0x928, 0x94b, 0x935, 0x94d, 0x939, 0x947, 0x902, 0x3b, 0x921, 0x93f, 0x938, 0x947, 0x902, 0x3b, 0x91c, 0x93e, 0x928, 0x947, 0x935, 0x93e, +0x930, 0x940, 0x3b, 0x92b, 0x947, 0x92c, 0x94d, 0x930, 0x941, 0x935, 0x93e, 0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, +0x90f, 0x92a, 0x94d, 0x930, 0x93f, 0x932, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x942, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x948, 0x3b, 0x911, +0x917, 0x938, 0x94d, 0x91f, 0x3b, 0x938, 0x92a, 0x94d, 0x91f, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x911, 0x915, 0x94d, 0x91f, 0x94b, 0x92c, +0x930, 0x3b, 0x928, 0x94b, 0x935, 0x94d, 0x939, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x921, 0x93f, 0x938, 0x947, 0x902, 0x92c, 0x930, 0x3b, +0x91c, 0x93e, 0x3b, 0x92b, 0x947, 0x3b, 0x92e, 0x93e, 0x3b, 0x90f, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x942, 0x3b, 0x91c, 0x941, 0x3b, +0x911, 0x3b, 0x938, 0x3b, 0x911, 0x3b, 0x928, 0x94b, 0x3b, 0x921, 0x93f, 0x3b, 0x31, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, +0x32, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x33, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x34, 0x2d, 0x440, 0x20, +0x441, 0x430, 0x440, 0x3b, 0x35, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x36, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, +0x37, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x38, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x39, 0x2d, 0x440, 0x20, +0x441, 0x430, 0x440, 0x3b, 0x31, 0x30, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x31, 0x31, 0x2d, 0x440, 0x20, 0x441, 0x430, +0x440, 0x3b, 0x31, 0x32, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x41d, 0x44d, 0x433, 0x434, 0x4af, 0x433, 0x44d, 0x44d, 0x440, +0x20, 0x441, 0x430, 0x440, 0x3b, 0x425, 0x43e, 0x451, 0x440, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, +0x413, 0x443, 0x440, 0x430, 0x432, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x414, 0x4e9, 0x440, 0x4e9, +0x432, 0x434, 0x4af, 0x433, 0x44d, 0x44d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x422, 0x430, 0x432, 0x434, 0x443, 0x433, 0x430, 0x430, +0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x417, 0x443, 0x440, 0x433, 0x430, 0x430, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, +0x430, 0x440, 0x3b, 0x414, 0x43e, 0x43b, 0x43e, 0x43e, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x41d, +0x430, 0x439, 0x43c, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x415, 0x441, 0x434, 0x4af, 0x433, 0x44d, +0x44d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x410, 0x440, 0x430, 0x432, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, +0x440, 0x3b, 0x410, 0x440, 0x432, 0x430, 0x43d, 0x20, 0x43d, 0x44d, 0x433, 0x434, 0x4af, 0x433, 0x44d, 0x44d, 0x440, 0x20, 0x441, 0x430, +0x440, 0x3b, 0x410, 0x440, 0x432, 0x430, 0x43d, 0x20, 0x445, 0x43e, 0x451, 0x440, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, +0x430, 0x440, 0x3b, 0x49, 0x3b, 0x49, 0x49, 0x3b, 0x49, 0x49, 0x49, 0x3b, 0x49, 0x56, 0x3b, 0x56, 0x3b, 0x56, 0x49, 0x3b, +0x56, 0x49, 0x49, 0x3b, 0x56, 0x49, 0x49, 0x49, 0x3b, 0x49, 0x58, 0x3b, 0x58, 0x3b, 0x58, 0x49, 0x3b, 0x58, 0x49, 0x49, +0x3b, 0x43d, 0x44d, 0x433, 0x434, 0x4af, 0x433, 0x44d, 0x44d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x445, 0x43e, 0x451, 0x440, 0x434, +0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x433, 0x443, 0x440, 0x430, 0x432, 0x434, 0x443, 0x433, 0x430, 0x430, +0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x434, 0x4e9, 0x440, 0x4e9, 0x432, 0x434, 0x4af, 0x433, 0x44d, 0x44d, 0x440, 0x20, 0x441, 0x430, +0x440, 0x3b, 0x442, 0x430, 0x432, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x437, 0x443, 0x440, 0x433, +0x430, 0x430, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x434, 0x43e, 0x43b, 0x43e, 0x43e, 0x434, 0x443, +0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x43d, 0x430, 0x439, 0x43c, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, +0x441, 0x430, 0x440, 0x3b, 0x435, 0x441, 0x434, 0x4af, 0x433, 0x44d, 0x44d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x430, 0x440, 0x430, +0x432, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x430, 0x440, 0x432, 0x430, 0x43d, 0x20, 0x43d, 0x44d, +0x433, 0x434, 0x4af, 0x433, 0x44d, 0x44d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x430, 0x440, 0x432, 0x430, 0x43d, 0x20, 0x445, 0x43e, +0x451, 0x440, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x91c, 0x928, 0x935, 0x930, 0x940, 0x3b, 0x92b, +0x947, 0x92c, 0x94d, 0x930, 0x941, 0x905, 0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x905, 0x92a, 0x94d, 0x930, 0x93f, +0x932, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x941, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x93e, 0x908, 0x3b, 0x905, 0x917, 0x938, 0x94d, 0x91f, +0x3b, 0x938, 0x947, 0x92a, 0x94d, 0x91f, 0x947, 0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x905, 0x915, 0x94d, 0x91f, 0x94b, 0x92c, 0x930, 0x3b, +0x928, 0x94b, 0x92d, 0x947, 0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x921, 0x93f, 0x938, 0x947, 0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x91c, 0x928, +0x3b, 0x92b, 0x947, 0x947, 0x92c, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x905, 0x92a, 0x94d, 0x930, 0x3b, 0x92e, 0x947, 0x3b, +0x91c, 0x941, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x3b, 0x905, 0x917, 0x3b, 0x938, 0x947, 0x92a, 0x3b, 0x905, 0x915, 0x94d, 0x91f, 0x94b, +0x3b, 0x928, 0x94b, 0x92d, 0x947, 0x3b, 0x921, 0x93f, 0x938, 0x947, 0x3b, 0x91c, 0x928, 0x3b, 0x92b, 0x947, 0x92c, 0x3b, 0x92e, 0x93e, +0x930, 0x94d, 0x91a, 0x3b, 0x905, 0x92a, 0x94d, 0x930, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x941, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x3b, +0x905, 0x917, 0x3b, 0x938, 0x947, 0x92a, 0x3b, 0x905, 0x915, 0x94d, 0x91f, 0x94b, 0x3b, 0x928, 0x94b, 0x92d, 0x947, 0x3b, 0x921, 0x93f, +0x938, 0x947, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, +0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, +0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, +0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x73, +0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0xb1c, 0xb3e, 0xb28, 0xb41, 0xb06, 0xb30, 0xb40, 0x3b, 0xb2b, 0xb47, 0xb2c, 0xb43, 0xb06, 0xb30, +0xb40, 0x3b, 0xb2e, 0xb3e, 0xb30, 0xb4d, 0xb1a, 0xb4d, 0xb1a, 0x3b, 0xb05, 0xb2a, 0xb4d, 0xb30, 0xb47, 0xb32, 0x3b, 0xb2e, 0xb07, 0x3b, +0xb1c, 0xb41, 0xb28, 0x3b, 0xb1c, 0xb41, 0xb32, 0xb3e, 0xb07, 0x3b, 0xb05, 0xb17, 0xb37, 0xb4d, 0xb1f, 0x3b, 0xb38, 0xb47, 0xb2a, 0xb4d, +0xb1f, 0xb47, 0xb2e, 0xb4d, 0xb2c, 0xb30, 0x3b, 0xb05, 0xb15, 0xb4d, 0xb1f, 0xb4b, 0xb2c, 0xb30, 0x3b, 0xb28, 0xb2d, 0xb47, 0xb2e, 0xb4d, +0xb2c, 0xb30, 0x3b, 0xb21, 0xb3f, 0xb38, 0xb47, 0xb2e, 0xb4d, 0xb2c, 0xb30, 0x3b, 0xb1c, 0xb3e, 0x3b, 0xb2b, 0xb47, 0x3b, 0xb2e, 0xb3e, +0x3b, 0xb05, 0x3b, 0xb2e, 0xb07, 0x3b, 0xb1c, 0xb41, 0x3b, 0xb1c, 0xb41, 0x3b, 0xb05, 0x3b, 0xb38, 0xb47, 0x3b, 0xb05, 0x3b, 0xb28, +0x3b, 0xb21, 0xb3f, 0x3b, 0x62c, 0x646, 0x648, 0x631, 0x64a, 0x3b, 0x641, 0x628, 0x631, 0x648, 0x631, 0x64a, 0x3b, 0x645, 0x627, 0x631, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x6cd, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648, 0x644, 0x627, 0x6cc, -0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x6d0, 0x67e, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648, 0x628, 0x631, -0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x62c, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x627, -0x3b, 0x645, 0x3b, 0x62c, 0x3b, 0x62c, 0x3b, 0x627, 0x3b, 0x633, 0x3b, 0x627, 0x3b, 0x646, 0x3b, 0x62f, 0x3b, 0x698, 0x627, 0x646, -0x648, 0x6cc, 0x647, 0x3b, 0x641, 0x648, 0x631, 0x6cc, 0x647, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x622, 0x648, 0x631, 0x6cc, 0x644, -0x3b, 0x645, 0x647, 0x3b, 0x698, 0x648, 0x626, 0x646, 0x3b, 0x698, 0x648, 0x626, 0x6cc, 0x647, 0x3b, 0x627, 0x648, 0x62a, 0x3b, 0x633, -0x67e, 0x62a, 0x627, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x627, 0x645, 0x628, 0x631, 0x3b, -0x62f, 0x633, 0x627, 0x645, 0x628, 0x631, 0x3b, 0x698, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x622, 0x3b, 0x645, 0x3b, 0x698, 0x3b, 0x698, -0x3b, 0x627, 0x3b, 0x633, 0x3b, 0x627, 0x3b, 0x646, 0x3b, 0x62f, 0x3b, 0x698, 0x627, 0x646, 0x648, 0x6cc, 0x647, 0x654, 0x3b, 0x641, -0x648, 0x631, 0x6cc, 0x647, 0x654, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x622, 0x648, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x647, 0x654, -0x3b, 0x698, 0x648, 0x626, 0x646, 0x3b, 0x698, 0x648, 0x626, 0x6cc, 0x647, 0x654, 0x3b, 0x627, 0x648, 0x62a, 0x3b, 0x633, 0x67e, 0x62a, -0x627, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x627, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, -0x627, 0x645, 0x628, 0x631, 0x3b, 0x62c, 0x646, 0x648, 0x631, 0x6cc, 0x3b, 0x641, 0x628, 0x631, 0x648, 0x631, 0x6cc, 0x3b, 0x645, 0x627, -0x631, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x6cc, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648, 0x644, 0x627, -0x6cc, 0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x67e, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648, 0x628, 0x631, -0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x62c, 0x646, 0x648, 0x3b, 0x641, 0x628, 0x631, -0x648, 0x631, 0x6cc, 0x3b, 0x645, 0x627, 0x631, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x6cc, 0x3b, 0x62c, 0x648, -0x646, 0x3b, 0x62c, 0x648, 0x644, 0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x67e, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, -0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x3b, 0x73, 0x74, 0x79, 0x3b, 0x6c, -0x75, 0x74, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6b, 0x77, 0x69, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x63, 0x7a, 0x65, 0x3b, 0x6c, -0x69, 0x70, 0x3b, 0x73, 0x69, 0x65, 0x3b, 0x77, 0x72, 0x7a, 0x3b, 0x70, 0x61, 0x17a, 0x3b, 0x6c, 0x69, 0x73, 0x3b, 0x67, -0x72, 0x75, 0x3b, 0x73, 0x74, 0x79, 0x63, 0x7a, 0x65, 0x144, 0x3b, 0x6c, 0x75, 0x74, 0x79, 0x3b, 0x6d, 0x61, 0x72, 0x7a, -0x65, 0x63, 0x3b, 0x6b, 0x77, 0x69, 0x65, 0x63, 0x69, 0x65, 0x144, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x63, 0x7a, 0x65, 0x72, -0x77, 0x69, 0x65, 0x63, 0x3b, 0x6c, 0x69, 0x70, 0x69, 0x65, 0x63, 0x3b, 0x73, 0x69, 0x65, 0x72, 0x70, 0x69, 0x65, 0x144, -0x3b, 0x77, 0x72, 0x7a, 0x65, 0x73, 0x69, 0x65, 0x144, 0x3b, 0x70, 0x61, 0x17a, 0x64, 0x7a, 0x69, 0x65, 0x72, 0x6e, 0x69, -0x6b, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x3b, 0x67, 0x72, 0x75, 0x64, 0x7a, 0x69, 0x65, 0x144, 0x3b, -0x53, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x43, 0x3b, 0x4c, 0x3b, 0x53, 0x3b, 0x57, 0x3b, 0x50, 0x3b, -0x4c, 0x3b, 0x47, 0x3b, 0x73, 0x74, 0x79, 0x63, 0x7a, 0x6e, 0x69, 0x61, 0x3b, 0x6c, 0x75, 0x74, 0x65, 0x67, 0x6f, 0x3b, -0x6d, 0x61, 0x72, 0x63, 0x61, 0x3b, 0x6b, 0x77, 0x69, 0x65, 0x74, 0x6e, 0x69, 0x61, 0x3b, 0x6d, 0x61, 0x6a, 0x61, 0x3b, -0x63, 0x7a, 0x65, 0x72, 0x77, 0x63, 0x61, 0x3b, 0x6c, 0x69, 0x70, 0x63, 0x61, 0x3b, 0x73, 0x69, 0x65, 0x72, 0x70, 0x6e, -0x69, 0x61, 0x3b, 0x77, 0x72, 0x7a, 0x65, 0x15b, 0x6e, 0x69, 0x61, 0x3b, 0x70, 0x61, 0x17a, 0x64, 0x7a, 0x69, 0x65, 0x72, -0x6e, 0x69, 0x6b, 0x61, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x61, 0x3b, 0x67, 0x72, 0x75, 0x64, 0x6e, -0x69, 0x61, 0x3b, 0x73, 0x3b, 0x6c, 0x3b, 0x6d, 0x3b, 0x6b, 0x3b, 0x6d, 0x3b, 0x63, 0x3b, 0x6c, 0x3b, 0x73, 0x3b, 0x77, -0x3b, 0x70, 0x3b, 0x6c, 0x3b, 0x67, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x76, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, -0x62, 0x72, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x67, 0x6f, 0x3b, 0x73, -0x65, 0x74, 0x3b, 0x6f, 0x75, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x7a, 0x3b, 0x6a, 0x61, 0x6e, 0x65, 0x69, -0x72, 0x6f, 0x3b, 0x66, 0x65, 0x76, 0x65, 0x72, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0xe7, 0x6f, 0x3b, 0x61, -0x62, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x6f, 0x3b, 0x6a, 0x75, 0x6e, 0x68, 0x6f, 0x3b, 0x6a, 0x75, 0x6c, 0x68, -0x6f, 0x3b, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x6f, 0x75, -0x74, 0x75, 0x62, 0x72, 0x6f, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x64, 0x65, 0x7a, 0x65, 0x6d, -0x62, 0x72, 0x6f, 0x3b, 0xa1c, 0xa28, 0x3b, 0xa2b, 0xa3c, 0xa30, 0x3b, 0xa2e, 0xa3e, 0xa30, 0xa1a, 0x3b, 0xa05, 0xa2a, 0xa4d, 0xa30, -0xa48, 0x3b, 0xa2e, 0xa08, 0x3b, 0xa1c, 0xa42, 0xa28, 0x3b, 0xa1c, 0xa41, 0xa32, 0xa3e, 0x3b, 0xa05, 0xa17, 0x3b, 0xa38, 0xa24, 0xa70, -0x3b, 0xa05, 0xa15, 0xa24, 0xa42, 0x3b, 0xa28, 0xa35, 0xa70, 0x3b, 0xa26, 0xa38, 0xa70, 0x3b, 0xa1c, 0xa28, 0xa35, 0xa30, 0xa40, 0x3b, -0xa2b, 0xa3c, 0xa30, 0xa35, 0xa30, 0xa40, 0x3b, 0xa2e, 0xa3e, 0xa30, 0xa1a, 0x3b, 0xa05, 0xa2a, 0xa4d, 0xa30, 0xa48, 0xa32, 0x3b, 0xa2e, -0xa08, 0x3b, 0xa1c, 0xa42, 0xa28, 0x3b, 0xa1c, 0xa41, 0xa32, 0xa3e, 0xa08, 0x3b, 0xa05, 0xa17, 0xa38, 0xa24, 0x3b, 0xa38, 0xa24, 0xa70, -0xa2c, 0xa30, 0x3b, 0xa05, 0xa15, 0xa24, 0xa42, 0xa2c, 0xa30, 0x3b, 0xa28, 0xa35, 0xa70, 0xa2c, 0xa30, 0x3b, 0xa26, 0xa38, 0xa70, 0xa2c, -0xa30, 0x3b, 0xa1c, 0x3b, 0xa2b, 0xa3c, 0x3b, 0xa2e, 0xa3e, 0x3b, 0xa05, 0x3b, 0xa2e, 0x3b, 0xa1c, 0xa42, 0x3b, 0xa1c, 0xa41, 0x3b, -0xa05, 0x3b, 0xa38, 0x3b, 0xa05, 0x3b, 0xa28, 0x3b, 0xa26, 0x3b, 0x62c, 0x646, 0x648, 0x631, 0x6cc, 0x3b, 0x641, 0x631, 0x648, 0x631, -0x6cc, 0x3b, 0x645, 0x627, 0x631, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x626, 0x3b, 0x62c, 0x648, 0x646, 0x3b, -0x62c, 0x648, 0x644, 0x627, 0x626, 0x6cc, 0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, -0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x45, 0x6e, 0x65, -0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x4a, 0x75, 0x6e, -0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x63, 0x74, 0x3b, 0x4e, 0x6f, 0x76, -0x3b, 0x44, 0x69, 0x63, 0x3b, 0x45, 0x6e, 0x65, 0x72, 0x6f, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x65, 0x72, 0x6f, 0x3b, 0x4d, -0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x79, 0x6f, 0x3b, 0x4a, 0x75, 0x6e, 0x69, -0x6f, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x6f, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x69, 0x65, -0x6d, 0x62, 0x72, 0x65, 0x3b, 0x4f, 0x63, 0x74, 0x75, 0x62, 0x72, 0x65, 0x3b, 0x4e, 0x6f, 0x76, 0x69, 0x65, 0x6d, 0x62, -0x72, 0x65, 0x3b, 0x44, 0x69, 0x63, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x73, 0x63, 0x68, 0x61, 0x6e, 0x2e, 0x3b, -0x66, 0x61, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x74, 0x67, -0x3b, 0x7a, 0x65, 0x72, 0x63, 0x6c, 0x2e, 0x3b, 0x66, 0x61, 0x6e, 0x2e, 0x3b, 0x61, 0x76, 0x75, 0x73, 0x74, 0x3b, 0x73, -0x65, 0x74, 0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, -0x73, 0x63, 0x68, 0x61, 0x6e, 0x65, 0x72, 0x3b, 0x66, 0x61, 0x76, 0x72, 0x65, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, -0x61, 0x76, 0x72, 0x69, 0x67, 0x6c, 0x3b, 0x6d, 0x61, 0x74, 0x67, 0x3b, 0x7a, 0x65, 0x72, 0x63, 0x6c, 0x61, 0x64, 0x75, -0x72, 0x3b, 0x66, 0x61, 0x6e, 0x61, 0x64, 0x75, 0x72, 0x3b, 0x61, 0x76, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x74, 0x74, -0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x63, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, -0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x53, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, -0x4d, 0x3b, 0x5a, 0x3b, 0x46, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x69, 0x61, 0x6e, 0x2e, -0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b, -0x69, 0x75, 0x6e, 0x2e, 0x3b, 0x69, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x2e, -0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x69, 0x61, 0x6e, 0x75, -0x61, 0x72, 0x69, 0x65, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x65, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x69, -0x65, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x69, 0x65, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x69, 0x75, 0x6e, 0x69, 0x65, 0x3b, -0x69, 0x75, 0x6c, 0x69, 0x65, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, -0x72, 0x69, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x6f, 0x6d, 0x62, 0x72, 0x69, 0x65, 0x3b, 0x6e, 0x6f, 0x69, 0x65, 0x6d, 0x62, -0x72, 0x69, 0x65, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x65, 0x3b, 0x49, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, -0x41, 0x3b, 0x4d, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x44f, 0x43d, -0x432, 0x2e, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, -0x430, 0x439, 0x3b, 0x438, 0x44e, 0x43d, 0x44c, 0x3b, 0x438, 0x44e, 0x43b, 0x44c, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, -0x43d, 0x442, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x2e, 0x3b, -0x44f, 0x43d, 0x432, 0x2e, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x2e, 0x3b, 0x430, 0x43f, 0x440, 0x2e, -0x3b, 0x43c, 0x430, 0x44f, 0x3b, 0x438, 0x44e, 0x43d, 0x2e, 0x3b, 0x438, 0x44e, 0x43b, 0x2e, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, -0x441, 0x435, 0x43d, 0x442, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x2e, 0x3b, 0x434, 0x435, 0x43a, -0x2e, 0x3b, 0x44f, 0x43d, 0x432, 0x430, 0x440, 0x44f, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x44f, 0x3b, 0x43c, 0x430, 0x440, -0x442, 0x430, 0x3b, 0x430, 0x43f, 0x440, 0x435, 0x43b, 0x44f, 0x3b, 0x43c, 0x430, 0x44f, 0x3b, 0x438, 0x44e, 0x43d, 0x44f, 0x3b, 0x438, -0x44e, 0x43b, 0x44f, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x430, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x44f, -0x3b, 0x43e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44f, 0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x440, 0x44f, 0x3b, 0x434, 0x435, 0x43a, 0x430, -0x431, 0x440, 0x44f, 0x3b, 0x4e, 0x79, 0x65, 0x3b, 0x46, 0x75, 0x6c, 0x3b, 0x4d, 0x62, 0xe4, 0x3b, 0x4e, 0x67, 0x75, 0x3b, -0x42, 0xea, 0x6c, 0x3b, 0x46, 0xf6, 0x6e, 0x3b, 0x4c, 0x65, 0x6e, 0x3b, 0x4b, 0xfc, 0x6b, 0x3b, 0x4d, 0x76, 0x75, 0x3b, -0x4e, 0x67, 0x62, 0x3b, 0x4e, 0x61, 0x62, 0x3b, 0x4b, 0x61, 0x6b, 0x3b, 0x4e, 0x79, 0x65, 0x6e, 0x79, 0x65, 0x3b, 0x46, -0x75, 0x6c, 0x75, 0x6e, 0x64, 0xef, 0x67, 0x69, 0x3b, 0x4d, 0x62, 0xe4, 0x6e, 0x67, 0xfc, 0x3b, 0x4e, 0x67, 0x75, 0x62, -0xf9, 0x65, 0x3b, 0x42, 0xea, 0x6c, 0xe4, 0x77, 0xfc, 0x3b, 0x46, 0xf6, 0x6e, 0x64, 0x6f, 0x3b, 0x4c, 0x65, 0x6e, 0x67, -0x75, 0x61, 0x3b, 0x4b, 0xfc, 0x6b, 0xfc, 0x72, 0xfc, 0x3b, 0x4d, 0x76, 0x75, 0x6b, 0x61, 0x3b, 0x4e, 0x67, 0x62, 0x65, -0x72, 0x65, 0x72, 0x65, 0x3b, 0x4e, 0x61, 0x62, 0xe4, 0x6e, 0x64, 0xfc, 0x72, 0x75, 0x3b, 0x4b, 0x61, 0x6b, 0x61, 0x75, -0x6b, 0x61, 0x3b, 0x4e, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x42, 0x3b, 0x46, 0x3b, 0x4c, 0x3b, 0x4b, 0x3b, 0x4d, -0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4b, 0x3b, 0x458, 0x430, 0x43d, 0x3b, 0x444, 0x435, 0x431, 0x3b, 0x43c, 0x430, 0x440, 0x3b, 0x430, -0x43f, 0x440, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x3b, 0x458, 0x443, 0x43b, 0x3b, 0x430, 0x432, 0x433, 0x3b, 0x441, -0x435, 0x43f, 0x3b, 0x43e, 0x43a, 0x442, 0x3b, 0x43d, 0x43e, 0x432, 0x3b, 0x434, 0x435, 0x446, 0x3b, 0x458, 0x430, 0x43d, 0x443, 0x430, -0x440, 0x3b, 0x444, 0x435, 0x431, 0x440, 0x443, 0x430, 0x440, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b, -0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x3b, 0x458, 0x443, 0x43b, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, -0x441, 0x435, 0x43f, 0x442, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x431, 0x430, 0x440, 0x3b, 0x43d, 0x43e, -0x432, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x434, 0x435, 0x446, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, -0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, -0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x76, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, -0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, -0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, -0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x76, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, -0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x72, 0x3b, 0x6e, 0x6f, 0x76, -0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x6a, 0x3b, 0x66, 0x3b, 0x6d, -0x3b, 0x61, 0x3b, 0x6d, 0x3b, 0x6a, 0x3b, 0x6a, 0x3b, 0x61, 0x3b, 0x73, 0x3b, 0x6f, 0x3b, 0x6e, 0x3b, 0x64, 0x3b, 0x6a, -0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, -0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x76, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, -0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x458, 0x430, 0x43d, 0x2e, 0x3b, 0x444, 0x435, 0x431, 0x2e, 0x3b, 0x43c, 0x430, 0x440, -0x442, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x3b, 0x458, 0x443, 0x43b, 0x3b, 0x430, -0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x432, 0x2e, 0x3b, -0x434, 0x435, 0x446, 0x2e, 0x3b, 0x42f, 0x43d, 0x432, 0x2e, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x2e, 0x3b, 0x41c, 0x430, 0x440, 0x442, -0x2e, 0x3b, 0x410, 0x43f, 0x440, 0x2e, 0x3b, 0x41c, 0x430, 0x439, 0x3b, 0x418, 0x44e, 0x43d, 0x44c, 0x3b, 0x418, 0x44e, 0x43b, 0x44c, -0x3b, 0x410, 0x432, 0x433, 0x2e, 0x3b, 0x421, 0x435, 0x43d, 0x442, 0x2e, 0x3b, 0x41e, 0x43a, 0x442, 0x2e, 0x3b, 0x41d, 0x43e, 0x44f, -0x431, 0x2e, 0x3b, 0x414, 0x435, 0x43a, 0x2e, 0x3b, 0x42f, 0x43d, 0x432, 0x430, 0x440, 0x44c, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x430, -0x43b, 0x44c, 0x3b, 0x41c, 0x430, 0x440, 0x442, 0x44a, 0x438, 0x3b, 0x410, 0x43f, 0x440, 0x435, 0x43b, 0x44c, 0x3b, 0x41c, 0x430, 0x439, -0x3b, 0x418, 0x44e, 0x43d, 0x44c, 0x3b, 0x418, 0x44e, 0x43b, 0x44c, 0x3b, 0x410, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x421, 0x435, -0x43d, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x41e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x41d, 0x43e, 0x44f, 0x431, 0x440, -0x44c, 0x3b, 0x414, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x44c, 0x3b, 0x44f, 0x43d, 0x432, 0x2e, 0x3b, 0x444, 0x435, 0x432, 0x2e, 0x3b, -0x43c, 0x430, 0x440, 0x2e, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x439, 0x44b, 0x3b, 0x438, 0x44e, 0x43d, 0x44b, 0x3b, -0x438, 0x44e, 0x43b, 0x44b, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43d, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, -0x43d, 0x43e, 0x44f, 0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x2e, 0x3b, 0x44f, 0x43d, 0x432, 0x430, 0x440, 0x44b, 0x3b, 0x444, 0x435, 0x432, -0x440, 0x430, 0x43b, 0x44b, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x44a, 0x438, 0x439, 0x44b, 0x3b, 0x430, 0x43f, 0x440, 0x435, 0x43b, 0x44b, -0x3b, 0x43c, 0x430, 0x439, 0x44b, 0x3b, 0x438, 0x44e, 0x43d, 0x44b, 0x3b, 0x438, 0x44e, 0x43b, 0x44b, 0x3b, 0x430, 0x432, 0x433, 0x443, -0x441, 0x442, 0x44b, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x44b, 0x3b, 0x43e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44b, -0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x440, 0x44b, 0x3b, 0x434, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x44b, 0x3b, 0x4e, 0x64, 0x69, 0x3b, -0x4b, 0x75, 0x6b, 0x3b, 0x4b, 0x75, 0x72, 0x3b, 0x4b, 0x75, 0x62, 0x3b, 0x43, 0x68, 0x76, 0x3b, 0x43, 0x68, 0x6b, 0x3b, -0x43, 0x68, 0x67, 0x3b, 0x4e, 0x79, 0x61, 0x3b, 0x47, 0x75, 0x6e, 0x3b, 0x47, 0x75, 0x6d, 0x3b, 0x4d, 0x62, 0x75, 0x3b, -0x5a, 0x76, 0x69, 0x3b, 0x4e, 0x64, 0x69, 0x72, 0x61, 0x3b, 0x4b, 0x75, 0x6b, 0x61, 0x64, 0x7a, 0x69, 0x3b, 0x4b, 0x75, -0x72, 0x75, 0x6d, 0x65, 0x3b, 0x4b, 0x75, 0x62, 0x76, 0x75, 0x6d, 0x62, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x76, 0x61, 0x62, -0x76, 0x75, 0x3b, 0x43, 0x68, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x6b, 0x75, 0x6e, 0x67, 0x75, 0x72, -0x75, 0x3b, 0x4e, 0x79, 0x61, 0x6d, 0x61, 0x76, 0x68, 0x75, 0x76, 0x68, 0x75, 0x3b, 0x47, 0x75, 0x6e, 0x79, 0x61, 0x6e, -0x61, 0x3b, 0x47, 0x75, 0x6d, 0x69, 0x67, 0x75, 0x72, 0x75, 0x3b, 0x4d, 0x62, 0x75, 0x64, 0x7a, 0x69, 0x3b, 0x5a, 0x76, -0x69, 0x74, 0x61, 0x3b, 0x4e, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x4e, 0x3b, -0x47, 0x3b, 0x47, 0x3b, 0x4d, 0x3b, 0x5a, 0x3b, 0x62c, 0x646, 0x648, 0x631, 0x64a, 0x3b, 0x641, 0x64a, 0x628, 0x631, 0x648, 0x631, -0x64a, 0x3b, 0x645, 0x627, 0x631, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x64a, 0x644, 0x3b, 0x645, 0x626, 0x64a, 0x3b, 0x62c, 0x648, 0x646, -0x3b, 0x62c, 0x648, 0x644, 0x627, 0x621, 0x650, 0x3b, 0x622, 0x6af, 0x633, 0x67d, 0x3b, 0x633, 0x64a, 0x67e, 0x67d, 0x645, 0x628, 0x631, -0x3b, 0x622, 0x6aa, 0x67d, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x68a, 0x633, 0x645, 0x628, 0x631, 0x3b, -0xda2, 0xdb1, 0x3b, 0xdb4, 0xdd9, 0xdb6, 0x3b, 0xdb8, 0xdcf, 0xdbb, 0xdca, 0x3b, 0xd85, 0xdb4, 0xdca, 0x200d, 0xdbb, 0xdda, 0xdbd, 0xdca, -0x3b, 0xdb8, 0xdd0, 0xdba, 0xdd2, 0x3b, 0xda2, 0xdd6, 0xdb1, 0xdd2, 0x3b, 0xda2, 0xdd6, 0xdbd, 0xdd2, 0x3b, 0xd85, 0xd9c, 0xddd, 0x3b, -0xdc3, 0xdd0, 0xdb4, 0xdca, 0x3b, 0xd94, 0xd9a, 0xdca, 0x3b, 0xdb1, 0xddc, 0xdc0, 0xdd0, 0x3b, 0xdaf, 0xdd9, 0xdc3, 0xdd0, 0x3b, 0xda2, -0xdb1, 0xdc0, 0xdcf, 0xdbb, 0xdd2, 0x3b, 0xdb4, 0xdd9, 0xdb6, 0xdbb, 0xdc0, 0xdcf, 0xdbb, 0xdd2, 0x3b, 0xdb8, 0xdcf, 0xdbb, 0xdca, 0xdad, -0xdd4, 0x3b, 0xd85, 0xdb4, 0xdca, 0x200d, 0xdbb, 0xdda, 0xdbd, 0xdca, 0x3b, 0xdb8, 0xdd0, 0xdba, 0xdd2, 0x3b, 0xda2, 0xdd6, 0xdb1, 0xdd2, -0x3b, 0xda2, 0xdd6, 0xdbd, 0xdd2, 0x3b, 0xd85, 0xd9c, 0xddd, 0xdc3, 0xdca, 0xdad, 0xdd4, 0x3b, 0xdc3, 0xdd0, 0xdb4, 0xdca, 0xdad, 0xdd0, -0xdb8, 0xdca, 0xdb6, 0xdbb, 0xdca, 0x3b, 0xd94, 0xd9a, 0xdca, 0xdad, 0xddd, 0xdb6, 0xdbb, 0xdca, 0x3b, 0xdb1, 0xddc, 0xdc0, 0xdd0, 0xdb8, -0xdca, 0xdb6, 0xdbb, 0xdca, 0x3b, 0xdaf, 0xdd9, 0xdc3, 0xdd0, 0xdb8, 0xdca, 0xdb6, 0xdbb, 0xdca, 0x3b, 0xda2, 0x3b, 0xdb4, 0xdd9, 0x3b, -0xdb8, 0xdcf, 0x3b, 0xd85, 0x3b, 0xdb8, 0xdd0, 0x3b, 0xda2, 0xdd6, 0x3b, 0xda2, 0xdd6, 0x3b, 0xd85, 0x3b, 0xdc3, 0xdd0, 0x3b, 0xd94, -0x3b, 0xdb1, 0xdd9, 0x3b, 0xdaf, 0xdd9, 0x3b, 0xda2, 0xdb1, 0x3b, 0xdb4, 0xdd9, 0xdb6, 0x3b, 0xdb8, 0xdcf, 0xdbb, 0xdca, 0xdad, 0xdd4, -0x3b, 0xd85, 0xdb4, 0xdca, 0x200d, 0xdbb, 0xdda, 0xdbd, 0xdca, 0x3b, 0xdb8, 0xdd0, 0xdba, 0xdd2, 0x3b, 0xda2, 0xdd6, 0xdb1, 0xdd2, 0x3b, -0xda2, 0xdd6, 0xdbd, 0xdd2, 0x3b, 0xd85, 0xd9c, 0xddd, 0x3b, 0xdc3, 0xdd0, 0xdb4, 0xdca, 0x3b, 0xd94, 0xd9a, 0xdca, 0x3b, 0xdb1, 0xddc, -0xdc0, 0xdd0, 0x3b, 0xdaf, 0xdd9, 0xdc3, 0xdd0, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, -0x61, 0x70, 0x72, 0x3b, 0x6d, 0xe1, 0x6a, 0x3b, 0x6a, 0xfa, 0x6e, 0x3b, 0x6a, 0xfa, 0x6c, 0x3b, 0x61, 0x75, 0x67, 0x3b, -0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x6a, 0x61, 0x6e, 0x75, -0xe1, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0xe1, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x65, 0x63, 0x3b, 0x61, 0x70, 0x72, -0xed, 0x6c, 0x3b, 0x6d, 0xe1, 0x6a, 0x3b, 0x6a, 0xfa, 0x6e, 0x3b, 0x6a, 0xfa, 0x6c, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, -0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0xf3, 0x62, 0x65, 0x72, 0x3b, -0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6a, 0x61, -0x6e, 0x75, 0xe1, 0x72, 0x61, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0xe1, 0x72, 0x61, 0x3b, 0x6d, 0x61, 0x72, 0x63, 0x61, -0x3b, 0x61, 0x70, 0x72, 0xed, 0x6c, 0x61, 0x3b, 0x6d, 0xe1, 0x6a, 0x61, 0x3b, 0x6a, 0xfa, 0x6e, 0x61, 0x3b, 0x6a, 0xfa, -0x6c, 0x61, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x61, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x61, -0x3b, 0x6f, 0x6b, 0x74, 0xf3, 0x62, 0x72, 0x61, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x64, 0x65, -0x63, 0x65, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, -0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, -0x3b, 0x61, 0x76, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, -0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, -0x3b, 0x6d, 0x61, 0x72, 0x65, 0x63, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, -0x69, 0x6a, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x6a, 0x3b, 0x61, 0x76, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, -0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, -0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4b, 0x6f, 0x62, 0x3b, 0x4c, 0x61, 0x62, 0x3b, -0x53, 0x61, 0x64, 0x3b, 0x41, 0x66, 0x72, 0x3b, 0x53, 0x68, 0x61, 0x3b, 0x4c, 0x69, 0x78, 0x3b, 0x54, 0x6f, 0x64, 0x3b, -0x53, 0x69, 0x64, 0x3b, 0x53, 0x61, 0x67, 0x3b, 0x54, 0x6f, 0x62, 0x3b, 0x4b, 0x49, 0x54, 0x3b, 0x4c, 0x49, 0x54, 0x3b, -0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x4b, 0x6f, 0x6f, 0x62, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, -0x4c, 0x61, 0x62, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x53, 0x61, 0x64, 0x64, 0x65, 0x78, 0x61, -0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x41, 0x66, 0x72, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, -0x61, 0x20, 0x53, 0x68, 0x61, 0x6e, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x4c, 0x69, 0x78, 0x61, -0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x54, 0x6f, 0x64, 0x6f, 0x62, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, -0x73, 0x68, 0x61, 0x20, 0x53, 0x69, 0x64, 0x65, 0x65, 0x64, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, -0x53, 0x61, 0x67, 0x61, 0x61, 0x6c, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x54, 0x6f, 0x62, 0x6e, -0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x4b, 0x6f, 0x77, 0x20, 0x69, 0x79, 0x6f, 0x20, 0x54, 0x6f, -0x62, 0x6e, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x4c, 0x61, 0x62, 0x61, 0x20, 0x69, 0x79, 0x6f, -0x20, 0x54, 0x6f, 0x62, 0x6e, 0x61, 0x61, 0x64, 0x3b, 0x4b, 0x3b, 0x4c, 0x3b, 0x53, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4c, -0x3b, 0x54, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x4c, 0x3b, 0x65, 0x6e, 0x65, 0x2e, 0x3b, 0x66, 0x65, -0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x79, 0x2e, 0x3b, 0x6a, 0x75, -0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x67, 0x6f, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, -0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x69, 0x63, 0x2e, 0x3b, 0x65, 0x6e, 0x65, 0x72, 0x6f, 0x3b, -0x66, 0x65, 0x62, 0x72, 0x65, 0x72, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x3b, -0x6d, 0x61, 0x79, 0x6f, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x6f, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x6f, 0x3b, 0x61, 0x67, 0x6f, -0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x75, 0x62, -0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x69, 0x63, 0x69, 0x65, 0x6d, 0x62, -0x72, 0x65, 0x3b, 0x45, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x53, -0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x65, 0x6e, 0x65, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, -0x2e, 0x3b, 0x61, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x79, 0x2e, 0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, -0x2e, 0x3b, 0x61, 0x67, 0x6f, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, -0x2e, 0x3b, 0x64, 0x69, 0x63, 0x2e, 0x3b, 0x65, 0x6e, 0x65, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, -0x62, 0x72, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x67, 0x6f, 0x3b, 0x73, -0x65, 0x70, 0x3b, 0x6f, 0x63, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x69, 0x63, 0x3b, 0x45, 0x6e, 0x65, 0x2e, 0x3b, -0x46, 0x65, 0x62, 0x2e, 0x3b, 0x4d, 0x61, 0x72, 0x2e, 0x3b, 0x41, 0x62, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x79, 0x2e, 0x3b, -0x4a, 0x75, 0x6e, 0x2e, 0x3b, 0x4a, 0x75, 0x6c, 0x2e, 0x3b, 0x41, 0x67, 0x6f, 0x2e, 0x3b, 0x53, 0x65, 0x74, 0x2e, 0x3b, -0x4f, 0x63, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x69, 0x63, 0x2e, 0x3b, 0x65, 0x6e, 0x65, 0x2e, 0x3b, -0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x79, 0x2e, 0x3b, -0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x67, 0x6f, 0x2e, 0x3b, 0x73, 0x65, 0x74, 0x2e, 0x3b, +0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x67e, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648, 0x628, 0x631, 0x3b, +0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x62c, 0x646, 0x648, 0x631, 0x64a, 0x3b, 0x641, 0x6d0, +0x628, 0x631, 0x648, 0x631, 0x64a, 0x3b, 0x645, 0x627, 0x631, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x6cd, 0x3b, +0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648, 0x644, 0x627, 0x6cc, 0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x67e, 0x62a, 0x645, 0x628, +0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, +0x3b, 0x62c, 0x646, 0x648, 0x631, 0x64a, 0x3b, 0x641, 0x628, 0x631, 0x648, 0x631, 0x64a, 0x3b, 0x645, 0x627, 0x631, 0x686, 0x3b, 0x627, +0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x6cd, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648, 0x644, 0x627, 0x6cc, 0x3b, 0x627, 0x6af, +0x633, 0x62a, 0x3b, 0x633, 0x6d0, 0x67e, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, +0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x62c, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x627, 0x3b, 0x645, 0x3b, +0x62c, 0x3b, 0x62c, 0x3b, 0x627, 0x3b, 0x633, 0x3b, 0x627, 0x3b, 0x646, 0x3b, 0x62f, 0x3b, 0x698, 0x627, 0x646, 0x648, 0x6cc, 0x647, +0x3b, 0x641, 0x648, 0x631, 0x6cc, 0x647, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x622, 0x648, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x647, +0x3b, 0x698, 0x648, 0x626, 0x646, 0x3b, 0x698, 0x648, 0x626, 0x6cc, 0x647, 0x3b, 0x627, 0x648, 0x62a, 0x3b, 0x633, 0x67e, 0x62a, 0x627, +0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x627, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x627, +0x645, 0x628, 0x631, 0x3b, 0x698, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x622, 0x3b, 0x645, 0x3b, 0x698, 0x3b, 0x698, 0x3b, 0x627, 0x3b, +0x633, 0x3b, 0x627, 0x3b, 0x646, 0x3b, 0x62f, 0x3b, 0x698, 0x627, 0x646, 0x648, 0x6cc, 0x647, 0x654, 0x3b, 0x641, 0x648, 0x631, 0x6cc, +0x647, 0x654, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x622, 0x648, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x647, 0x654, 0x3b, 0x698, 0x648, +0x626, 0x646, 0x3b, 0x698, 0x648, 0x626, 0x6cc, 0x647, 0x654, 0x3b, 0x627, 0x648, 0x62a, 0x3b, 0x633, 0x67e, 0x62a, 0x627, 0x645, 0x628, +0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x627, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x627, 0x645, 0x628, +0x631, 0x3b, 0x62c, 0x646, 0x648, 0x631, 0x6cc, 0x3b, 0x641, 0x628, 0x631, 0x648, 0x631, 0x6cc, 0x3b, 0x645, 0x627, 0x631, 0x686, 0x3b, +0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x6cc, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648, 0x644, 0x627, 0x6cc, 0x3b, 0x627, +0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x67e, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, +0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x62c, 0x646, 0x648, 0x3b, 0x641, 0x628, 0x631, 0x648, 0x631, 0x6cc, +0x3b, 0x645, 0x627, 0x631, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x6cc, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, +0x648, 0x644, 0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x67e, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648, 0x628, +0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x3b, 0x73, 0x74, 0x79, 0x3b, 0x6c, 0x75, 0x74, 0x3b, +0x6d, 0x61, 0x72, 0x3b, 0x6b, 0x77, 0x69, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x63, 0x7a, 0x65, 0x3b, 0x6c, 0x69, 0x70, 0x3b, +0x73, 0x69, 0x65, 0x3b, 0x77, 0x72, 0x7a, 0x3b, 0x70, 0x61, 0x17a, 0x3b, 0x6c, 0x69, 0x73, 0x3b, 0x67, 0x72, 0x75, 0x3b, +0x73, 0x74, 0x79, 0x63, 0x7a, 0x65, 0x144, 0x3b, 0x6c, 0x75, 0x74, 0x79, 0x3b, 0x6d, 0x61, 0x72, 0x7a, 0x65, 0x63, 0x3b, +0x6b, 0x77, 0x69, 0x65, 0x63, 0x69, 0x65, 0x144, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x63, 0x7a, 0x65, 0x72, 0x77, 0x69, 0x65, +0x63, 0x3b, 0x6c, 0x69, 0x70, 0x69, 0x65, 0x63, 0x3b, 0x73, 0x69, 0x65, 0x72, 0x70, 0x69, 0x65, 0x144, 0x3b, 0x77, 0x72, +0x7a, 0x65, 0x73, 0x69, 0x65, 0x144, 0x3b, 0x70, 0x61, 0x17a, 0x64, 0x7a, 0x69, 0x65, 0x72, 0x6e, 0x69, 0x6b, 0x3b, 0x6c, +0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x3b, 0x67, 0x72, 0x75, 0x64, 0x7a, 0x69, 0x65, 0x144, 0x3b, 0x53, 0x3b, 0x4c, +0x3b, 0x4d, 0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x43, 0x3b, 0x4c, 0x3b, 0x53, 0x3b, 0x57, 0x3b, 0x50, 0x3b, 0x4c, 0x3b, 0x47, +0x3b, 0x73, 0x74, 0x79, 0x63, 0x7a, 0x6e, 0x69, 0x61, 0x3b, 0x6c, 0x75, 0x74, 0x65, 0x67, 0x6f, 0x3b, 0x6d, 0x61, 0x72, +0x63, 0x61, 0x3b, 0x6b, 0x77, 0x69, 0x65, 0x74, 0x6e, 0x69, 0x61, 0x3b, 0x6d, 0x61, 0x6a, 0x61, 0x3b, 0x63, 0x7a, 0x65, +0x72, 0x77, 0x63, 0x61, 0x3b, 0x6c, 0x69, 0x70, 0x63, 0x61, 0x3b, 0x73, 0x69, 0x65, 0x72, 0x70, 0x6e, 0x69, 0x61, 0x3b, +0x77, 0x72, 0x7a, 0x65, 0x15b, 0x6e, 0x69, 0x61, 0x3b, 0x70, 0x61, 0x17a, 0x64, 0x7a, 0x69, 0x65, 0x72, 0x6e, 0x69, 0x6b, +0x61, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x61, 0x3b, 0x67, 0x72, 0x75, 0x64, 0x6e, 0x69, 0x61, 0x3b, +0x73, 0x3b, 0x6c, 0x3b, 0x6d, 0x3b, 0x6b, 0x3b, 0x6d, 0x3b, 0x63, 0x3b, 0x6c, 0x3b, 0x73, 0x3b, 0x77, 0x3b, 0x70, 0x3b, +0x6c, 0x3b, 0x67, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x76, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x62, 0x72, 0x3b, +0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x67, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x3b, +0x6f, 0x75, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x7a, 0x3b, 0x6a, 0x61, 0x6e, 0x65, 0x69, 0x72, 0x6f, 0x3b, +0x66, 0x65, 0x76, 0x65, 0x72, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0xe7, 0x6f, 0x3b, 0x61, 0x62, 0x72, 0x69, +0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x6f, 0x3b, 0x6a, 0x75, 0x6e, 0x68, 0x6f, 0x3b, 0x6a, 0x75, 0x6c, 0x68, 0x6f, 0x3b, 0x61, +0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x6f, 0x75, 0x74, 0x75, 0x62, +0x72, 0x6f, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x64, 0x65, 0x7a, 0x65, 0x6d, 0x62, 0x72, 0x6f, +0x3b, 0xa1c, 0xa28, 0x3b, 0xa2b, 0xa3c, 0xa30, 0x3b, 0xa2e, 0xa3e, 0xa30, 0xa1a, 0x3b, 0xa05, 0xa2a, 0xa4d, 0xa30, 0xa48, 0x3b, 0xa2e, +0xa08, 0x3b, 0xa1c, 0xa42, 0xa28, 0x3b, 0xa1c, 0xa41, 0xa32, 0xa3e, 0x3b, 0xa05, 0xa17, 0x3b, 0xa38, 0xa24, 0xa70, 0x3b, 0xa05, 0xa15, +0xa24, 0xa42, 0x3b, 0xa28, 0xa35, 0xa70, 0x3b, 0xa26, 0xa38, 0xa70, 0x3b, 0xa1c, 0xa28, 0xa35, 0xa30, 0xa40, 0x3b, 0xa2b, 0xa3c, 0xa30, +0xa35, 0xa30, 0xa40, 0x3b, 0xa2e, 0xa3e, 0xa30, 0xa1a, 0x3b, 0xa05, 0xa2a, 0xa4d, 0xa30, 0xa48, 0xa32, 0x3b, 0xa2e, 0xa08, 0x3b, 0xa1c, +0xa42, 0xa28, 0x3b, 0xa1c, 0xa41, 0xa32, 0xa3e, 0xa08, 0x3b, 0xa05, 0xa17, 0xa38, 0xa24, 0x3b, 0xa38, 0xa24, 0xa70, 0xa2c, 0xa30, 0x3b, +0xa05, 0xa15, 0xa24, 0xa42, 0xa2c, 0xa30, 0x3b, 0xa28, 0xa35, 0xa70, 0xa2c, 0xa30, 0x3b, 0xa26, 0xa38, 0xa70, 0xa2c, 0xa30, 0x3b, 0xa1c, +0x3b, 0xa2b, 0xa3c, 0x3b, 0xa2e, 0xa3e, 0x3b, 0xa05, 0x3b, 0xa2e, 0x3b, 0xa1c, 0xa42, 0x3b, 0xa1c, 0xa41, 0x3b, 0xa05, 0x3b, 0xa38, +0x3b, 0xa05, 0x3b, 0xa28, 0x3b, 0xa26, 0x3b, 0x62c, 0x646, 0x648, 0x631, 0x6cc, 0x3b, 0x641, 0x631, 0x648, 0x631, 0x6cc, 0x3b, 0x645, +0x627, 0x631, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x626, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648, 0x644, +0x627, 0x626, 0x6cc, 0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648, 0x628, +0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x45, 0x6e, 0x65, 0x3b, 0x46, 0x65, +0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, +0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x63, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, +0x63, 0x3b, 0x45, 0x6e, 0x65, 0x72, 0x6f, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x65, 0x72, 0x6f, 0x3b, 0x4d, 0x61, 0x72, 0x7a, +0x6f, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x79, 0x6f, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x6f, 0x3b, 0x4a, +0x75, 0x6c, 0x69, 0x6f, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x69, 0x65, 0x6d, 0x62, 0x72, +0x65, 0x3b, 0x4f, 0x63, 0x74, 0x75, 0x62, 0x72, 0x65, 0x3b, 0x4e, 0x6f, 0x76, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, +0x44, 0x69, 0x63, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x73, 0x63, 0x68, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x61, 0x76, +0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x74, 0x67, 0x3b, 0x7a, 0x65, +0x72, 0x63, 0x6c, 0x2e, 0x3b, 0x66, 0x61, 0x6e, 0x2e, 0x3b, 0x61, 0x76, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x74, 0x74, +0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x73, 0x63, 0x68, +0x61, 0x6e, 0x65, 0x72, 0x3b, 0x66, 0x61, 0x76, 0x72, 0x65, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x76, 0x72, +0x69, 0x67, 0x6c, 0x3b, 0x6d, 0x61, 0x74, 0x67, 0x3b, 0x7a, 0x65, 0x72, 0x63, 0x6c, 0x61, 0x64, 0x75, 0x72, 0x3b, 0x66, +0x61, 0x6e, 0x61, 0x64, 0x75, 0x72, 0x3b, 0x61, 0x76, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x74, 0x74, 0x65, 0x6d, 0x62, +0x65, 0x72, 0x3b, 0x6f, 0x63, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, +0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x53, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x5a, +0x3b, 0x46, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x69, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, +0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x69, 0x75, 0x6e, +0x2e, 0x3b, 0x69, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x63, +0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x69, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, +0x65, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x65, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x69, 0x65, 0x3b, 0x61, +0x70, 0x72, 0x69, 0x6c, 0x69, 0x65, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x69, 0x75, 0x6e, 0x69, 0x65, 0x3b, 0x69, 0x75, 0x6c, +0x69, 0x65, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x65, +0x3b, 0x6f, 0x63, 0x74, 0x6f, 0x6d, 0x62, 0x72, 0x69, 0x65, 0x3b, 0x6e, 0x6f, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x65, +0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x65, 0x3b, 0x49, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, +0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x44f, 0x43d, 0x432, 0x2e, 0x3b, +0x444, 0x435, 0x432, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x439, 0x3b, +0x438, 0x44e, 0x43d, 0x44c, 0x3b, 0x438, 0x44e, 0x43b, 0x44c, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x2e, +0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x2e, 0x3b, 0x44f, 0x43d, 0x432, +0x2e, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x2e, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430, +0x44f, 0x3b, 0x438, 0x44e, 0x43d, 0x2e, 0x3b, 0x438, 0x44e, 0x43b, 0x2e, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43d, +0x442, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x2e, 0x3b, 0x44f, +0x43d, 0x432, 0x430, 0x440, 0x44f, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x44f, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x430, 0x3b, +0x430, 0x43f, 0x440, 0x435, 0x43b, 0x44f, 0x3b, 0x43c, 0x430, 0x44f, 0x3b, 0x438, 0x44e, 0x43d, 0x44f, 0x3b, 0x438, 0x44e, 0x43b, 0x44f, +0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x430, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x44f, 0x3b, 0x43e, 0x43a, +0x442, 0x44f, 0x431, 0x440, 0x44f, 0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x440, 0x44f, 0x3b, 0x434, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x44f, +0x3b, 0x4e, 0x79, 0x65, 0x3b, 0x46, 0x75, 0x6c, 0x3b, 0x4d, 0x62, 0xe4, 0x3b, 0x4e, 0x67, 0x75, 0x3b, 0x42, 0xea, 0x6c, +0x3b, 0x46, 0xf6, 0x6e, 0x3b, 0x4c, 0x65, 0x6e, 0x3b, 0x4b, 0xfc, 0x6b, 0x3b, 0x4d, 0x76, 0x75, 0x3b, 0x4e, 0x67, 0x62, +0x3b, 0x4e, 0x61, 0x62, 0x3b, 0x4b, 0x61, 0x6b, 0x3b, 0x4e, 0x79, 0x65, 0x6e, 0x79, 0x65, 0x3b, 0x46, 0x75, 0x6c, 0x75, +0x6e, 0x64, 0xef, 0x67, 0x69, 0x3b, 0x4d, 0x62, 0xe4, 0x6e, 0x67, 0xfc, 0x3b, 0x4e, 0x67, 0x75, 0x62, 0xf9, 0x65, 0x3b, +0x42, 0xea, 0x6c, 0xe4, 0x77, 0xfc, 0x3b, 0x46, 0xf6, 0x6e, 0x64, 0x6f, 0x3b, 0x4c, 0x65, 0x6e, 0x67, 0x75, 0x61, 0x3b, +0x4b, 0xfc, 0x6b, 0xfc, 0x72, 0xfc, 0x3b, 0x4d, 0x76, 0x75, 0x6b, 0x61, 0x3b, 0x4e, 0x67, 0x62, 0x65, 0x72, 0x65, 0x72, +0x65, 0x3b, 0x4e, 0x61, 0x62, 0xe4, 0x6e, 0x64, 0xfc, 0x72, 0x75, 0x3b, 0x4b, 0x61, 0x6b, 0x61, 0x75, 0x6b, 0x61, 0x3b, +0x4e, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x42, 0x3b, 0x46, 0x3b, 0x4c, 0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, +0x4e, 0x3b, 0x4b, 0x3b, 0x458, 0x430, 0x43d, 0x3b, 0x444, 0x435, 0x431, 0x3b, 0x43c, 0x430, 0x440, 0x3b, 0x430, 0x43f, 0x440, 0x3b, +0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x3b, 0x458, 0x443, 0x43b, 0x3b, 0x430, 0x432, 0x433, 0x3b, 0x441, 0x435, 0x43f, 0x3b, +0x43e, 0x43a, 0x442, 0x3b, 0x43d, 0x43e, 0x432, 0x3b, 0x434, 0x435, 0x446, 0x3b, 0x458, 0x430, 0x43d, 0x443, 0x430, 0x440, 0x3b, 0x444, +0x435, 0x431, 0x440, 0x443, 0x430, 0x440, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b, 0x3b, 0x43c, 0x430, +0x458, 0x3b, 0x458, 0x443, 0x43d, 0x3b, 0x458, 0x443, 0x43b, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, 0x43f, +0x442, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x431, 0x430, 0x440, 0x3b, 0x43d, 0x43e, 0x432, 0x435, 0x43c, +0x431, 0x430, 0x440, 0x3b, 0x434, 0x435, 0x446, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x458, 0x430, 0x43d, 0x3b, 0x444, 0x435, 0x431, +0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x3b, 0x458, 0x443, +0x43b, 0x3b, 0x430, 0x432, 0x433, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x3b, 0x43e, 0x43a, 0x442, 0x3b, 0x43d, 0x43e, 0x432, 0x3b, 0x434, +0x435, 0x446, 0x3b, 0x458, 0x430, 0x43d, 0x2e, 0x3b, 0x444, 0x435, 0x431, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, +0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x3b, 0x458, 0x443, 0x43b, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, +0x441, 0x435, 0x43f, 0x442, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x432, 0x2e, 0x3b, 0x434, 0x435, 0x446, 0x2e, +0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, +0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x76, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x3b, 0x6f, +0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, +0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, +0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x76, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, +0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, +0x61, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, +0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, +0x61, 0x76, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63, 0x3b, +0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, +0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x76, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, +0x74, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x42f, 0x43d, +0x432, 0x2e, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x2e, 0x3b, 0x41c, 0x430, 0x440, 0x442, 0x2e, 0x3b, 0x410, 0x43f, 0x440, 0x2e, 0x3b, +0x41c, 0x430, 0x439, 0x3b, 0x418, 0x44e, 0x43d, 0x44c, 0x3b, 0x418, 0x44e, 0x43b, 0x44c, 0x3b, 0x410, 0x432, 0x433, 0x2e, 0x3b, 0x421, +0x435, 0x43d, 0x442, 0x2e, 0x3b, 0x41e, 0x43a, 0x442, 0x2e, 0x3b, 0x41d, 0x43e, 0x44f, 0x431, 0x2e, 0x3b, 0x414, 0x435, 0x43a, 0x2e, +0x3b, 0x42f, 0x43d, 0x432, 0x430, 0x440, 0x44c, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x44c, 0x3b, 0x41c, 0x430, 0x440, 0x442, +0x44a, 0x438, 0x3b, 0x410, 0x43f, 0x440, 0x435, 0x43b, 0x44c, 0x3b, 0x41c, 0x430, 0x439, 0x3b, 0x418, 0x44e, 0x43d, 0x44c, 0x3b, 0x418, +0x44e, 0x43b, 0x44c, 0x3b, 0x410, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x421, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, +0x41e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x41d, 0x43e, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x414, 0x435, 0x43a, 0x430, 0x431, +0x440, 0x44c, 0x3b, 0x44f, 0x43d, 0x432, 0x2e, 0x3b, 0x444, 0x435, 0x432, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x2e, 0x3b, 0x430, 0x43f, +0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x439, 0x44b, 0x3b, 0x438, 0x44e, 0x43d, 0x44b, 0x3b, 0x438, 0x44e, 0x43b, 0x44b, 0x3b, 0x430, 0x432, +0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43d, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x44f, 0x2e, 0x3b, 0x434, 0x435, +0x43a, 0x2e, 0x3b, 0x44f, 0x43d, 0x432, 0x430, 0x440, 0x44b, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x44b, 0x3b, 0x43c, 0x430, +0x440, 0x442, 0x44a, 0x438, 0x439, 0x44b, 0x3b, 0x430, 0x43f, 0x440, 0x435, 0x43b, 0x44b, 0x3b, 0x43c, 0x430, 0x439, 0x44b, 0x3b, 0x438, +0x44e, 0x43d, 0x44b, 0x3b, 0x438, 0x44e, 0x43b, 0x44b, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x44b, 0x3b, 0x441, 0x435, 0x43d, +0x442, 0x44f, 0x431, 0x440, 0x44b, 0x3b, 0x43e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44b, 0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x440, 0x44b, +0x3b, 0x434, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x44b, 0x3b, 0x4e, 0x64, 0x69, 0x3b, 0x4b, 0x75, 0x6b, 0x3b, 0x4b, 0x75, 0x72, +0x3b, 0x4b, 0x75, 0x62, 0x3b, 0x43, 0x68, 0x76, 0x3b, 0x43, 0x68, 0x6b, 0x3b, 0x43, 0x68, 0x67, 0x3b, 0x4e, 0x79, 0x61, +0x3b, 0x47, 0x75, 0x6e, 0x3b, 0x47, 0x75, 0x6d, 0x3b, 0x4d, 0x62, 0x75, 0x3b, 0x5a, 0x76, 0x69, 0x3b, 0x4e, 0x64, 0x69, +0x72, 0x61, 0x3b, 0x4b, 0x75, 0x6b, 0x61, 0x64, 0x7a, 0x69, 0x3b, 0x4b, 0x75, 0x72, 0x75, 0x6d, 0x65, 0x3b, 0x4b, 0x75, +0x62, 0x76, 0x75, 0x6d, 0x62, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x76, 0x61, 0x62, 0x76, 0x75, 0x3b, 0x43, 0x68, 0x69, 0x6b, +0x75, 0x6d, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x6b, 0x75, 0x6e, 0x67, 0x75, 0x72, 0x75, 0x3b, 0x4e, 0x79, 0x61, 0x6d, 0x61, +0x76, 0x68, 0x75, 0x76, 0x68, 0x75, 0x3b, 0x47, 0x75, 0x6e, 0x79, 0x61, 0x6e, 0x61, 0x3b, 0x47, 0x75, 0x6d, 0x69, 0x67, +0x75, 0x72, 0x75, 0x3b, 0x4d, 0x62, 0x75, 0x64, 0x7a, 0x69, 0x3b, 0x5a, 0x76, 0x69, 0x74, 0x61, 0x3b, 0x4e, 0x3b, 0x4b, +0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x4e, 0x3b, 0x47, 0x3b, 0x47, 0x3b, 0x4d, 0x3b, 0x5a, +0x3b, 0x62c, 0x646, 0x648, 0x631, 0x64a, 0x3b, 0x641, 0x64a, 0x628, 0x631, 0x648, 0x631, 0x64a, 0x3b, 0x645, 0x627, 0x631, 0x686, 0x3b, +0x627, 0x67e, 0x631, 0x64a, 0x644, 0x3b, 0x645, 0x626, 0x64a, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648, 0x644, 0x627, 0x621, 0x650, +0x3b, 0x622, 0x6af, 0x633, 0x67d, 0x3b, 0x633, 0x64a, 0x67e, 0x67d, 0x645, 0x628, 0x631, 0x3b, 0x622, 0x6aa, 0x67d, 0x648, 0x628, 0x631, +0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x68a, 0x633, 0x645, 0x628, 0x631, 0x3b, 0xda2, 0xdb1, 0x3b, 0xdb4, 0xdd9, 0xdb6, 0x3b, +0xdb8, 0xdcf, 0xdbb, 0xdca, 0x3b, 0xd85, 0xdb4, 0xdca, 0x200d, 0xdbb, 0xdda, 0xdbd, 0xdca, 0x3b, 0xdb8, 0xdd0, 0xdba, 0xdd2, 0x3b, 0xda2, +0xdd6, 0xdb1, 0xdd2, 0x3b, 0xda2, 0xdd6, 0xdbd, 0xdd2, 0x3b, 0xd85, 0xd9c, 0xddd, 0x3b, 0xdc3, 0xdd0, 0xdb4, 0xdca, 0x3b, 0xd94, 0xd9a, +0xdca, 0x3b, 0xdb1, 0xddc, 0xdc0, 0xdd0, 0x3b, 0xdaf, 0xdd9, 0xdc3, 0xdd0, 0x3b, 0xda2, 0xdb1, 0xdc0, 0xdcf, 0xdbb, 0xdd2, 0x3b, 0xdb4, +0xdd9, 0xdb6, 0xdbb, 0xdc0, 0xdcf, 0xdbb, 0xdd2, 0x3b, 0xdb8, 0xdcf, 0xdbb, 0xdca, 0xdad, 0xdd4, 0x3b, 0xd85, 0xdb4, 0xdca, 0x200d, 0xdbb, +0xdda, 0xdbd, 0xdca, 0x3b, 0xdb8, 0xdd0, 0xdba, 0xdd2, 0x3b, 0xda2, 0xdd6, 0xdb1, 0xdd2, 0x3b, 0xda2, 0xdd6, 0xdbd, 0xdd2, 0x3b, 0xd85, +0xd9c, 0xddd, 0xdc3, 0xdca, 0xdad, 0xdd4, 0x3b, 0xdc3, 0xdd0, 0xdb4, 0xdca, 0xdad, 0xdd0, 0xdb8, 0xdca, 0xdb6, 0xdbb, 0xdca, 0x3b, 0xd94, +0xd9a, 0xdca, 0xdad, 0xddd, 0xdb6, 0xdbb, 0xdca, 0x3b, 0xdb1, 0xddc, 0xdc0, 0xdd0, 0xdb8, 0xdca, 0xdb6, 0xdbb, 0xdca, 0x3b, 0xdaf, 0xdd9, +0xdc3, 0xdd0, 0xdb8, 0xdca, 0xdb6, 0xdbb, 0xdca, 0x3b, 0xda2, 0x3b, 0xdb4, 0xdd9, 0x3b, 0xdb8, 0xdcf, 0x3b, 0xd85, 0x3b, 0xdb8, 0xdd0, +0x3b, 0xda2, 0xdd6, 0x3b, 0xda2, 0xdd6, 0x3b, 0xd85, 0x3b, 0xdc3, 0xdd0, 0x3b, 0xd94, 0x3b, 0xdb1, 0xdd9, 0x3b, 0xdaf, 0xdd9, 0x3b, +0xda2, 0xdb1, 0x3b, 0xdb4, 0xdd9, 0xdb6, 0x3b, 0xdb8, 0xdcf, 0xdbb, 0xdca, 0xdad, 0xdd4, 0x3b, 0xd85, 0xdb4, 0xdca, 0x200d, 0xdbb, 0xdda, +0xdbd, 0xdca, 0x3b, 0xdb8, 0xdd0, 0xdba, 0xdd2, 0x3b, 0xda2, 0xdd6, 0xdb1, 0xdd2, 0x3b, 0xda2, 0xdd6, 0xdbd, 0xdd2, 0x3b, 0xd85, 0xd9c, +0xddd, 0x3b, 0xdc3, 0xdd0, 0xdb4, 0xdca, 0x3b, 0xd94, 0xd9a, 0xdca, 0x3b, 0xdb1, 0xddc, 0xdc0, 0xdd0, 0x3b, 0xdaf, 0xdd9, 0xdc3, 0xdd0, +0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0xe1, 0x6a, +0x3b, 0x6a, 0xfa, 0x6e, 0x3b, 0x6a, 0xfa, 0x6c, 0x3b, 0x61, 0x75, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, +0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0xe1, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, +0x75, 0xe1, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x65, 0x63, 0x3b, 0x61, 0x70, 0x72, 0xed, 0x6c, 0x3b, 0x6d, 0xe1, 0x6a, 0x3b, +0x6a, 0xfa, 0x6e, 0x3b, 0x6a, 0xfa, 0x6c, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, +0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0xf3, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, +0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0xe1, 0x72, 0x61, 0x3b, 0x66, +0x65, 0x62, 0x72, 0x75, 0xe1, 0x72, 0x61, 0x3b, 0x6d, 0x61, 0x72, 0x63, 0x61, 0x3b, 0x61, 0x70, 0x72, 0xed, 0x6c, 0x61, +0x3b, 0x6d, 0xe1, 0x6a, 0x61, 0x3b, 0x6a, 0xfa, 0x6e, 0x61, 0x3b, 0x6a, 0xfa, 0x6c, 0x61, 0x3b, 0x61, 0x75, 0x67, 0x75, +0x73, 0x74, 0x61, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x6f, 0x6b, 0x74, 0xf3, 0x62, 0x72, +0x61, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x61, 0x3b, +0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, +0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x76, 0x67, 0x2e, 0x3b, 0x73, +0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x6a, +0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x65, 0x63, 0x3b, +0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x6a, 0x3b, 0x6a, 0x75, 0x6c, 0x69, +0x6a, 0x3b, 0x61, 0x76, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, +0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, +0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72, +0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x4a, 0x75, 0x75, 0x6e, 0x3b, 0x4c, 0x75, 0x75, 0x6c, 0x69, 0x79, 0x6f, 0x3b, 0x4f, 0x67, +0x3b, 0x53, 0x65, 0x62, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x66, 0x3b, 0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, +0x6e, 0x61, 0x61, 0x79, 0x6f, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x61, 0x61, 0x79, 0x6f, 0x3b, 0x4d, 0x61, 0x61, 0x72, 0x73, +0x6f, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x4a, 0x75, 0x75, 0x6e, 0x3b, 0x4c, 0x75, +0x75, 0x6c, 0x69, 0x79, 0x6f, 0x3b, 0x4f, 0x67, 0x6f, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x62, 0x74, 0x65, 0x6d, 0x62, 0x61, +0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x3b, 0x4e, 0x6f, 0x66, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, +0x44, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, +0x3b, 0x4c, 0x3b, 0x4f, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4b, 0x6f, 0x62, 0x3b, 0x4c, 0x61, 0x62, +0x3b, 0x53, 0x61, 0x64, 0x3b, 0x41, 0x66, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x4a, 0x75, 0x75, 0x6e, 0x3b, 0x4c, 0x75, +0x75, 0x6c, 0x69, 0x79, 0x6f, 0x3b, 0x4f, 0x67, 0x3b, 0x53, 0x65, 0x62, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x4f, +0x6b, 0x74, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x3b, 0x4e, 0x6f, 0x66, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x44, 0x65, 0x63, +0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x4b, 0x6f, 0x6f, 0x62, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, +0x20, 0x4c, 0x61, 0x62, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x53, 0x61, 0x64, 0x64, 0x65, 0x78, +0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x41, 0x66, 0x72, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, +0x68, 0x61, 0x20, 0x53, 0x68, 0x61, 0x6e, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x4c, 0x69, 0x78, +0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x54, 0x6f, 0x64, 0x6f, 0x62, 0x61, 0x61, 0x64, 0x3b, 0x42, +0x69, 0x73, 0x68, 0x61, 0x20, 0x53, 0x69, 0x64, 0x65, 0x65, 0x64, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, +0x20, 0x53, 0x61, 0x67, 0x61, 0x61, 0x6c, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x54, 0x6f, 0x62, +0x6e, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x4b, 0x6f, 0x77, 0x20, 0x69, 0x79, 0x6f, 0x20, 0x54, +0x6f, 0x62, 0x6e, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x4c, 0x61, 0x62, 0x61, 0x20, 0x69, 0x79, +0x6f, 0x20, 0x54, 0x6f, 0x62, 0x6e, 0x61, 0x61, 0x64, 0x3b, 0x4b, 0x3b, 0x4c, 0x3b, 0x53, 0x3b, 0x41, 0x3b, 0x53, 0x3b, +0x4c, 0x3b, 0x54, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x4c, 0x3b, 0x65, 0x6e, 0x65, 0x2e, 0x3b, 0x66, +0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x79, 0x2e, 0x3b, 0x6a, +0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x67, 0x6f, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x69, 0x63, 0x2e, 0x3b, 0x65, 0x6e, 0x65, 0x72, 0x6f, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x65, 0x72, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x79, 0x6f, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x6f, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x6f, 0x3b, 0x61, 0x67, -0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x75, 0x62, -0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x69, 0x63, 0x69, 0x65, 0x6d, 0x62, -0x72, 0x65, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x63, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, -0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, -0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, -0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x69, -0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x41, 0x67, 0x6f, 0x73, -0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, -0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, -0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, -0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, -0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, -0x69, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x69, -0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, -0x73, 0x74, 0x69, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, -0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, -0x42f, 0x43d, 0x432, 0x430, 0x440, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x3b, 0x41c, 0x430, 0x440, 0x442, 0x3b, 0x410, 0x43f, -0x440, 0x435, 0x43b, 0x3b, 0x41c, 0x430, 0x439, 0x3b, 0x418, 0x44e, 0x43d, 0x3b, 0x418, 0x44e, 0x43b, 0x3b, 0x410, 0x432, 0x433, 0x443, -0x441, 0x442, 0x3b, 0x421, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x3b, 0x41e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x3b, 0x41d, 0x43e, -0x44f, 0x431, 0x440, 0x3b, 0x414, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x3b, 0xb9c, 0xba9, 0x2e, 0x3b, 0xbaa, 0xbbf, 0xbaa, 0xbcd, 0x2e, -0x3b, 0xbae, 0xbbe, 0xbb0, 0xbcd, 0x2e, 0x3b, 0xb8f, 0xbaa, 0xbcd, 0x2e, 0x3b, 0xbae, 0xbc7, 0x3b, 0xb9c, 0xbc2, 0xba9, 0xbcd, 0x3b, -0xb9c, 0xbc2, 0xbb2, 0xbc8, 0x3b, 0xb86, 0xb95, 0x2e, 0x3b, 0xb9a, 0xbc6, 0xbaa, 0xbcd, 0x2e, 0x3b, 0xb85, 0xb95, 0xbcd, 0x2e, 0x3b, -0xba8, 0xbb5, 0x2e, 0x3b, 0xb9f, 0xbbf, 0xb9a, 0x2e, 0x3b, 0xb9c, 0xba9, 0xbb5, 0xbb0, 0xbbf, 0x3b, 0xbaa, 0xbbf, 0xbaa, 0xbcd, 0xbb0, -0xbb5, 0xbb0, 0xbbf, 0x3b, 0xbae, 0xbbe, 0xbb0, 0xbcd, 0xb9a, 0xbcd, 0x3b, 0xb8f, 0xbaa, 0xbcd, 0xbb0, 0xbb2, 0xbcd, 0x3b, 0xbae, 0xbc7, -0x3b, 0xb9c, 0xbc2, 0xba9, 0xbcd, 0x3b, 0xb9c, 0xbc2, 0xbb2, 0xbc8, 0x3b, 0xb86, 0xb95, 0xbb8, 0xbcd, 0xb9f, 0xbcd, 0x3b, 0xb9a, 0xbc6, -0xbaa, 0xbcd, 0xb9f, 0xbae, 0xbcd, 0xbaa, 0xbb0, 0xbcd, 0x3b, 0xb85, 0xb95, 0xbcd, 0xb9f, 0xbcb, 0xbaa, 0xbb0, 0xbcd, 0x3b, 0xba8, 0xbb5, -0xbae, 0xbcd, 0xbaa, 0xbb0, 0xbcd, 0x3b, 0xb9f, 0xbbf, 0xb9a, 0xbae, 0xbcd, 0xbaa, 0xbb0, 0xbcd, 0x3b, 0xb9c, 0x3b, 0xbaa, 0xbbf, 0x3b, -0xbae, 0xbbe, 0x3b, 0xb8f, 0x3b, 0xbae, 0xbc7, 0x3b, 0xb9c, 0xbc2, 0x3b, 0xb9c, 0xbc2, 0x3b, 0xb86, 0x3b, 0xb9a, 0xbc6, 0x3b, 0xb85, -0x3b, 0xba8, 0x3b, 0xb9f, 0xbbf, 0x3b, 0x433, 0x44b, 0x439, 0x43d, 0x2e, 0x3b, 0x444, 0x435, 0x432, 0x2e, 0x3b, 0x43c, 0x430, 0x440, -0x2e, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x438, 0x44e, 0x43d, 0x44c, 0x3b, 0x438, 0x44e, 0x43b, 0x44c, -0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x44f, -0x431, 0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x2e, 0x3b, 0x433, 0x44b, 0x439, 0x43d, 0x432, 0x430, 0x440, 0x3b, 0x444, 0x435, 0x432, 0x440, -0x430, 0x43b, 0x44c, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x435, 0x43b, 0x44c, 0x3b, 0x43c, 0x430, 0x439, 0x3b, -0x438, 0x44e, 0x43d, 0x44c, 0x3b, 0x438, 0x44e, 0x43b, 0x44c, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, 0x43d, -0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x43e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x440, 0x44c, -0x3b, 0x434, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x44c, 0x3b, 0xc1c, 0xc28, 0x3b, 0xc2b, 0xc3f, 0xc2c, 0xc4d, 0xc30, 0x3b, 0xc2e, 0xc3e, -0xc30, 0xc4d, 0xc1a, 0xc3f, 0x3b, 0xc0f, 0xc2a, 0xc4d, 0xc30, 0xc3f, 0x3b, 0xc2e, 0xc47, 0x3b, 0xc1c, 0xc42, 0xc28, 0xc4d, 0x3b, 0xc1c, -0xc41, 0xc32, 0xc48, 0x3b, 0xc06, 0xc17, 0x3b, 0xc38, 0xc46, 0xc2a, 0xc4d, 0xc1f, 0xc46, 0xc02, 0x3b, 0xc05, 0xc15, 0xc4d, 0xc1f, 0xc4b, -0x3b, 0xc28, 0xc35, 0xc02, 0x3b, 0xc21, 0xc3f, 0xc38, 0xc46, 0xc02, 0x3b, 0xc1c, 0xc28, 0xc35, 0xc30, 0xc3f, 0x3b, 0xc2b, 0xc3f, 0xc2c, -0xc4d, 0xc30, 0xc35, 0xc30, 0xc3f, 0x3b, 0xc2e, 0xc3e, 0xc30, 0xc4d, 0xc1a, 0xc3f, 0x3b, 0xc0f, 0xc2a, 0xc4d, 0xc30, 0xc3f, 0xc32, 0xc4d, -0x3b, 0xc2e, 0xc47, 0x3b, 0xc1c, 0xc42, 0xc28, 0xc4d, 0x3b, 0xc1c, 0xc41, 0xc32, 0xc48, 0x3b, 0xc06, 0xc17, 0xc38, 0xc4d, 0xc1f, 0xc41, -0x3b, 0xc38, 0xc46, 0xc2a, 0xc4d, 0xc1f, 0xc46, 0xc02, 0xc2c, 0xc30, 0xc4d, 0x3b, 0xc05, 0xc15, 0xc4d, 0xc1f, 0xc4b, 0xc2c, 0xc30, 0xc4d, -0x3b, 0xc28, 0xc35, 0xc02, 0xc2c, 0xc30, 0xc4d, 0x3b, 0xc21, 0xc3f, 0xc38, 0xc46, 0xc02, 0xc2c, 0xc30, 0xc4d, 0x3b, 0xc1c, 0x3b, 0xc2b, -0xc3f, 0x3b, 0xc2e, 0xc3e, 0x3b, 0xc0f, 0x3b, 0xc2e, 0xc47, 0x3b, 0xc1c, 0xc42, 0x3b, 0xc1c, 0xc41, 0x3b, 0xc06, 0x3b, 0xc38, 0xc46, -0x3b, 0xc05, 0x3b, 0xc28, 0x3b, 0xc21, 0xc3f, 0x3b, 0xe21, 0x2e, 0xe04, 0x2e, 0x3b, 0xe01, 0x2e, 0xe1e, 0x2e, 0x3b, 0xe21, 0xe35, -0x2e, 0xe04, 0x2e, 0x3b, 0xe40, 0xe21, 0x2e, 0xe22, 0x2e, 0x3b, 0xe1e, 0x2e, 0xe04, 0x2e, 0x3b, 0xe21, 0xe34, 0x2e, 0xe22, 0x2e, -0x3b, 0xe01, 0x2e, 0xe04, 0x2e, 0x3b, 0xe2a, 0x2e, 0xe04, 0x2e, 0x3b, 0xe01, 0x2e, 0xe22, 0x2e, 0x3b, 0xe15, 0x2e, 0xe04, 0x2e, -0x3b, 0xe1e, 0x2e, 0xe22, 0x2e, 0x3b, 0xe18, 0x2e, 0xe04, 0x2e, 0x3b, 0xe21, 0xe01, 0xe23, 0xe32, 0xe04, 0xe21, 0x3b, 0xe01, 0xe38, -0xe21, 0xe20, 0xe32, 0xe1e, 0xe31, 0xe19, 0xe18, 0xe4c, 0x3b, 0xe21, 0xe35, 0xe19, 0xe32, 0xe04, 0xe21, 0x3b, 0xe40, 0xe21, 0xe29, 0xe32, -0xe22, 0xe19, 0x3b, 0xe1e, 0xe24, 0xe29, 0xe20, 0xe32, 0xe04, 0xe21, 0x3b, 0xe21, 0xe34, 0xe16, 0xe38, 0xe19, 0xe32, 0xe22, 0xe19, 0x3b, -0xe01, 0xe23, 0xe01, 0xe0e, 0xe32, 0xe04, 0xe21, 0x3b, 0xe2a, 0xe34, 0xe07, 0xe2b, 0xe32, 0xe04, 0xe21, 0x3b, 0xe01, 0xe31, 0xe19, 0xe22, -0xe32, 0xe22, 0xe19, 0x3b, 0xe15, 0xe38, 0xe25, 0xe32, 0xe04, 0xe21, 0x3b, 0xe1e, 0xe24, 0xe28, 0xe08, 0xe34, 0xe01, 0xe32, 0xe22, 0xe19, -0x3b, 0xe18, 0xe31, 0xe19, 0xe27, 0xe32, 0xe04, 0xe21, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf51, 0xf44, 0xf0b, 0xf54, 0xf7c, 0xf0b, -0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf42, -0xf66, 0xf74, 0xf58, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf5e, 0xf72, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, -0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf63, 0xf94, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf51, 0xfb2, 0xf74, 0xf42, 0xf0b, -0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf51, 0xf74, 0xf53, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, -0xf0b, 0xf56, 0xf62, 0xf92, 0xfb1, 0xf51, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf51, 0xf42, 0xf74, 0xf0b, 0xf54, -0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, -0xf45, 0xf74, 0xf0b, 0xf42, 0xf45, 0xf72, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, -0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf51, 0xf44, 0xf0b, 0xf54, 0xf7c, 0x3b, 0xf5f, -0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf42, 0xf66, 0xf74, 0xf58, -0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf5e, 0xf72, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf63, -0xf94, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf51, 0xfb2, 0xf74, 0xf42, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, -0xf0b, 0xf56, 0xf51, 0xf74, 0xf53, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf62, 0xf92, 0xfb1, 0xf51, 0xf0b, 0xf54, -0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf51, 0xf42, 0xf74, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf45, 0xf74, -0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf45, 0xf72, 0xf42, 0xf0b, 0xf54, 0x3b, 0xf5f, -0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0x3b, 0x1325, 0x122a, 0x3b, 0x1208, 0x12ab, -0x3b, 0x1218, 0x130b, 0x3b, 0x121a, 0x12eb, 0x3b, 0x130d, 0x1295, 0x3b, 0x1230, 0x1290, 0x3b, 0x1213, 0x121d, 0x3b, 0x1290, 0x1213, 0x3b, 0x1218, -0x1235, 0x3b, 0x1325, 0x1245, 0x3b, 0x1215, 0x12f3, 0x3b, 0x1273, 0x1215, 0x3b, 0x1325, 0x122a, 0x3b, 0x1208, 0x12ab, 0x1272, 0x1275, 0x3b, 0x1218, -0x130b, 0x1262, 0x1275, 0x3b, 0x121a, 0x12eb, 0x12dd, 0x12eb, 0x3b, 0x130d, 0x1295, 0x1266, 0x1275, 0x3b, 0x1230, 0x1290, 0x3b, 0x1213, 0x121d, 0x1208, -0x3b, 0x1290, 0x1213, 0x1230, 0x3b, 0x1218, 0x1235, 0x12a8, 0x1228, 0x121d, 0x3b, 0x1325, 0x1245, 0x121d, 0x1272, 0x3b, 0x1215, 0x12f3, 0x122d, 0x3b, -0x1273, 0x1215, 0x1233, 0x1235, 0x3b, 0x1325, 0x3b, 0x1208, 0x3b, 0x1218, 0x3b, 0x121a, 0x3b, 0x130d, 0x3b, 0x1230, 0x3b, 0x1213, 0x3b, 0x1290, -0x3b, 0x1218, 0x3b, 0x1325, 0x3b, 0x1215, 0x3b, 0x1273, 0x3b, 0x53, 0x101, 0x6e, 0x3b, 0x46, 0x113, 0x70, 0x3b, 0x4d, 0x61, 0x2bb, -0x61, 0x3b, 0x2bb, 0x45, 0x70, 0x65, 0x3b, 0x4d, 0x113, 0x3b, 0x53, 0x75, 0x6e, 0x3b, 0x53, 0x69, 0x75, 0x3b, 0x2bb, 0x41, -0x6f, 0x6b, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x2bb, 0x4f, 0x6b, 0x61, 0x3b, 0x4e, 0x14d, 0x76, 0x3b, 0x54, 0x12b, 0x73, 0x3b, -0x53, 0x101, 0x6e, 0x75, 0x61, 0x6c, 0x69, 0x3b, 0x46, 0x113, 0x70, 0x75, 0x65, 0x6c, 0x69, 0x3b, 0x4d, 0x61, 0x2bb, 0x61, -0x73, 0x69, 0x3b, 0x2bb, 0x45, 0x70, 0x65, 0x6c, 0x65, 0x6c, 0x69, 0x3b, 0x4d, 0x113, 0x3b, 0x53, 0x75, 0x6e, 0x65, 0x3b, -0x53, 0x69, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x2bb, 0x41, 0x6f, 0x6b, 0x6f, 0x73, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x69, 0x74, -0x65, 0x6d, 0x61, 0x3b, 0x2bb, 0x4f, 0x6b, 0x61, 0x74, 0x6f, 0x70, 0x61, 0x3b, 0x4e, 0x14d, 0x76, 0x65, 0x6d, 0x61, 0x3b, -0x54, 0x12b, 0x73, 0x65, 0x6d, 0x61, 0x3b, 0x53, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x53, -0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x4f, 0x63, 0x61, 0x3b, 0x15e, 0x75, 0x62, 0x3b, 0x4d, -0x61, 0x72, 0x3b, 0x4e, 0x69, 0x73, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x48, 0x61, 0x7a, 0x3b, 0x54, 0x65, 0x6d, 0x3b, 0x41, -0x11f, 0x75, 0x3b, 0x45, 0x79, 0x6c, 0x3b, 0x45, 0x6b, 0x69, 0x3b, 0x4b, 0x61, 0x73, 0x3b, 0x41, 0x72, 0x61, 0x3b, 0x4f, -0x63, 0x61, 0x6b, 0x3b, 0x15e, 0x75, 0x62, 0x61, 0x74, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x3b, 0x4e, 0x69, 0x73, 0x61, 0x6e, -0x3b, 0x4d, 0x61, 0x79, 0x131, 0x73, 0x3b, 0x48, 0x61, 0x7a, 0x69, 0x72, 0x61, 0x6e, 0x3b, 0x54, 0x65, 0x6d, 0x6d, 0x75, -0x7a, 0x3b, 0x41, 0x11f, 0x75, 0x73, 0x74, 0x6f, 0x73, 0x3b, 0x45, 0x79, 0x6c, 0xfc, 0x6c, 0x3b, 0x45, 0x6b, 0x69, 0x6d, -0x3b, 0x4b, 0x61, 0x73, 0x131, 0x6d, 0x3b, 0x41, 0x72, 0x61, 0x6c, 0x131, 0x6b, 0x3b, 0x4f, 0x3b, 0x15e, 0x3b, 0x4d, 0x3b, -0x4e, 0x3b, 0x4d, 0x3b, 0x48, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x45, 0x3b, 0x45, 0x3b, 0x4b, 0x3b, 0x41, 0x3b, 0xdd, 0x61, -0x6e, 0x3b, 0x46, 0x65, 0x77, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0xfd, 0x3b, 0x49, +0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x75, +0x62, 0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x69, 0x63, 0x69, 0x65, 0x6d, +0x62, 0x72, 0x65, 0x3b, 0x45, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, +0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x65, 0x6e, 0x65, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, +0x72, 0x2e, 0x3b, 0x61, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x79, 0x2e, 0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, +0x6c, 0x2e, 0x3b, 0x61, 0x67, 0x6f, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, +0x76, 0x2e, 0x3b, 0x64, 0x69, 0x63, 0x2e, 0x3b, 0x65, 0x6e, 0x65, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, +0x61, 0x62, 0x72, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x67, 0x6f, 0x3b, +0x73, 0x65, 0x70, 0x3b, 0x6f, 0x63, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x69, 0x63, 0x3b, 0x45, 0x6e, 0x65, 0x2e, +0x3b, 0x46, 0x65, 0x62, 0x2e, 0x3b, 0x4d, 0x61, 0x72, 0x2e, 0x3b, 0x41, 0x62, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x79, 0x2e, +0x3b, 0x4a, 0x75, 0x6e, 0x2e, 0x3b, 0x4a, 0x75, 0x6c, 0x2e, 0x3b, 0x41, 0x67, 0x6f, 0x2e, 0x3b, 0x53, 0x65, 0x74, 0x2e, +0x3b, 0x4f, 0x63, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x69, 0x63, 0x2e, 0x3b, 0x65, 0x6e, 0x65, 0x2e, +0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x79, 0x2e, +0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x67, 0x6f, 0x2e, 0x3b, 0x73, 0x65, 0x74, 0x2e, +0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x69, 0x63, 0x2e, 0x3b, 0x65, 0x6e, 0x65, 0x72, +0x6f, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x65, 0x72, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x61, 0x62, 0x72, 0x69, +0x6c, 0x3b, 0x6d, 0x61, 0x79, 0x6f, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x6f, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x6f, 0x3b, 0x61, +0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x75, +0x62, 0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x69, 0x63, 0x69, 0x65, 0x6d, +0x62, 0x72, 0x65, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x63, 0x3b, 0x41, 0x70, 0x72, 0x3b, +0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x70, 0x3b, +0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, +0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, +0x69, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x41, 0x67, 0x6f, +0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, +0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, +0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, +0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, +0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, +0x72, 0x69, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, +0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, +0x75, 0x73, 0x74, 0x69, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, +0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, +0x3b, 0x42f, 0x43d, 0x432, 0x430, 0x440, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x3b, 0x41c, 0x430, 0x440, 0x442, 0x3b, 0x410, +0x43f, 0x440, 0x435, 0x43b, 0x3b, 0x41c, 0x430, 0x439, 0x3b, 0x418, 0x44e, 0x43d, 0x3b, 0x418, 0x44e, 0x43b, 0x3b, 0x410, 0x432, 0x433, +0x443, 0x441, 0x442, 0x3b, 0x421, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x3b, 0x41e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x3b, 0x41d, +0x43e, 0x44f, 0x431, 0x440, 0x3b, 0x414, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x3b, 0xb9c, 0xba9, 0x2e, 0x3b, 0xbaa, 0xbbf, 0xbaa, 0xbcd, +0x2e, 0x3b, 0xbae, 0xbbe, 0xbb0, 0xbcd, 0x2e, 0x3b, 0xb8f, 0xbaa, 0xbcd, 0x2e, 0x3b, 0xbae, 0xbc7, 0x3b, 0xb9c, 0xbc2, 0xba9, 0xbcd, +0x3b, 0xb9c, 0xbc2, 0xbb2, 0xbc8, 0x3b, 0xb86, 0xb95, 0x2e, 0x3b, 0xb9a, 0xbc6, 0xbaa, 0xbcd, 0x2e, 0x3b, 0xb85, 0xb95, 0xbcd, 0x2e, +0x3b, 0xba8, 0xbb5, 0x2e, 0x3b, 0xb9f, 0xbbf, 0xb9a, 0x2e, 0x3b, 0xb9c, 0xba9, 0xbb5, 0xbb0, 0xbbf, 0x3b, 0xbaa, 0xbbf, 0xbaa, 0xbcd, +0xbb0, 0xbb5, 0xbb0, 0xbbf, 0x3b, 0xbae, 0xbbe, 0xbb0, 0xbcd, 0xb9a, 0xbcd, 0x3b, 0xb8f, 0xbaa, 0xbcd, 0xbb0, 0xbb2, 0xbcd, 0x3b, 0xbae, +0xbc7, 0x3b, 0xb9c, 0xbc2, 0xba9, 0xbcd, 0x3b, 0xb9c, 0xbc2, 0xbb2, 0xbc8, 0x3b, 0xb86, 0xb95, 0xbb8, 0xbcd, 0xb9f, 0xbcd, 0x3b, 0xb9a, +0xbc6, 0xbaa, 0xbcd, 0xb9f, 0xbae, 0xbcd, 0xbaa, 0xbb0, 0xbcd, 0x3b, 0xb85, 0xb95, 0xbcd, 0xb9f, 0xbcb, 0xbaa, 0xbb0, 0xbcd, 0x3b, 0xba8, +0xbb5, 0xbae, 0xbcd, 0xbaa, 0xbb0, 0xbcd, 0x3b, 0xb9f, 0xbbf, 0xb9a, 0xbae, 0xbcd, 0xbaa, 0xbb0, 0xbcd, 0x3b, 0xb9c, 0x3b, 0xbaa, 0xbbf, +0x3b, 0xbae, 0xbbe, 0x3b, 0xb8f, 0x3b, 0xbae, 0xbc7, 0x3b, 0xb9c, 0xbc2, 0x3b, 0xb9c, 0xbc2, 0x3b, 0xb86, 0x3b, 0xb9a, 0xbc6, 0x3b, +0xb85, 0x3b, 0xba8, 0x3b, 0xb9f, 0xbbf, 0x3b, 0x433, 0x44b, 0x439, 0x43d, 0x2e, 0x3b, 0x444, 0x435, 0x432, 0x2e, 0x3b, 0x43c, 0x430, +0x440, 0x2e, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x438, 0x44e, 0x43d, 0x44c, 0x3b, 0x438, 0x44e, 0x43b, +0x44c, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, +0x44f, 0x431, 0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x2e, 0x3b, 0x433, 0x44b, 0x439, 0x43d, 0x432, 0x430, 0x440, 0x3b, 0x444, 0x435, 0x432, +0x440, 0x430, 0x43b, 0x44c, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x435, 0x43b, 0x44c, 0x3b, 0x43c, 0x430, 0x439, +0x3b, 0x438, 0x44e, 0x43d, 0x44c, 0x3b, 0x438, 0x44e, 0x43b, 0x44c, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, +0x43d, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x43e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x440, +0x44c, 0x3b, 0x434, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x44c, 0x3b, 0xc1c, 0xc28, 0x3b, 0xc2b, 0xc3f, 0xc2c, 0xc4d, 0xc30, 0x3b, 0xc2e, +0xc3e, 0xc30, 0xc4d, 0xc1a, 0xc3f, 0x3b, 0xc0f, 0xc2a, 0xc4d, 0xc30, 0xc3f, 0x3b, 0xc2e, 0xc47, 0x3b, 0xc1c, 0xc42, 0xc28, 0xc4d, 0x3b, +0xc1c, 0xc41, 0xc32, 0xc48, 0x3b, 0xc06, 0xc17, 0x3b, 0xc38, 0xc46, 0xc2a, 0xc4d, 0xc1f, 0xc46, 0xc02, 0x3b, 0xc05, 0xc15, 0xc4d, 0xc1f, +0xc4b, 0x3b, 0xc28, 0xc35, 0xc02, 0x3b, 0xc21, 0xc3f, 0xc38, 0xc46, 0xc02, 0x3b, 0xc1c, 0xc28, 0xc35, 0xc30, 0xc3f, 0x3b, 0xc2b, 0xc3f, +0xc2c, 0xc4d, 0xc30, 0xc35, 0xc30, 0xc3f, 0x3b, 0xc2e, 0xc3e, 0xc30, 0xc4d, 0xc1a, 0xc3f, 0x3b, 0xc0f, 0xc2a, 0xc4d, 0xc30, 0xc3f, 0xc32, +0xc4d, 0x3b, 0xc2e, 0xc47, 0x3b, 0xc1c, 0xc42, 0xc28, 0xc4d, 0x3b, 0xc1c, 0xc41, 0xc32, 0xc48, 0x3b, 0xc06, 0xc17, 0xc38, 0xc4d, 0xc1f, +0xc41, 0x3b, 0xc38, 0xc46, 0xc2a, 0xc4d, 0xc1f, 0xc46, 0xc02, 0xc2c, 0xc30, 0xc4d, 0x3b, 0xc05, 0xc15, 0xc4d, 0xc1f, 0xc4b, 0xc2c, 0xc30, +0xc4d, 0x3b, 0xc28, 0xc35, 0xc02, 0xc2c, 0xc30, 0xc4d, 0x3b, 0xc21, 0xc3f, 0xc38, 0xc46, 0xc02, 0xc2c, 0xc30, 0xc4d, 0x3b, 0xc1c, 0x3b, +0xc2b, 0xc3f, 0x3b, 0xc2e, 0xc3e, 0x3b, 0xc0f, 0x3b, 0xc2e, 0xc47, 0x3b, 0xc1c, 0xc42, 0x3b, 0xc1c, 0xc41, 0x3b, 0xc06, 0x3b, 0xc38, +0xc46, 0x3b, 0xc05, 0x3b, 0xc28, 0x3b, 0xc21, 0xc3f, 0x3b, 0xe21, 0x2e, 0xe04, 0x2e, 0x3b, 0xe01, 0x2e, 0xe1e, 0x2e, 0x3b, 0xe21, +0xe35, 0x2e, 0xe04, 0x2e, 0x3b, 0xe40, 0xe21, 0x2e, 0xe22, 0x2e, 0x3b, 0xe1e, 0x2e, 0xe04, 0x2e, 0x3b, 0xe21, 0xe34, 0x2e, 0xe22, +0x2e, 0x3b, 0xe01, 0x2e, 0xe04, 0x2e, 0x3b, 0xe2a, 0x2e, 0xe04, 0x2e, 0x3b, 0xe01, 0x2e, 0xe22, 0x2e, 0x3b, 0xe15, 0x2e, 0xe04, +0x2e, 0x3b, 0xe1e, 0x2e, 0xe22, 0x2e, 0x3b, 0xe18, 0x2e, 0xe04, 0x2e, 0x3b, 0xe21, 0xe01, 0xe23, 0xe32, 0xe04, 0xe21, 0x3b, 0xe01, +0xe38, 0xe21, 0xe20, 0xe32, 0xe1e, 0xe31, 0xe19, 0xe18, 0xe4c, 0x3b, 0xe21, 0xe35, 0xe19, 0xe32, 0xe04, 0xe21, 0x3b, 0xe40, 0xe21, 0xe29, +0xe32, 0xe22, 0xe19, 0x3b, 0xe1e, 0xe24, 0xe29, 0xe20, 0xe32, 0xe04, 0xe21, 0x3b, 0xe21, 0xe34, 0xe16, 0xe38, 0xe19, 0xe32, 0xe22, 0xe19, +0x3b, 0xe01, 0xe23, 0xe01, 0xe0e, 0xe32, 0xe04, 0xe21, 0x3b, 0xe2a, 0xe34, 0xe07, 0xe2b, 0xe32, 0xe04, 0xe21, 0x3b, 0xe01, 0xe31, 0xe19, +0xe22, 0xe32, 0xe22, 0xe19, 0x3b, 0xe15, 0xe38, 0xe25, 0xe32, 0xe04, 0xe21, 0x3b, 0xe1e, 0xe24, 0xe28, 0xe08, 0xe34, 0xe01, 0xe32, 0xe22, +0xe19, 0x3b, 0xe18, 0xe31, 0xe19, 0xe27, 0xe32, 0xe04, 0xe21, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf51, 0xf44, 0xf0b, 0xf54, 0xf7c, +0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, +0xf42, 0xf66, 0xf74, 0xf58, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf5e, 0xf72, 0xf0b, 0xf54, 0xf0b, 0x3b, +0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf63, 0xf94, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf51, 0xfb2, 0xf74, 0xf42, +0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf51, 0xf74, 0xf53, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, +0xf56, 0xf0b, 0xf56, 0xf62, 0xf92, 0xfb1, 0xf51, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf51, 0xf42, 0xf74, 0xf0b, +0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, +0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf45, 0xf72, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf45, 0xf74, +0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf51, 0xf44, 0xf0b, 0xf54, 0xf7c, 0x3b, +0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf42, 0xf66, 0xf74, +0xf58, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf5e, 0xf72, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, +0xf63, 0xf94, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf51, 0xfb2, 0xf74, 0xf42, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, +0xf56, 0xf0b, 0xf56, 0xf51, 0xf74, 0xf53, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf62, 0xf92, 0xfb1, 0xf51, 0xf0b, +0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf51, 0xf42, 0xf74, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf45, +0xf74, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf45, 0xf72, 0xf42, 0xf0b, 0xf54, 0x3b, +0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0x3b, 0x1325, 0x122a, 0x3b, 0x1208, +0x12ab, 0x3b, 0x1218, 0x130b, 0x3b, 0x121a, 0x12eb, 0x3b, 0x130d, 0x1295, 0x3b, 0x1230, 0x1290, 0x3b, 0x1213, 0x121d, 0x3b, 0x1290, 0x1213, 0x3b, +0x1218, 0x1235, 0x3b, 0x1325, 0x1245, 0x3b, 0x1215, 0x12f3, 0x3b, 0x1273, 0x1215, 0x3b, 0x1325, 0x122a, 0x3b, 0x1208, 0x12ab, 0x1272, 0x1275, 0x3b, +0x1218, 0x130b, 0x1262, 0x1275, 0x3b, 0x121a, 0x12eb, 0x12dd, 0x12eb, 0x3b, 0x130d, 0x1295, 0x1266, 0x1275, 0x3b, 0x1230, 0x1290, 0x3b, 0x1213, 0x121d, +0x1208, 0x3b, 0x1290, 0x1213, 0x1230, 0x3b, 0x1218, 0x1235, 0x12a8, 0x1228, 0x121d, 0x3b, 0x1325, 0x1245, 0x121d, 0x1272, 0x3b, 0x1215, 0x12f3, 0x122d, +0x3b, 0x1273, 0x1215, 0x1233, 0x1235, 0x3b, 0x1325, 0x3b, 0x1208, 0x3b, 0x1218, 0x3b, 0x121a, 0x3b, 0x130d, 0x3b, 0x1230, 0x3b, 0x1213, 0x3b, +0x1290, 0x3b, 0x1218, 0x3b, 0x1325, 0x3b, 0x1215, 0x3b, 0x1273, 0x3b, 0x53, 0x101, 0x6e, 0x3b, 0x46, 0x113, 0x70, 0x3b, 0x4d, 0x61, +0x2bb, 0x61, 0x3b, 0x2bb, 0x45, 0x70, 0x65, 0x3b, 0x4d, 0x113, 0x3b, 0x53, 0x75, 0x6e, 0x3b, 0x53, 0x69, 0x75, 0x3b, 0x2bb, +0x41, 0x6f, 0x6b, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x2bb, 0x4f, 0x6b, 0x61, 0x3b, 0x4e, 0x14d, 0x76, 0x3b, 0x54, 0x12b, 0x73, +0x3b, 0x53, 0x101, 0x6e, 0x75, 0x61, 0x6c, 0x69, 0x3b, 0x46, 0x113, 0x70, 0x75, 0x65, 0x6c, 0x69, 0x3b, 0x4d, 0x61, 0x2bb, +0x61, 0x73, 0x69, 0x3b, 0x2bb, 0x45, 0x70, 0x65, 0x6c, 0x65, 0x6c, 0x69, 0x3b, 0x4d, 0x113, 0x3b, 0x53, 0x75, 0x6e, 0x65, +0x3b, 0x53, 0x69, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x2bb, 0x41, 0x6f, 0x6b, 0x6f, 0x73, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x69, +0x74, 0x65, 0x6d, 0x61, 0x3b, 0x2bb, 0x4f, 0x6b, 0x61, 0x74, 0x6f, 0x70, 0x61, 0x3b, 0x4e, 0x14d, 0x76, 0x65, 0x6d, 0x61, +0x3b, 0x54, 0x12b, 0x73, 0x65, 0x6d, 0x61, 0x3b, 0x53, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, +0x53, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x4f, 0x63, 0x61, 0x3b, 0x15e, 0x75, 0x62, 0x3b, +0x4d, 0x61, 0x72, 0x3b, 0x4e, 0x69, 0x73, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x48, 0x61, 0x7a, 0x3b, 0x54, 0x65, 0x6d, 0x3b, +0x41, 0x11f, 0x75, 0x3b, 0x45, 0x79, 0x6c, 0x3b, 0x45, 0x6b, 0x69, 0x3b, 0x4b, 0x61, 0x73, 0x3b, 0x41, 0x72, 0x61, 0x3b, +0x4f, 0x63, 0x61, 0x6b, 0x3b, 0x15e, 0x75, 0x62, 0x61, 0x74, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x3b, 0x4e, 0x69, 0x73, 0x61, +0x6e, 0x3b, 0x4d, 0x61, 0x79, 0x131, 0x73, 0x3b, 0x48, 0x61, 0x7a, 0x69, 0x72, 0x61, 0x6e, 0x3b, 0x54, 0x65, 0x6d, 0x6d, +0x75, 0x7a, 0x3b, 0x41, 0x11f, 0x75, 0x73, 0x74, 0x6f, 0x73, 0x3b, 0x45, 0x79, 0x6c, 0xfc, 0x6c, 0x3b, 0x45, 0x6b, 0x69, +0x6d, 0x3b, 0x4b, 0x61, 0x73, 0x131, 0x6d, 0x3b, 0x41, 0x72, 0x61, 0x6c, 0x131, 0x6b, 0x3b, 0x4f, 0x3b, 0x15e, 0x3b, 0x4d, +0x3b, 0x4e, 0x3b, 0x4d, 0x3b, 0x48, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x45, 0x3b, 0x45, 0x3b, 0x4b, 0x3b, 0x41, 0x3b, 0xdd, +0x61, 0x6e, 0x3b, 0x46, 0x65, 0x77, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0xfd, 0x3b, 0x49, 0xfd, 0x75, 0x6e, 0x3b, 0x49, 0xfd, 0x75, 0x6c, 0x3b, 0x41, 0x77, 0x67, 0x3b, 0x53, 0x65, 0x6e, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0xfd, 0x3b, 0x44, 0x65, 0x6b, 0x3b, 0xdd, 0x61, 0x6e, 0x77, 0x61, 0x72, 0x3b, 0x46, 0x65, 0x77, 0x72, 0x61, 0x6c, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x3b, 0x41, 0x70, 0x72, 0x65, 0x6c, 0x3b, 0x4d, 0x61, 0xfd, 0x3b, 0x49, 0xfd, @@ -3118,804 +3174,814 @@ static const ushort months_data[] = { 0x65, 0x3b, 0x4d, 0x61, 0x72, 0x73, 0x3b, 0x41, 0x77, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x65, 0x3b, 0x53, 0x75, 0x77, 0x65, 0x3b, 0x53, 0x75, 0x6c, 0x65, 0x74, 0x3b, 0x55, 0x74, 0x3b, 0x53, 0xe0, 0x74, 0x74, 0x75, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x3b, 0x4e, 0x6f, 0x77, 0xe0, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x44, -0x65, 0x73, 0xe0, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x5d9, 0x5d0, 0x5b7, 0x5e0, 0x3b, 0x5e4, 0x5bf, 0x5e2, 0x5d1, 0x3b, 0x5de, 0x5e2, -0x5e8, 0x5e5, 0x3b, 0x5d0, 0x5b7, 0x5e4, 0x5bc, 0x5e8, 0x3b, 0x5de, 0x5d9, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5e0, 0x5d9, 0x3b, 0x5d9, 0x5d5, -0x5dc, 0x5d9, 0x3b, 0x5d0, 0x5d5, 0x5d9, 0x5d2, 0x3b, 0x5e1, 0x5e2, 0x5e4, 0x5bc, 0x3b, 0x5d0, 0x5e7, 0x5d8, 0x3b, 0x5e0, 0x5d0, 0x5d5, -0x5d5, 0x3b, 0x5d3, 0x5e2, 0x5e6, 0x3b, 0x5d9, 0x5d0, 0x5b7, 0x5e0, 0x5d5, 0x5d0, 0x5b7, 0x5e8, 0x3b, 0x5e4, 0x5bf, 0x5e2, 0x5d1, 0x5e8, -0x5d5, 0x5d0, 0x5b7, 0x5e8, 0x3b, 0x5de, 0x5e2, 0x5e8, 0x5e5, 0x3b, 0x5d0, 0x5b7, 0x5e4, 0x5bc, 0x5e8, 0x5d9, 0x5dc, 0x3b, 0x5de, 0x5d9, -0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5e0, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dc, 0x5d9, 0x3b, 0x5d0, 0x5d5, 0x5d9, 0x5d2, 0x5d5, 0x5e1, 0x5d8, 0x3b, -0x5e1, 0x5e2, 0x5e4, 0x5bc, 0x5d8, 0x5e2, 0x5de, 0x5d1, 0x5e2, 0x5e8, 0x3b, 0x5d0, 0x5e7, 0x5d8, 0x5d0, 0x5d1, 0x5e2, 0x5e8, 0x3b, 0x5e0, -0x5d0, 0x5d5, 0x5d5, 0x5e2, 0x5de, 0x5d1, 0x5e2, 0x5e8, 0x3b, 0x5d3, 0x5e2, 0x5e6, 0x5e2, 0x5de, 0x5d1, 0x5e2, 0x5e8, 0x3b, 0x1e62, 0x1eb9, -0x301, 0x72, 0x1eb9, 0x301, 0x3b, 0xc8, 0x72, 0xe8, 0x6c, 0xe8, 0x3b, 0x1eb8, 0x72, 0x1eb9, 0x300, 0x6e, 0xe0, 0x3b, 0xcc, 0x67, -0x62, 0xe9, 0x3b, 0x1eb8, 0x300, 0x62, 0x69, 0x62, 0x69, 0x3b, 0xd2, 0x6b, 0xfa, 0x64, 0x75, 0x3b, 0x41, 0x67, 0x1eb9, 0x6d, -0x1ecd, 0x3b, 0xd2, 0x67, 0xfa, 0x6e, 0x3b, 0x4f, 0x77, 0x65, 0x77, 0x65, 0x3b, 0x1ecc, 0x300, 0x77, 0xe0, 0x72, 0xe0, 0x3b, -0x42, 0xe9, 0x6c, 0xfa, 0x3b, 0x1ecc, 0x300, 0x70, 0x1eb9, 0x300, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1e62, 0x1eb9, 0x301, 0x72, 0x1eb9, -0x301, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xc8, 0x72, 0xe8, 0x6c, 0xe8, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1eb8, 0x72, 0x1eb9, 0x300, -0x6e, 0xe0, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xcc, 0x67, 0x62, 0xe9, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1eb8, 0x300, 0x62, 0x69, -0x62, 0x69, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xd2, 0x6b, 0xfa, 0x64, 0x75, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x41, 0x67, 0x1eb9, -0x6d, 0x1ecd, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xd2, 0x67, 0xfa, 0x6e, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x4f, 0x77, 0x65, 0x77, -0x65, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1ecc, 0x300, 0x77, 0xe0, 0x72, 0xe0, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x42, 0xe9, 0x6c, -0xfa, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1ecc, 0x300, 0x70, 0x1eb9, 0x300, 0x3b, 0x53, 0x68, 0x25b, 0x301, 0x72, 0x25b, 0x301, 0x3b, -0xc8, 0x72, 0xe8, 0x6c, 0xe8, 0x3b, 0x190, 0x72, 0x25b, 0x300, 0x6e, 0xe0, 0x3b, 0xcc, 0x67, 0x62, 0xe9, 0x3b, 0x190, 0x300, -0x62, 0x69, 0x62, 0x69, 0x3b, 0xd2, 0x6b, 0xfa, 0x64, 0x75, 0x3b, 0x41, 0x67, 0x25b, 0x6d, 0x254, 0x3b, 0xd2, 0x67, 0xfa, -0x6e, 0x3b, 0x4f, 0x77, 0x65, 0x77, 0x65, 0x3b, 0x186, 0x300, 0x77, 0xe0, 0x72, 0xe0, 0x3b, 0x42, 0xe9, 0x6c, 0xfa, 0x3b, -0x186, 0x300, 0x70, 0x25b, 0x300, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0x53, 0x68, 0x25b, 0x301, 0x72, 0x25b, 0x301, 0x3b, 0x4f, -0x73, 0x68, 0xf9, 0x20, 0xc8, 0x72, 0xe8, 0x6c, 0xe8, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0x190, 0x72, 0x25b, 0x300, 0x6e, -0xe0, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0xcc, 0x67, 0x62, 0xe9, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0x190, 0x300, 0x62, -0x69, 0x62, 0x69, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0xd2, 0x6b, 0xfa, 0x64, 0x75, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, -0x41, 0x67, 0x25b, 0x6d, 0x254, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0xd2, 0x67, 0xfa, 0x6e, 0x3b, 0x4f, 0x73, 0x68, 0xf9, -0x20, 0x4f, 0x77, 0x65, 0x77, 0x65, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0x186, 0x300, 0x77, 0xe0, 0x72, 0xe0, 0x3b, 0x4f, -0x73, 0x68, 0xf9, 0x20, 0x42, 0xe9, 0x6c, 0xfa, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0x186, 0x300, 0x70, 0x25b, 0x300, 0x3b, -0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x73, 0x3b, 0x45, 0x70, 0x68, 0x3b, 0x4d, 0x65, 0x79, 0x3b, -0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x61, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, -0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x77, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, -0x72, 0x75, 0x77, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x73, 0x68, 0x69, 0x3b, 0x45, 0x70, 0x68, 0x72, 0x65, 0x6c, 0x69, -0x3b, 0x4d, 0x65, 0x79, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x79, 0x69, 0x3b, 0x41, 0x67, -0x61, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x68, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x68, 0x6f, -0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4a, -0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, -0x3b, 0x44, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, -0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, -0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x73, -0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, -0x74, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, -0x69, 0x3b, 0x61, 0x76, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x6f, -0x6b, 0x74, 0x6f, 0x62, 0x61, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, -0x6d, 0x62, 0x61, 0x72, 0x3b, 0x458, 0x430, 0x43d, 0x3b, 0x444, 0x435, 0x431, 0x3b, 0x43c, 0x430, 0x440, 0x3b, 0x430, 0x43f, 0x440, -0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x3b, 0x458, 0x443, 0x43b, 0x3b, 0x430, 0x443, 0x433, 0x3b, 0x441, 0x435, 0x43f, -0x3b, 0x43e, 0x43a, 0x442, 0x3b, 0x43d, 0x43e, 0x432, 0x3b, 0x434, 0x435, 0x446, 0x3b, 0x458, 0x430, 0x43d, 0x443, 0x430, 0x440, 0x3b, -0x444, 0x435, 0x431, 0x440, 0x443, 0x430, 0x440, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b, 0x3b, 0x43c, -0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x438, 0x3b, 0x458, 0x443, 0x43b, 0x438, 0x3b, 0x430, 0x443, 0x433, 0x443, 0x441, 0x442, 0x3b, -0x441, 0x435, 0x43f, 0x442, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x431, 0x430, 0x440, 0x3b, 0x43d, 0x43e, -0x432, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x434, 0x435, 0x446, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x4a, 0x2d, 0x67, 0x75, -0x65, 0x72, 0x3b, 0x54, 0x2d, 0x61, 0x72, 0x72, 0x65, 0x65, 0x3b, 0x4d, 0x61, 0x79, 0x72, 0x6e, 0x74, 0x3b, 0x41, 0x76, -0x72, 0x72, 0x69, 0x6c, 0x3b, 0x42, 0x6f, 0x61, 0x6c, 0x64, 0x79, 0x6e, 0x3b, 0x4d, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x65, -0x65, 0x3b, 0x4a, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x65, 0x65, 0x3b, 0x4c, 0x75, 0x61, 0x6e, 0x69, 0x73, 0x74, 0x79, 0x6e, -0x3b, 0x4d, 0x2d, 0x66, 0x6f, 0x75, 0x79, 0x69, 0x72, 0x3b, 0x4a, 0x2d, 0x66, 0x6f, 0x75, 0x79, 0x69, 0x72, 0x3b, 0x4d, -0x2d, 0x48, 0x6f, 0x75, 0x6e, 0x65, 0x79, 0x3b, 0x4d, 0x2d, 0x4e, 0x6f, 0x6c, 0x6c, 0x69, 0x63, 0x6b, 0x3b, 0x4a, 0x65, -0x72, 0x72, 0x65, 0x79, 0x2d, 0x67, 0x65, 0x75, 0x72, 0x65, 0x65, 0x3b, 0x54, 0x6f, 0x73, 0x68, 0x69, 0x61, 0x67, 0x68, -0x74, 0x2d, 0x61, 0x72, 0x72, 0x65, 0x65, 0x3b, 0x4d, 0x61, 0x79, 0x72, 0x6e, 0x74, 0x3b, 0x41, 0x76, 0x65, 0x72, 0x69, -0x6c, 0x3b, 0x42, 0x6f, 0x61, 0x6c, 0x64, 0x79, 0x6e, 0x3b, 0x4d, 0x65, 0x61, 0x6e, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x65, -0x65, 0x3b, 0x4a, 0x65, 0x72, 0x72, 0x65, 0x79, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x65, 0x65, 0x3b, 0x4c, 0x75, 0x61, 0x6e, -0x69, 0x73, 0x74, 0x79, 0x6e, 0x3b, 0x4d, 0x65, 0x61, 0x6e, 0x2d, 0x66, 0x6f, 0x75, 0x79, 0x69, 0x72, 0x3b, 0x4a, 0x65, -0x72, 0x72, 0x65, 0x79, 0x2d, 0x66, 0x6f, 0x75, 0x79, 0x69, 0x72, 0x3b, 0x4d, 0x65, 0x65, 0x20, 0x48, 0x6f, 0x75, 0x6e, -0x65, 0x79, 0x3b, 0x4d, 0x65, 0x65, 0x20, 0x6e, 0x79, 0x20, 0x4e, 0x6f, 0x6c, 0x6c, 0x69, 0x63, 0x6b, 0x3b, 0x47, 0x65, -0x6e, 0x3b, 0x48, 0x77, 0x65, 0x3b, 0x4d, 0x65, 0x75, 0x3b, 0x45, 0x62, 0x72, 0x3b, 0x4d, 0x65, 0x3b, 0x4d, 0x65, 0x74, -0x3b, 0x47, 0x6f, 0x72, 0x3b, 0x45, 0x73, 0x74, 0x3b, 0x47, 0x77, 0x6e, 0x3b, 0x48, 0x65, 0x64, 0x3b, 0x44, 0x75, 0x3b, -0x4b, 0x65, 0x76, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x47, 0x65, 0x6e, 0x76, 0x65, 0x72, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x48, -0x77, 0x65, 0x76, 0x72, 0x65, 0x72, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x4d, 0x65, 0x75, 0x72, 0x74, 0x68, 0x3b, 0x6d, 0x69, -0x73, 0x20, 0x45, 0x62, 0x72, 0x65, 0x6c, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x4d, 0x65, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x4d, -0x65, 0x74, 0x68, 0x65, 0x76, 0x65, 0x6e, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x47, 0x6f, 0x72, 0x74, 0x68, 0x65, 0x72, 0x65, -0x6e, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x45, 0x73, 0x74, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x47, 0x77, 0x79, 0x6e, 0x6e, 0x67, -0x61, 0x6c, 0x61, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x48, 0x65, 0x64, 0x72, 0x61, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x44, 0x75, -0x3b, 0x6d, 0x69, 0x73, 0x20, 0x4b, 0x65, 0x76, 0x61, 0x72, 0x64, 0x68, 0x75, 0x3b, 0x53, 0x2d, 0x186, 0x3b, 0x4b, 0x2d, -0x186, 0x3b, 0x45, 0x2d, 0x186, 0x3b, 0x45, 0x2d, 0x4f, 0x3b, 0x45, 0x2d, 0x4b, 0x3b, 0x4f, 0x2d, 0x41, 0x3b, 0x41, 0x2d, -0x4b, 0x3b, 0x44, 0x2d, 0x186, 0x3b, 0x46, 0x2d, 0x190, 0x3b, 0x186, 0x2d, 0x41, 0x3b, 0x186, 0x2d, 0x4f, 0x3b, 0x4d, 0x2d, -0x186, 0x3b, 0x53, 0x61, 0x6e, 0x64, 0x61, 0x2d, 0x186, 0x70, 0x25b, 0x70, 0x254, 0x6e, 0x3b, 0x4b, 0x77, 0x61, 0x6b, 0x77, -0x61, 0x72, 0x2d, 0x186, 0x67, 0x79, 0x65, 0x66, 0x75, 0x6f, 0x3b, 0x45, 0x62, 0x254, 0x77, 0x2d, 0x186, 0x62, 0x65, 0x6e, -0x65, 0x6d, 0x3b, 0x45, 0x62, 0x254, 0x62, 0x69, 0x72, 0x61, 0x2d, 0x4f, 0x66, 0x6f, 0x72, 0x69, 0x73, 0x75, 0x6f, 0x3b, -0x45, 0x73, 0x75, 0x73, 0x6f, 0x77, 0x20, 0x41, 0x6b, 0x65, 0x74, 0x73, 0x65, 0x61, 0x62, 0x61, 0x2d, 0x4b, 0x254, 0x74, -0x254, 0x6e, 0x69, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x62, 0x69, 0x72, 0x61, 0x64, 0x65, 0x2d, 0x41, 0x79, 0x25b, 0x77, 0x6f, -0x68, 0x6f, 0x6d, 0x75, 0x6d, 0x75, 0x3b, 0x41, 0x79, 0x25b, 0x77, 0x6f, 0x68, 0x6f, 0x2d, 0x4b, 0x69, 0x74, 0x61, 0x77, -0x6f, 0x6e, 0x73, 0x61, 0x3b, 0x44, 0x69, 0x66, 0x75, 0x75, 0x2d, 0x186, 0x73, 0x61, 0x6e, 0x64, 0x61, 0x61, 0x3b, 0x46, -0x61, 0x6e, 0x6b, 0x77, 0x61, 0x2d, 0x190, 0x62, 0x254, 0x3b, 0x186, 0x62, 0x25b, 0x73, 0x25b, 0x2d, 0x41, 0x68, 0x69, 0x6e, -0x69, 0x6d, 0x65, 0x3b, 0x186, 0x62, 0x65, 0x72, 0x25b, 0x66, 0x25b, 0x77, 0x2d, 0x4f, 0x62, 0x75, 0x62, 0x75, 0x6f, 0x3b, -0x4d, 0x75, 0x6d, 0x75, 0x2d, 0x186, 0x70, 0x25b, 0x6e, 0x69, 0x6d, 0x62, 0x61, 0x3b, 0x91c, 0x93e, 0x928, 0x947, 0x935, 0x93e, -0x930, 0x940, 0x3b, 0x92b, 0x947, 0x92c, 0x94d, 0x930, 0x941, 0x935, 0x93e, 0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, -0x90f, 0x92a, 0x94d, 0x930, 0x93f, 0x932, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x942, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x93e, 0x92f, 0x3b, -0x906, 0x917, 0x94b, 0x938, 0x94d, 0x924, 0x3b, 0x938, 0x92a, 0x94d, 0x91f, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x911, 0x915, 0x94d, 0x91f, -0x94b, 0x92c, 0x930, 0x3b, 0x928, 0x94b, 0x935, 0x94d, 0x939, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x921, 0x93f, 0x938, 0x947, 0x902, 0x92c, -0x930, 0x3b, 0x4a, 0x65, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x61, 0x3b, 0x45, 0x70, 0x72, 0x3b, 0x4d, 0x65, -0x65, 0x3b, 0x4a, 0x75, 0x75, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x1ecc, 0x67, 0x1ecd, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x1ecc, 0x6b, -0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x65, 0x6e, 0x1ee5, 0x77, 0x61, 0x72, 0x1ecb, 0x3b, 0x46, -0x65, 0x62, 0x72, 0x1ee5, 0x77, 0x61, 0x72, 0x1ecb, 0x3b, 0x4d, 0x61, 0x61, 0x63, 0x68, 0x1ecb, 0x3b, 0x45, 0x70, 0x72, 0x65, -0x6c, 0x3b, 0x4d, 0x65, 0x65, 0x3b, 0x4a, 0x75, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x1ecb, 0x3b, 0x1ecc, 0x67, 0x1ecd, -0x1ecd, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x1ecc, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, -0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4d, 0x62, 0x65, 0x3b, -0x4b, 0x65, 0x6c, 0x3b, 0x4b, 0x74, 0x169, 0x3b, 0x4b, 0x61, 0x6e, 0x3b, 0x4b, 0x74, 0x6e, 0x3b, 0x54, 0x68, 0x61, 0x3b, -0x4d, 0x6f, 0x6f, 0x3b, 0x4e, 0x79, 0x61, 0x3b, 0x4b, 0x6e, 0x64, 0x3b, 0x128, 0x6b, 0x75, 0x3b, 0x128, 0x6b, 0x6d, 0x3b, -0x128, 0x6b, 0x6c, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6d, 0x62, 0x65, 0x65, 0x3b, 0x4d, 0x77, 0x61, -0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x65, 0x6c, 0x129, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, -0x74, 0x61, 0x74, 0x169, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x77, -0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, -0x20, 0x74, 0x68, 0x61, 0x6e, 0x74, 0x68, 0x61, 0x74, 0x169, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6d, -0x75, 0x6f, 0x6e, 0x7a, 0x61, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6e, 0x79, 0x61, 0x61, 0x6e, 0x79, -0x61, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x4d, 0x77, 0x61, 0x69, -0x20, 0x77, 0x61, 0x20, 0x129, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x129, 0x6b, -0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x129, 0x6d, 0x77, 0x65, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, -0x129, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x69, 0x6c, 0x129, 0x3b, 0x4d, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, -0x3b, 0x4b, 0x3b, 0x54, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x4b, 0x3b, 0x128, 0x3b, 0x128, 0x3b, 0x128, 0x3b, 0x5a, 0x65, 0x6e, -0x3b, 0x46, 0x65, 0x76, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x76, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x67, -0x3b, 0x4c, 0x75, 0x69, 0x3b, 0x41, 0x76, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x74, 0x75, 0x3b, 0x4e, 0x6f, 0x76, -0x3b, 0x44, 0x69, 0x63, 0x3b, 0x5a, 0x65, 0x6e, 0xe2, 0x72, 0x3b, 0x46, 0x65, 0x76, 0x72, 0xe2, 0x72, 0x3b, 0x4d, 0x61, -0x72, 0xe7, 0x3b, 0x41, 0x76, 0x72, 0xee, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x67, 0x6e, 0x3b, 0x4c, 0x75, -0x69, 0x3b, 0x41, 0x76, 0x6f, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x4f, 0x74, 0x75, -0x62, 0x61, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x44, 0x69, 0x63, 0x65, 0x6d, 0x62, 0x61, -0x72, 0x3b, 0x5a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4c, 0x3b, 0x41, 0x3b, 0x53, 0x3b, -0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x64, 0x7a, 0x76, 0x3b, 0x64, 0x7a, 0x64, 0x3b, 0x74, 0x65, 0x64, 0x3b, 0x61, 0x66, -0x254, 0x3b, 0x64, 0x61, 0x6d, 0x3b, 0x6d, 0x61, 0x73, 0x3b, 0x73, 0x69, 0x61, 0x3b, 0x64, 0x65, 0x61, 0x3b, 0x61, 0x6e, -0x79, 0x3b, 0x6b, 0x65, 0x6c, 0x3b, 0x61, 0x64, 0x65, 0x3b, 0x64, 0x7a, 0x6d, 0x3b, 0x64, 0x7a, 0x6f, 0x76, 0x65, 0x3b, -0x64, 0x7a, 0x6f, 0x64, 0x7a, 0x65, 0x3b, 0x74, 0x65, 0x64, 0x6f, 0x78, 0x65, 0x3b, 0x61, 0x66, 0x254, 0x66, 0x129, 0x65, -0x3b, 0x64, 0x61, 0x6d, 0x61, 0x3b, 0x6d, 0x61, 0x73, 0x61, 0x3b, 0x73, 0x69, 0x61, 0x6d, 0x6c, 0x254, 0x6d, 0x3b, 0x64, -0x65, 0x61, 0x73, 0x69, 0x61, 0x6d, 0x69, 0x6d, 0x65, 0x3b, 0x61, 0x6e, 0x79, 0x254, 0x6e, 0x79, 0x254, 0x3b, 0x6b, 0x65, -0x6c, 0x65, 0x3b, 0x61, 0x64, 0x65, 0x25b, 0x6d, 0x65, 0x6b, 0x70, 0x254, 0x78, 0x65, 0x3b, 0x64, 0x7a, 0x6f, 0x6d, 0x65, -0x3b, 0x64, 0x3b, 0x64, 0x3b, 0x74, 0x3b, 0x61, 0x3b, 0x64, 0x3b, 0x6d, 0x3b, 0x73, 0x3b, 0x64, 0x3b, 0x61, 0x3b, 0x6b, -0x3b, 0x61, 0x3b, 0x64, 0x3b, 0x49, 0x61, 0x6e, 0x2e, 0x3b, 0x50, 0x65, 0x70, 0x2e, 0x3b, 0x4d, 0x61, 0x6c, 0x2e, 0x3b, -0x2bb, 0x41, 0x70, 0x2e, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x49, 0x75, 0x6e, 0x2e, 0x3b, 0x49, 0x75, 0x6c, 0x2e, 0x3b, 0x2bb, -0x41, 0x75, 0x2e, 0x3b, 0x4b, 0x65, 0x70, 0x2e, 0x3b, 0x2bb, 0x4f, 0x6b, 0x2e, 0x3b, 0x4e, 0x6f, 0x77, 0x2e, 0x3b, 0x4b, -0x65, 0x6b, 0x2e, 0x3b, 0x49, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x69, 0x3b, 0x50, 0x65, 0x70, 0x65, 0x6c, 0x75, 0x61, 0x6c, -0x69, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x6b, 0x69, 0x3b, 0x2bb, 0x41, 0x70, 0x65, 0x6c, 0x69, 0x6c, 0x61, 0x3b, 0x4d, 0x65, -0x69, 0x3b, 0x49, 0x75, 0x6e, 0x65, 0x3b, 0x49, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x2bb, 0x41, 0x75, 0x6b, 0x61, 0x6b, 0x65, -0x3b, 0x4b, 0x65, 0x70, 0x61, 0x6b, 0x65, 0x6d, 0x61, 0x70, 0x61, 0x3b, 0x2bb, 0x4f, 0x6b, 0x61, 0x6b, 0x6f, 0x70, 0x61, -0x3b, 0x4e, 0x6f, 0x77, 0x65, 0x6d, 0x61, 0x70, 0x61, 0x3b, 0x4b, 0x65, 0x6b, 0x65, 0x6d, 0x61, 0x70, 0x61, 0x3b, 0x45, -0x6e, 0x65, 0x3b, 0x50, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x48, -0x75, 0x6e, 0x3b, 0x48, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, -0x6f, 0x62, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x45, 0x6e, 0x65, 0x72, 0x6f, 0x3b, 0x50, 0x65, 0x62, 0x72, 0x65, 0x72, 0x6f, -0x3b, 0x4d, 0x61, 0x72, 0x73, 0x6f, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x79, 0x6f, 0x3b, 0x48, 0x75, -0x6e, 0x79, 0x6f, 0x3b, 0x48, 0x75, 0x6c, 0x79, 0x6f, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x53, 0x65, 0x74, -0x79, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x4f, 0x6b, 0x74, 0x75, 0x62, 0x72, 0x65, 0x3b, 0x4e, 0x6f, 0x62, 0x79, 0x65, -0x6d, 0x62, 0x72, 0x65, 0x3b, 0x44, 0x69, 0x73, 0x79, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x45, 0x3b, 0x50, 0x3b, 0x4d, -0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x48, 0x75, 0x6e, 0x3b, 0x48, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x74, -0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x62, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, -0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, -0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x63, 0x68, -0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, 0xe4, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x6f, 0x62, 0x65, 0x72, -0x3b, 0x4e, 0x6f, 0x76, 0xe4, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x7a, 0xe4, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0xa2cd, -0xa1aa, 0x3b, 0xa44d, 0xa1aa, 0x3b, 0xa315, 0xa1aa, 0x3b, 0xa1d6, 0xa1aa, 0x3b, 0xa26c, 0xa1aa, 0x3b, 0xa0d8, 0xa1aa, 0x3b, 0xa3c3, 0xa1aa, 0x3b, -0xa246, 0xa1aa, 0x3b, 0xa22c, 0xa1aa, 0x3b, 0xa2b0, 0xa1aa, 0x3b, 0xa2b0, 0xa2aa, 0xa1aa, 0x3b, 0xa2b0, 0xa44b, 0xa1aa, 0x3b, 0x4a, 0x61, 0x6e, -0x75, 0x61, 0x61, 0x72, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x61, 0x72, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41, -0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, -0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, -0x76, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x7a, 0x65, 0x6d, 0x62, 0x65, -0x72, 0x3b, 0x6f, 0x111, 0x111, 0x6a, 0x3b, 0x67, 0x75, 0x6f, 0x76, 0x3b, 0x6e, 0x6a, 0x75, 0x6b, 0x3b, 0x63, 0x75, 0x6f, -0x3b, 0x6d, 0x69, 0x65, 0x73, 0x3b, 0x67, 0x65, 0x61, 0x73, 0x3b, 0x73, 0x75, 0x6f, 0x69, 0x3b, 0x62, 0x6f, 0x72, 0x67, -0x3b, 0x10d, 0x61, 0x6b, 0x10d, 0x3b, 0x67, 0x6f, 0x6c, 0x67, 0x3b, 0x73, 0x6b, 0xe1, 0x62, 0x3b, 0x6a, 0x75, 0x6f, 0x76, -0x3b, 0x6f, 0x111, 0x111, 0x61, 0x6a, 0x61, 0x67, 0x65, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x67, 0x75, 0x6f, 0x76, 0x76, -0x61, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x6e, 0x6a, 0x75, 0x6b, 0x10d, 0x61, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x63, -0x75, 0x6f, 0x14b, 0x6f, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x6d, 0x69, 0x65, 0x73, 0x73, 0x65, 0x6d, 0xe1, 0x6e, 0x6e, -0x75, 0x3b, 0x67, 0x65, 0x61, 0x73, 0x73, 0x65, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x73, 0x75, 0x6f, 0x69, 0x64, 0x6e, -0x65, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x62, 0x6f, 0x72, 0x67, 0x65, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x10d, 0x61, -0x6b, 0x10d, 0x61, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x67, 0x6f, 0x6c, 0x67, 0x67, 0x6f, 0x74, 0x6d, 0xe1, 0x6e, 0x6e, -0x75, 0x3b, 0x73, 0x6b, 0xe1, 0x62, 0x6d, 0x61, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x6a, 0x75, 0x6f, 0x76, 0x6c, 0x61, -0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x4f, 0x3b, 0x47, 0x3b, 0x4e, 0x3b, 0x43, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x53, 0x3b, -0x42, 0x3b, 0x10c, 0x3b, 0x47, 0x3b, 0x53, 0x3b, 0x4a, 0x3b, 0x6f, 0x111, 0x111, 0x6a, 0x3b, 0x67, 0x75, 0x6f, 0x76, 0x3b, -0x6e, 0x6a, 0x75, 0x6b, 0x3b, 0x63, 0x75, 0x6f, 0x14b, 0x3b, 0x6d, 0x69, 0x65, 0x73, 0x3b, 0x67, 0x65, 0x61, 0x73, 0x3b, -0x73, 0x75, 0x6f, 0x69, 0x3b, 0x62, 0x6f, 0x72, 0x67, 0x3b, 0x10d, 0x61, 0x6b, 0x10d, 0x3b, 0x67, 0x6f, 0x6c, 0x67, 0x3b, -0x73, 0x6b, 0xe1, 0x62, 0x3b, 0x6a, 0x75, 0x6f, 0x76, 0x3b, 0x43, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, -0x63, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x43, 0x75, 0x6c, 0x3b, 0x41, 0x67, -0x74, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x62, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x43, 0x68, -0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x75, 0x72, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x68, -0x69, 0x3b, 0x41, 0x70, 0x69, 0x72, 0x69, 0x72, 0x69, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x43, -0x68, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, -0x61, 0x3b, 0x4f, 0x6b, 0x69, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x62, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, -0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x43, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x43, 0x3b, -0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x49, 0x6d, 0x62, 0x3b, 0x4b, 0x61, 0x77, 0x3b, 0x4b, 0x61, -0x64, 0x3b, 0x4b, 0x61, 0x6e, 0x3b, 0x4b, 0x61, 0x73, 0x3b, 0x4b, 0x61, 0x72, 0x3b, 0x4d, 0x66, 0x75, 0x3b, 0x57, 0x75, -0x6e, 0x3b, 0x49, 0x6b, 0x65, 0x3b, 0x49, 0x6b, 0x75, 0x3b, 0x49, 0x6d, 0x77, 0x3b, 0x49, 0x77, 0x69, 0x3b, 0x4d, 0x6f, -0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x69, 0x6d, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, -0x67, 0x68, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x77, 0x69, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, -0x6b, 0x61, 0x64, 0x61, 0x64, 0x75, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, -0x61, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x73, 0x61, 0x6e, 0x75, 0x3b, 0x4d, -0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x72, 0x61, 0x6e, 0x64, 0x61, 0x64, 0x75, 0x3b, 0x4d, -0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x6d, 0x66, 0x75, 0x6e, 0x67, 0x61, 0x64, 0x65, 0x3b, 0x4d, 0x6f, -0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x77, 0x75, 0x6e, 0x79, 0x61, 0x6e, 0x79, 0x61, 0x3b, 0x4d, 0x6f, 0x72, -0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, -0x68, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, -0x69, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x69, 0x6d, 0x77, 0x65, 0x72, 0x69, 0x3b, 0x4d, 0x6f, 0x72, 0x69, -0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x69, 0x77, 0x69, 0x3b, 0x49, -0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x57, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x49, -0x3b, 0x49, 0x3b, 0x73, 0x69, 0x69, 0x3b, 0x63, 0x6f, 0x6c, 0x3b, 0x6d, 0x62, 0x6f, 0x3b, 0x73, 0x65, 0x65, 0x3b, 0x64, -0x75, 0x75, 0x3b, 0x6b, 0x6f, 0x72, 0x3b, 0x6d, 0x6f, 0x72, 0x3b, 0x6a, 0x75, 0x6b, 0x3b, 0x73, 0x6c, 0x74, 0x3b, 0x79, -0x61, 0x72, 0x3b, 0x6a, 0x6f, 0x6c, 0x3b, 0x62, 0x6f, 0x77, 0x3b, 0x73, 0x69, 0x69, 0x6c, 0x6f, 0x3b, 0x63, 0x6f, 0x6c, -0x74, 0x65, 0x3b, 0x6d, 0x62, 0x6f, 0x6f, 0x79, 0x3b, 0x73, 0x65, 0x65, 0x257, 0x74, 0x6f, 0x3b, 0x64, 0x75, 0x75, 0x6a, -0x61, 0x6c, 0x3b, 0x6b, 0x6f, 0x72, 0x73, 0x65, 0x3b, 0x6d, 0x6f, 0x72, 0x73, 0x6f, 0x3b, 0x6a, 0x75, 0x6b, 0x6f, 0x3b, -0x73, 0x69, 0x69, 0x6c, 0x74, 0x6f, 0x3b, 0x79, 0x61, 0x72, 0x6b, 0x6f, 0x6d, 0x61, 0x61, 0x3b, 0x6a, 0x6f, 0x6c, 0x61, -0x6c, 0x3b, 0x62, 0x6f, 0x77, 0x74, 0x65, 0x3b, 0x73, 0x3b, 0x63, 0x3b, 0x6d, 0x3b, 0x73, 0x3b, 0x64, 0x3b, 0x6b, 0x3b, -0x6d, 0x3b, 0x6a, 0x3b, 0x73, 0x3b, 0x79, 0x3b, 0x6a, 0x3b, 0x62, 0x3b, 0x4a, 0x45, 0x4e, 0x3b, 0x57, 0x4b, 0x52, 0x3b, -0x57, 0x47, 0x54, 0x3b, 0x57, 0x4b, 0x4e, 0x3b, 0x57, 0x54, 0x4e, 0x3b, 0x57, 0x54, 0x44, 0x3b, 0x57, 0x4d, 0x4a, 0x3b, -0x57, 0x4e, 0x4e, 0x3b, 0x57, 0x4b, 0x44, 0x3b, 0x57, 0x49, 0x4b, 0x3b, 0x57, 0x4d, 0x57, 0x3b, 0x44, 0x49, 0x54, 0x3b, -0x4e, 0x6a, 0x65, 0x6e, 0x75, 0x61, 0x72, 0x129, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x65, -0x72, 0x129, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x74, 0x169, 0x3b, 0x4d, -0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, -0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, -0x74, 0x61, 0x6e, 0x64, 0x61, 0x74, 0x169, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x6d, 0x169, 0x67, -0x77, 0x61, 0x6e, 0x6a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x6e, -0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x4d, 0x77, 0x65, -0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x169, 0x6d, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, -0x20, 0x69, 0x6b, 0x169, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x169, 0x6d, 0x77, 0x65, 0x3b, 0x4e, 0x64, 0x69, 0x74, 0x68, -0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4a, 0x3b, 0x4b, 0x3b, 0x47, 0x3b, 0x4b, 0x3b, 0x47, 0x3b, 0x47, 0x3b, 0x4d, 0x3b, 0x4b, -0x3b, 0x4b, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x44, 0x3b, 0x4f, 0x62, 0x6f, 0x3b, 0x57, 0x61, 0x61, 0x3b, 0x4f, 0x6b, 0x75, -0x3b, 0x4f, 0x6e, 0x67, 0x3b, 0x49, 0x6d, 0x65, 0x3b, 0x49, 0x6c, 0x65, 0x3b, 0x53, 0x61, 0x70, 0x3b, 0x49, 0x73, 0x69, -0x3b, 0x53, 0x61, 0x61, 0x3b, 0x54, 0x6f, 0x6d, 0x3b, 0x54, 0x6f, 0x62, 0x3b, 0x54, 0x6f, 0x77, 0x3b, 0x4c, 0x61, 0x70, -0x61, 0x20, 0x6c, 0x65, 0x20, 0x6f, 0x62, 0x6f, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x77, 0x61, 0x61, -0x72, 0x65, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x6f, 0x6b, 0x75, 0x6e, 0x69, 0x3b, 0x4c, 0x61, 0x70, -0x61, 0x20, 0x6c, 0x65, 0x20, 0x6f, 0x6e, 0x67, 0x2019, 0x77, 0x61, 0x6e, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, -0x20, 0x69, 0x6d, 0x65, 0x74, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x69, 0x6c, 0x65, 0x3b, 0x4c, 0x61, -0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x73, 0x61, 0x70, 0x61, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x69, -0x73, 0x69, 0x65, 0x74, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x73, 0x61, 0x61, 0x6c, 0x3b, 0x4c, 0x61, -0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x6d, 0x6f, 0x6e, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, -0x74, 0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x6f, 0x62, 0x6f, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x74, 0x6f, -0x6d, 0x6f, 0x6e, 0x20, 0x77, 0x61, 0x61, 0x72, 0x65, 0x3b, 0x4f, 0x3b, 0x57, 0x3b, 0x4f, 0x3b, 0x4f, 0x3b, 0x49, 0x3b, -0x49, 0x3b, 0x53, 0x3b, 0x49, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, -0x76, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, -0x6c, 0x3b, 0x41, 0x75, 0x67, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x74, 0x75, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, -0x63, 0x3b, 0x4a, 0x61, 0x6e, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x46, 0x65, 0x76, 0x72, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x4d, -0x61, 0x72, 0x63, 0x6f, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x6f, 0x3b, 0x4a, 0x75, 0x6e, 0x68, -0x6f, 0x3b, 0x4a, 0x75, 0x6c, 0x68, 0x6f, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x65, -0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x4f, 0x74, 0x75, 0x62, 0x72, 0x6f, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x6f, -0x3b, 0x44, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x5a, 0x69, 0x62, 0x3b, 0x4e, 0x68, 0x6c, 0x6f, 0x3b, 0x4d, -0x62, 0x69, 0x3b, 0x4d, 0x61, 0x62, 0x3b, 0x4e, 0x6b, 0x77, 0x3b, 0x4e, 0x68, 0x6c, 0x61, 0x3b, 0x4e, 0x74, 0x75, 0x3b, -0x4e, 0x63, 0x77, 0x3b, 0x4d, 0x70, 0x61, 0x6e, 0x3b, 0x4d, 0x66, 0x75, 0x3b, 0x4c, 0x77, 0x65, 0x3b, 0x4d, 0x70, 0x61, -0x6c, 0x3b, 0x5a, 0x69, 0x62, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x6c, 0x61, 0x3b, 0x4e, 0x68, 0x6c, 0x6f, 0x6c, 0x61, 0x6e, -0x6a, 0x61, 0x3b, 0x4d, 0x62, 0x69, 0x6d, 0x62, 0x69, 0x74, 0x68, 0x6f, 0x3b, 0x4d, 0x61, 0x62, 0x61, 0x73, 0x61, 0x3b, -0x4e, 0x6b, 0x77, 0x65, 0x6e, 0x6b, 0x77, 0x65, 0x7a, 0x69, 0x3b, 0x4e, 0x68, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x6c, 0x61, -0x3b, 0x4e, 0x74, 0x75, 0x6c, 0x69, 0x6b, 0x61, 0x7a, 0x69, 0x3b, 0x4e, 0x63, 0x77, 0x61, 0x62, 0x61, 0x6b, 0x61, 0x7a, -0x69, 0x3b, 0x4d, 0x70, 0x61, 0x6e, 0x64, 0x75, 0x6c, 0x61, 0x3b, 0x4d, 0x66, 0x75, 0x6d, 0x66, 0x75, 0x3b, 0x4c, 0x77, -0x65, 0x7a, 0x69, 0x3b, 0x4d, 0x70, 0x61, 0x6c, 0x61, 0x6b, 0x61, 0x7a, 0x69, 0x3b, 0x5a, 0x3b, 0x4e, 0x3b, 0x4d, 0x3b, -0x4d, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4d, 0x31, -0x3b, 0x4d, 0x32, 0x3b, 0x4d, 0x33, 0x3b, 0x4d, 0x34, 0x3b, 0x4d, 0x35, 0x3b, 0x4d, 0x36, 0x3b, 0x4d, 0x37, 0x3b, 0x4d, -0x38, 0x3b, 0x4d, 0x39, 0x3b, 0x4d, 0x31, 0x30, 0x3b, 0x4d, 0x31, 0x31, 0x3b, 0x4d, 0x31, 0x32, 0x3b, 0x4d, 0x77, 0x65, -0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x77, 0x61, 0x6e, 0x7a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, -0x61, 0x20, 0x6b, 0x61, 0x69, 0x6c, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x74, -0x61, 0x74, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x61, 0x6e, 0x61, 0x3b, 0x4d, -0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x74, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, -0x61, 0x20, 0x73, 0x69, 0x74, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x73, 0x61, 0x62, 0x61, -0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6e, 0x61, 0x6e, 0x65, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, -0x20, 0x77, 0x61, 0x20, 0x74, 0x69, 0x73, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, -0x75, 0x6d, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, -0x61, 0x20, 0x6d, 0x6f, 0x6a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x75, 0x6d, -0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x54, -0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x2d49, 0x2d4f, 0x2d4f, 0x3b, 0x2d31, -0x2d55, 0x2d30, 0x3b, 0x2d4e, 0x2d30, 0x2d55, 0x3b, 0x2d49, 0x2d31, 0x2d54, 0x3b, 0x2d4e, 0x2d30, 0x2d62, 0x3b, 0x2d62, 0x2d53, 0x2d4f, 0x3b, 0x2d62, -0x2d53, 0x2d4d, 0x3b, 0x2d56, 0x2d53, 0x2d5b, 0x3b, 0x2d5b, 0x2d53, 0x2d5c, 0x3b, 0x2d3d, 0x2d5c, 0x2d53, 0x3b, 0x2d4f, 0x2d53, 0x2d61, 0x3b, 0x2d37, -0x2d53, 0x2d4a, 0x3b, 0x2d49, 0x2d4f, 0x2d4f, 0x2d30, 0x2d62, 0x2d54, 0x3b, 0x2d31, 0x2d55, 0x2d30, 0x2d62, 0x2d55, 0x3b, 0x2d4e, 0x2d30, 0x2d55, 0x2d5a, -0x3b, 0x2d49, 0x2d31, 0x2d54, 0x2d49, 0x2d54, 0x3b, 0x2d4e, 0x2d30, 0x2d62, 0x2d62, 0x2d53, 0x3b, 0x2d62, 0x2d53, 0x2d4f, 0x2d62, 0x2d53, 0x3b, 0x2d62, -0x2d53, 0x2d4d, 0x2d62, 0x2d53, 0x2d63, 0x3b, 0x2d56, 0x2d53, 0x2d5b, 0x2d5c, 0x3b, 0x2d5b, 0x2d53, 0x2d5c, 0x2d30, 0x2d4f, 0x2d31, 0x2d49, 0x2d54, 0x3b, -0x2d3d, 0x2d5c, 0x2d53, 0x2d31, 0x2d54, 0x3b, 0x2d4f, 0x2d53, 0x2d61, 0x2d30, 0x2d4f, 0x2d31, 0x2d49, 0x2d54, 0x3b, 0x2d37, 0x2d53, 0x2d4a, 0x2d30, 0x2d4f, -0x2d31, 0x2d49, 0x2d54, 0x3b, 0x2d49, 0x3b, 0x2d31, 0x3b, 0x2d4e, 0x3b, 0x2d49, 0x3b, 0x2d4e, 0x3b, 0x2d62, 0x3b, 0x2d62, 0x3b, 0x2d56, 0x3b, -0x2d5b, 0x3b, 0x2d3d, 0x3b, 0x2d4f, 0x3b, 0x2d37, 0x3b, 0x69, 0x6e, 0x6e, 0x3b, 0x62, 0x1e5b, 0x61, 0x3b, 0x6d, 0x61, 0x1e5b, 0x3b, -0x69, 0x62, 0x72, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x79, 0x75, 0x6e, 0x3b, 0x79, 0x75, 0x6c, 0x3b, 0x263, 0x75, 0x63, 0x3b, -0x63, 0x75, 0x74, 0x3b, 0x6b, 0x74, 0x75, 0x3b, 0x6e, 0x75, 0x77, 0x3b, 0x64, 0x75, 0x6a, 0x3b, 0x69, 0x6e, 0x6e, 0x61, -0x79, 0x72, 0x3b, 0x62, 0x1e5b, 0x61, 0x79, 0x1e5b, 0x3b, 0x6d, 0x61, 0x1e5b, 0x1e63, 0x3b, 0x69, 0x62, 0x72, 0x69, 0x72, 0x3b, -0x6d, 0x61, 0x79, 0x79, 0x75, 0x3b, 0x79, 0x75, 0x6e, 0x79, 0x75, 0x3b, 0x79, 0x75, 0x6c, 0x79, 0x75, 0x7a, 0x3b, 0x263, -0x75, 0x63, 0x74, 0x3b, 0x63, 0x75, 0x74, 0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b, 0x6b, 0x74, 0x75, 0x62, 0x72, 0x3b, 0x6e, -0x75, 0x77, 0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b, 0x64, 0x75, 0x6a, 0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b, 0x69, 0x3b, 0x62, -0x3b, 0x6d, 0x3b, 0x69, 0x3b, 0x6d, 0x3b, 0x79, 0x3b, 0x79, 0x3b, 0x263, 0x3b, 0x63, 0x3b, 0x6b, 0x3b, 0x6e, 0x3b, 0x64, -0x3b, 0x59, 0x65, 0x6e, 0x3b, 0x46, 0x75, 0x72, 0x3b, 0x4d, 0x65, 0x263, 0x3b, 0x59, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x79, -0x3b, 0x59, 0x75, 0x6e, 0x3b, 0x59, 0x75, 0x6c, 0x3b, 0x194, 0x75, 0x63, 0x3b, 0x43, 0x74, 0x65, 0x3b, 0x54, 0x75, 0x62, -0x3b, 0x57, 0x61, 0x6d, 0x3b, 0x44, 0x75, 0x6a, 0x3b, 0x59, 0x65, 0x6e, 0x6e, 0x61, 0x79, 0x65, 0x72, 0x3b, 0x46, 0x75, -0x1e5b, 0x61, 0x72, 0x3b, 0x4d, 0x65, 0x263, 0x72, 0x65, 0x73, 0x3b, 0x59, 0x65, 0x62, 0x72, 0x69, 0x72, 0x3b, 0x4d, 0x61, -0x79, 0x79, 0x75, 0x3b, 0x59, 0x75, 0x6e, 0x79, 0x75, 0x3b, 0x59, 0x75, 0x6c, 0x79, 0x75, 0x3b, 0x194, 0x75, 0x63, 0x74, -0x3b, 0x43, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x1e5b, 0x3b, 0x54, 0x75, 0x62, 0x65, 0x1e5b, 0x3b, 0x57, 0x61, 0x6d, 0x62, 0x65, -0x1e5b, 0x3b, 0x44, 0x75, 0x6a, 0x65, 0x6d, 0x62, 0x65, 0x1e5b, 0x3b, 0x59, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x59, 0x3b, 0x4d, -0x3b, 0x59, 0x3b, 0x59, 0x3b, 0x194, 0x3b, 0x43, 0x3b, 0x54, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x59, 0x65, 0x6e, 0x3b, 0x46, -0x75, 0x72, 0x3b, 0x4d, 0x65, 0x263, 0x3b, 0x59, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x59, 0x75, 0x6e, 0x3b, 0x59, -0x75, 0x6c, 0x3b, 0x194, 0x75, 0x63, 0x3b, 0x43, 0x74, 0x65, 0x3b, 0x54, 0x75, 0x62, 0x3b, 0x4e, 0x75, 0x6e, 0x3b, 0x44, -0x75, 0x1e7, 0x3b, 0x59, 0x65, 0x6e, 0x6e, 0x61, 0x79, 0x65, 0x72, 0x3b, 0x46, 0x75, 0x1e5b, 0x61, 0x72, 0x3b, 0x4d, 0x65, -0x263, 0x72, 0x65, 0x73, 0x3b, 0x59, 0x65, 0x62, 0x72, 0x69, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x79, 0x75, 0x3b, 0x59, 0x75, -0x6e, 0x79, 0x75, 0x3b, 0x59, 0x75, 0x6c, 0x79, 0x75, 0x3b, 0x194, 0x75, 0x63, 0x74, 0x3b, 0x43, 0x74, 0x65, 0x6d, 0x62, -0x65, 0x1e5b, 0x3b, 0x54, 0x75, 0x62, 0x65, 0x1e5b, 0x3b, 0x4e, 0x75, 0x6e, 0x65, 0x6d, 0x62, 0x65, 0x1e5b, 0x3b, 0x44, 0x75, -0x1e7, 0x65, 0x6d, 0x62, 0x65, 0x1e5b, 0x3b, 0x59, 0x3b, 0x46, 0x3b, 0x194, 0x3b, 0x42, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x4c, -0x3b, 0x43, 0x3b, 0x54, 0x3b, 0x52, 0x3b, 0x57, 0x3b, 0x44, 0x3b, 0x4b, 0x42, 0x5a, 0x3b, 0x4b, 0x42, 0x52, 0x3b, 0x4b, -0x53, 0x54, 0x3b, 0x4b, 0x4b, 0x4e, 0x3b, 0x4b, 0x54, 0x4e, 0x3b, 0x4b, 0x4d, 0x4b, 0x3b, 0x4b, 0x4d, 0x53, 0x3b, 0x4b, -0x4d, 0x4e, 0x3b, 0x4b, 0x4d, 0x57, 0x3b, 0x4b, 0x4b, 0x4d, 0x3b, 0x4b, 0x4e, 0x4b, 0x3b, 0x4b, 0x4e, 0x42, 0x3b, 0x4f, -0x6b, 0x77, 0x6f, 0x6b, 0x75, 0x62, 0x61, 0x6e, 0x7a, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6b, 0x61, 0x62, 0x69, 0x72, -0x69, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6b, 0x61, 0x73, 0x68, 0x61, 0x74, 0x75, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6b, 0x61, -0x6e, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6b, 0x61, 0x74, 0x61, 0x61, 0x6e, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6d, -0x75, 0x6b, 0x61, 0x61, 0x67, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6d, 0x75, 0x73, 0x68, 0x61, 0x6e, 0x6a, 0x75, 0x3b, -0x4f, 0x6b, 0x77, 0x61, 0x6d, 0x75, 0x6e, 0x61, 0x61, 0x6e, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6d, 0x77, 0x65, 0x6e, -0x64, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x69, 0x6b, 0x75, -0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6b, 0x75, 0x6d, 0x77, 0x65, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x69, 0x6b, 0x75, 0x6d, -0x69, 0x20, 0x6e, 0x61, 0x20, 0x69, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x48, 0x75, 0x74, 0x3b, 0x56, 0x69, 0x6c, 0x3b, 0x44, -0x61, 0x74, 0x3b, 0x54, 0x61, 0x69, 0x3b, 0x48, 0x61, 0x6e, 0x3b, 0x53, 0x69, 0x74, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4e, -0x61, 0x6e, 0x3b, 0x54, 0x69, 0x73, 0x3b, 0x4b, 0x75, 0x6d, 0x3b, 0x4b, 0x6d, 0x6a, 0x3b, 0x4b, 0x6d, 0x62, 0x3b, 0x70, -0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x68, 0x75, 0x74, 0x61, 0x6c, 0x61, 0x3b, -0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x77, 0x75, 0x76, 0x69, 0x6c, 0x69, -0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x77, 0x75, 0x64, 0x61, 0x74, -0x75, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x77, 0x75, 0x74, 0x61, -0x69, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x77, 0x75, 0x68, 0x61, -0x6e, 0x75, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x73, 0x69, 0x74, -0x61, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x73, 0x61, 0x62, 0x61, -0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x6e, 0x61, 0x6e, 0x65, 0x3b, -0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x74, 0x69, 0x73, 0x61, 0x3b, 0x70, -0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x70, 0x61, -0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, -0x6d, 0x6f, 0x6a, 0x61, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x6b, -0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x48, 0x3b, 0x56, 0x3b, 0x44, 0x3b, 0x54, -0x3b, 0x48, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4a, 0x61, 0x6e, -0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x3b, -0x41, 0x70, 0x72, 0x69, 0x6c, 0x79, 0x69, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x79, 0x69, 0x3b, 0x4a, 0x75, -0x6c, 0x79, 0x61, 0x69, 0x3b, 0x41, 0x67, 0x75, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, -0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x65, 0x73, 0x65, -0x6d, 0x62, 0x61, 0x3b, 0x7a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x77, 0x69, 0x3b, -0x6d, 0x25b, 0x3b, 0x7a, 0x75, 0x77, 0x3b, 0x7a, 0x75, 0x6c, 0x3b, 0x75, 0x74, 0x69, 0x3b, 0x73, 0x25b, 0x74, 0x3b, 0x254, -0x6b, 0x75, 0x3b, 0x6e, 0x6f, 0x77, 0x3b, 0x64, 0x65, 0x73, 0x3b, 0x7a, 0x61, 0x6e, 0x77, 0x75, 0x79, 0x65, 0x3b, 0x66, -0x65, 0x62, 0x75, 0x72, 0x75, 0x79, 0x65, 0x3b, 0x6d, 0x61, 0x72, 0x69, 0x73, 0x69, 0x3b, 0x61, 0x77, 0x69, 0x72, 0x69, -0x6c, 0x69, 0x3b, 0x6d, 0x25b, 0x3b, 0x7a, 0x75, 0x77, 0x25b, 0x6e, 0x3b, 0x7a, 0x75, 0x6c, 0x75, 0x79, 0x65, 0x3b, 0x75, -0x74, 0x69, 0x3b, 0x73, 0x25b, 0x74, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x75, 0x3b, 0x254, 0x6b, 0x75, 0x74, 0x254, 0x62, 0x75, -0x72, 0x75, 0x3b, 0x6e, 0x6f, 0x77, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x75, 0x3b, 0x64, 0x65, 0x73, 0x61, 0x6e, 0x62, 0x75, -0x72, 0x75, 0x3b, 0x5a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x5a, 0x3b, 0x5a, 0x3b, 0x55, 0x3b, 0x53, -0x3b, 0x186, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4d, 0x62, 0x65, 0x3b, 0x4b, 0x61, 0x69, 0x3b, 0x4b, 0x61, 0x74, 0x3b, 0x4b, -0x61, 0x6e, 0x3b, 0x47, 0x61, 0x74, 0x3b, 0x47, 0x61, 0x6e, 0x3b, 0x4d, 0x75, 0x67, 0x3b, 0x4b, 0x6e, 0x6e, 0x3b, 0x4b, -0x65, 0x6e, 0x3b, 0x49, 0x6b, 0x75, 0x3b, 0x49, 0x6d, 0x77, 0x3b, 0x49, 0x67, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, -0x20, 0x77, 0x61, 0x20, 0x6d, 0x62, 0x65, 0x72, 0x65, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, -0x61, 0x129, 0x72, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x74, 0x68, 0x61, 0x74, -0x169, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, -0x69, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, -0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x74, 0x61, 0x74, 0x169, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, -0x6d, 0x169, 0x67, 0x77, 0x61, 0x6e, 0x6a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, -0x6e, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x65, 0x6e, 0x64, 0x61, 0x3b, -0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x169, 0x6d, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, -0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x169, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x169, 0x6d, 0x77, 0x65, 0x3b, 0x4d, 0x77, -0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x169, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x4b, 0x61, 0x129, 0x72, -0x129, 0x3b, 0x4d, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x47, 0x3b, 0x47, 0x3b, 0x4d, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, -0x49, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x13a4, 0x13c3, 0x3b, 0x13a7, 0x13a6, 0x3b, 0x13a0, 0x13c5, 0x3b, 0x13a7, 0x13ec, 0x3b, 0x13a0, 0x13c2, -0x3b, 0x13d5, 0x13ad, 0x3b, 0x13ab, 0x13f0, 0x3b, 0x13a6, 0x13b6, 0x3b, 0x13da, 0x13b5, 0x3b, 0x13da, 0x13c2, 0x3b, 0x13c5, 0x13d3, 0x3b, 0x13a5, -0x13cd, 0x3b, 0x13a4, 0x13c3, 0x13b8, 0x13d4, 0x13c5, 0x3b, 0x13a7, 0x13a6, 0x13b5, 0x3b, 0x13a0, 0x13c5, 0x13f1, 0x3b, 0x13a7, 0x13ec, 0x13c2, 0x3b, -0x13a0, 0x13c2, 0x13cd, 0x13ac, 0x13d8, 0x3b, 0x13d5, 0x13ad, 0x13b7, 0x13f1, 0x3b, 0x13ab, 0x13f0, 0x13c9, 0x13c2, 0x3b, 0x13a6, 0x13b6, 0x13c2, 0x3b, -0x13da, 0x13b5, 0x13cd, 0x13d7, 0x3b, 0x13da, 0x13c2, 0x13c5, 0x13d7, 0x3b, 0x13c5, 0x13d3, 0x13d5, 0x13c6, 0x3b, 0x13a5, 0x13cd, 0x13a9, 0x13f1, 0x3b, -0x13a4, 0x3b, 0x13a7, 0x3b, 0x13a0, 0x3b, 0x13a7, 0x3b, 0x13a0, 0x3b, 0x13d5, 0x3b, 0x13ab, 0x3b, 0x13a6, 0x3b, 0x13da, 0x3b, 0x13da, 0x3b, -0x13c5, 0x3b, 0x13a5, 0x3b, 0x7a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x76, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x76, 0x72, 0x3b, -0x6d, 0x65, 0x3b, 0x7a, 0x69, 0x6e, 0x3b, 0x7a, 0x69, 0x6c, 0x3b, 0x6f, 0x75, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, -0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x73, 0x3b, 0x7a, 0x61, 0x6e, 0x76, 0x69, 0x65, 0x3b, 0x66, 0x65, -0x76, 0x72, 0x69, 0x79, 0x65, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x76, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x65, 0x3b, -0x7a, 0x69, 0x6e, 0x3b, 0x7a, 0x69, 0x6c, 0x79, 0x65, 0x3b, 0x6f, 0x75, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x61, 0x6d, -0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x3b, 0x6e, 0x6f, 0x76, 0x61, 0x6d, 0x3b, 0x64, 0x65, 0x73, 0x61, 0x6d, 0x3b, 0x7a, -0x3b, 0x66, 0x3b, 0x6d, 0x3b, 0x61, 0x3b, 0x6d, 0x3b, 0x7a, 0x3b, 0x7a, 0x3b, 0x6f, 0x3b, 0x73, 0x3b, 0x6f, 0x3b, 0x6e, -0x3b, 0x64, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x4e, 0x74, 0x61, 0x6e, 0x64, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x64, -0x69, 0x20, 0x77, 0x61, 0x20, 0x50, 0x69, 0x6c, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x54, -0x61, 0x74, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x63, 0x68, 0x65, 0x63, 0x68, 0x69, -0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x65, -0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x55, 0x6d, 0x6f, 0x3b, -0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4d, -0x69, 0x76, 0x69, 0x6c, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, -0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4d, 0x69, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, -0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4e, 0x63, 0x68, 0x65, 0x63, 0x68, 0x69, 0x3b, 0x4d, -0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4e, 0x6e, -0x79, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, -0x20, 0x6e, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x55, 0x3b, 0x4d, 0x77, 0x65, 0x64, -0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, -0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4d, 0x3b, 0x46, 0xfa, 0x6e, 0x67, 0x61, 0x74, 0x268, 0x3b, 0x4e, 0x61, 0x61, 0x6e, 0x268, -0x3b, 0x4b, 0x65, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x49, 0x6b, 0xfa, 0x6d, 0x69, 0x3b, 0x49, 0x6e, 0x79, 0x61, 0x6d, 0x62, -0x61, 0x6c, 0x61, 0x3b, 0x49, 0x64, 0x77, 0x61, 0x61, 0x74, 0x61, 0x3b, 0x4d, 0x289, 0x289, 0x6e, 0x63, 0x68, 0x268, 0x3b, -0x56, 0x268, 0x268, 0x72, 0x268, 0x3b, 0x53, 0x61, 0x61, 0x74, 0x289, 0x3b, 0x49, 0x6e, 0x79, 0x69, 0x3b, 0x53, 0x61, 0x61, -0x6e, 0x6f, 0x3b, 0x53, 0x61, 0x73, 0x61, 0x74, 0x289, 0x3b, 0x4b, 0x289, 0x66, 0xfa, 0x6e, 0x67, 0x61, 0x74, 0x268, 0x3b, -0x4b, 0x289, 0x6e, 0x61, 0x61, 0x6e, 0x268, 0x3b, 0x4b, 0x289, 0x6b, 0x65, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x4b, 0x77, 0x69, -0x69, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4b, 0x77, 0x69, 0x69, 0x6e, 0x79, 0x61, 0x6d, 0x62, 0xe1, 0x6c, 0x61, 0x3b, 0x4b, -0x77, 0x69, 0x69, 0x64, 0x77, 0x61, 0x61, 0x74, 0x61, 0x3b, 0x4b, 0x289, 0x6d, 0x289, 0x289, 0x6e, 0x63, 0x68, 0x268, 0x3b, -0x4b, 0x289, 0x76, 0x268, 0x268, 0x72, 0x268, 0x3b, 0x4b, 0x289, 0x73, 0x61, 0x61, 0x74, 0x289, 0x3b, 0x4b, 0x77, 0x69, 0x69, -0x6e, 0x79, 0x69, 0x3b, 0x4b, 0x289, 0x73, 0x61, 0x61, 0x6e, 0x6f, 0x3b, 0x4b, 0x289, 0x73, 0x61, 0x73, 0x61, 0x74, 0x289, -0x3b, 0x46, 0x3b, 0x4e, 0x3b, 0x4b, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x4d, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x49, -0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x75, -0x3b, 0x4d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x75, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x75, 0x3b, 0x53, 0x65, 0x62, -0x3b, 0x4f, 0x6b, 0x69, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x77, 0x61, 0x6c, 0x69, -0x79, 0x6f, 0x3b, 0x46, 0x65, 0x62, 0x77, 0x61, 0x6c, 0x69, 0x79, 0x6f, 0x3b, 0x4d, 0x61, 0x72, 0x69, 0x73, 0x69, 0x3b, -0x41, 0x70, 0x75, 0x6c, 0x69, 0x3b, 0x4d, 0x61, 0x61, 0x79, 0x69, 0x3b, 0x4a, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, -0x6c, 0x61, 0x61, 0x79, 0x69, 0x3b, 0x41, 0x67, 0x75, 0x73, 0x69, 0x74, 0x6f, 0x3b, 0x53, 0x65, 0x62, 0x75, 0x74, 0x74, -0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x69, 0x74, 0x6f, 0x62, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, -0x61, 0x3b, 0x44, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, -0x63, 0x3b, 0x45, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x4f, 0x67, -0x61, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x61, -0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69, -0x3b, 0x45, 0x70, 0x72, 0x65, 0x6f, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61, -0x69, 0x3b, 0x4f, 0x67, 0x61, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, -0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x61, -0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x4f, 0x3b, 0x53, 0x3b, 0x4f, -0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72, -0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x74, -0x3b, 0x4f, 0x74, 0x75, 0x3b, 0x4e, 0x75, 0x76, 0x3b, 0x44, 0x69, 0x7a, 0x3b, 0x4a, 0x61, 0x6e, 0x65, 0x72, 0x75, 0x3b, -0x46, 0x65, 0x62, 0x72, 0x65, 0x72, 0x75, 0x3b, 0x4d, 0x61, 0x72, 0x73, 0x75, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x3b, -0x4d, 0x61, 0x69, 0x75, 0x3b, 0x4a, 0x75, 0x6e, 0x68, 0x75, 0x3b, 0x4a, 0x75, 0x6c, 0x68, 0x75, 0x3b, 0x41, 0x67, 0x6f, -0x73, 0x74, 0x75, 0x3b, 0x53, 0x65, 0x74, 0x65, 0x6e, 0x62, 0x72, 0x75, 0x3b, 0x4f, 0x74, 0x75, 0x62, 0x72, 0x75, 0x3b, -0x4e, 0x75, 0x76, 0x65, 0x6e, 0x62, 0x72, 0x75, 0x3b, 0x44, 0x69, 0x7a, 0x65, 0x6e, 0x62, 0x72, 0x75, 0x3b, 0x4a, 0x41, -0x4e, 0x3b, 0x46, 0x45, 0x42, 0x3b, 0x4d, 0x41, 0x43, 0x3b, 0x128, 0x50, 0x55, 0x3b, 0x4d, 0x128, 0x128, 0x3b, 0x4e, 0x4a, -0x55, 0x3b, 0x4e, 0x4a, 0x52, 0x3b, 0x41, 0x47, 0x41, 0x3b, 0x53, 0x50, 0x54, 0x3b, 0x4f, 0x4b, 0x54, 0x3b, 0x4e, 0x4f, -0x56, 0x3b, 0x44, 0x45, 0x43, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x129, 0x3b, 0x46, 0x65, 0x62, 0x75, 0x72, 0x75, -0x61, 0x72, 0x129, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x3b, 0x128, 0x70, 0x75, 0x72, 0x169, 0x3b, 0x4d, 0x129, 0x129, 0x3b, -0x4e, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x4e, 0x6a, 0x75, 0x72, 0x61, 0x129, 0x3b, 0x41, 0x67, 0x61, 0x73, 0x74, 0x69, 0x3b, -0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x169, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, -0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x63, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x128, 0x3b, -0x4d, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4d, 0x75, 0x6c, 0x3b, -0x4e, 0x67, 0x61, 0x74, 0x3b, 0x54, 0x61, 0x61, 0x3b, 0x49, 0x77, 0x6f, 0x3b, 0x4d, 0x61, 0x6d, 0x3b, 0x50, 0x61, 0x61, -0x3b, 0x4e, 0x67, 0x65, 0x3b, 0x52, 0x6f, 0x6f, 0x3b, 0x42, 0x75, 0x72, 0x3b, 0x45, 0x70, 0x65, 0x3b, 0x4b, 0x70, 0x74, -0x3b, 0x4b, 0x70, 0x61, 0x3b, 0x4d, 0x75, 0x6c, 0x67, 0x75, 0x6c, 0x3b, 0x4e, 0x67, 0x2019, 0x61, 0x74, 0x79, 0x61, 0x61, -0x74, 0x6f, 0x3b, 0x4b, 0x69, 0x70, 0x74, 0x61, 0x61, 0x6d, 0x6f, 0x3b, 0x49, 0x77, 0x6f, 0x6f, 0x74, 0x6b, 0x75, 0x75, -0x74, 0x3b, 0x4d, 0x61, 0x6d, 0x75, 0x75, 0x74, 0x3b, 0x50, 0x61, 0x61, 0x67, 0x69, 0x3b, 0x4e, 0x67, 0x2019, 0x65, 0x69, -0x79, 0x65, 0x65, 0x74, 0x3b, 0x52, 0x6f, 0x6f, 0x70, 0x74, 0x75, 0x69, 0x3b, 0x42, 0x75, 0x72, 0x65, 0x65, 0x74, 0x3b, -0x45, 0x70, 0x65, 0x65, 0x73, 0x6f, 0x3b, 0x4b, 0x69, 0x70, 0x73, 0x75, 0x75, 0x6e, 0x64, 0x65, 0x20, 0x6e, 0x65, 0x20, -0x74, 0x61, 0x61, 0x69, 0x3b, 0x4b, 0x69, 0x70, 0x73, 0x75, 0x75, 0x6e, 0x64, 0x65, 0x20, 0x6e, 0x65, 0x62, 0x6f, 0x20, -0x61, 0x65, 0x6e, 0x67, 0x2019, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x49, 0x3b, 0x4d, 0x3b, 0x50, 0x3b, 0x4e, 0x3b, -0x52, 0x3b, 0x42, 0x3b, 0x45, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x1c3, 0x4b, 0x68, 0x61, 0x6e, 0x6e, 0x69, 0x3b, 0x1c3, 0x4b, -0x68, 0x61, 0x6e, 0x1c0, 0x67, 0xf4, 0x61, 0x62, 0x3b, 0x1c0, 0x4b, 0x68, 0x75, 0x75, 0x1c1, 0x6b, 0x68, 0xe2, 0x62, 0x3b, -0x1c3, 0x48, 0xf4, 0x61, 0x1c2, 0x6b, 0x68, 0x61, 0x69, 0x62, 0x3b, 0x1c3, 0x4b, 0x68, 0x61, 0x69, 0x74, 0x73, 0xe2, 0x62, -0x3b, 0x47, 0x61, 0x6d, 0x61, 0x1c0, 0x61, 0x65, 0x62, 0x3b, 0x1c2, 0x4b, 0x68, 0x6f, 0x65, 0x73, 0x61, 0x6f, 0x62, 0x3b, -0x41, 0x6f, 0x1c1, 0x6b, 0x68, 0x75, 0x75, 0x6d, 0xfb, 0x1c1, 0x6b, 0x68, 0xe2, 0x62, 0x3b, 0x54, 0x61, 0x72, 0x61, 0x1c0, -0x6b, 0x68, 0x75, 0x75, 0x6d, 0xfb, 0x1c1, 0x6b, 0x68, 0xe2, 0x62, 0x3b, 0x1c2, 0x4e, 0xfb, 0x1c1, 0x6e, 0xe2, 0x69, 0x73, -0x65, 0x62, 0x3b, 0x1c0, 0x48, 0x6f, 0x6f, 0x1c2, 0x67, 0x61, 0x65, 0x62, 0x3b, 0x48, 0xf4, 0x61, 0x73, 0x6f, 0x72, 0x65, -0x1c1, 0x6b, 0x68, 0xe2, 0x62, 0x3b, 0x4a, 0x61, 0x6e, 0x2e, 0x3b, 0x46, 0xe4, 0x62, 0x2e, 0x3b, 0x4d, 0xe4, 0x7a, 0x2e, -0x3b, 0x41, 0x70, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x2e, 0x3b, 0x4a, 0x75, 0x6c, 0x2e, 0x3b, -0x4f, 0x75, 0x6a, 0x2e, 0x3b, 0x53, 0xe4, 0x70, 0x2e, 0x3b, 0x4f, 0x6b, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, -0x44, 0x65, 0x7a, 0x2e, 0x3b, 0x4a, 0x61, 0x6e, 0x6e, 0x65, 0x77, 0x61, 0x3b, 0x46, 0xe4, 0x62, 0x72, 0x6f, 0x77, 0x61, -0x3b, 0x4d, 0xe4, 0xe4, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x65, 0x6c, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x75, -0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x75, 0x6c, 0x69, 0x3b, 0x4f, 0x75, 0x6a, 0x6f, 0xdf, 0x3b, 0x53, 0x65, 0x70, 0x74, 0xe4, -0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x68, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0xe4, 0x6d, 0x62, -0x65, 0x72, 0x3b, 0x44, 0x65, 0x7a, 0xe4, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0xe4, 0x62, 0x3b, -0x4d, 0xe4, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, -0x4f, 0x75, 0x6a, 0x3b, 0x53, 0xe4, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x7a, 0x3b, -0x44, 0x61, 0x6c, 0x3b, 0x41, 0x72, 0xe1, 0x3b, 0x186, 0x25b, 0x6e, 0x3b, 0x44, 0x6f, 0x79, 0x3b, 0x4c, 0xe9, 0x70, 0x3b, -0x52, 0x6f, 0x6b, 0x3b, 0x53, 0xe1, 0x73, 0x3b, 0x42, 0x254, 0x301, 0x72, 0x3b, 0x4b, 0xfa, 0x73, 0x3b, 0x47, 0xed, 0x73, -0x3b, 0x53, 0x68, 0x289, 0x301, 0x3b, 0x4e, 0x74, 0x289, 0x301, 0x3b, 0x4f, 0x6c, 0x61, 0x64, 0x61, 0x6c, 0x289, 0x301, 0x3b, -0x41, 0x72, 0xe1, 0x74, 0x3b, 0x186, 0x25b, 0x6e, 0x268, 0x301, 0x254, 0x268, 0x14b, 0x254, 0x6b, 0x3b, 0x4f, 0x6c, 0x6f, 0x64, -0x6f, 0x79, 0xed, 0xf3, 0x72, 0xed, 0xea, 0x20, 0x69, 0x6e, 0x6b, 0xf3, 0x6b, 0xfa, 0xe2, 0x3b, 0x4f, 0x6c, 0x6f, 0x69, -0x6c, 0xe9, 0x70, 0x16b, 0x6e, 0x79, 0x12b, 0x113, 0x20, 0x69, 0x6e, 0x6b, 0xf3, 0x6b, 0xfa, 0xe2, 0x3b, 0x4b, 0xfa, 0x6a, -0xfa, 0x254, 0x72, 0x254, 0x6b, 0x3b, 0x4d, 0xf3, 0x72, 0x75, 0x73, 0xe1, 0x73, 0x69, 0x6e, 0x3b, 0x186, 0x6c, 0x254, 0x301, -0x268, 0x301, 0x62, 0x254, 0x301, 0x72, 0xe1, 0x72, 0x25b, 0x3b, 0x4b, 0xfa, 0x73, 0x68, 0xee, 0x6e, 0x3b, 0x4f, 0x6c, 0x67, -0xed, 0x73, 0x61, 0x6e, 0x3b, 0x50, 0x289, 0x73, 0x68, 0x289, 0x301, 0x6b, 0x61, 0x3b, 0x4e, 0x74, 0x289, 0x301, 0x14b, 0x289, -0x301, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, -0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, -0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, -0x61, 0x63, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, -0x67, 0x6f, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x63, 0x3b, 0x52, -0x61, 0x72, 0x3b, 0x4d, 0x75, 0x6b, 0x3b, 0x4b, 0x77, 0x61, 0x3b, 0x44, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x4d, -0x6f, 0x64, 0x3b, 0x4a, 0x6f, 0x6c, 0x3b, 0x50, 0x65, 0x64, 0x3b, 0x53, 0x6f, 0x6b, 0x3b, 0x54, 0x69, 0x62, 0x3b, 0x4c, -0x61, 0x62, 0x3b, 0x50, 0x6f, 0x6f, 0x3b, 0x4f, 0x72, 0x61, 0x72, 0x61, 0x3b, 0x4f, 0x6d, 0x75, 0x6b, 0x3b, 0x4f, 0x6b, -0x77, 0x61, 0x6d, 0x67, 0x2019, 0x3b, 0x4f, 0x64, 0x75, 0x6e, 0x67, 0x2019, 0x65, 0x6c, 0x3b, 0x4f, 0x6d, 0x61, 0x72, 0x75, -0x6b, 0x3b, 0x4f, 0x6d, 0x6f, 0x64, 0x6f, 0x6b, 0x2019, 0x6b, 0x69, 0x6e, 0x67, 0x2019, 0x6f, 0x6c, 0x3b, 0x4f, 0x6a, 0x6f, -0x6c, 0x61, 0x3b, 0x4f, 0x70, 0x65, 0x64, 0x65, 0x6c, 0x3b, 0x4f, 0x73, 0x6f, 0x6b, 0x6f, 0x73, 0x6f, 0x6b, 0x6f, 0x6d, -0x61, 0x3b, 0x4f, 0x74, 0x69, 0x62, 0x61, 0x72, 0x3b, 0x4f, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x3b, 0x4f, 0x70, 0x6f, 0x6f, -0x3b, 0x52, 0x3b, 0x4d, 0x3b, 0x4b, 0x3b, 0x44, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x54, -0x3b, 0x4c, 0x3b, 0x50, 0x3b, 0x17d, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x65, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x77, 0x69, -0x3b, 0x4d, 0x65, 0x3b, 0x17d, 0x75, 0x77, 0x3b, 0x17d, 0x75, 0x79, 0x3b, 0x55, 0x74, 0x3b, 0x53, 0x65, 0x6b, 0x3b, 0x4f, -0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x6f, 0x3b, 0x44, 0x65, 0x65, 0x3b, 0x17d, 0x61, 0x6e, 0x77, 0x69, 0x79, 0x65, 0x3b, 0x46, -0x65, 0x65, 0x77, 0x69, 0x72, 0x69, 0x79, 0x65, 0x3b, 0x4d, 0x61, 0x72, 0x73, 0x69, 0x3b, 0x41, 0x77, 0x69, 0x72, 0x69, -0x6c, 0x3b, 0x4d, 0x65, 0x3b, 0x17d, 0x75, 0x77, 0x65, 0x14b, 0x3b, 0x17d, 0x75, 0x79, 0x79, 0x65, 0x3b, 0x55, 0x74, 0x3b, -0x53, 0x65, 0x6b, 0x74, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x6f, 0x62, 0x75, 0x72, 0x3b, 0x4e, -0x6f, 0x6f, 0x77, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x3b, 0x44, 0x65, 0x65, 0x73, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x3b, 0x17d, -0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x17d, 0x3b, 0x17d, 0x3b, 0x55, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, -0x3b, 0x44, 0x3b, 0x44, 0x41, 0x43, 0x3b, 0x44, 0x41, 0x52, 0x3b, 0x44, 0x41, 0x44, 0x3b, 0x44, 0x41, 0x4e, 0x3b, 0x44, -0x41, 0x48, 0x3b, 0x44, 0x41, 0x55, 0x3b, 0x44, 0x41, 0x4f, 0x3b, 0x44, 0x41, 0x42, 0x3b, 0x44, 0x4f, 0x43, 0x3b, 0x44, -0x41, 0x50, 0x3b, 0x44, 0x47, 0x49, 0x3b, 0x44, 0x41, 0x47, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, -0x63, 0x68, 0x69, 0x65, 0x6c, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x72, 0x69, 0x79, 0x6f, 0x3b, -0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x64, 0x65, 0x6b, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, -0x20, 0x41, 0x6e, 0x67, 0x2019, 0x77, 0x65, 0x6e, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x62, 0x69, -0x63, 0x68, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x75, 0x63, 0x68, 0x69, 0x65, 0x6c, 0x3b, 0x44, -0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x62, 0x69, 0x72, 0x69, 0x79, 0x6f, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, -0x61, 0x72, 0x20, 0x41, 0x62, 0x6f, 0x72, 0x6f, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x4f, 0x63, 0x68, -0x69, 0x6b, 0x6f, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x70, 0x61, 0x72, 0x3b, 0x44, 0x77, 0x65, -0x20, 0x6d, 0x61, 0x72, 0x20, 0x67, 0x69, 0x20, 0x61, 0x63, 0x68, 0x69, 0x65, 0x6c, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, -0x61, 0x72, 0x20, 0x41, 0x70, 0x61, 0x72, 0x20, 0x67, 0x69, 0x20, 0x61, 0x72, 0x69, 0x79, 0x6f, 0x3b, 0x43, 0x3b, 0x52, -0x3b, 0x44, 0x3b, 0x4e, 0x3b, 0x42, 0x3b, 0x55, 0x3b, 0x42, 0x3b, 0x42, 0x3b, 0x43, 0x3b, 0x50, 0x3b, 0x43, 0x3b, 0x50, -0x3b, 0x59, 0x65, 0x6e, 0x3b, 0x59, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x49, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x79, -0x3b, 0x59, 0x75, 0x6e, 0x3b, 0x59, 0x75, 0x6c, 0x3b, 0x194, 0x75, 0x63, 0x3b, 0x43, 0x75, 0x74, 0x3b, 0x4b, 0x1e6d, 0x75, -0x3b, 0x4e, 0x77, 0x61, 0x3b, 0x44, 0x75, 0x6a, 0x3b, 0x59, 0x65, 0x6e, 0x6e, 0x61, 0x79, 0x65, 0x72, 0x3b, 0x59, 0x65, -0x62, 0x72, 0x61, 0x79, 0x65, 0x72, 0x3b, 0x4d, 0x61, 0x72, 0x73, 0x3b, 0x49, 0x62, 0x72, 0x69, 0x72, 0x3b, 0x4d, 0x61, -0x79, 0x79, 0x75, 0x3b, 0x59, 0x75, 0x6e, 0x79, 0x75, 0x3b, 0x59, 0x75, 0x6c, 0x79, 0x75, 0x7a, 0x3b, 0x194, 0x75, 0x63, -0x74, 0x3b, 0x43, 0x75, 0x74, 0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b, 0x4b, 0x1e6d, 0x75, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x77, -0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b, 0x44, 0x75, 0x6a, 0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b, 0x59, 0x3b, 0x59, 0x3b, 0x4d, -0x3b, 0x49, 0x3b, 0x4d, 0x3b, 0x59, 0x3b, 0x59, 0x3b, 0x194, 0x3b, 0x43, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4a, -0x61, 0x6e, 0x75, 0x61, 0x6c, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x6c, 0x75, 0x61, 0x6c, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x68, -0x69, 0x3b, 0x41, 0x70, 0x6c, 0x69, 0x6c, 0x69, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, -0x6c, 0x61, 0x69, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, -0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x65, 0x73, 0x65, 0x6d, -0x62, 0x61, 0x3b, 0x91c, 0x93e, 0x928, 0x941, 0x935, 0x93e, 0x930, 0x940, 0x3b, 0x92b, 0x947, 0x92c, 0x94d, 0x930, 0x941, 0x935, 0x93e, -0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x938, 0x3b, 0x90f, 0x92b, 0x94d, 0x930, 0x93f, 0x932, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, -0x941, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x93e, 0x907, 0x3b, 0x906, 0x917, 0x938, 0x94d, 0x925, 0x3b, 0x938, 0x947, 0x92c, 0x925, 0x947, -0x91c, 0x94d, 0x92c, 0x93c, 0x930, 0x3b, 0x905, 0x916, 0x925, 0x92c, 0x930, 0x3b, 0x928, 0x92c, 0x947, 0x91c, 0x94d, 0x92c, 0x93c, 0x930, -0x3b, 0x926, 0x93f, 0x938, 0x947, 0x91c, 0x94d, 0x92c, 0x93c, 0x930, 0x3b, 0x91c, 0x3b, 0x92b, 0x947, 0x3b, 0x92e, 0x93e, 0x3b, 0x90f, -0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x941, 0x3b, 0x91c, 0x941, 0x3b, 0x906, 0x3b, 0x938, 0x947, 0x3b, 0x905, 0x3b, 0x928, 0x3b, 0x926, -0x93f, 0x3b, 0x456, 0x486, 0x430, 0x2de9, 0x487, 0x3b, 0x444, 0x435, 0x2de1, 0x487, 0x3b, 0x43c, 0x430, 0x2dec, 0x487, 0x3b, 0x430, 0x486, -0x43f, 0x2dec, 0x487, 0x3b, 0x43c, 0x430, 0xa675, 0x3b, 0x456, 0x486, 0xa64b, 0x2de9, 0x487, 0x3b, 0x456, 0x486, 0xa64b, 0x2de7, 0x487, 0x3b, -0x430, 0x486, 0x301, 0x475, 0x2de2, 0x487, 0x3b, 0x441, 0x435, 0x2deb, 0x487, 0x3b, 0x47b, 0x486, 0x43a, 0x2dee, 0x3b, 0x43d, 0x43e, 0x435, -0x2de8, 0x3b, 0x434, 0x435, 0x2de6, 0x487, 0x3b, 0x456, 0x486, 0x430, 0x43d, 0x43d, 0xa64b, 0x430, 0x301, 0x440, 0x457, 0x439, 0x3b, 0x444, -0x435, 0x432, 0x440, 0xa64b, 0x430, 0x301, 0x440, 0x457, 0x439, 0x3b, 0x43c, 0x430, 0x301, 0x440, 0x442, 0x44a, 0x3b, 0x430, 0x486, 0x43f, -0x440, 0x456, 0x301, 0x43b, 0x43b, 0x457, 0x439, 0x3b, 0x43c, 0x430, 0x301, 0x457, 0x439, 0x3b, 0x456, 0x486, 0xa64b, 0x301, 0x43d, 0x457, -0x439, 0x3b, 0x456, 0x486, 0xa64b, 0x301, 0x43b, 0x457, 0x439, 0x3b, 0x430, 0x486, 0x301, 0x475, 0x433, 0xa64b, 0x441, 0x442, 0x44a, 0x3b, -0x441, 0x435, 0x43f, 0x442, 0x435, 0x301, 0x43c, 0x432, 0x440, 0x457, 0x439, 0x3b, 0x47b, 0x486, 0x43a, 0x442, 0x461, 0x301, 0x432, 0x440, -0x457, 0x439, 0x3b, 0x43d, 0x43e, 0x435, 0x301, 0x43c, 0x432, 0x440, 0x457, 0x439, 0x3b, 0x434, 0x435, 0x43a, 0x435, 0x301, 0x43c, 0x432, -0x440, 0x457, 0x439, 0x3b, 0x406, 0x486, 0x3b, 0x424, 0x3b, 0x41c, 0x3b, 0x410, 0x486, 0x3b, 0x41c, 0x3b, 0x406, 0x486, 0x3b, 0x406, -0x486, 0x3b, 0x410, 0x486, 0x3b, 0x421, 0x3b, 0x47a, 0x486, 0x3b, 0x41d, 0x3b, 0x414, 0x3b, 0x456, 0x486, 0x430, 0x43d, 0x43d, 0xa64b, -0x430, 0x301, 0x440, 0x457, 0x430, 0x3b, 0x444, 0x435, 0x432, 0x440, 0xa64b, 0x430, 0x301, 0x440, 0x457, 0x430, 0x3b, 0x43c, 0x430, 0x301, -0x440, 0x442, 0x430, 0x3b, 0x430, 0x486, 0x43f, 0x440, 0x456, 0x301, 0x43b, 0x43b, 0x457, 0x430, 0x3b, 0x43c, 0x430, 0x301, 0x457, 0x430, -0x3b, 0x456, 0x486, 0xa64b, 0x301, 0x43d, 0x457, 0x430, 0x3b, 0x456, 0x486, 0xa64b, 0x301, 0x43b, 0x457, 0x430, 0x3b, 0x430, 0x486, 0x301, -0x475, 0x433, 0xa64b, 0x441, 0x442, 0x430, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x435, 0x301, 0x43c, 0x432, 0x440, 0x457, 0x430, 0x3b, 0x47b, -0x486, 0x43a, 0x442, 0x461, 0x301, 0x432, 0x440, 0x457, 0x430, 0x3b, 0x43d, 0x43e, 0x435, 0x301, 0x43c, 0x432, 0x440, 0x457, 0x430, 0x3b, -0x434, 0x435, 0x43a, 0x435, 0x301, 0x43c, 0x432, 0x440, 0x457, 0x430, 0x3b, 0x43, 0x69, 0x6f, 0x3b, 0x4c, 0x75, 0x69, 0x3b, 0x4c, -0x75, 0x73, 0x3b, 0x4d, 0x75, 0x75, 0x3b, 0x4c, 0x75, 0x6d, 0x3b, 0x4c, 0x75, 0x66, 0x3b, 0x4b, 0x61, 0x62, 0x3b, 0x4c, -0x75, 0x73, 0x68, 0x3b, 0x4c, 0x75, 0x74, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4b, 0x61, 0x73, 0x3b, 0x43, 0x69, 0x73, 0x3b, -0x43, 0x69, 0x6f, 0x6e, 0x67, 0x6f, 0x3b, 0x4c, 0xf9, 0x69, 0x73, 0x68, 0x69, 0x3b, 0x4c, 0x75, 0x73, 0xf2, 0x6c, 0x6f, -0x3b, 0x4d, 0xf9, 0x75, 0x79, 0xe0, 0x3b, 0x4c, 0x75, 0x6d, 0xf9, 0x6e, 0x67, 0xf9, 0x6c, 0xf9, 0x3b, 0x4c, 0x75, 0x66, -0x75, 0x69, 0x6d, 0x69, 0x3b, 0x4b, 0x61, 0x62, 0xe0, 0x6c, 0xe0, 0x73, 0x68, 0xec, 0x70, 0xf9, 0x3b, 0x4c, 0xf9, 0x73, -0x68, 0xec, 0x6b, 0xe0, 0x3b, 0x4c, 0x75, 0x74, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x6f, 0x3b, 0x4c, 0x75, 0x6e, 0x67, 0xf9, -0x64, 0x69, 0x3b, 0x4b, 0x61, 0x73, 0x77, 0xe8, 0x6b, 0xe8, 0x73, 0xe8, 0x3b, 0x43, 0x69, 0x73, 0x77, 0xe0, 0x3b, 0x43, -0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4b, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4b, -0x3b, 0x43, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0xe4, 0x65, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, -0x65, 0x65, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x75, 0x67, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, -0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x7a, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x46, 0x65, -0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x4d, 0xe4, 0x65, 0x72, 0x7a, 0x3b, 0x41, 0x62, 0x72, 0xeb, 0x6c, 0x6c, 0x3b, 0x4d, -0x65, 0x65, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, -0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, -0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x7a, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x61, 0x6e, 0x2e, -0x3b, 0x46, 0x65, 0x62, 0x2e, 0x3b, 0x4d, 0xe4, 0x65, 0x2e, 0x3b, 0x41, 0x62, 0x72, 0x2e, 0x3b, 0x4d, 0x65, 0x65, 0x3b, +0x65, 0x73, 0xe0, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x74, 0x3b, +0x45, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x79, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x61, 0x3b, +0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x79, +0x75, 0x77, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x77, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x74, 0x73, +0x68, 0x69, 0x3b, 0x45, 0x70, 0x72, 0x65, 0x6c, 0x69, 0x3b, 0x4d, 0x65, 0x79, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, +0x4a, 0x75, 0x6c, 0x61, 0x79, 0x69, 0x3b, 0x41, 0x67, 0x61, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, +0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x68, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, +0x69, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x5d9, 0x5d0, 0x5b7, 0x5e0, 0x3b, 0x5e4, 0x5bf, 0x5e2, 0x5d1, 0x3b, 0x5de, 0x5e2, 0x5e8, +0x5e5, 0x3b, 0x5d0, 0x5b7, 0x5e4, 0x5bc, 0x5e8, 0x3b, 0x5de, 0x5d9, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5e0, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dc, +0x5d9, 0x3b, 0x5d0, 0x5d5, 0x5d9, 0x5d2, 0x3b, 0x5e1, 0x5e2, 0x5e4, 0x5bc, 0x3b, 0x5d0, 0x5e7, 0x5d8, 0x3b, 0x5e0, 0x5d0, 0x5d5, 0x5d5, +0x3b, 0x5d3, 0x5e2, 0x5e6, 0x3b, 0x5d9, 0x5d0, 0x5b7, 0x5e0, 0x5d5, 0x5d0, 0x5b7, 0x5e8, 0x3b, 0x5e4, 0x5bf, 0x5e2, 0x5d1, 0x5e8, 0x5d5, +0x5d0, 0x5b7, 0x5e8, 0x3b, 0x5de, 0x5e2, 0x5e8, 0x5e5, 0x3b, 0x5d0, 0x5b7, 0x5e4, 0x5bc, 0x5e8, 0x5d9, 0x5dc, 0x3b, 0x5de, 0x5d9, 0x5d9, +0x3b, 0x5d9, 0x5d5, 0x5e0, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dc, 0x5d9, 0x3b, 0x5d0, 0x5d5, 0x5d9, 0x5d2, 0x5d5, 0x5e1, 0x5d8, 0x3b, 0x5e1, +0x5e2, 0x5e4, 0x5bc, 0x5d8, 0x5e2, 0x5de, 0x5d1, 0x5e2, 0x5e8, 0x3b, 0x5d0, 0x5e7, 0x5d8, 0x5d0, 0x5d1, 0x5e2, 0x5e8, 0x3b, 0x5e0, 0x5d0, +0x5d5, 0x5d5, 0x5e2, 0x5de, 0x5d1, 0x5e2, 0x5e8, 0x3b, 0x5d3, 0x5e2, 0x5e6, 0x5e2, 0x5de, 0x5d1, 0x5e2, 0x5e8, 0x3b, 0x1e62, 0x1eb9, 0x301, +0x72, 0x1eb9, 0x301, 0x3b, 0xc8, 0x72, 0xe8, 0x6c, 0xe8, 0x3b, 0x1eb8, 0x72, 0x1eb9, 0x300, 0x6e, 0xe0, 0x3b, 0xcc, 0x67, 0x62, +0xe9, 0x3b, 0x1eb8, 0x300, 0x62, 0x69, 0x62, 0x69, 0x3b, 0xd2, 0x6b, 0xfa, 0x64, 0x75, 0x3b, 0x41, 0x67, 0x1eb9, 0x6d, 0x1ecd, +0x3b, 0xd2, 0x67, 0xfa, 0x6e, 0x3b, 0x4f, 0x77, 0x65, 0x77, 0x65, 0x3b, 0x1ecc, 0x300, 0x77, 0xe0, 0x72, 0xe0, 0x3b, 0x42, +0xe9, 0x6c, 0xfa, 0x3b, 0x1ecc, 0x300, 0x70, 0x1eb9, 0x300, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1e62, 0x1eb9, 0x301, 0x72, 0x1eb9, 0x301, +0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xc8, 0x72, 0xe8, 0x6c, 0xe8, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1eb8, 0x72, 0x1eb9, 0x300, 0x6e, +0xe0, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xcc, 0x67, 0x62, 0xe9, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1eb8, 0x300, 0x62, 0x69, 0x62, +0x69, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xd2, 0x6b, 0xfa, 0x64, 0x75, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x41, 0x67, 0x1eb9, 0x6d, +0x1ecd, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xd2, 0x67, 0xfa, 0x6e, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x4f, 0x77, 0x65, 0x77, 0x65, +0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1ecc, 0x300, 0x77, 0xe0, 0x72, 0xe0, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x42, 0xe9, 0x6c, 0xfa, +0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1ecc, 0x300, 0x70, 0x1eb9, 0x300, 0x3b, 0x53, 0x68, 0x25b, 0x301, 0x72, 0x25b, 0x301, 0x3b, 0xc8, +0x72, 0xe8, 0x6c, 0xe8, 0x3b, 0x190, 0x72, 0x25b, 0x300, 0x6e, 0xe0, 0x3b, 0xcc, 0x67, 0x62, 0xe9, 0x3b, 0x190, 0x300, 0x62, +0x69, 0x62, 0x69, 0x3b, 0xd2, 0x6b, 0xfa, 0x64, 0x75, 0x3b, 0x41, 0x67, 0x25b, 0x6d, 0x254, 0x3b, 0xd2, 0x67, 0xfa, 0x6e, +0x3b, 0x4f, 0x77, 0x65, 0x77, 0x65, 0x3b, 0x186, 0x300, 0x77, 0xe0, 0x72, 0xe0, 0x3b, 0x42, 0xe9, 0x6c, 0xfa, 0x3b, 0x186, +0x300, 0x70, 0x25b, 0x300, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0x53, 0x68, 0x25b, 0x301, 0x72, 0x25b, 0x301, 0x3b, 0x4f, 0x73, +0x68, 0xf9, 0x20, 0xc8, 0x72, 0xe8, 0x6c, 0xe8, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0x190, 0x72, 0x25b, 0x300, 0x6e, 0xe0, +0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0xcc, 0x67, 0x62, 0xe9, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0x190, 0x300, 0x62, 0x69, +0x62, 0x69, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0xd2, 0x6b, 0xfa, 0x64, 0x75, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0x41, +0x67, 0x25b, 0x6d, 0x254, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0xd2, 0x67, 0xfa, 0x6e, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, +0x4f, 0x77, 0x65, 0x77, 0x65, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0x186, 0x300, 0x77, 0xe0, 0x72, 0xe0, 0x3b, 0x4f, 0x73, +0x68, 0xf9, 0x20, 0x42, 0xe9, 0x6c, 0xfa, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0x186, 0x300, 0x70, 0x25b, 0x300, 0x3b, 0x4a, +0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x73, 0x3b, 0x45, 0x70, 0x68, 0x3b, 0x4d, 0x65, 0x79, 0x3b, 0x4a, +0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x61, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, +0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x77, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, +0x75, 0x77, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x73, 0x68, 0x69, 0x3b, 0x45, 0x70, 0x68, 0x72, 0x65, 0x6c, 0x69, 0x3b, +0x4d, 0x65, 0x79, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x79, 0x69, 0x3b, 0x41, 0x67, 0x61, +0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x68, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x68, 0x6f, 0x62, +0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4a, 0x3b, +0x46, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, +0x44, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, +0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x2e, +0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x73, 0x2e, +0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x74, +0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, +0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x6f, 0x6b, +0x74, 0x6f, 0x62, 0x61, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, +0x62, 0x61, 0x72, 0x3b, 0x458, 0x430, 0x43d, 0x3b, 0x444, 0x435, 0x431, 0x3b, 0x43c, 0x430, 0x440, 0x3b, 0x430, 0x43f, 0x440, 0x3b, +0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x3b, 0x458, 0x443, 0x43b, 0x3b, 0x430, 0x443, 0x433, 0x3b, 0x441, 0x435, 0x43f, 0x3b, +0x43e, 0x43a, 0x442, 0x3b, 0x43d, 0x43e, 0x432, 0x3b, 0x434, 0x435, 0x446, 0x3b, 0x458, 0x430, 0x43d, 0x443, 0x430, 0x440, 0x3b, 0x444, +0x435, 0x431, 0x440, 0x443, 0x430, 0x440, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b, 0x3b, 0x43c, 0x430, +0x458, 0x3b, 0x458, 0x443, 0x43d, 0x438, 0x3b, 0x458, 0x443, 0x43b, 0x438, 0x3b, 0x430, 0x443, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, +0x435, 0x43f, 0x442, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x431, 0x430, 0x440, 0x3b, 0x43d, 0x43e, 0x432, +0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x434, 0x435, 0x446, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x4a, 0x2d, 0x67, 0x75, 0x65, +0x72, 0x3b, 0x54, 0x2d, 0x61, 0x72, 0x72, 0x65, 0x65, 0x3b, 0x4d, 0x61, 0x79, 0x72, 0x6e, 0x74, 0x3b, 0x41, 0x76, 0x72, +0x72, 0x69, 0x6c, 0x3b, 0x42, 0x6f, 0x61, 0x6c, 0x64, 0x79, 0x6e, 0x3b, 0x4d, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x65, 0x65, +0x3b, 0x4a, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x65, 0x65, 0x3b, 0x4c, 0x75, 0x61, 0x6e, 0x69, 0x73, 0x74, 0x79, 0x6e, 0x3b, +0x4d, 0x2d, 0x66, 0x6f, 0x75, 0x79, 0x69, 0x72, 0x3b, 0x4a, 0x2d, 0x66, 0x6f, 0x75, 0x79, 0x69, 0x72, 0x3b, 0x4d, 0x2d, +0x48, 0x6f, 0x75, 0x6e, 0x65, 0x79, 0x3b, 0x4d, 0x2d, 0x4e, 0x6f, 0x6c, 0x6c, 0x69, 0x63, 0x6b, 0x3b, 0x4a, 0x65, 0x72, +0x72, 0x65, 0x79, 0x2d, 0x67, 0x65, 0x75, 0x72, 0x65, 0x65, 0x3b, 0x54, 0x6f, 0x73, 0x68, 0x69, 0x61, 0x67, 0x68, 0x74, +0x2d, 0x61, 0x72, 0x72, 0x65, 0x65, 0x3b, 0x4d, 0x61, 0x79, 0x72, 0x6e, 0x74, 0x3b, 0x41, 0x76, 0x65, 0x72, 0x69, 0x6c, +0x3b, 0x42, 0x6f, 0x61, 0x6c, 0x64, 0x79, 0x6e, 0x3b, 0x4d, 0x65, 0x61, 0x6e, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x65, 0x65, +0x3b, 0x4a, 0x65, 0x72, 0x72, 0x65, 0x79, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x65, 0x65, 0x3b, 0x4c, 0x75, 0x61, 0x6e, 0x69, +0x73, 0x74, 0x79, 0x6e, 0x3b, 0x4d, 0x65, 0x61, 0x6e, 0x2d, 0x66, 0x6f, 0x75, 0x79, 0x69, 0x72, 0x3b, 0x4a, 0x65, 0x72, +0x72, 0x65, 0x79, 0x2d, 0x66, 0x6f, 0x75, 0x79, 0x69, 0x72, 0x3b, 0x4d, 0x65, 0x65, 0x20, 0x48, 0x6f, 0x75, 0x6e, 0x65, +0x79, 0x3b, 0x4d, 0x65, 0x65, 0x20, 0x6e, 0x79, 0x20, 0x4e, 0x6f, 0x6c, 0x6c, 0x69, 0x63, 0x6b, 0x3b, 0x47, 0x65, 0x6e, +0x3b, 0x48, 0x77, 0x65, 0x3b, 0x4d, 0x65, 0x75, 0x3b, 0x45, 0x62, 0x72, 0x3b, 0x4d, 0x65, 0x3b, 0x4d, 0x65, 0x74, 0x3b, +0x47, 0x6f, 0x72, 0x3b, 0x45, 0x73, 0x74, 0x3b, 0x47, 0x77, 0x6e, 0x3b, 0x48, 0x65, 0x64, 0x3b, 0x44, 0x75, 0x3b, 0x4b, +0x65, 0x76, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x47, 0x65, 0x6e, 0x76, 0x65, 0x72, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x48, 0x77, +0x65, 0x76, 0x72, 0x65, 0x72, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x4d, 0x65, 0x75, 0x72, 0x74, 0x68, 0x3b, 0x6d, 0x69, 0x73, +0x20, 0x45, 0x62, 0x72, 0x65, 0x6c, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x4d, 0x65, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x4d, 0x65, +0x74, 0x68, 0x65, 0x76, 0x65, 0x6e, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x47, 0x6f, 0x72, 0x74, 0x68, 0x65, 0x72, 0x65, 0x6e, +0x3b, 0x6d, 0x69, 0x73, 0x20, 0x45, 0x73, 0x74, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x47, 0x77, 0x79, 0x6e, 0x6e, 0x67, 0x61, +0x6c, 0x61, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x48, 0x65, 0x64, 0x72, 0x61, 0x3b, 0x6d, 0x69, 0x73, 0x20, 0x44, 0x75, 0x3b, +0x6d, 0x69, 0x73, 0x20, 0x4b, 0x65, 0x76, 0x61, 0x72, 0x64, 0x68, 0x75, 0x3b, 0x53, 0x2d, 0x186, 0x3b, 0x4b, 0x2d, 0x186, +0x3b, 0x45, 0x2d, 0x186, 0x3b, 0x45, 0x2d, 0x4f, 0x3b, 0x45, 0x2d, 0x4b, 0x3b, 0x4f, 0x2d, 0x41, 0x3b, 0x41, 0x2d, 0x4b, +0x3b, 0x44, 0x2d, 0x186, 0x3b, 0x46, 0x2d, 0x190, 0x3b, 0x186, 0x2d, 0x41, 0x3b, 0x186, 0x2d, 0x4f, 0x3b, 0x4d, 0x2d, 0x186, +0x3b, 0x53, 0x61, 0x6e, 0x64, 0x61, 0x2d, 0x186, 0x70, 0x25b, 0x70, 0x254, 0x6e, 0x3b, 0x4b, 0x77, 0x61, 0x6b, 0x77, 0x61, +0x72, 0x2d, 0x186, 0x67, 0x79, 0x65, 0x66, 0x75, 0x6f, 0x3b, 0x45, 0x62, 0x254, 0x77, 0x2d, 0x186, 0x62, 0x65, 0x6e, 0x65, +0x6d, 0x3b, 0x45, 0x62, 0x254, 0x62, 0x69, 0x72, 0x61, 0x2d, 0x4f, 0x66, 0x6f, 0x72, 0x69, 0x73, 0x75, 0x6f, 0x3b, 0x45, +0x73, 0x75, 0x73, 0x6f, 0x77, 0x20, 0x41, 0x6b, 0x65, 0x74, 0x73, 0x65, 0x61, 0x62, 0x61, 0x2d, 0x4b, 0x254, 0x74, 0x254, +0x6e, 0x69, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x62, 0x69, 0x72, 0x61, 0x64, 0x65, 0x2d, 0x41, 0x79, 0x25b, 0x77, 0x6f, 0x68, +0x6f, 0x6d, 0x75, 0x6d, 0x75, 0x3b, 0x41, 0x79, 0x25b, 0x77, 0x6f, 0x68, 0x6f, 0x2d, 0x4b, 0x69, 0x74, 0x61, 0x77, 0x6f, +0x6e, 0x73, 0x61, 0x3b, 0x44, 0x69, 0x66, 0x75, 0x75, 0x2d, 0x186, 0x73, 0x61, 0x6e, 0x64, 0x61, 0x61, 0x3b, 0x46, 0x61, +0x6e, 0x6b, 0x77, 0x61, 0x2d, 0x190, 0x62, 0x254, 0x3b, 0x186, 0x62, 0x25b, 0x73, 0x25b, 0x2d, 0x41, 0x68, 0x69, 0x6e, 0x69, +0x6d, 0x65, 0x3b, 0x186, 0x62, 0x65, 0x72, 0x25b, 0x66, 0x25b, 0x77, 0x2d, 0x4f, 0x62, 0x75, 0x62, 0x75, 0x6f, 0x3b, 0x4d, +0x75, 0x6d, 0x75, 0x2d, 0x186, 0x70, 0x25b, 0x6e, 0x69, 0x6d, 0x62, 0x61, 0x3b, 0x91c, 0x93e, 0x928, 0x947, 0x935, 0x93e, 0x930, +0x940, 0x3b, 0x92b, 0x947, 0x92c, 0x94d, 0x930, 0x941, 0x935, 0x93e, 0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x90f, +0x92a, 0x94d, 0x930, 0x93f, 0x932, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x942, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x93e, 0x92f, 0x3b, 0x906, +0x917, 0x94b, 0x938, 0x94d, 0x924, 0x3b, 0x938, 0x92a, 0x94d, 0x91f, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x911, 0x915, 0x94d, 0x91f, 0x94b, +0x92c, 0x930, 0x3b, 0x928, 0x94b, 0x935, 0x94d, 0x939, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x921, 0x93f, 0x938, 0x947, 0x902, 0x92c, 0x930, +0x3b, 0x4a, 0x65, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x61, 0x3b, 0x45, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x65, +0x3b, 0x4a, 0x75, 0x75, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x1ecc, 0x67, 0x1ecd, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x1ecc, 0x6b, 0x74, +0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x65, 0x6e, 0x1ee5, 0x77, 0x61, 0x72, 0x1ecb, 0x3b, 0x46, 0x65, +0x62, 0x72, 0x1ee5, 0x77, 0x61, 0x72, 0x1ecb, 0x3b, 0x4d, 0x61, 0x61, 0x63, 0x68, 0x1ecb, 0x3b, 0x45, 0x70, 0x72, 0x65, 0x6c, +0x3b, 0x4d, 0x65, 0x65, 0x3b, 0x4a, 0x75, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x1ecb, 0x3b, 0x1ecc, 0x67, 0x1ecd, 0x1ecd, +0x73, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x1ecc, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, +0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4d, 0x62, 0x65, 0x3b, 0x4b, +0x65, 0x6c, 0x3b, 0x4b, 0x74, 0x169, 0x3b, 0x4b, 0x61, 0x6e, 0x3b, 0x4b, 0x74, 0x6e, 0x3b, 0x54, 0x68, 0x61, 0x3b, 0x4d, +0x6f, 0x6f, 0x3b, 0x4e, 0x79, 0x61, 0x3b, 0x4b, 0x6e, 0x64, 0x3b, 0x128, 0x6b, 0x75, 0x3b, 0x128, 0x6b, 0x6d, 0x3b, 0x128, +0x6b, 0x6c, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6d, 0x62, 0x65, 0x65, 0x3b, 0x4d, 0x77, 0x61, 0x69, +0x20, 0x77, 0x61, 0x20, 0x6b, 0x65, 0x6c, 0x129, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x74, +0x61, 0x74, 0x169, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x77, 0x61, +0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, +0x74, 0x68, 0x61, 0x6e, 0x74, 0x68, 0x61, 0x74, 0x169, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6d, 0x75, +0x6f, 0x6e, 0x7a, 0x61, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6e, 0x79, 0x61, 0x61, 0x6e, 0x79, 0x61, +0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, +0x77, 0x61, 0x20, 0x129, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x129, 0x6b, 0x75, +0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x129, 0x6d, 0x77, 0x65, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x129, +0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x69, 0x6c, 0x129, 0x3b, 0x4d, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, +0x4b, 0x3b, 0x54, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x4b, 0x3b, 0x128, 0x3b, 0x128, 0x3b, 0x128, 0x3b, 0x5a, 0x65, 0x6e, 0x3b, +0x46, 0x65, 0x76, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x76, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x67, 0x3b, +0x4c, 0x75, 0x69, 0x3b, 0x41, 0x76, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x74, 0x75, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, +0x44, 0x69, 0x63, 0x3b, 0x5a, 0x65, 0x6e, 0xe2, 0x72, 0x3b, 0x46, 0x65, 0x76, 0x72, 0xe2, 0x72, 0x3b, 0x4d, 0x61, 0x72, +0xe7, 0x3b, 0x41, 0x76, 0x72, 0xee, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x67, 0x6e, 0x3b, 0x4c, 0x75, 0x69, +0x3b, 0x41, 0x76, 0x6f, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x4f, 0x74, 0x75, 0x62, +0x61, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x44, 0x69, 0x63, 0x65, 0x6d, 0x62, 0x61, 0x72, +0x3b, 0x5a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4c, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, +0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x64, 0x7a, 0x76, 0x3b, 0x64, 0x7a, 0x64, 0x3b, 0x74, 0x65, 0x64, 0x3b, 0x61, 0x66, 0x254, +0x3b, 0x64, 0x61, 0x6d, 0x3b, 0x6d, 0x61, 0x73, 0x3b, 0x73, 0x69, 0x61, 0x3b, 0x64, 0x65, 0x61, 0x3b, 0x61, 0x6e, 0x79, +0x3b, 0x6b, 0x65, 0x6c, 0x3b, 0x61, 0x64, 0x65, 0x3b, 0x64, 0x7a, 0x6d, 0x3b, 0x64, 0x7a, 0x6f, 0x76, 0x65, 0x3b, 0x64, +0x7a, 0x6f, 0x64, 0x7a, 0x65, 0x3b, 0x74, 0x65, 0x64, 0x6f, 0x78, 0x65, 0x3b, 0x61, 0x66, 0x254, 0x66, 0x129, 0x65, 0x3b, +0x64, 0x61, 0x6d, 0x61, 0x3b, 0x6d, 0x61, 0x73, 0x61, 0x3b, 0x73, 0x69, 0x61, 0x6d, 0x6c, 0x254, 0x6d, 0x3b, 0x64, 0x65, +0x61, 0x73, 0x69, 0x61, 0x6d, 0x69, 0x6d, 0x65, 0x3b, 0x61, 0x6e, 0x79, 0x254, 0x6e, 0x79, 0x254, 0x3b, 0x6b, 0x65, 0x6c, +0x65, 0x3b, 0x61, 0x64, 0x65, 0x25b, 0x6d, 0x65, 0x6b, 0x70, 0x254, 0x78, 0x65, 0x3b, 0x64, 0x7a, 0x6f, 0x6d, 0x65, 0x3b, +0x64, 0x3b, 0x64, 0x3b, 0x74, 0x3b, 0x61, 0x3b, 0x64, 0x3b, 0x6d, 0x3b, 0x73, 0x3b, 0x64, 0x3b, 0x61, 0x3b, 0x6b, 0x3b, +0x61, 0x3b, 0x64, 0x3b, 0x49, 0x61, 0x6e, 0x2e, 0x3b, 0x50, 0x65, 0x70, 0x2e, 0x3b, 0x4d, 0x61, 0x6c, 0x2e, 0x3b, 0x2bb, +0x41, 0x70, 0x2e, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x49, 0x75, 0x6e, 0x2e, 0x3b, 0x49, 0x75, 0x6c, 0x2e, 0x3b, 0x2bb, 0x41, +0x75, 0x2e, 0x3b, 0x4b, 0x65, 0x70, 0x2e, 0x3b, 0x2bb, 0x4f, 0x6b, 0x2e, 0x3b, 0x4e, 0x6f, 0x77, 0x2e, 0x3b, 0x4b, 0x65, +0x6b, 0x2e, 0x3b, 0x49, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x69, 0x3b, 0x50, 0x65, 0x70, 0x65, 0x6c, 0x75, 0x61, 0x6c, 0x69, +0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x6b, 0x69, 0x3b, 0x2bb, 0x41, 0x70, 0x65, 0x6c, 0x69, 0x6c, 0x61, 0x3b, 0x4d, 0x65, 0x69, +0x3b, 0x49, 0x75, 0x6e, 0x65, 0x3b, 0x49, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x2bb, 0x41, 0x75, 0x6b, 0x61, 0x6b, 0x65, 0x3b, +0x4b, 0x65, 0x70, 0x61, 0x6b, 0x65, 0x6d, 0x61, 0x70, 0x61, 0x3b, 0x2bb, 0x4f, 0x6b, 0x61, 0x6b, 0x6f, 0x70, 0x61, 0x3b, +0x4e, 0x6f, 0x77, 0x65, 0x6d, 0x61, 0x70, 0x61, 0x3b, 0x4b, 0x65, 0x6b, 0x65, 0x6d, 0x61, 0x70, 0x61, 0x3b, 0x45, 0x6e, +0x65, 0x3b, 0x50, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x48, 0x75, +0x6e, 0x3b, 0x48, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, +0x62, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x45, 0x6e, 0x65, 0x72, 0x6f, 0x3b, 0x50, 0x65, 0x62, 0x72, 0x65, 0x72, 0x6f, 0x3b, +0x4d, 0x61, 0x72, 0x73, 0x6f, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x79, 0x6f, 0x3b, 0x48, 0x75, 0x6e, +0x79, 0x6f, 0x3b, 0x48, 0x75, 0x6c, 0x79, 0x6f, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x79, +0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x4f, 0x6b, 0x74, 0x75, 0x62, 0x72, 0x65, 0x3b, 0x4e, 0x6f, 0x62, 0x79, 0x65, 0x6d, +0x62, 0x72, 0x65, 0x3b, 0x44, 0x69, 0x73, 0x79, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x45, 0x3b, 0x50, 0x3b, 0x4d, 0x3b, +0x41, 0x3b, 0x4d, 0x3b, 0x48, 0x75, 0x6e, 0x3b, 0x48, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x3b, +0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x62, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x46, +0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, +0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x63, 0x68, 0x74, +0x3b, 0x53, 0x65, 0x70, 0x74, 0xe4, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x6f, 0x62, 0x65, 0x72, 0x3b, +0x4e, 0x6f, 0x76, 0xe4, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x7a, 0xe4, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0xa2cd, 0xa1aa, +0x3b, 0xa44d, 0xa1aa, 0x3b, 0xa315, 0xa1aa, 0x3b, 0xa1d6, 0xa1aa, 0x3b, 0xa26c, 0xa1aa, 0x3b, 0xa0d8, 0xa1aa, 0x3b, 0xa3c3, 0xa1aa, 0x3b, 0xa246, +0xa1aa, 0x3b, 0xa22c, 0xa1aa, 0x3b, 0xa2b0, 0xa1aa, 0x3b, 0xa2b0, 0xa2aa, 0xa1aa, 0x3b, 0xa2b0, 0xa44b, 0xa1aa, 0x3b, 0x4a, 0x61, 0x6e, 0x2e, +0x3b, 0x46, 0x65, 0x62, 0x2e, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x2e, 0x3b, 0x53, 0x65, 0x70, 0x2e, 0x3b, -0x4f, 0x6b, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x65, 0x7a, 0x2e, 0x3b, 0x6e, 0xf9, 0x6d, 0x3b, 0x6b, -0x268, 0x7a, 0x3b, 0x74, 0x268, 0x64, 0x3b, 0x74, 0x61, 0x61, 0x3b, 0x73, 0x65, 0x65, 0x3b, 0x6e, 0x7a, 0x75, 0x3b, 0x64, -0x75, 0x6d, 0x3b, 0x66, 0x254, 0x65, 0x3b, 0x64, 0x7a, 0x75, 0x3b, 0x6c, 0x254, 0x6d, 0x3b, 0x6b, 0x61, 0x61, 0x3b, 0x66, -0x77, 0x6f, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x6e, 0xf9, 0x6d, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, -0x14b, 0x254, 0x300, 0x6b, 0x197, 0x300, 0x7a, 0xf9, 0x294, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x74, 0x197, -0x300, 0x64, 0x289, 0x300, 0x67, 0x68, 0xe0, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x74, 0x1ce, 0x61, 0x66, -0x289, 0x304, 0x67, 0x68, 0x101, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0xe8, 0x73, 0xe8, 0x65, 0x3b, 0x6e, 0x64, 0x7a, -0x254, 0x300, 0x14b, 0x254, 0x300, 0x6e, 0x7a, 0xf9, 0x67, 0x68, 0xf2, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, -0x64, 0xf9, 0x6d, 0x6c, 0x6f, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x6b, 0x77, 0xee, 0x66, 0x254, 0x300, -0x65, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x74, 0x197, 0x300, 0x66, 0x289, 0x300, 0x67, 0x68, 0xe0, 0x64, -0x7a, 0x75, 0x67, 0x68, 0xf9, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x67, 0x68, 0x1d4, 0x75, 0x77, 0x65, -0x6c, 0x254, 0x300, 0x6d, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x63, 0x68, 0x77, 0x61, 0x294, 0xe0, 0x6b, -0x61, 0x61, 0x20, 0x77, 0x6f, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0xe8, 0x66, 0x77, 0xf2, 0x6f, 0x3b, 0x6e, 0x3b, -0x6b, 0x3b, 0x74, 0x3b, 0x74, 0x3b, 0x73, 0x3b, 0x7a, 0x3b, 0x6b, 0x3b, 0x66, 0x3b, 0x64, 0x3b, 0x6c, 0x3b, 0x63, 0x3b, -0x66, 0x3b, 0x6b, 0x254, 0x6e, 0x3b, 0x6d, 0x61, 0x63, 0x3b, 0x6d, 0x61, 0x74, 0x3b, 0x6d, 0x74, 0x6f, 0x3b, 0x6d, 0x70, -0x75, 0x3b, 0x68, 0x69, 0x6c, 0x3b, 0x6e, 0x6a, 0x65, 0x3b, 0x68, 0x69, 0x6b, 0x3b, 0x64, 0x69, 0x70, 0x3b, 0x62, 0x69, -0x6f, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x6c, 0x69, 0x253, 0x3b, 0x4b, 0x254, 0x6e, 0x64, 0x254, 0x14b, 0x3b, 0x4d, 0xe0, 0x63, -0x25b, 0x302, 0x6c, 0x3b, 0x4d, 0xe0, 0x74, 0xf9, 0x6d, 0x62, 0x3b, 0x4d, 0xe0, 0x74, 0x6f, 0x70, 0x3b, 0x4d, 0x300, 0x70, -0x75, 0x79, 0x25b, 0x3b, 0x48, 0xec, 0x6c, 0xf2, 0x6e, 0x64, 0x25b, 0x300, 0x3b, 0x4e, 0x6a, 0xe8, 0x62, 0xe0, 0x3b, 0x48, -0xec, 0x6b, 0x61, 0x14b, 0x3b, 0x44, 0xec, 0x70, 0x254, 0x300, 0x73, 0x3b, 0x42, 0xec, 0xf2, 0xf4, 0x6d, 0x3b, 0x4d, 0xe0, -0x79, 0x25b, 0x73, 0xe8, 0x70, 0x3b, 0x4c, 0xec, 0x62, 0x75, 0x79, 0x20, 0x6c, 0x69, 0x20, 0x144, 0x79, 0xe8, 0x65, 0x3b, -0x6b, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x68, 0x3b, 0x6e, 0x3b, 0x68, 0x3b, 0x64, 0x3b, 0x62, 0x3b, -0x6d, 0x3b, 0x6c, 0x3b, 0x64, 0x69, 0x3b, 0x14b, 0x67, 0x254, 0x6e, 0x3b, 0x73, 0x254, 0x14b, 0x3b, 0x64, 0x69, 0x253, 0x3b, -0x65, 0x6d, 0x69, 0x3b, 0x65, 0x73, 0x254, 0x3b, 0x6d, 0x61, 0x64, 0x3b, 0x64, 0x69, 0x14b, 0x3b, 0x6e, 0x79, 0x25b, 0x74, -0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x74, 0x69, 0x6e, 0x3b, 0x65, 0x6c, 0xe1, 0x3b, 0x64, 0x69, 0x6d, 0x254, 0x301, 0x64, 0x69, -0x3b, 0x14b, 0x67, 0x254, 0x6e, 0x64, 0x25b, 0x3b, 0x73, 0x254, 0x14b, 0x25b, 0x3b, 0x64, 0x69, 0x253, 0xe1, 0x253, 0xe1, 0x3b, -0x65, 0x6d, 0x69, 0x61, 0x73, 0x65, 0x6c, 0x65, 0x3b, 0x65, 0x73, 0x254, 0x70, 0x25b, 0x73, 0x254, 0x70, 0x25b, 0x3b, 0x6d, -0x61, 0x64, 0x69, 0x253, 0x25b, 0x301, 0x64, 0xed, 0x253, 0x25b, 0x301, 0x3b, 0x64, 0x69, 0x14b, 0x67, 0x69, 0x6e, 0x64, 0x69, -0x3b, 0x6e, 0x79, 0x25b, 0x74, 0x25b, 0x6b, 0x69, 0x3b, 0x6d, 0x61, 0x79, 0xe9, 0x73, 0x25b, 0x301, 0x3b, 0x74, 0x69, 0x6e, -0xed, 0x6e, 0xed, 0x3b, 0x65, 0x6c, 0xe1, 0x14b, 0x67, 0x25b, 0x301, 0x3b, 0x64, 0x3b, 0x14b, 0x3b, 0x73, 0x3b, 0x64, 0x3b, -0x65, 0x3b, 0x65, 0x3b, 0x6d, 0x3b, 0x64, 0x3b, 0x6e, 0x3b, 0x6d, 0x3b, 0x74, 0x3b, 0x65, 0x3b, 0x53, 0x61, 0x3b, 0x46, -0x65, 0x3b, 0x4d, 0x61, 0x3b, 0x41, 0x62, 0x3b, 0x4d, 0x65, 0x3b, 0x53, 0x75, 0x3b, 0x53, 0xfa, 0x3b, 0x55, 0x74, 0x3b, -0x53, 0x65, 0x3b, 0x4f, 0x6b, 0x3b, 0x4e, 0x6f, 0x3b, 0x44, 0x65, 0x3b, 0x53, 0x61, 0x6e, 0x76, 0x69, 0x65, 0x3b, 0x46, -0xe9, 0x62, 0x69, 0x72, 0x69, 0x65, 0x3b, 0x4d, 0x61, 0x72, 0x73, 0x3b, 0x41, 0x62, 0x75, 0x72, 0x69, 0x6c, 0x3b, 0x4d, -0x65, 0x65, 0x3b, 0x53, 0x75, 0x65, 0x14b, 0x3b, 0x53, 0xfa, 0x75, 0x79, 0x65, 0x65, 0x3b, 0x55, 0x74, 0x3b, 0x53, 0x65, -0x74, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, -0x6d, 0x62, 0x61, 0x72, 0x3b, 0x44, 0x69, 0x73, 0x61, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x53, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, -0x41, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x55, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x6e, 0x67, -0x6f, 0x3b, 0x6e, 0x67, 0x62, 0x3b, 0x6e, 0x67, 0x6c, 0x3b, 0x6e, 0x67, 0x6e, 0x3b, 0x6e, 0x67, 0x74, 0x3b, 0x6e, 0x67, -0x73, 0x3b, 0x6e, 0x67, 0x7a, 0x3b, 0x6e, 0x67, 0x6d, 0x3b, 0x6e, 0x67, 0x65, 0x3b, 0x6e, 0x67, 0x61, 0x3b, 0x6e, 0x67, -0x61, 0x64, 0x3b, 0x6e, 0x67, 0x61, 0x62, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x6f, 0x73, 0xfa, 0x3b, 0x6e, 0x67, 0x254, -0x6e, 0x20, 0x62, 0x25b, 0x30c, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x6c, 0xe1, 0x6c, 0x61, 0x3b, 0x6e, 0x67, 0x254, 0x6e, -0x20, 0x6e, 0x79, 0x69, 0x6e, 0x61, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x74, 0xe1, 0x6e, 0x61, 0x3b, 0x6e, 0x67, 0x254, -0x6e, 0x20, 0x73, 0x61, 0x6d, 0x259, 0x6e, 0x61, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x7a, 0x61, 0x6d, 0x67, 0x62, 0xe1, -0x6c, 0x61, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x6d, 0x77, 0x6f, 0x6d, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x65, 0x62, -0x75, 0x6c, 0xfa, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x61, 0x77, 0xf3, 0x6d, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x61, -0x77, 0xf3, 0x6d, 0x20, 0x61, 0x69, 0x20, 0x64, 0x7a, 0x69, 0xe1, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x61, 0x77, 0xf3, -0x6d, 0x20, 0x61, 0x69, 0x20, 0x62, 0x25b, 0x30c, 0x3b, 0x6f, 0x3b, 0x62, 0x3b, 0x6c, 0x3b, 0x6e, 0x3b, 0x74, 0x3b, 0x73, -0x3b, 0x7a, 0x3b, 0x6d, 0x3b, 0x65, 0x3b, 0x61, 0x3b, 0x64, 0x3b, 0x62, 0x3b, 0x14b, 0x31, 0x3b, 0x14b, 0x32, 0x3b, 0x14b, -0x33, 0x3b, 0x14b, 0x34, 0x3b, 0x14b, 0x35, 0x3b, 0x14b, 0x36, 0x3b, 0x14b, 0x37, 0x3b, 0x14b, 0x38, 0x3b, 0x14b, 0x39, 0x3b, -0x14b, 0x31, 0x30, 0x3b, 0x14b, 0x31, 0x31, 0x3b, 0x14b, 0x31, 0x32, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x20, 0x6e, -0x74, 0x254, 0x301, 0x6e, 0x74, 0x254, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x62, 0x25b, 0x301, 0x25b, -0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x72, 0xe1, 0xe1, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, -0x6b, 0x1dd, 0x20, 0x6e, 0x69, 0x6e, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x74, 0xe1, 0x61, 0x6e, -0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x74, 0xe1, 0x61, 0x66, 0x254, 0x6b, 0x3b, 0x14b, 0x77, 0xed, -0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x74, 0xe1, 0x61, 0x62, 0x25b, 0x25b, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, -0x1dd, 0x20, 0x74, 0xe1, 0x61, 0x72, 0x61, 0x61, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x74, 0xe1, -0x61, 0x6e, 0x69, 0x6e, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x6e, 0x74, 0x25b, 0x6b, 0x3b, 0x14b, -0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x6e, 0x74, 0x25b, 0x6b, 0x20, 0x64, 0x69, 0x20, 0x62, 0x254, 0x301, 0x6b, -0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x6e, 0x74, 0x25b, 0x6b, 0x20, 0x64, 0x69, 0x20, 0x62, 0x25b, -0x301, 0x25b, 0x3b, 0x4b, 0x77, 0x61, 0x3b, 0x55, 0x6e, 0x61, 0x3b, 0x52, 0x61, 0x72, 0x3b, 0x43, 0x68, 0x65, 0x3b, 0x54, -0x68, 0x61, 0x3b, 0x4d, 0x6f, 0x63, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4e, 0x61, 0x6e, 0x3b, 0x54, 0x69, 0x73, 0x3b, 0x4b, -0x75, 0x6d, 0x3b, 0x4d, 0x6f, 0x6a, 0x3b, 0x59, 0x65, 0x6c, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, -0x6b, 0x77, 0x61, 0x6e, 0x7a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x75, 0x6e, 0x61, 0x79, -0x65, 0x6c, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x75, 0x6e, 0x65, 0x72, 0x61, 0x72, 0x75, -0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x75, 0x6e, 0x65, 0x63, 0x68, 0x65, 0x73, 0x68, 0x65, 0x3b, -0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x75, 0x6e, 0x65, 0x74, 0x68, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x77, -0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x75, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x6f, 0x63, 0x68, -0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x73, 0x61, 0x62, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, -0x69, 0x20, 0x77, 0x6f, 0x20, 0x6e, 0x61, 0x6e, 0x65, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x74, -0x69, 0x73, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4d, 0x77, -0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x6f, 0x6a, 0x61, 0x3b, -0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x79, 0x65, 0x6c, -0x2019, 0x6c, 0x69, 0x3b, 0x4b, 0x3b, 0x55, 0x3b, 0x52, 0x3b, 0x43, 0x3b, 0x54, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x4e, 0x3b, -0x54, 0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x59, 0x3b, 0x46, 0x4c, 0x4f, 0x3b, 0x43, 0x4c, 0x41, 0x3b, 0x43, 0x4b, 0x49, 0x3b, -0x46, 0x4d, 0x46, 0x3b, 0x4d, 0x41, 0x44, 0x3b, 0x4d, 0x42, 0x49, 0x3b, 0x4d, 0x4c, 0x49, 0x3b, 0x4d, 0x41, 0x4d, 0x3b, -0x46, 0x44, 0x45, 0x3b, 0x46, 0x4d, 0x55, 0x3b, 0x46, 0x47, 0x57, 0x3b, 0x46, 0x59, 0x55, 0x3b, 0x46, 0x129, 0x69, 0x20, -0x4c, 0x6f, 0x6f, 0x3b, 0x43, 0x6f, 0x6b, 0x63, 0x77, 0x61, 0x6b, 0x6c, 0x61, 0x14b, 0x6e, 0x65, 0x3b, 0x43, 0x6f, 0x6b, -0x63, 0x77, 0x61, 0x6b, 0x6c, 0x69, 0x69, 0x3b, 0x46, 0x129, 0x69, 0x20, 0x4d, 0x61, 0x72, 0x66, 0x6f, 0x6f, 0x3b, 0x4d, -0x61, 0x64, 0x1dd, 0x1dd, 0x75, 0x75, 0x74, 0x1dd, 0x62, 0x69, 0x6a, 0x61, 0x14b, 0x3b, 0x4d, 0x61, 0x6d, 0x1dd, 0x14b, 0x67, -0x77, 0xe3, 0x61, 0x66, 0x61, 0x68, 0x62, 0x69, 0x69, 0x3b, 0x4d, 0x61, 0x6d, 0x1dd, 0x14b, 0x67, 0x77, 0xe3, 0x61, 0x6c, -0x69, 0x69, 0x3b, 0x4d, 0x61, 0x64, 0x1dd, 0x6d, 0x62, 0x69, 0x69, 0x3b, 0x46, 0x129, 0x69, 0x20, 0x44, 0x1dd, 0x253, 0x6c, -0x69, 0x69, 0x3b, 0x46, 0x129, 0x69, 0x20, 0x4d, 0x75, 0x6e, 0x64, 0x61, 0x14b, 0x3b, 0x46, 0x129, 0x69, 0x20, 0x47, 0x77, -0x61, 0x68, 0x6c, 0x6c, 0x65, 0x3b, 0x46, 0x129, 0x69, 0x20, 0x59, 0x75, 0x72, 0x75, 0x3b, 0x4f, 0x3b, 0x41, 0x3b, 0x49, -0x3b, 0x46, 0x3b, 0x44, 0x3b, 0x42, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x55, 0x3b, 0x57, 0x3b, 0x59, 0x3b, 0x6e, -0x67, 0x31, 0x3b, 0x6e, 0x67, 0x32, 0x3b, 0x6e, 0x67, 0x33, 0x3b, 0x6e, 0x67, 0x34, 0x3b, 0x6e, 0x67, 0x35, 0x3b, 0x6e, -0x67, 0x36, 0x3b, 0x6e, 0x67, 0x37, 0x3b, 0x6e, 0x67, 0x38, 0x3b, 0x6e, 0x67, 0x39, 0x3b, 0x6e, 0x67, 0x31, 0x30, 0x3b, -0x6e, 0x67, 0x31, 0x31, 0x3b, 0x6b, 0x72, 0x69, 0x73, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0xe1, -0x68, 0x72, 0x61, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x144, 0x6d, 0x62, 0x61, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, -0x20, 0x144, 0x6c, 0x61, 0x6c, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x144, 0x6e, 0x61, 0x3b, 0x6e, 0x67, 0x77, 0x25b, -0x6e, 0x20, 0x144, 0x74, 0x61, 0x6e, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x144, 0x74, 0x75, 0xf3, 0x3b, 0x6e, 0x67, -0x77, 0x25b, 0x6e, 0x20, 0x68, 0x25b, 0x6d, 0x62, 0x75, 0x25b, 0x72, 0xed, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x6c, -0x254, 0x6d, 0x62, 0x69, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x72, 0x25b, 0x62, 0x76, 0x75, 0xe2, 0x3b, 0x6e, 0x67, -0x77, 0x25b, 0x6e, 0x20, 0x77, 0x75, 0x6d, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x77, 0x75, 0x6d, 0x20, 0x6e, 0x61, -0x76, 0x1d4, 0x72, 0x3b, 0x6b, 0x72, 0xed, 0x73, 0x69, 0x6d, 0x69, 0x6e, 0x3b, 0x54, 0x69, 0x6f, 0x70, 0x3b, 0x50, 0x25b, -0x74, 0x3b, 0x44, 0x75, 0x254, 0x331, 0x254, 0x331, 0x3b, 0x47, 0x75, 0x61, 0x6b, 0x3b, 0x44, 0x75, 0xe4, 0x3b, 0x4b, 0x6f, -0x72, 0x3b, 0x50, 0x61, 0x79, 0x3b, 0x54, 0x68, 0x6f, 0x6f, 0x3b, 0x54, 0x25b, 0x25b, 0x3b, 0x4c, 0x61, 0x61, 0x3b, 0x4b, -0x75, 0x72, 0x3b, 0x54, 0x69, 0x64, 0x3b, 0x54, 0x69, 0x6f, 0x70, 0x20, 0x74, 0x68, 0x61, 0x72, 0x20, 0x70, 0x25b, 0x74, -0x3b, 0x50, 0x25b, 0x74, 0x3b, 0x44, 0x75, 0x254, 0x331, 0x254, 0x331, 0x14b, 0x3b, 0x47, 0x75, 0x61, 0x6b, 0x3b, 0x44, 0x75, -0xe4, 0x74, 0x3b, 0x4b, 0x6f, 0x72, 0x6e, 0x79, 0x6f, 0x6f, 0x74, 0x3b, 0x50, 0x61, 0x79, 0x20, 0x79, 0x69, 0x65, 0x331, -0x74, 0x6e, 0x69, 0x3b, 0x54, 0x68, 0x6f, 0x331, 0x6f, 0x331, 0x72, 0x3b, 0x54, 0x25b, 0x25b, 0x72, 0x3b, 0x4c, 0x61, 0x61, -0x74, 0x68, 0x3b, 0x4b, 0x75, 0x72, 0x3b, 0x54, 0x69, 0x6f, 0x331, 0x70, 0x20, 0x69, 0x6e, 0x20, 0x64, 0x69, 0x331, 0x69, -0x331, 0x74, 0x3b, 0x54, 0x3b, 0x50, 0x3b, 0x44, 0x3b, 0x47, 0x3b, 0x44, 0x3b, 0x4b, 0x3b, 0x50, 0x3b, 0x54, 0x3b, 0x54, -0x3b, 0x4c, 0x3b, 0x4b, 0x3b, 0x54, 0x3b, 0x422, 0x43e, 0x445, 0x441, 0x3b, 0x41e, 0x43b, 0x443, 0x43d, 0x3b, 0x41a, 0x43b, 0x43d, -0x3b, 0x41c, 0x441, 0x443, 0x3b, 0x42b, 0x430, 0x43c, 0x3b, 0x411, 0x44d, 0x441, 0x3b, 0x41e, 0x442, 0x439, 0x3b, 0x410, 0x442, 0x440, -0x3b, 0x411, 0x43b, 0x495, 0x3b, 0x410, 0x43b, 0x442, 0x3b, 0x421, 0x44d, 0x442, 0x3b, 0x410, 0x445, 0x441, 0x3b, 0x442, 0x43e, 0x445, -0x441, 0x443, 0x43d, 0x43d, 0x44c, 0x443, 0x3b, 0x43e, 0x43b, 0x443, 0x43d, 0x43d, 0x44c, 0x443, 0x3b, 0x43a, 0x443, 0x43b, 0x443, 0x43d, -0x20, 0x442, 0x443, 0x442, 0x430, 0x440, 0x3b, 0x43c, 0x443, 0x443, 0x441, 0x20, 0x443, 0x441, 0x442, 0x430, 0x440, 0x3b, 0x44b, 0x430, -0x43c, 0x20, 0x44b, 0x439, 0x430, 0x3b, 0x431, 0x44d, 0x441, 0x20, 0x44b, 0x439, 0x430, 0x3b, 0x43e, 0x442, 0x20, 0x44b, 0x439, 0x430, -0x3b, 0x430, 0x442, 0x44b, 0x440, 0x434, 0x44c, 0x44b, 0x445, 0x20, 0x44b, 0x439, 0x430, 0x3b, 0x431, 0x430, 0x43b, 0x430, 0x495, 0x430, -0x43d, 0x20, 0x44b, 0x439, 0x430, 0x3b, 0x430, 0x43b, 0x442, 0x44b, 0x43d, 0x43d, 0x44c, 0x44b, 0x3b, 0x441, 0x44d, 0x442, 0x438, 0x43d, -0x43d, 0x44c, 0x438, 0x3b, 0x430, 0x445, 0x441, 0x44b, 0x43d, 0x43d, 0x44c, 0x44b, 0x3b, 0x422, 0x3b, 0x41e, 0x3b, 0x41a, 0x3b, 0x41c, -0x3b, 0x42b, 0x3b, 0x411, 0x3b, 0x41e, 0x3b, 0x410, 0x3b, 0x411, 0x3b, 0x410, 0x3b, 0x421, 0x3b, 0x410, 0x3b, 0x422, 0x43e, 0x445, -0x441, 0x443, 0x43d, 0x43d, 0x44c, 0x443, 0x3b, 0x41e, 0x43b, 0x443, 0x43d, 0x43d, 0x44c, 0x443, 0x3b, 0x41a, 0x443, 0x43b, 0x443, 0x43d, -0x20, 0x442, 0x443, 0x442, 0x430, 0x440, 0x3b, 0x41c, 0x443, 0x443, 0x441, 0x20, 0x443, 0x441, 0x442, 0x430, 0x440, 0x3b, 0x42b, 0x430, -0x43c, 0x20, 0x44b, 0x439, 0x44b, 0x43d, 0x3b, 0x411, 0x44d, 0x441, 0x20, 0x44b, 0x439, 0x44b, 0x43d, 0x3b, 0x41e, 0x442, 0x20, 0x44b, -0x439, 0x44b, 0x43d, 0x3b, 0x410, 0x442, 0x44b, 0x440, 0x434, 0x44c, 0x44b, 0x445, 0x20, 0x44b, 0x439, 0x44b, 0x43d, 0x3b, 0x411, 0x430, -0x43b, 0x430, 0x495, 0x430, 0x43d, 0x20, 0x44b, 0x439, 0x44b, 0x43d, 0x3b, 0x410, 0x43b, 0x442, 0x44b, 0x43d, 0x43d, 0x44c, 0x44b, 0x3b, -0x421, 0x44d, 0x442, 0x438, 0x43d, 0x43d, 0x44c, 0x438, 0x3b, 0x430, 0x445, 0x441, 0x44b, 0x43d, 0x43d, 0x44c, 0x44b, 0x3b, 0x4d, 0x75, -0x70, 0x3b, 0x4d, 0x77, 0x69, 0x3b, 0x4d, 0x73, 0x68, 0x3b, 0x4d, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x67, 0x3b, 0x4d, 0x75, -0x6a, 0x3b, 0x4d, 0x73, 0x70, 0x3b, 0x4d, 0x70, 0x67, 0x3b, 0x4d, 0x79, 0x65, 0x3b, 0x4d, 0x6f, 0x6b, 0x3b, 0x4d, 0x75, -0x73, 0x3b, 0x4d, 0x75, 0x68, 0x3b, 0x4d, 0x75, 0x70, 0x61, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x6c, 0x77, 0x61, 0x3b, 0x4d, -0x77, 0x69, 0x74, 0x6f, 0x70, 0x65, 0x3b, 0x4d, 0x75, 0x73, 0x68, 0x65, 0x6e, 0x64, 0x65, 0x3b, 0x4d, 0x75, 0x6e, 0x79, -0x69, 0x3b, 0x4d, 0x75, 0x73, 0x68, 0x65, 0x6e, 0x64, 0x65, 0x20, 0x4d, 0x61, 0x67, 0x61, 0x6c, 0x69, 0x3b, 0x4d, 0x75, -0x6a, 0x69, 0x6d, 0x62, 0x69, 0x3b, 0x4d, 0x75, 0x73, 0x68, 0x69, 0x70, 0x65, 0x70, 0x6f, 0x3b, 0x4d, 0x75, 0x70, 0x75, -0x67, 0x75, 0x74, 0x6f, 0x3b, 0x4d, 0x75, 0x6e, 0x79, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x4d, 0x6f, 0x6b, 0x68, 0x75, 0x3b, -0x4d, 0x75, 0x73, 0x6f, 0x6e, 0x67, 0x61, 0x6e, 0x64, 0x65, 0x6d, 0x62, 0x77, 0x65, 0x3b, 0x4d, 0x75, 0x68, 0x61, 0x61, -0x6e, 0x6f, 0x3b, 0xa5a8, 0xa595, 0xa51e, 0x3b, 0xa552, 0xa561, 0x3b, 0xa57e, 0xa5ba, 0x3b, 0xa5a2, 0xa595, 0x3b, 0xa591, 0xa571, 0x3b, 0xa5b1, -0xa60b, 0x3b, 0xa5b1, 0xa55e, 0x3b, 0xa5db, 0xa515, 0x3b, 0xa562, 0xa54c, 0x3b, 0xa56d, 0xa583, 0x3b, 0xa51e, 0xa60b, 0x3b, 0xa5a8, 0xa595, 0xa5cf, -0x3b, 0xa5a8, 0xa595, 0x20, 0xa56a, 0xa574, 0x20, 0xa51e, 0xa500, 0xa56e, 0xa54a, 0x3b, 0xa552, 0xa561, 0xa59d, 0xa595, 0x3b, 0xa57e, 0xa5ba, 0x3b, -0xa5a2, 0xa595, 0x3b, 0xa591, 0xa571, 0x3b, 0xa5b1, 0xa60b, 0x3b, 0xa5b1, 0xa55e, 0xa524, 0x3b, 0xa5db, 0xa515, 0x3b, 0xa562, 0xa54c, 0x3b, 0xa56d, -0xa583, 0x3b, 0xa51e, 0xa60b, 0xa554, 0xa57f, 0x20, 0xa578, 0xa583, 0xa5cf, 0x3b, 0xa5a8, 0xa595, 0x20, 0xa56a, 0xa574, 0x20, 0xa5cf, 0xa5ba, 0xa56e, -0xa54a, 0x3b, 0x6c, 0x75, 0x75, 0x6b, 0x61, 0x6f, 0x20, 0x6b, 0x65, 0x6d, 0xe3, 0x3b, 0x253, 0x61, 0x6e, 0x64, 0x61, 0x253, -0x75, 0x3b, 0x76, 0x254, 0x254, 0x3b, 0x66, 0x75, 0x6c, 0x75, 0x3b, 0x67, 0x6f, 0x6f, 0x3b, 0x36, 0x3b, 0x37, 0x3b, 0x6b, -0x254, 0x6e, 0x64, 0x65, 0x3b, 0x73, 0x61, 0x61, 0x68, 0x3b, 0x67, 0x61, 0x6c, 0x6f, 0x3b, 0x6b, 0x65, 0x6e, 0x70, 0x6b, -0x61, 0x74, 0x6f, 0x20, 0x253, 0x6f, 0x6c, 0x6f, 0x6c, 0x254, 0x3b, 0x6c, 0x75, 0x75, 0x6b, 0x61, 0x6f, 0x20, 0x6c, 0x254, -0x6d, 0x61, 0x3b, 0x4a, 0x65, 0x6e, 0x3b, 0x48, 0x6f, 0x72, 0x3b, 0x4d, 0xe4, 0x72, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, -0x65, 0x69, 0x3b, 0x42, 0x72, 0xe1, 0x3b, 0x48, 0x65, 0x69, 0x3b, 0xd6, 0x69, 0x67, 0x3b, 0x48, 0x65, 0x72, 0x3b, 0x57, -0xed, 0x6d, 0x3b, 0x57, 0x69, 0x6e, 0x3b, 0x43, 0x68, 0x72, 0x3b, 0x4a, 0x65, 0x6e, 0x6e, 0x65, 0x72, 0x3b, 0x48, 0x6f, -0x72, 0x6e, 0x69, 0x67, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x65, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x6c, 0x65, 0x3b, 0x4d, -0x65, 0x69, 0x6a, 0x65, 0x3b, 0x42, 0x72, 0xe1, 0x10d, 0x65, 0x74, 0x3b, 0x48, 0x65, 0x69, 0x77, 0x65, 0x74, 0x3b, 0xd6, -0x69, 0x67, 0x161, 0x74, 0x65, 0x3b, 0x48, 0x65, 0x72, 0x62, 0x161, 0x74, 0x6d, 0xe1, 0x6e, 0x65, 0x74, 0x3b, 0x57, 0xed, -0x6d, 0xe1, 0x6e, 0x65, 0x74, 0x3b, 0x57, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0xe1, 0x6e, 0x65, 0x74, 0x3b, 0x43, 0x68, -0x72, 0x69, 0x161, 0x74, 0x6d, 0xe1, 0x6e, 0x65, 0x74, 0x3b, 0x4a, 0x3b, 0x48, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, -0x42, 0x3b, 0x48, 0x3b, 0xd6, 0x3b, 0x48, 0x3b, 0x57, 0x3b, 0x57, 0x3b, 0x43, 0x3b, 0x6f, 0x2e, 0x31, 0x3b, 0x6f, 0x2e, -0x32, 0x3b, 0x6f, 0x2e, 0x33, 0x3b, 0x6f, 0x2e, 0x34, 0x3b, 0x6f, 0x2e, 0x35, 0x3b, 0x6f, 0x2e, 0x36, 0x3b, 0x6f, 0x2e, -0x37, 0x3b, 0x6f, 0x2e, 0x38, 0x3b, 0x6f, 0x2e, 0x39, 0x3b, 0x6f, 0x2e, 0x31, 0x30, 0x3b, 0x6f, 0x2e, 0x31, 0x31, 0x3b, -0x6f, 0x2e, 0x31, 0x32, 0x3b, 0x70, 0x69, 0x6b, 0xed, 0x74, 0xed, 0x6b, 0xed, 0x74, 0x69, 0x65, 0x2c, 0x20, 0x6f, 0xf3, -0x6c, 0xed, 0x20, 0xfa, 0x20, 0x6b, 0x75, 0x74, 0xfa, 0x61, 0x6e, 0x3b, 0x73, 0x69, 0x25b, 0x79, 0x25b, 0x301, 0x2c, 0x20, -0x6f, 0xf3, 0x6c, 0x69, 0x20, 0xfa, 0x20, 0x6b, 0xe1, 0x6e, 0x64, 0xed, 0x25b, 0x3b, 0x254, 0x6e, 0x73, 0xfa, 0x6d, 0x62, -0x254, 0x6c, 0x2c, 0x20, 0x6f, 0xf3, 0x6c, 0x69, 0x20, 0xfa, 0x20, 0x6b, 0xe1, 0x74, 0xe1, 0x74, 0xfa, 0x25b, 0x3b, 0x6d, -0x65, 0x73, 0x69, 0x14b, 0x2c, 0x20, 0x6f, 0xf3, 0x6c, 0x69, 0x20, 0xfa, 0x20, 0x6b, 0xe9, 0x6e, 0x69, 0x65, 0x3b, 0x65, -0x6e, 0x73, 0x69, 0x6c, 0x2c, 0x20, 0x6f, 0xf3, 0x6c, 0x69, 0x20, 0xfa, 0x20, 0x6b, 0xe1, 0x74, 0xe1, 0x6e, 0x75, 0x25b, -0x3b, 0x254, 0x73, 0x254, 0x6e, 0x3b, 0x65, 0x66, 0x75, 0x74, 0x65, 0x3b, 0x70, 0x69, 0x73, 0x75, 0x79, 0xfa, 0x3b, 0x69, -0x6d, 0x25b, 0x14b, 0x20, 0x69, 0x20, 0x70, 0x75, 0x254, 0x73, 0x3b, 0x69, 0x6d, 0x25b, 0x14b, 0x20, 0x69, 0x20, 0x70, 0x75, -0x74, 0xfa, 0x6b, 0x2c, 0x6f, 0xf3, 0x6c, 0x69, 0x20, 0xfa, 0x20, 0x6b, 0xe1, 0x74, 0xed, 0x25b, 0x3b, 0x6d, 0x61, 0x6b, -0x61, 0x6e, 0x64, 0x69, 0x6b, 0x25b, 0x3b, 0x70, 0x69, 0x6c, 0x254, 0x6e, 0x64, 0x254, 0x301, 0x3b, 0x58, 0x69, 0x6e, 0x3b, -0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x58, 0x75, 0x6e, 0x3b, -0x58, 0x6e, 0x74, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x63, 0x68, 0x3b, 0x50, 0x61, 0x79, 0x3b, -0x41, 0x76, 0x69, 0x3b, 0x78, 0x69, 0x6e, 0x65, 0x72, 0x75, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x65, 0x72, 0x75, 0x3b, 0x6d, -0x61, 0x72, 0x7a, 0x75, 0x3b, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x79, 0x75, 0x3b, 0x78, 0x75, 0x6e, 0x75, -0x3b, 0x78, 0x75, 0x6e, 0x65, 0x74, 0x75, 0x3b, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x75, 0x3b, 0x73, 0x65, 0x74, 0x69, 0x65, -0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x63, 0x68, 0x6f, 0x62, 0x72, 0x65, 0x3b, 0x70, 0x61, 0x79, 0x61, 0x72, 0x65, 0x73, -0x3b, 0x61, 0x76, 0x69, 0x65, 0x6e, 0x74, 0x75, 0x3b, 0x58, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x58, -0x3b, 0x58, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x50, 0x3b, 0x41, 0x3b, 0x78, 0x69, 0x6e, 0x3b, 0x66, 0x65, 0x62, -0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x62, 0x72, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x78, 0x75, 0x6e, 0x3b, 0x78, 0x6e, 0x74, -0x3b, 0x61, 0x67, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x3b, 0x6f, 0x63, 0x68, 0x3b, 0x70, 0x61, 0x79, 0x3b, 0x61, 0x76, 0x69, -0x3b, 0x64, 0x65, 0x20, 0x78, 0x69, 0x6e, 0x65, 0x72, 0x75, 0x3b, 0x64, 0x65, 0x20, 0x66, 0x65, 0x62, 0x72, 0x65, 0x72, -0x75, 0x3b, 0x64, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x7a, 0x75, 0x3b, 0x64, 0x2019, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x64, -0x65, 0x20, 0x6d, 0x61, 0x79, 0x75, 0x3b, 0x64, 0x65, 0x20, 0x78, 0x75, 0x6e, 0x75, 0x3b, 0x64, 0x65, 0x20, 0x78, 0x75, -0x6e, 0x65, 0x74, 0x75, 0x3b, 0x64, 0x2019, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x75, 0x3b, 0x64, 0x65, 0x20, 0x73, 0x65, 0x74, -0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x2019, 0x6f, 0x63, 0x68, 0x6f, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x65, 0x20, -0x70, 0x61, 0x79, 0x61, 0x72, 0x65, 0x73, 0x3b, 0x64, 0x2019, 0x61, 0x76, 0x69, 0x65, 0x6e, 0x74, 0x75, 0x3b, 0x4e, 0x64, -0x75, 0x14b, 0x6d, 0x62, 0x69, 0x20, 0x53, 0x61, 0x14b, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x50, 0x25b, 0x301, 0x70, -0xe1, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x50, 0x25b, 0x301, 0x74, 0xe1, 0x74, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, -0x20, 0x50, 0x25b, 0x301, 0x6e, 0x25b, 0x301, 0x6b, 0x77, 0x61, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x50, 0x61, 0x74, -0x61, 0x61, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x50, 0x25b, 0x301, 0x6e, 0x25b, 0x301, 0x6e, 0x74, 0xfa, 0x6b, 0xfa, -0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x53, 0x61, 0x61, 0x6d, 0x62, 0xe1, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, -0x50, 0x25b, 0x301, 0x6e, 0x25b, 0x301, 0x66, 0x254, 0x6d, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x50, 0x25b, 0x301, 0x6e, -0x25b, 0x301, 0x70, 0x66, 0xfa, 0xa78b, 0xfa, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x4e, 0x25b, 0x67, 0x25b, 0x301, 0x6d, -0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x4e, 0x74, 0x73, 0x254, 0x30c, 0x70, 0x6d, 0x254, 0x301, 0x3b, 0x50, 0x25b, 0x73, -0x61, 0x14b, 0x20, 0x4e, 0x74, 0x73, 0x254, 0x30c, 0x70, 0x70, 0xe1, 0x3b, 0x70, 0x61, 0x6d, 0x62, 0x61, 0x3b, 0x77, 0x61, -0x6e, 0x6a, 0x61, 0x3b, 0x6d, 0x62, 0x69, 0x79, 0x254, 0x20, 0x6d, 0x25b, 0x6e, 0x64, 0x6f, 0x14b, 0x67, 0x254, 0x3b, 0x4e, -0x79, 0x254, 0x6c, 0x254, 0x6d, 0x62, 0x254, 0x14b, 0x67, 0x254, 0x3b, 0x4d, 0x254, 0x6e, 0x254, 0x20, 0x14b, 0x67, 0x62, 0x61, -0x6e, 0x6a, 0x61, 0x3b, 0x4e, 0x79, 0x61, 0x14b, 0x67, 0x77, 0x25b, 0x20, 0x14b, 0x67, 0x62, 0x61, 0x6e, 0x6a, 0x61, 0x3b, -0x6b, 0x75, 0x14b, 0x67, 0x77, 0x25b, 0x3b, 0x66, 0x25b, 0x3b, 0x6e, 0x6a, 0x61, 0x70, 0x69, 0x3b, 0x6e, 0x79, 0x75, 0x6b, -0x75, 0x6c, 0x3b, 0x31, 0x31, 0x3b, 0x253, 0x75, 0x6c, 0x253, 0x75, 0x73, 0x25b, 0x3b, 0x6d, 0x62, 0x65, 0x67, 0x74, 0x75, +0x4f, 0x6b, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x65, 0x7a, 0x2e, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, +0x61, 0x72, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x61, 0x72, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41, 0x70, 0x72, +0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, +0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x76, 0x65, +0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x7a, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, +0x6f, 0x111, 0x111, 0x6a, 0x3b, 0x67, 0x75, 0x6f, 0x76, 0x3b, 0x6e, 0x6a, 0x75, 0x6b, 0x3b, 0x63, 0x75, 0x6f, 0x3b, 0x6d, +0x69, 0x65, 0x73, 0x3b, 0x67, 0x65, 0x61, 0x73, 0x3b, 0x73, 0x75, 0x6f, 0x69, 0x3b, 0x62, 0x6f, 0x72, 0x67, 0x3b, 0x10d, +0x61, 0x6b, 0x10d, 0x3b, 0x67, 0x6f, 0x6c, 0x67, 0x3b, 0x73, 0x6b, 0xe1, 0x62, 0x3b, 0x6a, 0x75, 0x6f, 0x76, 0x3b, 0x6f, +0x111, 0x111, 0x61, 0x6a, 0x61, 0x67, 0x65, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x67, 0x75, 0x6f, 0x76, 0x76, 0x61, 0x6d, +0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x6e, 0x6a, 0x75, 0x6b, 0x10d, 0x61, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x63, 0x75, 0x6f, +0x14b, 0x6f, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x6d, 0x69, 0x65, 0x73, 0x73, 0x65, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, +0x67, 0x65, 0x61, 0x73, 0x73, 0x65, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x73, 0x75, 0x6f, 0x69, 0x64, 0x6e, 0x65, 0x6d, +0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x62, 0x6f, 0x72, 0x67, 0x65, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x10d, 0x61, 0x6b, 0x10d, +0x61, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x67, 0x6f, 0x6c, 0x67, 0x67, 0x6f, 0x74, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, +0x73, 0x6b, 0xe1, 0x62, 0x6d, 0x61, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x6a, 0x75, 0x6f, 0x76, 0x6c, 0x61, 0x6d, 0xe1, +0x6e, 0x6e, 0x75, 0x3b, 0x4f, 0x3b, 0x47, 0x3b, 0x4e, 0x3b, 0x43, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x53, 0x3b, 0x42, 0x3b, +0x10c, 0x3b, 0x47, 0x3b, 0x53, 0x3b, 0x4a, 0x3b, 0x6f, 0x111, 0x111, 0x6a, 0x3b, 0x67, 0x75, 0x6f, 0x76, 0x3b, 0x6e, 0x6a, +0x75, 0x6b, 0x3b, 0x63, 0x75, 0x6f, 0x14b, 0x3b, 0x6d, 0x69, 0x65, 0x73, 0x3b, 0x67, 0x65, 0x61, 0x73, 0x3b, 0x73, 0x75, +0x6f, 0x69, 0x3b, 0x62, 0x6f, 0x72, 0x67, 0x3b, 0x10d, 0x61, 0x6b, 0x10d, 0x3b, 0x67, 0x6f, 0x6c, 0x67, 0x3b, 0x73, 0x6b, +0xe1, 0x62, 0x3b, 0x6a, 0x75, 0x6f, 0x76, 0x3b, 0x43, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x63, 0x3b, +0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x43, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x74, 0x3b, +0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x62, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x43, 0x68, 0x61, 0x6e, +0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x75, 0x72, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x3b, +0x41, 0x70, 0x69, 0x72, 0x69, 0x72, 0x69, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x43, 0x68, 0x75, +0x6c, 0x61, 0x69, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, +0x4f, 0x6b, 0x69, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x62, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, 0x65, +0x6d, 0x62, 0x61, 0x3b, 0x43, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x43, 0x3b, 0x41, 0x3b, +0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x49, 0x6d, 0x62, 0x3b, 0x4b, 0x61, 0x77, 0x3b, 0x4b, 0x61, 0x64, 0x3b, +0x4b, 0x61, 0x6e, 0x3b, 0x4b, 0x61, 0x73, 0x3b, 0x4b, 0x61, 0x72, 0x3b, 0x4d, 0x66, 0x75, 0x3b, 0x57, 0x75, 0x6e, 0x3b, +0x49, 0x6b, 0x65, 0x3b, 0x49, 0x6b, 0x75, 0x3b, 0x49, 0x6d, 0x77, 0x3b, 0x49, 0x77, 0x69, 0x3b, 0x4d, 0x6f, 0x72, 0x69, +0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x69, 0x6d, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, +0x77, 0x61, 0x20, 0x6b, 0x61, 0x77, 0x69, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x6b, 0x61, +0x64, 0x61, 0x64, 0x75, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, +0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x73, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x6f, 0x72, +0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x72, 0x61, 0x6e, 0x64, 0x61, 0x64, 0x75, 0x3b, 0x4d, 0x6f, 0x72, +0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x6d, 0x66, 0x75, 0x6e, 0x67, 0x61, 0x64, 0x65, 0x3b, 0x4d, 0x6f, 0x72, 0x69, +0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x77, 0x75, 0x6e, 0x79, 0x61, 0x6e, 0x79, 0x61, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, +0x67, 0x68, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, +0x61, 0x20, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x69, 0x6b, +0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x69, 0x6d, 0x77, 0x65, 0x72, 0x69, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, +0x68, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x69, 0x77, 0x69, 0x3b, 0x49, 0x3b, 0x4b, +0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x57, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x49, +0x3b, 0x73, 0x69, 0x69, 0x3b, 0x63, 0x6f, 0x6c, 0x3b, 0x6d, 0x62, 0x6f, 0x3b, 0x73, 0x65, 0x65, 0x3b, 0x64, 0x75, 0x75, +0x3b, 0x6b, 0x6f, 0x72, 0x3b, 0x6d, 0x6f, 0x72, 0x3b, 0x6a, 0x75, 0x6b, 0x3b, 0x73, 0x6c, 0x74, 0x3b, 0x79, 0x61, 0x72, +0x3b, 0x6a, 0x6f, 0x6c, 0x3b, 0x62, 0x6f, 0x77, 0x3b, 0x73, 0x69, 0x69, 0x6c, 0x6f, 0x3b, 0x63, 0x6f, 0x6c, 0x74, 0x65, +0x3b, 0x6d, 0x62, 0x6f, 0x6f, 0x79, 0x3b, 0x73, 0x65, 0x65, 0x257, 0x74, 0x6f, 0x3b, 0x64, 0x75, 0x75, 0x6a, 0x61, 0x6c, +0x3b, 0x6b, 0x6f, 0x72, 0x73, 0x65, 0x3b, 0x6d, 0x6f, 0x72, 0x73, 0x6f, 0x3b, 0x6a, 0x75, 0x6b, 0x6f, 0x3b, 0x73, 0x69, +0x69, 0x6c, 0x74, 0x6f, 0x3b, 0x79, 0x61, 0x72, 0x6b, 0x6f, 0x6d, 0x61, 0x61, 0x3b, 0x6a, 0x6f, 0x6c, 0x61, 0x6c, 0x3b, +0x62, 0x6f, 0x77, 0x74, 0x65, 0x3b, 0x73, 0x3b, 0x63, 0x3b, 0x6d, 0x3b, 0x73, 0x3b, 0x64, 0x3b, 0x6b, 0x3b, 0x6d, 0x3b, +0x6a, 0x3b, 0x73, 0x3b, 0x79, 0x3b, 0x6a, 0x3b, 0x62, 0x3b, 0x4a, 0x45, 0x4e, 0x3b, 0x57, 0x4b, 0x52, 0x3b, 0x57, 0x47, +0x54, 0x3b, 0x57, 0x4b, 0x4e, 0x3b, 0x57, 0x54, 0x4e, 0x3b, 0x57, 0x54, 0x44, 0x3b, 0x57, 0x4d, 0x4a, 0x3b, 0x57, 0x4e, +0x4e, 0x3b, 0x57, 0x4b, 0x44, 0x3b, 0x57, 0x49, 0x4b, 0x3b, 0x57, 0x4d, 0x57, 0x3b, 0x44, 0x49, 0x54, 0x3b, 0x4e, 0x6a, +0x65, 0x6e, 0x75, 0x61, 0x72, 0x129, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x65, 0x72, 0x129, +0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x74, 0x169, 0x3b, 0x4d, 0x77, 0x65, +0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, +0x67, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, +0x6e, 0x64, 0x61, 0x74, 0x169, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x6d, 0x169, 0x67, 0x77, 0x61, +0x6e, 0x6a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x6e, 0x61, 0x3b, +0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, +0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x169, 0x6d, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x69, +0x6b, 0x169, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x169, 0x6d, 0x77, 0x65, 0x3b, 0x4e, 0x64, 0x69, 0x74, 0x68, 0x65, 0x6d, +0x62, 0x61, 0x3b, 0x4a, 0x3b, 0x4b, 0x3b, 0x47, 0x3b, 0x4b, 0x3b, 0x47, 0x3b, 0x47, 0x3b, 0x4d, 0x3b, 0x4b, 0x3b, 0x4b, +0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x44, 0x3b, 0x4f, 0x62, 0x6f, 0x3b, 0x57, 0x61, 0x61, 0x3b, 0x4f, 0x6b, 0x75, 0x3b, 0x4f, +0x6e, 0x67, 0x3b, 0x49, 0x6d, 0x65, 0x3b, 0x49, 0x6c, 0x65, 0x3b, 0x53, 0x61, 0x70, 0x3b, 0x49, 0x73, 0x69, 0x3b, 0x53, +0x61, 0x61, 0x3b, 0x54, 0x6f, 0x6d, 0x3b, 0x54, 0x6f, 0x62, 0x3b, 0x54, 0x6f, 0x77, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, +0x6c, 0x65, 0x20, 0x6f, 0x62, 0x6f, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x77, 0x61, 0x61, 0x72, 0x65, +0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x6f, 0x6b, 0x75, 0x6e, 0x69, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, +0x6c, 0x65, 0x20, 0x6f, 0x6e, 0x67, 0x2019, 0x77, 0x61, 0x6e, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x69, +0x6d, 0x65, 0x74, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x69, 0x6c, 0x65, 0x3b, 0x4c, 0x61, 0x70, 0x61, +0x20, 0x6c, 0x65, 0x20, 0x73, 0x61, 0x70, 0x61, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x69, 0x73, 0x69, +0x65, 0x74, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x73, 0x61, 0x61, 0x6c, 0x3b, 0x4c, 0x61, 0x70, 0x61, +0x20, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x6d, 0x6f, 0x6e, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x74, 0x6f, +0x6d, 0x6f, 0x6e, 0x20, 0x6f, 0x62, 0x6f, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x6d, 0x6f, +0x6e, 0x20, 0x77, 0x61, 0x61, 0x72, 0x65, 0x3b, 0x4f, 0x3b, 0x57, 0x3b, 0x4f, 0x3b, 0x4f, 0x3b, 0x49, 0x3b, 0x49, 0x3b, +0x53, 0x3b, 0x49, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x76, 0x3b, +0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, +0x41, 0x75, 0x67, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x74, 0x75, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x63, 0x3b, +0x4a, 0x61, 0x6e, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x46, 0x65, 0x76, 0x72, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x4d, 0x61, 0x72, +0x63, 0x6f, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x6f, 0x3b, 0x4a, 0x75, 0x6e, 0x68, 0x6f, 0x3b, +0x4a, 0x75, 0x6c, 0x68, 0x6f, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x65, 0x6d, 0x62, +0x72, 0x6f, 0x3b, 0x4f, 0x74, 0x75, 0x62, 0x72, 0x6f, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x44, +0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x5a, 0x69, 0x62, 0x3b, 0x4e, 0x68, 0x6c, 0x6f, 0x3b, 0x4d, 0x62, 0x69, +0x3b, 0x4d, 0x61, 0x62, 0x3b, 0x4e, 0x6b, 0x77, 0x3b, 0x4e, 0x68, 0x6c, 0x61, 0x3b, 0x4e, 0x74, 0x75, 0x3b, 0x4e, 0x63, +0x77, 0x3b, 0x4d, 0x70, 0x61, 0x6e, 0x3b, 0x4d, 0x66, 0x75, 0x3b, 0x4c, 0x77, 0x65, 0x3b, 0x4d, 0x70, 0x61, 0x6c, 0x3b, +0x5a, 0x69, 0x62, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x6c, 0x61, 0x3b, 0x4e, 0x68, 0x6c, 0x6f, 0x6c, 0x61, 0x6e, 0x6a, 0x61, +0x3b, 0x4d, 0x62, 0x69, 0x6d, 0x62, 0x69, 0x74, 0x68, 0x6f, 0x3b, 0x4d, 0x61, 0x62, 0x61, 0x73, 0x61, 0x3b, 0x4e, 0x6b, +0x77, 0x65, 0x6e, 0x6b, 0x77, 0x65, 0x7a, 0x69, 0x3b, 0x4e, 0x68, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x6c, 0x61, 0x3b, 0x4e, +0x74, 0x75, 0x6c, 0x69, 0x6b, 0x61, 0x7a, 0x69, 0x3b, 0x4e, 0x63, 0x77, 0x61, 0x62, 0x61, 0x6b, 0x61, 0x7a, 0x69, 0x3b, +0x4d, 0x70, 0x61, 0x6e, 0x64, 0x75, 0x6c, 0x61, 0x3b, 0x4d, 0x66, 0x75, 0x6d, 0x66, 0x75, 0x3b, 0x4c, 0x77, 0x65, 0x7a, +0x69, 0x3b, 0x4d, 0x70, 0x61, 0x6c, 0x61, 0x6b, 0x61, 0x7a, 0x69, 0x3b, 0x5a, 0x3b, 0x4e, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, +0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4d, 0x31, 0x3b, 0x4d, +0x32, 0x3b, 0x4d, 0x33, 0x3b, 0x4d, 0x34, 0x3b, 0x4d, 0x35, 0x3b, 0x4d, 0x36, 0x3b, 0x4d, 0x37, 0x3b, 0x4d, 0x38, 0x3b, +0x4d, 0x39, 0x3b, 0x4d, 0x31, 0x30, 0x3b, 0x4d, 0x31, 0x31, 0x3b, 0x4d, 0x31, 0x32, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, +0x20, 0x77, 0x61, 0x20, 0x6b, 0x77, 0x61, 0x6e, 0x7a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, +0x6b, 0x61, 0x69, 0x6c, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x74, 0x61, 0x74, +0x75, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x77, 0x65, +0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x74, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, +0x73, 0x69, 0x74, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x73, 0x61, 0x62, 0x61, 0x3b, 0x4d, +0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6e, 0x61, 0x6e, 0x65, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, +0x61, 0x20, 0x74, 0x69, 0x73, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x75, 0x6d, +0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, +0x6d, 0x6f, 0x6a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x20, +0x6e, 0x61, 0x20, 0x6d, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x54, 0x3b, 0x53, +0x3b, 0x53, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x2d49, 0x2d4f, 0x2d4f, 0x3b, 0x2d31, 0x2d55, 0x2d30, +0x3b, 0x2d4e, 0x2d30, 0x2d55, 0x3b, 0x2d49, 0x2d31, 0x2d54, 0x3b, 0x2d4e, 0x2d30, 0x2d62, 0x3b, 0x2d62, 0x2d53, 0x2d4f, 0x3b, 0x2d62, 0x2d53, 0x2d4d, +0x3b, 0x2d56, 0x2d53, 0x2d5b, 0x3b, 0x2d5b, 0x2d53, 0x2d5c, 0x3b, 0x2d3d, 0x2d5c, 0x2d53, 0x3b, 0x2d4f, 0x2d53, 0x2d61, 0x3b, 0x2d37, 0x2d53, 0x2d4a, +0x3b, 0x2d49, 0x2d4f, 0x2d4f, 0x2d30, 0x2d62, 0x2d54, 0x3b, 0x2d31, 0x2d55, 0x2d30, 0x2d62, 0x2d55, 0x3b, 0x2d4e, 0x2d30, 0x2d55, 0x2d5a, 0x3b, 0x2d49, +0x2d31, 0x2d54, 0x2d49, 0x2d54, 0x3b, 0x2d4e, 0x2d30, 0x2d62, 0x2d62, 0x2d53, 0x3b, 0x2d62, 0x2d53, 0x2d4f, 0x2d62, 0x2d53, 0x3b, 0x2d62, 0x2d53, 0x2d4d, +0x2d62, 0x2d53, 0x2d63, 0x3b, 0x2d56, 0x2d53, 0x2d5b, 0x2d5c, 0x3b, 0x2d5b, 0x2d53, 0x2d5c, 0x2d30, 0x2d4f, 0x2d31, 0x2d49, 0x2d54, 0x3b, 0x2d3d, 0x2d5c, +0x2d53, 0x2d31, 0x2d54, 0x3b, 0x2d4f, 0x2d53, 0x2d61, 0x2d30, 0x2d4f, 0x2d31, 0x2d49, 0x2d54, 0x3b, 0x2d37, 0x2d53, 0x2d4a, 0x2d30, 0x2d4f, 0x2d31, 0x2d49, +0x2d54, 0x3b, 0x2d49, 0x3b, 0x2d31, 0x3b, 0x2d4e, 0x3b, 0x2d49, 0x3b, 0x2d4e, 0x3b, 0x2d62, 0x3b, 0x2d62, 0x3b, 0x2d56, 0x3b, 0x2d5b, 0x3b, +0x2d3d, 0x3b, 0x2d4f, 0x3b, 0x2d37, 0x3b, 0x69, 0x6e, 0x6e, 0x3b, 0x62, 0x1e5b, 0x61, 0x3b, 0x6d, 0x61, 0x1e5b, 0x3b, 0x69, 0x62, +0x72, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x79, 0x75, 0x6e, 0x3b, 0x79, 0x75, 0x6c, 0x3b, 0x263, 0x75, 0x63, 0x3b, 0x63, 0x75, +0x74, 0x3b, 0x6b, 0x74, 0x75, 0x3b, 0x6e, 0x75, 0x77, 0x3b, 0x64, 0x75, 0x6a, 0x3b, 0x69, 0x6e, 0x6e, 0x61, 0x79, 0x72, +0x3b, 0x62, 0x1e5b, 0x61, 0x79, 0x1e5b, 0x3b, 0x6d, 0x61, 0x1e5b, 0x1e63, 0x3b, 0x69, 0x62, 0x72, 0x69, 0x72, 0x3b, 0x6d, 0x61, +0x79, 0x79, 0x75, 0x3b, 0x79, 0x75, 0x6e, 0x79, 0x75, 0x3b, 0x79, 0x75, 0x6c, 0x79, 0x75, 0x7a, 0x3b, 0x263, 0x75, 0x63, +0x74, 0x3b, 0x63, 0x75, 0x74, 0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b, 0x6b, 0x74, 0x75, 0x62, 0x72, 0x3b, 0x6e, 0x75, 0x77, +0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b, 0x64, 0x75, 0x6a, 0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b, 0x69, 0x3b, 0x62, 0x3b, 0x6d, +0x3b, 0x69, 0x3b, 0x6d, 0x3b, 0x79, 0x3b, 0x79, 0x3b, 0x263, 0x3b, 0x63, 0x3b, 0x6b, 0x3b, 0x6e, 0x3b, 0x64, 0x3b, 0x59, +0x65, 0x6e, 0x3b, 0x46, 0x75, 0x72, 0x3b, 0x4d, 0x65, 0x263, 0x3b, 0x59, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x59, +0x75, 0x6e, 0x3b, 0x59, 0x75, 0x6c, 0x3b, 0x194, 0x75, 0x63, 0x3b, 0x43, 0x74, 0x65, 0x3b, 0x54, 0x75, 0x62, 0x3b, 0x57, +0x61, 0x6d, 0x3b, 0x44, 0x75, 0x6a, 0x3b, 0x59, 0x65, 0x6e, 0x6e, 0x61, 0x79, 0x65, 0x72, 0x3b, 0x46, 0x75, 0x1e5b, 0x61, +0x72, 0x3b, 0x4d, 0x65, 0x263, 0x72, 0x65, 0x73, 0x3b, 0x59, 0x65, 0x62, 0x72, 0x69, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x79, +0x75, 0x3b, 0x59, 0x75, 0x6e, 0x79, 0x75, 0x3b, 0x59, 0x75, 0x6c, 0x79, 0x75, 0x3b, 0x194, 0x75, 0x63, 0x74, 0x3b, 0x43, +0x74, 0x65, 0x6d, 0x62, 0x65, 0x1e5b, 0x3b, 0x54, 0x75, 0x62, 0x65, 0x1e5b, 0x3b, 0x57, 0x61, 0x6d, 0x62, 0x65, 0x1e5b, 0x3b, +0x44, 0x75, 0x1e7, 0x65, 0x6d, 0x62, 0x65, 0x1e5b, 0x3b, 0x59, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x59, 0x3b, 0x4d, 0x3b, 0x59, +0x3b, 0x59, 0x3b, 0x194, 0x3b, 0x43, 0x3b, 0x54, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x59, 0x65, 0x6e, 0x3b, 0x46, 0x75, 0x72, +0x3b, 0x4d, 0x65, 0x263, 0x3b, 0x59, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x59, 0x75, 0x6e, 0x3b, 0x59, 0x75, 0x6c, +0x3b, 0x194, 0x75, 0x63, 0x3b, 0x43, 0x74, 0x65, 0x3b, 0x54, 0x75, 0x62, 0x3b, 0x4e, 0x75, 0x6e, 0x3b, 0x44, 0x75, 0x1e7, +0x3b, 0x59, 0x65, 0x6e, 0x6e, 0x61, 0x79, 0x65, 0x72, 0x3b, 0x46, 0x75, 0x1e5b, 0x61, 0x72, 0x3b, 0x4d, 0x65, 0x263, 0x72, +0x65, 0x73, 0x3b, 0x59, 0x65, 0x62, 0x72, 0x69, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x79, 0x75, 0x3b, 0x59, 0x75, 0x6e, 0x79, +0x75, 0x3b, 0x59, 0x75, 0x6c, 0x79, 0x75, 0x3b, 0x194, 0x75, 0x63, 0x74, 0x3b, 0x43, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x1e5b, +0x3b, 0x54, 0x75, 0x62, 0x65, 0x1e5b, 0x3b, 0x4e, 0x75, 0x6e, 0x65, 0x6d, 0x62, 0x65, 0x1e5b, 0x3b, 0x44, 0x75, 0x1e7, 0x65, +0x6d, 0x62, 0x65, 0x1e5b, 0x3b, 0x59, 0x3b, 0x46, 0x3b, 0x194, 0x3b, 0x42, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x4c, 0x3b, 0x43, +0x3b, 0x54, 0x3b, 0x52, 0x3b, 0x57, 0x3b, 0x44, 0x3b, 0x4b, 0x42, 0x5a, 0x3b, 0x4b, 0x42, 0x52, 0x3b, 0x4b, 0x53, 0x54, +0x3b, 0x4b, 0x4b, 0x4e, 0x3b, 0x4b, 0x54, 0x4e, 0x3b, 0x4b, 0x4d, 0x4b, 0x3b, 0x4b, 0x4d, 0x53, 0x3b, 0x4b, 0x4d, 0x4e, +0x3b, 0x4b, 0x4d, 0x57, 0x3b, 0x4b, 0x4b, 0x4d, 0x3b, 0x4b, 0x4e, 0x4b, 0x3b, 0x4b, 0x4e, 0x42, 0x3b, 0x4f, 0x6b, 0x77, +0x6f, 0x6b, 0x75, 0x62, 0x61, 0x6e, 0x7a, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6b, 0x61, 0x62, 0x69, 0x72, 0x69, 0x3b, +0x4f, 0x6b, 0x77, 0x61, 0x6b, 0x61, 0x73, 0x68, 0x61, 0x74, 0x75, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6b, 0x61, 0x6e, 0x61, +0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6b, 0x61, 0x74, 0x61, 0x61, 0x6e, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6d, 0x75, 0x6b, +0x61, 0x61, 0x67, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6d, 0x75, 0x73, 0x68, 0x61, 0x6e, 0x6a, 0x75, 0x3b, 0x4f, 0x6b, +0x77, 0x61, 0x6d, 0x75, 0x6e, 0x61, 0x61, 0x6e, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6d, 0x77, 0x65, 0x6e, 0x64, 0x61, +0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x69, 0x6b, 0x75, 0x6d, 0x69, +0x20, 0x6e, 0x61, 0x20, 0x6b, 0x75, 0x6d, 0x77, 0x65, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x20, +0x6e, 0x61, 0x20, 0x69, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x48, 0x75, 0x74, 0x3b, 0x56, 0x69, 0x6c, 0x3b, 0x44, 0x61, 0x74, +0x3b, 0x54, 0x61, 0x69, 0x3b, 0x48, 0x61, 0x6e, 0x3b, 0x53, 0x69, 0x74, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4e, 0x61, 0x6e, +0x3b, 0x54, 0x69, 0x73, 0x3b, 0x4b, 0x75, 0x6d, 0x3b, 0x4b, 0x6d, 0x6a, 0x3b, 0x4b, 0x6d, 0x62, 0x3b, 0x70, 0x61, 0x20, +0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x68, 0x75, 0x74, 0x61, 0x6c, 0x61, 0x3b, 0x70, 0x61, +0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x77, 0x75, 0x76, 0x69, 0x6c, 0x69, 0x3b, 0x70, +0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x77, 0x75, 0x64, 0x61, 0x74, 0x75, 0x3b, +0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x77, 0x75, 0x74, 0x61, 0x69, 0x3b, +0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x77, 0x75, 0x68, 0x61, 0x6e, 0x75, +0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x73, 0x69, 0x74, 0x61, 0x3b, +0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x73, 0x61, 0x62, 0x61, 0x3b, 0x70, +0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x6e, 0x61, 0x6e, 0x65, 0x3b, 0x70, 0x61, +0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x74, 0x69, 0x73, 0x61, 0x3b, 0x70, 0x61, 0x20, +0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x70, 0x61, 0x20, 0x6d, +0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x6f, +0x6a, 0x61, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x6b, 0x75, 0x6d, +0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x48, 0x3b, 0x56, 0x3b, 0x44, 0x3b, 0x54, 0x3b, 0x48, +0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, +0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x3b, 0x41, 0x70, +0x72, 0x69, 0x6c, 0x79, 0x69, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x79, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x79, +0x61, 0x69, 0x3b, 0x41, 0x67, 0x75, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, +0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x65, 0x73, 0x65, 0x6d, 0x62, +0x61, 0x3b, 0x7a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x77, 0x69, 0x3b, 0x6d, 0x25b, +0x3b, 0x7a, 0x75, 0x77, 0x3b, 0x7a, 0x75, 0x6c, 0x3b, 0x75, 0x74, 0x69, 0x3b, 0x73, 0x25b, 0x74, 0x3b, 0x254, 0x6b, 0x75, +0x3b, 0x6e, 0x6f, 0x77, 0x3b, 0x64, 0x65, 0x73, 0x3b, 0x7a, 0x61, 0x6e, 0x77, 0x75, 0x79, 0x65, 0x3b, 0x66, 0x65, 0x62, +0x75, 0x72, 0x75, 0x79, 0x65, 0x3b, 0x6d, 0x61, 0x72, 0x69, 0x73, 0x69, 0x3b, 0x61, 0x77, 0x69, 0x72, 0x69, 0x6c, 0x69, +0x3b, 0x6d, 0x25b, 0x3b, 0x7a, 0x75, 0x77, 0x25b, 0x6e, 0x3b, 0x7a, 0x75, 0x6c, 0x75, 0x79, 0x65, 0x3b, 0x75, 0x74, 0x69, +0x3b, 0x73, 0x25b, 0x74, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x75, 0x3b, 0x254, 0x6b, 0x75, 0x74, 0x254, 0x62, 0x75, 0x72, 0x75, +0x3b, 0x6e, 0x6f, 0x77, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x75, 0x3b, 0x64, 0x65, 0x73, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x75, +0x3b, 0x5a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x5a, 0x3b, 0x5a, 0x3b, 0x55, 0x3b, 0x53, 0x3b, 0x186, +0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4d, 0x62, 0x65, 0x3b, 0x4b, 0x61, 0x69, 0x3b, 0x4b, 0x61, 0x74, 0x3b, 0x4b, 0x61, 0x6e, +0x3b, 0x47, 0x61, 0x74, 0x3b, 0x47, 0x61, 0x6e, 0x3b, 0x4d, 0x75, 0x67, 0x3b, 0x4b, 0x6e, 0x6e, 0x3b, 0x4b, 0x65, 0x6e, +0x3b, 0x49, 0x6b, 0x75, 0x3b, 0x49, 0x6d, 0x77, 0x3b, 0x49, 0x67, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, +0x61, 0x20, 0x6d, 0x62, 0x65, 0x72, 0x65, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x129, +0x72, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x74, 0x68, 0x61, 0x74, 0x169, 0x3b, +0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, +0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x67, +0x61, 0x74, 0x61, 0x6e, 0x74, 0x61, 0x74, 0x169, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6d, 0x169, +0x67, 0x77, 0x61, 0x6e, 0x6a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, +0x6e, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x4d, 0x77, +0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x169, 0x6d, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, +0x61, 0x20, 0x69, 0x6b, 0x169, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x169, 0x6d, 0x77, 0x65, 0x3b, 0x4d, 0x77, 0x65, 0x72, +0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x169, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x4b, 0x61, 0x129, 0x72, 0x129, 0x3b, +0x4d, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x47, 0x3b, 0x47, 0x3b, 0x4d, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x49, 0x3b, +0x49, 0x3b, 0x49, 0x3b, 0x13a4, 0x13c3, 0x3b, 0x13a7, 0x13a6, 0x3b, 0x13a0, 0x13c5, 0x3b, 0x13a7, 0x13ec, 0x3b, 0x13a0, 0x13c2, 0x3b, 0x13d5, +0x13ad, 0x3b, 0x13ab, 0x13f0, 0x3b, 0x13a6, 0x13b6, 0x3b, 0x13da, 0x13b5, 0x3b, 0x13da, 0x13c2, 0x3b, 0x13c5, 0x13d3, 0x3b, 0x13a5, 0x13cd, 0x3b, +0x13a4, 0x13c3, 0x13b8, 0x13d4, 0x13c5, 0x3b, 0x13a7, 0x13a6, 0x13b5, 0x3b, 0x13a0, 0x13c5, 0x13f1, 0x3b, 0x13a7, 0x13ec, 0x13c2, 0x3b, 0x13a0, 0x13c2, +0x13cd, 0x13ac, 0x13d8, 0x3b, 0x13d5, 0x13ad, 0x13b7, 0x13f1, 0x3b, 0x13ab, 0x13f0, 0x13c9, 0x13c2, 0x3b, 0x13a6, 0x13b6, 0x13c2, 0x3b, 0x13da, 0x13b5, +0x13cd, 0x13d7, 0x3b, 0x13da, 0x13c2, 0x13c5, 0x13d7, 0x3b, 0x13c5, 0x13d3, 0x13d5, 0x13c6, 0x3b, 0x13a5, 0x13cd, 0x13a9, 0x13f1, 0x3b, 0x13a4, 0x3b, +0x13a7, 0x3b, 0x13a0, 0x3b, 0x13a7, 0x3b, 0x13a0, 0x3b, 0x13d5, 0x3b, 0x13ab, 0x3b, 0x13a6, 0x3b, 0x13da, 0x3b, 0x13da, 0x3b, 0x13c5, 0x3b, +0x13a5, 0x3b, 0x7a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x76, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x76, 0x72, 0x3b, 0x6d, 0x65, +0x3b, 0x7a, 0x69, 0x6e, 0x3b, 0x7a, 0x69, 0x6c, 0x3b, 0x6f, 0x75, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, +0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x73, 0x3b, 0x7a, 0x61, 0x6e, 0x76, 0x69, 0x65, 0x3b, 0x66, 0x65, 0x76, 0x72, +0x69, 0x79, 0x65, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x76, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x65, 0x3b, 0x7a, 0x69, +0x6e, 0x3b, 0x7a, 0x69, 0x6c, 0x79, 0x65, 0x3b, 0x6f, 0x75, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x61, 0x6d, 0x3b, 0x6f, +0x6b, 0x74, 0x6f, 0x62, 0x3b, 0x6e, 0x6f, 0x76, 0x61, 0x6d, 0x3b, 0x64, 0x65, 0x73, 0x61, 0x6d, 0x3b, 0x7a, 0x3b, 0x66, +0x3b, 0x6d, 0x3b, 0x61, 0x3b, 0x6d, 0x3b, 0x7a, 0x3b, 0x7a, 0x3b, 0x6f, 0x3b, 0x73, 0x3b, 0x6f, 0x3b, 0x6e, 0x3b, 0x64, +0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x4e, 0x74, 0x61, 0x6e, 0x64, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, +0x77, 0x61, 0x20, 0x50, 0x69, 0x6c, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x54, 0x61, 0x74, +0x75, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x63, 0x68, 0x65, 0x63, 0x68, 0x69, 0x3b, 0x4d, +0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, +0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x55, 0x6d, 0x6f, 0x3b, 0x4d, 0x77, +0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4d, 0x69, 0x76, +0x69, 0x6c, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, +0x6e, 0x61, 0x20, 0x4d, 0x69, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, +0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4e, 0x63, 0x68, 0x65, 0x63, 0x68, 0x69, 0x3b, 0x4d, 0x77, 0x65, +0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, +0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, +0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x55, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, +0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, +0x6e, 0x61, 0x20, 0x4d, 0x3b, 0x46, 0xfa, 0x6e, 0x67, 0x61, 0x74, 0x268, 0x3b, 0x4e, 0x61, 0x61, 0x6e, 0x268, 0x3b, 0x4b, +0x65, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x49, 0x6b, 0xfa, 0x6d, 0x69, 0x3b, 0x49, 0x6e, 0x79, 0x61, 0x6d, 0x62, 0x61, 0x6c, +0x61, 0x3b, 0x49, 0x64, 0x77, 0x61, 0x61, 0x74, 0x61, 0x3b, 0x4d, 0x289, 0x289, 0x6e, 0x63, 0x68, 0x268, 0x3b, 0x56, 0x268, +0x268, 0x72, 0x268, 0x3b, 0x53, 0x61, 0x61, 0x74, 0x289, 0x3b, 0x49, 0x6e, 0x79, 0x69, 0x3b, 0x53, 0x61, 0x61, 0x6e, 0x6f, +0x3b, 0x53, 0x61, 0x73, 0x61, 0x74, 0x289, 0x3b, 0x4b, 0x289, 0x66, 0xfa, 0x6e, 0x67, 0x61, 0x74, 0x268, 0x3b, 0x4b, 0x289, +0x6e, 0x61, 0x61, 0x6e, 0x268, 0x3b, 0x4b, 0x289, 0x6b, 0x65, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x4b, 0x77, 0x69, 0x69, 0x6b, +0x75, 0x6d, 0x69, 0x3b, 0x4b, 0x77, 0x69, 0x69, 0x6e, 0x79, 0x61, 0x6d, 0x62, 0xe1, 0x6c, 0x61, 0x3b, 0x4b, 0x77, 0x69, +0x69, 0x64, 0x77, 0x61, 0x61, 0x74, 0x61, 0x3b, 0x4b, 0x289, 0x6d, 0x289, 0x289, 0x6e, 0x63, 0x68, 0x268, 0x3b, 0x4b, 0x289, +0x76, 0x268, 0x268, 0x72, 0x268, 0x3b, 0x4b, 0x289, 0x73, 0x61, 0x61, 0x74, 0x289, 0x3b, 0x4b, 0x77, 0x69, 0x69, 0x6e, 0x79, +0x69, 0x3b, 0x4b, 0x289, 0x73, 0x61, 0x61, 0x6e, 0x6f, 0x3b, 0x4b, 0x289, 0x73, 0x61, 0x73, 0x61, 0x74, 0x289, 0x3b, 0x46, +0x3b, 0x4e, 0x3b, 0x4b, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x4d, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x49, 0x3b, 0x53, +0x3b, 0x53, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x75, 0x3b, 0x4d, +0x61, 0x61, 0x3b, 0x4a, 0x75, 0x75, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x75, 0x3b, 0x53, 0x65, 0x62, 0x3b, 0x4f, +0x6b, 0x69, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x77, 0x61, 0x6c, 0x69, 0x79, 0x6f, +0x3b, 0x46, 0x65, 0x62, 0x77, 0x61, 0x6c, 0x69, 0x79, 0x6f, 0x3b, 0x4d, 0x61, 0x72, 0x69, 0x73, 0x69, 0x3b, 0x41, 0x70, +0x75, 0x6c, 0x69, 0x3b, 0x4d, 0x61, 0x61, 0x79, 0x69, 0x3b, 0x4a, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61, +0x61, 0x79, 0x69, 0x3b, 0x41, 0x67, 0x75, 0x73, 0x69, 0x74, 0x6f, 0x3b, 0x53, 0x65, 0x62, 0x75, 0x74, 0x74, 0x65, 0x6d, +0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x69, 0x74, 0x6f, 0x62, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, +0x44, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x63, 0x3b, +0x45, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x4f, 0x67, 0x61, 0x3b, +0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, +0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x3b, 0x45, +0x70, 0x72, 0x65, 0x6f, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x69, 0x3b, +0x4f, 0x67, 0x61, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, +0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4a, +0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x4f, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, +0x3b, 0x44, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, +0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, +0x74, 0x75, 0x3b, 0x4e, 0x75, 0x76, 0x3b, 0x44, 0x69, 0x7a, 0x3b, 0x4a, 0x61, 0x6e, 0x65, 0x72, 0x75, 0x3b, 0x46, 0x65, +0x62, 0x72, 0x65, 0x72, 0x75, 0x3b, 0x4d, 0x61, 0x72, 0x73, 0x75, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, +0x69, 0x75, 0x3b, 0x4a, 0x75, 0x6e, 0x68, 0x75, 0x3b, 0x4a, 0x75, 0x6c, 0x68, 0x75, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, +0x75, 0x3b, 0x53, 0x65, 0x74, 0x65, 0x6e, 0x62, 0x72, 0x75, 0x3b, 0x4f, 0x74, 0x75, 0x62, 0x72, 0x75, 0x3b, 0x4e, 0x75, +0x76, 0x65, 0x6e, 0x62, 0x72, 0x75, 0x3b, 0x44, 0x69, 0x7a, 0x65, 0x6e, 0x62, 0x72, 0x75, 0x3b, 0x4a, 0x41, 0x4e, 0x3b, +0x46, 0x45, 0x42, 0x3b, 0x4d, 0x41, 0x43, 0x3b, 0x128, 0x50, 0x55, 0x3b, 0x4d, 0x128, 0x128, 0x3b, 0x4e, 0x4a, 0x55, 0x3b, +0x4e, 0x4a, 0x52, 0x3b, 0x41, 0x47, 0x41, 0x3b, 0x53, 0x50, 0x54, 0x3b, 0x4f, 0x4b, 0x54, 0x3b, 0x4e, 0x4f, 0x56, 0x3b, +0x44, 0x45, 0x43, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x129, 0x3b, 0x46, 0x65, 0x62, 0x75, 0x72, 0x75, 0x61, 0x72, +0x129, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x3b, 0x128, 0x70, 0x75, 0x72, 0x169, 0x3b, 0x4d, 0x129, 0x129, 0x3b, 0x4e, 0x6a, +0x75, 0x6e, 0x69, 0x3b, 0x4e, 0x6a, 0x75, 0x72, 0x61, 0x129, 0x3b, 0x41, 0x67, 0x61, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, +0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x169, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, +0x61, 0x3b, 0x44, 0x69, 0x63, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x128, 0x3b, 0x4d, 0x3b, +0x4e, 0x3b, 0x4e, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4d, 0x75, 0x6c, 0x3b, 0x4e, 0x67, +0x61, 0x74, 0x3b, 0x54, 0x61, 0x61, 0x3b, 0x49, 0x77, 0x6f, 0x3b, 0x4d, 0x61, 0x6d, 0x3b, 0x50, 0x61, 0x61, 0x3b, 0x4e, +0x67, 0x65, 0x3b, 0x52, 0x6f, 0x6f, 0x3b, 0x42, 0x75, 0x72, 0x3b, 0x45, 0x70, 0x65, 0x3b, 0x4b, 0x70, 0x74, 0x3b, 0x4b, +0x70, 0x61, 0x3b, 0x4d, 0x75, 0x6c, 0x67, 0x75, 0x6c, 0x3b, 0x4e, 0x67, 0x2019, 0x61, 0x74, 0x79, 0x61, 0x61, 0x74, 0x6f, +0x3b, 0x4b, 0x69, 0x70, 0x74, 0x61, 0x61, 0x6d, 0x6f, 0x3b, 0x49, 0x77, 0x6f, 0x6f, 0x74, 0x6b, 0x75, 0x75, 0x74, 0x3b, +0x4d, 0x61, 0x6d, 0x75, 0x75, 0x74, 0x3b, 0x50, 0x61, 0x61, 0x67, 0x69, 0x3b, 0x4e, 0x67, 0x2019, 0x65, 0x69, 0x79, 0x65, +0x65, 0x74, 0x3b, 0x52, 0x6f, 0x6f, 0x70, 0x74, 0x75, 0x69, 0x3b, 0x42, 0x75, 0x72, 0x65, 0x65, 0x74, 0x3b, 0x45, 0x70, +0x65, 0x65, 0x73, 0x6f, 0x3b, 0x4b, 0x69, 0x70, 0x73, 0x75, 0x75, 0x6e, 0x64, 0x65, 0x20, 0x6e, 0x65, 0x20, 0x74, 0x61, +0x61, 0x69, 0x3b, 0x4b, 0x69, 0x70, 0x73, 0x75, 0x75, 0x6e, 0x64, 0x65, 0x20, 0x6e, 0x65, 0x62, 0x6f, 0x20, 0x61, 0x65, +0x6e, 0x67, 0x2019, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x49, 0x3b, 0x4d, 0x3b, 0x50, 0x3b, 0x4e, 0x3b, 0x52, 0x3b, +0x42, 0x3b, 0x45, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x1c3, 0x4b, 0x68, 0x61, 0x6e, 0x6e, 0x69, 0x3b, 0x1c3, 0x4b, 0x68, 0x61, +0x6e, 0x1c0, 0x67, 0xf4, 0x61, 0x62, 0x3b, 0x1c0, 0x4b, 0x68, 0x75, 0x75, 0x1c1, 0x6b, 0x68, 0xe2, 0x62, 0x3b, 0x1c3, 0x48, +0xf4, 0x61, 0x1c2, 0x6b, 0x68, 0x61, 0x69, 0x62, 0x3b, 0x1c3, 0x4b, 0x68, 0x61, 0x69, 0x74, 0x73, 0xe2, 0x62, 0x3b, 0x47, +0x61, 0x6d, 0x61, 0x1c0, 0x61, 0x65, 0x62, 0x3b, 0x1c2, 0x4b, 0x68, 0x6f, 0x65, 0x73, 0x61, 0x6f, 0x62, 0x3b, 0x41, 0x6f, +0x1c1, 0x6b, 0x68, 0x75, 0x75, 0x6d, 0xfb, 0x1c1, 0x6b, 0x68, 0xe2, 0x62, 0x3b, 0x54, 0x61, 0x72, 0x61, 0x1c0, 0x6b, 0x68, +0x75, 0x75, 0x6d, 0xfb, 0x1c1, 0x6b, 0x68, 0xe2, 0x62, 0x3b, 0x1c2, 0x4e, 0xfb, 0x1c1, 0x6e, 0xe2, 0x69, 0x73, 0x65, 0x62, +0x3b, 0x1c0, 0x48, 0x6f, 0x6f, 0x1c2, 0x67, 0x61, 0x65, 0x62, 0x3b, 0x48, 0xf4, 0x61, 0x73, 0x6f, 0x72, 0x65, 0x1c1, 0x6b, +0x68, 0xe2, 0x62, 0x3b, 0x4a, 0x61, 0x6e, 0x2e, 0x3b, 0x46, 0xe4, 0x62, 0x2e, 0x3b, 0x4d, 0xe4, 0x7a, 0x2e, 0x3b, 0x41, +0x70, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x2e, 0x3b, 0x4a, 0x75, 0x6c, 0x2e, 0x3b, 0x4f, 0x75, +0x6a, 0x2e, 0x3b, 0x53, 0xe4, 0x70, 0x2e, 0x3b, 0x4f, 0x6b, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x65, +0x7a, 0x2e, 0x3b, 0x4a, 0x61, 0x6e, 0x6e, 0x65, 0x77, 0x61, 0x3b, 0x46, 0xe4, 0x62, 0x72, 0x6f, 0x77, 0x61, 0x3b, 0x4d, +0xe4, 0xe4, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x65, 0x6c, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x75, 0x6e, 0x69, +0x3b, 0x4a, 0x75, 0x75, 0x6c, 0x69, 0x3b, 0x4f, 0x75, 0x6a, 0x6f, 0xdf, 0x3b, 0x53, 0x65, 0x70, 0x74, 0xe4, 0x6d, 0x62, +0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x68, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0xe4, 0x6d, 0x62, 0x65, 0x72, +0x3b, 0x44, 0x65, 0x7a, 0xe4, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0xe4, 0x62, 0x3b, 0x4d, 0xe4, +0x7a, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x4f, 0x75, +0x6a, 0x3b, 0x53, 0xe4, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x7a, 0x3b, 0x44, 0x61, +0x6c, 0x3b, 0x41, 0x72, 0xe1, 0x3b, 0x186, 0x25b, 0x6e, 0x3b, 0x44, 0x6f, 0x79, 0x3b, 0x4c, 0xe9, 0x70, 0x3b, 0x52, 0x6f, +0x6b, 0x3b, 0x53, 0xe1, 0x73, 0x3b, 0x42, 0x254, 0x301, 0x72, 0x3b, 0x4b, 0xfa, 0x73, 0x3b, 0x47, 0xed, 0x73, 0x3b, 0x53, +0x68, 0x289, 0x301, 0x3b, 0x4e, 0x74, 0x289, 0x301, 0x3b, 0x4f, 0x6c, 0x61, 0x64, 0x61, 0x6c, 0x289, 0x301, 0x3b, 0x41, 0x72, +0xe1, 0x74, 0x3b, 0x186, 0x25b, 0x6e, 0x268, 0x301, 0x254, 0x268, 0x14b, 0x254, 0x6b, 0x3b, 0x4f, 0x6c, 0x6f, 0x64, 0x6f, 0x79, +0xed, 0xf3, 0x72, 0xed, 0xea, 0x20, 0x69, 0x6e, 0x6b, 0xf3, 0x6b, 0xfa, 0xe2, 0x3b, 0x4f, 0x6c, 0x6f, 0x69, 0x6c, 0xe9, +0x70, 0x16b, 0x6e, 0x79, 0x12b, 0x113, 0x20, 0x69, 0x6e, 0x6b, 0xf3, 0x6b, 0xfa, 0xe2, 0x3b, 0x4b, 0xfa, 0x6a, 0xfa, 0x254, +0x72, 0x254, 0x6b, 0x3b, 0x4d, 0xf3, 0x72, 0x75, 0x73, 0xe1, 0x73, 0x69, 0x6e, 0x3b, 0x186, 0x6c, 0x254, 0x301, 0x268, 0x301, +0x62, 0x254, 0x301, 0x72, 0xe1, 0x72, 0x25b, 0x3b, 0x4b, 0xfa, 0x73, 0x68, 0xee, 0x6e, 0x3b, 0x4f, 0x6c, 0x67, 0xed, 0x73, +0x61, 0x6e, 0x3b, 0x50, 0x289, 0x73, 0x68, 0x289, 0x301, 0x6b, 0x61, 0x3b, 0x4e, 0x74, 0x289, 0x301, 0x14b, 0x289, 0x301, 0x73, +0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, +0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, +0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x63, +0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, +0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x63, 0x3b, 0x52, 0x61, 0x72, +0x3b, 0x4d, 0x75, 0x6b, 0x3b, 0x4b, 0x77, 0x61, 0x3b, 0x44, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x4d, 0x6f, 0x64, +0x3b, 0x4a, 0x6f, 0x6c, 0x3b, 0x50, 0x65, 0x64, 0x3b, 0x53, 0x6f, 0x6b, 0x3b, 0x54, 0x69, 0x62, 0x3b, 0x4c, 0x61, 0x62, +0x3b, 0x50, 0x6f, 0x6f, 0x3b, 0x4f, 0x72, 0x61, 0x72, 0x61, 0x3b, 0x4f, 0x6d, 0x75, 0x6b, 0x3b, 0x4f, 0x6b, 0x77, 0x61, +0x6d, 0x67, 0x2019, 0x3b, 0x4f, 0x64, 0x75, 0x6e, 0x67, 0x2019, 0x65, 0x6c, 0x3b, 0x4f, 0x6d, 0x61, 0x72, 0x75, 0x6b, 0x3b, +0x4f, 0x6d, 0x6f, 0x64, 0x6f, 0x6b, 0x2019, 0x6b, 0x69, 0x6e, 0x67, 0x2019, 0x6f, 0x6c, 0x3b, 0x4f, 0x6a, 0x6f, 0x6c, 0x61, +0x3b, 0x4f, 0x70, 0x65, 0x64, 0x65, 0x6c, 0x3b, 0x4f, 0x73, 0x6f, 0x6b, 0x6f, 0x73, 0x6f, 0x6b, 0x6f, 0x6d, 0x61, 0x3b, +0x4f, 0x74, 0x69, 0x62, 0x61, 0x72, 0x3b, 0x4f, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x3b, 0x4f, 0x70, 0x6f, 0x6f, 0x3b, 0x52, +0x3b, 0x4d, 0x3b, 0x4b, 0x3b, 0x44, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x4c, +0x3b, 0x50, 0x3b, 0x17d, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x65, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x77, 0x69, 0x3b, 0x4d, +0x65, 0x3b, 0x17d, 0x75, 0x77, 0x3b, 0x17d, 0x75, 0x79, 0x3b, 0x55, 0x74, 0x3b, 0x53, 0x65, 0x6b, 0x3b, 0x4f, 0x6b, 0x74, +0x3b, 0x4e, 0x6f, 0x6f, 0x3b, 0x44, 0x65, 0x65, 0x3b, 0x17d, 0x61, 0x6e, 0x77, 0x69, 0x79, 0x65, 0x3b, 0x46, 0x65, 0x65, +0x77, 0x69, 0x72, 0x69, 0x79, 0x65, 0x3b, 0x4d, 0x61, 0x72, 0x73, 0x69, 0x3b, 0x41, 0x77, 0x69, 0x72, 0x69, 0x6c, 0x3b, +0x4d, 0x65, 0x3b, 0x17d, 0x75, 0x77, 0x65, 0x14b, 0x3b, 0x17d, 0x75, 0x79, 0x79, 0x65, 0x3b, 0x55, 0x74, 0x3b, 0x53, 0x65, +0x6b, 0x74, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x6f, 0x62, 0x75, 0x72, 0x3b, 0x4e, 0x6f, 0x6f, +0x77, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x3b, 0x44, 0x65, 0x65, 0x73, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x3b, 0x17d, 0x3b, 0x46, +0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x17d, 0x3b, 0x17d, 0x3b, 0x55, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, +0x3b, 0x44, 0x41, 0x43, 0x3b, 0x44, 0x41, 0x52, 0x3b, 0x44, 0x41, 0x44, 0x3b, 0x44, 0x41, 0x4e, 0x3b, 0x44, 0x41, 0x48, +0x3b, 0x44, 0x41, 0x55, 0x3b, 0x44, 0x41, 0x4f, 0x3b, 0x44, 0x41, 0x42, 0x3b, 0x44, 0x4f, 0x43, 0x3b, 0x44, 0x41, 0x50, +0x3b, 0x44, 0x47, 0x49, 0x3b, 0x44, 0x41, 0x47, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x63, 0x68, +0x69, 0x65, 0x6c, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x72, 0x69, 0x79, 0x6f, 0x3b, 0x44, 0x77, +0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x64, 0x65, 0x6b, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, +0x6e, 0x67, 0x2019, 0x77, 0x65, 0x6e, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x62, 0x69, 0x63, 0x68, +0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x75, 0x63, 0x68, 0x69, 0x65, 0x6c, 0x3b, 0x44, 0x77, 0x65, +0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x62, 0x69, 0x72, 0x69, 0x79, 0x6f, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, +0x20, 0x41, 0x62, 0x6f, 0x72, 0x6f, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x4f, 0x63, 0x68, 0x69, 0x6b, +0x6f, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x70, 0x61, 0x72, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, +0x61, 0x72, 0x20, 0x67, 0x69, 0x20, 0x61, 0x63, 0x68, 0x69, 0x65, 0x6c, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, +0x20, 0x41, 0x70, 0x61, 0x72, 0x20, 0x67, 0x69, 0x20, 0x61, 0x72, 0x69, 0x79, 0x6f, 0x3b, 0x43, 0x3b, 0x52, 0x3b, 0x44, +0x3b, 0x4e, 0x3b, 0x42, 0x3b, 0x55, 0x3b, 0x42, 0x3b, 0x42, 0x3b, 0x43, 0x3b, 0x50, 0x3b, 0x43, 0x3b, 0x50, 0x3b, 0x59, +0x65, 0x6e, 0x3b, 0x59, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x49, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x59, +0x75, 0x6e, 0x3b, 0x59, 0x75, 0x6c, 0x3b, 0x194, 0x75, 0x63, 0x3b, 0x43, 0x75, 0x74, 0x3b, 0x4b, 0x1e6d, 0x75, 0x3b, 0x4e, +0x77, 0x61, 0x3b, 0x44, 0x75, 0x6a, 0x3b, 0x59, 0x65, 0x6e, 0x6e, 0x61, 0x79, 0x65, 0x72, 0x3b, 0x59, 0x65, 0x62, 0x72, +0x61, 0x79, 0x65, 0x72, 0x3b, 0x4d, 0x61, 0x72, 0x73, 0x3b, 0x49, 0x62, 0x72, 0x69, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x79, +0x75, 0x3b, 0x59, 0x75, 0x6e, 0x79, 0x75, 0x3b, 0x59, 0x75, 0x6c, 0x79, 0x75, 0x7a, 0x3b, 0x194, 0x75, 0x63, 0x74, 0x3b, +0x43, 0x75, 0x74, 0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b, 0x4b, 0x1e6d, 0x75, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x77, 0x61, 0x6e, +0x62, 0x69, 0x72, 0x3b, 0x44, 0x75, 0x6a, 0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b, 0x59, 0x3b, 0x59, 0x3b, 0x4d, 0x3b, 0x49, +0x3b, 0x4d, 0x3b, 0x59, 0x3b, 0x59, 0x3b, 0x194, 0x3b, 0x43, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4a, 0x61, 0x6e, +0x75, 0x61, 0x6c, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x6c, 0x75, 0x61, 0x6c, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x3b, +0x41, 0x70, 0x6c, 0x69, 0x6c, 0x69, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61, +0x69, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, +0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x61, +0x3b, 0x91c, 0x93e, 0x928, 0x941, 0x935, 0x93e, 0x930, 0x940, 0x3b, 0x92b, 0x947, 0x92c, 0x94d, 0x930, 0x941, 0x935, 0x93e, 0x930, 0x940, +0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x938, 0x3b, 0x90f, 0x92b, 0x94d, 0x930, 0x93f, 0x932, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x941, 0x928, +0x3b, 0x91c, 0x941, 0x932, 0x93e, 0x907, 0x3b, 0x906, 0x917, 0x938, 0x94d, 0x925, 0x3b, 0x938, 0x947, 0x92c, 0x925, 0x947, 0x91c, 0x94d, +0x92c, 0x93c, 0x930, 0x3b, 0x905, 0x916, 0x925, 0x92c, 0x930, 0x3b, 0x928, 0x92c, 0x947, 0x91c, 0x94d, 0x92c, 0x93c, 0x930, 0x3b, 0x926, +0x93f, 0x938, 0x947, 0x91c, 0x94d, 0x92c, 0x93c, 0x930, 0x3b, 0x91c, 0x3b, 0x92b, 0x947, 0x3b, 0x92e, 0x93e, 0x3b, 0x90f, 0x3b, 0x92e, +0x947, 0x3b, 0x91c, 0x941, 0x3b, 0x91c, 0x941, 0x3b, 0x906, 0x3b, 0x938, 0x947, 0x3b, 0x905, 0x3b, 0x928, 0x3b, 0x926, 0x93f, 0x3b, +0x456, 0x486, 0x430, 0x2de9, 0x487, 0x3b, 0x444, 0x435, 0x2de1, 0x487, 0x3b, 0x43c, 0x430, 0x2dec, 0x487, 0x3b, 0x430, 0x486, 0x43f, 0x2dec, +0x487, 0x3b, 0x43c, 0x430, 0xa675, 0x3b, 0x456, 0x486, 0xa64b, 0x2de9, 0x487, 0x3b, 0x456, 0x486, 0xa64b, 0x2de7, 0x487, 0x3b, 0x430, 0x486, +0x301, 0x475, 0x2de2, 0x487, 0x3b, 0x441, 0x435, 0x2deb, 0x487, 0x3b, 0x47b, 0x486, 0x43a, 0x2dee, 0x3b, 0x43d, 0x43e, 0x435, 0x2de8, 0x3b, +0x434, 0x435, 0x2de6, 0x487, 0x3b, 0x456, 0x486, 0x430, 0x43d, 0x43d, 0xa64b, 0x430, 0x301, 0x440, 0x457, 0x439, 0x3b, 0x444, 0x435, 0x432, +0x440, 0xa64b, 0x430, 0x301, 0x440, 0x457, 0x439, 0x3b, 0x43c, 0x430, 0x301, 0x440, 0x442, 0x44a, 0x3b, 0x430, 0x486, 0x43f, 0x440, 0x456, +0x301, 0x43b, 0x43b, 0x457, 0x439, 0x3b, 0x43c, 0x430, 0x301, 0x457, 0x439, 0x3b, 0x456, 0x486, 0xa64b, 0x301, 0x43d, 0x457, 0x439, 0x3b, +0x456, 0x486, 0xa64b, 0x301, 0x43b, 0x457, 0x439, 0x3b, 0x430, 0x486, 0x301, 0x475, 0x433, 0xa64b, 0x441, 0x442, 0x44a, 0x3b, 0x441, 0x435, +0x43f, 0x442, 0x435, 0x301, 0x43c, 0x432, 0x440, 0x457, 0x439, 0x3b, 0x47b, 0x486, 0x43a, 0x442, 0x461, 0x301, 0x432, 0x440, 0x457, 0x439, +0x3b, 0x43d, 0x43e, 0x435, 0x301, 0x43c, 0x432, 0x440, 0x457, 0x439, 0x3b, 0x434, 0x435, 0x43a, 0x435, 0x301, 0x43c, 0x432, 0x440, 0x457, +0x439, 0x3b, 0x406, 0x486, 0x3b, 0x424, 0x3b, 0x41c, 0x3b, 0x410, 0x486, 0x3b, 0x41c, 0x3b, 0x406, 0x486, 0x3b, 0x406, 0x486, 0x3b, +0x410, 0x486, 0x3b, 0x421, 0x3b, 0x47a, 0x486, 0x3b, 0x41d, 0x3b, 0x414, 0x3b, 0x456, 0x486, 0x430, 0x43d, 0x43d, 0xa64b, 0x430, 0x301, +0x440, 0x457, 0x430, 0x3b, 0x444, 0x435, 0x432, 0x440, 0xa64b, 0x430, 0x301, 0x440, 0x457, 0x430, 0x3b, 0x43c, 0x430, 0x301, 0x440, 0x442, +0x430, 0x3b, 0x430, 0x486, 0x43f, 0x440, 0x456, 0x301, 0x43b, 0x43b, 0x457, 0x430, 0x3b, 0x43c, 0x430, 0x301, 0x457, 0x430, 0x3b, 0x456, +0x486, 0xa64b, 0x301, 0x43d, 0x457, 0x430, 0x3b, 0x456, 0x486, 0xa64b, 0x301, 0x43b, 0x457, 0x430, 0x3b, 0x430, 0x486, 0x301, 0x475, 0x433, +0xa64b, 0x441, 0x442, 0x430, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x435, 0x301, 0x43c, 0x432, 0x440, 0x457, 0x430, 0x3b, 0x47b, 0x486, 0x43a, +0x442, 0x461, 0x301, 0x432, 0x440, 0x457, 0x430, 0x3b, 0x43d, 0x43e, 0x435, 0x301, 0x43c, 0x432, 0x440, 0x457, 0x430, 0x3b, 0x434, 0x435, +0x43a, 0x435, 0x301, 0x43c, 0x432, 0x440, 0x457, 0x430, 0x3b, 0x43, 0x69, 0x6f, 0x3b, 0x4c, 0x75, 0x69, 0x3b, 0x4c, 0x75, 0x73, +0x3b, 0x4d, 0x75, 0x75, 0x3b, 0x4c, 0x75, 0x6d, 0x3b, 0x4c, 0x75, 0x66, 0x3b, 0x4b, 0x61, 0x62, 0x3b, 0x4c, 0x75, 0x73, +0x68, 0x3b, 0x4c, 0x75, 0x74, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4b, 0x61, 0x73, 0x3b, 0x43, 0x69, 0x73, 0x3b, 0x43, 0x69, +0x6f, 0x6e, 0x67, 0x6f, 0x3b, 0x4c, 0xf9, 0x69, 0x73, 0x68, 0x69, 0x3b, 0x4c, 0x75, 0x73, 0xf2, 0x6c, 0x6f, 0x3b, 0x4d, +0xf9, 0x75, 0x79, 0xe0, 0x3b, 0x4c, 0x75, 0x6d, 0xf9, 0x6e, 0x67, 0xf9, 0x6c, 0xf9, 0x3b, 0x4c, 0x75, 0x66, 0x75, 0x69, +0x6d, 0x69, 0x3b, 0x4b, 0x61, 0x62, 0xe0, 0x6c, 0xe0, 0x73, 0x68, 0xec, 0x70, 0xf9, 0x3b, 0x4c, 0xf9, 0x73, 0x68, 0xec, +0x6b, 0xe0, 0x3b, 0x4c, 0x75, 0x74, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x6f, 0x3b, 0x4c, 0x75, 0x6e, 0x67, 0xf9, 0x64, 0x69, +0x3b, 0x4b, 0x61, 0x73, 0x77, 0xe8, 0x6b, 0xe8, 0x73, 0xe8, 0x3b, 0x43, 0x69, 0x73, 0x77, 0xe0, 0x3b, 0x43, 0x3b, 0x4c, +0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4b, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4b, 0x3b, 0x43, +0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0xe4, 0x65, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, 0x65, 0x65, +0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x75, 0x67, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, +0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x7a, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x46, 0x65, 0x62, 0x72, +0x75, 0x61, 0x72, 0x3b, 0x4d, 0xe4, 0x65, 0x72, 0x7a, 0x3b, 0x41, 0x62, 0x72, 0xeb, 0x6c, 0x6c, 0x3b, 0x4d, 0x65, 0x65, +0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, +0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, +0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x7a, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x61, 0x6e, 0x2e, 0x3b, 0x46, +0x65, 0x62, 0x2e, 0x3b, 0x4d, 0xe4, 0x65, 0x2e, 0x3b, 0x41, 0x62, 0x72, 0x2e, 0x3b, 0x4d, 0x65, 0x65, 0x3b, 0x4a, 0x75, +0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x2e, 0x3b, 0x53, 0x65, 0x70, 0x2e, 0x3b, 0x4f, 0x6b, +0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x65, 0x7a, 0x2e, 0x3b, 0x6e, 0xf9, 0x6d, 0x3b, 0x6b, 0x268, 0x7a, +0x3b, 0x74, 0x268, 0x64, 0x3b, 0x74, 0x61, 0x61, 0x3b, 0x73, 0x65, 0x65, 0x3b, 0x6e, 0x7a, 0x75, 0x3b, 0x64, 0x75, 0x6d, +0x3b, 0x66, 0x254, 0x65, 0x3b, 0x64, 0x7a, 0x75, 0x3b, 0x6c, 0x254, 0x6d, 0x3b, 0x6b, 0x61, 0x61, 0x3b, 0x66, 0x77, 0x6f, +0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x6e, 0xf9, 0x6d, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, +0x300, 0x6b, 0x197, 0x300, 0x7a, 0xf9, 0x294, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x74, 0x197, 0x300, 0x64, +0x289, 0x300, 0x67, 0x68, 0xe0, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x74, 0x1ce, 0x61, 0x66, 0x289, 0x304, +0x67, 0x68, 0x101, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0xe8, 0x73, 0xe8, 0x65, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, +0x14b, 0x254, 0x300, 0x6e, 0x7a, 0xf9, 0x67, 0x68, 0xf2, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x64, 0xf9, +0x6d, 0x6c, 0x6f, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x6b, 0x77, 0xee, 0x66, 0x254, 0x300, 0x65, 0x3b, +0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x74, 0x197, 0x300, 0x66, 0x289, 0x300, 0x67, 0x68, 0xe0, 0x64, 0x7a, 0x75, +0x67, 0x68, 0xf9, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x67, 0x68, 0x1d4, 0x75, 0x77, 0x65, 0x6c, 0x254, +0x300, 0x6d, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x63, 0x68, 0x77, 0x61, 0x294, 0xe0, 0x6b, 0x61, 0x61, +0x20, 0x77, 0x6f, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0xe8, 0x66, 0x77, 0xf2, 0x6f, 0x3b, 0x6e, 0x3b, 0x6b, 0x3b, +0x74, 0x3b, 0x74, 0x3b, 0x73, 0x3b, 0x7a, 0x3b, 0x6b, 0x3b, 0x66, 0x3b, 0x64, 0x3b, 0x6c, 0x3b, 0x63, 0x3b, 0x66, 0x3b, +0x6b, 0x254, 0x6e, 0x3b, 0x6d, 0x61, 0x63, 0x3b, 0x6d, 0x61, 0x74, 0x3b, 0x6d, 0x74, 0x6f, 0x3b, 0x6d, 0x70, 0x75, 0x3b, +0x68, 0x69, 0x6c, 0x3b, 0x6e, 0x6a, 0x65, 0x3b, 0x68, 0x69, 0x6b, 0x3b, 0x64, 0x69, 0x70, 0x3b, 0x62, 0x69, 0x6f, 0x3b, +0x6d, 0x61, 0x79, 0x3b, 0x6c, 0x69, 0x253, 0x3b, 0x4b, 0x254, 0x6e, 0x64, 0x254, 0x14b, 0x3b, 0x4d, 0xe0, 0x63, 0x25b, 0x302, +0x6c, 0x3b, 0x4d, 0xe0, 0x74, 0xf9, 0x6d, 0x62, 0x3b, 0x4d, 0xe0, 0x74, 0x6f, 0x70, 0x3b, 0x4d, 0x300, 0x70, 0x75, 0x79, +0x25b, 0x3b, 0x48, 0xec, 0x6c, 0xf2, 0x6e, 0x64, 0x25b, 0x300, 0x3b, 0x4e, 0x6a, 0xe8, 0x62, 0xe0, 0x3b, 0x48, 0xec, 0x6b, +0x61, 0x14b, 0x3b, 0x44, 0xec, 0x70, 0x254, 0x300, 0x73, 0x3b, 0x42, 0xec, 0xf2, 0xf4, 0x6d, 0x3b, 0x4d, 0xe0, 0x79, 0x25b, +0x73, 0xe8, 0x70, 0x3b, 0x4c, 0xec, 0x62, 0x75, 0x79, 0x20, 0x6c, 0x69, 0x20, 0x144, 0x79, 0xe8, 0x65, 0x3b, 0x6b, 0x3b, +0x6d, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x68, 0x3b, 0x6e, 0x3b, 0x68, 0x3b, 0x64, 0x3b, 0x62, 0x3b, 0x6d, 0x3b, +0x6c, 0x3b, 0x64, 0x69, 0x3b, 0x14b, 0x67, 0x254, 0x6e, 0x3b, 0x73, 0x254, 0x14b, 0x3b, 0x64, 0x69, 0x253, 0x3b, 0x65, 0x6d, +0x69, 0x3b, 0x65, 0x73, 0x254, 0x3b, 0x6d, 0x61, 0x64, 0x3b, 0x64, 0x69, 0x14b, 0x3b, 0x6e, 0x79, 0x25b, 0x74, 0x3b, 0x6d, +0x61, 0x79, 0x3b, 0x74, 0x69, 0x6e, 0x3b, 0x65, 0x6c, 0xe1, 0x3b, 0x64, 0x69, 0x6d, 0x254, 0x301, 0x64, 0x69, 0x3b, 0x14b, +0x67, 0x254, 0x6e, 0x64, 0x25b, 0x3b, 0x73, 0x254, 0x14b, 0x25b, 0x3b, 0x64, 0x69, 0x253, 0xe1, 0x253, 0xe1, 0x3b, 0x65, 0x6d, +0x69, 0x61, 0x73, 0x65, 0x6c, 0x65, 0x3b, 0x65, 0x73, 0x254, 0x70, 0x25b, 0x73, 0x254, 0x70, 0x25b, 0x3b, 0x6d, 0x61, 0x64, +0x69, 0x253, 0x25b, 0x301, 0x64, 0xed, 0x253, 0x25b, 0x301, 0x3b, 0x64, 0x69, 0x14b, 0x67, 0x69, 0x6e, 0x64, 0x69, 0x3b, 0x6e, +0x79, 0x25b, 0x74, 0x25b, 0x6b, 0x69, 0x3b, 0x6d, 0x61, 0x79, 0xe9, 0x73, 0x25b, 0x301, 0x3b, 0x74, 0x69, 0x6e, 0xed, 0x6e, +0xed, 0x3b, 0x65, 0x6c, 0xe1, 0x14b, 0x67, 0x25b, 0x301, 0x3b, 0x64, 0x3b, 0x14b, 0x3b, 0x73, 0x3b, 0x64, 0x3b, 0x65, 0x3b, +0x65, 0x3b, 0x6d, 0x3b, 0x64, 0x3b, 0x6e, 0x3b, 0x6d, 0x3b, 0x74, 0x3b, 0x65, 0x3b, 0x53, 0x61, 0x3b, 0x46, 0x65, 0x3b, +0x4d, 0x61, 0x3b, 0x41, 0x62, 0x3b, 0x4d, 0x65, 0x3b, 0x53, 0x75, 0x3b, 0x53, 0xfa, 0x3b, 0x55, 0x74, 0x3b, 0x53, 0x65, +0x3b, 0x4f, 0x6b, 0x3b, 0x4e, 0x6f, 0x3b, 0x44, 0x65, 0x3b, 0x53, 0x61, 0x6e, 0x76, 0x69, 0x65, 0x3b, 0x46, 0xe9, 0x62, +0x69, 0x72, 0x69, 0x65, 0x3b, 0x4d, 0x61, 0x72, 0x73, 0x3b, 0x41, 0x62, 0x75, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x65, +0x3b, 0x53, 0x75, 0x65, 0x14b, 0x3b, 0x53, 0xfa, 0x75, 0x79, 0x65, 0x65, 0x3b, 0x55, 0x74, 0x3b, 0x53, 0x65, 0x74, 0x74, +0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, +0x61, 0x72, 0x3b, 0x44, 0x69, 0x73, 0x61, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x53, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, +0x4d, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x55, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x6e, 0x67, 0x6f, 0x3b, +0x6e, 0x67, 0x62, 0x3b, 0x6e, 0x67, 0x6c, 0x3b, 0x6e, 0x67, 0x6e, 0x3b, 0x6e, 0x67, 0x74, 0x3b, 0x6e, 0x67, 0x73, 0x3b, +0x6e, 0x67, 0x7a, 0x3b, 0x6e, 0x67, 0x6d, 0x3b, 0x6e, 0x67, 0x65, 0x3b, 0x6e, 0x67, 0x61, 0x3b, 0x6e, 0x67, 0x61, 0x64, +0x3b, 0x6e, 0x67, 0x61, 0x62, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x6f, 0x73, 0xfa, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, +0x62, 0x25b, 0x30c, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x6c, 0xe1, 0x6c, 0x61, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x6e, +0x79, 0x69, 0x6e, 0x61, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x74, 0xe1, 0x6e, 0x61, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, +0x73, 0x61, 0x6d, 0x259, 0x6e, 0x61, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x7a, 0x61, 0x6d, 0x67, 0x62, 0xe1, 0x6c, 0x61, +0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x6d, 0x77, 0x6f, 0x6d, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x65, 0x62, 0x75, 0x6c, +0xfa, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x61, 0x77, 0xf3, 0x6d, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x61, 0x77, 0xf3, +0x6d, 0x20, 0x61, 0x69, 0x20, 0x64, 0x7a, 0x69, 0xe1, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x61, 0x77, 0xf3, 0x6d, 0x20, +0x61, 0x69, 0x20, 0x62, 0x25b, 0x30c, 0x3b, 0x6f, 0x3b, 0x62, 0x3b, 0x6c, 0x3b, 0x6e, 0x3b, 0x74, 0x3b, 0x73, 0x3b, 0x7a, +0x3b, 0x6d, 0x3b, 0x65, 0x3b, 0x61, 0x3b, 0x64, 0x3b, 0x62, 0x3b, 0x14b, 0x31, 0x3b, 0x14b, 0x32, 0x3b, 0x14b, 0x33, 0x3b, +0x14b, 0x34, 0x3b, 0x14b, 0x35, 0x3b, 0x14b, 0x36, 0x3b, 0x14b, 0x37, 0x3b, 0x14b, 0x38, 0x3b, 0x14b, 0x39, 0x3b, 0x14b, 0x31, +0x30, 0x3b, 0x14b, 0x31, 0x31, 0x3b, 0x14b, 0x31, 0x32, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x20, 0x6e, 0x74, 0x254, +0x301, 0x6e, 0x74, 0x254, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x62, 0x25b, 0x301, 0x25b, 0x3b, 0x14b, +0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x72, 0xe1, 0xe1, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, +0x20, 0x6e, 0x69, 0x6e, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x74, 0xe1, 0x61, 0x6e, 0x3b, 0x14b, +0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x74, 0xe1, 0x61, 0x66, 0x254, 0x6b, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, +0x61, 0x6b, 0x1dd, 0x20, 0x74, 0xe1, 0x61, 0x62, 0x25b, 0x25b, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, +0x74, 0xe1, 0x61, 0x72, 0x61, 0x61, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x74, 0xe1, 0x61, 0x6e, +0x69, 0x6e, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x6e, 0x74, 0x25b, 0x6b, 0x3b, 0x14b, 0x77, 0xed, +0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x6e, 0x74, 0x25b, 0x6b, 0x20, 0x64, 0x69, 0x20, 0x62, 0x254, 0x301, 0x6b, 0x3b, 0x14b, +0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x6e, 0x74, 0x25b, 0x6b, 0x20, 0x64, 0x69, 0x20, 0x62, 0x25b, 0x301, 0x25b, +0x3b, 0x4b, 0x77, 0x61, 0x3b, 0x55, 0x6e, 0x61, 0x3b, 0x52, 0x61, 0x72, 0x3b, 0x43, 0x68, 0x65, 0x3b, 0x54, 0x68, 0x61, +0x3b, 0x4d, 0x6f, 0x63, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4e, 0x61, 0x6e, 0x3b, 0x54, 0x69, 0x73, 0x3b, 0x4b, 0x75, 0x6d, +0x3b, 0x4d, 0x6f, 0x6a, 0x3b, 0x59, 0x65, 0x6c, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x6b, 0x77, +0x61, 0x6e, 0x7a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x75, 0x6e, 0x61, 0x79, 0x65, 0x6c, +0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x75, 0x6e, 0x65, 0x72, 0x61, 0x72, 0x75, 0x3b, 0x4d, +0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x75, 0x6e, 0x65, 0x63, 0x68, 0x65, 0x73, 0x68, 0x65, 0x3b, 0x4d, 0x77, +0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x75, 0x6e, 0x65, 0x74, 0x68, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x72, +0x69, 0x20, 0x77, 0x6f, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x75, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x6f, 0x63, 0x68, 0x61, 0x3b, +0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x73, 0x61, 0x62, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, +0x77, 0x6f, 0x20, 0x6e, 0x61, 0x6e, 0x65, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x74, 0x69, 0x73, +0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, +0x69, 0x20, 0x77, 0x6f, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x6f, 0x6a, 0x61, 0x3b, 0x4d, 0x77, +0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x79, 0x65, 0x6c, 0x2019, 0x6c, +0x69, 0x3b, 0x4b, 0x3b, 0x55, 0x3b, 0x52, 0x3b, 0x43, 0x3b, 0x54, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, +0x4b, 0x3b, 0x4d, 0x3b, 0x59, 0x3b, 0x46, 0x4c, 0x4f, 0x3b, 0x43, 0x4c, 0x41, 0x3b, 0x43, 0x4b, 0x49, 0x3b, 0x46, 0x4d, +0x46, 0x3b, 0x4d, 0x41, 0x44, 0x3b, 0x4d, 0x42, 0x49, 0x3b, 0x4d, 0x4c, 0x49, 0x3b, 0x4d, 0x41, 0x4d, 0x3b, 0x46, 0x44, +0x45, 0x3b, 0x46, 0x4d, 0x55, 0x3b, 0x46, 0x47, 0x57, 0x3b, 0x46, 0x59, 0x55, 0x3b, 0x46, 0x129, 0x69, 0x20, 0x4c, 0x6f, +0x6f, 0x3b, 0x43, 0x6f, 0x6b, 0x63, 0x77, 0x61, 0x6b, 0x6c, 0x61, 0x14b, 0x6e, 0x65, 0x3b, 0x43, 0x6f, 0x6b, 0x63, 0x77, +0x61, 0x6b, 0x6c, 0x69, 0x69, 0x3b, 0x46, 0x129, 0x69, 0x20, 0x4d, 0x61, 0x72, 0x66, 0x6f, 0x6f, 0x3b, 0x4d, 0x61, 0x64, +0x1dd, 0x1dd, 0x75, 0x75, 0x74, 0x1dd, 0x62, 0x69, 0x6a, 0x61, 0x14b, 0x3b, 0x4d, 0x61, 0x6d, 0x1dd, 0x14b, 0x67, 0x77, 0xe3, +0x61, 0x66, 0x61, 0x68, 0x62, 0x69, 0x69, 0x3b, 0x4d, 0x61, 0x6d, 0x1dd, 0x14b, 0x67, 0x77, 0xe3, 0x61, 0x6c, 0x69, 0x69, +0x3b, 0x4d, 0x61, 0x64, 0x1dd, 0x6d, 0x62, 0x69, 0x69, 0x3b, 0x46, 0x129, 0x69, 0x20, 0x44, 0x1dd, 0x253, 0x6c, 0x69, 0x69, +0x3b, 0x46, 0x129, 0x69, 0x20, 0x4d, 0x75, 0x6e, 0x64, 0x61, 0x14b, 0x3b, 0x46, 0x129, 0x69, 0x20, 0x47, 0x77, 0x61, 0x68, +0x6c, 0x6c, 0x65, 0x3b, 0x46, 0x129, 0x69, 0x20, 0x59, 0x75, 0x72, 0x75, 0x3b, 0x4f, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x46, +0x3b, 0x44, 0x3b, 0x42, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x55, 0x3b, 0x57, 0x3b, 0x59, 0x3b, 0x6e, 0x67, 0x31, +0x3b, 0x6e, 0x67, 0x32, 0x3b, 0x6e, 0x67, 0x33, 0x3b, 0x6e, 0x67, 0x34, 0x3b, 0x6e, 0x67, 0x35, 0x3b, 0x6e, 0x67, 0x36, +0x3b, 0x6e, 0x67, 0x37, 0x3b, 0x6e, 0x67, 0x38, 0x3b, 0x6e, 0x67, 0x39, 0x3b, 0x6e, 0x67, 0x31, 0x30, 0x3b, 0x6e, 0x67, +0x31, 0x31, 0x3b, 0x6b, 0x72, 0x69, 0x73, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0xe1, 0x68, 0x72, +0x61, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x144, 0x6d, 0x62, 0x61, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x144, +0x6c, 0x61, 0x6c, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x144, 0x6e, 0x61, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, +0x144, 0x74, 0x61, 0x6e, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x144, 0x74, 0x75, 0xf3, 0x3b, 0x6e, 0x67, 0x77, 0x25b, +0x6e, 0x20, 0x68, 0x25b, 0x6d, 0x62, 0x75, 0x25b, 0x72, 0xed, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x6c, 0x254, 0x6d, +0x62, 0x69, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x72, 0x25b, 0x62, 0x76, 0x75, 0xe2, 0x3b, 0x6e, 0x67, 0x77, 0x25b, +0x6e, 0x20, 0x77, 0x75, 0x6d, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x77, 0x75, 0x6d, 0x20, 0x6e, 0x61, 0x76, 0x1d4, +0x72, 0x3b, 0x6b, 0x72, 0xed, 0x73, 0x69, 0x6d, 0x69, 0x6e, 0x3b, 0x54, 0x69, 0x6f, 0x70, 0x3b, 0x50, 0x25b, 0x74, 0x3b, +0x44, 0x75, 0x254, 0x331, 0x254, 0x331, 0x3b, 0x47, 0x75, 0x61, 0x6b, 0x3b, 0x44, 0x75, 0xe4, 0x3b, 0x4b, 0x6f, 0x72, 0x3b, +0x50, 0x61, 0x79, 0x3b, 0x54, 0x68, 0x6f, 0x6f, 0x3b, 0x54, 0x25b, 0x25b, 0x3b, 0x4c, 0x61, 0x61, 0x3b, 0x4b, 0x75, 0x72, +0x3b, 0x54, 0x69, 0x64, 0x3b, 0x54, 0x69, 0x6f, 0x70, 0x20, 0x74, 0x68, 0x61, 0x72, 0x20, 0x70, 0x25b, 0x74, 0x3b, 0x50, +0x25b, 0x74, 0x3b, 0x44, 0x75, 0x254, 0x331, 0x254, 0x331, 0x14b, 0x3b, 0x47, 0x75, 0x61, 0x6b, 0x3b, 0x44, 0x75, 0xe4, 0x74, +0x3b, 0x4b, 0x6f, 0x72, 0x6e, 0x79, 0x6f, 0x6f, 0x74, 0x3b, 0x50, 0x61, 0x79, 0x20, 0x79, 0x69, 0x65, 0x331, 0x74, 0x6e, +0x69, 0x3b, 0x54, 0x68, 0x6f, 0x331, 0x6f, 0x331, 0x72, 0x3b, 0x54, 0x25b, 0x25b, 0x72, 0x3b, 0x4c, 0x61, 0x61, 0x74, 0x68, +0x3b, 0x4b, 0x75, 0x72, 0x3b, 0x54, 0x69, 0x6f, 0x331, 0x70, 0x20, 0x69, 0x6e, 0x20, 0x64, 0x69, 0x331, 0x69, 0x331, 0x74, +0x3b, 0x54, 0x3b, 0x50, 0x3b, 0x44, 0x3b, 0x47, 0x3b, 0x44, 0x3b, 0x4b, 0x3b, 0x50, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4c, +0x3b, 0x4b, 0x3b, 0x54, 0x3b, 0x422, 0x43e, 0x445, 0x441, 0x3b, 0x41e, 0x43b, 0x443, 0x43d, 0x3b, 0x41a, 0x43b, 0x43d, 0x3b, 0x41c, +0x441, 0x443, 0x3b, 0x42b, 0x430, 0x43c, 0x3b, 0x411, 0x44d, 0x441, 0x3b, 0x41e, 0x442, 0x439, 0x3b, 0x410, 0x442, 0x440, 0x3b, 0x411, +0x43b, 0x495, 0x3b, 0x410, 0x43b, 0x442, 0x3b, 0x421, 0x44d, 0x442, 0x3b, 0x410, 0x445, 0x441, 0x3b, 0x442, 0x43e, 0x445, 0x441, 0x443, +0x43d, 0x43d, 0x44c, 0x443, 0x3b, 0x43e, 0x43b, 0x443, 0x43d, 0x43d, 0x44c, 0x443, 0x3b, 0x43a, 0x443, 0x43b, 0x443, 0x43d, 0x20, 0x442, +0x443, 0x442, 0x430, 0x440, 0x3b, 0x43c, 0x443, 0x443, 0x441, 0x20, 0x443, 0x441, 0x442, 0x430, 0x440, 0x3b, 0x44b, 0x430, 0x43c, 0x20, +0x44b, 0x439, 0x430, 0x3b, 0x431, 0x44d, 0x441, 0x20, 0x44b, 0x439, 0x430, 0x3b, 0x43e, 0x442, 0x20, 0x44b, 0x439, 0x430, 0x3b, 0x430, +0x442, 0x44b, 0x440, 0x434, 0x44c, 0x44b, 0x445, 0x20, 0x44b, 0x439, 0x430, 0x3b, 0x431, 0x430, 0x43b, 0x430, 0x495, 0x430, 0x43d, 0x20, +0x44b, 0x439, 0x430, 0x3b, 0x430, 0x43b, 0x442, 0x44b, 0x43d, 0x43d, 0x44c, 0x44b, 0x3b, 0x441, 0x44d, 0x442, 0x438, 0x43d, 0x43d, 0x44c, +0x438, 0x3b, 0x430, 0x445, 0x441, 0x44b, 0x43d, 0x43d, 0x44c, 0x44b, 0x3b, 0x422, 0x3b, 0x41e, 0x3b, 0x41a, 0x3b, 0x41c, 0x3b, 0x42b, +0x3b, 0x411, 0x3b, 0x41e, 0x3b, 0x410, 0x3b, 0x411, 0x3b, 0x410, 0x3b, 0x421, 0x3b, 0x410, 0x3b, 0x422, 0x43e, 0x445, 0x441, 0x443, +0x43d, 0x43d, 0x44c, 0x443, 0x3b, 0x41e, 0x43b, 0x443, 0x43d, 0x43d, 0x44c, 0x443, 0x3b, 0x41a, 0x443, 0x43b, 0x443, 0x43d, 0x20, 0x442, +0x443, 0x442, 0x430, 0x440, 0x3b, 0x41c, 0x443, 0x443, 0x441, 0x20, 0x443, 0x441, 0x442, 0x430, 0x440, 0x3b, 0x42b, 0x430, 0x43c, 0x20, +0x44b, 0x439, 0x44b, 0x43d, 0x3b, 0x411, 0x44d, 0x441, 0x20, 0x44b, 0x439, 0x44b, 0x43d, 0x3b, 0x41e, 0x442, 0x20, 0x44b, 0x439, 0x44b, +0x43d, 0x3b, 0x410, 0x442, 0x44b, 0x440, 0x434, 0x44c, 0x44b, 0x445, 0x20, 0x44b, 0x439, 0x44b, 0x43d, 0x3b, 0x411, 0x430, 0x43b, 0x430, +0x495, 0x430, 0x43d, 0x20, 0x44b, 0x439, 0x44b, 0x43d, 0x3b, 0x410, 0x43b, 0x442, 0x44b, 0x43d, 0x43d, 0x44c, 0x44b, 0x3b, 0x421, 0x44d, +0x442, 0x438, 0x43d, 0x43d, 0x44c, 0x438, 0x3b, 0x430, 0x445, 0x441, 0x44b, 0x43d, 0x43d, 0x44c, 0x44b, 0x3b, 0x4d, 0x75, 0x70, 0x3b, +0x4d, 0x77, 0x69, 0x3b, 0x4d, 0x73, 0x68, 0x3b, 0x4d, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x67, 0x3b, 0x4d, 0x75, 0x6a, 0x3b, +0x4d, 0x73, 0x70, 0x3b, 0x4d, 0x70, 0x67, 0x3b, 0x4d, 0x79, 0x65, 0x3b, 0x4d, 0x6f, 0x6b, 0x3b, 0x4d, 0x75, 0x73, 0x3b, +0x4d, 0x75, 0x68, 0x3b, 0x4d, 0x75, 0x70, 0x61, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x6c, 0x77, 0x61, 0x3b, 0x4d, 0x77, 0x69, +0x74, 0x6f, 0x70, 0x65, 0x3b, 0x4d, 0x75, 0x73, 0x68, 0x65, 0x6e, 0x64, 0x65, 0x3b, 0x4d, 0x75, 0x6e, 0x79, 0x69, 0x3b, +0x4d, 0x75, 0x73, 0x68, 0x65, 0x6e, 0x64, 0x65, 0x20, 0x4d, 0x61, 0x67, 0x61, 0x6c, 0x69, 0x3b, 0x4d, 0x75, 0x6a, 0x69, +0x6d, 0x62, 0x69, 0x3b, 0x4d, 0x75, 0x73, 0x68, 0x69, 0x70, 0x65, 0x70, 0x6f, 0x3b, 0x4d, 0x75, 0x70, 0x75, 0x67, 0x75, +0x74, 0x6f, 0x3b, 0x4d, 0x75, 0x6e, 0x79, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x4d, 0x6f, 0x6b, 0x68, 0x75, 0x3b, 0x4d, 0x75, +0x73, 0x6f, 0x6e, 0x67, 0x61, 0x6e, 0x64, 0x65, 0x6d, 0x62, 0x77, 0x65, 0x3b, 0x4d, 0x75, 0x68, 0x61, 0x61, 0x6e, 0x6f, +0x3b, 0xa5a8, 0xa595, 0xa51e, 0x3b, 0xa552, 0xa561, 0x3b, 0xa57e, 0xa5ba, 0x3b, 0xa5a2, 0xa595, 0x3b, 0xa591, 0xa571, 0x3b, 0xa5b1, 0xa60b, 0x3b, +0xa5b1, 0xa55e, 0x3b, 0xa5db, 0xa515, 0x3b, 0xa562, 0xa54c, 0x3b, 0xa56d, 0xa583, 0x3b, 0xa51e, 0xa60b, 0x3b, 0xa5a8, 0xa595, 0xa5cf, 0x3b, 0xa5a8, +0xa595, 0x20, 0xa56a, 0xa574, 0x20, 0xa51e, 0xa500, 0xa56e, 0xa54a, 0x3b, 0xa552, 0xa561, 0xa59d, 0xa595, 0x3b, 0xa57e, 0xa5ba, 0x3b, 0xa5a2, 0xa595, +0x3b, 0xa591, 0xa571, 0x3b, 0xa5b1, 0xa60b, 0x3b, 0xa5b1, 0xa55e, 0xa524, 0x3b, 0xa5db, 0xa515, 0x3b, 0xa562, 0xa54c, 0x3b, 0xa56d, 0xa583, 0x3b, +0xa51e, 0xa60b, 0xa554, 0xa57f, 0x20, 0xa578, 0xa583, 0xa5cf, 0x3b, 0xa5a8, 0xa595, 0x20, 0xa56a, 0xa574, 0x20, 0xa5cf, 0xa5ba, 0xa56e, 0xa54a, 0x3b, +0x6c, 0x75, 0x75, 0x6b, 0x61, 0x6f, 0x20, 0x6b, 0x65, 0x6d, 0xe3, 0x3b, 0x253, 0x61, 0x6e, 0x64, 0x61, 0x253, 0x75, 0x3b, +0x76, 0x254, 0x254, 0x3b, 0x66, 0x75, 0x6c, 0x75, 0x3b, 0x67, 0x6f, 0x6f, 0x3b, 0x36, 0x3b, 0x37, 0x3b, 0x6b, 0x254, 0x6e, +0x64, 0x65, 0x3b, 0x73, 0x61, 0x61, 0x68, 0x3b, 0x67, 0x61, 0x6c, 0x6f, 0x3b, 0x6b, 0x65, 0x6e, 0x70, 0x6b, 0x61, 0x74, +0x6f, 0x20, 0x253, 0x6f, 0x6c, 0x6f, 0x6c, 0x254, 0x3b, 0x6c, 0x75, 0x75, 0x6b, 0x61, 0x6f, 0x20, 0x6c, 0x254, 0x6d, 0x61, +0x3b, 0x4a, 0x65, 0x6e, 0x3b, 0x48, 0x6f, 0x72, 0x3b, 0x4d, 0xe4, 0x72, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, 0x65, 0x69, +0x3b, 0x42, 0x72, 0xe1, 0x3b, 0x48, 0x65, 0x69, 0x3b, 0xd6, 0x69, 0x67, 0x3b, 0x48, 0x65, 0x72, 0x3b, 0x57, 0xed, 0x6d, +0x3b, 0x57, 0x69, 0x6e, 0x3b, 0x43, 0x68, 0x72, 0x3b, 0x4a, 0x65, 0x6e, 0x6e, 0x65, 0x72, 0x3b, 0x48, 0x6f, 0x72, 0x6e, +0x69, 0x67, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x65, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x6c, 0x65, 0x3b, 0x4d, 0x65, 0x69, +0x6a, 0x65, 0x3b, 0x42, 0x72, 0xe1, 0x10d, 0x65, 0x74, 0x3b, 0x48, 0x65, 0x69, 0x77, 0x65, 0x74, 0x3b, 0xd6, 0x69, 0x67, +0x161, 0x74, 0x65, 0x3b, 0x48, 0x65, 0x72, 0x62, 0x161, 0x74, 0x6d, 0xe1, 0x6e, 0x65, 0x74, 0x3b, 0x57, 0xed, 0x6d, 0xe1, +0x6e, 0x65, 0x74, 0x3b, 0x57, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0xe1, 0x6e, 0x65, 0x74, 0x3b, 0x43, 0x68, 0x72, 0x69, +0x161, 0x74, 0x6d, 0xe1, 0x6e, 0x65, 0x74, 0x3b, 0x4a, 0x3b, 0x48, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x42, 0x3b, +0x48, 0x3b, 0xd6, 0x3b, 0x48, 0x3b, 0x57, 0x3b, 0x57, 0x3b, 0x43, 0x3b, 0x6f, 0x2e, 0x31, 0x3b, 0x6f, 0x2e, 0x32, 0x3b, +0x6f, 0x2e, 0x33, 0x3b, 0x6f, 0x2e, 0x34, 0x3b, 0x6f, 0x2e, 0x35, 0x3b, 0x6f, 0x2e, 0x36, 0x3b, 0x6f, 0x2e, 0x37, 0x3b, +0x6f, 0x2e, 0x38, 0x3b, 0x6f, 0x2e, 0x39, 0x3b, 0x6f, 0x2e, 0x31, 0x30, 0x3b, 0x6f, 0x2e, 0x31, 0x31, 0x3b, 0x6f, 0x2e, +0x31, 0x32, 0x3b, 0x70, 0x69, 0x6b, 0xed, 0x74, 0xed, 0x6b, 0xed, 0x74, 0x69, 0x65, 0x2c, 0x20, 0x6f, 0xf3, 0x6c, 0xed, +0x20, 0xfa, 0x20, 0x6b, 0x75, 0x74, 0xfa, 0x61, 0x6e, 0x3b, 0x73, 0x69, 0x25b, 0x79, 0x25b, 0x301, 0x2c, 0x20, 0x6f, 0xf3, +0x6c, 0x69, 0x20, 0xfa, 0x20, 0x6b, 0xe1, 0x6e, 0x64, 0xed, 0x25b, 0x3b, 0x254, 0x6e, 0x73, 0xfa, 0x6d, 0x62, 0x254, 0x6c, +0x2c, 0x20, 0x6f, 0xf3, 0x6c, 0x69, 0x20, 0xfa, 0x20, 0x6b, 0xe1, 0x74, 0xe1, 0x74, 0xfa, 0x25b, 0x3b, 0x6d, 0x65, 0x73, +0x69, 0x14b, 0x2c, 0x20, 0x6f, 0xf3, 0x6c, 0x69, 0x20, 0xfa, 0x20, 0x6b, 0xe9, 0x6e, 0x69, 0x65, 0x3b, 0x65, 0x6e, 0x73, +0x69, 0x6c, 0x2c, 0x20, 0x6f, 0xf3, 0x6c, 0x69, 0x20, 0xfa, 0x20, 0x6b, 0xe1, 0x74, 0xe1, 0x6e, 0x75, 0x25b, 0x3b, 0x254, +0x73, 0x254, 0x6e, 0x3b, 0x65, 0x66, 0x75, 0x74, 0x65, 0x3b, 0x70, 0x69, 0x73, 0x75, 0x79, 0xfa, 0x3b, 0x69, 0x6d, 0x25b, +0x14b, 0x20, 0x69, 0x20, 0x70, 0x75, 0x254, 0x73, 0x3b, 0x69, 0x6d, 0x25b, 0x14b, 0x20, 0x69, 0x20, 0x70, 0x75, 0x74, 0xfa, +0x6b, 0x2c, 0x6f, 0xf3, 0x6c, 0x69, 0x20, 0xfa, 0x20, 0x6b, 0xe1, 0x74, 0xed, 0x25b, 0x3b, 0x6d, 0x61, 0x6b, 0x61, 0x6e, +0x64, 0x69, 0x6b, 0x25b, 0x3b, 0x70, 0x69, 0x6c, 0x254, 0x6e, 0x64, 0x254, 0x301, 0x3b, 0x58, 0x69, 0x6e, 0x3b, 0x46, 0x65, +0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x58, 0x75, 0x6e, 0x3b, 0x58, 0x6e, +0x74, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x63, 0x68, 0x3b, 0x50, 0x61, 0x79, 0x3b, 0x41, 0x76, +0x69, 0x3b, 0x78, 0x69, 0x6e, 0x65, 0x72, 0x75, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x65, 0x72, 0x75, 0x3b, 0x6d, 0x61, 0x72, +0x7a, 0x75, 0x3b, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x79, 0x75, 0x3b, 0x78, 0x75, 0x6e, 0x75, 0x3b, 0x78, +0x75, 0x6e, 0x65, 0x74, 0x75, 0x3b, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x75, 0x3b, 0x73, 0x65, 0x74, 0x69, 0x65, 0x6d, 0x62, +0x72, 0x65, 0x3b, 0x6f, 0x63, 0x68, 0x6f, 0x62, 0x72, 0x65, 0x3b, 0x70, 0x61, 0x79, 0x61, 0x72, 0x65, 0x73, 0x3b, 0x61, +0x76, 0x69, 0x65, 0x6e, 0x74, 0x75, 0x3b, 0x58, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x58, 0x3b, 0x58, +0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x50, 0x3b, 0x41, 0x3b, 0x78, 0x69, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, +0x61, 0x72, 0x3b, 0x61, 0x62, 0x72, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x78, 0x75, 0x6e, 0x3b, 0x78, 0x6e, 0x74, 0x3b, 0x61, +0x67, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x3b, 0x6f, 0x63, 0x68, 0x3b, 0x70, 0x61, 0x79, 0x3b, 0x61, 0x76, 0x69, 0x3b, 0x64, +0x65, 0x20, 0x78, 0x69, 0x6e, 0x65, 0x72, 0x75, 0x3b, 0x64, 0x65, 0x20, 0x66, 0x65, 0x62, 0x72, 0x65, 0x72, 0x75, 0x3b, +0x64, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x7a, 0x75, 0x3b, 0x64, 0x2019, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x64, 0x65, 0x20, +0x6d, 0x61, 0x79, 0x75, 0x3b, 0x64, 0x65, 0x20, 0x78, 0x75, 0x6e, 0x75, 0x3b, 0x64, 0x65, 0x20, 0x78, 0x75, 0x6e, 0x65, +0x74, 0x75, 0x3b, 0x64, 0x2019, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x75, 0x3b, 0x64, 0x65, 0x20, 0x73, 0x65, 0x74, 0x69, 0x65, +0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x2019, 0x6f, 0x63, 0x68, 0x6f, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x65, 0x20, 0x70, 0x61, +0x79, 0x61, 0x72, 0x65, 0x73, 0x3b, 0x64, 0x2019, 0x61, 0x76, 0x69, 0x65, 0x6e, 0x74, 0x75, 0x3b, 0x4e, 0x64, 0x75, 0x14b, +0x6d, 0x62, 0x69, 0x20, 0x53, 0x61, 0x14b, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x50, 0x25b, 0x301, 0x70, 0xe1, 0x3b, +0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x50, 0x25b, 0x301, 0x74, 0xe1, 0x74, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x50, +0x25b, 0x301, 0x6e, 0x25b, 0x301, 0x6b, 0x77, 0x61, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x50, 0x61, 0x74, 0x61, 0x61, +0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x50, 0x25b, 0x301, 0x6e, 0x25b, 0x301, 0x6e, 0x74, 0xfa, 0x6b, 0xfa, 0x3b, 0x50, +0x25b, 0x73, 0x61, 0x14b, 0x20, 0x53, 0x61, 0x61, 0x6d, 0x62, 0xe1, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x50, 0x25b, +0x301, 0x6e, 0x25b, 0x301, 0x66, 0x254, 0x6d, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x50, 0x25b, 0x301, 0x6e, 0x25b, 0x301, +0x70, 0x66, 0xfa, 0xa78b, 0xfa, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x4e, 0x25b, 0x67, 0x25b, 0x301, 0x6d, 0x3b, 0x50, +0x25b, 0x73, 0x61, 0x14b, 0x20, 0x4e, 0x74, 0x73, 0x254, 0x30c, 0x70, 0x6d, 0x254, 0x301, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, +0x20, 0x4e, 0x74, 0x73, 0x254, 0x30c, 0x70, 0x70, 0xe1, 0x3b, 0x70, 0x61, 0x6d, 0x62, 0x61, 0x3b, 0x77, 0x61, 0x6e, 0x6a, +0x61, 0x3b, 0x6d, 0x62, 0x69, 0x79, 0x254, 0x20, 0x6d, 0x25b, 0x6e, 0x64, 0x6f, 0x14b, 0x67, 0x254, 0x3b, 0x4e, 0x79, 0x254, +0x6c, 0x254, 0x6d, 0x62, 0x254, 0x14b, 0x67, 0x254, 0x3b, 0x4d, 0x254, 0x6e, 0x254, 0x20, 0x14b, 0x67, 0x62, 0x61, 0x6e, 0x6a, +0x61, 0x3b, 0x4e, 0x79, 0x61, 0x14b, 0x67, 0x77, 0x25b, 0x20, 0x14b, 0x67, 0x62, 0x61, 0x6e, 0x6a, 0x61, 0x3b, 0x6b, 0x75, +0x14b, 0x67, 0x77, 0x25b, 0x3b, 0x66, 0x25b, 0x3b, 0x6e, 0x6a, 0x61, 0x70, 0x69, 0x3b, 0x6e, 0x79, 0x75, 0x6b, 0x75, 0x6c, +0x3b, 0x31, 0x31, 0x3b, 0x253, 0x75, 0x6c, 0x253, 0x75, 0x73, 0x25b, 0x3b, 0x6d, 0x62, 0x65, 0x67, 0x74, 0x75, 0x67, 0x3b, +0x69, 0x6d, 0x65, 0x67, 0x20, 0xe0, 0x62, 0xf9, 0x62, 0xec, 0x3b, 0x69, 0x6d, 0x65, 0x67, 0x20, 0x6d, 0x62, 0x259, 0x14b, +0x63, 0x68, 0x75, 0x62, 0x69, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x6e, 0x67, 0x77, 0x259, 0x300, 0x74, 0x3b, 0x69, 0x6d, +0x259, 0x67, 0x20, 0x66, 0x6f, 0x67, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x69, 0x63, 0x68, 0x69, 0x69, 0x62, 0x254, 0x64, +0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0xe0, 0x64, 0xf9, 0x6d, 0x62, 0x259, 0x300, 0x14b, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, +0x69, 0x63, 0x68, 0x69, 0x6b, 0x61, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x6b, 0x75, 0x64, 0x3b, 0x69, 0x6d, 0x259, 0x67, +0x20, 0x74, 0xe8, 0x73, 0x69, 0x2bc, 0x65, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x7a, 0xf2, 0x3b, 0x69, 0x6d, 0x259, 0x67, +0x20, 0x6b, 0x72, 0x69, 0x7a, 0x6d, 0x65, 0x64, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x6d, 0x62, 0x65, 0x67, 0x74, 0x75, 0x67, 0x3b, 0x69, 0x6d, 0x65, 0x67, 0x20, 0xe0, 0x62, 0xf9, 0x62, 0xec, 0x3b, 0x69, 0x6d, 0x65, 0x67, 0x20, 0x6d, 0x62, 0x259, 0x14b, 0x63, 0x68, 0x75, 0x62, 0x69, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x6e, 0x67, 0x77, 0x259, 0x300, 0x74, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x66, 0x6f, 0x67, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x69, 0x63, 0x68, 0x69, 0x69, 0x62, 0x254, 0x64, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0xe0, 0x64, 0xf9, 0x6d, 0x62, 0x259, 0x300, 0x14b, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x69, 0x63, 0x68, 0x69, 0x6b, 0x61, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x6b, 0x75, 0x64, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x74, 0xe8, 0x73, 0x69, 0x2bc, 0x65, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x7a, 0xf2, 0x3b, 0x69, 0x6d, -0x259, 0x67, 0x20, 0x6b, 0x72, 0x69, 0x7a, 0x6d, 0x65, 0x64, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x6d, 0x62, 0x65, 0x67, -0x74, 0x75, 0x67, 0x3b, 0x69, 0x6d, 0x65, 0x67, 0x20, 0xe0, 0x62, 0xf9, 0x62, 0xec, 0x3b, 0x69, 0x6d, 0x65, 0x67, 0x20, -0x6d, 0x62, 0x259, 0x14b, 0x63, 0x68, 0x75, 0x62, 0x69, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x6e, 0x67, 0x77, 0x259, 0x300, -0x74, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x66, 0x6f, 0x67, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x69, 0x63, 0x68, 0x69, -0x69, 0x62, 0x254, 0x64, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0xe0, 0x64, 0xf9, 0x6d, 0x62, 0x259, 0x300, 0x14b, 0x3b, 0x69, -0x6d, 0x259, 0x67, 0x20, 0x69, 0x63, 0x68, 0x69, 0x6b, 0x61, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x6b, 0x75, 0x64, 0x3b, -0x69, 0x6d, 0x259, 0x67, 0x20, 0x74, 0xe8, 0x73, 0x69, 0x2bc, 0x65, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x7a, 0xf2, 0x3b, -0x69, 0x6d, 0x259, 0x67, 0x20, 0x6b, 0x72, 0x69, 0x7a, 0x6d, 0x65, 0x64, 0x3b, 0x4d, 0x31, 0x3b, 0x41, 0x32, 0x3b, 0x4d, -0x33, 0x3b, 0x4e, 0x34, 0x3b, 0x46, 0x35, 0x3b, 0x49, 0x36, 0x3b, 0x41, 0x37, 0x3b, 0x49, 0x38, 0x3b, 0x4b, 0x39, 0x3b, -0x31, 0x30, 0x3b, 0x31, 0x31, 0x3b, 0x31, 0x32, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x74, 0x73, 0x65, 0x74, 0x73, 0x25b, 0x300, -0x25b, 0x20, 0x6c, 0xf9, 0x6d, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x6b, 0xe0, 0x67, 0x20, 0x6e, 0x67, 0x77, 0xf3, 0x14b, 0x3b, -0x73, 0x61, 0x14b, 0x20, 0x6c, 0x65, 0x70, 0x79, 0xe8, 0x20, 0x73, 0x68, 0xfa, 0x6d, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x63, -0xff, 0xf3, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x74, 0x73, 0x25b, 0x300, 0x25b, 0x20, 0x63, 0xff, 0xf3, 0x3b, 0x73, 0x61, 0x14b, -0x20, 0x6e, 0x6a, 0xff, 0x6f, 0x6c, 0xe1, 0x2bc, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x74, 0x79, 0x25b, 0x300, 0x62, 0x20, 0x74, -0x79, 0x25b, 0x300, 0x62, 0x20, 0x6d, 0x62, 0x289, 0x300, 0x14b, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x6d, 0x62, 0x289, 0x300, 0x14b, -0x3b, 0x73, 0x61, 0x14b, 0x20, 0x6e, 0x67, 0x77, 0x254, 0x300, 0x2bc, 0x20, 0x6d, 0x62, 0xff, 0x25b, 0x3b, 0x73, 0x61, 0x14b, -0x20, 0x74, 0xe0, 0x14b, 0x61, 0x20, 0x74, 0x73, 0x65, 0x74, 0x73, 0xe1, 0x2bc, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x6d, 0x65, -0x6a, 0x77, 0x6f, 0x14b, 0xf3, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x6c, 0xf9, 0x6d, 0x3b, 0x57, 0x69, 0xf3, 0x74, 0x68, 0x65, -0x21f, 0x69, 0x6b, 0x61, 0x20, 0x57, 0xed, 0x3b, 0x54, 0x68, 0x69, 0x79, 0xf3, 0x21f, 0x65, 0x79, 0x75, 0x14b, 0x6b, 0x61, -0x20, 0x57, 0xed, 0x3b, 0x49, 0x161, 0x74, 0xe1, 0x77, 0x69, 0x10d, 0x68, 0x61, 0x79, 0x61, 0x7a, 0x61, 0x14b, 0x20, 0x57, -0xed, 0x3b, 0x50, 0x21f, 0x65, 0x17e, 0xed, 0x74, 0x21f, 0x6f, 0x20, 0x57, 0xed, 0x3b, 0x10c, 0x68, 0x61, 0x14b, 0x77, 0xe1, -0x70, 0x65, 0x74, 0x21f, 0x6f, 0x20, 0x57, 0xed, 0x3b, 0x57, 0xed, 0x70, 0x61, 0x7a, 0x75, 0x6b, 0x21f, 0x61, 0x2d, 0x77, -0x61, 0x161, 0x74, 0xe9, 0x20, 0x57, 0xed, 0x3b, 0x10c, 0x68, 0x61, 0x14b, 0x70, 0x21f, 0xe1, 0x73, 0x61, 0x70, 0x61, 0x20, -0x57, 0xed, 0x3b, 0x57, 0x61, 0x73, 0xfa, 0x74, 0x21f, 0x75, 0x14b, 0x20, 0x57, 0xed, 0x3b, 0x10c, 0x68, 0x61, 0x14b, 0x77, -0xe1, 0x70, 0x65, 0x1e7, 0x69, 0x20, 0x57, 0xed, 0x3b, 0x10c, 0x68, 0x61, 0x14b, 0x77, 0xe1, 0x70, 0x65, 0x2d, 0x6b, 0x61, -0x73, 0x6e, 0xe1, 0x20, 0x57, 0xed, 0x3b, 0x57, 0x61, 0x6e, 0xed, 0x79, 0x65, 0x74, 0x75, 0x20, 0x57, 0xed, 0x3b, 0x54, -0x21f, 0x61, 0x68, 0xe9, 0x6b, 0x61, 0x70, 0x161, 0x75, 0x14b, 0x20, 0x57, 0xed, 0x3b, 0x6a9, 0x627, 0x646, 0x648, 0x648, 0x646, -0x6cc, 0x20, 0x62f, 0x648, 0x648, 0x6d5, 0x645, 0x3b, 0x634, 0x648, 0x628, 0x627, 0x62a, 0x3b, 0x626, 0x627, 0x632, 0x627, 0x631, 0x3b, -0x646, 0x6cc, 0x633, 0x627, 0x646, 0x3b, 0x626, 0x627, 0x6cc, 0x627, 0x631, 0x3b, 0x62d, 0x648, 0x632, 0x6d5, 0x6cc, 0x631, 0x627, 0x646, -0x3b, 0x62a, 0x6d5, 0x645, 0x648, 0x648, 0x632, 0x3b, 0x626, 0x627, 0x628, 0x3b, 0x626, 0x6d5, 0x6cc, 0x644, 0x648, 0x648, 0x644, 0x3b, -0x62a, 0x634, 0x631, 0x6cc, 0x646, 0x6cc, 0x20, 0x6cc, 0x6d5, 0x6a9, 0x6d5, 0x645, 0x3b, 0x62a, 0x634, 0x631, 0x6cc, 0x646, 0x6cc, 0x20, -0x62f, 0x648, 0x648, 0x6d5, 0x645, 0x3b, 0x6a9, 0x627, 0x646, 0x648, 0x646, 0x6cc, 0x20, 0x6cc, 0x6d5, 0x6a9, 0x6d5, 0x645, 0x3b, 0x6a9, -0x3b, 0x634, 0x3b, 0x626, 0x3b, 0x646, 0x3b, 0x626, 0x3b, 0x62d, 0x3b, 0x62a, 0x3b, 0x626, 0x3b, 0x626, 0x3b, 0x62a, 0x3b, 0x62a, -0x3b, 0x6a9, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x11b, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, -0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x77, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, -0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x77, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, -0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x11b, 0x72, 0x63, 0x3b, 0x61, 0x70, 0x72, 0x79, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, -0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x6a, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x6a, 0x3b, 0x61, 0x77, 0x67, 0x75, 0x73, 0x74, 0x3b, -0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, -0x77, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, -0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x11b, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x6a, 0x2e, -0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x77, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, -0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x77, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, -0x61, 0x72, 0x61, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x61, 0x3b, 0x6d, 0x11b, 0x72, 0x63, 0x61, 0x3b, 0x61, -0x70, 0x72, 0x79, 0x6c, 0x61, 0x3b, 0x6d, 0x61, 0x6a, 0x61, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x6a, 0x61, 0x3b, 0x6a, 0x75, -0x6c, 0x69, 0x6a, 0x61, 0x3b, 0x61, 0x77, 0x67, 0x75, 0x73, 0x74, 0x61, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, -0x72, 0x61, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x72, 0x61, 0x3b, 0x6e, 0x6f, 0x77, 0x65, 0x6d, 0x62, 0x72, 0x61, 0x3b, -0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x11b, 0x72, -0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x65, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x77, 0x67, -0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x77, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x6a, 0x61, 0x6e, -0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x11b, 0x72, 0x63, 0x3b, 0x61, 0x70, 0x72, -0x79, 0x6c, 0x3b, 0x6d, 0x65, 0x6a, 0x61, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x6a, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x6a, 0x3b, -0x61, 0x77, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, -0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x77, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, -0x65, 0x72, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x11b, 0x72, 0x2e, 0x3b, 0x61, 0x70, -0x72, 0x2e, 0x3b, 0x6d, 0x65, 0x6a, 0x2e, 0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x77, -0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x77, 0x2e, 0x3b, 0x64, 0x65, -0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x61, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x61, 0x3b, -0x6d, 0x11b, 0x72, 0x63, 0x61, 0x3b, 0x61, 0x70, 0x72, 0x79, 0x6c, 0x61, 0x3b, 0x6d, 0x65, 0x6a, 0x65, 0x3b, 0x6a, 0x75, -0x6e, 0x69, 0x6a, 0x61, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x6a, 0x61, 0x3b, 0x61, 0x77, 0x67, 0x75, 0x73, 0x74, 0x61, 0x3b, -0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x72, 0x61, 0x3b, 0x6e, 0x6f, -0x77, 0x65, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x72, 0x61, 0x67, 0x3b, -0x77, 0x61, 0x73, 0x3b, 0x70, 0x16b, 0x6c, 0x3b, 0x73, 0x61, 0x6b, 0x3b, 0x7a, 0x61, 0x6c, 0x3b, 0x73, 0x12b, 0x6d, 0x3b, -0x6c, 0x12b, 0x70, 0x3b, 0x64, 0x61, 0x67, 0x3b, 0x73, 0x69, 0x6c, 0x3b, 0x73, 0x70, 0x61, 0x3b, 0x6c, 0x61, 0x70, 0x3b, -0x73, 0x61, 0x6c, 0x3b, 0x72, 0x61, 0x67, 0x73, 0x3b, 0x77, 0x61, 0x73, 0x73, 0x61, 0x72, 0x69, 0x6e, 0x73, 0x3b, 0x70, -0x16b, 0x6c, 0x69, 0x73, 0x3b, 0x73, 0x61, 0x6b, 0x6b, 0x69, 0x73, 0x3b, 0x7a, 0x61, 0x6c, 0x6c, 0x61, 0x77, 0x73, 0x3b, -0x73, 0x12b, 0x6d, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x6c, 0x12b, 0x70, 0x61, 0x3b, 0x64, 0x61, 0x67, 0x67, 0x69, 0x73, 0x3b, -0x73, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x73, 0x3b, 0x73, 0x70, 0x61, 0x6c, 0x6c, 0x69, 0x6e, 0x73, 0x3b, 0x6c, 0x61, 0x70, -0x6b, 0x72, 0x16b, 0x74, 0x69, 0x73, 0x3b, 0x73, 0x61, 0x6c, 0x6c, 0x61, 0x77, 0x73, 0x3b, 0x52, 0x3b, 0x57, 0x3b, 0x50, -0x3b, 0x53, 0x3b, 0x5a, 0x3b, 0x53, 0x3b, 0x4c, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x4c, 0x3b, 0x53, 0x3b, 0x75, -0x111, 0x69, 0x76, 0x3b, 0x6b, 0x75, 0x6f, 0x76, 0xe2, 0x3b, 0x6e, 0x6a, 0x75, 0x68, 0x10d, 0xe2, 0x3b, 0x63, 0x75, 0xe1, -0x14b, 0x75, 0x69, 0x3b, 0x76, 0x79, 0x65, 0x73, 0x69, 0x3b, 0x6b, 0x65, 0x73, 0x69, 0x3b, 0x73, 0x79, 0x65, 0x69, 0x6e, -0x69, 0x3b, 0x70, 0x6f, 0x72, 0x67, 0x65, 0x3b, 0x10d, 0x6f, 0x68, 0x10d, 0xe2, 0x3b, 0x72, 0x6f, 0x6f, 0x76, 0x76, 0xe2, -0x64, 0x3b, 0x73, 0x6b, 0x61, 0x6d, 0x6d, 0xe2, 0x3b, 0x6a, 0x75, 0x6f, 0x76, 0x6c, 0xe2, 0x3b, 0x75, 0x111, 0x111, 0xe2, -0x69, 0x76, 0x65, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x6b, 0x75, 0x6f, 0x76, 0xe2, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, -0x6e, 0x6a, 0x75, 0x68, 0x10d, 0xe2, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x63, 0x75, 0xe1, 0x14b, 0x75, 0x69, 0x6d, 0xe1, -0xe1, 0x6e, 0x75, 0x3b, 0x76, 0x79, 0x65, 0x73, 0x69, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x6b, 0x65, 0x73, 0x69, 0x6d, -0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x73, 0x79, 0x65, 0x69, 0x6e, 0x69, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x70, 0x6f, 0x72, -0x67, 0x65, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x10d, 0x6f, 0x68, 0x10d, 0xe2, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x72, -0x6f, 0x6f, 0x76, 0x76, 0xe2, 0x64, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x73, 0x6b, 0x61, 0x6d, 0x6d, 0xe2, 0x6d, 0xe1, -0xe1, 0x6e, 0x75, 0x3b, 0x6a, 0x75, 0x6f, 0x76, 0x6c, 0xe2, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x55, 0x3b, 0x4b, 0x3b, -0x4e, 0x4a, 0x3b, 0x43, 0x3b, 0x56, 0x3b, 0x4b, 0x3b, 0x53, 0x3b, 0x50, 0x3b, 0x10c, 0x3b, 0x52, 0x3b, 0x53, 0x3b, 0x4a, -0x3b, 0x62c, 0x627, 0x646, 0x6a4, 0x6cc, 0x6d5, 0x3b, 0x641, 0x626, 0x6a4, 0x631, 0x6cc, 0x6d5, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, -0x622, 0x6a4, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x626, 0x6cc, 0x3b, 0x62c, 0x648, 0x659, 0x623, 0x646, 0x3b, 0x62c, 0x648, 0x659, 0x644, -0x627, 0x3b, 0x622, 0x6af, 0x648, 0x633, 0x62a, 0x3b, 0x633, 0x626, 0x67e, 0x62a, 0x627, 0x645, 0x631, 0x3b, 0x626, 0x648, 0x6a9, 0x62a, -0x648, 0x6a4, 0x631, 0x3b, 0x646, 0x648, 0x6a4, 0x627, 0x645, 0x631, 0x3b, 0x62f, 0x626, 0x633, 0x627, 0x645, 0x631, 0x3b +0x259, 0x67, 0x20, 0x6b, 0x72, 0x69, 0x7a, 0x6d, 0x65, 0x64, 0x3b, 0x4d, 0x31, 0x3b, 0x41, 0x32, 0x3b, 0x4d, 0x33, 0x3b, +0x4e, 0x34, 0x3b, 0x46, 0x35, 0x3b, 0x49, 0x36, 0x3b, 0x41, 0x37, 0x3b, 0x49, 0x38, 0x3b, 0x4b, 0x39, 0x3b, 0x31, 0x30, +0x3b, 0x31, 0x31, 0x3b, 0x31, 0x32, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x74, 0x73, 0x65, 0x74, 0x73, 0x25b, 0x300, 0x25b, 0x20, +0x6c, 0xf9, 0x6d, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x6b, 0xe0, 0x67, 0x20, 0x6e, 0x67, 0x77, 0xf3, 0x14b, 0x3b, 0x73, 0x61, +0x14b, 0x20, 0x6c, 0x65, 0x70, 0x79, 0xe8, 0x20, 0x73, 0x68, 0xfa, 0x6d, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x63, 0xff, 0xf3, +0x3b, 0x73, 0x61, 0x14b, 0x20, 0x74, 0x73, 0x25b, 0x300, 0x25b, 0x20, 0x63, 0xff, 0xf3, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x6e, +0x6a, 0xff, 0x6f, 0x6c, 0xe1, 0x2bc, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x74, 0x79, 0x25b, 0x300, 0x62, 0x20, 0x74, 0x79, 0x25b, +0x300, 0x62, 0x20, 0x6d, 0x62, 0x289, 0x300, 0x14b, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x6d, 0x62, 0x289, 0x300, 0x14b, 0x3b, 0x73, +0x61, 0x14b, 0x20, 0x6e, 0x67, 0x77, 0x254, 0x300, 0x2bc, 0x20, 0x6d, 0x62, 0xff, 0x25b, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x74, +0xe0, 0x14b, 0x61, 0x20, 0x74, 0x73, 0x65, 0x74, 0x73, 0xe1, 0x2bc, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x6d, 0x65, 0x6a, 0x77, +0x6f, 0x14b, 0xf3, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x6c, 0xf9, 0x6d, 0x3b, 0x57, 0x69, 0xf3, 0x74, 0x68, 0x65, 0x21f, 0x69, +0x6b, 0x61, 0x20, 0x57, 0xed, 0x3b, 0x54, 0x68, 0x69, 0x79, 0xf3, 0x21f, 0x65, 0x79, 0x75, 0x14b, 0x6b, 0x61, 0x20, 0x57, +0xed, 0x3b, 0x49, 0x161, 0x74, 0xe1, 0x77, 0x69, 0x10d, 0x68, 0x61, 0x79, 0x61, 0x7a, 0x61, 0x14b, 0x20, 0x57, 0xed, 0x3b, +0x50, 0x21f, 0x65, 0x17e, 0xed, 0x74, 0x21f, 0x6f, 0x20, 0x57, 0xed, 0x3b, 0x10c, 0x68, 0x61, 0x14b, 0x77, 0xe1, 0x70, 0x65, +0x74, 0x21f, 0x6f, 0x20, 0x57, 0xed, 0x3b, 0x57, 0xed, 0x70, 0x61, 0x7a, 0x75, 0x6b, 0x21f, 0x61, 0x2d, 0x77, 0x61, 0x161, +0x74, 0xe9, 0x20, 0x57, 0xed, 0x3b, 0x10c, 0x68, 0x61, 0x14b, 0x70, 0x21f, 0xe1, 0x73, 0x61, 0x70, 0x61, 0x20, 0x57, 0xed, +0x3b, 0x57, 0x61, 0x73, 0xfa, 0x74, 0x21f, 0x75, 0x14b, 0x20, 0x57, 0xed, 0x3b, 0x10c, 0x68, 0x61, 0x14b, 0x77, 0xe1, 0x70, +0x65, 0x1e7, 0x69, 0x20, 0x57, 0xed, 0x3b, 0x10c, 0x68, 0x61, 0x14b, 0x77, 0xe1, 0x70, 0x65, 0x2d, 0x6b, 0x61, 0x73, 0x6e, +0xe1, 0x20, 0x57, 0xed, 0x3b, 0x57, 0x61, 0x6e, 0xed, 0x79, 0x65, 0x74, 0x75, 0x20, 0x57, 0xed, 0x3b, 0x54, 0x21f, 0x61, +0x68, 0xe9, 0x6b, 0x61, 0x70, 0x161, 0x75, 0x14b, 0x20, 0x57, 0xed, 0x3b, 0x6a9, 0x627, 0x646, 0x648, 0x648, 0x646, 0x6cc, 0x20, +0x62f, 0x648, 0x648, 0x6d5, 0x645, 0x3b, 0x634, 0x648, 0x628, 0x627, 0x62a, 0x3b, 0x626, 0x627, 0x632, 0x627, 0x631, 0x3b, 0x646, 0x6cc, +0x633, 0x627, 0x646, 0x3b, 0x626, 0x627, 0x6cc, 0x627, 0x631, 0x3b, 0x62d, 0x648, 0x632, 0x6d5, 0x6cc, 0x631, 0x627, 0x646, 0x3b, 0x62a, +0x6d5, 0x645, 0x648, 0x648, 0x632, 0x3b, 0x626, 0x627, 0x628, 0x3b, 0x626, 0x6d5, 0x6cc, 0x644, 0x648, 0x648, 0x644, 0x3b, 0x62a, 0x634, +0x631, 0x6cc, 0x646, 0x6cc, 0x20, 0x6cc, 0x6d5, 0x6a9, 0x6d5, 0x645, 0x3b, 0x62a, 0x634, 0x631, 0x6cc, 0x646, 0x6cc, 0x20, 0x62f, 0x648, +0x648, 0x6d5, 0x645, 0x3b, 0x6a9, 0x627, 0x646, 0x648, 0x646, 0x6cc, 0x20, 0x6cc, 0x6d5, 0x6a9, 0x6d5, 0x645, 0x3b, 0x6a9, 0x3b, 0x634, +0x3b, 0x626, 0x3b, 0x646, 0x3b, 0x626, 0x3b, 0x62d, 0x3b, 0x62a, 0x3b, 0x626, 0x3b, 0x626, 0x3b, 0x62a, 0x3b, 0x62a, 0x3b, 0x6a9, +0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x11b, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x6a, +0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x77, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, +0x3b, 0x6e, 0x6f, 0x77, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, +0x75, 0x61, 0x72, 0x3b, 0x6d, 0x11b, 0x72, 0x63, 0x3b, 0x61, 0x70, 0x72, 0x79, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, +0x75, 0x6e, 0x69, 0x6a, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x6a, 0x3b, 0x61, 0x77, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, +0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x77, 0x65, +0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, +0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x11b, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x6a, 0x2e, 0x3b, 0x6a, +0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x77, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, +0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x77, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, +0x61, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x61, 0x3b, 0x6d, 0x11b, 0x72, 0x63, 0x61, 0x3b, 0x61, 0x70, 0x72, +0x79, 0x6c, 0x61, 0x3b, 0x6d, 0x61, 0x6a, 0x61, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x6a, 0x61, 0x3b, 0x6a, 0x75, 0x6c, 0x69, +0x6a, 0x61, 0x3b, 0x61, 0x77, 0x67, 0x75, 0x73, 0x74, 0x61, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x61, +0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x72, 0x61, 0x3b, 0x6e, 0x6f, 0x77, 0x65, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x64, 0x65, +0x63, 0x65, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x11b, 0x72, 0x3b, 0x61, +0x70, 0x72, 0x3b, 0x6d, 0x65, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x77, 0x67, 0x3b, 0x73, +0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x77, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, +0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x11b, 0x72, 0x63, 0x3b, 0x61, 0x70, 0x72, 0x79, 0x6c, +0x3b, 0x6d, 0x65, 0x6a, 0x61, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x6a, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x6a, 0x3b, 0x61, 0x77, +0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, +0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x77, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, +0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x11b, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, +0x3b, 0x6d, 0x65, 0x6a, 0x2e, 0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x77, 0x67, 0x2e, +0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x77, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, +0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x61, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x61, 0x3b, 0x6d, 0x11b, +0x72, 0x63, 0x61, 0x3b, 0x61, 0x70, 0x72, 0x79, 0x6c, 0x61, 0x3b, 0x6d, 0x65, 0x6a, 0x65, 0x3b, 0x6a, 0x75, 0x6e, 0x69, +0x6a, 0x61, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x6a, 0x61, 0x3b, 0x61, 0x77, 0x67, 0x75, 0x73, 0x74, 0x61, 0x3b, 0x73, 0x65, +0x70, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x72, 0x61, 0x3b, 0x6e, 0x6f, 0x77, 0x65, +0x6d, 0x62, 0x72, 0x61, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x72, 0x61, 0x67, 0x3b, 0x77, 0x61, +0x73, 0x3b, 0x70, 0x16b, 0x6c, 0x3b, 0x73, 0x61, 0x6b, 0x3b, 0x7a, 0x61, 0x6c, 0x3b, 0x73, 0x12b, 0x6d, 0x3b, 0x6c, 0x12b, +0x70, 0x3b, 0x64, 0x61, 0x67, 0x3b, 0x73, 0x69, 0x6c, 0x3b, 0x73, 0x70, 0x61, 0x3b, 0x6c, 0x61, 0x70, 0x3b, 0x73, 0x61, +0x6c, 0x3b, 0x72, 0x61, 0x67, 0x73, 0x3b, 0x77, 0x61, 0x73, 0x73, 0x61, 0x72, 0x69, 0x6e, 0x73, 0x3b, 0x70, 0x16b, 0x6c, +0x69, 0x73, 0x3b, 0x73, 0x61, 0x6b, 0x6b, 0x69, 0x73, 0x3b, 0x7a, 0x61, 0x6c, 0x6c, 0x61, 0x77, 0x73, 0x3b, 0x73, 0x12b, +0x6d, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x6c, 0x12b, 0x70, 0x61, 0x3b, 0x64, 0x61, 0x67, 0x67, 0x69, 0x73, 0x3b, 0x73, 0x69, +0x6c, 0x6c, 0x69, 0x6e, 0x73, 0x3b, 0x73, 0x70, 0x61, 0x6c, 0x6c, 0x69, 0x6e, 0x73, 0x3b, 0x6c, 0x61, 0x70, 0x6b, 0x72, +0x16b, 0x74, 0x69, 0x73, 0x3b, 0x73, 0x61, 0x6c, 0x6c, 0x61, 0x77, 0x73, 0x3b, 0x52, 0x3b, 0x57, 0x3b, 0x50, 0x3b, 0x53, +0x3b, 0x5a, 0x3b, 0x53, 0x3b, 0x4c, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x4c, 0x3b, 0x53, 0x3b, 0x75, 0x111, 0x69, +0x76, 0x3b, 0x6b, 0x75, 0x6f, 0x76, 0xe2, 0x3b, 0x6e, 0x6a, 0x75, 0x68, 0x10d, 0xe2, 0x3b, 0x63, 0x75, 0xe1, 0x14b, 0x75, +0x69, 0x3b, 0x76, 0x79, 0x65, 0x73, 0x69, 0x3b, 0x6b, 0x65, 0x73, 0x69, 0x3b, 0x73, 0x79, 0x65, 0x69, 0x6e, 0x69, 0x3b, +0x70, 0x6f, 0x72, 0x67, 0x65, 0x3b, 0x10d, 0x6f, 0x68, 0x10d, 0xe2, 0x3b, 0x72, 0x6f, 0x6f, 0x76, 0x76, 0xe2, 0x64, 0x3b, +0x73, 0x6b, 0x61, 0x6d, 0x6d, 0xe2, 0x3b, 0x6a, 0x75, 0x6f, 0x76, 0x6c, 0xe2, 0x3b, 0x75, 0x111, 0x111, 0xe2, 0x69, 0x76, +0x65, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x6b, 0x75, 0x6f, 0x76, 0xe2, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x6e, 0x6a, +0x75, 0x68, 0x10d, 0xe2, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x63, 0x75, 0xe1, 0x14b, 0x75, 0x69, 0x6d, 0xe1, 0xe1, 0x6e, +0x75, 0x3b, 0x76, 0x79, 0x65, 0x73, 0x69, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x6b, 0x65, 0x73, 0x69, 0x6d, 0xe1, 0xe1, +0x6e, 0x75, 0x3b, 0x73, 0x79, 0x65, 0x69, 0x6e, 0x69, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x70, 0x6f, 0x72, 0x67, 0x65, +0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x10d, 0x6f, 0x68, 0x10d, 0xe2, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x72, 0x6f, 0x6f, +0x76, 0x76, 0xe2, 0x64, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x73, 0x6b, 0x61, 0x6d, 0x6d, 0xe2, 0x6d, 0xe1, 0xe1, 0x6e, +0x75, 0x3b, 0x6a, 0x75, 0x6f, 0x76, 0x6c, 0xe2, 0x6d, 0xe1, 0xe1, 0x6e, 0x75, 0x3b, 0x55, 0x3b, 0x4b, 0x3b, 0x4e, 0x4a, +0x3b, 0x43, 0x3b, 0x56, 0x3b, 0x4b, 0x3b, 0x53, 0x3b, 0x50, 0x3b, 0x10c, 0x3b, 0x52, 0x3b, 0x53, 0x3b, 0x4a, 0x3b, 0x62c, +0x627, 0x646, 0x6a4, 0x6cc, 0x6d5, 0x3b, 0x641, 0x626, 0x6a4, 0x631, 0x6cc, 0x6d5, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x622, 0x6a4, +0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x626, 0x6cc, 0x3b, 0x62c, 0x648, 0x659, 0x623, 0x646, 0x3b, 0x62c, 0x648, 0x659, 0x644, 0x627, 0x3b, +0x622, 0x6af, 0x648, 0x633, 0x62a, 0x3b, 0x633, 0x626, 0x67e, 0x62a, 0x627, 0x645, 0x631, 0x3b, 0x626, 0x648, 0x6a9, 0x62a, 0x648, 0x6a4, +0x631, 0x3b, 0x646, 0x648, 0x6a4, 0x627, 0x645, 0x631, 0x3b, 0x62f, 0x626, 0x633, 0x627, 0x645, 0x631, 0x3b }; static const ushort days_data[] = { @@ -3934,480 +4000,494 @@ static const ushort days_data[] = { 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x4d, 0x61, 0x61, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x44, 0x69, 0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x57, 0x6f, 0x65, 0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x44, 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x64, 0x61, 0x67, 0x3b, 0x56, 0x72, 0x79, 0x64, 0x61, 0x67, 0x3b, 0x53, 0x61, 0x74, 0x65, 0x72, 0x64, 0x61, 0x67, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, -0x44, 0x3b, 0x57, 0x3b, 0x44, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x44, 0x69, 0x65, 0x3b, 0x48, 0xeb, 0x6e, 0x3b, 0x4d, 0x61, -0x72, 0x3b, 0x4d, 0xeb, 0x72, 0x3b, 0x45, 0x6e, 0x6a, 0x3b, 0x50, 0x72, 0x65, 0x3b, 0x53, 0x68, 0x74, 0x3b, 0x45, 0x20, -0x64, 0x69, 0x65, 0x6c, 0x3b, 0x45, 0x20, 0x68, 0xeb, 0x6e, 0xeb, 0x3b, 0x45, 0x20, 0x6d, 0x61, 0x72, 0x74, 0xeb, 0x3b, -0x45, 0x20, 0x6d, 0xeb, 0x72, 0x6b, 0x75, 0x72, 0xeb, 0x3b, 0x45, 0x20, 0x65, 0x6e, 0x6a, 0x74, 0x65, 0x3b, 0x45, 0x20, -0x70, 0x72, 0x65, 0x6d, 0x74, 0x65, 0x3b, 0x45, 0x20, 0x73, 0x68, 0x74, 0x75, 0x6e, 0xeb, 0x3b, 0x44, 0x3b, 0x48, 0x3b, -0x4d, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x50, 0x3b, 0x53, 0x68, 0x3b, 0x65, 0x20, 0x64, 0x69, 0x65, 0x6c, 0x3b, 0x65, 0x20, -0x68, 0xeb, 0x6e, 0xeb, 0x3b, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x74, 0xeb, 0x3b, 0x65, 0x20, 0x6d, 0xeb, 0x72, 0x6b, 0x75, -0x72, 0xeb, 0x3b, 0x65, 0x20, 0x65, 0x6e, 0x6a, 0x74, 0x65, 0x3b, 0x65, 0x20, 0x70, 0x72, 0x65, 0x6d, 0x74, 0x65, 0x3b, -0x65, 0x20, 0x73, 0x68, 0x74, 0x75, 0x6e, 0xeb, 0x3b, 0x12a5, 0x1211, 0x12f5, 0x3b, 0x1230, 0x129e, 0x3b, 0x121b, 0x12ad, 0x1230, 0x3b, -0x1228, 0x1261, 0x12d5, 0x3b, 0x1210, 0x1219, 0x1235, 0x3b, 0x12d3, 0x122d, 0x1265, 0x3b, 0x1245, 0x12f3, 0x121c, 0x3b, 0x12a5, 0x1211, 0x12f5, 0x3b, -0x1230, 0x129e, 0x3b, 0x121b, 0x12ad, 0x1230, 0x129e, 0x3b, 0x1228, 0x1261, 0x12d5, 0x3b, 0x1210, 0x1219, 0x1235, 0x3b, 0x12d3, 0x122d, 0x1265, 0x3b, -0x1245, 0x12f3, 0x121c, 0x3b, 0x12a5, 0x3b, 0x1230, 0x3b, 0x121b, 0x3b, 0x1228, 0x3b, 0x1210, 0x3b, 0x12d3, 0x3b, 0x1245, 0x3b, 0x627, 0x644, -0x623, 0x62d, 0x62f, 0x3b, 0x627, 0x644, 0x627, 0x62b, 0x646, 0x64a, 0x646, 0x3b, 0x627, 0x644, 0x62b, 0x644, 0x627, 0x62b, 0x627, 0x621, -0x3b, 0x627, 0x644, 0x623, 0x631, 0x628, 0x639, 0x627, 0x621, 0x3b, 0x627, 0x644, 0x62e, 0x645, 0x64a, 0x633, 0x3b, 0x627, 0x644, 0x62c, -0x645, 0x639, 0x629, 0x3b, 0x627, 0x644, 0x633, 0x628, 0x62a, 0x3b, 0x62d, 0x3b, 0x646, 0x3b, 0x62b, 0x3b, 0x631, 0x3b, 0x62e, 0x3b, -0x62c, 0x3b, 0x633, 0x3b, 0x56f, 0x56b, 0x580, 0x3b, 0x565, 0x580, 0x56f, 0x3b, 0x565, 0x580, 0x584, 0x3b, 0x579, 0x580, 0x584, 0x3b, -0x570, 0x576, 0x563, 0x3b, 0x578, 0x582, 0x580, 0x3b, 0x577, 0x562, 0x569, 0x3b, 0x56f, 0x56b, 0x580, 0x561, 0x56f, 0x56b, 0x3b, 0x565, -0x580, 0x56f, 0x578, 0x582, 0x577, 0x561, 0x562, 0x569, 0x56b, 0x3b, 0x565, 0x580, 0x565, 0x584, 0x577, 0x561, 0x562, 0x569, 0x56b, 0x3b, -0x579, 0x578, 0x580, 0x565, 0x584, 0x577, 0x561, 0x562, 0x569, 0x56b, 0x3b, 0x570, 0x56b, 0x576, 0x563, 0x577, 0x561, 0x562, 0x569, 0x56b, -0x3b, 0x578, 0x582, 0x580, 0x562, 0x561, 0x569, 0x3b, 0x577, 0x561, 0x562, 0x561, 0x569, 0x3b, 0x53f, 0x3b, 0x535, 0x3b, 0x535, 0x3b, -0x549, 0x3b, 0x540, 0x3b, 0x548, 0x3b, 0x547, 0x3b, 0x9a6, 0x9c7, 0x993, 0x3b, 0x9b8, 0x9cb, 0x9ae, 0x3b, 0x9ae, 0x999, 0x9cd, 0x997, -0x9b2, 0x3b, 0x9ac, 0x9c1, 0x9a7, 0x3b, 0x9ac, 0x9c3, 0x9b9, 0x3b, 0x9b6, 0x9c1, 0x995, 0x9cd, 0x9f0, 0x3b, 0x9b6, 0x9a8, 0x9bf, 0x3b, -0x9a6, 0x9c7, 0x993, 0x9ac, 0x9be, 0x9f0, 0x3b, 0x9b8, 0x9cb, 0x9ae, 0x9ac, 0x9be, 0x9f0, 0x3b, 0x9ae, 0x999, 0x9cd, 0x997, 0x9b2, 0x9ac, -0x9be, 0x9f0, 0x3b, 0x9ac, 0x9c1, 0x9a7, 0x9ac, 0x9be, 0x9f0, 0x3b, 0x9ac, 0x9c3, 0x9b9, 0x9b8, 0x9cd, 0x9aa, 0x9a4, 0x9bf, 0x9ac, 0x9be, -0x9f0, 0x3b, 0x9b6, 0x9c1, 0x995, 0x9cd, 0x9f0, 0x9ac, 0x9be, 0x9f0, 0x3b, 0x9b6, 0x9a8, 0x9bf, 0x9ac, 0x9be, 0x9f0, 0x3b, 0x9a6, 0x3b, -0x9b8, 0x3b, 0x9ae, 0x3b, 0x9ac, 0x3b, 0x9ac, 0x3b, 0x9b6, 0x3b, 0x9b6, 0x3b, 0x42, 0x2e, 0x3b, 0x42, 0x2e, 0x45, 0x2e, 0x3b, -0xc7, 0x2e, 0x41, 0x2e, 0x3b, 0xc7, 0x2e, 0x3b, 0x43, 0x2e, 0x41, 0x2e, 0x3b, 0x43, 0x2e, 0x3b, 0x15e, 0x2e, 0x3b, 0x62, -0x61, 0x7a, 0x61, 0x72, 0x3b, 0x62, 0x61, 0x7a, 0x61, 0x72, 0x20, 0x65, 0x72, 0x74, 0x259, 0x73, 0x69, 0x3b, 0xe7, 0x259, -0x72, 0x15f, 0x259, 0x6e, 0x62, 0x259, 0x20, 0x61, 0x78, 0x15f, 0x61, 0x6d, 0x131, 0x3b, 0xe7, 0x259, 0x72, 0x15f, 0x259, 0x6e, -0x62, 0x259, 0x3b, 0x63, 0xfc, 0x6d, 0x259, 0x20, 0x61, 0x78, 0x15f, 0x61, 0x6d, 0x131, 0x3b, 0x63, 0xfc, 0x6d, 0x259, 0x3b, -0x15f, 0x259, 0x6e, 0x62, 0x259, 0x3b, 0x411, 0x2e, 0x3b, 0x411, 0x2e, 0x415, 0x2e, 0x3b, 0x427, 0x2e, 0x410, 0x2e, 0x3b, 0x427, -0x2e, 0x3b, 0x4b8, 0x2e, 0x410, 0x2e, 0x3b, 0x4b8, 0x2e, 0x3b, 0x428, 0x2e, 0x3b, 0x431, 0x430, 0x437, 0x430, 0x440, 0x3b, 0x431, -0x430, 0x437, 0x430, 0x440, 0x20, 0x435, 0x440, 0x442, 0x4d9, 0x441, 0x438, 0x3b, 0x447, 0x4d9, 0x440, 0x448, 0x4d9, 0x43d, 0x431, 0x4d9, -0x20, 0x430, 0x445, 0x448, 0x430, 0x43c, 0x44b, 0x3b, 0x447, 0x4d9, 0x440, 0x448, 0x4d9, 0x43d, 0x431, 0x4d9, 0x3b, 0x4b9, 0x4af, 0x43c, -0x4d9, 0x20, 0x430, 0x445, 0x448, 0x430, 0x43c, 0x44b, 0x3b, 0x4b9, 0x4af, 0x43c, 0x4d9, 0x3b, 0x448, 0x4d9, 0x43d, 0x431, 0x4d9, 0x3b, -0x69, 0x67, 0x2e, 0x3b, 0x61, 0x6c, 0x2e, 0x3b, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x7a, 0x2e, 0x3b, 0x6f, 0x67, 0x2e, 0x3b, -0x6f, 0x72, 0x2e, 0x3b, 0x6c, 0x72, 0x2e, 0x3b, 0x49, 0x67, 0x61, 0x6e, 0x64, 0x65, 0x61, 0x3b, 0x41, 0x73, 0x74, 0x65, -0x6c, 0x65, 0x68, 0x65, 0x6e, 0x61, 0x3b, 0x41, 0x73, 0x74, 0x65, 0x61, 0x72, 0x74, 0x65, 0x61, 0x3b, 0x41, 0x73, 0x74, -0x65, 0x61, 0x7a, 0x6b, 0x65, 0x6e, 0x61, 0x3b, 0x4f, 0x73, 0x74, 0x65, 0x67, 0x75, 0x6e, 0x61, 0x3b, 0x4f, 0x73, 0x74, -0x69, 0x72, 0x61, 0x6c, 0x61, 0x3b, 0x4c, 0x61, 0x72, 0x75, 0x6e, 0x62, 0x61, 0x74, 0x61, 0x3b, 0x49, 0x3b, 0x41, 0x3b, -0x41, 0x3b, 0x41, 0x3b, 0x4f, 0x3b, 0x4f, 0x3b, 0x4c, 0x3b, 0x69, 0x67, 0x61, 0x6e, 0x64, 0x65, 0x61, 0x3b, 0x61, 0x73, -0x74, 0x65, 0x6c, 0x65, 0x68, 0x65, 0x6e, 0x61, 0x3b, 0x61, 0x73, 0x74, 0x65, 0x61, 0x72, 0x74, 0x65, 0x61, 0x3b, 0x61, -0x73, 0x74, 0x65, 0x61, 0x7a, 0x6b, 0x65, 0x6e, 0x61, 0x3b, 0x6f, 0x73, 0x74, 0x65, 0x67, 0x75, 0x6e, 0x61, 0x3b, 0x6f, -0x73, 0x74, 0x69, 0x72, 0x61, 0x6c, 0x61, 0x3b, 0x6c, 0x61, 0x72, 0x75, 0x6e, 0x62, 0x61, 0x74, 0x61, 0x3b, 0x9b0, 0x9ac, -0x9bf, 0x3b, 0x9b8, 0x9cb, 0x9ae, 0x3b, 0x9ae, 0x999, 0x9cd, 0x997, 0x9b2, 0x3b, 0x9ac, 0x9c1, 0x9a7, 0x3b, 0x9ac, 0x9c3, 0x9b9, 0x9b8, -0x9cd, 0x9aa, 0x9a4, 0x9bf, 0x3b, 0x9b6, 0x9c1, 0x995, 0x9cd, 0x9b0, 0x3b, 0x9b6, 0x9a8, 0x9bf, 0x3b, 0x9b0, 0x9ac, 0x9bf, 0x9ac, 0x9be, -0x9b0, 0x3b, 0x9b8, 0x9cb, 0x9ae, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9ae, 0x999, 0x9cd, 0x997, 0x9b2, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9ac, 0x9c1, -0x9a7, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9ac, 0x9c3, 0x9b9, 0x9b7, 0x9cd, 0x9aa, 0x9a4, 0x9bf, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b6, 0x9c1, 0x995, -0x9cd, 0x9b0, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b6, 0x9a8, 0x9bf, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b0, 0x3b, 0x9b8, 0x9cb, 0x3b, 0x9ae, 0x3b, -0x9ac, 0x9c1, 0x3b, 0x9ac, 0x9c3, 0x3b, 0x9b6, 0x9c1, 0x3b, 0x9b6, 0x3b, 0x9b0, 0x9ac, 0x9bf, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b8, 0x9cb, -0x9ae, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9ae, 0x999, 0x9cd, 0x997, 0x9b2, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9ac, 0x9c1, 0x9a7, 0x9ac, 0x9be, 0x9b0, -0x3b, 0x9ac, 0x9c3, 0x9b9, 0x9b8, 0x9cd, 0x9aa, 0x9a4, 0x9bf, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b6, 0x9c1, 0x995, 0x9cd, 0x9b0, 0x9ac, 0x9be, -0x9b0, 0x3b, 0x9b6, 0x9a8, 0x9bf, 0x9ac, 0x9be, 0x9b0, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0x3b, 0xf58, 0xf72, 0xf62, 0xf0b, 0x3b, 0xf63, 0xfb7, -0xf42, 0xf0b, 0x3b, 0xf55, 0xf74, 0xf62, 0xf0b, 0x3b, 0xf66, 0xf44, 0xf66, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xf7a, 0xf53, 0xf0b, 0x3b, 0xf49, -0xf72, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf58, 0xf72, 0xf42, -0xf0b, 0xf51, 0xf58, 0xf62, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf63, 0xfb7, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, -0xf0b, 0xf55, 0xf74, 0xf62, 0xf0b, 0xf56, 0xf74, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf54, 0xf0b, 0xf66, 0xf44, 0xf66, 0xf0b, 0x3b, -0xf42, 0xf5f, 0xf60, 0xf0b, 0xf66, 0xfa4, 0xf7a, 0xf53, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf49, 0xf72, 0xf0b, 0xf58, -0xf0b, 0x3b, 0xf5f, 0xfb3, 0x3b, 0xf58, 0xf72, 0xf62, 0x3b, 0xf63, 0xfb7, 0xf42, 0x3b, 0xf55, 0xf74, 0xf62, 0x3b, 0xf66, 0xf44, 0xfb6, -0x3b, 0xf66, 0xfa4, 0xf7a, 0xf53, 0x3b, 0xf49, 0xf72, 0x3b, 0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4d, 0x65, 0x75, -0x2e, 0x3b, 0x4d, 0x65, 0x72, 0x2e, 0x3b, 0x59, 0x61, 0x6f, 0x75, 0x3b, 0x47, 0x77, 0x65, 0x2e, 0x3b, 0x53, 0x61, 0x64, -0x2e, 0x3b, 0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4d, 0x65, 0x75, 0x72, 0x7a, 0x68, 0x3b, 0x4d, 0x65, 0x72, -0x63, 0x2bc, 0x68, 0x65, 0x72, 0x3b, 0x59, 0x61, 0x6f, 0x75, 0x3b, 0x47, 0x77, 0x65, 0x6e, 0x65, 0x72, 0x3b, 0x53, 0x61, -0x64, 0x6f, 0x72, 0x6e, 0x3b, 0x53, 0x75, 0x3b, 0x4c, 0x3b, 0x4d, 0x7a, 0x3b, 0x4d, 0x63, 0x3b, 0x59, 0x3b, 0x47, 0x3b, -0x53, 0x61, 0x3b, 0x43d, 0x434, 0x3b, 0x43f, 0x43d, 0x3b, 0x432, 0x442, 0x3b, 0x441, 0x440, 0x3b, 0x447, 0x442, 0x3b, 0x43f, 0x442, -0x3b, 0x441, 0x431, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x43b, 0x44f, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x43b, 0x43d, 0x438, -0x43a, 0x3b, 0x432, 0x442, 0x43e, 0x440, 0x43d, 0x438, 0x43a, 0x3b, 0x441, 0x440, 0x44f, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, -0x44a, 0x440, 0x442, 0x44a, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x44a, 0x43a, 0x3b, 0x441, 0x44a, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x43d, -0x3b, 0x43f, 0x3b, 0x432, 0x3b, 0x441, 0x3b, 0x447, 0x3b, 0x43f, 0x3b, 0x441, 0x3b, 0x1010, 0x1014, 0x1004, 0x103a, 0x1039, 0x1002, 0x1014, -0x103d, 0x1031, 0x3b, 0x1010, 0x1014, 0x1004, 0x103a, 0x1039, 0x101c, 0x102c, 0x3b, 0x1021, 0x1004, 0x103a, 0x1039, 0x1002, 0x102b, 0x3b, 0x1017, 0x102f, -0x1012, 0x1039, 0x1013, 0x101f, 0x1030, 0x1038, 0x3b, 0x1000, 0x103c, 0x102c, 0x101e, 0x1015, 0x1010, 0x1031, 0x1038, 0x3b, 0x101e, 0x1031, 0x102c, 0x1000, -0x103c, 0x102c, 0x3b, 0x1005, 0x1014, 0x1031, 0x3b, 0x1010, 0x3b, 0x1010, 0x3b, 0x1021, 0x3b, 0x1017, 0x3b, 0x1000, 0x3b, 0x101e, 0x3b, 0x1005, -0x3b, 0x43d, 0x434, 0x3b, 0x43f, 0x43d, 0x3b, 0x430, 0x45e, 0x3b, 0x441, 0x440, 0x3b, 0x447, 0x446, 0x3b, 0x43f, 0x442, 0x3b, 0x441, -0x431, 0x3b, 0x43d, 0x44f, 0x434, 0x437, 0x435, 0x43b, 0x44f, 0x3b, 0x43f, 0x430, 0x43d, 0x44f, 0x434, 0x437, 0x435, 0x43b, 0x430, 0x43a, -0x3b, 0x430, 0x45e, 0x442, 0x43e, 0x440, 0x430, 0x43a, 0x3b, 0x441, 0x435, 0x440, 0x430, 0x434, 0x430, 0x3b, 0x447, 0x430, 0x446, 0x432, -0x435, 0x440, 0x3b, 0x43f, 0x44f, 0x442, 0x43d, 0x456, 0x446, 0x430, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x43d, 0x3b, -0x43f, 0x3b, 0x430, 0x3b, 0x441, 0x3b, 0x447, 0x3b, 0x43f, 0x3b, 0x441, 0x3b, 0x17a2, 0x17b6, 0x1791, 0x17b7, 0x178f, 0x17d2, 0x1799, 0x3b, -0x1785, 0x17d0, 0x1793, 0x17d2, 0x1791, 0x3b, 0x17a2, 0x1784, 0x17d2, 0x1782, 0x17b6, 0x179a, 0x3b, 0x1796, 0x17bb, 0x1792, 0x3b, 0x1796, 0x17d2, 0x179a, -0x17a0, 0x179f, 0x17d2, 0x1794, 0x178f, 0x17b7, 0x17cd, 0x3b, 0x179f, 0x17bb, 0x1780, 0x17d2, 0x179a, 0x3b, 0x179f, 0x17c5, 0x179a, 0x17cd, 0x3b, 0x17a2, -0x3b, 0x1785, 0x3b, 0x17a2, 0x3b, 0x1796, 0x3b, 0x1796, 0x3b, 0x179f, 0x3b, 0x179f, 0x3b, 0x64, 0x67, 0x2e, 0x3b, 0x64, 0x6c, 0x2e, -0x3b, 0x64, 0x74, 0x2e, 0x3b, 0x64, 0x63, 0x2e, 0x3b, 0x64, 0x6a, 0x2e, 0x3b, 0x64, 0x76, 0x2e, 0x3b, 0x64, 0x73, 0x2e, -0x3b, 0x64, 0x69, 0x75, 0x6d, 0x65, 0x6e, 0x67, 0x65, 0x3b, 0x64, 0x69, 0x6c, 0x6c, 0x75, 0x6e, 0x73, 0x3b, 0x64, 0x69, -0x6d, 0x61, 0x72, 0x74, 0x73, 0x3b, 0x64, 0x69, 0x6d, 0x65, 0x63, 0x72, 0x65, 0x73, 0x3b, 0x64, 0x69, 0x6a, 0x6f, 0x75, -0x73, 0x3b, 0x64, 0x69, 0x76, 0x65, 0x6e, 0x64, 0x72, 0x65, 0x73, 0x3b, 0x64, 0x69, 0x73, 0x73, 0x61, 0x62, 0x74, 0x65, -0x3b, 0x64, 0x67, 0x3b, 0x64, 0x6c, 0x3b, 0x64, 0x74, 0x3b, 0x64, 0x63, 0x3b, 0x64, 0x6a, 0x3b, 0x64, 0x76, 0x3b, 0x64, -0x73, 0x3b, 0x5468, 0x65e5, 0x3b, 0x5468, 0x4e00, 0x3b, 0x5468, 0x4e8c, 0x3b, 0x5468, 0x4e09, 0x3b, 0x5468, 0x56db, 0x3b, 0x5468, 0x4e94, 0x3b, -0x5468, 0x516d, 0x3b, 0x661f, 0x671f, 0x65e5, 0x3b, 0x661f, 0x671f, 0x4e00, 0x3b, 0x661f, 0x671f, 0x4e8c, 0x3b, 0x661f, 0x671f, 0x4e09, 0x3b, 0x661f, -0x671f, 0x56db, 0x3b, 0x661f, 0x671f, 0x4e94, 0x3b, 0x661f, 0x671f, 0x516d, 0x3b, 0x65e5, 0x3b, 0x4e00, 0x3b, 0x4e8c, 0x3b, 0x4e09, 0x3b, 0x56db, -0x3b, 0x4e94, 0x3b, 0x516d, 0x3b, 0x9031, 0x65e5, 0x3b, 0x9031, 0x4e00, 0x3b, 0x9031, 0x4e8c, 0x3b, 0x9031, 0x4e09, 0x3b, 0x9031, 0x56db, 0x3b, -0x9031, 0x4e94, 0x3b, 0x9031, 0x516d, 0x3b, 0x6e, 0x65, 0x64, 0x3b, 0x70, 0x6f, 0x6e, 0x3b, 0x75, 0x74, 0x6f, 0x3b, 0x73, 0x72, -0x69, 0x3b, 0x10d, 0x65, 0x74, 0x3b, 0x70, 0x65, 0x74, 0x3b, 0x73, 0x75, 0x62, 0x3b, 0x6e, 0x65, 0x64, 0x6a, 0x65, 0x6c, -0x6a, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x65, 0x64, 0x6a, 0x65, 0x6c, 0x6a, 0x61, 0x6b, 0x3b, 0x75, 0x74, 0x6f, 0x72, 0x61, -0x6b, 0x3b, 0x73, 0x72, 0x69, 0x6a, 0x65, 0x64, 0x61, 0x3b, 0x10d, 0x65, 0x74, 0x76, 0x72, 0x74, 0x61, 0x6b, 0x3b, 0x70, -0x65, 0x74, 0x61, 0x6b, 0x3b, 0x73, 0x75, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x6e, 0x3b, 0x70, 0x3b, 0x75, 0x3b, 0x73, 0x3b, -0x10d, 0x3b, 0x70, 0x3b, 0x73, 0x3b, 0x4e, 0x3b, 0x50, 0x3b, 0x55, 0x3b, 0x53, 0x3b, 0x10c, 0x3b, 0x50, 0x3b, 0x53, 0x3b, -0x6e, 0x65, 0x3b, 0x70, 0x6f, 0x3b, 0xfa, 0x74, 0x3b, 0x73, 0x74, 0x3b, 0x10d, 0x74, 0x3b, 0x70, 0xe1, 0x3b, 0x73, 0x6f, -0x3b, 0x6e, 0x65, 0x64, 0x11b, 0x6c, 0x65, 0x3b, 0x70, 0x6f, 0x6e, 0x64, 0x11b, 0x6c, 0xed, 0x3b, 0xfa, 0x74, 0x65, 0x72, -0xfd, 0x3b, 0x73, 0x74, 0x159, 0x65, 0x64, 0x61, 0x3b, 0x10d, 0x74, 0x76, 0x72, 0x74, 0x65, 0x6b, 0x3b, 0x70, 0xe1, 0x74, -0x65, 0x6b, 0x3b, 0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x4e, 0x3b, 0x50, 0x3b, 0xda, 0x3b, 0x53, 0x3b, 0x10c, 0x3b, -0x50, 0x3b, 0x53, 0x3b, 0x73, 0xf8, 0x6e, 0x3b, 0x6d, 0x61, 0x6e, 0x3b, 0x74, 0x69, 0x72, 0x3b, 0x6f, 0x6e, 0x73, 0x3b, -0x74, 0x6f, 0x72, 0x3b, 0x66, 0x72, 0x65, 0x3b, 0x6c, 0xf8, 0x72, 0x3b, 0x73, 0xf8, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x6d, -0x61, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x69, 0x72, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x6f, 0x6e, 0x73, 0x64, 0x61, 0x67, -0x3b, 0x74, 0x6f, 0x72, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x66, 0x72, 0x65, 0x64, 0x61, 0x67, 0x3b, 0x6c, 0xf8, 0x72, 0x64, -0x61, 0x67, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x54, 0x3b, 0x4f, 0x3b, 0x54, 0x3b, 0x46, 0x3b, 0x4c, 0x3b, 0x73, 0xf8, 0x6e, -0x2e, 0x3b, 0x6d, 0x61, 0x6e, 0x2e, 0x3b, 0x74, 0x69, 0x72, 0x2e, 0x3b, 0x6f, 0x6e, 0x73, 0x2e, 0x3b, 0x74, 0x6f, 0x72, -0x2e, 0x3b, 0x66, 0x72, 0x65, 0x2e, 0x3b, 0x6c, 0xf8, 0x72, 0x2e, 0x3b, 0x7a, 0x6f, 0x3b, 0x6d, 0x61, 0x3b, 0x64, 0x69, -0x3b, 0x77, 0x6f, 0x3b, 0x64, 0x6f, 0x3b, 0x76, 0x72, 0x3b, 0x7a, 0x61, 0x3b, 0x7a, 0x6f, 0x6e, 0x64, 0x61, 0x67, 0x3b, -0x6d, 0x61, 0x61, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x64, 0x69, 0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x77, 0x6f, 0x65, 0x6e, -0x73, 0x64, 0x61, 0x67, 0x3b, 0x64, 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x64, 0x61, 0x67, 0x3b, 0x76, 0x72, 0x69, 0x6a, 0x64, -0x61, 0x67, 0x3b, 0x7a, 0x61, 0x74, 0x65, 0x72, 0x64, 0x61, 0x67, 0x3b, 0x5a, 0x3b, 0x4d, 0x3b, 0x44, 0x3b, 0x57, 0x3b, -0x44, 0x3b, 0x56, 0x3b, 0x5a, 0x3b, 0x53, 0x75, 0x6e, 0x2e, 0x3b, 0x4d, 0x6f, 0x6e, 0x2e, 0x3b, 0x54, 0x75, 0x65, 0x2e, -0x3b, 0x57, 0x65, 0x64, 0x2e, 0x3b, 0x54, 0x68, 0x75, 0x2e, 0x3b, 0x46, 0x72, 0x69, 0x2e, 0x3b, 0x53, 0x61, 0x74, 0x2e, -0x3b, 0x53, 0x75, 0x2e, 0x3b, 0x4d, 0x2e, 0x3b, 0x54, 0x75, 0x2e, 0x3b, 0x57, 0x2e, 0x3b, 0x54, 0x68, 0x2e, 0x3b, 0x46, -0x2e, 0x3b, 0x53, 0x61, 0x2e, 0x3b, 0x64, 0x69, 0x3b, 0x6c, 0x75, 0x3b, 0x6d, 0x61, 0x3b, 0x6d, 0x65, 0x3b, 0x135, 0x61, -0x3b, 0x76, 0x65, 0x3b, 0x73, 0x61, 0x3b, 0x64, 0x69, 0x6d, 0x61, 0x6e, 0x109, 0x6f, 0x3b, 0x6c, 0x75, 0x6e, 0x64, 0x6f, -0x3b, 0x6d, 0x61, 0x72, 0x64, 0x6f, 0x3b, 0x6d, 0x65, 0x72, 0x6b, 0x72, 0x65, 0x64, 0x6f, 0x3b, 0x135, 0x61, 0x16d, 0x64, -0x6f, 0x3b, 0x76, 0x65, 0x6e, 0x64, 0x72, 0x65, 0x64, 0x6f, 0x3b, 0x73, 0x61, 0x62, 0x61, 0x74, 0x6f, 0x3b, 0x44, 0x3b, -0x4c, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x134, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x50, 0x3b, 0x45, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, -0x4e, 0x3b, 0x52, 0x3b, 0x4c, 0x3b, 0x70, 0xfc, 0x68, 0x61, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x65, 0x73, 0x6d, 0x61, 0x73, -0x70, 0xe4, 0x65, 0x76, 0x3b, 0x74, 0x65, 0x69, 0x73, 0x69, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x6b, 0x6f, 0x6c, 0x6d, 0x61, -0x70, 0xe4, 0x65, 0x76, 0x3b, 0x6e, 0x65, 0x6c, 0x6a, 0x61, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x72, 0x65, 0x65, 0x64, 0x65, -0x3b, 0x6c, 0x61, 0x75, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x73, 0x75, 0x6e, 0x3b, 0x6d, 0xe1, 0x6e, 0x3b, 0x74, 0xfd, 0x73, -0x3b, 0x6d, 0x69, 0x6b, 0x3b, 0x68, 0xf3, 0x73, 0x3b, 0x66, 0x72, 0xed, 0x3b, 0x6c, 0x65, 0x79, 0x3b, 0x73, 0x75, 0x6e, -0x6e, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6d, 0xe1, 0x6e, 0x61, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x74, 0xfd, -0x73, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6d, 0x69, 0x6b, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x68, 0xf3, 0x73, -0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x66, 0x72, 0xed, 0x67, 0x67, 0x6a, 0x61, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6c, -0x65, 0x79, 0x67, 0x61, 0x72, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x54, 0x3b, 0x4d, 0x3b, 0x48, -0x3b, 0x46, 0x3b, 0x4c, 0x3b, 0x73, 0x75, 0x6e, 0x2e, 0x3b, 0x6d, 0xe1, 0x6e, 0x2e, 0x3b, 0x74, 0xfd, 0x73, 0x2e, 0x3b, -0x6d, 0x69, 0x6b, 0x2e, 0x3b, 0x68, 0xf3, 0x73, 0x2e, 0x3b, 0x66, 0x72, 0xed, 0x2e, 0x3b, 0x6c, 0x65, 0x79, 0x2e, 0x3b, -0x73, 0x75, 0x3b, 0x6d, 0x61, 0x3b, 0x74, 0x69, 0x3b, 0x6b, 0x65, 0x3b, 0x74, 0x6f, 0x3b, 0x70, 0x65, 0x3b, 0x6c, 0x61, -0x3b, 0x73, 0x75, 0x6e, 0x6e, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x3b, 0x6d, 0x61, 0x61, 0x6e, 0x61, 0x6e, 0x74, 0x61, 0x69, -0x3b, 0x74, 0x69, 0x69, 0x73, 0x74, 0x61, 0x69, 0x3b, 0x6b, 0x65, 0x73, 0x6b, 0x69, 0x76, 0x69, 0x69, 0x6b, 0x6b, 0x6f, -0x3b, 0x74, 0x6f, 0x72, 0x73, 0x74, 0x61, 0x69, 0x3b, 0x70, 0x65, 0x72, 0x6a, 0x61, 0x6e, 0x74, 0x61, 0x69, 0x3b, 0x6c, -0x61, 0x75, 0x61, 0x6e, 0x74, 0x61, 0x69, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x54, 0x3b, 0x50, 0x3b, -0x4c, 0x3b, 0x73, 0x75, 0x6e, 0x6e, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x6d, 0x61, 0x61, 0x6e, 0x61, 0x6e, -0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x74, 0x69, 0x69, 0x73, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x6b, 0x65, 0x73, 0x6b, -0x69, 0x76, 0x69, 0x69, 0x6b, 0x6b, 0x6f, 0x6e, 0x61, 0x3b, 0x74, 0x6f, 0x72, 0x73, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, -0x70, 0x65, 0x72, 0x6a, 0x61, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x6c, 0x61, 0x75, 0x61, 0x6e, 0x74, 0x61, 0x69, -0x6e, 0x61, 0x3b, 0x64, 0x69, 0x6d, 0x2e, 0x3b, 0x6c, 0x75, 0x6e, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x6d, 0x65, -0x72, 0x2e, 0x3b, 0x6a, 0x65, 0x75, 0x2e, 0x3b, 0x76, 0x65, 0x6e, 0x2e, 0x3b, 0x73, 0x61, 0x6d, 0x2e, 0x3b, 0x64, 0x69, -0x6d, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x3b, 0x6c, 0x75, 0x6e, 0x64, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x64, 0x69, 0x3b, 0x6d, -0x65, 0x72, 0x63, 0x72, 0x65, 0x64, 0x69, 0x3b, 0x6a, 0x65, 0x75, 0x64, 0x69, 0x3b, 0x76, 0x65, 0x6e, 0x64, 0x72, 0x65, -0x64, 0x69, 0x3b, 0x73, 0x61, 0x6d, 0x65, 0x64, 0x69, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, -0x56, 0x3b, 0x53, 0x3b, 0x73, 0x69, 0x3b, 0x6d, 0x6f, 0x3b, 0x74, 0x69, 0x3b, 0x77, 0x6f, 0x3b, 0x74, 0x6f, 0x3b, 0x66, -0x72, 0x3b, 0x73, 0x6f, 0x3b, 0x73, 0x6e, 0x65, 0x69, 0x6e, 0x3b, 0x6d, 0x6f, 0x61, 0x6e, 0x64, 0x65, 0x69, 0x3b, 0x74, -0x69, 0x69, 0x73, 0x64, 0x65, 0x69, 0x3b, 0x77, 0x6f, 0x61, 0x6e, 0x73, 0x64, 0x65, 0x69, 0x3b, 0x74, 0x6f, 0x6e, 0x67, -0x65, 0x72, 0x73, 0x64, 0x65, 0x69, 0x3b, 0x66, 0x72, 0x65, 0x65, 0x64, 0x3b, 0x73, 0x6e, 0x65, 0x6f, 0x6e, 0x3b, 0x44, -0x69, 0x44, 0x3b, 0x44, 0x69, 0x4c, 0x3b, 0x44, 0x69, 0x4d, 0x3b, 0x44, 0x69, 0x43, 0x3b, 0x44, 0x69, 0x61, 0x3b, 0x44, -0x69, 0x68, 0x3b, 0x44, 0x69, 0x53, 0x3b, 0x44, 0x69, 0x44, 0xf2, 0x6d, 0x68, 0x6e, 0x61, 0x69, 0x63, 0x68, 0x3b, 0x44, -0x69, 0x4c, 0x75, 0x61, 0x69, 0x6e, 0x3b, 0x44, 0x69, 0x4d, 0xe0, 0x69, 0x72, 0x74, 0x3b, 0x44, 0x69, 0x43, 0x69, 0x61, -0x64, 0x61, 0x69, 0x6e, 0x3b, 0x44, 0x69, 0x61, 0x72, 0x44, 0x61, 0x6f, 0x69, 0x6e, 0x3b, 0x44, 0x69, 0x68, 0x41, 0x6f, -0x69, 0x6e, 0x65, 0x3b, 0x44, 0x69, 0x53, 0x61, 0x74, 0x68, 0x61, 0x69, 0x72, 0x6e, 0x65, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, -0x4d, 0x3b, 0x43, 0x3b, 0x41, 0x3b, 0x48, 0x3b, 0x53, 0x3b, 0x44, 0x6f, 0x6d, 0x2e, 0x3b, 0x4c, 0x75, 0x6e, 0x73, 0x3b, -0x4d, 0x61, 0x72, 0x2e, 0x3b, 0x4d, 0xe9, 0x72, 0x2e, 0x3b, 0x58, 0x6f, 0x76, 0x2e, 0x3b, 0x56, 0x65, 0x6e, 0x2e, 0x3b, -0x53, 0xe1, 0x62, 0x2e, 0x3b, 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x4c, 0x75, 0x6e, 0x73, 0x3b, 0x4d, 0x61, -0x72, 0x74, 0x65, 0x73, 0x3b, 0x4d, 0xe9, 0x72, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x3b, 0x58, 0x6f, 0x76, 0x65, 0x73, 0x3b, -0x56, 0x65, 0x6e, 0x72, 0x65, 0x73, 0x3b, 0x53, 0xe1, 0x62, 0x61, 0x64, 0x6f, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, -0x4d, 0x3b, 0x58, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x64, 0x6f, 0x6d, 0x2e, 0x3b, 0x6c, 0x75, 0x6e, 0x73, 0x3b, 0x6d, 0x61, -0x72, 0x2e, 0x3b, 0x6d, 0xe9, 0x72, 0x2e, 0x3b, 0x78, 0x6f, 0x76, 0x2e, 0x3b, 0x76, 0x65, 0x6e, 0x2e, 0x3b, 0x73, 0xe1, -0x62, 0x2e, 0x3b, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x6c, 0x75, 0x6e, 0x73, 0x3b, 0x6d, 0x61, 0x72, 0x74, -0x65, 0x73, 0x3b, 0x6d, 0xe9, 0x72, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x3b, 0x78, 0x6f, 0x76, 0x65, 0x73, 0x3b, 0x76, 0x65, -0x6e, 0x72, 0x65, 0x73, 0x3b, 0x73, 0xe1, 0x62, 0x61, 0x64, 0x6f, 0x3b, 0x64, 0x2e, 0x3b, 0x6c, 0x2e, 0x3b, 0x6d, 0x2e, -0x3b, 0x6d, 0x2e, 0x3b, 0x78, 0x2e, 0x3b, 0x76, 0x2e, 0x3b, 0x73, 0x2e, 0x3b, 0x10d9, 0x10d5, 0x10d8, 0x3b, 0x10dd, 0x10e0, 0x10e8, -0x3b, 0x10e1, 0x10d0, 0x10db, 0x3b, 0x10dd, 0x10d7, 0x10ee, 0x3b, 0x10ee, 0x10e3, 0x10d7, 0x3b, 0x10de, 0x10d0, 0x10e0, 0x3b, 0x10e8, 0x10d0, 0x10d1, -0x3b, 0x10d9, 0x10d5, 0x10d8, 0x10e0, 0x10d0, 0x3b, 0x10dd, 0x10e0, 0x10e8, 0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10e1, 0x10d0, 0x10db, 0x10e8, -0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10dd, 0x10d7, 0x10ee, 0x10e8, 0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10ee, 0x10e3, 0x10d7, 0x10e8, -0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10de, 0x10d0, 0x10e0, 0x10d0, 0x10e1, 0x10d9, 0x10d4, 0x10d5, 0x10d8, 0x3b, 0x10e8, 0x10d0, 0x10d1, 0x10d0, -0x10d7, 0x10d8, 0x3b, 0x10d9, 0x3b, 0x10dd, 0x3b, 0x10e1, 0x3b, 0x10dd, 0x3b, 0x10ee, 0x3b, 0x10de, 0x3b, 0x10e8, 0x3b, 0x53, 0x6f, 0x3b, -0x4d, 0x6f, 0x3b, 0x44, 0x69, 0x3b, 0x4d, 0x69, 0x3b, 0x44, 0x6f, 0x3b, 0x46, 0x72, 0x3b, 0x53, 0x61, 0x3b, 0x53, 0x6f, -0x6e, 0x6e, 0x74, 0x61, 0x67, 0x3b, 0x4d, 0x6f, 0x6e, 0x74, 0x61, 0x67, 0x3b, 0x44, 0x69, 0x65, 0x6e, 0x73, 0x74, 0x61, -0x67, 0x3b, 0x4d, 0x69, 0x74, 0x74, 0x77, 0x6f, 0x63, 0x68, 0x3b, 0x44, 0x6f, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x74, 0x61, -0x67, 0x3b, 0x46, 0x72, 0x65, 0x69, 0x74, 0x61, 0x67, 0x3b, 0x53, 0x61, 0x6d, 0x73, 0x74, 0x61, 0x67, 0x3b, 0x53, 0x3b, -0x4d, 0x3b, 0x44, 0x3b, 0x4d, 0x3b, 0x44, 0x3b, 0x46, 0x3b, 0x53, 0x3b, 0x53, 0x6f, 0x2e, 0x3b, 0x4d, 0x6f, 0x2e, 0x3b, -0x44, 0x69, 0x2e, 0x3b, 0x4d, 0x69, 0x2e, 0x3b, 0x44, 0x6f, 0x2e, 0x3b, 0x46, 0x72, 0x2e, 0x3b, 0x53, 0x61, 0x2e, 0x3b, -0x39a, 0x3c5, 0x3c1, 0x3b, 0x394, 0x3b5, 0x3c5, 0x3b, 0x3a4, 0x3c1, 0x3af, 0x3b, 0x3a4, 0x3b5, 0x3c4, 0x3b, 0x3a0, 0x3ad, 0x3bc, 0x3b, -0x3a0, 0x3b1, 0x3c1, 0x3b, 0x3a3, 0x3ac, 0x3b2, 0x3b, 0x39a, 0x3c5, 0x3c1, 0x3b9, 0x3b1, 0x3ba, 0x3ae, 0x3b, 0x394, 0x3b5, 0x3c5, 0x3c4, -0x3ad, 0x3c1, 0x3b1, 0x3b, 0x3a4, 0x3c1, 0x3af, 0x3c4, 0x3b7, 0x3b, 0x3a4, 0x3b5, 0x3c4, 0x3ac, 0x3c1, 0x3c4, 0x3b7, 0x3b, 0x3a0, 0x3ad, -0x3bc, 0x3c0, 0x3c4, 0x3b7, 0x3b, 0x3a0, 0x3b1, 0x3c1, 0x3b1, 0x3c3, 0x3ba, 0x3b5, 0x3c5, 0x3ae, 0x3b, 0x3a3, 0x3ac, 0x3b2, 0x3b2, 0x3b1, -0x3c4, 0x3bf, 0x3b, 0x39a, 0x3b, 0x394, 0x3b, 0x3a4, 0x3b, 0x3a4, 0x3b, 0x3a0, 0x3b, 0x3a0, 0x3b, 0x3a3, 0x3b, 0x73, 0x61, 0x62, -0x3b, 0x61, 0x74, 0x61, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x70, 0x69, 0x6e, 0x3b, 0x73, 0x69, 0x73, 0x3b, 0x74, 0x61, 0x6c, -0x3b, 0x61, 0x72, 0x66, 0x3b, 0x73, 0x61, 0x62, 0x61, 0x61, 0x74, 0x3b, 0x61, 0x74, 0x61, 0x61, 0x73, 0x69, 0x6e, 0x6e, -0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0x6d, 0x61, 0x72, 0x6c, 0x75, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, -0x3b, 0x70, 0x69, 0x6e, 0x67, 0x61, 0x73, 0x75, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0x73, 0x69, 0x73, -0x61, 0x6d, 0x61, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0x74, 0x61, 0x6c, 0x6c, 0x69, 0x6d, 0x61, 0x6e, -0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0x61, 0x72, 0x66, 0x69, 0x6e, 0x69, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, -0x65, 0x71, 0x3b, 0x53, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0xab0, 0xab5, 0xabf, -0x3b, 0xab8, 0xacb, 0xaae, 0x3b, 0xaae, 0xa82, 0xa97, 0xab3, 0x3b, 0xaac, 0xac1, 0xaa7, 0x3b, 0xa97, 0xac1, 0xab0, 0xac1, 0x3b, 0xab6, -0xac1, 0xa95, 0xacd, 0xab0, 0x3b, 0xab6, 0xaa8, 0xabf, 0x3b, 0xab0, 0xab5, 0xabf, 0xab5, 0xabe, 0xab0, 0x3b, 0xab8, 0xacb, 0xaae, 0xab5, -0xabe, 0xab0, 0x3b, 0xaae, 0xa82, 0xa97, 0xab3, 0xab5, 0xabe, 0xab0, 0x3b, 0xaac, 0xac1, 0xaa7, 0xab5, 0xabe, 0xab0, 0x3b, 0xa97, 0xac1, -0xab0, 0xac1, 0xab5, 0xabe, 0xab0, 0x3b, 0xab6, 0xac1, 0xa95, 0xacd, 0xab0, 0xab5, 0xabe, 0xab0, 0x3b, 0xab6, 0xaa8, 0xabf, 0xab5, 0xabe, -0xab0, 0x3b, 0xab0, 0x3b, 0xab8, 0xacb, 0x3b, 0xaae, 0xa82, 0x3b, 0xaac, 0xac1, 0x3b, 0xa97, 0xac1, 0x3b, 0xab6, 0xac1, 0x3b, 0xab6, -0x3b, 0x4c, 0x61, 0x68, 0x3b, 0x4c, 0x69, 0x74, 0x3b, 0x54, 0x61, 0x6c, 0x3b, 0x4c, 0x61, 0x72, 0x3b, 0x41, 0x6c, 0x68, -0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x41, 0x73, 0x61, 0x3b, 0x4c, 0x61, 0x68, 0x61, 0x64, 0x69, 0x3b, 0x4c, 0x69, 0x74, 0x69, -0x6e, 0x69, 0x6e, 0x3b, 0x54, 0x61, 0x6c, 0x61, 0x74, 0x61, 0x3b, 0x4c, 0x61, 0x72, 0x61, 0x62, 0x61, 0x3b, 0x41, 0x6c, -0x68, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0x4a, 0x75, 0x6d, 0x6d, 0x61, 0x2bc, 0x61, 0x3b, 0x41, 0x73, 0x61, 0x62, 0x61, 0x72, -0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x54, 0x3b, 0x4c, 0x3b, 0x41, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d0, -0x5f3, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d1, 0x5f3, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d2, 0x5f3, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, -0x5d3, 0x5f3, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d4, 0x5f3, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d5, 0x5f3, 0x3b, 0x5e9, 0x5d1, 0x5ea, -0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e8, 0x5d0, 0x5e9, 0x5d5, 0x5df, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e9, 0x5e0, 0x5d9, 0x3b, 0x5d9, -0x5d5, 0x5dd, 0x20, 0x5e9, 0x5dc, 0x5d9, 0x5e9, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e8, 0x5d1, 0x5d9, 0x5e2, 0x5d9, 0x3b, 0x5d9, -0x5d5, 0x5dd, 0x20, 0x5d7, 0x5de, 0x5d9, 0x5e9, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e9, 0x5d9, 0x5e9, 0x5d9, 0x3b, 0x5d9, 0x5d5, -0x5dd, 0x20, 0x5e9, 0x5d1, 0x5ea, 0x3b, 0x5d0, 0x5f3, 0x3b, 0x5d1, 0x5f3, 0x3b, 0x5d2, 0x5f3, 0x3b, 0x5d3, 0x5f3, 0x3b, 0x5d4, 0x5f3, -0x3b, 0x5d5, 0x5f3, 0x3b, 0x5e9, 0x5f3, 0x3b, 0x930, 0x935, 0x93f, 0x3b, 0x938, 0x94b, 0x92e, 0x3b, 0x92e, 0x902, 0x917, 0x932, 0x3b, -0x92c, 0x941, 0x927, 0x3b, 0x917, 0x941, 0x930, 0x941, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x3b, 0x930, -0x935, 0x93f, 0x935, 0x93e, 0x930, 0x3b, 0x938, 0x94b, 0x92e, 0x935, 0x93e, 0x930, 0x3b, 0x92e, 0x902, 0x917, 0x932, 0x935, 0x93e, 0x930, -0x3b, 0x92c, 0x941, 0x927, 0x935, 0x93e, 0x930, 0x3b, 0x917, 0x941, 0x930, 0x941, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x941, 0x915, 0x94d, -0x930, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x935, 0x93e, 0x930, 0x3b, 0x930, 0x3b, 0x938, 0x94b, 0x3b, 0x92e, 0x902, 0x3b, -0x92c, 0x941, 0x3b, 0x917, 0x941, 0x3b, 0x936, 0x941, 0x3b, 0x936, 0x3b, 0x56, 0x3b, 0x48, 0x3b, 0x4b, 0x3b, 0x53, 0x7a, 0x65, -0x3b, 0x43, 0x73, 0x3b, 0x50, 0x3b, 0x53, 0x7a, 0x6f, 0x3b, 0x76, 0x61, 0x73, 0xe1, 0x72, 0x6e, 0x61, 0x70, 0x3b, 0x68, -0xe9, 0x74, 0x66, 0x151, 0x3b, 0x6b, 0x65, 0x64, 0x64, 0x3b, 0x73, 0x7a, 0x65, 0x72, 0x64, 0x61, 0x3b, 0x63, 0x73, 0xfc, -0x74, 0xf6, 0x72, 0x74, 0xf6, 0x6b, 0x3b, 0x70, 0xe9, 0x6e, 0x74, 0x65, 0x6b, 0x3b, 0x73, 0x7a, 0x6f, 0x6d, 0x62, 0x61, -0x74, 0x3b, 0x56, 0x3b, 0x48, 0x3b, 0x4b, 0x3b, 0x53, 0x7a, 0x3b, 0x43, 0x73, 0x3b, 0x50, 0x3b, 0x53, 0x7a, 0x3b, 0x73, -0x75, 0x6e, 0x2e, 0x3b, 0x6d, 0xe1, 0x6e, 0x2e, 0x3b, 0xfe, 0x72, 0x69, 0x2e, 0x3b, 0x6d, 0x69, 0xf0, 0x2e, 0x3b, 0x66, -0x69, 0x6d, 0x2e, 0x3b, 0x66, 0xf6, 0x73, 0x2e, 0x3b, 0x6c, 0x61, 0x75, 0x2e, 0x3b, 0x73, 0x75, 0x6e, 0x6e, 0x75, 0x64, -0x61, 0x67, 0x75, 0x72, 0x3b, 0x6d, 0xe1, 0x6e, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0xfe, 0x72, 0x69, 0xf0, 0x6a, -0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6d, 0x69, 0xf0, 0x76, 0x69, 0x6b, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, -0x66, 0x69, 0x6d, 0x6d, 0x74, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x66, 0xf6, 0x73, 0x74, 0x75, 0x64, 0x61, 0x67, -0x75, 0x72, 0x3b, 0x6c, 0x61, 0x75, 0x67, 0x61, 0x72, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0xde, -0x3b, 0x4d, 0x3b, 0x46, 0x3b, 0x46, 0x3b, 0x4c, 0x3b, 0x4d, 0x69, 0x6e, 0x3b, 0x53, 0x65, 0x6e, 0x3b, 0x53, 0x65, 0x6c, -0x3b, 0x52, 0x61, 0x62, 0x3b, 0x4b, 0x61, 0x6d, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4d, 0x69, 0x6e, -0x67, 0x67, 0x75, 0x3b, 0x53, 0x65, 0x6e, 0x69, 0x6e, 0x3b, 0x53, 0x65, 0x6c, 0x61, 0x73, 0x61, 0x3b, 0x52, 0x61, 0x62, -0x75, 0x3b, 0x4b, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x3b, 0x53, 0x61, 0x62, 0x74, 0x75, 0x3b, -0x4d, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x52, 0x3b, 0x4b, 0x3b, 0x4a, 0x3b, 0x53, 0x3b, 0x44, 0x6f, 0x6d, 0x68, 0x3b, 0x4c, -0x75, 0x61, 0x6e, 0x3b, 0x4d, 0xe1, 0x69, 0x72, 0x74, 0x3b, 0x43, 0xe9, 0x61, 0x64, 0x3b, 0x44, 0xe9, 0x61, 0x72, 0x3b, -0x41, 0x6f, 0x69, 0x6e, 0x65, 0x3b, 0x53, 0x61, 0x74, 0x68, 0x3b, 0x44, 0xe9, 0x20, 0x44, 0x6f, 0x6d, 0x68, 0x6e, 0x61, -0x69, 0x67, 0x68, 0x3b, 0x44, 0xe9, 0x20, 0x4c, 0x75, 0x61, 0x69, 0x6e, 0x3b, 0x44, 0xe9, 0x20, 0x4d, 0xe1, 0x69, 0x72, -0x74, 0x3b, 0x44, 0xe9, 0x20, 0x43, 0xe9, 0x61, 0x64, 0x61, 0x6f, 0x69, 0x6e, 0x3b, 0x44, 0xe9, 0x61, 0x72, 0x64, 0x61, -0x6f, 0x69, 0x6e, 0x3b, 0x44, 0xe9, 0x20, 0x68, 0x41, 0x6f, 0x69, 0x6e, 0x65, 0x3b, 0x44, 0xe9, 0x20, 0x53, 0x61, 0x74, -0x68, 0x61, 0x69, 0x72, 0x6e, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x43, 0x3b, 0x44, 0x3b, 0x41, 0x3b, 0x53, 0x3b, -0x64, 0x6f, 0x6d, 0x3b, 0x6c, 0x75, 0x6e, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0x65, 0x72, 0x3b, 0x67, 0x69, 0x6f, 0x3b, -0x76, 0x65, 0x6e, 0x3b, 0x73, 0x61, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x65, 0x6e, 0x69, 0x63, 0x61, 0x3b, 0x6c, 0x75, 0x6e, -0x65, 0x64, 0xec, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x65, 0x64, 0xec, 0x3b, 0x6d, 0x65, 0x72, 0x63, 0x6f, 0x6c, 0x65, 0x64, -0xec, 0x3b, 0x67, 0x69, 0x6f, 0x76, 0x65, 0x64, 0xec, 0x3b, 0x76, 0x65, 0x6e, 0x65, 0x72, 0x64, 0xec, 0x3b, 0x73, 0x61, -0x62, 0x61, 0x74, 0x6f, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x65e5, -0x3b, 0x6708, 0x3b, 0x706b, 0x3b, 0x6c34, 0x3b, 0x6728, 0x3b, 0x91d1, 0x3b, 0x571f, 0x3b, 0x65e5, 0x66dc, 0x65e5, 0x3b, 0x6708, 0x66dc, 0x65e5, -0x3b, 0x706b, 0x66dc, 0x65e5, 0x3b, 0x6c34, 0x66dc, 0x65e5, 0x3b, 0x6728, 0x66dc, 0x65e5, 0x3b, 0x91d1, 0x66dc, 0x65e5, 0x3b, 0x571f, 0x66dc, 0x65e5, -0x3b, 0xcad, 0xcbe, 0xca8, 0xcc1, 0x3b, 0xcb8, 0xccb, 0xcae, 0x3b, 0xcae, 0xc82, 0xc97, 0xcb3, 0x3b, 0xcac, 0xcc1, 0xca7, 0x3b, 0xc97, -0xcc1, 0xcb0, 0xcc1, 0x3b, 0xcb6, 0xcc1, 0xc95, 0xccd, 0xcb0, 0x3b, 0xcb6, 0xca8, 0xcbf, 0x3b, 0xcad, 0xcbe, 0xca8, 0xcc1, 0xcb5, 0xcbe, -0xcb0, 0x3b, 0xcb8, 0xccb, 0xcae, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcae, 0xc82, 0xc97, 0xcb3, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcac, 0xcc1, 0xca7, -0xcb5, 0xcbe, 0xcb0, 0x3b, 0xc97, 0xcc1, 0xcb0, 0xcc1, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcb6, 0xcc1, 0xc95, 0xccd, 0xcb0, 0xcb5, 0xcbe, 0xcb0, -0x3b, 0xcb6, 0xca8, 0xcbf, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcad, 0xcbe, 0x3b, 0xcb8, 0xccb, 0x3b, 0xcae, 0xc82, 0x3b, 0xcac, 0xcc1, 0x3b, -0xc97, 0xcc1, 0x3b, 0xcb6, 0xcc1, 0x3b, 0xcb6, 0x3b, 0x622, 0x62a, 0x6be, 0x648, 0x627, 0x631, 0x3b, 0x698, 0x654, 0x646, 0x65b, 0x62f, -0x655, 0x631, 0x648, 0x627, 0x631, 0x3b, 0x628, 0x648, 0x65a, 0x645, 0x648, 0x627, 0x631, 0x3b, 0x628, 0x648, 0x62f, 0x648, 0x627, 0x631, -0x3b, 0x628, 0x631, 0x65b, 0x66e, 0x6ea, 0x633, 0x648, 0x627, 0x631, 0x3b, 0x62c, 0x64f, 0x645, 0x6c1, 0x3b, 0x628, 0x679, 0x648, 0x627, -0x631, 0x3b, 0x627, 0x64e, 0x62a, 0x6be, 0x648, 0x627, 0x631, 0x3b, 0x698, 0x654, 0x646, 0x65b, 0x62f, 0x631, 0x655, 0x631, 0x648, 0x627, -0x631, 0x3b, 0x628, 0x648, 0x65a, 0x645, 0x648, 0x627, 0x631, 0x3b, 0x628, 0x648, 0x62f, 0x648, 0x627, 0x631, 0x3b, 0x628, 0x631, 0x65b, -0x66e, 0x6ea, 0x633, 0x648, 0x627, 0x631, 0x3b, 0x62c, 0x64f, 0x645, 0x6c1, 0x3b, 0x628, 0x679, 0x648, 0x627, 0x631, 0x3b, 0x627, 0x3b, -0x698, 0x3b, 0x628, 0x3b, 0x628, 0x3b, 0x628, 0x3b, 0x62c, 0x3b, 0x628, 0x3b, 0x416, 0x441, 0x3b, 0x414, 0x441, 0x3b, 0x421, 0x441, -0x3b, 0x421, 0x440, 0x3b, 0x411, 0x441, 0x3b, 0x416, 0x43c, 0x3b, 0x421, 0x431, 0x3b, 0x416, 0x435, 0x43a, 0x441, 0x435, 0x43d, 0x431, -0x456, 0x3b, 0x414, 0x4af, 0x439, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x421, 0x435, 0x439, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, -0x421, 0x4d9, 0x440, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x411, 0x435, 0x439, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x416, 0x4b1, -0x43c, 0x430, 0x3b, 0x421, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x416, 0x3b, 0x414, 0x3b, 0x421, 0x3b, 0x421, 0x3b, 0x411, 0x3b, 0x416, -0x3b, 0x421, 0x3b, 0x436, 0x435, 0x43a, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x434, 0x4af, 0x439, 0x441, 0x435, 0x43d, 0x431, 0x456, -0x3b, 0x441, 0x435, 0x439, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x441, 0x4d9, 0x440, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x431, -0x435, 0x439, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x436, 0x4b1, 0x43c, 0x430, 0x3b, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x63, -0x79, 0x75, 0x2e, 0x3b, 0x6d, 0x62, 0x65, 0x2e, 0x3b, 0x6b, 0x61, 0x62, 0x2e, 0x3b, 0x67, 0x74, 0x75, 0x2e, 0x3b, 0x6b, -0x61, 0x6e, 0x2e, 0x3b, 0x67, 0x6e, 0x75, 0x2e, 0x3b, 0x67, 0x6e, 0x64, 0x2e, 0x3b, 0x4b, 0x75, 0x20, 0x63, 0x79, 0x75, -0x6d, 0x77, 0x65, 0x72, 0x75, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x6d, 0x62, 0x65, 0x72, 0x65, 0x3b, 0x4b, 0x75, 0x77, -0x61, 0x20, 0x6b, 0x61, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x74, 0x75, -0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x65, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, -0x6e, 0x75, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x74, 0x75, 0x3b, 0x436, 0x435, -0x43a, 0x2e, 0x3b, 0x434, 0x4af, 0x439, 0x2e, 0x3b, 0x448, 0x435, 0x439, 0x448, 0x2e, 0x3b, 0x448, 0x430, 0x440, 0x448, 0x2e, 0x3b, -0x431, 0x435, 0x439, 0x448, 0x2e, 0x3b, 0x436, 0x443, 0x43c, 0x430, 0x3b, 0x438, 0x448, 0x43c, 0x2e, 0x3b, 0x436, 0x435, 0x43a, 0x448, -0x435, 0x43c, 0x431, 0x438, 0x3b, 0x434, 0x4af, 0x439, 0x448, 0x4e9, 0x43c, 0x431, 0x4af, 0x3b, 0x448, 0x435, 0x439, 0x448, 0x435, 0x43c, -0x431, 0x438, 0x3b, 0x448, 0x430, 0x440, 0x448, 0x435, 0x43c, 0x431, 0x438, 0x3b, 0x431, 0x435, 0x439, 0x448, 0x435, 0x43c, 0x431, 0x438, -0x3b, 0x436, 0x443, 0x43c, 0x430, 0x3b, 0x438, 0x448, 0x435, 0x43c, 0x431, 0x438, 0x3b, 0x416, 0x3b, 0x414, 0x3b, 0x428, 0x3b, 0x428, -0x3b, 0x411, 0x3b, 0x416, 0x3b, 0x418, 0x3b, 0xc77c, 0x3b, 0xc6d4, 0x3b, 0xd654, 0x3b, 0xc218, 0x3b, 0xbaa9, 0x3b, 0xae08, 0x3b, 0xd1a0, -0x3b, 0xc77c, 0xc694, 0xc77c, 0x3b, 0xc6d4, 0xc694, 0xc77c, 0x3b, 0xd654, 0xc694, 0xc77c, 0x3b, 0xc218, 0xc694, 0xc77c, 0x3b, 0xbaa9, 0xc694, 0xc77c, -0x3b, 0xae08, 0xc694, 0xc77c, 0x3b, 0xd1a0, 0xc694, 0xc77c, 0x3b, 0x63, 0x75, 0x2e, 0x3b, 0x6d, 0x62, 0x65, 0x2e, 0x3b, 0x6b, 0x61, -0x62, 0x2e, 0x3b, 0x67, 0x74, 0x75, 0x2e, 0x3b, 0x6b, 0x61, 0x6e, 0x2e, 0x3b, 0x67, 0x6e, 0x75, 0x2e, 0x3b, 0x67, 0x6e, -0x64, 0x2e, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x2019, 0x69, 0x6e, 0x64, 0x77, 0x69, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x61, 0x20, -0x6d, 0x62, 0x65, 0x72, 0x65, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4b, -0x75, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, -0x6e, 0x65, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x75, 0x3b, 0x4b, 0x75, 0x20, 0x77, -0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x74, 0x75, 0x3b, 0xead, 0xeb2, 0xe97, 0xeb4, 0xe94, 0x3b, 0xe88, 0xeb1, -0xe99, 0x3b, 0xead, 0xeb1, 0xe87, 0xe84, 0xeb2, 0xe99, 0x3b, 0xe9e, 0xeb8, 0xe94, 0x3b, 0xe9e, 0xeb0, 0xeab, 0xeb1, 0xe94, 0x3b, 0xeaa, -0xeb8, 0xe81, 0x3b, 0xec0, 0xeaa, 0xebb, 0xeb2, 0x3b, 0xea7, 0xeb1, 0xe99, 0xead, 0xeb2, 0xe97, 0xeb4, 0xe94, 0x3b, 0xea7, 0xeb1, 0xe99, -0xe88, 0xeb1, 0xe99, 0x3b, 0xea7, 0xeb1, 0xe99, 0xead, 0xeb1, 0xe87, 0xe84, 0xeb2, 0xe99, 0x3b, 0xea7, 0xeb1, 0xe99, 0xe9e, 0xeb8, 0xe94, -0x3b, 0xea7, 0xeb1, 0xe99, 0xe9e, 0xeb0, 0xeab, 0xeb1, 0xe94, 0x3b, 0xea7, 0xeb1, 0xe99, 0xeaa, 0xeb8, 0xe81, 0x3b, 0xea7, 0xeb1, 0xe99, -0xec0, 0xeaa, 0xebb, 0xeb2, 0x3b, 0xead, 0xeb2, 0x3b, 0xe88, 0x3b, 0xead, 0x3b, 0xe9e, 0x3b, 0xe9e, 0xeab, 0x3b, 0xeaa, 0xeb8, 0x3b, -0xeaa, 0x3b, 0x53, 0x76, 0x113, 0x74, 0x64, 0x2e, 0x3b, 0x50, 0x69, 0x72, 0x6d, 0x64, 0x2e, 0x3b, 0x4f, 0x74, 0x72, 0x64, -0x2e, 0x3b, 0x54, 0x72, 0x65, 0x161, 0x64, 0x2e, 0x3b, 0x43, 0x65, 0x74, 0x75, 0x72, 0x74, 0x64, 0x2e, 0x3b, 0x50, 0x69, -0x65, 0x6b, 0x74, 0x64, 0x2e, 0x3b, 0x53, 0x65, 0x73, 0x74, 0x64, 0x2e, 0x3b, 0x53, 0x76, 0x113, 0x74, 0x64, 0x69, 0x65, -0x6e, 0x61, 0x3b, 0x50, 0x69, 0x72, 0x6d, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x4f, 0x74, 0x72, 0x64, 0x69, 0x65, 0x6e, -0x61, 0x3b, 0x54, 0x72, 0x65, 0x161, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x43, 0x65, 0x74, 0x75, 0x72, 0x74, 0x64, 0x69, -0x65, 0x6e, 0x61, 0x3b, 0x50, 0x69, 0x65, 0x6b, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x53, 0x65, 0x73, 0x74, 0x64, -0x69, 0x65, 0x6e, 0x61, 0x3b, 0x53, 0x3b, 0x50, 0x3b, 0x4f, 0x3b, 0x54, 0x3b, 0x43, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x73, -0x76, 0x113, 0x74, 0x64, 0x2e, 0x3b, 0x70, 0x69, 0x72, 0x6d, 0x64, 0x2e, 0x3b, 0x6f, 0x74, 0x72, 0x64, 0x2e, 0x3b, 0x74, -0x72, 0x65, 0x161, 0x64, 0x2e, 0x3b, 0x63, 0x65, 0x74, 0x75, 0x72, 0x74, 0x64, 0x2e, 0x3b, 0x70, 0x69, 0x65, 0x6b, 0x74, -0x64, 0x2e, 0x3b, 0x73, 0x65, 0x73, 0x74, 0x64, 0x2e, 0x3b, 0x73, 0x76, 0x113, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, -0x70, 0x69, 0x72, 0x6d, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x6f, 0x74, 0x72, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x74, -0x72, 0x65, 0x161, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x63, 0x65, 0x74, 0x75, 0x72, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, -0x3b, 0x70, 0x69, 0x65, 0x6b, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x73, 0x65, 0x73, 0x74, 0x64, 0x69, 0x65, 0x6e, -0x61, 0x3b, 0x65, 0x79, 0x65, 0x3b, 0x79, 0x62, 0x6f, 0x3b, 0x6d, 0x62, 0x6c, 0x3b, 0x6d, 0x73, 0x74, 0x3b, 0x6d, 0x69, -0x6e, 0x3b, 0x6d, 0x74, 0x6e, 0x3b, 0x6d, 0x70, 0x73, 0x3b, 0x65, 0x79, 0x65, 0x6e, 0x67, 0x61, 0x3b, 0x6d, 0x6f, 0x6b, -0x254, 0x6c, 0x254, 0x20, 0x6d, 0x77, 0x61, 0x20, 0x79, 0x61, 0x6d, 0x62, 0x6f, 0x3b, 0x6d, 0x6f, 0x6b, 0x254, 0x6c, 0x254, -0x20, 0x6d, 0x77, 0x61, 0x20, 0x6d, 0xed, 0x62, 0x61, 0x6c, 0xe9, 0x3b, 0x6d, 0x6f, 0x6b, 0x254, 0x6c, 0x254, 0x20, 0x6d, -0x77, 0x61, 0x20, 0x6d, 0xed, 0x73, 0xe1, 0x74, 0x6f, 0x3b, 0x6d, 0x6f, 0x6b, 0x254, 0x6c, 0x254, 0x20, 0x79, 0x61, 0x20, -0x6d, 0xed, 0x6e, 0xe9, 0x69, 0x3b, 0x6d, 0x6f, 0x6b, 0x254, 0x6c, 0x254, 0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x74, 0xe1, -0x6e, 0x6f, 0x3b, 0x6d, 0x70, 0x254, 0x301, 0x73, 0x254, 0x3b, 0x65, 0x3b, 0x79, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, -0x6d, 0x3b, 0x70, 0x3b, 0x73, 0x6b, 0x3b, 0x70, 0x72, 0x3b, 0x61, 0x6e, 0x3b, 0x74, 0x72, 0x3b, 0x6b, 0x74, 0x3b, 0x70, -0x6e, 0x3b, 0x161, 0x74, 0x3b, 0x73, 0x65, 0x6b, 0x6d, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x70, 0x69, 0x72, -0x6d, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x61, 0x6e, 0x74, 0x72, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, -0x3b, 0x74, 0x72, 0x65, 0x10d, 0x69, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x6b, 0x65, 0x74, 0x76, 0x69, 0x72, -0x74, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x70, 0x65, 0x6e, 0x6b, 0x74, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, -0x73, 0x3b, 0x161, 0x65, 0x161, 0x74, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x53, 0x3b, 0x50, 0x3b, 0x41, 0x3b, -0x54, 0x3b, 0x4b, 0x3b, 0x50, 0x3b, 0x160, 0x3b, 0x43d, 0x435, 0x434, 0x2e, 0x3b, 0x43f, 0x43e, 0x43d, 0x2e, 0x3b, 0x432, 0x442, -0x43e, 0x2e, 0x3b, 0x441, 0x440, 0x435, 0x2e, 0x3b, 0x447, 0x435, 0x442, 0x2e, 0x3b, 0x43f, 0x435, 0x442, 0x2e, 0x3b, 0x441, 0x430, -0x431, 0x2e, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x43b, 0x430, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x43b, 0x43d, 0x438, 0x43a, -0x3b, 0x432, 0x442, 0x43e, 0x440, 0x43d, 0x438, 0x43a, 0x3b, 0x441, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x440, -0x442, 0x43e, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x43e, 0x43a, 0x3b, 0x441, 0x430, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x43d, 0x435, 0x434, -0x2e, 0x3b, 0x43f, 0x43e, 0x43d, 0x2e, 0x3b, 0x432, 0x442, 0x2e, 0x3b, 0x441, 0x440, 0x435, 0x2e, 0x3b, 0x447, 0x435, 0x442, 0x2e, -0x3b, 0x43f, 0x435, 0x442, 0x2e, 0x3b, 0x441, 0x430, 0x431, 0x2e, 0x3b, 0x41, 0x6c, 0x61, 0x68, 0x3b, 0x41, 0x6c, 0x61, 0x74, -0x73, 0x3b, 0x54, 0x61, 0x6c, 0x3b, 0x41, 0x6c, 0x61, 0x72, 0x3b, 0x41, 0x6c, 0x61, 0x6b, 0x3b, 0x5a, 0x6f, 0x6d, 0x3b, -0x41, 0x73, 0x61, 0x62, 0x3b, 0x41, 0x6c, 0x61, 0x68, 0x61, 0x64, 0x79, 0x3b, 0x41, 0x6c, 0x61, 0x74, 0x73, 0x69, 0x6e, -0x61, 0x69, 0x6e, 0x79, 0x3b, 0x54, 0x61, 0x6c, 0x61, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x72, 0x6f, 0x62, 0x69, 0x61, -0x3b, 0x41, 0x6c, 0x61, 0x6b, 0x61, 0x6d, 0x69, 0x73, 0x79, 0x3b, 0x5a, 0x6f, 0x6d, 0x61, 0x3b, 0x41, 0x73, 0x61, 0x62, -0x6f, 0x74, 0x73, 0x79, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x5a, 0x3b, 0x41, 0x3b, 0x41, -0x68, 0x64, 0x3b, 0x49, 0x73, 0x6e, 0x3b, 0x53, 0x65, 0x6c, 0x3b, 0x52, 0x61, 0x62, 0x3b, 0x4b, 0x68, 0x61, 0x3b, 0x4a, -0x75, 0x6d, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x41, 0x68, 0x61, 0x64, 0x3b, 0x49, 0x73, 0x6e, 0x69, 0x6e, 0x3b, 0x53, 0x65, -0x6c, 0x61, 0x73, 0x61, 0x3b, 0x52, 0x61, 0x62, 0x75, 0x3b, 0x4b, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0x4a, 0x75, 0x6d, -0x61, 0x61, 0x74, 0x3b, 0x53, 0x61, 0x62, 0x74, 0x75, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x53, 0x3b, 0x52, 0x3b, 0x4b, 0x3b, -0x4a, 0x3b, 0x53, 0x3b, 0xd1e, 0xd3e, 0xd2f, 0xd7c, 0x3b, 0xd24, 0xd3f, 0xd19, 0xd4d, 0xd15, 0xd7e, 0x3b, 0xd1a, 0xd4a, 0xd35, 0xd4d, -0xd35, 0x3b, 0xd2c, 0xd41, 0xd27, 0xd7b, 0x3b, 0xd35, 0xd4d, 0xd2f, 0xd3e, 0xd34, 0xd02, 0x3b, 0xd35, 0xd46, 0xd33, 0xd4d, 0xd33, 0xd3f, -0x3b, 0xd36, 0xd28, 0xd3f, 0x3b, 0xd1e, 0xd3e, 0xd2f, 0xd31, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd24, 0xd3f, 0xd19, 0xd4d, 0xd15, -0xd33, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd1a, 0xd4a, 0xd35, 0xd4d, 0xd35, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd2c, 0xd41, -0xd27, 0xd28, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd35, 0xd4d, 0xd2f, 0xd3e, 0xd34, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd35, -0xd46, 0xd33, 0xd4d, 0xd33, 0xd3f, 0xd2f, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd36, 0xd28, 0xd3f, 0xd2f, 0xd3e, 0xd34, 0xd4d, 0x200c, -0xd1a, 0x3b, 0xd1e, 0xd3e, 0x3b, 0xd24, 0xd3f, 0x3b, 0xd1a, 0xd4a, 0x3b, 0xd2c, 0xd41, 0x3b, 0xd35, 0xd4d, 0xd2f, 0xd3e, 0x3b, 0xd35, -0xd46, 0x3b, 0xd36, 0x3b, 0xd1e, 0xd3e, 0xd2f, 0xd31, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd24, 0xd3f, 0xd19, 0xd4d, 0xd15, 0xd33, -0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd1a, 0xd4a, 0xd35, 0xd4d, 0xd35, 0xd3e, 0xd34, 0xd4d, 0xd1a, 0x3b, 0xd2c, 0xd41, 0xd27, 0xd28, -0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd35, 0xd4d, 0xd2f, 0xd3e, 0xd34, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd35, 0xd46, 0xd33, -0xd4d, 0xd33, 0xd3f, 0xd2f, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd36, 0xd28, 0xd3f, 0xd2f, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, -0xd1e, 0x3b, 0xd24, 0xd3f, 0x3b, 0xd1a, 0xd4a, 0x3b, 0xd2c, 0xd41, 0x3b, 0xd35, 0xd4d, 0xd2f, 0xd3e, 0x3b, 0xd35, 0xd46, 0x3b, 0xd36, -0x3b, 0x126, 0x61, 0x64, 0x3b, 0x54, 0x6e, 0x65, 0x3b, 0x54, 0x6c, 0x69, 0x3b, 0x45, 0x72, 0x62, 0x3b, 0x126, 0x61, 0x6d, -0x3b, 0x120, 0x69, 0x6d, 0x3b, 0x53, 0x69, 0x62, 0x3b, 0x49, 0x6c, 0x2d, 0x126, 0x61, 0x64, 0x64, 0x3b, 0x49, 0x74, 0x2d, -0x54, 0x6e, 0x65, 0x6a, 0x6e, 0x3b, 0x49, 0x74, 0x2d, 0x54, 0x6c, 0x69, 0x65, 0x74, 0x61, 0x3b, 0x4c, 0x2d, 0x45, 0x72, -0x62, 0x67, 0x127, 0x61, 0x3b, 0x49, 0x6c, 0x2d, 0x126, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0x49, 0x6c, 0x2d, 0x120, 0x69, 0x6d, -0x67, 0x127, 0x61, 0x3b, 0x49, 0x73, 0x2d, 0x53, 0x69, 0x62, 0x74, 0x3b, 0x126, 0x64, 0x3b, 0x54, 0x6e, 0x3b, 0x54, 0x6c, -0x3b, 0x45, 0x72, 0x3b, 0x126, 0x6d, 0x3b, 0x120, 0x6d, 0x3b, 0x53, 0x62, 0x3b, 0x126, 0x64, 0x3b, 0x54, 0x3b, 0x54, 0x6c, -0x3b, 0x45, 0x72, 0x3b, 0x126, 0x6d, 0x3b, 0x120, 0x6d, 0x3b, 0x53, 0x62, 0x3b, 0x930, 0x935, 0x93f, 0x3b, 0x938, 0x94b, 0x92e, +0x44, 0x3b, 0x57, 0x3b, 0x44, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x64, 0x69, 0x65, 0x3b, 0x68, 0xeb, 0x6e, 0x3b, 0x6d, 0x61, +0x72, 0x3b, 0x6d, 0xeb, 0x72, 0x3b, 0x65, 0x6e, 0x6a, 0x3b, 0x70, 0x72, 0x65, 0x3b, 0x73, 0x68, 0x74, 0x3b, 0x65, 0x20, +0x64, 0x69, 0x65, 0x6c, 0x3b, 0x65, 0x20, 0x68, 0xeb, 0x6e, 0xeb, 0x3b, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x74, 0xeb, 0x3b, +0x65, 0x20, 0x6d, 0xeb, 0x72, 0x6b, 0x75, 0x72, 0xeb, 0x3b, 0x65, 0x20, 0x65, 0x6e, 0x6a, 0x74, 0x65, 0x3b, 0x65, 0x20, +0x70, 0x72, 0x65, 0x6d, 0x74, 0x65, 0x3b, 0x65, 0x20, 0x73, 0x68, 0x74, 0x75, 0x6e, 0xeb, 0x3b, 0x64, 0x3b, 0x68, 0x3b, +0x6d, 0x3b, 0x6d, 0x3b, 0x65, 0x3b, 0x70, 0x3b, 0x73, 0x68, 0x3b, 0x44, 0x69, 0x65, 0x3b, 0x48, 0xeb, 0x6e, 0x3b, 0x4d, +0x61, 0x72, 0x3b, 0x4d, 0xeb, 0x72, 0x3b, 0x45, 0x6e, 0x6a, 0x3b, 0x50, 0x72, 0x65, 0x3b, 0x53, 0x68, 0x74, 0x3b, 0x12a5, +0x1211, 0x12f5, 0x3b, 0x1230, 0x129e, 0x3b, 0x121b, 0x12ad, 0x1230, 0x3b, 0x1228, 0x1261, 0x12d5, 0x3b, 0x1210, 0x1219, 0x1235, 0x3b, 0x12d3, 0x122d, +0x1265, 0x3b, 0x1245, 0x12f3, 0x121c, 0x3b, 0x12a5, 0x1211, 0x12f5, 0x3b, 0x1230, 0x129e, 0x3b, 0x121b, 0x12ad, 0x1230, 0x129e, 0x3b, 0x1228, 0x1261, +0x12d5, 0x3b, 0x1210, 0x1219, 0x1235, 0x3b, 0x12d3, 0x122d, 0x1265, 0x3b, 0x1245, 0x12f3, 0x121c, 0x3b, 0x12a5, 0x3b, 0x1230, 0x3b, 0x121b, 0x3b, +0x1228, 0x3b, 0x1210, 0x3b, 0x12d3, 0x3b, 0x1245, 0x3b, 0x627, 0x644, 0x623, 0x62d, 0x62f, 0x3b, 0x627, 0x644, 0x627, 0x62b, 0x646, 0x64a, +0x646, 0x3b, 0x627, 0x644, 0x62b, 0x644, 0x627, 0x62b, 0x627, 0x621, 0x3b, 0x627, 0x644, 0x623, 0x631, 0x628, 0x639, 0x627, 0x621, 0x3b, +0x627, 0x644, 0x62e, 0x645, 0x64a, 0x633, 0x3b, 0x627, 0x644, 0x62c, 0x645, 0x639, 0x629, 0x3b, 0x627, 0x644, 0x633, 0x628, 0x62a, 0x3b, +0x62d, 0x3b, 0x646, 0x3b, 0x62b, 0x3b, 0x631, 0x3b, 0x62e, 0x3b, 0x62c, 0x3b, 0x633, 0x3b, 0x56f, 0x56b, 0x580, 0x3b, 0x565, 0x580, +0x56f, 0x3b, 0x565, 0x580, 0x584, 0x3b, 0x579, 0x580, 0x584, 0x3b, 0x570, 0x576, 0x563, 0x3b, 0x578, 0x582, 0x580, 0x3b, 0x577, 0x562, +0x569, 0x3b, 0x56f, 0x56b, 0x580, 0x561, 0x56f, 0x56b, 0x3b, 0x565, 0x580, 0x56f, 0x578, 0x582, 0x577, 0x561, 0x562, 0x569, 0x56b, 0x3b, +0x565, 0x580, 0x565, 0x584, 0x577, 0x561, 0x562, 0x569, 0x56b, 0x3b, 0x579, 0x578, 0x580, 0x565, 0x584, 0x577, 0x561, 0x562, 0x569, 0x56b, +0x3b, 0x570, 0x56b, 0x576, 0x563, 0x577, 0x561, 0x562, 0x569, 0x56b, 0x3b, 0x578, 0x582, 0x580, 0x562, 0x561, 0x569, 0x3b, 0x577, 0x561, +0x562, 0x561, 0x569, 0x3b, 0x53f, 0x3b, 0x535, 0x3b, 0x535, 0x3b, 0x549, 0x3b, 0x540, 0x3b, 0x548, 0x3b, 0x547, 0x3b, 0x9a6, 0x9c7, +0x993, 0x3b, 0x9b8, 0x9cb, 0x9ae, 0x3b, 0x9ae, 0x999, 0x9cd, 0x997, 0x9b2, 0x3b, 0x9ac, 0x9c1, 0x9a7, 0x3b, 0x9ac, 0x9c3, 0x9b9, 0x3b, +0x9b6, 0x9c1, 0x995, 0x9cd, 0x9f0, 0x3b, 0x9b6, 0x9a8, 0x9bf, 0x3b, 0x9a6, 0x9c7, 0x993, 0x9ac, 0x9be, 0x9f0, 0x3b, 0x9b8, 0x9cb, 0x9ae, +0x9ac, 0x9be, 0x9f0, 0x3b, 0x9ae, 0x999, 0x9cd, 0x997, 0x9b2, 0x9ac, 0x9be, 0x9f0, 0x3b, 0x9ac, 0x9c1, 0x9a7, 0x9ac, 0x9be, 0x9f0, 0x3b, +0x9ac, 0x9c3, 0x9b9, 0x9b8, 0x9cd, 0x9aa, 0x9a4, 0x9bf, 0x9ac, 0x9be, 0x9f0, 0x3b, 0x9b6, 0x9c1, 0x995, 0x9cd, 0x9f0, 0x9ac, 0x9be, 0x9f0, +0x3b, 0x9b6, 0x9a8, 0x9bf, 0x9ac, 0x9be, 0x9f0, 0x3b, 0x9a6, 0x3b, 0x9b8, 0x3b, 0x9ae, 0x3b, 0x9ac, 0x3b, 0x9ac, 0x3b, 0x9b6, 0x3b, +0x9b6, 0x3b, 0x42, 0x2e, 0x3b, 0x42, 0x2e, 0x45, 0x2e, 0x3b, 0xc7, 0x2e, 0x41, 0x2e, 0x3b, 0xc7, 0x2e, 0x3b, 0x43, 0x2e, +0x41, 0x2e, 0x3b, 0x43, 0x2e, 0x3b, 0x15e, 0x2e, 0x3b, 0x62, 0x61, 0x7a, 0x61, 0x72, 0x3b, 0x62, 0x61, 0x7a, 0x61, 0x72, +0x20, 0x65, 0x72, 0x74, 0x259, 0x73, 0x69, 0x3b, 0xe7, 0x259, 0x72, 0x15f, 0x259, 0x6e, 0x62, 0x259, 0x20, 0x61, 0x78, 0x15f, +0x61, 0x6d, 0x131, 0x3b, 0xe7, 0x259, 0x72, 0x15f, 0x259, 0x6e, 0x62, 0x259, 0x3b, 0x63, 0xfc, 0x6d, 0x259, 0x20, 0x61, 0x78, +0x15f, 0x61, 0x6d, 0x131, 0x3b, 0x63, 0xfc, 0x6d, 0x259, 0x3b, 0x15f, 0x259, 0x6e, 0x62, 0x259, 0x3b, 0x411, 0x2e, 0x3b, 0x411, +0x2e, 0x415, 0x2e, 0x3b, 0x427, 0x2e, 0x410, 0x2e, 0x3b, 0x427, 0x2e, 0x3b, 0x4b8, 0x2e, 0x410, 0x2e, 0x3b, 0x4b8, 0x2e, 0x3b, +0x428, 0x2e, 0x3b, 0x431, 0x430, 0x437, 0x430, 0x440, 0x3b, 0x431, 0x430, 0x437, 0x430, 0x440, 0x20, 0x435, 0x440, 0x442, 0x4d9, 0x441, +0x438, 0x3b, 0x447, 0x4d9, 0x440, 0x448, 0x4d9, 0x43d, 0x431, 0x4d9, 0x20, 0x430, 0x445, 0x448, 0x430, 0x43c, 0x44b, 0x3b, 0x447, 0x4d9, +0x440, 0x448, 0x4d9, 0x43d, 0x431, 0x4d9, 0x3b, 0x4b9, 0x4af, 0x43c, 0x4d9, 0x20, 0x430, 0x445, 0x448, 0x430, 0x43c, 0x44b, 0x3b, 0x4b9, +0x4af, 0x43c, 0x4d9, 0x3b, 0x448, 0x4d9, 0x43d, 0x431, 0x4d9, 0x3b, 0x69, 0x67, 0x2e, 0x3b, 0x61, 0x6c, 0x2e, 0x3b, 0x61, 0x72, +0x2e, 0x3b, 0x61, 0x7a, 0x2e, 0x3b, 0x6f, 0x67, 0x2e, 0x3b, 0x6f, 0x72, 0x2e, 0x3b, 0x6c, 0x72, 0x2e, 0x3b, 0x69, 0x67, +0x61, 0x6e, 0x64, 0x65, 0x61, 0x3b, 0x61, 0x73, 0x74, 0x65, 0x6c, 0x65, 0x68, 0x65, 0x6e, 0x61, 0x3b, 0x61, 0x73, 0x74, +0x65, 0x61, 0x72, 0x74, 0x65, 0x61, 0x3b, 0x61, 0x73, 0x74, 0x65, 0x61, 0x7a, 0x6b, 0x65, 0x6e, 0x61, 0x3b, 0x6f, 0x73, +0x74, 0x65, 0x67, 0x75, 0x6e, 0x61, 0x3b, 0x6f, 0x73, 0x74, 0x69, 0x72, 0x61, 0x6c, 0x61, 0x3b, 0x6c, 0x61, 0x72, 0x75, +0x6e, 0x62, 0x61, 0x74, 0x61, 0x3b, 0x49, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x4f, 0x3b, 0x4f, 0x3b, 0x4c, 0x3b, +0x9b0, 0x9ac, 0x9bf, 0x3b, 0x9b8, 0x9cb, 0x9ae, 0x3b, 0x9ae, 0x999, 0x9cd, 0x997, 0x9b2, 0x3b, 0x9ac, 0x9c1, 0x9a7, 0x3b, 0x9ac, 0x9c3, +0x9b9, 0x9b8, 0x9cd, 0x9aa, 0x9a4, 0x9bf, 0x3b, 0x9b6, 0x9c1, 0x995, 0x9cd, 0x9b0, 0x3b, 0x9b6, 0x9a8, 0x9bf, 0x3b, 0x9b0, 0x9ac, 0x9bf, +0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b8, 0x9cb, 0x9ae, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9ae, 0x999, 0x9cd, 0x997, 0x9b2, 0x9ac, 0x9be, 0x9b0, 0x3b, +0x9ac, 0x9c1, 0x9a7, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9ac, 0x9c3, 0x9b9, 0x9b8, 0x9cd, 0x9aa, 0x9a4, 0x9bf, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b6, +0x9c1, 0x995, 0x9cd, 0x9b0, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b6, 0x9a8, 0x9bf, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b0, 0x3b, 0x9b8, 0x9cb, 0x3b, +0x9ae, 0x3b, 0x9ac, 0x9c1, 0x3b, 0x9ac, 0x9c3, 0x3b, 0x9b6, 0x9c1, 0x3b, 0x9b6, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0x3b, 0xf58, 0xf72, 0xf62, +0xf0b, 0x3b, 0xf63, 0xfb7, 0xf42, 0xf0b, 0x3b, 0xf55, 0xf74, 0xf62, 0xf0b, 0x3b, 0xf66, 0xf44, 0xf66, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xf7a, +0xf53, 0xf0b, 0x3b, 0xf49, 0xf72, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, +0xf0b, 0xf58, 0xf72, 0xf42, 0xf0b, 0xf51, 0xf58, 0xf62, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf63, 0xfb7, 0xf42, 0xf0b, 0xf54, 0xf0b, +0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf55, 0xf74, 0xf62, 0xf0b, 0xf56, 0xf74, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf54, 0xf0b, 0xf66, +0xf44, 0xf66, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf66, 0xfa4, 0xf7a, 0xf53, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, +0xf49, 0xf72, 0xf0b, 0xf58, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0x3b, 0xf58, 0xf72, 0xf62, 0x3b, 0xf63, 0xfb7, 0xf42, 0x3b, 0xf55, 0xf74, 0xf62, +0x3b, 0xf66, 0xf44, 0xfb6, 0x3b, 0xf66, 0xfa4, 0xf7a, 0xf53, 0x3b, 0xf49, 0xf72, 0x3b, 0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x75, 0x6e, +0x3b, 0x4d, 0x65, 0x75, 0x2e, 0x3b, 0x4d, 0x65, 0x72, 0x2e, 0x3b, 0x59, 0x61, 0x6f, 0x75, 0x3b, 0x47, 0x77, 0x65, 0x2e, +0x3b, 0x53, 0x61, 0x64, 0x2e, 0x3b, 0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4d, 0x65, 0x75, 0x72, 0x7a, 0x68, +0x3b, 0x4d, 0x65, 0x72, 0x63, 0x2bc, 0x68, 0x65, 0x72, 0x3b, 0x59, 0x61, 0x6f, 0x75, 0x3b, 0x47, 0x77, 0x65, 0x6e, 0x65, +0x72, 0x3b, 0x53, 0x61, 0x64, 0x6f, 0x72, 0x6e, 0x3b, 0x53, 0x75, 0x3b, 0x4c, 0x3b, 0x4d, 0x7a, 0x3b, 0x4d, 0x63, 0x3b, +0x59, 0x3b, 0x47, 0x3b, 0x53, 0x61, 0x3b, 0x43d, 0x434, 0x3b, 0x43f, 0x43d, 0x3b, 0x432, 0x442, 0x3b, 0x441, 0x440, 0x3b, 0x447, +0x442, 0x3b, 0x43f, 0x442, 0x3b, 0x441, 0x431, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x43b, 0x44f, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, +0x435, 0x43b, 0x43d, 0x438, 0x43a, 0x3b, 0x432, 0x442, 0x43e, 0x440, 0x43d, 0x438, 0x43a, 0x3b, 0x441, 0x440, 0x44f, 0x434, 0x430, 0x3b, +0x447, 0x435, 0x442, 0x432, 0x44a, 0x440, 0x442, 0x44a, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x44a, 0x43a, 0x3b, 0x441, 0x44a, 0x431, 0x43e, +0x442, 0x430, 0x3b, 0x43d, 0x3b, 0x43f, 0x3b, 0x432, 0x3b, 0x441, 0x3b, 0x447, 0x3b, 0x43f, 0x3b, 0x441, 0x3b, 0x1010, 0x1014, 0x1004, +0x103a, 0x1039, 0x1002, 0x1014, 0x103d, 0x1031, 0x3b, 0x1010, 0x1014, 0x1004, 0x103a, 0x1039, 0x101c, 0x102c, 0x3b, 0x1021, 0x1004, 0x103a, 0x1039, 0x1002, +0x102b, 0x3b, 0x1017, 0x102f, 0x1012, 0x1039, 0x1013, 0x101f, 0x1030, 0x1038, 0x3b, 0x1000, 0x103c, 0x102c, 0x101e, 0x1015, 0x1010, 0x1031, 0x1038, 0x3b, +0x101e, 0x1031, 0x102c, 0x1000, 0x103c, 0x102c, 0x3b, 0x1005, 0x1014, 0x1031, 0x3b, 0x1010, 0x3b, 0x1010, 0x3b, 0x1021, 0x3b, 0x1017, 0x3b, 0x1000, +0x3b, 0x101e, 0x3b, 0x1005, 0x3b, 0x43d, 0x434, 0x3b, 0x43f, 0x43d, 0x3b, 0x430, 0x45e, 0x3b, 0x441, 0x440, 0x3b, 0x447, 0x446, 0x3b, +0x43f, 0x442, 0x3b, 0x441, 0x431, 0x3b, 0x43d, 0x44f, 0x434, 0x437, 0x435, 0x43b, 0x44f, 0x3b, 0x43f, 0x430, 0x43d, 0x44f, 0x434, 0x437, +0x435, 0x43b, 0x430, 0x43a, 0x3b, 0x430, 0x45e, 0x442, 0x43e, 0x440, 0x430, 0x43a, 0x3b, 0x441, 0x435, 0x440, 0x430, 0x434, 0x430, 0x3b, +0x447, 0x430, 0x446, 0x432, 0x435, 0x440, 0x3b, 0x43f, 0x44f, 0x442, 0x43d, 0x456, 0x446, 0x430, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, +0x430, 0x3b, 0x43d, 0x3b, 0x43f, 0x3b, 0x430, 0x3b, 0x441, 0x3b, 0x447, 0x3b, 0x43f, 0x3b, 0x441, 0x3b, 0x17a2, 0x17b6, 0x1791, 0x17b7, +0x178f, 0x17d2, 0x1799, 0x3b, 0x1785, 0x1793, 0x17d2, 0x1791, 0x3b, 0x17a2, 0x1784, 0x17d2, 0x1782, 0x17b6, 0x179a, 0x3b, 0x1796, 0x17bb, 0x1792, 0x3b, +0x1796, 0x17d2, 0x179a, 0x17a0, 0x3b, 0x179f, 0x17bb, 0x1780, 0x17d2, 0x179a, 0x3b, 0x179f, 0x17c5, 0x179a, 0x17cd, 0x3b, 0x17a2, 0x17b6, 0x1791, 0x17b7, +0x178f, 0x17d2, 0x1799, 0x3b, 0x1785, 0x1793, 0x17d2, 0x1791, 0x3b, 0x17a2, 0x1784, 0x17d2, 0x1782, 0x17b6, 0x179a, 0x3b, 0x1796, 0x17bb, 0x1792, 0x3b, +0x1796, 0x17d2, 0x179a, 0x17a0, 0x179f, 0x17d2, 0x1794, 0x178f, 0x17b7, 0x17cd, 0x3b, 0x179f, 0x17bb, 0x1780, 0x17d2, 0x179a, 0x3b, 0x179f, 0x17c5, 0x179a, +0x17cd, 0x3b, 0x17a2, 0x3b, 0x1785, 0x3b, 0x17a2, 0x3b, 0x1796, 0x3b, 0x1796, 0x3b, 0x179f, 0x3b, 0x179f, 0x3b, 0x17a2, 0x17b6, 0x1791, 0x17b7, +0x178f, 0x17d2, 0x1799, 0x3b, 0x1785, 0x17d0, 0x1793, 0x17d2, 0x1791, 0x3b, 0x17a2, 0x1784, 0x17d2, 0x1782, 0x17b6, 0x179a, 0x3b, 0x1796, 0x17bb, 0x1792, +0x3b, 0x1796, 0x17d2, 0x179a, 0x17a0, 0x179f, 0x17d2, 0x1794, 0x178f, 0x17b7, 0x17cd, 0x3b, 0x179f, 0x17bb, 0x1780, 0x17d2, 0x179a, 0x3b, 0x179f, 0x17c5, +0x179a, 0x17cd, 0x3b, 0x64, 0x67, 0x2e, 0x3b, 0x64, 0x6c, 0x2e, 0x3b, 0x64, 0x74, 0x2e, 0x3b, 0x64, 0x63, 0x2e, 0x3b, 0x64, +0x6a, 0x2e, 0x3b, 0x64, 0x76, 0x2e, 0x3b, 0x64, 0x73, 0x2e, 0x3b, 0x64, 0x69, 0x75, 0x6d, 0x65, 0x6e, 0x67, 0x65, 0x3b, +0x64, 0x69, 0x6c, 0x6c, 0x75, 0x6e, 0x73, 0x3b, 0x64, 0x69, 0x6d, 0x61, 0x72, 0x74, 0x73, 0x3b, 0x64, 0x69, 0x6d, 0x65, +0x63, 0x72, 0x65, 0x73, 0x3b, 0x64, 0x69, 0x6a, 0x6f, 0x75, 0x73, 0x3b, 0x64, 0x69, 0x76, 0x65, 0x6e, 0x64, 0x72, 0x65, +0x73, 0x3b, 0x64, 0x69, 0x73, 0x73, 0x61, 0x62, 0x74, 0x65, 0x3b, 0x64, 0x67, 0x3b, 0x64, 0x6c, 0x3b, 0x64, 0x74, 0x3b, +0x64, 0x63, 0x3b, 0x64, 0x6a, 0x3b, 0x64, 0x76, 0x3b, 0x64, 0x73, 0x3b, 0x5468, 0x65e5, 0x3b, 0x5468, 0x4e00, 0x3b, 0x5468, 0x4e8c, +0x3b, 0x5468, 0x4e09, 0x3b, 0x5468, 0x56db, 0x3b, 0x5468, 0x4e94, 0x3b, 0x5468, 0x516d, 0x3b, 0x661f, 0x671f, 0x65e5, 0x3b, 0x661f, 0x671f, 0x4e00, +0x3b, 0x661f, 0x671f, 0x4e8c, 0x3b, 0x661f, 0x671f, 0x4e09, 0x3b, 0x661f, 0x671f, 0x56db, 0x3b, 0x661f, 0x671f, 0x4e94, 0x3b, 0x661f, 0x671f, 0x516d, +0x3b, 0x65e5, 0x3b, 0x4e00, 0x3b, 0x4e8c, 0x3b, 0x4e09, 0x3b, 0x56db, 0x3b, 0x4e94, 0x3b, 0x516d, 0x3b, 0x9031, 0x65e5, 0x3b, 0x9031, 0x4e00, +0x3b, 0x9031, 0x4e8c, 0x3b, 0x9031, 0x4e09, 0x3b, 0x9031, 0x56db, 0x3b, 0x9031, 0x4e94, 0x3b, 0x9031, 0x516d, 0x3b, 0x6e, 0x65, 0x64, 0x3b, +0x70, 0x6f, 0x6e, 0x3b, 0x75, 0x74, 0x6f, 0x3b, 0x73, 0x72, 0x69, 0x3b, 0x10d, 0x65, 0x74, 0x3b, 0x70, 0x65, 0x74, 0x3b, +0x73, 0x75, 0x62, 0x3b, 0x6e, 0x65, 0x64, 0x6a, 0x65, 0x6c, 0x6a, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x65, 0x64, 0x6a, 0x65, +0x6c, 0x6a, 0x61, 0x6b, 0x3b, 0x75, 0x74, 0x6f, 0x72, 0x61, 0x6b, 0x3b, 0x73, 0x72, 0x69, 0x6a, 0x65, 0x64, 0x61, 0x3b, +0x10d, 0x65, 0x74, 0x76, 0x72, 0x74, 0x61, 0x6b, 0x3b, 0x70, 0x65, 0x74, 0x61, 0x6b, 0x3b, 0x73, 0x75, 0x62, 0x6f, 0x74, +0x61, 0x3b, 0x6e, 0x3b, 0x70, 0x3b, 0x75, 0x3b, 0x73, 0x3b, 0x10d, 0x3b, 0x70, 0x3b, 0x73, 0x3b, 0x4e, 0x3b, 0x50, 0x3b, +0x55, 0x3b, 0x53, 0x3b, 0x10c, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x6e, 0x65, 0x3b, 0x70, 0x6f, 0x3b, 0xfa, 0x74, 0x3b, 0x73, +0x74, 0x3b, 0x10d, 0x74, 0x3b, 0x70, 0xe1, 0x3b, 0x73, 0x6f, 0x3b, 0x6e, 0x65, 0x64, 0x11b, 0x6c, 0x65, 0x3b, 0x70, 0x6f, +0x6e, 0x64, 0x11b, 0x6c, 0xed, 0x3b, 0xfa, 0x74, 0x65, 0x72, 0xfd, 0x3b, 0x73, 0x74, 0x159, 0x65, 0x64, 0x61, 0x3b, 0x10d, +0x74, 0x76, 0x72, 0x74, 0x65, 0x6b, 0x3b, 0x70, 0xe1, 0x74, 0x65, 0x6b, 0x3b, 0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b, +0x4e, 0x3b, 0x50, 0x3b, 0xda, 0x3b, 0x53, 0x3b, 0x10c, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x73, 0xf8, 0x6e, 0x3b, 0x6d, 0x61, +0x6e, 0x3b, 0x74, 0x69, 0x72, 0x3b, 0x6f, 0x6e, 0x73, 0x3b, 0x74, 0x6f, 0x72, 0x3b, 0x66, 0x72, 0x65, 0x3b, 0x6c, 0xf8, +0x72, 0x3b, 0x73, 0xf8, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x6d, 0x61, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x69, 0x72, 0x73, +0x64, 0x61, 0x67, 0x3b, 0x6f, 0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x6f, 0x72, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x66, +0x72, 0x65, 0x64, 0x61, 0x67, 0x3b, 0x6c, 0xf8, 0x72, 0x64, 0x61, 0x67, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x54, 0x3b, 0x4f, +0x3b, 0x54, 0x3b, 0x46, 0x3b, 0x4c, 0x3b, 0x73, 0xf8, 0x6e, 0x2e, 0x3b, 0x6d, 0x61, 0x6e, 0x2e, 0x3b, 0x74, 0x69, 0x72, +0x2e, 0x3b, 0x6f, 0x6e, 0x73, 0x2e, 0x3b, 0x74, 0x6f, 0x72, 0x2e, 0x3b, 0x66, 0x72, 0x65, 0x2e, 0x3b, 0x6c, 0xf8, 0x72, +0x2e, 0x3b, 0x7a, 0x6f, 0x3b, 0x6d, 0x61, 0x3b, 0x64, 0x69, 0x3b, 0x77, 0x6f, 0x3b, 0x64, 0x6f, 0x3b, 0x76, 0x72, 0x3b, +0x7a, 0x61, 0x3b, 0x7a, 0x6f, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x6d, 0x61, 0x61, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x64, 0x69, +0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x77, 0x6f, 0x65, 0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x64, 0x6f, 0x6e, 0x64, 0x65, +0x72, 0x64, 0x61, 0x67, 0x3b, 0x76, 0x72, 0x69, 0x6a, 0x64, 0x61, 0x67, 0x3b, 0x7a, 0x61, 0x74, 0x65, 0x72, 0x64, 0x61, +0x67, 0x3b, 0x5a, 0x3b, 0x4d, 0x3b, 0x44, 0x3b, 0x57, 0x3b, 0x44, 0x3b, 0x56, 0x3b, 0x5a, 0x3b, 0x53, 0x75, 0x2e, 0x3b, +0x4d, 0x2e, 0x3b, 0x54, 0x75, 0x2e, 0x3b, 0x57, 0x2e, 0x3b, 0x54, 0x68, 0x2e, 0x3b, 0x46, 0x2e, 0x3b, 0x53, 0x61, 0x2e, +0x3b, 0x53, 0x75, 0x6e, 0x2e, 0x3b, 0x4d, 0x6f, 0x6e, 0x2e, 0x3b, 0x54, 0x75, 0x65, 0x2e, 0x3b, 0x57, 0x65, 0x64, 0x2e, +0x3b, 0x54, 0x68, 0x75, 0x2e, 0x3b, 0x46, 0x72, 0x69, 0x2e, 0x3b, 0x53, 0x61, 0x74, 0x2e, 0x3b, 0x64, 0x69, 0x3b, 0x6c, +0x75, 0x3b, 0x6d, 0x61, 0x3b, 0x6d, 0x65, 0x3b, 0x135, 0x61, 0x3b, 0x76, 0x65, 0x3b, 0x73, 0x61, 0x3b, 0x64, 0x69, 0x6d, +0x61, 0x6e, 0x109, 0x6f, 0x3b, 0x6c, 0x75, 0x6e, 0x64, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x64, 0x6f, 0x3b, 0x6d, 0x65, 0x72, +0x6b, 0x72, 0x65, 0x64, 0x6f, 0x3b, 0x135, 0x61, 0x16d, 0x64, 0x6f, 0x3b, 0x76, 0x65, 0x6e, 0x64, 0x72, 0x65, 0x64, 0x6f, +0x3b, 0x73, 0x61, 0x62, 0x61, 0x74, 0x6f, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x134, 0x3b, 0x56, 0x3b, +0x53, 0x3b, 0x50, 0x3b, 0x45, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x52, 0x3b, 0x4c, 0x3b, 0x70, 0xfc, 0x68, 0x61, +0x70, 0xe4, 0x65, 0x76, 0x3b, 0x65, 0x73, 0x6d, 0x61, 0x73, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x74, 0x65, 0x69, 0x73, 0x69, +0x70, 0xe4, 0x65, 0x76, 0x3b, 0x6b, 0x6f, 0x6c, 0x6d, 0x61, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x6e, 0x65, 0x6c, 0x6a, 0x61, +0x70, 0xe4, 0x65, 0x76, 0x3b, 0x72, 0x65, 0x65, 0x64, 0x65, 0x3b, 0x6c, 0x61, 0x75, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x73, +0x75, 0x6e, 0x3b, 0x6d, 0xe1, 0x6e, 0x3b, 0x74, 0xfd, 0x73, 0x3b, 0x6d, 0x69, 0x6b, 0x3b, 0x68, 0xf3, 0x73, 0x3b, 0x66, +0x72, 0xed, 0x3b, 0x6c, 0x65, 0x79, 0x3b, 0x73, 0x75, 0x6e, 0x6e, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6d, 0xe1, +0x6e, 0x61, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x74, 0xfd, 0x73, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6d, 0x69, 0x6b, +0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x68, 0xf3, 0x73, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x66, 0x72, 0xed, 0x67, +0x67, 0x6a, 0x61, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6c, 0x65, 0x79, 0x67, 0x61, 0x72, 0x64, 0x61, 0x67, 0x75, 0x72, +0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x54, 0x3b, 0x4d, 0x3b, 0x48, 0x3b, 0x46, 0x3b, 0x4c, 0x3b, 0x73, 0x75, 0x6e, 0x2e, 0x3b, +0x6d, 0xe1, 0x6e, 0x2e, 0x3b, 0x74, 0xfd, 0x73, 0x2e, 0x3b, 0x6d, 0x69, 0x6b, 0x2e, 0x3b, 0x68, 0xf3, 0x73, 0x2e, 0x3b, +0x66, 0x72, 0xed, 0x2e, 0x3b, 0x6c, 0x65, 0x79, 0x2e, 0x3b, 0x73, 0x75, 0x3b, 0x6d, 0x61, 0x3b, 0x74, 0x69, 0x3b, 0x6b, +0x65, 0x3b, 0x74, 0x6f, 0x3b, 0x70, 0x65, 0x3b, 0x6c, 0x61, 0x3b, 0x73, 0x75, 0x6e, 0x6e, 0x75, 0x6e, 0x74, 0x61, 0x69, +0x3b, 0x6d, 0x61, 0x61, 0x6e, 0x61, 0x6e, 0x74, 0x61, 0x69, 0x3b, 0x74, 0x69, 0x69, 0x73, 0x74, 0x61, 0x69, 0x3b, 0x6b, +0x65, 0x73, 0x6b, 0x69, 0x76, 0x69, 0x69, 0x6b, 0x6b, 0x6f, 0x3b, 0x74, 0x6f, 0x72, 0x73, 0x74, 0x61, 0x69, 0x3b, 0x70, +0x65, 0x72, 0x6a, 0x61, 0x6e, 0x74, 0x61, 0x69, 0x3b, 0x6c, 0x61, 0x75, 0x61, 0x6e, 0x74, 0x61, 0x69, 0x3b, 0x53, 0x3b, +0x4d, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x54, 0x3b, 0x50, 0x3b, 0x4c, 0x3b, 0x73, 0x75, 0x6e, 0x6e, 0x75, 0x6e, 0x74, 0x61, +0x69, 0x6e, 0x61, 0x3b, 0x6d, 0x61, 0x61, 0x6e, 0x61, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x74, 0x69, 0x69, 0x73, +0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x6b, 0x65, 0x73, 0x6b, 0x69, 0x76, 0x69, 0x69, 0x6b, 0x6b, 0x6f, 0x6e, 0x61, 0x3b, +0x74, 0x6f, 0x72, 0x73, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x70, 0x65, 0x72, 0x6a, 0x61, 0x6e, 0x74, 0x61, 0x69, 0x6e, +0x61, 0x3b, 0x6c, 0x61, 0x75, 0x61, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x64, 0x69, 0x6d, 0x2e, 0x3b, 0x6c, 0x75, +0x6e, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x6d, 0x65, 0x72, 0x2e, 0x3b, 0x6a, 0x65, 0x75, 0x2e, 0x3b, 0x76, 0x65, +0x6e, 0x2e, 0x3b, 0x73, 0x61, 0x6d, 0x2e, 0x3b, 0x64, 0x69, 0x6d, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x3b, 0x6c, 0x75, 0x6e, +0x64, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x64, 0x69, 0x3b, 0x6d, 0x65, 0x72, 0x63, 0x72, 0x65, 0x64, 0x69, 0x3b, 0x6a, 0x65, +0x75, 0x64, 0x69, 0x3b, 0x76, 0x65, 0x6e, 0x64, 0x72, 0x65, 0x64, 0x69, 0x3b, 0x73, 0x61, 0x6d, 0x65, 0x64, 0x69, 0x3b, +0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x73, 0x69, 0x3b, 0x6d, 0x6f, 0x3b, +0x74, 0x69, 0x3b, 0x77, 0x6f, 0x3b, 0x74, 0x6f, 0x3b, 0x66, 0x72, 0x3b, 0x73, 0x6f, 0x3b, 0x73, 0x6e, 0x65, 0x69, 0x6e, +0x3b, 0x6d, 0x6f, 0x61, 0x6e, 0x64, 0x65, 0x69, 0x3b, 0x74, 0x69, 0x69, 0x73, 0x64, 0x65, 0x69, 0x3b, 0x77, 0x6f, 0x61, +0x6e, 0x73, 0x64, 0x65, 0x69, 0x3b, 0x74, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x73, 0x64, 0x65, 0x69, 0x3b, 0x66, 0x72, 0x65, +0x65, 0x64, 0x3b, 0x73, 0x6e, 0x65, 0x6f, 0x6e, 0x3b, 0x44, 0x69, 0x44, 0x3b, 0x44, 0x69, 0x4c, 0x3b, 0x44, 0x69, 0x4d, +0x3b, 0x44, 0x69, 0x43, 0x3b, 0x44, 0x69, 0x61, 0x3b, 0x44, 0x69, 0x68, 0x3b, 0x44, 0x69, 0x53, 0x3b, 0x44, 0x69, 0x44, +0xf2, 0x6d, 0x68, 0x6e, 0x61, 0x69, 0x63, 0x68, 0x3b, 0x44, 0x69, 0x4c, 0x75, 0x61, 0x69, 0x6e, 0x3b, 0x44, 0x69, 0x4d, +0xe0, 0x69, 0x72, 0x74, 0x3b, 0x44, 0x69, 0x43, 0x69, 0x61, 0x64, 0x61, 0x69, 0x6e, 0x3b, 0x44, 0x69, 0x61, 0x72, 0x44, +0x61, 0x6f, 0x69, 0x6e, 0x3b, 0x44, 0x69, 0x68, 0x41, 0x6f, 0x69, 0x6e, 0x65, 0x3b, 0x44, 0x69, 0x53, 0x61, 0x74, 0x68, +0x61, 0x69, 0x72, 0x6e, 0x65, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x43, 0x3b, 0x41, 0x3b, 0x48, 0x3b, 0x53, 0x3b, +0x44, 0x6f, 0x6d, 0x2e, 0x3b, 0x4c, 0x75, 0x6e, 0x73, 0x3b, 0x4d, 0x61, 0x72, 0x2e, 0x3b, 0x4d, 0xe9, 0x72, 0x2e, 0x3b, +0x58, 0x6f, 0x76, 0x2e, 0x3b, 0x56, 0x65, 0x6e, 0x2e, 0x3b, 0x53, 0xe1, 0x62, 0x2e, 0x3b, 0x44, 0x6f, 0x6d, 0x69, 0x6e, +0x67, 0x6f, 0x3b, 0x4c, 0x75, 0x6e, 0x73, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x3b, 0x4d, 0xe9, 0x72, 0x63, 0x6f, +0x72, 0x65, 0x73, 0x3b, 0x58, 0x6f, 0x76, 0x65, 0x73, 0x3b, 0x56, 0x65, 0x6e, 0x72, 0x65, 0x73, 0x3b, 0x53, 0xe1, 0x62, +0x61, 0x64, 0x6f, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x58, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x64, 0x6f, +0x6d, 0x2e, 0x3b, 0x6c, 0x75, 0x6e, 0x73, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x6d, 0xe9, 0x72, 0x2e, 0x3b, 0x78, 0x6f, +0x76, 0x2e, 0x3b, 0x76, 0x65, 0x6e, 0x2e, 0x3b, 0x73, 0xe1, 0x62, 0x2e, 0x3b, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, +0x3b, 0x6c, 0x75, 0x6e, 0x73, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x3b, 0x6d, 0xe9, 0x72, 0x63, 0x6f, 0x72, 0x65, +0x73, 0x3b, 0x78, 0x6f, 0x76, 0x65, 0x73, 0x3b, 0x76, 0x65, 0x6e, 0x72, 0x65, 0x73, 0x3b, 0x73, 0xe1, 0x62, 0x61, 0x64, +0x6f, 0x3b, 0x64, 0x2e, 0x3b, 0x6c, 0x2e, 0x3b, 0x6d, 0x2e, 0x3b, 0x6d, 0x2e, 0x3b, 0x78, 0x2e, 0x3b, 0x76, 0x2e, 0x3b, +0x73, 0x2e, 0x3b, 0x10d9, 0x10d5, 0x10d8, 0x3b, 0x10dd, 0x10e0, 0x10e8, 0x3b, 0x10e1, 0x10d0, 0x10db, 0x3b, 0x10dd, 0x10d7, 0x10ee, 0x3b, 0x10ee, +0x10e3, 0x10d7, 0x3b, 0x10de, 0x10d0, 0x10e0, 0x3b, 0x10e8, 0x10d0, 0x10d1, 0x3b, 0x10d9, 0x10d5, 0x10d8, 0x10e0, 0x10d0, 0x3b, 0x10dd, 0x10e0, 0x10e8, +0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10e1, 0x10d0, 0x10db, 0x10e8, 0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10dd, 0x10d7, 0x10ee, 0x10e8, +0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10ee, 0x10e3, 0x10d7, 0x10e8, 0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10de, 0x10d0, 0x10e0, 0x10d0, +0x10e1, 0x10d9, 0x10d4, 0x10d5, 0x10d8, 0x3b, 0x10e8, 0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10d9, 0x3b, 0x10dd, 0x3b, 0x10e1, 0x3b, 0x10dd, +0x3b, 0x10ee, 0x3b, 0x10de, 0x3b, 0x10e8, 0x3b, 0x53, 0x6f, 0x3b, 0x4d, 0x6f, 0x3b, 0x44, 0x69, 0x3b, 0x4d, 0x69, 0x3b, 0x44, +0x6f, 0x3b, 0x46, 0x72, 0x3b, 0x53, 0x61, 0x3b, 0x53, 0x6f, 0x6e, 0x6e, 0x74, 0x61, 0x67, 0x3b, 0x4d, 0x6f, 0x6e, 0x74, +0x61, 0x67, 0x3b, 0x44, 0x69, 0x65, 0x6e, 0x73, 0x74, 0x61, 0x67, 0x3b, 0x4d, 0x69, 0x74, 0x74, 0x77, 0x6f, 0x63, 0x68, +0x3b, 0x44, 0x6f, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x74, 0x61, 0x67, 0x3b, 0x46, 0x72, 0x65, 0x69, 0x74, 0x61, 0x67, 0x3b, +0x53, 0x61, 0x6d, 0x73, 0x74, 0x61, 0x67, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x44, 0x3b, 0x4d, 0x3b, 0x44, 0x3b, 0x46, 0x3b, +0x53, 0x3b, 0x53, 0x6f, 0x2e, 0x3b, 0x4d, 0x6f, 0x2e, 0x3b, 0x44, 0x69, 0x2e, 0x3b, 0x4d, 0x69, 0x2e, 0x3b, 0x44, 0x6f, +0x2e, 0x3b, 0x46, 0x72, 0x2e, 0x3b, 0x53, 0x61, 0x2e, 0x3b, 0x39a, 0x3c5, 0x3c1, 0x3b, 0x394, 0x3b5, 0x3c5, 0x3b, 0x3a4, 0x3c1, +0x3af, 0x3b, 0x3a4, 0x3b5, 0x3c4, 0x3b, 0x3a0, 0x3ad, 0x3bc, 0x3b, 0x3a0, 0x3b1, 0x3c1, 0x3b, 0x3a3, 0x3ac, 0x3b2, 0x3b, 0x39a, 0x3c5, +0x3c1, 0x3b9, 0x3b1, 0x3ba, 0x3ae, 0x3b, 0x394, 0x3b5, 0x3c5, 0x3c4, 0x3ad, 0x3c1, 0x3b1, 0x3b, 0x3a4, 0x3c1, 0x3af, 0x3c4, 0x3b7, 0x3b, +0x3a4, 0x3b5, 0x3c4, 0x3ac, 0x3c1, 0x3c4, 0x3b7, 0x3b, 0x3a0, 0x3ad, 0x3bc, 0x3c0, 0x3c4, 0x3b7, 0x3b, 0x3a0, 0x3b1, 0x3c1, 0x3b1, 0x3c3, +0x3ba, 0x3b5, 0x3c5, 0x3ae, 0x3b, 0x3a3, 0x3ac, 0x3b2, 0x3b2, 0x3b1, 0x3c4, 0x3bf, 0x3b, 0x39a, 0x3b, 0x394, 0x3b, 0x3a4, 0x3b, 0x3a4, +0x3b, 0x3a0, 0x3b, 0x3a0, 0x3b, 0x3a3, 0x3b, 0x73, 0x61, 0x70, 0x3b, 0x61, 0x74, 0x61, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x70, +0x69, 0x6e, 0x3b, 0x73, 0x69, 0x73, 0x3b, 0x74, 0x61, 0x6c, 0x3b, 0x61, 0x72, 0x66, 0x3b, 0x73, 0x61, 0x70, 0x61, 0x61, +0x74, 0x3b, 0x61, 0x74, 0x61, 0x61, 0x73, 0x69, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0x6d, 0x61, 0x72, +0x6c, 0x75, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0x70, 0x69, 0x6e, 0x67, 0x61, 0x73, 0x75, 0x6e, 0x6e, +0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0x73, 0x69, 0x73, 0x61, 0x6d, 0x61, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, +0x71, 0x3b, 0x74, 0x61, 0x6c, 0x6c, 0x69, 0x6d, 0x61, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0x61, 0x72, +0x66, 0x69, 0x6e, 0x69, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0x53, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x50, +0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0xab0, 0xab5, 0xabf, 0x3b, 0xab8, 0xacb, 0xaae, 0x3b, 0xaae, 0xa82, 0xa97, 0xab3, 0x3b, +0xaac, 0xac1, 0xaa7, 0x3b, 0xa97, 0xac1, 0xab0, 0xac1, 0x3b, 0xab6, 0xac1, 0xa95, 0xacd, 0xab0, 0x3b, 0xab6, 0xaa8, 0xabf, 0x3b, 0xab0, +0xab5, 0xabf, 0xab5, 0xabe, 0xab0, 0x3b, 0xab8, 0xacb, 0xaae, 0xab5, 0xabe, 0xab0, 0x3b, 0xaae, 0xa82, 0xa97, 0xab3, 0xab5, 0xabe, 0xab0, +0x3b, 0xaac, 0xac1, 0xaa7, 0xab5, 0xabe, 0xab0, 0x3b, 0xa97, 0xac1, 0xab0, 0xac1, 0xab5, 0xabe, 0xab0, 0x3b, 0xab6, 0xac1, 0xa95, 0xacd, +0xab0, 0xab5, 0xabe, 0xab0, 0x3b, 0xab6, 0xaa8, 0xabf, 0xab5, 0xabe, 0xab0, 0x3b, 0xab0, 0x3b, 0xab8, 0xacb, 0x3b, 0xaae, 0xa82, 0x3b, +0xaac, 0xac1, 0x3b, 0xa97, 0xac1, 0x3b, 0xab6, 0xac1, 0x3b, 0xab6, 0x3b, 0x4c, 0x61, 0x68, 0x3b, 0x4c, 0x69, 0x74, 0x3b, 0x54, +0x61, 0x6c, 0x3b, 0x4c, 0x61, 0x72, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x41, 0x73, 0x61, 0x3b, 0x4c, +0x61, 0x68, 0x61, 0x64, 0x69, 0x3b, 0x4c, 0x69, 0x74, 0x69, 0x6e, 0x69, 0x6e, 0x3b, 0x54, 0x61, 0x6c, 0x61, 0x74, 0x61, +0x3b, 0x4c, 0x61, 0x72, 0x61, 0x62, 0x61, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0x4a, 0x75, 0x6d, 0x6d, +0x61, 0x2bc, 0x61, 0x3b, 0x41, 0x73, 0x61, 0x62, 0x61, 0x72, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x54, 0x3b, 0x4c, 0x3b, 0x41, +0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d0, 0x5f3, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d1, 0x5f3, 0x3b, 0x5d9, +0x5d5, 0x5dd, 0x20, 0x5d2, 0x5f3, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d3, 0x5f3, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d4, 0x5f3, 0x3b, +0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d5, 0x5f3, 0x3b, 0x5e9, 0x5d1, 0x5ea, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e8, 0x5d0, 0x5e9, 0x5d5, 0x5df, +0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e9, 0x5e0, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e9, 0x5dc, 0x5d9, 0x5e9, 0x5d9, 0x3b, 0x5d9, +0x5d5, 0x5dd, 0x20, 0x5e8, 0x5d1, 0x5d9, 0x5e2, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d7, 0x5de, 0x5d9, 0x5e9, 0x5d9, 0x3b, 0x5d9, +0x5d5, 0x5dd, 0x20, 0x5e9, 0x5d9, 0x5e9, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e9, 0x5d1, 0x5ea, 0x3b, 0x5d0, 0x5f3, 0x3b, 0x5d1, +0x5f3, 0x3b, 0x5d2, 0x5f3, 0x3b, 0x5d3, 0x5f3, 0x3b, 0x5d4, 0x5f3, 0x3b, 0x5d5, 0x5f3, 0x3b, 0x5e9, 0x5f3, 0x3b, 0x930, 0x935, 0x93f, +0x3b, 0x938, 0x94b, 0x92e, 0x3b, 0x92e, 0x902, 0x917, 0x932, 0x3b, 0x92c, 0x941, 0x927, 0x3b, 0x917, 0x941, 0x930, 0x941, 0x3b, 0x936, +0x941, 0x915, 0x94d, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x3b, 0x930, 0x935, 0x93f, 0x935, 0x93e, 0x930, 0x3b, 0x938, 0x94b, 0x92e, 0x935, +0x93e, 0x930, 0x3b, 0x92e, 0x902, 0x917, 0x932, 0x935, 0x93e, 0x930, 0x3b, 0x92c, 0x941, 0x927, 0x935, 0x93e, 0x930, 0x3b, 0x917, 0x941, +0x930, 0x941, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x935, 0x93e, +0x930, 0x3b, 0x930, 0x3b, 0x938, 0x94b, 0x3b, 0x92e, 0x902, 0x3b, 0x92c, 0x941, 0x3b, 0x917, 0x941, 0x3b, 0x936, 0x941, 0x3b, 0x936, +0x3b, 0x56, 0x3b, 0x48, 0x3b, 0x4b, 0x3b, 0x53, 0x7a, 0x65, 0x3b, 0x43, 0x73, 0x3b, 0x50, 0x3b, 0x53, 0x7a, 0x6f, 0x3b, +0x76, 0x61, 0x73, 0xe1, 0x72, 0x6e, 0x61, 0x70, 0x3b, 0x68, 0xe9, 0x74, 0x66, 0x151, 0x3b, 0x6b, 0x65, 0x64, 0x64, 0x3b, +0x73, 0x7a, 0x65, 0x72, 0x64, 0x61, 0x3b, 0x63, 0x73, 0xfc, 0x74, 0xf6, 0x72, 0x74, 0xf6, 0x6b, 0x3b, 0x70, 0xe9, 0x6e, +0x74, 0x65, 0x6b, 0x3b, 0x73, 0x7a, 0x6f, 0x6d, 0x62, 0x61, 0x74, 0x3b, 0x56, 0x3b, 0x48, 0x3b, 0x4b, 0x3b, 0x53, 0x7a, +0x3b, 0x43, 0x73, 0x3b, 0x50, 0x3b, 0x53, 0x7a, 0x3b, 0x73, 0x75, 0x6e, 0x2e, 0x3b, 0x6d, 0xe1, 0x6e, 0x2e, 0x3b, 0xfe, +0x72, 0x69, 0x2e, 0x3b, 0x6d, 0x69, 0xf0, 0x2e, 0x3b, 0x66, 0x69, 0x6d, 0x2e, 0x3b, 0x66, 0xf6, 0x73, 0x2e, 0x3b, 0x6c, +0x61, 0x75, 0x2e, 0x3b, 0x73, 0x75, 0x6e, 0x6e, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6d, 0xe1, 0x6e, 0x75, 0x64, +0x61, 0x67, 0x75, 0x72, 0x3b, 0xfe, 0x72, 0x69, 0xf0, 0x6a, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6d, 0x69, 0xf0, +0x76, 0x69, 0x6b, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x66, 0x69, 0x6d, 0x6d, 0x74, 0x75, 0x64, 0x61, 0x67, 0x75, +0x72, 0x3b, 0x66, 0xf6, 0x73, 0x74, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6c, 0x61, 0x75, 0x67, 0x61, 0x72, 0x64, +0x61, 0x67, 0x75, 0x72, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0xde, 0x3b, 0x4d, 0x3b, 0x46, 0x3b, 0x46, 0x3b, 0x4c, 0x3b, 0x4d, +0x69, 0x6e, 0x3b, 0x53, 0x65, 0x6e, 0x3b, 0x53, 0x65, 0x6c, 0x3b, 0x52, 0x61, 0x62, 0x3b, 0x4b, 0x61, 0x6d, 0x3b, 0x4a, +0x75, 0x6d, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4d, 0x69, 0x6e, 0x67, 0x67, 0x75, 0x3b, 0x53, 0x65, 0x6e, 0x69, 0x6e, 0x3b, +0x53, 0x65, 0x6c, 0x61, 0x73, 0x61, 0x3b, 0x52, 0x61, 0x62, 0x75, 0x3b, 0x4b, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0x4a, 0x75, +0x6d, 0x61, 0x74, 0x3b, 0x53, 0x61, 0x62, 0x74, 0x75, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x52, 0x3b, 0x4b, 0x3b, +0x4a, 0x3b, 0x53, 0x3b, 0x64, 0x6f, 0x6d, 0x3b, 0x6c, 0x75, 0x6e, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0x65, 0x72, 0x3b, +0x6a, 0x6f, 0x76, 0x3b, 0x76, 0x65, 0x6e, 0x3b, 0x73, 0x61, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, +0x3b, 0x6c, 0x75, 0x6e, 0x65, 0x64, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x65, 0x64, 0x69, 0x3b, 0x6d, 0x65, 0x72, 0x63, +0x75, 0x72, 0x69, 0x64, 0x69, 0x3b, 0x6a, 0x6f, 0x76, 0x65, 0x64, 0x69, 0x3b, 0x76, 0x65, 0x6e, 0x65, 0x72, 0x64, 0x69, +0x3b, 0x73, 0x61, 0x62, 0x62, 0x61, 0x74, 0x6f, 0x3b, 0x64, 0x3b, 0x6c, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x6a, 0x3b, 0x76, +0x3b, 0x73, 0x3b, 0x44, 0x6f, 0x6d, 0x68, 0x3b, 0x4c, 0x75, 0x61, 0x6e, 0x3b, 0x4d, 0xe1, 0x69, 0x72, 0x74, 0x3b, 0x43, +0xe9, 0x61, 0x64, 0x3b, 0x44, 0xe9, 0x61, 0x72, 0x3b, 0x41, 0x6f, 0x69, 0x6e, 0x65, 0x3b, 0x53, 0x61, 0x74, 0x68, 0x3b, +0x44, 0xe9, 0x20, 0x44, 0x6f, 0x6d, 0x68, 0x6e, 0x61, 0x69, 0x67, 0x68, 0x3b, 0x44, 0xe9, 0x20, 0x4c, 0x75, 0x61, 0x69, +0x6e, 0x3b, 0x44, 0xe9, 0x20, 0x4d, 0xe1, 0x69, 0x72, 0x74, 0x3b, 0x44, 0xe9, 0x20, 0x43, 0xe9, 0x61, 0x64, 0x61, 0x6f, +0x69, 0x6e, 0x3b, 0x44, 0xe9, 0x61, 0x72, 0x64, 0x61, 0x6f, 0x69, 0x6e, 0x3b, 0x44, 0xe9, 0x20, 0x68, 0x41, 0x6f, 0x69, +0x6e, 0x65, 0x3b, 0x44, 0xe9, 0x20, 0x53, 0x61, 0x74, 0x68, 0x61, 0x69, 0x72, 0x6e, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, +0x3b, 0x43, 0x3b, 0x44, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x64, 0x6f, 0x6d, 0x3b, 0x6c, 0x75, 0x6e, 0x3b, 0x6d, 0x61, 0x72, +0x3b, 0x6d, 0x65, 0x72, 0x3b, 0x67, 0x69, 0x6f, 0x3b, 0x76, 0x65, 0x6e, 0x3b, 0x73, 0x61, 0x62, 0x3b, 0x64, 0x6f, 0x6d, +0x65, 0x6e, 0x69, 0x63, 0x61, 0x3b, 0x6c, 0x75, 0x6e, 0x65, 0x64, 0xec, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x65, 0x64, 0xec, +0x3b, 0x6d, 0x65, 0x72, 0x63, 0x6f, 0x6c, 0x65, 0x64, 0xec, 0x3b, 0x67, 0x69, 0x6f, 0x76, 0x65, 0x64, 0xec, 0x3b, 0x76, +0x65, 0x6e, 0x65, 0x72, 0x64, 0xec, 0x3b, 0x73, 0x61, 0x62, 0x61, 0x74, 0x6f, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, +0x4d, 0x3b, 0x47, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x65e5, 0x3b, 0x6708, 0x3b, 0x706b, 0x3b, 0x6c34, 0x3b, 0x6728, 0x3b, 0x91d1, 0x3b, +0x571f, 0x3b, 0x65e5, 0x66dc, 0x65e5, 0x3b, 0x6708, 0x66dc, 0x65e5, 0x3b, 0x706b, 0x66dc, 0x65e5, 0x3b, 0x6c34, 0x66dc, 0x65e5, 0x3b, 0x6728, 0x66dc, +0x65e5, 0x3b, 0x91d1, 0x66dc, 0x65e5, 0x3b, 0x571f, 0x66dc, 0x65e5, 0x3b, 0x41, 0x68, 0x64, 0x3b, 0x53, 0x65, 0x6e, 0x3b, 0x53, 0x65, +0x6c, 0x3b, 0x52, 0x61, 0x62, 0x3b, 0x4b, 0x61, 0x6d, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x41, 0x68, +0x61, 0x64, 0x3b, 0x53, 0x65, 0x6e, 0x69, 0x6e, 0x3b, 0x53, 0x65, 0x6c, 0x61, 0x73, 0x61, 0x3b, 0x52, 0x61, 0x62, 0x75, +0x3b, 0x4b, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x3b, 0x53, 0x61, 0x62, 0x74, 0x75, 0x3b, 0x41, +0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x52, 0x3b, 0x4b, 0x3b, 0x4a, 0x3b, 0x53, 0x3b, 0xcad, 0xcbe, 0xca8, 0xcc1, 0x3b, 0xcb8, 0xccb, +0xcae, 0x3b, 0xcae, 0xc82, 0xc97, 0xcb3, 0x3b, 0xcac, 0xcc1, 0xca7, 0x3b, 0xc97, 0xcc1, 0xcb0, 0xcc1, 0x3b, 0xcb6, 0xcc1, 0xc95, 0xccd, +0xcb0, 0x3b, 0xcb6, 0xca8, 0xcbf, 0x3b, 0xcad, 0xcbe, 0xca8, 0xcc1, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcb8, 0xccb, 0xcae, 0xcb5, 0xcbe, 0xcb0, +0x3b, 0xcae, 0xc82, 0xc97, 0xcb3, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcac, 0xcc1, 0xca7, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xc97, 0xcc1, 0xcb0, 0xcc1, +0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcb6, 0xcc1, 0xc95, 0xccd, 0xcb0, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcb6, 0xca8, 0xcbf, 0xcb5, 0xcbe, 0xcb0, 0x3b, +0xcad, 0xcbe, 0x3b, 0xcb8, 0xccb, 0x3b, 0xcae, 0xc82, 0x3b, 0xcac, 0xcc1, 0x3b, 0xc97, 0xcc1, 0x3b, 0xcb6, 0xcc1, 0x3b, 0xcb6, 0x3b, +0x622, 0x62a, 0x6be, 0x648, 0x627, 0x631, 0x3b, 0x698, 0x654, 0x646, 0x65b, 0x62f, 0x655, 0x631, 0x648, 0x627, 0x631, 0x3b, 0x628, 0x648, +0x65a, 0x645, 0x648, 0x627, 0x631, 0x3b, 0x628, 0x648, 0x62f, 0x648, 0x627, 0x631, 0x3b, 0x628, 0x631, 0x65b, 0x66e, 0x6ea, 0x633, 0x648, +0x627, 0x631, 0x3b, 0x62c, 0x64f, 0x645, 0x6c1, 0x3b, 0x628, 0x679, 0x648, 0x627, 0x631, 0x3b, 0x627, 0x64e, 0x62a, 0x6be, 0x648, 0x627, +0x631, 0x3b, 0x698, 0x654, 0x646, 0x65b, 0x62f, 0x631, 0x655, 0x631, 0x648, 0x627, 0x631, 0x3b, 0x628, 0x648, 0x65a, 0x645, 0x648, 0x627, +0x631, 0x3b, 0x628, 0x648, 0x62f, 0x648, 0x627, 0x631, 0x3b, 0x628, 0x631, 0x65b, 0x66e, 0x6ea, 0x633, 0x648, 0x627, 0x631, 0x3b, 0x62c, +0x64f, 0x645, 0x6c1, 0x3b, 0x628, 0x679, 0x648, 0x627, 0x631, 0x3b, 0x627, 0x3b, 0x698, 0x3b, 0x628, 0x3b, 0x628, 0x3b, 0x628, 0x3b, +0x62c, 0x3b, 0x628, 0x3b, 0x436, 0x441, 0x3b, 0x434, 0x441, 0x3b, 0x441, 0x441, 0x3b, 0x441, 0x440, 0x3b, 0x431, 0x441, 0x3b, 0x436, +0x43c, 0x3b, 0x441, 0x431, 0x3b, 0x436, 0x435, 0x43a, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x434, 0x4af, 0x439, 0x441, 0x435, 0x43d, +0x431, 0x456, 0x3b, 0x441, 0x435, 0x439, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x441, 0x4d9, 0x440, 0x441, 0x435, 0x43d, 0x431, 0x456, +0x3b, 0x431, 0x435, 0x439, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x436, 0x4b1, 0x43c, 0x430, 0x3b, 0x441, 0x435, 0x43d, 0x431, 0x456, +0x3b, 0x416, 0x3b, 0x414, 0x3b, 0x421, 0x3b, 0x421, 0x3b, 0x411, 0x3b, 0x416, 0x3b, 0x421, 0x3b, 0x63, 0x79, 0x75, 0x2e, 0x3b, +0x6d, 0x62, 0x65, 0x2e, 0x3b, 0x6b, 0x61, 0x62, 0x2e, 0x3b, 0x67, 0x74, 0x75, 0x2e, 0x3b, 0x6b, 0x61, 0x6e, 0x2e, 0x3b, +0x67, 0x6e, 0x75, 0x2e, 0x3b, 0x67, 0x6e, 0x64, 0x2e, 0x3b, 0x4b, 0x75, 0x20, 0x63, 0x79, 0x75, 0x6d, 0x77, 0x65, 0x72, +0x75, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x6d, 0x62, 0x65, 0x72, 0x65, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x6b, 0x61, +0x62, 0x69, 0x72, 0x69, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4b, 0x75, 0x77, +0x61, 0x20, 0x6b, 0x61, 0x6e, 0x65, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x75, 0x3b, 0x4b, +0x75, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x74, 0x75, 0x3b, 0x436, 0x435, 0x43a, 0x2e, 0x3b, 0x434, +0x4af, 0x439, 0x2e, 0x3b, 0x448, 0x435, 0x439, 0x448, 0x2e, 0x3b, 0x448, 0x430, 0x440, 0x448, 0x2e, 0x3b, 0x431, 0x435, 0x439, 0x448, +0x2e, 0x3b, 0x436, 0x443, 0x43c, 0x430, 0x3b, 0x438, 0x448, 0x43c, 0x2e, 0x3b, 0x436, 0x435, 0x43a, 0x448, 0x435, 0x43c, 0x431, 0x438, +0x3b, 0x434, 0x4af, 0x439, 0x448, 0x4e9, 0x43c, 0x431, 0x4af, 0x3b, 0x448, 0x435, 0x439, 0x448, 0x435, 0x43c, 0x431, 0x438, 0x3b, 0x448, +0x430, 0x440, 0x448, 0x435, 0x43c, 0x431, 0x438, 0x3b, 0x431, 0x435, 0x439, 0x448, 0x435, 0x43c, 0x431, 0x438, 0x3b, 0x436, 0x443, 0x43c, +0x430, 0x3b, 0x438, 0x448, 0x435, 0x43c, 0x431, 0x438, 0x3b, 0x416, 0x3b, 0x414, 0x3b, 0x428, 0x3b, 0x428, 0x3b, 0x411, 0x3b, 0x416, +0x3b, 0x418, 0x3b, 0xc77c, 0x3b, 0xc6d4, 0x3b, 0xd654, 0x3b, 0xc218, 0x3b, 0xbaa9, 0x3b, 0xae08, 0x3b, 0xd1a0, 0x3b, 0xc77c, 0xc694, 0xc77c, +0x3b, 0xc6d4, 0xc694, 0xc77c, 0x3b, 0xd654, 0xc694, 0xc77c, 0x3b, 0xc218, 0xc694, 0xc77c, 0x3b, 0xbaa9, 0xc694, 0xc77c, 0x3b, 0xae08, 0xc694, 0xc77c, +0x3b, 0xd1a0, 0xc694, 0xc77c, 0x3b, 0x79, 0x15f, 0x3b, 0x64, 0x15f, 0x3b, 0x73, 0x15f, 0x3b, 0xe7, 0x15f, 0x3b, 0x70, 0x15f, 0x3b, +0xee, 0x6e, 0x3b, 0x15f, 0x3b, 0x79, 0x65, 0x6b, 0x15f, 0x65, 0x6d, 0x3b, 0x64, 0x75, 0x15f, 0x65, 0x6d, 0x3b, 0x73, 0xea, +0x15f, 0x65, 0x6d, 0x3b, 0xe7, 0x61, 0x72, 0x15f, 0x65, 0x6d, 0x3b, 0x70, 0xea, 0x6e, 0x63, 0x15f, 0x65, 0x6d, 0x3b, 0xee, +0x6e, 0x3b, 0x15f, 0x65, 0x6d, 0xee, 0x3b, 0x59, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0xc7, 0x3b, 0x50, 0x3b, 0xce, 0x3b, 0x15e, +0x3b, 0x63, 0x75, 0x2e, 0x3b, 0x6d, 0x62, 0x65, 0x2e, 0x3b, 0x6b, 0x61, 0x62, 0x2e, 0x3b, 0x67, 0x74, 0x75, 0x2e, 0x3b, +0x6b, 0x61, 0x6e, 0x2e, 0x3b, 0x67, 0x6e, 0x75, 0x2e, 0x3b, 0x67, 0x6e, 0x64, 0x2e, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x2019, +0x69, 0x6e, 0x64, 0x77, 0x69, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x61, 0x20, 0x6d, 0x62, 0x65, 0x72, 0x65, 0x3b, 0x4b, 0x75, +0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, +0x61, 0x74, 0x75, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x65, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x61, +0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x75, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x64, +0x61, 0x74, 0x75, 0x3b, 0xead, 0xeb2, 0xe97, 0xeb4, 0xe94, 0x3b, 0xe88, 0xeb1, 0xe99, 0x3b, 0xead, 0xeb1, 0xe87, 0xe84, 0xeb2, 0xe99, +0x3b, 0xe9e, 0xeb8, 0xe94, 0x3b, 0xe9e, 0xeb0, 0xeab, 0xeb1, 0xe94, 0x3b, 0xeaa, 0xeb8, 0xe81, 0x3b, 0xec0, 0xeaa, 0xebb, 0xeb2, 0x3b, +0xea7, 0xeb1, 0xe99, 0xead, 0xeb2, 0xe97, 0xeb4, 0xe94, 0x3b, 0xea7, 0xeb1, 0xe99, 0xe88, 0xeb1, 0xe99, 0x3b, 0xea7, 0xeb1, 0xe99, 0xead, +0xeb1, 0xe87, 0xe84, 0xeb2, 0xe99, 0x3b, 0xea7, 0xeb1, 0xe99, 0xe9e, 0xeb8, 0xe94, 0x3b, 0xea7, 0xeb1, 0xe99, 0xe9e, 0xeb0, 0xeab, 0xeb1, +0xe94, 0x3b, 0xea7, 0xeb1, 0xe99, 0xeaa, 0xeb8, 0xe81, 0x3b, 0xea7, 0xeb1, 0xe99, 0xec0, 0xeaa, 0xebb, 0xeb2, 0x3b, 0xead, 0xeb2, 0x3b, +0xe88, 0x3b, 0xead, 0x3b, 0xe9e, 0x3b, 0xe9e, 0xeab, 0x3b, 0xeaa, 0xeb8, 0x3b, 0xeaa, 0x3b, 0x53, 0x76, 0x113, 0x74, 0x64, 0x2e, +0x3b, 0x50, 0x69, 0x72, 0x6d, 0x64, 0x2e, 0x3b, 0x4f, 0x74, 0x72, 0x64, 0x2e, 0x3b, 0x54, 0x72, 0x65, 0x161, 0x64, 0x2e, +0x3b, 0x43, 0x65, 0x74, 0x75, 0x72, 0x74, 0x64, 0x2e, 0x3b, 0x50, 0x69, 0x65, 0x6b, 0x74, 0x64, 0x2e, 0x3b, 0x53, 0x65, +0x73, 0x74, 0x64, 0x2e, 0x3b, 0x53, 0x76, 0x113, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x50, 0x69, 0x72, 0x6d, 0x64, +0x69, 0x65, 0x6e, 0x61, 0x3b, 0x4f, 0x74, 0x72, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x54, 0x72, 0x65, 0x161, 0x64, 0x69, +0x65, 0x6e, 0x61, 0x3b, 0x43, 0x65, 0x74, 0x75, 0x72, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x50, 0x69, 0x65, 0x6b, +0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x53, 0x65, 0x73, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x53, 0x3b, 0x50, +0x3b, 0x4f, 0x3b, 0x54, 0x3b, 0x43, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x73, 0x76, 0x113, 0x74, 0x64, 0x2e, 0x3b, 0x70, 0x69, +0x72, 0x6d, 0x64, 0x2e, 0x3b, 0x6f, 0x74, 0x72, 0x64, 0x2e, 0x3b, 0x74, 0x72, 0x65, 0x161, 0x64, 0x2e, 0x3b, 0x63, 0x65, +0x74, 0x75, 0x72, 0x74, 0x64, 0x2e, 0x3b, 0x70, 0x69, 0x65, 0x6b, 0x74, 0x64, 0x2e, 0x3b, 0x73, 0x65, 0x73, 0x74, 0x64, +0x2e, 0x3b, 0x73, 0x76, 0x113, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x70, 0x69, 0x72, 0x6d, 0x64, 0x69, 0x65, 0x6e, +0x61, 0x3b, 0x6f, 0x74, 0x72, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x74, 0x72, 0x65, 0x161, 0x64, 0x69, 0x65, 0x6e, 0x61, +0x3b, 0x63, 0x65, 0x74, 0x75, 0x72, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x70, 0x69, 0x65, 0x6b, 0x74, 0x64, 0x69, +0x65, 0x6e, 0x61, 0x3b, 0x73, 0x65, 0x73, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x65, 0x79, 0x65, 0x3b, 0x79, 0x62, +0x6f, 0x3b, 0x6d, 0x62, 0x6c, 0x3b, 0x6d, 0x73, 0x74, 0x3b, 0x6d, 0x69, 0x6e, 0x3b, 0x6d, 0x74, 0x6e, 0x3b, 0x6d, 0x70, +0x73, 0x3b, 0x65, 0x79, 0x65, 0x6e, 0x67, 0x61, 0x3b, 0x6d, 0x6f, 0x6b, 0x254, 0x6c, 0x254, 0x20, 0x6d, 0x77, 0x61, 0x20, +0x79, 0x61, 0x6d, 0x62, 0x6f, 0x3b, 0x6d, 0x6f, 0x6b, 0x254, 0x6c, 0x254, 0x20, 0x6d, 0x77, 0x61, 0x20, 0x6d, 0xed, 0x62, +0x61, 0x6c, 0xe9, 0x3b, 0x6d, 0x6f, 0x6b, 0x254, 0x6c, 0x254, 0x20, 0x6d, 0x77, 0x61, 0x20, 0x6d, 0xed, 0x73, 0xe1, 0x74, +0x6f, 0x3b, 0x6d, 0x6f, 0x6b, 0x254, 0x6c, 0x254, 0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x6e, 0xe9, 0x69, 0x3b, 0x6d, 0x6f, +0x6b, 0x254, 0x6c, 0x254, 0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x74, 0xe1, 0x6e, 0x6f, 0x3b, 0x6d, 0x70, 0x254, 0x301, 0x73, +0x254, 0x3b, 0x65, 0x3b, 0x79, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x70, 0x3b, 0x73, 0x6b, 0x3b, 0x70, +0x72, 0x3b, 0x61, 0x6e, 0x3b, 0x74, 0x72, 0x3b, 0x6b, 0x74, 0x3b, 0x70, 0x6e, 0x3b, 0x161, 0x74, 0x3b, 0x73, 0x65, 0x6b, +0x6d, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x70, 0x69, 0x72, 0x6d, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, +0x3b, 0x61, 0x6e, 0x74, 0x72, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x74, 0x72, 0x65, 0x10d, 0x69, 0x61, 0x64, +0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x6b, 0x65, 0x74, 0x76, 0x69, 0x72, 0x74, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, +0x3b, 0x70, 0x65, 0x6e, 0x6b, 0x74, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x161, 0x65, 0x161, 0x74, 0x61, 0x64, +0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x53, 0x3b, 0x50, 0x3b, 0x41, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x50, 0x3b, 0x160, 0x3b, +0x43d, 0x435, 0x434, 0x2e, 0x3b, 0x43f, 0x43e, 0x43d, 0x2e, 0x3b, 0x432, 0x442, 0x43e, 0x2e, 0x3b, 0x441, 0x440, 0x435, 0x2e, 0x3b, +0x447, 0x435, 0x442, 0x2e, 0x3b, 0x43f, 0x435, 0x442, 0x2e, 0x3b, 0x441, 0x430, 0x431, 0x2e, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x43b, +0x430, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x43b, 0x43d, 0x438, 0x43a, 0x3b, 0x432, 0x442, 0x43e, 0x440, 0x43d, 0x438, 0x43a, +0x3b, 0x441, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x440, 0x442, 0x43e, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x43e, +0x43a, 0x3b, 0x441, 0x430, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x43d, 0x435, 0x434, 0x2e, 0x3b, 0x43f, 0x43e, 0x43d, 0x2e, 0x3b, 0x432, +0x442, 0x2e, 0x3b, 0x441, 0x440, 0x435, 0x2e, 0x3b, 0x447, 0x435, 0x442, 0x2e, 0x3b, 0x43f, 0x435, 0x442, 0x2e, 0x3b, 0x441, 0x430, +0x431, 0x2e, 0x3b, 0x41, 0x6c, 0x61, 0x68, 0x3b, 0x41, 0x6c, 0x61, 0x74, 0x73, 0x3b, 0x54, 0x61, 0x6c, 0x3b, 0x41, 0x6c, +0x61, 0x72, 0x3b, 0x41, 0x6c, 0x61, 0x6b, 0x3b, 0x5a, 0x6f, 0x6d, 0x3b, 0x41, 0x73, 0x61, 0x62, 0x3b, 0x41, 0x6c, 0x61, +0x68, 0x61, 0x64, 0x79, 0x3b, 0x41, 0x6c, 0x61, 0x74, 0x73, 0x69, 0x6e, 0x61, 0x69, 0x6e, 0x79, 0x3b, 0x54, 0x61, 0x6c, +0x61, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x72, 0x6f, 0x62, 0x69, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x6b, 0x61, 0x6d, 0x69, +0x73, 0x79, 0x3b, 0x5a, 0x6f, 0x6d, 0x61, 0x3b, 0x41, 0x73, 0x61, 0x62, 0x6f, 0x74, 0x73, 0x79, 0x3b, 0x41, 0x3b, 0x41, +0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x5a, 0x3b, 0x41, 0x3b, 0x41, 0x68, 0x64, 0x3b, 0x49, 0x73, 0x6e, 0x3b, 0x53, +0x65, 0x6c, 0x3b, 0x52, 0x61, 0x62, 0x3b, 0x4b, 0x68, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x41, +0x68, 0x61, 0x64, 0x3b, 0x49, 0x73, 0x6e, 0x69, 0x6e, 0x3b, 0x53, 0x65, 0x6c, 0x61, 0x73, 0x61, 0x3b, 0x52, 0x61, 0x62, +0x75, 0x3b, 0x4b, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x61, 0x74, 0x3b, 0x53, 0x61, 0x62, 0x74, +0x75, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x53, 0x3b, 0x52, 0x3b, 0x4b, 0x3b, 0x4a, 0x3b, 0x53, 0x3b, 0xd1e, 0xd3e, 0xd2f, 0xd7c, +0x3b, 0xd24, 0xd3f, 0xd19, 0xd4d, 0xd15, 0xd7e, 0x3b, 0xd1a, 0xd4a, 0xd35, 0xd4d, 0xd35, 0x3b, 0xd2c, 0xd41, 0xd27, 0xd7b, 0x3b, 0xd35, +0xd4d, 0xd2f, 0xd3e, 0xd34, 0xd02, 0x3b, 0xd35, 0xd46, 0xd33, 0xd4d, 0xd33, 0xd3f, 0x3b, 0xd36, 0xd28, 0xd3f, 0x3b, 0xd1e, 0xd3e, 0xd2f, +0xd31, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd24, 0xd3f, 0xd19, 0xd4d, 0xd15, 0xd33, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd1a, +0xd4a, 0xd35, 0xd4d, 0xd35, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd2c, 0xd41, 0xd27, 0xd28, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, +0xd35, 0xd4d, 0xd2f, 0xd3e, 0xd34, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd35, 0xd46, 0xd33, 0xd4d, 0xd33, 0xd3f, 0xd2f, 0xd3e, 0xd34, +0xd4d, 0x200c, 0xd1a, 0x3b, 0xd36, 0xd28, 0xd3f, 0xd2f, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd1e, 0xd3e, 0x3b, 0xd24, 0xd3f, 0x3b, +0xd1a, 0xd4a, 0x3b, 0xd2c, 0xd41, 0x3b, 0xd35, 0xd4d, 0xd2f, 0xd3e, 0x3b, 0xd35, 0xd46, 0x3b, 0xd36, 0x3b, 0xd1e, 0xd3e, 0xd2f, 0xd31, +0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd24, 0xd3f, 0xd19, 0xd4d, 0xd15, 0xd33, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd1a, 0xd4a, +0xd35, 0xd4d, 0xd35, 0xd3e, 0xd34, 0xd4d, 0xd1a, 0x3b, 0xd2c, 0xd41, 0xd27, 0xd28, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd35, 0xd4d, +0xd2f, 0xd3e, 0xd34, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd35, 0xd46, 0xd33, 0xd4d, 0xd33, 0xd3f, 0xd2f, 0xd3e, 0xd34, 0xd4d, 0x200c, +0xd1a, 0x3b, 0xd36, 0xd28, 0xd3f, 0xd2f, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd1e, 0x3b, 0xd24, 0xd3f, 0x3b, 0xd1a, 0xd4a, 0x3b, +0xd2c, 0xd41, 0x3b, 0xd35, 0xd4d, 0xd2f, 0xd3e, 0x3b, 0xd35, 0xd46, 0x3b, 0xd36, 0x3b, 0x126, 0x61, 0x64, 0x3b, 0x54, 0x6e, 0x65, +0x3b, 0x54, 0x6c, 0x69, 0x3b, 0x45, 0x72, 0x62, 0x3b, 0x126, 0x61, 0x6d, 0x3b, 0x120, 0x69, 0x6d, 0x3b, 0x53, 0x69, 0x62, +0x3b, 0x49, 0x6c, 0x2d, 0x126, 0x61, 0x64, 0x64, 0x3b, 0x49, 0x74, 0x2d, 0x54, 0x6e, 0x65, 0x6a, 0x6e, 0x3b, 0x49, 0x74, +0x2d, 0x54, 0x6c, 0x69, 0x65, 0x74, 0x61, 0x3b, 0x4c, 0x2d, 0x45, 0x72, 0x62, 0x67, 0x127, 0x61, 0x3b, 0x49, 0x6c, 0x2d, +0x126, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0x49, 0x6c, 0x2d, 0x120, 0x69, 0x6d, 0x67, 0x127, 0x61, 0x3b, 0x49, 0x73, 0x2d, 0x53, +0x69, 0x62, 0x74, 0x3b, 0x126, 0x64, 0x3b, 0x54, 0x6e, 0x3b, 0x54, 0x6c, 0x3b, 0x45, 0x72, 0x3b, 0x126, 0x6d, 0x3b, 0x120, +0x6d, 0x3b, 0x53, 0x62, 0x3b, 0x126, 0x64, 0x3b, 0x54, 0x3b, 0x54, 0x6c, 0x3b, 0x45, 0x72, 0x3b, 0x126, 0x6d, 0x3b, 0x120, +0x6d, 0x3b, 0x53, 0x62, 0x3b, 0x54, 0x61, 0x70, 0x3b, 0x48, 0x69, 0x6e, 0x3b, 0x54, 0x16b, 0x3b, 0x41, 0x70, 0x61, 0x3b, +0x50, 0x61, 0x72, 0x3b, 0x4d, 0x65, 0x72, 0x3b, 0x48, 0x6f, 0x72, 0x3b, 0x52, 0x101, 0x74, 0x61, 0x70, 0x75, 0x3b, 0x52, +0x101, 0x68, 0x69, 0x6e, 0x61, 0x3b, 0x52, 0x101, 0x74, 0x16b, 0x3b, 0x52, 0x101, 0x61, 0x70, 0x61, 0x3b, 0x52, 0x101, 0x70, +0x61, 0x72, 0x65, 0x3b, 0x52, 0x101, 0x6d, 0x65, 0x72, 0x65, 0x3b, 0x52, 0x101, 0x68, 0x6f, 0x72, 0x6f, 0x69, 0x3b, 0x54, +0x3b, 0x48, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x50, 0x3b, 0x4d, 0x3b, 0x48, 0x3b, 0x930, 0x935, 0x93f, 0x3b, 0x938, 0x94b, 0x92e, 0x3b, 0x92e, 0x902, 0x917, 0x933, 0x3b, 0x92c, 0x941, 0x927, 0x3b, 0x917, 0x941, 0x930, 0x941, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x3b, 0x930, 0x935, 0x93f, 0x935, 0x93e, 0x930, 0x3b, 0x938, 0x94b, 0x92e, 0x935, 0x93e, 0x930, 0x3b, 0x92e, 0x902, 0x917, 0x933, 0x935, 0x93e, 0x930, 0x3b, 0x92c, 0x941, 0x927, 0x935, 0x93e, 0x930, 0x3b, 0x917, 0x941, 0x930, 0x941, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x935, 0x93e, 0x930, 0x3b, 0x41d, 0x44f, -0x3b, 0x414, 0x430, 0x3b, 0x41c, 0x44f, 0x3b, 0x41b, 0x445, 0x3b, 0x41f, 0x4af, 0x3b, 0x411, 0x430, 0x3b, 0x411, 0x44f, 0x3b, 0x43d, -0x44f, 0x43c, 0x3b, 0x434, 0x430, 0x432, 0x430, 0x430, 0x3b, 0x43c, 0x44f, 0x433, 0x43c, 0x430, 0x440, 0x3b, 0x43b, 0x445, 0x430, 0x433, -0x432, 0x430, 0x3b, 0x43f, 0x4af, 0x440, 0x44d, 0x432, 0x3b, 0x431, 0x430, 0x430, 0x441, 0x430, 0x43d, 0x3b, 0x431, 0x44f, 0x43c, 0x431, -0x430, 0x3b, 0x906, 0x907, 0x924, 0x3b, 0x938, 0x94b, 0x92e, 0x3b, 0x92e, 0x919, 0x94d, 0x917, 0x932, 0x3b, 0x92c, 0x941, 0x927, 0x3b, -0x92c, 0x93f, 0x939, 0x93f, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x3b, 0x906, 0x907, 0x924, 0x92c, 0x93e, -0x930, 0x3b, 0x938, 0x94b, 0x92e, 0x92c, 0x93e, 0x930, 0x3b, 0x92e, 0x919, 0x94d, 0x917, 0x932, 0x92c, 0x93e, 0x930, 0x3b, 0x92c, 0x941, -0x927, 0x92c, 0x93e, 0x930, 0x3b, 0x92c, 0x93f, 0x939, 0x93f, 0x92c, 0x93e, 0x930, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x92c, 0x93e, -0x930, 0x3b, 0x936, 0x928, 0x93f, 0x92c, 0x93e, 0x930, 0x3b, 0x906, 0x3b, 0x938, 0x94b, 0x3b, 0x92e, 0x3b, 0x92c, 0x941, 0x3b, 0x92c, -0x93f, 0x3b, 0x936, 0x941, 0x3b, 0x936, 0x3b, 0xb30, 0xb2c, 0xb3f, 0x3b, 0xb38, 0xb4b, 0xb2e, 0x3b, 0xb2e, 0xb19, 0xb4d, 0xb17, 0xb33, -0x3b, 0xb2c, 0xb41, 0xb27, 0x3b, 0xb17, 0xb41, 0xb30, 0xb41, 0x3b, 0xb36, 0xb41, 0xb15, 0xb4d, 0xb30, 0x3b, 0xb36, 0xb28, 0xb3f, 0x3b, -0xb30, 0xb2c, 0xb3f, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb38, 0xb4b, 0xb2e, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb2e, 0xb19, 0xb4d, 0xb17, 0xb33, 0xb2c, -0xb3e, 0xb30, 0x3b, 0xb2c, 0xb41, 0xb27, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb17, 0xb41, 0xb30, 0xb41, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb36, 0xb41, -0xb15, 0xb4d, 0xb30, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb36, 0xb28, 0xb3f, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb30, 0x3b, 0xb38, 0xb4b, 0x3b, 0xb2e, -0x3b, 0xb2c, 0xb41, 0x3b, 0xb17, 0xb41, 0x3b, 0xb36, 0xb41, 0x3b, 0xb36, 0x3b, 0x64a, 0x648, 0x646, 0x6cd, 0x3b, 0x62f, 0x648, 0x646, -0x6cd, 0x3b, 0x62f, 0x631, 0x6d0, 0x646, 0x6cd, 0x3b, 0x685, 0x644, 0x631, 0x646, 0x6cd, 0x3b, 0x67e, 0x64a, 0x646, 0x681, 0x646, 0x6cd, -0x3b, 0x62c, 0x645, 0x639, 0x647, 0x3b, 0x627, 0x648, 0x646, 0x6cd, 0x3b, 0x6cc, 0x6a9, 0x634, 0x646, 0x628, 0x647, 0x3b, 0x62f, 0x648, -0x634, 0x646, 0x628, 0x647, 0x3b, 0x633, 0x647, 0x200c, 0x634, 0x646, 0x628, 0x647, 0x3b, 0x686, 0x647, 0x627, 0x631, 0x634, 0x646, 0x628, -0x647, 0x3b, 0x67e, 0x646, 0x62c, 0x634, 0x646, 0x628, 0x647, 0x3b, 0x62c, 0x645, 0x639, 0x647, 0x3b, 0x634, 0x646, 0x628, 0x647, 0x3b, -0x6cc, 0x3b, 0x62f, 0x3b, 0x633, 0x3b, 0x686, 0x3b, 0x67e, 0x3b, 0x62c, 0x3b, 0x634, 0x3b, 0x6e, 0x69, 0x65, 0x64, 0x7a, 0x2e, -0x3b, 0x70, 0x6f, 0x6e, 0x2e, 0x3b, 0x77, 0x74, 0x2e, 0x3b, 0x15b, 0x72, 0x2e, 0x3b, 0x63, 0x7a, 0x77, 0x2e, 0x3b, 0x70, -0x74, 0x2e, 0x3b, 0x73, 0x6f, 0x62, 0x2e, 0x3b, 0x6e, 0x69, 0x65, 0x64, 0x7a, 0x69, 0x65, 0x6c, 0x61, 0x3b, 0x70, 0x6f, -0x6e, 0x69, 0x65, 0x64, 0x7a, 0x69, 0x61, 0x142, 0x65, 0x6b, 0x3b, 0x77, 0x74, 0x6f, 0x72, 0x65, 0x6b, 0x3b, 0x15b, 0x72, -0x6f, 0x64, 0x61, 0x3b, 0x63, 0x7a, 0x77, 0x61, 0x72, 0x74, 0x65, 0x6b, 0x3b, 0x70, 0x69, 0x105, 0x74, 0x65, 0x6b, 0x3b, -0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x4e, 0x3b, 0x50, 0x3b, 0x57, 0x3b, 0x15a, 0x3b, 0x43, 0x3b, 0x50, 0x3b, 0x53, -0x3b, 0x6e, 0x3b, 0x70, 0x3b, 0x77, 0x3b, 0x15b, 0x3b, 0x63, 0x3b, 0x70, 0x3b, 0x73, 0x3b, 0x64, 0x6f, 0x6d, 0x3b, 0x73, -0x65, 0x67, 0x3b, 0x74, 0x65, 0x72, 0x3b, 0x71, 0x75, 0x61, 0x3b, 0x71, 0x75, 0x69, 0x3b, 0x73, 0x65, 0x78, 0x3b, 0x73, -0xe1, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x73, 0x65, 0x67, 0x75, 0x6e, 0x64, 0x61, 0x2d, 0x66, -0x65, 0x69, 0x72, 0x61, 0x3b, 0x74, 0x65, 0x72, 0xe7, 0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x71, 0x75, 0x61, -0x72, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x71, 0x75, 0x69, 0x6e, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x69, -0x72, 0x61, 0x3b, 0x73, 0x65, 0x78, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x73, 0xe1, 0x62, 0x61, 0x64, -0x6f, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x51, 0x3b, 0x51, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x64, 0x6f, 0x6d, 0x69, -0x6e, 0x67, 0x6f, 0x3b, 0x73, 0x65, 0x67, 0x75, 0x6e, 0x64, 0x61, 0x3b, 0x74, 0x65, 0x72, 0xe7, 0x61, 0x3b, 0x71, 0x75, -0x61, 0x72, 0x74, 0x61, 0x3b, 0x71, 0x75, 0x69, 0x6e, 0x74, 0x61, 0x3b, 0x73, 0x65, 0x78, 0x74, 0x61, 0x3b, 0x73, 0xe1, -0x62, 0x61, 0x64, 0x6f, 0x3b, 0xa10, 0xa24, 0x3b, 0xa38, 0xa4b, 0xa2e, 0x3b, 0xa2e, 0xa70, 0xa17, 0xa32, 0x3b, 0xa2c, 0xa41, 0xa71, -0xa27, 0x3b, 0xa35, 0xa40, 0xa30, 0x3b, 0xa38, 0xa3c, 0xa41, 0xa71, 0xa15, 0xa30, 0x3b, 0xa38, 0xa3c, 0xa28, 0xa3f, 0xa71, 0xa1a, 0xa30, -0x3b, 0xa10, 0xa24, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa38, 0xa4b, 0xa2e, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa2e, 0xa70, 0xa17, 0xa32, 0xa35, 0xa3e, -0xa30, 0x3b, 0xa2c, 0xa41, 0xa71, 0xa27, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa35, 0xa40, 0xa30, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa38, 0xa3c, 0xa41, -0xa71, 0xa15, 0xa30, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa38, 0xa3c, 0xa28, 0xa3f, 0xa71, 0xa1a, 0xa30, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa10, 0x3b, -0xa38, 0xa4b, 0x3b, 0xa2e, 0xa70, 0x3b, 0xa2c, 0xa41, 0xa71, 0x3b, 0xa35, 0xa40, 0x3b, 0xa38, 0xa3c, 0xa41, 0xa71, 0x3b, 0xa38, 0xa3c, -0x3b, 0x627, 0x62a, 0x648, 0x627, 0x631, 0x3b, 0x67e, 0x6cc, 0x631, 0x3b, 0x645, 0x646, 0x6af, 0x644, 0x3b, 0x628, 0x64f, 0x62f, 0x6be, -0x3b, 0x62c, 0x645, 0x639, 0x631, 0x627, 0x62a, 0x3b, 0x62c, 0x645, 0x639, 0x6c1, 0x3b, 0x6c1, 0x641, 0x62a, 0x6c1, 0x3b, 0x44, 0x6f, -0x6d, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x4d, 0x69, 0xe9, 0x3b, 0x4a, 0x75, 0x65, 0x3b, 0x56, 0x69, -0x65, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x4c, 0x75, 0x6e, 0x65, 0x73, 0x3b, -0x4d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x3b, 0x4d, 0x69, 0xe9, 0x72, 0x63, 0x6f, 0x6c, 0x65, 0x73, 0x3b, 0x4a, 0x75, 0x65, -0x76, 0x65, 0x73, 0x3b, 0x56, 0x69, 0x65, 0x72, 0x6e, 0x65, 0x73, 0x3b, 0x53, 0xe1, 0x62, 0x61, 0x64, 0x6f, 0x3b, 0x44, -0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x58, 0x3b, 0x4a, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x64, 0x75, 0x3b, 0x67, 0x6c, 0x69, 0x3b, -0x6d, 0x61, 0x3b, 0x6d, 0x65, 0x3b, 0x67, 0x69, 0x65, 0x3b, 0x76, 0x65, 0x3b, 0x73, 0x6f, 0x3b, 0x64, 0x75, 0x6d, 0x65, -0x6e, 0x67, 0x69, 0x61, 0x3b, 0x67, 0x6c, 0x69, 0x6e, 0x64, 0x65, 0x73, 0x64, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x64, 0x69, -0x3b, 0x6d, 0x65, 0x73, 0x65, 0x6d, 0x6e, 0x61, 0x3b, 0x67, 0x69, 0x65, 0x76, 0x67, 0x69, 0x61, 0x3b, 0x76, 0x65, 0x6e, -0x64, 0x65, 0x72, 0x64, 0x69, 0x3b, 0x73, 0x6f, 0x6e, 0x64, 0x61, 0x3b, 0x44, 0x3b, 0x47, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, -0x47, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x64, 0x75, 0x6d, 0x2e, 0x3b, 0x6c, 0x75, 0x6e, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, -0x3b, 0x6d, 0x69, 0x65, 0x2e, 0x3b, 0x6a, 0x6f, 0x69, 0x3b, 0x76, 0x69, 0x6e, 0x2e, 0x3b, 0x73, 0xe2, 0x6d, 0x2e, 0x3b, -0x64, 0x75, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x103, 0x3b, 0x6c, 0x75, 0x6e, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x21b, 0x69, 0x3b, -0x6d, 0x69, 0x65, 0x72, 0x63, 0x75, 0x72, 0x69, 0x3b, 0x6a, 0x6f, 0x69, 0x3b, 0x76, 0x69, 0x6e, 0x65, 0x72, 0x69, 0x3b, -0x73, 0xe2, 0x6d, 0x62, 0x103, 0x74, 0x103, 0x3b, 0x44, 0x75, 0x6d, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x72, 0x3b, -0x4d, 0x69, 0x65, 0x3b, 0x4a, 0x6f, 0x69, 0x3b, 0x56, 0x69, 0x6e, 0x3b, 0x53, 0xe2, 0x6d, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, -0x4d, 0x61, 0x3b, 0x4d, 0x69, 0x3b, 0x4a, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x432, 0x441, 0x3b, 0x43f, 0x43d, 0x3b, 0x432, 0x442, -0x3b, 0x441, 0x440, 0x3b, 0x447, 0x442, 0x3b, 0x43f, 0x442, 0x3b, 0x441, 0x431, 0x3b, 0x432, 0x43e, 0x441, 0x43a, 0x440, 0x435, 0x441, -0x435, 0x43d, 0x44c, 0x435, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x43b, 0x44c, 0x43d, 0x438, 0x43a, 0x3b, 0x432, 0x442, 0x43e, -0x440, 0x43d, 0x438, 0x43a, 0x3b, 0x441, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x435, 0x440, 0x433, 0x3b, 0x43f, -0x44f, 0x442, 0x43d, 0x438, 0x446, 0x430, 0x3b, 0x441, 0x443, 0x431, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x412, 0x3b, 0x41f, 0x3b, 0x412, -0x3b, 0x421, 0x3b, 0x427, 0x3b, 0x41f, 0x3b, 0x421, 0x3b, 0x42, 0x6b, 0x31, 0x3b, 0x42, 0x6b, 0x32, 0x3b, 0x42, 0x6b, 0x33, -0x3b, 0x42, 0x6b, 0x34, 0x3b, 0x42, 0x6b, 0x35, 0x3b, 0x4c, 0xe2, 0x70, 0x3b, 0x4c, 0xe2, 0x79, 0x3b, 0x42, 0x69, 0x6b, -0x75, 0x61, 0x2d, 0xf4, 0x6b, 0x6f, 0x3b, 0x42, 0xef, 0x6b, 0x75, 0x61, 0x2d, 0xfb, 0x73, 0x65, 0x3b, 0x42, 0xef, 0x6b, -0x75, 0x61, 0x2d, 0x70, 0x74, 0xe2, 0x3b, 0x42, 0xef, 0x6b, 0x75, 0x61, 0x2d, 0x75, 0x73, 0xef, 0xf6, 0x3b, 0x42, 0xef, -0x6b, 0x75, 0x61, 0x2d, 0x6f, 0x6b, 0xfc, 0x3b, 0x4c, 0xe2, 0x70, 0xf4, 0x73, 0xf6, 0x3b, 0x4c, 0xe2, 0x79, 0x65, 0x6e, -0x67, 0x61, 0x3b, 0x4b, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x53, 0x3b, 0x4b, 0x3b, 0x50, 0x3b, 0x59, 0x3b, 0x43d, 0x435, 0x434, -0x3b, 0x43f, 0x43e, 0x43d, 0x3b, 0x443, 0x442, 0x43e, 0x3b, 0x441, 0x440, 0x435, 0x3b, 0x447, 0x435, 0x442, 0x3b, 0x43f, 0x435, 0x442, -0x3b, 0x441, 0x443, 0x431, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430, -0x43a, 0x3b, 0x443, 0x442, 0x43e, 0x440, 0x430, 0x43a, 0x3b, 0x441, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x440, -0x442, 0x430, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x430, 0x43a, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x43d, 0x3b, 0x43f, -0x3b, 0x443, 0x3b, 0x441, 0x3b, 0x447, 0x3b, 0x43f, 0x3b, 0x441, 0x3b, 0x6e, 0x65, 0x64, 0x2e, 0x3b, 0x70, 0x6f, 0x6e, 0x2e, +0x3b, 0x414, 0x430, 0x3b, 0x41c, 0x44f, 0x3b, 0x41b, 0x445, 0x3b, 0x41f, 0x4af, 0x3b, 0x411, 0x430, 0x3b, 0x411, 0x44f, 0x3b, 0x41d, +0x44f, 0x43c, 0x3b, 0x414, 0x430, 0x432, 0x430, 0x430, 0x3b, 0x41c, 0x44f, 0x433, 0x43c, 0x430, 0x440, 0x3b, 0x41b, 0x445, 0x430, 0x433, +0x432, 0x430, 0x3b, 0x41f, 0x4af, 0x440, 0x44d, 0x432, 0x3b, 0x411, 0x430, 0x430, 0x441, 0x430, 0x43d, 0x3b, 0x411, 0x44f, 0x43c, 0x431, +0x430, 0x3b, 0x43d, 0x44f, 0x43c, 0x3b, 0x434, 0x430, 0x432, 0x430, 0x430, 0x3b, 0x43c, 0x44f, 0x433, 0x43c, 0x430, 0x440, 0x3b, 0x43b, +0x445, 0x430, 0x433, 0x432, 0x430, 0x3b, 0x43f, 0x4af, 0x440, 0x44d, 0x432, 0x3b, 0x431, 0x430, 0x430, 0x441, 0x430, 0x43d, 0x3b, 0x431, +0x44f, 0x43c, 0x431, 0x430, 0x3b, 0x906, 0x907, 0x924, 0x3b, 0x938, 0x94b, 0x92e, 0x3b, 0x92e, 0x919, 0x94d, 0x917, 0x932, 0x3b, 0x92c, +0x941, 0x927, 0x3b, 0x92c, 0x93f, 0x939, 0x93f, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x3b, 0x906, 0x907, +0x924, 0x92c, 0x93e, 0x930, 0x3b, 0x938, 0x94b, 0x92e, 0x92c, 0x93e, 0x930, 0x3b, 0x92e, 0x919, 0x94d, 0x917, 0x932, 0x92c, 0x93e, 0x930, +0x3b, 0x92c, 0x941, 0x927, 0x92c, 0x93e, 0x930, 0x3b, 0x92c, 0x93f, 0x939, 0x93f, 0x92c, 0x93e, 0x930, 0x3b, 0x936, 0x941, 0x915, 0x94d, +0x930, 0x92c, 0x93e, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x92c, 0x93e, 0x930, 0x3b, 0x906, 0x3b, 0x938, 0x94b, 0x3b, 0x92e, 0x3b, 0x92c, +0x941, 0x3b, 0x92c, 0x93f, 0x3b, 0x936, 0x941, 0x3b, 0x936, 0x3b, 0xb30, 0xb2c, 0xb3f, 0x3b, 0xb38, 0xb4b, 0xb2e, 0x3b, 0xb2e, 0xb19, +0xb4d, 0xb17, 0xb33, 0x3b, 0xb2c, 0xb41, 0xb27, 0x3b, 0xb17, 0xb41, 0xb30, 0xb41, 0x3b, 0xb36, 0xb41, 0xb15, 0xb4d, 0xb30, 0x3b, 0xb36, +0xb28, 0xb3f, 0x3b, 0xb30, 0xb2c, 0xb3f, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb38, 0xb4b, 0xb2e, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb2e, 0xb19, 0xb4d, +0xb17, 0xb33, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb2c, 0xb41, 0xb27, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb17, 0xb41, 0xb30, 0xb41, 0xb2c, 0xb3e, 0xb30, +0x3b, 0xb36, 0xb41, 0xb15, 0xb4d, 0xb30, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb36, 0xb28, 0xb3f, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb30, 0x3b, 0xb38, +0xb4b, 0x3b, 0xb2e, 0x3b, 0xb2c, 0xb41, 0x3b, 0xb17, 0xb41, 0x3b, 0xb36, 0xb41, 0x3b, 0xb36, 0x3b, 0x64a, 0x648, 0x646, 0x6cd, 0x3b, +0x62f, 0x648, 0x646, 0x6cd, 0x3b, 0x62f, 0x631, 0x6d0, 0x646, 0x6cd, 0x3b, 0x685, 0x644, 0x631, 0x646, 0x6cd, 0x3b, 0x67e, 0x64a, 0x646, +0x681, 0x646, 0x6cd, 0x3b, 0x62c, 0x645, 0x639, 0x647, 0x3b, 0x627, 0x648, 0x646, 0x6cd, 0x3b, 0x6cc, 0x6a9, 0x634, 0x646, 0x628, 0x647, +0x3b, 0x62f, 0x648, 0x634, 0x646, 0x628, 0x647, 0x3b, 0x633, 0x647, 0x200c, 0x634, 0x646, 0x628, 0x647, 0x3b, 0x686, 0x647, 0x627, 0x631, +0x634, 0x646, 0x628, 0x647, 0x3b, 0x67e, 0x646, 0x62c, 0x634, 0x646, 0x628, 0x647, 0x3b, 0x62c, 0x645, 0x639, 0x647, 0x3b, 0x634, 0x646, +0x628, 0x647, 0x3b, 0x6cc, 0x3b, 0x62f, 0x3b, 0x633, 0x3b, 0x686, 0x3b, 0x67e, 0x3b, 0x62c, 0x3b, 0x634, 0x3b, 0x6e, 0x69, 0x65, +0x64, 0x7a, 0x2e, 0x3b, 0x70, 0x6f, 0x6e, 0x2e, 0x3b, 0x77, 0x74, 0x2e, 0x3b, 0x15b, 0x72, 0x2e, 0x3b, 0x63, 0x7a, 0x77, +0x2e, 0x3b, 0x70, 0x74, 0x2e, 0x3b, 0x73, 0x6f, 0x62, 0x2e, 0x3b, 0x6e, 0x69, 0x65, 0x64, 0x7a, 0x69, 0x65, 0x6c, 0x61, +0x3b, 0x70, 0x6f, 0x6e, 0x69, 0x65, 0x64, 0x7a, 0x69, 0x61, 0x142, 0x65, 0x6b, 0x3b, 0x77, 0x74, 0x6f, 0x72, 0x65, 0x6b, +0x3b, 0x15b, 0x72, 0x6f, 0x64, 0x61, 0x3b, 0x63, 0x7a, 0x77, 0x61, 0x72, 0x74, 0x65, 0x6b, 0x3b, 0x70, 0x69, 0x105, 0x74, +0x65, 0x6b, 0x3b, 0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x4e, 0x3b, 0x50, 0x3b, 0x57, 0x3b, 0x15a, 0x3b, 0x43, 0x3b, +0x50, 0x3b, 0x53, 0x3b, 0x6e, 0x3b, 0x70, 0x3b, 0x77, 0x3b, 0x15b, 0x3b, 0x63, 0x3b, 0x70, 0x3b, 0x73, 0x3b, 0x64, 0x6f, +0x6d, 0x3b, 0x73, 0x65, 0x67, 0x3b, 0x74, 0x65, 0x72, 0x3b, 0x71, 0x75, 0x61, 0x3b, 0x71, 0x75, 0x69, 0x3b, 0x73, 0x65, +0x78, 0x3b, 0x73, 0xe1, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x73, 0x65, 0x67, 0x75, 0x6e, 0x64, +0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x74, 0x65, 0x72, 0xe7, 0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, +0x71, 0x75, 0x61, 0x72, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x71, 0x75, 0x69, 0x6e, 0x74, 0x61, 0x2d, +0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x73, 0x65, 0x78, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x73, 0xe1, +0x62, 0x61, 0x64, 0x6f, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x51, 0x3b, 0x51, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x64, +0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x73, 0x65, 0x67, 0x75, 0x6e, 0x64, 0x61, 0x3b, 0x74, 0x65, 0x72, 0xe7, 0x61, +0x3b, 0x71, 0x75, 0x61, 0x72, 0x74, 0x61, 0x3b, 0x71, 0x75, 0x69, 0x6e, 0x74, 0x61, 0x3b, 0x73, 0x65, 0x78, 0x74, 0x61, +0x3b, 0x73, 0xe1, 0x62, 0x61, 0x64, 0x6f, 0x3b, 0xa10, 0xa24, 0x3b, 0xa38, 0xa4b, 0xa2e, 0x3b, 0xa2e, 0xa70, 0xa17, 0xa32, 0x3b, +0xa2c, 0xa41, 0xa71, 0xa27, 0x3b, 0xa35, 0xa40, 0xa30, 0x3b, 0xa38, 0xa3c, 0xa41, 0xa71, 0xa15, 0xa30, 0x3b, 0xa38, 0xa3c, 0xa28, 0xa3f, +0xa71, 0xa1a, 0xa30, 0x3b, 0xa10, 0xa24, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa38, 0xa4b, 0xa2e, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa2e, 0xa70, 0xa17, +0xa32, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa2c, 0xa41, 0xa71, 0xa27, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa35, 0xa40, 0xa30, 0xa35, 0xa3e, 0xa30, 0x3b, +0xa38, 0xa3c, 0xa41, 0xa71, 0xa15, 0xa30, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa38, 0xa3c, 0xa28, 0xa3f, 0xa71, 0xa1a, 0xa30, 0xa35, 0xa3e, 0xa30, +0x3b, 0xa10, 0x3b, 0xa38, 0xa4b, 0x3b, 0xa2e, 0xa70, 0x3b, 0xa2c, 0xa41, 0xa71, 0x3b, 0xa35, 0xa40, 0x3b, 0xa38, 0xa3c, 0xa41, 0xa71, +0x3b, 0xa38, 0xa3c, 0x3b, 0x627, 0x62a, 0x648, 0x627, 0x631, 0x3b, 0x67e, 0x6cc, 0x631, 0x3b, 0x645, 0x646, 0x6af, 0x644, 0x3b, 0x628, +0x64f, 0x62f, 0x6be, 0x3b, 0x62c, 0x645, 0x639, 0x631, 0x627, 0x62a, 0x3b, 0x62c, 0x645, 0x639, 0x6c1, 0x3b, 0x6c1, 0x641, 0x62a, 0x6c1, +0x3b, 0x44, 0x6f, 0x6d, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x4d, 0x69, 0xe9, 0x3b, 0x4a, 0x75, 0x65, +0x3b, 0x56, 0x69, 0x65, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x4c, 0x75, 0x6e, +0x65, 0x73, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x3b, 0x4d, 0x69, 0xe9, 0x72, 0x63, 0x6f, 0x6c, 0x65, 0x73, 0x3b, +0x4a, 0x75, 0x65, 0x76, 0x65, 0x73, 0x3b, 0x56, 0x69, 0x65, 0x72, 0x6e, 0x65, 0x73, 0x3b, 0x53, 0xe1, 0x62, 0x61, 0x64, +0x6f, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x58, 0x3b, 0x4a, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x64, 0x75, 0x3b, 0x67, +0x6c, 0x69, 0x3b, 0x6d, 0x61, 0x3b, 0x6d, 0x65, 0x3b, 0x67, 0x69, 0x65, 0x3b, 0x76, 0x65, 0x3b, 0x73, 0x6f, 0x3b, 0x64, +0x75, 0x6d, 0x65, 0x6e, 0x67, 0x69, 0x61, 0x3b, 0x67, 0x6c, 0x69, 0x6e, 0x64, 0x65, 0x73, 0x64, 0x69, 0x3b, 0x6d, 0x61, +0x72, 0x64, 0x69, 0x3b, 0x6d, 0x65, 0x73, 0x65, 0x6d, 0x6e, 0x61, 0x3b, 0x67, 0x69, 0x65, 0x76, 0x67, 0x69, 0x61, 0x3b, +0x76, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x64, 0x69, 0x3b, 0x73, 0x6f, 0x6e, 0x64, 0x61, 0x3b, 0x44, 0x3b, 0x47, 0x3b, 0x4d, +0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x64, 0x75, 0x6d, 0x2e, 0x3b, 0x6c, 0x75, 0x6e, 0x2e, 0x3b, 0x6d, +0x61, 0x72, 0x2e, 0x3b, 0x6d, 0x69, 0x65, 0x2e, 0x3b, 0x6a, 0x6f, 0x69, 0x3b, 0x76, 0x69, 0x6e, 0x2e, 0x3b, 0x73, 0xe2, +0x6d, 0x2e, 0x3b, 0x64, 0x75, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x103, 0x3b, 0x6c, 0x75, 0x6e, 0x69, 0x3b, 0x6d, 0x61, 0x72, +0x21b, 0x69, 0x3b, 0x6d, 0x69, 0x65, 0x72, 0x63, 0x75, 0x72, 0x69, 0x3b, 0x6a, 0x6f, 0x69, 0x3b, 0x76, 0x69, 0x6e, 0x65, +0x72, 0x69, 0x3b, 0x73, 0xe2, 0x6d, 0x62, 0x103, 0x74, 0x103, 0x3b, 0x44, 0x75, 0x6d, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4d, +0x61, 0x72, 0x3b, 0x4d, 0x69, 0x65, 0x3b, 0x4a, 0x6f, 0x69, 0x3b, 0x56, 0x69, 0x6e, 0x3b, 0x53, 0xe2, 0x6d, 0x3b, 0x44, +0x3b, 0x4c, 0x3b, 0x4d, 0x61, 0x3b, 0x4d, 0x69, 0x3b, 0x4a, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x432, 0x441, 0x3b, 0x43f, 0x43d, +0x3b, 0x432, 0x442, 0x3b, 0x441, 0x440, 0x3b, 0x447, 0x442, 0x3b, 0x43f, 0x442, 0x3b, 0x441, 0x431, 0x3b, 0x432, 0x43e, 0x441, 0x43a, +0x440, 0x435, 0x441, 0x435, 0x43d, 0x44c, 0x435, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x43b, 0x44c, 0x43d, 0x438, 0x43a, 0x3b, +0x432, 0x442, 0x43e, 0x440, 0x43d, 0x438, 0x43a, 0x3b, 0x441, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x435, 0x440, +0x433, 0x3b, 0x43f, 0x44f, 0x442, 0x43d, 0x438, 0x446, 0x430, 0x3b, 0x441, 0x443, 0x431, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x412, 0x3b, +0x41f, 0x3b, 0x412, 0x3b, 0x421, 0x3b, 0x427, 0x3b, 0x41f, 0x3b, 0x421, 0x3b, 0x42, 0x6b, 0x31, 0x3b, 0x42, 0x6b, 0x32, 0x3b, +0x42, 0x6b, 0x33, 0x3b, 0x42, 0x6b, 0x34, 0x3b, 0x42, 0x6b, 0x35, 0x3b, 0x4c, 0xe2, 0x70, 0x3b, 0x4c, 0xe2, 0x79, 0x3b, +0x42, 0x69, 0x6b, 0x75, 0x61, 0x2d, 0xf4, 0x6b, 0x6f, 0x3b, 0x42, 0xef, 0x6b, 0x75, 0x61, 0x2d, 0xfb, 0x73, 0x65, 0x3b, +0x42, 0xef, 0x6b, 0x75, 0x61, 0x2d, 0x70, 0x74, 0xe2, 0x3b, 0x42, 0xef, 0x6b, 0x75, 0x61, 0x2d, 0x75, 0x73, 0xef, 0xf6, +0x3b, 0x42, 0xef, 0x6b, 0x75, 0x61, 0x2d, 0x6f, 0x6b, 0xfc, 0x3b, 0x4c, 0xe2, 0x70, 0xf4, 0x73, 0xf6, 0x3b, 0x4c, 0xe2, +0x79, 0x65, 0x6e, 0x67, 0x61, 0x3b, 0x4b, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x53, 0x3b, 0x4b, 0x3b, 0x50, 0x3b, 0x59, 0x3b, +0x43d, 0x435, 0x434, 0x3b, 0x43f, 0x43e, 0x43d, 0x3b, 0x443, 0x442, 0x43e, 0x3b, 0x441, 0x440, 0x435, 0x3b, 0x447, 0x435, 0x442, 0x3b, +0x43f, 0x435, 0x442, 0x3b, 0x441, 0x443, 0x431, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, +0x435, 0x459, 0x430, 0x43a, 0x3b, 0x443, 0x442, 0x43e, 0x440, 0x430, 0x43a, 0x3b, 0x441, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, +0x442, 0x432, 0x440, 0x442, 0x430, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x430, 0x43a, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, +0x43d, 0x3b, 0x43f, 0x3b, 0x443, 0x3b, 0x441, 0x3b, 0x447, 0x3b, 0x43f, 0x3b, 0x441, 0x3b, 0x43d, 0x435, 0x434, 0x3b, 0x43f, 0x43e, +0x43d, 0x3b, 0x443, 0x442, 0x3b, 0x441, 0x440, 0x3b, 0x447, 0x435, 0x442, 0x3b, 0x43f, 0x435, 0x442, 0x3b, 0x441, 0x443, 0x431, 0x3b, +0x43d, 0x435, 0x434, 0x458, 0x435, 0x459, 0x430, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430, 0x43a, 0x3b, 0x443, 0x442, +0x43e, 0x440, 0x430, 0x43a, 0x3b, 0x441, 0x440, 0x438, 0x458, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x440, 0x442, 0x430, +0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x430, 0x43a, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x43d, 0x435, 0x434, 0x2e, 0x3b, +0x43f, 0x43e, 0x43d, 0x2e, 0x3b, 0x443, 0x442, 0x2e, 0x3b, 0x441, 0x440, 0x2e, 0x3b, 0x447, 0x435, 0x442, 0x2e, 0x3b, 0x43f, 0x435, +0x442, 0x2e, 0x3b, 0x441, 0x443, 0x431, 0x2e, 0x3b, 0x6e, 0x65, 0x64, 0x3b, 0x70, 0x6f, 0x6e, 0x3b, 0x75, 0x74, 0x3b, 0x73, +0x72, 0x3b, 0x10d, 0x65, 0x74, 0x3b, 0x70, 0x65, 0x74, 0x3b, 0x73, 0x75, 0x62, 0x3b, 0x6e, 0x65, 0x64, 0x6a, 0x65, 0x6c, +0x6a, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a, 0x61, 0x6b, 0x3b, 0x75, 0x74, 0x6f, 0x72, 0x61, 0x6b, +0x3b, 0x73, 0x72, 0x69, 0x6a, 0x65, 0x64, 0x61, 0x3b, 0x10d, 0x65, 0x74, 0x76, 0x72, 0x74, 0x61, 0x6b, 0x3b, 0x70, 0x65, +0x74, 0x61, 0x6b, 0x3b, 0x73, 0x75, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x6e, 0x65, 0x64, 0x2e, 0x3b, 0x70, 0x6f, 0x6e, 0x2e, 0x3b, 0x75, 0x74, 0x2e, 0x3b, 0x73, 0x72, 0x2e, 0x3b, 0x10d, 0x65, 0x74, 0x2e, 0x3b, 0x70, 0x65, 0x74, 0x2e, 0x3b, 0x73, -0x75, 0x62, 0x2e, 0x3b, 0x6e, 0x65, 0x64, 0x6a, 0x65, 0x6c, 0x6a, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x65, 0x64, 0x65, 0x6c, -0x6a, 0x61, 0x6b, 0x3b, 0x75, 0x74, 0x6f, 0x72, 0x61, 0x6b, 0x3b, 0x73, 0x72, 0x69, 0x6a, 0x65, 0x64, 0x61, 0x3b, 0x10d, -0x65, 0x74, 0x76, 0x72, 0x74, 0x61, 0x6b, 0x3b, 0x70, 0x65, 0x74, 0x61, 0x6b, 0x3b, 0x73, 0x75, 0x62, 0x6f, 0x74, 0x61, -0x3b, 0x6e, 0x65, 0x64, 0x3b, 0x70, 0x6f, 0x6e, 0x3b, 0x75, 0x74, 0x6f, 0x3b, 0x73, 0x72, 0x65, 0x3b, 0x10d, 0x65, 0x74, -0x3b, 0x70, 0x65, 0x74, 0x3b, 0x73, 0x75, 0x62, 0x3b, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a, 0x61, 0x3b, 0x70, 0x6f, 0x6e, -0x65, 0x64, 0x65, 0x6c, 0x6a, 0x61, 0x6b, 0x3b, 0x75, 0x74, 0x6f, 0x72, 0x61, 0x6b, 0x3b, 0x73, 0x72, 0x65, 0x64, 0x61, -0x3b, 0x10d, 0x65, 0x74, 0x76, 0x72, 0x74, 0x61, 0x6b, 0x3b, 0x70, 0x65, 0x74, 0x61, 0x6b, 0x3b, 0x73, 0x75, 0x62, 0x6f, -0x74, 0x61, 0x3b, 0x43d, 0x435, 0x434, 0x2e, 0x3b, 0x43f, 0x43e, 0x43d, 0x2e, 0x3b, 0x443, 0x442, 0x2e, 0x3b, 0x441, 0x440, 0x2e, -0x3b, 0x447, 0x435, 0x442, 0x2e, 0x3b, 0x43f, 0x435, 0x442, 0x2e, 0x3b, 0x441, 0x443, 0x431, 0x2e, 0x3b, 0x43d, 0x435, 0x434, 0x458, -0x435, 0x459, 0x430, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430, 0x43a, 0x3b, 0x443, 0x442, 0x43e, 0x440, 0x430, 0x43a, -0x3b, 0x441, 0x440, 0x438, 0x458, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x440, 0x442, 0x430, 0x43a, 0x3b, 0x43f, 0x435, -0x442, 0x430, 0x43a, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x425, 0x446, 0x431, 0x3b, 0x41a, 0x440, 0x441, 0x3b, 0x414, -0x446, 0x433, 0x3b, 0x4d4, 0x440, 0x442, 0x3b, 0x426, 0x43f, 0x440, 0x3b, 0x41c, 0x440, 0x431, 0x3b, 0x421, 0x431, 0x442, 0x3b, 0x425, -0x443, 0x44b, 0x446, 0x430, 0x443, 0x431, 0x43e, 0x43d, 0x3b, 0x41a, 0x44a, 0x443, 0x44b, 0x440, 0x438, 0x441, 0x4d5, 0x440, 0x3b, 0x414, -0x44b, 0x446, 0x446, 0x4d5, 0x433, 0x3b, 0x4d4, 0x440, 0x442, 0x44b, 0x446, 0x446, 0x4d5, 0x433, 0x3b, 0x426, 0x44b, 0x43f, 0x43f, 0x4d5, -0x440, 0x4d5, 0x43c, 0x3b, 0x41c, 0x430, 0x439, 0x440, 0x4d5, 0x43c, 0x431, 0x43e, 0x43d, 0x3b, 0x421, 0x430, 0x431, 0x430, 0x442, 0x3b, -0x425, 0x3b, 0x41a, 0x3b, 0x414, 0x3b, 0x4d4, 0x3b, 0x426, 0x3b, 0x41c, 0x3b, 0x421, 0x3b, 0x445, 0x446, 0x431, 0x3b, 0x43a, 0x440, -0x441, 0x3b, 0x434, 0x446, 0x433, 0x3b, 0x4d5, 0x440, 0x442, 0x3b, 0x446, 0x43f, 0x440, 0x3b, 0x43c, 0x440, 0x431, 0x3b, 0x441, 0x431, -0x442, 0x3b, 0x445, 0x443, 0x44b, 0x446, 0x430, 0x443, 0x431, 0x43e, 0x43d, 0x3b, 0x43a, 0x44a, 0x443, 0x44b, 0x440, 0x438, 0x441, 0x4d5, -0x440, 0x3b, 0x434, 0x44b, 0x446, 0x446, 0x4d5, 0x433, 0x3b, 0x4d5, 0x440, 0x442, 0x44b, 0x446, 0x446, 0x4d5, 0x433, 0x3b, 0x446, 0x44b, -0x43f, 0x43f, 0x4d5, 0x440, 0x4d5, 0x43c, 0x3b, 0x43c, 0x430, 0x439, 0x440, 0x4d5, 0x43c, 0x431, 0x43e, 0x43d, 0x3b, 0x441, 0x430, 0x431, -0x430, 0x442, 0x3b, 0x53, 0x76, 0x6f, 0x3b, 0x4d, 0x75, 0x76, 0x3b, 0x43, 0x68, 0x70, 0x3b, 0x43, 0x68, 0x74, 0x3b, 0x43, -0x68, 0x6e, 0x3b, 0x43, 0x68, 0x73, 0x3b, 0x4d, 0x75, 0x67, 0x3b, 0x53, 0x76, 0x6f, 0x6e, 0x64, 0x6f, 0x3b, 0x4d, 0x75, -0x76, 0x68, 0x75, 0x72, 0x6f, 0x3b, 0x43, 0x68, 0x69, 0x70, 0x69, 0x72, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x74, 0x61, 0x74, -0x75, 0x3b, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x3b, 0x43, 0x68, 0x69, 0x73, 0x68, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x75, 0x67, -0x6f, 0x76, 0x65, 0x72, 0x61, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x4d, 0x3b, -0x622, 0x686, 0x631, 0x3b, 0x633, 0x648, 0x645, 0x631, 0x3b, 0x627, 0x6b1, 0x627, 0x631, 0x648, 0x3b, 0x627, 0x631, 0x628, 0x639, 0x3b, -0x62e, 0x645, 0x64a, 0x633, 0x3b, 0x62c, 0x645, 0x639, 0x648, 0x3b, 0x687, 0x646, 0x687, 0x631, 0x3b, 0x622, 0x686, 0x3b, 0x633, 0x648, -0x3b, 0x627, 0x6b1, 0x3b, 0x627, 0x631, 0x3b, 0x62e, 0x645, 0x3b, 0x62c, 0x645, 0x3b, 0x687, 0x646, 0x3b, 0x622, 0x686, 0x631, 0x3b, -0x633, 0x648, 0x3b, 0x627, 0x6b1, 0x627, 0x631, 0x648, 0x3b, 0x627, 0x631, 0x628, 0x639, 0x3b, 0x62e, 0x645, 0x3b, 0x62c, 0x645, 0x639, -0x648, 0x3b, 0x687, 0x646, 0x687, 0x631, 0x3b, 0xd89, 0xdbb, 0xdd2, 0xdaf, 0xdcf, 0x3b, 0xdc3, 0xdb3, 0xdd4, 0xdaf, 0xdcf, 0x3b, 0xd85, -0xd9f, 0xdc4, 0x3b, 0xdb6, 0xdaf, 0xdcf, 0xdaf, 0xdcf, 0x3b, 0xdb6, 0xdca, 0x200d, 0xdbb, 0xdc4, 0xdc3, 0xdca, 0x3b, 0xdc3, 0xdd2, 0xd9a, -0xdd4, 0x3b, 0xdc3, 0xdd9, 0xdb1, 0x3b, 0xd89, 0xdbb, 0xdd2, 0xdaf, 0xdcf, 0x3b, 0xdc3, 0xdb3, 0xdd4, 0xdaf, 0xdcf, 0x3b, 0xd85, 0xd9f, -0xdc4, 0xdbb, 0xdd4, 0xdc0, 0xdcf, 0xdaf, 0xdcf, 0x3b, 0xdb6, 0xdaf, 0xdcf, 0xdaf, 0xdcf, 0x3b, 0xdb6, 0xdca, 0x200d, 0xdbb, 0xdc4, 0xdc3, -0xdca, 0xdb4, 0xdad, 0xdd2, 0xdb1, 0xdca, 0xdaf, 0xdcf, 0x3b, 0xdc3, 0xdd2, 0xd9a, 0xdd4, 0xdbb, 0xdcf, 0xdaf, 0xdcf, 0x3b, 0xdc3, 0xdd9, -0xdb1, 0xdc3, 0xdd4, 0xdbb, 0xdcf, 0xdaf, 0xdcf, 0x3b, 0xd89, 0x3b, 0xdc3, 0x3b, 0xd85, 0x3b, 0xdb6, 0x3b, 0xdb6, 0xdca, 0x200d, 0xdbb, -0x3b, 0xdc3, 0xdd2, 0x3b, 0xdc3, 0xdd9, 0x3b, 0x6e, 0x65, 0x3b, 0x70, 0x6f, 0x3b, 0x75, 0x74, 0x3b, 0x73, 0x74, 0x3b, 0x161, -0x74, 0x3b, 0x70, 0x69, 0x3b, 0x73, 0x6f, 0x3b, 0x6e, 0x65, 0x64, 0x65, 0x13e, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x64, 0x65, -0x6c, 0x6f, 0x6b, 0x3b, 0x75, 0x74, 0x6f, 0x72, 0x6f, 0x6b, 0x3b, 0x73, 0x74, 0x72, 0x65, 0x64, 0x61, 0x3b, 0x161, 0x74, -0x76, 0x72, 0x74, 0x6f, 0x6b, 0x3b, 0x70, 0x69, 0x61, 0x74, 0x6f, 0x6b, 0x3b, 0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b, -0x6e, 0x3b, 0x70, 0x3b, 0x75, 0x3b, 0x73, 0x3b, 0x161, 0x3b, 0x70, 0x3b, 0x73, 0x3b, 0x6e, 0x65, 0x64, 0x2e, 0x3b, 0x70, -0x6f, 0x6e, 0x2e, 0x3b, 0x74, 0x6f, 0x72, 0x2e, 0x3b, 0x73, 0x72, 0x65, 0x2e, 0x3b, 0x10d, 0x65, 0x74, 0x2e, 0x3b, 0x70, -0x65, 0x74, 0x2e, 0x3b, 0x73, 0x6f, 0x62, 0x2e, 0x3b, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a, 0x61, 0x3b, 0x70, 0x6f, 0x6e, -0x65, 0x64, 0x65, 0x6c, 0x6a, 0x65, 0x6b, 0x3b, 0x74, 0x6f, 0x72, 0x65, 0x6b, 0x3b, 0x73, 0x72, 0x65, 0x64, 0x61, 0x3b, -0x10d, 0x65, 0x74, 0x72, 0x74, 0x65, 0x6b, 0x3b, 0x70, 0x65, 0x74, 0x65, 0x6b, 0x3b, 0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61, -0x3b, 0x6e, 0x3b, 0x70, 0x3b, 0x74, 0x3b, 0x73, 0x3b, 0x10d, 0x3b, 0x70, 0x3b, 0x73, 0x3b, 0x41, 0x78, 0x64, 0x3b, 0x49, -0x73, 0x6e, 0x3b, 0x54, 0x61, 0x6c, 0x3b, 0x41, 0x72, 0x62, 0x3b, 0x4b, 0x68, 0x61, 0x3b, 0x4a, 0x69, 0x6d, 0x3b, 0x53, -0x61, 0x62, 0x3b, 0x41, 0x78, 0x61, 0x64, 0x3b, 0x49, 0x73, 0x6e, 0x69, 0x69, 0x6e, 0x3b, 0x54, 0x61, 0x6c, 0x61, 0x61, -0x64, 0x6f, 0x3b, 0x41, 0x72, 0x62, 0x61, 0x63, 0x6f, 0x3b, 0x4b, 0x68, 0x61, 0x6d, 0x69, 0x69, 0x73, 0x3b, 0x4a, 0x69, -0x6d, 0x63, 0x6f, 0x3b, 0x53, 0x61, 0x62, 0x74, 0x69, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x4b, 0x68, -0x3b, 0x4a, 0x3b, 0x53, 0x3b, 0x64, 0x6f, 0x6d, 0x2e, 0x3b, 0x6c, 0x75, 0x6e, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, -0x6d, 0x69, 0xe9, 0x2e, 0x3b, 0x6a, 0x75, 0x65, 0x2e, 0x3b, 0x76, 0x69, 0x65, 0x2e, 0x3b, 0x73, 0xe1, 0x62, 0x2e, 0x3b, -0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x6c, 0x75, 0x6e, 0x65, 0x73, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x65, 0x73, -0x3b, 0x6d, 0x69, 0xe9, 0x72, 0x63, 0x6f, 0x6c, 0x65, 0x73, 0x3b, 0x6a, 0x75, 0x65, 0x76, 0x65, 0x73, 0x3b, 0x76, 0x69, -0x65, 0x72, 0x6e, 0x65, 0x73, 0x3b, 0x73, 0xe1, 0x62, 0x61, 0x64, 0x6f, 0x3b, 0x64, 0x3b, 0x6c, 0x3b, 0x6d, 0x3b, 0x6d, -0x3b, 0x6a, 0x3b, 0x76, 0x3b, 0x73, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x6c, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, +0x75, 0x62, 0x2e, 0x3b, 0x6e, 0x65, 0x64, 0x3b, 0x70, 0x6f, 0x6e, 0x3b, 0x75, 0x74, 0x6f, 0x3b, 0x73, 0x72, 0x65, 0x3b, +0x10d, 0x65, 0x74, 0x3b, 0x70, 0x65, 0x74, 0x3b, 0x73, 0x75, 0x62, 0x3b, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a, 0x61, 0x3b, +0x70, 0x6f, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a, 0x61, 0x6b, 0x3b, 0x75, 0x74, 0x6f, 0x72, 0x61, 0x6b, 0x3b, 0x73, 0x72, +0x65, 0x64, 0x61, 0x3b, 0x10d, 0x65, 0x74, 0x76, 0x72, 0x74, 0x61, 0x6b, 0x3b, 0x70, 0x65, 0x74, 0x61, 0x6b, 0x3b, 0x73, +0x75, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x425, 0x446, 0x431, 0x3b, 0x41a, 0x440, 0x441, 0x3b, 0x414, 0x446, 0x433, 0x3b, 0x4d4, 0x440, +0x442, 0x3b, 0x426, 0x43f, 0x440, 0x3b, 0x41c, 0x440, 0x431, 0x3b, 0x421, 0x431, 0x442, 0x3b, 0x425, 0x443, 0x44b, 0x446, 0x430, 0x443, +0x431, 0x43e, 0x43d, 0x3b, 0x41a, 0x44a, 0x443, 0x44b, 0x440, 0x438, 0x441, 0x4d5, 0x440, 0x3b, 0x414, 0x44b, 0x446, 0x446, 0x4d5, 0x433, +0x3b, 0x4d4, 0x440, 0x442, 0x44b, 0x446, 0x446, 0x4d5, 0x433, 0x3b, 0x426, 0x44b, 0x43f, 0x43f, 0x4d5, 0x440, 0x4d5, 0x43c, 0x3b, 0x41c, +0x430, 0x439, 0x440, 0x4d5, 0x43c, 0x431, 0x43e, 0x43d, 0x3b, 0x421, 0x430, 0x431, 0x430, 0x442, 0x3b, 0x425, 0x3b, 0x41a, 0x3b, 0x414, +0x3b, 0x4d4, 0x3b, 0x426, 0x3b, 0x41c, 0x3b, 0x421, 0x3b, 0x445, 0x446, 0x431, 0x3b, 0x43a, 0x440, 0x441, 0x3b, 0x434, 0x446, 0x433, +0x3b, 0x4d5, 0x440, 0x442, 0x3b, 0x446, 0x43f, 0x440, 0x3b, 0x43c, 0x440, 0x431, 0x3b, 0x441, 0x431, 0x442, 0x3b, 0x445, 0x443, 0x44b, +0x446, 0x430, 0x443, 0x431, 0x43e, 0x43d, 0x3b, 0x43a, 0x44a, 0x443, 0x44b, 0x440, 0x438, 0x441, 0x4d5, 0x440, 0x3b, 0x434, 0x44b, 0x446, +0x446, 0x4d5, 0x433, 0x3b, 0x4d5, 0x440, 0x442, 0x44b, 0x446, 0x446, 0x4d5, 0x433, 0x3b, 0x446, 0x44b, 0x43f, 0x43f, 0x4d5, 0x440, 0x4d5, +0x43c, 0x3b, 0x43c, 0x430, 0x439, 0x440, 0x4d5, 0x43c, 0x431, 0x43e, 0x43d, 0x3b, 0x441, 0x430, 0x431, 0x430, 0x442, 0x3b, 0x53, 0x76, +0x6f, 0x3b, 0x4d, 0x75, 0x76, 0x3b, 0x43, 0x68, 0x70, 0x3b, 0x43, 0x68, 0x74, 0x3b, 0x43, 0x68, 0x6e, 0x3b, 0x43, 0x68, +0x73, 0x3b, 0x4d, 0x75, 0x67, 0x3b, 0x53, 0x76, 0x6f, 0x6e, 0x64, 0x6f, 0x3b, 0x4d, 0x75, 0x76, 0x68, 0x75, 0x72, 0x6f, +0x3b, 0x43, 0x68, 0x69, 0x70, 0x69, 0x72, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x43, 0x68, 0x69, +0x6e, 0x61, 0x3b, 0x43, 0x68, 0x69, 0x73, 0x68, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x75, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x61, +0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x4d, 0x3b, 0x622, 0x686, 0x631, 0x3b, 0x633, +0x648, 0x645, 0x631, 0x3b, 0x627, 0x6b1, 0x627, 0x631, 0x648, 0x3b, 0x627, 0x631, 0x628, 0x639, 0x3b, 0x62e, 0x645, 0x64a, 0x633, 0x3b, +0x62c, 0x645, 0x639, 0x648, 0x3b, 0x687, 0x646, 0x687, 0x631, 0x3b, 0x622, 0x686, 0x631, 0x3b, 0x633, 0x648, 0x3b, 0x627, 0x6b1, 0x627, +0x631, 0x648, 0x3b, 0x627, 0x631, 0x628, 0x639, 0x3b, 0x62e, 0x645, 0x3b, 0x62c, 0x645, 0x639, 0x648, 0x3b, 0x687, 0x646, 0x687, 0x631, +0x3b, 0xd89, 0xdbb, 0xdd2, 0xdaf, 0xdcf, 0x3b, 0xdc3, 0xdb3, 0xdd4, 0xdaf, 0xdcf, 0x3b, 0xd85, 0xd9f, 0xdc4, 0x3b, 0xdb6, 0xdaf, 0xdcf, +0xdaf, 0xdcf, 0x3b, 0xdb6, 0xdca, 0x200d, 0xdbb, 0xdc4, 0xdc3, 0xdca, 0x3b, 0xdc3, 0xdd2, 0xd9a, 0xdd4, 0x3b, 0xdc3, 0xdd9, 0xdb1, 0x3b, +0xd89, 0xdbb, 0xdd2, 0xdaf, 0xdcf, 0x3b, 0xdc3, 0xdb3, 0xdd4, 0xdaf, 0xdcf, 0x3b, 0xd85, 0xd9f, 0xdc4, 0xdbb, 0xdd4, 0xdc0, 0xdcf, 0xdaf, +0xdcf, 0x3b, 0xdb6, 0xdaf, 0xdcf, 0xdaf, 0xdcf, 0x3b, 0xdb6, 0xdca, 0x200d, 0xdbb, 0xdc4, 0xdc3, 0xdca, 0xdb4, 0xdad, 0xdd2, 0xdb1, 0xdca, +0xdaf, 0xdcf, 0x3b, 0xdc3, 0xdd2, 0xd9a, 0xdd4, 0xdbb, 0xdcf, 0xdaf, 0xdcf, 0x3b, 0xdc3, 0xdd9, 0xdb1, 0xdc3, 0xdd4, 0xdbb, 0xdcf, 0xdaf, +0xdcf, 0x3b, 0xd89, 0x3b, 0xdc3, 0x3b, 0xd85, 0x3b, 0xdb6, 0x3b, 0xdb6, 0xdca, 0x200d, 0xdbb, 0x3b, 0xdc3, 0xdd2, 0x3b, 0xdc3, 0xdd9, +0x3b, 0x6e, 0x65, 0x3b, 0x70, 0x6f, 0x3b, 0x75, 0x74, 0x3b, 0x73, 0x74, 0x3b, 0x161, 0x74, 0x3b, 0x70, 0x69, 0x3b, 0x73, +0x6f, 0x3b, 0x6e, 0x65, 0x64, 0x65, 0x13e, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x64, 0x65, 0x6c, 0x6f, 0x6b, 0x3b, 0x75, 0x74, +0x6f, 0x72, 0x6f, 0x6b, 0x3b, 0x73, 0x74, 0x72, 0x65, 0x64, 0x61, 0x3b, 0x161, 0x74, 0x76, 0x72, 0x74, 0x6f, 0x6b, 0x3b, +0x70, 0x69, 0x61, 0x74, 0x6f, 0x6b, 0x3b, 0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x6e, 0x3b, 0x70, 0x3b, 0x75, 0x3b, +0x73, 0x3b, 0x161, 0x3b, 0x70, 0x3b, 0x73, 0x3b, 0x6e, 0x65, 0x64, 0x2e, 0x3b, 0x70, 0x6f, 0x6e, 0x2e, 0x3b, 0x74, 0x6f, +0x72, 0x2e, 0x3b, 0x73, 0x72, 0x65, 0x2e, 0x3b, 0x10d, 0x65, 0x74, 0x2e, 0x3b, 0x70, 0x65, 0x74, 0x2e, 0x3b, 0x73, 0x6f, +0x62, 0x2e, 0x3b, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a, 0x65, +0x6b, 0x3b, 0x74, 0x6f, 0x72, 0x65, 0x6b, 0x3b, 0x73, 0x72, 0x65, 0x64, 0x61, 0x3b, 0x10d, 0x65, 0x74, 0x72, 0x74, 0x65, +0x6b, 0x3b, 0x70, 0x65, 0x74, 0x65, 0x6b, 0x3b, 0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x6e, 0x3b, 0x70, 0x3b, 0x74, +0x3b, 0x73, 0x3b, 0x10d, 0x3b, 0x70, 0x3b, 0x73, 0x3b, 0x41, 0x78, 0x64, 0x3b, 0x49, 0x73, 0x6e, 0x3b, 0x54, 0x61, 0x6c, +0x3b, 0x41, 0x72, 0x62, 0x3b, 0x4b, 0x68, 0x61, 0x3b, 0x4a, 0x69, 0x6d, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x41, 0x78, 0x61, +0x64, 0x3b, 0x49, 0x73, 0x6e, 0x69, 0x69, 0x6e, 0x3b, 0x54, 0x61, 0x6c, 0x61, 0x61, 0x64, 0x6f, 0x3b, 0x41, 0x72, 0x62, +0x61, 0x63, 0x6f, 0x3b, 0x4b, 0x68, 0x61, 0x6d, 0x69, 0x69, 0x73, 0x3b, 0x4a, 0x69, 0x6d, 0x63, 0x6f, 0x3b, 0x53, 0x61, +0x62, 0x74, 0x69, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x4b, 0x68, 0x3b, 0x4a, 0x3b, 0x53, 0x3b, 0x64, +0x6f, 0x6d, 0x2e, 0x3b, 0x6c, 0x75, 0x6e, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x6d, 0x69, 0xe9, 0x2e, 0x3b, 0x6a, +0x75, 0x65, 0x2e, 0x3b, 0x76, 0x69, 0x65, 0x2e, 0x3b, 0x73, 0xe1, 0x62, 0x2e, 0x3b, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x67, +0x6f, 0x3b, 0x6c, 0x75, 0x6e, 0x65, 0x73, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x3b, 0x6d, 0x69, 0xe9, 0x72, 0x63, +0x6f, 0x6c, 0x65, 0x73, 0x3b, 0x6a, 0x75, 0x65, 0x76, 0x65, 0x73, 0x3b, 0x76, 0x69, 0x65, 0x72, 0x6e, 0x65, 0x73, 0x3b, +0x73, 0xe1, 0x62, 0x61, 0x64, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x6c, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x73, 0xf6, 0x6e, 0x3b, 0x6d, 0xe5, 0x6e, 0x3b, 0x74, 0x69, 0x73, 0x3b, 0x6f, @@ -4450,701 +4530,707 @@ static const ushort days_data[] = { 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf49, 0xf72, 0x3b, 0xf5f, 0xfb3, 0x3b, 0xf58, 0xf72, 0xf42, 0x3b, 0xf63, 0xfb7, 0xf42, 0x3b, 0xf55, 0xf74, 0xf62, 0x3b, 0xf66, 0xf44, 0xf66, 0x3b, 0xf66, 0xfa4, 0xf7a, 0xf53, 0x3b, 0x1230, 0x1295, 0x3b, 0x1230, 0x1291, 0x3b, 0x1230, 0x1209, 0x3b, 0x1228, 0x1261, 0x3b, 0x1213, 0x1219, 0x3b, 0x12d3, 0x122d, 0x3b, 0x1240, 0x12f3, 0x3b, 0x1230, 0x1295, 0x1260, 0x1275, 0x3b, 0x1230, 0x1291, 0x12ed, -0x3b, 0x1230, 0x1209, 0x1235, 0x3b, 0x1228, 0x1261, 0x12d5, 0x3b, 0x1213, 0x1219, 0x1235, 0x3b, 0x12d3, 0x122d, 0x1262, 0x3b, 0x1240, 0x12f3, 0x121d, -0x3b, 0x1230, 0x3b, 0x1230, 0x3b, 0x1220, 0x3b, 0x1228, 0x3b, 0x1213, 0x3b, 0x12d3, 0x3b, 0x1240, 0x3b, 0x1230, 0x1295, 0x1260, 0x1275, 0x3b, -0x1230, 0x1291, 0x12ed, 0x3b, 0x1220, 0x1209, 0x1235, 0x3b, 0x1228, 0x1261, 0x12d5, 0x3b, 0x1283, 0x1219, 0x1235, 0x3b, 0x12d3, 0x122d, 0x1262, 0x3b, -0x1240, 0x12f3, 0x121d, 0x3b, 0x1230, 0x3b, 0x1230, 0x3b, 0x1230, 0x3b, 0x1228, 0x3b, 0x1213, 0x3b, 0x12d3, 0x3b, 0x1240, 0x3b, 0x53, 0x101, -0x70, 0x3b, 0x4d, 0x14d, 0x6e, 0x3b, 0x54, 0x16b, 0x73, 0x3b, 0x50, 0x75, 0x6c, 0x3b, 0x54, 0x75, 0x2bb, 0x61, 0x3b, 0x46, -0x61, 0x6c, 0x3b, 0x54, 0x6f, 0x6b, 0x3b, 0x53, 0x101, 0x70, 0x61, 0x74, 0x65, 0x3b, 0x4d, 0x14d, 0x6e, 0x69, 0x74, 0x65, -0x3b, 0x54, 0x16b, 0x73, 0x69, 0x74, 0x65, 0x3b, 0x50, 0x75, 0x6c, 0x65, 0x6c, 0x75, 0x6c, 0x75, 0x3b, 0x54, 0x75, 0x2bb, -0x61, 0x70, 0x75, 0x6c, 0x65, 0x6c, 0x75, 0x6c, 0x75, 0x3b, 0x46, 0x61, 0x6c, 0x61, 0x69, 0x74, 0x65, 0x3b, 0x54, 0x6f, -0x6b, 0x6f, 0x6e, 0x61, 0x6b, 0x69, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x54, 0x3b, 0x50, 0x3b, 0x54, 0x3b, 0x46, 0x3b, 0x54, -0x3b, 0x50, 0x61, 0x7a, 0x3b, 0x50, 0x7a, 0x74, 0x3b, 0x53, 0x61, 0x6c, 0x3b, 0xc7, 0x61, 0x72, 0x3b, 0x50, 0x65, 0x72, -0x3b, 0x43, 0x75, 0x6d, 0x3b, 0x43, 0x6d, 0x74, 0x3b, 0x50, 0x61, 0x7a, 0x61, 0x72, 0x3b, 0x50, 0x61, 0x7a, 0x61, 0x72, -0x74, 0x65, 0x73, 0x69, 0x3b, 0x53, 0x61, 0x6c, 0x131, 0x3b, 0xc7, 0x61, 0x72, 0x15f, 0x61, 0x6d, 0x62, 0x61, 0x3b, 0x50, -0x65, 0x72, 0x15f, 0x65, 0x6d, 0x62, 0x65, 0x3b, 0x43, 0x75, 0x6d, 0x61, 0x3b, 0x43, 0x75, 0x6d, 0x61, 0x72, 0x74, 0x65, -0x73, 0x69, 0x3b, 0x50, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0xc7, 0x3b, 0x50, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0xdd, 0x65, 0x6b, -0x3b, 0x44, 0x75, 0x15f, 0x3b, 0x53, 0x69, 0x15f, 0x3b, 0xc7, 0x61, 0x72, 0x3b, 0x50, 0x65, 0x6e, 0x3b, 0x41, 0x6e, 0x6e, -0x3b, 0x15e, 0x65, 0x6e, 0x3b, 0xdd, 0x65, 0x6b, 0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0x44, 0x75, 0x15f, 0x65, 0x6e, 0x62, -0x65, 0x3b, 0x53, 0x69, 0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0xc7, 0x61, 0x72, 0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0x50, -0x65, 0x6e, 0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0x41, 0x6e, 0x6e, 0x61, 0x3b, 0x15e, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0xdd, -0x3b, 0x44, 0x3b, 0x53, 0x3b, 0xc7, 0x3b, 0x50, 0x3b, 0x41, 0x3b, 0x15e, 0x3b, 0xfd, 0x65, 0x6b, 0x3b, 0x64, 0x75, 0x15f, -0x3b, 0x73, 0x69, 0x15f, 0x3b, 0xe7, 0x61, 0x72, 0x3b, 0x70, 0x65, 0x6e, 0x3b, 0x61, 0x6e, 0x6e, 0x3b, 0x15f, 0x65, 0x6e, -0x3b, 0xfd, 0x65, 0x6b, 0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0x64, 0x75, 0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0x73, 0x69, -0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0xe7, 0x61, 0x72, 0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0x70, 0x65, 0x6e, 0x15f, 0x65, -0x6e, 0x62, 0x65, 0x3b, 0x61, 0x6e, 0x6e, 0x61, 0x3b, 0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0x64a, 0x6d5, 0x3b, 0x62f, 0x6c8, -0x3b, 0x633, 0x6d5, 0x3b, 0x686, 0x627, 0x3b, 0x67e, 0x6d5, 0x3b, 0x62c, 0x6c8, 0x3b, 0x634, 0x6d5, 0x3b, 0x64a, 0x6d5, 0x643, 0x634, -0x6d5, 0x646, 0x628, 0x6d5, 0x3b, 0x62f, 0x6c8, 0x634, 0x6d5, 0x646, 0x628, 0x6d5, 0x3b, 0x633, 0x6d5, 0x64a, 0x634, 0x6d5, 0x646, 0x628, -0x6d5, 0x3b, 0x686, 0x627, 0x631, 0x634, 0x6d5, 0x646, 0x628, 0x6d5, 0x3b, 0x67e, 0x6d5, 0x64a, 0x634, 0x6d5, 0x646, 0x628, 0x6d5, 0x3b, -0x62c, 0x6c8, 0x645, 0x6d5, 0x3b, 0x634, 0x6d5, 0x646, 0x628, 0x6d5, 0x3b, 0x64a, 0x3b, 0x62f, 0x3b, 0x633, 0x3b, 0x686, 0x3b, 0x67e, -0x3b, 0x62c, 0x3b, 0x634, 0x3b, 0x43d, 0x435, 0x434, 0x456, 0x43b, 0x44f, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x456, 0x43b, 0x43e, -0x43a, 0x3b, 0x432, 0x456, 0x432, 0x442, 0x43e, 0x440, 0x43e, 0x43a, 0x3b, 0x441, 0x435, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, -0x442, 0x432, 0x435, 0x440, 0x3b, 0x43f, 0x2bc, 0x44f, 0x442, 0x43d, 0x438, 0x446, 0x44f, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430, -0x3b, 0x41d, 0x3b, 0x41f, 0x3b, 0x412, 0x3b, 0x421, 0x3b, 0x427, 0x3b, 0x41f, 0x3b, 0x421, 0x3b, 0x627, 0x62a, 0x648, 0x627, 0x631, -0x3b, 0x67e, 0x6cc, 0x631, 0x3b, 0x645, 0x646, 0x6af, 0x644, 0x3b, 0x628, 0x62f, 0x6be, 0x3b, 0x62c, 0x645, 0x639, 0x631, 0x627, 0x62a, -0x3b, 0x62c, 0x645, 0x639, 0x6c1, 0x3b, 0x6c1, 0x641, 0x62a, 0x6c1, 0x3b, 0x59, 0x61, 0x6b, 0x3b, 0x44, 0x75, 0x73, 0x68, 0x3b, -0x53, 0x65, 0x73, 0x68, 0x3b, 0x43, 0x68, 0x6f, 0x72, 0x3b, 0x50, 0x61, 0x79, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x53, 0x68, -0x61, 0x6e, 0x3b, 0x79, 0x61, 0x6b, 0x73, 0x68, 0x61, 0x6e, 0x62, 0x61, 0x3b, 0x64, 0x75, 0x73, 0x68, 0x61, 0x6e, 0x62, -0x61, 0x3b, 0x73, 0x65, 0x73, 0x68, 0x61, 0x6e, 0x62, 0x61, 0x3b, 0x63, 0x68, 0x6f, 0x72, 0x73, 0x68, 0x61, 0x6e, 0x62, -0x61, 0x3b, 0x70, 0x61, 0x79, 0x73, 0x68, 0x61, 0x6e, 0x62, 0x61, 0x3b, 0x6a, 0x75, 0x6d, 0x61, 0x3b, 0x73, 0x68, 0x61, -0x6e, 0x62, 0x61, 0x3b, 0x59, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x43, 0x3b, 0x50, 0x3b, 0x4a, 0x3b, 0x53, 0x3b, 0x6cc, 0x2e, -0x3b, 0x62f, 0x2e, 0x3b, 0x633, 0x2e, 0x3b, 0x686, 0x2e, 0x3b, 0x67e, 0x2e, 0x3b, 0x62c, 0x2e, 0x3b, 0x634, 0x2e, 0x3b, 0x42f, -0x43a, 0x448, 0x3b, 0x414, 0x443, 0x448, 0x3b, 0x421, 0x435, 0x448, 0x3b, 0x427, 0x43e, 0x440, 0x3b, 0x41f, 0x430, 0x439, 0x3b, 0x416, -0x443, 0x43c, 0x3b, 0x428, 0x430, 0x43d, 0x3b, 0x42f, 0x43a, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x414, 0x443, 0x448, 0x430, 0x43d, -0x431, 0x430, 0x3b, 0x421, 0x435, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x427, 0x43e, 0x440, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, -0x41f, 0x430, 0x439, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x416, 0x443, 0x43c, 0x430, 0x3b, 0x428, 0x430, 0x43d, 0x431, 0x430, 0x3b, -0x42f, 0x3b, 0x414, 0x3b, 0x421, 0x3b, 0x427, 0x3b, 0x41f, 0x3b, 0x416, 0x3b, 0x428, 0x3b, 0x44f, 0x43a, 0x448, 0x3b, 0x434, 0x443, -0x448, 0x3b, 0x441, 0x435, 0x448, 0x3b, 0x447, 0x43e, 0x440, 0x3b, 0x43f, 0x430, 0x439, 0x3b, 0x436, 0x443, 0x43c, 0x3b, 0x448, 0x430, -0x43d, 0x3b, 0x44f, 0x43a, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x434, 0x443, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x441, 0x435, -0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x447, 0x43e, 0x440, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x43f, 0x430, 0x439, 0x448, 0x430, -0x43d, 0x431, 0x430, 0x3b, 0x436, 0x443, 0x43c, 0x430, 0x3b, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x43, 0x4e, 0x3b, 0x54, 0x68, -0x20, 0x32, 0x3b, 0x54, 0x68, 0x20, 0x33, 0x3b, 0x54, 0x68, 0x20, 0x34, 0x3b, 0x54, 0x68, 0x20, 0x35, 0x3b, 0x54, 0x68, -0x20, 0x36, 0x3b, 0x54, 0x68, 0x20, 0x37, 0x3b, 0x43, 0x68, 0x1ee7, 0x20, 0x4e, 0x68, 0x1ead, 0x74, 0x3b, 0x54, 0x68, 0x1ee9, -0x20, 0x48, 0x61, 0x69, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x42, 0x61, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x54, 0x1b0, 0x3b, 0x54, -0x68, 0x1ee9, 0x20, 0x4e, 0x103, 0x6d, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x53, 0xe1, 0x75, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x42, -0x1ea3, 0x79, 0x3b, 0x43, 0x4e, 0x3b, 0x54, 0x32, 0x3b, 0x54, 0x33, 0x3b, 0x54, 0x34, 0x3b, 0x54, 0x35, 0x3b, 0x54, 0x36, -0x3b, 0x54, 0x37, 0x3b, 0x53, 0x75, 0x3b, 0x4d, 0x75, 0x3b, 0x54, 0x75, 0x3b, 0x56, 0x65, 0x3b, 0x44, 0xf6, 0x3b, 0x46, -0x72, 0x3b, 0x5a, 0xe4, 0x3b, 0x73, 0x75, 0x64, 0x65, 0x6c, 0x3b, 0x6d, 0x75, 0x64, 0x65, 0x6c, 0x3b, 0x74, 0x75, 0x64, -0x65, 0x6c, 0x3b, 0x76, 0x65, 0x64, 0x65, 0x6c, 0x3b, 0x64, 0xf6, 0x64, 0x65, 0x6c, 0x3b, 0x66, 0x72, 0x69, 0x64, 0x65, -0x6c, 0x3b, 0x7a, 0xe4, 0x64, 0x65, 0x6c, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x54, 0x3b, 0x56, 0x3b, 0x44, 0x3b, 0x46, 0x3b, -0x5a, 0x3b, 0x73, 0x75, 0x2e, 0x3b, 0x6d, 0x75, 0x2e, 0x3b, 0x74, 0x75, 0x2e, 0x3b, 0x76, 0x65, 0x2e, 0x3b, 0x64, 0xf6, -0x2e, 0x3b, 0x66, 0x72, 0x2e, 0x3b, 0x7a, 0xe4, 0x2e, 0x3b, 0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x6c, 0x75, 0x6e, 0x3b, 0x4d, -0x61, 0x77, 0x3b, 0x4d, 0x65, 0x72, 0x3b, 0x49, 0x61, 0x75, 0x3b, 0x47, 0x77, 0x65, 0x3b, 0x53, 0x61, 0x64, 0x3b, 0x44, -0x79, 0x64, 0x64, 0x20, 0x53, 0x75, 0x6c, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x4c, 0x6c, 0x75, 0x6e, 0x3b, 0x44, 0x79, -0x64, 0x64, 0x20, 0x4d, 0x61, 0x77, 0x72, 0x74, 0x68, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x4d, 0x65, 0x72, 0x63, 0x68, -0x65, 0x72, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x49, 0x61, 0x75, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x47, 0x77, 0x65, -0x6e, 0x65, 0x72, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x53, 0x61, 0x64, 0x77, 0x72, 0x6e, 0x3b, 0x53, 0x3b, 0x4c, 0x6c, -0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x49, 0x3b, 0x47, 0x3b, 0x53, 0x3b, 0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x6c, 0x75, 0x6e, 0x3b, -0x4d, 0x61, 0x77, 0x3b, 0x4d, 0x65, 0x72, 0x3b, 0x49, 0x61, 0x75, 0x3b, 0x47, 0x77, 0x65, 0x6e, 0x3b, 0x53, 0x61, 0x64, -0x3b, 0x44, 0x69, 0x62, 0x3b, 0x41, 0x6c, 0x74, 0x3b, 0x54, 0x61, 0x6c, 0x3b, 0xc0, 0x6c, 0x61, 0x3b, 0x41, 0x6c, 0x78, -0x3b, 0xc0, 0x6a, 0x6a, 0x3b, 0x41, 0x73, 0x65, 0x3b, 0x44, 0x69, 0x62, 0xe9, 0x65, 0x72, 0x3b, 0x41, 0x6c, 0x74, 0x69, -0x6e, 0x65, 0x3b, 0x54, 0x61, 0x6c, 0x61, 0x61, 0x74, 0x61, 0x3b, 0xc0, 0x6c, 0x61, 0x72, 0x62, 0x61, 0x3b, 0x41, 0x6c, -0x78, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0xc0, 0x6a, 0x6a, 0x75, 0x6d, 0x61, 0x3b, 0x41, 0x73, 0x65, 0x65, 0x72, 0x3b, 0x5d6, -0x5d5, 0x5e0, 0x5d8, 0x5d9, 0x5e7, 0x3b, 0x5de, 0x5d0, 0x5b8, 0x5e0, 0x5d8, 0x5d9, 0x5e7, 0x3b, 0x5d3, 0x5d9, 0x5e0, 0x5e1, 0x5d8, 0x5d9, -0x5e7, 0x3b, 0x5de, 0x5d9, 0x5d8, 0x5d5, 0x5d5, 0x5d0, 0x5da, 0x3b, 0x5d3, 0x5d0, 0x5e0, 0x5e2, 0x5e8, 0x5e9, 0x5d8, 0x5d9, 0x5e7, 0x3b, -0x5e4, 0x5bf, 0x5e8, 0x5f2, 0x5b7, 0x5d8, 0x5d9, 0x5e7, 0x3b, 0x5e9, 0x5d1, 0x5ea, 0x3b, 0xc0, 0xec, 0x6b, 0xfa, 0x3b, 0x41, 0x6a, -0xe9, 0x3b, 0xcc, 0x73, 0x1eb9, 0x301, 0x67, 0x75, 0x6e, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x72, 0xfa, 0x3b, 0x1ecc, 0x6a, 0x1ecd, -0x301, 0x62, 0x1ecd, 0x3b, 0x1eb8, 0x74, 0xec, 0x3b, 0xc0, 0x62, 0xe1, 0x6d, 0x1eb9, 0x301, 0x74, 0x61, 0x3b, 0x1ecc, 0x6a, 0x1ecd, -0x301, 0x20, 0xc0, 0xec, 0x6b, 0xfa, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x20, 0x41, 0x6a, 0xe9, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, -0x20, 0xcc, 0x73, 0x1eb9, 0x301, 0x67, 0x75, 0x6e, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x72, 0xfa, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, -0x62, 0x1ecd, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x20, 0x1eb8, 0x74, 0xec, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x20, 0xc0, 0x62, 0xe1, -0x6d, 0x1eb9, 0x301, 0x74, 0x61, 0x3b, 0xc0, 0xec, 0x6b, 0xfa, 0x3b, 0x41, 0x6a, 0xe9, 0x3b, 0xcc, 0x73, 0x25b, 0x301, 0x67, -0x75, 0x6e, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x72, 0xfa, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x62, 0x254, 0x3b, 0x190, 0x74, 0xec, -0x3b, 0xc0, 0x62, 0xe1, 0x6d, 0x25b, 0x301, 0x74, 0x61, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x20, 0xc0, 0xec, 0x6b, 0xfa, 0x3b, -0x186, 0x6a, 0x254, 0x301, 0x20, 0x41, 0x6a, 0xe9, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x20, 0xcc, 0x73, 0x25b, 0x301, 0x67, 0x75, -0x6e, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x72, 0xfa, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x62, 0x254, 0x3b, 0x186, 0x6a, 0x254, 0x301, -0x20, 0x190, 0x74, 0xec, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x20, 0xc0, 0x62, 0xe1, 0x6d, 0x25b, 0x301, 0x74, 0x61, 0x3b, 0x53, -0x6f, 0x6e, 0x3b, 0x4d, 0x73, 0x6f, 0x3b, 0x42, 0x69, 0x6c, 0x3b, 0x54, 0x68, 0x61, 0x3b, 0x53, 0x69, 0x6e, 0x3b, 0x48, -0x6c, 0x61, 0x3b, 0x4d, 0x67, 0x71, 0x3b, 0x49, 0x53, 0x6f, 0x6e, 0x74, 0x6f, 0x3b, 0x55, 0x4d, 0x73, 0x6f, 0x6d, 0x62, -0x75, 0x6c, 0x75, 0x6b, 0x6f, 0x3b, 0x55, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x55, 0x4c, 0x77, -0x65, 0x73, 0x69, 0x74, 0x68, 0x61, 0x74, 0x68, 0x75, 0x3b, 0x55, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x6e, 0x65, 0x3b, 0x55, -0x4c, 0x77, 0x65, 0x73, 0x69, 0x68, 0x6c, 0x61, 0x6e, 0x75, 0x3b, 0x55, 0x4d, 0x67, 0x71, 0x69, 0x62, 0x65, 0x6c, 0x6f, -0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x42, 0x3b, 0x54, 0x3b, 0x53, 0x3b, 0x48, 0x3b, 0x4d, 0x3b, 0x73, 0xf8, 0x6e, 0x3b, 0x6d, -0xe5, 0x6e, 0x3b, 0x74, 0x79, 0x73, 0x3b, 0x6f, 0x6e, 0x73, 0x3b, 0x74, 0x6f, 0x72, 0x3b, 0x66, 0x72, 0x65, 0x3b, 0x6c, -0x61, 0x75, 0x3b, 0x73, 0xf8, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x6d, 0xe5, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x79, 0x73, -0x64, 0x61, 0x67, 0x3b, 0x6f, 0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x6f, 0x72, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x66, -0x72, 0x65, 0x64, 0x61, 0x67, 0x3b, 0x6c, 0x61, 0x75, 0x72, 0x64, 0x61, 0x67, 0x3b, 0x73, 0xf8, 0x2e, 0x3b, 0x6d, 0xe5, -0x2e, 0x3b, 0x74, 0x79, 0x2e, 0x3b, 0x6f, 0x6e, 0x2e, 0x3b, 0x74, 0x6f, 0x2e, 0x3b, 0x66, 0x72, 0x2e, 0x3b, 0x6c, 0x61, -0x2e, 0x3b, 0x43d, 0x435, 0x434, 0x3b, 0x43f, 0x43e, 0x43d, 0x3b, 0x443, 0x442, 0x43e, 0x3b, 0x441, 0x440, 0x438, 0x3b, 0x447, 0x435, -0x442, 0x3b, 0x43f, 0x435, 0x442, 0x3b, 0x441, 0x443, 0x431, 0x3b, 0x43d, 0x435, 0x434, 0x458, 0x435, 0x459, 0x430, 0x3b, 0x43f, 0x43e, -0x43d, 0x435, 0x434, 0x458, 0x435, 0x459, 0x430, 0x43a, 0x3b, 0x443, 0x442, 0x43e, 0x440, 0x430, 0x43a, 0x3b, 0x441, 0x440, 0x438, 0x458, -0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x440, 0x442, 0x430, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x430, 0x43a, 0x3b, 0x441, -0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x4a, 0x65, 0x64, 0x3b, 0x4a, 0x65, 0x6c, 0x3b, 0x4a, 0x65, 0x6d, 0x3b, 0x4a, 0x65, -0x72, 0x63, 0x3b, 0x4a, 0x65, 0x72, 0x64, 0x3b, 0x4a, 0x65, 0x68, 0x3b, 0x4a, 0x65, 0x73, 0x3b, 0x4a, 0x65, 0x64, 0x6f, -0x6f, 0x6e, 0x65, 0x65, 0x3b, 0x4a, 0x65, 0x6c, 0x68, 0x65, 0x69, 0x6e, 0x3b, 0x4a, 0x65, 0x6d, 0x61, 0x79, 0x72, 0x74, -0x3b, 0x4a, 0x65, 0x72, 0x63, 0x65, 0x61, 0x6e, 0x3b, 0x4a, 0x65, 0x72, 0x64, 0x65, 0x69, 0x6e, 0x3b, 0x4a, 0x65, 0x68, -0x65, 0x69, 0x6e, 0x65, 0x79, 0x3b, 0x4a, 0x65, 0x73, 0x61, 0x72, 0x6e, 0x3b, 0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x75, 0x6e, -0x3b, 0x4d, 0x74, 0x68, 0x3b, 0x4d, 0x68, 0x72, 0x3b, 0x59, 0x6f, 0x77, 0x3b, 0x47, 0x77, 0x65, 0x3b, 0x53, 0x61, 0x64, -0x3b, 0x64, 0x79, 0x20, 0x53, 0x75, 0x6c, 0x3b, 0x64, 0x79, 0x20, 0x4c, 0x75, 0x6e, 0x3b, 0x64, 0x79, 0x20, 0x4d, 0x65, -0x75, 0x72, 0x74, 0x68, 0x3b, 0x64, 0x79, 0x20, 0x4d, 0x65, 0x72, 0x68, 0x65, 0x72, 0x3b, 0x64, 0x79, 0x20, 0x59, 0x6f, -0x77, 0x3b, 0x64, 0x79, 0x20, 0x47, 0x77, 0x65, 0x6e, 0x65, 0x72, 0x3b, 0x64, 0x79, 0x20, 0x53, 0x61, 0x64, 0x6f, 0x72, -0x6e, 0x3b, 0x4b, 0x77, 0x65, 0x3b, 0x44, 0x77, 0x6f, 0x3b, 0x42, 0x65, 0x6e, 0x3b, 0x57, 0x75, 0x6b, 0x3b, 0x59, 0x61, -0x77, 0x3b, 0x46, 0x69, 0x61, 0x3b, 0x4d, 0x65, 0x6d, 0x3b, 0x4b, 0x77, 0x65, 0x73, 0x69, 0x64, 0x61, 0x3b, 0x44, 0x77, -0x6f, 0x77, 0x64, 0x61, 0x3b, 0x42, 0x65, 0x6e, 0x61, 0x64, 0x61, 0x3b, 0x57, 0x75, 0x6b, 0x75, 0x64, 0x61, 0x3b, 0x59, -0x61, 0x77, 0x64, 0x61, 0x3b, 0x46, 0x69, 0x64, 0x61, 0x3b, 0x4d, 0x65, 0x6d, 0x65, 0x6e, 0x65, 0x64, 0x61, 0x3b, 0x4b, -0x3b, 0x44, 0x3b, 0x42, 0x3b, 0x57, 0x3b, 0x59, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x906, 0x92f, 0x924, 0x93e, 0x930, 0x3b, 0x938, -0x94b, 0x92e, 0x93e, 0x930, 0x3b, 0x92e, 0x902, 0x917, 0x933, 0x93e, 0x930, 0x3b, 0x92c, 0x941, 0x927, 0x935, 0x93e, 0x930, 0x3b, 0x917, -0x941, 0x930, 0x941, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x93e, 0x930, 0x3b, 0x936, 0x947, 0x928, 0x935, 0x93e, -0x930, 0x3b, 0x906, 0x3b, 0x938, 0x94b, 0x3b, 0x92e, 0x902, 0x3b, 0x92c, 0x941, 0x3b, 0x917, 0x941, 0x3b, 0x936, 0x941, 0x3b, 0x936, -0x947, 0x3b, 0x1ee4, 0x6b, 0x61, 0x3b, 0x4d, 0x1ecd, 0x6e, 0x3b, 0x54, 0x69, 0x75, 0x3b, 0x57, 0x65, 0x6e, 0x3b, 0x54, 0x1ecd, -0x1ecd, 0x3b, 0x46, 0x72, 0x61, 0x1ecb, 0x3b, 0x53, 0x61, 0x74, 0x3b, 0x4d, 0x62, 0x1ecd, 0x73, 0x1ecb, 0x20, 0x1ee4, 0x6b, 0x61, -0x3b, 0x4d, 0x1ecd, 0x6e, 0x64, 0x65, 0x3b, 0x54, 0x69, 0x75, 0x7a, 0x64, 0x65, 0x65, 0x3b, 0x57, 0x65, 0x6e, 0x65, 0x7a, -0x64, 0x65, 0x65, 0x3b, 0x54, 0x1ecd, 0x1ecd, 0x7a, 0x64, 0x65, 0x65, 0x3b, 0x46, 0x72, 0x61, 0x1ecb, 0x64, 0x65, 0x65, 0x3b, -0x53, 0x61, 0x74, 0x1ecd, 0x64, 0x65, 0x65, 0x3b, 0x57, 0x6b, 0x79, 0x3b, 0x57, 0x6b, 0x77, 0x3b, 0x57, 0x6b, 0x6c, 0x3b, -0x57, 0x74, 0x169, 0x3b, 0x57, 0x6b, 0x6e, 0x3b, 0x57, 0x74, 0x6e, 0x3b, 0x57, 0x74, 0x68, 0x3b, 0x57, 0x61, 0x20, 0x6b, -0x79, 0x75, 0x6d, 0x77, 0x61, 0x3b, 0x57, 0x61, 0x20, 0x6b, 0x77, 0x61, 0x6d, 0x62, 0x129, 0x6c, 0x129, 0x6c, 0x79, 0x61, -0x3b, 0x57, 0x61, 0x20, 0x6b, 0x65, 0x6c, 0x129, 0x3b, 0x57, 0x61, 0x20, 0x6b, 0x61, 0x74, 0x61, 0x74, 0x169, 0x3b, 0x57, -0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x57, 0x61, 0x20, 0x6b, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x57, 0x61, 0x20, -0x74, 0x68, 0x61, 0x6e, 0x74, 0x68, 0x61, 0x74, 0x169, 0x3b, 0x59, 0x3b, 0x57, 0x3b, 0x45, 0x3b, 0x41, 0x3b, 0x41, 0x3b, -0x41, 0x3b, 0x41, 0x3b, 0x64, 0x6f, 0x6d, 0x3b, 0x6c, 0x75, 0x6e, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0x69, 0x65, 0x3b, -0x6a, 0x6f, 0x69, 0x3b, 0x76, 0x69, 0x6e, 0x3b, 0x73, 0x61, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x65, 0x6e, 0x69, 0x65, 0x3b, -0x6c, 0x75, 0x6e, 0x69, 0x73, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x61, 0x72, 0x73, 0x3b, 0x6d, 0x69, 0x65, 0x72, 0x63, 0x75, -0x73, 0x3b, 0x6a, 0x6f, 0x69, 0x62, 0x65, 0x3b, 0x76, 0x69, 0x6e, 0x61, 0x72, 0x73, 0x3b, 0x73, 0x61, 0x62, 0x69, 0x64, -0x65, 0x3b, 0x6b, 0x254, 0x73, 0x3b, 0x64, 0x7a, 0x6f, 0x3b, 0x62, 0x6c, 0x61, 0x3b, 0x6b, 0x75, 0x256, 0x3b, 0x79, 0x61, -0x77, 0x3b, 0x66, 0x69, 0x256, 0x3b, 0x6d, 0x65, 0x6d, 0x3b, 0x6b, 0x254, 0x73, 0x69, 0x256, 0x61, 0x3b, 0x64, 0x7a, 0x6f, -0x256, 0x61, 0x3b, 0x62, 0x6c, 0x61, 0x256, 0x61, 0x3b, 0x6b, 0x75, 0x256, 0x61, 0x3b, 0x79, 0x61, 0x77, 0x6f, 0x256, 0x61, -0x3b, 0x66, 0x69, 0x256, 0x61, 0x3b, 0x6d, 0x65, 0x6d, 0x6c, 0x65, 0x256, 0x61, 0x3b, 0x6b, 0x3b, 0x64, 0x3b, 0x62, 0x3b, -0x6b, 0x3b, 0x79, 0x3b, 0x66, 0x3b, 0x6d, 0x3b, 0x4c, 0x50, 0x3b, 0x50, 0x31, 0x3b, 0x50, 0x32, 0x3b, 0x50, 0x33, 0x3b, -0x50, 0x34, 0x3b, 0x50, 0x35, 0x3b, 0x50, 0x36, 0x3b, 0x4c, 0x101, 0x70, 0x75, 0x6c, 0x65, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, -0x6b, 0x61, 0x68, 0x69, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x6c, 0x75, 0x61, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x6b, 0x6f, 0x6c, -0x75, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x68, 0x101, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x6c, 0x69, 0x6d, 0x61, 0x3b, 0x50, 0x6f, -0x2bb, 0x61, 0x6f, 0x6e, 0x6f, 0x3b, 0x4c, 0x69, 0x6e, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x4d, 0x69, -0x79, 0x3b, 0x48, 0x75, 0x77, 0x3b, 0x42, 0x69, 0x79, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4c, 0x69, 0x6e, 0x67, 0x67, 0x6f, -0x3b, 0x4c, 0x75, 0x6e, 0x65, 0x73, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x3b, 0x4d, 0x69, 0x79, 0x65, 0x72, 0x6b, -0x75, 0x6c, 0x65, 0x73, 0x3b, 0x48, 0x75, 0x77, 0x65, 0x62, 0x65, 0x73, 0x3b, 0x42, 0x69, 0x79, 0x65, 0x72, 0x6e, 0x65, -0x73, 0x3b, 0x53, 0x61, 0x62, 0x61, 0x64, 0x6f, 0x3b, 0x53, 0x75, 0x2e, 0x3b, 0x4d, 0xe4, 0x2e, 0x3b, 0x5a, 0x69, 0x2e, -0x3b, 0x4d, 0x69, 0x2e, 0x3b, 0x44, 0x75, 0x2e, 0x3b, 0x46, 0x72, 0x2e, 0x3b, 0x53, 0x61, 0x2e, 0x3b, 0x53, 0x75, 0x6e, -0x6e, 0x74, 0x69, 0x67, 0x3b, 0x4d, 0xe4, 0xe4, 0x6e, 0x74, 0x69, 0x67, 0x3b, 0x5a, 0x69, 0x69, 0x73, 0x63, 0x68, 0x74, -0x69, 0x67, 0x3b, 0x4d, 0x69, 0x74, 0x74, 0x77, 0x75, 0x63, 0x68, 0x3b, 0x44, 0x75, 0x6e, 0x73, 0x63, 0x68, 0x74, 0x69, -0x67, 0x3b, 0x46, 0x72, 0x69, 0x69, 0x74, 0x69, 0x67, 0x3b, 0x53, 0x61, 0x6d, 0x73, 0x63, 0x68, 0x74, 0x69, 0x67, 0x3b, -0xa46d, 0xa18f, 0x3b, 0xa18f, 0xa2cd, 0x3b, 0xa18f, 0xa44d, 0x3b, 0xa18f, 0xa315, 0x3b, 0xa18f, 0xa1d6, 0x3b, 0xa18f, 0xa26c, 0x3b, 0xa18f, 0xa0d8, -0x3b, 0xa46d, 0xa18f, 0xa44d, 0x3b, 0xa18f, 0xa282, 0xa2cd, 0x3b, 0xa18f, 0xa282, 0xa44d, 0x3b, 0xa18f, 0xa282, 0xa315, 0x3b, 0xa18f, 0xa282, 0xa1d6, -0x3b, 0xa18f, 0xa282, 0xa26c, 0x3b, 0xa18f, 0xa282, 0xa0d8, 0x3b, 0xa18f, 0x3b, 0xa2cd, 0x3b, 0xa44d, 0x3b, 0xa315, 0x3b, 0xa1d6, 0x3b, 0xa26c, -0x3b, 0xa0d8, 0x3b, 0x53, 0xfc, 0x2e, 0x3b, 0x4d, 0x61, 0x2e, 0x3b, 0x44, 0x69, 0x2e, 0x3b, 0x4d, 0x69, 0x2e, 0x3b, 0x44, -0x75, 0x2e, 0x3b, 0x46, 0x72, 0x2e, 0x3b, 0x53, 0x61, 0x2e, 0x3b, 0x53, 0xfc, 0x6e, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x4d, -0x61, 0x61, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x44, 0x69, 0x6e, 0x67, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x4d, 0x69, 0x64, 0x64, -0x65, 0x77, 0x65, 0x6b, 0x65, 0x6e, 0x3b, 0x44, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x46, 0x72, -0x65, 0x65, 0x64, 0x61, 0x67, 0x3b, 0x53, 0xfc, 0x6e, 0x6e, 0x61, 0x76, 0x65, 0x6e, 0x64, 0x3b, 0x73, 0x6f, 0x74, 0x6e, -0x3b, 0x76, 0x75, 0x6f, 0x73, 0x3b, 0x6d, 0x61, 0x14b, 0x3b, 0x67, 0x61, 0x73, 0x6b, 0x3b, 0x64, 0x75, 0x6f, 0x72, 0x3b, -0x62, 0x65, 0x61, 0x72, 0x3b, 0x6c, 0xe1, 0x76, 0x3b, 0x73, 0x6f, 0x74, 0x6e, 0x61, 0x62, 0x65, 0x61, 0x69, 0x76, 0x69, -0x3b, 0x76, 0x75, 0x6f, 0x73, 0x73, 0xe1, 0x72, 0x67, 0x61, 0x3b, 0x6d, 0x61, 0x14b, 0x14b, 0x65, 0x62, 0xe1, 0x72, 0x67, -0x61, 0x3b, 0x67, 0x61, 0x73, 0x6b, 0x61, 0x76, 0x61, 0x68, 0x6b, 0x6b, 0x75, 0x3b, 0x64, 0x75, 0x6f, 0x72, 0x61, 0x73, -0x64, 0x61, 0x74, 0x3b, 0x62, 0x65, 0x61, 0x72, 0x6a, 0x61, 0x64, 0x61, 0x74, 0x3b, 0x6c, 0xe1, 0x76, 0x76, 0x61, 0x72, -0x64, 0x61, 0x74, 0x3b, 0x53, 0x3b, 0x56, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x44, 0x3b, 0x42, 0x3b, 0x4c, 0x3b, 0x73, 0x6f, -0x3b, 0x6d, 0xe1, 0x3b, 0x64, 0x69, 0x3b, 0x67, 0x61, 0x3b, 0x64, 0x75, 0x3b, 0x62, 0x65, 0x3b, 0x6c, 0xe1, 0x3b, 0x73, -0x6f, 0x74, 0x6e, 0x61, 0x62, 0x65, 0x61, 0x69, 0x76, 0x69, 0x3b, 0x6d, 0xe1, 0x6e, 0x6e, 0x6f, 0x64, 0x61, 0x74, 0x3b, -0x64, 0x69, 0x73, 0x64, 0x61, 0x74, 0x3b, 0x67, 0x61, 0x73, 0x6b, 0x61, 0x76, 0x61, 0x68, 0x6b, 0x6b, 0x75, 0x3b, 0x64, -0x75, 0x6f, 0x72, 0x61, 0x73, 0x74, 0x61, 0x74, 0x3b, 0x62, 0x65, 0x61, 0x72, 0x6a, 0x61, 0x64, 0x61, 0x74, 0x3b, 0x6c, -0xe1, 0x76, 0x76, 0x6f, 0x72, 0x64, 0x61, 0x74, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x44, 0x3b, 0x47, 0x3b, 0x44, 0x3b, 0x42, -0x3b, 0x4c, 0x3b, 0x43, 0x70, 0x72, 0x3b, 0x43, 0x74, 0x74, 0x3b, 0x43, 0x6d, 0x6e, 0x3b, 0x43, 0x6d, 0x74, 0x3b, 0x41, -0x72, 0x73, 0x3b, 0x49, 0x63, 0x6d, 0x3b, 0x45, 0x73, 0x74, 0x3b, 0x43, 0x68, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x72, 0x69, -0x3b, 0x43, 0x68, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x6f, 0x3b, 0x43, 0x68, 0x75, 0x6d, 0x61, 0x69, 0x6e, 0x65, 0x3b, -0x43, 0x68, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x72, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x63, -0x68, 0x75, 0x6d, 0x61, 0x3b, 0x45, 0x73, 0x61, 0x62, 0x61, 0x74, 0x6f, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x43, -0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x45, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x4a, 0x69, 0x6d, 0x3b, 0x4b, 0x61, 0x77, 0x3b, 0x4b, -0x61, 0x64, 0x3b, 0x4b, 0x61, 0x6e, 0x3b, 0x4b, 0x61, 0x73, 0x3b, 0x4e, 0x67, 0x75, 0x3b, 0x49, 0x74, 0x75, 0x6b, 0x75, -0x20, 0x6a, 0x61, 0x20, 0x6a, 0x75, 0x6d, 0x77, 0x61, 0x3b, 0x4b, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x20, 0x6a, -0x69, 0x6d, 0x77, 0x65, 0x72, 0x69, 0x3b, 0x4b, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x20, 0x6b, 0x61, 0x77, 0x69, -0x3b, 0x4b, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x20, 0x6b, 0x61, 0x64, 0x61, 0x64, 0x75, 0x3b, 0x4b, 0x75, 0x72, -0x61, 0x6d, 0x75, 0x6b, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4b, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x20, -0x6b, 0x61, 0x73, 0x61, 0x6e, 0x75, 0x3b, 0x4b, 0x69, 0x66, 0x75, 0x6c, 0x61, 0x20, 0x6e, 0x67, 0x75, 0x77, 0x6f, 0x3b, -0x4a, 0x3b, 0x4a, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x64, 0x65, 0x77, 0x3b, 0x61, 0x61, -0x253, 0x3b, 0x6d, 0x61, 0x77, 0x3b, 0x6e, 0x6a, 0x65, 0x3b, 0x6e, 0x61, 0x61, 0x3b, 0x6d, 0x77, 0x64, 0x3b, 0x68, 0x62, -0x69, 0x3b, 0x64, 0x65, 0x77, 0x6f, 0x3b, 0x61, 0x61, 0x253, 0x6e, 0x64, 0x65, 0x3b, 0x6d, 0x61, 0x77, 0x62, 0x61, 0x61, -0x72, 0x65, 0x3b, 0x6e, 0x6a, 0x65, 0x73, 0x6c, 0x61, 0x61, 0x72, 0x65, 0x3b, 0x6e, 0x61, 0x61, 0x73, 0x61, 0x61, 0x6e, -0x64, 0x65, 0x3b, 0x6d, 0x61, 0x77, 0x6e, 0x64, 0x65, 0x3b, 0x68, 0x6f, 0x6f, 0x72, 0x65, 0x2d, 0x62, 0x69, 0x69, 0x72, -0x3b, 0x64, 0x3b, 0x61, 0x3b, 0x6d, 0x3b, 0x6e, 0x3b, 0x6e, 0x3b, 0x6d, 0x3b, 0x68, 0x3b, 0x4b, 0x4d, 0x41, 0x3b, 0x4e, -0x54, 0x54, 0x3b, 0x4e, 0x4d, 0x4e, 0x3b, 0x4e, 0x4d, 0x54, 0x3b, 0x41, 0x52, 0x54, 0x3b, 0x4e, 0x4d, 0x41, 0x3b, 0x4e, -0x4d, 0x4d, 0x3b, 0x4b, 0x69, 0x75, 0x6d, 0x69, 0x61, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x169, 0x3b, -0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x69, 0x6e, 0x65, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x61, 0x3b, 0x41, -0x72, 0x61, 0x6d, 0x69, 0x74, 0x68, 0x69, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, -0x6d, 0x6f, 0x74, 0x68, 0x69, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x41, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, -0x41, 0x72, 0x65, 0x3b, 0x4b, 0x75, 0x6e, 0x3b, 0x4f, 0x6e, 0x67, 0x3b, 0x49, 0x6e, 0x65, 0x3b, 0x49, 0x6c, 0x65, 0x3b, -0x53, 0x61, 0x70, 0x3b, 0x4b, 0x77, 0x65, 0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x61, 0x72, -0x65, 0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x6b, 0x75, 0x6e, 0x69, 0x3b, 0x4d, 0x64, 0x65, -0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x6f, 0x6e, 0x67, 0x2019, 0x77, 0x61, 0x6e, 0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f, -0x74, 0x20, 0x65, 0x65, 0x20, 0x69, 0x6e, 0x65, 0x74, 0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, -0x69, 0x6c, 0x65, 0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x73, 0x61, 0x70, 0x61, 0x3b, 0x4d, -0x64, 0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x6b, 0x77, 0x65, 0x3b, 0x41, 0x3b, 0x4b, 0x3b, 0x4f, 0x3b, 0x49, -0x3b, 0x49, 0x3b, 0x53, 0x3b, 0x4b, 0x3b, 0x44, 0x69, 0x6d, 0x3b, 0x50, 0x6f, 0x73, 0x3b, 0x50, 0x69, 0x72, 0x3b, 0x54, -0x61, 0x74, 0x3b, 0x4e, 0x61, 0x69, 0x3b, 0x53, 0x68, 0x61, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x44, 0x69, 0x6d, 0x69, 0x6e, -0x67, 0x75, 0x3b, 0x43, 0x68, 0x69, 0x70, 0x6f, 0x73, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x70, 0x69, 0x72, 0x69, 0x3b, 0x43, -0x68, 0x69, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x73, 0x68, 0x61, -0x6e, 0x75, 0x3b, 0x53, 0x61, 0x62, 0x75, 0x64, 0x75, 0x3b, 0x44, 0x3b, 0x50, 0x3b, 0x43, 0x3b, 0x54, 0x3b, 0x4e, 0x3b, -0x53, 0x3b, 0x53, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0x76, 0x75, 0x3b, 0x53, 0x69, 0x62, 0x3b, 0x53, 0x69, 0x74, 0x3b, -0x53, 0x69, 0x6e, 0x3b, 0x53, 0x69, 0x68, 0x3b, 0x4d, 0x67, 0x71, 0x3b, 0x53, 0x6f, 0x6e, 0x74, 0x6f, 0x3b, 0x4d, 0x76, -0x75, 0x6c, 0x6f, 0x3b, 0x53, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x53, 0x69, 0x74, 0x68, 0x61, 0x74, 0x68, 0x75, 0x3b, -0x53, 0x69, 0x6e, 0x65, 0x3b, 0x53, 0x69, 0x68, 0x6c, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x67, 0x71, 0x69, 0x62, 0x65, 0x6c, -0x6f, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x49, 0x6a, 0x70, 0x3b, -0x49, 0x6a, 0x74, 0x3b, 0x49, 0x6a, 0x6e, 0x3b, 0x49, 0x6a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x75, -0x3b, 0x49, 0x6a, 0x6d, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x6c, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, -0x74, 0x61, 0x74, 0x75, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x74, -0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, -0x49, 0x6a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x32, 0x3b, 0x33, 0x3b, 0x34, 0x3b, 0x35, 0x3b, 0x36, 0x3b, -0x37, 0x3b, 0x31, 0x3b, 0x2d30, 0x2d59, 0x2d30, 0x3b, 0x2d30, 0x2d62, 0x2d4f, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x3b, 0x2d30, 0x2d3d, 0x2d55, 0x3b, -0x2d30, 0x2d3d, 0x2d61, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d4e, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d39, 0x3b, 0x2d30, 0x2d59, 0x2d30, 0x2d4e, 0x2d30, 0x2d59, -0x3b, 0x2d30, 0x2d62, 0x2d4f, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d4f, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d3d, 0x2d55, 0x2d30, 0x2d59, 0x3b, -0x2d30, 0x2d3d, 0x2d61, 0x2d30, 0x2d59, 0x3b, 0x2d59, 0x2d49, 0x2d4e, 0x2d61, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d39, 0x2d62, 0x2d30, 0x2d59, -0x3b, 0x61, 0x73, 0x61, 0x3b, 0x61, 0x79, 0x6e, 0x3b, 0x61, 0x73, 0x69, 0x3b, 0x61, 0x6b, 0x1e5b, 0x3b, 0x61, 0x6b, 0x77, -0x3b, 0x61, 0x73, 0x69, 0x6d, 0x3b, 0x61, 0x73, 0x69, 0x1e0d, 0x3b, 0x61, 0x73, 0x61, 0x6d, 0x61, 0x73, 0x3b, 0x61, 0x79, -0x6e, 0x61, 0x73, 0x3b, 0x61, 0x73, 0x69, 0x6e, 0x61, 0x73, 0x3b, 0x61, 0x6b, 0x1e5b, 0x61, 0x73, 0x3b, 0x61, 0x6b, 0x77, -0x61, 0x73, 0x3b, 0x61, 0x73, 0x69, 0x6d, 0x77, 0x61, 0x73, 0x3b, 0x61, 0x73, 0x69, 0x1e0d, 0x79, 0x61, 0x73, 0x3b, 0x41, -0x63, 0x65, 0x3b, 0x41, 0x72, 0x69, 0x3b, 0x41, 0x72, 0x61, 0x3b, 0x41, 0x68, 0x61, 0x3b, 0x41, 0x6d, 0x68, 0x3b, 0x53, -0x65, 0x6d, 0x3b, 0x53, 0x65, 0x64, 0x3b, 0x41, 0x63, 0x65, 0x72, 0x3b, 0x41, 0x72, 0x69, 0x6d, 0x3b, 0x41, 0x72, 0x61, -0x6d, 0x3b, 0x41, 0x68, 0x61, 0x64, 0x3b, 0x41, 0x6d, 0x68, 0x61, 0x64, 0x3b, 0x53, 0x65, 0x6d, 0x3b, 0x53, 0x65, 0x64, -0x3b, 0x59, 0x3b, 0x53, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x59, 0x61, 0x6e, 0x3b, 0x53, -0x61, 0x6e, 0x3b, 0x4b, 0x72, 0x61, 0x1e0d, 0x3b, 0x4b, 0x75, 0x1e93, 0x3b, 0x53, 0x61, 0x6d, 0x3b, 0x53, 0x1e0d, 0x69, 0x73, -0x3b, 0x53, 0x61, 0x79, 0x3b, 0x59, 0x61, 0x6e, 0x61, 0x73, 0x73, 0x3b, 0x53, 0x61, 0x6e, 0x61, 0x73, 0x73, 0x3b, 0x4b, -0x72, 0x61, 0x1e0d, 0x61, 0x73, 0x73, 0x3b, 0x4b, 0x75, 0x1e93, 0x61, 0x73, 0x73, 0x3b, 0x53, 0x61, 0x6d, 0x61, 0x73, 0x73, -0x3b, 0x53, 0x1e0d, 0x69, 0x73, 0x61, 0x73, 0x73, 0x3b, 0x53, 0x61, 0x79, 0x61, 0x73, 0x73, 0x3b, 0x43, 0x3b, 0x52, 0x3b, -0x41, 0x3b, 0x48, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x44, 0x3b, 0x53, 0x41, 0x4e, 0x3b, 0x4f, 0x52, 0x4b, 0x3b, 0x4f, 0x4b, -0x42, 0x3b, 0x4f, 0x4b, 0x53, 0x3b, 0x4f, 0x4b, 0x4e, 0x3b, 0x4f, 0x4b, 0x54, 0x3b, 0x4f, 0x4d, 0x4b, 0x3b, 0x53, 0x61, -0x6e, 0x64, 0x65, 0x3b, 0x4f, 0x72, 0x77, 0x6f, 0x6b, 0x75, 0x62, 0x61, 0x6e, 0x7a, 0x61, 0x3b, 0x4f, 0x72, 0x77, 0x61, -0x6b, 0x61, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4f, 0x72, 0x77, 0x61, 0x6b, 0x61, 0x73, 0x68, 0x61, 0x74, 0x75, 0x3b, 0x4f, -0x72, 0x77, 0x61, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4f, 0x72, 0x77, 0x61, 0x6b, 0x61, 0x74, 0x61, 0x61, 0x6e, 0x6f, 0x3b, -0x4f, 0x72, 0x77, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x61, 0x67, 0x61, 0x3b, 0x53, 0x3b, 0x4b, 0x3b, 0x52, 0x3b, 0x53, 0x3b, -0x4e, 0x3b, 0x54, 0x3b, 0x4d, 0x3b, 0x4d, 0x75, 0x6c, 0x3b, 0x56, 0x69, 0x6c, 0x3b, 0x48, 0x69, 0x76, 0x3b, 0x48, 0x69, -0x64, 0x3b, 0x48, 0x69, 0x74, 0x3b, 0x48, 0x69, 0x68, 0x3b, 0x4c, 0x65, 0x6d, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x75, 0x6c, -0x75, 0x6e, 0x67, 0x75, 0x3b, 0x70, 0x61, 0x20, 0x73, 0x68, 0x61, 0x68, 0x75, 0x76, 0x69, 0x6c, 0x75, 0x68, 0x61, 0x3b, -0x70, 0x61, 0x20, 0x68, 0x69, 0x76, 0x69, 0x6c, 0x69, 0x3b, 0x70, 0x61, 0x20, 0x68, 0x69, 0x64, 0x61, 0x74, 0x75, 0x3b, -0x70, 0x61, 0x20, 0x68, 0x69, 0x74, 0x61, 0x79, 0x69, 0x3b, 0x70, 0x61, 0x20, 0x68, 0x69, 0x68, 0x61, 0x6e, 0x75, 0x3b, -0x70, 0x61, 0x20, 0x73, 0x68, 0x61, 0x68, 0x75, 0x6c, 0x65, 0x6d, 0x62, 0x65, 0x6c, 0x61, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, -0x48, 0x3b, 0x48, 0x3b, 0x48, 0x3b, 0x57, 0x3b, 0x4a, 0x3b, 0x4a, 0x70, 0x69, 0x3b, 0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6e, -0x6e, 0x3b, 0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x75, 0x3b, 0x4a, 0x6d, 0x6f, 0x3b, 0x4a, 0x75, -0x6d, 0x61, 0x70, 0x69, 0x6c, 0x79, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x75, 0x75, 0x3b, 0x4a, 0x75, -0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x75, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, -0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, -0x4a, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x4a, 0x3b, 0x6b, 0x61, 0x72, 0x3b, 0x6e, 0x74, -0x25b, 0x3b, 0x74, 0x61, 0x72, 0x3b, 0x61, 0x72, 0x61, 0x3b, 0x61, 0x6c, 0x61, 0x3b, 0x6a, 0x75, 0x6d, 0x3b, 0x73, 0x69, -0x62, 0x3b, 0x6b, 0x61, 0x72, 0x69, 0x3b, 0x6e, 0x74, 0x25b, 0x6e, 0x25b, 0x3b, 0x74, 0x61, 0x72, 0x61, 0x74, 0x61, 0x3b, -0x61, 0x72, 0x61, 0x62, 0x61, 0x3b, 0x61, 0x6c, 0x61, 0x6d, 0x69, 0x73, 0x61, 0x3b, 0x6a, 0x75, 0x6d, 0x61, 0x3b, 0x73, -0x69, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x4a, 0x3b, 0x53, 0x3b, -0x4b, 0x6d, 0x61, 0x3b, 0x54, 0x61, 0x74, 0x3b, 0x49, 0x6e, 0x65, 0x3b, 0x54, 0x61, 0x6e, 0x3b, 0x41, 0x72, 0x6d, 0x3b, -0x4d, 0x61, 0x61, 0x3b, 0x4e, 0x4d, 0x4d, 0x3b, 0x4b, 0x69, 0x75, 0x6d, 0x69, 0x61, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, -0x74, 0x61, 0x74, 0x75, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x69, 0x6e, 0x65, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x74, -0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x72, 0x61, 0x6d, 0x69, 0x74, 0x68, 0x69, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, -0x4e, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x74, 0x68, 0x69, 0x69, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, -0x41, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x13c6, 0x13cd, 0x13ac, 0x3b, 0x13c9, 0x13c5, 0x13af, 0x3b, 0x13d4, 0x13b5, 0x13c1, 0x3b, 0x13e6, 0x13a2, -0x13c1, 0x3b, 0x13c5, 0x13a9, 0x13c1, 0x3b, 0x13e7, 0x13be, 0x13a9, 0x3b, 0x13c8, 0x13d5, 0x13be, 0x3b, 0x13a4, 0x13be, 0x13d9, 0x13d3, 0x13c6, 0x13cd, -0x13ac, 0x3b, 0x13a4, 0x13be, 0x13d9, 0x13d3, 0x13c9, 0x13c5, 0x13af, 0x3b, 0x13d4, 0x13b5, 0x13c1, 0x13a2, 0x13a6, 0x3b, 0x13e6, 0x13a2, 0x13c1, 0x13a2, -0x13a6, 0x3b, 0x13c5, 0x13a9, 0x13c1, 0x13a2, 0x13a6, 0x3b, 0x13e7, 0x13be, 0x13a9, 0x13b6, 0x13cd, 0x13d7, 0x3b, 0x13a4, 0x13be, 0x13d9, 0x13d3, 0x13c8, -0x13d5, 0x13be, 0x3b, 0x13c6, 0x3b, 0x13c9, 0x3b, 0x13d4, 0x3b, 0x13e6, 0x3b, 0x13c5, 0x3b, 0x13e7, 0x3b, 0x13a4, 0x3b, 0x64, 0x69, 0x6d, -0x3b, 0x6c, 0x69, 0x6e, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0x65, 0x72, 0x3b, 0x7a, 0x65, 0x3b, 0x76, 0x61, 0x6e, 0x3b, -0x73, 0x61, 0x6d, 0x3b, 0x64, 0x69, 0x6d, 0x61, 0x6e, 0x73, 0x3b, 0x6c, 0x69, 0x6e, 0x64, 0x69, 0x3b, 0x6d, 0x61, 0x72, -0x64, 0x69, 0x3b, 0x6d, 0x65, 0x72, 0x6b, 0x72, 0x65, 0x64, 0x69, 0x3b, 0x7a, 0x65, 0x64, 0x69, 0x3b, 0x76, 0x61, 0x6e, -0x64, 0x72, 0x65, 0x64, 0x69, 0x3b, 0x73, 0x61, 0x6d, 0x64, 0x69, 0x3b, 0x64, 0x3b, 0x6c, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, -0x7a, 0x3b, 0x76, 0x3b, 0x73, 0x3b, 0x4c, 0x6c, 0x32, 0x3b, 0x4c, 0x6c, 0x33, 0x3b, 0x4c, 0x6c, 0x34, 0x3b, 0x4c, 0x6c, -0x35, 0x3b, 0x4c, 0x6c, 0x36, 0x3b, 0x4c, 0x6c, 0x37, 0x3b, 0x4c, 0x6c, 0x31, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, -0x20, 0x6c, 0x79, 0x61, 0x70, 0x69, 0x6c, 0x69, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x74, -0x61, 0x74, 0x75, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x63, 0x68, -0x69, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x6e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x3b, 0x4c, -0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x6e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x6c, -0x69, 0x6e, 0x6a, 0x69, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x6e, 0x6e, 0x79, 0x61, 0x6e, -0x6f, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x76, 0x69, 0x6c, 0x69, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, -0x69, 0x74, 0x61, 0x6e, 0x64, 0x69, 0x3b, 0x50, 0xed, 0x69, 0x6c, 0x69, 0x3b, 0x54, 0xe1, 0x61, 0x74, 0x75, 0x3b, 0xcd, -0x6e, 0x65, 0x3b, 0x54, 0xe1, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x6d, 0x3b, 0x4d, 0xf3, 0x6f, -0x73, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0xed, 0x69, 0x72, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0xe1, 0x74, -0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0xed, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0xe1, 0x61, 0x6e, 0x6f, 0x3b, -0x41, 0x6c, 0x61, 0x6d, 0xed, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0xe1, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61, -0x6d, 0xf3, 0x6f, 0x73, 0x69, 0x3b, 0x50, 0x3b, 0x54, 0x3b, 0x45, 0x3b, 0x4f, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x4d, 0x3b, -0x53, 0x61, 0x62, 0x3b, 0x42, 0x61, 0x6c, 0x3b, 0x4c, 0x77, 0x32, 0x3b, 0x4c, 0x77, 0x33, 0x3b, 0x4c, 0x77, 0x34, 0x3b, -0x4c, 0x77, 0x35, 0x3b, 0x4c, 0x77, 0x36, 0x3b, 0x53, 0x61, 0x62, 0x62, 0x69, 0x69, 0x74, 0x69, 0x3b, 0x42, 0x61, 0x6c, -0x61, 0x7a, 0x61, 0x3b, 0x4c, 0x77, 0x61, 0x6b, 0x75, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4c, 0x77, 0x61, 0x6b, 0x75, 0x73, -0x61, 0x74, 0x75, 0x3b, 0x4c, 0x77, 0x61, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x4c, 0x77, 0x61, 0x6b, 0x75, 0x74, 0x61, 0x61, -0x6e, 0x6f, 0x3b, 0x4c, 0x77, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x61, 0x67, 0x61, 0x3b, 0x53, 0x3b, 0x42, 0x3b, 0x4c, 0x3b, -0x4c, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x50, 0x61, 0x20, 0x4d, 0x75, 0x6c, 0x75, 0x6e, 0x67, 0x75, 0x3b, 0x50, -0x61, 0x6c, 0x69, 0x63, 0x68, 0x69, 0x6d, 0x6f, 0x3b, 0x50, 0x61, 0x6c, 0x69, 0x63, 0x68, 0x69, 0x62, 0x75, 0x6c, 0x69, -0x3b, 0x50, 0x61, 0x6c, 0x69, 0x63, 0x68, 0x69, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x50, 0x61, 0x6c, 0x69, 0x63, 0x68, 0x69, -0x6e, 0x65, 0x3b, 0x50, 0x61, 0x6c, 0x69, 0x63, 0x68, 0x69, 0x73, 0x61, 0x6e, 0x6f, 0x3b, 0x50, 0x61, 0x63, 0x68, 0x69, -0x62, 0x65, 0x6c, 0x75, 0x73, 0x68, 0x69, 0x3b, 0x64, 0x75, 0x6d, 0x3b, 0x73, 0x69, 0x67, 0x3b, 0x74, 0x65, 0x72, 0x3b, -0x6b, 0x75, 0x61, 0x3b, 0x6b, 0x69, 0x6e, 0x3b, 0x73, 0x65, 0x73, 0x3b, 0x73, 0x61, 0x62, 0x3b, 0x64, 0x75, 0x6d, 0x69, -0x6e, 0x67, 0x75, 0x3b, 0x73, 0x69, 0x67, 0x75, 0x6e, 0x64, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x74, 0x65, 0x72, -0x73, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x6b, 0x75, 0x61, 0x72, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, -0x6b, 0x69, 0x6e, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x73, 0x65, 0x73, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x72, -0x61, 0x3b, 0x73, 0xe1, 0x62, 0x61, 0x64, 0x75, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x53, -0x3b, 0x53, 0x3b, 0x64, 0x75, 0x6d, 0x69, 0x6e, 0x67, 0x75, 0x3b, 0x73, 0x69, 0x67, 0x75, 0x6e, 0x64, 0x61, 0x2d, 0x66, -0x65, 0x72, 0x61, 0x3b, 0x74, 0x65, 0x72, 0x73, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x6b, 0x75, 0x61, 0x72, 0x74, -0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x6b, 0x69, 0x6e, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x73, 0x65, -0x73, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x73, 0x61, 0x62, 0x61, 0x64, 0x75, 0x3b, 0x4b, 0x49, 0x55, 0x3b, -0x4d, 0x52, 0x41, 0x3b, 0x57, 0x41, 0x49, 0x3b, 0x57, 0x45, 0x54, 0x3b, 0x57, 0x45, 0x4e, 0x3b, 0x57, 0x54, 0x4e, 0x3b, -0x4a, 0x55, 0x4d, 0x3b, 0x4b, 0x69, 0x75, 0x6d, 0x69, 0x61, 0x3b, 0x4d, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b, 0x6f, 0x3b, -0x57, 0x61, 0x69, 0x72, 0x69, 0x3b, 0x57, 0x65, 0x74, 0x68, 0x61, 0x74, 0x75, 0x3b, 0x57, 0x65, 0x6e, 0x61, 0x3b, 0x57, -0x65, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x57, -0x3b, 0x57, 0x3b, 0x57, 0x3b, 0x57, 0x3b, 0x4a, 0x3b, 0x4b, 0x74, 0x73, 0x3b, 0x4b, 0x6f, 0x74, 0x3b, 0x4b, 0x6f, 0x6f, -0x3b, 0x4b, 0x6f, 0x73, 0x3b, 0x4b, 0x6f, 0x61, 0x3b, 0x4b, 0x6f, 0x6d, 0x3b, 0x4b, 0x6f, 0x6c, 0x3b, 0x4b, 0x6f, 0x74, -0x69, 0x73, 0x61, 0x70, 0x3b, 0x4b, 0x6f, 0x74, 0x61, 0x61, 0x69, 0x3b, 0x4b, 0x6f, 0x61, 0x65, 0x6e, 0x67, 0x2019, 0x3b, -0x4b, 0x6f, 0x73, 0x6f, 0x6d, 0x6f, 0x6b, 0x3b, 0x4b, 0x6f, 0x61, 0x6e, 0x67, 0x2019, 0x77, 0x61, 0x6e, 0x3b, 0x4b, 0x6f, -0x6d, 0x75, 0x75, 0x74, 0x3b, 0x4b, 0x6f, 0x6c, 0x6f, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4f, 0x3b, 0x53, 0x3b, 0x41, 0x3b, -0x4d, 0x3b, 0x4c, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0x61, 0x3b, 0x44, 0x65, 0x3b, 0x57, 0x75, 0x3b, 0x44, 0x6f, 0x3b, -0x46, 0x72, 0x3b, 0x53, 0x61, 0x74, 0x3b, 0x53, 0x6f, 0x6e, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x4d, -0x61, 0x6e, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x44, 0x65, 0x6e, 0x73, 0x74, 0x61, 0x78, 0x74, 0x73, -0x65, 0x65, 0x73, 0x3b, 0x57, 0x75, 0x6e, 0x73, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x44, 0x6f, 0x6e, -0x64, 0x65, 0x72, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x46, 0x72, 0x61, 0x69, 0x74, 0x61, 0x78, 0x74, -0x73, 0x65, 0x65, 0x73, 0x3b, 0x53, 0x61, 0x74, 0x65, 0x72, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x53, -0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x57, 0x3b, 0x44, 0x3b, 0x46, 0x3b, 0x41, 0x3b, 0x53, 0x75, 0x2e, 0x3b, 0x4d, 0x6f, 0x2e, -0x3b, 0x44, 0x69, 0x2e, 0x3b, 0x4d, 0x65, 0x2e, 0x3b, 0x44, 0x75, 0x2e, 0x3b, 0x46, 0x72, 0x2e, 0x3b, 0x53, 0x61, 0x2e, -0x3b, 0x53, 0x75, 0x6e, 0x6e, 0x64, 0x61, 0x61, 0x63, 0x68, 0x3b, 0x4d, 0x6f, 0x68, 0x6e, 0x64, 0x61, 0x61, 0x63, 0x68, -0x3b, 0x44, 0x69, 0x6e, 0x6e, 0x73, 0x64, 0x61, 0x61, 0x63, 0x68, 0x3b, 0x4d, 0x65, 0x74, 0x77, 0x6f, 0x63, 0x68, 0x3b, -0x44, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x64, 0x61, 0x61, 0x63, 0x68, 0x3b, 0x46, 0x72, 0x69, 0x69, 0x64, 0x61, 0x61, -0x63, 0x68, 0x3b, 0x53, 0x61, 0x6d, 0x73, 0x64, 0x61, 0x61, 0x63, 0x68, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0xed, 0x6c, -0xed, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0xe1, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e, 0x65, 0x3b, 0x4a, 0x75, -0x6d, 0x61, 0x74, 0xe1, 0x6e, 0x254, 0x3b, 0x41, 0x6c, 0x61, 0xe1, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0xe1, -0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0xf3, 0x73, 0x69, 0x3b, 0x53, 0x61, 0x62, 0x69, 0x3b, 0x42, 0x61, 0x6c, 0x61, -0x3b, 0x4b, 0x75, 0x62, 0x69, 0x3b, 0x4b, 0x75, 0x73, 0x61, 0x3b, 0x4b, 0x75, 0x6e, 0x61, 0x3b, 0x4b, 0x75, 0x74, 0x61, -0x3b, 0x4d, 0x75, 0x6b, 0x61, 0x3b, 0x53, 0x61, 0x62, 0x69, 0x69, 0x74, 0x69, 0x3b, 0x42, 0x61, 0x6c, 0x61, 0x7a, 0x61, -0x3b, 0x4f, 0x77, 0x6f, 0x6b, 0x75, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x4f, 0x77, 0x6f, 0x6b, 0x75, 0x73, 0x61, 0x74, 0x75, -0x3b, 0x4f, 0x6c, 0x6f, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x4f, 0x6c, 0x6f, 0x6b, 0x75, 0x74, 0x61, 0x61, 0x6e, 0x75, 0x3b, -0x4f, 0x6c, 0x6f, 0x6d, 0x75, 0x6b, 0x61, 0x61, 0x67, 0x61, 0x3b, 0x53, 0x3b, 0x42, 0x3b, 0x42, 0x3b, 0x53, 0x3b, 0x4b, -0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x4a, 0x32, 0x3b, 0x4a, 0x33, 0x3b, 0x4a, 0x34, 0x3b, 0x4a, 0x35, 0x3b, 0x41, 0x6c, 0x3b, -0x49, 0x6a, 0x3b, 0x4a, 0x31, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x72, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, -0x61, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, -0x3b, 0x4d, 0x75, 0x72, 0x77, 0x61, 0x20, 0x77, 0x61, 0x20, 0x4b, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4d, 0x75, 0x72, 0x77, -0x61, 0x20, 0x77, 0x61, 0x20, 0x4b, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, -0x3b, 0x4a, 0x70, 0x69, 0x3b, 0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6e, 0x6e, 0x3b, 0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, -0x3b, 0x49, 0x6a, 0x6d, 0x3b, 0x4a, 0x6d, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x42, 0x61, 0x72, 0x3b, 0x41, 0x61, 0x72, -0x3b, 0x55, 0x6e, 0x69, 0x3b, 0x55, 0x6e, 0x67, 0x3b, 0x4b, 0x61, 0x6e, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4e, 0x61, 0x6b, -0x61, 0x65, 0x6a, 0x75, 0x6d, 0x61, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x65, 0x62, 0x61, 0x72, 0x61, 0x73, 0x61, 0x3b, 0x4e, -0x61, 0x6b, 0x61, 0x61, 0x72, 0x65, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x75, 0x6e, 0x69, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x75, -0x6e, 0x67, 0x2019, 0x6f, 0x6e, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x6b, 0x61, 0x6e, 0x79, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x73, -0x61, 0x62, 0x69, 0x74, 0x69, 0x3b, 0x4a, 0x3b, 0x42, 0x3b, 0x41, 0x3b, 0x55, 0x3b, 0x55, 0x3b, 0x4b, 0x3b, 0x53, 0x3b, -0x41, 0x6c, 0x68, 0x3b, 0x41, 0x74, 0x69, 0x3b, 0x41, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x3b, 0x41, 0x6c, 0x6d, 0x3b, -0x41, 0x6c, 0x6a, 0x3b, 0x41, 0x73, 0x73, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x64, 0x69, 0x3b, 0x41, 0x74, 0x69, 0x6e, 0x69, -0x3b, 0x41, 0x74, 0x61, 0x6c, 0x61, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x72, 0x62, 0x61, 0x3b, 0x41, 0x6c, 0x68, 0x61, -0x6d, 0x69, 0x69, 0x73, 0x61, 0x3b, 0x41, 0x6c, 0x6a, 0x75, 0x6d, 0x61, 0x3b, 0x41, 0x73, 0x73, 0x61, 0x62, 0x64, 0x75, -0x3b, 0x48, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x53, 0x3b, 0x4a, 0x4d, 0x50, 0x3b, 0x57, -0x55, 0x54, 0x3b, 0x54, 0x41, 0x52, 0x3b, 0x54, 0x41, 0x44, 0x3b, 0x54, 0x41, 0x4e, 0x3b, 0x54, 0x41, 0x42, 0x3b, 0x4e, -0x47, 0x53, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x6c, 0x3b, 0x57, 0x75, 0x6f, 0x6b, 0x20, 0x54, 0x69, 0x63, 0x68, -0x3b, 0x54, 0x69, 0x63, 0x68, 0x20, 0x41, 0x72, 0x69, 0x79, 0x6f, 0x3b, 0x54, 0x69, 0x63, 0x68, 0x20, 0x41, 0x64, 0x65, -0x6b, 0x3b, 0x54, 0x69, 0x63, 0x68, 0x20, 0x41, 0x6e, 0x67, 0x2019, 0x77, 0x65, 0x6e, 0x3b, 0x54, 0x69, 0x63, 0x68, 0x20, -0x41, 0x62, 0x69, 0x63, 0x68, 0x3b, 0x4e, 0x67, 0x65, 0x73, 0x6f, 0x3b, 0x4a, 0x3b, 0x57, 0x3b, 0x54, 0x3b, 0x54, 0x3b, -0x54, 0x3b, 0x54, 0x3b, 0x4e, 0x3b, 0x41, 0x73, 0x61, 0x3b, 0x41, 0x79, 0x6e, 0x3b, 0x41, 0x73, 0x6e, 0x3b, 0x41, 0x6b, -0x72, 0x3b, 0x41, 0x6b, 0x77, 0x3b, 0x41, 0x73, 0x6d, 0x3b, 0x41, 0x73, 0x1e0d, 0x3b, 0x41, 0x73, 0x61, 0x6d, 0x61, 0x73, -0x3b, 0x41, 0x79, 0x6e, 0x61, 0x73, 0x3b, 0x41, 0x73, 0x69, 0x6e, 0x61, 0x73, 0x3b, 0x41, 0x6b, 0x72, 0x61, 0x73, 0x3b, -0x41, 0x6b, 0x77, 0x61, 0x73, 0x3b, 0x41, 0x73, 0x69, 0x6d, 0x77, 0x61, 0x73, 0x3b, 0x41, 0x73, 0x69, 0x1e0d, 0x79, 0x61, -0x73, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x6c, 0x68, 0x3b, -0x41, 0x74, 0x69, 0x3b, 0x41, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x3b, 0x41, 0x6c, 0x6d, 0x3b, 0x41, 0x6c, 0x7a, 0x3b, -0x41, 0x73, 0x69, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x64, 0x69, 0x3b, 0x41, 0x74, 0x69, 0x6e, 0x6e, 0x69, 0x3b, 0x41, 0x74, -0x61, 0x6c, 0x61, 0x61, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x72, 0x62, 0x61, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, -0x69, 0x73, 0x61, 0x3b, 0x41, 0x6c, 0x7a, 0x75, 0x6d, 0x61, 0x3b, 0x41, 0x73, 0x69, 0x62, 0x74, 0x69, 0x3b, 0x4a, 0x70, -0x69, 0x3b, 0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6d, 0x6e, 0x3b, 0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, -0x75, 0x3b, 0x4a, 0x6d, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x61, 0x70, 0x69, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x61, -0x74, 0x61, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x61, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x61, 0x74, 0x61, -0x6e, 0x6f, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4a, -0x75, 0x6d, 0x61, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x32, 0x3b, 0x33, 0x3b, 0x34, 0x3b, 0x35, 0x3b, 0x41, 0x3b, 0x49, -0x3b, 0x31, 0x3b, 0x930, 0x92c, 0x93f, 0x3b, 0x938, 0x92e, 0x3b, 0x92e, 0x902, 0x917, 0x932, 0x3b, 0x92c, 0x941, 0x926, 0x3b, 0x92c, -0x93f, 0x938, 0x925, 0x93f, 0x3b, 0x938, 0x941, 0x916, 0x941, 0x930, 0x3b, 0x938, 0x941, 0x928, 0x93f, 0x3b, 0x930, 0x92c, 0x93f, 0x92c, -0x93e, 0x930, 0x3b, 0x938, 0x92e, 0x92c, 0x93e, 0x930, 0x3b, 0x92e, 0x902, 0x917, 0x932, 0x92c, 0x93e, 0x930, 0x3b, 0x92c, 0x941, 0x926, -0x92c, 0x93e, 0x930, 0x3b, 0x92c, 0x93f, 0x938, 0x925, 0x93f, 0x92c, 0x93e, 0x930, 0x3b, 0x938, 0x941, 0x916, 0x941, 0x930, 0x92c, 0x93e, -0x930, 0x3b, 0x938, 0x941, 0x928, 0x93f, 0x92c, 0x93e, 0x930, 0x3b, 0x930, 0x3b, 0x938, 0x3b, 0x92e, 0x902, 0x3b, 0x92c, 0x941, 0x3b, -0x92c, 0x93f, 0x3b, 0x938, 0x941, 0x3b, 0x938, 0x941, 0x3b, 0x43a, 0x4c0, 0x438, 0x3b, 0x43e, 0x440, 0x3b, 0x448, 0x438, 0x3b, 0x43a, -0x445, 0x430, 0x3b, 0x435, 0x430, 0x3b, 0x43f, 0x4c0, 0x435, 0x3b, 0x448, 0x443, 0x43e, 0x3b, 0x43a, 0x4c0, 0x438, 0x440, 0x430, 0x3b, -0x43e, 0x440, 0x448, 0x43e, 0x442, 0x3b, 0x448, 0x438, 0x43d, 0x430, 0x440, 0x430, 0x3b, 0x43a, 0x445, 0x430, 0x430, 0x440, 0x430, 0x3b, -0x435, 0x430, 0x440, 0x430, 0x3b, 0x43f, 0x4c0, 0x435, 0x440, 0x430, 0x441, 0x43a, 0x430, 0x3b, 0x448, 0x443, 0x43e, 0x442, 0x3b, 0x43a, -0x4c0, 0x3b, 0x43e, 0x3b, 0x448, 0x3b, 0x43a, 0x445, 0x3b, 0x435, 0x3b, 0x43f, 0x4c0, 0x3b, 0x448, 0x3b, 0x43d, 0x434, 0x2de7, 0x487, -0x467, 0x3b, 0x43f, 0x43d, 0x2de3, 0x435, 0x3b, 0x432, 0x442, 0x43e, 0x2dec, 0x487, 0x3b, 0x441, 0x440, 0x2de3, 0x435, 0x3b, 0x447, 0x435, -0x2de6, 0x487, 0x3b, 0x43f, 0x467, 0x2de6, 0x487, 0x3b, 0x441, 0xa64b, 0x2de0, 0x487, 0x3b, 0x43d, 0x435, 0x434, 0x463, 0x301, 0x43b, 0x467, -0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x463, 0x301, 0x43b, 0x44c, 0x43d, 0x438, 0x43a, 0x44a, 0x3b, 0x432, 0x442, 0x43e, 0x301, 0x440, -0x43d, 0x438, 0x43a, 0x44a, 0x3b, 0x441, 0x440, 0x435, 0x434, 0x430, 0x300, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x435, 0x440, 0x442, 0x43e, -0x301, 0x43a, 0x44a, 0x3b, 0x43f, 0x467, 0x442, 0x43e, 0x301, 0x43a, 0x44a, 0x3b, 0x441, 0xa64b, 0x431, 0x431, 0x461, 0x301, 0x442, 0x430, -0x3b, 0x4c, 0x75, 0x6d, 0x3b, 0x4e, 0x6b, 0x6f, 0x3b, 0x4e, 0x64, 0x79, 0x3b, 0x4e, 0x64, 0x67, 0x3b, 0x4e, 0x6a, 0x77, -0x3b, 0x4e, 0x67, 0x76, 0x3b, 0x4c, 0x75, 0x62, 0x3b, 0x4c, 0x75, 0x6d, 0x69, 0x6e, 0x67, 0x75, 0x3b, 0x4e, 0x6b, 0x6f, -0x64, 0x79, 0x61, 0x3b, 0x4e, 0x64, 0xe0, 0x61, 0x79, 0xe0, 0x3b, 0x4e, 0x64, 0x61, 0x6e, 0x67, 0xf9, 0x3b, 0x4e, 0x6a, -0xf2, 0x77, 0x61, 0x3b, 0x4e, 0x67, 0xf2, 0x76, 0x79, 0x61, 0x3b, 0x4c, 0x75, 0x62, 0x69, 0x6e, 0x67, 0x75, 0x3b, 0x4c, -0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4c, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0xe9, 0x69, -0x3b, 0x44, 0xeb, 0x6e, 0x3b, 0x4d, 0xeb, 0x74, 0x3b, 0x44, 0x6f, 0x6e, 0x3b, 0x46, 0x72, 0x65, 0x3b, 0x53, 0x61, 0x6d, -0x3b, 0x53, 0x6f, 0x6e, 0x6e, 0x64, 0x65, 0x67, 0x3b, 0x4d, 0xe9, 0x69, 0x6e, 0x64, 0x65, 0x67, 0x3b, 0x44, 0xeb, 0x6e, -0x73, 0x63, 0x68, 0x64, 0x65, 0x67, 0x3b, 0x4d, 0xeb, 0x74, 0x74, 0x77, 0x6f, 0x63, 0x68, 0x3b, 0x44, 0x6f, 0x6e, 0x6e, -0x65, 0x73, 0x63, 0x68, 0x64, 0x65, 0x67, 0x3b, 0x46, 0x72, 0x65, 0x69, 0x64, 0x65, 0x67, 0x3b, 0x53, 0x61, 0x6d, 0x73, -0x63, 0x68, 0x64, 0x65, 0x67, 0x3b, 0x53, 0x6f, 0x6e, 0x2e, 0x3b, 0x4d, 0xe9, 0x69, 0x2e, 0x3b, 0x44, 0xeb, 0x6e, 0x2e, -0x3b, 0x4d, 0xeb, 0x74, 0x2e, 0x3b, 0x44, 0x6f, 0x6e, 0x2e, 0x3b, 0x46, 0x72, 0x65, 0x2e, 0x3b, 0x53, 0x61, 0x6d, 0x2e, -0x3b, 0x6e, 0x74, 0x73, 0x3b, 0x6b, 0x70, 0x61, 0x3b, 0x67, 0x68, 0x254, 0x3b, 0x74, 0x254, 0x6d, 0x3b, 0x75, 0x6d, 0x65, -0x3b, 0x67, 0x68, 0x268, 0x3b, 0x64, 0x7a, 0x6b, 0x3b, 0x74, 0x73, 0x75, 0x294, 0x6e, 0x74, 0x73, 0x268, 0x3b, 0x74, 0x73, -0x75, 0x294, 0x75, 0x6b, 0x70, 0xe0, 0x3b, 0x74, 0x73, 0x75, 0x294, 0x75, 0x67, 0x68, 0x254, 0x65, 0x3b, 0x74, 0x73, 0x75, -0x294, 0x75, 0x74, 0x254, 0x300, 0x6d, 0x6c, 0xf2, 0x3b, 0x74, 0x73, 0x75, 0x294, 0x75, 0x6d, 0xe8, 0x3b, 0x74, 0x73, 0x75, -0x294, 0x75, 0x67, 0x68, 0x268, 0x302, 0x6d, 0x3b, 0x74, 0x73, 0x75, 0x294, 0x6e, 0x64, 0x7a, 0x268, 0x6b, 0x254, 0x294, 0x254, -0x3b, 0x6e, 0x3b, 0x6b, 0x3b, 0x67, 0x3b, 0x74, 0x3b, 0x75, 0x3b, 0x67, 0x3b, 0x64, 0x3b, 0x6e, 0x254, 0x79, 0x3b, 0x6e, -0x6a, 0x61, 0x3b, 0x75, 0x75, 0x6d, 0x3b, 0x14b, 0x67, 0x65, 0x3b, 0x6d, 0x62, 0x254, 0x3b, 0x6b, 0x254, 0x254, 0x3b, 0x6a, -0x6f, 0x6e, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0x6e, 0x254, 0x302, 0x79, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0x6e, 0x6a, -0x61, 0x14b, 0x67, 0x75, 0x6d, 0x62, 0x61, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0xfb, 0x6d, 0x3b, 0x14b, 0x67, 0x77, 0xe0, -0x20, 0x14b, 0x67, 0xea, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0x6d, 0x62, 0x254, 0x6b, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, -0x6b, 0x254, 0x254, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0x6a, 0xf4, 0x6e, 0x3b, 0x6e, 0x3b, 0x6e, 0x3b, 0x75, 0x3b, 0x14b, -0x3b, 0x6d, 0x3b, 0x6b, 0x3b, 0x6a, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x64, 0x69, 0x3b, 0x41, 0x74, 0x69, 0x6e, 0x6e, 0x69, -0x3b, 0x41, 0x74, 0x61, 0x6c, 0x61, 0x61, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x72, 0x62, 0x61, 0x3b, 0x41, 0x6c, 0x68, -0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x41, 0x6c, 0x7a, 0x75, 0x6d, 0x61, 0x3b, 0x41, 0x73, 0x69, 0x62, 0x74, 0x69, 0x3b, -0x48, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x5a, 0x3b, 0x53, 0x3b, 0xe9, 0x74, 0x3b, 0x6d, 0x254, 0x301, -0x73, 0x3b, 0x6b, 0x77, 0x61, 0x3b, 0x6d, 0x75, 0x6b, 0x3b, 0x14b, 0x67, 0x69, 0x3b, 0x257, 0xf3, 0x6e, 0x3b, 0x65, 0x73, -0x61, 0x3b, 0xe9, 0x74, 0x69, 0x3b, 0x6d, 0x254, 0x301, 0x73, 0xfa, 0x3b, 0x6b, 0x77, 0x61, 0x73, 0xfa, 0x3b, 0x6d, 0x75, -0x6b, 0x254, 0x301, 0x73, 0xfa, 0x3b, 0x14b, 0x67, 0x69, 0x73, 0xfa, 0x3b, 0x257, 0xf3, 0x6e, 0x25b, 0x73, 0xfa, 0x3b, 0x65, -0x73, 0x61, 0x253, 0x61, 0x73, 0xfa, 0x3b, 0x65, 0x3b, 0x6d, 0x3b, 0x6b, 0x3b, 0x6d, 0x3b, 0x14b, 0x3b, 0x257, 0x3b, 0x65, -0x3b, 0x44, 0x69, 0x6d, 0x3b, 0x54, 0x65, 0x6e, 0x3b, 0x54, 0x61, 0x6c, 0x3b, 0x41, 0x6c, 0x61, 0x3b, 0x41, 0x72, 0x61, -0x3b, 0x41, 0x72, 0x6a, 0x3b, 0x53, 0x69, 0x62, 0x3b, 0x44, 0x69, 0x6d, 0x61, 0x73, 0x3b, 0x54, 0x65, 0x6e, 0x65, 0x14b, -0x3b, 0x54, 0x61, 0x6c, 0x61, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x72, 0x62, 0x61, 0x79, 0x3b, 0x41, 0x72, 0x61, 0x6d, -0x69, 0x73, 0x61, 0x79, 0x3b, 0x41, 0x72, 0x6a, 0x75, 0x6d, 0x61, 0x3b, 0x53, 0x69, 0x62, 0x69, 0x74, 0x69, 0x3b, 0x44, -0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x3b, 0x6d, 0x254, -0x301, 0x6e, 0x3b, 0x73, 0x6d, 0x62, 0x3b, 0x73, 0x6d, 0x6c, 0x3b, 0x73, 0x6d, 0x6e, 0x3b, 0x66, 0xfa, 0x6c, 0x3b, 0x73, -0xe9, 0x72, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x3b, 0x6d, 0x254, 0x301, 0x6e, 0x64, 0x69, 0x3b, 0x73, 0x254, 0x301, -0x6e, 0x64, 0x254, 0x20, 0x6d, 0x259, 0x6c, 0xfa, 0x20, 0x6d, 0x259, 0x301, 0x62, 0x25b, 0x30c, 0x3b, 0x73, 0x254, 0x301, 0x6e, -0x64, 0x254, 0x20, 0x6d, 0x259, 0x6c, 0xfa, 0x20, 0x6d, 0x259, 0x301, 0x6c, 0x25b, 0x301, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, -0x254, 0x20, 0x6d, 0x259, 0x6c, 0xfa, 0x20, 0x6d, 0x259, 0x301, 0x6e, 0x79, 0x69, 0x3b, 0x66, 0xfa, 0x6c, 0x61, 0x64, 0xe9, -0x3b, 0x73, 0xe9, 0x72, 0x61, 0x64, 0xe9, 0x3b, 0x73, 0x3b, 0x6d, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x66, 0x3b, -0x73, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x3b, 0x6c, 0x1dd, 0x6e, 0x3b, 0x6d, 0x61, 0x61, 0x3b, 0x6d, 0x25b, 0x6b, 0x3b, 0x6a, -0x1dd, 0x1dd, 0x3b, 0x6a, 0xfa, 0x6d, 0x3b, 0x73, 0x61, 0x6d, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x1dd, 0x3b, 0x6c, 0x1dd, -0x6e, 0x64, 0xed, 0x3b, 0x6d, 0x61, 0x61, 0x64, 0xed, 0x3b, 0x6d, 0x25b, 0x6b, 0x72, 0x25b, 0x64, 0xed, 0x3b, 0x6a, 0x1dd, -0x1dd, 0x64, 0xed, 0x3b, 0x6a, 0xfa, 0x6d, 0x62, 0xe1, 0x3b, 0x73, 0x61, 0x6d, 0x64, 0xed, 0x3b, 0x73, 0x3b, 0x6c, 0x3b, -0x6d, 0x3b, 0x6d, 0x3b, 0x6a, 0x3b, 0x6a, 0x3b, 0x73, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6e, -0x6e, 0x3b, 0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x72, 0x61, 0x3b, 0x49, 0x6a, 0x75, 0x3b, 0x4a, 0x6d, 0x6f, 0x3b, 0x53, 0x61, -0x62, 0x61, 0x74, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e, 0x6e, -0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x72, 0x61, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, -0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x53, 0x3b, 0x4a, -0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x4a, 0x3b, 0x43, 0x79, 0x61, 0x3b, 0x43, 0x6c, 0x61, 0x3b, 0x43, -0x7a, 0x69, 0x3b, 0x43, 0x6b, 0x6f, 0x3b, 0x43, 0x6b, 0x61, 0x3b, 0x43, 0x67, 0x61, 0x3b, 0x43, 0x7a, 0x65, 0x3b, 0x43, -0x6f, 0x6d, 0x2019, 0x79, 0x61, 0x6b, 0x6b, 0x65, 0x3b, 0x43, 0x6f, 0x6d, 0x6c, 0x61, 0x61, 0x257, 0x69, 0x69, 0x3b, 0x43, -0x6f, 0x6d, 0x7a, 0x79, 0x69, 0x69, 0x257, 0x69, 0x69, 0x3b, 0x43, 0x6f, 0x6d, 0x6b, 0x6f, 0x6c, 0x6c, 0x65, 0x3b, 0x43, -0x6f, 0x6d, 0x6b, 0x61, 0x6c, 0x64, 0x1dd, 0x253, 0x6c, 0x69, 0x69, 0x3b, 0x43, 0x6f, 0x6d, 0x67, 0x61, 0x69, 0x73, 0x75, -0x75, 0x3b, 0x43, 0x6f, 0x6d, 0x7a, 0x79, 0x65, 0x253, 0x73, 0x75, 0x75, 0x3b, 0x59, 0x3b, 0x4c, 0x3b, 0x5a, 0x3b, 0x4f, -0x3b, 0x41, 0x3b, 0x47, 0x3b, 0x45, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x3b, 0x6d, 0x254, 0x301, 0x6e, 0x3b, 0x73, 0x6d, 0x62, -0x3b, 0x73, 0x6d, 0x6c, 0x3b, 0x73, 0x6d, 0x6e, 0x3b, 0x6d, 0x62, 0x73, 0x3b, 0x73, 0x61, 0x73, 0x3b, 0x73, 0x254, 0x301, -0x6e, 0x64, 0x254, 0x3b, 0x6d, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x20, 0x6d, 0x61, -0x66, 0xfa, 0x20, 0x6d, 0xe1, 0x62, 0x61, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x20, 0x6d, 0x61, 0x66, 0xfa, 0x20, -0x6d, 0xe1, 0x6c, 0x61, 0x6c, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x20, 0x6d, 0x61, 0x66, 0xfa, 0x20, 0x6d, 0xe1, -0x6e, 0x61, 0x3b, 0x6d, 0x61, 0x62, 0xe1, 0x67, 0xe1, 0x20, 0x6d, 0xe1, 0x20, 0x73, 0x75, 0x6b, 0x75, 0x6c, 0x3b, 0x73, -0xe1, 0x73, 0x61, 0x64, 0x69, 0x3b, 0x73, 0x3b, 0x6d, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x6d, 0x3b, 0x73, 0x3b, -0x43, 0xe4, 0x14b, 0x3b, 0x4a, 0x69, 0x65, 0x63, 0x3b, 0x52, 0x25b, 0x77, 0x3b, 0x44, 0x69, 0x254, 0x331, 0x6b, 0x3b, 0x14a, -0x75, 0x61, 0x61, 0x6e, 0x3b, 0x44, 0x68, 0x69, 0x65, 0x65, 0x63, 0x3b, 0x42, 0xe4, 0x6b, 0x25b, 0x6c, 0x3b, 0x43, 0xe4, -0x14b, 0x20, 0x6b, 0x75, 0x254, 0x74, 0x68, 0x3b, 0x4a, 0x69, 0x65, 0x63, 0x20, 0x6c, 0x61, 0x331, 0x74, 0x3b, 0x52, 0x25b, -0x77, 0x20, 0x6c, 0xe4, 0x74, 0x6e, 0x69, 0x3b, 0x44, 0x69, 0x254, 0x331, 0x6b, 0x20, 0x6c, 0xe4, 0x74, 0x6e, 0x69, 0x3b, -0x14a, 0x75, 0x61, 0x61, 0x6e, 0x20, 0x6c, 0xe4, 0x74, 0x6e, 0x69, 0x3b, 0x44, 0x68, 0x69, 0x65, 0x65, 0x63, 0x20, 0x6c, -0xe4, 0x74, 0x6e, 0x69, 0x3b, 0x42, 0xe4, 0x6b, 0x25b, 0x6c, 0x20, 0x6c, 0xe4, 0x74, 0x6e, 0x69, 0x3b, 0x43, 0x3b, 0x4a, -0x3b, 0x52, 0x3b, 0x44, 0x3b, 0x14a, 0x3b, 0x44, 0x3b, 0x42, 0x3b, 0x431, 0x441, 0x3b, 0x431, 0x43d, 0x3b, 0x43e, 0x43f, 0x3b, -0x441, 0x44d, 0x3b, 0x447, 0x43f, 0x3b, 0x431, 0x44d, 0x3b, 0x441, 0x431, 0x3b, 0x431, 0x430, 0x441, 0x43a, 0x44b, 0x4bb, 0x44b, 0x430, -0x43d, 0x43d, 0x44c, 0x430, 0x3b, 0x431, 0x44d, 0x43d, 0x438, 0x434, 0x438, 0x44d, 0x43d, 0x43d, 0x44c, 0x438, 0x43a, 0x3b, 0x43e, 0x43f, -0x442, 0x443, 0x43e, 0x440, 0x443, 0x43d, 0x43d, 0x44c, 0x443, 0x43a, 0x3b, 0x441, 0x44d, 0x440, 0x44d, 0x434, 0x44d, 0x3b, 0x447, 0x44d, -0x43f, 0x43f, 0x438, 0x44d, 0x440, 0x3b, 0x411, 0x44d, 0x44d, 0x442, 0x438, 0x4a5, 0x441, 0x44d, 0x3b, 0x441, 0x443, 0x431, 0x443, 0x43e, -0x442, 0x430, 0x3b, 0x411, 0x3b, 0x411, 0x3b, 0x41e, 0x3b, 0x421, 0x3b, 0x427, 0x3b, 0x411, 0x3b, 0x421, 0x3b, 0x4d, 0x75, 0x6c, -0x3b, 0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6e, 0x6e, 0x3b, 0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x75, -0x3b, 0x4a, 0x6d, 0x6f, 0x3b, 0x4d, 0x75, 0x6c, 0x75, 0x6e, 0x67, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, -0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x41, -0x6c, 0x61, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61, -0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x4a, 0x3b, 0xa55e, -0xa54c, 0xa535, 0x3b, 0xa5f3, 0xa5e1, 0xa609, 0x3b, 0xa55a, 0xa55e, 0xa55a, 0x3b, 0xa549, 0xa55e, 0xa552, 0x3b, 0xa549, 0xa524, 0xa546, 0xa562, 0x3b, -0xa549, 0xa524, 0xa540, 0xa56e, 0x3b, 0xa53b, 0xa52c, 0xa533, 0x3b, 0x6c, 0x61, 0x68, 0x61, 0x64, 0x69, 0x3b, 0x74, 0x25b, 0x25b, 0x6e, -0x25b, 0x25b, 0x3b, 0x74, 0x61, 0x6c, 0x61, 0x74, 0x61, 0x3b, 0x61, 0x6c, 0x61, 0x62, 0x61, 0x3b, 0x61, 0x69, 0x6d, 0x69, -0x73, 0x61, 0x3b, 0x61, 0x69, 0x6a, 0x69, 0x6d, 0x61, 0x3b, 0x73, 0x69, 0x253, 0x69, 0x74, 0x69, 0x3b, 0x53, 0x75, 0x6e, -0x3b, 0x4d, 0xe4, 0x6e, 0x3b, 0x5a, 0x69, 0x161, 0x3b, 0x4d, 0x69, 0x74, 0x3b, 0x46, 0x72, 0xf3, 0x3b, 0x46, 0x72, 0x69, -0x3b, 0x53, 0x61, 0x6d, 0x3b, 0x53, 0x75, 0x6e, 0x6e, 0x74, 0x61, 0x67, 0x3b, 0x4d, 0xe4, 0x6e, 0x74, 0x61, 0x67, 0x3b, -0x5a, 0x69, 0x161, 0x74, 0x61, 0x67, 0x3b, 0x4d, 0x69, 0x74, 0x74, 0x77, 0x75, 0x10d, 0x3b, 0x46, 0x72, 0xf3, 0x6e, 0x74, -0x61, 0x67, 0x3b, 0x46, 0x72, 0x69, 0x74, 0x61, 0x67, 0x3b, 0x53, 0x61, 0x6d, 0x161, 0x74, 0x61, 0x67, 0x3b, 0x53, 0x3b, -0x4d, 0x3b, 0x5a, 0x3b, 0x4d, 0x3b, 0x46, 0x3b, 0x46, 0x3b, 0x53, 0x3b, 0x73, 0x64, 0x3b, 0x6d, 0x64, 0x3b, 0x6d, 0x77, -0x3b, 0x65, 0x74, 0x3b, 0x6b, 0x6c, 0x3b, 0x66, 0x6c, 0x3b, 0x73, 0x73, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x69, 0x25b, -0x3b, 0x6d, 0xf3, 0x6e, 0x64, 0x69, 0x65, 0x3b, 0x6d, 0x75, 0xe1, 0x6e, 0x79, 0xe1, 0x14b, 0x6d, 0xf3, 0x6e, 0x64, 0x69, -0x65, 0x3b, 0x6d, 0x65, 0x74, 0xfa, 0x6b, 0x70, 0xed, 0xe1, 0x70, 0x25b, 0x3b, 0x6b, 0xfa, 0x70, 0xe9, 0x6c, 0x69, 0x6d, -0x65, 0x74, 0xfa, 0x6b, 0x70, 0x69, 0x61, 0x70, 0x25b, 0x3b, 0x66, 0x65, 0x6c, 0xe9, 0x74, 0x65, 0x3b, 0x73, 0xe9, 0x73, -0x65, 0x6c, 0xe9, 0x3b, 0x73, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x65, 0x3b, 0x6b, 0x3b, 0x66, 0x3b, 0x73, 0x3b, 0x64, 0x6f, -0x6d, 0x3b, 0x6c, 0x6c, 0x75, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0x69, 0xe9, 0x3b, 0x78, 0x75, 0x65, 0x3b, 0x76, 0x69, -0x65, 0x3b, 0x73, 0xe1, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x75, 0x3b, 0x6c, 0x6c, 0x75, 0x6e, 0x65, 0x73, -0x3b, 0x6d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x3b, 0x6d, 0x69, 0xe9, 0x72, 0x63, 0x6f, 0x6c, 0x65, 0x73, 0x3b, 0x78, 0x75, -0x65, 0x76, 0x65, 0x73, 0x3b, 0x76, 0x69, 0x65, 0x6e, 0x72, 0x65, 0x73, 0x3b, 0x73, 0xe1, 0x62, 0x61, 0x64, 0x75, 0x3b, -0x53, 0x254, 0x301, 0x6e, 0x64, 0x69, 0x3b, 0x4d, 0x254, 0x301, 0x6e, 0x64, 0x69, 0x3b, 0xc1, 0x70, 0x74, 0x61, 0x20, 0x4d, -0x254, 0x301, 0x6e, 0x64, 0x69, 0x3b, 0x57, 0x25b, 0x301, 0x6e, 0x25b, 0x73, 0x25b, 0x64, 0x25b, 0x3b, 0x54, 0x254, 0x301, 0x73, -0x25b, 0x64, 0x25b, 0x3b, 0x46, 0x25b, 0x6c, 0xe2, 0x79, 0x25b, 0x64, 0x25b, 0x3b, 0x53, 0xe1, 0x73, 0x69, 0x64, 0x25b, 0x3b, -0x53, 0x254, 0x301, 0x3b, 0x4d, 0x254, 0x301, 0x3b, 0xc1, 0x4d, 0x3b, 0x57, 0x25b, 0x301, 0x3b, 0x54, 0x254, 0x301, 0x3b, 0x46, -0x25b, 0x3b, 0x53, 0xe1, 0x3b, 0x73, 0x254, 0x6e, 0x64, 0x69, 0x3b, 0x6c, 0x75, 0x6e, 0x64, 0x69, 0x3b, 0x6d, 0x61, 0x72, -0x64, 0x69, 0x3b, 0x6d, 0x25b, 0x72, 0x6b, 0x25b, 0x72, 0x25b, 0x64, 0x69, 0x3b, 0x79, 0x65, 0x64, 0x69, 0x3b, 0x76, 0x61, -0x14b, 0x64, 0x25b, 0x72, 0x25b, 0x64, 0x69, 0x3b, 0x6d, 0x254, 0x6e, 0x254, 0x20, 0x73, 0x254, 0x6e, 0x64, 0x69, 0x3b, 0x73, -0x6f, 0x3b, 0x6c, 0x75, 0x3b, 0x6d, 0x61, 0x3b, 0x6d, 0x25b, 0x3b, 0x79, 0x65, 0x3b, 0x76, 0x61, 0x3b, 0x6d, 0x73, 0x3b, -0x41, 0x6e, 0x65, 0x67, 0x20, 0x31, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x32, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x33, -0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x34, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x35, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, -0x36, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x37, 0x3b, 0x41, 0x31, 0x3b, 0x41, 0x32, 0x3b, 0x41, 0x33, 0x3b, 0x41, 0x34, -0x3b, 0x41, 0x35, 0x3b, 0x41, 0x36, 0x3b, 0x41, 0x37, 0x3b, 0x6c, 0x79, 0x25b, 0x2bc, 0x25b, 0x301, 0x20, 0x73, 0x1e85, 0xed, -0x14b, 0x74, 0xe8, 0x3b, 0x6d, 0x76, 0x66, 0xf2, 0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc, 0x3b, 0x6d, 0x62, 0x254, 0x301, 0x254, -0x6e, 0x74, 0xe8, 0x20, 0x6d, 0x76, 0x66, 0xf2, 0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc, 0x3b, 0x74, 0x73, 0xe8, 0x74, 0x73, -0x25b, 0x300, 0x25b, 0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc, 0x3b, 0x6d, 0x62, 0x254, 0x301, 0x254, 0x6e, 0x74, 0xe8, 0x20, 0x74, -0x73, 0x65, 0x74, 0x73, 0x25b, 0x300, 0x25b, 0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc, 0x3b, 0x6d, 0x76, 0x66, 0xf2, 0x20, 0x6d, -0xe0, 0x67, 0x61, 0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc, 0x3b, 0x6d, 0xe0, 0x67, 0x61, 0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc, -0x3b, 0x41, 0x14b, 0x70, 0xe9, 0x74, 0x75, 0x77, 0x61, 0x6b, 0x21f, 0x61, 0x14b, 0x3b, 0x41, 0x14b, 0x70, 0xe9, 0x74, 0x75, -0x77, 0x61, 0x14b, 0x17e, 0x69, 0x3b, 0x41, 0x14b, 0x70, 0xe9, 0x74, 0x75, 0x6e, 0x75, 0x14b, 0x70, 0x61, 0x3b, 0x41, 0x14b, -0x70, 0xe9, 0x74, 0x75, 0x79, 0x61, 0x6d, 0x6e, 0x69, 0x3b, 0x41, 0x14b, 0x70, 0xe9, 0x74, 0x75, 0x74, 0x6f, 0x70, 0x61, -0x3b, 0x41, 0x14b, 0x70, 0xe9, 0x74, 0x75, 0x7a, 0x61, 0x70, 0x74, 0x61, 0x14b, 0x3b, 0x4f, 0x77, 0xe1, 0x14b, 0x67, 0x79, -0x75, 0x17e, 0x61, 0x17e, 0x61, 0x70, 0x69, 0x3b, 0x41, 0x3b, 0x57, 0x3b, 0x4e, 0x3b, 0x59, 0x3b, 0x54, 0x3b, 0x5a, 0x3b, -0x4f, 0x3b, 0x2d30, 0x2d59, 0x2d30, 0x2d4e, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d62, 0x2d4f, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d4f, 0x2d30, -0x2d59, 0x3b, 0x2d30, 0x2d3d, 0x2d55, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d3d, 0x2d61, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d4e, 0x2d61, 0x2d30, -0x2d59, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d39, 0x2d62, 0x2d30, 0x2d59, 0x3b, 0x6cc, 0x6d5, 0x6a9, 0x634, 0x6d5, 0x645, 0x645, 0x6d5, 0x3b, 0x62f, -0x648, 0x648, 0x634, 0x6d5, 0x645, 0x645, 0x6d5, 0x3b, 0x633, 0x6ce, 0x634, 0x6d5, 0x645, 0x645, 0x6d5, 0x3b, 0x686, 0x648, 0x627, 0x631, -0x634, 0x6d5, 0x645, 0x645, 0x6d5, 0x3b, 0x67e, 0x6ce, 0x646, 0x62c, 0x634, 0x6d5, 0x645, 0x645, 0x6d5, 0x3b, 0x6be, 0x6d5, 0x6cc, 0x646, -0x6cc, 0x3b, 0x634, 0x6d5, 0x645, 0x645, 0x6d5, 0x3b, 0x6cc, 0x3b, 0x62f, 0x3b, 0x633, 0x3b, 0x686, 0x3b, 0x67e, 0x3b, 0x6be, 0x3b, -0x634, 0x3b, 0x6e, 0x6a, 0x65, 0x3b, 0x70, 0xf3, 0x6e, 0x3b, 0x77, 0x61, 0x142, 0x3b, 0x73, 0x72, 0x6a, 0x3b, 0x73, 0x74, -0x77, 0x3b, 0x70, 0x11b, 0x74, 0x3b, 0x73, 0x6f, 0x62, 0x3b, 0x6e, 0x6a, 0x65, 0x17a, 0x65, 0x6c, 0x61, 0x3b, 0x70, 0xf3, -0x6e, 0x6a, 0x65, 0x17a, 0x65, 0x6c, 0x65, 0x3b, 0x77, 0x61, 0x142, 0x74, 0x6f, 0x72, 0x61, 0x3b, 0x73, 0x72, 0x6a, 0x6f, -0x64, 0x61, 0x3b, 0x73, 0x74, 0x77, 0xf3, 0x72, 0x74, 0x6b, 0x3b, 0x70, 0x11b, 0x74, 0x6b, 0x3b, 0x73, 0x6f, 0x62, 0x6f, -0x74, 0x61, 0x3b, 0x6e, 0x3b, 0x70, 0x3b, 0x77, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x70, 0x3b, 0x73, 0x3b, 0x6e, 0x6a, 0x65, -0x3b, 0x70, 0xf3, 0x6e, 0x3b, 0x77, 0x75, 0x74, 0x3b, 0x73, 0x72, 0x6a, 0x3b, 0x161, 0x74, 0x77, 0x3b, 0x70, 0x6a, 0x61, -0x3b, 0x73, 0x6f, 0x62, 0x3b, 0x6e, 0x6a, 0x65, 0x64, 0x17a, 0x65, 0x6c, 0x61, 0x3b, 0x70, 0xf3, 0x6e, 0x64, 0x17a, 0x65, -0x6c, 0x61, 0x3b, 0x77, 0x75, 0x74, 0x6f, 0x72, 0x61, 0x3b, 0x73, 0x72, 0x6a, 0x65, 0x64, 0x61, 0x3b, 0x161, 0x74, 0x77, -0xf3, 0x72, 0x74, 0x6b, 0x3b, 0x70, 0x6a, 0x61, 0x74, 0x6b, 0x3b, 0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x6e, 0x3b, -0x70, 0x3b, 0x77, 0x3b, 0x73, 0x3b, 0x161, 0x3b, 0x70, 0x3b, 0x73, 0x3b, 0x6e, 0x61, 0x64, 0x3b, 0x70, 0x61, 0x6e, 0x3b, -0x77, 0x69, 0x73, 0x3b, 0x70, 0x75, 0x73, 0x3b, 0x6b, 0x65, 0x74, 0x3b, 0x70, 0x113, 0x6e, 0x3b, 0x73, 0x61, 0x62, 0x3b, -0x6e, 0x61, 0x64, 0x12b, 0x6c, 0x69, 0x3b, 0x70, 0x61, 0x6e, 0x61, 0x64, 0x12b, 0x6c, 0x69, 0x3b, 0x77, 0x69, 0x73, 0x61, -0x73, 0x12b, 0x64, 0x69, 0x73, 0x3b, 0x70, 0x75, 0x73, 0x73, 0x69, 0x73, 0x61, 0x77, 0x61, 0x69, 0x74, 0x69, 0x3b, 0x6b, -0x65, 0x74, 0x77, 0x69, 0x72, 0x74, 0x69, 0x6b, 0x73, 0x3b, 0x70, 0x113, 0x6e, 0x74, 0x6e, 0x69, 0x6b, 0x73, 0x3b, 0x73, -0x61, 0x62, 0x61, 0x74, 0x74, 0x69, 0x6b, 0x61, 0x3b, 0x4e, 0x3b, 0x50, 0x3b, 0x57, 0x3b, 0x50, 0x3b, 0x4b, 0x3b, 0x50, -0x3b, 0x53, 0x3b, 0x70, 0x61, 0x73, 0x3b, 0x76, 0x75, 0x6f, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6b, 0x6f, 0x73, 0x3b, 0x74, -0x75, 0x6f, 0x3b, 0x76, 0xe1, 0x73, 0x3b, 0x6c, 0xe1, 0x76, 0x3b, 0x70, 0x61, 0x73, 0x65, 0x70, 0x65, 0x69, 0x76, 0x69, -0x3b, 0x76, 0x75, 0x6f, 0x73, 0x73, 0x61, 0x72, 0x67, 0xe2, 0x3b, 0x6d, 0x61, 0x6a, 0x65, 0x62, 0x61, 0x72, 0x67, 0xe2, -0x3b, 0x6b, 0x6f, 0x73, 0x6b, 0x6f, 0x6b, 0x6b, 0x6f, 0x3b, 0x74, 0x75, 0x6f, 0x72, 0xe2, 0x73, 0x74, 0xe2, 0x68, 0x3b, -0x76, 0xe1, 0x73, 0x74, 0x75, 0x70, 0x70, 0x65, 0x69, 0x76, 0x69, 0x3b, 0x6c, 0xe1, 0x76, 0x75, 0x72, 0x64, 0xe2, 0x68, -0x3b, 0x70, 0x61, 0x73, 0x65, 0x70, 0x65, 0x65, 0x69, 0x76, 0x69, 0x3b, 0x76, 0x75, 0x6f, 0x73, 0x73, 0x61, 0x61, 0x72, -0x67, 0xe2, 0x3b, 0x6d, 0x61, 0x6a, 0x65, 0x62, 0x61, 0x61, 0x72, 0x67, 0xe2, 0x3b, 0x6b, 0x6f, 0x73, 0x6b, 0x6f, 0x68, -0x6f, 0x3b, 0x74, 0x75, 0x6f, 0x72, 0xe2, 0x73, 0x74, 0x75, 0x76, 0x3b, 0x76, 0xe1, 0x73, 0x74, 0x75, 0x70, 0x70, 0x65, -0x65, 0x69, 0x76, 0x69, 0x3b, 0x6c, 0xe1, 0x76, 0x75, 0x72, 0x64, 0x75, 0x76, 0x3b, 0x70, 0x3b, 0x56, 0x3b, 0x4d, 0x3b, -0x4b, 0x3b, 0x54, 0x3b, 0x56, 0x3b, 0x4c, 0x3b +0x3b, 0x1220, 0x1209, 0x1235, 0x3b, 0x1228, 0x1261, 0x12d5, 0x3b, 0x1283, 0x1219, 0x1235, 0x3b, 0x12d3, 0x122d, 0x1262, 0x3b, 0x1240, 0x12f3, 0x121d, +0x3b, 0x1230, 0x3b, 0x1230, 0x3b, 0x1220, 0x3b, 0x1228, 0x3b, 0x1213, 0x3b, 0x12d3, 0x3b, 0x1240, 0x3b, 0x1230, 0x3b, 0x1230, 0x3b, 0x1230, +0x3b, 0x1228, 0x3b, 0x1213, 0x3b, 0x12d3, 0x3b, 0x1240, 0x3b, 0x53, 0x101, 0x70, 0x3b, 0x4d, 0x14d, 0x6e, 0x3b, 0x54, 0x16b, 0x73, +0x3b, 0x50, 0x75, 0x6c, 0x3b, 0x54, 0x75, 0x2bb, 0x61, 0x3b, 0x46, 0x61, 0x6c, 0x3b, 0x54, 0x6f, 0x6b, 0x3b, 0x53, 0x101, +0x70, 0x61, 0x74, 0x65, 0x3b, 0x4d, 0x14d, 0x6e, 0x69, 0x74, 0x65, 0x3b, 0x54, 0x16b, 0x73, 0x69, 0x74, 0x65, 0x3b, 0x50, +0x75, 0x6c, 0x65, 0x6c, 0x75, 0x6c, 0x75, 0x3b, 0x54, 0x75, 0x2bb, 0x61, 0x70, 0x75, 0x6c, 0x65, 0x6c, 0x75, 0x6c, 0x75, +0x3b, 0x46, 0x61, 0x6c, 0x61, 0x69, 0x74, 0x65, 0x3b, 0x54, 0x6f, 0x6b, 0x6f, 0x6e, 0x61, 0x6b, 0x69, 0x3b, 0x53, 0x3b, +0x4d, 0x3b, 0x54, 0x3b, 0x50, 0x3b, 0x54, 0x3b, 0x46, 0x3b, 0x54, 0x3b, 0x50, 0x61, 0x7a, 0x3b, 0x50, 0x7a, 0x74, 0x3b, +0x53, 0x61, 0x6c, 0x3b, 0xc7, 0x61, 0x72, 0x3b, 0x50, 0x65, 0x72, 0x3b, 0x43, 0x75, 0x6d, 0x3b, 0x43, 0x6d, 0x74, 0x3b, +0x50, 0x61, 0x7a, 0x61, 0x72, 0x3b, 0x50, 0x61, 0x7a, 0x61, 0x72, 0x74, 0x65, 0x73, 0x69, 0x3b, 0x53, 0x61, 0x6c, 0x131, +0x3b, 0xc7, 0x61, 0x72, 0x15f, 0x61, 0x6d, 0x62, 0x61, 0x3b, 0x50, 0x65, 0x72, 0x15f, 0x65, 0x6d, 0x62, 0x65, 0x3b, 0x43, +0x75, 0x6d, 0x61, 0x3b, 0x43, 0x75, 0x6d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x69, 0x3b, 0x50, 0x3b, 0x50, 0x3b, 0x53, 0x3b, +0xc7, 0x3b, 0x50, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0xdd, 0x65, 0x6b, 0x3b, 0x44, 0x75, 0x15f, 0x3b, 0x53, 0x69, 0x15f, 0x3b, +0xc7, 0x61, 0x72, 0x3b, 0x50, 0x65, 0x6e, 0x3b, 0x41, 0x6e, 0x6e, 0x3b, 0x15e, 0x65, 0x6e, 0x3b, 0xdd, 0x65, 0x6b, 0x15f, +0x65, 0x6e, 0x62, 0x65, 0x3b, 0x44, 0x75, 0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0x53, 0x69, 0x15f, 0x65, 0x6e, 0x62, 0x65, +0x3b, 0xc7, 0x61, 0x72, 0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0x50, 0x65, 0x6e, 0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0x41, +0x6e, 0x6e, 0x61, 0x3b, 0x15e, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0xdd, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0xc7, 0x3b, 0x50, 0x3b, +0x41, 0x3b, 0x15e, 0x3b, 0xfd, 0x65, 0x6b, 0x3b, 0x64, 0x75, 0x15f, 0x3b, 0x73, 0x69, 0x15f, 0x3b, 0xe7, 0x61, 0x72, 0x3b, +0x70, 0x65, 0x6e, 0x3b, 0x61, 0x6e, 0x6e, 0x3b, 0x15f, 0x65, 0x6e, 0x3b, 0xfd, 0x65, 0x6b, 0x15f, 0x65, 0x6e, 0x62, 0x65, +0x3b, 0x64, 0x75, 0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0x73, 0x69, 0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0xe7, 0x61, 0x72, +0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0x70, 0x65, 0x6e, 0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0x61, 0x6e, 0x6e, 0x61, 0x3b, +0x15f, 0x65, 0x6e, 0x62, 0x65, 0x3b, 0x64a, 0x6d5, 0x3b, 0x62f, 0x6c8, 0x3b, 0x633, 0x6d5, 0x3b, 0x686, 0x627, 0x3b, 0x67e, 0x6d5, +0x3b, 0x62c, 0x6c8, 0x3b, 0x634, 0x6d5, 0x3b, 0x64a, 0x6d5, 0x643, 0x634, 0x6d5, 0x646, 0x628, 0x6d5, 0x3b, 0x62f, 0x6c8, 0x634, 0x6d5, +0x646, 0x628, 0x6d5, 0x3b, 0x633, 0x6d5, 0x64a, 0x634, 0x6d5, 0x646, 0x628, 0x6d5, 0x3b, 0x686, 0x627, 0x631, 0x634, 0x6d5, 0x646, 0x628, +0x6d5, 0x3b, 0x67e, 0x6d5, 0x64a, 0x634, 0x6d5, 0x646, 0x628, 0x6d5, 0x3b, 0x62c, 0x6c8, 0x645, 0x6d5, 0x3b, 0x634, 0x6d5, 0x646, 0x628, +0x6d5, 0x3b, 0x64a, 0x3b, 0x62f, 0x3b, 0x633, 0x3b, 0x686, 0x3b, 0x67e, 0x3b, 0x62c, 0x3b, 0x634, 0x3b, 0x43d, 0x435, 0x434, 0x456, +0x43b, 0x44f, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x456, 0x43b, 0x43e, 0x43a, 0x3b, 0x432, 0x456, 0x432, 0x442, 0x43e, 0x440, 0x43e, +0x43a, 0x3b, 0x441, 0x435, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x435, 0x440, 0x3b, 0x43f, 0x2bc, 0x44f, 0x442, +0x43d, 0x438, 0x446, 0x44f, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x41d, 0x3b, 0x41f, 0x3b, 0x412, 0x3b, 0x421, 0x3b, +0x427, 0x3b, 0x41f, 0x3b, 0x421, 0x3b, 0x627, 0x62a, 0x648, 0x627, 0x631, 0x3b, 0x67e, 0x6cc, 0x631, 0x3b, 0x645, 0x646, 0x6af, 0x644, +0x3b, 0x628, 0x62f, 0x6be, 0x3b, 0x62c, 0x645, 0x639, 0x631, 0x627, 0x62a, 0x3b, 0x62c, 0x645, 0x639, 0x6c1, 0x3b, 0x6c1, 0x641, 0x62a, +0x6c1, 0x3b, 0x59, 0x61, 0x6b, 0x3b, 0x44, 0x75, 0x73, 0x68, 0x3b, 0x53, 0x65, 0x73, 0x68, 0x3b, 0x43, 0x68, 0x6f, 0x72, +0x3b, 0x50, 0x61, 0x79, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x53, 0x68, 0x61, 0x6e, 0x3b, 0x79, 0x61, 0x6b, 0x73, 0x68, 0x61, +0x6e, 0x62, 0x61, 0x3b, 0x64, 0x75, 0x73, 0x68, 0x61, 0x6e, 0x62, 0x61, 0x3b, 0x73, 0x65, 0x73, 0x68, 0x61, 0x6e, 0x62, +0x61, 0x3b, 0x63, 0x68, 0x6f, 0x72, 0x73, 0x68, 0x61, 0x6e, 0x62, 0x61, 0x3b, 0x70, 0x61, 0x79, 0x73, 0x68, 0x61, 0x6e, +0x62, 0x61, 0x3b, 0x6a, 0x75, 0x6d, 0x61, 0x3b, 0x73, 0x68, 0x61, 0x6e, 0x62, 0x61, 0x3b, 0x59, 0x3b, 0x44, 0x3b, 0x53, +0x3b, 0x43, 0x3b, 0x50, 0x3b, 0x4a, 0x3b, 0x53, 0x3b, 0x6cc, 0x2e, 0x3b, 0x62f, 0x2e, 0x3b, 0x633, 0x2e, 0x3b, 0x686, 0x2e, +0x3b, 0x67e, 0x2e, 0x3b, 0x62c, 0x2e, 0x3b, 0x634, 0x2e, 0x3b, 0x44f, 0x43a, 0x448, 0x3b, 0x434, 0x443, 0x448, 0x3b, 0x441, 0x435, +0x448, 0x3b, 0x447, 0x43e, 0x440, 0x3b, 0x43f, 0x430, 0x439, 0x3b, 0x436, 0x443, 0x43c, 0x3b, 0x448, 0x430, 0x43d, 0x3b, 0x44f, 0x43a, +0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x434, 0x443, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x441, 0x435, 0x448, 0x430, 0x43d, 0x431, +0x430, 0x3b, 0x447, 0x43e, 0x440, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x43f, 0x430, 0x439, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, +0x436, 0x443, 0x43c, 0x430, 0x3b, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x42f, 0x3b, 0x414, 0x3b, 0x421, 0x3b, 0x427, 0x3b, 0x41f, +0x3b, 0x416, 0x3b, 0x428, 0x3b, 0x43, 0x4e, 0x3b, 0x54, 0x68, 0x20, 0x32, 0x3b, 0x54, 0x68, 0x20, 0x33, 0x3b, 0x54, 0x68, +0x20, 0x34, 0x3b, 0x54, 0x68, 0x20, 0x35, 0x3b, 0x54, 0x68, 0x20, 0x36, 0x3b, 0x54, 0x68, 0x20, 0x37, 0x3b, 0x43, 0x68, +0x1ee7, 0x20, 0x4e, 0x68, 0x1ead, 0x74, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x48, 0x61, 0x69, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x42, +0x61, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x54, 0x1b0, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x4e, 0x103, 0x6d, 0x3b, 0x54, 0x68, 0x1ee9, +0x20, 0x53, 0xe1, 0x75, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x42, 0x1ea3, 0x79, 0x3b, 0x43, 0x4e, 0x3b, 0x54, 0x32, 0x3b, 0x54, +0x33, 0x3b, 0x54, 0x34, 0x3b, 0x54, 0x35, 0x3b, 0x54, 0x36, 0x3b, 0x54, 0x37, 0x3b, 0x53, 0x75, 0x3b, 0x4d, 0x75, 0x3b, +0x54, 0x75, 0x3b, 0x56, 0x65, 0x3b, 0x44, 0xf6, 0x3b, 0x46, 0x72, 0x3b, 0x5a, 0xe4, 0x3b, 0x73, 0x75, 0x64, 0x65, 0x6c, +0x3b, 0x6d, 0x75, 0x64, 0x65, 0x6c, 0x3b, 0x74, 0x75, 0x64, 0x65, 0x6c, 0x3b, 0x76, 0x65, 0x64, 0x65, 0x6c, 0x3b, 0x64, +0xf6, 0x64, 0x65, 0x6c, 0x3b, 0x66, 0x72, 0x69, 0x64, 0x65, 0x6c, 0x3b, 0x7a, 0xe4, 0x64, 0x65, 0x6c, 0x3b, 0x53, 0x3b, +0x4d, 0x3b, 0x54, 0x3b, 0x56, 0x3b, 0x44, 0x3b, 0x46, 0x3b, 0x5a, 0x3b, 0x73, 0x75, 0x2e, 0x3b, 0x6d, 0x75, 0x2e, 0x3b, +0x74, 0x75, 0x2e, 0x3b, 0x76, 0x65, 0x2e, 0x3b, 0x64, 0xf6, 0x2e, 0x3b, 0x66, 0x72, 0x2e, 0x3b, 0x7a, 0xe4, 0x2e, 0x3b, +0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x6c, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x77, 0x3b, 0x4d, 0x65, 0x72, 0x3b, 0x49, 0x61, 0x75, +0x3b, 0x47, 0x77, 0x65, 0x3b, 0x53, 0x61, 0x64, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x53, 0x75, 0x6c, 0x3b, 0x44, 0x79, +0x64, 0x64, 0x20, 0x4c, 0x6c, 0x75, 0x6e, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x4d, 0x61, 0x77, 0x72, 0x74, 0x68, 0x3b, +0x44, 0x79, 0x64, 0x64, 0x20, 0x4d, 0x65, 0x72, 0x63, 0x68, 0x65, 0x72, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x49, 0x61, +0x75, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x47, 0x77, 0x65, 0x6e, 0x65, 0x72, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x53, +0x61, 0x64, 0x77, 0x72, 0x6e, 0x3b, 0x53, 0x3b, 0x4c, 0x6c, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x49, 0x3b, 0x47, 0x3b, 0x53, +0x3b, 0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x6c, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x77, 0x3b, 0x4d, 0x65, 0x72, 0x3b, 0x49, 0x61, +0x75, 0x3b, 0x47, 0x77, 0x65, 0x6e, 0x3b, 0x53, 0x61, 0x64, 0x3b, 0x44, 0x69, 0x62, 0x3b, 0x41, 0x6c, 0x74, 0x3b, 0x54, +0x61, 0x6c, 0x3b, 0xc0, 0x6c, 0x61, 0x3b, 0x41, 0x6c, 0x78, 0x3b, 0xc0, 0x6a, 0x6a, 0x3b, 0x41, 0x73, 0x65, 0x3b, 0x44, +0x69, 0x62, 0xe9, 0x65, 0x72, 0x3b, 0x41, 0x6c, 0x74, 0x69, 0x6e, 0x65, 0x3b, 0x54, 0x61, 0x6c, 0x61, 0x61, 0x74, 0x61, +0x3b, 0xc0, 0x6c, 0x61, 0x72, 0x62, 0x61, 0x3b, 0x41, 0x6c, 0x78, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0xc0, 0x6a, 0x6a, 0x75, +0x6d, 0x61, 0x3b, 0x41, 0x73, 0x65, 0x65, 0x72, 0x3b, 0x43, 0x61, 0x77, 0x3b, 0x4d, 0x76, 0x75, 0x3b, 0x42, 0x69, 0x6e, +0x3b, 0x54, 0x68, 0x61, 0x3b, 0x53, 0x69, 0x6e, 0x3b, 0x48, 0x6c, 0x61, 0x3b, 0x4d, 0x67, 0x71, 0x3b, 0x43, 0x61, 0x77, +0x65, 0x3b, 0x4d, 0x76, 0x75, 0x6c, 0x6f, 0x3b, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x62, 0x69, 0x6e, 0x69, 0x3b, 0x4c, 0x77, +0x65, 0x73, 0x69, 0x74, 0x68, 0x61, 0x74, 0x68, 0x75, 0x3b, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x6e, 0x65, 0x3b, 0x4c, 0x77, +0x65, 0x73, 0x69, 0x68, 0x6c, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x67, 0x71, 0x69, 0x62, 0x65, 0x6c, 0x6f, 0x3b, 0x5d6, 0x5d5, +0x5e0, 0x5d8, 0x5d9, 0x5e7, 0x3b, 0x5de, 0x5d0, 0x5b8, 0x5e0, 0x5d8, 0x5d9, 0x5e7, 0x3b, 0x5d3, 0x5d9, 0x5e0, 0x5e1, 0x5d8, 0x5d9, 0x5e7, +0x3b, 0x5de, 0x5d9, 0x5d8, 0x5d5, 0x5d5, 0x5d0, 0x5da, 0x3b, 0x5d3, 0x5d0, 0x5e0, 0x5e2, 0x5e8, 0x5e9, 0x5d8, 0x5d9, 0x5e7, 0x3b, 0x5e4, +0x5bf, 0x5e8, 0x5f2, 0x5b7, 0x5d8, 0x5d9, 0x5e7, 0x3b, 0x5e9, 0x5d1, 0x5ea, 0x3b, 0xc0, 0xec, 0x6b, 0xfa, 0x3b, 0x41, 0x6a, 0xe9, +0x3b, 0xcc, 0x73, 0x1eb9, 0x301, 0x67, 0x75, 0x6e, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x72, 0xfa, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, +0x62, 0x1ecd, 0x3b, 0x1eb8, 0x74, 0xec, 0x3b, 0xc0, 0x62, 0xe1, 0x6d, 0x1eb9, 0x301, 0x74, 0x61, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, +0x20, 0xc0, 0xec, 0x6b, 0xfa, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x20, 0x41, 0x6a, 0xe9, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x20, +0xcc, 0x73, 0x1eb9, 0x301, 0x67, 0x75, 0x6e, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x72, 0xfa, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x62, +0x1ecd, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x20, 0x1eb8, 0x74, 0xec, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x20, 0xc0, 0x62, 0xe1, 0x6d, +0x1eb9, 0x301, 0x74, 0x61, 0x3b, 0xc0, 0xec, 0x6b, 0xfa, 0x3b, 0x41, 0x6a, 0xe9, 0x3b, 0xcc, 0x73, 0x25b, 0x301, 0x67, 0x75, +0x6e, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x72, 0xfa, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x62, 0x254, 0x3b, 0x190, 0x74, 0xec, 0x3b, +0xc0, 0x62, 0xe1, 0x6d, 0x25b, 0x301, 0x74, 0x61, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x20, 0xc0, 0xec, 0x6b, 0xfa, 0x3b, 0x186, +0x6a, 0x254, 0x301, 0x20, 0x41, 0x6a, 0xe9, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x20, 0xcc, 0x73, 0x25b, 0x301, 0x67, 0x75, 0x6e, +0x3b, 0x186, 0x6a, 0x254, 0x301, 0x72, 0xfa, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x62, 0x254, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x20, +0x190, 0x74, 0xec, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x20, 0xc0, 0x62, 0xe1, 0x6d, 0x25b, 0x301, 0x74, 0x61, 0x3b, 0x53, 0x6f, +0x6e, 0x3b, 0x4d, 0x73, 0x6f, 0x3b, 0x42, 0x69, 0x6c, 0x3b, 0x54, 0x68, 0x61, 0x3b, 0x53, 0x69, 0x6e, 0x3b, 0x48, 0x6c, +0x61, 0x3b, 0x4d, 0x67, 0x71, 0x3b, 0x49, 0x53, 0x6f, 0x6e, 0x74, 0x6f, 0x3b, 0x55, 0x4d, 0x73, 0x6f, 0x6d, 0x62, 0x75, +0x6c, 0x75, 0x6b, 0x6f, 0x3b, 0x55, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x55, 0x4c, 0x77, 0x65, +0x73, 0x69, 0x74, 0x68, 0x61, 0x74, 0x68, 0x75, 0x3b, 0x55, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x6e, 0x65, 0x3b, 0x55, 0x4c, +0x77, 0x65, 0x73, 0x69, 0x68, 0x6c, 0x61, 0x6e, 0x75, 0x3b, 0x55, 0x4d, 0x67, 0x71, 0x69, 0x62, 0x65, 0x6c, 0x6f, 0x3b, +0x53, 0x3b, 0x4d, 0x3b, 0x42, 0x3b, 0x54, 0x3b, 0x53, 0x3b, 0x48, 0x3b, 0x4d, 0x3b, 0x73, 0xf8, 0x6e, 0x3b, 0x6d, 0xe5, +0x6e, 0x3b, 0x74, 0x79, 0x73, 0x3b, 0x6f, 0x6e, 0x73, 0x3b, 0x74, 0x6f, 0x72, 0x3b, 0x66, 0x72, 0x65, 0x3b, 0x6c, 0x61, +0x75, 0x3b, 0x73, 0xf8, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x6d, 0xe5, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x79, 0x73, 0x64, +0x61, 0x67, 0x3b, 0x6f, 0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x6f, 0x72, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x66, 0x72, +0x65, 0x64, 0x61, 0x67, 0x3b, 0x6c, 0x61, 0x75, 0x72, 0x64, 0x61, 0x67, 0x3b, 0x73, 0xf8, 0x2e, 0x3b, 0x6d, 0xe5, 0x2e, +0x3b, 0x74, 0x79, 0x2e, 0x3b, 0x6f, 0x6e, 0x2e, 0x3b, 0x74, 0x6f, 0x2e, 0x3b, 0x66, 0x72, 0x2e, 0x3b, 0x6c, 0x61, 0x2e, +0x3b, 0x43d, 0x435, 0x434, 0x3b, 0x43f, 0x43e, 0x43d, 0x3b, 0x443, 0x442, 0x43e, 0x3b, 0x441, 0x440, 0x438, 0x3b, 0x447, 0x435, 0x442, +0x3b, 0x43f, 0x435, 0x442, 0x3b, 0x441, 0x443, 0x431, 0x3b, 0x43d, 0x435, 0x434, 0x458, 0x435, 0x459, 0x430, 0x3b, 0x43f, 0x43e, 0x43d, +0x435, 0x434, 0x458, 0x435, 0x459, 0x430, 0x43a, 0x3b, 0x443, 0x442, 0x43e, 0x440, 0x430, 0x43a, 0x3b, 0x441, 0x440, 0x438, 0x458, 0x435, +0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x440, 0x442, 0x430, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x430, 0x43a, 0x3b, 0x441, 0x443, +0x431, 0x43e, 0x442, 0x430, 0x3b, 0x4a, 0x65, 0x64, 0x3b, 0x4a, 0x65, 0x6c, 0x3b, 0x4a, 0x65, 0x6d, 0x3b, 0x4a, 0x65, 0x72, +0x63, 0x3b, 0x4a, 0x65, 0x72, 0x64, 0x3b, 0x4a, 0x65, 0x68, 0x3b, 0x4a, 0x65, 0x73, 0x3b, 0x4a, 0x65, 0x64, 0x6f, 0x6f, +0x6e, 0x65, 0x65, 0x3b, 0x4a, 0x65, 0x6c, 0x68, 0x65, 0x69, 0x6e, 0x3b, 0x4a, 0x65, 0x6d, 0x61, 0x79, 0x72, 0x74, 0x3b, +0x4a, 0x65, 0x72, 0x63, 0x65, 0x61, 0x6e, 0x3b, 0x4a, 0x65, 0x72, 0x64, 0x65, 0x69, 0x6e, 0x3b, 0x4a, 0x65, 0x68, 0x65, +0x69, 0x6e, 0x65, 0x79, 0x3b, 0x4a, 0x65, 0x73, 0x61, 0x72, 0x6e, 0x3b, 0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, +0x4d, 0x74, 0x68, 0x3b, 0x4d, 0x68, 0x72, 0x3b, 0x59, 0x6f, 0x77, 0x3b, 0x47, 0x77, 0x65, 0x3b, 0x53, 0x61, 0x64, 0x3b, +0x64, 0x79, 0x20, 0x53, 0x75, 0x6c, 0x3b, 0x64, 0x79, 0x20, 0x4c, 0x75, 0x6e, 0x3b, 0x64, 0x79, 0x20, 0x4d, 0x65, 0x75, +0x72, 0x74, 0x68, 0x3b, 0x64, 0x79, 0x20, 0x4d, 0x65, 0x72, 0x68, 0x65, 0x72, 0x3b, 0x64, 0x79, 0x20, 0x59, 0x6f, 0x77, +0x3b, 0x64, 0x79, 0x20, 0x47, 0x77, 0x65, 0x6e, 0x65, 0x72, 0x3b, 0x64, 0x79, 0x20, 0x53, 0x61, 0x64, 0x6f, 0x72, 0x6e, +0x3b, 0x4b, 0x77, 0x65, 0x3b, 0x44, 0x77, 0x6f, 0x3b, 0x42, 0x65, 0x6e, 0x3b, 0x57, 0x75, 0x6b, 0x3b, 0x59, 0x61, 0x77, +0x3b, 0x46, 0x69, 0x61, 0x3b, 0x4d, 0x65, 0x6d, 0x3b, 0x4b, 0x77, 0x65, 0x73, 0x69, 0x64, 0x61, 0x3b, 0x44, 0x77, 0x6f, +0x77, 0x64, 0x61, 0x3b, 0x42, 0x65, 0x6e, 0x61, 0x64, 0x61, 0x3b, 0x57, 0x75, 0x6b, 0x75, 0x64, 0x61, 0x3b, 0x59, 0x61, +0x77, 0x64, 0x61, 0x3b, 0x46, 0x69, 0x64, 0x61, 0x3b, 0x4d, 0x65, 0x6d, 0x65, 0x6e, 0x65, 0x64, 0x61, 0x3b, 0x4b, 0x3b, +0x44, 0x3b, 0x42, 0x3b, 0x57, 0x3b, 0x59, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x906, 0x92f, 0x924, 0x93e, 0x930, 0x3b, 0x938, 0x94b, +0x92e, 0x93e, 0x930, 0x3b, 0x92e, 0x902, 0x917, 0x933, 0x93e, 0x930, 0x3b, 0x92c, 0x941, 0x927, 0x935, 0x93e, 0x930, 0x3b, 0x917, 0x941, +0x930, 0x941, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x93e, 0x930, 0x3b, 0x936, 0x947, 0x928, 0x935, 0x93e, 0x930, +0x3b, 0x906, 0x3b, 0x938, 0x94b, 0x3b, 0x92e, 0x902, 0x3b, 0x92c, 0x941, 0x3b, 0x917, 0x941, 0x3b, 0x936, 0x941, 0x3b, 0x936, 0x947, +0x3b, 0x1ee4, 0x6b, 0x61, 0x3b, 0x4d, 0x1ecd, 0x6e, 0x3b, 0x54, 0x69, 0x75, 0x3b, 0x57, 0x65, 0x6e, 0x3b, 0x54, 0x1ecd, 0x1ecd, +0x3b, 0x46, 0x72, 0x61, 0x1ecb, 0x3b, 0x53, 0x61, 0x74, 0x3b, 0x4d, 0x62, 0x1ecd, 0x73, 0x1ecb, 0x20, 0x1ee4, 0x6b, 0x61, 0x3b, +0x4d, 0x1ecd, 0x6e, 0x64, 0x65, 0x3b, 0x54, 0x69, 0x75, 0x7a, 0x64, 0x65, 0x65, 0x3b, 0x57, 0x65, 0x6e, 0x65, 0x7a, 0x64, +0x65, 0x65, 0x3b, 0x54, 0x1ecd, 0x1ecd, 0x7a, 0x64, 0x65, 0x65, 0x3b, 0x46, 0x72, 0x61, 0x1ecb, 0x64, 0x65, 0x65, 0x3b, 0x53, +0x61, 0x74, 0x1ecd, 0x64, 0x65, 0x65, 0x3b, 0x57, 0x6b, 0x79, 0x3b, 0x57, 0x6b, 0x77, 0x3b, 0x57, 0x6b, 0x6c, 0x3b, 0x57, +0x74, 0x169, 0x3b, 0x57, 0x6b, 0x6e, 0x3b, 0x57, 0x74, 0x6e, 0x3b, 0x57, 0x74, 0x68, 0x3b, 0x57, 0x61, 0x20, 0x6b, 0x79, +0x75, 0x6d, 0x77, 0x61, 0x3b, 0x57, 0x61, 0x20, 0x6b, 0x77, 0x61, 0x6d, 0x62, 0x129, 0x6c, 0x129, 0x6c, 0x79, 0x61, 0x3b, +0x57, 0x61, 0x20, 0x6b, 0x65, 0x6c, 0x129, 0x3b, 0x57, 0x61, 0x20, 0x6b, 0x61, 0x74, 0x61, 0x74, 0x169, 0x3b, 0x57, 0x61, +0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x57, 0x61, 0x20, 0x6b, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x57, 0x61, 0x20, 0x74, +0x68, 0x61, 0x6e, 0x74, 0x68, 0x61, 0x74, 0x169, 0x3b, 0x59, 0x3b, 0x57, 0x3b, 0x45, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, +0x3b, 0x41, 0x3b, 0x64, 0x6f, 0x6d, 0x3b, 0x6c, 0x75, 0x6e, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0x69, 0x65, 0x3b, 0x6a, +0x6f, 0x69, 0x3b, 0x76, 0x69, 0x6e, 0x3b, 0x73, 0x61, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x65, 0x6e, 0x69, 0x65, 0x3b, 0x6c, +0x75, 0x6e, 0x69, 0x73, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x61, 0x72, 0x73, 0x3b, 0x6d, 0x69, 0x65, 0x72, 0x63, 0x75, 0x73, +0x3b, 0x6a, 0x6f, 0x69, 0x62, 0x65, 0x3b, 0x76, 0x69, 0x6e, 0x61, 0x72, 0x73, 0x3b, 0x73, 0x61, 0x62, 0x69, 0x64, 0x65, +0x3b, 0x6b, 0x254, 0x73, 0x3b, 0x64, 0x7a, 0x6f, 0x3b, 0x62, 0x6c, 0x61, 0x3b, 0x6b, 0x75, 0x256, 0x3b, 0x79, 0x61, 0x77, +0x3b, 0x66, 0x69, 0x256, 0x3b, 0x6d, 0x65, 0x6d, 0x3b, 0x6b, 0x254, 0x73, 0x69, 0x256, 0x61, 0x3b, 0x64, 0x7a, 0x6f, 0x256, +0x61, 0x3b, 0x62, 0x6c, 0x61, 0x256, 0x61, 0x3b, 0x6b, 0x75, 0x256, 0x61, 0x3b, 0x79, 0x61, 0x77, 0x6f, 0x256, 0x61, 0x3b, +0x66, 0x69, 0x256, 0x61, 0x3b, 0x6d, 0x65, 0x6d, 0x6c, 0x65, 0x256, 0x61, 0x3b, 0x6b, 0x3b, 0x64, 0x3b, 0x62, 0x3b, 0x6b, +0x3b, 0x79, 0x3b, 0x66, 0x3b, 0x6d, 0x3b, 0x4c, 0x50, 0x3b, 0x50, 0x31, 0x3b, 0x50, 0x32, 0x3b, 0x50, 0x33, 0x3b, 0x50, +0x34, 0x3b, 0x50, 0x35, 0x3b, 0x50, 0x36, 0x3b, 0x4c, 0x101, 0x70, 0x75, 0x6c, 0x65, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x6b, +0x61, 0x68, 0x69, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x6c, 0x75, 0x61, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x6b, 0x6f, 0x6c, 0x75, +0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x68, 0x101, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x6c, 0x69, 0x6d, 0x61, 0x3b, 0x50, 0x6f, 0x2bb, +0x61, 0x6f, 0x6e, 0x6f, 0x3b, 0x4c, 0x69, 0x6e, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x4d, 0x69, 0x79, +0x3b, 0x48, 0x75, 0x77, 0x3b, 0x42, 0x69, 0x79, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4c, 0x69, 0x6e, 0x67, 0x67, 0x6f, 0x3b, +0x4c, 0x75, 0x6e, 0x65, 0x73, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x3b, 0x4d, 0x69, 0x79, 0x65, 0x72, 0x6b, 0x75, +0x6c, 0x65, 0x73, 0x3b, 0x48, 0x75, 0x77, 0x65, 0x62, 0x65, 0x73, 0x3b, 0x42, 0x69, 0x79, 0x65, 0x72, 0x6e, 0x65, 0x73, +0x3b, 0x53, 0x61, 0x62, 0x61, 0x64, 0x6f, 0x3b, 0x53, 0x75, 0x2e, 0x3b, 0x4d, 0xe4, 0x2e, 0x3b, 0x5a, 0x69, 0x2e, 0x3b, +0x4d, 0x69, 0x2e, 0x3b, 0x44, 0x75, 0x2e, 0x3b, 0x46, 0x72, 0x2e, 0x3b, 0x53, 0x61, 0x2e, 0x3b, 0x53, 0x75, 0x6e, 0x6e, +0x74, 0x69, 0x67, 0x3b, 0x4d, 0xe4, 0xe4, 0x6e, 0x74, 0x69, 0x67, 0x3b, 0x5a, 0x69, 0x69, 0x73, 0x63, 0x68, 0x74, 0x69, +0x67, 0x3b, 0x4d, 0x69, 0x74, 0x74, 0x77, 0x75, 0x63, 0x68, 0x3b, 0x44, 0x75, 0x6e, 0x73, 0x63, 0x68, 0x74, 0x69, 0x67, +0x3b, 0x46, 0x72, 0x69, 0x69, 0x74, 0x69, 0x67, 0x3b, 0x53, 0x61, 0x6d, 0x73, 0x63, 0x68, 0x74, 0x69, 0x67, 0x3b, 0xa46d, +0xa18f, 0x3b, 0xa18f, 0xa2cd, 0x3b, 0xa18f, 0xa44d, 0x3b, 0xa18f, 0xa315, 0x3b, 0xa18f, 0xa1d6, 0x3b, 0xa18f, 0xa26c, 0x3b, 0xa18f, 0xa0d8, 0x3b, +0xa46d, 0xa18f, 0xa44d, 0x3b, 0xa18f, 0xa282, 0xa2cd, 0x3b, 0xa18f, 0xa282, 0xa44d, 0x3b, 0xa18f, 0xa282, 0xa315, 0x3b, 0xa18f, 0xa282, 0xa1d6, 0x3b, +0xa18f, 0xa282, 0xa26c, 0x3b, 0xa18f, 0xa282, 0xa0d8, 0x3b, 0xa18f, 0x3b, 0xa2cd, 0x3b, 0xa44d, 0x3b, 0xa315, 0x3b, 0xa1d6, 0x3b, 0xa26c, 0x3b, +0xa0d8, 0x3b, 0x53, 0xfc, 0x2e, 0x3b, 0x4d, 0x61, 0x2e, 0x3b, 0x44, 0x69, 0x2e, 0x3b, 0x4d, 0x69, 0x2e, 0x3b, 0x44, 0x75, +0x2e, 0x3b, 0x46, 0x72, 0x2e, 0x3b, 0x53, 0x61, 0x2e, 0x3b, 0x53, 0xfc, 0x6e, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x4d, 0x61, +0x61, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x44, 0x69, 0x6e, 0x67, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x4d, 0x69, 0x64, 0x64, 0x65, +0x77, 0x65, 0x6b, 0x65, 0x6e, 0x3b, 0x44, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x46, 0x72, 0x65, +0x65, 0x64, 0x61, 0x67, 0x3b, 0x53, 0xfc, 0x6e, 0x6e, 0x61, 0x76, 0x65, 0x6e, 0x64, 0x3b, 0x73, 0x6f, 0x74, 0x6e, 0x3b, +0x76, 0x75, 0x6f, 0x73, 0x3b, 0x6d, 0x61, 0x14b, 0x3b, 0x67, 0x61, 0x73, 0x6b, 0x3b, 0x64, 0x75, 0x6f, 0x72, 0x3b, 0x62, +0x65, 0x61, 0x72, 0x3b, 0x6c, 0xe1, 0x76, 0x3b, 0x73, 0x6f, 0x74, 0x6e, 0x61, 0x62, 0x65, 0x61, 0x69, 0x76, 0x69, 0x3b, +0x76, 0x75, 0x6f, 0x73, 0x73, 0xe1, 0x72, 0x67, 0x61, 0x3b, 0x6d, 0x61, 0x14b, 0x14b, 0x65, 0x62, 0xe1, 0x72, 0x67, 0x61, +0x3b, 0x67, 0x61, 0x73, 0x6b, 0x61, 0x76, 0x61, 0x68, 0x6b, 0x6b, 0x75, 0x3b, 0x64, 0x75, 0x6f, 0x72, 0x61, 0x73, 0x64, +0x61, 0x74, 0x3b, 0x62, 0x65, 0x61, 0x72, 0x6a, 0x61, 0x64, 0x61, 0x74, 0x3b, 0x6c, 0xe1, 0x76, 0x76, 0x61, 0x72, 0x64, +0x61, 0x74, 0x3b, 0x53, 0x3b, 0x56, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x44, 0x3b, 0x42, 0x3b, 0x4c, 0x3b, 0x73, 0x6f, 0x3b, +0x6d, 0xe1, 0x3b, 0x64, 0x69, 0x3b, 0x67, 0x61, 0x3b, 0x64, 0x75, 0x3b, 0x62, 0x65, 0x3b, 0x6c, 0xe1, 0x3b, 0x73, 0x6f, +0x74, 0x6e, 0x61, 0x62, 0x65, 0x61, 0x69, 0x76, 0x69, 0x3b, 0x6d, 0xe1, 0x6e, 0x6e, 0x6f, 0x64, 0x61, 0x74, 0x3b, 0x64, +0x69, 0x73, 0x64, 0x61, 0x74, 0x3b, 0x67, 0x61, 0x73, 0x6b, 0x61, 0x76, 0x61, 0x68, 0x6b, 0x6b, 0x75, 0x3b, 0x64, 0x75, +0x6f, 0x72, 0x61, 0x73, 0x74, 0x61, 0x74, 0x3b, 0x62, 0x65, 0x61, 0x72, 0x6a, 0x61, 0x64, 0x61, 0x74, 0x3b, 0x6c, 0xe1, +0x76, 0x76, 0x6f, 0x72, 0x64, 0x61, 0x74, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x44, 0x3b, 0x47, 0x3b, 0x44, 0x3b, 0x42, 0x3b, +0x4c, 0x3b, 0x43, 0x70, 0x72, 0x3b, 0x43, 0x74, 0x74, 0x3b, 0x43, 0x6d, 0x6e, 0x3b, 0x43, 0x6d, 0x74, 0x3b, 0x41, 0x72, +0x73, 0x3b, 0x49, 0x63, 0x6d, 0x3b, 0x45, 0x73, 0x74, 0x3b, 0x43, 0x68, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x72, 0x69, 0x3b, +0x43, 0x68, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x6f, 0x3b, 0x43, 0x68, 0x75, 0x6d, 0x61, 0x69, 0x6e, 0x65, 0x3b, 0x43, +0x68, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x72, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x63, 0x68, +0x75, 0x6d, 0x61, 0x3b, 0x45, 0x73, 0x61, 0x62, 0x61, 0x74, 0x6f, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x43, 0x3b, +0x41, 0x3b, 0x49, 0x3b, 0x45, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x4a, 0x69, 0x6d, 0x3b, 0x4b, 0x61, 0x77, 0x3b, 0x4b, 0x61, +0x64, 0x3b, 0x4b, 0x61, 0x6e, 0x3b, 0x4b, 0x61, 0x73, 0x3b, 0x4e, 0x67, 0x75, 0x3b, 0x49, 0x74, 0x75, 0x6b, 0x75, 0x20, +0x6a, 0x61, 0x20, 0x6a, 0x75, 0x6d, 0x77, 0x61, 0x3b, 0x4b, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x20, 0x6a, 0x69, +0x6d, 0x77, 0x65, 0x72, 0x69, 0x3b, 0x4b, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x20, 0x6b, 0x61, 0x77, 0x69, 0x3b, +0x4b, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x20, 0x6b, 0x61, 0x64, 0x61, 0x64, 0x75, 0x3b, 0x4b, 0x75, 0x72, 0x61, +0x6d, 0x75, 0x6b, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4b, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x20, 0x6b, +0x61, 0x73, 0x61, 0x6e, 0x75, 0x3b, 0x4b, 0x69, 0x66, 0x75, 0x6c, 0x61, 0x20, 0x6e, 0x67, 0x75, 0x77, 0x6f, 0x3b, 0x4a, +0x3b, 0x4a, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x64, 0x65, 0x77, 0x3b, 0x61, 0x61, 0x253, +0x3b, 0x6d, 0x61, 0x77, 0x3b, 0x6e, 0x6a, 0x65, 0x3b, 0x6e, 0x61, 0x61, 0x3b, 0x6d, 0x77, 0x64, 0x3b, 0x68, 0x62, 0x69, +0x3b, 0x64, 0x65, 0x77, 0x6f, 0x3b, 0x61, 0x61, 0x253, 0x6e, 0x64, 0x65, 0x3b, 0x6d, 0x61, 0x77, 0x62, 0x61, 0x61, 0x72, +0x65, 0x3b, 0x6e, 0x6a, 0x65, 0x73, 0x6c, 0x61, 0x61, 0x72, 0x65, 0x3b, 0x6e, 0x61, 0x61, 0x73, 0x61, 0x61, 0x6e, 0x64, +0x65, 0x3b, 0x6d, 0x61, 0x77, 0x6e, 0x64, 0x65, 0x3b, 0x68, 0x6f, 0x6f, 0x72, 0x65, 0x2d, 0x62, 0x69, 0x69, 0x72, 0x3b, +0x64, 0x3b, 0x61, 0x3b, 0x6d, 0x3b, 0x6e, 0x3b, 0x6e, 0x3b, 0x6d, 0x3b, 0x68, 0x3b, 0x4b, 0x4d, 0x41, 0x3b, 0x4e, 0x54, +0x54, 0x3b, 0x4e, 0x4d, 0x4e, 0x3b, 0x4e, 0x4d, 0x54, 0x3b, 0x41, 0x52, 0x54, 0x3b, 0x4e, 0x4d, 0x41, 0x3b, 0x4e, 0x4d, +0x4d, 0x3b, 0x4b, 0x69, 0x75, 0x6d, 0x69, 0x61, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x169, 0x3b, 0x4e, +0x6a, 0x75, 0x6d, 0x61, 0x69, 0x6e, 0x65, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x61, 0x3b, 0x41, 0x72, +0x61, 0x6d, 0x69, 0x74, 0x68, 0x69, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x6d, +0x6f, 0x74, 0x68, 0x69, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x41, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x41, +0x72, 0x65, 0x3b, 0x4b, 0x75, 0x6e, 0x3b, 0x4f, 0x6e, 0x67, 0x3b, 0x49, 0x6e, 0x65, 0x3b, 0x49, 0x6c, 0x65, 0x3b, 0x53, +0x61, 0x70, 0x3b, 0x4b, 0x77, 0x65, 0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x61, 0x72, 0x65, +0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x6b, 0x75, 0x6e, 0x69, 0x3b, 0x4d, 0x64, 0x65, 0x72, +0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x6f, 0x6e, 0x67, 0x2019, 0x77, 0x61, 0x6e, 0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74, +0x20, 0x65, 0x65, 0x20, 0x69, 0x6e, 0x65, 0x74, 0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x69, +0x6c, 0x65, 0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x73, 0x61, 0x70, 0x61, 0x3b, 0x4d, 0x64, +0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x6b, 0x77, 0x65, 0x3b, 0x41, 0x3b, 0x4b, 0x3b, 0x4f, 0x3b, 0x49, 0x3b, +0x49, 0x3b, 0x53, 0x3b, 0x4b, 0x3b, 0x44, 0x69, 0x6d, 0x3b, 0x50, 0x6f, 0x73, 0x3b, 0x50, 0x69, 0x72, 0x3b, 0x54, 0x61, +0x74, 0x3b, 0x4e, 0x61, 0x69, 0x3b, 0x53, 0x68, 0x61, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x44, 0x69, 0x6d, 0x69, 0x6e, 0x67, +0x75, 0x3b, 0x43, 0x68, 0x69, 0x70, 0x6f, 0x73, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x70, 0x69, 0x72, 0x69, 0x3b, 0x43, 0x68, +0x69, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x73, 0x68, 0x61, 0x6e, +0x75, 0x3b, 0x53, 0x61, 0x62, 0x75, 0x64, 0x75, 0x3b, 0x44, 0x3b, 0x50, 0x3b, 0x43, 0x3b, 0x54, 0x3b, 0x4e, 0x3b, 0x53, +0x3b, 0x53, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0x76, 0x75, 0x3b, 0x53, 0x69, 0x62, 0x3b, 0x53, 0x69, 0x74, 0x3b, 0x53, +0x69, 0x6e, 0x3b, 0x53, 0x69, 0x68, 0x3b, 0x4d, 0x67, 0x71, 0x3b, 0x53, 0x6f, 0x6e, 0x74, 0x6f, 0x3b, 0x4d, 0x76, 0x75, +0x6c, 0x6f, 0x3b, 0x53, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x53, 0x69, 0x74, 0x68, 0x61, 0x74, 0x68, 0x75, 0x3b, 0x53, +0x69, 0x6e, 0x65, 0x3b, 0x53, 0x69, 0x68, 0x6c, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x67, 0x71, 0x69, 0x62, 0x65, 0x6c, 0x6f, +0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x49, 0x6a, 0x70, 0x3b, 0x49, +0x6a, 0x74, 0x3b, 0x49, 0x6a, 0x6e, 0x3b, 0x49, 0x6a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x75, 0x3b, +0x49, 0x6a, 0x6d, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x6c, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x74, +0x61, 0x74, 0x75, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x74, 0x61, +0x6e, 0x6f, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x49, +0x6a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x32, 0x3b, 0x33, 0x3b, 0x34, 0x3b, 0x35, 0x3b, 0x36, 0x3b, 0x37, +0x3b, 0x31, 0x3b, 0x2d30, 0x2d59, 0x2d30, 0x3b, 0x2d30, 0x2d62, 0x2d4f, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x3b, 0x2d30, 0x2d3d, 0x2d55, 0x3b, 0x2d30, +0x2d3d, 0x2d61, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d4e, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d39, 0x3b, 0x2d30, 0x2d59, 0x2d30, 0x2d4e, 0x2d30, 0x2d59, 0x3b, +0x2d30, 0x2d62, 0x2d4f, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d4f, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d3d, 0x2d55, 0x2d30, 0x2d59, 0x3b, 0x2d30, +0x2d3d, 0x2d61, 0x2d30, 0x2d59, 0x3b, 0x2d59, 0x2d49, 0x2d4e, 0x2d61, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d39, 0x2d62, 0x2d30, 0x2d59, 0x3b, +0x61, 0x73, 0x61, 0x3b, 0x61, 0x79, 0x6e, 0x3b, 0x61, 0x73, 0x69, 0x3b, 0x61, 0x6b, 0x1e5b, 0x3b, 0x61, 0x6b, 0x77, 0x3b, +0x61, 0x73, 0x69, 0x6d, 0x3b, 0x61, 0x73, 0x69, 0x1e0d, 0x3b, 0x61, 0x73, 0x61, 0x6d, 0x61, 0x73, 0x3b, 0x61, 0x79, 0x6e, +0x61, 0x73, 0x3b, 0x61, 0x73, 0x69, 0x6e, 0x61, 0x73, 0x3b, 0x61, 0x6b, 0x1e5b, 0x61, 0x73, 0x3b, 0x61, 0x6b, 0x77, 0x61, +0x73, 0x3b, 0x61, 0x73, 0x69, 0x6d, 0x77, 0x61, 0x73, 0x3b, 0x61, 0x73, 0x69, 0x1e0d, 0x79, 0x61, 0x73, 0x3b, 0x41, 0x63, +0x65, 0x3b, 0x41, 0x72, 0x69, 0x3b, 0x41, 0x72, 0x61, 0x3b, 0x41, 0x68, 0x61, 0x3b, 0x41, 0x6d, 0x68, 0x3b, 0x53, 0x65, +0x6d, 0x3b, 0x53, 0x65, 0x64, 0x3b, 0x41, 0x63, 0x65, 0x72, 0x3b, 0x41, 0x72, 0x69, 0x6d, 0x3b, 0x41, 0x72, 0x61, 0x6d, +0x3b, 0x41, 0x68, 0x61, 0x64, 0x3b, 0x41, 0x6d, 0x68, 0x61, 0x64, 0x3b, 0x53, 0x65, 0x6d, 0x3b, 0x53, 0x65, 0x64, 0x3b, +0x59, 0x3b, 0x53, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x59, 0x61, 0x6e, 0x3b, 0x53, 0x61, +0x6e, 0x3b, 0x4b, 0x72, 0x61, 0x1e0d, 0x3b, 0x4b, 0x75, 0x1e93, 0x3b, 0x53, 0x61, 0x6d, 0x3b, 0x53, 0x1e0d, 0x69, 0x73, 0x3b, +0x53, 0x61, 0x79, 0x3b, 0x59, 0x61, 0x6e, 0x61, 0x73, 0x73, 0x3b, 0x53, 0x61, 0x6e, 0x61, 0x73, 0x73, 0x3b, 0x4b, 0x72, +0x61, 0x1e0d, 0x61, 0x73, 0x73, 0x3b, 0x4b, 0x75, 0x1e93, 0x61, 0x73, 0x73, 0x3b, 0x53, 0x61, 0x6d, 0x61, 0x73, 0x73, 0x3b, +0x53, 0x1e0d, 0x69, 0x73, 0x61, 0x73, 0x73, 0x3b, 0x53, 0x61, 0x79, 0x61, 0x73, 0x73, 0x3b, 0x43, 0x3b, 0x52, 0x3b, 0x41, +0x3b, 0x48, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x44, 0x3b, 0x53, 0x41, 0x4e, 0x3b, 0x4f, 0x52, 0x4b, 0x3b, 0x4f, 0x4b, 0x42, +0x3b, 0x4f, 0x4b, 0x53, 0x3b, 0x4f, 0x4b, 0x4e, 0x3b, 0x4f, 0x4b, 0x54, 0x3b, 0x4f, 0x4d, 0x4b, 0x3b, 0x53, 0x61, 0x6e, +0x64, 0x65, 0x3b, 0x4f, 0x72, 0x77, 0x6f, 0x6b, 0x75, 0x62, 0x61, 0x6e, 0x7a, 0x61, 0x3b, 0x4f, 0x72, 0x77, 0x61, 0x6b, +0x61, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4f, 0x72, 0x77, 0x61, 0x6b, 0x61, 0x73, 0x68, 0x61, 0x74, 0x75, 0x3b, 0x4f, 0x72, +0x77, 0x61, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4f, 0x72, 0x77, 0x61, 0x6b, 0x61, 0x74, 0x61, 0x61, 0x6e, 0x6f, 0x3b, 0x4f, +0x72, 0x77, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x61, 0x67, 0x61, 0x3b, 0x53, 0x3b, 0x4b, 0x3b, 0x52, 0x3b, 0x53, 0x3b, 0x4e, +0x3b, 0x54, 0x3b, 0x4d, 0x3b, 0x4d, 0x75, 0x6c, 0x3b, 0x56, 0x69, 0x6c, 0x3b, 0x48, 0x69, 0x76, 0x3b, 0x48, 0x69, 0x64, +0x3b, 0x48, 0x69, 0x74, 0x3b, 0x48, 0x69, 0x68, 0x3b, 0x4c, 0x65, 0x6d, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x75, 0x6c, 0x75, +0x6e, 0x67, 0x75, 0x3b, 0x70, 0x61, 0x20, 0x73, 0x68, 0x61, 0x68, 0x75, 0x76, 0x69, 0x6c, 0x75, 0x68, 0x61, 0x3b, 0x70, +0x61, 0x20, 0x68, 0x69, 0x76, 0x69, 0x6c, 0x69, 0x3b, 0x70, 0x61, 0x20, 0x68, 0x69, 0x64, 0x61, 0x74, 0x75, 0x3b, 0x70, +0x61, 0x20, 0x68, 0x69, 0x74, 0x61, 0x79, 0x69, 0x3b, 0x70, 0x61, 0x20, 0x68, 0x69, 0x68, 0x61, 0x6e, 0x75, 0x3b, 0x70, +0x61, 0x20, 0x73, 0x68, 0x61, 0x68, 0x75, 0x6c, 0x65, 0x6d, 0x62, 0x65, 0x6c, 0x61, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x48, +0x3b, 0x48, 0x3b, 0x48, 0x3b, 0x57, 0x3b, 0x4a, 0x3b, 0x4a, 0x70, 0x69, 0x3b, 0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6e, 0x6e, +0x3b, 0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x75, 0x3b, 0x4a, 0x6d, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, +0x61, 0x70, 0x69, 0x6c, 0x79, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x75, 0x75, 0x3b, 0x4a, 0x75, 0x6d, +0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x75, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, +0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x4a, +0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x4a, 0x3b, 0x6b, 0x61, 0x72, 0x3b, 0x6e, 0x74, 0x25b, +0x3b, 0x74, 0x61, 0x72, 0x3b, 0x61, 0x72, 0x61, 0x3b, 0x61, 0x6c, 0x61, 0x3b, 0x6a, 0x75, 0x6d, 0x3b, 0x73, 0x69, 0x62, +0x3b, 0x6b, 0x61, 0x72, 0x69, 0x3b, 0x6e, 0x74, 0x25b, 0x6e, 0x25b, 0x3b, 0x74, 0x61, 0x72, 0x61, 0x74, 0x61, 0x3b, 0x61, +0x72, 0x61, 0x62, 0x61, 0x3b, 0x61, 0x6c, 0x61, 0x6d, 0x69, 0x73, 0x61, 0x3b, 0x6a, 0x75, 0x6d, 0x61, 0x3b, 0x73, 0x69, +0x62, 0x69, 0x72, 0x69, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x4a, 0x3b, 0x53, 0x3b, 0x4b, +0x6d, 0x61, 0x3b, 0x54, 0x61, 0x74, 0x3b, 0x49, 0x6e, 0x65, 0x3b, 0x54, 0x61, 0x6e, 0x3b, 0x41, 0x72, 0x6d, 0x3b, 0x4d, +0x61, 0x61, 0x3b, 0x4e, 0x4d, 0x4d, 0x3b, 0x4b, 0x69, 0x75, 0x6d, 0x69, 0x61, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x74, +0x61, 0x74, 0x75, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x69, 0x6e, 0x65, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x74, 0x61, +0x6e, 0x6f, 0x3b, 0x41, 0x72, 0x61, 0x6d, 0x69, 0x74, 0x68, 0x69, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4e, +0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x74, 0x68, 0x69, 0x69, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x41, +0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x13c6, 0x13cd, 0x13ac, 0x3b, 0x13c9, 0x13c5, 0x13af, 0x3b, 0x13d4, 0x13b5, 0x13c1, 0x3b, 0x13e6, 0x13a2, 0x13c1, +0x3b, 0x13c5, 0x13a9, 0x13c1, 0x3b, 0x13e7, 0x13be, 0x13a9, 0x3b, 0x13c8, 0x13d5, 0x13be, 0x3b, 0x13a4, 0x13be, 0x13d9, 0x13d3, 0x13c6, 0x13cd, 0x13ac, +0x3b, 0x13a4, 0x13be, 0x13d9, 0x13d3, 0x13c9, 0x13c5, 0x13af, 0x3b, 0x13d4, 0x13b5, 0x13c1, 0x13a2, 0x13a6, 0x3b, 0x13e6, 0x13a2, 0x13c1, 0x13a2, 0x13a6, +0x3b, 0x13c5, 0x13a9, 0x13c1, 0x13a2, 0x13a6, 0x3b, 0x13e7, 0x13be, 0x13a9, 0x13b6, 0x13cd, 0x13d7, 0x3b, 0x13a4, 0x13be, 0x13d9, 0x13d3, 0x13c8, 0x13d5, +0x13be, 0x3b, 0x13c6, 0x3b, 0x13c9, 0x3b, 0x13d4, 0x3b, 0x13e6, 0x3b, 0x13c5, 0x3b, 0x13e7, 0x3b, 0x13a4, 0x3b, 0x64, 0x69, 0x6d, 0x3b, +0x6c, 0x69, 0x6e, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0x65, 0x72, 0x3b, 0x7a, 0x65, 0x3b, 0x76, 0x61, 0x6e, 0x3b, 0x73, +0x61, 0x6d, 0x3b, 0x64, 0x69, 0x6d, 0x61, 0x6e, 0x73, 0x3b, 0x6c, 0x69, 0x6e, 0x64, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x64, +0x69, 0x3b, 0x6d, 0x65, 0x72, 0x6b, 0x72, 0x65, 0x64, 0x69, 0x3b, 0x7a, 0x65, 0x64, 0x69, 0x3b, 0x76, 0x61, 0x6e, 0x64, +0x72, 0x65, 0x64, 0x69, 0x3b, 0x73, 0x61, 0x6d, 0x64, 0x69, 0x3b, 0x64, 0x3b, 0x6c, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x7a, +0x3b, 0x76, 0x3b, 0x73, 0x3b, 0x4c, 0x6c, 0x32, 0x3b, 0x4c, 0x6c, 0x33, 0x3b, 0x4c, 0x6c, 0x34, 0x3b, 0x4c, 0x6c, 0x35, +0x3b, 0x4c, 0x6c, 0x36, 0x3b, 0x4c, 0x6c, 0x37, 0x3b, 0x4c, 0x6c, 0x31, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, +0x6c, 0x79, 0x61, 0x70, 0x69, 0x6c, 0x69, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x74, 0x61, +0x74, 0x75, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x63, 0x68, 0x69, +0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x6e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x3b, 0x4c, 0x69, +0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x6e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x6c, 0x69, +0x6e, 0x6a, 0x69, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x6e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, +0x20, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x76, 0x69, 0x6c, 0x69, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x69, +0x74, 0x61, 0x6e, 0x64, 0x69, 0x3b, 0x50, 0xed, 0x69, 0x6c, 0x69, 0x3b, 0x54, 0xe1, 0x61, 0x74, 0x75, 0x3b, 0xcd, 0x6e, +0x65, 0x3b, 0x54, 0xe1, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x6d, 0x3b, 0x4d, 0xf3, 0x6f, 0x73, +0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0xed, 0x69, 0x72, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0xe1, 0x74, 0x75, +0x3b, 0x4a, 0x75, 0x6d, 0x61, 0xed, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0xe1, 0x61, 0x6e, 0x6f, 0x3b, 0x41, +0x6c, 0x61, 0x6d, 0xed, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0xe1, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, +0xf3, 0x6f, 0x73, 0x69, 0x3b, 0x50, 0x3b, 0x54, 0x3b, 0x45, 0x3b, 0x4f, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x4d, 0x3b, 0x53, +0x61, 0x62, 0x3b, 0x42, 0x61, 0x6c, 0x3b, 0x4c, 0x77, 0x32, 0x3b, 0x4c, 0x77, 0x33, 0x3b, 0x4c, 0x77, 0x34, 0x3b, 0x4c, +0x77, 0x35, 0x3b, 0x4c, 0x77, 0x36, 0x3b, 0x53, 0x61, 0x62, 0x62, 0x69, 0x69, 0x74, 0x69, 0x3b, 0x42, 0x61, 0x6c, 0x61, +0x7a, 0x61, 0x3b, 0x4c, 0x77, 0x61, 0x6b, 0x75, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4c, 0x77, 0x61, 0x6b, 0x75, 0x73, 0x61, +0x74, 0x75, 0x3b, 0x4c, 0x77, 0x61, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x4c, 0x77, 0x61, 0x6b, 0x75, 0x74, 0x61, 0x61, 0x6e, +0x6f, 0x3b, 0x4c, 0x77, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x61, 0x67, 0x61, 0x3b, 0x53, 0x3b, 0x42, 0x3b, 0x4c, 0x3b, 0x4c, +0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x50, 0x61, 0x20, 0x4d, 0x75, 0x6c, 0x75, 0x6e, 0x67, 0x75, 0x3b, 0x50, 0x61, +0x6c, 0x69, 0x63, 0x68, 0x69, 0x6d, 0x6f, 0x3b, 0x50, 0x61, 0x6c, 0x69, 0x63, 0x68, 0x69, 0x62, 0x75, 0x6c, 0x69, 0x3b, +0x50, 0x61, 0x6c, 0x69, 0x63, 0x68, 0x69, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x50, 0x61, 0x6c, 0x69, 0x63, 0x68, 0x69, 0x6e, +0x65, 0x3b, 0x50, 0x61, 0x6c, 0x69, 0x63, 0x68, 0x69, 0x73, 0x61, 0x6e, 0x6f, 0x3b, 0x50, 0x61, 0x63, 0x68, 0x69, 0x62, +0x65, 0x6c, 0x75, 0x73, 0x68, 0x69, 0x3b, 0x64, 0x75, 0x6d, 0x3b, 0x73, 0x69, 0x67, 0x3b, 0x74, 0x65, 0x72, 0x3b, 0x6b, +0x75, 0x61, 0x3b, 0x6b, 0x69, 0x6e, 0x3b, 0x73, 0x65, 0x73, 0x3b, 0x73, 0x61, 0x62, 0x3b, 0x64, 0x75, 0x6d, 0x69, 0x6e, +0x67, 0x75, 0x3b, 0x73, 0x69, 0x67, 0x75, 0x6e, 0x64, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x74, 0x65, 0x72, 0x73, +0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x6b, 0x75, 0x61, 0x72, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x6b, +0x69, 0x6e, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x73, 0x65, 0x73, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, +0x3b, 0x73, 0xe1, 0x62, 0x61, 0x64, 0x75, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x53, 0x3b, +0x53, 0x3b, 0x64, 0x75, 0x6d, 0x69, 0x6e, 0x67, 0x75, 0x3b, 0x73, 0x69, 0x67, 0x75, 0x6e, 0x64, 0x61, 0x2d, 0x66, 0x65, +0x72, 0x61, 0x3b, 0x74, 0x65, 0x72, 0x73, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x6b, 0x75, 0x61, 0x72, 0x74, 0x61, +0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x6b, 0x69, 0x6e, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x73, 0x65, 0x73, +0x74, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x73, 0x61, 0x62, 0x61, 0x64, 0x75, 0x3b, 0x4b, 0x49, 0x55, 0x3b, 0x4d, +0x52, 0x41, 0x3b, 0x57, 0x41, 0x49, 0x3b, 0x57, 0x45, 0x54, 0x3b, 0x57, 0x45, 0x4e, 0x3b, 0x57, 0x54, 0x4e, 0x3b, 0x4a, +0x55, 0x4d, 0x3b, 0x4b, 0x69, 0x75, 0x6d, 0x69, 0x61, 0x3b, 0x4d, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b, 0x6f, 0x3b, 0x57, +0x61, 0x69, 0x72, 0x69, 0x3b, 0x57, 0x65, 0x74, 0x68, 0x61, 0x74, 0x75, 0x3b, 0x57, 0x65, 0x6e, 0x61, 0x3b, 0x57, 0x65, +0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x57, 0x3b, +0x57, 0x3b, 0x57, 0x3b, 0x57, 0x3b, 0x4a, 0x3b, 0x4b, 0x74, 0x73, 0x3b, 0x4b, 0x6f, 0x74, 0x3b, 0x4b, 0x6f, 0x6f, 0x3b, +0x4b, 0x6f, 0x73, 0x3b, 0x4b, 0x6f, 0x61, 0x3b, 0x4b, 0x6f, 0x6d, 0x3b, 0x4b, 0x6f, 0x6c, 0x3b, 0x4b, 0x6f, 0x74, 0x69, +0x73, 0x61, 0x70, 0x3b, 0x4b, 0x6f, 0x74, 0x61, 0x61, 0x69, 0x3b, 0x4b, 0x6f, 0x61, 0x65, 0x6e, 0x67, 0x2019, 0x3b, 0x4b, +0x6f, 0x73, 0x6f, 0x6d, 0x6f, 0x6b, 0x3b, 0x4b, 0x6f, 0x61, 0x6e, 0x67, 0x2019, 0x77, 0x61, 0x6e, 0x3b, 0x4b, 0x6f, 0x6d, +0x75, 0x75, 0x74, 0x3b, 0x4b, 0x6f, 0x6c, 0x6f, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4f, 0x3b, 0x53, 0x3b, 0x41, 0x3b, 0x4d, +0x3b, 0x4c, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0x61, 0x3b, 0x44, 0x65, 0x3b, 0x57, 0x75, 0x3b, 0x44, 0x6f, 0x3b, 0x46, +0x72, 0x3b, 0x53, 0x61, 0x74, 0x3b, 0x53, 0x6f, 0x6e, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x4d, 0x61, +0x6e, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x44, 0x65, 0x6e, 0x73, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, +0x65, 0x73, 0x3b, 0x57, 0x75, 0x6e, 0x73, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x44, 0x6f, 0x6e, 0x64, +0x65, 0x72, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x46, 0x72, 0x61, 0x69, 0x74, 0x61, 0x78, 0x74, 0x73, +0x65, 0x65, 0x73, 0x3b, 0x53, 0x61, 0x74, 0x65, 0x72, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x53, 0x3b, +0x4d, 0x3b, 0x45, 0x3b, 0x57, 0x3b, 0x44, 0x3b, 0x46, 0x3b, 0x41, 0x3b, 0x53, 0x75, 0x2e, 0x3b, 0x4d, 0x6f, 0x2e, 0x3b, +0x44, 0x69, 0x2e, 0x3b, 0x4d, 0x65, 0x2e, 0x3b, 0x44, 0x75, 0x2e, 0x3b, 0x46, 0x72, 0x2e, 0x3b, 0x53, 0x61, 0x2e, 0x3b, +0x53, 0x75, 0x6e, 0x6e, 0x64, 0x61, 0x61, 0x63, 0x68, 0x3b, 0x4d, 0x6f, 0x68, 0x6e, 0x64, 0x61, 0x61, 0x63, 0x68, 0x3b, +0x44, 0x69, 0x6e, 0x6e, 0x73, 0x64, 0x61, 0x61, 0x63, 0x68, 0x3b, 0x4d, 0x65, 0x74, 0x77, 0x6f, 0x63, 0x68, 0x3b, 0x44, +0x75, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x64, 0x61, 0x61, 0x63, 0x68, 0x3b, 0x46, 0x72, 0x69, 0x69, 0x64, 0x61, 0x61, 0x63, +0x68, 0x3b, 0x53, 0x61, 0x6d, 0x73, 0x64, 0x61, 0x61, 0x63, 0x68, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0xed, 0x6c, 0xed, +0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0xe1, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, +0x61, 0x74, 0xe1, 0x6e, 0x254, 0x3b, 0x41, 0x6c, 0x61, 0xe1, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0xe1, 0x61, +0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0xf3, 0x73, 0x69, 0x3b, 0x53, 0x61, 0x62, 0x69, 0x3b, 0x42, 0x61, 0x6c, 0x61, 0x3b, +0x4b, 0x75, 0x62, 0x69, 0x3b, 0x4b, 0x75, 0x73, 0x61, 0x3b, 0x4b, 0x75, 0x6e, 0x61, 0x3b, 0x4b, 0x75, 0x74, 0x61, 0x3b, +0x4d, 0x75, 0x6b, 0x61, 0x3b, 0x53, 0x61, 0x62, 0x69, 0x69, 0x74, 0x69, 0x3b, 0x42, 0x61, 0x6c, 0x61, 0x7a, 0x61, 0x3b, +0x4f, 0x77, 0x6f, 0x6b, 0x75, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x4f, 0x77, 0x6f, 0x6b, 0x75, 0x73, 0x61, 0x74, 0x75, 0x3b, +0x4f, 0x6c, 0x6f, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x4f, 0x6c, 0x6f, 0x6b, 0x75, 0x74, 0x61, 0x61, 0x6e, 0x75, 0x3b, 0x4f, +0x6c, 0x6f, 0x6d, 0x75, 0x6b, 0x61, 0x61, 0x67, 0x61, 0x3b, 0x53, 0x3b, 0x42, 0x3b, 0x42, 0x3b, 0x53, 0x3b, 0x4b, 0x3b, +0x4b, 0x3b, 0x4d, 0x3b, 0x4a, 0x32, 0x3b, 0x4a, 0x33, 0x3b, 0x4a, 0x34, 0x3b, 0x4a, 0x35, 0x3b, 0x41, 0x6c, 0x3b, 0x49, +0x6a, 0x3b, 0x4a, 0x31, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x72, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, +0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, +0x4d, 0x75, 0x72, 0x77, 0x61, 0x20, 0x77, 0x61, 0x20, 0x4b, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4d, 0x75, 0x72, 0x77, 0x61, +0x20, 0x77, 0x61, 0x20, 0x4b, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, +0x4a, 0x70, 0x69, 0x3b, 0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6e, 0x6e, 0x3b, 0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, 0x3b, +0x49, 0x6a, 0x6d, 0x3b, 0x4a, 0x6d, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x42, 0x61, 0x72, 0x3b, 0x41, 0x61, 0x72, 0x3b, +0x55, 0x6e, 0x69, 0x3b, 0x55, 0x6e, 0x67, 0x3b, 0x4b, 0x61, 0x6e, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4e, 0x61, 0x6b, 0x61, +0x65, 0x6a, 0x75, 0x6d, 0x61, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x65, 0x62, 0x61, 0x72, 0x61, 0x73, 0x61, 0x3b, 0x4e, 0x61, +0x6b, 0x61, 0x61, 0x72, 0x65, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x75, 0x6e, 0x69, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x75, 0x6e, +0x67, 0x2019, 0x6f, 0x6e, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x6b, 0x61, 0x6e, 0x79, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x73, 0x61, +0x62, 0x69, 0x74, 0x69, 0x3b, 0x4a, 0x3b, 0x42, 0x3b, 0x41, 0x3b, 0x55, 0x3b, 0x55, 0x3b, 0x4b, 0x3b, 0x53, 0x3b, 0x41, +0x6c, 0x68, 0x3b, 0x41, 0x74, 0x69, 0x3b, 0x41, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x3b, 0x41, 0x6c, 0x6d, 0x3b, 0x41, +0x6c, 0x6a, 0x3b, 0x41, 0x73, 0x73, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x64, 0x69, 0x3b, 0x41, 0x74, 0x69, 0x6e, 0x69, 0x3b, +0x41, 0x74, 0x61, 0x6c, 0x61, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x72, 0x62, 0x61, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, +0x69, 0x69, 0x73, 0x61, 0x3b, 0x41, 0x6c, 0x6a, 0x75, 0x6d, 0x61, 0x3b, 0x41, 0x73, 0x73, 0x61, 0x62, 0x64, 0x75, 0x3b, +0x48, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x53, 0x3b, 0x4a, 0x4d, 0x50, 0x3b, 0x57, 0x55, +0x54, 0x3b, 0x54, 0x41, 0x52, 0x3b, 0x54, 0x41, 0x44, 0x3b, 0x54, 0x41, 0x4e, 0x3b, 0x54, 0x41, 0x42, 0x3b, 0x4e, 0x47, +0x53, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x6c, 0x3b, 0x57, 0x75, 0x6f, 0x6b, 0x20, 0x54, 0x69, 0x63, 0x68, 0x3b, +0x54, 0x69, 0x63, 0x68, 0x20, 0x41, 0x72, 0x69, 0x79, 0x6f, 0x3b, 0x54, 0x69, 0x63, 0x68, 0x20, 0x41, 0x64, 0x65, 0x6b, +0x3b, 0x54, 0x69, 0x63, 0x68, 0x20, 0x41, 0x6e, 0x67, 0x2019, 0x77, 0x65, 0x6e, 0x3b, 0x54, 0x69, 0x63, 0x68, 0x20, 0x41, +0x62, 0x69, 0x63, 0x68, 0x3b, 0x4e, 0x67, 0x65, 0x73, 0x6f, 0x3b, 0x4a, 0x3b, 0x57, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x54, +0x3b, 0x54, 0x3b, 0x4e, 0x3b, 0x41, 0x73, 0x61, 0x3b, 0x41, 0x79, 0x6e, 0x3b, 0x41, 0x73, 0x6e, 0x3b, 0x41, 0x6b, 0x72, +0x3b, 0x41, 0x6b, 0x77, 0x3b, 0x41, 0x73, 0x6d, 0x3b, 0x41, 0x73, 0x1e0d, 0x3b, 0x41, 0x73, 0x61, 0x6d, 0x61, 0x73, 0x3b, +0x41, 0x79, 0x6e, 0x61, 0x73, 0x3b, 0x41, 0x73, 0x69, 0x6e, 0x61, 0x73, 0x3b, 0x41, 0x6b, 0x72, 0x61, 0x73, 0x3b, 0x41, +0x6b, 0x77, 0x61, 0x73, 0x3b, 0x41, 0x73, 0x69, 0x6d, 0x77, 0x61, 0x73, 0x3b, 0x41, 0x73, 0x69, 0x1e0d, 0x79, 0x61, 0x73, +0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x41, +0x74, 0x69, 0x3b, 0x41, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x3b, 0x41, 0x6c, 0x6d, 0x3b, 0x41, 0x6c, 0x7a, 0x3b, 0x41, +0x73, 0x69, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x64, 0x69, 0x3b, 0x41, 0x74, 0x69, 0x6e, 0x6e, 0x69, 0x3b, 0x41, 0x74, 0x61, +0x6c, 0x61, 0x61, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x72, 0x62, 0x61, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x69, +0x73, 0x61, 0x3b, 0x41, 0x6c, 0x7a, 0x75, 0x6d, 0x61, 0x3b, 0x41, 0x73, 0x69, 0x62, 0x74, 0x69, 0x3b, 0x4a, 0x70, 0x69, +0x3b, 0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6d, 0x6e, 0x3b, 0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x75, +0x3b, 0x4a, 0x6d, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x61, 0x70, 0x69, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x61, 0x74, +0x61, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x61, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x61, 0x74, 0x61, 0x6e, +0x6f, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4a, 0x75, +0x6d, 0x61, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x32, 0x3b, 0x33, 0x3b, 0x34, 0x3b, 0x35, 0x3b, 0x41, 0x3b, 0x49, 0x3b, +0x31, 0x3b, 0x930, 0x92c, 0x93f, 0x3b, 0x938, 0x92e, 0x3b, 0x92e, 0x902, 0x917, 0x932, 0x3b, 0x92c, 0x941, 0x926, 0x3b, 0x92c, 0x93f, +0x938, 0x925, 0x93f, 0x3b, 0x938, 0x941, 0x916, 0x941, 0x930, 0x3b, 0x938, 0x941, 0x928, 0x93f, 0x3b, 0x930, 0x92c, 0x93f, 0x92c, 0x93e, +0x930, 0x3b, 0x938, 0x92e, 0x92c, 0x93e, 0x930, 0x3b, 0x92e, 0x902, 0x917, 0x932, 0x92c, 0x93e, 0x930, 0x3b, 0x92c, 0x941, 0x926, 0x92c, +0x93e, 0x930, 0x3b, 0x92c, 0x93f, 0x938, 0x925, 0x93f, 0x92c, 0x93e, 0x930, 0x3b, 0x938, 0x941, 0x916, 0x941, 0x930, 0x92c, 0x93e, 0x930, +0x3b, 0x938, 0x941, 0x928, 0x93f, 0x92c, 0x93e, 0x930, 0x3b, 0x930, 0x3b, 0x938, 0x3b, 0x92e, 0x902, 0x3b, 0x92c, 0x941, 0x3b, 0x92c, +0x93f, 0x3b, 0x938, 0x941, 0x3b, 0x938, 0x941, 0x3b, 0x43a, 0x4c0, 0x438, 0x3b, 0x43e, 0x440, 0x3b, 0x448, 0x438, 0x3b, 0x43a, 0x445, +0x430, 0x3b, 0x435, 0x430, 0x3b, 0x43f, 0x4c0, 0x435, 0x3b, 0x448, 0x443, 0x43e, 0x3b, 0x43a, 0x4c0, 0x438, 0x440, 0x430, 0x3b, 0x43e, +0x440, 0x448, 0x43e, 0x442, 0x3b, 0x448, 0x438, 0x43d, 0x430, 0x440, 0x430, 0x3b, 0x43a, 0x445, 0x430, 0x430, 0x440, 0x430, 0x3b, 0x435, +0x430, 0x440, 0x430, 0x3b, 0x43f, 0x4c0, 0x435, 0x440, 0x430, 0x441, 0x43a, 0x430, 0x3b, 0x448, 0x443, 0x43e, 0x442, 0x3b, 0x43a, 0x4c0, +0x3b, 0x43e, 0x3b, 0x448, 0x3b, 0x43a, 0x445, 0x3b, 0x435, 0x3b, 0x43f, 0x4c0, 0x3b, 0x448, 0x3b, 0x43d, 0x434, 0x2de7, 0x487, 0x467, +0x3b, 0x43f, 0x43d, 0x2de3, 0x435, 0x3b, 0x432, 0x442, 0x43e, 0x2dec, 0x487, 0x3b, 0x441, 0x440, 0x2de3, 0x435, 0x3b, 0x447, 0x435, 0x2de6, +0x487, 0x3b, 0x43f, 0x467, 0x2de6, 0x487, 0x3b, 0x441, 0xa64b, 0x2de0, 0x487, 0x3b, 0x43d, 0x435, 0x434, 0x463, 0x301, 0x43b, 0x467, 0x3b, +0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x463, 0x301, 0x43b, 0x44c, 0x43d, 0x438, 0x43a, 0x44a, 0x3b, 0x432, 0x442, 0x43e, 0x301, 0x440, 0x43d, +0x438, 0x43a, 0x44a, 0x3b, 0x441, 0x440, 0x435, 0x434, 0x430, 0x300, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x435, 0x440, 0x442, 0x43e, 0x301, +0x43a, 0x44a, 0x3b, 0x43f, 0x467, 0x442, 0x43e, 0x301, 0x43a, 0x44a, 0x3b, 0x441, 0xa64b, 0x431, 0x431, 0x461, 0x301, 0x442, 0x430, 0x3b, +0x4c, 0x75, 0x6d, 0x3b, 0x4e, 0x6b, 0x6f, 0x3b, 0x4e, 0x64, 0x79, 0x3b, 0x4e, 0x64, 0x67, 0x3b, 0x4e, 0x6a, 0x77, 0x3b, +0x4e, 0x67, 0x76, 0x3b, 0x4c, 0x75, 0x62, 0x3b, 0x4c, 0x75, 0x6d, 0x69, 0x6e, 0x67, 0x75, 0x3b, 0x4e, 0x6b, 0x6f, 0x64, +0x79, 0x61, 0x3b, 0x4e, 0x64, 0xe0, 0x61, 0x79, 0xe0, 0x3b, 0x4e, 0x64, 0x61, 0x6e, 0x67, 0xf9, 0x3b, 0x4e, 0x6a, 0xf2, +0x77, 0x61, 0x3b, 0x4e, 0x67, 0xf2, 0x76, 0x79, 0x61, 0x3b, 0x4c, 0x75, 0x62, 0x69, 0x6e, 0x67, 0x75, 0x3b, 0x4c, 0x3b, +0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4c, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0xe9, 0x69, 0x3b, +0x44, 0xeb, 0x6e, 0x3b, 0x4d, 0xeb, 0x74, 0x3b, 0x44, 0x6f, 0x6e, 0x3b, 0x46, 0x72, 0x65, 0x3b, 0x53, 0x61, 0x6d, 0x3b, +0x53, 0x6f, 0x6e, 0x6e, 0x64, 0x65, 0x67, 0x3b, 0x4d, 0xe9, 0x69, 0x6e, 0x64, 0x65, 0x67, 0x3b, 0x44, 0xeb, 0x6e, 0x73, +0x63, 0x68, 0x64, 0x65, 0x67, 0x3b, 0x4d, 0xeb, 0x74, 0x74, 0x77, 0x6f, 0x63, 0x68, 0x3b, 0x44, 0x6f, 0x6e, 0x6e, 0x65, +0x73, 0x63, 0x68, 0x64, 0x65, 0x67, 0x3b, 0x46, 0x72, 0x65, 0x69, 0x64, 0x65, 0x67, 0x3b, 0x53, 0x61, 0x6d, 0x73, 0x63, +0x68, 0x64, 0x65, 0x67, 0x3b, 0x53, 0x6f, 0x6e, 0x2e, 0x3b, 0x4d, 0xe9, 0x69, 0x2e, 0x3b, 0x44, 0xeb, 0x6e, 0x2e, 0x3b, +0x4d, 0xeb, 0x74, 0x2e, 0x3b, 0x44, 0x6f, 0x6e, 0x2e, 0x3b, 0x46, 0x72, 0x65, 0x2e, 0x3b, 0x53, 0x61, 0x6d, 0x2e, 0x3b, +0x6e, 0x74, 0x73, 0x3b, 0x6b, 0x70, 0x61, 0x3b, 0x67, 0x68, 0x254, 0x3b, 0x74, 0x254, 0x6d, 0x3b, 0x75, 0x6d, 0x65, 0x3b, +0x67, 0x68, 0x268, 0x3b, 0x64, 0x7a, 0x6b, 0x3b, 0x74, 0x73, 0x75, 0x294, 0x6e, 0x74, 0x73, 0x268, 0x3b, 0x74, 0x73, 0x75, +0x294, 0x75, 0x6b, 0x70, 0xe0, 0x3b, 0x74, 0x73, 0x75, 0x294, 0x75, 0x67, 0x68, 0x254, 0x65, 0x3b, 0x74, 0x73, 0x75, 0x294, +0x75, 0x74, 0x254, 0x300, 0x6d, 0x6c, 0xf2, 0x3b, 0x74, 0x73, 0x75, 0x294, 0x75, 0x6d, 0xe8, 0x3b, 0x74, 0x73, 0x75, 0x294, +0x75, 0x67, 0x68, 0x268, 0x302, 0x6d, 0x3b, 0x74, 0x73, 0x75, 0x294, 0x6e, 0x64, 0x7a, 0x268, 0x6b, 0x254, 0x294, 0x254, 0x3b, +0x6e, 0x3b, 0x6b, 0x3b, 0x67, 0x3b, 0x74, 0x3b, 0x75, 0x3b, 0x67, 0x3b, 0x64, 0x3b, 0x6e, 0x254, 0x79, 0x3b, 0x6e, 0x6a, +0x61, 0x3b, 0x75, 0x75, 0x6d, 0x3b, 0x14b, 0x67, 0x65, 0x3b, 0x6d, 0x62, 0x254, 0x3b, 0x6b, 0x254, 0x254, 0x3b, 0x6a, 0x6f, +0x6e, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0x6e, 0x254, 0x302, 0x79, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0x6e, 0x6a, 0x61, +0x14b, 0x67, 0x75, 0x6d, 0x62, 0x61, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0xfb, 0x6d, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, +0x14b, 0x67, 0xea, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0x6d, 0x62, 0x254, 0x6b, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0x6b, +0x254, 0x254, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0x6a, 0xf4, 0x6e, 0x3b, 0x6e, 0x3b, 0x6e, 0x3b, 0x75, 0x3b, 0x14b, 0x3b, +0x6d, 0x3b, 0x6b, 0x3b, 0x6a, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x64, 0x69, 0x3b, 0x41, 0x74, 0x69, 0x6e, 0x6e, 0x69, 0x3b, +0x41, 0x74, 0x61, 0x6c, 0x61, 0x61, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x72, 0x62, 0x61, 0x3b, 0x41, 0x6c, 0x68, 0x61, +0x6d, 0x69, 0x73, 0x69, 0x3b, 0x41, 0x6c, 0x7a, 0x75, 0x6d, 0x61, 0x3b, 0x41, 0x73, 0x69, 0x62, 0x74, 0x69, 0x3b, 0x48, +0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x5a, 0x3b, 0x53, 0x3b, 0xe9, 0x74, 0x3b, 0x6d, 0x254, 0x301, 0x73, +0x3b, 0x6b, 0x77, 0x61, 0x3b, 0x6d, 0x75, 0x6b, 0x3b, 0x14b, 0x67, 0x69, 0x3b, 0x257, 0xf3, 0x6e, 0x3b, 0x65, 0x73, 0x61, +0x3b, 0xe9, 0x74, 0x69, 0x3b, 0x6d, 0x254, 0x301, 0x73, 0xfa, 0x3b, 0x6b, 0x77, 0x61, 0x73, 0xfa, 0x3b, 0x6d, 0x75, 0x6b, +0x254, 0x301, 0x73, 0xfa, 0x3b, 0x14b, 0x67, 0x69, 0x73, 0xfa, 0x3b, 0x257, 0xf3, 0x6e, 0x25b, 0x73, 0xfa, 0x3b, 0x65, 0x73, +0x61, 0x253, 0x61, 0x73, 0xfa, 0x3b, 0x65, 0x3b, 0x6d, 0x3b, 0x6b, 0x3b, 0x6d, 0x3b, 0x14b, 0x3b, 0x257, 0x3b, 0x65, 0x3b, +0x44, 0x69, 0x6d, 0x3b, 0x54, 0x65, 0x6e, 0x3b, 0x54, 0x61, 0x6c, 0x3b, 0x41, 0x6c, 0x61, 0x3b, 0x41, 0x72, 0x61, 0x3b, +0x41, 0x72, 0x6a, 0x3b, 0x53, 0x69, 0x62, 0x3b, 0x44, 0x69, 0x6d, 0x61, 0x73, 0x3b, 0x54, 0x65, 0x6e, 0x65, 0x14b, 0x3b, +0x54, 0x61, 0x6c, 0x61, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x72, 0x62, 0x61, 0x79, 0x3b, 0x41, 0x72, 0x61, 0x6d, 0x69, +0x73, 0x61, 0x79, 0x3b, 0x41, 0x72, 0x6a, 0x75, 0x6d, 0x61, 0x3b, 0x53, 0x69, 0x62, 0x69, 0x74, 0x69, 0x3b, 0x44, 0x3b, +0x54, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x3b, 0x6d, 0x254, 0x301, +0x6e, 0x3b, 0x73, 0x6d, 0x62, 0x3b, 0x73, 0x6d, 0x6c, 0x3b, 0x73, 0x6d, 0x6e, 0x3b, 0x66, 0xfa, 0x6c, 0x3b, 0x73, 0xe9, +0x72, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x3b, 0x6d, 0x254, 0x301, 0x6e, 0x64, 0x69, 0x3b, 0x73, 0x254, 0x301, 0x6e, +0x64, 0x254, 0x20, 0x6d, 0x259, 0x6c, 0xfa, 0x20, 0x6d, 0x259, 0x301, 0x62, 0x25b, 0x30c, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, +0x254, 0x20, 0x6d, 0x259, 0x6c, 0xfa, 0x20, 0x6d, 0x259, 0x301, 0x6c, 0x25b, 0x301, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, +0x20, 0x6d, 0x259, 0x6c, 0xfa, 0x20, 0x6d, 0x259, 0x301, 0x6e, 0x79, 0x69, 0x3b, 0x66, 0xfa, 0x6c, 0x61, 0x64, 0xe9, 0x3b, +0x73, 0xe9, 0x72, 0x61, 0x64, 0xe9, 0x3b, 0x73, 0x3b, 0x6d, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x66, 0x3b, 0x73, +0x3b, 0x73, 0x254, 0x301, 0x6e, 0x3b, 0x6c, 0x1dd, 0x6e, 0x3b, 0x6d, 0x61, 0x61, 0x3b, 0x6d, 0x25b, 0x6b, 0x3b, 0x6a, 0x1dd, +0x1dd, 0x3b, 0x6a, 0xfa, 0x6d, 0x3b, 0x73, 0x61, 0x6d, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x1dd, 0x3b, 0x6c, 0x1dd, 0x6e, +0x64, 0xed, 0x3b, 0x6d, 0x61, 0x61, 0x64, 0xed, 0x3b, 0x6d, 0x25b, 0x6b, 0x72, 0x25b, 0x64, 0xed, 0x3b, 0x6a, 0x1dd, 0x1dd, +0x64, 0xed, 0x3b, 0x6a, 0xfa, 0x6d, 0x62, 0xe1, 0x3b, 0x73, 0x61, 0x6d, 0x64, 0xed, 0x3b, 0x73, 0x3b, 0x6c, 0x3b, 0x6d, +0x3b, 0x6d, 0x3b, 0x6a, 0x3b, 0x6a, 0x3b, 0x73, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6e, 0x6e, +0x3b, 0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x72, 0x61, 0x3b, 0x49, 0x6a, 0x75, 0x3b, 0x4a, 0x6d, 0x6f, 0x3b, 0x53, 0x61, 0x62, +0x61, 0x74, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e, 0x6e, 0x65, +0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x72, 0x61, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, +0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x53, 0x3b, 0x4a, 0x3b, +0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x4a, 0x3b, 0x43, 0x79, 0x61, 0x3b, 0x43, 0x6c, 0x61, 0x3b, 0x43, 0x7a, +0x69, 0x3b, 0x43, 0x6b, 0x6f, 0x3b, 0x43, 0x6b, 0x61, 0x3b, 0x43, 0x67, 0x61, 0x3b, 0x43, 0x7a, 0x65, 0x3b, 0x43, 0x6f, +0x6d, 0x2019, 0x79, 0x61, 0x6b, 0x6b, 0x65, 0x3b, 0x43, 0x6f, 0x6d, 0x6c, 0x61, 0x61, 0x257, 0x69, 0x69, 0x3b, 0x43, 0x6f, +0x6d, 0x7a, 0x79, 0x69, 0x69, 0x257, 0x69, 0x69, 0x3b, 0x43, 0x6f, 0x6d, 0x6b, 0x6f, 0x6c, 0x6c, 0x65, 0x3b, 0x43, 0x6f, +0x6d, 0x6b, 0x61, 0x6c, 0x64, 0x1dd, 0x253, 0x6c, 0x69, 0x69, 0x3b, 0x43, 0x6f, 0x6d, 0x67, 0x61, 0x69, 0x73, 0x75, 0x75, +0x3b, 0x43, 0x6f, 0x6d, 0x7a, 0x79, 0x65, 0x253, 0x73, 0x75, 0x75, 0x3b, 0x59, 0x3b, 0x4c, 0x3b, 0x5a, 0x3b, 0x4f, 0x3b, +0x41, 0x3b, 0x47, 0x3b, 0x45, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x3b, 0x6d, 0x254, 0x301, 0x6e, 0x3b, 0x73, 0x6d, 0x62, 0x3b, +0x73, 0x6d, 0x6c, 0x3b, 0x73, 0x6d, 0x6e, 0x3b, 0x6d, 0x62, 0x73, 0x3b, 0x73, 0x61, 0x73, 0x3b, 0x73, 0x254, 0x301, 0x6e, +0x64, 0x254, 0x3b, 0x6d, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x20, 0x6d, 0x61, 0x66, +0xfa, 0x20, 0x6d, 0xe1, 0x62, 0x61, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x20, 0x6d, 0x61, 0x66, 0xfa, 0x20, 0x6d, +0xe1, 0x6c, 0x61, 0x6c, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x20, 0x6d, 0x61, 0x66, 0xfa, 0x20, 0x6d, 0xe1, 0x6e, +0x61, 0x3b, 0x6d, 0x61, 0x62, 0xe1, 0x67, 0xe1, 0x20, 0x6d, 0xe1, 0x20, 0x73, 0x75, 0x6b, 0x75, 0x6c, 0x3b, 0x73, 0xe1, +0x73, 0x61, 0x64, 0x69, 0x3b, 0x73, 0x3b, 0x6d, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x6d, 0x3b, 0x73, 0x3b, 0x43, +0xe4, 0x14b, 0x3b, 0x4a, 0x69, 0x65, 0x63, 0x3b, 0x52, 0x25b, 0x77, 0x3b, 0x44, 0x69, 0x254, 0x331, 0x6b, 0x3b, 0x14a, 0x75, +0x61, 0x61, 0x6e, 0x3b, 0x44, 0x68, 0x69, 0x65, 0x65, 0x63, 0x3b, 0x42, 0xe4, 0x6b, 0x25b, 0x6c, 0x3b, 0x43, 0xe4, 0x14b, +0x20, 0x6b, 0x75, 0x254, 0x74, 0x68, 0x3b, 0x4a, 0x69, 0x65, 0x63, 0x20, 0x6c, 0x61, 0x331, 0x74, 0x3b, 0x52, 0x25b, 0x77, +0x20, 0x6c, 0xe4, 0x74, 0x6e, 0x69, 0x3b, 0x44, 0x69, 0x254, 0x331, 0x6b, 0x20, 0x6c, 0xe4, 0x74, 0x6e, 0x69, 0x3b, 0x14a, +0x75, 0x61, 0x61, 0x6e, 0x20, 0x6c, 0xe4, 0x74, 0x6e, 0x69, 0x3b, 0x44, 0x68, 0x69, 0x65, 0x65, 0x63, 0x20, 0x6c, 0xe4, +0x74, 0x6e, 0x69, 0x3b, 0x42, 0xe4, 0x6b, 0x25b, 0x6c, 0x20, 0x6c, 0xe4, 0x74, 0x6e, 0x69, 0x3b, 0x43, 0x3b, 0x4a, 0x3b, +0x52, 0x3b, 0x44, 0x3b, 0x14a, 0x3b, 0x44, 0x3b, 0x42, 0x3b, 0x431, 0x441, 0x3b, 0x431, 0x43d, 0x3b, 0x43e, 0x43f, 0x3b, 0x441, +0x44d, 0x3b, 0x447, 0x43f, 0x3b, 0x431, 0x44d, 0x3b, 0x441, 0x431, 0x3b, 0x431, 0x430, 0x441, 0x43a, 0x44b, 0x4bb, 0x44b, 0x430, 0x43d, +0x43d, 0x44c, 0x430, 0x3b, 0x431, 0x44d, 0x43d, 0x438, 0x434, 0x438, 0x44d, 0x43d, 0x43d, 0x44c, 0x438, 0x43a, 0x3b, 0x43e, 0x43f, 0x442, +0x443, 0x43e, 0x440, 0x443, 0x43d, 0x43d, 0x44c, 0x443, 0x43a, 0x3b, 0x441, 0x44d, 0x440, 0x44d, 0x434, 0x44d, 0x3b, 0x447, 0x44d, 0x43f, +0x43f, 0x438, 0x44d, 0x440, 0x3b, 0x411, 0x44d, 0x44d, 0x442, 0x438, 0x4a5, 0x441, 0x44d, 0x3b, 0x441, 0x443, 0x431, 0x443, 0x43e, 0x442, +0x430, 0x3b, 0x411, 0x3b, 0x411, 0x3b, 0x41e, 0x3b, 0x421, 0x3b, 0x427, 0x3b, 0x411, 0x3b, 0x421, 0x3b, 0x4d, 0x75, 0x6c, 0x3b, +0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6e, 0x6e, 0x3b, 0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x75, 0x3b, +0x4a, 0x6d, 0x6f, 0x3b, 0x4d, 0x75, 0x6c, 0x75, 0x6e, 0x67, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x75, +0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x6c, +0x61, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, +0x6f, 0x73, 0x69, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x4a, 0x3b, 0xa55e, 0xa54c, +0xa535, 0x3b, 0xa5f3, 0xa5e1, 0xa609, 0x3b, 0xa55a, 0xa55e, 0xa55a, 0x3b, 0xa549, 0xa55e, 0xa552, 0x3b, 0xa549, 0xa524, 0xa546, 0xa562, 0x3b, 0xa549, +0xa524, 0xa540, 0xa56e, 0x3b, 0xa53b, 0xa52c, 0xa533, 0x3b, 0x6c, 0x61, 0x68, 0x61, 0x64, 0x69, 0x3b, 0x74, 0x25b, 0x25b, 0x6e, 0x25b, +0x25b, 0x3b, 0x74, 0x61, 0x6c, 0x61, 0x74, 0x61, 0x3b, 0x61, 0x6c, 0x61, 0x62, 0x61, 0x3b, 0x61, 0x69, 0x6d, 0x69, 0x73, +0x61, 0x3b, 0x61, 0x69, 0x6a, 0x69, 0x6d, 0x61, 0x3b, 0x73, 0x69, 0x253, 0x69, 0x74, 0x69, 0x3b, 0x53, 0x75, 0x6e, 0x3b, +0x4d, 0xe4, 0x6e, 0x3b, 0x5a, 0x69, 0x161, 0x3b, 0x4d, 0x69, 0x74, 0x3b, 0x46, 0x72, 0xf3, 0x3b, 0x46, 0x72, 0x69, 0x3b, +0x53, 0x61, 0x6d, 0x3b, 0x53, 0x75, 0x6e, 0x6e, 0x74, 0x61, 0x67, 0x3b, 0x4d, 0xe4, 0x6e, 0x74, 0x61, 0x67, 0x3b, 0x5a, +0x69, 0x161, 0x74, 0x61, 0x67, 0x3b, 0x4d, 0x69, 0x74, 0x74, 0x77, 0x75, 0x10d, 0x3b, 0x46, 0x72, 0xf3, 0x6e, 0x74, 0x61, +0x67, 0x3b, 0x46, 0x72, 0x69, 0x74, 0x61, 0x67, 0x3b, 0x53, 0x61, 0x6d, 0x161, 0x74, 0x61, 0x67, 0x3b, 0x53, 0x3b, 0x4d, +0x3b, 0x5a, 0x3b, 0x4d, 0x3b, 0x46, 0x3b, 0x46, 0x3b, 0x53, 0x3b, 0x73, 0x64, 0x3b, 0x6d, 0x64, 0x3b, 0x6d, 0x77, 0x3b, +0x65, 0x74, 0x3b, 0x6b, 0x6c, 0x3b, 0x66, 0x6c, 0x3b, 0x73, 0x73, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x69, 0x25b, 0x3b, +0x6d, 0xf3, 0x6e, 0x64, 0x69, 0x65, 0x3b, 0x6d, 0x75, 0xe1, 0x6e, 0x79, 0xe1, 0x14b, 0x6d, 0xf3, 0x6e, 0x64, 0x69, 0x65, +0x3b, 0x6d, 0x65, 0x74, 0xfa, 0x6b, 0x70, 0xed, 0xe1, 0x70, 0x25b, 0x3b, 0x6b, 0xfa, 0x70, 0xe9, 0x6c, 0x69, 0x6d, 0x65, +0x74, 0xfa, 0x6b, 0x70, 0x69, 0x61, 0x70, 0x25b, 0x3b, 0x66, 0x65, 0x6c, 0xe9, 0x74, 0x65, 0x3b, 0x73, 0xe9, 0x73, 0x65, +0x6c, 0xe9, 0x3b, 0x73, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x65, 0x3b, 0x6b, 0x3b, 0x66, 0x3b, 0x73, 0x3b, 0x64, 0x6f, 0x6d, +0x3b, 0x6c, 0x6c, 0x75, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0x69, 0xe9, 0x3b, 0x78, 0x75, 0x65, 0x3b, 0x76, 0x69, 0x65, +0x3b, 0x73, 0xe1, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x75, 0x3b, 0x6c, 0x6c, 0x75, 0x6e, 0x65, 0x73, 0x3b, +0x6d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x3b, 0x6d, 0x69, 0xe9, 0x72, 0x63, 0x6f, 0x6c, 0x65, 0x73, 0x3b, 0x78, 0x75, 0x65, +0x76, 0x65, 0x73, 0x3b, 0x76, 0x69, 0x65, 0x6e, 0x72, 0x65, 0x73, 0x3b, 0x73, 0xe1, 0x62, 0x61, 0x64, 0x75, 0x3b, 0x53, +0x254, 0x301, 0x6e, 0x64, 0x69, 0x3b, 0x4d, 0x254, 0x301, 0x6e, 0x64, 0x69, 0x3b, 0xc1, 0x70, 0x74, 0x61, 0x20, 0x4d, 0x254, +0x301, 0x6e, 0x64, 0x69, 0x3b, 0x57, 0x25b, 0x301, 0x6e, 0x25b, 0x73, 0x25b, 0x64, 0x25b, 0x3b, 0x54, 0x254, 0x301, 0x73, 0x25b, +0x64, 0x25b, 0x3b, 0x46, 0x25b, 0x6c, 0xe2, 0x79, 0x25b, 0x64, 0x25b, 0x3b, 0x53, 0xe1, 0x73, 0x69, 0x64, 0x25b, 0x3b, 0x53, +0x254, 0x301, 0x3b, 0x4d, 0x254, 0x301, 0x3b, 0xc1, 0x4d, 0x3b, 0x57, 0x25b, 0x301, 0x3b, 0x54, 0x254, 0x301, 0x3b, 0x46, 0x25b, +0x3b, 0x53, 0xe1, 0x3b, 0x73, 0x254, 0x6e, 0x64, 0x69, 0x3b, 0x6c, 0x75, 0x6e, 0x64, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x64, +0x69, 0x3b, 0x6d, 0x25b, 0x72, 0x6b, 0x25b, 0x72, 0x25b, 0x64, 0x69, 0x3b, 0x79, 0x65, 0x64, 0x69, 0x3b, 0x76, 0x61, 0x14b, +0x64, 0x25b, 0x72, 0x25b, 0x64, 0x69, 0x3b, 0x6d, 0x254, 0x6e, 0x254, 0x20, 0x73, 0x254, 0x6e, 0x64, 0x69, 0x3b, 0x73, 0x6f, +0x3b, 0x6c, 0x75, 0x3b, 0x6d, 0x61, 0x3b, 0x6d, 0x25b, 0x3b, 0x79, 0x65, 0x3b, 0x76, 0x61, 0x3b, 0x6d, 0x73, 0x3b, 0x41, +0x6e, 0x65, 0x67, 0x20, 0x31, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x32, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x33, 0x3b, +0x41, 0x6e, 0x65, 0x67, 0x20, 0x34, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x35, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x36, +0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x37, 0x3b, 0x41, 0x31, 0x3b, 0x41, 0x32, 0x3b, 0x41, 0x33, 0x3b, 0x41, 0x34, 0x3b, +0x41, 0x35, 0x3b, 0x41, 0x36, 0x3b, 0x41, 0x37, 0x3b, 0x6c, 0x79, 0x25b, 0x2bc, 0x25b, 0x301, 0x20, 0x73, 0x1e85, 0xed, 0x14b, +0x74, 0xe8, 0x3b, 0x6d, 0x76, 0x66, 0xf2, 0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc, 0x3b, 0x6d, 0x62, 0x254, 0x301, 0x254, 0x6e, +0x74, 0xe8, 0x20, 0x6d, 0x76, 0x66, 0xf2, 0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc, 0x3b, 0x74, 0x73, 0xe8, 0x74, 0x73, 0x25b, +0x300, 0x25b, 0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc, 0x3b, 0x6d, 0x62, 0x254, 0x301, 0x254, 0x6e, 0x74, 0xe8, 0x20, 0x74, 0x73, +0x65, 0x74, 0x73, 0x25b, 0x300, 0x25b, 0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc, 0x3b, 0x6d, 0x76, 0x66, 0xf2, 0x20, 0x6d, 0xe0, +0x67, 0x61, 0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc, 0x3b, 0x6d, 0xe0, 0x67, 0x61, 0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc, 0x3b, +0x41, 0x14b, 0x70, 0xe9, 0x74, 0x75, 0x77, 0x61, 0x6b, 0x21f, 0x61, 0x14b, 0x3b, 0x41, 0x14b, 0x70, 0xe9, 0x74, 0x75, 0x77, +0x61, 0x14b, 0x17e, 0x69, 0x3b, 0x41, 0x14b, 0x70, 0xe9, 0x74, 0x75, 0x6e, 0x75, 0x14b, 0x70, 0x61, 0x3b, 0x41, 0x14b, 0x70, +0xe9, 0x74, 0x75, 0x79, 0x61, 0x6d, 0x6e, 0x69, 0x3b, 0x41, 0x14b, 0x70, 0xe9, 0x74, 0x75, 0x74, 0x6f, 0x70, 0x61, 0x3b, +0x41, 0x14b, 0x70, 0xe9, 0x74, 0x75, 0x7a, 0x61, 0x70, 0x74, 0x61, 0x14b, 0x3b, 0x4f, 0x77, 0xe1, 0x14b, 0x67, 0x79, 0x75, +0x17e, 0x61, 0x17e, 0x61, 0x70, 0x69, 0x3b, 0x41, 0x3b, 0x57, 0x3b, 0x4e, 0x3b, 0x59, 0x3b, 0x54, 0x3b, 0x5a, 0x3b, 0x4f, +0x3b, 0x2d30, 0x2d59, 0x2d30, 0x2d4e, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d62, 0x2d4f, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d4f, 0x2d30, 0x2d59, +0x3b, 0x2d30, 0x2d3d, 0x2d55, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d3d, 0x2d61, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d4e, 0x2d61, 0x2d30, 0x2d59, +0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d39, 0x2d62, 0x2d30, 0x2d59, 0x3b, 0x6cc, 0x6d5, 0x6a9, 0x634, 0x6d5, 0x645, 0x645, 0x6d5, 0x3b, 0x62f, 0x648, +0x648, 0x634, 0x6d5, 0x645, 0x645, 0x6d5, 0x3b, 0x633, 0x6ce, 0x634, 0x6d5, 0x645, 0x645, 0x6d5, 0x3b, 0x686, 0x648, 0x627, 0x631, 0x634, +0x6d5, 0x645, 0x645, 0x6d5, 0x3b, 0x67e, 0x6ce, 0x646, 0x62c, 0x634, 0x6d5, 0x645, 0x645, 0x6d5, 0x3b, 0x6be, 0x6d5, 0x6cc, 0x646, 0x6cc, +0x3b, 0x634, 0x6d5, 0x645, 0x645, 0x6d5, 0x3b, 0x6cc, 0x3b, 0x62f, 0x3b, 0x633, 0x3b, 0x686, 0x3b, 0x67e, 0x3b, 0x6be, 0x3b, 0x634, +0x3b, 0x6e, 0x6a, 0x65, 0x3b, 0x70, 0xf3, 0x6e, 0x3b, 0x77, 0x61, 0x142, 0x3b, 0x73, 0x72, 0x6a, 0x3b, 0x73, 0x74, 0x77, +0x3b, 0x70, 0x11b, 0x74, 0x3b, 0x73, 0x6f, 0x62, 0x3b, 0x6e, 0x6a, 0x65, 0x17a, 0x65, 0x6c, 0x61, 0x3b, 0x70, 0xf3, 0x6e, +0x6a, 0x65, 0x17a, 0x65, 0x6c, 0x65, 0x3b, 0x77, 0x61, 0x142, 0x74, 0x6f, 0x72, 0x61, 0x3b, 0x73, 0x72, 0x6a, 0x6f, 0x64, +0x61, 0x3b, 0x73, 0x74, 0x77, 0xf3, 0x72, 0x74, 0x6b, 0x3b, 0x70, 0x11b, 0x74, 0x6b, 0x3b, 0x73, 0x6f, 0x62, 0x6f, 0x74, +0x61, 0x3b, 0x6e, 0x3b, 0x70, 0x3b, 0x77, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x70, 0x3b, 0x73, 0x3b, 0x6e, 0x6a, 0x65, 0x3b, +0x70, 0xf3, 0x6e, 0x3b, 0x77, 0x75, 0x74, 0x3b, 0x73, 0x72, 0x6a, 0x3b, 0x161, 0x74, 0x77, 0x3b, 0x70, 0x6a, 0x61, 0x3b, +0x73, 0x6f, 0x62, 0x3b, 0x6e, 0x6a, 0x65, 0x64, 0x17a, 0x65, 0x6c, 0x61, 0x3b, 0x70, 0xf3, 0x6e, 0x64, 0x17a, 0x65, 0x6c, +0x61, 0x3b, 0x77, 0x75, 0x74, 0x6f, 0x72, 0x61, 0x3b, 0x73, 0x72, 0x6a, 0x65, 0x64, 0x61, 0x3b, 0x161, 0x74, 0x77, 0xf3, +0x72, 0x74, 0x6b, 0x3b, 0x70, 0x6a, 0x61, 0x74, 0x6b, 0x3b, 0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x6e, 0x3b, 0x70, +0x3b, 0x77, 0x3b, 0x73, 0x3b, 0x161, 0x3b, 0x70, 0x3b, 0x73, 0x3b, 0x6e, 0x61, 0x64, 0x3b, 0x70, 0x61, 0x6e, 0x3b, 0x77, +0x69, 0x73, 0x3b, 0x70, 0x75, 0x73, 0x3b, 0x6b, 0x65, 0x74, 0x3b, 0x70, 0x113, 0x6e, 0x3b, 0x73, 0x61, 0x62, 0x3b, 0x6e, +0x61, 0x64, 0x12b, 0x6c, 0x69, 0x3b, 0x70, 0x61, 0x6e, 0x61, 0x64, 0x12b, 0x6c, 0x69, 0x3b, 0x77, 0x69, 0x73, 0x61, 0x73, +0x12b, 0x64, 0x69, 0x73, 0x3b, 0x70, 0x75, 0x73, 0x73, 0x69, 0x73, 0x61, 0x77, 0x61, 0x69, 0x74, 0x69, 0x3b, 0x6b, 0x65, +0x74, 0x77, 0x69, 0x72, 0x74, 0x69, 0x6b, 0x73, 0x3b, 0x70, 0x113, 0x6e, 0x74, 0x6e, 0x69, 0x6b, 0x73, 0x3b, 0x73, 0x61, +0x62, 0x61, 0x74, 0x74, 0x69, 0x6b, 0x61, 0x3b, 0x4e, 0x3b, 0x50, 0x3b, 0x57, 0x3b, 0x50, 0x3b, 0x4b, 0x3b, 0x50, 0x3b, +0x53, 0x3b, 0x70, 0x61, 0x73, 0x3b, 0x76, 0x75, 0x6f, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6b, 0x6f, 0x73, 0x3b, 0x74, 0x75, +0x6f, 0x3b, 0x76, 0xe1, 0x73, 0x3b, 0x6c, 0xe1, 0x76, 0x3b, 0x70, 0x61, 0x73, 0x65, 0x70, 0x65, 0x69, 0x76, 0x69, 0x3b, +0x76, 0x75, 0x6f, 0x73, 0x73, 0x61, 0x72, 0x67, 0xe2, 0x3b, 0x6d, 0x61, 0x6a, 0x65, 0x62, 0x61, 0x72, 0x67, 0xe2, 0x3b, +0x6b, 0x6f, 0x73, 0x6b, 0x6f, 0x6b, 0x6b, 0x6f, 0x3b, 0x74, 0x75, 0x6f, 0x72, 0xe2, 0x73, 0x74, 0xe2, 0x68, 0x3b, 0x76, +0xe1, 0x73, 0x74, 0x75, 0x70, 0x70, 0x65, 0x69, 0x76, 0x69, 0x3b, 0x6c, 0xe1, 0x76, 0x75, 0x72, 0x64, 0xe2, 0x68, 0x3b, +0x70, 0x61, 0x73, 0x65, 0x70, 0x65, 0x65, 0x69, 0x76, 0x69, 0x3b, 0x76, 0x75, 0x6f, 0x73, 0x73, 0x61, 0x61, 0x72, 0x67, +0xe2, 0x3b, 0x6d, 0x61, 0x6a, 0x65, 0x62, 0x61, 0x61, 0x72, 0x67, 0xe2, 0x3b, 0x6b, 0x6f, 0x73, 0x6b, 0x6f, 0x68, 0x6f, +0x3b, 0x74, 0x75, 0x6f, 0x72, 0xe2, 0x73, 0x74, 0x75, 0x76, 0x3b, 0x76, 0xe1, 0x73, 0x74, 0x75, 0x70, 0x70, 0x65, 0x65, +0x69, 0x76, 0x69, 0x3b, 0x6c, 0xe1, 0x76, 0x75, 0x72, 0x64, 0x75, 0x76, 0x3b, 0x70, 0x3b, 0x56, 0x3b, 0x4d, 0x3b, 0x4b, +0x3b, 0x54, 0x3b, 0x56, 0x3b, 0x4c, 0x3b }; static const ushort byte_unit_data[] = { 0x62, 0x79, 0x74, 0x65, 0x73, 0x6b, 0x42, 0x3b, 0x4d, 0x42, 0x3b, 0x47, 0x42, 0x3b, 0x54, 0x42, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x4b, 0x69, 0x42, 0x3b, 0x4d, 0x69, 0x42, 0x3b, 0x47, 0x69, 0x42, 0x3b, 0x54, 0x69, 0x42, 0x3b, 0x50, 0x69, 0x42, 0x3b, 0x45, 0x69, 0x42, 0x62, 0x79, 0x74, 0x65, 0x67, 0x72, 0x65, 0x70, 0x65, 0x62, 0x61, 0x6a, 0x74, 0x1263, 0x12ed, -0x1275, 0x12aa, 0x1263, 0x3b, 0x121c, 0x130b, 0x1263, 0x12ed, 0x1275, 0x3b, 0x130a, 0x1263, 0x3b, 0x1274, 0x122b, 0x1263, 0x12ed, 0x1275, 0x3b, 0x50, -0x42, 0x3b, 0x45, 0x42, 0x628, 0x627, 0x64a, 0x62a, 0x643, 0x64a, 0x644, 0x648, 0x628, 0x627, 0x64a, 0x62a, 0x3b, 0x645, 0x64a, 0x63a, +0x1275, 0x12aa, 0x1263, 0x3b, 0x121c, 0x130b, 0x1263, 0x12ed, 0x1275, 0x3b, 0x130a, 0x1263, 0x3b, 0x1274, 0x122b, 0x1263, 0x12ed, 0x1275, 0x3b, 0x1354, +0x1263, 0x3b, 0x45, 0x42, 0x628, 0x627, 0x64a, 0x62a, 0x643, 0x64a, 0x644, 0x648, 0x628, 0x627, 0x64a, 0x62a, 0x3b, 0x645, 0x64a, 0x63a, 0x627, 0x628, 0x627, 0x64a, 0x62a, 0x3b, 0x63a, 0x64a, 0x63a, 0x627, 0x628, 0x627, 0x64a, 0x62a, 0x3b, 0x62a, 0x64a, 0x631, 0x627, 0x628, -0x627, 0x64a, 0x62a, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x562, 0x561, 0x575, 0x569, 0x565, 0x580, 0x56f, 0x532, 0x3b, 0x544, 0x532, -0x3b, 0x533, 0x532, 0x3b, 0x54f, 0x532, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x9ac, 0x9be, 0x987, 0x99f, 0x995, 0x9bf, 0x983, 0x20, -0x9ac, 0x9be, 0x983, 0x3b, 0x9ae, 0x9c7, 0x983, 0x20, 0x9ac, 0x9be, 0x983, 0x3b, 0x997, 0x9bf, 0x983, 0x20, 0x9ac, 0x9be, 0x983, 0x3b, -0x99f, 0x9c7, 0x983, 0x20, 0x9ac, 0x9be, 0x983, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x62, 0x61, 0x79, 0x74, 0x62, 0x79, 0x74, -0x65, 0x2d, 0x61, 0x6b, 0x6f, 0x6b, 0x74, 0x65, 0x64, 0x6f, 0xf9, 0x6b, 0x6f, 0x3b, 0x4d, 0x6f, 0x3b, 0x47, 0x6f, 0x3b, +0x627, 0x64a, 0x62a, 0x3b, 0x628, 0x64a, 0x62a, 0x627, 0x628, 0x627, 0x64a, 0x62a, 0x3b, 0x45, 0x42, 0x562, 0x561, 0x575, 0x569, 0x565, +0x580, 0x56f, 0x532, 0x3b, 0x544, 0x532, 0x3b, 0x533, 0x532, 0x3b, 0x54f, 0x532, 0x3b, 0x54a, 0x532, 0x3b, 0x45, 0x42, 0x9ac, 0x9be, +0x987, 0x99f, 0x995, 0x9bf, 0x983, 0x20, 0x9ac, 0x9be, 0x983, 0x3b, 0x9ae, 0x9c7, 0x983, 0x20, 0x9ac, 0x9be, 0x983, 0x3b, 0x997, 0x9bf, +0x983, 0x20, 0x9ac, 0x9be, 0x983, 0x3b, 0x99f, 0x9c7, 0x983, 0x20, 0x9ac, 0x9be, 0x983, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x62, +0x61, 0x79, 0x74, 0x62, 0x79, 0x74, 0x65, 0x2d, 0x61, 0x6b, 0x6f, 0x6b, 0x74, 0x65, 0x64, 0x6f, 0xf9, 0x6b, 0x6f, 0x3b, +0x4d, 0x6f, 0x3b, 0x47, 0x6f, 0x3b, 0x54, 0x6f, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x431, 0x430, 0x439, 0x442, 0x43e, 0x432, +0x435, 0x1018, 0x102d, 0x102f, 0x1000, 0x103a, 0x431, 0x430, 0x439, 0x442, 0x44b, 0x41a, 0x411, 0x3b, 0x41c, 0x411, 0x3b, 0x413, 0x411, 0x3b, +0x422, 0x411, 0x3b, 0x41f, 0x411, 0x3b, 0x45, 0x42, 0x1794, 0x17c3, 0x5b57, 0x8282, 0x5343, 0x5b57, 0x8282, 0x3b, 0x5146, 0x5b57, 0x8282, 0x3b, +0x5409, 0x5b57, 0x8282, 0x3b, 0x592a, 0x5b57, 0x8282, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x4f4d, 0x5143, 0x7d44, 0x62, 0x61, 0x6a, 0x74, +0x6f, 0x76, 0x69, 0x62, 0x61, 0x6a, 0x74, 0x79, 0x62, 0x61, 0x6a, 0x74, 0x6f, 0x6a, 0x62, 0x61, 0x69, 0x64, 0x69, 0x64, +0x62, 0xfd, 0x74, 0x4b, 0x42, 0x3b, 0x4d, 0x42, 0x3b, 0x47, 0x42, 0x3b, 0x54, 0x42, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, +0x74, 0x61, 0x76, 0x75, 0x74, 0x6b, 0x74, 0x3b, 0x4d, 0x74, 0x3b, 0x47, 0x74, 0x3b, 0x54, 0x74, 0x3b, 0x50, 0x74, 0x3b, +0x45, 0x74, 0x4b, 0x69, 0x74, 0x3b, 0x4d, 0x69, 0x74, 0x3b, 0x47, 0x69, 0x74, 0x3b, 0x54, 0x69, 0x74, 0x3b, 0x50, 0x69, +0x74, 0x3b, 0x45, 0x69, 0x74, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x6b, 0x6f, 0x3b, 0x4d, 0x6f, 0x3b, 0x47, 0x6f, 0x3b, 0x54, 0x6f, 0x3b, 0x50, 0x6f, 0x3b, 0x45, 0x6f, 0x4b, 0x69, 0x6f, 0x3b, 0x4d, 0x69, 0x6f, 0x3b, 0x47, 0x69, 0x6f, 0x3b, -0x54, 0x69, 0x6f, 0x3b, 0x50, 0x69, 0x6f, 0x3b, 0x45, 0x69, 0x6f, 0x431, 0x430, 0x439, 0x442, 0x43e, 0x432, 0x435, 0x1018, 0x102d, -0x102f, 0x1000, 0x103a, 0x431, 0x430, 0x439, 0x442, 0x44b, 0x41a, 0x411, 0x3b, 0x41c, 0x411, 0x3b, 0x413, 0x411, 0x3b, 0x422, 0x411, 0x3b, -0x50, 0x42, 0x3b, 0x45, 0x42, 0x1794, 0x17c3, 0x5b57, 0x8282, 0x5343, 0x5b57, 0x8282, 0x3b, 0x5146, 0x5b57, 0x8282, 0x3b, 0x5409, 0x5b57, 0x8282, -0x3b, 0x592a, 0x5b57, 0x8282, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x4f4d, 0x5143, 0x7d44, 0x62, 0x61, 0x6a, 0x74, 0x6f, 0x76, 0x69, -0x62, 0x61, 0x6a, 0x74, 0x79, 0x62, 0x61, 0x6a, 0x74, 0x6f, 0x6a, 0x62, 0x61, 0x69, 0x64, 0x69, 0x64, 0x62, 0xfd, 0x74, -0x4b, 0x42, 0x3b, 0x4d, 0x42, 0x3b, 0x47, 0x42, 0x3b, 0x54, 0x42, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x74, 0x61, 0x76, -0x75, 0x74, 0x6b, 0x74, 0x3b, 0x4d, 0x74, 0x3b, 0x47, 0x74, 0x3b, 0x54, 0x74, 0x3b, 0x50, 0x74, 0x3b, 0x45, 0x74, 0x4b, -0x69, 0x74, 0x3b, 0x4d, 0x69, 0x74, 0x3b, 0x47, 0x69, 0x74, 0x3b, 0x54, 0x69, 0x74, 0x3b, 0x50, 0x69, 0x74, 0x3b, 0x45, -0x69, 0x74, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x62, 0x61, 0x69, 0x64, 0x68, 0x74, 0x10d1, 0x10d0, 0x10d8, 0x10e2, 0x10d8, 0x10d9, -0x10d1, 0x10d0, 0x10d8, 0x10e2, 0x10d8, 0x3b, 0x10db, 0x10d1, 0x10d0, 0x10d8, 0x10e2, 0x10d8, 0x3b, 0x10d2, 0x10d1, 0x10d0, 0x10d8, 0x10e2, 0x10d8, 0x3b, -0x10e2, 0x10d1, 0x10d0, 0x10d8, 0x10e2, 0x10d8, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x42, 0x79, 0x74, 0x65, 0x73, 0xaac, 0xabe, 0xa87, -0xa9f, 0x5d1, 0x5d9, 0x5d9, 0x5d8, 0x92c, 0x93e, 0x907, 0x91f, 0x62, 0xe1, 0x6a, 0x74, 0x62, 0xe6, 0x74, 0x69, 0x62, 0x65, 0x61, -0x72, 0x74, 0x61, 0x30d0, 0x30a4, 0x30c8, 0xcac, 0xcc8, 0xc9f, 0xccd, 0x200c, 0xc97, 0xcb3, 0xcc1, 0xc95, 0xcbf, 0x2e, 0xcac, 0xcc8, 0x2e, -0x3b, 0xcae, 0xcc6, 0x2e, 0xcac, 0xcc8, 0x2e, 0x3b, 0xc97, 0xcbf, 0x2e, 0xcac, 0xcc8, 0x2e, 0x3b, 0xc9f, 0xcc6, 0x2e, 0xcac, 0xcc8, -0x2e, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x431, 0x430, 0x439, 0x442, 0x43a, 0x411, 0x3b, 0x4d, 0x411, 0x3b, 0x413, 0x411, 0x3b, -0x54, 0x411, 0x3b, 0x50, 0x411, 0x3b, 0x45, 0x411, 0x4b, 0x69, 0x411, 0x3b, 0x4d, 0x69, 0x411, 0x3b, 0x47, 0x69, 0x411, 0x3b, -0x54, 0x69, 0x411, 0x3b, 0x50, 0x69, 0x411, 0x3b, 0x45, 0x69, 0x411, 0x43a, 0x411, 0x3b, 0x41c, 0x411, 0x3b, 0x413, 0x411, 0x3b, -0x422, 0x411, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0xbc14, 0xc774, 0xd2b8, 0x62, 0x61, 0x69, 0x74, 0x69, 0x62, 0x61, 0x69, 0x74, -0x61, 0x69, 0x431, 0x430, 0x458, 0x442, 0x438, 0x62, 0x61, 0x69, 0x74, 0xd2c, 0xd48, 0xd31, 0xd4d, 0xd31, 0xd4d, 0xd15, 0xd3f, 0x2e, -0xd2c, 0xd3f, 0x2e, 0x3b, 0xd2e, 0xd46, 0x2e, 0xd2c, 0xd48, 0x2e, 0x3b, 0xd1c, 0xd3f, 0x2e, 0xd2c, 0xd48, 0x2e, 0x3b, 0xd1f, 0xd3f, -0xd2c, 0xd3f, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0xb2c, 0xb3e, 0xb07, 0xb1f, 0xb4d, 0x628, 0x627, 0x6cc, 0x62a, 0x6a9, 0x6cc, 0x644, -0x648, 0x628, 0x627, 0x6cc, 0x62a, 0x3b, 0x645, 0x6af, 0x627, 0x628, 0x627, 0x6cc, 0x62a, 0x3b, 0x6af, 0x6cc, 0x6af, 0x627, 0x628, 0x627, -0x6cc, 0x62a, 0x3b, 0x62a, 0x631, 0x627, 0x628, 0x627, 0x6cc, 0x62a, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0xa2c, 0xa3e, 0xa07, 0xa1f, -0x62, 0x79, 0x21b, 0x69, 0x431, 0x430, 0x458, 0x442, 0x43e, 0x432, 0x438, 0x628, 0x627, 0x626, 0x64a, 0x67d, 0x632, 0x6aa, 0x644, 0x648, -0x20, 0x628, 0x627, 0x626, 0x64a, 0x67d, 0x632, 0x3b, 0x645, 0x64a, 0x6af, 0x627, 0x20, 0x628, 0x627, 0x626, 0x64a, 0x67d, 0x632, 0x3b, -0x6af, 0x64a, 0x6af, 0x627, 0x20, 0x628, 0x627, 0x626, 0x64a, 0x67d, 0x632, 0x3b, 0x67d, 0x64a, 0x631, 0x627, 0x20, 0x628, 0x627, 0x626, -0x64a, 0x67d, 0x632, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0xdb6, 0xdba, 0xdd2, 0xda7, 0xdca, 0xd9a, 0xdd2, 0xdb6, 0x20, 0x7b, 0x30, -0x7d, 0x3b, 0xdb8, 0xdd9, 0xdb6, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0xd9c, 0xdd2, 0xdb6, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0xda7, 0xdd9, -0xdb6, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x6b, 0x69, 0x6c, 0x6f, 0x62, 0x61, 0x69, 0x74, 0x69, -0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x4d, 0x42, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x47, 0x42, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x74, -0x65, 0x72, 0x61, 0x62, 0x61, 0x69, 0x74, 0x69, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0xbaa, 0xbc8, -0xb9f, 0xbcd, 0xb95, 0xbb3, 0xbcd, 0xc2c, 0xc48, 0xc1f, 0xc4d, 0x200c, 0xc32, 0xc41, 0xc15, 0xc47, 0xc2c, 0xc40, 0x3b, 0xc0e, 0xc2e, 0xc4d, -0x200c, 0xc2c, 0xc3f, 0x3b, 0xc1c, 0xc40, 0xc2c, 0xc40, 0x3b, 0xc1f, 0xc40, 0xc2c, 0xc40, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0xe44, -0xe1a, 0xe15, 0xe4c, 0x70, 0x61, 0x69, 0x74, 0x69, 0x6b, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x4d, 0x42, -0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x47, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x54, 0x42, -0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x50, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x45, 0x42, -0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x4b, 0x69, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x4d, 0x69, -0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x47, 0x69, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b, -0x54, 0x69, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x50, 0x69, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, -0x7d, 0x3b, 0x45, 0x69, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x62, 0x61, 0xfd, 0x74, 0x431, 0x430, 0x439, 0x442, -0x438, 0x628, 0x627, 0x626, 0x679, 0x62, 0x65, 0x69, 0x74, 0x69, 0x61, 0x75, 0x61, 0x1e6d, 0x61, 0x6d, 0x1e0d, 0x61, 0x6e, 0x6b, -0x41, 0x1e6c, 0x3b, 0x4d, 0x41, 0x1e6c, 0x3b, 0x47, 0x41, 0x1e6c, 0x3b, 0x54, 0x41, 0x1e6c, 0x3b, 0x50, 0x41, 0x1e6c, 0x3b, 0x45, -0x41, 0x1e6c, 0x4b, 0x69, 0x41, 0x1e6c, 0x3b, 0x4d, 0x69, 0x41, 0x1e6c, 0x3b, 0x47, 0x69, 0x41, 0x1e6c, 0x3b, 0x54, 0x69, 0x41, -0x1e6c, 0x3b, 0x50, 0x69, 0x41, 0x1e6c, 0x3b, 0x45, 0x69, 0x41, 0x1e6c, 0x13d7, 0x13d3, 0x13cd, 0x13a6, 0x13b5, 0x13a9, 0x431, 0x430, 0x430, -0x439, 0x442, 0x43a, 0x411, 0x3b, 0x41c, 0x411, 0x3b, 0x47, 0x42, 0x3b, 0x54, 0x42, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x62, -0x79, 0x74, 0x65, 0x79 +0x54, 0x69, 0x6f, 0x3b, 0x50, 0x69, 0x6f, 0x3b, 0x45, 0x69, 0x6f, 0x62, 0x61, 0x69, 0x64, 0x68, 0x74, 0x10d1, 0x10d0, 0x10d8, +0x10e2, 0x10d8, 0x10d9, 0x10d1, 0x10d0, 0x10d8, 0x10e2, 0x10d8, 0x3b, 0x10db, 0x10d1, 0x10d0, 0x10d8, 0x10e2, 0x10d8, 0x3b, 0x10d2, 0x10d1, 0x10d0, 0x10d8, +0x10e2, 0x10d8, 0x3b, 0x10e2, 0x10d1, 0x10d0, 0x10d8, 0x10e2, 0x10d8, 0x3b, 0x10de, 0x10d1, 0x10d0, 0x10d8, 0x10e2, 0x10d8, 0x3b, 0x45, 0x42, 0x42, +0x79, 0x74, 0x65, 0x73, 0xaac, 0xabe, 0xa87, 0xa9f, 0x6b, 0x42, 0x3b, 0x4d, 0x42, 0x3b, 0x47, 0x42, 0x3b, 0x54, 0x42, 0x3b, +0xaaa, 0xac0, 0xaac, 0xac0, 0x3b, 0x45, 0x42, 0x5d1, 0x5d9, 0x5d9, 0x5d8, 0x92c, 0x93e, 0x907, 0x91f, 0x62, 0xe1, 0x6a, 0x74, 0x62, +0xe6, 0x74, 0x69, 0x62, 0x65, 0x61, 0x72, 0x74, 0x61, 0x30d0, 0x30a4, 0x30c8, 0x62, 0x69, 0x74, 0x65, 0xcac, 0xcc8, 0xc9f, 0xccd, +0x200c, 0xc97, 0xcb3, 0xcc1, 0xc95, 0xcbf, 0x2e, 0xcac, 0xcc8, 0x2e, 0x3b, 0xcae, 0xcc6, 0x2e, 0xcac, 0xcc8, 0x2e, 0x3b, 0xc97, 0xcbf, +0x2e, 0xcac, 0xcc8, 0x2e, 0x3b, 0xc9f, 0xcc6, 0x2e, 0xcac, 0xcc8, 0x2e, 0x3b, 0xcaa, 0xcc6, 0xcac, 0xcc8, 0x3b, 0x45, 0x42, 0x431, +0x430, 0x439, 0x442, 0x43a, 0x411, 0x3b, 0x4d, 0x411, 0x3b, 0x413, 0x411, 0x3b, 0x54, 0x411, 0x3b, 0x41f, 0x411, 0x3b, 0x45, 0x411, +0x4b, 0x69, 0x411, 0x3b, 0x4d, 0x69, 0x411, 0x3b, 0x47, 0x69, 0x411, 0x3b, 0x54, 0x69, 0x411, 0x3b, 0x50, 0x69, 0x411, 0x3b, +0x45, 0x69, 0x411, 0x43a, 0x411, 0x3b, 0x41c, 0x411, 0x3b, 0x413, 0x411, 0x3b, 0x422, 0x411, 0x3b, 0x41f, 0x442, 0x431, 0x3b, 0x45, +0x42, 0xbc14, 0xc774, 0xd2b8, 0x62, 0x61, 0x69, 0x74, 0x69, 0x62, 0x61, 0x69, 0x74, 0x61, 0x69, 0x431, 0x430, 0x458, 0x442, 0x438, +0x62, 0x61, 0x69, 0x74, 0xd2c, 0xd48, 0xd31, 0xd4d, 0xd31, 0xd4d, 0xd15, 0xd3f, 0x2e, 0xd2c, 0xd3f, 0x2e, 0x3b, 0xd2e, 0xd46, 0x2e, +0xd2c, 0xd48, 0x2e, 0x3b, 0xd1c, 0xd3f, 0x2e, 0xd2c, 0xd48, 0x2e, 0x3b, 0xd1f, 0xd3f, 0xd2c, 0xd3f, 0x3b, 0x50, 0x42, 0x3b, 0x45, +0x42, 0x43a, 0x411, 0x3b, 0x41c, 0x411, 0x3b, 0x413, 0x411, 0x3b, 0x422, 0x411, 0x3b, 0x41f, 0x411, 0x3b, 0x45, 0x42, 0x6b, 0x42, +0x3b, 0x4d, 0x42, 0x3b, 0x47, 0x42, 0x3b, 0x54, 0x42, 0x3b, 0x92a, 0x93f, 0x91f, 0x93e, 0x3b, 0x45, 0x42, 0xb2c, 0xb3e, 0xb07, +0xb1f, 0xb4d, 0x628, 0x627, 0x64a, 0x67c, 0x633, 0x628, 0x627, 0x6cc, 0x62a, 0x6a9, 0x6cc, 0x644, 0x648, 0x628, 0x627, 0x6cc, 0x62a, 0x3b, +0x645, 0x6af, 0x627, 0x628, 0x627, 0x6cc, 0x62a, 0x3b, 0x6af, 0x6cc, 0x6af, 0x627, 0x628, 0x627, 0x6cc, 0x62a, 0x3b, 0x62a, 0x631, 0x627, +0x628, 0x627, 0x6cc, 0x62a, 0x3b, 0x67e, 0x62a, 0x627, 0x628, 0x627, 0x6cc, 0x62a, 0x3b, 0x45, 0x42, 0xa2c, 0xa3e, 0xa07, 0xa1f, 0x62, +0x79, 0x21b, 0x69, 0x431, 0x430, 0x458, 0x442, 0x43e, 0x432, 0x438, 0x628, 0x627, 0x626, 0x64a, 0x67d, 0x632, 0x6aa, 0x644, 0x648, 0x20, +0x628, 0x627, 0x626, 0x64a, 0x67d, 0x632, 0x3b, 0x645, 0x64a, 0x6af, 0x627, 0x20, 0x628, 0x627, 0x626, 0x64a, 0x67d, 0x632, 0x3b, 0x6af, +0x64a, 0x6af, 0x627, 0x20, 0x628, 0x627, 0x626, 0x64a, 0x67d, 0x632, 0x3b, 0x67d, 0x64a, 0x631, 0x627, 0x20, 0x628, 0x627, 0x626, 0x64a, +0x67d, 0x632, 0x3b, 0x67e, 0x64a, 0x631, 0x627, 0x20, 0x628, 0x627, 0x626, 0x64a, 0x67d, 0x633, 0x3b, 0x45, 0x42, 0xdb6, 0xdba, 0xdd2, +0xda7, 0xdca, 0xd9a, 0xdd2, 0xdb6, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0xdb8, 0xdd9, 0xdb6, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0xd9c, 0xdd2, +0xdb6, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0xda7, 0xdd9, 0xdb6, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0xdb4, 0xdd9, 0xdb6, 0x20, 0x7b, 0x30, +0x7d, 0x3b, 0x45, 0x42, 0x62, 0x65, 0x79, 0x74, 0x6b, 0x69, 0x6c, 0x6f, 0x62, 0x61, 0x69, 0x74, 0x69, 0x20, 0x7b, 0x30, +0x7d, 0x3b, 0x4d, 0x42, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x47, 0x42, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x74, 0x65, 0x72, 0x61, +0x62, 0x61, 0x69, 0x74, 0x69, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x50, 0x42, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x45, 0x42, 0xbaa, +0xbc8, 0xb9f, 0xbcd, 0xb95, 0xbb3, 0xbcd, 0xc2c, 0xc48, 0xc1f, 0xc4d, 0x200c, 0xc32, 0xc41, 0xc15, 0xc47, 0xc2c, 0xc40, 0x3b, 0xc0e, 0xc2e, +0xc4d, 0x200c, 0xc2c, 0xc3f, 0x3b, 0xc1c, 0xc40, 0xc2c, 0xc40, 0x3b, 0xc1f, 0xc40, 0xc2c, 0xc40, 0x3b, 0xc2a, 0xc40, 0xc2c, 0xc40, 0x3b, +0x45, 0x42, 0xe44, 0xe1a, 0xe15, 0xe4c, 0x70, 0x61, 0x69, 0x74, 0x69, 0x6b, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, +0x3b, 0x4d, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x47, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, +0x3b, 0x54, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x50, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, +0x3b, 0x45, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x4b, 0x69, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, +0x3b, 0x4d, 0x69, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x47, 0x69, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, +0x30, 0x7d, 0x3b, 0x54, 0x69, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x50, 0x69, 0x42, 0x20, 0x2bb, 0x65, +0x20, 0x7b, 0x30, 0x7d, 0x3b, 0x45, 0x69, 0x42, 0x20, 0x2bb, 0x65, 0x20, 0x7b, 0x30, 0x7d, 0x62, 0x61, 0xfd, 0x74, 0x431, +0x430, 0x439, 0x442, 0x438, 0x628, 0x627, 0x626, 0x679, 0x6b, 0x42, 0x3b, 0x4d, 0x42, 0x3b, 0x47, 0x42, 0x3b, 0x54, 0x42, 0x3b, +0x67e, 0x6cc, 0x20, 0x628, 0x6cc, 0x3b, 0x45, 0x42, 0x62, 0x65, 0x69, 0x74, 0x69, 0x61, 0x75, 0x61, 0x1e6d, 0x61, 0x6d, 0x1e0d, +0x61, 0x6e, 0x6b, 0x41, 0x1e6c, 0x3b, 0x4d, 0x41, 0x1e6c, 0x3b, 0x47, 0x41, 0x1e6c, 0x3b, 0x54, 0x41, 0x1e6c, 0x3b, 0x50, 0x42, +0x3b, 0x45, 0x42, 0x13d7, 0x13d3, 0x13cd, 0x13a6, 0x13b5, 0x13a9, 0x431, 0x430, 0x430, 0x439, 0x442, 0x43a, 0x411, 0x3b, 0x41c, 0x411, 0x3b, +0x47, 0x42, 0x3b, 0x54, 0x42, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42, 0x62, 0x79, 0x74, 0x65, 0x79, 0x6a9, 0x6cc, 0x644, 0x648, +0x628, 0x627, 0x6cc, 0x62a, 0x3b, 0x645, 0x6af, 0x627, 0x628, 0x627, 0x6cc, 0x62a, 0x3b, 0x6af, 0x6cc, 0x6af, 0x627, 0x628, 0x627, 0x6cc, +0x62a, 0x3b, 0x62a, 0x631, 0x627, 0x628, 0x627, 0x6cc, 0x62a, 0x3b, 0x50, 0x42, 0x3b, 0x45, 0x42 }; static const ushort am_data[] = { 0x41, 0x4d, 0x57, 0x44, 0x76, 0x6d, 0x2e, 0x65, 0x20, 0x70, 0x61, 0x72, 0x61, 0x64, 0x69, 0x74, 0x65, 0x73, 0x1325, 0x12cb, -0x1275, 0x635, 0x53f, 0x531, 0x9aa, 0x9c2, 0x9f0, 0x9cd, 0x9ac, 0x9be, 0x9b9, 0x9cd, 0x9a8, 0x410, 0x41c, 0xf66, 0xf94, 0xf0b, 0xf46, 0xf0b, -0x41, 0x2e, 0x4d, 0x2e, 0x43f, 0x440, 0x2e, 0x43e, 0x431, 0x2e, 0x1014, 0x1036, 0x1014, 0x1000, 0x103a, 0x61, 0x2e, 0x20, 0x6d, 0x2e, -0x4e0a, 0x5348, 0x64, 0x6f, 0x70, 0x2e, 0x61, 0x2e, 0x6d, 0x2e, 0x61, 0x6d, 0x61, 0x74, 0x6d, 0x61, 0x70, 0x2e, 0x6d, 0x61, -0x74, 0x69, 0x6e, 0x6d, 0x3c0, 0x2e, 0x3bc, 0x2e, 0x5dc, 0x5e4, 0x5e0, 0x5d4, 0x5f4, 0x5e6, 0x92a, 0x942, 0x930, 0x94d, 0x935, 0x93e, -0x939, 0x94d, 0x928, 0x64, 0x65, 0x2e, 0x66, 0x2e, 0x68, 0x2e, 0x72, 0x2e, 0x6e, 0x2e, 0x5348, 0x524d, 0xcaa, 0xcc2, 0xcb0, 0xccd, -0xcb5, 0xcbe, 0xcb9, 0xccd, 0xca8, 0x442, 0x430, 0x4a3, 0x43a, 0x44b, 0xc624, 0xc804, 0x5a, 0x2e, 0x4d, 0x55, 0x2e, 0xe81, 0xec8, 0xead, -0xe99, 0xe97, 0xec8, 0xebd, 0xe87, 0x70, 0x72, 0x69, 0x65, 0x6b, 0x161, 0x70, 0x75, 0x73, 0x64, 0x69, 0x65, 0x6e, 0x101, 0x6e, -0x74, 0x254, 0x301, 0x6e, 0x67, 0x254, 0x301, 0x70, 0x72, 0x69, 0x65, 0x161, 0x70, 0x69, 0x65, 0x74, 0x43f, 0x440, 0x435, 0x442, -0x43f, 0x43b, 0x430, 0x434, 0x43d, 0x435, 0x50, 0x47, 0x92e, 0x2e, 0x92a, 0x942, 0x2e, 0x4af, 0x2e, 0x4e9, 0x63a, 0x2e, 0x645, 0x2e, -0x642, 0x628, 0x644, 0x200c, 0x627, 0x632, 0x638, 0x647, 0x631, 0x64, 0x61, 0x20, 0x6d, 0x61, 0x6e, 0x68, 0xe3, 0xa2a, 0xa42, 0x2e, -0xa26, 0xa41, 0x2e, 0x4e, 0x44, 0x43f, 0x440, 0x435, 0x20, 0x43f, 0x43e, 0x434, 0x43d, 0x435, 0x70, 0x72, 0x69, 0x6a, 0x65, 0x20, -0x70, 0x6f, 0x64, 0x6e, 0x65, 0x70, 0x72, 0x65, 0x20, 0x70, 0x6f, 0x64, 0x6e, 0x65, 0x43f, 0x440, 0x438, 0x458, 0x435, 0x20, -0x43f, 0x43e, 0x434, 0x43d, 0x435, 0x4d5, 0x43c, 0x431, 0x438, 0x441, 0x431, 0x43e, 0x43d, 0x44b, 0x20, 0x440, 0x430, 0x437, 0x43c, 0x4d5, -0x635, 0x628, 0x62d, 0x60c, 0x20, 0x645, 0x646, 0x62c, 0x647, 0x646, 0x62f, 0xdb4, 0xdd9, 0x2e, 0xdc0, 0x2e, 0x73, 0x6e, 0x2e, 0x66, -0x6d, 0x43f, 0x435, 0x2e, 0x20, 0x447, 0x43e, 0x2e, 0xbae, 0xbc1, 0xbb1, 0xbcd, 0xbaa, 0xb95, 0xbb2, 0xbcd, 0xe01, 0xe48, 0xe2d, 0xe19, -0xe40, 0xe17, 0xe35, 0xe48, 0xe22, 0xe07, 0xf66, 0xf94, 0xf0b, 0xf51, 0xfb2, 0xf7c, 0xf0b, 0x1295, 0x1309, 0x1206, 0x20, 0x1230, 0x12d3, 0x1270, -0x68, 0x65, 0x6e, 0x67, 0x69, 0x68, 0x65, 0x6e, 0x67, 0x69, 0xd6, 0xd6, 0x67, 0xfc, 0x6e, 0x6f, 0x72, 0x74, 0x61, 0x64, -0x61, 0x6e, 0x20, 0xf6, 0x148, 0x686, 0x6c8, 0x634, 0x62a, 0x649, 0x646, 0x20, 0x628, 0x6c7, 0x631, 0x6c7, 0x646, 0x434, 0x43f, 0x54, -0x4f, 0x422, 0x41e, 0x53, 0x41, 0x79, 0x62, 0x53, 0x75, 0x62, 0x5e4, 0x5bf, 0x5d0, 0x5b7, 0x5e8, 0x5de, 0x5d9, 0x5d8, 0x5d0, 0x5b8, -0x5d2, 0xc0, 0xe1, 0x72, 0x1ecd, 0x300, 0xc0, 0xe1, 0x72, 0x254, 0x300, 0x66, 0x6f, 0x72, 0x6d, 0x69, 0x64, 0x64, 0x61, 0x67, -0x70, 0x72, 0x69, 0x6a, 0x65, 0x70, 0x6f, 0x64, 0x6e, 0x65, 0x41, 0x4e, 0x128, 0x79, 0x61, 0x6b, 0x77, 0x61, 0x6b, 0x79, -0x61, 0x61, 0x2e, 0x14b, 0x64, 0x69, 0x61, 0x6d, 0x20, 0x56, 0x6f, 0x72, 0x6d, 0x69, 0x74, 0x74, 0x61, 0x67, 0xa3b8, 0xa111, -0x69, 0x111, 0x69, 0x74, 0x62, 0x65, 0x61, 0x69, 0x76, 0x65, 0x74, 0x69, 0x62, 0x4d, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x4c, -0x75, 0x6d, 0x61, 0x20, 0x6c, 0x77, 0x61, 0x20, 0x4b, 0x73, 0x75, 0x62, 0x61, 0x6b, 0x61, 0x4b, 0x69, 0x72, 0x6f, 0x6b, -0x6f, 0x54, 0x65, 0x73, 0x69, 0x72, 0x61, 0x6e, 0x6b, 0x61, 0x6e, 0x67, 0x2019, 0x61, 0x6d, 0x61, 0x2d5c, 0x2d49, 0x2d3c, 0x2d30, -0x2d61, 0x2d5c, 0x74, 0x69, 0x66, 0x61, 0x77, 0x74, 0x6e, 0x20, 0x74, 0x75, 0x66, 0x61, 0x74, 0x70, 0x61, 0x6d, 0x69, 0x6c, -0x61, 0x75, 0x75, 0x74, 0x75, 0x6b, 0x6f, 0x4b, 0x49, 0x13cc, 0x13be, 0x13b4, 0x4d, 0x75, 0x68, 0x69, 0x54, 0x4f, 0x4f, 0x75, -0x6c, 0x75, 0x63, 0x68, 0x65, 0x6c, 0x6f, 0x52, 0x168, 0x6b, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x1c1, 0x67, 0x6f, 0x61, 0x67, -0x61, 0x73, 0x55, 0x68, 0x72, 0x20, 0x76, 0xf6, 0x72, 0x6d, 0x69, 0x64, 0x64, 0x61, 0x61, 0x63, 0x68, 0x73, 0x190, 0x6e, -0x6b, 0x61, 0x6b, 0x25b, 0x6e, 0x79, 0xe1, 0x4d, 0x75, 0x6e, 0x6b, 0x79, 0x6f, 0x69, 0x63, 0x68, 0x65, 0x68, 0x65, 0x61, -0x76, 0x6f, 0x54, 0x61, 0x70, 0x61, 0x72, 0x61, 0x63, 0x68, 0x75, 0x41, 0x64, 0x64, 0x75, 0x68, 0x61, 0x4f, 0x44, 0x5a, -0x64, 0x61, 0x74, 0x20, 0x61, 0x7a, 0x61, 0x6c, 0x6d, 0x61, 0x6b, 0x65, 0x6f, 0x92b, 0x941, 0x902, 0x44, 0x69, 0x6e, 0x64, -0x61, 0x6d, 0x6f, 0x69, 0x65, 0x73, 0x61, 0x2e, 0x67, 0x49, 0x20, 0x62, 0x69, 0x6b, 0x25b, 0x302, 0x67, 0x6c, 0xe0, 0x53, -0x75, 0x62, 0x62, 0x61, 0x61, 0x68, 0x69, 0x69, 0x64, 0x69, 0x253, 0x61, 0x6b, 0xed, 0x6b, 0xed, 0x72, 0xed, 0x67, 0x73, -0xe1, 0x72, 0xfa, 0x77, 0xe1, 0x77, 0x69, 0x63, 0x68, 0x69, 0x73, 0x68, 0x75, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6d, 0x61, -0x6e, 0xe1, 0x52, 0x57, 0x42d, 0x418, 0x4c, 0x77, 0x61, 0x6d, 0x69, 0x6c, 0x61, 0x77, 0x75, 0x6b, 0x69, 0x25b, 0x6d, 0x25b, -0x301, 0x25b, 0x6d, 0x64, 0x65, 0x20, 0x6c, 0x61, 0x20, 0x6d, 0x61, 0xf1, 0x61, 0x6e, 0x61, 0x6d, 0x62, 0x61, 0xa78c, 0x6d, -0x62, 0x61, 0xa78c, 0x6d, 0x62, 0x61, 0x2bc, 0xe1, 0x6d, 0x62, 0x61, 0x2bc, 0x628, 0x2e, 0x646, 0x64, 0x6f, 0x70, 0x6f, 0x142, -0x64, 0x6e, 0x6a, 0x61, 0x69, 0x70, 0x2e +0x1275, 0x635, 0x9aa, 0x9c2, 0x9f0, 0x9cd, 0x9ac, 0x9be, 0x9b9, 0x9cd, 0x9a8, 0x410, 0x41c, 0xf66, 0xf94, 0xf0b, 0xf46, 0xf0b, 0x41, 0x2e, +0x4d, 0x2e, 0x43f, 0x440, 0x2e, 0x43e, 0x431, 0x2e, 0x1014, 0x1036, 0x1014, 0x1000, 0x103a, 0x61, 0x2e, 0x20, 0x6d, 0x2e, 0x4e0a, 0x5348, +0x64, 0x6f, 0x70, 0x2e, 0x61, 0x2e, 0x6d, 0x2e, 0x61, 0x6d, 0x61, 0x74, 0x6d, 0x61, 0x70, 0x2e, 0x6d, 0x61, 0x74, 0x69, +0x6e, 0x6d, 0x3c0, 0x2e, 0x3bc, 0x2e, 0x5dc, 0x5e4, 0x5e0, 0x5d4, 0x5f4, 0x5e6, 0x92a, 0x942, 0x930, 0x94d, 0x935, 0x93e, 0x939, 0x94d, +0x928, 0x64, 0x65, 0x2e, 0x66, 0x2e, 0x68, 0x2e, 0x72, 0x2e, 0x6e, 0x2e, 0x5348, 0x524d, 0x49, 0x73, 0x75, 0x6b, 0xcaa, 0xcc2, +0xcb0, 0xccd, 0xcb5, 0xcbe, 0xcb9, 0xccd, 0xca8, 0x442, 0x430, 0x4a3, 0x43a, 0x44b, 0xc624, 0xc804, 0x5a, 0x2e, 0x4d, 0x55, 0x2e, 0xe81, +0xec8, 0xead, 0xe99, 0xe97, 0xec8, 0xebd, 0xe87, 0x70, 0x72, 0x69, 0x65, 0x6b, 0x161, 0x70, 0x75, 0x73, 0x64, 0x69, 0x65, 0x6e, +0x101, 0x6e, 0x74, 0x254, 0x301, 0x6e, 0x67, 0x254, 0x301, 0x70, 0x72, 0x69, 0x65, 0x161, 0x70, 0x69, 0x65, 0x74, 0x43f, 0x440, +0x435, 0x442, 0x43f, 0x43b, 0x430, 0x434, 0x43d, 0x435, 0x50, 0x47, 0x92e, 0x2e, 0x92a, 0x942, 0x2e, 0x4af, 0x2e, 0x4e9, 0x2e, 0x63a, +0x2e, 0x645, 0x2e, 0x642, 0x628, 0x644, 0x200c, 0x627, 0x632, 0x638, 0x647, 0x631, 0x64, 0x61, 0x20, 0x6d, 0x61, 0x6e, 0x68, 0xe3, +0xa2a, 0xa42, 0x2e, 0xa26, 0xa41, 0x2e, 0x4e, 0x44, 0x43f, 0x440, 0x435, 0x20, 0x43f, 0x43e, 0x434, 0x43d, 0x435, 0x43f, 0x440, 0x438, +0x458, 0x435, 0x20, 0x43f, 0x43e, 0x434, 0x43d, 0x435, 0x70, 0x72, 0x69, 0x6a, 0x65, 0x20, 0x70, 0x6f, 0x64, 0x6e, 0x65, 0x70, +0x72, 0x65, 0x20, 0x70, 0x6f, 0x64, 0x6e, 0x65, 0x4d5, 0x43c, 0x431, 0x438, 0x441, 0x431, 0x43e, 0x43d, 0x44b, 0x20, 0x440, 0x430, +0x437, 0x43c, 0x4d5, 0x635, 0x628, 0x62d, 0x60c, 0x20, 0x645, 0x646, 0x62c, 0x647, 0x646, 0x62f, 0xdb4, 0xdd9, 0x2e, 0xdc0, 0x2e, 0x73, +0x6e, 0x2e, 0x66, 0x6d, 0x43f, 0x435, 0x2e, 0x20, 0x447, 0x43e, 0x2e, 0xbae, 0xbc1, 0xbb1, 0xbcd, 0xbaa, 0xb95, 0xbb2, 0xbcd, 0xe01, +0xe48, 0xe2d, 0xe19, 0xe40, 0xe17, 0xe35, 0xe48, 0xe22, 0xe07, 0xf66, 0xf94, 0xf0b, 0xf51, 0xfb2, 0xf7c, 0xf0b, 0x1295, 0x1309, 0x1206, 0x20, +0x1230, 0x12d3, 0x1270, 0x68, 0x65, 0x6e, 0x67, 0x69, 0x68, 0x65, 0x6e, 0x67, 0x69, 0xd6, 0xd6, 0x67, 0xfc, 0x6e, 0x6f, 0x72, +0x74, 0x61, 0x64, 0x61, 0x6e, 0x20, 0xf6, 0x148, 0x686, 0x6c8, 0x634, 0x62a, 0x649, 0x646, 0x20, 0x628, 0x6c7, 0x631, 0x6c7, 0x646, +0x434, 0x43f, 0x54, 0x4f, 0x422, 0x41e, 0x53, 0x41, 0x79, 0x62, 0x53, 0x75, 0x62, 0x5e4, 0x5bf, 0x5d0, 0x5b7, 0x5e8, 0x5de, 0x5d9, +0x5d8, 0x5d0, 0x5b8, 0x5d2, 0xc0, 0xe1, 0x72, 0x1ecd, 0x300, 0xc0, 0xe1, 0x72, 0x254, 0x300, 0x66, 0x6f, 0x72, 0x6d, 0x69, 0x64, +0x64, 0x61, 0x67, 0x70, 0x72, 0x69, 0x6a, 0x65, 0x70, 0x6f, 0x64, 0x6e, 0x65, 0x41, 0x4e, 0x128, 0x79, 0x61, 0x6b, 0x77, +0x61, 0x6b, 0x79, 0x61, 0x61, 0x2e, 0x14b, 0x64, 0x69, 0x61, 0x6d, 0x20, 0x56, 0x6f, 0x72, 0x6d, 0x69, 0x74, 0x74, 0x61, +0x67, 0xa3b8, 0xa111, 0x69, 0x111, 0x69, 0x74, 0x62, 0x65, 0x61, 0x69, 0x76, 0x65, 0x74, 0x69, 0x62, 0x4d, 0x61, 0x6d, 0x62, +0x69, 0x61, 0x4c, 0x75, 0x6d, 0x61, 0x20, 0x6c, 0x77, 0x61, 0x20, 0x4b, 0x73, 0x75, 0x62, 0x61, 0x6b, 0x61, 0x4b, 0x69, +0x72, 0x6f, 0x6b, 0x6f, 0x54, 0x65, 0x73, 0x69, 0x72, 0x61, 0x6e, 0x6b, 0x61, 0x6e, 0x67, 0x2019, 0x61, 0x6d, 0x61, 0x2d5c, +0x2d49, 0x2d3c, 0x2d30, 0x2d61, 0x2d5c, 0x74, 0x69, 0x66, 0x61, 0x77, 0x74, 0x6e, 0x20, 0x74, 0x75, 0x66, 0x61, 0x74, 0x70, 0x61, +0x6d, 0x69, 0x6c, 0x61, 0x75, 0x75, 0x74, 0x75, 0x6b, 0x6f, 0x4b, 0x49, 0x13cc, 0x13be, 0x13b4, 0x4d, 0x75, 0x68, 0x69, 0x54, +0x4f, 0x4f, 0x75, 0x6c, 0x75, 0x63, 0x68, 0x65, 0x6c, 0x6f, 0x52, 0x168, 0x6b, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x1c1, 0x67, +0x6f, 0x61, 0x67, 0x61, 0x73, 0x55, 0x68, 0x72, 0x20, 0x76, 0xf6, 0x72, 0x6d, 0x69, 0x64, 0x64, 0x61, 0x61, 0x63, 0x68, +0x73, 0x190, 0x6e, 0x6b, 0x61, 0x6b, 0x25b, 0x6e, 0x79, 0xe1, 0x4d, 0x75, 0x6e, 0x6b, 0x79, 0x6f, 0x69, 0x63, 0x68, 0x65, +0x68, 0x65, 0x61, 0x76, 0x6f, 0x54, 0x61, 0x70, 0x61, 0x72, 0x61, 0x63, 0x68, 0x75, 0x41, 0x64, 0x64, 0x75, 0x68, 0x61, +0x4f, 0x44, 0x5a, 0x64, 0x61, 0x74, 0x20, 0x61, 0x7a, 0x61, 0x6c, 0x6d, 0x61, 0x6b, 0x65, 0x6f, 0x92b, 0x941, 0x902, 0x44, +0x69, 0x6e, 0x64, 0x61, 0x6d, 0x6f, 0x69, 0x65, 0x73, 0x61, 0x2e, 0x67, 0x49, 0x20, 0x62, 0x69, 0x6b, 0x25b, 0x302, 0x67, +0x6c, 0xe0, 0x53, 0x75, 0x62, 0x62, 0x61, 0x61, 0x68, 0x69, 0x69, 0x64, 0x69, 0x253, 0x61, 0x6b, 0xed, 0x6b, 0xed, 0x72, +0xed, 0x67, 0x73, 0xe1, 0x72, 0xfa, 0x77, 0xe1, 0x77, 0x69, 0x63, 0x68, 0x69, 0x73, 0x68, 0x75, 0x63, 0x6f, 0x6d, 0x6d, +0x65, 0x6d, 0x61, 0x6e, 0xe1, 0x52, 0x57, 0x42d, 0x418, 0x4c, 0x77, 0x61, 0x6d, 0x69, 0x6c, 0x61, 0x77, 0x75, 0x6b, 0x69, +0x25b, 0x6d, 0x25b, 0x301, 0x25b, 0x6d, 0x64, 0x65, 0x20, 0x6c, 0x61, 0x20, 0x6d, 0x61, 0xf1, 0x61, 0x6e, 0x61, 0x6d, 0x62, +0x61, 0xa78c, 0x6d, 0x62, 0x61, 0xa78c, 0x6d, 0x62, 0x61, 0x2bc, 0xe1, 0x6d, 0x62, 0x61, 0x2bc, 0x628, 0x2e, 0x646, 0x64, 0x6f, +0x70, 0x6f, 0x142, 0x64, 0x6e, 0x6a, 0x61, 0x69, 0x70, 0x2e }; static const ushort pm_data[] = { 0x50, 0x4d, 0x57, 0x42, 0x6e, 0x6d, 0x2e, 0x65, 0x20, 0x70, 0x61, 0x73, 0x64, 0x69, 0x74, 0x65, 0x73, 0x12a8, 0x1230, 0x12d3, -0x1275, 0x645, 0x53f, 0x540, 0x985, 0x9aa, 0x9f0, 0x9be, 0x9b9, 0x9cd, 0x9a8, 0x41f, 0x41c, 0xf55, 0xfb1, 0xf72, 0xf0b, 0xf46, 0xf0b, 0x47, -0x2e, 0x4d, 0x2e, 0x441, 0x43b, 0x2e, 0x43e, 0x431, 0x2e, 0x100a, 0x1014, 0x1031, 0x70, 0x2e, 0x20, 0x6d, 0x2e, 0x4e0b, 0x5348, 0x6f, -0x64, 0x70, 0x2e, 0x70, 0x2e, 0x6d, 0x2e, 0x70, 0x6d, 0x70, 0x74, 0x6d, 0x69, 0x70, 0x2e, 0x73, 0x6f, 0x69, 0x72, 0x66, -0x3bc, 0x2e, 0x3bc, 0x2e, 0x5d0, 0x5d7, 0x5d4, 0x5f4, 0x5e6, 0x905, 0x92a, 0x930, 0x93e, 0x939, 0x94d, 0x928, 0x64, 0x75, 0x2e, 0x65, -0x2e, 0x68, 0x2e, 0x69, 0x2e, 0x6e, 0x2e, 0x5348, 0x5f8c, 0xc85, 0xcaa, 0xcb0, 0xcbe, 0xcb9, 0xccd, 0xca8, 0x442, 0x4af, 0x448, 0x442, -0x4e9, 0x43d, 0x20, 0x43a, 0x438, 0x439, 0x438, 0x43d, 0x43a, 0x438, 0xc624, 0xd6c4, 0x5a, 0x2e, 0x4d, 0x57, 0x2e, 0xeab, 0xebc, 0xeb1, -0xe87, 0xe97, 0xec8, 0xebd, 0xe87, 0x70, 0x113, 0x63, 0x70, 0x75, 0x73, 0x64, 0x69, 0x65, 0x6e, 0x101, 0x6d, 0x70, 0xf3, 0x6b, -0x77, 0x61, 0x70, 0x6f, 0x70, 0x69, 0x65, 0x74, 0x43f, 0x43e, 0x43f, 0x43b, 0x430, 0x434, 0x43d, 0x435, 0x50, 0x54, 0x47, 0x92e, -0x2e, 0x909, 0x2e, 0x4af, 0x2e, 0x445, 0x63a, 0x2e, 0x648, 0x2e, 0x628, 0x639, 0x62f, 0x627, 0x632, 0x638, 0x647, 0x631, 0x64, 0x61, -0x20, 0x74, 0x61, 0x72, 0x64, 0x65, 0xa2c, 0xa3e, 0x2e, 0xa26, 0xa41, 0x2e, 0x4c, 0x4b, 0x43f, 0x43e, 0x20, 0x43f, 0x43e, 0x434, -0x43d, 0x435, 0x70, 0x6f, 0x20, 0x70, 0x6f, 0x64, 0x6e, 0x65, 0x4d5, 0x43c, 0x431, 0x438, 0x441, 0x431, 0x43e, 0x43d, 0x44b, 0x20, -0x444, 0x4d5, 0x441, 0x442, 0x4d5, 0x645, 0x646, 0x62c, 0x647, 0x646, 0x62f, 0x60c, 0x20, 0x634, 0x627, 0x645, 0xdb4, 0x2e, 0xdc0, 0x2e, -0x70, 0x6f, 0x70, 0x2e, 0x67, 0x6e, 0x2e, 0x65, 0x6d, 0x43f, 0x430, 0x2e, 0x20, 0x447, 0x43e, 0x2e, 0xbaa, 0xbbf, 0xbb1, 0xbcd, -0xbaa, 0xb95, 0xbb2, 0xbcd, 0xe2b, 0xe25, 0xe31, 0xe07, 0xe40, 0xe17, 0xe35, 0xe48, 0xe22, 0xe07, 0xf55, 0xfb1, 0xf72, 0xf0b, 0xf51, 0xfb2, -0xf7c, 0xf0b, 0x12f5, 0x1215, 0x122d, 0x20, 0x1230, 0x12d3, 0x1275, 0x65, 0x66, 0x69, 0x61, 0x66, 0x69, 0xd6, 0x53, 0x67, 0xfc, 0x6e, -0x6f, 0x72, 0x74, 0x61, 0x64, 0x61, 0x6e, 0x20, 0x73, 0x6f, 0x148, 0x686, 0x6c8, 0x634, 0x62a, 0x649, 0x646, 0x20, 0x643, 0x6d0, -0x64a, 0x649, 0x646, 0x43f, 0x43f, 0x54, 0x4b, 0x422, 0x41a, 0x43, 0x48, 0x79, 0x68, 0x4e, 0x67, 0x6f, 0x5e0, 0x5d0, 0x5b8, 0x5db, -0x5de, 0x5d9, 0x5d8, 0x5d0, 0x5b8, 0x5d2, 0x1ecc, 0x300, 0x73, 0xe1, 0x6e, 0x186, 0x300, 0x73, 0xe1, 0x6e, 0x65, 0x74, 0x74, 0x65, -0x72, 0x6d, 0x69, 0x64, 0x64, 0x61, 0x67, 0x70, 0x6f, 0x70, 0x6f, 0x64, 0x6e, 0x65, 0x43f, 0x43e, 0x43f, 0x43e, 0x434, 0x43d, -0x435, 0x45, 0x57, 0x92e, 0x2e, 0x928, 0x902, 0x2e, 0x50, 0x2e, 0x4d, 0x2e, 0x128, 0x79, 0x61, 0x77, 0x129, 0x6f, 0x6f, 0x70, -0x2e, 0x263, 0x65, 0x74, 0x72, 0x254, 0x61, 0x6d, 0x20, 0x4e, 0x61, 0x6d, 0x69, 0x74, 0x74, 0x61, 0x67, 0xa06f, 0xa2d2, 0x65, -0x61, 0x68, 0x6b, 0x65, 0x74, 0x62, 0x65, 0x61, 0x69, 0x76, 0x65, 0x74, 0x65, 0x62, 0x4d, 0x6f, 0x67, 0x6c, 0x75, 0x6d, -0x61, 0x20, 0x6c, 0x77, 0x61, 0x20, 0x70, 0x6b, 0x69, 0x6b, 0x69, 0x69, 0x257, 0x65, 0x48, 0x77, 0x61, 0x129, 0x2d, 0x69, -0x6e, 0x129, 0x54, 0x65, 0x69, 0x70, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x6f, 0x74, 0x6f, 0x2d5c, 0x2d30, 0x2d37, 0x2d33, 0x2d33, 0x2d6f, -0x2d30, 0x2d5c, 0x74, 0x61, 0x64, 0x67, 0x67, 0x2b7, 0x61, 0x74, 0x6e, 0x20, 0x74, 0x6d, 0x65, 0x64, 0x64, 0x69, 0x74, 0x70, -0x61, 0x6d, 0x75, 0x6e, 0x79, 0x69, 0x6b, 0x79, 0x69, 0x75, 0x6b, 0x6f, 0x6e, 0x79, 0x69, 0x55, 0x54, 0x13d2, 0x13af, 0x13f1, -0x13a2, 0x13d7, 0x13e2, 0x43, 0x68, 0x69, 0x6c, 0x6f, 0x4d, 0x55, 0x55, 0x61, 0x6b, 0x61, 0x73, 0x75, 0x62, 0x61, 0x168, 0x47, -0x6b, 0x6f, 0x6f, 0x73, 0x6b, 0x6f, 0x6c, 0x69, 0x6e, 0x79, 0x1c3, 0x75, 0x69, 0x61, 0x73, 0x55, 0x68, 0x72, 0x20, 0x6e, -0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x61, 0x63, 0x68, 0x73, 0x190, 0x6e, 0x64, 0xe1, 0x6d, 0xe2, 0x45, 0x69, 0x67, -0x75, 0x6c, 0x6f, 0x69, 0x63, 0x68, 0x61, 0x6d, 0x74, 0x68, 0x69, 0x45, 0x62, 0x6f, 0x6e, 0x67, 0x69, 0x41, 0x6c, 0x75, -0x75, 0x6c, 0x61, 0x4f, 0x54, 0x1e0c, 0x65, 0x66, 0x66, 0x69, 0x72, 0x20, 0x61, 0x7a, 0x61, 0x6e, 0x79, 0x69, 0x61, 0x67, -0x68, 0x75, 0x6f, 0x92c, 0x947, 0x932, 0x93e, 0x938, 0x947, 0x44, 0x69, 0x6c, 0x6f, 0x6c, 0x6f, 0x6e, 0x6f, 0x6d, 0xeb, 0x74, -0x74, 0x65, 0x73, 0x61, 0x2e, 0x6b, 0x49, 0x20, 0x253, 0x75, 0x67, 0x61, 0x6a, 0x254, 0x70, 0x5a, 0x61, 0x61, 0x72, 0x69, -0x6b, 0x61, 0x79, 0x20, 0x62, 0x65, 0x62, 0x79, 0xe1, 0x6d, 0x75, 0x6e, 0x67, 0x259, 0x67, 0xf3, 0x67, 0x259, 0x6c, 0x65, -0x63, 0x25b, 0x25b, 0x301, 0x6e, 0x6b, 0x6f, 0x6d, 0x63, 0x68, 0x6f, 0x63, 0x68, 0x69, 0x6c, 0x2019, 0x6c, 0x6c, 0x69, 0x6c, -0x6c, 0x69, 0x6b, 0x75, 0x67, 0xfa, 0x54, 0x14a, 0x42d, 0x41a, 0x50, 0x61, 0x73, 0x68, 0x61, 0x6d, 0x69, 0x68, 0x65, 0x6b, -0x69, 0x73, 0x25b, 0x301, 0x6e, 0x64, 0x25b, 0x64, 0x65, 0x20, 0x6c, 0x61, 0x20, 0x74, 0x61, 0x72, 0x64, 0x65, 0x14b, 0x6b, -0x61, 0x20, 0x6d, 0x62, 0x254, 0x301, 0x74, 0x20, 0x6e, 0x6a, 0x69, 0x6e, 0x63, 0x77, 0xf2, 0x6e, 0x7a, 0xe9, 0x6d, 0x62f, -0x2e, 0x646, 0x77, 0xf3, 0x74, 0x70, 0x6f, 0x142, 0x64, 0x6e, 0x6a, 0x61, 0x70, 0x6f, 0x70, 0x6f, 0x142, 0x64, 0x6e, 0x6a, -0x75, 0x65, 0x70, 0x2e +0x1275, 0x645, 0x985, 0x9aa, 0x9f0, 0x9be, 0x9b9, 0x9cd, 0x9a8, 0x41f, 0x41c, 0xf55, 0xfb1, 0xf72, 0xf0b, 0xf46, 0xf0b, 0x47, 0x2e, 0x4d, +0x2e, 0x441, 0x43b, 0x2e, 0x43e, 0x431, 0x2e, 0x100a, 0x1014, 0x1031, 0x70, 0x2e, 0x20, 0x6d, 0x2e, 0x4e0b, 0x5348, 0x6f, 0x64, 0x70, +0x2e, 0x70, 0x2e, 0x6d, 0x2e, 0x70, 0x6d, 0x70, 0x74, 0x6d, 0x69, 0x70, 0x2e, 0x73, 0x6f, 0x69, 0x72, 0x66, 0x3bc, 0x2e, +0x3bc, 0x2e, 0x5d0, 0x5d7, 0x5d4, 0x5f4, 0x5e6, 0x905, 0x92a, 0x930, 0x93e, 0x939, 0x94d, 0x928, 0x64, 0x75, 0x2e, 0x65, 0x2e, 0x68, +0x2e, 0x69, 0x2e, 0x6e, 0x2e, 0x5348, 0x5f8c, 0x57, 0x65, 0x6e, 0x67, 0x69, 0xc85, 0xcaa, 0xcb0, 0xcbe, 0xcb9, 0xccd, 0xca8, 0x442, +0x4af, 0x448, 0x442, 0x4e9, 0x43d, 0x20, 0x43a, 0x438, 0x439, 0x438, 0x43d, 0x43a, 0x438, 0xc624, 0xd6c4, 0x5a, 0x2e, 0x4d, 0x57, 0x2e, +0xeab, 0xebc, 0xeb1, 0xe87, 0xe97, 0xec8, 0xebd, 0xe87, 0x70, 0x113, 0x63, 0x70, 0x75, 0x73, 0x64, 0x69, 0x65, 0x6e, 0x101, 0x6d, +0x70, 0xf3, 0x6b, 0x77, 0x61, 0x70, 0x6f, 0x70, 0x69, 0x65, 0x74, 0x43f, 0x43e, 0x43f, 0x43b, 0x430, 0x434, 0x43d, 0x435, 0x50, +0x54, 0x47, 0x92e, 0x2e, 0x909, 0x2e, 0x4af, 0x2e, 0x445, 0x2e, 0x63a, 0x2e, 0x648, 0x2e, 0x628, 0x639, 0x62f, 0x627, 0x632, 0x638, +0x647, 0x631, 0x64, 0x61, 0x20, 0x74, 0x61, 0x72, 0x64, 0x65, 0xa2c, 0xa3e, 0x2e, 0xa26, 0xa41, 0x2e, 0x4c, 0x4b, 0x43f, 0x43e, +0x20, 0x43f, 0x43e, 0x434, 0x43d, 0x435, 0x70, 0x6f, 0x20, 0x70, 0x6f, 0x64, 0x6e, 0x65, 0x4d5, 0x43c, 0x431, 0x438, 0x441, 0x431, +0x43e, 0x43d, 0x44b, 0x20, 0x444, 0x4d5, 0x441, 0x442, 0x4d5, 0x645, 0x646, 0x62c, 0x647, 0x646, 0x62f, 0x60c, 0x20, 0x634, 0x627, 0x645, +0xdb4, 0x2e, 0xdc0, 0x2e, 0x70, 0x6f, 0x70, 0x2e, 0x67, 0x6e, 0x2e, 0x65, 0x6d, 0x43f, 0x430, 0x2e, 0x20, 0x447, 0x43e, 0x2e, +0xbaa, 0xbbf, 0xbb1, 0xbcd, 0xbaa, 0xb95, 0xbb2, 0xbcd, 0xe2b, 0xe25, 0xe31, 0xe07, 0xe40, 0xe17, 0xe35, 0xe48, 0xe22, 0xe07, 0xf55, 0xfb1, +0xf72, 0xf0b, 0xf51, 0xfb2, 0xf7c, 0xf0b, 0x12f5, 0x1215, 0x122d, 0x20, 0x1230, 0x12d3, 0x1275, 0x65, 0x66, 0x69, 0x61, 0x66, 0x69, 0xd6, +0x53, 0x67, 0xfc, 0x6e, 0x6f, 0x72, 0x74, 0x61, 0x64, 0x61, 0x6e, 0x20, 0x73, 0x6f, 0x148, 0x686, 0x6c8, 0x634, 0x62a, 0x649, +0x646, 0x20, 0x643, 0x6d0, 0x64a, 0x649, 0x646, 0x43f, 0x43f, 0x54, 0x4b, 0x422, 0x41a, 0x43, 0x48, 0x79, 0x68, 0x4e, 0x67, 0x6f, +0x5e0, 0x5d0, 0x5b8, 0x5db, 0x5de, 0x5d9, 0x5d8, 0x5d0, 0x5b8, 0x5d2, 0x1ecc, 0x300, 0x73, 0xe1, 0x6e, 0x186, 0x300, 0x73, 0xe1, 0x6e, +0x65, 0x74, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x64, 0x64, 0x61, 0x67, 0x70, 0x6f, 0x70, 0x6f, 0x64, 0x6e, 0x65, 0x43f, 0x43e, +0x43f, 0x43e, 0x434, 0x43d, 0x435, 0x45, 0x57, 0x92e, 0x2e, 0x928, 0x902, 0x2e, 0x50, 0x2e, 0x4d, 0x2e, 0x128, 0x79, 0x61, 0x77, +0x129, 0x6f, 0x6f, 0x70, 0x2e, 0x263, 0x65, 0x74, 0x72, 0x254, 0x61, 0x6d, 0x20, 0x4e, 0x61, 0x6d, 0x69, 0x74, 0x74, 0x61, +0x67, 0xa06f, 0xa2d2, 0x65, 0x61, 0x68, 0x6b, 0x65, 0x74, 0x62, 0x65, 0x61, 0x69, 0x76, 0x65, 0x74, 0x65, 0x62, 0x4d, 0x6f, +0x67, 0x6c, 0x75, 0x6d, 0x61, 0x20, 0x6c, 0x77, 0x61, 0x20, 0x70, 0x6b, 0x69, 0x6b, 0x69, 0x69, 0x257, 0x65, 0x48, 0x77, +0x61, 0x129, 0x2d, 0x69, 0x6e, 0x129, 0x54, 0x65, 0x69, 0x70, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x6f, 0x74, 0x6f, 0x2d5c, 0x2d30, +0x2d37, 0x2d33, 0x2d33, 0x2d6f, 0x2d30, 0x2d5c, 0x74, 0x61, 0x64, 0x67, 0x67, 0x2b7, 0x61, 0x74, 0x6e, 0x20, 0x74, 0x6d, 0x65, 0x64, +0x64, 0x69, 0x74, 0x70, 0x61, 0x6d, 0x75, 0x6e, 0x79, 0x69, 0x6b, 0x79, 0x69, 0x75, 0x6b, 0x6f, 0x6e, 0x79, 0x69, 0x55, +0x54, 0x13d2, 0x13af, 0x13f1, 0x13a2, 0x13d7, 0x13e2, 0x43, 0x68, 0x69, 0x6c, 0x6f, 0x4d, 0x55, 0x55, 0x61, 0x6b, 0x61, 0x73, 0x75, +0x62, 0x61, 0x168, 0x47, 0x6b, 0x6f, 0x6f, 0x73, 0x6b, 0x6f, 0x6c, 0x69, 0x6e, 0x79, 0x1c3, 0x75, 0x69, 0x61, 0x73, 0x55, +0x68, 0x72, 0x20, 0x6e, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x64, 0x61, 0x61, 0x63, 0x68, 0x73, 0x190, 0x6e, 0x64, 0xe1, 0x6d, +0xe2, 0x45, 0x69, 0x67, 0x75, 0x6c, 0x6f, 0x69, 0x63, 0x68, 0x61, 0x6d, 0x74, 0x68, 0x69, 0x45, 0x62, 0x6f, 0x6e, 0x67, +0x69, 0x41, 0x6c, 0x75, 0x75, 0x6c, 0x61, 0x4f, 0x54, 0x1e0c, 0x65, 0x66, 0x66, 0x69, 0x72, 0x20, 0x61, 0x7a, 0x61, 0x6e, +0x79, 0x69, 0x61, 0x67, 0x68, 0x75, 0x6f, 0x92c, 0x947, 0x932, 0x93e, 0x938, 0x947, 0x44, 0x69, 0x6c, 0x6f, 0x6c, 0x6f, 0x6e, +0x6f, 0x6d, 0xeb, 0x74, 0x74, 0x65, 0x73, 0x61, 0x2e, 0x6b, 0x49, 0x20, 0x253, 0x75, 0x67, 0x61, 0x6a, 0x254, 0x70, 0x5a, +0x61, 0x61, 0x72, 0x69, 0x6b, 0x61, 0x79, 0x20, 0x62, 0x65, 0x62, 0x79, 0xe1, 0x6d, 0x75, 0x6e, 0x67, 0x259, 0x67, 0xf3, +0x67, 0x259, 0x6c, 0x65, 0x63, 0x25b, 0x25b, 0x301, 0x6e, 0x6b, 0x6f, 0x6d, 0x63, 0x68, 0x6f, 0x63, 0x68, 0x69, 0x6c, 0x2019, +0x6c, 0x6c, 0x69, 0x6c, 0x6c, 0x69, 0x6b, 0x75, 0x67, 0xfa, 0x54, 0x14a, 0x42d, 0x41a, 0x50, 0x61, 0x73, 0x68, 0x61, 0x6d, +0x69, 0x68, 0x65, 0x6b, 0x69, 0x73, 0x25b, 0x301, 0x6e, 0x64, 0x25b, 0x64, 0x65, 0x20, 0x6c, 0x61, 0x20, 0x74, 0x61, 0x72, +0x64, 0x65, 0x14b, 0x6b, 0x61, 0x20, 0x6d, 0x62, 0x254, 0x301, 0x74, 0x20, 0x6e, 0x6a, 0x69, 0x6e, 0x63, 0x77, 0xf2, 0x6e, +0x7a, 0xe9, 0x6d, 0x62f, 0x2e, 0x646, 0x77, 0xf3, 0x74, 0x70, 0x6f, 0x142, 0x64, 0x6e, 0x6a, 0x61, 0x70, 0x6f, 0x70, 0x6f, +0x142, 0x64, 0x6e, 0x6a, 0x75, 0x65, 0x70, 0x2e }; static const ushort currency_symbol_data[] = { 0x42, 0x72, 0x4b, 0x73, 0x68, 0x52, 0x24, 0x4c, 0x65, 0x6b, 0xeb, 0x64, 0x65, 0x6e, 0x20ac, 0x1265, 0x122d, 0x62c, 0x2e, 0x645, 0x2e, 0x200f, 0x62f, 0x2e, 0x62c, 0x2e, 0x200f, 0x62f, 0x2e, 0x628, 0x2e, 0x200f, 0x46, 0x43, 0x46, 0x41, 0x43, 0x46, 0x46, 0x64, 0x6a, 0x4e, 0x66, 0x6b, 0x62f, 0x2e, 0x639, 0x2e, 0x200f, 0x20aa, 0x62f, 0x2e, 0x623, 0x2e, 0x200f, 0x62f, 0x2e, 0x643, 0x2e, 0x200f, -0x644, 0x2e, 0x644, 0x2e, 0x200f, 0x62f, 0x2e, 0x644, 0x2e, 0x200f, 0x62f, 0x2e, 0x645, 0x2e, 0x200f, 0x631, 0x2e, 0x639, 0x2e, 0x200f, -0x631, 0x2e, 0x642, 0x2e, 0x200f, 0x631, 0x2e, 0x633, 0x2e, 0x200f, 0x53, 0x62c, 0x2e, 0x633, 0x2e, 0x644, 0x2e, 0x633, 0x2e, 0x200f, -0x62f, 0x2e, 0x62a, 0x2e, 0x200f, 0x62f, 0x2e, 0x625, 0x2e, 0x200f, 0x631, 0x2e, 0x64a, 0x2e, 0x200f, 0xa3, 0x58f, 0x20b9, 0x20bc, 0x20bd, -0x9f3, 0x4e, 0x75, 0x2e, 0x43b, 0x432, 0x2e, 0x4b, 0x17db, 0xffe5, 0x48, 0x4b, 0x24, 0x4d, 0x4f, 0x50, 0x24, 0x48, 0x52, 0x4b, -0x4b, 0x4d, 0x4b, 0x10d, 0x6b, 0x72, 0x2e, 0x41, 0x66, 0x6c, 0x2e, 0x4e, 0x41, 0x66, 0x2e, 0x55, 0x53, 0x24, 0x50, 0x46, -0x42, 0x75, 0x44, 0x47, 0x48, 0x20b5, 0x41, 0x72, 0x4d, 0x4b, 0x52, 0x4d, 0x52, 0x73, 0x20a6, 0x20b1, 0x52, 0x46, 0x57, 0x53, -0x24, 0x53, 0x52, 0x4c, 0x65, 0x45, 0x6b, 0x72, 0x54, 0x53, 0x68, 0x54, 0x24, 0x55, 0x53, 0x68, 0x56, 0x54, 0x44, 0x41, -0x43, 0x46, 0x41, 0x46, 0x43, 0x46, 0x43, 0x46, 0x50, 0x46, 0x47, 0x47, 0x55, 0x4d, 0x4d, 0x41, 0x44, 0x43, 0x48, 0x46, -0x4c, 0x53, 0x44, 0x54, 0x20be, 0x20b2, 0x46, 0x74, 0x49, 0x53, 0x4b, 0x52, 0x70, 0x43, 0x41, 0x24, 0x20b8, 0x441, 0x43e, 0x43c, -0x20a9, 0x4b, 0x50, 0x57, 0x20ba, 0x20ad, 0x4b, 0x7a, 0x434, 0x435, 0x43d, 0x4e, 0x5a, 0x24, 0x20ae, 0x43, 0x4e, 0xa5, 0x928, 0x947, -0x930, 0x942, 0x60b, 0x631, 0x6cc, 0x627, 0x644, 0x7a, 0x142, 0x52, 0x24, 0x200b, 0x4d, 0x54, 0x6e, 0x44, 0x62, 0x631, 0x53, 0x2f, -0x42, 0x73, 0x52, 0x4f, 0x4e, 0x4c, 0x20b4, 0x52, 0x53, 0x44, 0x41a, 0x41c, 0xdbb, 0xdd4, 0x2e, 0x20a1, 0x52, 0x44, 0x24, 0x51, -0x43, 0x24, 0x42, 0x2f, 0x2e, 0x47, 0x73, 0x2e, 0x42, 0x73, 0x2e, 0x441, 0x43e, 0x43c, 0x2e, 0x52, 0x73, 0x2e, 0x54, 0x48, -0x42, 0xa5, 0x54, 0x4d, 0x54, 0x73, 0x6f, 0x2bb, 0x6d, 0x441, 0x45e, 0x43c, 0x20ab, 0x4e, 0x54, 0x24, 0x41, 0x24, 0x49, 0x52, +0x644, 0x2e, 0x644, 0x2e, 0x200f, 0x62f, 0x2e, 0x644, 0x2e, 0x200f, 0x623, 0x2e, 0x645, 0x2e, 0x62f, 0x2e, 0x645, 0x2e, 0x200f, 0x631, +0x2e, 0x639, 0x2e, 0x200f, 0x631, 0x2e, 0x642, 0x2e, 0x200f, 0x631, 0x2e, 0x633, 0x2e, 0x200f, 0x53, 0x62c, 0x2e, 0x633, 0x2e, 0x644, +0x2e, 0x633, 0x2e, 0x200f, 0x62f, 0x2e, 0x62a, 0x2e, 0x200f, 0x62f, 0x2e, 0x625, 0x2e, 0x200f, 0x631, 0x2e, 0x64a, 0x2e, 0x200f, 0xa3, +0x58f, 0x20b9, 0x20bc, 0x20bd, 0x9f3, 0x4e, 0x75, 0x2e, 0x43b, 0x432, 0x2e, 0x4b, 0x17db, 0xffe5, 0x48, 0x4b, 0x24, 0x4d, 0x4f, 0x50, +0x24, 0x48, 0x52, 0x4b, 0x4b, 0x4d, 0x4b, 0x10d, 0x6b, 0x72, 0x2e, 0x41, 0x66, 0x6c, 0x2e, 0x4e, 0x41, 0x66, 0x2e, 0x55, +0x53, 0x24, 0x50, 0x46, 0x42, 0x75, 0x44, 0x47, 0x48, 0x20b5, 0x41, 0x72, 0x4d, 0x4b, 0x52, 0x4d, 0x52, 0x73, 0x20a6, 0x20b1, +0x52, 0x46, 0x57, 0x53, 0x24, 0x53, 0x52, 0x4c, 0x65, 0x45, 0x6b, 0x72, 0x54, 0x53, 0x68, 0x54, 0x24, 0x55, 0x53, 0x68, +0x56, 0x54, 0x44, 0x41, 0x43, 0x46, 0x41, 0x46, 0x43, 0x46, 0x43, 0x46, 0x50, 0x46, 0x47, 0x47, 0x55, 0x4d, 0x4d, 0x41, +0x44, 0x43, 0x48, 0x46, 0x4c, 0x53, 0x44, 0x54, 0x20be, 0x20b2, 0x46, 0x74, 0x49, 0x53, 0x4b, 0x52, 0x70, 0x43, 0x41, 0x24, +0x20b8, 0x441, 0x43e, 0x43c, 0x20a9, 0x4b, 0x50, 0x57, 0x20ba, 0x20ad, 0x4b, 0x7a, 0x434, 0x435, 0x43d, 0x20ae, 0x43, 0x4e, 0xa5, 0x928, +0x947, 0x930, 0x942, 0x60b, 0x631, 0x6cc, 0x627, 0x644, 0x7a, 0x142, 0x52, 0x24, 0x200b, 0x4d, 0x54, 0x6e, 0x44, 0x62, 0x631, 0x53, +0x2f, 0x42, 0x73, 0x52, 0x4f, 0x4e, 0x4c, 0x20b4, 0x52, 0x53, 0x44, 0x41a, 0x41c, 0xdbb, 0xdd4, 0x2e, 0x20a1, 0x52, 0x44, 0x24, +0x51, 0x43, 0x24, 0x42, 0x2f, 0x2e, 0x47, 0x73, 0x2e, 0x42, 0x73, 0x2e, 0x53, 0x441, 0x43e, 0x43c, 0x2e, 0x52, 0x73, 0x2e, +0xe3f, 0xa5, 0x54, 0x4d, 0x54, 0x73, 0x6f, 0x2bb, 0x6d, 0x441, 0x45e, 0x43c, 0x20ab, 0x4e, 0x54, 0x24, 0x41, 0x24, 0x49, 0x52, 0x52 }; @@ -5630,103 +5716,114 @@ static const ushort currency_display_name_data[] = { 0x61, 0x70, 0x75, 0x72, 0x61, 0x3b, 0xd07, 0xd28, 0xd4d, 0xd24, 0xd4d, 0xd2f, 0xd7b, 0x20, 0xd30, 0xd42, 0xd2a, 0x3b, 0x3b, 0xd07, 0xd28, 0xd4d, 0xd24, 0xd4d, 0xd2f, 0xd7b, 0x20, 0xd30, 0xd42, 0xd2a, 0x3b, 0x3b, 0x3b, 0x3b, 0xd07, 0xd28, 0xd4d, 0xd24, 0xd4d, 0xd2f, 0xd7b, 0x20, 0xd30, 0xd42, 0xd2a, 0x3b, 0x65, 0x77, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x77, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x77, -0x72, 0x6f, 0x3b, 0x65, 0x77, 0x72, 0x6f, 0x3b, 0x65, 0x77, 0x72, 0x6f, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, -0x930, 0x941, 0x92a, 0x92f, 0x93e, 0x3b, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x941, 0x92a, 0x92f, 0x93e, 0x3b, -0x3b, 0x3b, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x941, 0x92a, 0x92f, 0x947, 0x3b, 0x442, 0x4e9, 0x433, 0x440, -0x4e9, 0x433, 0x3b, 0x3b, 0x442, 0x4e9, 0x433, 0x440, 0x4e9, 0x433, 0x3b, 0x3b, 0x3b, 0x3b, 0x442, 0x4e9, 0x433, 0x440, 0x4e9, 0x433, -0x3b, 0x928, 0x947, 0x92a, 0x93e, 0x932, 0x940, 0x20, 0x930, 0x942, 0x92a, 0x948, 0x92f, 0x93e, 0x901, 0x3b, 0x3b, 0x928, 0x947, 0x92a, -0x93e, 0x932, 0x940, 0x20, 0x930, 0x942, 0x92a, 0x948, 0x92f, 0x93e, 0x901, 0x3b, 0x3b, 0x3b, 0x3b, 0x928, 0x947, 0x92a, 0x93e, 0x932, -0x940, 0x20, 0x930, 0x942, 0x92a, 0x948, 0x92f, 0x93e, 0x901, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x942, 0x92a, -0x93f, 0x901, 0x92f, 0x93e, 0x3b, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x942, 0x92a, 0x93f, 0x901, 0x92f, 0x93e, -0x3b, 0x3b, 0x3b, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x942, 0x92a, 0x93f, 0x901, 0x92f, 0x93e, 0x3b, 0x6e, -0x6f, 0x72, 0x73, 0x6b, 0x65, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x72, 0x3b, 0x3b, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x20, -0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x65, 0x20, 0x6b, 0x72, 0x6f, 0x6e, -0x65, 0x72, 0x3b, 0xb2d, 0xb3e, 0xb30, 0xb24, 0xb40, 0xb5f, 0x20, 0xb1f, 0xb19, 0xb4d, 0xb15, 0xb3e, 0x3b, 0x3b, 0xb2d, 0xb3e, 0xb30, -0xb24, 0xb40, 0xb5f, 0x20, 0xb1f, 0xb19, 0xb4d, 0xb15, 0xb3e, 0x3b, 0x3b, 0x3b, 0x3b, 0xb2d, 0xb3e, 0xb30, 0xb24, 0xb40, 0xb5f, 0x20, -0xb1f, 0xb19, 0xb4d, 0xb15, 0xb3e, 0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cd, 0x3b, 0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cd, -0x3b, 0x3b, 0x3b, 0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cd, 0x3b, 0x631, 0x6cc, 0x627, 0x644, 0x20, 0x627, 0x6cc, 0x631, 0x627, -0x646, 0x3b, 0x3b, 0x631, 0x6cc, 0x627, 0x644, 0x20, 0x627, 0x6cc, 0x631, 0x627, 0x646, 0x3b, 0x3b, 0x3b, 0x3b, 0x631, 0x6cc, 0x627, -0x644, 0x20, 0x627, 0x6cc, 0x631, 0x627, 0x646, 0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cc, 0x20, 0x627, 0x641, 0x63a, 0x627, 0x646, -0x633, 0x62a, 0x627, 0x646, 0x3b, 0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cc, 0x20, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x633, 0x62a, -0x627, 0x646, 0x3b, 0x3b, 0x3b, 0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cc, 0x20, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x633, 0x62a, -0x627, 0x646, 0x3b, 0x7a, 0x142, 0x6f, 0x74, 0x79, 0x20, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x3b, 0x3b, 0x7a, 0x142, 0x6f, -0x74, 0x79, 0x20, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x3b, 0x3b, 0x7a, 0x142, 0x6f, 0x74, 0x65, 0x20, 0x70, 0x6f, 0x6c, -0x73, 0x6b, 0x69, 0x65, 0x3b, 0x7a, 0x142, 0x6f, 0x74, 0x79, 0x63, 0x68, 0x20, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x63, -0x68, 0x3b, 0x7a, 0x142, 0x6f, 0x74, 0x65, 0x67, 0x6f, 0x20, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x65, 0x67, 0x6f, 0x3b, -0x52, 0x65, 0x61, 0x6c, 0x20, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x3b, 0x52, 0x65, 0x61, -0x6c, 0x20, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x52, 0x65, 0x61, 0x69, -0x73, 0x20, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x65, 0x69, 0x72, 0x6f, 0x73, 0x3b, 0x4b, 0x77, 0x61, 0x6e, 0x7a, 0x61, -0x20, 0x61, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x4b, 0x77, 0x61, 0x6e, 0x7a, 0x61, 0x20, 0x61, 0x6e, -0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x4b, 0x77, 0x61, 0x6e, 0x7a, 0x61, 0x73, 0x20, 0x61, 0x6e, -0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x65, 0x73, 0x63, 0x75, 0x64, 0x6f, 0x20, 0x63, 0x61, 0x62, 0x6f, 0x2d, -0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x65, 0x73, 0x63, 0x75, 0x64, 0x6f, 0x20, 0x63, 0x61, 0x62, -0x6f, 0x2d, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x73, 0x63, 0x75, 0x64, 0x6f, -0x73, 0x20, 0x63, 0x61, 0x62, 0x6f, 0x2d, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x64, 0xf3, 0x6c, -0x61, 0x72, 0x20, 0x64, 0x6f, 0x73, 0x20, 0x45, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x73, 0x20, 0x55, 0x6e, 0x69, 0x64, 0x6f, -0x73, 0x3b, 0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x20, 0x64, 0x6f, 0x73, 0x20, 0x45, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x73, -0x20, 0x55, 0x6e, 0x69, 0x64, 0x6f, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x65, 0x73, 0x20, 0x64, -0x6f, 0x73, 0x20, 0x45, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x73, 0x20, 0x55, 0x6e, 0x69, 0x64, 0x6f, 0x73, 0x3b, 0x46, 0x72, -0x61, 0x6e, 0x63, 0x6f, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x46, 0x72, 0x61, -0x6e, 0x63, 0x6f, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x72, -0x61, 0x6e, 0x63, 0x6f, 0x73, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x66, 0x72, 0x61, -0x6e, 0x63, 0x6f, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x3b, 0x66, 0x72, 0x61, -0x6e, 0x63, 0x6f, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, -0x72, 0x61, 0x6e, 0x63, 0x6f, 0x73, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x50, -0x61, 0x74, 0x61, 0x63, 0x61, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x3b, 0x3b, 0x50, 0x61, 0x74, 0x61, -0x63, 0x61, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x3b, 0x3b, 0x3b, 0x3b, 0x50, 0x61, 0x74, 0x61, 0x63, -0x61, 0x73, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x3b, 0x4d, 0x65, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x20, -0x64, 0x65, 0x20, 0x4d, 0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69, 0x71, 0x75, 0x65, 0x3b, 0x3b, 0x4d, 0x65, 0x74, 0x69, 0x63, -0x61, 0x6c, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69, 0x71, 0x75, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, -0x4d, 0x65, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x65, 0x73, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69, -0x71, 0x75, 0x65, 0x3b, 0x53, 0xe3, 0x6f, 0x20, 0x54, 0x6f, 0x6d, 0xe9, 0x20, 0x26, 0x20, 0x50, 0x72, 0xed, 0x6e, 0x63, -0x69, 0x70, 0x65, 0x20, 0x44, 0x6f, 0x62, 0x72, 0x61, 0x20, 0x28, 0x32, 0x30, 0x31, 0x38, 0x29, 0x3b, 0x3b, 0x53, 0xe3, -0x6f, 0x20, 0x54, 0x6f, 0x6d, 0xe9, 0x20, 0x26, 0x20, 0x50, 0x72, 0xed, 0x6e, 0x63, 0x69, 0x70, 0x65, 0x20, 0x64, 0x6f, -0x62, 0x72, 0x61, 0x20, 0x28, 0x32, 0x30, 0x31, 0x38, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0xe3, 0x6f, 0x20, 0x54, 0x6f, -0x6d, 0xe9, 0x20, 0x26, 0x20, 0x50, 0x72, 0xed, 0x6e, 0x63, 0x69, 0x70, 0x65, 0x20, 0x64, 0x6f, 0x62, 0x72, 0x61, 0x73, -0x20, 0x28, 0x32, 0x30, 0x31, 0x38, 0x29, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x73, 0x75, 0xed, 0xe7, 0x6f, -0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x73, 0x75, 0xed, 0xe7, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, -0x61, 0x6e, 0x63, 0x6f, 0x73, 0x20, 0x73, 0x75, 0xed, 0xe7, 0x6f, 0x73, 0x3b, 0xa2d, 0xa3e, 0xa30, 0xa24, 0xa40, 0x20, 0xa30, -0xa41, 0xa2a, 0xa07, 0xa06, 0x3b, 0x3b, 0xa2d, 0xa3e, 0xa30, 0xa24, 0xa40, 0x20, 0xa30, 0xa41, 0xa2a, 0xa07, 0xa06, 0x3b, 0x3b, 0x3b, -0x3b, 0xa2d, 0xa3e, 0xa30, 0xa24, 0xa40, 0x20, 0xa30, 0xa41, 0xa2a, 0xa0f, 0x3b, 0x631, 0x648, 0x67e, 0x626, 0x6cc, 0x6c1, 0x3b, 0x3b, -0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x73, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x3b, 0x3b, -0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x73, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, -0x6e, 0x63, 0x20, 0x73, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x3b, 0x6c, 0x65, 0x75, 0x20, 0x72, 0x6f, 0x6d, 0xe2, 0x6e, -0x65, 0x73, 0x63, 0x3b, 0x3b, 0x6c, 0x65, 0x75, 0x20, 0x72, 0x6f, 0x6d, 0xe2, 0x6e, 0x65, 0x73, 0x63, 0x3b, 0x3b, 0x6c, -0x65, 0x69, 0x20, 0x72, 0x6f, 0x6d, 0xe2, 0x6e, 0x65, 0x219, 0x74, 0x69, 0x3b, 0x3b, 0x6c, 0x65, 0x69, 0x20, 0x72, 0x6f, -0x6d, 0xe2, 0x6e, 0x65, 0x219, 0x74, 0x69, 0x3b, 0x6c, 0x65, 0x75, 0x20, 0x6d, 0x6f, 0x6c, 0x64, 0x6f, 0x76, 0x65, 0x6e, -0x65, 0x73, 0x63, 0x3b, 0x3b, 0x6c, 0x65, 0x75, 0x20, 0x6d, 0x6f, 0x6c, 0x64, 0x6f, 0x76, 0x65, 0x6e, 0x65, 0x73, 0x63, -0x3b, 0x3b, 0x6c, 0x65, 0x69, 0x20, 0x6d, 0x6f, 0x6c, 0x64, 0x6f, 0x76, 0x65, 0x6e, 0x65, 0x219, 0x74, 0x69, 0x3b, 0x3b, -0x6c, 0x65, 0x69, 0x20, 0x6d, 0x6f, 0x6c, 0x64, 0x6f, 0x76, 0x65, 0x6e, 0x65, 0x219, 0x74, 0x69, 0x3b, 0x440, 0x43e, 0x441, -0x441, 0x438, 0x439, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44c, 0x3b, 0x3b, 0x440, 0x43e, 0x441, 0x441, 0x438, -0x439, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44c, 0x3b, 0x3b, 0x440, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x441, -0x43a, 0x438, 0x445, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44f, 0x3b, 0x440, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x441, 0x43a, 0x438, 0x445, -0x20, 0x440, 0x443, 0x431, 0x43b, 0x435, 0x439, 0x3b, 0x440, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x441, 0x43a, 0x43e, 0x433, 0x43e, 0x20, -0x440, 0x443, 0x431, 0x43b, 0x44f, 0x3b, 0x431, 0x435, 0x43b, 0x43e, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x440, 0x443, -0x431, 0x43b, 0x44c, 0x3b, 0x3b, 0x431, 0x435, 0x43b, 0x43e, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x440, 0x443, 0x431, -0x43b, 0x44c, 0x3b, 0x3b, 0x431, 0x435, 0x43b, 0x43e, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x440, 0x443, 0x431, 0x43b, -0x44f, 0x3b, 0x431, 0x435, 0x43b, 0x43e, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x435, 0x439, -0x3b, 0x431, 0x435, 0x43b, 0x43e, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x43e, 0x433, 0x43e, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44f, 0x3b, +0x72, 0x6f, 0x3b, 0x65, 0x77, 0x72, 0x6f, 0x3b, 0x65, 0x77, 0x72, 0x6f, 0x3b, 0x54, 0x101, 0x72, 0x61, 0x20, 0x6f, 0x20, +0x41, 0x6f, 0x74, 0x65, 0x61, 0x72, 0x6f, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x67, 0x101, 0x20, 0x74, 0x101, +0x72, 0x61, 0x20, 0x6f, 0x20, 0x41, 0x6f, 0x74, 0x65, 0x61, 0x72, 0x6f, 0x61, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, +0x20, 0x930, 0x941, 0x92a, 0x92f, 0x93e, 0x3b, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x941, 0x92a, 0x92f, 0x93e, +0x3b, 0x3b, 0x3b, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x941, 0x92a, 0x92f, 0x947, 0x3b, 0x442, 0x4e9, 0x433, +0x440, 0x4e9, 0x433, 0x3b, 0x3b, 0x442, 0x4e9, 0x433, 0x440, 0x4e9, 0x433, 0x3b, 0x3b, 0x3b, 0x3b, 0x442, 0x4e9, 0x433, 0x440, 0x4e9, +0x433, 0x3b, 0x928, 0x947, 0x92a, 0x93e, 0x932, 0x940, 0x20, 0x930, 0x942, 0x92a, 0x948, 0x92f, 0x93e, 0x901, 0x3b, 0x3b, 0x928, 0x947, +0x92a, 0x93e, 0x932, 0x940, 0x20, 0x930, 0x942, 0x92a, 0x948, 0x92f, 0x93e, 0x901, 0x3b, 0x3b, 0x3b, 0x3b, 0x928, 0x947, 0x92a, 0x93e, +0x932, 0x940, 0x20, 0x930, 0x942, 0x92a, 0x948, 0x92f, 0x93e, 0x901, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x942, +0x92a, 0x93f, 0x901, 0x92f, 0x93e, 0x3b, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x942, 0x92a, 0x93f, 0x901, 0x92f, +0x93e, 0x3b, 0x3b, 0x3b, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x942, 0x92a, 0x93f, 0x901, 0x92f, 0x93e, 0x3b, +0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x65, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x72, 0x3b, 0x3b, 0x6e, 0x6f, 0x72, 0x73, 0x6b, +0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x65, 0x20, 0x6b, 0x72, 0x6f, +0x6e, 0x65, 0x72, 0x3b, 0xb2d, 0xb3e, 0xb30, 0xb24, 0xb40, 0xb5f, 0x20, 0xb1f, 0xb19, 0xb4d, 0xb15, 0xb3e, 0x3b, 0x3b, 0xb2d, 0xb3e, +0xb30, 0xb24, 0xb40, 0xb5f, 0x20, 0xb1f, 0xb19, 0xb4d, 0xb15, 0xb3e, 0x3b, 0x3b, 0x3b, 0x3b, 0xb2d, 0xb3e, 0xb30, 0xb24, 0xb40, 0xb5f, +0x20, 0xb1f, 0xb19, 0xb4d, 0xb15, 0xb3e, 0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cd, 0x3b, 0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, +0x6cd, 0x3b, 0x3b, 0x3b, 0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cd, 0x3b, 0x631, 0x6cc, 0x627, 0x644, 0x20, 0x627, 0x6cc, 0x631, +0x627, 0x646, 0x3b, 0x3b, 0x631, 0x6cc, 0x627, 0x644, 0x20, 0x627, 0x6cc, 0x631, 0x627, 0x646, 0x3b, 0x3b, 0x3b, 0x3b, 0x631, 0x6cc, +0x627, 0x644, 0x20, 0x627, 0x6cc, 0x631, 0x627, 0x646, 0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cc, 0x20, 0x627, 0x641, 0x63a, 0x627, +0x646, 0x633, 0x62a, 0x627, 0x646, 0x3b, 0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cc, 0x20, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x633, +0x62a, 0x627, 0x646, 0x3b, 0x3b, 0x3b, 0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cc, 0x20, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x633, +0x62a, 0x627, 0x646, 0x3b, 0x7a, 0x142, 0x6f, 0x74, 0x79, 0x20, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x3b, 0x3b, 0x7a, 0x142, +0x6f, 0x74, 0x79, 0x20, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x3b, 0x3b, 0x7a, 0x142, 0x6f, 0x74, 0x65, 0x20, 0x70, 0x6f, +0x6c, 0x73, 0x6b, 0x69, 0x65, 0x3b, 0x7a, 0x142, 0x6f, 0x74, 0x79, 0x63, 0x68, 0x20, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, +0x63, 0x68, 0x3b, 0x7a, 0x142, 0x6f, 0x74, 0x65, 0x67, 0x6f, 0x20, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x65, 0x67, 0x6f, +0x3b, 0x52, 0x65, 0x61, 0x6c, 0x20, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x3b, 0x52, 0x65, +0x61, 0x6c, 0x20, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x52, 0x65, 0x61, +0x69, 0x73, 0x20, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x65, 0x69, 0x72, 0x6f, 0x73, 0x3b, 0x6b, 0x77, 0x61, 0x6e, 0x7a, +0x61, 0x20, 0x61, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x6b, 0x77, 0x61, 0x6e, 0x7a, 0x61, 0x20, 0x61, +0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x6b, 0x77, 0x61, 0x6e, 0x7a, 0x61, 0x73, 0x20, 0x61, +0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x65, 0x73, 0x63, 0x75, 0x64, 0x6f, 0x20, 0x63, 0x61, 0x62, 0x6f, +0x2d, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x65, 0x73, 0x63, 0x75, 0x64, 0x6f, 0x20, 0x63, 0x61, +0x62, 0x6f, 0x2d, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x73, 0x63, 0x75, 0x64, +0x6f, 0x73, 0x20, 0x63, 0x61, 0x62, 0x6f, 0x2d, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x64, 0xf3, +0x6c, 0x61, 0x72, 0x20, 0x64, 0x6f, 0x73, 0x20, 0x45, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x73, 0x20, 0x55, 0x6e, 0x69, 0x64, +0x6f, 0x73, 0x3b, 0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x20, 0x64, 0x6f, 0x73, 0x20, 0x45, 0x73, 0x74, 0x61, 0x64, 0x6f, +0x73, 0x20, 0x55, 0x6e, 0x69, 0x64, 0x6f, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x65, 0x73, 0x20, +0x64, 0x6f, 0x73, 0x20, 0x45, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x73, 0x20, 0x55, 0x6e, 0x69, 0x64, 0x6f, 0x73, 0x3b, 0x66, +0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x66, 0x72, +0x61, 0x6e, 0x63, 0x6f, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, +0x72, 0x61, 0x6e, 0x63, 0x6f, 0x73, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x66, 0x72, +0x61, 0x6e, 0x63, 0x6f, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x3b, 0x66, 0x72, +0x61, 0x6e, 0x63, 0x6f, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, +0x66, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x73, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, +0x50, 0x61, 0x74, 0x61, 0x63, 0x61, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x3b, 0x3b, 0x50, 0x61, 0x74, +0x61, 0x63, 0x61, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x3b, 0x3b, 0x3b, 0x3b, 0x50, 0x61, 0x74, 0x61, +0x63, 0x61, 0x73, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x3b, 0x6d, 0x65, 0x74, 0x69, 0x63, 0x61, 0x6c, +0x20, 0x6d, 0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x6d, 0x65, 0x74, 0x69, 0x63, 0x61, +0x6c, 0x20, 0x6d, 0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x6d, 0x65, 0x74, +0x69, 0x63, 0x61, 0x69, 0x73, 0x20, 0x6d, 0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x64, +0x6f, 0x62, 0x72, 0x61, 0x20, 0x64, 0x65, 0x20, 0x53, 0xe3, 0x6f, 0x20, 0x54, 0x6f, 0x6d, 0xe9, 0x20, 0x65, 0x20, 0x50, +0x72, 0xed, 0x6e, 0x63, 0x69, 0x70, 0x65, 0x3b, 0x3b, 0x64, 0x6f, 0x62, 0x72, 0x61, 0x20, 0x64, 0x65, 0x20, 0x53, 0xe3, +0x6f, 0x20, 0x54, 0x6f, 0x6d, 0xe9, 0x20, 0x65, 0x20, 0x50, 0x72, 0xed, 0x6e, 0x63, 0x69, 0x70, 0x65, 0x3b, 0x3b, 0x3b, +0x3b, 0x64, 0x6f, 0x62, 0x72, 0x61, 0x73, 0x20, 0x64, 0x65, 0x20, 0x53, 0xe3, 0x6f, 0x20, 0x54, 0x6f, 0x6d, 0xe9, 0x20, +0x65, 0x20, 0x50, 0x72, 0xed, 0x6e, 0x63, 0x69, 0x70, 0x65, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x73, 0x75, +0xed, 0xe7, 0x6f, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x73, 0x75, 0xed, 0xe7, 0x6f, 0x3b, 0x3b, 0x3b, +0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x73, 0x20, 0x73, 0x75, 0xed, 0xe7, 0x6f, 0x73, 0x3b, 0xa2d, 0xa3e, 0xa30, 0xa24, +0xa40, 0x20, 0xa30, 0xa41, 0xa2a, 0xa07, 0xa06, 0x3b, 0x3b, 0xa2d, 0xa3e, 0xa30, 0xa24, 0xa40, 0x20, 0xa30, 0xa41, 0xa2a, 0xa07, 0xa06, +0x3b, 0x3b, 0x3b, 0x3b, 0xa2d, 0xa3e, 0xa30, 0xa24, 0xa40, 0x20, 0xa30, 0xa41, 0xa2a, 0xa0f, 0x3b, 0x631, 0x648, 0x67e, 0x626, 0x6cc, +0x6c1, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x73, 0x76, 0x69, 0x7a, 0x7a, 0x65, +0x72, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x73, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, +0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x73, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x3b, 0x6c, 0x65, 0x75, 0x20, 0x72, 0x6f, +0x6d, 0xe2, 0x6e, 0x65, 0x73, 0x63, 0x3b, 0x3b, 0x6c, 0x65, 0x75, 0x20, 0x72, 0x6f, 0x6d, 0xe2, 0x6e, 0x65, 0x73, 0x63, +0x3b, 0x3b, 0x6c, 0x65, 0x69, 0x20, 0x72, 0x6f, 0x6d, 0xe2, 0x6e, 0x65, 0x219, 0x74, 0x69, 0x3b, 0x3b, 0x6c, 0x65, 0x69, +0x20, 0x72, 0x6f, 0x6d, 0xe2, 0x6e, 0x65, 0x219, 0x74, 0x69, 0x3b, 0x6c, 0x65, 0x75, 0x20, 0x6d, 0x6f, 0x6c, 0x64, 0x6f, +0x76, 0x65, 0x6e, 0x65, 0x73, 0x63, 0x3b, 0x3b, 0x6c, 0x65, 0x75, 0x20, 0x6d, 0x6f, 0x6c, 0x64, 0x6f, 0x76, 0x65, 0x6e, +0x65, 0x73, 0x63, 0x3b, 0x3b, 0x6c, 0x65, 0x69, 0x20, 0x6d, 0x6f, 0x6c, 0x64, 0x6f, 0x76, 0x65, 0x6e, 0x65, 0x219, 0x74, +0x69, 0x3b, 0x3b, 0x6c, 0x65, 0x69, 0x20, 0x6d, 0x6f, 0x6c, 0x64, 0x6f, 0x76, 0x65, 0x6e, 0x65, 0x219, 0x74, 0x69, 0x3b, +0x440, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44c, 0x3b, 0x3b, 0x440, 0x43e, +0x441, 0x441, 0x438, 0x439, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44c, 0x3b, 0x3b, 0x440, 0x43e, 0x441, 0x441, +0x438, 0x439, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44f, 0x3b, 0x440, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x441, +0x43a, 0x438, 0x445, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x435, 0x439, 0x3b, 0x440, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x441, 0x43a, 0x43e, +0x433, 0x43e, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44f, 0x3b, 0x431, 0x435, 0x43b, 0x43e, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x439, +0x20, 0x440, 0x443, 0x431, 0x43b, 0x44c, 0x3b, 0x3b, 0x431, 0x435, 0x43b, 0x43e, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x439, 0x20, +0x440, 0x443, 0x431, 0x43b, 0x44c, 0x3b, 0x3b, 0x431, 0x435, 0x43b, 0x43e, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x440, +0x443, 0x431, 0x43b, 0x44f, 0x3b, 0x431, 0x435, 0x43b, 0x43e, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x440, 0x443, 0x431, +0x43b, 0x435, 0x439, 0x3b, 0x431, 0x435, 0x43b, 0x43e, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x43e, 0x433, 0x43e, 0x20, 0x440, 0x443, 0x431, +0x43b, 0x44f, 0x3b, 0x43a, 0x430, 0x437, 0x430, 0x445, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x442, 0x435, 0x43d, 0x433, 0x435, 0x3b, 0x3b, 0x43a, 0x430, 0x437, 0x430, 0x445, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x442, 0x435, 0x43d, 0x433, 0x435, 0x3b, 0x3b, 0x43a, 0x430, 0x437, -0x430, 0x445, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x442, 0x435, 0x43d, 0x433, 0x435, 0x3b, 0x3b, 0x43a, 0x430, 0x437, 0x430, 0x445, 0x441, -0x43a, 0x438, 0x445, 0x20, 0x442, 0x435, 0x43d, 0x433, 0x435, 0x3b, 0x43a, 0x430, 0x437, 0x430, 0x445, 0x441, 0x43a, 0x438, 0x445, 0x20, -0x442, 0x435, 0x43d, 0x433, 0x435, 0x3b, 0x43a, 0x430, 0x437, 0x430, 0x445, 0x441, 0x43a, 0x43e, 0x433, 0x43e, 0x20, 0x442, 0x435, 0x43d, -0x433, 0x435, 0x3b, 0x43a, 0x438, 0x440, 0x433, 0x438, 0x437, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x441, 0x43e, 0x43c, 0x3b, 0x3b, 0x43a, -0x438, 0x440, 0x433, 0x438, 0x437, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x441, 0x43e, 0x43c, 0x3b, 0x3b, 0x43a, 0x438, 0x440, 0x433, 0x438, -0x437, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x441, 0x43e, 0x43c, 0x430, 0x3b, 0x43a, 0x438, 0x440, 0x433, 0x438, 0x437, 0x441, 0x43a, 0x438, -0x445, 0x20, 0x441, 0x43e, 0x43c, 0x43e, 0x432, 0x3b, 0x43a, 0x438, 0x440, 0x433, 0x438, 0x437, 0x441, 0x43a, 0x43e, 0x433, 0x43e, 0x20, -0x441, 0x43e, 0x43c, 0x430, 0x3b, 0x43c, 0x43e, 0x43b, 0x434, 0x430, 0x432, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x43b, 0x435, 0x439, 0x3b, -0x3b, 0x43c, 0x43e, 0x43b, 0x434, 0x430, 0x432, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x43b, 0x435, 0x439, 0x3b, 0x3b, 0x43c, 0x43e, 0x43b, -0x434, 0x430, 0x432, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x43b, 0x435, 0x44f, 0x3b, 0x43c, 0x43e, 0x43b, 0x434, 0x430, 0x432, 0x441, 0x43a, -0x438, 0x445, 0x20, 0x43b, 0x435, 0x435, 0x432, 0x3b, 0x43c, 0x43e, 0x43b, 0x434, 0x430, 0x432, 0x441, 0x43a, 0x43e, 0x433, 0x43e, 0x20, -0x43b, 0x435, 0x44f, 0x3b, 0x443, 0x43a, 0x440, 0x430, 0x438, 0x43d, 0x441, 0x43a, 0x430, 0x44f, 0x20, 0x433, 0x440, 0x438, 0x432, 0x43d, -0x430, 0x3b, 0x3b, 0x443, 0x43a, 0x440, 0x430, 0x438, 0x43d, 0x441, 0x43a, 0x430, 0x44f, 0x20, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x430, -0x3b, 0x3b, 0x443, 0x43a, 0x440, 0x430, 0x438, 0x43d, 0x441, 0x43a, 0x438, 0x435, 0x20, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x44b, 0x3b, -0x443, 0x43a, 0x440, 0x430, 0x438, 0x43d, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x433, 0x440, 0x438, 0x432, 0x435, 0x43d, 0x3b, 0x443, 0x43a, -0x440, 0x430, 0x438, 0x43d, 0x441, 0x43a, 0x43e, 0x439, 0x20, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x44b, 0x3b, 0x66, 0x61, 0x72, 0xe2, -0x6e, 0x67, 0x61, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, -0x3b, 0x421, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x20, 0x434, 0x438, 0x43d, 0x430, 0x440, 0x3b, 0x3b, 0x441, 0x440, 0x43f, 0x441, 0x43a, -0x438, 0x20, 0x434, 0x438, 0x43d, 0x430, 0x440, 0x3b, 0x3b, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x430, 0x20, 0x434, 0x438, 0x43d, 0x430, -0x440, 0x430, 0x3b, 0x3b, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x434, 0x438, 0x43d, 0x430, 0x440, 0x430, 0x3b, 0x42, +0x430, 0x445, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x442, 0x435, 0x43d, 0x433, 0x435, 0x3b, 0x43a, 0x430, 0x437, 0x430, 0x445, 0x441, 0x43a, +0x438, 0x445, 0x20, 0x442, 0x435, 0x43d, 0x433, 0x435, 0x3b, 0x43a, 0x430, 0x437, 0x430, 0x445, 0x441, 0x43a, 0x43e, 0x433, 0x43e, 0x20, +0x442, 0x435, 0x43d, 0x433, 0x435, 0x3b, 0x43a, 0x438, 0x440, 0x433, 0x438, 0x437, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x441, 0x43e, 0x43c, +0x3b, 0x3b, 0x43a, 0x438, 0x440, 0x433, 0x438, 0x437, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x441, 0x43e, 0x43c, 0x3b, 0x3b, 0x43a, 0x438, +0x440, 0x433, 0x438, 0x437, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x441, 0x43e, 0x43c, 0x430, 0x3b, 0x43a, 0x438, 0x440, 0x433, 0x438, 0x437, +0x441, 0x43a, 0x438, 0x445, 0x20, 0x441, 0x43e, 0x43c, 0x43e, 0x432, 0x3b, 0x43a, 0x438, 0x440, 0x433, 0x438, 0x437, 0x441, 0x43a, 0x43e, +0x433, 0x43e, 0x20, 0x441, 0x43e, 0x43c, 0x430, 0x3b, 0x43c, 0x43e, 0x43b, 0x434, 0x430, 0x432, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x43b, +0x435, 0x439, 0x3b, 0x3b, 0x43c, 0x43e, 0x43b, 0x434, 0x430, 0x432, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x43b, 0x435, 0x439, 0x3b, 0x3b, +0x43c, 0x43e, 0x43b, 0x434, 0x430, 0x432, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x43b, 0x435, 0x44f, 0x3b, 0x43c, 0x43e, 0x43b, 0x434, 0x430, +0x432, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x43b, 0x435, 0x435, 0x432, 0x3b, 0x43c, 0x43e, 0x43b, 0x434, 0x430, 0x432, 0x441, 0x43a, 0x43e, +0x433, 0x43e, 0x20, 0x43b, 0x435, 0x44f, 0x3b, 0x443, 0x43a, 0x440, 0x430, 0x438, 0x43d, 0x441, 0x43a, 0x430, 0x44f, 0x20, 0x433, 0x440, +0x438, 0x432, 0x43d, 0x430, 0x3b, 0x3b, 0x443, 0x43a, 0x440, 0x430, 0x438, 0x43d, 0x441, 0x43a, 0x430, 0x44f, 0x20, 0x433, 0x440, 0x438, +0x432, 0x43d, 0x430, 0x3b, 0x3b, 0x443, 0x43a, 0x440, 0x430, 0x438, 0x43d, 0x441, 0x43a, 0x438, 0x435, 0x20, 0x433, 0x440, 0x438, 0x432, +0x43d, 0x44b, 0x3b, 0x443, 0x43a, 0x440, 0x430, 0x438, 0x43d, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x433, 0x440, 0x438, 0x432, 0x435, 0x43d, +0x3b, 0x443, 0x43a, 0x440, 0x430, 0x438, 0x43d, 0x441, 0x43a, 0x43e, 0x439, 0x20, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x44b, 0x3b, 0x66, +0x61, 0x72, 0xe2, 0x6e, 0x67, 0x61, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x3b, +0x3b, 0x3b, 0x3b, 0x3b, 0x421, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x20, 0x434, 0x438, 0x43d, 0x430, 0x440, 0x3b, 0x3b, 0x441, 0x440, +0x43f, 0x441, 0x43a, 0x438, 0x20, 0x434, 0x438, 0x43d, 0x430, 0x440, 0x3b, 0x3b, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x430, 0x20, 0x434, +0x438, 0x43d, 0x430, 0x440, 0x430, 0x3b, 0x3b, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x434, 0x438, 0x43d, 0x430, 0x440, +0x430, 0x3b, 0x411, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, +0x447, 0x43a, 0x430, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x430, 0x20, 0x43c, 0x430, +0x440, 0x43a, 0x430, 0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, +0x43e, 0x432, 0x430, 0x447, 0x43a, 0x430, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x430, +0x20, 0x43c, 0x430, 0x440, 0x43a, 0x430, 0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, +0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x435, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, +0x43b, 0x43d, 0x435, 0x20, 0x43c, 0x430, 0x440, 0x43a, 0x65, 0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, +0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x438, 0x445, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, +0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x438, 0x445, 0x20, 0x43c, 0x430, 0x440, 0x430, 0x43a, 0x430, 0x3b, 0x415, 0x432, 0x440, 0x43e, +0x3b, 0x3b, 0x435, 0x432, 0x440, 0x43e, 0x3b, 0x3b, 0x435, 0x432, 0x440, 0x430, 0x3b, 0x3b, 0x435, 0x432, 0x440, 0x430, 0x3b, 0x42, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x61, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, @@ -5739,88 +5836,82 @@ static const ushort currency_display_name_data[] = { 0x76, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x76, 0x72, 0x61, 0x3b, 0x3b, 0x65, 0x76, 0x72, 0x61, 0x3b, 0x53, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x3b, 0x3b, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x3b, 0x3b, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x61, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x61, 0x3b, 0x3b, 0x73, -0x72, 0x70, 0x73, 0x6b, 0x69, 0x68, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x61, 0x3b, 0x411, 0x43e, 0x441, 0x430, 0x43d, 0x441, -0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x430, 0x20, 0x43a, 0x43e, 0x43d, 0x432, -0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x430, 0x20, 0x43c, 0x430, 0x440, 0x43a, 0x430, 0x3b, 0x3b, 0x431, 0x43e, 0x441, -0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x430, 0x20, 0x43a, -0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x430, 0x20, 0x43c, 0x430, 0x440, 0x43a, 0x430, 0x3b, 0x3b, -0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, -0x435, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x435, 0x20, 0x43c, 0x430, 0x440, 0x43a, -0x65, 0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, -0x430, 0x447, 0x43a, 0x438, 0x445, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x438, 0x445, -0x20, 0x43c, 0x430, 0x440, 0x430, 0x43a, 0x430, 0x3b, 0x415, 0x432, 0x440, 0x43e, 0x3b, 0x3b, 0x435, 0x432, 0x440, 0x43e, 0x3b, 0x3b, -0x435, 0x432, 0x440, 0x430, 0x3b, 0x3b, 0x435, 0x432, 0x440, 0x430, 0x3b, 0x41b, 0x430, 0x440, 0x3b, 0x3b, 0x43b, 0x430, 0x440, 0x3b, -0x3b, 0x3b, 0x3b, 0x43b, 0x430, 0x440, 0x44b, 0x3b, 0x421, 0x43e, 0x43c, 0x3b, 0x3b, 0x441, 0x43e, 0x43c, 0x3b, 0x3b, 0x3b, 0x3b, -0x441, 0x43e, 0x43c, 0x44b, 0x3b, 0x44, 0x6f, 0x72, 0x61, 0x20, 0x72, 0x65, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x6b, 0x61, -0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x67e, 0x627, 0x6aa, 0x633, 0x62a, 0x627, 0x646, 0x64a, 0x20, 0x631, 0x67e, 0x64a, 0x3b, -0x3b, 0x67e, 0x627, 0x6aa, 0x633, 0x62a, 0x627, 0x646, 0x64a, 0x20, 0x631, 0x67e, 0x64a, 0x3b, 0x3b, 0x3b, 0x3b, 0x67e, 0x627, 0x6aa, -0x633, 0x62a, 0x627, 0x646, 0x64a, 0x20, 0x631, 0x67e, 0x64a, 0x3b, 0xdc1, 0xdca, 0x200d, 0xdbb, 0xdd3, 0x20, 0xdbd, 0xd82, 0xd9a, 0xdcf, -0x20, 0xdbb, 0xdd4, 0xdb4, 0xdd2, 0xdba, 0xdbd, 0x3b, 0x3b, 0xdc1, 0xdca, 0x200d, 0xdbb, 0xdd3, 0x20, 0xdbd, 0xd82, 0xd9a, 0xdcf, 0x20, -0xdbb, 0xdd4, 0xdb4, 0xdd2, 0xdba, 0xdbd, 0x3b, 0x3b, 0x3b, 0x3b, 0xdc1, 0xdca, 0x200d, 0xdbb, 0xdd3, 0x20, 0xdbd, 0xd82, 0xd9a, 0xdcf, -0x20, 0xdbb, 0xdd4, 0xdb4, 0xdd2, 0xdba, 0xdbd, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, -0x65, 0x75, 0x72, 0xe1, 0x3b, 0x65, 0x75, 0x72, 0x61, 0x3b, 0x65, 0x75, 0x72, 0x3b, 0x65, 0x76, 0x72, 0x6f, 0x3b, 0x3b, -0x65, 0x76, 0x72, 0x6f, 0x3b, 0x65, 0x76, 0x72, 0x61, 0x3b, 0x65, 0x76, 0x72, 0x69, 0x3b, 0x3b, 0x65, 0x76, 0x72, 0x6f, -0x76, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x20, 0x73, 0x6f, 0x6f, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x3b, 0x3b, 0x3b, -0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x61, 0x72, 0x61, 0x6e, 0x20, 0x4a, 0x61, 0x62, 0x62, 0x75, 0x75, 0x74, 0x69, 0x3b, 0x3b, -0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x69, 0x72, 0x74, 0x61, 0x20, 0x49, 0x74, 0x6f, 0x6f, 0x62, 0x62, 0x69, 0x79, 0x61, -0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x61, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, -0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x61, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, -0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x61, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x6f, 0x73, 0x3b, 0x64, 0xf3, -0x6c, 0x61, 0x72, 0x20, 0x62, 0x65, 0x6c, 0x69, 0x63, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x20, -0x62, 0x65, 0x6c, 0x69, 0x63, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x65, 0x73, 0x20, -0x62, 0x65, 0x6c, 0x69, 0x63, 0x65, 0xf1, 0x6f, 0x73, 0x3b, 0x62, 0x6f, 0x6c, 0x69, 0x76, 0x69, 0x61, 0x6e, 0x6f, 0x3b, -0x3b, 0x62, 0x6f, 0x6c, 0x69, 0x76, 0x69, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x62, 0x6f, 0x6c, 0x69, 0x76, 0x69, -0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x72, 0x65, 0x61, 0x6c, 0x20, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x65, 0xf1, 0x6f, 0x3b, -0x3b, 0x72, 0x65, 0x61, 0x6c, 0x20, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x72, -0x65, 0x61, 0x6c, 0x65, 0x73, 0x20, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x65, 0xf1, 0x6f, 0x73, 0x3b, 0x50, 0x65, 0x73, -0x6f, 0x20, 0x63, 0x68, 0x69, 0x6c, 0x65, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x63, 0x68, 0x69, 0x6c, -0x65, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x63, 0x68, 0x69, 0x6c, 0x65, 0x6e, 0x6f, -0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, -0x65, 0x73, 0x6f, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, -0x73, 0x6f, 0x73, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x63, 0x6f, 0x6c, 0xf3, -0x6e, 0x20, 0x63, 0x6f, 0x73, 0x74, 0x61, 0x72, 0x72, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x3b, 0x63, 0x6f, 0x6c, -0xf3, 0x6e, 0x20, 0x63, 0x6f, 0x73, 0x74, 0x61, 0x72, 0x72, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, -0x63, 0x6f, 0x6c, 0x6f, 0x6e, 0x65, 0x73, 0x20, 0x63, 0x6f, 0x73, 0x74, 0x61, 0x72, 0x72, 0x69, 0x63, 0x65, 0x6e, 0x73, -0x65, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x63, 0x75, 0x62, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, -0x20, 0x63, 0x75, 0x62, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x63, 0x75, 0x62, -0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x6e, 0x6f, -0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, -0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x64, -0xf3, 0x6c, 0x61, 0x72, 0x20, 0x65, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x75, 0x6e, 0x69, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x3b, -0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x20, 0x65, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x75, 0x6e, 0x69, 0x64, 0x65, 0x6e, 0x73, -0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x65, 0x73, 0x20, 0x65, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x75, -0x6e, 0x69, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x43, 0x46, 0x41, 0x20, -0x64, 0x65, 0x20, 0xc1, 0x66, 0x72, 0x69, 0x63, 0x61, 0x20, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x3b, 0x3b, 0x66, -0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x43, 0x46, 0x41, 0x20, 0x64, 0x65, 0x20, 0xc1, 0x66, 0x72, 0x69, 0x63, 0x61, 0x20, -0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x73, 0x20, 0x43, -0x46, 0x41, 0x20, 0x64, 0x65, 0x20, 0xc1, 0x66, 0x72, 0x69, 0x63, 0x61, 0x20, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, -0x3b, 0x71, 0x75, 0x65, 0x74, 0x7a, 0x61, 0x6c, 0x3b, 0x3b, 0x71, 0x75, 0x65, 0x74, 0x7a, 0x61, 0x6c, 0x3b, 0x3b, 0x3b, -0x3b, 0x71, 0x75, 0x65, 0x74, 0x7a, 0x61, 0x6c, 0x65, 0x73, 0x3b, 0x6c, 0x65, 0x6d, 0x70, 0x69, 0x72, 0x61, 0x20, 0x68, -0x6f, 0x6e, 0x64, 0x75, 0x72, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x6c, 0x65, 0x6d, 0x70, 0x69, 0x72, 0x61, 0x20, 0x68, 0x6f, -0x6e, 0x64, 0x75, 0x72, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x6c, 0x65, 0x6d, 0x70, 0x69, 0x72, 0x61, 0x73, 0x20, -0x68, 0x6f, 0x6e, 0x64, 0x75, 0x72, 0x65, 0xf1, 0x6f, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x6d, 0x65, 0x78, 0x69, -0x63, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x6d, 0x65, 0x78, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x3b, -0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x6d, 0x65, 0x78, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x63, -0xf3, 0x72, 0x64, 0x6f, 0x62, 0x61, 0x20, 0x6e, 0x69, 0x63, 0x61, 0x72, 0x61, 0x67, 0xfc, 0x65, 0x6e, 0x73, 0x65, 0x3b, -0x3b, 0x63, 0xf3, 0x72, 0x64, 0x6f, 0x62, 0x61, 0x20, 0x6e, 0x69, 0x63, 0x61, 0x72, 0x61, 0x67, 0xfc, 0x65, 0x6e, 0x73, -0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x63, 0xf3, 0x72, 0x64, 0x6f, 0x62, 0x61, 0x73, 0x20, 0x6e, 0x69, 0x63, 0x61, 0x72, 0x61, -0x67, 0xfc, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x3b, 0x62, 0x61, 0x6c, 0x62, 0x6f, 0x61, 0x20, 0x70, 0x61, 0x6e, 0x61, 0x6d, -0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x62, 0x61, 0x6c, 0x62, 0x6f, 0x61, 0x20, 0x70, 0x61, 0x6e, 0x61, 0x6d, 0x65, 0xf1, 0x6f, -0x3b, 0x3b, 0x3b, 0x3b, 0x62, 0x61, 0x6c, 0x62, 0x6f, 0x61, 0x73, 0x20, 0x70, 0x61, 0x6e, 0x61, 0x6d, 0x65, 0xf1, 0x6f, -0x73, 0x3b, 0x67, 0x75, 0x61, 0x72, 0x61, 0x6e, 0xed, 0x20, 0x70, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x79, 0x6f, 0x3b, -0x3b, 0x67, 0x75, 0x61, 0x72, 0x61, 0x6e, 0xed, 0x20, 0x70, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x79, 0x6f, 0x3b, 0x3b, -0x3b, 0x3b, 0x67, 0x75, 0x61, 0x72, 0x61, 0x6e, 0xed, 0x65, 0x73, 0x20, 0x70, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x79, -0x6f, 0x73, 0x3b, 0x73, 0x6f, 0x6c, 0x20, 0x70, 0x65, 0x72, 0x75, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x73, 0x6f, 0x6c, 0x20, -0x70, 0x65, 0x72, 0x75, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x6f, 0x6c, 0x65, 0x73, 0x20, 0x70, 0x65, 0x72, -0x75, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x66, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x6f, 0x3b, -0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x66, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, -0x73, 0x6f, 0x73, 0x20, 0x66, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x6f, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x75, -0x72, 0x75, 0x67, 0x75, 0x61, 0x79, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x75, 0x72, 0x75, 0x67, 0x75, 0x61, -0x79, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x75, 0x72, 0x75, 0x67, 0x75, 0x61, 0x79, 0x6f, -0x73, 0x3b, 0x62, 0x6f, 0x6c, 0xed, 0x76, 0x61, 0x72, 0x20, 0x76, 0x65, 0x6e, 0x65, 0x7a, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, -0x3b, 0x3b, 0x62, 0x6f, 0x6c, 0xed, 0x76, 0x61, 0x72, 0x20, 0x76, 0x65, 0x6e, 0x65, 0x7a, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, -0x3b, 0x3b, 0x3b, 0x3b, 0x62, 0x6f, 0x6c, 0xed, 0x76, 0x61, 0x72, 0x65, 0x73, 0x20, 0x76, 0x65, 0x6e, 0x65, 0x7a, 0x6f, -0x6c, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61, +0x72, 0x70, 0x73, 0x6b, 0x69, 0x68, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x61, 0x3b, 0x41b, 0x430, 0x440, 0x3b, 0x3b, 0x43b, +0x430, 0x440, 0x3b, 0x3b, 0x3b, 0x3b, 0x43b, 0x430, 0x440, 0x44b, 0x3b, 0x421, 0x43e, 0x43c, 0x3b, 0x3b, 0x441, 0x43e, 0x43c, 0x3b, +0x3b, 0x3b, 0x3b, 0x441, 0x43e, 0x43c, 0x44b, 0x3b, 0x44, 0x6f, 0x72, 0x61, 0x20, 0x72, 0x65, 0x20, 0x41, 0x6d, 0x65, 0x72, +0x69, 0x6b, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x67e, 0x627, 0x6aa, 0x633, 0x62a, 0x627, 0x646, 0x64a, 0x20, 0x631, +0x67e, 0x64a, 0x3b, 0x3b, 0x67e, 0x627, 0x6aa, 0x633, 0x62a, 0x627, 0x646, 0x64a, 0x20, 0x631, 0x67e, 0x64a, 0x3b, 0x3b, 0x3b, 0x3b, +0x67e, 0x627, 0x6aa, 0x633, 0x62a, 0x627, 0x646, 0x64a, 0x20, 0x631, 0x67e, 0x64a, 0x3b, 0xdc1, 0xdca, 0x200d, 0xdbb, 0xdd3, 0x20, 0xdbd, +0xd82, 0xd9a, 0xdcf, 0x20, 0xdbb, 0xdd4, 0xdb4, 0xdd2, 0xdba, 0xdbd, 0x3b, 0x3b, 0xdc1, 0xdca, 0x200d, 0xdbb, 0xdd3, 0x20, 0xdbd, 0xd82, +0xd9a, 0xdcf, 0x20, 0xdbb, 0xdd4, 0xdb4, 0xdd2, 0xdba, 0xdbd, 0x3b, 0x3b, 0x3b, 0x3b, 0xdc1, 0xdca, 0x200d, 0xdbb, 0xdd3, 0x20, 0xdbd, +0xd82, 0xd9a, 0xdcf, 0x20, 0xdbb, 0xdd4, 0xdb4, 0xdd2, 0xdba, 0xdbd, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, +0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0xe1, 0x3b, 0x65, 0x75, 0x72, 0x61, 0x3b, 0x65, 0x75, 0x72, 0x3b, 0x65, 0x76, 0x72, +0x6f, 0x3b, 0x3b, 0x65, 0x76, 0x72, 0x6f, 0x3b, 0x65, 0x76, 0x72, 0x61, 0x3b, 0x65, 0x76, 0x72, 0x69, 0x3b, 0x3b, 0x65, +0x76, 0x72, 0x6f, 0x76, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x6b, 0x61, 0x20, 0x53, 0x6f, 0x6f, 0x6d, 0x61, +0x61, 0x6c, 0x69, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x61, 0x72, 0x61, 0x6e, 0x20, 0x4a, 0x61, +0x62, 0x62, 0x75, 0x75, 0x74, 0x69, 0x3b, 0x3b, 0x46, 0x61, 0x72, 0x61, 0x6e, 0x6b, 0x20, 0x4a, 0x61, 0x62, 0x75, 0x75, +0x74, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x61, 0x72, 0x61, 0x6e, 0x6b, 0x20, 0x4a, 0x61, 0x62, 0x75, 0x75, 0x74, 0x69, +0x3b, 0x42, 0x69, 0x72, 0x74, 0x61, 0x20, 0x49, 0x74, 0x6f, 0x6f, 0x62, 0x62, 0x69, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, +0x3b, 0x3b, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x6b, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, +0x53, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x68, 0x69, +0x6c, 0x69, 0x6e, 0x67, 0x6b, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x61, 0x72, +0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x61, 0x72, 0x67, 0x65, 0x6e, 0x74, +0x69, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x61, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, +0x6e, 0x6f, 0x73, 0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x20, 0x62, 0x65, 0x6c, 0x69, 0x63, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, +0x64, 0xf3, 0x6c, 0x61, 0x72, 0x20, 0x62, 0x65, 0x6c, 0x69, 0x63, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0xf3, +0x6c, 0x61, 0x72, 0x65, 0x73, 0x20, 0x62, 0x65, 0x6c, 0x69, 0x63, 0x65, 0xf1, 0x6f, 0x73, 0x3b, 0x62, 0x6f, 0x6c, 0x69, +0x76, 0x69, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x62, 0x6f, 0x6c, 0x69, 0x76, 0x69, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, +0x62, 0x6f, 0x6c, 0x69, 0x76, 0x69, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x72, 0x65, 0x61, 0x6c, 0x20, 0x62, 0x72, 0x61, 0x73, +0x69, 0x6c, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x72, 0x65, 0x61, 0x6c, 0x20, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x65, 0xf1, +0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x72, 0x65, 0x61, 0x6c, 0x65, 0x73, 0x20, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x65, 0xf1, +0x6f, 0x73, 0x3b, 0x50, 0x65, 0x73, 0x6f, 0x20, 0x63, 0x68, 0x69, 0x6c, 0x65, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, +0x6f, 0x20, 0x63, 0x68, 0x69, 0x6c, 0x65, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x63, +0x68, 0x69, 0x6c, 0x65, 0x6e, 0x6f, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x69, +0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x6f, +0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x6f, +0x73, 0x3b, 0x63, 0x6f, 0x6c, 0xf3, 0x6e, 0x20, 0x63, 0x6f, 0x73, 0x74, 0x61, 0x72, 0x72, 0x69, 0x63, 0x65, 0x6e, 0x73, +0x65, 0x3b, 0x3b, 0x63, 0x6f, 0x6c, 0xf3, 0x6e, 0x20, 0x63, 0x6f, 0x73, 0x74, 0x61, 0x72, 0x72, 0x69, 0x63, 0x65, 0x6e, +0x73, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x6e, 0x65, 0x73, 0x20, 0x63, 0x6f, 0x73, 0x74, 0x61, 0x72, +0x72, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x63, 0x75, 0x62, 0x61, 0x6e, 0x6f, +0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x63, 0x75, 0x62, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, +0x6f, 0x73, 0x20, 0x63, 0x75, 0x62, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x64, 0x6f, 0x6d, 0x69, +0x6e, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, +0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, +0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x20, 0x65, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x75, 0x6e, 0x69, +0x64, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x20, 0x65, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x75, +0x6e, 0x69, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x65, 0x73, 0x20, 0x65, +0x73, 0x74, 0x61, 0x64, 0x6f, 0x75, 0x6e, 0x69, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, +0x6f, 0x20, 0x43, 0x46, 0x41, 0x20, 0x64, 0x65, 0x20, 0xc1, 0x66, 0x72, 0x69, 0x63, 0x61, 0x20, 0x43, 0x65, 0x6e, 0x74, +0x72, 0x61, 0x6c, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x43, 0x46, 0x41, 0x20, 0x64, 0x65, 0x20, 0xc1, +0x66, 0x72, 0x69, 0x63, 0x61, 0x20, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, +0x6e, 0x63, 0x6f, 0x73, 0x20, 0x43, 0x46, 0x41, 0x20, 0x64, 0x65, 0x20, 0xc1, 0x66, 0x72, 0x69, 0x63, 0x61, 0x20, 0x43, +0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x3b, 0x71, 0x75, 0x65, 0x74, 0x7a, 0x61, 0x6c, 0x3b, 0x3b, 0x71, 0x75, 0x65, 0x74, +0x7a, 0x61, 0x6c, 0x3b, 0x3b, 0x3b, 0x3b, 0x71, 0x75, 0x65, 0x74, 0x7a, 0x61, 0x6c, 0x65, 0x73, 0x3b, 0x6c, 0x65, 0x6d, +0x70, 0x69, 0x72, 0x61, 0x20, 0x68, 0x6f, 0x6e, 0x64, 0x75, 0x72, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x6c, 0x65, 0x6d, 0x70, +0x69, 0x72, 0x61, 0x20, 0x68, 0x6f, 0x6e, 0x64, 0x75, 0x72, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x6c, 0x65, 0x6d, +0x70, 0x69, 0x72, 0x61, 0x73, 0x20, 0x68, 0x6f, 0x6e, 0x64, 0x75, 0x72, 0x65, 0xf1, 0x6f, 0x73, 0x3b, 0x70, 0x65, 0x73, +0x6f, 0x20, 0x6d, 0x65, 0x78, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x6d, 0x65, 0x78, +0x69, 0x63, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x6d, 0x65, 0x78, 0x69, 0x63, +0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x63, 0xf3, 0x72, 0x64, 0x6f, 0x62, 0x61, 0x20, 0x6e, 0x69, 0x63, 0x61, 0x72, 0x61, 0x67, +0xfc, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x3b, 0x63, 0xf3, 0x72, 0x64, 0x6f, 0x62, 0x61, 0x20, 0x6e, 0x69, 0x63, 0x61, 0x72, +0x61, 0x67, 0xfc, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x63, 0xf3, 0x72, 0x64, 0x6f, 0x62, 0x61, 0x73, 0x20, +0x6e, 0x69, 0x63, 0x61, 0x72, 0x61, 0x67, 0xfc, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x3b, 0x62, 0x61, 0x6c, 0x62, 0x6f, 0x61, +0x20, 0x70, 0x61, 0x6e, 0x61, 0x6d, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x62, 0x61, 0x6c, 0x62, 0x6f, 0x61, 0x20, 0x70, 0x61, +0x6e, 0x61, 0x6d, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x62, 0x61, 0x6c, 0x62, 0x6f, 0x61, 0x73, 0x20, 0x70, 0x61, +0x6e, 0x61, 0x6d, 0x65, 0xf1, 0x6f, 0x73, 0x3b, 0x67, 0x75, 0x61, 0x72, 0x61, 0x6e, 0xed, 0x20, 0x70, 0x61, 0x72, 0x61, +0x67, 0x75, 0x61, 0x79, 0x6f, 0x3b, 0x3b, 0x67, 0x75, 0x61, 0x72, 0x61, 0x6e, 0xed, 0x20, 0x70, 0x61, 0x72, 0x61, 0x67, +0x75, 0x61, 0x79, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x67, 0x75, 0x61, 0x72, 0x61, 0x6e, 0xed, 0x65, 0x73, 0x20, 0x70, 0x61, +0x72, 0x61, 0x67, 0x75, 0x61, 0x79, 0x6f, 0x73, 0x3b, 0x73, 0x6f, 0x6c, 0x20, 0x70, 0x65, 0x72, 0x75, 0x61, 0x6e, 0x6f, +0x3b, 0x3b, 0x73, 0x6f, 0x6c, 0x20, 0x70, 0x65, 0x72, 0x75, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x6f, 0x6c, +0x65, 0x73, 0x20, 0x70, 0x65, 0x72, 0x75, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x66, 0x69, 0x6c, +0x69, 0x70, 0x69, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x66, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x6f, +0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x66, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x6f, 0x73, 0x3b, +0x70, 0x65, 0x73, 0x6f, 0x20, 0x75, 0x72, 0x75, 0x67, 0x75, 0x61, 0x79, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, +0x75, 0x72, 0x75, 0x67, 0x75, 0x61, 0x79, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x75, 0x72, +0x75, 0x67, 0x75, 0x61, 0x79, 0x6f, 0x73, 0x3b, 0x62, 0x6f, 0x6c, 0xed, 0x76, 0x61, 0x72, 0x20, 0x73, 0x6f, 0x62, 0x65, +0x72, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x62, 0x6f, 0x6c, 0xed, 0x76, 0x61, 0x72, 0x20, 0x73, 0x6f, 0x62, 0x65, 0x72, 0x61, +0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x62, 0x6f, 0x6c, 0xed, 0x76, 0x61, 0x72, 0x65, 0x73, 0x20, 0x73, 0x6f, 0x62, 0x65, +0x72, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x73, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x7a, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x46, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x61, @@ -5883,126 +5974,134 @@ static const ushort currency_display_name_data[] = { 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x20, 0x62, 0x75, 0x20, 0x41, 0x66, 0x72, 0x69, 0x6b, 0x20, 0x53, 0x6f, 0x77, 0x77, 0x75, 0x2d, 0x6a, 0x61, 0x6e, 0x74, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x20, 0x79, 0x75, 0x20, 0x41, 0x66, 0x72, 0x69, 0x6b, 0x20, 0x53, 0x6f, 0x77, 0x77, 0x75, 0x2d, 0x6a, 0x61, 0x6e, -0x74, 0x3b, 0x4e, 0x61, 0x69, 0x72, 0x61, 0x20, 0x74, 0x69, 0x20, 0x4f, 0x72, 0xed, 0x6c, 0x1eb9, 0x301, 0xe8, 0x64, 0x65, -0x20, 0x4e, 0xe0, 0xec, 0x6a, 0xed, 0x72, 0xed, 0xe0, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x61, 0x72, 0x61, -0x6e, 0x73, 0x69, 0x20, 0x74, 0x69, 0x20, 0x4f, 0x72, 0xed, 0x6c, 0x25b, 0x301, 0xe8, 0x64, 0x65, 0x20, 0x42, 0x49, 0x4b, -0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x69, 0x2d, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, -0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x52, 0x61, 0x6e, 0x64, 0x3b, 0x3b, 0x69, 0x2d, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, -0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x52, 0x61, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x69, 0x2d, 0x53, 0x6f, -0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x52, 0x61, 0x6e, 0x64, 0x3b, 0x42, 0x6f, 0x73, -0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x61, 0x20, 0x6b, 0x6f, -0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x62, -0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x61, 0x20, -0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, -0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, -0x65, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x6b, -0x65, 0x3b, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, -0x10d, 0x6b, 0x69, 0x68, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20, -0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b, 0x41a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x430, -0x20, 0x43c, 0x430, 0x440, 0x43a, 0x430, 0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, -0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x430, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, -0x43b, 0x43d, 0x430, 0x20, 0x43c, 0x430, 0x440, 0x43a, 0x430, 0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, -0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x435, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, -0x438, 0x431, 0x438, 0x43b, 0x43d, 0x435, 0x20, 0x43c, 0x430, 0x440, 0x43a, 0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, -0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x438, 0x445, 0x20, 0x43a, 0x43e, 0x43d, 0x432, -0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x438, 0x445, 0x20, 0x43c, 0x430, 0x440, 0x430, 0x43a, 0x430, 0x3b, 0x47, 0x68, -0x61, 0x6e, 0x61, 0x20, 0x53, 0x69, 0x64, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x4e, 0x52, 0x3b, 0x3b, -0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x4e, 0x52, 0x3b, 0x4e, 0x61, 0x1ecb, 0x72, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, -0x53, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, -0x3b, 0x3b, 0x3b, 0x67, 0x68, 0x61, 0x6e, 0x61, 0x20, 0x73, 0x69, 0x256, 0x69, 0x3b, 0x3b, 0x67, 0x68, 0x61, 0x6e, 0x61, -0x20, 0x73, 0x69, 0x256, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x67, 0x68, 0x61, 0x6e, 0x61, 0x20, 0x73, 0x69, 0x256, 0x69, 0x3b, -0x263, 0x65, 0x74, 0x6f, 0x256, 0x6f, 0x66, 0x65, 0x20, 0x61, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x67, 0x61, 0x20, 0x43, 0x46, -0x41, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x263, 0x65, 0x74, 0x6f, 0x256, -0x6f, 0x66, 0x65, 0x20, 0x61, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x67, 0x61, 0x20, 0x43, 0x46, 0x41, 0x20, 0x66, 0x72, 0x61, -0x6e, 0x63, 0x20, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x3b, 0x3b, 0x263, 0x65, 0x74, 0x6f, 0x256, 0x6f, 0x66, 0x65, -0x20, 0x61, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x67, 0x61, 0x20, 0x43, 0x46, 0x41, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, -0x42, 0x43, 0x45, 0x41, 0x4f, 0x3b, 0x50, 0x69, 0x73, 0x6f, 0x20, 0x6e, 0x67, 0x20, 0x50, 0x69, 0x6c, 0x69, 0x70, 0x69, -0x6e, 0x61, 0x73, 0x3b, 0x3b, 0x70, 0x69, 0x73, 0x6f, 0x20, 0x6e, 0x67, 0x20, 0x50, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, -0x61, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x69, 0x73, 0x6f, 0x20, 0x6e, 0x67, 0x20, 0x50, 0x69, 0x6c, 0x69, 0x70, 0x69, -0x6e, 0x61, 0x73, 0x3b, 0x53, 0x63, 0x68, 0x77, 0x69, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, -0x3b, 0x3b, 0x53, 0x63, 0x68, 0x77, 0x69, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x3b, 0x3b, -0x3b, 0x3b, 0x53, 0x63, 0x68, 0x77, 0x69, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x3b, 0x45, -0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x6e, 0x6f, 0x72, 0x67, 0x67, 0x61, -0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x3b, 0x6e, 0x6f, 0x72, 0x67, 0x67, 0x61, 0x20, 0x6b, 0x72, 0x75, -0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x6e, 0x6f, 0x72, 0x67, 0x67, 0x61, 0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e, 0x6f, 0x3b, -0x3b, 0x3b, 0x6e, 0x6f, 0x72, 0x67, 0x67, 0x61, 0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x65, 0x75, 0x72, -0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, -0x72, 0x75, 0x6f, 0x167, 0x167, 0x61, 0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x3b, 0x72, 0x75, 0x6f, 0x167, -0x167, 0x61, 0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x72, 0x75, 0x6f, 0x167, 0x167, 0x61, 0x20, 0x6b, 0x72, -0x75, 0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x72, 0x75, 0x6f, 0x167, 0x167, 0x61, 0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, -0x6e, 0x6f, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, -0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x62, 0x75, 0x75, 0x257, 0x75, 0x20, 0x53, 0x65, 0x65, 0x66, 0x61, 0x61, -0x20, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x62, 0x75, 0x75, 0x257, 0x69, 0x20, -0x53, 0x65, 0x65, 0x66, 0x61, 0x61, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x67, -0x69, 0x79, 0x79, 0x61, 0x20, 0x4d, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, -0x43, 0x69, 0x72, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, -0x3b, 0x3b, 0x3b, 0x4e, 0x6a, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x65, 0x65, 0x6c, 0x20, 0x4b, 0x65, 0x6e, 0x79, -0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x65, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x64, 0x65, 0x20, 0x4d, -0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69, 0x71, 0x75, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x6f, 0x6c, 0x61, -0x20, 0x79, 0x61, 0x73, 0x65, 0x20, 0x41, 0x6d, 0x65, 0x6c, 0x69, 0x6b, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, -0x68, 0x65, 0x6c, 0x65, 0x72, 0x69, 0x20, 0x73, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, -0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x2d30, 0x2d37, 0x2d54, 0x2d49, 0x2d4e, 0x20, 0x2d4f, 0x20, 0x2d4d, 0x2d4e, 0x2d56, 0x2d54, 0x2d49, 0x2d31, 0x3b, -0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x61, 0x64, 0x72, 0x69, 0x6d, 0x20, 0x6e, 0x20, 0x6c, 0x6d, 0x263, 0x72, 0x69, 0x62, -0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x41, 0x7a, 0x7a, 0x61, 0x79, 0x72, -0x69, 0x3b, 0x3b, 0x41, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x6e, 0x20, 0x5a, 0x7a, 0x61, 0x79, 0x65, 0x72, 0x3b, 0x3b, -0x3b, 0x3b, 0x49, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x65, 0x6e, 0x20, 0x6e, 0x20, 0x5a, 0x7a, 0x61, 0x79, 0x65, 0x72, 0x3b, -0x45, 0x73, 0x68, 0x69, 0x72, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x3b, -0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x48, 0x75, -0x74, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0x69, -0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, -0x3b, 0x3b, 0x73, 0x65, 0x66, 0x61, 0x20, 0x46, 0x72, 0x61, 0x14b, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, -0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x53, 0x20, 0x13a0, 0x13d5, 0x13b3, 0x3b, 0x3b, 0x55, 0x53, 0x20, 0x13a0, 0x13d5, 0x13b3, -0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x53, 0x20, 0x13a0, 0x13d5, 0x13b3, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x20, 0x6d, 0x6f, 0x72, -0x69, 0x73, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0xed, 0x69, 0x6e, 0x67, -0x69, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0xed, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, -0x3b, 0x53, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x65, 0x79, 0x61, 0x20, 0x59, 0x75, 0x67, 0x61, 0x6e, 0x64, 0x61, -0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x6b, 0x75, 0x64, 0x75, 0x20, 0x4b, 0x61, 0x62, 0x75, 0x76, 0x65, 0x72, -0x64, 0x69, 0x61, 0x6e, 0x75, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x6b, 0x75, 0x64, 0x75, 0x20, 0x4b, 0x61, 0x62, -0x75, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x75, 0x3b, 0x53, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x74, 0x61, 0x62, -0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x61, 0x6d, 0x69, -0x62, 0x69, 0x61, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, -0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x72, 0x6f, 0x70, 0x69, 0x79, 0x69, 0x61, 0x6e, 0xed, 0x20, -0x65, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x72, 0x6f, 0x70, 0x69, 0x79, -0x69, 0x61, 0x6e, 0xed, 0x20, 0x65, 0x20, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, -0x3b, 0x3b, 0x53, 0x69, 0x72, 0x69, 0x6e, 0x6a, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, -0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x6e, -0x64, 0x68, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x6e, 0x67, 0x6f, 0x2019, 0x6f, 0x74, -0x6f, 0x6c, 0x20, 0x6c, 0x6f, 0x6b, 0x2019, 0x20, 0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, -0x3b, 0x41, 0x6e, 0x67, 0x6f, 0x2019, 0x6f, 0x74, 0x6f, 0x6c, 0x20, 0x6c, 0x6f, 0x6b, 0x2019, 0x20, 0x4b, 0x65, 0x6e, 0x79, -0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x46, 0x41, 0x20, 0x46, 0x72, 0x61, 0x14b, 0x20, 0x28, 0x42, 0x43, -0x45, 0x41, 0x4f, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x61, -0x72, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x65, 0x72, 0x68, 0x65, 0x6d, -0x20, 0x55, 0x6d, 0x65, 0x1e5b, 0x1e5b, 0x75, 0x6b, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x68, 0x69, 0x6c, -0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, -0x3b, 0x3b, 0x3b, 0x930, 0x93e, 0x902, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x420, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x43d, -0x20, 0x441, 0x43e, 0x43c, 0x3b, 0x3b, 0x420, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x43d, 0x20, 0x441, 0x43e, 0x43c, 0x3b, 0x3b, 0x3b, -0x3b, 0x420, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x43d, 0x20, 0x441, 0x43e, 0x44c, 0x43c, 0x430, 0x448, 0x3b, 0x440, 0x461, 0x441, 0x441, -0x456, 0x301, 0x439, 0x441, 0x43a, 0x457, 0x439, 0x20, 0x440, 0xa64b, 0x301, 0x431, 0x43b, 0x44c, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, -0x440, 0x461, 0x441, 0x441, 0x456, 0x301, 0x439, 0x441, 0x43a, 0x430, 0x433, 0x461, 0x20, 0x440, 0xa64b, 0x431, 0x43b, 0x467, 0x300, 0x3b, -0x4e, 0x66, 0x61, 0x6c, 0x61, 0x6e, 0x67, 0x61, 0x20, 0x77, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x75, 0x3b, 0x3b, 0x3b, -0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x46, 0x41, 0x20, 0x46, 0xe0, 0x6c, 0xe2, 0x14b, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, -0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x72, 0x1ce, 0x14b, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, -0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x65, 0x65, 0x66, 0x61, 0x20, 0x79, 0x61, 0x74, 0x69, 0x20, 0x42, 0x43, -0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x259, 0x6c, 0xe1, 0x14b, 0x20, 0x43, 0x46, 0x41, 0x20, -0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0xe1, 0x14b, 0x3b, 0x3b, 0x3b, -0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x6f, 0x6c, 0x61, 0x69, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, -0x3b, 0x46, 0x72, 0x61, 0x14b, 0x20, 0x43, 0x46, 0x41, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, -0x3b, 0x410, 0x440, 0x430, 0x441, 0x441, 0x44b, 0x44b, 0x439, 0x430, 0x20, 0x441, 0x43e, 0x43b, 0x43a, 0x443, 0x43e, 0x431, 0x430, 0x439, -0x430, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x410, 0x440, 0x430, 0x441, 0x441, 0x44b, 0x44b, 0x439, 0x430, 0x20, 0x441, 0x43e, 0x43b, -0x43a, 0x443, 0x43e, 0x431, 0x430, 0x439, 0x430, 0x3b, 0x49, 0x68, 0x65, 0x6c, 0x61, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x6e, -0x73, 0x61, 0x6e, 0x69, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xa55e, 0xa524, 0xa52b, 0xa569, 0x20, 0xa55c, 0xa55e, -0xa54c, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4c, 0x61, 0x69, 0x62, 0x68, 0x69, 0x79, 0x61, 0x20, 0x44, 0x61, 0x6c, -0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x25b, 0x6c, 0xe2, 0x14b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, -0x46, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x68, 0x69, 0x72, -0xe8, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x65, 0x6c, 0xe1, 0x14b, 0x20, 0x43, 0x46, 0x41, 0x3b, 0x3b, 0x3b, -0x3b, 0x3b, 0x3b, 0x3b, 0x62f, 0x6cc, 0x646, 0x627, 0x631, 0x6cc, 0x20, 0x639, 0x6ce, 0x631, 0x627, 0x642, 0x6cc, 0x3b, 0x3b, 0x3b, -0x3b, 0x3b, 0x3b, 0x3b, 0x695, 0x6cc, 0x627, 0x6b5, 0x6cc, 0x20, 0x626, 0x6ce, 0x631, 0x627, 0x646, 0x6cc, 0x3b, 0x3b, 0x3b, 0x3b, -0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x65, -0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, -0x3b, 0x65, 0x75, 0x72, 0x61, 0x6a, 0x3b, 0x65, 0x75, 0x72, 0x61, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x77, 0x3b, 0x65, -0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x627, 0x6cc, 0x631, 0x627, 0x646, 0x20, 0x631, 0x6cc, 0x627, 0x644, -0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x627, 0x6cc, 0x631, 0x627, 0x646, 0x20, 0x631, 0x6cc, 0x627, 0x644, 0x3b, 0x6e2f, 0x5e63, 0x3b, -0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6e2f, 0x5e63, 0x3b +0x74, 0x3b, 0x69, 0x52, 0x61, 0x6e, 0x64, 0x69, 0x20, 0x79, 0x61, 0x73, 0x65, 0x4d, 0x7a, 0x61, 0x6e, 0x7a, 0x69, 0x20, +0x41, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x3b, 0x3b, 0x69, 0x52, 0x61, 0x6e, 0x64, 0x69, 0x20, 0x59, 0x61, 0x73, 0x65, 0x4d, +0x7a, 0x61, 0x6e, 0x7a, 0x69, 0x20, 0x41, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x69, 0x52, 0x61, 0x6e, +0x64, 0x69, 0x20, 0x79, 0x61, 0x73, 0x65, 0x4d, 0x7a, 0x61, 0x6e, 0x7a, 0x69, 0x20, 0x41, 0x66, 0x72, 0x69, 0x6b, 0x61, +0x3b, 0x4e, 0x61, 0x69, 0x72, 0x61, 0x20, 0x74, 0x69, 0x20, 0x4f, 0x72, 0xed, 0x6c, 0x1eb9, 0x301, 0xe8, 0x64, 0x65, 0x20, +0x4e, 0xe0, 0xec, 0x6a, 0xed, 0x72, 0xed, 0xe0, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x61, 0x72, 0x61, 0x6e, +0x73, 0x69, 0x20, 0x74, 0x69, 0x20, 0x4f, 0x72, 0xed, 0x6c, 0x25b, 0x301, 0xe8, 0x64, 0x65, 0x20, 0x42, 0x49, 0x4b, 0x45, +0x41, 0x4f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x69, 0x2d, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, +0x69, 0x63, 0x61, 0x6e, 0x20, 0x52, 0x61, 0x6e, 0x64, 0x3b, 0x3b, 0x69, 0x2d, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, +0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x52, 0x61, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x69, 0x2d, 0x53, 0x6f, 0x75, +0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x52, 0x61, 0x6e, 0x64, 0x3b, 0x42, 0x6f, 0x73, 0x61, +0x6e, 0x73, 0x6b, 0x6f, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x61, 0x20, 0x6b, 0x6f, 0x6e, +0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x62, 0x6f, +0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x61, 0x20, 0x6b, +0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, +0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x65, +0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x65, +0x3b, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, +0x6b, 0x69, 0x68, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20, 0x6d, +0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b, 0x41a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x430, 0x20, +0x43c, 0x430, 0x440, 0x43a, 0x430, 0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, +0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x430, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, +0x43d, 0x430, 0x20, 0x43c, 0x430, 0x440, 0x43a, 0x430, 0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, +0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x435, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, +0x431, 0x438, 0x43b, 0x43d, 0x435, 0x20, 0x43c, 0x430, 0x440, 0x43a, 0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, +0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x438, 0x445, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, +0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x438, 0x445, 0x20, 0x43c, 0x430, 0x440, 0x430, 0x43a, 0x430, 0x3b, 0x47, 0x68, 0x61, +0x6e, 0x61, 0x20, 0x53, 0x69, 0x64, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x4e, 0x52, 0x3b, 0x3b, 0x3b, +0x3b, 0x3b, 0x3b, 0x49, 0x4e, 0x52, 0x3b, 0x4e, 0x61, 0x1ecb, 0x72, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, +0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, +0x3b, 0x3b, 0x67, 0x68, 0x61, 0x6e, 0x61, 0x20, 0x73, 0x69, 0x256, 0x69, 0x3b, 0x3b, 0x67, 0x68, 0x61, 0x6e, 0x61, 0x20, +0x73, 0x69, 0x256, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x67, 0x68, 0x61, 0x6e, 0x61, 0x20, 0x73, 0x69, 0x256, 0x69, 0x3b, 0x263, +0x65, 0x74, 0x6f, 0x256, 0x6f, 0x66, 0x65, 0x20, 0x61, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x67, 0x61, 0x20, 0x43, 0x46, 0x41, +0x20, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x263, 0x65, 0x74, 0x6f, 0x256, 0x6f, +0x66, 0x65, 0x20, 0x61, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x67, 0x61, 0x20, 0x43, 0x46, 0x41, 0x20, 0x66, 0x72, 0x61, 0x6e, +0x63, 0x20, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x3b, 0x3b, 0x263, 0x65, 0x74, 0x6f, 0x256, 0x6f, 0x66, 0x65, 0x20, +0x61, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x67, 0x61, 0x20, 0x43, 0x46, 0x41, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x42, +0x43, 0x45, 0x41, 0x4f, 0x3b, 0x50, 0x69, 0x73, 0x6f, 0x20, 0x6e, 0x67, 0x20, 0x50, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, +0x61, 0x73, 0x3b, 0x3b, 0x70, 0x69, 0x73, 0x6f, 0x20, 0x6e, 0x67, 0x20, 0x50, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x61, +0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x69, 0x73, 0x6f, 0x20, 0x6e, 0x67, 0x20, 0x50, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, +0x61, 0x73, 0x3b, 0x53, 0x63, 0x68, 0x77, 0x69, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x3b, +0x3b, 0x53, 0x63, 0x68, 0x77, 0x69, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x3b, 0x3b, 0x3b, +0x3b, 0x53, 0x63, 0x68, 0x77, 0x69, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x3b, 0x45, 0x75, +0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x6e, 0x6f, 0x72, 0x67, 0x67, 0x61, 0x20, +0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x3b, 0x6e, 0x6f, 0x72, 0x67, 0x67, 0x61, 0x20, 0x6b, 0x72, 0x75, 0x76, +0x64, 0x6e, 0x6f, 0x3b, 0x6e, 0x6f, 0x72, 0x67, 0x67, 0x61, 0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x3b, +0x3b, 0x6e, 0x6f, 0x72, 0x67, 0x67, 0x61, 0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x65, 0x75, 0x72, 0x6f, +0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x72, +0x75, 0x6f, 0x167, 0x167, 0x61, 0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x3b, 0x72, 0x75, 0x6f, 0x167, 0x167, +0x61, 0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x72, 0x75, 0x6f, 0x167, 0x167, 0x61, 0x20, 0x6b, 0x72, 0x75, +0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x72, 0x75, 0x6f, 0x167, 0x167, 0x61, 0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e, +0x6f, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, +0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x62, 0x75, 0x75, 0x257, 0x75, 0x20, 0x53, 0x65, 0x65, 0x66, 0x61, 0x61, 0x20, +0x42, 0x43, 0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x62, 0x75, 0x75, 0x257, 0x69, 0x20, 0x53, +0x65, 0x65, 0x66, 0x61, 0x61, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x61, 0x6c, +0x61, 0x73, 0x69, 0x20, 0x47, 0x61, 0x6d, 0x6d, 0x62, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x6f, 0x6c, +0x61, 0x61, 0x72, 0x20, 0x4c, 0x69, 0x62, 0x65, 0x72, 0x69, 0x79, 0x61, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, +0x55, 0x67, 0x69, 0x79, 0x79, 0x61, 0x20, 0x4d, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, +0x3b, 0x3b, 0x4e, 0x61, 0x79, 0x72, 0x61, 0x61, 0x20, 0x4e, 0x69, 0x6a, 0x65, 0x72, 0x69, 0x79, 0x61, 0x61, 0x3b, 0x3b, +0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4c, 0x65, 0x77, 0x6f, 0x6f, 0x6e, 0x20, 0x53, 0x65, 0x72, 0x61, 0x61, 0x20, 0x4c, 0x69, +0x79, 0x6f, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x69, 0x72, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, +0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x6a, 0x69, 0x6c, 0x69, 0x6e, 0x67, +0x69, 0x20, 0x65, 0x65, 0x6c, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x65, +0x74, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69, 0x71, 0x75, 0x65, 0x3b, +0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x6f, 0x6c, 0x61, 0x20, 0x79, 0x61, 0x73, 0x65, 0x20, 0x41, 0x6d, 0x65, 0x6c, +0x69, 0x6b, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x68, 0x65, 0x6c, 0x65, 0x72, 0x69, 0x20, 0x73, 0x61, 0x20, +0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x2d30, 0x2d37, 0x2d54, 0x2d49, 0x2d4e, +0x20, 0x2d4f, 0x20, 0x2d4d, 0x2d4e, 0x2d56, 0x2d54, 0x2d49, 0x2d31, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x61, 0x64, 0x72, 0x69, +0x6d, 0x20, 0x6e, 0x20, 0x6c, 0x6d, 0x263, 0x72, 0x69, 0x62, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x64, 0x69, +0x6e, 0x61, 0x72, 0x20, 0x41, 0x7a, 0x7a, 0x61, 0x79, 0x72, 0x69, 0x3b, 0x3b, 0x41, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, +0x6e, 0x20, 0x5a, 0x7a, 0x61, 0x79, 0x65, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x65, 0x6e, +0x20, 0x6e, 0x20, 0x5a, 0x7a, 0x61, 0x79, 0x65, 0x72, 0x3b, 0x45, 0x73, 0x68, 0x69, 0x72, 0x69, 0x6e, 0x67, 0x69, 0x20, +0x79, 0x61, 0x20, 0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x68, 0x69, 0x6c, +0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x48, 0x75, 0x74, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, +0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x6e, +0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x65, 0x66, 0x61, 0x20, 0x46, 0x72, 0x61, +0x14b, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x53, 0x20, 0x13a0, +0x13d5, 0x13b3, 0x3b, 0x3b, 0x55, 0x53, 0x20, 0x13a0, 0x13d5, 0x13b3, 0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x53, 0x20, 0x13a0, 0x13d5, 0x13b3, +0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x20, 0x6d, 0x6f, 0x72, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, +0x3b, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0xed, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x61, 0x6e, 0x73, +0x61, 0x6e, 0xed, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x65, +0x79, 0x61, 0x20, 0x59, 0x75, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x6b, 0x75, +0x64, 0x75, 0x20, 0x4b, 0x61, 0x62, 0x75, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x75, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, +0x3b, 0x53, 0x6b, 0x75, 0x64, 0x75, 0x20, 0x4b, 0x61, 0x62, 0x75, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x75, 0x3b, +0x53, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x74, 0x61, 0x62, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, +0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, +0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x49, +0x72, 0x6f, 0x70, 0x69, 0x79, 0x69, 0x61, 0x6e, 0xed, 0x20, 0x65, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, +0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x72, 0x6f, 0x70, 0x69, 0x79, 0x69, 0x61, 0x6e, 0xed, 0x20, 0x65, 0x20, 0x54, 0x61, 0x6e, +0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69, 0x72, 0x69, 0x6e, 0x6a, 0x69, 0x20, +0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x68, 0x69, 0x6c, 0x69, +0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x64, 0x68, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, +0x3b, 0x3b, 0x3b, 0x41, 0x6e, 0x67, 0x6f, 0x2019, 0x6f, 0x74, 0x6f, 0x6c, 0x20, 0x6c, 0x6f, 0x6b, 0x2019, 0x20, 0x55, 0x67, +0x61, 0x6e, 0x64, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x6e, 0x67, 0x6f, 0x2019, 0x6f, 0x74, 0x6f, 0x6c, +0x20, 0x6c, 0x6f, 0x6b, 0x2019, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x46, +0x41, 0x20, 0x46, 0x72, 0x61, 0x14b, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, +0x3b, 0x53, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, +0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x65, 0x72, 0x68, 0x65, 0x6d, 0x20, 0x55, 0x6d, 0x65, 0x1e5b, 0x1e5b, 0x75, 0x6b, 0x69, 0x3b, +0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61, +0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x930, 0x93e, 0x902, 0x3b, 0x3b, 0x3b, 0x3b, +0x3b, 0x3b, 0x3b, 0x420, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x43d, 0x20, 0x441, 0x43e, 0x43c, 0x3b, 0x3b, 0x420, 0x43e, 0x441, 0x441, +0x438, 0x439, 0x43d, 0x20, 0x441, 0x43e, 0x43c, 0x3b, 0x3b, 0x3b, 0x3b, 0x420, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x43d, 0x20, 0x441, +0x43e, 0x44c, 0x43c, 0x430, 0x448, 0x3b, 0x440, 0x461, 0x441, 0x441, 0x456, 0x301, 0x439, 0x441, 0x43a, 0x457, 0x439, 0x20, 0x440, 0xa64b, +0x301, 0x431, 0x43b, 0x44c, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x440, 0x461, 0x441, 0x441, 0x456, 0x301, 0x439, 0x441, 0x43a, 0x430, +0x433, 0x461, 0x20, 0x440, 0xa64b, 0x431, 0x43b, 0x467, 0x300, 0x3b, 0x4e, 0x66, 0x61, 0x6c, 0x61, 0x6e, 0x67, 0x61, 0x20, 0x77, +0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x75, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x46, 0x41, 0x20, 0x46, 0xe0, +0x6c, 0xe2, 0x14b, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x72, 0x1ce, 0x14b, 0x20, +0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x65, 0x65, +0x66, 0x61, 0x20, 0x79, 0x61, 0x74, 0x69, 0x20, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, +0x46, 0x259, 0x6c, 0xe1, 0x14b, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, +0x3b, 0x3b, 0x3b, 0x66, 0x72, 0xe1, 0x14b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x6f, 0x6c, 0x61, 0x69, 0x20, +0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x72, 0x61, 0x14b, 0x20, 0x43, 0x46, 0x41, 0x20, +0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x410, 0x440, 0x430, 0x441, 0x441, 0x44b, 0x44b, 0x439, 0x430, +0x20, 0x441, 0x43e, 0x43b, 0x43a, 0x443, 0x43e, 0x431, 0x430, 0x439, 0x430, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x410, 0x440, 0x430, +0x441, 0x441, 0x44b, 0x44b, 0x439, 0x430, 0x20, 0x441, 0x43e, 0x43b, 0x43a, 0x443, 0x43e, 0x431, 0x430, 0x439, 0x430, 0x3b, 0x49, 0x68, +0x65, 0x6c, 0x61, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0x69, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, +0x3b, 0x3b, 0x3b, 0xa55e, 0xa524, 0xa52b, 0xa569, 0x20, 0xa55c, 0xa55e, 0xa54c, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4c, 0x61, +0x69, 0x62, 0x68, 0x69, 0x79, 0x61, 0x20, 0x44, 0x61, 0x6c, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x25b, +0x6c, 0xe2, 0x14b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x3b, +0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x68, 0x69, 0x72, 0xe8, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x65, +0x6c, 0xe1, 0x14b, 0x20, 0x43, 0x46, 0x41, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x62f, 0x6cc, 0x646, 0x627, 0x631, 0x6cc, +0x20, 0x639, 0x6ce, 0x631, 0x627, 0x642, 0x6cc, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x695, 0x6cc, 0x627, 0x6b5, 0x6cc, 0x20, +0x626, 0x6ce, 0x631, 0x627, 0x646, 0x6cc, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, +0x75, 0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, +0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72, 0x61, 0x6a, 0x3b, 0x65, 0x75, 0x72, +0x61, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x77, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, +0x627, 0x6cc, 0x631, 0x627, 0x646, 0x20, 0x631, 0x6cc, 0x627, 0x644, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x627, 0x6cc, 0x631, 0x627, +0x646, 0x20, 0x631, 0x6cc, 0x627, 0x644, 0x3b, 0x6e2f, 0x5e63, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6e2f, 0x5e63, 0x3b }; static const ushort currency_format_data[] = { @@ -6148,162 +6247,169 @@ static const ushort endonyms_data[] = { 0x4e, 0x61, 0x6a, 0x65, 0x72, 0x69, 0x79, 0x61, 0x47, 0x61, 0x6e, 0x61, 0x4e, 0x69, 0x6a, 0x61, 0x72, 0x5e2, 0x5d1, 0x5e8, 0x5d9, 0x5ea, 0x5d9, 0x5e9, 0x5e8, 0x5d0, 0x5dc, 0x939, 0x93f, 0x928, 0x94d, 0x926, 0x940, 0x92d, 0x93e, 0x930, 0x924, 0x6d, 0x61, 0x67, 0x79, 0x61, 0x72, 0x4d, 0x61, 0x67, 0x79, 0x61, 0x72, 0x6f, 0x72, 0x73, 0x7a, 0xe1, 0x67, 0xed, 0x73, 0x6c, 0x65, 0x6e, -0x73, 0x6b, 0x61, 0xcd, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x49, 0x6e, 0x64, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x47, 0x61, -0x65, 0x69, 0x6c, 0x67, 0x65, 0xc9, 0x69, 0x72, 0x65, 0x69, 0x74, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x6f, 0x49, 0x74, 0x61, -0x6c, 0x69, 0x61, 0x53, 0x61, 0x6e, 0x20, 0x4d, 0x61, 0x72, 0x69, 0x6e, 0x6f, 0x53, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, -0x61, 0x43, 0x69, 0x74, 0x74, 0xe0, 0x20, 0x64, 0x65, 0x6c, 0x20, 0x56, 0x61, 0x74, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x65e5, -0x672c, 0x8a9e, 0x65e5, 0x672c, 0xc95, 0xca8, 0xccd, 0xca8, 0xca1, 0xcad, 0xcbe, 0xcb0, 0xca4, 0x6a9, 0x672, 0x634, 0x64f, 0x631, 0x6c1, 0x650, -0x646, 0x65b, 0x62f, 0x648, 0x633, 0x62a, 0x627, 0x646, 0x49b, 0x430, 0x437, 0x430, 0x49b, 0x20, 0x442, 0x456, 0x43b, 0x456, 0x49a, 0x430, -0x437, 0x430, 0x49b, 0x441, 0x442, 0x430, 0x43d, 0x4b, 0x69, 0x6e, 0x79, 0x61, 0x72, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x55, 0x20, -0x52, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x43a, 0x44b, 0x440, 0x433, 0x44b, 0x437, 0x447, 0x430, 0x41a, 0x44b, 0x440, 0x433, 0x44b, 0x437, -0x441, 0x442, 0x430, 0x43d, 0xd55c, 0xad6d, 0xc5b4, 0xb300, 0xd55c, 0xbbfc, 0xad6d, 0xc870, 0xc120, 0xbbfc, 0xc8fc, 0xc8fc, 0xc758, 0xc778, 0xbbfc, 0xacf5, -0xd654, 0xad6d, 0x49, 0x6b, 0x69, 0x72, 0x75, 0x6e, 0x64, 0x69, 0x55, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x69, 0xea5, 0xeb2, -0xea7, 0x6c, 0x61, 0x74, 0x76, 0x69, 0x65, 0x161, 0x75, 0x4c, 0x61, 0x74, 0x76, 0x69, 0x6a, 0x61, 0x6c, 0x69, 0x6e, 0x67, -0xe1, 0x6c, 0x61, 0x52, 0x65, 0x70, 0x75, 0x62, 0x6c, 0xed, 0x6b, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, -0xf3, 0x20, 0x44, 0x65, 0x6d, 0x6f, 0x6b, 0x72, 0x61, 0x74, 0xed, 0x6b, 0x69, 0x41, 0x6e, 0x67, 0xf3, 0x6c, 0x61, 0x52, -0x65, 0x70, 0x69, 0x62, 0x69, 0x6b, 0x69, 0x20, 0x79, 0x61, 0x20, 0x41, 0x66, 0x72, 0xed, 0x6b, 0x61, 0x20, 0x79, 0x61, -0x20, 0x4b, 0xe1, 0x74, 0x69, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x69, 0x65, 0x74, 0x75, 0x76, 0x69, 0x173, 0x4c, 0x69, -0x65, 0x74, 0x75, 0x76, 0x61, 0x43c, 0x430, 0x43a, 0x435, 0x434, 0x43e, 0x43d, 0x441, 0x43a, 0x438, 0x41c, 0x430, 0x43a, 0x435, 0x434, -0x43e, 0x43d, 0x438, 0x458, 0x430, 0x4d, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x73, 0x79, 0x4d, 0x61, 0x64, 0x61, 0x67, 0x61, 0x73, -0x69, 0x6b, 0x61, 0x72, 0x61, 0x4d, 0x65, 0x6c, 0x61, 0x79, 0x75, 0x42, 0x72, 0x75, 0x6e, 0x65, 0x69, 0x53, 0x69, 0x6e, -0x67, 0x61, 0x70, 0x75, 0x72, 0x61, 0xd2e, 0xd32, 0xd2f, 0xd3e, 0xd33, 0xd02, 0xd07, 0xd28, 0xd4d, 0xd24, 0xd4d, 0xd2f, 0x4d, 0x61, -0x6c, 0x74, 0x69, 0x92e, 0x930, 0x93e, 0x920, 0x940, 0x43c, 0x43e, 0x43d, 0x433, 0x43e, 0x43b, 0x41c, 0x43e, 0x43d, 0x433, 0x43e, 0x43b, -0x928, 0x947, 0x92a, 0x93e, 0x932, 0x940, 0x928, 0x947, 0x92a, 0x93e, 0x932, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x20, 0x62, 0x6f, 0x6b, -0x6d, 0xe5, 0x6c, 0x4e, 0x6f, 0x72, 0x67, 0x65, 0x53, 0x76, 0x61, 0x6c, 0x62, 0x61, 0x72, 0x64, 0x20, 0x6f, 0x67, 0x20, -0x4a, 0x61, 0x6e, 0x20, 0x4d, 0x61, 0x79, 0x65, 0x6e, 0xb13, 0xb21, 0xb3c, 0xb3f, 0xb06, 0xb2d, 0xb3e, 0xb30, 0xb24, 0x67e, 0x69a, -0x62a, 0x648, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x633, 0x62a, 0x627, 0x646, 0x641, 0x627, 0x631, 0x633, 0x6cc, 0x627, 0x6cc, 0x631, 0x627, -0x646, 0x62f, 0x631, 0x6cc, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x50, 0x6f, 0x6c, 0x73, 0x6b, 0x61, 0x70, 0x6f, 0x72, 0x74, -0x75, 0x67, 0x75, 0xea, 0x73, 0x42, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x41, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x43, 0x61, 0x62, -0x6f, 0x20, 0x56, 0x65, 0x72, 0x64, 0x65, 0x54, 0x69, 0x6d, 0x6f, 0x72, 0x2d, 0x4c, 0x65, 0x73, 0x74, 0x65, 0x47, 0x75, -0x69, 0x6e, 0xe9, 0x20, 0x45, 0x71, 0x75, 0x61, 0x74, 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x47, 0x75, 0x69, 0x6e, 0xe9, 0x2d, -0x42, 0x69, 0x73, 0x73, 0x61, 0x75, 0x4c, 0x75, 0x78, 0x65, 0x6d, 0x62, 0x75, 0x72, 0x67, 0x6f, 0x4d, 0x61, 0x63, 0x61, -0x75, 0x2c, 0x20, 0x52, 0x41, 0x45, 0x20, 0x64, 0x61, 0x20, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x4d, 0x6f, 0xe7, 0x61, 0x6d, -0x62, 0x69, 0x71, 0x75, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x75, 0x67, 0x75, 0xea, 0x73, 0x20, 0x65, 0x75, 0x72, 0x6f, 0x70, -0x65, 0x75, 0x50, 0x6f, 0x72, 0x74, 0x75, 0x67, 0x61, 0x6c, 0x53, 0xe3, 0x6f, 0x20, 0x54, 0x6f, 0x6d, 0xe9, 0x20, 0x65, -0x20, 0x50, 0x72, 0xed, 0x6e, 0x63, 0x69, 0x70, 0x65, 0x53, 0x75, 0xed, 0xe7, 0x61, 0xa2a, 0xa70, 0xa1c, 0xa3e, 0xa2c, 0xa40, -0xa2d, 0xa3e, 0xa30, 0xa24, 0x67e, 0x646, 0x62c, 0x627, 0x628, 0x6cc, 0x67e, 0x627, 0x6a9, 0x633, 0x62a, 0x627, 0x646, 0x52, 0x75, 0x6e, -0x61, 0x73, 0x69, 0x6d, 0x69, 0x50, 0x65, 0x72, 0xfa, 0x42, 0x6f, 0x6c, 0x69, 0x76, 0x69, 0x61, 0x45, 0x63, 0x75, 0x61, -0x64, 0x6f, 0x72, 0x72, 0x75, 0x6d, 0x61, 0x6e, 0x74, 0x73, 0x63, 0x68, 0x53, 0x76, 0x69, 0x7a, 0x72, 0x61, 0x72, 0x6f, -0x6d, 0xe2, 0x6e, 0x103, 0x52, 0x6f, 0x6d, 0xe2, 0x6e, 0x69, 0x61, 0x52, 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, -0x20, 0x4d, 0x6f, 0x6c, 0x64, 0x6f, 0x76, 0x61, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x439, 0x420, 0x43e, 0x441, 0x441, 0x438, -0x44f, 0x41a, 0x430, 0x437, 0x430, 0x445, 0x441, 0x442, 0x430, 0x43d, 0x41a, 0x438, 0x440, 0x433, 0x438, 0x437, 0x438, 0x44f, 0x41c, 0x43e, -0x43b, 0x434, 0x43e, 0x432, 0x430, 0x423, 0x43a, 0x440, 0x430, 0x438, 0x43d, 0x430, 0x53, 0xe4, 0x6e, 0x67, 0xf6, 0x4b, 0xf6, 0x64, -0xf6, 0x72, 0xf6, 0x73, 0xea, 0x73, 0x65, 0x20, 0x74, 0xee, 0x20, 0x42, 0xea, 0x61, 0x66, 0x72, 0xee, 0x6b, 0x61, 0x441, -0x440, 0x43f, 0x441, 0x43a, 0x438, 0x421, 0x440, 0x431, 0x438, 0x458, 0x430, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x43, 0x72, 0x6e, -0x61, 0x20, 0x47, 0x6f, 0x72, 0x61, 0x53, 0x72, 0x62, 0x69, 0x6a, 0x61, 0x411, 0x43e, 0x441, 0x43d, 0x430, 0x20, 0x438, 0x20, -0x425, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x438, 0x43d, 0x430, 0x426, 0x440, 0x43d, 0x430, 0x20, 0x413, 0x43e, 0x440, 0x430, -0x41a, 0x43e, 0x441, 0x43e, 0x432, 0x43e, 0x4b, 0x6f, 0x73, 0x6f, 0x76, 0x6f, 0x438, 0x440, 0x43e, 0x43d, 0x413, 0x443, 0x44b, 0x440, -0x434, 0x437, 0x44b, 0x441, 0x442, 0x43e, 0x43d, 0x423, 0x4d5, 0x440, 0x4d5, 0x441, 0x435, 0x63, 0x68, 0x69, 0x53, 0x68, 0x6f, 0x6e, -0x61, 0x633, 0x646, 0x68c, 0x64a, 0x67e, 0x627, 0x6aa, 0x633, 0x62a, 0x627, 0x646, 0xdc3, 0xdd2, 0xd82, 0xdc4, 0xdbd, 0xdc1, 0xdca, 0x200d, -0xdbb, 0xdd3, 0x20, 0xdbd, 0xd82, 0xd9a, 0xdcf, 0xdc0, 0x73, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0x10d, 0x69, 0x6e, 0x61, 0x53, 0x6c, -0x6f, 0x76, 0x65, 0x6e, 0x73, 0x6b, 0x6f, 0x73, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0x161, 0x10d, 0x69, 0x6e, 0x61, 0x53, 0x6c, -0x6f, 0x76, 0x65, 0x6e, 0x69, 0x6a, 0x61, 0x53, 0x6f, 0x6f, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x53, 0x6f, 0x6f, 0x6d, 0x61, -0x61, 0x6c, 0x69, 0x79, 0x61, 0x4a, 0x61, 0x62, 0x75, 0x75, 0x74, 0x69, 0x49, 0x74, 0x6f, 0x6f, 0x62, 0x69, 0x79, 0x61, -0x4b, 0x69, 0x69, 0x6e, 0x69, 0x79, 0x61, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x20, 0x64, 0x65, 0x20, 0x45, 0x73, -0x70, 0x61, 0xf1, 0x61, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x41, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x61, -0x42, 0x65, 0x6c, 0x69, 0x63, 0x65, 0x43, 0x68, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x69, 0x61, 0x43, -0x6f, 0x73, 0x74, 0x61, 0x20, 0x52, 0x69, 0x63, 0x61, 0x43, 0x75, 0x62, 0x61, 0x52, 0x65, 0x70, 0xfa, 0x62, 0x6c, 0x69, -0x63, 0x61, 0x20, 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x6e, 0x61, 0x45, 0x6c, 0x20, 0x53, 0x61, 0x6c, 0x76, -0x61, 0x64, 0x6f, 0x72, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x20, 0x45, 0x63, 0x75, 0x61, 0x74, 0x6f, 0x72, 0x69, 0x61, -0x6c, 0x47, 0x75, 0x61, 0x74, 0x65, 0x6d, 0x61, 0x6c, 0x61, 0x48, 0x6f, 0x6e, 0x64, 0x75, 0x72, 0x61, 0x73, 0x65, 0x73, -0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x20, 0x64, 0x65, 0x20, 0x4d, 0xe9, 0x78, 0x69, 0x63, 0x6f, 0x4d, 0xe9, 0x78, 0x69, 0x63, -0x6f, 0x4e, 0x69, 0x63, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x50, 0x61, 0x6e, 0x61, 0x6d, 0xe1, 0x50, 0x61, 0x72, 0x61, -0x67, 0x75, 0x61, 0x79, 0x46, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x61, 0x73, 0x45, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x73, -0x20, 0x55, 0x6e, 0x69, 0x64, 0x6f, 0x73, 0x55, 0x72, 0x75, 0x67, 0x75, 0x61, 0x79, 0x56, 0x65, 0x6e, 0x65, 0x7a, 0x75, -0x65, 0x6c, 0x61, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x69, 0x61, 0x73, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x20, 0x6c, -0x61, 0x74, 0x69, 0x6e, 0x6f, 0x61, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x4c, 0x61, 0x74, 0x69, 0x6e, 0x6f, -0x61, 0x6d, 0xe9, 0x72, 0x69, 0x63, 0x61, 0x43, 0x65, 0x75, 0x74, 0x61, 0x20, 0x79, 0x20, 0x4d, 0x65, 0x6c, 0x69, 0x6c, -0x6c, 0x61, 0x4b, 0x69, 0x73, 0x77, 0x61, 0x68, 0x69, 0x6c, 0x69, 0x4b, 0x69, 0x6e, 0x67, 0x77, 0x61, 0x6e, 0x61, 0x4a, -0x61, 0x6d, 0x68, 0x75, 0x72, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x69, 0x64, 0x65, 0x6d, 0x6f, 0x6b, 0x72, 0x61, 0x73, -0x69, 0x61, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x73, 0x76, 0x65, 0x6e, 0x73, 0x6b, 0x61, 0x53, 0x76, -0x65, 0x72, 0x69, 0x67, 0x65, 0xc5, 0x6c, 0x61, 0x6e, 0x64, 0x442, 0x43e, 0x4b7, 0x438, 0x43a, 0x4e3, 0x422, 0x43e, 0x4b7, 0x438, -0x43a, 0x438, 0x441, 0x442, 0x43e, 0x43d, 0xba4, 0xbae, 0xbbf, 0xbb4, 0xbcd, 0xb87, 0xba8, 0xbcd, 0xba4, 0xbbf, 0xbaf, 0xbbe, 0xbae, 0xbb2, -0xbc7, 0xb9a, 0xbbf, 0xbaf, 0xbbe, 0xb9a, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbaa, 0xbcd, 0xbaa, 0xbc2, 0xbb0, 0xbcd, 0xb87, 0xbb2, 0xb99, 0xbcd, -0xb95, 0xbc8, 0x442, 0x430, 0x442, 0x430, 0x440, 0xc24, 0xc46, 0xc32, 0xc41, 0xc17, 0xc41, 0xc2d, 0xc3e, 0xc30, 0xc24, 0xc26, 0xc47, 0xc36, -0xc02, 0xe44, 0xe17, 0xe22, 0xf56, 0xf7c, 0xf51, 0xf0b, 0xf66, 0xf90, 0xf51, 0xf0b, 0xf62, 0xf92, 0xfb1, 0xf0b, 0xf53, 0xf42, 0xf62, 0xf92, -0xfb1, 0xf0b, 0xf42, 0xf62, 0xf0b, 0x1275, 0x130d, 0x122d, 0x129b, 0x12a4, 0x122d, 0x1275, 0x122b, 0x6c, 0x65, 0x61, 0x20, 0x66, 0x61, 0x6b, -0x61, 0x74, 0x6f, 0x6e, 0x67, 0x61, 0x54, 0xfc, 0x72, 0x6b, 0xe7, 0x65, 0x54, 0xfc, 0x72, 0x6b, 0x69, 0x79, 0x65, 0x4b, -0x131, 0x62, 0x72, 0x131, 0x73, 0x74, 0xfc, 0x72, 0x6b, 0x6d, 0x65, 0x6e, 0x20, 0x64, 0x69, 0x6c, 0x69, 0x54, 0xfc, 0x72, -0x6b, 0x6d, 0x65, 0x6e, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x626, 0x6c7, 0x64a, 0x63a, 0x6c7, 0x631, 0x686, 0x6d5, 0x62c, 0x6c7, 0x6ad, -0x6af, 0x648, 0x443, 0x43a, 0x440, 0x430, 0x457, 0x43d, 0x441, 0x44c, 0x43a, 0x430, 0x423, 0x43a, 0x440, 0x430, 0x457, 0x43d, 0x430, 0x627, -0x631, 0x62f, 0x648, 0x628, 0x6be, 0x627, 0x631, 0x62a, 0x6f, 0x2018, 0x7a, 0x62, 0x65, 0x6b, 0x4f, 0x2bb, 0x7a, 0x62, 0x65, 0x6b, -0x69, 0x73, 0x74, 0x6f, 0x6e, 0x627, 0x648, 0x632, 0x628, 0x6cc, 0x6a9, 0x45e, 0x437, 0x431, 0x435, 0x43a, 0x447, 0x430, 0x40e, 0x437, -0x431, 0x435, 0x43a, 0x438, 0x441, 0x442, 0x43e, 0x43d, 0x54, 0x69, 0x1ebf, 0x6e, 0x67, 0x20, 0x56, 0x69, 0x1ec7, 0x74, 0x56, 0x69, -0x1ec7, 0x74, 0x20, 0x4e, 0x61, 0x6d, 0x56, 0x6f, 0x6c, 0x61, 0x70, 0xfc, 0x6b, 0x43, 0x79, 0x6d, 0x72, 0x61, 0x65, 0x67, -0x59, 0x20, 0x44, 0x65, 0x79, 0x72, 0x6e, 0x61, 0x73, 0x20, 0x55, 0x6e, 0x65, 0x64, 0x69, 0x67, 0x57, 0x6f, 0x6c, 0x6f, -0x66, 0x53, 0x65, 0x6e, 0x65, 0x67, 0x61, 0x61, 0x6c, 0x5d9, 0x5d9, 0x5b4, 0x5d3, 0x5d9, 0x5e9, 0x5d5, 0x5d5, 0x5e2, 0x5dc, 0x5d8, -0xc8, 0x64, 0xe8, 0x20, 0x59, 0x6f, 0x72, 0xf9, 0x62, 0xe1, 0x4f, 0x72, 0xed, 0x6c, 0x1eb9, 0x301, 0xe8, 0x64, 0x65, 0x20, -0x4e, 0xe0, 0xec, 0x6a, 0xed, 0x72, 0xed, 0xe0, 0x4f, 0x72, 0xed, 0x6c, 0x25b, 0x301, 0xe8, 0x64, 0x65, 0x20, 0x42, 0x25b, -0x300, 0x6e, 0x25b, 0x300, 0x69, 0x73, 0x69, 0x5a, 0x75, 0x6c, 0x75, 0x69, 0x4e, 0x69, 0x6e, 0x67, 0x69, 0x7a, 0x69, 0x6d, -0x75, 0x20, 0x41, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x6e, 0x79, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x4e, 0x6f, 0x72, 0x65, 0x67, -0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x69, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x438, 0x47, 0x61, 0x65, 0x6c, -0x67, 0x45, 0x6c, 0x6c, 0x61, 0x6e, 0x20, 0x56, 0x61, 0x6e, 0x6e, 0x69, 0x6e, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x77, 0x65, -0x6b, 0x52, 0x79, 0x77, 0x76, 0x61, 0x6e, 0x65, 0x74, 0x68, 0x20, 0x55, 0x6e, 0x79, 0x73, 0x41, 0x6b, 0x61, 0x6e, 0x47, -0x61, 0x61, 0x6e, 0x61, 0x915, 0x94b, 0x902, 0x915, 0x923, 0x940, 0x49, 0x67, 0x62, 0x6f, 0x4e, 0x61, 0x1ecb, 0x6a, 0x1ecb, 0x72, -0x1ecb, 0x61, 0x4b, 0x69, 0x6b, 0x61, 0x6d, 0x62, 0x61, 0x66, 0x75, 0x72, 0x6c, 0x61, 0x6e, 0x49, 0x74, 0x61, 0x6c, 0x69, -0x65, 0x45, 0x28b, 0x65, 0x67, 0x62, 0x65, 0x47, 0x68, 0x61, 0x6e, 0x61, 0x20, 0x6e, 0x75, 0x74, 0x6f, 0x6d, 0x65, 0x54, -0x6f, 0x67, 0x6f, 0x20, 0x6e, 0x75, 0x74, 0x6f, 0x6d, 0x65, 0x2bb, 0x14c, 0x6c, 0x65, 0x6c, 0x6f, 0x20, 0x48, 0x61, 0x77, -0x61, 0x69, 0x2bb, 0x69, 0x2bb, 0x41, 0x6d, 0x65, 0x6c, 0x69, 0x6b, 0x61, 0x20, 0x48, 0x75, 0x69, 0x20, 0x50, 0x16b, 0x20, -0x2bb, 0x49, 0x61, 0x46, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x6f, 0x50, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x61, 0x73, -0x53, 0x63, 0x68, 0x77, 0x69, 0x69, 0x7a, 0x65, 0x72, 0x74, 0xfc, 0xfc, 0x74, 0x73, 0x63, 0x68, 0x53, 0x63, 0x68, 0x77, -0x69, 0x69, 0x7a, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x72, 0x69, 0x69, 0x63, 0x68, 0x4c, 0x69, 0xe4, 0x63, 0x68, 0x74, 0x65, -0x73, 0x63, 0x68, 0x74, 0xe4, 0x69, 0xa188, 0xa320, 0xa259, 0xa34f, 0xa1e9, 0x4e, 0x65, 0x64, 0x64, 0x65, 0x72, 0x73, 0x61, 0x73, -0x73, 0x2019, 0x73, 0x63, 0x68, 0x44, 0xfc, 0xfc, 0x74, 0x73, 0x63, 0x68, 0x6c, 0x61, 0x6e, 0x64, 0x4e, 0x65, 0x64, 0x64, -0x65, 0x72, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x6e, 0x64, 0x61, 0x76, 0x76, 0x69, 0x73, 0xe1, 0x6d, 0x65, 0x67, 0x69, 0x65, -0x6c, 0x6c, 0x61, 0x4e, 0x6f, 0x72, 0x67, 0x61, 0x53, 0x75, 0x6f, 0x70, 0x6d, 0x61, 0x52, 0x75, 0x6f, 0x167, 0x167, 0x61, -0x45, 0x6b, 0x65, 0x67, 0x75, 0x73, 0x69, 0x69, 0x4b, 0x69, 0x74, 0x61, 0x69, 0x74, 0x61, 0x50, 0x75, 0x6c, 0x61, 0x61, -0x72, 0x4b, 0x61, 0x6d, 0x65, 0x72, 0x75, 0x75, 0x6e, 0x47, 0x69, 0x6e, 0x65, 0x4d, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e, -0x69, 0x47, 0x69, 0x6b, 0x75, 0x79, 0x75, 0x4b, 0x69, 0x73, 0x61, 0x6d, 0x70, 0x75, 0x72, 0x73, 0x65, 0x6e, 0x61, 0x69, -0x73, 0x69, 0x4e, 0x64, 0x65, 0x62, 0x65, 0x6c, 0x65, 0x4b, 0x69, 0x68, 0x6f, 0x72, 0x6f, 0x6d, 0x62, 0x6f, 0x2d5c, 0x2d30, -0x2d5b, 0x2d4d, 0x2d43, 0x2d49, 0x2d5c, 0x2d4d, 0x2d4e, 0x2d56, 0x2d54, 0x2d49, 0x2d31, 0x54, 0x61, 0x73, 0x68, 0x65, 0x6c, 0x1e25, 0x69, 0x79, -0x74, 0x6c, 0x6d, 0x263, 0x72, 0x69, 0x62, 0x54, 0x61, 0x71, 0x62, 0x61, 0x79, 0x6c, 0x69, 0x74, 0x4c, 0x65, 0x7a, 0x7a, -0x61, 0x79, 0x65, 0x72, 0x52, 0x75, 0x6e, 0x79, 0x61, 0x6e, 0x6b, 0x6f, 0x72, 0x65, 0x48, 0x69, 0x62, 0x65, 0x6e, 0x61, -0x48, 0x75, 0x74, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x4b, 0x79, 0x69, 0x76, 0x75, 0x6e, 0x6a, 0x6f, 0x62, 0x61, -0x6d, 0x61, 0x6e, 0x61, 0x6b, 0x61, 0x6e, 0x4b, 0x129, 0x65, 0x6d, 0x62, 0x75, 0x13e3, 0x13b3, 0x13a9, 0x13cc, 0x13ca, 0x20, 0x13a2, -0x13f3, 0x13be, 0x13b5, 0x13cd, 0x13d4, 0x13c5, 0x20, 0x13cd, 0x13a6, 0x13da, 0x13a9, 0x6b, 0x72, 0x65, 0x6f, 0x6c, 0x20, 0x6d, 0x6f, 0x72, -0x69, 0x73, 0x69, 0x65, 0x6e, 0x4d, 0x6f, 0x72, 0x69, 0x73, 0x43, 0x68, 0x69, 0x6d, 0x61, 0x6b, 0x6f, 0x6e, 0x64, 0x65, -0x4b, 0x268, 0x6c, 0x61, 0x61, 0x6e, 0x67, 0x69, 0x54, 0x61, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0xed, 0x61, 0x4c, 0x75, 0x67, -0x61, 0x6e, 0x64, 0x61, 0x59, 0x75, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x49, 0x63, 0x68, 0x69, 0x62, 0x65, 0x6d, 0x62, 0x61, -0x6b, 0x61, 0x62, 0x75, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x75, 0x4b, 0x61, 0x62, 0x75, 0x20, 0x56, 0x65, 0x72, -0x64, 0x69, 0x4b, 0x129, 0x6d, 0x129, 0x72, 0x169, 0x4b, 0x61, 0x6c, 0x65, 0x6e, 0x6a, 0x69, 0x6e, 0x45, 0x6d, 0x65, 0x74, -0x61, 0x62, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x4b, 0x68, 0x6f, 0x65, 0x6b, 0x68, 0x6f, 0x65, 0x67, 0x6f, 0x77, 0x61, -0x62, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x62, 0x4b, 0x69, 0x6d, 0x61, 0x63, 0x68, 0x61, 0x6d, 0x65, 0x4b, 0xf6, -0x6c, 0x73, 0x63, 0x68, 0x44, 0x6f, 0xfc, 0x74, 0x73, 0x63, 0x68, 0x6c, 0x61, 0x6e, 0x64, 0x4d, 0x61, 0x61, 0x54, 0x61, -0x6e, 0x73, 0x61, 0x6e, 0x69, 0x61, 0x4f, 0x6c, 0x75, 0x73, 0x6f, 0x67, 0x61, 0x4c, 0x75, 0x6c, 0x75, 0x68, 0x69, 0x61, -0x4b, 0x69, 0x70, 0x61, 0x72, 0x65, 0x54, 0x61, 0x64, 0x68, 0x61, 0x6e, 0x69, 0x61, 0x4b, 0x69, 0x74, 0x65, 0x73, 0x6f, -0x4b, 0x65, 0x6e, 0x69, 0x61, 0x4b, 0x6f, 0x79, 0x72, 0x61, 0x20, 0x63, 0x69, 0x69, 0x6e, 0x69, 0x4d, 0x61, 0x61, 0x6c, -0x69, 0x4b, 0x69, 0x72, 0x75, 0x77, 0x61, 0x44, 0x68, 0x6f, 0x6c, 0x75, 0x6f, 0x52, 0x75, 0x6b, 0x69, 0x67, 0x61, 0x54, -0x61, 0x6d, 0x61, 0x7a, 0x69, 0x263, 0x74, 0x20, 0x6e, 0x20, 0x6c, 0x61, 0x1e6d, 0x6c, 0x61, 0x1e63, 0x4d, 0x65, 0x1e5b, 0x1e5b, -0x75, 0x6b, 0x4b, 0x6f, 0x79, 0x72, 0x61, 0x62, 0x6f, 0x72, 0x6f, 0x20, 0x73, 0x65, 0x6e, 0x6e, 0x69, 0x4b, 0x69, 0x73, -0x68, 0x61, 0x6d, 0x62, 0x61, 0x61, 0x92c, 0x921, 0x93c, 0x94b, 0x43d, 0x43e, 0x445, 0x447, 0x438, 0x439, 0x43d, 0x420, 0x43e, 0x441, -0x441, 0x438, 0x446, 0x435, 0x440, 0x43a, 0x43e, 0x432, 0x43d, 0x43e, 0x441, 0x43b, 0x43e, 0x432, 0x435, 0x301, 0x43d, 0x441, 0x43a, 0x457, -0x439, 0x440, 0x461, 0x441, 0x441, 0x456, 0x301, 0x430, 0x54, 0x73, 0x68, 0x69, 0x6c, 0x75, 0x62, 0x61, 0x44, 0x69, 0x74, 0x75, -0x6e, 0x67, 0x61, 0x20, 0x77, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x75, 0x4c, 0xeb, 0x74, 0x7a, 0x65, 0x62, 0x75, 0x65, -0x72, 0x67, 0x65, 0x73, 0x63, 0x68, 0x4c, 0xeb, 0x74, 0x7a, 0x65, 0x62, 0x75, 0x65, 0x72, 0x67, 0x41, 0x67, 0x68, 0x65, -0x6d, 0x4b, 0xe0, 0x6d, 0xe0, 0x6c, 0xfb, 0x14b, 0x181, 0xe0, 0x73, 0xe0, 0x61, 0x4b, 0xe0, 0x6d, 0x25b, 0x300, 0x72, 0xfb, -0x6e, 0x5a, 0x61, 0x72, 0x6d, 0x61, 0x63, 0x69, 0x69, 0x6e, 0x65, 0x4e, 0x69, 0x17e, 0x65, 0x72, 0x64, 0x75, 0xe1, 0x6c, -0xe1, 0x6a, 0x6f, 0x6f, 0x6c, 0x61, 0x53, 0x65, 0x6e, 0x65, 0x67, 0x61, 0x6c, 0x65, 0x77, 0x6f, 0x6e, 0x64, 0x6f, 0x4b, -0x61, 0x6d, 0x259, 0x72, 0xfa, 0x6e, 0x72, 0x69, 0x6b, 0x70, 0x61, 0x6b, 0x61, 0x6d, 0x25b, 0x72, 0xfa, 0x6e, 0x4d, 0x61, -0x6b, 0x75, 0x61, 0x55, 0x6d, 0x6f, 0x7a, 0x61, 0x6d, 0x62, 0x69, 0x6b, 0x69, 0x4d, 0x55, 0x4e, 0x44, 0x41, 0x14a, 0x6b, -0x61, 0x6d, 0x65, 0x72, 0x75, 0x14b, 0x4b, 0x77, 0x61, 0x73, 0x69, 0x6f, 0x4b, 0x61, 0x6d, 0x65, 0x72, 0x75, 0x6e, 0x54, -0x68, 0x6f, 0x6b, 0x20, 0x4e, 0x61, 0x74, 0x68, 0x441, 0x430, 0x445, 0x430, 0x20, 0x442, 0x44b, 0x43b, 0x430, 0x410, 0x440, 0x430, -0x441, 0x441, 0x44b, 0x44b, 0x439, 0x430, 0x49, 0x73, 0x68, 0x69, 0x73, 0x61, 0x6e, 0x67, 0x75, 0x54, 0x61, 0x6e, 0x73, 0x61, -0x6e, 0x69, 0x79, 0x61, 0x54, 0x61, 0x73, 0x61, 0x77, 0x61, 0x71, 0x20, 0x73, 0x65, 0x6e, 0x6e, 0x69, 0xa559, 0xa524, 0xa55e, -0xa524, 0xa52b, 0xa569, 0x56, 0x61, 0x69, 0x4c, 0x61, 0x69, 0x62, 0x68, 0x69, 0x79, 0x61, 0x57, 0x61, 0x6c, 0x73, 0x65, 0x72, -0x53, 0x63, 0x68, 0x77, 0x69, 0x7a, 0x6e, 0x75, 0x61, 0x73, 0x75, 0x65, 0x4b, 0x65, 0x6d, 0x65, 0x6c, 0xfa, 0x6e, 0x61, -0x73, 0x74, 0x75, 0x72, 0x69, 0x61, 0x6e, 0x75, 0x4e, 0x64, 0x61, 0xa78c, 0x61, 0x4b, 0x61, 0x6d, 0x25b, 0x6c, 0xfb, 0x6e, -0x6b, 0x61, 0x6b, 0x254, 0x4b, 0x61, 0x6d, 0x25b, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x74, 0x61, 0x2bc, 0x4b, 0x61, 0x6d, 0x61, -0x6c, 0x75, 0x6e, 0x53, 0x68, 0x77, 0xf3, 0x14b, 0xf2, 0x20, 0x6e, 0x67, 0x69, 0x65, 0x6d, 0x62, 0x254, 0x254, 0x6e, 0x4b, -0xe0, 0x6d, 0x61, 0x6c, 0xfb, 0x6d, 0x4c, 0x61, 0x6b, 0x21f, 0xf3, 0x6c, 0x2bc, 0x69, 0x79, 0x61, 0x70, 0x69, 0x4d, 0xed, -0x6c, 0x61, 0x68, 0x61, 0x14b, 0x73, 0x6b, 0x61, 0x20, 0x54, 0x21f, 0x61, 0x6d, 0xe1, 0x6b, 0x21f, 0x6f, 0x10d, 0x68, 0x65, -0x2d5c, 0x2d30, 0x2d4e, 0x2d30, 0x2d63, 0x2d49, 0x2d56, 0x2d5c, 0x6a9, 0x648, 0x631, 0x62f, 0x6cc, 0x6cc, 0x20, 0x646, 0x627, 0x648, 0x6d5, 0x646, -0x62f, 0x6cc, 0x639, 0x6ce, 0x631, 0x627, 0x642, 0x626, 0x6ce, 0x631, 0x627, 0x646, 0x64, 0x6f, 0x6c, 0x6e, 0x6f, 0x73, 0x65, 0x72, -0x62, 0x161, 0x107, 0x69, 0x6e, 0x61, 0x4e, 0x69, 0x6d, 0x73, 0x6b, 0x61, 0x68, 0x6f, 0x72, 0x6e, 0x6a, 0x6f, 0x73, 0x65, -0x72, 0x62, 0x161, 0x107, 0x69, 0x6e, 0x61, 0x4e, 0x11b, 0x6d, 0x73, 0x6b, 0x61, 0x70, 0x72, 0x16b, 0x73, 0x69, 0x73, 0x6b, -0x61, 0x6e, 0x73, 0x77, 0x12b, 0x74, 0x61, 0x69, 0x61, 0x6e, 0x61, 0x72, 0xe2, 0x161, 0x6b, 0x69, 0x65, 0x6c, 0xe2, 0x53, -0x75, 0x6f, 0x6d, 0xe2, 0x645, 0x627, 0x632, 0x631, 0x648, 0x646, 0x6cc, 0x644, 0x6ca, 0x631, 0x6cc, 0x20, 0x634, 0x648, 0x645, 0x627, -0x644, 0x6cc, 0x7cb5, 0x8a9e, 0x4e2d, 0x83ef, 0x4eba, 0x6c11, 0x5171, 0x548c, 0x570b, 0x9999, 0x6e2f, 0x7279, 0x5225, 0x884c, 0x653f, 0x5340, 0x7ca4, 0x8bed, -0x4e2d, 0x534e, 0x4eba, 0x6c11, 0x5171, 0x548c, 0x56fd +0x73, 0x6b, 0x61, 0xcd, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x49, 0x6e, 0x64, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x69, 0x6e, +0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x75, 0x61, 0x4d, 0x75, 0x6e, 0x64, 0x6f, 0x47, 0x61, 0x65, 0x69, 0x6c, 0x67, +0x65, 0xc9, 0x69, 0x72, 0x65, 0x69, 0x74, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x6f, 0x49, 0x74, 0x61, 0x6c, 0x69, 0x61, 0x53, +0x61, 0x6e, 0x20, 0x4d, 0x61, 0x72, 0x69, 0x6e, 0x6f, 0x53, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x61, 0x43, 0x69, 0x74, +0x74, 0xe0, 0x20, 0x64, 0x65, 0x6c, 0x20, 0x56, 0x61, 0x74, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x65e5, 0x672c, 0x8a9e, 0x65e5, 0x672c, +0x4a, 0x61, 0x77, 0x61, 0x49, 0x6e, 0x64, 0x6f, 0x6e, 0xe9, 0x73, 0x69, 0x61, 0xc95, 0xca8, 0xccd, 0xca8, 0xca1, 0xcad, 0xcbe, +0xcb0, 0xca4, 0x6a9, 0x672, 0x634, 0x64f, 0x631, 0x6c1, 0x650, 0x646, 0x65b, 0x62f, 0x648, 0x633, 0x62a, 0x627, 0x646, 0x49b, 0x430, 0x437, +0x430, 0x49b, 0x20, 0x442, 0x456, 0x43b, 0x456, 0x49a, 0x430, 0x437, 0x430, 0x49b, 0x441, 0x442, 0x430, 0x43d, 0x4b, 0x69, 0x6e, 0x79, +0x61, 0x72, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x55, 0x20, 0x52, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x43a, 0x44b, 0x440, 0x433, 0x44b, +0x437, 0x447, 0x430, 0x41a, 0x44b, 0x440, 0x433, 0x44b, 0x437, 0x441, 0x442, 0x430, 0x43d, 0xd55c, 0xad6d, 0xc5b4, 0xb300, 0xd55c, 0xbbfc, 0xad6d, +0xc870, 0xc120, 0xbbfc, 0xc8fc, 0xc8fc, 0xc758, 0xc778, 0xbbfc, 0xacf5, 0xd654, 0xad6d, 0x6b, 0x75, 0x72, 0x64, 0xee, 0x54, 0x69, 0x72, 0x6b, +0x69, 0x79, 0x65, 0x49, 0x6b, 0x69, 0x72, 0x75, 0x6e, 0x64, 0x69, 0x55, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x69, 0xea5, +0xeb2, 0xea7, 0x6c, 0x61, 0x74, 0x76, 0x69, 0x65, 0x161, 0x75, 0x4c, 0x61, 0x74, 0x76, 0x69, 0x6a, 0x61, 0x6c, 0x69, 0x6e, +0x67, 0xe1, 0x6c, 0x61, 0x52, 0x65, 0x70, 0x75, 0x62, 0x6c, 0xed, 0x6b, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e, +0x67, 0xf3, 0x20, 0x44, 0x65, 0x6d, 0x6f, 0x6b, 0x72, 0x61, 0x74, 0xed, 0x6b, 0x69, 0x41, 0x6e, 0x67, 0xf3, 0x6c, 0x61, +0x52, 0x65, 0x70, 0x69, 0x62, 0x69, 0x6b, 0x69, 0x20, 0x79, 0x61, 0x20, 0x41, 0x66, 0x72, 0xed, 0x6b, 0x61, 0x20, 0x79, +0x61, 0x20, 0x4b, 0xe1, 0x74, 0x69, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x69, 0x65, 0x74, 0x75, 0x76, 0x69, 0x173, 0x4c, +0x69, 0x65, 0x74, 0x75, 0x76, 0x61, 0x43c, 0x430, 0x43a, 0x435, 0x434, 0x43e, 0x43d, 0x441, 0x43a, 0x438, 0x41c, 0x430, 0x43a, 0x435, +0x434, 0x43e, 0x43d, 0x438, 0x458, 0x430, 0x4d, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x73, 0x79, 0x4d, 0x61, 0x64, 0x61, 0x67, 0x61, +0x73, 0x69, 0x6b, 0x61, 0x72, 0x61, 0x4d, 0x65, 0x6c, 0x61, 0x79, 0x75, 0x42, 0x72, 0x75, 0x6e, 0x65, 0x69, 0x53, 0x69, +0x6e, 0x67, 0x61, 0x70, 0x75, 0x72, 0x61, 0xd2e, 0xd32, 0xd2f, 0xd3e, 0xd33, 0xd02, 0xd07, 0xd28, 0xd4d, 0xd24, 0xd4d, 0xd2f, 0x4d, +0x61, 0x6c, 0x74, 0x69, 0x4d, 0x101, 0x6f, 0x72, 0x69, 0x41, 0x6f, 0x74, 0x65, 0x61, 0x72, 0x6f, 0x61, 0x92e, 0x930, 0x93e, +0x920, 0x940, 0x43c, 0x43e, 0x43d, 0x433, 0x43e, 0x43b, 0x41c, 0x43e, 0x43d, 0x433, 0x43e, 0x43b, 0x928, 0x947, 0x92a, 0x93e, 0x932, 0x940, +0x928, 0x947, 0x92a, 0x93e, 0x932, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x20, 0x62, 0x6f, 0x6b, 0x6d, 0xe5, 0x6c, 0x4e, 0x6f, 0x72, +0x67, 0x65, 0x53, 0x76, 0x61, 0x6c, 0x62, 0x61, 0x72, 0x64, 0x20, 0x6f, 0x67, 0x20, 0x4a, 0x61, 0x6e, 0x20, 0x4d, 0x61, +0x79, 0x65, 0x6e, 0xb13, 0xb21, 0xb3c, 0xb3f, 0xb06, 0xb2d, 0xb3e, 0xb30, 0xb24, 0x67e, 0x69a, 0x62a, 0x648, 0x627, 0x641, 0x63a, 0x627, +0x646, 0x633, 0x62a, 0x627, 0x646, 0x641, 0x627, 0x631, 0x633, 0x6cc, 0x627, 0x6cc, 0x631, 0x627, 0x646, 0x62f, 0x631, 0x6cc, 0x70, 0x6f, +0x6c, 0x73, 0x6b, 0x69, 0x50, 0x6f, 0x6c, 0x73, 0x6b, 0x61, 0x70, 0x6f, 0x72, 0x74, 0x75, 0x67, 0x75, 0xea, 0x73, 0x42, +0x72, 0x61, 0x73, 0x69, 0x6c, 0x41, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x43, 0x61, 0x62, 0x6f, 0x20, 0x56, 0x65, 0x72, 0x64, +0x65, 0x54, 0x69, 0x6d, 0x6f, 0x72, 0x2d, 0x4c, 0x65, 0x73, 0x74, 0x65, 0x47, 0x75, 0x69, 0x6e, 0xe9, 0x20, 0x45, 0x71, +0x75, 0x61, 0x74, 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x47, 0x75, 0x69, 0x6e, 0xe9, 0x2d, 0x42, 0x69, 0x73, 0x73, 0x61, 0x75, +0x4c, 0x75, 0x78, 0x65, 0x6d, 0x62, 0x75, 0x72, 0x67, 0x6f, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x2c, 0x20, 0x52, 0x41, 0x45, +0x20, 0x64, 0x61, 0x20, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x4d, 0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69, 0x71, 0x75, 0x65, 0x70, +0x6f, 0x72, 0x74, 0x75, 0x67, 0x75, 0xea, 0x73, 0x20, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x75, 0x50, 0x6f, 0x72, 0x74, +0x75, 0x67, 0x61, 0x6c, 0x53, 0xe3, 0x6f, 0x20, 0x54, 0x6f, 0x6d, 0xe9, 0x20, 0x65, 0x20, 0x50, 0x72, 0xed, 0x6e, 0x63, +0x69, 0x70, 0x65, 0x53, 0x75, 0xed, 0xe7, 0x61, 0xa2a, 0xa70, 0xa1c, 0xa3e, 0xa2c, 0xa40, 0xa2d, 0xa3e, 0xa30, 0xa24, 0x67e, 0x646, +0x62c, 0x627, 0x628, 0x6cc, 0x67e, 0x627, 0x6a9, 0x633, 0x62a, 0x627, 0x646, 0x52, 0x75, 0x6e, 0x61, 0x73, 0x69, 0x6d, 0x69, 0x50, +0x65, 0x72, 0xfa, 0x42, 0x6f, 0x6c, 0x69, 0x76, 0x69, 0x61, 0x45, 0x63, 0x75, 0x61, 0x64, 0x6f, 0x72, 0x72, 0x75, 0x6d, +0x61, 0x6e, 0x74, 0x73, 0x63, 0x68, 0x53, 0x76, 0x69, 0x7a, 0x72, 0x61, 0x72, 0x6f, 0x6d, 0xe2, 0x6e, 0x103, 0x52, 0x6f, +0x6d, 0xe2, 0x6e, 0x69, 0x61, 0x52, 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x20, 0x4d, 0x6f, 0x6c, 0x64, 0x6f, +0x76, 0x61, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x439, 0x420, 0x43e, 0x441, 0x441, 0x438, 0x44f, 0x41a, 0x430, 0x437, 0x430, 0x445, +0x441, 0x442, 0x430, 0x43d, 0x41a, 0x438, 0x440, 0x433, 0x438, 0x437, 0x438, 0x44f, 0x41c, 0x43e, 0x43b, 0x434, 0x43e, 0x432, 0x430, 0x423, +0x43a, 0x440, 0x430, 0x438, 0x43d, 0x430, 0x53, 0xe4, 0x6e, 0x67, 0xf6, 0x4b, 0xf6, 0x64, 0xf6, 0x72, 0xf6, 0x73, 0xea, 0x73, +0x65, 0x20, 0x74, 0xee, 0x20, 0x42, 0xea, 0x61, 0x66, 0x72, 0xee, 0x6b, 0x61, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x421, +0x440, 0x431, 0x438, 0x458, 0x430, 0x411, 0x43e, 0x441, 0x43d, 0x430, 0x20, 0x438, 0x20, 0x425, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, +0x432, 0x438, 0x43d, 0x430, 0x426, 0x440, 0x43d, 0x430, 0x20, 0x413, 0x43e, 0x440, 0x430, 0x41a, 0x43e, 0x441, 0x43e, 0x432, 0x43e, 0x73, +0x72, 0x70, 0x73, 0x6b, 0x69, 0x43, 0x72, 0x6e, 0x61, 0x20, 0x47, 0x6f, 0x72, 0x61, 0x53, 0x72, 0x62, 0x69, 0x6a, 0x61, +0x4b, 0x6f, 0x73, 0x6f, 0x76, 0x6f, 0x438, 0x440, 0x43e, 0x43d, 0x413, 0x443, 0x44b, 0x440, 0x434, 0x437, 0x44b, 0x441, 0x442, 0x43e, +0x43d, 0x423, 0x4d5, 0x440, 0x4d5, 0x441, 0x435, 0x63, 0x68, 0x69, 0x53, 0x68, 0x6f, 0x6e, 0x61, 0x633, 0x646, 0x68c, 0x64a, 0x67e, +0x627, 0x6aa, 0x633, 0x62a, 0x627, 0x646, 0xdc3, 0xdd2, 0xd82, 0xdc4, 0xdbd, 0xdc1, 0xdca, 0x200d, 0xdbb, 0xdd3, 0x20, 0xdbd, 0xd82, 0xd9a, +0xdcf, 0xdc0, 0x73, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0x10d, 0x69, 0x6e, 0x61, 0x53, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0x73, 0x6b, +0x6f, 0x73, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0x161, 0x10d, 0x69, 0x6e, 0x61, 0x53, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0x69, 0x6a, +0x61, 0x53, 0x6f, 0x6f, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x53, 0x6f, 0x6f, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x79, 0x61, 0x4a, +0x61, 0x62, 0x75, 0x75, 0x74, 0x69, 0x49, 0x74, 0x6f, 0x6f, 0x62, 0x69, 0x79, 0x61, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, +0x6c, 0x20, 0x64, 0x65, 0x20, 0x45, 0x73, 0x70, 0x61, 0xf1, 0x61, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x41, 0x72, +0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x61, 0x42, 0x65, 0x6c, 0x69, 0x63, 0x65, 0x43, 0x68, 0x69, 0x6c, 0x65, 0x43, 0x6f, +0x6c, 0x6f, 0x6d, 0x62, 0x69, 0x61, 0x43, 0x6f, 0x73, 0x74, 0x61, 0x20, 0x52, 0x69, 0x63, 0x61, 0x43, 0x75, 0x62, 0x61, +0x52, 0x65, 0x70, 0xfa, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x20, 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x6e, 0x61, +0x45, 0x6c, 0x20, 0x53, 0x61, 0x6c, 0x76, 0x61, 0x64, 0x6f, 0x72, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x20, 0x45, 0x63, +0x75, 0x61, 0x74, 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x47, 0x75, 0x61, 0x74, 0x65, 0x6d, 0x61, 0x6c, 0x61, 0x48, 0x6f, 0x6e, +0x64, 0x75, 0x72, 0x61, 0x73, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x20, 0x64, 0x65, 0x20, 0x4d, 0xe9, 0x78, 0x69, +0x63, 0x6f, 0x4d, 0xe9, 0x78, 0x69, 0x63, 0x6f, 0x4e, 0x69, 0x63, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x50, 0x61, 0x6e, +0x61, 0x6d, 0xe1, 0x50, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x79, 0x46, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x61, 0x73, +0x45, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x73, 0x20, 0x55, 0x6e, 0x69, 0x64, 0x6f, 0x73, 0x55, 0x72, 0x75, 0x67, 0x75, 0x61, +0x79, 0x56, 0x65, 0x6e, 0x65, 0x7a, 0x75, 0x65, 0x6c, 0x61, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x69, 0x61, 0x73, 0x65, 0x73, +0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x6e, 0x6f, 0x61, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x6e, +0x6f, 0x4c, 0x61, 0x74, 0x69, 0x6e, 0x6f, 0x61, 0x6d, 0xe9, 0x72, 0x69, 0x63, 0x61, 0x43, 0x65, 0x75, 0x74, 0x61, 0x20, +0x79, 0x20, 0x4d, 0x65, 0x6c, 0x69, 0x6c, 0x6c, 0x61, 0x4b, 0x69, 0x73, 0x77, 0x61, 0x68, 0x69, 0x6c, 0x69, 0x4a, 0x61, +0x6d, 0x68, 0x75, 0x72, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x69, 0x64, 0x65, 0x6d, 0x6f, 0x6b, 0x72, 0x61, 0x73, 0x69, +0x61, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x73, 0x76, 0x65, 0x6e, 0x73, 0x6b, 0x61, 0x53, 0x76, 0x65, +0x72, 0x69, 0x67, 0x65, 0xc5, 0x6c, 0x61, 0x6e, 0x64, 0x442, 0x43e, 0x4b7, 0x438, 0x43a, 0x4e3, 0x422, 0x43e, 0x4b7, 0x438, 0x43a, +0x438, 0x441, 0x442, 0x43e, 0x43d, 0xba4, 0xbae, 0xbbf, 0xbb4, 0xbcd, 0xb87, 0xba8, 0xbcd, 0xba4, 0xbbf, 0xbaf, 0xbbe, 0xbae, 0xbb2, 0xbc7, +0xb9a, 0xbbf, 0xbaf, 0xbbe, 0xb9a, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbaa, 0xbcd, 0xbaa, 0xbc2, 0xbb0, 0xbcd, 0xb87, 0xbb2, 0xb99, 0xbcd, 0xb95, +0xbc8, 0x442, 0x430, 0x442, 0x430, 0x440, 0xc24, 0xc46, 0xc32, 0xc41, 0xc17, 0xc41, 0xc2d, 0xc3e, 0xc30, 0xc24, 0xc26, 0xc47, 0xc36, 0xc02, +0xe44, 0xe17, 0xe22, 0xf56, 0xf7c, 0xf51, 0xf0b, 0xf66, 0xf90, 0xf51, 0xf0b, 0xf62, 0xf92, 0xfb1, 0xf0b, 0xf53, 0xf42, 0xf62, 0xf92, 0xfb1, +0xf0b, 0xf42, 0xf62, 0xf0b, 0x1275, 0x130d, 0x122d, 0x129b, 0x12a4, 0x122d, 0x1275, 0x122b, 0x6c, 0x65, 0x61, 0x20, 0x66, 0x61, 0x6b, 0x61, +0x74, 0x6f, 0x6e, 0x67, 0x61, 0x54, 0xfc, 0x72, 0x6b, 0xe7, 0x65, 0x54, 0xfc, 0x72, 0x6b, 0x69, 0x79, 0x65, 0x4b, 0x131, +0x62, 0x72, 0x131, 0x73, 0x74, 0xfc, 0x72, 0x6b, 0x6d, 0x65, 0x6e, 0x20, 0x64, 0x69, 0x6c, 0x69, 0x54, 0xfc, 0x72, 0x6b, +0x6d, 0x65, 0x6e, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x626, 0x6c7, 0x64a, 0x63a, 0x6c7, 0x631, 0x686, 0x6d5, 0x62c, 0x6c7, 0x6ad, 0x6af, +0x648, 0x443, 0x43a, 0x440, 0x430, 0x457, 0x43d, 0x441, 0x44c, 0x43a, 0x430, 0x423, 0x43a, 0x440, 0x430, 0x457, 0x43d, 0x430, 0x627, 0x631, +0x62f, 0x648, 0x628, 0x6be, 0x627, 0x631, 0x62a, 0x6f, 0x2018, 0x7a, 0x62, 0x65, 0x6b, 0x4f, 0x2bb, 0x7a, 0x62, 0x65, 0x6b, 0x69, +0x73, 0x74, 0x6f, 0x6e, 0x627, 0x648, 0x632, 0x628, 0x6cc, 0x6a9, 0x45e, 0x437, 0x431, 0x435, 0x43a, 0x447, 0x430, 0x40e, 0x437, 0x431, +0x435, 0x43a, 0x438, 0x441, 0x442, 0x43e, 0x43d, 0x54, 0x69, 0x1ebf, 0x6e, 0x67, 0x20, 0x56, 0x69, 0x1ec7, 0x74, 0x56, 0x69, 0x1ec7, +0x74, 0x20, 0x4e, 0x61, 0x6d, 0x56, 0x6f, 0x6c, 0x61, 0x70, 0xfc, 0x6b, 0x43, 0x79, 0x6d, 0x72, 0x61, 0x65, 0x67, 0x59, +0x20, 0x44, 0x65, 0x79, 0x72, 0x6e, 0x61, 0x73, 0x20, 0x55, 0x6e, 0x65, 0x64, 0x69, 0x67, 0x57, 0x6f, 0x6c, 0x6f, 0x66, +0x53, 0x65, 0x6e, 0x65, 0x67, 0x61, 0x61, 0x6c, 0x69, 0x73, 0x69, 0x58, 0x68, 0x6f, 0x73, 0x61, 0x65, 0x4d, 0x7a, 0x61, +0x6e, 0x74, 0x73, 0x69, 0x20, 0x41, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x5d9, 0x5d9, 0x5b4, 0x5d3, 0x5d9, 0x5e9, 0x5d5, 0x5d5, 0x5e2, +0x5dc, 0x5d8, 0xc8, 0x64, 0xe8, 0x20, 0x59, 0x6f, 0x72, 0xf9, 0x62, 0xe1, 0x4f, 0x72, 0xed, 0x6c, 0x1eb9, 0x301, 0xe8, 0x64, +0x65, 0x20, 0x4e, 0xe0, 0xec, 0x6a, 0xed, 0x72, 0xed, 0xe0, 0x4f, 0x72, 0xed, 0x6c, 0x25b, 0x301, 0xe8, 0x64, 0x65, 0x20, +0x42, 0x25b, 0x300, 0x6e, 0x25b, 0x300, 0x69, 0x73, 0x69, 0x5a, 0x75, 0x6c, 0x75, 0x69, 0x4e, 0x69, 0x6e, 0x67, 0x69, 0x7a, +0x69, 0x6d, 0x75, 0x20, 0x41, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x6e, 0x79, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x4e, 0x6f, 0x72, +0x65, 0x67, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x69, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x438, 0x47, 0x61, +0x65, 0x6c, 0x67, 0x45, 0x6c, 0x6c, 0x61, 0x6e, 0x20, 0x56, 0x61, 0x6e, 0x6e, 0x69, 0x6e, 0x6b, 0x65, 0x72, 0x6e, 0x65, +0x77, 0x65, 0x6b, 0x52, 0x79, 0x77, 0x76, 0x61, 0x6e, 0x65, 0x74, 0x68, 0x20, 0x55, 0x6e, 0x79, 0x73, 0x41, 0x6b, 0x61, +0x6e, 0x47, 0x61, 0x61, 0x6e, 0x61, 0x915, 0x94b, 0x902, 0x915, 0x923, 0x940, 0x49, 0x67, 0x62, 0x6f, 0x4e, 0x61, 0x1ecb, 0x6a, +0x1ecb, 0x72, 0x1ecb, 0x61, 0x4b, 0x69, 0x6b, 0x61, 0x6d, 0x62, 0x61, 0x66, 0x75, 0x72, 0x6c, 0x61, 0x6e, 0x49, 0x74, 0x61, +0x6c, 0x69, 0x65, 0x45, 0x28b, 0x65, 0x67, 0x62, 0x65, 0x47, 0x68, 0x61, 0x6e, 0x61, 0x20, 0x6e, 0x75, 0x74, 0x6f, 0x6d, +0x65, 0x54, 0x6f, 0x67, 0x6f, 0x20, 0x6e, 0x75, 0x74, 0x6f, 0x6d, 0x65, 0x2bb, 0x14c, 0x6c, 0x65, 0x6c, 0x6f, 0x20, 0x48, +0x61, 0x77, 0x61, 0x69, 0x2bb, 0x69, 0x2bb, 0x41, 0x6d, 0x65, 0x6c, 0x69, 0x6b, 0x61, 0x20, 0x48, 0x75, 0x69, 0x20, 0x50, +0x16b, 0x20, 0x2bb, 0x49, 0x61, 0x46, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x6f, 0x50, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, +0x61, 0x73, 0x53, 0x63, 0x68, 0x77, 0x69, 0x69, 0x7a, 0x65, 0x72, 0x74, 0xfc, 0xfc, 0x74, 0x73, 0x63, 0x68, 0x53, 0x63, +0x68, 0x77, 0x69, 0x69, 0x7a, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x72, 0x69, 0x69, 0x63, 0x68, 0x4c, 0x69, 0xe4, 0x63, 0x68, +0x74, 0x65, 0x73, 0x63, 0x68, 0x74, 0xe4, 0x69, 0xa188, 0xa320, 0xa259, 0xa34f, 0xa1e9, 0x4e, 0x65, 0x64, 0x64, 0x65, 0x72, 0x73, +0x61, 0x73, 0x73, 0x2019, 0x73, 0x63, 0x68, 0x44, 0xfc, 0xfc, 0x74, 0x73, 0x63, 0x68, 0x6c, 0x61, 0x6e, 0x64, 0x4e, 0x65, +0x64, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x6e, 0x64, 0x61, 0x76, 0x76, 0x69, 0x73, 0xe1, 0x6d, 0x65, 0x67, +0x69, 0x65, 0x6c, 0x6c, 0x61, 0x4e, 0x6f, 0x72, 0x67, 0x61, 0x53, 0x75, 0x6f, 0x70, 0x6d, 0x61, 0x52, 0x75, 0x6f, 0x167, +0x167, 0x61, 0x45, 0x6b, 0x65, 0x67, 0x75, 0x73, 0x69, 0x69, 0x4b, 0x69, 0x74, 0x61, 0x69, 0x74, 0x61, 0x50, 0x75, 0x6c, +0x61, 0x61, 0x72, 0x42, 0x75, 0x72, 0x6b, 0x69, 0x62, 0x61, 0x61, 0x20, 0x46, 0x61, 0x61, 0x73, 0x6f, 0x4b, 0x61, 0x6d, +0x65, 0x72, 0x75, 0x75, 0x6e, 0x47, 0x61, 0x6d, 0x6d, 0x62, 0x69, 0x47, 0x61, 0x6e, 0x61, 0x61, 0x47, 0x69, 0x6e, 0x65, +0x47, 0x69, 0x6e, 0x65, 0x2d, 0x42, 0x69, 0x73, 0x61, 0x61, 0x77, 0x6f, 0x4c, 0x69, 0x62, 0x65, 0x72, 0x69, 0x79, 0x61, +0x61, 0x4d, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x4e, 0x69, 0x6a, 0x65, 0x65, 0x72, 0x4e, 0x69, 0x6a, 0x65, 0x72, +0x69, 0x79, 0x61, 0x61, 0x53, 0x65, 0x72, 0x61, 0x61, 0x20, 0x6c, 0x69, 0x79, 0x6f, 0x6e, 0x47, 0x69, 0x6b, 0x75, 0x79, +0x75, 0x4b, 0x69, 0x73, 0x61, 0x6d, 0x70, 0x75, 0x72, 0x73, 0x65, 0x6e, 0x61, 0x69, 0x73, 0x69, 0x4e, 0x64, 0x65, 0x62, +0x65, 0x6c, 0x65, 0x4b, 0x69, 0x68, 0x6f, 0x72, 0x6f, 0x6d, 0x62, 0x6f, 0x2d5c, 0x2d30, 0x2d5b, 0x2d4d, 0x2d43, 0x2d49, 0x2d5c, 0x2d4d, +0x2d4e, 0x2d56, 0x2d54, 0x2d49, 0x2d31, 0x54, 0x61, 0x73, 0x68, 0x65, 0x6c, 0x1e25, 0x69, 0x79, 0x74, 0x6c, 0x6d, 0x263, 0x72, 0x69, +0x62, 0x54, 0x61, 0x71, 0x62, 0x61, 0x79, 0x6c, 0x69, 0x74, 0x4c, 0x65, 0x7a, 0x7a, 0x61, 0x79, 0x65, 0x72, 0x52, 0x75, +0x6e, 0x79, 0x61, 0x6e, 0x6b, 0x6f, 0x72, 0x65, 0x48, 0x69, 0x62, 0x65, 0x6e, 0x61, 0x48, 0x75, 0x74, 0x61, 0x6e, 0x7a, +0x61, 0x6e, 0x69, 0x61, 0x4b, 0x79, 0x69, 0x76, 0x75, 0x6e, 0x6a, 0x6f, 0x62, 0x61, 0x6d, 0x61, 0x6e, 0x61, 0x6b, 0x61, +0x6e, 0x4b, 0x129, 0x65, 0x6d, 0x62, 0x75, 0x13e3, 0x13b3, 0x13a9, 0x13cc, 0x13ca, 0x20, 0x13a2, 0x13f3, 0x13be, 0x13b5, 0x13cd, 0x13d4, 0x13c5, +0x20, 0x13cd, 0x13a6, 0x13da, 0x13a9, 0x6b, 0x72, 0x65, 0x6f, 0x6c, 0x20, 0x6d, 0x6f, 0x72, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x4d, +0x6f, 0x72, 0x69, 0x73, 0x43, 0x68, 0x69, 0x6d, 0x61, 0x6b, 0x6f, 0x6e, 0x64, 0x65, 0x4b, 0x268, 0x6c, 0x61, 0x61, 0x6e, +0x67, 0x69, 0x54, 0x61, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0xed, 0x61, 0x4c, 0x75, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x59, 0x75, +0x67, 0x61, 0x6e, 0x64, 0x61, 0x49, 0x63, 0x68, 0x69, 0x62, 0x65, 0x6d, 0x62, 0x61, 0x6b, 0x61, 0x62, 0x75, 0x76, 0x65, +0x72, 0x64, 0x69, 0x61, 0x6e, 0x75, 0x4b, 0x61, 0x62, 0x75, 0x20, 0x56, 0x65, 0x72, 0x64, 0x69, 0x4b, 0x129, 0x6d, 0x129, +0x72, 0x169, 0x4b, 0x61, 0x6c, 0x65, 0x6e, 0x6a, 0x69, 0x6e, 0x45, 0x6d, 0x65, 0x74, 0x61, 0x62, 0x20, 0x4b, 0x65, 0x6e, +0x79, 0x61, 0x4b, 0x68, 0x6f, 0x65, 0x6b, 0x68, 0x6f, 0x65, 0x67, 0x6f, 0x77, 0x61, 0x62, 0x4e, 0x61, 0x6d, 0x69, 0x62, +0x69, 0x61, 0x62, 0x4b, 0x69, 0x6d, 0x61, 0x63, 0x68, 0x61, 0x6d, 0x65, 0x4b, 0xf6, 0x6c, 0x73, 0x63, 0x68, 0x44, 0x6f, +0xfc, 0x74, 0x73, 0x63, 0x68, 0x6c, 0x61, 0x6e, 0x64, 0x4d, 0x61, 0x61, 0x54, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0x69, 0x61, +0x4f, 0x6c, 0x75, 0x73, 0x6f, 0x67, 0x61, 0x4c, 0x75, 0x6c, 0x75, 0x68, 0x69, 0x61, 0x4b, 0x69, 0x70, 0x61, 0x72, 0x65, +0x54, 0x61, 0x64, 0x68, 0x61, 0x6e, 0x69, 0x61, 0x4b, 0x69, 0x74, 0x65, 0x73, 0x6f, 0x4b, 0x65, 0x6e, 0x69, 0x61, 0x4b, +0x6f, 0x79, 0x72, 0x61, 0x20, 0x63, 0x69, 0x69, 0x6e, 0x69, 0x4d, 0x61, 0x61, 0x6c, 0x69, 0x4b, 0x69, 0x72, 0x75, 0x77, +0x61, 0x44, 0x68, 0x6f, 0x6c, 0x75, 0x6f, 0x52, 0x75, 0x6b, 0x69, 0x67, 0x61, 0x54, 0x61, 0x6d, 0x61, 0x7a, 0x69, 0x263, +0x74, 0x20, 0x6e, 0x20, 0x6c, 0x61, 0x1e6d, 0x6c, 0x61, 0x1e63, 0x4d, 0x65, 0x1e5b, 0x1e5b, 0x75, 0x6b, 0x4b, 0x6f, 0x79, 0x72, +0x61, 0x62, 0x6f, 0x72, 0x6f, 0x20, 0x73, 0x65, 0x6e, 0x6e, 0x69, 0x4b, 0x69, 0x73, 0x68, 0x61, 0x6d, 0x62, 0x61, 0x61, +0x92c, 0x921, 0x93c, 0x94b, 0x43d, 0x43e, 0x445, 0x447, 0x438, 0x439, 0x43d, 0x420, 0x43e, 0x441, 0x441, 0x438, 0x446, 0x435, 0x440, 0x43a, +0x43e, 0x432, 0x43d, 0x43e, 0x441, 0x43b, 0x43e, 0x432, 0x435, 0x301, 0x43d, 0x441, 0x43a, 0x457, 0x439, 0x440, 0x461, 0x441, 0x441, 0x456, +0x301, 0x430, 0x54, 0x73, 0x68, 0x69, 0x6c, 0x75, 0x62, 0x61, 0x44, 0x69, 0x74, 0x75, 0x6e, 0x67, 0x61, 0x20, 0x77, 0x61, +0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x75, 0x4c, 0xeb, 0x74, 0x7a, 0x65, 0x62, 0x75, 0x65, 0x72, 0x67, 0x65, 0x73, 0x63, 0x68, +0x4c, 0xeb, 0x74, 0x7a, 0x65, 0x62, 0x75, 0x65, 0x72, 0x67, 0x41, 0x67, 0x68, 0x65, 0x6d, 0x4b, 0xe0, 0x6d, 0xe0, 0x6c, +0xfb, 0x14b, 0x181, 0xe0, 0x73, 0xe0, 0x61, 0x4b, 0xe0, 0x6d, 0x25b, 0x300, 0x72, 0xfb, 0x6e, 0x5a, 0x61, 0x72, 0x6d, 0x61, +0x63, 0x69, 0x69, 0x6e, 0x65, 0x4e, 0x69, 0x17e, 0x65, 0x72, 0x64, 0x75, 0xe1, 0x6c, 0xe1, 0x6a, 0x6f, 0x6f, 0x6c, 0x61, +0x53, 0x65, 0x6e, 0x65, 0x67, 0x61, 0x6c, 0x65, 0x77, 0x6f, 0x6e, 0x64, 0x6f, 0x4b, 0x61, 0x6d, 0x259, 0x72, 0xfa, 0x6e, +0x72, 0x69, 0x6b, 0x70, 0x61, 0x6b, 0x61, 0x6d, 0x25b, 0x72, 0xfa, 0x6e, 0x4d, 0x61, 0x6b, 0x75, 0x61, 0x55, 0x6d, 0x6f, +0x7a, 0x61, 0x6d, 0x62, 0x69, 0x6b, 0x69, 0x4d, 0x55, 0x4e, 0x44, 0x41, 0x14a, 0x6b, 0x61, 0x6d, 0x65, 0x72, 0x75, 0x14b, +0x4b, 0x77, 0x61, 0x73, 0x69, 0x6f, 0x4b, 0x61, 0x6d, 0x65, 0x72, 0x75, 0x6e, 0x54, 0x68, 0x6f, 0x6b, 0x20, 0x4e, 0x61, +0x74, 0x68, 0x441, 0x430, 0x445, 0x430, 0x20, 0x442, 0x44b, 0x43b, 0x430, 0x410, 0x440, 0x430, 0x441, 0x441, 0x44b, 0x44b, 0x439, 0x430, +0x49, 0x73, 0x68, 0x69, 0x73, 0x61, 0x6e, 0x67, 0x75, 0x54, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0x69, 0x79, 0x61, 0x54, 0x61, +0x73, 0x61, 0x77, 0x61, 0x71, 0x20, 0x73, 0x65, 0x6e, 0x6e, 0x69, 0xa559, 0xa524, 0xa55e, 0xa524, 0xa52b, 0xa569, 0x56, 0x61, 0x69, +0x4c, 0x61, 0x69, 0x62, 0x68, 0x69, 0x79, 0x61, 0x57, 0x61, 0x6c, 0x73, 0x65, 0x72, 0x53, 0x63, 0x68, 0x77, 0x69, 0x7a, +0x6e, 0x75, 0x61, 0x73, 0x75, 0x65, 0x4b, 0x65, 0x6d, 0x65, 0x6c, 0xfa, 0x6e, 0x61, 0x73, 0x74, 0x75, 0x72, 0x69, 0x61, +0x6e, 0x75, 0x4e, 0x64, 0x61, 0xa78c, 0x61, 0x4b, 0x61, 0x6d, 0x25b, 0x6c, 0xfb, 0x6e, 0x6b, 0x61, 0x6b, 0x254, 0x4b, 0x61, +0x6d, 0x25b, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x74, 0x61, 0x2bc, 0x4b, 0x61, 0x6d, 0x61, 0x6c, 0x75, 0x6e, 0x53, 0x68, 0x77, +0xf3, 0x14b, 0xf2, 0x20, 0x6e, 0x67, 0x69, 0x65, 0x6d, 0x62, 0x254, 0x254, 0x6e, 0x4b, 0xe0, 0x6d, 0x61, 0x6c, 0xfb, 0x6d, +0x4c, 0x61, 0x6b, 0x21f, 0xf3, 0x6c, 0x2bc, 0x69, 0x79, 0x61, 0x70, 0x69, 0x4d, 0xed, 0x6c, 0x61, 0x68, 0x61, 0x14b, 0x73, +0x6b, 0x61, 0x20, 0x54, 0x21f, 0x61, 0x6d, 0xe1, 0x6b, 0x21f, 0x6f, 0x10d, 0x68, 0x65, 0x2d5c, 0x2d30, 0x2d4e, 0x2d30, 0x2d63, 0x2d49, +0x2d56, 0x2d5c, 0x6a9, 0x648, 0x631, 0x62f, 0x6cc, 0x6cc, 0x20, 0x646, 0x627, 0x648, 0x6d5, 0x646, 0x62f, 0x6cc, 0x639, 0x6ce, 0x631, 0x627, +0x642, 0x626, 0x6ce, 0x631, 0x627, 0x646, 0x64, 0x6f, 0x6c, 0x6e, 0x6f, 0x73, 0x65, 0x72, 0x62, 0x161, 0x107, 0x69, 0x6e, 0x61, +0x4e, 0x69, 0x6d, 0x73, 0x6b, 0x61, 0x68, 0x6f, 0x72, 0x6e, 0x6a, 0x6f, 0x73, 0x65, 0x72, 0x62, 0x161, 0x107, 0x69, 0x6e, +0x61, 0x4e, 0x11b, 0x6d, 0x73, 0x6b, 0x61, 0x70, 0x72, 0x16b, 0x73, 0x69, 0x73, 0x6b, 0x61, 0x6e, 0x73, 0x77, 0x12b, 0x74, +0x61, 0x69, 0x61, 0x6e, 0x61, 0x72, 0xe2, 0x161, 0x6b, 0x69, 0x65, 0x6c, 0xe2, 0x53, 0x75, 0x6f, 0x6d, 0xe2, 0x645, 0x627, +0x632, 0x631, 0x648, 0x646, 0x6cc, 0x644, 0x6ca, 0x631, 0x6cc, 0x20, 0x634, 0x648, 0x645, 0x627, 0x644, 0x6cc, 0x7cb5, 0x8a9e, 0x4e2d, 0x83ef, +0x4eba, 0x6c11, 0x5171, 0x548c, 0x570b, 0x9999, 0x6e2f, 0x7279, 0x5225, 0x884c, 0x653f, 0x5340, 0x7ca4, 0x8bed, 0x4e2d, 0x534e, 0x4eba, 0x6c11, 0x5171, 0x548c, +0x56fd }; static const char language_name_list[] = diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h index f2e11499c8..a9c23aed61 100644 --- a/src/corelib/tools/qlocale_p.h +++ b/src/corelib/tools/qlocale_p.h @@ -408,9 +408,10 @@ inline char QLocaleData::digitToCLocale(QChar in) const if (in == m_exponential || in == QChar::toUpper(m_exponential)) return 'e'; - // In several languages group() is the char 0xA0, which looks like a space. - // People use a regular space instead of it and complain it doesn't work. - if (m_group == 0xA0 && in.unicode() == ' ') + // In several languages group() is a non-breaking space (U+00A0) or its thin + // version (U+202f), which look like spaces. People (and thus some of our + // tests) use a regular space instead and complain if it doesn't work. + if ((m_group == 0xA0 || m_group == 0x202f) && in.unicode() == ' ') return ','; return 0; diff --git a/src/corelib/tools/qt_attribution.json b/src/corelib/tools/qt_attribution.json index 63288be4e3..5bb95c9f5b 100644 --- a/src/corelib/tools/qt_attribution.json +++ b/src/corelib/tools/qt_attribution.json @@ -20,13 +20,14 @@ "Name": "Unicode Common Locale Data Repository (CLDR)", "QDocModule": "qtcore", "QtUsage": "Used in Qt Core (QTimeZone, QLocale).", + "Files": "For update, see qtbase/util/local_database/cldr2qlocalexml.py", "Files": "qlocale_data_p.h qtimezoneprivate_data_p.h", "Description": "The Unicode CLDR provides key building blocks for software to support the world's languages, with the largest and most extensive standard repository of locale data available.", "Homepage": "http://cldr.unicode.org/", - "Version": "v33.1", + "Version": "v34", "License": "// as specified in https://spdx.org/licenses/Unicode-DFS-2016.html", "License": "Unicode License Agreement - Data Files and Software (2016)", "LicenseId": "Unicode-DFS-2016", diff --git a/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp b/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp index e2f1307eb1..20aad6ba97 100644 --- a/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp +++ b/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp @@ -3848,7 +3848,7 @@ void tst_QDateTimeEdit::dateEditCorrectSectionSize_data() << threeDigitDayIssueKeypresses_DayName << QString::fromLatin1("00/2/Tuesday"); QTest::newRow("no fixday, leap, yy/M/ddd") << defaultLocale << defaultDate << QString::fromLatin1("yy/M/ddd") - << threeDigitDayIssueKeypresses_DayName << QString::fromLatin1("00/2/Tue."); + << threeDigitDayIssueKeypresses_DayName << QString::fromLatin1("00/2/Tue"); QTest::newRow("no fixday, leap, yy/MM/dddd") << defaultLocale << defaultDate << QString::fromLatin1("yy/MM/dddd") << threeDigitDayIssueKeypresses_DayName << QString::fromLatin1("00/02/Tuesday"); @@ -3896,13 +3896,13 @@ void tst_QDateTimeEdit::dateEditCorrectSectionSize_data() << threeDigitDayIssueKeypresses_YearDayMonth << QString::fromLatin1("2000/29/2"); QTest::newRow("fixday, leap, yyyy/MMM/dd") << defaultLocale << defaultDate << QString::fromLatin1("yyyy/MMM/dd") - << threeDigitDayIssueKeypresses_ShortMonthName << QString::fromLatin1("2000/Feb./29"); + << threeDigitDayIssueKeypresses_ShortMonthName << QString::fromLatin1("2000/Feb/29"); QTest::newRow("fixday, leap, yyyy/MMM/d") << defaultLocale << defaultDate << QString::fromLatin1("yyyy/MMM/d") - << threeDigitDayIssueKeypresses_ShortMonthName << QString::fromLatin1("2000/Feb./29"); + << threeDigitDayIssueKeypresses_ShortMonthName << QString::fromLatin1("2000/Feb/29"); QTest::newRow("fixday, leap, yy/MMM/dd") << defaultLocale << defaultDate << QString::fromLatin1("yy/MMM/dd") - << threeDigitDayIssueKeypresses_ShortMonthName << QString::fromLatin1("00/Feb./29"); + << threeDigitDayIssueKeypresses_ShortMonthName << QString::fromLatin1("00/Feb/29"); QTest::newRow("fixday, leap, yyyy/dddd/M") << defaultLocale << defaultDate << QString::fromLatin1("yyyy/dddd/M") << threeDigitDayIssueKeypresses_DayName_YearDayMonth << QString::fromLatin1("2000/Tuesday/2"); @@ -3977,16 +3977,16 @@ void tst_QDateTimeEdit::dateEditCorrectSectionSize_data() << threeDigitDayIssueKeypresses_MonthYearDay << QString::fromLatin1("02/2000/29"); QTest::newRow("fixday, leap, MMM/yy/d") << defaultLocale << defaultDate << QString::fromLatin1("MMM/yy/d") - << threeDigitDayIssueKeypresses_ShortMonthName_MonthYearDay << QString::fromLatin1("Feb./00/29"); + << threeDigitDayIssueKeypresses_ShortMonthName_MonthYearDay << QString::fromLatin1("Feb/00/29"); QTest::newRow("fixday, leap, MMM/yyyy/d") << defaultLocale << defaultDate << QString::fromLatin1("MMM/yyyy/d") - << threeDigitDayIssueKeypresses_ShortMonthName_MonthYearDay << QString::fromLatin1("Feb./2000/29"); + << threeDigitDayIssueKeypresses_ShortMonthName_MonthYearDay << QString::fromLatin1("Feb/2000/29"); QTest::newRow("fixday, MMM/yyyy/d") << defaultLocale << defaultDate.addYears(1) << QString::fromLatin1("MMM/yyyy/d") - << threeDigitDayIssueKeypresses_ShortMonthName_MonthYearDay << QString::fromLatin1("Feb./2001/28"); + << threeDigitDayIssueKeypresses_ShortMonthName_MonthYearDay << QString::fromLatin1("Feb/2001/28"); QTest::newRow("fixday, leap, MMM/yyyy/dd") << defaultLocale << defaultDate << QString::fromLatin1("MMM/yyyy/dd") - << threeDigitDayIssueKeypresses_ShortMonthName_MonthYearDay << QString::fromLatin1("Feb./2000/29"); + << threeDigitDayIssueKeypresses_ShortMonthName_MonthYearDay << QString::fromLatin1("Feb/2000/29"); QTest::newRow("fixday, leap, dddd, dd. MMMM yyyy") << defaultLocale << defaultDate << QString::fromLatin1("dddd, dd. MMMM yyyy") From afba8fcc4914b80be7733a059b26411bdde510eb Mon Sep 17 00:00:00 2001 From: Paul Wicking Date: Mon, 29 Oct 2018 12:30:34 +0100 Subject: [PATCH 0176/1650] Doc: Add description for mode argument of qmake's $$system() Fixes: QTBUG-70926 Change-Id: Icfd13352cd64053c11502058188041ad16f6c287 Reviewed-by: Edward Welbourne Reviewed-by: Oswald Buddenhagen --- qmake/doc/src/qmake-manual.qdoc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index 0ded8b574a..1a779a94b4 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -3038,6 +3038,7 @@ \snippet code/doc_src_qmake-manual.pro 59 + \target qmake-cat \section2 cat(filename[, mode]) Returns the contents of \c filename. You can specify the following options @@ -3404,6 +3405,10 @@ \snippet code/doc_src_qmake-manual.pro 72 + Like \l {qmake-cat}{$$cat()}, the \a mode argument takes \c blob, \c lines, + \c true, and \false as value. However, the legacy word splitting rules + (i.e. empty or \c true, and \c false) differ subtly. + If you pass \c stsvar, the command's exit status will be stored in that variable. If the command crashes, the status will be -1, otherwise a non-negative exit code of the command's choosing. Usually, comparing From 47869340b97686a4bf852f94edc3bae1e50d7053 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Wed, 31 Oct 2018 12:52:27 +0100 Subject: [PATCH 0177/1650] Doc: Solve issue with gridlayout image file Due to name conflict with file from qtdeclarative Task-number: QTBUG-65769 Change-Id: I9ebf237701ce76b424f528feacb24e4158f06c0d Reviewed-by: Venugopal Shivashankar --- .../doc/images/{gridlayout.png => qgridlayout.png} | Bin src/widgets/kernel/qgridlayout.cpp | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename src/widgets/doc/images/{gridlayout.png => qgridlayout.png} (100%) diff --git a/src/widgets/doc/images/gridlayout.png b/src/widgets/doc/images/qgridlayout.png similarity index 100% rename from src/widgets/doc/images/gridlayout.png rename to src/widgets/doc/images/qgridlayout.png diff --git a/src/widgets/kernel/qgridlayout.cpp b/src/widgets/kernel/qgridlayout.cpp index db8ef89477..f1c6c96a6d 100644 --- a/src/widgets/kernel/qgridlayout.cpp +++ b/src/widgets/kernel/qgridlayout.cpp @@ -1029,7 +1029,7 @@ QRect QGridLayoutPrivate::cellRect(int row, int col) const This illustration shows a fragment of a dialog with a five-column, three-row grid (the grid is shown overlaid in magenta): - \image gridlayout.png A grid layout + \image qgridlayout.png A grid layout Columns 0, 2 and 4 in this dialog fragment are made up of a QLabel, a QLineEdit, and a QListBox. Columns 1 and 3 are From daf9ba91ae19054b5860f87f8f39b518d60cda38 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Thu, 18 Oct 2018 15:55:43 +0200 Subject: [PATCH 0178/1650] Stabilize tst_QAccessibilityLinux::testFocus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tests would rely on the window manager giving it focus a bit too much. Change-Id: I1b28def2c95a4f0a9665a7cf6e0c14db03df98d5 Reviewed-by: Jędrzej Nowacki --- .../auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp b/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp index 47d24ce171..48594b2fa1 100644 --- a/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp +++ b/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp @@ -502,6 +502,8 @@ void tst_QAccessibilityLinux::testSlider() void tst_QAccessibilityLinux::testFocus() { + m_window->activateWindow(); + QVERIFY(QTest::qWaitForWindowActive(m_window)); QLineEdit *lineEdit1 = new QLineEdit(m_window); lineEdit1->setText("lineEdit 1"); QLineEdit *lineEdit2 = new QLineEdit(m_window); From ceeecbae510af6e2d1ebbf865761e4761d404033 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 22 Oct 2018 15:53:35 +0200 Subject: [PATCH 0179/1650] Update various qt_attribution.json files Marking various as final because no upstream is known or available. Listing versions of others, where I was able to discover them. Updated a stale link (that helpfully redirected). Task-number: QTBUG-70008 Change-Id: Id00f34827133c560735c68793b4f1353f2b2ca85 Reviewed-by: Tobias Koenig Reviewed-by: Lars Knoll Reviewed-by: Jani Heikkinen Reviewed-by: Volker Hilsheimer --- src/3rdparty/easing/qt_attribution.json | 3 +++ src/3rdparty/forkfd/qt_attribution.json | 2 ++ src/3rdparty/freebsd/qt_attribution.json | 5 +++++ src/3rdparty/iaccessible2/qt_attribution.json | 2 +- src/3rdparty/icc/qt_attribution.json | 2 ++ src/3rdparty/md4/qt_attribution.json | 1 + src/3rdparty/md5/qt_attribution.json | 1 + src/3rdparty/rfc6234/qt_attribution.json | 1 + src/3rdparty/tinycbor/qt_attribution.json | 1 + src/3rdparty/wintab/qt_attribution.json | 1 + src/corelib/codecs/qt_attribution.json | 7 +++++++ src/corelib/kernel/qt_attribution.json | 1 + 12 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/3rdparty/easing/qt_attribution.json b/src/3rdparty/easing/qt_attribution.json index b6240c61c8..bccc67b6d4 100644 --- a/src/3rdparty/easing/qt_attribution.json +++ b/src/3rdparty/easing/qt_attribution.json @@ -3,7 +3,10 @@ "Name": "Easing Equations by Robert Penner", "QDocModule": "qtcore", "QtUsage": "Used in Qt Core (QEasingCurve).", + "Files": "easing.cpp", + "Homepage": "treat as final", + "Homepage": "http://robertpenner.com/easing/", "License": "BSD 3-clause \"New\" or \"Revised\" License", "LicenseId": "BSD-3-Clause", "LicenseFile": "LICENSE", diff --git a/src/3rdparty/forkfd/qt_attribution.json b/src/3rdparty/forkfd/qt_attribution.json index f004116753..ebbb19c718 100644 --- a/src/3rdparty/forkfd/qt_attribution.json +++ b/src/3rdparty/forkfd/qt_attribution.json @@ -3,6 +3,8 @@ "Name": "forkfd", "QDocModule": "qtcore", "QtUsage": "Used on most Unix platforms in Qt Core.", + "Files": "No upstream; treat as final", + "Files": "forkfd.c forkfd.h forkfd_gcc.h", "License": "MIT License", "LicenseId": "MIT", diff --git a/src/3rdparty/freebsd/qt_attribution.json b/src/3rdparty/freebsd/qt_attribution.json index 57f425cdbc..6a4a9ca1af 100644 --- a/src/3rdparty/freebsd/qt_attribution.json +++ b/src/3rdparty/freebsd/qt_attribution.json @@ -3,8 +3,13 @@ "Name": "FreeBSD strtoll and strtoull", "QDocModule": "qtcore", "QtUsage": "Used in Qt Core.", + "Files": "strtoll.c strtoull.c", "Description": "strtoll() and strtoull() are functions for converting a string to (unsigned) long long integer.", + "Homepage": "https://github.com/freebsd/freebsd/", + "Upstream": "https://raw.githubusercontent.com/freebsd/freebsd/raw/tree/master/lib/libc/stdlib/$file", + "Version": "upstream has complicated with std locales; do not update", + "Version": "18b29f3fb8abee5d57ed8f4a44f806bec7e0eeff", "License": "BSD 3-clause \"New\" or \"Revised\" License", "LicenseId": "BSD-3-Clause", "LicenseFile": "LICENSE", diff --git a/src/3rdparty/iaccessible2/qt_attribution.json b/src/3rdparty/iaccessible2/qt_attribution.json index 290d0d4b7d..eea8314f1a 100644 --- a/src/3rdparty/iaccessible2/qt_attribution.json +++ b/src/3rdparty/iaccessible2/qt_attribution.json @@ -5,7 +5,7 @@ "QtUsage": "Optionally used in the Windows platform plugin. Configure with -no-accessibility to avoid.", "Description": "IAccessible2 is a new accessibility API which complements Microsoft's earlier work on MSAA", - "Homepage": "http://www.linuxfoundation.org/collaborate/workgroups/accessibility/iaccessible2", + "Homepage": "https://wiki.linuxfoundation.org/accessibility/iaccessible2/", "Version": "1.3.0", "License": "BSD 3-clause \"New\" or \"Revised\" License", "LicenseId": "BSD-3-Clause", diff --git a/src/3rdparty/icc/qt_attribution.json b/src/3rdparty/icc/qt_attribution.json index 7a1c813522..06049954e3 100644 --- a/src/3rdparty/icc/qt_attribution.json +++ b/src/3rdparty/icc/qt_attribution.json @@ -4,9 +4,11 @@ "Name": "sRGB color profile icc file", "QDocModule": "qtgui", "QtUsage": "Used in Qt Gui (Embedded into PDF/A-1b files generated by QPrinter/QPdfWriter).", + "Files": "No upstream: treat as final", "Files": "sRGB2014.icc", "Description": "An ICC color profile for PDF/A-1b compatible PDF files.", + "Homepage": "http://www.color.org/", "LicenseId": "ICC License", "License": "International Color Consortium License", "LicenseFile": "LICENSE.txt", diff --git a/src/3rdparty/md4/qt_attribution.json b/src/3rdparty/md4/qt_attribution.json index f1bca24660..ea7e22705f 100644 --- a/src/3rdparty/md4/qt_attribution.json +++ b/src/3rdparty/md4/qt_attribution.json @@ -4,6 +4,7 @@ "QDocModule": "qtcore", "QtUsage": "Used in Qt Core (QCryptographicHash). Configure with -DQT_CRYPTOGRAPHICHASH_ONLY_SHA1 to avoid.", + "Description": "Treat as final version; no upstream known", "Description": "An OpenSSL-compatible implementation of the RSA Data Security, Inc. MD4 Message-Digest Algorithm.", "License": "Public Domain", "Copyright": "Written by Alexander Peslyak - better known as Solar Designer - in 2001, and placed in the public domain. There's absolutely no warranty." diff --git a/src/3rdparty/md5/qt_attribution.json b/src/3rdparty/md5/qt_attribution.json index 52b613cf6c..e9783f9e49 100644 --- a/src/3rdparty/md5/qt_attribution.json +++ b/src/3rdparty/md5/qt_attribution.json @@ -4,6 +4,7 @@ "QDocModule": "qtcore", "QtUsage": "Used in Qt Core (QCryptographicHash). Configure with -DQT_CRYPTOGRAPHICHASH_ONLY_SHA1 to avoid.", + "Description": "Treat as final version; no upstream known", "Description": "MD5 message-digest algorithm.", "License": "Public Domain", "Copyright": "Written by Colin Plumb in 1993, no copyright is claimed. diff --git a/src/3rdparty/rfc6234/qt_attribution.json b/src/3rdparty/rfc6234/qt_attribution.json index 9fc427b4a6..1cce430cf6 100644 --- a/src/3rdparty/rfc6234/qt_attribution.json +++ b/src/3rdparty/rfc6234/qt_attribution.json @@ -4,6 +4,7 @@ "QDocModule": "qtcore", "QtUsage": "Used in Qt Core (QCryptographicHash and QMessageAuthenticationCode)", + "Description": "The RFC actually contains the code, embedded in RFC-boilerplate; presumably we extracted it; treat as final", "Description": "Implements the Secure Hash Algorithms SHA 384 and SHA-521", "License": "BSD 3-clause \"New\" or \"Revised\" License", "LicenseFile": "LICENSE", diff --git a/src/3rdparty/tinycbor/qt_attribution.json b/src/3rdparty/tinycbor/qt_attribution.json index 1d61534861..5b6355d013 100644 --- a/src/3rdparty/tinycbor/qt_attribution.json +++ b/src/3rdparty/tinycbor/qt_attribution.json @@ -5,6 +5,7 @@ "QtUsage": "Used for QCborStreamReader and QCborStreamWriter.", "Description": "Concise Binary Object Representation (CBOR) Library", + "Version": "0.6.0", "Homepage": "https://github.com/intel/tinycbor", "License": "MIT License", "LicenseId": "MIT", diff --git a/src/3rdparty/wintab/qt_attribution.json b/src/3rdparty/wintab/qt_attribution.json index ac06e8da5a..f0c9b49841 100644 --- a/src/3rdparty/wintab/qt_attribution.json +++ b/src/3rdparty/wintab/qt_attribution.json @@ -5,6 +5,7 @@ "QtUsage": "Used in the Qt platform plugin for Windows. Configure with -no-feature-tabletevent to avoid.", "Description": "Wintab is a de facto API for pointing devices on Windows.", + "Version": "Upstream no longer offers updates; treat as final", "Homepage": "http://www.pointing.com/Wintab.html", "License": "Public Domain", "LicenseId": "NONE", diff --git a/src/corelib/codecs/qt_attribution.json b/src/corelib/codecs/qt_attribution.json index 41f644a030..0815074675 100644 --- a/src/corelib/codecs/qt_attribution.json +++ b/src/corelib/codecs/qt_attribution.json @@ -6,6 +6,7 @@ "QtUsage": "Used in Qt Core if ICU is not used. Configure with -icu to avoid.", "Path": "qbig5codec.cpp", + "Description": "Treat as final version; no upstream known", "Description": "The Big5 codecs (QBig5Codec, QBig5hkscsCodec) provide conversion to and from the Big5 encodings.", "License": "BSD 2-clause \"Simplified\" License", @@ -23,6 +24,7 @@ Copyright (C) 2001, 2002 Anthony Fok, ThizLinux Laboratory Ltd." "QtUsage": "Used in Qt Core if ICU is not used. Configure with -icu to avoid.", "Path": "qeucjpcodec.cpp", + "Description": "Treat as final version; no upstream known", "Description": "The EUC-JP text codec provides conversion to and from EUC-JP, the main legacy encoding for Unix machines in Japan.", "License": "BSD 2-clause \"Simplified\" License", @@ -37,6 +39,7 @@ the main legacy encoding for Unix machines in Japan.", "QtUsage": "Used in Qt Core if ICU is not used. Configure with -icu to avoid.", "Path": "qeuckrcodec.cpp", + "Description": "Treat as final version; no upstream known", "Description": "The EUC-KR text codec provides conversion to and from EUC-KR, KR, the main legacy encoding for Unix machines in Korea.", "License": "BSD 2-clause \"Simplified\" License", @@ -51,6 +54,7 @@ the main legacy encoding for Unix machines in Korea.", "QtUsage": "Used in Qt Core if ICU is not used. Configure with -icu to avoid.", "Path": "qjiscodec.cpp", + "Description": "Treat as final version; no upstream known", "Description": "The ISO 2022-JP (JIS) text codec provides conversion to and from ISO 2022-JP.", "License": "BSD 2-clause \"Simplified\" License", "LicenseId": "BSD-2-Clause", @@ -64,6 +68,7 @@ the main legacy encoding for Unix machines in Korea.", "QtUsage": "Used in Qt Core if ICU is not used. Configure with -icu to avoid.", "Path": "qsjiscodec.cpp", + "Description": "Treat as final version; no upstream known", "Description": "The Shift-JIS text codec provides conversion to and from Shift-JIS.", "License": "BSD 2-clause \"Simplified\" License", "LicenseId": "BSD-2-Clause", @@ -77,6 +82,7 @@ the main legacy encoding for Unix machines in Korea.", "QtUsage": "Used in Qt Core.", "Path": "qtsciicodec.cpp", + "Description": "Treat as final version; no upstream known", "Description": "The TSCII text codec provides conversion to and from the Tamil TSCII encoding.", "License": "BSD 2-clause \"Simplified\" License", @@ -91,6 +97,7 @@ encoding.", "QtUsage": "Used in Qt Core if ICU is not used. Configure with -icu to avoid.", "Path": "qgb18030codec.cpp", + "Description": "Treat as final version; no upstream known", "Description": "The GBK codec provides conversion to and from the Chinese GB18030/GBK/GB2312 encoding.", "License": "BSD 2-clause \"Simplified\" License", diff --git a/src/corelib/kernel/qt_attribution.json b/src/corelib/kernel/qt_attribution.json index 37764a5330..6d8f4f2abc 100644 --- a/src/corelib/kernel/qt_attribution.json +++ b/src/corelib/kernel/qt_attribution.json @@ -5,6 +5,7 @@ "QtUsage": "Used in Qt Core on macOS.", "Path": "qeventdispatcher_cf_p.h", + "Description": "Treat as final version; no upstream known", "Description": "Implementation of QAbstractEventDispatcher for macOS.", "License": "BSD 3-clause \"New\" or \"Revised\" License", "LicenseId": "BSD-3-Clause", From dc2aead842f4cdf74f9259d3606c53c8bdae2c6b Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 1 Nov 2018 17:40:27 +0100 Subject: [PATCH 0180/1650] Fix build with -qt-libpng on powerpc It appears we are missing some setups for SIMD optimization, and already have a workaround for that for NEON, so do the same for VSX. Fixes: QTBUG-66388 Change-Id: I1cc1d0fe9c5a9df97acb589d29dec4dceb8fc576 Reviewed-by: Eirik Aavitsland --- src/3rdparty/libpng/libpng.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3rdparty/libpng/libpng.pro b/src/3rdparty/libpng/libpng.pro index 577b61d833..a2f56669b4 100644 --- a/src/3rdparty/libpng/libpng.pro +++ b/src/3rdparty/libpng/libpng.pro @@ -10,7 +10,7 @@ MODULE_INCLUDEPATH = $$PWD load(qt_helper_lib) -DEFINES += PNG_ARM_NEON_OPT=0 +DEFINES += PNG_ARM_NEON_OPT=0 PNG_POWERPC_VSX_OPT=0 SOURCES += \ png.c \ pngerror.c \ From 98365711a0c06673b8f55d43ba227a640dc798a6 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sun, 28 Oct 2018 15:30:51 +0100 Subject: [PATCH 0181/1650] Remove unused variable Change-Id: I241969d10502e944f7a73971771730d43dd2784f Reviewed-by: Gatis Paeglis --- src/plugins/platforms/xcb/qxcbeventdispatcher.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbeventdispatcher.h b/src/plugins/platforms/xcb/qxcbeventdispatcher.h index 6aadd63a70..ddf448cf87 100644 --- a/src/plugins/platforms/xcb/qxcbeventdispatcher.h +++ b/src/plugins/platforms/xcb/qxcbeventdispatcher.h @@ -107,9 +107,6 @@ class QXcbEventDispatcher { public: static QAbstractEventDispatcher *createEventDispatcher(QXcbConnection *connection); - -private: - QXcbConnection *m_connection; }; QT_END_NAMESPACE From 67c66c4ea4fbc11ee5547095117ef8930b3ab950 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Fri, 7 Sep 2018 15:01:07 +0200 Subject: [PATCH 0182/1650] windows: Give up on SwitchableComposition Opt out of switching between the normal and OpenGL based flush paths. Once a QOpenGLWidget or QQuickWidget becomes visible in a window, the window contents will be composed using OpenGL from that point on, even if said widgets become invisible afterwards. Now that Qt Creator does not rely on QQuickWidget the issue is less burning anyways. Task-number: QTBUG-68329 Change-Id: I177e6e6094ee06ea26d8d0343bd3d84aadfa5913 Reviewed-by: Friedemann Kleint Reviewed-by: Allan Sandfeld Jensen --- .../platforms/windows/qwindowsintegration.cpp | 2 +- src/widgets/kernel/qwidgetbackingstore.cpp | 14 +------------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 0a9e8b9d91..66a5c52da5 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -300,7 +300,7 @@ bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) co case AllGLFunctionsQueryable: return true; case SwitchableWidgetComposition: - return true; + return false; // QTBUG-68329 QTBUG-53515 QTBUG-54734 default: return QPlatformIntegration::hasCapability(cap); } diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index 3b093283cd..96a64f12c7 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -1000,20 +1000,8 @@ static QPlatformTextureList *widgetTexturesFor(QWidget *tlw, QWidget *widget) static bool switchableWidgetComposition = QGuiApplicationPrivate::instance()->platformIntegration() ->hasCapability(QPlatformIntegration::SwitchableWidgetComposition); - if (!switchableWidgetComposition -// The Windows compositor handles fullscreen OpenGL window specially. Besides -// having trouble with popups, it also has issues with flip-flopping between -// OpenGL-based and normal flushing. Therefore, stick with GL for fullscreen -// windows (QTBUG-53515). Similary, translucent windows should not switch to -// layered native windows (QTBUG-54734). -#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) && !defined(Q_OS_WINCE) - || tlw->windowState().testFlag(Qt::WindowFullScreen) - || tlw->testAttribute(Qt::WA_TranslucentBackground) -#endif - ) - { + if (!switchableWidgetComposition) return qt_dummy_platformTextureList(); - } } return 0; From 60197af4850e13409f26551ce812e866602e6926 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Fri, 2 Nov 2018 08:43:31 +0200 Subject: [PATCH 0183/1650] Android: Fix build.gradle Configuration 'compile' is obsolete and has been replaced with 'implementation' and 'api'. It will be removed at the end of 2018. For more information see: http://d.android.com/r/tools/update-dependency-configurations.html Task-number: QTBUG-71570 Change-Id: I6f498d8cb3ff01ad641aee697496e3dc56059a72 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/android/templates/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/android/templates/build.gradle b/src/android/templates/build.gradle index bf5ce1388a..fcd8ae345d 100644 --- a/src/android/templates/build.gradle +++ b/src/android/templates/build.gradle @@ -17,7 +17,7 @@ repositories { apply plugin: 'com.android.application' dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) + implementation fileTree(dir: 'libs', include: ['*.jar']) } android { From 81d8319276f26d399bdff47b49bd69b19bd86c5a Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Wed, 10 Oct 2018 15:54:07 +0200 Subject: [PATCH 0184/1650] doc: Fix all clang parse errors in QtBase during PCH build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This update eliminates ALL parsing errors when clang parses the Qt headers to build the precompiled header qdoc needs. These errors are often cases where an old use of Q_QDOC no longer works because clang sees the enclosed fake declarations as erroneous. In a few cases, clang reported errors because two dummy function declartations under the Q_CLANG_QDOC guard were indistinguishable, so one of them was removed, and the documentation was patched accordingly. Using the macro Q_DECLARE_INTERFACE(...) causes clang to report errors because the class parametewr is abstract. These uses of the macro are not needed, so they are removed with #ifndef Q_CLANG_QDOC. Some declarations of default GL types that had been provided for qdoc were no longer needed, so they are removed. Now there are some member function signatures in QDBusPendingReply and QDBusPendingCall that have very long template clauses and qualifiers in their signatures. These unwieldy signatures will be unnecessary in the documentation and will look bad there, but for now they are correct. The ultimate solution will be to add a metacommand to qdoc, something like \simplify-signature to tell qdoc to generate the documentation for these member functions without the long template caluses and qualifiers. Change-Id: I012cf17a544fbba2ebc71002f31bdc865119bb8e Reviewed-by: Paul Wicking Reviewed-by: Topi Reiniö Reviewed-by: Martin Smith --- src/corelib/global/qfloat16.h | 2 - src/corelib/io/qprocess.h | 2 +- src/corelib/kernel/qmetatype.h | 4 +- src/corelib/kernel/qvariant.h | 4 +- src/corelib/plugin/qfactoryinterface.h | 3 +- src/corelib/serialization/qjsonvalue.h | 2 - src/corelib/thread/qresultstore.cpp | 15 +++++++ src/corelib/thread/qresultstore.h | 2 - src/corelib/tools/qbytearraylist.h | 6 +-- src/dbus/qdbusargument.cpp | 2 +- src/dbus/qdbusargument.h | 12 +----- src/dbus/qdbusconnection.h | 2 - src/dbus/qdbuspendingcall.cpp | 12 +++--- src/dbus/qdbuspendingcall.h | 2 +- src/dbus/qdbuspendingreply.cpp | 29 ++++++------- src/dbus/qdbuspendingreply.h | 3 -- src/dbus/qdbusreply.cpp | 2 +- src/dbus/qdbusreply.h | 4 -- src/dbus/qdbusutil.cpp | 30 ++++++------- src/gui/accessible/qaccessible.h | 2 + src/gui/opengl/qopenglfunctions.h | 18 -------- src/gui/opengl/qopenglshaderprogram.h | 7 ---- src/gui/text/qabstracttextdocumentlayout.h | 2 + src/network/kernel/qhostinfo.cpp | 29 +++++-------- src/network/kernel/qhostinfo.h | 7 +--- src/opengl/qgl.h | 16 ------- src/opengl/qglshaderprogram.h | 11 ----- src/widgets/dialogs/qmessagebox.h | 4 +- src/widgets/graphicsview/qgraphicsitem.h | 2 + src/widgets/graphicsview/qgraphicslayout.h | 2 + .../graphicsview/qgraphicslayoutitem.h | 2 + src/widgets/widgets/qmenu.cpp | 42 ++++--------------- src/widgets/widgets/qmenu.h | 4 -- src/widgets/widgets/qtoolbar.cpp | 38 ++++------------- src/widgets/widgets/qtoolbar.h | 8 +--- 35 files changed, 106 insertions(+), 226 deletions(-) diff --git a/src/corelib/global/qfloat16.h b/src/corelib/global/qfloat16.h index a8befd7adb..766ab319a4 100644 --- a/src/corelib/global/qfloat16.h +++ b/src/corelib/global/qfloat16.h @@ -67,11 +67,9 @@ QT_BEGIN_NAMESPACE class qfloat16 { public: -#ifndef Q_QDOC Q_DECL_CONSTEXPR inline qfloat16() Q_DECL_NOTHROW : b16(0) { } inline qfloat16(float f) Q_DECL_NOTHROW; inline operator float() const Q_DECL_NOTHROW; -#endif private: quint16 b16; diff --git a/src/corelib/io/qprocess.h b/src/corelib/io/qprocess.h index 474fc87de8..5e022e3a52 100644 --- a/src/corelib/io/qprocess.h +++ b/src/corelib/io/qprocess.h @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE class QProcessPrivate; -#if !defined(Q_OS_WIN) || defined(Q_CLANG_QDOC) +#if !defined(Q_OS_WIN) typedef qint64 Q_PID; #else QT_END_NAMESPACE diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 0bf430bb26..a47fbfe28d 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -1977,7 +1977,9 @@ QT_FOR_EACH_STATIC_WIDGETS_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER) typedef QList QVariantList; typedef QMap QVariantMap; typedef QHash QVariantHash; -#ifndef Q_CLANG_QDOC +#ifdef Q_CLANG_QDOC +class QByteArrayList; +#else typedef QList QByteArrayList; #endif diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index ff73c27b6e..f95502e75f 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -55,6 +55,8 @@ #if QT_HAS_INCLUDE() && __cplusplus >= 201703L #include +#elif defined(Q_CLANG_QDOC) +namespace std { template struct variant; } #endif QT_BEGIN_NAMESPACE @@ -365,7 +367,7 @@ class Q_CORE_EXPORT QVariant static inline QVariant fromValue(const T &value) { return qVariantFromValue(value); } -#if defined(Q_CLANG_QDOC) || (QT_HAS_INCLUDE() && __cplusplus >= 201703L) +#if QT_HAS_INCLUDE() && __cplusplus >= 201703L template static inline QVariant fromStdVariant(const std::variant &value) { diff --git a/src/corelib/plugin/qfactoryinterface.h b/src/corelib/plugin/qfactoryinterface.h index f306460690..3aec4ddd55 100644 --- a/src/corelib/plugin/qfactoryinterface.h +++ b/src/corelib/plugin/qfactoryinterface.h @@ -52,8 +52,9 @@ struct Q_CORE_EXPORT QFactoryInterface virtual QStringList keys() const = 0; }; - +#ifndef Q_CLANG_QDOC Q_DECLARE_INTERFACE(QFactoryInterface, "org.qt-project.Qt.QFactoryInterface") +#endif QT_END_NAMESPACE diff --git a/src/corelib/serialization/qjsonvalue.h b/src/corelib/serialization/qjsonvalue.h index 16d2c0c14c..0339eb59f7 100644 --- a/src/corelib/serialization/qjsonvalue.h +++ b/src/corelib/serialization/qjsonvalue.h @@ -219,7 +219,6 @@ private: uint index : 31; }; -#ifndef Q_QDOC // ### Qt 6: Get rid of these fake pointer classes class QJsonValuePtr { @@ -244,7 +243,6 @@ public: QJsonValueRef& operator*() { return valueRef; } QJsonValueRef* operator->() { return &valueRef; } }; -#endif Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QJsonValue) diff --git a/src/corelib/thread/qresultstore.cpp b/src/corelib/thread/qresultstore.cpp index e0ce1b4b78..1b3bc20eca 100644 --- a/src/corelib/thread/qresultstore.cpp +++ b/src/corelib/thread/qresultstore.cpp @@ -43,6 +43,21 @@ QT_BEGIN_NAMESPACE namespace QtPrivate { +/*! + \class QtPrivate::ResultItem + \internal + */ + +/*! + \class QtPrivate::ResultIteratorBase + \internal + */ + +/*! + \class QtPrivate::ResultStoreBase + \internal + */ + ResultIteratorBase::ResultIteratorBase() : mapIterator(QMap::const_iterator()), m_vectorIndex(0) { } ResultIteratorBase::ResultIteratorBase(QMap::const_iterator _mapIterator, int _vectorIndex) diff --git a/src/corelib/thread/qresultstore.h b/src/corelib/thread/qresultstore.h index 39f0a6d1bb..1f29e8d187 100644 --- a/src/corelib/thread/qresultstore.h +++ b/src/corelib/thread/qresultstore.h @@ -56,7 +56,6 @@ QT_BEGIN_NAMESPACE either individually or in batches. */ -#ifndef Q_QDOC namespace QtPrivate { @@ -196,7 +195,6 @@ public: Q_DECLARE_TYPEINFO(QtPrivate::ResultItem, Q_PRIMITIVE_TYPE); -#endif //Q_QDOC QT_END_NAMESPACE diff --git a/src/corelib/tools/qbytearraylist.h b/src/corelib/tools/qbytearraylist.h index ed014dd157..be94bc1d40 100644 --- a/src/corelib/tools/qbytearraylist.h +++ b/src/corelib/tools/qbytearraylist.h @@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE typedef QListIterator QByteArrayListIterator; typedef QMutableListIterator QMutableByteArrayListIterator; -#ifndef Q_QDOC +#ifndef Q_CLANG_QDOC typedef QList QByteArrayList; namespace QtPrivate { @@ -58,13 +58,13 @@ namespace QtPrivate { } #endif -#ifdef Q_QDOC +#ifdef Q_CLANG_QDOC class QByteArrayList : public QList #else template <> struct QListSpecialMethods #endif { -#ifndef Q_QDOC +#ifndef Q_CLANG_QDOC protected: ~QListSpecialMethods() {} #endif diff --git a/src/dbus/qdbusargument.cpp b/src/dbus/qdbusargument.cpp index a33c4f8363..2d1373006d 100644 --- a/src/dbus/qdbusargument.cpp +++ b/src/dbus/qdbusargument.cpp @@ -267,7 +267,7 @@ bool QDBusArgumentPrivate::checkReadAndDetach(QDBusArgumentPrivate *&d) */ /*! - \fn qdbus_cast(const QDBusArgument &arg) + \fn template T qdbus_cast(const QDBusArgument &arg, T*) \relates QDBusArgument \since 4.2 diff --git a/src/dbus/qdbusargument.h b/src/dbus/qdbusargument.h index a6d4e9cd25..ac650d5f62 100644 --- a/src/dbus/qdbusargument.h +++ b/src/dbus/qdbusargument.h @@ -158,22 +158,14 @@ QT_END_NAMESPACE Q_DECLARE_METATYPE(QDBusArgument) QT_BEGIN_NAMESPACE -template inline T qdbus_cast(const QDBusArgument &arg -#ifndef Q_QDOC -, T * = nullptr -#endif - ) +template inline T qdbus_cast(const QDBusArgument &arg, T * = nullptr) { T item; arg >> item; return item; } -template inline T qdbus_cast(const QVariant &v -#ifndef Q_QDOC -, T * = nullptr -#endif - ) +template inline T qdbus_cast(const QVariant &v, T * = nullptr) { int id = v.userType(); if (id == qMetaTypeId()) diff --git a/src/dbus/qdbusconnection.h b/src/dbus/qdbusconnection.h index ca7adfaaeb..3711981f78 100644 --- a/src/dbus/qdbusconnection.h +++ b/src/dbus/qdbusconnection.h @@ -122,9 +122,7 @@ public: SubPath = 0x1 // Reserved = 0xff000000 }; -#ifndef Q_QDOC Q_DECLARE_FLAGS(VirtualObjectRegisterOptions, VirtualObjectRegisterOption) -#endif enum ConnectionCapability { UnixFileDescriptorPassing = 0x0001 diff --git a/src/dbus/qdbuspendingcall.cpp b/src/dbus/qdbuspendingcall.cpp index 2a31dd950a..4d0131afff 100644 --- a/src/dbus/qdbuspendingcall.cpp +++ b/src/dbus/qdbuspendingcall.cpp @@ -311,7 +311,7 @@ QDBusPendingCall &QDBusPendingCall::operator=(const QDBusPendingCall &other) \sa QDBusPendingReply::isFinished() */ /*! - \fn bool QDBusPendingReply::isFinished() const + \fn template bool QDBusPendingReply::isFinished() const Returns \c true if the pending call has finished processing and the reply has been received. If this function returns \c true, the @@ -340,7 +340,7 @@ void QDBusPendingCall::waitForFinished() } /*! - \fn bool QDBusPendingReply::isValid() const + \fn template bool QDBusPendingReply::isValid() const Returns \c true if the reply contains a normal reply message, false if it contains anything else. @@ -357,7 +357,7 @@ bool QDBusPendingCall::isValid() const } /*! - \fn bool QDBusPendingReply::isError() const + \fn template bool QDBusPendingReply::isError() const Returns \c true if the reply contains an error message, false if it contains a normal method reply. @@ -374,7 +374,7 @@ bool QDBusPendingCall::isError() const } /*! - \fn QDBusError QDBusPendingReply::error() const + \fn template QDBusError QDBusPendingReply::error() const Retrieves the error content of the reply message, if it has finished processing. If the reply message has not finished @@ -395,7 +395,7 @@ QDBusError QDBusPendingCall::error() const } /*! - \fn QDBusMessage QDBusPendingReply::reply() const + \fn template QDBusMessage QDBusPendingReply::reply() const Retrieves the reply message received for the asynchronous call that was sent, if it has finished processing. If the pending call @@ -445,7 +445,7 @@ bool QDBusPendingCall::setReplyCallback(QObject *target, const char *member) \since 4.6 Creates a QDBusPendingCall object based on the error condition \a error. The resulting pending call object will be in the - "finished" state and QDBusPendingReply::isError() will return true. + "finished" state and QDBusPendingReply::isError() will return true. \sa fromCompletedCall() */ diff --git a/src/dbus/qdbuspendingcall.h b/src/dbus/qdbuspendingcall.h index ec8ba6c541..24b1d6a7ca 100644 --- a/src/dbus/qdbuspendingcall.h +++ b/src/dbus/qdbuspendingcall.h @@ -67,7 +67,7 @@ public: void swap(QDBusPendingCall &other) Q_DECL_NOTHROW { qSwap(d, other.d); } -#ifndef Q_QDOC +#ifndef Q_CLANG_QDOC // pretend that they aren't here bool isFinished() const; void waitForFinished(); diff --git a/src/dbus/qdbuspendingreply.cpp b/src/dbus/qdbuspendingreply.cpp index fef6f36432..6aec571563 100644 --- a/src/dbus/qdbuspendingreply.cpp +++ b/src/dbus/qdbuspendingreply.cpp @@ -94,7 +94,7 @@ */ /*! - \fn QDBusPendingReply::QDBusPendingReply() + \fn template QDBusPendingReply::QDBusPendingReply() Creates an empty QDBusPendingReply object. Without assigning a QDBusPendingCall object to this reply, QDBusPendingReply cannot do @@ -102,7 +102,7 @@ */ /*! - \fn QDBusPendingReply::QDBusPendingReply(const QDBusPendingReply &other) + \fn template QDBusPendingReply::QDBusPendingReply(const QDBusPendingReply &other) Creates a copy of the \a other QDBusPendingReply object. Just like QDBusPendingCall and QDBusPendingCallWatcher, this QDBusPendingReply @@ -111,7 +111,7 @@ */ /*! - \fn QDBusPendingReply::QDBusPendingReply(const QDBusPendingCall &call) + \fn template QDBusPendingReply::QDBusPendingReply(const QDBusPendingCall &call) Creates a QDBusPendingReply object that will take its contents from the \a call pending asynchronous call. This QDBusPendingReply object @@ -119,7 +119,7 @@ */ /*! - \fn QDBusPendingReply::QDBusPendingReply(const QDBusMessage &message) + \fn template QDBusPendingReply::QDBusPendingReply(const QDBusMessage &message) Creates a QDBusPendingReply object that will take its contents from the message \a message. In this case, this object will be already @@ -129,7 +129,7 @@ */ /*! - \fn QDBusPendingReply &QDBusPendingReply::operator=(const QDBusPendingReply &other) + \fn template QDBusPendingReply &QDBusPendingReply::operator=(const QDBusPendingReply &other) Makes a copy of \a other and drops the reference to the current pending call. If the current reference is to an unfinished pending @@ -139,7 +139,7 @@ */ /*! - \fn QDBusPendingReply &QDBusPendingReply::operator=(const QDBusPendingCall &call) + \fn template QDBusPendingReply &QDBusPendingReply::operator=(const QDBusPendingCall &call) Makes this object take its contents from the \a call pending call and drops the reference to the current pending call. If the @@ -149,7 +149,7 @@ */ /*! - \fn QDBusPendingReply &QDBusPendingReply::operator=(const QDBusMessage &message) + \fn template QDBusPendingReply &QDBusPendingReply::operator=(const QDBusMessage &message) Makes this object take its contents from the \a message message and drops the reference to the current pending call. If the @@ -171,7 +171,7 @@ */ /*! - \fn int QDBusPendingReply::count() const + \fn template int QDBusPendingReply::count() const Return the number of arguments the reply is supposed to have. This number matches the number of non-void template parameters in this @@ -183,7 +183,7 @@ */ /*! - \fn QVariant QDBusPendingReply::argumentAt(int index) const + \fn template QVariant QDBusPendingReply::argumentAt(int index) const Returns the argument at position \a index in the reply's contents. If the reply doesn't have that many elements, this @@ -198,12 +198,7 @@ */ /*! - \typedef QDBusPendingReply::T1 - \internal - */ - -/*! - \fn T1 QDBusPendingReply::value() const + \fn template T1 QDBusPendingReply::value() const Returns the first argument in this reply, cast to type \c T1 (the first template parameter of this class). This is equivalent to @@ -221,7 +216,7 @@ */ /*! - \fn QDBusPendingReply::operator T1() const + \fn template QDBusPendingReply::operator T1() const Returns the first argument in this reply, cast to type \c T1 (the first template parameter of this class). This is equivalent to @@ -239,7 +234,7 @@ */ /*! - \fn void QDBusPendingReply::waitForFinished() + \fn template void QDBusPendingReply::waitForFinished() Suspends the execution of the calling thread until the reply is received and processed. After this function returns, isFinished() diff --git a/src/dbus/qdbuspendingreply.h b/src/dbus/qdbuspendingreply.h index 4d2c3a7c5a..bc5cd92c84 100644 --- a/src/dbus/qdbuspendingreply.h +++ b/src/dbus/qdbuspendingreply.h @@ -108,10 +108,8 @@ namespace QDBusPendingReplyTypes { template <> struct NotVoid { typedef TypeIsVoid Type; }; } // namespace QDBusPendingReplyTypes -#ifndef Q_CLANG_QDOC template -#endif class QDBusPendingReply: #ifdef Q_CLANG_QDOC public QDBusPendingCall @@ -171,7 +169,6 @@ public: QDBusError error() const; QDBusMessage reply() const; - typedef QVariant T1; inline T1 value() const; inline operator T1() const; #else diff --git a/src/dbus/qdbusreply.cpp b/src/dbus/qdbusreply.cpp index ab361f1674..6abfaf174c 100644 --- a/src/dbus/qdbusreply.cpp +++ b/src/dbus/qdbusreply.cpp @@ -81,7 +81,7 @@ QT_BEGIN_NAMESPACE */ /*! - \fn template QDBusReply::QDBusReply(const QDBusPendingReply &reply) + \fn template QDBusReply::QDBusReply(const QDBusPendingReply &reply) Constructs a QDBusReply object from the pending reply message, \a reply. */ diff --git a/src/dbus/qdbusreply.h b/src/dbus/qdbusreply.h index 177b6c6e89..869687ac85 100644 --- a/src/dbus/qdbusreply.h +++ b/src/dbus/qdbusreply.h @@ -82,14 +82,10 @@ public: other.waitForFinished(); return *this = other.reply(); } -#if defined(Q_CLANG_QDOC) - inline QDBusReply(const QDBusPendingReply &reply) { } -#else inline QDBusReply(const QDBusPendingReply &reply) { *this = static_cast(reply); } -#endif inline QDBusReply(const QDBusError &dbusError = QDBusError()) : m_error(dbusError), m_data(Type()) diff --git a/src/dbus/qdbusutil.cpp b/src/dbus/qdbusutil.cpp index 28341a71a8..dc94897ac4 100644 --- a/src/dbus/qdbusutil.cpp +++ b/src/dbus/qdbusutil.cpp @@ -331,8 +331,8 @@ namespace QDBusUtil /*! \internal - \fn bool QDBusUtil::isValidPartOfObjectPath(const QStringRef &part) - See QDBusUtil::isValidObjectPath + \fn bool isValidPartOfObjectPath(const QStringRef &part) + See isValidObjectPath */ bool isValidPartOfObjectPath(const QStringRef &part) { @@ -349,13 +349,13 @@ namespace QDBusUtil /*! \internal - \fn bool QDBusUtil::isValidPartOfObjectPath(const QString &part) + \fn bool isValidPartOfObjectPath(const QString &part) \overload */ /*! - \fn bool QDBusUtil::isValidInterfaceName(const QString &ifaceName) + \fn bool isValidInterfaceName(const QString &ifaceName) Returns \c true if this is \a ifaceName is a valid interface name. Valid interface names must: @@ -384,7 +384,7 @@ namespace QDBusUtil } /*! - \fn bool QDBusUtil::isValidUniqueConnectionName(const QStringRef &connName) + \fn bool isValidUniqueConnectionName(const QStringRef &connName) Returns \c true if \a connName is a valid unique connection name. Unique connection names start with a colon (":") and are followed by a list of dot-separated @@ -414,13 +414,13 @@ namespace QDBusUtil } /*! - \fn bool QDBusUtil::isValidUniqueConnectionName(const QString &connName) + \fn bool isValidUniqueConnectionName(const QString &connName) \overload */ /*! - \fn bool QDBusUtil::isValidBusName(const QString &busName) + \fn bool isValidBusName(const QString &busName) Returns \c true if \a busName is a valid bus name. A valid bus name is either a valid unique connection name or follows the rules: @@ -462,7 +462,7 @@ namespace QDBusUtil } /*! - \fn bool QDBusUtil::isValidMemberName(const QStringRef &memberName) + \fn bool isValidMemberName(const QStringRef &memberName) Returns \c true if \a memberName is a valid member name. A valid member name does not exceed 255 characters in length, is not empty, is composed only of ASCII letters, digits and underscores, but does not start with a digit. @@ -482,13 +482,13 @@ namespace QDBusUtil } /*! - \fn bool QDBusUtil::isValidMemberName(const QString &memberName) + \fn bool isValidMemberName(const QString &memberName) \overload */ /*! - \fn bool QDBusUtil::isValidErrorName(const QString &errorName) + \fn bool isValidErrorName(const QString &errorName) Returns \c true if \a errorName is a valid error name. Valid error names are valid interface names and vice-versa, so this function is actually an alias for isValidInterfaceName. */ @@ -498,7 +498,7 @@ namespace QDBusUtil } /*! - \fn bool QDBusUtil::isValidObjectPath(const QString &path) + \fn bool isValidObjectPath(const QString &path) Returns \c true if \a path is valid object path. Valid object paths follow the rules: @@ -529,7 +529,7 @@ namespace QDBusUtil } /*! - \fn bool QDBusUtil::isValidBasicType(int type) + \fn bool isValidBasicType(int type) Returns \c true if \a c is a valid, basic D-Bus type. */ bool isValidBasicType(int c) @@ -538,7 +538,7 @@ namespace QDBusUtil } /*! - \fn bool QDBusUtil::isValidFixedType(int type) + \fn bool isValidFixedType(int type) Returns \c true if \a c is a valid, fixed D-Bus type. */ bool isValidFixedType(int c) @@ -548,7 +548,7 @@ namespace QDBusUtil /*! - \fn bool QDBusUtil::isValidSignature(const QString &signature) + \fn bool isValidSignature(const QString &signature) Returns \c true if \a signature is a valid D-Bus type signature for one or more types. This function returns \c true if it can all of \a signature into valid, individual types and no characters remain in \a signature. @@ -569,7 +569,7 @@ namespace QDBusUtil } /*! - \fn bool QDBusUtil::isValidSingleSignature(const QString &signature) + \fn bool isValidSingleSignature(const QString &signature) Returns \c true if \a signature is a valid D-Bus type signature for exactly one full type. This function tries to convert the type signature into a D-Bus type and, if it succeeds and no characters remain in the signature, it returns \c true. diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h index 1309f17efd..e2163b06d0 100644 --- a/src/gui/accessible/qaccessible.h +++ b/src/gui/accessible/qaccessible.h @@ -966,8 +966,10 @@ protected: int m_lastColumn; }; +#ifndef Q_CLANG_QDOC #define QAccessibleInterface_iid "org.qt-project.Qt.QAccessibleInterface" Q_DECLARE_INTERFACE(QAccessibleInterface, QAccessibleInterface_iid) +#endif Q_GUI_EXPORT const char *qAccessibleRoleString(QAccessible::Role role); Q_GUI_EXPORT const char *qAccessibleEventString(QAccessible::Event event); diff --git a/src/gui/opengl/qopenglfunctions.h b/src/gui/opengl/qopenglfunctions.h index 00287b0665..4554291bbd 100644 --- a/src/gui/opengl/qopenglfunctions.h +++ b/src/gui/opengl/qopenglfunctions.h @@ -228,26 +228,8 @@ struct QOpenGLFunctionsPrivate; #undef glTexLevelParameteriv #if defined(Q_CLANG_QDOC) -#undef GLint -typedef int GLint; -#undef GLsizei -typedef int GLsizei; -#undef GLuint -typedef unsigned int GLuint; -#undef GLubyte -typedef unsigned int GLubyte; -#undef GLenum -typedef unsigned int GLenum; #undef GLbitfield typedef unsigned int GLbitfield; -#undef GLfloat -typedef float GLfloat; -#undef GLclampf -typedef float GLclampf; -#undef GLboolean -typedef bool GLboolean; -#undef GLvoid -typedef void GLvoid; #undef GLchar typedef char GLchar; #endif diff --git a/src/gui/opengl/qopenglshaderprogram.h b/src/gui/opengl/qopenglshaderprogram.h index bdd18c9d68..c79101fd4d 100644 --- a/src/gui/opengl/qopenglshaderprogram.h +++ b/src/gui/opengl/qopenglshaderprogram.h @@ -50,13 +50,6 @@ #include #include -#if defined(Q_CLANG_QDOC) -#undef GLint -typedef int GLint; -#undef GLfloat -typedef double GLfloat; -#endif - QT_BEGIN_NAMESPACE diff --git a/src/gui/text/qabstracttextdocumentlayout.h b/src/gui/text/qabstracttextdocumentlayout.h index 8fea27f772..3371401420 100644 --- a/src/gui/text/qabstracttextdocumentlayout.h +++ b/src/gui/text/qabstracttextdocumentlayout.h @@ -143,7 +143,9 @@ public: virtual void drawObject(QPainter *painter, const QRectF &rect, QTextDocument *doc, int posInDocument, const QTextFormat &format) = 0; }; +#ifndef Q_CLANG_QDOC Q_DECLARE_INTERFACE(QTextObjectInterface, "org.qt-project.Qt.QTextObjectInterface") +#endif QT_END_NAMESPACE diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp index 0973d0dd52..1c7a8da06d 100644 --- a/src/network/kernel/qhostinfo.cpp +++ b/src/network/kernel/qhostinfo.cpp @@ -299,25 +299,6 @@ int QHostInfo::lookupHost(const QString &name, QObject *receiver, \since 5.10 */ -/*! - \fn template int QHostInfo::lookupHost(const QString &name, const QObject *receiver, PointerToMemberFunction function) - - \since 5.9 - - \overload - - Looks up the IP address(es) associated with host name \a name, and - returns an ID for the lookup. When the result of the lookup is - ready, the slot or signal \a function in \a receiver is called with - a QHostInfo argument. The QHostInfo object can then be inspected - to get the results of the lookup. - - \note There is no guarantee on the order the signals will be emitted - if you start multiple requests with lookupHost(). - - \sa abortHostLookup(), addresses(), error(), fromName() -*/ - /*! \fn template int QHostInfo::lookupHost(const QString &name, Functor functor) @@ -354,6 +335,16 @@ int QHostInfo::lookupHost(const QString &name, QObject *receiver, thread of \a context. The context's thread must have a running Qt event loop. + Here is an alternative signature for the function: + \code + lookupHost(const QString &name, const QObject *receiver, PointerToMemberFunction function) + \endcode + + In this case, when the result of the lookup is ready, the slot or + signal \c{function} in \c{receiver} is called with a QHostInfo + argument. The QHostInfo object can then be inspected to get the + results of the lookup. + \note There is no guarantee on the order the signals will be emitted if you start multiple requests with lookupHost(). diff --git a/src/network/kernel/qhostinfo.h b/src/network/kernel/qhostinfo.h index 75917a02a3..49871ad470 100644 --- a/src/network/kernel/qhostinfo.h +++ b/src/network/kernel/qhostinfo.h @@ -91,13 +91,10 @@ public: static QString localDomainName(); #ifdef Q_CLANG_QDOC - template - static int QHostInfo::lookupHost(const QString &name, const QObject *receiver, - PointerToMemberFunction function); template - static int QHostInfo::lookupHost(const QString &name, Functor functor); + static int lookupHost(const QString &name, Functor functor); template - static int QHostInfo::lookupHost(const QString &name, const QObject *context, Functor functor); + static int lookupHost(const QString &name, const QObject *context, Functor functor); #else // lookupHost to a QObject slot template diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h index a1ba0485e0..f5accbeb3c 100644 --- a/src/opengl/qgl.h +++ b/src/opengl/qgl.h @@ -51,22 +51,6 @@ #include -#if defined(Q_CLANG_QDOC) -#undef GLint -typedef int GLint; -#undef GLuint -typedef unsigned int GLuint; -#undef GLenum -typedef unsigned int GLenum; -#undef GLclampf -typedef float GLclampf; -#undef GLsizei -typedef int GLsizei; -#undef GLboolean -typedef bool GLboolean; -#endif - - QT_BEGIN_NAMESPACE diff --git a/src/opengl/qglshaderprogram.h b/src/opengl/qglshaderprogram.h index dfdef44b54..3ce88197d2 100644 --- a/src/opengl/qglshaderprogram.h +++ b/src/opengl/qglshaderprogram.h @@ -46,17 +46,6 @@ #include #include -#if defined(Q_CLANG_QDOC) -#undef GLfloat -typedef double GLfloat; -#undef GLint -typedef int GLint; -#undef GLuint -typedef unsigned int GLuint; -#undef GLenum -typedef unsigned int GLenum; -#endif - QT_BEGIN_NAMESPACE diff --git a/src/widgets/dialogs/qmessagebox.h b/src/widgets/dialogs/qmessagebox.h index 4b993a9e65..0a2edb1eee 100644 --- a/src/widgets/dialogs/qmessagebox.h +++ b/src/widgets/dialogs/qmessagebox.h @@ -284,9 +284,9 @@ public: Q_SIGNALS: void buttonClicked(QAbstractButton *button); -#ifdef Q_QDOC +#ifdef Q_CLANG_QDOC public Q_SLOTS: - int exec(); + int exec() override; #endif protected: diff --git a/src/widgets/graphicsview/qgraphicsitem.h b/src/widgets/graphicsview/qgraphicsitem.h index c228e765d8..729176530d 100644 --- a/src/widgets/graphicsview/qgraphicsitem.h +++ b/src/widgets/graphicsview/qgraphicsitem.h @@ -487,7 +487,9 @@ private: }; Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsItem::GraphicsItemFlags) +#ifndef Q_CLANG_QDOC Q_DECLARE_INTERFACE(QGraphicsItem, "org.qt-project.Qt.QGraphicsItem") +#endif inline void QGraphicsItem::setPos(qreal ax, qreal ay) { setPos(QPointF(ax, ay)); } diff --git a/src/widgets/graphicsview/qgraphicslayout.h b/src/widgets/graphicsview/qgraphicslayout.h index 28b335ceaa..efcafa5e6a 100644 --- a/src/widgets/graphicsview/qgraphicslayout.h +++ b/src/widgets/graphicsview/qgraphicslayout.h @@ -83,7 +83,9 @@ private: friend class QGraphicsWidget; }; +#ifndef Q_CLANG_QDOC Q_DECLARE_INTERFACE(QGraphicsLayout, "org.qt-project.Qt.QGraphicsLayout") +#endif QT_END_NAMESPACE diff --git a/src/widgets/graphicsview/qgraphicslayoutitem.h b/src/widgets/graphicsview/qgraphicslayoutitem.h index 44f430034b..86a0a87361 100644 --- a/src/widgets/graphicsview/qgraphicslayoutitem.h +++ b/src/widgets/graphicsview/qgraphicslayoutitem.h @@ -116,7 +116,9 @@ private: friend class QGraphicsLayout; }; +#ifndef Q_CLANG_QDOC Q_DECLARE_INTERFACE(QGraphicsLayoutItem, "org.qt-project.Qt.QGraphicsLayoutItem") +#endif inline void QGraphicsLayoutItem::setMinimumSize(qreal aw, qreal ah) { setMinimumSize(QSizeF(aw, ah)); } diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index c79e88f094..bf1102434c 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -1800,21 +1800,6 @@ QAction *QMenu::addAction(const QString &text, const QObject *receiver, const ch return action; } -/*!\fn template QAction *QMenu::addAction(const QString &text, const QObject *receiver, PointerToMemberFunction method, const QKeySequence &shortcut = 0) - - \since 5.6 - - \overload - - This convenience function creates a new action with the text \a - text and an optional shortcut \a shortcut. The action's - \l{QAction::triggered()}{triggered()} signal is connected to the - \a method of the \a receiver. The function adds the newly created - action to the menu's list of actions and returns it. - - QMenu takes ownership of the returned QAction. -*/ - /*!\fn template QAction *QMenu::addAction(const QString &text, Functor functor, const QKeySequence &shortcut = 0) \since 5.6 @@ -1839,25 +1824,11 @@ QAction *QMenu::addAction(const QString &text, const QObject *receiver, const ch This convenience function creates a new action with the text \a text and an optional shortcut \a shortcut. The action's \l{QAction::triggered()}{triggered()} signal is connected to the - \a functor. The function adds the newly created - action to the menu's list of actions and returns it. + \a functor. The functor can be a pointer to a member function of + the \a context object. The newly created action is added to the + menu's list of actions and a pointer to it is returned. - If \a context is destroyed, the functor will not be called. - - QMenu takes ownership of the returned QAction. -*/ - -/*!\fn template QAction *QMenu::addAction(const QIcon &icon, const QString &text, const QObject *receiver, PointerToMemberFunction method, const QKeySequence &shortcut = 0) - - \since 5.6 - - \overload - - This convenience function creates a new action with an \a icon - and some \a text and an optional shortcut \a shortcut. The action's - \l{QAction::triggered()}{triggered()} signal is connected to the - \a method of the \a receiver. The function adds the newly created - action to the menu's list of actions and returns it. + If the \a context object is destroyed, the functor will not be called. QMenu takes ownership of the returned QAction. */ @@ -1886,8 +1857,9 @@ QAction *QMenu::addAction(const QString &text, const QObject *receiver, const ch This convenience function creates a new action with an \a icon and some \a text and an optional shortcut \a shortcut. The action's \l{QAction::triggered()}{triggered()} signal is connected to the - \a functor. The function adds the newly created - action to the menu's list of actions and returns it. + \a functor. The \a functor can be a pointer to a member function + of the \a context object. The newly created action is added to the + menu's list of actions and a pointer to it is returned. If \a context is destroyed, the functor will not be called. diff --git a/src/widgets/widgets/qmenu.h b/src/widgets/widgets/qmenu.h index 628f818b5e..84ab9e027a 100644 --- a/src/widgets/widgets/qmenu.h +++ b/src/widgets/widgets/qmenu.h @@ -82,14 +82,10 @@ public: QAction *addAction(const QIcon &icon, const QString &text, const QObject *receiver, const char* member, const QKeySequence &shortcut = 0); #ifdef Q_CLANG_QDOC - template - QAction *addAction(const QString &text, const QObject *receiver, PointerToMemberFunction method, const QKeySequence &shortcut = 0); template QAction *addAction(const QString &text, Functor functor, const QKeySequence &shortcut = 0); template QAction *addAction(const QString &text, const QObject *context, Functor functor, const QKeySequence &shortcut = 0); - template - QAction *addAction(const QIcon &icon, const QString &text, const QObject *receiver, PointerToMemberFunction method, const QKeySequence &shortcut = 0); template QAction *addAction(const QIcon &icon, const QString &text, Functor functor, const QKeySequence &shortcut = 0); template diff --git a/src/widgets/widgets/qtoolbar.cpp b/src/widgets/widgets/qtoolbar.cpp index 4af71c126e..1cd30e4d0d 100644 --- a/src/widgets/widgets/qtoolbar.cpp +++ b/src/widgets/widgets/qtoolbar.cpp @@ -799,18 +799,6 @@ QAction *QToolBar::addAction(const QIcon &icon, const QString &text, return action; } -/*!\fn template QAction *QToolBar::addAction(const QString &text, const QObject *receiver, PointerToMemberFunction method) - - \since 5.6 - - \overload - - Creates a new action with the given \a text. This action is added to - the end of the toolbar. The action's - \l{QAction::triggered()}{triggered()} signal is connected to the - \a method of the \a receiver. -*/ - /*!\fn template QAction *QToolBar::addAction(const QString &text, Functor functor) \since 5.6 @@ -829,24 +817,13 @@ QAction *QToolBar::addAction(const QIcon &icon, const QString &text, \overload - Creates a new action with the given \a text. This action is added to - the end of the toolbar. The action's + Creates a new action with the given \a text. This action is added + to the end of the toolbar. The action's \l{QAction::triggered()}{triggered()} signal is connected to the - \a functor. + \a functor. The \a functor can be a pointer to a member function + in the \a context object. - If \a context is destroyed, the functor will not be called. -*/ - -/*!\fn template QAction *QToolBar::addAction(const QIcon &icon, const QString &text, const QObject *receiver, PointerToMemberFunction method) - - \since 5.6 - - \overload - - Creates a new action with the given \a icon and \a text. This - action is added to the end of the toolbar. The action's - \l{QAction::triggered()}{triggered()} signal is connected to the - \a method of the \a receiver. + If the \a context object is destroyed, the \a functor will not be called. */ /*!\fn template QAction *QToolBar::addAction(const QIcon &icon, const QString &text, Functor functor) @@ -870,9 +847,10 @@ QAction *QToolBar::addAction(const QIcon &icon, const QString &text, Creates a new action with the given \a icon and \a text. This action is added to the end of the toolbar. The action's \l{QAction::triggered()}{triggered()} signal is connected to the - \a functor. + \a functor. The \a functor can be a pointer to a member function + of the \a context object. - If \a context is destroyed, the functor will not be called. + If the \a context object is destroyed, the \a functor will not be called. */ /*! diff --git a/src/widgets/widgets/qtoolbar.h b/src/widgets/widgets/qtoolbar.h index 4ae83190d1..0c434e8d1d 100644 --- a/src/widgets/widgets/qtoolbar.h +++ b/src/widgets/widgets/qtoolbar.h @@ -99,15 +99,11 @@ public: QAction *addAction(const QString &text, const QObject *receiver, const char* member); QAction *addAction(const QIcon &icon, const QString &text, const QObject *receiver, const char* member); -#ifdef Q_QDOC - template - QAction *addAction(const QString &text, const QObject *receiver, PointerToMemberFunction method); +#ifdef Q_CLANG_QDOC template QAction *addAction(const QString &text, Functor functor); template QAction *addAction(const QString &text, const QObject *context, Functor functor); - template - QAction *addAction(const QIcon &icon, const QString &text, const QObject *receiver, PointerToMemberFunction method); template QAction *addAction(const QIcon &icon, const QString &text, Functor functor); template @@ -149,7 +145,7 @@ public: connect(result, &QAction::triggered, slot); return result; } -#endif // !Q_QDOC +#endif // !Q_CLANG_QDOC QAction *addSeparator(); QAction *insertSeparator(QAction *before); From 73e7eb785fbf984e2b964be8c3acad788479dfa6 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 5 Nov 2018 16:03:29 +0100 Subject: [PATCH 0185/1650] Enable swizzling This part was accidently left disabling after testing the fallback still worked. Change-Id: Ic2df939753641a9771e68bc8857c570d356cff44 Reviewed-by: Laszlo Agocs --- src/gui/opengl/qopengltextureuploader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/opengl/qopengltextureuploader.cpp b/src/gui/opengl/qopengltextureuploader.cpp index 2428baed93..42e309b733 100644 --- a/src/gui/opengl/qopengltextureuploader.cpp +++ b/src/gui/opengl/qopengltextureuploader.cpp @@ -114,7 +114,7 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag externalFormat = GL_BGRA; internalFormat = GL_RGBA; pixelType = GL_UNSIGNED_INT_8_8_8_8_REV; - } else if (funcs->hasOpenGLExtension(QOpenGLExtensions::TextureSwizzle) && false) { + } else if (funcs->hasOpenGLExtension(QOpenGLExtensions::TextureSwizzle)) { #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN GLint swizzle[4] = { GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA }; funcs->glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle); From d82404428460a203daf1d0cc67fcc6b8a03f514c Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 26 Oct 2018 21:33:33 +0200 Subject: [PATCH 0186/1650] QCommandLinkButton: fix visibility of some public functions The three public functions heightForWidth/minimumSizeHint/sizeHint were accidentally marked as protected in QCommandLinkButton. This patch makes sure it get fixed with Qt6. Fixes: QTBUG-68722 Change-Id: I577e48cbe9274c8506a555dae1ec81044a889d6e Reviewed-by: Samuel Gaist Reviewed-by: Luca Beldi Reviewed-by: Richard Moe Gustavsen --- src/widgets/widgets/qcommandlinkbutton.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/widgets/widgets/qcommandlinkbutton.h b/src/widgets/widgets/qcommandlinkbutton.h index 2d01d63df8..3d2dd5784d 100644 --- a/src/widgets/widgets/qcommandlinkbutton.h +++ b/src/widgets/widgets/qcommandlinkbutton.h @@ -66,10 +66,16 @@ public: QString description() const; void setDescription(const QString &description); + // QTBUG-68722 +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) protected: +#else +public: +#endif QSize sizeHint() const override; int heightForWidth(int) const override; QSize minimumSizeHint() const override; +protected: bool event(QEvent *e) override; void paintEvent(QPaintEvent *) override; From f7ba6a0acfeb04b5ac0018ae42eda65398a47fd4 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sat, 27 Oct 2018 21:23:28 +0200 Subject: [PATCH 0187/1650] QAbstractOpenGLFunctions: disallow copy/assignment operations QAbstractOpenGLFunctions must not be copied but the copy and assignment operators were not marked as deleted. Add Q_DISABLE_COPY to prevent an accidentally copy. Fixes: QTBUG-71422 Change-Id: I5fa508bc76a4142a4404d3529720e717b7f7fd41 Reviewed-by: Thiago Macieira Reviewed-by: Niels Dekker Reviewed-by: Laszlo Agocs --- src/gui/opengl/qopenglversionfunctions.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/opengl/qopenglversionfunctions.h b/src/gui/opengl/qopenglversionfunctions.h index 3af1ed0466..f828e5668b 100644 --- a/src/gui/opengl/qopenglversionfunctions.h +++ b/src/gui/opengl/qopenglversionfunctions.h @@ -214,6 +214,7 @@ public: virtual bool initializeOpenGLFunctions(); + Q_DISABLE_COPY(QAbstractOpenGLFunctions) Q_DECLARE_PRIVATE(QAbstractOpenGLFunctions) protected: From f06e0f62fafcb0eeb725122b2a5321363d417663 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Wed, 31 Oct 2018 21:00:46 +0100 Subject: [PATCH 0188/1650] Fix usage of QGuiApplication::set/resetOverrideCursor Replace all occurrences of QApplication::set/resetOverrideCursor with the QGuiApplication::set/resetOverrideCursor since it's a static function of QGuiApplication. Change-Id: Ic898ab50a7ad4ed2bc9c6acb26cf4a979c2f82af Reviewed-by: Shawn Rutledge --- examples/network/loopback/dialog.cpp | 6 +++--- examples/widgets/mainwindows/application/mainwindow.cpp | 8 ++++---- examples/widgets/mainwindows/dockwidgets/mainwindow.cpp | 4 ++-- examples/widgets/mainwindows/mdi/mdichild.cpp | 8 ++++---- examples/widgets/mainwindows/sdi/mainwindow.cpp | 8 ++++---- examples/widgets/tools/completer/mainwindow.cpp | 4 ++-- examples/widgets/tools/customcompleter/mainwindow.cpp | 4 ++-- examples/widgets/tools/treemodelcompleter/mainwindow.cpp | 4 ++-- src/corelib/doc/snippets/resource-system/mainwindow.cpp | 8 ++++---- .../snippets/code/src_gui_kernel_qguiapplication_x11.cpp | 4 ++-- src/widgets/kernel/qwhatsthis.cpp | 6 +++--- src/widgets/kernel/qwidget.cpp | 4 ++-- src/widgets/widgets/qtextbrowser.cpp | 6 +++--- tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 4 ++-- tests/manual/qcursor/grab_override/mainwindow.cpp | 4 ++-- 15 files changed, 41 insertions(+), 41 deletions(-) diff --git a/examples/network/loopback/dialog.cpp b/examples/network/loopback/dialog.cpp index b4e6b0fd5e..d87f024031 100644 --- a/examples/network/loopback/dialog.cpp +++ b/examples/network/loopback/dialog.cpp @@ -99,7 +99,7 @@ void Dialog::start() startButton->setEnabled(false); #ifndef QT_NO_CURSOR - QApplication::setOverrideCursor(Qt::WaitCursor); + QGuiApplication::setOverrideCursor(Qt::WaitCursor); #endif bytesWritten = 0; @@ -162,7 +162,7 @@ void Dialog::updateServerProgress() tcpServerConnection->close(); startButton->setEnabled(true); #ifndef QT_NO_CURSOR - QApplication::restoreOverrideCursor(); + QGuiApplication::restoreOverrideCursor(); #endif } } @@ -198,6 +198,6 @@ void Dialog::displayError(QAbstractSocket::SocketError socketError) serverStatusLabel->setText(tr("Server ready")); startButton->setEnabled(true); #ifndef QT_NO_CURSOR - QApplication::restoreOverrideCursor(); + QGuiApplication::restoreOverrideCursor(); #endif } diff --git a/examples/widgets/mainwindows/application/mainwindow.cpp b/examples/widgets/mainwindows/application/mainwindow.cpp index dc93fe4eb2..4b639ead18 100644 --- a/examples/widgets/mainwindows/application/mainwindow.cpp +++ b/examples/widgets/mainwindows/application/mainwindow.cpp @@ -337,11 +337,11 @@ void MainWindow::loadFile(const QString &fileName) QTextStream in(&file); #ifndef QT_NO_CURSOR - QApplication::setOverrideCursor(Qt::WaitCursor); + QGuiApplication::setOverrideCursor(Qt::WaitCursor); #endif textEdit->setPlainText(in.readAll()); #ifndef QT_NO_CURSOR - QApplication::restoreOverrideCursor(); + QGuiApplication::restoreOverrideCursor(); #endif setCurrentFile(fileName); @@ -364,11 +364,11 @@ bool MainWindow::saveFile(const QString &fileName) QTextStream out(&file); #ifndef QT_NO_CURSOR - QApplication::setOverrideCursor(Qt::WaitCursor); + QGuiApplication::setOverrideCursor(Qt::WaitCursor); #endif out << textEdit->toPlainText(); #ifndef QT_NO_CURSOR - QApplication::restoreOverrideCursor(); + QGuiApplication::restoreOverrideCursor(); #endif setCurrentFile(fileName); diff --git a/examples/widgets/mainwindows/dockwidgets/mainwindow.cpp b/examples/widgets/mainwindows/dockwidgets/mainwindow.cpp index 47a6e78265..a62765cdab 100644 --- a/examples/widgets/mainwindows/dockwidgets/mainwindow.cpp +++ b/examples/widgets/mainwindows/dockwidgets/mainwindow.cpp @@ -161,9 +161,9 @@ void MainWindow::save() } QTextStream out(&file); - QApplication::setOverrideCursor(Qt::WaitCursor); + QGuiApplication::setOverrideCursor(Qt::WaitCursor); out << textEdit->toHtml(); - QApplication::restoreOverrideCursor(); + QGuiApplication::restoreOverrideCursor(); statusBar()->showMessage(tr("Saved '%1'").arg(fileName), 2000); } diff --git a/examples/widgets/mainwindows/mdi/mdichild.cpp b/examples/widgets/mainwindows/mdi/mdichild.cpp index 006c84574a..16f2040de0 100644 --- a/examples/widgets/mainwindows/mdi/mdichild.cpp +++ b/examples/widgets/mainwindows/mdi/mdichild.cpp @@ -82,9 +82,9 @@ bool MdiChild::loadFile(const QString &fileName) } QTextStream in(&file); - QApplication::setOverrideCursor(Qt::WaitCursor); + QGuiApplication::setOverrideCursor(Qt::WaitCursor); setPlainText(in.readAll()); - QApplication::restoreOverrideCursor(); + QGuiApplication::restoreOverrideCursor(); setCurrentFile(fileName); @@ -124,9 +124,9 @@ bool MdiChild::saveFile(const QString &fileName) } QTextStream out(&file); - QApplication::setOverrideCursor(Qt::WaitCursor); + QGuiApplication::setOverrideCursor(Qt::WaitCursor); out << toPlainText(); - QApplication::restoreOverrideCursor(); + QGuiApplication::restoreOverrideCursor(); setCurrentFile(fileName); return true; diff --git a/examples/widgets/mainwindows/sdi/mainwindow.cpp b/examples/widgets/mainwindows/sdi/mainwindow.cpp index 301c85c144..d44f7c918d 100644 --- a/examples/widgets/mainwindows/sdi/mainwindow.cpp +++ b/examples/widgets/mainwindows/sdi/mainwindow.cpp @@ -338,9 +338,9 @@ void MainWindow::loadFile(const QString &fileName) } QTextStream in(&file); - QApplication::setOverrideCursor(Qt::WaitCursor); + QGuiApplication::setOverrideCursor(Qt::WaitCursor); textEdit->setPlainText(in.readAll()); - QApplication::restoreOverrideCursor(); + QGuiApplication::restoreOverrideCursor(); setCurrentFile(fileName); statusBar()->showMessage(tr("File loaded"), 2000); @@ -434,9 +434,9 @@ bool MainWindow::saveFile(const QString &fileName) } QTextStream out(&file); - QApplication::setOverrideCursor(Qt::WaitCursor); + QGuiApplication::setOverrideCursor(Qt::WaitCursor); out << textEdit->toPlainText(); - QApplication::restoreOverrideCursor(); + QGuiApplication::restoreOverrideCursor(); setCurrentFile(fileName); statusBar()->showMessage(tr("File saved"), 2000); diff --git a/examples/widgets/tools/completer/mainwindow.cpp b/examples/widgets/tools/completer/mainwindow.cpp index d63d523548..8eb2e60030 100644 --- a/examples/widgets/tools/completer/mainwindow.cpp +++ b/examples/widgets/tools/completer/mainwindow.cpp @@ -159,7 +159,7 @@ QAbstractItemModel *MainWindow::modelFromFile(const QString& fileName) //! [6] #ifndef QT_NO_CURSOR - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); #endif QStringList words; @@ -170,7 +170,7 @@ QAbstractItemModel *MainWindow::modelFromFile(const QString& fileName) } #ifndef QT_NO_CURSOR - QApplication::restoreOverrideCursor(); + QGuiApplication::restoreOverrideCursor(); #endif //! [6] diff --git a/examples/widgets/tools/customcompleter/mainwindow.cpp b/examples/widgets/tools/customcompleter/mainwindow.cpp index 26948d0c8e..7b9db708b9 100644 --- a/examples/widgets/tools/customcompleter/mainwindow.cpp +++ b/examples/widgets/tools/customcompleter/mainwindow.cpp @@ -100,7 +100,7 @@ QAbstractItemModel *MainWindow::modelFromFile(const QString& fileName) return new QStringListModel(completer); #ifndef QT_NO_CURSOR - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); #endif QStringList words; @@ -111,7 +111,7 @@ QAbstractItemModel *MainWindow::modelFromFile(const QString& fileName) } #ifndef QT_NO_CURSOR - QApplication::restoreOverrideCursor(); + QGuiApplication::restoreOverrideCursor(); #endif return new QStringListModel(words, completer); } diff --git a/examples/widgets/tools/treemodelcompleter/mainwindow.cpp b/examples/widgets/tools/treemodelcompleter/mainwindow.cpp index a8b51c7aa0..72b2fad833 100644 --- a/examples/widgets/tools/treemodelcompleter/mainwindow.cpp +++ b/examples/widgets/tools/treemodelcompleter/mainwindow.cpp @@ -180,7 +180,7 @@ QAbstractItemModel *MainWindow::modelFromFile(const QString& fileName) return new QStringListModel(completer); #ifndef QT_NO_CURSOR - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); + QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); #endif QStringList words; @@ -218,7 +218,7 @@ QAbstractItemModel *MainWindow::modelFromFile(const QString& fileName) } #ifndef QT_NO_CURSOR - QApplication::restoreOverrideCursor(); + QGuiApplication::restoreOverrideCursor(); #endif return model; diff --git a/src/corelib/doc/snippets/resource-system/mainwindow.cpp b/src/corelib/doc/snippets/resource-system/mainwindow.cpp index 6fcf52e588..0ab0034d5e 100644 --- a/src/corelib/doc/snippets/resource-system/mainwindow.cpp +++ b/src/corelib/doc/snippets/resource-system/mainwindow.cpp @@ -338,11 +338,11 @@ void MainWindow::loadFile(const QString &fileName) QTextStream in(&file); #ifndef QT_NO_CURSOR - QApplication::setOverrideCursor(Qt::WaitCursor); + QGuiApplication::setOverrideCursor(Qt::WaitCursor); #endif textEdit->setPlainText(in.readAll()); #ifndef QT_NO_CURSOR - QApplication::restoreOverrideCursor(); + QGuiApplication::restoreOverrideCursor(); #endif setCurrentFile(fileName); @@ -365,11 +365,11 @@ bool MainWindow::saveFile(const QString &fileName) QTextStream out(&file); #ifndef QT_NO_CURSOR - QApplication::setOverrideCursor(Qt::WaitCursor); + QGuiApplication::setOverrideCursor(Qt::WaitCursor); #endif out << textEdit->toPlainText(); #ifndef QT_NO_CURSOR - QApplication::restoreOverrideCursor(); + QGuiApplication::restoreOverrideCursor(); #endif setCurrentFile(fileName); diff --git a/src/gui/doc/snippets/code/src_gui_kernel_qguiapplication_x11.cpp b/src/gui/doc/snippets/code/src_gui_kernel_qguiapplication_x11.cpp index e91aa3d548..961ecd6cde 100644 --- a/src/gui/doc/snippets/code/src_gui_kernel_qguiapplication_x11.cpp +++ b/src/gui/doc/snippets/code/src_gui_kernel_qguiapplication_x11.cpp @@ -49,7 +49,7 @@ ****************************************************************************/ //! [0] -QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); +QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); calculateHugeMandelbrot(); // lunch time... -QApplication::restoreOverrideCursor(); +QGuiApplication::restoreOverrideCursor(); //! [0] diff --git a/src/widgets/kernel/qwhatsthis.cpp b/src/widgets/kernel/qwhatsthis.cpp index 1fa83d3238..4a798a7490 100644 --- a/src/widgets/kernel/qwhatsthis.cpp +++ b/src/widgets/kernel/qwhatsthis.cpp @@ -398,10 +398,10 @@ QWhatsThisPrivate::QWhatsThisPrivate() #ifdef QT_NO_CURSOR Q_UNUSED(sentEvent); #else - QApplication::setOverrideCursor((!sentEvent || !e.isAccepted())? + QGuiApplication::setOverrideCursor((!sentEvent || !e.isAccepted())? Qt::ForbiddenCursor:Qt::WhatsThisCursor); } else { - QApplication::setOverrideCursor(Qt::WhatsThisCursor); + QGuiApplication::setOverrideCursor(Qt::WhatsThisCursor); #endif } #ifndef QT_NO_ACCESSIBILITY @@ -417,7 +417,7 @@ QWhatsThisPrivate::~QWhatsThisPrivate() action->setChecked(false); #endif // QT_CONFIG(action) #ifndef QT_NO_CURSOR - QApplication::restoreOverrideCursor(); + QGuiApplication::restoreOverrideCursor(); #endif #ifndef QT_NO_ACCESSIBILITY QAccessibleEvent event(this, QAccessible::ContextHelpEnd); diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 1bca3fc119..4300d83e9c 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -4920,9 +4920,9 @@ void QWidget::unsetLayoutDirection() Some underlying window implementations will reset the cursor if it leaves a widget even if the mouse is grabbed. If you want to have a cursor set for all widgets, even when outside the window, consider - QApplication::setOverrideCursor(). + QGuiApplication::setOverrideCursor(). - \sa QApplication::setOverrideCursor() + \sa QGuiApplication::setOverrideCursor() */ #ifndef QT_NO_CURSOR diff --git a/src/widgets/widgets/qtextbrowser.cpp b/src/widgets/widgets/qtextbrowser.cpp index 46b973bae7..1f00adcfe2 100644 --- a/src/widgets/widgets/qtextbrowser.cpp +++ b/src/widgets/widgets/qtextbrowser.cpp @@ -274,7 +274,7 @@ void QTextBrowserPrivate::setSource(const QUrl &url) Q_Q(QTextBrowser); #ifndef QT_NO_CURSOR if (q->isVisible()) - QApplication::setOverrideCursor(Qt::WaitCursor); + QGuiApplication::setOverrideCursor(Qt::WaitCursor); #endif textOrSourceChanged = true; @@ -308,7 +308,7 @@ void QTextBrowserPrivate::setSource(const QUrl &url) const QStringRef firstTag = txt.leftRef(txt.indexOf(QLatin1Char('>')) + 1); if (firstTag.startsWith(QLatin1String("isVisible()) - QApplication::restoreOverrideCursor(); + QGuiApplication::restoreOverrideCursor(); #endif emit q->sourceChanged(url); } diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 67b326e7ee..648c63b637 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -9422,7 +9422,7 @@ QWidgetBackingStore* backingStore(QWidget &widget) void tst_QWidget::rectOutsideCoordinatesLimit_task144779() { #ifndef QT_NO_CURSOR - QApplication::setOverrideCursor(Qt::BlankCursor); //keep the cursor out of screen grabs + QGuiApplication::setOverrideCursor(Qt::BlankCursor); //keep the cursor out of screen grabs #endif QWidget main(0,Qt::FramelessWindowHint); //don't get confused by the size of the window frame QPalette palette; @@ -9459,7 +9459,7 @@ void tst_QWidget::rectOutsideCoordinatesLimit_task144779() QTRY_COMPARE(mainPixmap.toImage().convertToFormat(QImage::Format_RGB32), correct.toImage().convertToFormat(QImage::Format_RGB32)); #ifndef QT_NO_CURSOR - QApplication::restoreOverrideCursor(); + QGuiApplication::restoreOverrideCursor(); #endif } diff --git a/tests/manual/qcursor/grab_override/mainwindow.cpp b/tests/manual/qcursor/grab_override/mainwindow.cpp index d2b7311846..087ee8d1d8 100644 --- a/tests/manual/qcursor/grab_override/mainwindow.cpp +++ b/tests/manual/qcursor/grab_override/mainwindow.cpp @@ -79,10 +79,10 @@ void MainWindow::toggleOverrideCursor() { switch (override) { case 0: - QApplication::setOverrideCursor(Qt::BusyCursor); + QGuiApplication::setOverrideCursor(Qt::BusyCursor); break; case 1: - QApplication::restoreOverrideCursor(); + QGuiApplication::restoreOverrideCursor(); break; case 2: ui->label->grabMouse(Qt::ForbiddenCursor); From e9bebc12812b5c50346952cd9128bdd08ddd0b9d Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Thu, 18 Oct 2018 22:45:09 +0200 Subject: [PATCH 0189/1650] Fix use of deprecated ItemDataRoles Background/TextColorRole Replace BackgroundColorRole/TextColorRole with BackgroundRole/ForegroundRole and explicit deprecate them for 5.13 Change-Id: I6b0d99844a32d2f5fdfd1878317a7b7422b800d3 Reviewed-by: Samuel Gaist Reviewed-by: Luca Beldi Reviewed-by: Richard Moe Gustavsen --- examples/sql/querymodel/customsqlmodel.cpp | 2 +- .../widgets/itemviews/spreadsheet/spreadsheetitem.cpp | 2 +- src/corelib/global/qnamespace.h | 4 +++- src/testlib/qabstractitemmodeltester.h | 4 ++-- src/widgets/itemviews/qitemdelegate.cpp | 4 ++-- src/widgets/itemviews/qstyleditemdelegate.cpp | 4 ++-- src/widgets/widgets/qcalendarwidget.cpp | 4 ++-- .../corelib/itemmodels/qitemmodel/modelstotest.cpp | 4 ++-- .../corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp | 4 ++-- .../gui/itemmodels/qstandarditem/tst_qstandarditem.cpp | 4 ---- .../qstandarditemmodel/tst_qstandarditemmodel.cpp | 2 +- .../auto/widgets/itemviews/qitemview/tst_qitemview.cpp | 2 +- .../widgets/itemviews/qtreewidget/tst_qtreewidget.cpp | 10 ++++------ 13 files changed, 23 insertions(+), 27 deletions(-) diff --git a/examples/sql/querymodel/customsqlmodel.cpp b/examples/sql/querymodel/customsqlmodel.cpp index 21bedee727..7be0a65882 100644 --- a/examples/sql/querymodel/customsqlmodel.cpp +++ b/examples/sql/querymodel/customsqlmodel.cpp @@ -67,7 +67,7 @@ QVariant CustomSqlModel::data(const QModelIndex &index, int role) const else if (index.column() == 2) return value.toString().toUpper(); } - if (role == Qt::TextColorRole && index.column() == 1) + if (role == Qt::ForegroundRole && index.column() == 1) return QVariant::fromValue(QColor(Qt::blue)); return value; } diff --git a/examples/widgets/itemviews/spreadsheet/spreadsheetitem.cpp b/examples/widgets/itemviews/spreadsheet/spreadsheetitem.cpp index 4c18fa8251..92cbaff031 100644 --- a/examples/widgets/itemviews/spreadsheet/spreadsheetitem.cpp +++ b/examples/widgets/itemviews/spreadsheet/spreadsheetitem.cpp @@ -79,7 +79,7 @@ QVariant SpreadSheetItem::data(int role) const bool isNumber = false; int number = t.toInt(&isNumber); - if (role == Qt::TextColorRole) { + if (role == Qt::ForegroundRole) { if (!isNumber) return QVariant::fromValue(QColor(Qt::black)); else if (number < 0) diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index ce6771d700..41b94bf15a 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1504,9 +1504,11 @@ public: // Metadata FontRole = 6, TextAlignmentRole = 7, +#if QT_DEPRECATED_SINCE(5, 13) BackgroundColorRole = 8, - BackgroundRole = 8, TextColorRole = 9, +#endif + BackgroundRole = 8, ForegroundRole = 9, CheckStateRole = 10, // Accessibility diff --git a/src/testlib/qabstractitemmodeltester.h b/src/testlib/qabstractitemmodeltester.h index 757074c6ae..57b8f283bc 100644 --- a/src/testlib/qabstractitemmodeltester.h +++ b/src/testlib/qabstractitemmodeltester.h @@ -123,11 +123,11 @@ do { \ MODELTESTER_VERIFY(variant.canConvert()); // General Purpose roles that should return a QColor or a QBrush - variant = model->data(model->index(0, 0), Qt::BackgroundColorRole); + variant = model->data(model->index(0, 0), Qt::BackgroundRole); if (variant.isValid()) MODELTESTER_VERIFY(variant.canConvert() || variant.canConvert()); - variant = model->data(model->index(0, 0), Qt::TextColorRole); + variant = model->data(model->index(0, 0), Qt::ForegroundRole); if (variant.isValid()) MODELTESTER_VERIFY(variant.canConvert() || variant.canConvert()); diff --git a/src/widgets/itemviews/qitemdelegate.cpp b/src/widgets/itemviews/qitemdelegate.cpp index 9c65d5fddd..16d4a21f50 100644 --- a/src/widgets/itemviews/qitemdelegate.cpp +++ b/src/widgets/itemviews/qitemdelegate.cpp @@ -266,7 +266,7 @@ QSizeF QItemDelegatePrivate::doTextLayout(int lineWidth) const \row \li \l Qt::AccessibleDescriptionRole \li QString \row \li \l Qt::AccessibleTextRole \li QString \endomit - \row \li \l Qt::BackgroundRole \li QBrush + \row \li \l Qt::BackgroundRole \li QBrush (\since 4.2) \row \li \l Qt::BackgroundColorRole \li QColor (obsolete; use Qt::BackgroundRole instead) \row \li \l Qt::CheckStateRole \li Qt::CheckState \row \li \l Qt::DecorationRole \li QIcon, QPixmap and QColor @@ -278,7 +278,7 @@ QSizeF QItemDelegatePrivate::doTextLayout(int lineWidth) const \row \li \l Qt::StatusTipRole \li \endomit \row \li \l Qt::TextAlignmentRole \li Qt::Alignment - \row \li \l Qt::ForegroundRole \li QBrush + \row \li \l Qt::ForegroundRole \li QBrush (\since 4.2) \row \li \l Qt::TextColorRole \li QColor (obsolete; use Qt::ForegroundRole instead) \omit \row \li \l Qt::ToolTipRole diff --git a/src/widgets/itemviews/qstyleditemdelegate.cpp b/src/widgets/itemviews/qstyleditemdelegate.cpp index 0f7566e8ec..22067851cb 100644 --- a/src/widgets/itemviews/qstyleditemdelegate.cpp +++ b/src/widgets/itemviews/qstyleditemdelegate.cpp @@ -139,7 +139,7 @@ public: \row \li \l Qt::AccessibleDescriptionRole \li QString \row \li \l Qt::AccessibleTextRole \li QString \endomit - \row \li \l Qt::BackgroundRole \li QBrush + \row \li \l Qt::BackgroundRole \li QBrush (\since 4.2) \row \li \l Qt::BackgroundColorRole \li QColor (obsolete; use Qt::BackgroundRole instead) \row \li \l Qt::CheckStateRole \li Qt::CheckState \row \li \l Qt::DecorationRole \li QIcon, QPixmap, QImage and QColor @@ -151,7 +151,7 @@ public: \row \li \l Qt::StatusTipRole \li \endomit \row \li \l Qt::TextAlignmentRole \li Qt::Alignment - \row \li \l Qt::ForegroundRole \li QBrush + \row \li \l Qt::ForegroundRole \li QBrush (\since 4.2) \row \li \l Qt::TextColorRole \li QColor (obsolete; use Qt::ForegroundRole instead) \omit \row \li \l Qt::ToolTipRole diff --git a/src/widgets/widgets/qcalendarwidget.cpp b/src/widgets/widgets/qcalendarwidget.cpp index 4946969360..0553972591 100644 --- a/src/widgets/widgets/qcalendarwidget.cpp +++ b/src/widgets/widgets/qcalendarwidget.cpp @@ -1178,9 +1178,9 @@ QVariant QCalendarModel::data(const QModelIndex &index, int role) const } QTextCharFormat fmt = formatForCell(row, column); - if (role == Qt::BackgroundColorRole) + if (role == Qt::BackgroundRole) return fmt.background().color(); - if (role == Qt::TextColorRole) + if (role == Qt::ForegroundRole) return fmt.foreground().color(); if (role == Qt::FontRole) return fmt.font(); diff --git a/tests/auto/corelib/itemmodels/qitemmodel/modelstotest.cpp b/tests/auto/corelib/itemmodels/qitemmodel/modelstotest.cpp index 6ea7a38137..dbc7173028 100644 --- a/tests/auto/corelib/itemmodels/qitemmodel/modelstotest.cpp +++ b/tests/auto/corelib/itemmodels/qitemmodel/modelstotest.cpp @@ -251,7 +251,7 @@ QModelIndex ModelsToTest::populateTestArea(QAbstractItemModel *model) QString val = xval + QString::number(y) + QString::number(i); QModelIndex index = model->index(x, y, parent); model->setData(index, val); - model->setData(index, blue, Qt::TextColorRole); + model->setData(index, blue, Qt::ForegroundRole); } } */ @@ -276,7 +276,7 @@ QModelIndex ModelsToTest::populateTestArea(QAbstractItemModel *model) QString val = xval + QString::number(y) + QString::number(i); QModelIndex index = realModel->index(x, y, parent); realModel->setData(index, val); - realModel->setData(index, blue, Qt::TextColorRole); + realModel->setData(index, blue, Qt::ForegroundRole); } } */ diff --git a/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp b/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp index 7cd220e684..da13b9f33f 100644 --- a/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp +++ b/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp @@ -576,12 +576,12 @@ void tst_QItemModel::data() alignment == Qt::AlignJustify); } - QVariant colorVariant = currentModel->data(currentModel->index(0,0), Qt::BackgroundColorRole); + QVariant colorVariant = currentModel->data(currentModel->index(0,0), Qt::BackgroundRole); if (colorVariant.isValid()) { QVERIFY(colorVariant.canConvert()); } - colorVariant = currentModel->data(currentModel->index(0,0), Qt::TextColorRole); + colorVariant = currentModel->data(currentModel->index(0,0), Qt::ForegroundRole); if (colorVariant.isValid()) { QVERIFY(colorVariant.canConvert()); } diff --git a/tests/auto/gui/itemmodels/qstandarditem/tst_qstandarditem.cpp b/tests/auto/gui/itemmodels/qstandarditem/tst_qstandarditem.cpp index d19aa9b54f..2deb84fa5f 100644 --- a/tests/auto/gui/itemmodels/qstandarditem/tst_qstandarditem.cpp +++ b/tests/auto/gui/itemmodels/qstandarditem/tst_qstandarditem.cpp @@ -202,9 +202,7 @@ void tst_QStandardItem::getSetData() QCOMPARE(qvariant_cast(item.data(Qt::SizeHintRole)), sizeHint); QCOMPARE(qvariant_cast(item.data(Qt::FontRole)), font); QCOMPARE(qvariant_cast(item.data(Qt::TextAlignmentRole)), int(textAlignment)); - QCOMPARE(qvariant_cast(item.data(Qt::BackgroundColorRole)), QBrush(backgroundColor)); QCOMPARE(qvariant_cast(item.data(Qt::BackgroundRole)), QBrush(backgroundColor)); - QCOMPARE(qvariant_cast(item.data(Qt::TextColorRole)), QBrush(textColor)); QCOMPARE(qvariant_cast(item.data(Qt::ForegroundRole)), QBrush(textColor)); QCOMPARE(qvariant_cast(item.data(Qt::CheckStateRole)), int(checkState)); QCOMPARE(qvariant_cast(item.data(Qt::AccessibleTextRole)), accessibleText); @@ -236,9 +234,7 @@ void tst_QStandardItem::getSetData() QCOMPARE(item.data(Qt::SizeHintRole), QVariant()); QCOMPARE(item.data(Qt::FontRole), QVariant()); QCOMPARE(item.data(Qt::TextAlignmentRole), QVariant()); - QCOMPARE(item.data(Qt::BackgroundColorRole), QVariant()); QCOMPARE(item.data(Qt::BackgroundRole), QVariant()); - QCOMPARE(item.data(Qt::TextColorRole), QVariant()); QCOMPARE(item.data(Qt::ForegroundRole), QVariant()); QCOMPARE(item.data(Qt::CheckStateRole), QVariant()); QCOMPARE(item.data(Qt::AccessibleTextRole), QVariant()); diff --git a/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp b/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp index e2d7a41bd1..550f70890e 100644 --- a/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp +++ b/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp @@ -1160,7 +1160,7 @@ void tst_QStandardItemModel::getSetItemData() QColor backgroundColor(Qt::blue); roles.insert(Qt::BackgroundRole, backgroundColor); QColor textColor(Qt::green); - roles.insert(Qt::TextColorRole, textColor); + roles.insert(Qt::ForegroundRole, textColor); Qt::CheckState checkState(Qt::PartiallyChecked); roles.insert(Qt::CheckStateRole, int(checkState)); QLatin1String accessibleText("accessibleText"); diff --git a/tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp b/tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp index bbdaac5c6f..071665a5e3 100644 --- a/tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp +++ b/tests/auto/widgets/itemviews/qitemview/tst_qitemview.cpp @@ -249,7 +249,7 @@ void tst_QItemView::populate() for (int y = 0; y < treeModel->columnCount(); ++y) { QModelIndex index = treeModel->index(x, y, parent); treeModel->setData(index, xS + QLatin1Char('_') + QString::number(y) + QLatin1Char('_') + iS); - treeModel->setData(index, QVariant(QColor(Qt::blue)), Qt::TextColorRole); + treeModel->setData(index, QVariant(QColor(Qt::blue)), Qt::ForegroundRole); } } } diff --git a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp index c5ccbc0d0b..e0a9684d13 100644 --- a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp +++ b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp @@ -1885,9 +1885,8 @@ void tst_QTreeWidget::setData() QCOMPARE(qvariant_cast(item->data(j, Qt::SizeHintRole)), sizeHint); QCOMPARE(qvariant_cast(item->data(j, Qt::FontRole)), font); QCOMPARE(qvariant_cast(item->data(j, Qt::TextAlignmentRole)), int(textAlignment)); - QCOMPARE(qvariant_cast(item->data(j, Qt::BackgroundColorRole)), QBrush(backgroundColor)); QCOMPARE(qvariant_cast(item->data(j, Qt::BackgroundRole)), QBrush(backgroundColor)); - QCOMPARE(qvariant_cast(item->data(j, Qt::TextColorRole)), textColor); + QCOMPARE(qvariant_cast(item->data(j, Qt::ForegroundRole)), textColor); QCOMPARE(qvariant_cast(item->data(j, Qt::CheckStateRole)), int(checkState)); item->setBackground(j, pixmap); @@ -1907,8 +1906,8 @@ void tst_QTreeWidget::setData() item->setData(j, Qt::SizeHintRole, QVariant()); item->setData(j, Qt::FontRole, QVariant()); item->setData(j, Qt::TextAlignmentRole, QVariant()); - item->setData(j, Qt::BackgroundColorRole, QVariant()); - item->setData(j, Qt::TextColorRole, QVariant()); + item->setData(j, Qt::BackgroundRole, QVariant()); + item->setData(j, Qt::ForegroundRole, QVariant()); item->setData(j, Qt::CheckStateRole, QVariant()); QCOMPARE(itemChangedSpy.count(), 11); itemChangedSpy.clear(); @@ -1921,9 +1920,8 @@ void tst_QTreeWidget::setData() QCOMPARE(item->data(j, Qt::SizeHintRole), QVariant()); QCOMPARE(item->data(j, Qt::FontRole), QVariant()); QCOMPARE(item->data(j, Qt::TextAlignmentRole), QVariant()); - QCOMPARE(item->data(j, Qt::BackgroundColorRole), QVariant()); QCOMPARE(item->data(j, Qt::BackgroundRole), QVariant()); - QCOMPARE(item->data(j, Qt::TextColorRole), QVariant()); + QCOMPARE(item->data(j, Qt::ForegroundRole), QVariant()); QCOMPARE(item->data(j, Qt::CheckStateRole), QVariant()); } } From 6963efb396f7f206afb2f3f9655f26b0c21b6a05 Mon Sep 17 00:00:00 2001 From: Luca Beldi Date: Mon, 5 Nov 2018 12:17:31 +0000 Subject: [PATCH 0190/1650] New proxy model: QTransposeProxyModel Implemented a new proxy model to transpose the source model. Rows will become columns and vice-versa. Both flat and tree models supported. [ChangeLog][QtCore] New class QTransposeProxyModel to swap rows and columns of the source model. Change-Id: I902963c6b81aa0f63b5ad2bddca538f28b565084 Reviewed-by: David Faure --- src/corelib/configure.json | 7 + src/corelib/itemmodels/itemmodels.pri | 9 + src/corelib/itemmodels/qabstractitemmodel.h | 2 + .../itemmodels/qtransposeproxymodel.cpp | 446 +++++++++ src/corelib/itemmodels/qtransposeproxymodel.h | 83 ++ .../itemmodels/qtransposeproxymodel_p.h | 73 ++ tests/auto/corelib/itemmodels/itemmodels.pro | 1 + .../qtransposeproxymodel.pro | 6 + .../tst_qtransposeproxymodel.cpp | 915 ++++++++++++++++++ 9 files changed, 1542 insertions(+) create mode 100644 src/corelib/itemmodels/qtransposeproxymodel.cpp create mode 100644 src/corelib/itemmodels/qtransposeproxymodel.h create mode 100644 src/corelib/itemmodels/qtransposeproxymodel_p.h create mode 100644 tests/auto/corelib/itemmodels/qtransposeproxymodel/qtransposeproxymodel.pro create mode 100644 tests/auto/corelib/itemmodels/qtransposeproxymodel/tst_qtransposeproxymodel.cpp diff --git a/src/corelib/configure.json b/src/corelib/configure.json index f09ef6c1dd..f18e79f1aa 100644 --- a/src/corelib/configure.json +++ b/src/corelib/configure.json @@ -793,6 +793,13 @@ "condition": "features.proxymodel", "output": [ "publicFeature", "feature" ] }, + "transposeproxymodel": { + "label": "QTransposeProxyModel", + "purpose": "Provides a proxy to swap rows and columns of a model.", + "section": "ItemViews", + "condition": "features.proxymodel", + "output": [ "publicFeature", "feature" ] + }, "concatenatetablesproxymodel": { "label": "QConcatenateTablesProxyModel", "purpose": "Supports concatenating source models.", diff --git a/src/corelib/itemmodels/itemmodels.pri b/src/corelib/itemmodels/itemmodels.pri index 5a977c6623..ebeac6e211 100644 --- a/src/corelib/itemmodels/itemmodels.pri +++ b/src/corelib/itemmodels/itemmodels.pri @@ -43,6 +43,15 @@ qtConfig(proxymodel) { SOURCES += \ itemmodels/qsortfilterproxymodel.cpp } + + qtConfig(transposeproxymodel) { + HEADERS += \ + itemmodels/qtransposeproxymodel.h \ + itemmodels/qtransposeproxymodel_p.h + + SOURCES += \ + itemmodels/qtransposeproxymodel.cpp + } } qtConfig(stringlistmodel) { diff --git a/src/corelib/itemmodels/qabstractitemmodel.h b/src/corelib/itemmodels/qabstractitemmodel.h index bec71b0606..0aa75d6ff7 100644 --- a/src/corelib/itemmodels/qabstractitemmodel.h +++ b/src/corelib/itemmodels/qabstractitemmodel.h @@ -163,6 +163,7 @@ typedef QList QModelIndexList; class QMimeData; class QAbstractItemModelPrivate; +class QTransposeProxyModelPrivate; template class QMap; @@ -173,6 +174,7 @@ class Q_CORE_EXPORT QAbstractItemModel : public QObject friend class QPersistentModelIndexData; friend class QAbstractItemViewPrivate; friend class QIdentityProxyModel; + friend class QTransposeProxyModelPrivate; public: explicit QAbstractItemModel(QObject *parent = nullptr); diff --git a/src/corelib/itemmodels/qtransposeproxymodel.cpp b/src/corelib/itemmodels/qtransposeproxymodel.cpp new file mode 100644 index 0000000000..dd84b97118 --- /dev/null +++ b/src/corelib/itemmodels/qtransposeproxymodel.cpp @@ -0,0 +1,446 @@ +/**************************************************************************** +** +** Copyright (C) 2018 Luca Beldi +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtransposeproxymodel.h" +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +QModelIndex QTransposeProxyModelPrivate::uncheckedMapToSource(const QModelIndex &proxyIndex) const +{ + if (!model || !proxyIndex.isValid()) + return QModelIndex(); + if (proxyIndex.internalPointer()) + return model->createIndex(proxyIndex.column(), proxyIndex.row(), proxyIndex.internalPointer()); + return model->index(proxyIndex.column(), proxyIndex.row()); +} + +QModelIndex QTransposeProxyModelPrivate::uncheckedMapFromSource(const QModelIndex &sourceIndex) const +{ + if (!model || !sourceIndex.isValid()) + return QModelIndex(); + Q_Q(const QTransposeProxyModel); + return q->createIndex(sourceIndex.column(), sourceIndex.row(), sourceIndex.internalPointer()); +} + +void QTransposeProxyModelPrivate::onLayoutChanged(const QList &parents, QAbstractItemModel::LayoutChangeHint hint) +{ + Q_Q(QTransposeProxyModel); + QModelIndexList toList; + toList.reserve(layoutChangePersistentIndexes.size()); + for (const QPersistentModelIndex &persistIdx : qAsConst(layoutChangePersistentIndexes)) + toList << q->mapFromSource(persistIdx); + q->changePersistentIndexList(layoutChangeProxyIndexes, toList); + layoutChangeProxyIndexes.clear(); + layoutChangePersistentIndexes.clear(); + QList proxyParents; + proxyParents.reserve(parents.size()); + for (const QPersistentModelIndex &srcParent : parents) + proxyParents << q->mapFromSource(srcParent); + QAbstractItemModel::LayoutChangeHint proxyHint = QAbstractItemModel::NoLayoutChangeHint; + if (hint == QAbstractItemModel::VerticalSortHint) + proxyHint = QAbstractItemModel::HorizontalSortHint; + else if (hint == QAbstractItemModel::HorizontalSortHint) + proxyHint = QAbstractItemModel::VerticalSortHint; + q->layoutChanged(proxyParents, proxyHint); +} + +void QTransposeProxyModelPrivate::onLayoutAboutToBeChanged(const QList &parents, QAbstractItemModel::LayoutChangeHint hint) +{ + Q_Q(QTransposeProxyModel); + const QModelIndexList proxyPersistentIndexes = q->persistentIndexList(); + layoutChangeProxyIndexes.clear(); + layoutChangePersistentIndexes.clear(); + layoutChangeProxyIndexes.reserve(proxyPersistentIndexes.size()); + layoutChangePersistentIndexes.reserve(proxyPersistentIndexes.size()); + for (const QPersistentModelIndex &proxyPersistentIndex : proxyPersistentIndexes) { + layoutChangeProxyIndexes << proxyPersistentIndex; + Q_ASSERT(proxyPersistentIndex.isValid()); + const QPersistentModelIndex srcPersistentIndex = q->mapToSource(proxyPersistentIndex); + Q_ASSERT(srcPersistentIndex.isValid()); + layoutChangePersistentIndexes << srcPersistentIndex; + } + QList proxyParents; + proxyParents.reserve(parents.size()); + for (auto& srcParent : parents) + proxyParents << q->mapFromSource(srcParent); + QAbstractItemModel::LayoutChangeHint proxyHint = QAbstractItemModel::NoLayoutChangeHint; + if (hint == QAbstractItemModel::VerticalSortHint) + proxyHint = QAbstractItemModel::HorizontalSortHint; + else if (hint == QAbstractItemModel::HorizontalSortHint) + proxyHint = QAbstractItemModel::VerticalSortHint; + q->layoutAboutToBeChanged(proxyParents, proxyHint); +} + +void QTransposeProxyModelPrivate::onDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector& roles) +{ + Q_Q(QTransposeProxyModel); + q->dataChanged(q->mapFromSource(topLeft), q->mapFromSource(bottomRight), roles); +} + +void QTransposeProxyModelPrivate::onHeaderDataChanged(Qt::Orientation orientation, int first, int last) +{ + Q_Q(QTransposeProxyModel); + q->headerDataChanged(orientation == Qt::Horizontal ? Qt::Vertical : Qt::Horizontal, first, last); +} + +void QTransposeProxyModelPrivate::onColumnsAboutToBeInserted(const QModelIndex &parent, int first, int last) +{ + Q_Q(QTransposeProxyModel); + q->beginInsertRows(q->mapFromSource(parent), first, last); +} + +void QTransposeProxyModelPrivate::onColumnsAboutToBeRemoved(const QModelIndex &parent, int first, int last) +{ + Q_Q(QTransposeProxyModel); + q->beginRemoveRows(q->mapFromSource(parent), first, last); +} + +void QTransposeProxyModelPrivate::onColumnsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationColumn) +{ + Q_Q(QTransposeProxyModel); + q->beginMoveRows(q->mapFromSource(sourceParent), sourceStart, sourceEnd, q->mapFromSource(destinationParent), destinationColumn); +} + +void QTransposeProxyModelPrivate::onRowsAboutToBeInserted(const QModelIndex &parent, int first, int last) +{ + Q_Q(QTransposeProxyModel); + q->beginInsertColumns(q->mapFromSource(parent), first, last); +} + +void QTransposeProxyModelPrivate::onRowsAboutToBeRemoved(const QModelIndex &parent, int first, int last) +{ + Q_Q(QTransposeProxyModel); + q->beginRemoveColumns(q->mapFromSource(parent), first, last); +} + +void QTransposeProxyModelPrivate::onRowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow) +{ + Q_Q(QTransposeProxyModel); + q->beginMoveColumns(q->mapFromSource(sourceParent), sourceStart, sourceEnd, q->mapFromSource(destinationParent), destinationRow); +} + +/*! + \since 5.13 + \class QTransposeProxyModel + \brief This proxy transposes the source model + \details This model will make the rows of the source model become columns of the proxy model and vice-versa. + + If the model is a tree, the parents will be transposed as well. For example, if an index in the source model had parent `index(2,0)`, it will have parent `index(0,2)` in the proxy. +*/ + +/*! + Constructs a new proxy model with the given \a parent. +*/ +QTransposeProxyModel::QTransposeProxyModel(QObject* parent) + : QAbstractProxyModel(*new QTransposeProxyModelPrivate, parent) +{} + +/*! + Destructs the proxy model. +*/ +QTransposeProxyModel::~QTransposeProxyModel() = default; + +/*! + \internal +*/ +QTransposeProxyModel::QTransposeProxyModel(QTransposeProxyModelPrivate &dd, QObject *parent) + : QAbstractProxyModel(dd, parent) +{} + +/*! + \reimp +*/ +void QTransposeProxyModel::setSourceModel(QAbstractItemModel* newSourceModel) +{ + Q_D(QTransposeProxyModel); + if (newSourceModel == d->model) + return; + beginResetModel(); + if (d->model) { + for (const QMetaObject::Connection& discIter : qAsConst(d->sourceConnections)) + disconnect(discIter); + } + d->sourceConnections.clear(); + QAbstractProxyModel::setSourceModel(newSourceModel); + if (d->model) { + using namespace std::placeholders; + d->sourceConnections = QVector{ + connect(d->model, &QAbstractItemModel::modelAboutToBeReset, this, &QTransposeProxyModel::beginResetModel), + connect(d->model, &QAbstractItemModel::modelReset, this, &QTransposeProxyModel::endResetModel), + connect(d->model, &QAbstractItemModel::dataChanged, this, std::bind(&QTransposeProxyModelPrivate::onDataChanged, d, _1, _2, _3)), + connect(d->model, &QAbstractItemModel::headerDataChanged, this, std::bind(&QTransposeProxyModelPrivate::onHeaderDataChanged, d, _1, _2, _3)), + connect(d->model, &QAbstractItemModel::columnsAboutToBeInserted, this, std::bind(&QTransposeProxyModelPrivate::onColumnsAboutToBeInserted, d, _1, _2, _3)), + connect(d->model, &QAbstractItemModel::columnsAboutToBeMoved, this, std::bind(&QTransposeProxyModelPrivate::onColumnsAboutToBeMoved, d, _1, _2, _3, _4, _5)), + connect(d->model, &QAbstractItemModel::columnsAboutToBeRemoved, this, std::bind(&QTransposeProxyModelPrivate::onColumnsAboutToBeRemoved, d, _1, _2, _3)), + connect(d->model, &QAbstractItemModel::columnsInserted, this, &QTransposeProxyModel::endInsertRows), + connect(d->model, &QAbstractItemModel::columnsRemoved, this, &QTransposeProxyModel::endRemoveRows), + connect(d->model, &QAbstractItemModel::columnsMoved, this, &QTransposeProxyModel::endMoveRows), + connect(d->model, &QAbstractItemModel::rowsAboutToBeInserted, this, std::bind(&QTransposeProxyModelPrivate::onRowsAboutToBeInserted, d, _1, _2, _3)), + connect(d->model, &QAbstractItemModel::rowsAboutToBeMoved, this, std::bind(&QTransposeProxyModelPrivate::onRowsAboutToBeMoved, d, _1, _2, _3, _4, _5)), + connect(d->model, &QAbstractItemModel::rowsAboutToBeRemoved, this, std::bind(&QTransposeProxyModelPrivate::onRowsAboutToBeRemoved, d, _1, _2, _3)), + connect(d->model, &QAbstractItemModel::rowsInserted, this, &QTransposeProxyModel::endInsertColumns), + connect(d->model, &QAbstractItemModel::rowsRemoved, this, &QTransposeProxyModel::endRemoveColumns), + connect(d->model, &QAbstractItemModel::rowsMoved, this, &QTransposeProxyModel::endMoveColumns), + connect(d->model, &QAbstractItemModel::layoutAboutToBeChanged, this, std::bind(&QTransposeProxyModelPrivate::onLayoutAboutToBeChanged, d, _1, _2)), + connect(d->model, &QAbstractItemModel::layoutChanged, this, std::bind(&QTransposeProxyModelPrivate::onLayoutChanged, d, _1, _2)) + }; + } + endResetModel(); +} + +/*! + \reimp +*/ +int QTransposeProxyModel::rowCount(const QModelIndex &parent) const +{ + Q_D(const QTransposeProxyModel); + if (!d->model) + return 0; + Q_ASSERT(checkIndex(parent)); + return d->model->columnCount(mapToSource(parent)); +} + +/*! + \reimp +*/ +int QTransposeProxyModel::columnCount(const QModelIndex &parent) const +{ + Q_D(const QTransposeProxyModel); + if (!d->model) + return 0; + Q_ASSERT(checkIndex(parent)); + return d->model->rowCount(mapToSource(parent)); +} + +/*! + \reimp +*/ +QVariant QTransposeProxyModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + Q_D(const QTransposeProxyModel); + if (!d->model) + return QVariant(); + return d->model->headerData(section, orientation == Qt::Horizontal ? Qt::Vertical : Qt::Horizontal, role); +} + +/*! + \reimp +*/ +bool QTransposeProxyModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role) +{ + Q_D(QTransposeProxyModel); + if (!d->model) + return false; + return d->model->setHeaderData(section, orientation == Qt::Horizontal ? Qt::Vertical : Qt::Horizontal, value, role); +} + +/*! + \reimp +*/ +bool QTransposeProxyModel::setItemData(const QModelIndex &index, const QMap &roles) +{ + Q_D(QTransposeProxyModel); + Q_ASSERT(checkIndex(index)); + if (!d->model || !index.isValid()) + return false; + return d->model->setItemData(mapToSource(index), roles); +} + +/*! + \reimp +*/ +QSize QTransposeProxyModel::span(const QModelIndex &index) const +{ + Q_D(const QTransposeProxyModel); + Q_ASSERT(checkIndex(index)); + if (!d->model || !index.isValid()) + return QSize(); + return d->model->span(mapToSource(index)).transposed(); +} + +/*! + \reimp +*/ +QMap QTransposeProxyModel::itemData(const QModelIndex &index) const +{ + Q_D(const QTransposeProxyModel); + if (!d->model) + return QMap(); + Q_ASSERT(checkIndex(index)); + return d->model->itemData(mapToSource(index)); +} + +/*! + \reimp +*/ +QModelIndex QTransposeProxyModel::mapFromSource(const QModelIndex &sourceIndex) const +{ + Q_D(const QTransposeProxyModel); + if (!d->model || !sourceIndex.isValid()) + return QModelIndex(); + Q_ASSERT(d->model->checkIndex(sourceIndex)); + return d->uncheckedMapFromSource(sourceIndex); +} + +/*! + \reimp +*/ +QModelIndex QTransposeProxyModel::mapToSource(const QModelIndex &proxyIndex) const +{ + Q_D(const QTransposeProxyModel); + Q_ASSERT(checkIndex(proxyIndex)); + if (!d->model || !proxyIndex.isValid()) + return QModelIndex(); + return d->uncheckedMapToSource(proxyIndex); +} + +/*! + \reimp +*/ +QModelIndex QTransposeProxyModel::parent(const QModelIndex &index) const +{ + Q_D(const QTransposeProxyModel); + Q_ASSERT(checkIndex(index, CheckIndexOption::DoNotUseParent)); + if (!d->model || !index.isValid()) + return QModelIndex(); + return d->uncheckedMapFromSource(d->uncheckedMapToSource(index).parent()); +} + +/*! + \reimp +*/ +QModelIndex QTransposeProxyModel::index(int row, int column, const QModelIndex &parent) const +{ + Q_D(const QTransposeProxyModel); + Q_ASSERT(checkIndex(parent)); + if (!d->model) + return QModelIndex(); + return mapFromSource(d->model->index(column, row, mapToSource(parent))); +} + +/*! + \reimp +*/ +bool QTransposeProxyModel::insertRows(int row, int count, const QModelIndex &parent) +{ + Q_D(QTransposeProxyModel); + Q_ASSERT(checkIndex(parent)); + if (!d->model) + return false; + return d->model->insertColumns(row, count, mapToSource(parent)); +} + +/*! + \reimp +*/ +bool QTransposeProxyModel::removeRows(int row, int count, const QModelIndex &parent) +{ + Q_D(QTransposeProxyModel); + Q_ASSERT(checkIndex(parent)); + if (!d->model) + return false; + return d->model->removeColumns(row, count, mapToSource(parent)); +} + +/*! + \reimp +*/ +bool QTransposeProxyModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) +{ + Q_D(QTransposeProxyModel); + Q_ASSERT(checkIndex(sourceParent)); + Q_ASSERT(checkIndex(destinationParent)); + if (!d->model) + return false; + return d->model->moveColumns(mapToSource(sourceParent), sourceRow, count, mapToSource(destinationParent), destinationChild); +} + +/*! + \reimp +*/ +bool QTransposeProxyModel::insertColumns(int column, int count, const QModelIndex &parent) +{ + Q_D(QTransposeProxyModel); + Q_ASSERT(checkIndex(parent)); + if (!d->model) + return false; + return d->model->insertRows(column, count, mapToSource(parent)); +} + +/*! + \reimp +*/ +bool QTransposeProxyModel::removeColumns(int column, int count, const QModelIndex &parent) +{ + Q_D(QTransposeProxyModel); + Q_ASSERT(checkIndex(parent)); + if (!d->model) + return false; + return d->model->removeRows(column, count, mapToSource(parent)); +} + +/*! + \reimp +*/ +bool QTransposeProxyModel::moveColumns(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) +{ + Q_D(QTransposeProxyModel); + Q_ASSERT(checkIndex(sourceParent)); + Q_ASSERT(checkIndex(destinationParent)); + if (!d->model) + return false; + return d->model->moveRows(mapToSource(sourceParent), sourceRow, count, mapToSource(destinationParent), destinationChild); +} + +/*! + \reimp + This method will perform no action. Use a QSortFilterProxyModel on top of this one if you require sorting. +*/ +void QTransposeProxyModel::sort(int column, Qt::SortOrder order) +{ + Q_UNUSED(column) + Q_UNUSED(order) + return; +} + +QT_END_NAMESPACE diff --git a/src/corelib/itemmodels/qtransposeproxymodel.h b/src/corelib/itemmodels/qtransposeproxymodel.h new file mode 100644 index 0000000000..879266d931 --- /dev/null +++ b/src/corelib/itemmodels/qtransposeproxymodel.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2018 Luca Beldi +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTRANSPOSEPROXYMODEL_H +#define QTRANSPOSEPROXYMODEL_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class QTransposeProxyModelPrivate; + +class Q_CORE_EXPORT QTransposeProxyModel : public QAbstractProxyModel +{ + Q_OBJECT + Q_DISABLE_COPY(QTransposeProxyModel) + Q_DECLARE_PRIVATE(QTransposeProxyModel) +public: + explicit QTransposeProxyModel(QObject* parent = nullptr); + ~QTransposeProxyModel(); + void setSourceModel(QAbstractItemModel* newSourceModel) override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole) override; + bool setItemData(const QModelIndex &index, const QMap &roles) override; + QSize span(const QModelIndex &index) const override; + QMap itemData(const QModelIndex &index) const override; + QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override; + QModelIndex mapToSource(const QModelIndex &proxyIndex) const override; + QModelIndex parent(const QModelIndex &index) const override; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; + bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; + bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; + bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) override; + bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override; + bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override; + bool moveColumns(const QModelIndex &sourceParent, int sourceColumn, int count, const QModelIndex &destinationParent, int destinationChild) override; + void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override; +protected: + QTransposeProxyModel(QTransposeProxyModelPrivate &, QObject *parent); +}; + +QT_END_NAMESPACE + +#endif // QTRANSPOSEPROXYMODEL_H diff --git a/src/corelib/itemmodels/qtransposeproxymodel_p.h b/src/corelib/itemmodels/qtransposeproxymodel_p.h new file mode 100644 index 0000000000..240fc4ccae --- /dev/null +++ b/src/corelib/itemmodels/qtransposeproxymodel_p.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2018 Luca Beldi +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTRANSPOSEPROXYMODEL_P_H +#define QTRANSPOSEPROXYMODEL_P_H + +#include "qtransposeproxymodel.h" +#include + +QT_BEGIN_NAMESPACE + +class QTransposeProxyModelPrivate : public QAbstractProxyModelPrivate +{ + Q_DECLARE_PUBLIC(QTransposeProxyModel) + Q_DISABLE_COPY(QTransposeProxyModelPrivate) +private: + QTransposeProxyModelPrivate() = default; + QVector sourceConnections; + QVector layoutChangePersistentIndexes; + QModelIndexList layoutChangeProxyIndexes; + QModelIndex uncheckedMapToSource(const QModelIndex &proxyIndex) const; + QModelIndex uncheckedMapFromSource(const QModelIndex &sourceIndex) const; + void onLayoutChanged(const QList &parents, QAbstractItemModel::LayoutChangeHint hint); + void onLayoutAboutToBeChanged(const QList &parents, QAbstractItemModel::LayoutChangeHint hint); + void onDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector& roles); + void onHeaderDataChanged(Qt::Orientation orientation, int first, int last); + void onColumnsAboutToBeInserted(const QModelIndex &parent, int first, int last); + void onColumnsAboutToBeRemoved(const QModelIndex &parent, int first, int last); + void onColumnsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationColumn); + void onRowsAboutToBeInserted(const QModelIndex &parent, int first, int last); + void onRowsAboutToBeRemoved(const QModelIndex &parent, int first, int last); + void onRowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow); +}; + +QT_END_NAMESPACE + +#endif //QTRANSPOSEPROXYMODEL_P_H diff --git a/tests/auto/corelib/itemmodels/itemmodels.pro b/tests/auto/corelib/itemmodels/itemmodels.pro index b27938e0c0..ffbda6ec40 100644 --- a/tests/auto/corelib/itemmodels/itemmodels.pro +++ b/tests/auto/corelib/itemmodels/itemmodels.pro @@ -9,6 +9,7 @@ qtHaveModule(gui): SUBDIRS += \ qidentityproxymodel \ qitemselectionmodel \ qsortfilterproxymodel_recursive \ + qtransposeproxymodel \ qtHaveModule(widgets) { SUBDIRS += \ diff --git a/tests/auto/corelib/itemmodels/qtransposeproxymodel/qtransposeproxymodel.pro b/tests/auto/corelib/itemmodels/qtransposeproxymodel/qtransposeproxymodel.pro new file mode 100644 index 0000000000..3834add115 --- /dev/null +++ b/tests/auto/corelib/itemmodels/qtransposeproxymodel/qtransposeproxymodel.pro @@ -0,0 +1,6 @@ +CONFIG += testcase +TARGET = tst_qtransposeproxymodel +QT = core gui testlib + +SOURCES = tst_qtransposeproxymodel.cpp + diff --git a/tests/auto/corelib/itemmodels/qtransposeproxymodel/tst_qtransposeproxymodel.cpp b/tests/auto/corelib/itemmodels/qtransposeproxymodel/tst_qtransposeproxymodel.cpp new file mode 100644 index 0000000000..a30ac46571 --- /dev/null +++ b/tests/auto/corelib/itemmodels/qtransposeproxymodel/tst_qtransposeproxymodel.cpp @@ -0,0 +1,915 @@ +/**************************************************************************** +** +** Copyright (C) 2018 Luca Beldi +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include + +class tst_QTransposeProxyModel : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void initTestCase(); + void index(); + void data(); + void setData_data(); + void setData(); + void parent(); + void mapToSource(); + void mapFromSource(); + void basicTest_data(); + void basicTest(); + void sort(); + void insertRowBase_data(); + void insertRowBase(); + void insertColumnBase_data(); + void insertColumnBase(); + void insertColumnProxy_data(); + void insertColumnProxy(); + void insertRowProxy_data(); + void insertRowProxy(); + void removeRowBase_data(); + void removeRowBase(); + void removeColumnBase_data(); + void removeColumnBase(); + void removeColumnProxy_data(); + void removeColumnProxy(); + void removeRowProxy_data(); + void removeRowProxy(); + void headerData(); + void setHeaderData(); + void span(); + void itemData(); + void setItemData(); + void moveRowsBase(); + void moveColumnsProxy(); +private: + void testTransposed( + const QAbstractItemModel *const baseModel, + const QAbstractItemModel *const transposed, + const QModelIndex &baseParent = QModelIndex(), + const QModelIndex &transposedParent = QModelIndex() + ); + QAbstractItemModel *createListModel(QObject *parent); + QAbstractItemModel *createTableModel(QObject *parent); + QAbstractItemModel *createTreeModel(QObject *parent); +}; + +QAbstractItemModel *tst_QTransposeProxyModel::createListModel(QObject *parent) +{ + QStringList sequence; + sequence.reserve(10); + for (int i = 0; i < 10; ++i) + sequence.append(QString::number(i)); + return new QStringListModel(sequence, parent); +} + +QAbstractItemModel *tst_QTransposeProxyModel::createTableModel(QObject *parent) +{ + QAbstractItemModel *model = new QStandardItemModel(parent); + model->insertRows(0, 5); + model->insertColumns(0, 4); + for (int i = 0; i < model->rowCount(); ++i) { + for (int j = 0; j < model->columnCount(); ++j) { + model->setData(model->index(i, j), QStringLiteral("%1,%2").arg(i).arg(j), Qt::EditRole); + model->setData(model->index(i, j), i, Qt::UserRole); + model->setData(model->index(i, j), j, Qt::UserRole + 1); + } + } + return model; +} + +QAbstractItemModel *tst_QTransposeProxyModel::createTreeModel(QObject *parent) +{ + QAbstractItemModel *model = new QStandardItemModel(parent); + model->insertRows(0, 5); + model->insertColumns(0, 4); + for (int i = 0; i < model->rowCount(); ++i) { + for (int j = 0; j < model->columnCount(); ++j) { + const QModelIndex parIdx = model->index(i, j); + model->setData(parIdx, QStringLiteral("%1,%2").arg(i).arg(j), Qt::EditRole); + model->setData(parIdx, i, Qt::UserRole); + model->setData(parIdx, j, Qt::UserRole + 1); + model->insertRows(0, 3, parIdx); + model->insertColumns(0, 2, parIdx); + for (int h = 0; h < model->rowCount(parIdx); ++h) { + for (int k = 0; k < model->columnCount(parIdx); ++k) { + const QModelIndex childIdx = model->index(h, k, parIdx); + model->setData(childIdx, QStringLiteral("%1,%2,%3,%4").arg(i).arg(j).arg(h).arg(k), Qt::EditRole); + model->setData(childIdx, i, Qt::UserRole); + model->setData(childIdx, j, Qt::UserRole + 1); + model->setData(childIdx, h, Qt::UserRole + 2); + model->setData(childIdx, k, Qt::UserRole + 3); + } + } + } + } + return model; +} + +void tst_QTransposeProxyModel::testTransposed( + const QAbstractItemModel *const baseModel, + const QAbstractItemModel *const transposed, + const QModelIndex &baseParent, + const QModelIndex &transposedParent +) +{ + QCOMPARE(transposed->hasChildren(transposedParent), baseModel->hasChildren(baseParent)); + QCOMPARE(transposed->columnCount(transposedParent), baseModel->rowCount(baseParent)); + QCOMPARE(transposed->rowCount(transposedParent), baseModel->columnCount(baseParent)); + for (int i = 0, maxRow = baseModel->rowCount(baseParent); i < maxRow; ++i) { + for (int j = 0, maxCol = baseModel->columnCount(baseParent); j < maxCol; ++j) { + const QModelIndex baseIdx = baseModel->index(i, j, baseParent); + const QModelIndex transIdx = transposed->index(j, i, transposedParent); + QCOMPARE(transIdx.data(), baseIdx.data()); + QCOMPARE(transIdx.data(Qt::UserRole), baseIdx.data(Qt::UserRole)); + QCOMPARE(transIdx.data(Qt::UserRole + 1), baseIdx.data(Qt::UserRole + 1)); + QCOMPARE(transIdx.data(Qt::UserRole + 2), baseIdx.data(Qt::UserRole + 2)); + QCOMPARE(transIdx.data(Qt::UserRole + 3), baseIdx.data(Qt::UserRole + 3)); + if (baseModel->hasChildren(baseIdx)) { + testTransposed(baseModel, transposed, baseIdx, transIdx); + } + } + } +} + +void tst_QTransposeProxyModel::initTestCase() +{ + qRegisterMetaType >(); + qRegisterMetaType(); +} + +void tst_QTransposeProxyModel::index() +{ + QAbstractItemModel *model = createTreeModel(this); + QTransposeProxyModel proxy; + new QAbstractItemModelTester(&proxy, &proxy); + proxy.setSourceModel(model); + QVERIFY(!proxy.index(0, -1).isValid()); + QVERIFY(!proxy.index(0, -1).isValid()); + QVERIFY(!proxy.index(-1, -1).isValid()); + QVERIFY(!proxy.index(0, proxy.columnCount()).isValid()); + QVERIFY(!proxy.index(proxy.rowCount(), 0).isValid()); + QVERIFY(!proxy.index(proxy.rowCount(), proxy.columnCount()).isValid()); + QModelIndex tempIdx = proxy.index(0, 1); + QVERIFY(tempIdx.isValid()); + QCOMPARE(tempIdx.row(), 0); + QCOMPARE(tempIdx.column(), 1); + tempIdx = proxy.index(0, 1, tempIdx); + QVERIFY(tempIdx.isValid()); + QCOMPARE(tempIdx.row(), 0); + QCOMPARE(tempIdx.column(), 1); + delete model; +} + +void tst_QTransposeProxyModel::data() +{ + QStringListModel model{QStringList{"A", "B"}}; + QTransposeProxyModel proxy; + new QAbstractItemModelTester(&proxy, &proxy); + proxy.setSourceModel(&model); + QCOMPARE(proxy.index(0, 1).data().toString(), QStringLiteral("B")); +} + +void tst_QTransposeProxyModel::parent() +{ + QAbstractItemModel *model = createTreeModel(this); + QTransposeProxyModel proxy; + new QAbstractItemModelTester(&proxy, &proxy); + proxy.setSourceModel(model); + const QModelIndex parentIdx = proxy.index(0, 0); + const QModelIndex childIdx = proxy.index(0, 0, parentIdx); + QVERIFY(parentIdx.isValid()); + QVERIFY(childIdx.isValid()); + QCOMPARE(childIdx.parent(), parentIdx); + delete model; +} + +void tst_QTransposeProxyModel::mapToSource() +{ + QAbstractItemModel *model = createTreeModel(this); + QTransposeProxyModel proxy; + new QAbstractItemModelTester(&proxy, &proxy); + proxy.setSourceModel(model); + QVERIFY(!proxy.mapToSource(QModelIndex()).isValid()); + QCOMPARE(proxy.mapToSource(proxy.index(0, 0)), model->index(0, 0)); + QCOMPARE(proxy.mapToSource(proxy.index(1, 0)), model->index(0, 1)); + QCOMPARE(proxy.mapToSource(proxy.index(0, 1)), model->index(1, 0)); + const QModelIndex proxyParent = proxy.index(1, 0); + const QModelIndex sourceParent = model->index(0, 1); + QCOMPARE(proxy.mapToSource(proxy.index(0, 0, proxyParent)), model->index(0, 0, sourceParent)); + QCOMPARE(proxy.mapToSource(proxy.index(1, 0, proxyParent)), model->index(0, 1, sourceParent)); + QCOMPARE(proxy.mapToSource(proxy.index(0, 1, proxyParent)), model->index(1, 0, sourceParent)); + delete model; +} + +void tst_QTransposeProxyModel::mapFromSource() +{ + QAbstractItemModel *model = createTreeModel(this); + QTransposeProxyModel proxy; + new QAbstractItemModelTester(&proxy, &proxy); + proxy.setSourceModel(model); + QVERIFY(!proxy.mapFromSource(QModelIndex()).isValid()); + QCOMPARE(proxy.mapFromSource(model->index(0, 0)), proxy.index(0, 0)); + QCOMPARE(proxy.mapFromSource(model->index(0, 1)), proxy.index(1, 0)); + QCOMPARE(proxy.mapFromSource(model->index(1, 0)), proxy.index(0, 1)); + const QModelIndex proxyParent = proxy.index(1, 0); + const QModelIndex sourceParent = model->index(0, 1); + QCOMPARE(proxy.mapToSource(proxy.index(0, 0, proxyParent)), model->index(0, 0, sourceParent)); + QCOMPARE(proxy.mapFromSource(model->index(1, 0, sourceParent)), proxy.index(0, 1, proxyParent)); + QCOMPARE(proxy.mapFromSource(model->index(0, 1, sourceParent)), proxy.index(1, 0, proxyParent)); + delete model; +} + +void tst_QTransposeProxyModel::basicTest_data() +{ + QTest::addColumn("model"); + QTest::newRow("List") << createListModel(this); + QTest::newRow("Table") << createTableModel(this); + QTest::newRow("Tree") << createTreeModel(this); +} + +void tst_QTransposeProxyModel::basicTest() +{ + QFETCH(QAbstractItemModel *, model); + QTransposeProxyModel proxy; + new QAbstractItemModelTester(&proxy, &proxy); + proxy.setSourceModel(model); + testTransposed(model, &proxy); + delete model; +} + +void tst_QTransposeProxyModel::sort() +{ + QStringList sequence; + sequence.reserve(100); + for (int i = 0; i < 100; ++i) + sequence.append(QStringLiteral("%1").arg(i, 3, 10, QLatin1Char('0'))); + std::shuffle(sequence.begin(), sequence.end(), std::mt19937(88)); + const QString firstItemBeforeSort = sequence.first(); + QStringListModel baseModel(sequence); + QTransposeProxyModel proxyModel; + new QAbstractItemModelTester(&proxyModel, &proxyModel); + proxyModel.setSourceModel(&baseModel); + QSignalSpy layoutChangedSpy(&proxyModel, &QAbstractItemModel::layoutChanged); + QVERIFY(layoutChangedSpy.isValid()); + QSignalSpy layoutAboutToBeChangedSpy(&proxyModel, &QAbstractItemModel::layoutAboutToBeChanged); + QVERIFY(layoutAboutToBeChangedSpy.isValid()); + QPersistentModelIndex firstIndexBeforeSort = proxyModel.index(0, 0); + baseModel.sort(0, Qt::AscendingOrder); + QCOMPARE(layoutChangedSpy.count(), 1); + QCOMPARE(layoutAboutToBeChangedSpy.count(), 1); + QCOMPARE(layoutChangedSpy.takeFirst().at(1).toInt(), int(QAbstractItemModel::HorizontalSortHint)); + QCOMPARE(firstIndexBeforeSort.data().toString(), firstItemBeforeSort); + for (int i = 0; i < 100; ++i) + QCOMPARE(proxyModel.index(0, i).data().toInt(), i); +} + +void tst_QTransposeProxyModel::removeColumnBase_data() +{ + QTest::addColumn("model"); + QTest::addColumn("parent"); + QTest::newRow("Table") << createTableModel(this) << QModelIndex(); + QTest::newRow("Tree_Root_Item") << createTreeModel(this) << QModelIndex(); + QAbstractItemModel *model = createTreeModel(this); + QTest::newRow("Tree_Child_Item") << model << model->index(0, 0); +} + +void tst_QTransposeProxyModel::removeColumnBase() +{ + QFETCH(QAbstractItemModel * const, model); + QFETCH(const QModelIndex, parent); + QTransposeProxyModel proxy; + QSignalSpy rowRemoveSpy(&proxy, &QAbstractItemModel::rowsRemoved); + QVERIFY(rowRemoveSpy.isValid()); + QSignalSpy rowAboutToBeRemoveSpy(&proxy, &QAbstractItemModel::rowsAboutToBeRemoved); + QVERIFY(rowAboutToBeRemoveSpy.isValid()); + new QAbstractItemModelTester(&proxy, &proxy); + proxy.setSourceModel(model); + const int oldRowCount = proxy.rowCount(proxy.mapFromSource(parent)); + const QVariant expectedNewVal = model->index(0, 2, parent).data(); + QVERIFY(model->removeColumn(1, parent)); + QCOMPARE(proxy.rowCount(proxy.mapFromSource(parent)), oldRowCount - 1); + QCOMPARE(proxy.index(1, 0, proxy.mapFromSource(parent)).data(), expectedNewVal); + QCOMPARE(rowRemoveSpy.count(), 1); + QCOMPARE(rowAboutToBeRemoveSpy.count(), 1); + for (const auto &spyArgs : {rowRemoveSpy.takeFirst(), + rowAboutToBeRemoveSpy.takeFirst()}) { + QCOMPARE(spyArgs.at(0).value(), proxy.mapFromSource(parent)); + QCOMPARE(spyArgs.at(1).toInt(), 1); + QCOMPARE(spyArgs.at(2).toInt(), 1); + } + delete model; +} + +void tst_QTransposeProxyModel::insertColumnBase_data() +{ + QTest::addColumn("model"); + QTest::addColumn("parent"); + QTest::newRow("Table") << createTableModel(this) << QModelIndex(); + QTest::newRow("Tree_Root_Item") << createTreeModel(this) << QModelIndex(); + QAbstractItemModel *model = createTreeModel(this); + QTest::newRow("Tree_Child_Item") << model << model->index(0, 0); +} + +void tst_QTransposeProxyModel::insertColumnBase() +{ + QFETCH(QAbstractItemModel * const, model); + QFETCH(const QModelIndex, parent); + QTransposeProxyModel proxy; + QSignalSpy rowInsertSpy(&proxy, &QAbstractItemModel::rowsInserted); + QVERIFY(rowInsertSpy.isValid()); + QSignalSpy rowAboutToBeInsertSpy(&proxy, &QAbstractItemModel::rowsAboutToBeInserted); + QVERIFY(rowAboutToBeInsertSpy.isValid()); + new QAbstractItemModelTester(&proxy, &proxy); + proxy.setSourceModel(model); + const int oldRowCount = proxy.rowCount(proxy.mapFromSource(parent)); + QVERIFY(model->insertColumn(1, parent)); + QCOMPARE(proxy.rowCount(proxy.mapFromSource(parent)), oldRowCount + 1); + QVERIFY(!proxy.index(1, 0, proxy.mapFromSource(parent)).data().isValid()); + QCOMPARE(rowInsertSpy.count(), 1); + QCOMPARE(rowAboutToBeInsertSpy.count(), 1); + for (const auto &spyArgs : {rowInsertSpy.takeFirst(), + rowAboutToBeInsertSpy.takeFirst()}) { + QCOMPARE(spyArgs.at(0).value(), proxy.mapFromSource(parent)); + QCOMPARE(spyArgs.at(1).toInt(), 1); + QCOMPARE(spyArgs.at(2).toInt(), 1); + } + delete model; +} + +void tst_QTransposeProxyModel::removeRowBase_data() +{ + QTest::addColumn("model"); + QTest::addColumn("parent"); + QTest::newRow("List") << createListModel(this) << QModelIndex(); + QTest::newRow("Table") << createTableModel(this) << QModelIndex(); + QTest::newRow("Tree_Root_Item") << createTreeModel(this) << QModelIndex(); + QAbstractItemModel *model = createTreeModel(this); + QTest::newRow("Tree_Child_Item") << model << model->index(0, 0); +} + +void tst_QTransposeProxyModel::removeRowBase() +{ + QFETCH(QAbstractItemModel * const, model); + QFETCH(const QModelIndex, parent); + QTransposeProxyModel proxy; + QSignalSpy columnsRemoveSpy(&proxy, &QAbstractItemModel::columnsRemoved); + QVERIFY(columnsRemoveSpy.isValid()); + QSignalSpy columnsAboutToBeRemoveSpy(&proxy, &QAbstractItemModel::columnsAboutToBeRemoved); + QVERIFY(columnsAboutToBeRemoveSpy.isValid()); + new QAbstractItemModelTester(&proxy, &proxy); + proxy.setSourceModel(model); + const int oldColCount = proxy.columnCount(proxy.mapFromSource(parent)); + const QVariant expectedNewVal = model->index(2, 0, parent).data(); + QVERIFY(model->removeRow(1, parent)); + QCOMPARE(proxy.columnCount(proxy.mapFromSource(parent)), oldColCount - 1); + QCOMPARE(proxy.index(0, 1, proxy.mapFromSource(parent)).data(), expectedNewVal); + QCOMPARE(columnsRemoveSpy.count(), 1); + QCOMPARE(columnsAboutToBeRemoveSpy.count(), 1); + for (const auto &spyArgs : {columnsRemoveSpy.takeFirst(), + columnsAboutToBeRemoveSpy.takeFirst()}) { + QCOMPARE(spyArgs.at(0).value(), proxy.mapFromSource(parent)); + QCOMPARE(spyArgs.at(1).toInt(), 1); + QCOMPARE(spyArgs.at(2).toInt(), 1); + } + delete model; +} + +void tst_QTransposeProxyModel::insertRowBase_data() +{ + QTest::addColumn("model"); + QTest::addColumn("parent"); + QTest::newRow("List") << createListModel(this) << QModelIndex(); + QTest::newRow("Table") << createTableModel(this) << QModelIndex(); + QTest::newRow("Tree_Root_Item") << createTreeModel(this) << QModelIndex(); + QAbstractItemModel *model = createTreeModel(this); + QTest::newRow("Tree_Child_Item") << model << model->index(0, 0); +} + +void tst_QTransposeProxyModel::insertRowBase() +{ + QFETCH(QAbstractItemModel * const, model); + QFETCH(const QModelIndex, parent); + QTransposeProxyModel proxy; + QSignalSpy columnsInsertSpy(&proxy, &QAbstractItemModel::columnsInserted); + QVERIFY(columnsInsertSpy.isValid()); + QSignalSpy columnsAboutToBeInsertSpy(&proxy, &QAbstractItemModel::columnsAboutToBeInserted); + QVERIFY(columnsAboutToBeInsertSpy.isValid()); + new QAbstractItemModelTester(&proxy, &proxy); + proxy.setSourceModel(model); + const int oldColCount = proxy.columnCount(proxy.mapFromSource(parent)); + QVERIFY(model->insertRow(1, parent)); + QCOMPARE(proxy.columnCount(proxy.mapFromSource(parent)), oldColCount + 1); + QVERIFY(proxy.index(0, 1, proxy.mapFromSource(parent)).data().isNull()); + QCOMPARE(columnsInsertSpy.count(), 1); + QCOMPARE(columnsAboutToBeInsertSpy.count(), 1); + for (const auto &spyArgs : {columnsInsertSpy.takeFirst(), + columnsAboutToBeInsertSpy.takeFirst()}) { + QCOMPARE(spyArgs.at(0).value(), proxy.mapFromSource(parent)); + QCOMPARE(spyArgs.at(1).toInt(), 1); + QCOMPARE(spyArgs.at(2).toInt(), 1); + } + delete model; +} + +void tst_QTransposeProxyModel::removeColumnProxy_data() +{ + QTest::addColumn("model"); + QTest::addColumn("rootItem"); + QTest::newRow("List") << createListModel(this) << true; + QTest::newRow("Table") << createTableModel(this) << true; + QTest::newRow("Tree_Root_Item") << createTreeModel(this) << true; + QTest::newRow("Tree_Child_Item") << createTreeModel(this) << false; +} + +void tst_QTransposeProxyModel::removeColumnProxy() +{ + QFETCH(QAbstractItemModel *, model); + QFETCH(bool, rootItem); + QTransposeProxyModel proxy; + new QAbstractItemModelTester(&proxy, &proxy); + QSignalSpy columnsRemoveSpy(&proxy, &QAbstractItemModel::columnsRemoved); + QVERIFY(columnsRemoveSpy.isValid()); + QSignalSpy columnsAboutToBeRemoveSpy(&proxy, &QAbstractItemModel::columnsAboutToBeRemoved); + QVERIFY(columnsAboutToBeRemoveSpy.isValid()); + QSignalSpy rowsRemoveSpy(model, &QAbstractItemModel::rowsRemoved); + QVERIFY(rowsRemoveSpy.isValid()); + QSignalSpy rowsAboutToBeRemoveSpy(model, &QAbstractItemModel::rowsAboutToBeRemoved); + QVERIFY(rowsAboutToBeRemoveSpy.isValid()); + proxy.setSourceModel(model); + const QModelIndex proxyParent = rootItem ? QModelIndex() : proxy.index(0, 1); + const QModelIndex sourceParent = proxy.mapToSource(proxyParent); + const int oldColCount = proxy.columnCount(proxyParent); + const int oldRowCount = model->rowCount(sourceParent); + const QVariant expectedNewVal = proxy.index(0, 2, proxyParent).data(); + QVERIFY(proxy.removeColumn(1, proxyParent)); + QCOMPARE(proxy.columnCount(proxyParent), oldColCount - 1); + QCOMPARE(model->rowCount(sourceParent), oldRowCount - 1); + QCOMPARE(proxy.index(0, 1, proxyParent).data(), expectedNewVal); + QCOMPARE(model->index(1, 0, sourceParent).data(), expectedNewVal); + QCOMPARE(columnsRemoveSpy.count(), 1); + QCOMPARE(columnsAboutToBeRemoveSpy.count(), 1); + QCOMPARE(rowsRemoveSpy.count(), 1); + QCOMPARE(rowsAboutToBeRemoveSpy.count(), 1); + for (const auto &spyArgs : {columnsRemoveSpy.takeFirst(), + columnsAboutToBeRemoveSpy.takeFirst()}) { + QCOMPARE(spyArgs.at(0).value(), proxyParent); + QCOMPARE(spyArgs.at(1).toInt(), 1); + QCOMPARE(spyArgs.at(2).toInt(), 1); + } + for (const auto &spyArgs : {rowsRemoveSpy.takeFirst(), + rowsAboutToBeRemoveSpy.takeFirst()}) { + QCOMPARE(spyArgs.at(0).value(), sourceParent); + QCOMPARE(spyArgs.at(1).toInt(), 1); + QCOMPARE(spyArgs.at(2).toInt(), 1); + } + delete model; +} + +void tst_QTransposeProxyModel::insertColumnProxy_data() +{ + QTest::addColumn("model"); + QTest::addColumn("rootItem"); + QTest::newRow("List") << createListModel(this) << true; + QTest::newRow("Table") << createTableModel(this) << true; + QTest::newRow("Tree_Root_Item") << createTreeModel(this) << true; + QTest::newRow("Tree_Child_Item") << createTreeModel(this) << false; +} + +void tst_QTransposeProxyModel::insertColumnProxy() +{ + QFETCH(QAbstractItemModel *, model); + QFETCH(bool, rootItem); + QTransposeProxyModel proxy; + new QAbstractItemModelTester(&proxy, &proxy); + QSignalSpy columnsInsertSpy(&proxy, &QAbstractItemModel::columnsInserted); + QVERIFY(columnsInsertSpy.isValid()); + QSignalSpy columnsAboutToBeInsertSpy(&proxy, &QAbstractItemModel::columnsAboutToBeInserted); + QVERIFY(columnsAboutToBeInsertSpy.isValid()); + QSignalSpy rowsInsertSpy(model, &QAbstractItemModel::rowsInserted); + QVERIFY(rowsInsertSpy.isValid()); + QSignalSpy rowsAboutToBeInsertSpy(model, &QAbstractItemModel::rowsAboutToBeInserted); + QVERIFY(rowsAboutToBeInsertSpy.isValid()); + proxy.setSourceModel(model); + const QModelIndex proxyParent = rootItem ? QModelIndex() : proxy.index(0, 1); + const QModelIndex sourceParent = proxy.mapToSource(proxyParent); + const int oldColCount = proxy.columnCount(proxyParent); + const int oldRowCount = model->rowCount(sourceParent); + QVERIFY(proxy.insertColumn(1, proxyParent)); + QCOMPARE(proxy.columnCount(proxyParent), oldColCount + 1); + QCOMPARE(model->rowCount(sourceParent), oldRowCount + 1); + QVERIFY(proxy.index(0, 1, proxyParent).data().isNull()); + QVERIFY(model->index(1, 0, sourceParent).data().isNull()); + QCOMPARE(columnsInsertSpy.count(), 1); + QCOMPARE(columnsAboutToBeInsertSpy.count(), 1); + QCOMPARE(rowsInsertSpy.count(), 1); + QCOMPARE(rowsAboutToBeInsertSpy.count(), 1); + for (const auto &spyArgs : {columnsInsertSpy.takeFirst(), + columnsAboutToBeInsertSpy.takeFirst()}) { + QCOMPARE(spyArgs.at(0).value(), proxyParent); + QCOMPARE(spyArgs.at(1).toInt(), 1); + QCOMPARE(spyArgs.at(2).toInt(), 1); + } + for (const auto &spyArgs : {rowsInsertSpy.takeFirst(), + rowsAboutToBeInsertSpy.takeFirst()}) { + QCOMPARE(spyArgs.at(0).value(), sourceParent); + QCOMPARE(spyArgs.at(1).toInt(), 1); + QCOMPARE(spyArgs.at(2).toInt(), 1); + } + delete model; +} + +void tst_QTransposeProxyModel::removeRowProxy_data() +{ + QTest::addColumn("model"); + QTest::addColumn("rootItem"); + QTest::newRow("Table") << createTableModel(this) << true; + QTest::newRow("Tree_Root_Item") << createTreeModel(this) << true; + QTest::newRow("Tree_Child_Item") << createTreeModel(this) << false; +} + +void tst_QTransposeProxyModel::removeRowProxy() +{ + QFETCH(QAbstractItemModel *, model); + QFETCH(bool, rootItem); + QTransposeProxyModel proxy; + new QAbstractItemModelTester(&proxy, &proxy); + QSignalSpy rowsRemoveSpy(&proxy, &QAbstractItemModel::rowsRemoved); + QVERIFY(rowsRemoveSpy.isValid()); + QSignalSpy rowsAboutToBeRemoveSpy(&proxy, &QAbstractItemModel::rowsAboutToBeRemoved); + QVERIFY(rowsAboutToBeRemoveSpy.isValid()); + QSignalSpy columnsRemoveSpy(model, &QAbstractItemModel::columnsRemoved); + QVERIFY(columnsRemoveSpy.isValid()); + QSignalSpy columnsAboutToBeRemoveSpy(model, &QAbstractItemModel::columnsAboutToBeRemoved); + QVERIFY(columnsAboutToBeRemoveSpy.isValid()); + proxy.setSourceModel(model); + const QModelIndex proxyParent = rootItem ? QModelIndex() : proxy.index(0, 1); + const QModelIndex sourceParent = proxy.mapToSource(proxyParent); + const int oldRowCount = proxy.rowCount(proxyParent); + const int oldColCount = model->columnCount(sourceParent); + const QVariant expectedNewVal = proxy.index(2, 0, proxyParent).data(); + QVERIFY(proxy.removeRow(1, proxyParent)); + QCOMPARE(proxy.rowCount(proxyParent), oldRowCount - 1); + QCOMPARE(model->columnCount(sourceParent), oldColCount - 1); + QCOMPARE(proxy.index(1, 0, proxyParent).data(), expectedNewVal); + QCOMPARE(model->index(0, 1, sourceParent).data(), expectedNewVal); + QCOMPARE(columnsRemoveSpy.count(), 1); + QCOMPARE(columnsAboutToBeRemoveSpy.count(), 1); + QCOMPARE(rowsRemoveSpy.count(), 1); + QCOMPARE(rowsAboutToBeRemoveSpy.count(), 1); + for (const auto &spyArgs : {columnsRemoveSpy.takeFirst(), + columnsAboutToBeRemoveSpy.takeFirst()}) { + QCOMPARE(spyArgs.at(0).value(), sourceParent); + QCOMPARE(spyArgs.at(1).toInt(), 1); + QCOMPARE(spyArgs.at(2).toInt(), 1); + } + for (const auto &spyArgs : {rowsRemoveSpy.takeFirst(), + rowsAboutToBeRemoveSpy.takeFirst()}) { + QCOMPARE(spyArgs.at(0).value(), proxyParent); + QCOMPARE(spyArgs.at(1).toInt(), 1); + QCOMPARE(spyArgs.at(2).toInt(), 1); + } + delete model; +} + +void tst_QTransposeProxyModel::insertRowProxy_data() +{ + QTest::addColumn("model"); + QTest::addColumn("rootItem"); + QTest::newRow("Table") << createTableModel(this) << true; + QTest::newRow("Tree_Root_Item") << createTreeModel(this) << true; + QTest::newRow("Tree_Child_Item") << createTreeModel(this) << false; +} + +void tst_QTransposeProxyModel::insertRowProxy() +{ + QFETCH(QAbstractItemModel *, model); + QFETCH(bool, rootItem); + QTransposeProxyModel proxy; + new QAbstractItemModelTester(&proxy, &proxy); + QSignalSpy rowsInsertSpy(&proxy, &QAbstractItemModel::rowsInserted); + QVERIFY(rowsInsertSpy.isValid()); + QSignalSpy rowsAboutToBeInsertSpy(&proxy, &QAbstractItemModel::rowsAboutToBeInserted); + QVERIFY(rowsAboutToBeInsertSpy.isValid()); + QSignalSpy columnsInsertSpy(model, &QAbstractItemModel::columnsInserted); + QVERIFY(columnsInsertSpy.isValid()); + QSignalSpy columnsAboutToBeInsertSpy(model, &QAbstractItemModel::columnsAboutToBeInserted); + QVERIFY(columnsAboutToBeInsertSpy.isValid()); + proxy.setSourceModel(model); + const QModelIndex proxyParent = rootItem ? QModelIndex() : proxy.index(0, 1); + const QModelIndex sourceParent = proxy.mapToSource(proxyParent); + const int oldRowCount = proxy.rowCount(proxyParent); + const int oldColCount = model->columnCount(sourceParent); + QVERIFY(proxy.insertRow(1, proxyParent)); + QCOMPARE(proxy.rowCount(proxyParent), oldRowCount + 1); + QCOMPARE(model->columnCount(sourceParent), oldColCount + 1); + QVERIFY(proxy.index(1, 0, proxyParent).data().isNull()); + QVERIFY(model->index(0, 1, sourceParent).data().isNull()); + QCOMPARE(columnsInsertSpy.count(), 1); + QCOMPARE(columnsAboutToBeInsertSpy.count(), 1); + QCOMPARE(rowsInsertSpy.count(), 1); + QCOMPARE(rowsAboutToBeInsertSpy.count(), 1); + for (const auto &spyArgs : {columnsInsertSpy.takeFirst(), + columnsAboutToBeInsertSpy.takeFirst()}) { + QCOMPARE(spyArgs.at(0).value(), sourceParent); + QCOMPARE(spyArgs.at(1).toInt(), 1); + QCOMPARE(spyArgs.at(2).toInt(), 1); + } + for (const auto &spyArgs : {rowsInsertSpy.takeFirst(), + rowsAboutToBeInsertSpy.takeFirst()}) { + QCOMPARE(spyArgs.at(0).value(), proxyParent); + QCOMPARE(spyArgs.at(1).toInt(), 1); + QCOMPARE(spyArgs.at(2).toInt(), 1); + } + delete model; +} + +void tst_QTransposeProxyModel::headerData() +{ + QStandardItemModel model; + model.insertRows(0, 3); + model.insertColumns(0, 5); + for (int i = 0; i < model.rowCount(); ++i) + model.setHeaderData(i, Qt::Horizontal, QChar('A' + i)); + for (int i = 1; i <= model.columnCount(); ++i) + model.setHeaderData(i, Qt::Vertical, i); + QTransposeProxyModel proxy; + new QAbstractItemModelTester(&proxy, &proxy); + proxy.setSourceModel(&model); + for (int i = 0; i < model.rowCount(); ++i) + QCOMPARE(model.headerData(i, Qt::Horizontal), proxy.headerData(i, Qt::Vertical)); + for (int i = 0; i < model.columnCount(); ++i) + QCOMPARE(model.headerData(i, Qt::Vertical), proxy.headerData(i, Qt::Horizontal)); +} + +void tst_QTransposeProxyModel::setHeaderData() +{ + QStandardItemModel model; + model.insertRows(0, 3); + model.insertColumns(0, 5); + for (int i = 0; i < model.rowCount(); ++i) + model.setHeaderData(i, Qt::Horizontal, QChar('A' + i)); + for (int i = 1; i <= model.columnCount(); ++i) + model.setHeaderData(i, Qt::Vertical, i); + QTransposeProxyModel proxy; + new QAbstractItemModelTester(&proxy, &proxy); + proxy.setSourceModel(&model); + QVERIFY(proxy.setHeaderData(1, Qt::Horizontal, 99)); + QCOMPARE(model.headerData(1, Qt::Vertical).toInt(), 99); + QVERIFY(proxy.setHeaderData(1, Qt::Vertical, QChar('Z'))); + QCOMPARE(model.headerData(1, Qt::Horizontal).toChar(), QChar('Z')); +} + +void tst_QTransposeProxyModel::span() +{ + class SpanModel : public QStandardItemModel + { + Q_DISABLE_COPY(SpanModel) + public: + SpanModel(int rows, int columns, QObject *parent = nullptr) + : QStandardItemModel(rows, columns, parent) + {} + QSize span(const QModelIndex &index) const override + { + Q_UNUSED(index) + return QSize(2, 1); + } + }; + SpanModel model(3, 5); + QTransposeProxyModel proxy; + new QAbstractItemModelTester(&proxy, &proxy); + proxy.setSourceModel(&model); + QCOMPARE(proxy.span(proxy.index(0, 0)), QSize(1, 2)); +} + +void tst_QTransposeProxyModel::itemData() +{ + QAbstractItemModel *model = createTreeModel(this); + QTransposeProxyModel proxy; + new QAbstractItemModelTester(&proxy, &proxy); + proxy.setSourceModel(model); + QMap itmData = proxy.itemData(proxy.index(0, 1)); + QCOMPARE(itmData.value(Qt::DisplayRole).toString(), QStringLiteral("1,0")); + QCOMPARE(itmData.value(Qt::UserRole).toInt(), 1); + QCOMPARE(itmData.value(Qt::UserRole + 1).toInt(), 0); + itmData = proxy.itemData(proxy.index(1, 2, proxy.index(0, 1))); + QCOMPARE(itmData.value(Qt::DisplayRole).toString(), QStringLiteral("1,0,2,1")); + QCOMPARE(itmData.value(Qt::UserRole).toInt(), 1); + QCOMPARE(itmData.value(Qt::UserRole + 1).toInt(), 0); + QCOMPARE(itmData.value(Qt::UserRole + 2).toInt(), 2); + QCOMPARE(itmData.value(Qt::UserRole + 3).toInt(), 1); + QVERIFY(proxy.itemData(QModelIndex()).isEmpty()); + delete model; +} + +void tst_QTransposeProxyModel::setItemData() +{ + QAbstractItemModel *model = createTreeModel(this); + QTransposeProxyModel proxy; + new QAbstractItemModelTester(&proxy, &proxy); + proxy.setSourceModel(model); + QSignalSpy sourceDataChangeSpy(model, &QAbstractItemModel::dataChanged); + QVERIFY(sourceDataChangeSpy.isValid()); + QSignalSpy proxyDataChangeSpy(&proxy, &QAbstractItemModel::dataChanged); + QVERIFY(proxyDataChangeSpy.isValid()); + const QMap itmData = { + std::make_pair(Qt::DisplayRole, QStringLiteral("Test")), + std::make_pair(Qt::UserRole, 88), + std::make_pair(Qt::UserRole + 1, 99), + }; + QModelIndex idx = proxy.index(0, 1); + QVERIFY(proxy.setItemData(idx, itmData)); + QCOMPARE(idx.data(Qt::DisplayRole).toString(), QStringLiteral("Test")); + QCOMPARE(idx.data(Qt::UserRole).toInt(), 88); + QCOMPARE(idx.data(Qt::UserRole + 1).toInt(), 99); + QCOMPARE(sourceDataChangeSpy.size(), 1); + QCOMPARE(proxyDataChangeSpy.size(), 1); + auto signalData = proxyDataChangeSpy.takeFirst(); + QCOMPARE(signalData.at(0).value(), idx); + QCOMPARE(signalData.at(1).value(), idx); + const QVector expectedRoles{Qt::DisplayRole, Qt::UserRole, Qt::EditRole, Qt::UserRole + 1}; + QVector receivedRoles = signalData.at(2).value >(); + QCOMPARE(receivedRoles.size(), expectedRoles.size()); + for (int role : expectedRoles) + QVERIFY(receivedRoles.contains(role)); + signalData = sourceDataChangeSpy.takeFirst(); + QCOMPARE(signalData.at(0).value(), proxy.mapToSource(idx)); + QCOMPARE(signalData.at(1).value(), proxy.mapToSource(idx)); + receivedRoles = signalData.at(2).value >(); + QCOMPARE(receivedRoles.size(), expectedRoles.size()); + for (int role : expectedRoles) + QVERIFY(receivedRoles.contains(role)); + idx = proxy.index(1, 2, proxy.index(0, 1)); + QVERIFY(proxy.setItemData(idx, itmData)); + QCOMPARE(idx.data(Qt::DisplayRole).toString(), QStringLiteral("Test")); + QCOMPARE(idx.data(Qt::UserRole).toInt(), 88); + QCOMPARE(idx.data(Qt::UserRole + 1).toInt(), 99); + QCOMPARE(idx.data(Qt::UserRole + 2).toInt(), 2); + QCOMPARE(idx.data(Qt::UserRole + 3).toInt(), 1); + QCOMPARE(sourceDataChangeSpy.size(), 1); + QCOMPARE(proxyDataChangeSpy.size(), 1); + signalData = proxyDataChangeSpy.takeFirst(); + QCOMPARE(signalData.at(0).value(), idx); + QCOMPARE(signalData.at(1).value(), idx); + receivedRoles = signalData.at(2).value >(); + QCOMPARE(receivedRoles.size(), expectedRoles.size()); + for (int role : expectedRoles) + QVERIFY(receivedRoles.contains(role)); + signalData = sourceDataChangeSpy.takeFirst(); + QCOMPARE(signalData.at(0).value(), proxy.mapToSource(idx)); + QCOMPARE(signalData.at(1).value(), proxy.mapToSource(idx)); + receivedRoles = signalData.at(2).value >(); + QCOMPARE(receivedRoles.size(), expectedRoles.size()); + for (int role : expectedRoles) + QVERIFY(receivedRoles.contains(role)); + QVERIFY(!proxy.setItemData(QModelIndex(), itmData)); + delete model; +} + +void tst_QTransposeProxyModel::moveRowsBase() +{ + QStringListModel model{QStringList{"A", "B", "C", "D"}}; + QTransposeProxyModel proxy; + QSignalSpy columnsMoveSpy(&proxy, &QAbstractItemModel::columnsMoved); + QVERIFY(columnsMoveSpy.isValid()); + QSignalSpy columnsAboutToBeMoveSpy(&proxy, &QAbstractItemModel::columnsAboutToBeMoved); + QVERIFY(columnsAboutToBeMoveSpy.isValid()); + new QAbstractItemModelTester(&proxy, &proxy); + proxy.setSourceModel(&model); + const QStringList expectedNewVal = {"B", "A", "C", "D"}; + QVERIFY(model.moveRows(QModelIndex(), 0, 1, QModelIndex(), 2)); + for (int i = 0; i < expectedNewVal.size(); ++i) + QCOMPARE(proxy.index(0, i).data(), expectedNewVal.at(i)); + QCOMPARE(columnsMoveSpy.count(), 1); + QCOMPARE(columnsAboutToBeMoveSpy.count(), 1); + for (const auto &spyArgs : {columnsMoveSpy.takeFirst(), + columnsAboutToBeMoveSpy.takeFirst()}) { + QVERIFY(!spyArgs.at(0).value().isValid()); + QCOMPARE(spyArgs.at(1).toInt(), 0); + QCOMPARE(spyArgs.at(2).toInt(), 0); + QVERIFY(!spyArgs.at(3).value().isValid()); + QCOMPARE(spyArgs.at(4).toInt(), 2); + } +} + +void tst_QTransposeProxyModel::moveColumnsProxy() +{ + QStringListModel model{QStringList{"A", "B", "C", "D"}}; + QTransposeProxyModel proxy; + new QAbstractItemModelTester(&proxy, &proxy); + QSignalSpy columnsMoveSpy(&proxy, &QAbstractItemModel::columnsMoved); + QVERIFY(columnsMoveSpy.isValid()); + QSignalSpy columnsAboutToBeMoveSpy(&proxy, &QAbstractItemModel::columnsAboutToBeMoved); + QVERIFY(columnsAboutToBeMoveSpy.isValid()); + QSignalSpy rowsMoveSpy(&model, &QAbstractItemModel::rowsMoved); + QVERIFY(rowsMoveSpy.isValid()); + QSignalSpy rowsAboutToBeMoveSpy(&model, &QAbstractItemModel::rowsAboutToBeMoved); + QVERIFY(rowsAboutToBeMoveSpy.isValid()); + proxy.setSourceModel(&model); + const QStringList expectedNewVal = {"B", "A", "C", "D"}; + QVERIFY(proxy.moveColumns(QModelIndex(), 0, 1, QModelIndex(), 2)); + for (int i = 0; i < expectedNewVal.size(); ++i) + QCOMPARE(proxy.index(0, i).data(), expectedNewVal.at(i)); + for (int i = 0; i < expectedNewVal.size(); ++i) + QCOMPARE(model.index(i, 0).data(), expectedNewVal.at(i)); + QCOMPARE(columnsMoveSpy.count(), 1); + QCOMPARE(columnsAboutToBeMoveSpy.count(), 1); + QCOMPARE(rowsMoveSpy.count(), 1); + QCOMPARE(rowsAboutToBeMoveSpy.count(), 1); + for (const auto &spyArgs : {columnsMoveSpy.takeFirst(), + columnsAboutToBeMoveSpy.takeFirst(), + rowsMoveSpy.takeFirst(),rowsAboutToBeMoveSpy.takeFirst()}) { + QVERIFY(!spyArgs.at(0).value().isValid()); + QCOMPARE(spyArgs.at(1).toInt(), 0); + QCOMPARE(spyArgs.at(2).toInt(), 0); + QVERIFY(!spyArgs.at(3).value().isValid()); + } +} + +void tst_QTransposeProxyModel::setData_data() +{ + QTest::addColumn("model"); + QTest::addColumn("rootItem"); + QTest::addColumn("viaProxy"); + QTest::newRow("List_via_Base") << createListModel(this) << true << false; + QTest::newRow("Table_via_Base") << createTableModel(this) << true << false; + QTest::newRow("Tree_via_Base_Root_Item") << createTreeModel(this) << true << false; + QTest::newRow("Tree_via_Base_Child_Item") << createTreeModel(this) << false << false; + QTest::newRow("List_via_Proxy") << createListModel(this) << true << true; + QTest::newRow("Table_via_Proxy") << createTableModel(this) << true << true; + QTest::newRow("Tree_via_Proxy_Root_Item") << createTreeModel(this) << true << true; + QTest::newRow("Tree_via_Proxy_Child_Item") << createTreeModel(this) << false << true; +} + +void tst_QTransposeProxyModel::setData() +{ + QFETCH(QAbstractItemModel *, model); + QFETCH(bool, rootItem); + QFETCH(bool, viaProxy); + QTransposeProxyModel proxy; + new QAbstractItemModelTester(&proxy, &proxy); + proxy.setSourceModel(model); + QSignalSpy sourceDataChangeSpy(model, &QAbstractItemModel::dataChanged); + QVERIFY(sourceDataChangeSpy.isValid()); + QSignalSpy proxyDataChangeSpy(&proxy, &QAbstractItemModel::dataChanged); + QVERIFY(proxyDataChangeSpy.isValid()); + const QString testData = QStringLiteral("TestingSetData"); + if (viaProxy) { + const QModelIndex parIdx = rootItem ? QModelIndex() : proxy.index(0, 1); + QVERIFY(proxy.setData(proxy.index(0, 1, parIdx), testData)); + QCOMPARE(model->index(1, 0, proxy.mapToSource(parIdx)).data().toString(), testData); + } else { + const QModelIndex parIdx = rootItem ? QModelIndex() : model->index(1, 0); + QVERIFY(model->setData(model->index(1, 0, parIdx), testData)); + QCOMPARE(proxy.index(0, 1, proxy.mapFromSource(parIdx)).data().toString(), testData); + } + QCOMPARE(sourceDataChangeSpy.size(), 1); + QCOMPARE(proxyDataChangeSpy.size(), 1); + delete model; +} + +QTEST_GUILESS_MAIN(tst_QTransposeProxyModel) + +#include "tst_qtransposeproxymodel.moc" From fe999230ec4385c181f7824a0eaeb3b5c1d020c4 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 2 Nov 2018 14:04:06 -0700 Subject: [PATCH 0191/1650] Remove unnecessary Q_STATIC_TEMPLATE_FUNCTION macro It expands to the same thing in all three branches. Change-Id: I343f2beed55440a7ac0bfffd15636a8bfd8fd21c Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qcompositionfunctions.cpp | 88 +++++++++++----------- src/gui/painting/qdrawhelper.cpp | 2 +- src/gui/painting/qdrawhelper_p.h | 7 +- src/gui/painting/qmemrotate.cpp | 14 ++-- 4 files changed, 54 insertions(+), 57 deletions(-) diff --git a/src/gui/painting/qcompositionfunctions.cpp b/src/gui/painting/qcompositionfunctions.cpp index 027bf23115..5c1afe8425 100644 --- a/src/gui/painting/qcompositionfunctions.cpp +++ b/src/gui/painting/qcompositionfunctions.cpp @@ -1107,7 +1107,7 @@ static inline uint multiply_op_rgb64(uint dst, uint src, uint da, uint sa) } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Multiply_impl(uint *dest, int length, uint color, const T &coverage) +static inline void comp_func_solid_Multiply_impl(uint *dest, int length, uint color, const T &coverage) { int sa = qAlpha(color); int sr = qRed(color); @@ -1130,7 +1130,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Multiply_impl(uint *dest, } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Multiply_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) +static inline void comp_func_solid_Multiply_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) { uint sa = color.alpha(); uint sr = color.red(); @@ -1169,7 +1169,7 @@ void QT_FASTCALL comp_func_solid_Multiply_rgb64(QRgba64 *dest, int length, QRgba } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Multiply_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) +static inline void comp_func_Multiply_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) { for (int i = 0; i < length; ++i) { uint d = dest[i]; @@ -1190,7 +1190,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Multiply_impl(uint *Q_DECL_REST } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Multiply_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) +static inline void comp_func_Multiply_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) { for (int i = 0; i < length; ++i) { QRgba64 d = dest[i]; @@ -1231,7 +1231,7 @@ void QT_FASTCALL comp_func_Multiply_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const Q = Sca + Dca - Sca.Dca */ template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Screen_impl(uint *dest, int length, uint color, const T &coverage) +static inline void comp_func_solid_Screen_impl(uint *dest, int length, uint color, const T &coverage) { int sa = qAlpha(color); int sr = qRed(color); @@ -1254,7 +1254,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Screen_impl(uint *dest, i } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Screen_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) +static inline void comp_func_solid_Screen_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) { uint sa = color.alpha(); uint sr = color.red(); @@ -1293,7 +1293,7 @@ void QT_FASTCALL comp_func_solid_Screen_rgb64(QRgba64 *dest, int length, QRgba64 } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Screen_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) +static inline void comp_func_Screen_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) { for (int i = 0; i < length; ++i) { uint d = dest[i]; @@ -1314,7 +1314,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Screen_impl(uint *Q_DECL_RESTRI } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Screen_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) +static inline void comp_func_Screen_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) { for (int i = 0; i < length; ++i) { QRgba64 d = dest[i]; @@ -1375,7 +1375,7 @@ static inline uint overlay_op_rgb64(uint dst, uint src, uint da, uint sa) } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Overlay_impl(uint *dest, int length, uint color, const T &coverage) +static inline void comp_func_solid_Overlay_impl(uint *dest, int length, uint color, const T &coverage) { int sa = qAlpha(color); int sr = qRed(color); @@ -1398,7 +1398,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Overlay_impl(uint *dest, } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Overlay_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) +static inline void comp_func_solid_Overlay_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) { uint sa = color.alpha(); uint sr = color.red(); @@ -1437,7 +1437,7 @@ void QT_FASTCALL comp_func_solid_Overlay_rgb64(QRgba64 *dest, int length, QRgba6 } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Overlay_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) +static inline void comp_func_Overlay_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) { for (int i = 0; i < length; ++i) { uint d = dest[i]; @@ -1458,7 +1458,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Overlay_impl(uint *Q_DECL_RESTR } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Overlay_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) +static inline void comp_func_Overlay_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) { for (int i = 0; i < length; ++i) { QRgba64 d = dest[i]; @@ -1509,7 +1509,7 @@ static inline uint darken_op_rgb64(uint dst, uint src, uint da, uint sa) } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Darken_impl(uint *dest, int length, uint color, const T &coverage) +static inline void comp_func_solid_Darken_impl(uint *dest, int length, uint color, const T &coverage) { int sa = qAlpha(color); int sr = qRed(color); @@ -1532,7 +1532,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Darken_impl(uint *dest, i } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Darken_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) +static inline void comp_func_solid_Darken_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) { uint sa = color.alpha(); uint sr = color.red(); @@ -1571,7 +1571,7 @@ void QT_FASTCALL comp_func_solid_Darken_rgb64(QRgba64 *dest, int length, QRgba64 } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Darken_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) +static inline void comp_func_Darken_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) { for (int i = 0; i < length; ++i) { uint d = dest[i]; @@ -1592,7 +1592,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Darken_impl(uint *Q_DECL_RESTRI } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Darken_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) +static inline void comp_func_Darken_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) { for (int i = 0; i < length; ++i) { QRgba64 d = dest[i]; @@ -1643,7 +1643,7 @@ static inline uint lighten_op_rgb64(uint dst, uint src, uint da, uint sa) } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Lighten_impl(uint *dest, int length, uint color, const T &coverage) +static inline void comp_func_solid_Lighten_impl(uint *dest, int length, uint color, const T &coverage) { int sa = qAlpha(color); int sr = qRed(color); @@ -1666,7 +1666,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Lighten_impl(uint *dest, } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Lighten_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) +static inline void comp_func_solid_Lighten_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) { uint sa = color.alpha(); uint sr = color.red(); @@ -1705,7 +1705,7 @@ void QT_FASTCALL comp_func_solid_Lighten_rgb64(QRgba64 *dest, int length, QRgba6 } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Lighten_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) +static inline void comp_func_Lighten_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) { for (int i = 0; i < length; ++i) { uint d = dest[i]; @@ -1726,7 +1726,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Lighten_impl(uint *Q_DECL_RESTR } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Lighten_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) +static inline void comp_func_Lighten_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) { for (int i = 0; i < length; ++i) { QRgba64 d = dest[i]; @@ -1795,7 +1795,7 @@ static inline uint color_dodge_op_rgb64(qint64 dst, qint64 src, qint64 da, qint6 } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_ColorDodge_impl(uint *dest, int length, uint color, const T &coverage) +static inline void comp_func_solid_ColorDodge_impl(uint *dest, int length, uint color, const T &coverage) { int sa = qAlpha(color); int sr = qRed(color); @@ -1818,7 +1818,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_ColorDodge_impl(uint *des } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_ColorDodge_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) +static inline void comp_func_solid_ColorDodge_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) { uint sa = color.alpha(); uint sr = color.red(); @@ -1857,7 +1857,7 @@ void QT_FASTCALL comp_func_solid_ColorDodge_rgb64(QRgba64 *dest, int length, QRg } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorDodge_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) +static inline void comp_func_ColorDodge_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) { for (int i = 0; i < length; ++i) { uint d = dest[i]; @@ -1878,7 +1878,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorDodge_impl(uint *Q_DECL_RE } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorDodge_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) +static inline void comp_func_ColorDodge_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) { for (int i = 0; i < length; ++i) { QRgba64 d = dest[i]; @@ -1947,7 +1947,7 @@ static inline uint color_burn_op_rgb64(qint64 dst, qint64 src, qint64 da, qint64 } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_ColorBurn_impl(uint *dest, int length, uint color, const T &coverage) +static inline void comp_func_solid_ColorBurn_impl(uint *dest, int length, uint color, const T &coverage) { int sa = qAlpha(color); int sr = qRed(color); @@ -1970,7 +1970,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_ColorBurn_impl(uint *dest } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_ColorBurn_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) +static inline void comp_func_solid_ColorBurn_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) { uint sa = color.alpha(); uint sr = color.red(); @@ -2009,7 +2009,7 @@ void QT_FASTCALL comp_func_solid_ColorBurn_rgb64(QRgba64 *dest, int length, QRgb } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorBurn_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) +static inline void comp_func_ColorBurn_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) { for (int i = 0; i < length; ++i) { uint d = dest[i]; @@ -2030,7 +2030,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorBurn_impl(uint *Q_DECL_RES } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_ColorBurn_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) +static inline void comp_func_ColorBurn_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) { for (int i = 0; i < length; ++i) { QRgba64 d = dest[i]; @@ -2093,7 +2093,7 @@ static inline uint hardlight_op_rgb64(uint dst, uint src, uint da, uint sa) } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_HardLight_impl(uint *dest, int length, uint color, const T &coverage) +static inline void comp_func_solid_HardLight_impl(uint *dest, int length, uint color, const T &coverage) { int sa = qAlpha(color); int sr = qRed(color); @@ -2116,7 +2116,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_HardLight_impl(uint *dest } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_HardLight_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) +static inline void comp_func_solid_HardLight_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) { uint sa = color.alpha(); uint sr = color.red(); @@ -2155,7 +2155,7 @@ void QT_FASTCALL comp_func_solid_HardLight_rgb64(QRgba64 *dest, int length, QRgb } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_HardLight_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) +static inline void comp_func_HardLight_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) { for (int i = 0; i < length; ++i) { uint d = dest[i]; @@ -2176,7 +2176,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_HardLight_impl(uint *Q_DECL_RES } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_HardLight_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) +static inline void comp_func_HardLight_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) { for (int i = 0; i < length; ++i) { QRgba64 d = dest[i]; @@ -2252,7 +2252,7 @@ static inline uint soft_light_op_rgb64(qint64 dst, qint64 src, qint64 da, qint64 } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_SoftLight_impl(uint *dest, int length, uint color, const T &coverage) +static inline void comp_func_solid_SoftLight_impl(uint *dest, int length, uint color, const T &coverage) { int sa = qAlpha(color); int sr = qRed(color); @@ -2275,7 +2275,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_SoftLight_impl(uint *dest } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_SoftLight_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) +static inline void comp_func_solid_SoftLight_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) { uint sa = color.alpha(); uint sr = color.red(); @@ -2314,7 +2314,7 @@ void QT_FASTCALL comp_func_solid_SoftLight_rgb64(QRgba64 *dest, int length, QRgb } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_SoftLight_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) +static inline void comp_func_SoftLight_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) { for (int i = 0; i < length; ++i) { uint d = dest[i]; @@ -2335,7 +2335,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_SoftLight_impl(uint *Q_DECL_RES } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_SoftLight_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) +static inline void comp_func_SoftLight_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) { for (int i = 0; i < length; ++i) { QRgba64 d = dest[i]; @@ -2386,7 +2386,7 @@ static inline uint difference_op_rgb64(qint64 dst, qint64 src, qint64 da, qint64 } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Difference_impl(uint *dest, int length, uint color, const T &coverage) +static inline void comp_func_solid_Difference_impl(uint *dest, int length, uint color, const T &coverage) { int sa = qAlpha(color); int sr = qRed(color); @@ -2409,7 +2409,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Difference_impl(uint *des } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_solid_Difference_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) +static inline void comp_func_solid_Difference_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) { uint sa = color.alpha(); uint sr = color.red(); @@ -2448,7 +2448,7 @@ void QT_FASTCALL comp_func_solid_Difference_rgb64(QRgba64 *dest, int length, QRg } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Difference_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) +static inline void comp_func_Difference_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) { for (int i = 0; i < length; ++i) { uint d = dest[i]; @@ -2469,7 +2469,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Difference_impl(uint *Q_DECL_RE } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Difference_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) +static inline void comp_func_Difference_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) { for (int i = 0; i < length; ++i) { QRgba64 d = dest[i]; @@ -2509,7 +2509,7 @@ void QT_FASTCALL comp_func_Difference_rgb64(QRgba64 *Q_DECL_RESTRICT dest, const Dca' = (Sca.Da + Dca.Sa - 2.Sca.Dca) + Sca.(1 - Da) + Dca.(1 - Sa) */ template -Q_STATIC_TEMPLATE_FUNCTION inline void QT_FASTCALL comp_func_solid_Exclusion_impl(uint *dest, int length, uint color, const T &coverage) +static inline void QT_FASTCALL comp_func_solid_Exclusion_impl(uint *dest, int length, uint color, const T &coverage) { int sa = qAlpha(color); int sr = qRed(color); @@ -2532,7 +2532,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void QT_FASTCALL comp_func_solid_Exclusion_imp } template -Q_STATIC_TEMPLATE_FUNCTION inline void QT_FASTCALL comp_func_solid_Exclusion_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) +static inline void QT_FASTCALL comp_func_solid_Exclusion_impl(QRgba64 *dest, int length, QRgba64 color, const T &coverage) { uint sa = color.alpha(); uint sr = color.red(); @@ -2572,7 +2572,7 @@ void QT_FASTCALL comp_func_solid_Exclusion_rgb64(QRgba64 *dest, int length, QRgb } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Exclusion_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) +static inline void comp_func_Exclusion_impl(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, const T &coverage) { for (int i = 0; i < length; ++i) { uint d = dest[i]; @@ -2593,7 +2593,7 @@ Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Exclusion_impl(uint *Q_DECL_RES } template -Q_STATIC_TEMPLATE_FUNCTION inline void comp_func_Exclusion_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) +static inline void comp_func_Exclusion_impl(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, const T &coverage) { for (int i = 0; i < length; ++i) { QRgba64 d = dest[i]; diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index bbeb9fd9ea..c240618199 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -5228,7 +5228,7 @@ void qBlendTexture(int count, const QSpan *spans, void *userData) proc(count, spans, userData); } -template Q_STATIC_TEMPLATE_FUNCTION +template static inline void qt_bitmapblit_template(QRasterBuffer *rasterBuffer, int x, int y, DST color, const uchar *map, diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index fb08261205..b1d4b3a9b0 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -69,13 +69,10 @@ QT_BEGIN_NAMESPACE #if defined(Q_CC_GNU) -# define Q_STATIC_TEMPLATE_FUNCTION static # define Q_DECL_RESTRICT __restrict__ #elif defined(Q_CC_MSVC) -# define Q_STATIC_TEMPLATE_FUNCTION static # define Q_DECL_RESTRICT __restrict #else -# define Q_STATIC_TEMPLATE_FUNCTION static # define Q_DECL_RESTRICT #endif @@ -887,7 +884,7 @@ inline quint24::operator uint() const return data[2] | (data[1] << 8) | (data[0] << 16); } -template Q_STATIC_TEMPLATE_FUNCTION +template static void qt_memfill(T *dest, T value, int count); template<> inline void qt_memfill(quint64 *dest, quint64 color, int count) @@ -931,7 +928,7 @@ inline void qt_memfill(T *dest, T value, int count) } } -template Q_STATIC_TEMPLATE_FUNCTION +template static inline void qt_rectfill(T *dest, T value, int x, int y, int width, int height, qsizetype stride) { diff --git a/src/gui/painting/qmemrotate.cpp b/src/gui/painting/qmemrotate.cpp index 43aeff3268..9cb787fb2c 100644 --- a/src/gui/painting/qmemrotate.cpp +++ b/src/gui/painting/qmemrotate.cpp @@ -44,7 +44,7 @@ QT_BEGIN_NAMESPACE static const int tileSize = 32; template -Q_STATIC_TEMPLATE_FUNCTION +static inline void qt_memrotate90_tiled(const T *src, int w, int h, int sstride, T *dest, int dstride) { sstride /= sizeof(T); @@ -103,7 +103,7 @@ inline void qt_memrotate90_tiled(const T *src, int w, int h, int sstride, T *des } template -Q_STATIC_TEMPLATE_FUNCTION +static inline void qt_memrotate90_tiled_unpacked(const T *src, int w, int h, int sstride, T *dest, int dstride) { @@ -131,7 +131,7 @@ inline void qt_memrotate90_tiled_unpacked(const T *src, int w, int h, int sstrid } template -Q_STATIC_TEMPLATE_FUNCTION +static inline void qt_memrotate270_tiled(const T *src, int w, int h, int sstride, T *dest, int dstride) { sstride /= sizeof(T); @@ -190,7 +190,7 @@ inline void qt_memrotate270_tiled(const T *src, int w, int h, int sstride, T *de } template -Q_STATIC_TEMPLATE_FUNCTION +static inline void qt_memrotate270_tiled_unpacked(const T *src, int w, int h, int sstride, T *dest, int dstride) { @@ -219,7 +219,7 @@ inline void qt_memrotate270_tiled_unpacked(const T *src, int w, int h, int sstri template -Q_STATIC_TEMPLATE_FUNCTION +static inline void qt_memrotate90_template(const T *src, int srcWidth, int srcHeight, int srcStride, T *dest, int dstStride) { @@ -246,7 +246,7 @@ inline void qt_memrotate90_template(const quint64 *src, int w, int h, i } template -Q_STATIC_TEMPLATE_FUNCTION +static inline void qt_memrotate180_template(const T *src, int w, int h, int sstride, T *dest, int dstride) { const char *s = (const char*)(src) + (h - 1) * sstride; @@ -261,7 +261,7 @@ inline void qt_memrotate180_template(const T *src, int w, int h, int sstride, T } template -Q_STATIC_TEMPLATE_FUNCTION +static inline void qt_memrotate270_template(const T *src, int srcWidth, int srcHeight, int srcStride, T *dest, int dstStride) { From a76f8caf29c9acf83f12dfe90f68cd3f13e45456 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Tue, 30 Oct 2018 15:50:39 +0100 Subject: [PATCH 0192/1650] [Micro]Optimize QStyleSheetStyle::subElementRect No need to make a QStyleOptionButton copy, we can just use the pointer we already have Change-Id: I3ef5f59eb4fe25adf675e67ebf548f4358456379 Reviewed-by: Christian Ehrlicher Reviewed-by: Richard Moe Gustavsen --- src/widgets/styles/qstylesheetstyle.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 6cfb65a800..654bd19d9b 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -5777,11 +5777,10 @@ QRect QStyleSheetStyle::subElementRect(SubElement se, const QStyleOption *opt, c case SE_PushButtonContents: case SE_PushButtonFocusRect: if (const QStyleOptionButton *btn = qstyleoption_cast(opt)) { - QStyleOptionButton btnOpt(*btn); if (rule.hasBox() || !rule.hasNativeBorder()) return visualRect(opt->direction, opt->rect, rule.contentsRect(opt->rect)); - return rule.baseStyleCanDraw() ? baseStyle()->subElementRect(se, &btnOpt, w) - : QWindowsStyle::subElementRect(se, &btnOpt, w); + return rule.baseStyleCanDraw() ? baseStyle()->subElementRect(se, btn, w) + : QWindowsStyle::subElementRect(se, btn, w); } break; From fc88dd52a42da682cbd360916be7c9f94a69b72c Mon Sep 17 00:00:00 2001 From: David Faure Date: Thu, 25 Oct 2018 11:07:58 +0200 Subject: [PATCH 0193/1650] QByteArrayList: add indexOf(const char*) overload This avoids memory allocation and data copying in e.g. QObject::property(). Detected by heaptrack's "Temporary allocations" counter in an application using the breeze widget style (many animations). Change-Id: Iabdb58a3e504cb121cce906ef707b0722de89df6 Reviewed-by: Thiago Macieira --- src/corelib/tools/qbytearraylist.cpp | 22 ++++++++++++++++ src/corelib/tools/qbytearraylist.h | 4 +++ .../qbytearraylist/tst_qbytearraylist.cpp | 26 +++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/src/corelib/tools/qbytearraylist.cpp b/src/corelib/tools/qbytearraylist.cpp index c815e766ab..d04555ed4d 100644 --- a/src/corelib/tools/qbytearraylist.cpp +++ b/src/corelib/tools/qbytearraylist.cpp @@ -150,4 +150,26 @@ QByteArray QtPrivate::QByteArrayList_join(const QByteArrayList *that, const char return res; } +/*! + \fn int QByteArrayList::indexOf(const char *needle, int from) const + + Returns the index position of the first occurrence of \a needle in + the list, searching forward from index position \a from. Returns + -1 if no item matched. + + \a needle must be NUL-terminated. + + This overload doesn't require creating a QByteArray, thus saving a + memory allocation and some CPU time. + + \since 5.13 + \overload +*/ + +int QtPrivate::QByteArrayList_indexOf(const QByteArrayList *that, const char *needle, int from) +{ + const auto it = std::find_if(that->begin() + from, that->end(), [needle](const QByteArray &item) { return item == needle; }); + return it == that->end() ? -1 : int(std::distance(that->begin(), it)); +} + QT_END_NAMESPACE diff --git a/src/corelib/tools/qbytearraylist.h b/src/corelib/tools/qbytearraylist.h index be94bc1d40..d69e8bb54b 100644 --- a/src/corelib/tools/qbytearraylist.h +++ b/src/corelib/tools/qbytearraylist.h @@ -55,6 +55,7 @@ typedef QList QByteArrayList; namespace QtPrivate { QByteArray Q_CORE_EXPORT QByteArrayList_join(const QByteArrayList *that, const char *separator, int separatorLength); + int Q_CORE_EXPORT QByteArrayList_indexOf(const QByteArrayList *that, const char *needle, int from); } #endif @@ -76,6 +77,9 @@ public: inline QByteArray join(char sep) const { return QtPrivate::QByteArrayList_join(self(), &sep, 1); } + inline int indexOf(const char *needle, int from = 0) const + { return QtPrivate::QByteArrayList_indexOf(self(), needle, from); } + private: typedef QList Self; Self *self() { return static_cast(this); } diff --git a/tests/auto/corelib/tools/qbytearraylist/tst_qbytearraylist.cpp b/tests/auto/corelib/tools/qbytearraylist/tst_qbytearraylist.cpp index 85b4c4bfb7..2d2c536453 100644 --- a/tests/auto/corelib/tools/qbytearraylist/tst_qbytearraylist.cpp +++ b/tests/auto/corelib/tools/qbytearraylist/tst_qbytearraylist.cpp @@ -49,6 +49,9 @@ private slots: void operator_plus() const; void operator_plus_data() const; + void indexOf_data() const; + void indexOf() const; + void initializerList() const; }; @@ -259,6 +262,29 @@ void tst_QByteArrayList::operator_plus_data() const << ( QByteArrayList() << "a" << "" << "c" ); } +void tst_QByteArrayList::indexOf_data() const +{ + QTest::addColumn("list"); + QTest::addColumn("item"); + QTest::addColumn("expectedResult"); + + QTest::newRow("empty") << QByteArrayList() << QByteArray("a") << -1; + QTest::newRow("found_1") << ( QByteArrayList() << "a" ) << QByteArray("a") << 0; + QTest::newRow("not_found_1") << ( QByteArrayList() << "a" ) << QByteArray("b") << -1; + QTest::newRow("found_2") << ( QByteArrayList() << "hello" << "world" ) << QByteArray("world") << 1; + QTest::newRow("returns_first") << ( QByteArrayList() << "hello" << "world" << "hello" << "again" ) << QByteArray("hello") << 0; +} + +void tst_QByteArrayList::indexOf() const +{ + QFETCH(QByteArrayList, list); + QFETCH(QByteArray, item); + QFETCH(int, expectedResult); + + QCOMPARE(list.indexOf(item), expectedResult); + QCOMPARE(list.indexOf(item.constData()), expectedResult); +} + void tst_QByteArrayList::initializerList() const { #ifdef Q_COMPILER_INITIALIZER_LISTS From d761c6278305ef8737daca4bc3e61a119b40e107 Mon Sep 17 00:00:00 2001 From: David Edmundson Date: Fri, 6 Apr 2018 01:27:32 +0100 Subject: [PATCH 0194/1650] QDBusServiceWatcher namespace prefix support This allows a user to efficiently watch for services with a common domain prefix. This is exposed in the API via a wildcard character in the service name. For example creating a watcher on "org.mpris*" will match "org.mpris.foo" "org.mpris.bar" and "org.mpris" itself. It will not match org.mprisasdf. Internally the argument match rules have been expanded from a single QStringList to a struct containing args and arg0namespace. This was done so that we can easily use argpath in match rules in the future. Change-Id: I55882ab603cc6ba478e8c0ea9a6800f6e483a50c Reviewed-by: Kai Uwe Broulik Reviewed-by: Thiago Macieira Reviewed-by: David Faure --- src/dbus/qdbusconnection_p.h | 20 ++- src/dbus/qdbusintegrator.cpp | 89 +++++++++--- src/dbus/qdbusservicewatcher.cpp | 11 ++ .../tst_qdbusservicewatcher.cpp | 137 +++++++++++++----- 4 files changed, 194 insertions(+), 63 deletions(-) diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index 444d4727fd..84ce21092a 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -121,6 +121,15 @@ public: QSocketNotifier *write; }; + struct ArgMatchRules { + QStringList args; + QString arg0namespace; + bool operator==(const ArgMatchRules &other) const { + return args == other.args && + arg0namespace == other.arg0namespace; + } + }; + struct SignalHook { inline SignalHook() : obj(0), midx(-1) { } @@ -128,7 +137,7 @@ public: QObject* obj; int midx; QVector params; - QStringList argumentMatch; + ArgMatchRules argumentMatch; QByteArray matchRule; }; @@ -207,12 +216,19 @@ public: QDBusMessage sendWithReplyLocal(const QDBusMessage &message); QDBusPendingCallPrivate *sendWithReplyAsync(const QDBusMessage &message, QObject *receiver, const char *returnMethod, const char *errorMethod,int timeout = -1); + bool connectSignal(const QString &service, const QString &path, const QString& interface, const QString &name, const QStringList &argumentMatch, const QString &signature, QObject *receiver, const char *slot); bool disconnectSignal(const QString &service, const QString &path, const QString& interface, const QString &name, const QStringList &argumentMatch, const QString &signature, QObject *receiver, const char *slot); + bool connectSignal(const QString &service, const QString &path, const QString& interface, + const QString &name, const ArgMatchRules &argumentMatch, const QString &signature, + QObject *receiver, const char *slot); + bool disconnectSignal(const QString &service, const QString &path, const QString& interface, + const QString &name, const ArgMatchRules &argumentMatch, const QString &signature, + QObject *receiver, const char *slot); void registerObject(const ObjectTreeNode *node); void unregisterObject(const QString &path, QDBusConnection::UnregisterMode mode); void connectRelay(const QString &service, @@ -332,7 +348,7 @@ public: static bool prepareHook(QDBusConnectionPrivate::SignalHook &hook, QString &key, const QString &service, const QString &path, const QString &interface, const QString &name, - const QStringList &argMatch, + const ArgMatchRules &argMatch, QObject *receiver, const char *signal, int minMIdx, bool buildSignature); static DBusHandlerResult messageFilter(DBusConnection *, DBusMessage *, void *); diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 03de5b0091..cee5c821c8 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -338,7 +338,7 @@ void QDBusConnectionPrivate::_q_newConnection(QDBusConnectionPrivate *newConnect static QByteArray buildMatchRule(const QString &service, const QString &objectPath, const QString &interface, - const QString &member, const QStringList &argMatch, const QString & /*signature*/) + const QString &member, const QDBusConnectionPrivate::ArgMatchRules &argMatch, const QString & /*signature*/) { QString result = QLatin1String("type='signal',"); QString keyValue = QLatin1String("%1='%2',"); @@ -353,11 +353,14 @@ static QByteArray buildMatchRule(const QString &service, result += keyValue.arg(QLatin1String("member"), member); // add the argument string-matching now - if (!argMatch.isEmpty()) { + if (!argMatch.args.isEmpty()) { keyValue = QLatin1String("arg%1='%2',"); - for (int i = 0; i < argMatch.count(); ++i) - if (!argMatch.at(i).isNull()) - result += keyValue.arg(i).arg(argMatch.at(i)); + for (int i = 0; i < argMatch.args.count(); ++i) + if (!argMatch.args.at(i).isNull()) + result += keyValue.arg(i).arg(argMatch.args.at(i)); + } + if (!argMatch.arg0namespace.isEmpty()) { + result += QStringLiteral("arg0namespace='%1',").arg(argMatch.arg0namespace); } result.chop(1); // remove ending comma @@ -456,21 +459,26 @@ static QObject *findChildObject(const QDBusConnectionPrivate::ObjectTreeNode *ro return 0; } -static QStringList matchArgsForService(const QString &service, QDBusServiceWatcher::WatchMode mode) +static QDBusConnectionPrivate::ArgMatchRules matchArgsForService(const QString &service, QDBusServiceWatcher::WatchMode mode) { - QStringList matchArgs; - matchArgs << service; + QDBusConnectionPrivate::ArgMatchRules matchArgs; + if (service.endsWith(QLatin1Char('*'))) { + matchArgs.arg0namespace = service.chopped(1); + matchArgs.args << QString(); + } + else + matchArgs.args << service; switch (mode) { case QDBusServiceWatcher::WatchForOwnerChange: break; case QDBusServiceWatcher::WatchForRegistration: - matchArgs << QString::fromLatin1("", 0); + matchArgs.args << QString::fromLatin1("", 0); break; case QDBusServiceWatcher::WatchForUnregistration: - matchArgs << QString() << QString::fromLatin1("", 0); + matchArgs.args << QString() << QString::fromLatin1("", 0); break; } return matchArgs; @@ -1310,7 +1318,7 @@ int QDBusConnectionPrivate::findSlot(QObject* obj, const QByteArray &normalizedN bool QDBusConnectionPrivate::prepareHook(QDBusConnectionPrivate::SignalHook &hook, QString &key, const QString &service, const QString &path, const QString &interface, const QString &name, - const QStringList &argMatch, + const ArgMatchRules &argMatch, QObject *receiver, const char *signal, int minMIdx, bool buildSignature) { @@ -1620,14 +1628,14 @@ void QDBusConnectionPrivate::handleSignal(const QString &key, const QDBusMessage continue; if (hook.signature.isEmpty() && !hook.signature.isNull() && !msg.signature().isEmpty()) continue; - if (!hook.argumentMatch.isEmpty()) { + if (!hook.argumentMatch.args.isEmpty()) { const QVariantList arguments = msg.arguments(); - if (hook.argumentMatch.size() > arguments.size()) + if (hook.argumentMatch.args.size() > arguments.size()) continue; bool matched = true; - for (int i = 0; i < hook.argumentMatch.size(); ++i) { - const QString ¶m = hook.argumentMatch.at(i); + for (int i = 0; i < hook.argumentMatch.args.size(); ++i) { + const QString ¶m = hook.argumentMatch.args.at(i); if (param.isNull()) continue; // don't try to match against this if (param == arguments.at(i).toString()) @@ -1638,7 +1646,15 @@ void QDBusConnectionPrivate::handleSignal(const QString &key, const QDBusMessage if (!matched) continue; } - + if (!hook.argumentMatch.arg0namespace.isEmpty()) { + const QVariantList arguments = msg.arguments(); + if (arguments.size() < 1) + continue; + const QString param = arguments.at(0).toString(); + if (param != hook.argumentMatch.arg0namespace + && !param.startsWith(hook.argumentMatch.arg0namespace + QLatin1Char('.'))) + continue; + } activateSignal(hook, msg); } } @@ -2180,10 +2196,21 @@ void QDBusConnectionPrivate::sendInternal(QDBusPendingCallPrivate *pcall, void * } } + bool QDBusConnectionPrivate::connectSignal(const QString &service, const QString &path, const QString &interface, const QString &name, const QStringList &argumentMatch, const QString &signature, QObject *receiver, const char *slot) +{ + ArgMatchRules rules; + rules.args = argumentMatch; + return connectSignal(service, path, interface, name, rules, signature, receiver, slot); +} + +bool QDBusConnectionPrivate::connectSignal(const QString &service, + const QString &path, const QString &interface, const QString &name, + const ArgMatchRules &argumentMatch, const QString &signature, + QObject *receiver, const char *slot) { // check the slot QDBusConnectionPrivate::SignalHook hook; @@ -2241,9 +2268,11 @@ bool QDBusConnectionPrivate::addSignalHook(const QString &key, const SignalHook WatchedServicesHash::mapped_type &data = watchedServices[hook.service]; if (++data.refcount == 1) { // we need to watch for this service changing + ArgMatchRules rules; + rules.args << hook.service; q_dbus_bus_add_match(connection, buildMatchRule(QDBusUtil::dbusService(), QString(), QDBusUtil::dbusInterface(), - QDBusUtil::nameOwnerChanged(), QStringList() << hook.service, QString()), + QDBusUtil::nameOwnerChanged(), rules, QString()), NULL); data.owner = getNameOwnerNoCache(hook.service); qDBusDebug() << this << "Watching service" << hook.service << "for owner changes (current owner:" @@ -2255,9 +2284,19 @@ bool QDBusConnectionPrivate::addSignalHook(const QString &key, const SignalHook return true; } +bool QDBusConnectionPrivate::disconnectSignal(const QString &service, + const QString &path, const QString &interface, const QString &name, + const QStringList &argumentMatch, const QString &signature, + QObject *receiver, const char *slot) +{ + ArgMatchRules rules; + rules.args = argumentMatch; + return disconnectSignal(service, path, interface, name, rules, signature, receiver, slot); +} + bool QDBusConnectionPrivate::disconnectSignal(const QString &service, const QString &path, const QString &interface, const QString &name, - const QStringList &argumentMatch, const QString &signature, + const ArgMatchRules &argumentMatch, const QString &signature, QObject *receiver, const char *slot) { // check the slot @@ -2288,7 +2327,7 @@ bool QDBusConnectionPrivate::removeSignalHook(const QString &key, const SignalHo entry.signature == hook.signature && entry.obj == hook.obj && entry.midx == hook.midx && - entry.argumentMatch == hook.argumentMatch) { + entry.argumentMatch.args == hook.argumentMatch.args) { // no need to compare the parameters if it's the same slot removeSignalHookNoLock(it); return true; // it was there @@ -2330,9 +2369,11 @@ QDBusConnectionPrivate::removeSignalHookNoLock(SignalHookHash::Iterator it) if (sit != watchedServices.end()) { if (--sit.value().refcount == 0) { watchedServices.erase(sit); + ArgMatchRules rules; + rules.args << hook.service; q_dbus_bus_remove_match(connection, buildMatchRule(QDBusUtil::dbusService(), QString(), QDBusUtil::dbusInterface(), - QDBusUtil::nameOwnerChanged(), QStringList() << hook.service, QString()), + QDBusUtil::nameOwnerChanged(), rules, QString()), NULL); } } @@ -2393,7 +2434,7 @@ void QDBusConnectionPrivate::connectRelay(const QString &service, QByteArray sig; sig.append(QSIGNAL_CODE + '0'); sig.append(signal.methodSignature()); - if (!prepareHook(hook, key, service, path, interface, QString(), QStringList(), receiver, sig, + if (!prepareHook(hook, key, service, path, interface, QString(), ArgMatchRules(), receiver, sig, QDBusAbstractInterface::staticMetaObject.methodCount(), true)) return; // don't connect @@ -2414,7 +2455,7 @@ void QDBusConnectionPrivate::disconnectRelay(const QString &service, QByteArray sig; sig.append(QSIGNAL_CODE + '0'); sig.append(signal.methodSignature()); - if (!prepareHook(hook, key, service, path, interface, QString(), QStringList(), receiver, sig, + if (!prepareHook(hook, key, service, path, interface, QString(), ArgMatchRules(), receiver, sig, QDBusAbstractInterface::staticMetaObject.methodCount(), true)) return; // don't disconnect @@ -2447,7 +2488,7 @@ bool QDBusConnectionPrivate::shouldWatchService(const QString &service) */ void QDBusConnectionPrivate::watchService(const QString &service, QDBusServiceWatcher::WatchMode mode, QObject *obj, const char *member) { - QStringList matchArgs = matchArgsForService(service, mode); + ArgMatchRules matchArgs = matchArgsForService(service, mode); connectSignal(QDBusUtil::dbusService(), QString(), QDBusUtil::dbusInterface(), QDBusUtil::nameOwnerChanged(), matchArgs, QString(), obj, member); } @@ -2462,7 +2503,7 @@ void QDBusConnectionPrivate::watchService(const QString &service, QDBusServiceWa */ void QDBusConnectionPrivate::unwatchService(const QString &service, QDBusServiceWatcher::WatchMode mode, QObject *obj, const char *member) { - QStringList matchArgs = matchArgsForService(service, mode); + ArgMatchRules matchArgs = matchArgsForService(service, mode); disconnectSignal(QDBusUtil::dbusService(), QString(), QDBusUtil::dbusInterface(), QDBusUtil::nameOwnerChanged(), matchArgs, QString(), obj, member); } diff --git a/src/dbus/qdbusservicewatcher.cpp b/src/dbus/qdbusservicewatcher.cpp index 0c2fb9118f..b0bfe7254d 100644 --- a/src/dbus/qdbusservicewatcher.cpp +++ b/src/dbus/qdbusservicewatcher.cpp @@ -139,6 +139,17 @@ void QDBusServiceWatcherPrivate::removeService(const QString &service) QDBusConnectionInterface::serviceOwnerChanged() signal because it allows one to receive only the signals for which the class is interested in. + Ending a service name with the character '*' will match all service names + within the specified namespace. + + For example "com.example.backend1*" will match + \list + \li com.example.backend1 + \li com.example.backend1.foo + \li com.example.backend1.foo.bar + \endlist + Substrings in the same domain will not be matched, i.e "com.example.backend12". + \sa QDBusConnection */ diff --git a/tests/auto/dbus/qdbusservicewatcher/tst_qdbusservicewatcher.cpp b/tests/auto/dbus/qdbusservicewatcher/tst_qdbusservicewatcher.cpp index b79f3ea5e3..1ba7ee51b1 100644 --- a/tests/auto/dbus/qdbusservicewatcher/tst_qdbusservicewatcher.cpp +++ b/tests/auto/dbus/qdbusservicewatcher/tst_qdbusservicewatcher.cpp @@ -34,22 +34,27 @@ class tst_QDBusServiceWatcher: public QObject { Q_OBJECT - QString serviceName; int testCounter; public: tst_QDBusServiceWatcher(); private slots: void initTestCase(); - void init(); - + void watchForCreation_data(); void watchForCreation(); + void watchForDisappearance_data(); void watchForDisappearance(); void watchForDisappearanceUniqueConnection(); + void watchForOwnerChange_data(); void watchForOwnerChange(); + void modeChange_data(); void modeChange(); void disconnectedConnection(); + void setConnection_data(); void setConnection(); + +private: + QString generateServiceName(); }; tst_QDBusServiceWatcher::tst_QDBusServiceWatcher() @@ -63,18 +68,45 @@ void tst_QDBusServiceWatcher::initTestCase() QVERIFY(con.isConnected()); } -void tst_QDBusServiceWatcher::init() +QString tst_QDBusServiceWatcher::generateServiceName() { + return "com.example.TestService" + QString::number(testCounter++); +} + +void tst_QDBusServiceWatcher::watchForCreation_data() { - // change the service name from test to test - serviceName = "com.example.TestService" + QString::number(testCounter++); + QTest::addColumn("watchedName"); + QTest::addColumn("registeredName"); + + //com.example.TestService5 matches com.example.TestService5 + QString name = generateServiceName(); + QTest::newRow("normal") << name << name; + + //com.example* matches com.example.TestService5 + name = generateServiceName(); + QTest::newRow("wildcard") << "com.example*" << name; + + //com.example.TestService5* matches com.example.TestService5 + name = generateServiceName(); + QTest::newRow("wildcard_exact") << name+"*" << name; + + //com.example.TestService5* matches com.example.TestService5.Foo + name = generateServiceName(); + QTest::newRow("wildcard_subdomain") << name+"*" << name + ".Foo"; + + //com.example.TestService5* matches com.example.TestService5.Foo.Bar + name = generateServiceName(); + QTest::newRow("wildcard_subsubdomain") << name+"*" << name + ".Foo.Bar"; } void tst_QDBusServiceWatcher::watchForCreation() { + QFETCH(QString, watchedName); + QFETCH(QString, registeredName); + QDBusConnection con = QDBusConnection::sessionBus(); QVERIFY(con.isConnected()); - QDBusServiceWatcher watcher(serviceName, con, QDBusServiceWatcher::WatchForRegistration); + QDBusServiceWatcher watcher(watchedName, con, QDBusServiceWatcher::WatchForRegistration); QSignalSpy spyR(&watcher, SIGNAL(serviceRegistered(QString))); QSignalSpy spyU(&watcher, SIGNAL(serviceUnregistered(QString))); @@ -82,18 +114,18 @@ void tst_QDBusServiceWatcher::watchForCreation() QTestEventLoop::instance().connect(&watcher, SIGNAL(serviceRegistered(QString)), SLOT(exitLoop())); // register a name - QVERIFY(con.registerService(serviceName)); + QVERIFY(con.registerService(registeredName)); QTestEventLoop::instance().enterLoop(1); QVERIFY(!QTestEventLoop::instance().timeout()); QCOMPARE(spyR.count(), 1); - QCOMPARE(spyR.at(0).at(0).toString(), serviceName); + QCOMPARE(spyR.at(0).at(0).toString(), registeredName); QCOMPARE(spyU.count(), 0); QCOMPARE(spyO.count(), 1); - QCOMPARE(spyO.at(0).at(0).toString(), serviceName); + QCOMPARE(spyO.at(0).at(0).toString(), registeredName); QVERIFY(spyO.at(0).at(1).toString().isEmpty()); QCOMPARE(spyO.at(0).at(2).toString(), con.baseService()); @@ -102,31 +134,39 @@ void tst_QDBusServiceWatcher::watchForCreation() spyO.clear(); // unregister it: - con.unregisterService(serviceName); + con.unregisterService(registeredName); // and register again - QVERIFY(con.registerService(serviceName)); + QVERIFY(con.registerService(registeredName)); QTestEventLoop::instance().enterLoop(1); QVERIFY(!QTestEventLoop::instance().timeout()); QCOMPARE(spyR.count(), 1); - QCOMPARE(spyR.at(0).at(0).toString(), serviceName); + QCOMPARE(spyR.at(0).at(0).toString(), registeredName); QCOMPARE(spyU.count(), 0); QCOMPARE(spyO.count(), 1); - QCOMPARE(spyO.at(0).at(0).toString(), serviceName); + QCOMPARE(spyO.at(0).at(0).toString(), registeredName); QVERIFY(spyO.at(0).at(1).toString().isEmpty()); QCOMPARE(spyO.at(0).at(2).toString(), con.baseService()); } +void tst_QDBusServiceWatcher::watchForDisappearance_data() +{ + tst_QDBusServiceWatcher::watchForCreation_data(); +} + void tst_QDBusServiceWatcher::watchForDisappearance() { + QFETCH(QString, watchedName); + QFETCH(QString, registeredName); + QDBusConnection con = QDBusConnection::sessionBus(); QVERIFY(con.isConnected()); - QDBusServiceWatcher watcher(serviceName, con, QDBusServiceWatcher::WatchForUnregistration); + QDBusServiceWatcher watcher(watchedName, con, QDBusServiceWatcher::WatchForUnregistration); watcher.setObjectName("watcher for disappearance"); QSignalSpy spyR(&watcher, SIGNAL(serviceRegistered(QString))); @@ -135,10 +175,10 @@ void tst_QDBusServiceWatcher::watchForDisappearance() QTestEventLoop::instance().connect(&watcher, SIGNAL(serviceUnregistered(QString)), SLOT(exitLoop())); // register a name - QVERIFY(con.registerService(serviceName)); + QVERIFY(con.registerService(registeredName)); // unregister it: - con.unregisterService(serviceName); + con.unregisterService(registeredName); QTestEventLoop::instance().enterLoop(1); QVERIFY(!QTestEventLoop::instance().timeout()); @@ -146,10 +186,10 @@ void tst_QDBusServiceWatcher::watchForDisappearance() QCOMPARE(spyR.count(), 0); QCOMPARE(spyU.count(), 1); - QCOMPARE(spyU.at(0).at(0).toString(), serviceName); + QCOMPARE(spyU.at(0).at(0).toString(), registeredName); QCOMPARE(spyO.count(), 1); - QCOMPARE(spyO.at(0).at(0).toString(), serviceName); + QCOMPARE(spyO.at(0).at(0).toString(), registeredName); QCOMPARE(spyO.at(0).at(1).toString(), con.baseService()); QVERIFY(spyO.at(0).at(2).toString().isEmpty()); } @@ -188,12 +228,20 @@ void tst_QDBusServiceWatcher::watchForDisappearanceUniqueConnection() QVERIFY(spyO.at(0).at(2).toString().isEmpty()); } +void tst_QDBusServiceWatcher::watchForOwnerChange_data() +{ + watchForCreation_data(); +} + void tst_QDBusServiceWatcher::watchForOwnerChange() { + QFETCH(QString, watchedName); + QFETCH(QString, registeredName); + QDBusConnection con = QDBusConnection::sessionBus(); QVERIFY(con.isConnected()); - QDBusServiceWatcher watcher(serviceName, con, QDBusServiceWatcher::WatchForOwnerChange); + QDBusServiceWatcher watcher(watchedName, con, QDBusServiceWatcher::WatchForOwnerChange); QSignalSpy spyR(&watcher, SIGNAL(serviceRegistered(QString))); QSignalSpy spyU(&watcher, SIGNAL(serviceUnregistered(QString))); @@ -201,18 +249,18 @@ void tst_QDBusServiceWatcher::watchForOwnerChange() QTestEventLoop::instance().connect(&watcher, SIGNAL(serviceRegistered(QString)), SLOT(exitLoop())); // register a name - QVERIFY(con.registerService(serviceName)); + QVERIFY(con.registerService(registeredName)); QTestEventLoop::instance().enterLoop(1); QVERIFY(!QTestEventLoop::instance().timeout()); QCOMPARE(spyR.count(), 1); - QCOMPARE(spyR.at(0).at(0).toString(), serviceName); + QCOMPARE(spyR.at(0).at(0).toString(), registeredName); QCOMPARE(spyU.count(), 0); QCOMPARE(spyO.count(), 1); - QCOMPARE(spyO.at(0).at(0).toString(), serviceName); + QCOMPARE(spyO.at(0).at(0).toString(), registeredName); QVERIFY(spyO.at(0).at(1).toString().isEmpty()); QCOMPARE(spyO.at(0).at(2).toString(), con.baseService()); @@ -221,35 +269,43 @@ void tst_QDBusServiceWatcher::watchForOwnerChange() spyO.clear(); // unregister it: - con.unregisterService(serviceName); + con.unregisterService(registeredName); // and register again - QVERIFY(con.registerService(serviceName)); + QVERIFY(con.registerService(registeredName)); QTestEventLoop::instance().enterLoop(1); QVERIFY(!QTestEventLoop::instance().timeout()); QCOMPARE(spyR.count(), 1); - QCOMPARE(spyR.at(0).at(0).toString(), serviceName); + QCOMPARE(spyR.at(0).at(0).toString(), registeredName); QCOMPARE(spyU.count(), 1); - QCOMPARE(spyU.at(0).at(0).toString(), serviceName); + QCOMPARE(spyU.at(0).at(0).toString(), registeredName); QCOMPARE(spyO.count(), 2); - QCOMPARE(spyO.at(0).at(0).toString(), serviceName); + QCOMPARE(spyO.at(0).at(0).toString(), registeredName); QCOMPARE(spyO.at(0).at(1).toString(), con.baseService()); QVERIFY(spyO.at(0).at(2).toString().isEmpty()); - QCOMPARE(spyO.at(1).at(0).toString(), serviceName); + QCOMPARE(spyO.at(1).at(0).toString(), registeredName); QVERIFY(spyO.at(1).at(1).toString().isEmpty()); QCOMPARE(spyO.at(1).at(2).toString(), con.baseService()); } +void tst_QDBusServiceWatcher::modeChange_data() +{ + watchForCreation_data(); +} + void tst_QDBusServiceWatcher::modeChange() { + QFETCH(QString, watchedName); + QFETCH(QString, registeredName); + QDBusConnection con = QDBusConnection::sessionBus(); QVERIFY(con.isConnected()); - QDBusServiceWatcher watcher(serviceName, con, QDBusServiceWatcher::WatchForRegistration); + QDBusServiceWatcher watcher(watchedName, con, QDBusServiceWatcher::WatchForRegistration); QSignalSpy spyR(&watcher, SIGNAL(serviceRegistered(QString))); QSignalSpy spyU(&watcher, SIGNAL(serviceUnregistered(QString))); @@ -257,18 +313,18 @@ void tst_QDBusServiceWatcher::modeChange() QTestEventLoop::instance().connect(&watcher, SIGNAL(serviceRegistered(QString)), SLOT(exitLoop())); // register a name - QVERIFY(con.registerService(serviceName)); + QVERIFY(con.registerService(registeredName)); QTestEventLoop::instance().enterLoop(1); QVERIFY(!QTestEventLoop::instance().timeout()); QCOMPARE(spyR.count(), 1); - QCOMPARE(spyR.at(0).at(0).toString(), serviceName); + QCOMPARE(spyR.at(0).at(0).toString(), registeredName); QCOMPARE(spyU.count(), 0); QCOMPARE(spyO.count(), 1); - QCOMPARE(spyO.at(0).at(0).toString(), serviceName); + QCOMPARE(spyO.at(0).at(0).toString(), registeredName); QVERIFY(spyO.at(0).at(1).toString().isEmpty()); QCOMPARE(spyO.at(0).at(2).toString(), con.baseService()); @@ -279,7 +335,7 @@ void tst_QDBusServiceWatcher::modeChange() watcher.setWatchMode(QDBusServiceWatcher::WatchForUnregistration); // unregister it: - con.unregisterService(serviceName); + con.unregisterService(registeredName); QTestEventLoop::instance().connect(&watcher, SIGNAL(serviceUnregistered(QString)), SLOT(exitLoop())); QTestEventLoop::instance().enterLoop(1); @@ -288,10 +344,10 @@ void tst_QDBusServiceWatcher::modeChange() QCOMPARE(spyR.count(), 0); QCOMPARE(spyU.count(), 1); - QCOMPARE(spyU.at(0).at(0).toString(), serviceName); + QCOMPARE(spyU.at(0).at(0).toString(), registeredName); QCOMPARE(spyO.count(), 1); - QCOMPARE(spyO.at(0).at(0).toString(), serviceName); + QCOMPARE(spyO.at(0).at(0).toString(), registeredName); QCOMPARE(spyO.at(0).at(1).toString(), con.baseService()); QVERIFY(spyO.at(0).at(2).toString().isEmpty()); } @@ -301,7 +357,7 @@ void tst_QDBusServiceWatcher::disconnectedConnection() QDBusConnection con(""); QVERIFY(!con.isConnected()); - QDBusServiceWatcher watcher(serviceName, con, QDBusServiceWatcher::WatchForRegistration); + QDBusServiceWatcher watcher(generateServiceName(), con, QDBusServiceWatcher::WatchForRegistration); watcher.addWatchedService("com.example.somethingelse"); watcher.addWatchedService("org.freedesktop.DBus"); @@ -311,8 +367,15 @@ void tst_QDBusServiceWatcher::disconnectedConnection() watcher.setWatchedServices(QStringList()); } +void tst_QDBusServiceWatcher::setConnection_data() +{ + QTest::addColumn("serviceName"); + QTest::newRow("normal") << generateServiceName(); +} + void tst_QDBusServiceWatcher::setConnection() { + QFETCH(QString, serviceName); // begin with a disconnected connection QDBusConnection con(""); QVERIFY(!con.isConnected()); From 033cc3403a8238d1b6d56c42e9e9be4fba1069dc Mon Sep 17 00:00:00 2001 From: Samuli Piippo Date: Fri, 19 Oct 2018 12:41:58 +0300 Subject: [PATCH 0195/1650] mkspecs: use cross compile tools with LTCG AR and NM have different tools when LTCG is used, override those also when cross compiling. Fixes: QTBUG-71595 Change-Id: I5347bd1874688dd89395c50ff6dd08fb1c0ebab1 Reviewed-by: Oswald Buddenhagen --- mkspecs/devices/common/linux_device_pre.conf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mkspecs/devices/common/linux_device_pre.conf b/mkspecs/devices/common/linux_device_pre.conf index 8c6c87d0b7..5b6a9bfcfa 100644 --- a/mkspecs/devices/common/linux_device_pre.conf +++ b/mkspecs/devices/common/linux_device_pre.conf @@ -24,5 +24,9 @@ QMAKE_OBJCOPY = $${CROSS_COMPILE}objcopy QMAKE_NM = $${CROSS_COMPILE}nm -P QMAKE_STRIP = $${CROSS_COMPILE}strip +# modifications to gcc-base.conf +QMAKE_AR_LTCG = $${CROSS_COMPILE}gcc-ar cqs +QMAKE_NM_LTCG = $${CROSS_COMPILE}gcc-nm -P + contains(DISTRO_OPTS, deb-multi-arch): \ QMAKE_PKG_CONFIG = $${CROSS_COMPILE}pkg-config From 1771b8d7c6fd052e6a16b109cc841e69fe180e2d Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sun, 29 Jul 2018 13:21:28 +0200 Subject: [PATCH 0196/1650] QFbCursor: Avoid nullptr access when QT_QPA_FB_HIDECURSOR is 0 When the environment variable QT_QPA_FB_HIDECURSOR is set to 0, the two class members mCursorImage and mDeviceListener are nullptr but this was not checked in the functions afterwards. Task-number: QTBUG-64844 Change-Id: Ic0fd6a09851777643e59bedf2c006a6bb9a36801 Reviewed-by: Laszlo Agocs --- .../fbconvenience/qfbcursor.cpp | 25 +++++++++++++------ .../fbconvenience/qfbcursor_p.h | 2 +- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/platformsupport/fbconvenience/qfbcursor.cpp b/src/platformsupport/fbconvenience/qfbcursor.cpp index 7daf3f4d0c..e0f6b69e77 100644 --- a/src/platformsupport/fbconvenience/qfbcursor.cpp +++ b/src/platformsupport/fbconvenience/qfbcursor.cpp @@ -63,9 +63,9 @@ QFbCursor::QFbCursor(QFbScreen *screen) mCursorImage(nullptr), mDeviceListener(nullptr) { - QByteArray hideCursorVal = qgetenv("QT_QPA_FB_HIDECURSOR"); - if (!hideCursorVal.isEmpty()) - mVisible = hideCursorVal.toInt() == 0; + const char *envVar = "QT_QPA_FB_HIDECURSOR"; + if (qEnvironmentVariableIsSet(envVar)) + mVisible = qEnvironmentVariableIntValue(envVar) == 0; if (!mVisible) return; @@ -83,7 +83,7 @@ QFbCursor::~QFbCursor() delete mDeviceListener; } -QRect QFbCursor::getCurrentRect() +QRect QFbCursor::getCurrentRect() const { QRect rect = mCursorImage->image()->rect().translated(-mCursorImage->hotspot().x(), -mCursorImage->hotspot().y()); @@ -102,6 +102,8 @@ void QFbCursor::setPos(const QPoint &pos) { QGuiApplicationPrivate::inputDeviceManager()->setCursorPos(pos); m_pos = pos; + if (!mVisible) + return; mCurrentRect = getCurrentRect(); if (mOnScreen || mScreen->geometry().intersects(mCurrentRect.translated(mScreen->geometry().topLeft()))) setDirty(); @@ -112,6 +114,8 @@ void QFbCursor::pointerEvent(const QMouseEvent &e) if (e.type() != QEvent::MouseMove) return; m_pos = e.screenPos().toPoint(); + if (!mVisible) + return; mCurrentRect = getCurrentRect(); if (mOnScreen || mScreen->geometry().intersects(mCurrentRect.translated(mScreen->geometry().topLeft()))) setDirty(); @@ -149,23 +153,28 @@ QRect QFbCursor::dirtyRect() void QFbCursor::setCursor(Qt::CursorShape shape) { - mCursorImage->set(shape); + if (mCursorImage) + mCursorImage->set(shape); } void QFbCursor::setCursor(const QImage &image, int hotx, int hoty) { - mCursorImage->set(image, hotx, hoty); + if (mCursorImage) + mCursorImage->set(image, hotx, hoty); } void QFbCursor::setCursor(const uchar *data, const uchar *mask, int width, int height, int hotX, int hotY) { - mCursorImage->set(data, mask, width, height, hotX, hotY); + if (mCursorImage) + mCursorImage->set(data, mask, width, height, hotX, hotY); } #ifndef QT_NO_CURSOR void QFbCursor::changeCursor(QCursor * widgetCursor, QWindow *window) { Q_UNUSED(window); + if (!mVisible) + return; const Qt::CursorShape shape = widgetCursor ? widgetCursor->shape() : Qt::ArrowCursor; if (shape == Qt::BitmapCursor) { @@ -196,7 +205,7 @@ void QFbCursor::setDirty() void QFbCursor::updateMouseStatus() { - mVisible = mDeviceListener->hasMouse(); + mVisible = mDeviceListener ? mDeviceListener->hasMouse() : false; mScreen->setDirty(mVisible ? getCurrentRect() : lastPainted()); } diff --git a/src/platformsupport/fbconvenience/qfbcursor_p.h b/src/platformsupport/fbconvenience/qfbcursor_p.h index beda10a5f3..cc36a2411b 100644 --- a/src/platformsupport/fbconvenience/qfbcursor_p.h +++ b/src/platformsupport/fbconvenience/qfbcursor_p.h @@ -105,7 +105,7 @@ private: void setCursor(const uchar *data, const uchar *mask, int width, int height, int hotX, int hotY); void setCursor(Qt::CursorShape shape); void setCursor(const QImage &image, int hotx, int hoty); - QRect getCurrentRect(); + QRect getCurrentRect() const; bool mVisible; QFbScreen *mScreen; From 8828993c4405a8aa98f11318151a74b352eb5521 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Thu, 1 Nov 2018 12:46:24 +0100 Subject: [PATCH 0197/1650] Doc: Qt GUI: Fix documentation warnings These are minor typos or documentation warnings that snuck in with new features. Task-number: QTBUG-71502 Change-Id: I03669cfecc3c3d80168ff7b1ca8bca7571e06d25 Reviewed-by: Martin Smith --- src/gui/itemmodels/qstandarditemmodel.cpp | 3 +++ src/gui/kernel/qplatformgraphicsbufferhelper.cpp | 6 ++++++ src/gui/opengl/qopenglfunctions.cpp | 1 + src/gui/painting/qcolor.cpp | 2 +- src/gui/text/qfont.cpp | 2 +- src/gui/text/qtextdocument.cpp | 2 +- src/gui/text/qtextformat.cpp | 3 ++- 7 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/gui/itemmodels/qstandarditemmodel.cpp b/src/gui/itemmodels/qstandarditemmodel.cpp index 8ec88ebc60..430ba152a9 100644 --- a/src/gui/itemmodels/qstandarditemmodel.cpp +++ b/src/gui/itemmodels/qstandarditemmodel.cpp @@ -3013,6 +3013,9 @@ bool QStandardItemModel::setData(const QModelIndex &index, const QVariant &value /*! \since 5.12 Removes the data stored in all the roles for the given \a index. + Returns \c true if \a index is valid and data was cleared, \c false + otherwise. + \sa setData(), data() */ bool QStandardItemModel::clearItemData(const QModelIndex &index) diff --git a/src/gui/kernel/qplatformgraphicsbufferhelper.cpp b/src/gui/kernel/qplatformgraphicsbufferhelper.cpp index 924266997d..c98aead5c2 100644 --- a/src/gui/kernel/qplatformgraphicsbufferhelper.cpp +++ b/src/gui/kernel/qplatformgraphicsbufferhelper.cpp @@ -56,6 +56,12 @@ QT_BEGIN_NAMESPACE +/*! + \namespace QPlatformGraphicsBufferHelper + \inmodule QtGui + \internal +*/ + /*! Convenience function to both lock and bind the \a graphicsBuffer to a texture. This function will first try to lock with texture read and texture write diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp index b4ff21f3fd..92770cb55f 100644 --- a/src/gui/opengl/qopenglfunctions.cpp +++ b/src/gui/opengl/qopenglfunctions.cpp @@ -142,6 +142,7 @@ void CLASS::init(QOpenGLContext *context) \ \value BlendColor glBlendColor() is available. \value BlendEquation glBlendEquation() is available. \value BlendEquationSeparate glBlendEquationSeparate() is available. + \value BlendEquationAdvanced Advanced blend equations are available. \value BlendFuncSeparate glBlendFuncSeparate() is available. \value BlendSubtract Blend subtract mode is available. \value CompressedTextures Compressed texture functions are available. diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index 1d7375d1df..ed6a44079d 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -1366,7 +1366,7 @@ QRgba64 QColor::rgba64() const Q_DECL_NOTHROW Sets the RGB64 value to \a rgba, including its alpha. - \sa \setRgba(), rgba64() + \sa setRgba(), rgba64() */ void QColor::setRgba64(QRgba64 rgba) Q_DECL_NOTHROW { diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 580a09427c..69255fd59d 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -1254,7 +1254,7 @@ QFont::StyleStrategy QFont::styleStrategy() const /*! Returns the StyleHint. - The style hint affects the \l{#fontmatching}{font matching algorithm}. + The style hint affects the \l{QFont#fontmatching}{font matching algorithm}. See \l QFont::StyleHint for the list of available hints. \sa setStyleHint(), QFont::StyleStrategy, QFontInfo::styleHint() diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 5d88530e65..f823b90785 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -153,7 +153,7 @@ bool Qt::mightBeRichText(const QString& text) This function is defined in the \c header file. - \sa escape(), mightBeRichText() + \sa QString::toHtmlEscaped(), mightBeRichText() */ QString Qt::convertFromPlainText(const QString &plain, Qt::WhiteSpaceMode mode) { diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index 4957da1908..919cdf3ff1 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -645,6 +645,7 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt) \value ImageName \value ImageWidth \value ImageHeight + \value ImageQuality Selection properties @@ -2251,7 +2252,7 @@ QList QTextBlockFormat::tabPositions() const \fn void QTextBlockFormat::setHeadingLevel(int level) \since 5.12 - Sets the paragraph's heading level, where 1 is the highest-level heading + Sets the paragraph's heading \a level, where 1 is the highest-level heading type (usually with the largest possible heading font size), and increasing values are progressively deeper into the document (and usually with smaller font sizes). For example when reading an HTML H1 tag, the heading level is From ec1548ae122af2febfc61c0242025ee52c8cbc30 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Wed, 31 Oct 2018 13:49:14 +0100 Subject: [PATCH 0198/1650] Doc: Fix various documentation warnings These include typos, marking functions as \internal, documenting trivial things, and fixing the function signatures passed to the \fn command. Task-number: QTBUG-71502 Change-Id: I24a9e1f7e1cdb39e5c31b99202bdd593c6b789ff Reviewed-by: Martin Smith Reviewed-by: Paul Wicking Reviewed-by: Edward Welbourne --- src/corelib/global/qglobal.cpp | 2 +- src/corelib/global/qglobalstatic.qdoc | 10 ++++++---- src/corelib/io/qdir.cpp | 11 ++++++----- src/corelib/io/qprocess.cpp | 8 ++++---- src/corelib/kernel/qdeadlinetimer.cpp | 5 +++++ src/corelib/kernel/qeventdispatcher_cf.mm | 2 +- src/corelib/kernel/qtimer.cpp | 18 +++++++++--------- src/corelib/tools/qbytearray.cpp | 4 ++-- src/corelib/tools/qmap.cpp | 2 +- src/corelib/tools/qregularexpression.cpp | 4 ++-- src/corelib/tools/qshareddata.cpp | 7 +++++++ src/corelib/tools/qstring.cpp | 2 +- src/corelib/tools/qtimezone.cpp | 2 +- 13 files changed, 46 insertions(+), 31 deletions(-) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 5c1665fa00..88d4877be5 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -3796,7 +3796,7 @@ bool qunsetenv(const char *varName) dependent delayed translation in the given \a context with the given \a comment. The \a context is typically a class and also needs to be specified - as a string literal. The string literal \a disambiguation should be + as a string literal. The string literal \a comment should be a short semantic tag to tell apart otherwise identical strings. The macro tells lupdate to collect the string, and expands to an diff --git a/src/corelib/global/qglobalstatic.qdoc b/src/corelib/global/qglobalstatic.qdoc index dbea04ecab..e7935d5a9b 100644 --- a/src/corelib/global/qglobalstatic.qdoc +++ b/src/corelib/global/qglobalstatic.qdoc @@ -435,6 +435,7 @@ */ /*! + \keyword qglobalstatic-operator-type-ptr \fn template QGlobalStatic::operator Type*() This function returns the address of the contents of this global static. If @@ -476,10 +477,11 @@ by this function. If the contents have already been destroyed, this function will return a null pointer. - This function is equivalent to \l {operator Type *()}. It is provided for - compatibility with the private Q_GLOBAL_STATIC implementation that existed - in Qt 4.x and 5.0. New code should avoid using it and should instead treat - the object as a smart pointer. + This function is equivalent to \l {qglobalstatic-operator-type-ptr} + {operator Type *()}. It is provided for compatibility with the private + Q_GLOBAL_STATIC implementation that existed in Qt 4.x and 5.0. New code + should avoid using it and should instead treat the object as a smart + pointer. */ /*! diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 75fd0f8e0a..7df461ddce 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -1040,7 +1040,8 @@ QStringList QDir::nameFilters() const list of filters specified by \a nameFilters. Each name filter is a wildcard (globbing) filter that understands - \c{*} and \c{?} wildcards. (See \l{QRegularExpression wildcard matching}.) + \c{*} and \c{?} wildcards. See \l{QRegularExpression#Wildcard matching} + {QRegularExpression Wildcard Matching}. For example, the following code sets three name filters on a QDir to ensure that only files with extensions typically used for C++ @@ -2120,8 +2121,8 @@ QString QDir::rootPath() patterns in the list of \a filters; otherwise returns \c false. The matching is case insensitive. - \sa {QRegularExpression Wildcard matching}, QRegularExpression::wildcardToRegularExpression(), - entryList(), entryInfoList() + \sa {QRegularExpression#Wildcard matching}{QRegularExpression Wildcard Matching}, + entryList(), entryInfoList() */ bool QDir::match(const QStringList &filters, const QString &fileName) { @@ -2143,8 +2144,8 @@ bool QDir::match(const QStringList &filters, const QString &fileName) contain multiple patterns separated by spaces or semicolons. The matching is case insensitive. - \sa {QRegularExpression wildcard matching}, QRegularExpression::wildcardToRegularExpression, - entryList(), entryInfoList() + \sa {QRegularExpression#Wildcard matching}{QRegularExpression Wildcard Matching}, + entryList(), entryInfoList() */ bool QDir::match(const QString &filter, const QString &fileName) { diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 890867cd51..e1f4a3a311 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -112,12 +112,12 @@ QT_BEGIN_NAMESPACE \relates QProcess Disables the - \l {QProcess::start(const QString &, OpenMode)}{QProcess::start()} - overload taking a single string. + \l {QProcess::start(const QString &, QIODevice::OpenMode)} + {QProcess::start}() overload taking a single string. In most cases where it is used, the user intends for the first argument to be treated atomically as per the other overload. - \sa QProcess::start(const QString &command, OpenMode mode) + \sa QProcess::start(const QString &command, QIODevice::OpenMode mode) */ /*! @@ -2557,7 +2557,7 @@ bool QProcess::startDetached(const QString &program, After the \a command string has been split and unquoted, this function behaves like the overload which takes the arguments as a string list. - \sa start(const QString &command, OpenMode mode) + \sa start(const QString &command, QIODevice::OpenMode mode) */ bool QProcess::startDetached(const QString &command) { diff --git a/src/corelib/kernel/qdeadlinetimer.cpp b/src/corelib/kernel/qdeadlinetimer.cpp index 466056d513..6aa886cfe1 100644 --- a/src/corelib/kernel/qdeadlinetimer.cpp +++ b/src/corelib/kernel/qdeadlinetimer.cpp @@ -720,6 +720,11 @@ QDeadlineTimer QDeadlineTimer::addNSecs(QDeadlineTimer dt, qint64 nsecs) Q_DECL_ Returns the time remaining before the deadline. */ +/*! + \fn QPair QDeadlineTimer::_q_data() const + \internal +*/ + // the rest of the functions are in qelapsedtimer_xxx.cpp QT_END_NAMESPACE diff --git a/src/corelib/kernel/qeventdispatcher_cf.mm b/src/corelib/kernel/qeventdispatcher_cf.mm index 8881305b18..b7b379e2c1 100644 --- a/src/corelib/kernel/qeventdispatcher_cf.mm +++ b/src/corelib/kernel/qeventdispatcher_cf.mm @@ -58,7 +58,7 @@ QT_USE_NAMESPACE -/*! +/* During scroll view panning, and possibly other gestures, UIKit will request a switch to UITrackingRunLoopMode via GSEventPushRunLoopMode, which records the new runloop mode and stops the current runloop. diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp index 90f29aa630..13f027074a 100644 --- a/src/corelib/kernel/qtimer.cpp +++ b/src/corelib/kernel/qtimer.cpp @@ -571,43 +571,43 @@ void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiv */ /*! - \fn template QMetaObject::Connection callOnTimeout(Functor functor, Qt::ConnectionType connectionType = Qt::AutoConnection) + \fn template QMetaObject::Connection QTimer::callOnTimeout(Functor slot, Qt::ConnectionType connectionType = Qt::AutoConnection) \since 5.12 \overload - Creates a connection from the timeout() signal to \a functor, and returns a + Creates a connection from the timeout() signal to \a slot, and returns a handle to the connection. This method is provided for convenience. - It's equivalent to calling \c {QObject::connect(timer, &QTimer::timeout, timer, functor, connectionType)}. + It's equivalent to calling \c {QObject::connect(timer, &QTimer::timeout, timer, slot, connectionType)}. \sa QObject::connect(), timeout() */ /*! - \fn template QMetaObject::Connection callOnTimeout(QObject *context, Functor functor, Qt::ConnectionType connectionType = Qt::AutoConnection) + \fn template QMetaObject::Connection QTimer::callOnTimeout(const QObject *context, Functor slot, Qt::ConnectionType connectionType = Qt::AutoConnection) \since 5.12 \overload callOnTimeout() - Creates a connection from the timeout() signal to \a functor to be placed in a specific + Creates a connection from the timeout() signal to \a slot to be placed in a specific event loop of \a context, and returns a handle to the connection. This method is provided for convenience. It's equivalent to calling - \c {QObject::connect(timer, &QTimer::timeout, context, functor, connectionType)}. + \c {QObject::connect(timer, &QTimer::timeout, context, slot, connectionType)}. \sa QObject::connect(), timeout() */ /*! - \fn template QMetaObject::Connection callOnTimeout(QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType connectionType = Qt::AutoConnection) + \fn template QMetaObject::Connection QTimer::callOnTimeout(const QObject *receiver, PointerToMemberFunction slot, Qt::ConnectionType connectionType = Qt::AutoConnection) \since 5.12 \overload callOnTimeout() - Creates a connection from the timeout() signal to the \a method in the \a receiver object. Returns + Creates a connection from the timeout() signal to the \a slot in the \a receiver object. Returns a handle to the connection. This method is provided for convenience. It's equivalent to calling - \c {QObject::connect(timer, &QTimer::timeout, receiver, method, connectionType)}. + \c {QObject::connect(timer, &QTimer::timeout, receiver, slot, connectionType)}. \sa QObject::connect(), timeout() */ diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 8f2ad8c012..53ae7b9452 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -3076,7 +3076,7 @@ bool QByteArray::endsWith(const char *str) const return qstrncmp(d->data() + d->size - len, str, len) == 0; } -/*! +/* Returns true if \a c is an uppercase Latin1 letter. \note The multiplication sign 0xD7 and the sz ligature 0xDF are not treated as uppercase Latin1. @@ -3112,7 +3112,7 @@ bool QByteArray::isUpper() const return true; } -/*! +/* Returns true if \a c is an lowercase Latin1 letter. \note The division sign 0xF7 is not treated as lowercase Latin1, but the small y dieresis 0xFF is. diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp index d7844f3128..5f7275c5f8 100644 --- a/src/corelib/tools/qmap.cpp +++ b/src/corelib/tools/qmap.cpp @@ -537,7 +537,7 @@ void QMapDataBase::freeData(QMapDataBase *d) \sa operator=() */ -/*! \fn template QMap::QMap(const std::map & other) +/*! \fn template QMap::QMap(const typename std::map & other) Constructs a copy of \a other. diff --git a/src/corelib/tools/qregularexpression.cpp b/src/corelib/tools/qregularexpression.cpp index fec5f620fc..908e7ff0d6 100644 --- a/src/corelib/tools/qregularexpression.cpp +++ b/src/corelib/tools/qregularexpression.cpp @@ -2000,8 +2000,8 @@ QString QRegularExpression::wildcardToRegularExpression(const QString &pattern) \since 5.12 - Returns the expression wrapped between the \c{\A} and \c{\z} anchors to be - used for exact matching. + Returns the \a expression wrapped between the \c{\A} and \c{\z} anchors to + be used for exact matching. \sa {Porting from QRegExp's Exact Matching} */ diff --git a/src/corelib/tools/qshareddata.cpp b/src/corelib/tools/qshareddata.cpp index bc4291e20f..c334f71fa0 100644 --- a/src/corelib/tools/qshareddata.cpp +++ b/src/corelib/tools/qshareddata.cpp @@ -579,6 +579,13 @@ QT_BEGIN_NAMESPACE the shared data object if the reference count became 0. */ +/*! \fn template T *QExplicitlySharedDataPointer::take() + \since 5.12 + + Returns a pointer to the shared object, and resets \e this to be null. + That is, this function sets the \e{d pointer} of \e this to \c nullptr. + */ + /*! \fn template QExplicitlySharedDataPointer::operator bool () const Returns \c true if the \e{d pointer} of \e this is \e not null. */ diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index c89635cfdb..fb7fb64223 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -254,7 +254,7 @@ inline RetType UnrollTailLoop<0>::exec(Number, RetType returnIfExited, Functor1, /*! * \internal * - * Searches for character \a \c in the string \a str and returns a pointer to + * Searches for character \a c in the string \a str and returns a pointer to * it. Unlike strchr() and wcschr() (but like glibc's strchrnul()), if the * character is not found, this function returns a pointer to the end of the * string -- that is, \c{str.end()}. diff --git a/src/corelib/tools/qtimezone.cpp b/src/corelib/tools/qtimezone.cpp index db6be581ec..cbc6b50c98 100644 --- a/src/corelib/tools/qtimezone.cpp +++ b/src/corelib/tools/qtimezone.cpp @@ -217,7 +217,7 @@ Q_GLOBAL_STATIC(QTimeZoneSingleton, global_tz); This class includes data obtained from the CLDR data files under the terms of the Unicode Data Files and Software License. See - \l{Unicode CLDR (Unicode Common Locale Data Repository)} for the details. + \l{Unicode Common Locale Data Repository (CLDR)} for details. \sa QDateTime */ From 411430f4201d36e9c8b44ad60344a87e271d07b8 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Thu, 1 Nov 2018 12:00:32 +0100 Subject: [PATCH 0199/1650] Re-add missing ANGLE license files Commit 0a7aebad inadvertently removed two ANGLE-related files for license information. This caused the licensing documentation to fail to generate for those components. Task-number: QTBUG-71502 Change-Id: I33ee673267c43474304d577e78fc1a0c3bd8691f Reviewed-by: Martin Smith --- src/3rdparty/angle/SYSTEMINFO_LICENSE | 22 ++++++++++++++++++++++ src/3rdparty/angle/TRACEEVENT_LICENSE | 27 +++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 src/3rdparty/angle/SYSTEMINFO_LICENSE create mode 100644 src/3rdparty/angle/TRACEEVENT_LICENSE diff --git a/src/3rdparty/angle/SYSTEMINFO_LICENSE b/src/3rdparty/angle/SYSTEMINFO_LICENSE new file mode 100644 index 0000000000..c12444e3bc --- /dev/null +++ b/src/3rdparty/angle/SYSTEMINFO_LICENSE @@ -0,0 +1,22 @@ +Copyright (C) 2009 Apple Inc. All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/3rdparty/angle/TRACEEVENT_LICENSE b/src/3rdparty/angle/TRACEEVENT_LICENSE new file mode 100644 index 0000000000..34d6cd9268 --- /dev/null +++ b/src/3rdparty/angle/TRACEEVENT_LICENSE @@ -0,0 +1,27 @@ +Copyright 2013 The Chromium Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. From a92735ec007b7cafacb70029ce10f039ace66515 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Tue, 30 Oct 2018 14:40:54 +0100 Subject: [PATCH 0200/1650] Doc: Document Qt::ScrollMomentum MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit And fix a typo in Qt::ScrollEnd. Task-number: QTBUG-71502 Change-Id: I3efdbd12415814e066edd1b2f102a792812d36d5 Reviewed-by: Tor Arne Vestbø --- src/corelib/global/qnamespace.qdoc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 42009e0b5e..652efb10bf 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -3187,8 +3187,12 @@ \value ScrollUpdate The scrolling distance has changed (default). - \value ScrollEnd Scrolling has ended, but the scrolling distance + \value ScrollEnd Scrolling has ended, and the scrolling distance did not change anymore. + + \value ScrollMomentum The user no longer touches the input device, + but scrolling continues due to scroll momentum. + This value was introduced in Qt 5.12. */ /*! From 46a595b047a928b1a5d527065c6814ef05e3a97b Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Tue, 30 Oct 2018 14:13:31 +0100 Subject: [PATCH 0201/1650] Doc: QCbor classes: Fix \variable commands \variable must not include the variable type, QDoc will resolve that. This commit resolves four documentation warnings. Task-number: QTBUG-71502 Change-Id: I5e88cf66d3c3bb8f18495d5477e1271ac2cd9e74 Reviewed-by: Martin Smith --- src/corelib/serialization/qcborstream.cpp | 6 ++++-- src/corelib/serialization/qcborvalue.cpp | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/corelib/serialization/qcborstream.cpp b/src/corelib/serialization/qcborstream.cpp index 22286188b8..7628019943 100644 --- a/src/corelib/serialization/qcborstream.cpp +++ b/src/corelib/serialization/qcborstream.cpp @@ -1422,12 +1422,14 @@ bool QCborStreamWriter::endMap() */ /*! - \variable Container QCborStreamReader::StringResult::data + \variable QCborStreamReader::StringResult::data + Contains the actual data from the string if \l status is \c Ok. */ /*! - \variable QCborStreamReader::StringResultCode QCborStreamReader::StringResult::status + \variable QCborStreamReader::StringResult::status + Contains the status of the attempt of reading the string from the stream. */ diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp index 5d97a6a06a..e53b6a0326 100644 --- a/src/corelib/serialization/qcborvalue.cpp +++ b/src/corelib/serialization/qcborvalue.cpp @@ -221,7 +221,7 @@ QT_BEGIN_NAMESPACE */ /*! - \variable qint64 QCborParserError::offset + \variable QCborParserError::offset This field contains the offset from the beginning of the data where the error was detected. The offset should point to the beginning of the item @@ -232,7 +232,7 @@ QT_BEGIN_NAMESPACE */ /*! - \variable QCborError QCborParserError::error + \variable QCborParserError::error This field contains the error code that indicates what decoding problem was found. From 4615415500bfa816b6010cfd47162899dd72c682 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Tue, 30 Oct 2018 14:01:00 +0100 Subject: [PATCH 0202/1650] Doc: Tie the QScopeGuard documentation to a class Previously no documentation was generated for the global qScopeGuard() function. Create a class documentation page and add the the function as a related non-member using \relates. Task-number: QTBUG-71502 Change-Id: Ida5d7044f4de962360dfee9321feb49005d4b299 Reviewed-by: Martin Smith --- src/corelib/tools/qscopeguard.qdoc | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/corelib/tools/qscopeguard.qdoc b/src/corelib/tools/qscopeguard.qdoc index 7cbc3e9c7b..70e13ab2fd 100644 --- a/src/corelib/tools/qscopeguard.qdoc +++ b/src/corelib/tools/qscopeguard.qdoc @@ -30,24 +30,36 @@ QT_BEGIN_NAMESPACE /*! - \fn const QScopeGuard qScopeGuard(F f) - \inmodule QtCore - \brief The qScopeGuard function can be used to call a function at the end of the scope. + \class QScopeGuard \since 5.12 + \inmodule QtCore + \brief Provides a scope guard for calling a function at the of + a scope. +*/ + +/*! + \fn template const QScopeGuard qScopeGuard(F f) + \inmodule QtCore + \relates QScopeGuard + \brief The qScopeGuard function can be used to call a function at the end + of the scope. \ingroup misc - QScopeGuard is a class which sole purpose is to run a function F in its destructor. - This is useful for guaranteeing your cleanup code is executed whether the function is exited normally, - exited early by a return statement, or exited by an exception. + QScopeGuard is a class which sole purpose is to run a function \e F in + its destructor. This is useful for guaranteeing your cleanup code is + executed, whether the function is exited normally, exited early by a return + statement, or exited by an exception. - If F is a lambda then you cannot instantiate the template directly, therefore the qScopeGuard() helper - is provided and QScopeGuard is made a private implementation detail. + If \e F is a lambda then you cannot instantiate the template directly, + therefore the qScopeGuard() helper is provided and QScopeGuard is made a + private implementation detail. Example usage is as follows: \snippet code/src_corelib_tools_qscopeguard.cpp 0 - \note Exceptions are not supported. The callable shouldn't throw when executed, copied or moved. + \note Exceptions are not supported. The callable shouldn't throw when + executed, copied or moved. \sa QScopedValueRollback */ From 9f2216667a96c2de94b28e4fd2891b6d3b938cb9 Mon Sep 17 00:00:00 2001 From: Andrew Smolko Date: Tue, 6 Nov 2018 11:20:34 +0300 Subject: [PATCH 0203/1650] Fix memory copy in QGIFFormat::disposePrevious() Fix invalid destination address in memcpy operation when RestoreImage disposal method is used. Task-number: QTBUG-71599 Change-Id: Ib74a044c0e45250ff708268c463f831ee54933e6 Reviewed-by: Eirik Aavitsland --- src/plugins/imageformats/gif/qgifhandler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/imageformats/gif/qgifhandler.cpp b/src/plugins/imageformats/gif/qgifhandler.cpp index ebe5964664..1aef1a24d2 100644 --- a/src/plugins/imageformats/gif/qgifhandler.cpp +++ b/src/plugins/imageformats/gif/qgifhandler.cpp @@ -213,7 +213,7 @@ void QGIFFormat::disposePrevious(QImage *image) case RestoreImage: { if (frame >= 0) { for (int ln=t; ln<=b; ln++) { - memcpy(image->scanLine(ln)+l, + memcpy(image->scanLine(ln)+l*sizeof(QRgb), backingstore.constScanLine(ln-t), (r-l+1)*sizeof(QRgb)); } @@ -426,7 +426,7 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length, unsigned char *dest_data = backingstore.bits(); for (int ln=0; ln Date: Wed, 24 Oct 2018 18:53:03 +0200 Subject: [PATCH 0204/1650] fix configure instructions in libpng and libjpeg attributions Fixes: QTBUG-71379 Change-Id: Ib1efbe0fc4407ccf6ab814229dc4a08d9d03b6b5 Reviewed-by: Lars Knoll --- src/3rdparty/libjpeg/qt_attribution.json | 2 +- src/3rdparty/libpng/qt_attribution.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/3rdparty/libjpeg/qt_attribution.json b/src/3rdparty/libjpeg/qt_attribution.json index 57c5001f6c..8fbdfdb9b7 100644 --- a/src/3rdparty/libjpeg/qt_attribution.json +++ b/src/3rdparty/libjpeg/qt_attribution.json @@ -2,7 +2,7 @@ "Id": "libjpeg", "Name": "LibJPEG-turbo", "QDocModule": "qtgui", - "QtUsage": "Used in the QJPEG image plugin. Configure with -no-jpeg to avoid.", + "QtUsage": "Used in the qjpeg image plugin. Configure with -system-libjpeg or -no-libjpeg to avoid.", "Description": "The Independent JPEG Group's JPEG software", "Homepage": "http://libjpeg-turbo.virtualgl.org/", diff --git a/src/3rdparty/libpng/qt_attribution.json b/src/3rdparty/libpng/qt_attribution.json index f9039a50f6..2f82b4c1c6 100644 --- a/src/3rdparty/libpng/qt_attribution.json +++ b/src/3rdparty/libpng/qt_attribution.json @@ -2,7 +2,7 @@ "Id": "libpng", "Name": "LibPNG", "QDocModule": "qtgui", - "QtUsage": "Used in the qpng image plugin. Configure with -system-png or -no-png to avoid.", + "QtUsage": "Used in the qpng image plugin. Configure with -system-libpng or -no-libpng to avoid.", "Description": "libpng is the official PNG reference library.", "Homepage": "http://www.libpng.org/pub/png/libpng.html", From 3f61873f497286af1bce97883f30bf9a520e6a75 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Fri, 26 Oct 2018 15:32:50 +0000 Subject: [PATCH 0205/1650] Correctly document value of QThread::currentThreadId on Windows The implementation calls GetCurrentThreadId, not GetCurrentThread, so the return value is not the pseudo-handle. Task-number: QTBUG-67686 Change-Id: Ifde0cf603dcea01bc1c454a8bebe1e5c0f22617f Reviewed-by: Paul Wicking Reviewed-by: Thiago Macieira --- src/corelib/thread/qthread.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index d2d6435004..d3f60eea4f 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -298,12 +298,9 @@ QThreadPrivate::~QThreadPrivate() \warning The handle returned by this function is used for internal purposes and should not be used in any application code. - \warning On Windows, the returned value is a pseudo-handle for the - current thread. It can't be used for numerical comparison. i.e., - this function returns the DWORD (Windows-Thread ID) returned by - the Win32 function getCurrentThreadId(), not the HANDLE - (Windows-Thread HANDLE) returned by the Win32 function - getCurrentThread(). + \note On Windows, this function returns the DWORD (Windows-Thread + ID) returned by the Win32 function GetCurrentThreadId(), not the pseudo-HANDLE + (Windows-Thread HANDLE) returned by the Win32 function GetCurrentThread(). */ /*! From d16babf351e11c9bbfce57a7e92ae06194d9dab0 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 22 Oct 2018 16:37:09 +0200 Subject: [PATCH 0206/1650] Update sha3's brg_endian.h, document provenance and version The existing copyright notice gave me a name; github found me a file; but it doesn't match what we had before. Made some guesses at which parts of the change relative to upstream to keep, documented the diff as a patch and recorded details in qt_attribution.json Task-number: QTBUG-70008 Change-Id: I423724435eaeeda7237f8b3df8691b436fed8652 Reviewed-by: Lars Knoll --- src/3rdparty/sha3/BRG_ENDIAN_LICENSE | 21 ++++-------- src/3rdparty/sha3/brg_endian.h | 47 +++++++++++++-------------- src/3rdparty/sha3/brg_endian.h.patch | 34 +++++++++++++++++++ src/3rdparty/sha3/qt_attribution.json | 8 +++-- 4 files changed, 68 insertions(+), 42 deletions(-) create mode 100644 src/3rdparty/sha3/brg_endian.h.patch diff --git a/src/3rdparty/sha3/BRG_ENDIAN_LICENSE b/src/3rdparty/sha3/BRG_ENDIAN_LICENSE index 0a4fdcbc3b..175347c263 100644 --- a/src/3rdparty/sha3/BRG_ENDIAN_LICENSE +++ b/src/3rdparty/sha3/BRG_ENDIAN_LICENSE @@ -1,21 +1,14 @@ -Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved. - -LICENSE TERMS +Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. The redistribution and use of this software (with or without changes) is allowed without the payment of fees or royalties provided that: - 1. source code distributions include the above copyright notice, this - list of conditions and the following disclaimer; + source code distributions include the above copyright notice, this + list of conditions and the following disclaimer; - 2. binary distributions include the above copyright notice, this list - of conditions and the following disclaimer in their documentation; - - 3. the name of the copyright holder is not used to endorse products - built using this software without specific written permission. - -DISCLAIMER + binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation. This software is provided 'as is' with no explicit or implied warranties -in respect of its properties, including, but not limited to, correctness -and/or fitness for purpose. +in respect of its operation, including, but not limited to, correctness +and fitness for purpose. diff --git a/src/3rdparty/sha3/brg_endian.h b/src/3rdparty/sha3/brg_endian.h index 7226eb3bec..09d2a8b6a9 100644 --- a/src/3rdparty/sha3/brg_endian.h +++ b/src/3rdparty/sha3/brg_endian.h @@ -1,29 +1,22 @@ /* - --------------------------------------------------------------------------- - Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved. +--------------------------------------------------------------------------- +Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. - LICENSE TERMS +The redistribution and use of this software (with or without changes) +is allowed without the payment of fees or royalties provided that: - The redistribution and use of this software (with or without changes) - is allowed without the payment of fees or royalties provided that: + source code distributions include the above copyright notice, this + list of conditions and the following disclaimer; - 1. source code distributions include the above copyright notice, this - list of conditions and the following disclaimer; + binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation. - 2. binary distributions include the above copyright notice, this list - of conditions and the following disclaimer in their documentation; - - 3. the name of the copyright holder is not used to endorse products - built using this software without specific written permission. - - DISCLAIMER - - This software is provided 'as is' with no explicit or implied warranties - in respect of its properties, including, but not limited to, correctness - and/or fitness for purpose. - --------------------------------------------------------------------------- - Issue Date: 20/12/2007 - Changes for ARM 9/9/2010 +This software is provided 'as is' with no explicit or implied warranties +in respect of its operation, including, but not limited to, correctness +and fitness for purpose. +--------------------------------------------------------------------------- +Issue Date: 20/12/2007 +Changes for ARM 9/9/2010 [Downstream relative to Gladman's GitHub, upstream to Qt] */ #ifndef _BRG_ENDIAN_H @@ -32,7 +25,12 @@ #define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */ #define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */ -#if 0 +/* This is needed when using clang with MSVC to avoid including */ +/* endian.h and byteswap.h which are not present on Windows */ +#if defined( _MSC_VER ) && defined( __clang__ ) +# undef __GNUC__ +#endif + /* Include files where endian defines and byteswap functions may reside */ #if defined( __sun ) # include @@ -42,14 +40,13 @@ defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ ) # include #elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ ) -# if !defined( __MINGW32__ ) && !defined( _AIX ) +# if !defined( __MINGW32__ ) && !defined( _AIX ) && !defined(Q_OS_QNX) # include # if !defined( __BEOS__ ) # include # endif # endif #endif -#endif /* Now attempt to set the define for platform byte order using any */ /* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, which */ @@ -134,7 +131,7 @@ #elif 0 /* **** EDIT HERE IF NECESSARY **** */ # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN #else -# error Please edit lines 132 or 134 in brg_endian.h to set the platform byte order +# error Please edit lines 129 or 131 in brg_endian.h to set the platform byte order #endif #endif diff --git a/src/3rdparty/sha3/brg_endian.h.patch b/src/3rdparty/sha3/brg_endian.h.patch new file mode 100644 index 0000000000..395133ad2a --- /dev/null +++ b/src/3rdparty/sha3/brg_endian.h.patch @@ -0,0 +1,34 @@ +diff -ub /home/eddy/.sys/tmp/sha/brg_endian.h /home/eddy/work/Qt-5.12/qtbase/src/3rdparty/sha3/brg_endian.h +--- upstream/sha/brg_endian.h 2018-10-22 16:27:04.106128670 +0200 ++++ qtbase/src/3rdparty/sha3/brg_endian.h 2018-10-22 16:30:35.098891562 +0200 +@@ -16,6 +16,7 @@ + and fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 20/12/2007 ++Changes for ARM 9/9/2010 [Downstream relative to Gladman's GitHub, upstream to Qt] + */ + + #ifndef _BRG_ENDIAN_H +@@ -119,12 +120,18 @@ + defined( THINK_C ) || defined( __VMCMS__ ) || defined( _AIX ) + # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN + +-#elif 0 /* **** EDIT HERE IF NECESSARY **** */ ++#elif defined(__arm__) ++# ifdef __BIG_ENDIAN ++# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN ++# else ++# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN ++# endif ++#elif 1 /* **** EDIT HERE IF NECESSARY **** */ + # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN + #elif 0 /* **** EDIT HERE IF NECESSARY **** */ + # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN + #else +-# error Please edit lines 126 or 128 in brg_endian.h to set the platform byte order ++# error Please edit lines 129 or 131 in brg_endian.h to set the platform byte order + #endif + + #endif + +Diff finished. Mon Oct 22 16:31:46 2018 diff --git a/src/3rdparty/sha3/qt_attribution.json b/src/3rdparty/sha3/qt_attribution.json index 4866be32ea..a3122b4e7b 100644 --- a/src/3rdparty/sha3/qt_attribution.json +++ b/src/3rdparty/sha3/qt_attribution.json @@ -4,13 +4,15 @@ "Name": "Secure Hash Algorithm SHA-3 - brg_endian", "QDocModule": "qtcore", "QtUsage": "Used in Qt Core (QCryptographicHash).", + "Files": "apply brg_endian.h.patch to upstream from https://github.com/BrianGladman/sha/", "Files": "brg_endian.h", "Description": "SHA-3, originally known as Keccak, is a cryptographic hash function.", - "License": "BSD 3-clause \"New\" or \"Revised\" License", + "Version": "https://github.com/BrianGladman/sha/ commit 4b9e13ead2c5b5e41ca27c65de4dd69ae0bac228", + "License": "BSD 2-clause \"Simplified\" License", "LicenseFile": "BRG_ENDIAN_LICENSE", - "LicenseId": "BSD-3-Clause", - "Copyright": "Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved." + "LicenseId": "BSD-2-Clause", + "Copyright": "Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved." }, { "Id": "sha3_keccak", From ac4d954cfba98b1a6abb5c8cabed6ee32a43560c Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 22 Oct 2018 19:42:12 +0200 Subject: [PATCH 0207/1650] Update DejaVuSans.ttf from upstream Document the version in the process; and make the wordings of copyright notices match those in DEJAVU-LICENSE. Task-number: QTBUG-70008 Change-Id: I1c965e5d7afb18dc4dbdffed908512c5771ab717 Reviewed-by: Lars Knoll --- src/3rdparty/wasm/DejaVuSans.ttf | Bin 493564 -> 757076 bytes src/3rdparty/wasm/qt_attribution.json | 5 +++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/3rdparty/wasm/DejaVuSans.ttf b/src/3rdparty/wasm/DejaVuSans.ttf index 7e411a71beeb3087ff9a23027dd5aeb415766942..e5f7eecce43be41ff0703ed99e1553029b849f14 100644 GIT binary patch literal 757076 zcmeFa4SW^F)jvKn`*PoJ?#*4YS0E(37~UcxA|fIpA|mgGh=_=UH+cyWBO)RoA|g^s z5s@MyMdSgBNRc8UMMOlT7A+!DN-0I97z0Jb2nd+_`_7rY$%X*Mmp+gG&%bv+bN1Xb zGiPVcoH=uLc6OF=#+U`5v)1j}<#xXRt&*dR@lK#tzq##A?PmRX`a%33%$S&UbGNSD zdra7T6=T{N#^z7Gx%+Kx-rC;!4#pNvVXVr&&Nt+?U(%%cIL6i@z1ga3_sg5yaoMQL z7~8NE{Ce~so;PCSEm=U{M6j#&A2l+Q4N1R-v0c@1jnY9Q?iqex(@{ei+l~M1rF-)3 zAHh60*zT?PAG|03p+R}U6DI!eWZs7l3?7&_Ab61PV!qt9h;KF+gwSs?{)GRi1FJK5 z_{hvAo&C1{M|spY>kLd~237cKw@OQ;~!2cw+ z0e@e72z-b52>4EM0Qf(}7r=|f*T73e3Gi>kH^7gJ%g zxJUB<_i8@ie$5X&pap@4benNKu2*N8o^FH~H^N4k2_wab0FN4%FwLlHR0Ce!r~y2~ z$N-*cWCE{gTnaqP$O2y1=m@-%(Fu5Gqbu-kMlSf=X50^aq%i^XM~xZ4pE8~TKGTdb zZdxX;Yo?pm18;4%27ZIt2KbF;2jCseTY=}8w*&9#J;Av5r1v|fc}oK|7!PCwGMETt z2I>QE5Xc68S>O@i69N-}KN@%n_{_i@rUjl2JPXR)!1JKY5BvuBg1~FQ*9Kk(zAmr> z_(y?{fbWc=ahz(2D;1AZW$ z5B+P3SI%f{pt=JjKf^9qL-u%-P9^M^?#@^pY6V9;Jt;cbL?iQ<%q|A4DXi;^sjESpjGPsaG9 zwPVc*wi=#SIE9^!BuMDH0QhzXK)ab zF3-Dh)}g6`%yuXNQu@!}KhD8H>Rhv>qStDn{?|TG!~pJ;@Vl=OuNk9^hm7$q zOll15I?^*%Ri?wQ0%UvG3dXq!&K4xnm^EW9A(Qs33#8JE^<{$~mqIq0jfZ5WvKeeP znSe)-k2D@I z9yCT9V~mH5vBoo3b!6fD+6`!Rcx{kT2Zegf9(`=pi9$wBCe&<9}v0>*hZ0$~)w zScHiP7+2YJgjoo45f&gUM!aa7lUDgr$_QfNStKD^ycN>)L{5`5tSZZd)@37pl8G_=yL``sXTd?9f@CZ+ zF-G2Kwl!}u+nKlE8ft8WqlGI}MaV?RLdZsFg3w&@($S`X(AYBQrU2)?I5eNnLaA#1 z8?9W(mO__Tvvq7E+rqZ79c(w-#}2S!c9b1wXSm>A9_HvdrR=+X<*>Ah#1;H*PdVF~%tWj-2v<22G%r!h8zM%S9;bJao~-&uM70?Hob3{lQB%2}0irc=%g%9+V( zqV*;tOhcH7Fb82i!Xkua2rCiRAgo8&gs>Ii1B9Ijdl2>`97H&ba17xjLMhY`_K`y` zImSVbah1c%=Cu&&Av8j0iqHa~H9|Wn7yN!sP#V|oT^`YfLl?z#=ywa)nz67mQ($9e z!M-ejZCMVxvKBUFGkcG1XS>*5_9-i3M_36vB|9|_@>Cw@HFzD~fH&sNcuU@fx944W zF8WPhK8WY@LOz<0=acwUK7-HZ^Y}u(l&|2c`8vLlZ{gcyiOs>4;B`bH?KTx`TZ!_H zq6?C<+p1PY+*C?}ioYA0)JG+SF=>A)LvV1H+>N`h z=%!x~H%`h@{TukVv(uP0(8r{gj6MJl_y|iCM{#!)qx&M8{NOlwz?YEkTb;b#8gv(w zLH9p3>5if{-6zzCcV3G%w(Hn+*cEmbJoP5zmtTWx1i$Y!h;Ih*y_CHEY~pn_Y%+s> zF=!ZrjxlH%W2d0hIKe}JbAynI5J#wiPzRv_LSuwx2rUuXAhbv5f{=^Q3!yK;}IqyOhuT1FdJbW!a{_l2rCd)BdkN%h_D4=8^R8R-3a>-4j>dG97Q;ea0ZeV z2wsFRf`w2OArm1B0b^My(;uz`F;b&_F=m|~o+DRfK14Ymp9&n#bHxg2T-+4>VmO~K zO=WuJYyA)ktP}i4*!3X%(p2~z%`i&$g3mY}zM{M*f*+#wPrzqnTN6Wn8VZeg6*yO> zoab8Vju)!JQZRpzYQzl7sA8lUwh=cjk+TSxF;G6Vyt`y1suR^tO> zr?JP_ZyYoZ8^?^3MyaWreludGnbpl&W<9f!+0<+SAFrL+39}wO%|7M;bErAO9A%C* zCz?~t>E00Y|lK;LeEmq3eRfKI?qPW z7SA@%4$p4SKFdTE2R|M!u%L7QWWLcD_!&9A8ggAKw7qP~QmODBoD$MBfzObl)uBT;BrU zV&8J#D&Jb)2H$4id%o?yUB11(PklwcBfb*fDL?a@{-8hAANSYr*YP*-H}*I4xAeF1 zxA%AP=lXm3`}zm@^ZkYX(f;xNN&cz+8UES+dH#j|rT!KE)&6z^7Zg4?xad3HXRd8)^LvVBO zz2NrXuHfF_r@^A&kzh&iREUMlP%xAliic{1>Vz7E8i$&NT87$$+K0M?aznjBeM5sn z`Juwl=+OAkq|nsRjL_`RywJkX($I>~>d?B-#?Y3~w$P5y?$Ex_flzViXy|z8Ojv}y z;c(arR}E)|v%=ZoCgJAcR^hhc4&iR$9^u~Me&NC4g7C=jnDB(~{P3di zvhd3An(+GYrtsGA2jQLJJ>mV~gW<#BW8stG(iA<#pAtz)OR1hxE2Umaqm-s8EmB&i zv`gufl9SRirBBL$l%XjjQbwhWO_`W7C1rZbtdzMa3sM%REKgaLvNmNy%I1{!Qnsh; zO4*z8X-ZMbk(82@QxO(1Bf&^&Bp#^|sS{}sX&h-5X&Gq~X&>nl$&K`i^oVW1e|!|shd;ZOWmHjD|K(` zr>RA$M^Z~tPsLcwj0Iz+t%e=Ms1JCXg#2%WpCtGaQKZf0JiDAC-jX=`C(&OddQHL) z6TX&Usf6VFaQ<6~YY~ED6Q^*kxs>KsN<%3{U7~CzC=D~$;AMB%bCq0$ZjVDV^rJYpT2Rxm+ zD2l2V;mI1QdR+jP)fC)N1}QNGl^nhERO?8 zlG++-FPBuyWGh=XlO&LYki5eu)5%pS4e`(X4(+J<At-72uIG@V_*VOe3hh6a*zT zNpY@AGC!Xjlr}o><1=&1+C7bQ`xeq_>Sdx2QJ#0fzU8CuClqye=)eAzM!C6m)vD=_Z{AlERup`W0j>9x3WCYXE`cWNMBB`F!s5%^gQ}m!Jbc*B^L_1$IA23vnaiS?(}ZDYi#A+N&gAD z$J`3^sietj6sDT;BUHQd(9ti>X&=;>0x0bpwaYo|iA(3v?q#C}$|JoIf@+j^#(HC=^J$V=CYnzaU;5m4b z7AcK#>(#|kT-MU1T}qN}8LIkL==Dx|l2SU2UoI$UBy~fsd{-BAMp!k@RvvBDSXmkN zrE$;=E2UARvm2_B+6|piTaDeW5nRwXuAmyt-B69}Zm7{H?}lm|cSDUve>ZeI0e8tK zP`z9bD+Qzv;D#=L!0`>pb5Q<++lz2t-SH?~oZVhTWlzKHb+~cI15tiRC2yoMPennm zIk!)H!7*3$HD%efBJvLjCMo2}7t#F%SuKrl1)VgR%Bz&nv5@Y*Pd2TB)v9E#l*jA# zBF;sj@x4UZD6)H%dUWMJt~>$0i24pehvKqk$|@>PLqU!FXLuCS9uhoPE?HkbgRBt2 z%4yEoyJ0yi^mp>N9Z%pElD6l}Gh~J2od}JXn&(V^!pp3aIHGK6nJ+3>2& z@5=Q#e5-vl-d5DYJzM0$Gn!^Kxxxg`_8Deq8J_ksJmF`Ut7WV&!XSiv1kBIlX+OjK zEyELkhG+f^Gr0`U{TV&^|BuaU3bk6M1kY|co;n1X%`R>=Lh`vU7yU8&%K3*_!^YV$ z3Hfpf#j`|du2lowBFd{oF(rjRB5{77z!NAwgknFY*doGTBDkAh0gFR<@x<+Y@Ej!R z{D6eoP?;C2} zTio`xCd z^Q_Q_ZK$+HL*6BRKmEgEPUOM!Av|?pc-GJGw4bq!2wM=gA>jECp8I3wU9K(o$<|-| zAa1cvsYkFfZyILmd+Y1;jrtaSo4!Net?$zh=*9n?yZ`Up{eS1~|2ud8^Panh4b34- zdI`bq67qDXX_;9{zzCn4pXK`CcQ zT&%}B2|!BIQ_BQi8Qv+cB?#i`YRqu0>aL*HM+BoWeJmt#Mta){^c}lq3~> zlgx#BEh8v-u9tO0?Wm4QN|hm9WxbLl!OGHeQ zSi(0^yQdjP!R;0a`AdZNA^5xt_ASTxe!^oC@&ba2!xF-OE1~u$!v9WqZ3)Hm#xcMN z5^93zRf#@JLQW}Fthl2*R#R!JQA(mavDBNCrtyZPGX#@*SWZ!~=cg-;m5?{2-byg3 z=jWiSULYmhkhGDYTSIt>)MsJJ*z?ley}l>4qk=yXy<%^o7FWF~*^j6vTQEx%9eHK4wP%a z**nrADcj4l$!a-J#`0_h-D#wK0A0cIG@D5G(mmS|>p<@ui4$~MlWL*H8rO&;dg@h? zvLVSqL06jd^#zO_=mjE6LZrcnpdfFkxJh`vevur%T$=oE^jVf%OeNS;j#((P9J$=1 z0F8jW!Z=7RrAEWbW8ze8lH^IyW!0fSvdr_E znCqfD<8KLRh#HHJC|va>*XVqNYV8_j(08D*!X(|GF_)L9ak-q1KBC4xKzDykj_G8< zT;(Yn<Ntcy&e2kuCX%(DG^65zyOu=(d&epo5mnCbVMqb{Xd^v*fzGP_| zQo9gDUC_rJDW%i+<$`J?bwf3(x}i`btQ$U0W88(I8in1kQhGHyyP=?w+6|piTaDeW z5uDRFuArdN+zmO6>~5$=c{fz!xEpFT`n#dy2`GQST~rxcR$rp*#>bba^9gZf?ASHB(-01rJtPGdCp5qsC&gNU&Pc z>JoHpS0yWV4*PZv%jW33w7Sa6bylyVh=h?()f*H+gG0!Pzc3Y#_?YcC(U7u#RN7L-~Y?|E` zG`l^SX1AZB+3go;c6&L^Zof>k+ju(|bL8ipS;U*VRj^LgHsj_cW>vHLIc6GbU{-Jp z!UTlL2-6VcN|iYX^AQ#yEJIj{um)j0!X|{R2p=HqMA(C{AK@T^Tt9XUL9RY4WfyvP z<)@yBr1k5V*Tm}Zi-JFB<`S#@k3&l$n14>ci1z`LGw^4>dBu&pARi9hm+(;uwY{a7 z>o!b9PqYR;f$%#C)*@J+=&cC9i68({DtKJtrb;=U=nB#^Lx-EXViSs`Re{C=iJQM9 z3a#%`rSi6r6oPm&)U0h@hiUkJW`8E16=?E(Ir+9X(u5H#1lT7)8T}SH=0X{0BwwG{IpIb(sppOB5r;fgC)Y9=@ zo>5;P4A_cN-b9eexf;A6+YRuzey5Zf-k9gcc!?Y1jgf%QQyRrhU9pMOEF*>J3-no1 zX8IIRBKiY>qxBiG=6Z)D^tO<(1fh&D$bec*VUe0ZI?p?>tb&qW(w&Kf4UNDH6}5_Uwf+(A$#ojY+Y% z6rLE4-{N`5x!;jH;JhPu{MYEI?R{upD6(!diq42%8b!L)eb63t=z9 zrwBy|M-WO7PB9b)0e$8NzJY`HTI4(INhq0>0uZINobFEZAIHnDD}KnejFtKa(8slC zxjDQEZ_Zosw!8!H#(VJIydNLT3;0MrhEL#=`7}P0&*Ag=BEF2TSBgktV8(TG$7pk!UJfh}NQ==p=IB@%Iq}#85Fpj1ptTL@`B7 z7qi4%u|O;q%f%|OR%{TP#d~7A*d_LgPel>l_$m>nu;YcP1+`QyuGP@$XbrT+S~IPs z)<$cubn=RZJ%~P zE7p!`$F(!M(7k$CxAdxdrkrM3LdMmxH-a+rC_t1Om{q(_lfj&|nqfgK$>(lg^ z`W$_}zDQrDuhiG*>!mtL@B6>-zY_Sb1bzk*5bRRCIS0=JW8YmEk>=uPiYMFa*j0G0 z{Vv|A+s;13`1m!B7Q7y>&#vV+@Eh25c-OZ*YsGKnIqZ6V2fu^e!1H(>Yr`Mn53?IZ zsz_z+VA0ap&7vAsDYX~rBAwkL8i)q0gSc8;%{q!)k;^)1)v#)zv-d;qhpdaw>x;6k z(J!Kh*d5U$(Jxu==r_@CSfA*((NpYhyvOk+%Zqtq0oFejja6g!;7yLYtT0wTb{QKR zYZAMPJ&HFv+Ox-FonqbCOuM_?o&6fNMqpPO`TieceuT(b)~6rVqj302>Mg=Js{wf= zccb8hL-|Zm4tMW{q#j}4d;|^{=5^^-xI!P$7?gVhYgz~+4Kw7!S z8xl@Xt4nDX5|n-h7t$Ny+J}ToPX#Mn2+o$!Ss$3;!qX`Beu8urF^+JX(x@v|g6g_l z@u>s_aZ_c`6QvVmc_b9742qk|brHDY=9EglwaJ}YOP|Y;i9?~ftE-49())8HcEM|j zCy37`2}KS;>9unCW;7^DGWLbIIajBY=EE|V@sNb(RfJ1Fm}}QcDBhRQX+b4<)pn|V zXHu+^iMskY@?q~lFUn$dSv}Se`))L5SHRD120L;c>`Xg$GuDB1#GOhvb}Q~ydfL7>_v;7s!}>A( zq+V+1hTn+bz2WLcEzEi}GMZvtS8Jmk);{GJJ&iub0Ar{z0&fzJH6|KUjOoTKW3I8l zSZpjeRvBxJ4aR2UJ!8AE%h+ptY7`kqj1uFNi7iyjpqYwUj2dPgvw_*zY-YAJ+u#ng z3+|PA;eKk6nQs=Fqs{T=By*}c!<=o-GZ&gm%@yWqbDg=-++uDscbL1)edYnP*gR?; zH_v#4$Lk4uEKgNWrYFmj?P=m^?rG&|>*?U>=IP<-?dj(k>?!b!^o;RL@J#kh^UUDlAi?>Xo>>^bH+=_&Q5M_U-c>@D=-x`i}d~_=Vr=5Bn{D zRez>G%b)FU;&1M67<^RM); z@vrx9@^AHj;NR)r_biaqO-d z)6{h-m$IOukkTl7Pu5zzMwCSa-6Ni|yEGRdXgo}gT2wYgAxo@%L3xSdTwUd&kwlOM z6PL;~T;9!dXGH2FaqVWJ^ds1pIA6s0seLBXC(Cm-?(kO21*uf(>S8G6RZwy3M--(kG{QUbCw)_X2lq&Bd;&r0 zJ2ce;503I4kx*%@_JzWUu3FH6GOyBPooa-gJtakHHTfpOfif?zP8{+Ge~eO&B&b@P z-kcV7DVEBhO2WS?r-(4&B@#N?t7Pu(BZP|q#F@M*r)N1hagek3T(ppoJGi7f?U+Zg z?FlM*zL=1++|<_MCA#|E6svqd7dNd`(zR0Jrtq63u1_a=ro|upiC4s7xMro9zV=l@igtsQBVtYzly{RK65}nG!Um^UBN>F*1 zGl;IBy4F2Jp)xpDOIa$ChM=oB?=2}kaod^0rMN2-g9sij#g1pdB|I#5P6ICCVY%NL za6q?(apM|UcrNEgozX;ZLwF9g%OEOYSVHW&3#fJr(6T8_Q-XCUC8bfa#p(&kZ4N=z z`llo=#+38aC@()j^evQ<+8xgWWnLvQqVunD?9beM8!%3_?M^aF{HvV_z_ z)fnfDcO-3PIh77LecYuR>RwIhzf+6*N#B$;dpmIeWl$}pMocxzC<^J7c#+DWdNJ8; zzLO|V6Q2zdD#;rKlCH-j)C9$nmCzm}d_KVrr9E&((mewSk&^Bs^(zSfi-h_+<#f3} zGt!JA=-{#^Ch3Z^j1?;=%`*~my2}xNB3#j3_eSn=I+7$kRHK`=S@Lvxlj_}nBR4 zidF5tnsDM=!QXq3=ojt#Ib#q>6+3(3Ue2+K?-Cz5W(n4p#jr~yqZuzh&3M(pedkkn z_9N%L+TiVurR+xBf38BDoCCWBcc5?MiIAKL>qs+UoiVrbG3$z_Bwyn075AdJcRhup z7Z33eyAyY&DXcfI!mF^mXtt~m?o=;heQC}tkKe>^V*P05tUq?j>%s=m{MkV4nU~A% zp;@%SG>bL_yXWPzp?nk{#fH(0TE4u$W%uF^_kDIBKh96G2ZSMlY_tfA4r~IR6x_q! z5JT_=iD!*gv$+T4%Ojds2IneWE?5J;y%P4rzzkXSzrC zvVZEe_1f%ny{X=m73o*&SF`JjQxv-u*2SA-VyAG_kQogti=0>_c8XJ_X+Pb zF66u&_sV%Y?vwY~JSOk7c@^JD-?!WjJQsM5UlMpRu$Wg3EDbEiz=ymsb_V(jzY6>AY~$BN_eS^f z7SVmtfADLgpG1%G>!Kym zYsSRFnvYB~%gi>LnCIG|OwE@}GiRD}%=!Q4`;%3iEy?xv^7i!(^5%OBy`#P3y_39C zy)(SCz4N>ay-U3-ysN$Iyc@k+yxY7xyt}>oya&9+{|CF1{dcb9qUK6Mn?hSdAB1*> z_JsC_4u%egj)hK!O2c~CAC836!qvmI!u7(9!cD_1!mY#Y!kxl7;hy0>;Q`^H;Su3c z;j!U~;VI$i;aTCi;RWHv;pO2~;kDrn;mzUq!rQ~U!h6G?hKs^S!X@ETDJ;cI38ti` zR87fD$x6viX_C@BrBzDXlnyD~QhNN1_aJNkK zDK9~-6XAym&M${rZ;7k-M)>6t=Z(r^c>{{QpD5oDUbj3}Q}{TdJWWugJVLm-F69#M z6Qz*g20$S?VD(RJ>9x_nMfhi<9HsPcHvXj|PQ4E^6#rB@`84iw;0n6d)M{VIG~!7> zA?^pnDjTtwX!jDd3D%X6%Qs(y7zbQF>+2(F+RYT-k6>Sdlta}}`-~`xpRBFA2G(ae zD|%&3%W6b*;My|KIKNfK@O0#-^*+Q$mXc#lg)A}2i%Nv~2uX3)7rW{vR0~o2Dc+)| zL9yV^t{&SE0vaOCQMIaM30Rm`eI zmBeJba-k%x@YzI}BI~6}%TtI#5>U0~86*eN72(nwRU`3Bk_l;~YV`^_r>^BL!xO|U zm*6hSD{CS62f#Iyj@r;^A*pM4lb_P<I~!W9iLZ_1!DOl@_}pX|&R7w|0l2KO`BU^nNjw=t?T@l`fogTjUXa z1YLO|;nxzpm7u$=Re8Unl!S{g;YtUnW=cyd^qM|&#R0@kwMZq%S5lf561s7xHB|}Q z69-k77wNjx&&5j$r&yAG1r8)dcZ+H_%d6uBhsz?3%PYT#TpkDEX)!oow}+ zD26mtkY(c$%0VS^`i;`EG@`5YN;V{8M<+&7tfDJjsY;Y(1eLBxtH(7}3RNNn7f=~U z=Nx$xHz(zn#6ejjf)#p(q8yWH9P6ZXzCH1LT0&(N^p7R3Q}1zlzv_iq2=IA2mj(9{(JrQQCA9N$EI2>MPoFgsc9n`hjYrlaj6(6szc})t)DcOU^=Fr7xu) zM%Pm9s8V($`ftl2-Z+w+(ATsuV^z9tS$>56nMjpU&8 zfqzZXAUmeyulQ?|h+a$P)v49A*~BfI_{dSRBHg0&ml~%~W@>hd7?%?L2?tSe^I|vZQ(A1P_3!F2qklBHD|0syPG)QT!HyyCf9* zh)x=zH8tehe05}rv@qy`S^%Duqe*ip?cFk!I7M&_QHU#YOMdU^Z2{>D+H^_LJ5d@n zny4#(ZG4V2&r8V1nb_?{oSZ z>?F8a$_#t|Na(&-RITr(To@;r@EVej^MezPh42@Lj~JdntVMf<1JO`F1(e z-U{>Vzh&2Bo_!U&fo9s>X)#y%Wu@ zcji~|t5{deuD4;`Xm&jZv+K98?lil8n_QF6dhniDoq89)li$Ve<~T3|FITGe$2V#Q zVFrE(AIb(|zI_B{;74NZYCd1im$Q+WWB=BfV}FR|*dL`i_6;=0zK7=6|4wu4`?Pji zAIz=~#1og3+E8sMJB4-i`Rue-pcSw)+6Zj~`wpw@N3&AxaqSl@q5V?(B{#LFw5Pa7 zdscgnd$sx6Z+Jjkq`k~T+V8aYxvl+KJHVT1UuZ{pC#^&mJXbe#KktuO`Z|1w-cZlx z!}QDbtNC#K2K@#;O7Eg~;ScI}=y&kZ`rZ27{2{%+-k*<=bNKvWtizwi$LUY&v-o&@ zslJp?(0{M5=8s}U{u=(6zE)q$Ct;p{1b-Ye{A2laIm6HA$nO>K=P@TZgD;|a{{O*O z38H*4&F!zCx&4(ixBm*w?Y~NM`)g@#|8<(%f0O3+H`3hxTQs--HqGsCp}GBcX>K1g z`x}-=uz)dXS$<{UY@X z!BP*U9ui#6`3oWE{Dm&({DoJ}`3t|C^A~Bc%VU>|tk@N?t3=&ci&!_2Eoc74jdJE+ z^pG?E;&wUnFM8TJcCP3rXa2=NIrA?D*$>$diF@p^_Bb(EJ_Qg%DWV^Lqe!E;5t zYwj7PxJZ!r}CPx`U`RnVGfeAlqT8PBraYo%Ry#dH|M zTyY9lDbCL!nPaMUFXb+DL0G%esk)*_oJsrlW8imm_gVS~@wtH@`Fm%Ie;Z?5iV2eEdS>$~OntZkG~>M!tm5<07)<`KRjfvai1r&#C!egqsNMWG5Qo_W)w;MRB(ByvXX^dR-dM3b7bDl#7;nnfAk(^IT5}xz0`DHk^~8S#WDM(xzbnC6 zWF5u4AFJ88b|&7h=myIFCw_^K60bQ0?TB4Eufel$mVks3QxY#H<|abttVC9ln)su{ z5_^;XoipMSADu;GlJocZp=5i(8S4oYe+h}g5_!PJC1717rl^QX*2A41wLts>Do$~b z>5+-}N`B=>885|k1|*P&yfTHnqQqZL%qTsX(3o6TQTB6}&*9DzZ^>)QGG5FNsi}5n zr&XL4RhC0yNm`PB^1qYnwZse@sP)DCD&{?Zj^wq^pW@sxZvHO3On=I2b9R1}`l99M z$flf&>uTl1N|>8}5{KUXQT715g8v%YoG^FBvt^-DsN9KRGG*d5=j^n8IgdnJnGW$Y zfK}j}%ulTf)%7A0#N#UR)bo z9M_*N6{M;9CfSRhri?$S{ABs0mefzmFsTcmkybz}Az#uIX=9XCaJ6*8!OPCW5^~ib za-*DxgI#x}{=Sk$>E23~4CjiLkYrkV5Ld{M+FE)v$=xmIBwluQ^#n=#andZ!`|coJ z^%_{~N_N3r9yNv}DHl2?OM0O+7aK?88fu*Qs1$NkEpxuSauiK0lCi2!(|_0kRj=|= zC9%XJr4`Bl=i_@pdKSwnmF*~3^8E~dBtPggT37ZIIliBz&C>d+F;GfZc_K=Rsya!$ z>?}u2sdsb18`6dpN#;MS@(J`dm;7C0-4EmUpUQ<1D1=@rJ)5&e6IbbR@zR$|Aq^Rj zl6rpWqSB8_A@@>PAv(Y1jB8U8(bD~(m6U!iQ>#1@`+h(4jFT6eqheVvHrG#)E-?k3 z;2jnF@3~6j_^6OGR6E2v{5HAK*Do>I%4$oj*U%3<o$@VSpwaQzPd7QG)h*puug?pqUJ=yPn zM9)=Mg!Eq~I~yv^D?Lj6qfCb9lBSe3YD6QQl1p;bOH@hL0sV|@Qt3e%2d-r?$rKlV zmTf`uJBO4mp38qOr5u~i)enB?6@N-z?lM4*!+xwDL*L}MK_jx8_m9GF0LSm4A4)#% znj~>$t--CVx5|>r|H+siRnDJjX0+-IvI1E@jpqE+vXWXye#tnDnitiF$>WipAf-kd zVrHaV_{n<#MIp;YqYTnJXUuGUzh4hIvSU=rJD0uteyp5Q{lpf*v9@$K{X@!gcAlTs zVnKFv?{@Z8&i7xord!M0_}O`6Tr%FR1!t%G_x~}9>@6R8|9$!krTD4kSDMsZTvYNV z36<%P)Jo-%{JZieb5hxVePMZBIQD$CM_+dC##BjVI(g?SJvtonZOjY&DwNOZ-xo;! zy`so!{Kw}{leJbgQU4r|*O@<6g)WzFa{lz^S-$f5-Je(al1*P;z9i-6c82%7=wio> za;>;)ez7IREdWul79?N}141@6UARfb7~uK418rRsTtnOYI{s_a}dT zB#TF_BfT%09aI0Lb|y8MaCNVLPWwmwSIAk@pU%F3m&?OfWjufR5br8qQsiajm(RDT zd@3eMPo_(r75(D-`T6)H`Ca@Oa&w-~TzsDLl!@!h@&7D_xsv}S|NeW+R{8h;f%(7W zT%o*w_-W?<(Ar7e{z;!tpQG(No`d#pN$4$jnk1iz5QH~ao`vSh%I?&XF|ba!LshAy z_n7RxrQ=iz&@fk2`IpRJIp%_tEbxOpq$^!6Z8zElGghTj5?bOl_jAOg7CC8&DP|B` zqI{~fS?Wxj&T+}_Sw4Z?;UYLV)?w7as;f(JXbjIDu!^EC4ujRlVPe0=2H5waAr3FQ z42O?3!r_Mny_^NGdZP)}uUv^EguN}BvM|z8Xgq>pPm`4YO--#8?X) z7P}Tl6|DMbiSJ}yhr`Ala(foXo&dM7OR#5T7wndKD~@U?V-9u|xD7`-_Heudt44a^ z$Y6Kk$i!Ni-mE4Yj-wVEhod%|h@%dB4Bt4tls%3k3oB?Q1D}GUE_)J3J*=mhiQ3J= zs+u5s4l8R?*>7;9u?0BlvlnnQz*?J^Q69O5vLX9Dj%wIHaxF^oCXSlyEgUtm4rdeA zuWZJVjkT3qAe*f?>S1lp2Y}mg82E1G4oK_oIO15XvmcT?jU&JkI09T?v-iunpZi%g zo`w}_Dct5ZOUF)>Re@LI)mUSm$un7m*W$GRvv?M}f;Yz6wN&1Mw_s`fdVW2#{a^dP zW=;GFe}Y{Z-~rB>#>|+BFOk-W)nNWuMl1vJ6!^xbYVRo8L_nVDXm8o}I<>t)ZEsTB zd#LTb)b>7C+xtK4}g zw1pnD!-2g_aa7cU4p^~L6>EYzLHb>BRL82GZjNT8lV;Sww{CNhOX^1k)=u?+PTY>8 zCU%bK37wD{Q=2rV4r$D#q%m2fF?C5}>Oo&7LjqDi>XUvnAk7GnW~7j2#Gn^1pwH!xC7+Zc}lm%8pHUC-c`@Jq1ot<-ogX?zB+&a1N!uYuK?A=3U3ugPn&OzHz6UYpkj zUWeDg4!M`|OW9S_E5f`kughv;<#IjjncEP1YPP1`L0a?6vExl^>N6?)3ViRk7Qd2T z35s0Z+?qGz&Dah6YJN3#*KN+5vm5y}{2JDldRL5km&K>>DXb~2T)v6F%wJ~h_zJ#) z-Nb*#e+PUI--B}Q<$Kx9{O|YO-C?(kW=NA4A|AuwIE{EgU z4ZcTwkFbuu3BC!elkZXAqpXc@qHiMTkNF-0e$;oA-RS$u_Z4ePy}EM%-HmmjzTK62 zHCAP^JoM)}=(}<+(E8}B4WVOo&HH8K=LpwJ|3${Qz$rX0(VO_h>uAsM}U-Uwc z=#8E*4n08H%g50Vrl1GRg#JH+??V3?_VGD<8~S-z$lp*8SOyK3`n?L8y&C$whP?)T zeiM4T37WbEI{5)KZ3lE{KlCC2>*hyG+i2TrXvbP;r^b-$^{`fn06vR?dSt*3^+oSv zs7Fs&OS$6>eu>=(*vTq^{frXWT_=`WD2PC%0WvVR=^q=eOXxGUlj zCOUTn|9JPDHh@kV51sL~YmC(A%87S-5m)t`aad&xOBsg6K37gzmUb*~;|;l)tk+H5 zy8+&OLnpvnx_8cG{W=otM6h#L&_{J4Jf|ySM|JPm9cj7~g-YllnR(DPQq;Q;at{=F zU7TfHGNy{$mx$z7PODzId=QZi35PH`+LdF8cSY&BYnYyyb8B0+GA}QGBwIspJ;6== z^X?zWw)XEod<6S|;7)>j2_6`bKja>EgkTB5Q-g*;ix@$3Fk*R-VCs;9AtQO5U=5J- zcpZY-`SJUA3kuv5Z;Pl+d`SQ1Hs(;Q7Yb>U_XL`QCHbJBvdPZFCn}JK>#I3 zv?clv{;8fPbyWU0C?48^RPs3)hdxT^Bj_b)5wr=02nGQKWE-P@sRT`e&^P3Ufdljd zYS5n)=($X<&Rn)2VyhBNM}NqH{pyFE#S5`MdKRqIB3P!?7*RK41l)=5Z5+V5=n{5@ z>paLUj3{-muXj`45?_<(gdL%J^8t7(Wh5WVC*eC1vp8&wC25hkce>)>UGAJ$;tWpS)z0~(I{Waxr=%boLj@W+wT%{k}d z3_dA6o%1N?JPT5n^kq)Ey$*f9I!CZWgp7~0cg~WZ{O|CI^mYCZcFrTvc0s1aZ;H2z z-wc|@`m;w)QkB^zA5S)--Ff8vdjHqbx&yBZ_5~#c_(`6vrt}^7F!8 zWr1_~A@`tH|4=e;SDKilU>!d!XB>Ppsjh8g`SE_-HI!DShut)y_?C{q{?F9`YZx^E zvy3djYbYIA7nuubWez!hr9lJbfnI@cg0uxy^1TLLYiIVA2wjAuZwl!5BOf+8~DD+n_{DQOKcKv<4Ys&;GLH*#ZmEV|H3;jm*5*A)qD+of5ba4Ph%J2X9D{JpP(#5F^*n`+TDahBad36dnyf{ zbVpERnK*oauE3?AtYPe*12`A{twx@wMn0!T-lj%=rbZs7M!uy+UZqCKr$dpN8+_i-O!kVDJJ=hVpC)X2}&(C01CrJt$sIFAEL4^t!G zQX}6|A{PbQ8(*qDYs{{Uu{|fLa{xsk-{29PSd=a30 zPfjC0QzH*kBM(y}-%=xgQiE;J9tCzUGW~%#rxs_V6pfY;1Tf+ z=*Puz;3vch;3vf?;HSlRz)MAf>GW2W(C`C}18*cx(Wc;ykwe-cz<+7~!doJ7yeA@{ zcMTc${n7VF#-V@DFhSa<`eYjVB=sw&ht#Bha@0^gM*Ww5TscMdWtmTMkiAL<>ire| zt2`A`q+(o?_U6z6DD9-X=xC5(9k#^$W@x^t} z<0U^iMpouqyAt2pNOkdilbp{kU7bpN>wHhXiu2igFRjG)(u?A&T|_Y&m)*(%>yV#G{2l*U-*O z;r;i3&oAKf_j2WvCAk__^tRY_}q!R27$YVyMF*5NCkYB35=<+zPRrYxbGNn zQG6;&M(V92-`GIhxs*$ya*a4<83e{b?6!nEpEodaVdq_7Zvuplt=2YcyS3BWZSA%8TL-KntJpe>Z%JNbvDnGjVSG=r zP3&mwOsvGd$!>2&tf1Y|vaGmO%RXvUc5%UX1tEoCSKRdjyJHH#xJuP#~a%P z@hjua;@8AmTFtE%@$2JltX6gxtG(6E>R@%Ua_#%9F7_zYR>xN{;aB4e5%;r8=-ZgJ z>D!pHA4#cBwSQ^Pu%EVP+t1qb?BCc6?f{sm7_G|V!`we@e{kFZu{-eFk z{*XMJiNv~sK?_Eq+^mWZ8-9kFk)+s2N?N@K_Eo9zx(sui|7TWMBR`;484i?|W@ z#sl%N-8>$RTb3EOEq}afJl$##&y3fOXIX9I^{qznY^z!Pa;r(ai9I5IRlIrp+ITDb zI;&;;hIm`6wcX9?Vc&0cLz(?Xu8|9g^f0iGFutFGo@C@fMjrVU4VGdQLQ-iYsW>F{ z0;_7QHvY=$8~cp?@KBW0eqm3ypR#A!zqaSv&)W;^7wyINZ|&vw@9b6ftM*#^5B3K8 zEqk;5uKk| zWxZql(R$zd(E8Z=tMzy56YHPWt=7NnrgjU9$G(mI%WiGo82c*rUF;jXoqdZHwL*3$ ztBQ4recCRCbD_sQaeq8yUmcIcW0nz5vwZPO;?=GC@r-z__@&m3@p{%}@rKq_@kZ7a z@hj|m<4xmN$6Lg&vs+r%##_g4w63?iTDRGSmaO%UlN!hDj|R^>jb)-w>-J-iIriEI zHkmMiJDDKi4^f=-|22Hkq}SGXw>gv3pTATzwyScfaCDB zPhpIO%uqwz1!tm#vaN?ed)RsqaE$c;;6v8^fTOMZ03WpS0Y{>Qx`Ex9NuD}-qr%`t z8@CxljQh|7Im#>Rj+C)t#9s-F8+8HOpd?b0n#(vNj5r@gP^V>M>zU9?V(S2p#a;(I z99s+c9r5{tgK7A(&S}E{t^68tpWoX-;h3#=)7K>F_yQWoOr-P)>tXJ)9p?Odu|c@g zC!Gn%JI7i9dFLfPNN7=@p~M3XBpo^Rz(*)|9n5)3d;+NQI(h)5gRdd6*AZV2^Q01g z7C649hB(MJ@EiKqGccddIY{BfRcc{&Rn4Z#?<+x1!}9^TA$wRkF3>U_ZLoHaHbm}M zp$*f9BHn}VL$=UbW3TAW+HKmMxX#6;iZBDaA`BBT?3N(QVc?GWGCVEmicy+lu2=Tc zG-yH%lny?Y{RqM^_&_n7@kLkp#U;vTCi7wEY?;#xKLIH3dIjW)?2uWl5ZkTVmrWMA`dv4cZR+SB=4`iH$7>@hap=0~jS z?pNKl(%q`OOGOzX(laXe)Xm86&icRltpCuj3h6hv{>vE!BQ`X7xMGy|=*PWh5p<|! zka_+NPmzgJFc(8-TV&R zhZnQsn3E6VPB;s9v90i3)gHVbc4`@luc{XE@q8+u%@^XHa~(Ac`?FLP zS)z$(B|3;6qMsOq@1+)qLNOj+51%a-iWQj4*dn^2{v!}(Agn~#j@c0S{aRH7>{x-H z2+s9%jNjt#M)-5UvHvjP^MH5schg!U%^J_9cqji!qQ3^bvxBb%-o?RR2j11e*8%V5 z;C}#qtApbUSMeMNe*<`T2j2iZSK*^c@ z8qnk%CD7=-o~Pn>_@Vgy+6!5+d z{vhx?2OkZ*pMyUHyuX8w0Y1RN9|k_q!N&q03kj4nTMQKp~&?ZVV z2Wd7EhTT?Nv^Oc=W0Em`g2^wC)bmRGZW#lN%RkHry#rX!SCQl9b8vjSB1iwXGN0rK z%*{~?Eh3KhqC8uO&y&Djq}+1X5BU?Jb%08m6{R3hcNtT;?jlrChD^4FWCm^(CC6lL z6~i)du4l-Z-b`5nV96Lc`&v&24PFKyuw;yEk$R#B;C(U%*o9)G?-zjGliwJZo?vSn z8otopm+Ag*AsbI{Zg3v+2G;~Put2C|s0*_~Plsl+c=X=rM0k1_=TNpb?7l$FV6|X+ zFe7+*@QUD_!MlR=)fhd@XJG7Q#+AmiXtWyYto?-z5~(O#z|=IaE`XIz&cXdt zaTQOMR#m!H8CvD>DzmHnuFAeDpQPQKHY#mix|Lo#y;1s|=|j^;r$3xNF8%TJH`D)E z<8(%qjP#6~GCF76o^eOUof&s!jLTS^u{q2-)qbM(tlBGT|GD;O zwf|YWs7~!VL$c;&t<8En>(jb=U0>b0bvxGWTsNm~kGg&8&Z_&nx*O_lsk^`Kp?Zn> zp8A3MH`Je0|Ks|H>Yv6`YV`(}HyGAnL4$P-PBpCBuuj9=><6rr#S`5ZR7tbf1-OT`gxiFh6s+N~B8bDmhg~R+(C50kw0xw1Tt=SW1+Zo|WD> z{jT%}opydMeRB;w9?6JjWM;I_=;pNZ-5C=y)?{qS*p>13jAI$cGg;=)%#oQhG8bg7 zMLTcL+?Dw^v@@$2pmy$7^U0bsYR79=uU)5h!`k1If)w*trOQLu1+*bT%Kr@sGq2p$V${q)JRlKSc%j`G!aPzOOKUi zm)0+>d*ZVb3s1ao;x{MepO|-I_K9as%sTP(iJ2#6ocPs==_jV0_{E8-C#Ia3{LSWX z)*V}O?A2qdkNy7Gs$;Jl``xh>#}*&^pJR)TJ$LNa$EF|ad#uk_r@q?x)t?RxK6KBa zfrkbh>VN3=L$@8uJ=FP7^FvLGON&nxpDaFJTvB|j_^aZh#a|X5DL!0$sJOVesQB~Z ze-U@4T@_N$G`aYi-TYM^NY{ESoTFh(e9$Z6m2hBRWz&U>7u8KW)%IZXnN5v zil!D#DSEtUQqlOLfkl0bdKdL5$}P(L{2!ms{`}F;@BjSX&j)>;`+3#ReFx7R+;H&q zgRdTZ;-6#x`S5|$2fjK`bfEQt76+OiXuSD1!~dNBi~J|@AJ2a*|DpUo`91S{3@aLT zVA!X__6^%JZ1=ET!`>UVYS_!emJgdh?AAKB)*hB|Z$?4&L-AMQ{}W#j|4n>;{Q3C2 z_;c}R<4?y6;=|)Z;T zOo!)Z+<|a6@K12gLwEvs5zg=~4e&Hl5KwO8ZGZz{}W

    fI);V1&`p^P@z zxDDktQC{O_oUwMqgdb$wf-@v3gV7P^Dk>PAaK=g%8H~<2XQ*J{-V*BunArk!$jfZ~ z|0sJ8z$&WjfBfF5Z|3!u`jYpOmr6@W2pC$%P^1Y_=}HI)p(sUZLU3u4fPeuZ)Cds) z0TCl2CWwH7AkDIXE-NgnqOvO@-(A)M$?*H!nS|ok{r`S{;N)B;@6FtM?z!ijd&(UE z_UqypV9<(zi1ACH6$5cLa1j7B66XLJ&-;& zLA(fzaWN484t&-G@hf1AQTh$nzlOxfOZSumjRep_Wp6l zW)mdLuj5q{q+H+;Q)OYNZ?He=;Szs z_QSxShvOXD;8DkU0HfJ(LR?jV578b0jL*30(8d^i6d}4N!pgx4^iEe=OQR z1A_7yK9CI@(_V{|rFi)xVlzH3U9Vzd;*x z3Oz-L75xoO2E2ea`Wspb0R62`09OItMjLbt)d2RQjn9SNGr_tH_)`FAX?+nG{R!cj zR?I~R{R*8&dnGXDoq=^VL4r8|{0jdutW^NkhZSoq0kmLX{TjHp30Cwo0ewoq99b^` zFEqgx1B`x#-Gta;fiV~1Xy}lafCB(L#J&MI36O^NX5glPW@v8*o&=bJ_730~CfLER zVbGp|y&Aa81pAx77!L#cF5q>5ooK%W{4wAYw2uO#uMF(qoA9?L*pCBWHo<-Zsk(`P zFg|ke3#N#GlRn`n`gHD?x%q>OmO3V zO~wMAz;)cW3Ffv*722i1n8POEXZLpC-vGF;`yGN*a6k;&pj%Tc_@+r{p88$ z!o`5THk*bv=-F&KU>4ff3Bn8jOr{(CYn}-hNr)!_82w}589+#jC=-y;M_SbOtPJm1@$;3cPkXtXg-bdOx)(SCwp7YV>Ky`c4Vto!S% zZz~D;`9l-D)$sr0GdCq%2QT0B0wU3_0S15H#PgB)L2lj$!1KMJ+f6*1ffsXqQvQ!-wzR{2Kt@^MPJBF9ER5 ze3-wRbpVXf2iocAr|v`>w9`X?FxsGe2p{ zP>_c5@n|Ey$cF&9k00JUbcdeqk2bEIMV#_%F4~ACpGEZVEXM1f4y*w%Mn7W8XA!>x z5dU1@9)JS0=K&+eb{2hs{-{9@VhyzBS0VEXav+a>@P5PvU_1jr zA}#{s82}RTcS3&#t$xNFMSKN}+_ImW5)uiT{fzJa4E~EmEb`}029U@QkvJ8MLa6bN zwQm1GgubEOh;RSucMW_Qe^{2Fi0G&cC%e+%8@3~A&hp6J#DnZ}AMuk2WcWv+(l7?u z?*SNS%vBYFQcpy+SYt&^8lt|eriR5`SyfFY>aPAjJUNfGLK2x@T3P=m9GEJt4MdQ_Ti zL}vRIvKiH8+faS8-Kf8LgY3jf;BTS|=WXP?vzoGZ$UfARp_a_bBThboj3i^MB6$W` zy%Wh3*1cpZ8Eg9iG4-{!ZDf+|C)+hLicGUDu~pjE^8IXkkhw6EXYY;JOXeU?d%SHk z?Q1)2TgIw`tP1w5bIE+N3OTiY^=I`LRPPY=rdmg89UIB}w5>JO`kXajjq~pEzGW52 zbhRFJN?ueHEk<3@67oDLCrimP#3Wf&5izp$UqWTkzqtk6dh!&vmRrYFk{R3v?j;Tq zl;&VOteWk8jJA?)!T*Z!t*3CMira;LOu>~y^aNeVHOI9r5S^#-$ue?+-!2f^1GP^l z@cDBhN3J8=b~o;ki=OAo5>ifk3%iAf@lJ;Cg;S)BFiAKi6bX}PHop;G^DTf}{zLfn zkAWL%=tVM#?8RFmviW^NXTgEDP@LkolW*}90rx+FQEeh6=!=g|AhWmuR`?N;*w*Nv>FXECl5$Y`F&_vL1RU9-7j^#3UCbqe2KOD2JR z&r+4>TvJ>_@A0hR#?Lsuxp>z2dyUM(llziQQjO%3!*~j#*cN(-UXhlQDsmd0;-~m8 z>3qD=Vyn=Nl$#Xbi%2={y_S7PD#lwZij2P{?C#t&p@?qBd#Q`$;kfsQY(#kSZth`> zs2JQ;Or}XLjHw-+&o4wz*>B^>DY=J`f$!rE^0OE*-e zOOkP^?qnw2L#!cdft4SUob3<0v)z1{r#UB1obYY*>$-Th{waMOg(1go{~^Df`-kxi zndECukv=DoITk^b5TFw*>=~ZEJ*&NaAH{<>_Mp1+tn=6LyiBS&GZjrKP>Pg^N|kaz zk%v%s7$XY1>4fcE(sn%REZ3BQ@vQaOt4E6aF`ghP(ptt^NtrCfDPpvpD~t3x{qA6V zAT}m4!te8X+%AXRrdS#oAV!UnLaw@#k!+0Z&$Mq}*Pi`6oOLBDD^qhr$Z%Gh)$S8w z+%X>sPS@oj0e-6=u%MPkYcfmQYM=Vh0V9frlDuG4fEpa`)JQGA+)S{y>=J&IU5+2!k-4{# z@Z+FF8s=Nj)SP%4>25)DTD5MIlkLZU{J7|jr+%L#^KJ)lM5MbTexJha#+!ZqJhu3= z2^Wt2_2h^lJ0E%EjmN(E{F~25OrG)7SF`4n=%;COu6gs_+WnM%l(b{zEBhQjTo!_{ zZ!~Ek=>5XGE4LkTBFwqgK6YULqO*D*_xQmBM>F0O$y2w!k<;NNv_eCNQP-MH7HX}N zoXIK4DbCcS)O_-yE&jz8OQK#(l3uheN%1UBOIp?{H6b=x;q88hVs|Fkn>u3c&X(3z zCh^#U0l{qShmZYmupf4Vek~bQ4_~={#dY=PtBh3OG}oo9>+LTYS6o+3s)?YQ$mo

    H;PD}y4?!KO!O~c;1ekXo5;PJ-?^n3jAe(U$X`%=~3ck5R5e|-3W z0gsR1TUON#t_rT-_wI%bwR^c`E1sKMQ89O3#jNx1zWe2u@9z7O8&)y*xfLs(o3nD( zZ~vC;U%va^U%%Y9_dKH$N9Nr6M$|zkg=ErG+Dbch*h<|Vx3yHYdOU8WlqmiPzf2`d zX+(sdqdYB*i;p9v3W<-83kA7^c(>|RvF!LLpWCa-7EV&!UayJ+33y`uii`5&H~6hr z&G%RpULtBdpXPT+X{l00RMU#o6-mpY7CXFZ3#$WXLU{bCj(EO>CpE$0c4F0eVqGm= zb>PM`S6oL-;({9)L$c+3|NMBO4eLq!vy7ya(O$AD88SaWT7c`|6;? zUCt~@hiJQGtC*;y2S|Vhxkw}kHlZn=wxpG(v$c>6qJ!0bp20DLgM%_h#h1V!SxeV& zt1K1P<^GC@io`X|gNjwLS=_c%TUrzst3+F)ZPD(4FW`@e3ufVj44STlJx#n#d};oS ztaeH(Pp&sFtB2Cd*VErMx=&VrI#?NG>*pEdeJnUMYpiXIyC`c4oo<`qUQU+NRa}Kw zDOXxHSk@}*tZQvcv#PSHvvP;vWm?8k1DCZ?kfYTmTjFFIPIb_5B4KOOSfSZj5o~#e z4ThxudbHn}s-auD>m{_VUB0x}HhKt+tScXVY2N?nAD5P9X8o<^ku~#FT@Vp7e^McT*?0GWEO+A7aX~C}Z z?XTatuQxlw$LHm7YwDD!0gkiLeFYO7a2tyj0Dqx3axX~EO9K)Cq9 zq2VX=GCKXl@IxOweu7Td%b4{`aiRkezZ3rZpdMWO!mcGlPqTbq*gw>WAl2}_5%eNAi<<|n>E1&sIRSaMuJi2k%oxIh zM{u$A-*WRdv3`GvA3O03eD)nOk7Kt7v$39D$;7?GU!Fd#>-ZeGmCx-m__Dc%jA-OF zaxpyN^SKRRQKT918HWvKxqjt$G92=mvuv;b6%6^?IFJgmwCvV5LV2Uk(Y#WXhg8{? zc@{@00cSiP@W)1>2iMUD*CnPZGHD{`c6qY1V6bqhS;XxkSey9CEvkI!CH#BorJGdI zf4O;6|Ai`IfqqIq2{^^houI8~c9lL!FV)NRNpuM-0;EgWxW7U?Z7{~85>4~x^Hl;@ zCC-sam0}4>0T@rz>N>;JK2`>0tKrIFlPFo&nMn!d4)wI#$vXvZNSg$=n3J5%rc|dr zz&9h0(;ju3whNQG)pWaY7Tz4(0+zPW17i-5^;&9lOe`N2aD!dkqA29MUUsjrSNWC+ z*l`gTbb=a)bn#LgTl9WdAQ26^6n)_h4SMFv!GnhK%(#O7+(mNnM_L_lLAs-NT2?;+ zl_2sAVTL$0wk%r4e$1$26$6vWRB1}gq}a&;9L5qoH)d|^+`v|{HP#Jrn2cfM;3Nyf z@_@jTb2`%OEP+`i62T_${kmQtWcIKJUo9Pa`k5JL241GVE{{g**SBxqK8-GGJ8o6? zX)E(PootzP`GdzcPmI%lFveerIiG~_r;&+T3*z^xrAn|gqhtGiG;aUV+RZ!nRIGnx z^&|VAo^))`chvR*pBy~A^uoWAlMl7bT3P;F#g=IkCzT|n><)!K+conw#@iz>&zrzk z9Hi|WEsolGJK=ddQv0oP6?PSK6lzmRK(YunL-txRFw;1)v4Ndw520je>`P2S-L@l- z!6G`wCbfwbPLghLWsD)yu+^6%Xj76xoARykmdHM~KKA~|FP=hY@bjr1lc~T$&vvs7 z3X?Uwq;piy(a)YeR$nM4*L}mEs>|N0SJ9$F#vHB39F0KV<4BN` z7TUQgGRMAH-V`4hpeiETs!NJ@)zQ0W#&wqlaj`XnNpc;&%9b%($Cw};W-|EJ5JE6* zv$KdF7X955!{*}xA6;M7Y+$n+G)X_B|5SKr^x%U}yng)n>kqx$S3J92f6?jGum1CY z^#6oHCt7CisjS?Slw!!0a`b|8!2r@oRIWlL%j@FxYF3M4tixicXa`zl!dhat;B+{QI){4W>E_b!4aGixge))o^t z#R0Ax@EJzdG0cD>u(qJWpiG9MgQfOU-Vx#bz3%X?(*ex z=PlztTw7MQc3o-N+Ww(kv)}sk)3;{t3MC#XKX>`^x$+})*yOo$Cj&4h!?qX7Fs3N@ zA_r<=IT%e#NpzLES*RilBZ5_~Wf6;$f;__w2*#J$dj=8$fOE`)W1CWh@{d|x5SnitlDyk3|` zwqWZb(rAH1!8d}N7-q<&I;N$)=8X(%!ufHsl=$V% zUj@qzUF7&{`Z9g_9{Sl9`Wd6cIa(xs$!~0+gB|9OR4HHx0tquR90nO0yhPA@>@OUd z>^?Vie&g0_rtZGe_dZ%vsgl49TO#3kYW=zRMt z_jKOqIU9jFib09q9J~NHhZ@fmB>vhSJ!6ZWv4=84iGxp?@YUc;R$VnxYnl|VNP-%N z5Sp*lyTDZuxePNJ7h_lOHr;q?55x!o%r8la@g_5?-o|Vfuc0krE@Fn*ZV*Z{f?c9;Mt&M+2(zZ689?WhPA4AeSQj{$% zrfGaycTdwMY2BN3c+hqJ3Rn)JwEYo7S~DV_fq~}Ie>`)<_2Jbls2vO~lQ3^igD=8x z%oK*--EZ!l`p?Z7sHIoYO5CN(9AsVZ|@ z6d|zPW27WNSf!d3r z-`hibJUgpwXVviUO7!3KPbJ1zF6>p9K4H21A87XzH#P`ZddwE3ZWZM=ZVon!D#JjP z*hR(7s}}YPSTS-1vtdN$H8i}&im1X;K5Y67FP*v4Xt5ZM1?I+qf5BX_44Z8@3_>>M zFvxdOC+C!%$OIaQn8`#$Fcg`>H^M7I1dZnKx@)e$Hj0kso}p8@nf%kjH2E1z8C}55 zwyoyY@GFH#)5w9LALikCiwnE3doxi^^duGLE{o2j? z%iOX03uTKI&*zHujuW1KYT}lIZ!X;E3!PZ~5v#VH1iw=%WI!}&t;N`1cI;Fu-1KF# zQ^4|fFOHF;?IhFZieX)BP)Dq9KVQwzhP_uGv-OH3-(A`;rrkuB21C{5qsyQ2$Cl zq37c{yXZ=Nv|gYO6Ekj3!*Mb#a4byZ7JZdI8_p9J)1t;aF2eJz1W%VL1g-)u^$Ov2 zRiugx`&6(olAJkw`1X8d?h4xRbhZIDcHh9q`0Dx??r423_iJ58W?FXLUjL0L^BJFn zaeoD=CZ2}-3$H_Q7&nLVV>dTdD0JU0r}gezhmY}t>nCyr_0`AOUAt|sNBG&COJ+O8 zkz6fA#8_Iv$5vQ8FS~d8D;&!#i{m*GaJLe&qoS=Y7}rlW!(^&fE-r00pPXX&yn^|K!7 zN7vACs6$-St?L&CgowY<3VvE#Vk4OpV|)=ItDxQ~_OYj{~Ykt@V%GRG!b zq}+xsGSB_(dtNfEP8cdoEwFprHG6@*$X;&WU^njVk{b4e$Bv)+=E1zu@p#a3{a@F& zul(RPO~#_%D)~uEv$$cg$ZiQLpBdtY0UJq# zoiMBGsZbxw$LK%TXS2Co$W5#7R`(6}Nj;Jh8s=AEbP{1T+SsBLXn=1^1m?41UZqP{ zGBqVrE|6#Qvju2c+?_4NIiR)T-LggI+?2C0#B++OKuM`e zzAAIP1q8QPp^Xs06jdo8bW}liJ6k(US~CV^`{_o?H>x6LK(YYCu89st`TjgpK?LD%sC=EGwyv)evA zwl&6%A3sw~ab^7EQ_t)5ls|u-QvKF>9P0IqzCb^sf5?2SVlTZ${}!*1tHGgO>`>Eg zoAgKZ^*VMtbQ3D6u|o#UI71gK0nIGPHfgIxK@Tx?^4v@v`OqN&~`h)&F|4`J>iA<3<_=KRp;qMZfV$SGteaYIjOZ5BbM>kmyZ|cXzjQUSrEGvC+ z%Qs(M__}^8qlNx!11)e$vepD%N+-41Z4PR;+wz_9HiI}(aB$k=?XgZ+yV0=*i3}Of zBodPluEU12Gxsh73Os6f@(gFENjk3?nz%zi?j8c>QT6(Tgs{t`ACd<^&(Hoh8E<@| zU-$`omd$h+BcegnIvuHW1}$-l%vn$}K;G1HVCV5F-09fxxUu2MM^cBM7yK29ufjgZ ziV!yMhK&^A5Y^~t!JX$*12zGEOAz`nqcp~5EJ8+Z4~BN{;P3&gK`ox~Y5oi^6^Tei z7=N7(ha zmBZ^7if2Fn%aXlZpZcq1^XAQGGL8AGH-gtw$)B|Lb{prga`C}h5SUh~tEDG-OXOJtMtOI=l$CV^G0AaB612PBOhGLbpjLhi-mr+Ljq#f1zK{zaRV4 z?2;=_zrL?*ZOPZiY2<&#{8ilaVVl;or#?P17~S;To^yZC%=olR*9CtXKQkEB{NQUx zF2SKjZy~o;V0jBN=>ZRdDaBd>+U7}w?s(Va7uYZo?2a{MI8uvyLc}GhXn4ah1a5FVMLg+Y!fKrl= zILsS_ZGdosC6ycZKM=xqf**}e3PaBnSQw8FCwvqB0pS60F#jw+kB2{9<}3n}$38Ab zh!LB>lbgb&3+ZCA6tdihGp)0^_CkBHjnoaNUw7fU3*E&Bq(P*=RLqSL#^3~@sn`}x z7p99-q}dk4*`#!=fdrbZU_Zq5s6TR=o}+*LbNx}s?nvPuFq|l|<%qlmG`7(at-BZ_ ziO{D)jH>W4NT=Ws*FiRg#8fWUyV#&|ZTPesIrI4{OdJV%$ZD}!RmEZ^4q0Vlcb#d- z8bPYaA1mA2d%)XUKw{|Le@UDqA{!BZJ!+bm1g+bV>nOHTGu2+)gJQm_se^C;#uMTw zwMZ>NSZk&@OPsB)L^wB2CJF}&K!EoMDTq`Sz(pt&2=GihGI2E7v;0&8d%!k6ww`dkk>8w6z(;S*( zAO{_9D{vHZqxfOMaIr`#l8Y=Olo9F(>om+m3HJ;?O_(fBm!`|pEE6ry*k;*gIZC-Q zeu1!1oUc4@EqAOEHaOmJJjygIn<6$#VTFb}pM;ps{f7NGr7zSWyFWkz(M^wVl>zJn z*9~~{Fn7oYZm`RXHOVd@LBIyqJC8li?%8CP$_>HFG%QeN4`lYN&Mz3K`3y5vabtE3 zTNM+DWhJ|=-2SKe@GGQmDuPTzMUW_`@)C98&!C2GvQE-D=jbFl<(wXZPfdSJAM{tw z-;jEgUH2Z5Z7{ywyxb9!r1s(;NLFdOnXJ&sYWT_Tw z*q;{WbkDcIoaHM-upG_D$<-?JvN8XXY6PYv!_{`?5=0RMBXg}9DL|&B&q6mE_*{;X z(_vnkCRsO&BJx%Xu}1JQ7MC@{n#1Q>@~jW=JuH2!{rEwaVt$Nef^{1IjAfQ}gEfLN z4xIB4pgA;Ql2B1sz#qNYfv>I`C7xY-bHetu!ZM@(EZ#p5xl%G|r#Xdf(k^Zrc@tY# zz7w(B_6!oX*Sb6N%t&#oJINfPY~Rj;G|VxaP))a9yQbrQ<-gUH8~48_77Up|35nrB zA7pC%f5w7gywL4NFqp-Hkva)lA2o6XSYI$y);7nIh!QdI~}|cp;Go1tlpMZbx<+tLb)R zy`U3l%o=^KRIEQwacUVUfxXdOD1l5&Ci@UA4q77>2iX=W)jHgv(%{}eZMeq07%AP6 ze3V_WScAO9*Cho+Ie7;1*W^D~lXdVK95Es;Zf1CC<1^zj<1>Sqq0EHL#Jp53PK(!q zT1ZRK5)0xA;tPTWp@M{h#Ddg`sq^E?;>&_%p|XVeiAz(fQm>`PH-5G8OO0PBiZ2Ql zg^Cg;#!n1R3{6a!9X~rbJ2X2X>h4%s2igV`b=#4eaF1)5+kbJ#oC#}cYijcLE!c6Q z{w7YUT2-{C@5udw|9y?iE-o29>D=!0UiEXf7Y}=X<9i1^vlg{zu{|{vqJ|@TL90#R zbt?&w`?P4j*5*`dqx_4VHLJ*a>W9USg4`BUdx`6vfYuuZrhk z`8UR2umOPM+c32`IDJ#u3gEwe^~D!oWl;Y@+c!&2;$-`iC2zK^t>rRKeEKY{XXdhO)dm{(H<}G|AIqNhw_*I7;mc)LOSt8;Qw_kv(?O&DRBvJLK7b zPnhw~T=M_9nu%>mtSfeQ?9$k(Shg*>ZS*lOGjre>`vLeE`R{wbRPff3BX1SF)ce8B zL+WA0G^bL(jY7_jrcJ*&b?Td@O}8f{VL%QX(%cr+0iYN9B@9LnT_(L^YKg;FD_Ryi zYUnDM+r+{>;PzO%FnYnZV=f+(UWf0Y7jyF%(}~0kZ0aKJ_LuV;YiioQIr9YGxN~CW zoApOQxvg74J$?^Y_}i7OBZkq=)PldAhw1(X0ygw(7U<<8vB(feg8i?QS{8`@ZB(qa z(RZV2JvFw)fmlCh@mokw&g1M7FuHiyh-WbJnZeuZMu1sM&x@NFR~7eZ+_g9{4=*Um z^T;bsTM_aYp*`ygxrB>l#>!e>eylVGOq~TJ;M+x^U zXze9~w1DWMHp@1NmLVNV+NW|}1Y#A@Vs~15VP|TX(6!)VLnu3#-9k zK=OD(U66vovNjENIDE-u2>mRhbS_p=li4`G<#($n(#740>vu3hC}s{13!(5EH&?9K zym>{%<{DkUF>J>}53PUr?cKS%W`0~(_wmeKxiwsekItX}=;-fU|A>o!t67ux z4m|q!aF|Fe+TC{e<8abaR8J6LghAg{SosPH@TpYhaM##Ysc;vO-b^-jHMaf6!f($) z&@BH8erP|83ARNv7d{#+t^-CEM%2ulS+S$GHvg?D?;qhd)j!6q->`oFrus6;SHFJb zh@aRRdLIv;j_0!2YE$ft_6u*4eTc1E1k&|(Y!$vntYo(DF>|-El9>yWg<9XQ!5^XM zW|ido2kv+4OTE8wKlWaY&RW3A$;7eWCYOotk$tu|T^5%p^|4cnjdXPxLDx$V=MWi~ z2Nu<1lYj@gHFtr#$UV_*KFHVT&om$S%G+IAj_GAQb@As1D~GL-((vd88dhQ~Dl|>{ zfA?$dBdZ!6n-NBz`YbC>uI zS;bL|=61fDW_LBXoF|Ic;A%4_43j1KenXj~!EbUL)=eTAtffdECCW*pIN5J2iwp5J zvHPN3GI2XC7OB8(aTWxkpmxHLQCW3$@H!dRZTt3@t{Vgh9H;}_1H`k${E z%f4L6Se9GAaovGe>dSGyDE{%`jzYteM?K{!ftD{JT}t z(4qgjYVc^bXiU8`#gI9XkU3td)hBe^lxp=~wh0A^kz)Phw4E?k<44hH;glY#G;^REvn@djz{Tt9%ud+B@IdBEawVxKHe_-vx#$ zejF#pSz>6bHp!YzknbZkb)1=N5wU~2(`qM5ast)0?NZD(y~ zvxZ2BCUI$Mnze~H!1-w#GE_i+XPz zyl~<06?um@|MHi?hn_4xGHmYRk*{g5t^WJR#k+;PooQ)(`)b`298K0NtlSe0@6X8@ z^ia=&WM@*v-1R#e^3D*n&AX z(~ckv*5XdssRJ>$tbVke7PzC`7pruiuf_)5?z8rWmhb9kc3`f_SEwav6ju}c2bs9? zLbKoY1U76z=uW2OU$3d@^yZZJKcb(|z1)`iVH-B=-^7*NtlClh_%$9WcZR=3m?acp zA9+(t{k<;(F9&1342k(N4lp+%B2WT>FR;OsBc>_m!}is0Y+sH2wV5dKU%ebud!ZY= zUChr_%FX7Maho^`dys;J2<8)y;bR26F%-^?bRlHHn?Gq=zO4XH2z*!F`R+njv74k> z@Lonbh#w>r;B868bPPX67$uIDiY!yeWLm# zT3jV<6(&2qq3GrIiQh^{s4bs zKhvMs5B|h{%%9lr|H+?t;1B$XjEX(0-7H_n!+scdosM7?Rf|;tviZ4aJ_4THSWB$pv-)i;dJ*PQ`2-hC(pY)CGR!*4Ho-B4pxT9dmVZWg7V|qxnjz0Zvdnb6`LINtYJJvL#-hhK zuV@ur!7b-2g>@o}nyj&C87plY99zg1x{2Gwzb3pUZj-jjuUR(P-f+Cly~)2Pyerly z2ONjFL;OkMxH#S5iCCJAe>7~R;r=z>eS7Y^Z)@}~&;8H8&Vf5t@?#m?tm0SJu`{_* zV=tik74Ki|q;(ZpI8#7GNoEKcM<|wZBNk;v#XC{m3fz1^R^%DViW?4S#CZh@&+Y-{ zJu_NZ67YMP41&5mWBv_R0dGi+tB$ozhumQ^;s=*#qb$ES4BVKN)aapRuDaE#AgD2d zUrkXv2rboq!T@=oTC7f`GlZ$~WOa!!S6w4)5LU@As!P=^ber&ouvvaZtx^N=W$I&{_6%bcOsH-6U7rKe1o5-?C?b_6o;bSBC#s7@U+=8xAdpa z(R7+F6xCm>f1lRq-Ee?(g#HwTmkP2BwgZ!8PP$0zgz_`RO`MF(IIactW5j89+w5rD z-3~hzuFZ`wK)&6oxQJCOqAGNoAurgR3tCrbk;~-fN z;slC>m1cEVosrbfxdfLOsrsxwTZ|*dnM#tNc|$@-Oh;rsSxvGg*;4II98H`dcN<7c zc#efk@jkV+wYBX&d#)qbnd!ctXjJ1gWJ|!8Y^=b1rHlH2y}P5kQ*-wv57CFXetdyY zfcfc%`5B-Lz$)x#8{`<|EN~aoVs5lL#xcfOR{O8X9W7j8$?tt074AE2CEzgI=91 z1K_3}YAvEgTrpoH6p6#(s-A6q!y3z^#BFEwQ~cQaUfk}wXSv<=BZZ=^bzd&u$|Knb zYhB-kI$a+!T&HQRqMd%Ll&r+K{Bc$>l)w|~HU-YtgNlEf_swLRqKZj4#3N1>y_}DP zqC2ThF_|%EEuG|~pF$q0ff$lDZ(Uzr|hietY%F7dm!);mKEj%iG_-{MX7CVxwPp>DLzqlrO( zR!0F-q#;OQ7V+Z~hLfKKHBBe~?XvGZ?=~sI4i)v(Z>(hksMb}N9yaq1RU9+ zA4T5bYACV<@{rcl8{s2P8@0-ChFV>v&IPtwUxc+bE*PkZSezK}6D8hjb;^P#IuY@P zGpt_UaMQsd3Pap=*mNlyivfhpOg8Jv*)}2-RV&QjDWg9rEGwstJKGyixh=~#ZQ@)# z7Idav7k0aU;e*Bh!>a23rY z4p%VJIE4g5PR)VdACA0HW z^zOBw!-~nYOrOp*uM1u|di3+l9af3E_oSz<2#0WKlV=4sC2rCukEYhLU9!FeUMHtvUn%y=8|2u+fFnW%Yb z66Xy>DSVPu#Y-fU(zr>|Nl}@u^Ovq*ScVufM3X6@8cI^n7{6o;&%~4|zH-g- z)HabuF^nWf%0^*wN~)Y{7AChzZ4+tuguHi!F!+*Bp8hyFDJAW*r$1>oxkKA$I(+if zC&|evDW6RGq|Icl{glVnJw0*#OHVyj$$$0Pq>tN8>zFqw7avJWNlyM`(#IXAw$&!z z_wl4pQj?SPnG@Hpo%nR+OKihme~=WR`n zqZu0>lWq>U)CO0LKACR2~!ElKkQUPg-wFHX7 zAZA+eFk50~*(AHdeq-kH+VlI>x-PFfH41 zvSQ5toy&ChcGEb}BGUYr!F}*;HE>^pDv18WduVQECKVxdWFno&O%x|emLU}30Cs>3 zS9s!tKK;ZA$#wkrahP{B7W?XNaTZV{WKeh1DWr5b(Xs8x`;RBJJdxSz)au;u!$mdE<|;Zrw3x(Mi~smCj4xu@~OZ2`BfMDkx5aIVpiKDd;G3Kl}PAQ zb2{S@0cmX({-(At&Le@YHBaC$&qY4WPznweho5I4OLkov|J#YRuLkbK3GbbVR#!DM^1`}t+1+IVk*}np8 zjqqd=JLeLZC;=aMbrY`bT@&)82UX1#i|APAWz_KPJ${uu~ zfRLuSr6+_ZqY|I6H^Jfn#j>)Df@-z|zz)#%Fc%MB{Sl;N@fE{pG>TSXv>9PfMu>Lz z7D!=#Z<4A5UBp$_7jQc(nk^kNd-Z{Rd!|h3xS(_QWnJEROTY5+pN2m?dM;N`!qw>7 z#JtXBPnA6{Jo;#2;;cZR`dX(x+Jj4SY|sqg=KqHilHiF54}aW!avua8}`anQU<=Hj$HgGC@@33AXVLS6y9uWC<8@ zfDIL#5BtgxvG!h6kjze<(VK=%B!mwjIC}j6-S{xwc)Q8w ziP?HV*m{LX(u&knp%SnD;v?Bxsm>dV@62JAYXV8gO7FJb+`<=P_gcZe_y2y5fpE`y zxes+^MOy1F`JM8zj&;jCmfNG#aa-U9vNUmig`Ta$9$AS=6(2QK$BW z9wokKp`^qQZGze|R?eu`AI99XTnbFTp_8zdesukab@lmGrk+{Z>K`tf)c>-~yl`#b zb&?GfdJwt14VkI}`Gb}7+<#eR&z6*oA26`Edgqv;s7@^w?wHfAd+YplV(}j>ol*a7 zq3Of*D;<0G${RIpdjE-T%Y)r7epZyNSMr@f_p{<~zA4TQ<4MLl+)v~xGH3*3_%T8G zf5~QH#WiQS{`K3%pJC-Q`Fn_;!gnzA7~Z0%xurw?!{m@{S*$YH^C&+!Di-U{$P&K} zbWbTT4*W6I3G*AbYR!>?@#6~$#!u*@O>NquMQv%>?iz8zgn~Zf#`WnlaZbw?&7aPH z?w#Fbr3i4b=bl3jmw6tC6BR;H;-@lSNj^pKeWk;0oXcUe_*DsR3@iX9{#l{}+GyT$ zI0p-?-*rGo{b{2*RM4N@u0KoXZKv~YZb2v-G%MsPx!o9N6rx*6*DhUVVxN}TPnk^A4weYR_>X`RMBGvUepg@waL3{5M3 zsQc_TOScUciag^Uo>}VmO^=P~)3ryhC-d63?cj-==~W9DZ&0!mzOZkx?+c+8IT_`Ce1ya+HoVE)DU}5xSb%}N zmk_OZkUr2m$U+Q81t4NphIY8b4y?Lzo;kRT!04V}Vo~BJiAaFBC)QvD9U9bTgVFBZ zS@V3^ii(sD?_-NyF0R@;imh~5Q#`tI-?y8BSG$cw7ev!ITT5?{~N~$5mzd&_?SFrQX=C_9VnHFlp18;-)#n_q;h@R zw0>r4ivdj&dt|h0-?VwhF`0uNwb|ymotZ7-2XsJR7GfQJC|<cAa6>W}%mEIj0Rf>LQ`?x^>b{Qw|sfzV7Dw^z<;q$gZp~LGfUPe|l&k2{2S1DZvT|^iF@U-OH zQ0-;tb(;nC5|#<7OegSUBJ_IuI>;|$r_Ts;mtJT7);mS#jrzP%zoQ79X?2Aro9KOd zR&NT$ei~Jn4J{P%7e1^P9)Q%b9k|oPnLxM5LYyBrOT6YvVJB3&QmqBTqWTdo*_w)T zDI0&EcjxzH^6!2>{Py>!{O|9BUgi3DeuuGElVAsBgko?SmK044R|rX%7q(S+-wW?c zmJ*{Q6!>gn5>bvq69Wk;IDR4mb?{ft7?rz?9uRW{!@AQ?xvpP@9!E?7M!O4!e`A;l z)_<~L)+2b+xT&;GMr!wDX|g;uATpcXEQbHRY0Qe|nfZ(g`fPfAf1AOB+h)%j*L!zS z;lWWgfA2nMU}g%+rVk%K&V5oja_)eEe^?^lnmX{ZBC`%be!`Oi&nR)pk;%e7I^_?p zhwr&Q&iuSvj!a?KiEFoLcdK$!O?28()jg!8F(*cigIsv~vq{EheY;g(Sj1-)&DSR! z@@0gDdp_U$_U98DKku;{pU?E<*@?$#H$IQGX5N1s_O1?iu})}xZEm|QHW2G@2V&y^ zaqd7M*6vPlCfM8#o70&Payt`(?Em?;Sf^d#-}fu=6?Wx?P#``o5ETk0*gcX1=?$@@ ze^kIJ_4fo465%6+9qT&7j5Kps+vx7iX#X7yca+Owdhd7-8iPI!2}(fb6-4txNWmSV zg<@=zZ0l^S7BIFTTx=iXm|`z+Ob<+tn;M#$Fgt8x4uiYBEHuF=xM4dYFa!>bV-@Ip z-$8lWfPr~=gI4R;xCDJ*hmIR2J^gZCd(LN8q)UVI1`W7BZ{R@v-zZJ*oj$4iq^g&n z?m9L7#v-#wotBtu=cqvqNMa@uX8LnVSm;sPGk;e%3u7(flQ>0v@u0P};x(zxrO#RhVi<&d*k$X@e~a!+$j zbC=rYyH>iFBFpfAUtuYdjaAcb43kDe!N@uFu?^MJ9qO-Do#LKar0=0fsBb8wX5$gh zuCKesgCoGZlk_R9mK}VA@**Tl&7erN#&uR}y~yD8v<6;ZZ}9r>uZM-ZuQOi9=M7%R zbs}rLW}}Q{@7$B|tofNl_FbYN#ADN3Y$4#eh)dGF#&esQ&*d|W=Wc`n8NBOy*t~uV z8jvfJ*>mxE_FQ(ISau`ULgc3A+LG{@fiiop`I*Fq&kzV|<1>(H2)c=TF~2r=tww1f zm$J=j$2@u}99CJT(O$u6kBAnsRJT1~A=6_FVa@^=X7a$1ER^?SZ<48{g<@yLR>$%i zlnv?z>jp$|H#j%AHn1I`1k18x^mvAqeXfpU>_wu8;~8dKR&g@2k> z(Kk_WKL!Q&MaPbvpapvMziC4`zIe8=>Ym%TlzyYfEv^4&V?ll+oyBZJmSFs#Ns^$0 zCcfRon*0H@Gn(V`jOOe* z!59~gWin}R-h;_C^Rr3DXQOuW37HB$YtKx`%M2xCWV#Z9nbJMqVe@5vC(-zhZ#N%| zVc$`-V4oOQFc@RXHVV@y4@bXz2-!AYdr+-3JKU$3=~3&z-+HuI|3>)F#&LO#3DBqcsZs7SF_#4Jl$+^lJ{Cca2lC_Zd_ zBre@02j%E+wktZ))eQT>x+_Mc<}TMY27){<2%Cdu5Xaa^8+sVIk4*-U!Ttf!{SwCd zM<$f`rv|1ZC|$h>g?q=65#AAjv1v2OB=6L~j5I5lSHV_;CFSE7Se7S7kkJz<MK zi=072FJCqI_xIPs!rj*y|Kjt8tipAy57ie1nV~5ezED)q=Zb1vALe}+KboIUWcML~ z-89iqey^_@a${bw(hmM&xa2BS`62jaXLWUZFjJT<{4 zNcIpBnnaXF#?*S7)bgvmi(A+f`~P9?y#u4F^1ktV?%XMvUNbYvBr}s_k`PK7A@p28 zLWfWVqy&P9SZD$YXaJRfMnN%xh*AUuL@Y!$g8?kq0LwmNdlt(o?&>Zo>!Q0#a`S$^ z=guTU(Py9c{p0sj!EibE+|$puem-fTa88mT3s6F7hAew>M}u7`C-|_YlStV(MfNyu zlEF5~KcfIq?gR4bVzbD=)wbz?C6i;zy~liy1tEtvS+#32j0d}xslVKF0#y|Y`dwWIdA3a7o~Y`{^^@93=1mrN9ILl-#=sDAN;-@ z>1k81DI3$fv`5V~)%((}n|tq_7my7_cM{M2(apsCBU96%6Z(w;iIJ=?%g)aZW^2@Y z>(Vld{^v5{YLqe5n{qq2aSOG6r!@W@@p1gUyWZWYr-@c&s8fDVd#7MetjgB1_IO!g zHp+(T-5qnOtfxA6PHsiVskw5;5xE5&%W{Q|wp?S|dwN~`J#jPMi^$gO4(<-wCVf#? zch@4+U_XZc3I#c-tfVa8R$|MSCX>kmXB7IWpMw}c9Z;!zGmYFYr(>j-)gpA>6G>j> zS?v_|Si3u;0e`1e9S`McqShDng~o=Uzcy0Vxinj66C$MneYVXb7%aWA4YrP@hK&AY zSmh^AkqK0Fg_EAA8hwwET7T?J6X0oK`h}ej`T?yrE?XAJD+<~dbSUUp(5WE5pg?Xf zcaS^Eo#cGEprU<6hl-9BohtGx3hr)ycfoRboxD|kR(?r-PyPb`o|DtyH^D9|vzFPk z@jBw~$KORlif)c&j&+W$vO{IZ%1)K}b34rKIJeW>{N){%cU<0Sd43vCR8ezMRKP(v zJ5`H4caCSPMh3FbUz}d0i7TtUnC>9kx#p3m^{Tz z>l1atjX#^0A$c$qmj_$kz#+6tH`AUY^lO1*2;j&66z(SOEWXm zZA&xLbC>4i;?LPRxp1~da&vPsGBd#78xDnneRFfNBN^dP(2$v~v1MwasYy{!ZEEIo z?Xq*6=5WZD8$nrZx=m+xI!Ef9K1$Ppy#fbh>n)5sI2QV%+Obuc!U{A|L+ls-`8&Ne zCT1826{ReX)PP0Fk@msdjQq^}tag!(*&TE8a=S#zBjZEk!<6qgGh<Ya*DkXuU1oDG``)F(ftoTu)j;v z9rKklfBCEOHFJOJ?3}knc{$AdFPy1n!@|lZn)MF*$FDYi_F3bSMwY!+`Qqso&eJk|tER>D|@ znU7M1$mA@3{xkk*{*`Rq(wv_a=TBmvy{K_u%XVqA)EJW)&&WO7cgPN=rCcU6Mzbx^ zl!nV>Mo5fldS~Xyc6O(?Kgo=+R2E$v?r=q!5ephebb&lKmz8y#;2swkn>H>q+cOjE zYpGPNtxm`hsWvaQEb%N&sZOot>#90f9aYS+3nxj@m$Ajk~PPs zP0YPsnCZF}^5zoZ7A|kDNw4#5%G&OGI?K^2d2#}R_@eY8F%Xg`w0@F2VdNw@YLYxP zYZQOG>-wzU=bn^zUGEKhT<+VubYYHvOy1J(-l-3kbU_+Q<+ieWD>dQfXY+Eud2__V zP3_wK{r!PAciJ%QwZ#lsD8-$3k2o;w^;;=3rE~G_;aDd;4xX>O@#?yRnT^)nrOy{# z={c=CJjcE7O{Ej5^*vfks1NeRZ2Y~iUQG3omB=Eej_?(vmidHKn-3Zi%JaBU{{2b( z`-`UF`;aSnt_;q#Sgs7^kW#)(t)T(AG8?X(D|1%OmANz*h3CqsaKQhoTp9h5=IvKb zmT7G_^%L!;exlvU^**oDkA9j8yk*XiH{Tg_YGZn!YO^ZD{V-2xWIbFuvb#agv;uJo zZ)j!B2r;f_a`{X9Gi;vo1`8+&Nev}^8bBGMBm z3@*C6P*#{@5GNO)tSZw5?b+g{5g*0sG}LDZ2DF#g1>4C^?FY`7JrLYYXZSi;sw|Y2 z^LrMpzt$F#cVG)!5_o}H81Tv)-hrK!gHtByr0B=$%qQcfvCk^o7|w?U=o97K)o6a zM%@6v)776aqai7R0R~cQYj$)qLe-E9o4q`HYc}P=5=z0@ta-vV)=M3CoQps6wG6aGmyYBj8sE7>>-ehg z(m1x0w(Me5+cX+Xk;w%hOtsc7gxvVq2fu&S~nqkk!@*54BvtjugUad`H^C zLRx(9(mKDFub*t~B;M~l^qbbXr)`~6o*iVuY;pB08oj}>5=ONIZ&$1yd=u}(4$uy8 zj%1(bxz)OXc#gNwk4-T-RxPjYk+$z5Zb(yx0f)lV`mQ==v-y~z4m@9=FfDK+F%KVU zr?h;BvBWo9%Xh}}S2bTSGoGvEX^-@X^-<(~1iTWY3$v)x;*b;SEt1dTZ0d7nWCbTWN#pMA;*wBUBqdoAcnMV z8=y(@ly)y3v3Ue2xqCN3O5%6%GwlaoeDTGO3(t`KSsJ-x#}{9q$*?nE)ks^gpHq>+ z8K$hUWM*~NSUkF#WPgJ_mKg4`Iy^~0T!F8TzIyWHc{n>^9)}~I9&ooV45e+^;jo!v zGeb0rWr=T5v&3(|J<2MTt(WDBOF!>evSf$SNU5(aEiE{y#as1Lu-CExO-5%cY{R&f z)02F`m=4qOKFVCDE5%$sPFe)Y{F9dn7?RUsWgvkG;siavqgp!gJ4&qwI8^Y%a2sgL zk0>)x`xEW`mb8|Z)_M}l{6yd4^WE;E_E?eI5wC~ZJWk#F7qus$40vT0iV^JxX!Bz& zGx&N%d$2Aa#&Z+j`;WC?MPgkJ<Uf5430gY$QEIJkHGk(Kc|ss{qU12iU&w|ko8+& za~L6LxO|22CR|cJu8;C@RqI==q_d~h@dn?mF;*YlFKzcA-Ie@ZZ&=*Y@@isRGy=Vg z=iPt|r?v$?rnMm7qYH=DUHo0)HnC7xocOMI7hh|)2_FgzV()qpe>xJmY@>%f>l-<- zHQAA57hn=$ZzFe;VnE8|ba)T2rx6DT&yfL^T$2?b-Yj6&cL#K+m3&5&3KKVP0e2Pg zDh2fgwh9|%#e(9<3mF9m8Y0QxKf$_HD2oBXI_05Ze+CZH#y`zbz6TPr*kkt1kMnP1 zH{x8uxoQ%o$bgG8@NaJ*LZT#i9G3w6!ni~)ATO^cOlW6XKTELv+`kU5x|s(N157R! zL@c}PF%;ef(h}ob%NLe&mLzH#)G8dlXxJMKw-0@*Vd>!40KTzn;_UkXG`ng1?E7Nl z3cnLyAJS`l9nc_Q-bS>|o2tv-1UY?CUp;1aBuZd*%CIQ7IKb<{J_Oz>--jT4#Qg9* z%=h68X(?YX>-clLt>Q_skHasQpRchh+PRF6WZcWcKQNv z?`i}3KAa(lqa5oorW4@nZ93_IUSamvB|obd2~>K8p0e!;hKkw4+-MCgze_2c)=ocj z>*FXP5?GTCe02Qy@atzk^3}H^N4;=$;mi@5YPPTCvnJ3!{bNyx-lURlqRmAUSv*2QII@(!YeT9-pGc&RSC5QG+&P#5k^=y40^7FX*^Gk^{vp{^TnX0)fe zu-;G?+RNL(?~ETzgYik90UErN6HAL4?D`9yKaSYl*q(b zA2{&i-uz{3E+E5~?FCHx7l6_H9PQIkyY;VP4d?{oj=W1Q)Ei>KIeQG9%+X|5t|n@D zF(VRe@Vja|>p-Mkm}CP?yC9P9ff!+vC;n9Bzn5Y)9M-&#ga^vXZGK zb4#|Ayj${K$+;3eH>&H)3}s2AMeFA1=NRTBX%md(+C)$%7-+2AbEq0_C}l>7#0}#J zuLP3o4zi4E26ChL>^G;wD8BW_kpuo%%b`R5QTu-1;oq!<(frqEW5^=nLmLn5f4n4) z|8(m;-+Tus-k{Z$W!s;#KR6eOoQh z`+YBL38wn?A!|m)<=;@UXDBd zSKRT0xoZ>35&vka1I3}nh7AwXtqcTy+@auXq+1rLa%V_;f(?}iF$2}!B{*VuyEcM@ zn(Nr&h~e$hMUMdc62$Ou++Cu}J3)DU9Dld@rM=BZVd52K>J+0sbKH+K@GAxeLVzHVY(fMXIkE=-a8QtM@Bem9PR^!^5&wmsI4}s-hw2~ax)gcF zT{`lUW4wb&z8roQCk1`+vskr}a-B-Jlj~IDQ5JfaAvrsy=fvt$?S9|$dxGk7*8|VP zg8E2T*3exMzt4G{s(vNh$@MF>PMt=yUR4o0lCU`9}80VLk-3=VEaQcHB2KURb%PBlhl;*nRUX zzi&_nm4}@X7|gBTdQ8BIr1IDo-|+p1a%7(ov48OVDhOS>^tYh?Z0%2M8RnxqA7hUQ z+VfaU6n3nx1m_0yA=Y0YNo?Y!Wn%FQydG&juLp4qm@8A8UKO)NDRpsmB1xcwufZ;mJwJYS#lmXNzAoCDzrVYCIRdPg%+TG@8C{XKe$Y>YY(;+KoLq@0mg3~u3 zFQn^`Ylvj#ly{_$!CX=Va|zi?&eJAGjE{<@$vRVNHa>}6UR+d)yj&78y~z%{9zozp z+~$_hm>EU$_2@AVJ~(Ey`a5tnCyZZuvU>UQ>XS>yPv{=qv?XroyZaKk! z2gqhY;r8u>vblYGVZn^uT8XTqn6{P;n9~ZJnZ)VS4rkVX!0D4mA}Nmy{=eh&aS-St z5oNJ|{VuuBU5hrq^g9GU+JdRq7nZ;9gu2#9R|GeaQ>WR52W{A<$*_}mm4m6s>d%bY z&9zd4GkK3|gEP0k+v_w8um_V3uJRn}5j<+g_|%+jo0luhL)a6!Y`PX)G6$OB%{Pei z6Q@aY@RAwOxp%RqmlEcPv_!QJuv2)2V%h99AvM?DNoxX&bN*=>@?-XsK*`nCnV&YT z(A6Ozh+qs4cswRI#Jv0h-Y#5Iw1V(E@i1iK?qZU6#BgFzy6TDHBbt}7;b6z(>`89{ zck>VTUe&Mp)2sSPyPG%t_h+B}w{#VIfW}YYYuqC^kssJwwm6(2ms2;u;&&Qsc4`cb z7PZDIBu6z3R&yYlRO{GaRq@HNosJ!_*&J52SzKaN-BWxeBd;VO7MKAitqmFW5X%@T z&X1$IVb~JUVbQohHl-xsx+QWv709XnRl@4zI?V$q;I0J8TT*RGs@>(+6jeb;xhLG{E08nYIndeTlGFhH56 zY*ZdmrVSkU{?sXuTyt11>o#R7&K&4Fx{3N3@Q7R`XN2oQk;{0eA|db@q&hhF6#OAg zMQ0IbpgM0U6+)Is!J`CWwOug)+t?qFFpR~iLP`7%8CB(Gi`hPUrpn6m zo3vC}8tK*POZGmD_LDAk5@%Zmc%qRta4Gg~CaX!`kg0dN{f2Z7!V8qf^F=4o1wOPq zYOxK9H_M*2oMSZp9u%)Pe&p(|jLAEoeA^5C3$7n3-SN{Eka^8Eg5*@s03*&a#0JOx zQ*^fJ-27}y5q^VbE0r`To}|S!KCFu0;@L_#wa&*Qd@m;4qVwvCq+4w#l^Rn>9BO)C zvvrcq$p*<4Fm@9BRy)UH1F`n8LfPyB2a8dvb3U!9Gh&y=jSz@Hh8+U7{V*|mW)$8hL;bAbrSF0kR)<$q9q5Ho8u>wj%e+nT+EJxy~<_{FrR%jC2`)L~6l z@ryOi8bBC>g#-}Bf(sbNL5vH+ra5XY^6TO_jRz}3%R^g3$nIP(V`ia z;F;^*d|wKow*67O4tadyX(hc3Xf7*sj0V;g3Gp~a|F039Elm!$)ctUE@Dbh!u~?o+zpQ@13tZV=FdMX|9)@b{ml8p zIY3@Mn!}!Y=%Ia$cgV$6H}@TJpK`AJk@AI;3Lv2|3b>QNtC(Z(++!^+ zbaPZV-&)E>B2s~^L}Rj%Y?TU%s(=E;}eh99o)Y&`o@u)-W)Ug zjVa1E%6m^}BH^c&J^#m0s6IPu>4Le7ch%js_Ti$!S0j-hKV5eW?Is@vFlLBnrH>qR z7@U?m^RsOncTR^v(3@jKcf{eRW{_~m2-?L6j67>cV$CI-cWne}aqhb~j~XYy+tS9R z)=~}s2;pL<0(A%BpVGvHVXuQS#^fg zZ7KWHIl*5J4~a)9mCTPW$xHeClD%#4Qwi7R<-~s1JaN@q{7U>?c0a$r@o%88yM*Eo zd(EJX(k{XpK$I*vSS>jfPUe*SUb8=#m5sb1TBnnby3PtFJFgZ=EmOb32)@}KMN z5n!L#WIHmaG+tMhAtMYmJJV^9^zCUTzz$)d;2cl|E2^Bm5T2?0P8YO7$G}4Se%l@dF4-cjq z(#qS@PJm2!?Bpr(J<5JVO;V0KTc~k(QnNK7hp#4-l-ZEJ!4V)wGQgLpBX%TY;S~uqE!M$($;-)#u7oV2D_*eoS`Oxb(Prvrj z&*n}IKa{ri0p;vZ%3t1mhZ!ycDE~(Jas7342XP)f@pXPycarVkNYufOqzA?xT=0^) zjY)|%)!Ad*cmppH?Hu@E;*hP5w~pVus%+R-Z-X$Y<0}vEJZ_J;y*Z| zl2yZ$+86D=aMpT-nUL25Ob=IelF1gZN(3B@Bg)YY*~)Or$PtsnkYoUoWRk%_L`HUw zB55+%HCD4%)YiEkus&l>qDjIj!95YJ=oj%s8;*7X?T!>$mH7};#JD=^(f(`ipzQKU z^QSQq#N*r{;gBSsE@YMy@M2q%%vO66 zyx6XI!!azft*_l;)R-K)I?V=Cqr-}*h$gtv;3q-rWVhX6v09*vSS=<1HJXtc20?&l z^(M6WdApkecT0fXXv;O_m~$=dt?g~HdzPuvy@n$a-e+BF+hp2c+iQB#a?tjg?L*tY zOy^AhGM_W2Os-F|Bw59I7(nnR*^`Yq#&(wW_Hlr{yw1MBxY)ANxW;n7eZBEv%Le-s zMkggp#IC4T==JCmFC5){{m=ybb?FX{Hs9Qm0K(q7e)2FTCZR~y!+VJFz>@4qKn$`$ zGy%mBbXFXa0f}yagH-7{=fXv(;RRe}IRu>pH?>T8HW}=CHOPc8Tm8 zTV)q2)G{j^Qf3_pjvQv402Au5=a-|ZQ^)MbAYOU9)e}@d*<56sT3n|Sz|FP6g20gT zY6@k6Tx8Vj5%*B*B(pwAvN;5+gP}!&)*(Vuv{@NYOaY~-H)9bx^bU*8LTBMwuq|oN z8t|_cKjJLJGyJb75;Cn#J&RdeL^A<<_F{h@pqvV`c0=Cm%({mWsQlflphUbwDr&s8 zs_M0SW=)&*>qnZNO>~!&eNUf*eVBvjHK*WohtdM=f)&nyyTTYSNF-wdejc`BE+EOt zdNA}k1YOu*_0@$nS+%*&G{cHe{`sCg;V~wvOj>c>BIGN<5lh&~9AU5ZCvwpN!H$FA zz@oH^fas@AJ(1H5Q1mCdbz8i2^ym{O2#kK**bkO1TDs&*DfPk+hf0PY*`Yam;fL+R zhfS?~LUZ=lb^xUB-5c#ES%mXlI)qxeT>{^w!69(5g!5j;X)jGyb2p;CB&h_9u1Ho= zP0mF)WceS|_;xkf9f9osR}`48izqPL#F|zr%(uT9!1-ZY`7mqZvJLEdF`uYir=i#p zU=+nhx1Af>H4C?1J0^EIrG8u5kWErMCI&#E+!Gh8@*`riieTS{XCz2g?J zW`Z+Q^O|zz)mK@dd5O{jFtc8aY$Pqhb&zY)5Q~5u$n#{|J*nN!I^+2w$hYrHe}|3p zq%fXg!?1tyJSPn>a_Gbi7o#g=`wN76vgk1q4Jz$r7exsc{zo!6} zLB;`iDoAo9D<$204qdEYMP5+Z_!&CKHJDOIwoZHVl18;pl(si_8q4|W?WXZ6QRp+v z@6o*f%EK4#eLv0tntEROv8f|xxg=`8hU+9BVn)$U#Nufuz&DwUEcEVjNL%A*%Hh220zr zv#(#Hk_`M~#;A{97&Wpvh1`TIc3R^Q4xsyskxlQG`WKR(FJuwOD^ zKK9>z*k@s3hV0P${JJ!wEzK`=6f%r{58-_RsfxSJ=@gXxef>UU7hA)Eb(`%WbDbju z9#Rqdat2NlApMb5?i~sOB7wr_0~N5|FX|8xYNzBM>vt1eT|x+>vw;qRGH*&fQf7$6 zY+w_^N{1~F(w{uTUT5CpUoPEL)A;nC|E)BCsQmT82R{08$*!I~CQMYeozdl_XmrLKau5|s82Hxf8K~anIpU_JB;aRNtUoXY|tTAWK;^7 zLeL&`zJlR;8~>TNPN9 z>J%o+-avXFEfDAw?2z6etwW$kut$22v>pM|JTk>{BnTS81ht*RR}nNw48>{d(E6G0 ze6bN+4A<7Koc8+68(*FH@xOK+D|=}Anl%%550}c))Av2TvM$ROsTeYHLP^Py%*=zE z*F2JE4G)sXjLD@iZJf>ID?q$0?wPK1ekeaer~U~0G#O`d7ulRX$X~c4&#{f7JJCHM2?+ews=?- z_@wq9QGR6kFN`X29#vKu9O0XnX*7$a*%x}vs(9q77p49G^>L*<=h00admZ(8me6IN;;%WAYXkbt5O1?DT03e$5^sl}IK$_8RM9Pd?fQbqanb zu9@(VHLjb)H2G5C6O%60=1T^##E$y%g4x;GA3T{rFR>rT1Y(8Utt=A^XIk9XK3?`% zjAoVMR?st$+`?mF(Lzc*1(lwY$CINSN>VG^tsQy|Ls*WzHJYu}`wo>O?tPCFbG5pQ z_G@~8_I3(CcU9)wi7^jQ%D8(PHV*KGJu;H!5OEPRV{r+v zX6oyVhwWA(1hyM!umnixoWm2>JU(88U;oKCT^gkjZ>689Q3_Bzhkx}p4^g<#OVvH4 zSF!e=ZuysPDwkKfUT|}Hc4!IG(?&J&v8xUACvC_+b^4 zij5Ap-@+vnN`b@m)I@3+AXZpfUAlcm$O~B}gpP2fqzJnstbzy^0GMo`8Qb7#~(Ap>(7bfwZ8k5k6%$vD2v%W ztak&;yZ8C$rz!Qve^5SU8Rw3(q0^qHw!YQ!XKt5C6*^*25hG~O_|3k6Mz6-T%^2<=tW5 zOuG(B{eAS=T{m5Q6;m7b+A&dg%MxbQoNKbb@-WSL6MPZpxXwL8wz&dsvjk2bP_`z? zdS8sP^;oxjT=KGsGBjc0G9^6&r41MVNwNv~&EOE0OyHgc|10!Xu*Rr*xq38{=1Nc& zDx3w-?r_NH8O$Ms#LJa!?qbcBKI-O)IF!3iG@m2V*5MPMfV#aGRLEAJzxgN`k~P-m zP3)J|(6;Y{63)*YS{-RZP^C@4|1PFY2&uFQp;XWoni{ zcaxa0j(v`C;Bg~TCC1@3xsVS59}GSOd@%aj!2*$_wd|3s`aMZ@y-lMt!$5(tVCopO zQ9|%Bh*3fiRQ&`{Ld1wWRLcvU8>^4)KWkqIiTl#*XE~PdToy4@m7zn#=fo!xBRkq1tv)jmKL%)D?Xe_mf zTD!^QvG*`RaSF2?qYuI+xp5m%JiV+NMPhlP>F_%i;I= zeGa$F9q%FarqlyFyDIVH4_%7k9L2P#QA98TiTl>vQ9XOr9k(x5zS+2Oj%691RdV%}(!LuUK{s9PfLw4c=Z~NA(c$9(`vh>EX*>jScEoCTbdKNy znFZJiw6H=R(0_W|V)d9|BSv0bF>aa?Vh^*x-<8jhFoW+akFz;S!I#SS9#4k@A&Zsy zzb}bQUnX{4zgwB{wQ{!5H|<`GJuY-5HbL`Gsrpilcy+SAw-rUIE@j$8p-k|+ieVs6n;>atuaP-Hvdbrt+^d&>4ohh zdj#AaH#Q$r-ec>OKe5QF^_mWQl?Y?+%~HM?*DfvVwjV#eXbq;oa%Bog2B*<%NHLUi zH*%~wHnB!X@f}Xp*I3Op#>P~&L10EdTL5EdLX(P%(wW*MZ2DPy-(e3&cPd*n{^l*8 zUVmm6Z;|rNi>IEfink}b>Qt;XNQ=W+4qbRB^dig&(_eagPz+ruCZ|0kI7t{?i#=jk z+&lNio7X7cjU731=%6vfD-Kk3W8KHS)LZ=e>*Igb{N?ua#S8Wxy8SVyBXeJ_FL{2S zyQdGG&ulxGTRFP}-G@CV&T(mlCq;%e(qXV5ei3FH?nWt6C&b*>Q=?6))iet1u#XT# z&Y$EL!9lOqR)Z)*|}!qe>Dsn-t?|GzgyQ^ zPd~jxc@N~4eMc3}o%e`xHJs?{e!07EpC4!(kl(`AW1VP(YYI$X*E{pmrbd+EyLOp6O8|4Xo#&gPsN!KPkM_!}& zgZi8;;?I#YM>Yi1^P^gib}E04eaoMZ)4`!ad5~Hd=~2J>9Bb#2`bYBecIXMSI4&Yq zGU9G|jH{q~4#HPY$|tx4uS#5l@Lxpsw$D+qs4l}*%;9;Vrh0vd;p?sW11(=*0V8G^ zF|){xMGXI%mLTTYRByPrTrBq|h8ajPx0Gpvc2Mk4D^?4|++r|v&!w6vbCCM2#!9zg zwdF`ZBbPw;oJXtnLyfnl??VcUy>F`bg-nd8t&G=UD7I&N#}-hYKv%So>gMmN`AEW2 z)&qZYr0tuAiKr7L?KZ?@LoR-Wg|w$|TPesasPgz}ZG^-n0! zCA6ol{DfHjG)9z%uM?3Rf_nMf8VF+mbBp#NbA&(VbE+@IbHu7b#-1mPVm+=<{_4c? zy7MT16_xj1-LhVJ8RZR#A0MdijI}mT{D}3&xU7!Xub-p+k)E?}TAJ`2dkSX-#b8Ld z$0CTTvWK%W(gTjpAaN@8`Azn0sK^LWK0`4Wg6xxmEJM(yX4XYg>kQ6qj{P1Ugpp0o z6^IdP494kaO+&_ve=Y;kFE&4HV7UA|Ajk;uph{r*UlhDZDGN9NwD;b2+d}0pTb1p~ zLUu2k@*vaCxhM>yUvsl^P-9j;9N#i}EPDiLQ#Z3m29_s=VdT6p{w@mh#hFZ)0lz|5 zH3^-C@v_yHQ4~?B*L@xOm#FbgMHEvf$f+TRH8Wyvm*iXJ4@5nhXiO_Ks z2pH=;wE?6h^SG^J1mGT4-OXN#m7yQ8Jjnrp=b3L2`a|ztk37`3_wgB(%3qZ4uA2cQ z2;8}w#TggQZmAf~Mhw{@ZfTzQ`SM$DUGyz9Mp6;6x9Cn3abC2_I{}h+0-_o=(kAcJ zk-W3we~@=nR&Q?BP~{!&83gqI`s2sDK5+Gyua6$n^nkdnSI-sS9opP{NM9Wtcy-CG zK!PY$-eLQhdF_C5r3KBxIMUiJ)>9s6M4QgnZtRZ5+MS`Bf$_!NigUFe^R=|$fiJ*w z2w*rrGj)^L?Wl*&;nRA0{-pX`dzL>}&s9EuC`t2|aIWgAP#)(g>R-gJZD~e591k{@ z7o+g7(pnzl159YDKQ~tYPF_F1pKumX{fAoUG#D5kPn4(n)$+N( ziJ|({@@oBic>TP53r0&^!0Ydz)~}gB^|v6hQ(U3eubIi~hpd5mw0ORl*RPh(1qLJP zZ}|$($8wyES2P$2v_~z^{rVn2#_;+}V&iiguOE`HW^inLBE0>$vC)27Z)14evaa%JWu`{BaP?d=sElkZl0G(A2zybHkAx;|?zGIdk4EXv+X)1owI39%1Pkd`JszTjK6O-Vppq4S^1h z2w={dAwF3?w|BVjjT;|3P&at{PmfpSE}GnzQ%Y+=g4O zV{aR-nm9f(mp6AdKgsfle z0j zd^-xv!u{#YDyBgAo|Ybgv<)#(h&O zH$U2Z=+VuU)1G>&-`JJ6fbR3PVZ)RkhYcGxd{xaRu$(U&(SKmaK7Cd{-hP;2#;j?F zmOmfLsH$4~$u0QjleJY<8Nu=i<5!M`;K0X1ny0k^%cL_h_L95wHyV6>t(}Vu_S|;u z4cUDqLy%-&8U?zf5qZnShtBQX8A7zv(!FACV^{_U`qJ%yC2RpD?J;H+}HWEsJ|&-%o<<5rjBdrREiY-Qd7?!mSZ-m&fpwwdnhZF9Vf-M8AR zy<5EGlF-6q$hn)yoetw5w>*Zm!N&*A=g1oue$qVKbe&Y!RH1ppt$bb);jZ*e(gS-p zU6{kq+wriq5GS=q*eAo$=dsw_PKQ&c_O;FB!223=Ias*M;aI)wtaOT#VZ%lQZ@uiP zB%8K640|vPdmN4KJr@rH9|1lV3BypNbtSv9T?1T$tXh-J=JmN#ZS8F#Zx?jFz}w$F z$aXclKGi$ZJqz7l?tRAV`pu4O{uJ+ca|tn4tL)Wn9S3*ydT?0NeWl7lYJM;nS8$F( z3cz#K=Aq^XW5MIODhCn%9pX0Patd&fxAXF(SG3{Z0p9?)oKz2&Be?!easl-3>FRTm zYZh|-yMgX!=-&&t{(WirN!KTo*L{ocLf*iAKB?seAw3t7XZ2l7O10qQ)2yJ0x=Ydzg@zi~5^CPd@6S~R7XuJo0QU}!G;B75m# zFq&`FewCtM(_rh>Bbw{C+Mq_UaC;+rKk>_5!gLiC*3?7^DB-eCivI*Ug7V5*h!>5l+)q~rf zYls>;-2RH*oZ)`O*33PhzK>JddA#;y1N+@@Tr9kzJ0PTKttR;lHwn|GI!#UK6J@ zZ+}f`Y(A$nzP5Y!YumTeW!>~GzoBp8w>8NU$~b*3x5q?aS-pz-$DCOM+B?#mdTaWC z9KaV}+CQf;FY1yyMZ+l#W>>B4a9U#lf*uJ{KHfzVFx2L2GIAi{#5;yyQa}r;U2Yo) z-P;LWh_-d@L~DP4-QGF~Y(_%+m4Chl6tz*YuD!N*Z>+l-Z|gW<4x#fM(k=u4hZ7NF z*lDcT#k@&GVPs>O`kYMgN+%)T28>4H;ICJ)X*1!UUIqfA58o~-?=ebb?tF2b@_jO! zbC^vAG#ZTH+a@SEO{uK?xdT)*k>57mz z$ZHC;FHd$3rS?$Lciau>Vwu^Q7%_)?{>;-05wtvd)uLYAubo-dsj%sMl4&&)R^GB; z=Iq6b?o#Ss=_Y>6ZdutPtX^F{o@rkMInk_l-^+5Q-a28?i|xZrGcD%F^7E&@KQJrn z4d&5I%HRB$@-a8Wh(c1!c4@NIh<4#@@a8~7yu4l96~kSB896SNP3|&}`})emV>dj^ zbYn+$>NsKQBEPTseZ8*gK*jJ8!-tI;J^9@FQuh6T0SBt8rVRhfeJ7dovBw-n`;8;k zju8*aR-R+cK`!bcCxh&*PBiNf(qN#}8hv*& zu-1s`?IhVbAvGgf5(^9t62f&`u3v7bmZ~*v2@>3Cq2|*7+-)jPsaZ_n1e7KrwmgqH zDa4%EunGjYdU@AA1M+7nI7M&$w`j<(;f%HmbQ?!FVQ@9zVep36Y$a zjJeKfz%|CAV#G)e9s0#PGwX*A-#u~7Rs9PKA1ZsjV)W9h@7l6HZ)nb#`2!|=m!4&J zOuKPrRn@eWSa>-@a&sfLtieN8KE5wKeSdClUfvivk`=ag7&3It=4)ivmOHXG^~%2H zpXq@Aa%LVWNlER91qojq+Fguu(+4aMcwLjdtQD*VEo+Zhc^;Y2JbY3iGvMPluIFFx zHE{|F2vX(lrcdpK%D-c^mu)s{V5LL76_`)rU-2O-)8TZPO_EK3+sU8I0+J2%=g6~z zw}~jZA@Z1nI<2kFZmM&x5D{-ke^VorQQscbhIbT-KhmLI1p*&vu> zO^C7F!WA23Uh^u;YD3i4;6)oifwrw zN&ZkLQL+eu>`1bNOj!;!0*qJ;j|$NtdvaM_L;{t18bZx1h;Y!>S)a~CBmfkk?+GHF ze0E4nCH4ZQy6jYr8mwsbhX^taNdF-no5MHDif_HO?s(0;wRej% zmELpa&zrmJrRUaccZW`FeDlBA+;!^t_LcS>^vw+m=v3L}(FBmb+7+|xLY6H|pfQz~ z?9FgA5a%p@!;~kddF@~ib8G4xNy*7VN}Z(^*3ooWMJZY=A1Ojb6w*nW-N9gRZE#Ca zLl-pJO3729W`~elLK{|Nj!T|DA^!Qq&YeJLqil%JckR;bYYy&z^_BgwmOd=bZhm;j z!^&ypLzc&~9^SFz_H*yQe=aV^!al6izz&JIdaI?cbgynbe5YQ-qvC!bkAVgU3jNY& zmI6%*j%f!2bF-#lZ=dlGZeT{GF)DUy-q>evpJ&DWO3&yg%(Vg3rt6Qy5af;=LB96~ zVp{W8;v4Lcf+P(II&oiMRj0$gmMwH7KO-F&IU0bsX_9%w1y4oNXS(p1=ZAPpi%Eag zx^NEb^r$y2;q?ttm%5s2TGtjykI5Qd3%_xVZTrYQB+Z z+a)$M!<>or$Nd8V$YeBMqvb5`5%+UGo6aPdYLX87MAsgG6gK+Iz9i!a4~`!&~-Hpa1RT+kgN2+b91fefQ0;>(!v*>bsV+r`RO?`_%I0Ta~Yr7g>Ln zhJS%UMD2$>sFnHonI#OAGki6|;YbF6Cju()gtIZiygpYD$P+Fg#G6!v_$#y?qndya z57LNMcN=Gui1jKFfCGnQ%dU|rpVVqjf-$%6Wdlr1S7?1t`Z9RzSJ;K$Jz)eICB)~xt$cXy$g2%(Xv3?~AC!+?{_mS&(Yfr$wd`%Bn0~EQ z&hh%m#$SoCGr}wXylnRh8e>jSV{rS7$ha*huY3{N@OWBJq3jX%c+FN_)X|U~S`|DL zh-TKB8wpZ?sFrCo5n6uGA2fNBtb#KZFfA9BrI!WELS^9*=_7(8LL& zeQP=gtcmB|iu^82PCP3#+Zz(lYMS4OpAwpbdoOIgB83F4jYF8bC(tgF+AdAhY)gvz zJhirl)JDJHbPfRRt|6tICmup1X>AusToT%)+U+TAtV?1ZA0cHGYrc-Rr1?HN%Al+B zqpSh&ZYp99pxqJ>vi4%7wqc){_?;0M2dBLKr|%&P*b421%L~^PZY@lN!GiW4 zcZRE|96C=XsQ0*}22mTT9h@+k88J+(D!neJ_n_HN3@)2G`q7F(x<}02^6OYfsLy#`bT#%Kx#V8n5b=!&O3q7em)QuzCEA zUe)v&RkQyv^Ez|W^9|xU>*PtBR*xDjPWko02exeo?$ghkH+RU}-#I0vYQ~Xu?D4Cw zo;Wd~kCcJeN6vzzlC;XOTFdr$d{L+8MQzmF;H(XZp43!>ZHUKdVEvJl74Leihu~5J zaU>R1fvY6UZ+;$G%_USMke33Y4{_x4G{enr|3Ot%u&}!+A2ofc{L&!qTnz<96yliD z%A2^_zf%sg%wxpBNc(yj;@|GVzBa;dwpg}z>6B~8=`1=eL$uDIM~xP10>nzw>0<}8 zlTDH&0`?HL1=*Irr&CTwN;IRPBq{2sEulO;`tQ`~v-QDM>8mO1S~h7tCW|O#CmS+= z=7UsW+1S}6X&u?go*WNw$GAaP>KW;h(}f%Cii;S+epQ!h4k>O39#ihSL)C|-Z*UrX>H8BIV<%<1Cr_6%gce~9?cG(`+&^=oxUO=M^4<1r4_vpIy_l0Z13b(rq_u6%Y`5?sWY=%5ocJb=U+A%S zBP*s&-#hf!ys5UctplfgA&ZlI58n9nL4;yGg{*_FT_=w3TD-AC z$8xz-CyOQRNuO_c-`T6;L$?d6cx?T@hOtS(odKo+uQOQaG&{2;X9sTYMq)OclmwR< zO>HP}>~R(tqU~y7y{BbFgYkT(6U#>RK_~j16FQp1Ek{@+>X6X3KqAFIE>u=k&HAs4 zdN%9Wy!kzQ&gESPy2XbZHfT=YJpb+Y=G<~oXSNO>ao=RQkB|2jvWFFx*2h&ph!}t* z;lk|@j4Q(Km?G>pyP*h+P=o=mQ4U@Gw-jO0f@A9WT(xchFv+kjtJ0Ggs*`Tz>bJn*7 zaz63Gkv#zM>GkI6({H|U`t;wGFO_e3Ea%~)7sYX^mxkI$X(Gnj2!9X|!+oZJ!LiEe z!ATa)Y&1lzhy4Li-kAnyosMAttXR)ld)3yX$nwb62=&MT&_30g<-JmeIy;NQn(fNo znumX*6Jk*8#a6%l;+0$f3(LcDhpa|E)DbvK(+FJ`k-}_`CN*ksu5zqK+ZznE>3~Ud zbe4RO%PENQGy;psev=SA4EQ$WtU1U=rN#@#tlY8IYxX?K`ds_b(q@?3Am_|_ZSvHY zsz`PlvFvf?sBJ!%m8C9O*1fcJZ|~k;z5VuAHfozFR3d(924BCK!fmoKBKn;AkkjJK zih;8odqD`eHNKE~x*Oe5<6-D;&c-Y>P{n4m=mSQ+RO($oW(!b$)B%T63;=hio;gI3 zKY2l5u!GYxoKpuh*e-O;9{`FG|ABl!Jct6`syO1>rMPV3bk_GJW$Ntg9uMQ69@(>% zsV}j<{epo&ZujoFfk2RbBi`C{`nl1|t5&RBxuR)3zLjH;>`gZg*$ zK`*5~V?O?OeXjlguFvg0QRWZm(4YF;zrz4!{wJ&*`kWK&+BKLH2#SAXYn%Tzedw*d zSFTvGviGe+r;Eu=LG(E+7nPS6$ziq647lp!r15;7yCHQAd}UUqtFbz2jjYjp*lkHN zn1+k++Tx5Ny^xk4EW3P=!n}dsssE{i-HWOcs+53s1?CFMve$Op@`Av36 z+|@j7%a$WM#HGLdERLI51;t(El$wFFDHXdm#+Alt(gJ3WbB`^?m1c9=!Ifqr00Itx zz*VfC;NOCkFxHOeE7Qp24)cVnWYG^XY%mqp1spCaVH!tr8Fo2enu-#3lK9f7T^JK; zS6CPxKN6gRZRQR$+omR8}*vw=W%I$Q;z*xi;`!lEU6Pieu3xFaj z9F?GIXuDkE)}zc<8g}exsIQM(RmoBWgDPYiqz#BSOO>$IBfcHubqoG{7uJwT$dQd2 zurnA0B-#U%mGHL7$&e(O_OM26(jG%Te?+n=spiN7EOy)?+IR16KKHDqamS9PZ+7ee ztqAHw)Svh{`jsj4lr0g{IHME61Fpchv@HASCdfxUPdA+^l$~yem?_!9x>s#!rtqsi zVS@`!NqhvBF}_5RJr$SKi`CdWERLAKP7!$|)U#dolfy~vAFmex2r*?P584v zS?6y0jUaDq@2k?Nqb8AlAUY#qV{j+nh{91ENuS(ka}{;dfi%Be)JKY`L}Bu$YWz`{!hZfAwl04O|zK?P_979I!C;6QjO z0Ky9zEZ&-+lv$gT>NGS0pA|tX2}pRdt01=`cW&;w+^zWcXzu5^ExAc-a)d8s6(5hQ zp*&v!KgH1T)RmsC+23z^<;rJ{MCUJDJ9>0<{^I*~MWekYjwf`yk8kVM^XD&dxJ=)^ zxpK-5aS8qK(spslg~y-0wzvr3c>ElU^=I1u)E^&!{VwlM+F|sF;&A?-yX5$P>C!Lf z#fca9X(^=PD%oij95$ChUlA~*RJ4m2a>^n0;(%)6RvE-M;5@Cdr0Ub$krY9fmm2og zc0~bfcpoM(O2CF=$7$AZWWxmdv2B~_Vh|r!@eOfBRJP(9 zA|6Y+0WxN)FjBVRCLeAOSga$A9)nxGQOWy8SE_7P$x8VJ>~3V7DUFU$ISB~KZo)_= zs25eBt4w=0jeHGlH*VYAMv>EWncctz0M#`Yz4XRi!0kQKE&KV68@qG0vu zARH?H8T%jLvXVm{25TxlMAjr%E%+5YNrkqnUk4cqHw`poFY}MS@^bp01 zL2gA(*#DvII{>4qvcKPbWqO~?q}NG zsB|&GM5U?_)J3pjUAu_rS|RiD{my+eAwhTl`$5{gdGl^N_uNx|2Q|>Fu#YuE=HVW* zzA{XJ5)rm0$|Sp-1I!YF#%=;Wk`m##3L61Mbihm`fpa8=dEMOntLYNrtVhaR;#^nR zhO*s(Rl7G{V=fes=f%jRPmV8JcD#1yH;+F0jZ_OG(G?hpUJbzu5-)__iPY9)%$*A> z+QV;+mj$CvG`J&NHm=LSxeC~bQ-@715!wNCOuq@bv8&1ytKS2({#tO1+O~d!v`442 z+1#W@INr)ccaa4R|37^rc$|lDg=^tZw8T1Z;G*aWd@r`H{Y-uF>D{}ZW?h@6Tw92L z*HYx7$JCD=S0CN_@LCqeTo13kZ`#!N-k)|i`ub?yWu-mr4sM)q*?wzkSG_CJjo1`d z7 zC8bK;i>9XbcuSprwnysJB2{Lc#3WYGy7`!QcUfH9-g#Gi^wg8jXN}kf?E4lthOTWJ zk@ftOr(T2C_)fK4T|Vtl-pnWGE!yz|*_38tPyZ9O#&yzNm}>?*)0g5p%rz>9_>Fo| zHrbF=uay|lBD$?6-~q`9#T4P{vQkJlT!xs_tP~hCGs#S@9USc4+3KGux3jiGw?182 zx$kvTweQ?ZV&5A(X-$Le=uH1xJDdKec6O8p+j-+f>5o6*c;xLMmU}+N<3;SF#o5nF zL-IBpk^?q$zt?Lu3$OxJhc_HuIL@2k=&&a_yJ|ehkmEkL(O}`%E_nXQn8o8Pok1`Z01OtuwVF{sG_Obc18avkq~?1iDMMq6 z;ZjfTdaVpPVx=Q4=ed_^@g(ko)y5C~gSQzewDw1#1h%=@QXM5kx~1ZX3TIW6*@bo; zgkgbpgBAg-r^cP(2#($n-Jt3E@iy+lwx@ef`Br`Y$wvJMZ0ExUUnYMrUyGHHZSMtd z0ZzLgm`8#^(K~>ba)l~q`w=)~DK=L@W0bjIPfXO9G~m22Y&J(~tV{0Dhu@+Q!b8-B$D z{+53eOW=`Y&mLpg9%~g$%sR!r_r>3l7+tmGqefty*7_UnasU#8V9|(UPwBN2X zz*-4T9Ol_$5USjn@Z2FL4nSf~_!ywKz?}dGzKwB{s?L`PYk=0#W0iXbEbh7M@E1YXuM0pHxX(n@e zvR)XNY_RDKaT%H&lQLUy#=v4ga4-DqQ-6hD5fTHb!ThMc1*bEMGoSyK&dB0loSobhL~jM`^uS-TTnz2vgH7v_$o&Fq^%f zVm29=W-*2`uSHG)out@a9cE%WU9qx>3^f=lm_b%}y%hu^kS2cSy`-TmaDHdcHKhKQF}kLf$0FGa=DhIS(B~UQ5^<^(W)>~b}<_Y1Vb)@lQbS&L$*mn z6z#>if0&fcAw+9`;7mkpglU@Xw?rAOqEqr3!mYPpnp$G?5`wba#m-F-OA(ZWqymKG zBw~=Hwh)wQ&ds$zrlsaPWD8z+*_Au+dG(*n799J@!wV#7$@E0$<1_q4?_H4h@zGy@ zGN)q}tRmW&UlD(nM`6r4ewf86vrX)y(&|gQii=ToxBXhNsI>26J1zuvu2oNH^DO>`+!40`PqBvh zDFE^_%usBu4g;v7i0~1I%f=lU2v*Vxabo?0S|3`c#(C?I-9nR}%cGPu4A9o9+GxHbq%V2RP4F$$QBz!89*86RzLmukI|RMF#}pQh=sks1nZqrzLDx5eER|Gs z31ikQT`*N%&PIe7%w0|w?3D>`CIs!3!2s5v$C?)e4Mni-s}NgP96P3&F84`00*(&%%QFwW<6mamNlEG_)?W>OPlOqL1;2eze9$xe^5&BQBds2Er`> zJ};iCA>%!aK(SV~C(coo5MFr;zNbI(Q|G6SA7g)vd&~Kjo^cnpjcTr(oaYC_=b^^l`SALW3jjl2k(xd!XWfCGJ*H0{ z`gBf`XurC41K`KSvw^%VEwaT^+rODGE^ebCYs521@}mAAZXbDQMbKp?`_p8nB#DX> zhD;GLfXEXT7~s~J0O&vVvZPaFktvd(*KjmZpGTlr*Ioz02K74N8N{pC^VCKSTQR#q zgkU4s&m1@zc-e#U>#Y1FFjaOT+i0isZ0#U4h3s!#F8X6(KcX;$(PXwTQG&dHYU|bz zey4NLh+YR=^utX*%)Dtm^#!HpE$EDuE<3c#)T0{mh?`7`C|L|I>m>n90~;0kt3OK| z%tYY-NrO#hd9cZ7QU>c3qtV2ih*}5t5iJ(L&B+R?*yx;kz2WbWOhbsKdJW)|U?b~H zNQjOUZ!@(v6(|K_4^uzWAZ3s^9Hm0XC}YGarul%jnlH{2OO%buCh>98Vdb!RTzO4? zMT}Jx)U1%qqRC=5%Ty9ciIlxklo)M^HisEKh7^5@&ZnfwiBbwwnj|5`l4edeB^rH( zR&t({XK7`~vK1)ZHcvlKw@6tkFO-&w_poK`9$}fV(6Y$9%)Hn% z-?-FJtdxjrZJYF)bdM^J$Xlhy#m#K9u*Krf+-TTg`-lD?x^kslenxsm+{5+=&sfS0 z`)$uF2jyz%MX|#Cvh9>|Qm&ECii;5Ondmb!`eHfJEJv4H@zs~_fAwVrOL_mNpWm16 zs@+K6P{i+&HrCTEw*eO%aU*}w1wR=ebDq}&pdL1QIu){Ba9Ax)?%GngJ^m=slZ-HK z&CcR*IxW1!3Mv;FuH+EvITtk`rZJ5`uk`QUbIBvqdN*yJnaEC`RG(0vlrOy6zTIQV zzT#0g4smk;Xm%p@&{WW@0e(f3Xi!X`7ntPfY($+Jm}n2nLKPXHk-1}$2qRZ?g1}IA zi!cnY&`&oYaC6AMGx2?v!kWLYjywmk?RNHBV4dn<6n2SrkaH`)jCS0@UVoCyDN3RQ z|GTr3agV9m?t)k#?XjEs$u0@m9?TI&S;sdsaS68?d(};KwRns=z&|Mk7pFJpF(JV$ zm}d+kz6tp0RLm~BCqjyLWw;VNc~UDEg4hZ0Q}WAxduP`WX_#xYr-%SQr6RdV8S7f+ zS?<~I2?Bls>@#!-Y1zhr{0#IKkMy3B2_-O)AIhlt@M(S!g(2M*;}wCIx1Q%1N5M06 z(C_rZuo4~TvP5Eh7RJJXh~EpF-NN^Ic!S{q>5gNY^5K#51uWGXiTQDd8!8i|=sn>u zc))8^0~#SnJU)?t$h^6^l^@ z(eWNvk}fXZ26)YS4?(=aE72XN4eZ8>i0Ev^BARozF4*>DUHaOz(i1CMZ@fGFIJIhlqz zNk(>wz~I|a5VIJJzR}X$gZ>G<7qN?JS$bW*=K0CaXJ4xaMUgfAZM)^pQRTt*)Cp5o zj2|>0ZTyz>uuaCLr|)OmUmBot}^u#NB5(XeDzKXeF{E`v*ZQrMTM9#Wf8OD>FPn z#LC8f%EvsRKN4&%H|NO_>e8B6bct<>h3DqhUO_qLo+pYJY>-$;pqiK}M%}vmK@Cf@ zZ{L2QZi&B0n3%usmbS;Re&iRu?PyAr!Q~R*5WRAln`0ctVuQ6<-jp0w9PKTRuSTc~ zRCTQ1Mbz;jfQ^Qe!_DG6gs~oYcj)v|ZI%ey^T5Q`ttTF!bW&PK^@q~wvcD0u=Z#Mr zEhy~JJog{?B35L3Bw-SRF_Xx6!}!4!5L!$>82>9V0c>AK(GKvJ-glKrPW_ffx!3$RDSMjnbSYv;GMKyaBc1(9WTS4uFr%mHDSh>b^=nf4g7 z+?7dFW~bVGO_d1BWET?@K&p8NQtrQQ1u8ocSk z-_BLJGXB` zboI~biKEX=+Yk}a(LeH`etkg)6u)~8bdV-=^QXC@oiP!6Je$%5B?Uo5DU}9iOi4VC zAxcLKQFKc=2{A-ejH^C|2oVaQDv%*F>0d&L8Yt``O9;gLTY`%6r?k+575-yrk=>ri z-974;p$Mbk`mEsVa{=okab3GP#v{RF5G}OwJB@Bd_PXqHtez<->BkFDkRu(`PR1Nm zvWl=)BXRnm(G7N%39vypmkGxWS&7`6UaxxVp>T&0r5~@TsCd5GmEWt1RPN)3ig|3= z=nPbz`u5z7ovRmiEBfgC>P{WA5@`P)1K-{XzKxtwq{NZ<1#u`x-dY*>@OyD!pzNC1 zs#5JOZBk=Ji#RCok?6xP=yMp%Pxzc7MEkA6%Wz;QdWmokbWo^jpaNzRqAXYgTo}hH z#AUUwLx#+G1fSJn_5Q$Mw48&uP|iVxeT}a=CB8TY@#IK`Na`lIT=h9#uxF7UER=BI zHx}KjZ`3ek9D#|xq+nongIGMupbe!*h$tdnpXsHoX=Q!RL116QM6WY^LI3yKX)#ct5;Z9IbW}veedJ9q&kvf4L*MQP)Y~y{i(wV zNrErfdCv94xIM{<@UR9#wTI1%b^rngQBfA^mO!cY#Q_>S15dHQxP!4EI!H=x~c5-XOMD_nQ z9z$+01bKKxqu#Wx0NA(&V*hu-*!9*8fU%_WwK)wt2{0`598%HW%4%;ngvsJL!Rz%W z_`KSL9HI5CGs^&A&T0#z_rxuMNz!CU*=;}k7mm3@O}K=; z?UsSEK-j*5p^fH#bnSIXN1#6};kRloc{f-C4Db4~yb&V!4^ZiJe%R{p8^%5|w?PIX zU<(+EZd$5uR(aM;+j?CS#*I0YIH;NAQc~xLen1+GIux{Aa|{GBZl8H_NpJPfz^O|E z2HdP~l$Lf|vz9&jGz}WC3Hm^@ayQ#lx?w{5{{1e9MIn10?6$~M4g=L@@?K_<{ZiiL;H*{5HQyoGZJx)URXxDE^Glo6~v~ znvC22VEV_k;b8qUk?=kPa|@J3)-dYiW>^HpJYks|%y}$J#Ow!EL*0x}>1=rnBjyyN4>@vuZ~W<%i<(m!i6rGKJY^4-k12?8B_{|hl5uV8`yMtuErVb@pvSBe8aLc8+kXx9XZ^kKi%sz_#?WHi%h3=k6v zT;oabWZ>*%-6K{hdk~k$@f{C+17kP8nuPa@@Zf<4C<}D?a4PS_Z z)o}JLeFq*A#ek}`Yy2AXl_xyM+t9I}YP|jF~ z`9l4%i?ub`{6`kB7y!#~^E*#Eyf!d(t@ab`0~<%ZAd?5<)#ToYw1HgED)MN~&YdV)Sm^#EXXL`--Cua1Lk&^Y&e(z_Hm ztGV+Gf_&z@|K4=s^$cN-Yj8gJVbV>rhu%r1#rWIyg?>n>#*O-dj91 zw{PE3)8@@)m#Sno6jp)V2m+SQ)(yhD$v+x7Hvofh6mj2MDOas}lJ}d8v!<#?#W`bIfM^eBs${3QG+JZ<3&%n%12^dhT59(PAwE zJUlmANIM#9L)jQ1hMs)+GI2A29}3Y@guxgFy@(p%GgIHjP3x!FsIjb0@y%vWy0t}f zVcyVb3(fUo5`_fN8g>9w3*MfcWJM*CQZ_MEtS5t_iZ!cw%f!x>hGSg4o^Ij8y8n6ghymHkD$6+ zdE!>^Bs=(CW3JbT(JA&@co`E?F+Z31yu)WyFHv-0oNuxnEi#+;9oZ!-DmuZVe!lpl z%ZtUaGn0Hn!oqrGic?fC`;Ke~JLS1-2Qbfd67Z?C*OHsC(do5AFS!^DSh&7V`j)*- z*fpjb{PiJ8W$*IWlzh*GQ}R{zt?mQpgyD#f-!7nHmJq4v5XgQJgvP^1J;0X8Wt#@B zDA#@PEPSy3XK61=KeA%*CY#XW2>hL>wsrYP2TMPTII`yQQMkSI33_QHpdpSj#C91r z*};o0A3}p8TY;i-wIGaKNU2z!dH$h8{d4;F>(^iUaq&=phoOu6_xq}Ue~m^PwPOH6 z6v+KDv{xB53}uHoK~6C1csn*T_8M>JVyGPw8_CY&(K4o3F>hoJH7EVpzyDYL`Y#^Z z!4EAf$XiNvB5aQtej|m+c%y7WEGnU2zD&_*pj=~=;Ii6`t{7Ym(XB>FA(I|AIbuv9 zlVe!gqWom$>o5xr-xgUpIl23Wbm>wsb-6sk-!#8hvfpBfC_=K`(1OXM{hggE6m5;i zY5lm(Z;BBj>_UVdNgmiFmupapP3wt-!P~>kV#A(b?+0}{68;<88QFKsrgrPnb;xtM zIXPJ^vRh=&YM;zf@)pS>)Q;?KXJ`ND$pu4A#;~FYi^ZSZE5E6q=7gE$Z1Gp!0r)!w zmg2E8PYN@$@6;`9lIm4n{B`w_BddSC^*$x{HkPZ1zk*ID;m+@rwEFvmPB3@-d1~*RQgLzy7M0;Mwm;U$arL>EIOi%ZdQ}8W1}u9X_5+ zgpPuu*r*bnD{x5!{vUYBC1tFXq5KALLTJ%%?Qq%u2b8)mLiLhXNOn~Djb?OLsA-nRORluMyemY^)k|4 zbtI+0Bi?`LVZC4U-+ucr9=n2*_EeVNXvedPgc%ZYH~iNAdI-;QkvLu&kHQ#$jFH@l zEb$PVaQLwLxcEMf#5DCN#ySIkYi+f}OGyx!1jeGZA!}`58{krwAAyZU0?KCljr{=| zgGUQ!31H*&RC*#`hj~n8#j+38U6(^nwcm1Wg?0_&k7pOf&)@=v354-$eN-5u94dJ}ZFxNQm zxY3fjVA6sk(2C4kkp(%}3Oiu!HRyn?7w^Jf-o*5<$7*VH4kXo!!d3Y*$)(p}?tn7o zcS^@SKO2wRe~J(aEemypF4T&J&OigluMoyN$BM}h<2nQn-V-+u^>-XHq@#c6Jv-*i z*+JjRFCB&s!9|>$J9pAGjH$OePlR3xnLNR7H``45f7^b+^qAx{CuDDm|AmPcp)+t4 zBw~gjYC*6ILioU*&MFq%mXV*A&^|u3OWZwka@!4!Z{FN)f52oKGBRrl9&}WRMg4?) z$aUlV$pY|RQSZ^Ex0_|x$w<9?(qsN12KBuKy{FK-0P8xRk}`Pa0R?{{s-PB18cwkK zuMpoNuXME#!&f^7CvcF z$H3x8ViH4t5N(RWHSnu_oG0mpPJR@rIwA{)4KjjU6l{OJ0a^q?Z$5(#~`;V}eA zeoO+wszV)wjw|6?tUdHc@ru2lfZeGjv`8i741jCpUO5qvL= zFAqTt?84)JL?0dKBkeVu2>EHmy!GMYop+8r^8E8hM&5bk=u!FVm@zL_7Zp{%sEunL zdqxaEp0olxQUK~i7=`uabG8pZI@}AW!mJ$nS^f3->!mNhP^wmymaLF2|9NEP%9l~C z{L@d>2ls96)29>-lX(FVsI%X+7f4-EtZj`?GB82ic)t7$z4PLs8Pd=gZg~kK9 z3sr^g=i_?^>lUjF#p&RIJh%t!%pi+8^21>dfk!3sXhpG1?I?DW-zvGj8*PU^qerf3 zLVWBZE%?TgG$P%O%p*64nxrYV@o~zxnS! ze(R^j$tB`s`gG&Zqc1b%nJi02%}Ck7bn+gExBquvSW9%LabL8#5cUuvmmHc4s;^B3 z{amrEBv4r*zjb|g3Fh;7;EL3t?j4*_#e(qXOig}}KbJCe^IfQ0hCVI_viU4wxu&B? zcLVnwfouG}tEhA05?bN2Tk+W(KAxlMe5q&MI%svH{WcdOf{amx(F=@)ruj(?xeO50 zyhf)@VP2!lrg%@r8;^se5iJ}yjU&fd`K4Z{1ygzQLa#AsS8qbxI|20;Ej0?jvf#Nj-Vj# zflOs&fxEd-#fEBPmFf}1z$|%jUH_ZUCRw!p**swK|9&>fa^Y$z33F?SrOlx}AIEbw z*E9B1e&<`(9R>)U`mp9=-V3jX&r<%*QUw^>FB^ z5blsAVi8{w4$^$U&Z^)@%-h|5v zsL+axF`OK4$ijI;g^`WNbH>X?QkPrNG5$p@?2uW^?~@HJ4P6XH2=gkEiUj^!Dbf`g zX0n;$Ol78SroqWu!r9R)5zKR$7wZ7*^<4mRkxV zt(i4fqAo|FA-^vCxL59yZTNUy_ng6<+jUHcGCC40>3JzhN$H;CmYBaQ@@I8GETVl^Kli`LSL+VJuAmop zXmbx*IF0$}3>woxvIH#zwGz+*DJBhQ;eS<4^nqiVTGbcE2(FwEF|a_Dd`0b|+l{re z9YV>)OpN=W#4D@~|IM7tv~hG@Pg z8lC$JbV`ZomH+Q^ANG($d>VC?}4A9Wh;lp(GO?=`6`tFZd*Q-@GZqvZU=wlLj)Z8ZUiY*F{Ok{FwZb2tx}u z1^V1M>d$YNuYlpF1C5^r*2yQ-`*g=ay8?6ga=nnWz|_IYDxrgZCeCL8P@ORB_dv1d?@Dyvl&D^OUcDww6&A~%LKbe} z*XavwvQx-x5b#Wfg-SF8OY!CG%e0{oiF#acW}d1AdF5*6NQAFLpFoHZjGpSX#^SK_ zZewAY`n+6qsfBefK@N-Y>#RCcp=9IE2imT><9h3HNZ(jrMsP9pRw=b`_>v{V({ppv zRoBwt!htCtoqrkFtIjDLMmZ)1xN)G*DPD!D?lLTCD3U;zohNbwsmaJeS@7QKV}cd4c7@VYtF zHrCunJousSKv$R4(z>*|J3v==-BADRjJ}8g%$9l)b4_|xoZoPZI_1}Sj!V$9wE5Pu zuK%J{sUz|*)w$_ud5e||r$rdPMEx!`kLEuwb@)BcVYh4)(z738670F&lFI9 zpbGm8CQ;D2Po1Yi_d*}<37tm)=wsS7ahrAxW30lny43B&vu^S<200r!Kt3mUT9G=J ztr1x5HMM_Tc->>P_Ie6_LQKZDrRw*k6V;<9PLLe{_l#3p)ordDN=Ud2G%B^s%^|06 zju&Mjb3}boKy5qs1Lr*3s%^I@hgn zqH1uh{AVhBp&_-WJ}7zwx5IHg7eEKBo7vDw$+264&088Pr%IOnnw>)G4$^ zH?GjNx~mSo>3V35ZmeNf>YkG<&~pU|$t+xx(O7aW*F_1m1Df+4z1H>{KFe$FGbyLv zLp}O#xFdIbPm5>n$bwSIvad~kj!908XwzX|+dOZ)V#-JI2{K1ZbfR$yHkpNi zYd|_K=kHzr0q@mm@6q17{)6HIt_{7(ZcMJ*Rab?OGTIwyEd0i6MbfXMNA;C!`e~na z)g7x_k9rls_pdLSq(n|E7^+i-@%IDIV!zz?A9#~++^RpW<9kKnMF4z31AXAx5O3;q zlQps0pVSd`5p_>-z7$NUt^KK#c}fxH*z?2**u2C*BIx{Ib?=}*pkM`_SC;GZ06x4u z>v^Fm*@V=i7cMlWVFgl*JIsUHCP{i04nwGC)^zID<>$9!{;hOZA)zY3Bt ztODBjGUR`&U+SLYJWij65-n6aC0wr>mKH4yeJL|Tf8i3&2%UVQE%R!si^;&d@O#$>VEG8(_EtGjVUZp~%X zG)+d;WL5Pg?W~lqkq)4pl{5r8DfGmD;txlZQj+Ids)i{8?Ws1$ATf7vS}Y zt)*Q=&pM+Ps=MmSam}k;!(3m2Y@MO&K`SC@EG6;MM)jSIVxbaC20`Mh@oKjESzU#; zZe+ou|0=A8STXv}UbqoLju`M@eZS{?jMf(?IADT&0S_MI-?))8F%=FdhUbOhdGF9U zt>Bb)CI-m5s9q!*fNilB#*Dh2kj>I?vsS&Jfu@D2hY6&yIu`B?)OEUhs@dC60ZWKW z>@I}ND5CDUT{eGDWEzn@$&S#ZFMK;Y-Rb0 z;l4CXMk0(qdUfVXHFD*${ri`#WM8kmcmIAh{qe`opQmq{-yF>E`MPp0+xc?!x%uIq zG&OrX-Jyo@`|n*z_brq^Q%hin1bvXtk*J*eh~OW~S4;d&n>B0dpWU~A|Gu+zt69@# z{*D{aOMiFog3Tku4( ztXwclIQjHhG0NAXk5%j=h$tDelw?USE-cZVg1mv;0oJ-kGHBd<>$ZpYfpRHLPJbq`>lCe^-9 z&C)g9RB4_5l6K9|9~T*}y^Cv8iPusTW9>|R!XKaNr;^NrXS{-EkgNcD554y+je-T5 z>a5~B`ZUDH3ld11_?#{T^z|1jLt3i5E~a0zQ)8Plqp9J-?G znQwNPlC!#T3QyuMn)Tu@Lj9M~*XiiLPa6~ZxIj&p9s#Y9K9I|a%$HxgKsSe|>)w^> zNlrbm%U}*rhZ4SH=T9^j6tg6~MRC#2pJ_bwzAgs!6ChVM46k`zx#O(5>YTa?HK=QU z5yxJ?q+|quJIbFop~3w;Ocn*KrL7f}_}A!edVbKyjk$FCb+CS*mOUgdXxR|ID8guG z$CswV4gRx=BsP9O>bva_x@-3%6H*Xw-k&1*+-wIv&|S4L>b^EUC5Of*J;z@k!+232 z4zIDbU{61a9QO^_TeK%h2mmXfeba`C8y<~{3M(^NY(BLxF{=5OU)n6ViJlq6ILH2g z8iLn|gC(qSN1CvR^{ZP6-x>6q2KV8*@GxBu-oL%h#ZJmT*v8`MzPgR-MD_^T#wbSz zeY)v$YXQFnS$AMI3i>VnFQd^dPCDL?ca;KZp#B1C9|ErhK_!r$*fdC#e*J#K4#Q}J zG}5n(HrNf~tSo*%_=hqXXH=RLqkaH+S0{mUV>};<-Pt~=0R3DA(hq7k&BxzIq7M)WBY5)@(O>_=q8n~6eyu_#Yf|^PbtPro!+SF-t zs_hHV3Gov2p#`5)qMNax6Ow<;LQ{b1VZqHbr-m}KRc1yYA;>Zy5D^mBmS&SDmZE1g zmlDwr&1tsyYM>P|9cw4??^$~#+uj??_M-jZnxVbyP=B;Fm5zj7Q*AZ8pTp;b`U9Fk zUkd!rP9|NMeuW^HNdV!L5xs+MT;xUbI6Q$iJ7%Y%$R;8~`~^x>8j~Rc%@cEtI6u%$ zc2NAFwmthqO_UAy#tC4oVKX*cRy;a1Lug1wvVDRP>58qoFLtm6i$PJ}|lH zXI8yzL)oNUc9(F_5(VbNq6JZeh*IzIi6=IWz3;xU8_#YWyL>r*{j$BfdfTsOf7w=5 zwe6R)^244XbIzQeGsJ`6r_bPbt;4%&C-ATAPZWE1>&x?d$Eh0%m7cQP)?47C#<cBLI>iasD=6&p*V;Yu zEPhXGevd`ehwj1o`?dUqZlWty!nupnDrUO&e2#^Wb0JlV=}+9BEGpElhOf)dH{lFF z7kcyS|3H5>^XFhDahk={;d!{f47qzv>HL(2^XJFHXh8g)w<|A#?9fzr&2M%&_01gN zdL;B^5HX*E55AS()WMPIh<8Y99c<(*0VNQD-&NV9BGO!$xW-=PEv7=SoW~+LTk(g* zIt8ZtXBVG>-H;TiaT>T03u#z1`Wt+E!@K3?u#K3~L5!Dm1Y*apH5f7wLL#x{L>D7DDs_y0E%Fm}8 zeN7UEP9HU>iL?2rW^2EnJ#X1VXIQ>y{Q8IK4<5ZdW$GpNHA@LR@nMT5Sz8A+9Xex3 zlg-;ua4z-1$7nuZK|X(pE)lUFF+#rIj-=N(l#4NYg&2dRAw$8h`UP3i{kEt|#ptQ@ zIxDSf#OhcAUAtJ@>LREZ`lll?0kbCKcM^)|;cq23!P(N6;AD#`*5)hrTF2yH0XhrAxkzZ+?Y;~Dh_tI&p5II2F#%isH`T8 zt8B`zY}84$O@;bFv(YUIPJ_Mnmd4-M2|;(S)aBmoAzA~*B63?}AR`X)hv}4bIkRg_ zy2~`cCA%ULk&)M&hz_Uqp=BmE5{EZJ99m(bbV`aCBZ!qzDV4T0&2gBc&lK(0%CGar z-k~5p(B^=T4A7OnBu^N!!#VpTQP@d(BQ`(Mc0(+ef`rLfk}6%9_+x+>-kSGtY3a2e zA1p1+?X{IvezZ`H=#pPJxUlSzXGe^=7Xi%$^X|+_nOUrUul~Mu+qSLDUGtPbx!*&~ zQJ|*B_Lx<3ZuXpSUV61?l39m24%V)~Y1hu5WLae{aa0;Aa-#P{aS}Pv8__q3>y87a! zOBdNZHvetJ*9mlP0FNB!K(t?P2ky0%=l5{dpjfMvV!)1nfmlnfSMp-Nxe^+ZxotYK5xU`malz}2D98Ja_Avu|#lbysv zoRG8e3J^i~Ja5u?<%$AzhBwY58GJZd!0^Jo;yogKl4sO=PqOcOW=<`d_qj6R`r}gD z+Ea4&nR~Y*a{*^A)dl#H^mJhXr&FBWas=kYgQzapd|hbAOTD6$dD%=JVh$(c4MQm# zrw5QtvZN38h}HK9fP2an`~ctxq1#aETv|?x;O5e^o$B5*EOFuZ-m(}GbJwx1&6}1S zT#WSSK}()pF*A4kg8PRpncer){x9ZYjM&>U@ZKP6`Tch6?Q}UQHYULpfkN# zF=e&LICcehb(+^#oD>(0H0m^vFNuYOlJ_5Wx6_f54E{?N+yrNs;z@S9#19&6^YyHc z`pxCHBu`+q=m?w!-Y)jAro^MB*4#lBTxKW%?v_h_G1F^52dMao%0 z%Po}#jzAXHZd041H6W*&#RpqgN*Pqyj=rVM6NmdS8Gqn^)tK>tebSp>e-x@33Ty-L zZK@rYOp!aWU?Zu|{}D9NDzlHcLHCl2#x zPOzI??g6qZx+~$(VZz*)Ffa`)U}gB4cxN#{nXBT7eQNW^k3(8Neyn3P>+4yOh$qh3 zJh1Q?9Oi}n9uvpCad(g}&XV4kKIf&^zy9X67w(z9pJQrC&ODE=z}^^-y?QtL zL>W^Cw^gzmEGFPl0fvswYQMn_K-ns>QXzFX8;4s^xXh(+JIWXqzY4NO^-kHS4yn;t zqpPAK@UQj6AGth^=TjbsDXyy#Mg0shTtI|)h(jT+gRz5K8i}TK)|e`#G8_#-ZRF{@ z6ynur+mkj1c04dUf9l35ZS00P?EHe;nl9g}9-c6k^X6iI*SF@sIC1%c`-d-{^H|`; zFWAEQr-@V3{Bta1c`|Z5n?P!DWB|L_?iLMk-gKWUs%uk{QQFqfW+$oDA;edj<0_g; zX~k~u8c%go0;i`#o)kltvAxwYy{f6WJJ(1%moAtb}-V8y3Kw!f74?( z?6DiGBEt4~#OeqN_(ic1iueV1+<_EsaS;F`=2RpbDyN zIh-VFH_=gAvUs^nJ^wyCbhO1|Eee>}@llrZzS@_+LbWHhEbx{T!QRC&qkmdmA!gNn zqc))zL|58c7QrW+hg?jzAuQ4g6mFeCL2BDgP2O*FTa>C8o4GhrSQ8CY`p_D-&7x9# zK|sQwX3t+iYj*m?u3t~R|JdN3OJ2CY^WbCm&%gXaWXhNY{}xLF_rB1(lTEr*+sxK! z(0*}6U}5d_aXyuFSoEnF_E3Q7q9)nx{xFxz9n;m}@|X=4y-NfprPwu^*Qg|+{tC_# z(3sKelB;aSVlZ=1)h}&Nfg3qnx^qMi@>88T^rNMeLogx$*#Io=YT#8dn!Dccae29 zq$k6t13Pmp>D$nj`E`EYXnOckx;`j)o$q7qdQ!vt`IxyLK1$QW89BJ&TR`4E*<}$o zK;lfIQAB_wd<$pA?Mx0tOHt~ERm>5v!Y4sxjsx9m{{&^QBAt0##n{8n6Lt}K%q?Um5YZuM1g72c8xI$m2v4Pb-gAX>~m8(*d~2l zJlY{HKF%Hoxs#Aharous=80ef8;Y?;CyT(r&5Q zOP3h?T>bLs#xV7}ReRCdS0 zMLn5Yt-1g0xAuSVtNMlNQ-7^Gz%rkbX8v~X-qPWFhv)C@IECfy{8$}dTdPiBN7)5P zQ~yTg#!gtbA+SpgP(Be7NS;j+qQm4EyB@G?HMOlSpE}Y(@JAz~5S?`DFDT1>r3QG#5y6_<=`MlH|?B$S6o6d3#&-?#upncYdo9G)#<$4JGXXnW2f`4 zXF-nB9X!T-k`rV{1{$&U)dxyTA9$4?2CH6uVOF0(j1~5o^}?*)Ll_&}8#(>swroY6 zgdetUQD+3t1NYV~Y}@q(ljfX#ZQi8X3aR^~d9UGUAlm8(zC&lY1LNrG_sU2dmUXs- zu2QT^7h#ADb1@r<7!VM_d9*rMSV4P)!zmTBs(9dk87yn!`N;+{%g&~ZP))o@NtQ$y zXjtZ+0gq>_C2lf?h*2Nc@j`G1meOi^YtPrdbuqrN|x(?xuEQDfa2=& zT_iMm!YFToZ%*8ql$MKaD*gFeqRCoa^jdyWK1*(Ii+Z@#2>*zvXcil*T~se?7gNs{ z>>4?`N4Y8CT8|aE)70OWB=viY86Ui-b>8G@pJvHv>d6s(rZFR3R)5zn2R@yc++t@7 z%>K(Lgkz6Y|q%27qi4AfTiBq;L8+Z+|B#XPu zv_2uKOpsW0f&+&V-^3JGhCxG2NaP4$dYza+o|5GgqBHcg{Djy*hVZtr3FFhUldv*@SJ~ zs?`D6x|sUPgw@c`p21m>4Ewyv<#nZ6d~!@2AfdobG$>@Nqs(Q1>nlYlOIndae4T4! zEI4z271({mA2G*Gm`5s5|6R0r#NDsmGpt@_%aa9QPpY$2PVWGvXMo>!k=ws}xv znf=^5Yy#{1!@<40kI*yZ0oY>+z(O=f#=4T+dJEJHf-dKsJY^2n}-8LY=rzaH0Cl^OobB_*9 zD%dv=n}I;C*@teL@AOXID3uO*8gx_t$Y#dACAsT zOahNYpmSPkzMHur{_80%UCf&6dc z1ejiA9i&<%C=YX~7_MF)GD>qKxkUZC;`2Z%i>&xunpwL}JR|i9jO27O8<;vp;1`J) z3-$^s3}c_WT~Gvkpa8PT<0J$N?ZCvuByqsr^ON6V_p$eXc;~mzm^^UcX#aWf=!np__g+)`tDmT)Y}9Ysv*)P2Anad)t!aoqrmdAZ3<4Y$9UQrk#+(^3&5~jw z<6NwiS{uNM^YVCF6jx?J(LHcB7$vMyuEr?X9UT$~qcJ`M621(?-4FIu`O%?I*>CYvF+na6yPO_<9Q2(ESMm3Cb|JfdEizh=yXi_Vu% z>M}kpZTy4{Z!cOrzRk!#2Niej-ec+P?%iH3D44sdW4F%5gRYOheZ2Uo`s2B;{!uc% zY4`&XSp$}bcO3QHbE8HbJi<1=&TKoD6{s)octJfs_3kN?&;0b$naNY`Uck~`*ugp$ z+_zQzp09PWI+)A*DZp`$bRtR>TL%?|O*ok^su@6wovbMf|6KXY_QgF?9MjAh z9r(EBKz8pA8YX|K$sXgh2y#rMR#p~nQS{pefA1RGiZ}xn62>2H;ekPgdwWBgJNZe8 z{!!C_Sg|`VMZ9vP=z-~DPo5e(?)~?>OrE^APT0EZ*d~^)^mMJPRImQ|%;wEom|48? z#|m-XN`Hq-AF*yMj~OmuJM!~v4bHO|>XQxA8zUPcG~CxvpNeDFSgT_7JHyu4G%u4Q z)F+Z1aJq89pHOu;?sO1WKh}Tts5@BiL4zs?L2lg#50q|S7LWqAaSy#!y<+a1x#z?d zs6slB0MvH>apkpL*j~_WdMTe{KcoPA(gvJvPfS`@IW{pSLB?Wpz2x#KQ2s%y#le@^ z99bq*Aoj32VMSc#7qvB5<}4QS(b7_Kswd4vlYY3coa4j=sW(eI_)^=>dr$sU*<;MA zrSESpX_j~Iob%`A%sP9v@02O>;=?D@K+O|}mOs)p*Ybcjd&oU^PhR%QwvDS+-21Vb z2Honh;!d4O9=Hv*rwzyz38xB_X69+jW~jeEG_F@}#{q+iN8dNF z!-#GDdbNm-FPJy6Ta)hD{;Vc(vGL8@_n$E8!n)g=mgGxaHhay9Q3=tB37!~~AyFd3 zT0~^Oa`C{{lIFgSkMwTt8#Qd%npu(IEi+P4pIx66)xBk>Hf`Evc1X(DQ8>B(2CPj# z(5_kejrgx3Cnf;ou6|Z|Xdek(Q2bz#&Pm9Zuh$6>v-hi&;<3Zirj08~ss zbrq?OkFzTj$ZScWv>{x^_vsrTTiQ>9$Sa@AeUl%N0lG(7m`y_5{(pA z;Y+eJ3Jaih3pZ-^R{Z7R%c;{FsXQ|5E-0i5?#Vt7r$g=uW6Rac?x>^=k>0L}3Gp$r zdo{~sA~Uv3>oq$zE+Mf?ctqP&ca(a8&DH5+yLP*NvRn5k%U*U?oh-IvFUCeC$)*?0 ziqbi~KwZI>_40LA6!VKFImwx-b`6{~8WQ*JO+?Z)^*Ik`@j1*NZ zOzqJ+QrXUKSFf^i)-J{tDd`_Vs83E@E=)|i+_)TBHaw)4B5g6i3Z7(8BDZgkgw=%R z7`VA9$TN%;5SPW0v19n;LeHwNC`Y;-S^HcLzNLaniquqnXUOf|0fQIc_bbcB`TeK* zM){Mgm#_nK%69e|wQ1VJuN|wJJY~v+m#fAqKr`yOvoNWJS{1maR&9Np^=BVnc+q4^ zJD63)|%w;A5FBRHX|^ zbTB+}ibPlqooeI7=tS5u~Fu7bz9OH?+u@@j(y3WEVpwa1 zC9q%A7}X_Z+%ZVKJm?ONsw$?u_2k%5K8DU;)-k^KwJ@5|jbuQP^`2`0AKe{?Fk0xf2Qcb*1dM_nq z++8nB9PJXH3XE`#p7_G@K0W(Qo~r)BeIJ$y)6>(WeO6P{xI6c(+jHl*sK}>X-mP23 z^sQUH23Rby=BKdFGPL&GoTuX4z|>F)M7Txyaj6Ad(MftLEq(d~W}%0xzf7InuVTg#WIS)W9nnl)O1K(?+%G;Hn0fGv$dr^gT?&^utUBKdQM~QQ<1m zn97;}kF2%S)zH&u;>9Bn5)0W68VC%&>^8O({?6M@tIN)*%T6hm)I|0P;x^;eNcQ#h z&uFfffp;8+Zf!wafzeigcpVf>w?h378YcKKjBunIE!DbASg`8H;S!w&lQB3LZ3GAz z{lW1Aei$4-409*CZ+2xFi&n9zqbt=bTh#9>!B!Tt2T;7{kXpocUN6VgVm}Q=U&zNv zR%ZcK(SmYL{k9-I7%APpT%pm%;Lc0FF%}OU)|!2(MpsUd)-~7_>%`~3UIS0&&2918 z-kCG^vR@i*j3C|fwPxKLt$nKWFj+N)MIyM+&HE^honp0N(?l3ckd{{Kr^4P3yM;p^ zo`MwadG*)(YS*3m@FaN~n1 z1Ix!wKHx4Gb3iC4I zQA^IjjI%m$l|6CnCo`FU=OF0(ur#>z}9 zVsvE+AS5aL2rP)grX8Y^o9A-o;yfqeSN0{Qz?2Lxpi@R>&ui-X_sgV(-`!vi_1X=! zH-i2A+n)SX$*2gN4cxeWZzlVPI8+Th_Q6LVfAA0HTwNUai1sIVpS}kDBIN&Exc4IM z1|cRKd@e?jV@UggHmD_#Tf=w&Imp*-B2Zen@nc6CjM~6QC=mYiw^{1HV7IHYzts6Dbz=S0S?5s8< zzG-Aj%Cgy1=C-)3W%d<{g@SR2WZ{THX+aLVdXrY=uwx&;-hfD@S>Ikow#kDx=~G)r zWfiB*{XyES-``3Ozy4fs-+#&XJ#w4mYW>}a+ifEMKjPj4F3M~9AKvpk&o-8_h0fBO zfD}OlY#<_H#fpmEAhy^5dqs^s#O`)IfkNUy)xYj5KgdF{pMdX{=g< zO)pvn!k#NPl&w^!43bSFlrLYGmt1fE*0Chgq37f*S|U8tsSojdoSl)% zyg?7$Oa7nci;M-o2t%%g2i+Ro(XH+lo1f7~w7PlPe1N_I_=c}JUvbgqR&Mt8Q2Eeg zaG$~<+mt~-g^=5%nf-7mQFMgXp1m(@mIJ2w$S*FB8ZFMQs=EJaRh3kJU3QaS&WX#M z%~}gl%>UjE*^9!f><2{#D0cvJLOu!B694LEf;Nk4Tb2Pm9wl62SzT3Vq6K+J7cbuH z(UgsFghi)U3pz6_0uL7rZzPxOun4>X3)7jXeVdx&($qR2)9@Qe=JwK$Ms(J~d8)>d z%Cam-Qa}q=R5vjqTZ2hvl+ZJFYuor6un`ODMxrIV-q>FGjbIRmwBd{nH*ttr3KPGt z6{`NQe~;|QIS>VQ~y9*DfF@<4-0c9 z{k8+TxP>Yc^`L|O#8_`XJx+lbV?8d00sJAc^7gj{xEl9)9JSb7Blkre4YR2>xUP+% zvN+IE^p|f%C?^f?NGpYhMMO6gn{XT`9Hd04$3nM1S^B!A8xF|3f0`?Q)pC2~{4>{T zE?m9-(w+lvE+6*x^gHTb{&8ad;n3iV>%aak+j?zC+ncvr6^n~?S|AYhUXs5) zSL&u8Bn{S&l_u!t=%12S>uu5w{a)TDp4Na%AXBGYv`>_OxhQO*TpHL(%B6~Hml{N)Kufr%QqH&(ARO zO|g9k-0V0=oLwsi6pyJ&Jjeu`Q7~rd(30=kmA&~$9#TVY7rx)%*HE4i>0!`AdRVIp z&N52K0unSphQg4yYH>>eRZK*23@5ExDE_M3)!M@_H+n1-FVvh<&o$&1IiAztGvIv3 zIn|i+gXi*d0Y7X~bv$V?Y1|0&MS#^;vW;%#ILcAlK3T~-@-V5OIZS9q=wWhoH@Ue{ z>uu~FNBUbN`~tpHsGKwH@f6`1uaNxvy)tJdSk3Wr=uKA2X54%^Icj)SfGKvOG^u{G z_#}uHDKk++x>&<+DLZ7DLX9qdDD&%O4RrGs{Y?CV)p-F=iq+jsW%Kd$Do1NKTcCSz zBI!5d@APjHLIbFu=#xSf0-~bD2)b^IM2e9_U#PvpMYo$@e|@v==2u_ctdlRum242} zP{%s3f%0MbLY=hV^XjEbb)KGemo8oPtT+0g0fQdD<9*hw@sV%92K$eE!{-F}`fzR$ zoujug2RcVx-SjqO;9>_mj?p{qxf(*5xpIRJ$%!}&5P@hsM{x$I+udJB=V%pF9zRB* z=t(Ycx=Sx%Tn|+Q$tiQQxytEcR#Tm^31(^gv-cC;7noF->~md-`M=sJ=FAd}iB zMJfkBHvps;g#6mSq+0x2MJK;Px+2f=>$<6&?&K^FlbcP2p&cwSIxGu?DJ~ipq1?mO z!4~366UNZ9z#Q!*9WMuRSHnCh~wyBR;Y$~IhpWci- zP|??T^%jNXaU3}93h)XxsbWxsb4(4rLPYcrxvQ{LF)4nz&)Veo=7z?;KKbwt8tlHD z&h}4o5K?#S^<3mDM~Uai=2EqkUIGuejmm8v7uY-zSr)a;?T7(;%F74YJ8D;}K{0(C zG~p~#fISW(z+i{9EcrMnIM6%4{zR>lFmCE7R7i&uvaqI85vvSu@J-Y@KZ{o74&MYd z-IeADK1eY<;^(%{{iwlaB;UmMs9^Jc*f-G{y1gi9$T!hy6yL<+9U6iv8%Qn_LPPj% zChaH$K&QSB_e1xScl{S)koQmW-3O}ouOTBZpDmZ?!e#m6I?FxFtnf!z;Mp7NfEL*< zZ<9x_2Y=pw@TD#Zw0a<(k)8zvk>`eJoz1#7I@A_*B%(aLg{z;h^7UPbz4<2O4!CO|$_>5< zL|RQMKfRj|l&E8WBKV@Q8O!xvHt~oBX9;W#EHsX`Q(h()ZxiAziWVJ0jkmD$VX)bv z&Oc71b&aLbp!qqE{Pc#a-@JpUvF*mpN~vv-&pm=?XxOs(em z9_Q(1234g?h`!Q%hE;~}Eq@&w44Vq~KT-(2U_xw%kpBgvE!*^TB777|EecY~r zHuw~;Ap2a$aw+@#7UcD$REcy4#3>v(=%+<*`vGaxrg{W%1mq>$RtMteG>{|mDRge; zN?#9eQRix@^!9Q16ljtTb)RJrD_zf+yxdjZm6nHm3N2iUHr&m2SP1M@!CPK1Q~qdZ zi!s6N*#ZQ3NZT`L#eYSUui`>gVMeTv)z z@ah=Asbd_O1aKvOuRreEqwnDQfZvCZH__~M5~?9l+ym(jf9q86LXjHb{QT9j{8OLG z!md@rw^nXhwRvaRiZ!#k?i)R(s^`ToXCsqs*B|Ss?k>d4HRGR~p%66!BJh%$qK6Akt z^6h3W4Rfr^E(;N2`z|362# zn*`fWGdE!RyK=umknG6%hCFcGc#}LOT3>pO;@4Da z&j=b(r_TlSN}Kz5zeXxo1}4VUr{G5wIaA{Ch;{ULKBw{C2=jpr$n#gUD(fq_Pu3x$ z4?U#0@_kvxFXgt6BV#Sb4~OFUU8k+@GX;nQtc;)Z!+N=nAe z+rU20Sla*j@4kD!|I&<_#xL3D&JPHQKU_W}cpkcZzrBz#qBlzg$P&qsJx9>$jOYn> z2T)?UuJ;K0W$`9HYQJ;nGOZb^BaqI(yoV|>iu1^m%SH?GWhyn$9HLI(n-Ufn`7)<8 z!Wpo@pC!L9ni8^?K&oQ$M~lnuqn$&)L$7Z0m$ojRVyRI?99 z7F08<{Kt%T?bx69D=;NR-Zhjjr^GpP1)b=kL+2)qGAYW$z@*^noKfj2AM5I<**|OU zh1IZ|HR!Q+ze1UsV{G}hHV$KZphgRPol4wV8Bh&@Smy9`6s93C>>`{YUx)MU@xG2` zoAMMqu91OGCJL&Kh!Z5>S+4LYT4ou1kZdoy8+1AsZ{tO5S3VB}St<=@wC$EkU0H=Z(!P_%Qhi`Y309|cHz>c!qx+a4jmNV-Xy1OQY;?K zQ_=P6oxEn!ZxVu7sM_!^d;@pSSXad+vmlyc@am#6d#DZA<(^!NbJj|g20fbP!DbDUa&ai$_mfe^-#>nO@lh8ijrJS4 zI8;;;E>21acX7g^r|;Rl={<}6Eg{);@8uo)c0Y&8@$vG<@`JORZWJ8;=cWmt6}*s( z?S6X8KaT?rz>918+i=R2oX8HVU z*bYu3JK?VVKhWBpKqC+vQW#{3{FnBqX06tlROUwS1*D-$Po?pU-m6k1-$fCm$NMhm zPYbQ4SL!ulSAssq<}RLf_wKC4Sk;2E9UtCguhiU@Ul9ZQk6@#R)jz|2@L%=J{(bi= z*iAXwd3G$)(48d`^>8EAxe)jp$CPoOhPtxU=+l z{GDY`!<}UiT}w8(v-B_?#}JM?%W%_i5qFm69ex#uo?pr)YF;lf1XEN^z?$}Gcvs_#ZXk{nl zd3W(M)_;{;&zmXw2+PHlYSVJ#O7|LzzS8AYb&aap^6+NTtGm7E?n3bby^G^6GZ|Ny z5DB`%q_WKbB8Bt)BpiHh_r4vM_qqzn_O~qWZQ8wO(^>g}{4s;On)^b*XA?I4^Kd~` z9#5t9U>&gjh-rwIxlK{P=W-5AS1=;5))3SD9UBg=79{3H{<;~41agi~XBzGcl zlgaJAj}CwEEtKg_dB@-p;%ssw4>*iKMSD36!I|Vk%FmE4KsuG{1(bDlQYQ6wP-XwL zrbY;3!#G`Jw~<06%RsT=>QfwKL7t%(RzaT8&oRpb5hMt-pF^HO5SM3YCs+Zfe!*qg zo6EA#_#UJ$;Cqn17_R6GZpU$-&j=*68AGfw-c}zss|4t`WK4BJ zzaeD&wp{NWp({68ZSjtLPgI$PNrQ~f{~6;>Qpa;I5N;RR{mym|lFIF@7J1OIn$ z_HSO3i%+~bf&<{ecb?Np^&G?zTvl=8rhXCjuo+P##E^n5erh+9pNGn7(7T~<7UfI> z#?J$EsIOqQxfzZ+ws;VM{!Iv^ zQ`cQ@sx)}GNtG72t?Eju_JQM#(-+||PEZ{grjnwKVWb!};ZnH6M6q9xUu9itSfxBj zu~dFNi5(5Ya1-g_O>*r4`M44jLX1-zfEXtsNBP!Fq4*?$(|DB|Kx|18ed#mw&a0o=86zXOSe4(XG2||!N~JmHdR+|^O?JqEA5k=20ioph!m*p zBkRB78YQK6@g7bp?h)fW;8f-C8tI2*@PB0)qWT7kCCi>bDErt7K$2Z!&#)I zn4e?p2HG0OHZbiq2aPbpCRJCn?^sY%TG==(u+dHHMN_HmfScyyGrh>Hp_humYun=c+_3i(Y{m|Vt-y3VqJI;A;vN9 zEpH`!Z?_~bc@G^Sg7(d=6c_Im|ADhh3Pcpd~RW`vNhN{QIGZb)VCZKOFRqpgdhd-0QpZ`NMJUPw!j8(uK zLm`uVV$eoZm;@8{QYI{Rk%#|7(8;e(>aprVLED1r{^2abUF2+97{h03M;ALRBh+X&SlLl&gxwsKL;m<-LuJ+^%qU z;1v7IwYB0hVyieE_@hQfhBRgJ$kqx%X$rVY&xU+z$X{&!?1v|)JR1xU)8ua?<3sZd z2$na(p;$ybm<1_)>|}#|9a5YrZ=o|0HgTzTE=6k?PZxxyp_XSzvM1FC!;nrfo_s@^ zk7vB3Ci7dI)YhToeW6jBg;19~kAdedco5^fj8yMTDlOgiX3pvGQMWoRE(;kmAg8Qd zeftI752R+!U}&1!>D9r1nG1Xl^qV1HdiK+b^1Y=M6N5Z_e8RK+!=nuzVabKhjVY0T ze!Aa4_S(DSR_d0NxEcg)@`TJ)7g@`~DZSg5 zs81M>CBsrj2bPktfFshXxj6^20p_le3D%TX{XjE{(3RlJF6Sbjr8|9$gUMH9Qh*%3X^x2 z0^c3KVYARIHRsy;g+vBsx0k=VS9?z$c7cspP`lvU-s7{&Q_|I*$g4=-XLpfnSsNqru5lXK2Nx|?;m5eysHBHd}{ETaj&p73H#wq7B#7~{iKn*^6hI-?TVuJ*xi2 zi&9)Ve^QU*<-U*DfhF5$KG5C4IAbl3jDM(%V|1A_F^h0JAu&zU@<-jlc?} zpQP=#yAb)pv>W+2_=r|cn|2zodo87}*jzKPJ^X$C9IAC7ydj-e0sAYt;0I7QST4}M zgt?fo>syk>X@q7Vmo_DUAd9Hm)_UxD2eg38=d&Wkk&6oFI zu-omKBNxi5MWaS75>yLE-ms?2+uB+KGuZeHx)DgPYujN*MCdA(CQh=i7G|Q<+9%iK zJIwMAA?F{=Q~vQE@~2Ew^8NQ^@_o6!?ECLah(_e4YaW0{lur*t-lH_)BAu%U95@g! z!5AK9Owl}e3~@6?mR^0QY}BZ-cdnKeef;_7k0a@@ocH{dx1M8Xo_p&`{oCTG`U=vG zWVgqIPcc+eE0S~*?Z-G`7gZOa95*tLD4D07QhSW-Hg7FiXp~|=1`-P0(|bNCl*dPj z0pX25Ee#L)p=9ymk{^N$9^L`|9sL8mjV=j4lq^|N@;K5DjIe($iw!AE-QEa{O$f#4X?3xW&&eyPg`b;GQSUBFj@-GY{mat$xoBSqVfH0kb!+v|Hgb> z`M$bd-bLS6+a6rN_qlJUO~Kx~qk4k%hcEO8-+SCQQh#oY!u#+s#XrGW(q)u0OL`;_ zIiaWz5#W~O?WZ;dA>dbk{bXW5Cd#Ie_u=Zk&+Vug;BYJILL}Zn;1VI)lODmr!7xNZ zomC5(`3W54fP-4RcT|4%)e9Gz`vxmlZu^Bzy7J~V)}M`kx4{kAEq^4xzhtxhIMIeZ z$74O5wm`GLYo3=`;`zM4^Z0_RE8?am)bF(VRdS;0|M&?N8a;xI!Ha{}2Ui56LL)&c zcx_>lispqnaViMg*Gqp~*|PT@GwW#c+|6c@T^!XKF{@~HX4-zqaB@MqSJiPEk>*@`e?#OMIS9Vx&Z&uR}+p- z5KKoGysW%~f9b22i(W=Qo_|W8KFHS0wqNKs`WN2^dZ4nsHXjMwai`v24K$W1y&qwAiS-mD4VUq_q0)D$;+`OtT@ zr<#5DKd#MQN~@Z^)O2#RwUYZfzIev*|2_858-lYFpz{;=w>dsRYoNP3*nUAcuZssp z1ZgAi?gHV7$B?u_)-BZbFj~YJ9i0~Gqh>x@b#x@k4XeH4nHP$|qM3TCCB=Zs2V%Ho z(v~?>hgII6#s5uH-KR}N)X&8Qcs0@&U2XoJSGq>*Td*6)4#r*I2C zFpLGNU*0l@4Z@Ge|F+GYGSo5BA;I_h!6p5!(?7yzO^1Lkq*`9}$RUXG`H^&}f&<3; z=kR{I#uM)&Zw98t4pjv(00MbC9RK$JUA)NIC9g@mh;3?&7aclOdx+ioUj&N;$gfK3 zqTYkM-5_Xc+|Q`YChs7PtJUi3?H~M5tjNtfsM6Q!uda0U*Hn5T^UN74YDx#9S4!3- zbTp6RW0}f3c3w=EYUSA-?RSy4GpDSq6hNY#JF9oIo+Dxta4i%pJ;TcrbpjljDrl%B4O}~MQ&(55`VAfIAa7W z5geq88v4t6(<)PA5h2|EiLkj!*jgo9s_akl@zXK>K=|NpD%8H@qoPl9!>EK0LrEIf zN<6kwO(?O)J|UAo!5gKbE0Cx7dlfssTmHC8b|oIl#S-O01yF{T+1Dxsx&nSIQXUl2 zt*>6>S5NL{8?L!jHm#rmK2`u*IZTNz4+y(L!B>cu$&o(?Q6TPv*&U z>1p%lD^W0{$;~SH2|4Y^p6k(rr_b^AfZuPxTmy*~iyz84r1Vuv65=w=JwxX+T4EVYd?PKrG1O+w}6L{Y0$4L&01HT-V8+bJ*S@osT4Zk2UFgMnU9eMMS}W|JR8`AVXo93DPrdu z@-&K$AeX@&^dcMZ6RUINYDBUbXsgP{a^l1sW5F0Ankch4m6J4TEX#J{y2g&;z^>7s z%w)MT$9Bn=u8#)13-iL6#A&h+O=Ex5@H%wFyTg z6`=O$GN`q=7(}Z&-HjochTu5K_(M?IL|kOzlKW25i9TpCG~5Ai<5G^3hANbPT6^V+ zl4C;|pGxW-DL;DNIbfu+`2J{>&x<+Gkx637F?%#2Qs#{_LJKTqIy4{1-`9M7D|zN8P}vV z7ybkYqvHvv<>9~tHavmmK?=HYB31R>>4urFPqD5Ha|py8se7=8)#8ujCLLurk#CF} z3Dl*dgU}<;=5j<3kpQK!*gQ43vA~0HR>3{yhXbF>#YRDSCMZ3H1Gr_@M-#j@|J?L4p*Q@npYbOKi^Q^8URSjLwbs z^3R;uH)?#lj$>02W_O6{J8)23_JuiB^6zJ!82ZA0c9$NWmfn8eYvuhGznIxS$A&RbEP{S=%Cez|mH#sxD5-UcIzzP;&BsY4aAf?SJw_Rd;_ci~k`Xv(7U-AgXoQ zyDacf1vAzyaDU#rc*ooG7kv8s7{AGFm#^E!v`?mAKSw zX|5`h;!>8@9fhW|;Vi(sf&>MwpOUP6pHS8AVt81Bpym?>fYKcwncm}>e=HxqdT4y| zsMUj`3#<{Di2*J8l=aG<)+c`0$ncz?fcThLUsGg!dSu#?&Oy1|x(2VfzM-dB5Ek!m z@D6QZ_HP+#5n3$$XxCtIrzW>#+u$)3B^?c>$Z@lmWDVb2+9_lF#vwcZJ;LH5xmY}Q zyP(9iwWT@0tRJxbgX*XeMNh=_n2;SDl{caDfB0ElD$k&}5b89{W$_fN6<^`+PsbS! zEE~PAg5i(%KcGF2ItZ^*o*ul!mcS~wWHBp}rFB_qoh#w|>H#RkKFrdiVVIu!)u|J& zB7%g%><*n?y>4>g3ba#yPfou_zH~+91gUV^bOBPZqJ|Nz|$grF%>zDx-)`a zBdT=h|A@bOh)1Vfv*&*ZyxWNzDkxykmhoj2{jpvFR}{4^`ALZ>(T4xzaIS7IgfhjWe?M~@%n zML`JFKx0XZYC+(4B4;hzk=(a zWbYX~a2UCkYb6yyJP6TBLP*XU2_jA(E{GrSqxAkdhcGIcdrpC5Dm6MpXY;cZI@qMH zL@^pXk2(+_&k-F62$sPQ2ZINWCD$`}TIGLv+H9c^hbhibMMTBR%5kcQDe>tTay92; zex6i`fO$(Ai&gS;vm&4l2r?$XL8Jz)&2+@#TCP$y7tgMA?k*?(nCDnZFJYS@%X0c; z6m3A7rLs7eaoVsn`6iMri|CnKur@f|f!fW*Gks8&RVR5NGv2%DGhMWmW=~h=zT+@x z^>Hn5hvws+90sj5H^88q(BiCx3ARfrOuZ=@nlG`S2PFFY_X!aF8qFX3lyXXaK^VV< z#bSBlii5A3qCmohCGC_Mnb&_%SNFksp>aYiL%s}iC{DO6zsvW)7L2FD+-N))=E~ZK zQ*|6L%0V3as{(4{ScQ%Qwc~_?=P$C?kT;;ec+o*y5+BP+o05N_vua#bRu9E)=G z@9I&mbw?^4w+RS73{m5l9c=o!RMJJMo&h^{SCh&a2p7O-B0r*t*Hr3(=LzUB|E1Ow z@%k`WxZSc$;SqX|2tQql-p?1MOjW*d##^x1s6@a;u8p$1sf>VYkgv|Bia6qG^K4<0 zHh8X$BWSS#^(V_9$(e*`2}Oz|9n}agb6k(6fgzEhxM@MWg`Ei7at3|NI=}oXyFU%h zL(FUHr%heDY@@vY(ixYknRBapWV0;si0_ysa^B+6;$-IX{Cn?xEH9IPm){vR^26MS zh_}zPfo$BQ&w6&O=#(M6KL6ms`Fw63!1@&9o+lFhHz#D75~92UqjZ)YDvep~g{n1) znA@FOSq7DQTGAr*@uYW?)WgZpa?I4<66G1RJaDC-#t>EM=~ok`@_aQGNae7#i8R}< zPE7S=!;_H#4n!b2m?Z|Hx)^wr#2Oc!F38AM3uK|VLZS<{22L~-?_z`34;i&9DWki8 z*+$iaFP1K=KjB(D?$pGhC&r9_V#-+gw_TgX-a^0rD|ZYZ<}OJ63SY==wKX*A(vp1} zHr^|It>_7V|JFxadV25L%*wYG77iLj!EUUpyn?T*miqHD2d}ke(1XxI(`6xN4KZ-B zab<)x4cz|sW7lT#tP`@m!nru&WX|!|A6b_mwS0g*5%SyxHlSg3ly#9$@paLuP$0p{ z2#^1nZ$v7DMmp+b$D99!b@|<&J3nu;uvy{BGk?c7qlA)bO5Vu+CFfSg5Ql~<%Sn&dPwvR-U$Pqy-AylYb(=?tW zuLRZ#-5|v24_oLQ%7U&C82fd^l~zK>1ku=!jSe|RPZ36VGId^KfT-mfxgN;Z$RC7R z%}wp+B4RjXC6Ijy^6`u|xRVz7xd5aZ94D&MLS-L#nHDb=u5OEZ56i~L8?JYrA$0z0Wlw)T;Sh@yQmH^om0W-+mUWsC0<@GZ!5Jc7*BQL?6nqu1Abb1%S|xBt&&53h_vK+z(Keh)^fdFwB1g*ncR5m6^(I=F)}9m8EKjPsdOMreXcrKcnVod( z;{wgM*as$u>;mwkMC}kZ3e^OY;IlYK9Y1GTKa@>_@T!CBVG7*C#YMeNyz7u5)L9?Z zFc$Vf<5=oEz6nn7EX5N{!;=;z$3Af6Dk`~)T<;)8;lTap^Ve8o^?2<@(nG3uSa*v? zd=~VZPx`8K7V1TtrJkyq3T$K&bQ{ly*904*gdO=G;**!~N!`gX^v=d7@qJ}1s*8s) zP~#>{I)fTFo+n+*Zfb2@mOjax>4vl>HwiV&$&OIQqkcLV$)r(D?59$Nob-%uVZf)o z7PXk#qEGzD7FqH6Et29hTd3kaTDT0S=in|^o5y{mmCkXrQ+aL!G%3DM_daVJb-MQP z-nryxXtTsD74;S1pW%7hivFcc7|fWUJBNR6u-sEhq?|-y0Dld>paxMZJZHM<57rJp zd4#`D_S_uxAN>7|4<6wCx0`&P(@WKgntvYi1HGz^oL=Sg93Q5o^?ylOe|0ope=*o! zPwSr*obPW84)%AhKgW;poTT@a^)FRHTAF@3DL9ipjk*0-?3wfX^lS;SVBD*Q(X;V> z!!sn@*&)ASBA!7!*}=g}u!_&ux4M{Z~2t zXE;6Fk5K66pT9-)@blnxUaL*73eR#e;QmUFiY`v0;BTJh&<}s6x<# z_zjuVX=uXlPxwxQ2k8U=udY#}P<{}Y;AZJr*8t*6X+-i@;?*9Wd&F?Fx zzUvPgG$$J_&ZvE04;~?r-CV2EOM*YqeX)O%$h=&3q z{(|poW8f*JmI||*M@49^?J(CO%oXG71rGPY1E{}Os`CL-5z+=G1$6Fv@!Unf{8agD z(?AJMpwDEVsEoHqm+lf>CT~NEM?=7b^U_fZiq1F-!agaed5IJUjLooC<&L0DZ&rqM zmUnLQU=A8DtYxUR#$z|L*4uL^m?NB7kKu@3(rL<>iP0V!ke!k%9r2qg^mF)}Exf73 zbr#8=37e6nfiRBTdcD1#$91Ij@P#&DJh~60Iz&-fE|!*ymOAY z>0TTa>J*B3JXfU>|G+$4kavN+VBcJ|7p{!VrY=4dTIY8nr+}w0ATO96dmVmr^T%?S zB|SH_V|F>ECok^YQFuen_@K0`Yz`F}>RA|0;d70(3!Yvv-$P3O^kaau3s2wqlk3@#eKH0?%MNh@f6? zoQ|V5eH%U>9{vFw4orURbUJXJcgmW$d02d_&cjEne4%(OXMJ_Y_7lgq?^s2LU))Dix5pY%H7Pfp zn_pnGHBRu0^wh-i6-4P+nxHvUYtyMb_jw&P+59#{+gh9jt`v*Mr-;@z)C&-RYu<=L z$%S~#`jPh{m0tNT3wGrSd-18iTcgn%<-hDOKCv!12bN-8VvwipYBGm1bDYK;ph<39QBysH>_{I4gl-ELhV5KhA5Ghlzj8s)%pBT3!8j%doI>m+khm zsCb+^`0?!b?bc(W!tXZNGXO{czkt39;kXNO@v^GCt)bR1rDWyxdLrK4+ZI|LrnVW^ zT5SO?VaBUeyHdG3eN81I`naAMx$3{$eB>7(qnBvrN2J38I3$f*hHN+ArV0nsdVnRMwxAh zoZx(x2CZ%?qVt4j9txsx`x1Ib7tehR*uRhm=gS)tBk-H7 zu+`10(%uu|VMCQJG-;}EP^GoFUCG%Ow*Dl@p=D9s| zCq=Pr$iE+AGeG4T0(`Sj?>o!WpWjEJwj(HUh2VRkGHAJRt&2bI4RIj~j6y>X>E?2U ziz(s5%+^yKCo)8yZl~07^;?=Bza;IBds8)d@h9ZlPnC>X2|CcA(s}uS0+gk9Qc!7J z>#y>z^f^Nm5COm6IblTOjsHf*>}I-{uC2sZ>_-c7o2lJ-!a`04{Ema5V;=YI5p=+7 zN8K`bWZn6iAx)jvw)F+C3~v6C#j5p0aa%t}aoek4m7AN*^{k(#QsUOnnCws!ROObJ zIcNwKI(FcIPuil~?b~1W%3Pk7#*5x29r#lyk{#i~p68?sO6gnLS3RL;$yRYZKi8tu zdZN@q^XFI6^OZUak9odlBk~VQ3U#$!O+j6)125;c8l4cut7`==c#d5=g|OipyOLt| ziT`R+V+#=jy%n+od*4~Mm)p@~k|TmeN{^TCox>~A${~VEvC479T4AqlEapv(zANB9&C1EbQRgM;Y1q}>gtqRL^Nzl2VDNrMsUO}jy8&?4R`_gJc1AqB(QY-?mDfM?TK6;F34q<=$LTl4ZDEWyX z6&O9mOR+F~kOdeOqA_}hXf`P`s`DSV=<2)|3G(|Q5WfQgS)?5IynO5V=UIefR{IW> z?H}zx{Epr~X)9Z0m)MqXzL6(>!{>$Qm-YL)}a1 zTf0@bWN#<@S>F-YUo+EC8#7&gYonw7B_OF)_Ajfb2&Pme-$QLoJPNsHWzh4pFvnn^ zz7xSkr67p{pg}rIbU4_TfO^5Of{|;cLLL&;Es5k;qV&})TuHrsYU1TFPh3OmnBChX zRIzzeDQP2&Eg1I&(^d=5uG~@MZttNKyb(qezIM5F>!YzPcWpZ_M>`7L1jwIU+Rq3YE5ehzr_9O}wyRBid|0>m3qsU8EeE=UF` zCPw&5PrOL+Neg8@;n7+LmJ#e@~-zxaC7x}J+1CG<|Q9#Tx!tnW7U zEO%7Vg9QAFp3A7QEf?!bK_Bmr=WdO*_=Q*lwV_Z&QI4uBw=P~K#qEK98G$xkDAbYp ztWFh7&^(;6_}y4{`*D~rx*BNQ&a<0Czi_S8v^w{r_%B>}IO=sPI!o({c}J7C=&ppZEgeZ(4GH-zlhZva5m8QT-O(=&R2Aj@m!g0|-Rc;hfa3VDSp1Hs#Q+<|4IonvO z@UeVtz$hvhQUmUt__dRAal&uQq!I)YIgn7nfztj%EK!|-x#9EB%#cOpvPvqiu2vrC z0G=pi44LZ0gNy2E*bh{DBZwj6f_tRiK3X8ySa^tvT4g%0dkHLBTp2wup=I6Z{2{s1 zpX_pMlKg{wvo3bX+A*2MF>OXfu`gQ}#*D2I*VGTYy*?#+PwTvdM8J9?#e?-TW*?rM zV)l$51+_wSo}k#d`d8R3DqI4pLPJz0fHPVrC{Q`4BA z#aHUPiw9XGi;-{2H#0)!9G;w;SGX;??hprhZlweqPq0hRD-(GsA zulxZ@fxN@~=%HGFh^9Xg09f+JLJ|!>@1W20L!nLDEttpJFV-c8- zFAKYOPh8_9J|qJNZ?ya&YPY>Z)1Wo^lJ{W%ZxHALC-?$%6bQEB7?&*|Uc?rz8Np4%>HcozXR^c+ag}PbAd!+=6j*3&cy!QLImlDjnk!3=;yO%rTI!4zQ~P)WlouaNH&^ z6_^beXDUj^xij&?FUO|0sT+FuPuAwo!$aSBC%bIlh>?5CI_1pRJM{b1sq$Nqod%CD z=ot2WMqx*FZ<59O8REfBpKR{lee)-qS|5`?oOEDHM%&V3-yeE1#dq$J$@Tv_G%ed2 z&}mX17VbwaZAoUa-qb9?i_2^yK|BBk2?_<-${tKLNgsDxe`C#BMP%2osde}6*)NS; zGqh!7!7~%yI4TU<_}%_N!*~DV+iQD4Oj~ZbL_uCo@iZjK)2c{ zr&!ao^|MiN|DRYx69RmV77WWX|wRf9!cxr0u)Wfp`U41^u3+ElvJ@{JV58pJ7s!(D< zQ#y)-$Mx|_0R9$1D2d7(y905Ir?qaA7H)CuC0go;ICN%Uu64b$w;wpvuYJ+r0r9C5 z#}11g{Zjr;X1Y2vy64nQCnxUxd0(HNo!8XGj(u*y{1+xBX782%d@Hc$AoYzuGRJm} z)B|AqVR)j|kkMK{WZ$>j`|n;eV?g2)M}J(k_?xkE>ygKv>eF-4p<$zrF6%w|2Zbjj z<471IY#K~vf=UxBxSoaNVVA38>bktrd=c1}nVo3~ged!O$|4+|yAAx!eNe0R$5_x6 zkzOo81l+n!1j>{!cTwvuc>AdR>%BXU%QUoGGixVHKltuXOq^bK?$uG_M!KaZZhHqE zb2564nz6di_~*K^M0r)*;L($_x(w?Wv z94blpf)peS3A@H$?vGw=;eAZdsXLzoAc#`;cD3@AmJz zmaAjJvxa8WmmCb~^5pin7EZo0m~EAR%AVA{Mg793Do2G2_q#ub`H(IP$68}POwo-E zr!y(6P%m{1Ji4#tujJ49p*(u+kXUv}9c4GjpU5}plyM%!DU%P+7S|lZm>Z#ch5*x_ zhB2`zLm-JM4O;~D&r(B48McP6gmq;I*4j=28O4yOEHCOpWus! ziQmT5Kf4E*2e&m+rc})i$-u$*0pK8^!tckGy;t$z3-ug~nSci*ppy#1yxu;{E0X*x zhs-JmtwRmdd6*^?rLP|N^v4tTcNHedTl}+Pr=DKX$mHx4I95ZFu3>X zvr|!I-(2MzB+J(~8{G1izcJ^RyX_}$8`ibQ;`g`qFL?IXT?;>ab`rc8T1&12eud6= zo^yVHv^3a1CzwMR8*QJ1+)RKZ)(>km9_nXctl1CVRQJI?#Z5+}59;ptP%Z{vHJVf7 zp-%f$>~*33{*V6MV@qCL*6qD(<98O*6ux8;-yIm#W7XO32EN0(Tpwp}E7<(z^v`~7 zq`rT}cU#InePsdBPBzcWI8&{70sZYRIv#GuQ54Jtv->2VI79xf+nXxx?CRC?sZ&p~o3LPd_q{N( z#eQ}pY3!bY;HwX zO=gD^7rrj4n%5c+;f({(Yc|rT2@i;}-F1cN&)6I{Jd+fKo?sR6nxXpQD2yXZO zNqh$O8_#f8|3vwMmc|W_%$)>vG&oKS52qv4T>yXahu9D0u%#|_)QWz6Ru-kV8NF&i z=S9;;=C%-oZYy5@{=(C}>%{2Za|`lk=SN6VRFCO>R^Hg$yWf@@a{YU@KI}qH*?^>w zoC)394(!mv%_S&4b8u;o!W|`99iH4UpyhzrJ1il7NIwc_ZD?6hpinoX7%70hdl_T*XSc)r;x2xfq9REzJrI4p_NHJr14S` zD6^@Fs$&f*5FA&Jd#v93JS44!&qEr|zSF4-eRJkNR{fchGrPw;qWjo5t`VN1G2SxL2qgCg8Kx(tgR565$~jacOEwyxb!SHEJSAeY zM2iWc5!ws^?;z2L-Q*Q6e0c63|2S7S+%`TveY|aW-HOjE1`n?Id9{%FC`tfzIy@ti~S#y(nWU?lr;OY0)4UCK$ zwC>v40`{R-Wa}XL>tj21923UEl?v&-=KQzkR`(JLca;xIP99pm=c&!HLGBr{pzUn$}1oSlWtR6_euuoC< zORMVqU?7o(v31h7Vyfmx@;6amrcsTPy&IiEYMTxzd>!R3%$Ur&E<9SCId@e1kPbuJ zN9T8LrClys0)pKAqx@X0N!d}|pBmdv`en{*OLD?;r}Rwf*D>4@*EPk%*Q~b$MVh1A z$NGwzgeRz9Mxpd?@dS7Yzr+FuH`J?et#DQPHw&+v%jr7$;47_38b$fTkG<8$U8`e0#M=IrCs zg@g9qeW&Mzv>LXwpD@=x=D^P6;Y<1obMIFioiJK?HucXgLfqFI3`#`-F_a#rL(Li4 zMp}aS!d=@7!oTevH8m)yef|fWH8)I1ytR2?^=+ zTa`TpTSA!`HauB4RQ$s$oF&HfE!#MwZ(K|KSJqclRkuC9p!m?7&YkBRDqe8BZS{>C z!sgn2({LNVZ*0-N>G=PCsL-!y^uV1rndausfuoD6>a!|nZ7~mZTV)Xr`UeCulihH9mSSy@uSS!v8$E`4Sri1;_QAewVdb`xI z!-8!C3aYC+AD?-ysED1G3gw;^G6S4r;vs(6-|f9?Ua!bb14kDp z_1-zZS5#KPC?JhEkD!q6U~Y(e;M`Uw7bfokg z?9hD&vKAatQD2}41#%O>%=!ft4vDZ2!@OxtzQvlfq|PHOl$00Qw2E+%kt9)Z0e7C5 ziUUqfaRntYx1%5yvsQUCx90a-JFZ<#P3#ksXLiV0xo~pdgpFIwqslku<}DhPo>o}O ziscXdlUw-u#AU_!_3fJ@Bo^(P)*+^F-Prp-ppZ)Yo-Iw$dE=Mv98@uV--K2X-KK1w z+AXreBQzx@cYsTOBs0Q5P+AL4%b&2D9V;~=`-`p)bX zRh_-)^slcj%FbH!>O9uI`iA&MYO!tfSd!Z56=T^3Iiuvl`o0A_KUzAyZpToneO#f) zE9F@6T8d5ORjFw&6;(IL>Lu*rVG4imf1-WOz6U$bv7T~)@FesG#XCr`s?mpInLL}3bVDX)nZ=}24md(-@bncL|^o>8?Sd!Cm>W-oRYSDLApZwWD6 zy^7u+E}Q$#)`0`JzB70Bo0~@%?QitAP3_cas;z&oSx*$S>@s7A!l$E<<-wo@o(}D4 zBd=me%9QUzZ05VR0u&d(Ha>rucJciq^7)Y?o)zZ(^`}rUZp_bQ1E0pJ)ift=;)5@w zB#ara$|mlj$FH{;lAWqZGmfk@vf46PiWc9}1PSoS9lIO>6*^PWG|w@I)mL;W?H`{u zd|pmL>Z}>#qmpN=AjT*Lta$)j@DGmeWeD*L`Rv^EXqmC*?@?bxb|Y&)6buqYjLWmZj)Z1iSIT#J-4)fLhP8mGr9)G2Dl(sb=0$SyJ)1dfw4Wtcj&qL z{4D#iqb<9)3GP&~vv4U3Tw}Kno{<}vGIV~o@mb3!cj>fZ88G6QH*~x@9&3j)&mj+V zxI#Xi$15bF$E^PG?CBdM6c^rPr-kS2qvi7?=u%?Ey|vKn${u`h9Vs0p*n_y=K>X5i zCEq6XbT!?>Pw0tMX1aYJy&cbea1(qYImB~Cu)FzwL`Tx_X!bOJFqg#(Z{E;&k|@$s zg?aZY=%L?<5JZ}T3UvzSVeOFa;6wWe%9&e?9W`XZP^dALwlw!sHRmK3Pm|EcUKX2^ z%8OWgkT`tf`g#Q3t)JIC8N#dIU zTRsIQ9jK-7lveq&p53#55Rsb}8s5JDsEMhGQ$}VQLfR#L)2>%bQ&eWZc)#p$R$MtJ zTQZm+fZhqYiEUS`Tfb^SiV%`Bsb^4TZm*V+d7V4@C*`zoSBqZeQ$ym%3@FtcT{#*c-JSzk6Rbc&9wvS^1|ri+yzI+^v z)|2O~?$fP&bUI{+Y_7pvhRBJ){)FA|=>8;&QL&szW7GbuhL!Y~{dxC`3R2s&LHSw#VleADY{_^V~zl^N$PZSS_j^`)vaxk z8qXjzUdY*kU-4Utws6@!EO!={Jb2$2tu|2%)udJX$X{V(3tC}%K~JIKBXvV}G5JBR`j5s=`h5JJ*m zP!U9w=zvBAjXR<-fAkyT8gX-UzF0o(8%g(g;zZH6aUBF%}bFB zDVtXbf0+Eob}_NmT3 zFgmn2%xT~{l(6I~2nMO?H9-o@3CtM=iizH6vZvOdRe3YTa7>61@x`dd77P@-w`Y%X zV-MK|Jp6+W~TKHyI>j+VHNy@Xf!yYunxGnhKKTBd>u9KuOjO$1S9{Lv9v z&K~m7kN12@OMYcEWS<4%g0M&4!|6t_s-gt^P{{`ATa0V>;BR}_zV^JQQ^_HWuW%j=xYxclt#G9`T{NDxZ;_@RX5)}?vLL?vfEEwU*+O$h576yeQx4fECt#c~&|HIZ zZM@`16`_)@zCN|uj++?fg8HM0-`%ZyURMIPa(ZG9y^KBd-}B{#d)NjX7H0Px1T68w%-Y1FNKFLM z(Aofv8KKNY2`r%7*;uYJL>NSqb7Y9han#bpfOv}DrnyyFTN4OMDL&&4O_ z6^0&l>b8=<7mu6R-nunq@W!Kal)+os`UoXWzlqG>iC%!U7RY%)6A*gRHwx1?Ab`KV zdS3WQ9R=z9`xl?^9XPyX=?RrB2;{2`tqiM+(p7q&5N$TpRAISrhQJtiZL|1H=HOr! zspl4zE-&o;X8T}EQNMoKDe2L%Nrgjl64ED(9A5hA6*_vG^4ga2S^Xzv8T~4?z8NEq z&wt{X4qNYX9$>Ty1bk{Cp~g!<=`SwKK$&Kea3La`CTN3JC)%9Oi>dH$BCZQ1D*`W_ zb)6Sq6|XsMC{>K%pqCj>m0>&)cOV^W^+oP#fmO7KcRp=!I;&^-PSrAuIkV{9%z`e; zK6O+ODX_OSTtxOQ;^SlVGQLb-&})eX`Jg4ExrEa z)_WWm%uVL;xh*wv5tzA1!bncfRI+=jDpp|jCLf;6!_H)_TirZDSq(H_p|HlE$QrgU zQU8q7!Ea#k30?o;B{11+L8qpQ!^P^U-ow3-%#9Ld91VZYH>asjrEi_uO(gf;1^ftn z$)wZ!4eflkcg`PD>DGPcT;+7p@~U{wAIALW1kZ>#JyJV5cyvTLlGw8(0;EWk~^6*|nt?eT99#1n1Np z_`FWYsWB9x@|+e15=dSBh|d_W7Pd6Fd8I~+zPaR_UI!siGe+zy=8Gajj@`0*hd!ER8)qF z*QlgyBr}};&HH~haMfV{XJG#e8gH$JoMhXdadb15eBTQ-XfzIuho;eYZ&%OsS>}V< z9PriyU24WZZ0}3EomTSo=GPv}aDGlFtvn-@wqJ2>1DWf5h5YlVTdS>V~M?0v%(l&n7p=UO#7HNF<~*alVgU*^pqw`)pI4E7)|pQi+8Vj zt*KHg)cIHXod|{Kbv8I_OQdP~k@^Kv)pET&3IWmx)luURa57h7q` z;+b1de(FkLLZ5nMN-4~9qcE!0ENRfv+NeuwtcGQ*rh~vc*8j#)+B_YHE!NlN1 zT@(v;IYYiB;e<8`u6s=aN`JpccO{QORp5J&8&?s48&6WnX5~?(2YGe={*qX}ADare zJzx}yYt3l=jrux1C;d#Uwjk(I)5$m7*WVYQJ`5goaitHb^E+8*2BjNr->f$2Wa#eH z>Pf!cd?{Mu!6%ByUOCgs3>sn(*S%(JSF-N)l}Z_jRT^F=rq$bu#I9)icXL72OY4?T zwQa1NEcrUqa`%8&A)Bz)p1K61YlE3=^3`anj732p2V1aac!J&J0zB$UQyo2dE(r1o z!lb7$5(N=$-kh+3{fbW*U{9cYCOdCAYp04M#h&7F34isdjJEEJ64vA~8Xj4uJjS2h zUg_%AGqKBnE^GIZ8lt;NN8kTL(q4V$Up)$a_v&_?Ame|o&T+QyRCtcIT6`pLvk+=z~9{aqv@js|`YlCDBi#KLsN#5JIuRc@g}pX8c>5 zC3Y1DiL%%Vk08Ddr`1B8?pz?2;9^xa8WE-vG{WiRj%~n|0M``={v+0d6Wh<9?8uv3 z*8Oa5Uc2|DaW{87nR4NY)vIToT{h6*Tr0-)dwyyUlI!00%r28b-wY$LMAfv+&k`k8} z8$m?pz%Al?uD3*4ACQqfJR3H5&!r{3Q*36PvZdP=W(&f%sh7q;S8Ig_JohE#h5elxvQD(r!ccpVf^(gIVlP@Tk5cfbiXLReb$`bZyB0(kiN@a zeY|%hZ4ZOAeUAlGiW0YGj@tZ8%Ua38|RaYOB&k)(VmRgi>La0J-OEEI#4g51ym|xI75J%V~E~GTWBoq);1$0uV#Z zL)pG=S3A)-NqS6LV5};aTFzr_+@v&DN|AoFF5o0<<>b70v9b0gDH0`>4zf?)uIUoq zCAzy6){O;D6JsY$b~@!s&6w6ng{urTd9m)PGd)s^a}vV!=tQkLVhBo{Hs-muW1raZ z=(xh1Xzdw8o4n#FE1qYu<3AC9ON>2pRNB=*BwqE^;HyC`R#}uA6Jwm2cqad+3nje&qR}%w?fs)tj&T3=rv-_oM&nJ)-D^Wv3~A*9}zwH;D<>fI61>V1HU1juY>Y~ zwZ)%j@aL)S=j0IlAMAN5L5v^X$8+F&7T%U8!3UyXvU|~L7^%<(%&7ri5GxYO;)C8} z@j(z)tJ(gcH>DZ;eRMOi`-$pmBG+l~8Fg2j(%AWteGvIl{G*6}juD?@A3xVT23f+# z5t=@d8r9LTj{pbnnHhsh1@Y-9hQS)vA>ari3qRrqUJnDtjMaUh9|v&%_;t!YkR zWeKJ6g2yJOULLiwLInCX8Ok1e#y?ws-jZh>4q;6clViqkJUzHH97*# zFst|vEpoW)wsWuxe2W?Xib`~XPtSa17~_U+o`3@(bW+B#+T%S!2E&mY|_ziVQ4 za##%6Qsmn6FqG=V(c1917*kXz9oZ(w6u1Jtw!WOVNyB?M7z~8?ti3Q`m3M3WLQ6@iW9T z3)w6UoAV9h9~?(KbGTeNkMS4bUWNHv;fp=*aHvdw-o~FGqgE=1RNvDB@EyZeM=iNzF;_W+ z=Np?Yi4{@^p3maXQ-pisYW9B9ZPoW;RLlD*w2p3Qe$L-_k7M&ZKcM)?2_kB`$s;`D z!xIVGd!DoUtSm1i(2UZ?tUeN&`@-JzG!4vV2d4wXbb-WPR6hRbi=N9#@%e^5_mt6< zs~SqzPdK=2vKXJA_0)4OD)-Av4=-?xdwtIrgnm9D!|0FjGKL?YM>_Ffewr^a-Lkal zV=)x>L&4xQEI2DB!v!8=b-7tHkn+F9XgU_W@b&D10a5*wdnw5iC(RvXd7|B{&^CSM zt=KVQ$=)gBieFDu$2ro}Ii@tT%wrgXNUs4Q7BqtL(pS#72x zO_PE&kekXYB=yS2Pq**BY~6y@13D>(_C4V!+raQ}k0I6o4}_$$b)vJyDB!VD@$m|w zchCbtu!2b;pX1_V^%>deDkige3FWN#I2-c4J->2ko}R|DQ~3K3n(_RTk~3(~n)Ce@ zmQ7cFnBtg5$j&kS$BtPv+K&FOc1Nr(ti#*^Nmhr^K4XhxWbs66RFBjR`gUW|idH9` zdh~dw5E9mnbpNgT-NsXKLDtl#r)^o9_s{)3JFa+q((CV}RU)-APC5SO?2$oU!9|M? zM)->=H~#^CPP0ciUN-3~;6*uJM*0mRgn^m-pYdX(WN5Oj3n}H6Q;94@H`7EI>oD|z zU7WP7;-^iRyLj1(zWtXza@O%SR^WDAMlyY-*Ro^VU;bgm%Y?4C z{=BdE!>D!LFm3tH4gT2)X*;IP$ciS^+U*~e(-%gB=+4s0{?lI1A5m0pl-ZuZ+8Fto zjdQP=bf4q44RPR&*pEK&vO%(YfMl&>jqL0KscWz@5ya)L*tr>y)P9ejobNiXY$r1v zH;8Fu*M$=Svm<|0S4`J`A$o4hBk%i>{Bf4}!tVhP=YP*!;F}3<7{tGW>k-qe_()Y! z8x{{Ix7u{g+S485?AEWGiOdrFg$#U*4CFg-#L=-sXZKFGmDDeBUYIv3H8~|A@o7c* z@%FWoPh%g}&3xEa>9G1~89f7K+?O)`mw%O(VVp;m?(#nV9GK#HiZ}q( zFR8Gt=`Hz9(AdJVC?41hoTMJR&$H`cC}d}mEVdy~I7E%Q-tn=pBGOf6&yEqV_KfT2 z=hJm!$$&luIbD-G=63AU(-1{y@nABsmt)56PuDH@`vm0^ox_h-ELy&4*j{Po0Ld@H z5@yh8{Yz%FiT5tihJ-}K>2+bYl>TvToiFwvL_F#2tDIT{D%neCHCro@EW zur}M2%W@E4heo#Yq;J5*Wm2pd$KZmPWNRWB`Z&feQtq!EJf?@zNQm9h`Dj9qe$!v< zvFvMU>is>+g>5Gbq60<}{f3cq=dSFei-!5c^z0_ZB#oxOKpv%lHhe5D{}80c7FivK z@9bO(J?QSZ4pwwCV~mQ9eY{taIa6iskdV?LwCjwt;^4~*I}fLadXMbgwNRC2nY8v;rv=G-66Ot?yna~smBD&)G1n5C zZcB1>2u9_R`ihb^Lma)v?9y7I$FAQzbW-~8t+?sq@*6r^>?ve1`R!ih7U|6xvzbW& z0oH>p1Oz<(b8k&X6nV%*rSjy$72TCj@*M?)9)2Wm*@}~cIxH)g)1|$gyfWr$>E=*} zZ$Uy~pH3Z@{*l|85})He;zA}9dH(EG<8~&8sJw$L{cz ziPHGE=S7VHlEd?-d3|Ea9Uwl zevgD~AETeaWHV)i6b~LfC&z!dPfTjgK~eOIHU)Ycl1=jX*fwh4+|ffb%<)-$v8rSS zmGk-xc`9-CBO%3i)M|53beNZKnAHFe8`~R=N`M&K^xFemtPgNe0)WO0h6-`xEFb4K zmHQ3ptQ$#2k29c$3$_i5aeo*?r2m;2J2CD>O;OJZdv;!608R8VdNA|T$C_fIBEs4h zUf#KPW8jchNS&qHoH1^cqLLX(RLpC$c*bYRixjp8s$r`5hvcTYDbiOTpDPo6V-{Eva z;K+9;)F9f(q>7Hq$V#JoO6;A74()6&dHmq5g9mTPck@ez;z`M=TNM?z4&pL@;co`>)86U(#OcfugR1Cay1^Jg>#D8o_Fr7oBZ^cu z5(}9D!*tg^HkL4e-w&}kcJ3w6yFbGS9{@&9SE&)%MvjICMzImzED#4&FV2e8RBIB) z{W4R0Wa^xKN`Pm~eezzqdvL!+)0KM|w-*l02Ebwc>$qI}J@7t&U$C+uEO|c2pHFhp zmSD1V*Ql!f0&E@peXHZU?OPL-fy=kdp~GHLay_%nS<*@4V^2H!S+JGTq&9CWfA27@ zQ@W3q;q+3|ZSgrd%AFU$*9?pJzj_wpVK9g>k560&g*U8xR%(Zy<4Tqd>9J(Ogx#~o zKiavZdr~%`U(J%Ej_EVH*kf{2rNh1Ka|U$mNdhfxFIvL_m(Dt}wyalBRBHSDJ!SdW z3*~^}4LKHfFv!{!IP(MsxUE7lz!<>lnc+YLwP2uA)(+_-N!=2a#BP$*=gC*s4j(*4 z=`>~V@N#K#!)q_TIk%u-?wc>ZMz#^CS zQh7sp`xa41dnQ}Pb37vu%O8W`nJj3fyaPGj%-(TZJ4}VrSKrNhq5YIGi+4XYa)qzf zU>$yOL{d_>k$rP>I))DHMh6?xvnMRx`pDA3j~y-Fqr9UWCi}^Zq0>4(lAYBpH!H{l zieiVsZzH}5y14y5+-KA5@e!qmy*(aZ4}q+Sq!Z~zwkBqeGH{;{nFOhv^{6c*U{7$b zzDK52=Uo4a`d{TU7~ZdW{)cF0Hd6` zZFlhoY`h$x!q4DLY^u4^Cu!NSdd8f5?YK+EBXQwf?*X-gMdFi5gWLA*kd9D;Hi_x| z;(}eOx&I{Hi@OY6k&(2kFg9)YV-qXtH+^vKAR({Lc(MBWnSC8IzJV-#OS(q0)xlhr z;*dt(nt=zfa@aaNE~k-es(&)sXl!NFu*46ysg`Y)AMcZ-)8(`u*(oE=B;d(HC z8s6u=p})+J=lp%{gOOhXyxa#QFBLX4u~>Ka^W)9W1KZJj+0^{JmCq=JZV-b1!}E5c z8uI(!$FY&urI6<5t;R{Edyrf2dB4?j*cyBs?!S?L2Rz(=Bll{0ox{IW*~WZD&ChXr z7tHClR5|p}^JG%VeP{eR#)%K)PntjXU_9n~YUL+_Z;ivdRB3owN8_@iC?c0&;jkX-W{Ge-Vkw$JIr7iQ|bEliKroMdx;y7T4#2gzP>sYyDSl z8KoRzumdNLUq*b?LmNDA@z=1mfWL;VMf2Yo&MLo_&)MXK+@G`3b?l+>Qt2J{cz=06 zOM2nw}O+Il^?%g2@to6A!g=hgmNQpg~urD zcBL|fCsN1j2V!+u%G+t$nDO)Qholr1kR^Hj zV=RxgAz5edMI?9!M_HAc#fxW87&5p=+*snx=(?;Rn(J`DgeIlvE{WCW_g65xxoQiP zIV2LQjJ1L!-I5lYg^a;?Yb<%wTYre2Af?X9WBk1&)r;cWe*hlSGm1|OKu?gn4l>=g z$T>_oAU>**JB@t=fw13Y$7o|RL-)k}0g#?<1<{_V8qHMW_H5ABLo2M&1^51!i@2Qk z_}1_oHy3P8=^eQU@4KIW*z(*)XS<)HiY$C_EzeVFiDyl*7V5SwGXePZ3wE4zu^cgYI!W&zr{wFSUN&j(+f9UQI^JIM|OMMZ~r?Yt> z#p(#tkK7-pe!BU2V6rq-t?@ix$j9OD2inB%+~YXEVE((7_fwIz@-g1u=~~dr*M&X7 zd|jM=b*=@lA-FFLzWi|Tfx9;ML(AUGuIT}C_wh6Se5Bv%>59YVX!q8rQN6mI?-f1K zF`4ANQ1wRFQ0r7O{`>yh{`NygkSX)Cv89gB_A|Qj@#O%(#eHqi0+$slhilY-gsT(a z9@YFgF6Z1nIxdG{1#N3OCx?pP;O>xn=}86-@z^QQk7BcQV%|y|E?WC};&9vu6x^*9 zaJVt~yFHK@apIUUos-q(uCYC)?U|7~;XM4QOF~0(lDmf+l9Icq)k*z7{*?4d==sv> z<*Kpa8SR$p)t$%>i*q(_8*9vXJ-mdLkj*n zDQ`B-x5n?BVoB)|F$y=0z^nOgC_a!|2A~VKPuRLJed6{Fy7gj{`#z1|zj>a206n*` z>9Fg1^Szw=xtxLL+na7Hp$|U?{h(P$5>~wV9*^JG!JnpL{xrbjzQ3CTIPg2;KQ=3S z?o_znEglxq2G<`g?|Xct_f=pJ)tN8Dpb2olp z&E*jL`x~;A=gc*qnB3Q(OaMaXut>0YSm6&&{^YV$GIH9Wl963=A|iursfC*_YY4r#Ag6euZ44d?(EoG#r6} zZoblG8`9H^0d5|mWyxt4W9ZP~LraDa3H7(8B@a*7UXhYH=G5_nuZ+n|+rOO*f2QZ7 zLq59x#TOrZ+;L6MXRhvk+OdelT_g*X4KFL#HlkoW$Nwtu-zG;2QK!xMl(l1LZCY3|bZ)2Ag6yP8n@Yc&wKfwKwPp^sPJiOXM`lJ=r`tM@ z?VX;OSlwf9?Uz_f&si5VM|8+Tzpv-Nd(N)-JMR5J6V?}PEAGU-k)4oW_YMs83iFQ; z!%U&9r{Z1SkVdPj2oNfKw;MJExZBF666Ct;Kq7-)M`IBT$s;0lbmRU52k`#`%4G5z z@lt+Qw94;tKOAT4@%0YEOVUXONv}}mDr=Q;WiHuF7Lmsxm%haLe7MZ|0VN=jDpE$% zgGj9pOSVA>4jLS4D%4&TXd)?8Q1o<0djVubATA6SS+d!xm-3v4Nzb>*1m(%&$B)Zx zyF0qy-^}UF#?8aHUP5Fo38NA^Cu$Lqi{>*(b`dMQsAh!}g$8{b8J4X15YIbhw{;d$Nq4cK02&&8 z`_jwKE$mF#jGtNvJ&jDeFcEoRx6@byG9OiiAg!P_-owa^m_^ECh{0L+p$pBeT+aio zhsUTPh>dX%!YFiFRY9c{0w2S|DhUG+DUVSHV~i8$xY(gu_z*Pi3>vG2c;w`%!jP1N z?gP2Vzd?PW6{77nlFVw<<*IVTMyhqvZTU7q*G!B>q|UCL%3E}xH2;FL59)?~g3g7s zWju;iOQ`Wy%K|5m6N!n!XeXELf?9e z9>U-!(2iWARA6|9D-{j^*2SoM<_!;Pn%ys|P#qQ$5E14_!i?14CvliBiyXDojNOJURW*jVmBh{3U8fQ;lGLf4ZA8;K<)7*`zz3>O*8miIz z^>&&*5Ur7n=`4B?LZIr@>&mxC5_w(9BG0<|J3kcLP*#r;<4ViL+05t6WCgkyYi{@uLJ6&4g z%w?sxMRc0Qt>43AczH=em@Fda6}_W*hm{)apJyeu5$`hLz;?4GlZ_$zIe%u5?4-re z@!%$l8zse!QV{WtE_ly)u^1k zmtcUPpAPtx)hPB7;?bv3_A){~iS9m)XeY?>oYfUx1k(E@0w5qevD5$nU_g{Ca?n*u zCb>dCcUj~Qb}F_Vz>)JPeXV6omD=DX8i@=MjuwP$t3rWQAd9U+^^&G}OgHxcF9;(H zsASSr4*K~Hat+PtINjKqXfUQ0)m_n-E;v*j<{wDI%o2;d@5sBt)shPD0O%N&5QrU& z>;nWcxuc5MT{VlFWCEJ*SFVzz0U1e2dBIbbmz0!DbG>_pe&#wos_)}VdyLsxKIXj_ z%Ga<)^d9<1v6xqfo{L(8q*I0YsC|*&a2KKQh&soed(d{n+dg&$Pq-P^hP++4ew z7zBflua8Px&{s2i7nG0nnc9*p@(DATi4mL1M#idW$&y*eGjcWcZZBiZ3pwPOP>UlCC2+ zHMj=B<2bv2VP41aqh0$M>h$+D+m>t}v4jv;G$`qoVM_sA(_X;X864=J41|8cC|s zzy%PEKchVV=u#$xXd3B7f2YMBDa4v|xFwM*n$>J%_5|AxY9Z3@1!J9tNs%gMM>^SF zI4#o(H7rRquS)f(h)i)KxF3-{AMCvMid?YsKk$pxieKavv;tNLR5|Atum~lLU(iZa z2J=V{^9u_-w~%!45^G~BuD|~{xq54-wDSJ4odA*3&aLxVP2M8%73Ei23`XQAo~B|+;T+h5JqJ3N2Jcchv*(c()h+e?Wv8;(HzMumrK3>W%3`wC zJF?x;O9O}4B9+gWE1FuD1FS&wpo z@&hrju!Gb>45NK z1pe?0Yp5<*TFt5w>)cFxZ^Urt+5O{S!|Q#_VbMV(EWFU_HsXWGD6p@`;9^sHi@Sr& z+TA|UF)IRW%$EPFIdA=s>xYUk#J6RE$e@2)y#Wp}x@BeF{m*OXP1bsBBiM-_;0B&W z!~Eyz7$=!64;y^{KBsb8?4z7+W%Nn?{)d@=*}2p8MGJh4cZqOA9xK{p7JsCxLJbvO zK&6UQ;Gl-=HnZgh9pXAJ|F(<2TOfTQzM`7QBWOfcMiX(q>KJ1>uQ8ra#8(dK3-faO zhmNb>`0K8Da+O=`58FbNW}|RAa-ER3Y02 zQ}U3J!}awlT|HoX6)`7ym`^2SS4(t0M1JFKoFr=`8ObWA)HuDQ<)#Y7C%gs~pYTJ{ z)Hy-T@{u4n)JQ_pXXgw<9e%WjiXqjze%)AIy%E5y`}J3j%Lt5pgpXZ#N>;(nXk>@f z8koOgg@E6j_4?e@S`qACA**Dy%oK>-Yp`m9YQAcXO0s(=O1V-GX|Oy&mXY;73MyHS zPnX3b&KkP-b`6oGJGz$7&}nu))u?RFMl2^wg;$F<>^i=rEQ^GWymCcZbmfXl_x9UxyEA+)OY_ND z+(T%Duv#r@1Bq(M3xc7Mk3dCD1rjm&frCY^#blR-wvmtowh7>5?2d-)%tj0^lvEY>!>LKsIm2!m|BErL( z*b(HT`g&!vc*@yZykGAczZ0K?4-I2{#>eo+*}}_Li*Zm|0~Q=J6dExU6j_Bg8&1QA z^9;zUClSw}&BM~wXo@9%#*P=B_~hS_sUivntT{I5#YR{?o*f#GkD5ep=dU|qK+D1j z<(9Nv70=;_5aIJfSXQHmdVM1xArYJnoSP9I}r`8MoOCAxozBQxH4=N)A} z**N~%ocRmqZQNJ3;-~TB7k28}wbR1AJ$mer)+-Ch2G_TWg?#SXCWoNI_b+t7pr;mY zF@&95^HS*}RJkQTt2`zprH&uhF4^@xUTojt@x}9)UA405d+8I@Dq}v1HbO7Ef2_u; z(**dbwA2u4Dr}3jzuU2)BQ%54uChdii=i=kLm;-LT_XfY<%UhMZFL=?AughtRIsKz zp*-Ay&)@)bG1VIFjvN#{{~Ap((U}<*7SNHI0joWWWyd4L7;aTEIX}O1XM8#SyhY;M z2Hd)JEUDKyvd8h&`l0`_eRrOJ=dG(`mgahG|NhD=&Ns!}<1B}CW7DT{xwHv5 z*aW-XuU(kGA%VrwnG7+7sQ`wxrEhefCXK=65dr0vO{s=*tE3Uyl>0i^8|;O<%qs() zYJr+{?2gjwdteS z96PvS?Uca_t~{@_Cm#~OkCaDe^vV}!;#IqH`{w$K%Ja(YJ{=0DPTcarBion%`QwE4 zDNmiv$r*f|t;zbP+tOW*j~|bUVP5dK_-F&7Fr(2nF(aGXa_H6?!0Cr5CM3?7K~7ZG zi)WXYfYpq+Q8Fb<4ovMq48@ZtD=)Q4T(c8hP%Il~Iz|t8RdJPcXw#lZ_i{~P0fEnh z(dW}rlR-}uoh?3EdSQ84R^Nt+vrlbRes{e}JJ+q5H@jC4qf+A?J2E$A^W_>QYo;qf zVt>FHjMH0|-B+d2BL!KA3J4RJR|Pah)@38}4*Nv}g_z1kN3^ehxz{;%va81zc1@}g z4HUrzI`BkXd^QkeMR)^Pkf|{)P?a4JpEdo^r)0uY?|eAV_gwVCmsX+})b*<$b`fbo z7m;M3$eN~x)tz75G4la+|lnsdSfBdyI*lHHXAEh_>5}?Ao5?~OWQBC#K z(wduDY$Yl6;PC6W+s<;9e&Igx|8Y^w!Y6iZd!?r`1suJb^yM7gLl^Sud*aMyv{KhE zDpvlX%$nL~{KOx-exx{+UH!>8@|g1LpVya9>9T!EPUhTmz-?~RkKpg!z^x6u8h&va zt7!5H4~l|p<^l)Gfh`GJ5nXh7;-*_jGC1Pu+UjoKWth7gRPzk~_&Bya1iK>J z;Jzzo*HhVMYzdPr@sti+lHZCAvqWNLloyU11%FIy{B%VY9o~7{=AC3CS>kZjyH1I_ zqoQI%39&@QhPn1`9Wwo&=uAUuFHy4YT(=CLX99y}9aE{uD>UDA-c?Nq=dH8w@z!zq z878!|dwXfZR66RXG4XEDOsp_0RNm!54o$cY#Y;NI%fl^>Bmu#wo8rzTfj>Z4wn19cw^^tg zv3(hZks-$pe@q3TZV8ZsET>+etnwtjy+{Hnz4@ah@&+OAAIe^Io+Ll*P;OO?{uO_; z)8E*4*WOPrd`&~u^rJTknK1r?>GwX7to64jeMQ=ibx2}fo|JGyRIDM`ODCEP zK8c0N&AS(}v5{@xfb#fF$*Q(Obh%%s1Ixgc=`UhOhNNNUK_Cmo*JsGAEE-dsX1&fD ztJh^m6T4>#ls|9X-nNmPu0c_g1jqcT%64VP2k(o2G*jPxqC>T8EG<;tKaI>^&c&K~u=wL5x$l_Q4rf@N)#!MVQOOHbv;}I-3FXXnHO>veKb-1ap7| z+6YNtkQkW&L20N#*wi;a5Te{Bq&J!5aDD0eRlLK%a}D_TVqDGZwC)Mz+OaF>oLlYc zr4(?n&wXb)^5|2u3?{O_;@{`as+5{Iqhk8fCOUnk_;3(9*8IBD|zy&m91VOZ0T za=r8q@MoY<2z#{EZnw1h8Cff;cvkf#D=-boXL`7t3PU~F~ZALKvjOz`$C1Mh^6Wn4Tk`%#q2X%7u}GO*tP_zBocJio+Z_H3~k30!lLk7!}LF;g2 z4|KNc;ss4;pvI(&MF~BPrYMd{KG-7IZCqw(%)y3os@fC>W`$8`*F^hAcss(Lh-+pG z9p_E(0pE1!?#cEX>h|z|nk9)mS*c{`DX+NRSH1&ohxR#~oj`jMrCjLQljPAQpMPJk zj68gp*p*k0J}2FE)w7jhd^;KR50I9E{>hMVx*&~NuklOrN)VGYu~CI79{B*{iCyv9 zb*g9~&Jj?T;&1dR4~f{6!r{J%YknrGTQ8om6`Xnx7RVUjc8b{~LZ*}Pp0(-B0d7X& z$@RBxe^>BeEu5#GV>GWk&i5Nf=U+#yPyf-lUiqo_w&z-K0L}leaCqYX3ml~H?gzP- z#Erv7<(FRDfddij;F|!c6uThSu2yMKS5F9nJA*4ot(w#YN#)-Dn}Qg(-T-v{lvNr8W$`8ay8=P+_ujJ(H-?Nyh2CO}| zeK_6zZ*89^{{LY6h#x!ST5O+<;9~=~QImvhyHB{m$16VAAnIbcj;p^7JB?ZYy0+z! zn^IJQ)vr7>u-xDP1EZ`@1GeP9X*mndTR7L?oCOQR{fpbo=6QipWE^8(e9?1CnX7?j zk+HYt|M88oiR_>uE*z@L2fzPCKyfYFjg|2C@UHGVl0#w}7r(sept4ojH=}UzmG}CX ztZXg%LVq0R@TUrPyDlxs5D@|#3|4~}7f{#^YtC>$;KyyIr}cj2)*uvW2`e|*Hnp>q zw{b8_o2zTI%znsbl98LB=BJoUpkw4Z4?iFPAs$u-GfGWXl>de~%8()6NzZrn`I^$d z|A|(>9fw-GF2H5_FYzI?R;BMoo}qEdE1&&g;qo;$G~ySL3?j8367oG+ubkLU=!@hS z37XS$oM~pqKOtz>yBh8>EyQ^38)*Tzr7S{wyV_#VPy@g3Zh#r83h>c{#V~e<@51f{ zm!=d_?!PIT9UfqR+vUh|tpi6jXUmD07?^Sd9#G}n90^E|f-wTT$RJ2I<&Q-24xGZ# zO@i{tH=h;;ZzU0kD!LKG|7s`il3~h6E{F2TfvxX-l-EOZom{N{0DD4Y>maX?XF`@_ zvU`Ts)~8jkvLMFjFOTkAEXS zy;eBAHw)RqIrBSJu=FH+qrO5eFpD;;aB`1z|3jFa2CI|lawPc&SYu&^wk7NdTp^yL zJo}T{s3XV9NauV)zTp3$vsu`)(BmSiX(#Bfmo#sc29^r?W~l}DydoowIL`!Cps`yx=!2%@&e+kU%XlA426EG9Df!MjM?57oUAW7?xyW#a66$tpF zWb!*O#olj_4u9Nd@JGw`|Eipne9P`ft)*>AM2Fm|duC%tY$My=g><=UvM9=}f}@X! z^3h7=GK*8333*Z@mFePDcG=%GA1R6W_a5S{1$w_!4ntHu%j898LEM;o`+Ernf0I{` zY~yw~0*<)TFhCtb^}YraO{>@852+$N5PT1S@dMIh<1=7T${A|xnZSTy)b*xPa{-+H zvqWMnoyiC?WWzD%X9YPVzoRN#X*%}k4RXC-tV9N<6m8hrJD+sQYqq}^V?(|L*{4Hn zL0bfTXe6_@-oG%IpI^9!_crn&GYa?CWH^MxgcvF%+;yERSC8s@Ikbi?y;WBJoC|3IGKeukOl^oi5h%3Vh|S> zIi82`bY3ho{z{fL5en|XNk;l@39Pd$dBvJ z%FdlfZj%$bo;p6E&xrcE6-4>_%n^EB?9*rajMz9Ip_$bAoNJ46x#=Z-RIt z%`r!q>rKJ8=_K$A5n}AJN>77)ZS}wdm}vvbQ3hD@E;piVr4!FO!rDBVwxw@<{5QwQi->gj?6cBQN7ufp^hvd)w3|ZGqvpK&9OZWP9is8;ecZmTsyuj9Cqq5QCnW>4>p1{l+39~@Z$HqjP1oE>-uG5nW zaktM2DFI zBxaO>511{+>N~|m^P?%hjWF~6cNK31 z%=bwwhi1hmAi!qE&7KRA`?@UYqke1#o5!64Ch0PI#>A5MIo8Cu#`c!oi z=*aHHAMy~uk^!IV)0u6{;j*zrD!2uSn)dNfPdPj{D)!2z34ug}@}c*)ZJhnq-p9%G zHN?=Y2<4z{A>qoO)vHb`;ori4pF`7LJX^he(b4@%(gIGekxgHV->YN5LD9Ht(1-?| z+Tg?7QPAEnZ3DuMh?Zp5EZ;BQa=G8$m{3z>5c5fatGFGT0cCED!~KXlj@jjU6WnOA zoWHW0T|uvtDa!R_*1PON7Ivt#Is%@i6>=N(-wNhGDi z7wB+LKDfXCN1|#bj(B<9fs14Qn6>-d-}Wl&wLe`2c{)8g-#zC}#VYNU=Hce61LlOD zVxu!NC7fU)bxa)C-0h`hPJfv1sAt1W7id{Y-x@~oi|F(&Y0Dqa?wJ(LV8BAvtg-dz zGcqrAWlh0QWsmaApuXqKi23dAs`S7umdqR3wd=@vqqIN$9gCa!8=)OX4(_5T&g07O z6W2X9Yk~G{jTf0jyEo$kpoz;M{p7l&8UlO9&yGGREZhL+L>sgMLIquh>T1;xWgq0m za_NhvXVp=V8=<(t)r4yNsad7>!OaW~D14on=rD%*2Km?;;qGISk>JV*@=9ejQ3UyC zWvZB?Djca)QCXSJ;I@>sLG+h+`XgnvGI(1pIk3GOIr)ofI%(UMCMGTYM)`D2$}IJP zb%d;{9htEC9)tIOC+V_~qWT5aB~}%pBMrw5euaW!HTa38pj%=v7pFcunJ^=<1K$W- zjyhBRMXYJd+Qjwf-o5d_>Vm%VlXOyo^3@wxdj%DA88yY)DR9SxPAR36DeaUlT_z?H zxRT%i@X@k7#QaWPIWl(5qhoX0cYs-6wCx!>W;l6tVp<|wf8y*TeW7epM}X%ncC}j8 zR0@^GHt@hNtAxoK*`{S#;4ZLCG(%S z?E3q$a)#r$rbW_7`6T9##r$a*(PA3Xbh%9AsY-0`>GDZzW}pt0sadr{v29t|oU2y< z^iRL|VbsJ%<((Br|NcISbSS%SESc4v6qPCcYK-Eg>&nf4O`M6D$e=?bd9 z=yseXf8aD2D!t2T05=Px0g08Rf5RKlVIA1vMI8_*TFT1E3(8l@Ps%HEHniYBDEG%{ z<8DyeaNEaw*}_9)Z<#B<7aMz|Z0y!0e*vf&;6L)Z0JbY+ z@-qp?zkT6_L*(4|hkf!VmMA~B2J8R_UA#OGkr#|tm>>SGYB}VJ9ZP6}z2$MZW99zp zaM!sP^nrN-^C;jU0WPbnj<_A}u2%l`8_M7AxowsC=XxkV59~!oe(vn#k>4cg$djbm z-TwJsz3o#;;UiC7zvjHa440uf?`=eB%8&}Cyd9+I#}86eMsuJgtTsyC}-(^`KCFdCzgz3sl)%SK;<2fC0eUFbrn zzt*}iJ5X)rhh@eJ@hT(1nG^DytoM+Ieluf+QoUf-T1wg`?1QUBM{TzB$G)T|-D*?$+@m+i*=EJ* zx;$sl3(uqN#;&5|G$M}ehDgh+k>==?W0TxGGo|Tw>33;6Vico*KP)?NFu$FUQI8!c zw_GCY3~b}QL8cS3Y_mgoO?ji{2nl-M^|!JzX*&*duF44_3Sw_|&P7uag_fK+tc}hQnglfPzVNx=>$uZpw}Uk5^-(td!ZVo0DYPrpjxYRP->NvN?+2b z%#(Y%=DS{kpH6>|3>>&`fvAJQ*n#{(O33R(I#&6u60Q8Ki~=M}h|ii=i{Y&x!i=US z`4Hy8=~-q`VM3-Z+k#*#h-8HIB2ryEU$^Hg<;z!yzw%T4?5EFGV=?LZo}}03ME(2k zf1LZYL~M7D9%5t7RIbTss#CbjL42J>p9LF?nHOqEd@L9A9+DWADVxcxnX8tK--ZoP zd+u{GSGh(~WO4J_g>xs3UtG2I#V>w5aetH24zhVh(^sl|z~;^Bae)ee4#=mc3E3cl zgrBYMNMN%hqx8T#*Oa5A2Vyijo>Th4>HWT9r%$-9$|~12x|4neLn04en%@-{UMqDe z4y6a2D%GS1&D)<}S=sRjSPnR_n8m5U!6>jE^DP+YGuXVrM67vt<*t((7QIV!Ki?!# z(l8>`KEM6_HJe{0;U{ok*Py(A|Nmj^JK&-`p1*IOaz|4*iiltY5wI7!3WC^sN5lfw zsIkNzJC?*AE4HYhq9S66BG_XzHZ+N`Br$62nna?;7)^v*-|y`69M#|d^O~S{5Bu!Q z&d$uv&d$zkr+zvc5I>53X#Oy6L<$u46@qxHK-j}Rh^pu52UjF~v?y-w3d_MG&mSIO@!zK(JGl@upSVjsA z_cq8)IA@y<%sF|FrAYkAGQe{@E(`J@FvixvB zs>jsBtXbNB=`?&du78d}LqB_*sWcj2$EKjrbcr zQSNLxySn^_d0CQm}h;Vy^#B#Ch zg5@CJ$y$|{JQ1xu9A$$lLZ|)7gS)?wiJr_5`0l=XT$5K;fy4j>azHz9NfU-OSv`(? zcMtFJpZQd&;l%|@P8?wG?()+t@(;y6CBN(LpV;+1${tN#L8DaEmjR88)K4%%t9{&z zGEESvLiyU3-7oozZ9lW0e`9R_%H`-w%8g}po}~Pox^g0ae0XoH9Q@w^4KLDNSJ9uK zIi^;i<^=DVb;6-raju5kd5>>B;J1&B8!Mel+OsN48a79s%)>$ETddwy=CyRpgfr{U z-?^%cu;l0eru97=F=h+UH*^$KU=h2DS`tCZq7xS_jAeiI3;%}K+HB0?=#}~%#23AfKLVjcd=Rw` zD;qsqSwyY?{@C~LThwRi|KuOm;{+f1Sdymy3|I$v3#?vkz|dzeT#);NIZ}CF>`<;k zxg4^j^PQWHO$`51s>%{s0(-%o`38QT|C|IIDE^!o7Z@|4%gn+XgzNNy*ndcVzDCK- z)quS`Sd@w+`YMp`8qC|Egbf&wb&E;YcQ@5SbjLp#vYJ@r6H_KL0kDCyTLC@O_5z(#SrlRoOk!c{Ft#m(;{Mm%0Msvv>drB z^RvEMwD9779HHKO#N1gGB{TCDyP28aT}l6)HRXrkQ$QccldDVs4(LPhwnY3QDl*|; z`Rgmo3jWEGR;M01fQo#lIxy#(Ql#a~mz#RXA^-KK_hE}DGw?oXELTbOuO`Y>SAgD% zWDph6oh~KHj92`RANcj-+4DZXn7#8g&tf~ar|mw#zB|Ofm82JUtNAQT+qNUW8^bm8 zaLf5MN8@B{4U2S?z>zEm(osUcW8nl@(CO^CYHq zEK6dpsg`WkeS5EwD-Alx#zx^pDNiQ()^$Ac|O0-S}~jd4oXJ3fWO-G%j#+`4QUeWAIjRt~XKUz%6g4~?YA3;XA_TdA< zu7R%fI=lG_@D=+uGi^O&FOgrn{|rUECMPYFgXJ@GrfMev`dV^V~^B1IS=Zp`A=1z=(kSLX9yUu^qAx>S&q zwdBOy@3WLEFyDT5=O1JmQwx?TXM&sT2=nuS$ zykRJJCRi6UQyKTRWXHI7vbTKjMO#Jv zX_3&l${DK=R_6+Cz9bM83`hmL_SN4!gXJuk^*H_NIjP|7>FLW)pJL0WYPcNmreAP6`RBe>F11KEQolvEnK?J8yrq zH$Rrew)UUXFZrM{kKee*EOVsk>=E;oJS>mS?PO^eCD?S((Vbz_5--|eHi7^ETLzOh zcJaZN;6w`o+L$n5;w3vJ23Q< zuh_3A53qQ?UHWm=zF)2%JjG|T8PcK6C+sqH>lUV_=A%NrCjAt);!;E zQIgK>UwMytBp*C+>X;ZSMWt&iIt0 z*x|Db9?q_O|2+)jh->VlYiWEn(F|)L&P`5YjLtYY!7QUECqF8PA=0WlGDXH|KDo5z zle`yi#}>KNTe&i4*6jK&tVz~uLQW;=!r|Geq^PqW%g<$)~6%@w;; z;UhN0^AD8v$}pU?!{_M-sivJADyqO8QH7ZT091B0DKfmgwDytYDed{YzklO@uq(UR zfen%|)e*5C-K3ptde-tCJ2P^Y&;6?APy8Ya{gG{7GHLe8&l*(k$!z$;nX`BDdC9LU zd+~P*_FSWz=YybGT$KJ;9|ABw3FE_os4u+qs)8)}I4(oP6(VmC!-1nrgr;HqK7nxc z@P53bSI-Hr*)foyD!nfEU$&f zG|nf}(5DaC_8A|o_m_$Osut_dr-B)V7B1e2 z;|6QDIEZiqQ;gaCm_=TGvDOMs3G;Vx@>9%4OrDbor7MsjI@GtSyW}1! zZ{&S={MQJI?v0(;C#-$e%fJ49c8u-%lCiyeq;i%YrJ8I^|1qpQYhgC?%rD0`=K&10 z7V%nt<-*%r94E*+e;O5xv4W@qB<2YhRgm@BV0I?G9ps!Ehry?mDUO0t)F9LurfVfXi#xv^;W`H{BA5hPfhJtdyMwi@=3rV zd&o)lMP@8;12SOaU-{(HoE6+*`Jp9pAE`OkoD0mG`LbnvB)`k=V3Xh|VI4#t@tEUn zN-TK=R79Q$xfF9kwX)!I*Ah1?W_g>0cUuN#RA;uo{Fe10tC9Wt4!LLSR@?o06IVp{H{08QH{<)}j-372a)vFv-Y4f_C1bPYjgrco= zed1FA-Y`0F^cAP7G7fV{$jll;vLiDGU%rupu%am$%~$gm%=CaAAV6R?nJB-7>3j6Ae=x$bTxJEyx-~hU+4DB zI_1Upe$DD+-IJK*9=mb=EdP?NWFuGaN?CVm(E0SetyhV@!H2tq&J}zpYwLpt!wo1W zHN-n06g4a4U5pRpJtfyH*Ozbjpa(G2YCr;ilHq9W%eJgq1qJLOzv(n@EWahCt)9?o z;(icc$cg$Ec>CguQ!)BLAmIrl`oPEQrZBfK!FK9fe*Y2cBt86f2fGDJ@)>+SoTc-L z{G03>y%TRCIJX_Y3DVfG7=)~DI(?cA;FGWke}k3P8yV)>u-4H#+F9UW6p>0t{F^u%+4FLJ%3>jEbk;I1v?Kujp3Sz)69&tzWkEL zN03+LK5`>E5FbIC$w4xCF@4}HkjUD^a_HjgqQpz8`+j%!4msrW`M>;R7Q1z5_hY`- z{mTk`FKZ;7Pk;~d&pwtw{xz?`t{}6^6}}O=FI1|(!ZJ&mv5fGx!<=L*D-7Pn^)(LT zupYU|zH)Fa77*sHiKqyt0otJiMmdfhW{A_*j07-M) z~yu4uhZK51eQHHgM3oAD^b?boT6aSiY9h-_8zpcQ0x6 zKY#xDk2IL&pZ%J5eY!uf5)cTb(Yp?Jj!dRk5M<)53~*qD->Cru|j8(JQpcTH>zZbW9`ldco(+#=fvK* zY+d?=lhWOr@+S4}FOtMY9eDiJsRI!q5RYW`;K>sna^o$NFJl+``#0Y(cfNzyxR>$Q zjxn`%>#!@sHtUF}gp%vL(L~k<(w#a5g<{JGvHp;EaXwVR^5?W9K4tIs7q2e=C?kd^ zu+-HnF|{6SVw4@*ee1`&SNN~?O_1OmbBq0fyaoF80}*S3$$~Pn>Q`5zepO zjN=k{T^1l#MtKXTL|9wqO-V~?)sf9u^jUmd*EANM5jv&yOI%&riLIHB6lGVNty{c0 zHY6Y*BrYj9_s}8!EdQZoG`p$11OG^jZ8p}(T)-!1w{!_wtd?LP*xbO$%_PNF zNKIQco~_<}_2Ton6EmQJo0?U>wd23%>ss+(i2FX)4doe|H!PT=c4LYEtOGBQEQTvh zNj?yeQGqU>B02>XBh18=W(1*PWC5Z60VtlXR5}Ok>&hL+ADs&0K3e)|_x5v=^po8Y zyKkgjI}&?ho2JMgY()TfV|+Zj)-sBXV3G5_>$xO*ZZd`<)~W~cF5&MaZxyZ9PClW; zZf0R2V)cN6gdxqg_DR{fbM7b4p69bSmOMB_YOz+**8I9`M-1=JaUdkY7jhq&eQ90- zAafGglZ}~MKvj1)F)Kxs0u*;ABAKth3FlA^)4ImRf4Xo6>)0wOW#)9OQ?>Y#jQh;y z<;=19(s;4Zm%!$GRoY|PS=L={q5U|cakUv*eiZ#XLCoAqo1sNo8fvg^L@e5N$ z5Qvz6iUVZ1UG+*ASt8X86J!v1m^2xzt zmsgMbcx_+{mU?9Isr6O;>IBcLTW4{PrnKRvwO+GVFl%D>qwk}H2^|;`T6!tgm*f7t zXZ5V=&;J^;b?ad1!>wE5B|duxo3%CP%j0Yo$1V?R=M83mOPakQ>C+V>lefh#%t?)G zF@Je$$_E8Mjo5SPFva?Xbzf7&g)nIgRsn$s6!%gA+b=L;#@}xy<>ZW(#^huVk_wJI zS9a%oc}xI&t{lp5jTOiK!6$2$PW@_Rm#^pd+H#;tixu+#QSdsyD`#L$Fw;8cPIWU# zq;MfR$PL>r+$nGm1xr?4vZf_}%eJ#riT~Mk`Mu?v?kswl_v}UYar;?dWWgV<(m{)h)Np>JXJS@k%UPl&Gxdl9TSh@Un4!7?SQuNP0Kax{Rw ze17}jXy(gf_Q+NEFU+5IA!+w-!(CY=jeQ`^iGMZOF=hMq!1Dmkht6#}%o zj~fkJXnYbp=*qA_V?&AenxDw~{rm4rrtsEm`;)%C{$x82zIpK5ODVu|bpAO$W%0k# zO17DISvzdj0kWwee49d@U04ZBQ!|FuxWc$7u<6Yl%PG0;sjkB ziu4hoDPKwI20JzY1|OWxxd;^uPCOCofnVmbhR2RC*_#nj4-V+>e?5HY1pu|5wO074 zH2x85ChE^taECb1R>=v2B~4-u2y!P<56T#^?CPBxhxwG*Q}Ulz&Z>+F?xl3FjKHB- z)q|FwZt`xm_#S?bc`jK7^I(UdUuUcenSWteT4} z*?aJj!Ohe89}Bbjmn(C0?*q<)c1y{8UDnFI zF(-o!O5#YIJoCscnmp1k10fgvg)M;HA3E2!Wq#f;LBhlgsukR&-y1hhnA2=dv-$ix zwwJB5KV9iQXE95rZDewXcFQ`Atp7Ee%f6C$_lxIPHGYimTvK}^@#ZMhg$j`G;uF=8 z#tE03ud4qbEev~k?i??ln=9Wvo_plqqr^+tzg7n?(>~t70kSgKLQ@ ztnD54@b1}sp4aq`siWBViRyk707BetARBlpvHi}=Imb_! zAMTbofd_}$v_l254Th7fg|pFkSi~fY=jwH5qg=D-yQvfMsMl0Zvhi9wV0Z!V??dh` z!ZkWa@}iu?$S;TN9=Jn$Fb1B(y+~%&u%VV-4oL_VWR{bW7njgQWhAuy)9Fw8%jVBs z%xufd@F9$ox8@&Eo+zgZI|A|9;UanIYfIgPQAT0hoFmbBf&KuDb>Hh7>eiq#v`I10Y#&) zsfFn0D1#|ih!6VFpWjsXiRXp%HMJ1^A1m8l^nXn2pWZ4tf5r=j`j`*=UVCo*TfqIQ zL_eULfa`Ary)a$@-P&HjJz2KBfP1n;`(pH$qXb<19y;U#iqt2A4`fZgFI>8$UcUtX zSRieXpQv{PPa|x>M@8_p6#g2Q<$AFXm$47kL`%jfxmm$+^wCfHMS7&>h(2%{*H7{o zWqBfpNlASzNd%+V@0p2(A+*i%WRx7%7Yzgs3*`FJZgr6GH&gXRI;PWn;lUw6(r%Pr zoFeKlD$T~FrjBDi{0_=6M%Q{xeJ_xG@NN(BuGu$OQ?VjLMJPPvyQfeQM=Ic`#PB<> zYemQPYzmi}5Bd@B)|U?AUC24bkkCO8&YJL{f~%2jg}VtXw z0X&wK@sISK?9`y(MFa7-fGcf~wqagKCs)a_mHQe@eUaJ`mk;uAr6pTd-Y|8!4c!e6 ztWQT9bmS_zEwemah6%-Vi7CU_FGw?3vfQrNyvyyrC7LKkX}2XYo4@1Y>G!im?4YN=rBq zmu@d~-{Z3Fh3=z|)^-{9fJqTiN!ae*~nIZZF3Bv}}9PKj>1ry}&=O zYOoo0DD z&GK|vonCsDF~c;=a%#cvvb!ZwE-u>xE_%DQbJJhdzSo$Em!Ey zvJ2G90$sI;x!jMu7Bz&-g=^m-gEe&9>IKs`PidPAO{kWA?~SmoJ_Opl63xj=)hGX(k-fM%PLZDDRY z2_rMi$J+qFRJTL_Fo~T2$*Q2X*+nF_Nn!ihYCaUfm;JY+z*${Zo4If2YY-JT11F&+ z!nE zWbD4x@L9<$LPitiYtVAg`ARWUcArm3+JEU%(*CFXIrF`d$DDH2u4!x1SM6Mxw#E|F zhP}vpd+$YF{vY~$DPI@g$Kh@o;e>ftzAnPa*2Arw?B%EsPDnea<5ba*?7Y1EdvGH2 zMZ?HdLEy-lA(!?iC7j>QyXP{eyc_T_J%74i?Ybsy<<3>KNchscF0S}~d}ZYF!-=E7*c>FCDK@pt%x~Yw<1cdOSZ7xH z);hCF1%M|y5_}C`IYi*=t33xFRunqMi~S<_8M+DW!H4Pr!Ou4pZ~^$%tFV2PX#W9& zv=!A49WERt#Dg46K?KBP0eOX7od@c^Ft z6Fo(Hy?@AKMH-jMr)+!CzfYO=QKEm}lK7(^v*;gmDTNQ=A7H9hw!P>de!pVvU!WiA z-=B1mlL@)9@h|Onq(#X7en;?YwH$ed+18_P#Y)giqFPq8o$+>g!)@0$H2JTPVhO6L z7_Z7An9J3OM61}_u?umX`?c-Uy?_5M39B-579{UlCjA%NvU}?ut-7>h(`$S-ckztR z=1RB+3b^6YBI%HTOEE;n`egM<07RD*E5<(Q)W3V5w*5LYn`OI_7vyBFN|63**QHgD z*4DX{ z`g5&4XpeQ;sskMjp4oO@$Ro|1Kq%5Q2MuJ+P~{igT=li;IT4#~glf|@+@&E&`xSRh zuPN?nYj$eMcjZ2iX7ykk+wb|DWuz*tFaU+2NjHc-juWP)ji< z0Z~^@CkUeAuIVI#S5_Z25qQw^lKKeGL1U{va-@7FUJPU|9Cr>8d9h6)B8YS#HA$Gz zskHniS64SgXLf?6s=a@hQ|Zpi^;t3iV7>+4iFUs50#}J=3%#K81P) zbSZ_8hJQ@i_M-oo675Ut836_JYSlBuUxvQS4kdjcJG9BhwBA9d;bBFd|mlFNr{Fm53@Pkkv%%gjsPW^?}kdwQ#@6cIlt0@b5 z5B84&eU5vk?gu3=LnGOUR3X47OHNj(qDr19rxN0$RLr&1kTQ9%)onrmd`YVo~ z;>C*NXP^RqP{iV5h*Gg2LHdabe4qp(c{S;1ghqBTNd{dyHS;<8Q+F1Rnz{y?^ox z2bg-5Z7=%oRi-`RA7JWT79Sdy33L(t7vZDf-=}PQ(SM&3?XgEt1%34OSU?f{toZ>| zg9l=)`x0AHTHI{IZ3%mSBV+_KkK=kQw;pUU+<({y$jz*>utE3@{(trt2#wZ!t7kv*Lzb2)H>!I3Q&^>3YHOQCQO_L5D1qDF>;rePs`KH(L)! z4_Ff@uhkGz0CNI{ZzXp_vO^^lBn)(VRdSmUP-sa8hoSD?k`0T_CnTI-yA**l{COU> z3hgcHrK{UVrLS6*K4*Exz1w*&UgTvA&%pd*Ju&t&+KIECVeb^!w_`vQ>|5x$j#CZP zrt)w!%O2(2$sqrx2r1Xal^p*kQlK`@({+xA2-osE8MI!`W?&XSTm2FIR zF*qhWh~i`=b_nk9-y->g*i5-9%95pPiAsw$5IC7VoobM7NZ{!bv9IdFQSEeK39{Eo7C)!Md$k^o?o~0 zEw?ap-cx4oAbprob~Xh*0!82oVF?*+BA!6*{)km+fkz$cOjIf%|M@G z4HZ1>XsC41AbU92U`fA5+UlS&+18NkDC()`ds_g}gj-oM;LO^k`F|)CG^yUUVw*0? zMfB9=I8Dg$Tmj3tIx!*IcxYgBz@#h@a`%=- zwsh?o>7SCY%F5kmV!UPL4$nc`662LUP{yEeyr3-Tt0AE|hiJIMy&^RmaCY5N8m%T{ z(m#dNE#%eW<6TfFBdvvu%q}TY@MB%ZbAQupjps?Sw6#>1skxJ}uiGvgU94v`l*qpU?gWKA@54zX+e!LT2ZcZ7=$tSEjwD6Bd-kN8k^-ychq4 zW!sDX7Z$ZAS=D8q?gSJ~5Q%*dyVZ4A=U&nZ%cxCTGk2&Ho5#0qHfqM4=|HgP9LfPV zUf{d0L+<->%uS_p8hLoZYUN3RtDINhnw`x8A6~oukOdz7J@3%(R(?^auAc+;izY86 z%HU;R4yJ?fw9CmRdn)4z0iheBNQh;|eL~b(azfVMW&?Av@;l_J>8Lbw+#*SFG8@e{ zB9DTINeI+zUCCS6x*G*7%%`$M!1^HC76rDWj9xZKDpjCCvr9IzS=b5_G@K*iqB-CN zc^l-@x!i%j%^k>^vF>Vmol%G*UoKnHCC*CBNXHFMqpkpd&P{o1Nm{DS*Ok@wvmmNr8tYkj|*6$PYss3RlrIq ze11u{leY>x8P72{CB}?uj2N?8G-gm(Mb%D$1t?56Jrx7O|K-!jCUAUUE^hq2%B{mb zWX&XQNtY4FJaAN*G0Q;$k1bYOs1Jqx`9*1-gU>?P+j0T8&S?6=+TQ3S+HWjle`aaz z74m2qO`xepYoim5-?XW0dtt9`(s-KQ(s@C{C*{5P_?ti{k{QCv+FtaZTDHCDKecpw z9sez5@d5t+CeVfYFTzL1e{0$HqW`TW+QZ%!{agKC0t(40&fR~*y6S*^sY73T9J&*0 ziG8W*w&L(cU0x10HLG3`|wEL>bB+F z8;2&0PO2by)jFo~z@a`4^n*jg$f*Wgn8&ib2g_Q2e@Hr8GdA;)8*9beZV>OlPF6?2 zm+pyow0(4tD4>KuFMk?@uM_$D%yN_1K8am(kDSW5Quu+LxH>fc9?E*>Fh41dJ~NL~ zIs9gse$84RzPis!^lwJMDt7JC_$wKwj^uVt>=Rq~0abD0m|qTRhTn@HdKGu$Z=(8y z2R;*j34Dpa+-s_Tv+>~T94kEIEjfoGsu3zq{s2G=LGYeY@~Mi19Qu?XgcbL^gPnZ> zo!#ZPK6A%TnbvL>lg}eOk}CK<8FRqE3%TvyV^~gGHx#0_wfwo!Otge z=f}1^N}RUiV%*0wPzxhGc{hvH9svA%@j9x>C~Rg1zo>OjpG~J{diy!_+?1`$(6bWl z157z3&e>>>rM1T#2pKKbUg&^BW!noGJyg2A%?&vRI_WU8;5Sy=9{t<&py#kCPSSIt zEAWJ`(B_6%_m7lqFV^KFTL1KxwY}*7Xxa97?r#EJ#JXRsz3Bf~+4iFUV@2)7y8peh zSA8sauZa|fO45+{V$-aZfrPvlPP5dzX27`7CkC*&8{0&-jc6C>-qe2ixFbW@jIABQ z+ck=5pn)*(3JF=&H|1Uq9T(`mC4w}uNG{#zNW2g&1mW>g{ z>a9zpzOrL%k|pCTc%HB{qW&%N{;MWLf>6<0M1u6fBIScR+RR63oNF;kk-3)B(pxER zw{+Q3hiFA>ytekgyD!%M?+g&B!gUZS8&RJVhc8ry5fu#xAWJsM#Q-7o-YvxuOzJyY*CW3On3n}Ec#b-i+IiV8!VbXmQsY-q zI=A@vP06wWb{1Iy?;$usl(FISWj+^j3kiVe&-C4v`qI@h^OTR0r@9iPkZ#mCG7+g|klL+SQ9{#VQ5BWwZCr6fK&{@2R37yVx=(Y~}TAfS-^N?!BVpPy$8!# zJ#_IatI8)M=Tlc?w}Q$MdjXoLUh6Xgf98X|byVw&AW$ z*CJ3;oAQAH4mQUvGnk2!r<=+5&>YY89XL^ z)!H=LxoP@L_!L|y3KDh6i^Iyspd0|GUIgv+p}=%Q0$XtXB;U9Y14_7R@scWOjxctD zhQnhrn5#YzAnYwm-Oe`#$Zk zR?Pcs1<0$7-MYt8DhPe|r^ZjD@3D>u_=<-k!M802-;```KRv!v|_t$&(KCol- zz1v>`C#&9ZHB`&7?~C%vGo0K=@eoC#?QCw_8*baaab50)z&~*UUxF&y4#G$Jjo*vy z8rPXsS+;al?=D+5u`24A7M)|-A^}J1R#DTY&eZ5nYX;p9fR7;z4hE}_flVUE0{y_r zuv#9D_|<2>AIkgvDF5!^^=l6~77EF*8t)EO|AtS~%g{O7*4gTq7Ui|hJte{@ zrZm?`>q$E%lP!z}U$#9sA|kMMOe6lJ#=gYiJ5pw_s_d65xb&fRtXDs}ZcOc}xLGrN z@~{nT`M4n)YzpqH<=@sKeqW7zG$rnUnEnGHFcx|aI_P7O-E18_OO6FjZF9N32o)?g z7FQQ9H?z6CLpdk2qhon9ijH6`<;skucs!3x_}gMHLfbzh2FA7rHj1eo7!h%REqWw1 zyn+iAzs^Y6F+6eKyvVAxW9mlN$6Y7I0hd_H7u>hmFl5|vwqe-h!m$uv6`tK|W9fi- ziBsE&v2=%z9_6OIygZyS9x7SkgqeV3#TXnAMc`Jc-mQi-U)tQ1FX!msW%j64(ZTFq z(H);W&6PYV6^|9x=Ek~JK_r@=uwuoo)m=oGvcCFwSaXN8#F1O~v})Q`UWCZv4)Sg5 zfExFoxq0B{v;24{!l4lvjVZv~2)y<2>=81WFXo1LbhbX8u2|h1WOv7MUQQTJ-ZkPY zZ8VjP}+<%r}Ab;C&&MDGy%3^479h^w&%)Nozs4`>_sTI zhrFn5(^h-3;zzBMZ(BL7F~4HDL^0DW*KgM6BiGEsSOm`6ShSdF6Lv6ojy1*PE_4Ae zu?IqXalgdh#5LQ5?vaq69XzcbPrGoQ$Jv;Wi|J$3TJ|B^zrwv;#Jdc zKHn@M&Q}VnTcdVB>%jW0m=rxgIpyhD&BL#vi?7Ef{sTq-a#xRfof_A!)keV5VtQX9 zR}t-&1uU`u6iF%Z70MmXEN|qE6g~=^Siph7o>q@(G^kNb%%0Py_FP25&BwU)cxU&* z;XB&2oe`lVK@^)b0UyujT`5pkUR2Nr_rQKc7RPGR{^8q}jZf$ii*f!h*zN#fb&4Rd zxCY*8xyUb|0swn;{fHTD+w2&=a5vyT0tRyTkT@)~F>8R5jyeMd{%bSRoM(ujy(X!7~!5`i9wZew( zkUG0o2n?lseN+z_xvfb>H)bUwr~~}}ju;xzI3$EMa9#B2xQ$y!9w-W-)8HymI+~p*ikdz!a_h!%pDt21C)Q;^>zM7V z#ag^{VFdN&fgcl|!?m*v0biGM5kqZbS19LA>A8)4i9HV58;|3;zm2^v=ZHZTa=t-6 zE^L2)$ez{h1BZ}_&IiLlV2b*Map_&n31PrOJ;`oW{QZ4A{rx{^Ik4Q{KUzO*oCIyjA5~Xh+flhdce8<> zfN!#HPJjij&=!T)!k}2Yo@W#V*(Mc6*{WSF8-_>@1?g7sfGuF?d?4a%ZJY&c+AAfz z54MaPLxtfDW~8)L2EHd$mS?PIYYW3=0eGsFymFl7)evcr7&pPtU@IDISDmL8DQ57L zlgJKamIJWmD_Ysq;)Ga!Hs;M{YnUdB)&n=?WOkDCNY;t3(V{ggTEjQ3Jg&mmgjgYX zw?PAa|BAEo$J%$C^Hn0Bk*TuW3*2rr{ZsT@_!IFRv8Nx*0x&Z!TFJ5`%#8AX_M*Ff)*Yc9392*^ zV#9x>z(hS5^n?%=5e2$}A{8Nwg>oa{+jyBAy_^hYz`xZ{1epT9$v)YjEO&M+2H)9i z#w`{zau>p_NAPv|vU=Gea?*#IROM2nrjWA}nkZ@Ep^z=G4~<`!8)w|iwskU>_hLXo z8$U+x5aa9!_{w5Xz{TldLj;35X(T9(f>p#c*FKU_GLzCo6D)y(5H;0ZlP4`;6auE< zV3i+dLlo@~9aJybAQhv5Lkv?KY?2)pgAOIJC_NFjkTLimHIu0))uJ`*}`+I}l|xv`49l9SPJ)%xqN;=HTQaVn>`vs&itT zrDR7NEucc%7TKB2W@l$7GhPx~J8^qo-*j68Ojww)mxw7DphcKKJ--|(zvP^POGM}g z>#?5J2@Ss3vxyiJo4Nw8N!%>_T+W8@9N^^OYD#VEIS}%B5z@~EzoU`{KACygfjaI;k zV!br|$DGT1*qMk_RIyl4%0Ai7oXq56SV_2J%49Q?hm}$)iJcaWq91ek7<*YZ43)|k zq-#MbT8K&q0;CmgDy#D#LVqE9>BCl0zHPe@U(bW41} zvY9grJ>4^Bs&^)g8X}zC*GA#p;&+QY4YetD&|JaO*2_cj!iiC!c09pl3On{s%-X2Bj8IE};ic+4f` zP_Ke&re1b|ibr|vz9rmk+2rJe6H;6dWr!o8-B^%|*+=`NEPG|WV)-h!XcM8%FaIy?QC=M>bMN*krb#ALauFeF*beBki>OC%IV~OE%o7-ifu$8Wk&%gATft<;fk5 zOW}vDfXGmBA0Ka!CmmdZ4(JTYEldtEN!5lS?Mooi>Q@`aypWj)_hU!?I9uAVZ(l5u zrbU zzu@RmX&nEapLqQm^^$AdxudU#u*qoM^D45LKwsE!wqKHMN9!7FxJD`{tUY(QAfDF| z&m(C6W_=Fc^|#TUM_Ql1dteuab{v}mjTg0{GQVr{LxA^J7VLwm%56>G1(WBNk8Q|he}uxwl7U6(TNYVX_j z(cgbh55?fy+oBKm_x7RnV_&(jpa0QQF`RJyTvbdglKqwHvsAyO z`!3Oc5e(a2fZ+9B8Wsa9;FQM)%cI-JfV|kEiZ7_O(CnZC9SQZBOXZ^@VL|c) zc=?9{4^&)f{yXY6^+QJNqrW3X+*Y~5_sBHyhF4;b(+e3)TEa1@+S=69I1oC#9N`C^ zB0~UwV}&wK%Fk#2q1xDg1>?lh!)?;jxs8;H_tbZJ+|4!z@44dsfhV%@(Oe=|4~k4+ zH?I2NTCyMPbov(N=i?s6+{2JZnEANcUgSqCuOtNO@=0@W5$NrlIY{nkoP%V#ZzTr{ zLTcFp?Fs&#Lw}Hd`7L_`(2m@ZO_=uIH2lvOvA@_~d=Y))j??H5gXLkcqqV`dl_?DK zT@UpU!cbv2%FxWv%FxcxiAG3fW#JF(O)`zGKd@-Y{?u$xkku{7PybQ>$7fodv_EgK zKEKgF(@J1``sNLf(thOG@BfUo|9yYt7iFHJo^_sKhq?&#ruG{xXWy}8-*yO4y zZ~L=O>FnQh*k5A|jTB#{H|$T?c0LT}Phm{)<D7AYcA#v&2>bSM{m8$cZ#$2*cC5_^`JN+Pg*dl5)B#iI!Fpx%}}S)@-#m-g6|)B>0z>dF@9A8=LLf4SBfb zHT#>FliV%!_=)js{cjBE_E+(%tN8qt)S>*X(jS9 z8+IqNY4m7({35>J@)d96zdG+(DP&L0+K~~HKKZ0?zx3mYiOw@ywy0Y-Bf!eXz@ z*P{O=N}{zd_D@~|ej;hGGSLy~nMr=HSaYI$`rPK^UhA);V5f=`UnS06`2j2-h$`-}noJ9lX{sYT1?&BlMRYC-Fc z-FvL*+oMOT`0hPAKVuRK{8Vfj-FHc+juk8Js9dgG-MY~&>(pKw6do5J9`5Yox67-1 z`Rv^zR)8*Fqw>{c;IGLuU73Iy`ufnJLrP+PDsTV$@4(sc?twHFZLl|v6v4*GIE*Ds z#5Ffx(ecB&wbpDp(rRhs;fTl%Eq{_GTjue{e_)$L`yiUX4N4;B^DQ1QKs3k&kQ3;6 zcg-uV8l z_zu2NCJ4UiD!$JIo&TZlQU$=3ppWXPwn_u=Fuo(!+gqGFLHJw^V1|%j`dbc#+YGqWbhK$_hQ97ZK@A!@zJ0CcE_CV*29Xo96 zYr)3$Du3Gp;r}FaK?YUrp!C9i+J$TeTfC!rH^T%FgsPhYpi8_BbV%uL3V^<$VT59N zllNQp)vW&8`A!qo*QoLIYU@#T*K{~DiAE6=oZjg`hqIs1$by5?J0jcDlNuj3U76|H zr{;%E*6eg~ogNy>pa0c2rP-o{6(OM*XyWFmMZ_JTujw@A%^&L-bS?t35YtasXtjK( zI5;UbGr|=~l@UJpC(NqR7}T1Rc!8AO80fMgLvn_n9{^pJ`m#%_p~DvcHGjc^`F|}Q zHaw=|Z%d)>4oh7%EhgElijD0N3*yJdN{09og9Zi%Lx+tTIVv=4;|2^RZ^MSL@DU$< zynMwsYvX%CfAOqw9>qm3m^q;yq9b+@QS&b~%qyCpe&z3~Mlfmmn`DO=rP- z38;S1ijWvs%gFc6dJi1f8>xp69sBz0WBgr?e1@;>m)Y-&44$3Ap>8FryRA5)j|${j zLo`3mN>TWc3{hH5uvG%V#mYkTY|Plf;U9lA;s%?0cxV5{jia`l-V+iW!hSwGDJnWT zYSLM$oaf?UTe@`4Ph~g!s*OSNtiXPuq3lAF76Y@VhlGhx1tx%t zRf`=A1AslJw?s8=+<)g`KJ5l3K(g22N!`q$q5a^rxi_YoAG?vC+PTY?VT<`d)}>ah zZry9vgkFfi_(lr({R#XIJ^Jph;)?NNZ(Pk=Pj29?WzuAinKbV34IX#n@bu5ONCzy9 zZ{EFoQ#xbmAY_FZ_88i$wdB{dlKa7G)RqW*aPt+blHA=AFQufUoJg~Lsw8F(8Tg|8 zp=r}rXC68fvw!@l^P0TvF?2+<+P^{%!X$Np7L@U$zNf!Eu&?CBrTdgVxpaw7$<0ke z->dcNax^pQ4g-T=Jk zNt?EG=$M$W)iO^>-1FgpCQX<_i<7hWCL|mlJ7MYe!wnlwTGFlC;lok;CQpg&LHbg+ zi=cOL@`vxS@Xv<`JsdB-$AL$0itl{|{Xc=eJOcW|HxNcf3Ect;VJOt=#sUQuy#p3* zzM3?5>ZqB_&T>sQ@YgNZjDE6Y7My6(mVLlI_f70_Xw}b=5 zd_ZnvnWaq4D5xjk7vd*%6!1xA@`TJ_m4{;rKXP6+ch9DENX{u}gWu6OblJi=75Nd7 zhZ}s<55L2lA-_L_Laa;>5jWoua53eNhk&?ChC@9X#-5r#^2r?BL@Zs@|nffJWOWI2L{2 zSv}N7$JRo=yBmOI`@Q=MFnlS%?z6 zU-72wSIZWDVDK!qu;*n~RlS?=Zvy`z;m054=5f3Y%K>=|GXcL6`l6a^usU7H^3qsG zMzuBlBlL_GIAt}-_@xgU1O_(v@Y1nDzH*U0nkvhj@DSh|Sm;+XFgZj7M&-j|U77^GGl;4i3IcO5%Yt z)w`&N+q2*p`<#!}+Z#CA%a}*Borz-wpf70i?l{X9zjF}3Lo}MO2tz|=&TJaJv_bXm zEz$J#n&vGMyN|HaQXYoBz?JAr#MeWH0D5~Gi1}&cb?^-+)tmC;G;`tlYUqk~ktFa$x^M zIp0J^ju=rhv}>C!N{w2z+PAA+t5)rH?Q3D$C12m#{xv+R`L*v=v6d3vD0En>z(8l0 zu<*{4n>L+2xpR1!i*rC=gEn<*YBDPQDroNp>I>~adkCQs1Q(fod1|lv4I0$%Md>p) z5oI=|&Q#~{vo&h0u2G|JRP^iUD8A1s@4eBNyTKcD!0@U-*I`(CB)&G>!u^;OS;Idd zVAlM}b!*pdzi=k2vbl4o8a4U2)IRU^ zo3_|0vv&p1EfoRF1SLo65t5_GUVMKN-wzdF@su8Eyz(*TCK~Oq&Vy&kBEz(UUobYz zc*w^|qozy^3r*_Xn{Vh1+`01E#Kw(3V+EGiTf2Ab)_p5r8EQcvUqK&Mz9vT)Il*cr zojtSk?3vkrrk=f!3O0?DPSX$A??(&Kwu7`-+N^$n_h2q*d?(;XvM_8Sg>s>ofX1`~ z&^G+KMa+&Y4h`$tGO* zx!2GYj_5sXgk7tS<;qn`bhEc_*{TG5oF|brt;4CzOgP-tVG#?~()I~p!a}z~ zh!unJ;{^uMQJp&#;SdqNu6=v?s)j?vVE0;V2;mSK8b3TV)QW|J9k9^lLplLE;NA-G z2!VWSgNMXvI{*dx6zGBRs+y#>kZXe0^}pp%DBz6r$`)uq^2p z?&%rdn^o@}@9DYuVbkd7rt}xBb)Yxy7=D0#Pz3o?u>H~fDMD>y+o2Cx+jt1!qmc_; z9)@zG*i`%Jn~x}sT$;MCjNNg)&$@lyt-IuAif%ft>5QnTrZF+YJ9eyJw|Vp4lje5r zl(Ho_Bq4HaNYp0{dws?$u;Ad>#Kw(mA1nzCtx>&Y|3;0Zzk`CibX^?yQF!>^)7~QmKH2uYvgonoW=0Eq2 z4-M}pe^@w2fT7J1>EQpLIqKY{OXo6k#JUx%D>+G4xEKp`rF0#0REfMo4B3M;%~;5I z*0t88FSRD=y5*@2h~6x!Ns}fqO`Go=FtA_Wl+U|$8&5fy2YY9m@-{_UxIw zzIS|=t|Pk#1vaP;i?tX`SLpu^?e;lzi;Ff%o{qL|1}~>;m%h1nDX`r>w{GqBRqPVq zZlAe(@3`Y|TAnmG;>Qy?nZv_-QGlCl>n5oV6`kpwdWf{g9gbeu($)prSa-DK&Z_Dk z_5o%kG^`bvW%jsc)0;%iX}0ss(Ui}(k7q+;`%kcuj|P4;x-zh>xF>o2!L1{^4<0~x zGDCOJW`J6S_Hi!O)j*gX1VghrsN__!1xzQKSUCP`v*-Ra<^mzFM{5PPJ>BOy&BS%X?I+7U1F0qjHr7K~=o% z?c5TbOg2OMN7N90JZ9($oDzW(`JVKB2yN9h-;*#T%ebC2rX;<>j<#%XMJX_-PP;gP zQf%D@A)yJ42&LhHtGjloT}wVzu61yyI<<_Z@_hk5SYYJk-5}7rik-b{qN7t#kcJWX zhwT=+q#R*HvOwezA{>U=P9T3Fa$%^&ryFp(nsG;Eg|@-L{rU#uPv3sQ>76@oi-ZOW z3JeSy+puA^@bHeaJ9X~dX?Dl(@M`1bk#{4TG>N3YTBdgFWNYIz*u%j-IOL!>|@HEn*hT;GeQd@o^s! zZkUH}fZGSa&15n-xVyMk(Ga`TZeO`BabJ2zLu~fX^d|gl9Nj#tV4Be4+9kRa1>D54 zgZgt=jWz#@KvLJx(l^0DV^deg)bH4_--rnlYJ@jzJ2|R};?Adh5*iv88p~$)>ZPL= z?&THJ9IT+r`S-xd9u`Pwv})@pyH$j+UIRuY#QUfaZCes;l5ExBV05O2^?+BgX!8K; zy%(&}Y*F8lBl`6nF{1C9-MiPU&CFEJ%^EXi*6fc*&*{16i}ic=uK!|>kYUnq6M%y^ zWVqN0TY@ijt~Ir)9~2b2tzSaleyNQ@p!WkC1bqxG7xi%vJ}Pfq?QG-X)~)H)%g)X< z0V_sS^yBC#2P8-)erhFOmuRf;uQF{#K-op%PIId-bq@_a5*juobM2a*vGV_8>^%UY zJevRUXP@V}JBq;35k$&SEFhf&K}1ySil~5yV#N+o!G^s>qsAU%MU9#SOHN}FTZ|^g z7)`gNSdti%n7qdL=GDX~_uT(8`#eXB`TqXuAve$L?Ck9B?9A*wvscQpp!O$iIhdcn z1x2YWc>Gl2=e<1nIzop)`P4~@eYdt~UVg)(SclN(cTp#Dv7>dhgUY@Dh1FY`eyyme zxB9S>+Eqz>th_D_FRopGcGfORDsLunE4!vUgS|Py(;M3bFxj}ygRMq^_oTbO{~p_Q z+O#DJ2?GY`&K%BB_Vjbe}OtTF)w#r30g)laq?r2uz;sCc}wHd=W`JToCPqeoBigVCnY?0#{vqeq92>@XoEh4`uvS7I(3`AJmG@@vT6 zQ#cj-woY%CTROcWEUa5$Qet^nSdW2;NifLFDLs2lki0vGgu-r~sVp1RIx0C4%&Wg8 z7g95Zrv)^l?GV%*0o`*2GSNdOw2RA35tTQtS1OOTLqYu^x>{Efo+!*f|6bEOW0w~1 zKT!V~$x%1>_XLlu#xn2U%2^ZK*u+XLc&ql)#i`k|-%zgow0@8Hp7N_S zgb815N=ev&d%KPfvutltEWcIx8u8%;`oxE;AOwgwBZ$*{6fsJO|6vQb`Jwz+v-F^- zS@Ho~EBljm6e$6Ii_WJa&la@e6p`Hw{6nw^7aV@-TUl$ zv2ehx?*|lY-jUnRSkxq{!?;PAZQ1-+A-iy{Z;cddW08`HamkT~1&`U2rbuK2`*_G1 zoKc$+G%P6Ur55;I`F%3~T{M2FoMR`Mp-Tai2Y<=hDxH)^*#kux@hS?{+>=Io7@YeE zf^{U1mti+r^bi+#7)1Q0!AfoS#ka*N9tH;l95fi>N#Yd_d#4sQ!{#ntlgfa1x)$aI zn2L8sh0$08?00d2`aXuLDJj&AZ7qzuM4h@M@BsSZh~n@m^LFf**SjpdoGD|A28|mx zsA#MxrN(=`p?vkGIYoJ044q#&X~BX?ljqa>QC)2AlA|~sJiJ%SLpbU?E0zOxww8zE zN}l`@;*HH{R(cwd@CG3sZqEgB%Nmyz<7QhjtUc9GKIiJV!t}%T!wb%R<4Ee^S)bI@ zd@}2B>d~WnHmu*XXZ?mfVm1sV-@xXtN40wUok1gpE9VreQlp$3KB8JQoxgtl{0G;s zL+Id>;$w*aATIeL08A){JQpD@NxmxS7&?KA4^B6d>T@p_jkLRNy>GEtq?6cD+`n7- zZuf2$yqon$c}a*@@^oQn53**`ObLf1shqm>W5$4-s(P5+>}KkY3@o)N$CfTV*7i{4 z#d#&(i|0F+&%0Q8NHkklJ9O{Ac5VOe)@@>mTL%4_@rw1JbZ|BMsCwkET?^h@{p*HZ z!`SJACFSKMEMrk#c{!rSXv-QUPmIxf@iWCRi!~!L(u@YVi!r;8WXFz+XeEnBk8VDA z_4L-*;9ug9czwfSD_FM4trXiKTKQ&fMYIRSSu#oT+I>WY|CSV>Z%>MkaVkBh}A zswYCePD6JQJlfZ4tY*v}+SAmq<_==zCkIQcz~US~DWiS+j7jnFh=q(vt2%jVPf|jH z{MS&d%$eMh0 zkrsx>7O~t+1m7LPnh!a(CowTDJ_a9RLDVNzo@DHc1o578aI4M15n@`5XJFwARIk@i zUl(pCh`Qm=jkU}2Q`nvELL0PFbE?!`L5fD1H9d-9uC>)S5*w?y9TMBDqA@t2ng7_f zX{AMjO5NS{eZs;D2d-Ir_~3G6Tnrfbq4%N5t8+g0J}z%{l6CFUCytvnYh0(K#63BE zbB3+T&p)_o#X*rtqta6nCil(2rO`Al>^=_p6SZ~Mv)PF$K3KR4Cvn-2L0}ZIw|lpa z>YMuljK-Acq~x~6$w_f-@&*si)&O=pTw@jPjlEC-$Fi!eyOfiARP}^XAbv8*|%jGP5s_^ zr=qmfY@Vi<2Kf54P06v|5KTEzV`E}b%=QaAz>2W0Q3Op5r(jJZ_k+(q%)fiEW}||# z{QM?QE-w|gI+GC_&}@Knj%c#p$Wg}%^!q8$Xd*;`B(4{>do{_PWGXkXA8Y*@&Y;-+ zoZX>GEdMu;M!NAI)s<<-c3H2%ok9AR2JXz71qE1ZVLyS7f3cs`aCk&L`zgiz5BsTR zJL{twP@>QcvV8%vb*3FU?2cjTL$+8X>A!B1%SVrfk0fm>V*bicMOLdg4xSS6FcanG za9O|#!L;B8And<;zJ48>M@=r#xhc;KXcmw^VH#Ua_`DwA)4qVFH%Vu9W4*?WQ(iBV zUoR?BIu{kO6ZLTII+koqe1M-s<|Qw~OO^3*r;2tK;om9nCE4=O&qL8332%WQl1z7l zN})-(>{D$RbZew3R5du^{f&C3dS?0L8P1^zUXy!>V(%2VC=h&eG_b-&Gk;f=##(wtQ_Yf6`pG&U#PR+P z?S2f7C1_JK!mQpp2xUggwYDpQUu(mPVpZ#Q>A7WT=_QkQ!jEGNUL|Z-Zo($Q-%K(0 z>Y1D@Z|ocr(z(+d_;nND*2Ugw7hPD8lnkd6&Sz9>{u{ZU%>qIZE~0j;eEt8lqqPzH z|Fok+LvUeuCAXfF$O%yG=%hhxM9ntVx2;@=~>TxwXd)BMWN03*z#7- zbf1~gzC02;XUWOp8r6Lj=L}0p$?7zp+-W!-Xr{ew(g4s8Mnj(_Q}24tkeI{0nB-dL zI5sONYH~uN?5PsuZaepl=PNVw;4>#<*g$^N@8q{P*lU@zk40DRQ!XLcpcvTS);a94 z0%w723f1;*jv1^*_3fsvX6O2lf`$>{TWe7)htHXpzwyNZ`S}AL9#4)jur>OaIAxl1 z1Pt!v2wiiyp_{p(y(K?CKQpyxP|EL}qdRoK^2F<72Sr-10}Om<#g_A?umAsb6O=I3`TEl-B69bTPiGAD=WUM?zH z;hIf6ba7o=RI~)YZ{CvM*=>;0$~CIPGi4p3l~i`wwN-~(nXMtOZ0N&bkXKvq!fiv< ztk;rOl46db;JN0bwiCfAKNvPxA^E* z@O~V;`gbdcjYR+etnoGI0^|n&z*Cgq5^;{eY~4tm$(T7|W@%Z5UsF+CkYdF(Y%uFJ zDj}9uHEVZ1IypVT1pPvOIF0o>KfHF-V{M}mP|qdTC`t`HbFO%j^PKGtx`=yGS4gX& zt9|K=in=Dy#;3Y2sMcvahLeKmOj<*Sl$Nv6t@&ERzEL*waUZ8G8|u=*UG@b! zk(~G#mH#ftHTo6mfsaCK0w~)_s+({aRobAkyO3R&Z|4>*%_)V0%qgv++B1*!UBW^O z2P(G*7KVg&$0AZ0*|vR;f#&37^T6Dc3{z!MO8bnS3v+Y(=FZDaZ-)Uw^Q!^}>DHoN ztS^jWTYRTUl@)&VVT<~9t?1Nw@siG+D!Pidathf(WlAL(mX&zg ze8G$O+C~K|G@|C~Q@b|-mv8jNuBOm|h0kMEEcf;A5L}pIZW-S;Rz9ooMoT0umdzNn z_`tp?9fSN-KI_E<)XZuL;+4wlH!7Lqc4!D!gaxMX_L%Xl6ugkWsC`GPix`O`fJdw! zvLgx%pCL-S+#w9U7I-&fzF2`z@fVJ7s$0%*vK23QX@!}#vMCvLM4Z+2&6yJu1+zGW z*G+MIfg#UoqS*uj=uVbEma>;Al7bQ@J)0#C6@Mf;#8_#>bF0`FE-n+Jz=p4P@QG2#D8{aB#gZjT;d^y&7^|IH-I$IrU=xN8wWPIg-!W-U z=jj>k+qNB3%G^+6g!FQ-Z@aW!vpRM{uzF%ZvsSHgy0>aMnEB-np}I(iu7XZ$g7c_G zik#JYU*rXl{`3R`>K+aP)nY%TOdmtKGDhdv8gaZRhYvKBio9^PalZGcwt0XBF;8=grmnci0hJ*cAgUOmB4zT|6%5r@PuO|z9oB|&h zH!J}}3?|g3B&~nA{KygdL9`w|WYZslr~0_QX6&s3+tYgS$dTm_*V7Mu$-{>#Hu!_z zY*aicKNaq?xGJ9%7~WqD@O@jC5@J<~5A_@^7-uc8x2;Pbe0 zx&i(wVHJl@Q7Uwih6&)ur0dD1qTXd3K1r#Ne%63V0lzHY<#N#QmFMI_y%&dCk!IxrQN-+aTN5bpL?>7mnK72*2=d1ANc{p3&f2X#3JeF|QAm9`bVDzeL|4-jojs zX22%_K3A@^;{$Ht@DG)#4e%{=QjOzJZGdkP5Mbx@E9B*diQu!Pyc7MRw!?r}8~g}f zu0o!x@2b@kDQ*^?Rpr&Aw!dYQ`VO-^mEJd|cq7VTX%io*{VjdR`@0*5PeFd_c>dN_IxjW_^bsur{!z$rWP|wth5-Li zSw^`{Xx!+~)3x|CA4Y292_qYD4WHA`LA{`BGzjCE1Ix78Y`<~($Qvsj)8?Cs@2-^d z+$nbanaVw2+XPW5C;FfRJkXh`e9Pe8xB&mSl3E{M{8rw;;es+%T+jO( zzBT&WVuL(D=@Q_hIsXDt;ubE~BM1m`{+G#Hd3%A!;cGPf(+%)f zF&7R0bUl2%xQf;Q;s^Z#`h1>4Lt!Rj8|{ z;`)J?vssm8Vn0KiF%l=bTd*{v-Z9C}7r!5i&UX{PtAytXZhN4d7Q6F$R@q=bLau!@ zd@qf!rNYL)BLG+F-&DNBB96b*7RccmKF*&8X?k)BmtQQW1GyRkxt@f%gmE#IVd0|o zaeSUnKsSxgoBH^q_m1j*;ryVSDi3{-Hm=dbkdub5EHec1b>y<{Cl1%}(a#B*9)8H@ zAEH>GL;bAIgQM~?PQS06zAi!Q2Zhto@M+$t^yO6?ZpS}O_!t+!PLAY*N^IWM?XvIxIQYw&%*c}pyFdb_t*M)Hm_O3SC&cL z)qa+OIlLaeI-hVuInAd6jUV9a9zs5o{A_^Y6t+hHG|@-9K$rLbj~w1#IZgBd2VH{O z=5qM6SSNRB>&H<(50W{&4Cl2!(Atan5B~F1e2m9ky8C?IKgaph@RjGJ543R_&h>$Y z&*{_pW+Huu|63uc-dfPBtLGN)2jCkc#4RiGXqF1Awf1oS9P)ABYVmF20;THsGki$% zRE}nEc<32|KIo5Ui9fA9Tc|ybLsfj@Pj{2!N7^m`K8)bD#~2^KX!w(P`^_95KgB<^ z_0ylv-+UDx^ncO%ZxV06h7Y~>hi*H`MY_Y`cKp+X54i&m>*}iED*tBmM-cEM#8nTd zUBK4pdujBS3X}PKwA1&JB02q~wmTfo=?jN3o^TB!>b)Z0=lztz`9BCg3wVEA!7dNg zppKiv%2a;;e1rfzj021ChlW3u@WChWI2_sr@;t2cXn=oH{*K!@2Vwuz$G<68a5&F_ z=un9M8rp_xMJ+0QjDrHhU1J1O*ZHZ!3ykiXRq+#npBMiReEkEAmpt2f<#a9oM(EWs zhS}gVmGik>_>EJ8UDWV29jTMozQ)Fl+=cOw>zDfY>N?e>K0el?y?nd@kJ_bsqVlgSqxUl)AMnlL+^!+H z!M;=V-33lRjpO5|JVTrR7_#7J5QnSyy+H>UWUmPqSO(;#;u`@69`xxrb-l3FfX>g_ zIyjlnqjZ%H^yyrU{!mW8h{N$y7sT!12>BGpM~$G5Q7K*HdSWoq7nl00{ab|o#k!1o zfyevtYZV{*6z`t^PWaTn>UvkCoNj=>O87v-KV1(W^E5!EPkvdQT?x3h4$53VkQ^`% zNe;GXE(bnN40^y-Id5fIoPIlMFNdRr;Ag8apTqH9uWlH(<1q37pC^68;jnfZ+V89b z7~=0YijS~Y>PK%QyJP!}ht=p{uzJ`JuRQA5i^tY=zhSW)eEXnfWJJW(9?G|(*O+nJ zSo2lAPwd;&qUC6%{Kc`Ka(cWT(DUW=Xj=mx1o1U`NIzx*IqV|8?$RZn(`&A`+N92_ zR;*fJw#cW zcrdf1I5Xm6>d4i5M|{m<&7Uf^j^pOfAJ(Y@ACmt#rzOiNYpphd7Ww-oReo*L_ zIp*cEnx)d3g`X}jYVrQtvx}oUMn`A#Us1IC!{X06XHP9i%1LM$92TE7y5p)77&qK5 zz{1zW~VQN1>AE@zw%QE6T81Lv0lvnl5ee@^r&_BmzLh z(wAz#9hdvp;XAa|@b$h}WmNjWe@*{B^vW>XMrAo>NIm-X@M(FVdR6-8pr1H>-{H3P z$_hI_4ufjxllf!E-=_Zw^vBp<_y_%pTKp09@S_a^@JBSnCw*y{2>eC7y_eD&^7gI;{#mVEr|Y#h2=MncxM~NIzl3-I=&134 z%kp-PKZ&m=m4J8E@RxHq*`Lb|G=5b4j~^BPxQv5U;77%$xJ4LYVjQ9z z;3~cu>-=_#7y*uQD!$H-j~}96H{J;UjyB#tFBFLYo`lUb)pMr7mHS~t+mjJGV6%0Dm&v@4taQGLT-zh3S`AeK1 zI1+##*G1O$a|Q2b75}(AyAGfC1L33JCe+F46RqFg#!-dVZw>HCKD^&vP~}ixK3cy)GU&I9 z)IM=3z7W09$c-9E@dLy&AtBi9(0G7PMLm~LE<%_(1*4nU^;8{x_`l$HdVkFm*oG{(!VULd@*7v=XqPY zgA)2eYhz>hEx5GAmkKA@s`zgOKOKHHybk^Y&2*FeUGZrZa`yp?q_KA^#2G5$lw*eE1EM0nqL zRwrXRZ#$C9jIYa1)xuuRUt{^y(9Pkh7!Oz;#IUS5M@yB}bqw4&!eF6Brdhqvc@cBU> z7KT{L`$naIOy$RRt`Yp44O&I*8?ghIf6UYRMoiM4sdJ-2-^e{sf20&69_1}>F#a1n ztEXcSM^(!t@-hu{446i_$sakO!C{_bmVK@*wyXGWVHnrp*TK(*JRN>?=+oiv=huVt zajeom1{1KBem(d(KNU{%w;TA6l-jD+s47KX25X+d#@pRi0y%q@y^hs8Mod1m84aOnhlei2sw6(Coe0LxlI#SBO zzI&sw2su`0&#*Gp$`|z*I;wC@r`8*bcs4_O1{1IGd^fmr*=JD15YHOScSDZ$46_H% z>iVUjeWrK1TCR=_J6tby;BskfQ(V>NvmLINP%Gruc>TL7K#SIc>!ptL-G*od)&S}+ zRp(w+e&BeJh4>=idZ`ot-cVnFKe#zW&kom1!}#~cbL(nsy|K^f4d;03c&i&HS6QzH zaJ{6CgGsO-xc%$+n0iO@vD>+|@F!1!gRUbyfPdf<-1;wY2o-1 z05{_OoG~LNxd;I~{JbML30Oa1)0^{@h-RaKd+@PwTQO ze{QQqIEATjaikre+i4L_;Tl}q*F`^aeeJ~OC(h7l`nMJiCxPVC08V`7{0kgD&QtN> zR6G?9PpUDT%OCA|DxB|2*YZQ-lk01zJi>?ki)!US`Z~f1izbI#I2`ilx;nzCK!r=M za5&`8^>l<2+Rx>A#7>9n=?JGn6^{1{NzNpH($Nu4gEaWjT71&a5l-NP=!lS$hEKXV z!fCJuhqVT{s(-seKVlvt{=xDm=~(M;^+PEKQAf=&DIR zQe+m%;i?V&kM?qW!1WU53wmwj??V#>+?Ai^ZZi*y7$Jr{JT2(*r;H=x}=j z8|yeb1J$w4sabLZni;pf$tv(&gTG!W3ISz_*Vosd|}6Tx@(hU8_LY)a)jOnZ*$OgoMVQ(ZYhscnKMz7*9JU0q&~B`sq!kOGXIp< zElx|dfk+EyRl57?^TFk)!uR|0`m~rS>5#Und~p&LdodcEnTlSqQ zGtwedx9xk3(=}Yae5_E6PN(|gW&s)r%SHD*M4J2L5%hj$q9FCZ<=Cd?}qkII}mi5;z?i0~mCY^0?+Q<6T zqfc}BoBH^+8u+4KG#;cRmZoxC+wMO=i}7}wxEwH-4W1k~gLP_zdkr$uaa^qVXism< zt7wn~=+@KFtGAFtoO4N0PyFp_;M&J`EpjRyBOg{`8@ z1lforG*I1lV=0mKNHM_rqqvaY?WEy)=$)XYc-dd%*ToqqYkX6DRrm#kW6q&yjaF3d z^W=~?1A0@%mA3vLxKc{Z`Fgkp71!+z&?U0x~`Ar<1^i2(tY(VRppmj*CV^l7GLTskr zMZzK8NL{_Avd#4xd_ZmXKWIBj+w}s`HZ;{U-g?kR3yjzA)uYWDQolJWZQT{#s{Lx) zK-=aaP2@7+d~@0hn{cWIUPD9LHN>|{RsAV)j+K%+foY^0$wZS}h$_GNke@h_3-JK; z&jIx(WSweD!x=@oOFc5v%RxQ{*KfZ5-6qmN9m{tdh{Q>-h3*Xd4 zbaz1wx`ECH$%~Rg-HorIAH1Hk@kac+NB?5OdG16cJ4JQs&Xs$J^nq3<)yp|xW#7`J zAe+UYO>|?(ChPaG>k`=K(qf#faTYw@a{NGQqA#N6P*b1~?Dt~h4ao?WaA3}?efww6 z-Y-6$wQt|7+57jS4Jbcfx*|`4WRbrYU&UQ)zIb0*O6|LgA7{{y&^51PKFFNzVPT;d zb2ruu{dD)r6-7Zw;K}1TotXTg-^1eAe^3vLGyP~nKV0aCE6;@2Q^-V@e2^_An%}n4S;(Os<3=qs(g?=EHeEf&ks8bn7J~8WpdM+* z6T{JJ4~~QvKNHbrJ4*c~H}P-OWb2GZfJawZ`pFZ@yT{~jNd^`BM+`qWLhAj0NI-dx zOQ5!ebFXWVr^-Z0vOlgZfDUdU4`n-`r!ZzILsW|cxV|2s3I(BAvPbY-{D^!DXY30Z z4bI*y$_|$v(O$d?se3LKpkM>Kxa=o^?a0T4^hCG;O+QZ4uMy1%XM#sM`w=bF$)AI! zGuG#Qw)e<~K!RE1#1{9hKXGyc%T)sZ{+sRP^==ndic@40_KCY>hD&#F|CD%#i8}gE z67_47;MVMwORv7tWAeWym|oz14*JJw^pQUS{yHeUKGau&Y~$7~%q3X2_#^RW7R(1iU38dHR`A$%9;jkfRMj!pQYhgi5q=R1n{>6*$ zN2exq2xn`g0}d{xjwe%7-mU7nEH5u6si}8*qVk8L%TjWqlZM0%GzXz-_y>1&vt%#5 zGdP7sWq{3v(_Jqs0s0SYi*b)a`0KKpldJLU<+HCF1UFYGwbZywgR|rWGsG23&GqZ) zlg}c6d0>F#5`-YRD6@3Da&xz%E#zCNobwvDY!9_iEhYJ zk|nMX*2u7^klK*ef!mEVKh%{Ny`!dRhwlF0Fw&V|QT`AMa5lvmU+_jgOah*JiH*6h z6tGwB-xr5iO{)x{tE?v2!wvE2O@7LlPI*@>_wUo?Y(VcW-dOeM<|^?9(9uqmGWhcI zccE{QT^$Oqg5YSOuDc4Sc`nFw=Aj{Pg=+a-QeQG7O|zt&q6n%cNkqKtT)hM9sCvdf63(keEIyT zmAWf;P944BUUOI<^!N9A&ZH=O#om=#$R6kyl4ydvp*7OIH7R^xri*#<{@T5 z4@qwJZMLlG!1*6_nf=!Yq={3kgs^juvLoV@4NHV%6PM$XP>Ig z=R_~vBUOfB>-L}4uD@$^aPs|S#iHx$@y+sut3wm-Usf#mQi?m=r&F3Niu#OR{SNo( zoGy!!E~6*s+Y9<(4ps$l{K!akvJ~OGZkEo4&b?FaQyip+O^d7BVAdj=6=sdEL8{*I z_oTlmul?gmk9XjM1ou^sCy6Zq8v6I-zjr*I{Dcixw$szUCqs&lS-kY73{M&}8NEn% zd@y_@d>)@?QRmN}7gwJ@uk6DAC(oZ(Wrwv=7xs@e5i6v$h@|A~&DTbmm0)4$E#J{- z(@+Cd%%IvDSjl;@;Joz}trpbt%=z<@{)0T!XAs}$q|v8*PyxtK*N9K*GrJQagHM%X zHfx8qMBKbX+>B;W+wE*Ci&Xd)>!=-&JGiKkGBME$xy7Wiufm* zgZ5m*xIL(w*04SH67;`T>e3}~nIhd)YF<#J`&1NjHD6pQ-h<9{p__;WWO1N07d&l5 zOnqxtbhr?Y{KE8OceJEsdHzBjXGYe!fER}U*+0sC1th8L(C!LU-85Srv z(M{*3cQd#-xH-EuadSb^aTX*7>4NaOZ;(Tfb5N5Ymr%Uyh^r4>`U!(vMhT0AJ;ED8 z^TBK|u4R<$`C^bxS%bLDawpyfz6uj95Q6sP)quptkjH*&SeW0lqHTy)_q(2k)tg4>bdaQ z9^E}WCIz^EFK~f6dF52@~D~Se}@eGzjUlk`fCC!Lt}X+RMqgN6$@h z{{B6CEt=b>_sz@aDyBM+!WSl>|F59UdfsNNZXpxIvC8hHtgDis`!=@bH}N*ct0W8r z-*>@x6QLEo4X2J^o^mHKGMwjEO4csMK>pX-gMb>;RCy=cx;@L1f+r#I*I#NNDV{oiJ zL!RX}u}~)J*lNg|R$^CX^zk*JqbU0=Tiri5xBsXiF)=Z1iuL0B8fe~m3+K&!Ja^6_ z)IA#ImZBV17*EP41SuIz7?HSKZS<((m^N)9 zH)TMpP34`kgxeSSw*QLvr2fcBi#;DL*X%L~>V2srY#rD+8f*w)M+lEHr)sd_DEl#o z!4B78?Sc1z$~x!N!b*U5iNml5uHh8{_CH=PTsjRl0cEdnyneN?fxx@V@v!f$;q?RT z7Y-Xx3j@!RMf?=?Vvk0{TgFl(3)=`7_PXsb;eFsa0tP=!hnVFwz(KIO1CYhjQO-FJ^Xzk6z7b!89M!hk29r5wTH z%6GtVU~zElfCS-Fzei#>X+ZJZv#oCnpxke~N1$2(pJL%plTb*OiD zEezHkyC#LB-V-VeV-(WWAJkptH%ibg9@x01RQGBsUn3crW(x4zKhljphes&NH5RUn zI@G)8f#Ih=`snoV13hv5<|Wa``m5O18pDp_synmTjG2>?tGZFPkCdW zGJYOr>J-~v`IJ5tQM@(+DFq)SE`p|n!snMis3xz$gcMKwM}#|4JB0%U3JW>Bkcbr} zq%j>bns13|5#BaaIpZ0` zN$Q~ckAvsfJwDB@q_=#saY*r{u3g3U`5w)m{mH}oQ#P87`RtfikD8!owkcoTTQ6Po zl%H&9;Z6EysO`4=I`k)^HsP51Jijf!4>iOtDbd{slN>e$zbGIG+3RpYfVb3USi!i# z!@i!OTu`>KQ7pOg>*B$er~Uf(tRb6TjNM%77U9eM)5GR1f6fpY19rNw?ZgJF>eA&( z@et($v}(s;TislNn&(O(A{_5 z!6mPE+HLI9b7{NvL4ZYV+rE+e=&1eLWKlR3m>m7Aqo8i79?m%_iy+wJY{A1{TbiIUqTFadkn_^w&QG-PyChFJ7}|F}tCkH1qE7 zr`UnJGxPoW9%Q4GEnOz;8+u~U%tggJ(|4}A^zP7CyLR6`VE+8U%hQf+`Q_q(w@UVX z_@XYx`svzdm#kGjIzMib^%dQfNx4f|hVt$z>yBl;O-V@u`}W8QcMIFFVEg{&%@4L{ z(Z7FYw-DD>o0e^T(_~^*Ux-67rg$42kbec%H^vxmqY+K?HQ{K1+DIPi#T|J(`=cs? z|Fd~W(6>%myJ5px@g4c=ce*d1e*FSF&xD$VvpZB~3>rRk#IOY`M(xYo_u_Y-lpN{V z`<23F%Z9ISe|FDbUlk6ELZj|I%k+yMe`R2EUl?v(rn_?WtCh#Yd{)mnlF&5Z|7eqk z1Db=el7@H-`E)_rsEMY$G8i^V3CQn^)Nu5nm%-_Si`w|#BwYYwc)$WgLqcQ-etWa| z;I?re#fqM>KhTel<5C9)&fNaJ^38kKmG7$L(|h(P6@hF`;FI7zdwvX@-OSpPzR7MC ztKQ{*R#mL3nJ3Mo&#G0{(c&g1S5zo9_TMV78bJ2NI8**#@ajUIp=Wq7HedMdB`~g9 zvQT`Z?1>35{fk9|fcxZ+ZnG$dj_RJbT5ZZ>d}00Mqq;97<*ITWn^t-EFFiiYTCp(f zo>kw!q=OxSc+w=i_y2&u7kY{OaO5j`4s|m;`$1j>T@uHdWws6WxD;w^ZMfvvbf^D8 zpACU*r*Kf-5VIz5MN7x{)}bLSO%WbOC&|Up-61MC!qedH;O^3_sSwdBBqsgx+4!2X zXAz*pKiYrs<-Z_aDPX_t_Jg|*?rM85H`1{W1Bc5I{!`tC3wOPI$?Njt4p%()sp9eW zrsh-4g!9FmMd!HwUSpd~a4mH!GnToRd6apM^%@^k7F-rm7FuR14Vw@?Hgarqm7&U^ z%CX9+%DJjZl}nXtm0Oju%Du{?%JYSws^F@Ss?aJ^RajMcRYX-}Rg0>YRjsO8S4C}$ zj>jB#G&&d^gB^k$2YB~uKF)h|5Kh7kR`Z`C-K!ylUo7m4Unp0ix|oCtlF6KqNINA- z_{D>kV0qP`S4*~C2o^h-tv`tjfyq-T%5%XNww1g(XyCD-zbO}6Trw|b>|OKL7A*Ph z@MF5+SH>2eKT+w|#uVJfukyr&!m(K4SSXV!ePe=6F}{_IvCuB)vldW{J{T`pKRlrU zv9ka*4|fN;$dvTX+hWE4tn*m4QXpFXwids=QR*+ww=NT>S?5l%28o|qV(gfRL9*IQ$E;R8ZJx|7Gj`9;+_M(xT+47met#n zQb20iNoi%~u1jQuF4^n}IR4_!W^xy0U-kYagy9JcKc@|&EVJtGB=>}PhT|SuT&<20 zNhSg<;(*!#l*r^&OON&WLILSAJX*qmyrNMp(L^m#2GR6F;xNk2P^V z(k9sC=k0#be`LpLuU%x(Lk8qF^Un$!n$f9eagU5P3B!Xk-P}C9dlyx}4ISH!-9FUR zyG6f*)T9ZUQ=^*sH4jQzWbM)-Cc@Rl*Ebkxbz6#`Z5*3Bv28-Z+G!(4o7)Hb#Dw9 zIz@X%I5~y-_V182bns$nZOxWhnE@$2O_!AB&Ko~sgwv|=jKYfr48oy z^XQ9~lt0Nc5_00nWozAVxQ(iZo22IbB-uh{;q{!zW6Rf-&B`nYjWz#}GjM77u>RxU zm@}?s$)Il2mQ9@0Js#%}V><!mckynJRioEi@B?)F=rH%vrP7;GCPAJR_;SJ4>G z{9ar#VaO2UG~Z=%f4MPcIY!hipLKh-@AR+ z)afjA#Pl&0D;D=DE98GDo zYB^adupXVnm`TRGrDj4k@TrM$p+&H<5rDo4!PXd9!2I>GYr^0##3NwD7Rf%{=P60j z+9ob(ukR`TXv*Yo#y(`eOD9_=g9KYOqpI2n62L5SZV&JSbV zofI*;fHo&EIy{r=x{K5T{*q>pCl|dkYSb%5g+&E}Mjk7_%r4J3JZf-3k+Pf(>NwTS z)wSt_j`D73;V1tk-5VAvD)*VU&(y0d)tzNsEcd;0OAHNrvRnGwr(;F+&XOY&I$|7) zbYBzKqkOM}N83o1!Z7rbe}Cdm>hmJ9%U`LUUj5`R8IdY5O(*6w1TG@i-`|b z6dLOkaq>ln@-fb@QZR>@X~dhxnPpeAvb_&t+vY!Y?K;fv&@QdR$6vqGqf_?u>&n{h zo%GgIW>N5n?!H!6SXtS7e&w72gTs8fc3Pl}VRJXe#_jExF}bp1BK&OB?}Ykqp?-gS zF{-I|NZ*I^{Q`9jh{q=CEoF?dWB*URq4ayQ#0#_p+{sbS|A>&~U1g5)g4ld#=~v5k zm43}`E7e#DmcCT>jr9rhV{IT8NJsu0b@-sC1QtTuM=~y*RE2}lirJnfa$_3XJT92W zxKPRVL=jtAuj0yZ{83hJ-n>%LUHReKjaz&7Di2tby?ghPvCCyxJMjExbd@{a{0BfmH zxNw1J)U}0TWLi@+Mt{=UlWu31xaAz9i-eB0PYqw;mM14@ycV<%U3&^dy{(nv3VeGYNE)gfgmGnOrzky19K+k$Qv?%w;n<2>oltlW;>)-Q1CrMP71`fQ*7!WMmgQLy=N zSn~^y|Gp?KI-J;i>-u%uf)Wpf20Z@!^4|d({|fjI#wyZT=m!4V-~<--tZ60FTrS-4 z28WB*KKNyk|Gyik&wF<6G1hx#*faBwq>YW;wCqClYiq*SEkD$*^2xIQR}0zfX0v{O zo+Y02NF5m#<>wSK_kSDoNf$hOmPEw`h>QNumXcnf94V2|!+t^t+N5UScdt{mf;%Q| zybrUlJ-Wz&cQ(E>W5!Dx?+hIG+al$FGLtP~{g(V@bv6ZU+ZLo7KD9$(;*;pa!mJ7y zmQ`A;;)$m`C?I6Na$GsFAN9ajcn|NTPUL&ihi@ev1uGN?L&syF_3*8UH|{{%OEhP=H_F~=bvnBc9C3L(bWI5G-p zL(13vAL}(=B1r!vL7~!;&Zc!s7%?KD+l7?mzCC;QHmBe=rQW@A6H~-5Yl?S{->`A4 z{CZ&9$sd0_DJ@XCJhN1G_Au>l?c*lb?3Rt*t*gU4oaI*4H-jfvAt>#!jm%%LosRkR zBgSJ>ST-#v|IEKn6F!OThpUVcVYLUUB>hunhj@b~jy!(Y)TzUUPMfBD%NBg|jWXwJ z-Nt&;BCv+0MGs6CdHdQmRXbSlj%|;wTz>TEGVO4JH-}!}%@ei_JYsnI%+-o=U1@%HLE*0=A4mjPh%4z!^p|cB;O1|#*%x2Q)a6&!h0v}5|H?fHLekKZo6^3PI-r7>w#A}dbB8K? zq<6##>`{xwXQ2 zv!48X#f#lWd$kN~Kq{pz42pKgDt=wN1I zhAGO;BP7Z>vTt_v%YscD2X4A|2}(4Eg+&=#1$wlMNnJFfhbbI8Wssk!{H;?TSonxF`{4Vxsla!QQ;q!LR0JMHkZ0zI-m*#8@2-U6W(QS4}TDR;e zX+c4yJAeCQTUxR5OaCDsujm^TWKNwu?eGgjCba3YY{ulGL5a%aKB?iRv8J0tdKIM2 z+cRTo=7^Px*3C9Be{ocsZk>w!eazj`GUD@oetB8NC5y7_l6LO(Lj;J(@1?zFPjwE2 zVEE%SaP43D%7rJ-Ur@eaYegTnRw=dqs+8&`J^r80g+3##OU3DrTZ`AM;UvGVnDo!W z#%PK!u){OdJI(b5r0`0R_*#i`GjhekV+$Rf#ucysI(WuW7ISo3_BYelzvL+HM#ytp zOjqyzL(cEDuG4#2w+@-OV@(*Q0nx^8M=k9HL%6R_qG1Qpo*vXS_#a0-*wSOsY^AG` zlUV)pnT^p4k1oh~wBhsM%46St?)p&g_3Nx*OO=No{(gsotE}Cr-H5u*%^J~@=%?Af zm&&omq~Z(aj&{kMeN(Y+9wfQj=Yd!4wBiGR&w}#iW6msCRhn)#`kMlR9Gsm4ywZB~ z%?Jsag{{&};dIH$rCXeu(nHF5QxM7o?jzrMd-}4CXcgp1s;FS#(Nr z_YZ6n*FL~U&UB0n^6+WVYi>ce7LhP$XgwT<^)MT}hLBEe&rq{EOKHC|DX~3n$-w-s zoAaJ_1e)5g1PtR=lvSiIS{*WDWS5MboGUpwNf(a)kvxBK%8=5DD=X*DoHu*+`Q>G+ zuCAInuW(OfPTsO%J?1>KcH+n#E0)g~zkc}1A%EQLlcP&ciHm7l-FA3e-anndQ>pF` ze&@PQ(;DE%T+2sf7%s+y3W=o6O8lk!9vf;W^=yz9+5o06Vj0(%SX$UGeRN)yW0YU% zj2Vd~1*?=Nxt+{OE=k?|_=7`THcgb>X859-h;%sP{klLe-DNL5Vd?L(Q zl3NBVE{*kTnwPaXx4G*g*W0BtOhH|jIb^k86=6X%&4B^d77%RQ_T`%x7Ih=X~qqHR$tTyhjwkeZ5F{N@~_9av*403HB>0De#5W zD*@@*g7rq9;4?>$9up5)``}K;kFdCWRC%cFv7^W>C2x6Ix&HFYEKJQWr5qlKB=*+( z%E@6PU(r%cJ^6vXfP;DxZy1 z3aqgsM{?aT=}D0M{o~g1_fO#Sz!rcHZ8!rObhmtKAx88$w02{bWu4{4EWskgyzc52 z6=RWo(+{x?zgYxJ^bJd!bW5})@TSG|vC())p5OkE&dDMI!5Ii9cZ;)!#W&UB8=O6+ ztHsx7X=yQ80!`h>i-=r z!hiycm-Z!PpvB90*gqoJBB73X0;k~@%Pg_RLz1jmBpZ)UX^(~bDeCAr4p znr?A9qzA~5ZgESsxDhu-i;D&CdRin?w=roJXW+V6yso06;2V~xR7(`+IM@<#)e>Rx zCopksiLpdkyilU8k^bO89C&ZcZ%)A*5&mAmkQ9H?(W3WF>0xooEubp?iJzHMU`NcX zZTu0v!Nt|h4%hjn3>-MHPG(*fe@$jykeTn(W#+4uhRl48hXYM58^|oqB3ld~BIFh{ zIb?J*Slo<<^zOe|(2F{Et5Xxv<&aMAV3Ca$UAnVV6G{DQFk1BZIxrzAK8Xev0-4^p zTo=FL#z%^3LXVL4GS|C=RYIgTc^xx~FKj!$PPuO#w@v9Zm=K0cK`E7-m2 z@$%^>LDEO_HdK#)k|}>*lQ?gKSo+*M?>tAJ-lIqN#>d*JvJ&HzVdp{rqwWGcR=Pno zn&vvW7r}x=KlS*<-Gjcm8zXi09k6hCA7GEdb9(1*l$PvromGXbDDW52x(QQgB7JuIyr7TwdR-P!&vKb8L zwoXh_UMuLEQ!sMb!o|-jFJd}jPL?WZx{lJHxUC=^Jd(z5s7;eq14cap!#wP(0Rlp# ztR&Sl;Gs@2X=%`)eb*K(%styrO&s^TEd)bw$Ht{ zyXNjE{dZ zPVOHV{-$;78{u-&lh*>n-V{f?8OHlC%XUxSOdpT2hO<44JX*W8=_!#3X*b2yWwMbC zf*x1*0$^{F0TPnjo_WI%P*;9!2LMZ~-N2W!g4(SbJhopzQQ^i<@`4g#v#XAkn$!H7 zn*4nN+B^12;PU)D~n;%yO1+|Fxo7}ctP#+rG{jkKx6ZIIXd>}7`!a0Llg**hGw8%z zpB8;u6-^&Kdd13;(a~)(Ggr6I%xquOw?k%TX20Z(C8I}|Y}_@fx$)A8XJW$UbjX_B zHZCk6IC^!fn%&-;SNH1P-7hG!B=D`O6@&J+PWj-IsTCDdElrxt%)_0AFNj+<6y)dU zUC7HXs+hWUTSY~MDR_9kYuusy%2`9=!p2lCoHw=OAh}I3Cb(xi-!m9Dh)?4^{7FJteyBF?&jb*6dsVu#j+16$P`zQ7}+F&`>FihY_c znnRIN`*!nZ!&{1b)LG`sXBW#D&@!6Lf9k7O!S6!w>wtCr<)cC{Vjdy*1S2Zpis*zZ zes`g`2!0O%%oD%st|PSZE86-PA8{}OBu(*4OMFuC>4wihe8%E41D|F1Y{KVNe2(Gs zAwFN@MU0;ISz@;L3uh98j=Xk8o`7gQxB&AG40Xe0uo~>t;V{U@cCjg9blb+dux= zugVf-Jl-0vVH;4ZjI$Eqy8ikPz$oqMw4wQ(;2B}^#QfC4+L4SdYQ>=mbGTVYz9p6r zXWD1L=}u1*Tle|-_C+-vGTQRkcIV{&%E7YiA?*B|VrS)e6nirzz<18VSugib=x)8X zY84$6V2}K*E9>Ii$arLlLTKGTU_sfz6-LkTI5@z5RtCF8cUm~S=2?dKF7U2^ge(Uw zbYI~N6P;jEk4rT=oza~3cN?7IFel*sFqoP+F5qqwe;SY<*`Z5J=ags0u3nKirOTj^ zF`avu+owD;;<;G~V?R5(bJx-5Ry@0MneHvT&eSTVMXOQCqPg!5EN+&2qH=-q9E);$OA=C;g97h0=5T= zDE0=5g8s23dne!T%-!82fWE))`@STby=7)jnVBY)IKNt)o4leQ z*}kA8$an{4ig!Twm{Y#3orW#USf`H=Z>bNPd(ufaSPgdza_EH^6fhr?v*1)x7F~lN zu5lTl5PBFzXdHp*#x*(^vu2|l`HDR_Zpq^5aUBOoEZy9EY<$F)IQ,GZiO*k^1+ zR@J>Tc%Rg|N%1v5iwpB7a5W$zE~QsQ|51ap1_pXJi^|=ypkJ%Rz!2+{ni<7>?`qG* z(;sLb*WTMZu9@{*R-9Echec%ed1BeUd5YhbMN7r^qV`n8{VkIMBC_JMlj7pS77cF} zRo;K`;w>X`a;?)zXvnzdUTFWQJu3}&^6+KQ6vzg}#?Kfv>qy}c{@#Z6Db?dAp4TzS zBEG?{LuZ8{J_L%uJ=&9u1!Okej|7Tr6Q7!CY{@afyu!kXNf=4mFdIfy@Plj|&@Y-= zI1+4>&Pb`bHI=x)5Jq>6xCp&Poom@QZrtKa;;=qHbMuNWkBe5^(5&1J7o7yjJ&X8pbdbe#6p}!odx8}_w zQ$`(|HzFw_!hChsTe5#u)nC?Z&1`)pwyyjyz*282ypJ2i7bo5%=n#oyn*_x#tI7xj&6Zw+43cUsLS><-2* zOgbsnRTZ~SDLJX7$IY16a#3_^|1fL&o__H!_{O&ElGg`%U;l&$de4fE3+o$Ko_4H! zNb!mf#j%>tTUB;h*}wIOsmehZ19<3!~y^{1<;2#6tlPMx5o~L&T ziieL#P^dLFG(9BEim8;*H9L(kvrVSa~2`U=!7zsP| zc(o_&A!PcK(+O!Xm8ck8GNr}PvGv4BnCO%kmZZjJZZGdLIpY4-4^I_kvj_QiWJ9jA z``>)`jyYehc)knk&bG9QE$KEZE@yD%=x&eRv9;$woplo5zdmK!X9MT{77GUM+{0%4fC_MjBgj65Z^9$(j!X-rGz)nh>Gko>(MsYT25*6kD9CiWV?ql+yFdqWQ_ zzRNZtBy+MYvs>@9_9car2KHuJz2#6|Vq{QMQoKi)#anIGJhFLPEmBXvv~*dAu%x71Yi7?0U2NNjap>_Iq7RE# z1)_Bg^k?6&%zd*K^%nj=yl}XrAg4nTRz5PjOCN(QF#gDv#K_3RfH==E-$*qg41%7Urq+L}^i$eE(6~iqoOBF@@pMny&p)uIrpBtW>J~wOu%JC{ZaLK;6hew395noD6|fV zS-8_YM6y%$(oHk_xCvLh()%C0KL)M6bgHFBMTnx**+lONdNIc)hBefA@dus^h6 zgJ;ji!&!9;7B5!P7o(h_`u8kDv`oy0VVMh(mN@#Su~4uyRNhPboGMs86!7NQ<91Yh zBfdsBrnqaI!x*yz=9n=s&P+t}o~KL_`9fz3I|`3eGVxgBnwofM?)C`U`T*!$o^ndHjX0>!q?0E?N;8@SVaA9*_6T1tLfDI<=OfDUXW8_6(<5xr>LSszXsz=8x?g@> zFJ56o)`RBL zI0nq$dsmqV8Z8bgTTmA!F<&c!e~yRT(G9^Gm=*w$j1Pt*9L%1P76W0MhNu^T?81TJ zy{dZ6=+t}dzxG9x^%?vNduG+FomFRg^j0HZ5@W?vq5_^5c}%Z8!CSDleB_Ra1x0!` zdyM&sb&!iEbX~S1vKgkx`HLr7FiaZ>H1P|BWl-s=w{mX+16Ln81E!-<*6^avDT zvF3qx z>&epD9wk6G3kR=tT-P3PG^1}d{EycZiykgM#4gvij`tl;nZGTguhLRws1jOWH@FHb2w$+X}yi|xYo{&Y{+LpKG-y5KD8xloX@n3clZiHo#Z&K>~)Oe z2wGO#&aSnC48}a2&SN3CR@o)U3ia(pF;Psq$OF#s$@*i8AAeo%g8l^|Y3_%#-dGI^ zhn3yLjBTbIY68=6w44o=61e#XW098@3Q2iW?q-MfmWTHjv7%7dSuCrpEB)o^FE;)v zX4jpr;|Jet(d?b>A(Ml&_ny7`)6#|Hlc&9hX>50OO?R?YRn&bM5WI~QP9Fa9%wXV9 zg!*_I^2rM`+c>ha1sl3yFf=cySon|8lhi8su#?HgYN5_9yPb1x5EuJxblaGWgL$17 zDHY<7b*rYlXBZuK2m;MX4RGZbM`+n#%C@kvnR&hJ`_8GUhvS@7h9W!R$A#N-w z@=t&Eu;Z)Ay#s>ubs?O2bs4m;Uk{#=WqV+1WSG)5v}KjvFEl!=^@6rxVb!zu^c={7 zcRjwLbYt(rqO#7Z3x~`P1b$?=T?T$SVvw1zzdG_{1ulWK*EnS6T1J8|jxsr|*J zOCcSnrF4kA!UlcPrfd>Qt^FT0sP3I-hxw=E-vC=5RrlAeeSiFT;vdKQ{+HTOISxWg z@WdDlX&Gc=Y2h>;nqYdP;Y2PmxsNhzB}3dmi-LQ>^Fqzcf4;m}TydJg!KmDoa;%BZ_0&8)ynCC>+$-SKSI=LiKyA4mmix`h z{iYYG>rq5C+4<0K1C^DIH+ZG6us_uCbvrk**&Epz%=Hlm#xfqhL5bdoMhWMzRpceE0ht*L&LU+kl_@J;A@{Ht>fy;ZJtG_eKph z%I|tl`4`WaPtWPS`BB$<&y%;jM>={>={%BUI*jLt7u0}%Cc7k`!-gZ{9LpVU zzytT#|4ZpIop?ZBG@g6pxt|jrcrNic=qg{HNAEm`-sNiw`k*lz{L^ZX-wX@6^Io18 z?>Z;`C3IpsXV6UN3?e=5`IUxq2TcRm9M^MowEKCY@f>&z;GenPo4dQ;TTG+b%knws zlIIzlu_)rCM>{Ul;hyrt2IG8gNp?R+`ShILYtOjedu+SqJ<`#8N@u~Eq=CPg&Np|S zn`j!t-j&b6Rdq39=(^4e#=Ul4rW@nL1K-Gx=a!!C=Y)szy$0WGqkJd7Fk;{yG5C~k z5og;>GX~>cEkb_8Y?Jrc32up$@6nGjx-5qDUIN|0*SUf$)uuMg(4Jgc6fH{_Pt57; z5Zesr{X%`MD8#bXX58<%0W~gKd@j!1IDJE$5ual-XF5XMJR+8o-oU1_Dz=nOt9_UJ z_gNAPuUn+95?91|@ozzqdeA1RO+Y(r4&9;dc{w?ug(godH2FcLp=&=}M?;OG>u9We zdE#Sw=l`>nFO(K!lopP4v~brtS~$#t;pm#-SVs#-lL^N%j&-zftfPfv9W5N| zXyG6t9P4P|avhEEOSpuSD7e#qm;?Ei(B%mEmbiv@pu7&owU-Ietnl26R?o=bdSELLb|E2gfq#bKVjP_AY#!Kp zA*bI~ZM+k;23#eQgWhXsH@w_H*YQu|mAmQO$gltDI^sBWkeIvaaMTb14o_EmauI?E z$`Q*}uU*EsA96LS!>_#aw$b06zV2A_$d~QE68+;BYX6AmNBY8i#Dpea_?ARBY#K&0 zr|1SUTA%AaOiP^nZB@Mqi!lMrRQ2uTH+*~+Hgbi>CQH}OeDQk8I6Z(JQ`LC4FFZh@ zFT%zv$8gu^o@k8jh!8eN;!*bo0{vH%X2+bc#5Z5+%eaS zYn}{Yt*gym6cRSDOP8|&XH#;0JUl&39u^NvHF6^un?;*~coE&$ zuT&7e>h1A$J(l>goAFiM_~L3btO%Aw z)R_fA{fpSjip%!zDzr;tVa0cKS?a6b0b#^l0e=hK{56?f{3XQ3@o@%!J&2)GZ%_Q6<6xA)mOmagGF>B84Ui`{{jAz?*jPSfLBxgHjqKhq>vZ>|HEGd zYH$X9Q|>P!w%RXOSlH@{@6=c8vWUIlFSTFdufOTTBNi`Dj@?EGlbA|v*cXWTkMkO5 zDex+=n2Vu^`&+o`81Rjj73l09%8OSj*ea?zM^AS*xl$n($?BBdh5AeVHQ8VMO`rS~`5jF+ zb1x9B)4$NG(1MogpX-%t@t`i$gh#Hvaubgl9yj4p!{a7Aay>RW+@JBNNyl^Yh@Kfd zYUqsc5R#3?-6bzqhzi+uTwT-AP7PaCHXNB?JuSV`B$yOXGgbM*79pUkkYY5D~0$g?sV zj9}W1Mv3O3uA-1g8ZJ}}2RC?YaJ}xvmCv{|>F{Ano%G|k6vW4A1 zEcf8h-YErHU1MWn5^Pxo-BaSM;laTn@o_1A^U@PzVq&}Q6i0Yc&ORn(NEq;3>BQ5P zkZz?qm8KYJuO$@SNYbLR8+}@QCgXK0P!HlE$f{19E|!+ zqdKP1lEvX8hs^720;>2+Jrb3%<2uy{KS;Gsk0IdM1gbhJi|xiZ8i;We_3VjJEYvlU zv2;r!Q|_n!!6r(H%f?@>U@MJr?Yh`r@txk1fAw7jn|K}nR#W?Pjd8LpI7GQd8J33D zV+=Ld#g2+AdL;jnkN{$A6(3Hbiyi|pv4e1xcwzhrlzKS=W7-h*#yJ8ogmPd?2O0$k z2aE(_C-rSP9$Y6>`B!>NbnWdx3*mSPFPCoP2g{)B5DaTu76y(c{wL7W~2GAK?B^6>AP5Qmj3D&C;3F;4IWAw-Oh zias8vJzV!KC6k&@GrOH9Q$a@O9PM}#$z`39?t{DuP&y3t11%t3(Wr`~3c`vUPukVy zR5el&`NmF0;f6Z$HLZA#j(_0Qsvm|wIZ%2Qcoz7K^Bm_Rl|4@l<5abe!YF9+*|QF4 zdroD~ODcO_O~yN4A0KaDU{sB<@TT$ZurD-3x3Wir?W>!*LV8c6 zlZ9EDAEo4QS1q}A$W2rvM6}>;ol-lrOKz8(*tKJfBi~iu>>|4u77-kT-X9zhrd+az zg(kO|ot-tkJ@($Yn}L^CP+-UAE!u|!d3nh?T_|;*734)??Cdk#A*7>$ldm>7O-cDh zW^gIG*yAk-l$V#6PXK_mP#$se{EA~*_l{i?lS9M8!rOI7?bJ=VL=c;Yw`d;T(jOUI zm2m|d@Y;9E$jZ*>(gvxC7hLu=;zfiBeqS)h8qmnVz<6& zUzKbQ;bEw5G>GobJAR?6g~4$*|0OkU{$IL8?V}6TKqqP;#vQCoPMJsg@F?8Sut0K8 zjor zw!!}va>i8bP6 z06R5N`~*B1_D5=-*nj7Z8wf{NchEfTBG`qRx}k2if`P(0G*F$h{m3`Qna|ztp~3Fw z?!GO8?dk?M&W>g>AFZExVyq>2E?`(_)jaiSE^zDzJHzb42~GLdfQNizocS6=xQ*?% zvmabMV?EUk4v2H-bVTO+xc(1wh(X1H= z#5=2KY;t>hUS8ISekTSE$<2+k@}sViCAD(S9pgrHY~Q})h;et!sVv@=mzij_#^vM= z9b60)fI|UrxZjCGV~HXcuZ-U4#3ho(B}`t_yR31!xkCn>=rrKQ3> zi9y~u^^YUgcPZL+3(}ydX_2Oa`3|%n$QC((Gbo{R)F2ue5k(7(V=veJ*f3_QL5z{I zR>2189;}eYRz8YGS5d=%7l+7dBKdUARB3Le&5?0>Fdo3?iRy=j5gI)kCIwbmZPIbf z>1~G!l(ouv&lsz_n)33jv3YU!T$;nh6(Kfm%IIO`Q|?NR6KZaUL4H}a_w7t}W9fZU%7+m?9g19#^I}1SyZWs$YP$+*T7=9;Y_)c&HlB=hG=%~F3&1ZLHzodN4t||K`%Hm0PV!5Gy388*^?%2o z8Ui|txv(~YOl_F;B!d8&=}4HQzd3n^n4nEzat3=~1J7=$BTq{}mXl{q>&R*4bD8*{ zP0&OO^YO+!BYzr*8%2|SQ@cd=G|ZZ$ebvP;t6_dq4pvFq8)?Amt7KCytKVrZ)XD-9 zeIOUa`2dSgB*=lx#k)n2@tN8syo;hIc-K;#CvuzQLwcDH`6(5(AC#G+l^He+w;kB1 z{&ZGaFQ-K?2w%8hn1#_6s!a8UY50QCDlmL96Q&C0EMs1aI7+Trtx@x7N|7icGVJev z0J6u`@si>)z+BPE(AVOyQxu~q1q5rJu#IGs2466W>nN|RlQ+J zmH1%bllXuiS&+Y&8)N69Yc^|eKTavCH<2{IZ2#bWG)jo}Kk7{epX;(d_`oo88fVLt znf%Z`e+6F$fR}mTE7sObCk(#2-_d#lz3XqhbL!<}Gf<^xhSd^og$XLuN@r@gW}os* z4dple(P`7zkF3>V9-=?BpsKHUr`Q;Wi+Ly9vf=#uY197w?~2p?D~p{9K{2l7+)RP~ z{}S-)0UfI)_Gv=TvbnTRE6OKBfMjB@#cE4z!+?fjd7xX33j!N9Sl&rRu~_V{7{GQ; zn`9L#Zfc{r)`-KcJPHTs8&u_@3b(#1n?l&x0}*1h4PNVU}sp2nM1 zxDl@)JR9sTuq8OwrLHN!8s`I^?7VQ# zMV$A^XQ8t&vi8DZ17R-_*_g>?gpp-fvU_^Fa5lkt-o%d94?)65@nB4ZZ zP%sT63P`74v{2{rA2vMFrpFKL;zQPoKCU$f@t_^LF*Zixi_OETL&G{7$~Bg`T&2m4 zkP?C|T)9t<4o0c0wcRLHeE6MV_GI&@ykTNLmHr?tW{@0qt>^mEnA5PN%AotF;Ujf7 zHdm|zBkZPn{57nwvI!`O=3I)To9x4$(Ed?Q!%`>301U+}fM}+n6dKe-%4Mis;z6QM zj1cyEYIlmeZk**v`>7OK3Fv-_u%H-vide_yQq9!81x3LQl%&o=HPYIN65-^OUCy$| zKI~Lu5FHIp3xP_q)Kq9BtwJ_w8)ox}HDaOCNeH%=(NXHuX6`VZfqvYD=Il(0ao1$V zoYQ#v0)>-QL~#$yi%W@K%DVu0`x<$J8&8U?3mVUZ>VD)G2ryd;qoP!yNPgN(D**Q% z=$T|K;AlS9U{81iB4WbZ;#cOS`qbSh6Do7ig|b%sDt=wg{PZQv!5re6XiIXk1Z`%7 z*~3)^T1+4o=ut$VT6RkYbq@0qzt-JQeacXRN*9DjKJX}X;Qeokf}#05pq2w zza7fj<>Ke%xL0wy>-#KFAebF1see-&p}l9|fS{%55C#fXrk35Do=qZZK;A6*ts+K8 zV;TaDu_TZjv{8-NDH})}q5Z*XFVR+9Gl)mAk{k0xTU6@L%#X*j%S4m78{Z&OM8Li0 zNjA1@6V-78pS-C2HZ*r72rzKO!DbHQGXQD6j>k^90G!faJH@x3a)KGlYp8I&ux!&N zrGm<*evu2_mxK2d{Q`YA!C4fBK}4>0L%_-hKSyOfUM4Ea9_L*N%DcQdZ!X?FrC+>U z{yWMnDl4lyz{Vo-MRWZdeU@S`NBIqW34|?GmLJ%(XviJl&R;#oB0nhSeI1WsTdrh~ zI3_AtCsYvY6Qy*oWkB?7q4h1v}BbNVqhA%WvAH; zju~(bj@<gqqX5uZ60=nPjIjP5^tUT5AD#? z8TAbeq#l?kTR8o5)u2Q@+C`76sk2Eq!Hf9!3ke-5aCi@@!p1V2;%s+!u6a4vXI*w- z1gLV_l3k``5`^)Ft(Zdm!p`cp;AA*u{NrY?7O5R`vp06_(LS|>m-)nrn;x)nGzK`v z4T)cAiGubgr|a0GwnZ zHWGVWxKKHe0nC|O5=`YeCp9n*uvJt96)G0l#Ujc~6LGBgJByO~l7XGeBHchI_-N=K z0N^@PL`GB~5QZM|6ozRQCBDFy7~Om3EZtqMeFE{kQTOt9YY#3pUypGMaYKWdeQ2A+h89t4n zJBtGj@D%MS)zyjL_!V|1d*HRw^?hxRiZ{hs{J#09t?&BMf3dYB zhv~c%=aAT71AXCD|lbA0Kc1!FT3 zd}I2&*k@MxROT};y;;r^OT|k`9rAP2^3#*TMn86M*Z9cclb$=VX-nUB`Gd#aKj`VC zz0tpxKRtK3I9h!t8(NmpCAr(Ap`$Mxm|^hx4fuMmK|RT}Bx)zdM_uFS#(&p6=p#3N zv8#6WJ*oWQ*cDtdFyO)#jRk#5HKvt5oCS(<)ao2(x{r)Jguq`idH z)VB_Tr+vXw@+p=BFU{;@o$(}aX^h|2P&U$%({JsnP5hYN=Ok!9!Aeik^`=#8`saG8 zzwr6}D%K1dz;;MRvhk;Ouz>}uD~flbeH;{DoBNs%%BWTy07tqXQ8XWHsUv8Ka1uks z$QTxxjM_SWgKfdaqH?JE!REd!UhF!?!}WtT@$m$hn+qEx0kb z!*5l;R;NIsm=fp!hxj%u6qRBoqbIchZcG+A64nh;z7A2)cb_u_Er5GVqr$al(M%SD{#Fqb0zn^O((j z#U)m9OuxbhgSP~>fw#cpJ0-67u&PG96<>q5%(0Vw3Er|GoA@2Pb>gLD8oU+xJB4~% z-m(}9^oNKL2?QUcgDX&B`9^THEe>z`K=fwM6K@@>m4ykt%Rfe7qba}sbPdcc1aH}f zjzj3EX+}Dj^1bo}T9>!!sEHx!m#ITaM~EwI59a@)eBp>P>Y!RI(&nPiSxiy6{$_qb zecyD@Lz%*~DRh)Bw$zek`??=o_{($bzOijvA-nU%P z*g+3%iUq|ql#%6dqy%I9C!M1D8vpgWSY+w<$8z(M-;Yok*jJ1_OD_T2;@l9-*12ZE zYL|}}1OQy*%^p5D*Oz)f&bdDu@D?3%pOTw0SQ&wpw<53k${b~(xazjJiwJN16bwc1bkdwO5(rI++H zT|N1*V&z{N{JF@JwU4ltq?iJan5wzTOgJw7Rp5aQhg8-@jn@iTGic1Z2>JDqrh*1o z^NcOTL@+FYm=q}o_Tu=&wtp|%KU@rx|MubmuljA{Z|s@~#25Z>0ME7G zHd6ULSs&$u@-oVwXIiHJTf!X0Mk{t@ANEyf2`kY~vgo+;mw7@(Y zeE`xg2>rwleT({rANqsoo#(N37i6+Plu&mwt|%TNj*-B-Fz1t$j&#~{q6{}j!!CLd zdAB55!BJb7IzF*q_mSeQFWLB?#elg(ircYK;th4J=4i`(qoNBVPp?@qzeGgwFL`Ty z$o!2@)tpYZ+0vDa(2xbRZ;YFMsIS#7Y42jb7->qUuH4eum4UaX6K}%KQ{qWj8CT7m zS1BFIXO?gYPYBh*EQrOWg(e`Bct)@%Lqk*M>34DdV6(_Ik3{hhOu2eB=N8`=?gc0Wtgvj$XQc*Rt(YH#MRk zFEqD9>w?`Heo!?#cbeP%j+q_mWwPj}Y{ffolkIuPE;Kh(r#_I6P~LM?*UbLb(MFl_&soGX763f1OFS%2 zObDBRojX~sfsy5NVAX(Au<5R&rVxM*#U})~P{d6WuKf^klklT+L%eXU;^T#DGoGpV zCP_=U2e@$8kjWb#e@TP4lLiZ@HmLD+Uj;g^oODUr=;SH+NhD-H{ud8q->AJD z?dB?Fx=-%xin`~O3v(Qg^543HSjIds-#Dl4B9_YNDxP?R?U!uoE8-LJvAV0SMA`2c z2DUU!D=mKzc^lt;5Nk6(Ve{>%PNyZ3C` z&kJ2@2Vzp$Zk#)JLx1C@{2QaPrvXXIHUFr%ExVbjiDZ* zUKWUf$`P}lv`%+ph)8ImNt@!waNennJpb939=jg7CuCD#mp&fd8!pu^p1NQSJ%=&h^*qsdPVd!z$cQx*CmzX|EkWC-?jmQH z20G~N(g}&;D@ai;Q6oiMx#QPEb?|!Iy_V8eF!u^nSjOaUiYxVpQ z!TQ#K4*652_lXY@o!I+?MElJYvwNCSds`OxiK?cloIF{@?uigpCk&P-zW4@<8nfmLW^=RT_I!#LueejN zlx8lbJ;Z(zRyVsaJ89?SBIG{!Ms372(=-=j{XG-~@}_ohGv{u;|C4rdGbeApceNwz z!&TbQKX)_wKXdoLWA~r&Urhr0BlM3NSA&-NAFAPR*2!N~kpG`n63I5y(*U)-+253g z8!0WocJl1B;5fE$qaXUw5oCq{k-Vg+OE#ReLNQO3*uczQ9s#3s7M0|m$apb-Y(ZL5 zlE=>cf~DxJc+)Po!-&ZSx_BSoPYdyesR?Nfoa~3DZB5#a~*oA zvNE9kh3ZshKfQv}K4B%?vDu&gInf($1e(UOiJsW-alz-E6*hy|tyB7_ck zwj?4nOe3-VXJpKb%SZ~#o@N=Ee@GHix+dt!{QfWhU&vq?c_~34q$+nJr6eCb6|qLb&;LZK2lO;{H;*xMNoM0OTm5QF@DnCgmF1T z`)JzX39}yZvY7q1mW&)2$hS8#R*8d7 z6&w_v8mxVESKT*dlP8ytvb!$$1)RJ5KD)$39AAnx_;|)XCi(Ub6x$Ry_(np{i=*I- zWPYMiwpC&p;cPGoPR~5$nL$0fswy{U4H!n3V2L@a-_&QuqhdVFe$`Yl(+^FY^^lKh z4tT6&1R0?T&uzeS26>#5{B+eUS--#=9L`16t|anrN_!d=TfBJx*1eN@jo3E@wLE_D zKeqCrF|uCUv3q)pwK4sNqmGlreZ5gU<}nvp0NT(lOkZLEK^BMLm$z#~WPEWpq`=#? zqq<4bq%xbDkmaVv#8&Q=u*L({4R~I{h;=(y(VU3-GeG`f)LacP%8f$>PB23c0ifA4 zyT7LwJo&W`d?vJ%abPspkmQ48dZV> zjnxzbokk5V8rp$6(aW>{_2Gx*Pr!&4vX_6Hj_Q{?cL3sM^-S?P+0 z)L51fRSXVU{s9DD9#oG1ABJQb6_Zdqs8L(Lfxen)%E^sxAKj&`DLFQn1+?&qYFpj0 zOLeST-NL6jI4jDO?4K2IKI>IPE0f05OOEqbPm=M{^+_?B@1F_WV1v;AMjTVOy;)Ry zX%;D}x$IoGh-&sBH4WpjY>6sYNP^2cz|qnlsrAO5^9G4wX^XDf9BmuPW!j8ycC za5b?Xk zK%9bG!W!vg$)O)z0B_qleRyIL(p4=cAr$|#(D(#ZOOIE^Aiz~M&bDpITCve$m-vh& zup;pUOe&v=ZEPw(x98BqfqM=;au^?f{^X%YjDBx|2Bf})F|G@&k8*srLHv+1Z#Hx$ ztSCXl4-X@)8Naxdsc4a0nhs@0R>t&5?i|%ZWn0Csel2YyM!z+BWJZ(^9EPgZ7Ezts z_vq1{UW+p3qJF=<`)j_ujAU6e9N zjcV7k=h(en(u@}=S$oIy>XAeXJv2UJ%#^stptb!KdNgbT#lOTshjNFZq}`uD)W4K^ zssXcJ>b#-s7~+-zw$w*Ca50_->(3*e8lIEB3VrmLe6MMr81L%^^10uuDf)5e`;T4k z_2cv&4itvIOZnes8J1M#ZK)C85I-8b$R!|w* zed0$Kzo5^^*vc}7e;S!Q$o`vdB?}O~Xyr46f77Yc&uN_=V2f%6yQf(Tu~g$?RddE` zQ~LHvN$Jxk^}5}j)45yb-o4Gobp~+Ns0(wb)cFI6c3McHU*pK>)C?$nP>x+eH*wyq zTxBAb^ZWA4$~Kfu%Fnzbv2EMEci#2nQ_8Nr*X?T0iM@M`AHQbeTr3!rb)EnC_Js?d zkaC9VUF+|J)c`3bJhT;BZhE7ltC;EY&qTfW=87y*`TmhZkMM_O+lRcOa?F*o9KQyP z$>$KKu(g=Eo)a?!rJ~^a^ruC4gL&bEyY(g_^V-9%6HYld0Cbh zRt6e4qrg>@8S8qI<5hdupik#8t3Jpm>7*Ehh`rI6uNnBjV2|q-@KdoNE?+^TlCZ>M zj-(kK?7noAJwi|`p;l=wH8dEsBa(y`3P*1aO~mE}=kdz&u{k7+nnJ9bD)q^n_!cu~ z_Q=V}>G^|rdr)4h{J8jjiR0(qF=p_%9$6i2`LE^Wh2|#p9XqyfQtq2s)3URt892Xa zi;9m=6Fb@Xw3a=yg*~QcesEAX|A0B;OUtMA$;iv;GVMeCo$UCy@)HZ3wYt9}eWo^H9Z*fOv1w^dWM+2?IPuj(Lk zfJaD>A3}3LfAYZIdn`0ug5qbaLuQ>#b!1%)5Ls7A^TWci;p0JiGm{<(HtR(NYs*Ux z;N+wHSNL6yS|OGk5bv=gujuzHyIAJr_t4A5>yyvfuY)hHxxoM@U#z))s@cRnynGOW z#6vat0CpDsNbS5tKXR>FF8>0gn=7(?U$FCNyM9vY|D=$SC&0GM10Ja%@zTCfU?VedDtfC&u8r44cmzSXOOfDt%$Eu31CvX?dDTE=J0`=BF&xp3H-r;w@^NH^SIm z#Tl9KH@bS`D%Ow@X3wJjUxgE^aIAU7Gi4MTWL_z(qF%^?}mS@%!Zqn3u84&U?TX?*uYLW;6qoxQ+ zYzQj@Gn^p?9g0vQMM~oF66+4m{9YqA*v0xoEJ%NylqALUVf_fKJHoFIyn*yf0}Tz- zd`MX}-jpP}7J3U!x0Hio(gPcCz-C~nvMDE7UadeNnmd{z!c8BFe@Z-pp$VHbYH>|l zU82N_@kAU0@ZosNeQ#9y^X_>lv$8E1$TqwA<&~pPb(j|96*by&F(PQ$Snz zk8t3E3eNpGAaP0Z^JG&nZgL35CR2OMS@l!2H@OFeio^a9`m&sLyry)mJFR9ogzHKT z6m!J9e{qi;-0Q7|%bUwFYLqDkdYjaYIz;#HY<#JKZ|T48(0~6IdyuVnUrKsw#LtS^ z90Z?h4873z$nZ=?B&ea%%TF4Z;7tzw6z3u)LLtOaPW-Mmaicr+>(^;?TpMw+;d*CS zVE68UVe-E@s88=Fwtw;IXJ2mL)dxSjwtxBAr(bM;qIaL#)XdB;*jt}xW@Tl5E>gcB zw*%WJSXhYotNi9>F*8GmSQ!n3|x4juFsJBG;qjyWp! z7W-pu+{Ca9jtOZ(IwqeMER9=ynX-*{)9-xr{*59~Y4P;RnTT_H=P5W;WwB4s9QjTh z&t)0U>|rr%cJ4P*kF4plZ4Q-Lzms%TXPF7<8Z2gTVOJ7uT6%&lnJMA=%X|gOWY-*D zqf7+MU2zIaOs^^lD3kTb6{nxsgIUFfCS`U2o+D5?4J*J4O&*96Q-COnPax+%OQQ0S zScT&V;HrGQLO-J@3!lu#sdlU8u`BvVlldAweZZ4S!HnVhJUi>L%lkzF36ALo_#K3T~=)Mw6A zOpccZJ;@&#(9Q9w{pzAaYkqmE<~cSgTkKtFKaPEQ1WLkMkGkFqy9m}K6aLb40p|qS zJuXR0CF04zQVA;nSur=^4pz(&d#AX1_VwFZJP|a|En=O0yuL=lZz0c3FyLd^qQO81 zl^U*!unZcVNpnK?X$;&)!mgX_l%9Tv2KCNTRdcri!`xR&w?^Gw(%l9!tPmbRoj`XZ za5q(|+m7zEUtu=bfx+3qm+?EId=2sw+ufnRrg$va-HRoNb@SO*`sa68TpXF|=2mRs zZnjX|%Q_}2(h6*0kx$q^VO_evFsx=ew(}gS7GHA1GCab?J>L(ql&iDk1juL?m(T_! z&gd)hlubgg!L}nOtFQ^vfe)A{*q~`qn>QLxLZa%y&glzEQZjDEu21IFCr5P77%_2b z(ZHcu2w;4rL_fxtFMaYd<8LYdv%>zuZ@ytF?A9)>;xf`-{FMEvXGAOTIW9_l9Ifoe z-kPIqa<;y-A4CcG{7(HK@OgY-eqIc-$~H@+tdiwz8Et zKf7j$`0Bw!k1gA6KP48mV#)Ik-NPa_)NEy+Or%Z7jd9Tk7eoPIwhqkQ!KL(bNkjPP zr6=%{2ez<&dmegHU&#MCVNV%5pkIyUN&3DdzFZ$Me$PZPfVYg*&+>7sXKE6EqC?vb zFV_5v?QJCr?y_&$w4>(fmyaHLRg7uH4lJ=hwrSU)r-29Qj)x%E3TX!e6e^X4niA6E znf8&Gr~fbaWDkkij&;g>woaWOmQ5%T_gv$qyZ7A9Z_XQ>Zqhh;}K;9+b@=3spS%@6w4e- zl;y1Q0z0wcz>tu+|u-{mKZ(BVr1xRF*rI z&_)b)357p?-+>JxPaAnbEWLZry<+7B)}pxBS>6zdW2C9|f0T=jalefP*R|L-m`%+YWU&ZctLd2;ib2VOfR zzLRvHtAWmm1lB<1&c_IYfUC_4><$Ba4l zIVg-UeM2Iqv|@9_`px>B&0-6iYM^ZJ_-uU|V7=~yg#m^9Gukn4h9hr`9WTLYSZ{}Gy5qk_+Culwi{ZgS_y=0AL z6q)g6Hvg<%sS8)HI9_^V^_n#XuUDNIN4(y=nI)}R(}>;F|54_zjmr$Yh3jw$yGUgc z>&Kl~Ww0Jazd_|S;{KX7DDOl)R)Vz);0NjA&brU!q~p=Ym{eo5HLy0O+{(M+v_vtn znlI6NW%J)1Z%kM*KwM$Nx*e+`BG~-W6$4m`ct{;0d9-=+<{#3JZr<#%T#|Fmc676p zWx?97ZrHSVMwQV)s)6CISwTB&lXWA4DpE>b09oVmMm(x}D(R&whRqp8wEdRDKXZIJ z5m>y#W_A<9*%kIOHMH?PLOeHLvz>_jNJ_*5ZN8aj?$v*!_*+1|{ z{fTT`)SuRnMKf2!YPQ8A0OlhYVsNKuxFdU#+nNL$L)~6=6qW+k*d1?BZ0g(P&$@Jp z@>?{8_JdG<>_m`T=d_QIbrgzNQ@6mb*j#oJ*d{*GybX^SviFg>hko7Qq^zFXyA z?-!39FmM3=#uhhRiUTa<$BCsK@l!hSM{(7C&E8~XqS}r{tupn&#KZvukItNabl`wQ z{NQ@}Ou9Z^HnDWk!nLawEi9c_hU!YTh*UbS>d)5Vy2+5xf3s^VMTN6w?VL5cAa`NA_U(_Yxc`}> z*Z(GE-DejT%$&J>&a#f}ljr5#``k14uXz6K-zBx7ZwH#%$uq*;d$p38v3raE7d53` z7spwTPU79k;@wWHhdADeb(qXL{Ps6V?0B$d)N|r#HuSksH3vsO$A*fhpJVFZrLmzd zXpNdZumE~Q8%18h53skN;AN_$LSP^r&>zCwH7jJ)pMrRIK>NYS#A zudn2o5xMrqQTZn3w_G_(0CGn_9IwMk!HS{2VU@3o~QfpEBH6@a1 zl)ELarUsPwApMXFrABE`N7(Tyce_eYhW3?}l+s8o;w!&u1ea*IO?pYJB-ouEd->cn zQw{?_AVK0mmC7+kAF-{n(uodA#a?=6dfNBwZ{S2)GPOd=#R#uHm3)M5H*(faZpaP2 zzEOTx?whD$rIive0oNX*>`rXKulj?ipYI8-RPNA#2sAdT}t9ySWvxeG!ROmfw|^S|TG^rxru^gP`2z9jgXV&GW^%7fFWBiG7JpC zTDIL$4+ekV2uniS@e`PhAMm>ozVIzJ+CWphsbq@f#5bV48;sBYj&&7lr?XG=Zzb+m zsV4ZL=>q%|@jUq^0vs<%^wHKX)<314(TYuN;ROIY5iHVhkH%(%L~^1aYl5bdVr_;e zvyJT7a$5*&h+A3isY%%byA|5z7wueGv*}ALt1S9*Q_aeqMe}Wi-3De)Iwel>_Iq28 zwiTpgrF89f&-9&(cZ^w^m9=)vj>S8t-_xxt9v9d~H^l*KSFnsj#mB5V96;s#Jt3av z@jys!YLix$aKtq}BPNNHO_5-W#Hyx9uw1s4xBrh=z=%jTiYUy}zQGlC2C_gzyklBN z$1c@_7F<~jCb!%5Y96?UW0T)4={>m;i1nA{N{M3^W-%;=O=J@tUDZ?iwLPfQi}l+v z|0=^3t(=>})3JM9LcsjX?t+2fgxu5^%x&`-kmS702~6f|43C=@vnduhIiSTygO-fc zun_4^X9ag-TXo7H?>TFR8f*B&Xgh{}Z-46N!D+$z;E=RoKkwS}{m4$i{9uTqY+gaZ z`~sz5=-z8j4o>Tlmo{YA&rc2S)T5_gA>Pb2_|Ozqqw;Ny;Kob88*>Ps;DUwn-LL>x zsg|(V^M46zBAa3!0=j%*Z8QbrwCM&I@vRJUCNkw@aK|y<@80$E&`!bZv4Z)91?2^3 zi#SdKQ?LO9 zYgbYKsC^3P=G;wsO6_0wi+e*ULQ`IKZYf18Y?6nx4+Jn`2%JWFp3QC8v8r9Q*Pd{1 zTfI%baEe*S;*5N5V92)935+wy8SPQTpYtKU%J_riEJv*bLvX7^TJn>-#*0Sm{;_vL z5DRf6@m~Hdvfo;V2$ACZpoHE(J~^U@_tanPp0n<)Y!uf}rnCmYr9(>xbJc5(_i<)@ zl5!q9&>ipF@xQK$+7YX-6^qQ95w8Nh&y(nkW6E><(=+-KeaRXAv5bzf=#N#Fez&BR zNn?%s`8@;?%1pJvCIV8@>pZ)=fXI_kQppRqiOoGMP##i*~>el2k~-2@|0 zQ-W>_LraZM$B<*dz&>9UFj%LjMGwJ6kEdD3ufKGtuh+$h6BJ05<*A?5bpZ%&sxnon zOVy=lKWJs17B-IsFh6l!aHv8i!Fd%<-t@yR?w^?uxF>#^KH~Z8fYKXzf}Z2c5y-L` zc3{isBNS)@Gsut5ol|-Xnf4FXQT0@t!JZ0lFqiM&AB|l8xZcFukH#rOUVbZaY6gHP z5mA2QXz864LwRx$BR!FS`YV2hhym;wv8IBZW~VE}8e9)x3o0-$W>m1?U(`2#63VTZ)a@5xHUF8&(Ipmh29Aq-Ez4kEs1rXUEe$9X>NOv;uYkadR39$*sKIdLrX^D3(96w(92dKN z#y)3Xd|X%jF(=pc#%ba2f~1H9EwMBY(#!eUZn9|giH}8;fPe>W48EkU{X2i{5&qZS z;K~hb3HyJ@dlT@eimZRQtM1kb**e|n&IVaKArK(@1|(sN?4T(7z6dA?f-vB)1aK50 zD2fX1xFJSFKtzm+C@#2-`#PcygBvmqE~Ak2t^9wdZg-~>6q)y(?|I(m`2x4^QdOr; zojP^uRMn|dVfq=C;J^txptYsgHxCKsEVMaeS)onI;L|>2i>d~&OFtB47dKq2-YYf= zFZ%>udsq36C>d0ikaS2^7|Swj@IW<<9Y%b1_(O5?fGV)VN+rX01S@}+vrmLqY($w3 zz>mYPe1ca1B>RH%}Wl`ip4AZW+kFyPI<-f`mv)|*Y5T8edYkn1|pt) zrk>V#u*zW7c_Zff{Wv%==Pi{Yxl$x`p$tsF`xgM{BfO_MVhla)V}8r3J!8h!nwRjK zD~5OMSYckuZ?+an@M$xPZg}RIr^OFSME%~{)uYGO53eZC>4<#{*8F?@GtY{j#ZL#G zA>QXUcx};+YC|zU4I7X&Scqb!i3~((^SL_?!!Jk^k6VhY?5tFf!J!-*enqfYY#EO~ z_;h{UdNIFlJ%6cU`0xs|f*-COJ9rpM= z%9p_>0n|UpE+~bhm|6K|XTj}_1M6NmJgnHk-wNidJT0y=zmfT}jdkm_e6xab<}aCL zGG~6+tbqJl`*Z_~!E>3FGg>NR%TV4j_#;6lBArK}tfUlLMJ7M+G}r6MP_G+XF{pk} z#n}4wb8e{LG^ehf-(5SV!sV+_UUF7|_EY$shu6>Xuqonh&z!o$<`gLdiojC@8_hU-KPX7SdKP02kR(5eloGLvtu7F2mT=nqIC?CX%`uf+gvi}~>tv|V)7n*O-1yj=c zlP4{nu}y>?Nm?IT3Q0xF-cG$AdrwQ7PFeb-ViW9paf8^jkG;K(4m~IRvrRg`fg0=i z?z_|F{JAbu?GxR$iEjJYT;u@zxbT2|oQuZgAr^9eL%Hyvp`2+87|Q*j$y})Q9Le7{ z`Lwp6`%Oc-inH0%wKlB-{EtOftXaP&wPUE)uw{}mkE+EoYx-Du&Q~QD9I%kkVn-=H zgA|S3BR1BH8x&Em3~ezlL0y~y7m+1gQou<5Lc_;$3BXl}X9K{MgW|JYY+gN^zejw} z%b}sPn0or_m)3JE8(3H}1R?rCRf_`}hfRD41SFI78=@KqF$v}q>_Fo~A2KqZU`swE%LP9!%^@(Q zbx0UXptG`zRZpq3L4cJX*&x6^5&I;(hRR?BLe7O z$65DZ)@*xb_2HwlS^Hl;5w+FqHZdXZ@;^=dka_Pn?-|5nM)nbNtr5OwKNI_fZ#0UrT$G7@-><&@wnf{%nkHU{*`Qg2b-(UX3hp)~4)9j5&@T_Iw^f~C1 zfw37$xS(f3THAzW7+4-|T+`sb!l4e?I-1ppM$b$Xzh*_c-OOCL8 zl#Q=%Ad`ANs~(y1S;R}Et5l&q{A`2#39KwyChh?`a#>ucM>f-kBT<9KUv(_^4>4+S6>6bbNt3kG54>+75gSXB34w%9I) z+7MzLndUMATV4b9&|gjKV;KxiTyoj%v$0QmI~fN~x^m9#%7lO&nt&Bp>agsWp}HGnN~nH) z*P4&bC;xWWr{+;*FpIeMt-Edz;d(^1cy3Hn*-7)8YM$`LHa6b(FaAQgP^;OLzsf$P zHQa2c;jnC&0k;%l&dc5aTz($l@(#Ye;%9=(;E2AORgF;(pXBk?=GR|r6Zb0)vqw4e zRg1eVxXXd>Uyy@GT5bVHCasw1phiO7YP`&;Y5CW^X=-fQR`ZxL;JLe2{mp#hFZ{2* z6N~Q}&$2g)NOl*0p+acp<@N09&$qF0?89pD;@GCLAH-Aj;`8di^S9WfH_%2D+xud< z_9615xzR*e`#2~sGRC&@qCMc4;rHU0$oKgJ-`@2td)6#pqYU)TM^+8YHh~#1_Ksoa zUBWKELp?0MjV9^DzwbZE0>+ZfWkV&erzJ{fkfe8m&8D zAa^Q0)eK)#*hhGR3B$>KFJ8<`c$tZKt&Fgw(}UQYMWq$TT)F(T-YV*xJ49SCziNj_ z+#x;8g7y-Bqd#nDHu?9Lmcdgb&4a_Iul|nTSA{gk@RzN)$X_@=SxJ)rk!Rn=2efg& z>)ls*b}NcV@{Y;~+hsR#?(cZerQBKH9ZP*(Y0m&rGCE3yPn2Ka+!ZNU*|$rD6We{AaG7`R?CUu!<8yLM1ig!)ob6u2?{ zOdrWfiCf$9zvO$B#;|Ay_=g9}SRD@qSOd^bu%|^0_+Q*{(Cp8jwD`X%LjBR=e|YiT ze~?X|*k8#$SN_l9nSSrY*ImcIA^w+6 zfJG`AK*e8nu&>YnhLaay;=9(o9zvxvyeyMRAc`WrShp=pz|*oej=24I{Vgl)ww}T3 zDA8|uG^Xk5vw1aEz9eox)316kVbsI|)iF2he(z&pH#Ah{Jzi8Ux z%ft&u_HS4`ZP7ez7CJb+_TF#Ln>KC5ec$#|J(n+@ws=Fs5%I!2`S3aG@qYhrAE=!+ z^}KKItDP!wUBCvb7bxrHnyiBrYgl{X_nL39T|AFpDc)fNpKoMc#lGi>b~oB=>S`PZ zsnYCbAx#-#86CFs>=ZlY+sE%0JH<}Em1mltnv?6<`)sMWhVo$dDWAx5J88xhV*ng} z$CNJOdz`UE$JdLK>Tz+>I`oc&F5*M$iso{*+e^ou;Rr=Kc`61c%8tchPe0NVoli%$ zh%&BH6_e$um2woU<;x0uSCeA0>AUSy8U7*qJ{gWYx;MYbAJK=(b3Z&f=3OuwBY(3? zV1tS&A^K%cTse5~vSoAy9`vD$hs__p>eQ;?^M}}(tbr1N@uQJ`dM<+7 zq^CZpkk1pNPwp2#UazAg;r!?3sk)P|21kL~v<8E@wmAOt#*K&hDAr(Z=NmU}q`I8m zJXN_W7>{fb5tl!0Mc}Iu-`p%>a2a-H~L|9)<8`~LmrDOR^`9jj%lVPL)jZ$Ihq3^O6WV%tfW?nD{#VR2J~eeh$DJ6fd!3$m%SB-$NyL2INXsc_tvCf7)5v9>do z=V_vn=IMGeIKHB>0H#ji-QHSTEx}5RwH_A-STwJPD9RjK)_79*_U~U=U%ztyex^Rj zIzG92%@a@5*4NiQ@x+?dPl~=%`}LhVwcoaF{qWm&Dj)t}->FmTrcSM!GPN&X3;=x* zbN`y!2G+4*)$09L%KfWXHHeQIYS+*^lJuK`B<8NEeF3B|{}qX+^fSW%i9k}>Thp6V zBFySGitXxHmcpyVrB<9>%1oug&y!RoX-b9AH}X21M)(g-+h+jhYQ%~0^EKv@G8|X) zx{caZ8_f}%jD2mpn&&GOctpLDz{9z073N~p{3GT+tn>(vvBELm3_Px8jT^DWr@c9X z!r7z3rZgIJWP8MnY$E9DUoNLbGjd)Qm*-%QDiH@>9X`Ffv~zNNv>p~S%V8Hb&7Qf6 zE9~hDdzDlUMhc_W7Iz^ju;B1 ze`l^TP0=?9mtV@daE*vYd!pa6-=UH%i(Kst$Tf5wIUGlr%@bKm_yuG6@Fk+7*kIQ1 z2408O&{x?mIwHW_xrBYxU%G?=&);FQ1z|yIkiNpwy!gEX$&T@=0P1bN zn0f_sq@Xm?wHt;yA$c5u_JS2h5H^g{`Cd5;3x#2Hu-6^NLrS>sms8(u;ET;V^`A{& z(ITvxh!xl)W*uLA9evhazF&O5Xthl)z8LR6nQ1(de{R+x!WDdpm6!bvOBcv6?Ib0cO>BWvBkHb}%R)7b*!V0=GOYg~wx}(PpdG>}pYa!2}aenW6 zXq?}B4ow@H*YCyu-+a#w!Qc4*;5iij{|3)_?9r`L)B5O#|&m2MqYN1N2|-KrjA(?j4kwImpWfTCbwUx*xG_?8#QI{;#cX z>^g6g7ynQ7`K`F0{?^CV05Z=K)^fCOaHyzUpi%ay*F8C_z80Q0k2n8 zyB z-kVds1H5Mc5IBDFpc{Z(WHwv)-qtc$ie3YD7ljbTVN9VX7QXk?DBmwixbe_U8%XMI zXuKK{7J}IP>8ewB{}(J^#bh(eKO*Z=-&e|b_J|na zyI+jZdQB52rit`03>YwpGQoiGSFFjj^Pn7SM zH-D`jQR%AZzmqqErL$!q8z@kcso29&>#wYMa_ zu)|Syi1_8PDEb_6li5++#5#)$*dxj~wo{B);HO!IK~-^ z6?=s{*uq0w8@6o~zOgG!-*II#JIeEzV*VtqHoy1%(@Mt{Lhn$Z#iBxX9Xe#J`(+{V z42=<7fVob>j3ba493YF?!j+p|+xphVt;V|Jz6Zo8;Sw{jr}TTCr4$@*i%W3~mi`N4 zow1HM*u{<&zOCCDwh}5%9?O>UC}Em!i4MNm$8C&nkY!j0JptBu8IC+=7P31*ie$jvhWb!Dl$x8 z*yV@LvHX-)4vo=sA2BBz>wX=2C~T3RMiOTWzFf258?e}c654kj`h|uafzu^(=iAlXw_Ef)V>@gl;ek1yC=|Q-_-gY$L5-wx{ zKr>=wn&D6;l=q#%62w3E|9PHq^{Ja~8+q}ryRQGcG2JTvedf==XT2;xjmjo8G?+h! zS$gkw^Ekq+@;NY;m6jH?+|Ta=Oz|~yHY}Zo;w`^*6ky))`KfCIFntmiDkElOWT`yv zw8A(82eQc$Zh19eAE-M`g53A5bS`@WJnEnD^)X;-4%5^hP1?`1|#s_sH9tu`4hEmI#anC`Xc!>w|OD|Fr0&TG%^QDgTs1WNarc@Qn)jwvz6r`%M3m`aw~fyG2&TiqGbSzK09GJe7*6ULX|&wAKi z_dSdMzOL?j@y++YC$E*mt&&h$Q6EfIS4Z+&x80_vDc8m5QR`4f#WqI#s=mp`q8<`x z*DLMcpxxHe^rjomyRZhk7y)Btr??cuxNl!2Pmc7n`JVdvd+voV%aNadwT`oqBX>M9 z5`T~E82RXD@4olhXYalHnQsSwJLigQ9~s>6=G8d+@qYA;mhCL9pxNjcjw~Djjsuvy zIKbQMfp3JYR6WL>$`)4a{xcoz^!lH7S3D`cO=D$GvWztGG+*$b`1HXCS*EgY`V{fB zc~U$*W%_pYs|nL)9b7YI%3NPHyXEVz#U)=OPiDJObX8ZQzoFR=InIQAcLm?N-4_F+ zQ+CRn$nQlw#kK|W>^EuOfDW|E_cuC#$2!$23I|nXU~?gz5tD&u8?m6at{Pk;ab1jSF|Mm|-GXZyu6?*(!u0_z|CyChII}VervUcSY{vnz5f@&PPz^4a zWx3$C(`6fgYYeX0xR&BthwD~c58-+e*DJU_#uZ5?Upi0w zb{-~Qo-~{Jiq2cQ`M$!0TU&aUv8vYeE(B2t<--57^d{W)+uFZ{tDCIBEYx6Dpa!#0 zgITD-EYx5YYA_2mn1ve5LJel22D4CuS*XD*)L<5BFbg%<0EdCFVt~uNv(#mKctjw= zvb)5CUW|G#M!grK-iuN1#i;jU)O#`Ny%_agEbBcP_ui;?;sEPu zzb)6|s$4+N4M5KY^jtvC1@v4%&js{cK+gsATtLqS^jtvC1@v4%&js}TwvW!gB#mXQS^0cuvN10eOc!E9Yqeudvz0G_^*Pp`BT= z^$;|opdRL2xKMdAa`8ups@IMlx4iG7g_llS4;S_0#}zHTbkf?M_dGZ24_WaRWz~cY zcX*Pv=OqsteBRLYJt}%s#ieeJcdc7^{sQ7hwN)R`0mS~PHAkkR*hGNT|FaxPxIxfE zDkbBd_10M=Njf?;Doi>ek{HXtJ^K%O2QN;Pr@n!lHl!7wOQrE=#ZN3U{;wN0>=S+d zu!@F>)x5vCf5W@)QYX>6PcCPJTGvL3zcx}(8(G+VN`=Y#KU*^mwl4mbC#6Oq+BH06 zSp9t=SgjE4x)ANU5be4U?Ya={x)ANU5be4U?Ya={x)ANU5be4U?fNV=+tM#IKy7L1 zFEXH|5Ro#@p}&aJr3tiL=xAxY)Mn46*4Y-`Q_NGUQg*%h{(eeo z%pbAHr# z0=7*-ouoi>Oo8T@0?jc6nqvwy#}sIeDbO5KpgE>Mb4-Een1X5t^L&Yif8+9Nj$Uw* zH^50=aFQ3ClW5-QpcixfVzG-;7p1W_l;W6{;Pgpxz4GbLv zq}#qjQ^E0xnYe5?Ymo#bowcarJ?hi{j_yyR2%PfxX|Mmv7@z?IxIjOj_Q(Bvd)Q}D zJ+}XYy2J7lR@~2RJa8$0Slsj+J747gVO_9IJ@KVfy0N!b>(5EZJbK}zNf+W0FR7P2 zap#@;W~)E?^&&uAt+vuD{XZCBAsPllZZJBv!fckAI=H32J%|b}2Sc!hE68%~w z*rF2sS|$3mO7v@$=+`RIuT`R7t3@!u?%gX zEYJqZ5K@LVPzI(cLmMbV8z@5?C_@`4LmMbV8z@5?C_@`4LmMaq@U!q?Dta&?FRApo z7#z`aE}n}~26`_3BiU#TY)VVWA|$|jG^ORVOg|)Zo(s#djTcSnivBFTcG%t2pFR8S z;o?g_9y)Fu^>u&9Z05ChWX5e87TM#`n{L=^e)Ea=#mV+g9XD<&T{O07En~A#>PmKd zYZ)6l$JGhPLQ?TNffOZ}XrSj3JhyP*f2aTZ@AP{TN*=f*FTf?F0_TBC^1vl|;F3IW zNglW)4_uN5F3AIz#PObs!e75{f6H4bYM~CGjITMRHI?L~qHK4{R zEWx?jbK$r*?%MJ6qPs<RF7-6OWXBHTLke>tY>o`W96g1( za1J?a%NUOrHoo6jMPW3*&*QgZet*?3EAh$>!yd>U2!ox;VOH%ARBSzv-_0^V>s(6Y ziNyqYDGOMJ+1t7Z3Hk#bl*WZLgol-e)(iaqTBVW55rPs)1vt(Hj-)O6(_u=SteY%+ zaYpu5M7YGfMd{G;i~NB9T;Ly)j%;Q87nS9p|2i|V+NOMD2ZyQh!jP-S(@W^zGl3Gy zGE%zGGEzEV8Tv1nu2m_m>aeLO>t!gbW$S18aPXJ3O^LT|)#kH%#l%yBe$^fHYu3{* z)wznYUxu=`f)i4DqCzMIK#AW4CwWBjR&cG5$MZMLcVYGA-qA#EJS{$wJZ8lK{9v3p zVtW(Ji!6R>4Tl|8+KY@(IK*?U;RNFZ;WVEho(1n&dBGA6OJ48s*OBs)9gSF}MPB|m zbNq26KK?kMd*e-kIEp_lH0;ToDev{I6*ilDcT;|iNpsBopESIybHfX^EBPO zgJ?tTFC?5=8NyxK+@|lS6-wHK!a%EtqxxY-0zmw6Lf}x#@yBTaB;|l?&%gz80KDVk zxm&@b>ZOg}O1f}YFdPv4;V6q5*SN`&BeKo=(?eRoD|U4NfRrV{aHJ1}2LKSBBvWL0 zY5fN|Kq^=zCYA|X1)4~vIWr!hNy_-+fi}cAQVvOYuz04mbD|E#98LtHxT-~IKy4G3 z+8xDZhlhjU7N@C~`VnY}EAh0TS`?+2K}1{Pwd5}`ZOPwX0g}ys69>c(!C{UXM-`9g zEwBSP$e2_xKMwwQ7C(cBta!3!CD-RdUW4t`OG#u0_&yj9&`73(^JP3)OH#HIJXw#j zOpx4&nIU6Rbr1K$Z2XpJdS+arE42ea4Mc6anOa^;+#sG*a_L$feMb<{mUveF$h~d; zevb0fv<(ijT&-}B(VMbfX?;_&@=17VifH{Y(^BI{uNXl9@V989-V5C*|LAW7!QcQpTfY~aZJ6QL?lW3}* zCLRI2v*KyVD~q4hKfu$fDN81w9nX;bL-6#=FqFrVJ zejEWYPD(fuwSFYe$eZ#dITDBoBbX3G&%jg0F7`w9{Ua37mbiXADQ+PD5Jdfa1Uiw; z7RfxT{BeB$R@s<|rcJlV_T;B4@n|4EK@G@VfAj#GO7dFr*W$lmngE3Z^1{#Bk}8%I z^0)6Z@nw$y7dKgd!k zPY6qrr!6g&NGPRBXxXfE$WQid$j>TWpns!Q+d}#?XipT8|ERu5(g%g%leoS7!rlu#btN|%Qo zp9VcXEv^SUxs;tm8A*2tq(bl!Y|9Y8>*yGNrvS^JBSzwD2f&^Snr-TdP>OAiA)t1pTp2}b-${gBmAwdYZIUvJa} z!IXVrATDGMcJ3}w=8A;`R%-exM260HE$uV*2?SxBnZLL_+}$~gE@!Y7`B z&K|&p+6(I2k{Z;HqC^LPOJk*H%l&fSa%|&L=AeM6F9J%U4`LejO{B++2HXHH z78eoh{brFeN2H1?c&^01u@YIJ0MI*$&Y+(xtHd0X@oS#E3p=14^7SIFkaY3)Y5usf z)x|NQHQQh*=T^@q>Eeg$$AushcL4T&#P)64%HL4j>ZJfKwrhtPzs1;q>RjsMR#_!g zq)slyHY1uS&o=g?vLY_OMAo~XE>^v}*m{dDgomZ&OS-TFGOol0yaYVJP57nwMDeZQ zDCOCvo556?hjM7q$7QVs=t8xG8V#^a*eXdIRI21dNk{UfD%*iY9q_nCAL0Vy#h@yU zF}dV3&|U-eF*>&BL%%XV)S5*p$wPi(H6AA*eom5f@XuLT+~?<|fSxM}=VvG7Stz@H z9zmXgSqDi6$`ROHA;~AzDAJ*=rejkqzLI##QMg4xXcqpolIp}-*uHDgvGKTMFAIRo zQ?`+oJmWwYwC8|^XBI(!lU(oXjn*Z3!QTc^E^7Ux5z{|N0BVH9`{3Uo^Gh84@wH$5lw(2_Buh*1nXMLGEgWeK}gLE z@Te3e5@k!e`FSP)Clv1>jr}+T2yHbcIZ_M|Tn+Y%)TSJ;sPxM|^cA2R>Q-{G)!wBD zl(Gl?EHzNJLGqZdx8xF3IJLb%F#~N6GEed}mS#~vOk|^c@YIDpyko|JSLQ#!*p3y; zd>gI4Q_g`{@h#J0vMi1tH%6>wOSbQz_$!t{(jdAeJEWYkcndS-Ko+J3F1BRMxUD<3 zquy35Q!e*izg?tTn#y{DJCUD%K2^gwV;P5nz%atVc%Gxb z599}~z$}hGL&`5W4@+7A-j`ECD;?^~9>~v1=g*Mxv(i~(7VsI3f;JLafG!4;BdvJ^ znJ?m4(v(KW!{zW?mX|QMaBqP{JvaUZU;&kp7!7$P)3wlXA)ZE6)}dpr<^ zw);vT2!3mvpi70Z3iUQ!$tJd-v+>Y=r^@zAJ(jhziTny?V5OupmOkmEf$ns24U7rn zF#3RQ+WJoO=*ek`hBtGL)%Av;}QIcS3kqwsRnvxCGxja z{ua}BRw{qxcPdLqDvO?teazN+!S9!)56)vBgq`RkY@=-Bu+MdxZ6@}*&a*AVe%C+S zR$|ZVHMVQ9?{$-HGxomTjk$aro8&<`1M2|Tl9AyJximb}(Mk^7Jb2D;b1y|&CFIIS zoVbwde;fY73on40_-mT_;)|@V<)U{4A~bMW@y`8MU-7;F@1*tjuahVLCDQ(7{hjpR z+2{ZI7yAqs?)1(2e$HRX$E2(~>PK4mkj#5~+InG0wXhiUF3t$t1J96n#n^lkyyOTE zejPHvkr{C~^9s8ttW@AWNf_UW7UIye_!E%_#Nk7UD_=Bs%V^+71nxUB7VI|qvoT<_ z#sT0!cKv7Udip(bWKlmd9X`8CUY6EyudddS1_V5o9*!Pj|W25$$S}FDk z-(X(=eCcCIzFCy7l`BI0a@h}0=IMghV_A0f;4hRV_K-9*tNQymFH0f+$Z3uSJ;|r1 zp8f)1*dr7SLvN=6ACl56S1WCNWr3blr}b#O;EcGmr`_gl*>nz%^)WdtHG$DD%RQ#d zJ9f->!?6Wyq%x0<6!pFvME%%f$CNAZdA)Ll{Ip)wQ@H~9gPyAyc0OTW&r;x}2fnxB zU5Pz8vuXPeC2AZ+D7U?2IT!3&u*bU23YWH-wz&XT{C(Fh@#&sDaQzv)OQ=_9WsQeh zUpDxg3Z>`SWdCo;OW7u=J<`QmnqaUww*B^>zEiVis9!#K&mNWuSET8C_V{kw8T@0Z zd;EVCYW-0h>yKqV68vjY^`x~jo$~2U(RGi=-6eAOh^{+BU-|x)px=8&67iYjFnb8? z=q!XNYz&Hr4ONQ8wU9hGf4Gpv!9fBpI4XgcM0t6NW&IyL%C2fMS1D;tO~=#&OPhM% zt0wzCzn8BR%kDiYtBhTEl&|!O<@oOVoM}B)HuYvJ)n}TH`IJ<1m5;4CdKA3(2Y5hE zYLuRM=j0gfVtLY*ETFqf@ZCLW`o z$Cod|k9=Led|9*Y%A#cj>e?0g1!6B^BME@*qo>D;Hx;emPc1Jfz()dBw5fOnODVdt zpmCj^q!#8cD>9EE+k8T!NHim%@Ado@%kv41B4Jtx02PA9PAtn`X<@NXjwl0=Zb<`^Fy#8?8V-qq7|&eihP6sbHbts&{yXB`5AK8=2rKpWH$i+iIBU> zDYxSDsi<4pn;8g$+@;f-EV-+=d?ywtr`9U*zQz8y1m`yWedRiWLosO!r=D~h|Ji~Q z2$Q3gGzZCWeHujJLllce@EG&t0*XuhfUZ2EVRwwbAK*VV>dB{%S@;CQTJ-}w+WcVw z|7k4*-AI321}Q4{U|RUFG<8eUWvouUL1IKWwS)r}cAYW}{$JFoEXFrN{7X4z#SX!Y zaMRHbrJ;}Fz%7jFv_;k5NdaCk485iYUSM{sFPeAyexgWq>Z^?}Ncll{xfKC=0|vY( z>$El2PjJF15C#~f1cToz9;HpS%(s?r^L-)yv}-Bz;10vEaZ-*+f+Qb8G|~;d@l^S#c#CJ>XlW%A>*zUd0!b0(Z14ap-9mFq_>)2{=xqOTJtccro2a6>SyaU(@j_cWELuP%^r zTa}C8D5r#~#`<}>6^;FH*!k>y-(wU_*=mmE+ZM>Ut?2Az4&cLGO3ZKKL#HV?j;k*= zj-p8BZR+dhZT_glH^F+f5gg?dW&y-+;$y+#_xi4+Na7K`4aeVEQ7t$DItTCxh0{W3 zAVc0MGSu}JLahL`lnZUl8OAL>{*lV&I|%k;TkD#5C9PC47mw z)}I1uVvzqWJ>C}9j#a`N-TR`md2QR&>_d?wa@dD$peVNaqFKLI%aQwob8IlwqeB8b zZtU=fLq1!K=ElKFnK9%H*|5cUDNK#gD2#mDudH1GQC_=p1spgGd0^Xv53nKPu?HU9 z_JF8l*BmelmR{}P@^Ci0uEGn1O_yiizV0c{-h6<=IQ2Z2Eo7Nk3T7%=C3yHhN_zOntL4qA$g0 z{ya!$@&sy-<428LWqQb8tdm|#DZopw*%aW!{&Ww{U1IRcR|-#k3|s26arP2}%RU3n z`q=o+-Mg0M*OU(`Rz4}~T2wH-d%yDY?#Qj^T9$WS`M?riR$15Xou}syE3f(I;M)dg zO*%MP85k3DnagF~gZJ#o2PgUV%lGShc)9?u^K)(o{MH5K@nh2XI-s0omd% zJQFSi%40;#ws6%WlMfQ9TH))qp^b;)%PjGwI@$tO-}g(a$Jzqsm24%+D6y(F&S$_@ z{Ld; z%(j^X2;7Y zBA!&g;El_7>{!0+;fH;T^&Y2RpnkAH*x>iFqwK>lDnxe`(oePS!w4K35U88q?ySTl zeb~*icaqFC8M+|#PDiD@Io;ph@z;;2Y|z!YOXe%jKyw0eMu5|Dz;hCZ27Oqf)dh;B z+P20w*^q4yY}>|$V70;3bb>ukaM4+=cy99K=Pa017Vfh7VHO7X3rh`YR>zy!kQfk? ziH+4-zIbdKV2Z~uujLYz1du)7bOO(-EuiQ(p=UTz2Vu}X2(LIaG>1+=h>M^Y0gc6y z*;~g&UvCvjKZKrq5va9I%aQn^agc6=x^)6qf?G^{3T$JZI@H#H5SE%=MOq+SAUl{g1+A>4!g1mQ&LhQAO2-27#c{Sxql zFMnrV3nl$zoGd97!&+vSelit&3Fa} zcHq0zw&9?Jy{-I3O#}bKyJZOf8-a~q=~?Wuy2Ewrrp>sv`y(rsJ&Y#78>iRRO`o=I z-83|ZWoQ<}lfc)S(?iRoSv?vVV*UXt@D?*F_MOq;ACXkcJL_a)GDqg z4aaa|7<5KV(lc%Lt00HuJZNkT!x>k$7={zJ@SB+m4?s*!_5Q$KJjz};%3c)RkBS~g z%?7S9g{!zUvkBhJe8N;aG@TGlYt}Fg7GT<%HH~+w+gYbuZV?|ejTRr=g0;LB`jL$X zXh5TT|6Bp?G*3(9!+;NU2^wO)*32<;XgsV8;4{ulPjt7^6Th%r{vL*TG}CLP=R?e# zz?AQT-%8(-zd!v{{=Q6a)npz2kk7DYj4An<`M0DeOeFrD&AX6)ApH#fp_Sf`f1uxt zgsz=>Mvt!>s*5QANKPWjWgktCeKfX12hNB)xN$TV-=I^`%3Ig|J@cNCpn$ls3|W;Ox| zkpIpz+HWZwcsSCQsMZ`us(K@_3Yu=)c8&o$*fTIj#{|Y@>Wy*&qm4YkA*ON;$AVV} zcv1*iGIObRTzwQZ0QpK>Yt7H8gPZm)(DLHc3z~XpC5^8lZ<<#N#Fg@`LCd?wA4YQW zh?cGnvfxmg@z3*Jg&v2Ik?qhtaYnY+V`ShAF0CMi$#eVYB<0c)mWD7K zap(2ll|r0}W#GLqaFY;}g+p|Gh|WtZPWAMezMjhAE-y-_j3@e-gV+dN z7mw)bA~wb_#Dn^I%GC>co-!X-y8lwilVob`eO=tE>ulofRf?$kUR1wasy_br$;5Zee1cs${>{jY zq`CP;p8kn5!gglo&&gNSh)rYdou|wC!LNQ8w5^h~j4MoK$Olw}SDTcLBdpT&3PZf8b$?k)4}X`9zx z(qWvJ>z%cBmEol>{oRp{D8o?uyx3=2x=X1z_%DXT5B23Dab%=Dx@-K5!f4*Rr#WIq zJfEDLsOu3k$~*DjtzgsPYHc#_R$bUt8PN$roRt?kp)q)zFay2BrsKhMSs6+y-DY+2P5~DlCX*G?tA6 z`6xmLXy|cgq!*Xc{8TY2kNC5&fa0EGRP8?i>pXX`zl$w!K38mAXT$`uC|#U!E;LZi z9a*BmIg%>{6mAvOs)Jyuf>lr|Q9ZZnLfqCs12uaF0WeF}imyEW_unP=f505SN$zvR z>vtLMj1v4Om?}QIy>~)_R=XlB-rK{tvJ+D}XDf>ME=N&1cT|+>EUsi{a{lVFUmx9h zYT1lyxzeLcujLcQ*Y)mFx-l+s(^dI=#9&wayiwP|P2nZtAJ>mx9OoQ7*nB8QXVI8U z?Wn3T_PlOkF{;{8hm%gNqoPHHbnHr0ZP%~5|%HFB7JzBZA4HOxp6_lpeoSYeUrnnfl zEAbxH&Y6?LqpXuFy6TBn5afwdaAKnB<~&SIjMwa(yVV#aj&r-3kf?@n-&0Q2u&Yjm z+cmdaHMrtbnBAZchU#`B!FZR-Vi-Q-0}dk!#DJDBlOP651|AfJDRzotSC|9>JQ$z? zFE$Uc5rYs_J#7$mdlX&yHBP~K)ry;`b}cbMx2xFs$-)dJju4AaK+(pz10}I5{*ov- zz!nFl*)>^|onFp!GEm7+Q000V^JQ5d*yIe2MMX0`lc?P(#~!IEnJNb@Gf+kL&bdaE z>buAy6!Htx5{OVrTq{C}^F1mkDM_a!5<)xBY(?UXpT5)sYQN@HS5(~z^`j#Jt>*xM;ZkyN{peooJv>}?@$mOUC@C?g(*&# zX2c9iDT<1c;YyrSmEloQGF)|{=3-b*iC(vqmQ!s0VvJPXh$>HJ2u`GP010BQ3|6m-EW@J|KT1Hs=~4|CTt>sb(563R(1^SXoUjaohI6@XHLMNq zw>=I&Eg#yxv7KhHh-0K3;;301g#+aSiUo((QRvpB(_ncLRTYEk(v8vLfD;R3IAeiS z5U6xeSpFLyl(s;jm$uHOwC#s8vOOb-w{4O?{=oZoO>`B+P5!gHD63nKoQN4~Ri#oi z4hz$wqB`Uj^)I|YO-;=!9rSDaXd|&*WM(8wjNBgbT$haR;ZYe;_Lkl@Ya*W~8UPV`4M9 z6->V(F)1&rfL)Rj5v`}h8o5zQip$O_Iz&Vp9h~;A5n2bl7NtZ)868}P|Fvfza-@pL zCJ($uDXC7o@FB9E8f$bxsMF333zX3XpyG_iR&PvAMckBFyNnyw6wxZ%cRPgSYJBYn z3k;FVtHDg@O^!eQ()_Fbp!SNKhfPa@T?N+Ioqyq@8lK`KMRJ2k5Q$GJ8+p0;vbftk z%qEMiyo|=OE$OiH!x>Cjs-R0_Y3*2A8yJ1pvqh|S3%gz<-f*3WZwoR`3}q4GEA~8# zXHN(WEYYlN^)^-c4r3$C<1)7g^X076=`Ce6s$?a~u5un`E@$75%o3$vm`9ww_@;K+ z`@AGG!u*T*^H-uQdm=CLc#^94)o7#^Je$5s`Ll|y z_VpOA$p6~>S9B5kvS~Z(U&EO8@rd*!^F@*LzUY}ghr46CBp0yH8-0Bl>!Xb;M;;1r zw&|<2k1#GufWIUg^ShD`I+i9c(;N#mT$7F@i;F55dNO^r7${y5uZe-Luvrbyuvv#2 zFK2Z;kJarJPm3Mm>AlLtxkHCsRxozrSlB%w>L46kUHUwm{oHfn))&M#;!kWHi{H(9 z@7yU4>>fII?$G?Pd3j^0+=>lDHvMkxZOnMOF;27DTHJ$qTOPA$p*i3!hgJcLi-0DL zwXmWOX_bXlO?kv#TB)X9_`KYn`R@Xi;F4lP^JBZn#zWDtXsbzEe2R_1;svL(1}sEK4uYR~|Pej}`L<9^w0kxokiad;)Fa5VWE11zwiTPac0gG5x&G98zp`$hOumps-KI=Byz#nMUb$}L;qEccTg7nkCd+5L7|!u|cZ^l{%(x5f zo6Z2pm$}gTSWy<3Kze{HqTY+L!r_U?%Z>BX`(0frv4hn$1%pDGiO36oZTa$Z+g=m>3t)5irI#Ku@~bEn=*Lg4_}`i_07o} z9zOBF_T%3^^x$#6V9mq{Yt~GdxaRKEcu!iICq6ZBe>+ikI=e>>dKBX}!{v_8v11{`jbDe`-B~x{L|jx?r_&xC znXEaYof=ynorDLM8WEYK#YQ_-?S04X_t)Rb*2i{sCY+b*Q4~+=dGW5!vFq8b_4nT@ z77yAosC<$*D%|Wi>oBPtujY{lj~{<<+ldnoOt|W*36s{W`OJ-;H9kGvTo|907Vk+< z=cBT^Mn)S>SC{B;^Mtc&bU3uME>V#>n_|z&jnj?v$gnVX+@YxSNIUL!BL@`_C9&7z z++p^}6NbE{*>QL0h?`=K$f$1EsTm%PV(ht%OE+=>g%@rFFJKwLw2hd$G0p4N=-4Ymz%88Yy~JP0FI50unk`ze)* zD-z1Jj;!oVFHW6MHB6{svdv2^j9QvVf;d{)*Z5uUfT# z)ze*5Qv?6SkFoa1=q}D!JulJx{?X}IKKlFB;-SPr z$=yX=_|jgHr%v%c@pHI=|NsutB^1hhF)3>Hqb8_kZ=({r7$S$g2IdwfmV%md|`# z-gv)Aluwq@VVKRbe9@7)C?(4el+Q5S@5iC6ak(AshN~QEi;)8!H0&K8igQ~f#jjWd z?)H}|mwgpUCAG@SQqQ}iv~-mCw(%{!mX~p2>dPg zJ3G@bYoC_wpq0}D+AhOr9Ijucexbc@G?wYQc6e5kT|GszS;361O<(L!hxzc(lm^;? zP0=&-3=S9e7-1BG&q_<4(H_(F#v%GV^^0o;=ZGgO^_WGGGv4sryLo_KST*(bDVT6> zEQ5WOmCapxuL@Bkp6T9=abv)mZC5<@)RH#&!Xa*Gz8LPooHx#ZjeJIS7z@d-=~o=T zw0V-4#kPzSGgL8K9mh6{*{w6YTFhpf5iBmokye|XwX{t@sCx<+Njos;*vyQ-8aT67O;Gjxvhni#N4u(az33i@r#x!ca!AUq!o- z>@@o~7JBS9n&bbsu~_!OiRk6%NP|k-3hL8n%!p(8f)C!n7f;|J7^DTh1cPV=<$tqa zz&=nqjMpppNZx+DQO-Naw_jEHt%K5jf?mP0c=80Je4Gq1AO0V$FX-&e@C;tYroU;= zP)h&traevx>4G{XtY}uZzRUL-7n9*nhhzvK-U~2lT*8`9@3HZ>|YU? zl6(2!i~1@#Wot)We(CNTXLK2^=`)rz{uJ3RX7kWd@!{d&F+DTGqwPkF&iO^Lk!rgz zmtfuUc>J{6Z_RP{S6NkJtTTcAyCAuG++}@h$}Y_8IuHw7r1Qd$f*ga9Bz{&w>b|U2N1D5lW`p(~_LJI}B9%yJe+5thNntY- zX>}!)H}tv~QdpdU?lUVJbA~ZSMhSX+Ow*AL3f2H)U_DB9k>DEuQI>o(aI`mTbg$gr z730ey$Gyz@4e4KAoRLvu#Ln?Xv`Z_mPRqDt@S9=tC*5fLb;#_D^s2J-h<4sNu|`cs zMsZpHp_sldnlfEa>E2d4>3HMzSL!sdw+Vxbp1wj?zvknck$Fi1dq@d-Mo# z$eVsBHI1TS-{367 zN-dNqED)iq2kU2I9T9!BjtToB3_jw}Qx}xRdgUAvc%If5QC5X?isCHo!FjHMyIjmx zn&j-NIJQhpaK(UoheV1-Ls`@J>M*g#yfwFXp*`~QF_Fcr(+iy@Oz+u$Xu0^<09mD(}uXRF3icy zjO-yEu!mhWKzZC>_g|w-8?XwEy(?04N6Rgw)lgJQCF{;ggJ09EM`+z>j3qeI7KJP^ zhj;FooDl0QQP*}$NNHb?xECXmzLo70TyAy&)+jqy;+v9dk4fpw7I&)ry0UXp0VZf8 zcw&d#q=Mw|p1FwyQSCVHNrj1SM@nUGfG2}^IbnL0M#HHzjP7Yvo#siS!<4PZLiv#- zg9oz1|8+-YC$_kA2ZvqBP0a65+1Z5I`UP%RLUPZ(7(hLSj5{RcU89ybW8>TR>}(EK zGjc0a9PY%zq}-n2yj@g5BJRlrNx2;oc?2eq3z9llT0F4F_MZM{&?_C1(dKnxoSc?! zq~&F#W4oo1mL5m94BWaic`Gz%p-j?~Za8KSvad7^ABl)WLPfU^$V(Gn+v zrI>CI-RbR_ykR+>*w_Qcr5nyJgiQ61S2)VuZ;f*|ZBT5HEy%j>5)Pp|Dh_LFx{=9aC6$x{F&>Zc?dz z@1^w;bto(+9fR9;+uoIRkw!By-h$#HbQOix4d*SRo61frz_&E2BR$S(D8xv_Mlk%B zJVdMnrt$NRZYa-<7*Q3wbHs?x!&ndCb!Q|OBZjHIkKHBWuGIX29S0F#^-5E62^~{W z*(DOe7nNgl-=Pko+YbW<4emc^7=CXoFZBAp>!1wnQpNktoP}zbIm?L)6*F@-lV#Y{ zd>VD}Jn8~vaJmW$&=Z1*=!RpXacZ=@p>|M5Ss6IR4lIM&HHQm~nO6Rlyswr2>{x&PvlxGD#E70Ql=euNcnK^wHPU1wMkv{y5;i3* zZ(t4zE9!cu`re~LaUXg=$$Az17~LOM2hz<3iv^k!dld6@!!XZqt?g#a=|6@&anHf` z`lmQM`)k{GI6wO*+po4JTQep!v5LSFSr+TWy0QXjh7}A=i=|qV?9d2|!jfW`g%rd= zV!|>*H{v{Ua79Nicf*(TY&{ODUV1V0I@ssvh3utC3?xZm#o3s1De+>`3VR;$)SY<@ zh+rDfwP&8fQkv|@F2#Sm8Xin*U|iOjr5d^>yC{IoE&_{CF3?t-g_(t(62QrVgxBM| z(9a1Oj~vZqk)00VKq<3}q1ebdy;8)Kix=7Wj<`TWi-Vm>x}l*BdE-ip>0TIDnr+C- z@~?nG7DE9=9b)?`LNJDtT2xlC?nP&UE~E-e9){QOAd06rTShM}E(JKclm}V%My5J%?Kfl0$`{fS(;`z6QuOn_sGXlB9+~Z8mv`l5WA&k#?9JD7 z@8sTnzSCKJ{Kcs?hAX+~v@hKeRn&D-)ekdXOW-r23bX#)uVcRWcb5-7?#z-ilLuW< z_H2aF#U0~H(8Jg@(Mm#OytpNnWhROb5?)W@=XsQcsjh?v5*8*5Ni|O|F#73H&YIiP zoefHK>^}VbuIST{=fbPLI9WD2q($J%4_sK5D|ekG`7HUMyL>X!!iH0%z`Z zeYZzU>`;~)ADK9@cjlm{?uhN|YL}kBGyZ~co!^4)xbMHaM+y#4l3;pcC@UE#w; z>}t&(J|L?qZ03CDck{dn?X=iGMNUi@(JM33xVs>te0G=O%ku06_lm1uj(RpcqSx%K zodeusCJvv_*Lk~l?f9yy@xw;-iOkhj88)!bS+Ch_el%9xjS7MI1>&EcgCPKR8$K z!2ahvxT>$Qjiy$O8Bv&dqlMAXEQXb6SsAHNeaM>+^AlE!>;aK3;rK(-vQXfk+!Yb)vnxRt5}kYWLuIgxp!IaHpUGb z8{-DpfB{oXC&BdI2`zzu=_H|r9(qCusgMGJgcKl`a_NPHl)L0|2iEXEv$81(ci-KY z`+l(H)z+DJ-krBU6G%q&pl?(~#FwOnR!7)`Zt2hD6o@Bv#Re`*&!aQoIL~BFL(VV2ZgxA4=Gz3e18QJXoGySW3dfxhZvCzIojh zjk#uBuU5r^vOpTySj?+h#&Xg83!`_&CvWddawhd1FnxAimGi00gy14eSg0vK$eH(O zQ5D^}wV$d;K78^^%D2WnIk%YPAFp);+*l}|GWw{7i^Xcz{)a5KA_i(+763QdH z4D2_!dsTFR!Cu^TV4wSQgh#u+mzp|ytXJ2$^rqM5<6aL(Dip6I)l^(&))!DV|WZV=_ zR!GtdT!fps8)1hy1aH_Xc=&(sXc_{+NI2m35f2%GHeo_(omxb>o_x1_&>Y?x` za3Z)h%9`t~d|k;cFWyWvba7LtAE|E%R(c7RAH0Js`~i7>d~6O$Ly|^o8U0$$%}%X9 zK#q?~D&k1bGWswt+*dLD0`bBE>Oxz~HW&S?K*p7J+s5g5`2ln06Q|0`%IF;Bd5@gb z(R~d8=>;B&XzndhaUgFjQE)zVqQKS^CxtIAC&%g@oB(|Se_@OcL3>M+lT%V9bPC8^N@Rb`R8!~f*~-Mlh4QvQ+xVHC$_g*vP-S}PHzvv z)3ZG;Jt#dYBrPdGDe81lX+zWZHz@nYlop0*J%jAgxn=Rb-fEK|7|8l%$_H$N9B}UX znK&-BYh6)Tusz7W-8>*8#7AL{jjX6G()oFZM4L?ud^q_mj~TlAX3BE{3_<{x5EC`D z(O>0fObz9RYQog!0*g8v2v zUQA31)T#1QxG7UOkMYyaO!DE+p5^ClJ9c3A5pjDn-PycLJhJ=1G5JS_IPTDj`+7e@ ze;V@CUpeltzEAdUroX09pJN9O93wxc5zl7khuwo%;bJ_WN5uflO@^6-HPv+zIF$gP zMesIn*rh}xL~fIuFIbUcFzFz8Q8zp;o2X~Sj7sW@R z3XKr)<2v&wo?9l0dt9f*@gjb>>^&m<&yz&g#m8`{n<#E^z3M)hOW%T2^(RH~F)l%z z1RgsKfjbSdHdq>AOp8`~r{WR8Vop#=;I@LM!D5J5Z64gJusWRJ1Ade4!?(mA=SsWRJ!vE*L zA$z{>LsMSkXP#6~pU%HFlgC)gCH-g~cuo&1X^@2f!o)WF1ttA<&_j1FdxChPc= zaG2x{h;SBcXPN4f$)kX42`$7m5a4Ki9(F^Qa`1>4NWEh7vgEp9<%OwiVwUow6fk?B zenoIsgY)Cf5wQh2fh!7$wVLC4st$9>77x6l;bT7fxO+m?j-UypbM!@p52Y{8o>Jd? zMtJip<_W~6;jK4iOJY{|0#X^7ml~-cSnmw z&9DFP%_Xkvn~}qa&-r3G7c%b2D+%u$?3Ja^z&r$log9+=!C0lCih669HNZ&@r)I-`d77# zt=gc-5TktC;;UOXd@kr_T*{j=>GkgeRJ|@Nk{6r$q(qW&mM#y0W`5J-t9sVGGN^p= zoXsyEykEP6Qu;A{?LeIIVOuoEXK|MAliGNB@qJm@tre^KJ!j3z-)@Q7kG!IaZ+2>@ z9JsM9K{L6$@9WPFo31H!-CR{Rd}+Kc{;3Oiz1Ex`r5^|880s5PwaSa&x5p`e_b9#`UEKM z+w$Dn_eO~)J-;ErGru$y+<0J8#GuK0gv+NkUVd%K>Un#{^yX>Oaz!9nXR2#?d3>u6 z;e3Thp77-wriarZMNWhh1nHe%`90pK4Ar9!!VC|HJI6=*)cP9;FUqufLoi7Ld!gjAaa>JVJt5qC75Z}U3y(5lzyAf$hPM5p-&99r|>%j9g1Ejl|pIx@>u zlvSOXS)Ijy(b$bHU5(9e5a1K+?2}ulQn0^*vg7zX;hj5<6K(;HLl_D^_qZPWrQ>&AkNN!8^_|Dr z^_};3AIF}K=d=6&{`$L*|Fi3{|DQbHeSPO~>3U=@ExLIXg6b1QLGodDc9&Jd_UsR9 zYXtHQu%sNcQ)CfHa1sJ^V7O_ZY(u+s0MSDSMHrAEaMM7cg0TdJ8R`h83~0A@DDcpY z!F#-@aI4MO#$n8>D5Znqf}H>j!L1PIM-2^j;!fPpi3wc``X?rI>6+l0Wi*Zp9$D+x zTs{3odu8PD2YL)u*9|w0!*2ik>eNGfEIDqsR~}o^bD+9sOE9@%4)<9xh|G>MJvn$8 zeZoV3uDgNzH9#a9ZBN%oe=qu@zMMPip?|$vOZ_=$_tvtEN0nVzpjGsjt}M zrG2?lM{{jKdk4&QhFH924Wi{C(duROKie$(hE01w<4u1Iso3G^|6)Z5dv|Y+Q0y1S zfciSTw{gI%ME+PBUJm$!Ew%_&3e5cT7MpO#YjM}x4eJ$7KUki2ROX5bZf?)4%iI&yj4BLr&4I^d)+lcKI$mW~ zN>n3g>yd*=2|bB!#zuO0albW@x1AWk(Jr#aGeqW^N#rtWDHOs$#|ZN4~Bxl7{VD z$dvsrlf{HI`zd-HI)|*Dai8>1$-P*M$ThO^>j1u{?U%m&J?V?IeJI-V#LYx`rtm&; zHCcoKT#UzKa(C(!um%8K3|?lc9^CfKtte%ENqINYHbMf->91nK16V}-@W}85^G7{+ z_xNVnI0l)i$B7@yWTfo@}g>*9V2qJN3-;!M+!{ z!Q||@K^K)nrayCPUU*Po#Jp!byyiC4C=@jfbGX9;KE|Gd1+@(^)#{bmFO&#_x%np9yi| zv+n0cNKeG90Oh7Lua%`OOHX9Bn^~>D^<2)mn;!h(JGvjwr9Tlr>EXxPIv>kx@mPA4 zbSEF-vBYCKOIw{ze`SwFf4AQJ4D$OW%wbaJqaM`Tjw=VI1G~IeqHN6;k?n`%l}!nIDikPmf`w?+WVwAelh7 zuX^EY_Dn*Mw*VuS*@wtNWJ$c}DT;+9@-i0$aPS#%dF9kSyQfXr+eWyjP7-ePXKUBC zYdJ01`z`=$dvEk?`CpC8wwN4m2|W=>-Fb)!eF z@1Bqgd*i~!jR?bqttDY3Y5jWo2K|^U>*36(tjut}s7dU8W&Qdq-ILU087*JSy}gc> zL1o78I#=9U=1(AUvAb_(j<84AP5@s0uD9ovX*1`67e`hdbc)jj8jCTwZ zl#c&&?ZJaPrnaHjdF8r?9^yFCQaNlTS+#cM${`gaI`$IMHg(4nCr_SSyHr25?Q-pk zW$V{3TT#ocZRz39on5|k!-l2HT~7bX5pAT8`&b|O+ig<}OEEMuj(mr)$wON;@bAiq z8QKRkudN`Bw^Ze^HKM0*<;{vF z`nSGn*M5(=9v;Fg^Jw_opsMZJDm;hC`hg}F@cxF&WM-Cn&g6>~uWlM*9`JNIHIj!1 zIWQ6{$kcp2{dD&nOYOpb+g6d*c^-n?V?G)G@Ya3{>nwA3(NDSFyl}=cd-nXt=AUf8 zkrWx3#0w|!W%eA)X-KGD>>Xmcg%i*>53G02<_wiS4BjLty15*1hBy#en*ZF{>F6W| ziL*M8J7LiCYaYIEf!N+Szh++d`hky~nD+QQogqGE6@BmRH|dqtQHcS%IeVv`c)GN% zg75nV{gZTZn~+m*^uQ?k>L{&WNYt9QF4Fgi{o-3|qC5^}QV(XJ7o zg;sjgz!-pDf&T@W13EylIFLh@20;#eo73#tLmIiilU@gR?mS3$yFBQQJ-gPmPWT2t z@^*dd>V}532>~}gH6*NSY+UWo`6!igg;EKd?JHTnSR{-^-%W^pF;Jab3Hhv3Sp2-go0=1&u{9#0FY^~($(u-WK`B%k9p@G zUUQ+P+uvM!`!87V%)$l4L^8;z^)A|$xuEmlFWgh}pIxxvS?a?@#!Ro(2aS6C;Wt39 zVHMrE5X*rUoonn(~KVp%U3VYa_RqTzf40uDBAb$PO{={|e7wLHl;WUSqq z_~)bh{zN~LFDx0{W!Bi{he+u5`Lo*M10y`cQd-l~v-c`G z?8@-&N!*W*z4qb3lho_zbiQ}#q$y)xA)masaL2|u*(-Ag%~tm+93Q7IpPZJSoqd12 zE=n2n6ovvkFq%FnK8yZkvV0SQj!0ItNy^`cs|J!8&IeI}@CDLO9Do`p3QWE#xPTD} z!&WMw4Gg)+)D1_z4Rjol+m$yd^5yc}>cn}4*@NjkvT9d++2c<~lR1_Isv%mFvyxr22)W7o`5|m5qc?1*>f{`K*N` zM9k9MA(}A|*x|5Bu{p^#fZ1=aaOrw9TeF7@>PpCorwLz3=DVIC8g>1ipZC!>rF-wvWvdN{^W2k0D4x&T_NqRJo?fo zlGAY*!g~avFL5udbKRatt{`s8Y?fpV%Mx_IwTxZhxlPkzLbGsi@+nd|yCYc-gB(1g zhwf{$TlkuhJp)I-G-dsRD>hDzow;P!hN;7o^E1OYY*{}4;m0E5ny)*LpX$wcA#n*{lVBA0!#b zL)r?Y(VpN3sr1L42?=SElB`wWHB|sjRQkh4%xaOt?=79jG;;(C*`Hfyx=&$mv)#td zJV=Vh$0-BG?MqJ!2)e&MCTjZV{&`I)+4bWBjakl`Ue5HufHWtif`b&c#`*@NJL`Lm zF$AY);M5uJQ*lmEaF(;SKHV7@Fb3+SgKQ>#ktHiiN=m}%>68m7YmHkyg>YvaqDI^xc8reL}iGhF--OBcP2?8c~4%9cGRI0y9NJoH8Cs za2kRI=jFaXh0&`!NJ=ohLL!ay{7%4d{UwwbcF^;|$mpe4OeAF|{U(%K&(j0+Ii55T z=RSD$2JrNG0RPsIe4ai^&+dc&?lB$(Z`Eur5fFcsiOqPvA7UoqvRW2Xhf@aA9zvVY zRPnNzS!Nvzs!MYylY0bO5COI+3!}4_0g+C;o-jc=^)pPXA(+uI1XBJWrc#8cLvUv2 zZF~t|ML26p*`|kUtIKf5Udu^+fWE9}&BHw^%2F*Hp?Tad?I)sbMWe>N+)~v&JWQz? zHEQ^%Q7UCNk%!_E`kgLrFiMU#&y&16h7$}@gQtZMYV&82iT$KnhNTR%g{}!u|a<9tyf)aH3YF*6A%;O@vmf1tvsP%T8}^T%xmR z{jFN9M$Yp$xF%zY5kL8QDss>EGbS7H6K8Sx^Qj?;#?+voRAX8|`&sVugy>*)VsM?x zRmSm_7;Iukf12dF$R*G}e^Q?FcH;K!q&AvEiiDRHPhf4v(}?TuVcb7B-pgtWN1JVI zk2aXQNc=l@05-to#TR&aN#~H5FEH`jG@!Z3$z41L?R^9%m>TbM$8F9@NE^XYn^`SP`lWQK_w(Y@nT+!Nxwr;$B z!|CL&&TDF#=bG3$dvC z71T>+SYSiai~vc9dPX$fiY}$-w9vfci8Nyvc(V))+sTw7cP=!{!#g`X3MxcQr7Ry#7X9co`&UTKxQs#|%qub0MTkBTXejxLXhvYWJ?zR~5~aHurb=BIXK zXQuITI)SVvmD5K}#}7Rm*DaDGnE9PF3`cQfGL1bR+`hDN`yByi>0kd4kO+G*S7`f76AES*1kkB_6gs( zf=!gzMhUASf+NXLZ19NA)A$g%zIdt!xf<7=rX))m(&M*y#x4!5V9$_^N+AA7UImHB2i6j|rYkzs-xcCWZLXan@A75JM98 z_yAjOM6g+-@*CJ38++#Y?g6D`UJuFlhlEU~-_1x%CA<^f4zC!W9%W@wTC-N|2bm%# ziCDAf27GBsya82+EFxy$p8TbGO4R;F6cDhy0^LAm479D|Iy5h`7`dD zGH>3L`(~j39`}&5EwU-HCI6qKEh90@lD{RfS+Z0L}nwupmdHq2K(UN$vLIufBRg;bWfCwP0FTvmu=4I6mB9?mDfY z>lCvOssrzk>D|Gn|2;`Au<4xr{z3WbisCN2qW)VF@LXjjz0{)z-p@|?#IPPCFx$an z=WZ};FSfk(zmQV$ORm}6+4k?+|Cwx(&+p&AJz?xv!TL|c672I%8I+3nBBEUG*Z$v@ zKE#Y<_dA3Sx9{H+FhtM9OCX7m5O2osz{MWuw5g;Dk}bvpN?aA_G}r?( z^zk7*`zRB92;JwN{DbfFP&~e>rOH_I#k0Xdqg%W@jX~Ckg5aq)RUt{1#C#eRVDfWV zxcol!uP!-X4I8C%K8Ghv_|N8PlJ)P*zyIOH3fcqI1a0{m^>WOkuh(ii5_4eUS#>G{ zKqu99E3^0{93xpC`~m&1TodhE9r+uYqH8YK@wSAzStq-Do+Md)c;TJL>38&MMqO3p z;{)^``p_@h#I?l4_g-+ZTl|yf$lM(~p2^8hAT@P7@>v7i*&kXx5@a+me~=WUQpglm zwPHR5TqZ^N7EG-E!aJ@Y zg)0ks>+E_Z*XA1L8q96tSkOTBIqaPh+{cM8Ec+H2RVh;J$*s;)o+S*{NP`n8yfhxf)vmCO1{>V zeHjn>EH!tGry_vG4drvV|x0&)}lq;5-E@o z*v;>vZY*0?z<7XRlR{Ns8dxU_fCJc9o5P9MOXfs2JPcDk8p+anrN7c3aeN9q8VY{x zOfswfm?craau8UgK03W_xcS-k5Ww<@T4NNW|;PYE?(!pT#={r z6IH^ypU||W3;Bzcsy`{|*Bik*)*%xP6yz!SSKlGSy1hcj&RuZQ;rXZH)sIJpgdTi@ zgx(luXkZ37kzpJdU0`J#{=0yFyuj(yJx1Wac)fX9e{O$Q+fxmW5 zvE_s|8?Ti7xZ7vsM9;tGC>G~bzIDG!uZXB=*s`n6$CV~d962W}=ww>dQ#C|k%r*)i zTqw?%ztbRIPS1RMun(T&NgtQEsE3?>eXc0;+iD+i+#%b!;aYlRu&&=?cRe(x&R$?bY zX^n92(6W3%sWe--^9-DzWnw`D%#Wnv0%BJ5*W(*YrLl7pl`FZ|6-v{#M86%Ri*glr zUR0X4Ci(3oecWG++wdiJ*Rv-8V6>VZI&o?jKd-$0aTI-(k%XP~-RB7zc^jMOPI+x- zYf6Lf{fn;+xVHApNqXVN;mV~Ro`)_r_BcJ`u??;_R~FpwyK+AbNjfxez`;R-4h|T2 zC@HF_V%NI5x^=rMilV@i`)>Y?dlK)Kn)MPDi9qqiL@FT)V>RoRQpM>+>pMpI+ves5 zK&*INcWsN4F9@9*Amq#6!6oc^`B+?UlCEd(98`8p6>RwJsI;>J;g-FEYOZ%LkKp}3 zPL+q`eBL+kVx<=3xmjNUGv zspm80-n(zS|3JFOM#WT%ysP|eHrAZ%nVWwTS^L>)j530Upt>j3iKz`<8dM*Iq4l^w zvTPmVNIAXnjpm!tJ^1z=9)FQj`rY8(z4=DrUHJ{oySnX5e6zSUu7)?l56w{J%RhNz z(hq!7UW#I*TMjWQ;;;M{&gc3s9L;+_mQ9==0^Izq}1Rtr|#G$lf9Jp`!K zN=_ar&?mT5j+i*%J%J`X#@%Q}67m<1%9ps-(-{w8^%f4*88SW<_lk7q`Wnk#E1_2(NCiW+gd`rPH41IE^!> z*BpC7I;+^3lx1z8)yHZw!f*rW&Zt$IkM?gu`$de9KVo-TZ2c_w65tbH1&qw{g|`sN zZz;SLJCP%o;$$^1Y)wm6`NBxe!jF)z_|zjymw8?gkY-*OlBG{fFf?)3`Wq4w40K^^ zLTp@N9Es~17aJd^`20<;sZ+h){Cwt!;VmsQKY!DE>QrxhYZ=}$V&<6E*0k1E{%Bl$ zY+ToP65ll*SCBF6Hcjo-P3$lC>&)RJa3QUH(|gJk?>EU|TsnOC%u5&9jV_LVB%aPD zv*Q6^AOlBZoDj>|hdx>nIZcC?sRG{8Nx;!s3zVWK&}TEsO7ZsVcqFZ-IUO9!6+wvt zCJ9bq4Yxbs1`tqOtV@BioIr>{%jAjzN*>F0VI#>q4B8abZ$hq!5z>WVN)ABU7+0Rv zv*i&u*1)sKL-&Vzjk66{uM^>OGk5~rz~e4RmFIGZ9WRO5tt0|CBgK&lLAqMhKnRiGffqPJcRvpyP&B)sfxePFwPlrP{q@?cU{tK4)TaMaCEaDzh8MqDbR~ch~c53^cOY#AVys)(HiO1i1>*dTqMbg>De~oDW za`%ARyuhp3&6ZS!BG2*q;-Bp42|)hZ5Hv7^lD^e8P~6+V*Q4BrR0a9AvP#2h^E zVXtm$*A#m@)!NijGN1?TSI{L*zJ;t>8BTAGwC;-}o+IgFm1KJtGg4n}_t^*^Vj0$j z2fss3W!VYC`g9+cIBSC~(RZoK>yJ?7 zt$uY$TXa$BL6Io|wlRVJ%{^^}amvy3=|4=Q+cb&Zp$E*;|N-?zTU*zu($W!<6%)R&J=nzNy%eZ(K28uu($ zlihcSuVz$;COIW8xe@vf(8LD$Df^VCmeGJeOgrJ$JH%?v4IQrwmly0N8KR^Qh>15XlF32_QztCU) z);tn`_$2%%3|aLLisM)RK;JI?7y2Yhy5}t6G1%xqh`VOMR)CMCL*ImQX@Oi6(@2Zh;zia==d0?aOUT+KfaOqTw2ARW8yNuE}HT|=^;eZZD7B{-7= zc+KZ)dT4Y(uEl@xl&>i;n39_ul}c{T`iX;rhD7<^IA2xnz0|}9ukh@?l>B3nIENSa zh3Aam^%iVD zTXbXjFbT-8D*z7-K;@H+fN%_Z10G#>oh$P1v#=ADY!No*=5;d~=!j4o3>Pb7GZ>m+ zCgz$1m+@F-3YLnMQ|N3w911W=7=vNK2CD*|R2+p}4Pzt?$!lw`4Wsk7U!?uNY9fpG zxc)%~ZQheeTD|~y)1yz(X@BkuRNhQSKxWU;04u9l6%<_27!tRE|4cK<7|U&YKsRde zruHkues^=I{{H3Q|1adfCd-xsN`uK{YAB&X5k_b4g2KiXy;#0Eoa`{Sm(#gBQ6c9~#(e>l5Ui-;j`evbER1hn~bt z9K%mM?7M6#*|=!)tl3)@Z6s5d`5vCcxw3yxmM2%6KxF9X|ZLj zWgD)?g|pY+m(RX2oBO8o$nA52T?NAV>nS_r^YA?R9nXt{Kh@FsM7RMuAIO3Vc;dfq z2sv@<@wZ#Vjk>*k>u~#hovkAW?$J7K(>->!``m6ac=$Gr;*fb;ipt0iI{n+N{$F$k zX(YcV^*wj~4?QG9@6kgt@E$vFcU$~TpBrJ(Hvgx+j*xo&Z_}uQ#s2+~b*;WN$hS%L zKk$G&^d9|oJ$;Xzx0w76R{kHEMe#ej-7lLcoBDrDx&H-s-IGlJK0)c(+Z4Yw2)E~f z{{t!m0;Xfqxnn%;oLV5mJKs|SBzQ5ZM_PfR_aH-Q{QYF&o@Cq{%3O(ePdoN>=N`(DgX9=_KI)Zb(0y{_hE z_c-y!pYE7v872im-aCtr1WVZ|$sJ3_b67^6_-ha|(*QaGbtZC7-kBukix`!SZ+nIe zId_I`q|@ofGp~^$H1YrnlY5iw14roT$B`m`h=16UZ4S$}ShGXTS;BiS&~97{nIj*4=GO15f?itqVtvus>^O zJSw~Y)26y|^RulTP5+OY{XtkxM;Fk3R#VzZTOgO;-S*C$O)0zhckSacLsp7s*ony#sv48cXaHu#PNz4}UUq7~eM@Iv)^Z$n?JaT*3B#a($uIyE`O2(Yb zdxR_3BVT=$ji*#&+i^_cJ{rN!;0CxJnhyu^#T&59xTv z{z{yWJ#Op2&MC5I}hnQP#f$K!{VK9`*4-&~Gm9J)JFUfjF;vC8rhL-*2`W>*yt;2u$L z^Wg@0HO=(o`Z*jy9+Ug(TuS4H5ZB96&Vc**0eJd9dluP#?>h_Ie{(y;>qdajUO=51 z>NZii0?)nE;4~mJ-2GP%Tx|o8OYQg}d>TD+;^n8~m&BYn^AxEd6;HkVRP5r|A}f8H z9yv_%PSC#`IZXfZ6lz;$lAb4DIT^bo_UTujrUyxnldqnPTM~O8Z6yx+#1Z=A36g*G zD1H6}%Iz_>FW>x59D;gfKgrtYV6)B?cqF1T>N?;xwS+^{R3Ivo$OM2JrHbWBcFrv< z%~S`rV8xdBZ;#*+sKb9=WiPcwmPAIC*dt0KKl6ydnwAR1ZhEd>rR;?WWG}JX{LvEt zpfV{aFt@O1Mwf!=B}F;GL1Z+2cyRyuNK)@bQbT(AsOvY5mtV4%+VK;~KCk};xUL*G zptoApg_KXv7kei~D!6y%qXdhbe^Ir;v*!s3?B6*SJKv3V*FQ{*DInld53*#1ZOU&FU`es)4 zgl@Ju0Y zATF@;oq4ZPoIycqjY@AJ{2xBSR{q#_)WUS-{ETPlr^I(J7mIZ9YvlNuii!$4QLcPf z&UbN)YYGU;DD+UoaX(-YoHn9C?$l=$f-WE+T5kYcqE5cu$5Zt3zOlN%l%HtHuMSEG z2uR4C)P+208{3>vXiJIjGq7iZ!;)mT(4$z4lg?3*3ECwO2}L1+VlbDMoG@XDDklu^ zo#xRB66YNs5Evg25FZ#2@6G1YDd6M7pphIE-N?s^KvGYb^nrO39+wz`VRg%u974>n zkbMaT76D}|i-rPn+>jDXQk-HFvfRE~O8i|B^cwwc3Bk&cm(rtNB>r4t!v3cId;1fW ztAc3y?|Wu{5+bkK*TXU{J5t)`%xO=(#%H&mw%Mdl{$g}sWcw?Hxp^feQwu!!wDz-N z*J&jsdAWsrhT79i)7ajt(8apJ;3&@ zTJEi1Xw`nuJBQp7x!UJu|YF zXIj&blys`}bJIQ4l#eTU4#%CNsmMdHx?;~mgTk|*h=sHAw)0|*1mK~5o zY~ehUNKQ8fBPIbRxAD4jUnVyuCO0OhHY6o9o`k6SWIv4p%vyAeK>d2Z^6ea@uh=EK zvRCiTJGV6SuFR019^5B6xzFIn#6%jm={eh18`duVW!DD(`45sL?i;dEVU5|eZ%bX> zmVKLI!q_;!c=JQl_P&X1(h|H0G8sHbop3r%2C4&0NeNCz`ox-!@D<@LmOyo+Pq>ue zD!>HAKJy4XSSt1__ZKZT0LbtoddCEH&7avlzc#_VBSN)WE?=#R*kMkn&F?-lziUv; zzdlTq$UCCQ8yrPA`dQ=b#>Uygo5D$D$o#ncP087zwS9}Mh1TN6+R*HjjrsBOO}iVbd7Y+krUYc8qsMPI(GA#7$JNJZuf=% zG5~o*5y(VILc}LamJhqT2Wkpfx&fQf83-r9rvGycPFn{Ar}GvBr@#u!G54^jBZDit zTL2)Pmt``6ynx_jNhI(>fnj(Zq(}mmY(SbJmUM$m1|)q1J1vc`SBGkRebr&)uVbQv z8dr{qus2NZu1d_FmQ1p2gLGNh3CWp}?c;-@$MlM_hmRfLpQ!3yGwNP6$v+H7y@|C@odgV;>*A1S=2RRq}DjQ=e9PUQNH85bxXgk^! zEx}Uu@r>lT#a^o(?rY1C?;ZH;2;GA~c4gnmT8J82i* zhI|f%ta4&pn=r0>fp&gUc24%T?0uk}|G;!dHf_5nI98YhUdP+$P8wi-LSziUlZY1< z1BY2p1X8BILMkO;-!Mkfxzf;KRDeS69!BYG=HV6)n@9Z1z_crtwJ41%PG=kJsdk22 zA{mPKbdR%icZ|0rbp-5V_hD%}cs1GGS)1@IR?gx+##+mGLOKhaB7MU#>95pAb{*@3 z)5f=HQ6LAikbQpAqhwY}gomNt!?SsvFZopTUEl2KQE%{wNS#&Eo#Qe9(3_ByoSc-H zoWODMDTygbNy+hiAV6k{XQbJ1p{Mr{*HL1bl$SfvvV9ycZw>RYrY|N-oMxZUiQ<^; z#FCkn-z7WKvUQ9&In>*nwq$Xd)jMpwoFB(U1ji>Nr6j}$*VWhd&Ca!io6Q1U<0+Ue zR!i>4HO=0h^?FZR+VtWcqGv`*N(RXgJhO9==zb|T+fxX$gg4aI1;r<%ro_hw)$Wb@8AIx_>{{PQf`y!qJpcR=E|W|5501|rGJ#BN&W#K9ck-DB z2Q@bjI+!JQ`Ul13HBXu_I4>c{KbVc-xvn{5#?flQWm_7wpd16i+@SA|a7} z5Ebj;)R8|Ebq?0ECRTbmF*+uN_l-|Zw$oqJ!+br%`V8f`CwJGzCfRq8?e?g6p>Eex zgd5r?O!PJ72Ki^C2ZULYiLxL$tGFpJEUb4yUUF9@NwI_((lh*1hdfVd1=;o>3 zJx&=iV$Xt+5q^)8Fu+X&T4XEAvCFLq8ZC zXDzGnaTX-#EDtdv8AQXdNU7 z56tNr)DdjKmbCg9RA4Olqcdw^o{&EB2V-yCmoI{Yi(~=tB5?7s0!Szy>l&O)_ zC@{PwMFVWV5ZJOwK(gzKd)lPsLNUYM1-8@)xPVeR^{!4priE@yCgR6%jPf#;EX}ywdkC32v@|2{(W_Scnf}SAI@UTv4wf2R3WkSI2qLzY|Zd9jYs&*450K&;$WdO<`z5#UuZjWCl(34-a#yeHS`MQx?K#x)Lo(bU#N9`ef$hol{fJ|g5 zgJfDmH{=K3SBQPre)Xkqeq>5*B}G>!#JiS1c6Iw_eE9u9Y#J3Cbb+KO(p(RHO;0^C zYE{ILEeyIzEg?5e?!<25C(`XT&B1wC62|#Dz3iQnGzv&h_s7xKu5AApeE9^O=kaIp zJ@hyZ(extpoim`#=pUpZ8zq>;9f(=1udu(;r2ch)OJM=uTZ77My3Wz$SCR1(Ch)!J zk-u)3*=z7^T&+cHeAiB&z2S?oWCUFX2&xt6?~RAuBm2P8OfoS&Z|l{oTf1Z~=U+uH z*{INOzoO3+#bU&6fp5)}hPtp!ybG!7<&F{F_lU-&#K@Mik%gKq;e&~X6?J(3BGE@S zk{BDo-J?68vM}G?*=6~Zs~EGdK>PMTvxYyvhP2$m&AJOOOy2c#_UtQPOYIs%8gHRz zz4*iLV8dXmD1jUHruZ|E=nC=XFjisnJ`8wK(n6$(9vOvrnGDRYqE*-<@XH&JB+E+w zol->s>anFunBt+AM;5183V|bOoiV6>Ktn_SEPSzr&ui@6FEgctX3&M7WReTdFYULG zX1a=VX69r!1O)~f5~62L&CBi+90+4H624D!cxg@FqmA|Rq9Y>gxurGzj`Z(6*B0Tk zcleUwq_F?e=V)@qC-l_trS0vwyl+nS?Cgx>xTL_q-g%kxvon(5+G6y6gKiVPS7fN@z1n09ed|XBw5A`H~cNt)Q?Q;80>~1fZL4qzd%j4V)mo zeBAe`vtqRvZ$n_D8C^tn`r5^HrV*u^rZU2qLSibdr~MUP}^_W^W;Lt zr?oVbE-7*3#>6Kj#V2HDEV;cYU*zLMw)9>Ei2kwGK=-ZdjLf%P{g*RkaGrtmKPs%@p0e`G%E)ZU`55mqbPW}WUDq4QkX zMgsSbBm?OqBW_f|JKG+2U;EJGh!<_2IuT_k*^&f8MmZwhua6_S!#d8TSYy!9ODpBi+7{ zbPL_`&&b1g8Ox>sFI;{GvH*Dv`F=VLme}zO2-IjqAB`+P^}%=Ve0MrYrg{f|6G;ae z9;Q#3v(wTC+5U{`6`3&H7Ud7Mxl%mW>^}#!@v*(nV5N`K}wH?bpe2`P1@psqHan`$*nzBy0Of(PyN)?d1nm zwY^Ws#GB8j_qnqln0la|Vmh+j)sO3MtX%m9`&~Dore*^B<-S{W{`{(y7cM*`eV;fH z`VJXPmJ3yQt`-_|6zsksc<9T@Ks9P4MZ2=d5quaPOSBO}8{2K$ec zrAtI)gj8z`8SFPnmanr}450!a>Ss`grj1naiH4C%HO|cbE}8wRH8_#|WF+>H;B=8f z(g|~PtMw@zmb=)AO73K;Hw;Qxh|oW7SgO+>o0m zh^&7C>uy*W>#*6(y4?G|alOdIFM1oru7AphT7#QU|iai(f3%6&sZjizvGwKd#i3JD8_ ztF}C|Ykac9k(`vD^YHCWSLlCowtQ;)$6SM-CMdKxDzYrtsPY3cLkOJZ!utqu(N5ioWt{a3);N1dG5y z`;QRRLWD56{q+w%pexAz{Mq(2x`MmBWJtx+6{P>%$#ni?q+ouhzjqT0l z_l~U{IE|=}{yB9}->9Um5ji;#Ta%*t4ody=(UTVRkamIoGIzg`$v-uKx7SKT^A zC&sG+t+-2vg98*J4w+;7jlxFWmtb9w9=lsT>#z@8)3}9d%(Z<0?iCAL2GP<^W!J6B zh9Q#Dac{GZ?{q%+y=&B1+yeZwC=>+!!}4rv7q_E zj(cla^{>{GQzrvj(yEqz9LXtarzdxi%jI&ZdC}s0Sh-sSZNc%MUIeCE2B)X}t zTiUp5D$!xr1M+`h=U}?IeJcHYI{kK<%XPs0NUqv7jp(N1{hNH#54Euo@YgD(I%XZv zfpBjuoeQ!PvjIU@EVyD7YZ1`P!~eHY(Ab@H|7jncMC6w)5%~&`<>(4hHl21M&rPSt zNg4mXYbV#>YJK-z>8o2uT5&U0{-W>%^mNo^hD&SN+bkSxMxeB&px{wS6cGTz)MM#i z+k~AHChW|8qouUpJ`zz+*OOuO^!+}?EpL3t4oq~tcY#=kmFW2k^uqqt7vEZafWDzU1Mg}XwC}sx%>WSY><6pv36vrz?xqJq60^3; z=iJfS8zb-PN%URcKJ|DuCIK9)VDi(ce{VWt#R;{YP<7f@C+fM z#t4mtz06@U2CI*?d70pl40|SBoWJem-88xPXbF=;)1RV0(I1Xyg?vX+Ns{Y%F6?+_ zsF4c_&3wxBF?O2>2@cD6@2>9ukHbm^2OInK3khoGw)Ha^1ATqbsq#XBO;S;X>-bCWR_zg9${pP#ZALB3n zUbHlJP`bV2uYAaVg9~|Jt9N3ByVuZ?mX3Dosw`ds#4s2QY^LK`oL)!x4(${(1YpDS z2lnq;+}Pi6Y|(Apa66Hvasj@du32Jm;xQ3^&Gv zhldC03>qJ0lGPM#^=uf}5aFwjKrV*TM_*Z+lpJXE)A}e=!>pyHL7_^Gk7o!kSfWN( zlcitx7@~F!dbeGv^AAwzupXR`m!CRT?eDJ(Qiw{g5R#}d7=3gha(2Kk#^0dU83i2h z^Ck<%Hs9 zEh__j6-uOK=fiK^Sjt6rKhEZgx2e=B{Mb4-kg_s5c6878>BMTZ};n z<6zTsVExcwTR?y$kC#0K%7EicLE)yK2@UjYsIAodC>1qLh^)2Aj>_JWQ4$ByS&F$xig|T%ur$#~J z$%PsL`b*nv96DX9l6ivb*{hKzW0p7mO95rvnOTPT&lDT{*Zk|F?0v%j&Kt5f%H0}v z5AI(c6>eX8??-+0%( zeS7at?`wKXcc(-4J%MZxAc3%jJ%q3(U_b<9je>}50?MKSvP1-Ql+B${L`Odvb(k5) zVH6z|aU4e-w?Wi#8A+GlukP(m!s@&}|NrxTB$rg(TkAQes!p9cbxuB9DlyuXE_1N` zn5f*$4b&=?TD5Ch6$X&$$_OJ=*u`_QA3bop>(?x0;USsV&YQh( z)`r{LcWzuWfA0L*3uoW9f&OlNdcSZWSw8F62Zk$*;S_aoy1!qQ(QHpCikgjsoN4(k z2cM-da~g{$6tM8ThwQGj8*O@@CRx+V?t|54SZpRM)oQAZDX$s0 zQm(KE!sGLUi?lkMqsZ?oa@cfQG3@iRFlQ6-wqf;G%~Pg#M`6oF=mPSHHGxV17%Nw% zqK|M8duN#iE>R1h2?CpQuuc;aAI1r@g(;}S8}SL5E#as#RI(-9yXDS1iLdC;lKET4 zwCtR)ov3PZ1A*Kc`os1KJ6pzVnZM*v5&huKJ6n2le@zqK`Mq94tOV@Wiu#w`U}W7d zBeac7CO)n1_wTT?>s7LM6}j^NU@vclb$}kMO%T>de20iESa)X&rGS^>0Fu@#yu^Zr zb14)59XWcwfgDw;MA>DAU6n%~rXzTIFRhX9r!@*?T&Ahaqa$(WF!r@@m~SPS^psk~ zB#;)D`XGIe+d$8l%$92*3(8U{B`KxyAW4bMCqdZ#j{QyUJ^v4OR`3M=TPl2s{l`gY zgM9;VV%ZYetpZ2qGAqp#Oj}YK{o=aK7Cq?$#y$`I9(+fLO$=U$r`Uc2UBU@G_%1MP z;%^ix(qgIDdWh4CpNr2O5}P1?W#6PjSqvC9?ZnvvR=SuO%|qdF&VqSEVf!6B^U{kZ z!RS!Dc|{gnYZb3ii(`)|e@U&9iciF$1Na1tc@-M6I8N^F;j^YVJYl0b*HkwsHOXLB z3K~Ht5aRdrDDmovhNzJY>f?4k_BTNt$@Q4ITlr{6E)Y#fuot`38K$hkZmS7Xywa<; zOjqTDLT?Pdj^Grv%o?z8BW0V@fqC1f#lOR+7fy7?h;d2rgdG_m!vA=h@#> zYwvxkS8hSMs$Z|7hJo2VU`(W+Txm(A(jEc?45F1N z7k<_3pn?KMSfL_?I1`K81SP1Iy(}hBJykMgM-~IYiEJ(Ch|ztVeiY(2m{S663B@HK zbCFyT72v7w&abN)lr|Zf zf9o>xU4!zocjs1iJUUXpuW@d!Kf^)y~cD3lHU&y1b`v_4-yG`SaFUkxwIYyh&t%&+uu{oIVxNabY!?V!UVdeWSQ^z1p8)c6q~L08};DC1ck+5@R|&2gHbM6vu@@pwVIxU^j0Nn1l3u` zfZ~#5XBnsE{fuCn9F;$V`AQ(PbWQNewtw+V6+ z3O4%n1`K?IQL8ul{%wdI=c)mhBC<`fQC^9ANDk<4ML@?@?9^Tcm1xY3uwjp18#sbu zp(u(oBEE#l`f-%N;1QJJu?556(x5cYgf*K7p^w%0U*^85o6 zCr*6i5q<>M5ZmAJ@FQd(cf=KnDfqhl*ck3$$1J4^jwQ_aKM{DTp8GN6;@)%G)Jny& zptW>!sWrGvp;QlgYwp~)=91PE^e{bqf@HcJ9v6Lau5(X$S||y8w;?H%2+U}4c^s~* z&;S!du>pobgoh1R*a-D=QDu}T5y;;h%r5}5On?CgWxwJg#zO(;AOp6kXZw2ba2%U@ z3n^xagoxU$QL6rBA6Q)MbChwqjyZSgcigGp|FVf&%I!EBTWL1nq^F9DFieRQpolpb zdW^uk$!joJ;7`M#(Hs3{_+0I&(Z-GoYPFUtb0(J*4{)4S37X`XQ-9}n{he>T48mG^ zG}anh`2~nYrzu?vqWbZAP6492&fqiZwMGLd$pHF7i6*&V1AXhNL4G)sY9LE+4mci| zuZ48U7|kyTM2IcIIw)~@5~CIr6du~ z!Cf1BUND&TKD|M!(HT@)1A=CQ!1al3#aY&ArD}&mEg7OrvDn5tTL(;3WY}P4fvHFcjJt)xZ~$P;Zo7iFMd!e^79qSA2=&I^o|mX zuqoYSHYDL+BFMdz97HoFzt5T(^qP|3j|LuTl0r~`PJ~%INP+BSVXUALEsaW(wv6%K zY&yXqgv50)PKLY`wWgW$2IBg%^45SoNSDzk9km1WDcOZJ8QjL+ZB}xe*azs;h8{FG z))7`Dt=|Eqe0H4=Iw9LU`A$mT8l3c55B6o0g<+&o6QG z98fbkmv^&j?s=q61s7JHnD4#8Zrz5**W?8FQR6~o$!T*!| zej_cVB^%)rmHme(_ZcnOz@qq%{C)#1#eX7R9+6dHuf0tyLo2@n?uCC(Z^zH?5xN~N zx)N4y=vaU1emY6M^ z6hd-o2^M)t`41Xwv4K9f(SGv9;hS{6fZXoZxvg!>55E@}9F`Yo1VZ$J79u*UG#flZrA_)NULDE5VMl5C-u`T{l)Kj?z=e`=JI*oipn ziGG2O#onb#r|;eRX2t|Q%ImSJ+?s&FVEpRyEn7@JYlJg617V-a5cW9S<8Ju4!DQpi zrXLZJ_+fh5asAT*c`+S8$B={MC^<+UAkWe2*nV0~p5q!$ zu*eA(KEc0C4$;wxg!PFO(n_2sh?9O2 z`+-F{)gBf(!NMox*Re2N#i}7o>ti3X0GEuH1Ei`+eC#A(ItbW^s|+&VOKhj*Bg|Z| zILG6rvp9+j@KzQV#lxO4n+~yd!$_>O*cCW}Y&~P*Dn4mR%M$~uGsF2VS2(?2|0i0P z46f}vX@qCEd}(p96y9T- zYHA1F*z#m;bw&hbMlz}g9%;F8P;E^U5}aR!1e2==3|?|k0ya)mvS)t!NcfNN4aSKH zyLktsI$rRyY{XcCyd|i`R+CB_Y1?ee(SK@6$fgL!R&T zzyoCP0}nhf>#c{bn>FjYx9N><&7%JlgTgm3sBja0mXcLuC0W@*|IUm#6F>1k)AGzS z^rmNa5R_qTCS>K+Nhz0R^;$KYm{sqHgf7bJOSc+r++9~K_KhpI=ndAQD;4{5 zEdu;Uf_A2Wb{PDnG1>(Wwgz^A7m{S@@C@Vfvfu@O9+zr%X1Wl(7|)V2aTiV)FVI;W zD&x~K!v>>Mla`jA8t9chFSj_Hnx3AjajUF7qWz`?ak!?5wv_goni_W6Y|e1%)Lx}6 zQ4P+bdraw_6Vw}BnrM&o)Npamyd0LbM^xi7>Z3iXnxh6}O%<~SA>I_TR!mCOm=)Hv zseE$Z=9I1kf#i!4OsTp`*+18;9?>iGD2-iz5XbLF7{6bWTtpbm@x!SBR-4QloE-WO$;3OJ?IKyNjQ{r>RT{*^MwwYN%&g{Qx66tTXq3h6@_7(r9nx9!CKAyYtS+$~X&S9oW3`|e zUMD&(_TS=m2w!V;X7m$%aZ81WF~7r=7B7RIj+c=y7OSgW=S0sqicc4FEV4Y2X)C|$RN{#m7+Gql#Ru==Q+X9ewYm|ryy_rPR28W&1 z?6ydCF_3y)7F}lyAdT1D1yTlW22!8HZ2@K@COw0qHqGTub^&1wh$>CDMv3EVEatdL z!ncg`vWOc?bCK1|D6N3)ITf4@4tGI^V|Q(k&Y##>RQv54W-XkJ-Hj~`z%q;}B2y0J}k!xh_=8mSxb#Ej{W4H*zkO^ps1^4RnlPYkGwr2b5M zb70?MHTW1cyM1VZWeWkaHUUnYgM^0?DGBCqdMFY4I6ZwJLN!zqA%A&3ww3(*dGam! z_IdK}*jD~mE6E>e(Mmcc_VFM7z`6M^Vo%U5xc5AZZs7)#S%5p&dH$tlp5(hq=fyd$ z>zomwPaIP5jfdf6`uJh;Tk_k(pEVwv$&l=oh$aOfKj@;ayJ-bJiKF?iCbDTffI^9|MrDfH9%1ZOI+)gRhr&^3bj3GhiTDnz)4lnD%K@@j3yJ11reFXq@ zcAt2QOTb`W5l0)lx9_6HULAYnz5hw$0YAPIo{WaPz^)~zglhpyl(E3^7IuSU<786w zUX%)1>({JLgT%7Kigb6?O*(*wBzgpwtif2@gB7N-dn)bP^T$J86sU zA#I)gP6Yg9sP1p>^ymT(C=R6mebmo`H>ek0%*V(%a=J7YlNpH zO>huxG(w`FT#Ezsu|5<01{G^)<>7twaXNF~VOq&$9p1N#w8x@r=rA&I4IEcbT0|G-kJ?!ivAV59F z!W|>M$+kUoruZNHV9(q`w$f|&$YtaWn*KTc{4+eC({%FY=fw8;XM|lHKp(cF%w&`) zU{56@@C#Cclj;(J?J#k$3*tFJ4@ zXz^s>;cJEwcoE`iV#lB*nmKG3%_PmSV_Xfrhny15#h!+|HM5?*ZGqwOTG~!d4XZ~E z_%Kp;?(w>4OxlBDHUo+w3z4u<_64>Fej)Y@*Z&2!3x0u>k=W~A4!(`olgBYn{F~}9Uktte zdO8$;b%=jS9v9A0*h{8E=drhDgukU{$>Z10LyohTlzSoE_{M|ehIMRZTSsp_c#z(@ zj&32d*1_e{Iq}t@Zm$j=LelQ#F^UErq!J}uNZ8=f?*$~OmNb7!#?XUb(tB#@R|^)< zuWIQ%U($nQ%$KCOmL#E$1JbwoiEjtUSn1n>`BHvXUqb$pg9rwW#lhpGB;pVt?-7&{ z3?hq?-41~#7Z^(rFew!UBPDE<@g=;k?ckh)q}OQr5^2w-%@E+#kR92yg_Mn^zdJDJ zAp1;T9!+}DY1w2a?T-Y_*<=SjF`D!|Fb7xepTj$3m@bxaXwD&II80x}S9(o0*^bhl zrPH&?F8UJ6Kv`{v<{ThBQ8qHMwm*n5qX%8=LgW(p1^BdXoPT_8fm2-R$VfUej4SDh znirf_L_ajs6_$|d_X;*5{#)G%YrZCt~QxdFXM4)y;K9_L(qdL$ks zjr-rmZvDjvRL*i+3#NmlJMyEJ9MOu=EY9%4RzIS*qC&xc#TjM^n z)|EcnI&?=yZE5bz-o+#Kk0|avGdHI`@2;WN$F$~sqjuMaa&r?&GiTX`^&Xo@dw3{I zTQE3h>rm_CI?G<}MU6GtV^&TWkU2SXKtM6Bd0#NOq-00a9}0&JD?B-7Q=gLL7vVS(u7LLfmrUgq4`B5{G1P({{;J#ZK4QTqP;9be$w7N|Z3cCOZlG5-t+LmiX++ zvO(x8URq!Q)WYhPS_aK!gc4!a@t z*{+P&Wh64D2B#I!?fv@rylPERd6`ns+bT6We@2ZfOx_(3cGYC~b(%_>UQm{m7vXf; z*N1<-xh{WrKX*okyWjBqI(kGK;7MB1fXrym%sQVUHFx^D9vbVYrA?D(0`Vo+Om12_ z%BqRpc1=#IA}}DcXEbwQVH)8BTCE@X3hFXbduD-LF3MLpvwJ>Y9m_YM2>JZW&2o~G z5_Q_(3Ed`lrS%$JS2wy>noDkjPjs6zngY9>jQ7RyxS~dQ2wE|VuQH!T*%HWb-zASt zfk^KnIct=O2&K`LkZFrUEfJAQxG*Lb!SCB#QCR@x*usL!imqT=Wuz27TynE|WTs_B zN^{10a)ViEnLV;{^KZy0jpX9~P9zb@O3RL>h8<&bdWGUi$|`fpdcd>*OM!4{BrDA$ z*SeE)igpYGmwQXMMj6ini0LGvR89>!gQnH)NDz1rUSZy{}YTnRD z>ezTVySZ28wV@Q7+~x_ha6C<>p}I4i%JNnLo{CQRHo+eJ26#mLjqFYA&HiVA>Vo@! zg9VNy7nNAp&`GS2jDujxzKj96V8vuUa+n}DG0wWa7GTn3Kb`9;cp8RZi^vbfS6XRs zCb2u8R=!d2<^oSQTDxpL9a|j-?xk9Bh=v^LH zz&F4bz+c{}RP_x7s&jmvYn;iQADr?x`JD7Nl``ZHBc1fcCg(~+A!ldaWal*=Uru%4 z+xmJND=V3O3j0G!Ra<(_50RmHK)j6+K}A_}c8Ws);w1!Un;Z^fk-mz(XKC1bAXxu% zM8lW5d3kNEHC*X&;x>}O>8T7`bt~k2tXX03W&1LxI;z8=#7C!^9J4zH&dcp9=UHNB zWmNp8rpE^laV81~g{vJ?Gm+Uq!Wxa5l^Kdwil2FT-`sfv!STZbV`87uLpBOD_c8Q& zdy#1{4|0IKjx~XCp%)!;F#=)86j97(V`hh?1b3I%R1CW7vd03Q3eZ>l2u55&*oj#P zN>Sp1EPd)y2?AxX6Bdb<*cpIyG?vK72nRGLwMPSkeO)hoX7xu3uI&b;(H_sNb3!Nh{2wAICSxF&)*~xpbhz7bW9rC^tR88>WUDC< zEg6y$N-`SFf#fmykpRqBBX#zO?y1v;Wo4$P!B}-lD8D|QIAsWV!D`&7Rp6>4R5&ey zoDkf(F&r^yj|L4k8_{Ue3%!ASo54apPtsg_tsY*@H5!|Zy|n9vg;vv`L4pQ1{Ioia zn&sB21pWan3Q$1UMdX4-r^W3+wL-hmWSL*ldPiY@OLsQK7f9cQzY) zY1ga&q%};QBxrC`KrW~?$ZfKtNV52{hC6t>&BJNb*e1EL>r!htkKIa7Jx;k&KG>8-EK(g%%X+a)}3~HGN-{m6r#ha0q3?`OEp%z-R&%QyYW}k;E_b@|m#cKx3d2vCiA8(SgFxfVy22w(i zwCwzFTELeI+-3IY(dXjiQJ>M+r$>*5QQ;Jpcrwza1Zc8We?$*bVlXl5bb7rLR<9+1 zS_}MMj|+>V)ez*`M0nc7S77mMHh@!Sm^4{HHyJq9$ZNE#1&(?xri~hf%B9!qbmlnL z^+ybvr-KF*mErPu{RLJL=~^Hild;V%z5{2q&|)4`CukikD-0Y0=fFJww<}mapTVi4Y7jc_A5z4~MRoox>r?9?z_EU^pvetW~5o-}=!pojMICx2%>48iN(oBKB`^JKz4Dnx4L053@*nUHbdtx!_ zSvTNdS8(JNjw;&kp*P=0Zz3!2Be&dh54q(&vXb6(AH7*_u{+bUTg%H@v(ub7Z$`MR zoQ2o;Q;JKsjT*YGtf${EhWCj%^W!1)nVKvIk|4%U;0k z4#aLSSwhYam+!EuzV&c(fp2&lH2%!X&A%@QvyJOM8>u zV#N=WWu4m+8m22cBLnD)Zd()b7FpIU%D+yY{$JXpd`oMkn#l`i;=2_3r$mSpoax-D zobL)kUI(K$0)@Q34`?VV`I;yyusKZ85(oamN}#Dk`s+|el@4Y#P#J}3!Kg|4iyS66 z;46}Havz*KUcTnV@)z6K-?la7$IrDP#{ORE1NZs*xvfLywa(l1{%yoQr*+6b{xPI= z4*h)n`@8URNbB77w{?D}pC!H%`)!Hu7!wexE1c+q7dA*D;=L@%D;n(DFv~VPEZamN zFNH;>Xck|BKTy7BR+>uSx4a~R2QR7!-a&dwLPT9ozawFKh6TQdIGmoL-JLO;YJRC1zpc$vnStf0*EGM}{4#zq{}I^=nOr=NVYrZBAAxIP3Fdl|fIa%s1$)7i zfPEH8U=JMy_RyExTh0;PiH7p=2%t;ab1k=zD{neM|APSgNWVWZzPy2@($eqouBm+7 z38F_pc%yarL$}dacM;pZ!q%eU53S#^>$Zo6Be<8?w$qacw@yO}QnZ79zPG5gVEDtg z?c9O42=1ky?;^zrqf6-1-k&~FSTN7uibyw+1!xIVfW*mmmz*%MEzA&!&VEE+KbR>@ zi3{i5MI_?JEDA1EbP2@flg`2%CdQ(&6`~;SeE>wd+?Lc6*Xms=qKN2LX3ZcCp=dJN;Ct^@ug%KaUo7BW}0Zi?egw zQi??G+iyc|w5;<3vf{FgnAO8Ru)OqBF>h9~#{+kSYS|RvV5IO@j1(=-vY5rJY*->{ z5^d7N{TncCa}K{z{1Rzz%LGr-MT9usnC5gsqldBDagc)F7tz4ph*=~=;J#ERQba+a zggyRT!_tO^rQ|_+(`d3Xrl&WLCbw|ArPxzq?CG9K4msiYB*#2Q63-F2BdO=5ukI~( zM*4Y2^!N1%ID~m5N{fHlgzTj^0HOOR;@Y~n?ZVvrhkR$1R>exC;s=X=$TIrZ(WFOgqWFg&cuB7FPh9ef8+YZV zbhc82?;V*e@v;EoSdAd zp_9oTO{y>XKmRUG(~v!MGK&c5UXPMKRZBQ!a*y=$Zy-hn)>4XCn%|qA<^|Gg=~GIN ze41}WvXVkeVxZC!+cv`I&4;~`Gvb)B#bewT>AqyV_W9D%%JDbZ#|`nON4>~agKWv? zcZo5A!|11!$tV#8K2?LNJ*fIk#K^!JRE?OR_p%mGA@^#c-q>hyjC3@!cjR6=1@9RB zvU6GqzR(1U9|Z8&yNeU9ICo2?ZWz%4vJr?1#0f(j?*xv2@g7hD&@4>m#a@e3i)3hr zO&P$AfGxZDnmLhhz$FMv!Z&8*goL3a*~S&-SNna18W&wc{^rsRPRY&=*C``3jjT`R z3Vr_Sj53XxemYbL<&0rj=%;3llm+_j>uFj#KJpey zQ?o3C-Na5jLlj|TNs$jF4zpU!VuhJNnCg4WXFwjvh^Iqe>t*2+=y-%=|2zipT4a32 zF*xy1;O|kH-`K|k8#*%P@drLzWa9n7G59+j&muf)@NC2L0G=oDyo~2fJo*WJ1ldOj ze2a%;kYmIIY(tI?n2lV4|@=1-&0QJ=2?ugU_fSyyB);M zEEX|`fp(x?Znoib%F|>MNyg8nC+X3L9->E|fsfr5qNWHWauMqkBMQWF*lFt!#LQD4&3Ju&j0wDsYN)|@?+*mA^XSI zMv6gXWp#lEeOyu6RhNWM1~RBfh{b8U>XI75>e9sP(!}eEu&X0Q(7{1n!Yw~$qB^mz zc)e0xo&ADOE7mW$SU#&u6|YN$y0lWiRGs}&#OqST>w-yksQI#*#Gce8ItK;I25hy zs7wtyO3DH4s0|0nNHUT>1a}*w$O!sy%qGS0Mtl!2cv!?A|MH`&8{ z8pm{<6fzGZAVxH3IiGV3ZzS+ANRyz+Qot8*$@I?qZyB+RPb0HQ6@3B8+YtU(%pX05 zsFVfn_oOlisESb}0f;#~!bv~_HY7rpP#c-eio%BDPWl3=Vm=np7XD4)4P$B&CIR?N z{D`1Qc#k^xJ>vV1#rGex_qfAU`BSwbOYvvX7qg_PE}kAqtQ`J_BTJFpiyv5+g3PF1 zxB&jyZ9!#7G^Tms=~OWTD|f~Zdm}c7!-gBE?qrJvHqIPF(Usf zDcC?p-F~9JvTyy+$NJS~!(+y^Y+7rww zy`>+SboS_TpPb15amo49GoR{R6OFjs*#+}@4{0gM@H$B$HzsxvecS!h8NrS{hmCph z6SeR~!8mgggHDKishRB`I(v*I2|EVq6W_S!hV;zT=-S6uta*5CG&PbpVcF8cqRgy} zjI7L}!mgljF3pgUI;C)F%gR?@T{->6!YQd?TUtkr-I<;}v!Z-vb~=*;AzWU;!f4k} zv}-!r6@)J?oEt{v^kUVBz4WCkH66q`TXqO%n`vmfEb_B0 z=Ns42Nyke{iu(82*{5G|QO}-5#r+WMUsO_ZoK8CQ<=59gK4^V$A*|bZiwf5b9lEZt z$P1fxg~jU!9hvhrfI}L7qQWWo1_~h}UN!~p;*0}MK%^rKk&O_~L(IadvtQ49yiO`J zxwvrc(4lJ!i<6}?>yFI*n)_@$oqW8ww6Lc4(81OHiVJ&{78m!E!o{V>=|qgSWwLbG zHQ0@{c?N0~#ZgQcC7!3_HU?uMVcZ3A>D1q54KiNF7-ZL8(Ksn>C-1{r$2due!C|lM zEFTkcNuLsI5`VYG>n!%!Eg5xlY}pgXEG^5Tf7~%+fw7>tioW#9v6qQ3efSXLw2%AO zjjT#bcZaP3mtp>dMXmXRdZZ5>oL68hA2T>T%a(5Qm-b1wZkp8AM}AFiW>t@%Imy#2 zrRVK+!}<=docPY7UPGGGS2ecpxQ~))8}9C#d$3?=K~W^t3xi%+u0ac$21R;~^am=d z#}2J91;hR-bJ$jzoK_PoS~3v_u$*iU?5ZNz>EccmBp7P-j zO|1d#-9bMTauiWn0KH^W1AatOV?3`71i>YAEFj7ha*iF?yM9egzka=MU-jUDW7oA# zejpA1Mh>0UJdb`@+jrgS2k(F8HwW(7w5Fyur*9?waaa4%$J%$Tys2Mb6yI4_3L?2h zqF_{_5e@`}7i`Nd5el1{$sO~Wrwtv+DtKUW>vhKtJh56pUe~u4)4q&wUiy`MyTXLM5-hIpNbsK$j z^~x0r(-*Y-Z|~DypMOMNBCnF;tX}do*3r{gM+HQJ%xaSSG<}yD#Dh>xhHqd4aAlj2 z(+GD+>C_w&!Wj5ZNR|Sc;1bD@P%JYoJfo^dm`N(-OKFB z?TJk$FLGOAvl7V?WsXMLstd}jqE@k;UtG}6#Yi`~dzp*Hc7Ar5c5*LLi+ljmDj{oy zVH0RVEBVH=GwH{~J@f3=voncX_!A4F|J*EU;m=8F;qMn|qa`dYanp}yo|Qk#a{XAq z!syp@`nX_0THMGG;E9(xEX5!!!igP|sbDOuE`SR`so91slcjm554I6&AXQRurvHgb)4X9%;>KGcYBVI6^ zuyxji4Y3t=6%#eVo$6kc+c;H}||4OA+PV%yl@R%XHjo~qfibXsI zfyZD1kIcbK5O@p%k3rxu2s{RX#~|<+1RjIHV-R=@0*^u9F$g@OPr#1Y51-hljCh}p ziB^eNUrl(QhB24TNf>A?YDSR!|LA8 zz47Nq{Z%}0Q-JM{ z;v^mxN7(Q#Q1-3}F)JWuO+d^Fh*<$KDGe(|e8|+cR{zTDW;}&XiGgGcQ2}-PAaBYUB8+Q@M2d z?K}UBJ#ojD$11e-TkN5Br{#h<$108(^g(PnqaqCe$a-<<+#CtQ4P#O8GDLEm{Fy%T z0+|&XeMwUmb$rZE7z9S3Yfg4CABY5F#EmUAtICaP4e@H(@*rd2#(SCZ{~Kx$set+0 zc7qDspaM6jzzr&Jg9_ZB0yn6@4JvSh3f!OqH>kj!paM6jz|Dw}N#6pX%s_%N1E9lh>18Or45gQ$^fHuQhSJMWdKpSDL+NEGy-cM0A~xfD^RBzG)>-7L8o6 zcI|?ZiwM7xyjWdXQC(e8S$)Brl8QOy)2=y1hB?F}%^@bh(v*Ou39vK)mL|Z`1X!8? zOA}ye0xV5{r3tV!0hT7f(gawVL|C#JDvB8@iWw?PnoF`kMOmPtEKpGvs3;3mlm#lv z0u^O}in2gOS)igUP*E1BC@VolS)igUGzZwZkP}LbHZ~k2vS-5~U6w0iCmrDs-n%b1 zm*kr}QG!_n(jBI;h~<|Trxyu7mm;U*FDE{Io=qY54qL9l6p}qkRKTGOMv|hMgE8< zK4vmdN(M^FKq(n0B?F~opp*=hl7UiSgc8rwcz%!PZ9L-YniL-|Nob^o@k?kh6C(3? z(%!w4b6^|;G!0Cl?$deaP{CY&Db&x0$? z^3t7oW^Wi**u^XJ5K{^`CS$gX%%anl%c)iI|E903S#{l<>+rj34Jqsl$9_dr^zX#C zm#AX(8%WdkZA+IeS+Z>Dw(a!(&am)y&*C|A==be+)9>fZDelQ)M16NVQ6qN#CVo@T zyLz2JvsT#OyYi-G^weXA>8WKmRrY2vl6m+sl8M-beJYmKU%gM@$l+EtF(E075Gjn&(mMjWa=_QpI~@k@XbyTR4I;L+ngZ+kSYZQjhqt0y%! zP4)UVJCYyV*s_*aUllU)ZuFjv9Z8?7K}HFq0PvS-!w7|~u3ymo_h>8Gp8m&!2lwKZ za>g&|?7w0wcx}hGYnUjYo&Wl(ed|7!nYX^H;GEqQH6=*>0@Sm;*e@C0_i;B;cc?aW z;?r~Q3~C=ac#-s%;U2C7oeQJIcxdyS=Zfs^QnrZ<$Dh3ayE`R z@|Smh{pZs}|3Sr4I`Nl4BX--?70b76TfSl|`SC8V@2z+G4?6wq(f458Fbi^Wz{E||eKx-%B!{t{TkGMBuyWa+iDmh^XTyk^q_4{W+-quaB4{zJ!(Jv4te zaW}QLHce=4B`1FdR^7)#{?CpFY4R@-89#AP311g*in$s` z@>{PCm@XRff@v#-CA}#L8tRhUi=2-nXoq-TDW393`)eEo0t_ZNz6@ZRD1l>HWl;%R zCW6v*(It!*{n>RM4J25jqSDf$F6Jm6^Nz~Q7&Cgzn2d}sN&fKq`r-7|J@vF;!?vxr ztb{IuAi=4;s;az;Ws1inrfKDx_Pf`tOfXF=*WBGM#{RhE#_zxV?z?ZlS+->Py}JRb z*YCYooHsJ}c3i`6irkgj$xm&)`?14!Z%y!1Tkk&nm>6Sn#l*a-VUlD>x}bglxoX68 zWe$n+r-+P26{}H?Gvc!0+C3G_D%B>sVU!zM`VGNo8#f z+4T8IYu5_i|E|5v4~S&-{J)WLUb*dZ#f*7>JzBfBscC!ljVqS5-ErHhE%$C8yQkmi zdk4S&%}Sbog&y!O&)Sxa54zl&ecq`}jgwX{o;j~AE!yt&9e;E|J700NUUcUnIh=S# z(G!y>=Y+)xCg%)ac`|4R-!q#gah|=fpfTqPjgvpYc$=8Eo$)qn5V~4xx@f=)PsC_R z*IM08O3av-t8!|bx9=@|7-KSK$AFRTgWfs!=?U;G4&&>btb!1NzPB zKmYojzZ@B}F-Lb`Px;ac>bXJ(_>3;z!Re%r(2wZr^!R&6pFKUO|2uENBj%y2fxX+< zS3q*W#y*qVT^aS{O?cF8-A^8mU6Bjuz4rVW`Sku*MRzw|PL1t(2J?$5K`;du6r~V2hWV=s5X0Mb{Z9WC#Bj}j zyM}i07FwL~h+JiN3JBGBg!93a&P&)-3g@4e-T zBipXfeEA#SitF0<-!2z90MN9!tmVW6wyLDw75TYU1q3BqDBG#1m(OHcUhKpf>lz6v z>Zz0dA2Jt28lsy?Z*B#3lDX%|T%_-i%@r2NKV?E!=))5a92R^Z6Ao~{K2;MNN^awh z9E=I1FgCPSEc+FdUCPoDp-6zOJ^792&&!2=oEv7U%Ja|Vlex5xLcfib>p{6&q;jL+ z>Unu%Y|sJjJpCj0cnxol2?x0&r)pzES-C`|sOLLan_-ApF5voQa3S~1e$vFvify6y z?~nE8o+FhV%a(P(PBiP|LWNhp31f)qk}H{32DbVlH(W)6DcM|MC07uPYd48@JRHQX z@LElDuF+{P%ru)VR@1SLoHTd+m&fCSv6WCool%WCX9&yOm?0>Esu~VX&u*C4_n*}Ags+@u)8Fk z^&z+


    *Toc{%?n7Na{@W#kyM+}-t@ zl`z3{4HI>%paEfoP#so^%nk*Q){2G33zzRaO6gHLr@pK3hu70rSFNJ2u4n!>x*mq# zg|an@o8-$x{Bq0)xcnB6egst72ST=|B zI~6{0E`YVM2oeX23Q)d{o$Q+U@>oyqcR!L(sPiCfT(!n}?mSEWeHJr?lT@B1+sXE` z^f0UUzc0u7Gv#E!)?cIiQ78w4u3_Y_1Xl=1sHg;<<_WJ1@);z+4_x2!RxEX!J(j`$ zWj(j*@cNFYUW7u;zt6_#37UT*l{hbK+l6Ho1*1g;#Kyx;J8TFB9Tt+oyM+r^@Gb6a4-p6bK`B|O|LYf-eIZ8~ub^HRe?QFPj(WCengv2Eig zpwxWooSonCM*i3Ha1j_~cD&9#O6t%?G`hL0h1C5hwezy&mO$Y(-q>#C=JOf(@sd04 z>sIbyQrA+}ES9|cf^rEd|LHB^MfoE*ofoYLiI*NO(m+jx10d#}x;)yq@wz$7Zdfp5 zVq;Uo#4*>;`5wWl9vA?BpvC;`+P;n1IXM{<#+_My<2#cYa#^@?;BN8<@`v5%gj%+O zRAUV}j(I@Rr}oKGa2A!0(+XH*EGU7WysoE+XDF~c7-tP@p9N9))$4k=zwasEbEMnT z_6(Q&47v58-~RR?dc!lZ54lO@@DkMR;Tq4y|J5^Z1H}I9iWSciJ3_7T_YBUw>{o29 z6)HPt;S#V%4yHm`5{2KBAgloslYHMJ%Jhx*SJylO4=7%80L<-JGMelsOCGK1d*7yX z<)gGGnL``M{$9jG$I_2c?m{vZecy-mlg;m#8(7zhf<;158H7bshn(&_dUPk<9(xe( zEn@pmoWLLM;1AEXv^@Jm{fHC9ed2`Jz6XDLNnEoNt3(vi0kMryC0w(Zm<8ORe8wX+ z)%R~qS3dGnDZPX2rwzU6M`)ghf8kMO`sRIoYaacnCmOyV4R2r#$DH|Kyx-|ej~3m< zZkOp7VrK&ehpCIQn~KFHqOVVA{;}OKAR{c;^sDOr1C~1(K0`x5K$P!VTzG>$FLwQ=%E}?B!BQhoxux0 zq=YT%5c=2vKqL)*7Y&DzZ~0#mqSue)8dGNiK*V-~ci4F@9Cj zVRnS&Ip2|tf83~JO7P6-rj6;tcT5U+MDLDd3O~JL1$` zk@D54!xz$+mnp$_Da7ABVvrlqGpsHyU1>-%yZt1@l;wSXQCS}8OaV$4HM8->$+i){ zqMZK-C&hrSMQnF`&an$};8?t!1*k}Z(-JmH#9nUe;|o}$(Ttp;!t#QBP*0t+uXJ{P zLA0mM>+s4I5&WCl(J>W&xD~0rsw`o%#bOUkA3S(^DAnS1g>rhOMjP@A8lqp#oA*_; zp&*}$>4EEgWQ-!8e^|zvXJrl}yC7S|RISkzkY|t)p!5|t#YFZMU*S}a*{#7(0d%dw zw=i#&_(2RW*%lEA*r>q|zT>MRU!gcBS1XN5B^+Dv9$ujkR4OI?7~aqng1k}S6)J@) z)~+(>6nt4PvH%GbaFoWis1&e-Av6NNh!VF_1$V+y0eE3ls^#Yt+-+t9N*8#r=L&;b zu5H!|$|Qxr%ke@`9nru%E3eSu+QPzxR_+rx>qeDu<*eW}M^plWa$Zm*DFx({tEF!O zijBib_7&D#OB_xTKM&AI!yy4DShc(?oTB`NaB{#DK7K^E+?T?MZ3F-(Iu~A);r?xnpW{PkcSV!6uaM~upX@vx*rZ|{bb`eZ)ak!bmDM_H)S>HuKDOIO|gDyaw z>jKnWcUd`7+8t7~qZ_DH$f=BjO3sR8u)`a!ch zJbZe3iG^D+Z1koBv#+~9T3j5xKkwlETSmv;s8~IqW#d!)rXEjiY#Fe+0&T(l2>Lj8 zQjv;tb{R=0(J-GX6K@1CJ4U!V3aYagmvAT5ttE5-N62+@eqyhzwFPgyM;}${Nb-pO zR{FShBpLBA|LyQ$>+;?r8G*wnq2<$4^Dx#1n zIm}4Ito=ujWSx>e`raD_YqNSyd7~BJNFvhMrOvc6${UwKL5Hri_eRx zIyPdf!O0%QrX&|S!t9B<93=f}Y}*pF0;@E z@gTQ?-`p{`W3H6$exz%a(jk$W6mYHd88GiTzz zrZ(<1;oVqfTT{%+Pka6R3HhU~t>+;%c)ep6_XWP5lG;1&r~fF%32(4+Va3-00E$lu z0^$RXJ0q6ez1&!~k~`Jb#C_4R>vehQ`TEvY`J?Agyv|RHS)1BonT%d!vtT2?pA6JV za!W805>q866a0wt2Zl?D0|$a74mM`+!)~~+AMsW%MiW~kxM_=fj~Mz~-I(&~>R_mM zA`C}YpS01oM!Kl&Q&l*3+^7ZDtX@9r`mv2U+1WXbBNwvROcHFX3I&7Fvg&;k#tk3Y zJ02O{v+A=px`?cA`*d={_2WhsW@qP)9e4fQB{$ENVsNa?;5|&X6nz*auE+7#u(o&J z#fZ1o5$}Z9vCghBE+XD-`Rs`^XDwfS&4N+ma#7W|hPjDYSoJ9y(n#CdK2bV?)#YRA zo*O!%ckfWJIuRy$jak{*g(K0to0p(@V^IQ&HB4qX(S^^ddJeBHiw1+Cs@@}qkDIVB z9%1v-PybN8CxoHo)KfMD9kM~0KgcF20|`itjbD+eBmuFpj$pJToInlkfyRBqL?P>d zih`6R;ov~^9$nn_Dcz$D<~2_}OTRcfwK*@S{mpMQDJ)K`ES{nvXlBO;Z%$|$JR}wN z*B?Ge9#%V2hYW5aWpusql1Sul~j;vbXP@5(~!Z@*voVmnO0WJ!uW@;><~xRB6~&4Lq4XK-ExFeE1)BF z>eMUwz16+B-s)T~S1q5A*IUEEWVlQrv@0|+c#ebQjF-0)j�$)HrBlgX{^OQ>l&R#_}Voc4WraFOKl-NY6s!EJe6+ z5rp+lWeZu?_Nn^T?{4_CjT_y_A_qTh6KM@{A+5Euy)s3jy~DU+>Pg%rsl93iM`VJc z9X==j|7@>BDA>xDXsrw%-`$|T6%CeQgU)ll8mU-a=pA=kCb1S96evjH@=b&aKrhg%%C^u+fi62T(1D` z-muZ8QEPQt9pJ3#mKw{xN+AH33~>pZNyvE$KB<*FXGmfQ5|LzRN0kgUT}V2jZAZc4 zJ4HKlS=)s;T!RruP8@xz<)5~Zbqp@wBNRs?2IFFpc13h{qdxR!R?q)l zn1Bqx{{+?f?>5ZfTx}CjCL@RmZMge~{0Vws`Aec;91^W4QhzdI#&;W3=UEQ4V#4j+Bp6|<&Kx|*Wie2RbWX-~+|TkR`o;2MQo$4x z?-=nPJg7R804Ei&q!r; z^(g|r0E~61*)Np^jFkL4wE=xg{61g8LmODmfmq^y51pOR7!W@HyMNy@ zK|l;8fQWzyh=34+(iOq4O0z}ftLRtB?d1QN+1p$p#Nhu&xVtSgZ(f@>Z`zyfI?nvs zphG-!!_W1Oe&u?nmsjySHPjs^R~qSUSAOYjj&H^9jQo|QLHPp5%F-BcDo!iU;PmM7 z;n#+ITsR`Xz|sAkC%^BRPvBH}V^JyT5ajvj=VNX^i~dG`XkohEs7`oqjzn zm&4t(dcvtZjb29OX*}g|cUmv~01qlpW55G1|1qr_5B@Q&0k`rz@(hlzUSIjOQD5)Y zANO}|@-uV#+~0Zfo76@5ccnpjz@OAL^ry1?6{T@2zshjj_~3?*PQSPQ+#4U4EGtT* zmr;2dPq|c{)>|hkD${^hm9%a=0N*Mv+kjhn9-V)>Ja}EaTh^ZXP;nYhc~+dp6OPa; zK|@7l8t@FBRFuXWUS(+wc;39I3f#)`+@*i_q{$OsA-jJ}tCwB1w4U;=S{{REdfuwZ z?SArj^X`7iscK#}iuNp9#q}2FS7Y#n`$7Df8^7;*=cW&Ly>rV4`55-k6Sk-Q^L*!> zAN;zj47c({85O1RhU3N$FL;KnH|&8sKE^xl54yKc6{m62w|kUfz;V@Iz`bW$H(j}B z8XYgumZZ9DT4nfEEv*69jc@maugk;G|BA~t_y>4*(c&r3s=#sauQGTB|0+u3tsj-8 z^~BG`zpB7R8t|oW0Z40 zd3Afl+oHR5)8M61c13AC^`k0qTzswwo|}CXb*`c`o_M+VT2We0{3=iD4cD8G6~Wi@ zxb*DaX$<>UwY1*)`_FJ)e637g291Dc*tGlRb5-Db^R6m+^fU$?E?HHUSC_A_n^mNv z^0c1%Qh8c~m!5c6p2vW1@ZXSgRpeWhJO+Gk{@+hI_n+6L(^W6${_+@b4P7wqtHL)U z?fv96czr*43_bWad37A`)_DW>s?%9j81f7@O4+Xazx>+pe?9y@Gxw|9-?{16UGFNW z4|k<;v+sAk^Ukl+e9!Vz-NzB!arB1c##^^Cb^7(RLKofMasR`E4=AhhG=`j@1OEWW zuy2*abJL-JgjbccZanx$S`0m|Jde&lT_1$a`v*KLPUEIe0xy*L4{%)kt0=7j&)`W# zX}tBLva|*~Z(dXdZsmFI(!VOw?_oFZ$t%6=s-^Xmch&M3Jk#@5EZckWxhi?Qc~_M@ zo^(`b2i^Fk^WW3|<-X;JMkydzN`GzE%X!6F(PE zDoX1O*INdjc`DXl&ouY6qyI>oxBmV!To+#rU8yV&-U%G4lGf0x`^n?YyZb4pYI$}3 z>+<#XIV;n@%F}x4OXX=R)|blj81M~V8gi~oR^I%tERO--n}?OTFfudfWfX z^LXlasXVQxTwVM(@UKX}4fqCMDog7P zzbbhQ_y*jnl>2XB zxcUE8YzKsof6ug@`d4|{iuJDYJf7`Civy!**(l;zYB+{qy1eVCieTO)V-}53SlAV~q9C^8A8=($Y%T zLyK4n_g)Vz&o|aXJH`|gDC#}eLlZ2pR(D~a5_aul^OI|*lGvn#W2NdnN$ZK-MA)Jv zZ=>}!{5nP`zUN94m9Nf~{wXiv5k(1+%KiqN3mlGXTat4}QX-D8;v1d#E+_5WlQb2e zmX!W^PWh@d@tor87=g!U!J|i{scNd}J?wkOPNZb)C*prrzS#(eDw>^JS`ciF|H$v2}+>&JpRd#j()XiS*%=QN#N6Xi&d?gC0-k@ip%Kdm8ushK*{EJwmvX#rpUp@uZAD>0PhBQtSJ1q-{c5V}Fz9UMH}_gBI)%_M{~n z+t&3>sRk{A4zr0YbQ?l%zv3mU`agS#wfseCu*JNWxD3ERvAnbs$P2HZ>x` zqKzNSBDdPQwf*+=jO`t@4~f}D82ei%mIRZ)*3C)qt>weaE!UQ&zwwZH_;U5XZfB(o z=s90Gz2I>k$L12tP%o>0Lo4}yP3-1SZ9X)MU_+H`BVlR-M}Z>UVJa=%B=>L>6sWYA z4q%^Z#pK(K2uB zm&y*CQ`MH(BZFv15eWBUL)0bPB{@}2bzFL#Ty3sS)wa_vcc#+LquDxojMu>m@}#=* zusHWTq_5T*rpqmlvlM3$ZfSv#D;=;&MkEd(6b9qzxa1J&wddD;Lpy6bb)>#xvEF$? zvP7ON;so!wMCU0_f1~ZBok2nuZTnZ`y2#_&Yl}EN}wXg zX~jlBM5)0RK>o?1{+mdrO(c_@+QfEkVyEcmw4Qd3e+u*;TCYII%?T$)hl99&`X4sg zxcz03O`CS(@3YVJ9~U?ekQ_7z3z;`z!_3FjQe5fL`Vhk9-f_i~;uUTH^)01JJoYUc zJ2>URB%Pfmjo6`iujDusl{^+|lpZ68U)3 zCV696$y;k!$(Xz*P5B)OUGo+R#og^i^A~I>IB|4K!GigVa9yzF=!t?Y3+8*^A0=ht ztYGQi;I8sG=|UO^JM`xLQ!tfIq4Tvdo3t@>zS{Es37Oha8&kkD7tsGRny^0<|II!G z0Z#rEO?}8I^65C1NluMrnJi-*ImI&n6>;Bl7~^mPS>{*{V;q7Wox)j`FR+JwlTCrv zRR7&3gn_cA`0vIy?kIMCS}G#2Kr;p{JB^=H>fQjlIKM7{$nNO%MQIXO(#3&{~ABbL98hFpV#k0!0yd(~aVMY98>gMP34`EsH5 z-R?K{X~UgG(J0)}rA|VzSI^1M+Ndu$x008}S(z$l=OAo|d#Og<){7<~aDw>hi8>B} zE835)*(E$ata)~8H_C(hv>!3@u^03wjD$Z>w_V3%jug9CEC0cE39OFEHY&-79dKet z8br1q`TD9cJwiyc_4yMPI@*wnw)!2O9o#NSmx)pjvd=Iuh1c}}tawglggI3hA#Z#$ zxr@dT#*dC@o!qn@ecFAPy}w=W5#5K|EN{LB&9F6X?PKlLeC(hunRV;pQTyyLj-+Fp zHLZJI9Fl+7u20;m=X%)KS_9FCqneLhnb$efPhPQMcH4%~8W%5RDFGNF_`J*`V0mZ^ z0x=2gg0woc(U9%Uj*ATJYgaW4_(nR~6SQgisxjM)uSc{g5T_nU*6) z^cWLlJZb9_UNd{->{o#UnM_sk@!K;e&F2_gjO;jxogLXdgdK1qMRr@4elf+#17#Fs zB#Vetz=sHx1sc3isFyo(*$C8b<&g+<^ytEK=hy_U(lPZKjXJh$&gct|MVi*>5^7@! zYTEjpPp`cGcza!HbQ{y&Lmkd+9-F=R%)+&_57!uu-^q|4*xAbo>@A_?*sJf zfzG9HAj1QU%K|%Rx5XVb55AGD=gyscb`ZOi-CGYbm3SHx&xb&Q;FW>#1NcqkN{6^IcaJ&r1g*`2tm1y1X|u% zI7O(ACE#e}7It*=($^^??G5cYtx@)$ty3m003O7LKF`9*j|{;nz?QND>|td%WLFP2 z!VXpj`O3hjO><+6u~23|Q4X4H6horV!e z%@H--sOX_@jB_}~?Qq(DE~JPx6PRP%PTd9zBh>Sa@kp~>yKU6!t8elL?~*TcvADGZ zwT*Uwn>{!Oh)Cq6F5;;ZDZTNj_h5X(@vn~$beZOWC!6;eKdGM43dkF+8C_Pfz(L+vHw*{?Pi z3fA5&dW@f3M?4TlZhi^^_BCSfvw5j(oxzAs5pAEkNZPaGe>9M1>desX+ac56I6sPe zojjzO(dvrO^QqjZVLyLD7P)3w*RhkZXb)K)w5;pY(Roed9KR}8ow|5uyYs^Q?3-_L z+c8XgTD0wz!_P_xyC-~hLblxvUpo!>*uNAdwNO_nN3A9t0fc+$5;><{R))gY_=Niy zh^-JxlK69Jjob6ofG*N^>~a2H&Lv5rpQ7MB?_K#qE5b;Y55*TzFN;puUwV(K?QU{r zHyy|pv!%G&NY3y&#``#Kc_YvXv1Q>4{R)-x+;^B_X^V_3O)0_GMwYgl3>UZ}-&e{; zE3i@0%094~Y_oJ4ba>X3fG&(boz08kH1OwYDo>9vqThO^*PqMP#B=0urvD0YaRhu? z?3vyaz@Ou+)=!)zpkK-Ut6ot%OR+eW;z8c0a)lk^p}fUmJQ(JQfJ$VCRQM7WR)5R8 zV&LADp*x=*vBcM8vaamgbIa3%cl96fs;__Gs=hro4X)^wViE72b>zy2IP1E++qq3s zMW&_)I(6fhs$zPeBYAyim)1=bg_@dm>bkQtE~#Q_)&a3ce`3GvB%=xloK4Z!{Xe4z zwEX|jQ#z1qfqdxx$l1;o7qCS;34%9p9kW0`H|g<5F%kzK74{L%tFEW=mSsXlJ_1;2>GoWmCal_{g2z*i#8SC#hZl(Tx@qxPfy+kK@Ps3EjyS5sY-@;Acx` z=ZNbx?$W`=8CvALhO@`xzrpqkopRHf){ixu_qeVl!X>f*t)Jbqxlz%3HR|kUvLr4CBfYwb6?A`f~@g;4BdfC)Xj0o983=^)fVXBCt zU5{TPN@rGrZqFQZ7Na2YcL9LI_LNbfKhYR@hOb1NT7%}V zTxqIPt|UA8T#&1BbHd*jZ0uSw=JcE1Wly85^$wxVu8Wv_!u`BCf{Zq*mDKy zDz_?ezc|R{CZSR!h_l|@3j>!Fx%~}>4E+%UG65&PR>A{>9u~6I*{@z6!cnl9f?nrF zmftK53V*$Ck9VHsLgxH8Btj4De56fNGq4X~&`@?@jL(!S36!?J<@FE0F@Wgw!rkIq8jIo!LB%Jy>jJxJPic1GK1 zl)+Bp)pjm7PK#GL<$NMWJw=fi_VlRyhEb61U1|0AT{7b7okIyP8u%A=>(tz&D9ze--dTR- zXyZ-@FE_nv6|M)Iy5sWrY5aB@9Ng6nTaY2E*-7i`SEXYa;rQltqdjb z$f=|MfR!h&_>FtXQ(@m0|(Tc9FBpcDu{TWoRwtsv)DA2M6Qr2Y?|XGoGLtJe1Woq z-RRSY-T0i0o3U{cnJR3L0Vjy}a1yd?S(1tn(BC{L&jl`iJOZe@FYbnum;X$6d1FULI~{Yy?1iLWC+}GX@O7f= zRfe|H6L+@~JSouqEg#U(QRqK97&s$dXul0yRXw?SO8bH)kS6RcM=yB;>67Wy=wa+e zy+{A|IeEV4#vbHF;LLrv3Sok^0^_9Qq;eZa`p6p`z1Ul%2~E(xD2Mquo6}=sPd4xK z|2>KUD`A`1Xn|)4{6a~EzVSW}`U}tiy${5B?!=g;uy@Iq{k3EC_$za2kuI!8Kl*@{ zJ!g*mALd2Hj|F22){kj`?+wqZ3%yAZGXAG>T~yt(Tz18iPR~-kh~@s@c+ff*^B_(5 z2}`Qp0})lq=>+rclF`M!`>hcUwmAuLF~#YP`65iW?jG)Zy8l`~1hf_oqVODD@3`ye zi{RJ=tG7Sv&9a&veeuTrrUz9DN3tVX$$d(_lP;V}h03N@{%zzEPqzMF(&wg9|CYYe zfu6FtfAYNK2fLvCj5cL1PQ}CMiQa=rz3)D-o83+!Zk`LFvwP?q-37f}T5wvqy_~0YFnsUn|ycaR}^f4cN8HL$?{zEr= z^%Xr~CF`CMS`z@pz?T>{G`z5n;e73+JNdUf#MR*w_U*m06Y3h}UGxb8cw55%Y$2&W z6od1J`)G*==~ul6exxO`UG%HN^fRS%Z}F@T8K*5ftR<38^sA3J91>r4!sJ^H2Pd@< z9Lr%#F#AxdvHafjtAhYCm40@Ze#LfaiAraduY=cqqn|ko;P&=CsiC??jdS8-#xSxu zLCx`@IX1OP1!YrP9|0Oj(yvG-E%C61*%*$G)X?N>z)4Oe__N6oJ~SeMYIkQ@p(EIb z<-9kSHN{5`F15^AKC|5CIy0cmxf*$T1)%I8>(aa$Pc)Fn148 zt7}{$CfD8MO5Eg%wIy7fB)(jTYt4lu6IxZFx?@A)e zZbH!cq|3lf0-k*L; zah|SprhEp=1@l!ugg^h0H7OvmKaL}Fc)oThE7@6=C<@C&5TBf!pO*(XWao+#K z%BBRw-M1y|GsWC_T+O+2!eNU4`YXWf9)8UMb5c;Av$ML%yAO|{r8$id=aaz7? zb=-2?68L(g55Zb2c{P2(NKQkweC1Xp>7f@s6dCA?cV5y<;92N6qW~{_LK1wG)yhvU zd}yc#I+A}m|8Tl6EGr)ojlo*MM5z{LLL2ZiOVuz0bI%IFH~(OvV^*T^E3WiAOm>&2 zK|0)-E?gU(hktBC@sCBy!+E2B#4lT)cbz}PSNP56^T_VvVzR5K$dU9s{;6AT=JDU> z?;Oi}{-*JcoPIvIDBEkg zq`rc(B&=;jg(s(3SF%m+MYgf759xWdNS*FcOtQ={)#O-(TS-#9Dp`pVpF9fd5@f32 zqiUs0(;Q68RW^~@%a*Z=r9IijWy?^`!)0%p-ZnkVdFF%p!6y8)MMtQqlcT^~kj`m?sAwVs;G+lQRSPfj|NsF+z^jAUHS$ z{{M+0N^Ais!NK$;I;dA@2*=H&x}HRZs~5Dog!m*Ub)EI9!qN)BX<5HRvqc5n^FgICXgJaUdQMh7owIpsj=UH|zvCUOIK!w5g@6=-|O3Hh<;H`Hb{ZFO1H+ z{MG2u+9vt4MT^cXnLTUCX+aB>POw30H^7d;D8eVX(YC-K^h4w*A1Ns=T=h+eQleVK z`o@MT$yP^6hT{m2d5<-{jjdS9jCIQ?J{Gg=YqIgcT5hi1N9u#K zt|CGb<@y9H63e79Y8FKj#L4zJT17vtU7r8o#O9|i9qcf7+?5ftT0DI16giG#MyG49 zuqAf;61qQp(PW&_JZ0I_+J6r(E4WPp)!`Svn7@xcqWv;^`t+I5@^)qGlvT=pSg@K> zx_;(zVwTVXKCy`cs(CxMUySoiM@Z@*nUhTK3@dsIr3fcbV&#c(19lh~PW)C_=n^rLBsb(*Ap4nsK zhldXO`?slIzaTX=@7+gEj;ZrtaO6HVuKuN6wQ#n0n15X6MAST}dfE47E#+X-Qp_d8 zZ^;bFl%ec0mX~88xj4#7P7L7+g{4vr4iy}F^Grd=5A3rTZ~^`2k{O^SNKYEodwQCIh|8)_`-7|!y+3L3s5Ni65c zv|((D_ld($*AkThdnQe?Z`r%IIdm(S_4$7SLj#`$I>|Q zQC0yTKE{h|IQhnavTrX<{z=a@- zhh4;28ybGTikKvfQS6Q`%Aymc56Igc&#D(zmX74*uT&NzPfvD3S*rB+&NEsbs&$f| z+v9kN?$QP-{Wm!-!yLzKl9N%_$CO=D$EyEDU5}OO&A3)cJ14RI-`$#^2_t+BkNNeL&h^yFoS5hJ7ID zhn+B02mNUH(9(l`D-4jnE+41g*b+}*vg9R<&(%A1?cvt5MzAR-*_0#d1&2lc>&{a4 z+wFp7hn4pos5E!J1w6{n6;uZUp0IAo5Mv_A3`q#dr29#*cA3n)p?z{TpRUcn@Cp6S z(G_MKgMU1q!Ji-r4OX%^A_+z|9`LXiLK3v%RArJQ$i)eO-PjiP+lCT3L6A#Ueg`3f zSk_%@$GT5N!`g(Chyz$SnUEQF*r?wq6UB*`=^QB^!iU+b;iyflWHXzTB=-It*85}h zB0{_UXZqfqkLJ}1lZQJXXGb@B^V@^7^75K=tIZFrkXoaKGpV<@)fQ(c31}RkUIlcR z7}z(N2eA{39c70Zn^R1hkjB^WWe#rE38E{Wvu-;Ii5_qH(VoI_i<88<+n3 z+a-2+&&?Z`Zp!&R9_a6+AS%?cR9@y73c8lbLmkV&`@v}Url3C?!b=FTCWA3yp+N-a zNRdR@oQ2a4v$Igq!$OafZlS@O_DtDK`hLuM-#N3XL9-2Cka~sk!z81D{MU*;xhzfI zQu-#%=zb(Lw#$fy4c|-#{wDx`G;{)}nrWiZ;$R6wi|X2V{nEWUjR_Q!_Rnu%uYrLysj zRAJ6Vwpi&UKk#6`e%*Vt&7M2;l~<;neE;~&{QQA$w`|g*$HSxKlZ&;kgZq4adQ`7B zX3S?;o3nN~S+NQnh+8r|_N|D{V-6IJd6pKE`T|d>>;_!~n-c*Wm}N?+ktVFZzL5o0 zhZ{lic^>;axe;mBbJg1q5BZM0|47$uCwxClJb8dVx8kW){hvNx`Z8e2(&(~l$_tRK z83)Y7RnUQTFT=nBEB!wUF9^urii0mvmyzlHjeK4NT3x46ZSdIM)tImFvAKbz& zZNWkCy=Ue>kr@$8p6b_kcJJPFFczjA*DkS7NMrKl58s{W|L{YN`t-|a*}fMTCp`@W zGQn@yKJ<6diPJxFrj|w{_{nD4pGyDIHM zXrWkvj5SZ9*{V-*ZXuuG(5Jjr@tsbi;3EXmutfA-3WSBpr*A49%W*B{Nvp8Dc5ne`K+(uO>@`_iZ< zg2#?%Utmprq|vAKd=t!(X{Xz?&7VACQuWAshc+L(o&sEZGpovNBPn_of^?z z@M~h(WThAQULA08CSPI=93=?1Au~hfNAx9fPXqPY3`)&PqeCH4Ll?1&ZDPhuz4GMy zb%GBDhctZRk7b8yKYuWiOjvR@if)~@WeZcbtz=hUet8C&P8!H*J9g{<{uwMz$y54q zy&|S?*to>_q?}AscqX4?OvzCaYvjOLFlB}(gIGr&B=yFfSv`C0=4GuXk#;ZkKlkYNLV2>LZll|2si3V3%4~-+ z`C3yG{8CUfHt zM_#_Xg{^AbIG)T@o}5{KJ@q}}>)XC%(V3^#zCg#XHxDLB4dq97MaCDgn)^TZe{;Yy z*oQOa+b7Au(6Gt*T^?+h_0YHnl0#D2t3EMoI*^fufFB*f59|noG3CUoF5;DjXSxoK z8Zw)mX?x^_gHdGi!n2VtusAx1ZUTwZWl*@?aly&gYNi{2!+kt&I9yQxRKQk(Pj-JU zYVZ*9||So<`+ef=aycGSpCr}Q6m?#l3}bGeU`&_oLBns0=7FImFuFoo`RQB z*{{k<(`?v;B+g5rn>l>1X#@`Hgu=w|&Jg4Y=Q1Z#7A2pE8nTF8dL*ph`H90q52mtH z?63TDkwXXX-flbQGxYJG?GwnvMdzaAIw<7RS)@_R$@2eNK3GUElGZnW(1vBRC!nod zj?bZ;YX};B#N4=EHk6aN)0gN}TV6ZlcVY)FWFK^m&YKUTkxGUvI3M}?f!UFR7qOC; z_r$S@o4-t2bTEdjSa=Z>?qt4POJI z=0^=)%C2M`=zA!FOnc>vc+N1kn6BHt{Sa?IA>%RNnGaSI89d9(NalSNQOD%W5K)=s zwbe&1VxM%599>Al3x=QS!{%%`7rChYxrWuqlKJN%g&6+WcJK{2xQh=J%Gan#`}Gs9 z~>3Xf{o4L6rQz`AUaTp@C#U-ayYeIYk#*4U&jVtb$8uG31mFJz7apCQTQasvrIb2}-11jFUJY{{y#ksA*z zjfPz`&ptFKtoIuvddQ)rA4RdLa}E?1LbDv_wr!K^>EESm3kwDQ+}GkZna_xO!cTMp zU3usg4%9a0(5l03a7x#T{0mr|DG~Hzh8A`}uM93YsFDIrXq;@KXFCP44;K~1wqzw! z-U;vhY3I1-GcF!@G@#`a5;0^#@!%;iHIbcXd_?x;zeYZ1`xcJTuJs*Huh4B;ssj~* z^PBU-59Ptv#SoaG$VLruwILaD*6?npa{Wo({0ot*^h$Vh%%KRj3Vd4r@f=Q4hAh$U z+S>818feg0UY61aWx-bRqC7aB^Yg=3az;fD2DkebS9^@lw5W^mHU&~d|0g8(nRsawLna}3dDaJpn^BFd^EY(R+EW0Gx7 z5uQUb>@=#sDZ*(FQq8bDIZ8sg7r||%{6^r&)$F^6qDK`HUpXx5r6*WnyU6)=BHQ1O z#z5cmKHWdfjbFxV{X4ezt)O;Tyv^$swv4R!L44@=S($CWff;@Mk}LG@CtH?a0JW z9w8fBc0b%Ele`&wa$<28)_bH@NV}356MvRRYJbflAJE6NiEQ(@Lyk2xcCxen_txu= zXS)!RNtTg`3ob;yeqwfHUo=RgKU#fIE_CS{GU@U{{p-*Bsc!X;`$51qkQKguHuBX2 z)1a-t=buN|3^$y^RX=E`7z3-^G*su2~!%;Snb`pPFe+yJpk`P(8eDZI9h*@0 zi*gkBn)#@$-X_H7z#>r<9#?QOs&A&eOmjrGs(y+ziXsb#45+JJX7AK)o=Oi7J=<}V zd@J=mmT_?>eP8R%Zq_3`$vzU(iq_Jw!JG3K{4k;S!E11WjxJ}4?lijl1N8Qon0|}d zH~o8m**YKo&I^l9gp(o5&V;{y_?4K^i`Y-k^H$aIho+IMN`J1WJ9K}?abA?u41D7H z6puoke94Z8w^@@-d^=9OEd|G}i*_|4TUKfusulL^B6g+EkFSw;wOv2_6!+B)@}`-6 z@$S*1Zyc*e>VAE?Hccd!Z9BBr#t=52^`+#|0~1K-*CUjgJ9ZLoGC*5@l=&3O4CI`H zDU##4{!x`C(BoR8{;wXGOVxyKhx#UIjdRF%ERN7ta+xFf7X8U_j+Iqoa{;3*VDwjB z5$!;DL{bQRdz|Wx4I%M4nH14B%t@)Hki_6*Y~<~lG?r{d(Z8|pt)?$5rnTg$#cRW~ zKQ3->%F6bhtZ|r<(AVqI>6^c}Le38Ox$E#pU)A#1fo;uRnXvr;4z~XM;K{#qnV>C@ zfVXISx#@>*?cvYrO{8hu;YhY@O;O$U5yPglZw7t5;9xk3zkWLE$;fAikXC&U78a5W z@;9V%QRxeLXfwF|22HRXqHTxm&;es)BP2M1cfHJVQcgIWTo~*jli0C7l>W&Yyjz=$ z+Vb?sC~nEJ^}4+XO)V+98G|Z@|F^O z&sK8a&6;?xz$};5)wZxRwG&UKL?0!MVjcshGEqeV_-8l#5Ma&*dYLDrBuIUVI zB~5-#m`}&qt+Y^1pjn!*q1>N53qJE%_{1D;%;8&c718;twE56-e)!1_M{^HGE;>9b zbm0_|H}d1Q{n}^;XjmpUF1r@4kXr&ZQBQw0ePGIm;F7tviJno83Qaewvfx8@vW+Gv z!h15;h_EHc%d%Z#(Jdo4lZRsEh!4la4rFTv)zbE|i?!Rw(j%12Cy$dN^3EZOv9iqC z@})W-vhU{@h0&o#P+0nHX0zy^ZmP5cIa|NH_qvo;4vf%6D;m zSd?U~%O^i>mt^pw1H$gj+CAUk`LmCEW!{8|4!C|2kUFaG~ zDKr`9P4f;doZ#$ati$Bv7#Qs{jhTF&q^w&vKWQ(`D+s%g+<3vQg&tOP^Jxxvw)_8N&>Vy;ztk6>85+3gZcGv$T_*f88=vZ(>8zfHEt7MqW+PfIcTL@@j0`s9ZC`S=H@ zzCQkv$t;;Hn9;HXs6qJmL=C<`-8q1pLlRz8?5rlGx7ds9gD?=AAFz_S(bY~+cjS)E2Dv#gfmc|GI*4o|*x7V{b+UKL4D151aIVvXG*bIF`r z8XLzp(|1-P62oY^4_HQMZQo+p;Sb#hKa~r>lR|%jq@lSs{~%%ynC5Gi?LM|3v#-C^ zdZpRbm;VuA0YK(MliYxhWxDQh20g#$Pm!oGg>!N$Slz~0ICc+Qu7(+^hc-MfN+g#G(l zw}llv({kiD9sQLtjT<&>)Tm*@#_JbMe|f=zm!~gq?78ca+`9m@66vxenO=enLZl|S z0jiI`9BU4sv63}7)Qb34B^g&rGK#rvv6_SJQh=Rqm6XLci`_4X+nnn#sxU6;JbZ(g zI0v@;iVrbgrha5D^B_%?Ip$q=e3HG3vcvl0;TbPPl7d`Zw&4kS_Xk)PHMayNo*n%UlzM(OQ#0m*e z8E5uUtB2R;S(NIb!M+jIYlZpNvIkcO-NEzf>yASjvNh%lBY0kZX|N%JuN5#{iB!Ix zfaZio@Q?(7RBf2bXOfyzoekHHy!rAQBc=*Z;`)&{r>z<><-%h62%nX_06 zTO=->ym;}*ki$dSe{?@$?9pK#4J8SyZ*G&9_wB#o+etSH9nbO$m^2CYmAqQ6$3as4 z+z7K>fgYp&`rD<#pa370_*)c-w-4ODiV5lKC09_XufQXM3WvFUmT^ty|DeZTpZXSm zupbyHRK7(SX4nrOb0LDSnTcw#Ub%9FH#g0$r{{*sHp#3|8$oIr)m5>f!kUToXY0=y z8D{Ix7VFQ(>?++!>wnMsuzfe>Dc_@&YfIy_s{oFiu-R%;T>4>FJs?1lV@)*H&m8NE z>f+#Sgu?-m`AUmbvz_{F^-*Cenw40uqdvkQq5AU=eWQq+FT#W*InND|V<9&}@@VJ` zk(vX3Gr$j&rscv2Dhej*%vk0YWIcc6$`LN*w2}t9rb<%+XdemVmaB?fy!kMY8+JDp8~WAAbuMILsG5yIQDD0|r`zmzWHZ zi)B>KU-*3Zr~SsiPjMSodQ@04-ELb@7R88oPOg>O)oB*H0u?Yxv8v+Bn?2oZbN@Qm zN3vN6=Zs;t6p&g2OA#}x-b$( zWSP*l1hht|FNKQ5ZpH$-SQz27;tU6G5z|DE0!<%p^56jBd!(Gg&XM|#FG)RiR=vQR zIlYNPaU;vFnj65UNR#U3h6g3sLt_{Fq}uB$^U@o{)lQ1?4>qM+A(4_R86dz4uTmEV zpW8~nL=5`-VpT{DOw(t^W4j7^Bv?ommXhdPErKcV#Q4+{`E+u_!)(jcyy4?f->mFb znKXWQ-c<6)Ck>PFhIHd^$|N|IRwCZ8oyQxJ+AXtBCluDkqJ>malQgPT82?%JgDtZ^ zi!ZFjjpVCD#0CfYTcuEI8s~$-j6kbury-Il$d1lRp$KpV;#;38fpoE|Kq zt+WsMr-+AwAA4?79Wezvp{F8VK6#jd}2M2 zhej2h{?tr9gPahbwC2DE)aqETY|+NOfAsQ+s~1il{FZ&d_OegeUh?r8qKqY-A<%)( zUmv?{eSZGCpMJCU)0=;DyY~!y_N{I{d*j@|25p4HuKVlh!e8g^I*`k?I{ox?r=Ong z^3(6zMW^}YgA{yt!f?-xfeY6&CAv%d_FedA{f6bQZQS_U@(r4;{1Lz9k0D3b7(l92 zGuMyz`gK2y_xa(6@s=*i9+c?n;#(^ozsL!VqukHPYFHnO$O4`IhS#{oh2E<$W&u~j z_`QeE_3eiK@GD-Lr2le#8&kGejJbqMbzuu4g93f4$0x)ESWOX$f%UD4Kso~cRXtDt z3dn~C1;=RP8_UNx|^yg z&#jyG_K_Q6JVwy<_9C`;IvKjiMcZl;cY4Bv)9mW%)$E%gpA0J+JK;2mTRrLO`u=^% zfuXGZwj2Dq|N5(xT}Kr{AHH#lC(PyS&vGOJy@)zSBd{g2MwBjt3SH z|EGx6EusVD(OP5riDMz}1@Ss7i#q#>v(EZK+M(`!jQ}64rd4>;)(r7@^$xt=&EUQn zZ>0GLOV9W}_dW*tu&~qU13TNxAoTBA;$JGB-Dp@^;iCc7FWBWi_@CBWuyMQ;xl z>Pj*H-rd67LT=$B^Ii?=3olUECcd;3AEOV>i&h8olC?;DiGGf1Id!MbDLTXG?YNK2 zrD9yJc`nq!w^q%Xp@vH9T?<>|v|?+?&a_$th2{p<`LyQNas_t{(UFSA=)84Y1zHt% zFAN+vG?>dR!5(Pt3)&if3* z*f&u5t6ce=`VJkRbYmN9@fc+;_<)1~y1^t0MOV*4@eWdBM#fzu4%Vr1IRs0>uZpZJNK9V|y zteMcPL4#&ZGcx4a;vy{#Z5^tndI)t#j7g~$-l34t|5s_Ouf@+F{>>3bGd@OnUHHq+ zHk+>}PM}+hXnXDbBJF+J9$k!~1==ubFW|ny1AvMC3&xz9ih9r2!E!$H=(`=ILAg;; zkumnLxVY+V8%6~t*Re!pH%YI~``(?vaN!Gbj-#Hyr-Fx=TRkE+G}0ay{eZn@d%ItB zE5Di;?YAb{8*l+MnAgcu0K6U-AGuo$7|jmLL`6oOfh|cyZ#}bICOlk4)rIoQYg0Zb z{^5t>52n2Ki!PW4o6cmvR#7tR=6nq%6<`GK>pANT@jMdIuwwbZCiC$-*tDj(v4MVe zh1#WQR=Y*n8mtD|{Vdp)5(Hme3FWLif8>a+t8m!Scv^qSNZ(mK6q^-v&%K;@;l-bj zw`h z^SsGU<6}7(UKh=R+O%{5ZxqxE=;73H!cfM8CX4hyu767mHYwAf;|fmpa5OuQ+-O$# zriEg9p!`@4C|zEXnq2zVXB~ zEhsG59_tqsia|h(E2F`~=q&$D=j34|Gt(+1+A<_tA}TSwc#L)?TBS@|4at@n8cq)v z&H3#dn|<*j8Gr7#IsArppfFpI?q&Wj#p2)#Hc@-`)fk|VsH!VTR;!7+u8I)o&kOU>82N7Io1uotk# zU8_f{VO6_}FLh8Kqr>aLpN)#O`Pa1)b4rvcH9j)bKQ^(B><6MbbI`xxW4}6kP)u%g zWSzZXgw&P;eC?sK)z37oT705Cs&;CPYF>QeqX~jtSqWJ>Q&0&F#)Uz8VRtbvixBdW zV3Ob%*hdbs2R&E_OVeEEkc*4W3m))hBPh4RX{Db4+h19-KsYf<(!^?F@mKL%R@)o5pM#%ZjBdnX{8$vm7}OiQ(xOh-?iJX)`DX3Hdc%JG;bAhFf{ z#*GfI>GVpE9%)%oVa*znKz8Q<*;X&BZ-Xatu#lG5KM{9Q&TxxI8Nwb1P21%rv?tbU z14UGBXx?_R>DC@o=tAv1LGvegKT>~>g`pS{BD;SjoA#$zvjLW-pjc>f9BkJR6z2LqAOk*w#hd)aRbX-AINQZQz_ddq4;yhnat!1kM7 zhRsinxGqVKZ1~0a^?3f1^ErM!o?{$Zr2oO|Iqt>tAHAL%@IBL~@bYjXrO4$0-+<#; zZVFF{^a3l7^alLz%gdb(x(xU?I96`yQ#b^`5xLx+r|OXJ;)4MPvx6RRTztbDH#i1- zaKR&eN(A`kg+IqLl|L7J1Ey|pQX@c*7eDp%f+FDQ%^#%qg0IWhfbWebFhqK9x>6$a z=Xdkjfa6)N3x9Cb4SxfUH=m8?0-7_uE-%mpd<4}VaCEtQ>q!d7+zWqqIQQbeH~dsi zui&#c{=g9Mz43SHi8nuWy}Fy9x?J3!>v-z;->siIz25kz>NN#&2VNe0)8%zH9KGCo z@!6X$L(kp$e=yG@G57%2mzV7Mu=ek_n>C&I;eDLO5 z3fCye(fzqjmk#G{zUj~Jg^xQNy<8o>JD%=*yBofq-d&&d^t#;L)9cUm^zP5y`EWNr zIvj8OU2?%2$mIn5)DrbVu!*n9ao*1t_nBx9+~h=H9^b^H-#@H z=ZYP`S19&No; z3(g^TL6sj$Z8Z2K4K7gY+_?Z4ygxEmy@for%V7=`FzWNRuMCqg%8S6&SHjXqY}@4H z_O?vr#Ukx#=AbtmHxVD?R1x-TzC!oN)wBlmGaWan?3(-thZ8YOz~$wnigHps?@2px z&*y@%7YBI2PjT`rQQX(^y!R_I?)kn(q)#{Q`4}(m^|^m81D%dE@qRYO3D=48v&++W z6X~;rOwc=1j)6|GM-Cg2Qn9d$Z&l(#-b# zt;b|Jo3`v}I`&Q-zUf%oL4#+rJ2Q2jSV1GkW`a!=5&@0n_pbE`ysrov>WKGmfoC6Z zoc%6wSqQy~RDa`Z%ZwiF9Uh?Rp_LGia8E1R^$cLy= zR%@*7+bCc+5%gIFQ@#`Ln<0ZNEyn#Wp`$jjcG8xhuhk;P1=N+ZC8s{7 zc9Sv_d zJhbDLb)oSmmmlXYmIp7AJnwC=j!u0*-w*iK6ufY*-9TSm*KKsdc}HAnq!!+ z%`UPlj^6UzTj$Q*a=d`DEnxUNylg+t42-X$>?fVPua5b%Sl{EIYahq=xzVTZ&!lX!>a-HCX;e%kukJOSS2 z0)OOJ!bx*$YVao%i?FSx;7!2+_gcn)1j zQ0g;^8Cnnk`xl`j>x@lCUt zxU}3E^!$&#Mm*Jj!ng?&50B{eos2?tQ~K#$sQt~CFw;)>~tVo zjveC1SUwqtdDf<6u-b|3VK>-KwuiKXWr#USm))sD?d*Fth-@HF;iR|?>{(InDA=S@ z>>c(M`&@MUn~`lzL8qG+j3xhx7)8J~;$WJ$bjy~d_RU+!;0t^9oc3XV{}*QjV({df zzvZug_~iKa-;pKXvBTsb_HO(9#m-{8a0ocmh{08*(mC)0OSI6g1VdH%rtkz*NxpOf zjUO6(W$g{x_-ww`FaLsrHNm!SGZ~4PzR4KHs>4HsQoA;ck9v~NG%PHl(nna6s{rpB zViybM4*2#=G!{8dklC3DSn!MHR6hnGynGq(1H`28h#Ff?rm?^F>>+1|+6jHz8B*i- zTWs;yTc(X%vDX2Ljs^9>95h~gft2sV!A?*v^wBXD!ikH9JbU^aF7AhWglnD!Rg z!zT9ZyQ11l8_DVSmpU@#QzKcI!=E8P?3sm+v%%L8aU(z%GCPORM92t5(P|x4*$h{} z2#!LqBfuFe0=!gp-(DJ#CL zB^WCt5H0}gCs3=)>o09^?i^Wv?%aR1PNzTn>@?klZ!CL=X5Wx_a+Ac%ZTTG6>u1l> zBj?VZJ*PE0tGwn}bx|g8QCmURd6~gtw}!J!S$K>3(ssiWfBcglaP|!=VLyxg{i4DOI|Vv@hoUV?2}uF{ z;EpNJ$p>%=d;?DA-LPYLql_$@A@~OlSxq6S(5)bxVfeV|Q^YFaIQ!u~1fzM?vEn=p z{e~9OL;T!YX$E>GPD%_e8ov@h7z(FV1v`I}?s0FVGv0@Y8J{|Y&-*|isc5jcXPr|+ z7zYI1;r^s^jSG+YW99`a9cInaew{Uo+Vo%c*Q{AejajoC6L$?6vTN|0;+wo9e%6X_ zZI<|9i`-v5G=KBv`AWmh>{|EmprEks?CLw%Mze79=7lul9TL|)EGQ_vJE^w0p;kC+ zR`{w_tJL=RVr}t7`Yib0f(8Gh*BAb|V8NdY#W!m#p5Zb6vmCb@xoh#3cZz$@+|L~ZOYxI4Hy00#u2wC2VDaXePqMSC(6_pS*eq7mF=#43m(M05L>U2E z5b}bD-{E#D!KD1E{X*968$G=EdZ*^I8s$uy#PUySzld3iv3b8>nFJ!WbnJMT)L63` z0XMkIfjZob^-$ZP{#EDoj~ga1m!HjZM$}T^u3R^j7UgH zsXLcB-eWD5{!3ZGLyz8Izg>8$|ElzyrNpu^sTPZp`Q#{QfbYl0lVK+W4Q_Fp1lGev zh$exm<8wV8lU$4AhJ3?;8|<6F4a3CFa7J0S1ddJH#Khq}N9^wM7;6I*v;&Llr}MBH zly_~BpZlEeqTC4h=YCO^SW}3<6dR=QttJ`8=lN=|TwiMU+ZtvMo@Nf@3y8V19ER{Z z;v6cSY|KJpytsymOaOELb3$te8p*F{&|!#%HSRJsVhR8xC8{Yxk`LHmO!=Hy_$+B3g2UF~^C_@R}g zQ1FDdY-pbdOS0NqQpU;XbOve`i!MRA(@ypK#iX6MU=-?F-eVj~+!?@W`Jei>6 zAJaK0`NwolO8zmOlajmAam$6#igNrohR_*<$Eq01K#d@M^XWtEL7*>m%6M-U@8SE1 z6#0C@MeWIok;nz3!Zh0Qe@^2V;E@KnB#XL<%~l7sy@KbwoI!LIU7%iv&xuwHt6*RT z5D~L)rfc2l=IO0O+T}?5jYyk_W8R=)2)p@OPL zv(_DHsq`^jMOq=P%v0;DNo?lC)Q_i5ofi*i?uHQ&`~j&O%9mNi;p^K# z%Z!C4-xXxi3KG4XeZTtQC-$>F00I7tAt&Vy!hgro$OtpdvL=MZlX@?#pG!YSppjFI zovlwAoTu@Zo#~|>atE~OocDL9r#;Klf2gPDvH18JWsK(W_=aG=E65hCt5^nv@LDZq zjlddYz5q{WO>`Ys8>_X!TsW(Jhvno)M+Y=Thlq9Pq^ z6sbxP=_)EJR*=|5MFqj$H7a&2vBzMqQKQD#E1GLBF={j>YSbjgBpO?qiGMZu8{sbB zZ}yx67lY>ie&72(&-*>k8w1?CXV2`+?Ck99?C#8YWg>YFDJBsur@?g`vZWY+SXJwD zlloCCN-6LZ&ZUuGaNh8Qgpni8q-^V**|uGasr8#DHGOmSk~u9?J9b*0*{)NIZXG+d z{S5)a*bbl0ohBUa-@i)W!7x|1hAoE-Y2Iu_n@(>bR#>%a@y7#PoFCtR=M?b493xML z%+m-Z-9SHnhov*tKiPF2a#+b&!oOHz{X@_)41S1nhE%A&F*2>aDTHe9t zodEkXNUTd^42gy|;F`WRZGf96S|~+?>(G{cFD>^x;LZ?YZSxi`H0!m@Ch54k%#-)g zT5xDPbwy|`uvrS`I3vbl$%4>2JBE!rC!Tk2EJbNcz!VW|F~}Yf7f)?Cc2Zv>PIgTS z3MyGBvi?IiC*YX}I7j>|x?3&`y21sgy?j7flnb4>)(m)vtja^1MMUfSmaySRv9Pbl za`ZyVG2kSMng9`l z8^PTds~=K^245eU7$+Si(c%;Cv!ksUJH6{7);tgRs4)TLSs)3McNL60`Nd;-UST@F z#c#0a{(LGR5-+^Li(s6ZG6a+@RqjsOp<*;BB+ti&A@bsu8}{wJXiNIj$IzoYEtaNx zN5dKOjmm@X-yUWwDTPIbH$q{`U|$3Jo@jn<@Bp` zcGX9#S6}&pyQ&?=TD-JnN-m9tat7KBH!O3k}PyA|oO0AGcmtvAXXBV%EP8@NzQG;#%0dGZWotdbdL|0N@^3I|!gUC2czzE8oN@dwQrGU;;>pIO9cbru#OY-fF+4}LNV&V1s88lqLM!v93T zR*KGiXdB`@BS>rET?rvu6}pMQ$j_r}f(@g>p;=4ZWn!=>0O#}}y0Rf+wn~E@BVucQ zzR7jRChH-J+G^cF5nGirn+VP)*#GE@zM}aL!x_1r0qTQvjss3bF9Wzg=?kz)Hlq~0l2LJOpI1oy+os!Rb!$GE^OIC zfVXThUcbGmux}EVIe7mgpQMuIAu1=eStK2N47iOTY!O1>Ak&Vr9%2N8j_9I=TFwqhi+B zTYmCXj}1o=nX%>6fv$4C%YZ3`&F#ldWtOR9jE}D#;CJ)*ad@K6u%>ye`hlyPHqE?o zVo#omzm{}vC(v;@73g zYu1eFG<|BP(L7*#zfo`YBR-3B#IzoU$JJj%>(l%>z9lm#(7`uHgCdGb|B{2il-hoN z;m2$z)MMfPe&K>id=?u=4AN&*Ij`h1cofs1K}^Z?8r>iv8V)|`410f5=?Rv#Ed3pL zYd$mh+TDa5STcqBmVBfDq#od5l$edhE{tF<&CSMqZT>6_)jlkKJjc!1*=^3h#1#Da zU+TBV|DrS+^7s1essCNG#>fR#}~&HfAok3Zf)!5;uwJ%SNu#KFJwv{U>6l&{jmwMgR`t?%MoEo9o>DP zq9FQYtceJ{fk8A7VA#p`Kj61M_<;Er9y@WU-rfnHLd$$QVQ)Q-+dA27*~5o?;6vUo zPx*CQb|yb+eaw$$X7f+;7A#QdfOa&l1RbiB`ihJ2YE*QxwlO?B%$gZqU%ek6!q{~X zg7`YX^Fmm9L_Jo;BO&RHX3eK$Zt&H@r5mr)*$C?vDb3TnK@5&?biJw? z5*_=+#OZvvaB|Bb7FmAVsNtVqeE9Gpzl#IjjiZA#bY^y~?;&k2X3GZa74+*UzJ&Io zq3`^FXYq(&$k|R2F15WS1cWww;C8WxUyve~h&|73xouFCb0ustVQ{F!=E~V-U$#8j z`6>Ck-A17an4`fJc?VBk~BVww8n=yjTqhQJ~Jp z2}%QG1N%@u@`ieQCtk$q?TZul*0Y>AVZlf1+mMSbTllRl*_kX!a%4%FxcKji&d-x) zLM|RcK5S&!OwopfEIS5LhzAldghp`0kzh^Zk|eKOz~e7GdW2)BstBAop#)j4EMgTF z;)rNo@*Upt2foYb2}v%NWicn%$TAitq`+fTn_vk zyv2+2_{YTp{c0L8Fa`dC7UEYFE2crGK#ax`8u)V}p=VxpcAh>KU&ddIMd1(le>E0O z>#ZA#aW5W>jOI6a2gV}&P_Vjif6na zCRF|FPZS`&duNk_(D&#?+}d!Xko_eN3^$=IosE@;&HUG;RV(*@dEr94zJ1o-{Yjq0 z-%{PdY|@w4i@qzcGf(-~tfoykCUk-ee~7UP+J%Lp!ws?tM=z9;yOP~{@P&=c#v_7D z%MTZ1t~qs`*-=3Hf^SXsyZU7R4v?^e9s|}#iXYB^K!2kD*0WYpZ^SDSXA0p+{jgTckRHRp5D@qdLaY#v>d~3=sU}5cI4fbI(;(%=f*fMTz+Orvksfqy^ zPZa{~+%b8NOULfGyeSFzfKEQ_#EOZ=w#E$OaATfvz0uTz#tHJQ0_Jr(YXCYm-?+0$ zJ}T&J!#m3zAx|b6({z`}>>3pZ!wO@qIL|^%gzN{aBr1|E@`!80(%V{Iyl9Y9r}>GM zQUd>xu|HyD=NZX$Ur2U^e7$w}#5dP`dO@0bOp}2V$Rn%TR&+XymS8w^L5J-frDbQ} zBYtchhy(Xx*>jz?QYk7rP!s)pU-`GtH>3qMix=zp2FUA$7^1(^o~iEkQZhsr zGlK#%woSD+%T{plrSYbe@ z$RXmtP_c0ym6%a@1$o9*Yyf4keg{PmYd+iUcb?ijb;n!vB8b_7mp*e5;FVD z7W@Y8&mo5d8+rpbJ^~<8m@*-ZMh$z}DZs@EatU{P{28FkAM?%p41HoJ3)#Y(7B29-Zvz)Fg>txl97@hdW@lCy` zJ;)Mhqq|SlVOL|6+onnp-Qt9McA`z%T@52QW{{tgTa-JFCD>+65xs>S#9G3Se0Hz;qLJY|l|qNX&Fnh$E2ojRpcMTfT!KiS_XxC!I#!7M30i^eW+ z5`J>h(HK`XOw}1gMP;;RJ0Z_;YwuQ}Yd&E6e0iAQK)u6nxrA4f^PQb89*@rJy+)-x zL7K6vZKZ8#>k)x|p*ae>m`WJzjjK^@kAFr%gnkQc>gkcsm`KGBzk4apP}C6bFiT$)7T|MtFt@ z7LPs2MoYxEnb3T~A1uxZ zh`0dCFxIb2#%Mdq$@+_3?x?1d8#bEWw9ksDuo-D9cI;S@_ExPri@GiNz^WV`GPq}t z!HPqt?98rSkpqWUub%1Y*`Ptggx#xF?`oKk&~RhQ)E}l!8$L|Ti}0(PRwx;m7rzz# zITrGJ1-zqu9!M?C7``#`6*bzza5~*2eX@;NU)Q|ZWNN$Y7 z=`Zdm24orYei0%+FSILumn}9Afi@t`jD4jG<{{5XtpaWmyjq<=OC`)RsvDAG$WR!W zDES#{NQp`6UgC2^wvxN>H=Mh~#`2Gij+B+;MF?dmq3k3809dD$%ZTYhd)7_|*;eGV zVv6G#Tt;-f2J?eVq@_HJeW6^Qjk<5kYoueS3tiw61pEC)E6FZcUNefdf=b5op;CY8 z9-h;{_QOr)DCwRfM_JGt%4O?{F49WW$-ptIC#C8{y zQg!|+Z~bwiR6kp}To4gw^nD2zq((xr$cMq!=VI%YwSrxA8n`Z1{IN&b&S2o53YmBt zxEvE@?TgEX0-t-L3|=FxUIyBKBFbE0XGulqBO{cCAu7wZbNSpvUv zF|5;QbE))L#lyNn#RF{~6J@|dD;tV7?};+tL1i!TN^SE=59`G-k^}a_<=aVx*=Vx_ z|L(S?;kBKtiL1m?RkIX$p=U>^@k0(l=*jM+BD~KSQ zvxGnRr17i-f8e3hSqvX|Xl9p0r4Fn zg>?*P&d}(&p&w9iptuL-dd6F*S8}FF%~DA52Pl?b9J~2pZU2bixX|c$L_I)Ug@lBI z-hLrIQPqOPms<%3T`N>|v2*m)pUUP+iie@R_H<9(PxquHw@=#>@0h&DzIR`rJ%)~H zd!r%}61w{AN$i-GXde|(J2WmjBsj>QfUE!ES#HO){RrP1N(K0O5?|w@^{*D3^-DWI z@5DvxZ&(<>p^kSo^%V;Ph`sc!tB-}@{SQNeqat(|qK?JU(Ay&AW+nS&s(5+0ipCh> zRjEQ%PY+iY$MSYmSN#u&NNB{YxHwV)zRLLO;#k#F`>Ft~s-ETTDpe?c!H62Np}2+# zNXZ8At{FJFIC{8N_0+4QcuzT0pxRxl9;{S>NQ@V4B_w=kR%AnYJHk-|UdQmEQqj{V zx@Lvo+G^h<95A|8_Kk?SC2AZnxH(p<6RLjsuv`GMbE@tirhdJZ5J6g0CVh$%nBoVY z-RLuwz2=$eMs{|#bqvDH-^9$$+in3mi*o{;S ziT$T4|DnA8cj(p>A+0I@Yh^X%|0MN)NK*fQs9RGs-J0^hShuG9pKkr1vIhQpbSu_J zML#I9rgh@17OrpkIK?0jfchaCVN=`%>#p&g3}jIw>=O{nB7#yY~AAuYKA~Yv&!) zeypE;VWkuD0&%oMbclwKKLRmee0^}uMv;*oif=?Fkkn(=e_4N%%styk?D)Y=NH>tq zDkLEe=w!Bu_wL1eu#K5rtox;gIqXJidgiJ#ESsO2*J-4n4Qu$_XjAMi2gJr1&=592 zV@2aeem`DSyp_cyv(5o!FAu za*fT3=g%wRnBE`CTR0E&JFalK;BwYSslKc;J3E9u-@nybwA6altC|!sw%7bs{KG6B z#`k)5xY0f_F<A{x?WfR2A&L|SEo^>=Y{^s6D` z@}LhD#^NZUkBi)jKjn|mi52B8_Mh^9GdqtbU%DVkPXhbw_R>-RX455Q5u3&*TNm?m zwrMqQ&R^VT->|D}9DigDqqv*W5F~7QaMSt|^(WS{ij4N%sCC&7SIHdxs5uuuNyS8w zSD)SV2mfZ*`AzID+b0$9xqJd^igSOf*knG9_vIbi$j3wo; zge_BdFFka82>*9>7GJC3ZTAcCj)7k&7Woj>(Sq}WxE<=|3PKt%XFngh6XED5GCc=E zK;4{;u^tNZ4Gi!{z^qXVd4mY{;g7?!+1epJpR!%wUn*qQBEycm-|Un)e;&s6jn9Jv z!kJ$V<}3MX{>kQ?rcc@93GA1BM~>{{-u(_EXz||jjaZ9^yc^rh40sEFku`N3Z~T)- zc|Shp{q*kqBVBhzi+(2erc+=Ljb)>cix6(dfJl!Rj38uar|j8wMvR}b@TH9PwsJ|@#eQ>bedVtagV{u$MQu$3|67~ZLx0g8 zH13|7Nrs$+{z9kLWNyASsw0iCkGzb3vSljv0Ymb+8~0=FB$-P)w$5iiN!!^Q$xzTc zaqs;F_hdiH9oe+?56*SccyF2sT6_pP^D~g3)S%1Z;*VYe<%Pa5&E)59v!49P{SW!S ze_;*3~qQY@nb9H znbLJXaZl*sxG1yWolp#vcpxUq6`2Rj3e-;ow{tyL9d!BbxjBl-yvHpz;TJ;@`!aw> zuN{ z6QIO!PwsmhyGBvgFIk4w!Zt98_mIybF+?RvYK=|hHGMcd;k7b}ZXiSg@Y)ucDtl z6FOFvjgon}GWKs(K1xAgsjES0O`?!b=lBZcu=A~%on#KNd@61(!R-!I)* zI|S8UN8B?#@4TsUJwROgGzv>WUJ28+{Ssw65wj7M`jCH`U(Yl0nx z(;rCdT-Pq1zdCuqRyKnDW_`+jX5m0&AB&Omw{}E$fj0A9)~#E|XKH$SKH5QKaI~cM z8#<4faJ&HLb5e`{R^}^{?@NzcnmS=B;=L`^Y+E{t>qA*RPbdYz%*A9tD54p1j7t`+92q+)Hy9 zTQ1G{p2g%2UosMc$fTO{B*$~7csG83(FD=YG+tt0f6*QmVXF?8%1pxbL>Ek;#z+^0 zJBh(e?HBiHGYE8}%lT(mll=*7$c}HfvI{ikzrBTtI#u$A)<>wcqQ6*AiEm>Yboj{6 zw4d%@U@K0wR$QDhLAjZP@A>EHwIW-=r0@6kuEDBFKFRFg{4ZwaKAFGpB`o7fM)^<613xHkWhm1{88ulH%!Xd0^L@QvAeVP?b?qM9jsbxr)w-3M(){GJZ~iK zQuN@mR3VT3B{g6f6Z7lU%U^f$B;OC(remINjW+3oTpZv#xnU-Q{i`zD7)ZO=lCO`8 zS$fCu{WH5(vrpN{TR-xfQxENDP_R>&tI=T*jsx83kGuR0dV=jAu+e*V!H{6R3nwa% z*+=}*BD6Cca`O@94x-E*e8b^<=y!?27C2R59vIt!+ANNg%&v;EP8T6n zccgt4oww^S&d4HBd5gZ(=1CYqh$1w9`~`lGRbxq8xEBnCdz+VR!PWhZZTax7d;}Y8 zeI_+*4FcP83D|T zKiu@e?#**?PKKA`5z>AfuV}?TpR?IGj@3JMY~A{#r1h)$+D?o+jkSIwRpoE75%XC4 z42_O-@UfcUBtnoQ3^{?nJuJxJhS3~K3tI^uYU1&ho|Fk8;8O5G= zct5tLXTbRyPYQo~ay@CmAI1Uv(AykykUloq$1IG+;#At_?~5Q1`rNPc&(YUZYVJo= zLoAM#@rxT~v$`xWpO#<;-kXE@{%tlz?!?oe;B$xevR;t_loi&asZ5OZ$f6(Q-@!j$ z^oTh?Ry<4!Bs(@HFd)b!AkG*Ui*r$Coci`~cdf+a-`nsH7P7X`>7QWA^7w@D7o&dS zg3k@;?9V6 zRUM|zo5VZOKhY$9k?MK?e|)hl5O%q{8}8qg%+Fz~9)7WE)x(F=`H(SVq;|`tt!(-- zwvxA!6ut&)%KbCOu>&hDYx%a-nW?juv=|E6&w-pYH0`5#+6e8XPK?67h>R0bkFzTv z9NAy|+&!>BadVW?d9?#rzy?jkgbyrGPd)i7ki+zDcH{sGw0jV z-szJ*WcgFq@~iK6=r=hxz4INOs>y?qtLw#19SrFA6De_X-wJ*NKl@{04tjeaHEXU(l_KutN#M%-3YH=G)O!?3v>O2ICfSPio ze)C6uKm{RG5!@vT3t2_&y%UiAF#hw&p{$?u!E|A5eK%=Ud48SM6f4LF3l@mBGj@8h zBf}&%_Uy-Zc<$ykM3cIvI|W%qx)X6`-PfPYn;5csouYkxRNK)pz)uw8APHzh#^)LQ z9J~dAEYi9K@rCN*-uX?r91TTQfx!g3$L`LbKVSMz!h>tiCoezFFIY4kW{w5T_7sx|&0>PUQcf8AHG)8Xj86=ZqGKg=VG~Oif3o^~6=yfo z#HpKcmjE0HI?O$DSMl1+mEWAVk_BL1VxAY7GG`2y@Ii;=15EyC6%ttt!W~gI!}{&4 zwS4gUXL1e;T7BBecfZg6v@-UBef1UNXHI}G8|Ge*^6DRtnb|ph9X`lQf9uWCk0yv4y8=H#Gh;)Y;rMufzxBS zEzjHyWVJiNks(LN!GmK0s}v8vzyOmu2rE0JG!2ZwnIjQ7J0{S8u2hp2(qc|Vs_o8R zY?vF2g5ItP%?Eb+mi3WBjNg>!6PLX?e$X1emeunQT<^I&b676pJEZr2_pTb7*3_P{ z`=&28@dw-cHgn~n+{e|G{nB@VeYx~FBxl&M^W=A1y2>jC_pALAOvMxNZAR~nAGaWH z&b;xg>a_v~*4`LhrN?`GsXb1v6Ftz6J4{~SGFA?Bv$5FXii&g!gmH-DJzqp`hzcW7mh;;mf$!kfW507WZFJDFi%7kzEw>#;uiLAkl$0svIdBF(;5%Hr8 z$WqG1i+tS0i_*it0gu0M;X+};-@#)WTHp-7nlo^&BCKZ`mNYw+;LL~=tzmh`%h0VA zi6k~hZ5<(cU!p=fxI_v70$QI79?e&IL^rU?q9o`S&UZ?!UT(=WpFb}Qd>KB$)%axg zEa8*vXD+)3q@Y9hRxT6W@cqjzm_7OPaZ3t6D60*iXrq57iD?`S;e$vD76m*1xhn zooCc9K4`6seks+Q+_t!Lj{m(my?g#@`Kkud9t7?r`pBu+TSg8##Psr$Xp*5`lTWVP zx#&;6aMyBpYqnYAL|-NGXZ$>t8h$JfvHfrJ@8R012>04?Tw4?RL%_{`C0vSJRSGWu z@DAr2C4&12^LZIAES%>yaK`~IX%Jc}l)_imIaV6@@M1Q-vVqE~D66`!$oK#}sV4fs znZdb%i@Z*_PeH7a=({kuqXc`54;X)Rh1F(PA8vm51!M77_yackPM6-d*jt6Jf?1v6 z9{w6j9E(eZe6Wu(SK_H zD^h8sKheH9SZhD{pD?h|q_4xG(3yCk>s0BVaEa43Ea@oXNA`cx4-lu<;b0vjgzF#L zR)tJ&cO2Tq;qce@f-Y{aYn;z3k-mSzpjZk?4ilhzeiZtX)_Au1(>GFhgWPaS0c!_@ z5y3)*Jd=-vxE1iByhY`G9?bZoG;4zWJN9eZ4{`0%_MJDHu4fUXQDbS_=I&ki13ct@ z2j}zmS@)da_acuR;pb@nQQKALX_A7M=jm6qF1@MA+v^da8T>{2*P#Ge6gZd@gx)Pr zHm9KfKgHyiQX=J4f?F*WHvj2m2 zX+Eflc6D+4$HwL6#WKe{UyFh^h5yy!HE0ye;uYLW2?8GQwwe80{t*i)?T>l+`Sbpe z{9lX06+ZiqKUmK5-(QCUa1gQNa37(Z(93ky6ASj}K;|d{+fsZeUu<^4j=_yp9|Of% z+|Gh`?63~{=#9pw*Rnz$e021pM@UQei2Ly0wQHT{&i};QvNo%0zg=hIlErgcMf3C4 zoBS*jXRR5XA2)78oBqfzjIdG2H)>bG*R!IRol^y0N7s}9r2aS)Nx5bmk@V#ZrLstL zDp%2ItFu&Pmcetm$=mrT<>7r08OalVi$rFV$Os&FrF9apg@22Fuxvz-2oX}tOb;kx zgmK%RtTwc-c!--1?b);I*seWUL4oYAUB^tWE8F(ZdZ)0qe1(4ANjP%u9(d$8`>v2Rc&tYuye2Es@U1d?)IjXDkb>x1f0!8t`d2x!Eu&@=W+MF4$I3K zjvA3y<>k3}MG>?R7LPcQ^YV ztz6v~=|k>C>e-f&Ygg@Otv}&TR{NK_SL^i>HbxNiWv)f4fh@o2V z%it$EUhU^j)m(yzojQAUF_6Gr3{H{(L0_ODHPJn|c||)%cTZP4M;tLQ+4)v2=k1pg zWJ8-EO^AYLHJ`1%PSUIjfy>>@zDFxn@luI;hCC=QQ-sk*bd+>~4LLd~yN=oRhek;; z729q5MkhhX-?WMEpaX z9@9SDY3YhDwtnByJhK06E4)&{6$-i~-w9ToV%UAcF)vE`~ zNS~cjirm!3A(5<3L}CM?dpqL7+y&p0@r6R~X>mYsBv*A*AVe{Rf+9kNvT}2c@-6k% zoB7IGRor>dUsv8JN1-6btut#jUxGTSYm*G&KeM^@^ z)i5uo&dUb_d<*js$>s4w)|bCWpIdi zSJ)TQ6RX3-i7PsE5piiwoj3Mjp+Pl{=CskUmNr{6RjeBY9X--wJWtui%dcD4tM_}X ze&KCFn81^F7CgtE|9^z1xP3!oLBF^AY80>0{k5~|ZOnhd&bk&iZ-2z?wzcY2T%jj- z72`%eE$VvGW5g_7AWAp|j3^zCdQnJ|81NENd@&_Q$?N$yOM7;ZK^&~k9U`+ z;mV*!Th4@g_f*c~e#UG=cZOJ=&Vfc;t8m0+ES&0EZ-7_OXpqmFyb%)t7N~kZE6RcS z1hUR!%4c@zoKbO%{aXIrT9bEja_f|L^781eM{7fOX@h{3Bw%@BhYqj|aMLRkw~WpO zxIpUTVjEy{z}3O%=ZkygEbG*Z^h7)9utQ*CpLxe~_(0}*O35f}w{gUigfai-H{LwB zXX>zKL3`!hG}bWRgaMWhMeFfn4ziHXhEg1SG7V+$)y>sGR`#>;kF3dIy}Q@9v>H3U z5uf!)$`9+EUf&X#+CPI0;LD}urud%A)A%!HpS^QzsyiEK9Uw|rg+Dv58rqFEsSRnc z$Bv;bGrqubqKjb0V;2q=dK>#_wgyB2cF76Q#dMw=6%-T`P(Azx%c}#sikF+_Q4&fW`}I zwH!Kn)##xuYiYC`fxOxo35D_-cT|U^1l9n9V^5UuAbBSH>g<&d{OyF zbl{uH6-niaWIS@XddK;17M_>mHheKHMsmdlw(HFIhSYoqaEPbOkWuv9h=_K=vnn_W z!V&He(_xG{fDmp1Xc-S5w)amQ-j@4MSP_%jIIuIGOY z-MH-dj>E`}Qq((5=jN;Mzm~#~^G*?ci>@Mu7{7VJrLZkhm=v~63bTG8?mdwVbTBS+ z3^dkw&){q_CerJWb;z_lkFL&hLmPSX~2tTG5}flUD94%CXj? za@6fGFd4~AsqHTI+GKP&OScec_ z@q{u6w5hOQJBl{CvJFzT;`-~Mg(3_$wP$IFQLspRwpUR2Eq62fFUM}TmaKI1XilJYOEA@klYrIxp#N$MLl#d`dnDa$_;?n}P zd?J~3w*Fd{ME=0Lc(Fjql$pxG-7qoJ~Kz)^;f-WKdKB836 zrH*Z7A@m8L3O%fl4HwIPb-@d~D2q<4|et&Uu`$b`OwNv)Qff44375He8oE3d$2NomM)6-^TBQO9t* z$b=j>D3>Oq9B`-v`Mw|>rQkh@d$`7{uQBsIM80(Woxr#ryMCCT{ zfoB=;0|_qZ6;D+-?5PcW;8`Yotz3h@5;B~EE!r(F;lC1i3i#?%4bKQ;rjEZcr6`0C z*YOwS0)M?6@Hd&)njFBN+QuAZGTd7(gK}sIQQlDgQSe8HA8E|N^H;&gQ)N#X@FQ8MF{cdpkr-S*0RFqYf-zX` zEBe=L*bVsI1^!gtP%W1>8YVfKT(P-NaCk!{U9RmI==!d}vyN1;C|)f`eJWpTTW$kC zT$*dBTn7AbDX{2a3H+k?Qt-oBo(jJxz7%||+y;Jxw9K%q4EPaJWkX~M{Fm^L(Bboj zrQmDjHt-_>zbyVlz7~GuE8uJ8hDrRITvcul{)e*=ehv8d5d25E(!#dfb(30NbW^UX z?4kOG7Z`uV^^0yQEo{qe>l?R`eEz+@ZF#Bs|EBR$bXw>u4IhGUv?*8X7j5Si^*xY>Et)*zDddFepE5#Ds2*nN6vI*8P%T#`Q@L7SFUR=$z+97J z;u}B0ti;6kuQ6v}^x$v;*>e6)bgYm9Dbs40qOKvQIj#BQn41w*@Py*=Xc+)%h;T{;0m^Pzvy?(x#m2*-O zS_SrI<>#jNoISZojkb;Bs)RRd!X`Fo=jS`N7K=Un!YjCZWuE|Rqbd%L7SE8HIf-Jd zU_ShuaCf~fcmf@$OcCF2(07$Ka|rsTos2Ddl}4@nYm^7NVqS$V5Kn205j;^2dkZs6 zyWwDoTCPkH<*>I($_>-3Tg){D{5sNgz5(z*QQJki3Li5s;ESgO$9hwP4^I}Avu6C7 zTCTwlw=LK3uSc>d&oFH&fsa1>+FTF#tMJ9sV*IIGg&%H6Hf<`#pUPGETDf5{KVWPr z{RX(#MBgvQTpc1c6KA;5qk5mBk6$GS%I(mq?vXJG$ zIBg0^4p1fCJt`t9M$I{cSmE#lxx>kabSH3l7{xHaCPR=(+S}-I$K=+5*6$rH4ijCy z=f265q;NMno4#dZIP9Y*^+ueMd;{Ay>v*D;%etzYqKCiTa&(o}u?>Tp1;(**QwC)< z9XYPIW$+J8vcCJ?JEr!4rf(0AUS7eh%3RSg`558sdSCs{E6Qi2?fCvc@FuV56XQA4 z4bnT(2+V^f<6ynqbQR@+uHYffbM&-WHU^^{V};5M$;Mm7vO(n-GdAUmplwLYh@U&u`-Bnf;ICE(}J z0w3M(EU_HzJ>{o;9%k{NU#zNYxP+zMPniV&6nf~&?I-wRC3)A>hL63>(5#JvRI!f@r z#)Mt#iWLm{G2D=)>K1-Y*v)~i?MuoHtZ=wVLDY?*w6=Dtp_pT0{i7c81`mE^AAfJU z)^EV%v7<3mFdrBYFfUK57ehhV0{y>dAOHG*H!xjWHG1si0sTZhYb_HvVGbg1gp+W8 zivw(a!ledPqU2S3Bhm$zxbO>nro)VAnP zz!{^rsp0`Uz-%0=mkC>aFxdub8O91)6L=f~&V)x!>AENjQp-x}@*mOGSExI#q%O(^ z8!V_R%JjNL&y7f(@Nj4=(qs>5u? zntTNHp)0_dNrp6Q66prue?@tSaxv!6uFYCTl#4N^ms7lJHjeBQ;tOO9-w6*9*BT4* z5-~ev5i+)_Z5K95d9Pp)DS`ApLPnivJAA@NTfd5@I((b; zYi&bT34ELNu~u%g{s@!JWvrh9XZ6Yb(s)6yt*RmJY>dyOSIBsnIUgddmC3B+`O9ZM*CVfqyZ+ehH@4juY+ z%5VQ(%j69^m~<;8ZFB2|$=`0w&AvOe|C>Ff>K-00$WUl8Gr#EGt30E7HIMw;H#K^y)vdN#`q*gX=e|Y13q%VtnKZXwtQ2 zYK^g$EwP#50eZ`R#W)E$7VB}bo(hv1L4HcD$AulC_cxxZ@}#6IDUf@0J&u0W{S3y2 zqFh~%YvqPXw0^|8Qmh-%-}p}JOoI;?t>$y3m6ST2sFND`%GGt1RHN>}yP56Vb)X4m zab}Ot!^8Ua8`aUb#tuI_snPhAsdHwIZq*^wGA-BF9B8RkuFmkPwV;R8HdUHfGeMKh zno`h&wJpgoJq1l<+x33+;S{lvVE&seUhh5 zi%cru_xN!Zaq*^~y%adyt6!T?OGEziTgxrEb1&CxN&XhmhI|luAxs+a^12n}`npv- z6}q=Vxhi5Ul1Vs`-_5>-^c%(Q3vkDxGfEiVbYbNs_6gBZ#}I4;1Pu_&RU$%VYY?JL zMv2j5NsS1wxFil;U=a*nI3{UGfKRK4xlVO@CC1MQ^6dE5skS+}L-?ZsmcfiI?$xe$ zuW>yS8FNgu_&ZjscR-rh>%t{u9P~sihi#eYhm7u(%T;bZVV#$&Bqi)0w5?$kR;>kV z`DgxTxAq5m21KkKykJs;pVzcbz-f2l^RGBZU=Nz=kPTQY?XW5I#kHU^E>=*fExH7G zq$XHyNPJ4xwB)SNwwBP4{zF1FTGEsI2KY6Ko8ugjk<_?%%Y?c0eZwuGZL?3VNzBd~ z-|zIL$ZZIi;7&N78vXRso?poY@t5>5bSldmP2_e_Dl^=u*K{nKKd-BBuy6zBiEuPX?CH{)?oocx> zSF90GZjKY>*qOvQsI8WhjFoedXkD0v{=vO6e7}RF6A6Y^w5JB9$6(=Crc}WR5@mu^ z!M;UW1_&F@f#~A~E)bbiH_0DqQ`2bvYhZL(>$KlWi&x+78$x`8wlfF&;87C>FK(GO zDf4hG2ge5Olc!DZSM5{hl*wBb9(gqN2$SXncvW#coV&VBX#q=`J9x_Cxs~FABNq+s z*}Mjm0$Tjkrg??(Fczwek>c77KHaE$^I0wk-zbreH${TB3L>+EiX0t2LGT5U&a2cK zMx%>vyV3a;`LaOd@VtPCl*9bj)~Sty`tDFA(K)P7ua$Ypokk5hY`MT5=q*}5spZ#T zE{WmDRL{1NGds>{((JT8ZKr9xP*}82|fqCrg>YomckpE&B{V$#E|1QT)bU^ zdYLFCx77Gmg1jzc3&O60?BTn42W-J=G&|Om#BQf^K&;jUHarN>#fr=WCDD3_{Z3_|5a1?BhBoEBoJ;e0foO6_8^Om#(5cK-wIyDyT9A}NQ0zFnZNa#(!Fla zq=TK-=kY(Euc|qS^*VLUT4(lWd|1}e@odrj$Tw>ZO^k?09NxWYh)-f0%e|?C1~*tc zMp_o15#_Jid-8Lo7TuVL!>v!%-o({QlbB=U0^E$q;1HAW-i74ov`;4$+&tW{L-V-S z%!jA*4g1n8Jv{4Y&u4a%+H9Ru6y4l+s^#NN7F~Yi$Dq%jP8=3{MMMMSE+!&Xg;K04 zCGxr<91Z!De>;6)Ova!l^@B5$yec~O@A_NU{*D#B+N60WH5i^T=E9a}uiE|k)jo8{ z66_z;sasH(cg?uyu(0U3n%-eSz1w()23w>~<_bR5d-baBQ$dVX!GHM1(7$Xf^uOo_ z^t;+GWYe9|#^hGrrjwteexU2eS~=cQ`(1u4Y`wEu`9`XbwF&l)j96cKgc<*Md2fp9 zYkO08S`5Dt>g#(`VQg#3-W1-~_ol+w5wSNlh_^JZ7VyL6_5wa66YUOypZ27}P`|Fg z2mW7qkcOuUzn)rdyZ0sFV`mt;DV)U%_^J<))}w=keBwKNhpxB-odo$L&{8tTC>7ZW}qDhcflpq6TGmA262%dG?3I#fvNo7O(HNqkaRLfwSa*3LdmO71jw z$imP2@NeKdmDZ1&GQaDJ-YM#;cjbt+%CPo|gO_hLXGi-=X+vuTl~1#;QpGFK$+24P z@OFVA1;b%*d8K`n98)heJ>0Kq?Vha|llQ9YX!3P_h>iUX{=wea6olJ;j_dgz%#8CO_cikI^WOv)P)?!s7Fn18w$p z6z5d63x=mUR~^R-W_HSIhFeK2(b9NxaI3aMcD0&(R~e|XIVwDOZ<8AC-I?>;^iiWG zH*u_ib-T)Uwi|5|CcbB%S$Y`izVWal-NhjZ^vQ&RZI*fO0eWP^xPDht@ zXtP3nQ@BMm->9-w#YCljK6h1mN>3rnLs1|Z@ZH!?dK34;fLDMJPE~Sg+H`ZJjVrRM z@tIC8;S{3~4VrH0pIDzsy~n47y2Y5>>Ia9{ubRY8R;u_`@`1M_lPjOkY1~cP&?dcQ z$8Eutf&&L6PusnvmV4cLo~~(56{;pB1#fk*YnxgvwaOcOF&nb8Z(Ob5B{LfNx7gn_ z6y99I54P$hd9ySG=klp{2p81^5(cF@>z81S`vI`RvNIQdHZ-yS`ZuGy7+q)eY`3R- zruA{db+uihgKMRQcdulQ?%O-U(xT3Rw(%XiTHZ-*<{Z;3Ik09zW`Jn#GbJDGRabR$ zaeJhfLA@>ACGC=VNCq&Po_9lSIy8jZ?$NTzDJNr;|Dfb)d$_B>!RTHuC@7|8q=tsS zAK_8G!v}R5hFZ=LDlX2%9A98VvMTm`RQpP5B`G9`mR)_`2(?6c*KbuRV%5$mNd_7HEcS75zAntr04;;rB!{XLdbpd_`4`Q31VX{W z=OQd_t$T1rnHC_$(#w|k*9fZQUav7;bo(nhHLQ|zSVWu9cHe)+42cfGt#?mfm9uD$ zwB6LZf>U&zNls?p>a1eb#Fh=h1ERx1{Ja9j%q~BmS!!a(4&BNHIUGvbf91RAy8RlA z7+llBk^+Jj4{&e^Z|dcnklGA91Mcdcli(T6=%nG*oiektDlnx$BD0j6I(X{bX5k1RDE7wY;%m9xtY2X3cLZ##O1CnPkj=#*HSjr#L+^U6~@3^<9wI$*|@hGW9!MGdrSRQZsgwS82gqHi zeH!7%5c@Q=pKe4n5kf=kor@u-?JDTPfL;a4U}WhncO|7et6kkIG`ej^uUezKihrfB#;s&|MDES5{g003-(a(SbCdnu+bs2s@(rnI7hJzVsVx!RMD4`V5Q`@>jFRa3 ztuDOx66_j@Z3j%<-PegFbZ`7p1BFSuI(?cB{N;vOVUBa~CzqGEz@ zL5#F`BUQUVxtPpqk}c$usU%X1C{^UbLZuLKaW0xnCOa38(6sa#{@+{ro$8sn|Bb=Z zqw03+7H>`wRSK=UkWywsbb?#uD&8TTyCpVDS$8_V?$M^rhjy*gGp1|jX?<4F_``kN zyGG=$!XBbMRuW*I8Hsdp3O5B^%Bc zJyKkaKVlDFL@Z)Ryhh3eT0@KsXcVDU;F~}UFa6QP=z_5g&hF;l&CY(j;j=GqjNZOff z7%?8pF^_Ug9#r_3Y@TAxk!Dwy?PR+t*0EM{i-SH$kzz7l#d_FHWc;8kJ?`*tE530J zv4b4Wg3fniGuE!FY#$VlkQ%4EeRi&~z4K9SyqYuquRgr@6wA(&c3Ich`1BnM?a?;i z$!m;Hglz|EDSqGPUAb1_ zjpEnP-ZBtD`NVO)7q?}_g$!f@^jjvSUA=1Ea`me5dVay;{CtJ7k`S%&sH^5+Kz-z0 z!fA3N{+^eI7v@Pvt|`{#2+Spg@P!SA*SJgo!^t}=EJs8lj3KK_A{ zqjRjkkK*pkVhwS=vXig70SDVnK;JjeVA?ePG9m?><+m@7AAgzoAYy>e*`|-Z>Bg@iHac9Y;UKwsNs+NHceY}x5f~jC>26%qv*)_+9)Gt^ z{loT_+23!qf3rRQXG^|+{QcTqz1FIKU@82qtG}dr*izMat2~7MaKaagj7b4N{Sf)f z2eBB8axg28WIR8_#N}_8%zCqT`BbTE-)jf|GQBusyyl9igun7Vi*z`qTHqPR2#!RT z!~TMw6Zm{SpIMnTKcCB7M)z!xdcFuzj#=N6dKHimNHn&TDj3VJ`TTWUusU`g?9N#ywWqyms{d2~B{_OK{^25awTeh6I7!Omf z)DLi=^lJ_Q377F`+~)wR>7XRzPmm!GgTW5h4JB9zf>IefGny$WeZ>Z!FB&rs)DC9l z-kLdYm_hDUEp#TeM!8;c#0ER*<6kV zN$q&EWo!{!yo@(vN0uS1$k1idBWYuA>W1Fd9@ezpQnqzXZ!`w^L|Z?gA6;-G2Nu4s zAK6;8jf!Ags@67Frs>fUJ1GcmCOjLmd;Yem@4c71UHg-fJY+~R|5g0?v`X%K?A(Uj zDi<%}6R(R;@+@nFN6KIpIXKzcQo8JsGIYhVp)^jx6O+4&KlBK4>6tV+mmAn!UY%6LG%=?BC2ueu0)IsAX+v}%TyXA@{y1w!m=gi9J~ZKwzf97e zO219mHDSUoR{K6bet%@`xVYLQ@3SV_r+oF957n4Z=RO{cs$I2O_(<0DKB{Y z*^+N#4B6AE9SWN#vibT}rXZhmozQ%K#?+^9`)%b0zzX<6Ri%*GVceJa;-)ds`jxIbV54hug0smD8l2kJ>==9#R!ljj zSuotljjHit4194@*p!&-NLKMK=+*i@NYl|YdqB$Z_Iasby!D%W?kI;MOBvyeLa^G*`+(o#xtm_3+GIea3p@8Qy30v}g6z zXH=ghs4y9x7q_RqSJb2QGsyfjV@nkmCD$>KV5;9(uG)euV7ydM;Eoz94LFlS?NVEM zJ;I;kJPE-AT)nVZ@pho zUzMNI{MPwQl0rSBV)FO4Rho6~mDCgO+0s(nc9{@M^SczMb(kjNcp3FdV^Ah7Wx~^X z`ehuMkJ`tt;dkj41?{LU;4z<<;ZZ*m?KW^VE|#K2P-)XAT3@Sgz6=wvO5-4?W~F38 zZan3#k8T+v2ScWt8MC|x-`E_(XDakwK&@F`!)4+ei!ox?W}(lEn-Zoa{0G0t@Dv+DOC^O%Yyee zev9|YtgDYL)S%I?wonF4RjvisU*9jqZI^;rcH6{{lF?6`d`&%VWT_awrd~0QDkf#n zBKn2-*ystgTt+>eX0=z$1do-{J5&OhE$(NvhCZ{F2~(F_O`p6TCUCT&y0qT0ZJTJJ z@1##uc`v(d4L?=Fg_QkA_0W_5K|R4A%p4F8tUYgGeTvklwED#26V4)E_`Ch!+VGWo zTw=dn;$5VAJbi^VcjZ{At|#J1#~Vkyc#5A8_8#wLyne3m-)Pii_yn+00jmPm%oI~J zfHF)ViU@hU-JP&}hU*nRZzKkgouXo+@Rwp=Ff68P)32aUq`nVdoaFp*fpsR!`?-Ep zRQ;cC`1|{w9tyOfXAh&C+b^Em`uGfKkN)r=(l= zla|F^Iunc7ia!FWDBxoUD#?QjT*!@vgA>d}#RKijEY`^}=toIL(AQ^)}WtuXw+lxHVDyE;(U8QT(jKq;}Tb zd?*XQaKU(8yjF=|sBMqJI)5JGcvTlS90UE~;UFgkTrDDhxJmI7Wc%WplkgEaIbtg@ zdkQan>&UEGM;1=$)0wxIoRMH+J=|iW**w;B5i<`fY+tR))~!{Pdzmc~3+g8ZddIMb z+14o?I65T<1g_6G*Iq#Bz_OSz=uj{pnFSp zw$6hWPw^SYDx{)iysy+%^p`8~(A6w9tpa?V98Cz`LS7dZ);X`y8wi`8cj+#F)M(~V z0NMK_+rD+rpN-|RUo7TNo@FmPt?|LjQp(5gZg6KoU2Pz`^9H?b8~M-o3st%_x^>Zx%+(MeCvGQcUy1AmtEY_B%6bo0f1+y6OijT2hI;8 z{6@h;4TyouU_y}>{$g&IeZr0J!%ad!%YUF7;oTk|aPOSDm~=`uuk~@Z@!}TQd$u6v zcZgQw85ZuiHH=_B(D*~3aU{e`ailr}%QvkC-b^FM`F1J@tf@6Rm|HppgX4feVgzr; zAaOw^9hDwA`oasaB=Pc*7hX8hXC_k4oXK67IXz8x_uV@BQ$xz#cc-+TmR)$~J?=j4 z{xk2s`wp6jCcXR4#mxl;><0w}tMr5&OtA4;?T%+q|`rH|P? zvR@%)odctSc9pn+oKjJwgp42v78_&IbrAm}J6WC40^KYN$q{9m4qex@?!cT!_NCu^ z&;Hp@?q(w2a==3z^=p$Z|$=r|#+&Z+ecqG++d3 z`l~6ybnoZS%w2Trx6{)S3jWQF_f*cq9c_fs(U&g5ynGU9g5{fJUaIu; z{FAn0vP1Uoxw-c9PF~zXmf+#+rvTqS!F6(&j}Qq*fM|HN1F)hjT@7;^8iPSkPFQrn z9XM6&D{GY{vU#>Uxvy4FLKB&4+c9qUgcT@-nc8Ht zTzL203(V`bG4P(W_faNF1AfD@_*pVmSh-Qdx}y!p-sYLK)1MS8RK^o8av+ zi_w}%TmvYMzVOny6;0@nW61V5=>q#2+r#krCcPXOh`wY4xDUWRgZTKT8Kx;L?vVLv zW@clEF94A)KqP-ZS8x)YKEBH?uNemb&kf6n!jztzMEh~|=NCr*apsOm|eOE>Ox+d<)sw2Y= zyl!uOYtii!4h^~Cvtr=sc<#x!in@=RR94DO?YV9lz4G0)v18ZSN74!QoA*zd_|gL} z9P7JsLvHRulgY+y7|PoJ!w%@%=VN4#n!4eJg#ar{?Et<~%cEf)_7ubpIU*d%U@sdR4Ml~8#NAI;htThiL^DY zMSsM_KUm*i6ES}5gYj|lX!`?A6S*URydx8v_R$OXtgg`6mgy=6E~sZdym&x1gll4^ zPg_{Gd(Z0C45lsgon^iT{KeyyPGb!2afj6&R)L>{ziH(f54Oc7G3C!Sl1wAs^8v!S3s3L-#OQct0&5ChDbSe-o2FX=XTD3kG(4}B+v~NK54u6?2)x6oC->oRXx=jJBkrfo=-s1V z!^$7fqB~4#+@mrCEP^PeE(Y5l3W?hvXD*Ydyr)jjt`<&{Sf*t*OZt&wSO?bY#ddjQe@qF!lnOGX|)j zz?od2cQsI|gDj-;UIh@(kjj%m3kw*)4yox3rU#}5(1SNLu=$2Lm6bQk{%xB%Xm{hm zXGDsW0)gJ=-k5)CslctMyOdR#i?)hW8)f&RC}z&Z+gD|0zVPBaCy|==*>d0&RNp2s zH((CNv;q#c|4quf4DJ;s>r3zz0ka?adP2e(#u#1}GpkJeB!gYhNDjsc*wnLBa8RF( zgDtkdwfq|m?DxveXFlQ%%$TuiC-)Q^9vU|7sC@@r{nF@Cbm-zUvW6yS=g7Bk|3dpv z;Ek_?E%!b5Ts<1dJp~CW)0jKx*l%BNy$?tW`DY(+!{{)$ zE{MFpgOb783bAz*Ku(+z0)xcWDR3*auf^CWqvGdJ@@J+Q(ZE5C6AvHOuu-jV9UKyw z*Z1e9y!<=a1Fak1pD;mj^jo+$>7OSnaNxn+?s*;!q}ObOHNLlZ*=KQ2HMPj2ZPU@` z_Fv)cCIKgV06xrVU8m65#-GxcxEVB@dY`I3a||3 zC9ztAy{A+U3y)rK0a8l7zwiURBv`fDyu=Lun+i>H=bF%m=8U;>GuY+uy4&;65Byco z_i7Z4id#Pj4P~AW4Ykc+<|gH=;?h>-Fpaj`5_4`wAFTqlB$W+LU1bDNdGhhgT5X>r z>wEDqSnQ`nu`H2W;@Di}l%DXdLq=iO!&Oc(54cLFr|so}Xac3NmQzT@lc+G7_WkiY zvqK_=Yz4Buw!TtP#Lq$IGoT@Z^Q(CALs%sR#b70Yg%3(z`yJrs`9CE@7N+#ezUN`? zX`UgQ9-lIqQT!=N_4-l!GPoD$ALdoKR}uxet3(fg>?I8(z^TUm5lA>kTV{p`Y_M*y z)s1_rW4+Bkkhi`eYYy8OXu2t}KHW60@WF~2qcLe{R_+?}){;K&4!&<-^Sp*_g+ z5F2ML9yfHrz-(pq?du*os7qOvpEhztZG$1Q`|hoKj~O9X8|R8L>twsZK1%@mBHapd zPp$#m3{)9@1t)a1$8rW7Mf6rC(}Koq#l4{G7rekd_TB?6EzLt$FqdrB#|FqUxC2f0 zp|=ib+Vc**s0j_hbM>i9U&?CP3Bp`8;(SyrSHaVTKU%^5kj-3*hr+^ezuC*b2wVJ)EQf!{X^-nsQ1^mHY+6W$6l4jSl>pUFjEciW2X+eZw_Vr;D+-N|fhvfa*1Z!Lax zc~ei^!jtraoJ8&i{xk1O#NgKjz`K8$G4{n9>Gif-nIG&o(6_e!O5bYV>KIuQ(4&dD z1BL`~K<_}WN!VsLkZtg&9oHMk zb~oqs5LHmB z3OSx9Y|9{K1<%VT+j#tE$@2?@x=L< z_J`ST$#IyCaQ)M8|88U(>JngE#3$5X!8Z7niigPYQnC#^FXQ1a!`s+*gS-(uUeN7u z{unsU!vkl+HulMK*yV5>?gZP?m@)k8^t^xxO#i2CUJ) zljHsP!?Uz7mlHMc~%m^6oNAQ|we!IW({Cmjx1BCPG61=Tl zBpg>Hk^5gKY_m;ddl1PQmN0Duy3cHkSkLJ&Z=kwf(80&hBhZ%bZefCpkfpCOTEFrgqm39}utaV@Kol{ork)jQJOOt`cp0x<~Qdk9Hd@FHt0L#&XP3jrvwM_Lhux=l!Jm{~iC8P#j` z+t3)CIrtMw$s075yGUoWegka;c2_KInRUlYP3VoC)mu=>n37m_?!Kny|IU5FmQ4Hk z^rQp3wsF&8EOd`aFQT}8JMnlJ>K?$|0vJyk$Of3bGAJb^<$|hozR3VKha!;$6fulT z4mGflLS_Mtoo1+42NqSGK2ugu+HlX=gs-0X3WaT2wfO<=t<#H! z_i9S2YYwYb(mO+%f@obxdC;`#x1V0IU!U^w)=z%CZRj^MH>J_LxcH={BS>x{Ljf1C zhY615B!?8`= zRKY8G&Tub0_tpy^-^^@7=j`?b+gD@I#}n-R=nq2b>HjuyhTvbg-hY&@17`tzQFz{d zz$bWSFm{mNMjV>QyaxskZ~3YVv@s@#apI&t-~({Nl@zn$)G03gjW?P~AI-^lwCd-F z_od#+y+5vI+Am1PUHFyz3=*fWn>!g^2O2vDo%##6jWg^lPzEunay7lNyg95Whnu2- z_f~g@7qV`mKSB>;Uh4q^dY|ACbh}eGfnwUpg};w}YJH#GY5$rVOvl@`4rXnF;O#uX zn*wUIJ_ntG;RplX=mwI!1mDkyyCzT&n8mKM+JbGgG#&6R6g3dm&_TX$ks6zztZH3~v{rU0w>}*}bDrkIiq>|K&;9&=FsPy8 zdtAw7ysQ^`=*nfh>~`s~1G>tkF3hn#32F=FvI*q=;`O|&-wL|G*?R%TBh)|1Wedpp zE_Kmx+@-D-wq0sXVOywWl*{Ij>v10uXD=H#?$QSUwuQQJxeSa@ye;iR0^35}w_FCA zK!8W+*W)-pp478X;;(n~;F8OD-6!;vmdkkEC-gj$%Xr;J@JFs6CqAFx3n&fu7x6QN zYzuYta@jQTdC9L@&NUw|! zg&tb$F{XP|x(3#wNbTo5?hIc;$qr_|1Pi^RHI%R%=3YZdXL_%p{ODsOD-&ucxqmV} z_#(=ils<|mdp`62S!ogF`uUO~O1`%iz~oPFt!JIRtfalQzBuW-x0VB^{~`U+bJ1At zOq3ksmaoTVUxOGG#AJQd!P9y6BXr*OTpxAt$?2|j@XJ<6>fq@|;920MAY2g&CJPDE zndwKM_M2OSdbwAB<2vX!*>W1!L1R4zlF-CoM*{nvbdgIXlkYnV_31?BRKtzb|`?ZIH?bp|6H~msm?4CD#x= z#p4e8dB~%|+XcDw67>Au1U?Jkj`<4D5e@GP!hZQ_em@I+!C^l{F~P2T>Cy}G9N=dY zcpKnl;czR&N#Jc`LQ4}bHQNyUb(c6YNBBvI`H}99o7Ch!-_ov2|ReVK_tjq=RW|547i1eA+g_{R7QO$?No`| z{fSNYB#i)}gC&ihA5;s^55psH=`n<3#eiP39{!4*kL0936#Iy?+0ft{o@(8S+f<-j zNw*>H3)>hNgtO_8%+WSe()9>B4>@{hVm|nT&^wozF7SZ^H&rk;h-f%)V{W%`hyi!b zBFI4_+YpC&5W4U8j_^lAW?fe&9|{sEhp$Vhkv9uC|I z3@MS8tXyabLF6Dh!3)ca7(0Nq+eL}_s-r;!7K%?p>xePeKkdMpvxfu>2hSU@=bZBf z&qq9OFuvfOYRh1pWlntIxq)9C`j0-3r}B| z0}sGhNdGhGEF_q7Yrf{}j|PK+xVFd)BHCPpG<0TkbZEoKlC2a)yORsOv}MD+(Li_@ zg$8Z{-5ul4W$qEikKy9!j^#6ZkH$LXOc8l{sXy47tEsP6@V3ayJh)4&JoWRI%Ygk_v8mZuZ7});7BqJ*icvFFe zTLCXFqKDi*uskKQYU1hvlY+Fn1~iPSnUJd;P`6^%Htu>D4J+$blagJSk%6oknSGsv z(}s=BE3ndZui-c6n0NF_E9g7Lyz#9q>#|KiyAfIa%gnGIo!QNNT{<{oxPHBNh#uZ@ zgx6guT-k~svLVaew5j#3;E`xNecYDD{?Zx>xWe_{;<>N~B2Fq3{9>VeGI->s-(F(Q zZt9KC-o$)lGj61h+abaRey(txhU960-b5aF04(6uW$}iJJf$jLo1PXMuTsLd*nY8b zQOZB=5FSGxPt(RnDV54ZZJH4u!spocxj!7&JM&}KKo(0LRfxL@VzFpS_ZWi5ZbBgG zn1Y`2_RyDMj8T!1ssybOe}j=EXfFl{14UIzWkPJ<*f=#gfKO2=X_ZoysO{@GJGM`3 zyjp4d)ot){$=I_X=Ftl}PC}g3W0*W6Np_PyJ^bL^A@vU=?oEIbk5?R{mV2k;V4`4* zl{!Kw_|i8H@PvY-w`~J-;6;IMF(3hZK>T(zHJ+L*aE=He_yRyn%7d7AcN*DC&UH*S zyjRM51RdlKQZma;n3;I$IQff?!gLjR4Ij3D>Uko(Ho)UNYOo4|_7N_;;Dlfk!I$8(_a}2@zmS zf8lNFd&rw$C+@KpsHTR(I|5cxw@@wA2A7#DGB5=AfPs0%Anw(Xy%MZyF{@H!uSsNU zypzT|b0O!>(K}H*QKD^<5u7RIam8NGDQ@)K#l2DI5Uzk|El4h;QpM9l>og$e;492& zLH2p>vft$8+KY+Knb0T*0wO!%dbQI2Up#p{$H9vUe1001Li`+aP7ESl@mx$0&%@*L zcAD*Tj|n5{C;a~NBG0keH`~E;P^YDm14}TKl5J{tmUta0CV+3 z|ETJ;g7?%>v#5F0B5G-y{3Ff@!XlSL?|Z{3GuBhZD+6Q;c*Qfy_0;l#H4sD{CD>N8 zs5S8Z=#4n0-^T2{OxX9sZn!c;@nK6`2}=28V1!8Y1-37SK_0+LYA1CkbuV>)Thud( zvRAY)u9Ds1jhyUzKq*R@< z^WA+7RlNN%Pm#mT5^Nb%ElNPav+?TW*najft)SvZ@Z$vEzgV;pc#SVrkrMx(6`59Y zo_7F!#0t1){e#&n7r4h1QvAe*)IJbn4+C(2BHxxk8@5nKaMGDrg};dEbWFo<|-*q54^ULcvz2hY@sB838FLmj4$T+7tI+&V4rOyR@mzjipqA3uPC3`oJg=Xqxs^o&^z zb&`)lzTL}EpZP{0xJNJg+@b)vT0TNo^oFe8)ea4AhT^kaEHvx?O zpqE4y0g+~6*@K3F6ddwZI4F(iI8Foa*!?V}?H3_}E%D&tMto=|fRP$3gI&v=|Um&7jc+QA% zOZOQ677A=)4%at>{9@cvu!;Hn&ZQKlJyZl;E?S&47L_g2(H{!o9YrGQ*Z zX$8;a;uKzHl8GQm^>Nk<1)hw&Tyss$cB@JXFpj-RB3J(e_oq#T+9RC*!}}-hsatZN zZegIz6Ym7+n8O$VSHv5cB#tEi1nl6n<4Fd>VDU;ksc$0GjR~~FIThEMcj=v`*M`sO zjnLPMAL^C(;G2s6i8tRA`zJm*Kvex6=X$J`U0K=dl`XCbpVeY9>U0g1DUkUHlyQm4gdvZB_UT=K%f6EW{%6SxY)p1=f^7M_rxqRHmbA~kBdX;UO zz%wP!IBiy?Um0UIz?|xhm9B=(72)LFwteeATr{t!Vz1I_<>iv&-ev6nqR;JB68|sy z;ofGM)JNof^Hk^@ave2=T0!0B=A9E!Dyit!5F=8`_fo;Db2m>({Wx!ky48=%$vq?m zy5hj9hDGJ(z`S34`n9j!6&iLU$XJH1@( z=FFoX`J!=0MkwD`0auda<^aO8MR$@>$^N~tuto;vbasV{Na88JkINbs@8g$H zgQ%(0jnsDP5kb>R3FD~|uMNWbaR09+x%~+{RNF5&s`J3+gN+!m++wM!J^+7N$%_aw#e#?|E60K1azi~m=Zi$#A@$T1P> zRknd`_9FEj^>2hO9~b)*4f$VXZXaQi{~?a|=GM6fPp;}LprAvn5EJwsS2<1nllm1w zKSznRAPRMiB~JS%kDe*QH$%b%*IZs%)lBq$jH5I-xHL zyqgfemz58`@Rk%|NhG-;)5}ZH#Y5W2_{fJ#fvkL*_-yDW<9IgKi;jLWl87UjDf|c| z@l8qYhIB}fv){S)rYoGFIB7_iL5jG0Cso<+;>e*bxpVAN|A>-|UW!1;@Ci^v-AZ8RtaUtP-CM5Gsh%g=InVQyig{ALf%*(L+zGazW8R7U!Rwr^ zV~_EQ|03z+2{2Oqu|)!pXk2^m(S}tjZ=g=YfqPH;gEA6M6Pc25AHS22lZk{;il_1u zSAkFF>tw91cOboIDiIc_&g=OTCBe4{gd5UG#p{`Cp#*E2r)1_tEnI(3z|o~T}_ zrxsRPkyhX>z=v)&P$bUIk!FP^+P`#!8D|8XbU2h!LF zspAQ3{G-b#?W}p#6*PCk;_@H$xYvMF$4K8tgLAs2zR6{?!#YBf0EZRaV>SL#De$2N zF{aZ2(%~E}H`)oYAHF}TXdeWWdVa)zt|C$WG4HM(p?#Qq{!<_7cpS9%j6IS5sMk{b zsUz&bTobV>e>vo;$F%(C80i`V?+Xh3QN0>p5`%1Mc)pSLN9{89JfdIz#tOTF z(@wW5?GmE@*zbjPeOS@36zgH5x%NlB0u&Gf2_DoUmW9-n3piOiYjX#lRGqNIz1V23 z{ZYG2J$|J?q)?!ub%CPkRH80_M+*FfkQ_eXX5l+yR( zc*KDS+wh4bgm1*fBabW`e5(6`61iNeUnFrI$e9XwA5-~4QO-jcoTO#J3LA)gXNDHe zvXf@uI8K8E9QU)7OsF*GEwzpLd;+mQswD1B%p?!Ey&|TIc$I|5ozS^Q$0c2Y0)cNI zL3HL~Akpt)54*wsm>-6N~q*qh3G;D_fCZH-6+Q=Oz<;D zOrG#Eb;v<}?zo<(l-R@Wv3}AU)i?D-MdgPta+xBaUYA=s>!(}+GIzppxeTPoy@yPDN;Y^%IRyLhU2Qn*EI#Ggb11Ka=A>GYhx`Yz@qP} zFWI>9YapyD@}33<&wBJil~(RtHck;OEzub)a;p;xFd;>;CK{PyDN^9E%*Sk86TBs{ zd1=m*&Yi6n5%u(b;tF^0Cn6Heb7_#l6y7^gq1$ zp3wXB|AzO;+oTefY?~Rb5ua3K5K-!g93t+!Cj3;dtRwM1gtZ*k_j=&or=kuFXuj3e zQx_6HBoLb5GW)dNxXjHFacUAF8`|0MOzItg=Ri*MQGV$rv7Gl7F86wG;lW;`W8PU$ z;*SWtC(ZN2?*+lVPcIYqNj>0e!iEVjQ+nf?t6&iYo>6&ba_i_SmakqR?uA}8K7DEE zefs}}H!aRk$wc~}^s&87s{cX1yA63Q=G1%Xed^+k6U&Xyrj)Eo@smNio97qrb>h53 z;#Mb~PVONo6zA{Yy;R)IO?U54LR9~iX*(*q@3c4j&|7sgGJ9#HYJZDl+PSt|<*#<# zN6+wbHG}|N)~USpKlQ`2zcz^Lm&<<@N$w*QaJBhB>N5&8`!4-Yefx}(neAfAUmN`4 zbuE)t2`M$WPjGCXSg4D%{p#BF=PL4yH`(ALyl}PoNL;^?#vWYypZew`G5+I66zUpg zug-=gt}&MDM7ZLrvZ1)HCHRrvdY_6`>g9`KTpPR@U{BILym1w|HSpe~SfO}TS(uXg zlYEY%kOzR*W)D%XQ|G8(Jfk6m;kuexC$ah3$OVw_wJ58l=DfJq-I(W_HsKpctakDk zcT=A1bZ-ejE|)O$Ws2*&M@HOvoIKXuS8y%?1ge*z8+!|D1wwA8kZ$M})5E8ABE3Mu z?@mBON5r`c6?$nn>AxQ`)63P^4}l)1?Z!`>Jx+Npa}(bFv7S88{l<9f#Jx(;zrh4z z9=OF+{=e$;>1UXwP+(k_E^CAdogQ))Z77XC>?1#^5KUdM@Zj0$=LgKX5`TN)ly`o zEQRTYRJp=ZiOdB6I+FVd2ilGH+4rYbp%K%D7B1`C|4${`9_J1g`wNe)YX0n$Vw69w zW{|@)u_Nwy0T+E7rzDFHMLa*t@P_W>tAN5**IiRGTb@vw!_R-l{^$o+avvy^Tjmj_R+qAH>w5cvHKPsx! zdfn0<@UwJ4N%1RH=|*E(5Ax|LqpqXIcLHM|YIvr%%E=TL_?w^cFb}ZM=4S$)9)6+; zZeCcfeA6xQdsCWo3ws5H99n;zW%Q63GsKV zxw-#7XiBI1>^XaE& z-u={efPTB%LX+(U5BsB{6R^t6Dv<6Dwd^Nc=;@U`s<-544C(DJBp2)-@9f=c!jPFB zW3KDOm{A1c$pNO4HYOJ~KzL)#Wc3pOrab@pl7lB-d!}ScUiapr6)TqCXl>5*7ns(6 zYc-$0`No%8?ZVWw{RbX>G%Zy+A5~x>7ea=613;GQ;2UDo$rV~floHg6TnU4fb=1bC zTUnKC_ucpG-gD2e5jTww89H&o(4iA1q8)zOyG%Cv;KPqT_~4@lU(0ANMyt@=-MhK1 zyJ!1n_IlbBow3rjW)(6AgGy2PYo%XUiJJFv)6wCFxg{(8rOyR!51Pm=<7&`$ZWh*s zqCFQw>8Tv>GKzsVqGk_9L?>Xy-lk_GaWGD6td&DHRH|>}PH@L=R9CGZR&KS^?fVz# z(BjHIJ9El*@8M>n+wQ%uEN5q*9_(p<{R@8Fy*oVWHk}K_;Hp}BjBy7 z9UN;HoCv?b>!1(eFAloqL-6?OPmSp)wmRxS_=O@r{Re+h(+U59$442}hw8AL^X)wN zg@d+y2Y-R~-**t^N(bkOtK;AoOrqc5FBIPV27bJKI?SnUI}Lsf-n-A>FCcCB3}?A$ z#S)0CW1k_Ps-SQLxgDROV^X&*hv8Ol_N&^>er>~F;PU*lV{aZ|W;ZuoRtZ=nCM|7gER%jF^M zy8seA^5emAJRhTJ)97z&Y;D;2?ToQa)81pec%J$guiwUeTjTd(zqbR2Pm^8ZI|}@e z?Gqw5BfZUGOYQP@2I*poi)&8&c&dDk#<$_!)&SeLwc8nS+vc?gK68nN^}!(>jn20P zkiRx`JD~Y%HoMcw=#x%@k=)kcMZ372;R&X&Bo@l^Nfzjq5kAMz1>?7^VRz8pZ3ni_ zn7AJNR!Q~uiG_|DwQYg!rybi4$bOry9`w$J7?*F^;M-Vj3%0iG({_OIWs-X6jx3*) zay3HR8mnk`wlg}>)btn!wq1NksJ4yEwg%W)WJxN^lh1YZ0u(AHh1e5?p6*~>2F1Ead~c7k>zuJxc_o}kc#^+dJd_W8@-`H zLOTPzS+|U;q#(j8E3(MpRg*$Q8vg2FHIA%0^F!Nbv)ngYE8yEF&7;DB@l{0=%L z9mi1@eH9*`Bnzr55~ZV#Oh-`Yr*qSB)OE(^;qlcEx(aqt2K#o1I)bCNoTQE;r31c` zFc-Tt4_zIrj=(HBTOEhes}IJ*Gqh`RrJaeFr}taC>+mV^fJZ>|MiSo zhSWxx8X4R2=GfRK?g)}!j}%BY8OgZ6PI?SI%^jYA{mx0;v*<5ee>Xploz1;@lzZdo zQDi=fe&Ob1aR1_leD)dIhf*_`p&niv&W%FU{!7h@$Kz~A$dk9tjAE&J0t#iipT6favQk~b{G>{gci~fwwvIdFLFJ& z6ZCg5a=afy0%LEzO?V!LT^xTX9>14+11#;`p4-#*0|-E_&(OMJxLs_wpce^Z2<9Ns ztcN@L(L&hUQvipn_Jl`ze*{!D5`1~km067@aQERypcmaA!YxM(veEJ%xN7b=ex3`? z)UNQLJXKpyXzT8>U!6C089&cY&M`|V!)B56zT+5n_C(JF8ZCp}ex>nBW*M=d0(YUK)iJekp&tm91mIrIh>i=_pjMVf z_VX;-GxCmG>hBr**oG~qvY6tnQ>Sj7y1F7Zsxnr!h-`e!Z`f0dOr|2!Sn_!;tz_)* zN>nOuO=+01aC<}D9aeLO;g%7Drq9?rrlu-=@Q{QEhKWcRGB~}eX3X9h(+7>X#gJjP z-ci@Eec_CTlvX+SO6BmeC30H6_UN-4*Uvw2a^}hVZ!*W%8c<5gS(zMC&A-l5TGfP^N0tKRjV*r5!Ck>fu{H{E^~rvW0Ev)vTC%ItQAsy;S=+PDVH^* zM$nN+u1HVQu?iq-E(3cQe5pp8EQ4#4S#6O~d>(?7VR%BJ6UPgJE?@11cI{r2qDv*CY2j~G=-Qe4!TchClY4}CD_!{=jn*!#cp z&i2J=wW_%KGHYs3cx_pIoT@f$ad@P9nq_!@Q*>yUPL&^$*Eh*VWv+<;rI zpEc|HTL#3%sZt}R7lCRQ*g+`nD54TKHM-Fg2lfLV(J7S;zu=T&0+1Gv2 zFE}V6JUg-^xO7Hi;do1G!Qd!UY@8{kF)3ldfP|#R7*kxVDQa**s%3m(%wqTxt$VQbZGJmq8U! zJz&LkC3P4$9P=jm)k2!O34W1Qo(gPR033?18Ak37`*N*TN zB64t43v+2;GGK3*E%rCkk%z<Y8Z&ciU2U&^ThZalWq(^%IchCu%NnH1 z=v@?J>E5IF^#juKWLdqUH0ZFbsdr6xOH5Jk4BeomVexqxN;WJ!yBcke3JKA$37J3L zx$y3L7vA|(W`ZmxG$abugm5oLXi;)J_s^+&52Ei5?w!j0Gae%g|C&D5zNJi=u9c;PsTHc3A+sWNv*TwiI)0Wr$9;D8rNy)2XC*6Vg`ka- zs_!Q4PP&-Tw2nQ zT~o1QOG)z$J+{X#+E^N_xpiWA_{3W^!KE7)#cuC$LvzWN6_GU&gNEl;=5oJn-o1Mx z3WcwOhDSgEDiqstLAw;8L@y>$M#x9P`ES#xJE;BC5pUX&AvL+?0=z6iIrJeakCIF79q#bOdz-kdoKwtyRW>Gp8*Z{K~S?-8HAjv>{DL`oD zA|eKf7$bU63(}9l%trJr$h0z$hv`PSLZcPrFq~{iW#SqaHa0HYrm-qD#md-hV>0~G z;bbRwDK^EJjek)xId1#BdG(tUo+)eI$9=!*yY=YUgDZw4C#4J@R*D&g|<&hIvZ4Oku6kO%7fVSls;NTRz^&?jt#1^?1v zWIrd1NlDYeFPg!hVc$1o?}&yW@6YExef_S(Yj+{FuW$#>j z_%1oMcg4E9<$GJQi$+(~PhUQF_G8wD2J2(9=PsXKUp2ZYyJfHZ?sY5dr(+b6jit%v z+q=iKEFV5$!tmuSG2L%BCzm!xf-=PKOBMYD4OwR_q)K4Lss^uFA)+byDk&qjqWG^e zi5tL3z9YSo(m{B_sxmMtgGys8vKnL-gN9x`sI0WHv9xRuUDLR5@L>32o8@i?x463y zD4P9<+iACPJLsoJH0)isw}B4po7iO6U7yHYDjNj1BzGczKXSF1!6$KXX;3rAal26S zXQ7$M$UTHcaUW&g+1PaW@DvyLwO}=Nr!272T1EAQIpX3uxByCUVJJ+8nV^?^SG0iu zla@*F1X8 z%W}VFq|`lB6LJ~#K#nwPk(YVc`jvn-AspaD4tDLaf451%Ia^~Jt{<}*?btlVa{>zB z3vQVJB8~xoFZdjfx8;lA`ppo_b%9TqceonAea<3W(*}T6u+V8u+kD|SfTvCYfExwE z3V)ph_76gZgnm4HWniJZiC=0C1u0W>#ue{QqJ9{5@ z7Jsq-(kaGeO>fTLuzvQNLx;XOd;Nyl_Fp>6w+du$ zOfnV>VeB%3aVx;p9bsEnA?ImL3XVaQ5(gBDT~T40UWZL%4IiCTDZ$PGJBr_{Ez;|> z*bV}No=#ejn6U+I-)u@+U@SOfw;d{gBos$5>C=cWxevI1d=+ty+2PQz_M?K*<-+M? zv=Xg?RucabCc)>N?4u*X41eKgREO$&KKbba?Gl7fQ=&1jG~ zm(N9%lti4%lxW|@jf3eiYmXjXyLya`dr+7gXtZq%T~s${{`^68MSuTg_UuG#YdGeF zA`f&;1n@%=)NGcJIRQZte&&1NM=LWC%wiYA4YN3=iNH%Xszl_e=yy=}{@mMil?NIa z7WVhIzXE8)GRzwq1%#k~twEV<&|e=D(Dk@%>X|w3aYtMMN9Sk1H^*KH=-TWRTUheZ zNtv1F?Qea}z3s$J_pj+Z$Pp6cdnD8dn81H4aqv(Zkh<9)0t4kBGMNZ>_yWt*#QKN8 zBj}aorpUTv;$88xVUly1W?VsY_Fx8V#5kK3dG?iiR2Ie{NIdo=Vr#Rqq znuFX9JlWSRzP?9R4k*(dEhq`?K#48Ot#1o#>p@?ca^RSh^t1$JxE>+ei%!EcyIbB& z8Mr+3Deg;@_}Y8-HBDweL}rKHb~B`ldZuN>YJ=1zGI_2P7d#Jpr8UAHB!I1f=$Bsd zU67A>7E9&67h1EF0~wrEz)F=*>F-8t`o98^g}>aS_GP~mJ}t@P>x0+r@Vg^oAO>fE zFiJXvQGjS#GZ?jcyx$CtEAB3?h$bhPV1HY1s@>*|zf`8sa%(2HJj8#1<|9-T#AttUC>2&!KNqzbx zMda&rs5UO9q4wzCD|=KKBe=}=@nYZaBJf~NuufTqEgdt3?Nq_OH-O6s^v53+$RJlp zw7tRP%-+}kJ z@$+a`RmYUY$DKPD=Q_`^U!($Eg|k^LIAu{EqsFroYa@MI)Mf8L`&-YT{WDKF6b;AO zZt_VqW@8Kd*bg|g30=}YCEUk}bt;bUka2=c5_CixuDi>uYhaGq77N8AVP9-w(G zE%ZiS34miy-0`y=8@Gb=pEHQ~#d!9GS#Be9?BZ^JQTk;|3tH-HRIai;0Vr;Dax&pt z7kQ1xXweHX5lbO71CwrvOx&h;Mh^heX|#loji6!hjf6Br-t{hpWq|RV7J}(ghIW2| zn6O||1c4{7g!K<>p%y_b2YVfO3Km*1YSl(-I5HWv9b*ysbv+V_z}2u-FvmiWrQN{%5p;QW5_8R4yW~@wPCTw?-4{AW`U@CCt zE5?0IUFoDR`ii1GGO zf=AQlq+!40euPu+D(n^-+xtZC#IRILv2Lj{&hfo4BMk43RW40o#^76Wt3>yOgd*Hj z0Qw4_^dmQXdQ$2nG&w^*etbzr>ZC~-spF?7!{5}567cRMd=^S+NSqM&`0ySdWx%bK z#VEAI!Ik30MdEq}Mc=$`YY)VfmvimZz-hC4U5 zV^B%?Hw;$AaYt4RmkXnIP+&5@O2METIwL#3m4ZRPBuG!;uTLrJ8b{>UFN$IHqOF

    WD@#T4*yLiDN-*s#APg~XSQML)$y2;b!68k|Bx9Wl0xeS;|C8(7GCS*HvuwIkO9 zme$h^={Pv7?Xr1w9zujPd&r!I-9QLvo03>f=WHyyvDgezz~a8yCJ5b|ph{k1XGTK) zBi0=_j@OHVeqTmGxnp2J>!ZM6gn4hN(xKKBLCHgsgXpr$fTBG_@q@xwE6dB3OjDo` zCgm4C?%54^AFr=MbQ9vjUi>tKBcc+EN@_WH@QZ9Mj%;#Sf<|?^Z(IZkhH^%qri3TI z$fiPY^HW#j5S@o8sQrib%?eM35&aS+l}PfjtYm%J(H~9+wxE;ur9ex~NP-X&X7d&z zX5840PV(S??tY)Lj?QR5cD&k+2~mUV)IeXhFAtd?+6p4u!dzI-&ECXOl|pJ@JJM33 zx`oU!5u^A$8sef8EWSeIijT+nBS-rRdi`k+lrm5EF72-qmY{U~OMBx5Y+sUbHyr3rhUte-3 zKa<*_wI!*J$9g1|^svOM0N_o5*A(nYNv#Iw`xRQ-()qj-g$@%B$=2PIU?0{bAn@T6 zTNOShgTs6Jk$6Y;ZEln@IK20x?Q^^oM(j7?I`%?hd3yJpq<~399?};=@LYxigpeZO z#X9pNP{saaiv-mE8JTR4&@aUHn!&x(+{@EQYhSq8_I`tUL%!jJhJ}lu5v)`fN^OBM zSQnr=r~6z%4S*@&74FVj10L{4IAczsU<<@S4&o@N7Mw{fq1I6Asjbv5>K^I=zy;~! z%fAc(Imjp@M0E)KLQ{-Em2OfQEWqL>g9W&pY^vl6l_pvdV}R%tJ_R-n7MC!xixXaC zg@cH6vgca|n}in6pkz^uMr#2UGC>1;Xd@0=kWz-f!>2~e?pjzkbo!iu4f8px$RAY# z)3k;QQ^r!8Y^+V5wYj)9D@&hRo2t*ssx96;JE_)~TwCN3r)KA+YGd^&@fw4Dx6WYD zq2T!q1LsU1TDR~|22Fg5K31Dbr=+Fmrs`862P{ILniXpsXwb!FqKH&|S_&KAICD|I zfpg~Az9l^O72!W*73SUDe|jF3<#yv{k1XnwR$YD%6kV{$-c0X8EO#6>tJ8X0N22YS zx!lV~*52dF-1Od9y*^fB(Ah%J1CdeOHh9dyev4){#_0?iIE0q|8HH?AXM_a(7#*CR z9J@xJ^G;mSJvn;2BJ_B0w8Rd?ydUa_zvU3SUXWq@UwCmPUgzOgz1o@BBnTwPua9u} z#<6knh))y7JD;mb42YLv+z81=l`AgX%P!m*U9{o&wEzobbMzrP8I}UTg2VAFlGrFW zFcNL-Pvp^c#>-9&g)AXWcz9Y=h%C&MQWhmB;0`Q)dBp{Na$!MaC>xd<9TO3m7Oh0b z1Vt?T_2qB7Aw~4*I+5Su3Uz1lJG=tf!2}OCh;W=l$cK|b3|$Sq`zC=`!%Hd`pVYz8 zfy#B0?-c}%{jj^|YReUvKXAEiuM;^!FLd#8zY*p{V3OFxSg`^ynM~FqoYgokVp}xq z+Y%H^_O3I#cAeplc{n+KsD3mGU%QJb19!$HZB&3)$juO>D!=Z6^}9Il1^tdA^|&K{ zyPmC3Pb76`q;k)fUgy54Z?3Ozw*5t*ypW0Fk)GG4Cg-B@9qQ3TK7kbdvmml+6bt?a z?l(j{RL8oJ6QFj%Zi{-t+L1kpP>~+mW$#^FKg#84+t@j8ou{$kQhAUCa$psp!*E0+ z1v*{qfJ3-Q3=p7m{58U&nG6aYoXD_1>N>3|#H;?44ndUzicvC<)DERXu=H;&QsWe1 z9MOq{Lggd`mWvLI7%+pnV=oL6-ywlG3agGJWP}76{vx;#YBKOWd2<)?LU2tG|1U-s zGYF?P+4~I|w5YL>`vWh*(Kiu%+D;Pe+VAf>EO!00in7O%g8mlCA1|wzwmx=P--7^ z7BUT<5%SrSD2V(0iE|+{26Jb*Z}Uf2zW#Mu%IuO0C@L|-Fzcsz*~aR`@~YN`WZi() zs`A8YWA?nCW*IUPx$iHO%uY%B`lEECeq`D8!&23?OCr}67v)8S9Nc>D+?Io(5qY!M zMlPvUrw+TmY$Q-jn$IreU1B{wnskho7=v1g2V#|2r_%k#HVjFcXN%OfW;gTWZDX3( zY?wTL%fc<=CvRBOJm$7M!MOaBU=DH*dl-T$LO| z2JCaI3iiZ^0gLL|7}8Qp)^!`!5Ycl96b*il$3mm5=RdwAI63{51fx)v#G zYu6Pr`Gs+|KWb|e;tKN_F?6wi3->4VQ+CEwHkiv0=l(Q7I$Yn&)uWSC*r2b011XL=3 zj4vowv68$6;_I=xG!rgpfvipBQV+=|yNWfD-YO^+{uD~e6+)>bu9GCil18XEPldWT z1LkL_K9X*MQ30Y7hEs(gtRct6SE(iqbAI)h$|aMpUtD?L{Dr%3lO+{#|KaZ8&X*aO zo%b!Zk5!=lGVYn62vn%yPDW{_{27-=-aj>7$-SXLxe-C!^D@*&?yanHm8_kzN!fIE zMo`Q&O_Mrd;W55&^4P*8CO@VHFPFaN{K}Q4WyBX`rFGM-n_%u+ z%JqqVuZ*&`zoJ$#Y!hzlv1>LOir>c9z#+Cf>Pdi5F! zX~!ovir+X!5vmB;CS%u3HuVmfI58N)e%Jc%(>*ZI=mUxV#E(R7iNmXC1E4h7c+g zFq`3mT;MV}a$zZd7)qO|P7sEF9?g~$G3Klb6V zg_-fnH2MooUQI#tI?QmVoL_l{%TCJxhARYy>m6NLUC6A+$o9fLxtXTyxa@W2a^vs@ zcb==AkWp@4mmT+nS61y&WXvv9B{6l1TDc!ASQwY2D$F((m76oCO%fP!?A)9==!D36 z;y15M=qk%Hp+e;zsP}z_I!?XiOO_EamyF=GYru9_Qn2BLP@GkZO9Dx=4!$;>yrmSp zC72Cx0w% zwqKSmJY3#gADNS+)rZCPtjSCtzl@2Fi3Zn_wzWgzec33%*U&2+G zp&Y#kaFx^LZ7YBr?N=PB_`p06qBR1G;dFiABq7JGu&BKT1oZP)vZDa~c}QtaZY56i z&!?-qJrG;_pZ6>hd8dMo}S7KEUy^NQnAnfQ4QQ{UaYIy(wf0$Xk+`)Yo=L3gk@ichr+H z2&Y&q_`lGUg8A>M%^8UcQY{BLJ1JY64T&6F#kJU;f?K&cBdc$b<)E~mNd&Bfn_!iA zI@nDIsiPo694Y}v$FKtEQr8lPc?C8Wj;Dc%RRw`u(z%3k=~W_+A)QLdhtmibY;Z8d zrPh^NnnpeCMX>!}l?kJE?OmcsRIDE^v@Zz~ zteqf71Cz)JH)pz-?5(9018&$fGB;=BrW*!Spbv??1#&0UDR%_^xt`ihJw!bLQs)SD zEWlh8xZXDi^4}HdsR|<$vXcHfPCpZiNh73z1%{6p@z6aKh$O zC$}Q4z((j-l9;xfq*eLPQ&&Wraq7vF$CsD?au5c+8C@iNL|1^QJOfEuIL;*4Gdk!W zR!B8L4>8DM0C_+bM4;SeO}f&_u?U7iJw456q_fzp+53jB9zh?Iho5v(05!2g2} z8nRo2Zb-5yeLFA--Env999m*h38`s;8_&g{P}t{lB)v{@0U>%R); zU^xpVf8(jb&E9H%Po>jDdvrL8&I%R#8*xqc7r80U?nY%Fpih56BPETJP>-niWMvjK zR{}o|H&;^X)S`G|*KK$vq6(MwWHXEfx*_FGj!mkHc*dm_iS0uk zabs27w)6)&a#HEw#>ImMsrW^93SD}Ry^DHP9tHgmLaG^xVJYRA(|Ia0V|aDZo$@Gd z9rP8oeISdt)J=Al^y7K3I-I56l+!_|iIO$3LCQ0>kI(1BRpsXk@~HYJBZkyJsTwkR z#0wCytcISiK~&JCW5p_K@kqoU3?DMO{z)x=#-(HY8C11!h6*l^^LjblJ9Y@Zt=mP_ zstITUJwY}>J{QfU=gQ{FgV0z6-4l)Q%Z+>eb#CeFuglK9{`%`cLu6mTe$QQy{R*(G ztX9zgF`_7@hN3UBh+$ae3FR>W=I7IS^@B$!l(N_G@5oemb{Kv(OPvLb+39U(g$78b{ z0zB8rzJ*BdqH4WH8Of-_6o_Jiv|-0t_3?zDi^)n9NhvhLVim)Jla*)ApE<88fge2L za@Z({(w3;;7t?`^H<^q#8C)LM@xnGB9`-xN`;0O)C7vFOVEGq97_cf#V*OYlKy%Ux zWX55@bh`~20fnVy+&FbuT18%oHZ@Y0aU(r-NNSm^L?01akR!i-u`(e!Jj~op-gJW! za2*D?-av4DYqbih{b`C}=o$(I7T1|_N{%#C6iTDgkOlQbL#d%?548t9K|O&Y0P753 zodK*f1nX)8V}JF;onK+BqacF!zq8+8%9s5P68eVf5SEhB7ZofGtAS@u@Tff@VpKse zssKmQ6{D~X7=`^(W(Ur2KfhXy*&vL?jF7})R>)z4Dc}XQ!K5(QA2{;vhKC;7Ap4#B z_35YG#9x7wjTFs380W#8e+3!)v(@%51V*Y(qCcjhycnpUN4TO~x1`_djb#eIQ!HpA@ zi$m_)vUQJ4UQ}W&zG3+?*K3-qBNP;SJoI9OVptFwMnwFML0qUQOB&cw|2$>0ITY1K|xef1k=kS1s?~+AuQ)C~3yy){R^(J(sZK7Bh z7?ybFUFDs-5CD7=f#ohVuxzs5b^5gIqc=ddeg(YuG?^oikyH%`U=%^{gwyx|Gmpz~{hOd`=~$hBI(`T72e>yLQ2UI2mo- z)x_Tu&c7sg-V=I#<8$#fF6TGlD}*szk~_u*V~Bw>Rq%_SPENv)XWi}@$=?;9r*NE4 z224K4Rs5xhT7Buf;=lC0R64*AjoUWH;8-qLuh1dal*Xi6&Dea^n4zN+iQ$?x^8fa( zsw$tdu+Md|cYn*--#xJcI-sNK!#!S~b~|E^zPh|D>9898{#KdgaKFJdw^&NkuSY@a z$BbKdW6xCDS~{!nhDvKajQ7%|^YF|TdW2FQ4INqdZTcp%-3TzzFt!JS#xN?d=Ak|i zQhr%|nq)}&0wYeh;WKcY>6{ufG<-~+Bkq~Ly@K4+RNqA)chR#Tytcgs)9iY-T`sYs5&SkOPE zh)u{|u{0&^?s{#(;9bV#t z+;i*BuH0@)N{b27K9}61swy(7I5s3UrM4<9E>v5hrY~N%t01#qe$N8c;gXWWs*L`* z4cU2HhDRI@(OF`WvMjZlm|g|BvGIla5KQ|ST$ubA{RL#TRRiteY2sM;v?@$z=uU#s z$FJ$~jH-t?pt{JF_R!_)a82&glI`-0?cIjYEuLHuEstk0o%3=kR_%V`4Q}(eUX_O{ z6Uvc%wR8uORkv90udba+|sZ3BiO`sn%_ zADS@Z?uOFUwUf}OWy9+YaUlt%$#Lb`WzoTaW}c@p4=CkY$a>(nG2USt-eoAA1KL7i zo1X*!kG$^yjH=lBpSg8Q%BB&@LV%D&dJG_h8W9i$>0&@BLO?`C5RsyQp$I(jiAJyi zM!*ILh?KxXsUjd&Kt*H6_FnX%#zuDU{(oogy}Ngp1by%QzwckZz`5t%DQC`{nK^T& zZaU4;oBC%5-zo0fU|FctVlJ&#URR7o>9$4;RPxe!XTN_?2ZCAM3d*__6m%;qD8I;G zzeCez{(2o2mKETyte{)BP>9Vlmg)bL8~Sq6TSw#AKbz~{1}yzCVzvQ zbiogWVq@h&K0UoF8(>sg{&R#s_&eX<)F<)|_~c4^kWQE`YS~Z9=N4T(J(rDD`kMKd z<_LG97j|c>j5xKcy4jbVx{}=0+3YW&4rX}eI<*hnS6S|b#!1s1;mLiq)7_%8-lmg& zvD8gX4b$mm(}8=uvL#H1+yx!m{X9CY`2nSFHFR3@W%7<{=veM19c7EfPfmJEshd)l z^3A_ybts-Yw-ms@@1h8@NX%_n{CLGhbHmz` zM+KggM`_EA)hqZI6ahPB48;k?Q`ie~WkI7PSe;x-@+JAYdzX92+~4d=@%ng@FRw5yf8{&fr+hc8@z#tq&PSxQ;n)U-3Tf(%OWNW3(Nks8 z=VgNiZa2QYF*`fhpiDhgHD8&1F8$rnqgUo${Jb)|YCiFUo=VD4Mx%b`VZ7mePIa+8 znksRZ%gcJj`2wAhY#vfSQ%(b@0JkvXFxp^0VSO{O-^uDjv#1dJ|sguvZW6GVO0oo*AwuJGDPnXJInGUCRipt-Dx1e^KL_4io zVBQQs&Y<~)+#hWeZKI1h#%zZ=>%&rP_O%Bl+&|^miC;&*+@)gRz~!&W-v^S7um0YG z_y}!)&P-~l#|G}?3z4HoXF!|uDI+_AGp^ham4y>c(2!}bJ|LFeygc;lqhK`9{j zP;(;=Wr?21I2o}O;XkKZf7p(uER;FQZ6;l#E8;yXWV;{y zd5>Pda^Jhi(*rQbM@ru#%`+m8Q$k;;S?XDz#>3yr6g3gwUkd*f#x%*R-090^KZ!cB zDui2S(f8y0urwXI%Nl#6WTrGqY4qwnTkmONZ2f@uE0P}xDDbARp<2*$6xM|^n@q(x z2iG#UzeLS!Px`HWN+W!0yxp;T-pXv(JFkyXUY>gKjk&Gsf6M!Q+_Y$1EhV|?t?fe+ zb9+}7v`p3WK+BywelzFFdKg}F2Z zbCZX{QS)*!9Y~^W!)Klfu0B;(Qc|K~DoTveX4>gWLzK--M{EW2KNK6|d`h<|h6@za zn2LyqhI)WHuRJZ6VAPz(IuyjGrT0|*u9PJ1kMCK_S6Oj#hc78NsWeF*k)K~d>=$_T z(nObBiqngwuGSTm6=MFtSF7PAzU+n^st@N}8Zw;MYm>&~cX4gkE?m>ytlzMM#y@x( zzlWzy_)h9-oZCfSL3e%A&G^T`=jM_eFy0CCQ-@tzkW{-K_(|}((v>vs_w|gg>pLWv zO3O_vO_N8YTTI34r73a5R6=@boj5XqVi{|k1F2z{R2_3$`x#e$H=#QA>X*!Y?jTQ# z;jd9dUL>v*S0eX&dZyK~cuUMpEKL*wgV;%4@hNg?(o$DxO02wOlOZ3&7`{=vu)J(u zknAw97LnIViyLE>@sIkV-q3j|c?RaRJ*;g(yy}uXak}R6%ZlXnl^@Cr9Lg&{l$4C= zzk)bba>+8+?cHW>}kYoC>IiOG%R&$uoi<8($xI@x=qi*L^sqBIvp&l?cD^*X9Ou&AenpkJ*G}%Zl`lIA58Ov{D@j zMUn};i|U5<3i&B-$y1<@SyS%D#a?ZA8|5vd!dPRhImp+Y|nBPL7DQb!Iaj49SzIRqNOOD*s7Km)e)0cs$5!kWQ#&H>}V?jc4qn`EraXvp! z^J_gDqF~Fn7GPi&0E*)yEDc+GIrlYK?tUPNat(FYxgxg_&IGmM_#vx?Slp)Bl%z&! z3_k#a`32fktVznCD{ou4@C=XpYX1DGeFjOj1NqmkEL$~v_^Ps%a)P(v#m~O-+?X-X zz4GkE4ZXpICCc-YM|bEjnjTbF%y}l_GYvCMUC{$&_N?zu0+Z=}Z%?H$l`L3?q0k5s#=wp2TsXJcTPW6}tBMl;QyaByt$ z+dm>#5^F-TUrzJ8dh&+nvnw=l?d5WEgXP`_BvTU;uT%$O7)^3=ntCB7V_6LR=oG7D zwrAyO=$1H^UEq;4rh1k5xP*AD$oK-~$B)Bk+9AoR?k#n4I8UNVoz;9MRNp0Jr-FT-A(s2o1sN$1{{sp?{R;gppr>hiO zbej~oiRU;)P%i)T97~g9I2P?d+pc~uPF}SyNKDR1f=!g_k`nNvTs<3*hC`=~HCQq+ z;;}MRT0gONsmIX-@{XesG@?0##@P0Owd(pf`2r(@CXgFzIA*A}GA>*B+ny~i@bM$> zmF{>W&~QYD!?)ZvQu>$@J@Gnzq}A=` z3TA`?odcakaeCEKtOu1!n?0sJ!(R-_Dl1PcKkJ?o#abi8&x-%4eSQyDG8E4PN_{*=cL&cx_N10e6d`s)a!#CiIqw^?S_FeH7jBL z(8hBbYe*}Nw|I*|ZCkYH5@s(;yv6LJyDwp7a>K1C3owS3c)Hm#;4PTfa z)CfE22t#2WTtWtQNCx#Ff;6AxPf+4)7D&X9K~iFIyjWQ|#hv6=nWm)rD$BQyVthnCY^OtL1F-ltPpMvP z*(CXxY%b8f$)03YQ?a?EqT=G*Ms0EOFh|DOL^Z`cQ{N~}T3@f-RZ9-aV}p;bTHLm~ zCUO4AqkPng@^YR(w1gY~{Cn9~D+}_&?OpIvi}fgoORKHKrTSfxTjA*#Sb-ZU%uQT^ zi@D=VJ;kYZy*BwtNRCf-xm^}N=-b75R18b0(%)oP{CQlJ6pq+Z9b1+S-^7+tni7{{ zvX$y&s{%5zxw6{ApW`W6Kc68lKaU&ZC@e`+r%0cH7ZVkbu-QO4iDeI62JB4>o2<|G8?wWV^ zE6a^ZeC+(W&%E;^%2lSmPVkt5dmOV^J6K3LiqD@~*Iz%AbW*nH7CG8D5O0d4`|Ct#`^%Rl#5IFexqASFj@2=qMe8|5>cn(6Oz0c@ov8^qZRnj zLyA<6iy1SoT&lWV#ZrQ4pony+X*g3#e+ifn5udQqz4I7*nx04`zH_ z8Coq^`<8^OwQaTsL zd4wN_xWn9#$!>`~!cTCc(Zv>v&5q#Fv>7z&uaivqq$g&?CnYC)-KlYeLiOX1Wmee4)%x^ zuPAZq-zfnEw#AwnaMi4U0C>jSx4->ojL%@#|GE&8(B99ho)S z=>}n0xA`?qY?Z`9(?;^Efgh!-LAJ!^m+GsUit>=q8(y|e_oxaw!b69s&3U@>!mX01i>Ws!4@P-Ng9_}5_&BuN#;okdQaU~;j6&I<*OLR8*v?gD?knhZ|A+H8oA0n z#svPY+P!KH>|oRMw&Y}{>tVgNyD{UcQ0FKT_99^o2`g?&InR-_i;~uLT=IivqoM1J zNm^}(q{E2^Z|2_`6CCNoa5EV&WqB~1Zx52E4l|r@k$g@JUb#QBcuL}>x_8b2{*q~@+}Jrdh#CEEj=mSBTpIF zvrFfqk-?Qz4}y*5DN@nGWp_Pr?OmJ)w?i|FzBJ5dBi6Y9zpxHI>try0D)>xRd}2P! z!D&JRaGK&NO)E}{Zzx!;iB}p{UWnUZ`%@QY7Ztc#ekVEQN@A^>$oy$wH$_RZW+6zh z)ThR0fZJ40X{}<6N_;iSH3bVEQOrimwJb0L;RX>$5fm3H}VFc1EqbelORP z>S5aJIMqT^ZgF*BhNMfVg!M}6+Y>ipz>7V7v^5fK0~^W2SxwZzGy-1EbB&W?*vlsw z8*Z9iNW;B6>RP2n(yvkI#OwRasBwx3{l}|!YPV3>dr2}opH5X=R*9I@VBEFB-x4e3r|FLxUn_D zB29alEK(W8g*l9`L3Zc!=a5}B+&N_DgW^t#*X9P`Yo zj-fWy0%63MbW4=YHeu5~C7V(3>D4pPm1n5b;SyOGC_CLSPl{zxufeBnlcY7W%|xOp zD4KQI+20nt=Cn@nzm=7!9xn^JL#&?3hmGCF z?jV2bEB?rm5@lZ1oRS*)+U_s9{@q4@(7e9S?@X*#7-k(a0 zJL4PVJ$?9TECu~oA~&8qszZlS=1P#6?~|xAbf+kTKEz}CCLWACqeS88?}UYocFr-nLvJT6Y%xE%6V*UPL#NSJ zxSK;KXLfPYo|9^K;}!mf*||mfHep?R;>luH{F-fDTQi<2`n7OFcl2pQ*6e9O7mYGZ z*lg$2j|o1#*qmc_n5Jb-Cc{qZ!mLqY6iJ()O^-S)tDjfC!YII8H^zj%$her)hwgxZ zy;H*|KoS%BCu4eetACf|lX8Ev%MH8`nco`-x-=$_k0<-V>e{XT*6at}E)S+$t=W7* zJgQr_gs=HQZ6Nw^vU|EizA`v( zZE>#4+^@RH^63n#*5usFVEABG61%7UpPI=UpO^8e^z2tw<0>u%d#=9_hntwQ}<`o&Ge_o zbANKr9CJlHo{xZ8gq7wDd!;#ES)Lj1Szb52PH~gcI1K4vfZ%_wbFDVTT*(!>3MQaa zU-J0y((+1LbQTJtETSqMEk7{FsVwcqj+(0qMVE>O4CZTxp8)0QNBpMR3zI31ndfiT=d zL5}B@cg9WRe(=I~)Ohe7<+G{`91h7)K09}6y)l&R1jOy2(3uSpm&V=Zs#2zM_s-y% zik(uu@5+pi@08~UW-FrubLHYd{-cOV{lF$;s8XohiFu@kXe;f+$!yv^Z{8P;7oXG! zzf00i9B}1w>18iW+kd3&uDg~$UuGERuHQIt;Oar!w;3Nz>^^?%*{`LigV#Ut#LMfX zI|I#)&y8>EH+Zo{vzHXQkPmffwy{jP9H*mjhKkprGgPTKbRyi>Sne(PbHz{-D{&a?`5PRgs9(Q~1 zyKrwQw>5fK=Z@{|7g74>`-`(%t#~D!-J(77Ha(nKLi)TCrd(d+#KVq7%|mC!QlB^dWnG*lYbmd?{q^?3e^Yh-CVlLqH|gVylsY4% z3A%BbN4OJRxXTS~cfGxECwgIbla4rZW%Ait`CRZBMNjyfe72VUV){Gj3V)N&7=NPg z{!IE3d~Orzwo+%<`P1@*`*zbErDVwk2k0sM4yU_GN2FuYX|2ow2jZNpmM7dzI&_xI za@Q5%Zql*b@f$u&->9X6{vJWUwY)$cWYSSj3U_P^g?w5|ciHaRI^q7Z)16Jjxsk0Z zorODOy7LzH**5t%tpM(?*zWe(Ir*#zf7o`X@W|I1I>(E1DVGTMmhw%O98QX}k=b-M zlIjhA);!B+oD^pyv+0av#NDJrXWs-Js&7A|_932=9@>XV5B~f)WlkhM>LcjF#iUFA ze?#pq@0!41Q%Ac&BV?G~)K%ZS3eKPJ9*Zmvyb{*wOs);5Y3vJ(=z5t;qhZ=g1_rEH5{IUiKL7rDN4|x;I9@L3X3I z0K7tbV|a!wIoSG94YTyaJ(;PhtE5$m96wgDm9!>?t*)a!DVxy3KPeFmxYVv=u8(41 z%DBg^^mGmBHMP^j0zx(EMG1!zUYzfnTz#@a8pAtyM?X_Gp?>YTNtC+MEhhDzqkL*v z>x-@t{RPTLKP}oH<|I)5UDaOl0;|5fDcnz)?$FAXyE0d}zw2~o%R)!BcZB;%vmQy` ztG&W>ZbN%D>9k}=)N-rd&DF@=q+_|WWx;2o=;YdZ3+=$kPcAzWZU;_&EO)AR`f0s6 z=)-P}&6jX*>EvIG8RiQ2R!(EyCva%UxhSGDHS9=Mal=cK(74%N>MbMb=VV|NWH_wQ} zpM7fUZHdl?NBrBF`8EAPe^a&eyGq%CO@h98_B;~5t%x6c_B`Tm(zpCs3GNJNF6`Yx*l%jQ z?yLMhIX@q#Xpjvb*iDYGnDwLx;9*S0}CWB|O1EeKhlZB3Vx^gsPqfqg(V3Qn6Hs88h4n zl8Lb|x(M9BgxR~S-m8p_y#Cl07ncnkTGry?iKkEh4N)NTkAf%lt*%VE!6gMVX7ukP z?UeC+)mz3USLV+zxLf{mA~u{EEa@XYNXg}cgC{-xe>vf9`SS}DE)(>|gPzx<=cb*S z?cBVd_S3m-@{T}rb=hw(DN>-RE7SOAz*BX^ID105MM)F9JQaLYEpRQPQ<{(zHh+mL zB=HMG*nXbVo=&4n8{*Eq`=bAy+5?K>uJe91@h0nC`=(;gmRHlte*0~<`SL4`H9*hR z+qKM>UAr&U;o5z1r-$Y49SHZF+I_Vo_yCiSPor?C*)|_7@vE%ezzdcG#2qRoJNA7b zbZS)G2O~I3u`l7E-!sm^LVFHRA?pEl1DKvRdBQD4{pt(8Qe#MqfAfD$1I1ZR3fX-~4Fh48M_YJO0YIG`?Zg zhaat(RWGnAz5DnFR}{6W6TCxur1qsZKKS7HHdMxnEeCcL8;JAO81u&Ds1flTokJZq zgdUSaaZa|n9OL9|II~=~@*kUP$)5%>+z2uF->yBdC@yvB$d&x@S!-%}ovtatGt~;_ zfaGr+JY)Q1iA5RM(3F%@J~#6+TP`&SYn4%8hxnCm%A8;}Bf5w#t+AM( zcc{&Ni*iDh=XAA^jAmM&w@=6E!uIJTtsJKwp{9x79D$LaA}$$AS0>dSJjRuS<5pWS?u z#lNLtEGK?K)b|HU#<$@;-yeb+|JQo^$H|4HW-@MBwRzmQ??x5Qg{HA`6VWq#?>GC9 z8(UAF6!}S}ePNOO;CJLGLwb&xp$0sI>p7|HPi9BC_^PfMLzjE*7#|QBTKYyHIw}fBqIc=^lW-OQZW?8sR@zFI5ta z&jM2eQ;pA*IME+w{qms)mk%Jj)r42{svof7^*;GNo>5gPdd6~h6Y3ceo*fRJbj<^O zA3hqgIy@7o>b%n#A~nl*S2c9YuhFOD898auY==uxA7@O8s)e<}W8l{#$5 zpeNTFv%db!n6>7~!Gi}6TCha^R9{u4b zUW@yG`041Y&OFqC20)+v@9>XpkJ#FgDV7bjzx?aD*e)-Y9}kTCJ}^#xT%Y`JW@h`u zz_=fX!Vfa++eq2`2l+~I(=V{&=JgymZfW~B@-<(=8HV-2snUJV2B!w6u9xl$PW|^Y zXp|8pkPA+ImMDRobf0aPB@7GOYYywoT_<9{S-PI=#0;!TkX49Xca1DPZklK)M@w_^ z>7+th8ngNRnU*q4A2P<8+@t!jEPm8z(ZZqpvy6QHj^#i-SJ2J*=f>}W>n!yy{bm?nV8g*W(Nod5 z%FcHSaR;8&FX`w-FToFoT~LvSy8*LLO?`htY5tUqmJJH~UhkAdbbl0VX?13zU%j^D zzU#)f3f}0dy}C_&jY|96?r64dxh22#dW9?DKRX zJ7AMx>gX4Y=W%^;_IKXO8R+o8m}qvQqvO+y3!hy!rFXZkvmZP;skcu}|90=#E75UAWGmy`x6rmS4ZXlcc*uiK6tFew zk;e08#=GgYr4%F0@BQ-Ktu&4p8=uPmW+Wzi|M|ui`W`3mH69JdNpW&*X>`S&7Y@^i zVNul>t!yG3P{D9tMarRj75+>QPk-?F+Yzm@F*q*doJDpA2|w9D`w)#ZpFo z-&K3xCQc-5&zI&@?Ad(89=RA-uM#5{!P>9V&FOFPycen5ggms%QEoDRi&*f*MXLro zBJs?I#3daDGF$g0xP4q)-(fK-ujb8-Q^C{J(z6TtufA{T$%CcFi8~s*z?p6R3?BVY z-o!Za;hi^FAF7&hcYk62H-{Kp2`~xeD7&e%*NV z`Qu>k^^ymV2X8JjM|`{tBRnqp*7UbX;lD zN7^3j1N&%g@KLQh%C$A*B{WE*yjr-as~!Cmu&toY!808KXosKIHPv{yDK_DA?tA66 zMT@=O#l}oaT|-8r<69bIxqGp38GmW9@hg8in^c|E9D}LHjBgI_)9%056=-U;LV26< z`(nOlJm0g}_+3WZq=smY8K@u0viWOI{bWv5{nycHwl_6|tswj#KWD7uMbA~)Jqi_M zqtBk_HyA6|2Q0lVwCr;qZ!jK*-H3VKmwtnw?w0buF*l@ZpA3hq_OhTR3aO<^t0N{hQh}z1NhFjLZ4kJd1m3^Jna? z=C;OTmKbjvt@$oqc=@?~qVh!e!MwkvM^k8VSd9`4s(T%*Jo}<$)AZzNfA;qNvYvxK+i?-;#|r+X^rqWYnJ?sCit)de>W z73t9A9GiEf4Uu|_nW38|3YAn8Cxxn>quC*$5NURZUVin=`22HI_dFcvYt1=bfIfDS z)I{IttqeV%e&CxgzA*bF=(mw&e}C+kdZQ9M|I9Kl&4j-b2bu?L{Oh}cz6rySL;BSq zWRcwIso!GMXDq?^_1$v=6NXvt!jm4gM=Gzg@$@FG2iyx&5f>lGo7gMbHnv(#XY2LH z*c7b`E0)@@S8$8@7Qi|Mm*&C$G{UczzF2)_vM8DIrqC7=jEbnXW{3%D0h zjId_`tBHmUN;g&l#uuqGnGZLS9#vPcsajLu1a=g^4{%g#gKvc$m98TQtx&tceHz@q zMwkF_Up7@aVPf@uxTUg1$`_$?xHo$%(bT_XJ=8l{7q|t0ucN#W&%mz|4+;xaAYbd1 zui2f5yIUF0rT|Y-D%ce1ZPuFJ)nv9?%4hqf{LqKW8uML$jqN6P5QPC>*8$#hFQ+~9W#aFFQWcjra|#wd(WMf^>G)l@$C&V>6C#2=0L`}O^7i3MXI`}>95 zN%k>-{JE$ss2rSta_9tDgR(GyHI$FXE(a=$DA>m9;G6C+-|7S^3*|k~^*~;bdv&0H z2zQhPm4g#d2Ct$lmH~eZs1)+I%7NaUAjWa@-FH^4OrAs zl)1=1)e)+%;PsC%)n}?JHDc6tH97R9J_PuFHUn}#gM6NVtYzRI@%=OK8GLVn9994y zrMjtN6|*$|Dk9nsH;?8slA9WCSFY6GD95t-UB=rbbB$0%8}}HEY{|+*KIe^ z-XP~#?7E*#b+tzR(FUm>oj-j0ALk827ze6uR2ARJd znk&k54s+?BKu4S;eTBC1E6QaJ+XeZ1h#$18t!e;z400wJ>iyUasIzzI52Nj*Kz{9! zPAc0)as$2%GAp7wC2cW&H08r;+j7!AV$Xxl7Og((ryfH1pP=L3N1e9wIfRv}Ly+eu z*aYNz3UtB>e2);{Y0yQ;FV!FUEMOx`l}50m-qGx+r-&VOcSad+hFY`3whOZ!hrYGburcycihLAOU610~YF{qu zA5g#TdTa9>P6v7ka_?=shjC0hMjoF*8V4aK75ED~eH){kUPXP6)brSSYSnkUUaJaQ zskC61Q=f)*eirv(9fh8ng1R$KX!UGVXEg;zvScWFWSp&xBND1PqNVi zYzl!oGZaJ`anNaQw0jT2Z>9D~?E(Gg0QnRffV%HN8OD(;Y&~Y{6Rp71Tga~m`AtCl zUyz;`cEl#sBkD7$58SPcV{`33RDCd_yS2ZvyOhCfp>io(sI_Ga)dA>VNl!f>;!aWB z2zv;96hO3d(nA2Wn*?b)ds_OP-7Ys{edMp$RZ>T`Uws;N5`C}@YID%a6medpJ^*cF zih6=Qq+ZS@%LCBg6JX+%bd!7q`0UCS0B%=K;++7pz&)&|3FH?bJFC4}eK}Kp0DniJ zD1VJ@2-GW~qbNU}*);iLHjR%DeJdriX=uZ}rID;R zRwNrzIH`(dLtdq@?Mh(}YyxZr9FnFXEWytvz)rxmfCNax0kHqx#W(B>J{5R<_a;_H->1-nYn!taQ)z_W}6rvUEYEX#wO%@3R2Y0hHb;;EMng z0hxfl06V?0@JIS~ngTm`CcdkdBK!=-&V7gX3Bbwt-iSCq0Asc%02;yO;00?8BA<5t zL5KJcd<}dUnE0SPVP%|ffMjI@(GW|!z(|YuAe!_Z!fu=Z(U}|#!DiO?bkxD4%DrsA z_9gUJEA&gKTLePSwn3d{e21+A2%~PSCLIEIsz2|ke_=kdOV!^(Uu(aGev*5HzSHgw z{ir<}`b>K~^dZ{1D)bM=0%V`qx`^~5=}c-*)Mrt@Kz{Z(fbk_{g7hM} zBYqd*kG>M|HF8&bq3uB@2|WWHqddu$lbc$P?L#|nC~Qg6S;N^)6o$S@7b!d0UeW_( zXDc(-cCUgoXnZ7Z2o)gAi-5ga1-ngE*>rsdVaz?8{)#ZhA`?Tgb9GRPg$nu52@dw zF(8#a;%fzL9MN;FW*4cAAR~kofOrT$g!r)QM7Z3^W}|W^nqRP)qTDY*yt~+D*Iz+v zAL2a6I_rsMI^gkE*IIT0{n}zN4*4g_YA4FNE%Le;<%<04?N~4Bw^Y<`0_7BNebyJh zNwu5wxhNB0TXqWQi+$E@ z%BD4?Pky3bGRK~kqCfAz`s%r$(H>!l58{XFBGM0+do$KR9nBi(e?h(s^pkG1lOC*% z`*P$TcPm--=q6Wt$l?+7E9sEgV0Nwc0mjQR%d_hl6;@`-w<*HfsbKWQ+ES zxLBH)1$fq z{50@j$U#GWycg}q=9B6Pm6c^X*_i4Km76{@bWXb+`UrK0%Fl^OALxr%s(OMY+L-Ej zm{)4gr_d(bp`DFjt!$n&s*4z>*|hY!D1$tjTY#Hw^I6!oRfR4?-9WiaqdH>aa9Xxp zESuQY#WoI?r=>saZ>syEj-jnk9ilel#5Rw1xlo&-daGLHW6LRwXR`-To>N?L>;b(c z>dA40uVfq4Nsz^Mw!u}xF43Q5t;jalUqU@3Tm5q6r!{oJ7U)D8OF`d4Rzs+LxrehM z`cJ6uIiT}*)PqaeV*LwtJMoXUHpL$6kshJ?;Cc$-yRyEby!&E&RR~$%0o=%(f6#O` z0x+D$DOyXoWw1Ts{Zo9yPhG_JC_UI7eKdY3bFL zJ%~MnOiM(+NA~_UHbc9C4cD>|j{J!}!mI00XYRxIPZ+CQ1)6suT!PuYv_Wi=u)koB z@lP=acZR9_>rhDUiYwq58;-K4Ig8!uWvH+HfNAWDJSz>v`)>6c%MW3s7O0Ewq5V`L ztU1@QTlt7hR8tVf#g>wr)FN~e7z+%r|M2URxG$gLm~r`7w3oNR z4OVB_EA%cera4JIRvm`Cl(Is(FKp?N7^ikb9$NukG2g-OE`AL9n*2KfmcqS1@^CB0 zg9s^%P@Az;Hpt7^ zYypTv@!W^lJOLYl0s45hj6gYzb`FpVLlv$*Y#wyTP0-WJ)VJVQiSqoEl~5W)gVH4c ze>4YN9UOr>Y)keCWQ!340e&Nav7eN_ybMqaavTKc3)l=;1h^W|*@7bAh0>!aIn-6< zI(7}^i+BR9qtZ||%g$>}*v@}-I4l!eHq~KEUUDF`LFoec+{BcB8^W?AnL6Z2awHj6 z2STpMhu#$alOTU!lCur;T^&$4L;=c!$|MR_APmah=Fi4LNASOnzx>xN8A$D*^MgD}k+e+DOw4 z3V-^ZuQWB|$ZJ@tMQ4VSb8_`Awr zXZHk@BAtJ-=}un7`zg3p1H>o!*T8R>H=9Qr6D=i)E#XVp5@D~9&0@oQNGlp<;(Mk( z5_$Hst>@vJ;ocTwOdCHWzGvzYd{&-`H6|5t0or#6n}Knd4*OjP{}G^X8-%+?W4>mv zF%|+Z0@&Dgx3TRW!Dr=5A@fUF2aO|s8^pEne|fsIkS+i=@^l6B6=9%n8!UH>#g1y( zkoRxEe#pYcw!4jO_Xs{K*FqX7L&DlysJm|=pC)*%Z*mK}i?QzIY`SYE(n2^J(>vyD zm&i|m9vF&bS+dYEKJdp1A6m4fP+SFjQ8x!bVfJ1&HGh2SW zY}twYlirw#zQqY|va3`RrUOsci;&+0QzwM=fUOT~{2m(&JwRaU1FL;g9n_veIX#7Z znn3U2Z)G0*AtTC%Yjn+ke!xjb#P_7IB{pCXw1mL^Rv*Rpa#3IHdLLCsMP186-m_RE z3+O%k4cT}|_t3g6#&J{Sy^u8l=A4O7587~iq6uEcmJrzA^4p;b`3Kl4Tk(s|Q$rQ* zwxJ5o&oORoEVlr{?M1kG2-h=I;dME}O@>=uB%G#(DzyG^TMIyZbvpJUB*LCb0H!&e zmzYlQ@!n%i~gg=-fzL$0N&-HCP<&NA=0O85V`S5u*tB709$67+!N5B zT`v8CaKHi(7h}szxeJ>lAApTS;fAtoxjmbSwUJag4dDhO&bKU!Xwe#q22UZ7H2y!9$>5i(Mh!KMf6~Z~hs( zR+dpF;7jm!1>(Fb@-oHF1L*aV`e1zr`GCDM5_S1<=?uaYAn)K)`ku9y=U~l>FxJp1 z9&Aw9-BAGBJkTBW!QAga^Q@_?Ow6|;Pho7$jfM9&&|VzOJJj^8!cKxM`G@-+6wFmi z*iRE)-z7bo%*set(0qi6u@<1!o-3;flTM~OVPh5R_HtzZgS`*J#zPRc+Wil) z?lgyOuk%-jh2EyQ9@5tr!c^X*ODt^9nf(zC&*@onp^mxHs67-2XMWS1QYKTvYoplL zL*)&SM7d{U?ts=V?E3d#h5uxItf}6jz70p4?g31DX7<)p?tkR2+xt5H0LPXe)~(Gw z9e;rB@~8>Zm_>e@HB@Om>q3BXpfZ82t^zc~)3qC!g0*U0{edYoA6p%$Ti_4ScO%|$ zreRG&*KbBV)PoCwwiWd8OP4Op_quj44Qmj(YXW|8a|Ys@c&^ImL;s52$D6+MZocXuXKml@9{2ZVer%BOdlcu=fa8CnJ3k!eX6U zzaALt+#1%Q%{6h#r@498#?o5!d2r)HG3S*o=3N=b{3|;SsOFF6(+Lo^2sE%aQ~(2g zh4!~%-qzmtA+Xp(LHj6dU@RZ;@|80DkS0KSo>i#VunN$jxHP9+;~(+m*~6y9WA74w zn_VOY*+rPYxybo0;XVer4OM^`1ptqHI~Tc zp5rb0XsoG!gt=9Kd`{$%_UpcHK^N?ktxxgs-9>(sJwSOEG`H~%$`;(|)sJ1IZR6t! zX#O7i*NVWyWO^sySgrV1{^WM-8ewy`W8LsR9&jDtX23AOU?m@Q&jS7{yA^PQoC{kG z@c>HzVxKPXpN~)WFxkFj(_*|L-a7+ZduN2*NNJF*3p*0^IujLgDCz_41s)Ap2q-4| z2e`4P6~=!L!yfvUb<%oaJ~bVE1nL>!B0wtq-vVw0=m8i3@M+j%1pE{r6)+Lt0bB-~ zG6m4Z0r;*OK;N!xb{T;Ro6;3v2i45byZG+xT7oeL*81RntG10T^DiL^++gyusNhp)StyZ$U&M-R?KhY%UdzW{0qB5Eeci1yIDP~6AeXQ)JvbhhP&@$538$L6RZm|=<*}lF^nwCO~$&KD`#(tb7WUt8B$EhwrxsCy*KK**;bN$SGo+Ws{25zwB^y#dNJ09%} zb}^NU7!SiXrga1PIn4FfK^vWed3_oK&PMp}5Pk&S?-OpFw1-$HjLSPwcx6254XwkX zUb%n4yfVfLgdxYN3ikdGeeib;+8f#&Ukg0V!qzu$h;IjowuvyT1)!D{?R{n8~!H$>5*`l zmp9WUY{d=ZYWO8Tz7BxAV_jH)c&E5lcw1H?eG2cC-%VDy_HZAG_ueL^cL4>_--6~W zgae51lm_wdNGq0K>^n65+l%&t^$aBwx&rn!f%Y4FTpf;edjQ@y6R0oaT!-TwXB=8! z4Rs}fT7>rCIQM}yWTw{Ue*r%#E}icIC`8@s5{8|uTw4#=#_OR?Zze!|^wWF`bp3c> zA7S-FTBnZy_RCDu24GGH`w?T`>6-w0YbJq|#-1eX;Ol+I`)Rzdp>M4HycOe4et!h9 zv`%X~5C?!h>P^7we}cvzrSSo1gaPwd4-v>auqS*QJ3oDsX9{oArF=QTcCQH^M|dZ^ zY|(P!m!0L|NXw+z6=@S}V}JXX!Kzz!9aEZNy&7PD*N7wejmj6wU?u_h7z3CITHj+l zcEkp%djgiBjtgK*wPjd;moWDR+X47@#G~>&56E3D$C@7i@3ws2!8?H8MgBH;uV)Vt z*x&yq{wyZmDHoGhfHz^sS-6m76x&X1xgkuHzZLE@_Ay=wxDC4gLGTVe6ao1g-pR7n zUbV3{L#otfK%dwcc~$CR48_>5#G||q=gIc5du*&U=bO5-;Gfy?#H^ zLb@0aYtRwH)YQ;?%0KkbBYy@I%o&>?)yB;hMCe-vz?zSI=x8vLRU-c&%PO$0x z--=`9LwxcXmP~-@-O0O<)xY5Gj9b$?(X{=<`!o2q0sN4gG{M9aj^s<d) ze*|(0>K=;#(Nm|GG|8_z`Vn`kzkdeQn=vK;*kP3$Fqa8Hx-=IQ1`H%M0^2S2yC(OV z!in%z*jG{sn!teDEKKh;g3=yq1nt4!5b%630&*RuIU!8Lkq1hX#lkPhB1EA{#5Dn;v4bXQJfQta@0rLS136$mdZZ6!`>-E@d0(BIdjdLHf z-M_M>9*+H!Em#>~CxOzPJqAp4NcU{C;0fRjj_<9?C#(eDFIafC#>iE+zGZ4RyT`xqG!AR5nklFhOM{3j3<3WSos!xOt}g8UZc0*g8}>S{u{6Y zsKEOO0OgO|zlK`_;9CI1Lr=hS0P@=cze|CS0zSw4)qovj<-20mD{4)6M!h0d` z8Q|`~6wmr*@5_gA=C&Tmlh1(P9(-??%GpNw6U@N|*hZ}(TL5?Xvz31U6viPhelhmF zuBZ;8!#U%`z7wB<*NKR881M1Q5Y&|x*qhOUFmDQc02pr#sg->z08cXkd+4?i@Xo+g2G;yQxa^1ymE%;v3IL7m2&TbqodoDl zeUbbNY|~%ZW_<4itW%~!|4wD=5bj#QFhG9-cXu|;3mX?;?Julrvp@Bb70{$DS@|CIm#31wV!9-%Xe0MJ2n?+0hHmVXwAG@QAo{VFv7O7H5Yn2Xm~5B&vkr_2PbHHfpg zs&&Sl){e0^Yz&ES)(+}ojR2rd!`}TF zSSw0n1rj1$4MBG&h3Cd--4phgW32E$@16FV(S9jFFIqFg+8CYF zJ}35up$(|rLZ_74u$LfbT1ygj80&Df7AM*Rl_9NPQT;|c0(25<6x2>o9%9|Cwpibc z-2H^JiFO!k4P(A2dpb*K?Rf=F7wrv|FkS*YsJw#tWdOaCn}Tr(0n!!svPg8t3+5&5 zbFi*XIGa(xy5c>l_i*Y`&9nLl0f;B}SbOzFY`ZOA&Ks^SbP=?FVa?EMJ;%C}U>#tTr{LCFH_gIpq= z#`^SO?2QH3I!V{S$Md+0!aAEN_MYOd40i}?il4DN-KD_)0LHz<`e}Bj{tC+AUI*T2 zeuvityFmx8X9?;QtXF1Y4e=T57oCW)&h5}wYnaE*pU{!1p(^zgoR`cq&rCw@Q?UOP zdM#8H#?zRW)*{uj<&<%Tk)&K_p z$$Ky*}_JoY}#*nvZY9Ri>E! z?qR??0A&~tRhn+l%aio}rki>ics*o$4w&4V0#kT`U2ML3G3MIneJ9T390LX&r4jm( zwRqo%ajMP7Q%JiW;^P~A#Vl<)bUmHR`7;2Ws#t)#hKgcA8HF}b9iZK)^KmbV#{_*3 zYfS*%(pvih^>Y>50NCVy05F?vitEfa(V0=&RU>5Qk+#ytC4Eyg)cWukeOlQ8PxJOcSm@N*OL`!9aO zPAbvT&GVRqZMms*CNlwNXggp}{ua!i(^=1#*)lsFI-{vHw)m(9i?f>>BIRJyjdf@L z@gLp4LVtAc3if{$G8df%7PvOM(foF}*?t0tDy^`!3Cs3b<;muGWofc`W|{H{y?HZz z$MR456z<|Iv$Nib^Qu>3Zu$@E-+x>`V(J5(?e(;wIUUr6Oq`X7{igH2ufzW}l<8Uc z$9#)()l}9a;lB(t=$y6VTb#GXe2#J$@+wE2qx0AF-P-()Z66w)$KJ?pvfE2+J)*P0 zSf5-b;k<|RH0aTp?ZIrRas}Q?(SEG@Y1bcHu6Dh&>!DpPHV%hh7HS1vTPe#zUjl!L zJ+SHEIURTi@DQpqv45_%tO5366e;C6e|tCZ8^A>-$O~X6Gwhw}h;`N;SpTjA_fhPK zcOu;40SHHa(5*+bAK|x!tx!H-M{r($1@8DNQfnj5Y`o8ajXn#sVSnRJoFfFFT}0^; zUBVO&_5rPB{ExPQ|10yaeuw>Tr(p-*$G%bDg*2G*hjcS@ium|`YiU=_QAcV>)AtMuNUD8+zYV_{Vd&O_9g7C zH`!O%$M&Au&U|;%d2G0oT`R&M9M)6Jdr^1cj-kI}eX1P$%6eme;so3|5W-%xGW3hI zM~}{=&^QZY0x@nQdmnd%kS!`NWe?N+LE_v8Y=3(kAZ%!iB?ybL0G+RZ%`9ws+5;DJ z|0~Aa|4sM2LZ<1sH!2-xs?9rbhXX$ZpuLut0`7&}X&$UMt`V%&UPI{9t+{llB;*&e+RJ8zk8H0U>&zjivI_!72;q2so zZI}7(ZUVnc@O>HE@9tz_xKTJeKDkp|3Mb+ttmj*HKxPj(Yrhfb5sG`Ym(0r@q5NUsx$b54k*Dpf$eq& z-tPs(V%v?}=R4qD&!l!t9H7r@LshCt;HV%sXiai}x-jMjX1MW(HvZ?y6C~Bn-P6ch*R+ z6Gp#+yKD4~gb^3_)W}B&gD&o}(RvV$P8YT=?y`X!0q(d_(T5Qz;$9oV_{N<#D#jB8 zPMXfR&U`uJM!nM=IjumGz##|cJIcA@kL*G1MgFju!=iihaNd)~(dPl`0M!F0ILA#j zy+@6m9OI~{F_L3^W#5(zcKE4CYLd9;@_E%H3^--Gb^+cPuziwXG?Y)o_Q=E z&$hy)eW(ZC^FxdA>=?qWHmpjOu37Yf8bAfm+6wiCa z^C3Zbxp=M+&xghH5%GLN(A*|yZWqrT;)%N)LAgvk_li{Zi{}AB^N@HR7SB(KXP!+w z^Nyg_g!$m!ge4(-6INe5n;@+wEL*%c6VE*HY%8AaL)XJMKQtT9j-h3Eb`~zZgzx3z z*;_oXfZUp}LE?RgcwQr(!yv0BY&c}q1TvY1=Pe@SJdy5v@mwID3&ryu@mwO}J|v#Y z#dC#tJ}jP(i02c6ljp?ydhy&Ko*TvUdGXvPp4-K9hj{K3&oc4cEBM(jo(Dv_hs5)+ zcped9j*90o@qA4@kBjH);`xSnzA2t>i{}aPJSCp*iRWqY{7^hU63>st^HcHsoSr;E zJQKy!C!V5=c(Qm;5zi)+U!Eo2v&DOkc)x_og|{aO^A5s2pK^o}r|^qK7$FlbWWqNI zm(Ai?F2V?|_*vodlXzAN_n(Q5dk)ce&n5cqyTyC4c%LWU=Zp8V6yE&?C5YL9<*;qU;A>JTW@CJF(lO&lXWSGT25bq?nEJz63q6VJ00-V>rHq(M&( zS>a?J!e=9=^rW0-BNuog6?%3Q&q{i_iE_4=Aw&+eQ#qdb;z_c~5fpL+g&gP^@|`c9 z3&eAwc-|wPB&8g7K)fFk&%^W-`N|Rb%Hfq11}WkRo=>nG@O%_c4(-vDB^f*MtdCM| z3Qov{O0X$wFP{I4wD*szv#jI)-}il=vv9J)HWL9Ajf^SVaKprjNkxT*3ymo%7S>8i zR%BFUERpj=EL56oBSnV}6_pt&+b~ht@kA`iXi`#Pp^{QjVNp`h_&l%I_xs29zwhJm z{p#cSI`_Hm_w~N6`#P_4-}kxBbw-IwN~ycn%9d|HFJ}bS+E#5>s=P`u&C-Z8Dve3w z(g&pbq}|d7r4LCTmOiR%k4bx_`=$MA@qqN8^pJEw`m|yOrO!y8l|HAOhouSW^U|dB zC(>c*Po=+7t(T?0k^WBliu5fV@4uXS?{e*WCrDRIPg42G(oCsy-CEDNZms8Bx7Ks6 zTkE;kdM)Q|r@7LzU4Cz!bc6I9=_cv9((_#pd5^nxe<*eSTd zec;kqjt*gn|lpnIQDL;&Q zY_H>5!Ej!O59m@J)?ct)@!skFwT>lt#e=l zBYX%w@7Nn?A@LhH^PGlm#yK0Th<~MjgOw`YUGXW4d$-$8_Zqh zH<-K1Z?LDOgVJZD&r02Ue}lRA{swbbzzyD+?syp`j+aq#C7WHlT+yzx4aeL6-r!!4 zyFc^<&g2_)2enbovgD|P3bP4=YPa_8YqycSN~d3Y1A zg;RGP-lW%JleyPoleyPoleyPo6XVZbZ>8JzPLgIyPnW(|>Rypej1|Yba+z!5CS4gf zaRxiY-MM>R3N(fV8p8s{aEG1C816^idH7sjufu4LO3vg}K9}>}4e0s2UgzR%7g?lQ zCA4xbBixN%F0GVSDRR5iUAxa^R9!817j!PKuhW<`F1<~y>{ZSOlyjf7Tl%2%A?d@? zN7c$>(q8F)X}|P<^q};RbU^yFbWr+?^jYb1>gQqUhW?7utTssdth)UN2L6y6dO+Ua7m{pXZ(9GV>}BgSQu~ z&@QCB(7OoblPKBF=bW&Bp0a!u>dp+DleD*laX25}I(27;^Kq}+uH?@Ae9q5D(Cy1x zP&c0E>zr^ty8SPueYg zQ2LPcVd~ z(gj>|osOvPi&A$!xj^@;7tn|6>;l}oAN3gRB6_k4J%MXzk)6Wzv`FWNBHhas>0Yjg z^TQjImuhbr$5O(t%36>&sP-JM$z zzIE#E+=}?j==1@#wNKhDeNg(4^kM0vYW*>3uXMk(UwS}#Phu*CiElYB#)=YMt%~%jUC3DRt*u_i3sruh&cmg44doZJw+%gkakvDe?qIi=yMx_g?hbZ~xjTU^c*Ci?6WD?`oVt5}ExHHTqI-ZXx(C>z zdw?z61GrWOrO!y8l|H9hho$a*U<;#k*e+uL!> zBd8nOt@eoaJ}P}o+AG~Jb$3Bq83C7pe^CuRC_N+{kRFl#Li$T9CFT`vzv}AhE@&(7 zZny33g0^y>a|P;gUAT(la(V)8zl!5(L*3`KtMrOrCC^+%Ce(3?}LFpmsfYi;BU1M$@>>7^cuvN*) zRlMsb**=9=uu6TXQXi`5;Y+rixmNxidd>q*ojzw)6aUowv8M-f$1wZoX(cchoM%Ie)vHznwFc+jcWT+igthW`wqLz9K(&J~tS% zo4m3+H21qh{n?@Z>`+g*qbGg`=g$)Ke6F5cPpHc|Ra(T^X@`2XL%rIeUhUva<#I-( zQE5yXm%85W&=q!vuCT1wQHi_4?$GSk4vxiTcE_?q$HK}WZM$RHp<~&>QP3-n;xz8k z+~&(;4QM0;1v%Ae4_1D>U?~!KyckQ~_-DW-mI(4(V&E{rz`L~OepNkl%0$R`o` zBqE2@<~KKiO44r`6QzENJQ_EhVy5|K|LoV#3! zn;(eCClUE1BA-O$lZbp0kxwG>Nkl%0$R`o`BqEr1xg{dEMC6u;+!B#nB63SaZi&b( zQMn~5w?yTZsNBNmKr%<=mZ;nkm0O~63-5W{5|vw`a!XWh;oqWGEq7Ll$}Lg3B`UW> z<(8=25|vw`a!XWhiOMZeMwHJg{O{DARibiBRBnmNEm66J^_FVIxh1NzN>px%$}Lg3 zB`UW><(8=25|vw`a!XWhiOMZexg{#MMCF#K+!B>rqH;@AZi&h*QMn~5w?yTZsN52j zTcUDHRBnmNEm658Dz`-CmZ;nkm0O~6OH^)&$}Lg3B`UW><(8=25|vw`a!XWhiOMZe zxg{#MMCF#K+!B>rqH;@AZi&h*QMn~5w?yTZsN52jTcUDHRBnmNEm658Cbz`omYCcU zlUtZC;8lppEit(zCbz`o7G6c%5|dkEa!X8ZiODT7om*mZOH6Kw$t^LtB__AT(Og@RpCo%aXCZELRlel~mmrvsI2{THJMqECL%O`R9 zBrczD_kd60@=07iiOVN(`6Mo%#O0H?d=i&W;_^vcK8edGarq=JpTy;pxO@_qPvY`P zTt11*Cvo{CE}z8Zlel~mmrvsINnAdO%O`R9Brc!C<&(I45|>Zn@=07iiOVN(`6Mo% z#O0H?d=i&W;_^vcXO*~o5|>Zn@=07iiOVN(`6Mo%#O0H?d=i&W;_^vcK8edGarq=J zpTy;pxO@_qPvY`PTt11*Cvo{CE}z8Zlel~mmrvsINnAdO%O`R9B(AecTyBZWEpfRe zF1N(xmbly!ms{d;OI&V=%PlQ@zT0mtlysx+TOs~!Q+#q8ub@-+Y41(bGC%?$74 zu71*X;u)uIPJXB2cPf4-_vfzMeP_B;GxIw&GrvQB4+)2{xs zt3U1PPrKS}S6l70MNYM~OKt5^Tf5ZOF15wV5@L4gTZvt2YnR&ErM7mdtzBwsm)hE; zwsxtlU21EW+S;YIcB!r1YHPRJ+O4*Bt1Z^A(AI9XwOeiNR$IH()^4@6TW#%DTf5cP zZnd>rZS7WDyVcfiwY5iW?NM8M)Ycxg#VQ%v+M~Ais4YJKsl>ged(_q*wY5iW?NM8M z)YcxgwMT93QCoY|R)^Z^P+J{pt3z$E7KfZ2YO6zSb*QZl9ao3i>QGx9YO6zSb*QZl zwbh}vI@DH&+PX(Gy7y>Cw^Q4l+P+uY_iFn-ZQrNuy__vq*0s=h zw%2oWXnPr3N;I~6HHX&4D|mx-@d_TYF7{4Zm&W{lUf(nAe#PHUe4E`*`F?v;b8C-D zd!_rOPY~H{Pbl&UA`jVZh z0mTd`<~h7HY0qh9<~c^`2DaUM=Q*7fpVQ3DVZ|I)%wfeGR?K0=99B$1SMY?|O6dKP z&=owPD|kXzaQ-y}GADEePv{EH=Wxa(p(}WTchhxje@rp%b3sB^@Pw}530=Vxx`HQk z1yAS-p3oIMp(}WTULB&A`xKeb6+EFUctTh3gs$KTUAq&yb|-Z0PUza5(6u|k`_%Qp z%`+r)?M~?0ozS&Ap=)!iGqlsA&{MpE8L${R^}BPnkr<&C7g!KmSlq`bl3 zMx;MUc_XR2yQI94lsA&{MpE8L${R^}BPnkr<&C7g!EbPQEt2v^Qr<|)8%cR1DQ_g@ zjikJhlsA&{MpE8L${R^}BPnkr<&C7gk(4)*@Yc_S%rB;}2yypfbQlJZ7U z-bl(DNqHkFZzSc7q`Z-oHU%-WZlQhUE=@ zpUJyvSl$?xH-_bnVYy;ht{9dphUJQ3xnfwZ7?vxB<%(gsVpy&imMezkieb58SgshB zEBIFq)#83>zx06gp!AT`twhSWXz06Ncr4VL4$~P8gOGhUI}_d0JRJH zAJ(fstXF?nul}%J{b9ZO!+Q0H_397nbsyI2KCIV$gjbDU#p*gTqU*>ABS{JQQQfh> zsF)WO^P*y2RLqNtc~LQAx+@#gUD+7%Z8oO(F~yJRu53(qWn;Q4<1b5-e@u5}V`Ovj z?yi2!++F>cxx4x?-PMoL3VU@|Kc>6-F|M93*%(K01a)`yN7edKwSH8sA64r|)%sDj zepIa=RqIF9`cbuhRIMLXD@T?2s4^c_=2y60Pa5kHxS~yw`EJx*m#36@in^5WO0ky= zY%9YQ8D6p}G90l*U9}f^H*H|st>9YJ3a&-1;98{5r%~coa4l*D*P`Avi+aB-a+f$s zxm&@t$h*U3a4WbLd3QK4GrDcuMvPNlHqqMA1TGl8nYm}BXO3NChWsTCZ zMrm22w5(BD)+jA&l$JG0%NnI+H%gvwpIpAkTj}l|y_I;Z4dss4dk>?xA7woi%6cl4 z^;9V9sZiEap{%DuSx<$so(g3>70P-ll=W07>#0!IQ=zQ8K=~ApvYra%TMU%-R4D7I zP}WnStfxX*Pld9c3S~VN%6cl4^;9V9sZiEap{!m&S-pU=dI4qi0?K+Sl=W07>#0!I zQ=zP&qj z+l=0%cM_ww1La$3lsN&EZ>3T0eo?-aM)_761^Wx`u9*@~t%6+ykS0 zD~d@GIetu)HF(kS0bqkJok@~t$=x6&xzN~3%$jqaVJIQ@3jqB`E2(_FmGUbX) zxgyhZuE_M9D>CJZOt~VPbL^R3Hs?vFe7lJ9tr5z%0Vs35-WiHHLosJ4<_yK0p_nri z!>^rqznsbVtU_5~h%)cm$Jf;@`KVt(gEqy>LDu(+53$2St%c-QpqjT!UbF;>Cv&M6?n`@$kxh9mkCX~4* zl({C9xh9nLS}1c(D059Hb4@67O(=6sD059Hb4@67O(=6sD059Hb4@67O(=6sD059H zb4@67O(=6sD059Hb4@67O(^TNyv@9SDd(L_3FF2nY1}SitR}sSC`VO(k$Xq4{3j#! z63TB0QGQE^@>@cbb>b+$B}7?Ig7RBJlxro*ZwXO;ONjDYLX_VUqO9yf`7I&JZwb+; zl;0Av9hWk%%r-N=D08tWv!p2Vmngp_MENZt%5Mo#eoKh*TSAoI5~9zkmBUhgIk@tl zxP=~a)>_57v7BQI==+uryS3LG*D@<)-1b`OSt>bO+v}w3r5mK&ixRm>+XdP_SKAkG z?EK3lw7Bd(yP=mYx1pCW-+*q__EjpsTFS~a%A3`bh%_pVN#oL%V>^hsO_AKGvdx_; z%AG38ohr(mD%zz!+%J7XB~Plwezkr;dQf^uIv{108g*HvhK@*Il#VISl(rYO&2KAK zE^~(Dh`je``y_2=XggEeyyI3buRe8|IW>1CMDYyDdkuZRw%1A-VM@-HuH)ATo~_sR z1}X1KN;YY`K-=ePn_qBHe*Q7OHNj&6dV$J|RC4k1Bqf)rgcX2nZev5Rx$H+T58&Wb2!MU=B5%2fvCDuZ&BL0QL+a+N_@$Bwd&9c3Lm$~tzGs|?CIc9g3O z$~tzGb?hkX*io)BDC^i!*0H0kV@FxXj&hYjS;vmDjveJHgL0KYxyqniWl*j%C|4Pj ztIX;Z?ka58t}-ZBnbj-YRR-lMv-(sdOa-sZ^3+0zw=mW~bI#{;5rL2Qx`yuJWQhv!r3BTk*`6U<1FS$^D$%XPu zE|gz#q5P5y<(FJ2zvM#sB^Sysxln$|g+8aF6eVWGYH0~P@vCaD$Wo0kQ`4e?Vbedb)i@GB^&8_T3-4UJUR`#N- z>_u7Gi?Xs8-7n=G$~Ny%ly@k~I~3&|in6j7Wo0kQ%3hR}y(s5QlyfG^%HGwd(euNr zFJJwo<%!jwLVvWn0^PTIE84mG3YAw%uR?#c`f7CF>T9%JrSeZpKckXrbl>XhwEbC? zZXh(I2g@apm@Z{a3=n|C1j6Nq{vlYZg!*s^zZ&jq|UVh1Kv@RuWs*O0!Ypgt>=a^8O@S7((<;oe$$5G; zjG3Lm^Y<2*<;YP1lme*yruF&|A zBv5Dlh}nh`vwZgF*O{He<2fA5#&V#IO>M?)joG=hf9|B&2Y5U$%AdRKF}onotZ0FM z4up0;*ac%|7Y&*f7ysXkn|+A#4_BIfq>h)R9mw&q9N@9kfX9o;b@7zhC8=hgAodg8 zW@TB>YIZ4YTsmX6r4VM#K1rod)&sfA*;n3gc3Bjtb6FCm%`PYB<@08rN(JhDss=jD zDkjXf_Q43y-qr;^>e9{?#ZU?K@rrgBFuRhRSCae6Q6Oh!8k9i2*;PemSMzvvD|ExS z*)_CvO%C*$Rq?!v+}D!(T4JxI{cF2`Hb2t|{XpK&kheMo@_^jcRnP?8W}mHqT8IL5 zK063AW}jOF^mE%ZESY_t=btZtZP3V{bj*S>XaL&$0_}WZ*6jKau-y6tr z137Leg;ulLHP8dpubng7&hzbsPz6oU0evuK_T@Y%hkBs=%Y!fuvu0nJgn6?%V(RE? zT@6sbt{aG}BllNpVae>qY#`>wDj?U5#N0Rr^zUobsm}uXS5J=mcIbyum^S-*)a)C* zkc3H?H~VHPQJ6DpOoIX_gKf|V-7pB#W;>|+ofH^@DYKi~&6;ShX~gUn z+HX#WaUeF*0P|+iPP14&P$%AGc55LFn6=dL=fKJL-Ey<h)fFl*LIe{LT%yCci^ zCto0G)rlwAGW*dQ$b%B7f_i9$ZWx4d zm^FJM1X;k?Jy`@5(7~UNPlZ0S1H>NWH8@1wfhcrBKa9dOESWvE2J)Z;s-PZ-f2td( z|J1nIk8`2d>}g`3ZZI3HG<&89D0`NA&l2+-ujg~^W3<&EcQ&V*kj5*%9g-X)*g*uh|RaePPmUl$<}$f+e#T2l?}}wfsrj za+o(ex(29!w7~2o%EpNs?>74tIetxlem%*bwIAb8t|$3(Bs~8OZTvP03ueDdfhzu~ zFdiq{V8-nCX)tB>hkmmu^1MpFUgh~~t_ zon|wAW`C+M`*SsnoBgE;$TM3HwDZ>*v%jT6((LcV{hhl1;Q2o~%>HRW?tjsjf9F6y ze|oeOIF<$K|A+Gb(8hmy&HmfS-zzVIGGPDG8Yt)Aol607AEVu6;<-QLGo*Q5AtcS? zFLilAE_9j4J(e-n&AO4XrQ7Fz`S|yCfDjUKrZh4yw$VZauz~0(C&%!=fq;DhauyO1t8aZnxGwe zVG!uUNgUfr)JZP~a;1;L6wI4W#enitsDH|gd8ZP8Y9UlW6#8Klh&`VWdo$bT9+PNR+NJg9+g7=T&x zPABi_YakbjfcVqN#r>;yI{iE&4e0k7P0$0By*CHQ{oXDh_Prx83FO0qUJm(k=vz)T zv;g(qN1gYP`+a>dW8RtM73DnEKqCyon0fCnfKs4c?v=gwx0{!n0$ET36|fClc@pN$ zTTA}61;GBb)LGjC^l$9|jKG9>XXQdA)Ik$;0{hPz2l{?CZJeDAg-{B_p4|pZ=H;aV z?dRpeBoLoR`8tkq9r@OgZ`~BknYZ2`4O*cSdd=HV3ytRGQ=UHr)8?H+d*@^W?VVE& zHPB?<#xe6Y5x;5HyaKk*?K1BJ9M=b^cU}ujm{&;O3h757G3S$aGdVWX=gmp;E?{3# z2s&WFybGh|eUSPW(Z)s7<`p+U8}tAF2Byp_FE{Tp z`gd8sd6$<0WuKz#Q`D=dG;eDfWJ5j_L!Wuv`+Ha9K@pUhcO}oSq@R_!PzcnoB!6X- zc~?>QD%!p(Y2MX!K-tx8&;{hWhBmL6Ft3Wos%oI`RqU^tfd%uf<@vQOFl64RY3tKf z=6$Bzyy_I7&(-thUB~|Gh`)~b&r<%`bRgGf>!1n9$Nj(exe=H!Z(BaJ0(CxL0pl=h z-WRBIeJYHaS5pJD{l#LKH1A8)|57LPns)<_wZztrnYTR+y3G5sK?_X5oOxdCG);Y?yu7Bjm0nsY=5l;=u>^Gd0)?h0-*dG#D1gAyl?XSo5Xyx0=7ZD zc@4DRK+bQm?^|U+`L`Nj+`OA;^CohCy9(%2V-xVWgV-I^-7#j~cXG|UnH)FIo7Yqa zw0{eAoBPa*tO44Nv_J<;n-?tr+KJLmECuLmJZj#p)V;M0sCVlKFb*yB<2G{KRt*d0 zeK!v(fb#FsuT}&1I1aPs-A+4q_v?W8odrNYcG8cXJwW}t z3ZV%`&1+AG0rPfM!iaghiQnA;3+C-|lifXCrP=EMIb_}|DUc3@K#t$jhu@dLta*Q+>jH!*Kl!6=a9?IrUT)<7PV z0C5Wq&;}gS!VpZD_aAcnrxJQ0Y2JTRARDG&!MsIsFVcr4;+BY8qR!Hsd3-kT{zu&Z z3W2^Hs{ra8qt0?QOqp-3&<$hedv(wO{pS0{Pz4j_2U)NU8i4pvIx2hjTfjB<5 z`0pHm379kgT`9ovysHq(ftWP%r;$I6{Ao#;gn9E%NQE3If(odGDA2|Uv~dD$oG@$t zyUSo3uK+e^@kc3Gfc1;MfAP2w%X3T$o z1$3I9OP<_3s0HG4iCs&cwQVqH{#jM#bKmcuO?e*euA{H(=FML}X8s21=jXz#`RDYR zzp>8zP3b@%3d+qtmwM+C_kniv&#Qz{^9#vwKHHlMVaogqddx4PUl$VlL4y|PHvb~} za1l8#8Zp0^{uR^Kht>e~KSaF`)2|N?ng0>;d}Q4Gk{W0-|DznwN6GoIETHX=Etvmt z%1e1(N=#`Zkn>`4UfgT`B{@JlpP;=@OqgFr{!3HL-;xRq=6|x<{PH?r-(|#JRu41g zU!D(9VEa>LK>4SLsVId(^SMv=w~~wbdH)JxuV@AKU&;2B{pNFD?pHPdv6V~aUqw4t zb(w!PZC_2Ut4GbhrU+=`8n&ylpb|#Rzm}M5*}it({7)0}Y3hB3{h#T91@o)7!KC@u zl>+TvH*5Z9dHgK#pDTv}^S7;mI+!#6^W^wEb-$1XgXUk)zU$k7dNs8$V*VEkfxdjn zpaGKR-$1<^`pmD*0ru6-n7^Il*gj?cmn(souVh0fESX=I2h^>b2A+R46{!1F+WIQ( ze{~2Z%)hY|$a5pHH?r?W_T9+78{NJ+^S_n?VAv5-^zg^sDN6CLZ|sR8RSDTR08#GqTaVlpbF}t70A;_o<{OClBbb8 zjpS)0Pa}C6`(YHOVafa*YakEEvx7W*&hU4P!HoIeq0R541MPmN7n0`RO#3&}{>>9G zXMR%(aI8&TFaXqTqV6r!y@k5BQ1_NnsD=h;gB}Wh`wpJp$(Y^AnB7?iEkK?-=gn_R zg&ZgX+HR|bD0D(UjKVZ5ng9JYkOw7D1?@0q{!Z%er2bBx@9Z`IF8XvAeYz_jXzMQ8 zx{E&FMeJSlxt;xdp7Yz;-%g*~tDynfpa+Iv0_M!$l>(J8Y5wjsr~&rxX8)cFpuc-& z&F=_778F1kY=cIiPaX8BBMIc_m^c3isX(89Pz2=o!HD^HXG0+ne>d^>(C$5y-9yh~|0e}I?+u_S0PGfF77Oe}v~FQK0UT6i5fkjx+#qM~FKz z22U)z=HXsHNf-HejxYH)1eURpbN{7?Fkt@CHkdd6r79RRf4sr`U!_8)`M=JG3TQF^g1$|VZ-RdQCLJ1K z(EQ(~0I|O%$8Q(R|6L`Jdy<&RcAzh>7_5O@AkQo1unmS_9A?b_eGN3gfcbwYfhM4w z&%pi^$M9+ukn1)2_F6qGng2TbUMKGLKA1Frnl`8FfPPL-oBziUbejJL1Ie)IoC%%7?tY5t#!fP8T+#GRp#LW>mN8B87ZxQzvac>d#RwdLy3v|H%jKPfg|1e00d?B-%ltMK$KpXVH5KO?F`Tt6RY$%3GsDl>hf&mzV z8T0>bkPi7!3f0g6ZO{WlFadMsznucvPz=PqP2AhWy-nQP#Jx@2+r%vpw?N!NA(TT6 zG(iXS!3a#jg86*k=>I1dilGwfpar^M0LEa({QnxHLq3#3H8emQ^uQ2Iz?}JuDUc0? zP!2WF1Rc-^BQOOE<}al|E)+v0)WMMX|0Bo$x`6oq5&u8p|3~~W;*Sx3jQC^3A0z%) z3lMv30LEa({AGi5$cIv>h6ZSZ9vFfNn6toAAR7vy9BQBmI-n0mUhf&mzV84Fezq(eSbK?n2!xmJ*C#exOzNCR@cgIw>Z zggPMCJGx;ICScxzlvK!pBB+2`h(agy!x+q3a9j#x198WZ?>O=uN512_U;v0aZpMO@ z2I)`$ue9RFAskEC) zyQ##b(r#)!v_TIH0r^trELcU{D&kfZ0`0CMA9F;(D%xE|yQ{{5eD4fF78F1kY=cJV zfIb)nj^kYh>5vblPz?>x2DJUIA((^(3)0dc4~R=6Us@B8FO9e~;?l-o28ca@*b}m$ z5Qsma8tR}0sB=OejKCBS|8C;noeRZK3BFiG@S9&$@8l|@axzY!K*z{QoPUiJInb-4V zUeA-ufbl;WkDN^G$=xsry!I#0S&%{A3}Tr#3o?k!AU1=%8SOx92C*5$W{@{C1jJ?% zn^_L@A(PllVl#=&?1xd9h9wKK)<7Q6->gcghbVMHuLY-YJpaEbAx8x?fy+5z!Kob6 zspLMDu{yOD7@t$8EI2I$^!cwe)8# zZLg(#Z3}c;a8??WLIaTNERNwU`gwK;vVlBj6LL2M1dRyy)XphK%WbiEI2m}==-^aPzKdd4=vCMeHMIx{U4yt zdE21df^8)*Bp{>1^H>`V0ZOG7|^Z^(x#n6jX@ z&4TSb-(CY_7JQku!0_xX|z?21FHAshC zD28fifiCC+;=Vcqv~^<&5PM@T6hb-FK?`&M@i&eEv0qDrY#{Dyl~4l>K_6@eb8G;;OY#X8$e5(MaE%-L&jk!<>#5NAVj0HQ`zoW^5@38MXw0ko- zZ?1uU3z`f{p&i(F3x2qT$7UXzt6|E5NUa6Ye3-W&o&wa3_rZ(>w`K$F-P#5t7POGB zg+ARzUv4V~UR&nYg75O$eUCifo3x;neXV)WWx?%fPypn(y&lMOJ9TcStviZN58fbZvtr3+~Scay?K9gD`8szH*qi zpt}@$EqIXU4|c<-1rMbGIUXYJ;dEg8VUF+N1q*sofjm96&l-9_Kh8FNQW?-{T_|{IK1EzEKOFsJGxr>OD#Re)9IS zuYcBp11V4d@Kg&JB#JWab#&s#9q zZoxAp7Cf5=T|i%-qux+16hk#M0sDrMFm1tM$`AJf^%I5A0PK67emze+$yy-KPohA3 z%-;mVJr?|w*q;(NLjOj}fOd|g18p4Xw%})Z&;hd+yg(Z-^ja{={!z+)o(9x?u>l4x z_(cdf)-m>vRX{6DS@6qz7_#7K84&kU9&o%b(bjl25I0WTuZa6quLZwm|F6maGWlNK z28}Rj!9*5RLpzMXoCUvG1JwO3WxpeKl6;fn7Q8|`zwff(55!LqGsV6sp1(@YSBro? zzuE~&V0>On1Suwa_~)6|(>vfz(V=!Yo_-XP|Uau~GW&0HYn zO}EXy8QPsGgC?L)f1>R_ag2W==bwfw_;WT?0Q>(;zQ6GNFWaCSrY)FFgJR%0b1=bQ z$@kX|3;vb`?H2r?D5&GWaZyFku`24H;tlL~pjvHqtXDElwl|LuVx3l33bQ{<`N}$&w9xV7I=&isetZ+O0Xb7sfqkhh&<(_{ zqMcRwK)zL!ucCa_2$1)kDUb_QKwIym>|K<-s~G6ZyGCKgLTN=%W1$n$ARAgO^lk&{ zt|sopP79^yS%}XNq0A8royzuUv~xz6h2EE9q4(DVeSCi}u>bwj7RpTr`kLDUNm#Pb zTH09~g)x}7&{@QsMcG-^Ksoogp|eI|&O&FWK><`kBXq(bOj;<9zUAct`SaM9N4-39 zuA_V%edC@tw2tz1-QdcXEX2KUXg%fYn}GQBl&`0J19>)(XF~%Jzk%`%3l_@Hf>Nl5 zPDsL>h0dY;oD!h?9P*qqX`zj2K-oreY-9{JPFrXbahqswQ!5O?yoCyAi~HSBK^yeL zl!eYsg+i!?7NGoG%0I9MilG*|U=--rd3jI?Q5b+33l-8=(7o?k$n3+63Uvpc{z!Abt4Yf`u-kjf-gGBKmSs4Md>}`Ylx4WT6iiS?D7M z#C;?eN}v+R_mMW}g)x}7P)Q1812HAl&Rb`PEG@WT9(# zehu4IJXY~|EsxjcLOC=*Hw?k7g+84E`4;+2Hndu(nzp`3Y;7vAUE2c-7TR6~a~AsY zpoPBD0@ST*v(VSpSm^7F-8b@pyx*k1->kDx!(xn+@dZBJTbin77aaH5S@Oo_#!ahhWY^57t@eA^O^rw9q5f7UG^T z^cdT{6Bc@$yg%Fq(-!I@_mA2w^aRKB1pRoj7-*-T=l$e4Py+Q9I!LZVQAk>7fIbYc zJuq#drwW1XAEyJkpB}Q%Gou!ImdEGVf0)<=JYQm=WP^o%LLa#&3;ndzLL*HUIzpYF zOKqM0mxW%c2Fk`OfMXl)fIe_#Q?Ov6Uy zg23@CvDHFv)LZCH zV&9y$&n3%@JX!f7Fh!T`)$_=G|r{si*8yVSy~^B`&AHRNHQ zF?oZrL6 zl@|U`w}n5F28}>}O2|_(VBwEuK_OH?9rVGHg+I0iIJS?|kB@g*xRm249kuYq#TLG# z+QOWR!=LE4a2b6n<9S&pBw^0Nm!?Ara4eU00OglbzJ)fn(B>x#V9LUmWkZjJFCVgS z1^X&SEPUk}3s-ho_-Y=RLkV9qYvF4{K>VlSGYb~3Cf{}B`&^2Jw-o|8KVM_vFXY3Z zg|DaG8rrDoweT0C7XDJ1g>OiMVqo759YBs7<}F;?1U)cj;q5ul0A0ZIFB@b-9Sp&& zg};&o+ko74?5`^aj=he3Uo8Q)Z=_#0vj1x#D1&Yb*XKi@g}+{8;cuh@aofSVE;ct`Y+tmAZDO3Z;*+|{SF$?c#v+#FXEqpU|Zl1O9EtKC< z29(`0W8vl;piXlyELb=~8-jWf`V$#~ahS7kl)B7Wgrg-uohY%6sUJA^=_r!txFbe$p-Sau)l@A zxAX!1y3HU5%ApY`zikxeEd1RyPz>9k4aoOh%D+eX_bC5fEp!3#t>kGffI6W4R?1t6 zZ=C|#zdajh|91A@PW!j_0qx&Gy*p_Cj&h*=J1D<{e0R)Q_)glnvlwXq&Nd+5os_px z-bQ&F?Q<;)w-Nt+@_e86zh4LB|9&5ke<$TT$-lE4$iI{Fos{22`CWNX4aDCy1oIYd z&xZyN^_(}3gIP2BE&n6vO6^6jaED0Bh+-9!C7OBU|P2I4!| z-$8pFeK2m}9~jWTACv?A`vK)Y7=<|t-@OKkVH>mo`R=Ct9?I{b{GM9q0^&Q#(^&v@ zK>p4?AV1gP@V(@}w;afSFXi`AejnxcPd3f%f-NzK`;5%Daj0t_I?}hhW~q z59UJ!G(j&+S@@w;D295V{zJ6?a2nA5!%ff+a~AF)Ur!yh!w}3`_>pWV1L7Vb?h)c1 z&4O}>0&$PdTllejsD(Zte{UL)zn6Nw)a#wI@P6{|uY+!wvhd^NdAu4rf#*NW0rvlJ z(87J3Q~Jt*zWj(7?o+}~roya+`wO8S`e53^2hyP!C_B&tBNjfG1~nEwM7={x79Jq~ zQz=0Hr^xZ+N((<70{SvY{lOj!KT`z6J-ZF4^IU_4hYX@HZQ;WuPyw~j3L_Ryus=cl zL_U;4HBc|nX5r`APUb-)j9U07lns|bpM`OpZ4gDwjn$%j^$v+&O!i(YN1KS$Hx9*q*F`UKqFVD;&owMNkdYd1czdzo)(5)1Tjy zbBg$>NejQqalcCLS36+B!mrW(Yh^%Rnac{lPR`f6EIduVY09SuE&RtUXoPMUweTC1 zzd`*s*8sWRtb!H`&lEr_%v<M3q8;GB!?5{;IV&T8B?{6)@ z_TLMExWCU@c&-wX7JjP+*!PbVpzVKj0mt-D#`2$i7M@QB+MOS>@V`oc`u{edoqzYj zf`#9X0*?!{`yclImpuQapNs5Y3IWHmlmi^YQi+BCmk<3GKF0R3ZVN9L*a{2T3NIDv zV8T}Tg|;Fvs0E&fhzXTIhph-#+lm!gkO%Bv(FjYn;vJQ+U@KCRw&FO-SC&JctvEgf z+H6H?m91D+Y%AXRf5>|iIIpJvkN@25oO{pR?^M$Ik%^YkzG;d|8+i}`Iy4j-`CIg`}_SLe|gU5-h1BX z{eGYKS?`&9KLb4u^f)UCb&nD1Wq}f~kx)Mt949nrOK40TkOLqS1N{}M0bH*z2uuRA zzzVPx90aEbt*C-(0RC1?23Y{I6&He4U^h4n&JbG307RyMQCLeR0GXGGROjxz(TMJ>;{Ly8A30%KrCnr(m@`W0hWMu zU_Uqp&JkLr0*C_%U=Sz)vjAkPtO92Ut*QdZRc!^jfPMgRueuDN9;)sD2fz_l@ZnPExpWqxu@yiGI6!D^52OO< ztqqylrwF}F1>*sZFSkG(p>@^~TDJng^}1`oX+rCvP1VDBy_sM!*a40cS|2*=w*v61 zKGNz#zWyPCW)5Nje2PQfxLE*caRGfMndBu8($4Te>~1Rz(xm@wIg(OTuEpG&Jzm35keE8GZ8vFWr4GVc82}Vvk2`1 zon4@_%P@dEU5*i&L_jit-K50;{v|<2SLo{s`L3-1(z_y0SLp2unXaqA4sZ}0C$yUd zLIApPKS#U4=WbKLLI6A6ptIW{LX!!hDahLs>FGM5eKr!>7kT?aZ(r!?Hy4~Dv_I1O zA0c$WFtCo$ftA5NLI*+rAm|*7yo2+=ZbFBof@Opb4S|`24r>J#6PghRAUhng!x5L^ zrwPqW0I-?W2+RQI2+f9`>|=zEfXxv*2px&Ek+7N51so(acLg|0=%{{RAEBdRXEgGT zK2B&JWb#%KI;I+!1)wLtEr34-mBC^{3+n)!UxQEl-kKK00_ZP>f5rGLX$7F86!ymw zFon=@!w4N80?P=U038#v2))(bq5HY47-ydHyJvw*FiHd z32Y>EN@dUO1N*@-aE{QK6+j$F0E0jYm<3jVt>7RyMd-~cs0NyWWRL|W0m$BhSl!YEAO^P- zf|+0$*a!}QUc1+Y0AHfO`; zY}lN=5Uc{b!C`QQ(Az8k+1uKJbdU#TfF)oZI7a9kq|a#v62Kr(@(%$0b9NIt7xw4E z?%W(O1uO*nz+rHj(0Mwj24H_4$~X^YoCo{3*QN880mNz^0dO2Z7Wct)0m`%hWm*88xF4nqR)DSGAUH+nLKVRNLfBuJ46?u^un?>Q zyTM@q+1sZ8=)NNl%m7QkInV&U?tcA4uRu@-V3|; z?jv+rKY-(9kYBb8Yy<}YWbPxNGH3+40NB58Jb>)|=>Yncj=zzRaw zGy{{sIzpeQ21>vx0J*gUBmn4GdzR2A$Ahheu2TVQtb=dsrU1yV6W31@x*pfDA5Yg0 z1JJvEF@Wy%hY8()d>a~pegOG4Am4_A;2fb(#e!r2`%f(c`vCN9tOlTOV;)!twt{1X zZt_4Y06Uvz0od3C8=GNca~wzqu(5e1H~?T{3v6tGjV-XTWeL~~U<3EmbZdJ68(U#x zD{O3qji)Wp48X?IGr<}F8{1%G8*FTYjct>_3IH41&Jwyk1Yl!3Y;1>(?Xa=^6rnpR z0NB`(1LgwQz_ruG54*GX+2&?$zmT z=-PdT&^?U+WcKU;ka;#494B-y^zDV6eMsMz2M!YYTpdtI=<^l88bV*d`3t)V-QO0# z#*2`9@d%+WAto=CfQ^K{tODph&}z;19590O+veNzP$KrCnm z5gdS2s1rQ6Gfdr5avOo!#0TzN4guaFHzLg44-nWtV zHsbM4Bd`@9CWj9a`tC4L2&RC!U>R5gAp7nCa0Hwt^gRMR5CV-rdyoo-fkH3^%mvH9 z8n6Q#07t-SLfgutvxNDO3ziX9p#otQ4-$6K0m76A;KChCaekaHakvOOQg4MMp!%KX%C(4k=7o%;*$yMpcB>+ zb`#nYmI%9@A=~*BVYnY*NuVqAB@ZJkr5a(W9@tM<&wYgTLZ0*~g!O^Weys=_0KEfq z2phD5upzO84Lw3w#$m#;Dibzh7GWcI5S9xcMx7=s5Bdx05O&Q%!b-XjR*JN7lL(st z9avMd$;gj&Fq?jmup8j(P0I+o`8Z*-kUpmoVe>f3}Ndx61D;UY=AGA zN7%+V03DmA5VmVR3`EMdBoi<_ECtik8%Dn&Od?d@kxZ8 zNG0rK7Ga;ZCF~T^PMsp`v#o?-UypqOPQ#}!!B@Ec^*O?@SI53tN7%Ou3HuIw4|_jA z&yV;#2R%QnA?)W8!hY#TbOPj9qAOWMSC0{$s^AdO*%YGd!-&pT65Wm?y1Rtv{tBYU z9430DYDBM`NAxPVUiB2wtL*^DTYU}DYa|oBCemx}CVB|@FR?&-aD?c!@L6jTfX-Sw z0P7bku=doqga4I7{@p9%uw0SGN$%C3-#Ntq1vf2LQ@dANuOYg7#n#7!MYL zHDEtDPV_hxAYUB(jq3+W0CdHz09tAaCQd zL~jE5rgZ@1n}q=EHN*AhxYoQMfPc*o61_zn7!P(6y`=|`)(U!Cts(lA=>VUtbubJd zf14#lZ`%qi1UPR8nRbx5ssbnkr-^=b2|!wV*uZ{{9>0?49V{>&9430lDMU|z-Gl=~ zPizL35xtWN<`TVgELcPIE;#Q3n_bosJqfZ&tB8)h8old&qIa7_^kf_-&je?P-n}1y z-IRqy?*Z8!Nbhlw=&6uNT}-S7!C`QQ z=!0QvFmw)v+~7f=1VDE1DggU~AvYMhhExM>K|06-Gr$S}nIXpjWQJA%&^0sx3cN23cSdSO`{u z{Qzc&qbZjBf$LRpJ#t#BVh(2Ko z(I?{CMA*6(`LCS;@O@*1R34+Gllmlw;H_`skvlOK<8f4cL6lBZLP!{ueEbhPYPCaUy(*|9=Q%^DWmK~ddt?bw&tz|r=9JXcGZmrZPJ9bD8Mx4lXk5p>2sO;Fs zD71xiBn709Odv)0I{%S~a0v;KIwX_S#b*=J2>+VmXgDN7qyuD1NHHiP*(8IEA#u2x zMDiiu07vm85C1|W?N?pJ;j?Vy$wr>B_?ZPs{uivaK+cHObXXb-TchAk3zmaq!b!5kv}7>P52hVu_#dpe&^$7A!LT5B)O0a!Q%p0&j_b+LOK={PAJM9 znNt#~lUX;^q*0@$q2Uuk9db*GONz2H#>9n^@-rKR;`8!CX+o+vl$KqbT{Jd3s{#LA z))pdbddAo>qYCmzhB{>A{ELhU*`qT0l!h{MGV(`e7l$&6vO~G~p~BMPdAXUPtb#Ea zx%u$y!Xowx7qA$YBbj?;OzNt0{r|dS^kPlpK$#aBSxZ*M9XP_cGHrO zKG{XZxdr*5CJmb6?0i+f@h{@u`2ry_BCJicxDeW0q{T&xGom0Lu`NNwNx0RPpw?RB zFS9m8eMM?|ENZa<@)qE;2sN1<)>niUl#T28_*sIiB_)Ne8#c^BjK-EWC@v^1%FG^7 zP&6{TL4G!pJDul2w2ef2$M1WC=sBXLi)@3udosWbFWKxuQr zamhv7EQFn+aD=juJ_5(0#fttYTJ_lQHBm2-NdC4Q<^8J^GUfg2UzLWV|Nc?gBW)l9 z*3OUG@5dL8zlrzv{|W2A*ZH3xv;JuG3t==7iTrYOB_Ht)y0Xwh?(n`^|ui@GBE}Gs?=xks_{?!ivx$d@VtG#QPCA z%ENULr8>X*SZ*OidO>moQpO>lh?1~a9usk;5Z4P}r4&|#hf!~`!X*%Onu{2fLWf9= z#DV`>hTmHd+C>~P;aMs4Mq@G#MfMTsR(L#EO>tUt5UuG|>XZs4iNoD52;B(H1URiYQ4zxZK6zNQ{C+ zW;osvucGxg0#c&9Vw{fFkSMumiK0#-Evy(bi|C!{VM`)r!yzM9Gv#$qUQ^MS3V(h- z667PN&?{P*h(LL?qJ5=2Vxk{J+xYqUMCru(MR?BPi}2(8wibzoxFYob>-rSs6nP_c zKPLPcIX}Oz|5;s>gl8f#vx-qblt`@Z$|Ln>dBx}`R+SO|g>?~g(U+qmn($rpH_<;M zV_d{jF}jLbK3eDH?Klz#v4Ru*JQC+pXc1=|=c1*Ez92jm>s>J(MO*hs$d%8l5lhiA zRFp2_iI9&(HmWUJMv?O8Ws26em?uOD%3GKyX$b!ORSzz-^V@j*z8@8b`+}%%VL_DO z{2CU$AhJ3To{4CO!awtICdQR$oI{X`ToGlBw8%&gh>XZ0E&?%oWQR)^nX}6M85eG2 zS>dSH`h)qf7IH=+AB}D_2gjHloo#EK*UBREOERp9_7|OBM4O7tNs(Tbk5M4f52F2T zEbQc-SF)(RY%)Gv)1pM8z6$X#GJA<$FJ_tOICFlzM|_T6;lG=2A`uXCmYB!I3>Rtl z!eh~DE^PbJb|UIYNdD2-E$T$9*F;+uBX`vQKZ+_pFLLMC;ot46VrT%rs@zB@=S^E4gT%dKAMmC!6o5%H`$&eEX2 zOPSB{(47?4C;X3tU!B5wQ^L7KJ`p+LX*@{9&oo#~f`;D6CCclf!4_af`GCQK#|9(LL|Tj_L(>!vprGr zNR34Fi96);OCjp1Z@4DP>myPF!b8z6gvDsg%4=WP6h24&5v^IYvS>Y&M@95M(Z+<= zq7{fUVL|i}(Z)nAiL_|{6gEWLiHrfg!+E1xMZOE;8-k?hM^U+GzCRl~A~A~EzOV*G zYZbAKco-Q;L>wY|BW)?t6Mj1;MMn8V%xhwXEG(PXijg<6(v9BtMdtbPwM}I1Ie*c?hZO*HWGJ%+2N=~<;t%{?v^5RR{7nV&>5YRe}8{0+Gu2VQOK3AddpWI zk=0}5o=D7z5&y-CNUYBzYe2Eqi>yk-JT2~JBiFGiemUE z=6>Nt#8z~jQm!kqt`u?+Ya+rCZ-kaeG@~no-`_d$urER~dS@u^NX6>E2zthak4wT{ z<>Nd9UPNSt%tV|=?^Vv<|A~5EUI&rAncvnyv@E}mKffUUVr5v278JRc$_+~vVp*Jv2#g4)i8X7~OA*KN)+g51t;2bv>rhcbu~rf*^hlc$(G{^4wI}X# zg-vm%5s$OT9#=HBBJLd_b>Xh|e`D9_pWd_nzqB6|+1nCzcK*67+QLK)NA4g*&Ha=6 zLBj6u_k$v>;lH;ZB)o|1PW{nZynLKEe7tFB#d;3Zvj$$X~ z|JuHi*uVV!zEXLg{_pH7@juxw`0wm1MOJc=@m}LUH~&-ac*{}JuzkM^_wvwKI; z-Ti+(qx^oyC;I!&e`m)>*op2)h~M-6Q#(H5?ngY8^!Ijr#IBAQ{r{&sJ{)U-=o3Hx zDw6-y4o%7LR#xpX>O`MB;o)5wan^v4PT>c%#G`8BIk{h-j|~!I)5dQTEtSjz=efhGsNNf#mv0YEaAzx+>)Gv(h@i`Cb!Ixun>O65>NOQgi4E1P*I$? z(3osdY94;_u{b9#RBj_q*lbu(6e`ZfqnD7*g{x)7|BY!;MyN&1V30>b7dA952MtTu zz92&gff`X-l%HFigT{x9Sp}iug1As|>F`n6nI+EKW z&MRj@KH5c5XiNb*+#eM?R5GD3dqf5dHHbKMVHw9{OhBhZ_N?3yxuT(EbqS=q(8BlE-I9vSJY$Rt{5MkbV?=jQ(!)#A`^EQw-s z7zhU}BQNxa3d-_C{V3N4_ww^5gmTYo=3ER1McMfoVkv^(lvtEXB=B0I+tvz)3^kKn)?bEaqbCWirKkf@Z(|E`!%aiv%N}2X z9uvwaEJXLp7@mjbUr;vWK(h!tkM}bip&p$=@hSa7-I7ug;zEi2QqvN9_2NC!LP_0Ilams0Eh(jAa_@ws zl+K|J$d}S1J(Qf(Jt-YZ(|d%omZ?fg>?M?SPfY9B1)AeKBqb-M_mAV9lG0P46V9cD z;zOzNY3WHFdnd=Ig;IN`rS|BR2ptJfo062$DGgQukSQG( z<9K>nd_rRP__S_uAt>vCBBzDIA`Rdrbc7Q7h|ImZ#3v_*IwYm{N>59S?=ECTbULT> z=$^s!@)&{ z&WS0BY4OQ%pqI6zMLhDK#pP5~VzE&LV+>xO%Jd8%hPE1Vb zlaWCHExL0)I&S1z_z=?)dRBOPi;Ql+jsxN6_%X_hp*K8yV0gq#6d8K6#%5y#EEc1E zK@l$ygUPsDOr&C3!Rn+SGUtVgGxA^zxx|k%w$$gCaWl1>-P}PKJd=xyUlE zD7OTINhqTfQ)E%@#Ik8vtbatQ!X=6q^~2dwA6$9Q(D_Lg8iN z1#KdZ|4-IRk+(#!R^sJ;gj@Rm(po9JVE7NNm3XAX{*Ts5{2yE^aWUye)=J^({~K#1 z9$l4%*9CuLtrT8+7yrRpDf}kUUt24M>#c09bp9Jl7c7@BpX0XdpIRUbX0RTe|vSrBWujxtd1^R zXaAe4BeC4Sprib{@DcZ&f4uOCENTAQ!iWF)!spjrfInII@bJdZ`A+_o1x-ox^~(0) z%@f`LAK0D}Z@T`ycLp1V_w7bw@2(+;Jb^tPJ6__Ayh2>N@LBXff5WihxZKgX4RdjC zH@-n(PGQ5c8_WyeloStvh{sRXK_MXtniU2RBP(vDn3t|smAdy5YE z?TOfr?i7ALHwnMP=!S@O$NsZ;a-F7Ll3c8S)WWQ zCdKbMe&r80`7xlV#Xfz6NzJ-e?lfaW=WA$Nt39=B%S<3ewGZ0OQvLzUnC;gk|Vj2BzclA1yYPuL8>TK zk}i@eOBYL3q^jgB`Ch6fRhMc=HKmYriBwCvREm{qOP5KPOLe5WQa!0Y`GLGC#YtC4 z4Wx!rBdM{}L~1HElbTB{q?S@E=}M_J`H&oy+DL7scG6YS)lz#YUg{uqloF&wsgu-M z>LMkPHRK7YtJFM5m3y~vN`963fllG3H#QXi?W)KBU!4Uh&(gQUUI z5NW71Ov;dkOPNxZlr4>rMoKwSF4-cDl158;(irkF`9#W>3Zz2m8mUMsmP({jX{zlcejU$2Ya|^n|oldQw^^t(P`PPe~i4P10s*i?mgGTG}RUmv%@yrCri9(r#&w^sKa3 z+9y3HJukf=?U!DZUXosx4oI&^uS%~;2c_4gH>5YEL(*H)+tNGIVd-7zJ?VYvi1dN< zp>$L_CVeD*EPWy!mrh70rB9_((r41=(ihTc=}YM=>1*kX^o{hb^qq88`d<1$`cXP3 z{UrS?{UQ@tl4V(uRauj%%w%0QWGu<) zUG6RSk^9R1t~^hkFE5Z6%D2mR$cyB~@}2Ts^4;hXP5F@gmi)H-j(k{tSAI`^Up^v#Ab%(ym5<3E$sfy~$j9Xq@=5tq`IP*b{JH#v zd|Lie{!0E@J|ll4e=C0{pOwFte~^Ea&&fZ@Kg+);M3EF(Q503t6sj;qR}6(KreZ0! z;wY}-DZUaYF-ircqEbn@NU5w`tW;5|D%F(gN)4r^5>hTvYAKg0u}W>_GUalmj#5{t zr_@*Clq-}5N<*cQ(pYJtG*y}@&6O5POQn@^rP5kyqqJ4pDOV|1EA5qdrGwH@Nl+4% zPD*E`i;|>tRk|t3N_Qni>7k@5J(V=2my)jZR{AJ?m3~TpWq>kJ8KewWhA2aoVM+$M zR~fEkDp^XlGC~=t((uxkf2cij@+jR2i#`BX=v~l?lp3>3mGYRfT6tVqqdcLk zRi0GVDeILD%2UclWs|a5*`jP!o>sOg+m#*4PGy(!jIvwVqdcqZRrV>*DbFh}DEpNc zm6w#4l>^Ev%B#w2%0cCIO8HtjqkN-$t9+-NRlZk#P<~X-DL*McE5E2jl~h?( zR8`efsxnnq4V9~=YN@vBsIKa%z8a`8Y6Z2TT1mY~t*l04Yj5kQZG?! zsh6s;YHjs0^>Ve2T34;7)>q@yE7S&RL$#6GSZ$&b2@5^*VL3dc8VDovKb#r>is68`K-so79==&FU@ct?DdwwtAa7N1dzA zQ|GG-)P?Hp>K*DLb+LMrJQ?^l=Ok83@kKBzvVu2dgZA5kAw zSE-MwtJTNVHR==UTJ=eFow{D#pgyH;R5z)c)h+5)^=WmRx?SC&?o@ZFfAJ?gXS zUUi@Pocg@_g1TRQQGH2$Sv{b>fbiXsvc86Qa@HdQID%9)RXF`>M8Xz^>g(L^|bn>`jz^%dPe<5{Z{=>J*$4N{-FM- zo>PBPe^!6dh$d;Wrf90BX;fpHt{EEFOwH14&Cy)V(|j$^VzdfcMXi!{kycr|SgWE{ z)v9ULwHjJYEu>wd)zU82Vzt`ZW!mLh9j&fbPphxRX;)|sw1!$Et+CcbYpONVnrkhz zmRc+AO0BilMr*6J)2`C4*4k_FS_iG8mY^kSowUwc7cEKas&&(nweDJq)QtsZ9p5+Mzk?)LYvZN zv^i}-ThdnaO4^#Xp>1h9dKJBzwx{v51MNr?Xd>-IJJT*SiFT#kXfo|iQ)myGN_)~Y z+KZ;s-n0+xOZ(CObO0Sl2hqWF2pvj?(F{7AX3{L0O-Im?G>7KWQFJuTqhn}3Eue+; z8d^k)X$dW*W9c|Lo=%_>>9uqcy^c<%*V8F3%7x|Tjk*U|NK1AU5aq?_nwx`l3~Pt$F5JKaHd(p~f!x|{By&(ghg zAAOEKPhX(>>5KFw`Z7I0U!kwk*XTj|I(>t_Ne|Jt=-c!idYHaT-=pu-BlH9MAw5cu z(U0iI^b>lVo}ee`r}Py4jDAkPpr`4V^eg%`Jwv~t-_q~sS^7Qwf&NI((Vytg^cO~$ z#AK#0m1&GJ#&l*d&P--8n>oy79`jkiVps)MkyTpYwPo$tRqSfk zp2f2ctRqWciL4Xr%(}27)|GW*$*em|VLezX>&ensFP6@Fvp%dZ>&N=D0c;=}#0Ik= zY$zMXGT3mI$+B2B8^K1h9G1&QvC%A#jbZt$fEBW9SP?5`C9IT<+ewEoOJJ zyV%`q30unUVfV6S>^^osTh3On2iSw`A-0k|%pPHnvQ_LcwwgW8*03koTJ|Jc$JVnA z>?yX9ZDO0*7Pgf=&9<@aYzN!PcClyJZnlR#%l5K;>^b&4dx7m|FS3`|%j^Jqg}usN zV+Yym><#uNJH*~%Z?kvUVfHS2kG;>1un*XW>?k|NK4KrUPuOvGf}LcavQz9c_Bs24 zon~LMuh`e@4Eu(C%f4f0+4t-R_9HvTequkfU+}ePk}m6tuIidjb*AgOp>y5TE#1}~ z-PJwa*8@F9ub@}dE9n>MmGz7DDtcADnqFP6q1V(y`XzcT{Zc(vudQFEUyd(;tgF|< z*EYuKSKx~k8|sbp#(ERIsoqR)uD8%z>aFxE@r8wL^tO6C{VM%xy}cf zT+h_A^lW{EK2p!obM;aBXgyCKqvz`ddZB)eUZfZ6C3>ko7GDiFUY~$3gS%Frq+h2` z*00y6=u`D+`gDDUeuI9aev>{^zgfRUzg3^5&(?3#=je0wdHQ^Pfxb|`UB5$Lq%YR* z)bG;o)|co@^?USt^=0~f`u+NHeTDvj{-FMlzEXc!e?)&&U!^~$uht*e*XU2^YxO7f zb^3aJgZ`AhQQxF**0<e) zep3HbKc#=Bf3AO_pVq(BztX?f&*mQG&Y(TO^s$obEAdP(r9H|X|y)l7;TMq##P4E zMtdXP=wNg-5{yKnlhN7eVk8+|jc!J=(cMTfdKjrjPb1CfWuzOujXp+Sqo2{=7+?%E z1{s5mA;wT+n2})&H!_VZBik5Zj5KnLTw|0m+Q>7;82LtlQD|Ia6dA=viBW2dHO3j^ zjS0p?<62{qah);QxZapzOf{w%(~TL%4aSYeO~y>)X5$v)R%4bi+qlh`W6U+?8S{+= z#zNzE;|^nyvDmoNxXZZPSYj+S?lJB)mKpaM_Z!QN6~+U`gT_O~O5dW0SGj*kWuoo;J1_+l?K@PGgtxjIrC;V?1l@HTD_L z8P6Lp82gPEjhBpIAVNYd}tgs zju{^r9~++-$Bh%lN#j%Fl<}GIx$%W@+W6A=%J|wiV|-(LYkX&%HNH1~Fn%=789y06 z8^7RHM~TZ^;VRcS<&5jx;GCP>;x>1<%RTP%fXDC(ydtl}FXEN?#k>ly%B%6}yauny zL;Mn6i(krPd2N0fzns_Mb$LBrpU3elcmv*$H{y+X6W)|Jp2BKG~K9k?fZ{fG{S$sCXjnCn8`8+ef&B8Jb!`j=P&Y?_{;nN ze}%uwU*iY)>--J=CO^dA;&1bJ_+kDoe~-V@lm6X=E3<$*gYH zFl&-W&5(JCSJ!*={yAo0v__W@dA< zh1t?WOg>Ym`P?=vzwW0b~jVZ9%ic9 z(@ZmandxS4vya)=>}U2j2bcrRLFQm{h&j|8W@ebf%}g`P%r-}uBh4H$*BoVzHuKCe zX1-Zq7MjYOXRLGgq6Bn`_J`%(do|<~nn|xxswO+-PnxH=A3`t>)9_ zHgmhV!`x}^GM_Pbn|sV>&AsM6^EvZ*GRu6y+;6^UzGS{^9xz`qUo~Gd51Ox=Z2mw*!;viZk{ktnxC4d%+Jiv%`eQ;=9lJI z=GW#K^BeP9^E>mb`Mvpr`J;Kx{K@>;{KX=cWXYCdsg`C@i&?s5Sllu#%d#!UaxKsD zt-y-0Dp(b*O4dbIW$R+AidEIBW>vRpST(JXb%|BWy3~rbYFn3Cms@qLx>h}_z7=O( zVKuNCT8*s6RuikK)y!&cwXj-Rt*k4p)>a#Dtbx`bYp^xM8fp!*GOXcNrj=!7 zTO+KIR*scxjj~2tdDa*!-zu;Qt!u0ztJo^BO0BWhIBUE$!J24YYfZAQvnE^DTT`s5 z)--FnHN(2Wy3xAHnrYo^-D2Hp&9Y`&w^?(nxz;>uzO}$wXx(nzVJ)&2TX$M_S$A7Y z$YN`$b&qu~S!pe^?z8TV2doFJhsa&lN_^k!7uLhpBi5tVD(f+8we>i8z*=KH zVXYI+GK6Ewpd%Or>$*diM8F@VePbbSUbo(`-n0%`Z&`1Xhpcz3!`8djd)E8b5$gl%L+hw@ z%=*as*!sjeZk@1BTAx~{tk0~^tuL(8)|X_C^_BItb%rb?w_D#>-&)^UXRYt8AFLm( zbJkDR&(<$Cu_ar!6Y^j9tO5Xjif?vMbvc+g0qU zb~U@YUBj+vhwMx2TK1)OtXNW7oCo+4b!>`wF{(-Oz4iH@2JDP3>lObGwDz z(r#s6X}7l9*lq20_Eq-Pc6&SC?qGMc6YNC0lik_wVkg;M?QV9m-Q7;Hd)TRVPdm-- zWvAP{?LKy2yPw_P9$*i&2ib$|A@)#vn4Mt{w=?Z5JKG*%kF;~_Tzix~+Rn4b*!gyW zU1(op7um&jiCt=swa3}x?Fsfo`&xUFeVskozTTcM3gx&4KG+Wyl1%Kq9uV}E0R zYky~-wZFH2uz$4A*+1Do+rK!(ksR4k9M#br>M%!l42L_WV>!0tIIiP4z7sexP6el; zQ^~o=sq9?rRB@_0)tu^14X36PaxQUdIhQ)IPHpEh=W?fxQ`f2I)OX^XE1U*SL#L6` z*lFT4b(%TNofb|@rC zcPGW^;iNh}oiwMHlkW6(`Z#@^eolX9fHTk;vH>sIWwJ`om-q+omtLo=Qd}KGuN5t%y$+z3!U4YJDf$%V&_ihF6VA%iL=zX$GO*8 z=G^Dp?<{v#I1i9b&V$ZF&PwND=Mm>oXO;7qv)XywS>rt6taYAr);a5)4bD@}MrV_= z+1cW3b)I&%Ioq8b&Q52S^Nh3G+2cIx>~;1z&pFRKFF5<17oC@!mz@L7E6%IVYtBLE zb>|J|P3MsFmh-mrj&s;~*Llx*-#OxZ;C$#Db&fe7IUhTpILDn6&PnG}=aloA^SSed zbK3dR`O5j)IpcieeCvGYoOQl;esF$t&N)9hKRds;#FbpxRb188T$tA#xxO2?F>VF7qFc$m$gS*N>{fBBy4Bq3ZVk7l8*(pkYq^)Yv2JbmGWT+~j$7BQ z=hk=Q+$-D$ZbP?`+t_X5Hg%i1&D|DmOShGKrQ6zVh(4 zPHtzni<{(jb-TIAZg)4u?ct`nJ>4|7mz(bPcKf(}-F|L=cYr(49pnynhqy!CVQz*y z+|6{e+-!G*JJQW@bKOzyXgALtjr)YV)_u}l z=dO1*xKFto-A(RhcZ<8#ecIjTZg+RMJKbIGGwyD8kNd2<*WKqn=RWVg;O=){bYF5` zb`Q9(xUagexd+|X-8bAf-9zqM?%VD=?qT;`_dWN0_lWy}`=NW(J?4Joe(ZkY9(PZ; zC*4ooQ|@Q(=k6EoY4=O_EB9;njQfrIt^1vO*8Sf7!Tr%a=l@l;Rq zsK-3rGd%8@p5@t|gUM24$ud;WsSH-L9Rr9KQHN2W$$h*X=*ghU-MtjAhnMR0^wPXuUb@%Y>*MwH`g#4m0p37w zkT=*H;tlnNc^TetFVoBNvb_=BNH53B^+tK4y*zJ>m+uvLh2Aw@kyq@Mc%|N0Z=5&Y zo8V3KuJtB)*Ljn@>%A%7RBxI$-J9Xv;N9rm}J>_lmHhG)9E#6k|X>Xgi-P_^q^mcjAc)Ptl-m~6bZ=d&^ z_q_Llx8Hlwd&zs*JK(+Iz3RQ@9rRxJ-tgY^4tZ~RZ+q`}hrM^b_q_MLBi;wzhu%@| znD>$QvG<90+&kf&^gi`Yd7pWodtZ2`y)V75ysy18-Z$R2-gn+v?|bhD??>;P_mlUt z_lr+_$(Mb_SAET=KJ#_o@VRgLmT&ux@A{ta`+*-FZb*Cb^UsNeLv2>!f)U=^c(q&{U&}>znS0MZ{fG}TlrV| zt^GEBTfd!um4CJ0-jDY?_#OQOKhf{xclNvZNq$$qo1g4=_fz~HeyZQoPxE{E>3(m& zkKfnt=lAyq_yhex{$PKIKhz)QXZXYYOh3!d_DA?5{Tx5nALWns^ZYS>zF*)M`q%hH zez9NTm-=J3!++C18jKCb1>=JW!NlO&U{Y{hFgdtBm=a74rUlc38Nm&~jloU9 z%;4tWmf+T4RxmrbEtnI`4dw;&g9X9D;P&8-U{SC*xHGsbxI0)9EDi1n?hTd&_XYO{ z%Yzlc1HpsAL&3`6;oy|c zwguaR9l_3ESMW@*JJ=IE8|)4C1!7IV5!E3?6;Pv2*;LYGr z@K*44@J?_zcsF=2ct1E2d=PvX91V^I9|a!=p9IH)6T!*g)8JI_S@3!AMQ}R!GWaU^ zIye)26MP$d7n}{g4}J)K49*2V1wRMB#E=*%MvhTp)EF&>#;_PY#)#oDW{eeM$2c)= zj2Gj_1Tir&6=EvJREoJMrgF^1F;!x!##D=`{{K|>7JhPD*ZY4PdF+@%qDdh|m+P)r zTg=Qz3N~p2O(|{H_Qu|14PAQ!ZBu5(l$n_^W%_)|%*@Q}_A~uH(s}Q$lE2{h%j*?i zojV#m7o_Jo=ib#B_XPKP?)BXpxHoifnHp5vbD-pxJFy}Nr4_nz*(+)y|ub9cBq-Cgdydx5*# z-QzB}7rGa@i|$@`pS#~Z;NIU|au2$P+-3J-_Y(I~_cHeZ?gQNixtF^Sb|2zC)P0!y zaQ6}JBi%>2k9Hs9KGuDl`*`;W?i1Z7xleYV;y%@Vn)`J38SXRPXSr9n&vu{VKG%Jo z`+WBW?hD-)xi5BK;=a^keVzMy_YLkF-8Z>!cHiQ@)qR`$ zcK03E`0zD8;=a>;m-}w_J??wm_qkWP?{`1oe$f4p`(gJZ?nm8^xgU2w;eOKnANPOV zPr09VKjVJZ{ha%G_Y3Y9-7mRccE93&)%}|Lb@v|8f7%ox1<^uHjwNJHm6kb>6^R?``mo^fr2%yv^PgZ>x8dceHnmcdU1u=X##! zdw~~vL+^O+THdw2>v-4oPVlbhUEjNbcSG++-i^I&-c7uldN=cK?%l$>rFSdu*4}pS zHr|XEd9jyxsh4@VS9qm2>)qD7op*ch4&EKTJ9#I1BX8_YyvnP+#yiP7**nEM)jQ2Q z-Mh1QhIgiS7w@j#S>D;+Io`S6-MsU>yLG(Mp?8tD=X(|ecqZtp$bd%gF0S9q!z+dlg@Q?I2`kVaC{uY0$f0Tc;e~f>uf1L07p6~mC zANoW8c>h}dwf*b(*Y!{EujgOizkz>4|3?0e{cZkD{G0kW^Kb6o!oQ_|EC1I1cK2pZKYt`MF>Cr9bQ6*1w&9d;bpp9sN7`C;B6Q>`(m4ul>e9$v@dY#Xr?Q%|G40 zvwwzvrhgazuKrp6+5S2Hx&Gb!^ZdK}_weuO-^;(Zf4+Yo|GxhH{5gMzzti94&-)kn zyZt@>f`6fZk-zBg_4oPv{R95}{U!gPf5>0cb|G5%xy$N7)xulL{JztMk_|7QO!{#*UG z`EU2%;lI;=m;Y}6J^p+B_xV@)@Ap68f6)Js|6%_l{zv_f`5*T`;eXQqAOC;-Px+tr zKjVMa|D6AM{|o*X{V(}n_P^qP)&H9Rb^jawH~nw<-}b-bf7kz>|9$@l{tx{h`9Jo5 z;{VkDng4VD7yd8(U-`fGf8+nw|DFGP{}28j{XhAC_W$Dl)&HCScmE&$KmC9Chy8#1 z|MCCNpZfm|t`S@_I3jR@b-^H5A8ZJY3^oRvg3ZB}U~6zxaCC4?aBOf~;09jc2SE@9 z!{GSfTEVr0>jc*gP6)0STtB!$aKqq6!Ht7$!A*jj1~&_C9^4|hWpJzD*1`7RHo;5~ z1#yrBX^;hZPy}T#8{9UyU2yy04#6FRI|U~OqhK6Nf-0zkCO9cLIXERaH8?FeJ-Bml zMsQ|um*B3!S;5)CIl;NX-GcLiy9f6O?it)GxOZ@VaG&75!To}{U`Mbs*cHqN7X-V5 zJ;6e7VQ^8f80-!91^a^o!Tp1!;9zhlSPm`@E(tCTE(;zIJTQ1raCz|H;32_7gNFqV z4;~RbGI&(*=-@HIV}r*9j}M*@JTZ7u@Z{hr!Bc~$1y2v25j-<^R&Yh|?BF@UbA#sv z&ktS@yfAoC@Z#Vl!Apae1uqX?5xg>ZRq*QIHNk6x*9ET+-VnSocvJA^;4Q&hgSQ25 z58e^HGk90m_+Ie+;0M7EgC7My4t^5+ zH27KY^WYc3FN0qNzYcyA{5JSq@cZBo!5@P^1%D3y68tszTk!YbAHhF^e+7qwe+T~w z{x6sY{|&DZUNbx*bi#GvAY31A2#*XmhMU68;g)b~cvN_FcuaU~cwFd)Ug(EG7>2{} z`0!fcwZrR#*9}hyuNPiFyg_)w@J8W{!)@VB!kdOS3vV9YBD`gItMJz0_V700Oc;f6 zn1pGVg?U(nWjGt&HoRSU`|u9o9m6|?Cx)YN98SV2tivWeDLgqmB|J4eEj&HEb9hF0 zW_XwIuHjkX+2J|ix#8Wy^TNA__XzJ9-YdL!cz$@F@V?>w!ntrqxHH@p&W9I-yTd)< zLU>_#QMefH4flon!vo>{!=>5H$51$b}GkjKfMfmLSIpK4|=Y`J? zUl6`9d{Ow~@Fn3(!hLw;Ys1%tuMgi4zA=1L_~!5};akJEg>Mhv z5xz5gSNQJmJ>h%9_k~x6?+-r^elYw{_~Gy);YY)dg&z+;5q>iKpYVUfPlcZjKNEg7 z{9O3?@C)G=!!Lzj4!;t9HT+um_3#_vH^Xm*-wwYMemDGH`2Fw);Sa+fg+C5|68<#& zS@`qt7vV3%UxmL8e-r*T{9X9_@DJf1!#{<84*wGVHT+xn_wXO#Kf`~8hr@q|{|Wyu zoQD4$USoL8;Sob;xNbNYt{-j~9y#1N+%()g+%nucJZgCK@R;GT!{dhT&>Q;0U>FXE z!{dk78eV&No#AzdCk(GQy#DY8!y687G`#U}+wdmCn+|U_y!r4J!&?q-HN5q3`|viy znPD`HhsiJ_a2@kfTncufzw0Caj(*AuL=B!*l+Mzen=GV`4 z#fH)T-FiXmq78FaZl3I1SkjxF7c9F%IMJoudfYozAHA>tKZ%7>;Q zY}&ngxaB0JBG@};joq@lXKX%s?Yo=ztR1gAdB@z+x;^@5{V9hQ7I)3BSMCKB8&07o z3-sg^>&b!*-6^zr!O9~}IrWHz3pby-cHPYvt{rbVt=Et(7hT2JtrRBv7WHQA!p`-l z&+SxxkoAjQvE}ssd5b+`{pmJ9i(RqqboGASqW)QbhJAmZegBN!SGMfy8SBrm@9(n# z-Zyt(zjBl8*A3&;`*u6?`*v?Qlg{hM)VgUr(>lMuE4H4wM|oxDmX`M}>Q(Hm`}@}V zv#bqDcA>6pIjaY|WvOSZKg-&%WX0L`t%F^$`Rui!+k9~Cc*{Ax3v4;mGuEGDmpRlG z>&|JX^iVsc=h~Dm+mxP5ua@c6xz?-Yt{9xVq&LwA%k95g&+YeV>vG@Pa4u87Y~|+j z)>^pvlHTz>ddHWo9k0Kq_4NT=vFVo;Ld_O z+YHXs>;3vG*!Ev*!-zhQz#f4;0(%7Z2<#EqBd|wckH8**Jpy}F56;JqCLW_89Cj*kiEA^n1*BPZ;kB_!ICa;7`DxfIk6$0{#U23HTH6 zC*V)OpMXCBe*%65eg%F7eg%F7eg%F7eg%F7eg%F7eg%F7eg%F7eg%FFehq#Nehq#N zex0p9$)5V%U14`h4SEfF4SEfF4SEfF4SEfF19}5`19}5`1A0U68+zZ+`v&}GRv9A1 zB=(TctsZU|)m_zwx%sZ#eCEN$IlWxkvgPLeYsX!0^mCe&)|z<6S`*J$YvLJeO*~_* ziD#@e@r<=5p0U=%Gd3FWjEzP-W1|tz*l5HvHX8AajYd3UqY+2oN8m@`N8m@`N8m@` zN5z)2d-S~JV9&4~MYJTMB@r!&Xh}p%B3csDl9-mnv?Qh_F)fK{NlZ&(Mj~b;Vn!kc zKL$SrKL$SrKL$SmKLI}hKLI}hKLJ0jL(13&nBs3tQ z0VxegX+TN?QW}ubfRqNL3_!{Nq~NFEr{JgHr{JgHr{JgHXW(bxXW(bxXW(bxXW(bx zXW(bxXW(bxXW(bxXW(bx=iuky=iuky=iuky=iuky=iuky=iuky=iuky=iuky7vLA* z7vLA*7vLA*7vLA*7vLA*7vLA*7vLA*7vLA*;|9bf_$Bxy_$Bxy_$Bxy_$Bxy_$Bxy z_$Bxy_$Bxy__zTvZa_Q>KJGw_I}qaz#JB@7?m&z?5aSNSxC1fnK#V&O;||2Q1Mw{Q zBgTJ3|8WUoT!I*vAjTz#aS38vf*6+|#wCbx31VD=7?&W%C5T7#e+2#*eB6QUfZLNi<6mn zV;2zgYV7Gr5Yhx8O%T##rrf$mKM~!fF6@2Fo}mOeO_0+BIZcq$1UXHR(*!w9kkbS? zO_0+BIZcq$B(gC`B726D$e!T@5ls-$1QAUT(F74q5YYq?O%Tx}j<-mpy6mHCokB?y zlr%v}6O=STNfVSbK}i#oG(kxdlr%v}6O=STNfVSbK}i#oG(kxdlr%}~Mo1C{0U=Eg z(gYz*5Yhx8O%T!qAx#j{1R+fj(gYz*5Yhx8O%T!qAx#j{1R+fj(gYz*5Yhx8O%T!q zAx#j{1OZJD&;$WZ5XuChOc2NfVN4Ll1Yt}N#spzZ5XJ;yOc1OD!AcOU1i?xWtOUVI z5Ud2jN)V_7fl3gl1c6ErsHA8HhxYH=e{k!r1*OP5s5GaowQ00?K0=vWUch3-RGxhb*Vera^~KJcDccfb9*OmI&<&*ZaeAN1)Y8stU-sh zZajZzZgA3^mVfLimm-0;?wH71dlsCD{=dt?g)QxMR$6j2C#=|;=2iz_ z%Y3gVN2&qV?Y1A?k+*E0uY9$u9CY7bw?n57cDJ1x?3!OZG`E3kt$TnzaM}-*Fil-* zFE+TS>(XM^B^!hB*%XBa|_qB+2X^_*wlTwJG5pXDoHi7zH4rD*C;+GC;+GC;+GvK&I$pN&uOnlPNlxqLV2)nWB>^ zI+>!ADFI|k0GSd%rUZ~F0c1)5nG!&z1du5KWJ&;;5K&I$(iaw|4bBaEv=yOT{nG!&z1du5KWJ&;;5 zK&AwcDFI|k0GSd%rUZ~F0c1)5nG!&z1du5KWJ&;;5K&AwcDFI|k z0GSd%rUZ~F0c1)5nG!&z1du5KWJ&;;5K&AwcDFI|k0GSd%rUZ~F z0c1)5nG!&z1du5KWJ&;;5K&AwcDFI|k0GSd%rUZ~F0c1)5nG!&z z1du5KWJ&;;5TdSe@Z}^5>TcDlquSu z5>TcDlqmsaNxSpQ8UM`k$izDf*wH|0(*PqW>xSpQ8UM`k$izDf*wH z|0(*PqW>xSpQ8UM`k$izDf*wH|0(*PqW>xSpQ8UM`k$izDf*wH|0(*PqW>xSpQ8UM z`k$izDf*wG{~7w9q5m2BpP~O5`k$fy8Ty~0{~7w9q5m2BpP~O5`k$fy8Ty~0{~7w9 zq5m2BpP~O5`k$fy8Ty~0{~7w9q5m2BpP~O5`k$fy8Ty~0{~7w9q5m2BpP~O5`k$fG z89JSz(-}IQq0<>UouShiI-Q}@89JSz(-}IQq0<>UouShiI-Q}@89JSz(-}IQq0<>U zouShiI-Q}@89JSz(-}IQq0<>UouShiI-Q}@89JSz(-}IQq0<>UouSJax}2fQ8M>UI z%Ne?yq01S1oT0}VdYqxh8G4+d#~FH@p~o3|oT0}VdYqxh8G4+d#~FH@p~o3|oT0}V zdYqxh8G4+d#~FH@p~o3|oT0}VdYqxh8G4+d#~FH@p~o3|oT0}VdYqxh8G4+d#~FH@ zp~D$EoS`on`jVk98Tyi;FB$rhp)VQwlA$jd`jVk98Tyi;FB$rhp)VQwlA$jd`jVk9 z8Tyi;CmDK@p$8dykf8?|dXS+98G4YR2N`;hp$8dykf8?|dXS+98G4YR2N`;hp$8dy zkf8?|dXS+98G4YR2N`;hp$8dykf8?|JfFey89blC^BFv!!>>8~n!~F(yqd$OIeeJI zb2)sL!(%x-mcwH?JeI>_IdM!*9Fr5rOimn=6UXH6V-7#& z@M8`?=I~<PMnYvC*;HlIdMWxoRAYIPMnYvC*;HlIdMWxoRAYI4v**Xcn*)}@OTc7=kRzAkLU1s4v**Xcn*)}@OTc7=kRzAkLU1s z4o~OsbdKMjeBGk z1-eq8D+O^&LEKW%{(|-ww7(#3DTrGN`cu%Kg1DuiUj=bXLH`PLsz9d-bgDq73i@B5 zQw2Izpi>1pRiIM^I#r-k1v*urQw2Izpi>1pRiIM^I#r-k1v*urQw2Iz5T6vpCk63I zL3~mWpA^hn!MqjBTfw{)%v-^{70gqyGEc-KHGXUjf7I|t4R6%&L=8{W@IwtB)I8rc z&v(u9UGsd`Jl8ePb|&2wGzJl8zWHP3U+b6oTM);zB@&uh(dTJxON zJf}6!Y0Yz5^PJW^r!~)M&2w7woYp+2HP30yb6WF!);ymz&u7j3UvvN0-2XNAf6e`0 zbKlq8?=|;(&HY|;zt`OFHTQeX{atf^*WBMV_jk?xU2}ie+}}0#cg_7>bAQ*|&$Zpp z(Twq_%5L3RW%q{zD!V^iP}yz0s_Zs?Rd)M*D!X-mmEESN%5L3TWw-9FvRn67*{yr4 z?AE%ZT@7_f8(!c#^ysM?X~%kO?z!VWYb=o581TW=0i5^HNKHedu@JX(_Z5n*|gXA zCYmw6QAvA^Z)DS6;~Uw`m+_5k=F9wI+02*mkZk75ct|$$Wjqwk7!RqW|HebI>A&%i zZ2E8dA)EdiFUh9=#!Is4zpax*?1QMZ{;>}t+xo{oh-~X0`yjIIy6k_*w(GM0A=}24 z{SVnTuIztA?0={P*VaE|gKPf2Y;bM;L$-}8`yaAxT-pDS4X&+w$OhNeJtFo!RDx^q zf^2XtUXTs0#S5~*wRk}`xE3$Sw)te=L$=K)`yLVd9x81<+4qob^U1!4Y@1K^J7j}v zae{1cZ5>56xVDZW8(h<$i2V+g;95K(8(fPgWP@w*glxNy*zb_dd|Nyr8(fPcWP@vQ zM8rOaN^mWXkj*$-{2-fgwm3pI{k3%z+4R@eQDlQ_>nO6pwRMz;{SB4iTKplK{#yJY zoBmq-A)EeM{2`nETKplK``h9V+1zIqf5_%Ov-l%oe?ukrnXRYDrvJ8{BAfo(dWvlN zZ*hxk`fqWIZ2E6;i){LDaZAMhhD!Qxeur%OZ~ljD`fqWIZ2E8hh-~_Aeu-@QZ*hxk z`fqWIZ2E6;OT_+$O8Reci){LDevNGUZ+?wz`fvV?Z2E8hjcodF{*7$#Qug#@X=ZJH&hQkI?Mis>cK~6 z+22q-_~$B%U1dKbVn0JA^Np^upP_oj+u{P*jJNqovcWSyNjBqcev)j)+v0+V z{S1}#7oBE5L-q6*on}8n_4F5=Wvy^y__lr*Www5&5`0^~lg;?q`kidX&(`l`Gk)kY`x~mK|L8LN8>+Yami>*0eGQf1 zqQ~rOsGfeK$LwpU9$Z`BlWqLWzJ_eOZ`jw64KBLOzDC5phDzq!*7anAi!QUDp?Yx9 zW%f5zPk+&6_BT`yF1pPAMwHpQpi26UF0;>}dhpR@_Bm7!KDx|4hw8ycPuZV{*q>0z z_s~=JCse=kJ;n`z4OPpD+v&{Os&RL^~aUS{ZJhF)gqWrkj6=w*gp zX12~3W$0ywUS{ZJhF)gqWkx)ip>r8Jml029=v;=*WyF&iI+vky8S!L>&SmIaMm(9J za~V395l^y@5V3C%u@0@$#+`N9h;`YBby<}*|2ck9j$g!jtvXj+%n$3Zst2F>VI5ZW zj064*>#(W^AAg2**r>97X_bak5sy{yc||-{!RHn6SOuR~wlA&k8!uG0e(WbTvnk26*^E6msRk71@Bkzeg*GW@O}mFSMYuX?^p1C1>aZjeFfiF@O=f}SMYrW z-&gQ`1>aZ1VHJE|!S@w$SOwo##9Aufyk8NARXk4>ykEil z6>(Sv?^ncQ6}(@;`xWt6W&1i&MLbr){}udS!T%NfUlEs8@P7sWSHxu%{9nQU6}(@; z`xWt61@Bkzeg*GW#A6k_U%~qo@mK}#SMYvCJXXQ`75rYo?-lV;MO;+D#}&_6Mchyk zH&nz86>&oapH}c`1)o;%X$7BF@M#5~R`6*BpH}c`1)o;%X$7BF@M#5~R`6-X`dmfa zP!Ts&tj|@%4Ha=i#rj-D+)xoWRIJZc#0?d3L&f@BMch!aK3B0mR}m*vtiM&n2^Dcd zMVwF(C)Ds&4PVvpRSjR&@Kp_8)$mmfU)Atc4PVvpRSjR&@Kp_8)$mmfU)Atc4PVvp zRSjR&@Kwz^QVnm_@Kz0P)$mpgZ`JTt4R6)(Rt;~}@Kz0P)$mpgZ`JTtjsIHXzt-?r z4Ug6ESPhTW@K_Cx)$mvikJa#4jsIH1XEl6Q!)G;oR>NmCd{)C}HGEdXXEl6Q!)G;o zR>NmCd{)C}>}y0dd{)C}HGEdXXEl6Q!)G;oR>NmCd{)C}HGEdXXEl6Q!)G;oR>NmC zd{)C}HGEdXXEl6Q!)G;oR>NmCd{)C}HGEdXXEp0gHM~~CYc;%9!)rCXR>NyGyjH_& zHM~~CYc;%9!)rCXR>NyG>r6H4Of~CFHS0_@>r6H4Of~*gjXzc6Pu2LvHU3nMKUKq< zHN07~&Q#+U*YIeKUtGhdHGXkjH0#gn-Y8pti52H{ZSIS&iS!{#nHSnM(5u**}vF zKI=^Eqp2Qz^n!gf)q{^-)aV8KX%YKrDlLAj(F^v~R1ZFSQKJ_%dcl61&I2F4VBbyk z;G-ApyG87~sWg9$eK*!Drp6X5Fb~-HH9Wi2XX1;Ilu(ex2&UXMc$O zI@L4(><`tfJJqZ^v45xY%wMiqcdFSRs@Wf^S$C>gcdFSRs#$lcS$C@0AF5e*s#$lc z*&nJ|cdFSRs#$-k*&nJ|f2vu3s@Wf^n`r$#>_NP&E9_}wcc^Cdsb=-5W_PG&^{Hm{ zsb+VmX7#B--5b=sLERhFy+Pd@)V)F78`Ql)-5b=sLERhFy+Pd@)V)F78`Ql)-5b=s zLERhFy+Pd@)V)E?8`Qi(%^TFbLCqV~yg|Ji)Vo2w8`Qf&y&KfKLA@K)yFtAh)Vo2w z8`Qf&y&KfKLA@K)yFtAh)Vo2w8`Qf&y&KfKLA@K)yFtAh)Vo2w8`Qf&y&KfKLA@KI zkp}f{Q11ryZcy(A^=?q_2DNTb>jt%MQ0oS@Zcyt6b#74S26b*w=LU6dQ0E49Zcyh2 zRc=t@1{H2l-v;$DYS`6jSOsZVg=$y@X^46n z)V5()r$KES)V5(2q(N;P)V5)jszGfV)V4uw8`QQzZ5!0KVHKod6{JCJ8&*LY)V4uw z8&*LY)V4uw8=|uYwQW$_2DNR7&Kjb#2DNQa+lJ_@L2VnU(_1{G~k(FPT5P|*ezZBWq$6>U(_1{G~k(FPT5P|*ez zZBWsMU7Lnon+Dx%(8~tBY|zUFy=>6SW<@XAt!db;X>7MfiHo{)87jL~J(Zo8qO$W6 zRd!yQ%Fats*?DOyJ1YB>VOH|o;Nh&)pMP=uusq9wu;u+IXmC>dP z7IrT$&F@l{rPf7I6_8QBb$Q>e`6VSM(#Ja%x88qQ@2R)>5tk0m@8Vo87biz4Q=*b3 zC|BS7oW69_p-cAnOgq~|Qdyd4yosc28gC*go5q_+%BJxqlFIHBt>3$_uT2GbQ28tN z(H4_NeMhQFbrzOdMr1ewkeN7>+; zC@QNM<7c8MoAEPIl+FB^D9UF3OcZ4^e!^9OYn)%46{PgfeP+ohC>>+0pD{hYzQVS=YKxHnAjlp&42nc&H$ zZzg!M0XCtNOq5NHH} zMi6KOfkqIh{vNUGxBlLc(%PrLzr(ivN72lYr(Cc!chRBcCHuf4kT|jkM5WzS5i}av z`l9NK&6mt81&C6K&K*3+cWqE2i%N9P_{g)adhu$@0VNIDxwLTL(1P;Rwges7N@E;Z ztfJC}F0vR!HZ8CiMYi465%e2DzY+8sLBA378$rKOTy2~`cu4tO4?*`41RPnE5=R!L zsI&(wvM5D%s`MQ52TV{Rh&Y0XBZxS%7)58>V-;D9BAY3ImLq66f|m6sgEkJ(vi_tF z+ipSq$r-lYg8CCIY`dlOCrQ|hKD4Yq<*<6_SAUv-9Us{~V0#vpc5Rfbbq7o!46I#e zP6Yx6)~+q}qm8=6{KD=%hxTkav`0B@?fBs43l=V3Io@(m+PaSq_#Ss1j2ywp5sVzc z$l6`C^DV52wY!QL@h zOdi4H5lkMzH49>L@hOiq&5ID*L|m^^~XBbYpb$)j?1jx179$z5xaifo3^A{E(8;i%X`2X^h-ad6(|72b|4T+zv}mxU{`VK3M_g1sZy zJA%C<*gJx~qj7qal7%iU%#(~&R?lj0kyWF;OKkXU?J$lIs|c}*EZR{$kC{a~vY8%4EV8Ia^|Z^Po;b3o zMX8k;MLn{?x2Q)pw}(YNvY8iKJB%ay+j5o6i$y`Q znHO6y|^SJ?y4P4$F}Tmv@S8=T<5Vn_R9jxm;s% zxT>@rahz{j+`oHa=Ukird?SbZm$oeIQ+pKpv>*cw z9F9SZaL2?=F>zCjY{$rUjBLlqcAO*|m3C@r{sIMh)-qzK80n6Y?ilHgk?t7jjwRg( z7xpeJ&MonMyTM|lJ4U)=q&r5sW28GKqKeaWqXN3!OUtYCh+R56Mkqv$a)Rg9v?D0)mx6%$j%#8fdcRZL73XU*pM z`!6qCEPrU=nb#<{UEG8n0ZMiaziOk5-D%%Jy zCNfi&)=h0Ddik!4%jV)KQR`7wwRd^((87Vm%d9211LSMfm5l1h*D4#j!5tu9tLlwv zW88rlcOb?cAYW^&e63s6@dNYi4<9VAK36yeWNp=1j0gSzSzA>PAK?#>wN>>-xH0}f zj6V?L50JGrCTpuoBYd*9$~M9$YpZPVaRkWPs(SEo1jyQ|dhl@s$l5C6f)Q~9$l9v< zbc0rr)_503AjT0Oi>uBv!6S>SZ18ae$l|Jc@NGF$L}{S}SzKjvKiG1nZ2FJjlf_l_ zCb%(zA0zlNf*&LJF@hf>_+)+6_qhuYe6qfZu)#<0$@;2#6Z{y#j}iPB!6)mh&f_jb z@W}$JdiWT@j}iPB!H*IA7{Mn?tb~L9Blt0buk5k*6d?F9f*&LJF@hf>_%VVXBlxlX zvAP7w#y^>f27C4|&-F;-8m2G!lLJXg<2ui+LeQwVn`DSI?>?_~w zRxM+qr(&V5FJzsSIC53Aovg8{w=pDZtn6k}E5!0d77ra*J>0?7&~nnmN@{64K{#n* zRd07HX<;R_=7x}dRJP4L=|*MK3f8C+){+v!kObaI;GKjpB!PDlcqf5(5_l&e3`qz> z62g!K#z}0$M1s%gz&HsJNCM*|Fit`QlE63#PhP^4M_Nfa2=tFTnb+^+7}z-Q+E&bK zTPp1d;k7Nw;QXUqi5|BGZ#jXxbBW&#yGWHnHWBSfBKYMSFr4=~qvn39KRM z9gFq^rK(&#fi|#!q?at(6UyERw88#LO;AQWyk#LT$cUG0PqMov%&uJkUzFD@bONKm zA`-7zsNR@IuUWJ$$a@!{1vsM_&M5C$$p4}RIHP*cqP;+|b^&}*5=rR`v;bd}7cEpz z3zDt{dJkr0kXT3JO$(jK7~qWZ#)UjUrU7S^H!f7qEZ~ar#)azb*5Zu|*)#x`ls7I^ z&j{d>>WvHaQ15-}KOM*?wgbI+!$Efk=%b{YhxVM6ns(jOzSZ?lA9ZDW9VHO7kCJZs z+i$HNbfekUbn~JEWku%Xm5-GF(`urX>vR=e3s;(|9F2C4UMA#Vr9FDBlbV$)cin2g zt~XokBTYHy^zLAMSkh0)?PhZDVM#wFH=N0VA4xx@dL{=Sme)H}&*b34@_L8rjc-Xm zC7a2?hwai&9oVtBf9FNU3amKsdWXV*WP{dWdY^;O-ht9j4f>z*eB!6JFMljv(El8C z{M7d4kEKKQ`Qjn{?8&bALHF;5T^Cu|E&%iDhf1(ns>)cZ%J5AymZ~y*(+rKs(1;9; z$k2#vw%K^Wf>uU$?bv_m`jd6jtqe9I!8;_1eT;N@heWoKF7J@YX7ER|>rd92T$*%6 z*6ua7mtRuoYNLxv@Dho>$n4{nw#m8S=)d((e09 z;K?uTY!>-Q)}`~!Gay-)f;mJ2zm#NMs!#0uix*gXSfC<#mp+G^SfI)#v+FH*;B<3H zGS;QCN!<+$%jTr~QV0np;*FB>OZ5yp-Y6-*R9|dd*mv=cWsU8j_NWhuM@rf+ol6t& zNO@gH^^80oDX;G+jODq*BPH#Z>a$G>=Jpw=^$w?$%wIZ%n;)k%!zs;Jh01VBGn~>4 zr<4p~ikuk+oKiA`sh(lLDa~+7Gn~>4r!>PU&2UOHoYD-ZG{Y&)a7r_rQW03!pPa3w zoUNrCw=~Bs&2bROR3>h<$Y0Ar0ursMp6=rokZ3I?(V9xT{YkVY8+=x(NVKMUhM$$HoRzAal`0aj z={$y?m8zVTs+^UoJZlCA4@hzB=4Yo#Y1-E9TwLBkWjfe1KPNKXwJ@hm=Uvp&aa?U> zXxqGZ`Cz+j*)GZ+)jMAKiwlyqY2k}8UQ9n4)q{`vljKbcaNwifMdLBVM0A4OsJyU@Pz{`cIr~h~Wyj-YyaET5{?xqDt za1nlzyQv;rqC=9qsUBQ}pX6?;2bbuO$Fd zP$Fd>^Brpc>$FdPO1r%OD;RV560fiU*tyTer7wj_>P#C8RLB2e%r0tNhCz~2R-T|sD9u+LBs+7*O$1sq-w+7*O$1sq<$;RU-51sq<$ z;RW1Xu)9#OyHLQ{1-lCc++4uP1)N;4dr-j11)N;K$pxHTz`_Nq9tArF1*;wf`~3y0 z9tArH1yo$HgHW)8P_Tngu!B&*zXkkT5PcQ!Zvp=nL|+B`Tfn~s(N_Wg7VvKY{}x1F z1^ipUzXdx81^ipUzXdx81^ipUzXkjK1^ipUzXkjK1^ipUzXgA}RlvUm@mB%=7VvMu zK0yKh7VHxg>=P95Zvp=n>=P95ZvoF1L|O$rTfnmgkyb&ZRlv6ed|R*@SHQOgd|R*@ zSHQOgd|MD`74U5V-xjRK74U5V-xjRK74U5V-xkDK1w32ucK`)ETfnmg@l^rO7VvCA zd{waSU+@P21?&C=>;46Q08kKLk%UqkNXFYFZ`20TifuYluo_qpLKK7$Bx}@0lkq#r z7-gG_N-{>-rc)$il+E=C5lGIcdei5E5TPJMCLWF`4p&&%i@<-?Tl;}r^ew64( ziGGxX2qijFq9Y|bQlcXzAwo%rP@*d(x>BMmCAw0gDBMmCAw0g zDBMmCAw0gDBMmCAv})B9!P$iN2KRONqXe z=u3&dl;}%|zLe-oiN2KRONqXe=u3&dl;}%|zLe-oiN2KRONqXe=u3&dl;}%|zLe-o ziN2KRONqXe=u3&dl;}%|zLe-oiN2KROUZ6_iO!V72qk(`qBkXaQ=&H|F@ly{?EYjo zyF`adVuTVsD$%17Ju1qY^zT`3vEazeg+4rxJZC(Wer9D$%DBeJatX5`8Ms zrxJZC(Wer9D$%DBeJatX5`8MsrxJZC(Wer9D$%DBeJatX5`8MsrxJZC(Wer9D$%DB zeJatX5`8MsrxJZC(Wer9D$%DBeJatX5`8MsrxJZC(Wer9D$%DBeJatX5`8MsrxJZC z(Wer9Dv1wDRtQVtgA&~;(XA5QD$%VH-73+o65T4%trFcT(XA5QD$%VH-73+o65T4% ztrFcT(XA5QD$%VH-73+o65T4%t&%vQM88V(t3*2 zSt2aa|B^pcE7AXwCBhQ@FVX*!CBhQ@FVX)J{V&n~68$gH{}TP5MbBr^^I7zJ7X6+@ zA7;^qS$JU|na^3~bC&s>Wt?Vd_blxm;g^i?OGfx5Bm9XG z{=^7>VuU|2!k-x7PmJ&=Dr+rUyivi$K01= z?#nUv2ra#vLpZkGiWU4p6x8i;vDVgfQ=YAk5nd)tQlB8s^ZEJ+2WU_62 zl%!<(^DvA1NJ=K#;!cv1$p)XehvZ`VQE=KzoI-Lj)pI^^3dzM(PkV_|NG_&&+Dn{5 zaxv92Uc@OR7t^1w(Oz_jcQuEBDt9A!6!~3xtQv?Ux-skE~a|si#UZOW2)zV;W;JAnErf^`QkYx z$(ZW7UwOVr0;NC8v+Iz=Nq?Sa?IwwnZ2KNbn3R*Y>#xdgzEyU3D!cEg?B-i#_dS(e ze^qw#t+E?$m0f>TcH^zGdp=Zl{Z-kGx61DRRN1vtxp2WZKSDP6=10f|-~0&K;G174 z8+`K%WrJ^ip=|KYFO&_w`GxvTLGaBllnuW5g|fjnzfd;#<`>Ea-~2+^;G4fA8+`K% zWrJ^ip>qF%Z+@X{@Xarj4Zit>vcWgMP&W9cgR;Rl|4KIa<`>Ea-~7T6Nsm=_^RKeQ zSJ}tVN9?t#wDICctYq8xu(vAP#)luR8u6o5 zDy={KXq9a6Oy^}=fB4ZV+14L^v`RMZF`buf{b9dw#D1Yl&NDxC#QvX3+G&2KY@0Xs zsYdKmsWjZebXK-qk9{lIhReRyhw&UuUfFMw z&G?zl%BDZI9w?jsn9jTkIL1f+0~t)uY+%(K@}YwzpmWRkE&54pny3qOzNImEE)`*^_Ll*^r-BnO=WjmtL&ynWk)kAyT?XlH$5u5$3{t} zz&Dza4ZhKgZ19a{WP@++yln6-yps*S(U5HLjfP}{Z#1OjR^VIsCmVco^JIf>Zk}xL zjgDl~Z=)mG^xL*CWYcfkzK~77ZTmuh18nocZ@$Q8UW~3}Gww!LvKe;^3uJ?DbR`>n zqbu3q8(ql;-{?xoybM1#cT~xYY&;0>Wn2FV?`2#63BQ%}h|ifH!f(}EJI9Rsm~kiU zR+1!e7UR?G2=gG{KqC2 zO4yUWrJ_ald{1#w^26uwmc~t zd|RHB4ZbZ;Drp(`Ci}9%H`$lX^=w;5HrKOl9VIv8d9$!cHqX0-MY4G=EG&}Eb75hT zY@Q1Xi)7P23x||6js9D>Bb)wPxFehXTezd-YP8S73)x)H!V4uOv;LCXTDJ9<+}5%U zkKER>4UgQ`vJH>i*0ODU$Zaj#@X2j0+wjS4tt4pR!<#HisNTkr+`meKX1q@BU)d|4 z(>|U9a{lUb+QoA~&R^Br_>%Kiw($-*e`Oo*)I10LrlpdvF)lm@{I;d)ZGOr5E8FIm zoWHVde#!YO8+@Jva{j8Gap5^2=dY5z(Qlpua{j8Ge)AlV^H=rY^BnNonW|@Acn?Ip~TlSI-zAbyn2H%#wWP@+ZUb4ZrWiQ#_+p?FE`GIfCF0#RgUZdY()8g`B^t z2OoYR=dbD+e_M8u&HV?@kn>kb1i`mu7un#$L*)EbJ^1htIe%3TzAd}RrvJ9=BAfo( zvWsl`Z_6%9UI@M|yT}ILmR)2s{>?X{c(H~D$#&R~?NFti*KnS) z9j;$iCa#$oD5r`D+()0D`u@2SuwU^Vg(4bSxr|&h8G!LWO$L`MTQp{ zUSxQY;YEfQ8D3;~k>N##7a3k;c(DP+1{51m+yZIEzx_-_`$@!LUu<}>^)EKO*!mY6UTpn~4KKF-#fBGK z|6;?74KK0&Dd%I`+r;{p7+zv{iQy%Nml$4Rc!}X9hL;##Vt9$+C5ESWKU##;@KVD| z4Nq^db)OktYIv#PrG}RpUTS!$;iZO`8eVF6so|xDml6*H?t(3`HEWnIzxt!8zXZePZ0zn6BG)~|?})iqbY6=s%Q%$l27bM@A0 z_n9?UzY=DaUCi2gF}#W4>21Zfe-p!-7~aJ2CWfas7Q0gnuQI&K@G8Tr zIz0WZdwZsS*4>Kkn)*?9v$|{QC*95JuBjh%@2tAJrhd-dtnQlnF?X}NJ`{D=2mR5o zRd#*QpA4I2c(vixEuQ4Ly{3xxnkw3Bs%WpNqP>`k_F^j9i>YWYrlP%=iuPhExLDhG zS#9H0w2fEMHeUK~Kph#&GN6u(Wwni0VR#)G%QC!KN5--YuOnkwhS!m?EW_(q zSU)jfKpp+cvTJrsE6W<+F|90Xe8;r1tnnSw%2~0-cT6kGuGvwnENgW~v9b)Iqaaz< z&hAN-Yh&N*9#L6#X7^Cavi@}sr7UYpZXL_5ExC29u(lL7V})I_un{b*ErrckVF-m? zy0G3B)}+D^iuTfN<^?O-YszY`siM6LRJ4~?(Oz0bdubKzrB$>ygNhbGMT?-KMNrWq zsA&730-&}JZJq`z46joXRT^GLzp@OkV_{i_*C~lC!|Rkpmf>|uBFpePYL;bq9X0Eh z7YwgsXjz8WF|;hh>lj*=;dKlx%kVPmU&qj@wElGrEzA1XF?5^cq3d5a@3L$>JBF5J zS55FK83PslR7!ur?U8mhGZb+?8r z>tA7b-5sJz!|U!4S%z2GcygoYr)=8!D-Ex-@hlCmG`!OKR~lYv{VNTxG`!NrvoyTY z=C3ro((p>_Uuk%=hBs??vxYZoc%5?T*D~z0PPt_9nYE=;E>&7vI^~jOZRwOtmbIl* zE?L%=PPt@RTRN@M&v6)fr&Y2Hq0=f^hR|u1EJNtDN|qsXS|!U6I<1mr2%S3VhdvCU zQzu!5(5aIwL+I2=mLYWNB+C#wb&_QWojS<^!N#+bCH<0!0d=w@%YZ7IxXOSko48K0 zbc#(}Wk8)|snUQt$&zJ2on+~^I=Wdg-&VVAmmem27@7-<>wD*~Q5xy%r z-qjj?_XWL#-d5@zbSt_(=nZtUx<2UrbF;cW=~ECCl(S<&tH1opQ-Cye^E;&vO`F zCt$J+uZtgKS;sm#lVu(2R85w3tWz~vhF}A!_sF{*8QteLta^#uDhd)z)VAfx--=w7dl+h;a{UErW!7O@#ila0F;Pd}tIs{8jHSt;T3{K18TgV9c< zs~?=Ru&9h4CoRogJilq8Jafx?+kAI}Nqg>=cAHYS()OKm2j>UlHqZXXYX70Roja8a zam&fe`*zPQE$>~NTRyb8+P}PGu}wUs%gim!?O51(Uu8*Cp3?3x*73m=BWaDJ_@p!L zJGWwXC*F5%<0M05+Qnq7U9713r&ayas@`d3zXvkbt|nvc zYGvHJnvC9QasRZee_GZ*E$f{&?vICzwX4Z!L02Yd_uK{d-7&Ycq29N9yON9@-ECy& z<#tWf;{3sbX3thD_U7&ml58n)8pqnnohdoi%gw9x?Kx5J{F&bQEA{PnSL(HZah2~* zIKQo5x&B1QMX!G4I{ICORjl@S<(lnr!uevhs~oRv1!NB zT$fvB|DnOD?O@s6GHWvuXk@fnYIpT^Wz64wQ2FvXXWXAP8NKP~&)TH_OvqR}O~%@- zGHbWWU~#Pxl>r>vPET5t+m$(CzaHKLd#IURt2uh1%@#X<(aMyzQ>=`%SDA9zv;EH_ z{S@R??a6q>c6RODKRBgrisd@qzC+~FjiLVJNlx0hcWiU2x*2`etFL>?s^YX|+)X8Wh?>8B})B5*Y-M`;t^iJ#FZ~7yxUKjfJoBn8PjT~h3PV3)qb^m^o(L2rVw~c4X zf0)~`|Kg7O+6+T2CAM6qvF#_TqpvJ8{Y&?roA#65X}yOimpjwDTJMQcuA2VUde2S! zN$+Y`8J*s9lh5{^C}q0oT}{RssEoC%je1W{Hoc`5%4@CP(?`plxr`g1CycUpf=NBudK(L1d_r=$Ly%IKZe zpDa0Ey>aVL*0?_lGS*I$v39j_e->o)PV3LYxPQmX=$+PMA|(y#O_q$_X+4U`$NgE5 z(L1d_3*-JQ$mpHcpM`P%F_Y0dttV;uxIerydZ+b=ciewuWb{t6N9JgL;!M9^(FK&p z-ha9MEg$9VTB&K7N-wyS_OXmE>}xNyz0J3Mw34;&THbj`M0W7N;@oAOC#v+LEB3Jm zm-p&CU2&!6n3ZhED;4&Ycycvc&T9XXam$rGh`70`Ev~-G=i=+D+VR!wi6}k?bSZNYJc_W?bSZNYJc@A?o~h6ia@`=dNucI z_SM=OrC0kryPBO}%`UEHE7<7GhhFKunmxLjtzhFS=dbqvJx4tB#Q*+#>Kyi*e{FOA z89V>D!uk7A&fliaU#HGrwmE-3%K6h3&L6iqe|Y?8@Q11M`zxH^UE%!pu=AV4&abD= zuWsx7a_szK>ij%*e)iL|2S2;Q`KeC)>DkUtetet3PYydjzK!#vsq@3B^Mly=zUO@J z3g^31=R3za-@e@W)|JjTr_R@P`qwXazV_9V24B0}`RYl|SH67h!B?ivm#^)7Y3h7& z>U?49e17VD?h5C#pE+Uh*{SoH6P!=S&Znl%Cm(g};FH&JJ`p${pE@6#Iv<@nADKEI zo;n|zIv<=mADBAtpE_4go%bE2L6-n7ek<5A8VUcYVdhF#9^n!Y$4Vo`3w{1-qQ*Kkt~q^N)9)cZ~DgP0n+s&apX1gJapM6$zPIaAAuDf+`$}!H#Tb+}pPIHA*U*S|!XL7`?2b06j_)2GVnsegRxzp6S;~kD0 z+|hIHaQmYNcR0?u{q436Zhzu`k9Kai)w%7|nVmXi;SI{ePLUroC_E?6HV^V+oNTj` zp5P=~ojBS&h^J1p*_pY`=E2NX=Qf+2?YG`I*nW(2>y6H>V&|5(*fzN3F6S0EKW=b~ zZO+Y)b8dFiZG)SQoSSZQZnACj;3h{q+crBlo;o+0IyXGpxq&!o4z+?Hz6UAO{XU$gboQIga8RC1PnbP5PAz$+5%Dn0!9{CK%@qw ztF#4;GywroQBVO;h5Ir|0BN{DNt{E6cY zWN57xggjdVd8!42@{HqW*77JIWHACrpMo)iM~-bWaTxB$<9^5Bym4cQ6Mkfg0r&2M zM?76{vO)cQxNkt@q?93p@&$!9lzZ&NSBybPAvPbS z1TvhAfqyK10x2XD;Gc+}Kqir=;h%z^K&F!E@XsJK;h#la38ik-jR@3TSVgF?T3AN} zVZHDQ{I3cpi71>BPMH?c1fwVtQIw=_36*Y3w}~KqC*6Vnd+BE)O82Gv@c$xJ!e1p* zLS;b~h$xG4F#I8M2>hXPIQ$WEJtD~UamULO$heEGN|YuJc_YIRD`M6Z}6r--rJf=U?D|;9LQJrL&Dt7vciGxKJ0=%*D;c z1AeVbD*S0KY4CS-=>>mpmwrTa>F?4XA-OIC5R&gQ2>t?>@$gS@0nc0}xy*!rmdh;o zXS*y$A8=XXvKlupxGo~pb+PMWBDgMbYe%SCqFWatxTR{>5~^LN-AM%PF70mkU)H`0 z|9gs#P(`o!5kaY;)PUb#357pQSqc9tWj*{GluhuLDBywevI1VBr!n!`TY@VoA;zzW zb5e3@Hi^kA%o{*j=M|0|MLOp{T{wbd4=x-uoD3K;Xh0zuGa_%aflM2bH+~dZ$TJ}} z8?s^9F`s~}#YcD5!v%ysj#d2*;v|ysQ3ll?i3nx)GV3(x33-LXNd$KrjT}C5IBCk= z)`-PhG%udj3T=ZIMv2UyY0!N=NevQ08j+?XfpkU;mL>_$DG>$~cQa-o0ch|3W%k09 z$@XN)D|seDtNZnGh=xTRAr1G04+RVf%s)?P-6=dqKXQuZiW;$0{8DNzPmxRH1F}_f z#c93MH_rQHAMSffSDr+RyD6VnEKg@rW|78E!{)_xq1mp%32FwXq7*HIrB4ACx z_JD%{9|YX4si|qG*|KJK%~64uY9|IQ3)&rY+EClj$1uRKC^##mMo8_D2BAXevan%c zmEpeO(Gj&H>O|a)lp>ebnMNW=n9X>Bgxf5n9_d0FqHo8L7NiOM&1^}eg{_FRwCy6T zY^zCYn+M54f}XZBq>t??nQgm3o&n|nbAfrlGNfG&tN_fwN?;w*?L)f#zyZJl90ZOa zk7K}bBNCnfP65|Q7aCzpqAihVDDgyy7oyYx!jM%2uJwQzpb5~-mIo52gT!Kxmq(Hj z))7bnI-yEgxMl-S0XiZ5M5h`xdqd z;Ab8!LO2MgAe`<7UIwlr+=xPG8Sn#e4*@^gCOD0>6+4Zx?Q$B8>lj?e;#!F7C$>DN ztF{TwR`tH~Et}~44T(alsVR9qV`MtQ{*bpuL}CnL%wddSOsQ69 zasyMG__e!&tlZEnAeZh?FxV@p&Axc!2Zpx9_H5ig1Iz*D0`q`%sK{|#PXMQQ zZg!&Xfp_-8FQD)sZNt%eEu=fHIk@kG@Y%pK zz#L#MFb~)WYywJv&A=AmC15+!>;QHGyMTSjYd>%RumA^v*AZR{7~g<%7&wB2$AII& zo4^U+Byb9N3-}OmJ_arWs1F)vF)0UuKiY<)QCiR-Eoh7u>W6!OpeFEJVS$%uq*rMj zpgsiF&{k}uQSdYdVu3iI1vJ1eWb`t?BzYAmhyO=glG9aN5~O&+`5U!}xPoV_k*$Ul z9}00bvbR8pt9h(jEG86|#PkS4ED*pkgjitcc*13(H9k!I1esP#0u_TKb$OBq)I0`Y z3aB};m=y`+)<11vm)24wM3K0EdAiAnF)!8fCo;p#L+b z<zEP;Jg)~#YLVZ`GHw2;1Nu;$}#+5Bov^fB8ril9t zFb9|m%mbDo?Q&oRUaz>7vWYk_sh?5`-;*HKU@@CI-gc-U;28jDcBLN!*S z8tBMs8Prss^R23{h&OD27H9*z>|+U1u@2n|qG@e2G9AUnv){`IJ({T%M^n1Wdu|Lk zf?-KLhL*sRUx3t0zy%9B?FEvFTFB)E(Rrt%^G-+SoesfXfM83E zkZcJgTLQ_JK(Zx}Yza7Ffn+U^tOb&_kiE$0$-Vg3-1ro&-xam@18M@nKq$aDg5F>y z5lpS2|5(r~z!hgB>rS`OJ-z`=aj4xcFpB9WR>NJ;?W@twhl63okohjucsgo)0W~f` zO-oS263CtLu$b%7*@*KDFb9|m%mWrM@gm(uq}v3P0Goj=z)NiW-;PXn06T$Qz&>C< zZ~(9X2Z7gtQs52XFmMC~9s^Dz^LK$yZ6#>N!%@=`2yHrqHXPNOj%r;v`#2LKCj z5O^Jhl>%=7hk+v~^cZj&nV-S)cX53W*H6_F>Ze|yHGyDt7YzlNvTdxM0VkNw#KeZQ zK}bBR7X?ulp&=XZqvkz%YmQ;H2GuD5Yt31>=D?Qe12r_#*40tV-?!u^*-RUeb`wwn zYzDRfF9F+u9l%at7qHI=XFqTNumA^v*HLIG@CI-gI06EW0iQxmHHP`|4HQvBM^n{< z{34KF4AQ5A^dbl8MHoF<^R$3`)(Iar&teFv7(yzBkcuHBV=>z0bkI5-v`z=D(?RQW z&^jHo7J=3x&{_mqi_k2KKxz?4Edr@UAhigjT0p7=q*_3#1*F>T+D~mo=!7Ncge4%E zX;kzu2*3|yuSOdi4vjjUwKF5{N{qe*2waB1<-iKS46Fox+dEDp-n)Rk#j|k@TF$l$ zE&T$_cTY5BFEx+Ufgg&bV!gp$4}=$^%MOR+E!?{Ag;2YcEnEpXgurZJXuNjdjGhFdeX!w~ z%?m83{V}9qBdhU`hSpyz;3q5JW2ntB)aDp!a}2V#pqW}A7z-+MjED{;#0<_7C?QWM z92g>~#4*Pci}N=|NH`2NnvO?FsL@r-V=g%6F&9W@+;;&o0Q=x_fzN5WV=XY-VIw(2Q-)cxo!G}uzJYDz$){i`sCgE!4J2;IbqBB$*ahqZ_5%k1 z3vkeO%*dxk?;-N12mq7d^HSNYj~P$gt^+|A&~Y%s;ZqGrmCpkk;@S+v*@q@(pby79 z?<(eb_SR5@N$3Lj*CG62w`4O7Hp4g%U{(eFXk=sja1xBpV&OAks7%6&VA(T`XrBpp z#pqW|S^=%mX{r}98|j__<^Xenc>pW+Nm_9o(*A}NBcla$uvu>q>4W*9=G;tjCb%I^p?8g6eMf2ZbdNrOK|Mp7e-)-&84BG|Mr37YJF)WPM;IzZCK({yY zHNXGjTHl{7KEQrr^8c%g5C0;oe=8>=SG`F3cuB-=)%}l%!u;Q1-zWX)I?dlB>hV1H z&wVj${{QzTO#kqF$@q6COn)+8a?FX)-tCK3Y=tKRcaK-S?K7zAuF-zOI!Orx!R9KK zzczEhl;scRG=Jxbk+0KWBJ{5kp@}|eUhu~=hF*WktTX=STS$);?vri)KONwVm<;{v z?W41ZQ(e(A1NzT)jQ+Ys0sZ%+?V`V~WCgwp^w*gE1YWcCkH52D_a8C)3A{G`ey{Go z$LuHY8ukz0etS4u`Eygk&g|^J)Uuzz>?iQr_;_>l*Bhh%9HW1`7y2vyvhnZVY0dv? z-;?cm{)kY<8yp)-ZT%7yR*)e_(eI`#(;fJlbTiZx1S1jQGo&j@7m(?5XVv z{jcth8PEJLc6qSo`3IXkMl1^bejELDg#F!Jo_}w%%J{c-tNyqi|86ymv@vFW)px5X zNw>xSW(fZ8ZOj<|aAyV!QNLY!{--x)u<*&&KmTu5KJ5#iM#om!qm|G99;=_oX}16M z(*K6lPvo@mzqrVZPHbOfe)1YK-tP!m%ZR7fP@naE#Oi z>cL+h*M>kNAPQh_M#SRU1lKrRTVYoao2>j5v`j2GWMOxqJFY$PycfW>on|BNXMj2C zeIuC*&pe<=osNwI%M)LhSdWZ10DJI!FEZPQO!or^01I#sc)0y^8gbqQ&LjRcTq|(3 z*^XhGrW6Cpt~GIuXZv6Ae0!X|1<2lPiNv)oV6UqM8?8~Os|9tnpsvNJs|9r} zMqTZ1gtWk`I4x}=>W!Ci;O~UGXTooP55j_a>rwC4s5kb=u>HF2gI$YnkitPnQucn0WX&?!UwRr994$^3Qns4i72h{=?j#EltHM)4trl zh51F5`xo=@R@^`AaU2??i85^;6eLq&x-`{veo#;??nB=FcEo-~uYK|J1%oZ1DGJ)^yn)K|0M5uvj=Sv;92aKF9U zkt{J{;-zF7z{5EsXaGwq*qQPY54W=b1R~td2tQu%VrkMthEhd_Pz2M+!AXr7XYCQH zC!Eida1II|*^6eG(<9Q;rW=F9!J`D!!*fU%TEo<5NEZjsb`M$L!HVt22^k0;B@K-U z6o&K6^0=GA-7P%ACTXl`>Com0(k2!tc4UFl67Dzf(zxs#670+q&fp3A@ybo-eny98 z*y4uY*~56O@jMSMHQ^2q=kgc0%jJA(n4v9=;u-KpB&_28wak^$x!*22-q0M)a5N9^ z$y{;1Y3uM>rniR=ptDVlMojRxH?tR6!Sn|fgC6Cv`z$2B%u$t}DL{sVr=)SY^ej#N+eq!W#!ailX%q=|SXxdZJ$QfUh9MAB$i z+Lff!44OeQXcp~3GHDL&OM1}$v_I)X3upo9ONY{7q#qqY$BzFm7+?UNq$ld+ENOV479ZrD%GQHr8p^$CQFG@BJC)pNoh1i z>LzugousFvr)XzsrZkgwk)Dy}&{S!qw32p}pO<&gboq#UWCR^1pOW9A!!`Xhxpbr^ zUsFKGXohNr(eav5no)G3rchHzCut^VCeX>6r!`O0r!~_w)94h)n%~DU^?9` z!7YK#&=zS|Qls_-?TfTn`B3?Ynw0O9@91*nXXR(Q0s{9i872lbCL$#U5q~6ve;X2t zuR`{bFxetoNFDxFNL~IJM-=~RB9^o@%~aku)t{vGPr}>(oq-IX2hax?01PpCPHt;D zKe@5#)}%qE8i^?;@5!xA(UWT%oo_gOhR-{~@Ve;($h}e!1ZP1j=!5{lAVdfagczZ@ z&{jwiItv*>5224RKo}y762=QtgqgxTVUe&@SShR(N`&pgE5ZSxR5&i27Ty&u3Ri?{ z!dJp=;jVCBP(?{}6+J~?F;EN<>xhlSCSpr5K};5nsbZFxgSIqK943wtCyLX=*obE* zFK2oK?xtgzYy7kE6$KS6+}*-me1V0KWu}Q)t-`0V<9w(XW^?tKMA=!&L=!vu{|&)XOE^wOb4>-(gf4B z>@4N>85Gj&kDkDQ%aAlRB01SFLq>Uq$S*M;OTws`7&3S!Sm(RILZs+Pq{0s z<#AAH)8Y7+T`=9`98i!gCY`b3YGv#MGKT%1JfaZ$$nfi?GRtZm?$Pf%RxJl1LEi6HDZAx@gs+%I#M0-8dC}6b*2l*N6-cR$tCE5LF9^N zm}VIHl<5NU8Pfvf^JJz5$Tg+_$QMijkn2nVkQ-0{MdYS-q4rtwm3Fb#Osq^9kRO;b zAU`o>K<+bTKz;!qTulM}>iY=bVz9hlJ^*EK5Fdwyk#Li9y~g>3dngAM^knLg{c%yg%p#x%Zt zlP1UBmg0~P#x@>Ee>G|6DNM#{(q|g|A-5ORjY<;vI{=rb43Mc>wid}{joah z|6kT;d(YN8NKLb&LIh2rX-m{WK}t2{MvpfNrSfF7iBjnm<_f4V{LDrzmGEg`b(h{_ zG3~BY>f8iR7xMTES$uj=lfYaSLhtdA<04amSyC=sf9`f;t~f`uK6I(6VQjdmW$YbO zPLmYhhxrNU?ho^mzBCPsTMwf5x;GsqFsi3DALuNhWzqUlfXUi?n^7QIS&}7uFRGQb z_%6~<#`lEynz9qVjvOctB9Zc7c`m7|J)k{6QnW|3M@T2_N$p9}8Q&kSBwdvK$`Ptp zjwv5dgK|gtiN+}RmHV_68iSiui7zxe%U$F&xvQKZXUbV}H+-3iFLd!W9>Hg3gtRok zNdS_8R3HmrDvxQgfxs|RLVR;mnX|hyJ{#MOTt8S^cWYPvbtCIBf2j;)lK}kdB4{$j z*M2nB^h!dKQRq(aJtlo$h-Td4?oQ?ktGGXgxnvU$+0XsW#hQp|FT|_J{&FqirQM<3L45Hs=_|xfyH~r9_-o(BhovYF z1Kb1qx7lEay}oYWxZx{QcXxE>!oOg8{Bc+Pt39>ZziE1)tELDbUYH7zQ}BtoaKOcu z+&`YX9hgfGbN>$R9^)Yjcll5+1oQB&+?~VSXZceM4@kR>xuPczx5r=2{h4q(Qt}4B z@#gLc?lLN6hHCWm^Nk-My!_HC?Q6h_*E?@tds;$TfS@7^N4_$oQ#$s}M#oC;R-?@LtIpgnHXJ^__PP?56 z)tP2zS9L}`W)T&B&l^sPoi{=^mZw8}_B=DeKvQa96H`WD4b#lPk4+r{{7h?WMVr)G z?h>o2X=UvVwC&!OL8Ap+wg>Cc8PV`X*?_LVG+J%0(Gs~vOTxF*yGTBo{~j_>yI=7j zLlgxX?HJc+UARW;!8O_tuF){XBnrMtFO$lpyV4KRJ?Tg3C+TN=n_hu$(o^MhIh(M? z(-ueqFz}NMliJSTwAp*KX`|OG^&Tm$f0>QxPP@7+nLDkd=ygIOtbiDkXPsK6m*YK6 z^E)>)4e%H!Xs(z}d-MpYnxlaUST({43no|6SvM=5rbx?Hz^01jLNJ_Bw5|EMVii{r5^1wWc5odV1R<^hXh%2VMaV z0Hwfj;56_qa1poyTm!xWZUc9L`+y3=877!Y*h+%KHTC!0W%|q|%#`TW%OtoC7*Z9< zo;ln$+<&Q>%b%)P{ZdJFw-U!5AVkMq2n~MjR^iM9_}#eMin&#v*OO@4;B{0ZCwKiSz50}IwAk4WK0J4 z#il6tIHq~PG`ovaBKo1@EI|WyCBB$>gpfKI{F{)LBmo0*s%eE&^JJ=O3K7ZmiPpj& zg}b7VdO$SL6liVAi1atT@7%`Z>{M5=_eU&)*n6fa!6_6i#+7^{IREOngG7GZK@LCe zpnxBDP|S}z*vOAN*v*eSD24rvKOAx(;!8%mF`iffY+iFym=+0 zbxDF1-z_T<3@60MPf1{}WU;I$@p^Q9n7!T1_XM9FhM)qE{OmXcPgH>>b?stcb2#Lp z0bMvG0io_h@5s-a_~qq|7*7^)cUgY^$T4I!T;mwBp5JU8IAZ8vvYWg6xcgec&{28h zXhC6KJ~=gnJv}#c)X?$d194n0dpxCIcVTeswu<+>OKy| zQ*Z9p0D%JW$JZN#85Hc6)rkfE`k)3Kf5L|ZFq6f?EDNqLcTqR^naE+Tay2V}7vLa5 z-MQ<*T|Rnqu26Pv3!cIXg3C-!yyzCdZ)$>hElDCYbQbAF2H=2`LL6W+8^>BKC9BCs zvK-xr60&Os|ZRm9-h<=jsh^GmYtX6v^0ispERqalPocLWy8LUjscV1DqLw?mH7)SwptK z`aVuBLStCLjY_JaHE0NJK$~JIv=<$S?42PPopwJoBomk5QDQwLJ12eB?XCef9)z!+&4<+M{Q$Kk}7Ui}eQc!-^H8A9${Zt37)M{z^<& z9+qf4`pA3ik?;5;-~JN3x-)+66(?t93AGwco~wIJEFFT+(i zVP{$W?KQ_SE|1uMH6-kz5jqD^l%Pz3q-DM9<%M@7fu-=*N4$D12t|xpe4Tt;{*NrR`JfFp5){z8A8w)3hGb%;p9>%vLmA>0wZhl~ZZ zf3^%Hl1})EIP{|nT$U7XppbM^(KeGQc>4{L+m6;omKEh$vEzFnD4vtRa}rn$S*ya2 z`PrX+%|hgNyv5;(H_9~N$GU$ak3(hsqZk5_`I$cgEGjI}NEH%}-r=YH2(sSDBmTA+ zR+vV68ZM=5nMC7ygZV|Y8jLteN`z8Jsi!nh8YwYK6Q#M*QfaFsD#=P`rK^&mWZ~eI z9!f8zpE5uxP=+a^ltN{qGDVr8%vR6s^lnrlw4(?GDI1nj8Vobla0zWWu`JmDN+_G z#fqo0Qn4s+Xur~aru{&9Q#qym2xrM$QO+pmv_EO@D(`6@XjSDk?Kj#xibio&?kY!= z4-}p9BMNhs>*1gzA~%p5K>sw7W5DEQAk7J+C1Ylo0s?(Gfi*zj1QLK#ZDtW;UHKV# z4qg7qQP^j7*S`O08rxH4K9r%Y0&Dn{iQWxn#P@*HexvvNQw z)!x*8s(oKMuAJ0oSDia*>`c3hL( zMbX3UjIO}drd$_y*>WV@ZZfEmvp@;dDF!S9sB6HEbwa+ua5I!3xamqQxLuW+aMKiD zxSc_UQIhMx+l|o%A=`a2Y@qsbyxb9jr37b(f&PJH3`V>;IH2c=Mj1b^Ljo7W1)_ zurM`XT-M@@Ez$WW{C>vyTJ}Lgi?g;wcJ7w*19tuvQfPQC22zN4?7l71x!Pf~Q-^j12S~L{g+Z)3s zT-g(QV?eleoyl+@(8$jJA|Ws?*a*v`y0|mH3u`SQytcEDT^J4+U^P!eXbP>Q7^7%CjF`Q9K2zVEVfw>u`mubleY>McvgqZ-Y zFos}UYqvvhexTh7_q_HcxM#In;C{l2&~9`11nIJL9U+fev39db-S2DEmLR*Q@PN{G zKrh}<*5G_Ai3VULTZ_IF0n5E9q>xOyqBi|V0U3n`FoVo-S%Fi}oJmb~MaDI8gdMy0 zXII?&yA<>L8tjVu8ZJxty)V1s-WRrsktNW>!vgfkl->KWEAIXH`Do6}#T~1!H@ZfM z%kz$GaYaZCm**VW;);7;#!R>l!d=Y#X-#&;)0!?z9jS38-bM^gGkJg?yCMSmDVK)H z5e-*XNVVcuIx@tSXSkf-`@7(Zd-Qgmew8B@t}GTftU=G#gD^kj7Jyhf;v^dTh`q(W zZ1-2}FS03 zBn+6$l$Mn55cacjky+;wA|_#X+wq9}K!4$TC+rE#0@xG%ktmS3DK9CTu^g~P*`e&j z62UHIo3dNkjvU-z9PAPHLTy-}C=Ovs{0-r#a2!uGE-T^k0bkP6Vs_4&94q4(Lh)mM zn3 zdx}41Sug~mDEv7yRl$6LP)V3hP!%^$1k-skL%0RoU!u3bi;LHbmMf-=oaXf=$_YY&~4If)$P!|t~;tbsXMJZue+eTr29nojqW?$UEPm* zSs$UVuWzJpt54FW=`-}*^u6?h^~3bj^mFx#^(*vS^q=X!@SRvoS1YtuqguUd4XZV| z*3?>aHMNe^exdd+OOFN{BMtowV+~6T%MAMs?;Ac2Cc&CumtZB>D>xvyc5p~=Sa4); z{oqEyF~M=c3BjF$y99R)o)gk0<7 z9=bd9y|B=*p%H5$_TYFqm&nM-E|F=GS&=;=`$aB`d^z%P)6`X{jl!0Fed}+ zt*`f5y$AIJ8jNT#sf^+TM!&oLe>z#Asqm|)Rbi-TTG6_qZAH6^q>8Q;vnrNXtgEv*x?lzd(;dnBx2O#+0K z3t>I2dHzp@Rc4xbEYx@v!V-0^Tv&~D&2^n1tggE5Tv#J@gWaCrHtV)?VI9}K z#f9~u?g|&y_quyrSatLbA*@7wG8a~NeP1ptqkf_OIsJMrtWmW{E#F!ZwW4eFtu@Im ztQTsN+UreLkP>YeV;FBJHmoUdI7Qu3Cj(i8L>W+MrtD6BkMv|>5x@U zWM1UT$X6jNYaLSeT_a>g>bcjOUT=53U+Q}|$Zasbj69MRsqlfUf-34(G>5DbD%w{h zS7cQztXNxdxx!jesg6-6sy15{7AlDCy6w2_sIAm?$o8u3W!p~MHrq?K6}F|e#kNJZ zXKf2@3v6?3Lu>`MLAHUmcw1Xr8(S+|tj*ZSrnh<6oNcmAQf+F5`jdKBy`$b#ud83E zm(`EekJO9md+J&BlzLn(RW0fP^%Zr+&zV1aVx!mNXZN37f0lk0e-?hGKa-!-pQ?VU z{OQ3@zx;Inr*F#NDnC{JX8E@A4dv_0Uo2lzzPNl*`GWE(FW#hj8`c}VNeQ))?)$3NzTWPnt+)BLF(E6SAmi4;z z3+w0BPpzL=uUIczFIhjferUaDyOl!I|)!N0HY)!Pbv&LInS);8Dt@W*St&!FUYi(+9mL$9!G;t1oY!yLsm3)SFXoPQE$m=ER#5ZWi7gdvo;75jTh5 z?0mER&8U-~OrPmK6MRPcH1Ub_(R*(8Eb-i^Y$kMX`H36UG;>PLyLN zgUC?lJ7hB10E2Y6%OqG6!(cBKk=3qU$vD^NU6+!Ei5? z>0ITkYS(MsHaLGro_7Aq`5WhZdvAQ$TeCXb0TWKh{$_)-bt=aYg>MBr-x}{N_N|>OF7u@^&w3Y{6!ZcYN=+v)@zX~ zEp_*Badzv9bN$DS&(05iB;%L7xSWcm**@y z{OLi@>`0ez>Dj7*o)I{zmv}n4b`azElHmf|b*Ff_%n=@G5BGE;<5_I<-2r%R#Pi4L zCp=1T_DgW7Y=lYB0brZATHwx_AA^nvXei*}lq zw5LHHo}LlH3qu%(I)lL1+S9fy>Vx*IEo`;aOQQWKYoZG~&?PKwKr)@i(ymOVwOUeg z4C>`+s0fi5aO{`>m6I$%AwV14j!tm%#ClGKoGXu!W!l##)+_Yb!Glt6#d;KEOQzjf z0X;h6eO0tJ^WhZMH#VC;!Yi(Hx7pB%)(KEH3F~Zcg0v{k2^1z0jSj-wWEs$jPT}c3 z>&yt+X71C4=9>o#F2&}jQfWCOwR0NnEGWAyE7I^zm=4`{Ih}~S?E2<4@1GM`qIY?D>dH)&Vz} zS7y?04YB%Az0S|K71f7^L`Jlsp>eTsfES%ar>b)gA2x5!qQP27+TJDmp&nbzA7#;v zjMypNXy>lZT_82y9kJF?h8KQa66A#13Eo2A#;k?dyU|(1;oV4BGwlSAp-V8Z7@S9r z?vA{7nKjuoveqEEuKb}rTTdq}q&%>dv8>Q|tWvJIb2bfN@-E1x$?Up2n>CdZ^ZjfZ z$Qa_=oz`#F2D$B&w$cIMUK?Ht$`?ODTSe31Ew3*MXB75<4i4g~5%Hjdw^5$I-ixy@CZ5K{#tU(=&A`BB zv2pQ2(>O$q4EFWoKfTUL6Y8XijEIv4=I0-q(5q+Sp+h^DPn(vRwLkfbCG_!MXzj$N z%?s7TjZ)K^DK!#va*AUI*NG5HT3RPhiisH{4EW`?@N~)HwQJNLKg!Kr`Zyt_^`a(i zC>k|(pnHRcDf+O1OVsa;n*|Wks)V1;}No^Ipc>F6Vku}>_-4-T2s4u)%)mVf&MHb```s*5v4*4BR zXyEDPq4iL_v|0~0FLw`jS1%6__e4(*S5dQEG`p30X(bOAcdgzN>k`R6=x8w)Pk6OB zf$rA&My0u*GYv6E7tk>FvJJHH_k*Cw#}adP0c~Y|z5wq^67$-@6z_$YqleI;X7dpG znXw&+5D6c1@J6~D$nYmo32y$L{+d|D$DeoxuwwWKpP=Puo{NV9SDY1)dmq?6SmSjQ*T`NBTy_Zsmv&G%J_ z9>jL`Y-?ik5N^={bhFx9U8}BBd(#r}q`LF=ZJJ#b@TPi$2ENH!)?nLp&70glh`EQB zC7jcw5I1v^VKmg}PC~&)G$k)jKi}AxW?m80t4TztmnPT{8R6NiX>g1m{`vaj4b`i& zX3w5=_2rohg%+cxlroA+-*}^xwi<&YtFIRfmQzbgVAg+CQc@yLFL|&}yl{L)#j_Va z_&_*u;e(n}rl@x-8#18@WUSgl?ungvR}wlDg`)|eY=gaMv}-R7QvqHmJT}G;|IoCB zai*twbnijyHE2LrMMMl;P*z^FU_nv&z^qIAvogicg$d);QRBz;6t?z%Fi9G}s&RB> z>5DI}p*~c%W=+l9+>a_2nb!@cYv@69>k%|l8#yy_JtjyJ?HleDDw4; zI2YHXS<`shv>ESwp&=Tlb%j@k{`l;ovtLeK-9D*wSK;lcGbc|PrhdKj`QanJoU)~L ztDe0!_dhpIE{TXJEIhU2Xu}#oZQG8TQIy=_d{m7ZW5!(89vCsQzJE|mZ2rWAgr?0b zMWbkUYGfQ0Frn%pe2iY;OoBmJgk3kp%Hm^%8s`;ih-<h$JTE8GNa`#6^ z*F-m7rOQbFK*)WLwzcTS(nXYdnKu;DSWo#DY=h<%I@U(z8)&093TYjqsPV7kNdjYi z6?cDcUr&Q)<%!A@p7&1Nu0-ce(E2Dr;&Q=rmceDY|009uz1yCZt#8M~#6;7$V7;%m zUPnShNL&-|X1ER32zq;eYa&F-?^SJm^^|)5(k1ohxAs(RrSWT@r}&ziM$uVIHpn&h z?8#I2oh>t}pV83o&(hSqJ$s&2KRSqc>O{JL#vP}17IT)Iv3(&=L}RH*8YXzSJ9+AL z{{Eg)ppz7c-hc6SRBJEq79i9`r&v_6KF7&K`b%X1B)PEg%~sq3<7rV**x zvB7GqH(~7f#bo9U`Z(^*%)lY1r>stymo0UzTqe9eqi#&}AXC3cHgegAIdBVm|K=r= zxI%qlGHuDW8t{#zbRUnx2?>vBW>(&#dJ(y>x~?;(A>Rlt+1zkyu;sY?C;MCLT>vW<@UI5Mp1KvDKt!Ks0(am z&YVI6jbXLwb~i5^GO}KCdUfk|HEc`gPV=7Y(gk@8QB$ROm}m|q2~8D5A)w%xW=)&L zX(>}wtgE-e*G5=u(+j}pv-aeo;rb~@3&&}zAs{CNu%G(q4qX_$g1ew=Qr8@KesWf%PG-@=$B&Dne zqkV9l!&Gz>jfjgyKS%Rn<9ukaKGchKN>MXpc7AtI!kMOCUCC;DW?(*@#;H+{ofS7! z)fF?F*B|kab5CjrBYNH5FJTBY82`k3Y@50HEE-Pz%>8CD)A(ca#96e7QMtliG~F=1~Xz( zXVXRj%4Ouuh?$B}rJ?3WWP*7ah`DTDHk-y9G4Z7j#}hUha_y~eL_-bs(c0b!nW2oP z=M}4$pPjIH@p^URsgoy9(SA$kJTrPs<+JLY1q&B0px(o?v)flysRsn_r|Cjlw|e#8 zIY&p*QSY1!3rqgEf9|SP>ig;kt5*4VNAAy=vqk+VhrMlLAFHJY7^@W=zy8SVWR^OU zx!AM~Wt~9q^7MuY>IZvW=LAb0gJ5vArqN7}6E|jcTfQu-Teqxb%e!Uy`nK3J?cK`C zcc<-XanNV)si2ld^+8^b9+{bIv-bDWdsWR5+MI4b3V)~HVy>Frv0v}}0WgI`Y-Y6_ zkiWgM{-~Vfz6p!8O6|Q3>h<>vq{(0;GsNtR3)mp{ViV4iIkdGw*(Pn|b43i>Hk<7h zvl+Ra-PImz#atTKX^?!Gt&m`f+{9J}TOG>;$Z@PXNSa`uCz6>wJd1~qQxV^(F`J>% zNZQIQ+>!J*MLzsENzCqK#IKYh+PrS6orw*bycRs%A!1B!6`Lsy` zWwWLao$hFgSDnUz=$Cj?+$`Vb;m+80NpTv1xy)v>I-kw+Hk%t2(I$ej+dQy{-ETK9 zyUj`b zy4^f}A)Rl;EX@ZsVY&vhABD!*{TPVYR4DFYCBarFt|Xl_vc_r6TgNxg7_hW=d~(_S zCBxD)`{xfG+jH`y+*yN;&Y9OSYx2U(o-1an=dbKn?N!lM! z)^X1(%L;Q6+hw(gzx4UE{EnTv=JpwqJ~DT}xZXRSo}AEW#I#Ns^Czq2CpM|?$ELK- zZ;?8#ceAGcJ)Z3zmEUoEZd6QEX#3UCk&U`{FJ6$@J6_4j>;3Auf`ZPl0a??*P%mKUmrg~oc`dl zT=(M0;j?CZR=G$1uzY@E`*rKgpDm*MF%$ZBG2N`dpoan*D@Wli$|e}puP>o>p?E!> zqc!_>nzb}5bM73~d(PaFrAyj0iQiDaQ_3^5J9Ta#oJ>no@1~`tb)7dqEln7fHD*;p zPeVw4{&SbdAdKpIloX8P4?HkTV7&YU znDXpMJH@t^~IX>ajo~E9W5eBDlN9*;({DG-XJq#{3mw?|s5%Tr(YDEc;Yo9LB zsBYObEE|97)okH%%bqz?&lzXVG@hH9)3YT#*fOW*w6|v(jWge#)-$K&K`In>V-dR{ zkufY=c%Tj&KW^N3x&m&>!05&sH&&Hx+}JpJ;MT4DPVnS+LcfX(9%np{&t|)@PMj8@ z(LbsLBi~Mv>{Xw7{f6o|Eb08ZZaA=!+bj0Eyz_{xuQ%YATAk^@YLul^ z?H01CQ@(wBwOR=Ws#TX*JXg@o*bFe2n`u}kVNtk34xTtBs9<`YB=Higpl<%?IRrY%uB^y<+yH8ZojS}}9hteF*&XGOA< zx~FvV)z?1|>g7FljG8ibY}FRl_%lG#}`l@DHuUUZ>A>Xn`K;(*w>!# zFSBQ9)yZe+mZkF+w@VhO-@|;bsv{!QO1cF?b;X!?8@}pv>mG#Jxv$Xy)V@jt^Da)eO%`|CK*YxzR zo77VI!=tY**r+oMDp+~?3LR4{MyYL^H7^|7ym{sO#b=Y+Kf5Tg{TbLC?ij}31u?#S zIvb1OF&1N3s2+@CCa)J;7?gt_8X<9e-WI-id-LY!i!ol_e7<-KzKX62dMf6rH;+H{ z6h_Du!mz3pB`egc%kf9UR+N-XFB>*==&&+-AH_UL9)cBOjTm8Rvw|&KNtncy`^a!EFY8}jp^H$MISZf!^IHOvic||VA+r&(fGsDW; zQwR-_nQ>)b9|Z?sbr~?lgP3TCZ_d5*?YHlo6Xu*4HLpY3^>@;4Z^nwiPJHUC-F#cp zRGm^^ryYcrv_n7Z1Jm&p+wW1Wan4M-LpVrx%tR4(D^F$zJNS_xlnRRuE3n+K^Ta}w z-L6B?#M9T%)HA|h&UlIX8EM$ot?E^^$I*{U2j)SGdeWr4f!iw!) z^G4I+ODVP4k~*6_`T2y3Sfi*28Iu1M0gLO*B`iP#%*k1Z01IbV9926ebU`=+n9Xk%~+b?qI`+dEu{x9ICfSTZ;b$1uKD-x3MO0!t>&d z1GU3F0^K}`w^s|V7TztQ6B@^d#fQg7#7CxwrH7|Sq(}A->mS}fqJQM*u+ib8BSuFW z!;HpoV}vpCxv=NLpNn`dvPR#8`thL;lf~DGubUqFFmZaF^t$~+A7;_NPXD@k+Sj2< zn5|NaI#n|l*;=uqpE;(_ArV5Y&v&*<7`>`b--8F^`}Hf@Sun^LJEKBXyJeem4`dJO z-@n%nWkUUesRLTJ7&&5J-BiK2y&$@AUhc*>a&x_n$sHOs+8(L%skF@8MBC6d5u{B* zpm@k#aXC~&zeqXgAF?gT>`%PCJJxX5I0qz0avt7en9j zCSonah&kquXc-0)olw&-j}!$Sk`4xY&QpqXhujtghjggn?VN(1=6SXCz1tuIa>D8j zbE28e7i;kI#o8?&v*XaXW78h$MW*wOOs`YT3bXoARo`w|XZxPT^R+Z++f(##ruQppw1fxj8Wxq@I?hd27U@7R?TN z!I`$VT-i%yeD7+xwvX-?YYa$;aH^#X4opV))+vps>1i5)3{M@>1nYD8LF{AOA`IFb_ z3F9i;mvUQa8b+38U^vVJwuHg@c^ex0P>DA~r(~wH>@7<^+<1q|i-=@8C^CYX`E*Gu zv4-T*uyxn8X0_MUZkE<1KFnKI#MVQ>yifbnqqJmVgrwbV8oVShaLHiPQ+ckUo3H4e zt7|GcmCIB=+bdiUr9T?YI0UB8}=p@M3fEDY-Tm3nW9A+-p6*NM(k(l^#(mD#K9hWtQBrn z9VscH+s!LuqSu6HSjHU1(!A`AZtQLO_!yld7-OYDcw>;rj~8Z}`M?f$LO(*lI6! zh8}m0eS0V2V3BE~g1yh}KjIyiwO@UoY7ak^`R49d28Ktjj%^q1_tp!e6LK$oAno4Q zr^l)~bq8BgPSULu%dg&bNTA~G?d>bs*IqB4IA>paRYaelZGva1!R63zmR=M5uPN6& zzZbt3&MW6VKgSY%f|B5wE~X3aeX%aB`M#o{8q((pNUHf>&?et z$Mls3U>J)^a1SQldVkr|-Pt7>bXT4@apK}_wh-&?bx86*6mZb3RKj}k4c4F0`oT3A zYFN*+Ps8J>qa(MCWc}LDSL!1^yW|VVCi7rKox!oiIXRs>jT(|u(lks^?mV{?n+(F) zs-~+N#|SiUz*_5|{Msv=qkHbMgq^0JYs65}z^r+XhMDWXM|)cqyhqQ`OyUFi*jIHN zW0I4Xqia0gNXQwrfckXL%uKcGjuw=*uxk%)GJdyUl$7w=^cTIoLU-2Jo8Nz*>e#xC zh$OOv!5Etz(>Y0h8NqyfM9ma_yTJ1ol+;qdN_%Pjv+YX~3z01q&AqEZDz# z^`(oeS7U7`ef4U(D#Q@oD8!K1&k!OsU7VkPYVpDX{5^Yd4fa|tUQ*AmTzREYh<`{( zNTaC4V8=8Rd&Lr#Enr{0Zl3W0y-d%Ub1u-6^pv^wMS5P4M043iTF3RQV63!Axs{!_ zTS7j>i9^oVvP!_xU$Xi3QPJPXW<*RCa9a!lVwMB%L|o@OB!#t5wj7J9`D&!DTYD|& zkkq*GviMV(S<|Lo>Xp}b@Ed$H;t<eb6m2oDR^Ht3SNU`_AdUS7cw%^q%7Jlw`eiwmgPut8>*I$?E{u+Cj(uiaUj*-_XW zk)2@#hO-?aOdHIGEA(m0$}4mb^$_qsOI?@F;Atp{t5z%2hLcPm%AT3nyeiUSR*9qz zyb>ARrcS%mYe3&22M;nztC|n!}T$f^G$$~C&GS|ConShXj{zdFevSIfK0m!QZM z?Sz=UKcx-L?LNi6CS*tXh8F7#*pRbNMB}^|X%1yoi_*2zrY+xj=ul$MUK5Vx=i4<` zW)?lVZtdX`;c09S4;T~^GikC_C^2vimiv(bU6g=F6Hz9XH-jHeaetHZKv=rm@Q(Gu zVBvTtAX5DJHzo1nrFs!VVv-MJb&+@euC%HFc2X*qENco4+VfLB;!hCP2q!g?x$Wn4 ztP?!wA+5}>e@vp|D$prCxIv>)*w8^JQ9GinigyQPw3tMqQLQYP?xQz7l4DtImZF3UhbK11cNdGD$ z168h;jwxBDa&-C-zHO?b^Le6iEV=l7M#fj^8ExC-#3$si6(5!s0$ZTL{~8bL-Q4B| zO~;y#JQeoFC4w-_w?1k>O>bkN?t>I=eU$SP7jz)BsBn~M^@+d-ilt#nrVV|0P&Cw`8F z4}$TZO&|23n2OSk%f9$x*%yM!+%J~#qG*sXO!z`%ikPsCA>j+PEj=y_vlQH-{l&EH zLKUR%!P*jK^BxH{ju`9LES93Vqh&P_V8Ic~0=0CJD9oEl#jC&UnAEh1*u@8|=zWA|H@Saf%28XY>1kYC1d34bVkDc09a^v0q!sGNzG zF_z54>y3Kpj_@t`!aj}$2eCB4pkJ|qCahQi78bEL5YS@oR5cR4ZQZb>wuX@VX5i?9rT{UEDpX=#P)?gAxd@evH)wj5N94M;#+np7 zUR`nD9#&N%C#hrbRt(nbD$!thybtAMTO-09Dq=yUhzKf>y?MWxyBmVv_r3rBJrR33<-KU8z#_3zwMBU7tjy1|0j(Brx4uvNk9 zM>kad<2CM-T=bZfW_vqhlopi+jx-pCj24`wixaPU;g(fwVNv-+SzE~s>Y2vcH&&+^m2Z# zJgMp)=4mRr=cA+l#RoVD)t`xksRgQamSXG!iAD5r#t6`H5mVar?pCjKU%@t(6@r9q{U=gL3r<(mJHE-B9S zKvXxjFw8%Nh1tW_g+W*GQ1Ps^;yX|tf|(e2#$R7o?!LZ9e*YiRt*!H`%I1|_uozh8 zf9|QoUfGg_8FPtc{f|GGerO%eN~? zAF@nt>?8rYi7NZbeVk;Mfq@l`u|bN=MWvIy6cXCW*=pUotLxU)%m@nej;b|lSdXYi z2^rQ1KU=L?bXd2DOet&~ZNBc4a9^*ay4oR=4Z$^iyp!X!`BPLx9~D2UY@=Oeh=3=o z$RHptZ;nECHQ_w|1^DSS09<9z(qhd|fHU6NP5HT!@%aM?kwFX-&Z*+}%3>Y6iUyJu z%9Wkq$RjFAER(&fDv5s*COuXO7FJch2FwT*INRV$FjhNCSf#tJw&^?Z&f=v|dPAFD zFdn7rq}~OmXf5g?7W_u*$?FNtlLIMTAn&1cFk(&&0*!MR6;us@c^blc)O<}_k$plA zWaBjUxe`7sX%YlYtYB0o;yImQ<7H6TcL?o89+CRp9R6JdFO$N)yANuZ<@#x(h`rTS#II@QXr@tx%QZa9A@ISubH^-Sl07Gfcq zVRT~C+Puh9q#skVtLUm0wI)6Nb_j^6Hfx0_dAA3x;qcobj^m#Z7^=}9_NF>LB8~a% z$5s9;{=~wQg-kw#5m2x}xaR?b#|XwwYzX)xc>6Kzl=D@fH0Su>O?f+9qI5m)2eJV; zGgjvC_JYdWVsO0fDhBAt2QUS*p4bTz1{SBw{XOXw8XF@gdeM+!%q74MzSED1%SJwjf6z3AqMQP;^G z67Agfbz)q?rf%^)NA-y(bloQ6PvREI0^K-=XoWX8fy!#uUj?+N8%q`<8Oh9-B&7!5+B zrv3AJ5Yjy-ZPkp|L~;3R9~XVRa4~s(_>N``bJ5;zoP0Nc)?=B5nM!vtUmOUJ@nr0$ z4U#B&1o`_39)X5yXRn<-YqDl&>?YoB)-Uq)C=E0(3J{J58Xji>0a^Eq)(pw+?`uRR zyth%3L~2A0RE^PSH0TWXs{Xh88;st5)W_)UD~P^WG~x%JE0WCp{1Ox7YgYQJa9dkT zJ{3rF95gveNXCSWDMGTzVv3FuD5UMcjptU9?>-fGi=TeG^4vzM3{d`vhzq4%?h?Cl z>Y>t+)^PqHP_q9a`+V2A7fTqgTz50pEEab!G)FBMm>`V3zzd9q<5~EwW@ISi1rRdY z9Xt#kr-qzKX0b0?^Do>l@b-uoFH~w4RRVaxX@>j9FHX8O}G>f-p zehBs4g`M><2Re`8#rg@DE?YWlfKKax$kaySV2y1|(y>h=BRX}P(qdXv(xmDA(#V6n z%s!d3|EgH}Dj`!BUfnSYKhtBLH}BV`L&Hw{R^|qhj{SwPL})a6ZEk9756`n>m9nO7 zC#{?};QIAlWE)v};yUG0|Jm^2`>!mTd|H@iQPJ8>@~)9v(8<={yn)$lzE?TbZpuQ zs?3G7?ks(W9UUBvf|i|ar^G^@;PB1LxEttVvCm@8)-Lg7@m;n~oZ5UVY2IoS347H( zH7$Hn56Rd{`E&U@&dGGiJIjertCSkMErAKjcrv4Tjl_QIdend?&?Tt1xrDJQs6+b@ zrhXWKa3FLYa7w&G{D{S!2z}(CA@ozP+uB#eJSaK13gp*9X?y|->< z)4_R^(vwBTAY3mDVBe~V7((deF!~C9)UnZFD9STV=^}Q9EQkcwBUmUb1JXsNDX9Uj zLqj-@K?yjwqkFz+Jb3WnG4nfhYt!lN?0B2amQk+UKtOd0*(>a7HSQEV;O#n2ozN+_ zZ9Az>WOQmBRH!Dtf0oWC#SFpF{$eEG$;JUBdpN~@P+kyDN6CML)8Y7iQv?kIT;r7< z+B}@3VQ<0$9@r5qyvvYE@WvSpu?(BWNC=E3BqlnBcHVty_+>JWe0l%IU*8k4OM_|I z(j|KIgUiZ}1gW8O8ExHm#JSJ)p2`=>AI{@SPh|~hM=p{pvuu4+E<4YKQ~$qLE`RDp z7}|(tirgTQ4#5hi;H)b$z#PC%FPR4msSR%a1wKsa@YW(E)y211Yb(IgS)ub7*XyMG z1_PdTThzQ|(}fdraz1X^YW%F$t(q_D_OxGS{)}m#tr?OZ8=K!^*p5rnmJD1rnfM?6 zxol=!nwO)T+|sN_`EtrDBZi;*-Pult&ko;fD|O@4t6% z|EAVCof86Iv&QEy-uZJGhklXLU0VyZ8V&q`#*%nWS7rh=&8xXAIU$rUD9pxc)Xl*R$tCf#9v*2)q{NM121*`;SqP6}n zctm9!@@6&u;Ot?0=wc6ti)*S{!5l@H_6|%WkcFD4AwZ1s-9a3tIGl0X%u&^%HjdGr zjpWRuFCsN0VngM_5XDm~)U6f@L8Hsx9ojpxDl9|kDSuX%CbH@Z?sNkkq7@)YNVtiI zQ?R&i1Y+n2Kao<8%3(Z7LPfTI`dm^xcM1s@G*@XgH!q0XAPr0LpF4)1o>M9}?AY-p z*>i06jvdoZ(m7W@WBCMEUD5k0NwYMsqTqVegoRl&vqe=q55x zu8~N?n!)4X;?kuoyG+>3)LT_f9pm1mx(-$CJH(&JBm^!$Q-(@=KrNuFXn7mane(t4 zM4mL0B+{PpAKNuv*dTr8Ol5Hy#LZIY1G4SdI7HIo5Wa2O(+%5<42$-OWv78Gvz;%D62~;w@9XK>+yJh5^gaFS_x4VCSxjs z50XR!Vj!YzNQ^+>hKP;G&_T-TFB|8|_mio$j`EMQ!S4Dy;N9z~I5&KyWPi1j7?&<` zGH)Yj1oPFEV_qiCF#}Vm1>S7*!xXjX<6Ma7zUdc#drk}po*-!ml(=6gYzgCl7G)?| z0zCD1A}GtEseYT|g>Y-$FinI*V4lF- zB5~JF#m?r9F6B09v{#KJyAKWV4Kf?7LWqyQHPCRg{MtRkwes?7^2szhP(JvV)>4$5 zP6tsh72@~ACrFt(pF#himRfc%AB~4LL??t$(VIu*Un`eC&7x_t*ob~qBhl__)cAOY zc)1=iutzGc-NQpaHlo>bt;X>F9+8hWrb|hd+^h-6W@QuF1;NO-noz62fz$g0n*0I; zy*J#$)qpcMr+tdXHm6Og*M|&~D893yvb^ZWZ2Gnk$f45f1U=1hLsgCgD!sg=HEoQ1 zq;Ff(a5=CIO_JNUp~Kx^>buhj3@YcX8-z*_H$}#4ZFBvr$=k7U)W5Q!*&fL(sM~NiPTDx|ZlFNMZV;(uT@H6-HwY1Nc z%>#yPc77WJ^1#uM@P!unp+YGKX0m1>{1Z?n5HxqVRBbDd??^KZ$cFT*VW=^u#;O`y zYakm^KGl)75&*cY??l@=RHjV|Fd$k1Cqt0FjCa!*@0yd+IMYhx#xHknC>xaxJ^L$V zM;o-DU%Wkg!GhUuQ~7P>{T;%kSCvkuKMj2|WcC5_QIV4FtQc^(zp@fTfNTM$7H3m1 zfr3ElU|iQo;5HVVCIdgqihUi8wFg@YE^AK$b6c5_w{8q)VxSC`545J6lx=yT!q5mm=j7X23T|{P+-?B&-F{gd(?YY5G-H+8yzy zXcX_DQO6cYp5Bet4$Vf;lkbf?cWyjl>$q09w3bX#mabJUvZW|G+l_kRU>gb)l@v)B zvkqf%YLJY-;>e%x+!=cDTV?XeBA5w0gp)1bN(wdCo?` zDyJ`@{@BaS-LF@cJ-JA67^X|T*1sywf z?y|n?iSZNi5#6zHVat~D*LLbWVg0!t?YhU;vIS1+Z~AQM&Yep?yQ0;`yc?(YY@WAv zRjbZ*gL*feHoZ;jotarS9=bRxJ}S6*Zmdn0N<0r9 zRQ}==*+-cuoX6=&YZjduEw6l!)J$g_!VZ1}+BP>cO}_jd z@_lYCqhg(zOCId%klEH26=WVXa#@#p{W3FqE+C4M_j*dh9?8QRH|FPCPu@(d+ozp8 zb}0>T1g^>3c2uGvku|OD1_uR8UNx3RXgwNqUcWrEMU+MCPNqJ2g1gw5US`YnHPg#N z693EtUc@|n#%i$d5rE0EA+)%biP`8ZzPmjHvJO58Gg@rW?D!jH(;{2djMyMs8cCdn zkOn%VEMpPjA;H%1$gPXRcJ(#3N&)fel#FbQ24ws4=I|>i~Q*R%;MJZ`6o@$fd2Fs z(uRvNU6CPH^w!oPji5t+<&Ub)ntawSovr*0?aYY}LS~{*mkd#92jsfQ*htr3feXUW ze+fcqc79UQek3R2Z~kyD6fM<+qAvM-KK?uZES3vL$N!sfap^&9-letYSY zhCKgD{I;^0b~^K^kZ{I{_yZ9VD|Z}39ggRJOL59mZF`o0NVt7tO?EM<&XVRd_3M+< zAi-<0XU85(W=?Ije2G+0KR&Ac%2w^0$JJVB#koy{_=EBf?y=F~eG5CVO15ANaBAH; z>F;&3$(q?{e(4z&HHMR|iU^A1RA=5P>F?RfnAw$;f8S762|2nvLv0)@t`NUCrD4B4 z_tPIxe-nM&zg6T(Pt`VDSK|7uBF}4tyN&|&(kv(Ayq!?Sc9F@&D)mw|@Ko?BP0+9H1c z92pnS!^H2OUEi(r@UW(3q&Ju{V>-t85Mwle-B>jSQ(HJb?v?x>gNSpAoIleZWt`4zKZQ8Xhpp3#*N)Ab#}XCERwa)--c3%wrF^|x@diX}w=+~^ zdphQ4ME86kz6~>IL3 zZ#xfGOcRLms}jJvBrN4jnx{@m?E~U760yCJ#j5}1+fpH{dQdf{Ts=XO*kuoo;;|klP z+Rv`P7@D1s@yI{z&#oE2^d5#(2gLnqM=RRA7*Kr=OR1lT0p07w-{npRqda8<^_3IG zV%G!;8%uL>8O4Okx>_dZ5^>X(CfeoP<{o(+oSryMi4(tOTQzxzH*0OaM<<}D}+OfI{XU>qWlNQbG-}l+HO3mWMsJr0zW$OgT zz}mH2x2auwaS1WsoHgs&%^Pn`XwolmX8<|nNv>Q)wCV6qFGoc*E=upe=`Hvvf7!XC zUQ`pujj7o!vvZ~?P+JeiJpZFM}AIT=1kZoast6M^Zlqzkx` z!W~rxjN8pC6!b^kqvcfruc6*$y$DxWqRu^qbYKI zP=FZ`(HADdVgaLMLCs8(fPQRor<1z;z!9qm4jKmzf~sNdnw7l$BBKg8l}?HXdg5-0 zv^S zoF|*f#xI=@@%!U4=VO*N@7zF#Ry^A6{DFqDQkux1M~$I8mV3a$9>B`(Ug$?>luYuG znls=3jFLl+%~YcU*%{t5vWrBDvoNWrtKo>oy(09AT#v-aO4WPJOMJNKqd}ykhh~<*L za1kN3lw+LjeR0BzSZJ8)jC}lI@A!lMBbbPhk58rjsBX6$GK~g>ywxIuo}9U3$4oqk zC;briJrsn-VA<8u-S4JZO9e`nonHpLiF)ja0oq}MHk@vy|Za17Kg2a#`Se02fm($tH#Ki@{%Sf zA0?E?d2?ux?oFP5jM8IsXdEe#ch8|cJpJAiQP|3?6*kMBb1~uxx!zpb5Qp}XjZG5A zES%n9k+XVNIE3uRkTi(l9O#2LK|fhNd(w9P52P5tA0ydiD$p?}`SXj=&j#07)gu1< zR^F~2`1Af7vZu)@`IosgW5724Eq5PCPte;q&6>(eeE%VDSDl9H$rqe&Xs`A>pvCC8 zi-7f~KF{|V+!g$;8x!+@iI3&o^H8c*m?htsN5g`!2Z8%|hpUhq+lx$M$Fkyh*>^tn zJve0>#>YC!Vc^aq6*ITlNH<)VQ5}~&V_P$xWo!#@Tmoa9OEH%i&A9$-Cd>oE+STXP zxl}ni-OsE2_hl_em^+tkPG$Yd;;(Df!Cp3Q*D6D z3?L93RIyzfS6XRcn@&*o$gxnv<1RI?Y+=4gR}fj#vE zl+Oy2Yvd=3Xm&lSSq-t#9PfCebhd_sLw&f8yi(2FJZIaa)Rd@Xn5crBxRjdZqQx|r zUL^8oixH87GEA@2)%X#!gl@qPpQUsqn2cGtSrA5X80g2P^c5}v-veXLN4g1Xd}|qf z70;z%^otlh98H&3!3rC)oc2UFkCxLJ__1RJ?NAShVC1+|V#)uIZTQSct)n;tHO!d% z8p;IU4@Ec3$%Jl#<@{B&4!W1{++Ucnt35{!TunnAP_I~sZaCFwh4UcLoZsUT#Tr)I86Q~yU4xw?7psF$AF zaGQ-0;UA6!Sm0G*+$al?6cCEgLgpyNit{|qgJt{9oZeUFQRj_Qn}&7n7hl(v!6{v@ znDp?o&mIa(EBdx_ZV(=17GoH&W?&ZaFvt?*z*6!R(Zm~j@ zWF_Go^3>it>39`Lr4c!EXy$|8NhE6U-c&vzL72hz?X8*q=4j@?*VMGKdo#F0yc<|T z0#pbl#H?kWg&jL-Ux39ld@HQ3%uMY5b0N0OMoR8r#@O-eN?LXmnp*b>@ z*_Jr9l&rltT3d2R%YgA;;`d8dLP+bGx8}_!hTB9xe`CXxI|T!fjF{fpnOgQPF?8(IsiX1`|L*_( za;&l5;zf6VCIRPuQwmWb`R_h`7$?LhBJ7}Dzkb`d_3Pii-?r`juv#1wdRD6twAR9I z3G~zWJ51&VUMk5o)F7o)R7=qvoP+ZdMr#N|Qz_0IRNyOV3Vchw=X!yWf4o=D7$dqm z@ncW?f)&Ut@|sHh@0V5a!G3j#r0dF3^*2^NhOG~S>Jc0ecDunGVhS`_IkPfe4R!M> zs&yGuSUeb;dRWZ`U{qwyB2W(eS#xF0Ej9lOe_E;m#nzS4c&)O1XV2{6P=Wqk%=wLS zoiXQ)`_3pAY$|K60AO`-kCaA@$Y60dEb=Bf-0iXji@7M1m!WelZFppaJ8LmDMQUgq zHe&snSLRXDxH1LNm*K!=w2Erz)2}cr&A6c51_V!U5ZN<0p7}b{l$p zZM)80l17dk@vvf&3Tr{1?R=F-)=6A6qHf*J_O(V3o?DKD;_^NKix@doezL$S=F?$* zWfyR9RRK5-951IzV_PCE{wL-B`c-4LTp%~fTB_uxyrp#8**jHb0^tBYvh4U3q~5KW zhsYXbjGNSEwJNwZf&u6vGA??VBc`F<(<4ORfEclmD5a=sh$Pf5wd;Kf#A3}{y#rd| zEHaxD4pJ=?LIzgSf2IExe}UC9McV8OL5rirgJoN85b82PoV}lWh0)q8gn^+fWnYE&AfD_VK|vT9vF5?TDu-@R`fx4@eo2mI=5i zh(dN&BNzBoUJx;kbG~v@uWO(mBzBs_ojYzb1!#sRk+FLa{AkR}CCrRYo;o)^x@=s} ztLO5^DdlBlsLu1b@>Ap7+_sCT<9%oP^;v@kjU^+<+KP^hGnf!*3RC1w?Ij$DCu1#< zI_z3Y0|J3qaFCi2%Nz%8NfHfXiIs?B1>z7$BHg&)4%|31>U8VmHS+fV1opoA>aE4 z!J)@vx_HX26o-ga94aIBr2nTqkR>1+`#P@P7#)qva<53cmZNJ7R;In!OItcA58zJ1cs+K z0C7_+rqvN0!=mM0mcex2m>zpt52MnBgKx|q|1Vjbe!>>jt=`<(!`5$5KIs?VBP{Sp zHHjQzk4zf#WW$u-UzW=!%Oj!#1YQ2AUPL(8S=49Mr7>JMJKWNlOF^zmLo`jeD)kD{ zG%$zws}j)PrAia+21sGA5O0%3^zthRTI~;M?AD-6f!2fqjjl2PV3NG7J~c*F?+@#& zJYYi5;nJTZ+$Ec)KDLTkjU%Z9Ts04`xH%v?vk4<2Tc zs(ORSm+Im(&EGXy&h3p-W#|Xr6XU!@|mh}%IKZZTp2EDc4AF6bJV*Dtq zu#@EE7ra5DxsLb&*x|-GakE1;igW95SY=SFQk=WY2dIw~_#h@12}vkTrd!fh)txf8!5pr882cGy6k4%LTvG|+??t)_qw10qb2eS8*1s#xH&EW}u#2|$TR z!{eJQO8ls&ju^xMky+CR^?IG*RQ&`j68v&Ja~?GbY?>hEzUNXSAeo+K>t3dO$9P(C zeAjZ#Y1pXZH_lg7s|hyV4N{kclZvBza*{^(20}Rczn9{)Yhm~EBw^;FWc@)dMZ=59 zOta|p=v2ufi3mQP-n-8Um`!D?wr>tS;Uh+jf`z8s zbQHW}FwNii8;QxkwXNy06DLk=+P1kn8_;FHn>6Wm4^JS283R>1gsBj36c*Ks8g2~0 z5uXfo!t-%2sV9-XvlA>PB;wP(fds?QYm4<8V--3EeVdo`#H2qxEn%;4n{Kpgj~vc+vDmF-(iGDzH({biGy zNiCTl(A;U}H!yak!vzIzE5EUslrLx32)PZ>P{y{=uvUyI|7n3bAR$n(fJKoqyGFG^ z1L*ebhZp~w@k#vO8{*d_Bq*KRpYq!`Z|+_}#Q$o2zIEnwo#UUMurmR-d*W<$N&jQ7 z;P^jn76Pg^3*G_lMgBkR6<{g2EwcaPUcupBcb8?=mv8A^8wPCg8@T8}?-o9BgezUX zS77y--1@!|%tN-fNJBL@%*loEuN$U+M z>W_*sUS>^*sezX+#IvcTn)O)@L24?{hy}jIo{qUFhs-Td6n8l2ZSaK+de9NTcA@J2 zo)HtbL~%xwY!Ul&)05kw@}$5!{V=f}FGXh=U_hV2&gW~fKSjsw@ zEXLqWUot%jtT|vSa;53E_@ka$J`)nBVmQb!q7@CuUUTg@q*Q>7d-x}HF@k( zYl?T7+eo7EOZw&J_FJ-eKyK~;I-cqaCX5|BeO1Bqv0cA%D>=5OSATcJC(@gwY2$AF z8X?7~MWa4F8aL-NfCfZt2RI-JGZ5Uw31pdZsD(Lz0ysFxoM3t%5K0V4HYetAP^)1W zT{M!MWT7SFTJ~?=Tq(^+tz9E4hDZswM~z;y+M(PTId#gM8I!Y{o#->9ZJ&4U&^Mg_ zc%`(MJ*IIZVj>F~Q+xF4!O3AwJ!`)*`skNq#|8%0znmTE?@8;_$<2H3^MT{xm;}mQ znd1mgo2#<0J5Qa?=5*0t{6i?zp2k$LH^L!J@^w1-y7-5KT!CboiZ2)HqWM`rn@uEN zAAVU6 z`Z9q>OyLp6WdGzOCS`Tnip{oh0HS-ky{+=$^YsI##Y9~CBqK=t(?%lKKT=5UoksGv5{{ARwrVkA^=}SX#Ka5gDTF9>! z5l=^UUf#U@CrZXoTG_R0$@nSDcb1ei>DhDI^d8;6nAtGvuiJEobI|rpdHr|L>Fk$N z+v)V@TlWo5NNUWEyLrkUj%BPcMr)#~u3+#K7a7dOzNMa4k3vt4-Xoxcm!D4WlM|?x zUdrONm&$qVC1#5FBpl8Q`ZS1bslZ5b=iTtZvq}u~4_pFT((KTr56_X)H(B8YC2c=4 zFg*7S$^ZSA+nikx5h5MN;9f8{vh2PQHEZ~4_1+;ZH75UTI2ySpEa~R8M7v2S@ilss z)UXyCm(?uvJ|0{ejyhRC-g6g#a#g3`CNQel8+oxZ6efaw%&O4hppMjkcg>nzyVk6E zSEyaw@W9NnN=;?i%mb)|*jw3IRU7JgUsfH8v_J@vp4Ts{=mp7HM+*nxA zctmT5Tf}_CZ}RFH9AUlT(rv|X=3FG^afB&e91!)|3U-eumP_ZSLC;=`{H@DOMyXIN zHJSbNqOpTR%PtcNX6wa#iKvwYpBpQX&Otbw7xHNcmdgxr$4)R^WSydq~SeoJgTD6hGJ0Dnasap9?&TZML2`V@nm7T#aq9y{(t++Nsjcg54z zY(G6BCdOs!xmnAiY0Ov)G++@`3bBB*j$6Q6{vCXDdas-S*HXQxYUWxg>!((%lxuIt z=!6+@E}{|ksBBizL*+8MnGsCIvi(|z%45#HSQ`K#rD1JsH~^Vs_pWUwsHLX!LJg#N zJ}4;nP?RZDXSi8$C>)8B*n=F@gh#dR+VfDTN0iQxWytE4X!najL8o{Tb=goQ$>Vsu z#-Os^<9l|ki4&D*mzWoom0(ro<}Nm|+_B}C=bide1ZZnciv{%yUt5n6lr z%o!af?_V`;T$a03H8fj&thYC;`xLuRcuh^P-Y2xBWU^$V{1cZgjB9=MC8lMzFil~N z(9#gu#^@1Hv#eagH@a+t1qES7@+w>nlnX`9?s{D~I(^`tvOA+DTqBE==F0vJwV6!$?!9-(VNi-&>~dmEwbyuY9ayoq?0KAk zdpoc@!T5b(I7tCn+>>=WlIeKc9LGMA#%9NtAm$t`NckGO1VJyB zYBhzzajgM&iu{O~Fv7w0A^n}d6@yc>o+=31g#aN))7tLqt<&R%HoZB>UmuXeUBhfA znglO|xX9bjT&U5P`Yj7|$d==t%qa{UfnV+&(Gip2t>MIa&>qZ;sTXHFkzANCr#rW- zgf~F0dsS(2UXe>m;2j&dWeZ9J%~0<*yF)6TZPlGn+A%|F9I|Rl0h})m2>aT-l5F0l zsFsq$R3|%;3zVB@51UNE);flpH?c!B5?f(HSZQKlp;b=Qm(*Iu>+)d@ky~7mm2fz` zW<+R&1Y*uQqA`a18EYEgVm|0=(4Yl7W@gs#RmR>3)!Wnx{+7rXb`JwEhh#li2TY$k z`0CR$ecox>_1!gl`_&VuRr#iCK#K;6Ydh2@#IFZgrCit-{@SA3e>)tGabF2Xdrvr4 zc4uAdE`8x0SYNA0ySmZ)NnBL$=H1HCCa>>YzLJn_+ll_}KJFyj2eIFiQ$<5mL1dT2 zdGbr*i0oPFeca#2@*fw)fe(L_KRrN_9b)h2dsTEk{fqX%eQ_{X*ui}DXbpCP*&F?P zAvAx8-P5Gi8=z~0vQrsOD$|G-cXn17ljy)@8J zaJp5fbtbE8aRPSwmrQd&jY}EIglbwGjP@@jUeS%4J#Hl)3K!-eR0F7`_t$i=>3uzO z>an{@n9e?G@Tpq^J`cuPML~K)O}&r72Z`{8d*pqe`Y?#17YW*Bq^56SkY6dWEcACU zjpZVErs|J`d)5;C1kRe+y}A@Te0k|`3_wv6jd?R%)jk~-e|{AQ>?&36>|+MiUP16| zUyq25vXqwMf-Z`y*mhcM?f&@3kF9SuEEs0$z&&Vi`7%a zjV0dUg*MqIpiuBG_0cWzGc98$xr}KbL*dI}W}(?X^S?<>wm+b1R+FHa1^v4U zLhgjgy?V_Te_P^o{9Bgx@49+^vs@UBSb{Bxyj};Y57%_I`$T3NOi~!Nn!EyYBKX}n z*Rt;Yh^?|zs68HG^)Cr7j$ma?uVHZ#?E27f-20A;v~-dI_eizw)bl`i7;J(=ws5qG zhAat;n;dR&@XcUMI^nxToR?#7<=*^~g}%6)(Rn7fVKj;`kW0-Y?V~ftm3*-O+JqL_ zr_2`H_Ut-YjT+Fs`MrB3^y)wO?Q8E1S+jPCTY#~U3r%M}ksM4U6FM(i)6-8dSKed=cI!hg_(mF};NZd)7F&fN>V>}}x;b^pLS|X-( z)NC{vZQ(Y|=iWWngw)e?%qKk!lvbq^IGI5okXpXU>YQSuNKP1W&^`t20+Mb_7?PK^ zVp#2?#&FE4e&eR~$=+I7*@NHiI;2+8^!>O$Aamo`F_SX*ZW6YcE>y%#aFp%6Y1J~Z z5{-lHzO}P!nWP}hE5c;VX4YEPJ$0o#*=*u#mRO2mh=J$XIyt;*1P5bE(Y`)0Y^}1e z`M~NN)C33dMGFqXqS-y7jZsG57#}}ho&M#i#>O-u0-vVKVGIZ1&5cHaP{(9 zd42fmZE2OCnU)#e^Q5B%A+Dutnx63``SJCfw_h3d-jJmmhLEMb>Lw1$nyQ>6HHP%> z#rIS2lbq&axZ(d2!``ml6cfXc!r+yE@1>%vOJPTqT`Zk;{#H#2@87Q)#?^LGAS^C| z8Beq8|Co@1nOqk74?``KICOPk@@^t_U%y4go%y9C*WbT&! zFLO83lQe?4tGWxYL|8LcRG>E(25tD7eF%Tm7H$BC{)Yjq6-x!|FzbVA5WApSzc`VM zDBiyxZ}9cjvGVNEno<87)s95FxjL>xONs2y3}9@2{(mFe=-R$jLpI;>s)c4>Lbd}K zp4{tS*cR*a4S*Zlecyfl4X2+M=%%curg##B#Oe@qw;N)zz05%-ua;o}qDhYpW&NA5 zFp{vbIBS614~Qr+`i7K9`eNT@(f)yjCK_;DD2>KO$Z?Nt>eS8o*#`$T0f9{X2LwWr zBv{~9Q3(gNGk9@kwmU_z6j2Q$uBWfNHgc8aGY&MQzdEfYLT$FeV}GBm6VJMKaL5uv zC2r;My7%7~;$H08tBUCGHSdBo7c|o`vvu0qIIydWQW2Bv#s<4{O zecP0Av_^70PtgW5g~hBLwnhd9)?sQc>qtGL)zcWsOfXiNGoE5~9na=$1Jjo{b~ zVx|;02^OzpbUDgtofi4CmM4DJcJQ5{L&gqRKO?nk{u7rQ;h)p|0+r(RY=vM)X$3NXtq11c8Qj%$(3L z>M!Tq+O1C>YSUPiX0T9>a%tA!e@QbFmuA>rK$@}b1%w%+YbIk=iv+fo!)0u7KT&n7 zs+esgU6Sm@z5~88#`jE<;U98F=z;~)X~3Kk5kyU(o*Nt3ooco7Ma_ILCoZ;S1*$@!6Xx+qK>=i%Z?8%?^;GjiD#NX%Mg)=+G60O@Xf_0>yt#*d%l=-9#kT>~8) zNSbc<4GHeveM_#KTTI(~iofGZaoqSMJ}H7LOH1_PpR;gRviN6FX$cIF8l*mo$CXrm zgY>;WHQ!a{8DhjgfBFm0|0#QaKsU?hKA`Cc1g%j@$Kl8RQff&fnxUB3O$ZOf?~@dm zovBPeBKiYy{I)R*-&pg*u%UFa(t=Jqy>2DD-qN{!rA9U%r*;R9I1z%H2On!!yO)>V zVXB};=+5tH!$MW%-^V&M2)G`TZ;qEESQ9CyY{sE`%7jm{uuQ}lSyaN>5TZK zGf4M!9-v6csq@In>cviHQRX8OH#FdE!DvWB?NHRmNfp)=A8bkLeW^G`G|DgD-R$v~ zq+iQnV%|aJ&yonGA?;>daP2Ok#CKmDndW@v`#QpUfqLjeaUp>9(}W$Bd^LJcFQehw z&3nwPP$U*grJlZpKK0oprU{JG*&#XhbWn7u;X=%qg-UO-5sd&a2)0p4I9cZ@8Wv&mG3P|lAY7@aFI>Sqm`jcA zs_{O{^Nz54qFRGj2d!SrF)~|$xyO%E&q5RvXQ!A5oeOt>z}2H^jx8gZfN}tTlmJ-* zdG^C4x&-B=T)3(NkZ!;LUK;BW$xH8<;{(4=d7|bp$3MVhs8{EX?KJs*%)){-KU^wt zcjDZxE~DVd`>5eKqVdoRIv?1@kcgTif~Js^>i8_pNOpm#j=37rdm_zb%&}f2rSq~c*3;{O;CW^gCiNAND#;4SOSrBu` z-7`F3@xz9I^u{DTO`W^RY|=zWQRA^=1&227rR23K3l^MxK&j$X6y@)ya4-F)IL`>e zM~=H6U0tdCraVN{9Hxv0f`X6Qva|y#IY7P-3RT>_bCt%5v$;4xL ziY`&<2D*oGlm;KwaWr6EuyfKJl?rvGn&Uoz6icI`f$@b=qznlTku5V`j#L>!?F>Z3 zIx}iQi##+PB$ID8yMy>~7P^CXxRew^9HTqj=9h#(FV1N;)T+`(_9PSUuG#syvJ96T z_24;@?jbWB2jXJA6HLdZ~j5LgFNfAYw+OQlUqw zR`%tikQ7ZL!n~R|4$y!ch=Ln~wI5JL*>jTkt|f*(AJOJYJ7o_txks}_e8B};MBs(l zJ#_F{dg!%PlyTID5gDI^1G8W>5k#W7+a&xL!-vyA(}0{4oGKtI$#18T>fnNYGpCLA zb`LMTWVYyyOjh12zlQj2CMz{1KE?20mr6!l)tr$5EHPne@-lkp^`1r#5IbbOQ9|$r zlNk3MIs=m%y+{Pr36Us5ftmr>ngSm1BWM<-n)g{+9m@&HKlkOp4YxkJYehf7Y<)B#M@274MUFuxZFyJTg`Tbjs$zHmP5srroJ&ZlyE~?Cuq-_h z!^KKC)7y6;J3kp3Z4ehZkF8tWE_$KR=>%VXQ ztk2h{=Le^B-#ClJ|Ls8FPrnn*>b}yhQTTzlnj*UlR^5=~VZRq^hi1_mz|WQ(E8{>W zBhgmqtt~WytF4TyuT}ANRZ(^ph*l-$`i||^x!}(iZ2qu&=E~`(NIn;MJoMQuMzOcI zdj%Nv;CUaDn2o4srZd>Gcm@<&jfI+0&q6(0atvu!mn4ob8NkKfi_wpfIYdL^iSl`+ zMwvrWet=~A=Jt%f?WRl`_a~}yu%&sZ+*(m|_h-ikDmdzzG=~diEC|FGG1#7hMD@Px zq=AB{W5&fWnQEi=mK2o{WpHc?bjIY$J~; zUtRiQ+<@YDc43e_x?2$pv#xJ+9Q@-eq|-8jfDIsqV{kuY5qNn~Z;h|Fq}Oq=gfgKl z039@;)s%7@<8hWs5?+)bc+Jm<-!T3Y9sXxVP%kqxc6f*yj3Dqv^RLL@_QQ&g z_9V@bV!sJ$z`<;rjR%#dXG4{SoHF^bn8=JdGuR~7?yWHqt3JR>Yx3iKf+PzZD`<)W zm>%~(&LlBY=^m4n+x48qVhYCslh3Lm34|hHs>h{B4s%7q6ue8BR?{L}iMW|v#U^M< zI*v&Mu@g;iiZg4y&aC(6C%-I|5GTJ_;zEbFSw~>tvuR{yfv&J~Ga{l5842JZBLazW zb!#$8QN@vCCB(a7a0yKqqs$}iHhnyBJ}p`BjnYjy13dmA9O#OY9v4SHC(5PT>07Rm z3g`WsYE>jv>97RI08O;r1II~zY+jtz9h|&9w1z^Mw>TJwFNaxJt|=OMk`f{<;dI~} zwV3J5zurD#8{e*!&W3#is+B;j=9Qq?Opm7y3a=^I=}rw2I_%V zYL-@>6SgAxBSu1EEZX1KJQEh6eQxDl?OnlE_5Ay^lrC|%^XJum4!GLiQoN*E!Z19K zC?VcItF}Zmu67$M!(fiGidIV$J6^*!m~Y}x0G7p&rpL%PuF$abMFWIbJ0YnXd=8iX zy{ymMWODH!LeH-MmeB8pqzD1#IEE75r}+MhvE*7;=@3*|;RDNWT&3N0sjd$XuhJ_a z>HNb1+;3omN}Q*7dzk6Z2ykiwvXN_!!`;zKCg^achx7{3U80$&c!>wa+AQl< zVgZ8Kv|_&8g|GgbhH^hDHh=;PB4}~c)pZK#`r);8&y-#}1`^V9LffQ-UW8tpS#f4! zzl3f*H!I5T_pTh+%n@^9?D+#j76ghl8_YYith>H2O4~AHaND3dG1;NTH45gJu!?*f z2q_1UHgZ9F>N*Weo?E#?w?* zmXMWl`3?HJPisE;Ij%0xe@@3aK)=G5$mOX63gji$qL3c|gfd^b8u+I2jlhotn7Y>S zb0$(;r0jn74r$Y5`fF_m>8Ti;pniB(-#&4;(t-9V#=TT}Rqo@QZ6YWX6g?vkB=o`Q1h9luODEvWbkz9i25WJ*{O%T9^;q8iG9U z7QNJiivs!yS1%iN!;w#>8rG`n8**oKb!#IXM^cXvALJv~0Ls zLOe8;&C^LBeXDoQq9MDRHl($N5WT$Zd+JYG%16JadmNhSQX;vk{f)&zn|XjKm$G0F zHZ>+L(k;^T4s{F$A+@T2s$*&z?1d^VlG^zu9_v44KRS( zzT4gIcZfETaQ}u|=vKAAj~#2!e`!A?=rsG$?)Y~{2gqr$#(#O?AYG?f_g~r%qa7VV ziFpgBr35IY2u&$hN|3{@_6y>8w0Hk^yJV&@_1G6w`?Mys*ozkya1pNx@&n{Cm)%@! z$)|p%MUD8cT3<|3m0$;?sa%5nyZx{n? zj>oke01Bcr3h^ZfgaEHsm4-asA>%a=y1CuU*Rz+eHj59!47M zJ@`?J;OLPg|8D11d+w(M`lo(7D6jb2O{&^*YtC3dzLHf0vY$3#>#Z6g(q**6{J>&# ze~cF~8E$L{ZB!$}{Tb^S!;B6?cg&&^HVD4p<^=r~55k;)cq=BS=^L~ZpL_7n0oaq4 zLcM6ET;6dPNSTNHGfX(V-wvj*iGS`TH@;6736F&z){Ju53_@|psOUC#)gtkCP@D(9VPdDK+_!i^IoAe{BUypri0oi$Hg6Py}sys4qO(1GjQPg z{p)jo{@Eq1F}VRix1{+<`B~hljpbhNFsPmc3=RWQFhWzYs!7T0O1G+eltG5ZNV73b zK2HTdF&zOi&1KwRlHnU`Hi$lTn%QPo| zgDeoqh&0KX(3+SWX;er|qaTtK$UELBoa!SFOU9Vx?<=)&L)N z85oR82D-tlqehDK_7{k?YDr#Hh|LxqY>T`~e_HtgZ3`^Xqe8;NqJw+cR+FVQwyn-%>Ei1fTEf>6nyoL{?a`9KdU}g20s*_T9 zHL@bLVOnZqnHV&tA(tIW(O{AL`v{?^t}2GPAa!b8ztE19zA<#z;hmk@k!SQ8L0!3b zb`+DhH!63?XP*a$>P)-BByzTIcj2m=l-xfnLP_hkq+7=gbkHqw_hU&}Rb#;dlA@F? zm85xOnZE1+A?sn?rPu8@^rJCKhU1-%t@*@pKp+i=@(#rbJ;KH``e3Wx-w@?vGwAg^ z7y>vzeB#XtxH$BdAk!kMT^7TmJp9zvrUSmH0w1FO*FhH9nqH-k#9Z4jn9xV+$C!8h`|*xfry+y>(SxLSe*G>OYp#;v}9QcSqb%u;%E zF|m*#lE|2u?dJKmHXuEU3})+xzw|g!<~lzkgr<@~KTrDSCuOlHk>xa)P+Y{e_jO#N zboEw1o7`g5r0B`tz*~l2NCOgebH*`3S8N7Tty12k#4!rfoXn>g%geM@n<$f?Oquwz%vKfmP~99PtvQ9I zA;Ws;EK%ZG=lYNc#R zSU$tcUGp9>%&DxyHnocHgZIoagicklZ> zG09AIcXd^Db#--5ch_9!Wqgg?a(2kr{$oeyJ>TVzU6VU){uGKcO-v%hxmQ2EbOIsY zd_l@Kkri%>s^1s&x0)9GP}z4Jk(%gh37K6|Hndp}Ov5LOWLnw0uL(X_l7R*FnY=~e zjP_*+T@o|F^@CI)Ex^2MpX}$Hj(G_FKER1OL3}t!uJ78dEeNHbcr%wfkefre+XKRA zeaC4+-Y5I??%CNnBI_@Ry!Qgy@dJfT2HxY72DZl(LV1`g-Exgp$MC~-K{3I+@Az9| zGU2AgL_gF?g6`+*gh0eiMcAe*S7tKW9M!~e zga&mKOPvC#g|H@xwUO2&a^00Hlie)4=|q@Fr!!rzaN+a}zDEdBY*2a@&9cLD$B6^J z8#6?8-hQG@n*pyxC$`%!$@@ok=}$g-b0N{sEgBWSQqQ(JrXpFOmD zL1z2>J}i>MNdZS`O#M*3uqXwj6mBP5d}51e_N;UX%c!AQ@j>?3Oj~+i(RoV$an>9H zn-J`o64M4@Cwnd5U3o3P8Oc>V2^l=7^b#TEz1vBoXG+2HXP%x9w2`3#)NtEe0&EI^2R&p;+?)8 zHf!j>or_QD#iVIOAPEg^GKs9&MM%`N4~cjH$8eV8<-I9?qi-zK1Est2F?8xQOy6p_ zulVvQOa7TwIm8i)d4)ZgyR#VrGe1&Db}06{#mB{l2;_IOM~eq^;&hVn7bW@Hs>Y-n z>EJ|wyuYUtkFvQ7rXBC7|54gS5)b88`?KO}&cS*+_~yY5=EI&kFOn&bt${r#6sOE1 z>0e&-l0_xI^9XuImumx4elTR}J`Vk{6u*Ll}H+O%RoB()Q=x?)ij?L-{& zrEgr@)flkEOoww%nbWm8oQBu*+nERQBDcG9WY{I4CS2nC>JCd+Lkyp3hd0 z727+I17(g7WmGVB%!dSq1uWck@#&{hCaIg35^`qJfW+24@1n1^mQD#N${#pOB9K^g z^t6y{ZEQ5X7#blXfVe7x)FbH3C0sLKkp9$q#n9O1eCidaWE)l{wsM2`*(Vo1Tim&{ zq(nY`=+J5ML1AG>Oq9?WFhr;yNE;BK*$3`yZ>=Daw#6MA+S7^js1;)gOJ8HA7it6S zG>@geXs7Ggeb>l=Xft2pNnx9M^M$q2LUApQNl7Y#65>lI|FF(?4v5$rc6kW3OxOFtbJarOQi&L!VFStMs()~LgzhK<%lSSD_yTjj5Tv*jW9BMjw-Y4}F_dcN`( zU9IA9nX&VN%%hSl%u^JZ%#*}LYbgOf)xV7>IqGtP&RFXPX z-?Bj8g1OX%?lez}|4W&uZR|lkn23JjBDt*X>p^F*_f!1+idI(2-?6mIM0QQvIg}35 zUPf`ZbPH06Maos9W0Df&85jg+-*>TK*t9Q2SyK&D7!t z({`-nzc{(SYf}c(0#@=h{(e`xJeWomRY^_b=%V0+q!Vk&9K&mhWzz22Vs`Qt* z8b<-~UD?>yM#7&J>r+qhV&z*CP*h7CM(1j84x>-AD#y55LbeaI?!)O~yeoV7d!_ck zc$Z4~yRM~;1cwo$Xg6)qC_0#x+`&>5QM)~g4y`JwNZORq{M}4fw3M;5m9}dvN?IS| z0#c$GTZ*SP|1q9Z-p=2>HF2CFAZ)}!y03P5JnDRL3VwM{rK3>?{f?&uX!EDiv3Qp+ z^Ya=pF?sw9fUdc6kncE%IA=bj?nxpz|WR3$pi-J8OI9 z(qkb&xsRj7M=7MSPWJ@T9-l`KGs?LcP?9Rf&ZlF=SY+m%K*3%$^iY0LiCKXGZ=&5> zK$kN*dFN2lwdD)xDhCkp&Y@)TN|uS6=v!RHaffNm$qhSyi-j7T+`;OKH9p2r>bSJ@ zSll3#nL&da*laNoHrugxI(9j}n}q8Ru${z(Ehqj{x(^!K0b4S}4nyV1;qejpFFu?W z6m2~^XTn(r*>|RI_ZGc-x4`(r2#1TwZimG|3*&S6GTca9PyXF%Lwry+n0-faAO!h1 z91ObQ|8c`{L7FCiT?PNXCcH-e9}IXqtPlPN6;v1avATezUX21jx#8jpWhnC7dIqlVO|F%$Ge1c zkBDva4u7BI`bL^A%|_g??t)(N;U?OjIHCnRbDpt}xK?YhHo>_N0k*`>n=9LB7IN9nzT85mmcm}s z578LxIvd!o7(+4GZKfE)*=A*|36TE7hV|DA$&okTdFM^tRYBj=*O&F`Rkm@@%P;TI zp>dD}KD9`(Tozv@!~&+XxXW>v`ZI)BkK!j& zLfO6+{|wQyVT)E-B&$(e|Kc80>{B{_>iizPNbfeIlHzfYv`Ggo|8;7|DvCDxb$qd# z4Po7;qphk3hC(N{5}9z2h!;8R^(xqGm%n(0 zPDH-LRj?qyjC>VUunxd?j`m1KM$FI5N(x;5a0q7scC-qXfWrS4rvY|MJA9Zv=dG~a zli25k%Ae9oD=3bpAEB7n&!~t$N`EFTLSYG5$Q*VwEDl$fR)vXdMIN6rW!i*^Sb?9C z+#o+JOx#q$j8=))tgNg)5%qg|RTR8IA0t_!&=G-S*WrAK5k(KnKB5s*iG@uf>-5)1 zm$75@*Cx_G2MjnqV1V9!zyR__#m{fj45dCC7uNBNujl+xA&a^fPH)$K@l#rhlQdqz z?2M#0)rOy>r4>g{(l3YuGPgQY*yIfnBK8ZA5?mFu2jFv@DN@-26GI>uQG=Y>#GdTK0NJEp8_7-s?Tol7up;7^(8D`QGku*L(5)}UN-UruKn>o zEeb^BMdkom+X^!TUA&VgB!8%NK84SrMkP*OiJcc>S2#>CDv@g0zn_ zVdh6AIIIq$E=Z4axI6y|mLC-(ABcKJxNhLrPq6%eBcFm>ww~#Vi}6poY_I#zNhlQFp#rzD`I_&oe}! zg08-nen?AZbopJ@(ZR4e<1XL@Y6#$enD8O`n~VgE(>#W{06ONMmGgQpbUv zmuWvT1LPG0SENBV!bJcXE5wxWioqx7?tYebXu5<&li+Hy0T~n~E#Nz>FCkAF>O--j z40u-#r}|Ru%vl;4_?x~&EL3?M4Oe~A0w>YpwFhUha154DU@@Grj3U;y;xn#!*na`0 zxfDaq>Xr)H{e~cuSLeE>hl&GubxU259BxzxmX!u9{4o0r!dNExHCa|86{Z9wNK=va zJV?}5en`FY(WoCo4 z>tp~Z#g;4sl{8#_hoQoi#0LQH=0+u_n}XCiDle%Y;HXR+&2H%b8*i|hL>COGFjINz-M@KyB!d54qG7 zB9sQynECZ3w1`XT0*wYdQ(*<&1=MuwFoYXg2@bz+zh{*pOEnQHHae3y6jGsDv1F^82vdF= z8PTfIEhaJ|nEcoxE0bRmmmdoUF5NKmPvJ~vbNu)%{;sBisNNiZ+(uU%X#i9609+z2 z7Uyy@LnW96ptaw9LYpLtzsp<9V)^1TEvt+dN(P%HmkLwv+qJAu;mi)!W_(Ihy9`E& zKD?rG7KICp9CTh~w}}Ieoi5zEf5YMXVBP!RItF+CYtnQhKMpcCwDhyup!mOkN>l3j zeVN7thSEkkNV|`67rpaKt@&p(H)jbS$!$UoM}I+jlV@uM_7Hjt+TYiNmvJ~obakhS zZHj)ow1c0~6w&Wx?YqxtBS!|0jPxgoM_tW%R6?`w zQSzoX7A0Hy{ZJ#Nu__?t2iH1%1#}n~+*Gk12^RKqsupqh98mS{7c@S|@26TABw+YS zdjQ-)e%Jqza$QUMlBL|Jm6C}vH?)38arpgMD}`2Z@}uiHeNPoV%rgAj6zmB%JyK(( z0pRbMaKos=<6s^U@E9J^1!)VV zUDA~Or(E`h9L{N15z<|F+T^JQ?aD~rCZO7CQ@3gPmuag`r{Qlr&za@Eka&T@T|osE zrXOPXPtZmh$>CF>ax65lG5)dcCBMXR4%i__^pUb@xnwj3fIb?R9V2WmsxByTvs&|9&-IFw1H}XcWL=oXhU*R z8+V1K0><3(o!Yi5)ZS%@auRm{+gJ&1dJG}XfQFryeg=G)0hdq}YB~rCVZ|YI!-`*! z{^am|$PX*7g+3K1LT&$2%oygM^%d1Nn zTm?MDD1>z8m_^@T`!blTafG>BQv=2D3k_wsVJq^x#CngdA1-%jqrg^SLCpjc zj@CDOgIS;|zgvsz!uK)la96;R#GpZg4TjnhLh2N|Y?^M>Fje z&UtMy|HP#d`$#eWVx}FeEoF5AgF9%fnEp>Ot1p^`hSw1@2vPQfD?7zEGM>iunKJ;5 zR?e7da8}(a&C@o*Z=S%Lr!7xek6m8#M}Sb=f)m7~rRB zz+XiSTZRbACK|TH$p4bj&0L=We!E8geJ(g-z<(C-3F>&({zidq21Ty-jf5)reizIO zDgftV8{P!*k7^z<(@ZmZNUi3PI&o>ni$^%`HG6?WsFhg5*kD@1EL6Oh!3)*u1-zTG zH0WlnUH~F#EN_B%Vl+Xm=AjMEG(Ijei{mi+F>_p|^Y-ZolrTE8jQ(90es)4lIBOmw z|JD(YhQC_+C^&4Vu#`*HVN~EogdQzGBbc}`Z>i)2CB-owd0#N#N-qOGkHNX1S^MLo zWmhh-BoV^}Qfi19X?@MK1)M$8*0}!TQ2mSqlEn+v5HmhFmY8WXd0MrxS&NPANt_6n zP9`nr6eGGW{A@%`IAhYtzZJS{aFeKv))G~Vkv8E>2Y+6`BzvD{I2G<;itJwJR?~ z{KrSY9jw4lk4Rwf>;Hr^tyM8|u1gSyV=7q#ZpDS1+$&ap23)l~$CkFiXf^y6^Z%+7 zWW<(WZm~`M#VEj5cu_#9g5RzMR{>`pu}%HefRoWYzXUk*hHdH{6ApC+9^^MXVf8ly zF8nMwSON;b6=t0MZWc)61q`KuC#<>{oO-*s@|em5xCL$e4>&5ekpBWM)`dH8yEiL9 z>n50R*tNP9FhVVGHy#OBYQY)D%%!tg&_S7`S*UPR63m^mSsY-2C%{2M0-8W&zMKuW z+i*BFoJKT(%KSK+#nXht%`gygKh9=>*TnG9I1YzIxeI5rc$;v;va%*)?wifxW56Ba zaCZUjyV)$hMuG^-hzgdV05{PV^l!$o+Z0#9(Io$XGeXgQ9|><>3+^x~U23~3 z6L6btvls^UIeN&Ah?{JirLB=)e1gMS6EJgav$QkeN2>BOQ*E=f2OR$Yb7DzV0cNLd z7IZsCDZVJOCNNBKq1!}@8ydF6nW1e#4;g`MotT7c+Y|Pg+L#K~hI9H%C9h?Fm|zSQd0u$727V@( z7dU>0X|On_#xyM2^tL#wtdI-FUuFZGLivn{oXKZ}4g+3< z=EIT}lbTzqE{q-+s+s<^)%4$JsDtY{)Do5g^nb~c)z4Tmr{OJz6zE_f#RY&XG=k^D zXo<#RLNoF`Z{%}fR1_cQT4TW1x|;C(Sk)3oad-P#x;o2m@Fp2%~z0^i|0tjj1 zRwpWP!NnU(V}?F)WEjwls8ckQ6E`2cuHZ5_tN+c(ew&>Z<7sP=cECt;`5E#VR8u~V zY5|=!3h>zg6A<_A#SL~75rgv%%HhIf(8~~USA|QA!!2(?KsDhCg^ff$rmj2KC_%Zp zLdoA?@Nxf0I4c~eM!-dEAb!3kAzYLOd~H2mAyYN!Ck{_FM2wI9xB$n5GYKO~)*oo` zRPv1>B-TM$RjzNLiK`(bg@*I0RcNs>15Rca$3knXJ>fla0VbZGVfhx_km)nFkcAqI3COM z1ahdVfc4jtHS@bFG4%^#8bFf>8z8Cy66VlmUT`Z`TcwA|;p@7Kv~<8Zs>zQ~1cxnD6!r+b1F>eHhVpL?v4_!6LM*n2=ZjK~Vp<)7YDP1tdJJJ93DLwSfeG#P< z#Zt+U8W)UPz=8wQDPdPC?^xJfiqoB!_Ub3tCpyL+B0@8UUc zt#~6yI-$hx(a%dWaf&;J-}(@YeUWi&gCySxsbT{j0RGzM2r0DZ%>Jc4M~vuM+Q09B zzWs+EoqFNI?1Li)_8p)vC;i*b@bmQzAJPF|PVa~2Pv7&>$V21WYK}-r)6PUmZ#NM6{ueu>}gJ7ct zf_Izgt-Dv;iIxV5+SE8HL_3-w?HdZuMj8rPMWQ?7#3Vb-$?u?Lo1oc4Ty}bPx*DU# zkmq|28$SJ=&Yc=RdE|)(1Lv;&G^PM^J#fJ^(hYQy3 zdF)}H^lfDZd%_;yv&qt6;$VdLSdUPQ1dd+w9S}nin#OW_#GxC=wcotJj&t2&Bbig}#Uu#CBzxQap0i=~aXK z={sfxK}x%cP`PMs-rUw7>V?OPoX6fLw_|PkyQH;kdGo}wGFwY=X6gs}4dgd!A%vXSSP>cofbMhH>D;0pcoBRD}m zgDfMN?~=ro+B4ZwtTsMJTB?P&l#;b&t)#LBS%QF_^3b6SJ5h1L7gs0T@CiY&@IIQ< zTI$(w?6~CC&2k4urVh&*)pO;>--b1PqH~Wl=Q?4P*{ne7!vhlk3r-RJHEoH;P|vcnp%oz2*;Y-B{M$r!rjX3LW6`BF(- zEKCH z$g^kqv}w>+^mcwezCm_qL3sO8izKC|4^QgcX$$#Jr9>;Elc(-(nLAt$=-Z%iX!Ede zD#|PAdTbTA-bR`k&bne#-W5HJZpfnS#Q2lO+N^x()rzL=q#t0&(gWiH)8XF0xjD7? z;Np@aDMv*8;AK)goURwcZalaMsbD~Ig z;aM?55gf-3Or(|%>!N>3QjeCG?|bWolF`GSVVCwlQ~bs&&_|pKQ~Pj>4X49u_iV3O z3Z*C!e-rW7)3ZIzWZsO2O)DvsLTbKG!h2G6y0pSM9Qbm9uZ-bijtIk7RldAde!H1} zB=XPa`QfD0$Zyx~)T*zcX6-126jkACSfl*RN0fJ`j{|-q9llKs{0+59zz04nmUfh` zi`aoyF{Lv$vZ9ZA%tJH#3-z$As41JXkaToFbVF?5#|f4UTMUAjn5O~*c}hcKWC-LZ z1bGCEXm*A$1`S}Oq|1Zv;-GN@{agL)-9o|j+Z~rsSp4FeH7_n9(^g9`N_F=okPX2h0C8_h+EIb zk|%KQ^%&f1wLqV*uOnYCe0ur9#qXZ`}Of<3VCoWq3=m0a-)ww)pn z_9;{)!{x6Ywz@G(pDBK^=f*6u4C<|w50?hw9lB^eSRZLEfKhAkuzh~DheQf<0 zfpPGE6Vj>NyR=ieS84xF<-Y8fmHi4T?ce7uAxX%C;F5$S*NJBS+0FX05G3qmG>jiV zG(9K{(F@ptFc^KPmCDjYb^Ozzpo$A3%=a`K2C0ZGi{!(pPM#^NEIK=mIjFO_xLhc zuBFVC60O{>h6ZK_8nI?oZRA`j-m2ynJslajwZ)P0HOp6Y%Jb0H&y}LBD~hc?}cdw1TWklmeUBGU`E>XI8-?0o55J!le~ zWBhEAF5Yo^{;JPZi|#+E%!7v79nxB&Eh18(_Td6)npQuNq-fn2N~0W~1lT-_n1VpP zrjl=<9<5wo$l>bSZaC}@;Fthj#WC-d^fnH&!y=(87^m!DCUIz;pTRSau7~1m9%6pL zZ%C)%O`qyH(lMiN_r>I`j%&LXY%W`RY}evJFBG=hGNjQ{MNJnw+KLV^n6I{K(FM4NJz4K@52^Me2(67AXvM5u;!I9DPRM{dsJY-K#gaq&l@C)<| z3KoNDFm7bDDpobv66_J|S-MsCjVn zkoIDG+Fo+x$$3hi+TPOMqrGR5Z;@Y-wX1*EfUbc>K}EquA-xVYD330WDUU6;mD|e` z4>hz5L_jru)X~s=wMILHvV)K{8o@Y%7;B?znl3IKu>h^`)W56R<5{CEQq0C!{N}F3 zWoyOMKK+)A8L@atw%H~j)eZ9PuKl0StVn$l)%~Rv}+a9#Lv@H ze;}5RbL5DWyjj{NE7un1SLj^(&ICP1AKIf$v)st~0X>*G1c6vJ#@PyU z4Y;LU72IyXS-OP&0=1l`ccvAJACD7;Wdk<*;+~d@o~%;X1~#8ieL%UwowIC!w9l4E zy=^->v=zm68PE7F5OJ@|=V6`ZKDTLN&p`e7%LO$Ov<^$9_@1amzJgl1;P^*BVc0+F ziGi>lRd20ov*EzkBICqTX;EQqGQK0(wE_PXT_j#VS)0(g%Otx4gjxs)9ghzf(}nqL z*H#^o)Frjl_wl)X^6G?EEI?kR=V*`Wjwx*JlZ0XUps7r_Jpy&N_ zI#?Q6{nFzT?IR;1Gc()9+x?A1hnZ>(32L9785vPlcs%RPLUJ#vS(7xIEm$O#qiVGj zT`H-e@%ACjI=5|?nOWbekU_Q5_16@S25Fh?+IEf_Soqdkg@*lQOh$r9cElM=xC9Zx z;FX1j2zCdUMZ6??b|_$V*fyHwk?ev~g;a#JN-pe_K<2cKPY!9-&0|Snub^I2{c3UT zH?ZS`i9M#*2Ko-mALdzDxT_v1a*)scQ;J59DvT#xT0{rvjjSUAmlpQcf9zMcGm)lY z9Vc$wG__YCX<1uIpaK);0$p39OG^znr$KDKRmCZ8v!rZH#xZwWO->!GPiF`I*Q_=m zs=b=kW{lIsHfoQ;WpPFSQ(ij;>?rKyMT)9fUCKF4E6FQ$6t2kEOaFJwcFzUAxy-=L z7Cw@;NLbMJ?C9E}<5;O@NAV8+s-7K52ev=1b{^8forgTb^0>AThmq+e;UmPk`kW(r zpFGPG-`Ah2i$J`Cg1j>0ue&lWuO)jY2T%K*Fna>b?129jHNu)EMvJ zLrNj>$j>TamD@bW8TrLPBVF6NN;*}s;#nz+_zppq^EkbW5rWVV?bFp#1B)0)WO}x2 zx%ObS6lM2||J6B9nyBB1ZPzFEVAu8`$M)#MH|+VNS?3-Hi`%zQtfXV*N;vK@9g~e|X*L!W zurBJppQ3>n5}F+<4fXWs^{-LdvNcjfj<>(!x3R3x-l1b&8!};yUr2P+;^(AT(y1q? zQeW9~cF()T)A0MUtcpr2lRDMM>p^kFg*8%!?0_}|lcV_D6m2w)Ac9&KZ=68qG3?C; zoXHQD?jMExJ{M#(5>Izkq8!q7o-U<0-$MFDq+d4EA2{Etk)FiMe@wE}G6yiw(+gvE>q?a&L-V;&w@+^f&%(wc0L!X0dh zk^Q4(g~Nxh9zLS5#bfrQq}`9t*|E!cR~8@W{Ab6|g7$+4uNXSHQDWlo=2KtVGGoSe z=gQr8_CVh*k-=z=PJ#y(JpIum(Fhd7k z_hxw9h!h9BPEQ0z!b%YW_IVN6B#=0XbcoOwj~~&q+(_tm;%4VCa!I%6JsJl|k6>7; zaqK*D{6*b)$oZv-!l5e;-A*n!hj9!hH_DkRZek)xj2dWH1Kr$^^Q6(hGLrOr+1)<| z>OpQ&4AaV&{1^eWMf_&OKeD515WEpVld=ma<6->r74g z$@6mKBgT(!o12^4?ic->RFrQkjEgU_51#y3|89fYwrrZ+R(?M}KR7SBK@w2${matVlBa-sP=m1u8BerNR!Nb84@Y3x^oky@ zFC-57WaT`4;Q{T}RZ_6FaE}zI#k?YY*X^vZUA`d=!bKfIf*J3eElS3)uK=MT=`r&4 z%6HE!$A713Uge3U$IAvUrFq*|tT_Gt$`$KQEL~nU82uiz{wh3L$zCZa84I2t(!8aE z%Z@LtJVEnLGYn_8uNz#peCdgGD^|XLdc_JX8vwNjc@>y59e50arujC_= z>ze0&sRu6DDcdiF;%&x$sheYTozf^z_%uh_hW-)(A~NB&fOIU?U`enla4ic>ERuWw zZaIw%(>G6RsTc2ke&@^2@BQ=6Z-0`zjo)iIz2~%+BvveOesK5v`MYAavm8+rKPO4p zkYnP47vYep)*s_Cv22zp|D$Rey=TveJ$v*n)zwn# zE5l#G|408>DMWcmmp(Q?mn0jRyw z4p=~=2Y67*EdZ!#j9|tT=Ygh|OX=la=?73b%h{x9w#kXfje`va21`fwNI&jzu4hcu zsk}%iH~3=W0dL@oRSv#PwB;Vj$Jzs^uP$S}5FodT(6?CNISI!UbuSHsr9B8m_m&1_>DUH}Em#z8sHR3)5kd@u@|7 zwnEB?ta-hgJuM{ExJQUDIZ%!)gv=_LFrlPm!o;q5Ga99&99_KR&=C`Pn7(jgN!Rh? zyLO$luxU!;Dfx>k4lP-H42x6G9+t+4j)lSj#WRtx)FRk2~ z#v1p4Cw~0#69C~0Llt>~!q67=35K}&J@C$?{NlL8+0ky}4_SIk74EPHrIvTl6vHjUEJ zy!)|NrbylZHORzvCN8LQIkj9tC+mmK+3y#wnyFmdN%{d1K$f83N9~8&_~%Y^-u(`_ z{)6x34bJHf=Olq>#m6KsNBVz{lJ_`N#TrKdLc$R8wMHORiX6aK-;L2EwIe5$e`ZC; z4yG*^h$|nAlp`MeAV)Z0?3l(fmUuqACoq*opD;5zSWe{QndsdAFMNx|&Vz0$tMPh4 zy}NLMlJs&<-eeZA=mCLNTM__d0GJ#gVbcZxXo{Xm_y8;A#RQ|>J|@Lz{%=UFdvvdo zt0f&~;86|6>jYAd)N;>sHxlSJQ%;ih&vw*G-oSTtrlM|*U}n)zm}pc5Cb*$1_f9YO zL7g0{NuEJJCnB}nH?`caE-&RiT#0?t4tRqZKX5FSdxH)+&8l`|gXy$v?ghxODPwaoQyVu- z+BNI(Zs~!}Zb9j#vmW2Jb7pe}4VEQwe^5q`hdXk*cAeU_gl-E7Ol~-`<;)%3(%a^z zci%R9_AWpi4by#m+hz7xSCWH#lkq`M6lRnEHBq7eJECSachlr}6jA@62}BJcBb6SI zR1l9~n9U@?{+VCG*oRzP!ygpF?`9iH=m|*+pY9}|>isZY)G3EgUMNV|{xo*n-OfqjS$dDU9%_1Y=hD}T+c&yfa5K77Pdp{xDUjFeKMWkG z|L_HwwP@#DvY;aI6X|(kf${0>x~2ZBqU1BF8Hx66W=?mTNg{aO@4AH#L7#z>Xy`i# z)jpmhMOu`O4_=o0KlIgpnIlEXO4`z2^m!l;V)t*2i!J~(aV)n5|+!46{9;`Zsx1hzv2&Ky=K)R;`^IAh0oQH%LPs#gSd z^qcp7`xWezfE%*9X?Mc-VV(}QZ_Dq(oWa><&Yaa+nzy0&mMSREV~CLX#8$vv+IHv{)^4U|?o z34Ny#9XGsX)&ytnpJ0gUAf}hkQWGJ4a@EnzTL`cH(COmJ#a{}^>#xr1K0{*VX-_yol zEZ*W_9ROF%gx@|nLViObAQwHa;5?QU=7H60Ma=}eVAwOkb1Wug>^T-xk0gWGGZ_hZ zbNH(a-W>1?upS{Y{>lc7c$qMN{Pj0sp(ZR6ed#BqdVn!pw& zunqpUF<~7{SQq^5V#0cuu)g@)7qCIrBjhnWkHp`}_{-jBn(y<>_b1KwW#;=c=KETQ z3D{@?UNYZzneVTf@2{EfN6q)Q&G+}r_p|2vr;u8N^$59+zp?mx+kC%kzCSSEoyNN; ziJvrST5#?0%Pp@-0 zD{qP+0g(-&NeisK$*cq18Wr&IM_j4LiCdkOYR{8@UFVr5pMzqUu-c;&;@xqq! zk-av6tKAUgKqXmg{*%p=83b5s6|@Ow0B9pU&%|H}M?QMj~&t zA4EK{J@2~y=lYhcPORhhQCjml`PHRho?R{LPY33-8-aV*e>vossIr%XRyM4TC_Sx^pt@KaTq6jdutiMsz? zRhk@ED@~32`)XAhT#uSK4Jq*Y+Uotzz6Ommx~6XnVR#a>qG5K(FAYSbc{2t zEL;x9Is#i>z)zt0_y6`T?K)HGd*;lUO1}^2?~i&k^nmFC8P9*SrwLV0wPB8jwKFmb zB}2KuQ2?B+W;~iAU*5yQO3i<;bN>GiAbIi`^1MFI_;IiY=e8P<{{rv+A586cj>q~d5$cK$5=Sm_wS5-f=NwMpe z9A|d_E+93I!Q{zRdevWc;1f0e<4Q^cYV==f(_t>qeN9Eo5rbeuh8l`!*cBSUm2;?J zR~QV4a{#k>0fyhh@LTc1Jf>D!6_mjp|0sm)C^Y5~g=`F!JBrBDOTe zfEp3hco2p9P+yZAe2xS)NYlQHlSiR6dn}HZL(Rvr@p46V;lLQ8fRo?lc#{=(;rs-7 zVvTIXAKAnpYORy)vjn-qM7+u-N0^WMY;vmcSn-`r9w^zp*sk&bYe0Oo6krvl=y*9T zJ03wh<0gGd9wXbyW1oJiuhj=?qZ`Qy`1mghlU$OrLXL*ZR;M6|Rk1}eB)v|-6DY`6 z8LA7St!vguSt-=&U#H~sWZ9Nhv%)&%Sa?$$DUj-x3s064D>f#}y)n|6sLh-jNs%*s z=^CeaV({P-qK@D5w00@-NfM-4QspP{=jl{=rUab`)GSTp%zhZ*O}X<1<-&GrSDiF} z-d?8W)lG|GZK*_~qq^~F>zcSVOS{*kN;_klRy`IsmE+J>Oxv7xz4SEcJ?G}iKbQ)Vu>di!UL>7)@NYMj)hZd4#_MG& zS(GL}W7c~u4F}Z?5~9+p9?Pm9x1`H$GQ6+{A*yzp5=BK+YZ<|hS<6EF_PVVUoFV7s z!N}H7sIaeN&v$ka%~|%85mPX(}FYq@3b&1j2CQXR#XCH z|KMmXuwb#HTBg@Bc>^+;Dp^&JDOvJsW*7W1OKv6RdO&>P7zp$49LjeiNPFGZ$Jv~GlnIk8Vkcw3~ay0eqT0dM~ zFyAAr;Zg0)mU4`kn_BU0OL>WCk(1iXYTKlK+N4}LP82gMp3jv>i=F(0Ct>;irLyiE zgPTCx3Z=pb+;+W0STFnw-soB3itvk|vkFzkk0>mHGPXSAidi^Zh;WEFP?Sruu<1t) z)XwJ1G1^!8vVVrlA<4 zGjaH+3+^=@E=x<-u;{(a7erix)V?Q4?Ffc{; z4h!;43JD2OEe*v!$-(#&5`y2({mDtH8Wa-N(4vY@hTwN_NJt|^4c3EwQvw4mem?9s zS>V?=Fi7Pus(jIZeUpJ4Bm+*dr3w56u?HhT??EA&6BUpI{G;ldz^7lAVxcw`o!rd1K3h zneB$@%NMls`TK9NZCH~qG5_zsecCznWy9LdY#&}a3^U4t0Y#p-5cej&NtPa`pZeLe zXaFf_)oNG|?b|N$?sV(8vcQ);E}R;%!k-ZT6(dev@OU|}Y@D@z;^bu8()iamPg)pG zNch4@n_rJ#YD=DsgF+Rji!o9sdEf(87(NWO#;(fAh)cE@%A>GvKpAl{N+A0hlnX-! zmh9TqZn90bWf3Vs^X@LUuSeoUe`%o?je5AXey(h#cYQoMdNl9dq=Bf7?Jmby=oI}c zoPM0DJ=a}s9g;5|YSAsDPl%*{R4*VTf zpceFri<`Zi!U&C?_*h=Z`0-Pc60oEA=Miak?+ENx3eIUVt!F|+L+{v;Bt)O4e?bz- zO8w@@Snq}r2|cGZ$q5c>n;+qAPlHbdYxoL@QWi?q?c-88Brh9Q)Q*80!NBEs znvoq68mtC|rey~tgdnJDR(2W-zhgt3@JyS$YhqAQc@Pn@BLY*X|N5cfLDrU9t=`XMDQt@n0IhR;t*g>#_K%C8qiB)54!P+;y04AnAKE(9^3?b(P0tH2`SU~Y(-j$i)4_zIz@_AEPZ zJRB^A@`ge`0}>RGjS>oiiK{k6YSyk;jgR+nEb3{swBOx2CV1e3qHsO2e*v|Qp6#7P z-x&_@W_tQZx%lj zZF9t?Tpge|5B9*Rez8yc)J|;&4B37xsY$ARuQsKJe7NnU7hm>l`-JZD+uBSAy2$bveX4TVa`$P~fv^ zpAV634%*wlmFH~F)IlBlk4x(Mp^vz-U^5BTpB&V{kMtUy9~}FuSG`!epGbKr$t?*b zIig>^X+`>VNnDW8YYzg_zOG2qnwI#GZbkYUDo^e*<||)MafT?b8@*k0>3_&%QensK zI1?r9i)nsH7T+i;D$*AapO5mh#}6nP)GyUj5R(c7Z7pUN<+Tc@ z4ac_3NK=0$hGvEYsn+O> zwmsWNN7%y?cf<_NiSkxsk`ud>wh#96YS5@bDmDtEm}3X-;@zY{t(4K-t9k3|0|p5-mmZ5_d2;tvWW*)7b=zx zmrqf-R2U?T(n?3marH2|K}T_BGc+hJHZ!XgQQ+UfU}9iiKU!`d6fOEB<*6;oq|(t7 zOE##v4ShFA+Ha%fmSKsFTX;0Q-E>{yj211Yb$M>!+X-TeyxlSXhqUhijH9?3zS+Iq zE4tqAbSGUu^{!LzU6$o88@cyx8EkOHXKZ8KZ47t~HpUHO8`K&CHuLrgb5e*?av$>KhbNz&3780RJXn z(>DG~DPeyC^q<~Ly`l5>zefa|LQp_NN=gxVzX@Ly5qS^Kx%aW<6TQdfh5GUPkRMkW z0RT5JxPtii11k{9!}B2k;L8i|x$>~#`WeC(|~D8GrwFywYp17mnSbC zubw@2{j;5;9^F1_o_4}Q`*L_{xORee-l!dqb~4FJsZLL4XYcya(>0^#rQnyQo-yhf zW7a(0*?E5R=qX8K<~!givu7z)54(!!P1M`qaWHZLAz&j9Tr=(BPhLAkdOn~6>~}zZ zu!VeLSVRJa#HmJD>F55QMUSE&aMvU32==#dkhc9GtSWzvrnARb9eaZ4`a@@v9!*3e z^$l|imWk<=i)cE04u4q)af(7;K*?UVjVsxKE}-D|>^*4a_y0vx*%Rz;CHoVasS$K{q*FCx8MH9-Cuu$I@k-}e0}!@ z9s47(fnbqnJ(7XH1?$FNvX?1nI|SPloY1(N)_`*WuJ{aafv*ZBl+mXJEs4*4i!>!c z;%mOy&%fiEIZ1%w{O!Zr?_b*=;iN0Uf+Zcd$26fzgx+^ zuyVzUm8j|Z6-ma^e)Sdnn=h11uooGf?;o< z-~=&rT1$4ZAD_9YZ1L8qC-$S2o28Ukx&^Jc?fBHKi%U11WQyEmWIE> zkGRiNbbEI z?z`>PSJ`*xkL(~G-SXrX_(!ZJ(lghMclno`y8YExZ{I(EOwuU_o392 zTS5nNtUk5BaOL%%=9-cVuivuKG8Ofd-`+l=&XKZzLO8GW-P=YL0th+F4MlAazH$dMeC_7;wa59>#2;8 z{Z%52zNKe=$bR+PNs|xs`EPyxZfFa;z3T3Yt(@v_eqBKyIP5zMZZ*4^x9u&M=x4+a2OhB_FyauBm~Gi4897ljEdgc1qNF-lA#xGL61pn_r# zcqnLy1(u>L?7k}veUaT4RHEBt-K9B4WLY~?yH$CuMumSt@VIXVo!MlRis9lqxjp@D z&&bRwYekl!+d6-y=N8Apu|akMp&%CrSRE1vj3aY0b>h!0GgfcDiT!n7PpPr|D9Wi_ zLGIC+QgTKk=O34@b-F{$m@SmawW!fObN0Xf(P3$Am+uola0mO+hN2=wmZ0@Wxw(Bw zhr5^ALVYJrcSB&T5_}67?k%|g3JsqA9tU8q7U^-&&pf}Ka!#olGhu=y6Amm{xIP_M zHLahzIB)TF$#YbBvy)o<3rf$5rN*XAdWLU>UEV6GM!zjWtLTy0;?Dy2WR2OcM(jC& z902#O`UTwmzF@R{9HRcXbU{W&h#9qmvcZy4?}8na8rCpi?w$n(n+U-bzu+Y_!-Nn% zK_8#gN0LD6ED+B$MJl%_$<1HPuWl46!ZOFD$TKe*H<&XVxE73 zedW?aojZU1*5pyo-FWP-@N2i$Uw7z1rg|Th3=zyG?W2~WG>`#(p;=oPEHvo}DgZ0l zUTrYoej=M9&))ip!4ZC#EJeqa$Cz(!rOd=R86)3MeML6`@YEYmA4ithfn0fsGrPl_?5&(6#kUt|5Ea<;#k zsb#2?k);KN(tBLVGjD_K%6Bv;l~m0}Ge)sf>+6EzBWVAvUiR{0&$(<`wwOKEiB8tJ zV89f^Win2BFU+azu)y4iFC)YoBjF}@=A*B~CKYy@TpiTQ43#x(P`eIN*@0n#%KYLW zWtLQdPY5Pq%+%%5^kG7jdnZ*eY>0Nf1w;mLR0HzS&ptCexMt1W>?U?!mVbQpKP*+VhfC{2cTuj^pARmK3{h%3IHsHg zNR@pjP8lXrXB+~`4HwGC4pAAyCbRM|Wur<&?V_nn)?q4Nz+eKY*m;=B8#WA|9j0=J z4MXkSl+~UL3Kj+%kO2fC)rQCY$L^*a!v^W^cY{<9lXy(t5y}kF`2w(AS5z`s65-CP z0ZOBv!Cw5COjT3-(zbsFN^{>DIjVKUe(z%TviICop`>|z(ks4)dYpuNJ6f5ik5hgf zUbcb-tpanf5QZr5;nECof+{ntdtz6JCXd{5cWC30TaJ))Xx9_#nNjdY_qrYY^A|r#@bCSw7h+(U>h@L^c3_i|W zumDQ>v-OlnVcLI&QZUobP!L4`Hehh)#va!jQteP&dmoj8t5KbzJj|$jsVoJqA##{H z(o}pMOnh>1mG9n5rC2gD>?uY)3PLl?xR*|_>N77b)sMD+9 z{@L3^Og}Wx(-dax8A>;x(S&e4eTFK;{_|8`4l)K%i44ImA%8BcMq@8JMCAjwKg_sFK(|mY z<{4z-O9y27{C47Z%%t;FQDOK6CoxtWJ`_GICdRYROv*QMpY{vTO+Lj$4NS~2aYs{!q*@l@w6)3K>S)2Zes5&pF(upT(9w$pt)&?eWuu_ zslT~{xCXQ_IIV8H{3ZD&^&Tu^n84u2TLNJDKW-fYJbv6V1nCXa{%Is-v{*7s<_wG3 zC_b5znRMy)dPi-ZyKbyC*J8@6SydN8y}q6~xsCq9oNH!|$u0I2dfnhKBN2O(23@b; zv5ykBrC4Z^*c0G&MMC`3Cd2&u~>5~mK>`k2X=MGKPQ2e#L%?4CHNZm8L(73`Ab; z1JkG7Ka)h7@JQ&)jB~$wAU_u&{Y%cWKNT1D-E>o5(N|<;-*X)u+;8&73~O57ZyKv> zT3R+Vlfk~^qU{|(RG!b6DQq$>PYvb&NA_HbFL{U zxMt4eygWAhFnZemx4W2a-#>g}%U+aEe6Ktt@njx8cVxnZBj*lhI-yZO@fm=83qY=h z!Du?b9)Y8n14M;<9P98{E-ngzb3zi3fGa_bJh||-BoO(Zi;A%+ZN^cc@c$ZA2*y4v zc18ZDBBL6_Eg(T#cU{`PxwGv)N!rex!%^X z)6|vMwbrI>4J=ZHHYgXQZBDOg4XvouOda3q;ofU1SG3lpZ}l%yhc>7d1U6?7Uv0m% zb0^f!Zr{$T0&QHat%0<*KzJQj(_+=eka8hc6RxPgp^8XF@LIJnuqC6eHU2fm6l})1 z{8b0-qdox7mJ+t>nqgMqg7_bq5Hh(KjF=jjVT{K2@^Peu1wDE=>v?eZC%2x*jD3X4 zW;VhK-#CdIL>Jb6z>@BQh=UG?)`|YTEW{J<5-C-jXLU1)zvm?Z>Y}mml|ePyC!68Xwon3xOIf|#u<0D$T!W~R${wO z?$4{%EOJ%POy8<++R(5~I^x!eJLN5REnHzM**3qNS^p^PcCuKQV~b5AbyYt#j#v9l3*7%Z34H3 z--mtO@QpF`QdyPQi$lSNBG|QI#={f0TLbht{{^-f!CDEwnBMRD0|kMX%AtlGy_6Gt zMa=nLs!|gym^=HR3Vlqg?wmc>YAa#TW0V&>Jhu6B!xxZyRZaB`?lae|bSgZh+t7{@ zmm>A!bI4s@QCnA8?!Nz%)FfAM$F`s+$+_Y>B7>Rt7?moXZ%r;`c0NXxtGl|y;^r0=1-4NnPpwsSrjEB9)9}ihlxspC^aPKRL{L0-7vd4JK0b|SDl|Vd-kmJ z)shl}ExTs+s_W;}sWcqZ|~VsUkokUcCm!LVo78$6@c-zaOV26w#(C5^nGaue=wu*0hnjHuF+|L}#%b(kHeRGgTQ=5oE$Ns@Oe{IGT$!@y z?9GdP>if{LX&KCy7pYVteF~#|f+}Tx`vmoe&_1BN7sBV`5P7p8HsE%wBun_<;XorC z1qRO?IkhQ}5uQtoFkOe3C*1#HS20%a{S@T0>%p^(=^3dE-r}t;5l-N%DE5b9%Hj9; zIoBv=mBIqD+i$X1On&Znz@FN%V8-~a#wM@F<87+#&aQ+5IbR)MA3XqLqrNmh`lfT< ztg-pGlvcJBS7*YQ1!Grkd09hMNv_@FvEOfVL&^5i{H$HMA^ae>xF$YhJz17fTv1nF zQJevP>+33ti4Kj*~*E%wZu zN?b!_POimbEUU-G8jtD~Pz(y_uP<$w00kOCrID=A2$vO%jwZOFWfk>%*pO8SI}ooG zZ3L3wH60!`fESDzu#x;AE})J0v1|~s-Fly162M_DqbTQ`%uo;amm^n*rx1`AGW+x} z4B$9=I0+*-PY6iE(kF3ORb}n!oXlivUQSwlRZVqOw$<-XM$Rm&-)GBe4AxZDWMZ@*=8-Ro_b+gT~SH(lqpju z)|T3=w(Oj$%9^^$vVv@jm9Rd*7L@&kebD7?9XDn2HIuvRtJ8fxl}@Yn`2y9gXEz3`t7FJlRr?60fB|^fVlf;kt#2=gm7~TWM|*Kd zr;4C49_L-nRT(~?!k|<0LNZuH)Hep}utd~_f&&QHwnBsH)6~N^wmk z7I-lG(_r~qkSLzI@v?OP!W|1yBghj6_^%i4?CS$nkQ0iLOh{rW206{o0JHp6_5}5{ zL(JahLmlqIhck0P9cj~^K@ z7jFbQ7IAbO1*pJhUyUZ_FWepN6vXTz+uOtS)YeOHpsKe>-ri+>ln=Waz>J zRaaAk&*On4-&JPAvy>?m=~SlOVzJ~3!yTlsY(fM@4Sh`f9B?P@6+SSAZ9e>ojy}Aw z3ATk9hd?R}fF~f}!|D${2`mV%3To5)2PT9#_!5B!z#3%}4!r-sVlL&(6Mdxeh;4lGU3z; zi*-s2WgIxg86rGoz|j*0k_WMw7#fHxHU%9Hqut_O2)GR$W`6fQLe_>q)U|)R0Q?c+=9o?o_+x zUYk8HSXtB7TvHj$v)lMoa~qe!12tURw3`|Upd^DsKQtF&T!YyZnN+w3o0ed3C+0-Z z8`wtxA8y-BBwNW~R`f)&1cY%Kvf^=@c-^QD*=%ZjvcR2g!8p*^0SD=ly;50K>xlA( zoPuPVEx91S7N=xVc)G8uHlKf((@;L5wMw>8mF{slF%GoJP8XD=jcTa#h*70htBjT; z_)U0HJvGfEE8I@C&c8@%)QEKdB$X-TnRLO8J>Y&`0wXNcE=Q^ExrdphUUg)^bdOW#ut zA{Q3zzNHMDwnAd&JP={Df2gr()u@eIF6s z5wwKTyc}NoxhY`7+{7V>Lk31r9J&s~BXsx$vD-$DcGG8p4Kbd;`GkUuZUSu!a1$LD zr@e+?Jj`=mj6MhA{-lI{lqk$Wo=akI!f{YB?5Jg*rxgMh4SXLoDmlS)9cugDxE0yp>q&Wc7&d5xXT-GtI&QYCnG^g58H?3pS`&(vpHh7xR zOU<5!&ROWXeGg@Hwz~qG9QpZ+>4d!w*#?w@yU(1q85h63I&p_}O? zlmYgZt`Xe{t-$FI>?$!DnEE$iKrJkQQ)Ggo;b+EN6zNF6v1W=>O!zzj4(nicnSK4` zgfRCpDi6*lB$`7&eZoLQzWmmTUxe%#Bq38;&0c$^*Xy+z%{qnBV)ZyOJih9g-9D8` zrzc46-K32jNhq^CPT=qH7eBX zM5VHu(p;S`x80^u@rgh~*SutZl2V!EPoCA?5OAfL?C?rsv%4W9mk3GZqYo@XJ@1WK zn)TCX(aK}mLD#C3Dm8?n(Wv1I_g$yQ-_er3nu+_fs#PkfNn`b-I&4ObQmHZ<-Kico zpK{A=dZWgux5?Z}jnU>vb$e3XMzc!Er##k>#w1m#sd0hPnBb3nWb#;<3}R0)hLopNQD( zj1m}32#=euF)CRDa)b1|NgUD69rZbT{n$AL4uevr&?!@Gt*stsvR$swD^jh#>hYZ> zg%ZSv)XPID(#-Ce)jm(A-D|NZ6*^rJ2plBLR;7%f1J(yugdaDmWf~=1P$IWz&BhG1 zS`G=7)TT8XVAp@-om#ImaqkqAM5WOg3@Y)cS4X5f$IkH>)U-}vc6pNhc94i9xz(29 zPPJtur&!e1S?)#<9Fs*VQA?7@fK{EOGMSxDx7+0`P^puYCX3Uovr#G;JzlDkTJ&0j zTC0#rX^;+`NvBomlH^hJB>-LQ79=&r&K|hAd^Ci6R-{G(>JK!ljE0x`)WUE zx;X6e>w;3f0J+f@FoLaVX_n{*@G8(-) z6?6SNRG`~uNJdAhO`y6`i4KwQcvRYZuNaillbm zvbwSQ;L=;RAHI9{=2gooD=JE_>)E;e*g;4wFR!T3)pzCPX1bYwzC&e{Iw@N0G-(z2 z*~MPJLaqyz*Ta5LSgh{?=O0`v2mV+)Y;0?XLuuF}3rGq0u#RCyze^d_7+t;ylS6z$ zY;mWg#?FB8id8(415q0-gwE8sXbNRW^?I)}-yr?BH#>7dX12Gvu%xtL8_FPLt{Qf~ zN|o>Q>hxLwS(QHdjO-Z(yjfx~bm6FP(2qRC4 z-8ZjYHGAf~c(TkHKmd*$KpY829pKRW-lJNPWQ6Dih-~kLp~( zhDrX>*OU^EGxVRSnaYyd#`5AxZNVJWs4ZmH{F!q1-u-9T{TMRBRLKqIR-tGdSR@g@ ze=aCX9KFc^t2LO3Pz_QOdLP37C}aXWAQA37l7Okg>qV?gg}D+IWUOp?8HQDSs3bu7 zq;S--!kiKewwblSoN%^y`bGiJv@H;zLW4TqdD6 zxD2KHN)4_Jv_vMKz-T@J+W~ypDvbv06xO(J3YalhOYkzc1mW+T+TkcE43~J&^kP!;<0))A!g(p5 zEJ-bwNWU_*1%oN(3PM6LPksXSY@H9Io}(olHgm|90QG=|aPzZVMpIImN{%V4gWzao z@}%&y6c}GLQDL!{1Y6BtODVZV5ww1f#6D#7VaqI{ zJ|m7N&Svu&k(biJNo>joXZ7*sb^PHLDS00OXz_pBok60Xjic;y6DN0q6oTh21 zG)bilr6_eOil__U5q^(-_fGRU!U4yp4iC_xoJvJ=*tYN|=ZH4cID@>F{c4!+px{Ts4PAOyqK1`|3^0?y)&^TaND$B4T^NuV zA929C9Key-P{llHG+?IWQp_`drLL1YpnYJu5~kua%36w^4;a!w@R0SJxidnxBy;%2 zbr}Z>O3Y=g&9g{b?HXi2cmJ|oN}6=Z;gkM3vZOwOP_wM_Q8jqxxFVj-$3(*+n z%fC?>gokFVpHrQLUdJr@oN6HmKl9M%l(+XC{4g{I8t$J2LHw!+X)F3K0>jIf7!N8q zh~7V5f?I$Z=^4pMyB+_qEl}7}XMLm5t3 zDH|gO0oGcAIAdKE(bqh0gRRS9iCOdmoLu0I;0UJxmUy8TbbGWKtQE*KgT<@TSmbGG z29w`eo>N|$7xel~21vio>o3eLFNKwDIm|WF z3vz1>$u6bFDi0V9At>q%=3bY}*JBLGtr{gfugNP6sGuG{+<^?&sJXy8focl!%B!*q z{Bj*_NGr%A?G0IQa66jIX&;m;Kd&a*Sc0}j;Kqgtv@vjnzNZ-sy%WEsmXIOXRjQBB zp*X^hg@PnT$T;!PZow+WHtOMByO&&FTvk@Te8tw?#Fr71MzAm|m#x~o`|e}gclKOY zS^?T^B3O^psqbOKPz^72m^8+S#wv6RtL+iG^Y?_qKrjR-Xztu86WiNh0oOgUdGh3W z^CnMj9_jY^{B7+Mr?9)P2&muJ-r9Z5!g*6BjBE|~{ejkz6Q;}yExe|?wcY2xN-y#* ze+3(#{sr3w@u3RXRz`vKLFwW0B81H+0 z{}lQzd0PvyxwiA7*c7yx&t+74|RnS4BqcVrK65lv&q5ALzGP znH}F#w&WN~UN9shcBF{;)%VnP?GpBOq5~}fcR>Vxrt1f)TssI>=GYHZt|}Hd^daN= zf$}nYexw||sqhPp*OF!}Yy{WK5ZwKQK1Qp#x3wl&`V>B9c+~Go*Tr{Wtrs*N`&& z8DV4p{TlPsf2j{cE+3pX@o8ZXp-&GXp1@4hl6tM)M=F7AaEF#Y8^MjP-?1O8A{yEE z*uS8=*0FzCwThjGJgdULf&d_??7Vd-b=9hS(3X?v7Iw`^cKto~ucM5c|PuLed14end)o1DB{ug1iUTU2-l{aQ+mW{&?<>O;c>j!iPB$rmFPZ z*Mb@@GzXsC!-x4YOciUuCnVoIM*;q*d7JPk&g8OG0rzyv90es-%-JkYf~P$!b(D07 z9>?n)sZ91|>ZCSqbi@hf!^_lmL)>TxW23>S)84U)-qxmv8QvmbL+t#+ninf&EUIw# zHK+ls#v>**+&al=Vf+%S>VO~i>Y4b=IL&;kqEk4r=Bp?nzR%5ntY_R59qc(@);eWk zW=m<_qT1lt(_@3Ri}G?u=Z~4vx(qgN>!wUxe7-C%FYj?abJmiMN&T6}PwK?E3p;Yh z;oO-H{p5*@9}W^mrZGE=I+zOs%f= zl|n$5yzF$d(WuY%mF8AElJi{IdZW>to}E`vQJq`r%hQ18LlsTqx7L6koI2IH<(}BQ z73or%D;bIu#V=`b(iN7t^u-#p*^n6s=2w>&<>vUUaGKkllUr0#l^+ab8lWYAewN$k zcL^zYS6-c8?r|H%#$+#_ioDBGsqi~U)pG^;YEUd<%ya^{C?)#Q9*%Fe10Dd+zH@!*eL#Z%n#5Z!n2NOrIvG`$;5B3D-(6C_g)Dtq8 zf${N27(YQ!V6KYu=y@3teA#?a5PZxLWH+VM#C-=mP@ZM}e7XfSiMwi+K&R1IH%3mBa100*>ar8<=yj;e{u?m}8Nk8yeorn` z!KWk5V7cOZ5%GkV@Wv^JO$=%TqY$kOYU7cNAM?OLLwpnHwML_J+OskWd}^UkPI^qCkjtIs%gD~kNOL(gP_L&TLnsB+p=S)5 zJxSosSE!Up3b_pKYDAP+MyoEUk{)xZjNqn_%ZsD2hln z8B66!a+A?!t+d*V&kxZYqU>BNhR4ER`Ef z0BfbqW-tK>=UCv0LT)nHY?T(9$z+fR%|;s$;&}l|LU97l%{YDOS(%v`=}wnMqtSW` z$2wDWu;!QQ99!rIVrpFW?6hoOL7HEqaeI7eIR)M{XNp0GNuQOTs1!`{pp-K`Ju53S z-K&e1a%(iKJ(Q%ppaf#@*pn#~pw<;KTF#TeV6&z=lC2;J@+5=GMXcs104VBzY6Jo( zR1YaBKm|ttT!lualu>flr`PV0!-6PZXFu~OFR0{?yHtiGxxr`(S(6>9R-1uio+Mx% zBlnnpY6RZV>vqa1aG-N=@pVu#O8Mp$R_$3Y7B*>;5_2s4aGWL8eoD|U`}7W*6=V!5 zG?=V5hrZs2W$(8>kiD4aDLUV8IpI?S$@n@HawP~KXX6RW9S#T$GDWn6GpU8mBT1l9 zB2!m=%q;B_C2ejs8I7jQ%;Lheg~gefk;L+ejU$6)&eYVDin8|Baq+4C*&Mgl)1P9B zRkV9#VR2rMO$SqE4bkbMYUX<)|s%)9!~S%n1;S$A09g>SkwBinTE@PnJf!kPT1|t zd;JX`3w42%UwND8r@Z!ANnpG2?0DvrT{*K`~Ps8J@>X!M30gGr^MWy!AW(yGQrG(FVw*pr{X zSn$)jOU>^s8b7Y%>$r(*wu{uJ|2)1 z7@Y-TM7Uc>8YE&ufN>rBBM(~klAK(>&j3F@e{Rl_?0g>vo&DjlSRmsdCLVb1*tpF+ zn7EiPKQ|c6&G+F-j9%Q8En|c)}CBa z+*Eg0U1PA=VYfSqgN=}ADlSR3Kg&+P|C@hZ`_PEy#$Ztjepl4o(AnA0T!eF`6a^cb zM_lOn7qlHhlP(9QCC^j~)84SB(|0CUDem&mK&a-OF861x#G|M1WSjNMDGGB}|)=QxJ) zcw$e0<;0xv(w)qIy>xS-3SPTR;4ueF%mrCA1S}AYW+0N$0rvdO^>v$Q?U!ujpFjHK zlYjj6<4@2l=vh(kG9UdsoK%HPd0?7VLBw+m6Z{2lbum^YaQf10sz64t(BLc9G3Z$1 z?yl~hWjWbhyBpv5?}YKe;=NT>dzOr!@ZUF{oV5Ethxa5~TUze^&+bWk+uJ_)_Kvdh zy(^h-K4@?6-4&qcCs7W#_PUw*wt{vthC*7)R94c(%-BNOz%Z52(c24Y4f9&Z z+2sTD{d5&<28GRUToE4^)&u&6KNtm^;(<6H7*@e1B$$#)y4=O46GdV9lzWb(cc!M) zH!L1KX8eqqXPYlB>#--d85S?O$lO{*myiu9E$ z>+9C8`KV*mXgI_(@!+V@?d@B3-nzP`X4BgGj*cl~Cy#EqxM=ZpY!wG$dU%bsvvcM7 znKNPY>)}8e#F|=ES#fh-ZugW~Ds{>}vsyWB{GK`6NErszp~EMm`!VN)V~cGVT9*>R zW$h5Sg}ZE{m;*%hA-ez_%=rD;v&X`JMVVY{>aW6^$fUmSx3Zrh+hOuwT%B>*Ia_uJ1-p0PCpy_2xpLpgioApGxPQU-g_4}cNZ3jevs>TfPHI8ZSBS-OKWRtYTu|@UwL%GctvhYOV@=33*UX@ z)uqd}-tuwPdUhHISXy}Ji1tkz4~!VGaZ~#U^wVvQlqE~vZSwn;F8kGEAKr5hgd29; zciI9su@7Ptuc)2_QA*)R9LU9^gDEJZbsV=#XEa^9OYA{6a~(9|t+7$cWx^4mPOxDx zs^KbT2@R4M=_0H!78eDbz(6+Qtb|8vExJ_3-mq1N>sYSg`UXH0Pz23$CxL ze}i55#+I^`3m4pQ!-9n?^SGX6hqJ1x->#~zu3o&Px~j>xXa3$(r}oa@V@rlhP9L~< z@qrabkZsC>1yiOjSb$#Rx~Glhtx8zMUc|wdha%ix0_Fgg1^^FpyjH^}@hXKNu6T~d zi)dQ-z6kDfT3WjvnZMxO3$HC*x^?Tva2|~1XtNZ^R9oB5L7Q<&g;Brwy+)sJ$x@8^ zBkb$!XJ<|;6od{abW{6?5$!htiO4%RbTaQ%&|{KdsSOxjVl2^e$R8s?`!?Tn$AQ(j z$_Yu^wuwFd+kAc3QckXn9iKFa$c`Kol?Xw3xS0lr9pqqkD2P&`9h?W0E>oOrZx!st;QAFWwiSI-u3K&6w`M*FL zWvrS=J_fhl_e3yVLmN3v=SMN^;?|~kHG~C%)5S)ti~BiF0#~zfeM=!64WMzb;^`XM z(K_z%h!tKy7Aek9<`GQ_JOErgMbg@e;b;E(`3r>2dLaQMdBTJ%7}`l^p_*}81$tB<_9 zaKVMHmX=(__z6cV*H^L0T-VdcOss@Pj5xq6A&ceo8TPO2AMd&6!^eKLY^l%R^zM=+ zDGqc$MzY-;MGwsd@r0}M3Q;kKSw|9ji>PK7oJJ3Y-{N{Kt=)F%1M$43Fh`)QsDvw_ zY#wK{L`GK-Y_Kr{csr`eiP6iPuA@`1=CS&(SqUnq;WMm#a#wD71MPaFzV3QZK8Us&mK#zT`N= z>y*%#Eu1=l9BY?Y?c{KZ@0?puFlX+ZIRyo9Vbzo4CrlWR>d#KN^ci~g*i8>#IKYD? zeskU0AHVxPJ%DmqFE%e_Bu?y;E-u;%crNE8oaJjV+RR$Wmm-cK} zvvT3I?wp*QjA>ohLW+5?oi@=u%QmjPc46=D+v&#;rWJRo4(N*#>@CLD3^+@JSaF*p zlqT$5I!#xizEe$7t zi!jR2OnNljX^!uHrzIF^E({}v$R(gKLXTosKbbJ(CVF)5A)f|rF-?a9U2wc8d|Ib> zr{-ql=V#=my7f9@k~+knZ$jr(8s8ye)7)Rp?GEU{tAr01V zqYre?{S^n;eV1RLR*G+jBfJ0@U!}KiCw3B#H+Lo=Bs&xEXZHp=0Us#W61b+dss3K^?R!o%w6t^w%)XWk!YMg?M2dVM#?6BF+v?P- z|H|HuUYRxKdN#~COk&+9%vdtxv*W{bdDI)G%U zbS3#$i1d-eeBDW>fWMQ69WMg#-x=E|+BH+B*Xw+<`ub-1@Hb+Uzr058g|8;(ypE1} z9>3mU_2icO1DV+ch1r>be_nUpKjC{}K{f~}=DFjji!LC40Wl0fk>M+o`WHPQwj(zf z-8PCY$MFW3S4YvFT9Skffl>+knN$LPY;iZ-4JD>lSrh*94RfM zNU9s(pd*nY8!Wg}G)XdfqiIh_BBd$VWG|*D=><9LJ0NKVc$Ge-4e(#5f_h14hm>Cc zKP}`UDH>X%l4d7~W&BG@{4G{zqT`}}(gk8Yj+GWw!$49!oCq*6_A#_gypJUB zV#>$R_7FUp$ah#Hky27&)QGs3^9}Y+r1j zrBE0)V{!-)<65QAQ4)0PDPZ$yqL3ao5n*kMdEA46$Bu?vgzq>(9-IU_8{Xj=HSCUd zVPw#ww~gD?zC=FusK2Gfe{`&TN$Z|*;g=TbEvXrOZ;^jpR<2blwdKp;w)u>VREwV2 zG-|@$GnW5583+agC;!iK^7aYgH>)bzTj%WAqev(Brl;@OGpDt^qKZ+CqpL&U>+FS{ zDC=k)+*1gqKBP}VdI6V)O+Ea3@>NI&lF|^w>Wa-r{)&5^9(m5?M_CXvZW3Lqk*L4K z-*Fu%i}-+;B$o5fh!6Uog>c3IpE3TW=oB#t{gHnrx{oh_pAF0(`wkl5>LNb4V!4<+ zA(X{eKyIN7;`2Pz_&eWVhBK62GGiu|P%hh)zNIP^9;w`!K`)2Vx*LPYllpfJE91#r6m{F7y_YBK95TVBsC+Y7F$1^Y8#&IS&2^r0R;ME2^fCGF=$Qz47mjZ%!@62?-$!R%t7N#pZ?{f{e*_M#s$4zT#lLSCUlLF5KA;^6v* z$Q$As7b=X(C2x=nr{dw4;Yba965AlR^XQ_ zm4SC05DD^zh7i9fCK41HRAwkfyb@4+y+Hq;Q<$eQC$d*WYZOyg&MOW@Jr;tj4zpqb z@T)Wson0raKNKDNuc)(!1ZpU*7kKI_B;d#Yfh4$k;iwc`J?~&?h?e2z|A~iGA(Oy> zLi#E_0!&3obJen;n4x!|nEadu|Ch43{(%<7$zI^u3wc#Jt>3o#9PI&b%zpi{h$hB00?0E@;ne*(cpSwFcVWBE+gax zCIbs#&P?4@XG*|aT#o_mgBlfhM8II8JOk?!g(5>^qRc{t zJdLB+NR)SA#aAv9WkQhuI8{2RSMe1OFE8Ktu=0i?u2g~M!zvW(upE*c@qkCM7o(D) zvoQaQRWw4Of#{1bl(YCe{OqlukU445ywbrg427{bMl@ zqbfPnCTdi`lF(y;;}hkL2QZ42NZwFF^a~XaBtv`yJPLVWqI?sdCov`ka*FPY`2S-u zAoOk^7hk>NC~Bh(4Av7u{ZL=O|MzF3dN>UX#9pE@gY-Y2N$5$GUWp1{zRZ(=r}02T z^vcW}!7ldy4MtHs)BK!@1;DRdMyMatUr-=Fn*;)XT)hKPEDkCY>URtZMuA|h3O%_( zVXkaqDHzny5bX@q|5wF=P_e)dLOKx^1Wu3Vsi>$zS>FGDrNZ!z1L}Wi@akm~_<#5w zMbZAhG(7A&V(AZNG4vE`ticj75S5AY2wW{Ro+!`2diwo8i89BJ1;Yc3M|tAB0|A7* z{QNIb;{zcTdUd4+_%Z^6B?cnCUf%zERkZVs|D1{i@x4l!nDze{E*}o$0~z$nW#X|H z1q$Z>S7)}N3MVSd(^ycyR|X0siWwSIumAjf5(t$g!dSc%T$vPCTL1f*QgP*mh9FG{Z?oVy|LQ#&$nig~K>_XY?ZNzS zXcP(z^#9ke(6NL73`Kul^>X(7RmmXqh;JZqhvJzqTJO)0|7f8^7>ge(uADc97kK?I zpl0|zh?3+=WnvoQusDzu5&JJO$_9$j@Ea1;>oBkoUH|_Xg}_GOX)ZA6&nqin8`r_v zf5Y!t6z#)dIsyFy(H>Lwe;xma*W>uXC=odl*na|aJk*H_MVHYAiq&w+2w36TiKYK= z3JVPiG#pNuxCVLWWxvL~D*c59`G%tO|6dwTPzOK$U!4J?^#1t`U#aZRnE(I$h6ju1 zpgKZVFuw#E{~U%Kiq=EbaYg+zkD+Mh7L+qGpaQVY_tpSj{5If<;ZAwqF) za|1y%7VTAUB!~xD<=ODaxF^J2(0&X6u+KXo0FuE#z*g^)^T?}?YgL7$?6(SJXWuu& z^H3B*6Z;>eQ4l|!MzwJOuxfE9>a3x@#WkU$mt;t@skz)io8 zq{hG#YLVL5CsBLsvlc0F{?Vfs!%O3uB&_g^xGnA(#thL=6$L z?1Tr(!EuI=nGQhABkrsZF)ZxtZdd6KJ|4?;j+qG$2g zFBWIMTVV)h1RmZm^eziyoxM=B2v7D0i)gy42@EJy&k9!{m{u~gy13pm&!$dwjO z)f+wNxU{8Ad%H2%GO~W+IH?j%XMdxTHNzuANz2IgQRAcrG@0Fw{`kjb4-&*i^?~e4 zxvahUUWCX-l*B#SThvGp4bAtmW5chZ<7_`LAuQARTqF{JffYOv&{>ML(esO)(%EgWKG^uCXLvhfd zdi{i+!~55du%L{X7cD2*Dry4;n&)=$asawaR0W)Z5ywHt@ykGdh@M4;KE;WqNsobd z_k`xn8PVF(w0KQ>O@@V@5Tmfv6^&s`No$FYF%rRni#hU-D`P3Z%uQ9|zM>s$Sx zH57+;^F3?XzSR%mfiF7l8SW;VAn*C`cX6MtqSE8-0bO5v+)MJ5reO48_C=V841ks!Tn2!Ig$M!!;IpIy`hm5Jwvb%Z)wn8N z3uva)0JQd;%s6N>sxh?Jy}EF$mOYLE3iVqysKeYm^DWfIzIePnO-J4w2X5bPP5$V^ zs1$%DL|~GUKhggMp~Do1Q{4IjfXW6z2lx;Kd<017f*eAT;NyDu=JFIoKHc}twnZue zDW3e@=sC3|8KnwZ7Sb$MiN)GqKR0S_W0fmUEtk{(J$m#%h&aEbj3Cjk#@7XF{2p~{ z_>O0mu`YJjxVq9Bhg}CzxG*5$SpbNN2Ly~RBN`SUi%D(xi3lL|{g4a-Bs}ZrQFQR? zfG{)eqDO{|s8~k8FZ2#Y{KSf-m;QtQHb079f0UTZ-pbwv-%g>|;auH2m&Mcv;!|M5 zwuy5uKcS&jaH2o*{5^Q?m$$L_DO^MweNF{%exyc!iO528fs9 z3(!jZ{4z`YCej2cdWZcd^*+_f-LqNG{B%<6VvP4gOqE|8qMZc9Xnyq&UBO)5Bc>SD zVcHAPaE2=I)LF>0`7oV~OWkvrF7Gd8m7iyCJG+Z!K+1&Y1^lM+!dDL?jEq{pp8d&QcQ6AuA zSk1_Y_*Ue%FPm{;!K`zWrribcuI2le&3b6jPhs+zz8cICWa|*k&jC<%53&2svbW+$ z3h%%v()X!1fVU+ONg+!lGGqRR|9T-3DYNnvoxx%H6rDy81oPr4+Tj~sQR#hjIxbpp zADxMdPP>n`GdJExznuedw0tmAK_ZB$X%zX2y@-16Cl*5vk;L9-z3fd0?j!BHk-cfn zS@DC+pHI^{y=P9-tpr&Ck*&TvOIM&0Cii~2ffzN4S#dvI>!Il;@=Nxw*<*hE6Iwax zR2RAdkJs<8Yk;;pIi~9`r#{D*8+VSb(Q)Pe#O~-iHHqEzrys{;i+Ycrqss`%#mgl9 zCgo#Zd58|clm>tODf-p_aR1Y>57QpV0CCirwGY#ok*{Z?U*C;>m0#d8;L6G`(D(MP zc$A)kmN;<4HhfUttoM+hg)@=Xz()l0Tak;4K?FeugBo~2?yjpYuY38Or$#h2t$u&m z)|!!@yo_E%qQ1@H?d<+L?%2-~zcRHpZi2`zAtokmdz#4T{=qqKi1v`tco&!`2Wt!c^M@^ zMMcFTL!`tc#Y97;qN0ro6_bjTjFOZL3zG^xsAyztQIUs=iZ(JTN-`8ODl{@IwkWBk zqLzvZU255lS~7(HXYK=L`}BMM*Y!Nl<@LE|=6iqN?w6UlXAYh-eQ|wYaN_Eys8U)a z-o)3Pi;{2d|IYl-Oy~Q6S?y~RM-Aue0JtB9O=iV0as=m;i~n*zTxSVu|7xVY2AMHD zz?ggP($p(7ZSjR?7v8zWH2=Ki?drF;=4*GSmz_6f3G#$B-tO0(Q@xRAxK>rqpX55K z#f9j}$I6ez*`*^eE$wK2TAHC`X=!Q4%5AY;`~Ron{UFqJM)fn3U2(eS|AoJD&hlIN zwdi$@e{qW0-;2yQ(vAqwLmV^t*^-&Vw9`T)Ku(=LTD#zg_V7Rc(YHd+tFOPb^Xa~S zPw%VHlC)t@cbd*)2l`&sF3{&_7cA{KI_0~(TlB_3!zP-u`pS;>rM#&v z)q>-nIBWXHGvAyr*C_2xHB)<&^k4S{UH{acUP&$W5;y#HG0nlfQ;{2e>Bh{+T0KXz^D z<(I!+rr-H%X~hlKb$zGx@ zF_D)nO0JgS_BRIy_&Zzy-v@kufXM-w7!*E z;J*DYO^bf+RxRp3eINH_^N~W z)Z80WAIb8971*hx&@b1g>QkT7rye`R_hs5QT)rdJ@tR{hjpf%)1Ds}`{hPjjRMC(4 z1bILhsxrbk?BM?*NAm>vuD(~z&8pW772xMipPyZQYkw#I&!C+6Cser1qy1HVDP)?A ze5-O~s_sA9&)07tKc7qTRZ8yg$@@x_+}2N5a=yobVLaMDVXy&anv%OzLPrN0fWH0+ za!;836$rLL-&2E*j3LUv8j!31YA<{HzcTBTe5lV+n6G6Ew2!s-%+vtp&s9D@h8(pU z(07HYEB%uO{In1HACPkckTP~ZGd@l+4dV*&?CBL};lzxwz6ay7pTkHV#&(`|7+B{V` z;<~N^tnPmdx$US`$;bKhf9ukLmW}u6_h0M_Y)?9+Z%;ZB(oXgz%8=!IR0U&Y2afrz zWsj&?>KmFK`Qf<1RwcLRgwyPO^SHjLE4kgJ$hZ0AdkK)H!Qq z?#qT}cE2;g=}1!nsBryrphC(0ciZy*&OSfwE5XB>l={c$d&{+ z{e465TYz19?H~Fdko)gu{tpEB@q_@o{{=*!nx@fkM_gfG3ce?(0qI@s_x8=LcuTJbCGr?{cr`ZN2_cefi zvgN<|_xO|P9|Q=q9n)e}>vN?2ctQXY{lfqQ@__)41Wa~J)bfs%|5pPZAyMVu;ZfBC znV#iXKG*`s#QrILnS(7*a@B%CIRVOCPuQ>f{ai?$z)bc+TR9F8l zKouXtX8Yv7^IxUSGrz+BV|_y%;f8008e^C2B*0m!1$Mf2=OANa4-!#w@p{T84<`gZ{;wL)Kj{^;KY z7?7V3V3)pKw*NtZUHVwzw|xGG2JFJW=Z{)oS0FzjKotT0sE4Zlw*jgK8_+lJcMTYn zKi}ua-*=gn_9W7}jSyNeQ*|{JEHWzT(uD(af?B#7xv}37$;}460GDH;)b`Eu$;}P6 z+^0V%XOix4o$d_8?|LqMnmYc3)z&PYomeRIBG)g}2%9xSeQLosGHqP$njCn;j=xsd z*2L-E?ow{>MVSdzZUT8Fkql-qD6%uerCSEX`kk{%M+i+5FkwBgU_VR!jz?U`l!Q*!%e@AN;! zABn1&$SLDda{Fd)%kA%#$I*j*yB!znJeNCiy;r5Va?Yg3rW@xwn&`2`-6hDGy2^#! z!)KefaD7YExgA^9^06qDUEZ_BCt1OQ^a%`&Y_!ea&k2 zHxFDv161wuCInzKHXzTF6oc(rrqeez>_d& zmr-%ll`XK*P$o&x1f9ZZ@S1bq=rAc z@CgT%`@79|^y{77C@21=tXk8JVN#6@BIt4Ok?}$KveyLjyiEzeBF(6;}3rXOgPm)@fI$ zi8WBsFZ(dK-9D)tQ@ro2a?SQ^?EA~Wa%QJ7yYDYl46bJWqE<75w^CJWM`R|SxSH81 zZT~fsefR1Cx!lu#z$jJs{7N~hZq@33AokmzrRF#f8QyC*$-h!tYUI%cYVp9;%)ao~ z>f3%x$X+}kA52Kq4s^kfMh9}=@`_W)Sm=}M8z}x5nHKn_7FvJPDHCSIUsY4HJ*~ulS5RVg@3w26(r&9+uIcr~UugQ@ua7cD zk3795R?}uaVhp*ublE!bE?n*U@kW*d>Q=NR=77W(-k?LL0I$OcTQsuY5DG)s#cwre%3g3XP8y}ZKi94 z?(u)g{7M;eGxRA8@x{MF#aFdIAC+Gb4vqtLQ zk}rQlz{?f;_)Gm;e(8j#q0{Xzyq%>!l=q&x#x>Hr?N(Q$IWc;M)BD=3u6g=+fA6td zUFQVp_GQ629Wy_BPH0Y-{jIr^!@LW!TqpCxXTA@Zji&PZU;TdLs~TUwo15htt(V^I zEzWXH9DU#H5KTY*qQlSLluZh@FPEu*>wPcF72@%I)M$TJu3oV4qfdPP;qyM3_jE>a zU&o&=J9qL86`L-(E+VmJ#MJATmEL{H;#*hkHMJ?j0_HBfWYgvq!HsRlLr;oKIODXr z+iD^b({8yeC~^AMBwzRok6aS(H#DLqW!!Drw;B8AUwz?SBOUhhrs^SvXtMuK^H((j z^whu*eW`|Ssc#0@wZ56gcPH9Iy38lnJ{y#~OeIe}Q7(maU8}l4o})&9V^;->o?!b^ zpz4mbu1wA2ztebMO-57*J)lB}8+@+pT3={Kv%1Ky@X7VJ2j$K(B~L$5&S!Z;&0Xdc z27j&!z1BW9>@S~YlFd-RB%wZI_V|7bME#Y(z(|BlR%biE&gwhcg>RVT^ygL48rG5`}s%w$W z1=Hhak3Z$~Sy5A`&WH}1I4?SNWbCByn)Zz=Z<_l!*8-2GzkY`?(&ZNtdhV<X~88(1CA;_q@y^_vNr>)QF3L|v)r@8tA;x_92P%jZnj zLi$qr{<14MG3}F6CIp?6R&ey5#qMWah1=FfCHh&TH`csW#`BPxi$<5>eLCB<&7*pY zM-2$~Q_zm(tH1kUwSXbD!V|O8rgP zPRCFG{fK5J*f%cUGaA*$1I))@@EL8V_N@JkW_OGkf`h?Fw4K_k>Je>K-$jl`Re(xk zp$c%lnog_whC1s^4gFVDLX}3Iv1%YupZ{9qGwnO3dI&rrz-vAOEm{RA>~C zzqpuiT)q4b*K6AF`}!IjL8^u~V%$OQ^G4>le$wK+Ve4Hlc!J~%-wJ=SbKplV?4eZO zOUx&qlSbR;yZTEM&UpJVz(`9iXwHmHFU^XInBoY$Yw0x?T=3c`^H|rsC#H>za*Uoc zdGgHDr~A92uGjRm$ePg8&f1+AJ>l}_L(jPP(hEk+ykO*rmV_IDa@IKQW;p!x;_P=8 zJ}ooEaHGYm3g59BwZVm(8oNPnCoJ5Q{GmW=5o^^#wFDeo8cz1F)1U1t#3L(z+p@1) zcOG8~qGhktm?w3T*w;N!|J#!Af2rq`x0jgqy@fYy_PiVP%dFt_k$uYh)|k9W`@{D~ z19IPr%&`-Fwd`TJzRmY8f=fY);}Ya**<&x`eJed)a?Vq7wd@&`5BPa*z>kM_hdNgP zUmxMfeoy3EKk+tY@M4A|Tdo|TujK#b$bL<<|F?D634UJE3J0%czw@Ky_M3IJ)>I1@ zyJehMYPrX|MeREotGbxiJjWMybfop>_r~hh-qu5gUy z_pf-@>vbe(mwSKGtv7Z5GVfl)8aLX%%&gU~wuf4Kz`4}uaL*uv3hxo>=J-EtcIjzE zLPuMybRKkGXME$n3Y}-ng8!;}zZ6NG>5paz>l5Vdg_$@33f}U!%kaET?INhs?N5H^u>3?s@!~b z>Kj7{=m>Jp!LWS5@M%8!jvI7p-lXcDaeSr6;Z*4iIK7T!)}CO8Q@voI?h5Lzr0#iq zCi)W9x#iKo&CV-~pHwo>XAD%T-u&;%fjZTjC)C{&Fj?PgKCcJhR5@35b|YNwtL-{x zfYx?mqP->N5B-VGmEJEL)@rx^Kh>3Nu{X(SUG3r4#0RqVJOMA(Yc>1a-ekM8Z*qF7 zPtIp)wp@KMq2zmiC(pC>Sts%a#$b8iSS+>2MxcNEO^hCG^3A)vx|za-TU`bEnyFXU zvMBp$j3?(mQsCl7BI*&s_wL7je}>^g?{b%QORD`G%e|C5Pp+xF^zRAF{9}HSQ``td z_H7Nemy>GypO24)opg))9uDnF+d`GDoBCKgo%GdzK0dnOq+15$s?sj}f2j^!Y~^dZ zV@&nqS6C}_E!pe5(mL1p$T7m(cY`&qI_*m9B<-Xs*{e6pK|Mu=IJS5~; zLB8|(0&neA)>Oy+{k_i2>L0GMuFVy<)vZiHvv#znO))Kr;*H}}uhrPYmSV6k6 z!8>}Xb%SYsC`-M$ORbrUie;AhrOa~9frB#55hD8>F|yA*Mb1_favi&zbzqFFHO}G( z1a9a*tdEej`ZaQqzEmzU+!A8z>Ay;tK11H(i{9Vzx|dluxh}-H>11oZCTpCr65v=U(+9VX?d0*5tZ|jft?LU16Q26?q?6VTE~||CC*h&tw;s3VYuXCXYI@d~)Y|zsb$Dvdih^xLwXw zdgV&@KHJtgOH%AD@&e~8lA`KuU*KG%^d23k_r(d6yQuT{46aA%YkFa!q}aVi@7|@a zWpdslyO?TAA={WJkDF(!{i|H>%3j9^+3O6VcPFa-7ab4Mt8wz8Eq6Qu9NYW+QP4iu zWR64Bv9CUm{l{#(t1!4wUesszf5wC4S!Relp^To83+*8Gu`|q8MDKoi(e=(i034VG zj_u=VtQ@|Fe3=`z+ysyF#Y>kN-Zt$rEAaUr>mQ~v|b!?BFwTlT)OLwGLL zuETbh`Gq7K56Ssvog_O>Ch;VWm;3e|k<8LF$){G5&0FE!0r>^!*n0UKKMbSgGTYYt z2+qLQ|#OiS%SOOYkE z4_jBiLhcy!`9E#FxvQ)RGd}Ns-T*$tQd>LNAg9r# zxsKOlh`07OYtpQbB*05javIDa{371L$A*(6!spmkPg zup>#bv3}WhX>O**u6;$WVn5uQyv}-e=7suUnWU|j+wI$@F;`X_S4fyKi{oD!6{oh4a zj+MK8y*0u6n8zCG?c87mRmZHi{;q4LH#pa7^y5k^HtIgpoogj{Q#V@6PP*9fIp-W0 zU2?OxaibMtI;-RpZ`VdE!fniyC3b&!lQvmXwX?jNHdzZJU8Y>&7{i$}Mp9u5Y*d%+ zURgWjOgZTG%0bs*ImdY+XCigp(9N{%RC$iO9DnxG%ktibH)pdIrP|kLXHXiwEPT+&~UBtOr7CD#5ZLSD;)*Y@H?&AJlbS67~ z;x03R6B_ts?Jt_a@wB#fNKG^xf?U(zZFPG=524 zi{s+>8JGXL$5|<#JD-!!y|s5)r=8_;e5M_T_jS{pi89T-R;IC^#eNq1S@!-Q-hg~- zig*5_R-|`Iz7;V16Gr7@_=xd)5B}VXI=<jf7JdIZ6|$o2FDdc3s^*)BGpjFe}oz5ZM(-x^mEx$qde}v}nA!*F2=SZy(E`W=e8Oz}$_TOil%hvL3?S1VStU#6oL!5Q;p|eVN zIzI8<@Sye3Ns$Pz0DBu*?Jly$>SO5D!B(uEY` z?Stk$JeOP~H@li-yNxrJYXr|g_Vw1={FHT?=Q-;!dC_9AWv!PN{bE>9E#*4eEqm<6 z4GsOoc|DiP6X5?1>^jao7DG?6@M&d@vlY8rINrcMYahK*7O)6N<`SRm7zORr?O;6= z!T#AygCv;XVZoHk4vKaV$9pK@gjIvj5GA#W`AjzIbNV~=mAsg;S4{t}j>qFrt$N~R zqj88ggnqvrd!wJWE?#0UkyZ{YmDmn0jg0qEUPU$oOQpeMd%5Hs!=>A{o7n&SVAjs_ zWs~!H*)(|Ut=nPUIrVo9v6qAV=jQwWrv`e{pRrz@lx3bLYs~|^3ZtV>Qh-lc9@@9lcYI_)=+-NW9H zUDkZ2EYRi_iE<~8fgFm-eWiify@9YKAH49DFRh4r&L*{%BNMiLzT~{^4Y#J zbe>b?^Qx>++pQr9EZ~W-!I_QLg~oI>e>b`8IlGCu zS4e5k*-gx>YbotHyGhO2O*k^xKT^Hped}i}S{ZIuQ+~5D->l3xEA!3De6up&tjsqn z^Uatye{kG9PnqW_^E_pqr_A$|d7d)QQ|5WfJP&id+3FgIzD1dDQRZ8e`4(lqMVW6= z=3A8c7G=H#^D{ms`kz$tTb21%WxiFJZ&l`7mHAd>zEzoTRpwjWNBDire7gJv%EJsu zKHa&p#hR#d3f$W=cs@RW#vyqCjf0e&PM-{(97V`lr3hK}aoIyk_7Jl6FU1(Oz%ScvH+O{vN*;ystpIWWqb`q^+Rj}P^+U~~PKH05wb}OCTN@tJK*`sv${}kx#Q965+&K{*xt#tTL5~NtI zbgGq3wbH3pIyK_m^0_tKcO|J&6*Y8O+2{5k9q~5!w$+`VTkQjrXup~T`_(MiuV%r1 zH4FBuS+HNtg8gb1?8luh`{`|W+i~-HWnQn$>y>%EGOt(W^~$_nnb#}xddx$=vJPmz zGw*;hKcLJHDDwl#{D3k)pbQTv!vmxr-0queu>;$*_Q5&VL{A)&CNvLH9`SzFZYB6G z$R8@%hsa{Sv7&skHe`pSjZ`*#bNo8~E0^`MZ#fJh>b27EK78z3O_$62=W9dkex_uw zDUVct_1)mrS{sdUJ>?N^$l-x&k2VICp2Npg#wnF?sGR+eL6z~S4C}Q1!X=bcxJ?|X zuKC_N!#9PsIS5-Rxm;@V?aQS$pA78Mmd|ITTivY^+JA_0Qhzn&8FC5bRJnz6y3D4G zQj%HyaqQ3T&!?Qz{{rPX{f|(_^q)kzkUJ?C$NqzqDaxm3lXALQm3gY%qROqREK;r? zQss74dR1Ah$|sc5D&=&yD)*?eT9q}bd_#rVr^+@vMJ>!uQJaHphlG0ide}_r-)G-9 zX<3I%R{N)`@(d-JqV}h%@=R4uQ{{A3J45Y9sr{L1{~TK1A#(}YAr~w8g8oAG7xu5B zT&(u5RPw9(J$A?xb+AdLvRRdRs@$T=t*XrLTaV`5O0!6n52>`%te5jkCzcJF$Q$P{%jm37S#IaBRVQ{{AJFhlJ} zsr{L1e-=MTdqigUaWi0w8I%`|Xl$x69G09HYu{svNJ%FuQNGIeqy&FP8tz zCw}E3euaGSl^`;VPjQB|^I;dCu>{143}@jzJQ>g#5dvwzgXTy+2pSb7GCCYu_)o*= zkLeN#N`x|zvG^K`%~)jPQboq+L!(G=gUAGQC-jP(oFj5dyoe_xMdZ{Zs27=t;Iwd& z(02X;CSN2BN0Uivat73hgtH$`kZ_E{8~KyG9+5K&MW$dgrA{QGNMvdRbc>vc&6%|# z)1pNpsgET2v)GVe^GoSqZN<3*du+zOF-`9K2m z%S2*vqTu-4JdyKaM9#-PE*nVVLN~Czhyd|yFD`(3=n}aE-AnM5Ado3?X@G~KQRK2< zAc4yxAQ^C;7y!j03(^6j1?A8nvJj^WTL6cPuv>(;ML8l#wIYj)paKZExK&toLMX%l zNnVi+CA@jT=MsD`@l;aabV;{JayTT5Tp1#A72B&aAs=dhU{|}LP$Y%p6r5j!^J~z( zh6Jw31A;Egg<`<(GW;&<6iE#Le5b}j8sKwzG$b9WxFH%+ARj6K+dH~N?(}2)?0gH0|$HU>e9$fhDdcXKpU ziR7h-Y{AzSY_`Ti5B+~vwn%;?;BZ?2G>hEB@jW=br%R-uN951R!1297&;iKqD~3uS ziNZLj6}dl26hQ^lLo0L(uQQp3FXG_E7)XK)$b%B-64{vrC|AacyktUy$gXH; z5_y@#UdHLm?IKm^SK)AXB9P>sC@6(W{t!9{>P2d>uOXqDI+0f*fV#bY%;~);?9__9 z+9Oh1DDql3w28c)Bk~4yb-~ccAH-m=KS|`xEXac*k$Plrp?3i12RcOFCTK&9$iYaF zcS3>VcS-o&c9F(pNQYWJh+zBIE5DM1Dc` z3r>G&5jh$R1hW4F_0a@Kfm|SoquqS^oCuYGZm$5rdXe>3@P{x2JVqkN;vo(2f2@k} zKi0rb2Y-uW0?zwT=)8Jg66q56m@39H8sSgklc`M$RCJfLKU^bjX21D1#bk+z#R>#Ku~unQ15PlPTv1gZ$$z=tya;7F#oh6p^yj}Pyz%Rg2N%*q7CIE z!l4lm3j`jT2}OYM&@R#Vh*a|VxfkkFY)&>$L*5!y6#BZDCV z%0xR$fc>+|MVn5H>Gh(`z|J#+jH3deK(v`z&?(y41et|w7D~~{&?VYzjAy4ow`gx>%23f(wu!b1rB&sk zWw;>|Xu(a%Pz(fKO`z52tS*6G(QZzKI%t6|(J~2|nGN-#t?>hF*OUQ?-VzS>_}@|r z7~G1pTQi|qw5%f0)+RzaN^g+MBl0*=;20zI>?9H`HZhJ3)!?ST*qHKN^- z0BMi|1wbNqcxpwvGYAmg*&td@FrbuE0XSce@p_!EuM%y808Tcf00B0X1BrVAfTTPm z!lQ-e$p-2@#ZU2V{!0ASk*q8?; zKr$N}p&fcf+l20>2#AABKxY#=o6y-D4A^e26D<$Dyb95_!~zLz&0+j`u+i?y0-WV1 z0tw~U0>=5RqTL+{1irfn$^iXs3D7OtJp?L9hF;PBoG#kECKQWyA2#=4TbKp}x}TQb zkL?3-Pyo%MJ&3=e2*$stQnZJHp-{B#5r9)~5aa_+iZeueI1oYs*~0{Q#0`z2@vNgg zO2Q=p5CV131OzSV745MYNC0des}=3>0@0qp_Y>%ql2oaO08i#ZmuP><674C1mEpV$ zSs6-Cr-;U5gSLZUJJ5Xw%2P#q7N@NLwdaC?y65wN7FAGJktx~>$WMWCC>uFnpV!Z>K^T)QZ-ClLnj|Oo1$D1AM%L{2k=);QXC> zXcg_(BpORZ`>P4)yhoh(JOp}=iuXf-7QLSi-J&&-OcP2?Euwu80#QH`ACS}s z1yIX>=MRKJ(GIaaMBqd9qBXPMoCfWpeG~-v|A@MeDni#Ga(dWAOX?< zAD`tx5tK3hpH+$08U;0?eNIb1kAzrAgl^Hks2A<;C8D*Fz?UZA{446eY8LJ5bm$VT z9UtEy`=&#*Z*l$|emVs3d6>Y5+eAB(1l0e7dY+uLPW*mf!1(_V4^;fKRJ1NCy5a!m z|H9y38BhtmqWv33|1N`0{*PBIu-{FWcH`)$WXObW(S9x#?LU4{2l(y5PY+4{LNEN1 z2*f#x&tK8&^_Uca5COJ;ien)V4Y^PV7#yn+tuGj&0KGo+`h$Sv`;&nr`ddYpI7oqd z;8=@+8qxJANPtFY7u`sM9ML^Sx9Da(lmd!8BI%BB$c19)65YwMGZnI-5*nZdsN;{z zbXU3PZgkwSfDd<*=vF*nW1&C9gk;DB5*tEdLn9%cKSv!(prOs8^8};&#X&J(bdnoF z0Hc!{L?0Fkv}PFf!>IT717!Yr&?S063e<@{9NBR6hL=ID=p#5DQ2-o|#OKH?(F4Pw z6}mm5kE(!r(MM-PA@qtqhW#=0Oc23?Iz=CALNE|~EWyV`LOhVzxEAOVeLT*`lkoUx zNQ88talry?C*WfOiA*4o2_!awMo;kI{A4Ol#`(#GqMs52RGva*2u?z964D|1sW>?` z4w9fAdPScY2oZpMVhUsd0Vb9KJ|=dHej0VBp&N>yP#P6lC;FryhzAn)OrkQ3jKivc zR!k<)Ppg4W(IfqU7DZ-3ndoPkK#=Lkr{j1! zex~Di2EJzCCn^*QM4y=k4WgeN31yWZMZee& zazy_V+dpA<2|AbH`;vOm6Jj8j@lU|`QWP#laA`hpd|4vYLNj!VemRDh2SXGjKpNyg zF;qeWkksWpq9+DGIK)CSkYpl$6HB26nxI4U1p+~g|AI(%;vp6CpbQAUfZz)V&SR6l zkl+gmzL4Mx3BHiv3yYuv>Y)|7MPK9x1Ybn(MFd}z1qFc5MfhCQ44tAU;WG)JNimFn zQW9hUStgNX5?Lmpn1teD6c?koI0_OV4RW9eDxe-(p?IOEi^-?=qV-yLlh)H z8stC`R6+x^L67Ly1VA{%LNeojO(r|}Pzto_nkMKF{>&C=)zV0ahg6_dOADbK>YxR> zL|^8H5Qv6ENQYb~hDvCFHs}#OH2}gP7LpnNR9clvt5RuIDy>STRjIV6hQ^lLo0NPeuE#-`WtBd4atoE4VmoZ zLn+ii6Lg5aLLdkt0jDc)x*``!pb8qH9ePDi4}=JagA~XHf~QwP1E6;!{%*wIjrhAU z9#SEj@xQTGW@Jbx6B=9QqR-wmx0(}*M zR}pv>fmacD6@gcwmqFl+V2Fl9NC*676hkHBpMhdV8xZ&=9NvV(n+SXpfp5wI9Nts` z_0S64qObOYP>6+O$O0O&x*Y1D1-eAP*$p8O4FtbA9rBfnp{OGs6LgnJ8wW z$eRm2vk*|uL^-no+5r7EZU}-%z=k&)`kGA02lUsVzorQ~M88D6 zH)F(*@g9cucEq&J@Uk0w{x8Xa-XAmmfbP}~=oS4gZ11Xt4o;waKL`aB@=Kr*+5yG8adbDzcNYNx?(P(mzKz#uT{y7*jp-S|7J$0hrNAUYN;FXVF zh_m|%dOrsD*+Se|LGplcW|(yO!Q~` zfYy~0w7dk!^jQ*lE)W_-e?AsEM6bZv3j}$wT=bpT?qpjT1zA9V%5KqLG6B1n@bglG z=(~cUUi6pIucD`_3ZRzp-z|^?Eu!zq7rinSG!STSD&#^jltUe~iTf3sKgx5(rzoW7L{ zmCz>o0Td2oi~crsZ#RhEKvy=TLIn`yU@Q~>b?@N(9gcZ@q`%W7`n&jg7w3(oqW_g1 zd=EeGwTS+H2qZ%xVAmv!e^WF&nLw5wWI?6q9|l9c=!Y@@vF}fcoK$Yl!i-Hnp6}=@GQlNzKZ|M>JlO!mDX3;+l1dc!D z_*0HQ!^vl~^s{!+TVsF#tpxZy2-1KgKF8@7wC)RzzbJ!t(f=L~CD1E+TME$PFOhwT z>`NN+RVa9JMgN-0ud{(xvMYt2+|n`)O{Zd=}-YQ>W2&{X8eEP;Gb0dvl4LD6#$`tvo2&^WZi|M ze;GM(gD5yl#1SyCHgP5qW_vBdT*-e z$LtpFU? z{Ge70XPFqTAjlNM9Ra0K11-=ahDDtf11TN~Du#pt4u(`hml#81Ax{jybm$c0q-^15 z4j>wefuR2A`}c?ufNlVZ1$2lpJOPTJMT`-t&?v^p5XgcyF#@R%L^g`VNA-#^+C#w6 z-C~R(n=uVy1SLWN)Qd4T2uNToLB{0++wmNa$7Vb>!2}4#*#rVi$b?QYPR;;=pArXU zP%B0VenO}Z!T+hqPsR7C=uQj}!!wbVoK`4CD9$DYLz5U`bz)4$I6O^^(=k3BvsxP!1f=!0C*5$bwR+1d^K3Ek;x{WJ3+Ki!l@3nHF>b7a20*q_AQ++{2}pir z0hB{MV8io`u__3nfWWKpw<=eR432LKg+^#&{COTRRtEsW)i_*@!__FS&WAFnfhOn_ z<7PMD;AZN01~G2#5hF8Mj5S4K+(JUPpr4fn1j?#_2EhMX{I89H6etAh);2>I<9}Na z;Pkds$boXGhb}SJ`9U-!0Z!MI08ZDni;<1f>}}WB|vWtsHD+=PtH)+1q9yC@W$kKM^vZ7^WJ;ISkzO8o$NDak&G{*(EP z|6j|t{h-Lh1Qy~{hp-zm~BY>pdC>NtHR*Zc( z+}9<>estc9hAJ`Y!=XZqw@gTdZZQs&it)A^2-Xk)BybSDgY9CxQz^!~p-?YIBXy0~ z{xt_Yy<)si#RrMdDaIijG>3@sQIr@TH;D1KIx$*e#rOm{ixcD1bf86_43GyS(eq_HpUW}jO#P}Imk6Vmin#4GoA;z!R|5_wQFM7Q( zkOnzm%POE=jAO()mJXeae_y+p5-O$^16^Y3nPM6NVw%xnI^AM&?>2`dLbI4dL&Wr} z6muB5{u~E1i8;Jp%n@B;j_eRKuvN@a#n3C}=o&GD0>m6!DCT(ljE@6!gTuw-PHCQ! zFXpLn9x*4GVun?S8J+}fVxEpc1i`1ah&c_zNH{A>%;~{UCgu!|XJkMnbcq>ND<(G| z^Xy1S0}?*FUCdd5kOkdhMw8fV_UE8;4!U!*#f-)Oxt>@t&m)2JaCko3^NYlcO9B$P zAQe!$Fdj;T?|p`Js1q|j7wW~ln4~Vo_F@A3saVW}1Timz%L~L@P%Gx5WHGM@7c(VP z%xkb&)+A;sF|JJ!b2-U)uB#IB`Y17PK)9ku%p2pxTuFwjaJ(uXy2Q-DNe0d`TA*9Z zn*tyaN&tJV<>u-JF>lTiGcz7YYz=;HNfYx{j&DULD+CCdg-sUqS@`8;jK^Gy;@S)- z1}b>_V&0Yn?5~T3PBCwf0G!-Gpqx}_CUYF-R*1QY?PgQVyl^qOs+n6!_O2{3^DD)? zyFkos=oSQt`DYUObCa0&lE8iWVipEN8{>aJfgXqx^T9|lix3udi}_F}Btj0911;aq z{`N8;2`@pt1o4)DecUT%aWG^8{))TAsC7DOrFYyFY)QI_5 z0Fe1(C_m2jag?4Y7PB;4%qP+LORShrv0sK>SpuX$2IK)rD6lOfcv%~Ci}^IVPe(u^ zq(LsA`*a<&in&AR#T}vSps)jl9Vl?=HFuz}1BGW$c!v6CsDFlF&lExxw24`6LL{UB z^71mkt{l5(v3oWcVgbL;QvYlPGy#b{7XopR$@o84!VVSBb&C0X07OA5K4T5h;;M+g1tz!OwzaL7WTg-nV|7V?;T~T8GD+qcS z|9=zUM*{xXA!awN>n2EdK2!k?e)5AD$N=vk(|G7!b|KR*T$a(^Sz`uk5K7Pps z0v#0~*wJ)ofG#nACGfAMV)iA7Lsa5P@IR>LNj!VgQdJ3NUtgMF|fA{qmR009ryGy*g?%!AS@9(SnzOTM|_4M@4 zqTGb%L5Dymh%pheiPJz$pv9nW^#8;Spj{v+ng~S`QFzjW#F#t^1pZ_wnF7!8nvgMN z2MDsM7lBZAS}W)(&=%1Bpr=6KpEZXVRdBd!8)!E%rdNZ&n|_2C_&i}m;d~U4h!&tI z+79Xkp>Pz+qtAg}A%>Fx-R4nj5;0;>5FZZOM~uX^#7Is9p=_!fw3`^|SsWn;7*_T8~!N&jO)hJ&e~QBK41fUIHB!r#K(Nt>`i)nCP`~kU5b8H&(Em+%2a(`sr-O6JRI-hPh(^lD4CMG6X|yB96K}!~ zlp;Yw%3G0#L5ARfj~~nK1Lku6!`UAI@fw=sqmJO81YZZ#CEoz%KZD+P9L0HskPvvr zIR7Z2f?p>16eVx~zaewZ?gJKvIggN%muGm_aG#WbhQQup&;}4TI`D>)Wyr^9Piqg6 z%?0g%_AGwQ?T6Y6cDVEg|8H7bVxQyu?{?f-DcdDkCu@E>hIRv2;kOAueY`05wLse|~8DZyC^ zGLYgBGhgdPj*9{+%B4UoqK1@?J%J^K>d#29ngqwI0}xArgXAF^+=r|loxui8Ij&#~{> z@7Qm$@7wR$C)wBSKiYp{1~b{4>|5-IY%qIUxEDa%aTw1U&ywL@Be1XVxP(aI@Ae#y z&th}f0=AefW38;6t!C?3H@lKu#d_Jb>;|@hZDwU`8!NJJ+P|~^!~PNb4tvJ_iT!K) z=j^-edHY@a&+G>U`+fTZ_V4y<_Uo*KS?tePuYbgbuy=%iIvLJ81R>o{rXZNR5m+9~ zh5Bm<<`S+12cG>^k;EwvpY$wy;~+ zBkUXYA^TAFv1?Q|6m_xIt#HQEX-bH zHmhK7;S&Q6t!V}l06z5iZZ`_>ZqV<*2G*v5@X-rl9xQge3bEr|D>l46V#9k>J5<1q z_k`H-e$970@-E-;$T6|wRfrvLyx8%k8RPITlB z+E|Rm0v!nc=L75b?ic9xB7|}O*UrLU6Z{|X3xCzKzt;i2OY-@CsuR5=4{wd&_df#| z{N~6z_^p)&HU3d5u6Zx>L+j-!RtR;-_e}=a z?QF*~$Tx#{B~IKV1`nwPEeCajt^)Onfu!NS52i2&4v;bW@Aco4i0onBYX6YVh|9pu zk(W*@^a{KKXgc{e68Wk-vhxj~7Dz8(bek{#$;H zgSVTT4w}RqWQI-Lu$E*vkK5;~Hl81d;LZc@T9m^>PNNF+8Vr@7uXu1vNCnREWF+of zCzv5KL{hNGP5J{XL`-7g&Nxg4f$JaMfbzP*Z<;T|Cc}rqsf6CZ8YtuH`%mAH4ITrP z4LHl;=wP@x6ui?!13iPo#9$quvw&r^|KQGyfHS9q^zvP^oNyV1oR(X z11m{H)EnC`01DtG8?=5LIYS7?4-lUD5v3CbNd2fy6!iuO0Dak{kH{t~8J`in5mV&& z1MIJ8;KNo4!5Tf_@Rb_)F~bsqk)aO!tDFyYVN}Tm>f{EU0TNGE=6xUom*6N7DVHLgNT-Sv?FV*7BIRY8vB)Aj zkCX`(Q-V37!i6HeSfumGU?IhGGJfnJWPwN*)%Cr53^V;tb%NeK4txao4e&nzehc`` zy1t_U;CF#>eN+d25BQzBzQWN`T%5oKghwr4KA(99@Fjy2?*_g&1wp(sN|75N-X#`t ze$6|E&v+BWyN9nRTs8!FF!BoM9t%7acrfsIU_S5gB_koDaWN7XBR~;gK6yr?&{@C{ z;7Z^qFrOnF$AS4=;4}?*GIDednGVbcEypq7>By^4z7CiVJWd&4bP|b!KNC0w`y_#j zS-8jobE*ffMvfjNO~7@?Yf$DBz%zh3&F&?n5xIBpIElfBl*h@7m=`B+qVXts_d;Hj zy!c>~#rVV#7OA&rVyxm|BISV;;}&U!z&xB{3?t>?6eAhwFoC_rj7O4)Ma+w=x3nXw zg6}O(mFBIaU~X(6SDTy7E#@uWrMlW=-e`hIuX&T{dZ~Fc&aLJ)LEFvkLfM?)E$(#- ztgrA73u3$sKj(lLHY5-rX7wi|)<{M5=Ohk-|D?qD2O!nIl-M8@HFG2`A!RjRkhqlC zHHRe*5n5X-u}Mm6+a<=Y-Gpm5$_q*=YJVayd?3Tm`HjTfp+ypFWLWi9iMd1HlUOH} z)o)159a<_e_P&~1BrYYa=D5TmV%N?F#yAQDOfnSD)_5cW0gIH?epzBlPOJT+z#4>O z&%vMkqKqaYl#^H|!)lnsC8WIOs}h%z@>(h}cD&mAC8ned)8Ep+8~C8ngjZhUdv zr>&z}xkIo+T$1bT%CGH+#HyTFamr$ANw!eGdUa&pKdoE4va@AfdwxZvIoHzN)0yic z&1*YWbfa)rq+5wE>wy3@az3vu-?gGW*Acnk)|IRCE817(^4+-((%jRr9yRlkd3m9@ z4WisB>P1%N3LR^5ovTo1PJX2{{80pH&XcNQ9i*`bZMi%bS+TaGBPTp1jS5Cub6pWx zqRT6qL)pu7oy+qbt@)0Xq`9+&S1NR%r5*%o=*;zSXJk-v{n41Wwx=5^+x})y>U+A@ z=g`)Uo{p7WEuB0R^Lo0wa}fm0kBJIH4u;m`3Zn5B=Pv8Xcjj6nA8mVALp36s)02wZt3j5>{7h|=OE}JpUkaBWBW@CFu@Cug}K$O>s!_g^n8AY=(xg) z?p!Ne?C|?>BlkF;>lS^rwxbm>l>JC9TAj;xz{`&AfrW)M*9IMt{*Jt;r3*t~0ONdA zjWl%j@PRlt*VWb2(ZZ$c3mB(4v>ju3x$OL=e9OwU9WAQ|)K-ckDCf&_M4?VkHQ^e? z!1pEj{xV8G?)SvecOO|uZth$^Si^sYymzbBR-%#H-Ll)P(}o9^2Ui4JgSlW^aAmMP zm=9hWToqhRzUZ*A_gGhJ&7FeIQ7Fvs}#nxx6CDu}FnbksWbEn*E#WZq{yZBzK zDoi$6H(57ZTgVo&wYd3St0d4whtm=CbUKobqNC{;T1g{xEFDMBpyTP8bON17C(+4t z3Y|))(X(h3olc|Fp)ne#37VuSnx+|=b>F|wx_dbNSGtjIqMPZB^d@>U-9oq0Tc}IE z?ml+E)mDr=VC@P_3x6g2Z{gd+JHk7|cZBZ@?+V`)zB_zRcz5`#;d{gPh3^kP5Z)8s z8-6hSQ21f@gFV)8clcf_<6gYiswxTpIs8`m?c#>L)`Fl-o*+-!JMBB{JMCTeUBx30 zTf4O4wa-|42MsY>+Vc5iIvdLhluBgd>0;wc)=z`(xP#VYv#}KOFd9!bxvLLam1e@b zOefu^4qB6nZy&VAX~i+Wu&xdiM13b3jm3SGbQFpy)GtjaUQ(fyLTQCE3VA-lMk?y_ zQjYK_5iK++mT$~SD8-Ia=O}fKQWsO|V#?*1uO%8&j>eR}m~u2GH5brwrCLT4p2n5x zxKbTgs^cmeab+Z~jKr0ZxN<+PY{ZrO32vj1&%<0o8A&K331uXqjPyq)p^PMyk%Tgm zP)1V9t(2;fQZ-T;)&D6~C9T??R?eiAGil{aTB%Me)oGH%Bt88SIjjXUy;Nj0IBUxo6oAyR%QmIS#tMiSa zt{lEj)R#I@-bJ;=W~BrE3~?M~EF1S^si@4A zaWyWSY{K35D{I{(-$6A_9MxP$jTk4Ja+_YUUK}DzNBf(d%@oJKYGpJ_iZY2*vGq4r zX~6x`A!~2(z;CU4HE$Fp)9I`inPfU6

    VHb-7$csVaJ9C?x9$cqd|UJy9)0>kTi zJ;QlE%E+)K(}j$jRwyXv5=Xwdj0`_l;~P#TGa`1$#+1x`Q>m2iQcBLAWI82h4@dpw zd^b}CIeQ?Mvxg(EQ#kS+Ny&M{dCG{KN1W%kEG6d==P4s{9)Tz45l5bl0*A_ooJX9e zjL3P!dCG{KN1UgO$aw^woJR<_DFyzMX{_Xenzdjm(xh};`EPZ^QB1m`LD zRX20z9$i^PM}PhG{|#(}Y~|xm2}XF8Q42 zcSAyrv4ot!OSxG2CFd@9ax3RZ1vshPN-85s)%K(^l2mO^X58oh)2b}gixnW5j?3kg zBVSou&EvS5$8j}N<7ytq)!dG&wIZQbh=f`-;u-G_A(d(n(=(N7oF>et;!et2np3Hn zQq=6_YDy&?$K7z)ig-&_GM$X3+xn`#t{CFlE@762Tz)}AT z$DG;J#4R`ohr90`YvPD{c`0JyBx1ra@@99)QEQ?pJaiKAto!^?tI~bzs1+F@e8jDk zESmE32KVJ-&?uVeB+{bU*a!R^D&DguoSqdMi<8KTUT_liejaykd%xeIdg)Mu%p0R_ z_i>0tc%4L}bgW5gYl^$!6aBTDWUZO9c{7{bm$+Dj%t`dH6@uyxJ`Zdh>`S+CzEk^U!RqBkM~&%OwVF6-MIB}y3{=*K(DZx zq@J0Mdm=zDC^|uUUa%x9g)Yf zS$Qq2#;~>Xu0!rvZTXdW8q(U*)h;UI#xt66?;1vz6=x2o3j)QHBWPK`y50HyAP(Esgm%7bz!}5CI2A^fq#F4}o0747q3{^5)QaZJjNv z@OVZxB$kmyy#X6@_dJcq+*d}^q3-B0H0rJyL!IKIW9XfMVm?9}boXoH>FDCY@pM?ASUQ3JOVHgh znJ%>&JtMJ3$DKR{mM@w@r@Q;7&?ns6r_xJpqkU~pS5BypV|t%EjYiz-r_l-S3)AT6 z31aBP;(XQaSh+g4I@i{13DlWi+1~BdN;kQmJd55FXm&?dp%dsf4@jGjypbmaXQ7ShP563AF>oB}?fw0k^V+E*l~GsktF5 zi!_POX>Mq$cW+ouQ^h4KXkHIAxrZ*NEA^HYJ>A6%ub}q_`4jKr;p=I;fj`*?=FbfI zH^iGDD8&;3{=$ic?+kQ&8508Ez?BJ%vz&id7_OxF_FxdMZJatDeKXYKU+3YGBEGaK z#rHFVp<^`8QhYry1|=&=Wd$V>oRo|uW5-Z@Jur?xO|K=j5Y*wMcu+qBf<{sgyo4+P ze<@B%mXT%Px8S7sCV4rOuE0sjO417FR*`n#%g7p}U8EBn{4-*hzZ@qe>&cZ!KZ`R+ zt|9*nyd5VcU&l!c+EvdTG!IA`(F}SOQFg zc&Hn!2$mro5*&iG5G)X?Gd`Jp#p1oV?6z+Zs? zju=7U!dPQ0Ddq1&^lHX=#u;GEGiC$NH|7(~SZZ8CN{nU3GQ7CH+-L#*g0TW+HW}C9 zkMlPho59EX6NDQ3jE9guYCO_Q@h(LX81GW_($I~e8wm|<4c(0Nj?fOIdqWQ(-5>fU z((e^Q2ax?F^gOXbKMVa7_!ps{1HTn|8TeQT?~R5|gx&)_89G@`Lmz}bsHA3TsE<(b zeR8RZqnzSlj|KiXd`(TwGt4vawe=M9Or+DysYEx=GS33P%B(`k>E?8lJlk|2tu_ni zKwM+iKwN9qLR@FoLA=nMiP!S+9!M`Wmzo#>X3j+4o2$%KNY|R^Y4ZxawolFV=6a<6 zjQ_}MnAe!s0AFWbhjfFv0qL#gMnbK6^9iI4Rs+%TNU0Go^^e4ZC5op!qt=&GJn9); zN%6R63~(i_1fEDSO7XB~5;&9T<&Wt3oE^Zzpe=mUe`p5cW{v6bxrvyEBP-|1(2Bl diff --git a/src/3rdparty/wasm/qt_attribution.json b/src/3rdparty/wasm/qt_attribution.json index 5d89e4adfa..d569fdc167 100644 --- a/src/3rdparty/wasm/qt_attribution.json +++ b/src/3rdparty/wasm/qt_attribution.json @@ -24,10 +24,11 @@ "Description": "The DejaVu fonts are a font family based on the Vera Fonts.", "Homepage": "https://dejavu-fonts.github.io/", + "Version": "2.37", "License": "Bitstream Vera Font License", "LicenseFile": "DEJAVU-LICENSE", - "Copyright": "Copyright (C) 2003 Bitstream,Inc + "Copyright": "Copyright (c) 2003 by Bitstream, Inc Copyright (c) 2006 by Tavmjong Bah (c) American Mathematical Society" } -] \ No newline at end of file +] From 97600d2c2885e667ced0926815b5a12a7f25285c Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 19 Feb 2018 10:23:15 +0100 Subject: [PATCH 0208/1650] White-list more recent Mesa version for multi-threading The issue we had has been fixed for years, but was unfortunately in libxcb which we can't check at runtime. Instead assume very recent Mesa drivers works. Change-Id: I5fdd726b480b77edbedc0f369ae82ab4acbb77c9 Reviewed-by: Frederik Gladhorn Reviewed-by: Laszlo Agocs --- .../xcb_glx/qglxintegration.cpp | 60 ++++++++----------- 1 file changed, 25 insertions(+), 35 deletions(-) diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp index 741885e321..6316aa2d99 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp @@ -51,6 +51,7 @@ #undef register #include +#include #include #include @@ -692,32 +693,6 @@ static const char *qglx_threadedgl_blacklist_renderer[] = { 0 }; -// This disables threaded rendering on anything using mesa, e.g. -// - nvidia/nouveau -// - amd/gallium -// - intel -// - some software opengl implementations -// -// The client glx vendor string is used to identify those setups as that seems to show the least -// variance between the bad configurations. It's always "Mesa Project and SGI". There are some -// configurations which don't use mesa and which can do threaded rendering (amd and nvidia chips -// with their own proprietary drivers). -// -// This, of course, is very broad and disables threaded rendering on a lot of devices which would -// be able to use it. However, the bugs listed below don't follow any easily recognizable pattern -// and we should rather be safe. -// -// http://cgit.freedesktop.org/xcb/libxcb/commit/?id=be0fe56c3bcad5124dcc6c47a2fad01acd16f71a will -// fix some of the issues. Basically, the proprietary drivers seem to have a way of working around -// a fundamental flaw with multithreaded access to xcb, but mesa doesn't. The blacklist should be -// reevaluated once that patch is released in some version of xcb. -static const char *qglx_threadedgl_blacklist_vendor[] = { - "Mesa Project and SGI", // QTCREATORBUG-10875 (crash in creator) - // QTBUG-34492 (flickering in fullscreen) - // QTBUG-38221 - 0 -}; - void QGLXContext::queryDummyContext() { if (m_queriedDummyContext) @@ -777,18 +752,33 @@ void QGLXContext::queryDummyContext() } } - if (glxvendor) { - for (int i = 0; qglx_threadedgl_blacklist_vendor[i]; ++i) { - if (strstr(glxvendor, qglx_threadedgl_blacklist_vendor[i]) != 0) { - qCDebug(lcQpaGl).nospace() << "Multithreaded OpenGL disabled: " - "blacklisted vendor \"" - << qglx_threadedgl_blacklist_vendor[i] - << "\""; + if (glxvendor && m_supportsThreading) { + // Blacklist Mesa drivers due to QTCREATORBUG-10875 (crash in creator), + // QTBUG-34492 (flickering in fullscreen) and QTBUG-38221 + const char *mesaVersionStr = nullptr; + if (strstr(glxvendor, "Mesa Project") != 0) { + mesaVersionStr = (const char *) glGetString(GL_VERSION); + m_supportsThreading = false; + } - m_supportsThreading = false; - break; + if (mesaVersionStr) { + // The issue was fixed in Xcb 1.11, but we can't check for that + // at runtime, so instead assume it fixed with recent Mesa versions + // released several years after the Xcb fix. + QRegularExpression versionTest(QStringLiteral("Mesa (\\d+)")); + QRegularExpressionMatch result = versionTest.match(QString::fromLatin1(mesaVersionStr)); + int versionNr = 0; + if (result.hasMatch()) + versionNr = result.captured(1).toInt(); + if (versionNr >= 17) { + // White-listed + m_supportsThreading = true; } } + if (!m_supportsThreading) { + qCDebug(lcQpaGl).nospace() << "Multithreaded OpenGL disabled: " + "blacklisted vendor \"Mesa Project\""; + } } context.doneCurrent(); From b5d249f9538bf3dc44f11879c2244deb5a37bf97 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 8 Oct 2018 12:19:01 -0700 Subject: [PATCH 0209/1650] Update the floppy disk icon (save) to be physically correct [ChangeLog][Documentation] Fixed the icons for the "file save" action that were inaccurate representations of a 3.5-inch floppy disk (the cut edge was on the wrong side). Now all floppy representations are physically accurate. Change-Id: Ia3b27ae12a1a4fefa3b7fffd155bb86fee5271c3 Fixes: QTBUG-71012 Reviewed-by: Lars Knoll Reviewed-by: Thiago Macieira --- .../mainwindows/application/images/save.png | Bin 1187 -> 2699 bytes .../widgets/mainwindows/mdi/images/save.png | Bin 1187 -> 2699 bytes .../widgets/mainwindows/sdi/images/save.png | Bin 1187 -> 2699 bytes .../textedit/images/mac/exportpdf.png | Bin 1215 -> 12637 bytes .../richtext/textedit/images/mac/filesave.png | Bin 1206 -> 2699 bytes .../textedit/images/win/exportpdf.png | Bin 1059 -> 1215 bytes 6 files changed, 0 insertions(+), 0 deletions(-) diff --git a/examples/widgets/mainwindows/application/images/save.png b/examples/widgets/mainwindows/application/images/save.png index daba865fafd22fa18e7c0488eb699b79d3554170..e65a29d5f1735d95d5e96fce818e251fbbc88ee1 100644 GIT binary patch literal 2699 zcmV;63Uu{}P)VA_wI)m0!v5$ z*Wfhuf-yB84A~=cdN-4r_-Ne{9s+$;ND6k98!g6mPU>DfknVs34@3}u|#V|8F_w2p@Ip^Ga z=K~N31OkCTAP@)y?t-Y@fB*jdb&RnZ03~V*qnvM!bN;m2@3{#|>0JQ-&9sekzQh>o z8yp;*)~Y;30_f`M@=Q)n9wET50n}(!xF9!t3kww&FJGR};#gS)5DteQ_Y!g%lzvx> z0tNZQfgApXh3{w~0$Blcb#?itCMMnorTYLNS{%X`o4=1}uo_FAfU1K0UrnOvlh*+N zt*x!-?Ci|dX3gLL!1?O`oF~`umGz0ge|YhH4%YVZsX+SfP6{AeQjJ(3T_l6w>qX-y z-6(r-1q5hV@cRea_wLP01XOB6dwYA3GxkdWm@I!5quX+Cd@GV{T&$kuQjO0u9>I7R z_2GJRHy&2(1^^JCA?EY-x9{DXt`>zz3LqAXJx?hu1eVW!5N9?1%0gxjkUla1XQ42VAd?6v zr2}e2ASVFFklOgF6F>_#eu9JuCM&)LK)nc*2|$bZZ?YqibM+bHz1i+xMZGeQ4Q55^=loYv`#UlR$S2v$FbpWc5du)s-BX(Et@QwDf^s0X7l6|4URu9ifd^Q3e1~G|93Zdmo>b#o z!2^gKAUkh{Ruw5oGy+EtqXdZ;#4R7DGH9 z&-piOudhc%MMciv*8^MR0D4UA%6WiwWvOoId}j-eX{2^jLQLXK`<$V_8x*-p#>mVAZD~p~31HD5MC9@1hl{*-=@MpVXEW|+c6ZMVBD1p?8X5us z%$C+6?k&vn4ec;A1l*~A8BHI)hVk)n9DU^#?Ax~wMMXu)?Q0ui-SYB^tlQF-<+i2n zXA<*sbGUNl3T9?z006h^Up6%48afd4@N2s<+He##H%?({Y6?9)Jw_I9d2a3a38pr- z7+R*`BY~f9`ynEwwb*j=&nTJvCkSUon_ww8p_ndf#8};r@V|;3Q1DbmGo~t< zL0CNb%p14DJbrNEF|B-4yMf%}#gfN1(-DruvI9W^V-NyxIYIy~Cwl<4z{4E``XM}k z%Mk)_IhLLc6zGre04_%ez~u-5xEzrKxE$dDT#gWc%Mk)_IU)yeIl4{87e?-(VD3x3 z4(}=+6;)!sDE&P{TA+&n3Zh?Nci)deSnfAc3RYp%i;oZd1z#0ve`BdGkBSXEnh=ez zA(X{Y^6-W(kLK0=daOf-4&mF+J*Rguj%4VA4{-kcc>qA{F@0_;*IfWRo14+x+^lyo zjwBk5CIz4uq8sRP^yvnQZlgZvP_M!RxEvt>mt#l>F#GOXN1)Tixxxdu9NoKt*`B*| z^X5(5zI|J7Gb~9>O%3Ym>Lj-t;WYHMpz zUte#k4TcCnPRR|8jc90WG{Ou^Vs;l<3kZr#FbufB@8xj8eAP^jwT%w|kw^r6eSMPkV+6+J01~cjQ)Q*f13QnZsw!p4 zo?W|va&&ZbfH8*A(NQzaFpb)+TXEpP0aI--bsWIs^`h&=7xgy5@<`Q>7zc1WmgxoL z^U61fk-%J8S8uk>0fYz09m{xtJP;nh+K8cGyWqqSFg-nu-@o-1#>U2UH^YilS6Acs z@#6@Vl$d6NF&BhLtUr79EJj8~j4;8H3=a?EZ|Bb8r6Wf&Zg)mE5Rmi$B2oZ^5b0#k zGD%<_Ie=Ue*!jW>_|Lt2xZ~1m0;_9k&~f;%@_`^7axqhff`cU`c>Rqx%rwFEn0`Hg zKn4TqP23yka`Ybu5F>%wVB2v3h>^ftF{0i?2yi*Z%mzw?fOtHPv+ulvyLa#AUVx1W zg+e&o*$J;Vb2F@~H#>&_DSCT)aOU)BGfgm+zhAqC4S@g-9z1B84W`ZojJx!5@U@KJ zzi;YDp#Haq%Y53}+E7$fq_+u{B^V5%t*y-kR|QM(jV)X7$5W^9aAHDb0nVVTyc~YN zU)j#K%>lBE1p0hFS6?13S2v;?D9{~aW&_1YU{0jfn|My3Kx>2mT#j4_hyz%D^9Sbu z$<6EJxbquvNO$WlCUoJFbqBs~BpWDHn-T}fbWT(@Th3KXKU{tIUAfvof+IHi)8 zT*-xizQn?&&)&<^dV$ew`s`A2*}JrKQEER)0SpWbjBubI0G=NHD~cbw^A27+5}f!H zUmrP>`1iu4!NGq^?JJuEa?XFs7@PCNV`%O@hE1Pd1Ql-svn-UwQFZfOG@t)D=+Ytp zL>T8kllxBAXx-Y{+78ao0SEv<+*gR`lOZr)09@khzE}jo2dkpn@ys(Seuf~y$nbD- zd3NJBvFOh{Z$iM~S$u?|sWEsK<`b(Qfslj!{r&IDm7yqI+aC_Ma6`O|i zbia_XIS}$M0-P%?E9*IP=FF0TCJF=sfj}S-2m}J#@PC`#$s>84XuJRb002ovPDHLk FV1kc9>)`+Z literal 1187 zcmV;U1YG-xP)5-PJz!8#8DIjU4h)0S{a*K!i>mJVVCD^kQ5IHGsm^=1>z+FI)Tw&v zz2|;5 zYXiKvXAppke-?cB?jC^K0C4>59N#}M1b8m}xWN9m&Tq?d4;^`$3nP}(pC4rW)qR_5 zKt-??KzML0Bg?XF0WdI@VU185d=w)kA`~mw7?IVLbLY;3D!2sF6tWD`ER0DCNfO?7 zI*{j(x1rU7b}No;C~~s;IMxc|ue?cX@%rWftQD*k1h7Wfy?f^tYwL!tfLf?lf$D8h zjjsf?g7=`NgaKy-HG&AJ3Y9FwBOo3K!0;X~0^TDMCKY^$Bg7#dJRx2{O;{K}*Gh>7 ztf1Os0Gczu1&UJ#X#$l5vNZMt5(iG9=s;dTE04VeOF6W2$O}}5aXkPkPoHKY21CJ!U{_^v8Xy`U*q`vX%#{A#01X5mtL``3Wj}4_b=eEU&o)}BH zcC!Nrol+61khoCqTE#GZvCBZkunzPltylR~F5%(E(lYhTaDB;yE$K=b5S$vobLD22 zD>u8WQCC0Ls$_n}C!#5=1r@`b3$=HqY!|4(sUXN2HLsgB8jo2qp8k93?-T&>g72GH zFe_J90#zZ=ko@OU-}3936D%#>xTpG8Y6Cp=>`tC}VFC}RGg~nb1AK?~_rJly!UDH$ z-J&Q8L>2*RmC}ns$#9hnDF1_1m8Hc<-5*m|${p@{U>9F*?@YhOX2JRd6<}qE@f>YdJGB!_d$W)>^#xG@H%40#K{h zaM6gg)QA+E3nyHlDgdZft7KW$r?@xXX>%H>7ePy{I3CBnBed6yF^ELpk2<)ko3Ayf z4fFOGEVA_wI)m0!v5$ z*Wfhuf-yB84A~=cdN-4r_-Ne{9s+$;ND6k98!g6mPU>DfknVs34@3}u|#V|8F_w2p@Ip^Ga z=K~N31OkCTAP@)y?t-Y@fB*jdb&RnZ03~V*qnvM!bN;m2@3{#|>0JQ-&9sekzQh>o z8yp;*)~Y;30_f`M@=Q)n9wET50n}(!xF9!t3kww&FJGR};#gS)5DteQ_Y!g%lzvx> z0tNZQfgApXh3{w~0$Blcb#?itCMMnorTYLNS{%X`o4=1}uo_FAfU1K0UrnOvlh*+N zt*x!-?Ci|dX3gLL!1?O`oF~`umGz0ge|YhH4%YVZsX+SfP6{AeQjJ(3T_l6w>qX-y z-6(r-1q5hV@cRea_wLP01XOB6dwYA3GxkdWm@I!5quX+Cd@GV{T&$kuQjO0u9>I7R z_2GJRHy&2(1^^JCA?EY-x9{DXt`>zz3LqAXJx?hu1eVW!5N9?1%0gxjkUla1XQ42VAd?6v zr2}e2ASVFFklOgF6F>_#eu9JuCM&)LK)nc*2|$bZZ?YqibM+bHz1i+xMZGeQ4Q55^=loYv`#UlR$S2v$FbpWc5du)s-BX(Et@QwDf^s0X7l6|4URu9ifd^Q3e1~G|93Zdmo>b#o z!2^gKAUkh{Ruw5oGy+EtqXdZ;#4R7DGH9 z&-piOudhc%MMciv*8^MR0D4UA%6WiwWvOoId}j-eX{2^jLQLXK`<$V_8x*-p#>mVAZD~p~31HD5MC9@1hl{*-=@MpVXEW|+c6ZMVBD1p?8X5us z%$C+6?k&vn4ec;A1l*~A8BHI)hVk)n9DU^#?Ax~wMMXu)?Q0ui-SYB^tlQF-<+i2n zXA<*sbGUNl3T9?z006h^Up6%48afd4@N2s<+He##H%?({Y6?9)Jw_I9d2a3a38pr- z7+R*`BY~f9`ynEwwb*j=&nTJvCkSUon_ww8p_ndf#8};r@V|;3Q1DbmGo~t< zL0CNb%p14DJbrNEF|B-4yMf%}#gfN1(-DruvI9W^V-NyxIYIy~Cwl<4z{4E``XM}k z%Mk)_IhLLc6zGre04_%ez~u-5xEzrKxE$dDT#gWc%Mk)_IU)yeIl4{87e?-(VD3x3 z4(}=+6;)!sDE&P{TA+&n3Zh?Nci)deSnfAc3RYp%i;oZd1z#0ve`BdGkBSXEnh=ez zA(X{Y^6-W(kLK0=daOf-4&mF+J*Rguj%4VA4{-kcc>qA{F@0_;*IfWRo14+x+^lyo zjwBk5CIz4uq8sRP^yvnQZlgZvP_M!RxEvt>mt#l>F#GOXN1)Tixxxdu9NoKt*`B*| z^X5(5zI|J7Gb~9>O%3Ym>Lj-t;WYHMpz zUte#k4TcCnPRR|8jc90WG{Ou^Vs;l<3kZr#FbufB@8xj8eAP^jwT%w|kw^r6eSMPkV+6+J01~cjQ)Q*f13QnZsw!p4 zo?W|va&&ZbfH8*A(NQzaFpb)+TXEpP0aI--bsWIs^`h&=7xgy5@<`Q>7zc1WmgxoL z^U61fk-%J8S8uk>0fYz09m{xtJP;nh+K8cGyWqqSFg-nu-@o-1#>U2UH^YilS6Acs z@#6@Vl$d6NF&BhLtUr79EJj8~j4;8H3=a?EZ|Bb8r6Wf&Zg)mE5Rmi$B2oZ^5b0#k zGD%<_Ie=Ue*!jW>_|Lt2xZ~1m0;_9k&~f;%@_`^7axqhff`cU`c>Rqx%rwFEn0`Hg zKn4TqP23yka`Ybu5F>%wVB2v3h>^ftF{0i?2yi*Z%mzw?fOtHPv+ulvyLa#AUVx1W zg+e&o*$J;Vb2F@~H#>&_DSCT)aOU)BGfgm+zhAqC4S@g-9z1B84W`ZojJx!5@U@KJ zzi;YDp#Haq%Y53}+E7$fq_+u{B^V5%t*y-kR|QM(jV)X7$5W^9aAHDb0nVVTyc~YN zU)j#K%>lBE1p0hFS6?13S2v;?D9{~aW&_1YU{0jfn|My3Kx>2mT#j4_hyz%D^9Sbu z$<6EJxbquvNO$WlCUoJFbqBs~BpWDHn-T}fbWT(@Th3KXKU{tIUAfvof+IHi)8 zT*-xizQn?&&)&<^dV$ew`s`A2*}JrKQEER)0SpWbjBubI0G=NHD~cbw^A27+5}f!H zUmrP>`1iu4!NGq^?JJuEa?XFs7@PCNV`%O@hE1Pd1Ql-svn-UwQFZfOG@t)D=+Ytp zL>T8kllxBAXx-Y{+78ao0SEv<+*gR`lOZr)09@khzE}jo2dkpn@ys(Seuf~y$nbD- zd3NJBvFOh{Z$iM~S$u?|sWEsK<`b(Qfslj!{r&IDm7yqI+aC_Ma6`O|i zbia_XIS}$M0-P%?E9*IP=FF0TCJF=sfj}S-2m}J#@PC`#$s>84XuJRb002ovPDHLk FV1kc9>)`+Z literal 1187 zcmV;U1YG-xP)5-PJz!8#8DIjU4h)0S{a*K!i>mJVVCD^kQ5IHGsm^=1>z+FI)Tw&v zz2|;5 zYXiKvXAppke-?cB?jC^K0C4>59N#}M1b8m}xWN9m&Tq?d4;^`$3nP}(pC4rW)qR_5 zKt-??KzML0Bg?XF0WdI@VU185d=w)kA`~mw7?IVLbLY;3D!2sF6tWD`ER0DCNfO?7 zI*{j(x1rU7b}No;C~~s;IMxc|ue?cX@%rWftQD*k1h7Wfy?f^tYwL!tfLf?lf$D8h zjjsf?g7=`NgaKy-HG&AJ3Y9FwBOo3K!0;X~0^TDMCKY^$Bg7#dJRx2{O;{K}*Gh>7 ztf1Os0Gczu1&UJ#X#$l5vNZMt5(iG9=s;dTE04VeOF6W2$O}}5aXkPkPoHKY21CJ!U{_^v8Xy`U*q`vX%#{A#01X5mtL``3Wj}4_b=eEU&o)}BH zcC!Nrol+61khoCqTE#GZvCBZkunzPltylR~F5%(E(lYhTaDB;yE$K=b5S$vobLD22 zD>u8WQCC0Ls$_n}C!#5=1r@`b3$=HqY!|4(sUXN2HLsgB8jo2qp8k93?-T&>g72GH zFe_J90#zZ=ko@OU-}3936D%#>xTpG8Y6Cp=>`tC}VFC}RGg~nb1AK?~_rJly!UDH$ z-J&Q8L>2*RmC}ns$#9hnDF1_1m8Hc<-5*m|${p@{U>9F*?@YhOX2JRd6<}qE@f>YdJGB!_d$W)>^#xG@H%40#K{h zaM6gg)QA+E3nyHlDgdZft7KW$r?@xXX>%H>7ePy{I3CBnBed6yF^ELpk2<)ko3Ayf z4fFOGEVA_wI)m0!v5$ z*Wfhuf-yB84A~=cdN-4r_-Ne{9s+$;ND6k98!g6mPU>DfknVs34@3}u|#V|8F_w2p@Ip^Ga z=K~N31OkCTAP@)y?t-Y@fB*jdb&RnZ03~V*qnvM!bN;m2@3{#|>0JQ-&9sekzQh>o z8yp;*)~Y;30_f`M@=Q)n9wET50n}(!xF9!t3kww&FJGR};#gS)5DteQ_Y!g%lzvx> z0tNZQfgApXh3{w~0$Blcb#?itCMMnorTYLNS{%X`o4=1}uo_FAfU1K0UrnOvlh*+N zt*x!-?Ci|dX3gLL!1?O`oF~`umGz0ge|YhH4%YVZsX+SfP6{AeQjJ(3T_l6w>qX-y z-6(r-1q5hV@cRea_wLP01XOB6dwYA3GxkdWm@I!5quX+Cd@GV{T&$kuQjO0u9>I7R z_2GJRHy&2(1^^JCA?EY-x9{DXt`>zz3LqAXJx?hu1eVW!5N9?1%0gxjkUla1XQ42VAd?6v zr2}e2ASVFFklOgF6F>_#eu9JuCM&)LK)nc*2|$bZZ?YqibM+bHz1i+xMZGeQ4Q55^=loYv`#UlR$S2v$FbpWc5du)s-BX(Et@QwDf^s0X7l6|4URu9ifd^Q3e1~G|93Zdmo>b#o z!2^gKAUkh{Ruw5oGy+EtqXdZ;#4R7DGH9 z&-piOudhc%MMciv*8^MR0D4UA%6WiwWvOoId}j-eX{2^jLQLXK`<$V_8x*-p#>mVAZD~p~31HD5MC9@1hl{*-=@MpVXEW|+c6ZMVBD1p?8X5us z%$C+6?k&vn4ec;A1l*~A8BHI)hVk)n9DU^#?Ax~wMMXu)?Q0ui-SYB^tlQF-<+i2n zXA<*sbGUNl3T9?z006h^Up6%48afd4@N2s<+He##H%?({Y6?9)Jw_I9d2a3a38pr- z7+R*`BY~f9`ynEwwb*j=&nTJvCkSUon_ww8p_ndf#8};r@V|;3Q1DbmGo~t< zL0CNb%p14DJbrNEF|B-4yMf%}#gfN1(-DruvI9W^V-NyxIYIy~Cwl<4z{4E``XM}k z%Mk)_IhLLc6zGre04_%ez~u-5xEzrKxE$dDT#gWc%Mk)_IU)yeIl4{87e?-(VD3x3 z4(}=+6;)!sDE&P{TA+&n3Zh?Nci)deSnfAc3RYp%i;oZd1z#0ve`BdGkBSXEnh=ez zA(X{Y^6-W(kLK0=daOf-4&mF+J*Rguj%4VA4{-kcc>qA{F@0_;*IfWRo14+x+^lyo zjwBk5CIz4uq8sRP^yvnQZlgZvP_M!RxEvt>mt#l>F#GOXN1)Tixxxdu9NoKt*`B*| z^X5(5zI|J7Gb~9>O%3Ym>Lj-t;WYHMpz zUte#k4TcCnPRR|8jc90WG{Ou^Vs;l<3kZr#FbufB@8xj8eAP^jwT%w|kw^r6eSMPkV+6+J01~cjQ)Q*f13QnZsw!p4 zo?W|va&&ZbfH8*A(NQzaFpb)+TXEpP0aI--bsWIs^`h&=7xgy5@<`Q>7zc1WmgxoL z^U61fk-%J8S8uk>0fYz09m{xtJP;nh+K8cGyWqqSFg-nu-@o-1#>U2UH^YilS6Acs z@#6@Vl$d6NF&BhLtUr79EJj8~j4;8H3=a?EZ|Bb8r6Wf&Zg)mE5Rmi$B2oZ^5b0#k zGD%<_Ie=Ue*!jW>_|Lt2xZ~1m0;_9k&~f;%@_`^7axqhff`cU`c>Rqx%rwFEn0`Hg zKn4TqP23yka`Ybu5F>%wVB2v3h>^ftF{0i?2yi*Z%mzw?fOtHPv+ulvyLa#AUVx1W zg+e&o*$J;Vb2F@~H#>&_DSCT)aOU)BGfgm+zhAqC4S@g-9z1B84W`ZojJx!5@U@KJ zzi;YDp#Haq%Y53}+E7$fq_+u{B^V5%t*y-kR|QM(jV)X7$5W^9aAHDb0nVVTyc~YN zU)j#K%>lBE1p0hFS6?13S2v;?D9{~aW&_1YU{0jfn|My3Kx>2mT#j4_hyz%D^9Sbu z$<6EJxbquvNO$WlCUoJFbqBs~BpWDHn-T}fbWT(@Th3KXKU{tIUAfvof+IHi)8 zT*-xizQn?&&)&<^dV$ew`s`A2*}JrKQEER)0SpWbjBubI0G=NHD~cbw^A27+5}f!H zUmrP>`1iu4!NGq^?JJuEa?XFs7@PCNV`%O@hE1Pd1Ql-svn-UwQFZfOG@t)D=+Ytp zL>T8kllxBAXx-Y{+78ao0SEv<+*gR`lOZr)09@khzE}jo2dkpn@ys(Seuf~y$nbD- zd3NJBvFOh{Z$iM~S$u?|sWEsK<`b(Qfslj!{r&IDm7yqI+aC_Ma6`O|i zbia_XIS}$M0-P%?E9*IP=FF0TCJF=sfj}S-2m}J#@PC`#$s>84XuJRb002ovPDHLk FV1kc9>)`+Z literal 1187 zcmV;U1YG-xP)5-PJz!8#8DIjU4h)0S{a*K!i>mJVVCD^kQ5IHGsm^=1>z+FI)Tw&v zz2|;5 zYXiKvXAppke-?cB?jC^K0C4>59N#}M1b8m}xWN9m&Tq?d4;^`$3nP}(pC4rW)qR_5 zKt-??KzML0Bg?XF0WdI@VU185d=w)kA`~mw7?IVLbLY;3D!2sF6tWD`ER0DCNfO?7 zI*{j(x1rU7b}No;C~~s;IMxc|ue?cX@%rWftQD*k1h7Wfy?f^tYwL!tfLf?lf$D8h zjjsf?g7=`NgaKy-HG&AJ3Y9FwBOo3K!0;X~0^TDMCKY^$Bg7#dJRx2{O;{K}*Gh>7 ztf1Os0Gczu1&UJ#X#$l5vNZMt5(iG9=s;dTE04VeOF6W2$O}}5aXkPkPoHKY21CJ!U{_^v8Xy`U*q`vX%#{A#01X5mtL``3Wj}4_b=eEU&o)}BH zcC!Nrol+61khoCqTE#GZvCBZkunzPltylR~F5%(E(lYhTaDB;yE$K=b5S$vobLD22 zD>u8WQCC0Ls$_n}C!#5=1r@`b3$=HqY!|4(sUXN2HLsgB8jo2qp8k93?-T&>g72GH zFe_J90#zZ=ko@OU-}3936D%#>xTpG8Y6Cp=>`tC}VFC}RGg~nb1AK?~_rJly!UDH$ z-J&Q8L>2*RmC}ns$#9hnDF1_1m8Hc<-5*m|${p@{U>9F*?@YhOX2JRd6<}qE@f>YdJGB!_d$W)>^#xG@H%40#K{h zaM6gg)QA+E3nyHlDgdZft7KW$r?@xXX>%H>7ePy{I3CBnBed6yF^ELpk2<)ko3Ayf z4fFOGEZhgW`PJN;($(F? z#?H~2($m+~n$p_G&ISPR**MR4NTaQ8F8geW1HvNYue$rhZIMmg9DchROPHEC@u&fQ zCX9Lh_(!t^<2t3HikHA~`}uas^?57)X;}wy@rcf_jJ@9L18$9I2aT^jU%s`jg8KSE zt)Cw^-Oru7KI6BGMdJGb7Y#k+V&IgE!~2JOuk@EiwIE_YwjScUllALK57Qvxn~NUj zqCQpM9o@^0KfWK&t$9zK&#z!_3of}`*~^5yotOAaO^}b=ZcBq-;$`-%T7y84_s0%6 znA;n&zv`0yc)i)t1w6U!{uIK4#Lc2zZ<2~OY+l`NofG*{q`sd$PevZJ(*%4x@_9QX z_N<7g>t2qj$li)9ooYU~Y^~)e^?~u9mEKU^3LkX;GT+7&C{pOPTrVfGu5h+Y?)+G@ z&n|fV-cdlc*0e%O8c+IE)CT<`L0>!o>;&h(9AZR|N|S%e*!+_bjsvi|OsckHWo z;h8mRHDcO3rOy6Q(2yLpl6Gp~|1Y`A!blB$jKfMW@Q@AFVwJnneD?B#%O%JIM6_Z# z&{!#W8**=78H;~b>GJIKeKzoK_q5m6cEvSMKkmG@8OMrcD6;{DW9v;ctcg!{le+am zXSai1f7EUiFUqD51t4EDD1J7jpfxGs6P2#zOB;vIp%!foyE7NbTBsWXc`XO&a z=E;@AKVgR3}dSx|DFo^M9Sz&{iu?Vyt~^xVMJ~V3R9r&cs-G@A35`SrjrA2#a1>M zr)fQ^KZ0h>)e92o0e%4utczi(@eW#8B=FCe&5FZIlYJpg#^}@Par&+kW|HU=geo2> z0ijE-+a;3xXbv=eFHe)zN!8*X$fa=9bk-Ig25KSQqeK-;D z#b+fW)TG7e{;tUQhxu|wwHZsl)a%0tBTyBP6(p6{1 zlSK5rZ^xP%l;e}1O@VPKK+-bI)?Gxu!TFNH%d7o(7gfXx;~n?{uL^zYpN}^i!q_$J z1d1L8&(RqT$_1J(60F+X^)9(Cr+75Nn~kLOTQi=L%Zke%q3)5tMI-1QUQJxsn-ExD zv`X7XG#gWQoCm9b%nt}~m;Sv>@8ggrJP`f%t(X!2#(${&Wh?H_&zW@Bu2r2f!mhP@ zUkr6(w_j0B26;>`(25sKGSa_QC~TU|ADXYs95=@|g?XrLipWhC)ar!k+B@hmccfk$lf^j5Y zo$`2)fv9H9Pc-S$*1if!7b+&5GX(Bt^YN&TAR=@KK?&11ccH!?7$WHt_>AITy6KXn z!QtT&mi*0FtG_$8FX~5FZCF1XjQ`6FS_0Bg-JBQ00Fb|$X%8kKOcM2*g-vWb9ADv( zzdro3KzSPbO>>plC*R?RNnhugPF=-YLIiEOs!U8~OT(i~vM0*gZ|834RED=y@Cuzk z(P`TYuw*qmBEmt3M(7G5E~4U?kgLA#@0H5W+NV%4?l;>Urp&%(+UEJ%c%wjeGcpDC zD^yDPJ;!2z3U<|hhhxWZRp5DrQ@)nHg{p|{|NL=HX8Sh;E*qfYqXx8rZIJ5+x%n~i zw2+m%Z0-j3wD2}jENIL!n~GK}3z;|nz5v$Jz@!*m**+O>4}`5xel@xE@e*ZHpGFA$ zLj^&zhRJVl5Z;^M26;s)Jd{a?sSPB&cJ}AzTd(HjNbwn6`Cq8%<~2wuTrUl{ICg{R!#B@l?cdOU()OikOj7n(_(Y z!dfMh$ihqB%xehhTTBd0Ua5|e@)#<-EMl_j2+4G$R<4RDNEuF22$ z;j945g+V|s7W_f9fPHir2}2)!qwDH3;i*A){&yR4hdh?&mhSHI9MYSE?h zmDO2h!|$lCKG6QX9Lx`$I{CG2o!9=U*_eO^bmChG0ijCQxr5He-4TGrMIBQ9DDcm- zP<>)IE)wljH?x%jBSyL+t6Y>fiX6L+u41W{1`4btrn9J_^Il!}7VP0SV}y=NRu^S$fOZxlx_Iby8~1Yhnr#(Q=Y z1!8q%uF@ka2oM}9E3j}*GgD6s4Kfa`ygx+nsc1@eg zebwHhUn@&e-bfJNFZ=e<*K5K_k!=;#^W)_o)Rx-m1bf%Yjo)%mPn@lze~;om+>452 zTD?o|AeM+RO5?)Ij>#Af&{ff$B7X^)BGWXg*vr5rka3{cci^>F)mhH8j4&|lPUi;g zgIIxDH+RU`NnN6<9P0+1S?4QXD@DB#jvUvOzk=;;LbVPoEMpo;N--1z$>V0W_>66N zTZIRlZdiwlEtO7|MzB9$BY?+JR4+I+9fXLxID3w`^lRaVKYny3>INdQlc(a{EoL1x zG)A4=Tr0^&Lb9aP7-M6ipE&Dd>+RS?*F-_xiI56Q&icp4HWt(^SOi#0^QA zq;-%k`|tZ>Hq!4o)#CZ~F2p11#D9pzo2YC|$VdN5=e2V_IJZ2G0jnQ!?yL96TfSZ8 zGvK%wmfMIWmeb{%3TZ9UCijstc}UNRkp;sJG^F2(O;FG?W!(blzYbEw;qEyr|;F__&lF=b^O4|m?E#NH- zS)j-mQr2v1E2b6+BqT^{BQA|=e^2Vae^Sy#OsnveZSJ16$k=w2R~AgLiY0fdayYEZ*QS{KmU^2Q~vdKu`w~zu&H#IGY!4;p~=OV%1(T^iFZtL=yJ}l zr&3_D#4bb=ij(mQHj$eyHF?wIkC>?lI%d9J?6nYy2aHH}qYlmRYB@ay8-=;PUr$0V z+o|EPz$z9=swbp+o({G$m1Q)y?mz76dP>%D{(%*D{V^sC;RJBkLcirNkJ zASz_&I(>0WRO6Q(>LATGb`>ddgxjs;!wzYSzfN`6Eo~d@JY+j3-+*$7;mnDY)%3?a#|pAEK9*Qw}ptu83_0v%JbB6}zu&sPbClf#-7uwgO_4O^Ru_2sK% z>WRymt{s&9!2X61JL4%1JEC$d_u!qW$cQK1pHvO+!qdC!pK9DFe;*roer3i4mlG9D z^({`_K)`ktY_}fV3-7eDTIV?f%9D|?TZ><9&}9bd7#l71q?R(pPz=g2twF*Ii3fGS zU8ky(#3`Albkx07E6Sx6A-$(1c8H_000nT_qQfJP8E^Z8i!;|6K7UNT(teT_nGvNT#0{Z)~b42SKYN?}+qyu?XAkrjE zOT83zuKH)k2QL;sgouslG~AoLaO9-DG`W5iU;+y|?Rh0%Ck&~xvG}=D0&UsBN{M0s zosUnJQ8NZ*Yr4lP#AKS#Z>;nJ6Ik>Jsd0Qc z>j?s%GW*P_uF3_$?+S71##CjgIDP5f`bqvSa2}KyvH7llqVQ-^P2-&Z=#M0TrDZGg zojJ#45phhHAs1_ODFKRF-gs|&#py>*)?&y$T;KA2=1BLLE zWOT~whjFCtd%_uW+Pk}|-U?q98RO|8+ik4%-h!?_RWA8G*(4uVaIrqlPclaTkf}FB z!;p)S7IK_3x<#n_$3J)rAcoD?to*r~-+9DP;$uQ*^reyxB^XCL@#x_?)NNqGY?O90 zsmZx;Aa*jjy|cH-#!7_oa;cO8k9NrIrpVu5%stFjO~F==7--3a@&W5VcXx!N#vxNc z$xo7v-xxTpKI`es$y&1wnT|X0k+*DSC|KH%F%ywFI(wNrG%iW;(n680dyI%v!KBl&nMLa7Pd zwCr1r@0W5Q7h8X4R2`DsdlT+r^74?`1@oit;Syf9w>#R#Gv{y?!`FZCw1q|PEzld- zb1|>DE#HnPDR~mcU*Dlgr-K!7h9!gyuVP$@H2qENw30!S_Fh+{b#%!;ofFrzrjGs+ z21pO5>?1RJ&Jtg^uGUf!qDomu~d_7x?TikLf+Hx%eR$3VHD>YHs>Tn zh3#%35Fh}D5-cIk@3>8Wm9;}3SPRQg%i!DJ=Kj@*{YxHIopGaP)F<%QV9Qk5yfX7* z*E)J{mP3-8EMfSMC!ma~2}Mi2_S9v%SpP#Up;yFYmQgpd2wM+zRXY-{mg;oyc@D%u zWk5bd6wzLr-TC5WDIFF}^N|vDzY!q$fhG1ul(_94h9=UiRRrTf2QR|~jY75e&h|XP z2vjM1Q2jy~VOBe&`)yIkOPfb5oa-}?2NV{oaGc;!{nN@6LHxq%00wNdyFHj4aRFVG z@ueLEspC<$w-@FyNj2|{l+(8bCmM!o!8oU~mN>w8iqtxFwg;M{Huf;rMRM9;6Yw!| zraen3L@FBN2?q0$LWwwcxL{qzj9GoyQ<-_r2UhhOF1-6*NL|+VGtW(8PEuwq!~|(y z%Bva}bcf=&EeIA&^CJPO`UwBqHd8a;?sSqI>(9##JY&3cW3U$Iu~wTdpu5>7Tz7Ww zqh?=yBcOw%i+$^e>uQWqd>jXNo-?36Bw)y~i^+&H^R?+p`LRQ$gh=~93jGXl0`+ch+Dh0(KvhEUiV}Jz(ZN`X z#9WJ+g=uvkIn`~wWr9-Ley00_%UAfRx%Q=(hZ7yHA|V@3nI%29Ny7B(xH|P%hQ&`= zoy4!&2VLmQKEWx%Y4!?-wB*Yqc$;Xc5?e4~98!i_}hvvMhH#)y#_({`CE?jZwOG)ns|vg?9+C7;`XoKJhHC_Xb{ zfH2RrVX+1tQGI?Y`tqWH@qR`AL`Y;tuCx57_qcA}E|7){jzWtmBig3BNXV4K@ScFb zVG;9Jm%(XRcn_Daq;srtdv`0)#UXzH^EW3q42Vx+u6_5KM?r^Egi?=mi{Nb1qW<z{3Jm(WhiO1a%eeUC)2;~!AXs(?#-D;VJ8@O5+9U{L>ruj-U zd9)_uT<@TEV^*@Cc z6vTG{? z!=#{Jba#ofQ0m$voB#8&^dXj)8@*_g_5o{&PkY;5C%`59?Vp<6BKLEbtv-=qr`5P- zrv$XsS&O>ul|&`2=XpU%i(M>2lCZUCW4nR2(U>QYZiwvT;ukl$~^T-bEXhMBua4co7yrpw9YWuJNoRnpnf>8u>wL zE@5MLS&i5_#iXJQV*<4P|!87GG9 zTy5!^G$I#bpI9*jm@!HG4XA{SV{=lxw?T^@JbsfdTdc`YYk?iyY2E7I=%Ca@Edy#U!c8$X`h=`Y zpPr~G3OgZ)w>0laTlMua(aWkFCZ*+@s)7;m9nK!TvstH!JUayb{KPtM(sH8S&)3YZDo=cdQ1${ znpR1m<648s?)yT3Bo<4&ujxkbiq6zavt3ULh56!R?{2VdAGe9!wqu0cRukICygK}; zZaYa&a!RS?hLIqFVeL@t)5n1-Fu%LinDN(6rf>5P^z)%!e++V{2J`ufa*Y++z33lB zC&L`%J|8JimtkXd{){H!iA^tEb_4jtl$p*>K$pIj*hHDs9zbZU#<-E9ff_ic*F{x- zs4_e*w%X)2Qq_lBnh?+^Iw#6PR7dxZ57(U6TXmBs+3u&P9c525gnTW=0K%g~CXpJt&2(@bVzEKX%1hrj5eKrK~4< zBV$1GqZDAFDo;k6i^bOaw$u{_7qJv_qLb z#y&!|hpyv5+25mKqoGcV;A`cII*VdTXQHxxRK27G{1kerg+C&@gR9Tvo2jn9u}XC) ziVOBt9*9qG*8wm(L65fNx}Re5B@-+PJ`d-4E;apO=r833rh!`7HA}5w>lQB<=LhtK zrmt8M4s_0i_~KBL2cC@sM9q2)EEhSCzj6du83e^v@o6|I?e+6cW(g?&5tp`*VVET) z46-K9Smc@R{W`tr*DiJ|Nq4K>Yxw;8##;N^o?6~P!Xes$xl?9Nx8L$}+LNq|1GWj5 z!6Epip1%6J*6|OmLCE?q9&nUkD}5K`=c%o22k#x?CH9MaiQ`9llnvYYccQsVy4L5! zC=>8w83mLoeDsa&YtIqjurh$pQ2f>Oz6JauC?XsEvXwE*q6==xM-ND_*47RdD-Ib= zjkdHzzwsNw9kmeU@@|)q zC3^U3DOC#QTb-piCDd=v>cLO_{6Y4Lgxa2J-db9wZXir0*Vm|1KQ# z?$`q!gGiNn&On;uI6GJkCWMG6{hQ$%vs8Dh~+Uhl+g}xsaR+azX3E4Sg4m?g`Q2IWT2} zX3b+Rrui~QtYMZ>Aew`FUTtauq)0Iz6!llBqT6nm^w7@4?3vJu7K2sHRFI3mJeUe? zGvi^3fS6gYRMwT7gm8LUt^G5BqT;{YyZl1W*2s2c!&TAbn|)qoQgIHmH})RpQcI^9xK*dn&X&ELnMF7!Q$jmWMa-1M;CUI~{HLRja_P zC#(-C8?Qw3ss@1BD&{lxt&UGw${^CZ$5kuq4YChEW)}pm>T&WVX>DycLt}ND@&`6w z1y$VRfsbd~f4|2Y8pq8E34|E9_UchX^C){-mti`*|w9B)yDe(pKK-AL-voEdtvgXrX-C7o|Lx z5EASM21Z@SI>Rg>Zz1CapJgy(u;XFIPXOn|#)MyJY}n*0-fBGL0 zMHxx0{{%h8POjgyiGwacia)c`+UM{~cIB(e=dz@j>?4WGtT(-g7&|+Kg_w`xrl`YV zn#cYWGuF<0xnSf@;`%La6f8hP9bTuy{BP(>vGD$nc(&Sq()cn;;>D^jsq}*1gEKOC zx)hzAozwi&Z>Ovf5BUxY^B+ZLUwbY=f&^y&pDD1omV5+STU(1!(Go})R59!`6&#h_ z;q#qCL1GSrp|4ujIF+j7F~0`i9nCvvdWBd|W+4?66fg^z;e;63RIEvf3*@{XXPdUm zk3g~DD|aXD?;y;wn|*6Q*Vq*v+T9JH%MU?mzCklSKSvn2{Rc23aT+a;?Teb`Az~XK zT!=-5DPa8gK>{c)ErnLjX44*$fzI&zdge+3+PV06yf+5AUYxBr&UOX8`&rpoKew)~ ztn58CSpq^J`t1Fw8Jt`^DUwrfklEc>X-$SXIH9%m^{!l?^V=;1{8!~eX)eWj2s0rt zI~oiw%#QA1`etznFo`1P>y5_g1d}An$<7G6EzqirjbGdGs~3u#0oq%~8%Y8S4vre^ zHSf-USeXbyp)->55Ta|(7La7&Tz#Nx>FVY&QjtIvb35>= zjjH&Fs%1IK%Rd-9zp%BQ-X|`59NI8l0Db`9`9)?cJ9Wi7pSZ+is&?`|M9HAPctIEL z#|^qc_o4T@8Ku4kKIVi`wP9W;%Z^r3yOEpx#^i=aL96Dk#t~Cs`<-ljM*L!6D$N+eck+SVa@+lO@jl;P@O6B(_ z61Re?lG^tdmi+!u(3~&v6UKF}2Od%8zVupb<&I*o2U{{ZYvE8%AT(*8HWEe*OD9;t zLfsN|cO14*4NzFbHiGoj$={3GB(Kc|fDs<}LBUW}RYjQRijJAJcKZWSiT4(SszL1Ci6$5@OV?AzT(PXIouOfo*~0^9)<{G%9yfUhHk3@~$goB$8N zzeUk8vk)KtUI?#*-f^M$er+gJ4t$JMH$lV)P9&619f>&O`>XP!6lTcv8SGCKC@rLy zY%0L76KED#SfdZDx`)_#@kwZ&{L^TybCiAnbie+$j47Q zWe(epp<~a95A;Q3r}|?l<-?xn{bB-4gdal# zwgr1?LW4bm#)+EAvd$~E8VsZ4r#Y7dM-#y}hARVcV&eU*rv^I zYPsqO1qwYJY2~hDT2{=(Rzh7p`O6|muYY4PyrP00AfYZNmfxN6gbMW?gTXu<$2zX=WBl2@e6F zPC*fBRY7UB4&cC80{%z1rNeV^z?+$&_xF>AgxUe%NB_^G92gD`wEki~gp^R+Q(4-_ zk3kzfsJluv2~+!|AEcD)KajkaKe0&NxK5b>gQu69C{rGxb^DcbLq~MiEI#Nhycdy5FV+ zO&FjIL&TE--`vW{wM+P46$oZ?Mu-Ya(*(Gc!T8XGJlXK@o8E^@)!zg>ASzO7LC(%> zH@CMiGX)SbO3YqI`@tkKVQfD*=im#$jLghxBUrhkV>8p>cdx;3jR%4;bKf?o>!G%& zB+htiTY3JH6}PtX?2?XnAvWr<5T>VwE+W-H-Q3)0XlP)9sX20Tm{`6HPU*Lld3j!f zify=U6_IQ;vBsuyCBCMC#aBsCKVFqo;aKqJwv6V&py%{kByMh?9~in^kSOo(T~+h& zZ*lbv%Xf#O2gt-wFU~ul08;uyMzi7=?z5r*f;~kizTN#~`3U8b8sz%vJjsh5986fR z`AD5pfYzWgUlK)hqZw4hHc%1?sSi9W7S7>9?kVgYwsD?HW1o-1e5XMmW`NK%iHHB@e_U zDlZ@Ndvn{}Xd{_wwn3|h92EPXXqm#Xdrf`J&4)TlO1Qf>vs{xB*qJ#vFtSB^EE)BoM`mWY2eh9Rjo=6Fdub&bT9gRzMB&j^7AJ#rW9aSFNo~f+PYJ*;qi5yNr&0>U@V4jb**WPm0i9b zC@I%hU~Jq!o=&sjE}#4WYSEViiwW&LY&N<69ek>Xg)ilntQ=}aAO~czKMJ<{?aR#p zpvSLP40}-<{doCY*4=+e9w=Eh1_{>U`RpfRIT6t>js;mikl7|l*{x)Xm(D+ubnS=1Vln2;_N~q%tJIZOweDG$fUi(IEX0i!O}{m znq~keQxt&2N}cp4@N$sXIln9@JjvR1?oqnBno?0wvk$+R9IL9CB5H0zDdogo;BY$J zV*)oscP<$LK48}SaXYP^552V&fISGynJY!1D-spruv-6jxj^`uKh^Sbst6-bzFr;b z?pmZ97OKuqRN)(r>${}#N26(((_$Q6CuXrh$FTj#kcksnU7gR{07Cc!$Zaw!B+%dT z=3w0Cq`J~9&BIuN8yz!b=HYxZIx7o*-qN(oNZ^#_);MH{s#}SU-L)2P1t9lxV+FGK zgN+VOC;3nJ`1vNu^z`(T>t_&)X%ltQVn4t_&PkkVsuVYpfbFTZ2$xBi87^u6Egt04 zNlL0P#{&8cGV1ivY^}*kD@?jW+{(nM0;3VIQ?H-;Ms26lmryYv9GgF|5<|OtXtr3z z-brb|w(6-U4^*`BIQm0~b~AMYlHRRn$@R6{u%51@?cTA&%4p=x^m^6~FVlDYF@g#F z9eb8~wUctd7{zyoVGxk`r-;^E32s2J_>*#WaYHRkpMS?JSjaRGFMP35xx!-P59#G2 z%rG<)ce!X@@^6F4k7$ad*XNi3G6~kq4$R$+cCRB%N0j52^%4tY5TP+ zL1t!ia3j=%@I{K3VdsKnQW1|vA|Wrb=M1Sv3sHS3wZQkO5E^zD+hqpKQV-ra3|656 zwX@eI@?+8O8E61S!`fFd8yt56aIB;`hB-kHZd^~VaOc-sA|uGAbHvQUKPOHa)UqFe-o3TI)SoBF!z7_^Z2^1bOXegmgks{Lq zNWU{gyba#=eDjQ=AXU literal 1215 zcmV;w1VHPQF`lm8y1`8}?eeOibRVJIa zx;(rshVT1KOiXh5;?#RULjb<{HpB4f8B(b=T)ANJ#=d80g^u=r&y}Lbzz-Qx=?*qO zun~ZU0Jde*-ku`8rUTb>iO1u#LS6UWLt<4ypO_j0VEF(sCywhTNFh5vgVl*@_|6pK(&=(YrvGON=oF&&e~9)F7QvGdIX7^b1H6ej9` z?c1Nk+O-S0b}dMW$mIxj>>${)r{3@TI-I|EFLZUO{@r0eg#8B(a^l1p?HPKD<^cjf zQ26+sBJlJQ`0edjM~)(p$hlekH+ymR?ZZ?3_R%9qK%N}J{OAD2$DinWTh&Ve0sx7p zyiDaAXkI3rGYAi9kR$%lz)$ zy3R1D*=|{OGnPwO&nP54c8XTfn6gB_m z0T2SAF<8I81KYM~fwb4ySWf#QB4}FozBu z(#N+U?WH^w`YMYGP~U{E>r&Im$Ox%aigY@y86F-cN>WPdLVMLtOhjLXwPg@USuac^ z68gzlonqZas9}(>UQ+Fim;tH@7emxd>YFDtzx}I2fVA_wI)m0!v5$ z*Wfhuf-yB84A~=cdN-4r_-Ne{9s+$;ND6k98!g6mPU>DfknVs34@3}u|#V|8F_w2p@Ip^Ga z=K~N31OkCTAP@)y?t-Y@fB*jdb&RnZ03~V*qnvM!bN;m2@3{#|>0JQ-&9sekzQh>o z8yp;*)~Y;30_f`M@=Q)n9wET50n}(!xF9!t3kww&FJGR};#gS)5DteQ_Y!g%lzvx> z0tNZQfgApXh3{w~0$Blcb#?itCMMnorTYLNS{%X`o4=1}uo_FAfU1K0UrnOvlh*+N zt*x!-?Ci|dX3gLL!1?O`oF~`umGz0ge|YhH4%YVZsX+SfP6{AeQjJ(3T_l6w>qX-y z-6(r-1q5hV@cRea_wLP01XOB6dwYA3GxkdWm@I!5quX+Cd@GV{T&$kuQjO0u9>I7R z_2GJRHy&2(1^^JCA?EY-x9{DXt`>zz3LqAXJx?hu1eVW!5N9?1%0gxjkUla1XQ42VAd?6v zr2}e2ASVFFklOgF6F>_#eu9JuCM&)LK)nc*2|$bZZ?YqibM+bHz1i+xMZGeQ4Q55^=loYv`#UlR$S2v$FbpWc5du)s-BX(Et@QwDf^s0X7l6|4URu9ifd^Q3e1~G|93Zdmo>b#o z!2^gKAUkh{Ruw5oGy+EtqXdZ;#4R7DGH9 z&-piOudhc%MMciv*8^MR0D4UA%6WiwWvOoId}j-eX{2^jLQLXK`<$V_8x*-p#>mVAZD~p~31HD5MC9@1hl{*-=@MpVXEW|+c6ZMVBD1p?8X5us z%$C+6?k&vn4ec;A1l*~A8BHI)hVk)n9DU^#?Ax~wMMXu)?Q0ui-SYB^tlQF-<+i2n zXA<*sbGUNl3T9?z006h^Up6%48afd4@N2s<+He##H%?({Y6?9)Jw_I9d2a3a38pr- z7+R*`BY~f9`ynEwwb*j=&nTJvCkSUon_ww8p_ndf#8};r@V|;3Q1DbmGo~t< zL0CNb%p14DJbrNEF|B-4yMf%}#gfN1(-DruvI9W^V-NyxIYIy~Cwl<4z{4E``XM}k z%Mk)_IhLLc6zGre04_%ez~u-5xEzrKxE$dDT#gWc%Mk)_IU)yeIl4{87e?-(VD3x3 z4(}=+6;)!sDE&P{TA+&n3Zh?Nci)deSnfAc3RYp%i;oZd1z#0ve`BdGkBSXEnh=ez zA(X{Y^6-W(kLK0=daOf-4&mF+J*Rguj%4VA4{-kcc>qA{F@0_;*IfWRo14+x+^lyo zjwBk5CIz4uq8sRP^yvnQZlgZvP_M!RxEvt>mt#l>F#GOXN1)Tixxxdu9NoKt*`B*| z^X5(5zI|J7Gb~9>O%3Ym>Lj-t;WYHMpz zUte#k4TcCnPRR|8jc90WG{Ou^Vs;l<3kZr#FbufB@8xj8eAP^jwT%w|kw^r6eSMPkV+6+J01~cjQ)Q*f13QnZsw!p4 zo?W|va&&ZbfH8*A(NQzaFpb)+TXEpP0aI--bsWIs^`h&=7xgy5@<`Q>7zc1WmgxoL z^U61fk-%J8S8uk>0fYz09m{xtJP;nh+K8cGyWqqSFg-nu-@o-1#>U2UH^YilS6Acs z@#6@Vl$d6NF&BhLtUr79EJj8~j4;8H3=a?EZ|Bb8r6Wf&Zg)mE5Rmi$B2oZ^5b0#k zGD%<_Ie=Ue*!jW>_|Lt2xZ~1m0;_9k&~f;%@_`^7axqhff`cU`c>Rqx%rwFEn0`Hg zKn4TqP23yka`Ybu5F>%wVB2v3h>^ftF{0i?2yi*Z%mzw?fOtHPv+ulvyLa#AUVx1W zg+e&o*$J;Vb2F@~H#>&_DSCT)aOU)BGfgm+zhAqC4S@g-9z1B84W`ZojJx!5@U@KJ zzi;YDp#Haq%Y53}+E7$fq_+u{B^V5%t*y-kR|QM(jV)X7$5W^9aAHDb0nVVTyc~YN zU)j#K%>lBE1p0hFS6?13S2v;?D9{~aW&_1YU{0jfn|My3Kx>2mT#j4_hyz%D^9Sbu z$<6EJxbquvNO$WlCUoJFbqBs~BpWDHn-T}fbWT(@Th3KXKU{tIUAfvof+IHi)8 zT*-xizQn?&&)&<^dV$ew`s`A2*}JrKQEER)0SpWbjBubI0G=NHD~cbw^A27+5}f!H zUmrP>`1iu4!NGq^?JJuEa?XFs7@PCNV`%O@hE1Pd1Ql-svn-UwQFZfOG@t)D=+Ytp zL>T8kllxBAXx-Y{+78ao0SEv<+*gR`lOZr)09@khzE}jo2dkpn@ys(Seuf~y$nbD- zd3NJBvFOh{Z$iM~S$u?|sWEsK<`b(Qfslj!{r&IDm7yqI+aC_Ma6`O|i zbia_XIS}$M0-P%?E9*IP=FF0TCJF=sfj}S-2m}J#@PC`#$s>84XuJRb002ovPDHLk FV1kc9>)`+Z literal 1206 zcmV;n1WEgeP)&5=xu1RdJ#IDvEdG#3 zHaCTnPtA0PfLqE+VPYbS+|emGrh`l-GZFyPPdo~Dysj3;K6>T=x3rysAOY8jkHDy!V7X1OV!!}8XFd%6MIs~jQ1$9!5 zC684vblv5b$90roQufLluWeb+J+m-_W$hJgV2{9qtn45cPc!se-reB4C7@O=? zSt*nu*e2O#AAJF6LZvoJVsqj}O+|wL3Pm)M5-y^j?GN-k$3p6HY%j6jAAryzwER*m zLs|wz+R}70^>H|C-W?nQS~*cHDGZ{aDOW;cNnsIwkl0J?_X8jj-vZu53TIz?{%{+e zcMXH`+@8}HmVc#PDfV&nWk3k!TnGclk5AD8QzI!vY^zk-RdzcObTA-b(Ec|J0oQTx z^MzH6AMsRuxR=J;y1KikY#D~3L<|C8@aher6t7*cVC%1H5*o<;^f~w~q8vk4bobM` zNtMxL=WKf*14_Y&(3*hGV1l(eK~iWF&sN~0=cP& z4-*2tdZvpj*2f=xfSsKk)M_=fTCD`2Mb$ADPE_t0G|#EnQ_=D1aEj&gFTPSXS=h%A z1~?B4OlEV*{}&e*v9z?L9B=`eot>pBId^Cl*p`TLppyZk6F{7V4rOlKip3(G<#bQT z<&+c(g(1~hc7(x67AC}yLZrhW)TtLYmyTIJ8Dom$zF+HFrP7x@cgdX$AVSC>4j4I@ zJlx;)?ufRmj1IX0mGD5>?uqx_8s9DWF5uIRiKQU z25$Ym-5NbgsDi-@lIk0gSG! UB0_&5sQ>@~07*qoM6N<$f^ZKn4*&oF diff --git a/examples/widgets/richtext/textedit/images/win/exportpdf.png b/examples/widgets/richtext/textedit/images/win/exportpdf.png index eef5132928be462a4aa01552c3ea09312dc6ee12..ebb44e6b8829fd968aa7cca386f21577f5635711 100644 GIT binary patch literal 1215 zcmV;w1VHPQF`lm8y1`8}?eeOibRVJIa zx;(rshVT1KOiXh5;?#RULjb<{HpB4f8B(b=T)ANJ#=d80g^u=r&y}Lbzz-Qx=?*qO zun~ZU0Jde*-ku`8rUTb>iO1u#LS6UWLt<4ypO_j0VEF(sCywhTNFh5vgVl*@_|6pK(&=(YrvGON=oF&&e~9)F7QvGdIX7^b1H6ej9` z?c1Nk+O-S0b}dMW$mIxj>>${)r{3@TI-I|EFLZUO{@r0eg#8B(a^l1p?HPKD<^cjf zQ26+sBJlJQ`0edjM~)(p$hlekH+ymR?ZZ?3_R%9qK%N}J{OAD2$DinWTh&Ve0sx7p zyiDaAXkI3rGYAi9kR$%lz)$ zy3R1D*=|{OGnPwO&nP54c8XTfn6gB_m z0T2SAF<8I81KYM~fwb4ySWf#QB4}FozBu z(#N+U?WH^w`YMYGP~U{E>r&Im$Ox%aigY@y86F-cN>WPdLVMLtOhjLXwPg@USuac^ z68gzlonqZas9}(>UQ+Fim;tH@7emxd>YFDtzx}I2fgY~PDBh=qfNApHBybnVEtGSgDgmlF?QjuZcTSCx@)?q z#F#d-ZdlkRWh17zfT(F3Eu|Hzduh@iDWYrQ7SlK}v8Lqm+6KFw>FFH@MBVx+g1 zcv~BX`}+YH>FcAkv{ZILFh+X-*6oncYgBv|P9_-{v66rMcN00L8)-CFe9ATud4`bV&eUS=4f;$M2o69kO{d#4* zI6O?_i4)`|CYZc*iBK|$D7CJ!2wG{h(p6Ts1vtyg+#eXIjHfagrZSnz_|Ca=)k#zd zkpisk0hZ6l<9G_kAHpYQM;W>rs=*G|U{y2-JOKct-s$E_YZ|RRfEa@ah^)Vj2x0_d z1o8U`HXTGM7(@(OdqM_-0mKMcf^rQ?DTL4# zfDJpkeRG`JkmjS~2k}{g5rZ)Xr8Gusl-4L$G5=_l+jADRsd^s#JwqfK#&y-!l`Q3A z(b}aZ7Nt2Uyp*ovhk+lt`qMQ;;LESR;Q5Yr9LK>aDVh>~#up5S4mC6L?*gu?a9veZ zXo1a{V2pU@iZR%BiMhFX?oHeW;NkK^3i&*a<4`JbWI z7-NXVVq~)`72~U`Hrk}tE7^5XuB!IHvMdX*IzITWe{}S(!Tn9CL?IR+5;QD4c6qkr z6hCxMXby#|ct$432_iJWNm=QppI>fM#DTq-r9;Nz1bQfU$rG&z`vo+t=(TaRecA@ dS$qB4@*jxcBlgPF?Z*HB002ovPDHLkV1i~?^WXpg From edacfd2f0b6f95430b62296853c3ae5b3405b406 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Tue, 6 Nov 2018 12:01:33 +0100 Subject: [PATCH 0210/1650] Fix QTableView/Widget on macOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For this we can use whatever the current NSColor.gridColor contains. While this is mostly needed by the 'Dark' appearance, it also affects the 'Light' theme, since the color QCommonStyle returns is different. Let's use whatever Apple suggests. Task-number: QTBUG-71048 Change-Id: I084414bad546755e9e67792484fe4601826ed0fa Reviewed-by: Tor Arne Vestbø --- src/plugins/styles/mac/qmacstyle_mac.mm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index 94d048ca7e..0204bd6104 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -2789,6 +2789,9 @@ int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w case SH_SpinBox_ButtonsInsideFrame: ret = false; break; + case SH_Table_GridLineColor: + ret = int(qt_mac_toQColor(NSColor.gridColor).rgb()); + break; default: ret = QCommonStyle::styleHint(sh, opt, w, hret); break; From b64ce6f6bb48524cfba3212d145ee624bd8819f0 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 1 Nov 2018 15:06:18 +0100 Subject: [PATCH 0211/1650] Fix matching semi-transparent formats For some reason some Visuals with semi-transparency incorrectly reports a depth of 24. Change-Id: If41ba1032fbe7d248f53f735cb84e61038b3300a Reviewed-by: Gatis Paeglis --- .../glxconvenience/qglxconvenience.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/platformsupport/glxconvenience/qglxconvenience.cpp b/src/platformsupport/glxconvenience/qglxconvenience.cpp index d7cc36627a..99ae2671dd 100644 --- a/src/platformsupport/glxconvenience/qglxconvenience.cpp +++ b/src/platformsupport/glxconvenience/qglxconvenience.cpp @@ -223,14 +223,15 @@ GLXFBConfig qglx_findConfig(Display *display, int screen , QSurfaceFormat format continue; } - QXlibPointer visual(glXGetVisualFromFBConfig(display, candidate)); - if (visual.isNull()) - continue; + int actualRed; + int actualGreen; + int actualBlue; + int actualAlpha; + glXGetFBConfigAttrib(display, candidate, GLX_RED_SIZE, &actualRed); + glXGetFBConfigAttrib(display, candidate, GLX_GREEN_SIZE, &actualGreen); + glXGetFBConfigAttrib(display, candidate, GLX_BLUE_SIZE, &actualBlue); + glXGetFBConfigAttrib(display, candidate, GLX_ALPHA_SIZE, &actualAlpha); - const int actualRed = qPopulationCount(visual->red_mask); - const int actualGreen = qPopulationCount(visual->green_mask); - const int actualBlue = qPopulationCount(visual->blue_mask); - const int actualAlpha = visual->depth - actualRed - actualGreen - actualBlue; if (requestedRed && actualRed < requestedRed) continue; From b3ae87fe765fe6ad005760d6370f2674873fead7 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Mon, 29 Oct 2018 14:26:15 +0100 Subject: [PATCH 0212/1650] Add missing protocol enumerators, report TLS 1.3 if negotiated 1. Remove the conditional inclusion of DTLS versions, they made difficult and unnecessary ugly adding new protocols (something like TlsV1_2OrLater + 4). 2. OpenSSL 1.1.1 first introduced TLS 1.3 support. OpenSSL 1.1 back-end is compatible with OpenSSL 1.1.1, but would fail to extract/report protocol versions and set versions like 'TLS 1.3 only' or 'TLS 1.3 or better' on a new context. Given 1.1.1 is deployed/adapted fast by different distros, and 5.12 is LTS, we fix this issue by introducing QSsl::Tls1_3 and QSsl::Tls1_3OrLater. SecureTransport, WinRT and OpenSSL below 1.1.1 will report an error in case the application requests this protocol (SecureTransport in future will probably enable TLS 1.3). Saying all that, TLS 1.3 support is experimental in QSslSocket. Done-by: Albert Astals Cid Done-by: Timur Pocheptsov Change-Id: I4a97cc789b62763763cf41c44157ef0a9fd6cbec Reviewed-by: Lars Knoll --- src/network/ssl/qssl.cpp | 2 + src/network/ssl/qssl.h | 5 +- src/network/ssl/qsslcontext_openssl11.cpp | 87 ++++++++++++++++--- src/network/ssl/qsslcontext_opensslpre11.cpp | 15 ++++ src/network/ssl/qsslsocket_mac.cpp | 12 +++ src/network/ssl/qsslsocket_openssl.cpp | 6 ++ .../ssl/qsslsocket_openssl11_symbols_p.h | 4 + .../ssl/qsslsocket_openssl_symbols.cpp | 4 + src/network/ssl/qsslsocket_winrt.cpp | 2 + .../network/ssl/qsslsocket/tst_qsslsocket.cpp | 60 ++++++++++++- 10 files changed, 182 insertions(+), 15 deletions(-) diff --git a/src/network/ssl/qssl.cpp b/src/network/ssl/qssl.cpp index 3a0983e8b5..19d99bc489 100644 --- a/src/network/ssl/qssl.cpp +++ b/src/network/ssl/qssl.cpp @@ -129,6 +129,8 @@ Q_LOGGING_CATEGORY(lcSsl, "qt.network.ssl"); \value DtlsV1_0OrLater DTLSv1.0 and later versions. \value DtlsV1_2 DTLSv1.2 \value DtlsV1_2OrLater DTLSv1.2 and later versions. + \value TlsV1_3 TLSv1.3. (Since Qt 5.12) + \value TlsV1_3OrLater TLSv1.3 and later versions. (Since Qt 5.12) \value UnknownProtocol The cipher's protocol cannot be determined. \value AnyProtocol The socket understands SSLv2, SSLv3, TLSv1.0 and all supported later versions of TLS. This value is used by QSslSocket only. diff --git a/src/network/ssl/qssl.h b/src/network/ssl/qssl.h index dd268cd86d..60362cb410 100644 --- a/src/network/ssl/qssl.h +++ b/src/network/ssl/qssl.h @@ -91,12 +91,13 @@ namespace QSsl { TlsV1_1OrLater, TlsV1_2OrLater, -#if QT_CONFIG(dtls) || defined(Q_CLANG_QDOC) DtlsV1_0, DtlsV1_0OrLater, DtlsV1_2, DtlsV1_2OrLater, -#endif + + TlsV1_3, + TlsV1_3OrLater, UnknownProtocol = -1 }; diff --git a/src/network/ssl/qsslcontext_openssl11.cpp b/src/network/ssl/qsslcontext_openssl11.cpp index 708cb7bb0e..02ce466c80 100644 --- a/src/network/ssl/qsslcontext_openssl11.cpp +++ b/src/network/ssl/qsslcontext_openssl11.cpp @@ -105,7 +105,24 @@ init_context: isDtls = true; sslContext->ctx = q_SSL_CTX_new(client ? q_DTLS_client_method() : q_DTLS_server_method()); break; +#else // dtls + case QSsl::DtlsV1_0: + case QSsl::DtlsV1_0OrLater: + case QSsl::DtlsV1_2: + case QSsl::DtlsV1_2OrLater: + sslContext->ctx = nullptr; + unsupportedProtocol = true; + qCWarning(lcSsl, "DTLS protocol requested, but feature 'dtls' is disabled"); + break; #endif // dtls + case QSsl::TlsV1_3: + case QSsl::TlsV1_3OrLater: +#if !defined(TLS1_3_VERSION) + qCWarning(lcSsl, "TLS 1.3 is not supported"); + sslContext->ctx = nullptr; + unsupportedProtocol = true; + break; +#endif // TLS1_3_VERSION default: // The ssl options will actually control the supported methods sslContext->ctx = q_SSL_CTX_new(client ? q_TLS_client_method() : q_TLS_server_method()); @@ -155,6 +172,16 @@ init_context: minVersion = TLS1_2_VERSION; maxVersion = TLS1_2_VERSION; break; + case QSsl::TlsV1_3: +#ifdef TLS1_3_VERSION + minVersion = TLS1_3_VERSION; + maxVersion = TLS1_3_VERSION; +#else + // This protocol is not supported by OpenSSL 1.1 and we handle + // it as an error (see the code above). + Q_UNREACHABLE(); +#endif // TLS1_3_VERSION + break; // Ranges: case QSsl::TlsV1SslV3: case QSsl::AnyProtocol: @@ -192,6 +219,17 @@ init_context: maxVersion = DTLS_MAX_VERSION; break; #endif // dtls + case QSsl::TlsV1_3OrLater: +#ifdef TLS1_3_VERSION + minVersion = TLS1_3_VERSION; + maxVersion = 0; + break; +#else + // This protocol is not supported by OpenSSL 1.1 and we handle + // it as an error (see the code above). + Q_UNREACHABLE(); + break; +#endif // TLS1_3_VERSION case QSsl::SslV2: // This protocol is not supported by OpenSSL 1.1 and we handle // it as an error (see the code above). @@ -223,23 +261,52 @@ init_context: // http://www.openssl.org/docs/ssl/SSL_CTX_set_mode.html q_SSL_CTX_set_mode(sslContext->ctx, SSL_MODE_RELEASE_BUFFERS); + auto filterCiphers = [](const QList &ciphers, bool selectTls13) + { + QByteArray cipherString; + bool first = true; + + for (const QSslCipher &cipher : qAsConst(ciphers)) { + const bool isTls13Cipher = cipher.protocol() == QSsl::TlsV1_3 || cipher.protocol() == QSsl::TlsV1_3OrLater; + if (selectTls13 != isTls13Cipher) + continue; + + if (first) + first = false; + else + cipherString.append(':'); + cipherString.append(cipher.name().toLatin1()); + } + return cipherString; + }; + // Initialize ciphers - QByteArray cipherString; - bool first = true; QList ciphers = sslContext->sslConfiguration.ciphers(); if (ciphers.isEmpty()) ciphers = isDtls ? q_getDefaultDtlsCiphers() : QSslSocketPrivate::defaultCiphers(); - for (const QSslCipher &cipher : qAsConst(ciphers)) { - if (first) - first = false; - else - cipherString.append(':'); - cipherString.append(cipher.name().toLatin1()); + const QByteArray preTls13Ciphers = filterCiphers(ciphers, false); + + if (preTls13Ciphers.size()) { + if (!q_SSL_CTX_set_cipher_list(sslContext->ctx, preTls13Ciphers.data())) { + sslContext->errorStr = QSslSocket::tr("Invalid or empty cipher list (%1)").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); + sslContext->errorCode = QSslError::UnspecifiedError; + return; + } } - if (!q_SSL_CTX_set_cipher_list(sslContext->ctx, cipherString.data())) { - sslContext->errorStr = QSslSocket::tr("Invalid or empty cipher list (%1)").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); + const QByteArray tls13Ciphers = filterCiphers(ciphers, true); +#ifdef TLS1_3_VERSION + if (tls13Ciphers.size()) { + if (!q_SSL_CTX_set_ciphersuites(sslContext->ctx, tls13Ciphers.data())) { + sslContext->errorStr = QSslSocket::tr("Invalid or empty cipher list (%1)").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); + sslContext->errorCode = QSslError::UnspecifiedError; + return; + } + } +#endif // TLS1_3_VERSION + if (!preTls13Ciphers.size() && !tls13Ciphers.size()) { + sslContext->errorStr = QSslSocket::tr("Invalid or empty cipher list (%1)").arg(QStringLiteral("")); sslContext->errorCode = QSslError::UnspecifiedError; return; } diff --git a/src/network/ssl/qsslcontext_opensslpre11.cpp b/src/network/ssl/qsslcontext_opensslpre11.cpp index c8be2ecb31..34537d1da4 100644 --- a/src/network/ssl/qsslcontext_opensslpre11.cpp +++ b/src/network/ssl/qsslcontext_opensslpre11.cpp @@ -104,6 +104,15 @@ init_context: isDtls = true; sslContext->ctx = q_SSL_CTX_new(client ? q_DTLS_client_method() : q_DTLS_server_method()); break; +#else // dtls + case QSsl::DtlsV1_0: + case QSsl::DtlsV1_0OrLater: + case QSsl::DtlsV1_2: + case QSsl::DtlsV1_2OrLater: + sslContext->ctx = nullptr; + unsupportedProtocol = true; + qCWarning(lcSsl, "DTLS protocol requested, but feature 'dtls' is disabled"); + break; #endif // dtls case QSsl::SslV2: #ifndef OPENSSL_NO_SSL2 @@ -168,6 +177,12 @@ init_context: unsupportedProtocol = true; #endif break; + case QSsl::TlsV1_3: + case QSsl::TlsV1_3OrLater: + // TLS 1.3 is not supported by the system, but chosen deliberately -> error + sslContext->ctx = nullptr; + unsupportedProtocol = true; + break; } if (!client && isDtls && configuration.peerVerifyMode() != QSslSocket::VerifyNone) { diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp index 9166e0ac29..65d98758ac 100644 --- a/src/network/ssl/qsslsocket_mac.cpp +++ b/src/network/ssl/qsslsocket_mac.cpp @@ -1110,6 +1110,18 @@ bool QSslSocketBackendPrivate::setSessionProtocol() return false; } + // SecureTransport has kTLSProtocol13 constant and also, kTLSProtocolMaxSupported. + // Calling SSLSetProtocolVersionMax/Min with any of these two constants results + // in errInvalidParam and a failure to set the protocol version. This means + // no TLS 1.3 on macOS and iOS. + switch (configuration.protocol) { + case QSsl::TlsV1_3: + case QSsl::TlsV1_3OrLater: + qCWarning(lcSsl) << plainSocket << "SecureTransport does not support TLS 1.3"; + return false; + default:; + } + OSStatus err = errSecSuccess; if (configuration.protocol == QSsl::SslV3) { diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 64501a75e8..e7d2478092 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -180,6 +180,8 @@ QSslCipher QSslSocketBackendPrivate::QSslCipher_from_SSL_CIPHER(const SSL_CIPHER ciph.d->protocol = QSsl::TlsV1_1; else if (protoString == QLatin1String("TLSv1.2")) ciph.d->protocol = QSsl::TlsV1_2; + else if (protoString == QLatin1String("TLSv1.3")) + ciph.d->protocol = QSsl::TlsV1_3; if (descriptionList.at(2).startsWith(QLatin1String("Kx="))) ciph.d->keyExchangeMethod = descriptionList.at(2).mid(3).toString(); @@ -291,6 +293,8 @@ long QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SslProtocol protocol, Q options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1; else if (protocol == QSsl::TlsV1_2OrLater) options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1; + else if (protocol == QSsl::TlsV1_3OrLater) + options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1_2; #endif else options = SSL_OP_ALL; @@ -1294,6 +1298,8 @@ QSsl::SslProtocol QSslSocketBackendPrivate::sessionProtocol() const return QSsl::TlsV1_1; case 0x303: return QSsl::TlsV1_2; + case 0x304: + return QSsl::TlsV1_3; } return QSsl::UnknownProtocol; diff --git a/src/network/ssl/qsslsocket_openssl11_symbols_p.h b/src/network/ssl/qsslsocket_openssl11_symbols_p.h index 844c3437be..fae007e12d 100644 --- a/src/network/ssl/qsslsocket_openssl11_symbols_p.h +++ b/src/network/ssl/qsslsocket_openssl11_symbols_p.h @@ -130,6 +130,10 @@ const char *q_OpenSSL_version(int type); unsigned long q_SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *session); unsigned long q_SSL_set_options(SSL *s, unsigned long op); +#ifdef TLS1_3_VERSION +int q_SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str); +#endif + #if QT_CONFIG(dtls) // Functions and types required for DTLS support: extern "C" diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index 5482440b98..781b3d6640 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -161,6 +161,7 @@ DEFINEFUNC(void, OPENSSL_sk_free, OPENSSL_STACK *a, a, return, DUMMYARG) DEFINEFUNC2(void *, OPENSSL_sk_value, OPENSSL_STACK *a, a, int b, b, return nullptr, return) DEFINEFUNC(int, SSL_session_reused, SSL *a, a, return 0, return) DEFINEFUNC2(unsigned long, SSL_CTX_set_options, SSL_CTX *ctx, ctx, unsigned long op, op, return 0, return) +DEFINEFUNC2(int, SSL_CTX_set_ciphersuites, SSL_CTX *ctx, ctx, const char *str, str, return 0, return) DEFINEFUNC3(size_t, SSL_get_client_random, SSL *a, a, unsigned char *out, out, size_t outlen, outlen, return 0, return) DEFINEFUNC3(size_t, SSL_SESSION_get_master_key, const SSL_SESSION *ses, ses, unsigned char *out, out, size_t outlen, outlen, return 0, return) DEFINEFUNC6(int, CRYPTO_get_ex_new_index, int class_index, class_index, long argl, argl, void *argp, argp, CRYPTO_EX_new *new_func, new_func, CRYPTO_EX_dup *dup_func, dup_func, CRYPTO_EX_free *free_func, free_func, return -1, return) @@ -966,6 +967,9 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(OPENSSL_sk_value) RESOLVEFUNC(DH_get0_pqg) RESOLVEFUNC(SSL_CTX_set_options) +#ifdef TLS1_3_VERSION + RESOLVEFUNC(SSL_CTX_set_ciphersuites) +#endif // TLS 1.3 or OpenSSL > 1.1.1 RESOLVEFUNC(SSL_get_client_random) RESOLVEFUNC(SSL_SESSION_get_master_key) RESOLVEFUNC(SSL_session_reused) diff --git a/src/network/ssl/qsslsocket_winrt.cpp b/src/network/ssl/qsslsocket_winrt.cpp index e72edcbc52..cc69b9ac96 100644 --- a/src/network/ssl/qsslsocket_winrt.cpp +++ b/src/network/ssl/qsslsocket_winrt.cpp @@ -251,6 +251,8 @@ void QSslSocketBackendPrivate::startClientEncryption() case QSsl::TlsV1_0OrLater: case QSsl::TlsV1_1OrLater: case QSsl::TlsV1_2OrLater: + case QSsl::TlsV1_3: + case QSsl::TlsV1_3OrLater: // TlsV1_0OrLater, TlsV1_1OrLater and TlsV1_2OrLater are disabled on WinRT // because there is no good way to map them to the native API. setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError, diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index b759aed074..6158347f62 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -1025,6 +1025,26 @@ void tst_QSslSocket::protocol() socket->abort(); } #endif +#ifdef TLS1_3_VERSION + { + // qt-test-server probably doesn't allow TLSV1.3 + socket->setProtocol(QSsl::TlsV1_3); + QCOMPARE(socket->protocol(), QSsl::TlsV1_3); + socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443); + if (setProxy && !socket->waitForEncrypted()) + QSKIP("TLS 1.3 is not supported by the test server or the test is flaky - see QTBUG-29941"); + QCOMPARE(socket->protocol(), QSsl::TlsV1_3); + socket->abort(); + QCOMPARE(socket->protocol(), QSsl::TlsV1_3); + socket->connectToHost(QtNetworkSettings::serverName(), 443); + QVERIFY2(socket->waitForConnected(), qPrintable(socket->errorString())); + socket->startClientEncryption(); + if (setProxy && !socket->waitForEncrypted()) + QSKIP("TLS 1.3 is not supported by the test server or the test is flaky - see QTBUG-29941"); + QCOMPARE(socket->sessionProtocol(), QSsl::TlsV1_3); + socket->abort(); + } +#endif // TLS1_3_VERSION #if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) { // qt-test-server allows SSLV2. @@ -1279,7 +1299,9 @@ void tst_QSslSocket::protocolServerSide_data() QTest::newRow("tls1.0orlater-tls1.0") << QSsl::TlsV1_0OrLater << QSsl::TlsV1_0 << true; QTest::newRow("tls1.0orlater-tls1.1") << QSsl::TlsV1_0OrLater << QSsl::TlsV1_1 << true; QTest::newRow("tls1.0orlater-tls1.2") << QSsl::TlsV1_0OrLater << QSsl::TlsV1_2 << true; - +#ifdef TLS1_3_VERSION + QTest::newRow("tls1.0orlater-tls1.3") << QSsl::TlsV1_0OrLater << QSsl::TlsV1_3 << true; +#endif #if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) QTest::newRow("tls1.1orlater-ssl2") << QSsl::TlsV1_1OrLater << QSsl::SslV2 << false; #endif @@ -1290,7 +1312,9 @@ void tst_QSslSocket::protocolServerSide_data() QTest::newRow("tls1.1orlater-tls1.0") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_0 << false; QTest::newRow("tls1.1orlater-tls1.1") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_1 << true; QTest::newRow("tls1.1orlater-tls1.2") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_2 << true; - +#ifdef TLS1_3_VERSION + QTest::newRow("tls1.1orlater-tls1.3") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_3 << true; +#endif #if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) QTest::newRow("tls1.2orlater-ssl2") << QSsl::TlsV1_2OrLater << QSsl::SslV2 << false; #endif @@ -1300,6 +1324,21 @@ void tst_QSslSocket::protocolServerSide_data() QTest::newRow("tls1.2orlater-tls1.0") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_0 << false; QTest::newRow("tls1.2orlater-tls1.1") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_1 << false; QTest::newRow("tls1.2orlater-tls1.2") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_2 << true; +#ifdef TLS1_3_VERSION + QTest::newRow("tls1.2orlater-tls1.3") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_3 << true; +#endif +#ifdef TLS1_3_VERSION +#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) + QTest::newRow("tls1.3orlater-ssl2") << QSsl::TlsV1_3OrLater << QSsl::SslV2 << false; +#endif +#if !defined(OPENSSL_NO_SSL3) + QTest::newRow("tls1.3orlater-ssl3") << QSsl::TlsV1_3OrLater << QSsl::SslV3 << false; +#endif + QTest::newRow("tls1.3orlater-tls1.0") << QSsl::TlsV1_3OrLater << QSsl::TlsV1_0 << false; + QTest::newRow("tls1.3orlater-tls1.1") << QSsl::TlsV1_3OrLater << QSsl::TlsV1_1 << false; + QTest::newRow("tls1.3orlater-tls1.2") << QSsl::TlsV1_3OrLater << QSsl::TlsV1_2 << false; + QTest::newRow("tls1.3orlater-tls1.3") << QSsl::TlsV1_3OrLater << QSsl::TlsV1_3 << true; +#endif // TLS1_3_VERSION QTest::newRow("any-tls1.0") << QSsl::AnyProtocol << QSsl::TlsV1_0 << true; QTest::newRow("any-tls1ssl3") << QSsl::AnyProtocol << QSsl::TlsV1SslV3 << true; @@ -3505,7 +3544,12 @@ protected: socket = new QSslSocket(this); socket->setSslConfiguration(config); socket->setPeerVerifyMode(peerVerifyMode); - socket->setProtocol(protocol); + if (QSslSocket::sslLibraryVersionNumber() > 0x10101000L) { + // FIXME. With OpenSSL 1.1.1 and TLS 1.3 PSK auto-test is broken. + socket->setProtocol(QSsl::TlsV1_2); + } else { + socket->setProtocol(protocol); + } if (ignoreSslErrors) connect(socket, SIGNAL(sslErrors(QList)), this, SLOT(ignoreErrorSlot())); @@ -3885,6 +3929,11 @@ void tst_QSslSocket::pskServer() return; QSslSocket socket; +#ifdef TLS1_3_VERSION + // FIXME: with OpenSSL 1.1.1 (thus TLS 1.3) test is known to fail + // due to the different PSK mechanism (?) - to be investigated ASAP. + socket.setProtocol(QSsl::TlsV1_2); +#endif this->socket = &socket; QSignalSpy connectedSpy(&socket, SIGNAL(connected())); @@ -3970,6 +4019,11 @@ void tst_QSslSocket::signatureAlgorithm_data() if (QSslSocket::sslLibraryVersionNumber() < 0x10002000L) QSKIP("Signature algorithms cannot be tested with OpenSSL < 1.0.2"); + if (QSslSocket::sslLibraryVersionNumber() >= 0x10101000L) { + // FIXME: investigate if this test makes any sense with TLS 1.3. + QSKIP("Test is not valid for TLS 1.3/OpenSSL 1.1.1"); + } + QTest::addColumn("serverSigAlgPairs"); QTest::addColumn("serverProtocol"); QTest::addColumn("clientSigAlgPairs"); From efc7e02911f2244c693fe8336f7b4b1c0ea3bc09 Mon Sep 17 00:00:00 2001 From: Janne Koskinen Date: Wed, 24 Oct 2018 14:57:44 +0200 Subject: [PATCH 0213/1650] INTEGRITY: Fix missing uint/int 128 support for 64-bit ARM Add 64bit specializations for mul_overflow. Change-Id: I8bba69233dd71b94346983a100cf4d69bfc686f7 Reviewed-by: Thiago Macieira --- src/corelib/global/qnumeric_p.h | 36 +++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h index 9c8514f5a3..e318c3759b 100644 --- a/src/corelib/global/qnumeric_p.h +++ b/src/corelib/global/qnumeric_p.h @@ -64,6 +64,10 @@ #include #endif +# if defined(Q_OS_INTEGRITY) && defined(Q_PROCESSOR_ARM_64) +#include +#endif + #if !defined(Q_CC_MSVC) && (defined(Q_OS_QNX) || defined(Q_CC_INTEL)) # include # ifdef isnan @@ -323,6 +327,38 @@ mul_overflow(T v1, T v2, T *r) return lr > std::numeric_limits::max() || lr < std::numeric_limits::min(); } +# if defined(Q_OS_INTEGRITY) && defined(Q_PROCESSOR_ARM_64) +template <> inline bool mul_overflow(quint64 v1, quint64 v2, quint64 *r) +{ + *r = v1 * v2; + return __MULUH64(v1, v2); +} +template <> inline bool mul_overflow(qint64 v1, qint64 v2, qint64 *r) +{ + qint64 high = __MULSH64(v1, v2); + if (high == 0) { + *r = v1 * v2; + return *r < 0; + } + if (high == -1) { + *r = v1 * v2; + return *r >= 0; + } + return true; +} + +template <> inline bool mul_overflow(uint64_t v1, uint64_t v2, uint64_t *r) +{ + return mul_overflow(v1,v2,reinterpret_cast(r)); +} + +template <> inline bool mul_overflow(int64_t v1, int64_t v2, int64_t *r) +{ + return mul_overflow(v1,v2,reinterpret_cast(r)); +} + +#endif + # if defined(Q_CC_MSVC) && defined(Q_PROCESSOR_X86) // We can use intrinsics for the unsigned operations with MSVC template <> inline bool add_overflow(unsigned v1, unsigned v2, unsigned *r) From 1dd6433b19b51f4c43a7f3c34314cc50edaeda34 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 11 Sep 2018 10:38:43 +0200 Subject: [PATCH 0214/1650] qmake: fix .prl file generation for bundles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit amends 2b27646146a. Fixes: QTBUG-70444 Change-Id: I8bd310f5624ea0ac9260c7d9ea0d29b0c9caa077 Reviewed-by: Tor Arne Vestbø --- qmake/generators/makefile.cpp | 2 -- qmake/generators/unix/unixmake2.cpp | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index e41e391cad..b7e591d2ab 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -1101,8 +1101,6 @@ QString MakefileGenerator::prlFileName(bool fixify) { QString ret = project->first("PRL_TARGET") + Option::prl_ext; - if(!project->isEmpty("QMAKE_BUNDLE")) - ret.prepend(project->first("QMAKE_BUNDLE") + Option::dir_sep); if(fixify) { if(!project->isEmpty("DESTDIR")) ret.prepend(project->first("DESTDIR").toQString()); diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index 976751b02c..d3abedb50b 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -1225,6 +1225,8 @@ void UnixMakefileGenerator::init2() else ar_cmd.append("$(AR) $(TARGETA) $(OBJECTS)"); if (!project->isEmpty("QMAKE_BUNDLE")) { + project->values("PRL_TARGET").prepend( + project->first("QMAKE_BUNDLE") + Option::dir_sep + project->first("TARGET")); ProString bundle_loc = project->first("QMAKE_BUNDLE_LOCATION"); if(!bundle_loc.isEmpty() && !bundle_loc.startsWith("/")) bundle_loc.prepend("/"); From 47dc8107243a22df91fb911184a197cadb80c2cb Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 3 Nov 2016 09:38:44 +0100 Subject: [PATCH 0215/1650] Manual test foreignwindows: Add option to recover lost windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an option that moves windows back to the top left corner, which is useful when some window (of some application saving its position) is lost after changing the monitor setup. Change-Id: If358b1ed7f481f2bb98e375e88f11049f97a4a91 Reviewed-by: Morten Johan Sørvig --- tests/manual/foreignwindows/main.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/manual/foreignwindows/main.cpp b/tests/manual/foreignwindows/main.cpp index 74c6d8c376..44aff54773 100644 --- a/tests/manual/foreignwindows/main.cpp +++ b/tests/manual/foreignwindows/main.cpp @@ -195,6 +195,9 @@ static QString description(const QString &appName) "tests embedding foreign windows into Qt.\n\nUse cases:\n\n" << appName << " -a Dump a list of all native window ids.\n" << appName << " Dump information on the window.\n" + << appName << " -m Move window to top left corner\n" + << QByteArray(appName.size(), ' ') + << " (recover lost windows after changing monitor setups).\n" << appName << " -c Dump information on the window continuously.\n" << appName << " -e Embed window into a Qt widget.\n" << "\nOn Windows, class names of well known controls (EDIT, BUTTON...) can be\n" @@ -245,6 +248,10 @@ int main(int argc, char *argv[]) parser.addOption(outputAllOption); QCommandLineOption continuousOption(QStringList() << QStringLiteral("c") << QStringLiteral("continuous"), QStringLiteral("Output continuously.")); + parser.addOption(outputAllOption); + QCommandLineOption moveOption(QStringList() << QStringLiteral("m") << QStringLiteral("move"), + QStringLiteral("Move window to top left corner.")); + parser.addOption(moveOption); parser.addOption(continuousOption); QCommandLineOption embedOption(QStringList() << QStringLiteral("e") << QStringLiteral("embed"), QStringLiteral("Embed a foreign window into a Qt widget.")); @@ -274,8 +281,12 @@ int main(int argc, char *argv[]) return -1; } QWindow *foreignWindow = QWindow::fromWinId(wid); + if (!foreignWindow) + return -1; foreignWindow->setObjectName("ForeignWindow" + QString::number(wid, 16)); windows.append(foreignWindow); + if (parser.isSet(moveOption)) + foreignWindow->setFramePosition(QGuiApplication::primaryScreen()->availableGeometry().topLeft()); } if (windows.isEmpty()) From d786c55b9e03c3cb8444ebeef8d31ca9d84071a0 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Wed, 7 Nov 2018 12:48:29 +0100 Subject: [PATCH 0216/1650] Make tst_qsslsocket::protocolServerSide() less flaky MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By accident, when we erroneously tried testing TlsV1_3 on macOS with SecureTransport (which does not support TLS 1.3) we hit this quite subtle problem: it can happen that a server-side socket is never created but a client (after TCP connection was established) fails in TLS initialization and ... stops the loop preventing SslServer::incomingConnection() from creating its socket. Then we dereference nullptr. Task-number: QTBUG-71638 Change-Id: I8dc5a4c53022a25aafe2c80a6931087517a48441 Reviewed-by: Mårten Nordheim Reviewed-by: Edward Welbourne --- .../auto/network/ssl/qsslsocket/tst_qsslsocket.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index b759aed074..f45a5af5a1 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -1343,13 +1343,19 @@ void tst_QSslSocket::protocolServerSide() QAbstractSocket::SocketState expectedState = (works) ? QAbstractSocket::ConnectedState : QAbstractSocket::UnconnectedState; // Determine whether the client or the server caused the event loop // to quit due to a socket error, and investigate the culprit. - if (server.socket->error() != QAbstractSocket::UnknownSocketError) { + if (client.error() != QAbstractSocket::UnknownSocketError) { + // It can happen that the client, after TCP connection established, before + // incomingConnection() slot fired, hits TLS initialization error and stops + // the loop, so the server socket is not created yet. + if (server.socket) + QVERIFY(server.socket->error() == QAbstractSocket::UnknownSocketError); + + QCOMPARE(int(client.state()), int(expectedState)); + } else if (server.socket->error() != QAbstractSocket::UnknownSocketError) { QVERIFY(client.error() == QAbstractSocket::UnknownSocketError); QCOMPARE(int(server.socket->state()), int(expectedState)); - } else if (client.error() != QAbstractSocket::UnknownSocketError) { - QVERIFY(server.socket->error() == QAbstractSocket::UnknownSocketError); - QCOMPARE(int(client.state()), int(expectedState)); } + QCOMPARE(client.isEncrypted(), works); } From 6d255b467becad5b5ffebbfa1d13e16b2dd20a64 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 1 Nov 2018 15:05:29 +0100 Subject: [PATCH 0217/1650] Fix composition example during OpenGL resizes Previous images were sometimes not cleared correctly. Change-Id: I62949b756bf797aa79c5160774f2f258e5c353dd Reviewed-by: Friedemann Kleint Reviewed-by: Laszlo Agocs --- examples/widgets/painting/composition/composition.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/widgets/painting/composition/composition.cpp b/examples/widgets/painting/composition/composition.cpp index 3bc31b1fce..e0abc5875c 100644 --- a/examples/widgets/painting/composition/composition.cpp +++ b/examples/widgets/painting/composition/composition.cpp @@ -358,10 +358,10 @@ void CompositionRenderer::paint(QPainter *painter) m_blitter.create(); int new_pbuf_size = m_pbuffer_size; - if (size().width() > m_pbuffer_size || size().height() > m_pbuffer_size) + while (size().width() > new_pbuf_size || size().height() > new_pbuf_size) new_pbuf_size *= 2; - if (size().width() < m_pbuffer_size/2 && size().height() < m_pbuffer_size/2) + while (size().width() < new_pbuf_size/2 && size().height() < new_pbuf_size/2) new_pbuf_size /= 2; if (!m_fbo || new_pbuf_size != m_pbuffer_size) { @@ -372,6 +372,9 @@ void CompositionRenderer::paint(QPainter *painter) if (size() != m_previous_size) { m_previous_size = size(); QPainter p(m_fbo.data()); + p.setCompositionMode(QPainter::CompositionMode_Source); + p.fillRect(QRect(QPoint(0, 0), size()), Qt::transparent); + p.setCompositionMode(QPainter::CompositionMode_SourceOver); drawBase(p); p.end(); m_base_tex = m_fbo->takeTexture(); From cfbb0d2b407e45d652d18ecd940adbbc8b3ddddd Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 7 Nov 2018 11:00:07 +0100 Subject: [PATCH 0218/1650] Avoid crashing with opaque opacity effect Fixes the crash, but doesn't fix the underlying bug. Task-number: QTBUG-60231 Change-Id: I5db9b151089b5c0e21e21443c77c725804d3059c Reviewed-by: Laszlo Agocs --- src/widgets/kernel/qwidget.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 8c680560d4..da0d530990 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -5858,7 +5858,11 @@ QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint * pixmapOffset -= effectRect.topLeft(); - const qreal dpr = context->painter->device()->devicePixelRatioF(); + qreal dpr(1.0); + if (const auto *paintDevice = context->painter->device()) + dpr = paintDevice->devicePixelRatioF(); + else + qWarning("QWidgetEffectSourcePrivate::pixmap: Painter not active"); QPixmap pixmap(effectRect.size() * dpr); pixmap.setDevicePixelRatio(dpr); From 825f98815683faea06144ab0262129b0367798ee Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Tue, 2 Oct 2018 12:59:24 +0200 Subject: [PATCH 0219/1650] Modernize the "textcodec" feature Also clean up QTextCodec usage in qmake build and some includes of qtextcodec.h. Change-Id: I0475b82690024054add4e85a8724c8ea3adcf62a Reviewed-by: Edward Welbourne Reviewed-by: Oswald Buddenhagen --- qmake/Makefile.unix | 6 +- qmake/Makefile.win32 | 1 - qmake/library/qmakevfs.cpp | 8 +- qmake/library/qmakevfs.h | 6 +- qmake/qmake.pro | 2 - src/corelib/codecs/codecs.pri | 88 ++++++++++--------- src/corelib/codecs/qiconvcodec.cpp | 2 - src/corelib/codecs/qicucodec.cpp | 4 - src/corelib/codecs/qicucodec_p.h | 6 +- src/corelib/codecs/qlatincodec.cpp | 4 - src/corelib/codecs/qlatincodec_p.h | 6 +- src/corelib/codecs/qsimplecodec.cpp | 4 - src/corelib/codecs/qsimplecodec_p.h | 6 +- src/corelib/codecs/qtextcodec.cpp | 5 +- src/corelib/codecs/qtextcodec.h | 7 +- src/corelib/codecs/qtextcodec_p.h | 9 +- src/corelib/codecs/qutfcodec.cpp | 4 +- src/corelib/codecs/qutfcodec_p.h | 10 ++- src/corelib/codecs/qwindowscodec_p.h | 2 + src/corelib/global/qconfig-bootstrapped.h | 1 - src/corelib/global/qt_pch.h | 2 + src/corelib/io/qsettings.cpp | 12 +-- src/corelib/io/qsettings.h | 2 +- src/corelib/kernel/qcoreapplication.cpp | 1 - src/corelib/kernel/qcoreglobaldata.cpp | 2 + src/corelib/kernel/qcoreglobaldata_p.h | 2 + src/corelib/kernel/qmimedata.cpp | 6 +- src/corelib/serialization/qtextstream.cpp | 24 ++--- src/corelib/serialization/qtextstream.h | 2 +- src/corelib/serialization/qtextstream_p.h | 6 +- src/corelib/serialization/qxmlstream.cpp | 42 ++++----- src/corelib/serialization/qxmlstream.g | 4 +- src/corelib/serialization/qxmlstream.h | 2 +- src/corelib/serialization/qxmlstream_p.h | 4 +- src/corelib/tools/qstring.cpp | 10 +-- src/corelib/tools/qstringbuilder.cpp | 1 - src/gui/image/qpnghandler.cpp | 1 - src/gui/kernel/qclipboard.cpp | 8 +- src/gui/kernel/qsimpledrag.cpp | 1 - src/gui/kernel/qt_gui_pch.h | 2 + src/gui/text/qtextdocument.cpp | 4 +- src/gui/text/qtextdocument.h | 2 +- src/gui/text/qtextdocumentfragment.cpp | 1 - src/gui/text/qtextdocumentwriter.cpp | 16 ++-- src/gui/text/qtextdocumentwriter.h | 2 +- src/gui/text/qtexthtmlparser.cpp | 1 - src/gui/text/qtextodfwriter.cpp | 2 +- src/platformsupport/clipboard/qmacmime.mm | 4 + .../input/libinput/qlibinputkeyboard.cpp | 4 +- .../platforms/cocoa/qcocoafiledialoghelper.mm | 1 - .../platforms/cocoa/qpaintengine_mac.mm | 1 - src/plugins/platforms/xcb/qxcbmime.cpp | 2 +- src/plugins/sqldrivers/mysql/qsql_mysql.cpp | 20 +++-- src/tools/uic/main.cpp | 2 +- src/widgets/kernel/qapplication.cpp | 1 - src/widgets/kernel/qt_widgets_pch.h | 2 + src/widgets/widgets/qtextbrowser.cpp | 4 +- src/xml/dom/qdom.cpp | 10 ++- src/xml/sax/qxml.cpp | 14 +-- 59 files changed, 206 insertions(+), 202 deletions(-) diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index 426387f0c2..e9f8c48651 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -17,7 +17,7 @@ OBJS = \ #qt code (please keep in order matching DEPEND_SRC) QOBJS = \ - qtextcodec.o qutfcodec.o \ + qutfcodec.o \ qglobal.o qlogging.o qmalloc.o qnumeric.o qoperatingsystemversion.o qrandom.o \ qabstractfileengine.o qbuffer.o qdatastream.o qdebug.o \ qdir.o qdiriterator.o \ @@ -66,7 +66,6 @@ DEPEND_SRC = \ $(QMKGENSRC)/win32/msvc_vcxproj.cpp \ $(QMKGENSRC)/win32/winmakefile.cpp \ $(QMKGENSRC)/xmloutput.cpp \ - $(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp \ $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp \ $(SOURCE_PATH)/src/corelib/global/qglobal.cpp \ $(SOURCE_PATH)/src/corelib/global/qlibraryinfo.cpp \ @@ -337,9 +336,6 @@ qcore_foundation.o: $(SOURCE_PATH)/src/corelib/kernel/qcore_foundation.mm qutfcodec.o: $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< -qtextcodec.o: $(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp - $(CXX) -c -o $@ $(CXXFLAGS) $< - qstring.o: $(SOURCE_PATH)/src/corelib/tools/qstring.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index 5292332187..6234616c2d 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -99,7 +99,6 @@ QTOBJS= \ qoperatingsystemversion.obj \ qoperatingsystemversion_win.obj \ qregexp.obj \ - qtextcodec.obj \ qutfcodec.obj \ qstring.obj \ qstring_compat.obj \ diff --git a/qmake/library/qmakevfs.cpp b/qmake/library/qmakevfs.cpp index 2239a2beec..265f1e60d3 100644 --- a/qmake/library/qmakevfs.cpp +++ b/qmake/library/qmakevfs.cpp @@ -35,7 +35,7 @@ using namespace QMakeInternal; #include #include -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) #include #endif @@ -49,7 +49,7 @@ QMakeVfs::QMakeVfs() , m_magicExisting(fL1S("existing")) #endif { -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) m_textCodec = 0; #endif } @@ -219,7 +219,7 @@ QMakeVfs::ReadResult QMakeVfs::readFile(int id, QString *contents, QString *errS return ReadOtherError; } *contents = -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) m_textCodec ? m_textCodec->toUnicode(bcont) : #endif QString::fromLocal8Bit(bcont); @@ -273,7 +273,7 @@ void QMakeVfs::invalidateContents() } #endif -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) void QMakeVfs::setTextCodec(const QTextCodec *textCodec) { m_textCodec = textCodec; diff --git a/qmake/library/qmakevfs.h b/qmake/library/qmakevfs.h index 1217225471..7d4f9bb890 100644 --- a/qmake/library/qmakevfs.h +++ b/qmake/library/qmakevfs.h @@ -38,7 +38,7 @@ # include #endif -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) QT_FORWARD_DECLARE_CLASS(QTextCodec) #endif @@ -89,7 +89,7 @@ public: void invalidateContents(); #endif -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) void setTextCodec(const QTextCodec *textCodec); #endif @@ -125,7 +125,7 @@ private: QString m_magicMissing; QString m_magicExisting; #endif -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) const QTextCodec *m_textCodec; #endif }; diff --git a/qmake/qmake.pro b/qmake/qmake.pro index 7c3ce3ef89..ebd61751b7 100644 --- a/qmake/qmake.pro +++ b/qmake/qmake.pro @@ -152,7 +152,6 @@ SOURCES += \ qstringlist.cpp \ qsystemerror.cpp \ qtemporaryfile.cpp \ - qtextcodec.cpp \ qtextstream.cpp \ qutfcodec.cpp \ quuid.cpp \ @@ -204,7 +203,6 @@ HEADERS += \ qstringmatcher.h \ qsystemerror_p.h \ qtemporaryfile.h \ - qtextcodec.h \ qtextstream.h \ qutfcodec.h \ quuid.h \ diff --git a/src/corelib/codecs/codecs.pri b/src/corelib/codecs/codecs.pri index d86d446c72..f1bbde1d69 100644 --- a/src/corelib/codecs/codecs.pri +++ b/src/corelib/codecs/codecs.pri @@ -1,62 +1,68 @@ # Qt core library codecs module HEADERS += \ - codecs/qlatincodec_p.h \ - codecs/qsimplecodec_p.h \ codecs/qtextcodec_p.h \ - codecs/qtextcodec.h \ codecs/qutfcodec_p.h SOURCES += \ - codecs/qlatincodec.cpp \ - codecs/qsimplecodec.cpp \ - codecs/qtextcodec.cpp \ codecs/qutfcodec.cpp -qtConfig(codecs) { +qtConfig(textcodec) { HEADERS += \ - codecs/qisciicodec_p.h \ - codecs/qtsciicodec_p.h + codecs/qlatincodec_p.h \ + codecs/qsimplecodec_p.h \ + codecs/qtextcodec.h SOURCES += \ - codecs/qisciicodec.cpp \ - codecs/qtsciicodec.cpp -} + codecs/qlatincodec.cpp \ + codecs/qsimplecodec.cpp \ + codecs/qtextcodec.cpp -qtConfig(icu) { - HEADERS += \ - codecs/qicucodec_p.h - SOURCES += \ - codecs/qicucodec.cpp -} else { - qtConfig(big_codecs) { + qtConfig(codecs) { HEADERS += \ - codecs/qgb18030codec_p.h \ - codecs/qeucjpcodec_p.h \ - codecs/qjiscodec_p.h \ - codecs/qsjiscodec_p.h \ - codecs/qeuckrcodec_p.h \ - codecs/qbig5codec_p.h + codecs/qisciicodec_p.h \ + codecs/qtsciicodec_p.h SOURCES += \ - codecs/qgb18030codec.cpp \ - codecs/qjpunicode.cpp \ - codecs/qeucjpcodec.cpp \ - codecs/qjiscodec.cpp \ - codecs/qsjiscodec.cpp \ - codecs/qeuckrcodec.cpp \ - codecs/qbig5codec.cpp + codecs/qisciicodec.cpp \ + codecs/qtsciicodec.cpp } - qtConfig(iconv) { - HEADERS += codecs/qiconvcodec_p.h - SOURCES += codecs/qiconvcodec.cpp - qtConfig(gnu-libiconv): \ - QMAKE_USE_PRIVATE += iconv - } + qtConfig(icu) { + HEADERS += \ + codecs/qicucodec_p.h + SOURCES += \ + codecs/qicucodec.cpp + } else { + qtConfig(big_codecs) { + HEADERS += \ + codecs/qgb18030codec_p.h \ + codecs/qeucjpcodec_p.h \ + codecs/qjiscodec_p.h \ + codecs/qsjiscodec_p.h \ + codecs/qeuckrcodec_p.h \ + codecs/qbig5codec_p.h - win32 { - SOURCES += codecs/qwindowscodec.cpp - HEADERS += codecs/qwindowscodec_p.h + SOURCES += \ + codecs/qgb18030codec.cpp \ + codecs/qjpunicode.cpp \ + codecs/qeucjpcodec.cpp \ + codecs/qjiscodec.cpp \ + codecs/qsjiscodec.cpp \ + codecs/qeuckrcodec.cpp \ + codecs/qbig5codec.cpp + } + + qtConfig(iconv) { + HEADERS += codecs/qiconvcodec_p.h + SOURCES += codecs/qiconvcodec.cpp + qtConfig(gnu-libiconv): \ + QMAKE_USE_PRIVATE += iconv + } + + win32 { + SOURCES += codecs/qwindowscodec.cpp + HEADERS += codecs/qwindowscodec_p.h + } } } diff --git a/src/corelib/codecs/qiconvcodec.cpp b/src/corelib/codecs/qiconvcodec.cpp index 330eb7c038..9c39727946 100644 --- a/src/corelib/codecs/qiconvcodec.cpp +++ b/src/corelib/codecs/qiconvcodec.cpp @@ -39,8 +39,6 @@ #include -QT_REQUIRE_CONFIG(iconv); - #include "qiconvcodec_p.h" #include "qtextcodec_p.h" #include diff --git a/src/corelib/codecs/qicucodec.cpp b/src/corelib/codecs/qicucodec.cpp index 06a6d95e82..101c3a3278 100644 --- a/src/corelib/codecs/qicucodec.cpp +++ b/src/corelib/codecs/qicucodec.cpp @@ -39,8 +39,6 @@ #include "qicucodec_p.h" -#ifndef QT_NO_TEXTCODEC - #include "qtextcodec_p.h" #include "qutfcodec_p.h" #include "qlatincodec_p.h" @@ -698,5 +696,3 @@ int QIcuCodec::mibEnum() const } QT_END_NAMESPACE - -#endif // QT_NO_TEXTCODEC diff --git a/src/corelib/codecs/qicucodec_p.h b/src/corelib/codecs/qicucodec_p.h index 0c2dbe17d6..1cbe4d4e7a 100644 --- a/src/corelib/codecs/qicucodec_p.h +++ b/src/corelib/codecs/qicucodec_p.h @@ -59,9 +59,9 @@ extern "C" { typedef struct UConverter UConverter; } -QT_BEGIN_NAMESPACE +QT_REQUIRE_CONFIG(textcodec); -#ifndef QT_NO_TEXTCODEC +QT_BEGIN_NAMESPACE class QIcuCodec : public QTextCodec { @@ -90,8 +90,6 @@ private: const char *m_name; }; -#endif // QT_NO_TEXTCODEC - QT_END_NAMESPACE #endif diff --git a/src/corelib/codecs/qlatincodec.cpp b/src/corelib/codecs/qlatincodec.cpp index cfbd481f1e..1b53d26ef4 100644 --- a/src/corelib/codecs/qlatincodec.cpp +++ b/src/corelib/codecs/qlatincodec.cpp @@ -40,8 +40,6 @@ #include "qlatincodec_p.h" #include "qlist.h" -#ifndef QT_NO_TEXTCODEC - QT_BEGIN_NAMESPACE QLatin1Codec::~QLatin1Codec() @@ -238,5 +236,3 @@ int QLatin15Codec::mibEnum() const } QT_END_NAMESPACE - -#endif // QT_NO_TEXTCODEC diff --git a/src/corelib/codecs/qlatincodec_p.h b/src/corelib/codecs/qlatincodec_p.h index 3e258e5ae1..26f9e596a9 100644 --- a/src/corelib/codecs/qlatincodec_p.h +++ b/src/corelib/codecs/qlatincodec_p.h @@ -54,9 +54,9 @@ #include #include "QtCore/qtextcodec.h" -QT_BEGIN_NAMESPACE +QT_REQUIRE_CONFIG(textcodec); -#ifndef QT_NO_TEXTCODEC +QT_BEGIN_NAMESPACE class QLatin1Codec : public QTextCodec { @@ -86,8 +86,6 @@ public: int mibEnum() const override; }; -#endif // QT_NO_TEXTCODEC - QT_END_NAMESPACE #endif // QLATINCODEC_P_H diff --git a/src/corelib/codecs/qsimplecodec.cpp b/src/corelib/codecs/qsimplecodec.cpp index beb0a08f62..9ab545d783 100644 --- a/src/corelib/codecs/qsimplecodec.cpp +++ b/src/corelib/codecs/qsimplecodec.cpp @@ -40,8 +40,6 @@ #include "qsimplecodec_p.h" #include "qlist.h" -#ifndef QT_NO_TEXTCODEC - QT_BEGIN_NAMESPACE #define LAST_MIB 2004 @@ -724,5 +722,3 @@ int QSimpleTextCodec::mibEnum() const } QT_END_NAMESPACE - -#endif // QT_NO_TEXTCODEC diff --git a/src/corelib/codecs/qsimplecodec_p.h b/src/corelib/codecs/qsimplecodec_p.h index 188c3f3cb4..a4b2a45e6b 100644 --- a/src/corelib/codecs/qsimplecodec_p.h +++ b/src/corelib/codecs/qsimplecodec_p.h @@ -54,9 +54,9 @@ #include #include "QtCore/qtextcodec.h" -QT_BEGIN_NAMESPACE +QT_REQUIRE_CONFIG(textcodec); -#ifndef QT_NO_TEXTCODEC +QT_BEGIN_NAMESPACE template class QAtomicPointer; @@ -79,8 +79,6 @@ private: mutable QAtomicPointer reverseMap; }; -#endif // QT_NO_TEXTCODEC - QT_END_NAMESPACE #endif // QSIMPLECODEC_P_H diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp index 790921610a..1ec443cd73 100644 --- a/src/corelib/codecs/qtextcodec.cpp +++ b/src/corelib/codecs/qtextcodec.cpp @@ -38,11 +38,10 @@ ****************************************************************************/ #include "qplatformdefs.h" + #include "qtextcodec.h" #include "qtextcodec_p.h" -#ifndef QT_NO_TEXTCODEC - #include "qbytearraymatcher.h" #include "qlist.h" #include "qfile.h" @@ -1221,5 +1220,3 @@ bool QTextDecoder::hasFailure() const } QT_END_NAMESPACE - -#endif // QT_NO_TEXTCODEC diff --git a/src/corelib/codecs/qtextcodec.h b/src/corelib/codecs/qtextcodec.h index 8153bebac8..c0261b7aa2 100644 --- a/src/corelib/codecs/qtextcodec.h +++ b/src/corelib/codecs/qtextcodec.h @@ -43,11 +43,10 @@ #include #include +QT_REQUIRE_CONFIG(textcodec); + QT_BEGIN_NAMESPACE - -#ifndef QT_NO_TEXTCODEC - class QTextCodec; class QIODevice; @@ -167,8 +166,6 @@ private: QTextCodec::ConverterState state; }; -#endif // QT_NO_TEXTCODEC - QT_END_NAMESPACE #endif // QTEXTCODEC_H diff --git a/src/corelib/codecs/qtextcodec_p.h b/src/corelib/codecs/qtextcodec_p.h index f3c2d090c9..6e19d1d30e 100644 --- a/src/corelib/codecs/qtextcodec_p.h +++ b/src/corelib/codecs/qtextcodec_p.h @@ -52,12 +52,13 @@ // #include -#include "qtextcodec.h" #include QT_BEGIN_NAMESPACE -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) + +#include "qtextcodec.h" #if defined(Q_OS_MAC) || defined(Q_OS_ANDROID) || defined(Q_OS_QNX) #define QT_LOCALE_IS_UTF8 @@ -82,7 +83,7 @@ struct QTextCodecUnalignedPointer bool qTextCodecNameMatch(const char *a, const char *b); -#else +#else // without textcodec: class QTextCodec { @@ -109,7 +110,7 @@ public: }; }; -#endif //QT_NO_TEXTCODEC +#endif // textcodec QT_END_NAMESPACE diff --git a/src/corelib/codecs/qutfcodec.cpp b/src/corelib/codecs/qutfcodec.cpp index ce1b092a54..0dffdd723e 100644 --- a/src/corelib/codecs/qutfcodec.cpp +++ b/src/corelib/codecs/qutfcodec.cpp @@ -922,7 +922,7 @@ QString QUtf32::convertToUnicode(const char *chars, int len, QTextCodec::Convert } -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) QUtf8Codec::~QUtf8Codec() { @@ -1076,6 +1076,6 @@ QList QUtf32LECodec::aliases() const return list; } -#endif //QT_NO_TEXTCODEC +#endif // textcodec QT_END_NAMESPACE diff --git a/src/corelib/codecs/qutfcodec_p.h b/src/corelib/codecs/qutfcodec_p.h index 659a229dae..d7743753af 100644 --- a/src/corelib/codecs/qutfcodec_p.h +++ b/src/corelib/codecs/qutfcodec_p.h @@ -52,7 +52,13 @@ // We mean it. // +#include +#include + +#if QT_CONFIG(textcodec) #include "QtCore/qtextcodec.h" +#endif + #include "private/qtextcodec_p.h" QT_BEGIN_NAMESPACE @@ -311,7 +317,7 @@ struct QUtf32 static QByteArray convertFromUnicode(const QChar *, int, QTextCodec::ConverterState *, DataEndianness = DetectEndianness); }; -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) class QUtf8Codec : public QTextCodec { public: @@ -391,7 +397,7 @@ public: }; -#endif // QT_NO_TEXTCODEC +#endif // textcodec QT_END_NAMESPACE diff --git a/src/corelib/codecs/qwindowscodec_p.h b/src/corelib/codecs/qwindowscodec_p.h index 2fd3c35378..1ca6d5567e 100644 --- a/src/corelib/codecs/qwindowscodec_p.h +++ b/src/corelib/codecs/qwindowscodec_p.h @@ -53,6 +53,8 @@ #include #include "qtextcodec.h" +QT_REQUIRE_CONFIG(textcodec); + QT_BEGIN_NAMESPACE class QWindowsLocalCodec: public QTextCodec diff --git a/src/corelib/global/qconfig-bootstrapped.h b/src/corelib/global/qconfig-bootstrapped.h index da66e3bcd3..229b4d17a1 100644 --- a/src/corelib/global/qconfig-bootstrapped.h +++ b/src/corelib/global/qconfig-bootstrapped.h @@ -127,7 +127,6 @@ #define QT_NO_COMPRESS #define QT_JSON_READONLY #define QT_NO_STANDARDPATHS -#define QT_NO_TEXTCODEC #define QT_FEATURE_textcodec -1 #else #define QT_FEATURE_codecs -1 diff --git a/src/corelib/global/qt_pch.h b/src/corelib/global/qt_pch.h index b3b526342d..76e46374c3 100644 --- a/src/corelib/global/qt_pch.h +++ b/src/corelib/global/qt_pch.h @@ -66,5 +66,7 @@ #include #include #include +#if QT_CONFIG(textcodec) #include #endif +#endif diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 4b1b9888d8..580fe6caf3 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -54,7 +54,7 @@ #include "qstandardpaths.h" #include -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) # include "qtextcodec.h" #endif @@ -677,7 +677,7 @@ void QSettingsPrivate::iniEscapedString(const QString &str, QByteArray &result, if (ch <= 0x1F || (ch >= 0x7F && !useCodec)) { result += "\\x" + QByteArray::number(ch, 16); escapeNextIfDigit = true; -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) } else if (useCodec) { // slow result += codec->fromUnicode(&unicode[i], 1); @@ -830,7 +830,7 @@ StNormal: ++j; } -#ifdef QT_NO_TEXTCODEC +#if !QT_CONFIG(textcodec) Q_UNUSED(codec) #else if (codec) { @@ -1668,7 +1668,7 @@ bool QConfFileSettingsPrivate::readIniFile(const QByteArray &data, int sectionPosition = 0; bool ok = true; -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) // detect utf8 BOM const uchar *dd = (const uchar *)data.constData(); if (data.size() >= 3 && dd[0] == 0xef && dd[1] == 0xbb && dd[2] == 0xbf) { @@ -2824,7 +2824,7 @@ QString QSettings::applicationName() const return d->applicationName; } -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) /*! \since 4.5 @@ -2877,7 +2877,7 @@ QTextCodec *QSettings::iniCodec() const return d->iniCodec; } -#endif // QT_NO_TEXTCODEC +#endif // textcodec /*! Returns a status code indicating the first error that was met by diff --git a/src/corelib/io/qsettings.h b/src/corelib/io/qsettings.h index d78edd23a2..ccfec787a6 100644 --- a/src/corelib/io/qsettings.h +++ b/src/corelib/io/qsettings.h @@ -178,7 +178,7 @@ public: QString organizationName() const; QString applicationName() const; -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) void setIniCodec(QTextCodec *codec); void setIniCodec(const char *codecName); QTextCodec *iniCodec() const; diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 4e32f90964..0ea969ece5 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -55,7 +55,6 @@ #include #include #include -#include #ifndef QT_NO_QOBJECT #include #include diff --git a/src/corelib/kernel/qcoreglobaldata.cpp b/src/corelib/kernel/qcoreglobaldata.cpp index e2087b9e64..c3ca2f74e4 100644 --- a/src/corelib/kernel/qcoreglobaldata.cpp +++ b/src/corelib/kernel/qcoreglobaldata.cpp @@ -38,7 +38,9 @@ ****************************************************************************/ #include "qcoreglobaldata_p.h" +#if QT_CONFIG(textcodec) #include "qtextcodec.h" +#endif QT_BEGIN_NAMESPACE diff --git a/src/corelib/kernel/qcoreglobaldata_p.h b/src/corelib/kernel/qcoreglobaldata_p.h index c3c2f7b4a4..fda6b52b6e 100644 --- a/src/corelib/kernel/qcoreglobaldata_p.h +++ b/src/corelib/kernel/qcoreglobaldata_p.h @@ -57,7 +57,9 @@ #include "QtCore/qreadwritelock.h" #include "QtCore/qhash.h" #include "QtCore/qbytearray.h" +#if QT_CONFIG(textcodec) #include "QtCore/qtextcodec.h" +#endif #include "QtCore/qmutex.h" QT_BEGIN_NAMESPACE diff --git a/src/corelib/kernel/qmimedata.cpp b/src/corelib/kernel/qmimedata.cpp index 73307e925a..c8ad1bc43f 100644 --- a/src/corelib/kernel/qmimedata.cpp +++ b/src/corelib/kernel/qmimedata.cpp @@ -42,7 +42,9 @@ #include "private/qobject_p.h" #include "qurl.h" #include "qstringlist.h" +#if QT_CONFIG(textcodec) #include "qtextcodec.h" +#endif QT_BEGIN_NAMESPACE @@ -150,7 +152,7 @@ QVariant QMimeDataPrivate::retrieveTypedData(const QString &format, QVariant::Ty if (data.type() == QVariant::ByteArray) { // see if we can convert to the requested type switch(type) { -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) case QVariant::String: { const QByteArray ba = data.toByteArray(); QTextCodec *codec = QTextCodec::codecForName("utf-8"); @@ -158,7 +160,7 @@ QVariant QMimeDataPrivate::retrieveTypedData(const QString &format, QVariant::Ty codec = QTextCodec::codecForHtml(ba, codec); return codec->toUnicode(ba); } -#endif // QT_NO_TEXTCODEC +#endif // textcodec case QVariant::Color: { QVariant newData = data; newData.convert(QVariant::Color); diff --git a/src/corelib/serialization/qtextstream.cpp b/src/corelib/serialization/qtextstream.cpp index ee3cb4efcb..c0a9854d8b 100644 --- a/src/corelib/serialization/qtextstream.cpp +++ b/src/corelib/serialization/qtextstream.cpp @@ -326,7 +326,7 @@ QT_BEGIN_NAMESPACE */ QTextStreamPrivate::QTextStreamPrivate(QTextStream *q_ptr) : -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) readConverterSavedState(0), #endif readConverterSavedStateOffset(0), @@ -347,12 +347,12 @@ QTextStreamPrivate::~QTextStreamPrivate() #endif delete device; } -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) delete readConverterSavedState; #endif } -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) static void resetCodecConverterStateHelper(QTextCodec::ConverterState *state) { state->~ConverterState(); @@ -401,7 +401,7 @@ void QTextStreamPrivate::reset() readBufferStartDevicePos = 0; lastTokenSize = 0; -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) codec = QTextCodec::codecForLocale(); resetCodecConverterStateHelper(&readConverterState); resetCodecConverterStateHelper(&writeConverterState); @@ -461,7 +461,7 @@ bool QTextStreamPrivate::fillReadBuffer(qint64 maxBytes) if (bytesRead <= 0) return false; -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) // codec auto detection, explicitly defaults to locale encoding if the // codec has been set to 0. if (!codec || autoDetectUnicode) { @@ -485,7 +485,7 @@ bool QTextStreamPrivate::fillReadBuffer(qint64 maxBytes) #endif int oldReadBufferSize = readBuffer.size(); -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) // convert to unicode readBuffer += Q_LIKELY(codec) ? codec->toUnicode(buf, bytesRead, &readConverterState) : QString::fromLatin1(buf, bytesRead); @@ -567,7 +567,7 @@ void QTextStreamPrivate::flushWriteBuffer() } #endif -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) if (!codec) codec = QTextCodec::codecForLocale(); #if defined (QTEXTSTREAM_DEBUG) @@ -786,7 +786,7 @@ inline void QTextStreamPrivate::consume(int size) */ inline void QTextStreamPrivate::saveConverterState(qint64 newPos) { -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) if (readConverterState.d) { // converter cannot be copied, so don't save anything // don't update readBufferStartDevicePos either @@ -807,7 +807,7 @@ inline void QTextStreamPrivate::saveConverterState(qint64 newPos) */ inline void QTextStreamPrivate::restoreToSavedConverterState() { -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) if (readConverterSavedState) { // we have a saved state // that means the converter can be copied @@ -1202,7 +1202,7 @@ bool QTextStream::seek(qint64 pos) return false; d->resetReadBuffer(); -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) // Reset the codec converter states. resetCodecConverterStateHelper(&d->readConverterState); resetCodecConverterStateHelper(&d->writeConverterState); @@ -1253,7 +1253,7 @@ qint64 QTextStream::pos() const QTextStreamPrivate *thatd = const_cast(d); thatd->readBuffer.clear(); -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) thatd->restoreToSavedConverterState(); if (d->readBufferStartDevicePos == 0) thatd->autoDetectUnicode = true; @@ -3021,7 +3021,7 @@ QTextStream &ws(QTextStream &stream) Equivalent to QTextStream::setRealNumberPrecision(\a precision). */ -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) /*! \relates QTextStream diff --git a/src/corelib/serialization/qtextstream.h b/src/corelib/serialization/qtextstream.h index ee0b09419d..5c766abc3e 100644 --- a/src/corelib/serialization/qtextstream.h +++ b/src/corelib/serialization/qtextstream.h @@ -98,7 +98,7 @@ public: explicit QTextStream(const QByteArray &array, QIODevice::OpenMode openMode = QIODevice::ReadOnly); virtual ~QTextStream(); -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) void setCodec(QTextCodec *codec); void setCodec(const char *codecName); QTextCodec *codec() const; diff --git a/src/corelib/serialization/qtextstream_p.h b/src/corelib/serialization/qtextstream_p.h index a642beddc4..172824d27d 100644 --- a/src/corelib/serialization/qtextstream_p.h +++ b/src/corelib/serialization/qtextstream_p.h @@ -54,7 +54,7 @@ #include #include "qtextstream.h" -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) #include "qtextcodec.h" #endif @@ -118,7 +118,7 @@ public: int stringOffset; QIODevice::OpenMode stringOpenMode; -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) // codec QTextCodec *codec; QTextCodec::ConverterState readConverterState; @@ -141,7 +141,7 @@ public: int lastTokenSize; bool deleteDevice; -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) bool autoDetectUnicode; #endif diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp index f18c4cc8e7..77a195a7e5 100644 --- a/src/corelib/serialization/qxmlstream.cpp +++ b/src/corelib/serialization/qxmlstream.cpp @@ -45,7 +45,9 @@ #include #include #include +#if QT_CONFIG(textcodec) #include +#endif #include #include #ifndef QT_BOOTSTRAPPED @@ -420,7 +422,7 @@ QXmlStreamReader::QXmlStreamReader(const QString &data) : d_ptr(new QXmlStreamReaderPrivate(this)) { Q_D(QXmlStreamReader); -#ifdef QT_NO_TEXTCODEC +#if !QT_CONFIG(textcodec) d->dataBuffer = data.toLatin1(); #else d->dataBuffer = d->codec->fromUnicode(data); @@ -515,7 +517,7 @@ void QXmlStreamReader::addData(const QString &data) { Q_D(QXmlStreamReader); d->lockEncoding = true; -#ifdef QT_NO_TEXTCODEC +#if !QT_CONFIG(textcodec) addData(data.toLatin1()); #else addData(d->codec->fromUnicode(data)); @@ -792,7 +794,7 @@ QXmlStreamReaderPrivate::QXmlStreamReaderPrivate(QXmlStreamReader *q) { device = 0; deleteDevice = false; -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) decoder = 0; #endif stack_size = 64; @@ -838,7 +840,7 @@ void QXmlStreamReaderPrivate::init() lineNumber = lastLineStart = characterOffset = 0; readBufferPos = 0; nbytesread = 0; -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) codec = QTextCodec::codecForMib(106); // utf8 delete decoder; decoder = 0; @@ -903,7 +905,7 @@ inline void QXmlStreamReaderPrivate::reallocateStack() QXmlStreamReaderPrivate::~QXmlStreamReaderPrivate() { -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) delete decoder; #endif free(sym_stack); @@ -1482,7 +1484,7 @@ uint QXmlStreamReaderPrivate::getChar_helper() characterOffset += readBufferPos; readBufferPos = 0; readBuffer.resize(0); -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) if (decoder) #endif nbytesread = 0; @@ -1503,7 +1505,7 @@ uint QXmlStreamReaderPrivate::getChar_helper() return StreamEOF; } -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) if (!decoder) { if (nbytesread < 4) { // the 4 is to cover 0xef 0xbb 0xbf plus // one extra for the utf8 codec @@ -1545,7 +1547,7 @@ uint QXmlStreamReaderPrivate::getChar_helper() } #else readBuffer = QString::fromLatin1(rawReadBuffer.data(), nbytesread); -#endif // QT_NO_TEXTCODEC +#endif // textcodec readBuffer.reserve(1); // keep capacity when calling resize() next time @@ -1816,7 +1818,7 @@ void QXmlStreamReaderPrivate::startDocument() if (!QXmlUtils::isEncName(value)) err = QXmlStream::tr("%1 is an invalid encoding name.").arg(value); else { -#ifdef QT_NO_TEXTCODEC +#if !QT_CONFIG(textcodec) readBuffer = QString::fromLatin1(rawReadBuffer.data(), nbytesread); #else QTextCodec *const newCodec = QTextCodec::codecForName(value.toLatin1()); @@ -1828,7 +1830,7 @@ void QXmlStreamReaderPrivate::startDocument() decoder = codec->makeDecoder(); decoder->toUnicode(&readBuffer, rawReadBuffer.data(), nbytesread); } -#endif // QT_NO_TEXTCODEC +#endif // textcodec } } else if (prefix.isEmpty() && key == QLatin1String("standalone")) { hasStandalone = true; @@ -2966,7 +2968,7 @@ public: ~QXmlStreamWriterPrivate() { if (deleteDevice) delete device; -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) delete encoder; #endif } @@ -2993,7 +2995,7 @@ public: NamespaceDeclaration emptyNamespace; int lastNamespaceDeclaration; -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) QTextCodec *codec; QTextEncoder *encoder; #endif @@ -3015,7 +3017,7 @@ QXmlStreamWriterPrivate::QXmlStreamWriterPrivate(QXmlStreamWriter *q) device = 0; stringDevice = 0; deleteDevice = false; -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) codec = QTextCodec::codecForMib(106); // utf8 encoder = codec->makeEncoder(QTextCodec::IgnoreHeader); // no byte order mark for utf8 #endif @@ -3032,7 +3034,7 @@ QXmlStreamWriterPrivate::QXmlStreamWriterPrivate(QXmlStreamWriter *q) void QXmlStreamWriterPrivate::checkIfASCIICompatibleCodec() { -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) Q_ASSERT(encoder); // test ASCII-compatibility using the letter 'a' QChar letterA = QLatin1Char('a'); @@ -3052,7 +3054,7 @@ void QXmlStreamWriterPrivate::write(const QStringRef &s) if (device) { if (hasIoError) return; -#ifdef QT_NO_TEXTCODEC +#if !QT_CONFIG(textcodec) QByteArray bytes = s.toLatin1(); #else QByteArray bytes = encoder->fromUnicode(s.constData(), s.size()); @@ -3075,7 +3077,7 @@ void QXmlStreamWriterPrivate::write(const QString &s) if (device) { if (hasIoError) return; -#ifdef QT_NO_TEXTCODEC +#if !QT_CONFIG(textcodec) QByteArray bytes = s.toLatin1(); #else QByteArray bytes = encoder->fromUnicode(s); @@ -3324,7 +3326,7 @@ QIODevice *QXmlStreamWriter::device() const } -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) /*! Sets the codec for this stream to \a codec. The codec is used for encoding any data that is written. By default, QXmlStreamWriter @@ -3382,7 +3384,7 @@ QTextCodec *QXmlStreamWriter::codec() const Q_D(const QXmlStreamWriter); return d->codec; } -#endif // QT_NO_TEXTCODEC +#endif // textcodec /*! \property QXmlStreamWriter::autoFormatting @@ -3847,7 +3849,7 @@ void QXmlStreamWriter::writeStartDocument(const QString &version) d->write(version); if (d->device) { // stringDevice does not get any encoding d->write("\" encoding=\""); -#ifdef QT_NO_TEXTCODEC +#if !QT_CONFIG(textcodec) d->write("iso-8859-1"); #else const QByteArray name = d->codec->name(); @@ -3871,7 +3873,7 @@ void QXmlStreamWriter::writeStartDocument(const QString &version, bool standalon d->write(version); if (d->device) { // stringDevice does not get any encoding d->write("\" encoding=\""); -#ifdef QT_NO_TEXTCODEC +#if !QT_CONFIG(textcodec) d->write("iso-8859-1"); #else const QByteArray name = d->codec->name(); diff --git a/src/corelib/serialization/qxmlstream.g b/src/corelib/serialization/qxmlstream.g index fd69a6e4af..10bfcd491c 100644 --- a/src/corelib/serialization/qxmlstream.g +++ b/src/corelib/serialization/qxmlstream.g @@ -291,7 +291,7 @@ public: QIODevice *device; bool deleteDevice; -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) QTextCodec *codec; QTextDecoder *decoder; #endif @@ -584,7 +584,7 @@ bool QXmlStreamReaderPrivate::parse() lockEncoding = true; documentVersion.clear(); documentEncoding.clear(); -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) if (decoder && decoder->hasFailure()) { raiseWellFormedError(QXmlStream::tr("Encountered incorrectly encoded content.")); readBuffer.clear(); diff --git a/src/corelib/serialization/qxmlstream.h b/src/corelib/serialization/qxmlstream.h index 2350d12dd6..d30c6bc01f 100644 --- a/src/corelib/serialization/qxmlstream.h +++ b/src/corelib/serialization/qxmlstream.h @@ -478,7 +478,7 @@ public: void setDevice(QIODevice *device); QIODevice *device() const; -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) void setCodec(QTextCodec *codec); void setCodec(const char *codecName); QTextCodec *codec() const; diff --git a/src/corelib/serialization/qxmlstream_p.h b/src/corelib/serialization/qxmlstream_p.h index f8b1ede943..61f501f81b 100644 --- a/src/corelib/serialization/qxmlstream_p.h +++ b/src/corelib/serialization/qxmlstream_p.h @@ -788,7 +788,7 @@ public: QIODevice *device; bool deleteDevice; -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) QTextCodec *codec; QTextDecoder *decoder; #endif @@ -1081,7 +1081,7 @@ bool QXmlStreamReaderPrivate::parse() lockEncoding = true; documentVersion.clear(); documentEncoding.clear(); -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) if (decoder && decoder->hasFailure()) { raiseWellFormedError(QXmlStream::tr("Encountered incorrectly encoded content.")); readBuffer.clear(); diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 82a065efc0..0a8b2b4238 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -44,7 +44,7 @@ #include "qregularexpression.h" #endif #include "qunicodetables_p.h" -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) #include #endif #include @@ -5057,11 +5057,11 @@ static QByteArray qt_convert_to_local_8bit(QStringView string) { if (string.isNull()) return QByteArray(); -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) QTextCodec *localeCodec = QTextCodec::codecForLocale(); if (localeCodec) return localeCodec->fromUnicode(string); -#endif // QT_NO_TEXTCODEC +#endif // textcodec return qt_convert_to_latin1(string); } @@ -5255,13 +5255,13 @@ QString QString::fromLocal8Bit_helper(const char *str, int size) QStringDataPtr empty = { Data::allocate(0) }; return QString(empty); } -#if !defined(QT_NO_TEXTCODEC) +#if QT_CONFIG(textcodec) if (size < 0) size = qstrlen(str); QTextCodec *codec = QTextCodec::codecForLocale(); if (codec) return codec->toUnicode(str, size); -#endif // !QT_NO_TEXTCODEC +#endif // textcodec return fromLatin1(str, size); } diff --git a/src/corelib/tools/qstringbuilder.cpp b/src/corelib/tools/qstringbuilder.cpp index 73748e55a3..081d7136a7 100644 --- a/src/corelib/tools/qstringbuilder.cpp +++ b/src/corelib/tools/qstringbuilder.cpp @@ -38,7 +38,6 @@ ****************************************************************************/ #include "qstringbuilder.h" -#include #include QT_BEGIN_NAMESPACE diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index 42b9e71087..53d9a8a49a 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -45,7 +45,6 @@ #include #include #include -#include #include #include diff --git a/src/gui/kernel/qclipboard.cpp b/src/gui/kernel/qclipboard.cpp index 771f0fe93d..a76150d91d 100644 --- a/src/gui/kernel/qclipboard.cpp +++ b/src/gui/kernel/qclipboard.cpp @@ -46,7 +46,9 @@ #include "qvariant.h" #include "qbuffer.h" #include "qimage.h" +#if QT_CONFIG(textcodec) #include "qtextcodec.h" +#endif #include "private/qguiapplication_p.h" #include @@ -298,16 +300,16 @@ QString QClipboard::text(QString &subtype, Mode mode) const const QByteArray rawData = data->data(QLatin1String("text/") + subtype); -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) QTextCodec* codec = QTextCodec::codecForMib(106); // utf-8 is default if (subtype == QLatin1String("html")) codec = QTextCodec::codecForHtml(rawData, codec); else codec = QTextCodec::codecForUtfText(rawData, codec); return codec->toUnicode(rawData); -#else //QT_NO_TEXTCODEC +#else // textcodec return rawData; -#endif //QT_NO_TEXTCODEC +#endif // textcodec } /*! diff --git a/src/gui/kernel/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp index 12e204a09f..c678a7479d 100644 --- a/src/gui/kernel/qsimpledrag.cpp +++ b/src/gui/kernel/qsimpledrag.cpp @@ -44,7 +44,6 @@ #include "qpixmap.h" #include "qevent.h" #include "qfile.h" -#include "qtextcodec.h" #include "qguiapplication.h" #include "qpoint.h" #include "qbuffer.h" diff --git a/src/gui/kernel/qt_gui_pch.h b/src/gui/kernel/qt_gui_pch.h index db12ba1078..aa5d3f0572 100644 --- a/src/gui/kernel/qt_gui_pch.h +++ b/src/gui/kernel/qt_gui_pch.h @@ -63,7 +63,9 @@ #include #include #include +#if QT_CONFIG(textcodec) #include +#endif #include #include diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 44d1b2f201..613ac8fa6c 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -51,7 +51,9 @@ #include #endif #include +#if QT_CONFIG(textcodec) #include +#endif #include #include #include @@ -181,7 +183,7 @@ QString Qt::convertFromPlainText(const QString &plain, Qt::WhiteSpaceMode mode) return rich; } -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) QTextCodec *Qt::codecForHtml(const QByteArray &ba) { return QTextCodec::codecForHtml(ba); diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h index 64e39d4648..140ed628b7 100644 --- a/src/gui/text/qtextdocument.h +++ b/src/gui/text/qtextdocument.h @@ -76,7 +76,7 @@ namespace Qt Q_GUI_EXPORT bool mightBeRichText(const QString&); Q_GUI_EXPORT QString convertFromPlainText(const QString &plain, WhiteSpaceMode mode = WhiteSpacePre); -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) Q_GUI_EXPORT QTextCodec *codecForHtml(const QByteArray &ba); #endif } diff --git a/src/gui/text/qtextdocumentfragment.cpp b/src/gui/text/qtextdocumentfragment.cpp index ea37695f4e..0c2cb6f87f 100644 --- a/src/gui/text/qtextdocumentfragment.cpp +++ b/src/gui/text/qtextdocumentfragment.cpp @@ -43,7 +43,6 @@ #include "qtextlist.h" #include -#include #include #include #include diff --git a/src/gui/text/qtextdocumentwriter.cpp b/src/gui/text/qtextdocumentwriter.cpp index 731aaf1fcf..5ea04fe9e9 100644 --- a/src/gui/text/qtextdocumentwriter.cpp +++ b/src/gui/text/qtextdocumentwriter.cpp @@ -41,7 +41,9 @@ #include #include #include +#if QT_CONFIG(textcodec) #include +#endif #include #include #include "qtextdocument.h" @@ -63,7 +65,7 @@ public: QByteArray format; QIODevice *device; bool deleteDevice; -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) QTextCodec *codec; #endif @@ -104,7 +106,7 @@ public: QTextDocumentWriterPrivate::QTextDocumentWriterPrivate(QTextDocumentWriter *qq) : device(0), deleteDevice(false), -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) codec(QTextCodec::codecForName("utf-8")), #endif q(qq) @@ -258,7 +260,7 @@ bool QTextDocumentWriter::write(const QTextDocument *document) #ifndef QT_NO_TEXTODFWRITER if (format == "odf" || format == "opendocumentformat" || format == "odt") { QTextOdfWriter writer(*document, d->device); -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) writer.setCodec(d->codec); #endif return writer.writeAll(); @@ -272,7 +274,7 @@ bool QTextDocumentWriter::write(const QTextDocument *document) return false; } QTextStream ts(d->device); -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) ts.setCodec(d->codec); ts << document->toHtml(d->codec->name()); #endif @@ -286,7 +288,7 @@ bool QTextDocumentWriter::write(const QTextDocument *document) return false; } QTextStream ts(d->device); -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) ts.setCodec(d->codec); #endif ts << document->toPlainText(); @@ -317,7 +319,7 @@ bool QTextDocumentWriter::write(const QTextDocumentFragment &fragment) uses UTF-8. */ -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) void QTextDocumentWriter::setCodec(QTextCodec *codec) { if (codec == 0) @@ -330,7 +332,7 @@ void QTextDocumentWriter::setCodec(QTextCodec *codec) /*! Returns the codec that is currently assigned to the writer. */ -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) QTextCodec *QTextDocumentWriter::codec() const { return d->codec; diff --git a/src/gui/text/qtextdocumentwriter.h b/src/gui/text/qtextdocumentwriter.h index 0502bf1a96..4a57b181b4 100644 --- a/src/gui/text/qtextdocumentwriter.h +++ b/src/gui/text/qtextdocumentwriter.h @@ -70,7 +70,7 @@ public: bool write(const QTextDocument *document); bool write(const QTextDocumentFragment &fragment); -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) void setCodec(QTextCodec *codec); QTextCodec *codec() const; #endif diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp index 9154182df1..0aad65479a 100644 --- a/src/gui/text/qtexthtmlparser.cpp +++ b/src/gui/text/qtexthtmlparser.cpp @@ -40,7 +40,6 @@ #include "qtexthtmlparser_p.h" #include -#include #include #include #include diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp index 30f5bc1051..1b742cf202 100644 --- a/src/gui/text/qtextodfwriter.cpp +++ b/src/gui/text/qtextodfwriter.cpp @@ -772,7 +772,7 @@ bool QTextOdfWriter::writeAll() return false; } QXmlStreamWriter writer(m_strategy->contentStream); -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) if (m_codec) writer.setCodec(m_codec); #endif diff --git a/src/platformsupport/clipboard/qmacmime.mm b/src/platformsupport/clipboard/qmacmime.mm index 09901ba0a5..8fa45dd50b 100644 --- a/src/platformsupport/clipboard/qmacmime.mm +++ b/src/platformsupport/clipboard/qmacmime.mm @@ -418,8 +418,10 @@ QVariant QMacPasteboardMimeUnicodeText::convertToMime(const QString &mimetype, Q QVariant ret; if (flavor == QLatin1String("public.utf8-plain-text")) { ret = QString::fromUtf8(firstData); +#if QT_CONFIG(textcodec) } else if (flavor == QLatin1String("public.utf16-plain-text")) { ret = QTextCodec::codecForName("UTF-16")->toUnicode(firstData); +#endif } else { qWarning("QMime::convertToMime: unhandled mimetype: %s", qPrintable(mimetype)); } @@ -432,8 +434,10 @@ QList QMacPasteboardMimeUnicodeText::convertFromMime(const QString & QString string = data.toString(); if (flavor == QLatin1String("public.utf8-plain-text")) ret.append(string.toUtf8()); +#if QT_CONFIG(textcodec) else if (flavor == QLatin1String("public.utf16-plain-text")) ret.append(QTextCodec::codecForName("UTF-16")->fromUnicode(string)); +#endif return ret; } diff --git a/src/platformsupport/input/libinput/qlibinputkeyboard.cpp b/src/platformsupport/input/libinput/qlibinputkeyboard.cpp index 5152725468..2524066301 100644 --- a/src/platformsupport/input/libinput/qlibinputkeyboard.cpp +++ b/src/platformsupport/input/libinput/qlibinputkeyboard.cpp @@ -269,11 +269,11 @@ int QLibInputKeyboard::keysymToQtKey(xkb_keysym_t key) const int QLibInputKeyboard::keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers *modifiers, const QString &text) const { int code = 0; -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) QTextCodec *systemCodec = QTextCodec::codecForLocale(); #endif if (keysym < 128 || (keysym < 256 -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) && systemCodec->mibEnum() == 4 #endif )) { diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index 94f2125bad..0035d30e36 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -56,7 +56,6 @@ #include #include #include -#include #include #include #include diff --git a/src/plugins/platforms/cocoa/qpaintengine_mac.mm b/src/plugins/platforms/cocoa/qpaintengine_mac.mm index 3f363b62d5..f3629c2eb4 100644 --- a/src/plugins/platforms/cocoa/qpaintengine_mac.mm +++ b/src/plugins/platforms/cocoa/qpaintengine_mac.mm @@ -47,7 +47,6 @@ #include #include #include -#include #include #include #include diff --git a/src/plugins/platforms/xcb/qxcbmime.cpp b/src/plugins/platforms/xcb/qxcbmime.cpp index 7170d259fd..d611f86a9c 100644 --- a/src/plugins/platforms/xcb/qxcbmime.cpp +++ b/src/plugins/platforms/xcb/qxcbmime.cpp @@ -168,7 +168,7 @@ QVariant QXcbMime::mimeConvertToFormat(QXcbConnection *connection, xcb_atom_t a, if (!encoding.isEmpty() && atomName == format + QLatin1String(";charset=") + QLatin1String(encoding)) { -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) if (requestedType == QVariant::String) { QTextCodec *codec = QTextCodec::codecForName(encoding); if (codec) diff --git a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp index 5a100b8075..49bceb88a0 100644 --- a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp +++ b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp @@ -48,7 +48,9 @@ #include #include #include +#if QT_CONFIG(textcodec) #include +#endif #include #include #include @@ -82,7 +84,7 @@ class QMYSQLDriverPrivate : public QSqlDriverPrivate public: QMYSQLDriverPrivate() : QSqlDriverPrivate(), mysql(0), -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) tc(QTextCodec::codecForLocale()), #else tc(0), @@ -96,7 +98,7 @@ public: static inline QString toUnicode(QTextCodec *tc, const char *str) { -#ifdef QT_NO_TEXTCODEC +#if !QT_CONFIG(textcodec) Q_UNUSED(tc); return QString::fromLatin1(str); #else @@ -106,7 +108,7 @@ static inline QString toUnicode(QTextCodec *tc, const char *str) static inline QString toUnicode(QTextCodec *tc, const char *str, int length) { -#ifdef QT_NO_TEXTCODEC +#if !QT_CONFIG(textcodec) Q_UNUSED(tc); return QString::fromLatin1(str, length); #else @@ -116,7 +118,7 @@ static inline QString toUnicode(QTextCodec *tc, const char *str, int length) static inline QByteArray fromUnicode(QTextCodec *tc, const QString &str) { -#ifdef QT_NO_TEXTCODEC +#if !QT_CONFIG(textcodec) Q_UNUSED(tc); return str.toLatin1(); #else @@ -251,7 +253,7 @@ public: bool preparedQuery; }; -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) static QTextCodec* codec(MYSQL* mysql) { #if MYSQL_VERSION_ID >= 32321 @@ -261,7 +263,7 @@ static QTextCodec* codec(MYSQL* mysql) #endif return QTextCodec::codecForLocale(); } -#endif // QT_NO_TEXTCODEC +#endif // textcodec static QSqlError qMakeError(const QString& err, QSqlError::ErrorType type, const QMYSQLDriverPrivate* p) @@ -1199,7 +1201,7 @@ QMYSQLDriver::QMYSQLDriver(MYSQL * con, QObject * parent) init(); if (con) { d->mysql = (MYSQL *) con; -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) d->tc = codec(con); #endif setOpen(true); @@ -1428,14 +1430,14 @@ bool QMYSQLDriver::open(const QString& db, if (mysql_get_client_version() >= 50503 && mysql_get_server_version(d->mysql) >= 50503) { // force the communication to be utf8mb4 (only utf8mb4 supports 4-byte characters) mysql_set_character_set(d->mysql, "utf8mb4"); -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) d->tc = QTextCodec::codecForName("UTF-8"); #endif } else { // force the communication to be utf8 mysql_set_character_set(d->mysql, "utf8"); -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) d->tc = codec(d->mysql); #endif } diff --git a/src/tools/uic/main.cpp b/src/tools/uic/main.cpp index 46a1e66bcc..b1567cc3c5 100644 --- a/src/tools/uic/main.cpp +++ b/src/tools/uic/main.cpp @@ -137,7 +137,7 @@ int runUic(int argc, char *argv[]) return 1; } out = new QTextStream(&f); -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) out->setCodec(QTextCodec::codecForName("UTF-8")); #endif } diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index ba315d4338..b71efabcc9 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -58,7 +58,6 @@ #include "qstyle.h" #include "qstyleoption.h" #include "qstylefactory.h" -#include "qtextcodec.h" #include "qtooltip.h" #include "qtranslator.h" #include "qvariant.h" diff --git a/src/widgets/kernel/qt_widgets_pch.h b/src/widgets/kernel/qt_widgets_pch.h index 924a68d62e..bec6536637 100644 --- a/src/widgets/kernel/qt_widgets_pch.h +++ b/src/widgets/kernel/qt_widgets_pch.h @@ -63,7 +63,9 @@ #include #include #include +#if QT_CONFIG(textcodec) #include +#endif #include #include diff --git a/src/widgets/widgets/qtextbrowser.cpp b/src/widgets/widgets/qtextbrowser.cpp index fa4dd14c92..29fd07edc1 100644 --- a/src/widgets/widgets/qtextbrowser.cpp +++ b/src/widgets/widgets/qtextbrowser.cpp @@ -47,7 +47,9 @@ #include #include #include "private/qtextdocumentlayout_p.h" +#if QT_CONFIG(textcodec) #include +#endif #include #include #if QT_CONFIG(whatsthis) @@ -290,7 +292,7 @@ void QTextBrowserPrivate::setSource(const QUrl &url) if (data.type() == QVariant::String) { txt = data.toString(); } else if (data.type() == QVariant::ByteArray) { -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) QByteArray ba = data.toByteArray(); QTextCodec *codec = Qt::codecForHtml(ba); txt = codec->toUnicode(ba); diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp index 91796106a2..5893d8448e 100644 --- a/src/xml/dom/qdom.cpp +++ b/src/xml/dom/qdom.cpp @@ -49,7 +49,9 @@ #include #include #include +#if QT_CONFIG(textcodec) #include +#endif #include #include #include "private/qxml_p.h" @@ -4149,7 +4151,7 @@ static QString encodeText(const QString &str, const bool performAVN = false, const bool encodeEOLs = false) { -#ifdef QT_NO_TEXTCODEC +#if !QT_CONFIG(textcodec) Q_UNUSED(s); #else const QTextCodec *const codec = s.codec(); @@ -4191,7 +4193,7 @@ static QString encodeText(const QString &str, len += 4; i += 5; } else { -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) if(codec->canEncode(ati)) ++i; else @@ -6428,7 +6430,7 @@ void QDomDocumentPrivate::saveDocument(QTextStream& s, const int indent, QDomNod const QDomNodePrivate* n = first; if(encUsed == QDomNode::EncodingFromDocument) { -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) const QDomNodePrivate* n = first; QTextCodec *codec = 0; @@ -6464,7 +6466,7 @@ void QDomDocumentPrivate::saveDocument(QTextStream& s, const int indent, QDomNod else { // Write out the XML declaration. -#ifdef QT_NO_TEXTCODEC +#if !QT_CONFIG(textcodec) const QLatin1String codecName("iso-8859-1"); #else const QTextCodec *const codec = s.codec(); diff --git a/src/xml/sax/qxml.cpp b/src/xml/sax/qxml.cpp index 168e8c3cb4..7b6669b057 100644 --- a/src/xml/sax/qxml.cpp +++ b/src/xml/sax/qxml.cpp @@ -39,7 +39,9 @@ #include "qxml.h" #include "qxml_p.h" +#if QT_CONFIG(textcodec) #include "qtextcodec.h" +#endif #include "qbuffer.h" #include "qregexp.h" #include "qmap.h" @@ -237,7 +239,7 @@ public: int pos; int length; bool nextReturnedEndOfData; -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) QTextDecoder *encMapper; #endif @@ -1075,7 +1077,7 @@ void QXmlInputSource::init() d->inputStream = 0; setData(QString()); -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) d->encMapper = 0; #endif d->nextReturnedEndOfData = true; // first call to next() will call fetchData() @@ -1121,7 +1123,7 @@ QXmlInputSource::QXmlInputSource(QIODevice *dev) QXmlInputSource::~QXmlInputSource() { // ### close the input device. -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) delete d->encMapper; #endif delete d; @@ -1284,7 +1286,7 @@ void QXmlInputSource::fetchData() } } -#ifndef QT_NO_TEXTCODEC +#if QT_CONFIG(textcodec) static QString extractEncodingDecl(const QString &text, bool *needMoreText) { *needMoreText = false; @@ -1326,7 +1328,7 @@ static QString extractEncodingDecl(const QString &text, bool *needMoreText) return encoding; } -#endif // QT_NO_TEXTCODEC +#endif // textcodec /*! This function reads the XML file from \a data and tries to @@ -1341,7 +1343,7 @@ static QString extractEncodingDecl(const QString &text, bool *needMoreText) */ QString QXmlInputSource::fromRawData(const QByteArray &data, bool beginning) { -#ifdef QT_NO_TEXTCODEC +#if !QT_CONFIG(textcodec) Q_UNUSED(beginning); return QString::fromLatin1(data.constData(), data.size()); #else From a545b85bdd8d227c63dda07728de4d1bac285cf5 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 6 Nov 2018 13:38:09 +0100 Subject: [PATCH 0220/1650] QWidgetWindow: check if receiver is deleted after event delivery When a popup is active, we set the receiver of mouse events to be the active popup widget. But when we send a mouse event to the popup, the receiver might start a new QEventLoop (e.g by executing a new dialog). And in the meantime, the popup will be destroyed. This will cause a crash in the line after the event delivery (where we sat "qt_last_mouse_receiver = receiver"), since at that point, "receiver" would be a dangling pointer. This patch will use a QPointer instead of a raw pointer to store "receiver", to ensure that it's set to null for such cases. Fixes: QTBUG-71062 Change-Id: Ie017cfa97370513ecfdd62c056fcb0e6c991f9f6 Reviewed-by: Eirik Aavitsland --- src/widgets/kernel/qwidgetwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 7292c795b8..0b2d72f330 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -521,7 +521,7 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) if (activePopupWidget->isEnabled()) { // deliver event qt_replay_popup_mouse_event = false; - QWidget *receiver = activePopupWidget; + QPointer receiver = activePopupWidget; QPoint widgetPos = mapped; if (qt_button_down) receiver = qt_button_down; From 993351183893c8c5b1e55b8d819b190cc11ae008 Mon Sep 17 00:00:00 2001 From: Sergio Martins Date: Sun, 7 Oct 2018 16:16:41 +0100 Subject: [PATCH 0221/1650] Fix typo in define. s/GL_FRAMEBUFFER_SRB/GL_FRAMEBUFFER_SRGB Found with clazy Change-Id: Ied84c0fa95a7ae7b7791e167695acfc7877f7e25 Reviewed-by: Sean Harmer --- src/gui/painting/qplatformbackingstore.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp index cc8d850689..e05efca9c8 100644 --- a/src/gui/painting/qplatformbackingstore.cpp +++ b/src/gui/painting/qplatformbackingstore.cpp @@ -71,7 +71,7 @@ #define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 #endif -#ifndef GL_FRAMEBUFFER_SRB +#ifndef GL_FRAMEBUFFER_SRGB #define GL_FRAMEBUFFER_SRGB 0x8DB9 #endif #ifndef GL_FRAMEBUFFER_SRGB_CAPABLE From 38b87cc4bb0d4dfb47d907d39906104fea60a187 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 3 Oct 2018 15:55:06 +0200 Subject: [PATCH 0222/1650] Doc: Clarify what samples() returns if not explicitly set Change-Id: Icf4478121a9d67356eb976039c666d6945a2099c Reviewed-by: Paul Wicking Reviewed-by: Laszlo Agocs --- src/gui/kernel/qsurfaceformat.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qsurfaceformat.cpp b/src/gui/kernel/qsurfaceformat.cpp index 574310f554..1a814ec21f 100644 --- a/src/gui/kernel/qsurfaceformat.cpp +++ b/src/gui/kernel/qsurfaceformat.cpp @@ -319,7 +319,8 @@ void QSurfaceFormat::setStereo(bool enable) /*! Returns the number of samples per pixel when multisampling is - enabled. By default, multisampling is disabled. + enabled, or \c -1 when multisampling is disabled. The default + return value is \c -1. \sa setSamples() */ From 7b9de1d4da67573d6bb0a6bf2fb0cdd1b7fb86a3 Mon Sep 17 00:00:00 2001 From: Alexander Akulich Date: Tue, 6 Nov 2018 16:51:31 +0300 Subject: [PATCH 0223/1650] QSocks5SocketEngine: Remove too optimistic check for UDP proxy setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The engine used to send a UDP datagram to the local address to check the proxy setup, but the check fails in case of the proxy hosted in WAN and the local address hidden behind a NAT. In other words the check fails because a public proxy hosted somewhere in internet has no access to local addresses such as 192.168.1.2. Remove the check to fix the issue; we still have other means to detect network errors. Change-Id: Ib6df263c87ebd7d6e88a0b5e024e78a559995234 Reviewed-by: Thiago Macieira Reviewed-by: Edward Welbourne Reviewed-by: Mårten Nordheim --- src/network/socket/qsocks5socketengine.cpp | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/network/socket/qsocks5socketengine.cpp b/src/network/socket/qsocks5socketengine.cpp index a07ea65046..dd2bc90855 100644 --- a/src/network/socket/qsocks5socketengine.cpp +++ b/src/network/socket/qsocks5socketengine.cpp @@ -1383,23 +1383,6 @@ bool QSocks5SocketEngine::bind(const QHostAddress &addr, quint16 port) d->localAddress = QHostAddress(); d->udpData->associatePort = d->localPort; d->localPort = 0; - QUdpSocket dummy; -#ifndef QT_NO_BEARERMANAGEMENT - dummy.setProperty("_q_networksession", property("_q_networksession")); -#endif - dummy.setProxy(QNetworkProxy::NoProxy); - if (!dummy.bind() - || writeDatagram(0,0, QIpPacketHeader(d->data->controlSocket->localAddress(), dummy.localPort())) != 0 - || !dummy.waitForReadyRead(qt_subtract_from_timeout(msecs, stopWatch.elapsed())) - || dummy.readDatagram(0,0, &d->localAddress, &d->localPort) != 0) { - QSOCKS5_DEBUG << "udp actual address and port lookup failed"; - setState(QAbstractSocket::UnconnectedState); - setError(dummy.error(), dummy.errorString()); - d->data->controlSocket->close(); - //### reset and error - return false; - } - QSOCKS5_DEBUG << "udp actual address and port" << d->localAddress << ':' << d->localPort; return true; #endif // QT_NO_UDPSOCKET } From 2569ac2857a52fa271a7038e0c36fe3e5b2d760e Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Fri, 26 Oct 2018 14:07:36 +0200 Subject: [PATCH 0224/1650] xcb: fix regression with open/close hand cursors On Linux the correspondence between cursor functions and names of cursors has never been standardized. Projects have either assembled their own cursor function-to-name lookup table or borrowed the table from other projects. The origins of our table is described in QTBUG-71423. On Ubuntu the default theme is called Adwaita. Before bd72950fbedc457fb997e99beff4767505ff5d8f, we would not find a cursor for 'openhand' and would fall-back to QXcbCursor:: createNonStandardCursor(). Which was sub-optimal, because the cursors created by the fall-back path don't look like the themed ones. But the situation was worse after bd72950fb (hence the regression) - the 'openhand' fall-back name 'fleur' is a symbolic link to 'grabbing', so we would get into a situation where Qt::OpenHandCursor displays the same as Qt::ClosedHandCursor. This patch adds a correct fall-back name for 'openhand' on Adwaita, which is 'grab'. 'grab' actually is a symbolic link to 'hand1', but 'hand1' with other theams is a pointing hand cursor, that is why we use the symbolic link's name in this case. The lookup table still appears to be incomplete when comparing e.g with KWin. Eventually we need to revise the table and put in a common place so it can be shared between X11 and Wayland, but is out-of-scope for this patch (see QTBUG-71423). Fixes: QTBUG-71296 Task-number: QTBUG-71423 Change-Id: I247ed4b346c2cd3fe1c7fd0440d3763e0033346b Reviewed-by: Frederik Gladhorn --- src/plugins/platforms/xcb/qxcbcursor.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp index 57629ac03a..7831671d42 100644 --- a/src/plugins/platforms/xcb/qxcbcursor.cpp +++ b/src/plugins/platforms/xcb/qxcbcursor.cpp @@ -255,6 +255,7 @@ static const uint8_t * const cursor_bits20[] = { forbidden_bits, forbiddenm_bits }; +// ### FIXME This mapping is incomplete - QTBUG-71423 static const std::vector cursorNames[] = { { "left_ptr", "default", "top_left_arrow", "left_arrow" }, { "up_arrow" }, @@ -273,7 +274,7 @@ static const std::vector cursorNames[] = { { "forbidden", "not-allowed", "crossed_circle", "circle", "03b6e0fcb3499374a867c041f52298f0" }, { "whats_this", "help", "question_arrow", "5c6cd98b3f3ebcb1f9c7f1c204630408", "d9ce0ab605698f320427677b458ad60b" }, { "left_ptr_watch", "half-busy", "progress", "00000000000000020006000e7e9ffc3f", "08e8e1c95fe2fc01f976f1e063a24ccd" }, - { "openhand", "fleur", "5aca4d189052212118709018842178c0", "9d800788f1b08800ae810202380a0822" }, + { "openhand", "grab", "fleur", "5aca4d189052212118709018842178c0", "9d800788f1b08800ae810202380a0822" }, { "closedhand", "grabbing", "208530c400c041818281048008011002" }, { "dnd-copy", "copy" }, { "dnd-move", "move" }, From 35069301f048eed21a27f89b6495d56c44f2b55d Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Tue, 30 Oct 2018 17:58:17 +0100 Subject: [PATCH 0225/1650] Windows QPA: Fix incorrect button state reporting for touchpad The current state of (emulated) mouse buttons was being incorrectly reported for touchpad events under some conditions. In the handling of pointer messages, GetAsyncKeyState() was being used to retrieve the mouse button state. However, it does not seem to work always with all touchpads. Furthermore, its use is not necessary, since the button state information comes as a set of flags with the pointer message itself. This change makes the handler use these flags instead. Fixes: QTBUG-71470 Change-Id: Ie2e35bd80778ef74db672604a0f2af659785efbf Reviewed-by: Friedemann Kleint --- .../windows/qwindowspointerhandler.cpp | 53 ++++++++++++------- .../windows/qwindowspointerhandler.h | 1 - 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp index 2b6c696979..4d3e2f71ec 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp @@ -336,6 +336,38 @@ static void getMouseEventInfo(UINT message, POINTER_BUTTON_CHANGE_TYPE changeTyp *mouseButton = buttonMapping.value(changeType, Qt::NoButton); } +static Qt::MouseButtons mouseButtonsFromPointerFlags(POINTER_FLAGS pointerFlags) +{ + Qt::MouseButtons result = Qt::NoButton; + if (pointerFlags & POINTER_FLAG_FIRSTBUTTON) + result |= Qt::LeftButton; + if (pointerFlags & POINTER_FLAG_SECONDBUTTON) + result |= Qt::RightButton; + if (pointerFlags & POINTER_FLAG_THIRDBUTTON) + result |= Qt::MiddleButton; + if (pointerFlags & POINTER_FLAG_FOURTHBUTTON) + result |= Qt::XButton1; + if (pointerFlags & POINTER_FLAG_FIFTHBUTTON) + result |= Qt::XButton2; + return result; +} + +static Qt::MouseButtons mouseButtonsFromKeyState(WPARAM keyState) +{ + Qt::MouseButtons result = Qt::NoButton; + if (keyState & MK_LBUTTON) + result |= Qt::LeftButton; + if (keyState & MK_RBUTTON) + result |= Qt::RightButton; + if (keyState & MK_MBUTTON) + result |= Qt::MiddleButton; + if (keyState & MK_XBUTTON1) + result |= Qt::XButton1; + if (keyState & MK_XBUTTON2) + result |= Qt::XButton2; + return result; +} + static QWindow *getWindowUnderPointer(QWindow *window, QPoint globalPos) { QWindow *currentWindowUnderPointer = QWindowsScreen::windowAt(globalPos, CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT); @@ -405,23 +437,6 @@ QTouchDevice *QWindowsPointerHandler::ensureTouchDevice() return m_touchDevice; } -Qt::MouseButtons QWindowsPointerHandler::queryMouseButtons() -{ - Qt::MouseButtons result = 0; - const bool mouseSwapped = GetSystemMetrics(SM_SWAPBUTTON); - if (GetAsyncKeyState(VK_LBUTTON) < 0) - result |= mouseSwapped ? Qt::RightButton: Qt::LeftButton; - if (GetAsyncKeyState(VK_RBUTTON) < 0) - result |= mouseSwapped ? Qt::LeftButton : Qt::RightButton; - if (GetAsyncKeyState(VK_MBUTTON) < 0) - result |= Qt::MidButton; - if (GetAsyncKeyState(VK_XBUTTON1) < 0) - result |= Qt::XButton1; - if (GetAsyncKeyState(VK_XBUTTON2) < 0) - result |= Qt::XButton2; - return result; -} - bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, PVOID vPointerInfo) @@ -430,7 +445,7 @@ bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND h const QPoint globalPos = QPoint(pointerInfo->ptPixelLocation.x, pointerInfo->ptPixelLocation.y); const QPoint localPos = QWindowsGeometryHint::mapFromGlobal(hwnd, globalPos); const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers(); - const Qt::MouseButtons mouseButtons = queryMouseButtons(); + const Qt::MouseButtons mouseButtons = mouseButtonsFromPointerFlags(pointerInfo->pointerFlags); QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos); QWindowsWindow *platformWindow = static_cast(window->handle()); @@ -788,7 +803,7 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtW m_windowUnderPointer = currentWindowUnderPointer; } - const Qt::MouseButtons mouseButtons = queryMouseButtons(); + const Qt::MouseButtons mouseButtons = mouseButtonsFromKeyState(msg.wParam); if (!discardEvent) QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos, mouseButtons, Qt::NoButton, QEvent::MouseMove, diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.h b/src/plugins/platforms/windows/qwindowspointerhandler.h index c4d0e0ce4a..3861ebf919 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.h +++ b/src/plugins/platforms/windows/qwindowspointerhandler.h @@ -61,7 +61,6 @@ public: bool translateMouseEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result); QTouchDevice *touchDevice() const { return m_touchDevice; } QTouchDevice *ensureTouchDevice(); - Qt::MouseButtons queryMouseButtons(); QWindow *windowUnderMouse() const { return m_windowUnderPointer.data(); } void clearWindowUnderMouse() { m_windowUnderPointer = nullptr; } From bdebc90c2826866e4434a6429aa6f822ee3cb8f6 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 8 Nov 2018 11:26:39 +0100 Subject: [PATCH 0226/1650] Bump version Change-Id: I02c0289a7c8a5becde63875fa684075a2a3a4eba --- .qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.qmake.conf b/.qmake.conf index afdc0cb413..24e408e027 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -4,4 +4,4 @@ CONFIG += warning_clean QT_SOURCE_TREE = $$PWD QT_BUILD_TREE = $$shadowed($$PWD) -MODULE_VERSION = 5.11.2 +MODULE_VERSION = 5.11.3 From b971310e2df095678dd0d6d8e08a8f657d346036 Mon Sep 17 00:00:00 2001 From: Kari Oikarinen Date: Tue, 6 Nov 2018 15:14:44 +0200 Subject: [PATCH 0227/1650] QObject: Check for declarative signals in isSignalConnected Amends a952fd7d5b03ce1968ec58871fbb8b3600895900. The mentioned commit started to skip QObjectPrivate::isSignalConnected() call if the connectionLists are dirty, which lead to tst_qqmllanguage::receivers() test inside qtdeclarative breaking. Declarative signals were not checked if that function was not called. It previously also wasn't called for signals higher than 64. Fix that by checking for declarative signals after the connectionLists search is unsuccessful. Fixes: QTBUG-71550 Change-Id: Ifcb5fdd0dc9a6b14b9f448a016fd09356a55b985 Reviewed-by: Liang Qi Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/kernel/qobject.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index deab51cfd0..14af9ac8ef 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -2513,22 +2513,21 @@ bool QObject::isSignalConnected(const QMetaMethod &signal) const signalIndex += QMetaObjectPrivate::signalOffset(signal.mobj); QMutexLocker locker(signalSlotLock(this)); - if (!d->connectionLists) - return false; + if (d->connectionLists) { + if (signalIndex < sizeof(d->connectedSignals) * 8 && !d->connectionLists->dirty) + return d->isSignalConnected(signalIndex); - if (signalIndex < sizeof(d->connectedSignals) * 8 && !d->connectionLists->dirty) - return d->isSignalConnected(signalIndex); - - if (signalIndex < uint(d->connectionLists->count())) { - const QObjectPrivate::Connection *c = - d->connectionLists->at(signalIndex).first; - while (c) { - if (c->receiver) - return true; - c = c->nextConnectionList; + if (signalIndex < uint(d->connectionLists->count())) { + const QObjectPrivate::Connection *c = + d->connectionLists->at(signalIndex).first; + while (c) { + if (c->receiver) + return true; + c = c->nextConnectionList; + } } } - return false; + return d->isDeclarativeSignalConnected(signalIndex); } /*! From 75e8f6f41e0c436c257eec543684f5e8d47213f4 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 1 Nov 2018 15:44:41 -0700 Subject: [PATCH 0228/1650] QResource: catch signed integer overflow (just in case) Change-Id: I343f2beed55440a7ac0bfffd156321748e4d6048 Reviewed-by: Lars Knoll --- src/corelib/io/qresource.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index 367cd78d65..b85bca8590 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -54,6 +54,7 @@ #include #include #include "private/qabstractfileengine_p.h" +#include "private/qnumeric_p.h" #include "private/qsimd_p.h" #include "private/qsystemerror_p.h" @@ -1502,7 +1503,9 @@ uchar *QResourceFileEnginePrivate::map(qint64 offset, qint64 size, QFile::Memory { Q_Q(QResourceFileEngine); Q_UNUSED(flags); - if (offset < 0 || size <= 0 || !resource.isValid() || offset + size > resource.size()) { + qint64 end; + if (offset < 0 || size <= 0 || !resource.isValid() || + add_overflow(offset, size, &end) || end > resource.size()) { q->setError(QFile::UnspecifiedError, QString()); return 0; } From c0b1230108090cf914ccc5329b1213063ed21bdd Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 18 Oct 2018 22:52:13 -0700 Subject: [PATCH 0229/1650] Add qHash(QCborTag) and qHash(QCborSimpleType) Needed in qHash(QCborValue). Change-Id: If7e743cf8476463880ccfffd155eeca91369b356 Reviewed-by: Ulf Hermann Reviewed-by: Edward Welbourne --- src/corelib/serialization/qcborcommon.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/corelib/serialization/qcborcommon.h b/src/corelib/serialization/qcborcommon.h index 9661cd70bb..f8278f1649 100644 --- a/src/corelib/serialization/qcborcommon.h +++ b/src/corelib/serialization/qcborcommon.h @@ -133,6 +133,16 @@ Q_CORE_EXPORT QDebug operator<<(QDebug, QCborKnownTags tg); Q_CORE_EXPORT QDebug operator<<(QDebug, QCborTag tg); #endif +inline uint qHash(QCborSimpleType tag, uint seed = 0) +{ + return qHash(quint8(tag), seed); +} + +inline uint qHash(QCborTag tag, uint seed = 0) +{ + return qHash(quint64(tag), seed); +} + QT_END_NAMESPACE Q_DECLARE_METATYPE(QCborTag) From e7998dc187cf8f1218711ac963c441afbea1577c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 27 Oct 2018 19:43:09 -0700 Subject: [PATCH 0230/1650] QCborStreamReader: make sure setDevice() clears the last error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The unit tests weren't running into this problem because the every setDevice() was preceded by the object being initialized with the exact same data, so there was never a previous error state. I've only changed a couple of tests, left the other setDevice() unchanged so we test both behaviors. Fixes: QTBUG-71426 Change-Id: I1bd327aeaf73421a8ec5fffd1561a590e3933376 Reviewed-by: Nils Jeisecke Reviewed-by: Mårten Nordheim Reviewed-by: Edward Welbourne --- src/corelib/serialization/qcborstream.cpp | 2 ++ .../serialization/qcborstreamreader/tst_qcborstreamreader.cpp | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/corelib/serialization/qcborstream.cpp b/src/corelib/serialization/qcborstream.cpp index 22286188b8..fc5610e341 100644 --- a/src/corelib/serialization/qcborstream.cpp +++ b/src/corelib/serialization/qcborstream.cpp @@ -1779,6 +1779,8 @@ public: preread(); if (CborError err = cbor_parser_init_reader(nullptr, &parser, ¤tElement, this)) handleError(err); + else + lastError = { QCborError::NoError }; } char *bufferPtr() diff --git a/tests/auto/corelib/serialization/qcborstreamreader/tst_qcborstreamreader.cpp b/tests/auto/corelib/serialization/qcborstreamreader/tst_qcborstreamreader.cpp index 24d9c7409e..3dd4b5114c 100644 --- a/tests/auto/corelib/serialization/qcborstreamreader/tst_qcborstreamreader.cpp +++ b/tests/auto/corelib/serialization/qcborstreamreader/tst_qcborstreamreader.cpp @@ -269,7 +269,7 @@ void tst_QCborStreamReader::integers() quint64 absolute = (isNegative ? expectedRaw + 1 : expectedRaw); QBuffer buffer(&data); - QCborStreamReader reader(data); + QCborStreamReader reader(useDevice ? QByteArray() : data); if (useDevice) { buffer.open(QIODevice::ReadOnly); reader.setDevice(&buffer); @@ -605,7 +605,7 @@ void tst_QCborStreamReader::fixed() removeIndicators(expected); QBuffer buffer(&data); - QCborStreamReader reader(data); + QCborStreamReader reader(useDevice ? QByteArray() : data); if (useDevice) { buffer.open(QIODevice::ReadOnly); reader.setDevice(&buffer); From a0907e6ac1deee086c04a8987ad76fc2c78f65ab Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 17 Oct 2018 15:57:42 -0700 Subject: [PATCH 0231/1650] Fix warning about missing initializer for a struct member MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GCC 4.8 is complaining about perfectly valid (and recommended) code but we still support it, so... qcborvalue.h:74:25: warning: missing initializer for member ‘QCborError::c’ Fixes: QTBUG-71222 Change-Id: If7e743cf8476463880ccfffd155e8775b6b95469 Reviewed-by: Edward Welbourne --- src/corelib/serialization/qcborvalue.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/serialization/qcborvalue.h b/src/corelib/serialization/qcborvalue.h index 6d9ed0810a..105af1ba73 100644 --- a/src/corelib/serialization/qcborvalue.h +++ b/src/corelib/serialization/qcborvalue.h @@ -71,7 +71,7 @@ class QCborStreamWriter; struct QCborParserError { qint64 offset = 0; - QCborError error = {}; + QCborError error = { QCborError::NoError }; QString errorString() const { return error.toString(); } }; From 570ef11c28b885817a69523835fac40d9e0d1f4e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 12 Sep 2018 18:10:11 -0700 Subject: [PATCH 0232/1650] QUtf8Codec: Use one 32-byte load instead of two 16-byte ones on AVX2 The number of instructions is the same. But if the CPU can issue 32-byte-wide loads, this will be faster. For CPUs that would do two 16-byte loads, this is no worse than current code. Change-Id: I8f261579aad648fdb4f0fffd1553d060b4fc852f Reviewed-by: Allan Sandfeld Jensen --- src/corelib/codecs/qutfcodec.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/corelib/codecs/qutfcodec.cpp b/src/corelib/codecs/qutfcodec.cpp index 26c68cdee5..8bc1294c49 100644 --- a/src/corelib/codecs/qutfcodec.cpp +++ b/src/corelib/codecs/qutfcodec.cpp @@ -70,9 +70,14 @@ static inline bool simdEncodeAscii(uchar *&dst, const ushort *&nextAscii, const { // do sixteen characters at a time for ( ; end - src >= 16; src += 16, dst += 16) { +# ifdef __AVX2__ + __m256i data = _mm256_loadu_si256(reinterpret_cast(src)); + __m128i data1 = _mm256_castsi256_si128(data); + __m128i data2 = _mm256_extracti128_si256(data, 1); +# else __m128i data1 = _mm_loadu_si128((const __m128i*)src); __m128i data2 = _mm_loadu_si128(1+(const __m128i*)src); - +# endif // check if everything is ASCII // the highest ASCII value is U+007F From 66a2d159073bfbeec53a0b9e09575c3fe9beac8d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 20 Oct 2018 21:28:17 -0700 Subject: [PATCH 0233/1650] QTextCodec: update the docs for codecForUtfText It can detect the standard UTF codecs, but not non-standard like UTF-7[1], UTF-9 or UTF-18[2]. [1] https://tools.ietf.org/html/rfc2152 [2] https://tools.ietf.org/html/rfc4042 Fixes: QTBUG-67188 Change-Id: If7e743cf8476463880ccfffd155f853dc947421a Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/codecs/qtextcodec.cpp | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp index fedd39e104..a2a128158e 100644 --- a/src/corelib/codecs/qtextcodec.cpp +++ b/src/corelib/codecs/qtextcodec.cpp @@ -1164,9 +1164,19 @@ QTextCodec *QTextCodec::codecForHtml(const QByteArray &ba) Tries to detect the encoding of the provided snippet \a ba by using the BOM (Byte Order Mark) and returns a QTextCodec instance - that is capable of decoding the text to unicode. If the codec - cannot be detected from the content provided, \a defaultCodec is - returned. + that is capable of decoding the text to unicode. This function can + detect one of the following codecs: + + \list + \li UTF-32 Little Endian + \li UTF-32 Big Endian + \li UTF-16 Little Endian + \li UTF-16 Big Endian + \li UTF-8 + \endlist + + If the codec cannot be detected from the content provided, \a defaultCodec + is returned. \sa codecForHtml() */ @@ -1209,8 +1219,19 @@ QTextCodec *QTextCodec::codecForUtfText(const QByteArray &ba, QTextCodec *defaul Tries to detect the encoding of the provided snippet \a ba by using the BOM (Byte Order Mark) and returns a QTextCodec instance - that is capable of decoding the text to unicode. If the codec - cannot be detected, this overload returns a Latin-1 QTextCodec. + that is capable of decoding the text to unicode. This function can + detect one of the following codecs: + + \list + \li UTF-32 Little Endian + \li UTF-32 Big Endian + \li UTF-16 Little Endian + \li UTF-16 Big Endian + \li UTF-8 + \endlist + + If the codec cannot be detected from the content provided, this overload + returns a Latin-1 QTextCodec. \sa codecForHtml() */ From 99baa0d4401516cff978cab8a7102fc0a25731a9 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 20 Oct 2018 21:45:10 -0700 Subject: [PATCH 0234/1650] Optimize QTextCodec::codecForUtfText a little Instead of doing byte comparisons, let the compiler do 16- and 32-bit comparisons on its own. Change-Id: If7e743cf8476463880ccfffd155f8629991b0b87 Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Tobias Hunger --- src/corelib/codecs/qtextcodec.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp index a2a128158e..e5c33d9d59 100644 --- a/src/corelib/codecs/qtextcodec.cpp +++ b/src/corelib/codecs/qtextcodec.cpp @@ -45,8 +45,9 @@ #ifndef QT_NO_TEXTCODEC #include "qbytearraymatcher.h" -#include "qlist.h" +#include "qendian.h" #include "qfile.h" +#include "qlist.h" #include "qstringlist.h" #include "qvarlengtharray.h" #if !defined(QT_BOOTSTRAPPED) @@ -1183,32 +1184,31 @@ QTextCodec *QTextCodec::codecForHtml(const QByteArray &ba) QTextCodec *QTextCodec::codecForUtfText(const QByteArray &ba, QTextCodec *defaultCodec) { const int arraySize = ba.size(); + const uchar *buf = reinterpret_cast(ba.constData()); + const uint bom = 0xfeff; if (arraySize > 3) { - if ((uchar)ba[0] == 0x00 - && (uchar)ba[1] == 0x00 - && (uchar)ba[2] == 0xFE - && (uchar)ba[3] == 0xFF) + uint uc = qFromUnaligned(buf); + if (uc == qToBigEndian(bom)) return QTextCodec::codecForMib(1018); // utf-32 be - else if ((uchar)ba[0] == 0xFF - && (uchar)ba[1] == 0xFE - && (uchar)ba[2] == 0x00 - && (uchar)ba[3] == 0x00) + else if (uc == qToLittleEndian(bom)) return QTextCodec::codecForMib(1019); // utf-32 le } if (arraySize < 2) return defaultCodec; - if ((uchar)ba[0] == 0xfe && (uchar)ba[1] == 0xff) + + ushort uc = qFromUnaligned(buf); + if (uc == qToBigEndian(ushort(bom))) return QTextCodec::codecForMib(1013); // utf16 be - else if ((uchar)ba[0] == 0xff && (uchar)ba[1] == 0xfe) + else if (uc == qToLittleEndian(ushort(bom))) return QTextCodec::codecForMib(1014); // utf16 le if (arraySize < 3) return defaultCodec; - if ((uchar)ba[0] == 0xef - && (uchar)ba[1] == 0xbb - && (uchar)ba[2] == 0xbf) + + static const char utf8bom[] = "\xef\xbb\xbf"; + if (memcmp(buf, utf8bom, sizeof(utf8bom) - 1) == 0) return QTextCodec::codecForMib(106); // utf-8 return defaultCodec; From f80ed83cd92deb015b78c39f4c634c046ef75b1c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 20 Oct 2018 21:55:20 -0700 Subject: [PATCH 0235/1650] Correct which codecs QTextStream::autoDetectUnicode detects Fixes: QTBUG-67187 Change-Id: If7e743cf8476463880ccfffd155f86b78a279f81 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/serialization/qtextstream.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/corelib/serialization/qtextstream.cpp b/src/corelib/serialization/qtextstream.cpp index 05a5a55926..2d22cb291d 100644 --- a/src/corelib/serialization/qtextstream.cpp +++ b/src/corelib/serialization/qtextstream.cpp @@ -3111,15 +3111,15 @@ QTextCodec *QTextStream::codec() const } /*! - If \a enabled is true, QTextStream will attempt to detect Unicode - encoding by peeking into the stream data to see if it can find the - UTF-16 or UTF-32 BOM (Byte Order Mark). If this mark is found, QTextStream - will replace the current codec with the UTF codec. + If \a enabled is true, QTextStream will attempt to detect Unicode encoding + by peeking into the stream data to see if it can find the UTF-8, UTF-16, or + UTF-32 Byte Order Mark (BOM). If this mark is found, QTextStream will + replace the current codec with the UTF codec. This function can be used together with setCodec(). It is common to set the codec to UTF-8, and then enable UTF-16 detection. - \sa autoDetectUnicode(), setCodec() + \sa autoDetectUnicode(), setCodec(), QTextCodec::codecForUtfText() */ void QTextStream::setAutoDetectUnicode(bool enabled) { @@ -3131,7 +3131,7 @@ void QTextStream::setAutoDetectUnicode(bool enabled) Returns \c true if automatic Unicode detection is enabled, otherwise returns \c false. Automatic Unicode detection is enabled by default. - \sa setAutoDetectUnicode(), setCodec() + \sa setAutoDetectUnicode(), setCodec(), QTextCodec::codecForUtfText() */ bool QTextStream::autoDetectUnicode() const { From 9d90c0edac91b35ec96646fd3e6cdd339639ca79 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 1 Nov 2018 21:43:48 -0700 Subject: [PATCH 0236/1650] QImage: merge the size calculations with proper (non-UB) checks This check, which was only done once, was wrong: const int bytes_per_line = ((width * depth + 31) >> 5) << 2; // sanity check for potential overflows if (std::numeric_limits::max()/depth < width If width*height overflows, then it's already UB and checking afterwards with a division is pointless and slow. The other instances weren't properly guarding against overflows. Change-Id: I343f2beed55440a7ac0bfffd1563350d4cfa639c Reviewed-by: Allan Sandfeld Jensen --- src/gui/image/qimage.cpp | 68 ++++++++++++---------------- src/gui/image/qimage_conversions.cpp | 58 ++++++++++++------------ src/gui/image/qimage_p.h | 33 ++++++++++++++ 3 files changed, 91 insertions(+), 68 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 421362dd9e..0105f1decd 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -118,21 +118,14 @@ QImageData::QImageData() QImageData * QImageData::create(const QSize &size, QImage::Format format) { if (!size.isValid() || format == QImage::Format_Invalid) - return 0; // invalid parameter(s) + return nullptr; // invalid parameter(s) - uint width = size.width(); - uint height = size.height(); - uint depth = qt_depthForFormat(format); - - const int bytes_per_line = ((width * depth + 31) >> 5) << 2; // bytes per scanline (must be multiple of 4) - - // sanity check for potential overflows - if (std::numeric_limits::max()/depth < width - || bytes_per_line <= 0 - || height <= 0 - || std::numeric_limits::max()/uint(bytes_per_line) < height - || std::numeric_limits::max()/sizeof(uchar *) < uint(height)) - return 0; + int width = size.width(); + int height = size.height(); + int depth = qt_depthForFormat(format); + auto params = calculateImageParameters(width, height, depth); + if (params.bytesPerLine < 0) + return nullptr; QScopedPointer d(new QImageData); @@ -154,18 +147,15 @@ QImageData * QImageData::create(const QSize &size, QImage::Format format) d->has_alpha_clut = false; d->is_cached = false; - d->bytes_per_line = bytes_per_line; - - d->nbytes = d->bytes_per_line*height; + d->bytes_per_line = params.bytesPerLine; + d->nbytes = params.totalSize; d->data = (uchar *)malloc(d->nbytes); - if (!d->data) { - return 0; - } + if (!d->data) + return nullptr; d->ref.ref(); return d.take(); - } QImageData::~QImageData() @@ -786,27 +776,27 @@ QImage::QImage(const QSize &size, Format format) QImageData *QImageData::create(uchar *data, int width, int height, int bpl, QImage::Format format, bool readOnly, QImageCleanupFunction cleanupFunction, void *cleanupInfo) { - QImageData *d = 0; - - if (format == QImage::Format_Invalid) - return d; + if (width <= 0 || height <= 0 || !data || format == QImage::Format_Invalid) + return nullptr; const int depth = qt_depthForFormat(format); - const int calc_bytes_per_line = ((width * depth + 31)/32) * 4; - const int min_bytes_per_line = (width * depth + 7)/8; + auto params = calculateImageParameters(width, height, depth); + if (params.totalSize < 0) + return nullptr; - if (bpl <= 0) - bpl = calc_bytes_per_line; + if (bpl > 0) { + // can't overflow, because has calculateImageParameters already done this multiplication + const int min_bytes_per_line = (width * depth + 7)/8; + if (bpl < min_bytes_per_line) + return nullptr; - if (width <= 0 || height <= 0 || !data - || INT_MAX/sizeof(uchar *) < uint(height) - || INT_MAX/uint(depth) < uint(width) - || bpl <= 0 - || bpl < min_bytes_per_line - || INT_MAX/uint(bpl) < uint(height)) - return d; // invalid parameter(s) + // recalculate the total with this value + params.bytesPerLine = bpl; + if (mul_overflow(bpl, height, ¶ms.totalSize)) + return nullptr; + } - d = new QImageData; + QImageData *d = new QImageData; d->ref.ref(); d->own_data = false; @@ -817,8 +807,8 @@ QImageData *QImageData::create(uchar *data, int width, int height, int bpl, QIm d->depth = depth; d->format = format; - d->bytes_per_line = bpl; - d->nbytes = d->bytes_per_line * height; + d->bytes_per_line = params.bytesPerLine; + d->nbytes = params.totalSize; d->cleanupFunction = cleanupFunction; d->cleanupInfo = cleanupInfo; diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index 964dc0d5c6..215dd33499 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -817,10 +817,10 @@ static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConve Q_ASSERT(data->own_data); const int depth = 32; - - const qsizetype dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2; - const qsizetype nbytes = dst_bytes_per_line * data->height; - uchar *const newData = (uchar *)realloc(data->data, nbytes); + auto params = QImageData::calculateImageParameters(data->width, data->height, depth); + if (params.bytesPerLine < 0) + return false; + uchar *const newData = (uchar *)realloc(data->data, params.totalSize); if (!newData) return false; @@ -828,10 +828,10 @@ static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConve // start converting from the end because the end image is bigger than the source uchar *src_data = newData + data->nbytes; // end of src - quint32 *dest_data = (quint32 *) (newData + nbytes); // end of dest > end of src + quint32 *dest_data = (quint32 *) (newData + params.totalSize); // end of dest > end of src const int width = data->width; const int src_pad = data->bytes_per_line - width; - const int dest_pad = (dst_bytes_per_line >> 2) - width; + const int dest_pad = (params.bytesPerLine >> 2) - width; if (data->colortable.size() == 0) { data->colortable.resize(256); for (int i = 0; i < 256; ++i) @@ -858,9 +858,9 @@ static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConve data->colortable = QVector(); data->format = QImage::Format_ARGB32_Premultiplied; - data->bytes_per_line = dst_bytes_per_line; + data->bytes_per_line = params.bytesPerLine; data->depth = depth; - data->nbytes = nbytes; + data->nbytes = params.totalSize; return true; } @@ -871,10 +871,10 @@ static bool convert_indexed8_to_ARGB_inplace(QImageData *data, Qt::ImageConversi Q_ASSERT(data->own_data); const int depth = 32; - - const qsizetype dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2; - const qsizetype nbytes = dst_bytes_per_line * data->height; - uchar *const newData = (uchar *)realloc(data->data, nbytes); + auto params = QImageData::calculateImageParameters(data->width, data->height, depth); + if (params.bytesPerLine < 0) + return false; + uchar *const newData = (uchar *)realloc(data->data, params.totalSize); if (!newData) return false; @@ -882,10 +882,10 @@ static bool convert_indexed8_to_ARGB_inplace(QImageData *data, Qt::ImageConversi // start converting from the end because the end image is bigger than the source uchar *src_data = newData + data->nbytes; - quint32 *dest_data = (quint32 *) (newData + nbytes); + quint32 *dest_data = (quint32 *) (newData + params.totalSize); const int width = data->width; const int src_pad = data->bytes_per_line - width; - const int dest_pad = (dst_bytes_per_line >> 2) - width; + const int dest_pad = (params.bytesPerLine >> 2) - width; if (data->colortable.size() == 0) { data->colortable.resize(256); for (int i = 0; i < 256; ++i) @@ -909,9 +909,9 @@ static bool convert_indexed8_to_ARGB_inplace(QImageData *data, Qt::ImageConversi data->colortable = QVector(); data->format = QImage::Format_ARGB32; - data->bytes_per_line = dst_bytes_per_line; + data->bytes_per_line = params.bytesPerLine; data->depth = depth; - data->nbytes = nbytes; + data->nbytes = params.totalSize; return true; } @@ -939,10 +939,10 @@ static bool convert_indexed8_to_RGB16_inplace(QImageData *data, Qt::ImageConvers Q_ASSERT(data->own_data); const int depth = 16; - - const qsizetype dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2; - const qsizetype nbytes = dst_bytes_per_line * data->height; - uchar *const newData = (uchar *)realloc(data->data, nbytes); + auto params = QImageData::calculateImageParameters(data->width, data->height, depth); + if (params.bytesPerLine < 0) + return false; + uchar *const newData = (uchar *)realloc(data->data, params.totalSize); if (!newData) return false; @@ -950,10 +950,10 @@ static bool convert_indexed8_to_RGB16_inplace(QImageData *data, Qt::ImageConvers // start converting from the end because the end image is bigger than the source uchar *src_data = newData + data->nbytes; - quint16 *dest_data = (quint16 *) (newData + nbytes); + quint16 *dest_data = (quint16 *) (newData + params.totalSize); const int width = data->width; const int src_pad = data->bytes_per_line - width; - const int dest_pad = (dst_bytes_per_line >> 1) - width; + const int dest_pad = (params.bytesPerLine >> 1) - width; quint16 colorTableRGB16[256]; const int tableSize = data->colortable.size(); @@ -983,9 +983,9 @@ static bool convert_indexed8_to_RGB16_inplace(QImageData *data, Qt::ImageConvers } data->format = QImage::Format_RGB16; - data->bytes_per_line = dst_bytes_per_line; + data->bytes_per_line = params.bytesPerLine; data->depth = depth; - data->nbytes = nbytes; + data->nbytes = params.totalSize; return true; } @@ -997,6 +997,7 @@ static bool convert_RGB_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFl const int depth = 16; + // cannot overflow, since we're shrinking the buffer const qsizetype dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2; const qsizetype src_bytes_per_line = data->bytes_per_line; quint32 *src_data = (quint32 *) data->data; @@ -1013,12 +1014,11 @@ static bool convert_RGB_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFl data->depth = depth; data->nbytes = dst_bytes_per_line * data->height; uchar *const newData = (uchar *)realloc(data->data, data->nbytes); - if (newData) { + if (newData) data->data = newData; - return true; - } else { - return false; - } + + // can't fail, since we're shrinking + return true; } static void convert_ARGB_PM_to_ARGB(QImageData *dest, const QImageData *src) diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h index 2fe29a88d3..e3a6c53833 100644 --- a/src/gui/image/qimage_p.h +++ b/src/gui/image/qimage_p.h @@ -52,6 +52,7 @@ // #include +#include #include #include @@ -104,8 +105,40 @@ struct Q_GUI_EXPORT QImageData { // internal image data bool doImageIO(const QImage *image, QImageWriter* io, int quality) const; QPaintEngine *paintEngine; + + struct ImageSizeParameters { + qsizetype bytesPerLine; + qsizetype totalSize; + }; + static ImageSizeParameters calculateImageParameters(qsizetype width, qsizetype height, qsizetype depth); }; +inline QImageData::ImageSizeParameters +QImageData::calculateImageParameters(qsizetype width, qsizetype height, qsizetype depth) +{ + ImageSizeParameters invalid = { -1, -1 }; + if (height <= 0) + return invalid; + + // calculate the size, taking care of overflows + qsizetype bytes_per_line; + if (mul_overflow(width, depth, &bytes_per_line)) + return invalid; + if (add_overflow(bytes_per_line, qsizetype(31), &bytes_per_line)) + return invalid; + // bytes per scanline (must be multiple of 4) + bytes_per_line = (bytes_per_line >> 5) << 2; // can't overflow + + qsizetype total_size; + if (mul_overflow(height, bytes_per_line, &total_size)) + return invalid; + qsizetype dummy; + if (mul_overflow(height, qsizetype(sizeof(uchar *)), &dummy)) + return invalid; // why is this here? + + return { bytes_per_line, total_size }; +} + typedef void (*Image_Converter)(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags); typedef bool (*InPlace_Image_Converter)(QImageData *data, Qt::ImageConversionFlags); From b01a53fe328b37324c6e3ab38c50f156c93c6afe Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 6 Nov 2018 08:15:26 -0800 Subject: [PATCH 0237/1650] QStyleSheet: use the << form of qWarning to get more info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit %p just prints a pointer. The operator<<(QObject*) member will print the class type and object name. Change-Id: Iba4b5c183776497d8ee1fffd1564951da0c6bebc Reviewed-by: Sérgio Martins --- src/widgets/styles/qstylesheetstyle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 71c7f5449a..fe6a4d0e40 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -1641,7 +1641,7 @@ QVector QStyleSheetStyle::styleRules(const QObject *obj) const if (!parser.parse(&ss)) { parser.init(QLatin1String("* {") + styleSheet + QLatin1Char('}')); if (Q_UNLIKELY(!parser.parse(&ss))) - qWarning("Could not parse stylesheet of object %p", o); + qWarning() << "Could not parse stylesheet of object" << o; } ss.origin = StyleSheetOrigin_Inline; styleSheetCaches->styleSheetCache.insert(o, ss); From 3e36fb641e15b92826792daf9153bbab7573a6f1 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 15 Oct 2018 19:51:46 +0200 Subject: [PATCH 0238/1650] Test and document QTest::toHexRepresentation() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's not actually exercised by anything in our source tree, but is potentially useful and has been part of the documented public API for some time. So mention that the caller is responsible for delete[]ing its return and add a test that exercises it. Task-number: QTPM-1385 Change-Id: Ifc5284b9eb1b678cf3c9708c681311e874838fc6 Reviewed-by: Jędrzej Nowacki --- src/testlib/qtestcase.cpp | 4 +- tests/auto/testlib/outformat/outformat.pro | 7 ++ .../auto/testlib/outformat/tst_outformat.cpp | 71 +++++++++++++++++++ tests/auto/testlib/testlib.pro | 7 +- 4 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 tests/auto/testlib/outformat/outformat.pro create mode 100644 tests/auto/testlib/outformat/tst_outformat.cpp diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 59ea4c194c..1c3292ead9 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -1200,7 +1200,9 @@ char *formatString(const char *prefix, const char *suffix, size_t numArguments, Returns a pointer to a string that is the string \a ba represented as a space-separated sequence of hex characters. If the input is considered too long, it is truncated. A trucation is indicated in - the returned string as an ellipsis at the end. + the returned string as an ellipsis at the end. The caller has + ownership of the returned pointer and must ensure it is later passed + to operator delete[]. \a length is the length of the string \a ba. */ diff --git a/tests/auto/testlib/outformat/outformat.pro b/tests/auto/testlib/outformat/outformat.pro new file mode 100644 index 0000000000..ea02f3167f --- /dev/null +++ b/tests/auto/testlib/outformat/outformat.pro @@ -0,0 +1,7 @@ +CONFIG += testcase +QT = core testlib + +SOURCES += tst_outformat.cpp +TARGET = outformat + +include($$QT_SOURCE_TREE/src/testlib/selfcover.pri) diff --git a/tests/auto/testlib/outformat/tst_outformat.cpp b/tests/auto/testlib/outformat/tst_outformat.cpp new file mode 100644 index 0000000000..5d131159a9 --- /dev/null +++ b/tests/auto/testlib/outformat/tst_outformat.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +class tst_OutFormat : public QObject +{ + Q_OBJECT +private slots: + void toHex_data() const; + void toHex() const; + // other formats of interest ? +}; + +void tst_OutFormat::toHex_data() const +{ + QTest::addColumn("raw"); + QTest::addColumn("hex"); + + QTest::newRow("empty") << QByteArray("") << QByteArray(""); + QTest::newRow("long") + << QByteArray("Truncates in ellipsis when more than fifty characters long") + << QByteArray("54 72 75 6E 63 61 74 65 73 20 69 6E 20 65 6C 6C " + "69 70 73 69 73 20 77 68 65 6E 20 6D 6F 72 65 20 " + "74 68 61 6E 20 66 69 66 74 79 20 63 68 61 72 61 " + "63 74 ..."); + QTest::newRow("spaces") + << QByteArray(" \t\n\v\f\r") << QByteArray("20 09 0A 0B 0C 0D"); + QTest::newRow("ASCII-escapes") + << QByteArray("\a\b\\\"'\177") << QByteArray("07 08 5C 22 27 7F"); + // These are the ISO Latin-15  , pound, Euro, ..., y-umlaut + QTest::newRow("8-bit-sampler") + << QByteArray("\240\243\244\261\327\360\377") << QByteArray("A0 A3 A4 B1 D7 F0 FF"); +} + +void tst_OutFormat::toHex() const +{ + QFETCH(QByteArray, raw); + QFETCH(QByteArray, hex); + QScopedArrayPointer repr(QTest::toHexRepresentation(raw.constData(), raw.size())); + QCOMPARE(repr.data(), hex); +} + +QTEST_APPLESS_MAIN(tst_OutFormat) + +#include "tst_outformat.moc" diff --git a/tests/auto/testlib/testlib.pro b/tests/auto/testlib/testlib.pro index 25ccc591d6..587c76a189 100644 --- a/tests/auto/testlib/testlib.pro +++ b/tests/auto/testlib/testlib.pro @@ -1,6 +1,7 @@ -TEMPLATE=subdirs -SUBDIRS=\ +TEMPLATE = subdirs +SUBDIRS = \ + outformat \ qsignalspy \ selftests \ -qtHaveModule(widgets):SUBDIRS += qabstractitemmodeltester +qtHaveModule(widgets): SUBDIRS += qabstractitemmodeltester From b514c82e1d6629d213d705da09169954f453c454 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 2 Nov 2018 14:14:09 -0700 Subject: [PATCH 0239/1650] Remove QT_MEMFILL_xxx macros They were just calling a function, may as well just call said function directly. Change-Id: I343f2beed55440a7ac0bfffd15636b183c1a420f Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qdrawhelper.cpp | 4 ++-- src/gui/painting/qdrawhelper_neon.cpp | 2 +- src/gui/painting/qdrawhelper_p.h | 6 ------ 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index c240618199..c0320f5a70 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -4343,7 +4343,7 @@ static void blend_color_argb(int count, const QSpan *spans, void *userData) while (count--) { uint *target = ((uint *)data->rasterBuffer->scanLine(spans->y)) + spans->x; if (spans->coverage == 255) { - QT_MEMFILL_UINT(target, spans->len, color); + qt_memfill(target, color, spans->len); } else { uint c = BYTE_MUL(color, spans->coverage); int ialpha = 255 - spans->coverage; @@ -4422,7 +4422,7 @@ static void blend_color_rgb16(int count, const QSpan *spans, void *userData) while (count--) { ushort *target = ((ushort *)data->rasterBuffer->scanLine(spans->y)) + spans->x; if (spans->coverage == 255) { - QT_MEMFILL_USHORT(target, spans->len, c); + qt_memfill(target, c, spans->len); } else { ushort color = BYTE_MUL_RGB16(c, spans->coverage); int ialpha = 255 - spans->coverage; diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp index 629dfe2358..2e6832d992 100644 --- a/src/gui/painting/qdrawhelper_neon.cpp +++ b/src/gui/painting/qdrawhelper_neon.cpp @@ -791,7 +791,7 @@ void QT_FASTCALL qt_destStoreRGB16_neon(QRasterBuffer *rasterBuffer, int x, int void QT_FASTCALL comp_func_solid_SourceOver_neon(uint *destPixels, int length, uint color, uint const_alpha) { if ((const_alpha & qAlpha(color)) == 255) { - QT_MEMFILL_UINT(destPixels, length, color); + qt_memfill32(destPixels, color, length); } else { if (const_alpha != 255) color = BYTE_MUL(color, const_alpha); diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index b1d4b3a9b0..06dc64549b 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -944,12 +944,6 @@ inline void qt_rectfill(T *dest, T value, } } -#define QT_MEMFILL_UINT(dest, length, color) \ - qt_memfill(dest, color, length); - -#define QT_MEMFILL_USHORT(dest, length, color) \ - qt_memfill(dest, color, length); - #define QT_MEMCPY_REV_UINT(dest, src, length) \ do { \ /* Duff's device */ \ From 87d6a631b76bb9c0a803e25a1efed017578c66c4 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 5 Nov 2018 12:51:46 -0800 Subject: [PATCH 0240/1650] Remove unused QT_MEMCPY_REV_UINT macro It's not used anywhere. Patch-By: Allan Sandfeld Jensen Change-Id: Iba4b5c183776497d8ee1fffd1564559d6502a6f5 Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qdrawhelper_p.h | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 06dc64549b..509fa044f8 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -944,26 +944,6 @@ inline void qt_rectfill(T *dest, T value, } } -#define QT_MEMCPY_REV_UINT(dest, src, length) \ -do { \ - /* Duff's device */ \ - uint *_d = (uint*)(dest) + length; \ - const uint *_s = (uint*)(src) + length; \ - int n = ((length) + 7) / 8; \ - switch ((length) & 0x07) \ - { \ - case 0: do { *--_d = *--_s; Q_FALLTHROUGH(); \ - case 7: *--_d = *--_s; Q_FALLTHROUGH(); \ - case 6: *--_d = *--_s; Q_FALLTHROUGH(); \ - case 5: *--_d = *--_s; Q_FALLTHROUGH(); \ - case 4: *--_d = *--_s; Q_FALLTHROUGH(); \ - case 3: *--_d = *--_s; Q_FALLTHROUGH(); \ - case 2: *--_d = *--_s; Q_FALLTHROUGH(); \ - case 1: *--_d = *--_s; \ - } while (--n > 0); \ - } \ -} while (false) - #define QT_MEMCPY_USHORT(dest, src, length) \ do { \ /* Duff's device */ \ From 2b8b878f5a33e067c22d8387f8a3e14c5ea51114 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 5 Nov 2018 12:53:28 -0800 Subject: [PATCH 0241/1650] Remove QT_MEMCPY_USHORT macro and just use memcpy Compilers can optimize memcpy, so don't try to be too smart. Change-Id: Iba4b5c183776497d8ee1fffd156455b50de65182 Patch-By: Allan Sandfeld Jensen Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qblendfunctions.cpp | 18 +++++------------- src/gui/painting/qdrawhelper_p.h | 20 -------------------- 2 files changed, 5 insertions(+), 33 deletions(-) diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp index 2dd5144e40..348eceb47f 100644 --- a/src/gui/painting/qblendfunctions.cpp +++ b/src/gui/painting/qblendfunctions.cpp @@ -187,19 +187,11 @@ void qt_blend_rgb16_on_rgb16(uchar *dst, int dbpl, #endif if (const_alpha == 256) { - if (w <= 64) { - while (h--) { - QT_MEMCPY_USHORT(dst, src, w); - dst += dbpl; - src += sbpl; - } - } else { - int length = w << 1; - while (h--) { - memcpy(dst, src, length); - dst += dbpl; - src += sbpl; - } + int length = w << 1; + while (h--) { + memcpy(dst, src, length); + dst += dbpl; + src += sbpl; } } else if (const_alpha != 0) { quint16 *d = (quint16 *) dst; diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 509fa044f8..23520ad64b 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -944,26 +944,6 @@ inline void qt_rectfill(T *dest, T value, } } -#define QT_MEMCPY_USHORT(dest, src, length) \ -do { \ - /* Duff's device */ \ - ushort *_d = (ushort*)(dest); \ - const ushort *_s = (const ushort*)(src); \ - int n = ((length) + 7) / 8; \ - switch ((length) & 0x07) \ - { \ - case 0: do { *_d++ = *_s++; Q_FALLTHROUGH(); \ - case 7: *_d++ = *_s++; Q_FALLTHROUGH(); \ - case 6: *_d++ = *_s++; Q_FALLTHROUGH(); \ - case 5: *_d++ = *_s++; Q_FALLTHROUGH(); \ - case 4: *_d++ = *_s++; Q_FALLTHROUGH(); \ - case 3: *_d++ = *_s++; Q_FALLTHROUGH(); \ - case 2: *_d++ = *_s++; Q_FALLTHROUGH(); \ - case 1: *_d++ = *_s++; \ - } while (--n > 0); \ - } \ -} while (false) - inline ushort qConvertRgb32To16(uint c) { return (((c) >> 3) & 0x001f) From f519cd501e5568dd80f7f0ba652d331bde90bbdf Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 2 May 2018 16:18:46 +0200 Subject: [PATCH 0242/1650] Add Q_FALLTHROUGH to qdrawhelper_neon.cpp Edited-By: Thiago Macieira Change-Id: I8981c9bad1b1dce288b8265bb79e485079769342 Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qdrawhelper_neon.cpp | 28 +++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp index 2e6832d992..c33a1e7fc5 100644 --- a/src/gui/painting/qdrawhelper_neon.cpp +++ b/src/gui/painting/qdrawhelper_neon.cpp @@ -84,20 +84,20 @@ void qt_memfill32(quint32 *dest, quint32 value, int count) switch (epilogueSize) { - case 15: *dest++ = value; - case 14: *dest++ = value; - case 13: *dest++ = value; - case 12: *dest++ = value; - case 11: *dest++ = value; - case 10: *dest++ = value; - case 9: *dest++ = value; - case 8: *dest++ = value; - case 7: *dest++ = value; - case 6: *dest++ = value; - case 5: *dest++ = value; - case 4: *dest++ = value; - case 3: *dest++ = value; - case 2: *dest++ = value; + case 15: *dest++ = value; Q_FALLTHROUGH(); + case 14: *dest++ = value; Q_FALLTHROUGH(); + case 13: *dest++ = value; Q_FALLTHROUGH(); + case 12: *dest++ = value; Q_FALLTHROUGH(); + case 11: *dest++ = value; Q_FALLTHROUGH(); + case 10: *dest++ = value; Q_FALLTHROUGH(); + case 9: *dest++ = value; Q_FALLTHROUGH(); + case 8: *dest++ = value; Q_FALLTHROUGH(); + case 7: *dest++ = value; Q_FALLTHROUGH(); + case 6: *dest++ = value; Q_FALLTHROUGH(); + case 5: *dest++ = value; Q_FALLTHROUGH(); + case 4: *dest++ = value; Q_FALLTHROUGH(); + case 3: *dest++ = value; Q_FALLTHROUGH(); + case 2: *dest++ = value; Q_FALLTHROUGH(); case 1: *dest++ = value; } } From db3777dd50210467aac44a152cb4dae8bb16c422 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 5 Nov 2018 12:57:48 -0800 Subject: [PATCH 0243/1650] Use regular SSE2 stores instead of non-temporal ones in qt_memfill32 There's no good reason to use non-temporal stores. Images may be 100x bigger than strings, but they're not so big that the non-temporal stores make sense. Patch-By: Allan Sandfeld Jensen Change-Id: Iba4b5c183776497d8ee1fffd156380ec9103ef1a Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qdrawhelper_sse2.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index 3212ffdd2d..1673b27922 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -266,20 +266,20 @@ void qt_memfill32(quint32 *dest, quint32 value, int count) int count128 = count / 4; __m128i *dst128 = reinterpret_cast<__m128i*>(dest); __m128i *end128 = dst128 + count128; - const __m128i value128 = _mm_set_epi32(value, value, value, value); + const __m128i value128 = _mm_set1_epi32(value); while (dst128 + 3 < end128) { - _mm_stream_si128(dst128 + 0, value128); - _mm_stream_si128(dst128 + 1, value128); - _mm_stream_si128(dst128 + 2, value128); - _mm_stream_si128(dst128 + 3, value128); + _mm_store_si128(dst128 + 0, value128); + _mm_store_si128(dst128 + 1, value128); + _mm_store_si128(dst128 + 2, value128); + _mm_store_si128(dst128 + 3, value128); dst128 += 4; } switch (count128 & 0x3) { - case 3: _mm_stream_si128(dst128++, value128); Q_FALLTHROUGH(); - case 2: _mm_stream_si128(dst128++, value128); Q_FALLTHROUGH(); - case 1: _mm_stream_si128(dst128++, value128); + case 3: _mm_store_si128(dst128++, value128); Q_FALLTHROUGH(); + case 2: _mm_store_si128(dst128++, value128); Q_FALLTHROUGH(); + case 1: _mm_store_si128(dst128++, value128); } } From 97f73e957756753b09a778daf2ee8f0ddb97f746 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Sat, 15 Sep 2018 00:12:42 +0200 Subject: [PATCH 0244/1650] Handle fonts that have commas/quotes in the family name Since the comma character was originally used as a separator, we need to extend QFont to have setFamilies() so that we can avoid joining the family strings together. This enables us to see the family name as a single string and for multiple family names, we have families(). Subsequently, this has added functions to QTextCharFormat to account for multiple font families too. So it is now possible to set a single one directly with setFontFamily() and multiple ones with setFontFamilies(). This also bumps up the datastream version to 19 as QFont now streams the families list as well. [ChangeLog][QtGui][QFont] Add setFamilies()/families() to aid using of font families with commas and quotes in their name. [ChangeLog][Important Behavior Changes] QDataStream version bumped up to 19 to account for changes in the serialization of QFont. Fixes: QTBUG-46322 Change-Id: Iee9f715e47544a7a705c7f36401aba216a7d42b0 Reviewed-by: Lars Knoll Reviewed-by: Allan Sandfeld Jensen --- src/corelib/serialization/qdatastream.cpp | 2 +- src/corelib/serialization/qdatastream.h | 2 +- src/gui/text/qcssparser.cpp | 11 +- src/gui/text/qfont.cpp | 67 +++++++++- src/gui/text/qfont.h | 6 +- src/gui/text/qfont_p.h | 4 + src/gui/text/qfontdatabase.cpp | 54 ++++---- src/gui/text/qfontengine.cpp | 2 +- src/gui/text/qtextformat.cpp | 23 ++++ src/gui/text/qtextformat.h | 6 + src/gui/text/qtexthtmlparser.cpp | 3 +- tests/auto/gui/text/qfont/qfont.pro | 1 + tests/auto/gui/text/qfont/testfont.qrc | 5 + tests/auto/gui/text/qfont/tst_qfont.cpp | 123 ++++++++++++++++++ tests/auto/gui/text/qfont/weirdfont.otf | Bin 0 -> 25008 bytes .../gui/text/qfontcache/tst_qfontcache.cpp | 45 +++++++ .../tst_qtextdocumentfragment.cpp | 51 ++++++-- 17 files changed, 356 insertions(+), 49 deletions(-) create mode 100644 tests/auto/gui/text/qfont/testfont.qrc create mode 100644 tests/auto/gui/text/qfont/weirdfont.otf diff --git a/src/corelib/serialization/qdatastream.cpp b/src/corelib/serialization/qdatastream.cpp index 8566b4fd56..01808ebce6 100644 --- a/src/corelib/serialization/qdatastream.cpp +++ b/src/corelib/serialization/qdatastream.cpp @@ -559,7 +559,7 @@ void QDataStream::setByteOrder(ByteOrder bo) \value Qt_5_10 Same as Qt_5_6 \value Qt_5_11 Same as Qt_5_6 \value Qt_5_12 Version 18 (Qt 5.12) - \value Qt_5_13 Same as Qt_5_12 + \value Qt_5_13 Version 19 (Qt 5.13) \omitvalue Qt_DefaultCompiledVersion \sa setVersion(), version() diff --git a/src/corelib/serialization/qdatastream.h b/src/corelib/serialization/qdatastream.h index ad69621bbe..2c874700e4 100644 --- a/src/corelib/serialization/qdatastream.h +++ b/src/corelib/serialization/qdatastream.h @@ -99,7 +99,7 @@ public: Qt_5_10 = Qt_5_9, Qt_5_11 = Qt_5_10, Qt_5_12 = 18, - Qt_5_13 = Qt_5_12, + Qt_5_13 = 19, #if QT_VERSION >= 0x050e00 #error Add the datastream version for this Qt version and update Qt_DefaultCompiledVersion #endif diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp index 8e317d5b97..91fa40eddf 100644 --- a/src/gui/text/qcssparser.cpp +++ b/src/gui/text/qcssparser.cpp @@ -1200,11 +1200,13 @@ static bool setFontWeightFromValue(const QCss::Value &value, QFont *font) static bool setFontFamilyFromValues(const QVector &values, QFont *font, int start = 0) { QString family; + QStringList families; bool shouldAddSpace = false; for (int i = start; i < values.count(); ++i) { const QCss::Value &v = values.at(i); if (v.type == Value::TermOperatorComma) { - family += QLatin1Char(','); + families << family; + family.clear(); shouldAddSpace = false; continue; } @@ -1216,9 +1218,12 @@ static bool setFontFamilyFromValues(const QVector &values, QFont *f family += str; shouldAddSpace = true; } - if (family.isEmpty()) + if (!family.isEmpty()) + families << family; + if (families.isEmpty()) return false; - font->setFamily(family); + font->setFamily(families.at(0)); + font->setFamilies(families); return true; } diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index a23ef95fde..258a9ba675 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -116,7 +116,17 @@ bool QFontDef::exactMatch(const QFontDef &other) const if (stretch != 0 && other.stretch != 0 && stretch != other.stretch) return false; + if (families.size() != other.families.size()) + return false; + QString this_family, this_foundry, other_family, other_foundry; + for (int i = 0; i < families.size(); ++i) { + QFontDatabase::parseFontName(families.at(i), this_foundry, this_family); + QFontDatabase::parseFontName(other.families.at(i), other_foundry, other_family); + if (this_family != other_family || this_foundry != other_foundry) + return false; + } + QFontDatabase::parseFontName(family, this_foundry, this_family); QFontDatabase::parseFontName(other.family, other_foundry, other_family); @@ -261,6 +271,9 @@ void QFontPrivate::resolve(uint mask, const QFontPrivate *other) if (! (mask & QFont::FamilyResolved)) request.family = other->request.family; + if (!(mask & QFont::FamiliesResolved)) + request.families = other->request.families; + if (! (mask & QFont::StyleNameResolved)) request.styleName = other->request.styleName; @@ -424,7 +437,8 @@ QFontEngineData::~QFontEngineData() \target fontmatching The font matching algorithm works as follows: \list 1 - \li If the specified font family exists and can be used to represent + \li The specified font families (set by setFamilies()) are searched for. + \li If not found, then if set the specified font family exists and can be used to represent the writing system in use, it will be selected. \li If not, a replacement font that supports the writing system is selected. The font matching algorithm will try to find the @@ -506,6 +520,7 @@ QFontEngineData::~QFontEngineData() individually and then considered resolved. \value FamilyResolved + \value FamiliesResolved \value SizeResolved \value StyleHintResolved \value StyleStrategyResolved @@ -1691,6 +1706,7 @@ bool QFont::operator<(const QFont &f) const if (r1.stretch != r2.stretch) return r1.stretch < r2.stretch; if (r1.styleHint != r2.styleHint) return r1.styleHint < r2.styleHint; if (r1.styleStrategy != r2.styleStrategy) return r1.styleStrategy < r2.styleStrategy; + if (r1.families != r2.families) return r1.families < r2.families; if (r1.family != r2.family) return r1.family < r2.family; if (f.d->capital != d->capital) return f.d->capital < d->capital; @@ -2192,6 +2208,48 @@ QString QFont::lastResortFont() const } #endif +/*! + \since 5.13 + + Returns the requested font family names, i.e. the names set in the last + setFamilies() call or via the constructor. Otherwise it returns an + empty list. + + \sa setFamily(), setFamilies(), family(), substitutes(), substitute() +*/ + +QStringList QFont::families() const +{ + return d->request.families; +} + +/*! + \since 5.13 + + Sets the list of family names for the font. The names are case + insensitive and may include a foundry name. The first family in + \a families will be set as the main family for the font. + + Each family name entry in \a families may optionally also include a + foundry name, e.g. "Helvetica [Cronyx]". If the family is + available from more than one foundry and the foundry isn't + specified, an arbitrary foundry is chosen. If the family isn't + available a family will be set using the \l{QFont}{font matching} + algorithm. + + \sa family(), families(), setFamily(), setStyleHint(), QFontInfo +*/ + +void QFont::setFamilies(const QStringList &families) +{ + if ((resolve_mask & QFont::FamiliesResolved) && d->request.families == families) + return; + detach(); + d->request.families = families; + resolve_mask |= QFont::FamiliesResolved; +} + + /***************************************************************************** QFont stream functions *****************************************************************************/ @@ -2256,6 +2314,8 @@ QDataStream &operator<<(QDataStream &s, const QFont &font) s << (quint8)font.d->request.hintingPreference; if (s.version() >= QDataStream::Qt_5_6) s << (quint8)font.d->capital; + if (s.version() >= QDataStream::Qt_5_13) + s << font.d->request.families; return s; } @@ -2351,6 +2411,11 @@ QDataStream &operator>>(QDataStream &s, QFont &font) s >> value; font.d->capital = QFont::Capitalization(value); } + if (s.version() >= QDataStream::Qt_5_13) { + QStringList value; + s >> value; + font.d->request.families = value; + } return s; } diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h index a94586166e..1fe450e002 100644 --- a/src/gui/text/qfont.h +++ b/src/gui/text/qfont.h @@ -164,7 +164,8 @@ public: WordSpacingResolved = 0x4000, HintingPreferenceResolved = 0x8000, StyleNameResolved = 0x10000, - AllPropertiesResolved = 0x1ffff + FamiliesResolved = 0x20000, + AllPropertiesResolved = 0x3ffff }; QFont(); @@ -179,6 +180,9 @@ public: QString family() const; void setFamily(const QString &); + QStringList families() const; + void setFamilies(const QStringList &); + QString styleName() const; void setStyleName(const QString &); diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h index 350ba7ce3c..09c18de5a6 100644 --- a/src/gui/text/qfont_p.h +++ b/src/gui/text/qfont_p.h @@ -78,6 +78,7 @@ struct QFontDef } QString family; + QStringList families; QString styleName; QStringList fallBackFamilies; @@ -109,6 +110,7 @@ struct QFontDef && styleStrategy == other.styleStrategy && ignorePitch == other.ignorePitch && fixedPitch == other.fixedPitch && family == other.family + && families == other.families && styleName == other.styleName && hintingPreference == other.hintingPreference ; @@ -122,6 +124,7 @@ struct QFontDef if (styleHint != other.styleHint) return styleHint < other.styleHint; if (styleStrategy != other.styleStrategy) return styleStrategy < other.styleStrategy; if (family != other.family) return family < other.family; + if (families != other.families) return families < other.families; if (styleName != other.styleName) return styleName < other.styleName; if (hintingPreference != other.hintingPreference) return hintingPreference < other.hintingPreference; @@ -144,6 +147,7 @@ inline uint qHash(const QFontDef &fd, uint seed = 0) Q_DECL_NOTHROW ^ qHash(fd.ignorePitch) ^ qHash(fd.fixedPitch) ^ qHash(fd.family, seed) + ^ qHash(fd.families, seed) ^ qHash(fd.styleName) ^ qHash(fd.hintingPreference) ; diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 196eebb353..42e7871214 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -696,20 +696,20 @@ static QStringList familyList(const QFontDef &req) { // list of families to try QStringList family_list; - if (req.family.isEmpty()) - return family_list; - const auto list = req.family.splitRef(QLatin1Char(',')); - const int numFamilies = list.size(); - family_list.reserve(numFamilies); - for (int i = 0; i < numFamilies; ++i) { - QStringRef str = list.at(i).trimmed(); - if ((str.startsWith(QLatin1Char('"')) && str.endsWith(QLatin1Char('"'))) - || (str.startsWith(QLatin1Char('\'')) && str.endsWith(QLatin1Char('\'')))) - str = str.mid(1, str.length() - 2); - family_list << str.toString(); + family_list << req.families; + if (!req.family.isEmpty()) { + const auto list = req.family.splitRef(QLatin1Char(',')); + const int numFamilies = list.size(); + family_list.reserve(numFamilies); + for (int i = 0; i < numFamilies; ++i) { + QStringRef str = list.at(i).trimmed(); + if ((str.startsWith(QLatin1Char('"')) && str.endsWith(QLatin1Char('"'))) + || (str.startsWith(QLatin1Char('\'')) && str.endsWith(QLatin1Char('\'')))) + str = str.mid(1, str.length() - 2); + family_list << str.toString(); + } } - // append the substitute list for each family in family_list for (int i = 0, size = family_list.size(); i < size; ++i) family_list += QFont::substitutes(family_list.at(i)); @@ -2688,9 +2688,8 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script) } QString family_name, foundry_name; - - parseFontName(request.family, foundry_name, family_name); - + const QString requestFamily = request.families.size() > 0 ? request.families.at(0) : request.family; + parseFontName(requestFamily, foundry_name, family_name); QtFontDesc desc; QList blackListed; int index = match(multi ? QChar::Script_Common : script, request, family_name, foundry_name, &desc, blackListed); @@ -2703,8 +2702,8 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script) // Don't pass empty family names to the platform font database, since it will then invoke its own matching // and we will be out of sync with the matched font. - if (fontDef.family.isEmpty()) - fontDef.family = desc.family->name; + if (fontDef.families.isEmpty() && fontDef.family.isEmpty()) + fontDef.families = QStringList(desc.family->name); engine = loadEngine(script, fontDef, desc.family, desc.foundry, desc.style, desc.size); @@ -2717,13 +2716,13 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script) } if (!engine) { - if (!request.family.isEmpty()) { + if (!requestFamily.isEmpty()) { QFont::StyleHint styleHint = QFont::StyleHint(request.styleHint); if (styleHint == QFont::AnyStyle && request.fixedPitch) styleHint = QFont::TypeWriter; QStringList fallbacks = request.fallBackFamilies - + fallbacksForFamily(request.family, + + fallbacksForFamily(requestFamily, QFont::Style(request.style), styleHint, QChar::Script(script)); @@ -2741,7 +2740,7 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script) index = match(multi ? QChar::Script_Common : script, def, def.family, QLatin1String(""), &desc, blackListed); if (index >= 0) { QFontDef loadDef = def; - if (loadDef.family.isEmpty()) + if (loadDef.families.isEmpty() && loadDef.family.isEmpty()) loadDef.family = desc.family->name; engine = loadEngine(script, loadDef, desc.family, desc.foundry, desc.style, desc.size); if (engine) @@ -2782,7 +2781,10 @@ void QFontDatabase::load(const QFontPrivate *d, int script) // look for the requested font in the engine data cache // note: fallBackFamilies are not respected in the EngineData cache key; // join them with the primary selection family to avoid cache misses - req.family = fallBackFamilies.join(QLatin1Char(',')); + if (!d->request.family.isEmpty()) + req.family = fallBackFamilies.join(QLatin1Char(',')); + if (!d->request.families.isEmpty()) + req.families = fallBackFamilies; d->engineData = fontCache->findEngineData(req); if (!d->engineData) { @@ -2803,14 +2805,14 @@ void QFontDatabase::load(const QFontPrivate *d, int script) req.fallBackFamilies = fallBackFamilies; if (!req.fallBackFamilies.isEmpty()) - req.family = req.fallBackFamilies.takeFirst(); + req.families = QStringList(req.fallBackFamilies.takeFirst()); // list of families to try QStringList family_list; - if (!req.family.isEmpty()) { + if (!req.families.isEmpty()) { // Add primary selection - family_list << req.family; + family_list << req.families.at(0); // add the default family QString defaultFamily = QGuiApplication::font().family(); @@ -2824,11 +2826,11 @@ void QFontDatabase::load(const QFontPrivate *d, int script) QStringList::ConstIterator it = family_list.constBegin(), end = family_list.constEnd(); for (; !fe && it != end; ++it) { - req.family = *it; + req.families = QStringList(*it); fe = QFontDatabase::findFont(req, script); if (fe) { - if (fe->type() == QFontEngine::Box && !req.family.isEmpty()) { + if (fe->type() == QFontEngine::Box && !req.families.isEmpty()) { if (fe->ref.load() == 0) delete fe; fe = 0; diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 9b0b0ec0d5..b06b64ca63 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -1842,7 +1842,7 @@ QFontEngine *QFontEngineMulti::loadEngine(int at) { QFontDef request(fontDef); request.styleStrategy |= QFont::NoFontMerging; - request.family = fallbackFamilyAt(at - 1); + request.families = QStringList(fallbackFamilyAt(at - 1)); // At this point, the main script of the text has already been considered // when fetching the list of fallback families from the database, and the diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index 4957da1908..18de8408b5 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -361,6 +361,9 @@ void QTextFormatPrivate::recalcFont() const case QTextFormat::FontFamily: f.setFamily(props.at(i).value.toString()); break; + case QTextFormat::FontFamilies: + f.setFamilies(props.at(i).value.toStringList()); + break; case QTextFormat::FontPointSize: f.setPointSizeF(props.at(i).value.toReal()); break; @@ -562,6 +565,7 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt) Character properties \value FontFamily + \value FontFamilies \value FontPointSize \value FontPixelSize \value FontSizeAdjustment Specifies the change in size given to the fontsize already set using @@ -1390,7 +1394,23 @@ QTextCharFormat::QTextCharFormat(const QTextFormat &fmt) \sa font() */ +/*! + \fn void QTextCharFormat::setFontFamilies(const QStringList &families) + \since 5.13 + Sets the text format's font \a families. + + \sa setFont() +*/ + +/*! + \fn QStringList QTextCharFormat::fontFamilies() const + \since 5.13 + + Returns the text format's font families. + + \sa font() +*/ /*! \fn void QTextCharFormat::setFontPointSize(qreal size) @@ -1919,6 +1939,9 @@ void QTextCharFormat::setFont(const QFont &font, FontPropertiesInheritanceBehavi if (mask & QFont::FamilyResolved) setFontFamily(font.family()); + if (mask & QFont::FamiliesResolved) + setFontFamilies(font.families()); + if (mask & QFont::SizeResolved) { const qreal pointSize = font.pointSizeF(); if (pointSize > 0) { diff --git a/src/gui/text/qtextformat.h b/src/gui/text/qtextformat.h index a8e573d5a4..d27d2e7f17 100644 --- a/src/gui/text/qtextformat.h +++ b/src/gui/text/qtextformat.h @@ -188,6 +188,7 @@ public: FontStyleStrategy = 0x1FE4, FontKerning = 0x1FE5, FontHintingPreference = 0x1FE6, + FontFamilies = 0x1FE7, FontFamily = 0x2000, FontPointSize = 0x2001, FontSizeAdjustment = 0x2002, @@ -428,6 +429,11 @@ public: inline QString fontFamily() const { return stringProperty(FontFamily); } + inline void setFontFamilies(const QStringList &families) + { setProperty(FontFamilies, QVariant(families)); } + inline QVariant fontFamilies() const + { return property(FontFamilies); } + inline void setFontPointSize(qreal size) { setProperty(FontPointSize, size); } inline qreal fontPointSize() const diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp index 4be800b251..9d2a5d553a 100644 --- a/src/gui/text/qtexthtmlparser.cpp +++ b/src/gui/text/qtexthtmlparser.cpp @@ -862,7 +862,8 @@ QString QTextHtmlParser::parseWord() ++pos; while (pos < len) { QChar c = txt.at(pos++); - if (c == QLatin1Char('\'')) + // Allow for escaped single quotes as they may be part of the string + if (c == QLatin1Char('\'') && (txt.length() > 1 && txt.at(pos - 2) != QLatin1Char('\\'))) break; else word += c; diff --git a/tests/auto/gui/text/qfont/qfont.pro b/tests/auto/gui/text/qfont/qfont.pro index 048d952faf..96cd4cfdab 100644 --- a/tests/auto/gui/text/qfont/qfont.pro +++ b/tests/auto/gui/text/qfont/qfont.pro @@ -4,3 +4,4 @@ QT += testlib QT += core-private gui-private qtHaveModule(widgets): QT += widgets SOURCES += tst_qfont.cpp +RESOURCES += testfont.qrc diff --git a/tests/auto/gui/text/qfont/testfont.qrc b/tests/auto/gui/text/qfont/testfont.qrc new file mode 100644 index 0000000000..cf51e4a2b4 --- /dev/null +++ b/tests/auto/gui/text/qfont/testfont.qrc @@ -0,0 +1,5 @@ + + + weirdfont.otf + + diff --git a/tests/auto/gui/text/qfont/tst_qfont.cpp b/tests/auto/gui/text/qfont/tst_qfont.cpp index 8090f38a2c..9acf877790 100644 --- a/tests/auto/gui/text/qfont/tst_qfont.cpp +++ b/tests/auto/gui/text/qfont/tst_qfont.cpp @@ -66,6 +66,12 @@ private slots: void fromStringWithoutStyleName(); void sharing(); + void familyNameWithCommaQuote_data(); + void familyNameWithCommaQuote(); + void setFamilies_data(); + void setFamilies(); + void setFamiliesAndFamily_data(); + void setFamiliesAndFamily(); }; // Testing get/set functions @@ -116,6 +122,14 @@ void tst_QFont::exactMatch() QVERIFY(!QFont("sans-serif").exactMatch()); QVERIFY(!QFont("serif").exactMatch()); QVERIFY(!QFont("monospace").exactMatch()); + + font.setFamilies(QStringList() << "BogusFont"); + QVERIFY(!font.exactMatch()); + QVERIFY(!QFont("sans").exactMatch()); + QVERIFY(!QFont("sans-serif").exactMatch()); + QVERIFY(!QFont("serif").exactMatch()); + QVERIFY(!QFont("monospace").exactMatch()); + } void tst_QFont::italicOblique() @@ -277,6 +291,12 @@ void tst_QFont::resolve() QCOMPARE(f4.pointSize(), 45); f4 = f4.resolve(f3); QCOMPARE(f4.pointSize(), 55); + + QFont font5, font6; + const QStringList fontFamilies = { QStringLiteral("Arial") }; + font5.setFamilies(fontFamilies); + font6 = font6.resolve(font5); + QCOMPARE(font6.families(), fontFamilies); } #ifndef QT_NO_WIDGETS @@ -624,5 +644,108 @@ void tst_QFont::sharing() QVERIFY(QFontPrivate::get(f2)->engineData != QFontPrivate::get(f)->engineData); } +void tst_QFont::familyNameWithCommaQuote_data() +{ + QTest::addColumn("familyName"); + QTest::addColumn("chosenFamilyName"); + + const QString standardFont(QFont().defaultFamily()); + if (standardFont.isEmpty()) + QSKIP("No default font available on the system"); + const QString weirdFont(QLatin1String("'My, weird'' font name',")); + const QString commaSeparated(standardFont + QLatin1String(",Times New Roman")); + const QString commaSeparatedWeird(weirdFont + QLatin1String(",") + standardFont); + const QString commaSeparatedBogus(QLatin1String("BogusFont,") + standardFont); + + QTest::newRow("standard") << standardFont << standardFont; + QTest::newRow("weird") << weirdFont << weirdFont; + QTest::newRow("commaSeparated") << commaSeparated << standardFont; + QTest::newRow("commaSeparatedWeird") << commaSeparatedWeird << weirdFont; + QTest::newRow("commaSeparatedBogus") << commaSeparatedBogus << standardFont; +} + +void tst_QFont::familyNameWithCommaQuote() +{ + QFETCH(QString, familyName); + QFETCH(QString, chosenFamilyName); + + const int weirdFontId = QFontDatabase::addApplicationFont(":/weirdfont.otf"); + + QVERIFY(weirdFontId != -1); + QFont f(familyName); + QCOMPARE(f.family(), familyName); + QCOMPARE(QFontInfo(f).family(), chosenFamilyName); + + QFontDatabase::removeApplicationFont(weirdFontId); +} + +void tst_QFont::setFamilies_data() +{ + QTest::addColumn("families"); + QTest::addColumn("chosenFamilyName"); + + const QString weirdFont(QLatin1String("'My, weird'' font name',")); + const QString standardFont(QFont().defaultFamily()); + if (standardFont.isEmpty()) + QSKIP("No default font available on the system"); + + QTest::newRow("standard") << (QStringList() << standardFont) << standardFont; + QTest::newRow("weird") << (QStringList() << weirdFont) << weirdFont; + QTest::newRow("standard-weird") << (QStringList() << standardFont << weirdFont) << standardFont; + QTest::newRow("weird-standard") << (QStringList() << weirdFont << standardFont) << weirdFont; + QTest::newRow("nonexist-weird") << (QStringList() << "NonExistentFont" << weirdFont) << weirdFont; +} + +void tst_QFont::setFamilies() +{ + QFETCH(QStringList, families); + QFETCH(QString, chosenFamilyName); + + const int weirdFontId = QFontDatabase::addApplicationFont(":/weirdfont.otf"); + + QVERIFY(weirdFontId != -1); + QFont f; + f.setFamilies(families); + QCOMPARE(QFontInfo(f).family(), chosenFamilyName); + + QFontDatabase::removeApplicationFont(weirdFontId); +} + +void tst_QFont::setFamiliesAndFamily_data() +{ + QTest::addColumn("families"); + QTest::addColumn("family"); + QTest::addColumn("chosenFamilyName"); + + const QString weirdFont(QLatin1String("'My, weird'' font name',")); + const QString defaultFont(QFont().defaultFamily()); + if (defaultFont.isEmpty()) + QSKIP("No default font available on the system"); + + const QString timesFont(QLatin1String("Times")); + const QString nonExistFont(QLatin1String("NonExistentFont")); + + QTest::newRow("firstInFamilies") << (QStringList() << defaultFont << timesFont) << weirdFont << defaultFont; + QTest::newRow("secondInFamilies") << (QStringList() << nonExistFont << weirdFont) << defaultFont << weirdFont; + QTest::newRow("family") << (QStringList() << nonExistFont) << defaultFont << defaultFont; +} + +void tst_QFont::setFamiliesAndFamily() +{ + QFETCH(QStringList, families); + QFETCH(QString, family); + QFETCH(QString, chosenFamilyName); + + const int weirdFontId = QFontDatabase::addApplicationFont(":/weirdfont.otf"); + + QVERIFY(weirdFontId != -1); + QFont f; + f.setFamilies(families); + f.setFamily(family); + QCOMPARE(QFontInfo(f).family(), chosenFamilyName); + + QFontDatabase::removeApplicationFont(weirdFontId); +} + QTEST_MAIN(tst_QFont) #include "tst_qfont.moc" diff --git a/tests/auto/gui/text/qfont/weirdfont.otf b/tests/auto/gui/text/qfont/weirdfont.otf new file mode 100644 index 0000000000000000000000000000000000000000..b91c559f5b7b69e6efd3bb840a0b5e910e2fc424 GIT binary patch literal 25008 zcmb_^2Vh&p{r}xt+OnP{TXwu8%kq-EB-`?etyrFMf=3dM3`cT2L-rmJ0we)K$|@TQ zNuU%+3Ub1Rwv<9!$|$t7rGqfauZ-}c{PSU%uc5we zRcPgaZ+H9easL^{cX-X}^&5_~`mQ0QZ9nbKWRSchJwy-M&;hF;pf@DA#fP7` zlB3V)VwA92$wZ)jq_feBNVLeMkR4<{IZS>`#%U4vEADyj4St8sVw+)0wWZrKZ56gU z+ugPw*$&&|?dj=Ux|AN19-AJQJ|jIf-Id;yKJW>5k{cgKPpmH+`Z|EV9zb8eL|?C? zFS9MdmTa@3uX6Nt*ExO3=qqueul`TyNs7Mc_`BnOCuIERxSk%rdhF!biLsAP?SJdh zw;p=y=vznLdho3uymkFsrEe9#Rruzw-hArV8^``~?03grJ@yMij{WM`lgI8nw#)Q^ z_(62;7*`#xS~kFM@L?-8^}_?7HWT0s#kw<4vJd6(k6lwgc*qN)q*80NI=#UdW0GUd zmbiFpLgI|1$EbAYBZPT5rmLJqnyaiA)>@d zBDWJ&d4cdlXdsD#G(tE^xh}$Sbg2qC+DeE$Ex~Hgsqh$m@v>U7y1cSocG_jTwbWPY z^~A?nB$biIS*(uClH%Bs;!H=nN>Z8GvowmQF;sG-7f?Lx=gUr=;9eVZKbV$OQn`3d zzQ3j^!RENDwjwiaMykJDr_t)mG}iz<8#Nki7>@jQ{3Lx|3==hWlgD3xStxXglHCHE&~C!< zJlBI6@*%==d^;i5ID-z=)eaF;qkOS4C0;en@M(EbZcc7a+eIBQMni0y-q>c*m<-)o z+9c@n@j3a~f%!&Lr^ygw>b4jM42Bqnc^nxK=5sYt4$+fDlHs>owH%>z4v(P`+Jl6W zr5uJyTAguDlOWA-nH@Z!6@{(ptefXjtA(7bESGR%G9%2VLsqRbJIkq_5xM0|9`D@< zMEHe*18Jn&zd)cI&+XPxjasuOM&x*-Wa25|>5xIi5w)6hv6QHn>a`refu&DNO-W9g zk(gk`BAR1m6K1W~X*KH8$RH~a^O|`t?=^dQyUMOy4h-30w)^bt;^r^-wDX=N-~05c z#owcRN@Q#vwWdbi-?#Y6Pp(?LFY?b+8q*p1a|+Gk7e$WIbgm}ipl?JRp~$hmNH%?) zU41k?#Hi-lal-#WGLd{zN@~a&|H?dUaq25@#t15|kg8R2R1k$ZMyjPPm?qWi22io& zAf>yBmeXSKRoreOss*(u>;&fXdx%OcsJaO5)jfcL5R#~%7JwDyWq3_~tSp=5WLb{W zOKC0&G7<0f_`GIEW>#jFoC=(mRB?_H+yUhsvNx4_W!#h$`$~N!X1SV{6lZ1fvZRu* zJL0)nb*njGxu{-2D_H77M z(il!H2AWs)`AQk?iKKe`?~-0TN@7SZCR9zjxzv`huC3djk3G*5f#0cRB#|Thh+g72 z4W(+1jsPH{0uV8z(s80%Y)@(l>(RWj9qIW%-)hRIQU&X)sjn31oKLedUDQY!N}H)yGi~)sI!$f*^S;N22Ob~j ze|&KG@oNnW{N?2;sb)CNAn3bmD#~>;hvQg2VdCs@sa$0ll4mg~-`C?4&5 zxPRHvfq|pT`XBC#Y+ihqE1UBDou%bA`;s5#X7YWV6_sfxZxtUt(ZY={dw5y@(SH0P z6WN5iSzoEj==9CwpGaH92SBHr$c6rGiIk{jc{qc{MD+$9JQI{bRPO{*6Sa!$1X)oN z?G9ql=rsoYP7n?h3+fS~1?@3tH6su}c-lksMx=Uf2sEGZ9Ll#F4UG+f+UlyxigI6` zD?2OGnc=XdT4D`N#-=PeMoMrwX*%E=Zv{c|l#1z@S!_KBSb~o&3K+u_LgZjotrWbt zq}WAE>~RYFjju$BRV5^i{c+Rw#@ePQ2D%T@%ggSWA9#KDe?;E6`G(w_TSw|}@=DXyMMXo;a)%CYTJ-SjdEJ34J?GC}M)Qsz z_!_dsOi$n$NH}8JFht8@%(+){>$an^gTv@DC2#=6~_Bg{YfAf zV0gT~WMiDspX8Pw+mv6bUY z)_6!G+$ruChuRKTl$Tc=Zaee~u7}3a6F>R%*`G%qiH|(;^s}G-g#Hifq9Sq?J#o6v zD9a$55+{ZQz{({i5PWZZtXWIQMdYeapM9Fnj;FJKj_x8-DcJU38LQQH!e$i>B_YPE8VoSssm6Lp*> z#bA=nj#xb}l@&#Ct&7I-cM7|Sf#mozA<8mdPsBY@L8~h&XbD(e(kjP7gf&T0vWwbF z?6MCMtu@XrJLtoagS3}kNte*b!F}9i`{-H<y>v_ug`5r`d78H%$?K6dw9Ro861m~xkPt~~B?eSdRqZgi|0=q+3>=Oj9k=2!GU z+NJD>s2~W+BM=?c@*v3O^qI8SYxks3i{tj}9NM3gO>aq_my$A%wYwPd?slpnW|H8K z!%!&cVf!S6N3=aVoo$O63gkFP62JBw5%x!46@%Q-q6gk61T>fl8CMr}Y8U>TL*^oHePKhHuZi3y23cHDqjk9pT zzf2C=Ln$90JC)sJatbC#`3*g};^hr%Us|)~rM2r{K44thILj|d4eJwPL}RFNR*fXq zZAdVQN1u+|{>(Fx{m(v2gU>ue`=34)c_{Mq{PU>l7x$jOw%Y$Nt?QUWRX@9L)%xn_ zTKolLoq>7E#Op7F1jJ!c73^VChKMW(1Y$ab>7^owya34JkRwI?qC#Mrtu?|Znr*m&lRf5=~i z@nn+*e;`SMa;QumL`mF<-9trKAYh#UCmWHXkU&C&5QZyYF*BX%ws?zdG8#xW%~oMS zogVO^%q$FyCE!htNlivlG06h!pE;9yE%Ef|O?!HFweMK9x^8vu_d9NTaoesXFGk*a z_~xG#9ghFt?%@{-%y~EMS#_sjVeOrkqpq8Qu3j}CFHr)-{s@g4SIIw9B=qL<<000dYg^OFt7Pyt?(L(~y6ddR`F-AR8 zZbbCQ=@@FtRE%TmX~zoB1fhU*&%}Qf*B$BRikjv`8s@Z*{hqr%-MqW1Xox<-JuueM ze`uq}v*lig;5?PQ>-{Kx%>|6_5?>~%q|#p&-A5vbuqf@sbB-sF4WOorylR9-Xkbb%!+~$0)nD)|Hn0S-;l;r6PY*s4y}v4{qW7f z#rcOXy=nK~9?a(Fa}C9ZBccBZe;7HD<;+{&z4U|k?u2>l%)SL3A_2eO1eB+9R9JS7 z7dhY`hCA)j>-CiA)AVUciDubo0MK+)r=DDXPLWAsX`DoO(4I+wk}EM0E`Q*HUvF4+ z&Clqz(a0a>2k&QF`oWI>{(>IVJ$J(kRD9uvTOz*|?=93vMkB8+S@-)58(!T&>wic6 z9MoA#f>^N|vF2t{>@QMLEF;@H7$(0HvtgTNNTj?V@I6R)VJUW#&}x?fMO&2ILs9eD zRYcjSY+*}cxwj*0cUO9bxZi@-2R23q0!?Ny9XsUI9g!bj?D1Smv)MZG6EyAt5(ms{ zC3*hbYIic|0!9ElqCB>%f?$9k7h?F;-qcW9?66e`jAbkG*;(Q^aoJlPNxZ(j(&yEbhb$1HTbHd1lyRVne!oE>iner;O3YvolMslFGZFghf$hIuzv$Yh zBYQ@vYyQ$hlV}v_6|V*!MNR^bXwix8LOpGz?g>1KJo&rG(_>e%@hW_i|0(b&i=_M0 zP=bAk0iMf2v$NBgMP@o4I-P~f)PNXQv+HHt(a)?qm2x$<%jaw|iV>2=gTxs#NCIj$JMMIg>lJ+CI zj1J-5yT(s)w}MV25I3^}Cb0d;NCiw_j8p&xKs!L+7^MI_8NKC&_Uw$T8Fo=ha+#yT z^;Zp>)4_Mw&UL%?&sw~2$Wh?=pm*N<-bLrEy673cd|mxj>(|~;SF>Yp^GbT-@{Zp2 zlMkN*afX-ukzUn8j9W|E$bi4ks8REh;IHA-9N3z`OS}NCp#`_lf?J3fzX+t2bRanr z%r@vj&8DT+XcQBSCPZNEYuD>qngg?{t4h3i?(EETds<4YN!O-tbLtsoVz%3OZ>dj~ zD71T~X=avGb3QQeeB_}lFnbnkTXC|*TN+yeiOil(K(|ap@Y3!9)lHZ_l|ys!81yDhIh7x|BuB3E<- zfYnQ{rm-|H@;{LmKZ!Ja_9cDtI9*OZ4nN4P((b$X{0GE?^lvp|x6yQ`)A#)Dt~(oz zrjo+?HJczASS;LyOUI6GbkOp5XzNQ)MgH?IM;?v*Dzg5uS6UwX7k%{8Pw7wo87Yp0 zBcI-PF8~A>zcv1f7!;l*734h9>7Um~RYXHY$qSjss0Vrokm;eAVU8+jmoO7j0fL#Z zi@<0qb^-l4UILIInk|KZ#<$LHuANm=>B>z{O$IkKDH@uhjalO%w5!Y(E7USaI?wd4 z5)d+#HZb4O5f-u}>Nl2Sz zD~#2ug~4s5Gn!^zS(VW5*2QVL1dF@B*uNs7Fg4xz(m=uD`kJd#x);~k^f@u{GaR#0 zg=cT37j3xN7^~K(BJWoGLvK;j?1Ak*jY+Tx!X=%N&wFiZwM8(wsc_RR884PTQm4)u zdtR`ZK3cON$&zSZeBaU<2EW5FEOv{@#7oX6+x=V03-jD+Q6+T30^8a=D^man=V+*) zRcQqkGnZ&p>K#Ne;i19c zl11I^Z4Gs0J^(l&)HYrlHvkDxm0BV z=vB(HNGcx7;tZuk?|6)&m!q3Fy!ub4*l-AmGEUPm~Xsl10yW!qKTN@T3Hr8cWb8yvL`^t9e z<|cQho0`;R9mZ>1&F3A9yuT(sv%4g)MYTKOUW>(~w+Iq}KA4%bt3kqZ$ zo=jpJmHO)@^unnWS5e_cB~lj$dMl7qq`wO7UK4!W0ni>DNmSaM(fKk@H=qvZgb6C% z${nbWJd&1{W4Giu1mABg+3{)F2@bZ$DEVaE$ZvrC!$C@5H0H5scn~hoTr4)DQxZH* zBSa8Ip$A(_48gi4w#V6>nRX{=NQ%o0@*@|QLi%PTNM?q1P#_p1l@eIrpAX%!Mmf+(HKrb5Dr70`#@nmw5se5&gWIK>BZ-7tvP)JeSR;uhs4n zl`+yokzTF^wke)WwIxOMTgdtjdT9TCDd)=)HlIr{AL-0|zyf)g07XbRq5uMnZ6QI- zVeYdj%I=i;Fe)n>DYQfgH9mNme4wr+a(=WV9<(*y%1eg_=`GP2(QWhQZH><8R!nGz zxT`keRwhJ0n|C87bkjWgnKGe>JD^O6l3vcu-^Qd5VB+u>wz{#w;khRw%m4*35F0c$uRNdlg$62EUJ*y1D*^ z^C6TBM~)a}$3c4CC6$T-{A9XpJaAdX7mo@pZ&Zk4AZ=jD^)WG*?X5~pt!X*%$6fS2 z&&LnVt+l0AUA^j^Pm?VNW-=V%$Tm3YwhQM$J8B_y{#ki0haDrYE6s-x5|~x)gTBts zai??K?AkJpZ$1rN23=-};X{Bh-(FpnotY0HCxApL_6>#9GxEZ|ip3T*i+PFoET0t* z6&oC88lAMHvZ}x^z&lV~l?8P`aWc`~oQf2DDsr-6T9dPLDwVtJELp2D)o*IsyzUss>W3DQ;?D|2&N z!dkdG{6qs8jNt=zjS9O)uj3@><|{1dd z$F{N`x1 zdCC4AlVg6ff7|3tQwQ}OCdXWI|BlHqC*8koa^|Un`VNzeo7&HJK+E{4{d|YmBWMmeM=U%wlp`^1$?FH zmLjLwDLWlzFf?Ztq!uUCE4c9NS@wyH!T^*q50g4sJPlMZaA2rqige2)26$ANJyjw6 z3UfeBrlVRFhmT5%fpt)6X@{+RGHa3Itcn-$beBxGgY3b+)s%A}7$%ZzG#X;)@3%(o zl?{3m^}1$V8dT}y;**}P>$aOxtx}?tkYrE2!(hot)x@Z1oLXy1ikVShl6ieu@s+6! zoGylD#%gNjtHk?gASPBXN3P2s;OKa4j4@{HV-C+#Z?nX3fwV=(6VqZ%DH_x4SlRgY zr)Hap8Vm;gVV%LKEAM+wCqa8MSk!vKY>KUOy3d`t`+Wg1no z#B(u&8tG-dE=E_rTF~i@MqQTnPwSf0vXG)Tsnu$|-XL+j$z-U5s1ud*a>0mIB*i}i z>Ki;m;L5uh(^CA0lO_lz^~n>G-~Rn{{i)-s7f&5$a=`tOAU_9oa+%C$w&pZQQhot4 zAGC5rP(cdV8I@_F=ulX_m<1m;8-WQsqDXs?P$uM3vE3Zo-Zr~^JNBqGeC;z{v8ACk=Dc2-cEjp{g5nkVzJUvFfo`Nc zsiU(@&RGMZXf({MP3dXge(E1mjep?6oBY=eU*9uJHY;hXirN#OY4;WgJsYs|ZV1)r^?Lk6l2z8m$YQp5kq|xcD zElwsJo#W1Wvk{R=rh2WuURE1*P(HVxQy^-Z^u}f*5UoYlcj|QpLzCVx8~27evc5~F zgB6n}{o@}?nTQ>;k^-`jtWicdfWSD7C}|+QYIGX4ZYMzmluo+?=5I)^gvSDlkZMJ^ z`?Urta9U^s=V$>%g)m=r&hKcbubt(usje*d6)r4VnD0)vA@Iyftwxy5717%xSQTfO zN)jCD8Ci-$%vYKbHPA$30hm<=WI!>@(9;&ts7UFB%lk}lhGJB?~0*t8$y%#jQ;(F`Wl;?3`}nqNd&p_Lclx46hv?hJ0UcbqjkF6Suxx zl+CSa=+AElemp?Jd<$>HE{!4Thm9I&3CzytjpNO64t^qifOZ;RddZj)P3W7nz!~{G z^0|{1Oy(eU1K`xm-^qGMnYX;q(Oqa=o?`b_fOtxPf3!} zW}1M{g|pK3b@Y4EBlqN`*0<#5W|Typbvd0b+V7uPHOv3bH$f|*C9+ptmKZP8*LX?{ z#=v^#*uOS>&jZzM!C>y4TRonw+>EUaG$-e}*7L6AJ>Lku*s_u;eiJt=9)$hEO3IYA z%7d+mIq8`z749G<>V$_zh9DdRcCcC2TMgEz^GcfBg$mzQJP(;!lgt=Alg{hhzOAck z%ht~I2k&0LasOT7Vs^Wwt7}`sUF+A~eQ?8ugP>(qLMg8~%Z37ERCr8$I&;P=YZ-Og z!lofQxTTI9i#;bTE%HdcxYUu5ofe;Md4b^{B}+hJ4v4p5Hxwx`Ulj4-J3%DrE(z#I z#4aSF5<4owA4O2l2u3E$Dj2X~HvubS->A8UKX6gUJ@X%U;ZH}z+Zs+B5*M5}#J!{b z$xT0aI{L1QxiY$)Zvbun+Bkygi1E4J1n%9h*t98h@m@H{2yF2ylvObr5ekL*(FFL0 zc&LX=txIDbBEql3I!4VCirXEngg)kL?nv_6SPeL$cYa-!o<}p%@-%C^X{Vpm?C*~Ep11=`*`r^m){Y5+6| zp|TS+$)Luz_qcqH5;I@orTj#?o>3&)nG#LHP6VK8osm}~uTJLJ>?t`w*YgX6Ea0bf zRHX1>P^j`y_o3!nRrKT+%f7(hmwoupEuYNc25or|u8-h*c@Usr9*t7J7dfcEB5Y|0 z69UZO^f))NIm?-nWR?-y2lxRgtS)m2!d%2@_~&#>+r>B1v45W9$vD@a#X@AR{O37q z{#B#`<~KFMs1ExOJT6f=Y^oFx^$8)iLRJ>iIq86pQngZ_mp1k1M;h|` zR~H`3Dtz z5zw2ZdgJ{~?^k^Af#9RdB0qTjb+%q_U@u4evMYVX1O3n!I^?jWIc}32tFRE(i`i@S zd3nbh=%V8NP2#P8{A1*H)<;A*#B*XcRxnfPBMF7fn}q~H-xwO(xGb=qpCI&Dqqqns z2!}4bkhTA-GM{?HG-WI8Qy8omK{=b6;nauXLyHb2m4yxZyox37uU>h>%9ZP6ujTsf z+in!=o9hCzcVDrW4dZ5E6So@jSQ7A2X8t@1@d7$U8U^Pt(ijLH&=(5e6=L-7o_fis zk_=L#C_ut()T?=|L1;m|0%R)*pE-hFtZW$b!-7*CKBIdRhw%xapGZU}!)@&^zLEr&|1C>DfXNxc;P)ez2b~-0<0!kF~ zi2;aK1qMuK;&wK+mgZ+yT9PwX&T8o1I#9jdS5TH_H`UZN`sN&f1&poNhr$XzTO0%j zs#4xt1RBkYz!t*o0r@5{cQew5m3?r%cU+b9kW4O$a&yvs+Z)ta4;E;;gN;7;ZQ?2DAq zWSS9O2o#PYk;q(Ibdz3Bh~BEV$}yl!I)^lYh)Ga6S!|I7x}_K9_{sdAuSswvCTGW4 zUi$m#9CnTD&dg3SWyZgDCdc4WM(+}mxg<=Q$zlHs?lZhEK~kEb-4pzm^bsZAbTUQ{?_?n&(cracj2<*3tf)6mQo%JxYbHJ5U!LXgM!X;T zT7Onw40ddE3Pb;2;{BwYv${fy&5`#JJD5nmMeJbW*?nC|^p(ir)a4~st_9>!yx$wr7Aj#L;7 z6k#9h4q;#qSPBayLqfR_ya9;x$;h&1>TLjP}!p!M={;QXU4qFn!>&M$AODsS=SYl7_q$wgJZJlpVsUiIK|DN|Z8s0ntUu+rzYjV$0JAyy-L z(|fv|E<6w^9*baDFAjvYc}j0(`M|pd%;!POXAzm}pWQvXDj$d67P@hWF*n)B=n>-D zF-p)U%I#5834U-Wydz9z27yFECe`u<^Kx=Bax?JH!F)5$b0-#+tuQ56DbAXmH8bn0 zCDEx*4 zo2GqxNRwZt^qQxA=kTF-PD4yHJ#^nWbQrLFo&J!|=KlpMIn`g7p~&^-DNO412exnf z@q^p8ALd@(e)z}RwmtX&;|)BEIg(zbELJy*RI;5bKqFP)j1+)IASmF@3?MLpFkG50 z>S#Li$8=?1k<6bwN0j5vEjTv@*mRCqckVsrM48Uc#VYbKVuF}VJE^Zv=;>z^bOr;Q z2Owek{6u|`#qmta(i1ZDY2lgB$o=Dg=k6D82IQ=MocILUg~X%?aFYU)NWG}092!Ys zM?IqNCehMr{3UwRBQt|~31>io{r zj#r)(j{m3XL9C&b6q0S^R{u>E5Zq!?DOPX}B1f=B#+@VvQdJBruUbtUNA)nb5F;^h zMibnLIvBoTCDy^o3{9CQP?UH<=DXAqC&W^fET~|cftW3a%v2WS_M)Q11VW0o6>ZzJ zVeOh#EBb=HOBQx@E|`zQ7cI?A4FP7ltMZj(I&5hPg^7h2n58rUq7s!Mn@tT_XD6iK z(4`I;-dt;zFDkm7G3Gj1P?^FF&cvWbQAz2@>h-_^ZHM@-z&IaOqamUSJ5fYJ<_E@7 z$n+Lo$O)8JYBhD6lH;jrL2X%?R>xm>G(EYbvB+0h-k@4sSs57{=xmOZsd7AzEbCun zPm1E*P>@@`xMxwZhiYHOHHv7AIIYyp-#pk&Ll2RaLKFdjV6c%rwbzXYKsvsugQ|7cSbjXg=bsd2!ul?m>p@;|NF=T;j_lK>GZM zcRzjHidU-;Jzxah8x1>8pR)pz1Klal4FU0C%rP?WtRW^wF|oyjNQ@z-z1Ck z7j>CQ73Jv}`>KsA*n5t_pKk~F%Yi1{^=pJ{xmN#+w7Y+|A zTjh>@KWMF^eD|W>s~gHoxo08UPoB4!L5f&>V?H!$9POjn91~hK(=nDq3*ZzzhYK+c zq#e9?X1o&L7!5kcbiZ;^Pn>f2PXS6M$ttmt_eCYNSW-2tx0<2{E_Cd?1^4sliHr>| zuUI*hk~lx|hf(UG2f4(Y%x$limr(K2bB|C zlMTMHUou?<5i~*(_B;D|g-HukR7(c2qpb)dfV!@scKmT%WI1n-+{hVE{y{i&@)a@d z#Gpbe3laSLB>Hd=zkeogSS|S73EqHgi z{5*3kf$jDvO=gA;MbU*!{%A~Pex_bm)D>^xy!k0MlU&eMsqd&S)oH6&r_A6270#^q z_`sGzjXr%_Ah4~jj{Q&9YeZF2Z*g(Z>kSqc_a>>h{~k(>=d|^ne7Cx=L)P)y!2Do& zA*XMfSz4;AVxjw*ILvvflwR7iO*U{F5LtTKv_+ydxxIah_ z;S9;yCGbM?LS&cPm;JzTKG?g9f;c*TPQNVCOLc)i^5YhRN0T_Q`Av~PEDuV`6 zX@}jWZcrz^z5};)DUAz-X3HCq_fqb3xegw@l{;4bF};Z0M4o?TjJ_9vQwD?Ur5EwH z2`P$P-0GjBM6Fr0aIU7saiR(u3gu>l^Eabv)NllAGQ#hGAEJPxk`m?todriGSroTQ zVDW71>rn7wns_$zG-cDoxHW$z>P<+Q67?4Oa>|V|51ineh>zEiY`+uxm416mhAA=gCtp$CfT1#c!!Pv|)RZlasrna*LD(KXe|j$CzG$k+kK7;WRTE$%Go`Zn z?1NN#DAG%gso%u&!)P`6B>Eh`7bFmzhh$!rSFrQ z=|VEVeNIl{sz95+;8_=!M>cbJkPS#L=E{iyWpi<{XX|jy!{x%o%Ged0%q#WL7WZ9~ z7xxj_rTRPR2fcqw_ysvEZibBbF(}$axM0W=e}%cYFurS}7wmaN7)DSyxRiw70Futb zeK49rwj=_A1;qwjZ{P}}9{OVU!mGG2W6XnK%u0$efW9f$Ydn4vi2pmTD{zm{UH*Hh zQ-JhR+_xdm)WQhzY&UE1K0EUB@%+>1#rol}3fxa|9mF#S%HPJjFPo^t-u)-!KPR8? zpVLD~FTvFdm=j^WQa%Uw+k}sadgA&0=<`)+FX`vt1jR2hJ%Hz3%KaV6JF0Nc`cp0( zS*#LZ=0=+(SkH@bKg^zSFDq>aq{Dy(E|vo3Ea-RIOU+=1HBjKs)?nhAg#Tp9)@Ty` zYz?Mfc<%vrudD%EhlxvB1FV(6;LPAX&4suQWephor(O*HQ!fUysqmj%2PI|rg>_+T zF!kcG2Fi1!=*tWcyfJY_kp2}gyBSw2uC=)T5Z9majxx6EfV)p9c+c?nD%kz5Qc{M? zjkp?6_jS~}nA=Pqz%@WSp$vac3USR*eZh-Y>o)ekP?$Wzvn( zizvJl^$mV1%EJ%J%~6 zLF=>DcN1b0>JoM)Je9~L)+GiLFGxI?`0K=vXJpUln{j)RkaU02Z<33X=Op(f??`?( zC78M}^%M3@>rUI2_8VKQtACapeZ?g{vJv&H%|KyNS z5jl`klR*dxRL~#~>Nk<6s5v~5=b)7_`wXkYgU{VFkrz{p3G}5K_*kgE$EkVqj5YW7f?1Bg4Cz#{=WDmKDTuFX_-EueCOa4MGCEsVp5bWTa$mQf0@x5%H#o8$;NN**DPl4r?7o*d121&usiH|Vcu=)KgwI;NNpf&4%mXh+ELCDs2z3kfiM@Czr_~T zJCF&4`oluomLnX;p_{OMAlc4Jj~L@XwxWl|F z92e+j?+eEV0uvRIZ2h+I(`{iPbK#L}Y6#RXs}D={-S#l=?CDt4jmk-TyKUjNHWc}L zl5F8JmMiP&v5iJ+V?@~~nz*xt3)%BRR`cn$ZX2MnH)La{J%T8)v1eMAD`mOTU{VmV z(n)|;SRYsxCLP^jq8tse;~s}Qpv~IDsV$+$Ok^3W@t8>ZdV2apJz?tV>6w^8kF6i` zan$zYg+;fm-WC>|AZJ>8BTdyg&bpVy6NNenI%L&*!P++j_? zbp(V(fw~&Ej#>xM#ZemybA5whx(ovet8(+g8n=y&)`)2dqz_dvUVpHMRSDK9qt&{P zXpAIKUz=+`jW{~@*@%Q=g{&9q!Vm(OdeBzC*AZfissNiLu>}d+k}$~0QDSKwp}OcR z3}4ecoPkzoe0pkA8yOk?J8F-@#lY8NiIN=lo?IYtjC+*h>cjn^y1cN-jVah{;h4Z| zHZx?fLSYlT>%g5!SuYtKnG~Sd0E1;1cvubuZF_^Zune%}g=5_<^Seid{<@xwuwlTl zB`<7tx3qV+%!?K#*->s*$}R3u5*t|1JsKMu2-8q)Saz{32h^$^jbZ;x_!p+}SPS0S z);-GhA;49;7b}d{nsV(9G@Hx=AJ}u&1Us2M?ZHeMG5$uBp1oLKvxK9FG;sjPK&a{? za8fDw5a%YNgsY$59gcO>+Umnbpq~LN7X&I=P!hx#9!*HVX(uqA+S*zM2@3{-XQLLi zD}1FZDIItokIBZl^1@d4C}n8^0MF7y_bAWO8SYVmrAh8lk)_G*QHiA~?oky>Q{AI# zmZrH!H7s?x0hZ`Ogry)r?y%*D=@PbW^1|*Z593ciTpN9uH|1gG>4)p04{dG|j&Xh6 zgxOplj?R@$bn5)cIS1nt}PT)QS1AG!yeY|J9;iAJFAv^&!gDswOj|G(A% zUgm{8lWRR{lt%Nacr)ofCnZpZJQu=O{gp{>~rT^tMbBS|5sID_%c*4#}bivr!C*s z$Y=vV+q`#gqoWbDs2dy*}t0BXn$b|yJ4cXEgWRT#oyk2RIrJ*q@zNnIHRYQkz6gPH{OpCI2wXs39Ehf zzQxv}t|)sF0>OSqSOj+k)e{1tB;9Xuv#?C~rZ3)4T)& zVYFGoCdOijKsd0Hb4G$5LyT>)LGbuLK~m4W3&>J62@4xWAZAX$!che<%{=`mtOX6R z*%};;?4@iKt0$i+lZiq)Oy+mz+p56X+32}wAv!(16k*AUyJkE(EyP3@@vE2@bWE%k zSU_I5X7X(c^e2`p$RwR}r#!jDe$bD62E~T3HPGFb1md7B1q!#SkS!X@%NNPLl zY3*50C)-Z#@7xvvceuhewZdeh$rskS!bvu z@*zlSwb7|Fbar5;{l@Vo1t{$bO`osu$aM{(XlE=S(1GUzSw&v z#@Pr0T;ZC8N)zrXU3Ru+3@#J1ISqnlfFLfq?IEUMhnw@mrP$@Ozoxte-BF7<>_eS7 z?r=GhxeSW+0Jp6H+;|dN=eZd|hvx#!t?na)G$7N43}u;i_YuT0A=813QZkR#X++6< zR)=L4usST$$?C97m-{GaVF0;qv12Y(XxfeMavekdXzm~%<3t*C9Iy3>t*$n z+*0<=dQ=Otcd|@~y_047*gIKf8LQKTOh2o`G6Sp*%M7wQEHk8xs}8wgWn3&bqKu2> zmMi08x$~8AvD^w}Tr9Uz85hf~QpUw{s{!Mx(+jvpxeNR8U~M!z3)yuH=&V|}7I*8x zYmsGjHbk?m&PJsUd%)^!LgSgId)=(uDJ`}{v#iC|XqHvqhJI#7yWAelvI-YOv#i2} zsEePRoj|%B%AL~RMbRv)zB8I-)h|ZN>S%wLM6;~IrO_;_unTo-PWQK4xl{Vv6V0;f zmqoLz`sHX@6YcMcXqHvj8_lu`SGter6cINpB^|+U7Suy~0x#>Sb%oUfVLqd6%Ope3 zV=NZR;IBI%TGFe)?xO17no**vg(#RCO|@sGkE4xFDT(GDhc$xKjb_lx+o1|v-p%g& z>qfKL{bOnpEg*G0Nuyb;=n3^sn9cl`FPpE_!~^yjCC1#x==koi@I7$kx}#!0V$tjV EAL)STcK`qY literal 0 HcmV?d00001 diff --git a/tests/auto/gui/text/qfontcache/tst_qfontcache.cpp b/tests/auto/gui/text/qfontcache/tst_qfontcache.cpp index fbca313ea3..785cc3fef2 100644 --- a/tests/auto/gui/text/qfontcache/tst_qfontcache.cpp +++ b/tests/auto/gui/text/qfontcache/tst_qfontcache.cpp @@ -45,6 +45,8 @@ public: private slots: void engineData_data(); void engineData(); + void engineDataFamilies_data(); + void engineDataFamilies(); void clear(); }; @@ -109,6 +111,49 @@ void tst_QFontCache::engineData() QCOMPARE(engineData, QFontPrivate::get(f)->engineData); } +void tst_QFontCache::engineDataFamilies_data() +{ + QTest::addColumn("families"); + + const QStringList multiple = { QLatin1String("invalid"), QLatin1String("Times New Roman") }; + const QStringList multipleQuotes = { QLatin1String("'invalid'"), QLatin1String("Times New Roman") }; + const QStringList multiple2 = { QLatin1String("invalid"), QLatin1String("Times New Roman"), + QLatin1String("foobar"), QLatin1String("'baz'") }; + + QTest::newRow("unquoted-family-name") << QStringList(QLatin1String("Times New Roman")); + QTest::newRow("quoted-family-name") << QStringList(QLatin1String("Times New Roman")); + QTest::newRow("invalid") << QStringList(QLatin1String("invalid")); + QTest::newRow("multiple") << multiple; + QTest::newRow("multiple spaces quotes") << multipleQuotes; + QTest::newRow("multiple2") << multiple2; +} + +void tst_QFontCache::engineDataFamilies() +{ + QFETCH(QStringList, families); + + QFont f; + f.setFamily(QString()); // Unset the family as taken from the QGuiApplication default + f.setFamilies(families); + f.exactMatch(); // loads engine + QFontPrivate *d = QFontPrivate::get(f); + + QFontDef req = d->request; + // copy-pasted from QFontDatabase::load(), to engineer the cache key + if (req.pixelSize == -1) { + req.pixelSize = std::floor(((req.pointSize * d->dpi) / 72) * 100 + 0.5) / 100; + req.pixelSize = qRound(req.pixelSize); + } + if (req.pointSize < 0) + req.pointSize = req.pixelSize*72.0/d->dpi; + + req.families = families; + + QFontEngineData *engineData = QFontCache::instance()->findEngineData(req); + + QCOMPARE(engineData, QFontPrivate::get(f)->engineData); +} + void tst_QFontCache::clear() { #ifdef QT_BUILD_INTERNAL diff --git a/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp b/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp index 3e354b7523..08f7cf4fb2 100644 --- a/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp +++ b/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp @@ -159,6 +159,7 @@ private slots: void nonZeroMarginOnImport(); void html_charFormatPropertiesUnset(); void html_headings(); + void html_quotedFontFamily_data(); void html_quotedFontFamily(); void html_spanBackgroundColor(); void defaultFont(); @@ -2184,23 +2185,45 @@ void tst_QTextDocumentFragment::html_headings() QCOMPARE(doc->blockCount(), 2); } +void tst_QTextDocumentFragment::html_quotedFontFamily_data() +{ + QTest::addColumn("html"); + QTest::addColumn("fontFamily"); + QTest::addColumn("fontFamilies"); + + const QString fooFamily = QLatin1String("Foo Bar"); + const QString weirdFamily = QLatin1String("'Weird, & font '' name',"); + + QTest::newRow("data1") << QString("
    Test
    ") + << fooFamily << QStringList(fooFamily); + QTest::newRow("data2") << QString("
    Test
    ") + << QString("Foo Bar") << QStringList("Foo Bar"); + QTest::newRow("data3") << QString("
    Test
    ") + << fooFamily << QStringList(fooFamily); + QTest::newRow("data4") << QString("
    Test" + "
    ") + << fooFamily << (QStringList() << "Foo Bar" << "serif" << "bar foo"); + QTest::newRow("data5") << QString("
    Test
    ") + << weirdFamily << QStringList(weirdFamily); + QTest::newRow("data6") << QString("
    Test
    ") + << weirdFamily << QStringList(weirdFamily); + QTest::newRow("data7") << QString("
    Test
    ") + << weirdFamily + << (QStringList() << weirdFamily << "serif" << "bar foo"); +} + void tst_QTextDocumentFragment::html_quotedFontFamily() { - setHtml("
    Test
    "); - QCOMPARE(doc->begin().begin().fragment().charFormat().fontFamily(), QString("Foo Bar")); - - setHtml("
    Test
    "); - QCOMPARE(doc->begin().begin().fragment().charFormat().fontFamily(), QString("Foo Bar")); - - setHtml("
    Test
    "); - QCOMPARE(doc->begin().begin().fragment().charFormat().fontFamily(), QString("Foo Bar")); - - setHtml("
    Test
    "); - QCOMPARE(doc->begin().begin().fragment().charFormat().fontFamily(), QString("Foo Bar")); - - setHtml("
    Test
    "); - QCOMPARE(doc->begin().begin().fragment().charFormat().fontFamily(), QString("Foo Bar,serif,bar foo")); + QFETCH(QString, html); + QFETCH(QString, fontFamily); + QFETCH(QStringList, fontFamilies); + setHtml(html); + QCOMPARE(doc->begin().begin().fragment().charFormat().fontFamily(), fontFamily); + QCOMPARE(doc->begin().begin().fragment().charFormat().font().families(), fontFamilies); } void tst_QTextDocumentFragment::defaultFont() From dec7961709c90f6977d2447f7fa6c6625af41cb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Tue, 6 Nov 2018 12:08:05 +0100 Subject: [PATCH 0245/1650] QSyntaxHighlighter: Delay all highlights until first rehighlight MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When calling setDocument (directly or through the constructor) a delayed rehighlight is initiated. Previously, if any text was changed before this rehighlight could run it would cancel the rehighlight, even if the changed text only caused a new block of text to be highlighted. Fixes: QTBUG-71307 Change-Id: Ib09b664d90906f5b4427105f0e45469806f3a779 Reviewed-by: Jędrzej Nowacki --- src/gui/text/qsyntaxhighlighter.cpp | 10 +++++----- .../qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/gui/text/qsyntaxhighlighter.cpp b/src/gui/text/qsyntaxhighlighter.cpp index fcda17605f..b09f8b565a 100644 --- a/src/gui/text/qsyntaxhighlighter.cpp +++ b/src/gui/text/qsyntaxhighlighter.cpp @@ -157,14 +157,12 @@ void QSyntaxHighlighterPrivate::applyFormatChanges() void QSyntaxHighlighterPrivate::_q_reformatBlocks(int from, int charsRemoved, int charsAdded) { - if (!inReformatBlocks) + if (!inReformatBlocks && !rehighlightPending) reformatBlocks(from, charsRemoved, charsAdded); } void QSyntaxHighlighterPrivate::reformatBlocks(int from, int charsRemoved, int charsAdded) { - rehighlightPending = false; - QTextBlock block = doc->findBlock(from); if (!block.isValid()) return; @@ -346,8 +344,10 @@ void QSyntaxHighlighter::setDocument(QTextDocument *doc) if (d->doc) { connect(d->doc, SIGNAL(contentsChange(int,int,int)), this, SLOT(_q_reformatBlocks(int,int,int))); - d->rehighlightPending = true; - QTimer::singleShot(0, this, SLOT(_q_delayedRehighlight())); + if (!d->doc->isEmpty()) { + d->rehighlightPending = true; + QTimer::singleShot(0, this, SLOT(_q_delayedRehighlight())); + } } } diff --git a/tests/auto/gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp b/tests/auto/gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp index 0a2e024701..9d6ce78b24 100644 --- a/tests/auto/gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp +++ b/tests/auto/gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp @@ -74,6 +74,7 @@ private slots: void emptyBlocks(); void setCharFormat(); void highlightOnInit(); + void highlightOnInitAndAppend(); void stopHighlightingWhenStateDoesNotChange(); void unindent(); void highlightToEndOfDocument(); @@ -265,6 +266,19 @@ void tst_QSyntaxHighlighter::highlightOnInit() QTRY_VERIFY(hl->highlighted); } +void tst_QSyntaxHighlighter::highlightOnInitAndAppend() +{ + cursor.insertText("Hello"); + cursor.insertBlock(); + cursor.insertText("World"); + + TestHighlighter *hl = new TestHighlighter(doc); + cursor.insertBlock(); + cursor.insertText("More text"); + QTRY_VERIFY(hl->highlighted); + QVERIFY(hl->highlightedText.endsWith(doc->toPlainText().remove(QLatin1Char('\n')))); +} + class StateTestHighlighter : public QSyntaxHighlighter { public: @@ -330,6 +344,7 @@ void tst_QSyntaxHighlighter::unindent() QCOMPARE(doc->toPlainText(), plainText); TestHighlighter *hl = new TestHighlighter(doc); + QTRY_VERIFY(hl->highlighted); hl->callCount = 0; cursor.movePosition(QTextCursor::Start); From 63967313f57add6517cdc50b8a77fa319a2b7df0 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sun, 4 Nov 2018 19:42:41 +0100 Subject: [PATCH 0246/1650] ItemWidgets: add helper function to retrieve the underlying model Add a new function to return the underlying model to avoid code duplication and make the code more readable. Also replace some 0 with nullptr. Change-Id: I1ca33de6f26b4e36f46ce7d2eacc45d0799478a3 Reviewed-by: Konstantin Shegunov Reviewed-by: Shawn Rutledge --- src/widgets/itemviews/qlistwidget.cpp | 49 ++++++++++------ src/widgets/itemviews/qlistwidget.h | 8 ++- src/widgets/itemviews/qtablewidget.cpp | 25 +++++--- src/widgets/itemviews/qtablewidget.h | 3 + src/widgets/itemviews/qtreewidget.cpp | 80 +++++++++++++++----------- src/widgets/itemviews/qtreewidget.h | 7 ++- 6 files changed, 105 insertions(+), 67 deletions(-) diff --git a/src/widgets/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp index 895622616e..6e0bdb3f22 100644 --- a/src/widgets/itemviews/qlistwidget.cpp +++ b/src/widgets/itemviews/qlistwidget.cpp @@ -634,14 +634,14 @@ Qt::DropActions QListModel::supportedDropActions() const \sa type() */ -QListWidgetItem::QListWidgetItem(QListWidget *view, int type) - : rtti(type), view(view), d(new QListWidgetItemPrivate(this)), +QListWidgetItem::QListWidgetItem(QListWidget *listview, int type) + : rtti(type), view(listview), d(new QListWidgetItemPrivate(this)), itemFlags(Qt::ItemIsSelectable |Qt::ItemIsUserCheckable |Qt::ItemIsEnabled |Qt::ItemIsDragEnabled) { - if (QListModel *model = (view ? qobject_cast(view->model()) : 0)) + if (QListModel *model = listModel()) model->insert(model->rowCount(), this); } @@ -661,16 +661,18 @@ QListWidgetItem::QListWidgetItem(QListWidget *view, int type) \sa type() */ -QListWidgetItem::QListWidgetItem(const QString &text, QListWidget *view, int type) - : rtti(type), view(0), d(new QListWidgetItemPrivate(this)), +QListWidgetItem::QListWidgetItem(const QString &text, QListWidget *listview, int type) + : rtti(type), view(listview), d(new QListWidgetItemPrivate(this)), itemFlags(Qt::ItemIsSelectable |Qt::ItemIsUserCheckable |Qt::ItemIsEnabled |Qt::ItemIsDragEnabled) { - setData(Qt::DisplayRole, text); - this->view = view; - if (QListModel *model = (view ? qobject_cast(view->model()) : 0)) + { + QSignalBlocker b(view); + setData(Qt::DisplayRole, text); + } + if (QListModel *model = listModel()) model->insert(model->rowCount(), this); } @@ -692,17 +694,19 @@ QListWidgetItem::QListWidgetItem(const QString &text, QListWidget *view, int typ \sa type() */ QListWidgetItem::QListWidgetItem(const QIcon &icon,const QString &text, - QListWidget *view, int type) - : rtti(type), view(0), d(new QListWidgetItemPrivate(this)), + QListWidget *listview, int type) + : rtti(type), view(listview), d(new QListWidgetItemPrivate(this)), itemFlags(Qt::ItemIsSelectable |Qt::ItemIsUserCheckable |Qt::ItemIsEnabled |Qt::ItemIsDragEnabled) { - setData(Qt::DisplayRole, text); - setData(Qt::DecorationRole, icon); - this->view = view; - if (QListModel *model = (view ? qobject_cast(view->model()) : 0)) + { + QSignalBlocker b(view); + setData(Qt::DisplayRole, text); + setData(Qt::DecorationRole, icon); + } + if (QListModel *model = listModel()) model->insert(model->rowCount(), this); } @@ -711,7 +715,7 @@ QListWidgetItem::QListWidgetItem(const QIcon &icon,const QString &text, */ QListWidgetItem::~QListWidgetItem() { - if (QListModel *model = (view ? qobject_cast(view->model()) : 0)) + if (QListModel *model = listModel()) model->remove(this); delete d; } @@ -748,7 +752,7 @@ void QListWidgetItem::setData(int role, const QVariant &value) } if (!found) d->values.append(QWidgetItemData(role, value)); - if (QListModel *model = (view ? qobject_cast(view->model()) : nullptr)) { + if (QListModel *model = listModel()) { const QVector roles((role == Qt::DisplayRole) ? QVector({Qt::DisplayRole, Qt::EditRole}) : QVector({role})); @@ -815,7 +819,7 @@ void QListWidgetItem::write(QDataStream &out) const \sa data(), flags() */ QListWidgetItem::QListWidgetItem(const QListWidgetItem &other) - : rtti(Type), view(0), + : rtti(Type), view(nullptr), d(new QListWidgetItemPrivate(this)), itemFlags(other.itemFlags) { @@ -837,6 +841,15 @@ QListWidgetItem &QListWidgetItem::operator=(const QListWidgetItem &other) return *this; } +/*! + \internal + returns the QListModel if a view is set + */ +QListModel *QListWidgetItem::listModel() const +{ + return (view ? qobject_cast(view->model()) : nullptr); +} + #ifndef QT_NO_DATASTREAM /*! @@ -998,7 +1011,7 @@ QDataStream &operator>>(QDataStream &in, QListWidgetItem &item) void QListWidgetItem::setFlags(Qt::ItemFlags aflags) { itemFlags = aflags; - if (QListModel *model = (view ? qobject_cast(view->model()) : 0)) + if (QListModel *model = listModel()) model->itemChanged(this); } diff --git a/src/widgets/itemviews/qlistwidget.h b/src/widgets/itemviews/qlistwidget.h index d3b27d201a..e96f639502 100644 --- a/src/widgets/itemviews/qlistwidget.h +++ b/src/widgets/itemviews/qlistwidget.h @@ -61,10 +61,10 @@ class Q_WIDGETS_EXPORT QListWidgetItem friend class QListWidget; public: enum ItemType { Type = 0, UserType = 1000 }; - explicit QListWidgetItem(QListWidget *view = nullptr, int type = Type); - explicit QListWidgetItem(const QString &text, QListWidget *view = nullptr, int type = Type); + explicit QListWidgetItem(QListWidget *listview = nullptr, int type = Type); + explicit QListWidgetItem(const QString &text, QListWidget *listview = nullptr, int type = Type); explicit QListWidgetItem(const QIcon &icon, const QString &text, - QListWidget *view = nullptr, int type = Type); + QListWidget *listview = nullptr, int type = Type); QListWidgetItem(const QListWidgetItem &other); virtual ~QListWidgetItem(); @@ -165,6 +165,8 @@ public: inline int type() const { return rtti; } +private: + QListModel *listModel() const; private: int rtti; QVector dummy; diff --git a/src/widgets/itemviews/qtablewidget.cpp b/src/widgets/itemviews/qtablewidget.cpp index 26006fc6c5..0916079cfc 100644 --- a/src/widgets/itemviews/qtablewidget.cpp +++ b/src/widgets/itemviews/qtablewidget.cpp @@ -1148,7 +1148,7 @@ void QTableWidgetItem::setSelected(bool select) void QTableWidgetItem::setFlags(Qt::ItemFlags aflags) { itemFlags = aflags; - if (QTableModel *model = (view ? qobject_cast(view->model()) : 0)) + if (QTableModel *model = tableModel()) model->itemChanged(this); } @@ -1339,7 +1339,7 @@ void QTableWidgetItem::setFlags(Qt::ItemFlags aflags) \sa type() */ QTableWidgetItem::QTableWidgetItem(int type) - : rtti(type), view(0), d(new QTableWidgetItemPrivate(this)), + : rtti(type), view(nullptr), d(new QTableWidgetItemPrivate(this)), itemFlags(Qt::ItemIsEditable |Qt::ItemIsSelectable |Qt::ItemIsUserCheckable @@ -1355,7 +1355,7 @@ QTableWidgetItem::QTableWidgetItem(int type) \sa type() */ QTableWidgetItem::QTableWidgetItem(const QString &text, int type) - : rtti(type), view(0), d(new QTableWidgetItemPrivate(this)), + : rtti(type), view(nullptr), d(new QTableWidgetItemPrivate(this)), itemFlags(Qt::ItemIsEditable |Qt::ItemIsSelectable |Qt::ItemIsUserCheckable @@ -1372,7 +1372,7 @@ QTableWidgetItem::QTableWidgetItem(const QString &text, int type) \sa type() */ QTableWidgetItem::QTableWidgetItem(const QIcon &icon, const QString &text, int type) - : rtti(type), view(0), d(new QTableWidgetItemPrivate(this)), + : rtti(type), view(nullptr), d(new QTableWidgetItemPrivate(this)), itemFlags(Qt::ItemIsEditable |Qt::ItemIsSelectable |Qt::ItemIsUserCheckable @@ -1389,9 +1389,8 @@ QTableWidgetItem::QTableWidgetItem(const QIcon &icon, const QString &text, int t */ QTableWidgetItem::~QTableWidgetItem() { - if (QTableModel *model = (view ? qobject_cast(view->model()) : 0)) + if (QTableModel *model = tableModel()) model->removeItem(this); - view = 0; delete d; } @@ -1427,7 +1426,7 @@ void QTableWidgetItem::setData(int role, const QVariant &value) } if (!found) values.append(QWidgetItemData(role, value)); - if (QTableModel *model = (view ? qobject_cast(view->model()) : nullptr)) + if (QTableModel *model = tableModel()) { const QVector roles((role == Qt::DisplayRole) ? QVector({Qt::DisplayRole, Qt::EditRole}) : @@ -1481,6 +1480,16 @@ void QTableWidgetItem::write(QDataStream &out) const out << values; } +/*! + \internal + returns the QTableModel if a view is set +*/ +QTableModel *QTableWidgetItem::tableModel() const +{ + return (view ? qobject_cast(view->model()) : nullptr); +} + + /*! \relates QTableWidgetItem @@ -1524,7 +1533,7 @@ QDataStream &operator<<(QDataStream &out, const QTableWidgetItem &item) \sa data(), flags() */ QTableWidgetItem::QTableWidgetItem(const QTableWidgetItem &other) - : rtti(Type), values(other.values), view(0), + : rtti(Type), values(other.values), view(nullptr), d(new QTableWidgetItemPrivate(this)), itemFlags(other.itemFlags) { diff --git a/src/widgets/itemviews/qtablewidget.h b/src/widgets/itemviews/qtablewidget.h index 2ddc24d30b..d93032f3f0 100644 --- a/src/widgets/itemviews/qtablewidget.h +++ b/src/widgets/itemviews/qtablewidget.h @@ -182,6 +182,9 @@ public: inline int type() const { return rtti; } +private: + QTableModel *tableModel() const; + private: int rtti; QVector values; diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp index 4768869843..fdca2b058b 100644 --- a/src/widgets/itemviews/qtreewidget.cpp +++ b/src/widgets/itemviews/qtreewidget.cpp @@ -1346,7 +1346,7 @@ bool QTreeWidgetItem::isHidden() const \sa type() */ QTreeWidgetItem::QTreeWidgetItem(int type) - : rtti(type), view(0), d(new QTreeWidgetItemPrivate(this)), par(0), + : rtti(type), view(nullptr), d(new QTreeWidgetItemPrivate(this)), par(nullptr), itemFlags(Qt::ItemIsSelectable |Qt::ItemIsUserCheckable |Qt::ItemIsEnabled @@ -1365,7 +1365,7 @@ QTreeWidgetItem::QTreeWidgetItem(int type) \sa type() */ QTreeWidgetItem::QTreeWidgetItem(const QStringList &strings, int type) - : rtti(type), view(0), d(new QTreeWidgetItemPrivate(this)), par(0), + : rtti(type), view(nullptr), d(new QTreeWidgetItemPrivate(this)), par(nullptr), itemFlags(Qt::ItemIsSelectable |Qt::ItemIsUserCheckable |Qt::ItemIsEnabled @@ -1385,16 +1385,16 @@ QTreeWidgetItem::QTreeWidgetItem(const QStringList &strings, int type) \sa type() */ -QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *view, int type) - : rtti(type), view(0), d(new QTreeWidgetItemPrivate(this)), par(0), +QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *treeview, int type) + : rtti(type), view(nullptr), d(new QTreeWidgetItemPrivate(this)), par(nullptr), itemFlags(Qt::ItemIsSelectable |Qt::ItemIsUserCheckable |Qt::ItemIsEnabled |Qt::ItemIsDragEnabled |Qt::ItemIsDropEnabled) { - if (view && view->model()) { - QTreeModel *model = qobject_cast(view->model()); + // do not set this->view here otherwise insertChild() will fail + if (QTreeModel *model = treeModel(treeview)) { model->rootItem->addChild(this); values.reserve(model->headerItem->columnCount()); } @@ -1410,8 +1410,8 @@ QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *view, int type) \sa type() */ -QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *view, const QStringList &strings, int type) - : rtti(type), view(0), d(new QTreeWidgetItemPrivate(this)), par(0), +QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *treeview, const QStringList &strings, int type) + : rtti(type), view(nullptr), d(new QTreeWidgetItemPrivate(this)), par(nullptr), itemFlags(Qt::ItemIsSelectable |Qt::ItemIsUserCheckable |Qt::ItemIsEnabled @@ -1420,8 +1420,8 @@ QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *view, const QStringList &strings, { for (int i = 0; i < strings.count(); ++i) setText(i, strings.at(i)); - if (view && view->model()) { - QTreeModel *model = qobject_cast(view->model()); + // do not set this->view here otherwise insertChild() will fail + if (QTreeModel *model = treeModel(treeview)) { model->rootItem->addChild(this); values.reserve(model->headerItem->columnCount()); } @@ -1435,21 +1435,19 @@ QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *view, const QStringList &strings, \sa type() */ -QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *view, QTreeWidgetItem *after, int type) - : rtti(type), view(0), d(new QTreeWidgetItemPrivate(this)), par(0), +QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *treeview, QTreeWidgetItem *after, int type) + : rtti(type), view(nullptr), d(new QTreeWidgetItemPrivate(this)), par(nullptr), itemFlags(Qt::ItemIsSelectable |Qt::ItemIsUserCheckable |Qt::ItemIsEnabled |Qt::ItemIsDragEnabled |Qt::ItemIsDropEnabled) { - if (view) { - QTreeModel *model = qobject_cast(view->model()); - if (model) { - int i = model->rootItem->children.indexOf(after) + 1; - model->rootItem->insertChild(i, this); - values.reserve(model->headerItem->columnCount()); - } + // do not set this->view here otherwise insertChild() will fail + if (QTreeModel *model = treeModel(treeview)) { + int i = model->rootItem->children.indexOf(after) + 1; + model->rootItem->insertChild(i, this); + values.reserve(model->headerItem->columnCount()); } } @@ -1459,7 +1457,7 @@ QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *view, QTreeWidgetItem *after, int \sa type() */ QTreeWidgetItem::QTreeWidgetItem(QTreeWidgetItem *parent, int type) - : rtti(type), view(0), d(new QTreeWidgetItemPrivate(this)), par(0), + : rtti(type), view(nullptr), d(new QTreeWidgetItemPrivate(this)), par(nullptr), itemFlags(Qt::ItemIsSelectable |Qt::ItemIsUserCheckable |Qt::ItemIsEnabled @@ -1477,7 +1475,7 @@ QTreeWidgetItem::QTreeWidgetItem(QTreeWidgetItem *parent, int type) \sa type() */ QTreeWidgetItem::QTreeWidgetItem(QTreeWidgetItem *parent, const QStringList &strings, int type) - : rtti(type), view(0), d(new QTreeWidgetItemPrivate(this)), par(0), + : rtti(type), view(nullptr), d(new QTreeWidgetItemPrivate(this)), par(nullptr), itemFlags(Qt::ItemIsSelectable |Qt::ItemIsUserCheckable |Qt::ItemIsEnabled @@ -1499,7 +1497,7 @@ QTreeWidgetItem::QTreeWidgetItem(QTreeWidgetItem *parent, const QStringList &str \sa type() */ QTreeWidgetItem::QTreeWidgetItem(QTreeWidgetItem *parent, QTreeWidgetItem *after, int type) - : rtti(type), view(0), d(new QTreeWidgetItemPrivate(this)), par(0), + : rtti(type), view(nullptr), d(new QTreeWidgetItemPrivate(this)), par(nullptr), itemFlags(Qt::ItemIsSelectable |Qt::ItemIsUserCheckable |Qt::ItemIsEnabled @@ -1522,7 +1520,7 @@ QTreeWidgetItem::QTreeWidgetItem(QTreeWidgetItem *parent, QTreeWidgetItem *after QTreeWidgetItem::~QTreeWidgetItem() { - QTreeModel *model = (view ? qobject_cast(view->model()) : 0); + QTreeModel *model = treeModel(); bool wasSkipSort = false; if (model) { wasSkipSort = model->skipPendingSort; @@ -1684,16 +1682,17 @@ void QTreeWidgetItem::setFlags(Qt::ItemFlags flags) void QTreeWidgetItemPrivate::updateHiddenStatus(QTreeWidgetItem *item, bool inserting) { - QTreeModel *model = (item->view ? qobject_cast(item->view->model()) : 0); + QTreeModel *model = item->treeModel(); if (!model) return; QStack parents; parents.push(item); while (!parents.isEmpty()) { QTreeWidgetItem *parent = parents.pop(); - QModelIndex index = model->index(parent, 0); - if (parent->d->hidden) + if (parent->d->hidden) { + const QModelIndex index = model->index(parent, 0); item->view->setRowHidden(index.row(), index.parent(), inserting); + } for (int i = 0; i < parent->children.count(); ++i) { QTreeWidgetItem *child = parent->children.at(i); parents.push(child); @@ -1758,7 +1757,7 @@ void QTreeWidgetItem::setData(int column, int role, const QVariant &value) if (column < 0) return; - QTreeModel *model = (view ? qobject_cast(view->model()) : 0); + QTreeModel *model = treeModel(); switch (role) { case Qt::EditRole: case Qt::DisplayRole: { @@ -1966,7 +1965,7 @@ void QTreeWidgetItem::insertChild(int index, QTreeWidgetItem *child) if (index < 0 || index > children.count() || child == 0 || child->view != 0 || child->par != 0) return; - if (QTreeModel *model = (view ? qobject_cast(view->model()) : 0)) { + if (QTreeModel *model = treeModel()) { const bool wasSkipSort = model->skipPendingSort; model->skipPendingSort = true; if (model->rootItem == this) @@ -2017,7 +2016,7 @@ QTreeWidgetItem *QTreeWidgetItem::takeChild(int index) { // we move this outside the check of the index to allow executing // pending sorts from inline functions, using this function (hack) - QTreeModel *model = (view ? qobject_cast(view->model()) : 0); + QTreeModel *model = treeModel(); if (model) { // This will trigger a layoutChanged signal, thus we might want to optimize // this function by not emitting the rowsRemoved signal etc to the view. @@ -2075,7 +2074,7 @@ void QTreeWidgetItem::insertChildren(int index, const QList &c insertChild(index, children.at(n)); return; } - QTreeModel *model = (view ? qobject_cast(view->model()) : 0); + QTreeModel *model = treeModel(); QStack stack; QList itemsToInsert; for (int n = 0; n < children.count(); ++n) { @@ -2122,7 +2121,7 @@ QList QTreeWidgetItem::takeChildren() { QList removed; if (children.count() > 0) { - QTreeModel *model = (view ? qobject_cast(view->model()) : 0); + QTreeModel *model = treeModel(); if (model) { // This will trigger a layoutChanged signal, thus we might want to optimize // this function by not emitting the rowsRemoved signal etc to the view. @@ -2154,7 +2153,7 @@ QList QTreeWidgetItem::takeChildren() void QTreeWidgetItemPrivate::sortChildren(int column, Qt::SortOrder order, bool climb) { - QTreeModel *model = (q->view ? qobject_cast(q->view->model()) : 0); + QTreeModel *model = q->treeModel(); if (!model) return; model->sortItems(&q->children, column, order); @@ -2177,7 +2176,7 @@ void QTreeWidgetItemPrivate::sortChildren(int column, Qt::SortOrder order, bool */ void QTreeWidgetItem::sortChildren(int column, Qt::SortOrder order, bool climb) { - QTreeModel *model = (view ? qobject_cast(view->model()) : 0); + QTreeModel *model = treeModel(); if (!model) return; if (model->isChanging()) @@ -2257,7 +2256,7 @@ void QTreeWidgetItem::emitDataChanged() */ void QTreeWidgetItem::itemChanged() { - if (QTreeModel *model = (view ? qobject_cast(view->model()) : 0)) + if (QTreeModel *model = treeModel()) model->itemChanged(this); } @@ -2266,10 +2265,21 @@ void QTreeWidgetItem::itemChanged() */ void QTreeWidgetItem::executePendingSort() const { - if (QTreeModel *model = (view ? qobject_cast(view->model()) : 0)) + if (QTreeModel *model = treeModel()) model->executePendingSort(); } +/*! + \internal + returns the QTreeModel if a view is set +*/ +QTreeModel *QTreeWidgetItem::treeModel(QTreeWidget *v) const +{ + if (!v) + v = view; + return (v ? qobject_cast(v->model()) : nullptr); +} + #ifndef QT_NO_DATASTREAM /*! diff --git a/src/widgets/itemviews/qtreewidget.h b/src/widgets/itemviews/qtreewidget.h index 5044ec9e02..c9186de90c 100644 --- a/src/widgets/itemviews/qtreewidget.h +++ b/src/widgets/itemviews/qtreewidget.h @@ -66,9 +66,9 @@ public: enum ItemType { Type = 0, UserType = 1000 }; explicit QTreeWidgetItem(int type = Type); explicit QTreeWidgetItem(const QStringList &strings, int type = Type); - explicit QTreeWidgetItem(QTreeWidget *view, int type = Type); - QTreeWidgetItem(QTreeWidget *view, const QStringList &strings, int type = Type); - QTreeWidgetItem(QTreeWidget *view, QTreeWidgetItem *after, int type = Type); + explicit QTreeWidgetItem(QTreeWidget *treeview, int type = Type); + QTreeWidgetItem(QTreeWidget *treeview, const QStringList &strings, int type = Type); + QTreeWidgetItem(QTreeWidget *treeview, QTreeWidgetItem *after, int type = Type); explicit QTreeWidgetItem(QTreeWidgetItem *parent, int type = Type); QTreeWidgetItem(QTreeWidgetItem *parent, const QStringList &strings, int type = Type); QTreeWidgetItem(QTreeWidgetItem *parent, QTreeWidgetItem *after, int type = Type); @@ -215,6 +215,7 @@ private: QVariant childrenCheckState(int column) const; void itemChanged(); void executePendingSort() const; + QTreeModel *treeModel(QTreeWidget *v = nullptr) const; int rtti; // One item has a vector of column entries. Each column has a vector of (role, value) pairs. From 8713f22372b7aa63ecafbe87214b8994203fac5f Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sun, 4 Nov 2018 18:43:00 +0100 Subject: [PATCH 0247/1650] QHeaderView: Fix updating hidden sections during initializeSections() QHeaderView::initializeSections() was calling updateHiddenSections() with wrong parameters which lead to an inconsistency in the hidden section handling. updateHiddenSections() needs the first and last index which got removed. Therefore we must pass the new section count for logicalFirst. Fixes: QTBUG-55461 Change-Id: Ica06125cf19bdd500f55fd9cd59ace1795f3703f Reviewed-by: David Faure --- src/widgets/itemviews/qheaderview.cpp | 5 +- .../itemviews/qheaderview/tst_qheaderview.cpp | 55 ++++++++++++++++--- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index b7de69d63a..e9091ca1a2 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -2321,9 +2321,10 @@ void QHeaderView::initializeSections() if (stretchLastSection()) // we've already gotten the size hint d->maybeRestorePrevLastSectionAndStretchLast(); - //make sure we update the hidden sections + // make sure we update the hidden sections + // simulate remove from newCount to oldCount if (newCount < oldCount) - d->updateHiddenSections(0, newCount-1); + d->updateHiddenSections(newCount, oldCount); } } diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp index b6932d4892..9d3770064f 100644 --- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp +++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp @@ -253,11 +253,12 @@ protected: void calculateAndCheck(int cppline, const int precalced_comparedata[]); void testMinMaxSectionSize(bool stretchLastSection); - QWidget *topLevel; - QHeaderView *view; - QStandardItemModel *model; - QTableView *m_tableview; - bool m_using_reset_model; + QWidget *topLevel = nullptr; + QHeaderView *view = nullptr; + QStandardItemModel *model = nullptr; + QTableView *m_tableview = nullptr; + bool m_using_reset_model = false; + bool m_special_prepare = false; QElapsedTimer timer; }; @@ -614,6 +615,27 @@ void tst_QHeaderView::hidden() view->setSectionHidden(1, false); QCOMPARE(view->isSectionHidden(0), false); QCOMPARE(view->sectionSize(0), view->defaultSectionSize()); + + // d->hiddenSectionSize could go out of sync when a new model + // was set which has fewer sections than before and some of them + // were hidden + QStandardItemModel model2(model->rowCount() - 1, model->columnCount()); + + for (int i = 0; i < model->rowCount(); ++i) + view->setSectionHidden(i, true); + view->setModel(&model2); + QVERIFY(view->sectionsHidden()); + for (int i = 0; i < model2.rowCount(); ++i) { + QVERIFY(view->isSectionHidden(i)); + } + + view->setModel(model); + for (int i = 0; i < model2.rowCount(); ++i) { + QVERIFY(view->isSectionHidden(i)); + } + QCOMPARE(view->isSectionHidden(model->rowCount() - 1), false); + for (int i = 0; i < model->rowCount(); ++i) + view->setSectionHidden(i, false); } void tst_QHeaderView::stretch() @@ -2822,6 +2844,7 @@ void tst_QHeaderView::additionalInit() QFETCH(bool, reset_model); m_using_reset_model = reset_model; + m_special_prepare = special_prepare; if (m_using_reset_model) { XResetModel *m = new XResetModel(); @@ -3035,18 +3058,34 @@ void tst_QHeaderView::mixedTests() view->moveSection(0, 5); for (int u = model->rowCount(); u >= 0; --u) { - if (u % 5 != 0) + if (u % 5 != 0) { view->hideSection(u); - if (u % 3 != 0) + QVERIFY(view->isSectionHidden(u)); + } + if (u % 3 != 0) { view->showSection(u); + QVERIFY(!view->isSectionHidden(u)); + } } model->insertRows(3, 7); model->removeRows(8, 3); model->setRowCount(model->rowCount() - 10); + // the upper is not visible (when m_using_reset_model is true) + // the lower 11 are modified due to insert/removeRows + for (int u = model->rowCount() - 1; u >= 11; --u) { + // when using reset, the hidden rows will *not* move + const int calcMod = m_using_reset_model ? u : u - 4; // 7 added, 3 removed + if (calcMod % 5 != 0 && calcMod % 3 == 0) { + QVERIFY(view->isSectionHidden(u)); + } + if (calcMod % 3 != 0) { + QVERIFY(!view->isSectionHidden(u)); + } + } if (m_using_reset_model) { - const int precalced_results[] = { 898296472, 337096378, -543340640, 1, -1251526424, -568618976, 9250 }; + const int precalced_results[] = { 898296472, 337096378, -543340640, -1964432121, -1251526424, -568618976, 9250 }; calculateAndCheck(__LINE__, precalced_results); } else { const int precalced_results[] = { 1911338224, 1693514365, -613398968, -1912534953, 1582159424, -1851079000, 9300 }; From 5668e059f2ffcf12b4171ea54ff016689ff91239 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Sun, 28 Oct 2018 10:10:11 +0100 Subject: [PATCH 0248/1650] Make QAbstractItemModel::resetInternalData virtual for Qt 6 Change-Id: I9cfeb93addb717abc187a8dab8d24076f68bd61d Reviewed-by: David Faure Reviewed-by: Luca Beldi Reviewed-by: Shawn Rutledge --- src/corelib/itemmodels/qabstractitemmodel.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/corelib/itemmodels/qabstractitemmodel.h b/src/corelib/itemmodels/qabstractitemmodel.h index 0aa75d6ff7..c34876d1d6 100644 --- a/src/corelib/itemmodels/qabstractitemmodel.h +++ b/src/corelib/itemmodels/qabstractitemmodel.h @@ -302,7 +302,9 @@ public Q_SLOTS: virtual void revert(); protected Q_SLOTS: - // Qt 6: Make virtual +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + virtual +#endif void resetInternalData(); protected: From b53f997d8f20938d46b755eca54b4ec9a40e4ffe Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sat, 20 Oct 2018 21:23:04 +0200 Subject: [PATCH 0249/1650] QHeaderView: check for changed roles in dataChanged() QHeaderView::dataChanged() did not check for the modified roles which lead to unneeded size calculations even if the size did not change. Avoid it by only looking at the relevant roles (DisplayRole, DecorationRole, SizeHintRole and FontRole). [ChangeLog][QtWidgets][QHeaderView] dataChanged now respects the given roles to avoid useless recomputations Fixes: QTBUG-71172 Change-Id: I0de53897347a72bddc425ae1fae8f2560ad0e977 Reviewed-by: David Faure --- src/widgets/itemviews/qheaderview.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index e9091ca1a2..62abf56751 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -3117,9 +3117,25 @@ void QHeaderView::scrollContentsBy(int dx, int dy) \reimp \internal */ -void QHeaderView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &) +void QHeaderView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles) { Q_D(QHeaderView); + if (!roles.isEmpty()) { + const auto doesRoleAffectSize = [](int role) -> bool { + switch (role) { + case Qt::DisplayRole: + case Qt::DecorationRole: + case Qt::SizeHintRole: + case Qt::FontRole: + return true; + default: + // who knows what a subclass or custom style might do + return role >= Qt::UserRole; + } + }; + if (std::none_of(roles.begin(), roles.end(), doesRoleAffectSize)) + return; + } d->invalidateCachedSizeHint(); if (d->hasAutoResizeSections()) { bool resizeRequired = d->globalResizeMode == ResizeToContents; From c99544a474cd8b651e29702ff10dee908463daf5 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Fri, 2 Nov 2018 10:24:23 +0100 Subject: [PATCH 0250/1650] benchmarks: Fix copy and paste error in .pro-file Change-Id: I30e4c640b9299559063b0337b6639d7c5a19e1db Reviewed-by: Mikhail Svetkin Reviewed-by: Simon Hausmann --- tests/benchmarks/corelib/io/qtextstream/qtextstream.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/benchmarks/corelib/io/qtextstream/qtextstream.pro b/tests/benchmarks/corelib/io/qtextstream/qtextstream.pro index 758930c139..e8170319f2 100644 --- a/tests/benchmarks/corelib/io/qtextstream/qtextstream.pro +++ b/tests/benchmarks/corelib/io/qtextstream/qtextstream.pro @@ -1,5 +1,5 @@ TEMPLATE = app -TARGET = tst_bench_qtemporaryfile +TARGET = tst_bench_qtextstream QT = core testlib From 757d4b85a91643c289d3224082b48b4835868104 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Fri, 2 Nov 2018 10:27:09 +0100 Subject: [PATCH 0251/1650] Benchmark: Add _bench_ into the name of the qmap benchmark Change-Id: I6a1790981eb56d56bc190634e796bc3736ddd475 Reviewed-by: Simon Hausmann --- tests/benchmarks/corelib/tools/qmap/qmap.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/benchmarks/corelib/tools/qmap/qmap.pro b/tests/benchmarks/corelib/tools/qmap/qmap.pro index 6a0c8d62bd..6c9bf5e8d6 100644 --- a/tests/benchmarks/corelib/tools/qmap/qmap.pro +++ b/tests/benchmarks/corelib/tools/qmap/qmap.pro @@ -1,4 +1,4 @@ -TARGET = tst_qmap +TARGET = tst_bench_qmap QT = core testlib INCLUDEPATH += . SOURCES += main.cpp From 9137691e745039f8ad9cdee2594a958e244ba341 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 5 Nov 2018 10:18:50 +0100 Subject: [PATCH 0252/1650] Windows QPA: Fix crash showing QSystemTrayIcon's context menu with PROCESS_DPI_UNAWARE The coordinates of the WM_CONTEXT message may be out of any screen in PROCESS_DPI_UNAWARE mode since hi-res coordinates are delivered in this case (Windows issue). Default to primary screen with check to prevent a crash. Fixes: QTBUG-67966 Change-Id: I1950360520e93cbf3509611b3057635769f6543a Reviewed-by: Andre de la Rocha --- .../windows/qwindowssystemtrayicon.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp b/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp index 901d132ea5..3c27f2914d 100644 --- a/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp +++ b/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp @@ -382,12 +382,20 @@ bool QWindowsSystemTrayIcon::winEvent(const MSG &message, long *result) emit activated(DoubleClick); // release we must ignore it break; case WM_CONTEXTMENU: { + // QTBUG-67966: Coordinates may be out of any screen in PROCESS_DPI_UNAWARE mode + // since hi-res coordinates are delivered in this case (Windows issue). + // Default to primary screen with check to prevent a crash. const QPoint globalPos = QPoint(GET_X_LPARAM(message.wParam), GET_Y_LPARAM(message.wParam)); - const QPlatformScreen *screen = QWindowsContext::instance()->screenManager().screenAtDp(globalPos); - emit contextMenuRequested(globalPos, screen); - emit activated(Context); - if (m_menu) - m_menu->trackPopupMenu(message.hwnd, globalPos.x(), globalPos.y()); + const auto &screenManager = QWindowsContext::instance()->screenManager(); + const QPlatformScreen *screen = screenManager.screenAtDp(globalPos); + if (!screen) + screen = screenManager.screens().value(0); + if (screen) { + emit contextMenuRequested(globalPos, screen); + emit activated(Context); + if (m_menu) + m_menu->trackPopupMenu(message.hwnd, globalPos.x(), globalPos.y()); + } } break; case NIN_BALLOONUSERCLICK: From d0e66df1a561cfe3f43879f37a7a3b5a477bd3f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 8 Nov 2018 15:22:00 +0100 Subject: [PATCH 0253/1650] macOS: Skip tst_QGLThreads::renderInThread MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It crashes in the render thread: thread #7, name = 'SceneRenderingThread' frame #0: libsystem_kernel.dylib`__wait4_nocancel + 10 frame #1: libsystem_c.dylib`system + 452 frame #2: QtTest`stackTrace() + 325 frame #3: QtTest`QTest::FatalSignalHandler::signal(int) + 207 frame #4: libsystem_platform.dylib`_sigtramp + 26 frame #5: libsystem_platform.dylib`_platform_bzero$VARIANT$Base + 23 frame #6: GLRendererFloat`gldSetZero + 63 frame #7: GLRendererFloat`gldClearDrawBuffer + 3792 frame #8: GLRendererFloat`gldClearFramebufferData + 49 frame #9: GLEngine`glClear_Exec + 541 frame #10: tst_qglthreads`SceneRenderingThread::run() + 227 Task-number: QTBUG-68524 Change-Id: I6bc67cb342f77dc1a590a25af535f9bb7f0d325a Reviewed-by: Morten Johan Sørvig --- tests/auto/opengl/qglthreads/tst_qglthreads.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/auto/opengl/qglthreads/tst_qglthreads.cpp b/tests/auto/opengl/qglthreads/tst_qglthreads.cpp index 09bea20d26..b7b5b505a0 100644 --- a/tests/auto/opengl/qglthreads/tst_qglthreads.cpp +++ b/tests/auto/opengl/qglthreads/tst_qglthreads.cpp @@ -355,6 +355,11 @@ void tst_QGLThreads::renderInThread() QFETCH(bool, resize); QFETCH(bool, update); +#if defined(Q_OS_MACOS) + if (resize) + QSKIP("gldSetZero crashes in render thread, QTBUG-68524"); +#endif + ThreadSafeGLWidget widget; widget.resize(200, 200); SceneRenderingThread thread(&widget); From 2697148775703883ae700b15d4efe240050273a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 22 Oct 2018 13:04:42 +0200 Subject: [PATCH 0254/1650] macOS: Only enable layer-backed views on 10.14 if built against 10.14 SDK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of explicitly enabling layer-backing for Qt 5.12 on all macOS version, we follow the macOS default to enable it for 10.14 if the application binary was built against the 10.14 SDK. Aligning ourselves with Apple's switch to forced layer-backing means we have an easier story when it comes to supporting different runtime configurations. Fixes: QTBUG-71499 Change-Id: I34ee49b3daeb6ed8df444a3759d3573ebc9ea30f Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qnsview.mm | 15 +---- .../platforms/cocoa/qnsview_drawing.mm | 65 +++++++++++++++---- 2 files changed, 55 insertions(+), 25 deletions(-) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 9bd53ed334..540f701d43 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -71,7 +71,7 @@ @end @interface QT_MANGLE_NAMESPACE(QNSView) (Drawing) -- (BOOL)wantsLayerHelper; +- (void)initDrawing; @end @interface QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) : NSObject @@ -152,19 +152,8 @@ self.focusRingType = NSFocusRingTypeNone; self.cursor = nil; - self.wantsLayer = [self wantsLayerHelper]; - - // Enable high-DPI OpenGL for retina displays. Enabling has the side - // effect that Cocoa will start calling glViewport(0, 0, width, height), - // overriding any glViewport calls in application code. This is usually not a - // problem, except if the application wants to have a "custom" viewport. - // (like the hellogl example) - if (m_platformWindow->window()->supportsOpenGL()) { - self.wantsBestResolutionOpenGLSurface = qt_mac_resolveOption(YES, m_platformWindow->window(), - "_q_mac_wantsBestResolutionOpenGLSurface", "QT_MAC_WANTS_BEST_RESOLUTION_OPENGL_SURFACE"); - // See also QCocoaGLContext::makeCurrent for software renderer workarounds. - } + [self initDrawing]; [self registerDragTypes]; [[NSNotificationCenter defaultCenter] addObserver:self diff --git a/src/plugins/platforms/cocoa/qnsview_drawing.mm b/src/plugins/platforms/cocoa/qnsview_drawing.mm index 4f9d17504d..e9af90a45c 100644 --- a/src/plugins/platforms/cocoa/qnsview_drawing.mm +++ b/src/plugins/platforms/cocoa/qnsview_drawing.mm @@ -41,6 +41,24 @@ @implementation QT_MANGLE_NAMESPACE(QNSView) (Drawing) +- (void)initDrawing +{ + self.wantsLayer = [self layerExplicitlyRequested] + || [self shouldUseMetalLayer] + || [self layerEnabledByMacOS]; + + // Enable high-DPI OpenGL for retina displays. Enabling has the side + // effect that Cocoa will start calling glViewport(0, 0, width, height), + // overriding any glViewport calls in application code. This is usually not a + // problem, except if the application wants to have a "custom" viewport. + // (like the hellogl example) + if (m_platformWindow->window()->supportsOpenGL()) { + self.wantsBestResolutionOpenGLSurface = qt_mac_resolveOption(YES, m_platformWindow->window(), + "_q_mac_wantsBestResolutionOpenGLSurface", "QT_MAC_WANTS_BEST_RESOLUTION_OPENGL_SURFACE"); + // See also QCocoaGLContext::makeCurrent for software renderer workarounds. + } +} + - (BOOL)isOpaque { if (!m_platformWindow) @@ -71,6 +89,33 @@ m_platformWindow->handleExposeEvent(exposedRegion); } +- (BOOL)layerEnabledByMacOS +{ + // AppKit has its own logic for this, but if we rely on that, our layers are created + // by AppKit at a point where we've already set up other parts of the platform plugin + // based on the presence of layers or not. Once we've rewritten these parts to support + // dynamically picking up layer enablement we can let AppKit do its thing. + return QMacVersion::buildSDK() >= QOperatingSystemVersion::MacOSMojave + && QMacVersion::currentRuntime() >= QOperatingSystemVersion::MacOSMojave; +} + +- (BOOL)layerExplicitlyRequested +{ + static bool wantsLayer = [&]() { + int wantsLayer = qt_mac_resolveOption(-1, m_platformWindow->window(), + "_q_mac_wantsLayer", "QT_MAC_WANTS_LAYER"); + + if (wantsLayer != -1 && [self layerEnabledByMacOS]) { + qCWarning(lcQpaDrawing) << "Layer-backing can not be explicitly controlled on 10.14 when built against the 10.14 SDK"; + return true; + } + + return wantsLayer == 1; + }(); + + return wantsLayer; +} + - (BOOL)shouldUseMetalLayer { // MetalSurface needs a layer, and so does VulkanSurface (via MoltenVK) @@ -78,18 +123,6 @@ return surfaceType == QWindow::MetalSurface || surfaceType == QWindow::VulkanSurface; } -- (BOOL)wantsLayerHelper -{ - Q_ASSERT(m_platformWindow); - - bool wantsLayer = qt_mac_resolveOption(true, m_platformWindow->window(), - "_q_mac_wantsLayer", "QT_MAC_WANTS_LAYER"); - - bool layerForSurfaceType = [self shouldUseMetalLayer]; - - return wantsLayer || layerForSurfaceType; -} - - (CALayer *)makeBackingLayer { if ([self shouldUseMetalLayer]) { @@ -115,6 +148,14 @@ return [super makeBackingLayer]; } +- (void)setLayer:(CALayer *)layer +{ + qCDebug(lcQpaDrawing) << "Making" << self << "layer-backed with" << layer + << "due to being" << ([self layerExplicitlyRequested] ? "explicitly requested" + : [self shouldUseMetalLayer] ? "needed by surface type" : "enabled by macOS"); + [super setLayer:layer]; +} + - (NSViewLayerContentsRedrawPolicy)layerContentsRedrawPolicy { // We need to set this explicitly since the super implementation From 7a4ebf1b714956c7a8b676d83ea8461b2cdc0db3 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Tue, 9 Oct 2018 16:42:03 +0200 Subject: [PATCH 0255/1650] Painting: Fix capping of polylines having endpoint == startpoint A polyline should not be closed like a polygon, even if the start and end points are identical. But when the primitive was broken down to a vector path, the stroker no longer had available the information that it should be open, and so would join the start and end points. Fixes: QTBUG-65393 Change-Id: I0a566f91cf1a2843fda662b393dbae78c3c38f06 Reviewed-by: Lars Knoll --- src/gui/painting/qpaintengineex.cpp | 3 +++ src/gui/painting/qstroker.cpp | 5 +++-- src/gui/painting/qstroker_p.h | 5 +++++ src/gui/painting/qvectorpath_p.h | 6 ++++-- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 9f07af92e4..81ce5c60c5 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -439,6 +439,9 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) } } + if (d->activeStroker == &d->stroker) + d->stroker.setForceOpen(path.hasExplicitOpen()); + const QPainterPath::ElementType *types = path.elements(); const qreal *points = path.points(); int pointCount = path.elementCount(); diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp index 4776545be6..0a3d802b21 100644 --- a/src/gui/painting/qstroker.cpp +++ b/src/gui/painting/qstroker.cpp @@ -369,7 +369,8 @@ void QStrokerOps::strokeEllipse(const QRectF &rect, void *data, const QTransform QStroker::QStroker() : m_capStyle(SquareJoin), m_joinStyle(FlatJoin), m_back1X(0), m_back1Y(0), - m_back2X(0), m_back2Y(0) + m_back2X(0), m_back2Y(0), + m_forceOpen(false) { m_strokeWidth = qt_real_to_fixed(1); m_miterLimit = qt_real_to_fixed(2); @@ -748,7 +749,7 @@ template bool qt_stroke_side(Iterator *it, } } - if (start == prev) { + if (start == prev && !stroker->forceOpen()) { // closed subpath, join first and last point #ifdef QPP_STROKE_DEBUG qDebug("\n ---> (side) closed subpath"); diff --git a/src/gui/painting/qstroker_p.h b/src/gui/painting/qstroker_p.h index 1a7c184e1a..722a0904f3 100644 --- a/src/gui/painting/qstroker_p.h +++ b/src/gui/painting/qstroker_p.h @@ -222,6 +222,9 @@ public: void setMiterLimit(qfixed length) { m_miterLimit = length; } qfixed miterLimit() const { return m_miterLimit; } + void setForceOpen(bool state) { m_forceOpen = state; } + bool forceOpen() { return m_forceOpen; } + void joinPoints(qfixed x, qfixed y, const QLineF &nextLine, LineJoinMode join); inline void emitMoveTo(qfixed x, qfixed y); inline void emitLineTo(qfixed x, qfixed y); @@ -247,6 +250,8 @@ protected: qfixed m_back2X; qfixed m_back2Y; + + bool m_forceOpen; }; class Q_GUI_EXPORT QDashStroker : public QStrokerOps diff --git a/src/gui/painting/qvectorpath_p.h b/src/gui/painting/qvectorpath_p.h index d1b08ed423..8580598784 100644 --- a/src/gui/painting/qvectorpath_p.h +++ b/src/gui/painting/qvectorpath_p.h @@ -99,7 +99,8 @@ public: // Shape rendering specifiers... OddEvenFill = 0x1000, WindingFill = 0x2000, - ImplicitClose = 0x4000 + ImplicitClose = 0x4000, + ExplicitOpen = 0x8000 }; // ### Falcon: introduca a struct XY for points so lars is not so confused... @@ -124,6 +125,7 @@ public: inline bool isCacheable() const { return m_hints & ShouldUseCacheHint; } inline bool hasImplicitClose() const { return m_hints & ImplicitClose; } + inline bool hasExplicitOpen() const { return m_hints & ExplicitOpen; } inline bool hasWindingFill() const { return m_hints & WindingFill; } inline void makeCacheable() const { m_hints |= ShouldUseCacheHint; m_cache = 0; } @@ -142,7 +144,7 @@ public: case QPaintEngine::ConvexMode: return ConvexPolygonHint | ImplicitClose; case QPaintEngine::OddEvenMode: return PolygonHint | OddEvenFill | ImplicitClose; case QPaintEngine::WindingMode: return PolygonHint | WindingFill | ImplicitClose; - case QPaintEngine::PolylineMode: return PolygonHint; + case QPaintEngine::PolylineMode: return PolygonHint | ExplicitOpen; default: return 0; } } From 0dae641331bbd21207f6c74a7a34e0c74103d61e Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 8 Nov 2018 15:53:40 +0100 Subject: [PATCH 0256/1650] QAbstractSocket::Bind: clarify some details The function's documentation needlessly repeated parts of its first line. The BindFlag enum it takes as a parameter confused readers by saying an option is ignored on Windows, failing to make clear that it is so because that option is what Windows does by default. Tidied some phrasing and typos in the process. Fixes: QTBUG-52364 Change-Id: Ia6510caff7ec80216eefccf41fb009b1357e4b2e Reviewed-by: Andy Shaw Reviewed-by: Paul Wicking --- src/network/socket/qabstractsocket.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 13e10e4102..a33dcb5955 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -424,7 +424,7 @@ Note that by combining this option with ReuseAddressHint, you will also allow your service to rebind an existing shared address. On Unix, this is equivalent to the SO_REUSEADDR socket option. On Windows, - this option is ignored. + this is the default behavior, so this option is ignored. \value DontShareAddress Bind the address and port exclusively, so that no other services are allowed to rebind. By passing this option to @@ -444,7 +444,7 @@ \value DefaultForPlatform The default option for the current platform. On Unix and \macos, this is equivalent to (DontShareAddress - + ReuseAddressHint), and on Windows, its equivalent to ShareAddress. + + ReuseAddressHint), and on Windows, it is equivalent to ShareAddress. */ /*! \enum QAbstractSocket::PauseMode @@ -455,7 +455,7 @@ The only notification currently supported is QSslSocket::sslErrors(). \value PauseNever Do not pause data transfer on the socket. This is the - default and matches the behaviour of Qt 4. + default and matches the behavior of Qt 4. \value PauseOnSslErrors Pause data transfer on the socket upon receiving an SSL error notification. I.E. QSslSocket::sslErrors(). */ @@ -1538,11 +1538,9 @@ void QAbstractSocket::setPauseMode(PauseModes pauseMode) Binds to \a address on port \a port, using the BindMode \a mode. - Binds this socket to the address \a address and the port \a port. - For UDP sockets, after binding, the signal QUdpSocket::readyRead() is emitted whenever a UDP datagram arrives on the specified address and port. - Thus, This function is useful to write UDP servers. + Thus, this function is useful to write UDP servers. For TCP sockets, this function may be used to specify which interface to use for an outgoing connection, which is useful in case of multiple network From 76bb804405f424708fffec502788995ea91206b8 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Wed, 31 Oct 2018 22:10:35 +0100 Subject: [PATCH 0257/1650] QTreeWidget: mark (is|set)Item(Selected|Hidden|Expanded) as deprecated QTreeWidget::(is|set)Item(Selected|Hidden|Expanded)() are deprecated for a long time but not marked as such. Therefore explicitly mark them as deprecated so they can get removed with Qt6. Change-Id: Ie4971350de61326811e0788df0d359ed3c442869 Reviewed-by: Konstantin Shegunov Reviewed-by: Richard Moe Gustavsen --- .../snippets/qtreewidget-using/mainwindow.cpp | 4 +- src/widgets/itemviews/qtreewidget.cpp | 106 +++++++++++------- src/widgets/itemviews/qtreewidget.h | 30 +++-- .../tst_qabstractitemmodeltester.cpp | 2 +- .../itemviews/qtreewidget/tst_qtreewidget.cpp | 88 ++++++++------- .../tst_qtreewidgetitemiterator.cpp | 16 +-- 6 files changed, 134 insertions(+), 112 deletions(-) diff --git a/src/widgets/doc/snippets/qtreewidget-using/mainwindow.cpp b/src/widgets/doc/snippets/qtreewidget-using/mainwindow.cpp index ee7e028a13..7c8d3f936e 100644 --- a/src/widgets/doc/snippets/qtreewidget-using/mainwindow.cpp +++ b/src/widgets/doc/snippets/qtreewidget-using/mainwindow.cpp @@ -154,14 +154,14 @@ void MainWindow::findItems() QTreeWidgetItem *item; //! [6] foreach (item, treeWidget->selectedItems()) - treeWidget->setItemSelected(item, false); + item->setSelected(false); //! [7] QList found = treeWidget->findItems( itemText, Qt::MatchWildcard); foreach (item, found) { - treeWidget->setItemSelected(item, true); + item->setSelected(true); // Show the item->text(0) for each item. } //! [7] diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp index fdca2b058b..acd6ad6e41 100644 --- a/src/widgets/itemviews/qtreewidget.cpp +++ b/src/widgets/itemviews/qtreewidget.cpp @@ -1009,8 +1009,18 @@ void QTreeModel::timerEvent(QTimerEvent *ev) Sets the selected state of the item to \a select. \sa isSelected() - */ +void QTreeWidgetItem::setSelected(bool select) +{ + const QTreeModel *model = treeModel(); + if (!model || !view->selectionModel()) + return; + const QModelIndex index = model->index(this, 0); + view->selectionModel()->select(index, (select ? QItemSelectionModel::Select + : QItemSelectionModel::Deselect) + | QItemSelectionModel::Rows); + d->selected = select; +} /*! \fn bool QTreeWidgetItem::isSelected() const @@ -1020,6 +1030,10 @@ void QTreeModel::timerEvent(QTimerEvent *ev) \sa setSelected() */ +bool QTreeWidgetItem::isSelected() const +{ + return d->selected; +} /*! \fn void QTreeWidgetItem::setHidden(bool hide) @@ -1033,12 +1047,18 @@ void QTreeModel::timerEvent(QTimerEvent *ev) \sa isHidden() */ -void QTreeWidgetItem::setHidden(bool ahide) +void QTreeWidgetItem::setHidden(bool hide) { - if (view) { - view->setItemHidden(this, ahide); - d->hidden = ahide; + const QTreeModel *model = treeModel(); + if (!model) + return; + if (this == model->headerItem) { + view->header()->setHidden(hide); + } else { + const QModelIndex index = view->d_func()->index(this); + view->setRowHidden(index.row(), index.parent(), hide); } + d->hidden = hide; } /*! @@ -1052,7 +1072,15 @@ void QTreeWidgetItem::setHidden(bool ahide) bool QTreeWidgetItem::isHidden() const { - return (view ? d->hidden : false); + const QTreeModel *model = treeModel(); + if (!model) + return false; + if (this == model->headerItem) + return view->header()->isHidden(); + if (view->d_func()->hiddenIndexes.isEmpty()) + return false; + QTreeModel::SkipSorting skipSorting(model); + return view->d_func()->isRowHidden(view->d_func()->index(this)); } /*! @@ -1064,6 +1092,14 @@ bool QTreeWidgetItem::isHidden() const \sa isExpanded() */ +void QTreeWidgetItem::setExpanded(bool expand) +{ + const QTreeModel *model = treeModel(); + if (!model) + return; + QTreeModel::SkipSorting skipSorting(model); + view->setExpanded(view->d_func()->index(this), expand); +} /*! \fn bool QTreeWidgetItem::isExpanded() const @@ -1073,6 +1109,14 @@ bool QTreeWidgetItem::isHidden() const \sa setExpanded() */ +bool QTreeWidgetItem::isExpanded() const +{ + const QTreeModel *model = treeModel(); + if (!model) + return false; + QTreeModel::SkipSorting skipSorting(model); + return view->isExpanded(view->d_func()->index(this)); +} /*! \fn void QTreeWidgetItem::setFirstColumnSpanned(bool span) @@ -3058,6 +3102,7 @@ void QTreeWidget::setItemWidget(QTreeWidgetItem *item, int column, QWidget *widg QAbstractItemView::setIndexWidget(d->index(item, column), widget); } +#if QT_DEPRECATED_SINCE(5, 13) /*! Returns \c true if the \a item is selected; otherwise returns \c false. @@ -3069,9 +3114,7 @@ void QTreeWidget::setItemWidget(QTreeWidgetItem *item, int column, QWidget *widg */ bool QTreeWidget::isItemSelected(const QTreeWidgetItem *item) const { - if (!item) - return false; - return item->d->selected; + return ((item && item->treeWidget() == this) ? item->isSelected() : false); } /*! @@ -3086,16 +3129,10 @@ bool QTreeWidget::isItemSelected(const QTreeWidgetItem *item) const */ void QTreeWidget::setItemSelected(const QTreeWidgetItem *item, bool select) { - Q_D(QTreeWidget); - - if (!item) - return; - - selectionModel()->select(d->index(item), (select ? QItemSelectionModel::Select - : QItemSelectionModel::Deselect) - |QItemSelectionModel::Rows); - item->d->selected = select; + if (item && item->treeWidget() == this) + const_cast(item)->setSelected(select); } +#endif /*! Returns a list of all selected non-hidden items. @@ -3112,7 +3149,7 @@ QList QTreeWidget::selectedItems() const seen.reserve(indexes.count()); for (const auto &index : indexes) { QTreeWidgetItem *item = d->item(index); - if (isItemHidden(item) || seen.contains(item)) + if (item->isHidden() || seen.contains(item)) continue; seen.insert(item); items.append(item); @@ -3136,6 +3173,7 @@ QList QTreeWidget::findItems(const QString &text, Qt::MatchFla return items; } +#if QT_DEPRECATED_SINCE(5, 13) /*! Returns \c true if the \a item is explicitly hidden, otherwise returns \c false. @@ -3145,13 +3183,7 @@ QList QTreeWidget::findItems(const QString &text, Qt::MatchFla */ bool QTreeWidget::isItemHidden(const QTreeWidgetItem *item) const { - Q_D(const QTreeWidget); - if (item == d->treeModel()->headerItem) - return header()->isHidden(); - if (d->hiddenIndexes.isEmpty()) - return false; - QTreeModel::SkipSorting skipSorting(d->treeModel()); - return d->isRowHidden(d->index(item)); + return ((item && item->treeWidget() == this) ? item->isHidden() : false); } /*! @@ -3165,16 +3197,8 @@ bool QTreeWidget::isItemHidden(const QTreeWidgetItem *item) const */ void QTreeWidget::setItemHidden(const QTreeWidgetItem *item, bool hide) { - if (!item) - return; - Q_D(QTreeWidget); - if (item == d->treeModel()->headerItem) { - header()->setHidden(hide); - } else { - const QModelIndex index = d->index(item); - setRowHidden(index.row(), index.parent(), hide); - } - item->d->hidden = hide; + if (item && item->treeWidget() == this) + const_cast(item)->setHidden(hide); } /*! @@ -3188,9 +3212,7 @@ void QTreeWidget::setItemHidden(const QTreeWidgetItem *item, bool hide) */ bool QTreeWidget::isItemExpanded(const QTreeWidgetItem *item) const { - Q_D(const QTreeWidget); - QTreeModel::SkipSorting skipSorting(d->treeModel()); - return isExpanded(d->index(item)); + return ((item && item->treeWidget() == this) ? item->isExpanded() : false); } /*! @@ -3205,10 +3227,10 @@ bool QTreeWidget::isItemExpanded(const QTreeWidgetItem *item) const */ void QTreeWidget::setItemExpanded(const QTreeWidgetItem *item, bool expand) { - Q_D(QTreeWidget); - QTreeModel::SkipSorting skipSorting(d->treeModel()); - setExpanded(d->index(item), expand); + if (item && item->treeWidget() == this) + const_cast(item)->setExpanded(expand); } +#endif /*! \since 4.3 diff --git a/src/widgets/itemviews/qtreewidget.h b/src/widgets/itemviews/qtreewidget.h index c9186de90c..145b61ff9d 100644 --- a/src/widgets/itemviews/qtreewidget.h +++ b/src/widgets/itemviews/qtreewidget.h @@ -79,14 +79,14 @@ public: inline QTreeWidget *treeWidget() const { return view; } - inline void setSelected(bool select); - inline bool isSelected() const; + void setSelected(bool select); + bool isSelected() const; void setHidden(bool hide); bool isHidden() const; - inline void setExpanded(bool expand); - inline bool isExpanded() const; + void setExpanded(bool expand); + bool isExpanded() const; inline void setFirstColumnSpanned(bool span); inline bool isFirstColumnSpanned() const; @@ -315,17 +315,27 @@ public: void setItemWidget(QTreeWidgetItem *item, int column, QWidget *widget); inline void removeItemWidget(QTreeWidgetItem *item, int column); +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X ("Use QTreeWidgetItem::isSelected() instead") bool isItemSelected(const QTreeWidgetItem *item) const; + QT_DEPRECATED_X ("Use QTreeWidgetItem::setSelected() instead") void setItemSelected(const QTreeWidgetItem *item, bool select); +#endif QList selectedItems() const; QList findItems(const QString &text, Qt::MatchFlags flags, int column = 0) const; +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X ("Use QTreeWidgetItem::isHidden() instead") bool isItemHidden(const QTreeWidgetItem *item) const; + QT_DEPRECATED_X ("Use QTreeWidgetItem::setHidden() instead") void setItemHidden(const QTreeWidgetItem *item, bool hide); + QT_DEPRECATED_X ("Use QTreeWidgetItem::isExpanded() instead") bool isItemExpanded(const QTreeWidgetItem *item) const; + QT_DEPRECATED_X ("Use QTreeWidgetItem::setExpanded() instead") void setItemExpanded(const QTreeWidgetItem *item, bool expand); +#endif bool isFirstItemColumnSpanned(const QTreeWidgetItem *item) const; void setFirstItemColumnSpanned(const QTreeWidgetItem *item, bool span); @@ -413,18 +423,6 @@ inline QTreeWidgetItem *QTreeWidget::itemAt(int ax, int ay) const inline void QTreeWidget::setHeaderLabel(const QString &alabel) { setHeaderLabels(QStringList(alabel)); } -inline void QTreeWidgetItem::setSelected(bool aselect) -{ if (view) view->setItemSelected(this, aselect); } - -inline bool QTreeWidgetItem::isSelected() const -{ return (view ? view->isItemSelected(this) : false); } - -inline void QTreeWidgetItem::setExpanded(bool aexpand) -{ if (view) view->setItemExpanded(this, aexpand); } - -inline bool QTreeWidgetItem::isExpanded() const -{ return (view ? view->isItemExpanded(this) : false); } - inline void QTreeWidgetItem::setFirstColumnSpanned(bool aspan) { if (view) view->setFirstItemColumnSpanned(this, aspan); } diff --git a/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp b/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp index d37d332939..60aa350145 100644 --- a/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp +++ b/tests/auto/testlib/qabstractitemmodeltester/tst_qabstractitemmodeltester.cpp @@ -79,7 +79,7 @@ void tst_QAbstractItemModelTester::treeWidgetModel() root->removeChild(remove); QTreeWidgetItem *parent = new QTreeWidgetItem(&widget, QStringList("parent")); new QTreeWidgetItem(parent, QStringList("child")); - widget.setItemHidden(parent, true); + parent->setHidden(true); widget.sortByColumn(0, Qt::AscendingOrder); } diff --git a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp index e0a9684d13..d15a472072 100644 --- a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp +++ b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp @@ -608,31 +608,31 @@ void tst_QTreeWidget::setItemHidden() QVERIFY(testWidget->visualItemRect(child).isValid() && testWidget->viewport()->rect().intersects(testWidget->visualItemRect(child))); - QVERIFY(!testWidget->isItemHidden(parent)); - QVERIFY(!testWidget->isItemHidden(child)); + QVERIFY(!parent->isHidden()); + QVERIFY(!child->isHidden()); - testWidget->setItemHidden(parent, true); + parent->setHidden(true); QVERIFY(!(testWidget->visualItemRect(parent).isValid() && testWidget->viewport()->rect().intersects(testWidget->visualItemRect(parent)))); QVERIFY(!(testWidget->visualItemRect(child).isValid() && testWidget->viewport()->rect().intersects(testWidget->visualItemRect(child)))); - QVERIFY(testWidget->isItemHidden(parent)); - QVERIFY(!testWidget->isItemHidden(child)); + QVERIFY(parent->isHidden()); + QVERIFY(!child->isHidden()); // From task 78670 (This caused an core dump) // Check if we can set an item visible if it already is visible. - testWidget->setItemHidden(parent, false); - testWidget->setItemHidden(parent, false); - QVERIFY(!testWidget->isItemHidden(parent)); + parent->setHidden(false); + parent->setHidden(false); + QVERIFY(!parent->isHidden()); // hide, hide and then unhide. - testWidget->setItemHidden(parent, true); - testWidget->setItemHidden(parent, true); - testWidget->setItemHidden(parent, false); - QVERIFY(!testWidget->isItemHidden(parent)); + parent->setHidden(true); + parent->setHidden(true); + parent->setHidden(false); + QVERIFY(!parent->isHidden()); } @@ -658,7 +658,7 @@ void tst_QTreeWidget::setItemHidden2() if (testWidget->topLevelItemCount() > 0) { top = testWidget->topLevelItem(0); - testWidget->setItemExpanded(top, true); + top->setExpanded(true); } if (testWidget->topLevelItemCount() > 0) { @@ -666,8 +666,8 @@ void tst_QTreeWidget::setItemHidden2() for (int i = 0; i < top->childCount(); i++) { leaf = top->child(i); if (leaf->text(0).toInt() % 2 == 0) { - if (!testWidget->isItemHidden(leaf)) { - testWidget->setItemHidden(leaf, true); + if (!leaf->isHidden()) { + leaf->setHidden(true); } } } @@ -821,7 +821,7 @@ void tst_QTreeWidget::selectedItems() else item = item->child(index); } - testWidget->setItemSelected(item, true); + item->setSelected(true); } // hide rows @@ -833,7 +833,7 @@ void tst_QTreeWidget::selectedItems() else item = item->child(index); } - testWidget->setItemHidden(item, true); + item->setHidden(true); } // open/close toplevel @@ -862,18 +862,20 @@ void tst_QTreeWidget::selectedItems() // compare isSelected for (int t=0; ttopLevelItemCount(); ++t) { QTreeWidgetItem *top = testWidget->topLevelItem(t); - if (testWidget->isItemSelected(top) && !testWidget->isItemHidden(top)) + if (top->isSelected() && !top->isHidden()) QVERIFY(sel.contains(top)); for (int c=0; cchildCount(); ++c) { QTreeWidgetItem *child = top->child(c); - if (testWidget->isItemSelected(child) && !testWidget->isItemHidden(child)) + if (child->isSelected() && !child->isHidden()) QVERIFY(sel.contains(child)); } } +#if QT_DEPRECATED_SINCE(5, 13) // Possible to select null without crashing? testWidget->setItemSelected(0, true); QVERIFY(!testWidget->isItemSelected(0)); +#endif // unselect foreach (IntList itemPath, selectedItems) { @@ -884,7 +886,7 @@ void tst_QTreeWidget::selectedItems() else item = item->child(index); } - testWidget->setItemSelected(item, false); + item->setSelected(false); } QCOMPARE(testWidget->selectedItems().count(), 0); } @@ -1010,21 +1012,21 @@ void tst_QTreeWidget::expand() QTreeWidgetItem *topLevelItem = testWidget->topLevelItem(topLevelIndex); QTreeWidgetItem *childItem = topLevelItem->child(childIndex); - QVERIFY(!testWidget->isItemExpanded(topLevelItem)); - testWidget->setItemExpanded(topLevelItem, true); - QVERIFY(testWidget->isItemExpanded(topLevelItem)); + QVERIFY(!topLevelItem->isExpanded()); + topLevelItem->setExpanded(true); + QVERIFY(topLevelItem->isExpanded()); - QVERIFY(!testWidget->isItemExpanded(childItem)); - testWidget->setItemExpanded(childItem, true); - QVERIFY(testWidget->isItemExpanded(childItem)); + QVERIFY(!childItem->isExpanded()); + childItem->setExpanded(true); + QVERIFY(childItem->isExpanded()); - QVERIFY(testWidget->isItemExpanded(topLevelItem)); - testWidget->setItemExpanded(topLevelItem, false); - QVERIFY(!testWidget->isItemExpanded(topLevelItem)); + QVERIFY(topLevelItem->isExpanded()); + topLevelItem->setExpanded(false); + QVERIFY(!topLevelItem->isExpanded()); - QVERIFY(testWidget->isItemExpanded(childItem)); - testWidget->setItemExpanded(childItem, false); - QVERIFY(!testWidget->isItemExpanded(childItem)); + QVERIFY(childItem->isExpanded()); + childItem->setExpanded(false); + QVERIFY(!childItem->isExpanded()); } void tst_QTreeWidget::checkState_data() @@ -1525,7 +1527,7 @@ void tst_QTreeWidget::keyboardNavigation() } break; case Qt::Key_Down: - if (testWidget->isItemExpanded(item)) { + if (item->isExpanded()) { row = 0; item = item->child(row); } else { @@ -1538,7 +1540,7 @@ void tst_QTreeWidget::keyboardNavigation() break; case Qt::Key_Left: if (checkScroll) { - QVERIFY(testWidget->isItemExpanded(item)); + QVERIFY(item->isExpanded()); QCOMPARE(scrollBar->value(), valueBeforeClick - scrollBar->singleStep()); } // windows style right will walk to the parent @@ -1597,9 +1599,9 @@ void tst_QTreeWidget::scrollToItem() QCOMPARE(search->text(0), QLatin1String("111")); QTreeWidgetItem *par = search->parent(); - QVERIFY(testWidget->isItemExpanded(par)); + QVERIFY(par->isExpanded()); par = par->parent(); - QVERIFY(testWidget->isItemExpanded(par)); + QVERIFY(par->isExpanded()); } // From task #85413 @@ -2917,14 +2919,14 @@ void tst_QTreeWidget::randomExpand() QTreeWidgetItem *newItem1 = 0; for (int i = 0; i < 100; i++) { newItem1 = new QTreeWidgetItem(&tree, item1); - tree.setItemExpanded(newItem1, true); - QCOMPARE(tree.isItemExpanded(newItem1), true); + newItem1->setExpanded(true); + QCOMPARE(newItem1->isExpanded(), true); QTreeWidgetItem *x = new QTreeWidgetItem(); - QCOMPARE(tree.isItemExpanded(newItem1), true); + QCOMPARE(newItem1->isExpanded(), true); newItem1->addChild(x); - QCOMPARE(tree.isItemExpanded(newItem1), true); + QCOMPARE(newItem1->isExpanded(), true); } } @@ -2937,19 +2939,19 @@ void tst_QTreeWidget::crashTest() QTreeWidgetItem *item1 = new QTreeWidgetItem(tree); item1->setText(0, "item1"); - tree->setItemExpanded(item1, true); + item1->setExpanded(true); QTreeWidgetItem *item2 = new QTreeWidgetItem(item1); item2->setText(0, "item2"); QTreeWidgetItem *item3 = new QTreeWidgetItem(tree, item1); item3->setText(0, "item3"); - tree->setItemExpanded(item3, true); + item3->setExpanded(true); QTreeWidgetItem *item4 = new QTreeWidgetItem(item3); item4->setText(0, "item4"); QTreeWidgetItem *item5 = new QTreeWidgetItem(tree, item3); item5->setText(0, "item5"); - tree->setItemExpanded(item5, true); + item5->setExpanded(true); QTreeWidgetItem *item6 = new QTreeWidgetItem(item5); item6->setText(0, "item6"); diff --git a/tests/auto/widgets/itemviews/qtreewidgetitemiterator/tst_qtreewidgetitemiterator.cpp b/tests/auto/widgets/itemviews/qtreewidgetitemiterator/tst_qtreewidgetitemiterator.cpp index c2c02f3766..76ca148d3f 100644 --- a/tests/auto/widgets/itemviews/qtreewidgetitemiterator/tst_qtreewidgetitemiterator.cpp +++ b/tests/auto/widgets/itemviews/qtreewidgetitemiterator/tst_qtreewidgetitemiterator.cpp @@ -95,11 +95,11 @@ void tst_QTreeWidgetItemIterator::initTestCase() const QString topS = QLatin1String("top") + QString::number(i); top->setText(0, topS); switch (i) { - case 0: testWidget->setItemHidden(top, true);break; - case 1: testWidget->setItemHidden(top, false);break; + case 0: top->setHidden(true);break; + case 1: top->setHidden(false);break; - case 2: testWidget->setItemSelected(top, true);break; - case 3: testWidget->setItemSelected(top, false);break; + case 2: top->setSelected(true);break; + case 3: top->setSelected(false);break; case 4: top->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);break; case 5: top->setFlags(Qt::ItemIsEnabled);break; @@ -126,11 +126,11 @@ void tst_QTreeWidgetItemIterator::initTestCase() QTreeWidgetItem *child = new QTreeWidgetItem(top); child->setText(0, topS + QLatin1String(",child") + QString::number(j)); switch (j) { - case 0: testWidget->setItemHidden(child, true);break; - case 1: testWidget->setItemHidden(child, false);break; + case 0: child->setHidden(true);break; + case 1: child->setHidden(false);break; - case 2: testWidget->setItemSelected(child, true);break; - case 3: testWidget->setItemSelected(child, false);break; + case 2: child->setSelected(true);break; + case 3: child->setSelected(false);break; case 4: child->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);break; case 5: child->setFlags(Qt::ItemIsEnabled);break; From 60f53298544d52d36eb44247bab5d86c8e093117 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 7 Nov 2018 14:24:44 +0100 Subject: [PATCH 0258/1650] Fix test for multiscreen QTBUG_7714_fullUpdateDiscardingOpacityUpdate2() would fail when it moved to another screen if there is one to the left. Change-Id: I3f8edc04c31dffc5a3bd005d9e5170dd68151df7 Reviewed-by: Laszlo Agocs --- .../widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp index 27eac03880..bd08461544 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp @@ -11348,7 +11348,7 @@ void tst_QGraphicsItem::QTBUG_7714_fullUpdateDiscardingOpacityUpdate2() origView.show(); QVERIFY(QTest::qWaitForWindowActive(&origView)); - origView.setGeometry(origView.width() + 20, 20, + origView.setGeometry(origView.x() + origView.width() + 20, origView.y() + 20, origView.width(), origView.height()); parentGreen->setFlag(QGraphicsItem::ItemIgnoresTransformations); From 1cc30fe77d04f745263525e0d4d5e7796ecf792c Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Mon, 5 Nov 2018 13:15:13 +0100 Subject: [PATCH 0259/1650] QSpinBox: don't allow series of thousands-separator chars when editing The input validation did not check for unreasonable use of the group separator character. Fixes: QTBUG-65024 Change-Id: If9d70d990fc6d5b298f3bde5b1604bf7e16dce24 Reviewed-by: Richard Moe Gustavsen --- src/widgets/widgets/qspinbox.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/widgets/widgets/qspinbox.cpp b/src/widgets/widgets/qspinbox.cpp index dcf3906dd7..7624b1ed3c 100644 --- a/src/widgets/widgets/qspinbox.cpp +++ b/src/widgets/widgets/qspinbox.cpp @@ -1134,10 +1134,14 @@ QVariant QSpinBoxPrivate::validateAndInterpret(QString &input, int &pos, num = copy.toInt(&ok, displayIntegerBase); } else { num = locale.toInt(copy, &ok); - if (!ok && copy.contains(locale.groupSeparator()) && (max >= 1000 || min <= -1000)) { - QString copy2 = copy; - copy2.remove(locale.groupSeparator()); - num = locale.toInt(copy2, &ok); + if (!ok && (max >= 1000 || min <= -1000)) { + const QChar sep = locale.groupSeparator(); + const QChar doubleSep[2] = {sep, sep}; + if (copy.contains(sep) && !copy.contains(QString(doubleSep, 2))) { + QString copy2 = copy; + copy2.remove(locale.groupSeparator()); + num = locale.toInt(copy2, &ok); + } } } QSBDEBUG() << __FILE__ << __LINE__<< "num is set to" << num; From fe4448e9e825ce2d650c617c992fa26abda4a2c2 Mon Sep 17 00:00:00 2001 From: Kevin Funk Date: Thu, 25 Oct 2018 11:33:04 +0200 Subject: [PATCH 0260/1650] moc: Modernize generated code a bit, use auto Makes clang-tidy not trip over generated code while running the modernize-use-auto checker. In theory clang-tidy just shouldn't look at generated code of course; but in this case just modernizing the generated code is easy, so let's do it. Example: .../moc_kastentoolviewwidget.cpp:78:9: warning: use auto when initializing with a cast to avoid duplicating the type name [modernize-use-auto] KastenToolViewWidget *_t = static_cast(_o); ^~~~~~~~~~~~~~~~~~~~ auto Change-Id: I10c287320e1d5b5b8e66da3e0a22d517d0275dd1 Reviewed-by: Simon Hausmann Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/tools/moc/generator.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 9fb980893f..fd76646f4c 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -1194,9 +1194,9 @@ void Generator::generateStaticMetacall() #ifndef QT_NO_DEBUG fprintf(out, " Q_ASSERT(staticMetaObject.cast(_o));\n"); #endif - fprintf(out, " %s *_t = static_cast<%s *>(_o);\n", cdef->classname.constData(), cdef->classname.constData()); + fprintf(out, " auto *_t = static_cast<%s *>(_o);\n", cdef->classname.constData()); } else { - fprintf(out, " %s *_t = reinterpret_cast<%s *>(_o);\n", cdef->classname.constData(), cdef->classname.constData()); + fprintf(out, " auto *_t = reinterpret_cast<%s *>(_o);\n", cdef->classname.constData()); } fprintf(out, " Q_UNUSED(_t)\n"); fprintf(out, " switch (_id) {\n"); @@ -1359,9 +1359,9 @@ void Generator::generateStaticMetacall() #ifndef QT_NO_DEBUG fprintf(out, " Q_ASSERT(staticMetaObject.cast(_o));\n"); #endif - fprintf(out, " %s *_t = static_cast<%s *>(_o);\n", cdef->classname.constData(), cdef->classname.constData()); + fprintf(out, " auto *_t = static_cast<%s *>(_o);\n", cdef->classname.constData()); } else { - fprintf(out, " %s *_t = reinterpret_cast<%s *>(_o);\n", cdef->classname.constData(), cdef->classname.constData()); + fprintf(out, " auto *_t = reinterpret_cast<%s *>(_o);\n", cdef->classname.constData()); } fprintf(out, " Q_UNUSED(_t)\n"); if (needTempVarForGet) @@ -1405,9 +1405,9 @@ void Generator::generateStaticMetacall() #ifndef QT_NO_DEBUG fprintf(out, " Q_ASSERT(staticMetaObject.cast(_o));\n"); #endif - fprintf(out, " %s *_t = static_cast<%s *>(_o);\n", cdef->classname.constData(), cdef->classname.constData()); + fprintf(out, " auto *_t = static_cast<%s *>(_o);\n", cdef->classname.constData()); } else { - fprintf(out, " %s *_t = reinterpret_cast<%s *>(_o);\n", cdef->classname.constData(), cdef->classname.constData()); + fprintf(out, " auto *_t = reinterpret_cast<%s *>(_o);\n", cdef->classname.constData()); } fprintf(out, " Q_UNUSED(_t)\n"); fprintf(out, " void *_v = _a[0];\n"); From 4be8168ff7fe8c871a7f3cd7dce8fa4f70e1a6cf Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Mon, 5 Nov 2018 11:16:28 +0100 Subject: [PATCH 0261/1650] Revert "Revert "qmake: Work around MSVC compiler bug."" The assert still happens on MSVC 2015 64 bit when running qmake -tp vc -r. This reverts commit f4169a633b97b7b6e7365172cf3d38d2f16a8914. Fixes: QTBUG-71228 Change-Id: I05bd3e0677414edb970f07e0555cdc95ce32f592 Reviewed-by: Friedemann Kleint --- qmake/generators/win32/msvc_vcproj.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index f7837fc1b4..95c16661e7 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -208,6 +208,16 @@ struct VcsolutionDepend { QStringList dependencies; }; +/* Disable optimization in getProjectUUID() due to a compiler + * bug in MSVC 2015 that causes ASSERT: "&other != this" in the QString + * copy constructor for non-empty file names at: + * filename.isEmpty()?project->first("QMAKE_MAKEFILE"):filename */ + +#if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG) +# pragma optimize( "g", off ) +# pragma warning ( disable : 4748 ) +#endif + QUuid VcprojGenerator::getProjectUUID(const QString &filename) { bool validUUID = true; @@ -239,6 +249,10 @@ QUuid VcprojGenerator::getProjectUUID(const QString &filename) return uuid; } +#if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG) +# pragma optimize( "g", on ) +#endif + QUuid VcprojGenerator::increaseUUID(const QUuid &id) { QUuid result(id); From b20c15f2041205a1cab98fbaf9560a3e2e0d6367 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 19 Oct 2018 09:29:39 +0200 Subject: [PATCH 0262/1650] QtGui: Check event type in QWindowSystemInterface::handleMouseEvent() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Assert on receiving double clicks which are currently not implemented. Task-number: QTBUG-71263 Task-number: QTBUG-70999 Change-Id: I85cd21665ecaf118584053de63745044728d8f5b Reviewed-by: Gatis Paeglis Reviewed-by: Tor Arne Vestbø --- src/gui/kernel/qwindowsysteminterface.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index 67e1283462..5b32405f5e 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -394,6 +394,9 @@ QT_DEFINE_QPA_EVENT_HANDLER(void, handleMouseEvent, QWindow *window, ulong times Qt::MouseButton button, QEvent::Type type, Qt::KeyboardModifiers mods, Qt::MouseEventSource source) { + Q_ASSERT_X(type != QEvent::MouseButtonDblClick && type != QEvent::NonClientAreaMouseButtonDblClick, + "QWindowSystemInterface::handleMouseEvent", + "QTBUG-71263: Native double clicks are not implemented."); auto localPos = QHighDpi::fromNativeLocalPosition(local, window); auto globalPos = QHighDpi::fromNativePixels(global, window); From 1b0080a456871a52ac9b11ed8c9685b93bf20723 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 30 Oct 2018 13:07:34 +0100 Subject: [PATCH 0263/1650] Fix no-opengl developer builds Change-Id: I0c8fb7d0aa9a0d95a13447315bd8c1104089fed1 Reviewed-by: Friedemann Kleint Reviewed-by: Andy Nichols Reviewed-by: Laszlo Agocs --- src/plugins/platforms/eglfs/api/qeglfsintegration.cpp | 1 + src/plugins/platforms/eglfs/api/qeglfsscreen.cpp | 10 +++++++++- .../platforms/minimalegl/qminimaleglintegration.cpp | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp index 43f2e31a49..72420199e3 100644 --- a/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp @@ -198,6 +198,7 @@ QPlatformBackingStore *QEglFSIntegration::createPlatformBackingStore(QWindow *wi static_cast(window->handle())->setBackingStore(bs); return bs; #else + Q_UNUSED(window); return nullptr; #endif } diff --git a/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp index d5c22b3d37..285dbd93d3 100644 --- a/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp @@ -183,6 +183,8 @@ void QEglFSScreen::handleCursorMove(const QPoint &pos) if (enter && leave) QWindowSystemInterface::handleEnterLeaveEvent(enter, leave, enter->mapFromGlobal(pos), pos); +#else + Q_UNUSED(pos); #endif } @@ -231,7 +233,13 @@ QPixmap QEglFSScreen::grabWindow(WId wid, int x, int y, int width, int height) c return QPixmap::fromImage(img).copy(rect); } } -#endif // QT_NO_OPENGL +#else // QT_NO_OPENGL + Q_UNUSED(wid); + Q_UNUSED(x); + Q_UNUSED(y); + Q_UNUSED(width); + Q_UNUSED(height); +#endif return QPixmap(); } diff --git a/src/plugins/platforms/minimalegl/qminimaleglintegration.cpp b/src/plugins/platforms/minimalegl/qminimaleglintegration.cpp index 5d31af53d5..da58441d67 100644 --- a/src/plugins/platforms/minimalegl/qminimaleglintegration.cpp +++ b/src/plugins/platforms/minimalegl/qminimaleglintegration.cpp @@ -132,6 +132,7 @@ QPlatformBackingStore *QMinimalEglIntegration::createPlatformBackingStore(QWindo #ifndef QT_NO_OPENGL return new QMinimalEglBackingStore(window); #else + Q_UNUSED(window); return nullptr; #endif } From 185f9e0758cd7ee649f42b5c788fdfff6031d83c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 5 Nov 2018 13:12:16 -0800 Subject: [PATCH 0264/1650] Merge the qt_memfill{,_template} functions We had two copies of the Duff's Device implementation, one in the .cpp and one in the header. One of the two implementations had a protection against zero counts, the other didn't. So move the .cpp implementation to the header and use it in the functions that were declared there. Fixes: QTBUG-16104 Patch-By: Allan Sandfeld Jensen Change-Id: Iba4b5c183776497d8ee1fffd156456cc3502946e Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qdrawhelper.cpp | 43 +++-------------------------- src/gui/painting/qdrawhelper_p.h | 47 ++++++++++++++++---------------- 2 files changed, 28 insertions(+), 62 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index c0320f5a70..fdf867ec40 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -6244,36 +6244,13 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = }, }; -#if defined(Q_CC_MSVC) && !defined(_MIPS_) -template -inline void qt_memfill_template(T *dest, T color, int count) +void qt_memfill64(quint64 *dest, quint64 color, int count) { - while (count--) - *dest++ = color; + qt_memfill_template(dest, color, count); } -#else - -template -inline void qt_memfill_template(T *dest, T color, int count) -{ - int n = (count + 7) / 8; - switch (count & 0x07) - { - case 0: do { *dest++ = color; Q_FALLTHROUGH(); - case 7: *dest++ = color; Q_FALLTHROUGH(); - case 6: *dest++ = color; Q_FALLTHROUGH(); - case 5: *dest++ = color; Q_FALLTHROUGH(); - case 4: *dest++ = color; Q_FALLTHROUGH(); - case 3: *dest++ = color; Q_FALLTHROUGH(); - case 2: *dest++ = color; Q_FALLTHROUGH(); - case 1: *dest++ = color; - } while (--n > 0); - } -} - -template <> -inline void qt_memfill_template(quint16 *dest, quint16 value, int count) +#if !defined(__SSE2__) +void qt_memfill16(quint16 *dest, quint16 value, int count) { if (count < 3) { switch (count) { @@ -6294,18 +6271,6 @@ inline void qt_memfill_template(quint16 *dest, quint16 value, int count) dest[count - 1] = value; } #endif - -void qt_memfill64(quint64 *dest, quint64 color, int count) -{ - qt_memfill_template(dest, color, count); -} - -#if !defined(__SSE2__) -void qt_memfill16(quint16 *dest, quint16 color, int count) -{ - qt_memfill_template(dest, color, count); -} -#endif #if !defined(__SSE2__) && !defined(__ARM_NEON__) && !defined(__MIPS_DSP__) void qt_memfill32(quint32 *dest, quint32 color, int count) { diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 23520ad64b..68003ac321 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -884,8 +884,30 @@ inline quint24::operator uint() const return data[2] | (data[1] << 8) | (data[0] << 16); } -template static -void qt_memfill(T *dest, T value, int count); +template inline void qt_memfill_template(T *dest, T color, int count) +{ + if (!count) + return; + + qsizetype n = (count + 7) / 8; + switch (count & 0x07) + { + case 0: do { *dest++ = color; Q_FALLTHROUGH(); + case 7: *dest++ = color; Q_FALLTHROUGH(); + case 6: *dest++ = color; Q_FALLTHROUGH(); + case 5: *dest++ = color; Q_FALLTHROUGH(); + case 4: *dest++ = color; Q_FALLTHROUGH(); + case 3: *dest++ = color; Q_FALLTHROUGH(); + case 2: *dest++ = color; Q_FALLTHROUGH(); + case 1: *dest++ = color; + } while (--n > 0); + } +} + +template inline void qt_memfill(T *dest, T value, int count) +{ + qt_memfill_template(dest, value, count); +} template<> inline void qt_memfill(quint64 *dest, quint64 color, int count) { @@ -907,27 +929,6 @@ template<> inline void qt_memfill(quint8 *dest, quint8 color, int count) memset(dest, color, count); } -template -inline void qt_memfill(T *dest, T value, int count) -{ - if (!count) - return; - - int n = (count + 7) / 8; - switch (count & 0x07) - { - case 0: do { *dest++ = value; Q_FALLTHROUGH(); - case 7: *dest++ = value; Q_FALLTHROUGH(); - case 6: *dest++ = value; Q_FALLTHROUGH(); - case 5: *dest++ = value; Q_FALLTHROUGH(); - case 4: *dest++ = value; Q_FALLTHROUGH(); - case 3: *dest++ = value; Q_FALLTHROUGH(); - case 2: *dest++ = value; Q_FALLTHROUGH(); - case 1: *dest++ = value; - } while (--n > 0); - } -} - template static inline void qt_rectfill(T *dest, T value, int x, int y, int width, int height, qsizetype stride) From 1e2bf51d3e5d891db3c1383e6567d1c77dfc8973 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 2 Nov 2018 14:44:13 -0700 Subject: [PATCH 0265/1650] Use qsizetype for qt_memfill functions Just in case the image is larger than 2 GB (512 megapixels). Change-Id: I343f2beed55440a7ac0bfffd15636cbc68dfa13d Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qdrawhelper.cpp | 6 +++--- src/gui/painting/qdrawhelper_mips_dsp.cpp | 2 +- src/gui/painting/qdrawhelper_mips_dsp_p.h | 2 +- src/gui/painting/qdrawhelper_neon.cpp | 2 +- src/gui/painting/qdrawhelper_neon_p.h | 2 +- src/gui/painting/qdrawhelper_p.h | 20 ++++++++++---------- src/gui/painting/qdrawhelper_sse2.cpp | 4 ++-- src/gui/painting/qdrawhelper_x86_p.h | 4 ++-- 8 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index fdf867ec40..b4050b41ac 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -6244,13 +6244,13 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = }, }; -void qt_memfill64(quint64 *dest, quint64 color, int count) +void qt_memfill64(quint64 *dest, quint64 color, qsizetype count) { qt_memfill_template(dest, color, count); } #if !defined(__SSE2__) -void qt_memfill16(quint16 *dest, quint16 value, int count) +void qt_memfill16(quint16 *dest, quint16 value, qsizetype count) { if (count < 3) { switch (count) { @@ -6272,7 +6272,7 @@ void qt_memfill16(quint16 *dest, quint16 value, int count) } #endif #if !defined(__SSE2__) && !defined(__ARM_NEON__) && !defined(__MIPS_DSP__) -void qt_memfill32(quint32 *dest, quint32 color, int count) +void qt_memfill32(quint32 *dest, quint32 color, qsizetype count) { qt_memfill_template(dest, color, count); } diff --git a/src/gui/painting/qdrawhelper_mips_dsp.cpp b/src/gui/painting/qdrawhelper_mips_dsp.cpp index e92a6606de..17597deb1d 100644 --- a/src/gui/painting/qdrawhelper_mips_dsp.cpp +++ b/src/gui/painting/qdrawhelper_mips_dsp.cpp @@ -43,7 +43,7 @@ QT_BEGIN_NAMESPACE -void qt_memfill32(quint32 *dest, quint32 color, int count) +void qt_memfill32(quint32 *dest, quint32 color, qsizetype count) { qt_memfill32_asm_mips_dsp(dest, color, count); } diff --git a/src/gui/painting/qdrawhelper_mips_dsp_p.h b/src/gui/painting/qdrawhelper_mips_dsp_p.h index 36c4af2732..a3d0410274 100644 --- a/src/gui/painting/qdrawhelper_mips_dsp_p.h +++ b/src/gui/painting/qdrawhelper_mips_dsp_p.h @@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE #if defined(QT_COMPILER_SUPPORTS_MIPS_DSP) -extern "C" void qt_memfill32_asm_mips_dsp(quint32 *dest, quint32 value, int count); +extern "C" void qt_memfill32_asm_mips_dsp(quint32 *dest, quint32 value, qsizetype count); extern "C" void comp_func_SourceOver_asm_mips_dsp(uint *dest, const uint *src, int length, uint const_alpha); diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp index c33a1e7fc5..e33af3b784 100644 --- a/src/gui/painting/qdrawhelper_neon.cpp +++ b/src/gui/painting/qdrawhelper_neon.cpp @@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE -void qt_memfill32(quint32 *dest, quint32 value, int count) +void qt_memfill32(quint32 *dest, quint32 value, qsizetype count) { const int epilogueSize = count % 16; #if !defined(Q_PROCESSOR_ARM_64) diff --git a/src/gui/painting/qdrawhelper_neon_p.h b/src/gui/painting/qdrawhelper_neon_p.h index 40475a9bde..19e1f21a3b 100644 --- a/src/gui/painting/qdrawhelper_neon_p.h +++ b/src/gui/painting/qdrawhelper_neon_p.h @@ -123,7 +123,7 @@ void qt_transform_image_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl, const QTransform &targetRectTransform, int const_alpha); -void qt_memfill32_neon(quint32 *dest, quint32 value, int count); +void qt_memfill32_neon(quint32 *dest, quint32 value, qsizetype count); void qt_memrotate90_16_neon(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl); void qt_memrotate270_16_neon(const uchar *srcPixels, int w, int h, int sbpl, uchar *destPixels, int dbpl); diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 68003ac321..a2cf36f20e 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -160,9 +160,9 @@ extern SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::N extern DrawHelper qDrawHelper[QImage::NImageFormats]; void qBlendTexture(int count, const QSpan *spans, void *userData); -extern void qt_memfill64(quint64 *dest, quint64 value, int count); -extern void qt_memfill32(quint32 *dest, quint32 value, int count); -extern void qt_memfill16(quint16 *dest, quint16 value, int count); +extern void qt_memfill64(quint64 *dest, quint64 value, qsizetype count); +extern void qt_memfill32(quint32 *dest, quint32 value, qsizetype count); +extern void qt_memfill16(quint16 *dest, quint16 value, qsizetype count); typedef void (QT_FASTCALL *CompositionFunction)(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha); typedef void (QT_FASTCALL *CompositionFunction64)(QRgba64 *Q_DECL_RESTRICT dest, const QRgba64 *Q_DECL_RESTRICT src, int length, uint const_alpha); @@ -884,7 +884,7 @@ inline quint24::operator uint() const return data[2] | (data[1] << 8) | (data[0] << 16); } -template inline void qt_memfill_template(T *dest, T color, int count) +template inline void qt_memfill_template(T *dest, T color, qsizetype count) { if (!count) return; @@ -904,27 +904,27 @@ template inline void qt_memfill_template(T *dest, T color, int count) } } -template inline void qt_memfill(T *dest, T value, int count) +template inline void qt_memfill(T *dest, T value, qsizetype count) { qt_memfill_template(dest, value, count); } -template<> inline void qt_memfill(quint64 *dest, quint64 color, int count) +template<> inline void qt_memfill(quint64 *dest, quint64 color, qsizetype count) { qt_memfill64(dest, color, count); } -template<> inline void qt_memfill(quint32 *dest, quint32 color, int count) +template<> inline void qt_memfill(quint32 *dest, quint32 color, qsizetype count) { qt_memfill32(dest, color, count); } -template<> inline void qt_memfill(quint16 *dest, quint16 color, int count) +template<> inline void qt_memfill(quint16 *dest, quint16 color, qsizetype count) { qt_memfill16(dest, color, count); } -template<> inline void qt_memfill(quint8 *dest, quint8 color, int count) +template<> inline void qt_memfill(quint8 *dest, quint8 color, qsizetype count) { memset(dest, color, count); } @@ -935,7 +935,7 @@ inline void qt_rectfill(T *dest, T value, { char *d = reinterpret_cast(dest + x) + y * stride; if (uint(stride) == (width * sizeof(T))) { - qt_memfill(reinterpret_cast(d), value, width * height); + qt_memfill(reinterpret_cast(d), value, qsizetype(width) * height); } else { for (int j = 0; j < height; ++j) { dest = reinterpret_cast(d); diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index 1673b27922..88e3fc66fd 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -233,7 +233,7 @@ void QT_FASTCALL comp_func_Source_sse2(uint *dst, const uint *src, int length, u } } -void qt_memfill32(quint32 *dest, quint32 value, int count) +void qt_memfill32(quint32 *dest, quint32 value, qsizetype count) { if (count < 7) { switch (count) { @@ -314,7 +314,7 @@ void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, u } } -void qt_memfill16(quint16 *dest, quint16 value, int count) +void qt_memfill16(quint16 *dest, quint16 value, qsizetype count) { if (count < 3) { switch (count) { diff --git a/src/gui/painting/qdrawhelper_x86_p.h b/src/gui/painting/qdrawhelper_x86_p.h index cefc213999..964d522fd2 100644 --- a/src/gui/painting/qdrawhelper_x86_p.h +++ b/src/gui/painting/qdrawhelper_x86_p.h @@ -57,8 +57,8 @@ QT_BEGIN_NAMESPACE #ifdef __SSE2__ -void qt_memfill32(quint32 *dest, quint32 value, int count); -void qt_memfill16(quint16 *dest, quint16 value, int count); +void qt_memfill32(quint32 *dest, quint32 value, qsizetype count); +void qt_memfill16(quint16 *dest, quint16 value, qsizetype count); void qt_bitmapblit32_sse2(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 &color, const uchar *src, int width, int height, int stride); From f3652429de599d5cdd5c7e25821244ad9c127e3d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 2 Nov 2018 15:32:52 -0700 Subject: [PATCH 0266/1650] Optimize qt_memfill16, with tail jump This simplifies code generation and permits the compiler to implement a tail-jump optimization. Change-Id: I343f2beed55440a7ac0bfffd15636f640116313e Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qdrawhelper_sse2.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index 88e3fc66fd..efcbc8c643 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -325,15 +325,16 @@ void qt_memfill16(quint16 *dest, quint16 value, qsizetype count) } const int align = (quintptr)(dest) & 0x3; - switch (align) { - case 2: *dest++ = value; --count; + if (align) { + *dest++ = value; + --count; } - const quint32 value32 = (value << 16) | value; - qt_memfill32(reinterpret_cast(dest), value32, count / 2); - if (count & 0x1) dest[count - 1] = value; + + const quint32 value32 = (value << 16) | value; + qt_memfill32(reinterpret_cast(dest), value32, count / 2); } void qt_bitmapblit32_sse2_base(QRasterBuffer *rasterBuffer, int x, int y, From 6c1339ef4b44db3c298d1b58389d41c39af4ced5 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 2 Nov 2018 15:46:52 -0700 Subject: [PATCH 0267/1650] Move qt_memfill32-based implementation of qt_memfill16 to generic The SSE2 implementation and the one in qdrawhelper.cpp are almost identical. And if we make it so qt_memfill16 can tail-call to qt_memfill32, there's no need for inlining, so there's no need to keep it in qdrawhelper_sse2.cpp Change-Id: I343f2beed55440a7ac0bfffd15637027771c2254 Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qdrawhelper.cpp | 25 +++++++++---------------- src/gui/painting/qdrawhelper_sse2.cpp | 23 ----------------------- src/gui/painting/qdrawhelper_x86_p.h | 1 - 3 files changed, 9 insertions(+), 40 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index b4050b41ac..fa1990ca60 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2018 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. +** Copyright (C) 2018 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -6249,28 +6249,21 @@ void qt_memfill64(quint64 *dest, quint64 color, qsizetype count) qt_memfill_template(dest, color, count); } -#if !defined(__SSE2__) void qt_memfill16(quint16 *dest, quint16 value, qsizetype count) { - if (count < 3) { - switch (count) { - case 2: *dest++ = value; Q_FALLTHROUGH(); - case 1: *dest = value; - } - return; + const int align = quintptr(dest) & 0x3; + if (align) { + *dest++ = value; + --count; } - const int align = (quintptr)(dest) & 0x3; - switch (align) { - case 2: *dest++ = value; --count; - } - - const quint32 value32 = (value << 16) | value; - qt_memfill(reinterpret_cast(dest), value32, count / 2); if (count & 0x1) dest[count - 1] = value; + + const quint32 value32 = (value << 16) | value; + qt_memfill32(reinterpret_cast(dest), value32, count / 2); } -#endif + #if !defined(__SSE2__) && !defined(__ARM_NEON__) && !defined(__MIPS_DSP__) void qt_memfill32(quint32 *dest, quint32 color, qsizetype count) { diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index efcbc8c643..34bdf7909a 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -314,29 +314,6 @@ void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, u } } -void qt_memfill16(quint16 *dest, quint16 value, qsizetype count) -{ - if (count < 3) { - switch (count) { - case 2: *dest++ = value; Q_FALLTHROUGH(); - case 1: *dest = value; - } - return; - } - - const int align = (quintptr)(dest) & 0x3; - if (align) { - *dest++ = value; - --count; - } - - if (count & 0x1) - dest[count - 1] = value; - - const quint32 value32 = (value << 16) | value; - qt_memfill32(reinterpret_cast(dest), value32, count / 2); -} - void qt_bitmapblit32_sse2_base(QRasterBuffer *rasterBuffer, int x, int y, quint32 color, const uchar *src, int width, int height, int stride) diff --git a/src/gui/painting/qdrawhelper_x86_p.h b/src/gui/painting/qdrawhelper_x86_p.h index 964d522fd2..12b95abe46 100644 --- a/src/gui/painting/qdrawhelper_x86_p.h +++ b/src/gui/painting/qdrawhelper_x86_p.h @@ -58,7 +58,6 @@ QT_BEGIN_NAMESPACE #ifdef __SSE2__ void qt_memfill32(quint32 *dest, quint32 value, qsizetype count); -void qt_memfill16(quint16 *dest, quint16 value, qsizetype count); void qt_bitmapblit32_sse2(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 &color, const uchar *src, int width, int height, int stride); From 59a09022f3a6b773f73c21054b7a6c52434a8939 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 6 Nov 2018 09:54:45 +0100 Subject: [PATCH 0268/1650] Windows QPA: Extend the debug operator for IShellItem Output URL string and file system name, too. Task-number: QTBUG-67932 Change-Id: Ic5d1927d70d98f7c081bee06af85b9f3a2a09812 Reviewed-by: Andre de la Rocha --- src/plugins/platforms/windows/qwindowsdialoghelpers.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index 681b35eb7c..b629cc00a3 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -558,6 +558,10 @@ public: SFGAOF attributes() const { return m_attributes; } QString normalDisplay() const // base name, usually { return displayName(m_item, SIGDN_NORMALDISPLAY); } + QString urlString() const + { return displayName(m_item, SIGDN_URL); } + QString fileSysPath() const + { return displayName(m_item, SIGDN_FILESYSPATH); } QString desktopAbsoluteParsing() const { return displayName(m_item, SIGDN_DESKTOPABSOLUTEPARSING); } QString path() const; // Only set for 'FileSystem' (SFGAO_FILESYSTEM) items @@ -734,7 +738,8 @@ void QWindowsShellItem::format(QDebug &d) const if (canCopy()) d << " [copyable]"; d << ", normalDisplay=\"" << normalDisplay() - << "\", desktopAbsoluteParsing=\"" << desktopAbsoluteParsing() << '"'; + << "\", desktopAbsoluteParsing=\"" << desktopAbsoluteParsing() + << "\", urlString=\"" << urlString() << "\", fileSysPath=\"" << fileSysPath() << '"'; const QString pathS = path(); if (!pathS.isEmpty()) d << ", path=\"" << pathS << '"'; From fbbe8aba9d70a3c13d1cd7797eb4dbbd1f05ade5 Mon Sep 17 00:00:00 2001 From: Thomas Miller Date: Mon, 15 Oct 2018 11:20:10 -0700 Subject: [PATCH 0269/1650] Add Windows Desktop arm64 target to Qtbase Allows a qt build to be configured to target arm64 desktop apps cross platform and build them with nmake. Change-Id: I99fed12047b45a504a1644201bcc19b18c69f3e6 Reviewed-by: Oswald Buddenhagen Reviewed-by: Oliver Wolff --- mkspecs/win32-arm64-msvc2017/qmake.conf | 15 +++++ mkspecs/win32-arm64-msvc2017/qplatformdefs.h | 40 ++++++++++++ qmake/generators/win32/msvc_nmake.cpp | 46 ++++++++++---- src/3rdparty/angle/src/common/mathutil.h | 8 +-- src/3rdparty/angle/src/common/platform.h | 2 +- .../0011-ANGLE-Fix-build-for-ARM64.patch | 63 +++++++++++++++++++ src/corelib/global/qprocessordetection.h | 9 +-- 7 files changed, 162 insertions(+), 21 deletions(-) create mode 100644 mkspecs/win32-arm64-msvc2017/qmake.conf create mode 100644 mkspecs/win32-arm64-msvc2017/qplatformdefs.h create mode 100644 src/angle/patches/0011-ANGLE-Fix-build-for-ARM64.patch diff --git a/mkspecs/win32-arm64-msvc2017/qmake.conf b/mkspecs/win32-arm64-msvc2017/qmake.conf new file mode 100644 index 0000000000..ee10f9cc40 --- /dev/null +++ b/mkspecs/win32-arm64-msvc2017/qmake.conf @@ -0,0 +1,15 @@ +# +# qmake configuration for win32-arm64-msvc2017 +# +# Written for Microsoft C/C++ Optimizing Compiler targeting arm64. +# + +include(../common/msvc-desktop.conf) + +WINSDK_VER = 10.0 +VCPROJ_ARCH = ARM64 + +DEFINES += WIN64 +QMAKE_COMPILER_DEFINES += _WIN64 + +load(qt_config) diff --git a/mkspecs/win32-arm64-msvc2017/qplatformdefs.h b/mkspecs/win32-arm64-msvc2017/qplatformdefs.h new file mode 100644 index 0000000000..8a3afa7630 --- /dev/null +++ b/mkspecs/win32-arm64-msvc2017/qplatformdefs.h @@ -0,0 +1,40 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../win32-msvc/qplatformdefs.h" diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index f2cd7c633b..306ae57871 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -71,18 +71,28 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) return MakefileGenerator::writeStubMakefile(t); #endif if (!project->isHostBuild()) { + const QString msvcVer = project->first("MSVC_VER").toQString(); + if (msvcVer.isEmpty()) { + fprintf(stderr, "Mkspec does not specify MSVC_VER. Cannot continue.\n"); + return false; + } + + bool winrtBuild = false; + bool crossPlatformDesktopBuild = false; + QString arch = project->first("VCPROJ_ARCH").toQString().toLower(); if (project->isActiveConfig(QStringLiteral("winrt"))) { - QString arch = project->first("VCPROJ_ARCH").toQString().toLower(); + winrtBuild = true; + + // Only add explicit support for arm64 cross-platform desktop builds. + } else if ((arch == QLatin1String("arm64")) && (msvcVer == QStringLiteral("15.0"))) { + crossPlatformDesktopBuild = true; + } + + if (winrtBuild || crossPlatformDesktopBuild) { QString compiler; QString compilerArch; - const QString msvcVer = project->first("MSVC_VER").toQString(); - if (msvcVer.isEmpty()) { - fprintf(stderr, "Mkspec does not specify MSVC_VER. Cannot continue.\n"); - return false; - } - + const ProStringList hostArch = project->values("QMAKE_TARGET.arch"); if (msvcVer == QStringLiteral("15.0")) { - const ProStringList hostArch = project->values("QMAKE_TARGET.arch"); if (hostArch.contains("x86_64")) compiler = QStringLiteral("HostX64/"); else @@ -93,6 +103,9 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) } else if (arch == QLatin1String("x64")) { compiler += QStringLiteral("x64"); compilerArch = QStringLiteral("amd64"); + } else if (arch == QLatin1String("arm64")) { + compiler += QStringLiteral("arm64"); + compilerArch = QStringLiteral("arm64"); } else { arch = QStringLiteral("x86"); compiler += QStringLiteral("x86"); @@ -119,7 +132,7 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) return false; } const QString targetVer = project->first("WINTARGET_VER").toQString(); - if (targetVer.isEmpty()) { + if (targetVer.isEmpty() && winrtBuild) { fprintf(stderr, "Mkspec does not specify WINTARGET_VER. Cannot continue.\n"); return false; } @@ -181,10 +194,19 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) incDirs << crtInclude + QStringLiteral("/shared"); incDirs << crtInclude + QStringLiteral("/winrt"); - incDirs << kitDir + QStringLiteral("Extension SDKs/WindowsMobile/") - + crtVersion + QStringLiteral("/Include/WinRT"); + if (winrtBuild) { + // Only use mobile-specific headers and link against store-specific libs for + // winrt builds. + incDirs << kitDir + QStringLiteral("Extension SDKs/WindowsMobile/") + + crtVersion + QStringLiteral("/Include/WinRT"); - libDirs << toolsInstallDir + QStringLiteral("lib/") + arch + QStringLiteral("/store"); + libDirs << toolsInstallDir + QStringLiteral("lib/") + arch + QStringLiteral("/store"); + } else { + // Desktop projects may require the atl headers and libs. + incDirs << toolsInstallDir + QStringLiteral("atlmfc/include"); + libDirs << toolsInstallDir + QStringLiteral("atlmfc/lib/") + compilerArch; + libDirs << toolsInstallDir + QStringLiteral("lib/") + arch; + } libDirs << vcInstallDir + QStringLiteral("VC/Auxiliary/VS/lib/") + arch; diff --git a/src/3rdparty/angle/src/common/mathutil.h b/src/3rdparty/angle/src/common/mathutil.h index 372e432066..88aedddfe8 100644 --- a/src/3rdparty/angle/src/common/mathutil.h +++ b/src/3rdparty/angle/src/common/mathutil.h @@ -150,7 +150,7 @@ inline bool supportsSSE2() return supports; } -#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) +#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) && !defined(_M_ARM64) { int info[4]; __cpuid(info, 0); @@ -162,7 +162,7 @@ inline bool supportsSSE2() supports = (info[3] >> 26) & 1; } } -#endif // defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) +#endif // defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) && !defined(_M_ARM64) checked = true; return supports; #else // defined(ANGLE_USE_SSE) @@ -884,14 +884,14 @@ inline uint32_t BitfieldReverse(uint32_t value) // Count the 1 bits. #if defined(ANGLE_PLATFORM_WINDOWS) -#if defined(_M_ARM) +#if defined(_M_ARM) || defined(_M_ARM64) inline int BitCount(uint32_t bits) { bits = bits - ((bits >> 1) & 0x55555555); bits = (bits & 0x33333333) + ((bits >> 2) & 0x33333333); return (((bits + (bits >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24; } -#else // _M_ARM +#else // _M_ARM || _M_ARM64 inline int BitCount(uint32_t bits) { return static_cast(__popcnt(bits)); diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h index 47cd57b999..fb251da579 100644 --- a/src/3rdparty/angle/src/common/platform.h +++ b/src/3rdparty/angle/src/common/platform.h @@ -83,7 +83,7 @@ # undef far #endif -#if defined(_MSC_VER) && !defined(_M_ARM) +#if defined(_MSC_VER) && !defined(_M_ARM) && !defined(_M_ARM64) #include #define ANGLE_USE_SSE #elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) && !defined(__MINGW32__) diff --git a/src/angle/patches/0011-ANGLE-Fix-build-for-ARM64.patch b/src/angle/patches/0011-ANGLE-Fix-build-for-ARM64.patch new file mode 100644 index 0000000000..3a43894a8a --- /dev/null +++ b/src/angle/patches/0011-ANGLE-Fix-build-for-ARM64.patch @@ -0,0 +1,63 @@ +From 416fb93dae5009bb51da9f6720a95918a2c79e78 Mon Sep 17 00:00:00 2001 +From: Thomas Miller +Date: Tue Oct 16 08:29:58 2018 -0700 +Subject: [PATCH] ANGLE: Fix build for ARM64 + +__popcnt, SSE, and intrin.h are not available when building for ARM64. +--- + src/3rdparty/angle/src/common/mathutil.h | 8 ++++---- + src/3rdparty/angle/src/common/platform.h | 2 +- + 2 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/3rdparty/angle/src/common/mathutil.h b/src/3rdparty/angle/src/common/mathutil.h +index 372e432066..88aedddfe8 100644 +--- a/src/3rdparty/angle/src/common/mathutil.h ++++ b/src/3rdparty/angle/src/common/mathutil.h +@@ -150,7 +150,7 @@ inline bool supportsSSE2() + return supports; + } + +-#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) ++#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) && !defined(_M_ARM64) + { + int info[4]; + __cpuid(info, 0); +@@ -162,7 +162,7 @@ inline bool supportsSSE2() + supports = (info[3] >> 26) & 1; + } + } +-#endif // defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) ++#endif // defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) && !defined(_M_ARM64) + checked = true; + return supports; + #else // defined(ANGLE_USE_SSE) +@@ -884,14 +884,14 @@ inline uint32_t BitfieldReverse(uint32_t value) + + // Count the 1 bits. + #if defined(ANGLE_PLATFORM_WINDOWS) +-#if defined(_M_ARM) ++#if defined(_M_ARM) || defined(_M_ARM64) + inline int BitCount(uint32_t bits) + { + bits = bits - ((bits >> 1) & 0x55555555); + bits = (bits & 0x33333333) + ((bits >> 2) & 0x33333333); + return (((bits + (bits >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24; + } +-#else // _M_ARM ++#else // _M_ARM || _M_ARM64 + inline int BitCount(uint32_t bits) + { + return static_cast(__popcnt(bits)); +diff --git a/src/3rdparty/angle/src/common/platform.h b/src/3rdparty/angle/src/common/platform.h +index 47cd57b999..fb251da579 100644 +--- a/src/3rdparty/angle/src/common/platform.h ++++ b/src/3rdparty/angle/src/common/platform.h +@@ -83,7 +83,7 @@ + # undef far + #endif + +-#if defined(_MSC_VER) && !defined(_M_ARM) ++#if defined(_MSC_VER) && !defined(_M_ARM) && !defined(_M_ARM64) + #include + #define ANGLE_USE_SSE + #elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) && !defined(__MINGW32__) diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h index aaa27dff4a..77b3ba36b0 100644 --- a/src/corelib/global/qprocessordetection.h +++ b/src/corelib/global/qprocessordetection.h @@ -94,8 +94,8 @@ ARM is bi-endian, detect using __ARMEL__ or __ARMEB__, falling back to auto-detection implemented below. */ -#if defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM) || defined(__aarch64__) || defined(__ARM64__) -# if defined(__aarch64__) || defined(__ARM64__) +#if defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM) || defined(_M_ARM64) || defined(__aarch64__) || defined(__ARM64__) +# if defined(__aarch64__) || defined(__ARM64__) || defined(_M_ARM64) # define Q_PROCESSOR_ARM_64 # define Q_PROCESSOR_WORDSIZE 8 # else @@ -110,7 +110,8 @@ # elif defined(__ARM64_ARCH_8__) \ || defined(__aarch64__) \ || defined(__ARMv8__) \ - || defined(__ARMv8_A__) + || defined(__ARMv8_A__) \ + || defined(_M_ARM64) # define Q_PROCESSOR_ARM 8 # elif defined(__ARM_ARCH_7__) \ || defined(__ARM_ARCH_7A__) \ @@ -148,7 +149,7 @@ # else # error "ARM architecture too old" # endif -# if defined(__ARMEL__) +# if defined(__ARMEL__) || defined(_M_ARM64) # define Q_BYTE_ORDER Q_LITTLE_ENDIAN # elif defined(__ARMEB__) # define Q_BYTE_ORDER Q_BIG_ENDIAN From 8802826de6d8a87ad6f29b98eff1eb36964c3e60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 25 Sep 2018 12:20:37 +0200 Subject: [PATCH 0270/1650] Make grabWindow return pixmap with correct dpr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The devicePixelRatio on the returned pixmap should be the product of the Qt and platform scale factors. This handles the corner case of setting QT_SCALE_FACTOR on macOS with a high-dpi display. Change-Id: I3600165d47c03c4e043bcc5e375932cc3fc0c544 Reviewed-by: Tor Arne Vestbø --- src/gui/kernel/qscreen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp index 479e228e27..0ff439abea 100644 --- a/src/gui/kernel/qscreen.cpp +++ b/src/gui/kernel/qscreen.cpp @@ -748,7 +748,7 @@ QPixmap QScreen::grabWindow(WId window, int x, int y, int width, int height) QPixmap result = platformScreen->grabWindow(window, nativePos.x(), nativePos.y(), nativeSize.width(), nativeSize.height()); - result.setDevicePixelRatio(factor); + result.setDevicePixelRatio(result.devicePixelRatio() * factor); return result; } From ae5f440c3393f086a27241b69c4f9dddaf91ce73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 25 Sep 2018 12:25:10 +0200 Subject: [PATCH 0271/1650] macOS: set dpr on pixmap returned by grabWindow() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This matches the behavior of QScreen::grabWindow(), and gives the caller direct access to the scale factor. Change-Id: Ia3ed165a62eaa0f386f8b508ea6b1128ba6be604 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoascreen.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/platforms/cocoa/qcocoascreen.mm b/src/plugins/platforms/cocoa/qcocoascreen.mm index f82ef202b1..5b6b2c13be 100644 --- a/src/plugins/platforms/cocoa/qcocoascreen.mm +++ b/src/plugins/platforms/cocoa/qcocoascreen.mm @@ -466,6 +466,7 @@ QPixmap QCocoaScreen::grabWindow(WId window, int x, int y, int width, int height const qreal dpr = devicePixelRatio(); QPixmap windowPixmap(windowSize * dpr); + windowPixmap.setDevicePixelRatio(dpr); windowPixmap.fill(Qt::transparent); for (uint i = 0; i < displayCount; ++i) { From 98c789eb0fb36493254d60cddce4a1eaa6a1665b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 25 Sep 2018 12:54:09 +0200 Subject: [PATCH 0272/1650] macOS: Make QScreen::grabWindow() work again MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 17b73b0d2b8 introduced a regression where the grab rect position was added to the size when bounding to the display size. This is incorrect. Change-Id: I11d7ba7f53b96badfdead190ef9ddb525ed4ba99 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoascreen.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoascreen.mm b/src/plugins/platforms/cocoa/qcocoascreen.mm index 5b6b2c13be..0d6567070e 100644 --- a/src/plugins/platforms/cocoa/qcocoascreen.mm +++ b/src/plugins/platforms/cocoa/qcocoascreen.mm @@ -474,8 +474,8 @@ QPixmap QCocoaScreen::grabWindow(WId window, int x, int y, int width, int height // Calculate the position and size of the requested area QPoint pos(qAbs(bounds.origin.x - x), qAbs(bounds.origin.y - y)); - QSize size(qMin(pos.x() + width, qRound(bounds.size.width)), - qMin(pos.y() + height, qRound(bounds.size.height))); + QSize size(qMin(width, qRound(bounds.size.width)), + qMin(height, qRound(bounds.size.height))); pos *= dpr; size *= dpr; From e72613000edc46f3f2b354a698202ac0a4a32fb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 3 Oct 2018 14:14:23 +0200 Subject: [PATCH 0273/1650] wasm: skip examples by default This removes the need for specifying "-nomake examples" on the configure line. We are using static builds; building all of the examples is too space and time consuming (especially time). Change-Id: Iff23239ca7304b1d1cf734c8bf69ad3f8ef31844 Reviewed-by: Oswald Buddenhagen Reviewed-by: Lorn Potter --- config_help.txt | 3 ++- configure.json | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/config_help.txt b/config_help.txt index 5b32eb183f..44dccfb8da 100644 --- a/config_help.txt +++ b/config_help.txt @@ -213,7 +213,8 @@ Component selection: [libs and examples, also tools if not cross-building, also tests if -developer-build] -nomake ....... Exclude from the list of parts to be built. - -compile-examples .... When unset, install only the sources of examples [yes] + -compile-examples .... When unset, install only the sources of examples + [no on WebAssembly, otherwise yes] -gui ................. Build the Qt GUI module and dependencies [yes] -widgets ............. Build the Qt Widgets module and dependencies [yes] -no-dbus ............. Do not build the Qt D-Bus module diff --git a/configure.json b/configure.json index 522bd34e9b..7c79b5c582 100644 --- a/configure.json +++ b/configure.json @@ -1203,6 +1203,7 @@ }, "compile_examples": { "label": "Compile examples", + "autoDetect": "!config.wasm", "output": [ "privateConfig" ] }, "incredibuild_xge": { From f018e315fd654dcc0a22209e5a3506b4c8838e1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 19 Oct 2018 12:30:16 +0200 Subject: [PATCH 0274/1650] QWidgetBackingStore: Don't flush foreign windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Foreign windows do not have Qt backingstore content, and are also not capable of accepting Qt content. Change-Id: I959c7cdc32e6f4322497e132a436ce7d610a4106 Fixes: QTBUG-71183 Reviewed-by: Tor Arne Vestbø --- src/widgets/kernel/qwidgetbackingstore.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index b40c2d12ad..a32eb2a03b 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -101,6 +101,13 @@ void QWidgetBackingStore::qt_flush(QWidget *widget, const QRegion ®ion, QBack if (tlw->testAttribute(Qt::WA_DontShowOnScreen) || widget->testAttribute(Qt::WA_DontShowOnScreen)) return; + + // Foreign Windows do not have backing store content and must not be flushed + if (QWindow *widgetWindow = widget->windowHandle()) { + if (widgetWindow->type() == Qt::ForeignWindow) + return; + } + static bool fpsDebug = qEnvironmentVariableIntValue("QT_DEBUG_FPS"); if (fpsDebug) { if (!widgetBackingStore->perfFrames++) From 1e9e9acae7b352920f55843dc6c2a0819276fb4f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 24 Oct 2018 12:48:36 -0700 Subject: [PATCH 0275/1650] QFile::copy: include the QTemporaryFile's error message if it fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I1bd327aeaf73421a8ec5fffd1560a333fdfea909 Reviewed-by: Mikhail Svetkin Reviewed-by: Lars Knoll Reviewed-by: Jędrzej Nowacki --- src/corelib/io/qfile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index 3166fa1b83..d3f846bc1d 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -808,7 +808,7 @@ QFile::copy(const QString &newName) if (error) { out.close(); close(); - d->setError(QFile::CopyError, tr("Cannot open for output")); + d->setError(QFile::CopyError, tr("Cannot open for output: %1").arg(out.errorString())); } else { if (!d->engine()->cloneTo(out.d_func()->engine())) { char block[4096]; From 6f251c567c8b388d6594575c365c0e9d48bb6541 Mon Sep 17 00:00:00 2001 From: Sven Erdem Date: Tue, 9 Oct 2018 18:32:55 +0200 Subject: [PATCH 0276/1650] Use timeout error for TCP timeouts on unix When a TCP connection timed out a QAbstractSocket::NetworkError was set. To enable a more precise error handling for timeouts QAbstractSocket::SocketTimeoutError is now set instead. Separated ETIMEDOUT from other errors in nativeRead() and take over responsibility for setting the error, which was previously handled by read(). Change-Id: Iccd45bdbb3d944cd160ae50c257d3256e05b1ae5 Reviewed-by: Edward Welbourne Reviewed-by: David Faure --- src/network/socket/qnativesocketengine_unix.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index b380b0f7d6..24c17124dc 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -1383,19 +1383,23 @@ qint64 QNativeSocketEnginePrivate::nativeRead(char *data, qint64 maxSize) // No data was available for reading r = -2; break; - case EBADF: - case EINVAL: - case EIO: - //error string is now set in read(), not here in nativeRead() - break; case ECONNRESET: #if defined(Q_OS_VXWORKS) case ESHUTDOWN: #endif r = 0; break; - default: + case ETIMEDOUT: + socketError = QAbstractSocket::SocketTimeoutError; break; + default: + socketError = QAbstractSocket::NetworkError; + break; + } + + if (r == -1) { + hasSetSocketError = true; + socketErrorString = qt_error_string(); } } From c7275f6723089b0ba5f305fe8f3b51cb6f1eb845 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Thu, 25 Oct 2018 12:21:35 +0200 Subject: [PATCH 0277/1650] Doc: fix formatting error in QLineF This is a whitespace-only change; removing a couple of newlines that broke qdoc formatting of the enum values documentation. Change-Id: Id371a4519922c71d79a11f3cda131e6683812696 Reviewed-by: Venugopal Shivashankar --- src/corelib/tools/qline.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/corelib/tools/qline.cpp b/src/corelib/tools/qline.cpp index 9704a00b85..949f63ea15 100644 --- a/src/corelib/tools/qline.cpp +++ b/src/corelib/tools/qline.cpp @@ -387,10 +387,9 @@ QDataStream &operator>>(QDataStream &stream, QLine &line) \value UnboundedIntersection The two lines intersect, but not within the range defined by their lengths. This will be the case - if the lines are not parallel. - - intersect() will also return this value if the intersect point is - within the start and end point of only one of the lines. + if the lines are not parallel. intersect() will also return this + value if the intersect point is within the start and end point of + only one of the lines. \value BoundedIntersection The two lines intersect with each other within the start and end points of each line. From 508b9b49b9d178db959d2e2066b8d4b9f5173573 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 2 Nov 2018 11:48:55 +0100 Subject: [PATCH 0278/1650] Fix image grab when XCB is rgb-swapping The rgbSwap produces an image that fits the X-server, but not one that fits our internal image definitions, so instead return our internal image. Task-number: QTBUG-56806 Change-Id: I25aedf7279bcd86792213b11dbd07a77b49538de Reviewed-by: Gatis Paeglis --- src/plugins/platforms/xcb/qxcbbackingstore.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index c8c806749f..ba9a3e68ee 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -837,6 +837,9 @@ void QXcbBackingStore::endPaint() QImage QXcbBackingStore::toImage() const { + // If the backingstore is rgbSwapped, return the internal image type here. + if (!m_rgbImage.isNull()) + return m_rgbImage; return m_image && m_image->image() ? *m_image->image() : QImage(); } From 6857cd60dd884a763af26e43863187e9157fe32c Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 6 Nov 2018 11:03:42 +0100 Subject: [PATCH 0279/1650] win32: Fix text prediction with on screen keyboard When the on-screen keyboard completes a word via text prediction, the message contains VK_PACKET as identifier for a character sequence. While each character is send, the code only contains the first character of the sequence. Hence, resolve the actual code manually in case of a sequence. This does not modify the virtual key, so that users are able to distinguish between manual and predictive input. Fixes: QTBUG-71210 Change-Id: I787f1f2d83acaf124dfbbab6c4614a1bfe7bb2eb Reviewed-by: Andre de la Rocha Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowskeymapper.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp index 9e6101b758..96abfdb9d7 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.cpp +++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp @@ -1263,6 +1263,13 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, MSG msg, } #endif // !QT_NO_SHORTCUT key_recorder.storeKey(int(msg.wParam), a, state, text); + + // QTBUG-71210 + // VK_PACKET specifies multiple characters. The system only sends the first + // character of this sequence for each. + if (msg.wParam == VK_PACKET) + code = asciiToKeycode(char(uch.cell()), state); + QWindowSystemInterface::handleExtendedKeyEvent(receiver, QEvent::KeyPress, code, modifiers, scancode, quint32(msg.wParam), nModifiers, text, false); result =true; From ee91993997161635b8288aa95d9ecf8af5ecd589 Mon Sep 17 00:00:00 2001 From: Vitaly Fanaskov Date: Thu, 8 Nov 2018 10:16:00 +0100 Subject: [PATCH 0280/1650] Change the wording for license type in the About Qt box "the GNU LGPL version 3" -> "GNU (L)GPL" because some parts of Qt are GPL v3 (Qt Charts, Qt VirtualKeyboard, etc.). Fixes: QTBUG-57697 Change-Id: Iceb88244e28b6900c5282b070468fb65b2bf52d2 Reviewed-by: Lars Knoll --- src/widgets/dialogs/qmessagebox.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index 99157747dd..d8cd19ef1a 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -1844,10 +1844,10 @@ void QMessageBox::aboutQt(QWidget *parent, const QString &title) "

    Qt licensed under our commercial license agreement is appropriate " "for development of proprietary/commercial software where you do not " "want to share any source code with third parties or otherwise cannot " - "comply with the terms of the GNU LGPL version 3.

    " - "

    Qt licensed under the GNU LGPL version 3 is appropriate for the " + "comply with the terms of GNU (L)GPL.

    " + "

    Qt licensed under GNU (L)GPL is appropriate for the " "development of Qt applications provided you can comply with the terms " - "and conditions of the GNU LGPL version 3.

    " + "and conditions of the respective licenses.

    " "

    Please see %2 " "for an overview of Qt licensing.

    " "

    Copyright (C) %1 The Qt Company Ltd and other " From 45764e07eb16fc75cc91de6772415c3da4c450fe Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 22 Oct 2018 17:31:21 +0200 Subject: [PATCH 0281/1650] Document provenance and version of sha3_keccak Task-number: QTBUG-71327 Change-Id: Iccfda0320d61e60df53ba30c12b4ffd0fc60d1ef Reviewed-by: Lars Knoll --- src/3rdparty/sha3/qt_attribution.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/3rdparty/sha3/qt_attribution.json b/src/3rdparty/sha3/qt_attribution.json index 4866be32ea..5e6e993e19 100644 --- a/src/3rdparty/sha3/qt_attribution.json +++ b/src/3rdparty/sha3/qt_attribution.json @@ -17,9 +17,11 @@ "Name": "Secure Hash Algorithm SHA-3 - Keccak", "QDocModule": "qtcore", "QtUsage": "Used in Qt Core (QCryptographicHash).", + "Files": "https://keccak.team/obsolete/KeccakReferenceAndOptimized-3.2.zip - but it's obsolete", "Files": "KeccakF-1600-32-rvk.macros KeccakF-1600-32.macros KeccakF-1600-64.macros KeccakF-1600-interface.h KeccakF-1600-opt32.c KeccakF-1600-opt64.c KeccakF-1600-unrolling.macros KeccakNISTInterface.c KeccakNISTInterface.h KeccakSponge.c KeccakSponge.h", "Description": "SHA-3, originally known as Keccak, is a cryptographic hash function.", + "Version": "3.2", "License": "Creative Commons Zero v1.0 Universal", "LicenseId": "CC0-1.0", "LicenseFile": "CC0_LICENSE", From d38f635355dded964ce14de6160fb897e5d6b40d Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Fri, 19 Oct 2018 15:33:34 +0200 Subject: [PATCH 0282/1650] Clean up and update Unicode character data 3rd-party infrastructure Document how to do an update, fix the bit-rot that had crept into main.cpp since last it was compiled, correct the qt_attribution.json to use the actual version number of UCD (its Revision number) instead of the (admittedly correlated) Unicode release number. Updated to Release 22 (which came with Unicode 11.0.0) in the process; but this doesn't change our actual qunicodetables.cpp (so is incidental). Task-number: QTBUG-71281 Change-Id: Ieb7a6e1a4d49f639993f76ff82c8f12a572db3c3 Reviewed-by: Thiago Macieira Reviewed-by: Lars Knoll --- src/corelib/tools/qt_attribution.json | 4 +++- util/unicode/README | 31 +++++++++++++++++++++++++++ util/unicode/main.cpp | 11 ++++------ 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/corelib/tools/qt_attribution.json b/src/corelib/tools/qt_attribution.json index 5bb95c9f5b..a842d9467b 100644 --- a/src/corelib/tools/qt_attribution.json +++ b/src/corelib/tools/qt_attribution.json @@ -4,12 +4,14 @@ "Name": "Unicode Character Database (UCD)", "QDocModule": "qtcore", "QtUsage": "Qt Core uses data obtained from UCD files for working with characters and strings.", + "Files": "For update, see qtbase/util/unicode/README", "Files": "qunicodetables_p.h qunicodetables.cpp", "Description": "The Unicode Character Database (UCD) is a set of files that define the Unicode character properties and internal mappings.", "Homepage": "https://www.unicode.org/ucd/", - "Version": "10.0.0", + "Version": "Don't use the Unicode standard version; UCD has its own 'Revision' numbers", + "Version": "20", "License": "Unicode License Agreement - Data Files and Software (2016)", "LicenseId": "Unicode-DFS-2016", "LicenseFile": "UNICODE_LICENSE.txt", diff --git a/util/unicode/README b/util/unicode/README index ca34266a36..e52f26175a 100644 --- a/util/unicode/README +++ b/util/unicode/README @@ -1 +1,32 @@ Unicode is used to generate the unicode data in src/corelib/tools. + +To update: +* Find the data (UAX #44, UCD; not the XML version) at + ftp://www.unicode.org/Public/zipped/$Version/ +* Unpack the zip file; for each file in data/, replace with the new + version; find the *BreakProperty.txt in auxiliary/. (These last are + only in the zip, not in the web-space's unpacked versions.) +* If needed, add an entry to enum QChar::UnicodeVersion for the new + Unicode version +* In that case, also update main.cpp's initAgeMap and DATA_VERSION_S* + to match +* Build this project. Its binary, unicode, ignores command-line + options and assumes it is being run from this directory. When run, + it produces lots of output. Hopefully that doesn't matter. +* Assertions may trigger: if so, study code and understand what's more + complicated about this update; talk to folk named in the git logs, + maybe push a WIP to gerrit to solicit advice. Some bit-field may + need to be expanded, for example. In some cases QChar may need + additions to some of its enums. +* Build with the modified code, fix any compilation issues. +* That may have updated qtbase/src/corelib/tools/qunicodetables.cpp; + if so the update matters; be sure to commit the changes to data/ at + the same time and update tools/qt_attribution.json to match; use the + UCD Revision number, rather than the Unicode standard number, as the + Version, for all that qunicodetables.cpp uses the latter. + +The script writingSystems.sh generates a list of writing systems, +ostensibly as a the basis for updating QFontDatabase::WritingSystem +enum; however, the Release 20 output of it contains many more writing +systems than are present in that enum, suggesting it has not been run +in a very long time. Further research needed. diff --git a/util/unicode/main.cpp b/util/unicode/main.cpp index 0c3c0b2ee1..00c69de008 100644 --- a/util/unicode/main.cpp +++ b/util/unicode/main.cpp @@ -78,7 +78,6 @@ static void initAgeMap() } } - static QHash categoryMap; static void initCategoryMap() @@ -778,7 +777,6 @@ static void initScriptMap() { QChar::Script_Soyombo, "Soyombo" }, { QChar::Script_ZanabazarSquare, "ZanabazarSquare" }, - // unhandled { QChar::Script_Unknown, 0 } }; @@ -789,7 +787,6 @@ static void initScriptMap() } } - // Keep this one in sync with the code in createPropertyInfo static const char *property_string = "struct Properties {\n" @@ -2473,9 +2470,9 @@ static QByteArray createPropertyInfo() out += ", "; out += QByteArray::number( p.lowerCaseDiff ); out += ", "; - out += "#ifdef Q_OS_WASM \n" + out += "#ifdef Q_OS_WASM \n"; // " unsigned char : 0; //wasm 64 packing trick QTBUG-65259\n" - out += "#endif \n" + out += "#endif \n"; out += ", "; // " ushort upperCaseSpecial : 1;\n" // " signed short upperCaseDiff : 15;\n" @@ -2501,9 +2498,9 @@ static QByteArray createPropertyInfo() // " ushort nfQuickCheck : 8;\n" out += QByteArray::number( p.nfQuickCheck ); out += ", "; - out += "#ifdef Q_OS_WASM \n" + out += "#ifdef Q_OS_WASM \n"; // " unsigned char : 0; //wasm 64 packing trick QTBUG-65259\n" - out += "#endif \n" + out += "#endif \n"; out += ", "; // " ushort graphemeBreakClass : 5; /* 5 used */\n" // " ushort wordBreakClass : 5; /* 5 used */\n" From b26ce2f0bffc5b1fedc5935c90df62e621abd9c7 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Sun, 23 Sep 2018 19:33:18 +0200 Subject: [PATCH 0283/1650] qdbuscpp2xml: Don't silently ignore unregistered property types Change-Id: Icf23804cc4992314785f07cdc6aaf76eeea56465 Reviewed-by: Thiago Macieira --- src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp index 2115a14adf..738905a9a0 100644 --- a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp +++ b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp @@ -212,8 +212,11 @@ static QString generateInterfaceXml(const ClassDef *mo) access |= 2; int typeId = QMetaType::type(mp.type.constData()); - if (!typeId) + if (!typeId) { + fprintf(stderr, PROGRAMNAME ": unregistered type: '%s', ignoring\n", + mp.type.constData()); continue; + } const char *signature = QDBusMetaType::typeToSignature(typeId); if (!signature) continue; From c9f375f4e3d90e1296d8159f98f003c7570f902f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 25 Sep 2018 13:37:20 +0200 Subject: [PATCH 0284/1650] Document QScreen::grabWindow high-DPI behavior MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ib32510ff30e907365e64921fda14e686a495c77c Reviewed-by: Tor Arne Vestbø --- src/gui/kernel/qscreen.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp index 0ff439abea..f208eb02be 100644 --- a/src/gui/kernel/qscreen.cpp +++ b/src/gui/kernel/qscreen.cpp @@ -701,6 +701,11 @@ void QScreenPrivate::updatePrimaryOrientation() border of the window. If \a height is negative, the function copies everything to the bottom of the window. + The offset and size arguments are specified in device independent + pixels. The returned pixmap may be larger than the requested size + when grabbing from a high-DPI screen. Call QPixmap::devicePixelRatio() + to determine if this is the case. + The window system identifier (\c WId) can be retrieved using the QWidget::winId() function. The rationale for using a window identifier and not a QWidget, is to enable grabbing of windows From 74828aa657bda447c4a3f232688819333eb422df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 8 Nov 2018 15:53:12 +0100 Subject: [PATCH 0285/1650] macOS: Disable main thread checker for Xcode test target MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: If9bf63a94b8f2ca1846a502879af5bada9918cd7 Fixes: QTBUG-71636 Reviewed-by: Morten Johan Sørvig --- mkspecs/macx-xcode/default.xcscheme | 1 + 1 file changed, 1 insertion(+) diff --git a/mkspecs/macx-xcode/default.xcscheme b/mkspecs/macx-xcode/default.xcscheme index bd2cb0e565..170174ed2b 100644 --- a/mkspecs/macx-xcode/default.xcscheme +++ b/mkspecs/macx-xcode/default.xcscheme @@ -26,6 +26,7 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "NO" + disableMainThreadChecker = "YES" buildConfiguration = "Debug"> Date: Tue, 6 Nov 2018 14:16:05 +0100 Subject: [PATCH 0286/1650] macOS: Remove blacklist entries for no longer supported OS versions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Iae6552f1fdcf1dea07a03d3788d378af9140d1a7 Reviewed-by: Morten Johan Sørvig --- tests/auto/corelib/io/qsettings/BLACKLIST | 2 -- tests/auto/gui/kernel/qwindow/BLACKLIST | 1 - tests/auto/other/macnativeevents/BLACKLIST | 1 - tests/auto/testlib/selftests/test/BLACKLIST | 3 --- tests/auto/widgets/graphicsview/qgraphicsscene/BLACKLIST | 4 ---- tests/auto/widgets/kernel/qwidget/BLACKLIST | 1 - tests/auto/widgets/widgets/qmenu/BLACKLIST | 1 - 7 files changed, 13 deletions(-) delete mode 100644 tests/auto/corelib/io/qsettings/BLACKLIST delete mode 100644 tests/auto/testlib/selftests/test/BLACKLIST diff --git a/tests/auto/corelib/io/qsettings/BLACKLIST b/tests/auto/corelib/io/qsettings/BLACKLIST deleted file mode 100644 index 36d68bd918..0000000000 --- a/tests/auto/corelib/io/qsettings/BLACKLIST +++ /dev/null @@ -1,2 +0,0 @@ -[isWritable:native] -osx-10.11 diff --git a/tests/auto/gui/kernel/qwindow/BLACKLIST b/tests/auto/gui/kernel/qwindow/BLACKLIST index f54865b841..caf39742f6 100644 --- a/tests/auto/gui/kernel/qwindow/BLACKLIST +++ b/tests/auto/gui/kernel/qwindow/BLACKLIST @@ -26,7 +26,6 @@ osx # QTBUG-69163 android [visibility] -osx-10.11 ci osx-10.12 ci [testInputEvents] diff --git a/tests/auto/other/macnativeevents/BLACKLIST b/tests/auto/other/macnativeevents/BLACKLIST index 32e0b1d50b..2922e22d9f 100644 --- a/tests/auto/other/macnativeevents/BLACKLIST +++ b/tests/auto/other/macnativeevents/BLACKLIST @@ -32,7 +32,6 @@ osx osx # QTQAINFRA-1292 [testPushButtonPressRelease] -osx-10.11 ci osx-10.12 ci # QTQAINFRA-1292 diff --git a/tests/auto/testlib/selftests/test/BLACKLIST b/tests/auto/testlib/selftests/test/BLACKLIST deleted file mode 100644 index 2d4adf1feb..0000000000 --- a/tests/auto/testlib/selftests/test/BLACKLIST +++ /dev/null @@ -1,3 +0,0 @@ -#QTBUG-55155 -[runSubTest:maxwarnings all loggers] -osx-10.11 diff --git a/tests/auto/widgets/graphicsview/qgraphicsscene/BLACKLIST b/tests/auto/widgets/graphicsview/qgraphicsscene/BLACKLIST index 0e7a1b451f..b8b427b3dd 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsscene/BLACKLIST +++ b/tests/auto/widgets/graphicsview/qgraphicsscene/BLACKLIST @@ -1,10 +1,6 @@ -[removeItem] -# QTBUG-60754, QTest::mouseMove is not always respected, or the CI moves the cursor -osx-10.11 ci [isActive] opensuse-42.3 ci [removeFullyTransparentItem] -osx-10.11 osx-10.12 [tabFocus_sceneWithNestedFocusWidgets] opensuse diff --git a/tests/auto/widgets/kernel/qwidget/BLACKLIST b/tests/auto/widgets/kernel/qwidget/BLACKLIST index d8654e5768..1f68308bbe 100644 --- a/tests/auto/widgets/kernel/qwidget/BLACKLIST +++ b/tests/auto/widgets/kernel/qwidget/BLACKLIST @@ -32,7 +32,6 @@ osx [render_systemClip] osx [showMinimizedKeepsFocus] -osx-10.11 ci osx-10.12 ci osx-10.13 ci [maskedUpdate] diff --git a/tests/auto/widgets/widgets/qmenu/BLACKLIST b/tests/auto/widgets/widgets/qmenu/BLACKLIST index 89d12a259f..bac14ea225 100644 --- a/tests/auto/widgets/widgets/qmenu/BLACKLIST +++ b/tests/auto/widgets/widgets/qmenu/BLACKLIST @@ -1,7 +1,6 @@ [task258920_mouseBorder] osx [submenuTearOffDontClose] -osx-10.11 ci osx-10.12 ci [layoutDirection] # Fails when enabling synchronous expose events QTBUG-62092 From a6a5e81cd6a627108382270c482df8a5e7939f7d Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 9 Nov 2018 09:36:12 +0100 Subject: [PATCH 0287/1650] Fix a typo in the docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I0f1b015a34b8caffa3b60927cedbccf7db50b383 Reviewed-by: Topi Reiniö --- src/gui/text/qtextdocument.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 6ca4bc8209..008f695da0 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -1912,7 +1912,7 @@ static void printPage(int index, QPainter *painter, const QTextDocument *doc, co } /*! - Prints the document to the given \a printer. The QPageablePaintDevice must be + Prints the document to the given \a printer. The QPagedPaintDevice must be set up before being used with this function. This is only a convenience method to print the whole document to the printer. From 75818581488c88454cf69e6326f5172734592729 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 25 Sep 2018 15:40:48 +0200 Subject: [PATCH 0288/1650] Make QThreadPool::waitForDone more atomic Avoid having the reset in waitForDone interfere with other uses of the thread-pool by locking the mutex higher, and maintaining the state so the queues doesn't have threads not in allThreads. Task-number: QTBUG-62865 Change-Id: I17ee95d5f0e138ec15e785c6d61bb0fe064d3659 Reviewed-by: Edward Welbourne --- src/corelib/thread/qthreadpool.cpp | 79 +++++++++++++++--------------- src/corelib/thread/qthreadpool_p.h | 6 ++- 2 files changed, 44 insertions(+), 41 deletions(-) diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp index ea2c611082..4d2389f699 100644 --- a/src/corelib/thread/qthreadpool.cpp +++ b/src/corelib/thread/qthreadpool.cpp @@ -39,7 +39,7 @@ #include "qthreadpool.h" #include "qthreadpool_p.h" -#include "qelapsedtimer.h" +#include "qdeadlinetimer.h" #include @@ -130,11 +130,6 @@ void QThreadPoolThread::run() } } while (true); - if (manager->isExiting) { - registerThreadInactive(); - break; - } - // if too many threads are active, expire this thread bool expired = manager->tooManyThreadsActive(); if (!expired) { @@ -145,6 +140,10 @@ void QThreadPoolThread::run() ++manager->activeThreads; if (manager->waitingThreads.removeOne(this)) expired = true; + if (!manager->allThreads.contains(this)) { + registerThreadInactive(); + break; + } } if (expired) { manager->expiredThreads.enqueue(this); @@ -267,7 +266,7 @@ void QThreadPoolPrivate::startThread(QRunnable *runnable) QScopedPointer thread(new QThreadPoolThread(this)); thread->setObjectName(QLatin1String("Thread (pooled)")); Q_ASSERT(!allThreads.contains(thread.data())); // if this assert hits, we have an ABA problem (deleted threads don't get removed here) - allThreads.append(thread.data()); + allThreads.insert(thread.data()); ++activeThreads; if (runnable->autoDelete()) @@ -278,49 +277,54 @@ void QThreadPoolPrivate::startThread(QRunnable *runnable) /*! \internal - Makes all threads exit, waits for each thread to exit and deletes it. + + Helper function only to be called from waitForDone(int) */ void QThreadPoolPrivate::reset() { - QMutexLocker locker(&mutex); - isExiting = true; + // move the contents of the set out so that we can iterate without the lock + QSet allThreadsCopy; + allThreadsCopy.swap(allThreads); + expiredThreads.clear(); + waitingThreads.clear(); + mutex.unlock(); - while (!allThreads.empty()) { - // move the contents of the set out so that we can iterate without the lock - QList allThreadsCopy; - allThreadsCopy.swap(allThreads); - locker.unlock(); - - for (QThreadPoolThread *thread : qAsConst(allThreadsCopy)) { + for (QThreadPoolThread *thread: qAsConst(allThreadsCopy)) { + if (!thread->isFinished()) { thread->runnableReady.wakeAll(); thread->wait(); - delete thread; } - - locker.relock(); - // repeat until all newly arrived threads have also completed + delete thread; } - waitingThreads.clear(); - expiredThreads.clear(); + mutex.lock(); +} - isExiting = false; +/*! + \internal + + Helper function only to be called from waitForDone(int) +*/ +bool QThreadPoolPrivate::waitForDone(const QDeadlineTimer &timer) +{ + while (!(queue.isEmpty() && activeThreads == 0) && !timer.hasExpired()) + noActiveThreads.wait(&mutex, timer); + + return queue.isEmpty() && activeThreads == 0; } bool QThreadPoolPrivate::waitForDone(int msecs) { QMutexLocker locker(&mutex); - if (msecs < 0) { - while (!(queue.isEmpty() && activeThreads == 0)) - noActiveThreads.wait(locker.mutex()); - } else { - QElapsedTimer timer; - timer.start(); - int t; - while (!(queue.isEmpty() && activeThreads == 0) && - ((t = msecs - timer.elapsed()) > 0)) - noActiveThreads.wait(locker.mutex(), t); - } + QDeadlineTimer timer(msecs); + do { + if (!waitForDone(timer)) + return false; + reset(); + // More threads can be started during reset(), in that case continue + // waiting if we still have time left. + } while ((!queue.isEmpty() || activeThreads) && !timer.hasExpired()); + return queue.isEmpty() && activeThreads == 0; } @@ -686,10 +690,7 @@ void QThreadPool::releaseThread() bool QThreadPool::waitForDone(int msecs) { Q_D(QThreadPool); - bool rc = d->waitForDone(msecs); - if (rc) - d->reset(); - return rc; + return d->waitForDone(msecs); } /*! diff --git a/src/corelib/thread/qthreadpool_p.h b/src/corelib/thread/qthreadpool_p.h index 0e6a00d243..952e02ef20 100644 --- a/src/corelib/thread/qthreadpool_p.h +++ b/src/corelib/thread/qthreadpool_p.h @@ -63,6 +63,8 @@ QT_REQUIRE_CONFIG(thread); QT_BEGIN_NAMESPACE +class QDeadlineTimer; + class QueuePage { public: enum { @@ -163,12 +165,13 @@ public: void startThread(QRunnable *runnable = 0); void reset(); bool waitForDone(int msecs); + bool waitForDone(const QDeadlineTimer &timer); void clear(); void stealAndRunRunnable(QRunnable *runnable); void deletePageIfFinished(QueuePage *page); mutable QMutex mutex; - QList allThreads; + QSet allThreads; QQueue waitingThreads; QQueue expiredThreads; QVector queue; @@ -179,7 +182,6 @@ public: int reservedThreads = 0; int activeThreads = 0; uint stackSize = 0; - bool isExiting = false; }; QT_END_NAMESPACE From 49bbc9df99e1927b6e377054add05599587f88d3 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Fri, 9 Nov 2018 14:23:23 +0100 Subject: [PATCH 0289/1650] QMacStyle: remove weird frame translation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Numbers look completely out of thin air, and while I trust it was not an error back then it was introduced, today we end up with QComboBox vertically translated and thus misaligned. Task-number: QTBUG-69908 Change-Id: I784e06f00e4c92c4af67e9bd885b86648183f2e0 Reviewed-by: Morten Johan Sørvig --- src/plugins/styles/mac/qmacstyle_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index 0204bd6104..1fd3420899 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -1512,7 +1512,7 @@ QRectF QMacStylePrivate::CocoaControl::adjustedControlFrame(const QRectF &rect) frameRect = frameRect.translated(rect.topLeft()); if (type == QMacStylePrivate::Button_PullDown || type == QMacStylePrivate::Button_PopupButton) { if (size == QStyleHelper::SizeLarge) - frameRect = frameRect.adjusted(0, 0, -6, 0).translated(3, -1); + frameRect = frameRect.adjusted(0, 0, -6, 0).translated(3, 0); else if (size == QStyleHelper::SizeSmall) frameRect = frameRect.adjusted(0, 0, -4, 0).translated(2, 1); else if (size == QStyleHelper::SizeMini) From 79ed504f10ba49b19fe9122ae3de4cf652130320 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 9 Nov 2018 12:59:38 +0100 Subject: [PATCH 0290/1650] Manual dialogs test: Add option to turn off the printer panel On Linux, the printer panel impacts the application startup time,which can be annoying when testing other dialogs. Change-Id: Id13446047cf50765951a6bb5182ee50cae983457 Reviewed-by: Shawn Rutledge --- tests/manual/dialogs/main.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/manual/dialogs/main.cpp b/tests/manual/dialogs/main.cpp index 83089e684c..fc4adebcc0 100644 --- a/tests/manual/dialogs/main.cpp +++ b/tests/manual/dialogs/main.cpp @@ -44,6 +44,8 @@ #include #include +static bool optNoPrinter = false; + // Test for dialogs, allowing to play with all dialog options for implementing native dialogs. // Compiles with Qt 4.8 and Qt 5. @@ -109,7 +111,8 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) tabWidget->addTab(new WizardPanel, tr("QWizard")); tabWidget->addTab(new MessageBoxPanel, tr("QMessageBox")); #ifndef QT_NO_PRINTER - tabWidget->addTab(new PrintDialogPanel, tr("QPrintDialog")); + if (!optNoPrinter) + tabWidget->addTab(new PrintDialogPanel, tr("QPrintDialog")); #endif setCentralWidget(tabWidget); } @@ -123,14 +126,16 @@ void MainWindow::aboutDialog() int main(int argc, char *argv[]) { -#if QT_VERSION >= 0x050700 for (int a = 1; a < argc; ++a) { if (!qstrcmp(argv[a], "-n")) { qDebug("AA_DontUseNativeDialogs"); +#if QT_VERSION >= 0x050700 QCoreApplication::setAttribute(Qt::AA_DontUseNativeDialogs); +#endif + } else if (!qstrcmp(argv[a], "-p")) { + optNoPrinter = true; // Avoid startup slowdown by printer code } } -#endif // Qt 5 QApplication a(argc, argv); MainWindow w; From ac4f075274414aac1b6cf2e8e854f0f21fee0761 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Mon, 5 Nov 2018 15:56:47 +0100 Subject: [PATCH 0291/1650] Make sure mouse release events are delivered to correct widget The initial mouse press should create an implicit mouse grab so that all subsequent mouse events are delivered to the widget that was pressed first. After commit a4f7bb8733e0, every mouse press would reset the implicit grab. This change checks the previous button state, and does not reset the mouse grab if other buttons are already pressed. Fixes: QTBUG-70816 Change-Id: Icdd215c2f4aaee3c3f34607d68c1d8878155ec17 Reviewed-by: Shawn Rutledge --- src/widgets/kernel/qwidgetwindow.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 0b2d72f330..279c6c0282 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -642,7 +642,8 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) if (!widget) widget = m_widget; - if (event->type() == QEvent::MouseButtonPress) + const bool initialPress = event->buttons() == event->button(); + if (event->type() == QEvent::MouseButtonPress && initialPress) qt_button_down = widget; QWidget *receiver = QApplicationPrivate::pickMouseReceiver(m_widget, event->windowPos().toPoint(), &mapped, event->type(), event->buttons(), From 104200d688650db02f1447f73a499784115d897d Mon Sep 17 00:00:00 2001 From: Filippo Cucchetto Date: Sun, 21 Oct 2018 10:36:17 +0200 Subject: [PATCH 0292/1650] Fix QFileSystemWatcher::removePath after move operations Foreword: - During a file or directory move the inotify id for an entity is not changed. - QFileSystemWatcher implementation uses a QMultiHash for mapping an id to its path. Suppose this filesystem hypothetical directory structure - A |--> B and user watches both A and B directories. Suppose that the B directory gets moved by calling "mv B B1". The user receives a directoryChanged event for parent directory A and scan filesystem for changes. During this scan the user notices: - a new directory B1 - a deleted directory B The user simply invoke QFileSystemWatcher::addPath(B1) and QFileSystemWatcher::removePath(B). With the actual implementation the second operation could fail: - The call QFileSystemWatcher::addPath(B1) insert a duplicated records in the QFileSystemWatcher::idToPath multihash ( {0, "A"}, {1, "A/B"} {1, "A/B1"} - The call QFileSystemWatcher::removePath(B) fails because - it first retrieves the the id for path B ---> pathToId("A/B") <-- return 1 - Then it calls idToPath.take with the id obtain in the previous step <--- idToPath.take(1) This last operation could take the record {1, "A/B1"} instead of the {1, "A/B"} (because both have the same key) meaning that the next check "x != path" evaluates to true (making the removePath function fail). This patch fixes the problem in the following way: - Use idToPath.equal_range in order to obtain all paths with the given id - Remove the correct record that match (id, path) - Prevent the removal of the inotify watch if another record with the same id is still present in the multihash (like a simple reference counting). Change-Id: I9c8480b2a869d91e500af5c4aded596b9aa53b46 Reviewed-by: Edward Welbourne --- src/corelib/io/qfilesystemwatcher_inotify.cpp | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/corelib/io/qfilesystemwatcher_inotify.cpp b/src/corelib/io/qfilesystemwatcher_inotify.cpp index 3b7135e582..a5e629b646 100644 --- a/src/corelib/io/qfilesystemwatcher_inotify.cpp +++ b/src/corelib/io/qfilesystemwatcher_inotify.cpp @@ -330,13 +330,24 @@ QStringList QInotifyFileSystemWatcherEngine::removePaths(const QStringList &path while (it.hasNext()) { QString path = it.next(); int id = pathToID.take(path); - QString x = idToPath.take(id); - if (x.isEmpty() || x != path) + + // Multiple paths could be associated to the same watch descriptor + // when a file is moved and added with the new name. + // So we should find and delete the correct one by using + // both id and path + auto path_range = idToPath.equal_range(id); + auto path_it = std::find(path_range.first, path_range.second, path); + if (path_it == idToPath.end()) continue; - int wd = id < 0 ? -id : id; - // qDebug() << "removing watch for path" << path << "wd" << wd; - inotify_rm_watch(inotifyFd, wd); + const ssize_t num_elements = std::distance(path_range.first, path_range.second); + idToPath.erase(path_it); + + // If there was only one path associated to the given id we should remove the watch + if (num_elements == 1) { + int wd = id < 0 ? -id : id; + inotify_rm_watch(inotifyFd, wd); + } it.remove(); if (id < 0) { From 178bc49ac2b80b80f75829f3add5d7e66fd08240 Mon Sep 17 00:00:00 2001 From: Samuel Gaist Date: Fri, 5 Oct 2018 23:26:08 +0200 Subject: [PATCH 0293/1650] QImageWriter: improve documentation regarding use of resources QImageWriter's plugin can open devices while operating and only free them on destruction which means that if one wants to act on the file written if must first destroy the writer's instance. This patch adds the suggestion to use a scope to avoid that problem. Change-Id: I239157ea86c4a93faab237fe1860312a3c7ac7a2 Reviewed-by: Eirik Aavitsland --- src/gui/doc/snippets/qimagewriter/main.cpp | 71 ++++++++++++++++++++++ src/gui/image/qimagewriter.cpp | 10 +++ 2 files changed, 81 insertions(+) create mode 100644 src/gui/doc/snippets/qimagewriter/main.cpp diff --git a/src/gui/doc/snippets/qimagewriter/main.cpp b/src/gui/doc/snippets/qimagewriter/main.cpp new file mode 100644 index 0000000000..3758110356 --- /dev/null +++ b/src/gui/doc/snippets/qimagewriter/main.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2018 Samuel Gaist +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + +//! [0] + QString imagePath(QStringLiteral("path/image.jpeg")); + QImage image(64, 64, QImage::Format_RGB32); + image.fill(Qt::red); + { + QImageWriter writer(imagePath); + writer.write(image); + } + + QFile::rename(imagePath, + QStringLiteral("path/other_image.jpeg")); +//! [0] + + return 0; +} diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp index 5ce7e309bb..d3f9a9b881 100644 --- a/src/gui/image/qimagewriter.cpp +++ b/src/gui/image/qimagewriter.cpp @@ -71,6 +71,16 @@ formats, in addition to any image format plugins that support writing. + \note QImageWriter assumes exclusive control over the file or + device that is assigned. Any attempts to modify the assigned file + or device during the lifetime of the QImageWriter object will + yield undefined results. If immediate access to a resource is + desired, the use of a scope is the recommended method. + + For example: + + \snippet qimagewriter/main.cpp 0 + \sa QImageReader, QImageIOHandler, QImageIOPlugin */ From 1c957bb8e57adf7674716f40b67c5d6877b32f86 Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Sun, 11 Nov 2018 23:44:27 +0300 Subject: [PATCH 0294/1650] Fix ambiguous definition of atime/mtime/ctime on alpha MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One of the implementations is enabled when the stat struct has ::st_atim member, another — when it has ::st_atimensec member. On alpha, the stat struct has both members, defined as union here: https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/alpha/bits/stat.h#l48 and then used here: https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/alpha/bits/stat.h#l92 This commit forcefully disables the second implementation on alpha. Change-Id: Ifc284d72b68b9bac590b518f31960288df3a087d Done-with: Michael Cree Reviewed-by: Thiago Macieira --- src/corelib/io/qfilesystemengine_unix.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 5a5a3a82c6..b2d81066db 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -285,7 +285,7 @@ mtime(const T &statBuffer, int) { return timespecToMSecs(statBuffer.st_mtimespec); } #endif -#ifndef st_mtimensec +#if !defined(st_mtimensec) && !defined(__alpha__) // Xtimensec template Q_DECL_UNUSED static typename std::enable_if<(&T::st_atimensec, true), qint64>::type From 8c685b765bf4ceba3c4cf8fdd9c9d680f338b7a9 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sat, 20 Oct 2018 21:48:28 +0200 Subject: [PATCH 0295/1650] Itemviews: Cleanup examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cleanup some minor issues in the chart example: - remove unused members - use initializer list for members - pass a proper role to dataChanged() - honor roles parameter in PieView::dataChanged() - use nullptr instead 0 - use new-style connect - fix indentation and other whitespaces Change-Id: Idb212b07c006fe3ae31bee9cd9b1ba4d03043b5e Reviewed-by: André Hartmann Reviewed-by: Paul Wicking --- .../itemviews/addressbook/tablemodel.cpp | 2 +- .../widgets/itemviews/chart/mainwindow.cpp | 18 +++--- examples/widgets/itemviews/chart/mainwindow.h | 8 +-- examples/widgets/itemviews/chart/pieview.cpp | 56 +++++++++---------- examples/widgets/itemviews/chart/pieview.h | 14 ++--- .../itemviews/editabletreemodel/treemodel.cpp | 2 +- .../tutorials/modelview/1_readonly/main.cpp | 8 +-- .../modelview/1_readonly/mymodel.cpp | 5 +- .../tutorials/modelview/1_readonly/mymodel.h | 4 +- .../tutorials/modelview/2_formatting/main.cpp | 8 +-- .../modelview/2_formatting/mymodel.cpp | 24 +++----- .../modelview/2_formatting/mymodel.h | 4 +- .../modelview/3_changingmodel/main.cpp | 6 +- .../modelview/3_changingmodel/mymodel.cpp | 23 +++----- .../modelview/3_changingmodel/mymodel.h | 7 +-- .../tutorials/modelview/4_headers/main.cpp | 10 ++-- .../tutorials/modelview/4_headers/mymodel.cpp | 25 ++++----- .../tutorials/modelview/4_headers/mymodel.h | 4 +- .../tutorials/modelview/5_edit/main.cpp | 2 +- .../tutorials/modelview/5_edit/mainwindow.cpp | 14 +++-- .../tutorials/modelview/5_edit/mainwindow.h | 8 +-- .../tutorials/modelview/5_edit/mymodel.cpp | 30 +++++----- .../tutorials/modelview/5_edit/mymodel.h | 8 +-- .../tutorials/modelview/6_treeview/main.cpp | 2 +- .../modelview/6_treeview/mainwindow.cpp | 23 ++++---- .../modelview/6_treeview/mainwindow.h | 12 ++-- .../tutorials/modelview/7_selections/main.cpp | 2 +- .../modelview/7_selections/mainwindow.cpp | 18 +++--- .../modelview/7_selections/mainwindow.h | 6 +- 29 files changed, 161 insertions(+), 192 deletions(-) diff --git a/examples/widgets/itemviews/addressbook/tablemodel.cpp b/examples/widgets/itemviews/addressbook/tablemodel.cpp index 674e312753..b3704f857e 100644 --- a/examples/widgets/itemviews/addressbook/tablemodel.cpp +++ b/examples/widgets/itemviews/addressbook/tablemodel.cpp @@ -164,7 +164,7 @@ bool TableModel::setData(const QModelIndex &index, const QVariant &value, int ro return false; contacts.replace(row, contact); - emit(dataChanged(index, index)); + emit dataChanged(index, index, {role}); return true; } diff --git a/examples/widgets/itemviews/chart/mainwindow.cpp b/examples/widgets/itemviews/chart/mainwindow.cpp index 91e535a006..53f57fbb49 100644 --- a/examples/widgets/itemviews/chart/mainwindow.cpp +++ b/examples/widgets/itemviews/chart/mainwindow.cpp @@ -48,12 +48,13 @@ ** ****************************************************************************/ -#include - #include "pieview.h" #include "mainwindow.h" -MainWindow::MainWindow() +#include + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) { QMenu *fileMenu = new QMenu(tr("&File"), this); QAction *openAction = fileMenu->addAction(tr("&Open...")); @@ -124,17 +125,18 @@ void MainWindow::loadFile(const QString &fileName) return; QTextStream stream(&file); - QString line; model->removeRows(0, model->rowCount(QModelIndex()), QModelIndex()); int row = 0; - do { - line = stream.readLine(); + while (!stream.atEnd()) { + const QString line = stream.readLine(); if (!line.isEmpty()) { model->insertRows(row, 1, QModelIndex()); - QStringList pieces = line.split(',', QString::SkipEmptyParts); + const QStringList pieces = line.split(',', QString::SkipEmptyParts); + if (pieces.size() < 3) + continue; model->setData(model->index(row, 0, QModelIndex()), pieces.value(0)); model->setData(model->index(row, 1, QModelIndex()), @@ -143,7 +145,7 @@ void MainWindow::loadFile(const QString &fileName) QColor(pieces.value(2)), Qt::DecorationRole); row++; } - } while (!line.isEmpty()); + }; file.close(); statusBar()->showMessage(tr("Loaded %1").arg(fileName), 2000); diff --git a/examples/widgets/itemviews/chart/mainwindow.h b/examples/widgets/itemviews/chart/mainwindow.h index 058f5c7e90..51176d261b 100644 --- a/examples/widgets/itemviews/chart/mainwindow.h +++ b/examples/widgets/itemviews/chart/mainwindow.h @@ -56,7 +56,6 @@ QT_BEGIN_NAMESPACE class QAbstractItemModel; class QAbstractItemView; -class QItemSelectionModel; QT_END_NAMESPACE class MainWindow : public QMainWindow @@ -64,7 +63,7 @@ class MainWindow : public QMainWindow Q_OBJECT public: - MainWindow(); + MainWindow(QWidget *parent = nullptr); private slots: void openFile(); @@ -75,9 +74,8 @@ private: void setupViews(); void loadFile(const QString &path); - QAbstractItemModel *model; - QAbstractItemView *pieChart; - QItemSelectionModel *selectionModel; + QAbstractItemModel *model = nullptr; + QAbstractItemView *pieChart = nullptr; }; #endif // MAINWINDOW_H diff --git a/examples/widgets/itemviews/chart/pieview.cpp b/examples/widgets/itemviews/chart/pieview.cpp index 3f85e397ee..457ed8b4ec 100644 --- a/examples/widgets/itemviews/chart/pieview.cpp +++ b/examples/widgets/itemviews/chart/pieview.cpp @@ -48,30 +48,25 @@ ** ****************************************************************************/ -#include -#include -#include #include "pieview.h" +#include + PieView::PieView(QWidget *parent) : QAbstractItemView(parent) { horizontalScrollBar()->setRange(0, 0); verticalScrollBar()->setRange(0, 0); - - margin = 8; - totalSize = 300; - pieSize = totalSize - 2 * margin; - validItems = 0; - totalValue = 0.0; - rubberBand = 0; } void PieView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, - const QVector &) + const QVector &roles) { - QAbstractItemView::dataChanged(topLeft, bottomRight); + QAbstractItemView::dataChanged(topLeft, bottomRight, roles); + + if (!roles.contains(Qt::DisplayRole)) + return; validItems = 0; totalValue = 0.0; @@ -79,7 +74,7 @@ void PieView::dataChanged(const QModelIndex &topLeft, for (int row = 0; row < model()->rowCount(rootIndex()); ++row) { QModelIndex index = model()->index(row, 1, rootIndex()); - double value = model()->data(index).toDouble(); + double value = model()->data(index, Qt::DisplayRole).toDouble(); if (value > 0.0) { totalValue += value; @@ -197,15 +192,14 @@ QRect PieView::itemRect(const QModelIndex &index) const listItem++; } - double itemHeight; - switch (index.column()) { - case 0: - itemHeight = QFontMetrics(viewOptions().font).height(); + case 0: { + const qreal itemHeight = QFontMetricsF(viewOptions().font).height(); return QRect(totalSize, - int(margin + listItem*itemHeight), - totalSize - margin, int(itemHeight)); + qRound(margin + listItem * itemHeight), + totalSize - margin, qRound(itemHeight)); + } case 1: return viewport()->rect(); } @@ -235,7 +229,7 @@ QRegion PieView::itemRegion(const QModelIndex &index) const if (sliceIndex == index) { QPainterPath slicePath; slicePath.moveTo(totalSize / 2, totalSize / 2); - slicePath.arcTo(margin, margin, margin+pieSize, margin+pieSize, + slicePath.arcTo(margin, margin, margin + pieSize, margin + pieSize, startAngle, angle); slicePath.closeSubpath(); @@ -342,7 +336,7 @@ void PieView::paintEvent(QPaintEvent *event) double value = model()->data(index).toDouble(); if (value > 0.0) { - double angle = 360*value/totalValue; + double angle = 360 * value / totalValue; QModelIndex colorIndex = model()->index(row, 0, rootIndex()); QColor color = QColor(model()->data(colorIndex, Qt::DecorationRole).toString()); @@ -480,16 +474,16 @@ void PieView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlag } if (indexes.size() > 0) { - int firstRow = indexes[0].row(); - int lastRow = indexes[0].row(); - int firstColumn = indexes[0].column(); - int lastColumn = indexes[0].column(); + int firstRow = indexes.at(0).row(); + int lastRow = firstRow; + int firstColumn = indexes.at(0).column(); + int lastColumn = firstColumn; for (int i = 1; i < indexes.size(); ++i) { - firstRow = qMin(firstRow, indexes[i].row()); - lastRow = qMax(lastRow, indexes[i].row()); - firstColumn = qMin(firstColumn, indexes[i].column()); - lastColumn = qMax(lastColumn, indexes[i].column()); + firstRow = qMin(firstRow, indexes.at(i).row()); + lastRow = qMax(lastRow, indexes.at(i).row()); + firstColumn = qMin(firstColumn, indexes.at(i).column()); + lastColumn = qMax(lastColumn, indexes.at(i).column()); } QItemSelection selection( @@ -508,7 +502,7 @@ void PieView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlag void PieView::updateGeometries() { horizontalScrollBar()->setPageStep(viewport()->width()); - horizontalScrollBar()->setRange(0, qMax(0, 2*totalSize - viewport()->width())); + horizontalScrollBar()->setRange(0, qMax(0, 2 * totalSize - viewport()->width())); verticalScrollBar()->setPageStep(viewport()->height()); verticalScrollBar()->setRange(0, qMax(0, totalSize - viewport()->height())); } @@ -546,7 +540,7 @@ QRegion PieView::visualRegionForSelection(const QItemSelection &selection) const QRegion region; for (int i = 0; i < ranges; ++i) { - QItemSelectionRange range = selection.at(i); + const QItemSelectionRange &range = selection.at(i); for (int row = range.top(); row <= range.bottom(); ++row) { for (int col = range.left(); col <= range.right(); ++col) { QModelIndex index = model()->index(row, col, rootIndex()); diff --git a/examples/widgets/itemviews/chart/pieview.h b/examples/widgets/itemviews/chart/pieview.h index aa397e6d55..22c74dde81 100644 --- a/examples/widgets/itemviews/chart/pieview.h +++ b/examples/widgets/itemviews/chart/pieview.h @@ -59,7 +59,7 @@ class PieView : public QAbstractItemView Q_OBJECT public: - PieView(QWidget *parent = 0); + PieView(QWidget *parent = nullptr); QRect visualRect(const QModelIndex &index) const override; void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible) override; @@ -100,13 +100,13 @@ private: int rows(const QModelIndex &index = QModelIndex()) const; void updateGeometries() override; - int margin; - int totalSize; - int pieSize; - int validItems; - double totalValue; + int margin = 0; + int totalSize = 300; + int pieSize = totalSize - 2 * margin; + int validItems = 0; + double totalValue = 0.0; + QRubberBand *rubberBand = nullptr; QPoint origin; - QRubberBand *rubberBand; }; //! [0] diff --git a/examples/widgets/itemviews/editabletreemodel/treemodel.cpp b/examples/widgets/itemviews/editabletreemodel/treemodel.cpp index dbd53df1e6..72818372d7 100644 --- a/examples/widgets/itemviews/editabletreemodel/treemodel.cpp +++ b/examples/widgets/itemviews/editabletreemodel/treemodel.cpp @@ -225,7 +225,7 @@ bool TreeModel::setData(const QModelIndex &index, const QVariant &value, int rol bool result = item->setData(index.column(), value); if (result) - emit dataChanged(index, index); + emit dataChanged(index, index, {role}); return result; } diff --git a/examples/widgets/tutorials/modelview/1_readonly/main.cpp b/examples/widgets/tutorials/modelview/1_readonly/main.cpp index 80383f8c94..ea571d3699 100644 --- a/examples/widgets/tutorials/modelview/1_readonly/main.cpp +++ b/examples/widgets/tutorials/modelview/1_readonly/main.cpp @@ -50,16 +50,16 @@ //! [Quoting ModelView Tutorial] // main.cpp -#include -#include +#include +#include #include "mymodel.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); QTableView tableView; - MyModel myModel(0); - tableView.setModel( &myModel ); + MyModel myModel; + tableView.setModel(&myModel); tableView.show(); return a.exec(); } diff --git a/examples/widgets/tutorials/modelview/1_readonly/mymodel.cpp b/examples/widgets/tutorials/modelview/1_readonly/mymodel.cpp index 82ec53c665..2b36565bc6 100644 --- a/examples/widgets/tutorials/modelview/1_readonly/mymodel.cpp +++ b/examples/widgets/tutorials/modelview/1_readonly/mymodel.cpp @@ -53,7 +53,7 @@ #include "mymodel.h" MyModel::MyModel(QObject *parent) - :QAbstractTableModel(parent) + : QAbstractTableModel(parent) { } @@ -70,11 +70,10 @@ int MyModel::columnCount(const QModelIndex & /*parent*/) const QVariant MyModel::data(const QModelIndex &index, int role) const { if (role == Qt::DisplayRole) - { return QString("Row%1, Column%2") .arg(index.row() + 1) .arg(index.column() +1); - } + return QVariant(); } //! [Quoting ModelView Tutorial] diff --git a/examples/widgets/tutorials/modelview/1_readonly/mymodel.h b/examples/widgets/tutorials/modelview/1_readonly/mymodel.h index e675cc6bc2..8761322896 100644 --- a/examples/widgets/tutorials/modelview/1_readonly/mymodel.h +++ b/examples/widgets/tutorials/modelview/1_readonly/mymodel.h @@ -59,8 +59,8 @@ class MyModel : public QAbstractTableModel { Q_OBJECT public: - MyModel(QObject *parent); - int rowCount(const QModelIndex &parent = QModelIndex()) const override ; + MyModel(QObject *parent = nullptr); + int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; }; diff --git a/examples/widgets/tutorials/modelview/2_formatting/main.cpp b/examples/widgets/tutorials/modelview/2_formatting/main.cpp index 80383f8c94..ea571d3699 100644 --- a/examples/widgets/tutorials/modelview/2_formatting/main.cpp +++ b/examples/widgets/tutorials/modelview/2_formatting/main.cpp @@ -50,16 +50,16 @@ //! [Quoting ModelView Tutorial] // main.cpp -#include -#include +#include +#include #include "mymodel.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); QTableView tableView; - MyModel myModel(0); - tableView.setModel( &myModel ); + MyModel myModel; + tableView.setModel(&myModel); tableView.show(); return a.exec(); } diff --git a/examples/widgets/tutorials/modelview/2_formatting/mymodel.cpp b/examples/widgets/tutorials/modelview/2_formatting/mymodel.cpp index 9511648392..938597a34e 100644 --- a/examples/widgets/tutorials/modelview/2_formatting/mymodel.cpp +++ b/examples/widgets/tutorials/modelview/2_formatting/mymodel.cpp @@ -48,13 +48,14 @@ ** ****************************************************************************/ +#include "mymodel.h" + #include #include -#include "mymodel.h" #include MyModel::MyModel(QObject *parent) - :QAbstractTableModel(parent) + : QAbstractTableModel(parent) { } @@ -78,7 +79,7 @@ QVariant MyModel::data(const QModelIndex &index, int role) const qDebug() << QString("row %1, col%2, role %3") .arg(row).arg(col).arg(role); - switch(role){ + switch (role) { case Qt::DisplayRole: if (row == 0 && col == 1) return QString("<--left"); if (row == 1 && col == 1) return QString("right-->"); @@ -86,36 +87,25 @@ QVariant MyModel::data(const QModelIndex &index, int role) const return QString("Row%1, Column%2") .arg(row + 1) .arg(col +1); - break; case Qt::FontRole: - if (row == 0 && col == 0) //change font only for cell(0,0) - { + if (row == 0 && col == 0) { //change font only for cell(0,0) QFont boldFont; boldFont.setBold(true); return boldFont; } break; case Qt::BackgroundRole: - if (row == 1 && col == 2) //change background only for cell(1,2) - { - QBrush redBackground(Qt::red); - return redBackground; - } + return QBrush(Qt::red); break; case Qt::TextAlignmentRole: - if (row == 1 && col == 1) //change text alignment only for cell(1,1) - { return Qt::AlignRight + Qt::AlignVCenter; - } break; case Qt::CheckStateRole: - if (row == 1 && col == 0) //add a checkbox to cell(1,0) - { return Qt::Checked; - } + break; } return QVariant(); } diff --git a/examples/widgets/tutorials/modelview/2_formatting/mymodel.h b/examples/widgets/tutorials/modelview/2_formatting/mymodel.h index 9c12f98ba9..e8ae673f62 100644 --- a/examples/widgets/tutorials/modelview/2_formatting/mymodel.h +++ b/examples/widgets/tutorials/modelview/2_formatting/mymodel.h @@ -57,8 +57,8 @@ class MyModel : public QAbstractTableModel { Q_OBJECT public: - MyModel(QObject *parent); - int rowCount(const QModelIndex &parent = QModelIndex()) const override ; + MyModel(QObject *parent = nullptr); + int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; }; diff --git a/examples/widgets/tutorials/modelview/3_changingmodel/main.cpp b/examples/widgets/tutorials/modelview/3_changingmodel/main.cpp index c03019a910..2330019f93 100644 --- a/examples/widgets/tutorials/modelview/3_changingmodel/main.cpp +++ b/examples/widgets/tutorials/modelview/3_changingmodel/main.cpp @@ -48,8 +48,8 @@ ** ****************************************************************************/ -#include -#include +#include +#include #include "mymodel.h" int main(int argc, char *argv[]) @@ -57,7 +57,7 @@ int main(int argc, char *argv[]) QApplication a(argc, argv); QTableView tableView; MyModel myModel(0); - tableView.setModel( &myModel ); + tableView.setModel(&myModel); tableView.show(); return a.exec(); } diff --git a/examples/widgets/tutorials/modelview/3_changingmodel/mymodel.cpp b/examples/widgets/tutorials/modelview/3_changingmodel/mymodel.cpp index e4580a0e01..f289d9abda 100644 --- a/examples/widgets/tutorials/modelview/3_changingmodel/mymodel.cpp +++ b/examples/widgets/tutorials/modelview/3_changingmodel/mymodel.cpp @@ -48,18 +48,17 @@ ** ****************************************************************************/ -#include -#include #include "mymodel.h" +#include + //! [quoting mymodel_a] MyModel::MyModel(QObject *parent) - :QAbstractTableModel(parent) + : QAbstractTableModel(parent) + , timer(new QTimer(this)) { -// selectedCell = 0; - timer = new QTimer(this); timer->setInterval(1000); - connect(timer, SIGNAL(timeout()) , this, SLOT(timerHit())); + connect(timer, &QTimer::timeout , this, &MyModel::timerHit); timer->start(); } //! [quoting mymodel_a] @@ -82,13 +81,9 @@ QVariant MyModel::data(const QModelIndex &index, int role) const int row = index.row(); int col = index.column(); - if (role == Qt::DisplayRole) - { - if (row == 0 && col == 0) - { - return QTime::currentTime().toString(); - } - } + if (role == Qt::DisplayRole && row == 0 && col == 0) + return QTime::currentTime().toString(); + return QVariant(); } //! [quoting mymodel_QVariant ] @@ -99,6 +94,6 @@ void MyModel::timerHit() //we identify the top left cell QModelIndex topLeft = createIndex(0,0); //emit a signal to make the view reread identified data - emit dataChanged(topLeft, topLeft); + emit dataChanged(topLeft, topLeft, {Qt::DisplayRole}); } //! [quoting mymodel_b ] diff --git a/examples/widgets/tutorials/modelview/3_changingmodel/mymodel.h b/examples/widgets/tutorials/modelview/3_changingmodel/mymodel.h index dfcf0f6239..2ef0e480c2 100644 --- a/examples/widgets/tutorials/modelview/3_changingmodel/mymodel.h +++ b/examples/widgets/tutorials/modelview/3_changingmodel/mymodel.h @@ -58,13 +58,12 @@ class MyModel : public QAbstractTableModel { Q_OBJECT public: - MyModel(QObject *parent); - int rowCount(const QModelIndex &parent = QModelIndex()) const override ; + MyModel(QObject *parent = nullptr); + int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - QTimer *timer; private: - int selectedCell; + QTimer *timer; private slots: void timerHit(); }; diff --git a/examples/widgets/tutorials/modelview/4_headers/main.cpp b/examples/widgets/tutorials/modelview/4_headers/main.cpp index 82d493345d..90a8c6e894 100644 --- a/examples/widgets/tutorials/modelview/4_headers/main.cpp +++ b/examples/widgets/tutorials/modelview/4_headers/main.cpp @@ -48,16 +48,16 @@ ** ****************************************************************************/ -#include -#include +#include +#include #include "mymodel.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); QTableView tableView; - MyModel myModel(0); - tableView.setModel( &myModel ); + MyModel myModel; + tableView.setModel(&myModel); tableView.show(); return a.exec(); -} \ No newline at end of file +} diff --git a/examples/widgets/tutorials/modelview/4_headers/mymodel.cpp b/examples/widgets/tutorials/modelview/4_headers/mymodel.cpp index 35e3463b7f..0084475374 100644 --- a/examples/widgets/tutorials/modelview/4_headers/mymodel.cpp +++ b/examples/widgets/tutorials/modelview/4_headers/mymodel.cpp @@ -51,7 +51,7 @@ #include "mymodel.h" MyModel::MyModel(QObject *parent) - :QAbstractTableModel(parent) + : QAbstractTableModel(parent) { } @@ -70,8 +70,7 @@ int MyModel::columnCount(const QModelIndex & /*parent*/) const //------------------------------------------------------- QVariant MyModel::data(const QModelIndex &index, int role) const { - if (role == Qt::DisplayRole) - { + if (role == Qt::DisplayRole) { return QString("Row%1, Column%2") .arg(index.row() + 1) .arg(index.column() +1); @@ -82,18 +81,14 @@ QVariant MyModel::data(const QModelIndex &index, int role) const //! [quoting mymodel_c] QVariant MyModel::headerData(int section, Qt::Orientation orientation, int role) const { - if (role == Qt::DisplayRole) - { - if (orientation == Qt::Horizontal) { - switch (section) - { - case 0: - return QString("first"); - case 1: - return QString("second"); - case 2: - return QString("third"); - } + if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { + switch (section) { + case 0: + return QString("first"); + case 1: + return QString("second"); + case 2: + return QString("third"); } } return QVariant(); diff --git a/examples/widgets/tutorials/modelview/4_headers/mymodel.h b/examples/widgets/tutorials/modelview/4_headers/mymodel.h index fb2d7aa940..6d8477dae2 100644 --- a/examples/widgets/tutorials/modelview/4_headers/mymodel.h +++ b/examples/widgets/tutorials/modelview/4_headers/mymodel.h @@ -57,8 +57,8 @@ class MyModel : public QAbstractTableModel { Q_OBJECT public: - MyModel(QObject *parent); - int rowCount(const QModelIndex &parent = QModelIndex()) const override ; + MyModel(QObject *parent = nullptr); + int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QVariant headerData(int section, Qt::Orientation orientation, int role) const override; diff --git a/examples/widgets/tutorials/modelview/5_edit/main.cpp b/examples/widgets/tutorials/modelview/5_edit/main.cpp index e1b46339b1..315875a627 100644 --- a/examples/widgets/tutorials/modelview/5_edit/main.cpp +++ b/examples/widgets/tutorials/modelview/5_edit/main.cpp @@ -48,7 +48,7 @@ ** ****************************************************************************/ -#include +#include #include "mainwindow.h" int main(int argc, char *argv[]) diff --git a/examples/widgets/tutorials/modelview/5_edit/mainwindow.cpp b/examples/widgets/tutorials/modelview/5_edit/mainwindow.cpp index e0b6ea7b1f..d8dfc33212 100644 --- a/examples/widgets/tutorials/modelview/5_edit/mainwindow.cpp +++ b/examples/widgets/tutorials/modelview/5_edit/mainwindow.cpp @@ -48,23 +48,25 @@ ** ****************************************************************************/ -#include #include "mainwindow.h" #include "mymodel.h" +#include + MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) + , tableView(new QTableView(this)) { - tableView = new QTableView(this); setCentralWidget(tableView); - QAbstractTableModel *myModel = new MyModel(this); + MyModel *myModel = new MyModel(this); tableView->setModel(myModel); //transfer changes to the model to the window title - connect(myModel, SIGNAL(editCompleted(const QString &)), this, SLOT(setWindowTitle(const QString &))); + connect(myModel, &MyModel::editCompleted, + this, &MainWindow::showWindowTitle); } -void MainWindow::showWindowTitle(const QString & title) +void MainWindow::showWindowTitle(const QString &title) { -setWindowTitle(title); + setWindowTitle(title); } diff --git a/examples/widgets/tutorials/modelview/5_edit/mainwindow.h b/examples/widgets/tutorials/modelview/5_edit/mainwindow.h index 7915b29cdf..104f06f82e 100644 --- a/examples/widgets/tutorials/modelview/5_edit/mainwindow.h +++ b/examples/widgets/tutorials/modelview/5_edit/mainwindow.h @@ -51,9 +51,9 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H -#include +#include -QT_BEGIN_NAMESPACE // QT_BEGIN_NAMESPACE / QT_END_NAMESPACE are not needed in Qt user code +QT_BEGIN_NAMESPACE class QTableView; //forward declaration QT_END_NAMESPACE @@ -64,9 +64,9 @@ class MainWindow : public QMainWindow private: QTableView *tableView; public: - MainWindow(QWidget *parent = 0); + MainWindow(QWidget *parent = nullptr); public slots: - void showWindowTitle(const QString & title); + void showWindowTitle(const QString &title); }; #endif // MAINWINDOW_H diff --git a/examples/widgets/tutorials/modelview/5_edit/mymodel.cpp b/examples/widgets/tutorials/modelview/5_edit/mymodel.cpp index fb2954baf2..eeca2ce0a0 100644 --- a/examples/widgets/tutorials/modelview/5_edit/mymodel.cpp +++ b/examples/widgets/tutorials/modelview/5_edit/mymodel.cpp @@ -48,12 +48,10 @@ ** ****************************************************************************/ - #include "mymodel.h" - MyModel::MyModel(QObject *parent) - :QAbstractTableModel(parent) + : QAbstractTableModel(parent) { } @@ -72,33 +70,31 @@ int MyModel::columnCount(const QModelIndex & /*parent*/) const //----------------------------------------------------------------- QVariant MyModel::data(const QModelIndex &index, int role) const { - if (role == Qt::DisplayRole) - { - return m_gridData[index.row()][index.column()]; - } + if (role == Qt::DisplayRole && checkIndex(index)) + return m_gridData[index.row()][index.column()]; + return QVariant(); } //----------------------------------------------------------------- //! [quoting mymodel_e] -bool MyModel::setData(const QModelIndex & index, const QVariant & value, int role) +bool MyModel::setData(const QModelIndex &index, const QVariant &value, int role) { - if (role == Qt::EditRole) - { + if (role == Qt::EditRole) { + if (!checkIndex(index)) + return false; //save value from editor to member m_gridData m_gridData[index.row()][index.column()] = value.toString(); //for presentation purposes only: build and emit a joined string QString result; - for (int row= 0; row < ROWS; row++) - { - for(int col= 0; col < COLS; col++) - { + for (int row = 0; row < ROWS; row++) { + for (int col= 0; col < COLS; col++) result += m_gridData[row][col] + ' '; - } } - emit editCompleted( result ); + emit editCompleted(result); + return true; } - return true; + return false; } //! [quoting mymodel_e] diff --git a/examples/widgets/tutorials/modelview/5_edit/mymodel.h b/examples/widgets/tutorials/modelview/5_edit/mymodel.h index dd0d4f5066..ce462351af 100644 --- a/examples/widgets/tutorials/modelview/5_edit/mymodel.h +++ b/examples/widgets/tutorials/modelview/5_edit/mymodel.h @@ -64,12 +64,12 @@ class MyModel : public QAbstractTableModel { Q_OBJECT public: - MyModel(QObject *parent); - int rowCount(const QModelIndex &parent = QModelIndex()) const override ; + MyModel(QObject *parent = nullptr); + int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) override; - Qt::ItemFlags flags(const QModelIndex & index) const override ; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + Qt::ItemFlags flags(const QModelIndex &index) const override; private: QString m_gridData[ROWS][COLS]; //holds text entered into QTableView signals: diff --git a/examples/widgets/tutorials/modelview/6_treeview/main.cpp b/examples/widgets/tutorials/modelview/6_treeview/main.cpp index e1b46339b1..315875a627 100644 --- a/examples/widgets/tutorials/modelview/6_treeview/main.cpp +++ b/examples/widgets/tutorials/modelview/6_treeview/main.cpp @@ -48,7 +48,7 @@ ** ****************************************************************************/ -#include +#include #include "mainwindow.h" int main(int argc, char *argv[]) diff --git a/examples/widgets/tutorials/modelview/6_treeview/mainwindow.cpp b/examples/widgets/tutorials/modelview/6_treeview/mainwindow.cpp index 1016afba07..ae4a343680 100644 --- a/examples/widgets/tutorials/modelview/6_treeview/mainwindow.cpp +++ b/examples/widgets/tutorials/modelview/6_treeview/mainwindow.cpp @@ -50,24 +50,25 @@ //! [Quoting ModelView Tutorial] // modelview.cpp +#include "mainwindow.h" + #include #include #include -#include "mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) + , treeView(new QTreeView(this)) + , standardModel(new QStandardItemModel(this)) { - treeView = new QTreeView(this); setCentralWidget(treeView); - standardModel = new QStandardItemModel ; - QList preparedRow =prepareRow("first", "second", "third"); + QList preparedRow = prepareRow("first", "second", "third"); QStandardItem *item = standardModel->invisibleRootItem(); // adding a row to the invisible root item produces a root element item->appendRow(preparedRow); - QList secondRow =prepareRow("111", "222", "333"); + QList secondRow = prepareRow("111", "222", "333"); // adding a row to an item starts a subtree preparedRow.first()->appendRow(secondRow); @@ -76,13 +77,11 @@ MainWindow::MainWindow(QWidget *parent) } QList MainWindow::prepareRow(const QString &first, - const QString &second, - const QString &third) + const QString &second, + const QString &third) const { - QList rowItems; - rowItems << new QStandardItem(first); - rowItems << new QStandardItem(second); - rowItems << new QStandardItem(third); - return rowItems; + return {new QStandardItem(first), + new QStandardItem(second), + new QStandardItem(third)}; } //! [Quoting ModelView Tutorial] diff --git a/examples/widgets/tutorials/modelview/6_treeview/mainwindow.h b/examples/widgets/tutorials/modelview/6_treeview/mainwindow.h index d625d5991d..65d9c18658 100644 --- a/examples/widgets/tutorials/modelview/6_treeview/mainwindow.h +++ b/examples/widgets/tutorials/modelview/6_treeview/mainwindow.h @@ -51,9 +51,9 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H -#include +#include -QT_BEGIN_NAMESPACE // QT_BEGIN_NAMESPACE / QT_END_NAMESPACE are not needed in Qt user code +QT_BEGIN_NAMESPACE class QTreeView; //forward declarations class QStandardItemModel; class QStandardItem; @@ -66,11 +66,11 @@ class MainWindow : public QMainWindow private: QTreeView *treeView; QStandardItemModel *standardModel; - QList prepareRow( const QString &first, - const QString &second, - const QString &third ); + QList prepareRow(const QString &first, + const QString &second, + const QString &third) const; public: - MainWindow(QWidget *parent = 0); + MainWindow(QWidget *parent = nullptr); }; #endif // MAINWINDOW_H diff --git a/examples/widgets/tutorials/modelview/7_selections/main.cpp b/examples/widgets/tutorials/modelview/7_selections/main.cpp index e1b46339b1..315875a627 100644 --- a/examples/widgets/tutorials/modelview/7_selections/main.cpp +++ b/examples/widgets/tutorials/modelview/7_selections/main.cpp @@ -48,7 +48,7 @@ ** ****************************************************************************/ -#include +#include #include "mainwindow.h" int main(int argc, char *argv[]) diff --git a/examples/widgets/tutorials/modelview/7_selections/mainwindow.cpp b/examples/widgets/tutorials/modelview/7_selections/mainwindow.cpp index 200751ee6d..2b10071a68 100644 --- a/examples/widgets/tutorials/modelview/7_selections/mainwindow.cpp +++ b/examples/widgets/tutorials/modelview/7_selections/mainwindow.cpp @@ -49,17 +49,18 @@ ****************************************************************************/ //! [quoting modelview_a] +#include "mainwindow.h" + #include #include #include -#include "mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) + , treeView(new QTreeView(this)) + , standardModel(new QStandardItemModel(this)) { - treeView = new QTreeView(this); setCentralWidget(treeView); - standardModel = new QStandardItemModel ; QStandardItem *rootNode = standardModel->invisibleRootItem(); @@ -88,9 +89,9 @@ MainWindow::MainWindow(QWidget *parent) treeView->expandAll(); //selection changes shall trigger a slot - QItemSelectionModel *selectionModel= treeView->selectionModel(); - connect(selectionModel, SIGNAL(selectionChanged (const QItemSelection &, const QItemSelection &)), - this, SLOT(selectionChangedSlot(const QItemSelection &, const QItemSelection &))); + QItemSelectionModel *selectionModel = treeView->selectionModel(); + connect(selectionModel, &QItemSelectionModel::selectionChanged, + this, &MainWindow::selectionChangedSlot); } //! [quoting modelview_a] @@ -103,10 +104,9 @@ void MainWindow::selectionChangedSlot(const QItemSelection & /*newSelection*/, c const QModelIndex index = treeView->selectionModel()->currentIndex(); QString selectedText = index.data(Qt::DisplayRole).toString(); //find out the hierarchy level of the selected item - int hierarchyLevel=1; + int hierarchyLevel = 1; QModelIndex seekRoot = index; - while(seekRoot.parent() != QModelIndex()) - { + while (seekRoot.parent() != QModelIndex()) { seekRoot = seekRoot.parent(); hierarchyLevel++; } diff --git a/examples/widgets/tutorials/modelview/7_selections/mainwindow.h b/examples/widgets/tutorials/modelview/7_selections/mainwindow.h index 13ca7dbc30..c9761dd3d9 100644 --- a/examples/widgets/tutorials/modelview/7_selections/mainwindow.h +++ b/examples/widgets/tutorials/modelview/7_selections/mainwindow.h @@ -51,9 +51,9 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H -#include +#include -QT_BEGIN_NAMESPACE // QT_BEGIN_NAMESPACE / QT_END_NAMESPACE are not needed in Qt user code +QT_BEGIN_NAMESPACE class QTreeView; //forward declarations class QStandardItemModel; class QItemSelection; @@ -67,7 +67,7 @@ private: QTreeView *treeView; QStandardItemModel *standardModel; private slots: - void selectionChangedSlot(const QItemSelection & newSelection, const QItemSelection & oldSelection); + void selectionChangedSlot(const QItemSelection &newSelection, const QItemSelection &oldSelection); public: MainWindow(QWidget *parent = 0); }; From 15b1c3fd9b82c8a29148c73be7aa4e8b2e07add1 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Fri, 9 Nov 2018 15:44:02 +0100 Subject: [PATCH 0296/1650] Purge some unused code for the OpenGL library name We had a global static, a setter for it (that's nowhere used within Qt code) and a getter for it whose only use was commented out. Neither was declared in any header; the getter's commented-out client had a local extern declaration at the point of (non-)use. Found while reviewing a change to the next few lines of code after the commented-out use of the getter. Change-Id: I393d56219cb7dd7cf836ca80e1bdd605a2914003 Reviewed-by: Laszlo Agocs Reviewed-by: Gatis Paeglis --- src/opengl/qgl.cpp | 19 ------------------- .../xcb_glx/qglxintegration.cpp | 2 -- 2 files changed, 21 deletions(-) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index d9f2113c14..78c2dfda7c 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -5195,25 +5195,6 @@ void QGLWidgetPrivate::cleanupColormaps() { } -Q_GLOBAL_STATIC(QString, qt_gl_lib_name) - -void qt_set_gl_library_name(const QString& name) -{ - qt_gl_lib_name()->operator=(name); -} - -const QString qt_gl_library_name() -{ - if (qt_gl_lib_name()->isNull()) { -# if defined(QT_OPENGL_ES_2) - return QLatin1String("GLESv2"); -# else - return QLatin1String("GL"); -# endif - } - return *qt_gl_lib_name(); -} - void QGLContextGroup::addShare(const QGLContext *context, const QGLContext *share) { Q_ASSERT(context && share); if (context->d_ptr->group == share->d_ptr->group) diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp index 741885e321..93cd3e215f 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp @@ -648,8 +648,6 @@ QFunctionPointer QGLXContext::getProcAddress(const char *procName) #endif { #if QT_CONFIG(library) - extern const QString qt_gl_library_name(); -// QLibrary lib(qt_gl_library_name()); QLibrary lib(QLatin1String("GL")); if (!lib.load()) lib.setFileNameAndVersion(QLatin1String("GL"), 1); From 1446cde812fc557de4e29db3d63c42a1030e5c1f Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 7 Nov 2018 21:14:01 +0100 Subject: [PATCH 0297/1650] Android: Make sure that the path is using / for separators When passing \ to Gradle it will strip these out, so by using / it ensures that it is able to find the Android SDK directory fine. Change-Id: I053f087438ade6c30d015abe00e9958beb90a947 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/tools/androiddeployqt/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp index 3b78d2487f..11213872f3 100644 --- a/src/tools/androiddeployqt/main.cpp +++ b/src/tools/androiddeployqt/main.cpp @@ -707,7 +707,7 @@ bool readInputFile(Options *options) return false; } - options->sdkPath = sdkPath.toString(); + options->sdkPath = QDir::fromNativeSeparators(sdkPath.toString()); if (options->androidPlatform.isEmpty()) { options->androidPlatform = detectLatestAndroidPlatform(options->sdkPath); From ae0dd3201bc13b81c62752bb04e42362c78bfe16 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Tue, 30 Oct 2018 17:39:05 +0100 Subject: [PATCH 0298/1650] [Micro]optimization in QStyleSheetStyle::drawComplexControl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only copy QStyleOptionSlider when needed Change-Id: I9d9d8d40fa9ed8b7be4f6a32afa8bf68f64d7836 Reviewed-by: Christian Ehrlicher Reviewed-by: Sérgio Martins --- src/widgets/styles/qstylesheetstyle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 3e397c9e04..121de548b0 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -3246,8 +3246,8 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC #if QT_CONFIG(scrollbar) case CC_ScrollBar: if (const QStyleOptionSlider *sb = qstyleoption_cast(opt)) { - QStyleOptionSlider sbOpt(*sb); if (!rule.hasDrawable()) { + QStyleOptionSlider sbOpt(*sb); sbOpt.rect = rule.borderRect(opt->rect); rule.drawBackgroundImage(p, opt->rect); baseStyle()->drawComplexControl(cc, &sbOpt, p, w); From 2393551665a6dc608aa495d032d7408bd4b38297 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 24 Oct 2018 18:05:42 +0200 Subject: [PATCH 0299/1650] Fix precision in parsing hex format QColors We document being able to parse more than 8-bit per color, but were ignoring everything after the first 8 bits. Change-Id: Ic85ab04b0836e6979a623e294eebd5084c1a9478 Fixes: QTBUG-71373 Reviewed-by: Eirik Aavitsland --- src/gui/painting/qcolor.cpp | 86 +++++++++---------- tests/auto/gui/painting/qcolor/tst_qcolor.cpp | 3 + 2 files changed, 46 insertions(+), 43 deletions(-) diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index 1d7375d1df..8271ca7016 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -54,77 +54,77 @@ QT_BEGIN_NAMESPACE /*! \internal - If s[0..1] is a valid hex number, returns its integer value, + If s[0..n] is a valid hex number, returns its integer value, otherwise returns -1. */ -static inline int hex2int(const char *s) +static inline int hex2int(const char *s, int n) { - const int hi = QtMiscUtils::fromHex(s[0]); - if (hi < 0) + if (n < 0) return -1; - const int lo = QtMiscUtils::fromHex(s[1]); - if (lo < 0) - return -1; - return (hi << 4) | lo; + int result = 0; + for (; n > 0; --n) { + result = result * 16; + const int h = QtMiscUtils::fromHex(*s++); + if (h < 0) + return -1; + result += h; + } + return result; } -/*! - \internal - If s is a valid hex digit, returns its integer value, - multiplied by 0x11, otherwise returns -1. - */ -static inline int hex2int(char s) -{ - const int h = QtMiscUtils::fromHex(s); - return h < 0 ? h : (h << 4) | h; -} - -static bool get_hex_rgb(const char *name, size_t len, QRgb *rgb) +static bool get_hex_rgb(const char *name, size_t len, QRgba64 *rgb) { if (name[0] != '#') return false; name++; --len; int a, r, g, b; - a = 255; + a = 65535; if (len == 12) { - r = hex2int(name); - g = hex2int(name + 4); - b = hex2int(name + 8); + r = hex2int(name + 0, 4); + g = hex2int(name + 4, 4); + b = hex2int(name + 8, 4); } else if (len == 9) { - r = hex2int(name); - g = hex2int(name + 3); - b = hex2int(name + 6); + r = hex2int(name + 0, 3); + g = hex2int(name + 3, 3); + b = hex2int(name + 6, 3); + r = (r << 4) | (r >> 8); + g = (g << 4) | (g >> 8); + b = (b << 4) | (b >> 8); } else if (len == 8) { - a = hex2int(name); - r = hex2int(name + 2); - g = hex2int(name + 4); - b = hex2int(name + 6); + a = hex2int(name + 0, 2) * 0x101; + r = hex2int(name + 2, 2) * 0x101; + g = hex2int(name + 4, 2) * 0x101; + b = hex2int(name + 6, 2) * 0x101; } else if (len == 6) { - r = hex2int(name); - g = hex2int(name + 2); - b = hex2int(name + 4); + r = hex2int(name + 0, 2) * 0x101; + g = hex2int(name + 2, 2) * 0x101; + b = hex2int(name + 4, 2) * 0x101; } else if (len == 3) { - r = hex2int(name[0]); - g = hex2int(name[1]); - b = hex2int(name[2]); + r = hex2int(name + 0, 1) * 0x1111; + g = hex2int(name + 1, 1) * 0x1111; + b = hex2int(name + 2, 1) * 0x1111; } else { r = g = b = -1; } - if ((uint)r > 255 || (uint)g > 255 || (uint)b > 255 || (uint)a > 255) { + if ((uint)r > 65535 || (uint)g > 65535 || (uint)b > 65535 || (uint)a > 65535) { *rgb = 0; return false; } - *rgb = qRgba(r, g ,b, a); + *rgb = qRgba64(r, g ,b, a); return true; } bool qt_get_hex_rgb(const char *name, QRgb *rgb) { - return get_hex_rgb(name, qstrlen(name), rgb); + QRgba64 rgba64; + if (!get_hex_rgb(name, qstrlen(name), &rgba64)) + return false; + *rgb = rgba64.toArgb32(); + return true; } -static bool get_hex_rgb(const QChar *str, size_t len, QRgb *rgb) +static bool get_hex_rgb(const QChar *str, size_t len, QRgba64 *rgb) { if (len > 13) return false; @@ -948,9 +948,9 @@ bool QColor::setColorFromString(String name) } if (name[0] == QLatin1Char('#')) { - QRgb rgba; + QRgba64 rgba; if (get_hex_rgb(name.data(), name.size(), &rgba)) { - setRgba(rgba); + setRgba64(rgba); return true; } else { invalidate(); diff --git a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp index ece7a30830..72bad03a6a 100644 --- a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp +++ b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp @@ -318,6 +318,9 @@ void tst_QColor::namehex_data() QTest::newRow("global color darkCyan") << "#008080" << QColor(Qt::darkCyan); QTest::newRow("global color darkMagenta") << "#800080" << QColor(Qt::darkMagenta); QTest::newRow("global color darkYellow") << "#808000" << QColor(Qt::darkYellow); + QTest::newRow("#RGB") << "#888" << QColor(0x88, 0x88, 0x88); + QTest::newRow("#RRRGGGBBB") << "#80F80F80F" << QColor(qRgba64(0x80f8, 0x80f8, 0x80f8, 0xffff)); + QTest::newRow("#RRRRGGGGBBBB") << "#808180818081" << QColor(qRgba64(0x8081, 0x8081, 0x8081, 0xffff)); QTest::newRow("transparent red") << "#66ff0000" << QColor(255, 0, 0, 102); QTest::newRow("invalid red") << "#gg0000" << QColor(); QTest::newRow("invalid transparent") << "#gg00ff00" << QColor(); From 2569a5136e72214f45f4e34f8fa2fdf5ab0dbf83 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Fri, 5 Oct 2018 18:03:51 +0200 Subject: [PATCH 0300/1650] QMimeDatabase: update freedesktop.org.xml to shared-mime-info 1.10 Including https://gitlab.freedesktop.org/xdg/shared-mime-info/commit/4f7ad5ec448d38137ddc4de5624215ba0f8ebfa9 to make appimage not ambiguous Change-Id: I8db13fc785b267c09667ef38430bf98135c7f0d6 Reviewed-by: David Faure --- .../mime/packages/freedesktop.org.xml | 4417 +++++++++++------ .../qmimedatabase/tst_qmimedatabase.cpp | 12 +- 2 files changed, 2958 insertions(+), 1471 deletions(-) diff --git a/src/corelib/mimetypes/mime/packages/freedesktop.org.xml b/src/corelib/mimetypes/mime/packages/freedesktop.org.xml index b749fe41ac..d384ffb2d5 100644 --- a/src/corelib/mimetypes/mime/packages/freedesktop.org.xml +++ b/src/corelib/mimetypes/mime/packages/freedesktop.org.xml @@ -64,20 +64,32 @@ Atari 2600 + Atari 2600 Atari 2600 + Atari 2600 Atari 2600 Atari 2600 + Atari 2600 Atari 2600 + Atari 2600 Atari 2600 Atari 2600 + Atari 2600 אטארי 2600 + Atari 2600 Atari 2600 + Atari 2600 + Atari 2600 Atari 2600 Atari 2600 + Atari 2600 Atari 2600 Atari 2600 Atari 2600 Atari 2600 + Атари 2600 + Atari 2600 + Atari 2600 Atari 2600 雅达利 2600 Atari 2600 @@ -86,20 +98,32 @@ Atari 7800 + Atari 7800 Atari 7800 + Atari 7800 Atari 7800 Atari 7800 + Atari 7800 Atari 7800 + Atari 7800 Atari 7800 Atari 7800 + Atari 7800 אטארי 7800 + Atari 7800 Atari 7800 + Atari 7800 + Atari 7800 Atari 7800 Atari 7800 + Atari 7800 Atari 7800 Atari 7800 Atari 7800 Atari 7800 + Атари 7800 + Atari 7800 + Atari 7800 Atari 7800 雅达利 7800 Atari 7800 @@ -109,6 +133,35 @@ + + Atari Lynx + Atari Lynx + Atari Lynx + Atari Lynx + Atari Lynx + Atari Lynx + Atari Lynx + Atari Lynx + Atari Lynx + Atari Lynx + Atari Lynx + Atari Lynx + Atari Lynx + Atari Lynx + Atari Lynx + Atari Lynx + Atari Lynx + Atari Lynx + Atari Lynx + Atari Lynx + 雅达利 Lynx + Atari Lynx + + + + + + ATK inset شكل ATK @@ -146,7 +199,7 @@ Suplemento ATK Conjunto de entrada do ATK Inset ATK - вкладка ATK + Вкладка ATK Vložka ATK Vložka ATK Inset ATK @@ -165,6 +218,7 @@ electronic book document مستند كتاب إلكتروني + documentu de llibru electrónicu elektronnaja kniha Документ — електронна книга document de llibre electrònic @@ -181,7 +235,7 @@ leabhar leictreonach documento de libro electrónico מסמך מסוג ספר אלקטרוני - dokument elektroničke knjige + Dokument elektroničke knjige elektronikus könyvdokumentum Documento de libro electronic dokumen buku elektronik @@ -198,7 +252,7 @@ documento de livro eletrónico Documento de livro eletrônico document carte electronică - электронная книга + Электронная книга Dokument elektronickej knihy dokument elektronske knjige Dokument libri elektronik @@ -224,6 +278,7 @@ Adobe Illustrator document مستند أدوبي المصور + Documentu d'Adobe Illustrator Dakument Adobe Illustrator Документ — Adobe Illustrator document d'Adobe Illustrator @@ -244,7 +299,7 @@ Adobe Illustrator dokument Adobe Illustrator-dokumentum Documento Adobe Illustrator - Dokumen Adobe Illustrator + dokumen Adobe Illustrator Documento Adobe Illustrator Adobe Illustrator ドキュメント Adobe Illustrator-ის დოკუმენტი @@ -261,11 +316,11 @@ documento Adobe Illustrator Documento do Adobe Illustrator Document Adobe Illustrator - документ Adobe Illustrator + Документ Adobe Illustrator Dokument Adobe Illustrator Dokument Adobe Illustrator Dokument Adobe Illustrator - документ Адобе Илустратора + документ Адобе илустратора Adobe Illustrator-dokument Adobe Illustrator belgesi документ Adobe Illustrator @@ -274,10 +329,12 @@ Adobe Illustrator 文件 + Macintosh BinHex-encoded file ملف Macintosh BinHex مشفر + Ficheru codificáu en BinHex de Machintosh Macintosh BinHex-kodlanmış fayl Fajł Macintosh, BinHex-zakadavany Файл — кодиран във формат BinHex за Macintosh @@ -297,10 +354,10 @@ comhad ionchódaithe le Macintosh BinHex ficheiro de Macintosh codificado con BinHex קובץ בקידוד Macintosh BinHex - Macintosh BinHex-kodirana datoteka + Macintosh BinHex-kôdirana datoteka Macintosh BinHex kódolású fájl File codificate in BinHex de Macintosh - Berkas tersandi Macintosh BinHex + berkas tersandi Macintosh BinHex File Macintosh codificato BinHex Macintosh BinHex エンコードファイル Macintosh BinHex кодталған файлы @@ -316,7 +373,7 @@ ficheiro codificado em BinHex de Macintosh Arquivo do Macintosh codificado com BinHex Fișier codat Macintosh BinHex - файл (закодированный Macintosh BinHex) + Файл (закодированный Macintosh BinHex) Súbor kódovaný pomocou Macintosh BinHex Kodirana datoteka Macintosh (BinHex) File Macintosh i kodifikuar BinHex @@ -393,6 +450,7 @@ MathML document مستند MathML + Documentu MathML MathML sənədi Dakument MathML Документ — MathML @@ -415,7 +473,7 @@ MathML dokument MathML-dokumentum Documento MathML - Dokumen MathML + dokumen MathML Documento MathML MathML ドキュメント MathML-ის დოკუმენტი @@ -432,7 +490,7 @@ documento MathML Documento do MathML Document MathML - документ MathML + Документ MathML Dokument MathML Dokument MathML Dokument MathML @@ -469,7 +527,7 @@ comhad bhosca poist ficheiro de caixa de correo קובץ תיבת-דואר - datoteka poštanskog sandučića + Datoteka poštanskog sandučića mailbox fájl File de cassa postal berkas kotak surat @@ -487,7 +545,7 @@ ficheiro de caixa de correio Arquivo de caixa de correio fișier căsuță poștală - файл почтового ящика + Файл почтового ящика Súbor mailbox datoteka poštnega predala File mailbox @@ -496,7 +554,7 @@ posta kutusu dosyası файл поштової скриньки tập tin hộp thư - mailbox 文件 + 邮箱文件 郵箱檔 @@ -508,6 +566,7 @@ Metalink file ملف ميتالنك + Ficheru d'enllaz meta Изтегляне — Metalink fitxer Metalink soubor metalink @@ -527,7 +586,7 @@ Datoteka meta poveznice Metalink fájl File Metalink - Berkas Metalink + berkas Metalink File Metalink Metalink ファイル Metalink файлы @@ -540,14 +599,14 @@ ficheiro Metalink Arquivo Metalink Fișier Metalink - файл Metalink + Файл Metalink Súbor Metalink Datoteka povezave Metalink датотека метавезе Metalink-fil Metalink dosyası файл метапосилання - 元链接文件 + Metalink 文件 Metalink 檔案 @@ -559,6 +618,7 @@ Metalink file ملف ميتالنك + Ficheru d'enllaz meta Изтегляне — Metalink fitxer Metalink soubor metalink @@ -578,7 +638,7 @@ Datoteka meta poveznice Metalink fájl File Metalink - Berkas Metalink + berkas Metalink File Metalink Metalink ファイル Metalink файлы @@ -591,14 +651,14 @@ ficheiro Metalink Arquivo Metalink Fișier Metalink - файл Metalink + Файл Metalink Súbor Metalink Datoteka povezave Metalink датотека метавезе Metalink-fil Metalink dosyası файл метапосилання - 元链接文件 + Metalink 文件 Metalink 檔案 @@ -610,12 +670,13 @@ unknown مجهول + desconozse nieviadomy Неизвестен тип desconegut neznámý ukendt - Unbekannt + unbekannt Άγνωστο unknown nekonate @@ -627,7 +688,7 @@ anaithnid descoñecido לא ידוע - nepoznato + Nepoznato ismeretlen incognite tak diketahui @@ -647,7 +708,7 @@ desconhecido Desconhecido necunoscut - неизвестно + Неизвестно Neznámy neznano Nuk njihet @@ -658,10 +719,10 @@ không rõ 未知 不明 - Partially downloaded file + Ficheru baxáu parcialmente fitxer baixat parcialment částečně stažený soubor Delvist hentet fil @@ -672,6 +733,7 @@ Partzialki deskargatutako fitxategia Osittain ladattu tiedosto fichier partiellement téléchargé + Comhad leath-íoslódáilte Ficheiro descargado parcialmente קובץ שהתקבל חלקית Djelomično preuzeta datoteka @@ -692,7 +754,7 @@ Delvis hämtad fil Kısmen indirilmiş dosya частково отриманий файл - 下载的部分文件 + 部分下载的文件 已部份下載的檔案 @@ -702,6 +764,7 @@ ODA document مستند ODA + Documentu ODA ODA sənədi Dakument ODA Документ — ODA @@ -741,7 +804,7 @@ documento ODA Documento ODA Document ODA - документ ODA + Документ ODA Dokument ODA Dokument ODA Dokument ODA @@ -759,6 +822,7 @@ WWF document + Documentu WWF Документ — WWF document WWF dokument WWF @@ -771,6 +835,7 @@ WWF dokumentua WWF-asiakirja document WWF + cáipéis WWF documento de WWF מסמך WWF WWF dokument @@ -788,7 +853,7 @@ Dokument WWF documento WWF Documento WWF - документ WWF + Документ WWF Dokument WWF Dokument WWF ВВФ документ @@ -805,6 +870,7 @@ PDF document مستند PDF + Documentu PDF Dakument PDF Документ — PDF document PDF @@ -842,7 +908,7 @@ documento PDF Documento PDF Document PDF - документ PDF + Документ PDF Dokument PDF Dokument PDF Dokument PDF @@ -868,6 +934,7 @@ XSPF playlist قائمة تشغيل XSPF + Llista de reproducción XSPF Śpis piesień XSPF Списък за изпълнение — XSPF llista de reproducció XSPF @@ -885,7 +952,7 @@ seinmliosta XSPF lista de reprodución XSPF רשימת נגינה XSPF - XSPF popis za reprodukciju + XSPF popis izvođenja XSPF-lejátszólista Lista de selection XSPF Senarai pular XSPF @@ -903,7 +970,7 @@ lista de reprodução XSPF Lista de reprodução XSPF Listă XSPF - список воспроизведения XSPF + Список воспроизведения XSPF Zoznam skladieb XSPF Seznam predvajanja XSPF Listë titujsh XSPF @@ -929,11 +996,12 @@ Microsoft Windows theme pack حزمة سمات Microsoft Works + Paquete de temes de Microsoft Windows Пакет с тема — Microsoft Windows paquet de temes de Microsoft Windows balík motivů Microsoft Windows Microsoft Windows-temapakke - Themenpaket für Microsoft Windows + Microsoft-Windows-Themenpaket Πακέτο θέματος Microsoft Windows Microsoft Windows theme pack paquete de tema para Microsoft Windows @@ -961,7 +1029,7 @@ pacote de tema Microsoft Windows Pacote de temas do Microsoft Windows Pachet de teme Microsoft Windows - пакет темы Microsoft Windows + Пакет темы Microsoft Windows Balík tém Microsoft Windows Datoteka teme Microsoft Windows пакет теме Мајкрософт Виндоуза @@ -976,6 +1044,7 @@ AmazonMP3 download file + Ficheru de descarga AmazonMP3 fitxer baixat d'AmazonMP3 soubor stahování AmazonMP3 AmazonMP3-downloadfil @@ -985,6 +1054,7 @@ archivo de descarga de AmazonMP3 AmazonMP3 deskarga fitxategia fichier téléchargé AmazonMP3 + comhad íoslódáilte AmazonMP3 Ficheiro de descarga de AmazonMP3 קובץ הורדת AmazonMP3 AmazonMP3 preuzeta datoteka @@ -1000,7 +1070,7 @@ Pobrany plik AmazonMP3 ficheiro transferido AmazonMP3 Arquivo de download AmazonMP3 - файл загрузки AmazonMP3 + Файл загрузки AmazonMP3 Stiahnutý súbor AmazonMP3 Datoteka prenosa AmazonMP3 датотека преузимања АмазонаМП3 @@ -1014,6 +1084,7 @@ GSM 06.10 audio GSM 06.10 سمعي + Audiu GSM 6.10 Аудио — GSM 06.10 àudio de GSM 06.10 zvuk GSM 06.10 @@ -1029,7 +1100,7 @@ fuaim GSM 06.10 son de GSM 06.10 שמע GSM 06.10 - GSM 06.10 audio + GSM 06.10 zvučni zapis GSM 06.10 hang Audio GSM 06.10 Audio GSM 06.10 @@ -1046,7 +1117,7 @@ áudio GSM 06.10 Áudio GSM 06.10 GSM 06.10 audio - аудио GSM 06.10 + Аудио GSM 06.10 Zvuk GSM 06.10 Zvočna datoteka GSM 06.10 ГСМ 06.10 звук @@ -1063,6 +1134,7 @@ iRiver Playlist قائمة تشغيل iRiver + Llista de reproducción iRiver Śpis piesień iRiver Списък за изпълнение — iRiver llista de reproducció iRiver @@ -1080,7 +1152,7 @@ seinmliosta iRiver lista de reprodución de iRiver רשימת נגינה של iRiver - iRiver popis za reprodukciju + iRiver popis izvođenja iRiver lejátszólista Lista de selection iRiver iRiver Playlist @@ -1098,7 +1170,7 @@ lista de reprodução iRiver Lista de reprodução do iRiver Listă iRiver - список воспроизведения iRiver + Список воспроизведения iRiver Zoznam skladieb iRiver Seznam predvajanja iRiver Listë titujsh iRiver @@ -1117,6 +1189,7 @@ PGP/MIME-encrypted message header ترويسة رسالة PGP/MIME-مشفرة + Testera de mensaxe cifrada en PGP/MIME Zahałovak paviedamleńnia, zašyfravany ŭ PGP/MIME Заглавна част на шифрирано съобщение — PGP/MIME capçalera de missatge amb xifrat PGP/MIME @@ -1153,7 +1226,7 @@ cabeçalho de mensagem encriptada com PGP/MIME Cabeçalho de mensagem criptografada PGP/MIME Antet de mesaj encriptat PGP/MIME - заголовок сообщения, зашифрованный PGP/MIME + Заголовок сообщения, зашифрованный PGP/MIME Hlavičke správy zašifrovaná pomocou PGP/MIME Datoteka glave šifriranega sporočila PGP/MIME Header mesazhi të kriptuar PGP/MIME @@ -1177,6 +1250,7 @@ PGP keys مفاتيح PGP + Claves PGP PGP açarları Klučy PGP Ключове — PGP @@ -1215,7 +1289,7 @@ chaves PGP Chaves PGP Chei PGP - ключи PGP + Ключи PGP Kľúče PGP Datoteka ključa PGP Kyçe PGP @@ -1252,7 +1326,7 @@ signatura OpenPGP abstreta oddělený podpis OpenPGP frigjort OpenPGP-signatur - Isolierte OpenPGP-Signatur + isolierte OpenPGP-Signatur Αποκομμένη υπογραφή OpenPGP detached OpenPGP signature dekroĉa OpenPGP-subskribo @@ -1264,7 +1338,7 @@ síniú OpenPGP scartha sinatura de OpenPGP independente חתימת OpenPGP מנותקת - odvojen OpenPGP potpis + Odvojen OpenPGP potpis leválasztott OpenPGP-aláírás Signatura OpenPGP distachate tanda tangan OpenPGP yang terlepas @@ -1283,7 +1357,7 @@ assinatura OpenPGP solta Assinatura OpenPGP destacada semnătură OpenPGP detașată - отсоединённая подпись OpenPGP + Отсоединённая подпись OpenPGP Oddelený podpis OpenPGP odpet podpis OpenPGP Firmë e shkëputur OpenPGP @@ -1307,6 +1381,7 @@ PKCS#7 Message or Certificate + Mensaxe o certificáu PKCS#7 missatge o certificat PKCS#7 zpráva nebo certifikát PKCS#7 PKCS#7-besked eller certifikat @@ -1317,6 +1392,7 @@ PKCS#7 mezu edo zertifikazioa PKCS#7-viesti tai -varmenne Message ou certificat PKCS#7 + Teachtaireacht nó Teastas PKCS#7 Mensaxe ou certificado PKCS#7 הודעה או אישור מסוג PKCS#7 PKCS#7 poruka ili vjerodajnica @@ -1332,7 +1408,7 @@ Wiadomość lub certyfikat PKCS#7 Mensagem ou certificado PKCS#7 Certificado ou Mensagem PKCS#7 - сообщение или сертификат PKCS#7 + Сообщение или сертификат PKCS#7 Správa alebo certifikát PKCS#7 Sporočilo ali dovoljenje PKCS#7 ПКЦС#7 порука или уверење @@ -1355,7 +1431,7 @@ signatura S/MIME abstreta oddělený podpis S/MIME frigjort S/MIME-signatur - Isolierte S/MIME-Signatur + isolierte S/MIME-Signatur Αποκομμένη υπογραφή S/MIME detached S/MIME signature dekroĉa S/MIME-subskribo @@ -1367,7 +1443,7 @@ síniú S/MIME scartha sinatura S/MIME independente חתימת S/MIME מנותקת - odvojen S/MIME potpis + Odvojen S/MIME potpis leválasztott S/MIME-aláírás Signatura S/MIME distachate tanda tangan S/MIME yang terlepas @@ -1386,7 +1462,7 @@ assinatura S/MIME solta Assinatura S/MIME destacada semnătură S/MIME detașată - отсоединённая подпись S/MIME + Отсоединённая подпись S/MIME Oddelený podpis S/MIME odpet podpis S/MIME Firmë e shkëputur S/MIME @@ -1437,7 +1513,7 @@ chave privada PKCS#8 Chave privada PKCS#8 Cheie privată PKCS#8 - личный ключ PKCS#8 + Личный ключ PKCS#8 Súkromný kľúč PKCS#8 Datoteka osebnega ključa PKCS#8 ПКЦС#8 лични кључ @@ -1450,6 +1526,12 @@ Public-Key Cryptography Standards + + PKCS#8 private key (encrypted) + PKCS + Public-Key Cryptography Standards + + PKCS#10 certification request طلب شهادة PKCS#10 @@ -1487,7 +1569,7 @@ pedido de certificação PKCS#10 Pedido de certificação PKCS#12 Cerere de certificat PKCS#10 - запрос сертификации PKCS#10 + Запрос сертификации PKCS#10 Požiadavka na certifikát PKCS#10 Datoteka potrdila PKCS#10 Kërkesë çertifikimi PKCS#10 @@ -1506,6 +1588,7 @@ X.509 certificate شهادة X.509 + Certificáu X.509 Сертификат — X.509 certificat X.509 certifikát X.509 @@ -1521,7 +1604,7 @@ teastas X.509 Certificado X.509 אישור X.509 - X.509 certifikat + X.509 vjerodajnica X.509 tanúsítvány Certificato X.509 Sertifikat X.509 @@ -1537,7 +1620,7 @@ certificado X.509 Certificado X.509 Certificat X.509 - сертификат X.509 + Сертификат X.509 Certifikát X.509 Datoteka potrdila X.509 Икс.509 уверење @@ -1551,6 +1634,7 @@ Certificate revocation list قائمة إبطال الشهادات + Llistáu de revocación de certificaos Списък с отхвърлени сертификати llista de revocació de certificats seznam odvolaných certifikátů @@ -1563,10 +1647,10 @@ Varmenteiden sulkulista Prógv afturtøkulisti liste de révocation de certificat - liosta teastas cúlghairmthe + Liosta teastas cúlghairmthe lista de certificados de revogación רשימת אישורים מבוטלים - popis povučenih certifikata + Popis opozvanih vjerodajnica Tanúsítvány-visszavonási lista Lista de revocation de certificatos Daftar pencabutan sertificat (CRL) @@ -1596,6 +1680,7 @@ PkiPath certification path مسار شهادة PkiPath + Camín de certificación PkiPath Сертификационна верига — PkiPath camí cap a la certificació PkiPath cesta k certifikátu PkiPath @@ -1627,7 +1712,7 @@ caminho de certificação PkiPath Pedido de certificação PkiPath Cale certificare PkiPath - путь сертификации PkiPath + Путь сертификации PkiPath Cesta k certifikátu PkiPath Datoteka poti potrdila PkiPath путања уверења ПкиПат-а @@ -1642,6 +1727,7 @@ PS document مستند PS + Documentu PS Dakument PS Документ — PS document PS @@ -1677,7 +1763,7 @@ documento PS Documento PS Document PS - документ PS + Документ PS Dokument PS Dokument PS Dokument PS @@ -1701,6 +1787,7 @@ Plucker document مستند Plucker + Documentu Plucker Dakument Plucker Документ — Plucker document Plucker @@ -1736,7 +1823,7 @@ documento Plucker Documento do Plucker Document Plucker - документ Plucker + Документ Plucker Dokument Plucker Dokument Plucker Dokument Plucker @@ -1754,20 +1841,32 @@ RAML document + Documentu RAML document RAML + dokument RAML RAML-dokument RAML-Dokument + RAML document documento RAML + RAML dokumentua RAML-asiakirja document RAML + cáipéis RAML מסמך RAML + RAML dokument RAML dokumentum + dokumen RAML + Documento RAML RAML құжаты RAML 문서 + Document RAML Dokument RAML Documento RAML - документ RAML + Документ RAML Dokument RAML + РАМЛ документ + RAML-dokument + RAML belgesi документ RAML RAML 文档 RAML 文件 @@ -1831,6 +1930,7 @@ RTF document مستند RTF + Documentu RTF Dakument RTF Документ — RTF document RTF @@ -1866,7 +1966,7 @@ documento RTF Documento RTF Document RTF - документ RTF + Документ RTF Dokument RTF Dokument RTF Dokument RTF @@ -1902,7 +2002,7 @@ Sieve posta-iragazki script-a Sieve-postinsuodatuskomentotiedosto script de filtrage de courriel Sieve - script scagaire phost Sieve + script scagaire r-phost Sieve Script de filtro de correo Sieve תסריט סינון דואר של Sieve Sieve skripta filtriranja pošte @@ -1923,7 +2023,7 @@ Script de filtragem de correio Sieve Script de filtro de mensagens do Sieve Script filtrare email Sieve - сценарий почтового фильтра Sieve + Сценарий почтового фильтра Sieve Skript poštového filtra Sieve Skriptna datoteka Sieve poštnega filtra Script filtrim poste Sieve @@ -1941,6 +2041,7 @@ SMIL document مستند SMIL + Documentu SMIL Dakument SMIL Документ — SMIL document SMIL @@ -1976,7 +2077,7 @@ documento SMIL Documento SMIL Document SMIL - документ SMIL + Документ SMIL Dokument SMIL Dokument SMIL Dokument SMIL @@ -2022,7 +2123,7 @@ seinmliosta WPL lista de reprodución WPL רשימת נגינה WPL - WPL popis za reprodukciju + WPL popis izvođenja WPL-lejátszólista Lista de selection WPL Senarai putar WPL @@ -2038,7 +2139,7 @@ lista de reprodução WPL Lista de reprodução do WPL Listă redare WPL - список воспроизведения WPL + Список воспроизведения WPL Zoznam skladieb WPL Seznam predvajanja WPL ВПЛ списак нумера @@ -2094,7 +2195,7 @@ base de dados SQLite2 Banco de dados SQLite2 Bază de date SQLite2 - база данных SQLite2 + База данных SQLite2 Databáza SQLite2 Podatkovna zbirka SQLite2 Bazë me të dhëna SQLite2 @@ -2105,11 +2206,12 @@ Cơ sở dữ liệu SQLite2 SQLite2 数据库 SQLite2 資料庫 + - + SQLite3 database قاعدة بيانات SQLite3 Baza źviestak SQLite3 @@ -2147,7 +2249,7 @@ base de dados SQLite3 Banco de dados SQLite3 Bază de date SQLite3 - база данных SQLite3 + База данных SQLite3 Databáza SQLite3 Podatkovna zbirka SQLite3 Bazë me të dhëna SQLite3 @@ -2158,9 +2260,11 @@ Cơ sở dữ liệu SQLite3 SQLite3 数据库 SQLite3 資料庫 + + GEDCOM family history @@ -2189,7 +2293,7 @@ GEDCOM 家系図データ GEDCOM ოჯახის ისტორია GEDCOM отбасы тарихы - GEDCOM 가족 내력 + GEDCOM 패밀리 기록 GEDCOM šeimos istorija GEDCOM ģimenes vēsture GEDCOM-familiehistorikk @@ -2200,7 +2304,7 @@ história familiar GEDCOM Histórico familiar do GEDCOM Tablou genealogic GEDCOM - история семьи GEDCOM + История семьи GEDCOM Rodokmeň GEDCOM Datoteka družinske zgodovine GEDCOM Kronollogji familje GEDCOM @@ -2224,6 +2328,7 @@ Flash video Flash مرئي + Videu en Flash Videa Flash Видео — Flash vídeo de Flash @@ -2241,7 +2346,7 @@ físeán Flash vídeo Flash וידאו של פלאש - Flash video + Flash video snimka Flash videó Video Flash Video Flash @@ -2260,7 +2365,7 @@ vídeo Flash Vídeo Flash Video Flash - видео Flash + Видео Flash Video Flash Video datoteka Flash Video Flash @@ -2269,7 +2374,7 @@ Flash video відеокліп Flash Ảnh động Flash - Flash 影片 + Flash 视频 Flash 視訊 @@ -2282,6 +2387,7 @@ JavaFX video + Videu en JavaFX Видео — JavaFX vídeo de JavaFX video JavaFX @@ -2298,7 +2404,7 @@ físeán JavaFX vídeo JavaFX וידאו JavaFX - JavaFX video + JavaFX video snimka JavaFX videó Video JavaFX Video JavaFX @@ -2313,7 +2419,7 @@ vídeo JavaFX Vídeo JavaFX Video JavaFX - видео JavaFX + Видео JavaFX Video JavaFX Video JavaFX ЈаваФИкс видео @@ -2367,7 +2473,7 @@ gravação SGF Gravação SGF Înregistrare SGF - запись SGF + Запись SGF Záznam SGF Datoteka shranjene igre SGF Regjistrim SGF @@ -2388,9 +2494,10 @@ - + XLIFF translation file ملف ترجمة XLIFF + Ficheru de traducciones XLIFF Fajł pierakładu XLIFF Превод — XLIFF fitxer de traducció XLIFF @@ -2404,7 +2511,7 @@ XLIFF-käännöstiedosto XLIFF týðingarfíla fichier de traduction XLIFF - comhad aistrithe XLIFF + comhad aistriúcháin XLIFF ficheiro de tradución XLIFF קובץ תרגום CLIFF XLIFF datoteka prijevoda @@ -2425,7 +2532,7 @@ ficheiro de tradução XLIFF Arquivo de tradução XLIFF Fișier de traducere XLIFF - файл перевода XLIFF + Файл перевода XLIFF Súbor prekladu XLIFF Datoteka prevoda XLIFF File përkthimesh XLIFF @@ -2434,7 +2541,7 @@ XLIFF çeviri dosyası файл перекладу XLIFF Tập tin dịch XLIFF - XLIFF 消息翻译文件 + XLIFF 翻译文件 XLIFF 翻譯檔 XLIFF XML Localization Interchange File Format @@ -2446,10 +2553,12 @@ + YAML document مستند YAML + Documentu YAML Документ — YAML document YAML dokument YAML @@ -2482,7 +2591,7 @@ documento YAML Documento YAML Document YAML - документ YAML + Документ YAML Dokument YAML Dokument YAML ЈАМЛ документ @@ -2506,6 +2615,7 @@ Corel Draw drawing تصميم Corel Draw + Dibuxu de Corel Draw Corel Draw çəkimi Rysunak Corel Draw Чертеж — Corel Draw @@ -2533,7 +2643,7 @@ Corel Draw ドロー Corel Draw-ის ნახაზი Corel Draw суреті - Corel Draw 드로잉 + 코렐 드로우 드로잉 Corel Draw piešinys Corel Draw zīmējums Lukisan Corel Draw @@ -2545,16 +2655,16 @@ desenho Corel Drawdesenho Corel Draw Desenho do Corel Draw Desen Corel Draw - изображение Corel Draw + Рисунок Corel Draw Kresba Corel Draw Datoteka risbe Corel Draw Vizatim Corel Draw - Корел Дров цртеж + Корелов цртеж Corel Draw-teckning Corel Draw çizimi малюнок Corel Draw Bản vẽ Corel Draw - Corel Draw 图形 + Corel Draw 绘图 Corel Draw 繪圖 @@ -2572,6 +2682,7 @@ HPGL file ملف HPGL + Ficheru HPGL Fajł HPGL Файл — HPGL fitxer HPGL @@ -2607,7 +2718,7 @@ ficheiro HPGL Arquivo HPGL Fișier HPGL - файл HPGL + Файл HPGL Súbor HPGL Datoteka HPGL File HPGL @@ -2626,6 +2737,7 @@ PCL file ملف PCL + FIcheru PCL Fajł PCL Файл — PCL fitxer PCL @@ -2661,7 +2773,7 @@ ficheiro PCL Arquivo PCL Fișier PCL - файл PCL + Файл PCL Súbor PCL Datoteka PCL File PCL @@ -2680,6 +2792,7 @@ Lotus 1-2-3 spreadsheet جدول Lotus 1-2-3 + Fueya de cálculu de Lotus 1-2-3 Lotus 1-2-3 hesab cədvəli Raźlikovy arkuš Lotus 1-2-3 Таблица — Lotus 1-2-3 @@ -2718,7 +2831,7 @@ folha de cálculo Lotus 1-2-3 Planilha do Lotus 1-2-3 Foaie de calcul Lotus 1-2-3 - электронная таблица Lotus 1-2-3 + Электронная таблица Lotus 1-2-3 Zošit Lotus 1-2-3 Preglednica Lotus 1-2-3 Fletë llogaritjesh Lotus 1-2-3 @@ -2727,7 +2840,7 @@ Lotus 1-2-3 hesap tablosu ел. таблиця Lotus 1-2-3 Bảng tính Lotus 1-2-3 - Lotus 1-2-3 工作簿 + Lotus 1-2-3 电子表格 Lotus 1-2-3 試算表 @@ -2746,6 +2859,7 @@ Lotus Word Pro + Lotus Word Pro Lotus Word Pro Lotus Word Pro Lotus Word Pro @@ -2756,6 +2870,7 @@ Lotus Word Pro Lotus Word Pro Lotus Word Pro + Lotus Word Pro Lotus Word Pro Lotus Word Pro Lotus Word Pro @@ -2789,6 +2904,7 @@ JET database قاعدة بيانات JET + Base de datos JETº Baza źviestak JET База от данни — JET base de dades JET @@ -2824,7 +2940,7 @@ base de dados JET Banco de dados JET Bază de date JET - база данных JET + База данных JET Databáza JET Podatkovna zbirka JET Bazë me të dhëna JET @@ -2885,7 +3001,7 @@ arquivo Microsoft Cabinet Pacote Cabinet da Microsoft Arhivă Microsoft Cabinet - архив Microsoft Cabinet + Архив Microsoft Cabinet Archív Microsoft Cabinet Datoteka arhiva Microsoft Cabinet Мајкрософтова кабинет архива @@ -2893,7 +3009,7 @@ Microsoft Cabinet arşivi архів Cabinet Microsoft Kho lưu Cabinet Microsoft - Microsoft CAB 归档文件 + Microsoft Cabinet 归档文件 微軟 Cabinet 封存檔 @@ -2941,7 +3057,7 @@ folha de cálculo Excel Planilha do Excel Foaie de calcul Excel - электронная таблица Excel + Электронная таблица Excel Zošit Excel Razpredelnica Microsoft Excel Fletë llogaritje Excel @@ -2950,7 +3066,7 @@ Excel çalışma sayfası ел. таблиця Excel Bảng tính Excel - Microsoft Excel 工作簿 + Excel 电子表格 Excel 試算表 @@ -2981,9 +3097,10 @@ Excel gehigarria Excel-lisäosa complément Excel + breiseán Excel complemento de Excel תוסף של Excel - Excel priključak + Excel dodatak Excel bővítmény Add-in Excel Add-in Excel @@ -2998,14 +3115,14 @@ Dodatek Excel Extensão Excel Suplemento do Excel - дополнение Excel + Дополнение Excel Doplnok aplikácie Excel Vstavek Excel Екселов додатак Excel-tillägg Excel eklentisi додаток Excel - Excel 附加组件 + Excel 外接程序 Excel 增益集 @@ -3024,6 +3141,7 @@ Excel 2007 kalkulu-orri binarioa Excel 2007:n binaarinen taulukko feuille de calcul binaire Excel 2007 + scarbhileog dhénártha Excel 2007 ficheiro binario de folla de cálculo Excel 2007 גיליון נתונים בינרי של Excel 2007 Excel 2007 binarna proračunska tablica @@ -3041,14 +3159,14 @@ Binarny arkusz Excel 2007 folha de cálculo binária Excel 2007 Planilha binária do Excel 2007 - двоичная электронная таблица Excel 2007 + Двоичная электронная таблица Excel 2007 Binárny zošit Excel 2007 Binarna preglednica Excel 2007 Ексел 2007 бинарна табела Binärt Excel 2007-kalkylblad Excel 2007 ikilik çalışma sayfası бінарна електронна таблиця Excel 2007 - Excel 2007 二进制工作表 + Excel 2007 二进制电子表格 Excel 2007 二進位試算表 @@ -3093,7 +3211,7 @@ folha de cálculo Excel Planilha do Excel Foaie de calcul Excel - электронная таблица Excel + Электронная таблица Excel Zošit Excel Razpredelnica Microsoft Excel Fletë llogaritje Excel @@ -3102,7 +3220,7 @@ Excel çalışma sayfası ел. таблиця Excel Bảng tính Excel - Microsoft Excel 工作簿 + Excel 电子表格 Excel 試算表 @@ -3120,6 +3238,7 @@ Excel kalkulu-orri txantiloia Excel-taulukkomalli modèle de feuille de calcul Excel + teimpléad scarbhileoige Excel תבנית גיליון נתונים של Excel Predložak Excel proračunske tablice Excel munkafüzetsablon @@ -3127,18 +3246,18 @@ Templat lembar kerja Excel Modello foglio di calcolo Excel Excel кестесінің үлгісі - 액셀 스프레드시트 양식 + Excel 스프레드시트 서식 Modèl de fuèlh de calcul Excel Szablon arkusza Excel modelo de folha de cálculo Excel Modelo de planilha do Excel - шаблон таблицы Excel + Шаблон таблицы Excel Šablóna tabuľky aplikácie Excel - Шаблон табеле Ексела + Екселов шаблон табеле Excel-kalkylarksmall Excel hesap tablosu şablonu шаблон електронної таблиці Excel - Microsoft Excel 工作簿模板 + Excel 电子表格模板 Excel 試算表範本 @@ -3182,16 +3301,16 @@ apresentação PowerPoint Apresentação do PowerPoint Prezentare PowerPoint - презентация PowerPoint + Презентация PowerPoint Prezentácia PowerPoint Predstavitev Microsoft PowerPoint Prezantim PowerPoint - Пауер Поинт презентација + Пауер поинт презентација PowerPoint-presentation PowerPoint sunumu презентація PowerPoint Trình diễn PowerPoint - Microsoft PowerPoint 演示文稿 + PowerPoint 演示文稿 PowerPoint 簡報 @@ -3215,9 +3334,10 @@ PowerPoint gehigarria PowerPoint-lisäosa complément PowerPoint + breiseán PowerPoint complemento de PowerPoint תוסף של PowerPoint - PowerPoint priključak + PowerPoint dodatak PowerPoint bővítmény Add-in PowerPoint Add-in PowerPoint @@ -3232,14 +3352,14 @@ Dodatek PowerPoint extensão PowerPoint Suplemento do PowerPoint - дополнение PowerPoint + Дополнение PowerPoint Doplnok aplikácie PowerPoint Vstavek PowerPoint - Пауер Поинт додатак + Пауер поинт додатак PowerPoint-tillägg PowerPoint eklentisi додаток PowerPoint - PowerPoint 附加组件 + PowerPoint 外接程序 PowerPoint 增益集 @@ -3282,16 +3402,16 @@ apresentação PowerPoint Apresentação do PowerPoint Prezentare PowerPoint - презентация PowerPoint + Презентация PowerPoint Prezentácia PowerPoint Predstavitev Microsoft PowerPoint Prezantim PowerPoint - Пауер Поинт презентација + Пауер поинт презентација PowerPoint-presentation PowerPoint sunumu презентація PowerPoint Trình diễn PowerPoint - Microsoft PowerPoint 演示文稿 + PowerPoint 演示文稿 PowerPoint 簡報 @@ -3299,6 +3419,7 @@ PowerPoint slide + Diapositiva de PowerPoint dispositiva de PowerPoint promítání PowerPoint PowerPoint-dias @@ -3309,6 +3430,7 @@ PowerPoint diapositiba PowerPoint-dia diapositive PowerPoint + sleamhnán PowerPoint שקופית של PowerPoint PowerPoint prezentacija PowerPoint dia @@ -3321,13 +3443,13 @@ Slajd PowerPoint diapositivo PowerPoint Slide do PowerPoint - слайд PowerPoint + Слайд PowerPoint Snímka aplikácie PowerPoint - Слајд Пауер Поинта + Пауер поинт слајд PowerPoint-bildspel PowerPoint sunusu слайд PowerPoint - PowerPoint 文稿 + PowerPoint 幻灯片 PowerPoint 投影片 @@ -3371,16 +3493,16 @@ apresentação PowerPoint Apresentação do PowerPoint Prezentare PowerPoint - презентация PowerPoint + Презентация PowerPoint Prezentácia PowerPoint Predstavitev Microsoft PowerPoint Prezantim PowerPoint - Пауер Поинт презентација + Пауер поинт презентација PowerPoint-presentation PowerPoint sunumu презентація PowerPoint Trình diễn PowerPoint - Microsoft PowerPoint 演示文稿 + PowerPoint 演示文稿 PowerPoint 簡報 @@ -3388,6 +3510,7 @@ PowerPoint presentation template + Plantía de presentaciones de PowerPoint plantilla de presentació de PowerPoint šablona prezentace PowerPoint PowerPoint-præsentationsskabelon @@ -3398,6 +3521,7 @@ PowerPoint aurkezpen txantiloia PowerPoint-esitysmalli modèle de présentation PowerPoint + teimpléad láithreoireachta PowerPoint תבנית מצגת PowerPoint Predložak PowerPoint prezentacije PowerPoint bemutatósablon @@ -3405,18 +3529,18 @@ Templat presentasi PowerPoint Modello presentazione PowerPoint PowerPoint презентация үлгісі - 파워포인드 프리젠테이션 양식 + PowerPoint 프리젠테이션 서식 Modèl de presentacion PowerPoint Szablon prezentacji PowerPoint modelo de apresentação PowerPoint Modelo de apresentação do PowerPoint - шаблон презентации PowerPoint + Шаблон презентации PowerPoint Šablóna prezentácie aplikácie PowerPoint - Шаблон презентације Пауер Поинта + Шаблон презентације Пауер поинта PowerPoint-presentationsmall PowerPoint sunum şablonu шаблон презентації PowerPoint - Microsoft PowerPoint 演示文稿模板 + PowerPoint 演示文稿模板 PowerPoint 簡報範本 @@ -3434,6 +3558,7 @@ Office Open XML Visio marrazkia Office Open XML Visio -piirros dessin Visio Office Open XML + Líníocht Office Open XML Visio ציור Visio ב־Open XML מבית Office Office Open XML Visio crtež Office Open XML Visio rajz @@ -3445,13 +3570,13 @@ Rysunek Office Open XML Visio desenho Office Open XML Visio Desenho do Visio em Office Open XML - схема Visio формата Office Open XML + Рисунок Visio формата Office Open XML Kresba aplikácie Visio Office Open XML - Офис опен ИксМЛ Визио цртање + Офисов отворени ИксМЛ Визио цртеж Office Open XML Visio-teckning Office Open XML Visio Çizimi схема VIisio у форматі Office Open XML - OOXML Visio 绘图 + Office Open XML Visio 绘图 Office Open XML Visio 繪圖 @@ -3469,6 +3594,7 @@ Office Open XML Visio txantiloia Office Open XML Visio -malli modèle Visio Office Open XML + Teimpléad Office Open XML Visio תבנית Visio ב־Open XML מבית Office Predložak Office Open XML Visio Office Open XML Visio sablon @@ -3476,17 +3602,17 @@ Templat Visio Office Open XML Modello Visio Office Open XML Office Open XML Visio үлгісі - 오피스 오픈 XML 비지오 양식 + 오피스 오픈 XML 비지오 서식 Szablon Office Open XML Visio modelo Office Open XML Visio Modelo do Visio em Office Open XML - шаблон Visio формата Office Open XML + Шаблон Visio формата Office Open XML Šablóna aplikácie Visio Office Open XML - Офис опен ИксМЛ Визио шаблон + Офисов отворени ИксМЛ Визио шаблон Office Open XML Visio-mall Office Open XML Visio Şablonu шаблон Visio у форматі Office Open XML - OOXML Visio 模板 + Office Open XML Visio 模板 Office Open XML Visio 範本 @@ -3500,8 +3626,10 @@ Office-Open-XML-Visio-Schablone Office Open XML Visio Stencil esténcil en OOXML de Visio + Office Open XML Visio txantiloia Office Open XML Visio -kaavio stencil Visio Office Open XML + Stionsal Office Open XML Visio דגם ל־Visio ב־Open XML מבית Office Office Open XML Visio šablona Office Open XML Visio stencil @@ -3513,13 +3641,13 @@ Wzór Office Open XML Visio Stencil Office Open XML Visio Estêncil do Visio em Office Open XML - трафарет Visio формата Office Open XML + Трафарет Visio формата Office Open XML Objekt aplikácie Visio Office Open XML - Офис опен ИксМЛ Визио шаблон + Офисов отворени ИксМЛ Визио шаблон Office Open XML Visio-stencil Office Open XML Visio Kalıbı трафарет Visio у форматі Office Open XML - OOXML Visio 模具 + Office Open XML Visio 模具 Office Open XML Visio 圖形樣本 @@ -3537,6 +3665,7 @@ Office Open XML Visio marrazkia Office Open XML Visio -piirros dessin Visio Office Open XML + Líníocht Office Open XML Visio ציור Visio ב־Open XML מבית Office Office Open XML Visio crtež Office Open XML Visio rajz @@ -3548,13 +3677,13 @@ Rysunek Office Open XML Visio desenho Office Open XML Visio Desenho do Visio em Office Open XML - схема Visio формата Office Open XML + Рисунок Visio формата Office Open XML Kresba aplikácie Visio Office Open XML - Офис опен ИксМЛ Визио цртање + Офисов отворени ИксМЛ Визио цртеж Office Open XML Visio-teckning Office Open XML Visio Çizimi схема VIisio у форматі Office Open XML - OOXML Visio 绘图 + Office Open XML Visio 绘图 Office Open XML Visio 繪圖 @@ -3572,6 +3701,7 @@ Office Open XML Visio txantiloia Office Open XML Visio -malli modèle Visio Office Open XML + Teimpléad Office Open XML Visio תבנית Visio ב־Open XML מבית Office Predložak Office Open XML Visio Office Open XML Visio sablon @@ -3579,17 +3709,17 @@ Templat Visio Office Open XML Modello Visio Office Open XML Office Open XML Visio үлгісі - 오피스 오픈 XML 비지오 양식 + 오피스 오픈 XML 비지오 서식 Szablon Office Open XML Visio modelo Office Open XML Visio Modelo do Visio em Office Open XML - шаблон Visio формата Office Open XML + Шаблон Visio формата Office Open XML Šablóna aplikácie Visio Office Open XML - Офис опен ИксМЛ Визио шаблон + Офисов отворени ИксМЛ Визио шаблон Office Open XML Visio-mall Office Open XML Visio Şablonu шаблон Visio у форматі Office Open XML - OOXML Visio 模板 + Office Open XML Visio 模板 Office Open XML Visio 範本 @@ -3603,8 +3733,10 @@ Office-Open-XML-Visio-Schablone Office Open XML Visio Stencil esténcil en OOXML de Visio + Office Open XML Visio txantiloia Office Open XML Visio -kaavio stencil Visio Office Open XML + Stionsal Office Open XML Visio דגם ל־Visio ב־Open XML מבית Office Office Open XML Visio šablona Office Open XML Visio stencil @@ -3616,13 +3748,13 @@ Wzór Office Open XML Visio Stencil Office Open XML Visio Estêncil do Visio em Office Open XML - трафарет Visio формата Office Open XML + Трафарет Visio формата Office Open XML Objekt aplikácie Visio Office Open XML - Офис опен ИксМЛ Визио шаблон + Офисов отворени ИксМЛ Визио шаблон Office Open XML Visio-stencil Office Open XML Visio Kalıbı трафарет Visio у форматі Office Open XML - OOXML Visio 模具 + Office Open XML Visio 模具 Office Open XML Visio 圖形樣本 @@ -3631,6 +3763,7 @@ Word document مستند Word + Documentu de Word Dakument Word Документ — Word document Word @@ -3666,16 +3799,16 @@ documento Word Documento do Word Document Word - документ Word + Документ Word Dokument Word Dokument Word Dokument Word - Вордов документ + Ворд документ Word-dokument Word belgesi документ Word Tài liệu Word - Microsoft Word 文档 + Word 文档 Word 文件 @@ -3683,6 +3816,7 @@ Word document template + Plantía de documentu de Word plantilla de document Word šablona dokumentu Word Word-dokumentskabelon @@ -3693,6 +3827,7 @@ Word dokumentuaren txantiloia Word-asiakirjamalli modèle de document Word + teimpléad Word תבנית מסמך Word Predložak Word dokumenta Word dokumentumsablon @@ -3700,18 +3835,18 @@ Templat dokumen Word Modello documento Word Word құжатының үлгісі - 워드 문서 양식 + Word 문서 서식 modèl de document Word Szablon dokumentu Word modelo de documento Word Modelo de documento do Word - шаблон документа Word + Шаблон документа Word Šablóna dokumentu aplikácie Word - Шаблон документа Ворда + Шаблон Ворд документа Word-dokumentmall Word belgesi şablonu шаблон документа Word - Microsoft Word 文档模板 + Word 文档模板 Word 文件範本 @@ -3720,6 +3855,7 @@ XPS document مستند XPS + Documentu XPS Dakument XPS Документ — XPS document XPS @@ -3755,7 +3891,7 @@ documento XPS Documento XPS Document XPS - документ XPS + Документ XPS Dokument XPS Dokument XPS Dokument XPS @@ -3773,10 +3909,12 @@ + Microsoft Works document مستند Microsoft Works + Documentu de Microsoft Works Dakument Microsoft Works Документ — Microsoft Works document de Microsoft Works @@ -3812,11 +3950,11 @@ documento Microsoft Works Documento do Microsoft Works Document Microsoft Works - документ Microsoft Works + Документ Microsoft Works Dokument Microsoft Works Dokument Microsoft Works Dokument Microsoft Works - Микрософтов Воркс документ + документ Мајкрософт Воркса Microsoft Works-dokument Microsoft Works belgesi документ Microsoft Works @@ -3833,6 +3971,7 @@ Microsoft Visio document + Documentu de Microsoft Visio Документ — Microsoft Visio document de Microsoft Visio dokument Microsoft Visio @@ -3844,6 +3983,7 @@ Microsoft Visio dokumentua Microsoft Visio -asiakirja document Microsoft Visio + cáipéis Microsoft Visio Documento de Microsoft Visio מסמך Microsoft Visio dokument @@ -3861,10 +4001,10 @@ Dokument Microsoft Visio documento Microsoft Visio Documento do Microsoft Visio - документ Microsoft Visio + Документ Microsoft Visio Dokument Microsoft Visio Dokument Microsoft Visio - Микрософтов Визио документ + документ Мајкрософт Визиа Microsoft Visio-dokument Microsoft Visio belgesi документ Microsoft Visio @@ -3880,6 +4020,7 @@ Word document مستند Word + Documentu de Word Dakument Word Документ — Word document Word @@ -3915,16 +4056,16 @@ documento Word Documento do Word Document Word - документ Word + Документ Word Dokument Word Dokument Word Dokument Word - Вордов документ + Ворд документ Word-dokument Word belgesi документ Word Tài liệu Word - Microsoft Word 文档 + Word 文档 Word 文件 @@ -3947,6 +4088,7 @@ Word template قالب Word + Plantía de Word Šablon Word Шаблон за документи — Word plantilla de Word @@ -3982,11 +4124,11 @@ modelo Word Modelo do Word Șablon Word - шаблон Word + Шаблон Word Šablóna Word Predloga dokumenta Microsoft Word Model Word - Вордов шаблон + Ворд шаблон Word-mall Word şablonu шаблон Word @@ -3999,6 +4141,7 @@ GML document + Documentu GML document GML dokument GML GML-dokument @@ -4009,6 +4152,7 @@ GML dokumentua GML-asiakirja document GML + cáipéis GML Documento GML מסמך GML GML dokument @@ -4024,7 +4168,7 @@ Dokument GML documento GML Documento GML - документ GML + Документ GML Dokument GML Dokument GML ГМЛ документ @@ -4077,7 +4221,7 @@ ficheiro de procura GNUnet Arquivo de pesquisa do GNUnet Fișier căutare GNUnet - файл поиска GNUnet + Файл поиска GNUnet Vyhľadávací súbor GNUnet Iskalna datoteka GNUnet File kërkimi GNUnet @@ -4096,6 +4240,7 @@ TNEF message رسالة TNEF + Mensaxe TNEF List TNEF Съобщение — TNEF missatge TNEF @@ -4130,7 +4275,7 @@ mensagem TNEF Mensagem TNEF Mesaj TNEF - сообщение TNEF + Сообщение TNEF Správa TNEF Datoteka sporočila TNEF Mesazh TNEF @@ -4192,16 +4337,16 @@ folha de cálculo do StarCalc Planilha do StarCalc Foaie de calcul StarCalc - электронная таблица StarCalc + Электронная таблица StarCalc Zošit StarCalc Preglednica StarCalc Fletë llogaritjesh StarCalc - Табела Стар Рачуна + Стар калк табела StarCalc-kalkylblad StarCalc çalışma sayfası ел. таблиця StarCalc Bảng tính StarCalc - STarCalc 工作簿 + StarCalc 电子表格 StarCalc 試算表 @@ -4247,7 +4392,7 @@ gráfico do StarChart Gráfico do StarChart Diagramă StarChart - диаграмма StarChart + Диаграмма StarChart Graf StarChart Datoteka grafikona StarChart Grafik StarChart @@ -4256,7 +4401,7 @@ StarChart çizgelgesi діаграма StarChart Đồ thị StarChart - STarChart 图表 + StarCalc 图表 StarChart 圖表 @@ -4302,7 +4447,7 @@ desenho do StarDraw Desenho do StarDraw Desen StarDraw - изображение StarDraw + Рисунок StarDraw Kresba StarDraw Datoteka risbe StarDraw Vizatim StarDraw @@ -4311,7 +4456,7 @@ StarDraw çizimi малюнок StarDraw Bản vẽ StarDraw - STarDraw 绘图 + StarDraw 绘图 StarDraw 繪圖 @@ -4357,7 +4502,7 @@ apresentação do StarImpress Apresentação do StarImpress Prezentare StarImpress - презентация StarImpress + Презентация StarImpress Prezentácia StarImpress Predstavitev StarImpress Prezantim StarImpress @@ -4366,7 +4511,7 @@ StarImpress sunumu презентація StarImpress Trình diễn StarImpress - STarImpress 演示文稿 + StarImpress 演示文稿 StarImpress 簡報檔 @@ -4411,7 +4556,7 @@ email do StarMail E-mail do StarMail Email StarEmail - электронное письмо StarMail + Электронное письмо StarMail E-mail StarMail Datoteka pošte StarMail Mesazh StarMail @@ -4420,7 +4565,7 @@ StarMail epostası поштове повідомлення StarMail Thư điện tử StarMail - STarMail 电子邮件 + StarMail 电子邮件 StarMail 郵件 @@ -4463,7 +4608,7 @@ fórmula do StarMath Fórmula do StarMath Formulă StarMath - формула StarMath + Формула StarMath Vzorec StarMath Datoteka formule StarMath Formulë StarMath @@ -4472,7 +4617,7 @@ StarMath formülü формула StarMath Công thức StarMath - STarMath 公式 + StarMath 公式 StarMath 公式 @@ -4480,6 +4625,7 @@ StarWriter document مستند StarWriter + Documentu de StarWriter StarWriter sənədi Dakument StarWriter Документ — StarWriter @@ -4518,7 +4664,7 @@ documento do StarWriter Documento do StarWriter Document StarWriter - документ StarWriter + Документ StarWriter Dokument StarWriter Dokument StarWriter Dokument StarWriter @@ -4527,7 +4673,7 @@ StarWriter belgesi документ StarWriter Tài liệu StarWriter - STarWriter 文档 + StarWriter 文档 StarWriter 文件 @@ -4576,7 +4722,7 @@ folha de cálculo OpenOffice Calc Planilha do OpenOffice Calc Foaie de calcul OpenOffice Calc - электронная таблица OpenOffice Calc + Электронная таблица OpenOffice Calc Zošit OpenOffice Calc Razpredelnica OpenOffice.org Calc Fletë llogaritjesh OpenOffice Calc @@ -4585,7 +4731,7 @@ OpenOffice Calc çalışma sayfası ел. таблиця OpenOffice Calc Bảng tính Calc của OpenOffice.org - OpenOffice.org Calc 工作簿 + OpenOffice Calc 电子表格 OpenOffice Calc 試算表 @@ -4636,7 +4782,7 @@ modelo OpenOffice Calc Modelo do OpenOffice Calc Șablon OpenOffice Calc - шаблон OpenOffice Calc + Шаблон OpenOffice Calc Šablóna OpenOffice Calc Predloga OpenOffice.org Calc Model OpenOffice Calc @@ -4645,7 +4791,7 @@ OpenOffice Calc şablonu шаблон ел.таблиці OpenOffice Calc Mẫu bảng tính Calc của OpenOffice.org - OpenOffice.org Calc 工作簿模板 + OpenOffice Calc 模板 OpenOffice Calc 範本 @@ -4696,7 +4842,7 @@ desenho OpenOffice Draw Desenho do OpenOffice Draw Desen OpenOffice Draw - изображение OpenOffice Draw + Рисунок OpenOffice Draw Kresba OpenOffice Draw Datoteka risbe OpenOffice.org Draw Vizatim OpenOffice Draw @@ -4705,7 +4851,7 @@ OpenOffice Draw çizimi малюнок OpenOffice Draw Bản vẽ Draw của OpenOffice.org - OpenOffice.org Draw 绘图 + OpenOffice Draw 绘图 OpenOffice Draw 繪圖 @@ -4756,7 +4902,7 @@ modelo OpenOffice Draw Modelo do OpenOffice Draw Șablon OpenOffice Draw - шаблон OpenOffice Draw + Шаблон OpenOffice Draw Šablóna OpenOffice Draw Predloga OpenOffice.org Draw Model OpenOffice Draw @@ -4765,7 +4911,7 @@ OpenOffice Draw şablonu шаблон малюнку OpenOffice Draw Mẫu bản vẽ Draw của OpenOffice.org - OpenOffice.org Draw 绘图模板 + OpenOffice Draw 模板 OpenOffice Draw 範本 @@ -4818,7 +4964,7 @@ apresentação OpenOffice Impress Apresentação do OpenOffice Impress Prezentare OpenOffice Impress - презентация OpenOffice Impress + Презентация OpenOffice Impress Prezentácia OpenOffice Impress Predstavitev OpenOffice.org Impress Prezantim OpenOffice Impress @@ -4827,7 +4973,7 @@ OpenOffice Impress sunumu презентація OpenOffice Impress Trình diễn Impress của OpenOffice.org - OpenOffice.org Impress 演示文稿 + OpenOffice Impress 演示文稿 OpenOffice Impress 簡報 @@ -4878,7 +5024,7 @@ modelo OpenOffice Impress Modelo do OpenOffice Impress Șablon OpenOffice Impress - шаблон OpenOffice Impress + Шаблон OpenOffice Impress Šablóna OpenOffice Impress Predloga OpenOffice.org Impress Model OpenOffice Impress @@ -4887,7 +5033,7 @@ OpenOffice Impress şablonu шаблон презентації OpenOffice Impress Mẫu trình diễn Impress của OpenOffice.org - OpenOffice.org Impress 演示文稿模板 + OpenOffice Impress 模板 OpenOffice Impress 範本 @@ -4938,7 +5084,7 @@ fórmula OpenOffice Math Fórmula do OpenOffice Math Formulă OpenOffice Math - формула OpenOffice Math + Формула OpenOffice Math Vzorec OpenOffice Math Dokument formule OpenOffice.org Math Formulë OpenOffice Math @@ -4947,7 +5093,7 @@ OpenOffice Math formülü формула OpenOffice Math Công thức Math của OpenOffice.org - OpenOffice.org Math 公式 + OpenOffice Math 公式 OpenOffice Math 公式 @@ -4963,6 +5109,7 @@ OpenOffice Writer document مستند Writer المكتب المفتوح + Documentu d'OpenOffice Writer OpenOffice Writer sənədi Dakument OpenOffice Writer Документ — OpenOffice Writer @@ -5000,7 +5147,7 @@ documento OpenOffice Writer Documento do OpenOffice Writer Document OpenOffice Writer - документ OpenOffice Writer + Документ OpenOffice Writer Dokument OpenOffice Writer Dokument OpenOffice.org Writer Dokument OpenOffice Writer @@ -5009,7 +5156,7 @@ OpenOffice Writer belgesi документ OpenOffice Writer Tài liệu Writer của OpenOffice.org - OpenOffice.org Writer 文档 + OpenOffice Writer 文档 OpenOffice Writer 文件 @@ -5025,6 +5172,7 @@ OpenOffice Writer global document مستند المكتب المفتوح Writer العالمي + Documentu global d'OpenOffice Writer OpenOffice Writer qlobal sənədi Hlabalny dakument OpenOffice Writer Документ - глобален — OpenOffice Writer @@ -5062,7 +5210,7 @@ documento global OpenOffice Writer Documento global do OpenOffice Writer Document global OpenOffice Writer - основной документ OpenOffice Writer + Основной документ OpenOffice Writer Globálny dokument OpenOffice Writer Splošni dokument OpenOffice.org Writer Dokument i përgjithshëm OpenOffice Writer @@ -5071,7 +5219,7 @@ OpenOffice Writer global belgesi загальний документ OpenOffice Writer Tài liệu toàn cục Writer của OpenOffice.org - OpenOffice.org Writer 全局文档 + OpenOffice Writer 全局文档 OpenOffice Writer 主控文件 @@ -5125,7 +5273,7 @@ modelo OpenOffice Writer Modelo do OpenOffice Writer Șablon OpenOffice Writer - шаблон OpenOffice Writer + Шаблон OpenOffice Writer Šablóna OpenOffice Writer Predloga OpenOffice.org Writer Model OpenOffice Writer @@ -5134,7 +5282,7 @@ OpenOffice Writer şablonu шаблон документа OpenOffice Writer Mẫu tài liệu Writer của OpenOffice.org - OpenOffice.org Writer 文档模板 + OpenOffice Writer 模板 OpenOffice Writer 範本 @@ -5150,6 +5298,7 @@ ODT document مستند ODT + Documentu ODT Dakument ODT Документ — ODT document ODT @@ -5186,7 +5335,7 @@ documento ODT Documento ODT Document ODT - документ ODT + Документ ODT Dokument ODT Dokument ODT Dokument ODT @@ -5213,6 +5362,7 @@ ODT document (Flat XML) مستند ODT (Flat XML) + Documentu ODT (XML planu) Документ — ODT (само XML) document ODT (XML pla) dokument ODT (Flat XML) @@ -5245,14 +5395,14 @@ documento ODT (XML plano) Documento ODT (Flat XML) Document ODT (XML simplu) - документ ODT (простой XML) + Документ ODT (простой XML) Dokument ODT (čisté XML) Datoteka dokumenta ODT (nepovezan XML) ОДТ документ (Обични ИксМЛ) ODT-dokument (platt XML) ODT belgesi (Düz XML) документ ODT (Flat XML) - ODT 文档(Flat XML) + ODT 文档(Flat XML) ODT 文件 (Flat XML) FODT OpenDocument Text (Flat XML) @@ -5299,7 +5449,7 @@ modelo ODT Modelo ODT Șablon ODT - шаблон ODT + Шаблон ODT Šablóna ODT Predloga dokumenta ODT Model ODT @@ -5362,7 +5512,7 @@ modelo OTH Modelo OTH Șablon OTH - шаблон OTH + Шаблон OTH Šablóna OTH Predloga OTH Model OTH @@ -5389,6 +5539,7 @@ ODM document مستند ODM + Documentu ODM Dakument ODM Документ — ODM document ODM @@ -5425,7 +5576,7 @@ documento ODM Documento ODM Document ODM - документ ODM + Документ ODM Dokument ODM Dokument ODM Dokument ODM @@ -5488,7 +5639,7 @@ desenho ODG Desenho ODG Desen ODG - изображение ODG + Рисунок ODG Kresba ODG Datoteka risbe ODG Vizatim ODG @@ -5547,14 +5698,14 @@ desenho ODG (XML plano) Desenho ODG (Flat XML) Desen ODG (XML simplu) - изображение ODG (простой XML) + Рисунок ODG (простой XML) Kresba ODG (čisté XML) Datoteka risbe ODG (nepovezan XML) ОДГ цртеж (Обичан ИксМЛ) ODG-teckning (platt XML) ODG çizimi (Düz XML) малюнок ODG (Flat XML) - ODG 绘图(Flat XML) + ODG 绘图(Flat XML) ODG 繪圖 (Flat XML) FODG OpenDocument Drawing (Flat XML) @@ -5601,7 +5752,7 @@ modelo ODG Modelo ODG Șablon ODG - шаблон ODG + Шаблон ODG Šablóna ODG Predloga dokumenta ODG Model ODG @@ -5664,7 +5815,7 @@ apresentação ODP Apresentação ODP Prezentare ODP - презентация ODP + Презентация ODP Prezentácia ODP Predstavitev ODP Prezantim ODP @@ -5723,14 +5874,14 @@ apresentação ODP (XML plano) Apresentação ODP (Flat XML) Prezentare ODP (XML simplu) - презентация ODP (простой XML) + Презентация ODP (простой XML) Prezentácia ODP (čisté XML) Predstavitev ODP (nepovezan XML) ОДП презентација (Обични ИксМЛ) ODP-presentation (platt XML) ODP sunumu (Düz XML) презентація ODP (Flat XML) - ODP 演示文稿(Flat XML) + ODP 演示文稿(Flat XML) ODP 範本 (Flat XML) FODP OpenDocument Presentation (Flat XML) @@ -5777,7 +5928,7 @@ modelo ODP Modelo ODP Șablon ODP - шаблон ODP + Шаблон ODP Šablóna ODP Predloga dokumenta ODP Model ODP @@ -5840,16 +5991,16 @@ folha de cálculo ODS Planilha ODS Foaie de calcul ODS - электронная таблица ODS + Электронная таблица ODS Zošit ODS Preglednica ODS Fletë llogaritjesh ODS - ОДС spreadsheet + ОДС табела ODS-kalkylblad ODS çalışma sayfası ел. таблиця ODS Bảng tính ODS - ODS 工作簿 + ODS 电子表格 ODS 試算表 ODS OpenDocument Spreadsheet @@ -5899,14 +6050,14 @@ folha de cálculo ODS (XML plano) Planilha ODS (Flat XML) Foaie de calcul ODS (XML simplu) - электронная таблица ODS (простой XML) + Электронная таблица ODS (простой XML) Zošit ODS (čisté XML) Preglednica ODS (nepovezan XML) - ОДС spreadsheet (Обични ИксМЛ) + ОДС табела (обични ИксМЛ) ODS-kalkylblad (platt XML) ODS sunumu (Düz XML) ел. таблиця ODS (Flat XML) - ODS 工作簿(Flat XML) + ODS 电子表格 (Flat XML) ODS 試算表 (Flat XML) FODS OpenDocument Spreadsheet (Flat XML) @@ -5953,7 +6104,7 @@ modelo ODS Modelo ODS Șablon ODS - шаблон ODS + Шаблон ODS Šablóna ODS Predloga dokumenta ODS Model ODS @@ -6015,11 +6166,11 @@ gráfico ODC Gráfico ODC Diagramă ODC - диаграмма ODC + Диаграмма ODC Graf ODC Datoteka grafikona ODC Grafik ODC - ОДЦ chart + ОДЦ график ODC-diagram ODC çizelgesi діаграма ODC @@ -6075,7 +6226,7 @@ modelo ODC Modelo ODC Șablon ODC - шаблон ODC + Шаблон ODC Šablóna ODC Predloga ODC ОДЦ шаблон @@ -6137,11 +6288,11 @@ fórmula ODF Fórmula ODF Formulă ODF - формула ODF + Формула ODF Vzorec ODF Dokument formule ODF Formulë ODF - ОДФ formula + ОДФ формула ODF-formel ODF formülü формула ODF @@ -6197,7 +6348,7 @@ modelo ODF Modelo ODF Șablon ODF - шаблон ODF + Шаблон ODF Šablóna ODF Predloga dokumenta ODF ОДФ шаблон @@ -6259,7 +6410,7 @@ base de dados ODB Banco de dados ODB Bază de date ODB - база данных ODB + База данных ODB Databáza ODB Podatkovna zbirka ODB Bazë me të dhëna ODB @@ -6287,6 +6438,7 @@ ODI image صورة ODI + Imaxe ODI Vyjava ODI Изображение — ODI imatge ODI @@ -6323,7 +6475,7 @@ imagem ODI Imagem ODI Imagine ODI - изображение ODI + Изображение ODI Obrázok ODI Slikovna datoteka ODI Figurë ODI @@ -6350,6 +6502,7 @@ OpenOffice.org extension امتداد OpenOffice.org + Estensión d'OpenOffice.org Pašyreńnie OpenOffice.org Разширение — OpenOffice extensió d'OpenOffice.org @@ -6384,7 +6537,7 @@ extensão OpenOffice.org Extensão do OpenOffice Extensie OpenOffice.org - расширение OpenOffice.org + Расширение OpenOffice.org Rozšírenie OpenOffice.org Razširitev OpenOffice.org Shtojcë për OpenOffice.org @@ -6401,6 +6554,7 @@ Android package + Paquete d'Android Пакет — Android paquet d'Android balíčky systému Android @@ -6413,6 +6567,7 @@ Android paketea Android-paketti paquet Android + pacáiste Android paquete de Android חבילת אנדרויד Android paket @@ -6430,14 +6585,14 @@ Pakiet Androida pacote Android Pacote do Android - пакет Android + Пакет Android Balík Android Paket Android Андроидов пакет Android-paket Android paketi пакунок Android - Android + Android 应用包 Android 軟體包 @@ -6445,6 +6600,7 @@ SIS package حزمة SIS + Paquete SIS Pakunak SIS Пакет — SIS paquet SIS @@ -6480,7 +6636,7 @@ pacote SIS Pacote SIS Pachet SIS - пакет SIS + Пакет SIS Balíček SIS Datoteka paketa SIS Paketë SIS @@ -6502,6 +6658,7 @@ SISX package حزمة SISX + Paquete SISX Pakunak SISX Пакет — SISX paquet SISX @@ -6537,7 +6694,7 @@ pacote SISX Pacote SISX Pachet SISX - пакет SISX + Пакет SISX Balíček SISX Datoteka paketa SISX Paketë SISX @@ -6569,6 +6726,7 @@ Sareko pakete kaptura Verkkopakettien kaappaus capture de paquet réseau + Gabháltas Paicéid Líonra Captura de Network Packet לכידה של מנות נתונים ברשת Mrežno hvatanje paketa @@ -6586,7 +6744,7 @@ Przechwycenie pakietu sieciowego captura Network Packet Pacote de captura de rede - захваченные сетевые пакеты + Захваченные сетевые пакеты Zachytené sieťové pakety Zajem omrežnih paketov Снимање мрежног пакета @@ -6608,6 +6766,7 @@ WordPerfect document مستند WordPerfect + Documentu de WordPerfect WordPerfect sənədi Dakument WordPerfect Документ — WordPerfect @@ -6646,11 +6805,11 @@ documento WordPerfect Documento do WordPerfect Document WordPerfect - документ WordPerfect + Документ WordPerfect Dokument WordPerfect Dokument WordPerfect Dokument WordPerfect - документ Ворд Перфекта + документ Ворд перфекта WordPerfect-dokument WordPerfect belgesi документ WordPerfect @@ -6671,6 +6830,12 @@ + + YouTube Media Archive + + + + SPSS Portable Data File ملف بيانات SPSS متنقلة @@ -6704,7 +6869,7 @@ ficheiro de dados portátil SPSS Arquivo de Dados Portáteis SPSS Fișier portabil de date SPSS - файл переносимых данных SPSS + Файл переносимых данных SPSS Súbor prenosných dát SPSS Prenosna podatkovna datoteka SPSS СПСС датотека преносних података @@ -6730,6 +6895,7 @@ SPSS Data File archivo de datos SPSS SPSS datuen fitxategia + SPSS-datatiedosto SPSS dátufíla fichier de données SPSS comhad sonraí SPSS @@ -6751,7 +6917,7 @@ ficheiro de dados SPSS Arquivo de dados SPSS Fișier date SPSS - файл данных SPSS + Файл данных SPSS Dátový súbor SPSS Podatkovna datoteka SPSS СПСС датотека података @@ -6788,7 +6954,7 @@ leabharmharcanna XBEL Marcadores XBEL סימניית XBEL - XBEL knjižne oznake + XBEL zabilješka XBEL-könyvjelzők Marcapaginas XBEL Bookmark XBEL @@ -6807,7 +6973,7 @@ marcadores XBEL Marcadores do XBEL Semne de carte XBEL - закладки XBEL + Закладки XBEL Záložky XBEL Datoteka zaznamkov XBEL Libërshënues XBEL @@ -6830,6 +6996,7 @@ 7-zip archive أرشيف 7-zip + Archivu 7-zip Archiŭ 7-zip Архив — 7-zip arxiu 7-zip @@ -6866,7 +7033,7 @@ arquivo 7-zip Pacote 7-Zip Arhivă 7-zip - архив 7-zip + Архив 7-zip Archív 7-zip Datoteka arhiva 7-zip Arkiv 7-zip @@ -6886,6 +7053,7 @@ AbiWord document مستند آبي وورد + Documentu d'AbiWord Dakument AbiWord Документ — AbiWord document AbiWord @@ -6923,7 +7091,7 @@ documento AbiWord Documento do AbiWord Document AbiWord - документ AbiWord + Документ AbiWord Dokument AbiWord Dokument AbiWord Dokument AbiWord @@ -6961,7 +7129,7 @@ CD irudiaren CUE orria CD-vedos cuesheet index de pistes de CD - bileog chiúáil íomhá CD + bileog chiúála íomhá CD cue sheet dunha imaxe de CD גליון נתונים לתמונת דיסק CD slika s meta podacima @@ -6982,11 +7150,11 @@ índice de CD de imagem Índice de Imagem de CD Imagine CD cuesheet - таблица содержания образа CD + Таблица содержания образа CD Rozvrhnutie stôp obrazu CD Datoteka razpredelnice odtisa CD cue Cuesheet imazhi CD - редослед слика ЦД-а + Кју лист ЦД одраза Indexblad för cd-avbild CD görüntüsü belgesi таблиця CUE образу CD @@ -7000,6 +7168,7 @@ Lotus AmiPro document مستند Lotus AmiPro + Documentu de Lotus AmiPro Lotus AmiPro sənədi Dakument Lotus AmiPro Документ — Lotus AmiPro @@ -7038,7 +7207,7 @@ documento Lotus AmiPro Documento do Lotus AmiPro Document Lotus AmiPro - документ Lotus AmiPro + Документ Lotus AmiPro Dokument Lotus AmiPro Dokument Lotus AmiPro Dokument Lotus AmiPro @@ -7055,6 +7224,7 @@ AportisDoc document مستند AportisDoc + Documentu d'AportisDoc Документ — AportisDoc document AportisDoc dokument AportisDoc @@ -7088,7 +7258,7 @@ documento AportisDoc Documento do AportisDoc Document AportisDoc - документ AportisDoc + Документ AportisDoc Dokument AportisDoc Dokument AportisDoc Апортис Док документ @@ -7147,7 +7317,7 @@ folha de cálculo Applix Spreadsheets Planilha do Applix Spreadsheets Foaie de calcul Applix - электронная таблица Applix Spreadsheets + Электронная таблица Applix Spreadsheets Zošit Applix Spreadsheets Razpredelnica Applix Spreadsheets Fletë llogaritjesh Applix Spreadsheets @@ -7156,7 +7326,7 @@ Applix Spreadsheets çalışma sayfası ел. таблиця Applix Spreadsheets Bảng tính Applix Spreadsheets - Applix Spreadsheets 工作簿 + Applix Spreadsheets 电子表格 Applix Spreadsheets 試算表 @@ -7170,6 +7340,7 @@ Applix Words document مستند كلمات Applix + Documentu d'Applix Words Applix Words sənədi Dakument Applix Words Документ — Applix Words @@ -7209,7 +7380,7 @@ documento Applix Words Documento do Applix Words Document Applix Words - документ Applix Words + Документ Applix Words Dokument Applix Words Dokument Applix Words Dokument Applix Words @@ -7267,7 +7438,7 @@ arquivo ARC Pacote ARC Arhivă ARC - архив ARC + Архив ARC Archív ARC Datoteka arhiva ARC Arkiv ARC @@ -7328,7 +7499,7 @@ arquivo AR Pacote AR Arhivă AR - архив AR + Архив AR Archív AR Datoteka arhiva AR Arkiv AR @@ -7389,7 +7560,7 @@ arquivo ARJ Pacote ARJ Arhivă ARJ - архив ARJ + Архив ARJ Archív ARJ Datoteka arhiva ARJ Arkiv ARJ @@ -7411,6 +7582,7 @@ ASP page صفحة ASP + Páxina ASP Staronka ASP Страница — ASP pàgina ASP @@ -7447,7 +7619,7 @@ página ASP Página ASP Pagină ASP - страница ASP + Страница ASP Stránka ASP Datoteka spletne strani ASP Faqe ASP @@ -7467,6 +7639,7 @@ AWK script سكربت AWK + Script AWK AWK skripti Skrypt AWK Скрипт — AWK @@ -7506,7 +7679,7 @@ script AWK Script AWK Script AWK - сценарий AWK + Сценарий AWK Skript AWK Skriptna datoteka AWK Script AWK @@ -7537,6 +7710,7 @@ BCPIO document مستند BCPIO + Documentu BCPIO BCPIO sənədi Dakument BCPIO Документ — BCPIO @@ -7576,7 +7750,7 @@ documento BCPIO Documento BCPIO Document BCPIO - документ BCPIO + Документ BCPIO Dokument BCPIO Dokument BCPIO Dokument BCPIO @@ -7633,7 +7807,7 @@ ficheiro de semente BitTorrent Arquivo semente BitTorrent Fișier sursă-completă BitTorrent - файл источника BitTorrent + Файл источника BitTorrent Súbor BitTorrent Datoteka sejanja BitTorrent File bazë BitTorrent @@ -7652,6 +7826,7 @@ Blender scene مشهد بلندر + Escena de Blender Scena Blender Сцена — Blender escena de Blender @@ -7689,7 +7864,7 @@ cenário Blender Cena do Blender Scenă Blender - сцена Blender + Сцена Blender Scéna Blender Datoteka scene Blender Skenë Blender @@ -7711,6 +7886,7 @@ TeX DVI document (bzip-compressed) مستند TeX DVI (مضغوط-bzip) + Documentu Tex DVI (comprimíu en bzip) Dakument TeX DVI (bzip-skampresavany) Документ — TeX DVI, компресиран с bzip document de TeX DVI (amb compressió bzip) @@ -7727,7 +7903,7 @@ cáipéis DVI TeX (comhbhrúite le bzip) documento DVI de TeX (comprimido con bzip) מסמך מסוג TeX DVI (מכווץ ע״י bzip) - TeX DVI dokument (komprimiran bzip-om) + TeX DVI dokument (bzip sažeto) TeX DVI dokumentum (bzip-pel tömörítve) Documento TeX DVI (comprimite con bzip) Dokumen TeX DVI (terkompresi bzip) @@ -7745,7 +7921,7 @@ documento TeX DVI (compressão bzip) Documento DVI TeX (compactado com bzip) Document TeX DVI (comprimat bzip) - документ TeX DVI (сжатый bzip) + Документ TeX DVI (сжатый bzip) Dokument TeX DVI (komprimovaný pomocou bzip) Dokument TeX DVI (stisnjen z bzip) Dokument Tex DVI (i kompresuar me bzip) @@ -7754,7 +7930,7 @@ TeX DVI belgesi (bzip ile sıkıştırılmış) документ TeX DVI (стиснений bzip) Tài liệu DVI TeX (đã nén bzip) - TeX DVI 文档(gzip 压缩) + TeX DVI 文档(gzip 压缩) TeX DVI 文件 (bzip 格式壓縮) @@ -7763,6 +7939,7 @@ Bzip archive أرشيف Bzip + Archivu Bzip Archiŭ bzip Архив — bzip arxiu bzip @@ -7799,7 +7976,7 @@ arquivo Bzip Pacote Bzip Arhivă Bzip - архив BZIP + Архив BZIP Archív bzip Datoteka arhiva Bzip Arkiv bzip @@ -7808,7 +7985,7 @@ Bzip arşivi архів bzip Kho nén bzip - bzip 归档文件 + Bzip 归档文件 Bzip 封存檔 @@ -7821,6 +7998,7 @@ Tar archive (bzip-compressed) أرشيف Tar (مضغوط-bzip) + Archivu Tar (comprimíu en bzip) Archiŭ tar (bzip-skampresavany) Архив — tar, компресиран с bzip arxiu tar (amb compressió bzip) @@ -7837,7 +8015,7 @@ cartlann Tar (comhbhrúite le bzip) arquivo Tar (comprimido con bzip) ארכיון Tar (מכווץ ע״י bzip) - Tar arhiva (komprimirana bzip-om) + Tar arhiva (bzip sažeto) Tar archívum (bzip-pel tömörítve) Archivo Tar (comprimite con bzip) Arsip Tar (terkompresi bzip) @@ -7855,7 +8033,7 @@ arquivo Tar (compressão bzip) Pacote Tar (compactado com bzip) Arhivă Tar (comprimată bzip) - архив TAR (сжатый BZIP) + Архив TAR (сжатый bzip) Archív tar (komprimovaný pomocou bzip) Datoteka arhiva Tar (stisnjen z bzip) Arkiv tar (i kompresuar me bzip) @@ -7864,7 +8042,7 @@ Tar arşivi (bzip ile sıkıştırılmış) архів tar (стиснений bzip) Kho nén tar (đã nén bzip) - Tar 归档文件(bzip 压缩) + Tar 归档文件(bzip 压缩) Tar 封存檔 (bzip 格式壓縮) @@ -7877,6 +8055,7 @@ PDF document (bzip-compressed) مستند PDF (مضغوط-bzip) + Documentu PDF (comprimíu en bzip) Dakument PDF (bzip-skampresavany) Документ — PDF, компресиран с bzip document PDF (amb compressió bzip) @@ -7911,7 +8090,7 @@ documento PDF (compressão bzip) Documento PDF (compactado com bzip) Document PDF (comprimat bzip) - документ PDF (сжатый bzip) + Документ PDF (сжатый bzip) Dokument PDF (komprimovaný pomocou bzip) Dokument PDF (stisnjen z bzip) Dokument PDF (i kompresuar me bzip) @@ -7920,7 +8099,7 @@ PDF belgesi (bzip ile sıkıştırılmış) документ PDF (стиснений bzip) Tài liệu PDF (đã nén bzip) - PDF 文档(bzip 压缩) + PDF 文档(bzip 压缩) PDF 文件 (bzip 格式壓縮) @@ -7929,6 +8108,7 @@ PostScript document (bzip-compressed) مستند PostScript (مضغوط-bzip) + Documentu PostScript (comprimíu en bzip) Dakument PostScript (bzip-skampresavany) Документ — PostScript, компресиран с bzip document PostScript (amb compressió bzip) @@ -7963,7 +8143,7 @@ documento PostScript (compressão bzip) Documento PostScript (compactado com bzip) Document PostScript (comprimat bzip) - документ PostScript (сжатый bzip) + Документ PostScript (сжатый bzip) Dokument PostScript (komprimovaný pomocou bzip) Dokument PostScript (stisnjen z bzip) Dokument PostScript (i kompresuar me bzip) @@ -7972,13 +8152,13 @@ PostScript belgesi (bzip ile sıkıştırılmış) документ PostScript (стиснене bzip) Tài liệu PostScript (đã nén bzip) - PostScript 文档(bzip 压缩) + PostScript 文档(bzip 压缩) PostScript 文件 (bzip 格式壓縮) - + comic book archive أرشيف comic book archiŭ komiksaŭ @@ -8015,7 +8195,7 @@ arquivo de banda desenhada Pacote de histórias em quadrinhos arhivă benzi desenate - архив комиксов + Архив комиксов Archív knihy komiksov Datoteka arhiva stripov Arkiv comic book @@ -8024,11 +8204,12 @@ çizgi roman arşivi архів коміксів Kho nén sách tranh chuyện vui - Comic Book 归档文件 + 漫画书归档文件 漫畫書封存檔 + comic book archive @@ -8067,7 +8248,7 @@ arquivo de banda desenhada Pacote de histórias em quadrinhos arhivă benzi desenate - архив комиксов + Архив комиксов Archív knihy komiksov Datoteka arhiva stripov Arkiv comic book @@ -8076,7 +8257,7 @@ çizgi roman arşivi архів коміксів Kho nén sách tranh chuyện vui - Comic Book 归档文件 + 漫画书归档文件 漫畫書封存檔 @@ -8119,7 +8300,7 @@ arquivo de banda desenhada Pacote de histórias em quadrinhos arhivă benzi desenate - архив комиксов + Архив комиксов Archív knihy komiksov Datoteka arhiva stripov Arkiv comic book @@ -8128,7 +8309,7 @@ çizgi roman arşivi архів коміксів Kho nén sách tranh chuyện vui - Comic Book 归档文件 + 漫画书归档文件 漫畫書封存檔 @@ -8171,7 +8352,7 @@ arquivo de banda desenhada Pacote de histórias em quadrinhos arhivă benzi desenate - архив комиксов + Архив комиксов Archív knihy komiksov Datoteka arhiva stripov Arkiv comic book @@ -8180,7 +8361,7 @@ çizgi roman arşivi архів коміксів Kho nén sách tranh chuyện vui - Comic Book 归档文件 + 漫画书归档文件 漫畫書封存檔 @@ -8222,7 +8403,7 @@ arquivo Lrzip Pacote Lrzip Arhivă Lrzip - архив LRZIP + Архив LRZIP Archív Lrzip Datoteka arhiva Lrzip Лрзип архива @@ -8255,7 +8436,7 @@ cartlann Tar (comhbhrúite le lrzip) arquivo Tar (comprimido con lrzip) ארכיון Tar (מכווץ ע״י lrzip) - Tar arhiva (komprimirana lrzip-om) + Tar arhiva (lrzip sažeta) Tar archívum (lrzip-pel tömörítve) Archivo Tar (comprimite con lrzip) Arsip Tar (terkompresi lrzip) @@ -8271,14 +8452,14 @@ arquivo Tar (compressão Lrzip) Pacote Tar (compactado com lrzip) Arhivă Tar (comprimată lrzip) - архив TAR (сжатый LRZIP) + Архив TAR (сжатый lrzip) Archív tar (komprimovaný pomocou lrzip) Datoteka arhiva Tar (stisnjen z lrzip) Тар архива (запакована лрзипом) Tar-arkiv (lrzip-komprimerat) Tar arşivi (lrzip ile sıkıştırılmış) архів tar (стиснений lrzip) - Tar 归档文件 (lrzip 压缩) + Tar 归档文件(lrzip 压缩) Tar 封存檔 (lrzip 格式壓縮) @@ -8287,6 +8468,7 @@ Apple disk image + Imaxe de discu d'Apple Диск — Apple imatge de disc d'Apple obraz disku Apple @@ -8298,9 +8480,10 @@ Apple disko irudia Apple-levytiedosto image disque Apple + íomhá diosca Apple imaxe de disco de Appl תמונת כונן Apple - Apple snimka diska + Apple slika diska Apple lemezkép Imagine de disco Apple Image disk Apple @@ -8315,95 +8498,107 @@ Obraz dysku Apple imagem de disco Apple Imagem de disco Apple - образ диска Apple Mac OS X + Образ диска Apple Mac OS X Obraz disku Apple Odtis diska Apple - Еплова слика диска + Еплов одраз диска Apple-diskavbild Apple disk görüntüsü образ диска Apple - Apple 磁盘镜像 - Apple 磁碟映像 + Apple 磁盘映像 + Apple 磁碟映像檔 - Raw disk image - imatge de disc RAW - surový obraz disku - Rå diskaftryk - Rohes Datenträgerabbild - Ανεπεξέργαστη εικόνα δίσκου - Raw disk image - imagen de disco en bruto - Disko gordinaren irudia - Raaka levytiedosto - image disque Raw - Imaxe de disco en bruto - דמות גולמית של כונן - Osnovna slika diska - Nyers lemezkép - Imagine de disco crude - Image disk mentah - Immagine disco raw - Шикі диск бейнесі - RAW 디스크 이미지 - imatge disc Raw - Surowy obraz dysku - imagem de disco Raw - Imagem bruta de disco - необработанный образ диска - Obraz disku - Surovi odtis diska - сирова слика диска - Rå diskavbild - İşlem görmemiş disk imajı - простий образ диска - 原始磁盘镜像 - 原生磁碟映像 - - - - - Raw disk image (XZ-compressed) - imatge de disc RAW (amb compressió XZ) - surový obraz disku (komprimovaný pomocí XZ) - Rå diskaftryk (XZ-komprimeret) - Rohes Datenträgerabbild (XZ-komprimiert) - Ανεπεξέργαστη εικόνα δίσκου (συμπιεσμένη XZ) - Raw disk image (XZ-compressed) - imagen de disco en bruto (comprimida con XZ) - Disko gordinaren irudia (XZ-rekin konprimitua) - Raaka levytiedosto (XZ-pakattu) - image disque Raw (compression XZ) - Imaxe de disco en bruto (comprimida en XZ) - דמות גולמית של כונן (בדחיסת XZ) - Osnovna slika diska (XZ sažeta) - Nyers lemezkép (XZ-vel tömörítve) - Imagine de disco crude (comprimite con XZ) - Image disk mentah (terkompresi XZ) - Immagine disco raw (compressa XZ) - Шикі диск бейнесі (XZ-мен сығылған) - RAW 디스크 이미지(XZ 압축) - imatge disc Raw (compression XZ) - Surowy obraz dysku (kompresja XZ) - imagem de disco Raw (compressão XZ) - Imagem bruta de disco (compactada com XZ) - необработанный образ диска (XZ-сжатый) - Obraz disku (komprimovaný pomocou XZ) - Surovi odtis diska (stisnjeno z XZ) - сирова слика диска (запакована ИксЗ-ом) - Rå diskavbild (XZ-komprimerad) - İşlem görmemiş disk imajı (XZ ile sıkıştırılmış) - простий образ диска (стиснений XZ) - 原始磁盘镜像(XZ 压缩) - 原生磁碟映像 (XZ 格式壓縮) - - - - + Raw disk image + Imaxe de discu en bruto + imatge de disc RAW + surový obraz disku + Rå diskaftryk + Rohes Datenträgerabbild + Ανεπεξέργαστη εικόνα δίσκου + Raw disk image + imagen de disco en bruto + Disko gordinaren irudia + Raaka levytiedosto + image disque Raw + Amhíomha diosca + Imaxe de disco en bruto + דמות גולמית של כונן + Osnovna slika diska + Nyers lemezkép + Imagine de disco crude + Image disk mentah + Immagine disco raw + Шикі диск бейнесі + RAW 디스크 이미지 + imatge disc Raw + Surowy obraz dysku + imagem de disco Raw + Imagem bruta de disco + Необработанный образ диска + Obraz disku + Surovi odtis diska + сиров одраз диска + Rå diskavbild + İşlem görmemiş disk imajı + простий образ диска + 原始磁盘映像 + 原生磁碟映像檔 + + + + + Floppy disk image + + + + + + + Raw disk image (XZ-compressed) + Imaxe de discu en bruto (comprimida en XZ) + imatge de disc RAW (amb compressió XZ) + surový obraz disku (komprimovaný pomocí XZ) + Rå diskaftryk (XZ-komprimeret) + Rohes Datenträgerabbild (XZ-komprimiert) + Ανεπεξέργαστη εικόνα δίσκου (συμπιεσμένη XZ) + Raw disk image (XZ-compressed) + imagen de disco en bruto (comprimida con XZ) + Disko gordinaren irudia (XZ-rekin konprimitua) + Raaka levytiedosto (XZ-pakattu) + image disque Raw (compression XZ) + Amhíomhá (comhbhrúite le XZ) + Imaxe de disco en bruto (comprimida en XZ) + דמות גולמית של כונן (בדחיסת XZ) + Osnovna slika diska (XZ sažeta) + Nyers lemezkép (XZ-vel tömörítve) + Imagine de disco crude (comprimite con XZ) + Image disk mentah (terkompresi XZ) + Immagine disco raw (compressa XZ) + Шикі диск бейнесі (XZ-мен сығылған) + RAW 디스크 이미지(XZ 압축) + imatge disc Raw (compression XZ) + Surowy obraz dysku (kompresja XZ) + imagem de disco Raw (compressão XZ) + Imagem bruta de disco (compactada com XZ) + Необработанный образ диска (сжатый xz) + Obraz disku (komprimovaný pomocou XZ) + Surovi odtis diska (stisnjeno z XZ) + сиров одраз диска (запакована ИксЗ-ом) + Rå diskavbild (XZ-komprimerad) + İşlem görmemiş disk imajı (XZ ile sıkıştırılmış) + простий образ диска (стиснений XZ) + 原始磁盘映像(XZ 压缩) + 原生磁碟映像 (XZ 格式壓縮) + + + + raw CD image صورة CD خامة + imaxe de CD en bruto suvoraja vyjava CD Изображение — raw CD imatge de CD en cru @@ -8440,17 +8635,17 @@ imagem em bruto de CD Imagem bruta de CD imagine de CD brută - необработанный образ компакт-диска + Необработанный образ компакт-диска Surový obraz CD surovi CD odtis Imazh raw CD - сирова слика ЦД-а + сиров одраз ЦД-а rå cd-avbild Ham CD görüntüsü образ raw CD ảnh đĩa CD thô 原始 CD 映像 - 原生 CD 映像 + 原生 CD 映像檔 @@ -8460,20 +8655,31 @@ AppImage application bundle paquet d'aplicació AppImage + balíček AppImage s aplikací Applmage-programsamling AppImage-Anwendungspaket + AppImage application bundle paquete de aplicación AppImage + AppImage aplikazio bilduma + AppImage-sovelluspaketti lot applicatif AppImage + burla feidhmchláir AppImage חבילת יישומי AppImage + AppImage paket aplikacije AppImage alkalmazáscsomag + bundel aplikasi AppImage + Bundle applicazione AppImage AppImage қолданбалар дестесі AppImage 프로그램 번들 Pakiet programu AppImage Pacote de aplicativo AppImage - пакет приложений AppImage + Пакет приложения AppImage Balík aplikácií AppImage + скуп програма Ап-слике + AppImage-programbunt + AppImage uygulama paketi пакунок із програмами AppImage - AppImage 应用包 + AppImage 应用组合包 AppImage 應用程式套組 @@ -8488,7 +8694,6 @@ - CD Table Of Contents @@ -8527,7 +8732,7 @@ Tabela de conteúdos de CD Sumário de CD Tabel conținut CD - таблица содержания CD + Таблица содержания CD Obsah CD Kazalo vsebine CD nosilca Tregues CD @@ -8588,7 +8793,7 @@ notação de jogo de xadrez PGN Notação de jogo de xadrez PGN Notație joc șah PGN - шахматная партия PGN + Шахматная партия PGN Šachová notácia PGN Datoteka opomb šahovske igre PGN Njoftim loje shahu PGN @@ -8612,6 +8817,7 @@ CHM document مستند CHM + Documentu CHM Dakument CHM Документ — CHM document CHM @@ -8648,7 +8854,7 @@ documento CHM Documento CHM Document CHM - документ CHM + Документ CHM Dokument CHM Dokument CHM Dokument CHM @@ -8706,7 +8912,7 @@ byte-code Java Código compilado Java Bytecode Java - байт-код Java + Байт-код Java Bajtový kód Java Datoteka bitne kode Java Byte code Java @@ -8738,7 +8944,7 @@ comhad UNIX-comhbhrúite ficheiro comprimido de UNIX קובץ בכיווץ UNIX - UNIX-komprimirana datoteka + UNIX sažeta datoteka Tömörített UNIX-fájl File comprimite de UNIX Berkas terkompresi UNIX @@ -8757,7 +8963,7 @@ ficheiro comprimido UNIX Arquivo compactado do UNIX Fișier comprimat UNIX - файл (UNIX-сжатый) + Файл (UNIX-сжатый) Súbor komprimovaný v Unixe Skrčena Unix datoteka File i kompresuar UNIX @@ -8793,7 +8999,7 @@ cartlann Tar (comhbhrúite le gzip) arquivo Tar (comprimido con gzip) ארכיון Tar (מכווץ ע״י gzip) - Tar arhiva (komprimirana gzip-om) + Tar arhiva (gzip sažeta) Tar archívum (gzip-pel tömörítve) Archivo Tar (comprimite con gzip) Arsip Tar (terkompresi gzip) @@ -8811,7 +9017,7 @@ arquivo Tar (compressão gzip) Pacote Tar (compactado com gzip) Arhivă Tar (comprimată gzip) - архив TAR (сжатый GZIP) + Архив TAR (сжатый gzip) Archív tar (komprimovaný pomocou gzip) Datoteka arhiva Tar (stisnjen z gzip) Arkiv tar (i kompresuar me gzip) @@ -8820,7 +9026,7 @@ Tar arşivi (gzip ile sıkıştırılmış) архів tar (стиснений gzip) Kho nén tar (đã nén gzip) - Tar 归档文件(gzip 压缩) + Tar 归档文件(gzip 压缩) Tar 封存檔 (gzip 格式壓縮) @@ -8844,7 +9050,7 @@ ohjelman kaatumistiedot forrits sordáta données de plantage de programme - sonraí thuairt ríomhchláir + sonraí tuairte ríomhchláir datos de colgue do programa מידע מקריסת תכנית podaci o rušenju programa @@ -8866,7 +9072,7 @@ dados de rebentamento de aplicação Dados de travamento de programa date eroare program - данные аварийного завершения + Данные аварийного завершения программы Údaje o páde programu podatki sesutja programa Të dhëna nga programi i bllokuar @@ -8897,6 +9103,7 @@ CPIO archive أرشيف CPIO + Archivu CPIO CPIO arxivi Archiŭ CPIO Архив — CPIO @@ -8936,7 +9143,7 @@ arquivo CPIO Pacote CPIO Arhivă CPIO - архив CPIO + Архив CPIO Archív CPIO Datoteka arhiva CPIO Arkiv CPIO @@ -8978,7 +9185,7 @@ cartlann CPIO (comhbhrúite le gzip) arquivo CPIO (comprimido con gzip) ארכיון CPIO (מכווץ ע״י gzip) - CPIO arhiva (komprimirana gzip-om) + CPIO arhiva (gzip sažeta) CPIO-archívum (gzip-pel tömörítve) Archivo CPIO (comprimite con gzip) Arsip CPIO (terkompresi gzip) @@ -8998,7 +9205,7 @@ arquivo CPIO (compressão gzip) Pacote CPIO (compactado com gzip) Arhivă CPIO (compresie gzip) - архив CPIO (сжатый GZIP) + Архив CPIO (сжатый gzip) Archív CPIO (komprimovaný pomocou gzip) Datoteka arhiva CPIO (skrčena z gzip) Arkiv CPIO (kompresuar me gzip) @@ -9007,7 +9214,7 @@ CPIO arşivi (gzip ile sıkıştırılmış) архів CPIO (стиснений gzip) Kho nén CPIO (đã nén gzip) - CPIO 归档文件(gzip 压缩) + CPIO 归档文件(gzip 压缩) CPIO 封存檔 (gzip 格式壓縮) @@ -9019,7 +9226,7 @@ C qabıq skripti Skrypt abałonki C Скрипт — обвивка C - script de C shell + script C shell skript shellu C Sgript plisgyn C C-skalprogram @@ -9032,10 +9239,10 @@ Csh-komentotiedosto C skel boðrøð script C shell - script bhlaosc C + script bhlaoisce C script de C shell תסריט מעטפת C - C skripta + C skripta ljuske C héj-parancsfájl Script C-shell Skrip shell C @@ -9054,11 +9261,11 @@ script de terminal C Script de shell C Script C shell - сценарий C shell + Сценарий C shell Skript shellu C Skriptna datoteka lupine C Script shell C - скрипта Ц љуске + скрипта Ц шкољке Skalskript (csh) C kabuk betiği скрипт оболонки C @@ -9079,6 +9286,7 @@ Xbase document مستند Xbase + Documentu Xbase Dakument Xbase Документ — Xbase document Xbase @@ -9114,7 +9322,7 @@ documento Xbase Documento do Xbase Document Xbase - документ Xbase + Документ Xbase Dokument Xbase Dokument Xbase Dokument Xbase @@ -9169,7 +9377,7 @@ programa ECMAScript Programa ECMAScript Program ECMAScript - программа ECMAScript + Программа ECMAScript Program ECMAScript Programska datoteka ECMAScript Program ECMAScript @@ -9181,6 +9389,7 @@ ECMAScript 程序 ECMAScript 程式 + @@ -9188,22 +9397,33 @@ Sega CD disc image + Imaxe de discu de Sega CD imatge de disc de Sega CD + obraz disku CD pro Sega Sega CD-diskaftryk Sega-CD-Datenträgerabbild + Sega CD disc image imagen de disco CD de Sega + Sega CD disko irudia Sega CD -levykuva image disque Sega CD + íomhá dlúthdhiosca Sega דמות כונן Sega CD + Sega CD slika diska Sega CD-lemezkép + image cakram CD Sega + Immagine disco Sega Mega CD Sega CD диск бейнесі 세가 CD 디스크 이미지 Obraz płyty konsoli Mega-CD Imagem de disco Sega CD - образ диска CD Sega + Образ диска CD Sega Obraz disku CD Sega + одраз диска Сега ЦД-а + Mega-CD-skivavbild + Sega CD disk kalıbı образ диска Sega CD - Sega CD 光盘镜像 + Sega CD 光盘映像 Sega CD 光碟映像檔 @@ -9221,6 +9441,32 @@ Sega Pico ROM + ROM de Sega Pico + ROM de Sega Pico + ROM pro Sega Pico + Sega Pico ROM + Sega Pico ROM + ROM de Sega Pico + Sega Pico ROM + Sega Pico ROM + ROM Sega Pico + ROM Sega Pico + Sega Pico ROM + Sega Pico ROM + ROM Sega Pico + ROM Sega Pico + Sega Pico ROM + 세카 피코 롬 + Plik ROM konsoli Sega Pico + ROM de Sega Pico + Sega Pico ROM + ROM pre Sega Pico + Сега Пико РОМ + Sega Pico-rom + Sega Pico ROM + ППП Sega Pico + Sega Pico ROM + Sega Pico ROM @@ -9228,6 +9474,7 @@ Sega Saturn disc image + Imaxe de discu de Sega Saturn imatge de disc de Sega Saturn obraz disku pro Sega Saturn Sega Saturn-diskaftryk @@ -9238,6 +9485,7 @@ Sega Saturn disko irudia Sega Saturn -levykuva image disque Sega Saturn + íomhá diosca Sega Saturn דמות כונן Sega Saturn Sega Saturn slika diska Sega Saturn lemezkép @@ -9250,13 +9498,13 @@ Obraz płyty konsoli Sega Saturn imagem de disco Sega Saturn Imagem de disco do Sega Saturn - образ диска Sega Saturn + Образ диска Sega Saturn Obraz disku Sega Saturn - слика диска Сега Сатурна + одраз диска Сега Сатурна Sega Saturn-skivavbild Sega Saturn disk kalıbı образ диска Sega Saturn - Sega Saturn 光盘镜像 + Sega Saturn 光盘映像 Sega Saturn 光碟映像檔 @@ -9268,6 +9516,7 @@ Dreamcast GD-ROM + GD-ROM de Dreamcast GD-ROM de Dreamcast GD-ROM pro Dreamcast Dreamcast GD-ROM @@ -9277,6 +9526,7 @@ GD-ROM de Dreamcast Dreamcast GD-ROM GD-ROM Dreamcast + GD-ROM Dreamcast Dreamcast GD-ROM Dreamcast GD-ROM Dreamcast GD-ROM @@ -9288,8 +9538,8 @@ GD-ROM Dreamcast Plik GD-ROM konsoli Dreamcast GD-ROM Dreamcast - GD-ROM do Dreamcast - GD-ROM Dreamcast + GD-ROM de Dreamcast + Dreamcast GD-ROM Dreamcast GD-ROM Дримкаст ГД-РОМ Dreamcast-gd-rom @@ -9303,6 +9553,7 @@ Nintendo DS ROM Nintendo DS ROM + ROM de Nintendo DS Nintendo DS ROM ROM — Nintendo DS ROM de Nintendo DS @@ -9335,7 +9586,7 @@ ROM Nintendo DS Plik ROM konsoli Nintendo DS ROM Nintendo DS - ROM do Nintendo DS + ROM de Nintendo DS ROM Nintendo DS Nintendo DS ROM ROM pre Nintendo DS @@ -9346,13 +9597,14 @@ Nintendo DS ROM ППП Nintendo ROM DS Nintendo - Nintendo DS ROM + 任天堂 DS ROM 任天堂 DS ROM PC Engine ROM + ROM de PC Engine ROM de PC Engine ROM pro PC Engine PC Engine ROM @@ -9363,6 +9615,7 @@ PC Engine ROM PC Engine ROM ROM PC Engine + ROM PC Engine ROM de máquina de PC ROM של PC Engine PC Engine ROM @@ -9390,6 +9643,7 @@ Wii disc image + Imaxe de discu de Wii imatge de disc de Wii obraz disku pro Wii Wii-diskaftryk @@ -9400,6 +9654,7 @@ Wii disko irudia Wii-levykuva image disque Wii + íomhá diosca Wii Imaxe de disco de Wii דמות כונן Wii Wii slika diska @@ -9413,14 +9668,14 @@ Obraz płyty konsoli Wii imagem de disco Wii Imagem de disco Wii - образ диска Wii + Образ диска Wii Obraz disku Wii Odtis diska Wii - слика диска Вии-ја + одраз диска Вии-ја Wii-skivavbild Wii disk görüntüsü образ диска Wii - Wii光盘镜像 + Wii 光盘映像 Wii 光碟映像檔 @@ -9441,7 +9696,9 @@ WiiWare-Paket WiiWare bundle conjunto de WiiWare + WiiWare bilduma lot WiiWare + burla WiiWare מאגד WiiWare WiiWare paket WiiWare csomag @@ -9454,13 +9711,13 @@ Pakiet WiiWare pacote WiiWare Pacote WiiWare - пакет WiiWare + Пакет WiiWare Balík WiiWare ВииВер комплет WiiWare-paket WiiWare paketi пакет WiiWare - WiiWare bundle + WiiWare 捆绑包 WiiWare 綁包 @@ -9482,6 +9739,7 @@ GameCube disko irudia GameCube-levykuva image disque GameCube + íomhá diosca GameCube Imae de disco de GameCube דמות כונן GameCube GameCube slika diska @@ -9495,14 +9753,14 @@ Obraz płyty konsoli GameCube imagem de disco GameCube Imagem de disco GameCube - образ диска GameCube + Образ диска GameCube Obraz disku GameCube Odtis diska GameCube - слика диска Гејм Коцке + одраз диска Гејм Коцке GameCube-skivavbild GameCube disk görüntüsü образ диска GameCube - GameCube光盘镜像 + GameCube 光盘映像 GameCube 光碟映像檔 @@ -9513,16 +9771,85 @@ Thomson Mémo7 cartridge + cartutx Thomson Mémo7 + Kazeta Thomson Mémo7 + Thomson-Mémo7-Steckmodul + Thomson Mémo7 cartridge + cartucho Mémo7 de Thomson + cartouche Thomson Mémo7 + cartús Thomson Mémo7 + Thomson Mémo7 uložak + Thomson Mémo7 kazetta + cartridge Thomson Mémo7 + Cartuccia Thomson Mémo7 + Thomson Mémo7 картриджі + 톰슨 메모7 카트릿지 + Kartridż Thomson Mémo7 + Cartucho Thomson Mémo7 + Картридж Thomson Mémo7 + Kazeta Thomson Mémo7 + Томсон Мемо7 кертриџ + Thomson Mémo7-spelkassett + Thomson Mémo7 kartuşu + картридж Thomson Mémo7 + Thomson Mémo7 卡带 + Thomson Mémo7 卡匣 Thomson cassette + cinta de casset Thomson + Kazeta Thomson + Thomson-Kassette + Thomson cassette + casete de Thomson + cassette Thomson + caiséad Thomson + Thomson kaseta + Thomson kazetta + kaset Thomson + Cassetta Thomson + Thomson кассетасы + 톰슨 카셋트 + Kaseta Thomson + Cassete Thomson + Кассета Thomson + Kazeta Thomson + Томсон касете + Thomson-kassett + Thomson kaset + касета Thomson + Thomson 磁带 + Thomson 卡匣 HFE floppy disk image + imatge de disquet HFE + Obraz diskety HFE + HFE-Diskettenabbild + HFE floppy disk image + imagen de disquete HFE + image disquette HFE + íomhá diosca fhlapaigh HFE + HFE slika diskete + HFE flopi lemezkép + image disk floppy HFE + Immagine disco floppy HFE + HFE иілгіш диск бейнесі + HFE 플로피 디스크 이미지 + Obraz dyskietki HFE + Imagem de disco flexível HFE + Образ гибкого диска HFE + Obraz pružného disku HFE + ХФЕ слика флопи диска + HFE-diskavbild + HFE disket kalıbı + образ дискети HFE + HFE 软盘映像 + HFE 軟碟映像檔 HFE HxC Floppy Emulator @@ -9530,9 +9857,33 @@ + SAP Thomson floppy disk image + imatge de disquet SAP Thomson + Obraz diskety SAP Thomson + SAP-Thomson-Diskettenabbild + SAP Thomson floppy disk image + imagen de disquete SAP de Thomson + image disquette SAP Thomson + íomhá diosca fhlapaigh SAP Thomson + SAP Thomson slika diskete + SAP Thomson flopi lemezkép + image disk floppy SAP Thomson + Immagine disco floppy Thomson SAP + SAP Thomson иілгіш диск бейнесі + SAP 톰슨 플로피 디스크 이미지 + Obraz dyskietki SAP Thomson + Imagem de disco flexível SAP Thomson + Образ гибкого диска SAP Thomson + Obraz pružného disku SAP Thomson + САП Томсон слика флопи диска + SAP Thomson-diskavbild + SAP Thomson disket kalıbı + образ дискети Thomson SAP + SAP Thomson 软盘映像 + SAP Thomson 軟碟映像檔 SAP Système d'Archivage Pukall @@ -9540,6 +9891,7 @@ + Debian package @@ -9583,7 +9935,7 @@ pacote Debian Pacote Debian Pachet Debian - пакет Debian + Пакет Debian Balíček Debianu Datoteka paketa Debian Paketë Debian @@ -9644,11 +9996,11 @@ ficheiro do Qt Designer Arquivo do Qt Designer Fișier Qt Designer - файл Qt Designer + Файл Qt Designer Súbor Qt Designer Datoteka Qt Designer File Qt Designer - датотека Кут Дизајнера + датотека Кут дизајнера Qt Designer-fil Qt Tasarımcı dosyası файл програми Qt-дизайнер @@ -9676,6 +10028,7 @@ Qt Markup lengoai fitxategia QML-tiedosto fichier Qt Markup Language + comhad teanga mharcála Qt ficheiro de linguaxe de marcado Qt קובץ שפת סימון של Qt Qt Markup Language datoteka @@ -9692,17 +10045,23 @@ Plik języka znaczników Qt ficheiro de linguagem Qt Markup Arquivo de Qt Markup Language - файл Qt Markup Language + Файл Qt Markup Language Súbor značkovacieho jazyka Qt Datoteka označevalnega jezika Qt - датотека Кутовог језика означавања + датотека КуТ-овог језика означавања Qt-märkspråksfil Qt İşaretleme Dili dosyası файл мови розмітки Qt - Qt + Qt Markup Language 文件 Qt 標記語言檔 - + + + + + + + @@ -9725,10 +10084,10 @@ työpöydän asetustiedosto skriviborðssamansetingarfíla fichier de configuration desktop - comhad chumraíocht deisce + comhad cumraíochta deisce ficheiro de configuración de escritorio קובץ הגדרות שולחן עבודה - datoteka postavki radne površine + Datoteka prečaca radne površine asztalbeállító fájl File de configuration de scriptorio berkas konfigurasi destop @@ -9747,7 +10106,7 @@ ficheiro de configuração de área de trabalho Arquivo de configuração desktop fișier de configurare al desktopului - файл настроек рабочего стола + Файл настроек рабочего стола Súbor nastavení pracovnej plochy nastavitvena datoteka namizja File konfigurimi desktop @@ -9774,6 +10133,7 @@ FictionBook document مستند FictionBook + Documentu de FictionBook Документ — FictionBook document FictionBook dokument FictionBook @@ -9807,7 +10167,7 @@ documento FictionBook Documento FictionBook Document FictionBook - документ FictionBook + Документ FictionBook Dokument FictionBook Dokument FictionBook документ Фикшон Књиге @@ -9827,6 +10187,7 @@ Compressed FictionBook document + Documentu comprimíu de FictionBook document FictionBook amb compressió komprimovaný dokument FictionBook Komprimeret FictionBook-dokument @@ -9837,6 +10198,7 @@ Konprimitutako FictionBook dokumentua Pakattu FictionBook-asiakirja document FictionBook compressé + cáipéis chomhbhrúite FictionBook Documento de FictionBook comprimida מסמך FictionBook מכווץ Sažet FictionBook dokument @@ -9858,7 +10220,7 @@ Sıkıştırılmış KurguKitap belgesi стиснений документ FictionBook 压缩的 FictionBook 文档 - 壓縮的 FictionBook 文件 + 壓縮版 FictionBook 文件 @@ -9910,7 +10272,7 @@ diagrama Dia Diagrama do Dia Diagramă Dia - диаграмма Dia + Диаграмма Dia Diagram Dia Datoteka diagrama Dia Diagramë Dia @@ -9963,7 +10325,7 @@ forma Dia Formato Dia Figură Dia - фигура Dia + Фигура Dia Tvar Dia Datoteka oblik Dia облик Дие @@ -9983,6 +10345,7 @@ TeX DVI document مستند TeX DVI + Documentu Tex DVI Dakument TeX DVI Документ — TeX DVI document DVI de TeX @@ -10019,7 +10382,7 @@ documento TeX DVI Documento DVI TeX Document Tex DVI - документ TeX DVI + Документ TeX DVI Dokument TeX DVI Dokument TeX DVI Dokument TeX DVI @@ -10080,11 +10443,11 @@ tema Enlightenment Tema do Enlightenment Temă Enlightenment - тема Enlightenment + Тема Enlightenment Motív Enlightenment Datoteka teme Enlightenment Tema Enlightenment - тема Просвећености + тема за Енлајтмент Enlightenment-tema Enlightenment teması тема Enlightenment @@ -10133,7 +10496,7 @@ animação Egon Animator Animação do Egon Animator Animație Egon Animator - анимация Egon Animator + Анимация Egon Animator Animácia Egon Animator Datoteka animacije Egon Animator Animim Egon Animator @@ -10167,7 +10530,7 @@ comhad inrite executábel קובץ הרצה - izvršna datoteka + Izvršna datoteka futtatható Executabile dapat dieksekusi @@ -10186,7 +10549,7 @@ executável Executável executabil - исполняемый + Исполняемый Spustiteľný súbor izvedljiva datoteka I ekzekutueshëm @@ -10254,7 +10617,7 @@ ficheiro FLTK Fluid Arquivo Fluid do FLTK Fișier FLTK Fluid - файл FLTK Fluid + Файл FLTK Fluid Súbor FLTK Fluid Datoteka FLTK Fluid File FLTK Fluid @@ -10274,10 +10637,11 @@ - + WOFF font - tipus de lletra WOFF - písmo WOFF + Fonte WOFF + lletra WOFF + font WOFF WOFF-skrifttype WOFF-Schrift Γραμματοσειρά WOFF @@ -10286,13 +10650,14 @@ WOFF letra-tipoa WOFF-fontti police WOFF + cló WOFF Tipo de letra WOFF גופן WOFF WOFF slovo WOFF-betűkészlet Typo de litteras WOFF Fonta WOFF - Font WOFF + Carattere WOFF WOFF フォント WOFF қарібі WOFF 글꼴 @@ -10301,7 +10666,7 @@ Czcionka WOFF letra WOFF Fonte WOFF - шрифт WOFF + Шрифт WOFF Písmo WOFF Pisava WOFF ВОФФ слова @@ -10317,55 +10682,65 @@ + + + + WOFF2 font + Fonte WOFF2 + lletra WOFF2 + font WOFF2 + WOFF2-Schrift + WOFF2 font + tipo de letra WOFF2 + WOFF2-fontti + WOFF2 slovo + WOFF2 betűkészlet + Fonta WOFF2 + Carattere WOFF2 + WOFF2 қарібі + WOFF2 글꼴 + Czcionka WOFF2 + Fonte WOFF2 + Шрифт WOFF2 + Písmo WOFF2 + WOFF2-typsnitt + шрифт WOFF2 + WOFF2 字体 + WOFF2 字型 + WOFF2 + Web Open Font Format 2.0 + + + + + - Postscript type-1 font - خط Postscript type-1 - Šryft Postscript type-1 - Шрифт — Postscript Type 1 - tipus de lletra Postscript type-1 - písmo Postscript type-1 - PostScript type-1-skrifttype - Postscript-Typ-1-Schrift - Γραμματοσειρά Postscript type-1 - Postscript type-1 font + PostScript type-1 font + lletra type-1 de PostScript + font PostScript type-1 + PostScript-Typ-1-Schrift + PostScript type-1 font tipo de letra PostScript Type-1 PostScript type-1 letra-tipoa - PostScript tyyppi-1 -fontti - Postscript type-1 stavasnið - police Postscript Type 1 - cló Postscript type-1 - tipo de letra PostScript tipo-1 - גופן של Postscript type-1 - Postscript crsta-1 slovo - Postscript type-1 betűkészlet - Typo de litteras PostScript typo 1 - Fonta tipe-1 Postscript - Carattere Postscript type-1 - PostScript type-1 フォント - Postscript type-1 қарібі + police PostScript Type 1 + cló PostScript type-1 + PostScript type-1 slovo + PostScript type-1 betűkészlet + fonta PostScript type-1 + Carattere PostScript type-1 + PostScript type-1 қарібі PostScript Type-1 글꼴 - Postscript type-1 šriftas - Postscript 1-tipa fonts - Postscript type-1 skrift - PostScript type-1-lettertype - PostScript type 1-skrifttype - poliça Postescript Type 1 Czcionka PostScript Type-1 - letra PostScript tipo 1 Fonte PostScript tipo-1 - Font Postscript type-1 - шрифт PostScript Type-1 - Písmo Postscript type-1 - Datoteka pisave Postscript vrste-1 - Lloj gërmash Postscript type-1 + Шрифт PostScript Type-1 + Písmo PostScript typu 1 слова Постскрипта врсте-1 - Postscript type-1-typsnitt - Postscript type-1 yazı tipi - шрифт Postscript type-1 - Phông kiểu 1 PostScript - Postscript type-1 字体 - Postscript type-1 字型 + PostScript type-1-typsnitt + PostScript tip-1 yazı tipi + шрифт type-1 PostScript + PostScript type-1 字体 + PostScript type-1 字型 @@ -10386,8 +10761,8 @@ Adobe yazı növü metrikləri Metryka šryftu Adobe Шрифтова метрика — Adobe - mètrica de tipus de lletra Adobe - metrika písma Adobe + mètrica de lletra d'Adobe + metrika fontu Adobe Metrigau Ffont Adobe Adobe skrifttypefil Adobe-Schriftmetriken @@ -10401,7 +10776,7 @@ meadarachtaí cló Adobe métricas de fonte de Adobe מדדי גופן של Adobe - Adobe mjere fonta + Adobe mjere slova Adobe-betűmetrika Metricas de typo de litteras Adobe Metrik fonta Adobe @@ -10420,7 +10795,7 @@ métrica de letras Adobe Métricas de fonte Adobe Dimensiuni font Adobe - метрика шрифта Adobe + Метрика шрифта Adobe Metrika písma Adobe Matrika pisave Adobe Metrik lloj gërmash Adobe @@ -10429,7 +10804,7 @@ Adobe yazıtipi ölçüleri метрики шрифту Adobe Cách đo phông chữ Adobe - Adobe 字体参数 + Adobe 字体规格 Adobe 字型描述檔 @@ -10440,8 +10815,8 @@ BDF yazı növü Šryft BDF Шрифт — BDF - tipus de lletra BDF - písmo BDF + lletra BDF + font BDF Ffont BDF BDF-skrifttype BDF-Schrift @@ -10456,7 +10831,7 @@ cló BDF tipo de fonte BDF גופן BDF - BDF font + BDF slovo BDF-betűkészlet Typo de litteras BDF Fonta BDF @@ -10475,7 +10850,7 @@ letra BDF Fonte BDF Font BDF - шрифт BDF + Шрифт BDF Písmo BDF Datoteka pisave BDF Lloj gërme BDF @@ -10498,8 +10873,8 @@ DOS yazı növü Šryft DOS Шрифт — DOS - tipus de lletra DOS - písmo pro DOS + lletra DOS + font pro DOS Ffont DOS DOS-skrifttype DOS-Schrift @@ -10514,7 +10889,7 @@ cló DOS tipo de fonte de DOS גופן DOS - DOS font + DOS slovo DOS-betűkészlet Typo de litteras DOS Fonta DOS @@ -10533,7 +10908,7 @@ letra DOS Fonte do DOS Font DOS - шрифт DOS + Шрифт DOS Písmo pre DOS Datoteka pisave DOS Gërmë DOS @@ -10557,8 +10932,8 @@ Adobe FrameMaker yazı növü Šryft Adobe FrameMaker Шрифт — Adobe FrameMaker - tipus de lletra d'Adobe FrameMaker - písmo Adobe FrameMaker + lletra d'Adobe FrameMaker + font Adobe FrameMaker Ffont Adobe FrameMaker Adobe FrameMaker-skrifttype Adobe-FrameMaker-Schrift @@ -10573,7 +10948,7 @@ cló Adobe FrameMaker tipo de fonte de Adobe FrameMaker גופן של Adobe FrameMaker - Adobe FrameMaker font + Adobe FrameMaker slovo Adobe FrameMaker-betűkészlet Typo de litteras pro Adobe FrameMaker Fonta Adobe FrameMaker @@ -10592,7 +10967,7 @@ letra Adobe FrameMaker Fonte do Adobe FrameMaker Font Adobe FrameMaker - шрифт Adobe FrameMaker + Шрифт Adobe FrameMaker Písmo Adobe FrameMaker Datoteka pisave Adobe FrameMaker Gërma Adobe FrameMaker @@ -10614,8 +10989,8 @@ LIBGRX yazı növü Šryft LIBGRX Шрифт — LIBGRX - tipus de lletra LIBGRX - písmo LIBGRX + lletra LIBGRX + font LIBGRX Ffont LIBGRX LIBGRX-skrifttype LIBGRX-Schrift @@ -10630,7 +11005,7 @@ cló LIBGRX tipo de fonte en LIBGRX גופן LIBGRX - LIBGRX font + LIBGRX slovo LIBGRX-betűkészlet Typo de litteras LIBGRX Fonta LIBGRX @@ -10649,7 +11024,7 @@ letra LIBGRX Fonte LIBGRX Font LIBGRX - шрифт LIBGRX + Шрифт LIBGRX Písmo LIBGRX Datoteka pisave LIBGRX Lloj gërme LIBGRX @@ -10671,8 +11046,8 @@ Linux PSF konsol yazı növü Kansolny šryft PSF dla Linuksa Шрифт — PSF, за конзолата на Линукс - tipus de lletra de consola Linux PSF - písmo PSF pro konzolu Linuxu + lletra de consola PSF de Linux + font PSF pro konzolu Linuxu Ffont Linux PSF Linux PSF-konsolskrifttype Linux-PSF-Konsolenschrift @@ -10684,10 +11059,10 @@ Linux PSF -konsolifontti Linux PSF stýristøðs stavasnið police console Linux PSF - cló chonsól Linux PSF + cló consóil Linux PSF tipo de fonte de consola Linux PSF גופן לקונסול מסוג Linux PSF - Linux PSF konzolni font + Linux PSF konzolno slovo Linux PSF konzolos betűkészlet Typo de litteras console Linux PSF Fonta konsol Linux PSF @@ -10706,7 +11081,7 @@ letra de consola Linux PSF Fonte de console Linux PSF Font consolă Linux PSF - консольный шрифт Linux PSF + Консольный шрифт Linux PSF Písmo PSF pre konzolu Linuxu Datoteka pisave konzole Linux PSF Lloj gërme për konsolë Linux PSF @@ -10728,8 +11103,8 @@ خط كونسول PSF لينكس (مضغوط-gzip) Kansolny šryft PSF dla Linuksa (gzip-skampresavany) Шрифт — Linux PSF, компресиран с gzip - tipus de lletra de consola Linux PSF (amb compressió gzip) - písmo PSF pro konzolu Linuxu (komprimované pomocí gzip) + lletra de consola PSF de Linux (amb compressió gzip) + font PSF pro konzolu Linuxu (komprimace gzip) Linux PSF-konsolskrifttype (gzip-komprimeret) Linux-PSF-Konsolenschrift (gzip-komprimiert) Γραμματοσειρά κονσόλας PSF Linux (συμπιεσμένη με gzip) @@ -10739,10 +11114,10 @@ Linux PSF -konsolifontti (gzip-pakattu) Linux PSF stýristøðs stavasnið (gzip-stappað) police console Linux PSF (compressée gzip) - cló chonsól Linux PSF (comhbhrúite le gzip) + cló consóil Linux PSF (comhbhrúite le gzip) tipo de fonte de consola Linux PSF (comprimida con gzip) גופן למסוף מסוג Linux PSF (מכווץ ע״י gzip) - Linux PSF konzolni font (komprimiran gzip-om) + Linux PSF konzolno slovo (gzip sažeto) Linux PSF konzolos betűkészlet (gzip-tömörítésű) Typo de litteras console Linux PSF (comprimite con gzip) Fonta konsol Linux PSF (terkompresi gzip) @@ -10760,7 +11135,7 @@ letra de consola Linux PSF (compressão gzip) Fonte de console Linux PSF (compactada com gzip) Font consolă Linux PSF (compresie gzip) - консольный шрифт Linux PSF (сжатый gzip) + Консольный шрифт Linux PSF (сжатый gzip) Písmo PSF pre konzolu Linuxu (komprimované pomocou gzip) Datoteka pisave konzole Linux PSF (skrčena z gzip) Lloj gërme për konsolë Linux PSF (komresuar me gzip) @@ -10769,7 +11144,7 @@ Linux PSF konsol fontu (gzip ile sıkıştırılmış) консольний шрифт Linux PSF (стиснений gzip) Phông chữ bàn giao tiếp PSF Linux (đã nén gzip) - Linux PSF 控制台字体(gzip 压缩) + Linux PSF 控制台字体(gzip 压缩) Linux PSF console 字型 (gzip 格式壓縮) @@ -10781,8 +11156,8 @@ PCF yazı növü Šryft PCF Шрифт — PCF - tipus de lletra PCF - písmo PCF + lletra PCF + font PCF Ffont PCF PCF-skrifttype PCF-Schrift @@ -10816,7 +11191,7 @@ letra PCF Fonte PCF Font PCF - шрифт PCF + Шрифт PCF Písmo PCF Datoteka pisave PCF Gërma PCF @@ -10835,14 +11210,14 @@ - + OpenType font خط OpenType OpenType yazı növü Šryft OpenType Шрифт — OpenType - tipus de lletra OpenType - písmo OpenType + lletra OpenType + font OpenType Ffont OpenType OpenType-skrifttype OpenType-Schrift @@ -10876,7 +11251,7 @@ letra OpenType Fonte OpenType Font OpenType - шрифт OpenType + Шрифт OpenType Písmo OpenType Datoteka pisave OpenType Gërma OpenType @@ -10887,12 +11262,13 @@ Phông chữ OpenType OpenType 字体 OpenType 字型 - + + Speedo font @@ -10900,8 +11276,8 @@ Speedo yazı növü Šryft Speedo Шрифт — Speedo - tipus de lletra Speedo - písmo Speedo + lletra Speedo + font Speedo Ffont Speedo Speedoskrifttype Speedo-Schrift @@ -10916,7 +11292,7 @@ cló Speedo tipo de letra Speedo גופן של Speedo - Speedo font + Speedo slovo Speedo-betűkészlet Typo de litteras Speedo Fonta Speedo @@ -10935,7 +11311,7 @@ letra Speedo Fonte Speedo Font Speedo - шрифт Speedo + Шрифт Speedo Písmo Speedo Datoteka pisave Speedo Gërma Speedo @@ -10958,8 +11334,8 @@ SunOS News yazı növü Šryft SunOS News Шрифт — SunOS News - tipus de lletra SunOS News - písmo SunOS News + lletra News de SunOS + font SunOS News Ffont SunOS News SunOS News-skrifttype SunOS-News-Schrift @@ -10974,7 +11350,7 @@ cló SunOS News tipo de letra SunOS News גופן של SunOS News - SunOS News font + SunOS News slovo SunOS News-betűkészlet Typo de litteras SunOS News Fonta SunOS News @@ -10993,7 +11369,7 @@ letra SunOS News Fonte SunOS News Font SunOS News - шрифт SunOS News + Шрифт SunOS News Písmo SunOS News Datoteka pisave SunOS News Gërma SunOS News @@ -11017,8 +11393,8 @@ TeX yazı növü Šryft TeX Шрифт — TeX - tipus de lletra TeX - písmo TeX + lletra TeX + font TeX Ffont TeX TeX-skrifttype TeX-Schrift @@ -11033,7 +11409,7 @@ cló TeX tipo de letra de TeX גופן TeX - TeX font + TeX slovo TeX-betűkészlet Typo de litteras TeX Fonta TeX @@ -11052,7 +11428,7 @@ letra TeX Fonte TeX Font TeX - шрифт TeX + Шрифт TeX Písmo TeX Datoteka pisave TeX Gërma TeX @@ -11076,8 +11452,8 @@ TeX yazı növü metrikləri Metryka šryftu TeX Шрифтова метрика — TeX - mètrica de tipus de lletra TeX - metrika písma TeX + mètrica de lletra de TeX + metrika fontu TeX Metrigau Ffont TeX TeX-skrifttypeinformation TeX-Schriftmetriken @@ -11091,7 +11467,7 @@ meadarachtaí cló TeX Métricas de tipo de letra de TeX ממדי גופן של TeX - TeX mjere fonta + TeX mjere slova TeX-betűmetrika Metricas de typo de litteras TeX Fonta metrik TeX @@ -11110,7 +11486,7 @@ métricas de letra TeX Métrica de fonte TeX Dimensiuni font TeX - метрика шрифта TeX + Метрика шрифта TeX Metrika písma TeX Matrika pisave Tex Gërma TeX metrics @@ -11119,7 +11495,7 @@ TeX yazı tipi ölçüleri метрики шрифту TeX Cách đo phông chữ TeX - TeX 字体参数 + TeX 字体规格 TeX 字型描述檔 @@ -11127,13 +11503,13 @@ - + TrueType font خط TrueType Šryft TrueType Шрифт — TrueType - tipus de lletra TrueType - písmo TrueType + lletra TrueType + font TrueType TrueType-skrifttype TrueType-Schrift Γραμματοσειρά TrueType @@ -11147,7 +11523,7 @@ cló TrueType tipo de letra TrueType גופן מסוג TrueType - TrueType font + TrueType slovo TrueType-betűkészlet Typo de litteras TrueType Fonta TrueType @@ -11166,7 +11542,7 @@ letra TrueType Fonte TrueType Font TrueType - шрифт TrueType + Шрифт TrueType Písmo TrueType Datoteka pisave TrueType Lloj gërme TrueType @@ -11184,6 +11560,31 @@ + + + + Font collection + ccol·lecció de lletres + kolekce fontů + Schriftsammlung + Font collection + colección tipográfica + Fonttikokoelma + Kolekcija slova + Betűkészlet-gyűjtemény + Koleksi fonta + Raccolta di caratteri + Қаріптер жинағы + 글꼴 모음 + Kolekcja czcionek + coleção de fontes + Коллекция шрифтов + Zbierka písiem + Typsnittssamling + збірка шрифтів + 字体集 + 字型集 + @@ -11191,8 +11592,8 @@ خط TrueType XML Šryft TrueType XML Шрифт — TrueType XML - tipus de lletra TrueType XML - písmo TrueType XML + lletra XML de TrueType + font TrueType XML TrueType XML-skrifttype TrueType-XML-Schrift Γραμματοσειρά XML TrueType @@ -11205,7 +11606,7 @@ cló XML TrueType tipo de letra TrueType XML גופן XML מסוג TrueType - TrueType XML font + TrueType XML slovo TrueType XML betűkészlet Typo de litteras TrueType XML Fonta TrueType XML @@ -11223,7 +11624,7 @@ letra TrueType XML Fonte TrueType XML Font XML TrueType - шрифт TrueType XML + Шрифт TrueType XML Písmo TrueType XML Datoteka pisave TrueType XML Lloj gërme TrueType XML @@ -11247,8 +11648,8 @@ V yazı növü Šryft V Шрифт — V - tipus de lletra V - písmo V + lletra V + font V Ffont V V-skrifttype V-Schrift @@ -11263,7 +11664,7 @@ cló V tipo de letra V גופן של V - V font + V slovo V-betűkészlet Typo de litteras V Fonta V @@ -11282,7 +11683,7 @@ letra V Fonte V Font V - шрифт V font + Шрифт V font Písmo V Datoteka pisave V Gërmë V @@ -11301,6 +11702,7 @@ Adobe FrameMaker document مستند أدوبي الصانع للإطارات + Documentu d'Adobe FrameMaker Dakument Adobe FrameMaker Документ — Adobe FrameMaker document d'Adobe FrameMaker @@ -11337,7 +11739,7 @@ documento Adobe FrameMaker Documento do Adobe FrameMaker Document Adobe FrameMaker - документ Adobe FrameMaker + Документ Adobe FrameMaker Dokument Adobe FrameMaker Dokument Adobe FrameMaker Dokument Adobe FrameMaker @@ -11399,7 +11801,7 @@ ROM Game Boy Plik ROM konsoli Game Boy ROM Game Boy - ROM do Game Boy + ROM de Game Boy ROM Game Boy Game Boy ROM ROM pre Game Boy @@ -11424,18 +11826,29 @@ Game Boy Color ROM ROM de Game Boy Color + ROM pro Game Boy Color Game Boy Color ROM Game Boy Color ROM + Game Boy Colour ROM ROM de Game Boy Color + Game Boy Color ROM Game Boy Color -ROM ROM Game Boy Color + ROM Game Boy Color + ROM של Game Boy Color + Game Boy Color ROM Game Boy Color ROM + ROM Game Boy Color + ROM Game Boy Color Game Boy Color ROM 게임보이 컬러 롬 Plik ROM konsoli Game Boy Color ROM de Game Boy Color Game Boy Color ROM ROM pre Game Boy Color + Гејм Бој РОМ боје + Game Boy Color-rom + Game Boy Color ROM ППП Game Boy Color Game Boy Color ROM Game Boy Color ROM @@ -11484,7 +11897,7 @@ ROM Game Boy Advance Plik ROM konsoli Game Boy Advance ROM Game Boy Advance - ROM do Game Boy Advance + ROM de Game Boy Advance ROM Game Boy Advance Game Boy Advance ROM ROM pre Game Boy Advance @@ -11501,6 +11914,30 @@ + + Virtual Boy ROM + ROM de Virtual Boy + ROM pro Virtual Boy + Virtual Boy ROM + Virtual Boy ROM + ROM de Virtual Boy + Virtual Boy ROM + Virtual Boy ROM + ROM Virtual Boy + ROM Virtual Boy + Virtual Boy ROM + 버추얼보이 롬 + Plik ROM konsoli Virtual Boy + ROM de Virtual Boy + Virtual Boy ROM + ROM pre Virtual Boy + Virtual Boy-rom + ROM Virtual Boy + Virtual Boy ROM + Virtual Boy ROM + + + GDBM database قاعدة بيانات GDBM @@ -11540,7 +11977,7 @@ base de dados GDMB Banco de dados GDBM Bază de date GDBM - база данных GDBM + База данных GDBM Databáza GDBM Podatkovna zbirka GDBM Bazë me të dhëna GDBM @@ -11597,7 +12034,7 @@ ROM Mega Drive/Genesis Plik ROM konsoli Mega Drive ROM Mega Drive - ROM do Gênesis (Mega Drive) + ROM de Genesis (Mega Drive) ROM Genesis Genesis ROM ROM pre Megadrive @@ -11624,19 +12061,29 @@ Genesis 32X ROM ROM de Genesis 32X + ROM pro Genesis 32X Genesis 32X ROM Genesis 32X ROM + Genesis 32X ROM ROM de Genesis 32X + Genesis 32X ROM Genesis 32X -ROM ROM Genesis 32X + ROM Genesis 32X ROM מסוג Genesis 32X + Genesis 32X ROM Genesis 32X ROM + ROM Genesis 32X + ROM Sega Mega Drive 32X Genesis 32X ROM 제네시스 32X 롬 Plik ROM konsoli Mega Drive 32X ROM de Genesis 32X Genesis 32X ROM ROM pre Genesis 32X + Џенезис 32X РОМ + Mega Drive 32X-rom + Genesis 32X ROM ППП Genesis 32X Genesis 32X ROM Genesis 32X ROM @@ -11667,7 +12114,7 @@ teachtaireachtaí aistrithe (inléite ag meaisín) mensaxes traducidos (lexíbeis por máquinas) הודעות מתורגמות (מובן ע״י מכונה) - prevedene poruke (strojno čitljive) + Prevedene poruke (strojno čitljive) lefordított üzenetek (gépi kód) messages traducite (legibile pro machinas) pesan diterjemahkan (dapat dibaca mesin) @@ -11687,7 +12134,7 @@ mensagens traduzidas (leitura pelo computador) Mensagens traduzidas (legível pelo computador) mesaje traduse (citite de calculator) - переводы сообщений (откомпилированые) + Переводы сообщений (откомпилированые) Preložené správy (strojovo čitateľné) prevedena sporočila (strojni zapis) Mesazhe të përkthyer (të lexueshëm nga makina) @@ -11696,7 +12143,7 @@ çevrilmiş iletiler (makine tarafından okunabilir) перекладені повідомлення (у машинній формі) thông điệp đã dịch (máy đọc được) - 消息翻译(机读) + 已翻译消息(机读) 翻譯訊息 (程式讀取格式) @@ -11717,6 +12164,7 @@ GTK+ Builder GTK+ Builder GTK+ Builder + Tógálaí GTK+ Construtor de GTK+ בנייה של GTK+‎ GTK+ Builder @@ -11739,7 +12187,7 @@ GTK+ Builder GTK+ İnşa Edici GTK+ Builder - GTK+ 构建程序 + GTK+ Builder GTK+ Builder @@ -11789,7 +12237,7 @@ projecto Glade Projeto do Glade Proiect Glade - проект Glade + Проект Glade Projekt Glade Datoteka projekta Glade Projekt Glade @@ -11841,7 +12289,7 @@ dados financeiros GnuCash Dados financeiros do GnuCash Date financiare GnuCash - финансовые данные GnuCash + Финансовые данные GnuCash Finančné údaje GnuCash Datoteka finančnih podatkov GnuCash финансијски подаци Гнуовог новца @@ -11895,7 +12343,7 @@ folha de cálculo Gnumeric Planilha do Gnumeric Foaie de calcul Gnumeric - электронная таблица Gnumeric + Электронная таблица Gnumeric Zošit Gnumeric Razpredelnica Gnumeric Fletë llogaritjesh Gnumeric @@ -11904,7 +12352,7 @@ Gnumeric çalışma sayfası ел. таблиця Gnumeric Bảng tính Gnumeric. - Gnumeric 工作簿 + Gnumeric 电子表格 Gnumeric 試算表 @@ -11916,6 +12364,7 @@ Gnuplot document مستند Gnuplot + Documentu de Gnuplot Dakument Gnuplot Документ — Gnuplot document gnuplot @@ -11951,7 +12400,7 @@ documento Gnuplot Documento do Gnuplot Document Gnuplot - документ Gnuplot + Документ Gnuplot Dokument Gnuplot Dokument Gnuplot Dokument Gnuplot @@ -11985,7 +12434,7 @@ Graphite- tieteellinen graafi Grapite vísindarlig ritmynd graphe Graphite scientific - graf eolaíoch Graphite + graf eolaíochta Graphite gráfica científica de Graphite תרשים מדעי של Graphite Graphite znanstveni grafikon @@ -12007,7 +12456,7 @@ gráfico científico Graphite Gráfico científico do Graphite Grafic științific Graphite - научная диаграмма Graphite + Научная диаграмма Graphite Vedecký graf Graphite Datoteka znanstvenega grafa Graphite Grafik shkencor Graphite @@ -12061,7 +12510,7 @@ catálogo GTKtalog Catálogo GTKtalog Catalog GTKalog - каталог GTKtalog + Каталог GTKtalog Katalóg GTKtalog Datoteka kataloga GTKtalog Katallog GTKtalog @@ -12080,6 +12529,7 @@ TeX DVI document (gzip-compressed) مستند TeX DVI (مضغوط-gzip) + Documentu Tex DVI (comprimíu en gzip) Dakument TeX DVI (gzip-skampresavany) Документ — TeX DVI, компресиран с gzip document DVI de TeX (amb compressió gzip) @@ -12096,7 +12546,7 @@ cáipéis DVI TeX (comhbhrúite le gzip) documento DVI de TeX (comprimido con gzip) מסמך מסוג TeX DVI (מכווץ ע״י gzip) - TeX DVI dokument (komprimiran gzip-om) + TeX DVI dokument (gzip sažet) TeX DVI dokumentum (gzip-pel tömörítve) Documento TeX DVI (comprimite con gzip) Dokumen TeX DVI (terkompresi gzip) @@ -12114,7 +12564,7 @@ documento TeX DVI (compressão gzip) Documento DVI TeX (compactado com gzip) Document TeX DVI (comprimat gzip) - документ TeX DVI (сжатый gzip) + Документ TeX DVI (сжатый gzip) Dokument TeX DVI (komprimovaný pomocou gzip) Dokument TeX DVI (stisnjen z gzip) Dokument TeX DVI (i kompresuar me gzip) @@ -12123,7 +12573,7 @@ TeX DVI belgesi (gzip ile sıkıştırılmış) документ TeX DVI (стиснений gzip) Tài liệu DVI TeX (đã nén gzip) - TeX DVI 文档(gzip 压缩) + TeX DVI 文档(gzip 压缩) TeX DVI 文件 (gzip 格式壓縮) @@ -12167,7 +12617,7 @@ arquivo Gzip Pacote Gzip Arhivă Gzip - архив GZIP + Архив GZIP Archív gzip Datoteka arhiva Gzip Arkiv gzip @@ -12188,6 +12638,7 @@ PDF document (gzip-compressed) مستند PDF (مضغوط-gzip) + Documentu PDF (comprimíu en gzip) Dakument PDF (gzip-skampresavany) Документ — PDF, компресиран с gzip document PDF (amb compressió gzip) @@ -12222,7 +12673,7 @@ documento PDF (compressão gzip) Documento PDF (compactado com gzip) Document PDF (comprimat gzip) - документ PDF (сжатый gzip) + Документ PDF (сжатый gzip) Dokument PDF (komprimovaný pomocou gzip) Dokument PDF (stisnjen z gzip) Dokument PDF (i kompresuar me gzip) @@ -12231,7 +12682,7 @@ PDF belgesi (gzip ile sıkıştırılmış) документ PDF (стиснений gzip) Tài liệu PDF (đã nén gzip) - PDF 文档(gzip 压缩) + PDF 文档(gzip 压缩) PDF 文件 (gzip 格式壓縮) @@ -12240,6 +12691,7 @@ PostScript document (gzip-compressed) مستند PostScript (مضغوط-gzip) + Documentu PostScript (comprimíu en gzip) Dakument PostScript (gzip-skampresavany) Документ — PostScript, компресиран с gzip document PostScript (amb compressió gzip) @@ -12276,7 +12728,7 @@ documento PostScript (compressão gzip) Documento PostScript (compactado com gzip) Document PostScript (comprimat gzip) - документ PostScript (сжатый gzip) + Документ PostScript (сжатый gzip) Dokument PostScript (komprimovaný pomocou gzip) Dokument PostScript (stisnjen z gzip) Dokument PostScript (i kompresuar me gzip) @@ -12285,7 +12737,7 @@ PostScript belgesi (gzip ile sıkıştırılmış) документ PostScript (стиснене gzip) Tài liệu PostScript (đã nén gzip) - PostScript 文档(gzip 压缩) + PostScript 文档(gzip 压缩) PostScript 文件 (gzip 格式壓縮) @@ -12294,6 +12746,7 @@ HDF document مستند HDF + Documentu HDF HDF sənədi Dakument HDF Документ — HDF @@ -12332,7 +12785,7 @@ documento HDF Documento HDF Document HDF - документ HDF + Документ HDF Dokument HDF Dokument HDF Dokument HDF @@ -12368,6 +12821,7 @@ IFF fitxtegia IFF-tiedosto fichier IFF + comhad IFF Ficheiro IFF קובץ IFF IFF datoteka @@ -12383,7 +12837,7 @@ Plik IFF ficheiro IFF Arquivo IFF - файл IFF + Файл IFF Súbor IFF Datoteka IFF ИФФ датотека @@ -12437,7 +12891,7 @@ firmware iPod Firmware do iPod Firmware iPod - микропрограмма iPod + Микропрограмма iPod Firmware iPod Programska strojna oprema iPod Firmware iPod @@ -12491,7 +12945,7 @@ arquivo Java Pacote Java Arhivă Java - архив Java + Архив Java Archív Java Datoteka arhiva Java Arkiv Java @@ -12547,7 +13001,7 @@ classe Java Classe Java Clasă Java - класс Java + Класс Java Trieda Java Datoteka razreda Java Klasë Java @@ -12606,7 +13060,7 @@ ficheiro JNLP Arquivo JNLP Fișier JNLP - файл JNLP + Файл JNLP Súbor JNLP Datoteka JNLP File JNLP @@ -12660,7 +13114,7 @@ armazém de chaves Java Keystore de Java Stocare chei Java - хранилище ключей Java + Хранилище ключей Java Úložisko kľúčov Java Datoteka tipkovne razporeditve Java смештај кључа Јаве @@ -12710,7 +13164,7 @@ armazém de chaves JavaJCE Keystore JCE do Java Stocare chei Java JCE - хранилище ключей Java JCE + Хранилище ключей Java JCE Úložisko kľúčov Java JCE Datoteka tipkovne razporeditve Java JCE смештај ЈЦЕ кључа Јаве @@ -12763,7 +13217,7 @@ arquivo Java Pack200 Pacote Java Pack200 Arhivă Java Pack2000 - архив Java Pack200 + Архив Java Pack200 Archív Java Pack200 Datoteka arhiva Pack200 Java Arkiv Java Pack200 @@ -12819,7 +13273,7 @@ programa JavaScript Programa JavaScript Program JavaScript - сценарий JavaScript + Программа JavaScript Program jazyka JavaScript Programska datoteka JavaScript Program JavaScript @@ -12828,17 +13282,31 @@ JavaScript programı програма мовою JavaScript Chương trình JavaScript - Javascript 程序 + JavaScript 程序 JavaScript 程式 + + + + + + + + + + + + + JSON document + Documentu JSON document JSON dokument JSON JSON-dokument @@ -12849,6 +13317,7 @@ JSON dokumentua JSON-asiakirja document JSON + cáipéis JSON Documento JSON מסמך JSON JSON dokument @@ -12879,6 +13348,7 @@ JRD document + Documentu JRD document JRD dokument JRD JRD-dokument @@ -12889,6 +13359,7 @@ JRD dokumentua JRD-asiakirja document JRD + cáipéis JRD מסמך JRD JRD dokument JRD dokumentum @@ -12901,7 +13372,7 @@ Dokument JRD doxumento JRD Documento JRD - документ JRD + Документ JRD Dokument JRD ЈРД документ JRD-dokument @@ -12923,7 +13394,9 @@ JSON-Patch JSON patch parche en JSON + JSON adabakia correctif JSON + paiste JSON טלאי JSON JSON zakrpa JSON javítócsomag @@ -12936,13 +13409,13 @@ Łata JSON patch JSON Patch JSON - изменение JSON + Патч JSON Záplata JSON ЈСОН закрпа JSON patch JSON yaması латка JSON - JSON 补丁文件 + JSON 补丁 JSON 修補檔 JSON JavaScript Object Notation @@ -12952,6 +13425,7 @@ JSON-LD document + Documentu JSON-LD document JSON-LD dokument JSON-LD JSON-LD-dokument @@ -12962,6 +13436,7 @@ JSON-LD dokumentua JSON-LD-asiakirja document JSON-LD + cáipéis JSON-LD מסמך JSON-LD JSON-LD dokument JSON-LD dokumentum @@ -12974,7 +13449,7 @@ Dokument JSON-LD documento JSON-LD Documento JSON-LD - документ JSON-LD + Документ JSON-LD Dokument JSON-LD ЈСОН-ЛД документ JSON-LD-dokument @@ -12991,18 +13466,28 @@ Jupyter Notebook llibreta de notes de Jupyter + sešit Jupyter Jupyter Notebook Jupyter-Dokument + Jupyter Notebook libreta de Jupyter + Jupyter Notebook carnet de notes Jupyter + Leabhar nótaí Jupyter מחברת Jupyter + Jupyter bilježnica Jupyter notesz + Notebook Jupyter + Notebook Jupyter Jupyter Notebook Jupyter 노트북 Notatnik Jupyter Bloco de Notas Jupyter Jupyter Notebook Zošit programu Jupyter + Џупитер бележница + Jupyter Notebook-dokument + Jupyter Notebook записник Jupyter Jupyter 笔记本 Jupyter 記事本 @@ -13017,6 +13502,7 @@ CoffeeScript document + Documentu de CoffeScript document CoffeeScript dokument CoffeeScript CoffeeScript-dokument @@ -13027,6 +13513,7 @@ CoffeeScript dokumentua CoffeeScript-asiakirja document CoffeeScript + cáipéis CoffeeScript מסמך CoffeeScript CoffeeScript dokument CoffeeScript dokumentum @@ -13039,7 +13526,7 @@ Dokument CoffeeScript documento CoffeeScript Documento CoffeeScript - документ CoffeeScript + Документ CoffeeScript Dokument CoffeeScript Кофи скрипт документ CoffeeScript-dokument @@ -13090,7 +13577,7 @@ projecto JBuilder Projeto do JBuilder Proiect JBuilder - проект JBuilder + Проект JBuilder Projekt JBuilder Datoteka projekta JBuilder Projekt JBuilder @@ -13144,7 +13631,7 @@ desenho Karbon14 Desenho do Karbon14 Desen Karbon14 - изображение Karbon14 + Рисунок Karbon14 Kresba Karbon14 Datoteka risbe Karbon14 Vizatim Karbon14 @@ -13209,7 +13696,7 @@ gráfico KChart Gráfico do KChart Diagramă KChart - диаграмма KChart + Диаграмма KChart Graf KChart Datoteka grafikona KChart Grafik KChart @@ -13269,7 +13756,7 @@ definições Kexi para ligação de servidor de base de dados Configurações do Kexi para conexão a servidor de banco de dados Configurări Kexi pentru conexiunea la serverul de baze de date - параметры Kexi для подключения к серверу БД + Параметры Kexi для подключения к серверу БД Nastavenia Kexi pre pripojenie k databázovému serveru Strežniška povezava do nastavitvene datoteke Kexi. подешавања Кексија за везу са сервером базе података @@ -13298,7 +13785,7 @@ aicearra go tionscadal Kexi ar fhreastalaí bunachair sonraí acceso directo a proxecto Kexi no servidor de bases de datos קיצור דרך לפרוירט Kexi בשרת נתונים - prečac za Kexi projekt na poslužitelju baze podataka + Prečac do Kexi projekta na poslužitelju baze podataka indítóikon adatbázis-kiszolgálón lévő Kexi projektre Ligamine a projecto Kexi in servitor de base de datos pintasan ke projek Kexi pada server basis data @@ -13314,7 +13801,7 @@ atalho para projeto Kexi em servidor de base de dados Atalho para projeto Kexi no servidor de banco de dados scurtătură către un proiect Kexi pe un server de baze de date - ссылка на проект Kexi на сервере БД + Ссылка на проект Kexi на сервере БД Zástupca projektu Kexi na databázovom serveri bližnjica do Kexi projekta na podatkovnem strežniku пречица до пројекта Кексија на серверу базе података @@ -13355,11 +13842,11 @@ Kexi datubāzes datnes balstīts projekts Kexi database bestandgebaseerd project projècte de banca de donadas Kexi en mòde fichièr - Projekt bazy danych Kexi oparty na pliku + Projekt bazy danych Kexi na podstawie plików projeto Kexi em base de dados baseada em ficheiros Projeto de banco de dados baseado em arquivo do Kexi Proiect bazat pe fișiere al bazei de date Kexi - файловый проект базы данных Kexi + Файловый проект базы данных Kexi Projekt databázy Kexi s úložiskom typu súbor Datoteka projekta podatkovne zbirke Kexi пројекат Кексијеве базе података на основу датотеке @@ -13401,11 +13888,11 @@ Kexi datubāzes datnes balstīts projekts Kexi database bestandgebaseerd project projècte de banca de donadas Kexi en mòde fichièr - Projekt bazy danych Kexi oparty na pliku + Projekt bazy danych Kexi na podstawie plików projeto Kexi em base de dados baseada em ficheiros Projeto de banco de dados baseado em arquivo do Kexi Proiect bazat pe fișiere al bazei de date Kexi - файловый проект базы данных Kexi + Файловый проект базы данных Kexi Projekt databázy Kexi s úložiskom typu súbor Datoteka projekta podatkovne zbirke Kexi пројекат Кексијеве базе података на основу датотеке @@ -13458,7 +13945,7 @@ fórmula KFormula Fórmula do KFormula Formulă KFormula - формула KFormula + Формула KFormula Vzorec KFormula Datoteka formule KFormula Formulë KFormula @@ -13523,7 +14010,7 @@ desenho KIllustrator Desenho do KIllustrator Desen KIllustrator - изображение KIllustrator + Рисунок KIllustrator Kresba KIllustrator Datoteka risbe KIllustrator Vizatim KIllustrator @@ -13583,11 +14070,11 @@ gráfico de fluxo Kivio Fluxograma do Kivio Diagramă Kivio - диаграмма Kivio + Диаграмма Kivio Vývojový diagram Kivio Datoteka grafikona Kivio Diagramë fluksi Kivio - Кливиов дијаграм протока + Кивиов дијаграм тока Kivio-flödesschema Kivio akış şeması блок-схема Kivio @@ -13648,7 +14135,7 @@ desenho Kontour Desenho do Kontour Desen Kontour - изображение Kontour + Рисунок Kontour Kresba Kontour Datoteka risbe Kontour Vizatim Kontour @@ -13713,7 +14200,7 @@ cenário KPovModeler Cena do KPovModeler Scenă KPovModeler - сцена KPovModeler + Сцена KPovModeler Scéna KPovModeler Datoteka scene KPovModeler Skenë KPovModeler @@ -13766,7 +14253,7 @@ apresentação KPresenter Apresentação do KPresenter Prezentare KPresenter - презентация KPresenter + Презентация KPresenter Prezentácia KPresenter Predstavitev KPresenter Prezantim i KPresenter @@ -13796,6 +14283,7 @@ Krita document مستند Krita + Documentu de Krita Dakument Krita Документ — Krita document Krita @@ -13832,7 +14320,7 @@ documento Krita Documento do Krita Document Krita - документ Krita + Документ Krita Dokument Krita Dokument Krita Dokument Krita @@ -13897,7 +14385,7 @@ folha de cálculo KSpread Planilha do KSpread Foaie de calcul KSpread - электронная таблица KSpread + Электронная таблица KSpread Zošit KSpread Preglednica KSpread Fletë llogaritjesh KSpread @@ -13906,7 +14394,7 @@ KSpread çalışma sayfası ел. таблиця KSpread Bảng tính KSpread - KSpread 工作簿 + KSpread 电子表格 KSpread 試算表 @@ -13962,7 +14450,7 @@ folha de cálculo KSpread (encriptada) Planilha do KSpread (criptografada) Foaie de calcul KSpread (criptat) - электронная таблица KSpread (зашифрованная) + Электронная таблица KSpread (зашифрованная) Zošit KSpread (šifrovaný) Preglednica KSpread (šifrirana) Fletë llogaritjesh KSpread (e kriptuar) @@ -13971,7 +14459,7 @@ KSpread çalışma sayfası (şifreli) ел. таблиця KSpread (зашифрована) Bảng tính KSpread (đã mật mã) - KSpread 加密工作簿 + KSpread 电子表格(加密) KSpread 試算表 (已加密) @@ -13994,7 +14482,7 @@ KSysV init -paketti KSysV init pakki paquet d'initialisation KSysV - pacáiste thosú KSysV + pacáiste túsaithe KSysV paquete de KsysV init חבילת KSysV init KSysV init paket @@ -14015,7 +14503,7 @@ pacote inicial KSysV Pacote init do KSysV Pachet KSysV init - пакет инициализации KSysV + Пакет инициализации KSysV Balíček KSysV init Datoteka paketa KSysV init Paketë init KSysV @@ -14036,6 +14524,7 @@ Kugar document مستند Kugar + Documentu de Kugar Dakument Kugar Документ — Kugar document Kugar @@ -14072,7 +14561,7 @@ documento Kugar Documento do Kugar Document Kugar - документ Kugar + Документ Kugar Dokument Kugar Dokument Kugar Dokument Kugar @@ -14089,6 +14578,7 @@ KWord document مستند KWord + Documentu de Kword Dakument KWord Документ — KWord document KWord @@ -14126,7 +14616,7 @@ documento KWord Documento do KWord Document KWord - документ KWord + Документ KWord Dokument KWord Dokument KWord Dokument KWord @@ -14156,6 +14646,7 @@ KWord document (encrypted) مستند KWord (مشفر) + Documentu de Kword (cifráu) Dakument KWord (zašyfravany) Документ — KWord, шифриран document KWord (xifrat) @@ -14192,7 +14683,7 @@ documento KWord (encriptado) Documento do KWord (criptografado) Document KWord (criptat) - документ KWord (зашифрованный) + Документ KWord (зашифрованный) Dokument KWord (šifrovaný) Dokument KWord (šifriran) Dokument KWord (i kriptuar) @@ -14201,7 +14692,7 @@ KWord belgesi (şifreli) документ KWord (зашифрований) Tài liệu KWord (đã mật mã) - KWord 加密文档 + KWord 文档(加密) KWord 文件 (已加密) @@ -14249,7 +14740,7 @@ arquivo LHA Pacote LHA Arhivă LHA - архив LHA + Архив LHA Archív LHA Datoteka arhiva LHA Arkiv LHA @@ -14318,7 +14809,7 @@ arquivo LHZ Pacote LHZ Arhivă LHZ - архив LHZ + Архив LHZ Archív LHZ Datoteka arhiva LHZ Arkiv LHZ @@ -14332,7 +14823,7 @@ - + message catalog كتالوج الرسالة kataloh paviedamleńniaŭ @@ -14352,7 +14843,7 @@ catalóg theachtaireachtaí catálogo de mensaxes קטלוג הודעות - katalog poruka + Katalog poruka üzenetkatalógus Catalogo de messages katalog pesan @@ -14371,7 +14862,7 @@ catálogo de mensagens Catálogo de mensagens catalog de mesaje - каталог сообщений + Каталог сообщений Katalóg správ katalogov sporočil Katallog mesazhesh @@ -14388,10 +14879,12 @@ + LyX document مستند LyX + Documentu de Lyx Dakument LyX Документ — LyX document LyX @@ -14428,7 +14921,7 @@ documento LyX Documento LyX Document LyX - документ LyX + Документ LyX Dokument LyX Dokument LyX Dokument LyX @@ -14459,6 +14952,7 @@ LZ4 artxiboa LZ4-arkisto archive LZ4 + Cartlann LZ4 Arquivo LZ4 ארכיון LZ4 LZ4 arhiva @@ -14472,7 +14966,7 @@ Archiwum LZ4 arquivo LZ4 Pacote LZ4 - архив LZ4 + Архив LZ4 Archív LZ4 Datoteka arhiva LZ4 ЛЗ4 архива @@ -14491,21 +14985,31 @@ Tar archive (LZ4-compressed) arxiu tar (amb compressió LZ4) + archiv Tar (komprimace LZ4) Tar-arkiv (LZ4-komprimeret) Tar-Archiv (LZ4-komprimiert) + Tar archive (LZ4-compressed) archivador Tar (comprimido con LZ4) + Tar artxiboa (LZ4-rekin konprimatua) Tar-arkisto (LZ4-pakattu) archive tar (compression LZ4) + cartlann Tar (comhbhrúite le LZ4) ארכיון Tar (מכווץ ע״י LZ4) + Tar arhiva (LZ4 sažeto) Tar archívum (LZ4-el tömörítve) + arsip tar (terkompresi LZ4) + Archivio tar (compresso con LZ4) Tar архиві (LZ4-пен сығылған) Tar 묶음 파일(LZ4 압축) Archiwum tar (kompresja LZ4) Arquvio Tar (compactado com LZ4) - архив TAR (сжатый LZ4) + Архив TAR (сжатый lz4) Archív tar (komprimovaný pomocou LZ4) + Тар архива (запакована ЛЗ4-ом) + Tar-arkiv (LZ4-komprimerat) + Tar arşivi (LZ4 ile sıkıştırılmış) архів tar (стиснений LZ4) - Tar 归档文件 (LZ4 压缩) + Tar 归档文件(LZ4 压缩) Tar 封存檔 (LZ4 格式壓縮) @@ -14546,7 +15050,7 @@ arquivo LZip Pacote Lzip Arhivă Lzip - архив LZIP + Архив LZIP Archív Lzip Datoteka arhiva Lzip Лзип архива @@ -14564,21 +15068,31 @@ Tar archive (lzip-compressed) arxiu tar (amb compressió lzip) + archiv Tar (komprimace lzip) Tar-arkiv (lzip-komprimeret) Tar-Archiv (lzip-komprimiert) + Tar archive (lzip-compressed) archivador Tar (comprimido con lzip) + Tar artxiboa (lzip-rekin konprimatua) Tar-arkisto (lzip-pakattu) archive tar (compressée lzip) + cartlann Tar (comhbhrúite le lzip) ארכיון Tar (מכווץ ע״י lzip) + Tar arhiva (lzip sažeto) Tar archívum (lzippel tömörítve) + arsip tar (terkompresi lzip) + Archivio tar (compresso con lzip) Tar архиві (lzip-пен сығылған) TAR 묶음 파일(LZIP 압축) Archiwum tar (kompresja lzip) Arquivo Tar (compactado com lzip) - архив TAR (сжатый lzip) + Архив TAR (сжатый lzip) Archív tar (komprimovaný pomocou lzip) + Тар архива (запакована лзипом) + Tar-arkiv (lzip-komprimerat) + Tar arşivi (lzip ile sıkıştırılmış) архів tar (стиснений lzip) - Tar 归档文件 (lzip 压缩) + Tar 归档文件(lzip 压缩) Tar 封存檔 (lzip 格式壓縮) @@ -14586,6 +15100,32 @@ PDF document (lzip-compressed) + Documentu PDF (comprimíu en lzip) + document PDF (amb compressió lzip) + dokument PDF (komprimace lzip) + PDF-Dokument (lzip-komprimiert) + PDF document (lzip-compressed) + documento PDF (comprimido con lzip) + PDF dokumentua (lzip-rekin konprimitua) + PDF-asiakirja (lzip-pakattu) + document PDF (compressé lzip) + cáipéis PDF (comhbhrúite le lzip) + PDF dokument (lzip sažeto) + PDF dokumentum (lzip-tömörítésű) + dokumen PDF (termkompresi lzip) + Documento PDF (compresso con lzip) + PDF құжаты (lzip-пен сығылған) + PDF 문서(LZIP 압축) + Dokument PDF (kompresja lzip) + Documento PDF (compactado com lzip) + Документ PDF (сжатый lzip) + Dokument PDF (komprimovaný pomocou lzip) + ПДФ документ (запакован лзип-ом) + PDF-dokument (lzip-komprimerat) + PDF belgesi (lzip ile sıkıştırılmış) + документ PDF (стиснений lzip) + PDF 文档(lzip 压缩) + PDF 文件 (lzip 格式壓縮) @@ -14628,7 +15168,7 @@ arquivo LZMA Pacote LZMA Arhivă LZMA - архив LZMA + Архив LZMA Archív LZMA Datoteka arhiva LZMA Arkiv LZMA @@ -14650,7 +15190,7 @@ Archiŭ tar (LZMA-skampresavany) Архив — tar, компресиран с LZMA arxiu tar (amb compressió LZMA) - archiv tar (komprimovaný pomocí LZMA) + archiv Tar (komprimace LZMA) Tar-arkiv (LZMA-komprimeret) Tar-Archiv (LZMA-komprimiert) Αρχείο Tar (συμπιεσμένο με LZMA) @@ -14663,7 +15203,7 @@ cartlann Tar (comhbhrúite le LZMA) arquivo Tar (comprimido con LZMA) ארכיון Tar (מכווץ ע״י LZMA) - Tar arhiva (komprimirana LZMA-om) + Tar arhiva (LZMA sažeta) Tar archívum (LZMA-val tömörítve) Archivo Tar (comprimite con LZMA) Arsip Tar (terkompresi LZMA) @@ -14681,7 +15221,7 @@ arquivo Tar (compressão LZMA) Pacote Tar (compactado com LZMA) Arhivă Tar (comprimată LZMA) - архив TAR (сжатый LZMA) + Архив TAR (сжатый lzma) Archív tar (komprimovaný pomocou LZMA) Datoteka arhiva Tar (stisnjen z LZMA) Arkiv tar (i kompresuar me LZMA) @@ -14690,7 +15230,7 @@ Tar arşivi (LZMA ile sıkıştırılmış) архів tar (стиснений LZMA) Kho nén tar (đã nén LZMA) - Tar 归档文件 (LZMA 压缩) + Tar 归档文件(LZMA 压缩) Tar 封存檔 (LZMA 格式壓縮) @@ -14736,7 +15276,7 @@ arquivo LZO Pacote LZO Arhivă LZO - архив LZO + Архив LZO Archív LZO Datoteka arhiva LZO Arkiv LZO @@ -14764,9 +15304,9 @@ Συμπιεσμένο αρχείο Qpress Qpress archive archivador de Qpress - Qpress artxiboa Qpress-arkisto Archive Qpress + cartlann Qpress Arquivo Qpress ארכיון Qpress Qpress arhiva @@ -14780,7 +15320,7 @@ Archiwum Qpress arquivo Qpress Pacote Qpress - архив Qpress + Архив Qpress Archív Qpress Datoteka arhiva Qpress Купрес архива @@ -14806,6 +15346,7 @@ XAR artxiboa XAR-arkisto archive XAR + cartlann XAR ארכיון XAR XAR arhiva XAR archívum @@ -14816,7 +15357,7 @@ Archiu XAR Archiwum XAR Arquivo XAR - архив XAR + Архив XAR Archív XAR ИксАР архива XAR-arkiv @@ -14843,9 +15384,9 @@ Συμπιεσμένο αρχείο Zlib Zlib archive archivador Zlib - Zlib artxiboa Zlib-arkisto Archive Zlib + cartlann Zlib Arquivo Zlib ארכיון Zlib Zlib arhiva @@ -14859,7 +15400,7 @@ Archiwum Zlib arquivo Zlib Pacote Zlib - архив Zlib + Архив Zlib Archív Zlib Datoteka arhiva Zlib Злиб архива @@ -14912,7 +15453,7 @@ apresentação MagicPoint Apresentação do MagicPoint Prezentare MagicPoint - презентация MagicPoint + Презентация MagicPoint Prezentácia MagicPoint Predstavitev MagicPoint Prezantim MagicPoint @@ -14966,7 +15507,7 @@ ficheiro MacBinary de Macintosh Arquivo do Macintosh MacBinary Fișier Macintosh MacBinary - файл Macintosh MacBinary + Файл Macintosh MacBinary Súbor pre Macintosh MacBinary Izvedljiva dvojiška datoteka Macintosh MacBinary File MacBinary Macintosh @@ -15019,7 +15560,7 @@ fluxo Matroska Transmissão do Matroska Flux Matroska - поток Matroska + Поток Matroska Stream Matroska Pretočni vir Matroska Stream Matroska @@ -15045,6 +15586,7 @@ Matroska video Matroska مرئي + Videu en Matroska Videa Matroska Видео — Matroska vídeo Matroska @@ -15062,7 +15604,7 @@ físeán Matroska vídeo de Matroska וידאו Matroska - Matroska video + Matroška video snimka Matroska-videó Video Matroska Video Matroska @@ -15082,7 +15624,7 @@ vídeo Matroska Vídeo Matroska Video Matroska - видео Matroska + Видео Matroska Video Matroska Video datoteka Matroska Video Matroska @@ -15098,6 +15640,7 @@ Matroska 3D video + Videu en Matroska 3D vídeo Matroska 3D 3D video Matroska Matroska 3D-video @@ -15108,6 +15651,7 @@ Matroska 3D bideoa Matroska 3D-video vidéo Matroska 3D + físeán Matroska 3D Video Matroska 3D סרטון תלת ממדי מסוג Matroska Matroška 3D video snimka @@ -15153,7 +15697,7 @@ fuaim Matroska son de Matroska שמע Matroska - Matroska audio + Matroška zvučni zapis Matroska hang Audio Matroska Audio Matroska @@ -15172,7 +15716,7 @@ áudio Matroska Áudio Matroska Audio Matroska - аудио Matroska + Аудио Matroska Zvuk Matroska Zvočna datoteka Matroska Audio Matroska @@ -15189,6 +15733,7 @@ WebM video WebM مرئي + Videu en WebM Видео — WebM vídeo WebM video WebM @@ -15205,7 +15750,7 @@ físeán WebM vídeo WebM וידאו WebM - WebM video + WebM video snimka WebM videó Video WebM Video WebM @@ -15221,7 +15766,7 @@ vídeo WebM Vídeo WebM Video WebM - видео WebM + Видео WebM Video WebM Video datoteka WebM ВебМ видео @@ -15261,7 +15806,7 @@ fuaim WebM son WebM שמע WebM - WebM audio + WebM zvučni zapis WebM hang Audio WebM Audio WebM @@ -15277,7 +15822,7 @@ áudio WebM Áudio WebM Audio WebM - аудио WebM + Аудио WebM Zvuk WebM Zvočna datoteka WebM ВебМ звук @@ -15300,6 +15845,7 @@ MHTML web artxiboa MHTML-kooste archive web MHTML + cartlann ghréasáin MHTML Arquivo web MHTML ארכיון רשת MHTML MHTML web arhiva @@ -15315,7 +15861,7 @@ Archiwum witryny MHTML arquivo web MHTML Pacote web MHTML - веб-архив MHTML + Веб-архив MHTML Webový archív MHTML Spletni arhiv MHTML МХТМЛ веб архива @@ -15333,6 +15879,7 @@ MXF video MXF مرئي + Videu en MXF Видео — MXF vídeo MXF video MXF @@ -15349,7 +15896,7 @@ físeán MXF vídeo MXF וידאו MXF - MXF video + MXF video snimka MXF videó Video MXF Video MXF @@ -15366,7 +15913,7 @@ vídeo MXF Vídeo MXF Video MXF - видео MXF + Видео MXF Video MXF Video datoteka MXF МИксФ видео @@ -15421,7 +15968,7 @@ ficheiro OCL Arquivo OCL Fișier OCL - файл OCL + Файл OCL Súbor OCL Datoteka OCL File OCL @@ -15451,6 +15998,7 @@ COBOL iturburu-kodea COBOL-lähdekoodi fichier source COBOL + cód foinseach COBOL ficheiro fonte de COBOL קובץ מקור של COBOL COBOL izvorna datoteka @@ -15468,14 +16016,14 @@ Plik źródłowy COBOL ficheiro origem COBOL Arquivo de código-fonte em COBOL - файл исходного кода на COBOL + Файл исходного кода на COBOL Zdrojový súbor COBOLu Izvorna koda COBOL изворна датотека КОБОЛ-а COBOL-källkodsfil COBOL kaynak dosyası вихідний код мовою COBOL - COBOL 源 + COBOL 源文件 COBOL 源檔 COBOL COmmon Business Oriented Language @@ -15496,6 +16044,7 @@ Mobipocket liburua Mobipocket e-kirja livre numérique Mobipocket + r-leabhar Mobipocket E-book Mobipocket ספר אלקטרוני של Mobipocket Mobipocket e-knjiga @@ -15513,7 +16062,7 @@ E-book Mobipocket ebook Mobipocket E-book Mobipocket - электронная книга Mobipocket + Электронная книга Mobipocket E-kniha Mobipocket e-knjiga Mobipocket Мобипокет ел. књига @@ -15537,6 +16086,7 @@ Adobe FrameMaker MIF document مستند أدوبي الصانع للإطارات MIF + Documentu MIF d'Adobe FrameMaker Dakument Adobe FrameMaker MIF Документ — Adobe FrameMaker MIF document MIF d'Adobe FrameMaker @@ -15573,7 +16123,7 @@ documento Adobe FrameMaker MIF Documento MIF do Adobe FrameMaker Document Adobe FrameMaker MIF - документ Adobe FrameMaker MIF + Документ Adobe FrameMaker MIF Dokument Adobe FrameMaker MIF Dokument Adobe FrameMaker MIF Dokument MIF Adobe FrameMaker @@ -15606,7 +16156,7 @@ leabharmharcanna Mozilla Marcadores de Mozilla סימניה של Mozilla - Mozilla knjižne oznake + Mozilla zabilješke Mozilla-könyvjelzők Marcapaginas Mozilla Bookmark Mozilla @@ -15625,7 +16175,7 @@ marcadores do Mozilla Favoritos do Mozilla Semne de carte Mozilla - закладки Mozilla + Закладки Mozilla Záložky Mozilla Datoteka zaznamkov Mozilla Libërshënues Mozilla @@ -15683,7 +16233,7 @@ executável DOS/Windows Executável do DOS/Windows Executabil DOS/Windows - исполняемый файл DOS/Windows + Исполняемый файл DOS/Windows Spustiteľný súbor pre DOS/Windows Izvedljiva datoteka DOS/Windows I ekzekutueshëm DOS/Windows @@ -15741,7 +16291,7 @@ Internetový odkaz Internetna bližnjica Shkurtim internet - Интернет пречица + интернет пречица Internetgenväg İnternet kısayolu інтернет-посилання @@ -15759,6 +16309,7 @@ WRI document مستند WRI + Documentu WRI Dakument WRI Документ — WRI document WRI @@ -15794,7 +16345,7 @@ documento WRI Documento WRI Document WRI - документ WRI + Документ WRI Dokument WRI Dokument WRI Dokument WRI @@ -15847,7 +16398,7 @@ ROM MSX Plik ROM konsoli MSX ROM MSX - ROM do MSX + ROM de MSX ROM MSX MSX ROM ROM pre MSX @@ -15900,7 +16451,7 @@ macro M4 Macro M4 Macro M4 - макрос M4 + Макрос M4 Makro M4 Makro datoteka M4 Macro M4 @@ -15952,7 +16503,7 @@ ROM Nintendo64 Plik ROM konsoli Nintendo64 ROM Nintendo64 - ROM do Nintendo64 + ROM de Nintendo64 ROM Nintendo64 Nintendo64 ROM ROM pre Nintendo64 @@ -15963,7 +16514,7 @@ Nintendo64 ROM ППП Nintendo64 ROM Nintendo64 - Nintendo64 ROM + 任天堂 64 ROM Nintendo64 ROM @@ -16000,7 +16551,7 @@ nasc Nautilus ligazón de nautilus קישור של Nautilus - Nautilus veza + Nautilusova poveznica Nautilus-link Ligamine Nautilus Taut Nautilus @@ -16019,7 +16570,7 @@ atalho Nautilus Link do Nautilus Legătură Nautilus - ссылка Nautilus + Ссылка Nautilus Odkaz Nautilus Datoteka povezave Nautilus Lidhje Nautilus @@ -16039,25 +16590,49 @@ Neo-Geo Pocket ROM ROM de Neo-Geo Pocket + ROM pro Neo-Geo Pocket Neo-Geo Pocket ROM Neo-Geo Pocket ROM + Neo-Geo Pocket ROM ROM de Neo-Geo Pocket + Neo-Geo Pocket ROM Neo-Geo Pocket -ROM ROM Neo-Geo Pocket + ROM Neo-Geo Pocket + Neo-Geo Pocket ROM Neo-Geo Pocket ROM + ROM Neo-Geo Pocket + ROM Neo-Geo Pocket Neo-Geo Pocket ROM 네오지오 포켓 롬 Plik ROM konsoli Neo-Geo Pocket ROM de Neo-Geo Pocket Neo-Geo Pocket ROM ROM pre Neo-Geo Pocket + Нео-Гео Покет РОМ + Neo-Geo Pocket-rom + Neo-Geo Pocket ROM ППП Neo-Geo Pocket Neo-Geo Pocket ROM Neo-Geo Pocket ROM - + + + + + + + + Neo-Geo Pocket Color ROM + + + + + + + @@ -16099,7 +16674,7 @@ ROM NES Plik ROM konsoli NES ROM NES - ROM do NES + ROM de NES ROM NES NES ROM ROM pre NES @@ -16121,6 +16696,7 @@ Unidata NetCDF document مستند Unidata NetCDF + Documentu NetCDF d'Unidata Dakument Unidata NetCDF Документ — Unidata NetCDF document d'Unidata NetCDF @@ -16157,7 +16733,7 @@ documento Unidata NetCDF Documento do Unidata NetCDF Document Unidata NetCDF - документ Unidata NetCDF + Документ Unidata NetCDF Dokument Unidata NetCDF Dokument Unidata NetCDF Dokument Unidata NetCDF @@ -16186,6 +16762,7 @@ índice NewzBin de usenet NewzBin usenet indizea index usenet + innéacs usenet NewzBin Índice de usenet NEwzBin אינדקס שרתי חדשות NewzBin NewzBin usenet indeks @@ -16202,14 +16779,14 @@ Indeks grup dyskusyjnych NewzBin índice usenet NewzBin Índice de usenet NewzBin - индекс usenet NewzBin + Индекс usenet NewzBin Index Usenetu NewzBin Kazalo usenet NewzBin Њузбин попис јузнета NewzBin-usenetindex NewzBin usenet dizini покажчик usenet NewzBin - NewzBin usenet 索引 + NewzBin Usenet 索引 NewzBin usenet 索引 @@ -16236,10 +16813,10 @@ cód réada código obxecto קוד אובייקט - kod objekta + Object kôd tárgykód Codice objecto - kode object + kode objek Codice oggetto オブジェクトコード объектті коды @@ -16255,7 +16832,7 @@ código de objeto Código-objeto cod sursă obiect - объектный код + Объектный код Objektový kód predmetna koda Kod objekti @@ -16299,7 +16876,7 @@ formáid mhalairte Annodex formato intercambiábel de Annodex תבנית החלפת Annodex - Annodex oblik za razmjenu + Annodex format razmjene Annodex csereformátum Formato de excambio Annodex Format pertukaran Annodex @@ -16316,7 +16893,7 @@ formato de troca Annodex Formato de troca Annodex Format schimb Annodex - формат обмена Annodex + Формат обмена Annodex Formát pre výmenu Annodex Izmenjalna datoteka Annodex Анодексов запис размене @@ -16340,6 +16917,7 @@ Annodex Video Annodex مرئي + Videu n'Annodex Видео — Annodex Annodex Video video Annodex @@ -16353,10 +16931,10 @@ Annodex-video Annodex video vidéo Annodex - físeán Annodex + Físeán Annodex vídeo de Annodex וידאו Annodex - Annodex Video + Annodex video snimka Annodex videó Video Annodex Video Annodex @@ -16373,7 +16951,7 @@ vídeo Annodex Vídeo Annodex Video Annodex - видео Annodex + Видео Annodex Video Annodex Video datoteka Annodex Анодекс видео @@ -16410,10 +16988,10 @@ Annodex-ääni Annodex ljóður audio Annodex - fuaim Annodex + Fuaim Annodex son de Annodex שמע Annodex - Annodex Audio + Annodex zvučni zapis Annodex hang Audio Annodex Audio Annodex @@ -16430,7 +17008,7 @@ áudio Annodex Áudio Annodex Audio Annodex - аудио Annodex + Аудио Annodex Zvuk Annodex Zvočna datoteka Annodex Анодекс аудио @@ -16489,7 +17067,7 @@ ficheiro multimédia Ogg Arquivo multimídia Ogg Fișier multimedia Ogg - мультимедийный файл Ogg + Мультимедийный файл Ogg Súbor multimédií Ogg Večpredstavnostna datoteka Ogg File multimedial Ogg @@ -16523,7 +17101,7 @@ Ogg-ääni Ogg ljóður audio Ogg - fuaim Ogg + Fuaim Ogg son Ogg שמע Ogg Ogg zvučni zapis @@ -16545,7 +17123,7 @@ áudio Ogg Áudio Ogg Audio Ogg - аудио Ogg + Аудио Ogg Zvuk Ogg Zvočna datoteka Ogg Audio Ogg @@ -16568,6 +17146,7 @@ Ogg Video Ogg مرئي + Videu n'Ogg Videa Ogg Видео — Ogg vídeo Ogg @@ -16581,7 +17160,7 @@ Ogg-video Ogg Video vidéo Ogg - físeán Ogg + Físeán Ogg vídeo Ogg וידאו Ogg Ogg video snimka @@ -16603,7 +17182,7 @@ vídeo Ogg Vídeo Ogg Video Ogg - видео Ogg + Видео Ogg Video Ogg Video datoteka Ogg Video Ogg @@ -16664,7 +17243,7 @@ áudio Ogg Vorbis Áudio Ogg Vorbis Audio Ogg Vorbis - аудио Ogg Vorbis + Аудио Ogg Vorbis Zvuk Ogg Vorbis Zvočna datoteka Ogg Vorbis Audio Ogg Vorbis @@ -16724,7 +17303,7 @@ áudio Ogg FLAC Áudio Ogg FLAC Audio Ogg FLAC - аудио Ogg FLAC + Аудио Ogg FLAC Zvuk Ogg FLAC Zvočna datoteka Ogg FLAC Audio Ogg FLAC @@ -16760,6 +17339,7 @@ Opus audioa Opus-ääni audio Opus + fuaim Opus Son Opus שמע Opus Opus zvučni zapis @@ -16828,7 +17408,7 @@ áudio Ogg Speex Áudio Ogg Speex Audio Ogg Speex - аудио Ogg Speex + Аудио Ogg Speex Zvuk Ogg Speex Zvočna datoteka Ogg Speex Audio Ogg Speex @@ -16867,7 +17447,7 @@ fuaim Speex son Speex שמע של Speex - Speex audio + Speex zvučni zapis Speex hang Audio Speex Audio Speex @@ -16885,7 +17465,7 @@ áudio Speex Áudio Speex Audio Speex - аудио Speex + Аудио Speex Zvuk Speex Zvočna datoteka Speex Audio Speex @@ -16904,6 +17484,7 @@ Ogg Theora video Ogg Theora مرئي + Videu n'Ogg Theora Videa Ogg Theora Видео — Ogg Theora vídeo Ogg Theora @@ -16939,7 +17520,7 @@ vídeo Ogg Theora Vídeo Ogg Theora Video Ogg Theora - видео Ogg Theora + Видео Ogg Theora Video Ogg Theora Video datoteka Ogg Theora Video Ogg Theora @@ -16962,6 +17543,7 @@ OGM video OGM مرئي + Videu n'OGM Videa OGM Видео — OGM vídeo OGM @@ -16979,7 +17561,7 @@ físeán OGM vídeo OGM וידאו OGM - OGM video + OGM video snimka OGM-videó Video OGM Video OGM @@ -16998,7 +17580,7 @@ vídeo OGM Vídeo OGM Video OGM - видео OGM + Видео OGM Video OGM Video datoteka OGM Video OGM @@ -17022,6 +17604,7 @@ OLE2 compound document storage تخزين مجمع مستند OLE2 + Almacenamientu de documentos compuestu por OLE2 Schovišča dla kampanentaŭ dakumentu OLE2 Съставен документ-хранилище — OLE2 emmagatzematge de documents compostos OLE2 @@ -17036,7 +17619,7 @@ OLE2-yhdisteasiakirjatallenne OLE2 samansett skjalagoymsla document de stockage composé OLE2 - stóras cháipéisí comhshuite OLE2 + stóras cáipéisí comhshuite OLE2 almacenamento de documento composto OLE2 אחסון מסמך משותף OLE2 OLE2 pohrana složenog dokumenta @@ -17058,7 +17641,7 @@ armazenamento de documento composto OLE2 Armazenamento de documento composto OLE2 Document de stocare compus OLE2 - хранилище составных документов OLE2 + Хранилище составных документов OLE2 Úložisko zloženého dokumentu OLE2 Združeni dokument OLE2 Arkiv dokumenti i përbërë OLE2 @@ -17077,6 +17660,7 @@ Microsoft Publisher document + Documentu de Microsoft Publisher document de Microsoft Publisher dokument Microsoft Publisher Microsoft Publisher-dokument @@ -17087,6 +17671,7 @@ Microsoft Publisher dokumentua Microsoft Publisher -asiakirja document Microsoft Publisher + cáipéis Microsoft Publisher Documento de Microsoft Publisher מסמך Microsoft Publisher Microsoft Publisher dokument @@ -17131,7 +17716,7 @@ pacáiste Windows Installer paquete de instalación de Windows חבילה של Windows Installer - Windows Installer paket + Windows Instalacijski paket Windows Installer csomag Pacchetto Windows Installer Paket Windows Installer @@ -17148,7 +17733,7 @@ pacote de instalação Windows Pacote do Windows Installer Pachet instalator Windows - пакет Windows Installer + Пакет Windows Installer Balík Windows Installer Datoteka paketa Windows namestilnika Paketë Windows Installer @@ -17202,7 +17787,7 @@ folha de cálculo GNU Oleo Planilha do GNU Oleo Foaie de calcul GNU Oleo - электронная таблица GNU Oleo + Электронная таблица GNU Oleo Zošit GNU Oleo Preglednica GNU Oleo Fletë llogaritje GNU Oleo @@ -17211,7 +17796,7 @@ GNU Oleo çalışma sayfası ел. таблиця GNU Oleo Bảng tính Oleo của GNU - GNU Oleo 工作簿 + GNU Oleo 电子表格 GNU Oleo 試算表 @@ -17258,7 +17843,7 @@ arquivo PAK Pacote PAK Arhivă PAK - архив PAK + Архив PAK Archív PAK Datoteka arhiva PAK Arkiv PAK @@ -17267,7 +17852,7 @@ PAK arşivi архів PAK Kho nén PAK - AR 归档文件 + PAK 归档文件 PAK 封存檔 @@ -17316,7 +17901,7 @@ base de dados Palm OS Banco de dados do Palm OS Bază de date Palm OS - база данных Palm OS + База данных Palm OS Databáza Palm OS Podatkovna zbirka Palm OS Bankë me të dhëna Palm OS @@ -17370,7 +17955,7 @@ arquivo Parchive Pacote Parchive Arhivă Parchive - архив Parchive + Архив Parchive Archív Parchive Datoteka arhiva Parchive Arkiv Parchive @@ -17429,7 +18014,7 @@ executável PEF Executável PEF Executabil PEF - исполняемый файл PEF + Исполняемый файл PEF Spustiteľný súbor PEF Izvedljiva datoteka PEF E ekzekutueshme PEF @@ -17485,7 +18070,7 @@ script Perl Script Perl Script Perl - сценарий Perl + Сценарий Perl Skript jazyka Perl Skriptna datoteka Perl Script Perl @@ -17499,6 +18084,7 @@ + @@ -17563,7 +18149,7 @@ script PHP Script PHP Script PHP - сценарий PHP + Сценарий PHP Skript PHP Skriptna datoteka PHP Script PHP @@ -17600,7 +18186,7 @@ PKCS#7-varmennenippu PKCS#7 váttanar bundi lot de certificats PKCS#7 - cuach theastas PKCS#7 + burla teastas PKCS#7 paquete de certificado PKCS#7 בקשה מוסמכת PKCS#7 PKCS#7 paket vjerodajnica @@ -17619,7 +18205,7 @@ pacote de certificação PKCS#7 Pacote de certificados PKCS#7 Pachet certificat PKCS#7 - пакет сертификатов PKCS#7 + Пакет сертификата PKCS#7 Zväzok certifikátov PKCS#7 Datoteka potrdila PKCS#7 ПКЦС#7 пакет уверења @@ -17651,7 +18237,7 @@ PKCS#12-varmennenippu PKCS#12 váttanar bundi lot de certificats PKCS#12 - cuach theastas PKCS#12 + burla teastas PKCS#12 paquete de certificado PKCS#12 בקשה מוסמכת PKCS#12 PKCS#12 paket vjerodajnica @@ -17673,7 +18259,7 @@ pacote de certificação PKCS#12 Pacote de certificados PKCS#12 Certificat împachetat PKCS#12 - пакет сертификатов PKCS#12 + Пакет сертификата PKCS#12 Zväzok certifikátov PKCS#12 Datoteka potrdila PKCS#12 Bundle çertifikate PKCS#12 @@ -17727,7 +18313,7 @@ folha de cálculo PlanPerfect Planilha do PlanPerfect Foaie de calcul PlanPerfect - электронная таблица PlanPerfect + Электронная таблица PlanPerfect Zošit PlanPerfect Preglednica PlanPerfect Fletë llogaritjesh PlanPerfect @@ -17736,7 +18322,7 @@ PlanPerfect çalışma sayfası ел. таблиця PlanPerfect Bảng tính PlanPerfect - PlanPerfect 工作簿 + PlanPerfect 电子表格 PlanPerfect 試算表 @@ -17744,6 +18330,7 @@ Pocket Word document مستند Pocket Word + Documentu de PocketWord Документ — Pocket Word document de Pocket Word dokument Pocket Word @@ -17775,7 +18362,7 @@ documento Pocket Word Documento do Pocket Word Document Pocket Word - документ Pocket Word + Документ Pocket Word Dokument Pocket Word Dokument Pocket Word документ Покет Ворда @@ -17831,7 +18418,7 @@ resultados de análise de perfil Resultados do profiler rezultate profiler - результаты профилирования + Результаты профилирования Výsledky profilera rezultati profilirnika Rezultate të profiluesit @@ -17840,7 +18427,7 @@ profil sonuçları результати профілювання kết quả nét hiện trạng - profiler 结果 + 探查器结果 硬體資訊產生器成果 @@ -17849,6 +18436,7 @@ Pathetic Writer document مستند Pathetic Writer + Documentu de Pathetic Writer Dakument Pathetic Writer Документ — Pathetic Writer document de Pathetic Writer @@ -17885,7 +18473,7 @@ documento do Pathetic Writer Documento do Pathetic Writer Document Pathetic Writer - документ Pathetic Writer + Документ Pathetic Writer Dokument Pathetic Writer Dokument Pathetic Writer Dokument Pathetic Writer @@ -17940,7 +18528,7 @@ código binário Python Código compilado Python Bytecode Python - байт-код Python + Байт-код Python Bajtový kód Python Datoteka bitne kode Python Bytecode Python @@ -17959,6 +18547,7 @@ QtiPlot document + Documentu de QtiPlot document QtiPlot dokument GtiPlot QtiPlot-dokument @@ -17969,6 +18558,7 @@ QtiPlot dokumentua QtiPlot-asiakirja document QtiPlot + cáipéis QtiPlot Documento de QtiPilot מסמך QtiPlot QtiPlot dokument @@ -17984,7 +18574,7 @@ Dokument QtiPlot documento QtiPlot Documento do QtiPlot - документ QtiPlot + Документ QtiPlot Dokument QtiPlot Dokument QtiPlot КутиПлот документ @@ -18040,7 +18630,7 @@ folha de cálculo Quattro Pro Planilha do Quattro Pro Foaie de calcul Quattro Pro - электронная таблица Quattro Pro + Электронная таблица Quattro Pro Zošit Quattro Pro Preglednica Quattro Pro Fletë llogaritjesh Quattro Pro @@ -18049,7 +18639,7 @@ Quattro Pro çalışma sayfası ел. таблиця Quattro Pro Bảng tính Quattro Pro - Quattro Pro 工作簿 + Quattro Pro 电子表格 Quattro Pro 試算表 @@ -18093,7 +18683,7 @@ lista de reprodução QuickTime metalink Lista de reprodução metalink do QuickTime Listă cu metalegături QuickTime - список воспроизведения мета-ссылок QuickTime + Список воспроизведения мета-ссылок QuickTime Zoznam skladieb metalink QuickTime Seznam predvajanja QuickTime Listë titujsh metalink QuickTime @@ -18102,7 +18692,7 @@ QuickTime metalink çalma listesi список відтворення QuickTime metalink Danh mục nhạc siêu liên kết Quicktime - QuickTime 元链接播放列表 + QuickTime Metalink 播放列表 QuickTime metalink 播放清單 @@ -18120,6 +18710,7 @@ Quicken document مستند Quicken + Documentu de Quicken Quicken sənədi Dakument Quicken Документ — Quicken @@ -18158,7 +18749,7 @@ documento Quicken Documento do Quicken Document Quicken - документ Quicken + Документ Quicken Dokument Quicken Dokument Quicken Dokument Quicken @@ -18212,7 +18803,7 @@ arquivo RAR Pacote RAR Arhivă RAR - архив RAR + Архив RAR Archív RAR Datoteka arhiva RAR Arkiv RAR @@ -18272,7 +18863,7 @@ arquivo DAR Pacote DAR Arhivă DAR - архив DAR + Архив DAR Archív DAR Datoteka arhiva DAR Arkiv DAR @@ -18328,7 +18919,7 @@ arquivo Alzip Pacote Alzip Arhivă Alzip - архив ALZIP + Архив ALZIP Archív Alzip Datoteka arhiva Alzip Arkiv Alzip @@ -18358,14 +18949,14 @@ rejected patch reĵeta flikaĵo parche rechazado - baztertutako bide-izena + baztertutako adabakia hylättyjen muutosten tiedosto vrakað rætting correctif rejeté paiste diúltaithe parche rexeitado טלאי שנדחה - odbijena zakrpa + Odbijena zakrpa visszautasított folt Patch rejectate patch ditolak @@ -18384,7 +18975,7 @@ patch rejeitado Arquivo de patch rejeitado petec respsins - отвергнутый патч + Отклонённый патч Odmietnutá záplata zavrnjen popravek Patch i kthyer mbrapsht @@ -18439,7 +19030,7 @@ pacote RPM Pacote RPM Pachet RPM - пакет RPM + Пакет RPM Balík RPM Datoteka paketa RPM Paketë RPM @@ -18469,6 +19060,7 @@ Iturburu RPM paketea RPM-lähdepaketti paquet source RPM + pacáiste foinse RPM Paquete RPM de fontes חבילת מקור RPM RPM paket izvora @@ -18484,7 +19076,7 @@ Źródłowy pakiet RPM pacote origem RPM Pacote fonte RPM - пакет RPM с исходным кодом + Пакет RPM с исходным кодом Zdrojový balík RPM Paket izvorne kode RPM изворни РПМ пакет @@ -18537,7 +19129,7 @@ script Ruby Script Ruby Script Ruby - сценарий Ruby + Сценарий Ruby Skript Ruby Skriptna datoteka Ruby Script Ruby @@ -18596,7 +19188,7 @@ script Markaby Script Markaby Script Markaby - сценарий Markaby + Сценарий Markaby Skript Markaby Skriptna datoteka Markaby Script Markaby @@ -18623,6 +19215,7 @@ Rust iturburu-kodea Rust-lähdekoodi code source Rust + cód foinseach Rust קוד מקור של Rust Rust izvorni kôd Rust forrásfájl @@ -18635,7 +19228,7 @@ Kod źródłowy Rust código origem Rust Código-fonte Rust - исходный код Rust + Исходный код Rust Zdrojový kód Rust Раст изворни ко̂д Rust-källkod @@ -18684,7 +19277,7 @@ folha de cálculo SC/Xspread Planilha do SC/Xspread Foaie de calcul SC/Xspread - электронная таблица SC/Xspread + Электронная таблица SC/Xspread Zošit SC/Xspread Preglednica SC/Xspread Fletë llogaritjesh SC/Xspread @@ -18693,7 +19286,7 @@ SC/Xspread çalışma sayfası ел. таблиця SC/Xspread Bảng tính SC/Xspread - SC/Xspread 工作簿 + SC/Xspread 电子表格 SC/Xspread 試算表 @@ -18722,7 +19315,7 @@ cartlann bhlaoisce ficheiro shell ארכיון מעטפת - arhiva ljuske + Arhiva ljuske héjarchívum Archivo de shell arsip shell @@ -18741,7 +19334,7 @@ arquivo de terminal Pacote shell arhivă shell - архив оболочки UNIX + Архив shell Archív shellu lupinski arhiv Arkiv shell @@ -18792,7 +19385,7 @@ biblioteca partilhada libtool Biblioteca compartilhada libtool bibliotecă partajată libtool - разделяемая библиотека libtool + Разделяемая библиотека libtool Zdieľaná knižnica libtool Souporabna knjižnica libtool Librari e përbashkët libtool @@ -18848,7 +19441,7 @@ biblioteca partilhada Biblioteca compartilhada bibliotecă partajată - разделяемая библиотека + Разделяемая библиотека Zdieľaná knižnica souporabljena knjižnica Librari e përbashkët @@ -18883,7 +19476,7 @@ qabıq skripti skrypt abałonki Скрипт на обвивката - script de shell + script shell skript shellu sgript plisgyn skalprogram @@ -18899,7 +19492,7 @@ script bhlaoisce script de shell תסריט מעטפת - skripta ljuske + Skripta ljuske héj-parancsfájl Script de shell skrip shell @@ -18918,7 +19511,7 @@ script de terminal Script shell script shell - сценарий оболочки UNIX + Сценарий shell Skript shellu lupinski skript Script shell @@ -18987,7 +19580,7 @@ ficheiro Shockwave Flash Arquivo Shockwave Flash Fișier Shockwave Flash - файл Shockwave Flash + Файл Shockwave Flash Súbor Shockwave Flash Datoteka Shockwave Flash File Flash Shockwave @@ -19029,7 +19622,7 @@ fuaim Shorten son Shorten שמע של Shorten - Shorten audio + Shorten zvučni zapis Shorten hang Audio Shorten Audio Shorten @@ -19047,7 +19640,7 @@ áudio Shorten Áudio Shorten Audio Shorten - аудио Shorten + Аудио Shorten Zvuk Shorten Zvočna datoteka Shorten Audio Shorten @@ -19104,7 +19697,7 @@ folha de cálculo Siag Planilha do Siag Foaie de calcul Siag - электронная таблица Siag + Электронная таблица Siag Zošit Siag Preglednica Siag Fletë llogaritjesh Siag @@ -19113,7 +19706,7 @@ Siag çalışma sayfası ел. таблиця Siag Bảng tính Slag - Siag 工作簿 + Siag 电子表格 Siag 試算表 @@ -19121,6 +19714,7 @@ Skencil document مستند Skencil + Documentu de Skencil Dakument Skencil Документ — Skencil document Skencil @@ -19155,7 +19749,7 @@ documento Skencil Documento do Skencil Document Skencil - документ Skencil + Документ Skencil Dokument Skencil Dokument Skencil Dokument Skencil @@ -19213,7 +19807,7 @@ pacote Stampede Pacote Stampede Pachet Stampede - пакет Stampede + Пакет Stampede Balíček Stampede Datoteka paketa Stampede Paketë Stampede @@ -19229,18 +19823,28 @@ SG-1000 ROM ROM de SG-1000 + ROM pro SG-1000 SG-1000 ROM SG-1000 ROM + SG-1000 ROM ROM de SG-1000 + SG-1000 ROM SG-1000 -ROM ROM SG-1000 + ROM SG-1000 + SG-1000 ROM SG-1000 ROM + ROM SG-1000 + ROM SG-1000 SG-1000 ROM SG-1000 롬 Plik ROM konsoli SG-1000 ROM de SG-1000 SG-1000 ROM ROM pre SG-1000 + СГ-1000 РОМ + SG-1000-rom + SG-1000 ROM ППП SG-1000 SG-1000 ROM SG-1000 ROM @@ -19251,18 +19855,28 @@ Master System ROM ROM de Master System + ROM pro Master System Master System ROM Master System ROM + Master System ROM ROM de Master System + Master System ROM Master System -ROM ROM Master System + ROM Master System + Master System ROM Master System ROM + ROM Master System + ROM Master System Master System ROM 마스터 시스템 롬 Plik ROM konsoli SMS ROM de Master System Master System ROM ROM pre Master System + Мастер Систем РОМ + Master System-rom + Master System ROM ППП Master System Master System ROM Master System ROM @@ -19273,18 +19887,28 @@ Game Gear ROM ROM de Game Gear + ROM pro Game Gear Game Gear ROM Game Gear ROM + Game Gear ROM ROM de Game Gear + Game Gear ROM Game Gear -ROM ROM Game Gear + ROM Game Gear + Game Gear ROM Game Gear ROM + ROM Game Gear + ROM Game Gear Game Gear ROM 게임 기어 롬 Plik ROM konsoli Game Gear ROM de Game Gear Game Gear ROM ROM pre Game Gear + Гејм Гир РОМ + Game Gear-rom + Game Gear ROM ППП Game Gear Game Gear ROM Game Gear ROM @@ -19328,7 +19952,7 @@ ROM Super Nintendo Plik ROM konsoli SNES ROM Super Nintendo - ROM do Super Nintendo + ROM de Super Nintendo ROM Super Nintendo Super NES ROM ROM pre Super Nintendo @@ -19384,7 +20008,7 @@ arquivo StuffIt Pacote StuffIt Arhivă StuffIt - архив StuffIt + Архив StuffIt Archív StuffIt Datoteka arhiva StuffIt Arkiv StuffIt @@ -19424,7 +20048,7 @@ fotheidil SubRip subtítulos SubRip כתוביות של SubRip - SubRip titlovi + SubRip podnaslovi SubRip feliratok Subtitulos SubRip Subjudul SubRip @@ -19442,7 +20066,7 @@ legendas SubRip Legendas SubRip Subtitrare SubRip - субтитры SubRip + Субтитры SubRip Titulky SubRip Datoteka podnapisov SubRip Nëntituj SubRip @@ -19476,12 +20100,13 @@ WebVTT azpitituluak WebVTT-tekstitykset sous-titres WebVTT + fotheidil WebVTT subtítulos WebVTT כתוביות WebVTT - WebVTT titlovi + WebVTT podnaslovi WebVTT feliratok Subtitulos WebVTT - Subtitel WebVTT + Subjudul WebVTT Sottotitoli WebVTT WebVTT サブタイトル WebVTT ქვეტიტრები @@ -19493,7 +20118,7 @@ Napisy WebVTT legendas WebVTT Legendas WebVTT - субтитры WebVTT + Субтитры WebVTT Titulky WebVTT Podnapisi WebVTT Веб ВТТ преводи @@ -19531,7 +20156,7 @@ fotheidil SAMI subtítulos SAMI כתוביות SAMI - SAMI titlovi + SAMI podnaslovi SAMI feliratok Subtitulos SAMI Subjudul SAMI @@ -19549,7 +20174,7 @@ legendas SAMI Legendas SAMI Subtitrări SAMI - субтитры SAMI + Субтитры SAMI Titulky SAMI Datoteka podnapisov SAMI Nëntituj SAMI @@ -19590,7 +20215,7 @@ fotheidil MicroDVD subtítulos de MicroDVD כתוביות של MicroDVD - MicroDVD titlovi + MicroDVD podnaslovi MicroDVD feliratok Subtitulos MicroDVD Subjudul MicroDVD @@ -19609,7 +20234,7 @@ legendas MicroDVD Legendas MicroDVD Subtitrări MicroDVD - субтитры MicroDVD + Субтитры MicroDVD Titulky MicroDVD Datoteka podnapisov MicroDVD Nëntituj MicroDVD @@ -19648,7 +20273,7 @@ fotheidil MPSub subtítulos MPSub כתוביות MPSub - MPSub titlovi + MPSub podnaslovi MPSub feliratok Subtitulos MPSub Subjudul MPSub @@ -19667,7 +20292,7 @@ legendas MPSub Legendas MPSub Subtitrări MPSub - субтитры MPSub + Субтитры MPSub Titulky MPSub Datoteka podnapisov MPSub Nëntituj MPSub @@ -19706,7 +20331,7 @@ fotheidil SSA Subtitulos SSA כתובית SSA - SSA titlovi + SSA podnaslovi SSA feliratok Subtitulos SSA Subjudul SSA @@ -19724,7 +20349,7 @@ legendas SSA Legendas SSA Subtitrări SSA - субтитры SSA + Субтитры SSA Titulky SSA Datoteka podnapisov SSA Nëntituj SSA @@ -19765,7 +20390,7 @@ fotheidil SubViewer subtítulos SubViewer כתוביות של SubViewer - SubViewer titlovi + SubViewer podnaslovi SubViewer feliratok Subtitulos SubViewer Subjudul SubViewer @@ -19783,7 +20408,7 @@ legendas SubViewer Legendas SubViewer Subtitrare SubViewer - субтитры SubViewer + Субтитры SubViewer Titulky SubViewer Datoteka podnapisov SubViewer Nëntituj SubViewer @@ -19819,7 +20444,7 @@ ton buailte iMelody Melodía de iMelody צלצול של iMelody - iMelody ton zvonjenja + iMelody melodija zvona iMelody csengőhang Tono de appello iMelody nada dering iMelody @@ -19837,7 +20462,7 @@ toque iMelody Toque de celular do iMelody Sonerie iMelody - мелодия iMelody + Мелодия iMelody Vyzváňacie melódie iMelody Zvonjenje iMelody Zile iMelody @@ -19876,7 +20501,7 @@ fuaim SMAF son SMAF שמע SMAF - SMAF audio + SMAF zvučni zapis SMAF hang Audio SMAF Audio SMAF @@ -19894,7 +20519,7 @@ áudio SMAF Áudio SMAF Audio SMAF - аудио SMAF + Аудио SMAF Zvuk SMAF Zvočna datoteka SMAF Audio SMAF @@ -19935,7 +20560,7 @@ seinmliosta MRML lista de reprodución MRML רשימת השמעה MRML - MRML popis za reprodukciju + MRML popis izvođenja MRML-lejátszólista Lista de selection MRML Senarai putar MRML @@ -19954,7 +20579,7 @@ lista de reprodução MRML Lista de reprodução do MRML Listă redare MRML - список воспроизведения MRML + Список воспроизведения MRML Zoznam skladieb MRML Seznam predvajanja MRML Listë titujsh MRML @@ -19993,7 +20618,7 @@ fuaim XMF son XMF שמע XMF - XMF audio + XMF zvučni zapis XMF hang Audio XMF Audio XMF @@ -20011,7 +20636,7 @@ aúdio XMF Áudio XMF Audio XMF - аудио XMF + Аудио XMF Zvuk XMF Zvočna datoteka XMF Audio XMF @@ -20073,7 +20698,7 @@ arquivo SV4 CPIO Pacote SV4 CPIO Arhivă SV4 CPIO - архив SV4 CPIO + Архив SV4 CPIO Archív SV4 CPIO Datoteka arhiva SV4 CPIO Arkiv SV4 CPIO @@ -20126,7 +20751,7 @@ arquivo SV4 CPIO (com CRC) Pacote SV4 CPIO (com CRC) Arhivă SV4 CPIO (cu CRC) - архив SV4 CPIP (с CRC) + Архив SV4 CPIO (с CRC) Archív SV4 CPIO (s CRC) Datoteka arhiva SV4 CPIO (z razpršilom CRC) Arkiv SV4 CPIO (me CRC) @@ -20135,7 +20760,7 @@ SV4 CPIO arşivi (CRC ile) архів SV4 CPIO (з CRC) Kho nén CPIO SV4 (với CRC) - SV4 CPIP 归档文件(带有 CRC) + SV4 CPIP 归档文件(带 CRC) SV4 CPIO 封存檔 (具有 CRC) @@ -20180,7 +20805,7 @@ arquivo Tar Pacote Tar Arhivă Tar - архив TAR + Архив TAR Archív tar Datoteka arhiva Tar Arkiv tar @@ -20220,7 +20845,7 @@ cartlann Tar (comhbhrúite) arquivo Tar (comprimido) ארכיון Tar (מכווץ) - Tar arhiva (komprimirana) + Tar arhiva (sažeta) Tar archívum (tömörített) Archivo Tar (comprimite) Arsip Tar (terkompresi) @@ -20238,7 +20863,7 @@ arquivo Tar (comprimido) Pacote Tar (compactado) Arhivă Tar (comprimată) - архив TAR (сжатый) + Архив TAR (сжатый) Archív tar (komprimovaný) Datoteka arhiva Tar (stisnjen) Arkiv tar (i kompresuar) @@ -20247,7 +20872,7 @@ Tar arşivi (sıkıştırılmış) архів tar (стиснений) Kho nén tar (đã nén) - Tar 归档文件(压缩) + Tar 归档文件(压缩) Tar 封存檔 (UNIX 格式壓縮) @@ -20259,8 +20884,8 @@ ملف الخط العام zvyčajny fajł šryftu Шрифт - fitxer genèric de tipus de lletra - obecný soubor písma + fitxer de lletra genèrica + obecný soubor s fontem general skrifttypefil Allgemeine Schriftdatei Γενικό αρχείο γραμματοσειράς @@ -20274,7 +20899,7 @@ comhad cló ginearálta ficheiro de tipo de fonte xenérica קובץ גופן גנרי - općenita datoteka fonta + Izvorna datoteka slova általános betűkészletfájl File de typo de litteras generic berkas fonta generik @@ -20293,7 +20918,7 @@ ficheiro genérico de letra Arquivo de fonte genérico fișier de font generic - обычный файл шрифта + Обычный файл шрифта Obyčajný súbor písma izvorna datoteka pisave File lloj gërme i përgjithshëm @@ -20312,8 +20937,8 @@ ملف الخط المرزم zapakavany fajł šryftu Шрифт — компресиран - fitxer empaquetat de tipus de lletra - komprimovaný soubor písma + fitxer de lletra empaquetada + komprimovaný soubor s fontem pakket skrifttypefil Gepackte Schriftdatei Αρχείο συμπιεσμένης γραμματοσειράς @@ -20327,7 +20952,7 @@ comhad cló pacáilte ficheiro de fonte empaquetada קובץ גופן ארוז - pakirana datoteka fonta + Zapakirana datoteka slova packed font-fájl File de typos de litteras impacchettate berkas fonta terkemas @@ -20346,7 +20971,7 @@ ficheiro de letras empacotadas Arquivo de fonte empacotado fișier font împachetat - сжатый файл шрифта + Сжатый файл шрифта Komprimovaný súbor písma pakirana datoteka pisave File lloj gërmash i kondensuar @@ -20363,6 +20988,7 @@ TGIF document مستند TGIF + Documentu de TGIF Dakument TGIF Документ — TGIF document TGIF @@ -20399,7 +21025,7 @@ documento TGIF Documento TGIF Document TGIF - документ TGIF + Документ TGIF Dokument TGIF Dokument TGIF Dokument TGIF @@ -20438,7 +21064,7 @@ téama tema ערכת נושא - tema + Tema téma Thema tema @@ -20458,7 +21084,7 @@ tema Tema temă - тема + Тема Motív tema Temë @@ -20476,6 +21102,7 @@ ToutDoux document مستند ToutDoux + Documentu de ToutDoux ToutDoux sənədi Dakument ToutDoux Документ — ToutDoux @@ -20514,7 +21141,7 @@ documento ToutDoux Documento do ToutDoux Document ToutDoux - документ ToutDoux + Документ ToutDoux Dokument ToutDoux Dokument ToutDoux Dokument ToutDoux @@ -20566,7 +21193,7 @@ cópia de segurança Arquivo de backup fișier de backup - резервная копия + Резервная копия Záložný súbor varnostna kopija datoteke File backup @@ -20586,6 +21213,7 @@ Troff document مستند Troff + Documentu de Troff Troff sənədi Dakument Troff Документ — Troff @@ -20624,7 +21252,7 @@ documento Troff Documento Troff Document Troff - документ Troff + Документ Troff Dokument troff Dokument Troff Dokument Troff @@ -20657,7 +21285,9 @@ Έγγραφο βοήθειας manpage Manpage manual document documento de manual de Manpage + Manpage eskuliburu dokumentua document manuel Manpage + cáipéis lámhleabhair Man מסמך תיעוד man Manpage dokument priručnika Manpage kézikönyv-dokumentum @@ -20670,7 +21300,7 @@ Dokument podręcznika stron pomocy documento de ajuda Manpage Documento Manpage - документ справочной системы Manpage + Документ справочной системы Manpage Dokument manuálu Manpage документ упутства странице упутства Manpage-manualdokument @@ -20704,7 +21334,7 @@ leathanach lámhleabhair (comhbhrúite) páxina de manual (comprimida) דף עזר (מכווץ) - stranica priručnika (komprimirana) + Stranica priručnika (sažeta) kézikönyvoldal (tömörített) Pagina de manual (comprimite) halaman manual (terkompresi) @@ -20723,7 +21353,7 @@ página de manual (comprimida) Página de manual (compactada) pagină de manual (comprimată) - страница руководства (сжатая) + Страница руководства (сжатая) Manuálová stránka (komprimovaná) stran priročnika (stisnjena) Faqe manuali (e kompresuar) @@ -20732,7 +21362,7 @@ kılavuz dosyası (sıkıştırılmış) сторінка посібника (стиснена) trang hướng dẫn (đã nén) - 手册页 (压缩) + 手册页(压缩) 手冊頁面 (壓縮版) @@ -20755,7 +21385,7 @@ cartlann Tar (comhbhrúite le LZO) arquivo Tar (comprimido con LZO) ארכיון Tar (מכווץ ע״י LZO) - Tar arhiva (komprimirana LZO-om) + Tar arhiva (LZO sažeta) Tar archívum (LZO-val tömörítve) Archivo Tar (comprimite con LZO) Arsip Tar (terkompresi LZO) @@ -20773,7 +21403,7 @@ arquivo Tar (compressão LZO) Pacote Tar (compactado com LZO) Arhivă Tar (comprimată LZO) - архив TAR (сжатый LZO) + Архив TAR (сжатый lzo) Archív tar (komprimovaný pomocou LZO) Datoteka arhiva Tar (stisnjen z LZO) Arkiv tar (i kompresuar me LZO) @@ -20782,7 +21412,7 @@ Tar arşivi (LZO ile sıkıştırılmış) архів tar (стиснений LZO) Kho nén tar (đã nén LZO) - Tar 归档文件(LZO 压缩) + Tar 归档文件(LZO 压缩) Tar 封存檔 (LZO 格式壓縮) @@ -20824,7 +21454,7 @@ arquivo XZ Pacote XZ Arhivă XZ - архив XZ + Архив XZ Archív XZ Datoteka arhiva XZ ИксЗ архива @@ -20857,7 +21487,7 @@ cartlann Tar (comhbhrúite le XZ) arquivo Tar (comprimido con XZ) ארכיון Tar (מכווץ ע״י XZ) - Tar arhiva (komprimirana XZ-om) + Tar arhiva ( XZ sažeta) Tar archívum (XZ-vel tömörítve) Archivo Tar (comprimite con XZ) Arsip Tar (terkompresi XZ) @@ -20873,14 +21503,14 @@ arquivo Tar (compressão XZ) Pacote Tar (compactado com XZ) Arhivă Tar (comprimată XZ) - архив TAR (сжатый XZ) + Архив TAR (сжатый xz) Archív tar (komprimovaný pomocou XZ) Datoteka arhiva Tar (stisnjen z XZ) Тар архива (запакована ИксЗ-ом) Tar-arkiv (XZ-komprimerat) Tar arşivi (XZ ile sıkıştırılmış) архів tar (стиснений XZ) - Tar 归档文件(XZ 压缩) + Tar 归档文件(XZ 压缩) Tar 封存檔 (XZ 格式壓縮) @@ -20889,6 +21519,7 @@ PDF document (XZ-compressed) + Documentu PDF (comprimíu en XZ) Документ — PDF, компресиран с XZ document PDF (amb compressió XZ) dokument PDF (komprimovaný pomocí XZ) @@ -20900,9 +21531,10 @@ PDF dokumentua (XZ-rekin konprimitua) PDF-asiakirja (XZ-pakattu) document PDF (compressé XZ) + cáipéis PDF (comhbhrúite le XZ) documento PDF (comprimido en XZ) מסמך PDF (מכווץ ע״י XZ) - PDF dokument (komprimiran XZ-om) + PDF dokument ( XZ sažet) PDF dokumentum (XZ-vel tömörített) Documento PDF (comprimite con XZ) Dokumen PDF (terkompresi XZ) @@ -20917,14 +21549,14 @@ Dokument PDF (kompresja XZ) documento PDF (compressão XZ) Documento PDF (compactado com XZ) - документ PDF (сжатый XZ) + Документ PDF (сжатый xz) Dokument PDF (komprimovaný pomocou XZ) Dokument PDF (XZ-stisnjen) ПДФ документ (запакован ИксЗ-ом) PDF-dokument (XZ-komprimerat) PDF belgesi (XZ ile sıkıştırılmış) документ PDF (стиснений xz) - PDF 文档(XZ) + PDF 文档(XZ) PDF 文件 (XZ 格式壓縮) @@ -20968,7 +21600,7 @@ arquivo Ustar Pacote Ustar Arhivă Ustar - архив Ustar + Архив Ustar Archív ustar Datoteka arhiva Ustar Arkiv Ustar @@ -21004,7 +21636,7 @@ cód foinseach WAIS código fonte WAIS קוד מקור של WAIS - WAIS izvorni kod + WAIS izvorni kôd WAIS-forráskód Codice-fonte WAIS Kode program WAIS @@ -21023,7 +21655,7 @@ código origem WAIS Código-fonte WAIS Cod sursă WAIS - исходный код WAIS + Исходный код WAIS Zdrojový kód WAIS Datoteka izvorne kode WAIS Kod burues WAIS @@ -21077,7 +21709,7 @@ imagem do WordPerfect/Drawperfect Imagem do WordPerfect/Drawperfect Imagine WordPerfect/Drawperfect - изображение WordPerfect/Drawperfect + Изображение WordPerfect/Drawperfect Obrázok WordPerfect/Drawperfect Slikovna datoteka Drawperfect Figurë WordPerfect/Drawperfect @@ -21091,6 +21723,54 @@ + + Bandai WonderSwan ROM + ROM de Bandai WonderSwan + ROM pro Bandai WonderSwan + Bandai WonderSwan ROM + Bandai WonderSwan ROM + ROM de Bandai WonderSwan + Bandai WonderSwan ROM + Bandai WonderSwan ROM + ROM Bandai WonderSwan + ROM Bandai WonderSwan + Bandai WonderSwan ROM + 반다이 원더스완 롬 + Plik ROM konsoli Bandai WonderSwan + ROM de WonderSwan da Bandai + Bandai WonderSwan ROM + ROM pre Bandai WonderSwan + Bandai WonderSwan-rom + ROM Bandai WonderSwan + 万代 WonderSwan ROM + Bandai WonderSwan ROM + + + + + Bandai WonderSwan Color ROM + ROM de Bandai WonderSwan Color + ROM pro Bandai WonderSwan Color + Bandai WonderSwan Color ROM + Bandai WonderSwan Color ROM + ROM de Bandai WonderSwan Color + Bandai WonderSwan Color ROM + Bandai WonderSwan Color ROM + ROM Bandai WonderSwan Color + ROM Bandai WonderSwan Color + Bandai WonderSwan Color ROM + 반다이 원더스완 컬러 롬 + Plik ROM konsoli Bandai WonderSwan Color + ROM de WonderSwan Color da Bandai + Bandai WonderSwan Color ROM + ROM pre Bandai WonderSwan Color + Bandai WonderSwan Color-rom + ROM Bandai WonderSwan Color + 万代 WonderSwan Color ROM + Bandai WonderSwan Color ROM + + + DER/PEM/Netscape-encoded X.509 certificate شهادة DER/PEM/Netscape-encoded X.509 @@ -21111,7 +21791,7 @@ teastas X.509 ionchódaithe le DER/PEM/Netscape certificado X.509 codificado con DER/PEM/Netscape אישור מסוג X.509 של DER/PEM/Netscape-encoded - DER/PEM/Netscape-kodiran X.509 certifikat + DER/PEM/Netscape-kodiran X.509 vjerodajnica DER/PEM/Netscape formátumú X.509-tanúsítvány Certificato X.509 codificate in DER/PEM/Netscape Sertifikat DER/PEM/Netscape-tersandi X.509 @@ -21131,7 +21811,7 @@ certificado X.509 codificado com DER/PEM/Netscape Certificado X.509 codificado com DER/PEM/Netscape Certificat DER/PEM/Netscape-codat X.509 - сертификат X.509 (DER/PEM/Netscape-закодированный) + Сертификат X.509 (DER/PEM/Netscape-закодированный) Certifikát X.509 kódovaný ako DER/PEM/Netscape Datoteka potrdila DER/PEM/Netscape X.509 Çertifikatë DER/PEM/Netscape-encoded X.509 @@ -21151,6 +21831,7 @@ empty document مستند فارغ + documentu baleru pusty dakument Празен документ document buit @@ -21168,7 +21849,7 @@ cáipéis fholamh documeto baleiro מסמך ריק - prazan dokument + Prazan dokument üres dokumentum Documento vacue dokumen kosong @@ -21187,7 +21868,7 @@ documento vazio Documento vazio document gol - пустой документ + Пустой документ Prázdny dokument prazen dokument Dokument bosh @@ -21239,7 +21920,7 @@ arquivo Zoo Pacote Zoo Arhivă Zoo - архив ZOO + Архив ZOO Archív zoo Datoteka arhiva ZOO Arkiv zoo @@ -21295,7 +21976,7 @@ página XHTML Página XHTML Pagină XHTML - страница XHTML + Страница XHTML Stránka XHTML Datoteka spletne strani XHTML Faqe XHTML @@ -21360,7 +22041,7 @@ arquivo Zip Pacote Zip Arhivă zip - архив ZIP + Архив ZIP Archív ZIP Datoteka arhiva ZIP Arkiv zip @@ -21391,6 +22072,7 @@ WIM disko irudia WIM-levytiedosto image disque WIM + íomhá diosca WIM דמות דיסק WIM WIM slika diska WIM lemezkép @@ -21403,13 +22085,13 @@ Obraz dysku WIM imagem de disco WIM Imagem de disco WIM - образ диска WIM + Образ диска WIM Obraz disku WIM слика диска ВИМ-а WIM-diskavbild WIM disk kalıbı образ диска WIM - WIM 磁盘镜像 + WIM 磁盘映像 WIM 磁碟映像檔 WIM Windows Imaging Format @@ -21441,7 +22123,7 @@ fuaim Dolby Digital son Dolby Digital שמע Dolby Digital - Dolby Digital audio + Dolby Digital zvučni zapis Dolby Digital hang Audio Dolby Digital Audio Dolby Digital @@ -21461,7 +22143,7 @@ áudio Dolby Digital Áudio Dolby Digital Audio Dolby Digital - аудио Dolby Digital + Аудио Dolby Digital Zvuk Dolby Digital Zvočna datoteka Dolby Digital Audio Dolby Digital @@ -21489,6 +22171,7 @@ DTS audioa DTS-ääni audio DTS + fuaim DTS Son DTS שמע DTS DTS zvučni zapis @@ -21501,10 +22184,10 @@ DTS 오디오 DTS audio àudio DTS - Dźwięk DTS + Plik dźwiękowy DTS aúdio DTS Áudio DTS - аудио DTS + Аудио DTS Zvuk DTS Zvok DTS ДТС звук @@ -21534,6 +22217,7 @@ DTSHD audioa DTS-HD-ääni audio DTSHD + fuaim DTSHD Son DTSHD שמע DTSHD DTSHD zvučni zapis @@ -21546,10 +22230,10 @@ DTSHD 오디오 DTSHD audio àudio DTSHD - Dźwięk DTSHD + Plik dźwiękowy DTSHD áudio DTSHD Áudio DTSHD - аудио DTSHD + Аудио DTSHD Zvuk DTSHD Zvok DTSHD ДТСХД звук @@ -21585,7 +22269,7 @@ fuaim AMR son AMR שמע AMR - AMR audio + AMR zvučni zapis AMR hang Audio AMR Audio AMR @@ -21604,7 +22288,7 @@ áudio AMR Áudio AMR Audio AMR - аудио AMR + Аудио AMR Zvuk AMR Zvočna datoteka AMR Audio AMR @@ -21644,7 +22328,7 @@ fuaim AMR-WB son AMR-WB שמע AMR-WN - AMR-WB audio + AMR-WB zvučni zapis AMR-WB hang Audio AMR-WB Audio AMR-WB @@ -21663,7 +22347,7 @@ áudio AMR-WB Áudio AMR-WB Audio AMR-WB - аудио AMR-WB + Аудио AMR-WB Zvuk AMR-WB Zvočna datoteka AMR-WB Audio AMR-WB @@ -21724,7 +22408,7 @@ áudio ULAW (Sun) Áudio ULAW (Sun) Fișier audio ULAW (Sun) - аудио ULAW (Sun) + Аудио ULAW (Sun) Zvuk ULAW (Sun) Zvočna datoteka ULAW (Sun) Audio ULAW (Sun) @@ -21761,7 +22445,7 @@ fuaim Commodore 64 son de Commodore 64 שמע של Commodore 64 - Commodore 64 audio + Commodore 64 zvučni zapis Commodore 64 hang Audio Commodore 64 Audio Commodore 64 @@ -21781,7 +22465,7 @@ áudio Commodore 64 Áudio Commodore 64 Audio Commodore 64 - аудио Commodore 64 + Аудио Commodore 64 Zvuk Commodore 64 Zvočna datoteka Commodore 64 Audio Commodore 64 @@ -21839,7 +22523,7 @@ áudio PCM Áudio PCM Audio PCM - аудио PCM + Аудио PCM Zvuk PCM Zvočna datoteka PCM Audio PCM @@ -21888,7 +22572,7 @@ fuaim AIFC son AIFC שמע AIFC - AIFC audio + AIFC zvučni zapis AIFC hang Audio AIFC Audio AIFC @@ -21908,7 +22592,7 @@ áudio AIFC Áudio AIFC Fișier audio AIFC - аудио AIFC + Аудио AIFC Zvuk AIFC Zvočna datoteka AIFC Audio AIFC @@ -21951,7 +22635,7 @@ fuaim AIFF/Amiga/Mac son AIFF/Amiga/Mac שמע AIFF/Amiga/Mac - AIFF/Amiga/Mac audio + AIFF/Amiga/Mac zvučni zapis AIFF/Amiga/Mac hang Audio AIFF/Amiga/Mac Audio AIFF/Amiga/Mac @@ -21971,7 +22655,7 @@ áudio AIFF/Amiga/Mac Áudio AIFF/Amiga/Mac Audio AIFF/Amiga/Mac - аудио AIFF/Amiga/Mac + Аудио AIFF/Amiga/Mac Zvuk AIFF/Amiga/Mac Zvočna datoteka AIFF/Amiga/Mac Audio AIFF/Amiga/Mac @@ -22029,7 +22713,7 @@ áudio Monkey Áudio Monkey's Audio Monkey's - аудио Monkey's + Аудио Monkey's Zvuk Monkey's Zvočna datoteka Monkey Audio Monkey's @@ -22038,13 +22722,44 @@ Monkey's sesi звук Monkey's Âm thanh cua Monkey - Monkey's audio 音频 + Monkey's Audio 音频 Monkey's 音訊 + + Audible.Com audio + àudio Audible.Com + zvuk Audible.Com + Audible.Com-Audio + Audible.Com audio + sonido de Audible.com + Audible.Com zvučni zapis + Audible.Com hang + Audio Audible.Com + Audio Audible.Com + Audible.Com аудиосы + Audible.Com 오디오 + Plik dźwiękowy Audible.com + Áudio de audible.com + Аудио Audible.Com + Audio Audible.Com + Audible.Com-ljud + звук Audible.Com + Audible.Com 音频 + Audible.Com 音訊 + + + + + + + + + + Impulse Tracker audio Impulse Tracker سمعي @@ -22067,7 +22782,7 @@ fuaim Impulse Tracker son de Impulse Tracker שמע של Impulse Tracker - Impulse Tracker audio + Impulse Tracker zvučni zapis Impulse Tracker hang Audio Impulse Tracker Audio Impulse Tracker @@ -22086,7 +22801,7 @@ áudio Impulse Tracker Áudio Impulse Tracker Audio Impulse Tracker - аудио Impulse Tracker + Аудио Impulse Tracker Zvuk Impulse Tracker Zvočna datoteka Impulse Tracker Audio Impulse Tracker @@ -22122,7 +22837,7 @@ fuaim FLAC son FLAC קובץ שמע מסוג FLAC - FLAC audio + FLAC zvučni zapis FLAC hang Audio FLAC Audio FLAC @@ -22142,7 +22857,7 @@ áudio FLAC Áudio FLAC Audio FLAC - аудио FLAC + Аудио FLAC Zvuk FLAC Zvočna datoteka Flac Audio FLAC @@ -22179,7 +22894,7 @@ fuaim WavPack son WavPack שמע WavPack - WavPack audio + WavPack zvučni zapis WavPack hang Audio WavPack Audio WavPack @@ -22197,7 +22912,7 @@ áudio WavPack Áudio WavPack Audio WavPack - аудио WavPack + Аудио WavPack Zvuk WavPack Zvočna datoteka WavPack Audio WavPack @@ -22230,7 +22945,7 @@ WavPack-äänikorjaustiedosto WavPack ljóðrættingarfíla fichier de correction audio WavPack - comhad cheartú fhuaim WavPack + comhad ceartúchán fuaime WavPack ficheiro de corrección de son WavPack קובץ תיקון שמע של WavPack WavPack datoteka ispravke zvuka @@ -22251,7 +22966,7 @@ ficheiro de correção áudio WavPack Arquivo de correção de áudio WavPack Fișier audio de corecție WavPack - файл коррекции аудио WavPack + Файл коррекции аудио WavPack Opravný zvukový súbor WavPack popravljalna zvočna datoteka WavPack File korrigjgimi audio WavPack @@ -22260,7 +22975,7 @@ WavPack ses düzeltme dosyası файл корекції звуку WavPack Tập tin sửa chữa âm thanh WavPack - WavPack 音频校正文档 + WavPack 音频校正文件 WavPack 音訊校正檔 @@ -22289,7 +23004,7 @@ fuaim MIDI son MIDI שמע MIDI - MIDI audio + MIDI zvučni zapis MIDI hang Audio MIDI Audio MIDI @@ -22308,7 +23023,7 @@ áudio MIDI Áudio MIDI Audio MIDI - аудио MIDI + Аудио MIDI Zvuk MIDI Zvočna datoteka MIDI Audio MIDI @@ -22346,7 +23061,7 @@ fuaim chomhbhrúite Tracker son comprimido de Tracker שמע גשש מכווץ - komprimirani Tracker audio + Sažeti Tracker zvučni zapis tömörített Tracker hang Audio Tracker comprimite audio Tracker terkompresi @@ -22363,7 +23078,7 @@ áudio comprimido Tracker Áudio Tracker compactado Tracker audio comprimat - аудио Tracker (сжатое) + Сжатое аудио Tracker Komprimovaný zvuk Tracker Skrčena zvočna datoteka Tracker Audio Tracker e kompresuar @@ -22391,6 +23106,7 @@ AAC audioa AAC-ääni audio AAC + fuaim AAC Son AAC שמע AAC AAC zvučni zapis @@ -22403,10 +23119,10 @@ AAC 오디오 AAC audio àudio AAC - Dźwięk AAC + Plik dźwiękowy AAC áudio AAC Áudio AAC - аудио AAC + Аудио AAC Zvuk AAC Zvok AAC ААЦ звук @@ -22422,8 +23138,17 @@ + + + + USAC audio + USAC + Unified Speech and Audio Coding + + + MPEG-4 audio MPEG-4 سمعي @@ -22444,7 +23169,7 @@ fuaim MPEG-4 son MPEG-4 שמע MPEG-4 - MPEG-4 audio + MPEG-4 zvučni zapis MPEG-4 hang Audio MPEG-4 Audio MPEG-4 @@ -22463,7 +23188,7 @@ áudio MPEG-4 Áudio MPEG-4 Audio MPEG-4 - аудио MPEG-4 + Аудио MPEG-4 Zvuk MPEG-4 Zvočna datoteka MPEG-4 Audio MPEG-4 @@ -22482,9 +23207,15 @@ + + MPEG-4 Ringtone + + + MPEG-4 video MPEG-4 مرئي + Videu en MPEG-4 Videa MPEG-4 Видео — MPEG-4 vídeo MPEG-4 @@ -22502,7 +23233,7 @@ físeán MPEG-4 vídeo MPEG-4 וידאו MPEG-4 - MPEG-4 video + MPEG-4 video snimka MPEG-4 videó Video MPEG-4 Video MPEG-4 @@ -22521,7 +23252,7 @@ vídeo MPEG-4 Vídeo MPEG-4 Video MPEG-4 - видео MPEG-4 + Видео MPEG-4 Video MPEG-4 Video datoteka MPEG-4 Video MPEG-4 @@ -22563,10 +23294,10 @@ MPEG-4-äänikirja MPEG-4 ljóðbók livre audio MPEG-4 - leabhar fhuaim MPEG-4 + closleabhar MPEG-4 sonlibro de MPEG-4 ספר דיגיטלי MPEG-4 - MPEG-4 audio knjiga + MPEG-4 zvučna knjiga MPEG-4 hangoskönyv Libro audio MPEG-4 Buku audio MPEG-4 @@ -22585,7 +23316,7 @@ livro áudio MPEG-4 Áudio livro MPEG-4 Carte audio MPEG-4 - аудиокнига MPEG-4 + Аудиокнига MPEG-4 Zvuková kniha MPEG-4 Zvočna knjiga MPEG-4 Audiolibër MPEG-4 @@ -22641,7 +23372,7 @@ ficheiro multimédia 3GPP Arquivo multimídia 3GPP Fișier multimedia 3GPP - мультимедийный файл 3GPP + Мультимедийный файл 3GPP Súbor multimédií 3GPP Večpredstavnostna datoteka 3GPP File multimedial 3GPP @@ -22707,7 +23438,7 @@ ficheiro multimédia 3GPP2 Arquivo multimídia 3GPP2 Fișier multimedia 3GPP2 - мультимедийный файл 3GPP2 + Мультимедийный файл 3GPP2 Súbor multimédií 3GPP2 Večpredstavnostna datoteka 3GPP2 3ГПП2 мултимедијална датотека @@ -22747,7 +23478,7 @@ fuaim Amiga SoundTracker son de Amiga SoundTracker קובץ שמע של Amiga SoundTracker - Amiga SoundTracker audio + Amiga SoundTracker zvučni zapis Amiga SoundTracker hang Audio Amiga SoundTracker Audio Amida SoundTracker @@ -22767,7 +23498,7 @@ áudio SoundTracker do Amiga Áudio Amiga SoundTracker Audio Amiga SoundTracker - аудио Amiga SoundTracker + Аудио Amiga SoundTracker Zvuk Amiga SoundTracker Zvočna datoteka Amiga SoundTracker Audio Amiga SoundTracker @@ -22840,7 +23571,7 @@ fuaim MP2 son MP2 שמע MP2 - MP2 audio + MP2 zvučni zapis MP2 hang Audio MP2 Audio MP2 @@ -22858,7 +23589,7 @@ áudio MP2 Áudio MP2 Audio MP2 - аудио MP2 + Аудио MP2 Zvuk MP2 Zvočna datoteka MP2 Audio MP2 @@ -22894,7 +23625,7 @@ fuaim MP3 son MP3 שמע MP3 - MP3 audio + MP3 zvučni zapis MP3 hang Audio MP3 Audio MP3 @@ -22914,7 +23645,7 @@ áudio MP3 Áudio MP3 Audio MP3 - аудио MP3 + Аудио MP3 Zvuk MP3 Zvočna datoteka MP3 Audio MP3 @@ -22972,11 +23703,11 @@ MP3-audio (gestreamd) Strauma MP3-lyd àudio MP3 (flux) - Dźwięk MP3 (strumień) + Plik dźwiękowy MP3 (strumień) áudio MP3 (em fluxo) Áudio MP3 (em fluxo) Audio MP3 (flux) - аудио MP3 (потоковое) + Аудио MP3 (потоковое) Zvuk MP3 (streamovaný) Zvočna datoteka MP3 (pretočna) Audio MP3 (streamed) @@ -22985,7 +23716,7 @@ MP3 sesi (akış) звук MP3 (потоковий) Âm thanh MP3 (chạy luồng) - MP3 流音频 + MP3 音频流媒体 MP3 音訊 (串流) @@ -23033,14 +23764,14 @@ lista de reprodução HTTP Live Streaming Lista de Reprodução Streaming ao Vivo de HTTP Listă de redare difuzată ca flux HTTP - список воспроизведения HTTP-потока + Список воспроизведения HTTP-потока Zoznam stôp HTTP Live Streaming Seznam predvajanja živega pretoka HTTP ХТТП списак нумера Живог Протока HTTP Live Streaming-spellista HTTP Canlı Akış çalma listesi список відтворення HTTP Live Streaming - HTTP 直播流播放列表 + HTTP 实时流播放列表 HTTP 即時串流播放清單 @@ -23071,7 +23802,7 @@ seinmliosta Microsoft ASX lista de reprodución Microsoft ASX רשימת השמעה ASX (מיקרוסופט) - Microsoft ASX popis za reprodukciju + Microsoft ASX popis izvođenja Microsoft ASX lejátszólista Lista de selection Microsoft ASX Senarai putar Microsoft ASX @@ -23090,7 +23821,7 @@ lista de reprodução Microsoft ASX Lista de reprodução do Microsoft ASX Listă redare Microsoft ASX - список воспроизведения Microsoft ASX + Список воспроизведения Microsoft ASX Zoznam skladieb Microsoft ASX Seznam predvajanja Microsoft ASX Listë titujsh Microsoft ASF @@ -23154,7 +23885,7 @@ áudio PSF Áudio PSF Audio PSF - аудио PSF + Аудио PSF Zvuk PSF Zvočna datoteka PSF Audio PSF @@ -23192,7 +23923,7 @@ fuaim MiniPSF son MiniPSF שמע של MiniPSP - MiniPSF audio + MiniPSF zvučni zapis MiniPSF hang Audio MiniPSF Audio MiniPSF @@ -23211,7 +23942,7 @@ áudio MiniPSF Áudio MiniPSF Audio MiniPSF - аудио MiniPSF + Аудио MiniPSF Zvuk MiniPSF Zvočna datoteka MiniPSF Audio MiniPSF @@ -23243,7 +23974,7 @@ PSFlib-äänikirjasto PSFlib ljóðsavn bibliothèque audio PSFlib - leabharlann fhuaim PSFlib + leabharlann fhuaime PSFlib Biblioteca de son PSFlib ספריית שמע PSFlib PSFlib zvučna biblioteka @@ -23264,7 +23995,7 @@ biblioteca áudio PSFlib Biblioteca de áudio PSFlib Bibliotecă audio PSFlib - фонотека PSFlib + Фонотека PSFlib Zvuková knižnica PSFlib Zvočna knjižnica PSFlib Librari audio PSFlib @@ -23273,7 +24004,7 @@ PSFlib ses kitaplığı аудіобібліотека PSFlib Thư viện âm thanh PSFlib - PSFlib 音频库文件 + PSFlib 音频库 PSFlib 音訊庫 PSFlib Portable Sound Format Library @@ -23299,7 +24030,7 @@ fuaim Windows Media son de Windows Media שמע של Windows Media - Windows Media audio + Windows Media zvučni zapis Windows Media hang Audio Windows Media Audio Windows Media @@ -23317,7 +24048,7 @@ áudio Windows Media Áudio do Windows Media Audio Windows Media - аудио Windows Media + Аудио Windows Media Zvuk Windows Media Zvočna datoteka Windows Media Audio Windows Media @@ -23351,7 +24082,7 @@ fuaim Musepack son de Musepack שמע של Musepack - Musepack audio + Musepack zvučni zapis Musepack hang Audio Musepack Audio Musepack @@ -23369,7 +24100,7 @@ áudio Musepack Áudio Musepack Audio Musepack - аудио Musepack + Аудио Musepack Zvuk Musepack Zvočna datoteka Musepack Audio Musepack @@ -23390,6 +24121,7 @@ RealAudio document مستند RealAudio + Documentu RealAudio Dakument RealAudio Документ — RealAudio document RealAudio @@ -23425,7 +24157,7 @@ documento RealAudio Documento RealAudio Document RealAudio - документ RealAudio + Документ RealAudio Dokument RealAudio Dokument RealAudio Dokument RealAudio @@ -23457,7 +24189,7 @@ RealMedia-metatiedosto RealMedia metafíla métafichier RealMedia - meiteachomhad RealMedia + Meiteachomhad RealMedia Metaficheiro RealMedia קובץ מטא של RealMedia RealMedia meta datoteka @@ -23478,7 +24210,7 @@ metaficheiro RealMedia Meta arquivo do RealMedia Metafișier RealMedia - мета-файл RealMedia + Мета-файл RealMedia RealMedia Metafile Metadatoteka RealMedia Metafile RealMedia @@ -23494,6 +24226,7 @@ RealVideo document مستند RealVideo + Documentu RealVideo Dakument RealVideo Документ — RealVideo document RealVideo @@ -23529,7 +24262,7 @@ documento RealVideo Documento RealVideo Document RealVideo - документ RealVideo + Документ RealVideo Dokument RealVideo Video datoteka RealVideo Dokument RealVideo @@ -23547,6 +24280,7 @@ RealMedia document مستند RealMedia + Documentu RealMedia Dakument RealMedia Документ — RealMedia document RealMedia @@ -23582,7 +24316,7 @@ documento RealMedia Documento RealMedia Document RealMedia - документ RealMedia + Документ RealMedia Dokument RealMedia Dokument RealMedia Dokument RealMedia @@ -23608,6 +24342,7 @@ RealPix document مستند RealPix + Documentu RealPix Dakument RealPix Документ — RealPix document RealPix @@ -23643,7 +24378,7 @@ documento RealPix Documento RealPix Document RealPix - документ RealPix + Документ RealPix Dokument RealPix Dokument RealPix Dokument RealPix @@ -23659,6 +24394,7 @@ RealText document مستند RealText + Documentu RealText Dakument RealText Документ — RealText document RealText @@ -23694,7 +24430,7 @@ documento RealText Documento RealText Document RealText - документ RealText + Документ RealText Dokument RealText Dokument RealText Dokument RealText @@ -23729,7 +24465,7 @@ fuaim RIFF son RIFF שמע RIFF - RIFF audio + RIFF zvučni zapis RIFF-kép Audio RIFF Audio RIFF @@ -23748,7 +24484,7 @@ áudio RIFF Áudio RIFF Audio RIFF - аудио RIFF + Аудио RIFF Zvuk RIFF Zvočna datoteka RIFF Audio RIFF @@ -23771,6 +24507,7 @@ contenedor RIFF RIFF edukitzailea conteneur RIFF + coimeádán RIFF Contenedor RIFF מכולת RIFF RIFF spremnik @@ -23820,7 +24557,7 @@ fuaim Scream Tracker 3 son Scream Tracker 3 שמע של Scream Tracker 3 - Scream Tracker 3 audio + Scream Tracker 3 zvučni zapis Scream Tracker 3 hang Audio Scream Tracker 3 Audio Scream Tracker 3 @@ -23839,7 +24576,7 @@ áudio Scream Tracker 3 Áudio Scream Tracker 3 Audio Scream Tracker 3 - аудио Scream Tracker 3 + Аудио Scream Tracker 3 Skladba Scream Tracker 3 Zvočna datoteka Scream Tracker 3 Audio Scream Tracker 3 @@ -23875,7 +24612,7 @@ seinmliosta MP3 ShoutCast lista de reprodución MP3 de ShoutCast רשימת השמעה MP3 של ShoutCast - MP3 ShoutCast popis za reprodukciju + MP3 ShoutCast popis izvođenja MP3 ShoutCast-lejátszólista Lista de selection MP3 ShoutCast Senarai putar MP3 ShoutCast @@ -23894,7 +24631,7 @@ lista de reprodução MP3 ShoutCast Lista de reprodução MP3 ShoutCast Listă MP3 ShoutCast - список воспроизведения MP3 ShoutCast + Список воспроизведения MP3 ShoutCast Zoznam skladieb MP3 ShoutCast Seznam predvajanja MP3 ShoutCast Listë titujsh MP3 ShoutCast @@ -23936,7 +24673,7 @@ fuaim Scream Tracker son Scream Tracker שמע של Scream Tracker - Scream Tracker audio + Scream Tracker zvučni zapis Scream Tracker hang Audio Scream Tracker Audio Scream Tracker @@ -23955,7 +24692,7 @@ áudio Scream Tracker Áudio Scream Tracker Audio Scream Tracker - аудио Scream Tracker + Аудио Scream Tracker Skladba Scream Tracker Zvočna datoteka Scream Tracker Audio Scream Tracker @@ -23995,7 +24732,7 @@ fuaim VOC son VOC שמע VOC - VOC audio + VOC zvučni zapis VOC hang Audio VOC Audio VOC @@ -24014,7 +24751,7 @@ áudio VOC Áudio VOC Audio VOC - аудио VOC + Аудио VOC Zvuk VOC Zvočna datoteka VOC Audio VOC @@ -24049,7 +24786,7 @@ fuaim WAV son WAV שמע WAV - WAV audio + WAV zvučni zapis WAV hang Audio WAV Audio WAV @@ -24068,7 +24805,7 @@ áudio WAV Áudio WAV Audio WAV - аудио WAV + Аудио WAV Zvuk WAV Zvočna datoteka WAV Audio WAV @@ -24128,7 +24865,7 @@ instrumento Scream Tracker Instrumento Scream Tracker Instrument Scream Tracker - инструмент Scream Tracker + Инструмент Scream Tracker Nástroj pre Scream Tracker Datoteka zvoka glasbila Scream Tracker Instrument Scream Tracker @@ -24166,7 +24903,7 @@ fuaim FastTracker II son de FastTracker II שמע FastTracker II - FastTracker II audio + FastTracker II zvučni zapis FastTracker II hang Audio FastTracker II Audio FastTracker II @@ -24186,7 +24923,7 @@ áudio FastTracker II Áudio FastTracker II Audio FastTracker II - аудио FastTracker II + Аудио FastTracker II Zvuk FastTracker II Zvočna datoteka FastTracker II Audio FastTracker II @@ -24222,7 +24959,7 @@ fuaim TrueAudio son Trueson שמע TrueAudio - TrueAudio audio + TrueAudio zvučni zapis TrueAudio hang Audio TrueAudio Audio TrueAudio @@ -24240,7 +24977,7 @@ áudio TrueAudio Áudio TrueAudio Audio TrueAudio - аудио TrueAudio + Аудио TrueAudio Zvuk TrueAudio Zvočna datoteka TrueAudio Audio TrueAudio @@ -24298,7 +25035,7 @@ imagem BMP Windows Imagem BMP do Windows Imagine Windows BMP - изображение Windows BMP + Изображение Windows BMP Obrázok Windows BMP Slikovna datoteka Windows BMP Figurë Windows BMP @@ -24360,7 +25097,7 @@ imagem WBMP Imagem WBMP Imagine WBMP - изображение WBMP + Изображение WBMP Obrázok WBMP Slikovna datoteka WBMP Figurë WBMP @@ -24393,7 +25130,7 @@ Computer Graphics -metatiedosto Teldugrafikk metafíla métafichier Computer Graphics - meiteachomhad Grafaicí Ríomhaire + Meiteachomhad Grafaicí Ríomhaire metaficheiro de Computer Graphics קובץ-מטה מסוג Computer Graphics Computer Graphics meta datoteka @@ -24415,7 +25152,7 @@ metaficheiro Computer Graphics Meta-arquivo do Computer Graphics Metafișier Computer Graphics - метафайл компьютерной графики + Метафайл компьютерной графики Computer Graphics Metafile Metadatoteka računalniške grafike (CGM) Metafile Computer Graphics @@ -24424,7 +25161,7 @@ Computer Graphics Meta dosyası метафайл комп'ютерної графіки Siêu tập tin đồ họa máy tính (CMF) - CGM 计算机图像元文件 + 计算机图形图元文件 (CGM) CGM 影像 @@ -24468,7 +25205,7 @@ fax CCITT G3 Fax do CCITT G3 Fax CCITT G3 - факс CCITT G3 + Факс CCITT G3 Fax CCITT G3 Datoteka faksimila CCITT G3 Fax CCITT G3 @@ -24523,7 +25260,7 @@ imagem de fax G3 Imagem de fax G3 Imagine fax G3 - факсовое изображение G3 + Факсовое изображение G3 Obrázok fax G3 Slikovna datoteka G3 fax Figurë Fax G3 @@ -24532,7 +25269,7 @@ G3 fax görüntüsü факс G3 Ảnh điện thư G3 - G3 传真文档 + G3 传真图像 G3 傳真圖 @@ -24577,7 +25314,7 @@ imagem GIF Imagem GIF Imagine GIF - изображение GIF + Изображение GIF Obrázok GIF Slikovna datoteka GIF Figurë GIF @@ -24593,6 +25330,16 @@ + + HEIF image + HEIF + High Efficiency Image File + + + + + + IEF image صورة IEF @@ -24634,7 +25381,7 @@ imagem IEF Imagem IEF Imagine IEF - изображение IEF + Изображение IEF Obrázok IEF Slikovna datoteka IEF Figurë IEF @@ -24688,7 +25435,7 @@ imagem JPEG Imagem JPEG Imagine JPEG - изображение JPEG + Изображение JPEG Obrázok JPEG Slikovna datoteka JPEG Figurë JPEG @@ -24708,69 +25455,164 @@ - - JPEG-2000 image - صورة JPEG-2000 - Vyjava JPEG-2000 - Изображение — JPEG-2000 - imatge JPEG-2000 - obrázek JPEG-2000 - JPEG2000-billede - JPEG-2000-Bild - Εικόνα JPEG-2000 - JPEG-2000 image - JPEG-2000-bildo - imagen JPEG-2000 - JPEG-2000 irudia - JPEG-2000-kuva - JPEG-2000 mynd - image JPEG-2000 - íomhá JPEG-2000 - imaxe JPEG-2000 - תמונת JPEG-2000 - JPEG-2000 slika - JPEG-2000 kép - Imagine JPEG-2000 - Citra JPEG-2000 - Immagine JPEG-2000 - JPEG-2000 画像 - JPEG-2000 суреті - JPEG-2000 그림 - JPEG-2000 paveikslėlis - JPEG-2000 attēls - Imej JPEG-2000 - JPEG-2000-bilde - JPEG-2000-afbeelding - JPEG-2000-bilete - imatge JPEG-2000 - Obraz JPEG-2000 - imagem JPEG-2000 + + MJPEG video stream + MJPEG + Motion JPEG + + + + + + JPEG-2000 codestream + flux de codis JPEG-2000 + datový tok JPEG-2000 + JPEG-2000 Codestream + JPEG-2000 codestream + secuencia de código JPEG-2000 + JPEG-2000 kôd strujanja + JPEG-2000 kódfolyam + codestream JPEG-2000 + Codestream JPEG-2000 + JPEG-2000 код ағыны + JPEG-2000 코드스트림 + Strumień kodu JPEG-2000 Imagem JPEG-2000 - Imagine JPEG-2000 - изображение JPEG-2000 - Obrázok JPEG-2000 - Slikovna datoteka JPEG-2000 - Figurë JPEG-2000 - ЈПЕГ-2000 слика - JPEG-2000-bild - JPEG-2000 görüntüsü - зображення JPEG-2000 - Ảnh JPEG-2000 - JPEG-2000 图像 - JPEG-2000 影像 + Кодовый поток JPEG-2000 + JPEG-2000 codestream + JPEG-2000-kodström + потік коду JPEG-2000 + JPEG-2000 码流 + JPEG-2000 代碼串流 + + + + + + + + + JPEG-2000 JP2 image + imatge JPEG-2000 JP2 + obrázek JPEG-2000 JP2 + JPEG-2000 JP2-Bild + JPEG-2000 JP2 image + imagen JPEG-2000 JP2 + JPEG-2000 JP2 -kuva + JPEG-2000 JP2 slika + JPEG-2000 JP2 kép + Citra JPEG-2000 JP2 + Immagine JPEG-2000 JP2 + JPEG-2000 JP2 суреті + JPEG-2000 JP2 그림 + Obraz JP2 JPEG-2000 + Imagem JP2 de JPEG-2000 + Изоражение JPEG-2000 JP2 + Obrázok JPEG-2000 JP2 + JPEG-2000 JP2-bild + зображення JP2 JPEG-2000 + JPEG-2000 JP2 图像 + JPEG-2000 JP2 影像 + JP2 + JPEG-2000 - - - - + - + + + + JPEG-2000 JPX image + imatge JPEG-2000 JPX + obrázek JPEG-2000 JPX + JPEG-2000 JPX-Bild + JPEG-2000 JPX image + imagen JPEG-2000 JPX + JPEG-2000 JPX -kuva + JPEG-2000 JPX slika + JPEG-2000 JPX kép + Citra JPEG-2000 JPX + Immagine JPEG-2000 JPX + JPEG-2000 JPX суреті + JPEG-2000 JPX 그림 + Obraz JPX JPEG-2000 + Imagem JPX de JPEG-2000 + Изображение JPEG-2000 JPX + Obrázok JPEG-2000 JPX + JPEG-2000 JPX-bild + зображення JPX JPEG-2000 + JPEG-2000 JPX 图像 + JPEG-2000 JPX 影像 + JPX + JPEG-2000 eXtended + + + - + + + + JPEG-2000 JPM image + imatge JPEG-2000 JPM + obrázek JPEG-2000 JPM + JPEG-2000 JPM-Bild + JPEG-2000 JPM image + imagen JPEG-2000 JPM + JPEG-2000 JPM -kuva + JPEG-2000 JPM slika + JPEG-2000 JPM kép + Citra JPEG-2000 JPM + Immagine JPEG-2000 JPM + JPEG-2000 JPM суреті + JPEG-2000 JPM 그림 + Obraz JPM JPEG-2000 + Imagem JPM de JPEG-2000 + Изображение JPEG-2000 JPM + Obrázok JPEG-2000 JPM + JPEG-2000 JPM-bild + зображення JPM JPEG-2000 + JPEG-2000 JPM 图像 + JPEG-2000 JPM 影像 + JPM + JPEG-2000 Mixed + + + + + + + + JPEG-2000 MJ2 video + vídeo JPEG-2000 MJ2 + video JPEG-2000 MJ2 + JPEG-2000 MJ2-Video + JPEG-2000 MJ2 video + vídeo JPEG-2000 MJ2 + JPEG-2000 MJ2 -video + JPEG-2000 MJ2 video snimka + JPEG-2000 MJ2 videó + Video JPEG-2000 MJ2 + Video JPEG-2000 MJ2 + JPEG-2000 MJ2 видеосы + JPEG-2000 MJ2 동영상 + Plik wideo MJ2 JPEG-2000 + Imagem MJ2 de JPEG-2000 + Видео JPEG-2000 MJ2 + Video JPEG-2000 MJ2 + JPEG-2000 MJ2-bild + зображення MJ2 JPEG-2000 + JPEG-2000 MJ2 视频 + JPEG-2000 MJ2 視訊 + MJ2 + Motion JPEG-2000 + + + + + OpenRaster archiving image @@ -24807,14 +25649,14 @@ imagem arquivo OpenRaster Imagem de arquivamento OpenRaster Arhivă imagine OpenRaster - архивное изображение OpenRaster + Архивное изображение OpenRaster Archivačný obrázok OpenRaster Odtis arhiva OpenRaster слика Опен Растер архивирања OpenRaster-arkivbild OpenRaster arşivleme görüntüsü архівоване зображення OpenRaster - OpenRaster 归档映像 + OpenRaster 归档图像 OpenRaster 封存影像 @@ -24864,7 +25706,7 @@ superfície DirectDraw Superfície do DirectDraw Suprafață DirectDraw - плоскость DirectDraw + Плоскость DirectDraw Plocha DirectDraw Datoteka predmeta DirectDraw Superfaqe DirectDraw @@ -24899,7 +25741,7 @@ cúrsóir X11 Cursor X11 סמן של X11 - X11 kursor + X11 pokazivač X11 kurzor Cursor X11 Kursor X11 @@ -24917,7 +25759,7 @@ cursor X11 Cursor do X11 Cursor X11 - курсор X11 + Курсор X11 Kurzor X11 Datoteka kazalke X11 Kursor X11 @@ -24971,7 +25813,7 @@ imagem EXR Imagem EXR Imagine EXR - изображение EXR + Изображение EXR Obrázok EXR Slikovna datoteka EXR Figurë EXR @@ -25026,7 +25868,7 @@ desenho Quickdraw/PICT de Macintosh Desenho do Macintosh Quickdraw/PICT Desen Macintosh Quickdraw/PICT - рисунок Macintosh Quickdraw/PICT + Рисунок Macintosh Quickdraw/PICT Kresba Macintosh QuickDraw/PICT Datoteka risbe Macintosh Quickdraw/PICT Vizatim Macintosh Quickdraw/PICT @@ -25097,7 +25939,7 @@ imagem UFRaw ID Imagem ID do UFRaw ID imagine UFRaw - изображение UFRaw ID + Изображение UFRaw ID Obrázok ID UFRaw Slikovna datoteka UFRaw ID Figurë UFRaw ID @@ -25130,7 +25972,7 @@ digitaalinen raakakuva talgild rámynd image brute numérique - amhíomhá digiteach + amhíomhá dhigiteach imaxe en bruto dixital תמונה דיגטלית גולמית Digitalna osnovna slika @@ -25151,7 +25993,7 @@ imagem digital em bruto Imagem digital bruta imagine digitală brută - необработанные цифровые изображения + Необработанное цифровое изображение Digitálny surový obrázok surova digitalna slika Figurë raw dixhitale @@ -25201,7 +26043,7 @@ negativo Adobe DNG Negativo DNG da Adobe Negativ Adobe DNG - негатив Adobe DNG + Негатив Adobe DNG Adobe Digital Negative (DNG) Datoteka negativa Adobe DNG Negativ Adobe DNG @@ -25258,7 +26100,7 @@ imagem em bruto Canon CRW Imagem bruta CRW da Canon Imagine brută Canon CRW - необработанное изображение Canon CRW + Необработанное изображение Canon CRW Surový obrázok Canon CRW Surova slikovna datoteka Canon CRW Figurë raw Canon CRW @@ -25267,7 +26109,7 @@ Canon CRW ham görüntüsü цифровий негатив CRW Canon Ảnh thô Canon CRW - Canon CRW 原始图像 + 佳能 CRW 原始图像 Canon CRW 原生影像 CRW Canon RaW @@ -25316,7 +26158,7 @@ imagem em bruto Canon CR2 Imagem bruta CR2 da Canon Imagine brută Canon CR2 - необработанное изображение Canon CR2 + Необработанное изображение Canon CR2 Surový obrázok Canon CR2 Surova slikovna datoteka Canon CR2 Figurë raw Canon CR2 @@ -25325,7 +26167,7 @@ Canon CR2 ham görüntüsü цифровий негатив CR2 Canon Ảnh thô Canon CR2 - Canon CR2 原始图像 + 佳能 CR2 原始图像 Canon CR2 原生影像 CR2 Canon Raw 2 @@ -25371,7 +26213,7 @@ imagem em bruto Fuji RAF Imagem bruta RAF da Fuji Imagine brută Fuji RAF - необработанное изображение Fuji RAF + Необработанное изображение Fuji RAF Surový obrázok Fuji RAF Surova slikovna datoteka Fuji RAF Figurë raw Fuji RAF @@ -25380,7 +26222,7 @@ Fuji RAF ham görüntüsü Цифровий негатив RAF Fuji Ảnh thô Fuji RAF - 富士RAF 原始图像 + 富士 RAF 原始图像 Fuji RAF 原生影像 RAF RAw Format @@ -25427,7 +26269,7 @@ imagem em bruto Kodak DCR Imagem bruta DCR da Kodak Imagine brută Kodak DCR - необработанное изображение Kodak DCR + Необработанное изображение Kodak DCR Surový obrázok Kodak DCR Surova slikovna datoteka Kodak DCR Figurë raw Kodak DCR @@ -25436,7 +26278,7 @@ Kodak DCR ham görüntüsü цифровий негатив DCR Kodak Ảnh thô Kodak DCR - Kodak DCR 原始图像 + 柯达 DCR 原始图像 Kodak DCR 原生影像 DCR Digital Camera Raw @@ -25481,7 +26323,7 @@ imagem em bruto Kodak K25 Imagem bruta K25 da Kodak Imagine brută Kodak K25 - необработанное изображение Kodak K25 + Необработанное изображение Kodak K25 Surový obrázok Kodak K25 Surova slikovna datoteka Kodak K25 Figurë raw Kodak K25 @@ -25490,7 +26332,7 @@ Kodak K25 ham görüntüsü цифровий негатив K25 Kodak Ảnh thô Kodak K25 - Kodak K25 原始图像 + 柯达 K25 原始图像 Kodak K25 原生影像 K25 Kodak DC25 @@ -25535,7 +26377,7 @@ imagem em bruto Kodak KDC Imagem bruta KDC da Kodak Imagine brută Kodak KDC - необработанное изображение Kodak KDC + Необработанное изображение Kodak KDC Surový obrázok Kodak KDC Surova slikovna datoteka Kodak KDC Figurë raw Kodak KDC @@ -25544,7 +26386,7 @@ Kodak KDC ham görüntüsü цифровий негатив KDC Kodak Ảnh thô Kodak KDC - Kodak KDC 原始图像 + 柯达 KDC 原始图像 Kodak KDC 原生影像 KDC Kodak Digital Camera @@ -25592,7 +26434,7 @@ imagem em bruto Minolta MRW Imagem bruta MRW do Minolta Imagine brută Minolta MRW - необработанное изображение Minolta MRW + Необработанное изображение Minolta MRW Surový obrázok Minolta MRW Surova slikovna datoteka Minolta MRW Figurë raw Minolta MRW @@ -25601,7 +26443,7 @@ Minolta MRW ham görüntüsü цифровий негатив MRW Minolta Ảnh thô Minolta MRW - Minolta MRW 原始图像 + 美能达 MRW 原始图像 Minolta MRW 原生影像 MRW Minolta RaW @@ -25648,7 +26490,7 @@ imagem em bruto Nikon NEF Imagem bruta NEF da Nikon Imagine brută Nikon NEF - необработанное изображение Nikon NEF + Необработанное изображение Nikon NEF Surový obrázok Nikon NEF Surova slikovna datoteka Nikon NEF Figurë raw Nikon NEF @@ -25657,7 +26499,7 @@ Nikon NEF ham görüntüsü цифровий негатив NEF Nikon Ảnh thô Nikon NEF - Nikon NEF 原始图像 + 尼康 NEF 原始图像 Nikon NEF 原生影像 NEF Nikon Electronic Format @@ -25703,7 +26545,7 @@ imagem em bruto Olympus ORF Imagem bruta ORF da Olympus Imagine brută Olympus ORF - необработанное изображение Olympus ORF + Необработанное изображение Olympus ORF Surový obrázok Olympus ORF Surova slikovna datoteka Olympus ORF Figurë raw Olympus ORF @@ -25712,7 +26554,7 @@ Olympus ORF ham görüntüsü цифровий негатив ORF Olympus Ảnh thô Olympus ORF - Olympus ORF 原始图像 + 奥林巴斯 ORF 原始图像 Olympus ORF 原生影像 ORF Olympus Raw Format @@ -25727,7 +26569,7 @@ - + Panasonic raw image صورة Panasonic خامة Suvoraja vyjava Panasonic @@ -25764,7 +26606,7 @@ imagem em bruto Panasonic Imagem bruta da Panasonic Imagine brută Panasonic - необработанное изображение Panasonic + Необработанное изображение Panasonic Surový obrázok Panasonic Surova slikovna datoteka Panasonic Figurë raw Panasonic @@ -25773,7 +26615,7 @@ Panasonic ham görüntüsü цифровий негатив Panasonic Ảnh thô Panasonic - Panasonic 原始图像 + 松下原始图像 Panasonic 原生影像 @@ -25781,8 +26623,9 @@ + - + Panasonic raw2 image Изображение — Panasonic raw2 imatge «RAW2» de Panasonic @@ -25795,6 +26638,7 @@ Panasonic raw2 irudia Panasonic raw2 -kuva image raw2 Panasonic + íomhá raw2 Panasonic imaxe en bruto raw2 de Panasonic תמונת raw2 של Panasonic Panasonic raw2 image @@ -25811,14 +26655,14 @@ Obraz raw2 Panasonic imagem em bruto Panasonic Imagem raw2 da Panasonic - необработанное изображение Panasonic RAW 2 + Необработанное изображение Panasonic raw2 Surový obrázok Panasonic raw2 Slikovna datoteka Panasonic raw2 Панасоник сирова2 слика Panasonic raw2-bild Panasonic raw2 görüntüsü зображення формату raw2 Panasonic - Panasonic raw2 图像 + 松下 raw2 图像 Panasonic raw2 影像 @@ -25826,6 +26670,7 @@ + Pentax PEF raw image @@ -25864,7 +26709,7 @@ imagem em bruto Pentax PEF Imagem bruta PEF da Pentax Imagine brută Pentax PEF - необработанное изображение Pentax PEF + Необработанное изображение Pentax PEF Surový obrázok Pentax PEF Surova slikovna datoteka Pentax PEF Figurë raw Pentax PEF @@ -25873,7 +26718,7 @@ Pentax PEF ham görüntüsü цифровий негатив PEF Pentax Ảnh thô Pentax PEF - Pentax PEF 原始图像 + 宾得 PEF 原始图像 Pentax PEF 原生影像 PEF Pentax Electronic Format @@ -25918,7 +26763,7 @@ imagem em bruto Sigma X3F Imagem bruta X3F da Sigma Imagine brută Sigma X3F - необработанное изображение Sigma X3F + Необработанное изображение Sigma X3F Surový obrázok Sigma X3F Surova slikovna datoteka Sigma X3F Fifurë raw Sigma X3F @@ -25927,7 +26772,7 @@ Sigma X3F ham görüntüsü цифровий негатив X3F Sigma Ảnh thô Sigma X3F - Sigma X3F 原始图像 + 适马 X3F 原始图像 Sigma X3F 原生影像 X3F X3 Foveon @@ -25978,7 +26823,7 @@ imagem em bruto Sony SRF Imagem bruta SRF da Sony Imagine brută Sony SRF - необработанное изображение Sony SRF + Необработанное изображение Sony SRF Surový obrázok Sony SRF Surova slikovna datoteka Sony SRF Figurë raw Sony SRF @@ -25987,7 +26832,7 @@ Sony SRF ham görüntüsü цифровий негатив SRF Sony Ảnh thô Sony SRF - Sony SRF 原始映像 + 索尼 SRF 原始映像 Sony SRF 原生影像 SRF Sony Raw Format @@ -26032,7 +26877,7 @@ imagem em bruto Sony SR2 Imagem bruta SR2 da Sony Imagine brută Sony SR2 - необработанное изображение Sony SR2 + Необработанное изображение Sony SR2 Surový obrázok Sony SR2 Surova slikovna datoteka Sony SR2 Figurë raw Sony SR2 @@ -26041,7 +26886,7 @@ Sony SR2 ham görüntüsü цифровий негатив SR2 Sony Ảnh thô Sony SR2 - Sony SR2 原始映像 + 索尼 SR2 原始映像 Sony SR2 原生影像 SR2 Sony Raw format 2 @@ -26086,7 +26931,7 @@ imagem em bruto Sony ARW Imagem bruta ARW da Sony Imagine brută Sony ARW - необработанное изображение Sony ARW + Необработанное изображение Sony ARW Surový obrázok Sony ARW Surova slikovna datoteka Sony ARW Figurë raw Sony ARW @@ -26095,7 +26940,7 @@ Sony ARW ham görüntüsü цифровий негатив ARW Sony Ảnh thô Sony ARW - Sony ARW 原始映像 + 索尼 ARW 原始映像 Sony ARW 原生影像 ARW Alpha Raw format @@ -26144,7 +26989,7 @@ imagem PNG Imagem PNG Imagine PNG - изображение PNG + Изображение PNG Obrázok PNG Slikovna datoteka PNG Figurë PNG @@ -26175,7 +27020,7 @@ 'Run Lenght Encoded' bitmap irudia RLE-koodattu bittikartta image matricielle Run Length Encoded - íomhá mhapa giotáin Run Length Encoded + íomhá ghiotánmhapach ionchódaithe fad reatha mapa de bits con codificación do tamaño durante a execución מקודד מפת סיביות של Run Length Run Length Encoded bitmap slika @@ -26196,7 +27041,7 @@ mapa de bitas Run Length Encoded Classe de comprimento imagem bitmap codificada Imagine bitmap codată RLE - растровое изображение (сжатое RLE) + Растровое изображение, сжатое RLE Bitmapový obrázok Run Length Encoded Zaporedno kodirana bitna slika (RLE) Figurë bitmap RLE (Run Length Encoded) @@ -26247,7 +27092,7 @@ imagem SVG Imagem SVG Imagine SVG - изображение SVG + Изображение SVG Obrázok SVG Slikovna vektorska datoteka SVG Figurë SVG @@ -26287,7 +27132,7 @@ íomhá SVG comhbhrúite imaxe SVG comprimida תמונת SVG מכווצת - komprimirana SVG slika + Sažeta SVG slika tömörített SVG kép Imagine SVG comprimite Citra SVG terkompresi @@ -26305,7 +27150,7 @@ imagem SVG comprimida Imagem SVG compactada imagine comprimată SVG - сжатое изображение SVG + Сжатое изображение SVG Komprimovaný obrázok SVG Slikovna datoteka SVG (stisnjena) Figurë SVG e kompresuar @@ -26360,7 +27205,7 @@ imagem TIFF Imagem TIFF Imagine TIFF - изображение TIFF + Изображение TIFF Obrázok TIFF Slikovna datoteka TIFF Figurë TIFF @@ -26389,9 +27234,9 @@ Πολυσέλιδη εικόνα TIFF Multi-page TIFF image imagen TIFF de varias páginas - Orri anitzeko TIFF irudia Monisivuinen TIFF-kuva Image TIFF multi-page + íomhá il-leathanach TIFF Imaxe TIFF multipáxina תמונת TIFF עם ריבוי עמודים Višestrana TIFF slika @@ -26425,7 +27270,7 @@ Vyjava AutoCAD Изображение — AutoCAD imatge d'AutoCAD - obrázek AutoCAD + výkres AutoCAD Delwedd AutoCAD AutoCAD-billede AutoCAD-Bild @@ -26460,7 +27305,7 @@ imagem AutoCAD Imagem do AutoCAD Imagine AutoCAD - изображение AutoCAD + Изображение AutoCAD Obrázok AutoCAD Slikovna datoteka AutoCAD Figurë AutoCAD @@ -26490,7 +27335,7 @@ DXF-vektorikuva DXF vektormynd image vectorielle DXF - íomhá veicteoir DXF + íomhá veicteoireach DXF imaxe de vector DXF תמונת DXF וקטורית DXF vektorska slika @@ -26513,7 +27358,7 @@ imagem de vectores DXF Imagem vetorial DXF Imagine vectorială DXF - векторное изображение DXF + Векторное изображение DXF Vektorový obrázok DXF Slikovna vektorska datoteka DXF Figurë vektoriale DFX @@ -26533,6 +27378,7 @@ Microsoft Document Imaging format صيغة مستند تصوير مايكروسوفت + Formatu d'imáxenes de Microsoft Document Изображение — Microsoft Document Imaging format Microsoft Document Imaging formát Microsoft Document Imaging @@ -26564,7 +27410,7 @@ formato Microsoft Document Imaging Formato do Microsoft Document Imaging Format Microsoft Document Imaging - формат Microsoft Document Imaging + Формат Microsoft Document Imaging Formát Microsoft Document Imaging Zapis Microsoft Document Imaging запис слика Мајкрософтовог документа @@ -26572,7 +27418,7 @@ Microsoft Belge Görüntüleme biçimi формат Microsoft Document Imaging Định dạng tạo ảnh tài liệu Microsoft - Microsoft Document Imaging 扫描图像 + Microsoft Document Imaging 格式 微軟文件影像格式 MDI Microsoft Document Imaging @@ -26593,6 +27439,7 @@ WebP irudia WebP-kuva image WebP + íomhá WebP Imaxe WebP תמונת WebP WebP slika @@ -26664,7 +27511,7 @@ imagem 3D Studio Imagem do 3D Studio Imagine 3D Studio - сцена 3D Studio + Сцена 3D Studio Obrázok 3D Studio Slikovna datoteka 3D Studio Figurë 3D Studio @@ -26717,7 +27564,7 @@ imagem Applix Graphics Imagem do Applix Graphics Imagine Applix Graphics - изображение Applix Graphics + Изображение Applix Graphics Obrázok Applix Graphics Slikovna datoteka Applix Graphics Figurë Applix Graphics @@ -26754,7 +27601,7 @@ íomhá EPS (comhbhrúite le bzip) imaxe EPS (comprimida con bzip) תמונת EPS (מכווץ בbzip) - EPS slika (komprimirana bzip-om) + EPS slika (bzip sažeta) EPS kép (bzip-tömörítésű) Imagine EPS (comprimite con bzip) Citra EPS (terkompresi bzip) @@ -26773,7 +27620,7 @@ imagem EPS (compressão bzip) Imagem EPS (compactada com bzip) Imagine EPS (compresie bzip) - изображение EPS (сжатое bzip) + Изображение EPS (сжатое bzip) Obrázok EPS (komprimovaný pomocou bzip) Slikovna datoteka EPS (stisnjena z bzip) Figurë EPS (e kompresuar me bzip) @@ -26782,7 +27629,7 @@ EPS görüntüsü (bzip ile sıkıştırılmış) зображення EPS (стиснене bzip) Ảnh EPS (đã nén bzip) - EPS 图像(bzip 压缩) + EPS 图像(bzip 压缩) EPS 影像 (bzip 格式壓縮) @@ -26831,7 +27678,7 @@ imagem raster CMU Imagem raster CMU Imagine raster CMU - растровое изображение CMU + Растровое изображение CMU Rastrový obrázok CMU Slikovna rastrska datoteka CMU Figurë raster CMU @@ -26840,7 +27687,7 @@ CMU tarama görüntüsü растрове зображення CMU Ảnh mành CMU - CMU 矢量图像 + CMU 光栅图像 CMU raster 影像 @@ -26881,7 +27728,7 @@ imagem GIMP comprimida Imagem do GIMP compactada imagine comprimată GIMP - сжатое изображение GIMP + Сжатое изображение GIMP Komprimovaný obrázok GIMP Slikovna datoteka GIMP (stisnjena) Figurë GIMP e kompresuar @@ -26934,7 +27781,7 @@ imagem DICOM Imagem DICOM Imagine DICOM - изображение DICOM + Изображение DICOM Obrázok DICOM Slikovna datoteka DICOM Figurë DICOM @@ -26957,6 +27804,7 @@ DocBook document مستند DocBook + Documentu DocBook Dakument DocBook Документ — DocBook document DocBook @@ -26993,7 +27841,7 @@ documento DocBook Documento DocBook Document DocBook - документ DocBook + Документ DocBook Dokument DocBook Dokument DocBook Dokument DocBook @@ -27056,7 +27904,7 @@ imagem DIB Imagem DIB Imagine DIB - изображение DIB + Изображение DIB Obrázok DIB Slikovna datoteka DIB Figurë DIB @@ -27113,7 +27961,7 @@ imagem DjVu Imagem DjVu Imagine DjVu - изображение DjVu + Изображение DjVu Obrázok DjVu Slikovna datoteka DjVu Figurë DjVu @@ -27126,7 +27974,7 @@ DjVu 影像 - + @@ -27139,6 +27987,7 @@ DjVu document + Documentu DjVu document DjVu dokument DjVu DjVu-dokument @@ -27149,6 +27998,7 @@ DjVu dokumentua DjVu-asiakirja document DjVu + cáipéis DjVu מסמך DjVu DjVu dokument DjVu dokumentum @@ -27161,7 +28011,7 @@ Dokument DjVu documento DjVu Documento DjVu - документ DjVu + Документ DjVu Dokument DjVu ДјВу документ DjVu-dokument @@ -27170,7 +28020,7 @@ DjVu 文档 DjVu 文件 - + @@ -27221,7 +28071,7 @@ imagem DPX Imagem DPX Imagine DPX - изображение DPX + Изображение DPX Obrázok DPX Slikovna datoteka DPX Figurë DPX @@ -27277,7 +28127,7 @@ imagem EPS Imagem EPS Imagine EPS - изображение EPS + Изображение EPS Obrázok EPS Slikovna datoteka EPS Figurë EPS @@ -27307,6 +28157,7 @@ FITS document مستند FITS + Documentu FITS Dakument FITS Документ — FITS document FITS @@ -27343,7 +28194,7 @@ documento FITS Documento FITS Document FITS - документ FITS + Документ FITS Dokument FITS Dokument FITS Dokument FITS @@ -27401,7 +28252,7 @@ imagem FPX Imagem FPX Imagine FPX - изображение FPX + Изображение FPX Obrázok FPX Slikovna datoteka FPX Figurë FPX @@ -27437,7 +28288,7 @@ íomhá EPS (comhbhrúite le gzip) imaxe EPS (comprimida con gzip) תמונת EPS (מכווץ ע״י gzip) - EPS slika (komprimirana gzip-om) + EPS slika (gzip sažeta) EPS kép (gzip-tömörítésű) Imagine EPS (comprimite con gzip) Citra EPS (terkompresi gzip) @@ -27456,7 +28307,7 @@ imagem EPS (compressão gzip) Imagem EPS (compactada com gzip) Imagine EPS (compresie gzip) - изображение EPS (сжатое gzip) + Изображение EPS (сжатое gzip) Obrázok EPS (komprimovaný pomocou gzip) Slikovna datoteka EPS (stisnjena z gzip) Figurë EPS (e kompresuar me gzip) @@ -27465,7 +28316,7 @@ EPS görüntüsü (gzip ile sıkıştırılmış) зображення EPS (стиснене gzip) Ảnh EPS (đã nén gzip) - EPS 图像(gzip 压缩) + EPS 图像(gzip 压缩) EPS 影像 (gzip 格式壓縮) @@ -27484,6 +28335,7 @@ Windows ikonoa Windows-kuvake icône Windows + deilbhín Windows סמל של Windows Windows ikona Windows ikon @@ -27496,7 +28348,7 @@ Ikona Windows ícone Windows Ícone do Windows - значок Windows + Значок Windows Ikona Windows Ikona Windows Иконица Виндоуза @@ -27557,7 +28409,7 @@ ćone MacOS X Ícone do MacOS X Iconiță MacOS X - значок MacOS X + Значок MacOS X Ikona MacOS X Datoteka ikone MacOS X Ikonë MacOS X @@ -27614,7 +28466,7 @@ imagem ILBM Imagem ILBM Imagine ILBM - изображение ILBM + Изображение ILBM Obrázok ILMB Slikovna datoteka ILBM Figurë ILBM @@ -27678,7 +28530,7 @@ imagem JNG Imagem JNG Imagine JNG - изображение JNG + Изображение JNG Obrázok JNG Slikovna datoteka JNG Figurë JNG @@ -27734,7 +28586,7 @@ Objecto LightWave Objeto LightWave Obiect LightWave - объект LightWave + Объект LightWave Objekt LightWave Datoteka predmeta LightWave Objekt LightWave @@ -27789,7 +28641,7 @@ cenário LightWave Cena LightWave Scenă LightWave - сцена LightWave + Сцена LightWave Scéna LightWave Datoteka scene LightWave Skenë LightWave @@ -27818,7 +28670,7 @@ MacPaint-bittikartta MacPaint Bitmap mynd image matricielle MacPaint - íomhá MacPaint Bitmap + íomhá ghiotánmhapach MacPaint imaxe de mapa de bits MacPaint תמונת מפת-סיביות של MacPaint MacPaint Bitmap slika @@ -27839,7 +28691,7 @@ imagem MacPaint Bitmap Imagem de bitmap do MacPaint Imagine MacPaint Bitmap - растровое изображение MacPaint + Растровое изображение MacPaint Obrázok MacPaint Bitmap Slikovna bitna datoteka MacPaint Figurë BitMap MacPaint @@ -27889,7 +28741,7 @@ desenho Office Desenho do Office Desen Office - изображение Office + Рисунок Office Kresba Office Datoteka risbe Office Vizatim Office @@ -27898,7 +28750,7 @@ Ofis çizimi малюнок Office Bản vẽ Office - Microsoft Office 绘图 + Office 绘图 Office 繪圖 @@ -27940,7 +28792,7 @@ imagem NIFF Imagem NIFF Imagine NIF - изображение NIFF + Изображение NIFF Obrázok NIFF Slikovna datoteka NIFF Figurë NIFF @@ -27993,7 +28845,7 @@ imagem PCX Imagem PCX Imagine PCX - изображение PCX + Изображение PCX Obrázok PCX Slikovna datoteka PCX Figurë PCX @@ -28056,7 +28908,7 @@ imagem PCD Imagem PCD Imagine PCD - изображение PCD + Изображение PCD Obrázok PCD Slikovna datoteka PCD Figurë PCD @@ -28112,7 +28964,7 @@ imagem PNM Imagem PNM Imagine PNM - изображение PNM + Изображение PNM Obrázok PNM Slikovna datoteka PNM Figurë PNM @@ -28165,7 +29017,7 @@ imagem PBM Imagem PBM Imagine PBM - изображение PBM + Изображение PBM Obrázok PBM Slikovna datoteka PBM Figurë PBM @@ -28234,7 +29086,7 @@ imagem PGM Imagem PGM Imagine PGM - изображение PGM + Изображение PGM Obrázok PGM Slikovna datoteka PGM Figurë PGM @@ -28303,7 +29155,7 @@ imagem PPM Imagem PPM Imagine PPM - изображение PPM + Изображение PPM Obrázok PPM Slikovna datoteka PPM Figurë PPM @@ -28369,7 +29221,7 @@ imagem Photoshop Imagem do Photoshop Imagine Photoshop - изображение Photoshop + Изображение Photoshop Obrázok Photoshop Slikovna datoteka Photoshop Фотошоп слика @@ -28431,7 +29283,7 @@ imagem RGB Imagem RGB Imagine RGB - изображение RGB + Изображение RGB Obrázok RGB Slikovna datoteka RGB Figurë RGB @@ -28482,7 +29334,7 @@ imagem SGI Imagem SGI Imagine SGI - изображение SGI + Изображение SGI Obrázok SGI Slikovna datoteka SGI Figurë SGI @@ -28532,7 +29384,7 @@ imagem raster Sun Imagem raster da Sun Imagine rasterizată Sun - растровое изображение Sun + Растровое изображение Sun Rastrový obrázok Sun Slikovna rastrska datoteka Sun Figurë raster Sun @@ -28586,7 +29438,7 @@ imagem TGA Imagem TGA Imagine TGA - изображение TGA + Изображение TGA Obrázok TGA Slikovna datoteka TGA Figurë TGA @@ -28614,8 +29466,8 @@ - + @@ -28641,7 +29493,7 @@ cúrsóir Windows Cursor de Windows סמן של Windows - Windows kursor + Windows pokazivač Windows-kurzor Cursor pro Windows Kursor Windows @@ -28660,7 +29512,7 @@ cursor Windows Cursor do Windows Cursor Windows - курсор Windows + Курсор Windows Kurzor Windows Datoteka kazalke Windows Kursor Windows @@ -28694,10 +29546,10 @@ animoitu Windows-osoitin Windows livindaigjørdur vísi curseur animé Windows - cúrsóir beo Windows + cúrsóir beoite Windows Cursor animado de Windows סמן מונפש של Windows - Windows animirani kursor + Windows animirani pokazivač Windows animált kurzor Cursor animate pro Windows Kursor animasi Windows @@ -28714,7 +29566,7 @@ cursor animado Windows Cursor animado do Windows Cursor animat Windows - анимированный курсор Windows + Анимированный курсор Windows Animovaný kurzor Windows Datoteka animirane kazalke Windows Kursor i animuar Windows @@ -28723,7 +29575,7 @@ Windows canlandırmalı imleci анімований курсор Windows Con chạy hoạt họa Windows - Windows 动画光标 + Windows 动态光标 Windows 滑鼠動畫游標 @@ -28771,7 +29623,7 @@ imagem EMF Imagem EMF Imagine EMF - изображение EMF + Изображение EMF Obrázok EMF Slikovna datoteka EMF Figurë EMF @@ -28836,7 +29688,7 @@ imagem WMF Imagem WMF Imagine WMF - изображение WMF + Изображение WMF Obrázok WMF Slikovna datoteka WMF Figurë WMF @@ -28907,7 +29759,7 @@ imagem XBM Imagem XBM Imagine XBM - изображение XBM + Изображение XBM Obrázok XBM Slikovna datoteka XBM Figurë XBM @@ -28962,7 +29814,7 @@ imagem GIMP Imagem do GIMP Imagine GIMP - изображение GIMP + Изображение GIMP Obrázok GIMP Slikovna datoteka GIMP Figurë GIMP @@ -28979,6 +29831,80 @@ + + GIMP brush + pinzell de GIMP + štětec GIMP + GIMP-Pinsel + GIMP brush + pincel del GIMP + GIMP kist + GIMP ecset + Kuas GIMP + Pennello GIMP + GIMP бояу жаққышы + GIMP 붓 + Pędzel programu GIMP + Pincel do GIMP + Кисть GIMP + Štetec aplikácie GIMP + GIMP-pensel + пензель GIMP + GIMP 笔刷 + GIMP 筆刷 + + + + + + + GIMP brush pipe + conducte del pinzell de GIMP + zřetězení štětců GIMP + GIMP-Pinselanimation + GIMP brush pipe + pincel animado del GIMP + GIMP valjkasti kist + GIMP ecsetcsatorna + Pipa kuas GIMP + Pipe pennello GIMP + GIMP бояу жаққыш түтігі + GIMP 붓 파이프 + Potok pędzla programu GIMP + Tubo de pincel do GIMP + Анимированная кисть GIMP + GIMP-penselrör + канал пензлів GIMP + GIMP 管刷 + GIMP 筆刷導管 + + + + GIMP pattern + patró de GIMP + vzorek GIMP + GIMP-Muster + GIMP pattern + patrón del GIMP + GIMP uzorak + GIMP minta + Pola GIMP + Motivo GIMP + GIMP оюы + GIMP 패턴 + Deseń programu GIMP + Textura do GIMP + Шаблон GIMP + Vzor aplikácie GIMP + GIMP-mönster + візерунок GIMP + GIMP 图案 + GIMP 樣式 + + + + + XFig image صورة XFig @@ -29018,7 +29944,7 @@ imagem XFig Imagem do XFig Imagine XFig - изображение XFig + Изображение XFig Obrázok XFig Slikovna datoteka XFig Figurë XFig @@ -29073,7 +29999,7 @@ imagem XPM Imagem XPM Imagine XPM - изображение XPM + Изображение XPM Obrázok XPM Slikovna datoteka XPM Figurë XPM @@ -29111,7 +30037,7 @@ X-ikkunakuva X vindeyga mynd image X window - íomhá fhuinneog X + íomhá X-windows imaxe de X Window תמונת חלון של X X window slika @@ -29133,7 +30059,7 @@ imagem de janela X Imagem de janela do X Imagine X window - изображение X window + Изображение X window Obrázok X window slika X oken Figurë X window @@ -29142,13 +30068,14 @@ X pencere görüntüsü зображення X window Ảnh cửa sổ X - X window 图像 + X Window 图像 X window 影像 block device جهاز كتلي + preséu de bloques blokavaja pryłada Блоково устройство dispositiu de blocs @@ -29169,7 +30096,7 @@ Blokovski uređaj blokkos eszköz Dispositivo de blocos - blok divais + peranti blok Device a blocchi ブロックデバイス блоктық құрылғысы @@ -29185,7 +30112,7 @@ dispositivo de bloco Dispositivo de bloco dispozitiv bloc - блочное устройство + Блочное устройство Blokové zariadenie bločna naprava device me blloqe @@ -29200,6 +30127,7 @@ character device جهاز حرفي + preséu de caráuteres znakavaja pryłada Символно устройство dispositiu de caràcters @@ -29220,7 +30148,7 @@ Znakovni uređaj karakteres eszköz Dispositivo de characteres - karakter divais + peranti karakter Device a caratteri キャラクタデバイス символдық құрылғысы @@ -29236,7 +30164,7 @@ dispositivo de caracteres Dispositivo de caractere dispozitiv caracter - символьное устройство + Символьное устройство Znakové zariadenie znakovna naprava device me karaktere @@ -29251,6 +30179,7 @@ folder مجلّد + carpeta kataloh Папка carpeta @@ -29268,7 +30197,7 @@ fillteán cartafol תיקייה - direktorij + Mapa mappa Dossier folder @@ -29287,7 +30216,7 @@ pasta Pasta dosar - папка + Папка Priečinok mapa Kartelë @@ -29340,7 +30269,7 @@ canal Pipe canal pipe - канал + Канал Rúra cev Pipe @@ -29355,6 +30284,7 @@ mount point نقطة الوصْل + puntu de montaxe punkt mantavańnia Точка на монтиране punt de muntatge @@ -29372,7 +30302,7 @@ pointe feistithe punto de montaxe נקודת עיגון - točka montiranja + Točka montiranja csatolási pont Puncto de montage titik mount @@ -29391,7 +30321,7 @@ ponto de montagem Ponto de montagem loc montare - точка монтирования + Точка монтирования Miesto pripojenia priklopna točka Pikë montimi @@ -29424,7 +30354,7 @@ soicéad socket נקודת חיבור - utičnica + Priključnica illesztőpont Socket soket @@ -29443,7 +30373,7 @@ tomada Socket socket - сокет + Сокет Soket vtič Socket @@ -29458,6 +30388,7 @@ symbolic link وصلة رمزية + enllaz simbólicu simvolik körpü symbalnaja spasyłka Символна връзка @@ -29477,7 +30408,7 @@ nasc siombalach ligazón simbólica קישור סימבולי - simbolička veza + Simbolička poveznica szimbolikus link Ligamine symbolic taut simbolik @@ -29497,7 +30428,7 @@ ligação simbólica Ligação simbólica legătură simbolică - символьная ссылка + Символьная ссылка Symbolický odkaz simbolna povezava Lidhje simbolike @@ -29528,10 +30459,10 @@ viestin jakeluilmoitus post útberingarfrásøgn rapport de livraison de courriels - tuairisc sheachadadh poist + tuairisc sheachadta r-phoist informe de entrega de correo דוח העברת דואר - izvještaj dostave pošte + Izvještaj dostave pošte jelentés levélkézbesítésről Reporto de livration de e-mail laporan pengantaran surat @@ -29550,7 +30481,7 @@ relatório de entrega de email Relatório de entrega de correspondência raport de trimitere email - отчёт о доставке сообщения + Отчёт о доставке сообщения Správa o doručení pošty poročilo dostave pošte Raport mbi dorëzimin e mesazhit @@ -29583,7 +30514,7 @@ viestin kuittausilmoitus post avhendingarfrásøgn rapport de disposition de courriels - tuairisc chóiriú poist + tuairisc chóirithe r-phoist informe de disposición de correo דוח אספקת דואר Izvještaj smještaja e-pošte @@ -29605,7 +30536,7 @@ relatório de disposição de email Relatório de disposição de correspondência confirmare primire email - отчёт о перемещении почты + Отчёт о перемещении почты Správa o odovzdaní pošty poročilo razporeditve pošte Raport mbi njoftimin e mesazhit @@ -29641,7 +30572,7 @@ tagairt do chomhad cianda referencia a un ficheiro remoto התיחסות לקובץ מרוחק - referenca na udaljenu datoteku + Preporuka na udaljenu datoteku hivatkozás távoli fájlra Referentia a un file remote referensi ke berkas jarak jauh @@ -29660,7 +30591,7 @@ referência a um ficheiro remoto Referência para arquivo remoto referință fișier la distanță - ссылка на удалённый файл + Ссылка на удалённый файл Odkaz na vzdialený súbor sklic do oddaljene datoteke Referim për tek file në distancë @@ -29692,7 +30623,7 @@ nyyssiviesti Usenet news boð message de groupe d'échange Usenet - teachtaireacht nuacht Usenet + teachtaireacht nuachta Usenet mensaxes de noticias de Usenet הודעת חדשות של Usenet Usenet poruka novosti @@ -29714,7 +30645,7 @@ mensagem de notícias Usenet Mensagem de notícias da Usenet Mesaj Usenet de știri - новостное сообщение Usenet + Новостное сообщение Usenet Príspevok do diskusných skupín Usenet novičarsko sporočilo Usenet Mesazh lajmesh Usenet @@ -29754,14 +30685,14 @@ teachtaireacht ríomhphoist neamhiomlán mensaxe de correo electrónico parcial מסר דוא״ל חלקי - djelomična poruka e-pošte + Nepotpuna poruka e-pošte részleges elektronikus levél Message de e-mail partial pesan email sebagian Messaggio email parziale 部分メールメッセージ электронды поштаның үзінді мәлімдемесі - 부분적 전자 우편 메시지 + 전자 우편 메시지 일부 nepilnas el. laiškas daļēja e-pasta vēstule Bahagian mesej emel @@ -29773,7 +30704,7 @@ mensagem parcial de email Mensagem de e-mail parcial mesaj de email parțial - фрагмент сообщения электронной почты + Фрагмент сообщения электронной почты Čiastočná e-mailová správa delno elektronsko sporočilo Mesazh poste i pjesëshëm @@ -29807,7 +30738,7 @@ teachtaireacht ríomhphoist mensaxe de correo electrónico הודעת דואר אלקטרוני - poruka e-pošte + Poruka e-pošte elektronikus levél Message de e-mail pesan email @@ -29826,7 +30757,7 @@ mensagem de email Mensagem de e-mail mesaj email - почтовое сообщение + Почтовое сообщение E-mailová správa sporočilo elektronske pošte Mesazh poste @@ -29872,7 +30803,7 @@ GNU-postiviesti GNU mail boð message de courriel GNU - teachtaireacht phost GNU + teachtaireacht r-phoist GNU mensaxe de correo electrónico de GNU הודעת דואר של GNU GNU poruka pošte @@ -29895,7 +30826,7 @@ mensagem de email GNU Mensagem de e-mail GNU Mesaj GNU mail - почтовое сообщение GNU + Почтовое сообщение GNU Správa GNU mail Sporočilo pošte GNU Mesazh GNU mail @@ -29911,20 +30842,31 @@ IGES document + Documentu IGES document IGES + dokument IGES IGES-dokument IGES-Dokument + IGES document documento IGES + IGES dokumentua IGES-asiakirja document IGES + cáipéis IGES מסמך IGES + IGES dokument IGES dokumentum + dokumen IGES + Documento IGES IGES құжаты IGES 문서 Dokument IGES Documento IGES - документ IGES + Документ IGES Dokument IGES + ИГЕС документ + IGES-dokument + IGES belgesi документ IGES IGES 文档 IGES 文件 @@ -29942,6 +30884,7 @@ VRML document مستند VRML + Documentu VRML VRML sənədi Dakument VRML Документ — VRML @@ -29980,7 +30923,7 @@ documento VRML Documento VRML Document VRML - документ VRML + Документ VRML Dokument VRML Dokument VRML Dokument VRML @@ -30021,10 +30964,10 @@ viesti useissa muodoissa boð í fleiri sniðum message en formats divers - teachtaireacht i roinnt fhormáidí + teachtaireacht i bhformáidí éagsúla mensaxe en varios formatos הודעה במספר תבניות - poruka u nekoliko oblika + Poruka u nekoliko oblika többféle formátumú üzenet Message in plure formatos pesan dalam beberapa format @@ -30043,7 +30986,7 @@ mensagem em vários formatos Mensagem em vários formatos mesaj în diferite formate - сообщение в нескольких форматах + Сообщение в нескольких форматах Správa v niekoľkých formátoch sporočilo v več zapisih Mesazh në formate të ndryshëm @@ -30052,7 +30995,7 @@ farklı biçimlerde ileti повідомлення у кількох форматах thông điệp có vài định dạng - 各种格式的消息 + 各种格式的信件 多種格式的訊息 @@ -30096,7 +31039,7 @@ ficheiro codificado em AppleDouble de Macintosh Arquivo do Macintosh codificado com AppleDouble Fișier codat Macintosh AppleDouble - файл (закодированный Macintosh AppleDouble) + Файл, закодированный Macintosh AppleDouble Súbor kódovaný pomocou Macintosh AppleDouble Kodirana datoteka Macintosh (AppleDouble) File Macintosh i kodifikuar AppleDouble @@ -30133,7 +31076,7 @@ Poruka kratkg sadržaja ömlesztett üzenet Digesto de messages - pesan digest + digest pesan Digest di messaggi メッセージダイジェスト мәлімдеме профилі @@ -30149,7 +31092,7 @@ grupo de mensagens Resumo de mensagem colecție mesaje email - профиль сообщения + Дайджест сообщения Prehľad správ povzetek sporočila Shpërndarje mesazhesh @@ -30158,7 +31101,7 @@ mesaj özeti збірка повідомлень bản tóm tắt thông điệp - 消息摘要 + 信件摘要 訊息摘要 @@ -30183,7 +31126,7 @@ teachtaireacht chriptithe mensaxe cifrado הודעה מוצפנת - šifrirana poruka + Šifrirana poruka titkosított üzenet Message cryptate pesan terenkripsi @@ -30202,7 +31145,7 @@ mensagem encriptada Mensagem criptografada mesaj criptat - зашифрованное сообщение + Зашифрованное сообщение Zašifrovaná správa šifrirano sporočilo Mesazh i kriptuar @@ -30217,6 +31160,7 @@ compound documents مستندات مركبة + documentos compuestos składanyja dakumenty Съставни документи documents compostos @@ -30253,7 +31197,7 @@ documentos compostos Documentos compostos documente compuse - составные документы + Составные документы Zložené dokumenty združeni dokumenti dokumente të përbërë @@ -30268,6 +31212,7 @@ compound document مستند مركب + documentu compuestu birləşik sənəd składany dakument Съставен документ @@ -30306,7 +31251,7 @@ documento composto Documento composto document compus - составной документ + Составной документ Zložený dokument združeni dokument dokumet i përbërë @@ -30337,7 +31282,7 @@ viestijärjestelmän ilmoitus postkervisfrásøgn rapport système de courriels - tuairisc chóras poist + tuairisc chórais r-phoist informe do sistema de correo דו״ח של מערכת הדואר Izvještaj sustava pošte @@ -30359,7 +31304,7 @@ relatório de sistema de email Relatório do sistema de correspondência raport sistem email - отчёт почтовой системы + Отчёт почтовой системы Správa poštového systému poročilo poštnega sistema Raport i sistemit të postës @@ -30393,7 +31338,7 @@ teachtaireacht sínithe mensaxe firmado הודעה חתומה - potpisana poruka + Potpisana poruka aláírt üzenet Message signate pesan ditandatangani @@ -30412,7 +31357,7 @@ mensagem assinada Mensagem assinada mesaj semnat - подписанное сообщение + Подписанное сообщение Podpísaná správa podpisano sporočilo Mesazh i firmosur @@ -30444,7 +31389,7 @@ sruth sonraí (brú freastalaí) fluxo de datos (por iniciativa do servidor) מידע בזרימה (דחיפה ע״י השרת) - Tok podataka (poslužiteljem pogurano) + Strujanje podataka (poslužiteljem pogurano) sugárzott adatfolyam (kiszolgálóról) Fluxo de datos (pulsate per servitor) arus data (dorongan server) @@ -30463,7 +31408,7 @@ fluxo de dados (empurrados pelo servidor) Fluxo de dados (por iniciativa do servidor) flux de date (de la server) - поток данных (server push) + Поток данных (server push) Prúd dát (posielaný serverom) pretok podatkov (strežniški) Fluks me të dhëna (server push) @@ -30472,7 +31417,7 @@ veri akışı (sunucudan gönderilen) потік даних (від сервера) luồng dữ liệu (trình phục vụ đẩy) - 数据流(服务器推送) + 数据流(服务器推送) 資料串流 (server push) @@ -30513,7 +31458,7 @@ calendário VCS/ICS Calendário VCS/ICS Calendar VCS/ICS - календарь VCS/ICS + Календарь VCS/ICS Kalendár VCS/ICS Datoteka koledarja VCS/ICS Kalendar VCS/ICS @@ -30575,7 +31520,7 @@ folha de estilos CSS Folha de estilo CSS Pagină de stil CSS - таблица стилей CSS + Таблица стилей CSS Štýly CSS Slogovna predloga CSS Fletë stili CSS @@ -30611,7 +31556,7 @@ cárta gnó leictreonach tarxeta de negocio electrónica כרטיס ביקור אלקטרוני - elektronička posjetnica + Elektronička posjetnica elektronikus névjegykártya Carta de visita electronic kartu bisnis elektronik @@ -30628,7 +31573,7 @@ cartão de visita eletrónico Cartão de visitas eletrônico carte de vizită electronică - электронная визитная карточка + Электронная визитная карточка Elektronická vizitka elektronska poslovna vizitka Skedë elektronike biznesi @@ -30653,6 +31598,7 @@ Turtle document + Documentu Turtle document Turtle dokument Turtle Turtle-dokument @@ -30663,6 +31609,7 @@ Turtle dokumentua Turtle-asiakirja document Turtle + cáipéis Turtle מסמך Turtle Turtle dokument Turtle dokumentum @@ -30675,7 +31622,7 @@ Dokument Turtle documento Turtle Documento Turtle - документ Turtle + Документ Turtle Dokument Turtle Тартл документ Turtle-dokument @@ -30689,6 +31636,7 @@ txt2tags document مستند txt2tags + Documentu txt2tags dakument txt2tags Документ — txt2tags document txt2tags @@ -30709,7 +31657,7 @@ txt2tags dokument txt2tags dokumentum Documento txt2tags - dokumen txt2tags + Dokumen txt2tags Documento txt2tags txt2tags ドキュメント txt2tags დოკუმენტი @@ -30725,7 +31673,7 @@ documento txt2tags Documento do txt2tags document txt2tags - документ txt2tags + Документ txt2tags Dokument txt2tags Dokument txt2tags Dokument txt2tags @@ -30747,7 +31695,7 @@ Verilog source code Изходен код — Verilog codi font en Verilog - zdrojový kód Verilog + zdrojový kód v jazyce Verilog Verilog-kildekode Verilog-Quelltext Πηγαίος κώδικας Verilog @@ -30757,9 +31705,10 @@ Verilog iturburu-kodea Verilog-lähdekoodi code source Verilog + cód foinseach Verilog código fonte en Verilog קוד מקור של - Verilog izvorni kod + Verilog izvorni kôd Verilog-forráskód Codice-fonte Verilog Kode sumber Verilog @@ -30773,7 +31722,7 @@ Kod źródłowy Verilog código origem Verilog Código-fonte Verilog - исходный код Verilog + Исходный код Verilog Zdrojový kód Verilog Datoteka izvorne kode Verilog изворни код Верилога @@ -30798,6 +31747,7 @@ SystemVerilog goiburua SystemVerilog-otsake en-tête + ceanntásc SystemVerilog Cabeceiras de SystemVerilog כותרת SystemVerilog SystemVerilog zaglavlje @@ -30814,14 +31764,14 @@ Nagłówek SystemVerilog cabeçalho SystemVerilog Cabeçalho de SystemVerilog - заголовочный файл SystemVerilog + Заголовочный файл SystemVerilog Hlavičky SystemVerilog Datoteka glave SystemVerilog заглавље Система Верилога SystemVerilog-headerfil SystemVerilog başlığı заголовки SystemVerilog - SystemVerilog 头 + SystemVerilog 头文件 SystemVerilog 標頭 @@ -30839,9 +31789,10 @@ SystemVerilog iturburu-kodea SystemVerilog-lähdekoodi code source + cód foinseach SystemVerilog código fonte en SystemVerilog קוד מקור של SystemVerilog - SystemVerilog izvorni kod + SystemVerilog izvorni kôd SystemVerilog-forráskód Codice-fonte SystemVerilog Kode sumber SystemVerilog @@ -30855,7 +31806,7 @@ Kod źródłowy SystemVerilog código origem SystemVerilog Código-fonte de SystemVerilog - исходный код SystemVerilog + Исходный код SystemVerilog Zdrojový kód SystemVerilog Datoteka izvorne kode SystemVerilog изворни код Система Верилога @@ -30871,7 +31822,7 @@ VHDL source code Изходен код — VHDL codi font en VHDL - zdrojový kód VHDL + zdrojový kód v jazyce VHDL VHDL-kildekode VHDL-Quelltext Πηγαίος κώδικας VHDL @@ -30881,9 +31832,10 @@ VHDL iturburu-kodea VHDL-lähdekoodi code source VHDL + cód foinseach VHDL código fonte en VHDL קוד מקור של VHDL - VHDL izvorni kod + VHDL izvorni kôd VHDL-forráskód Codice-fonte VHDL Kode sumber VHDL @@ -30897,7 +31849,7 @@ Kod źródłowy VHDL código origem VHDL Código-fonte VHDL - исходный код VHDL + Исходный код VHDL Zdrojový kód VHDL Datoteka izvorne kode VHDL ВХДЛ изворни код @@ -30915,6 +31867,7 @@ enriched text document مستند نصي مغنى + documentu de testu arriquecíu zəngin mətn sənədi azdobleny tekstavy dakument Документ с обогатен текст @@ -30934,7 +31887,7 @@ cáipéis téacs saibhrithe documento de texto enriquecido מסמך טקסט מועשר - obogaćeni tekstualni dokument + Obogaćeni tekstovni dokument enriched text dokumentum Documento de texto inricchite dokumen teks diperkaya @@ -30953,7 +31906,7 @@ documento de texto rico Documento de texto enriquecido document text îmbogățit - форматированный текстовый документ + Форматированный текстовый документ Rozšírený textový dokument dokument z obogatenim besedilom Dokument teksti i pasuruar @@ -30962,7 +31915,7 @@ zenginleştirilmiş metin belgesi форматований текстовий документ tài liệu văn bản có kiểu dáng - 富文本文档 + 浓缩文本文档 (ETF) 豐富化文字文件 @@ -30988,7 +31941,7 @@ leathanach cabhrach páxina de axuda דף עזרה - stranica pomoći + Stranica pomoći súgóoldal Pagina de adjuta halaman bantuan @@ -31007,7 +31960,7 @@ página de ajuda Página de ajuda pagină de ajutor - страница справки + Страница справки Stránka Pomocníka stran pomoči Faqe ndihme @@ -31023,6 +31976,7 @@ plain text document مستند نصي مجرد + documentu de testu planu prosty tekstavy dakument Документ с неформатиран текст document de text pla @@ -31039,10 +31993,10 @@ cáipéis ghnáth-théacs documento de texto sinxelo מסמך טקסט פשוט - običan tekstualni dokument + Običan tekstovni dokument egyszerű szöveg Documento de texto simple - dokumen teks biasa + dokumen teks polos Documento in testo semplice 平文テキストドキュメント мәтіндік құжаты @@ -31058,7 +32012,7 @@ documento em texto simples Documento de Texto document text simplu - текстовый документ + Текстовый документ Obyčajný textový dokument običajna besedilna datoteka Dokument në tekst të thjeshtë @@ -31115,7 +32069,7 @@ ficheiro RDF Arquivo RDF Fișier RDF - файл RDF + Файл RDF Súbor RDF Datoteka RDF File RDF @@ -31146,6 +32100,7 @@ archivo en XML OWL OWL XML fitxategia fichier XML OWL + comhad XML OWL OWL XML datoteka OWL XML-fájl File XML OWL @@ -31157,7 +32112,7 @@ Plik XML OWL ficheiro OWL XML Arquivo OWL XML - файл XML OWL + Файл XML OWL Súbor XML OWL ОВЛ ИксМЛ датотека OWL XML-fil @@ -31196,14 +32151,14 @@ ceanntásca ríomhphoist cabeceiras de correo electrónico כותרת דוא״ל - zaglavlja e-pošte + Zaglavlja e-pošte levélfejléc Capites de e-mail - tajuk email + header email Intestazioni email メールヘッダー пошталық тақырыптамалары - 전자 우편 헤더 + 전자메일 헤더 el. laiško antraštės e-pasta galvene Pengepala emel @@ -31215,7 +32170,7 @@ cabeçalhos de email Cabeçalhos de e-mail antete email - почтовые заголовки + Почтовые заголовки Hlavičky e-mailu glava elektronske pošte Header email @@ -31231,6 +32186,7 @@ rich text document مستند نصي غني + documentu de testu ricu zəngin mətn sənədi azdobleny tekstavy dakument Документ — rich text @@ -31249,7 +32205,7 @@ cáipéis mhéith-théacs documento do texto enriquecido מסמך טקסט עשיר - obogaćeni tekstualni dokument + Obogaćeni tekstovni dokument rich text-dokumentum Documento de texto inricchite dokumen teks kaya @@ -31268,7 +32224,7 @@ documento em texto rico Documento rich text document text îmbogățit - документ с форматированным текстом + Документ с форматированным текстом Textový dokument RTF dokument z oblikovanim besedilom Dokument rich text @@ -31277,7 +32233,7 @@ zengin metin belgesi форматований текстовий документ tài liệu văn bản có kiểu dáng (RTF) - RTF 丰富文本文档 + 富文本文档 (RTF) 豐富文字文件 @@ -31319,7 +32275,7 @@ resumo RSS Resumo RSS Rezumat RSS - сводка RSS + Сводка RSS Súhrn RSS Datoteka povzetek RSS Përmbledhje RSS @@ -31366,7 +32322,7 @@ Feed di distribuzione Atom Atom 配信フィード Atom жаңалықтар таспасы - Atom 동기화 피드 + Atom 묶음 피드 Atom sindikacijos kanalas Atom sindikāta barotne Atom syndikeringsstrøm @@ -31377,7 +32333,7 @@ feed Atom Fonte de notícias Atom Flux agregare Atom - лента новостей Atom + Лента новостей Atom Kanál Atom Sindikalni vir Atom Feed për përhapje Atom @@ -31386,7 +32342,7 @@ Atom besleme kaynağı трансляція подач Atom Nguồn tin tức Atom - Atom 更新种子 + Atom 聚合种子 Atom 聯合供稿饋流 @@ -31432,7 +32388,7 @@ feed OPML Fonte de notícias OPML Flux OPML syndication - лента новостей OPML + Лента новостей OPML Kanál OPML Sindikalni vir OPML Feed për përhapje OPML @@ -31454,6 +32410,7 @@ SGML document مستند SGML + Documentu SGML Dakument SGML Документ — SGML document SGML @@ -31491,7 +32448,7 @@ documento SGML Documento SGML Document SGML - документ SGML + Документ SGML Dokument SGML Dokument SGML Dokument SGML @@ -31511,6 +32468,7 @@ spreadsheet interchange document مستند تبادل الجدول + documentu d'intercambéu de fueyes de cálculu dakument dla abmienu raźlikovymi arkušami Документ за обмяна между програми за електронни таблици document d'intercanvi de full de càlcul @@ -31545,7 +32503,7 @@ documento de troca interna de folhas de cálculo Documento de intercâmbio de planilhas document schimb filă de calcul - документ Spreadsheet Interchange + Документ Spreadsheet Interchange Zošitový prenosový dokument dokument izmenjeve preglednic Dokument shkëmbimi për fletë llogaritje @@ -31566,6 +32524,7 @@ TSV document مستند TSV + Documentu TSV Dakument TSV Документ — TSV document TSV @@ -31600,7 +32559,7 @@ documento TSV Documento TSV Document TSV - документ TSV + Документ TSV Dokument TSV Dokument TSV Dokument TSV @@ -31658,7 +32617,7 @@ Graphviz DOT grafiği граф DOT Graphviz Biểu đồ DOT Graphviz - Graphviz DOT 科学图形 + Graphviz DOT 图形 Graphviz DOT 圖 @@ -31673,6 +32632,7 @@ JAD document مستند JAD + Documentu JAD Dakument JAD Документ — JAD document JAD @@ -31708,7 +32668,7 @@ documento JAD Documento JAD Document JAD - документ JAD + Документ JAD Dokument JAD Dokument JAD Dokument JAD @@ -31729,6 +32689,7 @@ WML document مستند WML + Documentu WML WML sənədi Dakument WML Документ — WML @@ -31767,7 +32728,7 @@ documento WML Documento WML Document WML - документ WML + Документ WML Dokument WML Dokument WML Dokument WML @@ -31820,7 +32781,7 @@ programa WMLScript Programa WMLScript Program WMLScript - сценарий WMLScript + Программа WMLScript Program WMLScript Programska datoteka WMLScript Program WMLScript @@ -31872,7 +32833,7 @@ arquivo ACE Pacote ACE Arhivă ACE - архив ACE + Архив ACE Archív ACE Datoteka arhiva ACE Arkiv ACE @@ -31909,10 +32870,10 @@ cód foinseach Ada código fonte en Ada קוד מקור Ada - Ada izvorni kod + Ada izvorni kôd Ada-forráskód Codice-fonte Ada - Kode program Ada + Kode sumber Ada Codice sorgente Ada Ada ソースコード Ada-ის საწყისი კოდი @@ -31929,7 +32890,7 @@ código origem Ada Código-fonte Ada Cod sursă Ada - исходный код Ada + Исходный код Ada Zdrojový kód jazyka Ada Datoteka izvorne kode Ada Kod burues Ada @@ -31983,7 +32944,7 @@ lista de autores Lista de autores listă autori - список авторов + Список авторов Zoznam autorov seznam avtorjev Lista e autorëve @@ -32000,6 +32961,7 @@ BibTeX document مستند BibTeX + Documentu de BibTeX Dakument BibTeX Документ — BibTeX document BibTeX @@ -32036,7 +32998,7 @@ documento BibTeX Documento BibTeX Document BibTeX - документ BibTeX + Документ BibTeX Dokument BibTeX Dokument BibTeX Dokument BibTeX @@ -32075,7 +33037,7 @@ C++ zaglavlje C++ fejléc Capite C++ - Tajuk C++ + Header C++ Header C++ C++ ヘッダー C++-ის თავსართი @@ -32091,7 +33053,7 @@ cabeçalho C++ Cabeçalho C++ Antet C++ - заголовочный файл C++ + Заголовочный файл C++ Hlavičky jazyka C++ Datoteka glave C++ Header C++ @@ -32100,7 +33062,7 @@ C++ başlığı файл заголовків мовою C++ Phần đầu mã nguồn C++ - C++ 源代码头文件 + C++ 头文件 C++ 標頭檔 @@ -32115,7 +33077,7 @@ Kryničny kod C++ Изходен код — C++ codi font en C++ - zdrojový kód C++ + zdrojový kód v jazyce C++ C++-kildekode C++-Quelltext Πηγαίος κώδικας C++ @@ -32129,10 +33091,10 @@ cód foinseach C++ código fonte de C++ קוד מקור של C++‎ - C++ izvorni kod + C++ izvorni kôd C++-forráskód Codice-fonte C++ - Kode program C++ + Kode sumber C++ Codice sorgente C++ C++ ソースコード C++-ის საწყისი კოდი @@ -32149,7 +33111,7 @@ código origem C++ Código-fonte C++ Cod sursă C++ - исходный код C++ + Исходный код C++ Zdrojový kód jazyka C++ Datoteka izvorne kode C++ Kod burues C++ @@ -32170,6 +33132,7 @@ ChangeLog document مستند ChangeLog + Documentu de rexistru de cambeos Dakument zafiksavanych źmienaŭ ChangeLog Дневник за промени — ChangeLog document de registre de canvis @@ -32186,7 +33149,7 @@ cáipéis ChangeLog documento Changelog מסמך של ChangeLog - Dokument zaspisa promjena + Dokument zapisa promjena ChangeLog dokumentum Lista de cambiamentos Dokumen ChangeLog @@ -32205,11 +33168,11 @@ documento ChangeLog Documento ChangeLog Document ChangeLog - протокол изменений + Протокол изменений Dokument ChangeLog Dokument ChangeLog Dokument ChangeLog - Ченџ Лог документ + документ дневника измена Ändringsloggsdokument Değişim Günlüğü belgesi документ ChangeLog @@ -32241,7 +33204,7 @@ C zaglavlje C fejléc Capite C - Tajuk C + Header C Header C C ヘッダー C-ის თავსართი @@ -32257,7 +33220,7 @@ cabeçalho C Cabeçalho C Antet C - заголовочный файл C + Заголовочный файл C Hlavičky jazyka C Datoteka glave C Header C @@ -32291,10 +33254,10 @@ cód foinseach CMake código fonte de CMake קוד מקור של CMake - CMake izvorni kod + CMake izvorni kôd CMake-forráskód Codice-fonte CMake - Kode program CMake + Kode sumber CMake Codice sorgente CMake CMake ソースコード CMake-ის საწყისი კოდი @@ -32310,7 +33273,7 @@ código origem CMake Código-fonte CMake Cod sursă CMake - исходный код CMake + Исходный код CMake Zdrojový kód CMake Datoteka izvorne kode CMake Kod burues CMake @@ -32328,6 +33291,7 @@ CSV document مستند CSV + Documentu CVS Dakument CSV Документ — CSV document CSV @@ -32364,7 +33328,7 @@ documento CSV Documento CSV Document CSV - документ CSV + Документ CSV Dokument CSV Dokument CSV Dokument CSV @@ -32384,6 +33348,7 @@ CSV Schema document + Documentu d'esquema CSV document Schema de CSV dokument schématu CSV CSV Schema-dokument @@ -32392,6 +33357,8 @@ documento esquemático CSV CSV Schema dokumentua document schéma CSV + cáipéis scéimre CSV + מסמך פריסת CSV CSV Shema dokument CSV sémadokumentum Documento CSV Schema @@ -32402,7 +33369,7 @@ Dokument schematu CSV documento CSV Schema Documento CSV Schema - документ CSV Schema + Документ CSV Schema Dokument schémy CSV документ ЦСВ шеме CSV Schema-dokument @@ -32418,6 +33385,7 @@ license terms شروط الترخيص + términos de llicencia licenzijnyja ŭmovy Лицензни условия condicions de llicència @@ -32434,7 +33402,7 @@ téarmaí ceadúnais termos de licenza תנאי רישיון - uvjeti licence + Uvjeti licence licencfeltételek Conditiones de licentia persyaratan lisensi @@ -32452,7 +33420,7 @@ termos de licença Termos de licença termeni de licență - лицензионное соглашение + Лицензионное соглашение Licenčné podmienky pogoji in dovoljenja uporabe Kushte liçence @@ -32469,6 +33437,7 @@ author credits شكر وتقدير المؤلف + creitos del autor zasłuhi aŭtara Благодарности към авторите atribucions d'autor @@ -32502,7 +33471,7 @@ créditos de autor Créditos do autor mulțumiri autori - авторы программы + Авторы программы Autorské zásluhy avtorske zasluge Kreditë e autorëve @@ -32522,7 +33491,7 @@ Kryničny kod C Изходен код — C codi font en C - zdrojový kód C + zdrojový kód v jazyce C C-kildekode C-Quelltext Πηγαίος κώδικας C @@ -32536,10 +33505,10 @@ cód foinseach C código fonte en C קוד מקור של C - C izvorni kod + C izvorni kôd C-forráskód Codice-fonte C - Kode program C + Kode sumber C Codice sorgente C C ソースコード C-ის საწყისი კოდი @@ -32556,7 +33525,7 @@ código origem C Código-fonte C Cod sursă C - исходный код C + Исходный код C Zdrojový kód jazyka C Datoteka izvorne kode C Kod burues C @@ -32582,7 +33551,7 @@ Kryničny kod C# Изходен код — C# codi font en C# - zdrojový kód C# + zdrojový kód v jazyce C# C#-kildekode C#-Quelltext Πηγαίος κώδικας C# @@ -32596,10 +33565,10 @@ cód foinseach C# código fonte en C# קוד מקור של C#‎ - C# izvorni kod + C# izvorni kôd C#-forráskód Codice-fonte C# - Kode program C# + Kode sumber C# Codice sorgente C# C# ソースコード C#-ის საწყისი კოდი @@ -32616,7 +33585,7 @@ código origem C# Código-fonte C# Cod sursă C# - исходный код C# + Исходный код C# Zdrojový kód jazyka C# Datoteka izvorne kode C# Kod burues C# @@ -32636,7 +33605,7 @@ Kryničny kod Vala Изходен код — Vala codi font en Vala - zdrojový kód Vala + zdrojový kód v jazyce Vala Valakildekode Vala-Quelltext Πηγαίος κώδικας Vala @@ -32650,10 +33619,10 @@ cód foinseach Vala código fonte en Vala קוד מקור של Vala - Vala izvorni kod + Vala izvorni kôd Vala forráskód Codice-fonte Vala - Kode program Vala + Kode sumber Vala Codice sorgente Vala Vala ソースコード Vala бастапқы коды @@ -32668,7 +33637,7 @@ código origem Vala Código-fonte Vala Cod sursă Vala - исходный код Vala + Исходный код Vala Zdrojový kód Vala Datoteka izvorne kode Vala Kod burues Vala @@ -32697,9 +33666,10 @@ OOC iturburu-kodea OOC-lähdekoodi source code OOC + cód foinseach OOC código fonte de OOC קוד מקור של OOC - OOC izvorni kod + OOC izvorni kôd OOC forráskód Codice-fonte OCC Kode sumber OOC @@ -32714,14 +33684,14 @@ Kod źródłowy OOC código origem OOC Código-fonte OOC - исходный код OOC + Исходный код OOC Zdrojový kód OOC Izvorna koda OOC ООЦ изворни ко̂д OOC-källkod OOC kaynak kodu вихідний код мовою OOC - OOC + OOC 源代码 OOC 源碼 OOC Out Of Class @@ -32770,7 +33740,7 @@ script DCL Script DCL Script DCL - сценарий DCL + Сценарий DCL Skript DCL Skriptna datoteka DCL Script DCL @@ -32789,6 +33759,7 @@ DSSSL document مستند DSSSL + Documentu DSSSL DSSSL sənədi Dakument DSSSL Документ — DSSSL @@ -32828,7 +33799,7 @@ documento DSSSL Documento DSSSL Document DSSSL - документ DSSSL + Документ DSSSL Dokument DSSSL Dokument DSSSL Dokument DSSSL @@ -32850,7 +33821,7 @@ Kryničny kod D Изходен код — D codi font en D - zdrojový kód D + zdrojový kód v jazyce D D-kildekode D-Quelltext Πηγαίος κώδικας D @@ -32864,10 +33835,10 @@ cód foinseach D código fonte de D קוד מקור לשפת D - D izvorni kod + D izvorni kôd D-forráskód Codice-fonte D - Kode program D + Kode sumber D Codice sorgente D D ソースコード D-ის საწყისი კოდი @@ -32883,7 +33854,7 @@ código origem D Código-fonte D Cod sursă D - исходный код D + Исходный код D Zdrojový kód jazyka D Datoteka izvorne kode D Kod burues D @@ -32937,7 +33908,7 @@ ficheiro DTD Arquivo DTD Fișier DTD - файл DTD + Файл DTD Súbor DTD Datoteka DTD File DTD @@ -32961,7 +33932,7 @@ Kryničny kod Eiffel Изходен код — Eiffel codi font en Eiffel - zdrojový kód Eiffel + zdrojový kód v jazyce Eiffel Eiffelkildekode Eiffel-Quelltext Πηγαίος κώδικας Eiffel @@ -32975,10 +33946,10 @@ cód foinseach Eiffel código fone de Eiffel קוד מקור של Eiffel - Eiffel izvorni kod + Eiffel izvorni kôd Eiffel forráskód Codice-fonte Eiffel - Kode program Eiffel + Kode sumber Eiffel Codice sorgente Eiffel Eiffel ソースコード Eiffel-ის საწყისი კოდი @@ -32994,7 +33965,7 @@ código origem Eiffel Código-fonte Eiffel Cod sursă Eiffel - исходный код Eiffel + Исходный код Eiffel Zdrojový kód Eiffel Datoteka izvorne kode Eiffel Kod burues Eiffel @@ -33031,7 +34002,7 @@ cód foinseach Emacs Lisp código fonte de Emacs Lisp קוד מקור של Emcas Lisp - Emacs Lisp izvorni kod + Emacs Lisp izvorni kôd Emacs Lisp-forráskód Codice-fonte Lisp de Emacs Kode sumber Emacs Lisp @@ -33051,7 +34022,7 @@ código origem Emacs Lisp Código-fonte Lisp do Emacs Cod sursă Emacs Lisp - исходный код Emacs Lisp + Исходный код Emacs Lisp Zdrojový kód Emacs Lisp Datoteka izvorne kode Emacs Lisp Kod burues Emacs Lisp @@ -33075,7 +34046,7 @@ Kryničny kod Erlang Изходен код — Erlang codi font en Erlang - zdrojový kód Erlang + zdrojový kód v jazyce Erlang Erlangkildekode Erlang-Quelltext Πηγαίος κώδικας Erlang @@ -33089,10 +34060,10 @@ cód foinseach Erlang código fonte de Erlang קוד מקור של Erlang - Erlang izvorni kod + Erlang izvorni kôd Erlang forráskód Codice-fonte Erlang - Kode program Erlang + Kode sumber Erlang Codice sorgente Erlang Erlang ソースコード Erlang-ის საწყისი კოდი @@ -33108,7 +34079,7 @@ código origem Erlang Código-fonte Erlang Cod sursă Erlang - исходный код Erlang + Исходный код Erlang Zdrojový kód Erlang Datoteka izvorne kode Erlang Kod burues Erlang @@ -33129,7 +34100,7 @@ Kryničny kod Fortran Изходен код — Fortran codi font en Fortran - zdrojový kód Fortran + zdrojový kód v jazyce Fortran Ffynhonnell rhaglen FORTRAN Fortrankildekode Fortran-Quelltext @@ -33144,10 +34115,10 @@ cód foinseach Fortran código fonte de Fortran קוד מקור של Fortran - Fortran izvorni kod + Fortran izvorni kôd Fortran-forráskód Codice-fonte Fortran - Kode program Fortran + Kode sumber Fortran Codice sorgente Fortran Fortran ソースコード Fortran-ის საწყისი კოდი @@ -33164,7 +34135,7 @@ código origem Fortran Código-fonte Fortran Cod sursă Fortran - исходный код Fortran + Исходный код Fortran Zdrojový kód Fortran Datoteka izvorne kode Fortran Kod burues Fortran @@ -33193,10 +34164,12 @@ Genie iturburu-kodea Genie-lähdekoodi code source Genie + cód foinseach Genie + קוד מקור של Genie Genie izvorni kôd Genie forráskód Codice-fonte Genie - Kode program Genie + Kode sumber Genie Codice sorgente Genie Genie бастапқы коды Genie 소스 코드 @@ -33204,7 +34177,7 @@ Kod źródłowy Genie código origem Genie Código-fonte Genie - исходный код Genie + Исходный код Genie Zdrojový kód Genie Izvorna koda Genie Гение изворни ко̂д @@ -33220,6 +34193,7 @@ translation file ملف الترجمة + ficheru de traducción fajł pierakładu Превод fitxer de traducció @@ -33234,10 +34208,10 @@ käännöstiedosto týðingarfíla fichier de traduction - comhad aistrithe + comhad aistriúcháin ficheiro de tradución קובץ תרגום - datoteka prijevoda + Datoteka prijevoda fordítási fájl File de traduction berkas terjemahan @@ -33256,7 +34230,7 @@ ficheiro de tradução Arquivo de tradução fișier traducere - файл переводов + Файл переводов Súbor prekladu datoteka prevoda programa File përkthimesh @@ -33265,7 +34239,7 @@ çeviri dosyası файл перекладу tập tin dịch - 消息翻译文件 + 翻译文件 翻譯檔 @@ -33275,6 +34249,7 @@ translation template قالب الترجمة + plantía de traducción šablon dla pierakładu Шаблон за преводи plantilla de traducció @@ -33289,10 +34264,10 @@ käännösmalli týðingarformur modèle de traduction - teimpléad aistrithe + teimpléad aistriúcháin plantilla de tradución תבנית תרגום - predložak prijevoda + Predložak prijevoda fordítási sablon Patrono de traduction templat terjemahan @@ -33311,7 +34286,7 @@ modelo de tradução Modelo de tradução șablon de traducere - шаблон переводов + Шаблон переводов Šablóna prekladu predloga datoteke prevoda programa Model përkthimesh @@ -33320,7 +34295,7 @@ çeviri şablonu шаблон перекладу mẫu dịch - 消息翻译模板 + 翻译模板 翻譯模版 @@ -33332,18 +34307,27 @@ feature specification in Gherkin format especificació de funcionalitat en format Gherkin + specifikace vlastností ve formátu Gherkin funktionspecifikation i Gherkin-format Funktionsspezifikation im Gherkin-Format + feature specification in Gherkin format especificación de funcionalidad en formato Gherkin spécification fonctionnelle au format Gherkin + sonraíocht gnéithe i bhformáid Gherkin פירוט תכונות בתבנית Gherkin + opis značajke u Gherkin formatu funkcióleírás Gherkin formátumban + spesifikasi fitur dalam format Gherkin + Specifica di funzionalità in formato Gherkin Gherkin пішіміндегі функционалды анықтамалар Gherkin 형식의 기능 명세 Specyfikacja funkcji w formacie Gherkin Especificação de recurso no formato Gherkin - функциональные определения в формате Gherkin + Функциональные определения в формате Gherkin Špecifikácia funkcie vo formáte Gherkin + одредба функције у запису Геркина + egenskapsspecifikation i Gherkin-format + Gherkin biçiminde özellik belirtimi специфікація можливості у форматі Gherkin Gherkin 格式中的功能规范 Gherkin 格式的特徵規格 @@ -33353,6 +34337,7 @@ HTML document مستند HTML + Documentu HTML Dakument HTML Документ — HTML document HTML @@ -33388,7 +34373,7 @@ documento HTML Documento HTML Document HTML - документ HTML + Документ HTML Dokument HTML Dokument HTML Dokument HTML @@ -33434,7 +34419,7 @@ Webanwendungscache-Manifest Δηλωτικό λανθάνουσας μνήμης εφαρμογής Ιστού Web application cache manifest - manifiesto de caché de aplicación web + manifiesto de antememoria de aplicación web Web aplikazioaren cache-aren agiria Net nýtsluskipanarkova manifest manifeste de cache d'application Web @@ -33457,7 +34442,7 @@ manifesto de cache de aplicação web Manifest de cache de aplicação web Manifest de cache pentru aplicații web - манифест кэша веб-приложения + Манифест кэша веб-приложения Manifest vyrovnávacej pamäte webovej aplikácie Predpomnilnik spletnega programa проглас оставе Веб програма @@ -33480,6 +34465,7 @@ Google Video Pointer مؤشر فيديو جوجل + Google Video Pointer Pakazalnik Google Video Документ-указател към видео на Google apuntador a vídeo de Google @@ -33539,7 +34525,7 @@ Kryničny kod Haskell Изходен код на Haskell codi font en Haskell - zdrojový kód Haskell + zdrojový kód v jazyce Haskell Ffynhonnell rhaglen Haskell Haskellkildekode Haskell-Quelltext @@ -33554,10 +34540,10 @@ cód foinseach Haskell código fonte de Haskell קוד מקור של Haskell - Haskell izvorni kod + Haskell izvorni kôd Haskell-forráskód Codice-fonte Haskell - Kode program Haskell + Kode sumber Haskell Codice sorgente Haskell Haskell ソースコード Haskell бастапқы коды @@ -33573,7 +34559,7 @@ código origem Haskell Código-fonte Haskell Cod sursă Haskell - исходный код Haskell + Исходный код Haskell Zdrojový kód Haskell Datoteka izvorne kode Haskell Kod burues Haskell @@ -33590,6 +34576,7 @@ IDL document مستند IDL + Documentu IDL IDL sənədi Dakument IDL Документ — IDL @@ -33628,7 +34615,7 @@ documento IDL Documento IDL Document IDL - документ IDL + Документ IDL Dokument IDL Dokument IDL Dokument IDL @@ -33647,6 +34634,7 @@ installation instructions تعليمات التثبيت + instrucciones d'instalación instrukcyja dla instalavańnia Инструкции за инсталация instruccions d'instal·lació @@ -33663,7 +34651,7 @@ treoracha suiteála instrucións de instalación הוראות התקנה - upute za instalaciju + Upute za instalaciju telepítési utasítások Instructiones de installation instruksi instalasi @@ -33681,7 +34669,7 @@ instruções de instalação Instruções de instalação instrucțiuni de instalare - инструкции по установке программы + Инструкции по установке Návod na inštaláciu navodila namestitve Udhëzime instalimi @@ -33701,7 +34689,7 @@ Kryničny kod Java Изходен код на Java codi font en Java - zdrojový kód Java + zdrojový kód v jazyce Java Javakildekode Java-Quelltext Πηγαίος κώδικας Java @@ -33715,10 +34703,10 @@ cód foinseach Java código fonte de Java קוד מקור ב־Java - Java izvorni kod + Java izvorni kôd Java-forráskód Codice-fonte Java - Kode program Java + Kode sumber Java Codice sorgente Java Java ソースコード Java бастапқы коды @@ -33734,7 +34722,7 @@ código origem Java Código-fonte Java Cod sursă Java - исходный код Java + Исходный код Java Zdrojový kód Java Datoteka izvorne kode Java Kod burues Java @@ -33765,7 +34753,7 @@ LDIF-osoitekirja LDIF adressubók carnet d'adresses LDIF - leabhar sheoltaí LDIF + leabhar seoltaí LDIF lista de enderezos LDIF ספר כתובות של LDIF LDIF adresar @@ -33786,7 +34774,7 @@ livro de endereços LDIF Livro de endereços LDIF Agendă LDIF - адресная книга LDIF + Адресная книга LDIF Adresár LDIF Datoteka imenika naslovov LDIF Rubrikë LDIF @@ -33842,7 +34830,7 @@ folha de música Lilypond Partitura do Lilypond Fișă muzică Lilypond - список музыки Lilypond + Список музыки Lilypond Notový papier Lilypond Glasbena predloga Lilypond Partiturë Lilypond @@ -33876,10 +34864,10 @@ cód foinseach LHS código fonte en LHS קוד מקור של LHS - LHS izvorni kod + LHS izvorni kôd LHS forráskód Codice-fonte LHS - Kode program LHS + Kode sumber LHS Codice sorgente LHS LHS ソースコード LHS бастапқы коды @@ -33894,7 +34882,7 @@ código origem LHS Código-fonte LHS Cod sursă LHS - исходный код LHS + Исходный код LHS Zdrojový kód LHS Datoteka izvorne kode LHS Kod burues LHS @@ -33913,6 +34901,7 @@ application log سجل التطبيق + rexistru d'aplicación časopis aplikacyi Файл-дневник на приложение registre d'aplicació @@ -33949,7 +34938,7 @@ diário de aplicação Registro de aplicativo înregistrare aplicație - журнал сообщений + Журнал сообщений Záznam aplikácie dnevnik programa log i mesazheve të programit @@ -34005,7 +34994,7 @@ Makefile Makefile (arquivo do make) Makefile - Makefile (файл сборки) + Файл Makefile Makefile Datoteka Makefile Makefile @@ -34029,6 +35018,7 @@ Markdown document + Documentu Markdown Документ — Markdown document Markdown dokument Markdown @@ -34040,6 +35030,7 @@ Markdown dokumentua Markdown-asiakirja document Markdown + cáipéis Markdown documento de Markdown מסמך Markdown Markdown dokument @@ -34056,7 +35047,7 @@ Dokument Markdown documento Markdown Documento Markdown - документ Markdown + Документ Markdown Dokument Markdown Dokument Markdown Маркдаун документ @@ -34108,7 +35099,7 @@ ficheiro Qt MOC Arquivo Qt MOC Fișier Qt MOC - файл Qt MOC + Файл Qt MOC Súbor Qt MOC Datoteka Qt MOC File Qt MOC @@ -34117,7 +35108,7 @@ Qt MOC dosyası файл-метаоб'єкт Qt Tập tin MOC của Qt - Qt 元对象编译文件 + Qt 元对象编译器文件 Qt MOC 檔 Qt MOC Qt Meta Object Compiler @@ -34161,7 +35152,7 @@ extrato do registo do Windows Extrator de registro do Windows Extras al registrului Windows - фрагмент Windows Registry + Фрагмент Windows Registry Časť registrov Windows izvleček vpisnika Windows Pjesë Windows Registry @@ -34170,7 +35161,7 @@ Windows Kayıt Defteri özü частина реєстру Windows Bản trích Registry Windows - Windows 注册表文件 + Windows 注册表提取 Windows Registry 抽出 @@ -34216,7 +35207,7 @@ formato Managed Object Formato de objeto gerenciado Managed Object Format - формат управляемого объекта + Формат управляемого объекта Formát Managed Object Datoteka Managed Object Managed Object Format @@ -34267,7 +35258,7 @@ publicação Mup Publicação do Mup Publicație Mup - публикация Mup + Публикация Mup Publikácie Mup Datoteka objave Mup Publikim Mup @@ -34291,7 +35282,7 @@ Kryničny kod Objective-C Изходен код — Objective C codi font en Objective-C - zdrojový kód Objective-C + zdrojový kód v jazyce Objective-C Objektiv C-kildekode Objective-C-Quelltext Πηγαίος κώδικας Objective-C @@ -34308,7 +35299,7 @@ Objective-C izvorni kôd Objective-C forráskód Codice-fonte Objective-C - Kode program Objective-C + Kode sumber Objective-C Codice sorgente Objective-C Objective-C ソースコード Objective-C-ის საწყისი კოდი @@ -34325,7 +35316,7 @@ código origem Objective-C Código-fonte Objective-C Cod sursă Objective-C - исходный код Objective-C + Исходный код Objective-C Zdrojový kód Objective-C Datoteka izvorne kode Objective-C Kod burues C objekt @@ -34348,7 +35339,7 @@ Kryničny kod OCaml Изходен код — OCaml codi font en OCaml - zdrojový kód OCaml + zdrojový kód v jazyce OCaml OCaml-kildekode OCaml-Quelltext Πηγαίος κώδικας OCaml @@ -34362,10 +35353,10 @@ cód foinseach OCaml código fonte de OCaml קוד מקור של OCaml - OCaml izvorni kod + OCaml izvorni kôd OCaml forráskód Codice-fonte OCaml - Kode program OCaml + Kode sumber OCaml Codice sorgente OCaml OCaml ソースコード OCaml бастапқы коды @@ -34380,7 +35371,7 @@ código origem OCaml Código-fonte OCaml Cod sursă OCaml - исходный код OCaml + Исходный код OCaml Zdrojový kód OCaml Datoteka izvorne kode OCaml Kod burues OCaml @@ -34394,6 +35385,33 @@ + + OpenCL source code + codi font en OpenCL + zdrojový kód v jazyce OpenCL + OpenCL-Quelltext + OpenCL source code + código fuente en OpenCL + OpenCL-lähdekoodi + OpenCL izvorni kôd + OpenCL forráskód + Kode sumber OpenCL + Codice sorgente OpenCL + OpenCL бастапқы коды + OpenCL 소스 코드 + Kod źródłowy OpenCL + Código-fonte do OpenCL + Исходный код OpenGL + Zdrojový kód OpenCL + OpenCL-källkod + вихідний код мовою OpenCL + OpenCL 源代码 + OpenCL 源碼 + OpenCL + Open Computing Language + + + MATLAB script/function سكربت/وظيفة MATLAB @@ -34431,7 +35449,7 @@ script/função MATLAB Script/função do MATLAB Funcție/script MATLAB - сценарий/функция MATLAB + Сценарий/функция MATLAB Skript/funkcia MATLAB Skriptna datoteka MATLAB Script/Funksion MATLAB @@ -34467,11 +35485,12 @@ Meson iturburu-kodea Meson-lähdekoodi code source Meson + cód foinseach Meson קוד מקור Meson Meson izvorni kôd Meson forráskód Codice-fonte Meson - Kode program Meson + Kode sumber Meson Codice sorgente Meson Meson бастапқы коды Meson 소스 코드 @@ -34479,7 +35498,7 @@ Kod źródłowy Meson código origem Meson Código-fonte Meson - исходный код Meson + Исходный код Meson Zdrojový kód Meson Месон изворни ко̂д Meson-källkod @@ -34503,6 +35522,7 @@ Modelica modeloa Modelica-malli modèle Modelica + samhail Modelica Modelo de Modelica דגם של Modelica Modelica model @@ -34518,7 +35538,7 @@ Model Modelica modelo Modelica Modelo da Modelica - модель Modelica + Модель Modelica Model Modelica Model Modelica модел Моделике @@ -34551,7 +35571,7 @@ Kryničny kod Pascal Изходен код — Pascal codi font en Pascal - zdrojový kód Pascal + zdrojový kód v jazyce Pascal Pascalkildekode Pascal-Quelltext Πηγαίος κώδικας Pascal @@ -34568,7 +35588,7 @@ Pascal izvorni kôd Pascal-forráskód Codice-fonte Pascal - Kode program Pascal + Kode sumber Pascal Codice sorgente Pascal Pascal ソースコード Pascal бастапқы коды @@ -34584,7 +35604,7 @@ código origem Pascal Código-fonte Pascal Cod sursă Pascal - исходный код Pascal + Исходный код Pascal Zdrojový kód Pascal Datoteka izvorne kode Pascal Kod burues Pascal @@ -34619,7 +35639,7 @@ difríochtaí idir chomhaid diferenzas entre ficheiros הבדל בין קבצים - razlike između datoteka + Razlike između datoteka diff-különbségfájl Differentias inter files perbedaan diantara berkas @@ -34638,7 +35658,7 @@ diferenças entre ficheiros Diferenças entre arquivos diferențe între fișiere - различия между файлами + Различия между файлами Rozdiely medzi súbormi razlike med datotekami Diferencë midis file @@ -34670,7 +35690,7 @@ Go source code Изходен код — Go codi font en Go - zdrojový kód Go + zdrojový kód v jazyce Go Go-kildekode Go-Quelltext Πηγαίος κώδικας Go @@ -34680,9 +35700,10 @@ Go iturburu-kodea Go-lähdekoodi code source Go + cód foinseach Go código fonte de Go קוד מקור של Go - Go izvorni kod + Go izvorni kôd Go forráskód Codice-fonte Go Kode sumber Go @@ -34697,14 +35718,14 @@ Kod źródłowy Go cigo origem Go Código-fonte Go - исходный код Go + Исходный код Go Zdrojový kód Go Izvorna koda Go Гоу изворни ко̂д Go-källkod Go kaynak kodu вихідний код мовою Go - Go + Go 源代码 Go 源碼 @@ -34721,6 +35742,7 @@ SCons konfigurazio-fitxategia SCons-asetustiedosto fichier de configuration SCons + comhad cumraíochta SCons קובץ תצורה של SCons SCons datoteka podešavanja SCons beállítófájl @@ -34733,7 +35755,7 @@ Plik konfiguracji SCons ficheiro de configuração SCons Arquivo de configuração do SCons - файл настроек SCons + Файл настроек SCons Konfiguračný súbor SCons Prilagoditvena datoteka SCons СКонс датотека подешавања @@ -34747,13 +35769,52 @@ + + Python 3 script + script Python 3 + skript v jazyce Python 3 + Python-3-Skript + Python 3 script + secuencia de órdenes en Python 3 + Python 3 -skripti + Python3 skripta + Python 3 parancsfájl + Skrip Python 3 + Script Python 3 + Python 3 скрипті + 파이썬 3 스크립트 + Skrypt Python 3 + Script Python 3 + Сценарий Python 3 + Skript Python 3 + Python 3-skript + скрипт мовою Python 3 + Python 3 脚本 + Python 3 指令稿 + + + + + + + + + + + + + + + + + Python script سكربت بايثون Skrypt Python Скрипт — Python script Python - skript Python + skript v jazyce Python Pythonprogram Python-Skript Δέσμη ενεργειών Python @@ -34786,7 +35847,7 @@ script Python Script Python Script Python - сценарий Python + Сценарий Python Skript Python Skriptna datoteka Python Script Python @@ -34811,9 +35872,9 @@ - - - + + + Lua script @@ -34821,7 +35882,7 @@ Skrypt Lua Скрипт на Lua script Lua - skript Lua + skript v jazyce Lua Luaprogram Lua-Skript Δέσμη ενεργειών Lua @@ -34853,7 +35914,7 @@ script Lua Script Lua Script Lua - сценарий Lua + Сценарий Lua Skript Lua Skriptna datoteka Lua Script Lua @@ -34877,6 +35938,7 @@ README document مستند README + Documentu LLEIME README sənədi Dakument README Документ — „Да се прочете“ @@ -34915,7 +35977,7 @@ documento LEIA-ME Documento README Document README - документ README + Документ README Dokument README Dokument README Dokument README @@ -34932,6 +35994,7 @@ NFO document مستند NFO + Documentu NFO Dakument NFO Документ — NFO document NFO @@ -34967,7 +36030,7 @@ documento NFO Documento NFO Document NFO - документ NFO + Документ NFO Dokument NFO Dokument NFO Dokument NFO @@ -35018,7 +36081,7 @@ ficheiro de especificações RPM Arquivo de especificação RPM Fișier RPM spec - файл описания RPM + Файл описания RPM Súbor RPM spec Določilna datoteka RPM File specifikimi RPM @@ -35041,18 +36104,27 @@ Sass CSS pre-processor file fitxer preprocessador CSS Sass + soubor preprocesoru Sass CSS Sass CSS-forbrænderfil Sass-CSS-Präprozessordatei + Sass CSS pre-processor file archivo de preprocesador de CSS Sass fichier de prétraitement CSS Sass + comhad réamhphróiseálaí CSS Sass קובץ קדם עיבוד Sass CSS + Sass CSS datoteka predobrade Sass CSS előfeldolgozó fájl + berkas pre-processor Sass CSS + File CSS Sass Sass CSS препроцессор файлы Sass CSS 전처리기 파일 Plik preprocesora CSS Sass Arquivo de pré-processamento Sass CSS - файл препроцессора Sass CSS + Файл препроцессора Sass CSS Súbor Sass CSS pre-procesora + датотека Сас ЦСС пре-процесора + Sass CSS-preprocessorfil + Sass CSS önişlemci dosyası файл препроцесора CSS Sass Sass CSS 预处理器文件 Sass CSS 處理器前檔案 @@ -35073,9 +36145,10 @@ Scala iturburu-kodea Scala-lähdekoodi code source Scala + cód foinseach Scala código fnote en Scala קוד מקור של Scala - Scala izvorni kod + Scala izvorni kôd Scala forráskód Codice-fonte Scala Kode sumber Scala @@ -35090,7 +36163,7 @@ Kod źródłowy Scala código origem Scala Código-fonte Scala - исходный код Scala + Исходный код Scala Zdrojový kód Scala Izvorna koda Scala Скала изворни ко̂д @@ -35124,7 +36197,7 @@ cód foinseach Scheme código fonte en Scheme קוד מקור של Scheme - Scheme izvorni kod + Scheme izvorni kôd Scheme-forráskód Codice-fonte Scheme Kode program Scheme @@ -35143,7 +36216,7 @@ código origem Scheme Código-fonte Scheme Cod sursă Scheme - исходный код Scheme + Исходный код Scheme Zdrojový kód Scheme Datoteka izvorne kode Scheme Kod burues Scheme @@ -35161,18 +36234,27 @@ Sass CSS pre-processor file fitxer preprocessador CSS Sass + soubor preprocesoru Sass CSS Sass CSS-forbrænderfil Sass-CSS-Präprozessordatei + Sass CSS pre-processor file archivo de preprocesador de CSS Sass fichier de prétraitement CSS Sass + comhad réamhphróiseálaí CSS Sass קובץ קדם עיבוד Sass CSS + Sass CSS datoteka predobrade Sass CSS előfeldolgozó fájl + berkas pre-processor Sass CSS + File CSS Sass Sass CSS препроцессор файлы Sass CSS 전처리기 파일 Plik preprocesora CSS Sass Arquivo de pré-processamento Sass CSS - файл препроцессора Sass CSS + Файл препроцессора Sass CSS Súbor Sass CSS pre-procesora + датотека Сас ЦСС пре-процесора + Sass CSS-preprocessorfil + Sass CSS önişlemci dosyası файл препроцесора CSS Sass Sass CSS 预处理器文件 Sass CSS 處理器前檔案 @@ -35183,6 +36265,7 @@ Setext document مستند Setext + Documentu Setext Setext sənədi Dakument Setext Документ — Setext @@ -35221,7 +36304,7 @@ documento Setext Documento Setext Document Setext - документ Setext + Документ Setext Dokument Setext Dokument Setext Dokument Setext @@ -35257,7 +36340,7 @@ cód SQL código SQL קוד SQL - SQL kod + SQL kôd SQL-kód Codice SQL Kode SQL @@ -35276,7 +36359,7 @@ código SQL Código SQL Cod SQL - код SQL + Код SQL Kód SQL Datoteka kode SQL Kod SQL @@ -35330,7 +36413,7 @@ script Tcl Script Tcl Script Tcl - сценарий Tcl + Сценарий Tcl Skript Tcl Skriptna datoteka Tcl Script Tcl @@ -35348,6 +36431,7 @@ TeX document مستند TeX + Documentu TeX Dakument TeX Документ — TeX document TeX @@ -35385,7 +36469,7 @@ documento TeX Documento TeX Document TeX - документ TeX + Документ TeX Dokument TeX Dokument TeX Dokument TeX @@ -35415,6 +36499,7 @@ TeXInfo document مستند TeXInfo + Documentu TeXInfo TeXInfo sənədi Dakument TeXInfo Документ — TeXInfo @@ -35453,7 +36538,7 @@ documento TeXInfo Documento TeXInfo Document TexInfo - документ TeXInfo + Документ TeXInfo Dokument TeXInfo Dokument TeXInfo Dokument TeXInfo @@ -35471,6 +36556,7 @@ Troff ME input document مستند Troff ME input + Documentu d'entrada de Troff ME Uvodny dakument Troff ME Изходен документ — Troff ME document d'entrada Troff ME @@ -35485,7 +36571,7 @@ Troff ME -syöteasiakirja Troff ME inntaksskjal document d'entrée Troff ME - cáipéis ionchur Troff ME + cáipéis ionchurtha Troff ME documento de entrada Troff ME מסמך קלט של Troff ME Troff ME ulazni dokument @@ -35507,7 +36593,7 @@ documento origem Troff ME Documento de entrada Troff ME Document intrare Troff ME - входной документ Troff ME + Входной документ Troff ME Vstupný dokument Troff ME Vnosni dokument Troff ME Dokument i input Troff ME @@ -35524,6 +36610,7 @@ Troff MM input document مستند Troff MM input + Documentu d'entrada de Troff MM Uvodny dakument Troff MM Изходен документ — Troff MM document d'entrada Troff MM @@ -35538,7 +36625,7 @@ Troff MM -syöteasiakirja Troff MM inntaksskjal document d'entrée Troff MM - cáipéis ionchur Troff MM + cáipéis ionchurtha Troff MM documento de entrada Troff MM מסמך קלט של Troff MM Troff MM ulazni dokument @@ -35560,7 +36647,7 @@ documento origem Troff MM Documento de entrada Troff MM Document intrare Troff MM - входной документ Troff MM + Входной документ Troff MM Vstupný dokument Troff MM Vnosni dokument Troff MM Dokument i input Troff MM @@ -35577,6 +36664,7 @@ Troff MS input document مستند Troff MS input + Documentu d'entrada de Troff MS Uvodny dakument Troff MS Изходен документ — Troff MS document d'entrada Troff MS @@ -35591,7 +36679,7 @@ Troff MS -syöteasiakirja Troff MS inntaksskjal document d'entrée Troff MS - cáipéis ionchur Troff MS + cáipéis ionchurtha Troff MS documento de entrada Troff MS מסמך קלט של Troff MS Troff MS ulazni dokument @@ -35613,7 +36701,7 @@ documento origem Troff MS Documento de entrada Troff MS Document intrare Troff MS - входной документ Troff MS + Входной документ Troff MS Vstupný dokument Troff MS Vnosni dokument Troff MS Dokument i input Troff MS @@ -35630,18 +36718,28 @@ Twig template plantilla Twig + šablona Twig Twig-skabelon Twig-Vorlage + Twig template plantilla de Twig + Twig txantiloia modèle Twig + teimpléad Twig תבנית Twig + Twig predložak Twig-sablon + templat Twig + Modello twig Twig үлгісі Twig 문서 서식 Szablon Twig Modelo Twig - шаблон Twig + Шаблон Twig Šablóna Twig + Твиг шаблон + Twig-mall + Twig şablonu шаблон twig Twig 模板 Twig 範本 @@ -35687,7 +36785,7 @@ tabela UIL do X-Motif Tabela UIL do X-Motif Tabel X-Motif UIL - таблица UIL X-Motif + Таблица UIL X-Motif Tabuľka X-Motif UIL Preglednica X-Motif UIL Tabelë X-Motif UIL @@ -35721,7 +36819,7 @@ suíomh acmhainne localización do recurso מיקום של משאב - položaj resursa + Lokacija resursa erőforrás-hely Loco de ressources lokasi sumber daya @@ -35740,7 +36838,7 @@ localização de recurso Localização de recurso locație de resursă - расположение ресурса + Расположение ресурса Umiestnenie zdroja mesto vira Pozicion rezerve @@ -35765,6 +36863,7 @@ archivo codificado con uuencode uuencode-aturiko fitxategia fichier uuencodé + comhad uuencoded Ficheiro uuencoded קובץ בקידוד uu uuencoded datoteka @@ -35780,14 +36879,14 @@ Plik zakodowany za pomocą uuencode ficheiro uuencoded Arquivo codificado UUE - файл в кодировке uuencode + Файл, кодированный uuencode Súbor v kódovaní uuencode Datoteka uuencode уукодирана датотека uuencode-fil uuencoded dosyası файл даних у форматі UUE - 未编码的文件 + Uuencode 文件 uuencoded 檔 @@ -35834,7 +36933,7 @@ ficheiro XMI Arquivo XMI Fișier XMI - файл XMI + Файл XMI Súbor XMI Datoteka XMI File XMI @@ -35890,7 +36989,7 @@ ficheiro XSL FO Arquivo XSL FO Fișier XSL FO - файл XSL FO + Файл XSL FO Súbor XSL FO Datoteka XSL FO File XSL FO @@ -35911,6 +37010,7 @@ iptables configuration file ملف تضبيط iptables + ficheru de configuración d'iptables kanfihuracyjny fajł iptables Настройки за iptables fitxer de configuració d'iptables @@ -35927,7 +37027,7 @@ comhad cumraíochta iptables ficheiro de configuración de iptables קובץ הגדרה של iptables - iptables datoteka s postavkama + iptables datoteka podešavanja iptables beállítófájl File de configuration IPTables berkas konfigurasi iptables @@ -35945,7 +37045,7 @@ ficheiro de configuração iptables Arquivo de configuração do iptables fișier configurare iptables - файл настроек iptables + Файл настроек iptables Súbor nastavení iptables nastavitvena datoteka iptables File konfigurimi iptables @@ -35979,6 +37079,110 @@ + + D-Bus service file + fitxer de servei de D-Bus + soubor služby D-Bus + D-Bus-Dienstdatei + D-Bus service file + archivo de servicio de D-Bus + D-Bus zerbitzu fitxategia + D-Bus-palvelutiedosto + fichier de service D-Bus + comhad seirbhíse D-Bus + Datoteka D-Bus usluge + D-Bus szolgáltatás fájl + berkas layanan D-Bus + File servizio D-Bus + D-Bus қызметтік файлы + D-Bus 서비스 파일 + Plik usługi D-Bus + Arquivo de serviço do D-Bus + Файл службы D-Bus + Súbor služby D-Bus + датотека услуге Д-сабирнице + D-BUS-tjänstfil + D-Bus hizmeti dosyası + файл служби D-Bus + D-Bus 服务文件 + D-Bus 服務檔 + + + + + + + + + systemd unit file + ficheru d'unidaes de systemd + fitxer d'unitat de systemd + jednotkový soubor systemd + systemd-Einheitsdatei + systemd unit file + archivo de unidad de systemd + systemd unitate fitxategia + systemd-yksikkötiedosto + fichier d'unité systemd + comhad aonaid systemd + Datoteka systemd jedinice + systemd egység fájl + berkas unit systemd + File unità systemd + systemd юнит файлы + systemd 유닛 파일 + Plik jednostki systemd + Arquivo de unit do systemd + Модульный файл Systemd + Súbor jednotky systemd + датотека јединице системд-а + systemd-enhetsfil + systemd birim dosyası + файл модуля systemd + systemd 单元文件 + systemd 單位檔 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + XSLT stylesheet نمط XSLT @@ -36018,7 +37222,7 @@ folha de estilos XSLT Folha de estilo XSLT Fișă de stil XSLT - таблица стилей XSLT + Таблица стилей XSLT Štýl XSLT Slogovna predloga XSLT Fletë stili XSLT @@ -36077,7 +37281,7 @@ base de dados XMCD CD Banco de dados de CD XMCD Bază de date XMCD CD - база данных компакт-дисков XMCD + База данных компакт-дисков XMCD Databáza XMCD CD Podatkovna zbirka XMCD CD Bazë me të dhëna XMCD CD @@ -36096,6 +37300,7 @@ XML document مستند XML + Documentu XML Dakument XML Документ — XML document XML @@ -36131,7 +37336,7 @@ documento XML Documento XML Document XML - документ XML + Документ XML Dokument XML Dokument XML Dokument XML @@ -36159,6 +37364,7 @@ XML entities document مستند كيانات XML + Documentu d'entidaes XML Dakument elementaŭ XML Документ — заместващи последователности в XML document d'entitats XML @@ -36193,7 +37399,7 @@ documento de entidades XML Documento de entidades XML Document entități XML - файл сущностей XML + Файл сущностей XML Dokument entít XML Dokument XML določil Dokument njësish XML @@ -36214,6 +37420,7 @@ DV video DV مرئي + Videu en DV Videa DV Видео — DV vídeo DV @@ -36231,7 +37438,7 @@ físeán DV vídeo DV וידאו DV - DV video + DV video snimka DV videó Video DV Video DV @@ -36250,7 +37457,7 @@ vídeo DV Vídeo DV Video DV - видео DV + Видео DV Video DV Video datoteka DV Video DV @@ -36271,6 +37478,7 @@ ISI video مرئي ISI + Videu n'ISI ISI video faylı Videa ISI Видео — ISI @@ -36290,7 +37498,7 @@ físeán ISI vídeo ISI וידאו ISI - ISI video + ISI video snimka ISI-videó Video ISI Video ISI @@ -36309,7 +37517,7 @@ vídeo ISI Vídeo ISI Video ISI - видео ISI + Видео ISI Video ISI Video datoteka ISI Video ISI @@ -36336,10 +37544,10 @@ MPEG-2 -siirtobittivirta MPEG-2 flutningsstreymur flux de transport MPEG-2 - Sruth aistrithe MPEG-2 + sruth aistrithe MPEG-2 fluxo de transporte MPEG-2 העברת זרימה של MPEG-2 - MPEG-2 transportni tok + MPEG-2 transportno strujanje MPEG-2 átviteli adatfolyam Fluxo de transporto MPEG-2 Stream transport MPEG-2 @@ -36356,7 +37564,7 @@ fluxo de transporte MPEG-2 Fluxo de transporte de MPEG-2 Flux transport MPEG-2 - транспортный поток MPEG-2 + Транспортный поток MPEG-2 MPEG-2 Transport Stream Pretočni vir prenosega MPEG МПЕГ-2 ток преноса @@ -36401,6 +37609,7 @@ MPEG video MPEG مرئي + Videu en MPEG Videa MPEG Видео — MPEG vídeo MPEG @@ -36418,7 +37627,7 @@ físeán MPEG vídeo MPEG וידאו MPEG - MPEG video + MPEG video snimka MPEG-videó Video MPEG Video MPEG @@ -36438,7 +37647,7 @@ vídeo MPEG Vídeo MPEG Video MPEG - видео MPEG + Видео MPEG Video MPEG Video datoteka MPEG Video MPEG @@ -36469,6 +37678,7 @@ MPEG video (streamed) + Videu en MPEG (tresmitíu) Видео — MPEG, поточно vídeo MPEG (flux) video MPEG (proud) @@ -36480,6 +37690,7 @@ MPEG bideoa (korronte bidez) MPEG-video (virtaus) vidéo MPEG (flux) + físeán MPEG (sruthaithe) vídeo MPEG (en stream) קובץ MPEG (בהזרמה) MPEG video snimka (strujanje) @@ -36497,7 +37708,7 @@ Plik wideo MPEG (strumień) vídeo MPEG (em fluxo) Vídeo MPEG (fluxo) - видео MPEG (потоковое) + Видео MPEG (потоковое) MPEG video (streamované) MPEG-video (pretočni) МПЕГ видео (проточни) @@ -36518,6 +37729,7 @@ QuickTime video QuickTime مرئي + Videu en QuickTime Videa QuickTime Видео — QuickTime vídeo QuickTime @@ -36535,7 +37747,7 @@ físeán QuickTime vídeo QuickTime וידאו של QuickTime - QuickTime video + QuickTime video snimka QuickTime videó Video QuickTime Video QuickTime @@ -36554,7 +37766,7 @@ vídeo QuickTime Vídeo do QuickTime Video QuickTime - видео QuickTime + Видео QuickTime Video QuickTime Video datoteka QuickTime Video QuickTime @@ -36614,7 +37826,7 @@ imagem QuickTime Imagem do QuickTime Imagine QuickTime - изображение QuickTime + Изображение QuickTime Obrázok QuickTime Slikovna datoteka QuickTime Figurë QuickTime @@ -36631,9 +37843,44 @@ + + Khronos texture image + imatge de textura de Khronos + obrázek s texturou Khronos + Khronos-Texturbild + Khronos texture image + imagen de textura de Khronos + image de texture Khronos + íomhá uigeachta Khronos + Khronos tekstura slika + Khronos textúra kép + citra tekstur Khronos + Immagine texture Khronos + Khronos текстура суреті + 크로노스 텍스처 파일 + Obraz tekstury Khronos + Imagem de textura do Khronos + Изображение текстуры Khronos + Obrázok textúry Khronos + слика Кронос текстуре + Khronos-texturbild + Khronos kaplama görüntüsü + зображення текстури Khronos + Khronos 纹理图像 + Khronos 紋理影像 + + + + + + + + + Vivo video Vivo مرئي + Videu en Vivo Vivo video faylı Videa Vivo Видео — Vivo @@ -36653,7 +37900,7 @@ físeán Vivo vídeo Vivo וידאו של Vivo - Vivo video + Vivo video snimka Vivo-videó Video Vivo Video Vivo @@ -36672,7 +37919,7 @@ vídeo Vivo Vídeo Vivo Video Vivo - видео Vivo + Видео Vivo Video Vivo Video datoteka Vivo Video Vivo @@ -36690,6 +37937,7 @@ Wavelet video Wavelet مرئي + Videu en Wavelet Wavelet video faylı Videa Wavelet Видео — Wavelet @@ -36709,7 +37957,7 @@ físeán Wavelet vídeo Wavelet וידאו של Wavelet - Wavelet video + Wavelet video snimka Wavelet-videó Video Wavelet Video Wavelet @@ -36728,7 +37976,7 @@ vídeo Wavelet Vídeo Wavelet Video Wavelet - видео Wavelet + Видео Wavelet Video Wavelet Video datoteka Wavelet Video Wavelet @@ -36782,7 +38030,7 @@ animação ANIM Animação ANIM Animație ANIM - анимация ANIM + Анимация ANIM Animácia ANIM Datoteka animacije ANIM Animim ANIM @@ -36833,7 +38081,7 @@ animação FLIC Animação FLIC Animație FLIC - анимация FLIC + Анимация FLIC Animácia FLIC Datoteka animacije FLIC Animim FLIC @@ -36856,6 +38104,7 @@ Haansoft Hangul document مستند Haansoft Hangul + Documentu de Haansoft Hangul Dakument Haansoft Hangul Документ — Haansoft Hangul document d'Haansoft Hangul @@ -36890,7 +38139,7 @@ documento Haansoft Hangul Documento do Haansoft Hangul Document Haansoft Hangul - документ Haansoft Hangul + Документ Haansoft Hangul Dokument Haansoft Hangul Dokument Haansoft Hangul Dokument Haansoft Hangul @@ -36911,6 +38160,7 @@ Haansoft Hangul document template قالب مستند Haansoft Hangul + Plantía de documentu de Haansoft Hangul Šablon dakumentu Haansoft Hangul Шаблон за документи — Haansoft Hangul plantilla de document d'Haansoft Hangul @@ -36945,7 +38195,7 @@ modelo de documento Haansoft Hangul Modelo de documento do Haansoft Hangul Document șablon Haansoft Hangul - шаблон документа Haansoft Hangul + Шаблон документа Haansoft Hangul Šablóna dokumentu Haansoft Hangul Predloga dokumenta Haansoft Hangul Model dokumenti Haansoft Hangul @@ -36999,7 +38249,7 @@ animação MNG Animação MNG Animație MNG - анимация MNG + Анимация MNG Animácia MNG Datoteka animacije MNG Animim MNG @@ -37020,6 +38270,7 @@ ASF video ASF مرئي + Videu n'ASF Videa ASF Видео — ASF vídeo ASF @@ -37037,7 +38288,7 @@ físeán ASF vídeo ASF וידאו ASF - ASF video + ASF video snimka ASF videó Video ASF Video ASF @@ -37056,7 +38307,7 @@ vídeo ASF Vídeo ASF Video ASF - видео ASF + Видео ASF Video ASF Video datoteka ASF Video ASF @@ -37115,7 +38366,7 @@ ficheiro Windows Media Station Arquivo de estação do Windows Media Fișier Windows Media Station - файл Windows Media Station + Файл Windows Media Station Súbor Windows Media Station Datoteka Windows Media Station File Windows Media Station @@ -37136,6 +38387,7 @@ Windows Media video Windows Media مرئي + Videu de Windows Media Videa Windows Media Видео — Windows Media vídeo de Windows Media @@ -37152,7 +38404,7 @@ físeán Windows Media vídeo de Windows Media וידאו של Windows Media - Windows Media video + Windows Media video snimka Windows Media videó Video Windows Media Video Windows Media @@ -37170,7 +38422,7 @@ vídeo Windows Media Vídeo do Windows Media Video Windows Media - видео Windows Media + Видео Windows Media Video Windows Media Video datoteka Windows Media Video Windows Media @@ -37187,6 +38439,7 @@ AVI video AVI مرئي + Videu n'AVI AVI video faylı Videa AVI Видео — AVI @@ -37206,7 +38459,7 @@ físeán AVI vídeo AVI וידאו AVI - AVI video + AVI video snimka AVI-videó Video AVI Video AVI @@ -37226,7 +38479,7 @@ vídeo AVI Vídeo AVI Video AVI - видео AVI + Видео AVI Video AVI Video datoteka AVI Video AVI @@ -37259,6 +38512,7 @@ NullSoft video NullSoft مرئي + Videu de NullSoft Videa NullSoft Видео — NullSoft vídeo NullSoft @@ -37276,7 +38530,7 @@ físeán NullSoft vídeo de NullSoft וידאו של NullSot - NullSoft video + NullSoft video snimka NullSoft videó Video NullSoft Video NullSoft @@ -37294,7 +38548,7 @@ vídeo NullSoft Vídeo do NullSoft Video NullSoft - видео Nullsoft + Видео Nullsoft Video NullSoft Video datoteka NullSoft Video NullSoft @@ -37303,7 +38557,7 @@ Nullsoft videosu відеокліп NullSoft Ảnh động NullSoft - Nullsoft 视频 + NullSoft 视频 NullSoft 視訊 @@ -37347,7 +38601,7 @@ ficheiro de fluxo SDP multicast Arquivo de canal multicast SDP Fișier flux multicast SDP - файл мультикаст-потока SDP + Файл мультикаст-потока SDP Súbor viacsmerového vysielania prúdu SDP Pretočni vir večsmernega oddajanja File stream multicast SDP @@ -37374,6 +38628,7 @@ SGI video SGI مرئي + Videu en SGI SGI video faylı Videa SGI Видео — SGI @@ -37393,7 +38648,7 @@ físeán SGI vídeo SGI וידאו SGI - SGI video + SGI video snimka SGI-videó Video SGI Video SGI @@ -37412,7 +38667,7 @@ vídeo SGI Vídeo SGI Video SGI - видео SGI + Видео SGI Video SGI Video datoteka SGI Video SGI @@ -37465,7 +38720,7 @@ pacote transferido eMusic Pacote de download do eMusic pachet descărcare eMusic - пакет загрузок eMusic + Пакет загрузок eMusic Balíček sťahovania eMusic Datoteka paketa eMusic Paketë shkarkimi eMusic @@ -37516,7 +38771,7 @@ dados geográficos KML Dados geográficos KML Date geografice KML - географические данные KML + Географические данные KML Zemepisné údaje KML Datoteka geografskih podatkov KML КМЛ географски подаци @@ -37549,7 +38804,7 @@ sonraí comhbhrúite geografacha KML datos xeográficos KML comprimidos מידע גאוגרפי דחוס KML - KML geografski komprimirani podaci + KML sažeti geografski podaci KML tömörített földrajzi adatok Datos geographic KML comprimite Data geografis KML terkompresi @@ -37565,14 +38820,14 @@ dados geográficos comprimidos KML Dados geográficos KML compactados Date geografice comprimate KML - сжатые географические данные KML + Сжатые географические данные KML Komprimované zemepisné údaje KML Skrčeni geografski podatki KML КМЛ географски запаковани подаци KML geografiskt komprimerat data KML sıkıştırılmış coğrafi verisi стиснуті географічні дані KML - KML 压缩地理数据 + KML 地理压缩数据 KML 地理壓縮資料 KML Keyhole Markup Language @@ -37588,6 +38843,7 @@ GeoJSON geospatial data datos geoespaciales en GeoJSON données géospatiales GeoJSON + sonraí geospásúla GeoJSON GeoJSON geoprostorni podaci GeoJSON téradatok Data geospasial GeoJSON @@ -37596,10 +38852,10 @@ GeoJSON 지리 정보 데이터 Dane geoprzestrzenne GeoJSON Dados geoespaciais GeoJSON - геопространственные данные GeoJSON + Геопространственные данные GeoJSON Geopriestorové údaje GeoJSON ГеоЈСОН геопросторни подаци - GeoJSON geospatial data + Geospatialt GeoJSON-data GeoJSON coğrafi veriler геопросторові дані GeoJSON GeoJSON 地理空间数据 @@ -37620,6 +38876,7 @@ GPX datu geografikoak GPX-paikkatieto données géographiques GPX + sonraí geografacha GPX נתונים גאוגרפיים GPX GPX geografski podaci GPX földrajzi adatok @@ -37630,13 +38887,13 @@ Donadas geograficas GPX Dane geograficzne GPX Dados geográficos GPX - географические данные GPX + Географические данные GPX Zemepisné údaje GPX ГПИкс географски подаци GPX geografisk data GPX coğrafi verileri географічні дані GPX - GPX 地理空间数据 + GPX 地理数据 GPX 地理資料 GPX GPS Exchange Format @@ -37686,7 +38943,7 @@ ficheiro de definições Citrix ICA Arquivo de configuração do Citrix ICA Fișier de configurări Citrix ICA - файл настроек Citrix ICA + Файл настроек Citrix ICA Súbor nastavení Citrix ICA Nastavitvena datoteka Citrix ICA File rregullimesh Citrix ICA @@ -37706,6 +38963,7 @@ XUL interface document مستند واجهة XUL + Documentu d'interfaz XUL Interfejsny dakument XUL Документ — интерфейс за XUL document d'interfície XUL @@ -37740,7 +38998,7 @@ documento de ambiente XUL Documento de interface XUL Document interfață XUL - документ интерфейса XUL + Документ интерфейса XUL Dokument rozhrania XUL Dokument vmesnika XUL Dokument interfaqe XUL @@ -37792,7 +39050,7 @@ módulo de instalador XPInstall Módulo de instalador XPInstall Modul de instalare XPInstall - модуль установщика XPInstall + Модуль установщика XPInstall Modul inštalátora XPInstall modul namestilnika XPInstall модул инсталатера Инсталирања ИксПе-а @@ -37807,6 +39065,7 @@ Word 2007 document مستند Word 2007 + Documentu de Word 2007 Документ — Word 2007 document de Word 2007 dokument Word 2007 @@ -37838,7 +39097,7 @@ documento Word 2007 Documento do Word 2007 Document Word 2007 - документ Word 2007 + Документ Word 2007 Dokument Word 2007 Dokument Word 2007 документ Ворда 2007 @@ -37846,7 +39105,7 @@ Word 2007 belgesi документ Word 2007 Tài liệu Word 2007 - Microsoft Word 2007 文档 + Word 2007 文档 Word 2007 文件 @@ -37854,6 +39113,7 @@ Word 2007 document template + Plantía de documentu de Word 2007 Шаблон за документи — Word 2007 plantilla de document de Word 2007 šablona dokumentu Word 2007 @@ -37865,6 +39125,7 @@ Word 2007 dokumentuaren txantiloia Word 2007 -asiakirjamalli modèle de document Word 2007 + teimpléad cháipéis Word 2007 Plantilla de documento de Word 2007 תבנית מסמך של Word 2007 Word 2007 predložak dokumenta @@ -37882,7 +39143,7 @@ Szablon dokumentu Word 2007 modelo de documento Word 2007 Modelo de documento do Word 2007 - шаблон документа Word 2007 + Шаблон документа Word 2007 Šablóna dokumentu Word 2007 Predloga dokumenta Word 2007 шаблон документа Ворда 2007 @@ -37929,7 +39190,7 @@ apresentação PowerPoint 2007 Apresentação do PowerPoint 2007 Prezentare PowerPoint 2007 - презентация PowerPoint 2007 + Презентация PowerPoint 2007 Prezentácia PowerPoint 2007 Predstavitev Microsoft PowerPoint 2007 презентација Пауер Поинта 2007 @@ -37937,7 +39198,7 @@ PowerPoint 2007 sunumu презентація PowerPoint 2007 Trình diễn PowerPoint 2007 - Microsoft PowerPoint 2007 演示文稿 + PowerPoint 2007 演示文稿 PowerPoint 2007 簡報 @@ -37956,9 +39217,10 @@ PowerPoint 2007 diapositiba PowerPoint 2007 -dia diapositive PowerPoint 2007 + sleamhnán PowerPoint 2007 Diaporama de PowerPoint 2007 שקופית של PowerPoint 2007 - PowerPoint 2007 slajd + PowerPoint 2007 slikovna prezentacija PowerPoint 2007 dia Diapositiva PowerPoint 2007 Slide PowerPoint 2007 @@ -37973,14 +39235,14 @@ Slajd PowerPoint 2007 diapositivo PowerPoint 2007 Slide do PowerPoint 2007 - слайд PowerPoint 2007 + Слайд PowerPoint 2007 Snímka PowerPoint 2007 Prosojnica PowerPoint 2007 слајд Пауер Поинта 2007 PowerPoint 2007-bildspel PowerPoint 2007 slaytı слайд PowerPoint 2007 - PowerPoint 2007 文稿 + PowerPoint 2007 幻灯片 PowerPoint 2007 投影片 @@ -38020,14 +39282,14 @@ espetáculo PowerPoint 2007 Apresentação do PowerPoint 2007 Prezentare PowerPoint 2007 - презентация PowerPoint 2007 + Презентация PowerPoint 2007 Ukážka PowerPoint 2007 Zagonska predstavitev PowerPoint 2007 приказ Пауер Поинта 2007 PowerPoint 2007-visning PowerPoint 2007 gösterisi показ слайдів PowerPoint 2007 - Microsoft PowerPoint 2007 演示文稿 + PowerPoint 2007 放映 PowerPoint 2007 展示 @@ -38046,6 +39308,7 @@ PowerPoint 2007 aurkezpen txantiloia PowerPoint 2007 -esitysmalli modèle de présentation PowerPoint 2007 + teimpléad láithreoireachta PowerPoint 2007 modelo de presentación de PowerPoint 2007 תבנית למצגת של PowerPoint 2007 PowerPoint 2007 predložak prezentacije @@ -38063,7 +39326,7 @@ Szablon prezentacji PowerPoint 2007 modelo de apresentação PowerPoint 2007 Modelo de apresentação do PowerPoint 2007 - шаблон презентации PowerPoint 2007 + Шаблон презентации PowerPoint 2007 Šablóna prezentácie PowerPoint 2007 Predloga predstavitve PowerPoint 2007 шаблон презентације Пауер Поинта 2007 @@ -38111,7 +39374,7 @@ folha de cálculo Excel 2007 Planilha do Excel 2007 Foaie de calcul Excel 2007 - электронная таблица Excel 2007 + Электронная таблица Excel 2007 Zošit Excel 2007 Razpredelnica Microsoft Excel 2007 табела Ексела 2007 @@ -38119,7 +39382,7 @@ Excel 2007 çalışma sayfası ел. таблиця Excel 2007 Bảng tính Excel 2007 - Microsoft Excel 2007 工作簿 + Excel 2007 电子表格 Excel 2007 試算表 @@ -38138,6 +39401,7 @@ Excel 2007 kalkulu-orri txantiloia Excel 2007 -taulukkomalli modèle de feuille de calcul Excel 2007 + teimpléad scarbhileoige Excel 2007 modelo de folla de cálculo Excel 2007 תבנית של גיליון נתונים של Excel 2007 Excel 2007 predložak proračunske tablice @@ -38155,14 +39419,14 @@ Szablon arkusza Excel 2007 modelo de folha de cálculo Excel 2007 Modelo de planilha do Excel 2007 - шаблон электронной таблицы Excel 2007 + Шаблон электронной таблицы Excel 2007 Šablóna zošitu Excel 2007 Predloga razpredelnice Excel 2007 шаблон табеле Ексела 2007 Excel 2007-kalkylarksmall Excel 2007 çalışma sayfası şablonu шаблон електронної таблиці Excel 2007 - Excel 2007 工作表模板 + Excel 2007 电子表格模板 Excel 2007 試算表範本 @@ -38171,6 +39435,7 @@ T602 document مستند T602 + Documentu T602 Dakument T602 Документ — T602 document T602 @@ -38206,7 +39471,7 @@ documento T602 Documento T602 Document T602 - документ T602 + Документ T602 Dokument T602 Dokument T602 Dokument T602 @@ -38263,7 +39528,7 @@ definições de Cisco VPN Configurações de VPN da Cisco Configurări VPN Cisco - файл настроек Cisco VPN + Файл настроек Cisco VPN Nastavenia Cisco VPN Datoteka nastavitev Cisco VPN Rregullime VPN Cisco @@ -38285,6 +39550,7 @@ ICC profile تشكيلة OCL + Perfil ICC Цветови профил — OCL perfil ICC profil ICC @@ -38317,14 +39583,14 @@ perfil ICC Perfil ICC Profil ICC - профиль ICC + Профиль ICC Profil farieb ICC Datoteka profila ICC ИЦЦ профил ICC-profil ICC profili профіль ICC - ICC 文件 + ICC 配置文件 ICC 設定檔 @@ -38366,7 +39632,7 @@ ficheiro de calibração de cor IT 8.7 Arquivo de calibração de cor IT 8.7 Fișier de calibrare a culorii IT 8.7 - файл калибровки цвета IT 8.7 + Файл калибровки цвета IT 8.7 Súbor kalibrácie farieb IT 8.7 Umeritvena datoteka barve IT 8.7 ИТ 8.7 датотека калибрације боје @@ -38394,6 +39660,7 @@ CCMX kolore-kalibrazioaren fitxategia CCMX-värikorjaustiedosto fichier de correction colorimétrique CCMX + comhad ceartúchán dathanna CCMX Ficheiro de corrección de cor CCMX קובץ תיקון צבע מסוג CCMX CCMX datotkea ispravka boja @@ -38409,7 +39676,7 @@ Plik korekcji kolorów CCMX ficheiro de correção de cor CCMX Arquivo de correção de cor CCMX - файл цветовой коррекции CCMX + Файл цветовой коррекции CCMX Súbor korekcie farieb CCMX Datoteka barvne poprave CCMX ЦЦМИкс датотека поправке боје @@ -38437,6 +39704,7 @@ WinHelp laguntza fitxategia WinHelp-ohjetiedosto fichier d'aide WinHelp + comhad cabhrach WinHelp Ficheiro de axuda WinHelp קובץ עזרה מסוג WinHelp WinHelp datoteka pomoći @@ -38452,7 +39720,7 @@ Plik pomocy WinHelp ficheiro de ajuda WinHelp Arquivo de ajuda WinHelp - файл справки WinHelp + Файл справки WinHelp Súbor Pomocníka WinHelp Datoteka pomoči WinHelp датотека помоћи Вин хелпа @@ -38470,18 +39738,28 @@ binary differences between files diferencies binàries entre fitxers + binární rozdíl mezi soubory binære forskelle mellem filer binäre Unterschiede zwischen Dateien + binary differences between files diferencias entre archivos binarios + fitxategi binarioen arteko ezberdinstasunak différences binaires entre fichiers + difríochtaí dénártha idir comhaid הבדלים בינריים בין קבצים + Binarne razlike između datoteka bináris különbségfájl + perbedaan biner antar berkas + Differenze binarie tra file файлдар арасындағы бинарлық айырмашылықтар 바이너리 차이 비교 파일 Binarna różnica pomiędzy plikami Diferenças binárias entre arquivos - двоичные различия между файлами + Двоичные различия между файлами Binárne rozdiely medzi súbormi + бинарне разлике датотека + binära skillnader mellan filer + dosyalar arasındaki ikilik farklar двійкова різниця між файлами 文件的二进制区别 檔案間的二進位差異 @@ -38513,7 +39791,7 @@ grianghraif dhigiteacha fotos dixitais תמונות דיגיטליות - digitalne fotografije + Digitalne fotografije digitális fényképek Photos digital foto digital @@ -38530,7 +39808,7 @@ fotografias digitais Fotos digitais fotografii digitale - цифровые фотографии + Цифровые фотографии Digitálne fotografie digitalne fotografije Fotografi dixhitale @@ -38550,6 +39828,7 @@ Video CD Video CD + CD de videu Videa CD CD — видео Video CD @@ -38564,7 +39843,7 @@ Video CD Video CD CD vidéo - Video CD + dlúthdhiosca físe Video CD תקליטור וידאו Video CD @@ -38584,7 +39863,7 @@ Video CD CD de vídeo CD video - видеодиск VCD + Видео CD Video CD Video CD CD Video @@ -38604,6 +39883,7 @@ Super Video CD Super Video CD + CD de Super Video Super Video CD CD — супер видео Super Video CD @@ -38618,7 +39898,7 @@ Super Video CD Super Video CD Super VCD - Super Video CD + dlúthdhiosca Super Video Super vídeo CD Super Video CD Super Video CD @@ -38638,7 +39918,7 @@ Super Video CD CD de Super Vídeo (SVCD) Super Video CD - компакт-диск Super Video + Super Video CD Super Video CD Super Video CD CD Super Video @@ -38658,6 +39938,7 @@ video DVD DVD مرئي + DVD de videu videa DVD DVD — видео DVD-Video @@ -38675,7 +39956,7 @@ DVD físe DVD de vídeo DVD וידאו - video DVD + Video DVD video DVD DVD video DVD video @@ -38693,7 +39974,7 @@ DVD vídeo DVD de vídeo DVD video - видео-DVD + Видео DVD DVD-Video video DVD DVD video @@ -38750,7 +40031,7 @@ CD áudio CD de áudio CD audio - звуковой CD + Аудио CD Zvukové CD zvočni CD CD audio @@ -38800,7 +40081,7 @@ CD vazio Disco CD vazio disc gol CD - чистый компакт-диск + Чистый диск CD Prázdny disk CD prazen CD disk Disk bosh CD @@ -38850,7 +40131,7 @@ DVD vazio Disco DVD vazio disc gol DVD - чистый диск DVD + Чистый диск DVD Prázdny disk DVD prazen DVD disk Disk bosh DVD @@ -38900,7 +40181,7 @@ Blu-Ray vazio Disco Blu-ray vazio disc gol Blu-ray - чистый диск Blu-ray + Чистый диск Blu-ray Prázdny disk Blu-ray prazen Blu-Ray disk Disk bosh Blu-ray @@ -38950,7 +40231,7 @@ HD DVD vazio Disco HD DVD vazio disc gol HD DVD - чистый диск HD DVD + Чистый диск HD DVD Prázdny disk HD DVD prazen HD DVD disk Disk bosh DVD HD @@ -39001,7 +40282,7 @@ DVD áudio DVD de áudio DVD audio - звуковой DVD + Аудио DVD Zvukové DVD zvočni DVD DVD audio @@ -39022,6 +40303,7 @@ Blu-ray video disc قرص بلو-راي مرئي + Discu Blu-ray de videu Videadysk Blu-ray Blu-ray — видео disc de vídeo Blu-Ray @@ -39056,7 +40338,7 @@ Blu-ray de vídeo Disco de vídeo Blu-ray Disc video Blu-ray - видеодиск Blu-ray + Видеодиск Blu-ray Videodisk Blu-ray Blu-ray video disk Disk video Blu-ray @@ -39077,6 +40359,7 @@ HD DVD video disc قرص HD DVD مرئي + Discu HD DVD de videu Videadysk HD DVD HD DVD — видео disc de vídeo HD-DVD @@ -39110,7 +40393,7 @@ HD DVD de vídeo Disco de vídeo HD DVD Disc video HD DVD - видеодиск HD DVD + Видеодиск HD DVD Videodisk HD DVD HD DVD video disk Disk video DVD HD @@ -39142,9 +40425,10 @@ e-book irakurlea e-kirjan lukulaite lecteur de livre numérique + léitheoir r-leabhair lector de libros electrónicos קורא ספרים אלקטרוניים - čitač e-knjiga + Čitač e-knjiga e-könyvolvasó Lector de libro electronic Pembaca e-book @@ -39158,7 +40442,7 @@ Czytnik e-booków leitor de ebooks Leitor de e-book - устройство для чтения электронных книг + Устройство для чтения электронных книг Čítačka e-kníh Bralnik elektronskih knjig читач ел. књига @@ -39190,7 +40474,7 @@ Picture CD Picture CD CD Picture - Picture CD + dlúthdhiosca grianghraf Picture CD תקליטור תמונות Slikovni CD @@ -39246,7 +40530,7 @@ seinnteoir iniompartha fuaime dispositivo de son portábel נגן מוזיקה נייד - prenosivi audio svirač + Prenosivi glazbeni svirač hordozható zenelejátszó Lector audio portabile pemutar audio portable @@ -39263,7 +40547,7 @@ reprodutor áudio portátil Reprodutor de áudio portátil player audio portabil - портативный аудиопроигрыватель + Портативный аудиопроигрыватель Prenosný hudobný prehrávač prenosni predvajalnik zvoka Lexues audio portativ @@ -39296,7 +40580,7 @@ bogearraí software תכנה - softver + Softver szoftver Software peranti lunak @@ -39314,7 +40598,7 @@ programa Aplicativo software - программное обеспечение + Программное обеспечение Softvér programska oprema Software @@ -39362,7 +40646,7 @@ programa UNIX Aplicativo UNIX Software UNIX - программа UNIX + Программа UNIX Softvér UNIX Programska datoteka UNIX ЈУНИКС-ов софтвер @@ -39414,7 +40698,7 @@ programa Windows Programa do Windows Software Windows - программа Windows + Программа Windows Softvér Windows Programska oprema za okolje Windows Виндоузов софтвер @@ -39430,9 +40714,9 @@ - - + TriG RDF document + Documentu RDF TriG document TriG RDF dokument Trig RDF TriG RDF-dokument @@ -39443,6 +40727,7 @@ TriG RDF dokumentua TriG RDF -asiakirja document RDF TriG + cáipéis RDF TriG Documento RDF TriG מסמך RDF של TriG TriG RDF dokument @@ -39469,6 +40754,7 @@ TriG RDF Graph Triple Language + @@ -39483,6 +40769,7 @@ Apple Keynote 5 aurkezpena Apple Keynote 5 -esitys présentation Apple Keynote 5 + láithreoireacht Apple Keynote 5 Presentación de Apple Keynote 5 מצגת Apple Keynote 5 Apple Keynote 5 prezentacija @@ -39528,6 +40815,7 @@ Adobe PageMaker Adobe PageMaker Adobe PageMaker + Adobe PageMaker Adobe PageMaker Adobe PageMaker Adobe PageMaker @@ -39568,6 +40856,7 @@ WAD de Doom Doom WAD WAD Doom + WAD Doom Doom WAD Doom WAD WAD pro Doom @@ -39608,6 +40897,7 @@ Amiga disko irudia Amiga-levytiedosto image disque Amiga + íomhá diosca Amiga דמות כונן Amiga Amiga slika diska Amiga lemezkép @@ -39615,18 +40905,18 @@ Image disk Amiga Disco immagine Amiga Amiga диск бейнесі - 아미가 디스크 이미지 + Amiga 디스크 이미지 imatge disc Amiga Obraz dysku Amiga imagem de disco Amiga Imagem de disco Amiga - образ диска Amiga + Образ диска Amiga Obraz disku Amiga слика диска Амиге Amiga-diskavbild Amiga disk kalıbı образ диска Amiga - Amiga 磁盘镜像 + Amiga 磁盘映像 Amiga 磁碟映像檔 @@ -39637,19 +40927,31 @@ Flatpak application bundle paquet d'aplicació Flatpak + balíček Flatpak s aplikací Flatpak-programsamling Flatpak-Anwendungspaket + Flatpak application bundle paquete de aplicación Flatpak + Flatpak aplikazio bilduma + Flatpak-sovelluspaketti lot applicatif Flatpak + burla feidhmchláir Flatpak + חבילת יישומי Flatpak + Flatpak paket aplikacije Flatpak alkalmazáscsomag + bundel aplikasi Flatpak + Bundle applicazione Flatpak Flatpak қолданбалар дестесі Flatpak 프로그램 번들 Pakiet programu Flatpak Pacote de aplicativo Flatpak - пакет приложений Flatpak + Пакет приложения Flatpak Balík aplikácií Flatpak + скуп програма Флатпака + Flatpak-programbunt + Flatpak uygulama paketi пакунок із програмами Flatpak - Flatpak 应用包 + Flatpak 应用组合包 Flatpak 應用程式套組 @@ -39664,17 +40966,29 @@ Flatpak repository description descripció de dipòsit de Flatpak + popis repozitáře Flatpak Flatpak-arkivbeskrivelse Flatpak-Repositoriumsbeschreibung + Flatpak repository description descripción de repositorio de Flatpak + Flatpak biltegi deskribapena + Flatpak-ohjelmistolähdekuvaus description de dépôt Flatpak + cur síos ar stórlann Flatpak + תיאור מאגר Flatpak + Flatpak opis repozitorija Flatpak tárolóleírás + deskripsi repositori Flatpak + Descrizione repository Flatpack Flatpak репозиторийі сипаттамасы Flatpak 저장소 디스크립션 Opis repozytorium Flatpak Descrição de repositório Flatpak - описание репозитория Flatpak + Описание репозитория Flatpak Popis repozitára Flatpak + опис ризнице Флатпака + Flatpak-förrådsbeskrivning + Flatpak depo açıklaması опис сховища Flatpak Flatpak 软件库描述 Flatpak 軟體庫描述 @@ -39688,6 +41002,31 @@ Flatpak repository reference + referència de dipòsit Flatpak + odkaz na repozitář Flatpak + Flatpak-Repositoriumsreferenz + Flatpak repository reference + referencia a repositorio de Flatpak + Flatpak biltegi erreferentzia + Flatpak-ohjelmistolähdeviite + référence de dépôt Flatpak + tagairt do stórlann Flatpak + Flatpak preporučeni repozitorij + Flatpak tárolóhivatkozás + acuan repositori Flatpak + Riferimento repository Flatpack + Flatpak репозиторийіне сілтеме + Flatpak 저장소 참조 + Odwołanie do repozytorium Flatpak + Referência de repositório Flatpak + Ссылка на репозиторий Flatpak + Referencia repozitára Flatpak + упута ризнице Флатпака + Flatpak-förrådsreferens + Flatpak depo başvurusu + посилання на сховище Flatpak + Flatpak 软件库引用 + Flatpak 軟體庫參照 @@ -39699,18 +41038,29 @@ Squashfs filesystem Sistema de fitxers Squashfs + souborový systém Squashfs Squashfs-filsystem Squashfs-Dateisystem + Squashfs filesystem sistema de archivos Squashfs + Squashfs fitxategi sistema + Squashfs-tiedostojärjestelmä système de fichiers Squashfs + córas comhad Squashfs מערכת קבצים Squashfs + Squashfs datotečni sustav Squashfs fájlrendszer + sistem berkas Squashfs + File system squashfs Squashfs файлдық жүйесі Squashfs 파일 시스템 System plików SquashFS Sistema de arquivos Squashfs - файловая система Squashfs + Файловая система Squashfs Systém súborov Squashfs + систем датотека Сквошфс + Squashfs-filsystem + Squashfs dosya sistemi файлова система squashfs Squashfs 文件系统 Squashfs 檔案系統 @@ -39721,21 +41071,77 @@ + + + AppImage application bundle + paquet d'aplicació AppImage + balíček AppImage s aplikací + Applmage-programsamling + AppImage-Anwendungspaket + AppImage application bundle + paquete de aplicación AppImage + AppImage aplikazio bilduma + AppImage-sovelluspaketti + lot applicatif AppImage + burla feidhmchláir AppImage + חבילת יישומי AppImage + AppImage paket aplikacije + AppImage alkalmazáscsomag + bundel aplikasi AppImage + Bundle applicazione AppImage + AppImage қолданбалар дестесі + AppImage 프로그램 번들 + Pakiet programu AppImage + Pacote de aplicativo AppImage + Пакет приложения AppImage + Balík aplikácií AppImage + скуп програма Ап-слике + AppImage-programbunt + AppImage uygulama paketi + пакунок із програмами AppImage + AppImage 应用组合包 + AppImage 應用程式套組 + + + + + + + + + + + + + + + Snap package Paquet Snap + balíček Snap Snap-pakke Snap-Paket + Snap package paquete Snap + Snap paketea + Snap-paketti paquet Snap + pacáiste Snap חבילת Snap + Snap paket Snap-csomag + paket Snap + Pacchetto snap Snap дестесі Snap 패키지 Pakiet Snap Pacote Snap - пакет Snap + Пакет Snap Balík Snap + Снап пакет + Snap-paket + Snap paketi пакунок snap Snap 软件包 Snap 軟體包 @@ -39743,4 +41149,85 @@ + + + STL 3D model + STL + StereoLithography + + + + + + + + + + + G-code file + fitxer G-code + soubor G-code + G-Code-Datei + G-code file + archivo G-code + G-code fitxategia + G-code-tiedosto + fichier G-code + comhad G-code + G-kôd datoteka + G-code fájl + berkas G-code + File G-code + G-code файлы + 지-코드 파일 + Plik G-code + Arquivo G-code + Файл G-code + Súbor G-code + датотека Г-ко̂да + G-code-fil + G-code dosyası + файл G-code + G-code 文件 + G-code 檔案 + + + + + + + Nintendo FDS disk image + Imatge de disc Nintendo FDS + obraz disku pro Nintendo FDS + Nintendo-FDS-Datenträgerabbild + Nintendo FDS disk image + imagen de disco FDS de Nintendo + Nintendo FDS disko irudia + Nintendo FDS -levykuva + image disque Nintendo FDS + íomhá diosca Nintendo FDS + Nintendo FDS slika diska + Nintendo FDS lemezkép + image disk Nintendo FDS + Immagine disco Nintendo FDS + Nintendo FDS диск бейнесі + 닌텐도 FDS 디스크 이미지 + Obraz dysku Nintendo FDS + Imagem de disco Nintendo FDS + Образ диска Nintendo FDS + Obraz disku Nintendo FDS + Нинтендо ФДС слика диска + Nintendo FDS-diskavbild + Nintendo FDS disk kalıbı + образ диска FDS Nintendo + 任天堂 FDS 磁盘映像 + Nintendo FDS 磁碟映像檔 + FDS + Famicom Disk System + + + + + + diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp index 9df52887f7..fd3cc18af5 100644 --- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp +++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp @@ -73,12 +73,12 @@ static inline QString testSuiteWarning() str << "\nCannot find the shared-mime-info test suite\nstarting from: " << QDir::toNativeSeparators(QDir::currentPath()) << "\n" "cd " << QDir::toNativeSeparators(QStringLiteral("tests/auto/corelib/mimetypes/qmimedatabase")) << "\n" - "wget http://cgit.freedesktop.org/xdg/shared-mime-info/snapshot/Release-1-8.zip\n" - "unzip Release-1-8.zip\n"; + "wget http://cgit.freedesktop.org/xdg/shared-mime-info/snapshot/Release-1-10.zip\n" + "unzip Release-1-10.zip\n"; #ifdef Q_OS_WIN - str << "mkdir testfiles\nxcopy /s Release-1-8 s-m-i\n"; + str << "mkdir testfiles\nxcopy /s Release-1-10 s-m-i\n"; #else - str << "ln -s Release-1-8 s-m-i\n"; + str << "ln -s Release-1-10 s-m-i\n"; #endif return result; } @@ -611,7 +611,7 @@ void tst_QMimeDatabase::allMimeTypes() QVERIFY(!lst.isEmpty()); // Hardcoding this is the only way to check both providers find the same number of mimetypes. - QCOMPARE(lst.count(), 749); + QCOMPARE(lst.count(), 779); foreach (const QMimeType &mime, lst) { const QString name = mime.name(); @@ -640,7 +640,7 @@ void tst_QMimeDatabase::suffixes_data() QTest::newRow("mimetype with multiple patterns") << "text/plain" << "*.asc;*.txt;*,v" << "txt"; QTest::newRow("mimetype with uncommon pattern") << "text/x-readme" << "README*" << QString(); QTest::newRow("mimetype with no patterns") << "application/x-ole-storage" << QString() << QString(); - QTest::newRow("default_mimetype") << "application/octet-stream" << "*.bin" << QString(); + QTest::newRow("default_mimetype") << "application/octet-stream" << QString() << QString(); } void tst_QMimeDatabase::suffixes() From e8e8fb5154697132b930ff7a9005eef312511e71 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Fri, 12 Oct 2018 11:11:37 +0200 Subject: [PATCH 0301/1650] QMimeDatabasePrivate: Match shared-mime-info behavior better * Take into account alias when resolving inheritance FAIL! : tst_QMimeDatabase::findByFile(sqlite3.kexi) Compared values are not the same Actual (resultMimeTypeName.toLower()): "application/vnd.sqlite3" Expected (mimeTypeName.toLower()) : "application/x-kexiproject-sqlite3" Loc: [/home/tsdgeos/qt/qtbase_dev/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/../tst_qmimedatabase.cpp(841)] Change-Id: Ie5b095669979efef0b1de4175723190ea1f4d5a0 Reviewed-by: David Faure --- src/corelib/mimetypes/qmimedatabase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp index 50b30a1832..24a7a35ea5 100644 --- a/src/corelib/mimetypes/qmimedatabase.cpp +++ b/src/corelib/mimetypes/qmimedatabase.cpp @@ -422,7 +422,7 @@ bool QMimeDatabasePrivate::inherits(const QString &mime, const QString &parent) toCheck.pop(); const auto parentList = parents(mimeName); for (const QString &par : parentList) - toCheck.push(par); + toCheck.push(resolveAlias(par)); } return false; } From dbffff0116f9618902cf4e9615a0ca6a7a6db9ed Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 8 Nov 2018 10:35:22 +0100 Subject: [PATCH 0302/1650] Support table border color and cellpadding in ODF writer Change-Id: I1d57baa6820ee1322ac461c0db860990ff8f940d Fixes: QTBUG-67622 Reviewed-by: Konstantin Ritt Reviewed-by: Lars Knoll --- src/gui/text/qtextodfwriter.cpp | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp index f5d73affab..1a3f5309ae 100644 --- a/src/gui/text/qtextodfwriter.cpp +++ b/src/gui/text/qtextodfwriter.cpp @@ -886,26 +886,30 @@ void QTextOdfWriter::tableCellStyleElement(QXmlStreamWriter &writer, const int & if (hasBorder) { writer.writeAttribute(foNS, QString::fromLatin1("border"), pixelToPoint(tableFormatTmp.border()) + QLatin1String(" ") - + borderStyleName(tableFormatTmp.borderStyle()) - + QLatin1String(" #000000")); //!! HARD-CODING color black + + borderStyleName(tableFormatTmp.borderStyle()) + QLatin1String(" ") + + tableFormatTmp.borderBrush().color().name(QColor::HexRgb)); } - qreal padding = format.topPadding(); - if (padding > 0 && padding == format.bottomPadding() - && padding == format.leftPadding() && padding == format.rightPadding()) { + qreal topPadding = format.topPadding(); + qreal padding = topPadding + tableFormatTmp.cellPadding(); + if (padding > 0 && topPadding == format.bottomPadding() + && topPadding == format.leftPadding() && topPadding == format.rightPadding()) { writer.writeAttribute(foNS, QString::fromLatin1("padding"), pixelToPoint(padding)); } else { if (padding > 0) writer.writeAttribute(foNS, QString::fromLatin1("padding-top"), pixelToPoint(padding)); - if (format.bottomPadding() > 0) + padding = format.bottomPadding() + tableFormatTmp.cellPadding(); + if (padding > 0) writer.writeAttribute(foNS, QString::fromLatin1("padding-bottom"), - pixelToPoint(format.bottomPadding())); - if (format.leftPadding() > 0) + pixelToPoint(padding)); + padding = format.leftPadding() + tableFormatTmp.cellPadding(); + if (padding > 0) writer.writeAttribute(foNS, QString::fromLatin1("padding-left"), - pixelToPoint(format.leftPadding())); - if (format.rightPadding() > 0) + pixelToPoint(padding)); + padding = format.rightPadding() + tableFormatTmp.cellPadding(); + if (padding > 0) writer.writeAttribute(foNS, QString::fromLatin1("padding-right"), - pixelToPoint(format.rightPadding())); + pixelToPoint(padding)); } if (format.hasProperty(QTextFormat::TextVerticalAlignment)) { From ee3c66ca917b77f759acea7c6b27d15066f0b814 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 12 Nov 2018 15:29:33 +0100 Subject: [PATCH 0303/1650] macOS: Disable threaded GL rendering on SDK 10.14+ AppKit expects rendering to happen on the main thread, or at least any interaction with AppKit UI classes such as NSView. Our OpenGL helpers, such as QOpenGLContext, do not enforce this, and we may end up calling into AppKit UI classes on the render thread, deadlocking the application. Until this can be investigated and new APIs possibly introduced that allow a more fine grained control in our own classes, we disable threaded GL as a capability of the platform, which will inform clients such as QtQuick to use the basic render loop. [ChangeLog][macOS] Threaded OpenGL usage has been disabled when building using Xcode 10/SDK 10.14 and later. Qt Quick defaults to the 'basic' render loop now on macOS. Task-number: QTBUG-71731 Change-Id: I6fc3295e833ecd48ad49382b8275c762fa7978a6 Reviewed-by: Laszlo Agocs Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/platforms/cocoa/qcocoaintegration.mm | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 936fecf8de..1bd1029863 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -340,12 +340,17 @@ QCocoaScreen *QCocoaIntegration::screenForNSScreen(NSScreen *nsScreen) bool QCocoaIntegration::hasCapability(QPlatformIntegration::Capability cap) const { switch (cap) { - case ThreadedPixmaps: #ifndef QT_NO_OPENGL - case OpenGL: case ThreadedOpenGL: + // AppKit expects rendering to happen on the main thread, and we can + // easily end up in situations where rendering on secondary threads + // will result in visual artifacts, bugs, or even deadlocks, when + // building with SDK 10.14 or higher which enbles view layer-backing. + return QMacVersion::buildSDK() < QOperatingSystemVersion(QOperatingSystemVersion::MacOSMojave); + case OpenGL: case BufferQueueingOpenGL: #endif + case ThreadedPixmaps: case WindowMasks: case MultipleWindows: case ForeignWindows: From 24d1565789cbd31ce383ac789bb6d69116a77a09 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 22 Oct 2018 13:42:22 +0200 Subject: [PATCH 0304/1650] uic: Use the Qt configure system when generating code Replace the generation of #ifdef's for the macros by QT_CONFIG checks. Implement it using streamable classes to make it easier to switch the output language later. Task-number: PYSIDE-797 Change-Id: I28b5ed3ec80cd525a3df0cd54d9be4f09149cde4 Reviewed-by: Jarek Kobus --- src/tools/uic/cpp/cppwriteinitialization.cpp | 91 ++++++++------ src/tools/uic/shared/language.cpp | 53 +++++++++ src/tools/uic/shared/language.h | 76 ++++++++++++ src/tools/uic/shared/shared.pri | 5 + src/tools/uic/uic.pro | 1 + .../tools/uic/baseline/browserwidget.ui.h | 8 +- .../tools/uic/baseline/chatmainwindow.ui.h | 24 ++-- tests/auto/tools/uic/baseline/default.ui.h | 56 ++++----- .../tools/uic/baseline/embeddeddialog.ui.h | 4 +- tests/auto/tools/uic/baseline/finddialog.ui.h | 36 +++--- .../uic/baseline/formwindowsettings.ui.h | 4 +- tests/auto/tools/uic/baseline/gridpanel.ui.h | 4 +- tests/auto/tools/uic/baseline/helpdialog.ui.h | 76 ++++++------ tests/auto/tools/uic/baseline/idbased.ui.h | 12 +- .../tools/uic/baseline/languagesdialog.ui.h | 16 +-- .../tools/uic/baseline/listwidgeteditor.ui.h | 20 ++-- tests/auto/tools/uic/baseline/mydialog.ui.h | 4 +- .../tools/uic/baseline/newactiondialog.ui.h | 4 +- .../auto/tools/uic/baseline/orderdialog.ui.h | 8 +- tests/auto/tools/uic/baseline/pagefold.ui.h | 52 ++++---- .../tools/uic/baseline/phrasebookbox.ui.h | 36 +++--- .../tools/uic/baseline/previewdialogbase.ui.h | 4 +- .../auto/tools/uic/baseline/qfiledialog.ui.h | 24 ++-- .../tools/uic/baseline/qpagesetupwidget.ui.h | 36 +++--- .../uic/baseline/qprintsettingsoutput.ui.h | 4 +- .../auto/tools/uic/baseline/qprintwidget.ui.h | 4 +- .../uic/baseline/qsqlconnectiondialog.ui.h | 4 +- .../tools/uic/baseline/qtgradienteditor.ui.h | 112 +++++++++--------- .../uic/baseline/qtresourceeditordialog.ui.h | 16 +-- .../tools/uic/baseline/qttoolbardialog.ui.h | 28 ++--- .../uic/baseline/saveformastemplate.ui.h | 4 +- .../tools/uic/baseline/signalslotdialog.ui.h | 16 +-- .../tools/uic/baseline/stringlisteditor.ui.h | 20 ++-- .../tools/uic/baseline/tablewidgeteditor.ui.h | 44 +++---- tests/auto/tools/uic/baseline/textfinder.ui.h | 4 +- .../auto/tools/uic/baseline/topicchooser.ui.h | 4 +- .../tools/uic/baseline/translatedialog.ui.h | 28 ++--- .../uic/baseline/translationsettings.ui.h | 4 +- .../tools/uic/baseline/treewidgeteditor.ui.h | 52 ++++---- .../tools/uic/baseline/trpreviewtool.ui.h | 4 +- 40 files changed, 578 insertions(+), 424 deletions(-) create mode 100644 src/tools/uic/shared/language.cpp create mode 100644 src/tools/uic/shared/language.h create mode 100644 src/tools/uic/shared/shared.pri diff --git a/src/tools/uic/cpp/cppwriteinitialization.cpp b/src/tools/uic/cpp/cppwriteinitialization.cpp index 4f6ac1eb97..a75aa0abd7 100644 --- a/src/tools/uic/cpp/cppwriteinitialization.cpp +++ b/src/tools/uic/cpp/cppwriteinitialization.cpp @@ -34,6 +34,8 @@ #include "databaseinfo.h" #include "globaldefs.h" +#include + #include #include @@ -172,17 +174,16 @@ namespace { } return true; } - - inline void openIfndef(QTextStream &str, const QString &symbol) { if (!symbol.isEmpty()) str << QLatin1String("#ifndef ") << symbol << endl; } - inline void closeIfndef(QTextStream &str, const QString &symbol) { if (!symbol.isEmpty()) str << QLatin1String("#endif // ") << symbol << endl; } - - const char *accessibilityDefineC = "QT_NO_ACCESSIBILITY"; - const char *toolTipDefineC = "QT_NO_TOOLTIP"; - const char *whatsThisDefineC = "QT_NO_WHATSTHIS"; - const char *statusTipDefineC = "QT_NO_STATUSTIP"; - const char *shortcutDefineC = "QT_NO_SHORTCUT"; } +// QtGui +static inline QString accessibilityConfigKey() { return QStringLiteral("accessibility"); } +static inline QString shortcutConfigKey() { return QStringLiteral("shortcut"); } +static inline QString whatsThisConfigKey() { return QStringLiteral("whatsthis"); } +// QtWidgets +static inline QString statusTipConfigKey() { return QStringLiteral("statustip"); } +static inline QString toolTipConfigKey() { return QStringLiteral("tooltip"); } + namespace CPP { FontHandle::FontHandle(const DomFont *domFont) : @@ -520,7 +521,7 @@ void WriteInitialization::acceptUI(DomUI *node) acceptWidget(node->elementWidget()); if (!m_buddies.empty()) - openIfndef(m_output, QLatin1String(shortcutDefineC)); + m_output << language::openQtConfig(shortcutConfigKey()); for (const Buddy &b : qAsConst(m_buddies)) { if (!m_registeredWidgets.contains(b.objName)) { fprintf(stderr, "%s: Warning: Buddy assignment: '%s' is not a valid widget.\n", @@ -537,7 +538,7 @@ void WriteInitialization::acceptUI(DomUI *node) m_output << m_indent << b.objName << "->setBuddy(" << b.buddy << ");\n"; } if (!m_buddies.empty()) - closeIfndef(m_output, QLatin1String(shortcutDefineC)); + m_output << language::closeQtConfig(shortcutConfigKey()); if (node->elementTabStops()) acceptTabStops(node->elementTabStops()); @@ -1124,6 +1125,23 @@ QString WriteInitialization::writeStringListProperty(const DomStringList *list) return propertyValue; } +static QString configKeyForProperty(const QString &propertyName) +{ + if (propertyName == QLatin1String("toolTip")) + return toolTipConfigKey(); + if (propertyName == QLatin1String("whatsThis")) + return whatsThisConfigKey(); + if (propertyName == QLatin1String("statusTip")) + return statusTipConfigKey(); + if (propertyName == QLatin1String("shortcut")) + return shortcutConfigKey(); + if (propertyName == QLatin1String("accessibleName") + || propertyName == QLatin1String("accessibleDescription")) { + return accessibilityConfigKey(); + } + return QString(); +} + void WriteInitialization::writeProperties(const QString &varName, const QString &className, const DomPropertyList &lst, @@ -1461,28 +1479,18 @@ void WriteInitialization::writeProperties(const QString &varName, } if (propertyValue.size()) { - const char* defineC = 0; - if (propertyName == QLatin1String("toolTip")) - defineC = toolTipDefineC; - else if (propertyName == QLatin1String("whatsThis")) - defineC = whatsThisDefineC; - else if (propertyName == QLatin1String("statusTip")) - defineC = statusTipDefineC; - else if (propertyName == QLatin1String("shortcut")) - defineC = shortcutDefineC; - else if (propertyName == QLatin1String("accessibleName") || propertyName == QLatin1String("accessibleDescription")) - defineC = accessibilityDefineC; + const QString configKey = configKeyForProperty(propertyName); QTextStream &o = delayProperty ? m_delayedOut : autoTrOutput(p); - if (defineC) - openIfndef(o, QLatin1String(defineC)); + if (!configKey.isEmpty()) + o << language::openQtConfig(configKey); o << m_indent << varNewName << setFunction << propertyValue; if (!stdset) o << ')'; o << ");\n"; - if (defineC) - closeIfndef(o, QLatin1String(defineC)); + if (!configKey.isEmpty()) + o << language::closeQtConfig(configKey); if (varName == m_mainFormVarName && &o == &m_refreshOut) { // this is the only place (currently) where we output mainForm name to the retranslateUi(). @@ -2127,9 +2135,12 @@ void WriteInitialization::addCommonInitializers(Item *item, addQtFlagsInitializer(item, properties, QLatin1String("textAlignment"), column); addQtEnumInitializer(item, properties, QLatin1String("checkState"), column); addStringInitializer(item, properties, QLatin1String("text"), column); - addStringInitializer(item, properties, QLatin1String("toolTip"), column, QLatin1String(toolTipDefineC)); - addStringInitializer(item, properties, QLatin1String("whatsThis"), column, QLatin1String(whatsThisDefineC)); - addStringInitializer(item, properties, QLatin1String("statusTip"), column, QLatin1String(statusTipDefineC)); + addStringInitializer(item, properties, QLatin1String("toolTip"), column, + toolTipConfigKey()); + addStringInitializer(item, properties, QLatin1String("whatsThis"), column, + whatsThisConfigKey()); + addStringInitializer(item, properties, QLatin1String("statusTip"), column, + statusTipConfigKey()); } void WriteInitialization::initializeListWidget(DomWidget *w) @@ -2466,7 +2477,7 @@ static void generateMultiDirectiveBegin(QTextStream &outputStream, const QSet &directives) @@ -2531,9 +2545,11 @@ QString WriteInitialization::Item::writeSetupUi(const QString &parent, Item::Emp QMultiMap::ConstIterator it = m_setupUiData.setters.constBegin(); while (it != m_setupUiData.setters.constEnd()) { - openIfndef(m_setupUiStream, it.key()); + if (!it.key().isEmpty()) + m_setupUiStream << language::openQtConfig(it.key()); m_setupUiStream << m_indent << uniqueName << it.value() << endl; - closeIfndef(m_setupUiStream, it.key()); + if (!it.key().isEmpty()) + m_setupUiStream << language::closeQtConfig(it.key()); ++it; } for (Item *child : qAsConst(m_children)) @@ -2560,14 +2576,17 @@ void WriteInitialization::Item::writeRetranslateUi(const QString &parentPath) while (it != m_retranslateUiData.setters.constEnd()) { const QString newDirective = it.key(); if (oldDirective != newDirective) { - closeIfndef(m_retranslateUiStream, oldDirective); - openIfndef(m_retranslateUiStream, newDirective); + if (!oldDirective.isEmpty()) + m_retranslateUiStream << language::closeQtConfig(oldDirective); + if (!newDirective.isEmpty()) + m_retranslateUiStream << language::openQtConfig(newDirective); oldDirective = newDirective; } m_retranslateUiStream << m_indent << uniqueName << it.value() << endl; ++it; } - closeIfndef(m_retranslateUiStream, oldDirective); + if (!oldDirective.isEmpty()) + m_retranslateUiStream << language::closeQtConfig(oldDirective); for (int i = 0; i < m_children.size(); i++) m_children[i]->writeRetranslateUi(uniqueName + QLatin1String("->child(") + QString::number(i) + QLatin1Char(')')); diff --git a/src/tools/uic/shared/language.cpp b/src/tools/uic/shared/language.cpp new file mode 100644 index 0000000000..2ab89c2d7b --- /dev/null +++ b/src/tools/uic/shared/language.cpp @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "language.h" + +#include + +namespace language { + +QTextStream &operator<<(QTextStream &str, const qtConfig &c) +{ + str << "QT_CONFIG(" << c.parameter() << ')'; + return str; +} + +QTextStream &operator<<(QTextStream &str, const openQtConfig &c) +{ + str << "#if " << qtConfig(c.parameter()) << '\n'; + return str; +} + +QTextStream &operator<<(QTextStream &str, const closeQtConfig &c) +{ + str << "#endif // " << qtConfig(c.parameter()) << '\n'; + return str; +} + +} // namespace language diff --git a/src/tools/uic/shared/language.h b/src/tools/uic/shared/language.h new file mode 100644 index 0000000000..71cfddd6b0 --- /dev/null +++ b/src/tools/uic/shared/language.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef LANGUAGE_H +#define LANGUAGE_H + +#include + +QT_FORWARD_DECLARE_CLASS(QTextStream) + +namespace language { + +// Base class for streamable objects with one QStringView parameter +class StringViewStreamable +{ +public: + StringViewStreamable(QStringView parameter) : m_parameter(parameter) {} + + QStringView parameter() const { return m_parameter; } + +private: + QStringView m_parameter; +}; + +class qtConfig : public StringViewStreamable +{ +public: + qtConfig(QStringView name) : StringViewStreamable(name) {} +}; + +QTextStream &operator<<(QTextStream &str, const qtConfig &c); + +class openQtConfig : public StringViewStreamable +{ +public: + openQtConfig(QStringView name) : StringViewStreamable(name) {} +}; + +QTextStream &operator<<(QTextStream &str, const openQtConfig &c); + +class closeQtConfig : public StringViewStreamable +{ +public: + closeQtConfig(QStringView name) : StringViewStreamable(name) {} +}; + +QTextStream &operator<<(QTextStream &, const closeQtConfig &c); + +} // namespace language + +#endif // LANGUAGE_H diff --git a/src/tools/uic/shared/shared.pri b/src/tools/uic/shared/shared.pri new file mode 100644 index 0000000000..dce2af8bf1 --- /dev/null +++ b/src/tools/uic/shared/shared.pri @@ -0,0 +1,5 @@ +INCLUDEPATH += $$PWD + +HEADERS += $$PWD/language.h + +SOURCES += $$PWD/language.cpp diff --git a/src/tools/uic/uic.pro b/src/tools/uic/uic.pro index 18511395d9..4469ce50e5 100644 --- a/src/tools/uic/uic.pro +++ b/src/tools/uic/uic.pro @@ -5,6 +5,7 @@ option(host_build) DEFINES += QT_UIC QT_NO_CAST_FROM_ASCII QT_NO_FOREACH include(uic.pri) +include(shared/shared.pri) include(cpp/cpp.pri) HEADERS += uic.h diff --git a/tests/auto/tools/uic/baseline/browserwidget.ui.h b/tests/auto/tools/uic/baseline/browserwidget.ui.h index 3db93c34cf..7b666858b0 100644 --- a/tests/auto/tools/uic/baseline/browserwidget.ui.h +++ b/tests/auto/tools/uic/baseline/browserwidget.ui.h @@ -157,13 +157,13 @@ public: { Browser->setWindowTitle(QApplication::translate("Browser", "Qt SQL Browser", nullptr)); insertRowAction->setText(QApplication::translate("Browser", "&Insert Row", nullptr)); -#ifndef QT_NO_STATUSTIP +#if QT_CONFIG(statustip) insertRowAction->setStatusTip(QApplication::translate("Browser", "Inserts a new Row", nullptr)); -#endif // QT_NO_STATUSTIP +#endif // QT_CONFIG(statustip) deleteRowAction->setText(QApplication::translate("Browser", "&Delete Row", nullptr)); -#ifndef QT_NO_STATUSTIP +#if QT_CONFIG(statustip) deleteRowAction->setStatusTip(QApplication::translate("Browser", "Deletes the current Row", nullptr)); -#endif // QT_NO_STATUSTIP +#endif // QT_CONFIG(statustip) groupBox->setTitle(QApplication::translate("Browser", "SQL Query", nullptr)); clearButton->setText(QApplication::translate("Browser", "&Clear", nullptr)); submitButton->setText(QApplication::translate("Browser", "&Submit", nullptr)); diff --git a/tests/auto/tools/uic/baseline/chatmainwindow.ui.h b/tests/auto/tools/uic/baseline/chatmainwindow.ui.h index 8d4ccd53ae..2264dc8c32 100644 --- a/tests/auto/tools/uic/baseline/chatmainwindow.ui.h +++ b/tests/auto/tools/uic/baseline/chatmainwindow.ui.h @@ -125,9 +125,9 @@ public: statusbar = new QStatusBar(ChatMainWindow); statusbar->setObjectName(QString::fromUtf8("statusbar")); ChatMainWindow->setStatusBar(statusbar); -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) label->setBuddy(messageLineEdit); -#endif // QT_NO_SHORTCUT +#endif // QT_CONFIG(shortcut) QWidget::setTabOrder(chatHistory, messageLineEdit); QWidget::setTabOrder(messageLineEdit, sendButton); @@ -149,24 +149,24 @@ public: { ChatMainWindow->setWindowTitle(QApplication::translate("ChatMainWindow", "Qt D-Bus Chat", nullptr)); actionQuit->setText(QApplication::translate("ChatMainWindow", "Quit", nullptr)); -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) actionQuit->setShortcut(QApplication::translate("ChatMainWindow", "Ctrl+Q", nullptr)); -#endif // QT_NO_SHORTCUT +#endif // QT_CONFIG(shortcut) actionAboutQt->setText(QApplication::translate("ChatMainWindow", "About Qt...", nullptr)); actionChangeNickname->setText(QApplication::translate("ChatMainWindow", "Change nickname...", nullptr)); -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) actionChangeNickname->setShortcut(QApplication::translate("ChatMainWindow", "Ctrl+N", nullptr)); -#endif // QT_NO_SHORTCUT -#ifndef QT_NO_TOOLTIP +#endif // QT_CONFIG(shortcut) +#if QT_CONFIG(tooltip) chatHistory->setToolTip(QApplication::translate("ChatMainWindow", "Messages sent and received from other users", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) label->setText(QApplication::translate("ChatMainWindow", "Message:", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) sendButton->setToolTip(QApplication::translate("ChatMainWindow", "Sends a message to other people", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_WHATSTHIS +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(whatsthis) sendButton->setWhatsThis(QString()); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) sendButton->setText(QApplication::translate("ChatMainWindow", "Send", nullptr)); menuQuit->setTitle(QApplication::translate("ChatMainWindow", "Help", nullptr)); menuFile->setTitle(QApplication::translate("ChatMainWindow", "File", nullptr)); diff --git a/tests/auto/tools/uic/baseline/default.ui.h b/tests/auto/tools/uic/baseline/default.ui.h index fafff9d728..43de3c2f7c 100644 --- a/tests/auto/tools/uic/baseline/default.ui.h +++ b/tests/auto/tools/uic/baseline/default.ui.h @@ -192,13 +192,13 @@ public: statusbar = new QStatusBar(MainWindow); statusbar->setObjectName(QString::fromUtf8("statusbar")); MainWindow->setStatusBar(statusbar); -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) nameLabel->setBuddy(nameCombo); ageLabel->setBuddy(ageSpinBox); passwordLabel->setBuddy(passwordEdit); label->setBuddy(professionList); countryLabel->setBuddy(professionList); -#endif // QT_NO_SHORTCUT +#endif // QT_CONFIG(shortcut) QWidget::setTabOrder(maleRadioButton, femaleRadioButton); QWidget::setTabOrder(femaleRadioButton, ageSpinBox); QWidget::setTabOrder(ageSpinBox, passwordEdit); @@ -237,36 +237,36 @@ public: nameCombo->setItemText(2, QApplication::translate("MainWindow", "Simon", nullptr)); nameCombo->setItemText(3, QApplication::translate("MainWindow", "Zack", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) nameCombo->setToolTip(QApplication::translate("MainWindow", "Specify your name", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(tooltip) femaleRadioButton->setToolTip(QApplication::translate("MainWindow", "Check this if you are female", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) femaleRadioButton->setText(QApplication::translate("MainWindow", "&Female", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) agreeCheckBox->setToolTip(QApplication::translate("MainWindow", "Please read the license before checking this", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) agreeCheckBox->setText(QApplication::translate("MainWindow", "I &accept the terms and conditions", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) maleRadioButton->setToolTip(QApplication::translate("MainWindow", "Check this if you are male", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) maleRadioButton->setText(QApplication::translate("MainWindow", "&Male", nullptr)); genderLabel->setText(QApplication::translate("MainWindow", "Gender:", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) ageSpinBox->setToolTip(QApplication::translate("MainWindow", "Specify your age", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_STATUSTIP +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(statustip) ageSpinBox->setStatusTip(QApplication::translate("MainWindow", "Specify your age here", nullptr)); -#endif // QT_NO_STATUSTIP +#endif // QT_CONFIG(statustip) ageLabel->setText(QApplication::translate("MainWindow", "&Age:", nullptr)); passwordLabel->setText(QApplication::translate("MainWindow", "&Password:", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) passwordEdit->setToolTip(QApplication::translate("MainWindow", "Specify your password", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_STATUSTIP +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(statustip) passwordEdit->setStatusTip(QApplication::translate("MainWindow", "Specify your password here", nullptr)); -#endif // QT_NO_STATUSTIP +#endif // QT_CONFIG(statustip) passwordEdit->setText(QApplication::translate("MainWindow", "Password", nullptr)); label->setText(QApplication::translate("MainWindow", "Profession", nullptr)); countryLabel->setText(QApplication::translate("MainWindow", "&Country", nullptr)); @@ -281,27 +281,27 @@ public: ___qlistwidgetitem2->setText(QApplication::translate("MainWindow", "Fisherman", nullptr)); professionList->setSortingEnabled(__sortingEnabled); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) professionList->setToolTip(QApplication::translate("MainWindow", "Select your profession", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_STATUSTIP +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(statustip) professionList->setStatusTip(QApplication::translate("MainWindow", "Select your profession", nullptr)); -#endif // QT_NO_STATUSTIP -#ifndef QT_NO_WHATSTHIS +#endif // QT_CONFIG(statustip) +#if QT_CONFIG(whatsthis) professionList->setWhatsThis(QApplication::translate("MainWindow", "Select your profession", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) countryCombo->setItemText(0, QApplication::translate("MainWindow", "Germany", nullptr)); countryCombo->setItemText(1, QApplication::translate("MainWindow", "India", nullptr)); countryCombo->setItemText(2, QApplication::translate("MainWindow", "Norway", nullptr)); countryCombo->setItemText(3, QApplication::translate("MainWindow", "United States Of America", nullptr)); countryCombo->setItemText(4, QApplication::translate("MainWindow", "United Kingdom", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) countryCombo->setToolTip(QApplication::translate("MainWindow", "Specify your country", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_STATUSTIP +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(statustip) countryCombo->setStatusTip(QApplication::translate("MainWindow", "Specify your country here", nullptr)); -#endif // QT_NO_STATUSTIP +#endif // QT_CONFIG(statustip) menu_File->setTitle(QApplication::translate("MainWindow", "&File", nullptr)); menu_Help->setTitle(QApplication::translate("MainWindow", "&Help", nullptr)); } // retranslateUi diff --git a/tests/auto/tools/uic/baseline/embeddeddialog.ui.h b/tests/auto/tools/uic/baseline/embeddeddialog.ui.h index 194ff578e8..7e6bf06df4 100644 --- a/tests/auto/tools/uic/baseline/embeddeddialog.ui.h +++ b/tests/auto/tools/uic/baseline/embeddeddialog.ui.h @@ -83,12 +83,12 @@ public: formLayout->setWidget(3, QFormLayout::FieldRole, spacing); -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) label->setBuddy(layoutDirection); label_2->setBuddy(fontComboBox); label_3->setBuddy(style); label_4->setBuddy(spacing); -#endif // QT_NO_SHORTCUT +#endif // QT_CONFIG(shortcut) retranslateUi(embeddedDialog); diff --git a/tests/auto/tools/uic/baseline/finddialog.ui.h b/tests/auto/tools/uic/baseline/finddialog.ui.h index a427be3614..21be24f111 100644 --- a/tests/auto/tools/uic/baseline/finddialog.ui.h +++ b/tests/auto/tools/uic/baseline/finddialog.ui.h @@ -172,9 +172,9 @@ public: hboxLayout->addLayout(vboxLayout1); -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) findWhat->setBuddy(led); -#endif // QT_NO_SHORTCUT +#endif // QT_CONFIG(shortcut) QWidget::setTabOrder(led, findNxt); QWidget::setTabOrder(findNxt, cancel); QWidget::setTabOrder(cancel, comments); @@ -194,38 +194,38 @@ public: void retranslateUi(QDialog *FindDialog) { FindDialog->setWindowTitle(QApplication::translate("FindDialog", "Find", nullptr)); -#ifndef QT_NO_WHATSTHIS +#if QT_CONFIG(whatsthis) FindDialog->setWhatsThis(QApplication::translate("FindDialog", "This window allows you to search for some text in the translation source file.", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) findWhat->setText(QApplication::translate("FindDialog", "&Find what:", nullptr)); -#ifndef QT_NO_WHATSTHIS +#if QT_CONFIG(whatsthis) led->setWhatsThis(QApplication::translate("FindDialog", "Type in the text to search for.", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) groupBox->setTitle(QApplication::translate("FindDialog", "Options", nullptr)); -#ifndef QT_NO_WHATSTHIS +#if QT_CONFIG(whatsthis) sourceText->setWhatsThis(QApplication::translate("FindDialog", "Source texts are searched when checked.", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) sourceText->setText(QApplication::translate("FindDialog", "&Source texts", nullptr)); -#ifndef QT_NO_WHATSTHIS +#if QT_CONFIG(whatsthis) translations->setWhatsThis(QApplication::translate("FindDialog", "Translations are searched when checked.", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) translations->setText(QApplication::translate("FindDialog", "&Translations", nullptr)); -#ifndef QT_NO_WHATSTHIS +#if QT_CONFIG(whatsthis) matchCase->setWhatsThis(QApplication::translate("FindDialog", "Texts such as 'TeX' and 'tex' are considered as different when checked.", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) matchCase->setText(QApplication::translate("FindDialog", "&Match case", nullptr)); -#ifndef QT_NO_WHATSTHIS +#if QT_CONFIG(whatsthis) comments->setWhatsThis(QApplication::translate("FindDialog", "Comments and contexts are searched when checked.", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) comments->setText(QApplication::translate("FindDialog", "&Comments", nullptr)); ignoreAccelerators->setText(QApplication::translate("FindDialog", "Ignore &accelerators", nullptr)); -#ifndef QT_NO_WHATSTHIS +#if QT_CONFIG(whatsthis) findNxt->setWhatsThis(QApplication::translate("FindDialog", "Click here to find the next occurrence of the text you typed in.", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) findNxt->setText(QApplication::translate("FindDialog", "Find Next", nullptr)); -#ifndef QT_NO_WHATSTHIS +#if QT_CONFIG(whatsthis) cancel->setWhatsThis(QApplication::translate("FindDialog", "Click here to close this window.", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) cancel->setText(QApplication::translate("FindDialog", "Cancel", nullptr)); } // retranslateUi diff --git a/tests/auto/tools/uic/baseline/formwindowsettings.ui.h b/tests/auto/tools/uic/baseline/formwindowsettings.ui.h index d2cfa03edb..b25055b545 100644 --- a/tests/auto/tools/uic/baseline/formwindowsettings.ui.h +++ b/tests/auto/tools/uic/baseline/formwindowsettings.ui.h @@ -250,12 +250,12 @@ public: gridLayout->addWidget(gridPanel, 1, 0, 1, 2); -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) label_2->setBuddy(defaultSpacingSpinBox); label->setBuddy(defaultMarginSpinBox); label_3->setBuddy(marginFunctionLineEdit); label_3_2->setBuddy(spacingFunctionLineEdit); -#endif // QT_NO_SHORTCUT +#endif // QT_CONFIG(shortcut) QWidget::setTabOrder(authorLineEdit, defaultMarginSpinBox); QWidget::setTabOrder(defaultMarginSpinBox, defaultSpacingSpinBox); QWidget::setTabOrder(defaultSpacingSpinBox, marginFunctionLineEdit); diff --git a/tests/auto/tools/uic/baseline/gridpanel.ui.h b/tests/auto/tools/uic/baseline/gridpanel.ui.h index 858b71d0cc..94d4bc943e 100644 --- a/tests/auto/tools/uic/baseline/gridpanel.ui.h +++ b/tests/auto/tools/uic/baseline/gridpanel.ui.h @@ -120,10 +120,10 @@ public: vboxLayout->addWidget(m_gridGroupBox); -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) label->setBuddy(m_deltaXSpinBox); label_2->setBuddy(m_deltaYSpinBox); -#endif // QT_NO_SHORTCUT +#endif // QT_CONFIG(shortcut) retranslateUi(qdesigner_internal__GridPanel); diff --git a/tests/auto/tools/uic/baseline/helpdialog.ui.h b/tests/auto/tools/uic/baseline/helpdialog.ui.h index abcf280cf9..7a3fced1db 100644 --- a/tests/auto/tools/uic/baseline/helpdialog.ui.h +++ b/tests/auto/tools/uic/baseline/helpdialog.ui.h @@ -273,11 +273,11 @@ public: vboxLayout->addWidget(framePrepare); -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) TextLabel1->setBuddy(editIndex); TextLabel1_2->setBuddy(termsEdit); TextLabel2->setBuddy(resultBox); -#endif // QT_NO_SHORTCUT +#endif // QT_CONFIG(shortcut) QWidget::setTabOrder(tabWidget, listContents); QWidget::setTabOrder(listContents, editIndex); QWidget::setTabOrder(editIndex, listIndex); @@ -297,73 +297,73 @@ public: void retranslateUi(QWidget *HelpDialog) { HelpDialog->setWindowTitle(QApplication::translate("HelpDialog", "Help", nullptr)); -#ifndef QT_NO_WHATSTHIS +#if QT_CONFIG(whatsthis) HelpDialog->setWhatsThis(QApplication::translate("HelpDialog", "Help

    Choose the topic you want help on from the contents list, or search the index for keywords.

    ", nullptr)); -#endif // QT_NO_WHATSTHIS -#ifndef QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) +#if QT_CONFIG(whatsthis) tabWidget->setWhatsThis(QApplication::translate("HelpDialog", "Displays help topics organized by category, index or bookmarks. Another tab inherits the full text search.", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) QTreeWidgetItem *___qtreewidgetitem = listContents->headerItem(); ___qtreewidgetitem->setText(0, QApplication::translate("HelpDialog", "column 1", nullptr)); -#ifndef QT_NO_WHATSTHIS +#if QT_CONFIG(whatsthis) listContents->setWhatsThis(QApplication::translate("HelpDialog", "Help topics organized by category.

    Double-click an item to see the topics in that category. To view a topic, just double-click it.

    ", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) tabWidget->setTabText(tabWidget->indexOf(contentPage), QApplication::translate("HelpDialog", "Con&tents", nullptr)); TextLabel1->setText(QApplication::translate("HelpDialog", "&Look For:", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) editIndex->setToolTip(QApplication::translate("HelpDialog", "Enter keyword", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_WHATSTHIS +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(whatsthis) editIndex->setWhatsThis(QApplication::translate("HelpDialog", "Enter a keyword.

    The list will select an item that matches the entered string best.

    ", nullptr)); -#endif // QT_NO_WHATSTHIS -#ifndef QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) +#if QT_CONFIG(whatsthis) listIndex->setWhatsThis(QApplication::translate("HelpDialog", "List of available help topics.

    Double-click on an item to open its help page. If more than one is found, you must specify which page you want.

    ", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) tabWidget->setTabText(tabWidget->indexOf(indexPage), QApplication::translate("HelpDialog", "&Index", nullptr)); QTreeWidgetItem *___qtreewidgetitem1 = listBookmarks->headerItem(); ___qtreewidgetitem1->setText(0, QApplication::translate("HelpDialog", "column 1", nullptr)); -#ifndef QT_NO_WHATSTHIS +#if QT_CONFIG(whatsthis) listBookmarks->setWhatsThis(QApplication::translate("HelpDialog", "Displays the list of bookmarks.", nullptr)); -#endif // QT_NO_WHATSTHIS -#ifndef QT_NO_TOOLTIP +#endif // QT_CONFIG(whatsthis) +#if QT_CONFIG(tooltip) buttonAdd->setToolTip(QApplication::translate("HelpDialog", "Add new bookmark", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_WHATSTHIS +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(whatsthis) buttonAdd->setWhatsThis(QApplication::translate("HelpDialog", "Add the currently displayed page as a new bookmark.", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) buttonAdd->setText(QApplication::translate("HelpDialog", "&New", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) buttonRemove->setToolTip(QApplication::translate("HelpDialog", "Delete bookmark", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_WHATSTHIS +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(whatsthis) buttonRemove->setWhatsThis(QApplication::translate("HelpDialog", "Delete the selected bookmark.", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) buttonRemove->setText(QApplication::translate("HelpDialog", "&Delete", nullptr)); tabWidget->setTabText(tabWidget->indexOf(bookmarkPage), QApplication::translate("HelpDialog", "&Bookmarks", nullptr)); TextLabel1_2->setText(QApplication::translate("HelpDialog", "Searching f&or:", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) termsEdit->setToolTip(QApplication::translate("HelpDialog", "Enter searchword(s).", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_WHATSTHIS +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(whatsthis) termsEdit->setWhatsThis(QApplication::translate("HelpDialog", "Enter search word(s).

    Enter here the word(s) you are looking for. The words may contain wildcards (*). For a sequence of words quote them.

    ", nullptr)); -#endif // QT_NO_WHATSTHIS -#ifndef QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) +#if QT_CONFIG(whatsthis) resultBox->setWhatsThis(QApplication::translate("HelpDialog", "Found documents

    This list contains all found documents from the last search. The documents are ordered, i.e. the first document has the most matches.

    ", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) TextLabel2->setText(QApplication::translate("HelpDialog", "Found &Documents:", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) helpButton->setToolTip(QApplication::translate("HelpDialog", "Display the help page.", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_WHATSTHIS +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(whatsthis) helpButton->setWhatsThis(QApplication::translate("HelpDialog", "Display the help page for the full text search.", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) helpButton->setText(QApplication::translate("HelpDialog", "He&lp", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) searchButton->setToolTip(QApplication::translate("HelpDialog", "Start searching.", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_WHATSTHIS +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(whatsthis) searchButton->setWhatsThis(QApplication::translate("HelpDialog", "Pressing this button starts the search.", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) searchButton->setText(QApplication::translate("HelpDialog", "&Search", nullptr)); tabWidget->setTabText(tabWidget->indexOf(searchPage), QApplication::translate("HelpDialog", "&Search", nullptr)); labelPrepare->setText(QApplication::translate("HelpDialog", "Preparing...", nullptr)); diff --git a/tests/auto/tools/uic/baseline/idbased.ui.h b/tests/auto/tools/uic/baseline/idbased.ui.h index e246313e11..c463a47fc8 100644 --- a/tests/auto/tools/uic/baseline/idbased.ui.h +++ b/tests/auto/tools/uic/baseline/idbased.ui.h @@ -44,15 +44,15 @@ public: void retranslateUi(QWidget *Form) { Form->setWindowTitle(qtTrId("windowTitleId")); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) pushButton->setToolTip(qtTrId("buttonToolTipId")); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_STATUSTIP +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(statustip) pushButton->setStatusTip(qtTrId("buttonStatusTipId")); -#endif // QT_NO_STATUSTIP -#ifndef QT_NO_WHATSTHIS +#endif // QT_CONFIG(statustip) +#if QT_CONFIG(whatsthis) pushButton->setWhatsThis(qtTrId("buttonWhatsThisId")); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) pushButton->setText(qtTrId("buttonTextId")); } // retranslateUi diff --git a/tests/auto/tools/uic/baseline/languagesdialog.ui.h b/tests/auto/tools/uic/baseline/languagesdialog.ui.h index cf2599fd07..216b610271 100644 --- a/tests/auto/tools/uic/baseline/languagesdialog.ui.h +++ b/tests/auto/tools/uic/baseline/languagesdialog.ui.h @@ -112,33 +112,33 @@ public: QTreeWidgetItem *___qtreewidgetitem = languagesList->headerItem(); ___qtreewidgetitem->setText(1, QApplication::translate("LanguagesDialog", "File", nullptr)); ___qtreewidgetitem->setText(0, QApplication::translate("LanguagesDialog", "Locale", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) upButton->setToolTip(QApplication::translate("LanguagesDialog", "\n" "

    Move selected language up

    ", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) upButton->setText(QApplication::translate("LanguagesDialog", "up", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) downButton->setToolTip(QApplication::translate("LanguagesDialog", "\n" "

    Move selected language down

    ", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) downButton->setText(QApplication::translate("LanguagesDialog", "down", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) removeButton->setToolTip(QApplication::translate("LanguagesDialog", "\n" "

    Remove selected language

    ", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) removeButton->setText(QApplication::translate("LanguagesDialog", "remove", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) openFileButton->setToolTip(QApplication::translate("LanguagesDialog", "\n" "

    Open auxiliary language files

    ", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) openFileButton->setText(QApplication::translate("LanguagesDialog", "...", nullptr)); okButton->setText(QApplication::translate("LanguagesDialog", "OK", nullptr)); } // retranslateUi diff --git a/tests/auto/tools/uic/baseline/listwidgeteditor.ui.h b/tests/auto/tools/uic/baseline/listwidgeteditor.ui.h index 14067ced18..93d9c78901 100644 --- a/tests/auto/tools/uic/baseline/listwidgeteditor.ui.h +++ b/tests/auto/tools/uic/baseline/listwidgeteditor.ui.h @@ -174,24 +174,24 @@ public: { qdesigner_internal__ListWidgetEditor->setWindowTitle(QApplication::translate("qdesigner_internal::ListWidgetEditor", "Dialog", nullptr)); groupBox->setTitle(QApplication::translate("qdesigner_internal::ListWidgetEditor", "Items List", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) listWidget->setToolTip(QApplication::translate("qdesigner_internal::ListWidgetEditor", "Items List", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(tooltip) newItemButton->setToolTip(QApplication::translate("qdesigner_internal::ListWidgetEditor", "New Item", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) newItemButton->setText(QApplication::translate("qdesigner_internal::ListWidgetEditor", "&New", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) deleteItemButton->setToolTip(QApplication::translate("qdesigner_internal::ListWidgetEditor", "Delete Item", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) deleteItemButton->setText(QApplication::translate("qdesigner_internal::ListWidgetEditor", "&Delete", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) moveItemUpButton->setToolTip(QApplication::translate("qdesigner_internal::ListWidgetEditor", "Move Item Up", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) moveItemUpButton->setText(QApplication::translate("qdesigner_internal::ListWidgetEditor", "U", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) moveItemDownButton->setToolTip(QApplication::translate("qdesigner_internal::ListWidgetEditor", "Move Item Down", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) moveItemDownButton->setText(QApplication::translate("qdesigner_internal::ListWidgetEditor", "D", nullptr)); label->setText(QApplication::translate("qdesigner_internal::ListWidgetEditor", "Icon", nullptr)); } // retranslateUi diff --git a/tests/auto/tools/uic/baseline/mydialog.ui.h b/tests/auto/tools/uic/baseline/mydialog.ui.h index 1a784d1b0a..daa06528e8 100644 --- a/tests/auto/tools/uic/baseline/mydialog.ui.h +++ b/tests/auto/tools/uic/baseline/mydialog.ui.h @@ -59,9 +59,9 @@ public: MyDialog->setWindowTitle(QApplication::translate("MyDialog", "Mach 2!", nullptr)); aLabel->setText(QApplication::translate("MyDialog", "Join the life in the fastlane; - PCH enable your project today! -", nullptr)); aButton->setText(QApplication::translate("MyDialog", "&Quit", nullptr)); -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) aButton->setShortcut(QApplication::translate("MyDialog", "Alt+Q", nullptr)); -#endif // QT_NO_SHORTCUT +#endif // QT_CONFIG(shortcut) } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/newactiondialog.ui.h b/tests/auto/tools/uic/baseline/newactiondialog.ui.h index ca99ab8356..d3d55f7a2a 100644 --- a/tests/auto/tools/uic/baseline/newactiondialog.ui.h +++ b/tests/auto/tools/uic/baseline/newactiondialog.ui.h @@ -143,11 +143,11 @@ public: verticalLayout->addWidget(buttonBox); -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) label->setBuddy(editActionText); label_3->setBuddy(editObjectName); label_2->setBuddy(iconSelector); -#endif // QT_NO_SHORTCUT +#endif // QT_CONFIG(shortcut) QWidget::setTabOrder(editActionText, editObjectName); retranslateUi(qdesigner_internal__NewActionDialog); diff --git a/tests/auto/tools/uic/baseline/orderdialog.ui.h b/tests/auto/tools/uic/baseline/orderdialog.ui.h index 0ee08257f4..8cce528e1e 100644 --- a/tests/auto/tools/uic/baseline/orderdialog.ui.h +++ b/tests/auto/tools/uic/baseline/orderdialog.ui.h @@ -132,12 +132,12 @@ public: { qdesigner_internal__OrderDialog->setWindowTitle(QApplication::translate("qdesigner_internal::OrderDialog", "Change Page Order", nullptr)); groupBox->setTitle(QApplication::translate("qdesigner_internal::OrderDialog", "Page Order", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) upButton->setToolTip(QApplication::translate("qdesigner_internal::OrderDialog", "Move page up", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(tooltip) downButton->setToolTip(QApplication::translate("qdesigner_internal::OrderDialog", "Move page down", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/pagefold.ui.h b/tests/auto/tools/uic/baseline/pagefold.ui.h index c1ff03648d..684b365866 100644 --- a/tests/auto/tools/uic/baseline/pagefold.ui.h +++ b/tests/auto/tools/uic/baseline/pagefold.ui.h @@ -213,13 +213,13 @@ public: statusbar = new QStatusBar(MainWindow); statusbar->setObjectName(QString::fromUtf8("statusbar")); MainWindow->setStatusBar(statusbar); -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) ageLabel->setBuddy(ageSpinBox); nameLabel->setBuddy(nameCombo); passwordLabel->setBuddy(passwordEdit); label->setBuddy(professionList); countryLabel->setBuddy(professionList); -#endif // QT_NO_SHORTCUT +#endif // QT_CONFIG(shortcut) menubar->addAction(menu_File->menuAction()); menubar->addAction(menu_Help->menuAction()); @@ -252,35 +252,35 @@ public: nameCombo->setItemText(2, QApplication::translate("MainWindow", "Simon", nullptr)); nameCombo->setItemText(3, QApplication::translate("MainWindow", "Zack", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) nameCombo->setToolTip(QApplication::translate("MainWindow", "Specify your name", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) femaleRadioButton->setStyleSheet(QApplication::translate("MainWindow", "Check this if you are female", nullptr)); femaleRadioButton->setText(QApplication::translate("MainWindow", "&Female", nullptr)); genderLabel->setText(QApplication::translate("MainWindow", "Gender:", nullptr)); ageLabel->setText(QApplication::translate("MainWindow", "&Age:", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) maleRadioButton->setToolTip(QApplication::translate("MainWindow", "Check this if you are male", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) maleRadioButton->setText(QApplication::translate("MainWindow", "&Male", nullptr)); nameLabel->setText(QApplication::translate("MainWindow", "&Name:", nullptr)); passwordLabel->setText(QApplication::translate("MainWindow", "&Password:", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) ageSpinBox->setToolTip(QApplication::translate("MainWindow", "Specify your age", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_STATUSTIP +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(statustip) ageSpinBox->setStatusTip(QApplication::translate("MainWindow", "Specify your age", nullptr)); -#endif // QT_NO_STATUSTIP -#ifndef QT_NO_TOOLTIP +#endif // QT_CONFIG(statustip) +#if QT_CONFIG(tooltip) agreeCheckBox->setToolTip(QApplication::translate("MainWindow", "Please read the LICENSE file before checking", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) agreeCheckBox->setText(QApplication::translate("MainWindow", "I &accept the terms and &conditions", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) passwordEdit->setToolTip(QApplication::translate("MainWindow", "Specify your password", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_STATUSTIP +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(statustip) passwordEdit->setStatusTip(QApplication::translate("MainWindow", "Specify your password", nullptr)); -#endif // QT_NO_STATUSTIP +#endif // QT_CONFIG(statustip) passwordEdit->setText(QApplication::translate("MainWindow", "Password", nullptr)); const bool __sortingEnabled = professionList->isSortingEnabled(); @@ -293,15 +293,15 @@ public: ___qlistwidgetitem2->setText(QApplication::translate("MainWindow", "Fisherman", nullptr)); professionList->setSortingEnabled(__sortingEnabled); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) professionList->setToolTip(QApplication::translate("MainWindow", "Select your profession", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_STATUSTIP +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(statustip) professionList->setStatusTip(QApplication::translate("MainWindow", "Specify your name here", nullptr)); -#endif // QT_NO_STATUSTIP -#ifndef QT_NO_WHATSTHIS +#endif // QT_CONFIG(statustip) +#if QT_CONFIG(whatsthis) professionList->setWhatsThis(QApplication::translate("MainWindow", "Specify your name here", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) label->setText(QApplication::translate("MainWindow", "Profession:", nullptr)); countryCombo->setItemText(0, QApplication::translate("MainWindow", "Egypt", nullptr)); countryCombo->setItemText(1, QApplication::translate("MainWindow", "France", nullptr)); @@ -311,12 +311,12 @@ public: countryCombo->setItemText(5, QApplication::translate("MainWindow", "Korea", nullptr)); countryCombo->setItemText(6, QApplication::translate("MainWindow", "Norway", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) countryCombo->setToolTip(QApplication::translate("MainWindow", "Specify country of origin", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_STATUSTIP +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(statustip) countryCombo->setStatusTip(QApplication::translate("MainWindow", "Specify country of origin", nullptr)); -#endif // QT_NO_STATUSTIP +#endif // QT_CONFIG(statustip) countryLabel->setText(QApplication::translate("MainWindow", "Pro&fession", nullptr)); menu_File->setTitle(QApplication::translate("MainWindow", "&File", nullptr)); menu_Help->setTitle(QApplication::translate("MainWindow", "&Help", nullptr)); diff --git a/tests/auto/tools/uic/baseline/phrasebookbox.ui.h b/tests/auto/tools/uic/baseline/phrasebookbox.ui.h index 27a0fa79ed..06c0f97bce 100644 --- a/tests/auto/tools/uic/baseline/phrasebookbox.ui.h +++ b/tests/auto/tools/uic/baseline/phrasebookbox.ui.h @@ -165,11 +165,11 @@ public: unnamed->addLayout(buttonLayout); -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) target->setBuddy(targetLed); source->setBuddy(sourceLed); definition->setBuddy(definitionLed); -#endif // QT_NO_SHORTCUT +#endif // QT_CONFIG(shortcut) QWidget::setTabOrder(sourceLed, targetLed); QWidget::setTabOrder(targetLed, definitionLed); QWidget::setTabOrder(definitionLed, newBut); @@ -185,36 +185,36 @@ public: void retranslateUi(QDialog *PhraseBookBox) { PhraseBookBox->setWindowTitle(QApplication::translate("PhraseBookBox", "Edit Phrase Book", nullptr)); -#ifndef QT_NO_WHATSTHIS +#if QT_CONFIG(whatsthis) PhraseBookBox->setWhatsThis(QApplication::translate("PhraseBookBox", "This window allows you to add, modify, or delete phrases in a phrase book.", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) target->setText(QApplication::translate("PhraseBookBox", "&Translation:", nullptr)); -#ifndef QT_NO_WHATSTHIS +#if QT_CONFIG(whatsthis) targetLed->setWhatsThis(QApplication::translate("PhraseBookBox", "This is the phrase in the target language corresponding to the source phrase.", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) source->setText(QApplication::translate("PhraseBookBox", "S&ource phrase:", nullptr)); -#ifndef QT_NO_WHATSTHIS +#if QT_CONFIG(whatsthis) definitionLed->setWhatsThis(QApplication::translate("PhraseBookBox", "This is a definition for the source phrase.", nullptr)); -#endif // QT_NO_WHATSTHIS -#ifndef QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) +#if QT_CONFIG(whatsthis) sourceLed->setWhatsThis(QApplication::translate("PhraseBookBox", "This is the phrase in the source language.", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) definition->setText(QApplication::translate("PhraseBookBox", "&Definition:", nullptr)); -#ifndef QT_NO_WHATSTHIS +#if QT_CONFIG(whatsthis) newBut->setWhatsThis(QApplication::translate("PhraseBookBox", "Click here to add the phrase to the phrase book.", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) newBut->setText(QApplication::translate("PhraseBookBox", "&New Phrase", nullptr)); -#ifndef QT_NO_WHATSTHIS +#if QT_CONFIG(whatsthis) removeBut->setWhatsThis(QApplication::translate("PhraseBookBox", "Click here to remove the phrase from the phrase book.", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) removeBut->setText(QApplication::translate("PhraseBookBox", "&Remove Phrase", nullptr)); -#ifndef QT_NO_WHATSTHIS +#if QT_CONFIG(whatsthis) saveBut->setWhatsThis(QApplication::translate("PhraseBookBox", "Click here to save the changes made.", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) saveBut->setText(QApplication::translate("PhraseBookBox", "&Save", nullptr)); -#ifndef QT_NO_WHATSTHIS +#if QT_CONFIG(whatsthis) closeBut->setWhatsThis(QApplication::translate("PhraseBookBox", "Click here to close this window.", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) closeBut->setText(QApplication::translate("PhraseBookBox", "Close", nullptr)); } // retranslateUi diff --git a/tests/auto/tools/uic/baseline/previewdialogbase.ui.h b/tests/auto/tools/uic/baseline/previewdialogbase.ui.h index 8d4c0dae9f..05152726a8 100644 --- a/tests/auto/tools/uic/baseline/previewdialogbase.ui.h +++ b/tests/auto/tools/uic/baseline/previewdialogbase.ui.h @@ -156,10 +156,10 @@ public: vboxLayout->addLayout(hboxLayout2); -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) label->setBuddy(paperSizeCombo); label_2->setBuddy(paperOrientationCombo); -#endif // QT_NO_SHORTCUT +#endif // QT_CONFIG(shortcut) retranslateUi(PreviewDialogBase); QObject::connect(buttonBox, SIGNAL(accepted()), PreviewDialogBase, SLOT(accept())); diff --git a/tests/auto/tools/uic/baseline/qfiledialog.ui.h b/tests/auto/tools/uic/baseline/qfiledialog.ui.h index 53607db449..011346bf11 100644 --- a/tests/auto/tools/uic/baseline/qfiledialog.ui.h +++ b/tests/auto/tools/uic/baseline/qfiledialog.ui.h @@ -272,24 +272,24 @@ public: void retranslateUi(QDialog *QFileDialog) { lookInLabel->setText(QApplication::translate("QFileDialog", "Look in:", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) backButton->setToolTip(QApplication::translate("QFileDialog", "Back", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(tooltip) forwardButton->setToolTip(QApplication::translate("QFileDialog", "Forward", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(tooltip) toParentButton->setToolTip(QApplication::translate("QFileDialog", "Parent Directory", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(tooltip) newFolderButton->setToolTip(QApplication::translate("QFileDialog", "Create New Folder", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(tooltip) listModeButton->setToolTip(QApplication::translate("QFileDialog", "List View", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(tooltip) detailModeButton->setToolTip(QApplication::translate("QFileDialog", "Detail View", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) fileTypeLabel->setText(QApplication::translate("QFileDialog", "Files of type:", nullptr)); Q_UNUSED(QFileDialog); } // retranslateUi diff --git a/tests/auto/tools/uic/baseline/qpagesetupwidget.ui.h b/tests/auto/tools/uic/baseline/qpagesetupwidget.ui.h index a5379bc468..4227f38187 100644 --- a/tests/auto/tools/uic/baseline/qpagesetupwidget.ui.h +++ b/tests/auto/tools/uic/baseline/qpagesetupwidget.ui.h @@ -290,12 +290,12 @@ public: gridLayout_3->addItem(verticalSpacer, 6, 0, 1, 1); -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) pageSizeLabel->setBuddy(pageSizeCombo); widthLabel->setBuddy(pageWidth); heightLabel->setBuddy(pageHeight); paperSourceLabel->setBuddy(paperSource); -#endif // QT_NO_SHORTCUT +#endif // QT_CONFIG(shortcut) retranslateUi(QPageSetupWidget); @@ -316,30 +316,30 @@ public: reverseLandscape->setText(QApplication::translate("QPageSetupWidget", "Reverse landscape", nullptr)); reversePortrait->setText(QApplication::translate("QPageSetupWidget", "Reverse portrait", nullptr)); groupBox->setTitle(QApplication::translate("QPageSetupWidget", "Margins", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) topMargin->setToolTip(QApplication::translate("QPageSetupWidget", "top margin", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_ACCESSIBILITY +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(accessibility) topMargin->setAccessibleName(QApplication::translate("QPageSetupWidget", "top margin", nullptr)); -#endif // QT_NO_ACCESSIBILITY -#ifndef QT_NO_TOOLTIP +#endif // QT_CONFIG(accessibility) +#if QT_CONFIG(tooltip) leftMargin->setToolTip(QApplication::translate("QPageSetupWidget", "left margin", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_ACCESSIBILITY +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(accessibility) leftMargin->setAccessibleName(QApplication::translate("QPageSetupWidget", "left margin", nullptr)); -#endif // QT_NO_ACCESSIBILITY -#ifndef QT_NO_TOOLTIP +#endif // QT_CONFIG(accessibility) +#if QT_CONFIG(tooltip) rightMargin->setToolTip(QApplication::translate("QPageSetupWidget", "right margin", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_ACCESSIBILITY +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(accessibility) rightMargin->setAccessibleName(QApplication::translate("QPageSetupWidget", "right margin", nullptr)); -#endif // QT_NO_ACCESSIBILITY -#ifndef QT_NO_TOOLTIP +#endif // QT_CONFIG(accessibility) +#if QT_CONFIG(tooltip) bottomMargin->setToolTip(QApplication::translate("QPageSetupWidget", "bottom margin", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_ACCESSIBILITY +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(accessibility) bottomMargin->setAccessibleName(QApplication::translate("QPageSetupWidget", "bottom margin", nullptr)); -#endif // QT_NO_ACCESSIBILITY +#endif // QT_CONFIG(accessibility) pagesPerSheetButtonGroup->setTitle(QApplication::translate("QPageSetupWidget", "Page Layout", nullptr)); label->setText(QApplication::translate("QPageSetupWidget", "Page order:", nullptr)); label_2->setText(QApplication::translate("QPageSetupWidget", "Pages per sheet:", nullptr)); diff --git a/tests/auto/tools/uic/baseline/qprintsettingsoutput.ui.h b/tests/auto/tools/uic/baseline/qprintsettingsoutput.ui.h index 656b5f9deb..ee4227b4e4 100644 --- a/tests/auto/tools/uic/baseline/qprintsettingsoutput.ui.h +++ b/tests/auto/tools/uic/baseline/qprintsettingsoutput.ui.h @@ -260,9 +260,9 @@ public: horizontalLayout_2->addWidget(tabs); -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) label->setBuddy(copies); -#endif // QT_NO_SHORTCUT +#endif // QT_CONFIG(shortcut) retranslateUi(QPrintSettingsOutput); QObject::connect(printRange, SIGNAL(toggled(bool)), from, SLOT(setEnabled(bool))); diff --git a/tests/auto/tools/uic/baseline/qprintwidget.ui.h b/tests/auto/tools/uic/baseline/qprintwidget.ui.h index 04b05143c6..f7e326b84a 100644 --- a/tests/auto/tools/uic/baseline/qprintwidget.ui.h +++ b/tests/auto/tools/uic/baseline/qprintwidget.ui.h @@ -128,10 +128,10 @@ public: horizontalLayout_2->addWidget(printerGroup); -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) label->setBuddy(printers); lOutput->setBuddy(filename); -#endif // QT_NO_SHORTCUT +#endif // QT_CONFIG(shortcut) retranslateUi(QPrintWidget); diff --git a/tests/auto/tools/uic/baseline/qsqlconnectiondialog.ui.h b/tests/auto/tools/uic/baseline/qsqlconnectiondialog.ui.h index 2131bc6d9b..a557fb984a 100644 --- a/tests/auto/tools/uic/baseline/qsqlconnectiondialog.ui.h +++ b/tests/auto/tools/uic/baseline/qsqlconnectiondialog.ui.h @@ -179,14 +179,14 @@ public: vboxLayout->addLayout(hboxLayout1); -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) textLabel4->setBuddy(editUsername); textLabel2->setBuddy(comboDriver); textLabel3->setBuddy(editDatabase); textLabel5->setBuddy(editHostname); textLabel5_2->setBuddy(portSpinBox); textLabel4_2->setBuddy(editPassword); -#endif // QT_NO_SHORTCUT +#endif // QT_CONFIG(shortcut) QWidget::setTabOrder(comboDriver, editDatabase); QWidget::setTabOrder(editDatabase, editUsername); QWidget::setTabOrder(editUsername, editPassword); diff --git a/tests/auto/tools/uic/baseline/qtgradienteditor.ui.h b/tests/auto/tools/uic/baseline/qtgradienteditor.ui.h index 9db07f35ac..814adff7bd 100644 --- a/tests/auto/tools/uic/baseline/qtgradienteditor.ui.h +++ b/tests/auto/tools/uic/baseline/qtgradienteditor.ui.h @@ -584,117 +584,117 @@ public: void retranslateUi(QWidget *QtGradientEditor) { QtGradientEditor->setWindowTitle(QApplication::translate("QtGradientEditor", "Form", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) gradientWidget->setToolTip(QApplication::translate("QtGradientEditor", "Gradient Editor", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_WHATSTHIS +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(whatsthis) gradientWidget->setWhatsThis(QApplication::translate("QtGradientEditor", "This area shows a preview of the gradient being edited. It also allows you to edit parameters specific to the gradient's type such as start and final point, radius, etc. by drag & drop.", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) label1->setText(QApplication::translate("QtGradientEditor", "1", nullptr)); label2->setText(QApplication::translate("QtGradientEditor", "2", nullptr)); label3->setText(QApplication::translate("QtGradientEditor", "3", nullptr)); label4->setText(QApplication::translate("QtGradientEditor", "4", nullptr)); label5->setText(QApplication::translate("QtGradientEditor", "5", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) gradientStopsWidget->setToolTip(QApplication::translate("QtGradientEditor", "Gradient Stops Editor", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_WHATSTHIS +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(whatsthis) gradientStopsWidget->setWhatsThis(QApplication::translate("QtGradientEditor", "This area allows you to edit gradient stops. Double click on the existing stop handle to duplicate it. Double click outside of the existing stop handles to create a new stop. Drag & drop the handle to reposition it. Use right mouse button to popup context menu with extra actions.", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) zoomLabel->setText(QApplication::translate("QtGradientEditor", "Zoom", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) zoomAllButton->setToolTip(QApplication::translate("QtGradientEditor", "Reset Zoom", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) zoomAllButton->setText(QApplication::translate("QtGradientEditor", "Reset Zoom", nullptr)); positionLabel->setText(QApplication::translate("QtGradientEditor", "Position", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) hLabel->setToolTip(QApplication::translate("QtGradientEditor", "Hue", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) hLabel->setText(QApplication::translate("QtGradientEditor", "H", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) hueColorLine->setToolTip(QApplication::translate("QtGradientEditor", "Hue", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) hueLabel->setText(QApplication::translate("QtGradientEditor", "Hue", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) sLabel->setToolTip(QApplication::translate("QtGradientEditor", "Saturation", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) sLabel->setText(QApplication::translate("QtGradientEditor", "S", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) saturationColorLine->setToolTip(QApplication::translate("QtGradientEditor", "Saturation", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) saturationLabel->setText(QApplication::translate("QtGradientEditor", "Sat", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) vLabel->setToolTip(QApplication::translate("QtGradientEditor", "Value", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) vLabel->setText(QApplication::translate("QtGradientEditor", "V", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) valueColorLine->setToolTip(QApplication::translate("QtGradientEditor", "Value", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) valueLabel->setText(QApplication::translate("QtGradientEditor", "Val", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) aLabel->setToolTip(QApplication::translate("QtGradientEditor", "Alpha", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) aLabel->setText(QApplication::translate("QtGradientEditor", "A", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) alphaColorLine->setToolTip(QApplication::translate("QtGradientEditor", "Alpha", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) alphaLabel->setText(QApplication::translate("QtGradientEditor", "Alpha", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) typeComboBox->setToolTip(QApplication::translate("QtGradientEditor", "Type", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(tooltip) spreadComboBox->setToolTip(QApplication::translate("QtGradientEditor", "Spread", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) colorLabel->setText(QApplication::translate("QtGradientEditor", "Color", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) colorButton->setToolTip(QApplication::translate("QtGradientEditor", "Current stop's color", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) colorButton->setText(QString()); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) hsvRadioButton->setToolTip(QApplication::translate("QtGradientEditor", "Show HSV specification", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) hsvRadioButton->setText(QApplication::translate("QtGradientEditor", "HSV", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) rgbRadioButton->setToolTip(QApplication::translate("QtGradientEditor", "Show RGB specification", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) rgbRadioButton->setText(QApplication::translate("QtGradientEditor", "RGB", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) positionSpinBox->setToolTip(QApplication::translate("QtGradientEditor", "Current stop's position", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) zoomSpinBox->setSuffix(QApplication::translate("QtGradientEditor", "%", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) zoomInButton->setToolTip(QApplication::translate("QtGradientEditor", "Zoom In", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(tooltip) zoomOutButton->setToolTip(QApplication::translate("QtGradientEditor", "Zoom Out", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(tooltip) detailsButton->setToolTip(QApplication::translate("QtGradientEditor", "Toggle details extension", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) detailsButton->setText(QApplication::translate("QtGradientEditor", ">", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) linearButton->setToolTip(QApplication::translate("QtGradientEditor", "Linear Type", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) linearButton->setText(QApplication::translate("QtGradientEditor", "...", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) radialButton->setToolTip(QApplication::translate("QtGradientEditor", "Radial Type", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) radialButton->setText(QApplication::translate("QtGradientEditor", "...", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) conicalButton->setToolTip(QApplication::translate("QtGradientEditor", "Conical Type", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) conicalButton->setText(QApplication::translate("QtGradientEditor", "...", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) padButton->setToolTip(QApplication::translate("QtGradientEditor", "Pad Spread", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) padButton->setText(QApplication::translate("QtGradientEditor", "...", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) repeatButton->setToolTip(QApplication::translate("QtGradientEditor", "Repeat Spread", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) repeatButton->setText(QApplication::translate("QtGradientEditor", "...", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) reflectButton->setToolTip(QApplication::translate("QtGradientEditor", "Reflect Spread", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) reflectButton->setText(QApplication::translate("QtGradientEditor", "...", nullptr)); } // retranslateUi diff --git a/tests/auto/tools/uic/baseline/qtresourceeditordialog.ui.h b/tests/auto/tools/uic/baseline/qtresourceeditordialog.ui.h index 6a8c9c7172..b97833dd63 100644 --- a/tests/auto/tools/uic/baseline/qtresourceeditordialog.ui.h +++ b/tests/auto/tools/uic/baseline/qtresourceeditordialog.ui.h @@ -142,23 +142,23 @@ public: void retranslateUi(QDialog *QtResourceEditorDialog) { QtResourceEditorDialog->setWindowTitle(QApplication::translate("QtResourceEditorDialog", "Dialog", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) newQrcButton->setToolTip(QApplication::translate("QtResourceEditorDialog", "New File", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) newQrcButton->setText(QApplication::translate("QtResourceEditorDialog", "N", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) removeQrcButton->setToolTip(QApplication::translate("QtResourceEditorDialog", "Remove File", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) removeQrcButton->setText(QApplication::translate("QtResourceEditorDialog", "R", nullptr)); importQrcButton->setText(QApplication::translate("QtResourceEditorDialog", "I", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) newResourceButton->setToolTip(QApplication::translate("QtResourceEditorDialog", "New Resource", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) newResourceButton->setText(QApplication::translate("QtResourceEditorDialog", "N", nullptr)); addResourceButton->setText(QApplication::translate("QtResourceEditorDialog", "A", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) removeResourceButton->setToolTip(QApplication::translate("QtResourceEditorDialog", "Remove Resource or File", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) removeResourceButton->setText(QApplication::translate("QtResourceEditorDialog", "R", nullptr)); } // retranslateUi diff --git a/tests/auto/tools/uic/baseline/qttoolbardialog.ui.h b/tests/auto/tools/uic/baseline/qttoolbardialog.ui.h index e893386d9b..d80b123c02 100644 --- a/tests/auto/tools/uic/baseline/qttoolbardialog.ui.h +++ b/tests/auto/tools/uic/baseline/qttoolbardialog.ui.h @@ -183,33 +183,33 @@ public: ___qtreewidgetitem->setText(0, QApplication::translate("QtToolBarDialog", "1", nullptr)); label->setText(QApplication::translate("QtToolBarDialog", "Actions", nullptr)); label_2->setText(QApplication::translate("QtToolBarDialog", "Toolbars", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) newButton->setToolTip(QApplication::translate("QtToolBarDialog", "Add new toolbar", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) newButton->setText(QApplication::translate("QtToolBarDialog", "New", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) removeButton->setToolTip(QApplication::translate("QtToolBarDialog", "Remove selected toolbar", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) removeButton->setText(QApplication::translate("QtToolBarDialog", "Remove", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) renameButton->setToolTip(QApplication::translate("QtToolBarDialog", "Rename toolbar", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) renameButton->setText(QApplication::translate("QtToolBarDialog", "Rename", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) upButton->setToolTip(QApplication::translate("QtToolBarDialog", "Move action up", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) upButton->setText(QApplication::translate("QtToolBarDialog", "Up", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) leftButton->setToolTip(QApplication::translate("QtToolBarDialog", "Remove action from toolbar", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) leftButton->setText(QApplication::translate("QtToolBarDialog", "<-", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) rightButton->setToolTip(QApplication::translate("QtToolBarDialog", "Add action to toolbar", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) rightButton->setText(QApplication::translate("QtToolBarDialog", "->", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) downButton->setToolTip(QApplication::translate("QtToolBarDialog", "Move action down", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) downButton->setText(QApplication::translate("QtToolBarDialog", "Down", nullptr)); label_3->setText(QApplication::translate("QtToolBarDialog", "Current Toolbar Actions", nullptr)); } // retranslateUi diff --git a/tests/auto/tools/uic/baseline/saveformastemplate.ui.h b/tests/auto/tools/uic/baseline/saveformastemplate.ui.h index 9ef6eedb4c..00d92eb602 100644 --- a/tests/auto/tools/uic/baseline/saveformastemplate.ui.h +++ b/tests/auto/tools/uic/baseline/saveformastemplate.ui.h @@ -117,10 +117,10 @@ public: vboxLayout->addWidget(buttonBox); -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) label->setBuddy(templateNameEdit); label_2->setBuddy(categoryCombo); -#endif // QT_NO_SHORTCUT +#endif // QT_CONFIG(shortcut) retranslateUi(SaveFormAsTemplate); QObject::connect(buttonBox, SIGNAL(accepted()), SaveFormAsTemplate, SLOT(accept())); diff --git a/tests/auto/tools/uic/baseline/signalslotdialog.ui.h b/tests/auto/tools/uic/baseline/signalslotdialog.ui.h index 5833a25a8b..be48da9218 100644 --- a/tests/auto/tools/uic/baseline/signalslotdialog.ui.h +++ b/tests/auto/tools/uic/baseline/signalslotdialog.ui.h @@ -135,22 +135,22 @@ public: { SignalSlotDialogClass->setWindowTitle(QApplication::translate("SignalSlotDialogClass", "Signals and slots", nullptr)); slotGroupBox->setTitle(QApplication::translate("SignalSlotDialogClass", "Slots", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) addSlotButton->setToolTip(QApplication::translate("SignalSlotDialogClass", "Add", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) addSlotButton->setText(QApplication::translate("SignalSlotDialogClass", "...", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) removeSlotButton->setToolTip(QApplication::translate("SignalSlotDialogClass", "Delete", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) removeSlotButton->setText(QApplication::translate("SignalSlotDialogClass", "...", nullptr)); signalGroupBox->setTitle(QApplication::translate("SignalSlotDialogClass", "Signals", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) addSignalButton->setToolTip(QApplication::translate("SignalSlotDialogClass", "Add", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) addSignalButton->setText(QApplication::translate("SignalSlotDialogClass", "...", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) removeSignalButton->setToolTip(QApplication::translate("SignalSlotDialogClass", "Delete", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) removeSignalButton->setText(QApplication::translate("SignalSlotDialogClass", "...", nullptr)); } // retranslateUi diff --git a/tests/auto/tools/uic/baseline/stringlisteditor.ui.h b/tests/auto/tools/uic/baseline/stringlisteditor.ui.h index fd78ce91c1..941c73799b 100644 --- a/tests/auto/tools/uic/baseline/stringlisteditor.ui.h +++ b/tests/auto/tools/uic/baseline/stringlisteditor.ui.h @@ -201,9 +201,9 @@ public: vboxLayout->addWidget(buttonBox); -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) label->setBuddy(valueEdit); -#endif // QT_NO_SHORTCUT +#endif // QT_CONFIG(shortcut) retranslateUi(qdesigner_internal__Dialog); QObject::connect(buttonBox, SIGNAL(accepted()), qdesigner_internal__Dialog, SLOT(accept())); @@ -216,22 +216,22 @@ public: { qdesigner_internal__Dialog->setWindowTitle(QApplication::translate("qdesigner_internal::Dialog", "Dialog", nullptr)); groupBox->setTitle(QApplication::translate("qdesigner_internal::Dialog", "StringList", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) newButton->setToolTip(QApplication::translate("qdesigner_internal::Dialog", "New String", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) newButton->setText(QApplication::translate("qdesigner_internal::Dialog", "&New", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) deleteButton->setToolTip(QApplication::translate("qdesigner_internal::Dialog", "Delete String", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) deleteButton->setText(QApplication::translate("qdesigner_internal::Dialog", "&Delete", nullptr)); label->setText(QApplication::translate("qdesigner_internal::Dialog", "&Value:", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) upButton->setToolTip(QApplication::translate("qdesigner_internal::Dialog", "Move String Up", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) upButton->setText(QApplication::translate("qdesigner_internal::Dialog", "Up", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) downButton->setToolTip(QApplication::translate("qdesigner_internal::Dialog", "Move String Down", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) downButton->setText(QApplication::translate("qdesigner_internal::Dialog", "Down", nullptr)); } // retranslateUi diff --git a/tests/auto/tools/uic/baseline/tablewidgeteditor.ui.h b/tests/auto/tools/uic/baseline/tablewidgeteditor.ui.h index e3ba00095e..e0287246d5 100644 --- a/tests/auto/tools/uic/baseline/tablewidgeteditor.ui.h +++ b/tests/auto/tools/uic/baseline/tablewidgeteditor.ui.h @@ -313,50 +313,50 @@ public: { qdesigner_internal__TableWidgetEditor->setWindowTitle(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Edit Table Widget", nullptr)); itemsBox->setTitle(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Table Items", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) tableWidget->setToolTip(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Table Items", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) label_3->setText(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Icon", nullptr)); columnsBox->setTitle(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Columns", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) columnsListWidget->setToolTip(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Table Columns", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(tooltip) newColumnButton->setToolTip(QApplication::translate("qdesigner_internal::TableWidgetEditor", "New Column", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) newColumnButton->setText(QApplication::translate("qdesigner_internal::TableWidgetEditor", "New", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) deleteColumnButton->setToolTip(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Delete Column", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) deleteColumnButton->setText(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Delete", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) moveColumnUpButton->setToolTip(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Move Column Up", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) moveColumnUpButton->setText(QApplication::translate("qdesigner_internal::TableWidgetEditor", "U", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) moveColumnDownButton->setToolTip(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Move Column Down", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) moveColumnDownButton->setText(QApplication::translate("qdesigner_internal::TableWidgetEditor", "D", nullptr)); label->setText(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Icon", nullptr)); rowsBox->setTitle(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Rows", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) rowsListWidget->setToolTip(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Table Rows", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(tooltip) newRowButton->setToolTip(QApplication::translate("qdesigner_internal::TableWidgetEditor", "New Row", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) newRowButton->setText(QApplication::translate("qdesigner_internal::TableWidgetEditor", "New", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) deleteRowButton->setToolTip(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Delete Row", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) deleteRowButton->setText(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Delete", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) moveRowUpButton->setToolTip(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Move Row Up", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) moveRowUpButton->setText(QApplication::translate("qdesigner_internal::TableWidgetEditor", "U", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) moveRowDownButton->setToolTip(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Move Row Down", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) moveRowDownButton->setText(QApplication::translate("qdesigner_internal::TableWidgetEditor", "D", nullptr)); label_2->setText(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Icon", nullptr)); } // retranslateUi diff --git a/tests/auto/tools/uic/baseline/textfinder.ui.h b/tests/auto/tools/uic/baseline/textfinder.ui.h index 2f6bfebf98..ccad9a37c3 100644 --- a/tests/auto/tools/uic/baseline/textfinder.ui.h +++ b/tests/auto/tools/uic/baseline/textfinder.ui.h @@ -81,9 +81,9 @@ public: vboxLayout->addItem(spacerItem); -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) searchLabel->setBuddy(lineEdit); -#endif // QT_NO_SHORTCUT +#endif // QT_CONFIG(shortcut) retranslateUi(Form); QObject::connect(lineEdit, SIGNAL(returnPressed()), findButton, SLOT(animateClick())); diff --git a/tests/auto/tools/uic/baseline/topicchooser.ui.h b/tests/auto/tools/uic/baseline/topicchooser.ui.h index 90ec485e39..972fc485c0 100644 --- a/tests/auto/tools/uic/baseline/topicchooser.ui.h +++ b/tests/auto/tools/uic/baseline/topicchooser.ui.h @@ -86,9 +86,9 @@ public: vboxLayout->addWidget(Layout16); -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) label->setBuddy(listWidget); -#endif // QT_NO_SHORTCUT +#endif // QT_CONFIG(shortcut) retranslateUi(TopicChooser); diff --git a/tests/auto/tools/uic/baseline/translatedialog.ui.h b/tests/auto/tools/uic/baseline/translatedialog.ui.h index 5bea11f9f2..680f3e7f28 100644 --- a/tests/auto/tools/uic/baseline/translatedialog.ui.h +++ b/tests/auto/tools/uic/baseline/translatedialog.ui.h @@ -182,10 +182,10 @@ public: hboxLayout->addLayout(vboxLayout2); -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) findWhat->setBuddy(ledFindWhat); translateTo->setBuddy(ledTranslateTo); -#endif // QT_NO_SHORTCUT +#endif // QT_CONFIG(shortcut) QWidget::setTabOrder(ledFindWhat, ledTranslateTo); QWidget::setTabOrder(ledTranslateTo, findNxt); QWidget::setTabOrder(findNxt, translate); @@ -206,32 +206,32 @@ public: void retranslateUi(QDialog *TranslateDialog) { TranslateDialog->setWindowTitle(QApplication::translate("TranslateDialog", "Qt Linguist", nullptr)); -#ifndef QT_NO_WHATSTHIS +#if QT_CONFIG(whatsthis) TranslateDialog->setWhatsThis(QApplication::translate("TranslateDialog", "This window allows you to search for some text in the translation source file.", nullptr)); -#endif // QT_NO_WHATSTHIS -#ifndef QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) +#if QT_CONFIG(whatsthis) ledTranslateTo->setWhatsThis(QApplication::translate("TranslateDialog", "Type in the text to search for.", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) findWhat->setText(QApplication::translate("TranslateDialog", "Find &source text:", nullptr)); translateTo->setText(QApplication::translate("TranslateDialog", "&Translate to:", nullptr)); -#ifndef QT_NO_WHATSTHIS +#if QT_CONFIG(whatsthis) ledFindWhat->setWhatsThis(QApplication::translate("TranslateDialog", "Type in the text to search for.", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) groupBox->setTitle(QApplication::translate("TranslateDialog", "Search options", nullptr)); -#ifndef QT_NO_WHATSTHIS +#if QT_CONFIG(whatsthis) ckMatchCase->setWhatsThis(QApplication::translate("TranslateDialog", "Texts such as 'TeX' and 'tex' are considered as different when checked.", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) ckMatchCase->setText(QApplication::translate("TranslateDialog", "Match &case", nullptr)); ckMarkFinished->setText(QApplication::translate("TranslateDialog", "Mark new translation as &finished", nullptr)); -#ifndef QT_NO_WHATSTHIS +#if QT_CONFIG(whatsthis) findNxt->setWhatsThis(QApplication::translate("TranslateDialog", "Click here to find the next occurrence of the text you typed in.", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) findNxt->setText(QApplication::translate("TranslateDialog", "Find Next", nullptr)); translate->setText(QApplication::translate("TranslateDialog", "Translate", nullptr)); translateAll->setText(QApplication::translate("TranslateDialog", "Translate All", nullptr)); -#ifndef QT_NO_WHATSTHIS +#if QT_CONFIG(whatsthis) cancel->setWhatsThis(QApplication::translate("TranslateDialog", "Click here to close this window.", nullptr)); -#endif // QT_NO_WHATSTHIS +#endif // QT_CONFIG(whatsthis) cancel->setText(QApplication::translate("TranslateDialog", "Cancel", nullptr)); } // retranslateUi diff --git a/tests/auto/tools/uic/baseline/translationsettings.ui.h b/tests/auto/tools/uic/baseline/translationsettings.ui.h index 764e3a85b6..7c001786c7 100644 --- a/tests/auto/tools/uic/baseline/translationsettings.ui.h +++ b/tests/auto/tools/uic/baseline/translationsettings.ui.h @@ -86,9 +86,9 @@ public: vboxLayout->addWidget(buttonBox); -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) label->setBuddy(cbLanguageList); -#endif // QT_NO_SHORTCUT +#endif // QT_CONFIG(shortcut) retranslateUi(TranslationSettings); QObject::connect(buttonBox, SIGNAL(accepted()), TranslationSettings, SLOT(accept())); diff --git a/tests/auto/tools/uic/baseline/treewidgeteditor.ui.h b/tests/auto/tools/uic/baseline/treewidgeteditor.ui.h index d432195648..a15798ab92 100644 --- a/tests/auto/tools/uic/baseline/treewidgeteditor.ui.h +++ b/tests/auto/tools/uic/baseline/treewidgeteditor.ui.h @@ -280,57 +280,57 @@ public: itemsBox->setTitle(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Tree Items", nullptr)); QTreeWidgetItem *___qtreewidgetitem = treeWidget->headerItem(); ___qtreewidgetitem->setText(0, QApplication::translate("qdesigner_internal::TreeWidgetEditor", "1", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) treeWidget->setToolTip(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Tree Items", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(tooltip) newItemButton->setToolTip(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "New Item", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) newItemButton->setText(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "&New", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) newSubItemButton->setToolTip(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "New Subitem", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) newSubItemButton->setText(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "New &Subitem", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) deleteItemButton->setToolTip(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Delete Item", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) deleteItemButton->setText(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "&Delete", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) moveItemLeftButton->setToolTip(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Move Item Left (before Parent Item)", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) moveItemLeftButton->setText(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "L", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) moveItemRightButton->setToolTip(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Move Item Right (as a First Subitem of the Next Sibling Item)", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) moveItemRightButton->setText(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "R", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) moveItemUpButton->setToolTip(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Move Item Up", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) moveItemUpButton->setText(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "U", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) moveItemDownButton->setToolTip(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Move Item Down", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) moveItemDownButton->setText(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "D", nullptr)); label_2->setText(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Icon", nullptr)); columnsBox->setTitle(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Columns", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) listWidget->setToolTip(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Tree Columns", nullptr)); -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) +#if QT_CONFIG(tooltip) newColumnButton->setToolTip(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "New Column", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) newColumnButton->setText(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "New", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) deleteColumnButton->setToolTip(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Delete Column", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) deleteColumnButton->setText(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Delete", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) moveColumnUpButton->setToolTip(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Move Column Up", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) moveColumnUpButton->setText(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "U", nullptr)); -#ifndef QT_NO_TOOLTIP +#if QT_CONFIG(tooltip) moveColumnDownButton->setToolTip(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Move Column Down", nullptr)); -#endif // QT_NO_TOOLTIP +#endif // QT_CONFIG(tooltip) moveColumnDownButton->setText(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "D", nullptr)); label->setText(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Icon", nullptr)); } // retranslateUi diff --git a/tests/auto/tools/uic/baseline/trpreviewtool.ui.h b/tests/auto/tools/uic/baseline/trpreviewtool.ui.h index 3fbf125a1f..4b7d861191 100644 --- a/tests/auto/tools/uic/baseline/trpreviewtool.ui.h +++ b/tests/auto/tools/uic/baseline/trpreviewtool.ui.h @@ -166,9 +166,9 @@ public: actionOpenForm->setText(QApplication::translate("TrPreviewToolClass", "&Open Form...", nullptr)); actionLoadTranslation->setText(QApplication::translate("TrPreviewToolClass", "&Load Translation...", nullptr)); actionReloadTranslations->setText(QApplication::translate("TrPreviewToolClass", "&Reload Translations", nullptr)); -#ifndef QT_NO_SHORTCUT +#if QT_CONFIG(shortcut) actionReloadTranslations->setShortcut(QApplication::translate("TrPreviewToolClass", "F5", nullptr)); -#endif // QT_NO_SHORTCUT +#endif // QT_CONFIG(shortcut) actionClose->setText(QApplication::translate("TrPreviewToolClass", "&Close", nullptr)); actionAbout->setText(QApplication::translate("TrPreviewToolClass", "About", nullptr)); actionAbout_Qt->setText(QApplication::translate("TrPreviewToolClass", "About Qt", nullptr)); From d1e3a21631d011694517e05d68d2d59cca3d1953 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 23 Oct 2018 13:27:31 +0200 Subject: [PATCH 0305/1650] tst_uic: Brush up the uic autotest - Fix some clang nags (QFileInfo::exists(), raw string literals). - Update the version numbers in the baseline to be 5.12 consistently to make future modifications easier. - Introduce another environment variable to redirect the diff output to stderr. This can be used to generate a diff for applying when making larger changes to uic. Task-number: PYSIDE-797 Change-Id: I3f6716f0fe8e5939f6bef3965d90b2bb2c37f4c4 Reviewed-by: Jarek Kobus --- .../baseline/Dialog_with_Buttons_Bottom.ui.h | 2 +- .../baseline/Dialog_with_Buttons_Right.ui.h | 2 +- .../uic/baseline/Dialog_without_Buttons.ui.h | 2 +- .../auto/tools/uic/baseline/Main_Window.ui.h | 2 +- tests/auto/tools/uic/baseline/Widget.ui.h | 2 +- .../tools/uic/baseline/addlinkdialog.ui.h | 2 +- .../tools/uic/baseline/addtorrentform.ui.h | 2 +- .../uic/baseline/authenticationdialog.ui.h | 2 +- tests/auto/tools/uic/baseline/backside.ui.h | 2 +- .../tools/uic/baseline/batchtranslation.ui.h | 2 +- .../tools/uic/baseline/bookmarkdialog.ui.h | 2 +- tests/auto/tools/uic/baseline/bookwindow.ui.h | 2 +- .../tools/uic/baseline/browserwidget.ui.h | 2 +- .../uic/baseline/bug18156QTreeWidget.ui.h | 2 +- tests/auto/tools/uic/baseline/calculator.ui.h | 2 +- .../tools/uic/baseline/calculatorform.ui.h | 2 +- .../tools/uic/baseline/certificateinfo.ui.h | 2 +- tests/auto/tools/uic/baseline/chatdialog.ui.h | 2 +- .../tools/uic/baseline/chatmainwindow.ui.h | 2 +- .../tools/uic/baseline/chatsetnickname.ui.h | 2 +- tests/auto/tools/uic/baseline/config.ui.h | 2 +- .../tools/uic/baseline/connectdialog.ui.h | 2 +- tests/auto/tools/uic/baseline/controller.ui.h | 2 +- tests/auto/tools/uic/baseline/cookies.ui.h | 2 +- .../tools/uic/baseline/cookiesexceptions.ui.h | 2 +- tests/auto/tools/uic/baseline/default.ui.h | 2 +- tests/auto/tools/uic/baseline/dialog.ui.h | 2 +- .../auto/tools/uic/baseline/downloaditem.ui.h | 2 +- tests/auto/tools/uic/baseline/downloads.ui.h | 2 +- .../tools/uic/baseline/embeddeddialog.ui.h | 2 +- tests/auto/tools/uic/baseline/filespage.ui.h | 2 +- .../tools/uic/baseline/filternamedialog.ui.h | 2 +- tests/auto/tools/uic/baseline/filterpage.ui.h | 2 +- tests/auto/tools/uic/baseline/finddialog.ui.h | 2 +- tests/auto/tools/uic/baseline/form.ui.h | 2 +- .../uic/baseline/formwindowsettings.ui.h | 2 +- .../auto/tools/uic/baseline/generalpage.ui.h | 2 +- .../tools/uic/baseline/gridalignment.ui.h | 2 +- tests/auto/tools/uic/baseline/gridpanel.ui.h | 2 +- tests/auto/tools/uic/baseline/helpdialog.ui.h | 2 +- tests/auto/tools/uic/baseline/history.ui.h | 2 +- tests/auto/tools/uic/baseline/icontheme.ui.h | 2 +- tests/auto/tools/uic/baseline/idbased.ui.h | 2 +- .../tools/uic/baseline/identifierpage.ui.h | 2 +- .../auto/tools/uic/baseline/imagedialog.ui.h | 2 +- tests/auto/tools/uic/baseline/inputpage.ui.h | 2 +- .../tools/uic/baseline/installdialog.ui.h | 2 +- .../tools/uic/baseline/languagesdialog.ui.h | 2 +- .../tools/uic/baseline/listwidgeteditor.ui.h | 2 +- tests/auto/tools/uic/baseline/mainwindow.ui.h | 2 +- tests/auto/tools/uic/baseline/mydialog.ui.h | 2 +- tests/auto/tools/uic/baseline/myform.ui.h | 2 +- .../tools/uic/baseline/newactiondialog.ui.h | 2 +- .../baseline/newdynamicpropertydialog.ui.h | 2 +- tests/auto/tools/uic/baseline/newform.ui.h | 2 +- .../auto/tools/uic/baseline/orderdialog.ui.h | 2 +- tests/auto/tools/uic/baseline/outputpage.ui.h | 2 +- tests/auto/tools/uic/baseline/pagefold.ui.h | 2 +- .../tools/uic/baseline/paletteeditor.ui.h | 2 +- .../tools/uic/baseline/passworddialog.ui.h | 2 +- tests/auto/tools/uic/baseline/pathpage.ui.h | 2 +- .../tools/uic/baseline/phrasebookbox.ui.h | 2 +- .../auto/tools/uic/baseline/plugindialog.ui.h | 2 +- .../tools/uic/baseline/preferencesdialog.ui.h | 2 +- .../baseline/previewconfigurationwidget.ui.h | 2 +- .../tools/uic/baseline/previewdialogbase.ui.h | 2 +- .../tools/uic/baseline/previewwidget.ui.h | 2 +- tests/auto/tools/uic/baseline/proxy.ui.h | 2 +- .../auto/tools/uic/baseline/qfiledialog.ui.h | 2 +- .../uic/baseline/qprintpropertieswidget.ui.h | 2 +- .../uic/baseline/qprintsettingsoutput.ui.h | 2 +- .../auto/tools/uic/baseline/qprintwidget.ui.h | 2 +- .../uic/baseline/qsqlconnectiondialog.ui.h | 2 +- .../tools/uic/baseline/qtgradientdialog.ui.h | 2 +- .../tools/uic/baseline/qtgradientview.ui.h | 2 +- .../uic/baseline/qtgradientviewdialog.ui.h | 2 +- .../uic/baseline/qtresourceeditordialog.ui.h | 2 +- .../tools/uic/baseline/qttoolbardialog.ui.h | 2 +- .../auto/tools/uic/baseline/querywidget.ui.h | 2 +- .../tools/uic/baseline/remotecontrol.ui.h | 2 +- .../uic/baseline/saveformastemplate.ui.h | 2 +- tests/auto/tools/uic/baseline/settings.ui.h | 2 +- .../tools/uic/baseline/signalslotdialog.ui.h | 2 +- tests/auto/tools/uic/baseline/sslclient.ui.h | 2 +- tests/auto/tools/uic/baseline/sslerrors.ui.h | 2 +- tests/auto/tools/uic/baseline/statistics.ui.h | 2 +- .../tools/uic/baseline/stringlisteditor.ui.h | 2 +- .../tools/uic/baseline/stylesheeteditor.ui.h | 2 +- .../tools/uic/baseline/tabbedbrowser.ui.h | 2 +- .../tools/uic/baseline/tablewidgeteditor.ui.h | 2 +- .../auto/tools/uic/baseline/tetrixwindow.ui.h | 2 +- tests/auto/tools/uic/baseline/textfinder.ui.h | 2 +- .../auto/tools/uic/baseline/topicchooser.ui.h | 2 +- .../tools/uic/baseline/translatedialog.ui.h | 2 +- .../uic/baseline/translationsettings.ui.h | 2 +- .../tools/uic/baseline/treewidgeteditor.ui.h | 2 +- .../tools/uic/baseline/trpreviewtool.ui.h | 2 +- .../uic/baseline/wateringconfigdialog.ui.h | 2 +- tests/auto/tools/uic/tst_uic.cpp | 38 ++++++++++++++----- 99 files changed, 127 insertions(+), 107 deletions(-) diff --git a/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Bottom.ui.h b/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Bottom.ui.h index 1f5004b2aa..0da4e150ed 100644 --- a/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Bottom.ui.h +++ b/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Bottom.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'Dialog_with_Buttons_Bottom.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Right.ui.h b/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Right.ui.h index 8dd8b11b62..5acbefd998 100644 --- a/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Right.ui.h +++ b/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Right.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'Dialog_with_Buttons_Right.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/Dialog_without_Buttons.ui.h b/tests/auto/tools/uic/baseline/Dialog_without_Buttons.ui.h index 95acabf3f8..c9d803a090 100644 --- a/tests/auto/tools/uic/baseline/Dialog_without_Buttons.ui.h +++ b/tests/auto/tools/uic/baseline/Dialog_without_Buttons.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'Dialog_without_Buttons.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/Main_Window.ui.h b/tests/auto/tools/uic/baseline/Main_Window.ui.h index 9e59e9f2e5..b0ab882a6f 100644 --- a/tests/auto/tools/uic/baseline/Main_Window.ui.h +++ b/tests/auto/tools/uic/baseline/Main_Window.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'Main_Window.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/Widget.ui.h b/tests/auto/tools/uic/baseline/Widget.ui.h index 4318c2262f..bb62f52bb5 100644 --- a/tests/auto/tools/uic/baseline/Widget.ui.h +++ b/tests/auto/tools/uic/baseline/Widget.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'Widget.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/addlinkdialog.ui.h b/tests/auto/tools/uic/baseline/addlinkdialog.ui.h index 17f51a92f8..fced16ba64 100644 --- a/tests/auto/tools/uic/baseline/addlinkdialog.ui.h +++ b/tests/auto/tools/uic/baseline/addlinkdialog.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'addlinkdialog.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/addtorrentform.ui.h b/tests/auto/tools/uic/baseline/addtorrentform.ui.h index d259a011bf..5fd04eeb21 100644 --- a/tests/auto/tools/uic/baseline/addtorrentform.ui.h +++ b/tests/auto/tools/uic/baseline/addtorrentform.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'addtorrentform.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/authenticationdialog.ui.h b/tests/auto/tools/uic/baseline/authenticationdialog.ui.h index 16c9ce16a8..888e381695 100644 --- a/tests/auto/tools/uic/baseline/authenticationdialog.ui.h +++ b/tests/auto/tools/uic/baseline/authenticationdialog.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'authenticationdialog.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/backside.ui.h b/tests/auto/tools/uic/baseline/backside.ui.h index e7053c632f..b3e04dc810 100644 --- a/tests/auto/tools/uic/baseline/backside.ui.h +++ b/tests/auto/tools/uic/baseline/backside.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'backside.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/batchtranslation.ui.h b/tests/auto/tools/uic/baseline/batchtranslation.ui.h index 8a4dc7a677..fef162ead8 100644 --- a/tests/auto/tools/uic/baseline/batchtranslation.ui.h +++ b/tests/auto/tools/uic/baseline/batchtranslation.ui.h @@ -31,7 +31,7 @@ /******************************************************************************** ** Form generated from reading UI file 'batchtranslation.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/bookmarkdialog.ui.h b/tests/auto/tools/uic/baseline/bookmarkdialog.ui.h index b5a44998be..0e2f10500b 100644 --- a/tests/auto/tools/uic/baseline/bookmarkdialog.ui.h +++ b/tests/auto/tools/uic/baseline/bookmarkdialog.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'bookmarkdialog.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/bookwindow.ui.h b/tests/auto/tools/uic/baseline/bookwindow.ui.h index 8fe5f000e2..b9af619991 100644 --- a/tests/auto/tools/uic/baseline/bookwindow.ui.h +++ b/tests/auto/tools/uic/baseline/bookwindow.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'bookwindow.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/browserwidget.ui.h b/tests/auto/tools/uic/baseline/browserwidget.ui.h index 7b666858b0..aab629f85b 100644 --- a/tests/auto/tools/uic/baseline/browserwidget.ui.h +++ b/tests/auto/tools/uic/baseline/browserwidget.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'browserwidget.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/bug18156QTreeWidget.ui.h b/tests/auto/tools/uic/baseline/bug18156QTreeWidget.ui.h index 47f8f22132..1d090bcd86 100644 --- a/tests/auto/tools/uic/baseline/bug18156QTreeWidget.ui.h +++ b/tests/auto/tools/uic/baseline/bug18156QTreeWidget.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'bug18156QTreeWidget.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/calculator.ui.h b/tests/auto/tools/uic/baseline/calculator.ui.h index 0387ee472b..0a374ecf01 100644 --- a/tests/auto/tools/uic/baseline/calculator.ui.h +++ b/tests/auto/tools/uic/baseline/calculator.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'calculator.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/calculatorform.ui.h b/tests/auto/tools/uic/baseline/calculatorform.ui.h index f4661c6237..24027fd3fb 100644 --- a/tests/auto/tools/uic/baseline/calculatorform.ui.h +++ b/tests/auto/tools/uic/baseline/calculatorform.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'calculatorform.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/certificateinfo.ui.h b/tests/auto/tools/uic/baseline/certificateinfo.ui.h index 2aa47d40ad..75e4639d08 100644 --- a/tests/auto/tools/uic/baseline/certificateinfo.ui.h +++ b/tests/auto/tools/uic/baseline/certificateinfo.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'certificateinfo.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/chatdialog.ui.h b/tests/auto/tools/uic/baseline/chatdialog.ui.h index ace6951669..8138a2cdd8 100644 --- a/tests/auto/tools/uic/baseline/chatdialog.ui.h +++ b/tests/auto/tools/uic/baseline/chatdialog.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'chatdialog.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/chatmainwindow.ui.h b/tests/auto/tools/uic/baseline/chatmainwindow.ui.h index 2264dc8c32..a3cb6203a9 100644 --- a/tests/auto/tools/uic/baseline/chatmainwindow.ui.h +++ b/tests/auto/tools/uic/baseline/chatmainwindow.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'chatmainwindow.ui' ** -** Created by: Qt User Interface Compiler version 5.9.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/chatsetnickname.ui.h b/tests/auto/tools/uic/baseline/chatsetnickname.ui.h index c73dfb2c6e..c735f4b889 100644 --- a/tests/auto/tools/uic/baseline/chatsetnickname.ui.h +++ b/tests/auto/tools/uic/baseline/chatsetnickname.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'chatsetnickname.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/config.ui.h b/tests/auto/tools/uic/baseline/config.ui.h index 8287e0b1ac..71ac8535c7 100644 --- a/tests/auto/tools/uic/baseline/config.ui.h +++ b/tests/auto/tools/uic/baseline/config.ui.h @@ -31,7 +31,7 @@ /******************************************************************************** ** Form generated from reading UI file 'config.ui' ** -** Created by: Qt User Interface Compiler version 5.10.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/connectdialog.ui.h b/tests/auto/tools/uic/baseline/connectdialog.ui.h index a470a6705d..55198d43f3 100644 --- a/tests/auto/tools/uic/baseline/connectdialog.ui.h +++ b/tests/auto/tools/uic/baseline/connectdialog.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'connectdialog.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/controller.ui.h b/tests/auto/tools/uic/baseline/controller.ui.h index 72b0956472..814a0c0430 100644 --- a/tests/auto/tools/uic/baseline/controller.ui.h +++ b/tests/auto/tools/uic/baseline/controller.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'controller.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/cookies.ui.h b/tests/auto/tools/uic/baseline/cookies.ui.h index 144c306874..a3793f6def 100644 --- a/tests/auto/tools/uic/baseline/cookies.ui.h +++ b/tests/auto/tools/uic/baseline/cookies.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'cookies.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/cookiesexceptions.ui.h b/tests/auto/tools/uic/baseline/cookiesexceptions.ui.h index a3bf7a449e..22b06f65a2 100644 --- a/tests/auto/tools/uic/baseline/cookiesexceptions.ui.h +++ b/tests/auto/tools/uic/baseline/cookiesexceptions.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'cookiesexceptions.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/default.ui.h b/tests/auto/tools/uic/baseline/default.ui.h index 43de3c2f7c..af68bac7fd 100644 --- a/tests/auto/tools/uic/baseline/default.ui.h +++ b/tests/auto/tools/uic/baseline/default.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'default.ui' ** -** Created by: Qt User Interface Compiler version 5.10.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/dialog.ui.h b/tests/auto/tools/uic/baseline/dialog.ui.h index 2a159312b9..4c0edf4127 100644 --- a/tests/auto/tools/uic/baseline/dialog.ui.h +++ b/tests/auto/tools/uic/baseline/dialog.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'dialog.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/downloaditem.ui.h b/tests/auto/tools/uic/baseline/downloaditem.ui.h index f0e8e88307..b4a5e23226 100644 --- a/tests/auto/tools/uic/baseline/downloaditem.ui.h +++ b/tests/auto/tools/uic/baseline/downloaditem.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'downloaditem.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/downloads.ui.h b/tests/auto/tools/uic/baseline/downloads.ui.h index 1df992d30f..5b9f405f8f 100644 --- a/tests/auto/tools/uic/baseline/downloads.ui.h +++ b/tests/auto/tools/uic/baseline/downloads.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'downloads.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/embeddeddialog.ui.h b/tests/auto/tools/uic/baseline/embeddeddialog.ui.h index 7e6bf06df4..eb07718da3 100644 --- a/tests/auto/tools/uic/baseline/embeddeddialog.ui.h +++ b/tests/auto/tools/uic/baseline/embeddeddialog.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'embeddeddialog.ui' ** -** Created by: Qt User Interface Compiler version 5.10.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/filespage.ui.h b/tests/auto/tools/uic/baseline/filespage.ui.h index 29ed981a8a..8738109bd5 100644 --- a/tests/auto/tools/uic/baseline/filespage.ui.h +++ b/tests/auto/tools/uic/baseline/filespage.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'filespage.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/filternamedialog.ui.h b/tests/auto/tools/uic/baseline/filternamedialog.ui.h index 716c291fdd..8e5782c387 100644 --- a/tests/auto/tools/uic/baseline/filternamedialog.ui.h +++ b/tests/auto/tools/uic/baseline/filternamedialog.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'filternamedialog.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/filterpage.ui.h b/tests/auto/tools/uic/baseline/filterpage.ui.h index f6610fdc4d..a899938e33 100644 --- a/tests/auto/tools/uic/baseline/filterpage.ui.h +++ b/tests/auto/tools/uic/baseline/filterpage.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'filterpage.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/finddialog.ui.h b/tests/auto/tools/uic/baseline/finddialog.ui.h index 21be24f111..843c747b72 100644 --- a/tests/auto/tools/uic/baseline/finddialog.ui.h +++ b/tests/auto/tools/uic/baseline/finddialog.ui.h @@ -31,7 +31,7 @@ /******************************************************************************** ** Form generated from reading UI file 'finddialog.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/form.ui.h b/tests/auto/tools/uic/baseline/form.ui.h index ecc63e339b..9fda6daac4 100644 --- a/tests/auto/tools/uic/baseline/form.ui.h +++ b/tests/auto/tools/uic/baseline/form.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'form.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/formwindowsettings.ui.h b/tests/auto/tools/uic/baseline/formwindowsettings.ui.h index b25055b545..e18b72cb5b 100644 --- a/tests/auto/tools/uic/baseline/formwindowsettings.ui.h +++ b/tests/auto/tools/uic/baseline/formwindowsettings.ui.h @@ -31,7 +31,7 @@ /******************************************************************************** ** Form generated from reading UI file 'formwindowsettings.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/generalpage.ui.h b/tests/auto/tools/uic/baseline/generalpage.ui.h index bd04285d28..f13cc7faca 100644 --- a/tests/auto/tools/uic/baseline/generalpage.ui.h +++ b/tests/auto/tools/uic/baseline/generalpage.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'generalpage.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/gridalignment.ui.h b/tests/auto/tools/uic/baseline/gridalignment.ui.h index 421f257c9a..c8ce4bc477 100644 --- a/tests/auto/tools/uic/baseline/gridalignment.ui.h +++ b/tests/auto/tools/uic/baseline/gridalignment.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'gridalignment.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/gridpanel.ui.h b/tests/auto/tools/uic/baseline/gridpanel.ui.h index 94d4bc943e..22b639a95f 100644 --- a/tests/auto/tools/uic/baseline/gridpanel.ui.h +++ b/tests/auto/tools/uic/baseline/gridpanel.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'gridpanel.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/helpdialog.ui.h b/tests/auto/tools/uic/baseline/helpdialog.ui.h index 7a3fced1db..070f0484f1 100644 --- a/tests/auto/tools/uic/baseline/helpdialog.ui.h +++ b/tests/auto/tools/uic/baseline/helpdialog.ui.h @@ -31,7 +31,7 @@ /******************************************************************************** ** Form generated from reading UI file 'helpdialog.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/history.ui.h b/tests/auto/tools/uic/baseline/history.ui.h index 715312d11a..30477b8fb6 100644 --- a/tests/auto/tools/uic/baseline/history.ui.h +++ b/tests/auto/tools/uic/baseline/history.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'history.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/icontheme.ui.h b/tests/auto/tools/uic/baseline/icontheme.ui.h index 936d6b5cf7..3baf5539ee 100644 --- a/tests/auto/tools/uic/baseline/icontheme.ui.h +++ b/tests/auto/tools/uic/baseline/icontheme.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'icontheme.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/idbased.ui.h b/tests/auto/tools/uic/baseline/idbased.ui.h index c463a47fc8..0209895a3c 100644 --- a/tests/auto/tools/uic/baseline/idbased.ui.h +++ b/tests/auto/tools/uic/baseline/idbased.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'idbased.ui' ** -** Created by: Qt User Interface Compiler version 5.11.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/identifierpage.ui.h b/tests/auto/tools/uic/baseline/identifierpage.ui.h index 322a9cf30a..c0d86de1b3 100644 --- a/tests/auto/tools/uic/baseline/identifierpage.ui.h +++ b/tests/auto/tools/uic/baseline/identifierpage.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'identifierpage.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/imagedialog.ui.h b/tests/auto/tools/uic/baseline/imagedialog.ui.h index e32e7639fa..78384a21e4 100644 --- a/tests/auto/tools/uic/baseline/imagedialog.ui.h +++ b/tests/auto/tools/uic/baseline/imagedialog.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'imagedialog.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/inputpage.ui.h b/tests/auto/tools/uic/baseline/inputpage.ui.h index 9367dec6df..26bcca1ca4 100644 --- a/tests/auto/tools/uic/baseline/inputpage.ui.h +++ b/tests/auto/tools/uic/baseline/inputpage.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'inputpage.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/installdialog.ui.h b/tests/auto/tools/uic/baseline/installdialog.ui.h index 3ec7f69b76..45a0431f15 100644 --- a/tests/auto/tools/uic/baseline/installdialog.ui.h +++ b/tests/auto/tools/uic/baseline/installdialog.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'installdialog.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/languagesdialog.ui.h b/tests/auto/tools/uic/baseline/languagesdialog.ui.h index 216b610271..b04d8f1766 100644 --- a/tests/auto/tools/uic/baseline/languagesdialog.ui.h +++ b/tests/auto/tools/uic/baseline/languagesdialog.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'languagesdialog.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/listwidgeteditor.ui.h b/tests/auto/tools/uic/baseline/listwidgeteditor.ui.h index 93d9c78901..56df9f1beb 100644 --- a/tests/auto/tools/uic/baseline/listwidgeteditor.ui.h +++ b/tests/auto/tools/uic/baseline/listwidgeteditor.ui.h @@ -31,7 +31,7 @@ /******************************************************************************** ** Form generated from reading UI file 'listwidgeteditor.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/mainwindow.ui.h b/tests/auto/tools/uic/baseline/mainwindow.ui.h index fe84d0baa3..ed13a49860 100644 --- a/tests/auto/tools/uic/baseline/mainwindow.ui.h +++ b/tests/auto/tools/uic/baseline/mainwindow.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'mainwindow.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/mydialog.ui.h b/tests/auto/tools/uic/baseline/mydialog.ui.h index daa06528e8..940e13484a 100644 --- a/tests/auto/tools/uic/baseline/mydialog.ui.h +++ b/tests/auto/tools/uic/baseline/mydialog.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'mydialog.ui' ** -** Created by: Qt User Interface Compiler version 5.9.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/myform.ui.h b/tests/auto/tools/uic/baseline/myform.ui.h index d3a08e04c9..20de979fb5 100644 --- a/tests/auto/tools/uic/baseline/myform.ui.h +++ b/tests/auto/tools/uic/baseline/myform.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'myform.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/newactiondialog.ui.h b/tests/auto/tools/uic/baseline/newactiondialog.ui.h index d3d55f7a2a..6b8f8bb9d7 100644 --- a/tests/auto/tools/uic/baseline/newactiondialog.ui.h +++ b/tests/auto/tools/uic/baseline/newactiondialog.ui.h @@ -31,7 +31,7 @@ /******************************************************************************** ** Form generated from reading UI file 'newactiondialog.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/newdynamicpropertydialog.ui.h b/tests/auto/tools/uic/baseline/newdynamicpropertydialog.ui.h index f5fd6f1fa4..96b52a6549 100644 --- a/tests/auto/tools/uic/baseline/newdynamicpropertydialog.ui.h +++ b/tests/auto/tools/uic/baseline/newdynamicpropertydialog.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'newdynamicpropertydialog.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/newform.ui.h b/tests/auto/tools/uic/baseline/newform.ui.h index 80e70dcf66..ff4746a500 100644 --- a/tests/auto/tools/uic/baseline/newform.ui.h +++ b/tests/auto/tools/uic/baseline/newform.ui.h @@ -31,7 +31,7 @@ /******************************************************************************** ** Form generated from reading UI file 'newform.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/orderdialog.ui.h b/tests/auto/tools/uic/baseline/orderdialog.ui.h index 8cce528e1e..26dbacf133 100644 --- a/tests/auto/tools/uic/baseline/orderdialog.ui.h +++ b/tests/auto/tools/uic/baseline/orderdialog.ui.h @@ -31,7 +31,7 @@ /******************************************************************************** ** Form generated from reading UI file 'orderdialog.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/outputpage.ui.h b/tests/auto/tools/uic/baseline/outputpage.ui.h index 00491bb3d8..127f20d9fe 100644 --- a/tests/auto/tools/uic/baseline/outputpage.ui.h +++ b/tests/auto/tools/uic/baseline/outputpage.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'outputpage.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/pagefold.ui.h b/tests/auto/tools/uic/baseline/pagefold.ui.h index 684b365866..bcd11c14ff 100644 --- a/tests/auto/tools/uic/baseline/pagefold.ui.h +++ b/tests/auto/tools/uic/baseline/pagefold.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'pagefold.ui' ** -** Created by: Qt User Interface Compiler version 5.10.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/paletteeditor.ui.h b/tests/auto/tools/uic/baseline/paletteeditor.ui.h index 0061164960..9be067eec3 100644 --- a/tests/auto/tools/uic/baseline/paletteeditor.ui.h +++ b/tests/auto/tools/uic/baseline/paletteeditor.ui.h @@ -31,7 +31,7 @@ /******************************************************************************** ** Form generated from reading UI file 'paletteeditor.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/passworddialog.ui.h b/tests/auto/tools/uic/baseline/passworddialog.ui.h index 9ab95c4de9..4f59efabb9 100644 --- a/tests/auto/tools/uic/baseline/passworddialog.ui.h +++ b/tests/auto/tools/uic/baseline/passworddialog.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'passworddialog.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/pathpage.ui.h b/tests/auto/tools/uic/baseline/pathpage.ui.h index eb151f9550..b71f76e3a5 100644 --- a/tests/auto/tools/uic/baseline/pathpage.ui.h +++ b/tests/auto/tools/uic/baseline/pathpage.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'pathpage.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/phrasebookbox.ui.h b/tests/auto/tools/uic/baseline/phrasebookbox.ui.h index 06c0f97bce..9d7d5e8983 100644 --- a/tests/auto/tools/uic/baseline/phrasebookbox.ui.h +++ b/tests/auto/tools/uic/baseline/phrasebookbox.ui.h @@ -31,7 +31,7 @@ /******************************************************************************** ** Form generated from reading UI file 'phrasebookbox.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/plugindialog.ui.h b/tests/auto/tools/uic/baseline/plugindialog.ui.h index 3634b8436f..d25bfd1316 100644 --- a/tests/auto/tools/uic/baseline/plugindialog.ui.h +++ b/tests/auto/tools/uic/baseline/plugindialog.ui.h @@ -31,7 +31,7 @@ /******************************************************************************** ** Form generated from reading UI file 'plugindialog.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/preferencesdialog.ui.h b/tests/auto/tools/uic/baseline/preferencesdialog.ui.h index 289e6775b4..d81823fe75 100644 --- a/tests/auto/tools/uic/baseline/preferencesdialog.ui.h +++ b/tests/auto/tools/uic/baseline/preferencesdialog.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'preferencesdialog.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/previewconfigurationwidget.ui.h b/tests/auto/tools/uic/baseline/previewconfigurationwidget.ui.h index 3c729b9c65..cabdedeb97 100644 --- a/tests/auto/tools/uic/baseline/previewconfigurationwidget.ui.h +++ b/tests/auto/tools/uic/baseline/previewconfigurationwidget.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'previewconfigurationwidget.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/previewdialogbase.ui.h b/tests/auto/tools/uic/baseline/previewdialogbase.ui.h index 05152726a8..7c86215077 100644 --- a/tests/auto/tools/uic/baseline/previewdialogbase.ui.h +++ b/tests/auto/tools/uic/baseline/previewdialogbase.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'previewdialogbase.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/previewwidget.ui.h b/tests/auto/tools/uic/baseline/previewwidget.ui.h index 6e359416c8..a423ee7ff4 100644 --- a/tests/auto/tools/uic/baseline/previewwidget.ui.h +++ b/tests/auto/tools/uic/baseline/previewwidget.ui.h @@ -31,7 +31,7 @@ /******************************************************************************** ** Form generated from reading UI file 'previewwidget.ui' ** -** Created by: Qt User Interface Compiler version 5.10.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/proxy.ui.h b/tests/auto/tools/uic/baseline/proxy.ui.h index a1bc287190..47a15cc31b 100644 --- a/tests/auto/tools/uic/baseline/proxy.ui.h +++ b/tests/auto/tools/uic/baseline/proxy.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'proxy.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/qfiledialog.ui.h b/tests/auto/tools/uic/baseline/qfiledialog.ui.h index 011346bf11..a544afa31d 100644 --- a/tests/auto/tools/uic/baseline/qfiledialog.ui.h +++ b/tests/auto/tools/uic/baseline/qfiledialog.ui.h @@ -31,7 +31,7 @@ /******************************************************************************** ** Form generated from reading UI file 'qfiledialog.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/qprintpropertieswidget.ui.h b/tests/auto/tools/uic/baseline/qprintpropertieswidget.ui.h index 8626a9fc3c..bedb6e184d 100644 --- a/tests/auto/tools/uic/baseline/qprintpropertieswidget.ui.h +++ b/tests/auto/tools/uic/baseline/qprintpropertieswidget.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'qprintpropertieswidget.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/qprintsettingsoutput.ui.h b/tests/auto/tools/uic/baseline/qprintsettingsoutput.ui.h index ee4227b4e4..2bf7584a61 100644 --- a/tests/auto/tools/uic/baseline/qprintsettingsoutput.ui.h +++ b/tests/auto/tools/uic/baseline/qprintsettingsoutput.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'qprintsettingsoutput.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/qprintwidget.ui.h b/tests/auto/tools/uic/baseline/qprintwidget.ui.h index f7e326b84a..d624e28297 100644 --- a/tests/auto/tools/uic/baseline/qprintwidget.ui.h +++ b/tests/auto/tools/uic/baseline/qprintwidget.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'qprintwidget.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/qsqlconnectiondialog.ui.h b/tests/auto/tools/uic/baseline/qsqlconnectiondialog.ui.h index a557fb984a..557918375a 100644 --- a/tests/auto/tools/uic/baseline/qsqlconnectiondialog.ui.h +++ b/tests/auto/tools/uic/baseline/qsqlconnectiondialog.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'qsqlconnectiondialog.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/qtgradientdialog.ui.h b/tests/auto/tools/uic/baseline/qtgradientdialog.ui.h index 805f70e60d..8ef2e5f6de 100644 --- a/tests/auto/tools/uic/baseline/qtgradientdialog.ui.h +++ b/tests/auto/tools/uic/baseline/qtgradientdialog.ui.h @@ -31,7 +31,7 @@ /******************************************************************************** ** Form generated from reading UI file 'qtgradientdialog.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/qtgradientview.ui.h b/tests/auto/tools/uic/baseline/qtgradientview.ui.h index aa3c03b02f..5e2ff941b7 100644 --- a/tests/auto/tools/uic/baseline/qtgradientview.ui.h +++ b/tests/auto/tools/uic/baseline/qtgradientview.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'qtgradientview.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/qtgradientviewdialog.ui.h b/tests/auto/tools/uic/baseline/qtgradientviewdialog.ui.h index e6d98ed4f0..567ec0b5e5 100644 --- a/tests/auto/tools/uic/baseline/qtgradientviewdialog.ui.h +++ b/tests/auto/tools/uic/baseline/qtgradientviewdialog.ui.h @@ -31,7 +31,7 @@ /******************************************************************************** ** Form generated from reading UI file 'qtgradientviewdialog.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/qtresourceeditordialog.ui.h b/tests/auto/tools/uic/baseline/qtresourceeditordialog.ui.h index b97833dd63..6b394d7e8e 100644 --- a/tests/auto/tools/uic/baseline/qtresourceeditordialog.ui.h +++ b/tests/auto/tools/uic/baseline/qtresourceeditordialog.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'qtresourceeditordialog.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/qttoolbardialog.ui.h b/tests/auto/tools/uic/baseline/qttoolbardialog.ui.h index d80b123c02..7d8f91067c 100644 --- a/tests/auto/tools/uic/baseline/qttoolbardialog.ui.h +++ b/tests/auto/tools/uic/baseline/qttoolbardialog.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'qttoolbardialog.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/querywidget.ui.h b/tests/auto/tools/uic/baseline/querywidget.ui.h index 81516722d5..f1403d829d 100644 --- a/tests/auto/tools/uic/baseline/querywidget.ui.h +++ b/tests/auto/tools/uic/baseline/querywidget.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'querywidget.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/remotecontrol.ui.h b/tests/auto/tools/uic/baseline/remotecontrol.ui.h index 5893ff42af..aa4238c612 100644 --- a/tests/auto/tools/uic/baseline/remotecontrol.ui.h +++ b/tests/auto/tools/uic/baseline/remotecontrol.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'remotecontrol.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/saveformastemplate.ui.h b/tests/auto/tools/uic/baseline/saveformastemplate.ui.h index 00d92eb602..3beff599a8 100644 --- a/tests/auto/tools/uic/baseline/saveformastemplate.ui.h +++ b/tests/auto/tools/uic/baseline/saveformastemplate.ui.h @@ -31,7 +31,7 @@ /******************************************************************************** ** Form generated from reading UI file 'saveformastemplate.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/settings.ui.h b/tests/auto/tools/uic/baseline/settings.ui.h index cc680c8033..d17b935239 100644 --- a/tests/auto/tools/uic/baseline/settings.ui.h +++ b/tests/auto/tools/uic/baseline/settings.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'settings.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/signalslotdialog.ui.h b/tests/auto/tools/uic/baseline/signalslotdialog.ui.h index be48da9218..984198ba83 100644 --- a/tests/auto/tools/uic/baseline/signalslotdialog.ui.h +++ b/tests/auto/tools/uic/baseline/signalslotdialog.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'signalslotdialog.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/sslclient.ui.h b/tests/auto/tools/uic/baseline/sslclient.ui.h index 382889648e..794577d3d9 100644 --- a/tests/auto/tools/uic/baseline/sslclient.ui.h +++ b/tests/auto/tools/uic/baseline/sslclient.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'sslclient.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/sslerrors.ui.h b/tests/auto/tools/uic/baseline/sslerrors.ui.h index 04f21ded43..a5c9b1b697 100644 --- a/tests/auto/tools/uic/baseline/sslerrors.ui.h +++ b/tests/auto/tools/uic/baseline/sslerrors.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'sslerrors.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/statistics.ui.h b/tests/auto/tools/uic/baseline/statistics.ui.h index 0b508836f2..02bd4cdfd1 100644 --- a/tests/auto/tools/uic/baseline/statistics.ui.h +++ b/tests/auto/tools/uic/baseline/statistics.ui.h @@ -31,7 +31,7 @@ /******************************************************************************** ** Form generated from reading UI file 'statistics.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/stringlisteditor.ui.h b/tests/auto/tools/uic/baseline/stringlisteditor.ui.h index 941c73799b..2baab1b90d 100644 --- a/tests/auto/tools/uic/baseline/stringlisteditor.ui.h +++ b/tests/auto/tools/uic/baseline/stringlisteditor.ui.h @@ -31,7 +31,7 @@ /******************************************************************************** ** Form generated from reading UI file 'stringlisteditor.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/stylesheeteditor.ui.h b/tests/auto/tools/uic/baseline/stylesheeteditor.ui.h index 5ae254ebab..4206f35857 100644 --- a/tests/auto/tools/uic/baseline/stylesheeteditor.ui.h +++ b/tests/auto/tools/uic/baseline/stylesheeteditor.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'stylesheeteditor.ui' ** -** Created by: Qt User Interface Compiler version 5.10.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/tabbedbrowser.ui.h b/tests/auto/tools/uic/baseline/tabbedbrowser.ui.h index 09b230f5df..d657a6cfcc 100644 --- a/tests/auto/tools/uic/baseline/tabbedbrowser.ui.h +++ b/tests/auto/tools/uic/baseline/tabbedbrowser.ui.h @@ -31,7 +31,7 @@ /******************************************************************************** ** Form generated from reading UI file 'tabbedbrowser.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/tablewidgeteditor.ui.h b/tests/auto/tools/uic/baseline/tablewidgeteditor.ui.h index e0287246d5..f108c05fbd 100644 --- a/tests/auto/tools/uic/baseline/tablewidgeteditor.ui.h +++ b/tests/auto/tools/uic/baseline/tablewidgeteditor.ui.h @@ -31,7 +31,7 @@ /******************************************************************************** ** Form generated from reading UI file 'tablewidgeteditor.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/tetrixwindow.ui.h b/tests/auto/tools/uic/baseline/tetrixwindow.ui.h index dc1033ce3a..53d94b7f50 100644 --- a/tests/auto/tools/uic/baseline/tetrixwindow.ui.h +++ b/tests/auto/tools/uic/baseline/tetrixwindow.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'tetrixwindow.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/textfinder.ui.h b/tests/auto/tools/uic/baseline/textfinder.ui.h index ccad9a37c3..1cc082b34c 100644 --- a/tests/auto/tools/uic/baseline/textfinder.ui.h +++ b/tests/auto/tools/uic/baseline/textfinder.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'textfinder.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/topicchooser.ui.h b/tests/auto/tools/uic/baseline/topicchooser.ui.h index 972fc485c0..00e30bd546 100644 --- a/tests/auto/tools/uic/baseline/topicchooser.ui.h +++ b/tests/auto/tools/uic/baseline/topicchooser.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'topicchooser.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/translatedialog.ui.h b/tests/auto/tools/uic/baseline/translatedialog.ui.h index 680f3e7f28..dec725ac8f 100644 --- a/tests/auto/tools/uic/baseline/translatedialog.ui.h +++ b/tests/auto/tools/uic/baseline/translatedialog.ui.h @@ -31,7 +31,7 @@ /******************************************************************************** ** Form generated from reading UI file 'translatedialog.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/translationsettings.ui.h b/tests/auto/tools/uic/baseline/translationsettings.ui.h index 7c001786c7..88b0128e1b 100644 --- a/tests/auto/tools/uic/baseline/translationsettings.ui.h +++ b/tests/auto/tools/uic/baseline/translationsettings.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'translationsettings.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/treewidgeteditor.ui.h b/tests/auto/tools/uic/baseline/treewidgeteditor.ui.h index a15798ab92..57347f2464 100644 --- a/tests/auto/tools/uic/baseline/treewidgeteditor.ui.h +++ b/tests/auto/tools/uic/baseline/treewidgeteditor.ui.h @@ -31,7 +31,7 @@ /******************************************************************************** ** Form generated from reading UI file 'treewidgeteditor.ui' ** -** Created by: Qt User Interface Compiler version 5.0.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/trpreviewtool.ui.h b/tests/auto/tools/uic/baseline/trpreviewtool.ui.h index 4b7d861191..e99bf81a4c 100644 --- a/tests/auto/tools/uic/baseline/trpreviewtool.ui.h +++ b/tests/auto/tools/uic/baseline/trpreviewtool.ui.h @@ -31,7 +31,7 @@ /******************************************************************************** ** Form generated from reading UI file 'trpreviewtool.ui' ** -** Created by: Qt User Interface Compiler version 5.9.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/baseline/wateringconfigdialog.ui.h b/tests/auto/tools/uic/baseline/wateringconfigdialog.ui.h index d6f7ff5526..822a22336d 100644 --- a/tests/auto/tools/uic/baseline/wateringconfigdialog.ui.h +++ b/tests/auto/tools/uic/baseline/wateringconfigdialog.ui.h @@ -1,7 +1,7 @@ /******************************************************************************** ** Form generated from reading UI file 'wateringconfigdialog.ui' ** -** Created by: Qt User Interface Compiler version 5.10.0 +** Created by: Qt User Interface Compiler version 5.12.0 ** ** WARNING! All changes made in this file will be lost when recompiling UI file! ********************************************************************************/ diff --git a/tests/auto/tools/uic/tst_uic.cpp b/tests/auto/tools/uic/tst_uic.cpp index 85668c96d4..f9553028fe 100644 --- a/tests/auto/tools/uic/tst_uic.cpp +++ b/tests/auto/tools/uic/tst_uic.cpp @@ -37,6 +37,11 @@ #include #include +#include + +static const char keepEnvVar[] = "UIC_KEEP_GENERATED_FILES"; +static const char diffToStderrEnvVar[] = "UIC_STDERR_DIFF"; + class tst_uic : public QObject { Q_OBJECT @@ -69,7 +74,7 @@ private: tst_uic::tst_uic() : m_command(QLibraryInfo::location(QLibraryInfo::BinariesPath) + QLatin1String("/uic")) - , m_versionRegexp(QLatin1String("\\*\\* Created by: Qt User Interface Compiler version \\d{1,2}\\.\\d{1,2}\\.\\d{1,2}")) + , m_versionRegexp(QLatin1String(R"(\*\* Created by: Qt User Interface Compiler version \d{1,2}\.\d{1,2}\.\d{1,2})")) { } @@ -103,14 +108,19 @@ void tst_uic::initTestCase() qDebug("%s", qPrintable(msg)); } +static const char helpFormat[] = R"( +Note: The environment variable '%s' can be set to keep the temporary files +for error analysis. +The environment variable '%s' can be set to redirect the diff output to +stderr.)"; + void tst_uic::cleanupTestCase() { - static const char envVar[] = "UIC_KEEP_GENERATED_FILES"; - if (qgetenv(envVar).isEmpty()) { - qDebug("Note: The environment variable '%s' can be set to keep the temporary files for error analysis.", envVar); - } else { + if (qEnvironmentVariableIsSet(keepEnvVar)) { m_generated.setAutoRemove(false); qDebug("Keeping generated files in '%s'", qPrintable(QDir::toNativeSeparators(m_generated.path()))); + } else { + qDebug(helpFormat, keepEnvVar, diffToStderrEnvVar); } } @@ -152,7 +162,7 @@ void tst_uic::run() QVERIFY(process.waitForFinished()); QCOMPARE(process.exitStatus(), QProcess::NormalExit); QCOMPARE(process.exitCode(), 0); - QCOMPARE(QFileInfo(generatedFile).exists(), true); + QVERIFY(QFileInfo::exists(generatedFile)); } void tst_uic::run_data() const @@ -212,6 +222,16 @@ static QByteArray msgCannotReadFile(const QFile &file) return result.toLocal8Bit(); } +static void outputDiff(const QString &diff) +{ + // Use patch -p3 < diff to apply the obtained diff output in the baseline directory. + static const bool diffToStderr = qEnvironmentVariableIsSet(diffToStderrEnvVar); + if (diffToStderr) + std::fputs(qPrintable(diff), stderr); + else + qWarning("Difference:\n%s", qPrintable(diff)); +} + void tst_uic::compare() { QFETCH(QString, originalFile); @@ -233,7 +253,7 @@ void tst_uic::compare() if (generatedFileContents != originalFileContents) { const QString diff = generateDiff(originalFile, generatedFile); if (!diff.isEmpty()) - qWarning().noquote().nospace() << "Difference:\n" << diff; + outputDiff(diff); } QCOMPARE(generatedFileContents, originalFileContents); @@ -274,7 +294,7 @@ void tst_uic::runTranslation() QVERIFY(process.waitForFinished()); QCOMPARE(process.exitStatus(), QProcess::NormalExit); QCOMPARE(process.exitCode(), 0); - QCOMPARE(QFileInfo(generatedFile).exists(), true); + QVERIFY(QFileInfo::exists(generatedFile)); } @@ -301,7 +321,7 @@ void tst_uic::runCompare() if (generatedFileContents != originalFileContents) { const QString diff = generateDiff(originalFile, generatedFile); if (!diff.isEmpty()) - qWarning().noquote().nospace() << "Difference:\n" << diff; + outputDiff(diff); } QCOMPARE(generatedFileContents, originalFileContents); From 5cabf50164fa113bb427095f06620b3f6483d5e2 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 13 Nov 2018 14:10:43 +0100 Subject: [PATCH 0306/1650] Check if the string inside the families list is empty and not the list This amends 97f73e957756753b09a778daf2ee8f0ddb97f746 and accounts for when the minimial QPA platform is used ensuring the fallback to the QFontEngineBox. Task-number: QTBUG-71743 Change-Id: I72d45e02754fe31e31a2234d53c45e1d20dfa3d2 Reviewed-by: Liang Qi Reviewed-by: Allan Sandfeld Jensen --- src/gui/text/qfontdatabase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 42e7871214..fa9573441a 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -2830,7 +2830,7 @@ void QFontDatabase::load(const QFontPrivate *d, int script) fe = QFontDatabase::findFont(req, script); if (fe) { - if (fe->type() == QFontEngine::Box && !req.families.isEmpty()) { + if (fe->type() == QFontEngine::Box && !req.families.at(0).isEmpty()) { if (fe->ref.load() == 0) delete fe; fe = 0; From 299734c3ee96055f72557cf8c25221bab5ce1a11 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Mon, 5 Nov 2018 11:16:28 +0100 Subject: [PATCH 0307/1650] Revert "Revert "qmake: Work around MSVC compiler bug."" The assert still happens on MSVC 2015 64 bit when running qmake -tp vc -r. This reverts commit f4169a633b97b7b6e7365172cf3d38d2f16a8914. Fixes: QTBUG-71228 Change-Id: I05bd3e0677414edb970f07e0555cdc95ce32f592 Reviewed-by: Friedemann Kleint (cherry picked from commit 4be8168ff7fe8c871a7f3cd7dce8fa4f70e1a6cf) Reviewed-by: Joerg Bornemann --- qmake/generators/win32/msvc_vcproj.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index f7837fc1b4..95c16661e7 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -208,6 +208,16 @@ struct VcsolutionDepend { QStringList dependencies; }; +/* Disable optimization in getProjectUUID() due to a compiler + * bug in MSVC 2015 that causes ASSERT: "&other != this" in the QString + * copy constructor for non-empty file names at: + * filename.isEmpty()?project->first("QMAKE_MAKEFILE"):filename */ + +#if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG) +# pragma optimize( "g", off ) +# pragma warning ( disable : 4748 ) +#endif + QUuid VcprojGenerator::getProjectUUID(const QString &filename) { bool validUUID = true; @@ -239,6 +249,10 @@ QUuid VcprojGenerator::getProjectUUID(const QString &filename) return uuid; } +#if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG) +# pragma optimize( "g", on ) +#endif + QUuid VcprojGenerator::increaseUUID(const QUuid &id) { QUuid result(id); From 98a445fa23e7943f25d2de2f1fb36c104d5d7fda Mon Sep 17 00:00:00 2001 From: Antti Kokko Date: Wed, 31 Oct 2018 11:13:12 +0200 Subject: [PATCH 0308/1650] Add changes file for Qt 5.12.0 Edited-by: Thiago Macieira Change-Id: I65a59400c802db282fdbd87b1b9b89e9e5e962f6 Reviewed-by: Shawn Rutledge Reviewed-by: Edward Welbourne Reviewed-by: Tuukka Turunen Reviewed-by: Thiago Macieira --- dist/changes-5.12.0 | 470 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 470 insertions(+) create mode 100644 dist/changes-5.12.0 diff --git a/dist/changes-5.12.0 b/dist/changes-5.12.0 new file mode 100644 index 0000000000..fbed338b46 --- /dev/null +++ b/dist/changes-5.12.0 @@ -0,0 +1,470 @@ +Qt 5.12 introduces many new features and improvements as well as bugfixes +over the 5.11.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.12 series is binary compatible with the 5.11.x series. +Applications compiled for 5.11 will continue to run with 5.12. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Important Behavior Changes * +**************************************************************************** + + - QtCore: + * [QTBUG-34460] qFatal() no longer uses std::abort() on Windows, as + there are circumstances where global destructors are still run after + that call, leading to possible deadlocks. + - QRegularExpression: + * [QTBUG-66781] Regular expressions are now automatically optimized + (including JIT compiling) on their first usage. The pattern options + OptimizeOnFirstUsageOption and DontAutomaticallyOptimizeOption no + longer have any effect, and will get removed in a future version of + Qt. QRegularExpression::optimize() can be still used to compile and + optimize the regular expression in advance (before any match), if + needed. + - QDataStream: + * [QTBUG-59978][QTBUG-67995] version bumped up to 18 to account for + changes in the serialization of QGradient. + - Dialogs: + * QFileSystemModel now uses QRegularExpression internally for wildcard + matching. Note that QRegularExpression might not give the exact same + result as QRegExp as its implementation follows strictly the glob + patterns definition for wildcard expressions. + +**************************************************************************** +* Third-Party Code * +**************************************************************************** + + - Sources of xcb-xinput 1.13 were bundled and are available via -qt-xcb. + - The minimal required version of libxcb is now 1.9. Bundled xcb sources + were updated to libxcb 1.9.1 built with xcb-proto 1.8. + - [QTBUG-67654] Updated CLDR to version 33.1 + - [QTBUG-66561][QTBUG-70008] double-conversion got updated to upstream + version 3.1.1. + - libjpeg-turbo was updated to version 2.0.0 + - libpng was updated to version 1.6.35 + - Sqlite was updated to version 3.25.2 + - [QTBUG-71109] updated bundled libxkbcommon 0.4.1 -> 0.8.2 (up to + 31f1f355700870c6615399fbfa7934934b3a9a57) + - PCRE2 was updated to version 10.32. + - Added documentation for the SLJIT part of pcre2, which is available + under the BSD-2-Clause license. + +**************************************************************************** +* Tools * +**************************************************************************** + + - rcc: + * Added a --list-mapping option which shows a mapping of resource paths + to file system paths. + + - qmake + * New CONFIG options lrelease and embed_translations were added. + CONFIG+=lrelease does run lrelease on translation files listed in + TRANSLATIONS and EXTRA_TRANSLATIONS. CONFIG+=embed_translations does + include the generated .qm files as resources under :/i18n/. + + - uic + * [QTBUG-65251][QTBUG-51602] The -no-stringliteral option is now + deprecated and UIC will not generate QStringLiteral anymore. + +**************************************************************************** +* QtCore * +**************************************************************************** + + - Added support for CBOR: + * Added QCborStreamReader and QCborStreamWriter, classes for low-level + reading and writing of CBOR streams. + * Added QCborValue, QCborArray and QCborMap, classes that permit DOM-like + access to CBOR data. The API is similar to QJsonValue, QJsonArray and + QJsonObject, respectively. + + - QByteArray: + * Added QByteArray::isUpper() and QByteArray::isLower() to check if a + byte array contains only uppercase or only lowercase Latin1 letters. + * Added compare(), which takes Qt::CaseSensitivity as one of the + parameters. This function is more efficient than using toLower() or + toUpper() and then comparing. + * [QTBUG-66187] QByteArray::toInt(), QByteArray::toDouble() and the + other number conversion functions now ignore leading and trailing + whitespaces, as their QString counterparts already did. For + consistency reasons, the same behavior was added to + qEnvironmentVariableIntValue() also. + + - QCommandLineParser: + * [QTBUG-70174] Fixed a bug that caused the help output to show two + options or more in the same line if the options didn't have a + description. + + - QCryptographicHash: + * Add a static method, hashLength, which returns the length of the + output of a hash function in bytes. + + - QDir: + * QDir now uses QRegularExpression internally for wildcard matching. + Note that QRegularExpression might not give the exact same result as + QRegExp as its implementation follows strictly the glob patterns + definition for wildcard expressions. Nevertheless, the tests for QDir + return the same results as before. + * QDir::tempPath() now reports the canonical path of the temporary + directory, with any symlinks resolved. + * On Windows, QDir::drives() no longer returns drives whose media were + ejected. + + - QExplicitlySharedDataPointer: + * [QTBUG-66635][QTBUG-66946] Added operator== for nullptr. + + - QFile: + * [QTBUG-13470] When opening a file, if Truncate is asked for, or + implied by other flags, it shall be attempted, regardless of what + other options are selected. We previously did this on Windows; now we + do so also on Unix (even when appending). + + - QFileSystemWatcher: + * [QTBUG-69320] Fixed a bug that caused addPaths() to crash on Windows + if adding a path to be watched on removable storage, if that + addPaths() was called on a thread not created by QThread and no + QEventLoop has been created yet. + + - QFlags's operator| for enum types in the Qt namespace are now declared + in the Qt namespace itself. + + - QLocale: + * [QTBUG-57802] Added support for World and Europe as (numeric) + "country" codes ("territory" in CLDR terms), thereby enabling support + for Yiddish and Esperanto, among other locales using such codes. + + - Logging: + * [QTBUG-69548] Qt will now accept qtlogging.ini files written by + QSettings. + + - QMetaType can now register constructor for a set of dynamic types. + + - QRegularExpression: + * Implemented support for wildcard patterns through a static method. + * QRegularExpression now provides anchoredPattern() which is a helper + function to build regular expressions used for exact matching. + * Implemented support for wildcard patterns. Warning: QRegularExpression + might not give the exact same result as QRegExp as its implementation + follows strictly the glob patterns definition for the wildcard + expressions. + + - [QTBUG-62894] Introduced QScopeGuard. + + - QSharedDataPointer: + * [QTBUG-66635][QTBUG-66946] Added operator== for nullptr. + + - QSortFilterProxyModel: + * [QTBUG-46810] QSortFilterProxyModel now supports QRegularExpression. + * Setters of both the filterRegExp and filterRegularExpression + properties are now slots and can be used with the old as well as the + new syntax. + + - QString: + * Added the functions QString::isUpper() and QString::isLower() to check + if a string contains only uppercase or only lowercase letters. + + - QTextCodec: + * [QTBUG-56203] QTextCodec automatically deregisters on destruction now. + + - QTimer: + * [QTBUG-69800] Fixed singleShot() methods that lacked proper "const" + qualification to QObject context receivers. + * Added QTimer::connectTo(), a shorthand way of connecting to the + timeout() signal. + + - QTranslator: + * [QTBUG-31031] It is now possible to load qm files without any + translations. This is particularly useful for the language the + untranslated strings are written in; logic to load translations can + now handle the source language like all other languages. + + - QUndoStack: + * [QTBUG-40040] Exposed canUndo, canRedo, undoText, redoText and clean as + Q_PROPERTYs. + + - QUrl: + * Fixed a bug that caused QUrl::matches to incorrectly compare two URLs + with different hostnames or different usernames as equal, if certain + QUrl::RemoveXxx options were passed. + + - other: + * Added an overload of q{To,From}{Big,Little}Endian that operates on a + memory region. + * Added the QT_TR_N_NOOP(), QT_TRANSLATE_N_NOOP(), and + QT_TRANSLATE_N_NOOP3() macros for numeral dependent delayed + translation. + +**************************************************************************** +* QtGui * +**************************************************************************** + + - QBitmap: + * Added overloaded QBitmap::fromImage that takes QImage rvalue. + + - QDocumentWriter: + * [QTBUG-63581] QDocumentWriter now supports table borders, table + alignment, table width, column widths, line height and image + resolution when exporting QTextDocuments to ODF files. + + - QGradient: + * [QTBUG-59978][QTBUG-67995] Added ObjectMode coordinate mode. + + - QGuiApplication: + * [QTBUG-26413] Fixed queryKeyboardModifiers() on macOS to actually return + the current modifier key state. + + - QImage: + * [QTBUG-45858] QImage now supports 64bit image formats with 16 bits per + color channel, compatible with 16bpc PNG or RGBA16 OpenGL formats. + + - QIntValidator: + * [QTBUG-59650] Input value with over the highest acceptable value, but + with no more digits than the maximum value, is now considered + intermediate. + + - QOpenGLShader: + * [QTBUG-66074] QOpenGLShader has been fixed to expose geometry and + tessellation evaluation/control shaders with OpenGL ES 3.2. + + - QPagedPaintDevice: + * The default constructor has been deprecated since that class is + not meant to be used standalone. The two public but internal + devicePageLayout() methods are now deprecated. + + - QPainter: + * [QTBUG-67248] Fixed drawTiledPixmap() and texture-brush painting with + high-DPR images. + * QPainter::drawTiledPixmap() now tiles in the device independent + coordinate system. + + - QPicture: + * [QTBUG-71208] Fixed a crash reading malformed picture file. + + - QStandardItemModel: + * itemData does not return role 255 any more. + + - QTextImageFormat: + * Added two new functions to the class: setQuality(int=100) and + quality(). They are currently used by QTextODFWriter to determine the + image type and quality when exporting images to ODT files. + + - Text: + * [QTBUG-57479] Non-breaking spaces are now displayed as a degree symbol + when QTextOption::ShowTabsAndSpaces is used. + * [QTBUG-69085] Fixed position of text cursor set by clicking outside + the bounds of a text line that ends with a surrogate pair or ligature. + * [QTBUG-70293] Fixed a crash that can happen when calling a setter on a + QTextCursor after its QTextDocument has been deleted. + +**************************************************************************** +* QtNetwork * +**************************************************************************** + + - Added DTLS over UDP support. + + - QPasswordDigestor: + * [QTBUG-30550] Added QPasswordDigestor + + - QSslKey: + * [QTBUG-17718] The OpenSSL backend can now load encrypted PKCS#8 + DER-encoded keys. + * [QTBUG-59068] Added support for PKCS#8-encoded keys in the generic SSL + back-end (used for SecureTransport on macOS and for WinRT). Note that + it does not support keys encrypted with a PKCS#12 algorithm. + + - QSslSocket: + * Enabled ALPN (and thus HTTP/2 negotiation) in SecureTransport backend + (macOS). + * [QTBUG-69420] Implemented renegotiation for SecureTransport backend. + + - SSL: + * The OpenSSL 1.1 backend also works with OpenSSL 1.1.1 (and thus can + negotiate TLS 1.3). + * [QTBUG-68156] OpenSSL >= 1.0 is now required to build Qt with OpenSSL + support. + +**************************************************************************** +* QtSql * +**************************************************************************** + + - MySQL: + * Now supports MySQL versions >= 8.0.1. + * [QTBUG-57028] The TIME data type is now treated like a string-based + type in order to respect the full range of the TIME data type. + +**************************************************************************** +* QtTest * +**************************************************************************** + + - QCOMPARE: + * Now outputs contents of std::tuple on failure. + * [QTBUG-65845] QtTest now prints values of QFlags that failed to compare. + +**************************************************************************** +* QtWidgets * +**************************************************************************** + + - Itemviews: + * [QTBUG-12129][QTBUG-14949][QTBUG-57891] Fixed eliding of multi-line + items. + + - QAbstractSpinBox: + * [QTBUG-67380] The Qt::ControlModifier now increases the number of steps a + QAbstractSpinBox takes for the following interactions: scrolling, up/down + keyboard keys and the spin box buttons. Previously, Qt::ControlModifier + only affected scrolling. + + - QApplication: + * [QTBUG-67736] QApplication no longer sends a mouse move event to the + entered widget if it sends synthetic enter and leave events. + + - QHeaderView: + * [QTBUG-23203] Padding/margin is now taken into account when the text gets + elided. + * [QTBUG-59501] The qss padding attribute is now honored in all cases. + * [QTBUG-62091] The size of the decoration is now taken into account in + paintSection(). + * [QTBUG-65017] The drag'n'drop indicator is now using the correct font. + * [QTBUG-69431] setDefaultSectionSize() now checks if the given value is + inside min/max section size. + * [QTBUG-70084] The section indicator is now high-DPI-aware. + + - QItemDelegate: + * [QTBUG-16134] Fixed text height calculation when the item has a + decoration or checkbox. + + - QLineEdit: + * [QTBUG-44046] The textEdited() signal is now emitted even if the + QValidator has changed the user input. + * [QTBUG-57448] Added inputRejected() signal for when a key press is not + accepted by the QLineEdit. For instance, when an invalid key is + pressed for a validator set. + + - QListView: + * [QTBUG-27110] The pseudo states :first/:middle/:last are now respected. + * [QTBUG-56606] Added itemAlignment property. + * [QTBUG-67440] Fixed a bug that caused items on internal move to be + deleted. + + - QMenu: + * [QTBUG-69199] Removed icon highlight when a stylesheet was applied by + the application. + + - QMessageBox: + * [QTBUG-35545] On Android and iOS it's now possible to show a + QMessageBox with custom buttons as a native dialog. + + - QSpinBox/QDoubleSpinBox: + * Added an option for adaptive decimal step size. + + - QSplashScreen: + * [QTBUG-43081] The alignment when the message is passed as HTML is now + correctly honored. + + - QStyle: + * QStyle::SH_SpinBox_StepModifier allows the developer to pick which + keyboard modifier increases the number of steps a QAbstractSpinBox + takes for the following interactions: scrolling, up/down keyboard keys + and the spin box buttons. The Qt::ShiftModifier can now be used, or + the feature can be disabled using Qt::NoModifier. Previously, only + Qt::ControlModifier could be used as the modifier. + + - QTabBar: + * [QTBUG-18146] Fixed mixed up CSS pseudo class for left and right. + + - QTableView: + * [QTBUG-48244][QTBUG-49548] Fixed calculating geometries for editors. + * [QTBUG-70215] Fixed PageUp not getting to top when first row is hidden. + + - QTableWidget: + * Fixed handling of Qt::EditRole and Qt::DisplayRole in setItemData(). + + - QTreeView: + * [QTBUG-39486] Sped up expanding items when pressing asterisk. + + - QWidget: + * [QTBUG-68393][QTBUG-69619][QTBUG-10907] Fixed several bugs that + incorrectly reordered tabs for compound widgets under some special + circumstances. + * [QTBUG-65199] enterEvent() and leaveEvent() now occur when a hovering + drawing tablet stylus enters or leaves a widget. + * Added the Qt::WA_StyleSheetTarget attribute to indicate that a widget + was affected by a style sheet. + +**************************************************************************** +* Android * +**************************************************************************** + + - Added Android edit context menu. + - Removed old debugging bridge. To be able to debug Qt on Android apps the + user must use QtCreator 4.6.1+. + - [QTBUG-63735] The system no longer restarts the application when the user + replaces SIM card or changes the logical density of the screen. + - [QTBUG-70280] ARM64 builds now default to android-21 instead of failing. + - [QTBUG-35545] QMessageBox now supports buttons with custom labels. + +**************************************************************************** +* Linux * +**************************************************************************** + + - QFileDialog will use the native dialogs provided by the platform theme + instead of trying to use Flatpak portal to select directories. + +**************************************************************************** +* macOS * +**************************************************************************** + + - Layer-backed mode is now the default for QWindow. + + - QtGui: + * [QTBUG-63800] Fixed display of condensed fonts when NoFontMerging is + in use. + + - Text: + * [QTBUG-69955] Fixed font weights on macOS 10.14. + +**************************************************************************** +* Windows * +**************************************************************************** + + - [QTBUG-55762] The dimensions of invisible margins inside the frames of + Windows 10 windows will now be disregarded in the positioning of Qt + windows to avoid a misplaced look (offset by a few pixels from the + expected position). + - [QTBUG-44964][QTBUG-60437] The application attributes + AA_CompressTabletEvents and AA_CompressHighFrequencyEvents are now + supported on Windows 8 and above for touch/pen input, with the same + defaults as on X11 (compress touch events, don't compress tablet events) + + - QTimeZone: + * [QTBUG-42021] Changed MS-Win to use ICU for time-zone data, when + available, in preference to MS's TZ APIs. The choice is made when + building Qt. This will give reliable results when non-DST transitions + arise, or when a zone's DST is not simple (e.g. interrupted by + Ramadan). + +**************************************************************************** +* winrt * +**************************************************************************** + + - Added support to Windows UI Automation to the WinRT QPA, allowing + Qt-based UWP applications to operate with accessibility and + programmatic UI control tools. + +**************************************************************************** +* X11 * +**************************************************************************** + + - [QTBUG-39624] The xcb plugin was ported to use libxcb-xinput instead of + libXi for XInput2 support. The -xinput2 configure option was replaced by + -xcb-xinput. From d9200fcac58a9347decd417c217c18b7e34471ec Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Tue, 13 Nov 2018 20:22:20 +0100 Subject: [PATCH 0309/1650] Windows QPA: Fix broken focus for native child windows This issue was caused by missing logic in the implementation of the pointer message handler, necessary to support "click to focus" for native child windows. Fixes: QTBUG-71352 Change-Id: I2e261caa8dfab096647799ec1e7d781bec40654e Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowspointerhandler.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp index 4d3e2f71ec..3c7372958f 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp @@ -467,6 +467,11 @@ bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND h keyModifiers, Qt::MouseEventNotSynthesized); return false; // To allow window dragging, etc. } else { + if (eventType == QEvent::MouseButtonPress) { + // Implement "Click to focus" for native child windows (unless it is a native widget window). + if (!window->isTopLevel() && !window->inherits("QWidgetWindow") && QGuiApplication::focusWindow() != window) + window->requestActivate(); + } if (currentWindowUnderPointer != m_windowUnderPointer) { if (m_windowUnderPointer && m_windowUnderPointer == m_currentWindow) { QWindowSystemInterface::handleLeaveEvent(m_windowUnderPointer); From cd201b2c2c2849fea0c5a38ffd979cd9d5b24997 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 13 Nov 2018 11:15:44 +0100 Subject: [PATCH 0310/1650] Adjust QTRY_IMPL()'s default timestep MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was previously using 50ms steps, which was a bad choice for client code whose total time-out was comparable to 50ms or less. Reduce the time-step so that we loop several times within the timeout (but make sure it's never zero, by adding 1ms). Change-Id: I0428a7741c0741dfb312e40ae1eda900050195ab Reviewed-by: Jędrzej Nowacki --- src/testlib/qtestcase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testlib/qtestcase.h b/src/testlib/qtestcase.h index 54669c11de..fbc251a2a2 100644 --- a/src/testlib/qtestcase.h +++ b/src/testlib/qtestcase.h @@ -150,7 +150,7 @@ do {\ // Ideally we'd use qWaitFor instead of QTRY_LOOP_IMPL, but due // to a compiler bug on MSVC < 2017 we can't (see QTBUG-59096) #define QTRY_IMPL(expr, timeout)\ - const int qt_test_step = 50; \ + const int qt_test_step = timeout < 350 ? timeout / 7 + 1 : 50; \ const int qt_test_timeoutValue = timeout; \ QTRY_LOOP_IMPL((expr), qt_test_timeoutValue, qt_test_step); \ QTRY_TIMEOUT_DEBUG_IMPL((expr), qt_test_timeoutValue, qt_test_step)\ From 79af4ec056b6301752ee750f04192d170f9c1823 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 14 Nov 2018 14:58:47 +0100 Subject: [PATCH 0311/1650] Manual dialogs test: Fix shortcut Fix: QAction::event: Ambiguous shortcut overload: Ctrl+Q when pressing CTRL+Q Amends b5eb850e0deb61ff71e26a5a2d0e070b91306aa2 . Change-Id: Ie31d5830ea357cd34cdd422e667ceca507c7b53f Reviewed-by: Shawn Rutledge --- tests/manual/dialogs/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/manual/dialogs/main.cpp b/tests/manual/dialogs/main.cpp index fc4adebcc0..2676ceeb52 100644 --- a/tests/manual/dialogs/main.cpp +++ b/tests/manual/dialogs/main.cpp @@ -94,7 +94,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); QMenu *editMenu = menuBar()->addMenu(tr("&Edit")); QAction *action = editMenu->addAction(tr("Cut")); - action->setShortcut(QKeySequence(QKeySequence::Quit)); + action->setShortcut(QKeySequence(QKeySequence::Cut)); action = editMenu->addAction(tr("Copy")); action->setShortcut(QKeySequence(QKeySequence::Copy)); action = editMenu->addAction(tr("Paste")); From a52d7861edfb5956de38ba80015c4dd0b596259b Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 13 Nov 2018 16:00:23 +0100 Subject: [PATCH 0312/1650] Fix compile issue with gcc 9 It appears messenne_twisters in the latest libstdc++ has one more requirement before it is willing to construct with our SystemGenerator struct as an sseq provider. Change-Id: If38151d1fa6f40a80274acc26d9ed6b4ac6049fe Reviewed-by: Giuseppe D'Angelo Reviewed-by: Thiago Macieira --- src/corelib/global/qrandom.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp index 23e5e499b2..03534cf453 100644 --- a/src/corelib/global/qrandom.cpp +++ b/src/corelib/global/qrandom.cpp @@ -218,6 +218,7 @@ struct QRandomGenerator::SystemGenerator #endif // Q_OS_WINRT static SystemGenerator &self(); + typedef quint32 result_type; void generate(quint32 *begin, quint32 *end) Q_DECL_NOEXCEPT_EXPR(FillBufferNoexcept); // For std::mersenne_twister_engine implementations that use something From 6bdf1e337d9104081b6e3b335d8439b32fb8b020 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Tue, 13 Nov 2018 09:03:15 +0100 Subject: [PATCH 0313/1650] tst_qguieventdispatcher: Sync blacklist with tst_qeventdispatcher Windows and WinRT only have on event dispatcher class so that failing test cases in one test will most likely also happen in the other. Change-Id: Ib047c6870e6e02f3cf8deaaa6e438ed0ac7e2d5a Reviewed-by: Friedemann Kleint --- tests/auto/gui/kernel/qguieventdispatcher/BLACKLIST | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 tests/auto/gui/kernel/qguieventdispatcher/BLACKLIST diff --git a/tests/auto/gui/kernel/qguieventdispatcher/BLACKLIST b/tests/auto/gui/kernel/qguieventdispatcher/BLACKLIST new file mode 100644 index 0000000000..b1590a5ccf --- /dev/null +++ b/tests/auto/gui/kernel/qguieventdispatcher/BLACKLIST @@ -0,0 +1,5 @@ +[sendPostedEvents] +windows +[registerTimer] +windows +winrt From 67c29f15bd825f6246c8e993083ba7b87ad3b33e Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 12 Oct 2018 12:14:39 +0300 Subject: [PATCH 0314/1650] QPixmapFilter: use rvalue more Change-Id: I38b84d0cd1db10078ef663a64e62717fedf7697c Reviewed-by: Edward Welbourne Reviewed-by: Allan Sandfeld Jensen --- src/widgets/effects/qpixmapfilter.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/widgets/effects/qpixmapfilter.cpp b/src/widgets/effects/qpixmapfilter.cpp index 211c09ee71..60edd01d00 100644 --- a/src/widgets/effects/qpixmapfilter.cpp +++ b/src/widgets/effects/qpixmapfilter.cpp @@ -1104,13 +1104,15 @@ void QPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const Q if (srcRect.isNull()) { srcImage = src.toImage(); - srcImage = srcImage.convertToFormat(srcImage.hasAlphaChannel() ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32); + const auto format = srcImage.hasAlphaChannel() ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; + srcImage = std::move(srcImage).convertToFormat(format); destImage = QImage(srcImage.size(), srcImage.format()); } else { QRect rect = srcRect.toAlignedRect().intersected(src.rect()); srcImage = src.copy(rect).toImage(); - srcImage = srcImage.convertToFormat(srcImage.hasAlphaChannel() ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32); + const auto format = srcImage.hasAlphaChannel() ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; + srcImage = std::move(srcImage).convertToFormat(format); destImage = QImage(rect.size(), srcImage.format()); } destImage.setDevicePixelRatio(src.devicePixelRatioF()); @@ -1129,7 +1131,7 @@ void QPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const Q bufPainter.setOpacity(d->strength); bufPainter.drawImage(0, 0, destImage); bufPainter.end(); - destImage = buffer; + destImage = std::move(buffer); } if (srcImage.hasAlphaChannel()) @@ -1333,7 +1335,7 @@ void QPixmapDropShadowFilter::draw(QPainter *p, qt_blurImage(&blurPainter, tmp, d->radius, false, true); blurPainter.end(); - tmp = blurred; + tmp = std::move(blurred); // blacken the image... tmpPainter.begin(&tmp); From ae0cacb3838268a158e065879fb992b346429440 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 9 Nov 2018 10:02:13 +0100 Subject: [PATCH 0315/1650] QFileDialog: Document that options need to be applied first Flesh out the existing note on QFileDialog::setOptions(), add it to QFileDialog::setOption() and add a small note to the DontUseNativeDialogs option value. Fixes: QTBUG-68590 Change-Id: I3a2011c8210d499114b01dfe09ad2dc797dfc2ab Reviewed-by: Leena Miettinen Reviewed-by: Richard Moe Gustavsen --- src/widgets/dialogs/qfiledialog.cpp | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 5c6c03d3aa..9e270531f1 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -221,6 +221,9 @@ Q_GLOBAL_STATIC(QUrl, lastVisitedDir) of QFileDialog that contains the Q_OBJECT macro, or the platform does not have a native dialog of the type that you require. + \note This option must be set before changing dialog properties + or showing the dialog. + \value ReadOnly Indicates that the model is readonly. \value HideNameFilterDetails Indicates if the file name filter details are @@ -722,6 +725,16 @@ bool QFileDialogPrivate::usingWidgets() const Sets the given \a option to be enabled if \a on is true; otherwise, clears the given \a option. + Options (particularly the DontUseNativeDialogs option) should be set + before changing dialog properties or showing the dialog. + + Setting options while the dialog is visible is not guaranteed to have + an immediate effect on the dialog (depending on the option and on the + platform). + + Setting options after changing other properties may cause these + values to have no effect. + \sa options, testOption() */ void QFileDialog::setOption(Option option, bool on) @@ -752,9 +765,15 @@ bool QFileDialog::testOption(Option option) const By default, all options are disabled. - Options should be set before showing the dialog. Setting them while the - dialog is visible is not guaranteed to have an immediate effect on the - dialog (depending on the option and on the platform). + Options (particularly the DontUseNativeDialogs option) should be set + before changing dialog properties or showing the dialog. + + Setting options while the dialog is visible is not guaranteed to have + an immediate effect on the dialog (depending on the option and on the + platform). + + Setting options after changing other properties may cause these + values to have no effect. \sa setOption(), testOption() */ From 800cd53c7e7c34571582d463c3f40de4df908818 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 6 Nov 2018 13:24:30 +0100 Subject: [PATCH 0316/1650] Increase QOpenGLTextureCache max size From 64 to 256 MB. Note that this is especially important because bindTexture() will fail and return an invalid texture for image data larger than this. That is not ideal but is trickier to correct. Until that is available, increase the cache size to alleviate the pain somewhat. Task-number: QTBUG-59207 Change-Id: Ibc22524acad0b42a632eb7e4cd8ea86225174837 Reviewed-by: Allan Sandfeld Jensen --- src/gui/opengl/qopengltexturecache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/opengl/qopengltexturecache.cpp b/src/gui/opengl/qopengltexturecache.cpp index 8de0b25fee..ef07dbe109 100644 --- a/src/gui/opengl/qopengltexturecache.cpp +++ b/src/gui/opengl/qopengltexturecache.cpp @@ -97,7 +97,7 @@ void QOpenGLTextureCacheWrapper::cleanupTexturesForPixmapData(QPlatformPixmap *p QOpenGLTextureCache::QOpenGLTextureCache(QOpenGLContext *ctx) : QOpenGLSharedResource(ctx->shareGroup()) - , m_cache(64 * 1024) // 64 MB cache + , m_cache(256 * 1024) // 256 MB cache { } From c3d2d83fcb0f88de7d08cb7d088db8942e2e0f64 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 5 Nov 2018 13:19:49 +0100 Subject: [PATCH 0317/1650] Correctly initialize the logClusters array for tabs and objects The logclusters where never correctly initialized for tabs or inline objects. Change-Id: I376fd2dba19994eb5add24cdb8a93c38bde8cd1e Fixes: QTBUG-70946 Reviewed-by: Allan Sandfeld Jensen --- src/gui/text/qtextengine.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 4e9b00f9c9..8de16038ad 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1962,19 +1962,24 @@ const QCharAttributes *QTextEngine::attributes() const void QTextEngine::shape(int item) const { - if (layoutData->items.at(item).analysis.flags == QScriptAnalysis::Object) { + auto &li = layoutData->items[item]; + if (li.analysis.flags == QScriptAnalysis::Object) { ensureSpace(1); if (block.docHandle()) { docLayout()->resizeInlineObject(QTextInlineObject(item, const_cast(this)), - layoutData->items[item].position + block.position(), - format(&layoutData->items[item])); + li.position + block.position(), + format(&li)); } - } else if (layoutData->items.at(item).analysis.flags == QScriptAnalysis::Tab) { + // fix log clusters to point to the previous glyph, as the object doesn't have a glyph of it's own. + // This is required so that all entries in the array get initialized and are ordered correctly. + ushort *lc = logClusters(&li); + *lc = item ? lc[-1] : 0; + } else if (li.analysis.flags == QScriptAnalysis::Tab) { // set up at least the ascent/descent/leading of the script item for the tab - fontEngine(layoutData->items[item], - &layoutData->items[item].ascent, - &layoutData->items[item].descent, - &layoutData->items[item].leading); + fontEngine(li, &li.ascent, &li.descent, &li.leading); + // see the comment above + ushort *lc = logClusters(&li); + *lc = item ? lc[-1] : 0; } else { shapeText(item); } From ad2c7f588321f8c671cb9419f90a1e24887ed562 Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Wed, 14 Nov 2018 18:10:25 +0100 Subject: [PATCH 0318/1650] Windows QPA: Fix input context visibility status QWindowsInputContext::isInputPanelVisible() was ignoring the visibility status of the IME, only returning the status of the Win10 virtual keyboard. This issue caused qtwebengine to try to show the IME multiple times, breaking Asian languages input. Task-number: QTBUG-71753 Change-Id: Iaa4cef37b7dc98a9e0a787750a34d2e98a87a777 Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Alexandru Croitor Reviewed-by: Friedemann Kleint --- .../platforms/windows/qwindowsinputcontext.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp index 30da0da1de..d1e99c037b 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp @@ -242,7 +242,18 @@ QRectF QWindowsInputContext::keyboardRect() const bool QWindowsInputContext::isInputPanelVisible() const { HWND hwnd = getVirtualKeyboardWindowHandle(); - return hwnd && ::IsWindowEnabled(hwnd) && ::IsWindowVisible(hwnd); + if (hwnd && ::IsWindowEnabled(hwnd) && ::IsWindowVisible(hwnd)) + return true; + // check if the Input Method Editor is open + if (inputMethodAccepted()) { + if (QWindow *window = QGuiApplication::focusWindow()) { + if (QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(window)) { + if (HIMC himc = ImmGetContext(platformWindow->handle())) + return ImmGetOpenStatus(himc); + } + } + } + return false; } void QWindowsInputContext::showInputPanel() From d804146ced28c61631ea054fdb792c096cffa5e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 14 Nov 2018 14:38:34 +0100 Subject: [PATCH 0319/1650] macOS: Remove incorrect statement about layer-backing in changelog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Id31783227690445d06c21fcab40db1042d2fb33f Reviewed-by: Morten Johan Sørvig --- dist/changes-5.12.0 | 2 -- 1 file changed, 2 deletions(-) diff --git a/dist/changes-5.12.0 b/dist/changes-5.12.0 index fbed338b46..b5e664fc5a 100644 --- a/dist/changes-5.12.0 +++ b/dist/changes-5.12.0 @@ -424,8 +424,6 @@ information about a particular change. * macOS * **************************************************************************** - - Layer-backed mode is now the default for QWindow. - - QtGui: * [QTBUG-63800] Fixed display of condensed fonts when NoFontMerging is in use. From 16830c827b075c274f2f208fcc57c9f6174e9fcc Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 14 Nov 2018 12:09:51 +0100 Subject: [PATCH 0320/1650] Make sure QEventDispatcher::registerTimer() cleans up after itself MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The test needs to also unregister its timers when it fails. Therefore, wrap the registering and unregistering in an RAII class. Task-number: QTBUG-71773 Change-Id: I6ef44e580880deecb32763b5b0cd71e1c26929be Reviewed-by: Mårten Nordheim Reviewed-by: Edward Welbourne --- .../qeventdispatcher/tst_qeventdispatcher.cpp | 178 +++++++++++++----- 1 file changed, 126 insertions(+), 52 deletions(-) diff --git a/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp b/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp index 5784f0728c..ca183752a5 100644 --- a/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp +++ b/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp @@ -92,77 +92,151 @@ void tst_QEventDispatcher::initTestCase() } } +class TimerManager { + Q_DISABLE_COPY(TimerManager) + +public: + TimerManager(QAbstractEventDispatcher *eventDispatcher, QObject *parent) + : m_eventDispatcher(eventDispatcher), m_parent(parent) + { + } + + ~TimerManager() + { + if (!registeredTimers().isEmpty()) + m_eventDispatcher->unregisterTimers(m_parent); + } + + TimerManager(TimerManager &&) = delete; + TimerManager &operator=(TimerManager &&) = delete; + + int preciseTimerId() const { return m_preciseTimerId; } + int coarseTimerId() const { return m_coarseTimerId; } + int veryCoarseTimerId() const { return m_veryCoarseTimerId; } + + bool foundPrecise() const { return m_preciseTimerId > 0; } + bool foundCoarse() const { return m_coarseTimerId > 0; } + bool foundVeryCoarse() const { return m_veryCoarseTimerId > 0; } + + QList registeredTimers() const + { + return m_eventDispatcher->registeredTimers(m_parent); + } + + void registerAll() + { + // start 3 timers, each with the different timer types and different intervals + m_preciseTimerId = m_eventDispatcher->registerTimer( + PreciseTimerInterval, Qt::PreciseTimer, m_parent); + m_coarseTimerId = m_eventDispatcher->registerTimer( + CoarseTimerInterval, Qt::CoarseTimer, m_parent); + m_veryCoarseTimerId = m_eventDispatcher->registerTimer( + VeryCoarseTimerInterval, Qt::VeryCoarseTimer, m_parent); + QVERIFY(m_preciseTimerId > 0); + QVERIFY(m_coarseTimerId > 0); + QVERIFY(m_veryCoarseTimerId > 0); + findTimers(); + } + + void unregister(int timerId) + { + m_eventDispatcher->unregisterTimer(timerId); + findTimers(); + } + + void unregisterAll() + { + m_eventDispatcher->unregisterTimers(m_parent); + findTimers(); + } + +private: + void findTimers() + { + bool foundPrecise = false; + bool foundCoarse = false; + bool foundVeryCoarse = false; + const QList timers = registeredTimers(); + for (int i = 0; i < timers.count(); ++i) { + const QAbstractEventDispatcher::TimerInfo &timerInfo = timers.at(i); + if (timerInfo.timerId == m_preciseTimerId) { + QCOMPARE(timerInfo.interval, int(PreciseTimerInterval)); + QCOMPARE(timerInfo.timerType, Qt::PreciseTimer); + foundPrecise = true; + } else if (timerInfo.timerId == m_coarseTimerId) { + QCOMPARE(timerInfo.interval, int(CoarseTimerInterval)); + QCOMPARE(timerInfo.timerType, Qt::CoarseTimer); + foundCoarse = true; + } else if (timerInfo.timerId == m_veryCoarseTimerId) { + QCOMPARE(timerInfo.interval, int(VeryCoarseTimerInterval)); + QCOMPARE(timerInfo.timerType, Qt::VeryCoarseTimer); + foundVeryCoarse = true; + } + } + if (!foundPrecise) + m_preciseTimerId = -1; + if (!foundCoarse) + m_coarseTimerId = -1; + if (!foundVeryCoarse) + m_veryCoarseTimerId = -1; + } + + QAbstractEventDispatcher *m_eventDispatcher = nullptr; + + int m_preciseTimerId = -1; + int m_coarseTimerId = -1; + int m_veryCoarseTimerId = -1; + + QObject *m_parent = nullptr; +}; + // test that the eventDispatcher's timer implementation is complete and working void tst_QEventDispatcher::registerTimer() { -#define FIND_TIMERS() \ - do { \ - foundPrecise = false; \ - foundCoarse = false; \ - foundVeryCoarse = false; \ - for (int i = 0; i < registeredTimers.count(); ++i) { \ - const QAbstractEventDispatcher::TimerInfo &timerInfo = registeredTimers.at(i); \ - if (timerInfo.timerId == preciseTimerId) { \ - QCOMPARE(timerInfo.interval, int(PreciseTimerInterval)); \ - QCOMPARE(timerInfo.timerType, Qt::PreciseTimer); \ - foundPrecise = true; \ - } else if (timerInfo.timerId == coarseTimerId) { \ - QCOMPARE(timerInfo.interval, int(CoarseTimerInterval)); \ - QCOMPARE(timerInfo.timerType, Qt::CoarseTimer); \ - foundCoarse = true; \ - } else if (timerInfo.timerId == veryCoarseTimerId) { \ - QCOMPARE(timerInfo.interval, int(VeryCoarseTimerInterval)); \ - QCOMPARE(timerInfo.timerType, Qt::VeryCoarseTimer); \ - foundVeryCoarse = true; \ - } \ - } \ - } while (0) - - // start 3 timers, each with the different timer types and different intervals - int preciseTimerId = eventDispatcher->registerTimer(PreciseTimerInterval, Qt::PreciseTimer, this); - int coarseTimerId = eventDispatcher->registerTimer(CoarseTimerInterval, Qt::CoarseTimer, this); - int veryCoarseTimerId = eventDispatcher->registerTimer(VeryCoarseTimerInterval, Qt::VeryCoarseTimer, this); - QVERIFY(preciseTimerId > 0); - QVERIFY(coarseTimerId > 0); - QVERIFY(veryCoarseTimerId > 0); + TimerManager timers(eventDispatcher, this); + timers.registerAll(); + if (QTest::currentTestFailed()) + return; // check that all 3 are present in the eventDispatcher's registeredTimer() list - QList registeredTimers = eventDispatcher->registeredTimers(this); - QCOMPARE(registeredTimers.count(), 3); - bool foundPrecise, foundCoarse, foundVeryCoarse; - FIND_TIMERS(); - QVERIFY(foundPrecise && foundCoarse && foundVeryCoarse); + QCOMPARE(timers.registeredTimers().count(), 3); + QVERIFY(timers.foundPrecise()); + QVERIFY(timers.foundCoarse()); + QVERIFY(timers.foundVeryCoarse()); // process events, waiting for the next event... this should only fire the precise timer receivedEventType = -1; timerIdFromEvent = -1; QTRY_COMPARE_WITH_TIMEOUT(receivedEventType, int(QEvent::Timer), PreciseTimerInterval * 2); - QCOMPARE(timerIdFromEvent, preciseTimerId); + QCOMPARE(timerIdFromEvent, timers.preciseTimerId()); // now unregister it and make sure it's gone - eventDispatcher->unregisterTimer(preciseTimerId); - registeredTimers = eventDispatcher->registeredTimers(this); - QCOMPARE(registeredTimers.count(), 2); - FIND_TIMERS(); - QVERIFY(!foundPrecise && foundCoarse && foundVeryCoarse); + timers.unregister(timers.preciseTimerId()); + if (QTest::currentTestFailed()) + return; + QCOMPARE(timers.registeredTimers().count(), 2); + QVERIFY(!timers.foundPrecise()); + QVERIFY(timers.foundCoarse()); + QVERIFY(timers.foundVeryCoarse()); // do the same again for the coarse timer receivedEventType = -1; timerIdFromEvent = -1; QTRY_COMPARE_WITH_TIMEOUT(receivedEventType, int(QEvent::Timer), CoarseTimerInterval * 2); - QCOMPARE(timerIdFromEvent, coarseTimerId); + QCOMPARE(timerIdFromEvent, timers.coarseTimerId()); // now unregister it and make sure it's gone - eventDispatcher->unregisterTimer(coarseTimerId); - registeredTimers = eventDispatcher->registeredTimers(this); - QCOMPARE(registeredTimers.count(), 1); - FIND_TIMERS(); - QVERIFY(!foundPrecise && !foundCoarse && foundVeryCoarse); + timers.unregister(timers.coarseTimerId()); + if (QTest::currentTestFailed()) + return; + QCOMPARE(timers.registeredTimers().count(), 1); + QVERIFY(!timers.foundPrecise()); + QVERIFY(!timers.foundCoarse()); + QVERIFY(timers.foundVeryCoarse()); // not going to wait for the VeryCoarseTimer, would take too long, just unregister it - eventDispatcher->unregisterTimers(this); - registeredTimers = eventDispatcher->registeredTimers(this); - QVERIFY(registeredTimers.isEmpty()); - -#undef FIND_TIMERS + timers.unregisterAll(); + if (QTest::currentTestFailed()) + return; + QVERIFY(timers.registeredTimers().isEmpty()); } void tst_QEventDispatcher::sendPostedEvents_data() From 900b57ea90ebe60414a5188337bc85ee4faac220 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 13 Nov 2018 18:35:50 +0100 Subject: [PATCH 0321/1650] Re-blacklist tst_QEventDispatcher::registerTimer() on macOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The test has been failing over and over since it was removed from the blacklist. Obviously it is not stable. This is a partial revert of commit b10ee45546e152e08b2494bd45eb22426e9d2dc9. Task-number: QTBUG-71773 Change-Id: Ie2588538ee704652c2f09ce6ad947da3011e7dad Reviewed-by: Mårten Nordheim Reviewed-by: Edward Welbourne --- tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST b/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST index b1590a5ccf..06588188d4 100644 --- a/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST +++ b/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST @@ -3,3 +3,4 @@ windows [registerTimer] windows winrt +osx From a94a3098d0cc82a850d2d0c62baad6edef72e142 Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Wed, 14 Nov 2018 12:49:00 +0100 Subject: [PATCH 0322/1650] Windows QPA: Fix building with -no-feature-tabletevent This change fixes building Qt with the -no-feature-tabletevent configure option by disabling handling of pointer messages associated with tablet events within the pointer message handler. Fixes: QTBUG-71774 Change-Id: Icb47a39793edb9a0f87c07c656b6ea6573d5f947 Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowspointerhandler.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp index 2b6c696979..d88049019b 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp @@ -609,6 +609,7 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd, bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, PVOID vPenInfo) { +#if QT_CONFIG(tabletevent) if (et & QtWindows::NonClientEventFlag) return false; // Let DefWindowProc() handle Non Client messages. @@ -703,6 +704,14 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin } } return true; +#else + Q_UNUSED(window); + Q_UNUSED(hwnd); + Q_UNUSED(et); + Q_UNUSED(msg); + Q_UNUSED(vPenInfo); + return false; +#endif } // Process old-style mouse messages here. From aa7ad517c793e71e7e4e1aafce04cdb8c651f0f6 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 13 Nov 2018 13:04:29 +0100 Subject: [PATCH 0323/1650] Remove unnecessary drawhelper member It was just caching a pointer only used one other place where it could be looked up. Change-Id: I3a3455f467f8a107d24b208c8591e7c9725c3389 Reviewed-by: Eirik Aavitsland --- src/gui/painting/qpaintengine_raster.cpp | 17 +++++++++-------- src/gui/painting/qpaintengine_raster_p.h | 1 - 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 7caaf3a8fa..e530ee568d 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -3827,7 +3827,6 @@ QImage::Format QRasterBuffer::prepare(QImage *image) bytes_per_line = image->bytesPerLine(); format = image->format(); - drawHelper = qDrawHelper + format; if (image->depth() == 1 && image->colorTable().size() == 2) { monoDestinationWithClut = true; const QVector colorTable = image->colorTable(); @@ -4715,17 +4714,19 @@ void QSpanData::adjustSpanMethods() case None: unclipped_blend = 0; break; - case Solid: - unclipped_blend = rasterBuffer->drawHelper->blendColor; - bitmapBlit = rasterBuffer->drawHelper->bitmapBlit; - alphamapBlit = rasterBuffer->drawHelper->alphamapBlit; - alphaRGBBlit = rasterBuffer->drawHelper->alphaRGBBlit; - fillRect = rasterBuffer->drawHelper->fillRect; + case Solid: { + const DrawHelper &drawHelper = qDrawHelper[rasterBuffer->format]; + unclipped_blend = drawHelper.blendColor; + bitmapBlit = drawHelper.bitmapBlit; + alphamapBlit = drawHelper.alphamapBlit; + alphaRGBBlit = drawHelper.alphaRGBBlit; + fillRect = drawHelper.fillRect; break; + } case LinearGradient: case RadialGradient: case ConicalGradient: - unclipped_blend = rasterBuffer->drawHelper->blendGradient; + unclipped_blend = qDrawHelper[rasterBuffer->format].blendGradient; break; case Texture: unclipped_blend = qBlendTexture; diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h index 14eddf07b1..881144d1c2 100644 --- a/src/gui/painting/qpaintengine_raster_p.h +++ b/src/gui/painting/qpaintengine_raster_p.h @@ -471,7 +471,6 @@ public: QPainter::CompositionMode compositionMode; QImage::Format format; - DrawHelper *drawHelper; QImage colorizeBitmap(const QImage &image, const QColor &color); private: From dc0111b2a75eebf2535df894b66ef8d1a1ba57e0 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 15 Nov 2018 10:49:47 +0100 Subject: [PATCH 0324/1650] Change qopenglext to match official Khronos headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise we can hit issues when other versions are included, as ptrdiff_t while having the same length is not the same type as signed long long on MSVC. Change-Id: Id42049b1052e528a663125ee5426b068ee46db72 Reviewed-by: Jüri Valdmann Reviewed-by: Laszlo Agocs --- src/gui/opengl/qopenglext.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/gui/opengl/qopenglext.h b/src/gui/opengl/qopenglext.h index 856adb679e..63873476e4 100644 --- a/src/gui/opengl/qopenglext.h +++ b/src/gui/opengl/qopenglext.h @@ -468,9 +468,14 @@ GLAPI void APIENTRY glBlendEquation (GLenum mode); #ifndef GL_VERSION_1_5 #define GL_VERSION_1_5 1 -#include -typedef ptrdiff_t GLsizeiptr; -typedef ptrdiff_t GLintptr; +#ifdef _WIN64 +typedef signed long long int GLsizeiptr; +typedef signed long long int GLintptr; +#else +typedef signed long int GLsizeiptr; +typedef signed long int GLintptr; +#endif + #define GL_BUFFER_SIZE 0x8764 #define GL_BUFFER_USAGE 0x8765 #define GL_QUERY_COUNTER_BITS 0x8864 From 527406cbd99f44470ef87468b73c18df949e8ac7 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Mon, 12 Nov 2018 09:40:47 +0100 Subject: [PATCH 0325/1650] Modernize the "settings" feature Change-Id: I9b8a61ecb1413b513ae5c9e77d3ee1b3e8b6562c Reviewed-by: Edward Welbourne Reviewed-by: Oswald Buddenhagen --- src/corelib/global/qconfig-bootstrapped.h | 2 ++ src/corelib/global/qlibraryinfo.cpp | 14 +++++----- src/corelib/io/io.pri | 26 +++++++++++++------ src/corelib/io/qsettings.cpp | 4 --- src/corelib/io/qsettings.h | 7 +---- src/corelib/io/qsettings_mac.cpp | 2 -- src/corelib/io/qsettings_win.cpp | 3 --- src/corelib/io/qsettings_winrt.cpp | 3 --- src/corelib/kernel/qcoreapplication_p.h | 2 ++ src/gui/image/qiconloader.cpp | 6 +++-- src/gui/kernel/qplatformdialoghelper.cpp | 6 +++-- .../kernel/qplatforminputcontextfactory.cpp | 6 ++--- .../mac/qcoretextfontdatabase.mm | 18 ++++++++----- .../fontdatabases/mac/qfontengine_coretext.mm | 2 ++ .../genericunix/qgenericunixservices.cpp | 4 ++- .../themes/genericunix/qgenericunixthemes.cpp | 10 ++++--- .../themes/genericunix/qgenericunixthemes_p.h | 4 +-- src/widgets/dialogs/qcolordialog.cpp | 2 ++ src/widgets/dialogs/qfiledialog.cpp | 12 +++++---- src/widgets/dialogs/qfiledialog_p.h | 2 +- src/widgets/kernel/qapplication_p.h | 2 +- src/widgets/styles/qcommonstyle.cpp | 2 ++ tests/auto/corelib/io/io.pro | 3 +++ 23 files changed, 83 insertions(+), 59 deletions(-) diff --git a/src/corelib/global/qconfig-bootstrapped.h b/src/corelib/global/qconfig-bootstrapped.h index 229b4d17a1..f62137fe66 100644 --- a/src/corelib/global/qconfig-bootstrapped.h +++ b/src/corelib/global/qconfig-bootstrapped.h @@ -126,11 +126,13 @@ #define QT_FEATURE_commandlineparser -1 #define QT_NO_COMPRESS #define QT_JSON_READONLY +#define QT_FEATURE_settings 1 #define QT_NO_STANDARDPATHS #define QT_FEATURE_textcodec -1 #else #define QT_FEATURE_codecs -1 #define QT_FEATURE_commandlineparser 1 +#define QT_FEATURE_settings -1 #define QT_FEATURE_textcodec 1 #endif diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index e727f00c8e..4119012d85 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -41,7 +41,9 @@ #include "qdir.h" #include "qstringlist.h" #include "qfile.h" +#if QT_CONFIG(settings) #include "qsettings.h" +#endif #include "qlibraryinfo.h" #include "qscopedpointer.h" @@ -67,7 +69,7 @@ QT_BEGIN_NAMESPACE extern void qDumpCPUFeatures(); // in qsimd.cpp -#ifndef QT_NO_SETTINGS +#if QT_CONFIG(settings) struct QLibrarySettings { @@ -204,7 +206,7 @@ QSettings *QLibraryInfoPrivate::findConfiguration() return 0; //no luck } -#endif // QT_NO_SETTINGS +#endif // settings /*! \class QLibraryInfo @@ -464,7 +466,7 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group) #endif // QT_BUILD_QMAKE, started inside location ! QString ret; bool fromConf = false; -#ifndef QT_NO_SETTINGS +#if QT_CONFIG(settings) #ifdef QT_BUILD_QMAKE // Logic for choosing the right data source: if EffectivePaths are requested // and qt.conf with that section is present, use it, otherwise fall back to @@ -547,7 +549,7 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group) ret = QDir::fromNativeSeparators(ret); } } -#endif // QT_NO_SETTINGS +#endif // settings #ifndef QT_BUILD_QMAKE_BOOTSTRAP if (!fromConf) { @@ -646,7 +648,7 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group) QStringList QLibraryInfo::platformPluginArguments(const QString &platformName) { -#if !defined(QT_BUILD_QMAKE) && !defined(QT_NO_SETTINGS) +#if !defined(QT_BUILD_QMAKE) && QT_CONFIG(settings) QScopedPointer settings(QLibraryInfoPrivate::findConfiguration()); if (!settings.isNull()) { const QString key = QLatin1String(platformsSection) @@ -657,7 +659,7 @@ QStringList QLibraryInfo::platformPluginArguments(const QString &platformName) } #else Q_UNUSED(platformName); -#endif // !QT_BUILD_QMAKE && !QT_NO_SETTINGS +#endif // !QT_BUILD_QMAKE && settings return QStringList(); } diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index c6a5407e51..086d642c26 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -34,8 +34,6 @@ HEADERS += \ io/qurlquery.h \ io/qurltlds_p.h \ io/qtldurl_p.h \ - io/qsettings.h \ - io/qsettings_p.h \ io/qfsfileengine_p.h \ io/qfsfileengine_iterator_p.h \ io/qfilesystementry_p.h \ @@ -73,7 +71,6 @@ SOURCES += \ io/qurlidna.cpp \ io/qurlquery.cpp \ io/qurlrecode.cpp \ - io/qsettings.cpp \ io/qfsfileengine.cpp \ io/qfsfileengine_iterator.cpp \ io/qfilesystementry.cpp \ @@ -121,6 +118,24 @@ qtConfig(processenvironment) { SOURCES += io/qprocess_unix.cpp } +qtConfig(settings) { + SOURCES += \ + io/qsettings.cpp + HEADERS += \ + io/qsettings.h \ + io/qsettings_p.h + + win32 { + !winrt { + SOURCES += io/qsettings_win.cpp + } else { + SOURCES += io/qsettings_winrt.cpp + } + } else: darwin:!nacl { + SOURCES += io/qsettings_mac.cpp + } +} + win32 { SOURCES += io/qfsfileengine_win.cpp SOURCES += io/qlockfile_win.cpp @@ -136,7 +151,6 @@ win32 { io/qwindowspipewriter_p.h SOURCES += \ - io/qsettings_win.cpp \ io/qstandardpaths_win.cpp \ io/qstorageinfo_win.cpp \ io/qwindowspipereader.cpp \ @@ -146,7 +160,6 @@ win32 { } else { SOURCES += \ io/qstandardpaths_winrt.cpp \ - io/qsettings_winrt.cpp \ io/qstorageinfo_stub.cpp } } else:unix { @@ -162,9 +175,6 @@ win32 { ../3rdparty/forkfd/forkfd.h INCLUDEPATH += ../3rdparty/forkfd } - !nacl:mac: { - SOURCES += io/qsettings_mac.cpp - } mac { SOURCES += io/qstorageinfo_mac.cpp qtConfig(processenvironment): \ diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 580fe6caf3..68e77c4167 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -41,8 +41,6 @@ #include "qplatformdefs.h" #include "qsettings.h" -#ifndef QT_NO_SETTINGS - #include "qsettings_p.h" #include "qcache.h" #include "qfile.h" @@ -3573,5 +3571,3 @@ QT_END_NAMESPACE #ifndef QT_BOOTSTRAPPED #include "moc_qsettings.cpp" #endif - -#endif // QT_NO_SETTINGS diff --git a/src/corelib/io/qsettings.h b/src/corelib/io/qsettings.h index ccfec787a6..7a9eebe11b 100644 --- a/src/corelib/io/qsettings.h +++ b/src/corelib/io/qsettings.h @@ -45,10 +45,7 @@ #include #include -QT_BEGIN_NAMESPACE -QT_END_NAMESPACE - -#ifndef QT_NO_SETTINGS +QT_REQUIRE_CONFIG(settings); #include @@ -208,6 +205,4 @@ private: QT_END_NAMESPACE -#endif // QT_NO_SETTINGS - #endif // QSETTINGS_H diff --git a/src/corelib/io/qsettings_mac.cpp b/src/corelib/io/qsettings_mac.cpp index aa14d8435a..9a1b578f7e 100644 --- a/src/corelib/io/qsettings_mac.cpp +++ b/src/corelib/io/qsettings_mac.cpp @@ -38,7 +38,6 @@ ****************************************************************************/ #include "qsettings.h" -#ifndef QT_NO_SETTINGS #include "qsettings_p.h" #include "qdatetime.h" @@ -664,4 +663,3 @@ bool QConfFileSettingsPrivate::writePlistFile(QIODevice &file, const ParsedSetti } QT_END_NAMESPACE -#endif //QT_NO_SETTINGS diff --git a/src/corelib/io/qsettings_win.cpp b/src/corelib/io/qsettings_win.cpp index edcae16776..bbaf45a95b 100644 --- a/src/corelib/io/qsettings_win.cpp +++ b/src/corelib/io/qsettings_win.cpp @@ -39,8 +39,6 @@ #include "qsettings.h" -#ifndef QT_NO_SETTINGS - #include "qsettings_p.h" #include "qvector.h" #include "qmap.h" @@ -859,4 +857,3 @@ QSettingsPrivate *QSettingsPrivate::create(const QString &fileName, QSettings::F } QT_END_NAMESPACE -#endif // QT_NO_SETTINGS diff --git a/src/corelib/io/qsettings_winrt.cpp b/src/corelib/io/qsettings_winrt.cpp index 209b56d920..c54e5861f0 100644 --- a/src/corelib/io/qsettings_winrt.cpp +++ b/src/corelib/io/qsettings_winrt.cpp @@ -39,8 +39,6 @@ #include "qsettings.h" -#ifndef QT_NO_SETTINGS - #include "qsettings_p.h" #include "qvector.h" #include "qmap.h" @@ -690,4 +688,3 @@ QSettingsPrivate *QSettingsPrivate::create(const QString &fileName, QSettings::F } QT_END_NAMESPACE -#endif // QT_NO_SETTINGS diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index cd995c17f1..b3479414ab 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -53,7 +53,9 @@ #include "QtCore/qcoreapplication.h" #include "QtCore/qtranslator.h" +#if QT_CONFIG(settings) #include "QtCore/qsettings.h" +#endif #ifndef QT_NO_QOBJECT #include "private/qobject_p.h" #endif diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp index 1ea4f1340b..3695408597 100644 --- a/src/gui/image/qiconloader.cpp +++ b/src/gui/image/qiconloader.cpp @@ -50,7 +50,9 @@ #include #include #include +#if QT_CONFIG(settings) #include +#endif #include #include @@ -338,7 +340,7 @@ QIconTheme::QIconTheme(const QString &themeName) m_valid = true; } } -#ifndef QT_NO_SETTINGS +#if QT_CONFIG(settings) if (themeIndex.exists()) { const QSettings indexReader(themeIndex.fileName(), QSettings::IniFormat); const QStringList keys = indexReader.allKeys(); @@ -397,7 +399,7 @@ QIconTheme::QIconTheme(const QString &themeName) if (!m_parents.contains(QLatin1String("hicolor"))) m_parents.append(QLatin1String("hicolor")); } -#endif //QT_NO_SETTINGS +#endif // settings } QThemeIconInfo QIconLoader::findIconHelper(const QString &themeName, diff --git a/src/gui/kernel/qplatformdialoghelper.cpp b/src/gui/kernel/qplatformdialoghelper.cpp index b456c1ca31..61479016a2 100644 --- a/src/gui/kernel/qplatformdialoghelper.cpp +++ b/src/gui/kernel/qplatformdialoghelper.cpp @@ -42,7 +42,9 @@ #include #include #include +#if QT_CONFIG(settings) #include +#endif #include #include @@ -283,7 +285,7 @@ QColorDialogStaticData::QColorDialogStaticData() : customSet(false) void QColorDialogStaticData::readSettings() { -#ifndef QT_NO_SETTINGS +#if QT_CONFIG(settings) const QSettings settings(QSettings::UserScope, QStringLiteral("QtProject")); for (int i = 0; i < int(CustomColorCount); ++i) { const QVariant v = settings.value(QLatin1String("Qt/customColors/") + QString::number(i)); @@ -295,7 +297,7 @@ void QColorDialogStaticData::readSettings() void QColorDialogStaticData::writeSettings() const { -#ifndef QT_NO_SETTINGS +#if QT_CONFIG(settings) if (customSet) { const_cast(this)->customSet = false; QSettings settings(QSettings::UserScope, QStringLiteral("QtProject")); diff --git a/src/gui/kernel/qplatforminputcontextfactory.cpp b/src/gui/kernel/qplatforminputcontextfactory.cpp index c59d89fabe..df7b95d8df 100644 --- a/src/gui/kernel/qplatforminputcontextfactory.cpp +++ b/src/gui/kernel/qplatforminputcontextfactory.cpp @@ -48,14 +48,14 @@ QT_BEGIN_NAMESPACE -#ifndef QT_NO_SETTINGS +#if QT_CONFIG(settings) Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, (QPlatformInputContextFactoryInterface_iid, QLatin1String("/platforminputcontexts"), Qt::CaseInsensitive)) #endif QStringList QPlatformInputContextFactory::keys() { -#ifndef QT_NO_SETTINGS +#if QT_CONFIG(settings) return loader()->keyMap().values(); #else return QStringList(); @@ -70,7 +70,7 @@ QString QPlatformInputContextFactory::requested() QPlatformInputContext *QPlatformInputContextFactory::create(const QString& key) { -#ifndef QT_NO_SETTINGS +#if QT_CONFIG(settings) if (!key.isEmpty()) { QStringList paramList = key.split(QLatin1Char(':')); const QString platform = paramList.takeFirst().toLower(); diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index 91c2dc8cf0..898432e602 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -50,7 +50,9 @@ #include "qcoretextfontdatabase_p.h" #include "qfontengine_coretext_p.h" +#if QT_CONFIG(settings) #include +#endif #include #ifndef QT_NO_FREETYPE #include @@ -116,21 +118,25 @@ QCoreTextFontDatabase::QCoreTextFontDatabase() : m_hasPopulatedAliases(false) { #ifdef Q_OS_MACX - QSettings appleSettings(QLatin1String("apple.com")); - QVariant appleValue = appleSettings.value(QLatin1String("AppleAntiAliasingThreshold")); - if (appleValue.isValid()) - QCoreTextFontEngine::antialiasingThreshold = appleValue.toInt(); - /* font_smoothing = 0 means no smoothing, while 1-3 means subpixel antialiasing with different hinting styles (but we don't care about the exact value, only if subpixel rendering is available or not) */ int font_smoothing = 0; + +#if QT_CONFIG(settings) + QSettings appleSettings(QLatin1String("apple.com")); + QVariant appleValue = appleSettings.value(QLatin1String("AppleAntiAliasingThreshold")); + if (appleValue.isValid()) + QCoreTextFontEngine::antialiasingThreshold = appleValue.toInt(); + appleValue = appleSettings.value(QLatin1String("AppleFontSmoothing")); if (appleValue.isValid()) { font_smoothing = appleValue.toInt(); - } else { + } else +#endif // settings + { // non-Apple displays do not provide enough information about subpixel rendering so // draw text with cocoa and compare pixel colors to see if subpixel rendering is enabled int w = 10; diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index 98b753eff9..57ae622891 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -41,7 +41,9 @@ #include #include +#if QT_CONFIG(settings) #include +#endif #include diff --git a/src/platformsupport/services/genericunix/qgenericunixservices.cpp b/src/platformsupport/services/genericunix/qgenericunixservices.cpp index cb1e367b9f..e63eb3b5b2 100644 --- a/src/platformsupport/services/genericunix/qgenericunixservices.cpp +++ b/src/platformsupport/services/genericunix/qgenericunixservices.cpp @@ -45,7 +45,9 @@ #if QT_CONFIG(process) # include #endif +#if QT_CONFIG(settings) #include +#endif #include #include @@ -93,7 +95,7 @@ static inline QByteArray detectDesktopEnvironment() // This can be a path in /usr/share/xsessions int slash = desktopSession.lastIndexOf('/'); if (slash != -1) { -#ifndef QT_NO_SETTINGS +#if QT_CONFIG(settings) QSettings desktopFile(QFile::decodeName(desktopSession + ".desktop"), QSettings::IniFormat); desktopFile.beginGroup(QStringLiteral("Desktop Entry")); QByteArray desktopName = desktopFile.value(QStringLiteral("DesktopNames")).toByteArray(); diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp index 43d49cbbc8..1003812767 100644 --- a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp +++ b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp @@ -53,7 +53,9 @@ #include #endif #include +#if QT_CONFIG(settings) #include +#endif #include #include #include @@ -261,7 +263,7 @@ static QIcon xdgFileIcon(const QFileInfo &fileInfo) } #endif -#ifndef QT_NO_SETTINGS +#if QT_CONFIG(settings) class QKdeThemePrivate : public QPlatformThemePrivate { public: @@ -688,7 +690,7 @@ QPlatformSystemTrayIcon *QKdeTheme::createPlatformSystemTrayIcon() const } #endif -#endif // QT_NO_SETTINGS +#endif // settings /*! \class QGnomeTheme @@ -834,7 +836,7 @@ QPlatformTheme *QGenericUnixTheme::createUnixTheme(const QString &name) { if (name == QLatin1String(QGenericUnixTheme::name)) return new QGenericUnixTheme; -#ifndef QT_NO_SETTINGS +#if QT_CONFIG(settings) if (name == QLatin1String(QKdeTheme::name)) if (QPlatformTheme *kdeTheme = QKdeTheme::createKdeTheme()) return kdeTheme; @@ -859,7 +861,7 @@ QStringList QGenericUnixTheme::themeNames() const QList desktopNames = desktopEnvironment.split(':'); for (const QByteArray &desktopName : desktopNames) { if (desktopEnvironment == "KDE") { -#ifndef QT_NO_SETTINGS +#if QT_CONFIG(settings) result.push_back(QLatin1String(QKdeTheme::name)); #endif } else if (gtkBasedEnvironments.contains(desktopName)) { diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes_p.h b/src/platformsupport/themes/genericunix/qgenericunixthemes_p.h index 865a624694..a5963b79ea 100644 --- a/src/platformsupport/themes/genericunix/qgenericunixthemes_p.h +++ b/src/platformsupport/themes/genericunix/qgenericunixthemes_p.h @@ -96,7 +96,7 @@ public: static const char *name; }; -#ifndef QT_NO_SETTINGS +#if QT_CONFIG(settings) class QKdeThemePrivate; class QKdeTheme : public QPlatformTheme @@ -123,7 +123,7 @@ public: static const char *name; }; -#endif // QT_NO_SETTINGS +#endif // settings class QGnomeThemePrivate; diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp index 99946d341d..7f137fe848 100644 --- a/src/widgets/dialogs/qcolordialog.cpp +++ b/src/widgets/dialogs/qcolordialog.cpp @@ -57,7 +57,9 @@ #include "qpainter.h" #include "qpixmap.h" #include "qpushbutton.h" +#if QT_CONFIG(settings) #include "qsettings.h" +#endif #include "qsharedpointer.h" #include "qstyle.h" #include "qstyleoption.h" diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 778e8556c7..8a51c7d186 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -57,7 +57,9 @@ #include #endif #include +#if QT_CONFIG(settings) #include +#endif #include #if QT_CONFIG(mimetype) #include @@ -383,7 +385,7 @@ QFileDialog::QFileDialog(const QFileDialogArgs &args) */ QFileDialog::~QFileDialog() { -#ifndef QT_NO_SETTINGS +#if QT_CONFIG(settings) Q_D(QFileDialog); d->saveSettings(); #endif @@ -2723,7 +2725,7 @@ void QFileDialog::accept() } } -#ifndef QT_NO_SETTINGS +#if QT_CONFIG(settings) void QFileDialogPrivate::saveSettings() { Q_Q(QFileDialog); @@ -2781,7 +2783,7 @@ bool QFileDialogPrivate::restoreFromSettings() return restoreWidgetState(history, settings.value(QLatin1String("sidebarWidth"), -1).toInt()); } -#endif // QT_NO_SETTINGS +#endif // settings bool QFileDialogPrivate::restoreWidgetState(QStringList &history, int splitterPosition) { @@ -2854,7 +2856,7 @@ void QFileDialogPrivate::init(const QUrl &directory, const QString &nameFilter, else q->selectUrl(directory); -#ifndef QT_NO_SETTINGS +#if QT_CONFIG(settings) // Try to restore from the FileDialog settings group; if it fails, fall back // to the pre-5.5 QByteArray serialized settings. if (!restoreFromSettings()) { @@ -3019,7 +3021,7 @@ void QFileDialogPrivate::createWidgets() createToolButtons(); createMenuActions(); -#ifndef QT_NO_SETTINGS +#if QT_CONFIG(settings) // Try to restore from the FileDialog settings group; if it fails, fall back // to the pre-5.5 QByteArray serialized settings. if (!restoreFromSettings()) { diff --git a/src/widgets/dialogs/qfiledialog_p.h b/src/widgets/dialogs/qfiledialog_p.h index 17290381d3..447be19df1 100644 --- a/src/widgets/dialogs/qfiledialog_p.h +++ b/src/widgets/dialogs/qfiledialog_p.h @@ -187,7 +187,7 @@ public: #endif } -#ifndef QT_NO_SETTINGS +#if QT_CONFIG(settings) void saveSettings(); bool restoreFromSettings(); #endif diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h index 488ca6cbfd..557304e94f 100644 --- a/src/widgets/kernel/qapplication_p.h +++ b/src/widgets/kernel/qapplication_p.h @@ -113,7 +113,7 @@ public: bool tryCloseAllWindows() override; #if 0 // Used to be included in Qt4 for Q_WS_X11 -#ifndef QT_NO_SETTINGS +#if QT_CONFIG(settings) static bool x11_apply_settings(); #endif static void reset_instance_pointer(); diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 735ae6b080..8b7eb15577 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -102,7 +102,9 @@ #endif #include #include +#if QT_CONFIG(settings) #include +#endif #include #include #if QT_CONFIG(animation) diff --git a/tests/auto/corelib/io/io.pro b/tests/auto/corelib/io/io.pro index 3c93fd5e1f..eee2c0e30d 100644 --- a/tests/auto/corelib/io/io.pro +++ b/tests/auto/corelib/io/io.pro @@ -65,6 +65,9 @@ win32:!qtConfig(private_tests): SUBDIRS -= \ qprocess \ qprocess-noapplication +!qtConfig(settings): SUBDIRS -= \ + qsettings + winrt: SUBDIRS -= \ qstorageinfo From 1983abddc06350541ac7a4bb4b2da14091e96311 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 4 Oct 2018 10:08:26 +0200 Subject: [PATCH 0326/1650] Remove support for qml1 plugins and modules The Qt Quick 1 module got dropped in Qt 5.6, and almost certainly doesn't compile anymore. Change-Id: Ia1ae6937e9cc4d99508be8eeeff9b12d0f001002 Reviewed-by: Edward Welbourne Reviewed-by: Shawn Rutledge Reviewed-by: Oswald Buddenhagen --- .gitignore | 1 - mkspecs/features/qml1_module.prf | 13 ------------- mkspecs/features/qml1_plugin.prf | 13 ------------- mkspecs/features/qml_module.prf | 12 +++--------- mkspecs/features/qml_plugin.prf | 25 +++++-------------------- 5 files changed, 8 insertions(+), 56 deletions(-) delete mode 100644 mkspecs/features/qml1_module.prf delete mode 100644 mkspecs/features/qml1_plugin.prf diff --git a/.gitignore b/.gitignore index f133a2124e..b9188d84f7 100644 --- a/.gitignore +++ b/.gitignore @@ -98,7 +98,6 @@ qt*-config.pri /bin/qhelpgenerator /bin/qlalr /bin/qml -/bin/qml1plugindump /bin/qmleasing /bin/qmlimportscanner /bin/qmljs diff --git a/mkspecs/features/qml1_module.prf b/mkspecs/features/qml1_module.prf deleted file mode 100644 index 33c3e44808..0000000000 --- a/mkspecs/features/qml1_module.prf +++ /dev/null @@ -1,13 +0,0 @@ -# -# W A R N I N G -# ------------- -# -# This file is not part of the Qt API. It exists purely as an -# implementation detail. It may change from version to version -# without notice, or even be removed. -# -# We mean it. -# - -CONFIG += qml1_target -load(qml_module) diff --git a/mkspecs/features/qml1_plugin.prf b/mkspecs/features/qml1_plugin.prf deleted file mode 100644 index cb1f0ce267..0000000000 --- a/mkspecs/features/qml1_plugin.prf +++ /dev/null @@ -1,13 +0,0 @@ -# -# W A R N I N G -# ------------- -# -# This file is not part of the Qt API. It exists purely as an -# implementation detail. It may change from version to version -# without notice, or even be removed. -# -# We mean it. -# - -CONFIG += qml1_target -load(qml_plugin) diff --git a/mkspecs/features/qml_module.prf b/mkspecs/features/qml_module.prf index 65212b2abf..bd84ce597a 100644 --- a/mkspecs/features/qml_module.prf +++ b/mkspecs/features/qml_module.prf @@ -23,15 +23,9 @@ for(qmlf, AUX_QML_FILES): fq_aux_qml_files += $$absolute_path($$qmlf, $$_PRO_FIL load(qt_build_paths) -qml1_target { - DESTDIR = $$MODULE_BASE_OUTDIR/imports/$$TARGETPATH - instbase = $$[QT_INSTALL_IMPORTS] -} else { - DESTDIR = $$MODULE_BASE_OUTDIR/qml/$$TARGETPATH - instbase = $$[QT_INSTALL_QML] -} +DESTDIR = $$MODULE_BASE_OUTDIR/qml/$$TARGETPATH -!qml1_target:static: \ +static: \ CONFIG += builtin_resources else: \ CONFIG += install_qml_files @@ -52,7 +46,7 @@ qmldir.base = $$_PRO_FILE_PWD_ # Tools need qmldir and plugins.qmltypes always installed on the file system qmldir.files = $$qmldir_file $$fq_aux_qml_files install_qml_files: qmldir.files += $$fq_qml_files -qmldir.path = $$instbase/$$TARGETPATH +qmldir.path = $$[QT_INSTALL_QML]/$$TARGETPATH INSTALLS += qmldir !debug_and_release|!build_all|CONFIG(release, debug|release) { diff --git a/mkspecs/features/qml_plugin.prf b/mkspecs/features/qml_plugin.prf index cd6377dcc6..ad8ecdf5f1 100644 --- a/mkspecs/features/qml_plugin.prf +++ b/mkspecs/features/qml_plugin.prf @@ -48,15 +48,9 @@ exists($$QMLTYPEFILE): AUX_QML_FILES += $$QMLTYPEFILE load(qt_build_paths) -qml1_target { - DESTDIR = $$MODULE_BASE_OUTDIR/imports/$$TARGETPATH - instbase = $$[QT_INSTALL_IMPORTS] -} else { - DESTDIR = $$MODULE_BASE_OUTDIR/qml/$$TARGETPATH - instbase = $$[QT_INSTALL_QML] -} +DESTDIR = $$MODULE_BASE_OUTDIR/qml/$$TARGETPATH -target.path = $$instbase/$$TARGETPATH +target.path = $$[QT_INSTALL_QML]/$$TARGETPATH INSTALLS += target # Some final setup @@ -75,20 +69,11 @@ load(qt_common) # directory. Then review and commit the changes made to plugins.qmltypes. # !cross_compile { - qml1_target { - qmlplugindump = qml1plugindump - importpath.name = QML_IMPORT_PATH - } else { - qmlplugindump = qmlplugindump - importpath.name = QML2_IMPORT_PATH - } + qmlplugindump = qmlplugindump + importpath.name = QML2_IMPORT_PATH importpath.value = for(qmod, QTREPOS) { - qml1_target: \ - qmod = $$qmod/imports - else: \ - qmod = $$qmod/qml - exists($$qmod): importpath.value += $$shell_path($$qmod) + exists($$qmod/qml): importpath.value += $$shell_path($$qmod/qml) } importpath.value = $$unique(importpath.value) QT_TOOL_ENV = importpath From 8e8c11f4f3d5ccb8b1a9042d363e4d1639797df3 Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Thu, 15 Nov 2018 17:19:23 +0100 Subject: [PATCH 0327/1650] Windows QPA: Fix onPressedChanged only reported on touch up This issue was caused by the workaround added to fix QTBUG-70887. Certain events like the initial touch down do not generate mouse messages after the pointer messages (but only touch messages) and should not be postponed by the pointer handler. Fixes: QTBUG-71775 Change-Id: I7b64ae4d422f6a4c1bb465ce5f8255e85640dab1 Reviewed-by: Friedemann Kleint Reviewed-by: Oliver Wolff --- src/plugins/platforms/windows/qwindowspointerhandler.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp index 3c7372958f..b3bc6e6d7b 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp @@ -564,6 +564,7 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd, QList touchPoints; bool primaryPointer = false; + bool pressRelease = false; if (QWindowsContext::verbose > 1) qCDebug(lcQpaEvents).noquote().nospace() << showbase @@ -600,9 +601,11 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd, if (touchInfo[i].pointerInfo.pointerFlags & POINTER_FLAG_DOWN) { touchPoint.state = Qt::TouchPointPressed; m_lastTouchPositions.insert(touchPoint.id, touchPoint.normalPosition); + pressRelease = true; } else if (touchInfo[i].pointerInfo.pointerFlags & POINTER_FLAG_UP) { touchPoint.state = Qt::TouchPointReleased; m_lastTouchPositions.remove(touchPoint.id); + pressRelease = true; } else { touchPoint.state = stationaryTouchPoint ? Qt::TouchPointStationary : Qt::TouchPointMoved; m_lastTouchPositions.insert(touchPoint.id, touchPoint.normalPosition); @@ -615,7 +618,7 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd, // Avoid getting repeated messages for this frame if there are multiple pointerIds QWindowsContext::user32dll.skipPointerFrameMessages(touchInfo[i].pointerInfo.pointerId); } - if (primaryPointer) { + if (primaryPointer && !pressRelease) { // Postpone event delivery to avoid hanging inside DoDragDrop(). // Only the primary pointer will generate mouse messages. enqueueTouchEvent(window, touchPoints, QWindowsKeyMapper::queryKeyboardModifiers()); From 84ff636ecf90342ccb81a67d526f42731cd07793 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 1 Nov 2018 09:47:14 +0100 Subject: [PATCH 0328/1650] Logging: Explicitly cast Q_FUNC_INFO and __FILE__ to const char * Otherwise they might end up as const char[], which clang-tidy complains about because it implicitly decays into a pointer when passed to the QMessageLogger ctor. Change-Id: I0d223f0c94cb63be6fc2a165348f143fadaf11ea Reviewed-by: Thiago Macieira --- src/corelib/global/qlogging.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qlogging.h b/src/corelib/global/qlogging.h index 16e01183bd..dded09999b 100644 --- a/src/corelib/global/qlogging.h +++ b/src/corelib/global/qlogging.h @@ -153,9 +153,9 @@ private: #endif #ifdef QT_MESSAGELOGCONTEXT - #define QT_MESSAGELOG_FILE __FILE__ + #define QT_MESSAGELOG_FILE static_cast(__FILE__) #define QT_MESSAGELOG_LINE __LINE__ - #define QT_MESSAGELOG_FUNC Q_FUNC_INFO + #define QT_MESSAGELOG_FUNC static_cast(Q_FUNC_INFO) #else #define QT_MESSAGELOG_FILE nullptr #define QT_MESSAGELOG_LINE 0 From c7453cf6767d5be43de878291e7eff371f200b4d Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 1 Nov 2018 09:58:40 +0100 Subject: [PATCH 0329/1650] Testlib: Explicitly cast messages to const char * MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Macro parameters should always be enclosed in braces when used. Plain C strings passed in parantheses are interpreted as const char[], at least by clang-tidy. Implicitly decaying arrays into pointers should be avoided and clang-tidy warns about this. Avoid both problems by always static casting all messages to const char *. Change-Id: I2be668169bec2823f69af3aa75086a31b0b31938 Reviewed-by: Friedemann Kleint Reviewed-by: Mitch Curtis Reviewed-by: Tor Arne Vestbø Reviewed-by: Edward Welbourne --- src/testlib/qtestcase.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/testlib/qtestcase.h b/src/testlib/qtestcase.h index f6891dc941..a6f1711230 100644 --- a/src/testlib/qtestcase.h +++ b/src/testlib/qtestcase.h @@ -67,17 +67,17 @@ do {\ #define QFAIL(message) \ do {\ - QTest::qFail(message, __FILE__, __LINE__);\ + QTest::qFail(static_cast(message), __FILE__, __LINE__);\ return;\ } while (false) #define QVERIFY2(statement, description) \ do {\ if (statement) {\ - if (!QTest::qVerify(true, #statement, (description), __FILE__, __LINE__))\ + if (!QTest::qVerify(true, #statement, static_cast(description), __FILE__, __LINE__))\ return;\ } else {\ - if (!QTest::qVerify(false, #statement, (description), __FILE__, __LINE__))\ + if (!QTest::qVerify(false, #statement, static_cast(description), __FILE__, __LINE__))\ return;\ }\ } while (false) @@ -184,7 +184,7 @@ do { \ #define QSKIP_INTERNAL(statement) \ do {\ - QTest::qSkip(statement, __FILE__, __LINE__);\ + QTest::qSkip(static_cast(statement), __FILE__, __LINE__);\ return;\ } while (false) @@ -200,7 +200,7 @@ do {\ #define QEXPECT_FAIL(dataIndex, comment, mode)\ do {\ - if (!QTest::qExpectFail(dataIndex, comment, QTest::mode, __FILE__, __LINE__))\ + if (!QTest::qExpectFail(dataIndex, static_cast(comment), QTest::mode, __FILE__, __LINE__))\ return;\ } while (false) @@ -217,7 +217,7 @@ do {\ } while (false) #define QWARN(msg)\ - QTest::qWarn(msg, __FILE__, __LINE__) + QTest::qWarn(static_cast(msg), __FILE__, __LINE__) #ifdef QT_TESTCASE_BUILDDIR # define QFINDTESTDATA(basepath)\ From 5725809fe717f525f47dbe4165b9801c9437b152 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 13 Nov 2018 13:21:25 +0100 Subject: [PATCH 0330/1650] Cleanup gradient blending Moving it to a separate routine like blendTexture, so DrawHelper only has solid color routines, and generalizing the vertical gradient optimization. Change-Id: I54bd59eba7e95247b9a365a3738d02c4f8cc2631 Reviewed-by: Eirik Aavitsland --- src/gui/painting/qcosmeticstroker.cpp | 2 +- src/gui/painting/qdrawhelper.cpp | 244 +++++++++++------------ src/gui/painting/qdrawhelper_p.h | 9 +- src/gui/painting/qpaintengine_raster.cpp | 32 +-- 4 files changed, 131 insertions(+), 156 deletions(-) diff --git a/src/gui/painting/qcosmeticstroker.cpp b/src/gui/painting/qcosmeticstroker.cpp index 436a62d486..0fb89a75b5 100644 --- a/src/gui/painting/qcosmeticstroker.cpp +++ b/src/gui/painting/qcosmeticstroker.cpp @@ -289,7 +289,7 @@ void QCosmeticStroker::setup() drawCaps = state->lastPen.capStyle() != Qt::FlatCap; if (strokeSelection & FastDraw) { - color = multiplyAlpha256(state->penData.solid.color, opacity).toArgb32(); + color = multiplyAlpha256(state->penData.solidColor, opacity).toArgb32(); QRasterBuffer *buffer = state->penData.rasterBuffer; pixels = (uint *)buffer->buffer(); ppl = buffer->stride(); diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index fa1990ca60..0df1eaf928 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -4232,7 +4232,7 @@ static inline Operator getOperator(const QSpanData *data, const QSpan *spans, in switch(data->type) { case QSpanData::Solid: - solidSource = data->solid.color.isOpaque(); + solidSource = data->solidColor.isOpaque(); op.srcFetch = 0; op.srcFetch64 = 0; break; @@ -4313,7 +4313,7 @@ void blend_color_generic(int count, const QSpan *spans, void *userData) QSpanData *data = reinterpret_cast(userData); uint buffer[BufferSize]; Operator op = getOperator(data, spans, count); - const uint color = data->solid.color.toArgb32(); + const uint color = data->solidColor.toArgb32(); while (count--) { int x = spans->x; @@ -4336,7 +4336,7 @@ static void blend_color_argb(int count, const QSpan *spans, void *userData) QSpanData *data = reinterpret_cast(userData); const Operator op = getOperator(data, spans, count); - const uint color = data->solid.color.toArgb32(); + const uint color = data->solidColor.toArgb32(); if (op.mode == QPainter::CompositionMode_Source) { // inline for performance @@ -4372,7 +4372,7 @@ void blend_color_generic_rgb64(int count, const QSpan *spans, void *userData) } quint64 buffer[BufferSize]; - const QRgba64 color = data->solid.color; + const QRgba64 color = data->solidColor; bool solidFill = data->rasterBuffer->compositionMode == QPainter::CompositionMode_Source || (data->rasterBuffer->compositionMode == QPainter::CompositionMode_SourceOver && color.isOpaque()); bool isBpp32 = qPixelLayouts[data->rasterBuffer->format].bpp == QPixelLayout::BPP32; @@ -4413,12 +4413,12 @@ static void blend_color_rgb16(int count, const QSpan *spans, void *userData) from qt_gradient_quint16 with minimal overhead. */ QPainter::CompositionMode mode = data->rasterBuffer->compositionMode; - if (mode == QPainter::CompositionMode_SourceOver && data->solid.color.isOpaque()) + if (mode == QPainter::CompositionMode_SourceOver && data->solidColor.isOpaque()) mode = QPainter::CompositionMode_Source; if (mode == QPainter::CompositionMode_Source) { // inline for performance - ushort c = data->solid.color.toRgb16(); + ushort c = data->solidColor.toRgb16(); while (count--) { ushort *target = ((ushort *)data->rasterBuffer->scanLine(spans->y)) + spans->x; if (spans->coverage == 255) { @@ -4439,7 +4439,7 @@ static void blend_color_rgb16(int count, const QSpan *spans, void *userData) if (mode == QPainter::CompositionMode_SourceOver) { while (count--) { - uint color = BYTE_MUL(data->solid.color.toArgb32(), spans->coverage); + uint color = BYTE_MUL(data->solidColor.toArgb32(), spans->coverage); int ialpha = qAlpha(~color); ushort c = qConvertRgb32To16(color); ushort *target = ((ushort *)data->rasterBuffer->scanLine(spans->y)) + spans->x; @@ -5228,6 +5228,110 @@ void qBlendTexture(int count, const QSpan *spans, void *userData) proc(count, spans, userData); } +static void blend_vertical_gradient_argb(int count, const QSpan *spans, void *userData) +{ + QSpanData *data = reinterpret_cast(userData); + + LinearGradientValues linear; + getLinearGradientValues(&linear, data); + + CompositionFunctionSolid funcSolid = + functionForModeSolid[data->rasterBuffer->compositionMode]; + + /* + The logic for vertical gradient calculations is a mathematically + reduced copy of that in fetchLinearGradient() - which is basically: + + qreal ry = data->m22 * (y + 0.5) + data->dy; + qreal t = linear.dy*ry + linear.off; + t *= (GRADIENT_STOPTABLE_SIZE - 1); + quint32 color = + qt_gradient_pixel_fixed(&data->gradient, + int(t * FIXPT_SIZE)); + + This has then been converted to fixed point to improve performance. + */ + const int gss = GRADIENT_STOPTABLE_SIZE - 1; + int yinc = int((linear.dy * data->m22 * gss) * FIXPT_SIZE); + int off = int((((linear.dy * (data->m22 * qreal(0.5) + data->dy) + linear.off) * gss) * FIXPT_SIZE)); + + while (count--) { + int y = spans->y; + int x = spans->x; + + quint32 *dst = (quint32 *)(data->rasterBuffer->scanLine(y)) + x; + quint32 color = + qt_gradient_pixel_fixed(&data->gradient, yinc * y + off); + + funcSolid(dst, spans->len, color, spans->coverage); + ++spans; + } +} + +template +static void blend_vertical_gradient(int count, const QSpan *spans, void *userData) +{ + QSpanData *data = reinterpret_cast(userData); + + LinearGradientValues linear; + getLinearGradientValues(&linear, data); + + // Based on the same logic as blend_vertical_gradient_argb. + + const int gss = GRADIENT_STOPTABLE_SIZE - 1; + int yinc = int((linear.dy * data->m22 * gss) * FIXPT_SIZE); + int off = int((((linear.dy * (data->m22 * qreal(0.5) + data->dy) + linear.off) * gss) * FIXPT_SIZE)); + + while (count--) { + int y = spans->y; + + data->solidColor = qt_gradient_pixel64_fixed(&data->gradient, yinc * y + off); + blend_color(1, spans, userData); + ++spans; + } +} + +void qBlendGradient(int count, const QSpan *spans, void *userData) +{ + QSpanData *data = reinterpret_cast(userData); + bool isVerticalGradient = + data->txop <= QTransform::TxScale && + data->type == QSpanData::LinearGradient && + data->gradient.linear.end.x == data->gradient.linear.origin.x; + switch (data->rasterBuffer->format) { + case QImage::Format_RGB16: + if (isVerticalGradient) + return blend_vertical_gradient(count, spans, userData); + return blend_src_generic(count, spans, userData); + case QImage::Format_RGB32: + case QImage::Format_ARGB32_Premultiplied: + if (isVerticalGradient) + return blend_vertical_gradient_argb(count, spans, userData); + return blend_src_generic(count, spans, userData); +#if defined(__SSE2__) || defined(__ARM_NEON__) || (Q_PROCESSOR_WORDSIZE == 8) + case QImage::Format_ARGB32: + case QImage::Format_RGBA8888: +#endif + case QImage::Format_BGR30: + case QImage::Format_A2BGR30_Premultiplied: + case QImage::Format_RGB30: + case QImage::Format_A2RGB30_Premultiplied: + case QImage::Format_RGBX64: + case QImage::Format_RGBA64: + case QImage::Format_RGBA64_Premultiplied: + if (isVerticalGradient) + return blend_vertical_gradient(count, spans, userData); + return blend_src_generic_rgb64(count, spans, userData); + case QImage::Format_Invalid: + break; + default: + if (isVerticalGradient) + return blend_vertical_gradient(count, spans, userData); + return blend_src_generic(count, spans, userData); + } + Q_UNREACHABLE(); +} + template static inline void qt_bitmapblit_template(QRasterBuffer *rasterBuffer, int x, int y, DST color, @@ -5290,103 +5394,6 @@ inline void qt_bitmapblit_template(QRasterBuffer *rasterBuffer, } } -static void qt_gradient_argb32(int count, const QSpan *spans, void *userData) -{ - QSpanData *data = reinterpret_cast(userData); - - bool isVerticalGradient = - data->txop <= QTransform::TxScale && - data->type == QSpanData::LinearGradient && - data->gradient.linear.end.x == data->gradient.linear.origin.x; - - if (isVerticalGradient) { - LinearGradientValues linear; - getLinearGradientValues(&linear, data); - - CompositionFunctionSolid funcSolid = - functionForModeSolid[data->rasterBuffer->compositionMode]; - - /* - The logic for vertical gradient calculations is a mathematically - reduced copy of that in fetchLinearGradient() - which is basically: - - qreal ry = data->m22 * (y + 0.5) + data->dy; - qreal t = linear.dy*ry + linear.off; - t *= (GRADIENT_STOPTABLE_SIZE - 1); - quint32 color = - qt_gradient_pixel_fixed(&data->gradient, - int(t * FIXPT_SIZE)); - - This has then been converted to fixed point to improve performance. - */ - const int gss = GRADIENT_STOPTABLE_SIZE - 1; - int yinc = int((linear.dy * data->m22 * gss) * FIXPT_SIZE); - int off = int((((linear.dy * (data->m22 * qreal(0.5) + data->dy) + linear.off) * gss) * FIXPT_SIZE)); - - while (count--) { - int y = spans->y; - int x = spans->x; - - quint32 *dst = (quint32 *)(data->rasterBuffer->scanLine(y)) + x; - quint32 color = - qt_gradient_pixel_fixed(&data->gradient, yinc * y + off); - - funcSolid(dst, spans->len, color, spans->coverage); - ++spans; - } - - } else { - blend_src_generic(count, spans, userData); - } -} - -static void qt_gradient_quint16(int count, const QSpan *spans, void *userData) -{ - QSpanData *data = reinterpret_cast(userData); - - bool isVerticalGradient = - data->txop <= QTransform::TxScale && - data->type == QSpanData::LinearGradient && - data->gradient.linear.end.x == data->gradient.linear.origin.x; - - if (isVerticalGradient) { - - LinearGradientValues linear; - getLinearGradientValues(&linear, data); - - /* - The logic for vertical gradient calculations is a mathematically - reduced copy of that in fetchLinearGradient() - which is basically: - - qreal ry = data->m22 * (y + 0.5) + data->dy; - qreal t = linear.dy*ry + linear.off; - t *= (GRADIENT_STOPTABLE_SIZE - 1); - quint32 color = - qt_gradient_pixel_fixed(&data->gradient, - int(t * FIXPT_SIZE)); - - This has then been converted to fixed point to improve performance. - */ - const int gss = GRADIENT_STOPTABLE_SIZE - 1; - int yinc = int((linear.dy * data->m22 * gss) * FIXPT_SIZE); - int off = int((((linear.dy * (data->m22 * qreal(0.5) + data->dy) + linear.off) * gss) * FIXPT_SIZE)); - - // Save the fillData since we overwrite it when setting solid.color. - QGradientData gradient = data->gradient; - while (count--) { - int y = spans->y; - - data->solid.color = QRgba64::fromArgb32(qt_gradient_pixel_fixed(&gradient, yinc * y + off)); - blend_color_rgb16(1, spans, userData); - ++spans; - } - data->gradient = gradient; - - } else { - blend_src_generic(count, spans, userData); - } -} - inline static void qt_bitmapblit_argb32(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 &color, const uchar *map, @@ -6007,29 +6014,25 @@ static void qt_rectfill_quint64(QRasterBuffer *rasterBuffer, DrawHelper qDrawHelper[QImage::NImageFormats] = { // Format_Invalid, - { 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0 }, // Format_Mono, { blend_color_generic, - blend_src_generic, 0, 0, 0, 0 }, // Format_MonoLSB, { blend_color_generic, - blend_src_generic, 0, 0, 0, 0 }, // Format_Indexed8, { blend_color_generic, - blend_src_generic, 0, 0, 0, 0 }, // Format_RGB32, { blend_color_argb, - qt_gradient_argb32, qt_bitmapblit_argb32, qt_alphamapblit_argb32, qt_alphargbblit_argb32, @@ -6038,7 +6041,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_ARGB32, { blend_color_generic, - blend_src_generic, qt_bitmapblit_argb32, qt_alphamapblit_argb32, qt_alphargbblit_argb32, @@ -6047,7 +6049,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_ARGB32_Premultiplied { blend_color_argb, - qt_gradient_argb32, qt_bitmapblit_argb32, qt_alphamapblit_argb32, qt_alphargbblit_argb32, @@ -6056,7 +6057,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_RGB16 { blend_color_rgb16, - qt_gradient_quint16, qt_bitmapblit_quint16, qt_alphamapblit_quint16, qt_alphargbblit_generic, @@ -6065,7 +6065,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_ARGB8565_Premultiplied { blend_color_generic, - blend_src_generic, 0, qt_alphamapblit_generic, qt_alphargbblit_generic, @@ -6074,7 +6073,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_RGB666 { blend_color_generic, - blend_src_generic, 0, qt_alphamapblit_generic, qt_alphargbblit_generic, @@ -6083,7 +6081,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_ARGB6666_Premultiplied { blend_color_generic, - blend_src_generic, 0, qt_alphamapblit_generic, qt_alphargbblit_generic, @@ -6092,7 +6089,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_RGB555 { blend_color_generic, - blend_src_generic, 0, qt_alphamapblit_generic, qt_alphargbblit_generic, @@ -6101,7 +6097,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_ARGB8555_Premultiplied { blend_color_generic, - blend_src_generic, 0, qt_alphamapblit_generic, qt_alphargbblit_generic, @@ -6110,7 +6105,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_RGB888 { blend_color_generic, - blend_src_generic, 0, qt_alphamapblit_generic, qt_alphargbblit_generic, @@ -6119,7 +6113,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_RGB444 { blend_color_generic, - blend_src_generic, 0, qt_alphamapblit_generic, qt_alphargbblit_generic, @@ -6128,7 +6121,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_ARGB4444_Premultiplied { blend_color_generic, - blend_src_generic, 0, qt_alphamapblit_generic, qt_alphargbblit_generic, @@ -6137,7 +6129,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_RGBX8888 { blend_color_generic, - blend_src_generic, qt_bitmapblit_rgba8888, qt_alphamapblit_generic, qt_alphargbblit_generic, @@ -6146,7 +6137,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_RGBA8888 { blend_color_generic, - blend_src_generic, qt_bitmapblit_rgba8888, qt_alphamapblit_generic, qt_alphargbblit_generic, @@ -6155,7 +6145,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_RGB8888_Premultiplied { blend_color_generic, - blend_src_generic, qt_bitmapblit_rgba8888, qt_alphamapblit_generic, qt_alphargbblit_generic, @@ -6164,7 +6153,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_BGR30 { blend_color_generic_rgb64, - blend_src_generic_rgb64, qt_bitmapblit_rgb30, qt_alphamapblit_generic, qt_alphargbblit_generic, @@ -6173,7 +6161,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_A2BGR30_Premultiplied { blend_color_generic_rgb64, - blend_src_generic_rgb64, qt_bitmapblit_rgb30, qt_alphamapblit_generic, qt_alphargbblit_generic, @@ -6182,7 +6169,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_RGB30 { blend_color_generic_rgb64, - blend_src_generic_rgb64, qt_bitmapblit_rgb30, qt_alphamapblit_generic, qt_alphargbblit_generic, @@ -6191,7 +6177,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_A2RGB30_Premultiplied { blend_color_generic_rgb64, - blend_src_generic_rgb64, qt_bitmapblit_rgb30, qt_alphamapblit_generic, qt_alphargbblit_generic, @@ -6200,7 +6185,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_Alpha8 { blend_color_generic, - blend_src_generic, 0, qt_alphamapblit_generic, qt_alphargbblit_generic, @@ -6209,7 +6193,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_Grayscale8 { blend_color_generic, - blend_src_generic, 0, qt_alphamapblit_generic, qt_alphargbblit_generic, @@ -6218,7 +6201,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_RGBX64 { blend_color_generic_rgb64, - blend_src_generic_rgb64, 0, qt_alphamapblit_generic, qt_alphargbblit_generic, @@ -6227,7 +6209,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_RGBA64 { blend_color_generic_rgb64, - blend_src_generic_rgb64, 0, qt_alphamapblit_generic, qt_alphargbblit_generic, @@ -6236,7 +6217,6 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = // Format_RGBA64_Premultiplied { blend_color_generic_rgb64, - blend_src_generic_rgb64, 0, qt_alphamapblit_generic, qt_alphargbblit_generic, diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index a2cf36f20e..e9a1e48e5f 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -146,7 +146,6 @@ typedef void (*MemRotateFunc)(const uchar *srcPixels, int w, int h, int sbpl, uc struct DrawHelper { ProcessSpans blendColor; - ProcessSpans blendGradient; BitmapBlitFunc bitmapBlit; AlphamapBlitFunc alphamapBlit; AlphaRGBBlitFunc alphaRGBBlit; @@ -159,6 +158,7 @@ extern SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::N extern DrawHelper qDrawHelper[QImage::NImageFormats]; +void qBlendGradient(int count, const QSpan *spans, void *userData); void qBlendTexture(int count, const QSpan *spans, void *userData); extern void qt_memfill64(quint64 *dest, quint64 value, qsizetype count); extern void qt_memfill32(quint32 *dest, quint32 value, qsizetype count); @@ -219,11 +219,6 @@ struct Operator class QRasterPaintEngine; -struct QSolidData -{ - QRgba64 color; -}; - struct QLinearGradientData { struct { @@ -328,8 +323,8 @@ struct QSpanData int fast_matrix : 1; bool bilinear; QImage *tempImage; + QRgba64 solidColor; union { - QSolidData solid; QGradientData gradient; QTextureData texture; }; diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index e530ee568d..729029e233 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -873,7 +873,7 @@ void QRasterPaintEngine::updateRasterState() && s->intOpacity == 256 && (mode == QPainter::CompositionMode_Source || (mode == QPainter::CompositionMode_SourceOver - && s->penData.solid.color.isOpaque())); + && s->penData.solidColor.isOpaque())); } s->dirty = 0; @@ -1528,9 +1528,9 @@ static void fillRect_normalized(const QRect &r, QSpanData *data, if (data->fillRect && (mode == QPainter::CompositionMode_Source || (mode == QPainter::CompositionMode_SourceOver - && data->solid.color.isOpaque()))) + && data->solidColor.isOpaque()))) { - data->fillRect(data->rasterBuffer, x1, y1, width, height, data->solid.color); + data->fillRect(data->rasterBuffer, x1, y1, width, height, data->solidColor); return; } } @@ -1892,9 +1892,9 @@ void QRasterPaintEngine::fillRect(const QRectF &r, const QColor &color) Q_D(QRasterPaintEngine); QRasterPaintEngineState *s = state(); - d->solid_color_filler.solid.color = qPremultiply(combineAlpha256(color.rgba64(), s->intOpacity)); + d->solid_color_filler.solidColor = qPremultiply(combineAlpha256(color.rgba64(), s->intOpacity)); - if (d->solid_color_filler.solid.color.isTransparent() + if (d->solid_color_filler.solidColor.isTransparent() && s->composition_mode == QPainter::CompositionMode_SourceOver) { return; } @@ -2348,14 +2348,14 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe case QImage::Format_A2BGR30_Premultiplied: case QImage::Format_A2RGB30_Premultiplied: // Combine premultiplied color with the opacity set on the painter. - d->solid_color_filler.solid.color = multiplyAlpha256(QRgba64::fromArgb32(color), s->intOpacity); + d->solid_color_filler.solidColor = multiplyAlpha256(QRgba64::fromArgb32(color), s->intOpacity); break; default: - d->solid_color_filler.solid.color = qPremultiply(combineAlpha256(QRgba64::fromArgb32(color), s->intOpacity)); + d->solid_color_filler.solidColor = qPremultiply(combineAlpha256(QRgba64::fromArgb32(color), s->intOpacity)); break; } - if (d->solid_color_filler.solid.color.isTransparent() && s->composition_mode == QPainter::CompositionMode_SourceOver) + if (d->solid_color_filler.solidColor.isTransparent() && s->composition_mode == QPainter::CompositionMode_SourceOver) return; d->solid_color_filler.clip = d->clip(); @@ -2705,20 +2705,20 @@ void QRasterPaintEngine::alphaPenBlt(const void* src, int bpl, int depth, int rx if (unclipped) { if (depth == 1) { if (s->penData.bitmapBlit) { - s->penData.bitmapBlit(rb, rx, ry, s->penData.solid.color, + s->penData.bitmapBlit(rb, rx, ry, s->penData.solidColor, scanline, w, h, bpl); return; } } else if (depth == 8) { if (s->penData.alphamapBlit) { - s->penData.alphamapBlit(rb, rx, ry, s->penData.solid.color, + s->penData.alphamapBlit(rb, rx, ry, s->penData.solidColor, scanline, w, h, bpl, 0, useGammaCorrection); return; } } else if (depth == 32) { // (A)RGB Alpha mask where the alpha component is not used. if (s->penData.alphaRGBBlit) { - s->penData.alphaRGBBlit(rb, rx, ry, s->penData.solid.color, + s->penData.alphaRGBBlit(rb, rx, ry, s->penData.solidColor, (const uint *) scanline, w, h, bpl / 4, 0, useGammaCorrection); return; } @@ -2747,10 +2747,10 @@ void QRasterPaintEngine::alphaPenBlt(const void* src, int bpl, int depth, int rx ry = ny; } if (depth == 8) - s->penData.alphamapBlit(rb, rx, ry, s->penData.solid.color, + s->penData.alphamapBlit(rb, rx, ry, s->penData.solidColor, scanline, w, h, bpl, clip, useGammaCorrection); else if (depth == 32) - s->penData.alphaRGBBlit(rb, rx, ry, s->penData.solid.color, + s->penData.alphaRGBBlit(rb, rx, ry, s->penData.solidColor, (const uint *) scanline, w, h, bpl / 4, clip, useGammaCorrection); return; } @@ -4587,8 +4587,8 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode case Qt::SolidPattern: { type = Solid; QColor c = qbrush_color(brush); - solid.color = qPremultiply(combineAlpha256(c.rgba64(), alpha)); - if (solid.color.isTransparent() && compositionMode == QPainter::CompositionMode_SourceOver) + solidColor = qPremultiply(combineAlpha256(c.rgba64(), alpha)); + if (solidColor.isTransparent() && compositionMode == QPainter::CompositionMode_SourceOver) type = None; break; } @@ -4726,7 +4726,7 @@ void QSpanData::adjustSpanMethods() case LinearGradient: case RadialGradient: case ConicalGradient: - unclipped_blend = qDrawHelper[rasterBuffer->format].blendGradient; + unclipped_blend = qBlendGradient; break; case Texture: unclipped_blend = qBlendTexture; From a5e1dc5e9207a6068a8d42533dd77891c1a426cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Wed, 14 Nov 2018 15:16:00 +0100 Subject: [PATCH 0331/1650] Ssl: Windows: Don't load Crypt32 symbols on runtime We have linked against Crypt32 for a while. Change-Id: I7ec9401a63d7405e4b5357d6589501e997e31aca Reviewed-by: Timur Pocheptsov --- src/network/ssl/qsslsocket_openssl.cpp | 34 ++++++++------------- src/network/ssl/qsslsocket_openssl11.cpp | 16 +--------- src/network/ssl/qsslsocket_opensslpre11.cpp | 16 +--------- src/network/ssl/qsslsocket_p.h | 14 --------- 4 files changed, 15 insertions(+), 65 deletions(-) diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 37bb3e4933..c4306abdf8 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -87,12 +87,6 @@ QT_BEGIN_NAMESPACE -#if defined(Q_OS_WIN) - PtrCertOpenSystemStoreW QSslSocketPrivate::ptrCertOpenSystemStoreW = nullptr; - PtrCertFindCertificateInStore QSslSocketPrivate::ptrCertFindCertificateInStore = nullptr; - PtrCertCloseStore QSslSocketPrivate::ptrCertCloseStore = nullptr; -#endif - bool QSslSocketPrivate::s_libraryLoaded = false; bool QSslSocketPrivate::s_loadedCiphersAndCerts = false; bool QSslSocketPrivate::s_loadRootCertsOnDemand = false; @@ -544,22 +538,20 @@ QList QSslSocketPrivate::systemCaCertificates() #endif QList systemCerts; #if defined(Q_OS_WIN) - if (ptrCertOpenSystemStoreW && ptrCertFindCertificateInStore && ptrCertCloseStore) { - HCERTSTORE hSystemStore; - hSystemStore = ptrCertOpenSystemStoreW(0, L"ROOT"); - if (hSystemStore) { - PCCERT_CONTEXT pc = nullptr; - while (1) { - pc = ptrCertFindCertificateInStore(hSystemStore, X509_ASN_ENCODING, 0, CERT_FIND_ANY, nullptr, pc); - if (!pc) - break; - QByteArray der(reinterpret_cast(pc->pbCertEncoded), - static_cast(pc->cbCertEncoded)); - QSslCertificate cert(der, QSsl::Der); - systemCerts.append(cert); - } - ptrCertCloseStore(hSystemStore, 0); + HCERTSTORE hSystemStore; + hSystemStore = CertOpenSystemStoreW(0, L"ROOT"); + if (hSystemStore) { + PCCERT_CONTEXT pc = nullptr; + while (1) { + pc = CertFindCertificateInStore(hSystemStore, X509_ASN_ENCODING, 0, CERT_FIND_ANY, nullptr, pc); + if (!pc) + break; + QByteArray der(reinterpret_cast(pc->pbCertEncoded), + static_cast(pc->cbCertEncoded)); + QSslCertificate cert(der, QSsl::Der); + systemCerts.append(cert); } + CertCloseStore(hSystemStore, 0); } #elif defined(Q_OS_UNIX) QSet certFiles; diff --git a/src/network/ssl/qsslsocket_openssl11.cpp b/src/network/ssl/qsslsocket_openssl11.cpp index 2a2667bd48..b60b8be41f 100644 --- a/src/network/ssl/qsslsocket_openssl11.cpp +++ b/src/network/ssl/qsslsocket_openssl11.cpp @@ -122,21 +122,7 @@ void QSslSocketPrivate::ensureCiphersAndCertsLoaded() #if QT_CONFIG(library) //load symbols needed to receive certificates from system store -#if defined(Q_OS_WIN) - HINSTANCE hLib = LoadLibraryW(L"Crypt32"); - if (hLib) { - ptrCertOpenSystemStoreW = reinterpret_cast( - reinterpret_cast(GetProcAddress(hLib, "CertOpenSystemStoreW"))); - ptrCertFindCertificateInStore = reinterpret_cast( - reinterpret_cast(GetProcAddress(hLib, "CertFindCertificateInStore"))); - ptrCertCloseStore = reinterpret_cast( - reinterpret_cast(GetProcAddress(hLib, "CertCloseStore"))); - if (!ptrCertOpenSystemStoreW || !ptrCertFindCertificateInStore || !ptrCertCloseStore) - qCWarning(lcSsl, "could not resolve symbols in crypt32 library"); // should never happen - } else { - qCWarning(lcSsl, "could not load crypt32 library"); // should never happen - } -#elif defined(Q_OS_QNX) +#if defined(Q_OS_QNX) s_loadRootCertsOnDemand = true; #elif defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) // check whether we can enable on-demand root-cert loading (i.e. check whether the sym links are there) diff --git a/src/network/ssl/qsslsocket_opensslpre11.cpp b/src/network/ssl/qsslsocket_opensslpre11.cpp index bc4fd9dc85..f5aab821ea 100644 --- a/src/network/ssl/qsslsocket_opensslpre11.cpp +++ b/src/network/ssl/qsslsocket_opensslpre11.cpp @@ -251,21 +251,7 @@ void QSslSocketPrivate::ensureCiphersAndCertsLoaded() #if QT_CONFIG(library) //load symbols needed to receive certificates from system store -#if defined(Q_OS_WIN) - HINSTANCE hLib = LoadLibraryW(L"Crypt32"); - if (hLib) { - ptrCertOpenSystemStoreW = reinterpret_cast( - reinterpret_cast(GetProcAddress(hLib, "CertOpenSystemStoreW"))); - ptrCertFindCertificateInStore = reinterpret_cast( - reinterpret_cast(GetProcAddress(hLib, "CertFindCertificateInStore"))); - ptrCertCloseStore = reinterpret_cast( - reinterpret_cast(GetProcAddress(hLib, "CertCloseStore"))); - if (!ptrCertOpenSystemStoreW || !ptrCertFindCertificateInStore || !ptrCertCloseStore) - qCWarning(lcSsl, "could not resolve symbols in crypt32 library"); // should never happen - } else { - qCWarning(lcSsl, "could not load crypt32 library"); // should never happen - } -#elif defined(Q_OS_QNX) +#if defined(Q_OS_QNX) s_loadRootCertsOnDemand = true; #elif defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) // check whether we can enable on-demand root-cert loading (i.e. check whether the sym links are there) diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h index c27496ec02..2f394f013b 100644 --- a/src/network/ssl/qsslsocket_p.h +++ b/src/network/ssl/qsslsocket_p.h @@ -89,14 +89,6 @@ QT_BEGIN_NAMESPACE typedef OSStatus (*PtrSecTrustCopyAnchorCertificates)(CFArrayRef*); #endif -#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) - typedef HCERTSTORE (WINAPI *PtrCertOpenSystemStoreW)(HCRYPTPROV_LEGACY, LPCWSTR); - typedef PCCERT_CONTEXT (WINAPI *PtrCertFindCertificateInStore)(HCERTSTORE, DWORD, DWORD, DWORD, const void*, PCCERT_CONTEXT); - typedef BOOL (WINAPI *PtrCertCloseStore)(HCERTSTORE, DWORD); -#endif // Q_OS_WIN && !Q_OS_WINRT - - - class QSslSocketPrivate : public QTcpSocketPrivate { Q_DECLARE_PUBLIC(QSslSocket) @@ -155,12 +147,6 @@ public: const QString &peerName); Q_AUTOTEST_EXPORT static bool isMatchingHostname(const QString &cn, const QString &hostname); -#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) - static PtrCertOpenSystemStoreW ptrCertOpenSystemStoreW; - static PtrCertFindCertificateInStore ptrCertFindCertificateInStore; - static PtrCertCloseStore ptrCertCloseStore; -#endif // Q_OS_WIN && !Q_OS_WINRT - // The socket itself, including private slots. QTcpSocket *plainSocket; void createPlainSocket(QIODevice::OpenMode openMode); From 6e34552638cc4a6e71f90a36a7c6cea457b24fe1 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Fri, 20 Jul 2018 09:21:08 +0200 Subject: [PATCH 0332/1650] Enable users to specify WindowsTargetPlatform[Min]Version in VS projects [ChangeLog][qmake] Introduced the variables WINDOWS_TARGET_PLATFORM_VERSION and WINDOWS_TARGET_PLATFORM_MIN_VERSION for overriding the default values of WindowsTargetPlatformVersion and WindowsTargetPlatformMinVersion in Visual Studio project files. The code to determine the default values is moved to qmake feature files. A common/windows-desktop.conf file is introduced for variables common to all non-UWP Windows mkspecs. The package_manifest feature uses WINDOWS_TARGET_PLATFORM_VERSION as default value for WINRT_MANIFEST.minVersion, and WINDOWS_TARGET_PLATFORM_MIN_VERSION for WINRT_MANIFEST.maxVersionTested respectively. Task-number: QTBUG-53654 Change-Id: I251ec7f9b804c9bc9f7d571f5b43d52b2a2d99d3 Reviewed-by: Oswald Buddenhagen Reviewed-by: Oliver Wolff --- mkspecs/common/msvc-desktop.conf | 1 + mkspecs/common/windows-desktop.conf | 5 ++++ mkspecs/common/winrt_winphone/qmake.conf | 2 ++ mkspecs/features/default_post.prf | 4 +++ mkspecs/features/winrt/package_manifest.prf | 7 ++--- mkspecs/win32-g++/qmake.conf | 1 + qmake/doc/src/qmake-manual.qdoc | 26 +++++++++++++++++-- .../generators/win32/msbuild_objectmodel.cpp | 23 +++------------- qmake/generators/win32/msvc_objectmodel.h | 2 ++ qmake/generators/win32/msvc_vcproj.cpp | 4 +++ 10 files changed, 51 insertions(+), 24 deletions(-) create mode 100644 mkspecs/common/windows-desktop.conf diff --git a/mkspecs/common/msvc-desktop.conf b/mkspecs/common/msvc-desktop.conf index a4fadeb029..d5db3e81d5 100644 --- a/mkspecs/common/msvc-desktop.conf +++ b/mkspecs/common/msvc-desktop.conf @@ -115,4 +115,5 @@ VCSOLUTION_EXTENSION = .sln VCPROJ_KEYWORD = Qt4VSv1.0 include(angle.conf) +include(windows-desktop.conf) include(windows-vulkan.conf) diff --git a/mkspecs/common/windows-desktop.conf b/mkspecs/common/windows-desktop.conf new file mode 100644 index 0000000000..c1f2955e1b --- /dev/null +++ b/mkspecs/common/windows-desktop.conf @@ -0,0 +1,5 @@ +# This file contains initializations for Windows Desktop platforms (non-UWP) + +WINDOWS_TARGET_PLATFORM_VERSION = $$(WindowsSDKVersion) +# The version number might have a trailing backslash due to a VS bug. +WINDOWS_TARGET_PLATFORM_VERSION ~= s/\\\\$// diff --git a/mkspecs/common/winrt_winphone/qmake.conf b/mkspecs/common/winrt_winphone/qmake.conf index 375e084127..03fb96f2c5 100644 --- a/mkspecs/common/winrt_winphone/qmake.conf +++ b/mkspecs/common/winrt_winphone/qmake.conf @@ -97,6 +97,8 @@ WINRT_ASSETS_PATH = $$PWD/assets WINRT_MANIFEST.capabilities = defaults WINRT_MANIFEST.capabilities_device = defaults +WINDOWS_TARGET_PLATFORM_VERSION = $$(UCRTVERSION) + include(../angle.conf) load(qt_config) diff --git a/mkspecs/features/default_post.prf b/mkspecs/features/default_post.prf index fbf1f3b8df..d90da49781 100644 --- a/mkspecs/features/default_post.prf +++ b/mkspecs/features/default_post.prf @@ -90,6 +90,10 @@ staticlib:unix { QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_STATIC_LIB } +defined(WINDOWS_TARGET_PLATFORM_VERSION, var):isEmpty(WINDOWS_TARGET_PLATFORM_MIN_VERSION) { + WINDOWS_TARGET_PLATFORM_MIN_VERSION = $$WINDOWS_TARGET_PLATFORM_VERSION +} + incredibuild_xge { CONFIG -= incredibuild_xge CONFIG = incredibuild_xge $$CONFIG diff --git a/mkspecs/features/winrt/package_manifest.prf b/mkspecs/features/winrt/package_manifest.prf index d850254dcf..facf726715 100644 --- a/mkspecs/features/winrt/package_manifest.prf +++ b/mkspecs/features/winrt/package_manifest.prf @@ -96,9 +96,10 @@ isEmpty(WINRT_MANIFEST.foreground): WINRT_MANIFEST.foreground = light isEmpty(WINRT_MANIFEST.default_language): WINRT_MANIFEST.default_language = en *-msvc2015|*-msvc2017 { - isEmpty(WINRT_MANIFEST.minVersion): WINRT_MANIFEST.minVersion = $$(UCRTVersion) - isEmpty(WINRT_MANIFEST.minVersion): error("No UCRTVersion found in environment.")) - isEmpty(WINRT_MANIFEST.maxVersionTested): WINRT_MANIFEST.maxVersionTested = $$WINRT_MANIFEST.minVersion + isEmpty(WINRT_MANIFEST.minVersion): \ + WINRT_MANIFEST.minVersion = $$WINDOWS_TARGET_PLATFORM_VERSION + isEmpty(WINRT_MANIFEST.maxVersionTested): \ + WINRT_MANIFEST.maxVersionTested = $$WINDOWS_TARGET_PLATFORM_MIN_VERSION } INDENT = "$$escape_expand(\\r\\n) " diff --git a/mkspecs/win32-g++/qmake.conf b/mkspecs/win32-g++/qmake.conf index ed131c6823..9bd2f5525f 100644 --- a/mkspecs/win32-g++/qmake.conf +++ b/mkspecs/win32-g++/qmake.conf @@ -8,6 +8,7 @@ # include(../common/g++-win32.conf) +include(../common/windows-desktop.conf) # modifications to g++-win32.conf diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index 1a779a94b4..645422050b 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -2788,6 +2788,26 @@ See also \l{#DEPENDPATH}{DEPENDPATH}. + \target WINDOWS_TARGET_PLATFORM_VERSION + \section1 WINDOWS_TARGET_PLATFORM_VERSION + + Specifies the targeted Windows version; this corresponds to the tag + \c{WindowsTargetPlatformVersion} in vcxproj files. + + On desktop Windows, the default value is the value of the environment + variable \c{WindowsSDKVersion}. + + On WinRT, the default value is the value of the environment variable + \c{UCRTVERSION}. + + \target WINDOWS_TARGET_PLATFORM_MIN_VERSION + \section1 WINDOWS_TARGET_PLATFORM_MIN_VERSION + + Specifies the minimum version of the Windows target platform; this + corresponds to the tag \c{WindowsTargetPlatformMinVersion} in vcxproj files. + + Defaults to \c{WINDOWS_TARGET_PLATFORM_VERSION}. + \target WINRT_MANIFEST \section1 WINRT_MANIFEST @@ -2921,10 +2941,12 @@ \li The version number of the package. Defaults to \c{1.0.0.0}. \row \li minVersion - \li The minimum required Windows version to run the package. Defaults to the environment variable \c UCRTVersion. + \li The minimum required Windows version to run the package. + Defaults to \c{WINDOWS_TARGET_PLATFORM_VERSION}. \row \li maxVersionTested - \li The maximum Windows version the package has been tested against. Defaults to \c WINRT_MANIFEST.minVersion + \li The maximum Windows version the package has been tested against. + Defaults to \c{WINDOWS_TARGET_PLATFORM_MIN_VERSION}. \endtable diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp index ad2976aa01..0e95766f8e 100644 --- a/qmake/generators/win32/msbuild_objectmodel.cpp +++ b/qmake/generators/win32/msbuild_objectmodel.cpp @@ -34,7 +34,6 @@ #include #include #include -#include QT_BEGIN_NAMESPACE @@ -625,31 +624,17 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) << tagValue("RootNamespace", tool.Name) << tagValue("Keyword", tool.Keyword); - QString windowsTargetPlatformVersion; if (isWinRT) { xml << tagValue("MinimumVisualStudioVersion", tool.Version) << tagValue("DefaultLanguage", "en") << tagValue("AppContainerApplication", "true") << tagValue("ApplicationType", "Windows Store") << tagValue("ApplicationTypeRevision", tool.SdkVersion); - if (tool.SdkVersion == "10.0") - windowsTargetPlatformVersion = qgetenv("UCRTVERSION"); - } else { - QByteArray winSDKVersionStr = qgetenv("WindowsSDKVersion").trimmed(); - - // This environment variable might end with a backslash due to a VS bug. - if (winSDKVersionStr.endsWith('\\')) - winSDKVersionStr.chop(1); - - QVersionNumber winSDKVersion = QVersionNumber::fromString( - QString::fromLocal8Bit(winSDKVersionStr)); - if (!winSDKVersion.isNull()) - windowsTargetPlatformVersion = winSDKVersionStr; - } - if (!windowsTargetPlatformVersion.isEmpty()) { - xml << tagValue("WindowsTargetPlatformVersion", windowsTargetPlatformVersion) - << tagValue("WindowsTargetPlatformMinVersion", windowsTargetPlatformVersion); } + if (!tool.WindowsTargetPlatformVersion.isEmpty()) + xml << tagValue("WindowsTargetPlatformVersion", tool.WindowsTargetPlatformVersion); + if (!tool.WindowsTargetPlatformMinVersion.isEmpty()) + xml << tagValue("WindowsTargetPlatformMinVersion", tool.WindowsTargetPlatformMinVersion); xml << closetag(); diff --git a/qmake/generators/win32/msvc_objectmodel.h b/qmake/generators/win32/msvc_objectmodel.h index 9d1a170489..f8f9804c27 100644 --- a/qmake/generators/win32/msvc_objectmodel.h +++ b/qmake/generators/win32/msvc_objectmodel.h @@ -1123,6 +1123,8 @@ public: QString SccLocalPath; QString PlatformName; QString SdkVersion; + QString WindowsTargetPlatformVersion; + QString WindowsTargetPlatformMinVersion; // Single projects QList SingleProjects; diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 95c16661e7..db2a16ae35 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -191,6 +191,10 @@ bool VcprojGenerator::writeProjectMakefile() mergedProject.SccProjectName = mergedProjects.at(0)->vcProject.SccProjectName; mergedProject.SccLocalPath = mergedProjects.at(0)->vcProject.SccLocalPath; mergedProject.PlatformName = mergedProjects.at(0)->vcProject.PlatformName; + mergedProject.WindowsTargetPlatformVersion = + project->first("WINDOWS_TARGET_PLATFORM_VERSION").toQString(); + mergedProject.WindowsTargetPlatformMinVersion = + project->first("WINDOWS_TARGET_PLATFORM_MIN_VERSION").toQString(); XmlOutput xmlOut(t); projectWriter->write(xmlOut, mergedProject); From 7a4f41bad98da9953abcea05a71c2986406c7695 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Wed, 14 Nov 2018 09:47:21 +0100 Subject: [PATCH 0333/1650] tests: Distinguish tst_qeventdispatcher and tst_qguieventdispatcher Both use same source, but link without and with Qt Gui library. Task-number: QTBUG-71751 Change-Id: I5643a07a8067f5fc10fc66f717f19bc3e16a33ab Reviewed-by: Timur Pocheptsov Reviewed-by: Edward Welbourne --- .../corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp b/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp index ca183752a5..49c10c6a24 100644 --- a/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp +++ b/tests/auto/corelib/kernel/qeventdispatcher/tst_qeventdispatcher.cpp @@ -28,6 +28,7 @@ #ifdef QT_GUI_LIB # include +# define tst_QEventDispatcher tst_QGuiEventDispatcher #else # include #endif From c340b0b2791214fb52dfbfd0c6ae50eda6a37fa2 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 13 Nov 2018 13:44:28 +0100 Subject: [PATCH 0334/1650] Generalize fill span optimization This was added to RGB64 rendering because pixel conversions could be expensive, but when painting to non-standard imageformats, the same can also be expensive in the generic 32-bit backend, and thus benefit from the optimization as well. Change-Id: I747a398670b1d4dbd844a772e7aafce3c8dbef20 Reviewed-by: Eirik Aavitsland --- src/gui/painting/qdrawhelper.cpp | 68 ++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 16 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 0df1eaf928..a588ca0969 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -4280,7 +4280,7 @@ static inline Operator getOperator(const QSpanData *data, const QSpan *spans, in } ++spans; } - if (!alphaSpans) { + if (!alphaSpans && spanCount > 0) { // If all spans are opaque we do not need to fetch dest. // But don't clear passthrough destFetch as they are just as fast and save destStore. if (op.destFetch != destFetchARGB32P) @@ -4301,23 +4301,62 @@ static inline Operator getOperator(const QSpanData *data, const QSpan *spans, in return op; } +static void spanfill_from_first(QRasterBuffer *rasterBuffer, QPixelLayout::BPP bpp, int x, int y, int length) +{ + switch (bpp) { + case QPixelLayout::BPP64: { + quint64 *dest = reinterpret_cast(rasterBuffer->scanLine(y)) + x; + qt_memfill_template(dest + 1, dest[0], length - 1); + break; + } + case QPixelLayout::BPP32: { + quint32 *dest = reinterpret_cast(rasterBuffer->scanLine(y)) + x; + qt_memfill_template(dest + 1, dest[0], length - 1); + break; + } + case QPixelLayout::BPP24: { + quint24 *dest = reinterpret_cast(rasterBuffer->scanLine(y)) + x; + qt_memfill_template(dest + 1, dest[0], length - 1); + break; + } + case QPixelLayout::BPP16: { + quint16 *dest = reinterpret_cast(rasterBuffer->scanLine(y)) + x; + qt_memfill_template(dest + 1, dest[0], length - 1); + break; + } + case QPixelLayout::BPP8: { + uchar *dest = rasterBuffer->scanLine(y) + x; + memset(dest + 1, dest[0], length - 1); + break; + } + default: + Q_UNREACHABLE(); + } +} // -------------------- blend methods --------------------- -#if !defined(Q_CC_SUN) -static -#endif -void blend_color_generic(int count, const QSpan *spans, void *userData) +static void blend_color_generic(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast(userData); uint buffer[BufferSize]; - Operator op = getOperator(data, spans, count); + Operator op = getOperator(data, nullptr, 0); const uint color = data->solidColor.toArgb32(); + bool solidFill = data->rasterBuffer->compositionMode == QPainter::CompositionMode_Source + || (data->rasterBuffer->compositionMode == QPainter::CompositionMode_SourceOver && qAlpha(color) == 255); + QPixelLayout::BPP bpp = qPixelLayouts[data->rasterBuffer->format].bpp; while (count--) { int x = spans->x; int length = spans->len; + if (solidFill && bpp >= QPixelLayout::BPP8 && spans->coverage == 255 && length) { + // If dest doesn't matter we don't need to bother with blending or converting all the identical pixels + op.destStore(data->rasterBuffer, x, spans->y, &color, 1); + spanfill_from_first(data->rasterBuffer, bpp, x, spans->y, length); + length = 0; + } + while (length) { int l = qMin(BufferSize, length); uint *dest = op.destFetch(buffer, data->rasterBuffer, x, spans->y, l); @@ -4335,7 +4374,7 @@ static void blend_color_argb(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast(userData); - const Operator op = getOperator(data, spans, count); + const Operator op = getOperator(data, nullptr, 0); const uint color = data->solidColor.toArgb32(); if (op.mode == QPainter::CompositionMode_Source) { @@ -4365,7 +4404,7 @@ static void blend_color_argb(int count, const QSpan *spans, void *userData) void blend_color_generic_rgb64(int count, const QSpan *spans, void *userData) { QSpanData *data = reinterpret_cast(userData); - Operator op = getOperator(data, spans, count); + Operator op = getOperator(data, nullptr, 0); if (!op.funcSolid64) { qCDebug(lcQtGuiDrawHelper, "blend_color_generic_rgb64: unsupported 64bit blend attempted, falling back to 32-bit"); return blend_color_generic(count, spans, userData); @@ -4375,19 +4414,16 @@ void blend_color_generic_rgb64(int count, const QSpan *spans, void *userData) const QRgba64 color = data->solidColor; bool solidFill = data->rasterBuffer->compositionMode == QPainter::CompositionMode_Source || (data->rasterBuffer->compositionMode == QPainter::CompositionMode_SourceOver && color.isOpaque()); - bool isBpp32 = qPixelLayouts[data->rasterBuffer->format].bpp == QPixelLayout::BPP32; + QPixelLayout::BPP bpp = qPixelLayouts[data->rasterBuffer->format].bpp; while (count--) { int x = spans->x; int length = spans->len; - if (solidFill && isBpp32 && spans->coverage == 255) { + if (solidFill && bpp >= QPixelLayout::BPP8 && spans->coverage == 255 && length) { // If dest doesn't matter we don't need to bother with blending or converting all the identical pixels - if (length > 0) { - op.destStore64(data->rasterBuffer, x, spans->y, &color, 1); - uint *dest = (uint*)data->rasterBuffer->scanLine(spans->y) + x; - qt_memfill32(dest + 1, dest[0], length - 1); - length = 0; - } + op.destStore64(data->rasterBuffer, x, spans->y, &color, 1); + spanfill_from_first(data->rasterBuffer, bpp, x, spans->y, length); + length = 0; } while (length) { From 229b363c857f6ba8565096260367c454dc2c1a95 Mon Sep 17 00:00:00 2001 From: Lars Schmertmann Date: Fri, 6 Jul 2018 08:42:36 +0200 Subject: [PATCH 0335/1650] Add QSettings(Scope...) constructor to QSettings Because of the system specific folder/filenames (organization name vs domain) it was not possible to explicitly access the settings with SystemScope without using #ifdef, as it is done by Qt internally. The new constructor uses the default name while creating an instance with a scope. [ChangeLog][QtCore][QSettings] Added QSettings(Scope...) constructor to avoid using #ifdef in Qt applications. Change-Id: I81016430a1d18a382bfdd1e1cf32de367f98d7aa Reviewed-by: Oswald Buddenhagen Reviewed-by: Edward Welbourne --- src/corelib/io/qsettings.cpp | 45 +++++++++++++++++++++++++++++++----- src/corelib/io/qsettings.h | 4 ++++ 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 8b9f7bc9e5..4a9b2a7261 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -64,8 +64,8 @@ #include "qrect.h" #endif // !QT_NO_GEOM_VARIANT -#ifndef QT_NO_QOBJECT -#include "qcoreapplication.h" +#ifndef QT_BUILD_QMAKE +# include "qcoreapplication.h" #endif #ifndef QT_BOOTSTRAPPED @@ -2660,9 +2660,10 @@ QSettings::QSettings(const QString &fileName, Format format, QObject *parent) called, the QSettings object will not be able to read or write any settings, and status() will return AccessError. - On \macos and iOS, if both a name and an Internet domain are specified - for the organization, the domain is preferred over the name. On - other platforms, the name is preferred over the domain. + You should supply both the domain (used by default on \macos and iOS) and + the name (used by default elsewhere), although the code will cope if you + supply only one, which will then be used (on all platforms), at odds with + the usual naming of the file on platforms for which it isn't the default. \sa QCoreApplication::setOrganizationName(), QCoreApplication::setOrganizationDomain(), @@ -2670,7 +2671,20 @@ QSettings::QSettings(const QString &fileName, Format format, QObject *parent) setDefaultFormat() */ QSettings::QSettings(QObject *parent) - : QObject(*QSettingsPrivate::create(globalDefaultFormat, UserScope, + : QSettings(UserScope, parent) +{ +} + +/*! + \since 5.13 + + Constructs a QSettings object in the same way as + QSettings(QObject *parent) but with the given \a scope. + + \sa QSettings(QObject *parent) +*/ +QSettings::QSettings(Scope scope, QObject *parent) + : QObject(*QSettingsPrivate::create(globalDefaultFormat, scope, #ifdef Q_OS_MAC QCoreApplication::organizationDomain().isEmpty() ? QCoreApplication::organizationName() @@ -2710,6 +2724,25 @@ QSettings::QSettings(const QString &fileName, Format format) { d_ptr->q_ptr = this; } + +# ifndef QT_BUILD_QMAKE +QSettings::QSettings(Scope scope) + : d_ptr(QSettingsPrivate::create(globalDefaultFormat, scope, +# ifdef Q_OS_DARWIN + QCoreApplication::organizationDomain().isEmpty() + ? QCoreApplication::organizationName() + : QCoreApplication::organizationDomain() +# else + QCoreApplication::organizationName().isEmpty() + ? QCoreApplication::organizationDomain() + : QCoreApplication::organizationName() +# endif + , QCoreApplication::applicationName()) + ) +{ + d_ptr->q_ptr = this; +} +# endif #endif /*! diff --git a/src/corelib/io/qsettings.h b/src/corelib/io/qsettings.h index ccfec787a6..947507b642 100644 --- a/src/corelib/io/qsettings.h +++ b/src/corelib/io/qsettings.h @@ -132,6 +132,7 @@ public: const QString &application = QString(), QObject *parent = nullptr); QSettings(const QString &fileName, Format format, QObject *parent = nullptr); explicit QSettings(QObject *parent = nullptr); + explicit QSettings(Scope scope, QObject *parent = nullptr); #else explicit QSettings(const QString &organization, const QString &application = QString()); @@ -140,6 +141,9 @@ public: QSettings(Format format, Scope scope, const QString &organization, const QString &application = QString()); QSettings(const QString &fileName, Format format); +# ifndef QT_BUILD_QMAKE + explicit QSettings(Scope scope = UserScope); +# endif #endif ~QSettings(); From d3fe78f6c49840ac2697be39a98192f38cb60691 Mon Sep 17 00:00:00 2001 From: Lars Schmertmann Date: Tue, 6 Nov 2018 18:49:03 +0100 Subject: [PATCH 0336/1650] Replace Q_OS_MAC with Q_OS_DARWIN to match line 2731 Change-Id: Ieefa490d349169db801f3b6d8e3cf799c7621473 Reviewed-by: Edward Welbourne --- src/corelib/io/qsettings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 4a9b2a7261..3886b16dcf 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -2685,7 +2685,7 @@ QSettings::QSettings(QObject *parent) */ QSettings::QSettings(Scope scope, QObject *parent) : QObject(*QSettingsPrivate::create(globalDefaultFormat, scope, -#ifdef Q_OS_MAC +#ifdef Q_OS_DARWIN QCoreApplication::organizationDomain().isEmpty() ? QCoreApplication::organizationName() : QCoreApplication::organizationDomain() From 97d12b454118730afc2f03ac44a6be12b47823ee Mon Sep 17 00:00:00 2001 From: Ivan Komissarov Date: Sat, 20 Oct 2018 18:02:12 +0200 Subject: [PATCH 0337/1650] qnativesocketengine_win.cpp: Improve memory handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We use std::vector and thus RAII instead of manual memory management. std::vector (re)allocates only if needed, growing exponentially, initializing only new elements. std::vector<>::resize also makes initialization loop redundant Task-number: QTBUG-71156 Change-Id: I253bb428c0fb641872f0f7f2dcfe1f9e89db0296 Reviewed-by: Timur Pocheptsov Reviewed-by: Mikhail Svetkin Reviewed-by: Mårten Nordheim --- .../socket/qnativesocketengine_win.cpp | 24 ++++++------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index c999bd2088..24e8eabb6e 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -1146,22 +1146,17 @@ qint64 QNativeSocketEnginePrivate::nativePendingDatagramSize() const qint64 ret = -1; int recvResult = 0; DWORD flags; - DWORD bufferCount = 5; - WSABUF * buf = 0; + // We start at 1500 bytes (the MTU for Ethernet V2), which should catch + // almost all uses (effective MTU for UDP under IPv4 is 1468), except + // for localhost datagrams and those reassembled by the IP layer. + char udpMessagePeekBuffer[1500]; + std::vector buf; for (;;) { - // We start at 1500 bytes (the MTU for Ethernet V2), which should catch - // almost all uses (effective MTU for UDP under IPv4 is 1468), except - // for localhost datagrams and those reassembled by the IP layer. - char udpMessagePeekBuffer[1500]; + buf.resize(buf.size() + 5, {sizeof(udpMessagePeekBuffer), udpMessagePeekBuffer}); - buf = new WSABUF[bufferCount]; - for (DWORD i=0; i Date: Thu, 1 Nov 2018 15:57:35 -0700 Subject: [PATCH 0338/1650] tst_QResourceEngine: store the actual byte contents that we expect Instead of using a QString with only the prefix, let's do a full comparison to make sure there's no junk at the end of the file. Take the opportunity to remove the nonsense of a space at the end of most of these files (I didn't remove from all). Change-Id: I343f2beed55440a7ac0bfffd15632228c1bfe78f Reviewed-by: Lars Knoll --- .../corelib/io/qresourceengine/.gitattributes | 1 + .../testqrc/aliasdir/aliasdir.txt | 2 +- .../io/qresourceengine/testqrc/blahblah.txt | 2 +- .../io/qresourceengine/testqrc/currentdir.txt | 2 +- .../qresourceengine/testqrc/currentdir2.txt | 2 +- .../testqrc/otherdir/otherdir.txt | 2 +- .../qresourceengine/testqrc/subdir/subdir.txt | 2 +- .../testqrc/test/test/test1.txt | 2 +- .../testqrc/test/test/test2.txt | 2 +- .../qresourceengine/testqrc/test/testdir.txt | 2 +- .../qresourceengine/testqrc/test/testdir2.txt | 2 +- .../qresourceengine/tst_qresourceengine.cpp | 59 ++++++++++--------- 12 files changed, 41 insertions(+), 39 deletions(-) diff --git a/tests/auto/corelib/io/qresourceengine/.gitattributes b/tests/auto/corelib/io/qresourceengine/.gitattributes index add3716d81..88edd3681a 100644 --- a/tests/auto/corelib/io/qresourceengine/.gitattributes +++ b/tests/auto/corelib/io/qresourceengine/.gitattributes @@ -1 +1,2 @@ testqrc/test.qrc -crlf +*.txt -crlf diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/aliasdir/aliasdir.txt b/tests/auto/corelib/io/qresourceengine/testqrc/aliasdir/aliasdir.txt index 21a3dfa0b8..dcf7937f0a 100644 --- a/tests/auto/corelib/io/qresourceengine/testqrc/aliasdir/aliasdir.txt +++ b/tests/auto/corelib/io/qresourceengine/testqrc/aliasdir/aliasdir.txt @@ -1 +1 @@ -"This is a korean text file" +"This is a korean text file" diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/blahblah.txt b/tests/auto/corelib/io/qresourceengine/testqrc/blahblah.txt index 436c4d11c3..19f0805d8d 100644 --- a/tests/auto/corelib/io/qresourceengine/testqrc/blahblah.txt +++ b/tests/auto/corelib/io/qresourceengine/testqrc/blahblah.txt @@ -1 +1 @@ -qwerty +qwerty diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/currentdir.txt b/tests/auto/corelib/io/qresourceengine/testqrc/currentdir.txt index 38e389979a..65f1f43def 100644 --- a/tests/auto/corelib/io/qresourceengine/testqrc/currentdir.txt +++ b/tests/auto/corelib/io/qresourceengine/testqrc/currentdir.txt @@ -1 +1 @@ -"This is the current dir" +"This is the current dir" diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/currentdir2.txt b/tests/auto/corelib/io/qresourceengine/testqrc/currentdir2.txt index 6ac16a3306..7d89108011 100644 --- a/tests/auto/corelib/io/qresourceengine/testqrc/currentdir2.txt +++ b/tests/auto/corelib/io/qresourceengine/testqrc/currentdir2.txt @@ -1 +1 @@ -"This is also the current dir" +"This is also the current dir" diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/otherdir/otherdir.txt b/tests/auto/corelib/io/qresourceengine/testqrc/otherdir/otherdir.txt index b0e4a124ee..e1b430f33b 100644 --- a/tests/auto/corelib/io/qresourceengine/testqrc/otherdir/otherdir.txt +++ b/tests/auto/corelib/io/qresourceengine/testqrc/otherdir/otherdir.txt @@ -1 +1 @@ -"This is the other dir" +"This is the other dir" diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/subdir/subdir.txt b/tests/auto/corelib/io/qresourceengine/testqrc/subdir/subdir.txt index b6115207a2..4506acf413 100644 --- a/tests/auto/corelib/io/qresourceengine/testqrc/subdir/subdir.txt +++ b/tests/auto/corelib/io/qresourceengine/testqrc/subdir/subdir.txt @@ -1 +1 @@ -"This is in the sub directory" +"This is in the sub directory" diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/test/test/test1.txt b/tests/auto/corelib/io/qresourceengine/testqrc/test/test/test1.txt index adc01d1354..8baef1b4ab 100644 --- a/tests/auto/corelib/io/qresourceengine/testqrc/test/test/test1.txt +++ b/tests/auto/corelib/io/qresourceengine/testqrc/test/test/test1.txt @@ -1 +1 @@ -abc +abc diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/test/test/test2.txt b/tests/auto/corelib/io/qresourceengine/testqrc/test/test/test2.txt index 3f48e3cdc3..24c5735c3e 100644 --- a/tests/auto/corelib/io/qresourceengine/testqrc/test/test/test2.txt +++ b/tests/auto/corelib/io/qresourceengine/testqrc/test/test/test2.txt @@ -1 +1 @@ -def +def diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/test/testdir.txt b/tests/auto/corelib/io/qresourceengine/testqrc/test/testdir.txt index 40ee68dccb..b8cb3a8c01 100644 --- a/tests/auto/corelib/io/qresourceengine/testqrc/test/testdir.txt +++ b/tests/auto/corelib/io/qresourceengine/testqrc/test/testdir.txt @@ -1 +1 @@ -"This is in the test directory" +"This is in the test directory" diff --git a/tests/auto/corelib/io/qresourceengine/testqrc/test/testdir2.txt b/tests/auto/corelib/io/qresourceengine/testqrc/test/testdir2.txt index 051430298a..dccfdc9bcf 100644 --- a/tests/auto/corelib/io/qresourceengine/testqrc/test/testdir2.txt +++ b/tests/auto/corelib/io/qresourceengine/testqrc/test/testdir2.txt @@ -1 +1 @@ -"This is another file in this directory" +"This is another file in this directory" diff --git a/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp index ab49dea6d8..2678bb0db3 100644 --- a/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp +++ b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2018 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -104,7 +105,7 @@ void tst_QResourceEngine::cleanupTestCase() void tst_QResourceEngine::checkStructure_data() { QTest::addColumn("pathName"); - QTest::addColumn("contents"); + QTest::addColumn("contents"); QTest::addColumn("containedFiles"); QTest::addColumn("containedDirs"); QTest::addColumn("locale"); @@ -134,7 +135,7 @@ void tst_QResourceEngine::checkStructure_data() QTest::newRow("root dir") << QString(":/") - << QString() + << QByteArray() << (QStringList() #if defined(BUILTIN_TESTDATA) << "parentdir.txt" @@ -146,7 +147,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(0); QTest::newRow("secondary root") << QString(":/secondary_root/") - << QString() + << QByteArray() << QStringList() << (QStringList() << QLatin1String("runtime_resource")) << QLocale::c() @@ -158,56 +159,56 @@ void tst_QResourceEngine::checkStructure_data() const QString root = roots.at(i); QTest::newRow(QString(root + "prefix dir").toLatin1().constData()) << QString(root + "test/abc/123/+++") - << QString() + << QByteArray() << (QStringList() << QLatin1String("currentdir.txt") << QLatin1String("currentdir2.txt") << QLatin1String("parentdir.txt")) << (QStringList() << QLatin1String("subdir")) << QLocale::c() << qlonglong(0); QTest::newRow(QString(root + "parent to prefix").toLatin1().constData()) << QString(root + "test/abc/123") - << QString() + << QByteArray() << QStringList() << (QStringList() << QLatin1String("+++")) << QLocale::c() << qlonglong(0); QTest::newRow(QString(root + "two parents prefix").toLatin1().constData()) << QString(root + "test/abc") - << QString() + << QByteArray() << QStringList() << QStringList(QLatin1String("123")) << QLocale::c() << qlonglong(0); QTest::newRow(QString(root + "test dir ").toLatin1().constData()) << QString(root + "test") - << QString() + << QByteArray() << (QStringList() << QLatin1String("testdir.txt")) << (QStringList() << QLatin1String("abc") << QLatin1String("test")) << QLocale::c() << qlonglong(0); QTest::newRow(QString(root + "prefix no slashes").toLatin1().constData()) << QString(root + "withoutslashes") - << QString() + << QByteArray() << QStringList("blahblah.txt") << QStringList() << QLocale::c() << qlonglong(0); QTest::newRow(QString(root + "other dir").toLatin1().constData()) << QString(root + "otherdir") - << QString() + << QByteArray() << QStringList(QLatin1String("otherdir.txt")) << QStringList() << QLocale::c() << qlonglong(0); QTest::newRow(QString(root + "alias dir").toLatin1().constData()) << QString(root + "aliasdir") - << QString() + << QByteArray() << QStringList(QLatin1String("aliasdir.txt")) << QStringList() << QLocale::c() << qlonglong(0); QTest::newRow(QString(root + "second test dir").toLatin1().constData()) << QString(root + "test/test") - << QString() + << QByteArray() << (QStringList() << QLatin1String("test1.txt") << QLatin1String("test2.txt")) << QStringList() << QLocale::c() @@ -215,7 +216,7 @@ void tst_QResourceEngine::checkStructure_data() info = QFileInfo(QFINDTESTDATA("testqrc/test/test/test1.txt")); QTest::newRow(QString(root + "test1 text").toLatin1().constData()) << QString(root + "test/test/test1.txt") - << QString("abc") + << QByteArray("abc\n") << QStringList() << QStringList() << QLocale::c() @@ -223,7 +224,7 @@ void tst_QResourceEngine::checkStructure_data() info = QFileInfo(QFINDTESTDATA("testqrc/blahblah.txt")); QTest::newRow(QString(root + "text no slashes").toLatin1().constData()) << QString(root + "withoutslashes/blahblah.txt") - << QString("qwerty") + << QByteArray("qwerty\n") << QStringList() << QStringList() << QLocale::c() @@ -232,7 +233,7 @@ void tst_QResourceEngine::checkStructure_data() info = QFileInfo(QFINDTESTDATA("testqrc/test/test/test2.txt")); QTest::newRow(QString(root + "test1 text").toLatin1().constData()) << QString(root + "test/test/test2.txt") - << QString("def") + << QByteArray("def\n") << QStringList() << QStringList() << QLocale::c() @@ -240,7 +241,7 @@ void tst_QResourceEngine::checkStructure_data() info = QFileInfo(QFINDTESTDATA("testqrc/currentdir.txt")); QTest::newRow(QString(root + "currentdir text").toLatin1().constData()) << QString(root + "test/abc/123/+++/currentdir.txt") - << QString("\"This is the current dir\" ") + << QByteArray("\"This is the current dir\"\n") << QStringList() << QStringList() << QLocale::c() @@ -248,7 +249,7 @@ void tst_QResourceEngine::checkStructure_data() info = QFileInfo(QFINDTESTDATA("testqrc/currentdir2.txt")); QTest::newRow(QString(root + "currentdir text2").toLatin1().constData()) << QString(root + "test/abc/123/+++/currentdir2.txt") - << QString("\"This is also the current dir\" ") + << QByteArray("\"This is also the current dir\"\n") << QStringList() << QStringList() << QLocale::c() @@ -256,7 +257,7 @@ void tst_QResourceEngine::checkStructure_data() info = QFileInfo(QFINDTESTDATA("parentdir.txt")); QTest::newRow(QString(root + "parentdir text").toLatin1().constData()) << QString(root + "test/abc/123/+++/parentdir.txt") - << QString("abcdefgihklmnopqrstuvwxyz ") + << QByteArray("abcdefgihklmnopqrstuvwxyz \n") << QStringList() << QStringList() << QLocale::c() @@ -264,7 +265,7 @@ void tst_QResourceEngine::checkStructure_data() info = QFileInfo(QFINDTESTDATA("testqrc/subdir/subdir.txt")); QTest::newRow(QString(root + "subdir text").toLatin1().constData()) << QString(root + "test/abc/123/+++/subdir/subdir.txt") - << QString("\"This is in the sub directory\" ") + << QByteArray("\"This is in the sub directory\"\n") << QStringList() << QStringList() << QLocale::c() @@ -272,7 +273,7 @@ void tst_QResourceEngine::checkStructure_data() info = QFileInfo(QFINDTESTDATA("testqrc/test/testdir.txt")); QTest::newRow(QString(root + "testdir text").toLatin1().constData()) << QString(root + "test/testdir.txt") - << QString("\"This is in the test directory\" ") + << QByteArray("\"This is in the test directory\"\n") << QStringList() << QStringList() << QLocale::c() @@ -280,7 +281,7 @@ void tst_QResourceEngine::checkStructure_data() info = QFileInfo(QFINDTESTDATA("testqrc/otherdir/otherdir.txt")); QTest::newRow(QString(root + "otherdir text").toLatin1().constData()) << QString(root + "otherdir/otherdir.txt") - << QString("\"This is the other dir\" ") + << QByteArray("\"This is the other dir\"\n") << QStringList() << QStringList() << QLocale::c() @@ -288,7 +289,7 @@ void tst_QResourceEngine::checkStructure_data() info = QFileInfo(QFINDTESTDATA("testqrc/test/testdir2.txt")); QTest::newRow(QString(root + "alias text").toLatin1().constData()) << QString(root + "aliasdir/aliasdir.txt") - << QString("\"This is another file in this directory\" ") + << QByteArray("\"This is another file in this directory\"\n") << QStringList() << QStringList() << QLocale::c() @@ -296,7 +297,7 @@ void tst_QResourceEngine::checkStructure_data() info = QFileInfo(QFINDTESTDATA("testqrc/aliasdir/aliasdir.txt")); QTest::newRow(QString(root + "korean text").toLatin1().constData()) << QString(root + "aliasdir/aliasdir.txt") - << QString("\"This is a korean text file\" ") + << QByteArray("\"This is a korean text file\"\n") << QStringList() << QStringList() << QLocale("ko") @@ -304,7 +305,7 @@ void tst_QResourceEngine::checkStructure_data() info = QFileInfo(QFINDTESTDATA("testqrc/aliasdir/aliasdir.txt")); QTest::newRow(QString(root + "korean text 2").toLatin1().constData()) << QString(root + "aliasdir/aliasdir.txt") - << QString("\"This is a korean text file\" ") + << QByteArray("\"This is a korean text file\"\n") << QStringList() << QStringList() << QLocale("ko_KR") @@ -312,7 +313,7 @@ void tst_QResourceEngine::checkStructure_data() info = QFileInfo(QFINDTESTDATA("testqrc/test/german.txt")); QTest::newRow(QString(root + "german text").toLatin1().constData()) << QString(root + "aliasdir/aliasdir.txt") - << QString("Deutsch") + << QByteArray("Deutsch\n") << QStringList() << QStringList() << QLocale("de") @@ -320,7 +321,7 @@ void tst_QResourceEngine::checkStructure_data() info = QFileInfo(QFINDTESTDATA("testqrc/test/german.txt")); QTest::newRow(QString(root + "german text 2").toLatin1().constData()) << QString(root + "aliasdir/aliasdir.txt") - << QString("Deutsch") + << QByteArray("Deutsch\n") << QStringList() << QStringList() << QLocale("de_DE") @@ -330,7 +331,7 @@ void tst_QResourceEngine::checkStructure_data() file.open(QFile::ReadOnly); info = QFileInfo(QFINDTESTDATA("testqrc/aliasdir/compressme.txt")); QTest::newRow(QString(root + "compressed text").toLatin1().constData()) << QString(root + "aliasdir/aliasdir.txt") - << QString(file.readAll()) + << file.readAll() << QStringList() << QStringList() << QLocale("de_CH") @@ -341,7 +342,7 @@ void tst_QResourceEngine::checkStructure_data() void tst_QResourceEngine::checkStructure() { QFETCH(QString, pathName); - QFETCH(QString, contents); + QFETCH(QByteArray, contents); QFETCH(QStringList, containedFiles); QFETCH(QStringList, containedDirs); QFETCH(QLocale, locale); @@ -401,8 +402,8 @@ void tst_QResourceEngine::checkStructure() QFile file(pathName); QVERIFY(file.open(QFile::ReadOnly)); - QByteArray ba = file.readAll(); - QVERIFY(QString(ba).startsWith(contents)); + // check contents + QCOMPARE(file.readAll(), contents); } QLocale::setDefault(QLocale::system()); } From 460866ee47c2a2ee98d7874a88bc3cc4b17b6f6a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 1 Nov 2018 16:09:05 -0700 Subject: [PATCH 0339/1650] tst_QResourceEngine: use QTest::addRow instead of QString concatenation Change-Id: I343f2beed55440a7ac0bfffd156322c95aebb847 Reviewed-by: Oswald Buddenhagen Reviewed-by: hjk Reviewed-by: Kai Koehne --- .../qresourceengine/tst_qresourceengine.cpp | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp index 2678bb0db3..cf1d249f54 100644 --- a/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp +++ b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp @@ -158,56 +158,56 @@ void tst_QResourceEngine::checkStructure_data() for(int i = 0; i < roots.size(); ++i) { const QString root = roots.at(i); - QTest::newRow(QString(root + "prefix dir").toLatin1().constData()) << QString(root + "test/abc/123/+++") + QTest::addRow("%s prefix dir", qPrintable(root)) << QString(root + "test/abc/123/+++") << QByteArray() << (QStringList() << QLatin1String("currentdir.txt") << QLatin1String("currentdir2.txt") << QLatin1String("parentdir.txt")) << (QStringList() << QLatin1String("subdir")) << QLocale::c() << qlonglong(0); - QTest::newRow(QString(root + "parent to prefix").toLatin1().constData()) << QString(root + "test/abc/123") + QTest::addRow("%s parent to prefix", qPrintable(root)) << QString(root + "test/abc/123") << QByteArray() << QStringList() << (QStringList() << QLatin1String("+++")) << QLocale::c() << qlonglong(0); - QTest::newRow(QString(root + "two parents prefix").toLatin1().constData()) << QString(root + "test/abc") + QTest::addRow("%s two parents prefix", qPrintable(root)) << QString(root + "test/abc") << QByteArray() << QStringList() << QStringList(QLatin1String("123")) << QLocale::c() << qlonglong(0); - QTest::newRow(QString(root + "test dir ").toLatin1().constData()) << QString(root + "test") + QTest::addRow("%s test dir ", qPrintable(root)) << QString(root + "test") << QByteArray() << (QStringList() << QLatin1String("testdir.txt")) << (QStringList() << QLatin1String("abc") << QLatin1String("test")) << QLocale::c() << qlonglong(0); - QTest::newRow(QString(root + "prefix no slashes").toLatin1().constData()) << QString(root + "withoutslashes") + QTest::addRow("%s prefix no slashes", qPrintable(root)) << QString(root + "withoutslashes") << QByteArray() << QStringList("blahblah.txt") << QStringList() << QLocale::c() << qlonglong(0); - QTest::newRow(QString(root + "other dir").toLatin1().constData()) << QString(root + "otherdir") + QTest::addRow("%s other dir", qPrintable(root)) << QString(root + "otherdir") << QByteArray() << QStringList(QLatin1String("otherdir.txt")) << QStringList() << QLocale::c() << qlonglong(0); - QTest::newRow(QString(root + "alias dir").toLatin1().constData()) << QString(root + "aliasdir") + QTest::addRow("%s alias dir", qPrintable(root)) << QString(root + "aliasdir") << QByteArray() << QStringList(QLatin1String("aliasdir.txt")) << QStringList() << QLocale::c() << qlonglong(0); - QTest::newRow(QString(root + "second test dir").toLatin1().constData()) << QString(root + "test/test") + QTest::addRow("%s second test dir", qPrintable(root)) << QString(root + "test/test") << QByteArray() << (QStringList() << QLatin1String("test1.txt") << QLatin1String("test2.txt")) << QStringList() @@ -215,7 +215,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(0); info = QFileInfo(QFINDTESTDATA("testqrc/test/test/test1.txt")); - QTest::newRow(QString(root + "test1 text").toLatin1().constData()) << QString(root + "test/test/test1.txt") + QTest::addRow("%s test1 text", qPrintable(root)) << QString(root + "test/test/test1.txt") << QByteArray("abc\n") << QStringList() << QStringList() @@ -223,7 +223,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/blahblah.txt")); - QTest::newRow(QString(root + "text no slashes").toLatin1().constData()) << QString(root + "withoutslashes/blahblah.txt") + QTest::addRow("%s text no slashes", qPrintable(root)) << QString(root + "withoutslashes/blahblah.txt") << QByteArray("qwerty\n") << QStringList() << QStringList() @@ -232,7 +232,7 @@ void tst_QResourceEngine::checkStructure_data() info = QFileInfo(QFINDTESTDATA("testqrc/test/test/test2.txt")); - QTest::newRow(QString(root + "test1 text").toLatin1().constData()) << QString(root + "test/test/test2.txt") + QTest::addRow("%s test1 text", qPrintable(root)) << QString(root + "test/test/test2.txt") << QByteArray("def\n") << QStringList() << QStringList() @@ -240,7 +240,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/currentdir.txt")); - QTest::newRow(QString(root + "currentdir text").toLatin1().constData()) << QString(root + "test/abc/123/+++/currentdir.txt") + QTest::addRow("%s currentdir text", qPrintable(root)) << QString(root + "test/abc/123/+++/currentdir.txt") << QByteArray("\"This is the current dir\"\n") << QStringList() << QStringList() @@ -248,7 +248,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/currentdir2.txt")); - QTest::newRow(QString(root + "currentdir text2").toLatin1().constData()) << QString(root + "test/abc/123/+++/currentdir2.txt") + QTest::addRow("%s currentdir text2", qPrintable(root)) << QString(root + "test/abc/123/+++/currentdir2.txt") << QByteArray("\"This is also the current dir\"\n") << QStringList() << QStringList() @@ -256,7 +256,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("parentdir.txt")); - QTest::newRow(QString(root + "parentdir text").toLatin1().constData()) << QString(root + "test/abc/123/+++/parentdir.txt") + QTest::addRow("%s parentdir text", qPrintable(root)) << QString(root + "test/abc/123/+++/parentdir.txt") << QByteArray("abcdefgihklmnopqrstuvwxyz \n") << QStringList() << QStringList() @@ -264,7 +264,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/subdir/subdir.txt")); - QTest::newRow(QString(root + "subdir text").toLatin1().constData()) << QString(root + "test/abc/123/+++/subdir/subdir.txt") + QTest::addRow("%s subdir text", qPrintable(root)) << QString(root + "test/abc/123/+++/subdir/subdir.txt") << QByteArray("\"This is in the sub directory\"\n") << QStringList() << QStringList() @@ -272,7 +272,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/test/testdir.txt")); - QTest::newRow(QString(root + "testdir text").toLatin1().constData()) << QString(root + "test/testdir.txt") + QTest::addRow("%s testdir text", qPrintable(root)) << QString(root + "test/testdir.txt") << QByteArray("\"This is in the test directory\"\n") << QStringList() << QStringList() @@ -280,7 +280,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/otherdir/otherdir.txt")); - QTest::newRow(QString(root + "otherdir text").toLatin1().constData()) << QString(root + "otherdir/otherdir.txt") + QTest::addRow("%s otherdir text", qPrintable(root)) << QString(root + "otherdir/otherdir.txt") << QByteArray("\"This is the other dir\"\n") << QStringList() << QStringList() @@ -288,7 +288,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/test/testdir2.txt")); - QTest::newRow(QString(root + "alias text").toLatin1().constData()) << QString(root + "aliasdir/aliasdir.txt") + QTest::addRow("%s alias text", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") << QByteArray("\"This is another file in this directory\"\n") << QStringList() << QStringList() @@ -296,7 +296,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/aliasdir/aliasdir.txt")); - QTest::newRow(QString(root + "korean text").toLatin1().constData()) << QString(root + "aliasdir/aliasdir.txt") + QTest::addRow("%s korean text", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") << QByteArray("\"This is a korean text file\"\n") << QStringList() << QStringList() @@ -304,7 +304,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/aliasdir/aliasdir.txt")); - QTest::newRow(QString(root + "korean text 2").toLatin1().constData()) << QString(root + "aliasdir/aliasdir.txt") + QTest::addRow("%s korean text 2", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") << QByteArray("\"This is a korean text file\"\n") << QStringList() << QStringList() @@ -312,7 +312,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/test/german.txt")); - QTest::newRow(QString(root + "german text").toLatin1().constData()) << QString(root + "aliasdir/aliasdir.txt") + QTest::addRow("%s german text", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") << QByteArray("Deutsch\n") << QStringList() << QStringList() @@ -320,7 +320,7 @@ void tst_QResourceEngine::checkStructure_data() << qlonglong(info.size()); info = QFileInfo(QFINDTESTDATA("testqrc/test/german.txt")); - QTest::newRow(QString(root + "german text 2").toLatin1().constData()) << QString(root + "aliasdir/aliasdir.txt") + QTest::addRow("%s german text 2", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") << QByteArray("Deutsch\n") << QStringList() << QStringList() @@ -330,7 +330,7 @@ void tst_QResourceEngine::checkStructure_data() QFile file(QFINDTESTDATA("testqrc/aliasdir/compressme.txt")); file.open(QFile::ReadOnly); info = QFileInfo(QFINDTESTDATA("testqrc/aliasdir/compressme.txt")); - QTest::newRow(QString(root + "compressed text").toLatin1().constData()) << QString(root + "aliasdir/aliasdir.txt") + QTest::addRow("%s compressed text", qPrintable(root)) << QString(root + "aliasdir/aliasdir.txt") << file.readAll() << QStringList() << QStringList() From 6a792d6f0b5a15ce09b7883bbbb06b2724596e40 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 2 Nov 2018 13:54:26 -0700 Subject: [PATCH 0340/1650] QResourceFileEngine: fix map() for compressed files We were returning a pointer to the compressed data and comparing to the compressed data size. Change-Id: I343f2beed55440a7ac0bfffd1563232d557c9427 Reviewed-by: Oswald Buddenhagen Reviewed-by: hjk --- src/corelib/io/qresource.cpp | 17 ++++++++++++++--- .../io/qresourceengine/tst_qresourceengine.cpp | 6 ++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index b85bca8590..8c1bfc8c48 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -1503,14 +1503,25 @@ uchar *QResourceFileEnginePrivate::map(qint64 offset, qint64 size, QFile::Memory { Q_Q(QResourceFileEngine); Q_UNUSED(flags); + + qint64 max = resource.size(); + if (resource.isCompressed()) { + uncompress(); + max = uncompressed.size(); + } + qint64 end; if (offset < 0 || size <= 0 || !resource.isValid() || - add_overflow(offset, size, &end) || end > resource.size()) { + add_overflow(offset, size, &end) || end > max) { q->setError(QFile::UnspecifiedError, QString()); return 0; } - uchar *address = const_cast(resource.data()); - return (address + offset); + + const uchar *address = resource.data(); + if (resource.isCompressed()) + address = reinterpret_cast(uncompressed.constData()); + + return const_cast(address) + offset; } bool QResourceFileEnginePrivate::unmap(uchar *ptr) diff --git a/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp index cf1d249f54..6461e6274f 100644 --- a/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp +++ b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp @@ -404,6 +404,12 @@ void tst_QResourceEngine::checkStructure() // check contents QCOMPARE(file.readAll(), contents); + + // check memory map too + uchar *ptr = file.map(0, file.size(), QFile::MapPrivateOption); + QVERIFY2(ptr, qPrintable(file.errorString())); + QByteArray ba = QByteArray::fromRawData(reinterpret_cast(ptr), file.size()); + QCOMPARE(ba, contents); } QLocale::setDefault(QLocale::system()); } From 6b088b7a1da37511a8abb1503e4f2f95632dbdac Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 1 Nov 2018 16:35:29 -0700 Subject: [PATCH 0341/1650] QResourceFileEngine: fix use of mapped files after close() QFile::map() is documented to continue working after the QFile is closed, so this should work for the resource file engine too. Change-Id: I343f2beed55440a7ac0bfffd1563243a3966441f Reviewed-by: Oswald Buddenhagen Reviewed-by: Lars Knoll --- src/corelib/io/qresource.cpp | 1 - tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index 8c1bfc8c48..564a3e5f51 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -1288,7 +1288,6 @@ bool QResourceFileEngine::close() { Q_D(QResourceFileEngine); d->offset = 0; - d->uncompressed.clear(); return true; } diff --git a/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp index 6461e6274f..0b50c391b8 100644 --- a/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp +++ b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp @@ -410,6 +410,10 @@ void tst_QResourceEngine::checkStructure() QVERIFY2(ptr, qPrintable(file.errorString())); QByteArray ba = QByteArray::fromRawData(reinterpret_cast(ptr), file.size()); QCOMPARE(ba, contents); + + // check that it is still valid after closing the file + file.close(); + QCOMPARE(ba, contents); } QLocale::setDefault(QLocale::system()); } From 85b4aaaa99556fa248a7d688d2fe9d99d28234b0 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 2 Nov 2018 10:49:29 +0100 Subject: [PATCH 0342/1650] uic: Generate code for container page tooltips using the Qt configure system Previously, the generation of this code was #ifdefed in uic itself. However, the #ifdef should be in the generated code (anticipating the cmake port where host and target builds might differ). Task-number: PYSIDE-797 Change-Id: I46255f852f5f6a3d95d3a20456b6f00f2067a3fe Reviewed-by: Jarek Kobus --- src/tools/uic/cpp/cppwriteinitialization.cpp | 30 ++++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/tools/uic/cpp/cppwriteinitialization.cpp b/src/tools/uic/cpp/cppwriteinitialization.cpp index a75aa0abd7..28e97f3bba 100644 --- a/src/tools/uic/cpp/cppwriteinitialization.cpp +++ b/src/tools/uic/cpp/cppwriteinitialization.cpp @@ -726,12 +726,14 @@ void WriteInitialization::acceptWidget(DomWidget *node) autoTrOutput(plabelString, pageDefaultString) << m_indent << parentWidget << "->setItemText(" << parentWidget << "->indexOf(" << varName << "), " << autoTrCall(plabelString, pageDefaultString) << ");\n"; -#ifndef QT_NO_TOOLTIP if (DomProperty *ptoolTip = attributes.value(QLatin1String("toolTip"))) { - autoTrOutput(ptoolTip->elementString()) << m_indent << parentWidget << "->setItemToolTip(" - << parentWidget << "->indexOf(" << varName << "), " << autoTrCall(ptoolTip->elementString()) << ");\n"; + autoTrOutput(ptoolTip->elementString()) + << language::openQtConfig(toolTipConfigKey()) + << m_indent << parentWidget << "->setItemToolTip(" << parentWidget + << "->indexOf(" << varName << "), " + << autoTrCall(ptoolTip->elementString()) << ");\n" + << language::closeQtConfig(toolTipConfigKey()); } -#endif // QT_NO_TOOLTIP } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QTabWidget"))) { QString icon; if (const DomProperty *picon = attributes.value(QLatin1String("icon"))) { @@ -747,18 +749,22 @@ void WriteInitialization::acceptWidget(DomWidget *node) autoTrOutput(ptitleString, pageDefaultString) << m_indent << parentWidget << "->setTabText(" << parentWidget << "->indexOf(" << varName << "), " << autoTrCall(ptitleString, pageDefaultString) << ");\n"; -#ifndef QT_NO_TOOLTIP if (const DomProperty *ptoolTip = attributes.value(QLatin1String("toolTip"))) { - autoTrOutput(ptoolTip->elementString()) << m_indent << parentWidget << "->setTabToolTip(" - << parentWidget << "->indexOf(" << varName << "), " << autoTrCall(ptoolTip->elementString()) << ");\n"; + autoTrOutput(ptoolTip->elementString()) + << language::openQtConfig(toolTipConfigKey()) + << m_indent << parentWidget << "->setTabToolTip(" << parentWidget + << "->indexOf(" << varName << "), " + << autoTrCall(ptoolTip->elementString()) << ");\n" + << language::closeQtConfig(toolTipConfigKey()); } -#endif // QT_NO_TOOLTIP -#ifndef QT_NO_WHATSTHIS if (const DomProperty *pwhatsThis = attributes.value(QLatin1String("whatsThis"))) { - autoTrOutput(pwhatsThis->elementString()) << m_indent << parentWidget << "->setTabWhatsThis(" - << parentWidget << "->indexOf(" << varName << "), " << autoTrCall(pwhatsThis->elementString()) << ");\n"; + autoTrOutput(pwhatsThis->elementString()) + << language::openQtConfig(whatsThisConfigKey()) + << m_indent << parentWidget << "->setTabWhatsThis(" << parentWidget + << "->indexOf(" << varName << "), " + << autoTrCall(pwhatsThis->elementString()) << ");\n" + << language::closeQtConfig(whatsThisConfigKey()); } -#endif // QT_NO_WHATSTHIS } // From c0c4be672bd652d29a5c8f52e31ad76a1361e320 Mon Sep 17 00:00:00 2001 From: Luca Beldi Date: Tue, 13 Nov 2018 08:54:37 +0000 Subject: [PATCH 0343/1650] Fix constness of QPaintDevice arguments QFont, QFontMetrics, QFontMetricsF and QTextLayout constructors use only const methods of QPaintDevice so there is no reason for them to require a non-const pointer argument Fixes: QTBUG-65967 Change-Id: Ibfcdef2a25f0cd4284dad76135fc4c9bf5667d7a Reviewed-by: Samuel Gaist Reviewed-by: Christian Ehrlicher Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfont.cpp | 15 +++++++++++++-- src/gui/text/qfont.h | 7 +++++-- src/gui/text/qfontmetrics.cpp | 31 ++++++++++++++++++++++++++++++- src/gui/text/qfontmetrics.h | 30 +++++++++++++++++++++++++++--- src/gui/text/qtextlayout.cpp | 19 +++++++++++++++---- src/gui/text/qtextlayout.h | 14 +++++++++++++- 6 files changed, 103 insertions(+), 13 deletions(-) diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 258a9ba675..27d804a3b4 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -562,14 +562,25 @@ QFontEngineData::~QFontEngineData() \since 5.2 */ +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) /*! + \obsolete Constructs a font from \a font for use on the paint device \a pd. */ QFont::QFont(const QFont &font, QPaintDevice *pd) + : QFont(font, static_cast(pd)) +{} +#endif + +/*! + \since 5.13 + Constructs a font from \a font for use on the paint device \a pd. +*/ +QFont::QFont(const QFont &font, const QPaintDevice *pd) : resolve_mask(font.resolve_mask) { - Q_ASSERT(pd != 0); - int dpi = pd->logicalDpiY(); + Q_ASSERT(pd); + const int dpi = pd->logicalDpiY(); const int screen = 0; if (font.d->dpi != dpi || font.d->screen != screen ) { d = new QFontPrivate(*font.d); diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h index 1fe450e002..e86f06353a 100644 --- a/src/gui/text/qfont.h +++ b/src/gui/text/qfont.h @@ -170,8 +170,11 @@ public: QFont(); QFont(const QString &family, int pointSize = -1, int weight = -1, bool italic = false); - QFont(const QFont &, QPaintDevice *pd); - QFont(const QFont &); +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + QFont(const QFont &font, QPaintDevice *pd); +#endif + QFont(const QFont &font, const QPaintDevice *pd); + QFont(const QFont &font); ~QFont(); void swap(QFont &other) diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index 407559ad51..c8dc8d676e 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -156,6 +156,8 @@ QFontMetrics::QFontMetrics(const QFont &font) } /*! + \since 5.13 + \fn QFontMetrics::QFontMetrics(const QFont &font, const QPaintDevice *paintdevice) Constructs a font metrics object for \a font and \a paintdevice. The font metrics will be compatible with the paintdevice passed. @@ -168,9 +170,21 @@ QFontMetrics::QFontMetrics(const QFont &font) passed in the constructor at the time it is created, and is not updated if the font's attributes are changed later. */ + +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +/*! + \fn QFontMetrics::QFontMetrics(const QFont &font, QPaintDevice *paintdevice) + \obsolete + Identical to QFontMetrics::QFontMetrics(const QFont &font, const QPaintDevice *paintdevice) +*/ + + QFontMetrics::QFontMetrics(const QFont &font, QPaintDevice *paintdevice) +#else +QFontMetrics::QFontMetrics(const QFont &font, const QPaintDevice *paintdevice) +#endif { - int dpi = paintdevice ? paintdevice->logicalDpiY() : qt_defaultDpi(); + const int dpi = paintdevice ? paintdevice->logicalDpiY() : qt_defaultDpi(); const int screen = 0; if (font.d->dpi != dpi || font.d->screen != screen ) { d = new QFontPrivate(*font.d); @@ -1127,6 +1141,8 @@ QFontMetricsF::QFontMetricsF(const QFont &font) } /*! + \fn QFontMetricsF::QFontMetricsF(const QFont &font, const QPaintDevice *paintdevice) + \since 5.13 Constructs a font metrics object for \a font and \a paintdevice. The font metrics will be compatible with the paintdevice passed. @@ -1139,7 +1155,20 @@ QFontMetricsF::QFontMetricsF(const QFont &font) passed in the constructor at the time it is created, and is not updated if the font's attributes are changed later. */ + + +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +/*! + \fn QFontMetricsF::QFontMetricsF(const QFont &font, QPaintDevice *paintdevice) + \obsolete + Identical to QFontMetricsF::QFontMetricsF(const QFont &font, const QPaintDevice *paintdevice) +*/ + + QFontMetricsF::QFontMetricsF(const QFont &font, QPaintDevice *paintdevice) +#else +QFontMetricsF::QFontMetricsF(const QFont &font, const QPaintDevice *paintdevice) +#endif { int dpi = paintdevice ? paintdevice->logicalDpiY() : qt_defaultDpi(); const int screen = 0; diff --git a/src/gui/text/qfontmetrics.h b/src/gui/text/qfontmetrics.h index b6167a1d47..ba7f695380 100644 --- a/src/gui/text/qfontmetrics.h +++ b/src/gui/text/qfontmetrics.h @@ -59,7 +59,19 @@ class Q_GUI_EXPORT QFontMetrics { public: explicit QFontMetrics(const QFont &); - QFontMetrics(const QFont &, QPaintDevice *pd); +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + QFontMetrics(const QFont &font, QPaintDevice *pd); +#ifndef Q_QDOC + // the template is necessary to make QFontMetrics(font,nullptr) and QFontMetrics(font,NULL) + // not ambiguous. Implementation detail that should not be documented. + template +#endif + QFontMetrics(const QFont &font, const QPaintDevice *pd) + : QFontMetrics(font, const_cast(pd)) + {} +#else + QFontMetrics(const QFont &font, const QPaintDevice *pd); +#endif QFontMetrics(const QFontMetrics &); ~QFontMetrics(); @@ -137,8 +149,20 @@ Q_DECLARE_SHARED(QFontMetrics) class Q_GUI_EXPORT QFontMetricsF { public: - explicit QFontMetricsF(const QFont &); - QFontMetricsF(const QFont &, QPaintDevice *pd); + explicit QFontMetricsF(const QFont &font); +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + QFontMetricsF(const QFont &font, QPaintDevice *pd); +#ifndef Q_QDOC + // the template is necessary to make QFontMetrics(font,nullptr) and QFontMetrics(font,NULL) + // not ambiguous. Implementation detail that should not be documented. + template +#endif + QFontMetricsF(const QFont &font, const QPaintDevice *pd) + : QFontMetricsF(font, const_cast(pd)) + {} +#else + QFontMetricsF(const QFont &font, const QPaintDevice *pd); +#endif QFontMetricsF(const QFontMetrics &); QFontMetricsF(const QFontMetricsF &); ~QFontMetricsF(); diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index ca6866d836..ec49406548 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -344,6 +344,8 @@ QTextLayout::QTextLayout(const QString& text) } /*! + \since 5.13 + \fn QTextLayout::QTextLayout(const QString &text, const QFont &font, const QPaintDevice *paintdevice) Constructs a text layout to lay out the given \a text with the specified \a font. @@ -351,11 +353,20 @@ QTextLayout::QTextLayout(const QString& text) the paint device, \a paintdevice. If \a paintdevice is 0 the calculations will be done in screen metrics. */ -QTextLayout::QTextLayout(const QString& text, const QFont &font, QPaintDevice *paintdevice) + +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +/*! + \fn QTextLayout::QTextLayout(const QString &text, const QFont &font, QPaintDevice *paintdevice) + \obsolete + Identical to QTextLayout::QTextLayout(const QString &text, const QFont &font, const QPaintDevice *paintdevice) +*/ + +QTextLayout::QTextLayout(const QString &text, const QFont &font, QPaintDevice *paintdevice) +#else +QTextLayout::QTextLayout(const QString &text, const QFont &font, const QPaintDevice *paintdevice) +#endif { - QFont f(font); - if (paintdevice) - f = QFont(font, paintdevice); + const QFont f(paintdevice ? QFont(font, paintdevice) : font); d = new QTextEngine((text.isNull() ? (const QString&)QString::fromLatin1("") : text), f); } diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h index 67bc75a6b8..a29791534e 100644 --- a/src/gui/text/qtextlayout.h +++ b/src/gui/text/qtextlayout.h @@ -107,7 +107,19 @@ public: // does itemization QTextLayout(); QTextLayout(const QString& text); - QTextLayout(const QString& text, const QFont &font, QPaintDevice *paintdevice = nullptr); +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + QTextLayout(const QString &text, const QFont &font, QPaintDevice *paintdevice = nullptr); +#ifndef Q_QDOC + // the template is necessary to make QTextLayout(font,text,nullptr) and QTextLayout(font,text,NULL) + // not ambiguous. Implementation detail that should not be documented. + template +#endif + QTextLayout(const QString &text, const QFont &font, const QPaintDevice *paintdevice) + : QTextLayout(text, font, const_cast(paintdevice)) + {} +#else + QTextLayout(const QString &text, const QFont &font, const QPaintDevice *paintdevice = nullptr); +#endif QTextLayout(const QTextBlock &b); ~QTextLayout(); From 199f9c54484b0dae3bc81f83c880a965192ecb24 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 9 Nov 2018 15:57:42 +0100 Subject: [PATCH 0344/1650] Fix vertical alignment of inline images Inline images can have 4 different alignments. Unfortunately, AlignTop and AlignBottom can only be set once we have laid out the whole line and know the total height of the line, as one could otherwise end up with lines that are too high. To fix this, position the images for these cases in a second loop after we have calculated the length of the line and the maximal image height in that line. Task-number: QTBUG-59310 Change-Id: I1fd4cd39e43a13d1967b9f5c9ce8270a99269cd9 Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qtextdocumentlayout.cpp | 18 +++------ src/gui/text/qtextlayout.cpp | 60 ++++++++++++++++++++++++++-- 2 files changed, 63 insertions(+), 15 deletions(-) diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index a9227f0171..9aeea44dd3 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -3049,18 +3049,12 @@ void QTextDocumentLayout::resizeInlineObject(QTextInlineObject item, int posInDo QSizeF inlineSize = (pos == QTextFrameFormat::InFlow ? intrinsic : QSizeF(0, 0)); item.setWidth(inlineSize.width()); - QFontMetrics m(f.font()); - switch (f.verticalAlignment()) - { - case QTextCharFormat::AlignMiddle: - item.setDescent(inlineSize.height() / 2); - item.setAscent(inlineSize.height() / 2); - break; - case QTextCharFormat::AlignBaseline: - item.setDescent(m.descent()); - item.setAscent(inlineSize.height() - m.descent()); - break; - default: + if (f.verticalAlignment() == QTextCharFormat::AlignMiddle) { + QFontMetrics m(f.font()); + qreal halfX = m.xHeight()/2.; + item.setAscent((inlineSize.height() + halfX) / 2.); + item.setDescent((inlineSize.height() - halfX) / 2.); + } else { item.setDescent(0); item.setAscent(inlineSize.height()); } diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index ca6866d836..be306ed224 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1823,6 +1823,9 @@ void QTextLine::layout_helper(int maxGlyphs) lbh.logClusters = eng->layoutData->logClustersPtr; lbh.previousGlyph = 0; + bool hasInlineObject = false; + QFixed maxInlineObjectHeight = 0; + while (newItem < eng->layoutData->items.size()) { lbh.resetRightBearing(); lbh.softHyphenWidth = 0; @@ -1851,8 +1854,11 @@ void QTextLine::layout_helper(int maxGlyphs) lbh.tmpData.leading = qMax(lbh.tmpData.leading + lbh.tmpData.ascent, current.leading + current.ascent) - qMax(lbh.tmpData.ascent, current.ascent); - lbh.tmpData.ascent = qMax(lbh.tmpData.ascent, current.ascent); - lbh.tmpData.descent = qMax(lbh.tmpData.descent, current.descent); + if (current.analysis.flags != QScriptAnalysis::Object) { + // objects need some special treatment as they can special alignment or be floating + lbh.tmpData.ascent = qMax(lbh.tmpData.ascent, current.ascent); + lbh.tmpData.descent = qMax(lbh.tmpData.descent, current.descent); + } if (current.analysis.flags == QScriptAnalysis::Tab && (alignment & (Qt::AlignLeft | Qt::AlignRight | Qt::AlignCenter | Qt::AlignJustify))) { lbh.whiteSpaceOrObject = true; @@ -1900,9 +1906,18 @@ void QTextLine::layout_helper(int maxGlyphs) if (eng->block.docHandle()) { QTextInlineObject inlineObject(item, eng); - eng->docLayout()->positionInlineObject(inlineObject, eng->block.position() + current.position, inlineObject.format()); + QTextFormat f = inlineObject.format(); + eng->docLayout()->positionInlineObject(inlineObject, eng->block.position() + current.position, f); + QTextCharFormat::VerticalAlignment valign = f.toCharFormat().verticalAlignment(); + if (valign != QTextCharFormat::AlignTop && valign != QTextCharFormat::AlignBottom) { + lbh.tmpData.ascent = qMax(lbh.tmpData.ascent, current.ascent); + lbh.tmpData.descent = qMax(lbh.tmpData.descent, current.descent); + } } + hasInlineObject = true; + maxInlineObjectHeight = qMax(maxInlineObjectHeight, current.ascent + current.descent); + lbh.tmpData.textWidth += current.width; newItem = item + 1; @@ -2038,6 +2053,43 @@ found: line += lbh.tmpData; } + if (hasInlineObject && eng->block.docHandle()) { + // position top/bottom aligned inline objects + if (maxInlineObjectHeight > line.ascent + line.descent) { + // extend line height if required + QFixed toAdd = (maxInlineObjectHeight - line.ascent - line.descent)/2; + line.ascent += toAdd; + line.descent = maxInlineObjectHeight - line.ascent; + } + int startItem = eng->findItem(line.from); + int endItem = eng->findItem(line.from + line.length); + if (endItem < 0) + endItem = eng->layoutData->items.size(); + for (int item = startItem; item < endItem; ++item) { + QScriptItem ¤t = eng->layoutData->items[item]; + if (current.analysis.flags == QScriptAnalysis::Object) { + QTextInlineObject inlineObject(item, eng); + QTextCharFormat::VerticalAlignment align = inlineObject.format().toCharFormat().verticalAlignment(); + QFixed height = current.ascent + current.descent; + switch (align) { + case QTextCharFormat::AlignTop: + current.ascent = line.ascent; + current.descent = height - line.ascent; + break; + case QTextCharFormat::AlignBottom: + current.descent = line.descent; + current.ascent = height - line.descent; + break; + default: + break; + } + Q_ASSERT(line.ascent >= current.ascent); + Q_ASSERT(line.descent >= current.descent); + } + } + } + + LB_DEBUG("line length = %d, ascent=%f, descent=%f, textWidth=%f (spacew=%f)", line.length, line.ascent.toReal(), line.descent.toReal(), line.textWidth.toReal(), lbh.spaceData.width.toReal()); LB_DEBUG(" : '%s'", eng->layoutData->string.mid(line.from, line.length).toUtf8().data()); @@ -2511,6 +2563,8 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR QFixed itemY = y - si.ascent; if (format.verticalAlignment() == QTextCharFormat::AlignTop) { itemY = y - lineBase; + } else if (format.verticalAlignment() == QTextCharFormat::AlignBottom) { + itemY = y + line.descent - si.ascent - si.descent; } QRectF itemRect(iterator.x.toReal(), itemY.toReal(), iterator.itemWidth.toReal(), si.height().toReal()); From 5242540ee4bb507b81b9dc78280db61e7bd56520 Mon Sep 17 00:00:00 2001 From: Vitaly Fanaskov Date: Wed, 7 Nov 2018 16:34:06 +0100 Subject: [PATCH 0345/1650] Fix message about licensing options in the About Qt box Removed versions count. Replaced "different" -> "multiple". Fixes: QTBUG-57697 Change-Id: I924e4706a089fe244f0ea6c3a660a8a4529502a2 Reviewed-by: Paul Wicking Reviewed-by: Lars Knoll --- src/widgets/dialogs/qmessagebox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index d8cd19ef1a..32190151bc 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -1839,7 +1839,7 @@ void QMessageBox::aboutQt(QWidget *parent, const QString &title) "

    Qt provides single-source portability across all major desktop " "operating systems. It is also available for embedded Linux and other " "embedded and mobile operating systems.

    " - "

    Qt is available under three different licensing options designed " + "

    Qt is available under multiple licensing options designed " "to accommodate the needs of our various users.

    " "

    Qt licensed under our commercial license agreement is appropriate " "for development of proprietary/commercial software where you do not " From 6fdf398ab4b32c7a70af08191963c4e4f5a885fe Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Fri, 2 Nov 2018 11:41:32 +0200 Subject: [PATCH 0346/1650] Android: Prepare for the worst, when the NDK will remove all GNU tools In NDKr18 Google removed GCC, most probably the massacre will not end there and they will remove all GNU tools, so we need to start using LLVM ones. This patch still keeps the compatibility with GNU tools if the Qt was built with android-g++ mkspec. Change-Id: Ibe1979577e08ce63604d55fc5bbd5f64b3737675 Reviewed-by: Oswald Buddenhagen Reviewed-by: Eskil Abrahamsen Blomfeldt --- mkspecs/android-clang/qmake.conf | 2 + mkspecs/android-g++/qmake.conf | 1 + .../android/android_deployment_settings.prf | 26 +++-- src/tools/androiddeployqt/main.cpp | 97 +++++++++++-------- 4 files changed, 78 insertions(+), 48 deletions(-) diff --git a/mkspecs/android-clang/qmake.conf b/mkspecs/android-clang/qmake.conf index 1f5e690329..a0a369bb44 100644 --- a/mkspecs/android-clang/qmake.conf +++ b/mkspecs/android-clang/qmake.conf @@ -41,6 +41,8 @@ ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$$A ANDROID_STDCPP_PATH = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++_shared.so +ANDROID_USE_LLVM = true + exists($$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++.so): \ ANDROID_CXX_STL_LIBS = -lc++ else: \ diff --git a/mkspecs/android-g++/qmake.conf b/mkspecs/android-g++/qmake.conf index e72c802405..0cb3558f96 100644 --- a/mkspecs/android-g++/qmake.conf +++ b/mkspecs/android-g++/qmake.conf @@ -16,6 +16,7 @@ QMAKE_LINK = $$QMAKE_CXX ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl/gnu-libstdc++/$$NDK_TOOLCHAIN_VERSION/libs/$$ANDROID_TARGET_ARCH ANDROID_STDCPP_PATH = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libgnustl_shared.so ANDROID_CXX_STL_LIBS = -lgnustl_shared -lgcc +ANDROID_USE_LLVM = false exists($$NDK_ROOT/sysroot/usr/include): \ QMAKE_CFLAGS += --sysroot=$$NDK_ROOT/sysroot \ diff --git a/mkspecs/features/android/android_deployment_settings.prf b/mkspecs/features/android/android_deployment_settings.prf index e6b2431f9a..0db3230ce7 100644 --- a/mkspecs/features/android/android_deployment_settings.prf +++ b/mkspecs/features/android/android_deployment_settings.prf @@ -17,17 +17,22 @@ contains(TEMPLATE, ".*app"):!build_pass:!android-embedded { isEmpty(NDK_ROOT): NDK_ROOT = $$DEFAULT_ANDROID_NDK_ROOT FILE_CONTENT += " \"ndk\": $$emitString($$NDK_ROOT)," - NDK_TOOLCHAIN_PREFIX = $$(ANDROID_NDK_TOOLCHAIN_PREFIX) - isEmpty(NDK_TOOLCHAIN_PREFIX) { - equals(ANDROID_TARGET_ARCH, x86): NDK_TOOLCHAIN_PREFIX = x86 - else: equals(ANDROID_TARGET_ARCH, x86_64): NDK_TOOLCHAIN_PREFIX = x86_64 - else: equals(ANDROID_TARGET_ARCH, mips): NDK_TOOLCHAIN_PREFIX = mipsel-linux-android - else: equals(ANDROID_TARGET_ARCH, mips64): NDK_TOOLCHAIN_PREFIX = mips64el-linux-android - else: equals(ANDROID_TARGET_ARCH, arm64-v8a): NDK_TOOLCHAIN_PREFIX = aarch64-linux-android - else: NDK_TOOLCHAIN_PREFIX = arm-linux-androideabi + equals(ANDROID_USE_LLVM, true) { + FILE_CONTENT += " \"toolchain-prefix\": \"llvm\"," + FILE_CONTENT += " \"tool-prefix\": \"llvm\"," + } else { + NDK_TOOLCHAIN_PREFIX = $$(ANDROID_NDK_TOOLCHAIN_PREFIX) + isEmpty(NDK_TOOLCHAIN_PREFIX) { + equals(ANDROID_TARGET_ARCH, x86): NDK_TOOLCHAIN_PREFIX = x86 + else: equals(ANDROID_TARGET_ARCH, x86_64): NDK_TOOLCHAIN_PREFIX = x86_64 + else: equals(ANDROID_TARGET_ARCH, mips): NDK_TOOLCHAIN_PREFIX = mipsel-linux-android + else: equals(ANDROID_TARGET_ARCH, mips64): NDK_TOOLCHAIN_PREFIX = mips64el-linux-android + else: equals(ANDROID_TARGET_ARCH, arm64-v8a): NDK_TOOLCHAIN_PREFIX = aarch64-linux-android + else: NDK_TOOLCHAIN_PREFIX = arm-linux-androideabi + } + FILE_CONTENT += " \"toolchain-prefix\": $$emitString($$NDK_TOOLCHAIN_PREFIX)," + FILE_CONTENT += " \"tool-prefix\": $$emitString($$NDK_TOOLS_PREFIX)," } - FILE_CONTENT += " \"toolchain-prefix\": $$emitString($$NDK_TOOLCHAIN_PREFIX)," - FILE_CONTENT += " \"tool-prefix\": $$emitString($$NDK_TOOLS_PREFIX)," NDK_TOOLCHAIN_VERSION = $$(ANDROID_NDK_TOOLCHAIN_VERSION) isEmpty(NDK_TOOLCHAIN_VERSION): NDK_TOOLCHAIN_VERSION = $$DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION @@ -63,6 +68,7 @@ contains(TEMPLATE, ".*app"):!build_pass:!android-embedded { QML_ROOT_PATH = $$_PRO_FILE_PWD_ FILE_CONTENT += " \"qml-root-path\": $$emitString($$QML_ROOT_PATH)," FILE_CONTENT += " \"stdcpp-path\": $$emitString($$ANDROID_STDCPP_PATH)," + FILE_CONTENT += " \"useLLVM\": $$ANDROID_USE_LLVM," FILE_CONTENT += " \"application-binary\": $$emitString($$absolute_path($$DESTDIR, $$OUT_PWD)/$$TARGET)" FILE_CONTENT += "}" diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp index 11213872f3..587ae21e4f 100644 --- a/src/tools/androiddeployqt/main.cpp +++ b/src/tools/androiddeployqt/main.cpp @@ -157,6 +157,7 @@ struct Options QString toolchainVersion; QString toolchainPrefix; QString toolPrefix; + bool useLLVM = false; QString ndkHost; // Package information @@ -808,6 +809,11 @@ bool readInputFile(Options *options) options->ndkPath = ndk.toString(); } + { + const QJsonValue value = jsonObject.value(QStringLiteral("useLLVM")); + options->useLLVM = value.toBool(false); + } + { const QJsonValue toolchainPrefix = jsonObject.value(QStringLiteral("toolchain-prefix")); if (toolchainPrefix.isUndefined()) { @@ -827,7 +833,7 @@ bool readInputFile(Options *options) } } - { + if (!options->useLLVM) { const QJsonValue toolchainVersion = jsonObject.value(QStringLiteral("toolchain-version")); if (toolchainVersion.isUndefined()) { fprintf(stderr, "No toolchain version defined in json file.\n"); @@ -863,15 +869,17 @@ bool readInputFile(Options *options) { const QJsonValue stdcppPath = jsonObject.value(QStringLiteral("stdcpp-path")); - if (!stdcppPath.isUndefined()) { - options->stdCppPath = stdcppPath.toString(); - auto name = QFileInfo(options->stdCppPath).baseName(); - if (!name.startsWith(QLatin1String("lib"))) { - fprintf(stderr, "Invalid STD C++ library name.\n"); - return false; - } - options->stdCppName = name.mid(3); + if (stdcppPath.isUndefined()) { + fprintf(stderr, "No stdcpp-path defined in json file.\n"); + return false; } + options->stdCppPath = stdcppPath.toString(); + auto name = QFileInfo(options->stdCppPath).baseName(); + if (!name.startsWith(QLatin1String("lib"))) { + fprintf(stderr, "Invalid STD C++ library name.\n"); + return false; + } + options->stdCppName = name.mid(3); } { @@ -1546,14 +1554,16 @@ QStringList getQtLibsFromElf(const Options &options, const QString &fileName) { QString readElf = options.ndkPath + QLatin1String("/toolchains/") - + options.toolchainPrefix - + QLatin1Char('-') - + options.toolchainVersion - + QLatin1String("/prebuilt/") + + options.toolchainPrefix; + + if (!options.useLLVM) + readElf += QLatin1Char('-') + options.toolchainVersion; + + readElf += QLatin1String("/prebuilt/") + options.ndkHost + QLatin1String("/bin/") - + options.toolPrefix - + QLatin1String("-readelf"); + + options.toolPrefix + + (options.useLLVM ? QLatin1String("-readobj") : QLatin1String("-readelf")); #if defined(Q_OS_WIN32) readElf += QLatin1String(".exe"); #endif @@ -1563,27 +1573,40 @@ QStringList getQtLibsFromElf(const Options &options, const QString &fileName) return QStringList(); } - readElf = QString::fromLatin1("%1 -d -W %2").arg(shellQuote(readElf)).arg(shellQuote(fileName)); + if (options.useLLVM) + readElf = QString::fromLatin1("%1 -needed-libs %2").arg(shellQuote(readElf), shellQuote(fileName)); + else + readElf = QString::fromLatin1("%1 -d -W %2").arg(shellQuote(readElf), shellQuote(fileName)); FILE *readElfCommand = openProcess(readElf); - if (readElfCommand == 0) { + if (!readElfCommand) { fprintf(stderr, "Cannot execute command %s", qPrintable(readElf)); return QStringList(); } QStringList ret; + bool readLibs = false; char buffer[512]; while (fgets(buffer, sizeof(buffer), readElfCommand) != 0) { QByteArray line = QByteArray::fromRawData(buffer, qstrlen(buffer)); - if (line.contains("(NEEDED)") && line.contains("Shared library:") ) { - const int pos = line.lastIndexOf('[') + 1; - QString libraryName = QLatin1String("lib/") + QString::fromLatin1(line.mid(pos, line.length() - pos - 2)); - if (QFile::exists(absoluteFilePath(&options, libraryName))) { - ret += libraryName; + QString library; + if (options.useLLVM) { + line = line.trimmed(); + if (!readLibs) { + readLibs = line.startsWith("NeededLibraries"); + continue; } - + if (!line.startsWith("lib")) + continue; + library = QString::fromLatin1(line); + } else if (line.contains("(NEEDED)") && line.contains("Shared library:")) { + const int pos = line.lastIndexOf('[') + 1; + library = QString::fromLatin1(line.mid(pos, line.length() - pos - 2)); } + QString libraryName = QLatin1String("lib/") + library; + if (QFile::exists(absoluteFilePath(&options, libraryName))) + ret += libraryName; } pclose(readElfCommand); @@ -1837,10 +1860,12 @@ bool stripFile(const Options &options, const QString &fileName) { QString strip = options.ndkPath + QLatin1String("/toolchains/") - + options.toolchainPrefix - + QLatin1Char('-') - + options.toolchainVersion - + QLatin1String("/prebuilt/") + + options.toolchainPrefix; + + if (!options.useLLVM) + strip += QLatin1Char('-') + options.toolchainVersion; + + strip += QLatin1String("/prebuilt/") + options.ndkHost + QLatin1String("/bin/") + options.toolPrefix @@ -1854,7 +1879,10 @@ bool stripFile(const Options &options, const QString &fileName) return false; } - strip = QString::fromLatin1("%1 %2").arg(shellQuote(strip)).arg(shellQuote(fileName)); + if (options.useLLVM) + strip = QString::fromLatin1("%1 -strip-all -strip-all-gnu %2").arg(shellQuote(strip), shellQuote(fileName)); + else + strip = QString::fromLatin1("%1 %2").arg(shellQuote(strip), shellQuote(fileName)); FILE *stripCommand = openProcess(strip); if (stripCommand == 0) { @@ -2423,22 +2451,15 @@ bool copyStdCpp(Options *options) if (options->verbose) fprintf(stdout, "Copying STL library\n"); - QString filePath = !options->stdCppPath.isEmpty() ? options->stdCppPath - : options->ndkPath - + QLatin1String("/sources/cxx-stl/gnu-libstdc++/") - + options->toolchainVersion - + QLatin1String("/libs/") - + options->architecture - + QLatin1String("/libgnustl_shared.so"); - if (!QFile::exists(filePath)) { - fprintf(stderr, "STL library does not exist at %s\n", qPrintable(filePath)); + if (!QFile::exists(options->stdCppPath)) { + fprintf(stderr, "STL library does not exist at %s\n", qPrintable(options->stdCppPath)); return false; } const QString destinationDirectory = options->outputDirectory + QLatin1String("/libs/") + options->architecture; - if (!copyFileIfNewer(filePath, destinationDirectory + QLatin1String("/lib") + if (!copyFileIfNewer(options->stdCppPath, destinationDirectory + QLatin1String("/lib") + options->stdCppName + QLatin1String(".so"), options->verbose)) { return false; From 8ad9bdf9578d2879d7484c61cf9a46a667f642a4 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sun, 18 Nov 2018 13:41:52 +0100 Subject: [PATCH 0347/1650] QScrollBar: fix horizontal scrollbars in RTL mode When a QScrollBar had a stylesheet the subControlRect() was not properly mirrored which lead to a wrong scrolling behavior. Fix it by adjusting the resulting rect with visualRect(). This reverts 00c9ec63a552d040e851b561c11428fabf1a2b08 since it did not completely fixed the issue for all use cases. Fixes: QTBUG-27279 Fixes: QTBUG-38748 Fixes: QTBUG-40443 Change-Id: I19718287be7b4cfc9dbe6951fff99ae48264a855 Reviewed-by: Richard Moe Gustavsen --- src/widgets/styles/qstylesheetstyle.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index fe6a4d0e40..96c6fdf2e2 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -5632,22 +5632,18 @@ QRect QStyleSheetStyle::subControlRect(ComplexControl cc, const QStyleOptionComp } else { sliderlen = maxlen; } - const int sliderPosition = sb->orientation == Qt::Horizontal && sb->direction == Qt::RightToLeft ? sb->maximum - sb->sliderPosition + sb->minimum : sb->sliderPosition; int sliderstart = (styleOptionSlider.orientation == Qt::Horizontal ? contentRect.left() : contentRect.top()) - + sliderPositionFromValue(sb->minimum, sb->maximum, sliderPosition, + + sliderPositionFromValue(sb->minimum, sb->maximum, sb->sliderPosition, maxlen - sliderlen, sb->upsideDown); QRect sr = (sb->orientation == Qt::Horizontal) ? QRect(sliderstart, contentRect.top(), sliderlen, contentRect.height()) : QRect(contentRect.left(), sliderstart, contentRect.width(), sliderlen); - if (sc == SC_ScrollBarSlider) { - return sr; - } else if (sc == SC_ScrollBarSubPage) { - return QRect(contentRect.topLeft(), sb->orientation == Qt::Horizontal ? sr.bottomLeft() : sr.topRight()); - } else { // SC_ScrollBarAddPage - return QRect(sb->orientation == Qt::Horizontal ? sr.topRight() : sr.bottomLeft(), contentRect.bottomRight()); - } - break; + if (sc == SC_ScrollBarSubPage) + sr = QRect(contentRect.topLeft(), sb->orientation == Qt::Horizontal ? sr.bottomLeft() : sr.topRight()); + else if (sc == SC_ScrollBarAddPage) + sr = QRect(sb->orientation == Qt::Horizontal ? sr.topRight() : sr.bottomLeft(), contentRect.bottomRight()); + return visualRect(styleOptionSlider.direction, grooveRect, sr); } case SC_ScrollBarAddLine: pe = PseudoElement_ScrollBarAddLine; break; case SC_ScrollBarSubLine: pe = PseudoElement_ScrollBarSubLine; break; From ca3ac2e1c7548f2e66561fb0afe93494416ebf9c Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sat, 27 Oct 2018 21:41:16 +0200 Subject: [PATCH 0348/1650] Documentation: update Q_DISABLE_COPY documentation Q_DISABLE_COPY annotates the functions as deleted but this was not mentioned in the documentation. As a drive-by adjust some indentations. Change-Id: I808fe3f1ce9f949d2ba41436661569ab0f2a9f73 Reviewed-by: Sze Howe Koh Reviewed-by: Paul Wicking --- .../code/src_corelib_global_qglobal.cpp | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp index c73e782b76..7fdff974c1 100644 --- a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp @@ -595,8 +595,7 @@ namespace QT_NAMESPACE { //! [43] class MyClass : public QObject { - - private: +private: Q_DISABLE_COPY(MyClass) }; @@ -605,22 +604,21 @@ class MyClass : public QObject //! [44] class MyClass : public QObject { - - private: - MyClass(const MyClass &); - MyClass &operator=(const MyClass &); +private: + MyClass(const MyClass &) = delete; + MyClass &operator=(const MyClass &) = delete; }; //! [44] //! [45] - QWidget w = QWidget(); +QWidget w = QWidget(); //! [45] //! [46] - // Instead of comparing with 0.0 - qFuzzyCompare(0.0,1.0e-200); // This will return false - // Compare adding 1 to both values will fix the problem - qFuzzyCompare(1 + 0.0, 1 + 1.0e-200); // This will return true +// Instead of comparing with 0.0 +qFuzzyCompare(0.0, 1.0e-200); // This will return false +// Compare adding 1 to both values will fix the problem +qFuzzyCompare(1 + 0.0, 1 + 1.0e-200); // This will return true //! [46] //! [47] From e00c73911ae0127f986e056984eff02b099325f4 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Thu, 25 Oct 2018 15:08:13 +0200 Subject: [PATCH 0349/1650] Reduce run time of tst_QRegularExpression::threadSafety MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This test was taking so much time that it regularly timed out on WinRT and when running in qemu. Reduce it from around 40 to 7 seconds on a powerful desktop. Now it either runs for two full seconds for each test function or until it has done 50 iterations. Fixes: QTBUG-71405 Change-Id: If752c1e65d3b19009b883f64edc96d020df479d1 Reviewed-by: Oliver Wolff Reviewed-by: Jędrzej Nowacki Reviewed-by: Timur Pocheptsov --- .../tools/qregularexpression/tst_qregularexpression.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp b/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp index 18098f16bf..c23ee3b0ba 100644 --- a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp +++ b/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp @@ -2135,11 +2135,12 @@ void tst_QRegularExpression::threadSafety() QFETCH(QString, pattern); QFETCH(QString, subject); + QElapsedTimer time; + time.start(); static const int THREAD_SAFETY_ITERATIONS = 50; - const int threadCount = qMax(QThread::idealThreadCount(), 4); - for (int threadSafetyIteration = 0; threadSafetyIteration < THREAD_SAFETY_ITERATIONS; ++threadSafetyIteration) { + for (int threadSafetyIteration = 0; threadSafetyIteration < THREAD_SAFETY_ITERATIONS && time.elapsed() < 2000; ++threadSafetyIteration) { QRegularExpression re(pattern); QVector threads; From 574bf5d9aaea3319e6761b9782ab7ae99991771d Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Tue, 20 Nov 2018 09:47:23 +0100 Subject: [PATCH 0350/1650] Correct QT_FEATURE_settings in qconfig-bootstrapped.h This amends 4d180586cddbd71a67c83246db3bec1caa595e05. Change-Id: Ia008e618f726f113f84cf4caa8d5f30442dbbb64 Reviewed-by: Oswald Buddenhagen --- src/corelib/global/qconfig-bootstrapped.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/corelib/global/qconfig-bootstrapped.h b/src/corelib/global/qconfig-bootstrapped.h index f86cbaf74d..dfcc3c9c7f 100644 --- a/src/corelib/global/qconfig-bootstrapped.h +++ b/src/corelib/global/qconfig-bootstrapped.h @@ -104,7 +104,6 @@ #else # define QT_FEATURE_renameat2 -1 #endif -#define QT_FEATURE_settings -1 #define QT_FEATURE_sharedmemory -1 #define QT_FEATURE_slog2 -1 #ifdef __GLIBC_PREREQ From 6c1656397a2d0c30810cdbd880eda9e9c43fbe67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 15 Nov 2018 13:45:46 +0100 Subject: [PATCH 0351/1650] macOS: Ensure NSWindow delegate is released in sync with its NSWindow Releasing it in [QNSWindow closeAndRelease] is wrong, as we only call that method from a few call sites, and can easily end up with a normal dealloc by means of e.g. the [m_nsWindow release] in ~QCocoaWindow. This still leaves Xcode thinking we have a single leaking delegate per active NSWindow, as it apparently doesn't realize we're calling release manually. This needs to be investigated further. Task-number: QTBUG-65693 Change-Id: I9105602274d8532465e5108aba2b05bf253268e9 Reviewed-by: Andy Shaw Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qnswindow.mm | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/cocoa/qnswindow.mm b/src/plugins/platforms/cocoa/qnswindow.mm index 1b9dd95cbc..b3cd3c1d8c 100644 --- a/src/plugins/platforms/cocoa/qnswindow.mm +++ b/src/plugins/platforms/cocoa/qnswindow.mm @@ -239,10 +239,6 @@ static bool isMouseEvent(NSEvent *ev) - (void)closeAndRelease { qCDebug(lcQpaWindow) << "closeAndRelease" << self; - - [self.delegate release]; - self.delegate = nil; - [self close]; [self release]; } @@ -252,6 +248,9 @@ static bool isMouseEvent(NSEvent *ev) - (void)dealloc { qCDebug(lcQpaWindow) << "dealloc" << self; + [self.delegate release]; + self.delegate = nil; + qt_objcDynamicSuper(); } #pragma clang diagnostic pop From 12045801f742dd956f17d1a6c72b21f8f245a671 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 15 Nov 2018 14:21:56 +0100 Subject: [PATCH 0352/1650] macOS: Use shared NSWindowDelegate instead of one per window MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All the delegate callbacks give us the relevant NSWindow, so we don't need one delegate per window just to be able to resolve the correct platform window. Change-Id: I8e44186da63bf01f029bb0b1fefcd8880f49dda6 Fixes: QTBUG-65693 Reviewed-by: Morten Johan Sørvig Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qcocoawindow.mm | 4 +- src/plugins/platforms/cocoa/qnswindow.mm | 1 - .../platforms/cocoa/qnswindowdelegate.h | 3 -- .../platforms/cocoa/qnswindowdelegate.mm | 44 ++++++++++--------- 4 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 1ce671941d..4dc3ea4bd6 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1548,7 +1548,9 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel) QWindowSystemInterface::SynchronousDelivery>(window(), targetScreen); } - nsWindow.delegate = [[QNSWindowDelegate alloc] initWithQCocoaWindow:this]; + static QSharedPointer sharedDelegate([[QNSWindowDelegate alloc] init], + [](QNSWindowDelegate *delegate) { [delegate release]; }); + nsWindow.delegate = sharedDelegate.get(); // Prevent Cocoa from releasing the window on close. Qt // handles the close event asynchronously and we want to diff --git a/src/plugins/platforms/cocoa/qnswindow.mm b/src/plugins/platforms/cocoa/qnswindow.mm index b3cd3c1d8c..dd6ee3058a 100644 --- a/src/plugins/platforms/cocoa/qnswindow.mm +++ b/src/plugins/platforms/cocoa/qnswindow.mm @@ -248,7 +248,6 @@ static bool isMouseEvent(NSEvent *ev) - (void)dealloc { qCDebug(lcQpaWindow) << "dealloc" << self; - [self.delegate release]; self.delegate = nil; qt_objcDynamicSuper(); diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.h b/src/plugins/platforms/cocoa/qnswindowdelegate.h index e71afcbb2a..be870deb3a 100644 --- a/src/plugins/platforms/cocoa/qnswindowdelegate.h +++ b/src/plugins/platforms/cocoa/qnswindowdelegate.h @@ -48,9 +48,6 @@ class QCocoaWindow; QT_END_NAMESPACE @interface QT_MANGLE_NAMESPACE(QNSWindowDelegate) : NSObject - -- (instancetype)initWithQCocoaWindow:(QT_PREPEND_NAMESPACE(QCocoaWindow) *)cocoaWindow; - @end QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSWindowDelegate); diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.mm b/src/plugins/platforms/cocoa/qnswindowdelegate.mm index 97309ea990..14f1ca0114 100644 --- a/src/plugins/platforms/cocoa/qnswindowdelegate.mm +++ b/src/plugins/platforms/cocoa/qnswindowdelegate.mm @@ -49,23 +49,17 @@ static QRegExp whitespaceRegex = QRegExp(QStringLiteral("\\s*")); -@implementation QNSWindowDelegate { - QCocoaWindow *m_cocoaWindow; +static QCocoaWindow *toPlatformWindow(NSWindow *window) +{ + return qnsview_cast(window.contentView).platformWindow; } -- (instancetype)initWithQCocoaWindow:(QCocoaWindow *)cocoaWindow -{ - if ((self = [self init])) - m_cocoaWindow = cocoaWindow; - return self; -} +@implementation QNSWindowDelegate -- (BOOL)windowShouldClose:(NSNotification *)notification +- (BOOL)windowShouldClose:(NSWindow *)window { - Q_UNUSED(notification); - if (m_cocoaWindow) { - return m_cocoaWindow->windowShouldClose(); - } + if (QCocoaWindow *platformWindow = toPlatformWindow(window)) + return platformWindow->windowShouldClose(); return YES; } @@ -79,14 +73,16 @@ static QRegExp whitespaceRegex = QRegExp(QStringLiteral("\\s*")); - (NSRect)windowWillUseStandardFrame:(NSWindow *)window defaultFrame:(NSRect)proposedFrame { Q_UNUSED(proposedFrame); - Q_ASSERT(window == m_cocoaWindow->nativeWindow()); - const QWindow *w = m_cocoaWindow->window(); + + QCocoaWindow *platformWindow = toPlatformWindow(window); + Q_ASSERT(platformWindow); + const QWindow *w = platformWindow->window(); // maximumSize() refers to the client size, but AppKit expects the full frame size QSizeF maximumSize = w->maximumSize() + QSize(0, w->frameMargins().top()); // The window should never be larger than the current screen geometry - const QRectF screenGeometry = m_cocoaWindow->screen()->geometry(); + const QRectF screenGeometry = platformWindow->screen()->geometry(); maximumSize = maximumSize.boundedTo(screenGeometry.size()); // Use the current frame position for the initial maximized frame, @@ -113,6 +109,8 @@ static QRegExp whitespaceRegex = QRegExp(QStringLiteral("\\s*")); #pragma clang diagnostic ignored "-Wdeprecated-declarations" - (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)frameSize { + Q_ASSERT(toPlatformWindow(window)); + qCDebug(lcQpaWindow) << window << "will resize to" << QSizeF::fromCGSize(frameSize) << "- disabling screen updates temporarily"; @@ -131,6 +129,8 @@ static QRegExp whitespaceRegex = QRegExp(QStringLiteral("\\s*")); - (void)windowDidResize:(NSNotification *)notification { NSWindow *window = notification.object; + Q_ASSERT(toPlatformWindow(window)); + qCDebug(lcQpaWindow) << window << "was resized - re-enabling screen updates"; NSEnableScreenUpdates(); } @@ -138,23 +138,27 @@ static QRegExp whitespaceRegex = QRegExp(QStringLiteral("\\s*")); - (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu { - Q_UNUSED(window); Q_UNUSED(menu); + QCocoaWindow *platformWindow = toPlatformWindow(window); + Q_ASSERT(platformWindow); + // Only pop up document path if the filename is non-empty. We allow whitespace, to // allow faking a window icon by setting the file path to a single space character. - return !whitespaceRegex.exactMatch(m_cocoaWindow->window()->filePath()); + return !whitespaceRegex.exactMatch(platformWindow->window()->filePath()); } - (BOOL)window:(NSWindow *)window shouldDragDocumentWithEvent:(NSEvent *)event from:(NSPoint)dragImageLocation withPasteboard:(NSPasteboard *)pasteboard { - Q_UNUSED(window); Q_UNUSED(event); Q_UNUSED(dragImageLocation); Q_UNUSED(pasteboard); + QCocoaWindow *platformWindow = toPlatformWindow(window); + Q_ASSERT(platformWindow); + // Only allow drag if the filename is non-empty. We allow whitespace, to // allow faking a window icon by setting the file path to a single space. - return !whitespaceRegex.exactMatch(m_cocoaWindow->window()->filePath()); + return !whitespaceRegex.exactMatch(platformWindow->window()->filePath()); } @end From 666f3b4a7819d67f745f4497ef5191521ed8c33b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 16 Nov 2018 15:06:18 +0100 Subject: [PATCH 0353/1650] Take device-pixel-ratio into account in openglwindow example Also affects the windowcontainer example, which includes an OpenGL window. Change-Id: Ic9f0f2aa66410b657e08c0225b085dd8df44e2a7 Reviewed-by: Laszlo Agocs --- examples/gui/openglwindow/openglwindow.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/gui/openglwindow/openglwindow.cpp b/examples/gui/openglwindow/openglwindow.cpp index 57a996a876..a0c85006bd 100644 --- a/examples/gui/openglwindow/openglwindow.cpp +++ b/examples/gui/openglwindow/openglwindow.cpp @@ -88,7 +88,8 @@ void OpenGLWindow::render() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - m_device->setSize(size()); + m_device->setSize(size() * devicePixelRatio()); + m_device->setDevicePixelRatio(devicePixelRatio()); QPainter painter(m_device); render(&painter); From 9c560eb8b5ca2768ffa3a6e1b208e3e6b55470d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 16 Nov 2018 19:34:36 +0100 Subject: [PATCH 0354/1650] macOS: Improve logging during QNSView/QNSWindow deallocation Change-Id: Ie6945f2a1f35db6d1259b77ee63137abcaf68318 Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qnsview.mm | 2 ++ src/plugins/platforms/cocoa/qnswindow.mm | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 540f701d43..03c5001270 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -166,6 +166,8 @@ - (void)dealloc { + qCDebug(lcQpaWindow) << "Deallocating" << self; + if (m_trackingArea) { [self removeTrackingArea:m_trackingArea]; [m_trackingArea release]; diff --git a/src/plugins/platforms/cocoa/qnswindow.mm b/src/plugins/platforms/cocoa/qnswindow.mm index dd6ee3058a..c17ad47aba 100644 --- a/src/plugins/platforms/cocoa/qnswindow.mm +++ b/src/plugins/platforms/cocoa/qnswindow.mm @@ -238,7 +238,7 @@ static bool isMouseEvent(NSEvent *ev) - (void)closeAndRelease { - qCDebug(lcQpaWindow) << "closeAndRelease" << self; + qCDebug(lcQpaWindow) << "Closing and releasing" << self; [self close]; [self release]; } @@ -247,7 +247,7 @@ static bool isMouseEvent(NSEvent *ev) #pragma clang diagnostic ignored "-Wobjc-missing-super-calls" - (void)dealloc { - qCDebug(lcQpaWindow) << "dealloc" << self; + qCDebug(lcQpaWindow) << "Deallocating" << self; self.delegate = nil; qt_objcDynamicSuper(); From aa75697b63627d5c1ff90aa967ba58bbad7cae18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 20 Nov 2018 16:37:12 +0100 Subject: [PATCH 0355/1650] Add makefile target to generate Xcode project Removes need to manually build up qmake command line when there's already a Makefile generated (from a recursive qmake_all run e.g.) Instead, just run 'make xcodeproj'. Change-Id: Ibe91b183230721a4bcaddfde53b623df00f7adb5 Reviewed-by: Alexandru Croitor --- mkspecs/features/mac/default_post.prf | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mkspecs/features/mac/default_post.prf b/mkspecs/features/mac/default_post.prf index 99f68b78f5..c01e99fe8e 100644 --- a/mkspecs/features/mac/default_post.prf +++ b/mkspecs/features/mac/default_post.prf @@ -259,3 +259,10 @@ isEmpty(xcode_product_bundle_target): \ xcode_product_bundle_target = ${PRODUCT_NAME:rfc1034identifier} xcode_product_bundle_identifier_setting.value = "$${xcode_product_bundle_identifier_setting.value}.$${xcode_product_bundle_target}" QMAKE_MAC_XCODE_SETTINGS += xcode_product_bundle_identifier_setting + +!macx-xcode { + generate_xcode_project.commands = @$(QMAKE) -spec macx-xcode $(EXPORT__PRO_FILE_) + generate_xcode_project.target = xcodeproj + QMAKE_EXTRA_VARIABLES += _PRO_FILE_ + QMAKE_EXTRA_TARGETS += generate_xcode_project +} From 1135cf3df4ef9670332891153e9b38f1aa5f2f56 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Tue, 20 Nov 2018 16:37:28 +0100 Subject: [PATCH 0356/1650] Add missing "We mean it" warning Change-Id: I1e836f2c1f37813d7ab9343df9f6679aefe6a2ca Reviewed-by: David Faure Reviewed-by: Luca Beldi --- src/corelib/itemmodels/qtransposeproxymodel_p.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/corelib/itemmodels/qtransposeproxymodel_p.h b/src/corelib/itemmodels/qtransposeproxymodel_p.h index 240fc4ccae..fb5ce5c117 100644 --- a/src/corelib/itemmodels/qtransposeproxymodel_p.h +++ b/src/corelib/itemmodels/qtransposeproxymodel_p.h @@ -40,6 +40,17 @@ #ifndef QTRANSPOSEPROXYMODEL_P_H #define QTRANSPOSEPROXYMODEL_P_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + #include "qtransposeproxymodel.h" #include From 37f617c405ae4f26cbb6bb4f08d61d6ccc111a98 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 9 Nov 2018 14:05:35 +0100 Subject: [PATCH 0357/1650] Add qfloat16 support to QCOMPARE Change-Id: Ide06f215a888328308a06e7e48edd666f790a5f0 Reviewed-by: Friedemann Kleint Reviewed-by: Lars Knoll --- src/testlib/qtestcase.cpp | 18 +++++ src/testlib/qtestcase.h | 5 ++ .../testlib/selftests/expected_float.lightxml | 27 +++++++ .../auto/testlib/selftests/expected_float.tap | 78 ++++++++++++++----- .../testlib/selftests/expected_float.teamcity | 13 ++++ .../auto/testlib/selftests/expected_float.txt | 16 +++- .../auto/testlib/selftests/expected_float.xml | 27 +++++++ .../testlib/selftests/expected_float.xunitxml | 13 +++- .../testlib/selftests/float/tst_float.cpp | 39 ++++++++++ 9 files changed, 214 insertions(+), 22 deletions(-) diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 1c3292ead9..a9e2cc5ea3 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -2483,6 +2484,16 @@ bool QTest::compare_helper(bool success, const char *failureMsg, return QTestResult::compare(success, failureMsg, val1, val2, actual, expected, file, line); } +/*! \fn bool QTest::qCompare(const qfloat16 &t1, const qfloat16 &t2, const char *actual, const char *expected, const char *file, int line) + \internal + */ +bool QTest::qCompare(qfloat16 const &t1, qfloat16 const &t2, const char *actual, const char *expected, + const char *file, int line) +{ + return compare_helper(qFuzzyCompare(t1, t2), "Compared qfloat16s are not the same (fuzzy compare)", + toString(t1), toString(t2), actual, expected, file, line); +} + /*! \fn bool QTest::qCompare(const float &t1, const float &t2, const char *actual, const char *expected, const char *file, int line) \internal */ @@ -2547,6 +2558,13 @@ TO_STRING_IMPL(unsigned char, %hhu) TO_STRING_IMPL(float, %g) TO_STRING_IMPL(double, %lg) +template <> Q_TESTLIB_EXPORT char *QTest::toString(const qfloat16 &t) +{ + char *msg = new char[16]; + qsnprintf(msg, 16, "%.3g", static_cast(t)); + return msg; +} + template <> Q_TESTLIB_EXPORT char *QTest::toString(const char &t) { unsigned char c = static_cast(t); diff --git a/src/testlib/qtestcase.h b/src/testlib/qtestcase.h index a6f1711230..39364df8ef 100644 --- a/src/testlib/qtestcase.h +++ b/src/testlib/qtestcase.h @@ -57,6 +57,7 @@ QT_BEGIN_NAMESPACE +class qfloat16; class QRegularExpression; #define QVERIFY(statement) \ @@ -361,6 +362,9 @@ namespace QTest } #endif + Q_TESTLIB_EXPORT bool qCompare(qfloat16 const &t1, qfloat16 const &t2, + const char *actual, const char *expected, const char *file, int line); + Q_TESTLIB_EXPORT bool qCompare(float const &t1, float const &t2, const char *actual, const char *expected, const char *file, int line); @@ -405,6 +409,7 @@ namespace QTest QTEST_COMPARE_DECL(float) QTEST_COMPARE_DECL(double) + QTEST_COMPARE_DECL(qfloat16) QTEST_COMPARE_DECL(char) QTEST_COMPARE_DECL(signed char) QTEST_COMPARE_DECL(unsigned char) diff --git a/tests/auto/testlib/selftests/expected_float.lightxml b/tests/auto/testlib/selftests/expected_float.lightxml index 0dbc5dd8c8..37ccbfc2c5 100644 --- a/tests/auto/testlib/selftests/expected_float.lightxml +++ b/tests/auto/testlib/selftests/expected_float.lightxml @@ -34,6 +34,33 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/testlib/selftests/expected_float.tap b/tests/auto/testlib/selftests/expected_float.tap index fae2dc9796..158eff1470 100644 --- a/tests/auto/testlib/selftests/expected_float.tap +++ b/tests/auto/testlib/selftests/expected_float.tap @@ -10,9 +10,9 @@ not ok 3 - floatComparisons(should FAIL 1) found: 1 (operandLeft) expected: 3 (operandRight) actual: 1 (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:48) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 48 + line: 51 ... not ok 4 - floatComparisons(should FAIL 2) --- @@ -22,9 +22,9 @@ not ok 4 - floatComparisons(should FAIL 2) found: 1e-07 (operandLeft) expected: 3e-07 (operandRight) actual: 1e-07 (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:48) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 48 + line: 51 ... not ok 5 - floatComparisons(should FAIL 3) --- @@ -34,12 +34,50 @@ not ok 5 - floatComparisons(should FAIL 3) found: 99998 (operandLeft) expected: 99999 (operandRight) actual: 99998 (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:48) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 48 + line: 51 ... ok 6 - floatComparisons(should SUCCEED 2) -not ok 7 - compareFloatTests(1e0) +ok 7 - float16Comparisons(should SUCCEED 1) +not ok 8 - float16Comparisons(should FAIL 1) + --- + type: QCOMPARE + message: Compared qfloat16s are not the same (fuzzy compare) + wanted: 3 (operandRight) + found: 1 (operandLeft) + expected: 3 (operandRight) + actual: 1 (operandLeft) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:90) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 90 + ... +not ok 9 - float16Comparisons(should FAIL 2) + --- + type: QCOMPARE + message: Compared qfloat16s are not the same (fuzzy compare) + wanted: 0.0003 (operandRight) + found: 0.0001 (operandLeft) + expected: 0.0003 (operandRight) + actual: 0.0001 (operandLeft) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:90) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 90 + ... +not ok 10 - float16Comparisons(should FAIL 3) + --- + type: QCOMPARE + message: Compared qfloat16s are not the same (fuzzy compare) + wanted: 99 (operandRight) + found: 98 (operandLeft) + expected: 99 (operandRight) + actual: 98 (operandLeft) + at: tst_float::float16Comparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:90) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 90 + ... +ok 11 - float16Comparisons(should SUCCEED 2) +not ok 12 - compareFloatTests(1e0) --- type: QCOMPARE message: Compared floats are not the same (fuzzy compare) @@ -47,11 +85,11 @@ not ok 7 - compareFloatTests(1e0) found: 1 (t1) expected: 3 (t3) actual: 1 (t1) - at: tst_float::compareFloatTests() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:96) + at: tst_float::compareFloatTests() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:135) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 96 + line: 135 ... -not ok 8 - compareFloatTests(1e-7) +not ok 13 - compareFloatTests(1e-7) --- type: QCOMPARE message: Compared floats are not the same (fuzzy compare) @@ -59,11 +97,11 @@ not ok 8 - compareFloatTests(1e-7) found: 1e-07 (t1) expected: 3e-07 (t3) actual: 1e-07 (t1) - at: tst_float::compareFloatTests() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:96) + at: tst_float::compareFloatTests() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:135) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 96 + line: 135 ... -not ok 9 - compareFloatTests(1e+7) +not ok 14 - compareFloatTests(1e+7) --- type: QCOMPARE message: Compared floats are not the same (fuzzy compare) @@ -71,12 +109,12 @@ not ok 9 - compareFloatTests(1e+7) found: 1e+07 (t1) expected: 3e+07 (t3) actual: 1e+07 (t1) - at: tst_float::compareFloatTests() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:96) + at: tst_float::compareFloatTests() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:135) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 96 + line: 135 ... -ok 10 - cleanupTestCase() -1..10 -# tests 10 -# pass 4 -# fail 6 +ok 15 - cleanupTestCase() +1..15 +# tests 15 +# pass 6 +# fail 9 diff --git a/tests/auto/testlib/selftests/expected_float.teamcity b/tests/auto/testlib/selftests/expected_float.teamcity index d5b81593d8..140dc7edf9 100644 --- a/tests/auto/testlib/selftests/expected_float.teamcity +++ b/tests/auto/testlib/selftests/expected_float.teamcity @@ -14,6 +14,19 @@ ##teamcity[testFinished name='floatComparisons(should FAIL 3)' flowId='tst_float'] ##teamcity[testStarted name='floatComparisons(should SUCCEED 2)' flowId='tst_float'] ##teamcity[testFinished name='floatComparisons(should SUCCEED 2)' flowId='tst_float'] +##teamcity[testStarted name='float16Comparisons(should SUCCEED 1)' flowId='tst_float'] +##teamcity[testFinished name='float16Comparisons(should SUCCEED 1)' flowId='tst_float'] +##teamcity[testStarted name='float16Comparisons(should FAIL 1)' flowId='tst_float'] +##teamcity[testFailed name='float16Comparisons(should FAIL 1)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared qfloat16s are not the same (fuzzy compare)|n Actual (operandLeft) : 1|n Expected (operandRight): 3' flowId='tst_float'] +##teamcity[testFinished name='float16Comparisons(should FAIL 1)' flowId='tst_float'] +##teamcity[testStarted name='float16Comparisons(should FAIL 2)' flowId='tst_float'] +##teamcity[testFailed name='float16Comparisons(should FAIL 2)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared qfloat16s are not the same (fuzzy compare)|n Actual (operandLeft) : 0.0001|n Expected (operandRight): 0.0003' flowId='tst_float'] +##teamcity[testFinished name='float16Comparisons(should FAIL 2)' flowId='tst_float'] +##teamcity[testStarted name='float16Comparisons(should FAIL 3)' flowId='tst_float'] +##teamcity[testFailed name='float16Comparisons(should FAIL 3)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared qfloat16s are not the same (fuzzy compare)|n Actual (operandLeft) : 98|n Expected (operandRight): 99' flowId='tst_float'] +##teamcity[testFinished name='float16Comparisons(should FAIL 3)' flowId='tst_float'] +##teamcity[testStarted name='float16Comparisons(should SUCCEED 2)' flowId='tst_float'] +##teamcity[testFinished name='float16Comparisons(should SUCCEED 2)' flowId='tst_float'] ##teamcity[testStarted name='compareFloatTests(1e0)' flowId='tst_float'] ##teamcity[testFailed name='compareFloatTests(1e0)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (t1): 1|n Expected (t3): 3' flowId='tst_float'] ##teamcity[testFinished name='compareFloatTests(1e0)' flowId='tst_float'] diff --git a/tests/auto/testlib/selftests/expected_float.txt b/tests/auto/testlib/selftests/expected_float.txt index 8abea6a67e..4e3554758d 100644 --- a/tests/auto/testlib/selftests/expected_float.txt +++ b/tests/auto/testlib/selftests/expected_float.txt @@ -15,6 +15,20 @@ FAIL! : tst_float::floatComparisons(should FAIL 3) Compared floats are not the Expected (operandRight): 99999 Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] PASS : tst_float::floatComparisons(should SUCCEED 2) +PASS : tst_float::float16Comparisons(should SUCCEED 1) +FAIL! : tst_float::float16Comparisons(should FAIL 1) Compared qfloat16s are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): 3 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::float16Comparisons(should FAIL 2) Compared qfloat16s are not the same (fuzzy compare) + Actual (operandLeft) : 0.0001 + Expected (operandRight): 0.0003 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::float16Comparisons(should FAIL 3) Compared qfloat16s are not the same (fuzzy compare) + Actual (operandLeft) : 98 + Expected (operandRight): 99 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +PASS : tst_float::float16Comparisons(should SUCCEED 2) FAIL! : tst_float::compareFloatTests(1e0) Compared floats are not the same (fuzzy compare) Actual (t1): 1 Expected (t3): 3 @@ -28,5 +42,5 @@ FAIL! : tst_float::compareFloatTests(1e+7) Compared floats are not the same (fu Expected (t3): 3e+07 Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] PASS : tst_float::cleanupTestCase() -Totals: 4 passed, 6 failed, 0 skipped, 0 blacklisted, 0ms +Totals: 6 passed, 9 failed, 0 skipped, 0 blacklisted, 0ms ********* Finished testing of tst_float ********* diff --git a/tests/auto/testlib/selftests/expected_float.xml b/tests/auto/testlib/selftests/expected_float.xml index 096e1a5b54..1f17d48d1b 100644 --- a/tests/auto/testlib/selftests/expected_float.xml +++ b/tests/auto/testlib/selftests/expected_float.xml @@ -36,6 +36,33 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/testlib/selftests/expected_float.xunitxml b/tests/auto/testlib/selftests/expected_float.xunitxml index 5de14e8d9b..87f11ccba5 100644 --- a/tests/auto/testlib/selftests/expected_float.xunitxml +++ b/tests/auto/testlib/selftests/expected_float.xunitxml @@ -1,5 +1,5 @@ - + @@ -17,6 +17,17 @@ Actual (operandLeft) : 99998 Expected (operandRight): 99999" result="fail"/> + + + + + ("operandRight"); + + QTest::newRow("should SUCCEED 1") + << qfloat16(0) + << qfloat16(0); + + QTest::newRow("should FAIL 1") + << qfloat16(1.000) + << qfloat16(3.000); + + QTest::newRow("should FAIL 2") + << qfloat16(1.000e-4f) + << qfloat16(3.000e-4f); + + // QCOMPARE for qfloat16s uses qFuzzyCompare() + + QTest::newRow("should FAIL 3") + << qfloat16(98) + << qfloat16(99); + + QTest::newRow("should SUCCEED 2") + << qfloat16(1001) + << qfloat16(1002); +} + void tst_float::compareFloatTests() const { QFETCH(float, t1); From d5b3ddffae0a878618bb2637539054dc2e397706 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Fri, 9 Nov 2018 15:54:42 +0100 Subject: [PATCH 0358/1650] QMacStyle: account for QStyleSheetStyle using QTabBar directly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit in this case w->parentWidget() is not QTabBar, but QTabWidget and we never draw PE_IndicatorTabClose control (before the recent major re-write in qmacstyle we never tested the actual type). Task-number: QTBUG-61092 Change-Id: I87c4813258cc2b483b2ef278c4a2f8796973af1c Reviewed-by: Tor Arne Vestbø Reviewed-by: Morten Johan Sørvig --- src/plugins/styles/mac/qmacstyle_mac.mm | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index 1fd3420899..b84448d5e2 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -3229,7 +3229,13 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai break; case PE_IndicatorTabClose: { // Make close button visible only on the hovered tab. - if (QTabBar *tabBar = qobject_cast(w->parentWidget())) { + QTabBar *tabBar = qobject_cast(w->parentWidget()); + if (!tabBar) { + // QStyleSheetStyle instead of CloseButton (which has + // a QTabBar as a parent widget) uses the QTabBar itself: + tabBar = qobject_cast(const_cast(w)); + } + if (tabBar) { const bool documentMode = tabBar->documentMode(); const QTabBarPrivate *tabBarPrivate = static_cast(QObjectPrivate::get(tabBar)); const int hoveredTabIndex = tabBarPrivate->hoveredTabIndex(); From be92e67fbf519e27a95344220d88ddc6586b44d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Klitzing?= Date: Tue, 20 Nov 2018 15:42:50 +0100 Subject: [PATCH 0359/1650] Add log output if library does not exists Any other method logs this here, too. This helped to find the problem of QTBUG-71027. Change-Id: I2d1f6199837d778ada62dac357764b0609e99692 Reviewed-by: BogDan Vatra --- src/android/jar/src/org/qtproject/qt5/android/QtNative.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java index 61f6afe85d..adc67e93fb 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java @@ -177,6 +177,8 @@ public class QtNative File f = new File(libName); if (f.exists()) System.load(libName); + else + Log.i(QtTAG, "Can't find '" + libName + "'"); } catch (SecurityException e) { Log.i(QtTAG, "Can't load '" + libName + "'", e); } catch (Exception e) { From ac4b2a2b8e8f835e739f39b8b9509a841657c864 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 9 Nov 2018 09:36:21 +0100 Subject: [PATCH 0360/1650] Don't start a new page when printing very large images Don't start a new page to print a very high line of text if that line wouldn't fit on one page in any case. In that case we have to break the image up onto several pages anyway, so we might as well start it immediately. Change-Id: I823aa4961df179054476755c8f5df2e03874661f Fixes: QTBUG-59885 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qtextdocumentlayout.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index 9aeea44dd3..ebd7a7d69f 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -2709,7 +2709,8 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi qreal(q->paintDevice()->logicalDpiY()) / qreal(qt_defaultDpi()) : 1; getLineHeightParams(blockFormat, line, scaling, &lineAdjustment, &lineBreakHeight, &lineHeight, &lineBottom); - if (layoutStruct->pageHeight > 0 && layoutStruct->absoluteY() + lineBreakHeight > layoutStruct->pageBottom) { + if (layoutStruct->pageHeight > 0 && layoutStruct->absoluteY() + lineBreakHeight > layoutStruct->pageBottom && + layoutStruct->pageHeight >= lineBreakHeight) { layoutStruct->newPage(); floatMargins(layoutStruct->y, layoutStruct, &left, &right); From 127005d3608490e9688dfeedfdafb13458ed55ea Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 19 Nov 2018 12:37:34 +0100 Subject: [PATCH 0361/1650] qmake: fix return type of toLongLong() Fixes: QTBUG-71886 Change-Id: I62880e7ad8a1707c9094b07cf89d5c0c7841d235 Reviewed-by: Joerg Bornemann --- qmake/library/proitems.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/library/proitems.h b/qmake/library/proitems.h index 2b09fc2074..71e5e05367 100644 --- a/qmake/library/proitems.h +++ b/qmake/library/proitems.h @@ -133,7 +133,7 @@ public: bool contains(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(s, 0, cs) >= 0; } bool contains(const char *s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(QLatin1String(s), 0, cs) >= 0; } bool contains(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const { return indexOf(c, 0, cs) >= 0; } - int toLongLong(bool *ok = nullptr, int base = 10) const { return toQStringRef().toLongLong(ok, base); } + qlonglong toLongLong(bool *ok = nullptr, int base = 10) const { return toQStringRef().toLongLong(ok, base); } int toInt(bool *ok = nullptr, int base = 10) const { return toQStringRef().toInt(ok, base); } short toShort(bool *ok = nullptr, int base = 10) const { return toQStringRef().toShort(ok, base); } From 2842088cb7c2b29bab6453298fff7b1aa5b488d5 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 9 Nov 2018 13:05:04 -0800 Subject: [PATCH 0362/1650] Unbreak the build with ICC on Windows qlogging.obj : error LNK2019: unresolved external symbol __fastfail referenced in function "void __cdecl qt_message_fatal(enum QtMsgType,class QMessageLogContext const &,class QString const &)" (?qt_message_fatal@@YAXW4QtMsgType@@AEBVQMessageLogContext@@AEBVQString@@@Z) Fixes: QTBUG-71868 Change-Id: I42a48bd64ccc41aebf84fffd156590a93fe9da53 Reviewed-by: Lars Knoll --- src/corelib/global/qlogging.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 396aee8696..168934c202 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -1885,7 +1885,7 @@ static void qt_message_fatal(QtMsgType, const QMessageLogContext &context, const // [support.start.term]). So we bypass std::abort() and directly // terminate the application. -# ifdef Q_CC_MSVC +# if defined(Q_CC_MSVC) && !defined(Q_CC_INTEL) if (IsProcessorFeaturePresent(PF_FASTFAIL_AVAILABLE)) __fastfail(FAST_FAIL_FATAL_APP_EXIT); # else From 46076f73337d6b0fea9a006dab2af8864571ae2c Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Wed, 21 Nov 2018 13:46:28 +0100 Subject: [PATCH 0363/1650] tst_QNetworkReply: Blacklist getFromHttp:success-external Task-number: QTBUG-71953 Change-Id: I449ee3be8fa748046895386c9cbff90b30ed80c4 Reviewed-by: Timur Pocheptsov --- tests/auto/network/access/qnetworkreply/BLACKLIST | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/auto/network/access/qnetworkreply/BLACKLIST b/tests/auto/network/access/qnetworkreply/BLACKLIST index fab8224431..4d29a830e9 100644 --- a/tests/auto/network/access/qnetworkreply/BLACKLIST +++ b/tests/auto/network/access/qnetworkreply/BLACKLIST @@ -8,6 +8,9 @@ windows * [getErrors:ftp-host] linux +# QTBUG-71953 +[getFromHttp:success-external] +* [getFromHttpIntoBuffer] windows [getFromHttpIntoBuffer2] From 175ada2249cd110ede45468b8c821706525695f8 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 11 Oct 2018 17:00:28 +0200 Subject: [PATCH 0364/1650] qmake: fix test for $ANDROID_NDK_ROOT there is no reason whatsoever to ignore the variable if it's set to an invalid value. also, it being empty would lead to a warning from qmake since a while. so instead check it for emptiness like every other variable, not for file existence. Change-Id: I1119f67520d2986811501cd3f223f8f4a87d067d Reviewed-by: Eskil Abrahamsen Blomfeldt --- mkspecs/common/android-base-head.conf | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mkspecs/common/android-base-head.conf b/mkspecs/common/android-base-head.conf index c7c27298b9..93e7ba3ed4 100644 --- a/mkspecs/common/android-base-head.conf +++ b/mkspecs/common/android-base-head.conf @@ -4,9 +4,7 @@ load(device_config) isEmpty(DEFAULT_ANDROID_NDK_ROOT): return() NDK_ROOT = $$(ANDROID_NDK_ROOT) -!exists($$NDK_ROOT) { - NDK_ROOT = $$DEFAULT_ANDROID_NDK_ROOT -} +isEmpty(NDK_ROOT): NDK_ROOT = $$DEFAULT_ANDROID_NDK_ROOT NDK_HOST = $$(ANDROID_NDK_HOST) isEmpty(NDK_HOST): NDK_HOST = $$DEFAULT_ANDROID_NDK_HOST From 659eff9f2dbefaead70ff091b5ddaf1efb7f8c8f Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 12 Oct 2018 14:37:13 +0200 Subject: [PATCH 0365/1650] qmake: prune dead assignments from android spec Change-Id: Ide2bbe7116c24c6b952db835c23ebf2859f18c5f Reviewed-by: BogDan Vatra --- mkspecs/common/android-base-head.conf | 4 ---- mkspecs/common/android-base-tail.conf | 1 - 2 files changed, 5 deletions(-) diff --git a/mkspecs/common/android-base-head.conf b/mkspecs/common/android-base-head.conf index 93e7ba3ed4..a43fc7f23e 100644 --- a/mkspecs/common/android-base-head.conf +++ b/mkspecs/common/android-base-head.conf @@ -67,10 +67,6 @@ CONFIG += $$ANDROID_PLATFORM QMAKE_CFLAGS = -D__ANDROID_API__=$$replace(ANDROID_PLATFORM, "android-", "") ANDROID_PLATFORM_ROOT_PATH = $$NDK_ROOT/platforms/$$ANDROID_PLATFORM/arch-$$ANDROID_ARCHITECTURE/ -ANDROID_PLATFORM_PATH = $$ANDROID_PLATFORM_ROOT_PATH/usr - -equals(ANDROID_TARGET_ARCH, x86_64)|equals(ANDROID_TARGET_ARCH, mips64): \ - QMAKE_ANDROID_PLATFORM_LIBDIR = $${QMAKE_ANDROID_PLATFORM_LIBDIR}64 CROSS_COMPILE = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX- diff --git a/mkspecs/common/android-base-tail.conf b/mkspecs/common/android-base-tail.conf index e239fa01c5..57f009f78f 100644 --- a/mkspecs/common/android-base-tail.conf +++ b/mkspecs/common/android-base-tail.conf @@ -69,7 +69,6 @@ QMAKE_LIBDIR_OPENGL = QMAKE_LINK_SHLIB = $$QMAKE_LINK QMAKE_LFLAGS = --sysroot=$$ANDROID_PLATFORM_ROOT_PATH -QMAKE_RPATHLINK = $$QMAKE_ANDROID_PLATFORM_LIBDIR QMAKE_LFLAGS_APP = -Wl,--no-undefined -Wl,-z,noexecstack -shared QMAKE_LFLAGS_SHLIB = -Wl,--no-undefined -Wl,-z,noexecstack -shared QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB From 7e27afd88fbc28f767a51e39dda780290f65a7fb Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 11 Oct 2018 14:26:24 +0200 Subject: [PATCH 0366/1650] configure: log -I and -L before doing first library check ... for debugging purposes. this needs to work in every configure run even though the options (currently) come from qtbase's global scope. this is accomplished by automatically injecting the test type dependencies declared in the 'builtins' scope (where they generally make no sense whatsoever, because there are no tests there) into other scopes (the first one that has a test of the particular type, specifically). we do that *after* the scope's own test type deps, so it can do its custom stuff first (it can explicitly activate the required features if it depends on some global stuff). Change-Id: I67317da1b55804d39458bdbcf13d39a3e57a13bf Reviewed-by: Joerg Bornemann Reviewed-by: Oswald Buddenhagen --- mkspecs/features/data/configure.json | 10 ++++++++++ mkspecs/features/qt_configure.prf | 26 ++++++++++++++++++++------ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/mkspecs/features/data/configure.json b/mkspecs/features/data/configure.json index 167c502e82..faa89231a0 100644 --- a/mkspecs/features/data/configure.json +++ b/mkspecs/features/data/configure.json @@ -17,5 +17,15 @@ "list-features": "void", "list-libraries": "void" } + }, + + "testTypeDependencies": { + "library": [ "library-paths" ] + }, + + "features": { + "library-paths": { + "output": [ "libraryPaths" ] + } } } diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index 81b820978a..2cc6b49d3c 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -1156,7 +1156,7 @@ defineTest(qtConfSetupTestTypeDeps) { } } -defineTest(qtConfEnsureTestTypeDeps) { +defineTest(qtConfEnsureTestTypeDepsOne) { depsn = $${currentConfig}.testTypeDependencies.$${1}._KEYS_ !isEmpty($$depsn) { for (dep, $$depsn) { @@ -1170,12 +1170,18 @@ defineTest(qtConfEnsureTestTypeDeps) { fwdsn = $${currentConfig}.testTypeForwards.$${1} !isEmpty($$fwdsn) { for (fwd, $$fwdsn): \ - qtConfEnsureTestTypeDeps($$fwd) + qtConfEnsureTestTypeDepsOne($$fwd) $$fwdsn = export($$fwdsn) } } +defineTest(qtConfEnsureTestTypeDeps) { + qtConfEnsureTestTypeDepsOne($$1) + currentConfig = config.builtins + qtConfEnsureTestTypeDepsOne($$1) +} + defineTest(qtRunSingleTest) { tpfx = $${currentConfig}.tests.$${1} defined($${tpfx}.result, var): \ @@ -1660,6 +1666,11 @@ defineTest(qtConfCheckErrors) { # output generation # +defineTest(qtConfOutput_libraryPaths) { + qtLog("Global lib dirs: [$$val_escape(EXTRA_LIBDIR)] [$$val_escape(QMAKE_DEFAULT_LIBDIRS)]") + qtLog("Global inc dirs: [$$val_escape(EXTRA_INCLUDEPATH)] [$$val_escape(QMAKE_DEFAULT_INCDIRS)]") +} + # qtConfOutputVar(modifier, output, name, value) defineTest(qtConfOutputVar) { modifier = $$1 @@ -2028,6 +2039,9 @@ for(ever) { } configsToProcess = $$subconfigs $$configsToProcess } +# 'builtins' is used for command line parsing and test type dependency +# injection, but its features must not be processed regularly. +allModuleConfigs = $$member(allConfigs, 1, -1) QMAKE_SAVED_ARGS = $$QMAKE_EXTRA_ARGS QMAKE_REDO_CONFIG = false @@ -2036,7 +2050,7 @@ qtConfCheckErrors() !isEmpty(config.input.list-features) { all_ft = - for (currentConfig, allConfigs) { + for (currentConfig, allModuleConfigs) { for (k, $${currentConfig}.features._KEYS_) { pp = $$eval($${currentConfig}.features.$${k}.purpose) !isEmpty(pp) { @@ -2056,7 +2070,7 @@ qtConfCheckErrors() !isEmpty(config.input.list-libraries) { logn() - for (currentConfig, allConfigs) { + for (currentConfig, allModuleConfigs) { !isEmpty($${currentConfig}.exports._KEYS_) { !isEmpty($${currentConfig}.module): \ logn($$eval($${currentConfig}.module):) @@ -2093,7 +2107,7 @@ qtLog("Command line: $$qtSystemQuote($$QMAKE_SAVED_ARGS)") $$QMAKE_REDO_CONFIG: \ qtLog("config.opt: $$qtSystemQuote($$QMAKE_EXTRA_REDO_ARGS)") -for (currentConfig, allConfigs) { +for (currentConfig, allModuleConfigs) { qtConfSetModuleName() qtConfSetupModuleOutputs() # do early checks, mainly to validate the command line @@ -2137,7 +2151,7 @@ CONFIG += qt_conf_tests_allowed logn() logn("Running configuration tests...") -for (currentConfig, allConfigs) { +for (currentConfig, allModuleConfigs) { tdir = $$eval($${currentConfig}.testDir) isEmpty(tdir): tdir = config.tests QMAKE_CONFIG_TESTS_DIR = $$absolute_path($$tdir, $$eval($${currentConfig}.dir)) From bec8b75b8a2a3574053036fa6ce0992176c304f5 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 12 Oct 2018 15:34:36 +0200 Subject: [PATCH 0367/1650] configure: make config.status work for in-source builds on unix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ib2a62e71a88f46836c10b0d9c47da5ad1f98d413 Reviewed-by: Tor Arne Vestbø Reviewed-by: Oswald Buddenhagen --- configure.pri | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.pri b/configure.pri index 64ed6b9ed8..e04a7a24cd 100644 --- a/configure.pri +++ b/configure.pri @@ -1303,6 +1303,7 @@ defineTest(createConfigStatus) { cont = \ "$$system_quote($$system_path($$cfg)$$ext) -redo %*" } else { + !contains(cfg, .*/.*): cfg = ./$$cfg cont = \ "$${LITERAL_HASH}!/bin/sh" \ "exec $$system_quote($$cfg) -redo \"$@\"" From 6bea0398eadb08c69727dd2ec8919aa4e5f98b07 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 12 Oct 2018 15:51:38 +0200 Subject: [PATCH 0368/1650] configure: fix bogus message about not needing to install qt when building additional modules against an already installed qtbase, $$[QT_INSTALL_PREFIX/get] is obviously the same as $$[QT_INSTALL_PREFIX], so we would misdiagnose a non-prefix build. instead, use the same condition as qt_build_config.prf (we cannot just rely on what it sets, because in qtbase configure context it's evaluated before we set up the paths). Fixes: QTBUG-60541 Change-Id: I37be30e0e682ece76ed460a66f1984ee0fe2ed71 Reviewed-by: Thiago Macieira Reviewed-by: Oswald Buddenhagen --- mkspecs/features/qt_configure.prf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index 2cc6b49d3c..65ee7df50b 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -2215,7 +2215,7 @@ qtConfPrintReport() logn() logn("Qt is now configured for building. Just run '$$QMAKE_MAKE_NAME'.") pfx = $$[QT_INSTALL_PREFIX] -equals(pfx, $$[QT_INSTALL_PREFIX/get]) { +exists($$pfx/.qmake.cache) { logn("Once everything is built, Qt is installed.") logn("You should NOT run '$$QMAKE_MAKE_NAME install'.") logn("Note that this build cannot be deployed to other machines or devices.") From 4e6a3c7def9b634ccb79a5ba3010d8df0d6fdae3 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 15 Oct 2018 11:02:12 +0200 Subject: [PATCH 0369/1650] configure: fix license determination failure message we don't check for licheck at this stage any more. amends 60e56f167. Change-Id: I4f8d57100796dce99bd605835b25a954a6359d30 Reviewed-by: Kai Koehne --- configure.pri | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/configure.pri b/configure.pri index e04a7a24cd..b3b3e27c44 100644 --- a/configure.pri +++ b/configure.pri @@ -106,8 +106,7 @@ defineReplace(qtConfFunc_licenseCheck) { } } else { !$$hasCommercial: \ - qtConfFatalError("No license files and no licheck executables found." \ - "Cannot proceed. Try re-installing Qt.") + qtConfFatalError("No license files. Cannot proceed. Try re-installing Qt.") commercial = yes } } From ac4dd6e8f6a03bc65cdcfe3749ba2096d5a72727 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 19 Oct 2018 19:23:59 +0200 Subject: [PATCH 0370/1650] wasm: fix location and language of comment Change-Id: I7c9c65d037f808371a778e51d0877ed579ae8b26 Reviewed-by: Lorn Potter --- mkspecs/wasm-emscripten/qmake.conf | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/mkspecs/wasm-emscripten/qmake.conf b/mkspecs/wasm-emscripten/qmake.conf index c3b67310c8..0b72fcf0a8 100644 --- a/mkspecs/wasm-emscripten/qmake.conf +++ b/mkspecs/wasm-emscripten/qmake.conf @@ -28,6 +28,8 @@ EMCC_COMMON_LFLAGS = \ -s \"BINARYEN_METHOD=\'native-wasm\'\" \ -s \"BINARYEN_TRAP_MODE=\'clamp\'\" +# The -s arguments can also be used with release builds, +# but are here in debug for clarity. EMCC_COMMON_LFLAGS_DEBUG = \ $$EMCC_COMMON_LFLAGS \ -s ASSERTIONS=2 \ @@ -38,9 +40,6 @@ EMCC_COMMON_LFLAGS_DEBUG = \ # -s SOCKET_DEBUG \ #print out socket,network data transfer -s GL_DEBUG=1 -# the -s arguments can also be used with release builds -# but here in debug for clarity - QMAKE_COMPILER += emscripten QMAKE_CC = emcc From eea08d376ac5cb35ff03be630923f21f7fa3aecd Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 19 Oct 2018 19:24:34 +0200 Subject: [PATCH 0371/1650] wasm: remove seemingly pointless -s flags these libraries are handled by the configure system. i presume this to be an artifact of an early version. Change-Id: Ieee0554163a9fe296097d09e60a70719beee97b4 Reviewed-by: Lorn Potter --- mkspecs/wasm-emscripten/qmake.conf | 8 -------- 1 file changed, 8 deletions(-) diff --git a/mkspecs/wasm-emscripten/qmake.conf b/mkspecs/wasm-emscripten/qmake.conf index 0b72fcf0a8..e8ad5e18e7 100644 --- a/mkspecs/wasm-emscripten/qmake.conf +++ b/mkspecs/wasm-emscripten/qmake.conf @@ -12,11 +12,6 @@ EMTERP_FLAGS = \ -s ASSERTIONS=1 \ --profiling-funcs -EMCC_COMMON_CFLAGS = \ - -s USE_LIBPNG=1 \ - -s USE_FREETYPE=1 \ - -s USE_ZLIB=1 - EMCC_COMMON_LFLAGS = \ -s WASM=1 \ -s FULL_ES2=1 \ @@ -45,9 +40,6 @@ QMAKE_COMPILER += emscripten QMAKE_CC = emcc QMAKE_CXX = em++ -QMAKE_CFLAGS += $$EMCC_COMMON_CFLAGS -QMAKE_CXXFLAGS += $$EMCC_COMMON_CFLAGS - # Practical debugging setup: # "-g4" preserves function names for stack traces # "-Os" produces reasonably sized binaries From f5f46aaf421b2acbec3569a553973ccda223062c Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 19 Oct 2018 19:26:20 +0200 Subject: [PATCH 0372/1650] wasm: fix qmake variable names for optimization flags Change-Id: I43c0a94312504948c0db390994656d5f655c8d4c Reviewed-by: Lorn Potter --- mkspecs/wasm-emscripten/qmake.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mkspecs/wasm-emscripten/qmake.conf b/mkspecs/wasm-emscripten/qmake.conf index e8ad5e18e7..7090fa65dc 100644 --- a/mkspecs/wasm-emscripten/qmake.conf +++ b/mkspecs/wasm-emscripten/qmake.conf @@ -54,8 +54,8 @@ QMAKE_CXXFLAGS_RELEASE += -O3 QMAKE_CFLAGS_RELEASE -= -O2 QMAKE_CFLAGS_RELEASE += -O3 QMAKE_LFLAGS_RELEASE += -O3 -MAKE_CFLAGS_OPTIMIZE += -O3 -MAKE_CFLAGS_OPTIMIZE_FULL += -Oz +QMAKE_CFLAGS_OPTIMIZE += -O3 +QMAKE_CFLAGS_OPTIMIZE_FULL += -Oz QMAKE_LINK = $$QMAKE_CXX QMAKE_LINK_SHLIB = $$QMAKE_CXX From 54dabdd1e831491359e85fae444ab3ec700a0d2b Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 29 Oct 2018 17:04:38 +0100 Subject: [PATCH 0373/1650] wasm: fix qpa plugin build system integration fix the plugin name (it was missing the leading 'q') and the name used in configure (the latter making it unnecessary to mess with it in the mkspec). the qt.prf override which forced linkage of the plugin is also removed due to being completely redundant. Change-Id: I94687a34a295c36754e36a298af902b656ba2ecc Reviewed-by: Kyle Edwards Reviewed-by: Lorn Potter --- mkspecs/features/wasm/qt.prf | 12 ------------ mkspecs/wasm-emscripten/qmake.conf | 3 --- src/gui/configure.pri | 2 +- src/plugins/platforms/wasm/wasm.pro | 2 +- 4 files changed, 2 insertions(+), 17 deletions(-) delete mode 100644 mkspecs/features/wasm/qt.prf diff --git a/mkspecs/features/wasm/qt.prf b/mkspecs/features/wasm/qt.prf deleted file mode 100644 index 9b9b58d3de..0000000000 --- a/mkspecs/features/wasm/qt.prf +++ /dev/null @@ -1,12 +0,0 @@ - -qt_depends = $$resolve_depends(QT, "QT.") -equals(TEMPLATE, app):contains(qt_depends, gui(-private)?) { - LIBS *= -L$$[QT_INSTALL_PLUGINS/get]/platforms - - lib_name = wasm - lib_path_and_base = $$[QT_INSTALL_PLUGINS/get]/platforms/lib$${lib_name}$$qtPlatformTargetSuffix() - LIBS += -l$${lib_name}$$qtPlatformTargetSuffix() $$fromfile($${lib_path_and_base}.prl, QMAKE_PRL_LIBS) -} - -load(qt) - diff --git a/mkspecs/wasm-emscripten/qmake.conf b/mkspecs/wasm-emscripten/qmake.conf index 7090fa65dc..2539770b51 100644 --- a/mkspecs/wasm-emscripten/qmake.conf +++ b/mkspecs/wasm-emscripten/qmake.conf @@ -75,7 +75,4 @@ QMAKE_EXTENSION_STATICLIB = a # llvm bitcode QMAKE_AR = emar cqs QMAKE_DISTCLEAN += *.html *.js *.wasm -QT_QPA_DEFAULT_PLATFORM = wasm - -QTPLUGIN.platforms = wasm load(qt_config) diff --git a/src/gui/configure.pri b/src/gui/configure.pri index 2971fd136e..e21489ec28 100644 --- a/src/gui/configure.pri +++ b/src/gui/configure.pri @@ -55,7 +55,7 @@ defineTest(qtConfTest_qpaDefaultPlatform) { else: qnx: name = qnx else: integrity: name = integrityfb else: haiku: name = haiku - else: wasm: name = webassembly + else: wasm: name = wasm else: name = xcb $${1}.value = $$name diff --git a/src/plugins/platforms/wasm/wasm.pro b/src/plugins/platforms/wasm/wasm.pro index f1205702ef..eaaba53aa2 100644 --- a/src/plugins/platforms/wasm/wasm.pro +++ b/src/plugins/platforms/wasm/wasm.pro @@ -1,4 +1,4 @@ -TARGET = wasm +TARGET = qwasm CONFIG += static plugin QT += \ core-private gui-private \ From b1d6f64a94daef5ef3ca122246827818d1f12bba Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 29 Oct 2018 17:11:17 +0100 Subject: [PATCH 0374/1650] integrity: don't mess with QTPLUGIN.platforms this is an exclusively user-controllable variable. the mkspec may provide a default via QT_QPA_DEFAULT_PLATFORM when it deviates from the platform default known to configure, and these specs actually already make use of that. Change-Id: I7531063d4c404ebed7b2cc1647c61626db30daef Reviewed-by: Kyle Edwards Reviewed-by: Laszlo Agocs --- mkspecs/integrity-armv7-imx6/qmake.conf | 1 - mkspecs/integrity-armv7/qmake.conf | 2 -- mkspecs/integrity-armv8-rcar/qmake.conf | 1 - mkspecs/integrity-x86/qmake.conf | 2 -- 4 files changed, 6 deletions(-) diff --git a/mkspecs/integrity-armv7-imx6/qmake.conf b/mkspecs/integrity-armv7-imx6/qmake.conf index 3bf2abd844..eed6d41d35 100644 --- a/mkspecs/integrity-armv7-imx6/qmake.conf +++ b/mkspecs/integrity-armv7-imx6/qmake.conf @@ -6,7 +6,6 @@ include(../common/ghs-integrity-armv7.conf) DEFINES += QT_STATICPLUGIN -QTPLUGIN.platforms += qeglfs qeglfs-viv-integration QT_QPA_DEFAULT_PLATFORM = eglfs QMAKE_LIBS_EGL += -lEGL -lGAL -lVSC -lGLSLC -lGLESv2 -lfbdev -livfs diff --git a/mkspecs/integrity-armv7/qmake.conf b/mkspecs/integrity-armv7/qmake.conf index 7a2ffaba14..002c8b544e 100644 --- a/mkspecs/integrity-armv7/qmake.conf +++ b/mkspecs/integrity-armv7/qmake.conf @@ -5,5 +5,3 @@ include(../common/ghs-integrity-armv7.conf) DEFINES += QT_STATICPLUGIN - -QTPLUGIN.platforms += integrityfb diff --git a/mkspecs/integrity-armv8-rcar/qmake.conf b/mkspecs/integrity-armv8-rcar/qmake.conf index 46091f6a91..2dbe924086 100644 --- a/mkspecs/integrity-armv8-rcar/qmake.conf +++ b/mkspecs/integrity-armv8-rcar/qmake.conf @@ -11,7 +11,6 @@ DEFINES += INTEGRITY # parameter types as Symbian. The parameter types are defined in eglplatform.h. DEFINES += __WINSCW__ -QTPLUGIN.platforms += qeglfs QT_QPA_DEFAULT_PLATFORM = eglfs QMAKE_LIBS_EGL += -lEGL -lIMGegl -lsrv_um -lsrv_init -lpvrWSEGL_WM -lncg_usr.a -lmmgr_usr -lwm_usr -lprr_usr diff --git a/mkspecs/integrity-x86/qmake.conf b/mkspecs/integrity-x86/qmake.conf index 13d4a6c082..9e3569d15c 100644 --- a/mkspecs/integrity-x86/qmake.conf +++ b/mkspecs/integrity-x86/qmake.conf @@ -6,5 +6,3 @@ include(../common/ghs-integrity-x86.conf) QMAKE_CFLAGS += -cpu=Corei DEFINES += QT_STATICPLUGIN - -QTPLUGIN.platforms += integrityfb From 364337a27fce1fdc85f2ddece60bd3412060b79b Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 15 Nov 2018 10:55:23 +0100 Subject: [PATCH 0375/1650] Remove duplicated documentation from package_manifest.prf Descriptions for WINRT_MANIFEST's subkeys are in the documentation. Having a copy in the prf file is superfluous and is likely to run out of sync at some point. Change-Id: Icea49854981990139305f6dc4e73d1b9dcb01dd5 Reviewed-by: Oliver Wolff Reviewed-by: Oswald Buddenhagen --- mkspecs/features/winrt/package_manifest.prf | 29 +-------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/mkspecs/features/winrt/package_manifest.prf b/mkspecs/features/winrt/package_manifest.prf index d850254dcf..143b884dbf 100644 --- a/mkspecs/features/winrt/package_manifest.prf +++ b/mkspecs/features/winrt/package_manifest.prf @@ -5,34 +5,7 @@ # Afterwards, they can override the default template by assigning their template to WINRT_MANIFEST. # # All subkeys in WINRT_MANIFEST will be replaced if defined/found, so new variables can be easily -# added. The following keys have default values and are present in the default templates: -# WINRT_MANIFEST: The name of the input manifest file. Defaults to a file defined by the mkspec. -# WINRT_MANIFEST.target: The name of the target (.exe). Defaults to TARGET. -# WINRT_MANIFEST.identity: The unique ID of the app. Defaults to reusing the existing generated manifest's UUID, or generates a new UUID if none is present. -# WINRT_MANIFEST.name: The name of the package as displayed to the user. Defaults to TARGET. -# WINRT_MANIFEST.architecture: The target architecture. Defaults to VCPROJ_ARCH. -# WINRT_MANIFEST.version: The version number of the package. Defaults to "1.0.0.0". -# WINRT_MANIFEST.publisher: Display name of the publisher. Defaults to "Default publisher display name". -# WINRT_MANIFEST.publisher_id: The publisher's distinguished name (default: CN=MyCN). -# WINRT_MANIFEST.phone_product_id: The GUID of the product. Defaults to the value of WINRT_MANIFEST.identity. (Windows Phone only) -# WINRT_MANIFEST.phone_publisher_id: The GUID of the publisher. Defaults to an invalid GUID. (Windows Phone only) -# WINRT_MANIFEST.description: Package description. Defaults to "Default package description". -# WINRT_MANIFEST.background: Tile background color. Defaults to "green". -# WINRT_MANIFEST.foreground: Tile foreground (text) color (Windows 8/RT only). Defaults to "light". -# WINRT_MANIFEST.logo_store: Logo image file for Windows Store. Default provided by the mkspec. -# WINRT_MANIFEST.logo_small: Small logo image file. Default provided by the mkspec. -# WINRT_MANIFEST.logo_medium: Medium logo image file. Default provided by the mkspec. -# WINRT_MANIFEST.logo_large: Large logo image file. Default provided by the mkspec. -# WINRT_MANIFEST.splash_screen: Splash screen image file. Default provided by the mkspec. -# WINRT_MANIFEST.rotation_preference: Orientation specification. Default is empty. (portrait, landscape, landscapeFlipped) -# WINRT_MANIFEST.iconic_tile_icon: Image file for the "iconic" tile template icon. Default provided by the mkspec. -# WINRT_MANIFEST.iconic_tile_small: Image file for the small "iconic" tile template logo. Default provided by the mkspec. -# WINRT_MANIFEST.default_language: Specifies the default language of the application -# WINRT_MANIFEST.capabilities: Specifies capabilities to add to the capability list. -# WINRT_MANIFEST.capabilities_device: Specifies device capabilities to add to the capability list. (location, webcam...) -# WINRT_MANIFEST.dependencies: Specifies dependencies required by the package. -# WINRT_MANIFEST.minVersion: Specifies the minimum required Windows version to run the package. Defaults to %UCRTVersion% -# WINRT_MANIFEST.maxVersionTested: Specifies the maximum Windows version the package has been tested against. Defaults to WINRT_MANIFEST.minVersion +# added. # The manifest is generated for each build pass for normal apps, and only once for vcapps. # - Normal apps have their package root directory in the same place as the target (one for each build pass). From e71b640f3cde7e748f962240489888325accbfeb Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Wed, 21 Nov 2018 15:19:50 +0100 Subject: [PATCH 0376/1650] Fix crash when painting with pattern brush to print device on macOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CGContextRelease was called twice, both manual and from the destructor of QMacCGContext. Change-Id: Icba7dcda37af7e1f7c72937b3dd2d2cc4ea22c63 Fixes: QTBUG-71934 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qpaintengine_mac.mm | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qpaintengine_mac.mm b/src/plugins/platforms/cocoa/qpaintengine_mac.mm index ce7f92f2c7..5c880b1cad 100644 --- a/src/plugins/platforms/cocoa/qpaintengine_mac.mm +++ b/src/plugins/platforms/cocoa/qpaintengine_mac.mm @@ -313,7 +313,6 @@ static void qt_mac_draw_pattern(void *info, CGContextRef c) } pat->image = qt_mac_create_imagemask(pm, pm.rect()); CGImageRelease(swatch); - CGContextRelease(pm_ctx); w *= QMACPATTERN_MASK_MULTIPLIER; h *= QMACPATTERN_MASK_MULTIPLIER; #endif From c02d579c567a9e0413801aad87d3ecc9710ed2b2 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 21 Nov 2018 14:26:58 +0100 Subject: [PATCH 0377/1650] Remove usage of win32-msvc2012 qmake scope We don't support MSVC 2012 anymore. Change-Id: I454ba0f8e893f5910a17e473ab7cf70a1c581e81 Reviewed-by: Oliver Wolff --- tests/auto/corelib/kernel/qmetatype/qmetatype.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/corelib/kernel/qmetatype/qmetatype.pro b/tests/auto/corelib/kernel/qmetatype/qmetatype.pro index d70befecfd..56b8c071c3 100644 --- a/tests/auto/corelib/kernel/qmetatype/qmetatype.pro +++ b/tests/auto/corelib/kernel/qmetatype/qmetatype.pro @@ -10,7 +10,7 @@ msvc|winrt { # Prevents "fatal error C1128: number of sections exceeded object file format limit". QMAKE_CXXFLAGS += /bigobj # Reduce compile time - win32-msvc2012|winrt { + winrt { QMAKE_CXXFLAGS_RELEASE -= -O2 QMAKE_CFLAGS_RELEASE -= -O2 } From 755521aba6d63fc572b5b3ee43193ea24a2d5513 Mon Sep 17 00:00:00 2001 From: Andrew Smolko Date: Thu, 8 Nov 2018 18:18:55 +0300 Subject: [PATCH 0378/1650] Fix hang in QMacPasteboard::formats() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PasteboardGetItemCount() can return -1 as result to unsigned variable, so the further loop will iterate "forever". Return early to avoid hang. Change-Id: Ie91dba1c193d04513f0496d20bd0b6b0b5b6c151 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qmacclipboard.mm | 28 ++++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/plugins/platforms/cocoa/qmacclipboard.mm b/src/plugins/platforms/cocoa/qmacclipboard.mm index f3467fdc73..3a39e32fb5 100644 --- a/src/plugins/platforms/cocoa/qmacclipboard.mm +++ b/src/plugins/platforms/cocoa/qmacclipboard.mm @@ -49,6 +49,7 @@ #include #include #include "qcocoahelpers.h" +#include QT_BEGIN_NAMESPACE @@ -61,6 +62,23 @@ QT_BEGIN_NAMESPACE QMacPasteboard code *****************************************************************************/ +namespace +{ +OSStatus PasteboardGetItemCountSafe(PasteboardRef paste, ItemCount *cnt) +{ + Q_ASSERT(paste); + Q_ASSERT(cnt); + const OSStatus result = PasteboardGetItemCount(paste, cnt); + // Despite being declared unsigned, this API can return -1 + if (std::make_signed::type(*cnt) < 0) + *cnt = 0; + return result; +} +} // namespace + +// Ensure we don't call the broken one later on +#define PasteboardGetItemCount + class QMacMimeData : public QMimeData { public: @@ -210,7 +228,7 @@ QMacPasteboard::hasOSType(int c_flavor) const sync(); ItemCount cnt = 0; - if (PasteboardGetItemCount(paste, &cnt) || !cnt) + if (PasteboardGetItemCountSafe(paste, &cnt) || !cnt) return false; #ifdef DEBUG_PASTEBOARD @@ -257,7 +275,7 @@ QMacPasteboard::hasFlavor(QString c_flavor) const sync(); ItemCount cnt = 0; - if (PasteboardGetItemCount(paste, &cnt) || !cnt) + if (PasteboardGetItemCountSafe(paste, &cnt) || !cnt) return false; #ifdef DEBUG_PASTEBOARD @@ -374,7 +392,7 @@ QMacPasteboard::formats() const QStringList ret; ItemCount cnt = 0; - if (PasteboardGetItemCount(paste, &cnt) || !cnt) + if (PasteboardGetItemCountSafe(paste, &cnt) || !cnt) return ret; #ifdef DEBUG_PASTEBOARD @@ -417,7 +435,7 @@ QMacPasteboard::hasFormat(const QString &format) const sync(); ItemCount cnt = 0; - if (PasteboardGetItemCount(paste, &cnt) || !cnt) + if (PasteboardGetItemCountSafe(paste, &cnt) || !cnt) return false; #ifdef DEBUG_PASTEBOARD @@ -460,7 +478,7 @@ QMacPasteboard::retrieveData(const QString &format, QVariant::Type) const sync(); ItemCount cnt = 0; - if (PasteboardGetItemCount(paste, &cnt) || !cnt) + if (PasteboardGetItemCountSafe(paste, &cnt) || !cnt) return QByteArray(); #ifdef DEBUG_PASTEBOARD From eef9b4f0d5c3582364e327eca302f9499dffeea3 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 21 Nov 2018 14:18:28 +0100 Subject: [PATCH 0379/1650] Use msvc qmake scope where appropriate Use 'msvc' instead of 'win32-msvc' or even 'win32-mscv*'. Change-Id: I21dc7748a4019119066aea0a88a29a61827f9429 Reviewed-by: Oliver Wolff Reviewed-by: Thiago Macieira Reviewed-by: Edward Welbourne --- src/winmain/winmain.pro | 8 ++++---- tests/auto/corelib/plugin/qlibrary/lib/lib.pro | 2 +- tests/auto/corelib/plugin/qlibrary/lib2/lib2.pro | 2 +- tests/auto/corelib/plugin/qpluginloader/lib/lib.pro | 2 +- tests/auto/corelib/tools/qdatetime/qdatetime.pro | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/winmain/winmain.pro b/src/winmain/winmain.pro index 4140ae48de..61e9f29d23 100644 --- a/src/winmain/winmain.pro +++ b/src/winmain/winmain.pro @@ -12,10 +12,10 @@ DEFINES += QT_NO_FOREACH qtConfig(debug_and_release): CONFIG += build_all -win32-msvc*:QMAKE_CFLAGS_DEBUG -= -Zi -win32-msvc*:QMAKE_CXXFLAGS_DEBUG -= -Zi -win32-msvc*:QMAKE_CFLAGS_DEBUG *= -Z7 -win32-msvc*:QMAKE_CXXFLAGS_DEBUG *= -Z7 +msvc: QMAKE_CFLAGS_DEBUG -= -Zi +msvc: QMAKE_CXXFLAGS_DEBUG -= -Zi +msvc: QMAKE_CFLAGS_DEBUG *= -Z7 +msvc: QMAKE_CXXFLAGS_DEBUG *= -Z7 mingw: DEFINES += QT_NEEDS_QMAIN winrt { diff --git a/tests/auto/corelib/plugin/qlibrary/lib/lib.pro b/tests/auto/corelib/plugin/qlibrary/lib/lib.pro index 3e15861021..c44cd46597 100644 --- a/tests/auto/corelib/plugin/qlibrary/lib/lib.pro +++ b/tests/auto/corelib/plugin/qlibrary/lib/lib.pro @@ -6,7 +6,7 @@ TARGET = mylib DESTDIR = ../ QT = core -win32-msvc: DEFINES += WIN32_MSVC +msvc: DEFINES += WIN32_MSVC # This project is testdata for tst_qlibrary target.path = $$[QT_INSTALL_TESTS]/tst_qlibrary diff --git a/tests/auto/corelib/plugin/qlibrary/lib2/lib2.pro b/tests/auto/corelib/plugin/qlibrary/lib2/lib2.pro index bd73227b3d..bfda0e0194 100644 --- a/tests/auto/corelib/plugin/qlibrary/lib2/lib2.pro +++ b/tests/auto/corelib/plugin/qlibrary/lib2/lib2.pro @@ -7,7 +7,7 @@ DESTDIR = ../ VERSION = 2 QT = core -win32-msvc: DEFINES += WIN32_MSVC +msvc: DEFINES += WIN32_MSVC # Force a copy of the library to have an extension that is non-standard. # We want to test if we can load a shared library with *any* filename... diff --git a/tests/auto/corelib/plugin/qpluginloader/lib/lib.pro b/tests/auto/corelib/plugin/qpluginloader/lib/lib.pro index 44b71e6e99..9fc76a4201 100644 --- a/tests/auto/corelib/plugin/qpluginloader/lib/lib.pro +++ b/tests/auto/corelib/plugin/qpluginloader/lib/lib.pro @@ -7,7 +7,7 @@ DESTDIR = ../bin winrt:include(../winrt.pri) QT = core -win32-msvc: DEFINES += WIN32_MSVC +msvc: DEFINES += WIN32_MSVC # This is testdata for the tst_qpluginloader test. target.path = $$[QT_INSTALL_TESTS]/tst_qpluginloader/bin diff --git a/tests/auto/corelib/tools/qdatetime/qdatetime.pro b/tests/auto/corelib/tools/qdatetime/qdatetime.pro index ba36621cf1..742eb47075 100644 --- a/tests/auto/corelib/tools/qdatetime/qdatetime.pro +++ b/tests/auto/corelib/tools/qdatetime/qdatetime.pro @@ -5,7 +5,7 @@ SOURCES = tst_qdatetime.cpp # For some reason using optimization here triggers a compiler issue, which causes an exception # However, the code is correct -win32-msvc|win32-msvc9x { +msvc { !build_pass:message ( "Compiler issue, removing -O1 flag" ) QMAKE_CFLAGS_RELEASE -= -O1 QMAKE_CXXFLAGS_RELEASE -= -O1 From a90694d1a60f30ec2abffbfa9e8c7a336c45e736 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Thu, 8 Nov 2018 13:09:25 +0100 Subject: [PATCH 0380/1650] syncqt: Do not clean header directory before "-minimal" run It is possible that "syncqt -minimal" is run after a module's initial run (for example if a host tool relies on a module, but cannot use it directly and thus adds minimal_syncqt to its .pro file). In this case, the old directory content should not be wiped. Fixes: QTBUG-59319 Change-Id: I83767eff0ef74bcefae5efa9b18b7ab3724138e5 Reviewed-by: Oswald Buddenhagen --- bin/syncqt.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/syncqt.pl b/bin/syncqt.pl index 77ce90c164..972717efcf 100755 --- a/bin/syncqt.pl +++ b/bin/syncqt.pl @@ -941,7 +941,7 @@ foreach my $lib (@modules_to_sync) { my %master_contents = (); #remove the old files - if($remove_stale) { + if ($remove_stale && !$minimal) { my %injections = (); for my $p (keys %inject_headers) { next unless ($p =~ /^\Q$dir\E(\/|$)/); From 14984bd59affd3d7f14bf8f67b58b7a87957ead6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 21 Nov 2018 15:47:18 +0100 Subject: [PATCH 0381/1650] macOS: Don't assume platform input context is our own A plugin (such as the Qt virtual keyboard) may provide a platform input context. Change-Id: I349ac6c4b96a3536bcde0d44a785cb7bb989fcc6 Fixes: QTBUG-68328 Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qnsview_complextext.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qnsview_complextext.mm b/src/plugins/platforms/cocoa/qnsview_complextext.mm index d357082d33..6ff9b26ca4 100644 --- a/src/plugins/platforms/cocoa/qnsview_complextext.mm +++ b/src/plugins/platforms/cocoa/qnsview_complextext.mm @@ -307,8 +307,8 @@ { Q_UNUSED(textInputContextKeyboardSelectionDidChangeNotification) if (([NSApp keyWindow] == self.window) && self.window.firstResponder == self) { - QCocoaInputContext *ic = qobject_cast(QCocoaIntegration::instance()->inputContext()); - ic->updateLocale(); + if (QCocoaInputContext *ic = qobject_cast(QCocoaIntegration::instance()->inputContext())) + ic->updateLocale(); } } From 7c93f1cf5d31cb1031fa52a0a610916e4f996457 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 9 Nov 2018 18:03:18 +0100 Subject: [PATCH 0382/1650] Remove macOS specific path that causes reverse vertical advance This special case of macOS appears to be outdated and now causes a bug. Change-Id: Ie9c074bb69eda7abfe3d123f807b517334cc2958 Fixes: QTBUG-69803 Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Konstantin Ritt --- src/gui/text/qharfbuzzng.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/gui/text/qharfbuzzng.cpp b/src/gui/text/qharfbuzzng.cpp index 36bd81c76b..21f880e7be 100644 --- a/src/gui/text/qharfbuzzng.cpp +++ b/src/gui/text/qharfbuzzng.cpp @@ -686,11 +686,7 @@ _hb_qt_font_create(QFontEngine *fe) const int x_ppem = (fe->fontDef.pixelSize * fe->fontDef.stretch) / 100; hb_font_set_funcs(font, hb_qt_get_font_funcs(), (void *)fe, NULL); -#ifdef Q_OS_MAC - hb_font_set_scale(font, QFixed(x_ppem).value(), QFixed(y_ppem).value()); -#else hb_font_set_scale(font, QFixed(x_ppem).value(), -QFixed(y_ppem).value()); -#endif hb_font_set_ppem(font, x_ppem, y_ppem); return font; From cbac5a1a6edfd0d7a1e351bbe50bab118d1155e5 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Tue, 13 Nov 2018 10:42:14 +0100 Subject: [PATCH 0383/1650] QLocalSocket (windows) - remove broken setErrorString MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We report two types of errors - those found by our code and errors coming from the OS. setErrorString(), despite its name, does not just set a string, but extracts a windows error code via GetLastError() and then calls _q_winError(). This is wrong: some arbitrary error code (or no error) can be reported when it was actually an error found by Qt. Worse yet, string operations (allocations etc.) can potentially clear the real error code. So remove setErrorString(), set errors explicitly if it's the application code error or use _q_WinError directly. Task-number: QTBUG-71744 Change-Id: I67277d84006c4ad365f5636caf850e1f3ba4e1dc Reviewed-by: Edward Welbourne Reviewed-by: Mårten Nordheim Reviewed-by: Timur Pocheptsov --- src/network/socket/qlocalsocket_p.h | 1 - src/network/socket/qlocalsocket_win.cpp | 16 ++++++---------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/network/socket/qlocalsocket_p.h b/src/network/socket/qlocalsocket_p.h index 8b72da397f..d93b53be0c 100644 --- a/src/network/socket/qlocalsocket_p.h +++ b/src/network/socket/qlocalsocket_p.h @@ -131,7 +131,6 @@ public: #elif defined(Q_OS_WIN) ~QLocalSocketPrivate(); void destroyPipeHandles(); - void setErrorString(const QString &function); void _q_canWrite(); void _q_pipeClosed(); void _q_winError(ulong windowsError, const QString &function); diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp index 8e20f9efbe..d6ee76043f 100644 --- a/src/network/socket/qlocalsocket_win.cpp +++ b/src/network/socket/qlocalsocket_win.cpp @@ -50,12 +50,6 @@ void QLocalSocketPrivate::init() q->connect(pipeReader, SIGNAL(winError(ulong,QString)), SLOT(_q_winError(ulong,QString))); } -void QLocalSocketPrivate::setErrorString(const QString &function) -{ - DWORD windowsError = GetLastError(); - _q_winError(windowsError, function); -} - void QLocalSocketPrivate::_q_winError(ulong windowsError, const QString &function) { Q_Q(QLocalSocket); @@ -127,7 +121,8 @@ void QLocalSocket::connectToServer(OpenMode openMode) { Q_D(QLocalSocket); if (state() == ConnectedState || state() == ConnectingState) { - setErrorString(tr("Trying to connect while connection is in progress")); + d->error = OperationError; + d->errorString = tr("Trying to connect while connection is in progress"); emit error(QLocalSocket::OperationError); return; } @@ -137,8 +132,8 @@ void QLocalSocket::connectToServer(OpenMode openMode) d->state = ConnectingState; emit stateChanged(d->state); if (d->serverName.isEmpty()) { - d->error = QLocalSocket::ServerNotFoundError; - setErrorString(QLocalSocket::tr("%1: Invalid name").arg(QLatin1String("QLocalSocket::connectToServer"))); + d->error = ServerNotFoundError; + d->errorString = tr("%1: Invalid name").arg(QLatin1String("QLocalSocket::connectToServer")); d->state = UnconnectedState; emit error(d->error); emit stateChanged(d->state); @@ -177,7 +172,8 @@ void QLocalSocket::connectToServer(OpenMode openMode) } if (localSocket == INVALID_HANDLE_VALUE) { - d->setErrorString(QLatin1String("QLocalSocket::connectToServer")); + const DWORD winError = GetLastError(); + d->_q_winError(winError, QLatin1String("QLocalSocket::connectToServer")); d->fullServerName = QString(); return; } From 4538dd7ec4efcce5760f87dc1751b142b8f35479 Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Mon, 12 Nov 2018 13:17:40 +0100 Subject: [PATCH 0384/1650] Remove need for glXGetProcAddressARB We do already require glXGetProcAddress in line 241. Fixes: QTBUG-71488 Change-Id: Id0f3bc256a71097241b99d2dcba927c1165e980e Reviewed-by: Gatis Paeglis --- .../xcb_glx/qglxintegration.cpp | 43 +------------------ 1 file changed, 1 insertion(+), 42 deletions(-) diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp index 2ffb5d2629..ddb8f45188 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp @@ -38,9 +38,6 @@ ****************************************************************************/ #include -#if QT_CONFIG(library) -#include -#endif #include "qxcbwindow.h" #include "qxcbscreen.h" @@ -61,10 +58,6 @@ #include "qxcbglintegration.h" -#if !defined(QT_STATIC) && QT_CONFIG(dlopen) -#include -#endif - QT_BEGIN_NAMESPACE typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*); @@ -627,41 +620,7 @@ void QGLXContext::swapBuffers(QPlatformSurface *surface) QFunctionPointer QGLXContext::getProcAddress(const char *procName) { -#ifdef QT_STATIC - return glXGetProcAddressARB(reinterpret_cast(procName)); -#else - typedef void *(*qt_glXGetProcAddressARB)(const GLubyte *); - static qt_glXGetProcAddressARB glXGetProcAddressARB = 0; - static bool resolved = false; - - if (resolved && !glXGetProcAddressARB) - return 0; - if (!glXGetProcAddressARB) { - QList glxExt = QByteArray(glXGetClientString(m_display, GLX_EXTENSIONS)).split(' '); - if (glxExt.contains("GLX_ARB_get_proc_address")) { -#if QT_CONFIG(dlopen) - void *handle = dlopen(NULL, RTLD_LAZY); - if (handle) { - glXGetProcAddressARB = (qt_glXGetProcAddressARB) dlsym(handle, "glXGetProcAddressARB"); - dlclose(handle); - } - if (!glXGetProcAddressARB) -#endif - { -#if QT_CONFIG(library) - QLibrary lib(QLatin1String("GL")); - if (!lib.load()) - lib.setFileNameAndVersion(QLatin1String("GL"), 1); - glXGetProcAddressARB = (qt_glXGetProcAddressARB) lib.resolve("glXGetProcAddressARB"); -#endif - } - } - resolved = true; - } - if (!glXGetProcAddressARB) - return 0; - return (void (*)())glXGetProcAddressARB(reinterpret_cast(procName)); -#endif + return glXGetProcAddress(reinterpret_cast(procName)); } QSurfaceFormat QGLXContext::format() const From d0fadae79fb63aa4acc036571ecfe9e937fcc56b Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Thu, 15 Nov 2018 11:34:36 +0300 Subject: [PATCH 0385/1650] qnetworkinterface_unix: Use qstrncpy instead of strlcpy strlcpy is not available on some UNIX platforms, such as GNU/kFreeBSD. qstrncpy is available everywhere and has similar semantics (in addition it fills the rest of buffer size with NULL bytes, but that does not cause extra work as our buffer sizes are small). Change-Id: I76c5905eba248fd9fbc1f63f05e88e0617f8407a Reviewed-by: Edward Welbourne Reviewed-by: Thiago Macieira --- src/network/kernel/qnetworkinterface_unix.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/network/kernel/qnetworkinterface_unix.cpp b/src/network/kernel/qnetworkinterface_unix.cpp index d69fc47667..8f290e5107 100644 --- a/src/network/kernel/qnetworkinterface_unix.cpp +++ b/src/network/kernel/qnetworkinterface_unix.cpp @@ -38,6 +38,7 @@ ** ****************************************************************************/ +#include "qbytearray.h" #include "qset.h" #include "qnetworkinterface.h" #include "qnetworkinterface_p.h" @@ -500,7 +501,7 @@ static QList createInterfaces(ifaddrs *rawList) iface->flags = convertFlags(ptr->ifa_flags); iface->hardwareAddress = iface->makeHwAddress(sdl->sdl_alen, (uchar*)LLADDR(sdl)); - strlcpy(mediareq.ifm_name, ptr->ifa_name, sizeof(mediareq.ifm_name)); + qstrncpy(mediareq.ifm_name, ptr->ifa_name, sizeof(mediareq.ifm_name)); iface->type = probeIfType(openSocket(socket), sdl->sdl_type, &mediareq); iface->mtu = getMtu(socket, &req); } @@ -524,7 +525,7 @@ static void getAddressExtraInfo(QNetworkAddressEntry *entry, struct sockaddr *sa return; } - strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + qstrncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); // get flags ifr.ifr_addr = *reinterpret_cast(sa); From 794140fb86b470821e3a298a0ba9c8dbbee202b9 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sat, 17 Nov 2018 14:58:15 +0100 Subject: [PATCH 0386/1650] QGraphicsProxyWidget: Don't crash within setWidget() when a child proxy has no assigned widget QGraphicsProxyWidget::setWidget() is checking if the newly assigned widget is already assigned to a child proxy widget without checking if the child has a widget assigned at all which lead to a nullptr reference if it is not the case. Therefore check if the assigned widget is a valid pointer. Fixes: QTBUG-15442 Change-Id: I006877f99895ca01975bdcad071cfcf90bea22ad Reviewed-by: Friedemann Kleint Reviewed-by: Richard Moe Gustavsen --- src/widgets/graphicsview/qgraphicsproxywidget.cpp | 8 ++++---- .../tst_qgraphicsproxywidget.cpp | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/widgets/graphicsview/qgraphicsproxywidget.cpp b/src/widgets/graphicsview/qgraphicsproxywidget.cpp index 177dbc4871..513cf9d361 100644 --- a/src/widgets/graphicsview/qgraphicsproxywidget.cpp +++ b/src/widgets/graphicsview/qgraphicsproxywidget.cpp @@ -607,20 +607,20 @@ void QGraphicsProxyWidgetPrivate::setWidget_helper(QWidget *newWidget, bool auto for (QGraphicsItem *child : childItems) { if (child->d_ptr->isProxyWidget()) { QGraphicsProxyWidget *childProxy = static_cast(child); - QWidget * parent = childProxy->widget(); - while (parent->parentWidget() != 0) { + QWidget *parent = childProxy->widget(); + while (parent && parent->parentWidget()) { if (parent == widget) break; parent = parent->parentWidget(); } if (!childProxy->widget() || parent != widget) continue; - childProxy->setWidget(0); + childProxy->setWidget(nullptr); delete childProxy; } } - widget = 0; + widget = nullptr; #ifndef QT_NO_CURSOR q->unsetCursor(); #endif diff --git a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp index 49afc5f369..4a301337ef 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp @@ -140,6 +140,7 @@ private slots: void palettePropagation(); void fontPropagation(); void dontCrashWhenDie(); + void dontCrashNoParent(); void createProxyForChildWidget(); #ifndef QT_NO_CONTEXTMENU void actionsContextMenu(); @@ -2964,6 +2965,20 @@ void tst_QGraphicsProxyWidget::dontCrashWhenDie() qDeleteAll(QApplication::topLevelWidgets()); } +void tst_QGraphicsProxyWidget::dontCrashNoParent() // QTBUG-15442 +{ + QGraphicsProxyWidget *parent(new QGraphicsProxyWidget); + QGraphicsProxyWidget *child(new QGraphicsProxyWidget); + QScopedPointer label0(new QLabel); + QScopedPointer label1(new QLabel); + + child->setParentItem(parent); + // Set the first label as the proxied widget. + parent->setWidget(label0.data()); + // If we attempt to change the proxied widget we get a crash. + parent->setWidget(label1.data()); +} + void tst_QGraphicsProxyWidget::createProxyForChildWidget() { QGraphicsScene scene; From 5f49788e3348406f1399e4e911a765f850f5788f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 16 Nov 2018 18:37:01 +0100 Subject: [PATCH 0387/1650] macOS: Allow raising and lowering child windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ic598d200e2f774ced489a37c33b7a02767db4402 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoawindow.mm | 42 +++++++++++---------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 4dc3ea4bd6..df1ad82592 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -897,34 +897,36 @@ void QCocoaWindow::raise() qCDebug(lcQpaWindow) << "QCocoaWindow::raise" << window(); // ### handle spaces (see Qt 4 raise_sys in qwidget_mac.mm) - if (!isContentView()) - return; - - if (m_view.window.visible) { - { - // Clean up autoreleased temp objects from orderFront immediately. - // Failure to do so has been observed to cause leaks also beyond any outer - // autorelease pool (for example around a complete QWindow - // construct-show-raise-hide-delete cyle), counter to expected autoreleasepool - // behavior. - QMacAutoReleasePool pool; - [m_view.window orderFront:m_view.window]; - } - static bool raiseProcess = qt_mac_resolveOption(true, "QT_MAC_SET_RAISE_PROCESS"); - if (raiseProcess) { - [NSApp activateIgnoringOtherApps:YES]; + if (isContentView()) { + if (m_view.window.visible) { + { + // Clean up auto-released temp objects from orderFront immediately. + // Failure to do so has been observed to cause leaks also beyond any outer + // autorelease pool (for example around a complete QWindow + // construct-show-raise-hide-delete cycle), counter to expected autoreleasepool + // behavior. + QMacAutoReleasePool pool; + [m_view.window orderFront:m_view.window]; + } + static bool raiseProcess = qt_mac_resolveOption(true, "QT_MAC_SET_RAISE_PROCESS"); + if (raiseProcess) + [NSApp activateIgnoringOtherApps:YES]; } + } else { + [m_view.superview addSubview:m_view positioned:NSWindowAbove relativeTo:nil]; } } void QCocoaWindow::lower() { qCDebug(lcQpaWindow) << "QCocoaWindow::lower" << window(); - if (!isContentView()) - return; - if (m_view.window.visible) - [m_view.window orderBack:m_view.window]; + if (isContentView()) { + if (m_view.window.visible) + [m_view.window orderBack:m_view.window]; + } else { + [m_view.superview addSubview:m_view positioned:NSWindowBelow relativeTo:nil]; + } } bool QCocoaWindow::isExposed() const From 1931aedcf827f837ce81a58a8f8f0e55d8212df6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 16 Nov 2018 18:41:11 +0100 Subject: [PATCH 0388/1650] macOS: Track changes to our NSView's superview and window properties As a start, we just log the changes, but going forward we can use this to report parent changes to QPA or get rid of old QNSWindows. Change-Id: Id3625fb0b7608d85240f58bdecc70a5892075da3 Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qnsview.mm | 73 +++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 6 deletions(-) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 03c5001270..7f826942f3 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -68,6 +68,8 @@ // Private interface @interface QT_MANGLE_NAMESPACE(QNSView) () - (BOOL)isTransparentForUserInput; +@property (assign) NSView* previousSuperview; +@property (assign) NSWindow* previousWindow; @end @interface QT_MANGLE_NAMESPACE(QNSView) (Drawing) @@ -153,6 +155,9 @@ self.focusRingType = NSFocusRingTypeNone; self.cursor = nil; + self.previousSuperview = nil; + self.previousWindow = nil; + [self initDrawing]; [self registerDragTypes]; @@ -195,8 +200,40 @@ return description; } +// ----------------------------- Re-parenting --------------------------------- + +- (void)removeFromSuperview +{ + QMacAutoReleasePool pool; + [super removeFromSuperview]; +} + +- (void)viewWillMoveToSuperview:(NSView *)newSuperview +{ + Q_ASSERT(!self.previousSuperview); + self.previousSuperview = self.superview; + + if (newSuperview == self.superview) + qCDebug(lcQpaWindow) << "Re-ordering" << self << "inside" << self.superview; + else + qCDebug(lcQpaWindow) << "Re-parenting" << self << "from" << self.superview << "to" << newSuperview; +} + - (void)viewDidMoveToSuperview { + auto cleanup = qScopeGuard([&] { self.previousSuperview = nil; }); + + if (self.superview == self.previousSuperview) { + qCDebug(lcQpaWindow) << "Done re-ordering" << self << "new index:" + << [self.superview.subviews indexOfObject:self]; + return; + } + + qCDebug(lcQpaWindow) << "Done re-parenting" << self << "into" << self.superview; + + // Note: at this point the view's window property hasn't been updated to match the window + // of the new superview. We have to wait for viewDidMoveToWindow for that to be reflected. + if (!m_platformWindow) return; @@ -210,6 +247,36 @@ } } +- (void)viewWillMoveToWindow:(NSWindow *)newWindow +{ + Q_ASSERT(!self.previousWindow); + self.previousWindow = self.window; + + // This callback is documented to be called also when a view is just moved between + // subviews in the same NSWindow, so we're not necessarily moving between NSWindows. + if (newWindow == self.window) + return; + + qCDebug(lcQpaWindow) << "Moving" << self << "from" << self.window << "to" << newWindow; + + // Note: at this point the superview has already been updated, so we know which view inside + // the new window the view will be a child of. +} + +- (void)viewDidMoveToWindow +{ + auto cleanup = qScopeGuard([&] { self.previousWindow = nil; }); + + // This callback is documented to be called also when a view is just moved between + // subviews in the same NSWindow, so we're not necessarily moving between NSWindows. + if (self.window == self.previousWindow) + return; + + qCDebug(lcQpaWindow) << "Done moving" << self << "to" << self.window; +} + +// ---------------------------------------------------------------------------- + - (QWindow *)topLevelWindow { if (!m_platformWindow) @@ -239,12 +306,6 @@ // viewDidUnhide so no reason to override it here. } -- (void)removeFromSuperview -{ - QMacAutoReleasePool pool; - [super removeFromSuperview]; -} - - (BOOL)isTransparentForUserInput { return m_platformWindow->window() && From 52bd707f0d6a585c2f5da9565834eb91f1d3dbc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 16 Nov 2018 20:37:11 +0100 Subject: [PATCH 0389/1650] Improve logging of QWindowContainer operations By explicitly identifying the fake window created for the window container. Change-Id: Id67a6e22588d04e68f5ede09bc078bb387c12e0b Reviewed-by: Richard Moe Gustavsen --- src/widgets/kernel/qwindowcontainer.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/widgets/kernel/qwindowcontainer.cpp b/src/widgets/kernel/qwindowcontainer.cpp index 81916bba90..d2680e5280 100644 --- a/src/widgets/kernel/qwindowcontainer.cpp +++ b/src/widgets/kernel/qwindowcontainer.cpp @@ -227,6 +227,12 @@ QWindowContainer::QWindowContainer(QWindow *embeddedWindow, QWidget *parent, Qt: embeddedWindow->setSurfaceType(QSurface::RasterGLSurface); d->window = embeddedWindow; + + QString windowName = d->window->objectName(); + if (windowName.isEmpty()) + windowName = QString::fromUtf8(d->window->metaObject()->className()); + d->fakeParent.setObjectName(windowName + "ContainerFakeParent"); + d->window->setParent(&d->fakeParent); setAcceptDrops(true); From 736dfc3c63f7d7844d11fe4abd6bcfb1befad3cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sat, 17 Nov 2018 01:26:25 +0100 Subject: [PATCH 0390/1650] Remove unused inRepaint member of QWidgetPrivate The code that used it was removed in 55fa3c189f889 6 years ago. Change-Id: I76e42f147342feb1bda9bc2c5aa882af62757812 Reviewed-by: Richard Moe Gustavsen --- src/widgets/kernel/qwidget.cpp | 6 +----- src/widgets/kernel/qwidget_p.h | 1 - 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index da0d530990..e59fbb8963 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1775,7 +1775,6 @@ void QWidgetPrivate::createTLExtra() x->posIncludesFrame = 0; x->sizeAdjusted = false; x->inTopLevelResize = false; - x->inRepaint = false; x->embedded = 0; x->window = 0; x->shareContext = 0; @@ -11033,11 +11032,8 @@ void QWidgetPrivate::repaint(T r) return; QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData(); - if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) { - tlwExtra->inRepaint = true; + if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) tlwExtra->backingStoreTracker->markDirty(r, q, QWidgetBackingStore::UpdateNow); - tlwExtra->inRepaint = false; - } } /*! diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index c2fc27a9ad..be45c4c868 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -190,7 +190,6 @@ struct QTLWExtra { uint posIncludesFrame : 1; uint sizeAdjusted : 1; uint inTopLevelResize : 1; - uint inRepaint : 1; uint embedded : 1; // *************************** Platform specific values (bit fields first) ********** From 9f6f796a50bf42290d8abbbb08149bd98b1619a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boris=20Du=C5=A1ek?= Date: Sat, 3 Nov 2018 12:58:42 +0100 Subject: [PATCH 0391/1650] Fix VoiceOver interaction with multiline text components MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `convertLineOffset` requires exactly one of `line` and `offset` parameters to be -1. [ChangeLog][macOS][Accessibility] VoiceOver now reads all lines in multiline text components when navigating by lines. Change-Id: I2872c4f5255a33dd2b493b46b22e672eb5779ee8 Fixes: QTBUG-71563 Reviewed-by: Frederik Gladhorn Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index 03dc895ffb..68cf273f32 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -351,6 +351,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of if (QAccessibleTextInterface *text = iface->textInterface()) { int line = 0; // true for all single line edits if (iface->state().multiLine) { + line = -1; int position = text->cursorPosition(); convertLineOffset(text, &line, &position); } From 9dc19d6716f936e8b93a63fb2d27565e43ccb1ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boris=20Du=C5=A1ek?= Date: Sat, 3 Nov 2018 13:59:22 +0100 Subject: [PATCH 0392/1650] qcocoaaccessibilityelement.mm: Document convertLineOffset function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I359768a7cbd4c3e1e11a453a32bb28add891cf20 Reviewed-by: Frederik Gladhorn Reviewed-by: Tor Arne Vestbø --- .../platforms/cocoa/qcocoaaccessibilityelement.mm | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index 68cf273f32..63233a0390 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -51,6 +51,19 @@ QT_USE_NAMESPACE #ifndef QT_NO_ACCESSIBILITY +/** + * Converts between absolute character offsets and line numbers of a + * QAccessibleTextInterface. Works in exactly one of two modes: + * + * - Pass *line == -1 in order to get a line containing character at the given + * *offset + * - Pass *offset == -1 in order to get the offset of first character of the + * given *line + * + * You can optionally also pass non-NULL `start` and `end`, which will in both + * modes be filled with the offset of the first and last characters of the + * relevant line. + */ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *offset, NSUInteger *start = 0, NSUInteger *end = 0) { Q_ASSERT(*line == -1 || *offset == -1); From 6be4a67322403b44a39650f0dd3e6daf7eafe5c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boris=20Du=C5=A1ek?= Date: Sat, 3 Nov 2018 14:30:35 +0100 Subject: [PATCH 0393/1650] Align implementation of LineForIndex with InsertionPointLineNumber MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On macOS, the accessibility implementation of InsertionPointLineNumber currently reflects a fix for issue (QTBUG-49437). While it seems from testing this issue no longer requires such a fix, it still is a nice optimization for single-line edits. So we hereby bring the same optimization to LineForIndex parameterized attribute as well, and makes the code for both attributes consistent. Change-Id: I18b8cc249b6c65a25150f4e503999b04437e0306 Reviewed-by: Frederik Gladhorn Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index 63233a0390..b826e821fc 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -424,8 +424,11 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of int index = [parameter intValue]; if (index < 0 || index > iface->textInterface()->characterCount()) return nil; - int line = -1; - convertLineOffset(iface->textInterface(), &line, &index); + int line = 0; // true for all single line edits + if (iface->state().multiLine) { + line = -1; + convertLineOffset(iface->textInterface(), &line, &index); + } return @(line); } if ([attribute isEqualToString: NSAccessibilityRangeForLineParameterizedAttribute]) { From 18b1dc35e90a6a3946e9e88c8cfa1ced3a00b1fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Boris=20Du=C5=A1ek?= Date: Mon, 5 Nov 2018 10:22:12 +0100 Subject: [PATCH 0394/1650] macOS a11y: Implement AXInsertionPointLineNumber with AXLineForIndex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow DRY and do not repeat implementation of basically the same thing, especially now that the implementation is no longer completely trivial. AXLineForIndex can be considered a primitive attribute, and AXInsertionPointLineNumber a derived attribute, hence this opportunity to not repeat oneself. Change-Id: I64b596d8351e681f4438b91400a767407612c118 Reviewed-by: Frederik Gladhorn Reviewed-by: Tor Arne Vestbø --- .../platforms/cocoa/qcocoaaccessibilityelement.mm | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index b826e821fc..1a3c7793c0 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -362,13 +362,8 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of } else if ([attribute isEqualToString:NSAccessibilityInsertionPointLineNumberAttribute]) { if (QAccessibleTextInterface *text = iface->textInterface()) { - int line = 0; // true for all single line edits - if (iface->state().multiLine) { - line = -1; - int position = text->cursorPosition(); - convertLineOffset(text, &line, &position); - } - return @(line); + int position = text->cursorPosition(); + return [self accessibilityAttributeValue:NSAccessibilityLineForIndexParameterizedAttribute forParameter:@(position)]; } return nil; } else if ([attribute isEqualToString:NSAccessibilityMinValueAttribute]) { From bc1678c618342774be285f24c1e2995c0a0e1600 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Thu, 22 Nov 2018 13:22:34 +0100 Subject: [PATCH 0395/1650] macOS accessibility: fix crash for NSAccessibilityVisibleCharacterRangeAttribute MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VoiceOver or other tools may query this property even when there is no text interface. Make sure not to crash by verifying that the interface is supported. Found while using AccessibilityInspector to verify other changes. Change-Id: If7ee21b7616f091b71e86bab03a871ddbabe9200 Reviewed-by: Jan Arve Sæther --- src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index 03dc895ffb..a1176da33f 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -345,8 +345,9 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of return [NSValue valueWithRange: NSMakeRange(0, 0)]; } else if ([attribute isEqualToString:NSAccessibilityVisibleCharacterRangeAttribute]) { // FIXME This is not correct and may impact performance for big texts - return [NSValue valueWithRange: NSMakeRange(0, iface->textInterface()->characterCount())]; - + if (QAccessibleTextInterface *text = iface->textInterface()) + return [NSValue valueWithRange: NSMakeRange(0, text->characterCount())]; + return [NSValue valueWithRange: NSMakeRange(0, iface->text(QAccessible::Name).length())]; } else if ([attribute isEqualToString:NSAccessibilityInsertionPointLineNumberAttribute]) { if (QAccessibleTextInterface *text = iface->textInterface()) { int line = 0; // true for all single line edits From 6dcc13d4024ed5fd56610c44140aed72e0248a8e Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 19 Nov 2018 19:05:13 +0100 Subject: [PATCH 0396/1650] Make QCOMPARE()'s handling of non-finite float match double The qCompare() implementation for double was handling infinities and NaN the way tests need, but the one for float didn't; it has just the same need, so apply the same fix. Extends 79493a3ee1. Change-Id: I8425026acb61d535e449f579b77fdcd609157f7c Reviewed-by: Thiago Macieira --- src/testlib/qtestcase.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index f5668c274e..1090428bb0 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -2437,7 +2437,16 @@ bool QTest::compare_helper(bool success, const char *failureMsg, bool QTest::qCompare(float const &t1, float const &t2, const char *actual, const char *expected, const char *file, int line) { - return compare_helper(qFuzzyCompare(t1, t2), "Compared floats are not the same (fuzzy compare)", + bool equal = false; + int cl1 = std::fpclassify(t1); + int cl2 = std::fpclassify(t2); + if (cl1 == FP_INFINITE) + equal = ((t1 < 0) == (t2 < 0)) && cl2 == FP_INFINITE; + else if (cl1 == FP_NAN) + equal = (cl2 == FP_NAN); + else + equal = qFuzzyCompare(t1, t2); + return compare_helper(equal, "Compared floats are not the same (fuzzy compare)", toString(t1), toString(t2), actual, expected, file, line); } From 108c9015b960fccd79efc6de4459dbf05f6ced54 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Fri, 16 Nov 2018 14:29:42 +0100 Subject: [PATCH 0397/1650] Implement transient locale as instantiating a class A couple of QLocale tests were using setlocale twice to provide a transient locale tweak in tests; however, if the test in between fails, that can leave the program running in the "transient" locale after. So implement a proper class whose destructor ensures the transient is tidied away. Also change the locale in use by one of these transient changes: it purported to be checking things didn't depend on locale, but was using the same local as most of the test-cases for its test. Change-Id: I0d954edcc96019a8c2eb12b7a7c568e8b87a41d5 Reviewed-by: Thiago Macieira Reviewed-by: Ulf Hermann --- .../corelib/tools/qlocale/tst_qlocale.cpp | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp index b7cb8a1bdc..4803451399 100644 --- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp @@ -153,6 +153,16 @@ private: QString m_decimal, m_thousand, m_sdate, m_ldate, m_time; QString m_sysapp; bool europeanTimeZone; + + class TransientLocale + { + const int m_category; + const char *const m_prior; + public: + TransientLocale(int category, const char *locale) + : m_category(category), m_prior(setlocale(category, locale)) {} + ~TransientLocale() { setlocale(m_category, m_prior); } + }; }; tst_QLocale::tst_QLocale() @@ -806,10 +816,12 @@ void tst_QLocale::stringToDouble() double d = locale.toDouble(num_str, &ok); QCOMPARE(ok, good); - char *currentLocale = setlocale(LC_ALL, "de_DE"); - QCOMPARE(locale.toDouble(num_str, &ok), d); // make sure result is independent of locale - QCOMPARE(ok, good); - setlocale(LC_ALL, currentLocale); + { + // Make sure result is independent of locale: + TransientLocale ignoreme(LC_ALL, "ar_SA"); + QCOMPARE(locale.toDouble(num_str, &ok), d); + QCOMPARE(ok, good); + } if (ok) { double diff = d - num; @@ -939,9 +951,8 @@ void tst_QLocale::doubleToString() const QLocale locale(locale_name); QCOMPARE(locale.toString(num, mode, precision), num_str); - char *currentLocale = setlocale(LC_ALL, "de_DE"); + TransientLocale ignoreme(LC_ALL, "de_DE"); QCOMPARE(locale.toString(num, mode, precision), num_str); - setlocale(LC_ALL, currentLocale); } void tst_QLocale::strtod_data() From 704137f8de49a55a1b21bb6d612d2594562f51ce Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Fri, 16 Nov 2018 15:44:44 +0100 Subject: [PATCH 0398/1650] tst_QLocale: Add tests for toFloat() Mirror those for toDouble(). Change-Id: Ide0ef3cd99528d575f6a578ef19547f3b1119c5d Reviewed-by: Ulf Hermann --- .../corelib/tools/qlocale/tst_qlocale.cpp | 55 ++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp index 4803451399..fa1a64a045 100644 --- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp @@ -83,6 +83,8 @@ private slots: void matchingLocales(); void stringToDouble_data(); void stringToDouble(); + void stringToFloat_data() { stringToDouble_data(); } + void stringToFloat(); void doubleToString_data(); void doubleToString(); void strtod_data(); @@ -801,7 +803,7 @@ void tst_QLocale::stringToDouble_data() void tst_QLocale::stringToDouble() { -#define MY_DOUBLE_EPSILON (2.22045e-16) +#define MY_DOUBLE_EPSILON (2.22045e-16) // 1/2^{52}; double has a 53-bit mantissa QFETCH(QString, locale_name); QFETCH(QString, num_str); @@ -824,6 +826,8 @@ void tst_QLocale::stringToDouble() } if (ok) { + // First use fuzzy-compare, then a more precise check: + QCOMPARE(d, num); double diff = d - num; if (diff < 0) diff = -diff; @@ -834,11 +838,60 @@ void tst_QLocale::stringToDouble() QCOMPARE(ok, good); if (ok) { + QCOMPARE(d, num); double diff = d - num; if (diff < 0) diff = -diff; QVERIFY(diff <= MY_DOUBLE_EPSILON); } +#undef MY_DOUBLE_EPSILON +} + +void tst_QLocale::stringToFloat() +{ +#define MY_FLOAT_EPSILON (2.384e-7) // 1/2^{22}; float has a 23-bit mantissa + + QFETCH(QString, locale_name); + QFETCH(QString, num_str); + QFETCH(bool, good); + QFETCH(double, num); + QStringRef num_strRef = num_str.leftRef(-1); + float fnum = num; + + QLocale locale(locale_name); + QCOMPARE(locale.name(), locale_name); + + bool ok; + float f = locale.toFloat(num_str, &ok); + QCOMPARE(ok, good); + + { + // Make sure result is independent of locale: + TransientLocale ignoreme(LC_ALL, "ar_SA"); + QCOMPARE(locale.toFloat(num_str, &ok), f); + QCOMPARE(ok, good); + } + + if (ok) { + // First use fuzzy-compare, then a more precise check: + QCOMPARE(f, fnum); + float diff = f - fnum; + if (diff < 0) + diff = -diff; + QVERIFY(diff <= MY_FLOAT_EPSILON); + } + + f = locale.toFloat(num_strRef, &ok); + QCOMPARE(ok, good); + + if (ok) { + QCOMPARE(f, fnum); + float diff = f - fnum; + if (diff < 0) + diff = -diff; + QVERIFY(diff <= MY_FLOAT_EPSILON); + } +#undef MY_FLOAT_EPSILON } void tst_QLocale::doubleToString_data() From a9923674030980706940b3ee11145c38674bb35d Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 19 Nov 2018 16:27:03 +0100 Subject: [PATCH 0399/1650] Change documentation of some toDouble()s to reflect reality They actually return infinity if conversion overflows, while still setting ok to false; they were documented to return 0 on failure, with no mention of this special handling of overflow. Documented reality rather than changing the behavior. Gave underflow as an example of failure other than overflow (toDouble()s do indeed fail on it). Added some tests of out-of-range values, infinities and NaNs. [ChangeLog][QtCore][toDouble] QString, QByteArray and QLocale return an infinity on overflow (since 5.7), while setting ok to false; this was at odds with their documented behavior of returning 0 on failure. The documentation now reflects the actual behavior. Fixes: QTBUG-71256 Change-Id: I8d7e80ba1f06091cf0f1480c341553381103703b Reviewed-by: Ulf Hermann --- src/corelib/tools/qbytearray.cpp | 3 +- src/corelib/tools/qlocale.cpp | 18 ++++-- src/corelib/tools/qstring.cpp | 6 +- .../corelib/tools/qlocale/tst_qlocale.cpp | 56 +++++++++++++++---- 4 files changed, 62 insertions(+), 21 deletions(-) diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 424420204a..1b7a4366c7 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -3871,7 +3871,8 @@ ushort QByteArray::toUShort(bool *ok, int base) const /*! Returns the byte array converted to a \c double value. - Returns 0.0 if the conversion fails. + Returns an infinity if the conversion overflows or 0.0 if the + conversion fails for other reasons (e.g. underflow). If \a ok is not \c nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 6361280bc7..8f9fb3de2d 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -1373,8 +1373,10 @@ float QLocale::toFloat(const QString &s, bool *ok) const } /*! - Returns the double represented by the localized string \a s, or - 0.0 if the conversion failed. + Returns the double represented by the localized string \a s. + + Returns an infinity if the conversion overflows or 0.0 if the + conversion fails for any other reason (e.g. underflow). If \a ok is not \c nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. @@ -1542,8 +1544,10 @@ float QLocale::toFloat(const QStringRef &s, bool *ok) const } /*! - Returns the double represented by the localized string \a s, or - 0.0 if the conversion failed. + Returns the double represented by the localized string \a s. + + Returns an infinity if the conversion overflows or 0.0 if the + conversion fails for any other reason (e.g. underflow). If \a ok is not \c nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. @@ -1711,8 +1715,10 @@ float QLocale::toFloat(QStringView s, bool *ok) const } /*! - Returns the double represented by the localized string \a s, or - 0.0 if the conversion failed. + Returns the double represented by the localized string \a s. + + Returns an infinity if the conversion overflows or 0.0 if the + conversion fails for any other reason (e.g. underflow). If \a ok is not \c nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 0a8b2b4238..1381e8c11c 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -7169,7 +7169,8 @@ ushort QString::toUShort(bool *ok, int base) const /*! Returns the string converted to a \c double value. - Returns 0.0 if the conversion fails. + Returns an infinity if the conversion overflows or 0.0 if the + conversion fails for other reasons (e.g. underflow). If \a ok is not \c nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. @@ -11794,7 +11795,8 @@ ushort QStringRef::toUShort(bool *ok, int base) const /*! Returns the string converted to a \c double value. - Returns 0.0 if the conversion fails. + Returns an infinity if the conversion overflows or 0.0 if the + conversion fails for other reasons (e.g. underflow). If \a ok is not \c nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp index fa1a64a045..7bf6d1327e 100644 --- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp @@ -83,7 +83,7 @@ private slots: void matchingLocales(); void stringToDouble_data(); void stringToDouble(); - void stringToFloat_data() { stringToDouble_data(); } + void stringToFloat_data(); void stringToFloat(); void doubleToString_data(); void doubleToString(); @@ -155,6 +155,7 @@ private: QString m_decimal, m_thousand, m_sdate, m_ldate, m_time; QString m_sysapp; bool europeanTimeZone; + void toReal_data(); class TransientLocale { @@ -679,7 +680,7 @@ void tst_QLocale::unixLocaleName() #undef TEST_NAME } -void tst_QLocale::stringToDouble_data() +void tst_QLocale::toReal_data() { QTest::addColumn("locale_name"); QTest::addColumn("num_str"); @@ -801,6 +802,32 @@ void tst_QLocale::stringToDouble_data() QTest::newRow("de_DE 9.876543,0e--2") << QString("de_DE") << QString("9.876543,0e")+QChar(8722)+QString("2") << false << 0.0; } +void tst_QLocale::stringToDouble_data() +{ + toReal_data(); + if (std::numeric_limits::has_infinity) { + double huge = std::numeric_limits::infinity(); + QTest::newRow("C inf") << QString("C") << QString("inf") << true << huge; + QTest::newRow("C +inf") << QString("C") << QString("+inf") << true << +huge; + QTest::newRow("C -inf") << QString("C") << QString("-inf") << true << -huge; + // Overflow: + QTest::newRow("C huge") << QString("C") << QString("2e308") << false << huge; + QTest::newRow("C -huge") << QString("C") << QString("-2e308") << false << -huge; + } + if (std::numeric_limits::has_quiet_NaN) + QTest::newRow("C qnan") << QString("C") << QString("NaN") << true << std::numeric_limits::quiet_NaN(); + + // In range (but outside float's range): + QTest::newRow("C big") << QString("C") << QString("3.5e38") << true << 3.5e38; + QTest::newRow("C -big") << QString("C") << QString("-3.5e38") << true << -3.5e38; + QTest::newRow("C small") << QString("C") << QString("1e-45") << true << 1e-45; + QTest::newRow("C -small") << QString("C") << QString("-1e-45") << true << -1e-45; + + // Underflow: + QTest::newRow("C tiny") << QString("C") << QString("2e-324") << false << 0.; + QTest::newRow("C -tiny") << QString("C") << QString("-2e-324") << false << 0.; +} + void tst_QLocale::stringToDouble() { #define MY_DOUBLE_EPSILON (2.22045e-16) // 1/2^{52}; double has a 53-bit mantissa @@ -825,28 +852,33 @@ void tst_QLocale::stringToDouble() QCOMPARE(ok, good); } - if (ok) { + if (ok || std::isinf(num)) { // First use fuzzy-compare, then a more precise check: QCOMPARE(d, num); - double diff = d - num; - if (diff < 0) - diff = -diff; - QVERIFY(diff <= MY_DOUBLE_EPSILON); + if (std::isfinite(num)) { + double diff = d > num ? d - num : num - d; + QVERIFY(diff <= MY_DOUBLE_EPSILON); + } } d = locale.toDouble(num_strRef, &ok); QCOMPARE(ok, good); - if (ok) { + if (ok || std::isinf(num)) { QCOMPARE(d, num); - double diff = d - num; - if (diff < 0) - diff = -diff; - QVERIFY(diff <= MY_DOUBLE_EPSILON); + if (std::isfinite(num)) { + double diff = d > num ? d - num : num - d; + QVERIFY(diff <= MY_DOUBLE_EPSILON); + } } #undef MY_DOUBLE_EPSILON } +void tst_QLocale::stringToFloat_data() +{ + toReal_data(); +} + void tst_QLocale::stringToFloat() { #define MY_FLOAT_EPSILON (2.384e-7) // 1/2^{22}; float has a 23-bit mantissa From ce159d1a3e48308d54300560f024e8501c1395c9 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 19 Nov 2018 19:53:38 +0100 Subject: [PATCH 0400/1650] Fix toFloat()s between float and double ranges and document Revised some toFloat()s to be consistent with the matching toDouble()s; previously, they would return infinity if toDouble() did but return 0 if toDouble() got a finite value outside float's range. That also applied to values that underflowed float's range, succeeding and returning 0 as long as they were within double's range but failing if toDouble() underflowed. Now float-underflow also fails. Amended their documentation to reflect this more consistent reality. Added some tests of out-of-range values, infinities and NaNs. [ChangeLog][QtCore][toFloat] QString, QByteArray and QLocale returned an infinity on double-overflow (since 5.7) but returned 0 on a finite double outside float's range, while setting ok to false; this was at odds with their documented behavior of returning 0 on any failure. They also succeeded, returning zero, on underflow of float's range, unless double underflowed, where they failed. Changed the handling of values outside float's range to match that of values outside double's range: fail, returning an infinity on overflow or zero on underflow. The documentation now reflects the revised behavior, which matches toDouble(). Change-Id: Ia168bcacf7def0df924840d45d8edc5f850449d6 Reviewed-by: Ulf Hermann --- src/corelib/tools/qbytearray.cpp | 3 +- src/corelib/tools/qlocale.cpp | 18 +++++--- src/corelib/tools/qlocale_p.h | 11 ++++- src/corelib/tools/qstring.cpp | 6 ++- .../corelib/tools/qlocale/tst_qlocale.cpp | 42 ++++++++++++++----- 5 files changed, 60 insertions(+), 20 deletions(-) diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 1b7a4366c7..2a97fa50a9 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -3899,7 +3899,8 @@ double QByteArray::toDouble(bool *ok) const /*! Returns the byte array converted to a \c float value. - Returns 0.0 if the conversion fails. + Returns an infinity if the conversion overflows or 0.0 if the + conversion fails for other reasons (e.g. underflow). If \a ok is not \c nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 8f9fb3de2d..417b1e41f6 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -1353,8 +1353,10 @@ qulonglong QLocale::toULongLong(const QString &s, bool *ok) const } /*! - Returns the float represented by the localized string \a s, or 0.0 - if the conversion failed. + Returns the float represented by the localized string \a s. + + Returns an infinity if the conversion overflows or 0.0 if the + conversion fails for any other reason (e.g. underflow). If \a ok is not \c nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. @@ -1522,8 +1524,10 @@ qulonglong QLocale::toULongLong(const QStringRef &s, bool *ok) const } /*! - Returns the float represented by the localized string \a s, or 0.0 - if the conversion failed. + Returns the float represented by the localized string \a s. + + Returns an infinity if the conversion overflows or 0.0 if the + conversion fails for any other reason (e.g. underflow). If \a ok is not \c nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. @@ -1696,8 +1700,10 @@ qulonglong QLocale::toULongLong(QStringView s, bool *ok) const } /*! - Returns the float represented by the localized string \a s, or 0.0 - if the conversion failed. + Returns the float represented by the localized string \a s. + + Returns an infinity if the conversion overflows or 0.0 if the + conversion fails for any other reason (e.g. underflow). If \a ok is not \c nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h index 6669ae7c8b..deca671627 100644 --- a/src/corelib/tools/qlocale_p.h +++ b/src/corelib/tools/qlocale_p.h @@ -249,7 +249,16 @@ public: if (std::fabs(d) > std::numeric_limits::max()) { if (ok != 0) *ok = false; - return 0.0f; + const float huge = std::numeric_limits::infinity(); + return d < 0 ? -huge : huge; + } + if (std::fabs(d) >= std::numeric_limits::min() // i.e. d != 0 + && std::fabs(d) < std::numeric_limits::min()) { + // Values smaller than std::numeric_limits::min() have + // failed already; match them. + if (ok != 0) + *ok = false; + return 0; } return float(d); } diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 1381e8c11c..94b1784202 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -7208,7 +7208,8 @@ double QString::toDouble(bool *ok) const /*! Returns the string converted to a \c float value. - Returns 0.0 if the conversion fails. + Returns an infinity if the conversion overflows or 0.0 if the + conversion fails for other reasons (e.g. underflow). If \a ok is not \c nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. @@ -11821,7 +11822,8 @@ double QStringRef::toDouble(bool *ok) const /*! Returns the string converted to a \c float value. - Returns 0.0 if the conversion fails. + Returns an infinity if the conversion overflows or 0.0 if the + conversion fails for other reasons (e.g. underflow). If \a ok is not \c nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp index 7bf6d1327e..b8f1cc568a 100644 --- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp @@ -877,6 +877,28 @@ void tst_QLocale::stringToDouble() void tst_QLocale::stringToFloat_data() { toReal_data(); + if (std::numeric_limits::has_infinity) { + double huge = std::numeric_limits::infinity(); + QTest::newRow("C inf") << QString("C") << QString("inf") << true << huge; + QTest::newRow("C +inf") << QString("C") << QString("+inf") << true << +huge; + QTest::newRow("C -inf") << QString("C") << QString("-inf") << true << -huge; + // Overflow float, but not double: + QTest::newRow("C big") << QString("C") << QString("3.5e38") << false << huge; + QTest::newRow("C -big") << QString("C") << QString("-3.5e38") << false << -huge; + // Overflow double, too: + QTest::newRow("C huge") << QString("C") << QString("2e308") << false << huge; + QTest::newRow("C -huge") << QString("C") << QString("-2e308") << false << -huge; + } + if (std::numeric_limits::has_quiet_NaN) + QTest::newRow("C qnan") << QString("C") << QString("NaN") << true << double(std::numeric_limits::quiet_NaN()); + + // Underflow float, but not double: + QTest::newRow("C small") << QString("C") << QString("1e-45") << false << 0.; + QTest::newRow("C -small") << QString("C") << QString("-1e-45") << false << 0.; + + // Underflow double, too: + QTest::newRow("C tiny") << QString("C") << QString("2e-324") << false << 0.; + QTest::newRow("C -tiny") << QString("C") << QString("-2e-324") << false << 0.; } void tst_QLocale::stringToFloat() @@ -904,24 +926,24 @@ void tst_QLocale::stringToFloat() QCOMPARE(ok, good); } - if (ok) { + if (ok || std::isinf(fnum)) { // First use fuzzy-compare, then a more precise check: QCOMPARE(f, fnum); - float diff = f - fnum; - if (diff < 0) - diff = -diff; - QVERIFY(diff <= MY_FLOAT_EPSILON); + if (std::isfinite(fnum)) { + float diff = f > fnum ? f - fnum : fnum - f; + QVERIFY(diff <= MY_FLOAT_EPSILON); + } } f = locale.toFloat(num_strRef, &ok); QCOMPARE(ok, good); - if (ok) { + if (ok || std::isinf(fnum)) { QCOMPARE(f, fnum); - float diff = f - fnum; - if (diff < 0) - diff = -diff; - QVERIFY(diff <= MY_FLOAT_EPSILON); + if (std::isfinite(fnum)) { + float diff = f > fnum ? f - fnum : fnum - f; + QVERIFY(diff <= MY_FLOAT_EPSILON); + } } #undef MY_FLOAT_EPSILON } From d8b401959f6f58bc80f767684b250dd4589735d6 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 19 Nov 2018 16:26:02 +0100 Subject: [PATCH 0401/1650] Recognize E along with e as exponent character in asciiToDouble Fixed a misguided condition in the check for bogus texts in the sscanf branch of the decoder; it checked for 'e' but neglected 'E', which is just as valid. Change-Id: I9236c76faea000c92df641930e401bce445e06c8 Reviewed-by: Ulf Hermann --- src/corelib/tools/qlocale_tools.cpp | 2 +- tests/auto/corelib/tools/qlocale/tst_qlocale.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qlocale_tools.cpp b/src/corelib/tools/qlocale_tools.cpp index 4d969a4723..a315356a23 100644 --- a/src/corelib/tools/qlocale_tools.cpp +++ b/src/corelib/tools/qlocale_tools.cpp @@ -350,7 +350,7 @@ double asciiToDouble(const char *num, int numLen, bool &ok, int &processed, ok = false; for (int i = 0; i < processed; ++i) { char c = num[i]; - if ((c < '0' || c > '9') && c != '.' && c != '-' && c != '+' && c != 'e') { + if ((c < '0' || c > '9') && c != '.' && c != '-' && c != '+' && c != 'e' && c != 'E') { // Garbage found processed = 0; return 0.0; diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp index b8f1cc568a..fd37a03b8e 100644 --- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp @@ -693,6 +693,8 @@ void tst_QLocale::toReal_data() QTest::newRow("C 1.234e-10") << QString("C") << QString("1.234e-10") << true << 1.234e-10; QTest::newRow("C 1.234E10") << QString("C") << QString("1.234E10") << true << 1.234e10; QTest::newRow("C 1e10") << QString("C") << QString("1e10") << true << 1.0e10; + QTest::newRow("C 1e310") << QString("C") << QString("1e310") << false << std::numeric_limits::infinity(); + QTest::newRow("C 1E310") << QString("C") << QString("1E310") << false << std::numeric_limits::infinity(); QTest::newRow("C 1") << QString("C") << QString(" 1") << true << 1.0; QTest::newRow("C 1") << QString("C") << QString(" 1") << true << 1.0; QTest::newRow("C 1 ") << QString("C") << QString("1 ") << true << 1.0; From 76dafc9b94ebe08577eee1d929fe7fa0330189ed Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 21 Nov 2018 09:24:18 +0100 Subject: [PATCH 0402/1650] Add translator's comment to the copyright note State the policy that so far only exists in the localization wiki and is currently not followed by all translators. Task-number: QTBUG-57697 Change-Id: I2aa9f1bbd244b53e48e59f625520a7f86d2df347 Reviewed-by: Vitaly Fanaskov Reviewed-by: Lars Knoll --- src/widgets/dialogs/qmessagebox.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index 32190151bc..ffbbe82856 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -1832,8 +1832,9 @@ void QMessageBox::aboutQt(QWidget *parent, const QString &title) "

    About Qt

    " "

    This program uses Qt version %1.

    " ).arg(QLatin1String(QT_VERSION_STR)); - QString translatedTextAboutQtText; - translatedTextAboutQtText = QMessageBox::tr( + //: Leave this text untranslated or include a verbatim copy of it below + //: and note that it is the authoritative version in case of doubt. + const QString translatedTextAboutQtText = QMessageBox::tr( "

    Qt is a C++ toolkit for cross-platform application " "development.

    " "

    Qt provides single-source portability across all major desktop " From 36f3eeaf3ec12126956d151a026379ab0385ab72 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Thu, 22 Nov 2018 18:32:50 +0100 Subject: [PATCH 0403/1650] Fix build errors in OpenSSL 1.1 backend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SSL_CTX_set_ciphers is new in 1.1.1. Task-number: QTBUG-71983 Change-Id: If0ae9f95dcc867c62ed0d3a6a60c22c7f5e1cc9f Reviewed-by: Mårten Nordheim --- src/network/ssl/qsslsocket_openssl_symbols.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index 781b3d6640..fd58e9548e 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -161,7 +161,9 @@ DEFINEFUNC(void, OPENSSL_sk_free, OPENSSL_STACK *a, a, return, DUMMYARG) DEFINEFUNC2(void *, OPENSSL_sk_value, OPENSSL_STACK *a, a, int b, b, return nullptr, return) DEFINEFUNC(int, SSL_session_reused, SSL *a, a, return 0, return) DEFINEFUNC2(unsigned long, SSL_CTX_set_options, SSL_CTX *ctx, ctx, unsigned long op, op, return 0, return) +#ifdef TLS1_3_VERSION DEFINEFUNC2(int, SSL_CTX_set_ciphersuites, SSL_CTX *ctx, ctx, const char *str, str, return 0, return) +#endif DEFINEFUNC3(size_t, SSL_get_client_random, SSL *a, a, unsigned char *out, out, size_t outlen, outlen, return 0, return) DEFINEFUNC3(size_t, SSL_SESSION_get_master_key, const SSL_SESSION *ses, ses, unsigned char *out, out, size_t outlen, outlen, return 0, return) DEFINEFUNC6(int, CRYPTO_get_ex_new_index, int class_index, class_index, long argl, argl, void *argp, argp, CRYPTO_EX_new *new_func, new_func, CRYPTO_EX_dup *dup_func, dup_func, CRYPTO_EX_free *free_func, free_func, return -1, return) From 8b42614c6cee227200fdf67082d29a0f0b9adf9d Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Tue, 13 Nov 2018 20:43:58 +0100 Subject: [PATCH 0404/1650] Cleanup Spreadsheet example Cleanup the Spreadsheet example: - use nullptr - use for instead foreach Change-Id: I55deed157403a46d98a6d753ef46e4cbe5730b4f Reviewed-by: Luca Beldi Reviewed-by: Paul Wicking Reviewed-by: Sze Howe Koh --- .../widgets/itemviews/spreadsheet/main.cpp | 3 +- .../itemviews/spreadsheet/printview.cpp | 5 +- .../itemviews/spreadsheet/spreadsheet.cpp | 60 +++++++++---------- .../itemviews/spreadsheet/spreadsheet.h | 4 +- .../spreadsheet/spreadsheetdelegate.cpp | 12 ++-- .../spreadsheet/spreadsheetdelegate.h | 4 +- .../itemviews/spreadsheet/spreadsheetitem.cpp | 33 ++++------ .../itemviews/spreadsheet/spreadsheetitem.h | 7 +-- 8 files changed, 55 insertions(+), 73 deletions(-) diff --git a/examples/widgets/itemviews/spreadsheet/main.cpp b/examples/widgets/itemviews/spreadsheet/main.cpp index 769edbdf03..548dc8d604 100644 --- a/examples/widgets/itemviews/spreadsheet/main.cpp +++ b/examples/widgets/itemviews/spreadsheet/main.cpp @@ -53,7 +53,8 @@ #include #include -int main(int argc, char** argv) { +int main(int argc, char **argv) +{ Q_INIT_RESOURCE(spreadsheet); QApplication app(argc, argv); SpreadSheet sheet(10, 6); diff --git a/examples/widgets/itemviews/spreadsheet/printview.cpp b/examples/widgets/itemviews/spreadsheet/printview.cpp index 31424e9070..7db1a6bad9 100644 --- a/examples/widgets/itemviews/spreadsheet/printview.cpp +++ b/examples/widgets/itemviews/spreadsheet/printview.cpp @@ -48,12 +48,11 @@ ** ****************************************************************************/ +#include "printview.h" + #ifndef QT_NO_PRINTER #include #endif -#include - -#include "printview.h" PrintView::PrintView() { diff --git a/examples/widgets/itemviews/spreadsheet/spreadsheet.cpp b/examples/widgets/itemviews/spreadsheet/spreadsheet.cpp index 621f655b02..421b4a240c 100644 --- a/examples/widgets/itemviews/spreadsheet/spreadsheet.cpp +++ b/examples/widgets/itemviews/spreadsheet/spreadsheet.cpp @@ -48,36 +48,30 @@ ** ****************************************************************************/ -#include -#if defined(QT_PRINTSUPPORT_LIB) -#include -#if QT_CONFIG(printdialog) -#include -#include -#endif -#if QT_CONFIG(printpreviewdialog) -#include -#endif -#endif - #include "spreadsheet.h" #include "spreadsheetdelegate.h" #include "spreadsheetitem.h" #include "printview.h" -SpreadSheet::SpreadSheet(int rows, int cols, QWidget *parent) - : QMainWindow(parent) -{ - addToolBar(toolBar = new QToolBar()); - formulaInput = new QLineEdit(); +#include +#if defined(QT_PRINTSUPPORT_LIB) +#include +#endif + +SpreadSheet::SpreadSheet(int rows, int cols, QWidget *parent) + : QMainWindow(parent), + toolBar(new QToolBar(this)), + cellLabel(new QLabel(toolBar)), + table(new QTableWidget(rows, cols, this)), + formulaInput(new QLineEdit(this)) +{ + addToolBar(toolBar); - cellLabel = new QLabel(toolBar); cellLabel->setMinimumSize(80, 0); toolBar->addWidget(cellLabel); toolBar->addWidget(formulaInput); - table = new QTableWidget(rows, cols, this); table->setSizeAdjustPolicy(QTableWidget::AdjustToContents); for (int c = 0; c < cols; ++c) { QString character(QChar('A' + c)); @@ -88,7 +82,7 @@ SpreadSheet::SpreadSheet(int rows, int cols, QWidget *parent) table->setItemDelegate(new SpreadSheetDelegate()); createActions(); - updateColor(0); + updateColor(nullptr); setupMenuBar(); setupContents(); setupContextMenu(); @@ -103,7 +97,8 @@ SpreadSheet::SpreadSheet(int rows, int cols, QWidget *parent) this, &SpreadSheet::updateLineEdit); connect(table, &QTableWidget::itemChanged, this, &SpreadSheet::updateStatus); - connect(formulaInput, &QLineEdit::returnPressed, this, &SpreadSheet::returnPressed); + connect(formulaInput, &QLineEdit::returnPressed, + this, &SpreadSheet::returnPressed); connect(table, &QTableWidget::itemChanged, this, &SpreadSheet::updateLineEdit); @@ -245,11 +240,11 @@ void SpreadSheet::selectColor() if (!col.isValid()) return; - QList selected = table->selectedItems(); - if (selected.count() == 0) + const QList selected = table->selectedItems(); + if (selected.isEmpty()) return; - foreach (QTableWidgetItem *i, selected) { + for (QTableWidgetItem *i : selected) { if (i) i->setBackgroundColor(col); } @@ -259,8 +254,8 @@ void SpreadSheet::selectColor() void SpreadSheet::selectFont() { - QList selected = table->selectedItems(); - if (selected.count() == 0) + const QList selected = table->selectedItems(); + if (selected.isEmpty()) return; bool ok = false; @@ -268,7 +263,7 @@ void SpreadSheet::selectFont() if (!ok) return; - foreach (QTableWidgetItem *i, selected) { + for (QTableWidgetItem *i : selected) { if (i) i->setFont(fnt); } @@ -397,7 +392,7 @@ void SpreadSheet::actionSum() int col_last = 0; int col_cur = 0; - QList selected = table->selectedItems(); + const QList selected = table->selectedItems(); if (!selected.isEmpty()) { QTableWidgetItem *first = selected.first(); @@ -408,7 +403,7 @@ void SpreadSheet::actionSum() col_last = table->column(last); } - QTableWidgetItem *current = table->currentItem(); + const QTableWidgetItem *current = table->currentItem(); if (current) { row_cur = table->row(current); @@ -435,7 +430,7 @@ void SpreadSheet::actionMath_helper(const QString &title, const QString &op) QString cell2 = "C2"; QString out = "C3"; - QTableWidgetItem *current = table->currentItem(); + const QTableWidgetItem *current = table->currentItem(); if (current) out = encode_pos(table->currentRow(), table->currentColumn()); @@ -468,8 +463,9 @@ void SpreadSheet::actionDivide() void SpreadSheet::clear() { - foreach (QTableWidgetItem *i, table->selectedItems()) - i->setText(""); + const QList selectedItems = table->selectedItems(); + for (QTableWidgetItem *i : selectedItems) + i->setText(QString()); } void SpreadSheet::setupContextMenu() diff --git a/examples/widgets/itemviews/spreadsheet/spreadsheet.h b/examples/widgets/itemviews/spreadsheet/spreadsheet.h index a90d1d8c20..b36a377156 100644 --- a/examples/widgets/itemviews/spreadsheet/spreadsheet.h +++ b/examples/widgets/itemviews/spreadsheet/spreadsheet.h @@ -65,10 +65,8 @@ QT_END_NAMESPACE class SpreadSheet : public QMainWindow { Q_OBJECT - public: - - SpreadSheet(int rows, int cols, QWidget *parent = 0); + SpreadSheet(int rows, int cols, QWidget *parent = nullptr); public slots: void updateStatus(QTableWidgetItem *item); diff --git a/examples/widgets/itemviews/spreadsheet/spreadsheetdelegate.cpp b/examples/widgets/itemviews/spreadsheet/spreadsheetdelegate.cpp index aaf8902af5..eadd5fadb8 100644 --- a/examples/widgets/itemviews/spreadsheet/spreadsheetdelegate.cpp +++ b/examples/widgets/itemviews/spreadsheet/spreadsheetdelegate.cpp @@ -53,11 +53,12 @@ #include SpreadSheetDelegate::SpreadSheetDelegate(QObject *parent) - : QItemDelegate(parent) {} + : QItemDelegate(parent) +{} QWidget *SpreadSheetDelegate::createEditor(QWidget *parent, - const QStyleOptionViewItem &, - const QModelIndex &index) const + const QStyleOptionViewItem &, + const QModelIndex &index) const { if (index.column() == 1) { QDateTimeEdit *editor = new QDateTimeEdit(parent); @@ -92,7 +93,7 @@ void SpreadSheetDelegate::commitAndCloseEditor() } void SpreadSheetDelegate::setEditorData(QWidget *editor, - const QModelIndex &index) const + const QModelIndex &index) const { QLineEdit *edit = qobject_cast(editor); if (edit) { @@ -109,7 +110,8 @@ void SpreadSheetDelegate::setEditorData(QWidget *editor, } void SpreadSheetDelegate::setModelData(QWidget *editor, - QAbstractItemModel *model, const QModelIndex &index) const + QAbstractItemModel *model, + const QModelIndex &index) const { QLineEdit *edit = qobject_cast(editor); if (edit) { diff --git a/examples/widgets/itemviews/spreadsheet/spreadsheetdelegate.h b/examples/widgets/itemviews/spreadsheet/spreadsheetdelegate.h index 333467720f..c89459cadf 100644 --- a/examples/widgets/itemviews/spreadsheet/spreadsheetdelegate.h +++ b/examples/widgets/itemviews/spreadsheet/spreadsheetdelegate.h @@ -51,8 +51,6 @@ #ifndef SPREADSHEETDELEGATE_H #define SPREADSHEETDELEGATE_H -#include "spreadsheet.h" - #include class SpreadSheetDelegate : public QItemDelegate @@ -60,7 +58,7 @@ class SpreadSheetDelegate : public QItemDelegate Q_OBJECT public: - SpreadSheetDelegate(QObject *parent = 0); + SpreadSheetDelegate(QObject *parent = nullptr); QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const override; void setEditorData(QWidget *editor, const QModelIndex &index) const override; diff --git a/examples/widgets/itemviews/spreadsheet/spreadsheetitem.cpp b/examples/widgets/itemviews/spreadsheet/spreadsheetitem.cpp index 92cbaff031..62d3a6fdcd 100644 --- a/examples/widgets/itemviews/spreadsheet/spreadsheetitem.cpp +++ b/examples/widgets/itemviews/spreadsheet/spreadsheetitem.cpp @@ -50,19 +50,9 @@ #include "spreadsheetitem.h" -SpreadSheetItem::SpreadSheetItem() - : QTableWidgetItem(), isResolving(false) -{ -} - -SpreadSheetItem::SpreadSheetItem(const QString &text) - : QTableWidgetItem(text), isResolving(false) -{ -} - QTableWidgetItem *SpreadSheetItem::clone() const { - SpreadSheetItem *item = new SpreadSheetItem(); + SpreadSheetItem *item = new SpreadSheetItem; *item = *this; return item; } @@ -75,21 +65,20 @@ QVariant SpreadSheetItem::data(int role) const if (role == Qt::DisplayRole) return display(); - QString t = display().toString(); - bool isNumber = false; - int number = t.toInt(&isNumber); + const QString t = display().toString(); if (role == Qt::ForegroundRole) { - if (!isNumber) - return QVariant::fromValue(QColor(Qt::black)); - else if (number < 0) - return QVariant::fromValue(QColor(Qt::red)); - return QVariant::fromValue(QColor(Qt::blue)); + bool isNumber = false; + const int number = t.toInt(&isNumber); + QColor color = Qt::black; + if (isNumber) + color = (number < 0) ? Qt::red : Qt::blue; + return QVariant::fromValue(color); } - if (role == Qt::TextAlignmentRole) - if (!t.isEmpty() && (t.at(0).isNumber() || t.at(0) == '-')) - return (int)(Qt::AlignRight | Qt::AlignVCenter); + if (role == Qt::TextAlignmentRole) + if (!t.isEmpty() && (t.at(0).isNumber() || t.at(0) == '-')) + return int(Qt::AlignRight | Qt::AlignVCenter); return QTableWidgetItem::data(role); } diff --git a/examples/widgets/itemviews/spreadsheet/spreadsheetitem.h b/examples/widgets/itemviews/spreadsheet/spreadsheetitem.h index 46460df527..159f4a7eea 100644 --- a/examples/widgets/itemviews/spreadsheet/spreadsheetitem.h +++ b/examples/widgets/itemviews/spreadsheet/spreadsheetitem.h @@ -58,8 +58,7 @@ class SpreadSheetItem : public QTableWidgetItem { public: - SpreadSheetItem(); - SpreadSheetItem(const QString &text); + using QTableWidgetItem::QTableWidgetItem; QTableWidgetItem *clone() const override; @@ -74,10 +73,10 @@ public: static QVariant computeFormula(const QString &formula, const QTableWidget *widget, - const QTableWidgetItem *self = 0); + const QTableWidgetItem *self = nullptr); private: - mutable bool isResolving; + mutable bool isResolving = false; }; #endif // SPREADSHEETITEM_H From 14144079709201929c97b9a5f0db406c27275baf Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Wed, 21 Nov 2018 21:02:07 +0100 Subject: [PATCH 0405/1650] tst_QTreeView: set keyboardInputInterval to a smaller value keyboardInputInterval() is 400ms by default which slows down the testcase without a good reason. Set it to 100ms which speeds up the testcase from 20s to 10s on my system. Change-Id: Ib883c5d3f09f8e896ae56a8fc8df2233be63de01 Reviewed-by: David Faure --- tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index 6b732973b9..e452efff07 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -69,6 +69,7 @@ public slots: void selectionOrderTest(); private slots: + void initTestCase() { QApplication::setKeyboardInputInterval(100); } void getSetCheck(); // one test per QTreeView property From de83447830b0941216f922a37b6cd36e703197d4 Mon Sep 17 00:00:00 2001 From: Lars Schmertmann Date: Wed, 13 Jul 2016 08:42:33 +0200 Subject: [PATCH 0406/1650] Add support for Diffie-Hellman keys to QSslKey MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is necessary to provide details for the key too, when the server is using DHE-RSA-AESxxx-SHAxxx. Amends 7f77dc84fb434f33ffe96f6633792706b80fb0a3. Change-Id: I8ab15b6987c17c857f54bc368df3c6c1818f428c Reviewed-by: Mårten Nordheim Reviewed-by: Qt CI Bot Reviewed-by: Edward Welbourne Reviewed-by: Timur Pocheptsov --- src/network/ssl/qasn1element_p.h | 1 + src/network/ssl/qssl.cpp | 3 +- src/network/ssl/qssl.h | 3 +- src/network/ssl/qsslkey_openssl.cpp | 46 ++++++++++++++++-- src/network/ssl/qsslkey_p.cpp | 8 ++- src/network/ssl/qsslkey_p.h | 1 + src/network/ssl/qsslkey_qt.cpp | 32 ++++++++++++ .../ssl/qsslsocket_openssl_symbols.cpp | 8 +++ .../ssl/qsslsocket_openssl_symbols_p.h | 5 ++ .../ssl/qsslsocket_opensslpre11_symbols_p.h | 1 + .../network/ssl/qsslkey/keys/dh-pri-1024.der | Bin 0 -> 293 bytes .../network/ssl/qsslkey/keys/dh-pri-1024.pem | 9 ++++ .../network/ssl/qsslkey/keys/dh-pri-2048.der | Bin 0 -> 554 bytes .../network/ssl/qsslkey/keys/dh-pri-2048.pem | 14 ++++++ .../network/ssl/qsslkey/keys/dh-pri-512.der | Bin 0 -> 159 bytes .../network/ssl/qsslkey/keys/dh-pri-512.pem | 6 +++ .../network/ssl/qsslkey/keys/dh-pub-1024.der | Bin 0 -> 291 bytes .../network/ssl/qsslkey/keys/dh-pub-1024.pem | 9 ++++ .../network/ssl/qsslkey/keys/dh-pub-2048.der | Bin 0 -> 552 bytes .../network/ssl/qsslkey/keys/dh-pub-2048.pem | 14 ++++++ .../network/ssl/qsslkey/keys/dh-pub-512.der | Bin 0 -> 157 bytes .../network/ssl/qsslkey/keys/dh-pub-512.pem | 6 +++ .../auto/network/ssl/qsslkey/keys/genkeys.sh | 21 ++++++++ .../auto/network/ssl/qsslkey/tst_qsslkey.cpp | 5 +- 24 files changed, 182 insertions(+), 10 deletions(-) create mode 100644 tests/auto/network/ssl/qsslkey/keys/dh-pri-1024.der create mode 100644 tests/auto/network/ssl/qsslkey/keys/dh-pri-1024.pem create mode 100644 tests/auto/network/ssl/qsslkey/keys/dh-pri-2048.der create mode 100644 tests/auto/network/ssl/qsslkey/keys/dh-pri-2048.pem create mode 100644 tests/auto/network/ssl/qsslkey/keys/dh-pri-512.der create mode 100644 tests/auto/network/ssl/qsslkey/keys/dh-pri-512.pem create mode 100644 tests/auto/network/ssl/qsslkey/keys/dh-pub-1024.der create mode 100644 tests/auto/network/ssl/qsslkey/keys/dh-pub-1024.pem create mode 100644 tests/auto/network/ssl/qsslkey/keys/dh-pub-2048.der create mode 100644 tests/auto/network/ssl/qsslkey/keys/dh-pub-2048.pem create mode 100644 tests/auto/network/ssl/qsslkey/keys/dh-pub-512.der create mode 100644 tests/auto/network/ssl/qsslkey/keys/dh-pub-512.pem diff --git a/src/network/ssl/qasn1element_p.h b/src/network/ssl/qasn1element_p.h index 2068254a95..59d1f58482 100644 --- a/src/network/ssl/qasn1element_p.h +++ b/src/network/ssl/qasn1element_p.h @@ -64,6 +64,7 @@ QT_BEGIN_NAMESPACE #define RSA_ENCRYPTION_OID QByteArrayLiteral(RSADSI_OID "1.1.1") #define DSA_ENCRYPTION_OID QByteArrayLiteral("1.2.840.10040.4.1") #define EC_ENCRYPTION_OID QByteArrayLiteral("1.2.840.10045.2.1") +#define DH_ENCRYPTION_OID QByteArrayLiteral(RSADSI_OID "1.3.1") // These are mostly from the RFC for PKCS#5 // PKCS#5: https://tools.ietf.org/html/rfc8018#appendix-B diff --git a/src/network/ssl/qssl.cpp b/src/network/ssl/qssl.cpp index 19d99bc489..ea2b73bad5 100644 --- a/src/network/ssl/qssl.cpp +++ b/src/network/ssl/qssl.cpp @@ -71,7 +71,8 @@ Q_LOGGING_CATEGORY(lcSsl, "qt.network.ssl"); \value Rsa The RSA algorithm. \value Dsa The DSA algorithm. - \value Ec The Elliptic Curve algorithm + \value Ec The Elliptic Curve algorithm. + \value Dh The Diffie-Hellman algorithm. \value Opaque A key that should be treated as a 'black box' by QSslKey. The opaque key facility allows applications to add support for facilities diff --git a/src/network/ssl/qssl.h b/src/network/ssl/qssl.h index 60362cb410..5c25e4e105 100644 --- a/src/network/ssl/qssl.h +++ b/src/network/ssl/qssl.h @@ -62,7 +62,8 @@ namespace QSsl { Opaque, Rsa, Dsa, - Ec + Ec, + Dh, }; enum AlternativeNameEntryType { diff --git a/src/network/ssl/qsslkey_openssl.cpp b/src/network/ssl/qsslkey_openssl.cpp index 9a43e67772..99c1a39c73 100644 --- a/src/network/ssl/qsslkey_openssl.cpp +++ b/src/network/ssl/qsslkey_openssl.cpp @@ -69,6 +69,11 @@ void QSslKeyPrivate::clear(bool deep) q_DSA_free(dsa); dsa = nullptr; } + if (algorithm == QSsl::Dh && dh) { + if (deep) + q_DH_free(dh); + dh = nullptr; + } #ifndef OPENSSL_NO_EC if (algorithm == QSsl::Ec && ec) { if (deep) @@ -105,6 +110,12 @@ bool QSslKeyPrivate::fromEVP_PKEY(EVP_PKEY *pkey) type = QSsl::PrivateKey; dsa = q_EVP_PKEY_get1_DSA(pkey); return true; + } else if (keyType == EVP_PKEY_DH) { + isNull = false; + algorithm = QSsl::Dh; + type = QSsl::PrivateKey; + dh = q_EVP_PKEY_get1_DH(pkey); + return true; } #ifndef OPENSSL_NO_EC else if (keyType == EVP_PKEY_EC) { @@ -160,6 +171,15 @@ void QSslKeyPrivate::decodePem(const QByteArray &pem, const QByteArray &passPhra : q_PEM_read_bio_DSAPrivateKey(bio, &dsa, nullptr, phrase); if (dsa && dsa == result) isNull = false; + } else if (algorithm == QSsl::Dh) { + EVP_PKEY *result = (type == QSsl::PublicKey) + ? q_PEM_read_bio_PUBKEY(bio, nullptr, nullptr, phrase) + : q_PEM_read_bio_PrivateKey(bio, nullptr, nullptr, phrase); + if (result) + dh = q_EVP_PKEY_get1_DH(result); + if (dh) + isNull = false; + q_EVP_PKEY_free(result); #ifndef OPENSSL_NO_EC } else if (algorithm == QSsl::Ec) { EC_KEY *result = (type == QSsl::PublicKey) @@ -181,6 +201,7 @@ int QSslKeyPrivate::length() const switch (algorithm) { case QSsl::Rsa: return q_RSA_bits(rsa); case QSsl::Dsa: return q_DSA_bits(dsa); + case QSsl::Dh: return q_DH_bits(dh); #ifndef OPENSSL_NO_EC case QSsl::Ec: return q_EC_GROUP_get_degree(q_EC_KEY_get0_group(ec)); #endif @@ -215,7 +236,7 @@ QByteArray QSslKeyPrivate::toPem(const QByteArray &passPhrase) const fail = true; } else { if (!q_PEM_write_bio_RSAPrivateKey( - bio, rsa, cipher, const_cast((const uchar *)passPhrase.data()), + bio, rsa, cipher, (uchar *)passPhrase.data(), passPhrase.size(), nullptr, nullptr)) { fail = true; } @@ -226,20 +247,33 @@ QByteArray QSslKeyPrivate::toPem(const QByteArray &passPhrase) const fail = true; } else { if (!q_PEM_write_bio_DSAPrivateKey( - bio, dsa, cipher, const_cast((const uchar *)passPhrase.data()), + bio, dsa, cipher, (uchar *)passPhrase.data(), passPhrase.size(), nullptr, nullptr)) { fail = true; } } + } else if (algorithm == QSsl::Dh) { + EVP_PKEY *result = q_EVP_PKEY_new(); + if (!result || !q_EVP_PKEY_set1_DH(result, dh)) { + fail = true; + } else if (type == QSsl::PublicKey) { + if (!q_PEM_write_bio_PUBKEY(bio, result)) + fail = true; + } else if (!q_PEM_write_bio_PrivateKey( + bio, result, cipher, (uchar *)passPhrase.data(), + passPhrase.size(), nullptr, nullptr)) { + fail = true; + } + q_EVP_PKEY_free(result); #ifndef OPENSSL_NO_EC } else if (algorithm == QSsl::Ec) { if (type == QSsl::PublicKey) { if (!q_PEM_write_bio_EC_PUBKEY(bio, ec)) fail = true; } else { - if (!q_PEM_write_bio_ECPrivateKey(bio, ec, cipher, - const_cast((const uchar *)passPhrase.data()), - passPhrase.size(), nullptr, nullptr)) { + if (!q_PEM_write_bio_ECPrivateKey( + bio, ec, cipher, (uchar *)passPhrase.data(), + passPhrase.size(), nullptr, nullptr)) { fail = true; } } @@ -267,6 +301,8 @@ Qt::HANDLE QSslKeyPrivate::handle() const return Qt::HANDLE(rsa); case QSsl::Dsa: return Qt::HANDLE(dsa); + case QSsl::Dh: + return Qt::HANDLE(dh); #ifndef OPENSSL_NO_EC case QSsl::Ec: return Qt::HANDLE(ec); diff --git a/src/network/ssl/qsslkey_p.cpp b/src/network/ssl/qsslkey_p.cpp index 28e3e2efd8..b29b38beab 100644 --- a/src/network/ssl/qsslkey_p.cpp +++ b/src/network/ssl/qsslkey_p.cpp @@ -116,6 +116,8 @@ QByteArray QSslKeyPrivate::pemHeader() const return QByteArrayLiteral("-----BEGIN DSA PRIVATE KEY-----"); else if (algorithm == QSsl::Ec) return QByteArrayLiteral("-----BEGIN EC PRIVATE KEY-----"); + else if (algorithm == QSsl::Dh) + return QByteArrayLiteral("-----BEGIN PRIVATE KEY-----"); Q_UNREACHABLE(); return QByteArray(); @@ -141,6 +143,8 @@ QByteArray QSslKeyPrivate::pemFooter() const return QByteArrayLiteral("-----END DSA PRIVATE KEY-----"); else if (algorithm == QSsl::Ec) return QByteArrayLiteral("-----END EC PRIVATE KEY-----"); + else if (algorithm == QSsl::Dh) + return QByteArrayLiteral("-----END PRIVATE KEY-----"); Q_UNREACHABLE(); return QByteArray(); @@ -535,7 +539,9 @@ QDebug operator<<(QDebug debug, const QSslKey &key) debug << "QSslKey(" << (key.type() == QSsl::PublicKey ? "PublicKey" : "PrivateKey") << ", " << (key.algorithm() == QSsl::Opaque ? "OPAQUE" : - (key.algorithm() == QSsl::Rsa ? "RSA" : ((key.algorithm() == QSsl::Dsa) ? "DSA" : "EC"))) + (key.algorithm() == QSsl::Rsa ? "RSA" : + (key.algorithm() == QSsl::Dsa ? "DSA" : + (key.algorithm() == QSsl::Dh ? "DH" : "EC")))) << ", " << key.length() << ')'; return debug; diff --git a/src/network/ssl/qsslkey_p.h b/src/network/ssl/qsslkey_p.h index 7ae2cc740b..310553cab2 100644 --- a/src/network/ssl/qsslkey_p.h +++ b/src/network/ssl/qsslkey_p.h @@ -116,6 +116,7 @@ public: EVP_PKEY *opaque; RSA *rsa; DSA *dsa; + DH *dh; #ifndef OPENSSL_NO_EC EC_KEY *ec; #endif diff --git a/src/network/ssl/qsslkey_qt.cpp b/src/network/ssl/qsslkey_qt.cpp index a13275f3bb..5ebd8ac3bd 100644 --- a/src/network/ssl/qsslkey_qt.cpp +++ b/src/network/ssl/qsslkey_qt.cpp @@ -165,6 +165,7 @@ static int extractPkcs8KeyLength(const QVector &items, QSslKeyPriv switch (algorithm){ case QSsl::Rsa: return "RSA"; case QSsl::Dsa: return "DSA"; + case QSsl::Dh: return "DH"; case QSsl::Ec: return "EC"; case QSsl::Opaque: return "Opaque"; } @@ -217,6 +218,21 @@ static int extractPkcs8KeyLength(const QVector &items, QSslKeyPriv if (dsaInfo.size() != 3 || dsaInfo[0].type() != QAsn1Element::IntegerType) return -1; keyLength = numberOfBits(dsaInfo[0].value()); + } else if (value == DH_ENCRYPTION_OID) { + if (Q_UNLIKELY(that->algorithm != QSsl::Dh)) { + // As above for RSA. + qWarning() << "QSslKey: Found DH when asked to use" << getName(that->algorithm) + << "\nLoading will fail."; + return -1; + } + // DH's structure is documented here: + // https://www.cryptsoft.com/pkcs11doc/STANDARD/v201-95.pdf in section 11.9. + if (pkcs8Info[1].type() != QAsn1Element::SequenceType) + return -1; + const QVector dhInfo = pkcs8Info[1].toVector(); + if (dhInfo.size() < 2 || dhInfo.size() > 3 || dhInfo[0].type() != QAsn1Element::IntegerType) + return -1; + keyLength = numberOfBits(dhInfo[0].value()); } else { // in case of unexpected formats: qWarning() << "QSslKey: Unsupported PKCS#8 key algorithm:" << value @@ -268,6 +284,16 @@ void QSslKeyPrivate::decodeDer(const QByteArray &der, const QByteArray &passPhra if (params.isEmpty() || params[0].type() != QAsn1Element::IntegerType) return; keyLength = numberOfBits(params[0].value()); + } else if (algorithm == QSsl::Dh) { + if (infoItems[0].toObjectId() != DH_ENCRYPTION_OID) + return; + if (infoItems[1].type() != QAsn1Element::SequenceType) + return; + // key params + const QVector params = infoItems[1].toVector(); + if (params.isEmpty() || params[0].type() != QAsn1Element::IntegerType) + return; + keyLength = numberOfBits(params[0].value()); } else if (algorithm == QSsl::Ec) { if (infoItems[0].toObjectId() != EC_ENCRYPTION_OID) return; @@ -307,6 +333,12 @@ void QSslKeyPrivate::decodeDer(const QByteArray &der, const QByteArray &passPhra if (items.size() != 6 || items[1].type() != QAsn1Element::IntegerType) return; keyLength = numberOfBits(items[1].value()); + } else if (algorithm == QSsl::Dh) { + if (versionHex != "00") + return; + if (items.size() < 5 || items.size() > 6 || items[1].type() != QAsn1Element::IntegerType) + return; + keyLength = numberOfBits(items[1].value()); } else if (algorithm == QSsl::Ec) { if (versionHex != "01") return; diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index 781b3d6640..5ba2c40636 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -366,12 +366,14 @@ DEFINEFUNC(const EVP_MD *, EVP_sha1, DUMMYARG, DUMMYARG, return nullptr, return) DEFINEFUNC3(int, EVP_PKEY_assign, EVP_PKEY *a, a, int b, b, char *c, c, return -1, return) DEFINEFUNC2(int, EVP_PKEY_set1_RSA, EVP_PKEY *a, a, RSA *b, b, return -1, return) DEFINEFUNC2(int, EVP_PKEY_set1_DSA, EVP_PKEY *a, a, DSA *b, b, return -1, return) +DEFINEFUNC2(int, EVP_PKEY_set1_DH, EVP_PKEY *a, a, DH *b, b, return -1, return) #ifndef OPENSSL_NO_EC DEFINEFUNC2(int, EVP_PKEY_set1_EC_KEY, EVP_PKEY *a, a, EC_KEY *b, b, return -1, return) #endif DEFINEFUNC(void, EVP_PKEY_free, EVP_PKEY *a, a, return, DUMMYARG) DEFINEFUNC(DSA *, EVP_PKEY_get1_DSA, EVP_PKEY *a, a, return nullptr, return) DEFINEFUNC(RSA *, EVP_PKEY_get1_RSA, EVP_PKEY *a, a, return nullptr, return) +DEFINEFUNC(DH *, EVP_PKEY_get1_DH, EVP_PKEY *a, a, return nullptr, return) #ifndef OPENSSL_NO_EC DEFINEFUNC(EC_KEY *, EVP_PKEY_get1_EC_KEY, EVP_PKEY *a, a, return nullptr, return) #endif @@ -397,6 +399,7 @@ DEFINEFUNC4(EC_KEY *, PEM_read_bio_ECPrivateKey, BIO *a, a, EC_KEY **b, b, pem_p DEFINEFUNC4(DH *, PEM_read_bio_DHparams, BIO *a, a, DH **b, b, pem_password_cb *c, c, void *d, d, return nullptr, return) DEFINEFUNC7(int, PEM_write_bio_DSAPrivateKey, BIO *a, a, DSA *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return) DEFINEFUNC7(int, PEM_write_bio_RSAPrivateKey, BIO *a, a, RSA *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return) +DEFINEFUNC7(int, PEM_write_bio_PrivateKey, BIO *a, a, EVP_PKEY *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return) #ifndef OPENSSL_NO_EC DEFINEFUNC7(int, PEM_write_bio_ECPrivateKey, BIO *a, a, EC_KEY *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return) #endif @@ -409,6 +412,7 @@ DEFINEFUNC4(EC_KEY *, PEM_read_bio_EC_PUBKEY, BIO *a, a, EC_KEY **b, b, pem_pass #endif DEFINEFUNC2(int, PEM_write_bio_DSA_PUBKEY, BIO *a, a, DSA *b, b, return 0, return) DEFINEFUNC2(int, PEM_write_bio_RSA_PUBKEY, BIO *a, a, RSA *b, b, return 0, return) +DEFINEFUNC2(int, PEM_write_bio_PUBKEY, BIO *a, a, EVP_PKEY *b, b, return 0, return) #ifndef OPENSSL_NO_EC DEFINEFUNC2(int, PEM_write_bio_EC_PUBKEY, BIO *a, a, EC_KEY *b, b, return 0, return) #endif @@ -1168,12 +1172,14 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(EVP_PKEY_assign) RESOLVEFUNC(EVP_PKEY_set1_RSA) RESOLVEFUNC(EVP_PKEY_set1_DSA) + RESOLVEFUNC(EVP_PKEY_set1_DH) #ifndef OPENSSL_NO_EC RESOLVEFUNC(EVP_PKEY_set1_EC_KEY) #endif RESOLVEFUNC(EVP_PKEY_free) RESOLVEFUNC(EVP_PKEY_get1_DSA) RESOLVEFUNC(EVP_PKEY_get1_RSA) + RESOLVEFUNC(EVP_PKEY_get1_DH) #ifndef OPENSSL_NO_EC RESOLVEFUNC(EVP_PKEY_get1_EC_KEY) #endif @@ -1197,6 +1203,7 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(PEM_read_bio_DHparams) RESOLVEFUNC(PEM_write_bio_DSAPrivateKey) RESOLVEFUNC(PEM_write_bio_RSAPrivateKey) + RESOLVEFUNC(PEM_write_bio_PrivateKey) #ifndef OPENSSL_NO_EC RESOLVEFUNC(PEM_write_bio_ECPrivateKey) #endif @@ -1210,6 +1217,7 @@ bool q_resolveOpenSslSymbols() #endif RESOLVEFUNC(PEM_write_bio_DSA_PUBKEY) RESOLVEFUNC(PEM_write_bio_RSA_PUBKEY) + RESOLVEFUNC(PEM_write_bio_PUBKEY) #ifndef OPENSSL_NO_EC RESOLVEFUNC(PEM_write_bio_EC_PUBKEY) #endif diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h index bfdfbf0efc..7e759d3825 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols_p.h +++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h @@ -278,12 +278,14 @@ const EVP_MD *q_EVP_sha1(); int q_EVP_PKEY_assign(EVP_PKEY *a, int b, char *c); Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_RSA(EVP_PKEY *a, RSA *b); int q_EVP_PKEY_set1_DSA(EVP_PKEY *a, DSA *b); +int q_EVP_PKEY_set1_DH(EVP_PKEY *a, DH *b); #ifndef OPENSSL_NO_EC int q_EVP_PKEY_set1_EC_KEY(EVP_PKEY *a, EC_KEY *b); #endif void q_EVP_PKEY_free(EVP_PKEY *a); RSA *q_EVP_PKEY_get1_RSA(EVP_PKEY *a); DSA *q_EVP_PKEY_get1_DSA(EVP_PKEY *a); +DH *q_EVP_PKEY_get1_DH(EVP_PKEY *a); #ifndef OPENSSL_NO_EC EC_KEY *q_EVP_PKEY_get1_EC_KEY(EVP_PKEY *a); #endif @@ -314,6 +316,8 @@ int q_PEM_write_bio_DSAPrivateKey(BIO *a, DSA *b, const EVP_CIPHER *c, unsigned int e, pem_password_cb *f, void *g); int q_PEM_write_bio_RSAPrivateKey(BIO *a, RSA *b, const EVP_CIPHER *c, unsigned char *d, int e, pem_password_cb *f, void *g); +int q_PEM_write_bio_PrivateKey(BIO *a, EVP_PKEY *b, const EVP_CIPHER *c, unsigned char *d, + int e, pem_password_cb *f, void *g); #ifndef OPENSSL_NO_EC int q_PEM_write_bio_ECPrivateKey(BIO *a, EC_KEY *b, const EVP_CIPHER *c, unsigned char *d, int e, pem_password_cb *f, void *g); @@ -327,6 +331,7 @@ EC_KEY *q_PEM_read_bio_EC_PUBKEY(BIO *a, EC_KEY **b, pem_password_cb *c, void *d #endif int q_PEM_write_bio_DSA_PUBKEY(BIO *a, DSA *b); int q_PEM_write_bio_RSA_PUBKEY(BIO *a, RSA *b); +int q_PEM_write_bio_PUBKEY(BIO *a, EVP_PKEY *b); #ifndef OPENSSL_NO_EC int q_PEM_write_bio_EC_PUBKEY(BIO *a, EC_KEY *b); #endif diff --git a/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h b/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h index b7bac5d2a2..daf46f485c 100644 --- a/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h +++ b/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h @@ -218,6 +218,7 @@ DSA *q_d2i_DSAPrivateKey(DSA **a, unsigned char **pp, long length); #define q_SSL_SESSION_get_ticket_lifetime_hint(s) ((s)->tlsext_tick_lifetime_hint) #define q_RSA_bits(rsa) q_BN_num_bits((rsa)->n) #define q_DSA_bits(dsa) q_BN_num_bits((dsa)->p) +#define q_DH_bits(dsa) q_BN_num_bits((dh)->p) #define q_X509_STORE_set_verify_cb(s,c) X509_STORE_set_verify_cb_func((s),(c)) char *q_CONF_get1_default_config_file(); diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pri-1024.der b/tests/auto/network/ssl/qsslkey/keys/dh-pri-1024.der new file mode 100644 index 0000000000000000000000000000000000000000..687009e087cffd5c6a44c9b0b421346837d6dc2d GIT binary patch literal 293 zcmV+=0owjBf&n1{0RS+8l?DkahDe6@4FLlIFoA~xfq?*tWZ8xEOq}0CUm4As=t6-x zHz@6GY*t4QYlv^$_?4jt3vE<3`j;}z_+?4Obx(cHi6&sqMO1Nj5G69JzWZfrrpe{} ze=#9@F^=TiPCC4?cAyy+v@Q3bf<*)Ci$sL(B4@-lOovUZ)TO0$K-;t rQOQJBo)hkX0k-e0I`oyuw)Hl+A?pW~sgbfjnQ2PZU#UO;(~}qq0aS*m literal 0 HcmV?d00001 diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pri-1024.pem b/tests/auto/network/ssl/qsslkey/keys/dh-pri-1024.pem new file mode 100644 index 0000000000..233e0dfb37 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/dh-pri-1024.pem @@ -0,0 +1,9 @@ +-----BEGIN PRIVATE KEY----- +MIIBIQIBADCBlQYJKoZIhvcNAQMBMIGHAoGBAIlk2YX0TJzfQ18ZzZroQoE5Nyjt +bWxWRxBriG/c+JWhBwttVDb6lzLN+GVJxXVPfc6JJmDORVRxdxAlMqu++2Vqpsnl +/H8xIXsxjuTcTjq8sXagGRa0LfeggkUD64tEhO4iZ8Q2TIdb3OHkAF0Sn+06b/0e +iIz323Kywq0CsspTAgECBIGDAoGAQCo39UHP4s2ZVH4nOmWgNlb4JsHPX4EzqDBr +ig46hvMLAFrILYnsCbqqD/+GNAUl1PV/nfEQoAk/HvtACqLFLG5/3jK2w6dVHGEo +JnVOGz9vZpWUx+SCslHJRFaeE+6AAbbvrTr0lci29Ta4IesHlamRsj+ZaUrVX6k/ +/9OTGAo= +-----END PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pri-2048.der b/tests/auto/network/ssl/qsslkey/keys/dh-pri-2048.der new file mode 100644 index 0000000000000000000000000000000000000000..e193f25f0706fe38c014444b58df30af054c0da4 GIT binary patch literal 554 zcmV+_0@eL6f&wN20RS+90T%`dDuzgg_YDC90Wg9A2m*ou0RWpKMdEP=IRfl_z4QV= zPU|XS!%!X==y@{FczA3E;_W1@d@8v+-=%c*=hy0|fD&uqF$V8!dabPHnBK0Py553O zF_l~D6@zzwW6GM6MyI?<$d*`|OpKNzJqa>1wx+PU0_8tIOxbY-R7QTh$+QgFwN9IL2Cqq5@~bq35a2!oO7)7tG3I|5Ro8 zUqt)}qza+Yu6xKz-MPZDv@;C6=Y#f7w@H)}Uct_<6QcqF0tA8q1OkEq0Ad`p?esE+ zeGV&%Y~X3A&uf=v%^&hO=wY0ENRqJc^E(Zd^6UU9X-5DBy7wskF$M_d6ueBWAqmhDg` zkAuv^>p`yC#KPn97l8sU6{rZl@eTEMk&3zyl$HxVq_GXhS~Nk8q`EGd=Hzr@8Gz@G z<-iqy;c+kI<$V(wvC7z*w)3w&l9SYc`{=sM^||L}^Mo19)-4Ok^;Vi?Dri6Lkcz}W sHD$QNp56HJ5!GaW6*PwztY~maRG~cXi6iqzKD28O%91Mxm=H=46aeWDdjJ3c literal 0 HcmV?d00001 diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pri-2048.pem b/tests/auto/network/ssl/qsslkey/keys/dh-pri-2048.pem new file mode 100644 index 0000000000..32299b2b6c --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/dh-pri-2048.pem @@ -0,0 +1,14 @@ +-----BEGIN PRIVATE KEY----- +MIICJgIBADCCARcGCSqGSIb3DQEDATCCAQgCggEBAJsiReJxBjkC7Hy99AJATusq +YsNQHhjoeTLPeHhsBuLtJK18Krk736V09efX6qeAEmvgMQbvbHqtrOaY3q6dut6C +UTGVW+oVg3d/Y8qakkanvEnIlliaTIyWIz0JMjO2prC6AuU/QEzZcQVUS6bxyn3D +iYFxCE6+7cJJpEH9HVbcrl+J6Ch6ax5rQGUyxpSMkmItLJx92upRxOnaxJMHR+ZF +OSdDPfrkINpEzahnhteLszddyLasnE0or6ZnXYLvKsT1Uu6QwDc4EO1FJHScoeep +zsK/VRcXzMpj/1Rl+F9E/AikCqHRrnvISt25wrK0Mwy854P2T7dJlBNewc6vE6MC +AQIEggEEAoIBAGIctO30MoZ9DiuKbOBpqM9rl2bNH/I46GGcfEiSsO/zOw2V9WFC +MxkjF0I1ilDfPY+Ag3bLB2n89DPcfXliYH9MFolehPTc1fWplhX3+ImdC6y95uXO +FV5xtcEQCbPktnUtkUdcAT5831p9lu1QJo+DzMPrQa7axMLj8heBAi4VqAi+8Q31 +dpGKuhCUlgs+pLENx1o0QY2kui6Z5uR0YhmA547lwBWA4XEv5OV9ExmxytiatvOv +PZKT1ID76LrL9bnnZvOEGczWLQvJ9VaaZSpoP+2QisRANWW4w57d+PIR1WR/FTSH +F6xocElUoTzuiSPzRz60aw/KkisImBBKERQ= +-----END PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pri-512.der b/tests/auto/network/ssl/qsslkey/keys/dh-pri-512.der new file mode 100644 index 0000000000000000000000000000000000000000..42ddbaaae2eb93872a475e0fa528360435a9b665 GIT binary patch literal 159 zcmV;Q0AT+xft&&X05DSq2`Yw2hW8Bt0|78b0zm-1d~`z+Zy;bciVq2Uo>AJlo;!rv z*h?b-((cJp1x34VEL$CgPnwxWJZ{fXQ3<3_+|u`G7tq@2vPBq76hyAHkl9Y@oj%*Ed3BGnMFjzrYDNwY+=(|<;)J_=p&)TMSY Nzt>ioIT?KZWzMu{LyZ6c literal 0 HcmV?d00001 diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pri-512.pem b/tests/auto/network/ssl/qsslkey/keys/dh-pri-512.pem new file mode 100644 index 0000000000..d2c3170b16 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/dh-pri-512.pem @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIGcAgEAMFMGCSqGSIb3DQEDATBGAkEAvXx0QxJvIGA2ig8Je55R2rmeO4Ta2Esj +ANLuyVIFRbtuLFsdhU+amUc8bs9RUQmkUNzS92jkpAfqtCv+mQ06EwIBAgRCAkBJ +rDM0BTevOPIHpJzMtSQhw3e7Dr38HUfTn8zF3uYi1RCxjkTUukmzRLPTf0aqPgpd +8dSldjG/11aZORl8/mXO +-----END PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pub-1024.der b/tests/auto/network/ssl/qsslkey/keys/dh-pub-1024.der new file mode 100644 index 0000000000000000000000000000000000000000..2805a67633b8d696d9b2ef1371d82fa121c7b159 GIT binary patch literal 291 zcmV+;0o?vDf&m{eft3acDuzgg_YDC90Wg7w0)c@5iDcP@^h})JLth!qn&?7-IX5Wn zZERLY5Nn8U-1wED2McXfHu{$`&G=q&P7ylcMv5qtG@eXYNpBM{C_ba zdohmW+)g^Yv38&t7PKw*pn^pM>x)E$?jmQzHcW?G+~MQ^T@s(|I&b|Rh>Z8!acN!m{k1E2{CdI*s?`0fc5!wK@y|vnX^FqTWO8g|q+w literal 0 HcmV?d00001 diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pub-1024.pem b/tests/auto/network/ssl/qsslkey/keys/dh-pub-1024.pem new file mode 100644 index 0000000000..da4e327ac9 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/dh-pub-1024.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBHzCBlQYJKoZIhvcNAQMBMIGHAoGBAIlk2YX0TJzfQ18ZzZroQoE5NyjtbWxW +RxBriG/c+JWhBwttVDb6lzLN+GVJxXVPfc6JJmDORVRxdxAlMqu++2Vqpsnl/H8x +IXsxjuTcTjq8sXagGRa0LfeggkUD64tEhO4iZ8Q2TIdb3OHkAF0Sn+06b/0eiIz3 +23Kywq0CsspTAgECA4GEAAKBgA8pxU1sMDvRWKpvJKNs3jNhZPQWFf4Tszu/cMcb +1qAQ/q0DRb41VvsUoMaCfef/plZleV4MG26owb574AJeC86wX5MbRDTPS4CzAn+I +an92AZl3vlYRQ2sSo3ktkyhw6LV1iewi08Ky7J4rqvG0Oo335QGEZlK1OgwBsyh0 +FKLe +-----END PUBLIC KEY----- diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pub-2048.der b/tests/auto/network/ssl/qsslkey/keys/dh-pub-2048.der new file mode 100644 index 0000000000000000000000000000000000000000..9e749d8a41c67e743870d9811cefe96d4db01c34 GIT binary patch literal 552 zcmV+@0@wX8f&wHkf&mu>2`Yw2hW8Bt0|79C0SE$u0RaG;B1PhH1~~%ke7*DnKu+r_ zV#81#80dL2&vr_2<{>r+^Y`;4ud8YJ@``e`Cs;l18VzNywI1noNwABRvT+Gq$F%x&q}tKup@ydO}iGgtlPQLBJ zNu)vj9ah|~Uy0}_dTSnQKxHzDt7T2S?^bIVVFs`s5(mM9rvY zhS!U;H(kiKtej0Kucl{Rg6}HC^-}JTz&AJ$?L{PXoT2Bb&ceS{7Z=RRWB*iT_+Lc) z2&4+3(XM;QO5M4_va~Y{yyt`VPq#^w6JEj2uM?vJ0RjVp0R;d8f&l;&d1P*?IeQn* z6iSFOB;z$RjJ(LJL1B%GF3w^hSaVl}8T;RyFxEh#($^>Vyaat6i5)VNyJN&Yp^iG8 z`h1#vi3u3-B@D^aZ4<|XoY`Q>h~&TCeblBn_RQ@ID0a37<*EhY&f$#4|8m<{RBf2L zn=<0p&PL$dz`pdlnvSEY7zt49pQn8=?DcQR0z4 z4(}zE)+KWiSpC=BqWgw&=`y_15xSRsL*=^(q~~sgb{VwYazdOwuw?pTC#jM+E&Em^ q7+9i4&TkH010CiE$OucIe{Lzsx2uU^Xy=pWX?yFKJnp0e>+9>#dlM-D literal 0 HcmV?d00001 diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pub-2048.pem b/tests/auto/network/ssl/qsslkey/keys/dh-pub-2048.pem new file mode 100644 index 0000000000..f751157c87 --- /dev/null +++ b/tests/auto/network/ssl/qsslkey/keys/dh-pub-2048.pem @@ -0,0 +1,14 @@ +-----BEGIN PUBLIC KEY----- +MIICJDCCARcGCSqGSIb3DQEDATCCAQgCggEBAJsiReJxBjkC7Hy99AJATusqYsNQ +HhjoeTLPeHhsBuLtJK18Krk736V09efX6qeAEmvgMQbvbHqtrOaY3q6dut6CUTGV +W+oVg3d/Y8qakkanvEnIlliaTIyWIz0JMjO2prC6AuU/QEzZcQVUS6bxyn3DiYFx +CE6+7cJJpEH9HVbcrl+J6Ch6ax5rQGUyxpSMkmItLJx92upRxOnaxJMHR+ZFOSdD +PfrkINpEzahnhteLszddyLasnE0or6ZnXYLvKsT1Uu6QwDc4EO1FJHScoeepzsK/ +VRcXzMpj/1Rl+F9E/AikCqHRrnvISt25wrK0Mwy854P2T7dJlBNewc6vE6MCAQID +ggEFAAKCAQAUeWRuqjl7F84USogxJOM1M4y8yKtBYY2KLs5iIVhzV4UZ+9+cMNZA +otLXJ/e8BH0diR0yk7tjxD6hjjqd+nyafIkJGPElDMnTbRPHg5zZYMmI5L/efdSm +OPbM7QsodrYH5aoF4c7hjMb/cttYVG2Yupsy4tfORuDbwL70upqOo6rkVq55eOGS +6pseEume/SD+7e3xIPJTkrMMzBFHG6H7bVHikT4O7yWV1iVzElj919yi+4Zy6TK8 +0hG6l31D5bsJpOduhHYZtN1yQpw+sGT6Yiepkjgt+1YkGFiiRs5vDl4DHeYHyAhL +oH9uKcm3q4lhaOeT5ml765g87qQD6+vr +-----END PUBLIC KEY----- diff --git a/tests/auto/network/ssl/qsslkey/keys/dh-pub-512.der b/tests/auto/network/ssl/qsslkey/keys/dh-pub-512.der new file mode 100644 index 0000000000000000000000000000000000000000..8a75babb6df4d7283df84d18fafabd3b9ad5bbdf GIT binary patch literal 157 zcmV;O0Al|zftoN=1_>&LNQUa;8VnGHG<0s#U8LjVFmL||d` zS&>DSK*SqYW@Nm;hy%fE;|HzAL*X@~GVNsi?Y#6hdZi;y1g;pRd2lwTkOg%= 0) { keyInfoList << KeyInfo( fileInfo, rx.cap(1) == QLatin1String("rsa") ? QSsl::Rsa : - (rx.cap(1) == QLatin1String("dsa") ? QSsl::Dsa : QSsl::Ec), + rx.cap(1) == QLatin1String("dsa") ? QSsl::Dsa : + rx.cap(1) == QLatin1String("dh") ? QSsl::Dh : QSsl::Ec, rx.cap(2) == QLatin1String("pub") ? QSsl::PublicKey : QSsl::PrivateKey, rx.cap(3).toInt(), rx.cap(4) == QLatin1String("pem") ? QSsl::Pem : QSsl::Der); From 079df681ec546bd3d644efabc90604708cecadff Mon Sep 17 00:00:00 2001 From: Lars Schmertmann Date: Tue, 6 Nov 2018 18:41:08 +0100 Subject: [PATCH 0407/1650] Amend 7f77dc84fb to simplify the parameters of createPlainTestRows Change-Id: I61370a46722f729ea53cb365eab556a97ec5ee7b Reviewed-by: Edward Welbourne --- tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp b/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp index a257becfd2..70001f7375 100644 --- a/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp +++ b/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp @@ -63,7 +63,7 @@ class tst_QSslKey : public QObject QList keyInfoList; - void createPlainTestRows(bool filter = false, QSsl::EncodingFormat format = QSsl::EncodingFormat::Pem); + void createPlainTestRows(bool pemOnly = false); public slots: void initTestCase(); @@ -155,7 +155,7 @@ Q_DECLARE_METATYPE(QSsl::KeyAlgorithm) Q_DECLARE_METATYPE(QSsl::KeyType) Q_DECLARE_METATYPE(QSsl::EncodingFormat) -void tst_QSslKey::createPlainTestRows(bool filter, QSsl::EncodingFormat format) +void tst_QSslKey::createPlainTestRows(bool pemOnly) { QTest::addColumn("absFilePath"); QTest::addColumn("algorithm"); @@ -163,7 +163,7 @@ void tst_QSslKey::createPlainTestRows(bool filter, QSsl::EncodingFormat format) QTest::addColumn("length"); QTest::addColumn("format"); foreach (KeyInfo keyInfo, keyInfoList) { - if (filter && keyInfo.format != format) + if (pemOnly && keyInfo.format != QSsl::EncodingFormat::Pem) continue; #ifdef Q_OS_WINRT if (keyInfo.fileInfo.fileName().contains("RC2-64")) From 27f08ab49479b1cbd3f99e28cbe8b0a89a23bd10 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 20 Jul 2018 09:32:05 +0200 Subject: [PATCH 0408/1650] Long live Q_DISABLE_COPY_MOVE! When using Q_DISABLE_COPY, clang-tidy reports: warning: class 'Foo' defines a non-default destructor, a copy constructor and a copy assignment operator but does not define a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions] Add convenience macros to suppress move constructor/assignment as well. [ChangeLog][QtCore] Added macros Q_DISABLE_MOVE and Q_DISABLE_COPY_MOVE complementing Q_DISABLE_COPY. Change-Id: I0b07495ef4ef06c714f7368c706168613c3fe7bc Reviewed-by: Edward Welbourne Reviewed-by: Ulf Hermann --- src/corelib/global/qglobal.cpp | 25 +++++++++++++++++++++++++ src/corelib/global/qglobal.h | 8 ++++++++ 2 files changed, 33 insertions(+) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 046d4b7b2a..8da94c8624 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -525,6 +525,31 @@ Q_STATIC_ASSERT((std::is_same::value)); made private. In that case, no error would be reported, but your application would probably crash when you called a member function of \c{w}. + + \sa Q_DISABLE_COPY_MOVE, Q_DISABLE_MOVE +*/ + +/*! + \macro Q_DISABLE_MOVE(Class) + \relates QObject + + Disables the use of move constructors and move assignment operators + for the given \a Class. + + \sa Q_DISABLE_COPY, Q_DISABLE_COPY_MOVE + \since 5.13 +*/ + +/*! + \macro Q_DISABLE_COPY_MOVE(Class) + \relates QObject + + A convenience macro that disables the use of copy constructors, assignment + operators, move constructors and move assignment operators for the given + \a Class, combining Q_DISABLE_COPY and Q_DISABLE_MOVE. + + \sa Q_DISABLE_COPY, Q_DISABLE_MOVE + \since 5.13 */ /*! diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 8680742c94..e3073d80ec 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -372,6 +372,14 @@ typedef double qreal; Class(const Class &) Q_DECL_EQ_DELETE;\ Class &operator=(const Class &) Q_DECL_EQ_DELETE; +#define Q_DISABLE_MOVE(Class) \ + Class(Class &&) = delete; \ + Class &operator=(Class &&) = delete; + +#define Q_DISABLE_COPY_MOVE(Class) \ + Q_DISABLE_COPY(Class) \ + Q_DISABLE_MOVE(Class) + /* No, this is not an evil backdoor. QT_BUILD_INTERNAL just exports more symbols for Qt's internal unit tests. If you want slower loading times and more From 7264bf19dbc47b805bb7af5df584ce1aae081962 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 21 Nov 2018 09:06:50 +0100 Subject: [PATCH 0409/1650] Windows: Add a default setting for hasBorderInFullScreen The hasBorderInFullScreen only has an effect when set before the window is shown or switched to fullscreen. This is currently not possible in the QML case since the window is only accessible after all properties (including visibility) have been set. Add a function to set a default value. [ChangeLog][QtPlatformHeaders][QWindowsWindowFunctions] Add a default setting for hasBorderInFullScreen Task-number: QTBUG-47247 Task-number: QTBUG-71855 Change-Id: I3952e3f34bc4eb134cf1c5265b4489fc74112688 Reviewed-by: Andre de la Rocha Reviewed-by: Andy Shaw --- .../qwindowswindowfunctions.h | 9 +++++ .../qwindowswindowfunctions.qdoc | 33 +++++++++++++++++++ .../windows/qwindowsnativeinterface.cpp | 2 ++ .../platforms/windows/qwindowswindow.cpp | 8 ++++- .../platforms/windows/qwindowswindow.h | 2 ++ 5 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/platformheaders/windowsfunctions/qwindowswindowfunctions.h b/src/platformheaders/windowsfunctions/qwindowswindowfunctions.h index e51c2fde67..032dcafa6e 100644 --- a/src/platformheaders/windowsfunctions/qwindowswindowfunctions.h +++ b/src/platformheaders/windowsfunctions/qwindowswindowfunctions.h @@ -81,6 +81,15 @@ public: func(window, border); } + typedef void (*SetHasBorderInFullScreenDefault)(bool border); + static const QByteArray setHasBorderInFullScreenDefaultIdentifier() { return QByteArrayLiteral("WindowsSetHasBorderInFullScreenDefault"); } + static void setHasBorderInFullScreenDefault(bool border) + { + auto func = reinterpret_cast(QGuiApplication::platformFunction(setHasBorderInFullScreenDefaultIdentifier())); + if (func) + func(border); + } + typedef void (*SetWindowActivationBehaviorType)(WindowActivationBehavior); static const QByteArray setWindowActivationBehaviorIdentifier() { return QByteArrayLiteral("WindowsSetWindowActivationBehavior"); } diff --git a/src/platformheaders/windowsfunctions/qwindowswindowfunctions.qdoc b/src/platformheaders/windowsfunctions/qwindowswindowfunctions.qdoc index a52bbe061b..0c52cde753 100644 --- a/src/platformheaders/windowsfunctions/qwindowswindowfunctions.qdoc +++ b/src/platformheaders/windowsfunctions/qwindowswindowfunctions.qdoc @@ -93,9 +93,42 @@ is true then it will enable the WS_BORDER flag in full screen mode to enable other top level windows inside the application to appear on top when required. + \note The setting must be applied before showing the window or switching it + to full screen. For QML, setHasBorderInFullScreenDefault() can be used to + set a default value. + See also \l [QtDoc] {Fullscreen OpenGL Based Windows} */ +/*! + \typedef QWindowsWindowFunctions::SetHasBorderInFullScreenDefault + \since 5.13 + + This is the typedef for the function returned by QGuiApplication::platformFunction + when passed setHasBorderInFullScreenDefaultIdentifier. +*/ + +/*! + \fn QByteArray QWindowsWindowFunctions::setHasBorderInFullScreenDefaultIdentifier() + \since 5.13 + + This function returns the bytearray that can be used to query + QGuiApplication::platformFunction to retrieve the SetHasBorderInFullScreen function. +*/ + +/*! + \fn void QWindowsWindowFunctions::setHasBorderInFullScreenDefault(bool border) + \since 5.13 + + This is a convenience function that can be used directly instead of resolving + the function pointer. \a border will be relayed to the function retrieved by + QGuiApplication. When \a border is true, the WS_BORDER flag will be set + in full screen mode for all windows by default. + + See also \l [QtDoc] {Fullscreen OpenGL Based Windows} + \sa setHasBorderInFullScreen() +*/ + /*! \enum QWindowsWindowFunctions::WindowActivationBehavior diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp index de11356fd4..a1ff6f1141 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp @@ -277,6 +277,8 @@ QFunctionPointer QWindowsNativeInterface::platformFunction(const QByteArray &fun return QFunctionPointer(QWindowsWindow::setTouchWindowTouchTypeStatic); if (function == QWindowsWindowFunctions::setHasBorderInFullScreenIdentifier()) return QFunctionPointer(QWindowsWindow::setHasBorderInFullScreenStatic); + if (function == QWindowsWindowFunctions::setHasBorderInFullScreenDefaultIdentifier()) + return QFunctionPointer(QWindowsWindow::setHasBorderInFullScreenDefault); if (function == QWindowsWindowFunctions::setWindowActivationBehaviorIdentifier()) return QFunctionPointer(QWindowsNativeInterface::setWindowActivationBehavior); if (function == QWindowsWindowFunctions::isTabletModeIdentifier()) diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index f340f16679..6201da7b72 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1190,6 +1190,7 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w, const char *QWindowsWindow::embeddedNativeParentHandleProperty = "_q_embedded_native_parent_handle"; const char *QWindowsWindow::hasBorderInFullScreenProperty = "_q_has_border_in_fullscreen"; +bool QWindowsWindow::m_borderInFullScreenDefault = false; QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data) : QWindowsBaseWindow(aWindow), @@ -1227,7 +1228,7 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data) if (aWindow->isTopLevel()) setWindowIcon(aWindow->icon()); - if (aWindow->property(hasBorderInFullScreenProperty).toBool()) + if (m_borderInFullScreenDefault || aWindow->property(hasBorderInFullScreenProperty).toBool()) setFlag(HasBorderInFullScreen); clearFlag(WithinCreate); } @@ -2804,6 +2805,11 @@ void QWindowsWindow::setHasBorderInFullScreenStatic(QWindow *window, bool border window->setProperty(hasBorderInFullScreenProperty, QVariant(border)); } +void QWindowsWindow::setHasBorderInFullScreenDefault(bool border) +{ + m_borderInFullScreenDefault = border; +} + void QWindowsWindow::setHasBorderInFullScreen(bool border) { if (testFlag(HasBorderInFullScreen) == border) diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index e8c30bd44b..4d136151fe 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -338,6 +338,7 @@ public: static void setTouchWindowTouchTypeStatic(QWindow *window, QWindowsWindowFunctions::TouchWindowTouchTypes touchTypes); void registerTouchWindow(QWindowsWindowFunctions::TouchWindowTouchTypes touchTypes = QWindowsWindowFunctions::NormalTouch); static void setHasBorderInFullScreenStatic(QWindow *window, bool border); + static void setHasBorderInFullScreenDefault(bool border); void setHasBorderInFullScreen(bool border); static QString formatWindowTitle(const QString &title); @@ -381,6 +382,7 @@ private: // note: intentionally not using void * in order to avoid breaking x86 VkSurfaceKHR m_vkSurface = 0; #endif + static bool m_borderInFullScreenDefault; }; #ifndef QT_NO_DEBUG_STREAM From bfe53c7da57f402c66d8266b1f59469c40746321 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 13 Aug 2018 22:04:11 +0200 Subject: [PATCH 0410/1650] Optimize QRgba64::toArgb32() and premultiplied() Using similar techniques as used for QRgb qPremultiply and friends Change-Id: I4be68cb01dc3b634cf370323884e824674205998 Reviewed-by: Thiago Macieira --- src/gui/painting/qrgba64.h | 40 ++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/src/gui/painting/qrgba64.h b/src/gui/painting/qrgba64.h index 0e5344cacb..0e0b567890 100644 --- a/src/gui/painting/qrgba64.h +++ b/src/gui/painting/qrgba64.h @@ -118,7 +118,27 @@ public: Q_DECL_CONSTEXPR quint8 alpha8() const { return div_257(alpha()); } Q_DECL_CONSTEXPR uint toArgb32() const { +#if defined(__cpp_constexpr) && __cpp_constexpr-0 >= 201304 + quint64 br = rgba & Q_UINT64_C(0xffff0000ffff); + quint64 ag = (rgba >> 16) & Q_UINT64_C(0xffff0000ffff); + br += Q_UINT64_C(0x8000000080); + ag += Q_UINT64_C(0x8000000080); + br = (br - ((br >> 8) & Q_UINT64_C(0xffff0000ffff))) >> 8; + ag = (ag - ((ag >> 8) & Q_UINT64_C(0xffff0000ffff))); +#if Q_BYTE_ORDER == Q_BIG_ENDIAN + return ((br << 24) & 0xff000000) + | ((ag >> 24) & 0xff0000) + | ((br >> 24) & 0xff00) + | ((ag >> 8) & 0xff); +#else + return ((ag >> 16) & 0xff000000) + | ((br << 16) & 0xff0000) + | (ag & 0xff00) + | ((br >> 32) & 0xff); +#endif +#else return uint((alpha8() << 24) | (red8() << 16) | (green8() << 8) | blue8()); +#endif } Q_DECL_CONSTEXPR ushort toRgb16() const { @@ -131,11 +151,20 @@ public: return *this; if (isTransparent()) return QRgba64::fromRgba64(0); - const quint32 a = alpha(); - const quint16 r = div_65535(red() * a); - const quint16 g = div_65535(green() * a); - const quint16 b = div_65535(blue() * a); - return fromRgba64(r, g, b, quint16(a)); + const quint64 a = alpha(); + quint64 br = (rgba & Q_UINT64_C(0xffff0000ffff)) * a; + quint64 ag = ((rgba >> 16) & Q_UINT64_C(0xffff0000ffff)) * a; + br = (br + ((br >> 16) & Q_UINT64_C(0xffff0000ffff)) + Q_UINT64_C(0x800000008000)); + ag = (ag + ((ag >> 16) & Q_UINT64_C(0xffff0000ffff)) + Q_UINT64_C(0x800000008000)); +#if Q_BYTE_ORDER == Q_BIG_ENDIAN + ag = ag & Q_UINT64_C(0xffff0000ffff0000); + br = (br >> 16) & Q_UINT64_C(0xffff00000000); + return fromRgba64(a | br | ag); +#else + br = (br >> 16) & Q_UINT64_C(0xffff0000ffff); + ag = ag & Q_UINT64_C(0xffff0000); + return fromRgba64((a << 48) | br | ag); +#endif } Q_DECL_RELAXED_CONSTEXPR QRgba64 unpremultiplied() const @@ -163,7 +192,6 @@ private: static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE quint8 div_257_floor(uint x) { return quint8((x - (x >> 8)) >> 8); } static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE quint8 div_257(quint16 x) { return div_257_floor(x + 128U); } - static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE quint16 div_65535(uint x) { return quint16((x + (x>>16) + 0x8000U) >> 16); } Q_DECL_RELAXED_CONSTEXPR Q_ALWAYS_INLINE QRgba64 unpremultiplied_32bit() const { if (isOpaque() || isTransparent()) From 70d131af33c8b411f430d0699b4294b5976db8e3 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 23 Nov 2018 13:23:28 +0100 Subject: [PATCH 0411/1650] Windows: Fix embedded application not getting focus after clicking outside Amend the check introduced by bde6a049494f40cd71004d6926899f115af0c3e6 to not apply to embedded windows and plugin applications. Fixes: QTBUG-71991 Task-number: QTBUG-7081 Change-Id: I80b3dc0fa20ee3447a4bc4bbb41e66d4d90ab726 Reviewed-by: Shawn Rutledge --- src/widgets/kernel/qwidget.cpp | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index e59fbb8963..bcfae46155 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -6592,20 +6592,25 @@ QWidget *QWidgetPrivate::deepestFocusProxy() const return focusProxy; } +static inline bool isEmbedded(const QWindow *w) +{ + const auto platformWindow = w->handle(); + return platformWindow && platformWindow->isEmbedded(); +} + void QWidgetPrivate::setFocus_sys() { Q_Q(QWidget); // Embedded native widget may have taken the focus; get it back to toplevel // if that is the case (QTBUG-25852) - const QWidget *topLevel = q->window(); - // Do not activate in case the popup menu opens another application (QTBUG-70810). - if (QGuiApplication::applicationState() == Qt::ApplicationActive - && topLevel->windowType() != Qt::Popup) { - if (QWindow *nativeWindow = q->window()->windowHandle()) { - if (nativeWindow != QGuiApplication::focusWindow() - && q->testAttribute(Qt::WA_WState_Created)) { - nativeWindow->requestActivate(); - } + // Do not activate in case the popup menu opens another application (QTBUG-70810) + // unless the application is embedded (QTBUG-71991). + if (QWindow *nativeWindow = q->testAttribute(Qt::WA_WState_Created) ? q->window()->windowHandle() : nullptr) { + if (nativeWindow->type() != Qt::Popup && nativeWindow != QGuiApplication::focusWindow() + && (QGuiApplication::applicationState() == Qt::ApplicationActive + || QCoreApplication::testAttribute(Qt::AA_PluginApplication) + || isEmbedded(nativeWindow))) { + nativeWindow->requestActivate(); } } } From 45a6397e3eefdd98a13bcc59895125779915f445 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 5 Nov 2018 11:07:04 +0100 Subject: [PATCH 0412/1650] QStyleHintsPrivate: Use member initialization Task-number: QTBUG-71471 Change-Id: I368193bc363944825c01da5337738fd0a7ba2219 Reviewed-by: Shawn Rutledge --- src/gui/kernel/qstylehints.cpp | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/src/gui/kernel/qstylehints.cpp b/src/gui/kernel/qstylehints.cpp index 48060a2c37..b00e6fb0fd 100644 --- a/src/gui/kernel/qstylehints.cpp +++ b/src/gui/kernel/qstylehints.cpp @@ -69,29 +69,16 @@ class QStyleHintsPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QStyleHints) public: - inline QStyleHintsPrivate() - : m_mouseDoubleClickInterval(-1) - , m_mousePressAndHoldInterval(-1) - , m_startDragDistance(-1) - , m_startDragTime(-1) - , m_keyboardInputInterval(-1) - , m_cursorFlashTime(-1) - , m_tabFocusBehavior(-1) - , m_uiEffects(-1) - , m_wheelScrollLines(-1) - , m_mouseQuickSelectionThreshold(-1) - {} - - int m_mouseDoubleClickInterval; - int m_mousePressAndHoldInterval; - int m_startDragDistance; - int m_startDragTime; - int m_keyboardInputInterval; - int m_cursorFlashTime; - int m_tabFocusBehavior; - int m_uiEffects; - int m_wheelScrollLines; - int m_mouseQuickSelectionThreshold; + int m_mouseDoubleClickInterval = -1; + int m_mousePressAndHoldInterval = -1; + int m_startDragDistance = -1; + int m_startDragTime = -1; + int m_keyboardInputInterval = -1; + int m_cursorFlashTime = -1; + int m_tabFocusBehavior = -1; + int m_uiEffects = -1; + int m_wheelScrollLines = -1; + int m_mouseQuickSelectionThreshold = -1; }; /*! From b1a9a7794f51dd214e884fe331c5d1009972a48e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 5 Nov 2018 11:31:19 +0100 Subject: [PATCH 0413/1650] Add setter for property QStyleHints::showShortcutsInContextMenus Add a tri-state setter logic similar to the other properties. Fixes: QTBUG-71471 Change-Id: Iddb5be18a037634a53ad8725bddb91c12fb33fed Reviewed-by: Shawn Rutledge --- src/gui/kernel/qstylehints.cpp | 18 +++++++++++++++++- src/gui/kernel/qstylehints.h | 4 +++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qstylehints.cpp b/src/gui/kernel/qstylehints.cpp index b00e6fb0fd..9b5b7a6f1e 100644 --- a/src/gui/kernel/qstylehints.cpp +++ b/src/gui/kernel/qstylehints.cpp @@ -77,6 +77,7 @@ public: int m_cursorFlashTime = -1; int m_tabFocusBehavior = -1; int m_uiEffects = -1; + int m_showShortcutsInContextMenus = -1; int m_wheelScrollLines = -1; int m_mouseQuickSelectionThreshold = -1; }; @@ -358,10 +359,25 @@ bool QStyleHints::showIsMaximized() const \since 5.10 \brief \c true if the platform normally shows shortcut key sequences in context menus, otherwise \c false. + + Since Qt 5.13, the setShowShortcutsInContextMenus() function can be used to + override the platform default. */ bool QStyleHints::showShortcutsInContextMenus() const { - return themeableHint(QPlatformTheme::ShowShortcutsInContextMenus, QPlatformIntegration::ShowShortcutsInContextMenus).toBool(); + Q_D(const QStyleHints); + return d->m_showShortcutsInContextMenus >= 0 + ? d->m_showShortcutsInContextMenus != 0 + : themeableHint(QPlatformTheme::ShowShortcutsInContextMenus, QPlatformIntegration::ShowShortcutsInContextMenus).toBool(); +} + +void QStyleHints::setShowShortcutsInContextMenus(bool s) +{ + Q_D(QStyleHints); + if (s != showShortcutsInContextMenus()) { + d->m_showShortcutsInContextMenus = s ? 1 : 0; + emit showShortcutsInContextMenusChanged(s); + } } /*! diff --git a/src/gui/kernel/qstylehints.h b/src/gui/kernel/qstylehints.h index 7b0683e9b1..9091db9624 100644 --- a/src/gui/kernel/qstylehints.h +++ b/src/gui/kernel/qstylehints.h @@ -64,7 +64,7 @@ class Q_GUI_EXPORT QStyleHints : public QObject Q_PROPERTY(bool setFocusOnTouchRelease READ setFocusOnTouchRelease STORED false CONSTANT FINAL) Q_PROPERTY(bool showIsFullScreen READ showIsFullScreen STORED false CONSTANT FINAL) Q_PROPERTY(bool showIsMaximized READ showIsMaximized STORED false CONSTANT FINAL) - Q_PROPERTY(bool showShortcutsInContextMenus READ showShortcutsInContextMenus STORED false CONSTANT FINAL) + Q_PROPERTY(bool showShortcutsInContextMenus READ showShortcutsInContextMenus WRITE setShowShortcutsInContextMenus NOTIFY showShortcutsInContextMenusChanged FINAL) Q_PROPERTY(int startDragDistance READ startDragDistance NOTIFY startDragDistanceChanged FINAL) Q_PROPERTY(int startDragTime READ startDragTime NOTIFY startDragTimeChanged FINAL) Q_PROPERTY(int startDragVelocity READ startDragVelocity STORED false CONSTANT FINAL) @@ -93,6 +93,7 @@ public: bool showIsFullScreen() const; bool showIsMaximized() const; bool showShortcutsInContextMenus() const; + void setShowShortcutsInContextMenus(bool showShortcutsInContextMenus); int passwordMaskDelay() const; QChar passwordMaskCharacter() const; qreal fontSmoothingGamma() const; @@ -117,6 +118,7 @@ Q_SIGNALS: void startDragTimeChanged(int startDragTime); void tabFocusBehaviorChanged(Qt::TabFocusBehavior tabFocusBehavior); void useHoverEffectsChanged(bool useHoverEffects); + void showShortcutsInContextMenusChanged(bool); void wheelScrollLinesChanged(int scrollLines); void mouseQuickSelectionThresholdChanged(int threshold); From e824136a3b850e7b2760bbef7b9572332ca4a285 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 22 Nov 2018 09:26:09 +0100 Subject: [PATCH 0414/1650] Rename VcProjGenerator::[autogen]precompCPP to [autogen]precompSource Those names are a better fit as we want to support C precompiled headers in a subsequent commit. Change-Id: Ie3f852da945b9b2cf0e363c81f1a4b3063f27372 Reviewed-by: Oliver Wolff --- qmake/generators/win32/msvc_objectmodel.cpp | 8 ++++---- qmake/generators/win32/msvc_vcproj.cpp | 14 +++++++------- qmake/generators/win32/msvc_vcproj.h | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp index 4f0cee65e1..442010a3a9 100644 --- a/qmake/generators/win32/msvc_objectmodel.cpp +++ b/qmake/generators/win32/msvc_objectmodel.cpp @@ -2213,8 +2213,8 @@ void VCFilter::addFiles(const ProStringList& fileList) void VCFilter::modifyPCHstage(QString str) { - bool autogenSourceFile = Project->autogenPrecompCPP; - bool pchThroughSourceFile = !Project->precompCPP.isEmpty(); + bool autogenSourceFile = Project->autogenPrecompSource; + bool pchThroughSourceFile = !Project->precompSource.isEmpty(); bool isCFile = false; for (QStringList::Iterator it = Option::c_ext.begin(); it != Option::c_ext.end(); ++it) { if (str.endsWith(*it)) { @@ -2223,7 +2223,7 @@ void VCFilter::modifyPCHstage(QString str) } } const bool isHFile = (str == Project->precompH); - bool isCPPFile = pchThroughSourceFile && (str == Project->precompCPP); + bool isCPPFile = pchThroughSourceFile && (str == Project->precompSource); if(!isCFile && !isHFile && !isCPPFile) return; @@ -2231,7 +2231,7 @@ void VCFilter::modifyPCHstage(QString str) if(isHFile && pchThroughSourceFile) { if (autogenSourceFile) { useCustomBuildTool = true; - QString toFile(Project->precompCPP); + QString toFile(Project->precompSource); CustomBuildTool.Description = "Generating precompiled header source file '" + toFile + "' ..."; CustomBuildTool.Outputs += toFile; diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index db2a16ae35..8c0b801891 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -775,7 +775,7 @@ void VcprojGenerator::init() // Setup PCH variables precompH = project->first("PRECOMPILED_HEADER").toQString(); - precompCPP = project->first("PRECOMPILED_SOURCE").toQString(); + precompSource = project->first("PRECOMPILED_SOURCE").toQString(); usePCH = !precompH.isEmpty() && project->isActiveConfig("precompile_header"); if (usePCH) { precompHFilename = fileInfo(precompH).fileName(); @@ -790,13 +790,13 @@ void VcprojGenerator::init() project->values("PRECOMPILED_OBJECT") = ProStringList(precompObj); project->values("PRECOMPILED_PCH") = ProStringList(precompPch); - autogenPrecompCPP = precompCPP.isEmpty() && project->isActiveConfig("autogen_precompile_source"); - if (autogenPrecompCPP) { - precompCPP = precompH + autogenPrecompSource = precompSource.isEmpty() && project->isActiveConfig("autogen_precompile_source"); + if (autogenPrecompSource) { + precompSource = precompH + (Option::cpp_ext.count() ? Option::cpp_ext.at(0) : QLatin1String(".cpp")); - project->values("GENERATED_SOURCES") += precompCPP; - } else if (!precompCPP.isEmpty()) { - project->values("SOURCES") += precompCPP; + project->values("GENERATED_SOURCES") += precompSource; + } else if (!precompSource.isEmpty()) { + project->values("SOURCES") += precompSource; } } diff --git a/qmake/generators/win32/msvc_vcproj.h b/qmake/generators/win32/msvc_vcproj.h index 6af5ec7007..fafc69d9ab 100644 --- a/qmake/generators/win32/msvc_vcproj.h +++ b/qmake/generators/win32/msvc_vcproj.h @@ -57,9 +57,9 @@ public: ~VcprojGenerator(); QString defaultMakefile() const; - QString precompH, precompHFilename, precompCPP, + QString precompH, precompHFilename, precompSource, precompObj, precompPch; - bool autogenPrecompCPP; + bool autogenPrecompSource; static bool hasBuiltinCompiler(const QString &file); QHash extraCompilerSources; From 54fc1b5ae6d87e6de233eb30f26e7c8d2cad05ba Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 22 Nov 2018 11:07:16 +0100 Subject: [PATCH 0415/1650] Remove variable autogenSourceFile from VCFilter::modifyPCHstage There's no point in having it, and this will reduce the diff of a subsequent commit. Change-Id: I3d27d6808c585b87a44df2499f2fcea4331befbb Reviewed-by: Oliver Wolff --- qmake/generators/win32/msvc_objectmodel.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp index 442010a3a9..30c2239232 100644 --- a/qmake/generators/win32/msvc_objectmodel.cpp +++ b/qmake/generators/win32/msvc_objectmodel.cpp @@ -2213,7 +2213,6 @@ void VCFilter::addFiles(const ProStringList& fileList) void VCFilter::modifyPCHstage(QString str) { - bool autogenSourceFile = Project->autogenPrecompSource; bool pchThroughSourceFile = !Project->precompSource.isEmpty(); bool isCFile = false; for (QStringList::Iterator it = Option::c_ext.begin(); it != Option::c_ext.end(); ++it) { @@ -2229,7 +2228,7 @@ void VCFilter::modifyPCHstage(QString str) return; if(isHFile && pchThroughSourceFile) { - if (autogenSourceFile) { + if (Project->autogenPrecompSource) { useCustomBuildTool = true; QString toFile(Project->precompSource); CustomBuildTool.Description = "Generating precompiled header source file '" + toFile + "' ..."; @@ -2266,7 +2265,7 @@ void VCFilter::modifyPCHstage(QString str) CompilerTool.UsePrecompiledHeader = (isCFile ? pchNone : pchCreateUsingSpecific); if (isCFile) CompilerTool.PrecompiledHeaderThrough = QLatin1String("$(NOINHERIT)"); - else if (autogenSourceFile) + else if (Project->autogenPrecompSource) CompilerTool.PrecompiledHeaderThrough = Project->precompHFilename; CompilerTool.ForcedIncludeFiles = QStringList("$(NOINHERIT)"); } From e5f94f0f0586b2240691f4b17be513b45feac440 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 22 Nov 2018 11:10:32 +0100 Subject: [PATCH 0416/1650] Simplify VCFilter::modifyPCHstage a bit Merge two nested if blocks. This reduces the diff size for a subsequent commit. Change-Id: If60938077169fc6686329cc5c30ebc97ada013a1 Reviewed-by: Oliver Wolff --- qmake/generators/win32/msvc_objectmodel.cpp | 54 ++++++++++----------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp index 30c2239232..b9ecb14888 100644 --- a/qmake/generators/win32/msvc_objectmodel.cpp +++ b/qmake/generators/win32/msvc_objectmodel.cpp @@ -2227,36 +2227,34 @@ void VCFilter::modifyPCHstage(QString str) if(!isCFile && !isHFile && !isCPPFile) return; - if(isHFile && pchThroughSourceFile) { - if (Project->autogenPrecompSource) { - useCustomBuildTool = true; - QString toFile(Project->precompSource); - CustomBuildTool.Description = "Generating precompiled header source file '" + toFile + "' ..."; - CustomBuildTool.Outputs += toFile; + if (isHFile && pchThroughSourceFile && Project->autogenPrecompSource) { + useCustomBuildTool = true; + QString toFile(Project->precompSource); + CustomBuildTool.Description = "Generating precompiled header source file '" + toFile + "' ..."; + CustomBuildTool.Outputs += toFile; - QStringList lines; - CustomBuildTool.CommandLine += + QStringList lines; + CustomBuildTool.CommandLine += "echo /*-------------------------------------------------------------------- >" + toFile; - lines << "* Precompiled header source file used by Visual Studio.NET to generate"; - lines << "* the .pch file."; - lines << "*"; - lines << "* Due to issues with the dependencies checker within the IDE, it"; - lines << "* sometimes fails to recompile the PCH file, if we force the IDE to"; - lines << "* create the PCH file directly from the header file."; - lines << "*"; - lines << "* This file is auto-generated by qmake since no PRECOMPILED_SOURCE was"; - lines << "* specified, and is used as the common stdafx.cpp. The file is only"; - lines << QLatin1String("* generated when creating ") - + (Config->CompilerVersion < NET2010 ? ".vcproj" : ".vcxproj") - + " project files, and is not used for"; - lines << "* command line compilations by nmake."; - lines << "*"; - lines << "* WARNING: All changes made in this file will be lost."; - lines << "--------------------------------------------------------------------*/"; - lines << "#include \"" + Project->precompHFilename + "\""; - for (const QString &line : qAsConst(lines)) - CustomBuildTool.CommandLine += "echo " + line + ">>" + toFile; - } + lines << "* Precompiled header source file used by Visual Studio.NET to generate"; + lines << "* the .pch file."; + lines << "*"; + lines << "* Due to issues with the dependencies checker within the IDE, it"; + lines << "* sometimes fails to recompile the PCH file, if we force the IDE to"; + lines << "* create the PCH file directly from the header file."; + lines << "*"; + lines << "* This file is auto-generated by qmake since no PRECOMPILED_SOURCE was"; + lines << "* specified, and is used as the common stdafx.cpp. The file is only"; + lines << QLatin1String("* generated when creating ") + + (Config->CompilerVersion < NET2010 ? ".vcproj" : ".vcxproj") + + " project files, and is not used for"; + lines << "* command line compilations by nmake."; + lines << "*"; + lines << "* WARNING: All changes made in this file will be lost."; + lines << "--------------------------------------------------------------------*/"; + lines << "#include \"" + Project->precompHFilename + "\""; + for (const QString &line : qAsConst(lines)) + CustomBuildTool.CommandLine += "echo " + line + ">>" + toFile; return; } From e04aaf188c735b775dc4483099ec61a9372b0fa8 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 22 Nov 2018 09:35:38 +0100 Subject: [PATCH 0417/1650] Support 'CONFIG += precompile_header_c' in VS projects The CONFIG value precompile_header_c was ignored in the VS project generator. Add a member VcprojGenerator::pchIsCFile that is set to true if precompile_header_c is active. The code in modifyPCHstage had to be rearranged to separate the three parts for stable.h, stable.cpp and other files. Task-number: QTBUG-62821 Change-Id: I340eb165baa22cafcb64815cf223ce9a21aca558 Reviewed-by: Oliver Wolff --- qmake/generators/win32/msvc_objectmodel.cpp | 42 +++++++++++---------- qmake/generators/win32/msvc_vcproj.cpp | 7 +++- qmake/generators/win32/msvc_vcproj.h | 1 + 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp index b9ecb14888..7caa94c512 100644 --- a/qmake/generators/win32/msvc_objectmodel.cpp +++ b/qmake/generators/win32/msvc_objectmodel.cpp @@ -2213,20 +2213,8 @@ void VCFilter::addFiles(const ProStringList& fileList) void VCFilter::modifyPCHstage(QString str) { - bool pchThroughSourceFile = !Project->precompSource.isEmpty(); - bool isCFile = false; - for (QStringList::Iterator it = Option::c_ext.begin(); it != Option::c_ext.end(); ++it) { - if (str.endsWith(*it)) { - isCFile = true; - break; - } - } const bool isHFile = (str == Project->precompH); - bool isCPPFile = pchThroughSourceFile && (str == Project->precompSource); - - if(!isCFile && !isHFile && !isCPPFile) - return; - + const bool pchThroughSourceFile = !Project->precompSource.isEmpty(); if (isHFile && pchThroughSourceFile && Project->autogenPrecompSource) { useCustomBuildTool = true; QString toFile(Project->precompSource); @@ -2259,13 +2247,29 @@ void VCFilter::modifyPCHstage(QString str) } useCompilerTool = true; - // Setup PCH options - CompilerTool.UsePrecompiledHeader = (isCFile ? pchNone : pchCreateUsingSpecific); - if (isCFile) + const bool isPrecompSource = pchThroughSourceFile && (str == Project->precompSource); + if (isPrecompSource) { + CompilerTool.UsePrecompiledHeader = pchCreateUsingSpecific; + if (Project->autogenPrecompSource) + CompilerTool.PrecompiledHeaderThrough = Project->precompHFilename; + CompilerTool.ForcedIncludeFiles = QStringList("$(NOINHERIT)"); + return; + } + + bool isCFile = false; + for (QStringList::Iterator it = Option::c_ext.begin(); it != Option::c_ext.end(); ++it) { + if (str.endsWith(*it)) { + isCFile = true; + break; + } + } + + bool pchCompatible = (isCFile == Project->pchIsCFile); + if (!pchCompatible) { + CompilerTool.UsePrecompiledHeader = pchNone; CompilerTool.PrecompiledHeaderThrough = QLatin1String("$(NOINHERIT)"); - else if (Project->autogenPrecompSource) - CompilerTool.PrecompiledHeaderThrough = Project->precompHFilename; - CompilerTool.ForcedIncludeFiles = QStringList("$(NOINHERIT)"); + CompilerTool.ForcedIncludeFiles = QStringList("$(NOINHERIT)"); + } } VCFilterFile VCFilter::findFile(const QString &filePath, bool *found) const diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 8c0b801891..6a125ccd77 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -776,7 +776,8 @@ void VcprojGenerator::init() // Setup PCH variables precompH = project->first("PRECOMPILED_HEADER").toQString(); precompSource = project->first("PRECOMPILED_SOURCE").toQString(); - usePCH = !precompH.isEmpty() && project->isActiveConfig("precompile_header"); + pchIsCFile = project->isActiveConfig("precompile_header_c"); + usePCH = !precompH.isEmpty() && (pchIsCFile || project->isActiveConfig("precompile_header")); if (usePCH) { precompHFilename = fileInfo(precompH).fileName(); // Created files @@ -793,7 +794,9 @@ void VcprojGenerator::init() autogenPrecompSource = precompSource.isEmpty() && project->isActiveConfig("autogen_precompile_source"); if (autogenPrecompSource) { precompSource = precompH - + (Option::cpp_ext.count() ? Option::cpp_ext.at(0) : QLatin1String(".cpp")); + + (pchIsCFile + ? (Option::c_ext.count() ? Option::c_ext.at(0) : QLatin1String(".c")) + : (Option::cpp_ext.count() ? Option::cpp_ext.at(0) : QLatin1String(".cpp"))); project->values("GENERATED_SOURCES") += precompSource; } else if (!precompSource.isEmpty()) { project->values("SOURCES") += precompSource; diff --git a/qmake/generators/win32/msvc_vcproj.h b/qmake/generators/win32/msvc_vcproj.h index fafc69d9ab..6f9743cb09 100644 --- a/qmake/generators/win32/msvc_vcproj.h +++ b/qmake/generators/win32/msvc_vcproj.h @@ -66,6 +66,7 @@ public: QHash extraCompilerOutputs; const QString customBuildToolFilterFileSuffix; bool usePCH; + bool pchIsCFile = false; VCProjectWriter *projectWriter; protected: From c05080102fd160314d9ed14c47f9e303e1ac3ee7 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Wed, 21 Nov 2018 13:46:28 +0100 Subject: [PATCH 0418/1650] tst_QNetworkReply: Blacklist getFromHttp:success-external Task-number: QTBUG-71953 Change-Id: I59566d1994dd80e7fef78f3b22ae34db9d2ad2cc Reviewed-by: Timur Pocheptsov (cherry picked from commit 46076f73337d6b0fea9a006dab2af8864571ae2c) Reviewed-by: Liang Qi --- tests/auto/network/access/qnetworkreply/BLACKLIST | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/auto/network/access/qnetworkreply/BLACKLIST b/tests/auto/network/access/qnetworkreply/BLACKLIST index fab8224431..4d29a830e9 100644 --- a/tests/auto/network/access/qnetworkreply/BLACKLIST +++ b/tests/auto/network/access/qnetworkreply/BLACKLIST @@ -8,6 +8,9 @@ windows * [getErrors:ftp-host] linux +# QTBUG-71953 +[getFromHttp:success-external] +* [getFromHttpIntoBuffer] windows [getFromHttpIntoBuffer2] From 08de243eaa007597c2bfbc97d3d14e2f821ac4be Mon Sep 17 00:00:00 2001 From: Antti Kokko Date: Fri, 16 Nov 2018 09:22:24 +0200 Subject: [PATCH 0419/1650] Add changes file for Qt 5.11.3 + 059b10f295d8d04c4144984daf1464115bcb69c9 Doc: Check before including the \snippet from a .pro file + 7f0cc35d9c33802742aaa640472f3d9d2390ffa4 Examples: Fix minor bug in Tree Model Completer Example + 244c7bd193ab5e15e28108937cae4acf3d574350 Avoid conversion over RGBA64 for RGB32 LCD text blending + a381ba4220097bd7a982a86f32c7e65da5591c8c Document version number of pixman + ff2a71e310b18a43a41daf2d197f5715f7c26d29 Doc: Move the literal code blocks to a separate file + 20ac20bcea8954a980d1acdbc4e9fa55011fe088 Windows QPA: Fix missing accessibility info with WebEngineView + 689a1e186b76853144802d9c29f0346856bd5fde QString: Fix snippet explaining "non-spaced numbered place markers" + 85f127cb045200fa5fa3608b859e59bb4a9c27b2 Revise an incorrect QVulkanWindow doc note + 3bac18da8ef9f5750207ddf47192b5db3137c4ac Document SLJIT part of pcre2 + 621ab8ab59901cc3f9bd98be709929c9eac997a8 bmp image handler: check for out of range image size + e04b85b026f59120e69a4acb3f3e4469abccc325 Doc: improve Mandelbrot example + bff307ab93bd6963f84e08e8050efa6a838dba6e Fix XCB on endian mismatched client and server with SHM off + 45c1473847ad65c4d43f9a605a86439867442883 Detect when we are at the sentence boundary + 49efea26a5fae8c2275999c36c7c8d24cf4125de sqlite: Fix QSqlError handling when opening/closing database + 1511bfef52b0731e1fdeafd685bf4954024da0e9 Disable RGB64 backend for ARGB32 when it will be very slow + cb5c24fa26142edaff8fd2c9787dbe45c222b4ff Fix integer overflow in very long sections in ELF objects + 12c357bebb19407ee8e034f3679b6c8b77ece9c1 Document IAccessible2 version + 8aa9bb6d3fcb45579f3dc45c5bdef6d33a9f9d24 Clarify docs regarding the states of a QFutureWatcher with no future set + 4fc4f7b0ce0e6ee186a7d7fe9b5dd20e94efe432 Export qt_open64 from QtCore + 4b7ff8e98c0208273a25d84e1f0322cad5bce2bf Protect HSTS code for no-feature-settings build + 6948bf20a73d09e867fd7c2d89052237d94b7d6a QSslContext: Use 0 instead of TLS_MAX_VERSION + e226b0f94afc85f79d82fc54421487bf2a529ba5 Modernize the "textdate" feature + b26cd68bf61346273a5a03bbc1e60a7cdffa4f0d Modernize the "datestring" feature + 02663718a9da95968a7879b792508b8c0ae699b2 QHeaderView: Don't unhide hidden sections on layoutChanged() + f99e956d65058e22780d99832987edad16f6d077 Add QT_REQUIRE_CONFIG(ssl) to pre-shared key authenticator + 5e64957ee4162ecf4456306a530a68761c2b127f Fix QCompleter popups preventing the application from exiting + 555a6b5d5d2dd91a0dcf9e3d5fbadd1b31bf80f3 Modernize the "filesystemwatcher" feature + 857a0d4c51095e2f90274ab8246bb01e58c97dfc Fix the /J option for MSVC project generation + 3ed8dc37884bac67414c0840e27b5094a69cfdcd Android: fix log output pattern + ef4ba0285f9c5dd5ee2dca1e0cefee45eba3477c SSL: Don't write to closed socket or write to deallocated buffer + 94884246d445fb3e702ac8c4d4bb432768e61b61 QCommandLineParser: Ensure that an option text ends with a newline + caa598c843eb27fd0c645e62723fd2d4e3e12f60 Fix QUrl::matches for when removing authority parts (other than host) + b2b32d3147eb213c835072994c93d2af3e7d285a fix HTML subset documentation is not very readable on smaller screens + c958fb8b488ea6e86365298796d5710ec4deccc9 zlib: Fix spelling of license + 5a295a1009dad3a020be10331fa8e8c6163a9106 Scale seconds by a thousand to get milliseconds + ced34cb3d5805f1fbaf3b275714a1a5f3585900c QDateTimeParser: avoid using an invalid hour by default + d8817ddde65d8fd9c5a2785a31a01db43d050114 Use update() instead of repaint() when displaying a new message + 18ec0a8b0991855f4576c2993832f9da41d97766 Windows QPA: Fix WM_NCHITTEST not being sent to QAbstractNativeEventFilter + 04aeffbe8f6d452529671205fa2ded43103e1a46 Doc: Describe behavior of QSslConfiguration::caCertificates() on iOS + 92f42caff1d1cb02dc218adc8589c03d0b30ef80 Fix ICE on QNX 6.6 + 7146c9075c85cb46cb38b57ded3e12dfa6cbef66 Fix DejaVu fonts URL + 836a2fb8872217d2a04a209b89f2ac2ff86a4b99 [macOS] Fix position of sheets when using unifiedTitleAndToolBarOnMac + ba0ff45109a0eb051a42d6d8392d1f1b7a1e9345 Update the DNS public suffix list from publicsuffix.org + 4dc251879c129710298ec9f9360490daed6a6a59 Ssl: Fix contrived crash when calling resume + 091a386eaf91ad8932332a8aefc2df793de59f6c Use native visual ID when creating GBM surfaces for KMS + dc5f9d0c3101f95185d3c562d001e0af18f46a0b Only use a translucent background if there is support for alpha + 0d7c049e4407bf0db8d1eca1ea248c6d6b739c8c Update bundled libpng to version 1.6.35 + 0509383cf2852f2aebd1efd75413835747c8f341 Bump copyright year in executable metadata + c593492d1678a2ec08f1bfffcb572459b3bc6c00 Modernize the "animation" feature + 4e7b58629a0a431fbd5c0ba287c3958efd05da13 Modernize the "big_codecs" feature + 9c8ca26a4829d5ce810c9653fec3dfe48717f0b1 Modernize the "codecs" feature + 3eebadc1734463afa469dcd08eab8c5d2557dec6 Modernize the "mimetype" feature + b7887f9b4faad2227691a2af589e9d7680d6ae08 Linux: Remove our use of syscall() for statx(2) and renameat2(2) + fc4b0769a5d65960eea959730d5cd20d3496d40b Fix pdf printing in static builds + 1cd2955173e2248b92f44c9d52d81447ff87906c Fix enum passed to QFontDatabase::findFont + 2624676b5731a9d93a1e46429d2c597f1e4bae38 qmake: Remove the extra space before -MT + 7f60940fbedef17984e283da41eae94f29fef428 Re-disable statx() on Android + 6599c1f75832cc9286a3bf88c6b179d006dbb96e QPicture: fix crash for malformed picture + 44eeeb8e816fbdcd77ad734cfe7a7ec28da1c5ed Upgrade PCRE2 to 10.32 + 948f8ce2ecb2d6d2713279311d6090268321f0fb QWinEventNotifier: fix crash on application shutdown + 2708c6c11d685ab25c12d558961d924c9a4533d2 OpenSSL: force the "1.0.0" soname when loading OpenSSL 1.0 + 0cb44e2cfb11033cdb7e3b73a25f1ec394b08d6e Fix stylesheet example for QLineEdit:read-only code example + 72bedd49bfb02ba7c7abf2a1a4c6cd165ebcd447 [cocoa] Disable offline renderers for dual AMD FirePro GPU + 509d566ec0f257f7f1a723096b57a718d43d5002 Don't block mouse events if the window is a Tooltip type + 38afa46c47f4401cd5fe8ce6eb93978d5287cfbc macOS: Only detect changes to the SDK version within the same developer dir + d2e0e416d4444ccf3c208d6770e32ff0fb04b543 Fix leaking QTabletEventPrivate instance + d4e937a6280f34bc1cce8c8cea3806a741312fbc xcb: Don't get initial screen rotation + 3b8075de3b3c842311c157476a85d2cf9ddff403 Fix deleting of QSharedPointer internals in case QPointer loses the race + 1b9af84c1bb66770f607e157991375f7cb7ae0fb Don't create an offscreen surface when not on the GUI thread + c9d18d4a9c9d1243a267316e2a702f9ba69de2fd eglfs_kms: initialize m_deviceListener + 67c66c4ea4fbc11ee5547095117ef8930b3ab950 windows: Give up on SwitchableComposition + 033cc3403a8238d1b6d56c42e9e9be4fba1069dc mkspecs: use cross compile tools with LTCG + 9f2216667a96c2de94b28e4fd2891b6d3b938cb9 Fix memory copy in QGIFFormat::disposePrevious() + b5d249f9538bf3dc44f11879c2244deb5a37bf97 Update the floppy disk icon (save) to be physically correct + 825f98815683faea06144ab0262129b0367798ee Modernize the "textcodec" feature + 993351183893c8c5b1e55b8d819b190cc11ae008 Fix typo in define. s/GL_FRAMEBUFFER_SRB/GL_FRAMEBUFFER_SRGB + 38b87cc4bb0d4dfb47d907d39906104fea60a187 Doc: Clarify what samples() returns if not explicitly set + bdebc90c2826866e4434a6429aa6f822ee3cb8f6 Bump version + dec7961709c90f6977d2447f7fa6c6625af41cb2 QSyntaxHighlighter: Delay all highlights until first rehighlight + 9137691e745039f8ad9cdee2594a958e244ba341 Windows QPA: Fix crash showing QSystemTrayIcon's context menu with PROCESS_DPI_UNAWARE Change-Id: Id50872011aff4f604d7444d7aa4799c1c61b45f6 Reviewed-by: Thiago Macieira --- dist/changes-5.11.3 | 94 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 dist/changes-5.11.3 diff --git a/dist/changes-5.11.3 b/dist/changes-5.11.3 new file mode 100644 index 0000000000..5d13335309 --- /dev/null +++ b/dist/changes-5.11.3 @@ -0,0 +1,94 @@ +Qt 5.11.3 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.11.0 through 5.11.2. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.11 series is binary compatible with the 5.10.x series. +Applications compiled for 5.10 will continue to run with 5.11. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Third-Party Components * +**************************************************************************** + + - libpng was updated to version 1.6.35 + - PCRE2 was updated to version 10.32. + - Added documentation for the SLJIT part of pcre2, which is available + under the BSD-2-Clause license. + +**************************************************************************** +* Documentation * +**************************************************************************** + + - Fixed the icons for the "file save" action that were inaccurate + representations of a 3.5-inch floppy disk (the cut edge was on the wrong + side). Now all floppy representations are physically accurate. + +**************************************************************************** +* QtCore * +**************************************************************************** + + - QCommandLineParser: + * [QTBUG-70174] Fixed a bug that caused the help output to show two + options or more in the same line if the options didn't have a + description. + + - QDateTime: + * [QTBUG-70823] Fixed parsing of date/time strings when the day is the + start of daylight savings and that starts at midnight on the + timezone. + + - QPluginLoader: + * [QTBUG-70560] Fixed a bug in parsing certain plugins, which might + conclude a valid plugin wasn't valid. + + - QPointer: + * [QTBUG-71412] Fixed a race condition that would cause an assertion + failure when two threads created a QPointer for the same QObject. + + - QUrl: + * Fixed a bug that caused QUrl::matches to incorrectly compare two URLs + with different hostnames or different usernames as equal, if certain + QUrl::RemoveXxx options were passed. + * [QTBUG-70386][QTBUG-70852] Updated the public DNS suffix list. + +**************************************************************************** +* QtGui * +**************************************************************************** + + - QPicture: + * [QTBUG-71208] Fix crash reading malformed picture file + +**************************************************************************** +* QtNetwork * +**************************************************************************** + + - SSL: + * [QTBUG-68156] OpenSSL >= 1.0 is now required to build Qt with OpenSSL + support. + +**************************************************************************** +* Linux * +**************************************************************************** + + - Fixed a number of incompatibilities with Linux C libraries due to use of + new kernel system calls statx(2) and renameat2(2). In order to enable + them now in Qt, they need to be provided in the C library's own + headers. Currently, glibc 2.28 contains them. + +**************************************************************************** +* macOS * +**************************************************************************** + + - Offline renderers will be disabled when the application is + using Qt WebEngine and running on one of the late 2013 Mac Pro models. From c2bf0cac957b1e7866538201433f3cd38313ab7f Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 11 Oct 2018 16:37:19 +0200 Subject: [PATCH 0420/1650] Warn when using deprecated methods Change-Id: Id6e65d83e9279407b4b02967e4044f33d8c6ae01 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfontmetrics.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/text/qfontmetrics.h b/src/gui/text/qfontmetrics.h index ba7f695380..cbccc886fd 100644 --- a/src/gui/text/qfontmetrics.h +++ b/src/gui/text/qfontmetrics.h @@ -104,8 +104,11 @@ public: int rightBearing(QChar) const; #if QT_DEPRECATED_SINCE(5, 11) + QT_DEPRECATED_X("Use QFont::horizontalAdvance") int width(const QString &, int len = -1) const; + QT_DEPRECATED_X("Use QFont::horizontalAdvance") int width(const QString &, int len, int flags) const; + QT_DEPRECATED_X("Use QFont::horizontalAdvance") int width(QChar) const; #endif From b98c43ea602b336813fa967e610da2be100f748d Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 18 Oct 2018 21:43:59 +0200 Subject: [PATCH 0421/1650] Compile with QT_STRICT_ITERATORS defined This will be the only options for Qt 6, so make sure the code compiles now. Change-Id: I23f791d1efcbd0bd33805bb4563d40460954db43 Reviewed-by: Oswald Buddenhagen --- qmake/generators/makefile.cpp | 14 +++++++------- qmake/generators/unix/unixmake2.cpp | 2 +- qmake/generators/win32/msvc_vcproj.cpp | 4 ++-- qmake/generators/win32/winmakefile.cpp | 4 ++-- qmake/property.cpp | 14 +++++++------- src/corelib/codecs/qtextcodec.cpp | 4 ++-- src/plugins/platforms/xcb/qxcbeventqueue.cpp | 6 +++--- src/tools/qlalr/lalr.h | 2 ++ .../kernel/qapplication/tst_qapplication.cpp | 4 ++-- 9 files changed, 28 insertions(+), 26 deletions(-) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index b7e591d2ab..2fbaa00f2d 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -624,7 +624,7 @@ MakefileGenerator::init() compiler.flags |= Compiler::CompilerNoCheckDeps; compilers.append(compiler); } - for (ProStringList::ConstIterator it = quc.begin(); it != quc.end(); ++it) { + for (ProStringList::ConstIterator it = quc.cbegin(); it != quc.cend(); ++it) { const ProStringList &inputs = v[ProKey(*it + ".input")]; for(x = 0; x < inputs.size(); ++x) { Compiler compiler; @@ -1878,7 +1878,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) t << ' ' << escapeDependencyPath(Option::fixPathToTargetOS( replaceExtraCompilerVariables(tmp_out, input, QString(), NoShell))); } else { - for (ProStringList::ConstIterator input = tmp_inputs.begin(); input != tmp_inputs.end(); ++input) { + for (ProStringList::ConstIterator input = tmp_inputs.cbegin(); input != tmp_inputs.cend(); ++input) { t << ' ' << escapeDependencyPath(Option::fixPathToTargetOS( replaceExtraCompilerVariables(tmp_out, (*input).toQString(), QString(), NoShell))); } @@ -1912,7 +1912,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) const QString del_statement("-$(DEL_FILE)"); if(!wrote_clean) { QStringList dels; - for (ProStringList::ConstIterator input = tmp_inputs.begin(); input != tmp_inputs.end(); ++input) { + for (ProStringList::ConstIterator input = tmp_inputs.cbegin(); input != tmp_inputs.cend(); ++input) { QString tinp = (*input).toQString(); QString out = replaceExtraCompilerVariables(tmp_out, tinp, QString(), NoShell); for (const QString &rc : qAsConst(raw_clean)) { @@ -1940,7 +1940,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) if(!cleans.isEmpty()) t << valGlue(cleans, "\n\t" + del_statement, "\n\t" + del_statement, ""); if(!wrote_clean_cmds) { - for (ProStringList::ConstIterator input = tmp_inputs.begin(); input != tmp_inputs.end(); ++input) { + for (ProStringList::ConstIterator input = tmp_inputs.cbegin(); input != tmp_inputs.cend(); ++input) { QString tinp = (*input).toQString(); t << "\n\t" << replaceExtraCompilerVariables(tmp_clean_cmds, tinp, replaceExtraCompilerVariables(tmp_out, tinp, QString(), NoShell), TargetShell); @@ -1959,7 +1959,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) QStringList deps, inputs; if(!tmp_dep.isEmpty()) deps += fileFixify(tmp_dep, FileFixifyFromOutdir); - for (ProStringList::ConstIterator input = tmp_inputs.begin(); input != tmp_inputs.end(); ++input) { + for (ProStringList::ConstIterator input = tmp_inputs.cbegin(); input != tmp_inputs.cend(); ++input) { QString inpf = (*input).toQString(); deps += findDependencies(inpf); inputs += Option::fixPathToTargetOS(inpf, false); @@ -2043,7 +2043,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) t << "\n\t" << cmd << endl << endl; continue; } - for (ProStringList::ConstIterator input = tmp_inputs.begin(); input != tmp_inputs.end(); ++input) { + for (ProStringList::ConstIterator input = tmp_inputs.cbegin(); input != tmp_inputs.cend(); ++input) { QString inpf = (*input).toQString(); QString in = Option::fixPathToTargetOS(inpf, false); QStringList deps = findDependencies(inpf); @@ -3350,7 +3350,7 @@ MakefileGenerator::writePkgConfigFile() libs << "QMAKE_LIBS_PRIVATE"; libs << "QMAKE_LFLAGS_THREAD"; //not sure about this one, but what about things like -pthread? t << "Libs.private:"; - for (ProStringList::ConstIterator it = libs.begin(); it != libs.end(); ++it) + for (ProStringList::ConstIterator it = libs.cbegin(); it != libs.cend(); ++it) t << ' ' << fixLibFlags((*it).toKey()).join(' '); t << endl; } diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index d3abedb50b..4a6b5c8579 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -1485,7 +1485,7 @@ UnixMakefileGenerator::writeLibtoolFile() ProStringList libs; libs << "LIBS" << "QMAKE_LIBS"; t << "dependency_libs='"; - for (ProStringList::ConstIterator it = libs.begin(); it != libs.end(); ++it) + for (ProStringList::ConstIterator it = libs.cbegin(); it != libs.cend(); ++it) t << fixLibFlags((*it).toKey()).join(' ') << ' '; t << "'\n\n"; diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 6a125ccd77..d231260886 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -477,8 +477,8 @@ ProStringList VcprojGenerator::collectDependencies(QMakeProject *proj, QHash 1) fprintf(stdout, "%s:", (*it).toLatin1().constData()); const ProKey pkey(*it); @@ -191,11 +191,11 @@ QMakeProperty::exec() } } } else if(Option::qmake_mode == Option::QMAKE_SET_PROPERTY) { - for(QStringList::ConstIterator it = Option::prop::properties.begin(); - it != Option::prop::properties.end(); it++) { + for (QStringList::ConstIterator it = Option::prop::properties.cbegin(); + it != Option::prop::properties.cend(); it++) { QString var = (*it); it++; - if(it == Option::prop::properties.end()) { + if (it == Option::prop::properties.cend()) { ret = false; break; } @@ -203,8 +203,8 @@ QMakeProperty::exec() setValue(var, (*it)); } } else if(Option::qmake_mode == Option::QMAKE_UNSET_PROPERTY) { - for(QStringList::ConstIterator it = Option::prop::properties.begin(); - it != Option::prop::properties.end(); it++) { + for (QStringList::ConstIterator it = Option::prop::properties.cbegin(); + it != Option::prop::properties.cend(); it++) { QString var = (*it); if(!var.startsWith(".")) remove(var); diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp index 466c575c3e..3fc199c0a1 100644 --- a/src/corelib/codecs/qtextcodec.cpp +++ b/src/corelib/codecs/qtextcodec.cpp @@ -505,9 +505,9 @@ QTextCodec::~QTextCodec() globalData->allCodecs.removeOne(this); - auto it = globalData->codecCache.cbegin(); + auto it = globalData->codecCache.begin(); - while (it != globalData->codecCache.cend()) { + while (it != globalData->codecCache.end()) { if (it.value() == this) it = globalData->codecCache.erase(it); else diff --git a/src/plugins/platforms/xcb/qxcbeventqueue.cpp b/src/plugins/platforms/xcb/qxcbeventqueue.cpp index 862f68764b..883268b083 100644 --- a/src/plugins/platforms/xcb/qxcbeventqueue.cpp +++ b/src/plugins/platforms/xcb/qxcbeventqueue.cpp @@ -257,7 +257,7 @@ qint32 QXcbEventQueue::generatePeekerId() bool QXcbEventQueue::removePeekerId(qint32 peekerId) { - const auto it = m_peekerToNode.find(peekerId); + const auto it = m_peekerToNode.constFind(peekerId); if (it == m_peekerToNode.constEnd()) { qCWarning(lcQpaXcb, "failed to remove unknown peeker id: %d", peekerId); return false; @@ -276,7 +276,7 @@ bool QXcbEventQueue::peekEventQueue(PeekerCallback peeker, void *peekerData, const bool peekerIdProvided = peekerId != -1; auto peekerToNodeIt = m_peekerToNode.find(peekerId); - if (peekerIdProvided && peekerToNodeIt == m_peekerToNode.constEnd()) { + if (peekerIdProvided && peekerToNodeIt == m_peekerToNode.end()) { qCWarning(lcQpaXcb, "failed to find index for unknown peeker id: %d", peekerId); return false; } @@ -336,7 +336,7 @@ bool QXcbEventQueue::peekEventQueue(PeekerCallback peeker, void *peekerData, // Before updating, make sure that a peeker callback did not remove // the peeker id. peekerToNodeIt = m_peekerToNode.find(peekerId); - if (peekerToNodeIt != m_peekerToNode.constEnd()) + if (peekerToNodeIt != m_peekerToNode.end()) *peekerToNodeIt = node; // id still in the cache, update node } diff --git a/src/tools/qlalr/lalr.h b/src/tools/qlalr/lalr.h index 6a2baaa462..8eadee400d 100644 --- a/src/tools/qlalr/lalr.h +++ b/src/tools/qlalr/lalr.h @@ -61,6 +61,8 @@ public: public: const_iterator () {} + const_iterator (const typename _Base::iterator &it): + _M_iterator (typename _Base::const_iterator(it)) {} const_iterator (const typename _Base::const_iterator &it): _M_iterator (it) {} diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp index d06baed322..e2ef5635c2 100644 --- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp +++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp @@ -360,8 +360,8 @@ void tst_QApplication::setFont_data() int cnt = 0; QFontDatabase fdb; QStringList families = fdb.families(); - for (QStringList::const_iterator itr = families.begin(); - itr != families.end(); + for (QStringList::const_iterator itr = families.cbegin(); + itr != families.cend(); ++itr) { if (cnt < 3) { QString family = *itr; From f91d1e08099e67c77c8d7bcda362f07eec054ae8 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 19 Nov 2018 14:06:28 +0100 Subject: [PATCH 0422/1650] Documentation fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Most of our containers do not require a default constructor for the template argument. Of course some operations (such as reserve) still need it. Change-Id: If080c422a1ffc13b8cb5e0915cee9a7adee81adc Reviewed-by: Jędrzej Nowacki --- src/corelib/doc/src/containers.qdoc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/corelib/doc/src/containers.qdoc b/src/corelib/doc/src/containers.qdoc index a1c32bb007..e6c95129db 100644 --- a/src/corelib/doc/src/containers.qdoc +++ b/src/corelib/doc/src/containers.qdoc @@ -171,8 +171,9 @@ The values stored in the various containers can be of any \e{assignable data type}. To qualify, a type must provide a - default constructor, a copy constructor, and an assignment - operator. This covers most data types you are likely to want to + copy constructor, and an assignment operator. For some + operations a default constructor is also required. This + covers most data types you are likely to want to store in a container, including basic types such as \c int and \c double, pointer types, and Qt data types such as QString, QDate, and QTime, but it doesn't cover QObject or any QObject subclass From 71bd06d516a2410ae0ea698e79dcb94aba9bc5b4 Mon Sep 17 00:00:00 2001 From: Sami Nurmenniemi Date: Wed, 13 Jun 2018 16:35:40 +0300 Subject: [PATCH 0423/1650] Make developer build tests pass for boot2qt Some tests were fixed and others were skipped/blacklisted. Task-number: QTBUG-63152 Change-Id: Ica7df555f8d152ee589865911130525101d4b941 Reviewed-by: Liang Qi --- tests/auto/corelib/global/qlogging/BLACKLIST | 4 ++++ tests/auto/corelib/io/qstandardpaths/BLACKLIST | 3 --- .../corelib/io/qstandardpaths/qstandardpaths.pro | 3 +++ .../corelib/io/qstandardpaths/tst_qstandardpaths.cpp | 6 ++++++ .../corelib/serialization/qtextstream/test/test.pro | 2 ++ .../serialization/qtextstream/tst_qtextstream.cpp | 5 ++++- tests/auto/network/access/http2/http2.pro | 3 ++- tests/auto/network/access/http2/tst_http2.cpp | 5 +++++ .../network/socket/qtcpsocket/tst_qtcpsocket.cpp | 12 +++++++++++- tests/auto/other/qobjectrace/qobjectrace.pro | 3 +++ tests/auto/other/qobjectrace/tst_qobjectrace.cpp | 4 ++++ tests/auto/testlib/selftests/tst_selftests.cpp | 3 +++ .../auto/widgets/widgets/qcombobox/tst_qcombobox.cpp | 12 ++++++++++++ 13 files changed, 59 insertions(+), 6 deletions(-) delete mode 100644 tests/auto/corelib/io/qstandardpaths/BLACKLIST diff --git a/tests/auto/corelib/global/qlogging/BLACKLIST b/tests/auto/corelib/global/qlogging/BLACKLIST index 1dcee92361..e474064f54 100644 --- a/tests/auto/corelib/global/qlogging/BLACKLIST +++ b/tests/auto/corelib/global/qlogging/BLACKLIST @@ -1,3 +1,7 @@ +[qMessagePattern:backtrace] +# QTBUG-63915 +b2qt 64bit + [qMessagePattern:backtrace depth,separator] # QTBUG-63915 b2qt 64bit diff --git a/tests/auto/corelib/io/qstandardpaths/BLACKLIST b/tests/auto/corelib/io/qstandardpaths/BLACKLIST deleted file mode 100644 index d5ee9650cd..0000000000 --- a/tests/auto/corelib/io/qstandardpaths/BLACKLIST +++ /dev/null @@ -1,3 +0,0 @@ -[testFindExecutable] -# QTBUG-64404 -b2qt 64bit diff --git a/tests/auto/corelib/io/qstandardpaths/qstandardpaths.pro b/tests/auto/corelib/io/qstandardpaths/qstandardpaths.pro index 9fd7047405..44b1ce8dd8 100644 --- a/tests/auto/corelib/io/qstandardpaths/qstandardpaths.pro +++ b/tests/auto/corelib/io/qstandardpaths/qstandardpaths.pro @@ -5,3 +5,6 @@ INCLUDEPATH += ../../../../shared/ HEADERS += ../../../../shared/emulationdetector.h SOURCES = tst_qstandardpaths.cpp TESTDATA += tst_qstandardpaths.cpp qstandardpaths.pro + +# QTBUG-64404 +boot2qt: DEFINES+=SKIP_FINDEXECUTABLE diff --git a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp index 3de777653e..e316ce9acb 100644 --- a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp +++ b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp @@ -369,6 +369,12 @@ static inline QFileInfo findSh() void tst_qstandardpaths::testFindExecutable_data() { +#ifdef SKIP_FINDEXECUTABLE + // Test needs to be skipped or Q_ASSERT below will cancel the test + // and report FAIL regardless of BLACKLIST contents + QSKIP("QTBUG-64404"); +#endif + QTest::addColumn("directory"); QTest::addColumn("needle"); QTest::addColumn("expected"); diff --git a/tests/auto/corelib/serialization/qtextstream/test/test.pro b/tests/auto/corelib/serialization/qtextstream/test/test.pro index 3dcfa0b414..0f289a5ce1 100644 --- a/tests/auto/corelib/serialization/qtextstream/test/test.pro +++ b/tests/auto/corelib/serialization/qtextstream/test/test.pro @@ -3,6 +3,8 @@ TARGET = ../tst_qtextstream QT = core network testlib SOURCES = ../tst_qtextstream.cpp RESOURCES += ../qtextstream.qrc +INCLUDEPATH += ../../../../../shared/ +HEADERS += ../../../../../shared/emulationdetector.h win32 { CONFIG(debug, debug|release) { diff --git a/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp b/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp index df8746e518..77675b8e44 100644 --- a/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp +++ b/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp @@ -44,7 +44,7 @@ # include #endif #include "../../../network-settings.h" - +#include "emulationdetector.h" QT_BEGIN_NAMESPACE template<> struct QMetaTypeId @@ -1459,6 +1459,9 @@ void tst_QTextStream::pos2() // ------------------------------------------------------------------------------ void tst_QTextStream::pos3LargeFile() { + if (EmulationDetector::isRunningArmOnX86()) + QSKIP("Running QTextStream::pos() in tight loop is too slow on emulator"); + { QFile file(testFileName); file.open(QIODevice::WriteOnly | QIODevice::Text); diff --git a/tests/auto/network/access/http2/http2.pro b/tests/auto/network/access/http2/http2.pro index e130f30784..b244a827bd 100644 --- a/tests/auto/network/access/http2/http2.pro +++ b/tests/auto/network/access/http2/http2.pro @@ -2,7 +2,8 @@ QT += core core-private network network-private testlib CONFIG += testcase parallel_test c++11 TARGET = tst_http2 -HEADERS += http2srv.h +INCLUDEPATH += ../../../../shared/ +HEADERS += http2srv.h ../../../../shared/emulationdetector.h SOURCES += tst_http2.cpp http2srv.cpp DEFINES += SRCDIR=\\\"$$PWD/\\\" diff --git a/tests/auto/network/access/http2/tst_http2.cpp b/tests/auto/network/access/http2/tst_http2.cpp index ecf4c5814a..51e30804a3 100644 --- a/tests/auto/network/access/http2/tst_http2.cpp +++ b/tests/auto/network/access/http2/tst_http2.cpp @@ -48,6 +48,8 @@ #include #include +#include "emulationdetector.h" + #if !defined(QT_NO_OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(OPENSSL_NO_TLSEXT) // HTTP/2 over TLS requires ALPN/NPN to negotiate the protocol version. const bool clearTextHTTP2 = false; @@ -292,6 +294,9 @@ void tst_Http2::flowControlServerSide() // to let all replies finish without any error. using namespace Http2; + if (EmulationDetector::isRunningArmOnX86()) + QSKIP("Test is too slow to run on emulator"); + clearHTTP2State(); serverPort = 0; diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp index 263a475435..c473230246 100644 --- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp +++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp @@ -2429,7 +2429,17 @@ void tst_QTcpSocket::suddenRemoteDisconnect() QString::fromLatin1("Could not start %1: %2").arg(processExe, serverProcess.errorString()))); while (!serverProcess.canReadLine()) QVERIFY(serverProcess.waitForReadyRead(10000)); - QCOMPARE(serverProcess.readLine().data(), QByteArray(server.toLatin1() + "\n").data()); + + QByteArray line = serverProcess.readLine(); + + // Ignore following print, happens on Qemu: + if (line == "getsockopt level=41 optname=26 not yet supported\n") { + while (!serverProcess.canReadLine()) + QVERIFY(serverProcess.waitForReadyRead(10000)); + line = serverProcess.readLine(); + } + + QCOMPARE(line.data(), QByteArray(server.toLatin1() + "\n").data()); // Start client QProcess clientProcess; diff --git a/tests/auto/other/qobjectrace/qobjectrace.pro b/tests/auto/other/qobjectrace/qobjectrace.pro index 94e7928585..6536810534 100644 --- a/tests/auto/other/qobjectrace/qobjectrace.pro +++ b/tests/auto/other/qobjectrace/qobjectrace.pro @@ -2,3 +2,6 @@ CONFIG += testcase SOURCES += tst_qobjectrace.cpp QT = core testlib +INCLUDEPATH += ../../../shared/ +HEADERS += ../../../shared/emulationdetector.h + diff --git a/tests/auto/other/qobjectrace/tst_qobjectrace.cpp b/tests/auto/other/qobjectrace/tst_qobjectrace.cpp index e6eb51500b..0d656e223c 100644 --- a/tests/auto/other/qobjectrace/tst_qobjectrace.cpp +++ b/tests/auto/other/qobjectrace/tst_qobjectrace.cpp @@ -30,6 +30,7 @@ #include #include +#include "emulationdetector.h" enum { OneMinute = 60 * 1000, TwoMinutes = OneMinute * 2 }; @@ -256,6 +257,9 @@ public: void tst_QObjectRace::destroyRace() { + if (EmulationDetector::isRunningArmOnX86()) + QSKIP("Test is too slow to run on emulator"); + enum { ThreadCount = 10, ObjectCountPerThread = 2777, ObjectCount = ThreadCount * ObjectCountPerThread }; diff --git a/tests/auto/testlib/selftests/tst_selftests.cpp b/tests/auto/testlib/selftests/tst_selftests.cpp index 63e5721e7e..26e3ccd0fb 100644 --- a/tests/auto/testlib/selftests/tst_selftests.cpp +++ b/tests/auto/testlib/selftests/tst_selftests.cpp @@ -659,6 +659,9 @@ static inline QByteArray msgProcessError(const QString &binary, const QStringLis void tst_Selftests::doRunSubTest(QString const& subdir, QStringList const& loggers, QStringList const& arguments, bool crashes) { + if (EmulationDetector::isRunningArmOnX86() && (subdir == "crashes")) + QSKIP("Skipping \"crashes\" due to QTBUG-71915"); + #if defined(__GNUC__) && defined(__i386) && defined(Q_OS_LINUX) if (arguments.contains("-callgrind")) { QProcess checkProcess; diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp index 7c1deb8fff..d5eef521ed 100644 --- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp @@ -1671,6 +1671,13 @@ void tst_QComboBox::setCustomModelAndView() QTRY_VERIFY(combo.view()->isVisible()); const QRect subItemRect = view->visualRect(model->indexFromItem(subItem)); QWidget *window = view->window(); + + // QComboBox sometimes ignores the mouse click event for doubleClickInterval + // depending on which tests have been run previously. On arm this happens + // more often than on x86. Search for maybeIgnoreMouseButtonRelease to see + // why this happens. + QTest::qWait(QApplication::doubleClickInterval()); + QTest::mouseClick(window->windowHandle(), Qt::LeftButton, 0, view->mapTo(window, subItemRect.center())); QTRY_COMPARE(combo.currentText(), subItem21Text); } @@ -3436,6 +3443,11 @@ void tst_QComboBox::task_QTBUG_52027_mapCompleterIndex() model->setFilterFixedString("foobar1"); completer->setModel(model); + if (QGuiApplication::platformName() == "offscreen") { + QWARN("Offscreen platform requires explicit activateWindow()"); + cbox.activateWindow(); + } + QApplication::setActiveWindow(&cbox); QVERIFY(QTest::qWaitForWindowActive(&cbox)); From ba13c6c08f30a4c2f188f69deeaf4ca6a020d7a1 Mon Sep 17 00:00:00 2001 From: Vitaly Fanaskov Date: Thu, 22 Nov 2018 14:39:51 +0100 Subject: [PATCH 0424/1650] Fix calculation of text margin if line edit contains side widgets The previous implementation leads to infinite chain of showing/hidden line edit under circumstances described in QTBUG-54676. We basically got the situation when size hint were calculated differently depending on the line edit visibility state. In this case toolbar layout have to show/hide extension button and line edit a lot of times and can never leave this "loop" (please note, that the chain is much more complicated in reality): Resize toolbar -> Set layout geometry -> Size is OK to display line edit -> Set layout geometry -> Hide extension button -> Set layout geometry (wrong size is calculated here, so "run out of space") -> Hide line edit -> Set layout geometry -> Show extension button -> Set layout geometry - > Size is OK to display line edit ... And we're in the "loop" Clear button is hidden if there is no text in a line edit. In the previous implementation, the button was always visible, only opacity was changing in order to "hide" the button. It resulted to incorrect size hints (regular and minimum). In the current implementation the button is really hidden/shown, and size hints calculated correctly. Also updated unit test for line edit. Remove code duplication in functions for calculation text margin Fixes: QTBUG-54676 Change-Id: I4549c9ea98e10b750ba855a07037f6392276358b Reviewed-by: Shawn Rutledge --- src/widgets/widgets/qlineedit.cpp | 5 +- src/widgets/widgets/qlineedit_p.cpp | 98 +++++++++++++------ src/widgets/widgets/qlineedit_p.h | 15 ++- .../widgets/qlineedit/tst_qlineedit.cpp | 3 +- .../widgets/widgets/qtoolbar/tst_qtoolbar.cpp | 79 +++++++++++++++ 5 files changed, 169 insertions(+), 31 deletions(-) diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp index 242a4405ca..2ae2e16c89 100644 --- a/src/widgets/widgets/qlineedit.cpp +++ b/src/widgets/widgets/qlineedit.cpp @@ -488,7 +488,10 @@ void QLineEdit::setClearButtonEnabled(bool enable) QAction *clearAction = new QAction(d->clearButtonIcon(), QString(), this); clearAction->setEnabled(!isReadOnly()); clearAction->setObjectName(QLatin1String(clearButtonActionNameC)); - d->addAction(clearAction, 0, QLineEdit::TrailingPosition, QLineEditPrivate::SideWidgetClearButton | QLineEditPrivate::SideWidgetFadeInWithText); + + int flags = QLineEditPrivate::SideWidgetClearButton | QLineEditPrivate::SideWidgetFadeInWithText; + auto widgetAction = d->addAction(clearAction, nullptr, QLineEdit::TrailingPosition, flags); + widgetAction->setVisible(!text().isEmpty()); } else { QAction *clearAction = findChild(QLatin1String(clearButtonActionNameC)); Q_ASSERT(clearAction); diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp index df8d534afa..6dcb2dd693 100644 --- a/src/widgets/widgets/qlineedit_p.cpp +++ b/src/widgets/widgets/qlineedit_p.cpp @@ -392,9 +392,47 @@ void QLineEditIconButton::setOpacity(qreal value) } #if QT_CONFIG(animation) +bool QLineEditIconButton::shouldHideWithText() const +{ + return m_hideWithText; +} + +void QLineEditIconButton::setHideWithText(bool hide) +{ + m_hideWithText = hide; +} + +void QLineEditIconButton::onAnimationFinished() +{ + if (shouldHideWithText() && isVisible() && !m_wasHidden) { + hide(); + + // Invalidate previous geometry to take into account new size of side widgets + if (auto le = lineEditPrivate()) + le->updateGeometry_helper(true); + } +} + +void QLineEditIconButton::animateShow(bool visible) +{ + m_wasHidden = visible; + + if (shouldHideWithText() && !isVisible()) { + show(); + + // Invalidate previous geometry to take into account new size of side widgets + if (auto le = lineEditPrivate()) + le->updateGeometry_helper(true); + } + + startOpacityAnimation(visible ? 1.0 : 0.0); +} + void QLineEditIconButton::startOpacityAnimation(qreal endValue) { QPropertyAnimation *animation = new QPropertyAnimation(this, QByteArrayLiteral("opacity")); + connect(animation, &QPropertyAnimation::finished, this, &QLineEditIconButton::onAnimationFinished); + animation->setDuration(160); animation->setEndValue(endValue); animation->start(QAbstractAnimation::DeleteWhenStopped); @@ -409,6 +447,16 @@ void QLineEditIconButton::updateCursor() } #endif // QT_CONFIG(toolbutton) +#if QT_CONFIG(animation) && QT_CONFIG(toolbutton) +static void displayWidgets(const QLineEditPrivate::SideWidgetEntryList &widgets, bool display) +{ + for (const auto &e : widgets) { + if (e.flags & QLineEditPrivate::SideWidgetFadeInWithText) + static_cast(e.widget)->animateShow(display); + } +} +#endif + void QLineEditPrivate::_q_textChanged(const QString &text) { if (hasSideWidgets()) { @@ -416,15 +464,9 @@ void QLineEditPrivate::_q_textChanged(const QString &text) if (!newTextSize || !lastTextSize) { lastTextSize = newTextSize; #if QT_CONFIG(animation) && QT_CONFIG(toolbutton) - const bool fadeIn = newTextSize > 0; - for (const SideWidgetEntry &e : leadingSideWidgets) { - if (e.flags & SideWidgetFadeInWithText) - static_cast(e.widget)->animateShow(fadeIn); - } - for (const SideWidgetEntry &e : trailingSideWidgets) { - if (e.flags & SideWidgetFadeInWithText) - static_cast(e.widget)->animateShow(fadeIn); - } + const bool display = newTextSize > 0; + displayWidgets(leadingSideWidgets, display); + displayWidgets(trailingSideWidgets, display); #endif } } @@ -541,8 +583,15 @@ QWidget *QLineEditPrivate::addAction(QAction *newAction, QAction *before, QLineE QLineEditIconButton *toolButton = new QLineEditIconButton(q); toolButton->setIcon(newAction->icon()); toolButton->setOpacity(lastTextSize > 0 || !(flags & SideWidgetFadeInWithText) ? 1 : 0); - if (flags & SideWidgetClearButton) + if (flags & SideWidgetClearButton) { QObject::connect(toolButton, SIGNAL(clicked()), q, SLOT(_q_clearButtonClicked())); + +#if QT_CONFIG(animation) + // The clear button is handled only by this widget. The button should be really + // shown/hidden in order to calculate size hints correctly. + toolButton->setHideWithText(true); +#endif + } toolButton->setDefaultAction(newAction); w = toolButton; #else @@ -606,33 +655,26 @@ void QLineEditPrivate::removeAction(QAction *action) #endif // QT_CONFIG(action) } -static bool isSideWidgetVisible(const QLineEditPrivate::SideWidgetEntry &e) +static int effectiveTextMargin(int defaultMargin, const QLineEditPrivate::SideWidgetEntryList &widgets, + const QLineEditPrivate::SideWidgetParameters ¶meters) { - return e.widget->isVisible(); + if (widgets.empty()) + return defaultMargin; + + return defaultMargin + (parameters.margin + parameters.widgetWidth) * + int(std::count_if(widgets.begin(), widgets.end(), + [](const QLineEditPrivate::SideWidgetEntry &e) { + return e.widget->isVisibleTo(e.widget->parentWidget()); })); } int QLineEditPrivate::effectiveLeftTextMargin() const { - int result = leftTextMargin; - if (!leftSideWidgetList().empty()) { - const SideWidgetParameters p = sideWidgetParameters(); - result += (p.margin + p.widgetWidth) - * int(std::count_if(leftSideWidgetList().begin(), leftSideWidgetList().end(), - isSideWidgetVisible)); - } - return result; + return effectiveTextMargin(leftTextMargin, leftSideWidgetList(), sideWidgetParameters()); } int QLineEditPrivate::effectiveRightTextMargin() const { - int result = rightTextMargin; - if (!rightSideWidgetList().empty()) { - const SideWidgetParameters p = sideWidgetParameters(); - result += (p.margin + p.widgetWidth) - * int(std::count_if(rightSideWidgetList().begin(), rightSideWidgetList().end(), - isSideWidgetVisible)); - } - return result; + return effectiveTextMargin(rightTextMargin, rightSideWidgetList(), sideWidgetParameters()); } diff --git a/src/widgets/widgets/qlineedit_p.h b/src/widgets/widgets/qlineedit_p.h index 7cd91dfc29..12a2f1ddfd 100644 --- a/src/widgets/widgets/qlineedit_p.h +++ b/src/widgets/widgets/qlineedit_p.h @@ -90,7 +90,10 @@ public: qreal opacity() const { return m_opacity; } void setOpacity(qreal value); #if QT_CONFIG(animation) - void animateShow(bool visible) { startOpacityAnimation(visible ? 1.0 : 0.0); } + void animateShow(bool visible); + + bool shouldHideWithText() const; + void setHideWithText(bool hide); #endif protected: @@ -100,6 +103,10 @@ protected: private slots: void updateCursor(); +#if QT_CONFIG(animation) + void onAnimationFinished(); +#endif + private: #if QT_CONFIG(animation) void startOpacityAnimation(qreal endValue); @@ -107,6 +114,12 @@ private: QLineEditPrivate *lineEditPrivate() const; qreal m_opacity; + +#if QT_CONFIG(animation) + bool m_hideWithText = false; + bool m_wasHidden = false; +#endif + }; #endif // QT_CONFIG(toolbutton) diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp index 448e2030bc..95799905de 100644 --- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp @@ -4451,10 +4451,11 @@ void tst_QLineEdit::clearButtonVisibleAfterSettingText_QTBUG_45518() QTRY_VERIFY(clearButton->opacity() > 0); QTRY_COMPARE(clearButton->cursor().shape(), Qt::ArrowCursor); - QTest::mouseClick(clearButton, Qt::LeftButton, 0, clearButton->rect().center()); + QTest::mouseClick(clearButton, Qt::LeftButton, nullptr, clearButton->rect().center()); QTRY_COMPARE(edit.text(), QString()); QTRY_COMPARE(clearButton->opacity(), qreal(0)); + QVERIFY(clearButton->isHidden()); QTRY_COMPARE(clearButton->cursor().shape(), clearButton->parentWidget()->cursor().shape()); edit.setClearButtonEnabled(false); diff --git a/tests/auto/widgets/widgets/qtoolbar/tst_qtoolbar.cpp b/tests/auto/widgets/widgets/qtoolbar/tst_qtoolbar.cpp index 301801ed2e..d6c165642e 100644 --- a/tests/auto/widgets/widgets/qtoolbar/tst_qtoolbar.cpp +++ b/tests/auto/widgets/widgets/qtoolbar/tst_qtoolbar.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include QT_FORWARD_DECLARE_CLASS(QAction) @@ -80,6 +81,8 @@ private slots: void task191727_layout(); void task197996_visibility(); + + void extraCpuConsumption(); // QTBUG-54676 }; @@ -1098,5 +1101,81 @@ void tst_QToolBar::task197996_visibility() QTRY_VERIFY(toolBar->widgetForAction(pAction)->isVisible()); } +class ShowHideEventCounter : public QObject +{ +public: + using QObject::QObject; + + bool eventFilter(QObject *watched, QEvent *event) override + { + if (qobject_cast(watched) && !event->spontaneous()) { + if (event->type() == QEvent::Show) + ++m_showEventsCount; + + if (event->type() == QEvent::Hide) + ++m_hideEventsCount; + } + + return QObject::eventFilter(watched, event); + } + + uint showEventsCount() const { return m_showEventsCount; } + uint hideEventsCount() const { return m_hideEventsCount; } + +private: + uint m_showEventsCount = 0; + uint m_hideEventsCount = 0; +}; + +void tst_QToolBar::extraCpuConsumption() +{ + QMainWindow mainWindow; + + auto tb = new QToolBar(&mainWindow); + tb->setMovable(false); + + auto extensions = tb->findChildren(); + QVERIFY(!extensions.isEmpty()); + + auto extensionButton = extensions.at(0); + QVERIFY(extensionButton); + + tb->addWidget(new QLabel("Lorem ipsum dolor sit amet")); + + auto le = new QLineEdit; + le->setClearButtonEnabled(true); + le->setText("Lorem ipsum"); + tb->addWidget(le); + + mainWindow.addToolBar(tb); + mainWindow.show(); + QVERIFY(QTest::qWaitForWindowActive(&mainWindow)); + + auto eventCounter = new ShowHideEventCounter(&mainWindow); + le->installEventFilter(eventCounter); + + auto defaultSize = mainWindow.size(); + + // Line edit should be hidden now and extension button should be displayed + for (double p = 0.7; extensionButton->isHidden() || qFuzzyCompare(p, 0.); p -= 0.01) { + mainWindow.resize(int(defaultSize.width() * p), defaultSize.height()); + } + QVERIFY(!extensionButton->isHidden()); + + // Line edit should be visible, but smaller + for (double p = 0.75; !extensionButton->isHidden() || qFuzzyCompare(p, 1.); p += 0.01) { + mainWindow.resize(int(defaultSize.width() * p), defaultSize.height()); + } + QVERIFY(extensionButton->isHidden()); + + // Dispatch all pending events + qApp->sendPostedEvents(); + qApp->processEvents(); + + QCOMPARE(eventCounter->showEventsCount(), eventCounter->hideEventsCount()); + QCOMPARE(eventCounter->showEventsCount(), uint(1)); + QCOMPARE(eventCounter->hideEventsCount(), uint(1)); +} + QTEST_MAIN(tst_QToolBar) #include "tst_qtoolbar.moc" From 4744f31e59711a407ffaf2db725711aec41bc134 Mon Sep 17 00:00:00 2001 From: Nick D'Ademo Date: Mon, 5 Nov 2018 15:13:19 +0800 Subject: [PATCH 0425/1650] QMdiArea: Do not reset tiled flag on spontaneous system window events Do not reset the isSubWindowsTiled flag if the hide/show event is an external (spontaneous) system window event, i.e. we should instead reset this flag when the subwindow itself is directly hidden or shown. This change ensures that tiling will be performed during the resizeEvent after an application window minimize (hide) and then restore (show). Change-Id: Ib37f52f1162b493be3413fc59951be2f30701439 Reviewed-by: Richard Moe Gustavsen --- src/widgets/widgets/qmdiarea.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/widgets/widgets/qmdiarea.cpp b/src/widgets/widgets/qmdiarea.cpp index f32cd26478..c1817060dd 100644 --- a/src/widgets/widgets/qmdiarea.cpp +++ b/src/widgets/widgets/qmdiarea.cpp @@ -2640,7 +2640,11 @@ bool QMdiArea::eventFilter(QObject *object, QEvent *event) #endif // QT_CONFIG(tabbar) Q_FALLTHROUGH(); case QEvent::Hide: - d->isSubWindowsTiled = false; + // Do not reset the isSubWindowsTiled flag if the event is a spontaneous system window event. + // This ensures that tiling will be performed during the resizeEvent after an application + // window minimize (hide) and then restore (show). + if (!event->spontaneous()) + d->isSubWindowsTiled = false; break; #if QT_CONFIG(rubberband) case QEvent::Close: From 2aef845c03a9544d51cdf67f712ecd1a7e62110f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 25 Nov 2018 13:35:45 +0100 Subject: [PATCH 0426/1650] macOS: Don't link to debug versions of frameworks unless requested The failure mode of this behavior is worse than the surprises that the non-explicit library dependency chain has, so it should be opt-in. This reverts back to the behavior in Qt 5.11, but lets our tests opt in to the feature. Fixes: QTBUG-71724 Change-Id: Iede11f02d978b637324ddf71d29e7c99fe3ee99f Reviewed-by: Simon Hausmann Reviewed-by: Thiago Macieira Reviewed-by: Eike Ziller --- mkspecs/features/qt.prf | 2 +- mkspecs/features/testcase.prf | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index 90e318e2a4..d16b3cf1be 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -231,7 +231,7 @@ for(ever) { !isEmpty(MODULE_MODULE) { contains(MODULE_CONFIG, lib_bundle) { framework = $$MODULE_MODULE - qtConfig(debug_and_release):!macx-xcode { + qtConfig(debug_and_release):qt_link_suffixed_framework:!macx-xcode { platform_target_suffix = $$qtPlatformTargetSuffix() !isEmpty(platform_target_suffix): \ # The -framework linker argument supports a name[,suffix] version, diff --git a/mkspecs/features/testcase.prf b/mkspecs/features/testcase.prf index 79883b7f09..bfc28c6861 100644 --- a/mkspecs/features/testcase.prf +++ b/mkspecs/features/testcase.prf @@ -21,6 +21,9 @@ testcase_lowdpi { } } +# Make sure we explicitly link to the debug version of the Qt libraries if needed +macos: CONFIG += qt_link_suffixed_framework + benchmark: type = benchmark else: type = check From 05892bca9b0dc57dc3b4fbc57e2aab3dac1ad830 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Thu, 22 Nov 2018 18:32:50 +0100 Subject: [PATCH 0427/1650] Fix build errors in OpenSSL 1.1 backend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SSL_CTX_set_ciphers is new in 1.1.1. Task-number: QTBUG-71983 Change-Id: If0ae9f95dcc867c62ed0d3a6a60c22c7f5e1cc9f Reviewed-by: Mårten Nordheim (cherry picked from commit 36f3eeaf3ec12126956d151a026379ab0385ab72) Reviewed-by: Timur Pocheptsov --- src/network/ssl/qsslsocket_openssl_symbols.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index 781b3d6640..fd58e9548e 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -161,7 +161,9 @@ DEFINEFUNC(void, OPENSSL_sk_free, OPENSSL_STACK *a, a, return, DUMMYARG) DEFINEFUNC2(void *, OPENSSL_sk_value, OPENSSL_STACK *a, a, int b, b, return nullptr, return) DEFINEFUNC(int, SSL_session_reused, SSL *a, a, return 0, return) DEFINEFUNC2(unsigned long, SSL_CTX_set_options, SSL_CTX *ctx, ctx, unsigned long op, op, return 0, return) +#ifdef TLS1_3_VERSION DEFINEFUNC2(int, SSL_CTX_set_ciphersuites, SSL_CTX *ctx, ctx, const char *str, str, return 0, return) +#endif DEFINEFUNC3(size_t, SSL_get_client_random, SSL *a, a, unsigned char *out, out, size_t outlen, outlen, return 0, return) DEFINEFUNC3(size_t, SSL_SESSION_get_master_key, const SSL_SESSION *ses, ses, unsigned char *out, out, size_t outlen, outlen, return 0, return) DEFINEFUNC6(int, CRYPTO_get_ex_new_index, int class_index, class_index, long argl, argl, void *argp, argp, CRYPTO_EX_new *new_func, new_func, CRYPTO_EX_dup *dup_func, dup_func, CRYPTO_EX_free *free_func, free_func, return -1, return) From 61373dff502fd222f68ed84c90bcc1822c4498e6 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Wed, 21 Nov 2018 13:46:28 +0100 Subject: [PATCH 0428/1650] tst_QNetworkReply: Blacklist getFromHttp:success-external Task-number: QTBUG-71953 Change-Id: Ib69754b169dd4d5e78f566ce817608b2349c8ae0 Reviewed-by: Timur Pocheptsov (cherry picked from commit 46076f73337d6b0fea9a006dab2af8864571ae2c) Reviewed-by: Liang Qi --- tests/auto/network/access/qnetworkreply/BLACKLIST | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/auto/network/access/qnetworkreply/BLACKLIST b/tests/auto/network/access/qnetworkreply/BLACKLIST index fab8224431..4d29a830e9 100644 --- a/tests/auto/network/access/qnetworkreply/BLACKLIST +++ b/tests/auto/network/access/qnetworkreply/BLACKLIST @@ -8,6 +8,9 @@ windows * [getErrors:ftp-host] linux +# QTBUG-71953 +[getFromHttp:success-external] +* [getFromHttpIntoBuffer] windows [getFromHttpIntoBuffer2] From d41879db384905c47c8fca976ae70ad6595de41f Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 27 Nov 2018 13:59:53 +0100 Subject: [PATCH 0429/1650] Documention: Use const-ref in the snippets for qOverload() This makes it clearer that const-ref needs to be specified in the template arguments of qOverload() and related. Change-Id: I527c8ca853be159af8665e9759d9549df10573b3 Reviewed-by: Martin Smith Reviewed-by: Olivier Goffart (Woboq GmbH) --- .../snippets/code/src_corelib_global_qglobal.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp index 7fdff974c1..0248640369 100644 --- a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp @@ -647,24 +647,24 @@ template<> class QTypeInfo : public QTypeInfoMerger {}; //! [52] struct Foo { void overloadedFunction(); - void overloadedFunction(int, QString); + void overloadedFunction(int, const QString &); }; ... qOverload<>(&Foo::overloadedFunction) - ... qOverload(&Foo::overloadedFunction) + ... qOverload(&Foo::overloadedFunction) //! [52] //! [53] ... QOverload<>::of(&Foo::overloadedFunction) - ... QOverload::of(&Foo::overloadedFunction) + ... QOverload::of(&Foo::overloadedFunction) //! [53] //! [54] struct Foo { - void overloadedFunction(int, QString); - void overloadedFunction(int, QString) const; + void overloadedFunction(int, const QString &); + void overloadedFunction(int, const QString &) const; }; - ... qConstOverload(&Foo::overloadedFunction) - ... qNonConstOverload(&Foo::overloadedFunction) + ... qConstOverload(&Foo::overloadedFunction) + ... qNonConstOverload(&Foo::overloadedFunction) //! [54] //! [qlikely] From 4e01b851159342122d42be1091d4cfa464700a4e Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 15 Nov 2018 17:59:18 +0100 Subject: [PATCH 0430/1650] QDateTimeEdit: fix setDate() if time is in a spring-forward If the time the widget is set to use falls in the gap skipped by a spring-forward, setting the date to the day of the spring-forward turned a valid date into an invalid date-time. So use the usual trick to map the "draft" date-time to a valid one. Fixes: QTBUG-64485 Fixes: QTBUG-58947 Change-Id: Ib8f0f092cd5d6dce3da31eb52cd42150ca0d1fcb Reviewed-by: Mitch Curtis --- src/widgets/widgets/qdatetimeedit.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp index fca81bec48..68bfd175ff 100644 --- a/src/widgets/widgets/qdatetimeedit.cpp +++ b/src/widgets/widgets/qdatetimeedit.cpp @@ -273,7 +273,13 @@ void QDateTimeEdit::setDate(const QDate &date) setDateRange(date, date); d->clearCache(); - d->setValue(QDateTime(date, d->value.toTime(), d->spec), EmitIfChanged); + QDateTime when(date, d->value.toTime(), d->spec); + // The specified time might not exist on the specified day, + // i.e. the time is in the gap a spring-forward jumps over. + if (!when.isValid()) + when = QDateTime::fromMSecsSinceEpoch(when.toMSecsSinceEpoch(), d->spec); + Q_ASSERT(when.isValid()); + d->setValue(when, EmitIfChanged); d->updateTimeSpec(); } } From d1f924bbce4e0057bdfe3cf3c10140895bec7510 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 23 Nov 2018 17:59:49 +0100 Subject: [PATCH 0431/1650] Fix tst_QStyleSheetStyle crash on uncommon multi-screen setup It would crash if there is no screen at 0,0. Change-Id: Ic84d75b3d8b917fe3696530cbe843e82923ba676 Reviewed-by: Friedemann Kleint --- .../widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp index f5d9433f70..03f24ba151 100644 --- a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp +++ b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp @@ -2085,7 +2085,8 @@ void tst_QStyleSheetStyle::highdpiImages() QFETCH(QColor, color); QWidget w; - QScreen *screen = QGuiApplication::screenAt(w.pos()); + QScreen *screen = QGuiApplication::primaryScreen(); + w.move(screen->availableGeometry().topLeft()); QHighDpiScaling::setScreenFactor(screen, screenFactor); w.setStyleSheet("QWidget { background-image: url(\":/images/testimage.png\"); }"); w.show(); From 7f6497e623fd66e0dc1ecab89ef16533154a6472 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 15 Nov 2018 22:26:55 +0100 Subject: [PATCH 0432/1650] Ensure QOpenGLWidget FBO is always initialized QOpenGLWidget uses an FBO internally, that is glCleared whenever recreated. But for the clear to be visible across shared contexts we must also issue a glFlush. QOpenGLWidget defers this flush until the compositing step, in QOpenGLWidgetPrivate::beginCompose(), based on a flushPending variable. This variable is set either after invoking the user's paintGL() function, or when opening a QPainter on the QOpenGLWidget, via QOpenGLWidgetPaintDevice::ensureActiveTarget(). Unfortunately, if QOpenGLWidget::paintEvent() is overridden or intercepted (meaning we will not end up calling paintGL()), but the overridden paint event does not open a QPainter, we end up never setting flushPending to true, and end up composing an uninitialized FBO. This can lead to rendering issues, or even kernel panics with some unfortunate GL drivers. The fix is to ensure the glClear is always flushed before composing, by forcing a pending flush whenever the FBO is recreated. Fixes: QTBUG-70921 Change-Id: I72b596c09dcf54bd0f37668062daaad2d6f7f4bd Reviewed-by: Laszlo Agocs --- src/widgets/kernel/qopenglwidget.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index c96b6812c4..53dc88bd2c 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -756,6 +756,7 @@ void QOpenGLWidgetPrivate::recreateFbo() fbo->bind(); context->functions()->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + flushPending = true; // Make sure the FBO is initialized before use paintDevice->setSize(deviceSize); paintDevice->setDevicePixelRatio(q->devicePixelRatioF()); From a5e32f93759db5aff30994546cd1cc172e6a57dc Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 27 Nov 2018 14:34:26 +0100 Subject: [PATCH 0433/1650] Re-enable the QScroller tests on macOS Maybe they aren't flaky anymore... let's find out. Task-number: QTBUG-29950 Task-number: QTBUG-30133 Change-Id: I1a2a3ef7facac5b6e59588d7c6b1b28b40a788ea Reviewed-by: Friedemann Kleint --- tests/auto/widgets/util/qscroller/tst_qscroller.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/tests/auto/widgets/util/qscroller/tst_qscroller.cpp b/tests/auto/widgets/util/qscroller/tst_qscroller.cpp index 43063881b2..fac13c7074 100644 --- a/tests/auto/widgets/util/qscroller/tst_qscroller.cpp +++ b/tests/auto/widgets/util/qscroller/tst_qscroller.cpp @@ -347,9 +347,6 @@ void tst_QScroller::scrollerProperties() void tst_QScroller::scrollTo() { -#ifdef Q_OS_MAC - QSKIP("Flakey test - QTBUG-29950"); -#endif { tst_QScrollerWidget *sw = new tst_QScrollerWidget(); sw->scrollArea = QRectF( 0, 0, 1000, 1000 ); @@ -376,9 +373,6 @@ void tst_QScroller::scrollTo() void tst_QScroller::scroll() { -#ifdef Q_OS_MAC - QSKIP("Flakey test - QTBUG-30133"); -#endif #ifndef QT_NO_GESTURES // -- good case. normal scroll tst_QScrollerWidget *sw = new tst_QScrollerWidget(); @@ -419,9 +413,6 @@ void tst_QScroller::scroll() void tst_QScroller::overshoot() { -#ifdef Q_OS_MAC - QSKIP("Flakey test - QTBUG-29950"); -#endif #ifndef QT_NO_GESTURES tst_QScrollerWidget *sw = new tst_QScrollerWidget(); sw->scrollArea = QRectF(0, 0, 1000, 1000); From f1812aad895ed2b8337a6d98d05623714680aba9 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 8 Nov 2018 14:11:11 +0100 Subject: [PATCH 0434/1650] QFocusFrame: protect it from being moved around by accident If a focus frame is set around a widget that exist inside a QAbstractItemView, both the focus frame and the widget will be scrolled when the table is scrolled (since the focus frame is a child of the view). The result is that after the widget has been scrolled (which will move the focus frame to the correct position as well), the focus frame will be scrolled next, and therefore away from the widget. This patch will catch this case by always adjusting the focus frame position when someone tries to move it. Trying to move the focus frame away from the widget it tracks will anyway be flaky. Fixes: QTBUG-63877 Change-Id: Ic2aacc4fafc219280e32092c258a7539d0db9cd0 Reviewed-by: Timur Pocheptsov --- src/widgets/widgets/qfocusframe.cpp | 20 +++++++++- .../widgets/qfocusframe/tst_qfocusframe.cpp | 39 +++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/widgets/widgets/qfocusframe.cpp b/src/widgets/widgets/qfocusframe.cpp index 8b8f4db86e..0992becdf0 100644 --- a/src/widgets/widgets/qfocusframe.cpp +++ b/src/widgets/widgets/qfocusframe.cpp @@ -335,7 +335,25 @@ QFocusFrame::eventFilter(QObject *o, QEvent *e) /*! \reimp */ bool QFocusFrame::event(QEvent *e) { - return QWidget::event(e); + Q_D(QFocusFrame); + + switch (e->type()) { + case QEvent::Move: + case QEvent::Resize: + if (d->widget) { + // When we're tracking a widget, we don't allow anyone to move the focus frame around. + // We do our best with event filters to make it stay on top of the widget, so trying to + // move the frame somewhere else will be flaky at best. This can e.g happen for general + // purpose code, like QAbstractScrollView, that bulk-moves all children a certain distance. + // So we need to call updateSize() when that happens to ensure that the focus frame stays + // on top of the widget. + d->updateSize(); + } + break; + default: + return QWidget::event(e); + } + return true; } QT_END_NAMESPACE diff --git a/tests/auto/widgets/widgets/qfocusframe/tst_qfocusframe.cpp b/tests/auto/widgets/widgets/qfocusframe/tst_qfocusframe.cpp index e6e689336a..657a1ea55c 100644 --- a/tests/auto/widgets/widgets/qfocusframe/tst_qfocusframe.cpp +++ b/tests/auto/widgets/widgets/qfocusframe/tst_qfocusframe.cpp @@ -32,6 +32,8 @@ #include #include #include +#include +#include class tst_QFocusFrame : public QObject { @@ -43,6 +45,7 @@ public: private slots: void getSetCheck(); + void focusFrameInsideScrollview(); }; tst_QFocusFrame::tst_QFocusFrame() @@ -68,5 +71,41 @@ void tst_QFocusFrame::getSetCheck() delete obj1; } +void tst_QFocusFrame::focusFrameInsideScrollview() +{ + // Make sure that the focus frame follows the widget, even + // if the widget is inside a QAbstractItemView. A QAbstractItemView will scroll + // all the children, including the focus frame, when it scrolls, which + // is why special considerations are taken inside the focus frame to + // prevent the frame to scroll away from the widget it tracks. + + if (qApp->style()->objectName() != QLatin1String("macintosh")) + QSKIP("This test is only valid when using a style that has a focus frame"); + + QWidget window; + window.setGeometry(100, 100, 500, 500); + + QTableView tableView(&window); + tableView.resize(window.size()); + QStandardItemModel *itemModel = new QStandardItemModel(); + for (int i = 0; i < 50; ++i) + itemModel->appendRow(new QStandardItem("Value")); + tableView.setModel(itemModel); + tableView.edit(itemModel->index(8, 0)); + + window.show(); + QFocusFrame *focusFrame = nullptr; + QTRY_VERIFY(focusFrame = window.findChild()); + const QPoint initialOffset = focusFrame->widget()->mapToGlobal(QPoint()) - focusFrame->mapToGlobal(QPoint()); + + tableView.scrollTo(itemModel->index(40, 0)); + QPoint offsetAfterScroll = focusFrame->widget()->mapToGlobal(QPoint()) - focusFrame->mapToGlobal(QPoint()); + QCOMPARE(offsetAfterScroll, initialOffset); + + tableView.scrollTo(itemModel->index(0, 0)); + offsetAfterScroll = focusFrame->widget()->mapToGlobal(QPoint()) - focusFrame->mapToGlobal(QPoint()); + QCOMPARE(offsetAfterScroll, initialOffset); +} + QTEST_MAIN(tst_QFocusFrame) #include "tst_qfocusframe.moc" From 4447db44652420d80886de8de4b02f3bcd9fe86c Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 27 Nov 2018 08:26:40 +0100 Subject: [PATCH 0435/1650] Active Qt Servers: Fix midl warning about unknown option Remove the option from msvc-desktop.conf, which duplicates the /nologo option in idcidl.prf. Fixes: QTBUG-72046 Change-Id: I906097e0611f4578c307616b3f9ebecdfc4d8812 Reviewed-by: Volker Hilsheimer --- mkspecs/common/msvc-desktop.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/common/msvc-desktop.conf b/mkspecs/common/msvc-desktop.conf index a4fadeb029..c0d4bd2acc 100644 --- a/mkspecs/common/msvc-desktop.conf +++ b/mkspecs/common/msvc-desktop.conf @@ -106,7 +106,7 @@ QMAKE_LIBS_OPENGL_ES2_DEBUG = gdi32.lib user32.lib QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib QMAKE_LIBS_QT_ENTRY = -lqtmain -QMAKE_IDL = midl /NOLOGO +QMAKE_IDL = midl QMAKE_LIB = lib /NOLOGO QMAKE_RC = rc /NOLOGO From dba606767056986a8c0cc973ec5932f603f14759 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 25 Oct 2018 16:35:58 -0700 Subject: [PATCH 0436/1650] Optimize QSharedPointer::getAndRef with the three-operand testAndSet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Originally QAtomicPointer didn't have the three-operand version, resulting in code like: if (!atomic.testAndSetXxx(expected, newvalue)) expected = atomic.load(); The three-operand version gives us the current value of the atomic in case the test failed and it's free in all architectures, unlike the extra load. I have to use testAndSetOrdered here because I need the failing load to use the Acquire memory order, even though that has an extra Acquire for the successful case we don't need. QAtomicPointer does not have testAndSetReleaseAcquire. Change-Id: I1bd327aeaf73421a8ec5fffd1560fe30d3bfd9b8 Reviewed-by: Romain Pokrzywka Reviewed-by: Jędrzej Nowacki --- src/corelib/tools/qsharedpointer.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index 622b03f42d..a1caeeb135 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -1383,15 +1383,18 @@ QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::ge ExternalRefCountData *x = new ExternalRefCountData(Qt::Uninitialized); x->strongref.store(-1); x->weakref.store(2); // the QWeakPointer that called us plus the QObject itself - if (!d->sharedRefcount.testAndSetRelease(0, x)) { + + ExternalRefCountData *ret; + if (d->sharedRefcount.testAndSetOrdered(nullptr, x, ret)) { // ought to be release+acquire; this is acq_rel+acquire + ret = x; + } else { // ~ExternalRefCountData has a Q_ASSERT, so we use this trick to // only execute this if Q_ASSERTs are enabled Q_ASSERT((x->weakref.store(0), true)); delete x; - x = d->sharedRefcount.loadAcquire(); - x->weakref.ref(); + ret->weakref.ref(); } - return x; + return ret; } /** From d8962144b425b9929770b67bcfb8247a9e9b9022 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 26 Oct 2018 23:22:22 -0700 Subject: [PATCH 0437/1650] Fix calculation of the string tab size in QElfParser First of all, we were using the wrong size variable: instead of the size of the section, found in the section header, we were using the size of each section entry in the section table. Since that's usually smaller, we weren't hitting a problem. Second, if the string table is the last thing in the file and there's nothing else after it, not even padding, then offset + section_size can be equal to the file size. In fact, the .shstrtab section is usually the last one, as it contains the section names themselves, so it stands to reason that it's the second to last thing written. For generic linkers, the last data in the file is the section table itself, so usually the file is larger by at least a kilobyte, which is why we haven't hit this bug. It could only manifest as deciding that certain specially-crafted but valid ELF files were invalid. I can't think of a way to trick it into thinking an invalid ELF is valid. That's another reason why this code needs to be rewritten with more modern coding styles and actually using Fixes: QTBUG-71443 Change-Id: I1bd327aeaf73421a8ec5fffd156162f2df5557b8 Reviewed-by: Simon Hausmann --- src/corelib/plugin/qelfparser_p.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/plugin/qelfparser_p.cpp b/src/corelib/plugin/qelfparser_p.cpp index 159a324c6b..13eee3539e 100644 --- a/src/corelib/plugin/qelfparser_p.cpp +++ b/src/corelib/plugin/qelfparser_p.cpp @@ -168,11 +168,11 @@ int QElfParser::parse(const char *dataStart, ulong fdlen, const QString &library parseSectionHeader(dataStart + soff, &strtab); m_stringTableFileOffset = strtab.offset; - if ((quint32)(m_stringTableFileOffset + e_shentsize) >= fdlen || m_stringTableFileOffset == 0) { + if ((quint32)(strtab.offset + strtab.size) > fdlen || strtab.offset == 0) { if (lib) lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)") .arg(library, QLibrary::tr("string table seems to be at %1") - .arg(QString::number(soff, 16))); + .arg(QString::number(strtab.offset, 16))); return Corrupt; } From ae8389e19c5804c867b2981311c623003a691474 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 16 Nov 2018 17:24:09 +0100 Subject: [PATCH 0438/1650] Ensure alignment of image-data Instead of relying on the return value of malloc having the correct alignment, use proper non-throwing new[] operators. Change-Id: I06c6c619e21c848f3d184bdb7cef8c5589c1c7ab Reviewed-by: Thiago Macieira --- src/gui/image/qimage.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 0105f1decd..da963adae6 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -149,7 +149,10 @@ QImageData * QImageData::create(const QSize &size, QImage::Format format) d->bytes_per_line = params.bytesPerLine; d->nbytes = params.totalSize; - d->data = (uchar *)malloc(d->nbytes); + if (depth == 64) + d->data = (uchar *)new (std::nothrow) quint64[d->nbytes / sizeof(quint64)]; + else // nbytes is known to already be a multipla of 4: + d->data = (uchar *)new (std::nothrow) quint32[d->nbytes / sizeof(quint32)]; if (!d->data) return nullptr; @@ -165,8 +168,13 @@ QImageData::~QImageData() if (is_cached) QImagePixmapCleanupHooks::executeImageHooks((((qint64) ser_no) << 32) | ((qint64) detach_no)); delete paintEngine; - if (data && own_data) - free(data); + if (data && own_data) { + // Casting to avoid being theoretically UB: + if (depth == 64) + delete[] (quint64 *)data; + else + delete[] (quint32 *)data; + } data = 0; } From 49d63057e31427aff84d4fe33d60bacfe2445076 Mon Sep 17 00:00:00 2001 From: Kevin Funk Date: Wed, 28 Nov 2018 10:09:00 +0100 Subject: [PATCH 0439/1650] qobject_p.h: Use nullptr everywhere Change-Id: I605e44607cc09775548c1e6b781d476c1627c9c7 Reviewed-by: Simon Hausmann --- src/corelib/kernel/qobject_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 6aea40cf4a..5dfef786ec 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -341,7 +341,7 @@ inline QMetaObject::Connection QObjectPrivate::connect(const typename QtPrivate: Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible::value), "Return type of the slot is not compatible with the return type of the signal."); - const int *types = 0; + const int *types = nullptr; if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection) types = QtPrivate::ConnectionTypes::types(); From f4a84ac966077ec9e27c99a43b6911ebab1331bb Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 28 Nov 2018 10:50:18 +0100 Subject: [PATCH 0440/1650] QWindowContainer: Fix warning triggered by QT_ASCII_CAST_WARN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Amends 52bd707f0d6a585c2f5da9565834eb91f1d3dbc8. Change-Id: Icc42edc7a943099b36bfa92fe7cd1a92db344991 Reviewed-by: Tor Arne Vestbø --- src/widgets/kernel/qwindowcontainer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/kernel/qwindowcontainer.cpp b/src/widgets/kernel/qwindowcontainer.cpp index d2680e5280..4ef34f0102 100644 --- a/src/widgets/kernel/qwindowcontainer.cpp +++ b/src/widgets/kernel/qwindowcontainer.cpp @@ -231,7 +231,7 @@ QWindowContainer::QWindowContainer(QWindow *embeddedWindow, QWidget *parent, Qt: QString windowName = d->window->objectName(); if (windowName.isEmpty()) windowName = QString::fromUtf8(d->window->metaObject()->className()); - d->fakeParent.setObjectName(windowName + "ContainerFakeParent"); + d->fakeParent.setObjectName(windowName + QLatin1String("ContainerFakeParent")); d->window->setParent(&d->fakeParent); setAcceptDrops(true); From 9e1cb252e0c2628c238150250670a55bd479846c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 16 Nov 2018 20:38:39 +0100 Subject: [PATCH 0441/1650] Destroy QWindowContainer's fake parent window when not needed Keeping the fake parent window around in a created state means we're wasting system resources such as native platform views/windows, and makes it harder to debug the lifetime of these resources. The fake window will be re-created if re-parented into at a later point. Change-Id: Ib82560e7e565af19d58afe121fd087669a6ffb95 Reviewed-by: Richard Moe Gustavsen --- src/widgets/kernel/qwindowcontainer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/widgets/kernel/qwindowcontainer.cpp b/src/widgets/kernel/qwindowcontainer.cpp index 4ef34f0102..4b289d2d33 100644 --- a/src/widgets/kernel/qwindowcontainer.cpp +++ b/src/widgets/kernel/qwindowcontainer.cpp @@ -315,6 +315,7 @@ bool QWindowContainer::event(QEvent *e) d->window->setParent(d->usesNativeWidgets ? windowHandle() : window()->windowHandle()); + d->fakeParent.destroy(); } if (d->window->parent()) { d->markParentChain(); @@ -404,6 +405,7 @@ void QWindowContainer::parentWasChanged(QWidget *parent) Q_ASSERT(toplevel->windowHandle()); } d->window->setParent(toplevel->windowHandle()); + d->fakeParent.destroy(); d->updateGeometry(); } } From 4213f239361e042ae5a053e3eaa87931b6696caf Mon Sep 17 00:00:00 2001 From: Kirill Burtsev Date: Tue, 23 Oct 2018 18:06:55 +0200 Subject: [PATCH 0442/1650] xcb: Fix leaking events on destroy This patch amends 243c3044b647357ca6df79ac1497ae43de957d31 Change-Id: Ieeebb1e2b94d7c191bf80a1f439c826c406a0c08 Reviewed-by: Gatis Paeglis --- src/plugins/platforms/xcb/qxcbeventqueue.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbeventqueue.cpp b/src/plugins/platforms/xcb/qxcbeventqueue.cpp index 862f68764b..f6158d3127 100644 --- a/src/plugins/platforms/xcb/qxcbeventqueue.cpp +++ b/src/plugins/platforms/xcb/qxcbeventqueue.cpp @@ -105,7 +105,8 @@ QXcbEventQueue::~QXcbEventQueue() wait(); } - while (xcb_generic_event_t *event = takeFirst()) + flushBufferedEvents(); + while (xcb_generic_event_t *event = takeFirst(QEventLoop::AllEvents)) free(event); if (m_head && m_head->fromHeap) @@ -219,6 +220,8 @@ void QXcbEventQueue::run() tail->next = qXcbEventNodeFactory(event); tail = tail->next; m_tail.store(tail, std::memory_order_release); + } else { + free(event); } }; From 030b17ecc099ab3191b9b7a43a61560cf3d43f29 Mon Sep 17 00:00:00 2001 From: Kirill Burtsev Date: Thu, 22 Nov 2018 11:58:14 +0100 Subject: [PATCH 0443/1650] QDBusConnection: prevent leaking connection/server on destroy Amends fix 68964b1023 Change-Id: I05816f4b4d2128ed0b669e124d9c9eef92122ec0 Reviewed-by: Alex Blasche Reviewed-by: Thiago Macieira --- src/dbus/qdbusintegrator.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 03de5b0091..dfef25e3a8 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1062,10 +1062,11 @@ QDBusConnectionPrivate::~QDBusConnectionPrivate() "Timer and socket errors will follow and the program will probably crash", qPrintable(name)); + auto lastMode = mode; // reset on connection close closeConnection(); qDeleteAll(cachedMetaObjects); - if (mode == ClientMode || mode == PeerMode) { + if (lastMode == ClientMode || lastMode == PeerMode) { // the bus service object holds a reference back to us; // we need to destroy it before we finish destroying ourselves Q_ASSERT(ref.load() == 0); @@ -1077,7 +1078,7 @@ QDBusConnectionPrivate::~QDBusConnectionPrivate() if (connection) q_dbus_connection_unref(connection); connection = 0; - } else if (mode == ServerMode) { + } else if (lastMode == ServerMode) { if (server) q_dbus_server_unref(server); server = 0; From bd989d1652b8ad77088edbc7a68475dd1aabe52e Mon Sep 17 00:00:00 2001 From: Kirill Burtsev Date: Fri, 23 Nov 2018 13:02:33 +0100 Subject: [PATCH 0444/1650] xcb: free leaking clipboard events The leak has been there since the beginnings of Qt 5.0. Change-Id: I238181dcc63cb4cf8a60b5c565b184d8278d0315 Reviewed-by: Gatis Paeglis --- src/plugins/platforms/xcb/qxcbclipboard.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp index 9c7559d514..bc92f82d5f 100644 --- a/src/plugins/platforms/xcb/qxcbclipboard.cpp +++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp @@ -261,7 +261,9 @@ QXcbClipboard::~QXcbClipboard() connection()->sync(); // waiting until the clipboard manager fetches the content. - if (!waitForClipboardEvent(m_owner, XCB_SELECTION_NOTIFY, true)) { + if (auto event = waitForClipboardEvent(m_owner, XCB_SELECTION_NOTIFY, true)) { + free(event); + } else { qWarning("QXcbClipboard: Unable to receive an event from the " "clipboard manager in a reasonable time"); } @@ -838,6 +840,7 @@ QByteArray QXcbClipboard::clipboardReadIncrementalProperty(xcb_window_t win, xcb if (!ge) break; xcb_property_notify_event_t *event = (xcb_property_notify_event_t *)ge; + QScopedPointer guard(event); if (event->atom != property || event->state != XCB_PROPERTY_NEW_VALUE @@ -869,8 +872,6 @@ QByteArray QXcbClipboard::clipboardReadIncrementalProperty(xcb_window_t win, xcb } else { break; } - - free(ge); } // timed out ... create a new requestor window, otherwise the requestor From b22c4e593b99675a641fd6403a70ad9974b02508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sat, 24 Nov 2018 22:50:16 +0100 Subject: [PATCH 0445/1650] CoreText: Localize getTraitValue helper function It's only used in a single function (twice), so let's keep it closer to the call site. Change-Id: I7f8ceadc380171237eef3fa6b03ccd6bc89e99af Reviewed-by: Simon Hausmann --- .../fontdatabases/mac/qfontengine_coretext.mm | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index 0430e79bac..c00b9c3d46 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -155,17 +155,6 @@ static void loadAdvancesForGlyphs(CTFontRef ctfont, } } -static float getTraitValue(CFDictionaryRef allTraits, CFStringRef trait) -{ - if (CFDictionaryContainsKey(allTraits, trait)) { - CFNumberRef traitNum = (CFNumberRef) CFDictionaryGetValue(allTraits, trait); - float v = 0; - CFNumberGetValue(traitNum, kCFNumberFloatType, &v); - return v; - } - return 0; -} - int QCoreTextFontEngine::antialiasingThreshold = 0; QFontEngine::GlyphFormat QCoreTextFontEngine::defaultGlyphFormat = QFontEngine::Format_A32; @@ -277,6 +266,16 @@ void QCoreTextFontEngine::init() if (traits & kCTFontItalicTrait) fontDef.style = QFont::StyleItalic; + static const auto getTraitValue = [](CFDictionaryRef allTraits, CFStringRef trait) -> float { + if (CFDictionaryContainsKey(allTraits, trait)) { + CFNumberRef traitNum = (CFNumberRef) CFDictionaryGetValue(allTraits, trait); + float v = 0; + CFNumberGetValue(traitNum, kCFNumberFloatType, &v); + return v; + } + return 0; + }; + CFDictionaryRef allTraits = CTFontCopyTraits(ctfont); fontDef.weight = QCoreTextFontEngine::qtWeightFromCFWeight(getTraitValue(allTraits, kCTFontWeightTrait)); int slant = static_cast(getTraitValue(allTraits, kCTFontSlantTrait) * 500 + 500); From 9dd2048c1a11b29f0e16a7906e216133201d24db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sat, 24 Nov 2018 23:15:07 +0100 Subject: [PATCH 0446/1650] CoreText: Simplify and share code for loading glyph advances The function doesn't need the flags argument, nor does it need the ctfont or fontdef arguments if it's a normal const member function. It can also be used from QCoreTextFontEngine::stringToCMap(), instead of duplicating the code. This was originally the case before b4aa5d97 which improved surrogate pair handling, but for some reason the change introduced the duplicate code instead of just changing the arguments in the function call slightly. The use of 0xff000000 to skip certain glyphs looks dubious, and is probably related to QFontEngineMulti's use of the high byte to indicate which engine the glyph came from, but the multi engine strips this away before calling out to the concrete engine so it could potentially be removed in a later patch. Change-Id: I6c693595616da1b69fdbe3d7a31e392a8443369d Reviewed-by: Simon Hausmann --- .../fontdatabases/mac/qfontengine_coretext.mm | 65 +++++++------------ .../mac/qfontengine_coretext_p.h | 2 + 2 files changed, 27 insertions(+), 40 deletions(-) diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index c00b9c3d46..a58ea71b19 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -133,28 +133,6 @@ QFont::Weight QCoreTextFontEngine::qtWeightFromCFWeight(float value) return ret; } -static void loadAdvancesForGlyphs(CTFontRef ctfont, - QVarLengthArray &cgGlyphs, - QGlyphLayout *glyphs, int len, - QFontEngine::ShaperFlags flags, - const QFontDef &fontDef) -{ - Q_UNUSED(flags); - QVarLengthArray advances(len); - CTFontGetAdvancesForGlyphs(ctfont, kCTFontOrientationHorizontal, cgGlyphs.data(), advances.data(), len); - - for (int i = 0; i < len; ++i) { - if (glyphs->glyphs[i] & 0xff000000) - continue; - glyphs->advances[i] = QFixed::fromReal(advances[i].width); - } - - if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { - for (int i = 0; i < len; ++i) - glyphs->advances[i] = glyphs->advances[i].round(); - } -} - int QCoreTextFontEngine::antialiasingThreshold = 0; QFontEngine::GlyphFormat QCoreTextFontEngine::defaultGlyphFormat = QFontEngine::Format_A32; @@ -360,22 +338,9 @@ bool QCoreTextFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout * *nglyphs = glyph_pos; glyphs->numGlyphs = glyph_pos; - if (flags & GlyphIndicesOnly) - return true; + if (!(flags & GlyphIndicesOnly)) + loadAdvancesForGlyphs(cgGlyphs, glyphs); - QVarLengthArray advances(glyph_pos); - CTFontGetAdvancesForGlyphs(ctfont, kCTFontOrientationHorizontal, cgGlyphs.data(), advances.data(), glyph_pos); - - for (int i = 0; i < glyph_pos; ++i) { - if (glyphs->glyphs[i] & 0xff000000) - continue; - glyphs->advances[i] = QFixed::fromReal(advances[i].width); - } - - if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { - for (int i = 0; i < glyph_pos; ++i) - glyphs->advances[i] = glyphs->advances[i].round(); - } return true; } @@ -801,17 +766,37 @@ QImage QCoreTextFontEngine::bitmapForGlyph(glyph_t glyph, QFixed subPixelPositio void QCoreTextFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags flags) const { - int i, numGlyphs = glyphs->numGlyphs; + Q_UNUSED(flags); + + const int numGlyphs = glyphs->numGlyphs; QVarLengthArray cgGlyphs(numGlyphs); - for (i = 0; i < numGlyphs; ++i) { + for (int i = 0; i < numGlyphs; ++i) { if (glyphs->glyphs[i] & 0xff000000) cgGlyphs[i] = 0; else cgGlyphs[i] = glyphs->glyphs[i]; } - loadAdvancesForGlyphs(ctfont, cgGlyphs, glyphs, numGlyphs, flags, fontDef); + loadAdvancesForGlyphs(cgGlyphs, glyphs); +} + +void QCoreTextFontEngine::loadAdvancesForGlyphs(QVarLengthArray &cgGlyphs, QGlyphLayout *glyphs) const +{ + const int numGlyphs = glyphs->numGlyphs; + QVarLengthArray advances(numGlyphs); + CTFontGetAdvancesForGlyphs(ctfont, kCTFontOrientationHorizontal, cgGlyphs.data(), advances.data(), numGlyphs); + + for (int i = 0; i < numGlyphs; ++i) { + if (glyphs->glyphs[i] & 0xff000000) + continue; + glyphs->advances[i] = QFixed::fromReal(advances[i].width); + } + + if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { + for (int i = 0; i < numGlyphs; ++i) + glyphs->advances[i] = glyphs->advances[i].round(); + } } QFontEngine::FaceId QCoreTextFontEngine::faceId() const diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h index b77aaa27c1..f4213a2ffa 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h @@ -128,6 +128,8 @@ public: protected: void init(); QImage imageForGlyph(glyph_t glyph, QFixed subPixelPosition, bool colorful, const QTransform &m); + void loadAdvancesForGlyphs(QVarLengthArray &cgGlyphs, QGlyphLayout *glyphs) const; + CTFontRef ctfont; CGFontRef cgFont; int synthesisFlags; From 61a94d2d046c1448ba4c66dfc8e0246286bab14c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sat, 24 Nov 2018 23:42:32 +0100 Subject: [PATCH 0447/1650] CoreText: Share code by using delegate constructor Change-Id: If3d5d533f98552335517ef61cb748d0117fe3053 Reviewed-by: Simon Hausmann --- .../fontdatabases/mac/qfontengine_coretext.mm | 15 +++++++++------ .../fontdatabases/mac/qfontengine_coretext_p.h | 1 + 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index a58ea71b19..b5e4359caf 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -190,10 +190,8 @@ QCoreTextFontEngine *QCoreTextFontEngine::create(const QByteArray &fontData, qre } QCoreTextFontEngine::QCoreTextFontEngine(CTFontRef font, const QFontDef &def) - : QFontEngine(Mac) + : QCoreTextFontEngine(def) { - fontDef = def; - transform = qt_transform_from_fontdef(fontDef); ctfont = font; CFRetain(ctfont); cgFont = CTFontCopyGraphicsFont(font, NULL); @@ -201,10 +199,8 @@ QCoreTextFontEngine::QCoreTextFontEngine(CTFontRef font, const QFontDef &def) } QCoreTextFontEngine::QCoreTextFontEngine(CGFontRef font, const QFontDef &def) - : QFontEngine(Mac) + : QCoreTextFontEngine(def) { - fontDef = def; - transform = qt_transform_from_fontdef(fontDef); cgFont = font; // Keep reference count balanced CFRetain(cgFont); @@ -212,6 +208,13 @@ QCoreTextFontEngine::QCoreTextFontEngine(CGFontRef font, const QFontDef &def) init(); } +QCoreTextFontEngine::QCoreTextFontEngine(const QFontDef &def) + : QFontEngine(Mac) +{ + fontDef = def; + transform = qt_transform_from_fontdef(fontDef); +} + QCoreTextFontEngine::~QCoreTextFontEngine() { CFRelease(cgFont); diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h index f4213a2ffa..33c3c0cd40 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h @@ -126,6 +126,7 @@ public: static QCoreTextFontEngine *create(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference); protected: + QCoreTextFontEngine(const QFontDef &def); void init(); QImage imageForGlyph(glyph_t glyph, QFixed subPixelPosition, bool colorful, const QTransform &m); void loadAdvancesForGlyphs(QVarLengthArray &cgGlyphs, QGlyphLayout *glyphs) const; From d3ec5a2b09f3c9f5a67e757aa6b7b0dd09bbe97a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 25 Nov 2018 00:41:00 +0100 Subject: [PATCH 0448/1650] CoreText: Use QCFType to track CoreFoundation member variables The operator T() function of QAppleRefCounted should be const so that the underlying type can be accessed from const member functions just like the naked underlying type could. Change-Id: I0819c5795d28442a6ff4db2732e211b183574f9f Reviewed-by: Simon Hausmann --- src/corelib/kernel/qcore_mac_p.h | 2 +- .../fontdatabases/mac/qfontengine_coretext.mm | 19 +++++++------------ .../mac/qfontengine_coretext_p.h | 4 ++-- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h index b14a494296..acb87f8a3c 100644 --- a/src/corelib/kernel/qcore_mac_p.h +++ b/src/corelib/kernel/qcore_mac_p.h @@ -89,7 +89,7 @@ public: QAppleRefCounted(QAppleRefCounted &&other) : value(other.value) { other.value = T(); } QAppleRefCounted(const QAppleRefCounted &other) : value(other.value) { if (value) RetainFunction(value); } ~QAppleRefCounted() { if (value) ReleaseFunction(value); } - operator T() { return value; } + operator T() const { return value; } void swap(QAppleRefCounted &other) Q_DECL_NOEXCEPT_EXPR(noexcept(qSwap(value, other.value))) { qSwap(value, other.value); } QAppleRefCounted &operator=(const QAppleRefCounted &other) diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index b5e4359caf..2fba47d5dd 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -192,19 +192,16 @@ QCoreTextFontEngine *QCoreTextFontEngine::create(const QByteArray &fontData, qre QCoreTextFontEngine::QCoreTextFontEngine(CTFontRef font, const QFontDef &def) : QCoreTextFontEngine(def) { - ctfont = font; - CFRetain(ctfont); - cgFont = CTFontCopyGraphicsFont(font, NULL); + ctfont = QCFType::constructFromGet(font); + cgFont = CTFontCopyGraphicsFont(font, nullptr); init(); } QCoreTextFontEngine::QCoreTextFontEngine(CGFontRef font, const QFontDef &def) : QCoreTextFontEngine(def) { - cgFont = font; - // Keep reference count balanced - CFRetain(cgFont); - ctfont = CTFontCreateWithGraphicsFont(font, fontDef.pixelSize, &transform, NULL); + cgFont = QCFType::constructFromGet(font); + ctfont = CTFontCreateWithGraphicsFont(font, fontDef.pixelSize, &transform, nullptr); init(); } @@ -217,14 +214,12 @@ QCoreTextFontEngine::QCoreTextFontEngine(const QFontDef &def) QCoreTextFontEngine::~QCoreTextFontEngine() { - CFRelease(cgFont); - CFRelease(ctfont); } void QCoreTextFontEngine::init() { - Q_ASSERT(ctfont != NULL); - Q_ASSERT(cgFont != NULL); + Q_ASSERT(ctfont); + Q_ASSERT(cgFont); face_id.index = 0; QCFString name = CTFontCopyName(ctfont, kCTFontUniqueNameKey); @@ -856,7 +851,7 @@ QFontEngine *QCoreTextFontEngine::cloneWithSize(qreal pixelSize) const Qt::HANDLE QCoreTextFontEngine::handle() const { - return (Qt::HANDLE)ctfont; + return (Qt::HANDLE)(static_cast(ctfont)); } bool QCoreTextFontEngine::supportsTransformation(const QTransform &transform) const diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h index 33c3c0cd40..7ed2faff8e 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h @@ -131,8 +131,8 @@ protected: QImage imageForGlyph(glyph_t glyph, QFixed subPixelPosition, bool colorful, const QTransform &m); void loadAdvancesForGlyphs(QVarLengthArray &cgGlyphs, QGlyphLayout *glyphs) const; - CTFontRef ctfont; - CGFontRef cgFont; + QCFType ctfont; + QCFType cgFont; int synthesisFlags; CGAffineTransform transform; QFixed avgCharWidth; From 17cdb28ed5f68eea42e544a71c81b920b56baaf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 25 Nov 2018 13:58:49 +0100 Subject: [PATCH 0449/1650] macOS: Fix use of deprecated enum value Change-Id: Ibf979837e1adcadcbb100d059b06b1a48157eab6 Reviewed-by: Simon Hausmann --- src/gui/painting/qcoregraphics.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qcoregraphics.mm b/src/gui/painting/qcoregraphics.mm index 2249859c43..d45da14767 100644 --- a/src/gui/painting/qcoregraphics.mm +++ b/src/gui/painting/qcoregraphics.mm @@ -153,7 +153,7 @@ QPixmap qt_mac_toQPixmap(const NSImage *image, const QSizeF &size) return QPixmap(); [NSGraphicsContext saveGraphicsState]; [NSGraphicsContext setCurrentContext:gc]; - [image drawInRect:iconRect fromRect:iconRect operation:NSCompositeSourceOver fraction:1.0 respectFlipped:YES hints:nil]; + [image drawInRect:iconRect fromRect:iconRect operation:NSCompositingOperationSourceOver fraction:1.0 respectFlipped:YES hints:nil]; [NSGraphicsContext restoreGraphicsState]; return pixmap; } From 5fd6f4d8824b51cfdb05b4dd918db04941366ced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 25 Nov 2018 14:00:58 +0100 Subject: [PATCH 0450/1650] CoreText: Use QCFType instead of manual release/retain Change-Id: I4925ec0e563e784f542fd44706a214771c6abd2b Reviewed-by: Simon Hausmann --- .../fontdatabases/mac/qfontengine_coretext.mm | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index 2fba47d5dd..fbd2f81b19 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -252,12 +252,11 @@ void QCoreTextFontEngine::init() return 0; }; - CFDictionaryRef allTraits = CTFontCopyTraits(ctfont); + QCFType allTraits = CTFontCopyTraits(ctfont); fontDef.weight = QCoreTextFontEngine::qtWeightFromCFWeight(getTraitValue(allTraits, kCTFontWeightTrait)); int slant = static_cast(getTraitValue(allTraits, kCTFontSlantTrait) * 500 + 500); if (slant > 500 && !(traits & kCTFontItalicTrait)) fontDef.style = QFont::StyleOblique; - CFRelease(allTraits); if (fontDef.weight >= QFont::Bold && !(traits & kCTFontBoldTrait)) synthesisFlags |= SynthesizedBold; @@ -647,13 +646,13 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition #endif im.fill(0); // Faster than Qt::black - CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); + QCFType colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); uint cgflags = isColorGlyph ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst; #ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version cgflags |= kCGBitmapByteOrder32Host; #endif - CGContextRef ctx = CGBitmapContextCreate(im.bits(), im.width(), im.height(), + QCFType ctx = CGBitmapContextCreate(im.bits(), im.width(), im.height(), 8, im.bytesPerLine(), colorspace, cgflags); Q_ASSERT(ctx); @@ -706,9 +705,6 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition CTFontDrawGlyphs(ctfont, &cgGlyph, &CGPointZero, 1, ctx); } - CGContextRelease(ctx); - CGColorSpaceRelease(colorspace); - #if defined(Q_OS_MACOS) if (blackOnWhiteGlyphs) im.invertPixels(); From 09e3457541c54b084365bfb77ad58474f0666374 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 25 Nov 2018 14:09:00 +0100 Subject: [PATCH 0451/1650] macOS: Share code for resolving CGImage bitmapInfor for a QImage Removes assumptions about QImage format in a few places. Change-Id: I515701be53190429a48956c31986fa0804806406 Reviewed-by: Simon Hausmann --- src/gui/image/qimage_darwin.mm | 29 ++--------- src/gui/painting/qcoregraphics.mm | 48 +++++++++++++------ src/gui/painting/qcoregraphics_p.h | 2 + .../fontdatabases/mac/qfontengine_coretext.mm | 9 +--- 4 files changed, 41 insertions(+), 47 deletions(-) diff --git a/src/gui/image/qimage_darwin.mm b/src/gui/image/qimage_darwin.mm index a5c391ad21..7ca1a0869a 100644 --- a/src/gui/image/qimage_darwin.mm +++ b/src/gui/image/qimage_darwin.mm @@ -40,6 +40,7 @@ #include "qimage.h" #include +#include #import #import @@ -98,32 +99,10 @@ CGImageRef QImage::toCGImage() const if (isNull()) return nil; - // Determine the target native format - uint cgflags = kCGImageAlphaNone; - switch (format()) { - case QImage::Format_ARGB32: - cgflags = kCGImageAlphaFirst | kCGBitmapByteOrder32Host; - break; - case QImage::Format_RGB32: - cgflags = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host; - break; - case QImage::Format_RGBA8888_Premultiplied: - cgflags = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big; - break; - case QImage::Format_RGBA8888: - cgflags = kCGImageAlphaLast | kCGBitmapByteOrder32Big; - break; - case QImage::Format_RGBX8888: - cgflags = kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big; - break; - case QImage::Format_ARGB32_Premultiplied: - cgflags = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host; - break; - default: break; - } + CGBitmapInfo bitmapInfo = qt_mac_bitmapInfoForImage(*this); // Format not supported: return nil CGImageRef - if (cgflags == kCGImageAlphaNone) + if (bitmapInfo == kCGImageAlphaNone) return nil; // Create a data provider that owns a copy of the QImage and references the image data. @@ -140,7 +119,7 @@ CGImageRef QImage::toCGImage() const const bool shouldInterpolate = false; return CGImageCreate(width(), height(), bitsPerComponent, bitsPerPixel, - this->bytesPerLine(), colorSpace, cgflags, dataProvider, + this->bytesPerLine(), colorSpace, bitmapInfo, dataProvider, decode, shouldInterpolate, kCGRenderingIntentDefault); } diff --git a/src/gui/painting/qcoregraphics.mm b/src/gui/painting/qcoregraphics.mm index d45da14767..53066687d3 100644 --- a/src/gui/painting/qcoregraphics.mm +++ b/src/gui/painting/qcoregraphics.mm @@ -51,6 +51,33 @@ QT_BEGIN_NAMESPACE // ---------------------- Images ---------------------- +CGBitmapInfo qt_mac_bitmapInfoForImage(const QImage &image) +{ + CGBitmapInfo bitmapInfo = kCGImageAlphaNone; + switch (image.format()) { + case QImage::Format_ARGB32: + bitmapInfo = kCGImageAlphaFirst | kCGBitmapByteOrder32Host; + break; + case QImage::Format_RGB32: + bitmapInfo = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host; + break; + case QImage::Format_RGBA8888_Premultiplied: + bitmapInfo = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big; + break; + case QImage::Format_RGBA8888: + bitmapInfo = kCGImageAlphaLast | kCGBitmapByteOrder32Big; + break; + case QImage::Format_RGBX8888: + bitmapInfo = kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big; + break; + case QImage::Format_ARGB32_Premultiplied: + bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host; + break; + default: break; + } + return bitmapInfo; +} + CGImageRef qt_mac_toCGImage(const QImage &inImage) { CGImageRef cgImage = inImage.toCGImage(); @@ -362,13 +389,10 @@ QMacCGContext::QMacCGContext(QPaintDevice *paintDevice) : context(0) if (!image) return; // Context type not supported. - CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); - uint flags = kCGImageAlphaPremultipliedFirst; - flags |= kCGBitmapByteOrder32Host; + QCFType colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); + context = CGBitmapContextCreate(image->bits(), image->width(), image->height(), 8, + image->bytesPerLine(), colorSpace, qt_mac_bitmapInfoForImage(*image)); - context = CGBitmapContextCreate(image->bits(), image->width(), image->height(), - 8, image->bytesPerLine(), colorSpace, flags); - CFRelease(colorSpace); CGContextTranslateCTM(context, 0, image->height()); const qreal devicePixelRatio = paintDevice->devicePixelRatioF(); CGContextScaleCTM(context, devicePixelRatio, devicePixelRatio); @@ -396,16 +420,10 @@ QMacCGContext::QMacCGContext(QPainter *painter) : context(0) devType == QInternal::Pixmap || devType == QInternal::Image)) { - CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); - uint flags = kCGImageAlphaPremultipliedFirst; -#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version - flags |= kCGBitmapByteOrder32Host; -#endif const QImage *image = static_cast(paintEngine->paintDevice()); - - context = CGBitmapContextCreate((void *)image->bits(), image->width(), image->height(), - 8, image->bytesPerLine(), colorSpace, flags); - CFRelease(colorSpace); + QCFType colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); + context = CGBitmapContextCreate((void *)image->bits(), image->width(), image->height(), 8, + image->bytesPerLine(), colorSpace, qt_mac_bitmapInfoForImage(*image)); // Invert y axis CGContextTranslateCTM(context, 0, image->height()); diff --git a/src/gui/painting/qcoregraphics_p.h b/src/gui/painting/qcoregraphics_p.h index de721c94aa..868c2b08b5 100644 --- a/src/gui/painting/qcoregraphics_p.h +++ b/src/gui/painting/qcoregraphics_p.h @@ -64,6 +64,8 @@ QT_BEGIN_NAMESPACE +Q_GUI_EXPORT CGBitmapInfo qt_mac_bitmapInfoForImage(const QImage &image); + #ifdef HAVE_APPKIT Q_GUI_EXPORT NSImage *qt_mac_create_nsimage(const QPixmap &pm); Q_GUI_EXPORT NSImage *qt_mac_create_nsimage(const QIcon &icon, int defaultSize = 0); diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index fbd2f81b19..e4ee0c0ac4 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -45,7 +45,7 @@ #include #endif #include - +#include #include #include @@ -647,14 +647,9 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition im.fill(0); // Faster than Qt::black QCFType colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); - uint cgflags = isColorGlyph ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst; -#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version - cgflags |= kCGBitmapByteOrder32Host; -#endif - QCFType ctx = CGBitmapContextCreate(im.bits(), im.width(), im.height(), 8, im.bytesPerLine(), colorspace, - cgflags); + qt_mac_bitmapInfoForImage(im)); Q_ASSERT(ctx); CGContextSetFontSize(ctx, fontDef.pixelSize); const bool antialias = (aa || fontDef.pointSize > antialiasingThreshold) && !(fontDef.styleStrategy & QFont::NoAntialias); From 1f998e040eb7202691f4a4eb5fb77499247b2aab Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 27 Nov 2018 09:39:56 +0100 Subject: [PATCH 0452/1650] Fix crash in qmake parsing The read from a QHash needs to be protected too if other threads are writing. sync-up with qtc, no actual effect on qmake itself. Fixes: QTCREATORBUG-21416 Change-Id: I75e5634e11b10056d6dbb6fdceef482ca2222ca1 Reviewed-by: Allan Sandfeld Jensen (cherry picked from qtcreator/5f79b5d2e5e33321cdcd00362f0d6d9442a73ec2) Reviewed-by: Oswald Buddenhagen --- qmake/library/qmakevfs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qmake/library/qmakevfs.cpp b/qmake/library/qmakevfs.cpp index 9fd6ae470c..1f77595535 100644 --- a/qmake/library/qmakevfs.cpp +++ b/qmake/library/qmakevfs.cpp @@ -109,10 +109,10 @@ int QMakeVfs::idForFileName(const QString &fn, VfsFlags flags) return id; } #endif - if (!(flags & VfsAccessedOnly)) { #ifdef PROPARSER_THREAD_SAFE - QMutexLocker locker(&s_mutex); + QMutexLocker locker(&s_mutex); #endif + if (!(flags & VfsAccessedOnly)) { int &id = s_fileIdMap[fn]; if (!id) { id = ++s_fileIdCounter; From 2a494875b8f3d50046d35fb21988c288fcfa1dc7 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Wed, 28 Nov 2018 19:20:52 +0100 Subject: [PATCH 0453/1650] OpenSSL: also try the "1.0.2" soname MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Turns out that also Debian patches OpenSSL 1.0, changing its soname to "1.0.2". Therefore, try also to load that one. Amends 2708c6c11d685ab25c12d558961d924c9a4533d2. Task-number: QTBUG-68156 Change-Id: I37cc060e90422779a6c29a324ab900f0fb99cfa7 Reviewed-by: Lisandro Damián Nicanor Pérez Meyer Reviewed-by: Timur Pocheptsov --- .../ssl/qsslsocket_openssl_symbols.cpp | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index 59c93677dd..2f8095cd81 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -771,7 +771,7 @@ static QPair loadOpenSsl() // reason, we will search a few common paths (see findAllLibSsl() above) in hopes // we find one that works. // - // If that fails, for OpenSSL 1.0 we also try a fallback -- just look up + // If that fails, for OpenSSL 1.0 we also try some fallbacks -- look up // libssl.so with a hardcoded soname. The reason is QTBUG-68156: the binary // builds of Qt happen (at the time of this writing) on RHEL machines, // which change SHLIB_VERSION_NUMBER to a non-portable string. When running @@ -804,14 +804,23 @@ static QPair loadOpenSsl() } #if !QT_CONFIG(opensslv11) - // first-and-half attempt: for OpenSSL 1.0 try to load an hardcoded soname. - libssl->setFileNameAndVersion(QLatin1String("ssl"), QLatin1String("1.0.0")); - libcrypto->setFileNameAndVersion(QLatin1String("crypto"), QLatin1String("1.0.0")); - if (libcrypto->load() && libssl->load()) { - return pair; - } else { - libssl->unload(); - libcrypto->unload(); + // first-and-half attempts: for OpenSSL 1.0 try to load some hardcoded sonames: + // - "1.0.0" is the official upstream one + // - "1.0.2" is found on some distributions (e.g. Debian) that patch OpenSSL + static const QLatin1String fallbackSonames[] = { + QLatin1String("1.0.0"), + QLatin1String("1.0.2") + }; + + for (auto fallbackSoname : fallbackSonames) { + libssl->setFileNameAndVersion(QLatin1String("ssl"), fallbackSoname); + libcrypto->setFileNameAndVersion(QLatin1String("crypto"), fallbackSoname); + if (libcrypto->load() && libssl->load()) { + return pair; + } else { + libssl->unload(); + libcrypto->unload(); + } } #endif #endif From d4e3442fdbb98b5c635448031ff9958819a46bc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 25 Nov 2018 15:59:04 +0100 Subject: [PATCH 0454/1650] CoreText: Modernize font smoothing and antialiasing threshold detection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The way macOS does font smoothing has changed in Mojave, and we need to take both this new algorithm into account, as well as support users who set legacy preferences to revert back to subpixel font smoothing. As a followup to this patch we will tweak some of the existing logic to take the new font smoothing algorithm into account, so this is just a first step. Change-Id: If37014c18515f406b8bb8194c9df7a75c2eb10fc Reviewed-by: Simon Hausmann Reviewed-by: Tor Arne Vestbø Reviewed-by: Allan Sandfeld Jensen --- .../mac/qcoretextfontdatabase.mm | 65 --------- .../fontdatabases/mac/qfontengine_coretext.mm | 125 +++++++++++++++++- .../mac/qfontengine_coretext_p.h | 15 ++- .../platforms/cocoa/qpaintengine_mac.mm | 2 +- 4 files changed, 132 insertions(+), 75 deletions(-) diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index 3718ebdda6..ba23271e55 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -117,71 +117,6 @@ static NSInteger languageMapSort(id obj1, id obj2, void *context) QCoreTextFontDatabase::QCoreTextFontDatabase() : m_hasPopulatedAliases(false) { -#ifdef Q_OS_MACX - /* - font_smoothing = 0 means no smoothing, while 1-3 means subpixel - antialiasing with different hinting styles (but we don't care about the - exact value, only if subpixel rendering is available or not) - */ - int font_smoothing = 0; - -#if QT_CONFIG(settings) - QSettings appleSettings(QLatin1String("apple.com")); - QVariant appleValue = appleSettings.value(QLatin1String("AppleAntiAliasingThreshold")); - if (appleValue.isValid()) - QCoreTextFontEngine::antialiasingThreshold = appleValue.toInt(); - - appleValue = appleSettings.value(QLatin1String("AppleFontSmoothing")); - if (appleValue.isValid()) { - font_smoothing = appleValue.toInt(); - } else -#endif // settings - { - // non-Apple displays do not provide enough information about subpixel rendering so - // draw text with cocoa and compare pixel colors to see if subpixel rendering is enabled - int w = 10; - int h = 10; - NSRect rect = NSMakeRect(0.0, 0.0, w, h); - NSImage *fontImage = [[NSImage alloc] initWithSize:NSMakeSize(w, h)]; - - [fontImage lockFocus]; - - [[NSColor whiteColor] setFill]; - NSRectFill(rect); - - NSString *str = @"X\\"; - NSFont *font = [NSFont fontWithName:@"Helvetica" size:10.0]; - NSMutableDictionary *attrs = [NSMutableDictionary dictionary]; - [attrs setObject:font forKey:NSFontAttributeName]; - [attrs setObject:[NSColor blackColor] forKey:NSForegroundColorAttributeName]; - - [str drawInRect:rect withAttributes:attrs]; - - NSBitmapImageRep *nsBitmapImage = [[NSBitmapImageRep alloc] initWithFocusedViewRect:rect]; - - [fontImage unlockFocus]; - - float red, green, blue; - for (int x = 0; x < w; x++) { - for (int y = 0; y < h; y++) { - NSColor *pixelColor = [nsBitmapImage colorAtX:x y:y]; - red = [pixelColor redComponent]; - green = [pixelColor greenComponent]; - blue = [pixelColor blueComponent]; - if (red != green || red != blue) - font_smoothing = 1; - } - } - - [nsBitmapImage release]; - [fontImage release]; - } - QCoreTextFontEngine::defaultGlyphFormat = (font_smoothing > 0 - ? QFontEngine::Format_A32 - : QFontEngine::Format_A8); -#else - QCoreTextFontEngine::defaultGlyphFormat = QFontEngine::Format_A8; -#endif } QCoreTextFontDatabase::~QCoreTextFontDatabase() diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index e4ee0c0ac4..d939ee1b24 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -85,6 +85,8 @@ QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcQpaFonts, "qt.qpa.fonts") + static float SYNTHETIC_ITALIC_SKEW = std::tan(14.f * std::acos(0.f) / 90.f); bool QCoreTextFontEngine::ct_getSfntTable(void *user_data, uint tag, uchar *buffer, uint *length) @@ -133,9 +135,6 @@ QFont::Weight QCoreTextFontEngine::qtWeightFromCFWeight(float value) return ret; } -int QCoreTextFontEngine::antialiasingThreshold = 0; -QFontEngine::GlyphFormat QCoreTextFontEngine::defaultGlyphFormat = QFontEngine::Format_A32; - CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef) { CGAffineTransform transform = CGAffineTransformIdentity; @@ -236,8 +235,10 @@ void QCoreTextFontEngine::init() if (traits & kCTFontColorGlyphsTrait) glyphFormat = QFontEngine::Format_ARGB; + else if (fontSmoothing() == FontSmoothing::Subpixel) + glyphFormat = QFontEngine::Format_A32; else - glyphFormat = defaultGlyphFormat; + glyphFormat = QFontEngine::Format_A8; if (traits & kCTFontItalicTrait) fontDef.style = QFont::StyleItalic; @@ -520,7 +521,7 @@ static void convertCGPathToQPainterPath(void *info, const CGPathElement *element myInfo->path->closeSubpath(); break; default: - qDebug() << "Unhandled path transform type: " << element->type; + qCWarning(lcQpaFonts) << "Unhandled path transform type: " << element->type; } } @@ -608,6 +609,118 @@ glyph_metrics_t QCoreTextFontEngine::alphaMapBoundingBox(glyph_t glyph, QFixed s return br; } +int QCoreTextFontEngine::antialiasingThreshold() +{ + static const int antialiasingThreshold = [] { + auto defaults = [NSUserDefaults standardUserDefaults]; + int threshold = [defaults integerForKey:@"AppleAntiAliasingThreshold"]; + qCDebug(lcQpaFonts) << "Resolved antialiasing threshold. Defaults =" + << [[defaults dictionaryRepresentation] dictionaryWithValuesForKeys:@[ + @"AppleAntiAliasingThreshold" + ]] << "Result =" << threshold; + return threshold; + }(); + return antialiasingThreshold; +} + +/* + Apple has gone through many iterations of its font smoothing algorithms, + and there are many ways to enable or disable certain aspects of it. As + keeping up with all the different toggles and behavior differences between + macOS versions is tricky, we resort to rendering a single glyph in a few + configurations, picking up the font smoothing algorithm from the observed + result. + + The possible values are: + + - Disabled: No font smoothing is applied. + + Possibly triggered by the user unchecking the "Use font smoothing when + available" checkbox in the system preferences or setting AppleFontSmoothing + to 0. Also controlled by the CGContextSetAllowsFontSmoothing() API, + which gets its default from the settings above. This API overrides + the more granular CGContextSetShouldSmoothFonts(), which we use to + enable (request) or disable font smoothing. + + Note that this does not exclude normal antialiasing, controlled by + the CGContextSetShouldAntialias() API. + + - Subpixel: Font smoothing is applied, and affects subpixels. + + This was the default mode on macOS versions prior to 10.14 (Mojave). + The font dilation (stem darkening) parameters were controlled by the + AppleFontSmoothing setting, ranging from 1 to 3 (light to strong). + + On Mojave it is no longer supported, but can be triggered by a legacy + override (CGFontRenderingFontSmoothingDisabled=NO), so we need to + still account for it, otherwise users will have a bad time. + + - Grayscale: Font smoothing is applied, but does not affect subpixels. + + This is the default mode on macOS 10.14 (Mojave). The font dilation + (stem darkening) parameters are not affected by the AppleFontSmoothing + setting, but are instead computed based on the fill color used when + drawing the glyphs (white fill gives a lighter dilation than black + fill). This affects how we build our glyph cache, since we produce + alpha maps by drawing white on black. +*/ +QCoreTextFontEngine::FontSmoothing QCoreTextFontEngine::fontSmoothing() +{ + static const FontSmoothing cachedFontSmoothing = [] { + static const int kSize = 10; + QCFType font = CTFontCreateWithName(CFSTR("Helvetica"), kSize, nullptr); + + UniChar character('X'); CGGlyph glyph; + CTFontGetGlyphsForCharacters(font, &character, &glyph, 1); + + auto drawGlyph = [&](bool smooth) -> QImage { + QImage image(kSize, kSize, QImage::Format_RGB32); + image.fill(0); + + QMacCGContext ctx(&image); + CGContextSetTextDrawingMode(ctx, kCGTextFill); + CGContextSetGrayFillColor(ctx, 1, 1); + + // Will be ignored if CGContextSetAllowsFontSmoothing() has been + // set to false by CoreGraphics based on user defaults. + CGContextSetShouldSmoothFonts(ctx, smooth); + + CTFontDrawGlyphs(font, &glyph, &CGPointZero, 1, ctx); + return image; + }; + + QImage nonSmoothed = drawGlyph(false); + QImage smoothed = drawGlyph(true); + + FontSmoothing fontSmoothing = FontSmoothing::Disabled; + [&] { + for (int x = 0; x < kSize; ++x) { + for (int y = 0; y < kSize; ++y) { + QRgb sp = smoothed.pixel(x, y); + if (qRed(sp) != qGreen(sp) || qRed(sp) != qBlue(sp)) { + fontSmoothing = FontSmoothing::Subpixel; + return; + } + + if (sp != nonSmoothed.pixel(x, y)) + fontSmoothing = FontSmoothing::Grayscale; + } + } + }(); + + auto defaults = [NSUserDefaults standardUserDefaults]; + qCDebug(lcQpaFonts) << "Resolved font smoothing algorithm. Defaults =" + << [[defaults dictionaryRepresentation] dictionaryWithValuesForKeys:@[ + @"AppleFontSmoothing", + @"CGFontRenderingFontSmoothingDisabled" + ]] << "Result =" << fontSmoothing; + + return fontSmoothing; + }(); + + return cachedFontSmoothing; +} + bool QCoreTextFontEngine::expectsGammaCorrectedBlending() const { // Only works well when font-smoothing is enabled @@ -652,7 +765,7 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition qt_mac_bitmapInfoForImage(im)); Q_ASSERT(ctx); CGContextSetFontSize(ctx, fontDef.pixelSize); - const bool antialias = (aa || fontDef.pointSize > antialiasingThreshold) && !(fontDef.styleStrategy & QFont::NoAntialias); + const bool antialias = (aa || fontDef.pointSize > antialiasingThreshold()) && !(fontDef.styleStrategy & QFont::NoAntialias); CGContextSetShouldAntialias(ctx, antialias); const bool smoothing = antialias && !(fontDef.styleStrategy & QFont::NoSubpixelAntialias); CGContextSetShouldSmoothFonts(ctx, smoothing); diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h index 7ed2faff8e..2ce46a4706 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h @@ -53,6 +53,7 @@ #include #include +#include #ifdef Q_OS_OSX #include @@ -63,8 +64,12 @@ QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcQpaFonts) + class QCoreTextFontEngine : public QFontEngine { + Q_GADGET + public: QCoreTextFontEngine(CTFontRef font, const QFontDef &def); QCoreTextFontEngine(CGFontRef font, const QFontDef &def); @@ -118,13 +123,17 @@ public: QFontEngine::Properties properties() const override; + enum FontSmoothing { Disabled, Subpixel, Grayscale }; + Q_ENUM(FontSmoothing); + + static FontSmoothing fontSmoothing(); + static int antialiasingThreshold(); + static bool ct_getSfntTable(void *user_data, uint tag, uchar *buffer, uint *length); static QFont::Weight qtWeightFromCFWeight(float value); - static int antialiasingThreshold; - static QFontEngine::GlyphFormat defaultGlyphFormat; - static QCoreTextFontEngine *create(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference); + protected: QCoreTextFontEngine(const QFontDef &def); void init(); diff --git a/src/plugins/platforms/cocoa/qpaintengine_mac.mm b/src/plugins/platforms/cocoa/qpaintengine_mac.mm index 5c880b1cad..69e7a92234 100644 --- a/src/plugins/platforms/cocoa/qpaintengine_mac.mm +++ b/src/plugins/platforms/cocoa/qpaintengine_mac.mm @@ -914,7 +914,7 @@ void QCoreGraphicsPaintEngine::drawTextItem(const QPointF &pos, const QTextItem QFontEngine *fe = ti.fontEngine; const bool textAA = ((state->renderHints() & QPainter::TextAntialiasing) - && (fe->fontDef.pointSize > QCoreTextFontEngine::antialiasingThreshold) + && (fe->fontDef.pointSize > QCoreTextFontEngine::antialiasingThreshold()) && !(fe->fontDef.styleStrategy & QFont::NoAntialias)); const bool lineAA = state->renderHints() & QPainter::Antialiasing; if (textAA != lineAA) From 6b93b01ad6dfb5b0b2f067462690bdf14668f96c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 25 Nov 2018 16:22:30 +0100 Subject: [PATCH 0455/1650] CoreText: Add helper function to determine if a font has color glyphs Makes for clearer code than looking at the glyph format. Change-Id: Id6dd2a7851aac2a42cc27d9e2fb408ce9a5345d3 Reviewed-by: Simon Hausmann Reviewed-by: Allan Sandfeld Jensen --- .../fontdatabases/mac/qfontengine_coretext.mm | 16 ++++++++++------ .../fontdatabases/mac/qfontengine_coretext_p.h | 1 + 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index d939ee1b24..91d3d811b5 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -433,6 +433,11 @@ qreal QCoreTextFontEngine::maxCharWidth() const return bb.xoff.toReal(); } +bool QCoreTextFontEngine::hasColorGlyphs() const +{ + return glyphFormat == QFontEngine::Format_ARGB; +} + void QCoreTextFontEngine::draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight) { QVarLengthArray positions; @@ -529,7 +534,7 @@ static void convertCGPathToQPainterPath(void *info, const CGPathElement *element void QCoreTextFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nGlyphs, QPainterPath *path, QTextItem::RenderFlags) { - if (glyphFormat == QFontEngine::Format_ARGB) + if (hasColorGlyphs()) return; // We can't convert color-glyphs to path CGAffineTransform cgMatrix = CGAffineTransformIdentity; @@ -731,8 +736,7 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition { glyph_metrics_t br = alphaMapBoundingBox(glyph, subPixelPosition, matrix, glyphFormat); - bool isColorGlyph = glyphFormat == QFontEngine::Format_ARGB; - QImage::Format imageFormat = isColorGlyph ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; + QImage::Format imageFormat = hasColorGlyphs() ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; QImage im(br.width.ceil().toInt(), br.height.ceil().toInt(), imageFormat); if (!im.width() || !im.height()) return im; @@ -751,7 +755,7 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition if (!qt_mac_applicationIsInDarkMode()) glyphColor = CGColorGetConstantColor(kCGColorBlack); } - const bool blackOnWhiteGlyphs = !isColorGlyph + const bool blackOnWhiteGlyphs = !hasColorGlyphs() && CGColorEqualToColor(glyphColor, CGColorGetConstantColor(kCGColorBlack)); if (blackOnWhiteGlyphs) im.fill(Qt::white); @@ -775,7 +779,7 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition if (synthesisFlags & QFontEngine::SynthesizedItalic) cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, SYNTHETIC_ITALIC_SKEW, 1, 0, 0)); - if (!isColorGlyph) // CTFontDrawGlyphs incorporates the font's matrix already + if (!hasColorGlyphs()) // CTFontDrawGlyphs incorporates the font's matrix already cgMatrix = CGAffineTransformConcat(cgMatrix, transform); if (matrix.isScaling()) @@ -785,7 +789,7 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition qreal pos_x = -br.x.truncate() + subPixelPosition.toReal(); qreal pos_y = im.height() + br.y.toReal(); - if (!isColorGlyph) { + if (!hasColorGlyphs()) { CGContextSetTextMatrix(ctx, cgMatrix); #if defined(Q_OS_MACOS) CGContextSetFillColorWithColor(ctx, glyphColor); diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h index 2ce46a4706..13505be0aa 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h @@ -139,6 +139,7 @@ protected: void init(); QImage imageForGlyph(glyph_t glyph, QFixed subPixelPosition, bool colorful, const QTransform &m); void loadAdvancesForGlyphs(QVarLengthArray &cgGlyphs, QGlyphLayout *glyphs) const; + bool hasColorGlyphs() const; QCFType ctfont; QCFType cgFont; From ae1f749e9e25495e4ae1658289584adb74d0b076 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 25 Nov 2018 21:51:21 +0100 Subject: [PATCH 0456/1650] CoreText: Rename argument to imageForGlyph to better reflect how it's used The 'aa' argument doesn't unconditionally enabled antialiasing, it just overrides the check that the pointSize is larger than the antialiasing threshold. If the styleStrategy has QFont::NoAntialias we still end up without antialiasing. Change-Id: I7130e7c68d883c2443756242e96790264f583b0f Reviewed-by: Simon Hausmann Reviewed-by: Allan Sandfeld Jensen --- .../fontdatabases/mac/qfontengine_coretext.mm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index 91d3d811b5..b323496038 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -732,7 +732,8 @@ bool QCoreTextFontEngine::expectsGammaCorrectedBlending() const return (glyphFormat == Format_A32) && !(fontDef.styleStrategy & (QFont::NoAntialias | QFont::NoSubpixelAntialias)); } -QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, bool aa, const QTransform &matrix) +QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, + bool overrideAntialiasingThreshold, const QTransform &matrix) { glyph_metrics_t br = alphaMapBoundingBox(glyph, subPixelPosition, matrix, glyphFormat); @@ -769,7 +770,8 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition qt_mac_bitmapInfoForImage(im)); Q_ASSERT(ctx); CGContextSetFontSize(ctx, fontDef.pixelSize); - const bool antialias = (aa || fontDef.pointSize > antialiasingThreshold()) && !(fontDef.styleStrategy & QFont::NoAntialias); + const bool antialias = (overrideAntialiasingThreshold || fontDef.pointSize > antialiasingThreshold()) + && !(fontDef.styleStrategy & QFont::NoAntialias); CGContextSetShouldAntialias(ctx, antialias); const bool smoothing = antialias && !(fontDef.styleStrategy & QFont::NoSubpixelAntialias); CGContextSetShouldSmoothFonts(ctx, smoothing); From 2a1c368c873afe9b222c759d4348b93beafca8ea Mon Sep 17 00:00:00 2001 From: Mikhail Svetkin Date: Fri, 16 Nov 2018 10:32:39 +0100 Subject: [PATCH 0457/1650] xcb: Use std::move and pass argument by rvalue reference It will avoid a creation of temporary object and avoid copying. Change-Id: Ifae5f6f9e36bcb07f4bacc31f151f8adcfa621a3 Reviewed-by: Anton Kudryavtsev Reviewed-by: Gatis Paeglis --- src/plugins/platforms/xcb/qxcbconnection_screens.cpp | 2 +- src/plugins/platforms/xcb/qxcbscreen.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection_screens.cpp b/src/plugins/platforms/xcb/qxcbconnection_screens.cpp index fe9e0be86d..9aba996bb9 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_screens.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_screens.cpp @@ -384,7 +384,7 @@ void QXcbConnection::initializeScreens() } siblings << screen; } - virtualDesktop->setScreens(siblings); + virtualDesktop->setScreens(std::move(siblings)); xcb_screen_next(&it); ++xcbScreenNumber; } // for each xcb screen diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h index 7f22a8e4db..be6c45e415 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.h +++ b/src/plugins/platforms/xcb/qxcbscreen.h @@ -79,7 +79,7 @@ public: QXcbScreen *screenAt(const QPoint &pos) const; QList screens() const { return m_screens; } - void setScreens(QList sl) { m_screens = sl; } + void setScreens(QList &&sl) { m_screens = std::move(sl); } void removeScreen(QPlatformScreen *s) { m_screens.removeOne(s); } void addScreen(QPlatformScreen *s); void setPrimaryScreen(QPlatformScreen *s); From 2e86b652b789374ed9e0ddb15b0f60dd24b99fe8 Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Wed, 19 Sep 2018 13:56:50 +0200 Subject: [PATCH 0458/1650] Fix crash in QSimpleDrag when no platform window No need to return top level window if it was not created. It means no platform resources have been allocated. Events might not be delivered if the wrong window is returned. Fixes: QTBUG-70544 Change-Id: I43462974f70871470f7b7490dc2b3c08846f77b1 Reviewed-by: Richard Moe Gustavsen --- src/gui/kernel/qsimpledrag.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp index 2611dc8580..9aab332ef5 100644 --- a/src/gui/kernel/qsimpledrag.cpp +++ b/src/gui/kernel/qsimpledrag.cpp @@ -74,7 +74,7 @@ static QWindow* topLevelAt(const QPoint &pos) QWindowList list = QGuiApplication::topLevelWindows(); for (int i = list.count()-1; i >= 0; --i) { QWindow *w = list.at(i); - if (w->isVisible() && w->geometry().contains(pos) && !qobject_cast(w)) + if (w->isVisible() && w->handle() && w->geometry().contains(pos) && !qobject_cast(w)) return w; } return 0; From 3944f45c4d74b0389dc2246d1292790a9591ab82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 27 Nov 2018 17:13:38 +0100 Subject: [PATCH 0459/1650] CoreText: Remove handling of the AppleAntiAliasingThreshold user default The setting is not relevant for modern macOS applications, and none of the applications shipped with macOS today are affected by it. The only code path in macOS that picks it up is +[NSFont initialize] in the UIFoundation framework, storing it for later so that -[NSFont screenFont] and -[NSFont screenFontWithRenderingMode:] can use it, but these APIs are deprecated and we don't use them in Qt. Other NSFont code paths will not hit these APIs unless screen font substitution is enabled, something it hasn't been since OSX 10.7. https://preview.tinyurl.com/yctpfnqp Removing handling of this setting allows us to simplify the reasoning for whether or not antialiasing and font smoothing is enabled for a given engine. Change-Id: Ie2809052a1a0815d9bddedd4a6236eb6c898f993 Reviewed-by: Lars Knoll Reviewed-by: Allan Sandfeld Jensen --- .../fontdatabases/mac/qfontengine_coretext.mm | 26 ++++--------------- .../mac/qfontengine_coretext_p.h | 3 +-- .../platforms/cocoa/qpaintengine_mac.mm | 1 - 3 files changed, 6 insertions(+), 24 deletions(-) diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index b323496038..7a26416868 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -614,20 +614,6 @@ glyph_metrics_t QCoreTextFontEngine::alphaMapBoundingBox(glyph_t glyph, QFixed s return br; } -int QCoreTextFontEngine::antialiasingThreshold() -{ - static const int antialiasingThreshold = [] { - auto defaults = [NSUserDefaults standardUserDefaults]; - int threshold = [defaults integerForKey:@"AppleAntiAliasingThreshold"]; - qCDebug(lcQpaFonts) << "Resolved antialiasing threshold. Defaults =" - << [[defaults dictionaryRepresentation] dictionaryWithValuesForKeys:@[ - @"AppleAntiAliasingThreshold" - ]] << "Result =" << threshold; - return threshold; - }(); - return antialiasingThreshold; -} - /* Apple has gone through many iterations of its font smoothing algorithms, and there are many ways to enable or disable certain aspects of it. As @@ -732,8 +718,7 @@ bool QCoreTextFontEngine::expectsGammaCorrectedBlending() const return (glyphFormat == Format_A32) && !(fontDef.styleStrategy & (QFont::NoAntialias | QFont::NoSubpixelAntialias)); } -QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, - bool overrideAntialiasingThreshold, const QTransform &matrix) +QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &matrix) { glyph_metrics_t br = alphaMapBoundingBox(glyph, subPixelPosition, matrix, glyphFormat); @@ -770,8 +755,7 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition qt_mac_bitmapInfoForImage(im)); Q_ASSERT(ctx); CGContextSetFontSize(ctx, fontDef.pixelSize); - const bool antialias = (overrideAntialiasingThreshold || fontDef.pointSize > antialiasingThreshold()) - && !(fontDef.styleStrategy & QFont::NoAntialias); + const bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias); CGContextSetShouldAntialias(ctx, antialias); const bool smoothing = antialias && !(fontDef.styleStrategy & QFont::NoSubpixelAntialias); CGContextSetShouldSmoothFonts(ctx, smoothing); @@ -837,7 +821,7 @@ QImage QCoreTextFontEngine::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosit if (x.type() > QTransform::TxScale) return QFontEngine::alphaMapForGlyph(glyph, subPixelPosition, x); - QImage im = imageForGlyph(glyph, subPixelPosition, false, x); + QImage im = imageForGlyph(glyph, subPixelPosition, x); QImage alphaMap(im.width(), im.height(), QImage::Format_Alpha8); @@ -859,7 +843,7 @@ QImage QCoreTextFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed subPixelPo if (x.type() > QTransform::TxScale) return QFontEngine::alphaRGBMapForGlyph(glyph, subPixelPosition, x); - QImage im = imageForGlyph(glyph, subPixelPosition, true, x); + QImage im = imageForGlyph(glyph, subPixelPosition, x); qGamma_correct_back_to_linear_cs(&im); return im; } @@ -869,7 +853,7 @@ QImage QCoreTextFontEngine::bitmapForGlyph(glyph_t glyph, QFixed subPixelPositio if (t.type() > QTransform::TxScale) return QFontEngine::bitmapForGlyph(glyph, subPixelPosition, t); - return imageForGlyph(glyph, subPixelPosition, true, t); + return imageForGlyph(glyph, subPixelPosition, t); } void QCoreTextFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags flags) const diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h index 13505be0aa..0ff428084f 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h @@ -127,7 +127,6 @@ public: Q_ENUM(FontSmoothing); static FontSmoothing fontSmoothing(); - static int antialiasingThreshold(); static bool ct_getSfntTable(void *user_data, uint tag, uchar *buffer, uint *length); static QFont::Weight qtWeightFromCFWeight(float value); @@ -137,7 +136,7 @@ public: protected: QCoreTextFontEngine(const QFontDef &def); void init(); - QImage imageForGlyph(glyph_t glyph, QFixed subPixelPosition, bool colorful, const QTransform &m); + QImage imageForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &m); void loadAdvancesForGlyphs(QVarLengthArray &cgGlyphs, QGlyphLayout *glyphs) const; bool hasColorGlyphs() const; diff --git a/src/plugins/platforms/cocoa/qpaintengine_mac.mm b/src/plugins/platforms/cocoa/qpaintengine_mac.mm index 69e7a92234..3677877538 100644 --- a/src/plugins/platforms/cocoa/qpaintengine_mac.mm +++ b/src/plugins/platforms/cocoa/qpaintengine_mac.mm @@ -914,7 +914,6 @@ void QCoreGraphicsPaintEngine::drawTextItem(const QPointF &pos, const QTextItem QFontEngine *fe = ti.fontEngine; const bool textAA = ((state->renderHints() & QPainter::TextAntialiasing) - && (fe->fontDef.pointSize > QCoreTextFontEngine::antialiasingThreshold()) && !(fe->fontDef.styleStrategy & QFont::NoAntialias)); const bool lineAA = state->renderHints() & QPainter::Antialiasing; if (textAA != lineAA) From ec254d2555083ff258db9675fa43ad23888f0685 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 27 Nov 2018 18:52:29 +0100 Subject: [PATCH 0460/1650] CoreText: Add font antialiasing and smoothing helper functions The font smoothing helper in particular now takes into account whether or not we're dealing with color glyphs, in which case we shouldn't (or don't need to) smooth, and also makes sure the QFont::NoSubpixelAntialias style strategy doesn't affect font smoothing when we're dealing with non-subpixel-antialiased font smoothing, as on macOS 10.14. Change-Id: Ibd477158629402c55cafec31576b6d9901d184cf Reviewed-by: Lars Knoll Reviewed-by: Allan Sandfeld Jensen --- .../fontdatabases/mac/qfontengine_coretext.mm | 29 ++++++++++++++++--- .../mac/qfontengine_coretext_p.h | 2 ++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index 7a26416868..6c2ffba92e 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -712,6 +712,28 @@ QCoreTextFontEngine::FontSmoothing QCoreTextFontEngine::fontSmoothing() return cachedFontSmoothing; } +bool QCoreTextFontEngine::shouldAntialias() const +{ + return !(fontDef.styleStrategy & QFont::NoAntialias); +} + +bool QCoreTextFontEngine::shouldSmoothFont() const +{ + if (hasColorGlyphs()) + return false; + + if (!shouldAntialias()) + return false; + + switch (fontSmoothing()) { + case Disabled: return false; + case Subpixel: return !(fontDef.styleStrategy & QFont::NoSubpixelAntialias); + case Grayscale: return true; + } + + Q_UNREACHABLE(); +} + bool QCoreTextFontEngine::expectsGammaCorrectedBlending() const { // Only works well when font-smoothing is enabled @@ -755,10 +777,9 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition qt_mac_bitmapInfoForImage(im)); Q_ASSERT(ctx); CGContextSetFontSize(ctx, fontDef.pixelSize); - const bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias); - CGContextSetShouldAntialias(ctx, antialias); - const bool smoothing = antialias && !(fontDef.styleStrategy & QFont::NoSubpixelAntialias); - CGContextSetShouldSmoothFonts(ctx, smoothing); + + CGContextSetShouldAntialias(ctx, shouldAntialias()); + CGContextSetShouldSmoothFonts(ctx, shouldSmoothFont()); CGAffineTransform cgMatrix = CGAffineTransformIdentity; diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h index 0ff428084f..28810f13bc 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h @@ -139,6 +139,8 @@ protected: QImage imageForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &m); void loadAdvancesForGlyphs(QVarLengthArray &cgGlyphs, QGlyphLayout *glyphs) const; bool hasColorGlyphs() const; + bool shouldAntialias() const; + bool shouldSmoothFont() const; QCFType ctfont; QCFType cgFont; From 0cf5648ce6df8b60090a14f738dd5d66643a0532 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 28 Nov 2018 12:12:07 +0100 Subject: [PATCH 0461/1650] CoreText: Store glyphs in linear RGB when needed by blending algorithm Instead of tying the linear-conversion to a specific function, we move it to imageForGlyph and base it on the premise for needing it. Change-Id: Ib8fc79ad419ef703abcb82785ac15d4c75fb98e6 Reviewed-by: Lars Knoll Reviewed-by: Allan Sandfeld Jensen --- .../fontdatabases/mac/qfontengine_coretext.mm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index 6c2ffba92e..271f07e0c1 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -824,6 +824,9 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition CTFontDrawGlyphs(ctfont, &cgGlyph, &CGPointZero, 1, ctx); } + if (expectsGammaCorrectedBlending()) + qGamma_correct_back_to_linear_cs(&im); + #if defined(Q_OS_MACOS) if (blackOnWhiteGlyphs) im.invertPixels(); @@ -864,9 +867,7 @@ QImage QCoreTextFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed subPixelPo if (x.type() > QTransform::TxScale) return QFontEngine::alphaRGBMapForGlyph(glyph, subPixelPosition, x); - QImage im = imageForGlyph(glyph, subPixelPosition, x); - qGamma_correct_back_to_linear_cs(&im); - return im; + return imageForGlyph(glyph, subPixelPosition, x); } QImage QCoreTextFontEngine::bitmapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t) From 6d58a1cecbaf0a6ed7d751f67450a86c742770ff Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Fri, 23 Nov 2018 17:19:14 +0100 Subject: [PATCH 0462/1650] Fix QPpdPrintDevice::isDefault How to test: * Have two printers * Use lpoptions -d to set the default printer to be one and then the other * Use lpstat -d to check setting the default printer worked * Use this simple test program and check the resulting values make sense qDebug() << "DefaultPrinter" << QPrinterInfo::defaultPrinter().printerName(); const QList list = QPrinterInfo::availablePrinters(); for(const QPrinterInfo &pi : list) { qDebug() << pi.printerName() << pi.isDefault(); } Fixes: QTBUG-70317 Change-Id: I535d11451c568630a374f5c37d8cac32cbb6d3ab Reviewed-by: Frederik Gladhorn --- src/plugins/printsupport/cups/qcupsprintersupport.cpp | 5 +++++ src/plugins/printsupport/cups/qcupsprintersupport_p.h | 2 ++ src/plugins/printsupport/cups/qppdprintdevice.cpp | 9 ++++++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/plugins/printsupport/cups/qcupsprintersupport.cpp b/src/plugins/printsupport/cups/qcupsprintersupport.cpp index 19e1df31f6..42a7a821f2 100644 --- a/src/plugins/printsupport/cups/qcupsprintersupport.cpp +++ b/src/plugins/printsupport/cups/qcupsprintersupport.cpp @@ -174,6 +174,11 @@ QStringList QCupsPrinterSupport::availablePrintDeviceIds() const } QString QCupsPrinterSupport::defaultPrintDeviceId() const +{ + return staticDefaultPrintDeviceId(); +} + +QString QCupsPrinterSupport::staticDefaultPrintDeviceId() { QString printerId; cups_dest_t *dests; diff --git a/src/plugins/printsupport/cups/qcupsprintersupport_p.h b/src/plugins/printsupport/cups/qcupsprintersupport_p.h index 42de28aec0..c2b4895c7f 100644 --- a/src/plugins/printsupport/cups/qcupsprintersupport_p.h +++ b/src/plugins/printsupport/cups/qcupsprintersupport_p.h @@ -71,6 +71,8 @@ public: QStringList availablePrintDeviceIds() const override; QString defaultPrintDeviceId() const override; + static QString staticDefaultPrintDeviceId(); + private: QString cupsOption(int i, const QString &key) const; }; diff --git a/src/plugins/printsupport/cups/qppdprintdevice.cpp b/src/plugins/printsupport/cups/qppdprintdevice.cpp index 51b93a0016..ea6336c4d1 100644 --- a/src/plugins/printsupport/cups/qppdprintdevice.cpp +++ b/src/plugins/printsupport/cups/qppdprintdevice.cpp @@ -39,6 +39,8 @@ #include "qppdprintdevice.h" +#include "qcupsprintersupport_p.h" + #include #include @@ -118,7 +120,12 @@ bool QPpdPrintDevice::isValid() const bool QPpdPrintDevice::isDefault() const { - return printerTypeFlags() & CUPS_PRINTER_DEFAULT; + // There seems to be a bug in cups in which printerTypeFlags + // returns CUPS_PRINTER_DEFAULT based only on system values, ignoring user lpoptions + // so we can't use that. And also there seems to be a bug in which dests returned + // by cupsGetNamedDest don't have is_default set at all so we can't use that either + // so go the long route and compare our id against the defaultPrintDeviceId + return id() == QCupsPrinterSupport::staticDefaultPrintDeviceId(); } QPrint::DeviceState QPpdPrintDevice::state() const From 6b875f0625acc6c6a4f8899b829176baaf7d8502 Mon Sep 17 00:00:00 2001 From: Thomas Miller Date: Wed, 14 Nov 2018 16:19:43 -0800 Subject: [PATCH 0463/1650] Implement mul_overflow for MSVC arm64 Change-Id: Ia7c79614e6ef21222fb9683b540ac51b45a77c49 Reviewed-by: Thiago Macieira --- src/corelib/global/qnumeric_p.h | 74 ++++++++++++--------------------- 1 file changed, 26 insertions(+), 48 deletions(-) diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h index e318c3759b..5326d9485b 100644 --- a/src/corelib/global/qnumeric_p.h +++ b/src/corelib/global/qnumeric_p.h @@ -58,14 +58,21 @@ #if defined(Q_CC_MSVC) # include -#endif - -#if defined(Q_CC_MSVC) -#include +# include +# if defined(Q_PROCESSOR_X86_64) || defined(Q_PROCESSOR_ARM_64) +# define Q_INTRINSIC_MUL_OVERFLOW64 +# define Q_UMULH(v1, v2) __umulh(v1, v2); +# define Q_SMULH(v1, v2) __mulh(v1, v2); +# pragma intrinsic(__umulh) +# pragma intrinsic(__mulh) +# endif #endif # if defined(Q_OS_INTEGRITY) && defined(Q_PROCESSOR_ARM_64) #include +# define Q_INTRINSIC_MUL_OVERFLOW64 +# define Q_UMULH(v1, v2) __MULUH64(v1, v2); +# define Q_SMULH(v1, v2) __MULSH64(v1, v2); #endif #if !defined(Q_CC_MSVC) && (defined(Q_OS_QNX) || defined(Q_CC_INTEL)) @@ -327,26 +334,26 @@ mul_overflow(T v1, T v2, T *r) return lr > std::numeric_limits::max() || lr < std::numeric_limits::min(); } -# if defined(Q_OS_INTEGRITY) && defined(Q_PROCESSOR_ARM_64) +# if defined(Q_INTRINSIC_MUL_OVERFLOW64) template <> inline bool mul_overflow(quint64 v1, quint64 v2, quint64 *r) { *r = v1 * v2; - return __MULUH64(v1, v2); + return Q_UMULH(v1, v2); } template <> inline bool mul_overflow(qint64 v1, qint64 v2, qint64 *r) { - qint64 high = __MULSH64(v1, v2); - if (high == 0) { - *r = v1 * v2; - return *r < 0; - } - if (high == -1) { - *r = v1 * v2; - return *r >= 0; - } - return true; + // This is slightly more complex than the unsigned case above: the sign bit + // of 'low' must be replicated as the entire 'high', so the only valid + // values for 'high' are 0 and -1. Use unsigned multiply since it's the same + // as signed for the low bits and use a signed right shift to verify that + // 'high' is nothing but sign bits that match the sign of 'low'. + + qint64 high = __mulh(v1, v2); + *r = qint64(quint64(v1) * quint64(v2)); + return (*r >> 63) != high; } +# if defined(Q_OS_INTEGRITY) && defined(Q_PROCESSOR_ARM_64) template <> inline bool mul_overflow(uint64_t v1, uint64_t v2, uint64_t *r) { return mul_overflow(v1,v2,reinterpret_cast(r)); @@ -356,8 +363,8 @@ template <> inline bool mul_overflow(int64_t v1, int64_t v2, int64_t *r) { return mul_overflow(v1,v2,reinterpret_cast(r)); } - -#endif +# endif // OS_INTEGRITY ARM64 +# endif // Q_INTRINSIC_MUL_OVERFLOW64 # if defined(Q_CC_MSVC) && defined(Q_PROCESSOR_X86) // We can use intrinsics for the unsigned operations with MSVC @@ -369,37 +376,8 @@ template <> inline bool add_overflow(unsigned v1, unsigned v2, unsigned *r) # if defined(Q_PROCESSOR_X86_64) template <> inline bool add_overflow(quint64 v1, quint64 v2, quint64 *r) { return _addcarry_u64(0, v1, v2, reinterpret_cast(r)); } - -# pragma intrinsic(_umul128) -template <> inline bool mul_overflow(quint64 v1, quint64 v2, quint64 *r) -{ - // use 128-bit multiplication with the _umul128 intrinsic - // https://msdn.microsoft.com/en-us/library/3dayytw9.aspx - quint64 high; - *r = _umul128(v1, v2, &high); - return high; -} - -# pragma intrinsic(_mul128) -template <> inline bool mul_overflow(qint64 v1, qint64 v2, qint64 *r) -{ - // Use 128-bit multiplication with the _mul128 intrinsic - // https://msdn.microsoft.com/en-us/library/82cxdw50.aspx - - // This is slightly more complex than the unsigned case above: the sign bit - // of 'low' must be replicated as the entire 'high', so the only valid - // values for 'high' are 0 and -1. - - qint64 high; - *r = _mul128(v1, v2, &high); - if (high == 0) - return *r < 0; - if (high == -1) - return *r >= 0; - return true; -} # endif // x86-64 -# endif // MSVC x86 +# endif // MSVC X86 #endif // !GCC } #endif // Q_CLANG_QDOC From 1eeebae7e3b5eb8dda37755b32aafe6719b5cf7b Mon Sep 17 00:00:00 2001 From: Ville Voutilainen Date: Wed, 21 Nov 2018 14:07:18 +0200 Subject: [PATCH 0464/1650] Fix compilation of qendian's qswap specializations on gcc 4.8 Task-number: QTBUG-71945 Change-Id: Icf2b75c72946f57ebffc880c9238531dea13ab5b Reviewed-by: Ivan Komissarov Reviewed-by: Simon Hausmann --- src/corelib/global/qendian.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/corelib/global/qendian.h b/src/corelib/global/qendian.h index 0e67a1ab8e..f2e5833468 100644 --- a/src/corelib/global/qendian.h +++ b/src/corelib/global/qendian.h @@ -162,17 +162,17 @@ Float qbswapFloatHelper(Float source) return qFromUnaligned(&temp); } -template <> inline qfloat16 qbswap(qfloat16 source) +inline qfloat16 qbswap(qfloat16 source) { return qbswapFloatHelper(source); } -template <> inline float qbswap(float source) +inline float qbswap(float source) { return qbswapFloatHelper(source); } -template <> inline double qbswap(double source) +inline double qbswap(double source) { return qbswapFloatHelper(source); } @@ -185,7 +185,7 @@ template <> inline double qbswap(double source) */ template inline void qbswap(const T src, void *dest) { - qToUnaligned(qbswap(src), dest); + qToUnaligned(qbswap(src), dest); } template void *qbswap(const void *source, qsizetype count, void *dest) noexcept; @@ -223,9 +223,9 @@ template inline void qFromLittleEndian(const void *source, qsizetyp #else // Q_LITTLE_ENDIAN template inline Q_DECL_CONSTEXPR T qToBigEndian(T source) -{ return qbswap(source); } +{ return qbswap(source); } template inline Q_DECL_CONSTEXPR T qFromBigEndian(T source) -{ return qbswap(source); } +{ return qbswap(source); } template inline Q_DECL_CONSTEXPR T qToLittleEndian(T source) { return source; } template inline Q_DECL_CONSTEXPR T qFromLittleEndian(T source) From 247baedb2560d23d14f27cd52f4759e07b0049c0 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Wed, 28 Nov 2018 16:34:58 +0100 Subject: [PATCH 0465/1650] Doc: specifically list the QToolButton properties that actions affect Also, add a note that explains that autoRepeat does not affect QToolButton's autoRepeat property. Change-Id: I9e95cef9e9d1b5ee6cb1114d0b9a9fad562db601 Fixes: QTBUG-48204 Reviewed-by: Andy Shaw --- src/widgets/widgets/qtoolbutton.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/widgets/widgets/qtoolbutton.cpp b/src/widgets/widgets/qtoolbutton.cpp index 03950ef44b..6a24712319 100644 --- a/src/widgets/widgets/qtoolbutton.cpp +++ b/src/widgets/widgets/qtoolbutton.cpp @@ -898,7 +898,23 @@ bool QToolButton::autoRaise() const Sets the default action to \a action. If a tool button has a default action, the action defines the - button's properties like text, icon, tool tip, etc. + following properties of the button: + + \list + \li \l {QAbstractButton::}{checkable} + \li \l {QAbstractButton::}{checked} + \li \l {QWidget::}{enabled} + \li \l {QWidget::}{font} + \li \l {QAbstractButton::}{icon} + \li \l {QToolButton::}{popupMode} (assuming the action has a menu) + \li \l {QWidget::}{statusTip} + \li \l {QAbstractButton::}{text} + \li \l {QWidget::}{toolTip} + \li \l {QWidget::}{whatsThis} + \endlist + + Other properties, such as \l autoRepeat, are not affected + by actions. */ void QToolButton::setDefaultAction(QAction *action) { From 1f1dc3fc4c2e5e2d94e86dfc7235a4b762da2e72 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 16 Nov 2018 16:01:30 +0100 Subject: [PATCH 0466/1650] Fix gamma-correction in QCoreTextFontEngine with Mojave The code was previously assuming font-smoothing was only used with A32 font antialiasing, so the corresponding gamma-correction was not performed. Task-number: QTBUG-71075 Task-number: QTBUG-71946 Change-Id: I68d8304cf18638239d8bfac32c67333f16ccc7bd Reviewed-by: Lars Knoll --- src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index 271f07e0c1..7fb22c0675 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -736,8 +736,7 @@ bool QCoreTextFontEngine::shouldSmoothFont() const bool QCoreTextFontEngine::expectsGammaCorrectedBlending() const { - // Only works well when font-smoothing is enabled - return (glyphFormat == Format_A32) && !(fontDef.styleStrategy & (QFont::NoAntialias | QFont::NoSubpixelAntialias)); + return shouldSmoothFont(); } QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &matrix) From c3a963da1f9e7b1d37e63eedded61da4fbdaaf9a Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Fri, 16 Nov 2018 17:07:33 +0100 Subject: [PATCH 0467/1650] src/3rdparty: remove xkbcommon The only reason why we bundled this library ~6 years ago was because it was not available on distributions that we supported at the time, but library was a hard dependency for XCB plugin. See: 2122e731abdb619249df89642c0800640b2fa428 Later more and more projects started to depend on it (compose input context plugin, libinput, mir, wayland). The configuration had become too complex, because some projects used bundled and some used the version from the system. Having libxkbcommon in 3rdparty sources is not necessary anymore, after RHEL 6.6 was removed from the list of supported platforms for Qt 5.12. Ubuntu 16.04 - 0.5.0 Ubuntu 18.04 - 0.8.0 openSUSE 42.3 - 0.6.1 RHEL-7.4 - 0.7.1 This will also simplify further development, e.g. QTBUG-42181 Bumped the minimal required version 0.4.1 -> 0.5.0. The patch also contains a code marked with "TRANSITION HACK", which is temporary needed so we can update the dependent wayland module. [ChangeLog][Third-Party Code] Removed xkbcommon from bundled sources. This library is present on all supported platforms. The minimal required version now is 0.5.0. Task-number: QTBUG-65503 Change-Id: Iec50829bb6f8fbb19f3c4e4ad62e332beb837de5 Reviewed-by: Lars Knoll Reviewed-by: Laszlo Agocs Reviewed-by: Oswald Buddenhagen --- config_help.txt | 5 +- src/3rdparty/xkbcommon-x11.pri | 14 - src/3rdparty/xkbcommon.pri | 60 - src/3rdparty/xkbcommon/LICENSE | 215 - src/3rdparty/xkbcommon/NEWS | 404 - src/3rdparty/xkbcommon/README.md | 75 - src/3rdparty/xkbcommon/qt_attribution.json | 29 - src/3rdparty/xkbcommon/src/atom.c | 225 - src/3rdparty/xkbcommon/src/atom.h | 49 - .../xkbcommon/src/compose/compose-state.c | 196 - src/3rdparty/xkbcommon/src/compose/parser.c | 737 -- src/3rdparty/xkbcommon/src/compose/parser.h | 36 - src/3rdparty/xkbcommon/src/compose/paths.c | 203 - src/3rdparty/xkbcommon/src/compose/paths.h | 42 - src/3rdparty/xkbcommon/src/compose/table.c | 219 - src/3rdparty/xkbcommon/src/compose/table.h | 100 - src/3rdparty/xkbcommon/src/context-priv.c | 190 - src/3rdparty/xkbcommon/src/context.c | 331 - src/3rdparty/xkbcommon/src/context.h | 127 - src/3rdparty/xkbcommon/src/darray.h | 209 - src/3rdparty/xkbcommon/src/keymap-priv.c | 150 - src/3rdparty/xkbcommon/src/keymap.c | 519 -- src/3rdparty/xkbcommon/src/keymap.h | 482 -- src/3rdparty/xkbcommon/src/keysym-utf.c | 937 --- src/3rdparty/xkbcommon/src/keysym.c | 762 -- src/3rdparty/xkbcommon/src/keysym.h | 65 - src/3rdparty/xkbcommon/src/ks_tables.h | 7116 ----------------- src/3rdparty/xkbcommon/src/scanner-utils.h | 195 - src/3rdparty/xkbcommon/src/state.c | 1446 ---- src/3rdparty/xkbcommon/src/text.c | 346 - src/3rdparty/xkbcommon/src/text.h | 76 - src/3rdparty/xkbcommon/src/utf8.c | 138 - src/3rdparty/xkbcommon/src/utf8.h | 36 - src/3rdparty/xkbcommon/src/utils.c | 163 - src/3rdparty/xkbcommon/src/utils.h | 276 - src/3rdparty/xkbcommon/src/x11/util.c | 217 - src/3rdparty/xkbcommon/src/x11/x11-keymap.c | 1177 --- src/3rdparty/xkbcommon/src/x11/x11-priv.h | 54 - src/3rdparty/xkbcommon/src/x11/x11-state.c | 71 - src/3rdparty/xkbcommon/src/xkbcomp/action.c | 871 -- src/3rdparty/xkbcommon/src/xkbcomp/action.h | 56 - .../xkbcommon/src/xkbcomp/ast-build.c | 806 -- .../xkbcommon/src/xkbcomp/ast-build.h | 125 - src/3rdparty/xkbcommon/src/xkbcomp/ast.h | 353 - src/3rdparty/xkbcommon/src/xkbcomp/compat.c | 932 --- src/3rdparty/xkbcommon/src/xkbcomp/expr.c | 686 -- src/3rdparty/xkbcommon/src/xkbcomp/expr.h | 85 - src/3rdparty/xkbcommon/src/xkbcomp/include.c | 309 - src/3rdparty/xkbcommon/src/xkbcomp/include.h | 42 - src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c | 668 -- .../xkbcommon/src/xkbcomp/keymap-dump.c | 664 -- src/3rdparty/xkbcommon/src/xkbcomp/keywords.c | 348 - .../xkbcommon/src/xkbcomp/parser-priv.h | 44 - src/3rdparty/xkbcommon/src/xkbcomp/parser.h | 157 - src/3rdparty/xkbcommon/src/xkbcomp/rules.c | 1037 --- src/3rdparty/xkbcommon/src/xkbcomp/rules.h | 32 - src/3rdparty/xkbcommon/src/xkbcomp/scanner.c | 208 - src/3rdparty/xkbcommon/src/xkbcomp/symbols.c | 1595 ---- src/3rdparty/xkbcommon/src/xkbcomp/types.c | 742 -- src/3rdparty/xkbcommon/src/xkbcomp/vmod.c | 105 - src/3rdparty/xkbcommon/src/xkbcomp/vmod.h | 34 - .../xkbcommon/src/xkbcomp/xkbcomp-keymap.c | 298 - .../xkbcommon/src/xkbcomp/xkbcomp-parser.c | 3392 -------- .../xkbcommon/src/xkbcomp/xkbcomp-priv.h | 124 - src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp.c | 139 - .../xkbcommon/xkbcommon/xkbcommon-compat.h | 98 - .../xkbcommon/xkbcommon/xkbcommon-compose.h | 493 -- .../xkbcommon/xkbcommon/xkbcommon-keysyms.h | 3004 ------- .../xkbcommon/xkbcommon/xkbcommon-names.h | 45 - .../xkbcommon/xkbcommon/xkbcommon-x11.h | 244 - src/3rdparty/xkbcommon/xkbcommon/xkbcommon.h | 1868 ----- src/gui/configure.json | 55 +- .../input/libinput/libinput.pri | 5 +- .../input/libinput/qlibinputkeyboard.cpp | 16 +- .../platforminputcontexts/compose/compose.pro | 7 +- src/plugins/platforms/mirclient/mirclient.pro | 7 +- src/plugins/platforms/xcb/xcb_qpa_lib.pro | 14 +- 77 files changed, 47 insertions(+), 37353 deletions(-) delete mode 100644 src/3rdparty/xkbcommon-x11.pri delete mode 100644 src/3rdparty/xkbcommon.pri delete mode 100644 src/3rdparty/xkbcommon/LICENSE delete mode 100644 src/3rdparty/xkbcommon/NEWS delete mode 100644 src/3rdparty/xkbcommon/README.md delete mode 100644 src/3rdparty/xkbcommon/qt_attribution.json delete mode 100644 src/3rdparty/xkbcommon/src/atom.c delete mode 100644 src/3rdparty/xkbcommon/src/atom.h delete mode 100644 src/3rdparty/xkbcommon/src/compose/compose-state.c delete mode 100644 src/3rdparty/xkbcommon/src/compose/parser.c delete mode 100644 src/3rdparty/xkbcommon/src/compose/parser.h delete mode 100644 src/3rdparty/xkbcommon/src/compose/paths.c delete mode 100644 src/3rdparty/xkbcommon/src/compose/paths.h delete mode 100644 src/3rdparty/xkbcommon/src/compose/table.c delete mode 100644 src/3rdparty/xkbcommon/src/compose/table.h delete mode 100644 src/3rdparty/xkbcommon/src/context-priv.c delete mode 100644 src/3rdparty/xkbcommon/src/context.c delete mode 100644 src/3rdparty/xkbcommon/src/context.h delete mode 100644 src/3rdparty/xkbcommon/src/darray.h delete mode 100644 src/3rdparty/xkbcommon/src/keymap-priv.c delete mode 100644 src/3rdparty/xkbcommon/src/keymap.c delete mode 100644 src/3rdparty/xkbcommon/src/keymap.h delete mode 100644 src/3rdparty/xkbcommon/src/keysym-utf.c delete mode 100644 src/3rdparty/xkbcommon/src/keysym.c delete mode 100644 src/3rdparty/xkbcommon/src/keysym.h delete mode 100644 src/3rdparty/xkbcommon/src/ks_tables.h delete mode 100644 src/3rdparty/xkbcommon/src/scanner-utils.h delete mode 100644 src/3rdparty/xkbcommon/src/state.c delete mode 100644 src/3rdparty/xkbcommon/src/text.c delete mode 100644 src/3rdparty/xkbcommon/src/text.h delete mode 100644 src/3rdparty/xkbcommon/src/utf8.c delete mode 100644 src/3rdparty/xkbcommon/src/utf8.h delete mode 100644 src/3rdparty/xkbcommon/src/utils.c delete mode 100644 src/3rdparty/xkbcommon/src/utils.h delete mode 100644 src/3rdparty/xkbcommon/src/x11/util.c delete mode 100644 src/3rdparty/xkbcommon/src/x11/x11-keymap.c delete mode 100644 src/3rdparty/xkbcommon/src/x11/x11-priv.h delete mode 100644 src/3rdparty/xkbcommon/src/x11/x11-state.c delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/action.c delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/action.h delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/ast.h delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/compat.c delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/expr.c delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/expr.h delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/include.c delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/include.h delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/keywords.c delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/parser.h delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/rules.c delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/rules.h delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/scanner.c delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/symbols.c delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/types.c delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/vmod.c delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/vmod.h delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp-keymap.c delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp-parser.c delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp-priv.h delete mode 100644 src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp.c delete mode 100644 src/3rdparty/xkbcommon/xkbcommon/xkbcommon-compat.h delete mode 100644 src/3rdparty/xkbcommon/xkbcommon/xkbcommon-compose.h delete mode 100644 src/3rdparty/xkbcommon/xkbcommon/xkbcommon-keysyms.h delete mode 100644 src/3rdparty/xkbcommon/xkbcommon/xkbcommon-names.h delete mode 100644 src/3rdparty/xkbcommon/xkbcommon/xkbcommon-x11.h delete mode 100644 src/3rdparty/xkbcommon/xkbcommon/xkbcommon.h diff --git a/config_help.txt b/config_help.txt index 44dccfb8da..5369163055 100644 --- a/config_help.txt +++ b/config_help.txt @@ -303,10 +303,7 @@ Gui, printing, widget options: -mtdev ............. Enable mtdev support [auto] -tslib ............. Enable tslib support [auto] -xcb-xinput ........ Enable XInput2 support [auto] - -xkbcommon-x11 ..... Select xkbcommon used in combination with xcb - [system/qt/no] - -xkbcommon-evdev ... Enable X-less xkbcommon in combination with libinput - [auto] + -xkbcommon ......... Enable key mapping support [auto] Image formats: -gif ............... Enable reading support for GIF [auto] diff --git a/src/3rdparty/xkbcommon-x11.pri b/src/3rdparty/xkbcommon-x11.pri deleted file mode 100644 index 58e3a63b46..0000000000 --- a/src/3rdparty/xkbcommon-x11.pri +++ /dev/null @@ -1,14 +0,0 @@ -include(xkbcommon.pri) - -# Build xkbcommon-x11 support library, it depends on -lxcb and -lxcb-xkb, linking is done -# in xcb-plugin.pro (linked to system libraries or if Qt was configured with -qt-xcb then -# linked to -lxcb-static). -INCLUDEPATH += $$PWD/xkbcommon/src/x11 - -# Need to rename several files, qmake has problems processing a project when -# sub-directories contain files with an equal names. - -SOURCES += \ - $$PWD/xkbcommon/src/x11/util.c \ - $$PWD/xkbcommon/src/x11/x11-keymap.c \ # renamed: keymap.c -> x11-keymap.c - $$PWD/xkbcommon/src/x11/x11-state.c # renamed: state.c -> x11-state.c diff --git a/src/3rdparty/xkbcommon.pri b/src/3rdparty/xkbcommon.pri deleted file mode 100644 index 63c8e687ec..0000000000 --- a/src/3rdparty/xkbcommon.pri +++ /dev/null @@ -1,60 +0,0 @@ -# Requires GNU C extensions -CONFIG -= strict_c - -INCLUDEPATH += $$PWD/xkbcommon \ - $$PWD/xkbcommon/xkbcommon \ - $$PWD/xkbcommon/src \ - $$PWD/xkbcommon/src/xkbcomp - -include($$shadowed($$PWD/../gui/qtgui-config.pri)) - -# Unused (but needs to be set to something) - we don't use APIs that read xkb -# config files from file system. We use APIs that fetch the necessary keymap -# details directly from X server. -DEFINES += DFLT_XKB_CONFIG_ROOT='\\"/usr/share/X11/xkb\\"' -# Unused (but needs to be set to something) - After QTBUG-42181, this needs to -# be become a configure switch. -DEFINES += XLOCALEDIR='\\"/usr/share/X11/locale/\\"' - -### RMLVO names can be overwritten with environmental variables (see libxkbcommon documentation) -DEFINES += DEFAULT_XKB_RULES='\\"evdev\\"' -DEFINES += DEFAULT_XKB_MODEL='\\"pc105\\"' -DEFINES += DEFAULT_XKB_LAYOUT='\\"us\\"' - -# Need to rename several files, qmake has problems processing a project when -# sub-directories contain files with an equal names. - -SOURCES += \ - $$PWD/xkbcommon/src/keysym-utf.c \ - $$PWD/xkbcommon/src/keymap.c \ - $$PWD/xkbcommon/src/keymap-priv.c \ - $$PWD/xkbcommon/src/utils.c \ - $$PWD/xkbcommon/src/atom.c \ - $$PWD/xkbcommon/src/compose/paths.c \ - $$PWD/xkbcommon/src/compose/parser.c \ - $$PWD/xkbcommon/src/compose/compose-state.c \ # renamed: keymap.c -> compose-state.c - $$PWD/xkbcommon/src/compose/table.c \ - $$PWD/xkbcommon/src/xkbcomp/xkbcomp-keymap.c \ # renamed: keymap.c -> xkbcomp-keymap.c - $$PWD/xkbcommon/src/xkbcomp/xkbcomp.c \ - $$PWD/xkbcommon/src/xkbcomp/keymap-dump.c \ - $$PWD/xkbcommon/src/xkbcomp/rules.c \ - $$PWD/xkbcommon/src/xkbcomp/expr.c \ - $$PWD/xkbcommon/src/xkbcomp/action.c \ - $$PWD/xkbcommon/src/xkbcomp/compat.c \ - $$PWD/xkbcommon/src/xkbcomp/types.c \ - $$PWD/xkbcommon/src/xkbcomp/scanner.c \ - $$PWD/xkbcommon/src/xkbcomp/xkbcomp-parser.c \ # renamed: parser.c -> xkbcomp-parser.c - $$PWD/xkbcommon/src/xkbcomp/ast-build.c \ - $$PWD/xkbcommon/src/xkbcomp/keywords.c \ - $$PWD/xkbcommon/src/xkbcomp/keycodes.c \ - $$PWD/xkbcommon/src/xkbcomp/vmod.c \ - $$PWD/xkbcommon/src/xkbcomp/include.c \ - $$PWD/xkbcommon/src/xkbcomp/symbols.c \ - $$PWD/xkbcommon/src/context-priv.c \ - $$PWD/xkbcommon/src/text.c \ - $$PWD/xkbcommon/src/context.c \ - $$PWD/xkbcommon/src/keysym.c \ - $$PWD/xkbcommon/src/utf8.c \ - $$PWD/xkbcommon/src/state.c - -TR_EXCLUDE += $$PWD/* diff --git a/src/3rdparty/xkbcommon/LICENSE b/src/3rdparty/xkbcommon/LICENSE deleted file mode 100644 index 3dcd0391fc..0000000000 --- a/src/3rdparty/xkbcommon/LICENSE +++ /dev/null @@ -1,215 +0,0 @@ -The following is a list of all copyright notices and license statements which -appear in the xkbcommon source tree. - -If making new contributions, the first form (i.e. Daniel Stone, Ran Benita, -etc) is vastly preferred. - -All licenses are derivative of the MIT/X11 license, mostly identical other -than no-endorsement clauses (e.g. paragraph 4 of The Open Group's license). - -These statements are split into two sections: one for the code compiled and -distributed as part of the libxkbcommon shared library and the code -component of all tests (i.e. everything under src/ and xkbcommon/, plus the -.c and .h files under test/), and another for the test data under test/data, -which is distributed with the xkbcommon source tarball, but not installed to -the system. - - -BEGINNING OF SOFTWARE COPYRIGHT/LICENSE STATEMENTS: - - -------------------------------------------------------------------------------- - -Copyright © 2009-2012, 2016 Daniel Stone -Copyright © 2012 Ran Benita -Copyright © 2010, 2012 Intel Corporation -Copyright © 2008, 2009 Dan Nicholson -Copyright © 2010 Francisco Jerez - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice (including the next -paragraph) shall be included in all copies or substantial portions of the -Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - - -------------------------------------------------------------------------------- - - -Copyright 1985, 1987, 1988, 1990, 1998 The Open Group - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the names of the authors or their -institutions shall not be used in advertising or otherwise to promote the -sale, use or other dealings in this Software without prior written -authorization from the authors. - - -------------------------------------------------------------------------------- - - -Copyright (c) 1993, 1994, 1995, 1996 by Silicon Graphics Computer Systems, Inc. - -Permission to use, copy, modify, and distribute this -software and its documentation for any purpose and without -fee is hereby granted, provided that the above copyright -notice appear in all copies and that both that copyright -notice and this permission notice appear in supporting -documentation, and that the name of Silicon Graphics not be -used in advertising or publicity pertaining to distribution -of the software without specific prior written permission. -Silicon Graphics makes no representation about the suitability -of this software for any purpose. It is provided "as is" -without any express or implied warranty. - -SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON -GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL -DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, -DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH -THE USE OR PERFORMANCE OF THIS SOFTWARE. - - -------------------------------------------------------------------------------- - - -Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - - -------------------------------------------------------------------------------- - - -Copyright (C) 2011 Joseph Adams - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - -------------------------------------------------------------------------------- - - - -END OF SOFTWARE COPYRIGHT/LICENSE STATEMENTS - - -BEGINNING OF LICENSE STATEMENTS FOR UNDISTRIBUTED DATA FILES IN test/data, -derived from xkeyboard-config: - - - -------------------------------------------------------------------------------- - -Copyright 1996 by Joseph Moss -Copyright (C) 2002-2007 Free Software Foundation, Inc. -Copyright (C) Dmitry Golubev , 2003-2004 -Copyright (C) 2004, Gregory Mokhin -Copyright (C) 2006 Erdal Ronahî - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation, and that the name of the copyright holder(s) not be used in -advertising or publicity pertaining to distribution of the software without -specific, written prior permission. The copyright holder(s) makes no -representations about the suitability of this software for any purpose. It -is provided "as is" without express or implied warranty. - -THE COPYRIGHT HOLDER(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO -EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, -DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. - - -------------------------------------------------------------------------------- - - Copyright 1992 by Oki Technosystems Laboratory, Inc. - Copyright 1992 by Fuji Xerox Co., Ltd. - -Permission to use, copy, modify, distribute, and sell this software -and its documentation for any purpose is hereby granted without fee, -provided that the above copyright notice appear in all copies and -that both that copyright notice and this permission notice appear -in supporting documentation, and that the name of Oki Technosystems -Laboratory and Fuji Xerox not be used in advertising or publicity -pertaining to distribution of the software without specific, written -prior permission. -Oki Technosystems Laboratory and Fuji Xerox make no representations -about the suitability of this software for any purpose. It is provided -"as is" without express or implied warranty. - -OKI TECHNOSYSTEMS LABORATORY AND FUJI XEROX DISCLAIM ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL OKI TECHNOSYSTEMS -LABORATORY AND FUJI XEROX BE LIABLE FOR ANY SPECIAL, INDIRECT OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE -OR PERFORMANCE OF THIS SOFTWARE. diff --git a/src/3rdparty/xkbcommon/NEWS b/src/3rdparty/xkbcommon/NEWS deleted file mode 100644 index 50b01a3b5f..0000000000 --- a/src/3rdparty/xkbcommon/NEWS +++ /dev/null @@ -1,404 +0,0 @@ -libxkbcommon 0.8.2 - 2018-08-05 -================== - -- Fix various problems found with fuzzing (see commit messages for - more details): - - - Fix a few NULL-dereferences, out-of-bounds access and undefined behavior - in the XKB text format parser. - - -libxkbcommon 0.8.1 - 2018-08-03 -================== - -- Fix various problems found in the meson build (see commit messages for more - details): - - - Fix compilation on Darwin. - - - Fix compilation of the x11 tests and demos when XCB is installed in a - non-standard location. - - - Fix xkbcommon-x11.pc missing the Requires specification. - -- Fix various problems found with fuzzing and Coverity (see commit messages for - more details): - - - Fix stack overflow in the XKB text format parser when evaluating boolean - negation. - - - Fix NULL-dereferences in the XKB text format parser when some unsupported - tokens appear (the tokens are still parsed for backward compatibility). - - - Fix NULL-dereference in the XKB text format parser when parsing an - xkb_geometry section. - - - Fix an infinite loop in the Compose text format parser on some inputs. - - - Fix an invalid free() when using multiple keysyms. - -- Replace the Unicode characters for the leftanglebracket and rightanglebracket - keysyms from the deprecated LEFT/RIGHT-POINTING ANGLE BRACKET to - MATHEMATICAL LEFT/RIGHT ANGLE BRACKET. - -- Reject out-of-range Unicode codepoints in xkb_keysym_to_utf8 and - xkb_keysym_to_utf32. - - -libxkbcommon 0.8.0 - 2017-12-15 -================== - -- Added xkb_keysym_to_{upper,lower} to perform case-conversion directly on - keysyms. This is useful in some odd cases, but working with the Unicode - representations should be preferred when possible. - -- Added Unicode conversion rules for the signifblank and permille keysyms. - -- Fixed a bug in the parsing of XKB key type definitions where the number - of levels were determined by the number of level *names*. Keymaps which - omit level names were hence miscompiled. - - This regressed in version 0.4.3. Keymaps from xkeyboard-config were not - affected since they don't omit level names. - -- New API: - xkb_keysym_to_upper() - xkb_keysym_to_lower() - - -libxkbcommon 0.7.2 - 2017-08-04 -================== - -- Added a Meson build system as an alternative to existing autotools build - system. - - The intent is to remove the autotools build in one of the next releases. - Please try to convert to it and report any problems. - - See http://mesonbuild.com/Quick-guide.html for basic usage, the - meson_options.txt for the project-specific configuration options, - and the PACKAGING file for more details. - - There are some noteworthy differences compared to the autotools build: - - - Feature auto-detection is not performed. By default, all features are - enabled (currently: docs, x11, wayland). The build fails if any of - the required dependencies are not available. To disable a feature, - pass -Denable-=false to meson. - - - The libraries are either installed as shared or static, as specified - by the -Ddefault_library=shared/static option. With autotools, both - versions are installed by default. - - - xorg-util-macros is not used. - - - A parser generator (bison/byacc) is always required - there is no - fallback to pre-generated output bundled in the tarball, as there is - in autotools. - -- Removed Android.mk support. - -- Removed the *-uninstalled.pc pkgconfig files. - -- Ported the interactive-wayland demo program to v6 of the xdg-shell - protocol. - -- Added new keysym definitions from xproto. - -- New API: - XKB_KEY_XF86Keyboard - XKB_KEY_XF86WWAN - XKB_KEY_XF86RFKill - XKB_KEY_XF86AudioPreset - - -libxkbcommon 0.7.1 - 2017-01-18 -================== - -- Fixed various reported problems when the current locale is tr_TR.UTF-8. - - The function xkb_keysym_from_name() used to perform case-insensitive - string comparisons in a locale-dependent way, but required it to to - work as in the C/ASCII locale (the so called "Turkish i problem"). - - The function is now no longer affected by the current locale. - -- Fixed compilation in NetBSD. - - -libxkbcommon 0.7.0 - 2016-11-11 -================== - -- Added support for different "modes" of calculating consumed modifiers. - The existing mode, based on the XKB standard, has proven to be - unintuitive in various shortcut implementations. - - A new mode, based on the calculation used by the GTK toolkit, is added. - This mode is less eager to declare a modifier as consumed. - -- Added a new interactive demo program using the Wayland protocol. - See the PACKAGING file for the new (optional) test dependencies. - -- Fixed a compilation error on GNU Hurd. - -- New API: - enum xkb_consumed_mode - XKB_CONSUMED_MODE_XKB - XKB_CONSUMED_MODE_GTK - xkb_state_key_get_consumed_mods2 - xkb_state_mod_index_is_consumed2 - - -libxkbcommon 0.6.1 - 2016-04-08 -================== - -- Added LICENSE to distributed files in tarball releases. - -- Minor typo fix in xkb_keymap_get_as_string() documentation. - - -libxkbcommon 0.6.0 - 2016-03-16 -================== - -- If the XKB_CONFIG_ROOT environment variable is set, it is used as the XKB - configuration root instead of the path determined at build time. - -- Tests and benchmarks now build correctly on OSX. - -- An XKB keymap provides a name for each key it defines. Traditionally, - these names are limited to at most 4 characters, and are thus somewhat - obscure, but might still be useful (xkbcommon lifts the 4 character limit). - - The new functions xkb_keymap_key_get_name() and xkb_keymap_key_by_name() - can be used to get the name of a key or find a key by name. Note that - a key may have aliases. - -- Documentation improvements. - -- New API: - xkb_keymap_key_by_name() - xkb_keymap_key_get_name() - - -libxkbcommon 0.5.0 - 2014-10-18 -================== - -- Added support for Compose/dead keys in a new module (included in - libxkbcommon). See the documentation or the - xkbcommon/xkbcommon-compose.h header file for more details. - -- Improved and reordered some sections of the documentation. - -- The doxygen HTML pages were made nicer to read. - -- Most tests now run also on non-linux platforms. - -- A warning is emitted by default about RMLVO values which are not used - during keymap compilation, which are most often a user misconfiguration. - For example, "terminate:ctrl_alt_backspace" instead of - "terminate:ctrl_alt_bksp". - -- Added symbol versioning for libxkbcommon and libxkbcommon-x11. - Note: binaries compiled against this and future versions will not be - able to link against the previous versions of the library. - -- Removed several compatablity symbols from the binary (the API isn't - affected). This affects binaries which - - 1. Were compiled against a pre-stable (<0.2.0) version of libxkbcommon, and - 2. Are linked against the this or later version of libxkbcommon. - - Such a scenario is likely to fail already. - -- If Xvfb is not available, the x11comp test is now correctly skipped - instead of hanging. - -- Benchmarks were moved to a separate bench/ directory. - -- Build fixes from OpenBSD. - -- Fixed a bug where key type entries such as "map[None] = Level2;" were - ignored. - -- New API: - XKB_COMPOSE_* - xkb_compose_* - - -libxkbcommon 0.4.3 - 2014-08-19 -================== - -- Fixed a bug which caused xkb_x11_keymap_new_from_device() to misrepresent - modifiers for some keymaps. - - https://github.com/xkbcommon/libxkbcommon/issues/9 - -- Fixed a bug which caused xkb_x11_keymap_new_from_device() to ignore XKB - PrivateAction's. - -- Modifiers are now always fully resolved after xkb_state_update_mask(). - Previously the given state components were used as-is, without - considering virtual modifier mappings. - Note: this only affects non-standard uses of xkb_state_update_mask(). - -- Added a test for xkbcommon-x11, "x11comp". The test uses the system's - Xvfb server and xkbcomp. If they do not exist or fail, the test is - skipped. - -- Fixed memory leaks after parse errors in the XKB yacc parser. - The fix required changes which are currently incompatible with byacc. - - -libxkbcommon 0.4.2 - 2014-05-15 -================== - -- Fixed a bug where explicitly passing "--enable-x11" to ./configure would - in fact disable it (regressed in 0.4.1). - -- Added @since version annotations to the API documentation for everything - introduced after the initial stable release (0.2.0). - -- Added a section to the documentation about keysym transformations, and - clarified which functions perform a given transformation. - -- XKB files which fail to compile during keymap construction can no longer - have any effect on the resulting keymap: changes are only applied when - the entire compilation succeeds. - Note: this was a minor correctness issue inherited from xkbcomp. - -- Fix an out-of-bounds array access in src/x11/util.c:adopt_atoms() - error-handling code. - Note: it seems impossible to trigger in the current code since the input - size cannot exceed the required size. - - -libxkbcommon 0.4.1 - 2014-03-27 -================== - -- Converted README to markdown and added a Quick Guide to the - documentation, which breezes through the most common parts of - xkbcommon. - -- Added two new functions, xkb_state_key_get_utf{8,32}(). They - combine the operations of xkb_state_key_get_syms() and - xkb_keysym_to_utf{8,32}(), and provide a nicer interface for it - (espcially for multiple-keysyms-per-level). - -- The xkb_state_key_get_utf{8,32}() functions now apply Control - transformation: when the Control modifier is active, the string - is converted to an appropriate control character. - This matches the behavior of libX11's XLookupString(3), and - required by the XKB specification: - https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Control_Modifier - - https://bugs.freedesktop.org/show_bug.cgi?id=75892 - -- The consumed modifiers for a key are now calculated similarly - to libX11. The previous behavior caused a bug where Shift would - not cancel an active Caps Lock. - -- Make xkbcommon-x11 work with the keymap reported by the XQuartz - X server. - - https://bugs.freedesktop.org/show_bug.cgi?id=75798 - -- Reduce memory usage during keymap compilation some more. - -- New API: - xkb_state_key_get_consumed_mods() - xkb_state_key_get_utf8() - xkb_state_key_get_utf32() - -- Deprecated API: - XKB_MAP_COMPILE_PLACEHOLDER, XKB_MAP_NO_FLAGS - use XKB_KEYMAP_NO_FLAGS instead. - -- Bug fixes. - - -libxkbcommon 0.4.0 - 2014-02-02 -================== - -- Add a new add-on library, xkbcommon-x11, to support creating keymaps - with the XKB X11 protocol, by querying the X server directly. - See the xkbcommon/xkbcommon-x11.h header file for more details. - This library requires libxcb-xkb >= 1.10, and is enabled by default. - It can be disabled with the --disable-x11 configure switch. - Distributions are encouraged to split the necessary files for this - library (libxkbcommon-x11.so, xkbcommon-x11.pc, xkbcommon/xkbcommon-x11.h) - to a separate package, such that the main package does not depend on - X11 libraries. - -- Fix the keysym <-> name lookup table to not require huge amounts of - relocations. - -- Fix a bug in the keysym <-> name lookup, whereby lookup might fail in - some rare cases. - -- Reduce memory usage during keymap compilation. - -- New API: - New keysyms from xproto 7.0.25 (German T3 layout keysyms). - XKB_MOD_NAME_NUM for the usual NumLock modifier. - xkb_x11_* types and functions, XKB_X11_* constants. - - -libxkbcommon 0.3.2 - 2013-11-22 -================== - -- Log messages from the library now look like "xkbcommon: ERROR" by - default, instead of xkbcomp-like "Error: ". - -- Apply capitalization transformation on keysyms in - xkb_keysym_get_one_sym(), to match the behavior specified in the XKB - specification: - https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Lock_Modifier - -- Support byacc for generating the parser, in addition to Bison. - -- New API: - XKB_KEY_XF86AudioMicMute keysym from xproto 7.0.24. - XKB_KEYSYM_NO_FLAGS - XKB_CONTEXT_NO_FLAGS - XKB_MAP_COMPILE_NO_FLAGS - -- Bug fixes. - - -libxkbcommon 0.3.1 - 2013-06-03 -================== - -- Replace the flex scanner with a hand-written one. flex is no longer - a build requirement. - -- New API: - xkb_keymap_min_keycode() - xkb_keymap_max_keycode() - xkb_keymap_key_for_each() - - -libxkbcommon 0.3.0 - 2013-04-01 -================== - -- Allow passing NULL to *_unref() functions; do nothing instead of - crashing. - -- The functions xkb_keymap_num_levels_for_key() and - xkb_keymap_get_syms_by_level() now allow out-of-range values for the - 'layout' parameter. The functions now wrap the value around the number - of layouts instead of failing. - -- The function xkb_keysym_get_name() now types unicode keysyms in - uppercase and 0-padding, to match the format used by XKeysymToString(). - -- Building Linux-specific tests is no longer attempted on non-Linux - environments. - -- The function xkb_keymap_new_from_names() now accepts a NULL value for - the 'names' parameter, instead of failing. This is equivalent to passing - a 'struct xkb_rule_names' with all fields set to NULL. - -- New API: - xkb_keymap_new_from_buffer() - -- Bug fixes. diff --git a/src/3rdparty/xkbcommon/README.md b/src/3rdparty/xkbcommon/README.md deleted file mode 100644 index b8ae50de77..0000000000 --- a/src/3rdparty/xkbcommon/README.md +++ /dev/null @@ -1,75 +0,0 @@ -# libxkbcommon - -libxkbcommon is a keyboard keymap compiler and support library which -processes a reduced subset of keymaps as defined by the XKB (X Keyboard -Extension) specification. It also contains a module for handling Compose -and dead keys. - -## Quick Guide - -See [Quick Guide](doc/quick-guide.md). - -## Building - -libxkbcommon is built with [Meson](http://mesonbuild.com/): - - meson setup build - ninja -C build - -To build for use with Wayland, you can disable X11 support while still -using the X11 keyboard configuration resource files thusly: - - meson setup build \ - -Denable-x11=false \ - -Dxkb-config-root=/usr/share/X11/xkb \ - -Dx-locale-root=/usr/share/X11/locale - ninja -C build - -## API - -While libxkbcommon's API is somewhat derived from the classic XKB API as found -in X11/extensions/XKB.h and friends, it has been substantially reworked to -expose fewer internal details to clients. - -See the [API Documentation](https://xkbcommon.org/doc/current/modules.html). - -## Dataset - -libxkbcommon does not distribute a keymap dataset itself, other than for -testing purposes. The most common dataset is xkeyboard-config, which is used -by all current distributions for their X11 XKB data. More information on -xkeyboard-config is available here: - https://www.freedesktop.org/wiki/Software/XKeyboardConfig - -The dataset for Compose is distributed in libX11, as part of the X locale -data. - -## Relation to X11 - -See [Compatibility](doc/compat.md) notes. - -## Development - -An extremely rudimentary homepage can be found at - https://xkbcommon.org - -xkbcommon is maintained in git at - https://github.com/xkbcommon/libxkbcommon - -Patches are always welcome, and may be sent to either - or -or through github. - -Bug reports are also welcome, and may be filed either at - Bugzilla https://bugs.freedesktop.org/describecomponents.cgi?product=libxkbcommon -or - Github https://github.com/xkbcommon/libxkbcommon/issues - -The maintainers are -- Daniel Stone -- Ran Benita - -## Credits - -Many thanks are due to Dan Nicholson for his heroic work in getting xkbcommon -off the ground initially. diff --git a/src/3rdparty/xkbcommon/qt_attribution.json b/src/3rdparty/xkbcommon/qt_attribution.json deleted file mode 100644 index 215a4513f3..0000000000 --- a/src/3rdparty/xkbcommon/qt_attribution.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "Id": "xkbcommon", - "Name": "xkbcommon", - "QDocModule": "qtgui", - "QtUsage": "Used in xcb platform plugin. Configure with -system-xkbcommon-x11 to avoid.", - - "Description": "xkbcommon is a keymap compiler and support library which processes a reduced subset of keymaps as defined by the XKB specification.", - "Homepage": "http://xkbcommon.org/", - "Version": "0.8.2 + subsequent commits up to 31f1f355700870c6615399fbfa7934934b3a9a57", - "License": "MIT Licenses (with no-advertisement clause)", - "LicenseId": "MIT", - "LicenseFile": "LICENSE", - "Copyright": "Copyright 2009-2012, 2016 Daniel Stone -Copyright 2012 Ran Benita -Copyright 2010, 2012 Intel Corporation -Copyright 2008, 2009 Dan Nicholson -Copyright 2010 Francisco Jerez -Copyright 1985, 1987, 1988, 1990, 1998 The Open Group -Copyright 1993, 1994, 1995, 1996 by Silicon Graphics Computer Systems, Inc. -Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. -Copyright 2011 Joseph Adams -Copyright 1996 by Joseph Moss -Copyright 2002-2007 Free Software Foundation, Inc. -Copyright 2003-2004 Dmitry Golubev -Copyright 2004, Gregory Mokhin -Copyright 2006 Erdal Ronahî -Copyright 1992 by Oki Technosystems Laboratory, Inc. -Copyright 1992 by Fuji Xerox Co., Ltd." -} diff --git a/src/3rdparty/xkbcommon/src/atom.c b/src/3rdparty/xkbcommon/src/atom.c deleted file mode 100644 index 044f56681a..0000000000 --- a/src/3rdparty/xkbcommon/src/atom.c +++ /dev/null @@ -1,225 +0,0 @@ -/*********************************************************** - * Copyright 1987, 1998 The Open Group - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation. - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name of The Open Group shall not be - * used in advertising or otherwise to promote the sale, use or other dealings - * in this Software without prior written authorization from The Open Group. - * - * - * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. - * - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation, and that the name of Digital not be - * used in advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. - * - * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING - * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL - * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR - * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, - * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - ******************************************************************/ - -/************************************************************ - * Copyright 1994 by Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting - * documentation, and that the name of Silicon Graphics not be - * used in advertising or publicity pertaining to distribution - * of the software without specific prior written permission. - * Silicon Graphics makes no representation about the suitability - * of this software for any purpose. It is provided "as is" - * without any express or implied warranty. - * - * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - * THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - ********************************************************/ - -#include "utils.h" -#include "atom.h" - -struct atom_node { - xkb_atom_t left, right; - xkb_atom_t atom; - unsigned int fingerprint; - char *string; -}; - -struct atom_table { - xkb_atom_t root; - darray(struct atom_node) table; -}; - -struct atom_table * -atom_table_new(void) -{ - struct atom_table *table; - - table = calloc(1, sizeof(*table)); - if (!table) - return NULL; - - darray_init(table->table); - /* The original throw-away root is here, at the illegal atom 0. */ - darray_resize0(table->table, 1); - - return table; -} - -void -atom_table_free(struct atom_table *table) -{ - struct atom_node *node; - - if (!table) - return; - - darray_foreach(node, table->table) - free(node->string); - darray_free(table->table); - free(table); -} - -const char * -atom_text(struct atom_table *table, xkb_atom_t atom) -{ - if (atom == XKB_ATOM_NONE || atom >= darray_size(table->table)) - return NULL; - - return darray_item(table->table, atom).string; -} - -static bool -find_atom_pointer(struct atom_table *table, const char *string, size_t len, - xkb_atom_t **atomp_out, unsigned int *fingerprint_out) -{ - xkb_atom_t *atomp = &table->root; - unsigned int fingerprint = 0; - bool found = false; - - for (size_t i = 0; i < (len + 1) / 2; i++) { - fingerprint = fingerprint * 27 + string[i]; - fingerprint = fingerprint * 27 + string[len - 1 - i]; - } - - while (*atomp != XKB_ATOM_NONE) { - struct atom_node *node = &darray_item(table->table, *atomp); - - if (fingerprint < node->fingerprint) { - atomp = &node->left; - } - else if (fingerprint > node->fingerprint) { - atomp = &node->right; - } - else { - /* Now start testing the strings. */ - const int cmp = strncmp(string, node->string, len); - if (cmp < 0 || (cmp == 0 && len < strlen(node->string))) { - atomp = &node->left; - } - else if (cmp > 0) { - atomp = &node->right; - } - else { - found = true; - break; - } - } - } - - if (fingerprint_out) - *fingerprint_out = fingerprint; - if (atomp_out) - *atomp_out = atomp; - return found; -} - -xkb_atom_t -atom_lookup(struct atom_table *table, const char *string, size_t len) -{ - xkb_atom_t *atomp; - - if (!string) - return XKB_ATOM_NONE; - - if (!find_atom_pointer(table, string, len, &atomp, NULL)) - return XKB_ATOM_NONE; - - return *atomp; -} - -/* - * If steal is true, we do not strdup @string; therefore it must be - * dynamically allocated, NUL-terminated, not be free'd by the caller - * and not be used afterwards. Use to avoid some redundant allocations. - */ -xkb_atom_t -atom_intern(struct atom_table *table, const char *string, size_t len, - bool steal) -{ - xkb_atom_t *atomp; - struct atom_node node; - unsigned int fingerprint; - - if (!string) - return XKB_ATOM_NONE; - - if (find_atom_pointer(table, string, len, &atomp, &fingerprint)) { - if (steal) - free(UNCONSTIFY(string)); - return *atomp; - } - - if (steal) { - node.string = UNCONSTIFY(string); - } - else { - node.string = strndup(string, len); - if (!node.string) - return XKB_ATOM_NONE; - } - - node.left = node.right = XKB_ATOM_NONE; - node.fingerprint = fingerprint; - node.atom = darray_size(table->table); - /* Do this before the append, as it may realloc and change the offsets. */ - *atomp = node.atom; - darray_append(table->table, node); - - return node.atom; -} diff --git a/src/3rdparty/xkbcommon/src/atom.h b/src/3rdparty/xkbcommon/src/atom.h deleted file mode 100644 index 1bf8e49b8e..0000000000 --- a/src/3rdparty/xkbcommon/src/atom.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright © 2009 Dan Nicholson - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef ATOM_H -#define ATOM_H - -typedef uint32_t xkb_atom_t; - -#define XKB_ATOM_NONE 0 - -struct atom_table; - -struct atom_table * -atom_table_new(void); - -void -atom_table_free(struct atom_table *table); - -xkb_atom_t -atom_lookup(struct atom_table *table, const char *string, size_t len); - -xkb_atom_t -atom_intern(struct atom_table *table, const char *string, size_t len, - bool steal); - -const char * -atom_text(struct atom_table *table, xkb_atom_t atom); - -#endif /* ATOM_H */ diff --git a/src/3rdparty/xkbcommon/src/compose/compose-state.c b/src/3rdparty/xkbcommon/src/compose/compose-state.c deleted file mode 100644 index 8657ff7e17..0000000000 --- a/src/3rdparty/xkbcommon/src/compose/compose-state.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright © 2013 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "table.h" -#include "utils.h" -#include "keysym.h" - -struct xkb_compose_state { - int refcnt; - enum xkb_compose_state_flags flags; - struct xkb_compose_table *table; - - /* - * Offsets into xkb_compose_table::nodes. - * - * They maintain the current and previous position in the trie; see - * xkb_compose_state_feed(). - * - * This is also sufficient for inferring the current status; see - * xkb_compose_state_get_status(). - */ - uint32_t prev_context; - uint32_t context; -}; - -XKB_EXPORT struct xkb_compose_state * -xkb_compose_state_new(struct xkb_compose_table *table, - enum xkb_compose_state_flags flags) -{ - struct xkb_compose_state *state; - - state = calloc(1, sizeof(*state)); - if (!state) - return NULL; - - state->refcnt = 1; - state->table = xkb_compose_table_ref(table); - - state->flags = flags; - state->prev_context = 0; - state->context = 0; - - return state; -} - -XKB_EXPORT struct xkb_compose_state * -xkb_compose_state_ref(struct xkb_compose_state *state) -{ - state->refcnt++; - return state; -} - -XKB_EXPORT void -xkb_compose_state_unref(struct xkb_compose_state *state) -{ - if (!state || --state->refcnt > 0) - return; - - xkb_compose_table_unref(state->table); - free(state); -} - -XKB_EXPORT struct xkb_compose_table * -xkb_compose_state_get_compose_table(struct xkb_compose_state *state) -{ - return state->table; -} - -XKB_EXPORT enum xkb_compose_feed_result -xkb_compose_state_feed(struct xkb_compose_state *state, xkb_keysym_t keysym) -{ - uint32_t context; - const struct compose_node *node; - - /* - * Modifiers do not affect the sequence directly. In particular, - * they do not cancel a sequence; otherwise it'd be impossible to - * have a sequence like (needs Shift in the middle). - * - * The following test is not really accurate - in order to test if - * a key is "modifier key", we really need the keymap, but we don't - * have it here. However, this is (approximately) what libX11 does - * as well. - */ - if (xkb_keysym_is_modifier(keysym)) - return XKB_COMPOSE_FEED_IGNORED; - - node = &darray_item(state->table->nodes, state->context); - - context = (node->is_leaf ? 0 : node->u.successor); - node = &darray_item(state->table->nodes, context); - - while (node->keysym != keysym && node->next != 0) { - context = node->next; - node = &darray_item(state->table->nodes, context); - } - - if (node->keysym != keysym) - context = 0; - - state->prev_context = state->context; - state->context = context; - return XKB_COMPOSE_FEED_ACCEPTED; -} - -XKB_EXPORT void -xkb_compose_state_reset(struct xkb_compose_state *state) -{ - state->prev_context = 0; - state->context = 0; -} - -XKB_EXPORT enum xkb_compose_status -xkb_compose_state_get_status(struct xkb_compose_state *state) -{ - const struct compose_node *prev_node, *node; - - prev_node = &darray_item(state->table->nodes, state->prev_context); - node = &darray_item(state->table->nodes, state->context); - - if (state->context == 0 && !prev_node->is_leaf) - return XKB_COMPOSE_CANCELLED; - - if (state->context == 0) - return XKB_COMPOSE_NOTHING; - - if (!node->is_leaf) - return XKB_COMPOSE_COMPOSING; - - return XKB_COMPOSE_COMPOSED; -} - -XKB_EXPORT int -xkb_compose_state_get_utf8(struct xkb_compose_state *state, - char *buffer, size_t size) -{ - const struct compose_node *node = - &darray_item(state->table->nodes, state->context); - - if (!node->is_leaf) - goto fail; - - /* If there's no string specified, but only a keysym, try to do the - * most helpful thing. */ - if (node->u.leaf.utf8 == 0 && node->u.leaf.keysym != XKB_KEY_NoSymbol) { - char name[64]; - int ret; - - ret = xkb_keysym_to_utf8(node->u.leaf.keysym, name, sizeof(name)); - if (ret < 0 || ret == 0) { - /* ret < 0 is impossible. - * ret == 0 means the keysym has no string representation. */ - goto fail; - } - - return snprintf(buffer, size, "%s", name); - } - - return snprintf(buffer, size, "%s", - &darray_item(state->table->utf8, node->u.leaf.utf8)); - -fail: - if (size > 0) - buffer[0] = '\0'; - return 0; -} - -XKB_EXPORT xkb_keysym_t -xkb_compose_state_get_one_sym(struct xkb_compose_state *state) -{ - const struct compose_node *node = - &darray_item(state->table->nodes, state->context); - if (!node->is_leaf) - return XKB_KEY_NoSymbol; - return node->u.leaf.keysym; -} diff --git a/src/3rdparty/xkbcommon/src/compose/parser.c b/src/3rdparty/xkbcommon/src/compose/parser.c deleted file mode 100644 index 439d404f06..0000000000 --- a/src/3rdparty/xkbcommon/src/compose/parser.c +++ /dev/null @@ -1,737 +0,0 @@ -/* - * Copyright © 2013 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -/****************************************************************** - - Copyright 1992 by Oki Technosystems Laboratory, Inc. - Copyright 1992 by Fuji Xerox Co., Ltd. - -Permission to use, copy, modify, distribute, and sell this software -and its documentation for any purpose is hereby granted without fee, -provided that the above copyright notice appear in all copies and -that both that copyright notice and this permission notice appear -in supporting documentation, and that the name of Oki Technosystems -Laboratory and Fuji Xerox not be used in advertising or publicity -pertaining to distribution of the software without specific, written -prior permission. -Oki Technosystems Laboratory and Fuji Xerox make no representations -about the suitability of this software for any purpose. It is provided -"as is" without express or implied warranty. - -OKI TECHNOSYSTEMS LABORATORY AND FUJI XEROX DISCLAIM ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL OKI TECHNOSYSTEMS -LABORATORY AND FUJI XEROX BE LIABLE FOR ANY SPECIAL, INDIRECT OR -CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE -OR PERFORMANCE OF THIS SOFTWARE. - - Author: Yasuhiro Kawai Oki Technosystems Laboratory - Author: Kazunori Nishihara Fuji Xerox - -******************************************************************/ - -#include - -#include "utils.h" -#include "scanner-utils.h" -#include "table.h" -#include "paths.h" -#include "utf8.h" -#include "parser.h" - -#define MAX_LHS_LEN 10 -#define MAX_INCLUDE_DEPTH 5 - -/* - * Grammar adapted from libX11/modules/im/ximcp/imLcPrs.c. - * See also the XCompose(5) manpage. - * - * FILE ::= { [PRODUCTION] [COMMENT] "\n" | INCLUDE } - * INCLUDE ::= "include" '"' INCLUDE_STRING '"' - * PRODUCTION ::= LHS ":" RHS [ COMMENT ] - * COMMENT ::= "#" {} - * LHS ::= EVENT { EVENT } - * EVENT ::= [MODIFIER_LIST] "<" keysym ">" - * MODIFIER_LIST ::= (["!"] {MODIFIER} ) | "None" - * MODIFIER ::= ["~"] MODIFIER_NAME - * MODIFIER_NAME ::= ("Ctrl"|"Lock"|"Caps"|"Shift"|"Alt"|"Meta") - * RHS ::= ( STRING | keysym | STRING keysym ) - * STRING ::= '"' { CHAR } '"' - * CHAR ::= GRAPHIC_CHAR | ESCAPED_CHAR - * GRAPHIC_CHAR ::= locale (codeset) dependent code - * ESCAPED_CHAR ::= ('\\' | '\"' | OCTAL | HEX ) - * OCTAL ::= '\' OCTAL_CHAR [OCTAL_CHAR [OCTAL_CHAR]] - * OCTAL_CHAR ::= (0|1|2|3|4|5|6|7) - * HEX ::= '\' (x|X) HEX_CHAR [HEX_CHAR]] - * HEX_CHAR ::= (0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F|a|b|c|d|e|f) - * - * INCLUDE_STRING is a filesystem path, with the following %-expansions: - * %% - '%'. - * %H - The user's home directory (the $HOME environment variable). - * %L - The name of the locale specific Compose file (e.g., - * "/usr/share/X11/locale//Compose"). - * %S - The name of the system directory for Compose files (e.g., - * "/usr/share/X11/locale"). - */ - -enum rules_token { - TOK_END_OF_FILE = 0, - TOK_END_OF_LINE, - TOK_INCLUDE, - TOK_INCLUDE_STRING, - TOK_LHS_KEYSYM, - TOK_COLON, - TOK_BANG, - TOK_TILDE, - TOK_STRING, - TOK_IDENT, - TOK_ERROR -}; - -/* Values returned with some tokens, like yylval. */ -union lvalue { - struct { - /* Still \0-terminated. */ - const char *str; - size_t len; - } string; -}; - -static enum rules_token -lex(struct scanner *s, union lvalue *val) -{ -skip_more_whitespace_and_comments: - /* Skip spaces. */ - while (is_space(peek(s))) - if (next(s) == '\n') - return TOK_END_OF_LINE; - - /* Skip comments. */ - if (chr(s, '#')) { - skip_to_eol(s); - goto skip_more_whitespace_and_comments; - } - - /* See if we're done. */ - if (eof(s)) return TOK_END_OF_FILE; - - /* New token. */ - s->token_line = s->line; - s->token_column = s->column; - s->buf_pos = 0; - - /* LHS Keysym. */ - if (chr(s, '<')) { - while (peek(s) != '>' && !eol(s) && !eof(s)) - buf_append(s, next(s)); - if (!chr(s, '>')) { - scanner_err(s, "unterminated keysym literal"); - return TOK_ERROR; - } - if (!buf_append(s, '\0')) { - scanner_err(s, "keysym literal is too long"); - return TOK_ERROR; - } - val->string.str = s->buf; - val->string.len = s->buf_pos; - return TOK_LHS_KEYSYM; - } - - /* Colon. */ - if (chr(s, ':')) - return TOK_COLON; - if (chr(s, '!')) - return TOK_BANG; - if (chr(s, '~')) - return TOK_TILDE; - - /* String literal. */ - if (chr(s, '\"')) { - while (!eof(s) && !eol(s) && peek(s) != '\"') { - if (chr(s, '\\')) { - uint8_t o; - if (chr(s, '\\')) { - buf_append(s, '\\'); - } - else if (chr(s, '"')) { - buf_append(s, '"'); - } - else if (chr(s, 'x') || chr(s, 'X')) { - if (hex(s, &o)) - buf_append(s, (char) o); - else - scanner_warn(s, "illegal hexadecimal escape sequence in string literal"); - } - else if (oct(s, &o)) { - buf_append(s, (char) o); - } - else { - scanner_warn(s, "unknown escape sequence (%c) in string literal", peek(s)); - /* Ignore. */ - } - } else { - buf_append(s, next(s)); - } - } - if (!chr(s, '\"')) { - scanner_err(s, "unterminated string literal"); - return TOK_ERROR; - } - if (!buf_append(s, '\0')) { - scanner_err(s, "string literal is too long"); - return TOK_ERROR; - } - if (!is_valid_utf8(s->buf, s->buf_pos - 1)) { - scanner_err(s, "string literal is not a valid UTF-8 string"); - return TOK_ERROR; - } - val->string.str = s->buf; - val->string.len = s->buf_pos; - return TOK_STRING; - } - - /* Identifier or include. */ - if (is_alpha(peek(s)) || peek(s) == '_') { - s->buf_pos = 0; - while (is_alnum(peek(s)) || peek(s) == '_') - buf_append(s, next(s)); - if (!buf_append(s, '\0')) { - scanner_err(s, "identifier is too long"); - return TOK_ERROR; - } - - if (streq(s->buf, "include")) - return TOK_INCLUDE; - - val->string.str = s->buf; - val->string.len = s->buf_pos; - return TOK_IDENT; - } - - /* Discard rest of line. */ - skip_to_eol(s); - - scanner_err(s, "unrecognized token"); - return TOK_ERROR; -} - -static enum rules_token -lex_include_string(struct scanner *s, struct xkb_compose_table *table, - union lvalue *val_out) -{ - while (is_space(peek(s))) - if (next(s) == '\n') - return TOK_END_OF_LINE; - - s->token_line = s->line; - s->token_column = s->column; - s->buf_pos = 0; - - if (!chr(s, '\"')) { - scanner_err(s, "include statement must be followed by a path"); - return TOK_ERROR; - } - - while (!eof(s) && !eol(s) && peek(s) != '\"') { - if (chr(s, '%')) { - if (chr(s, '%')) { - buf_append(s, '%'); - } - else if (chr(s, 'H')) { - const char *home = secure_getenv("HOME"); - if (!home) { - scanner_err(s, "%%H was used in an include statement, but the HOME environment variable is not set"); - return TOK_ERROR; - } - if (!buf_appends(s, home)) { - scanner_err(s, "include path after expanding %%H is too long"); - return TOK_ERROR; - } - } - else if (chr(s, 'L')) { - char *path = get_locale_compose_file_path(table->locale); - if (!path) { - scanner_err(s, "failed to expand %%L to the locale Compose file"); - return TOK_ERROR; - } - if (!buf_appends(s, path)) { - free(path); - scanner_err(s, "include path after expanding %%L is too long"); - return TOK_ERROR; - } - free(path); - } - else if (chr(s, 'S')) { - const char *xlocaledir = get_xlocaledir_path(); - if (!buf_appends(s, xlocaledir)) { - scanner_err(s, "include path after expanding %%S is too long"); - return TOK_ERROR; - } - } - else { - scanner_err(s, "unknown %% format (%c) in include statement", peek(s)); - return TOK_ERROR; - } - } else { - buf_append(s, next(s)); - } - } - if (!chr(s, '\"')) { - scanner_err(s, "unterminated include statement"); - return TOK_ERROR; - } - if (!buf_append(s, '\0')) { - scanner_err(s, "include path is too long"); - return TOK_ERROR; - } - val_out->string.str = s->buf; - val_out->string.len = s->buf_pos; - return TOK_INCLUDE_STRING; -} - -struct production { - xkb_keysym_t lhs[MAX_LHS_LEN]; - unsigned int len; - xkb_keysym_t keysym; - char string[256]; - /* At least one of these is true. */ - bool has_keysym; - bool has_string; - - /* The matching is as follows: (active_mods & modmask) == mods. */ - xkb_mod_mask_t modmask; - xkb_mod_mask_t mods; -}; - -static uint32_t -add_node(struct xkb_compose_table *table, xkb_keysym_t keysym) -{ - struct compose_node new = { - .keysym = keysym, - .next = 0, - .is_leaf = true, - }; - darray_append(table->nodes, new); - return darray_size(table->nodes) - 1; -} - -static void -add_production(struct xkb_compose_table *table, struct scanner *s, - const struct production *production) -{ - unsigned lhs_pos; - uint32_t curr; - struct compose_node *node; - - curr = 0; - node = &darray_item(table->nodes, curr); - - /* - * Insert the sequence to the trie, creating new nodes as needed. - * - * TODO: This can be sped up a bit by first trying the path that the - * previous production took, and only then doing the linear search - * through the trie levels. This will work because sequences in the - * Compose files are often clustered by a common prefix; especially - * in the 1st and 2nd keysyms, which is where the largest variation - * (thus, longest search) is. - */ - for (lhs_pos = 0; lhs_pos < production->len; lhs_pos++) { - while (production->lhs[lhs_pos] != node->keysym) { - if (node->next == 0) { - uint32_t next = add_node(table, production->lhs[lhs_pos]); - /* Refetch since add_node could have realloc()ed. */ - node = &darray_item(table->nodes, curr); - node->next = next; - } - - curr = node->next; - node = &darray_item(table->nodes, curr); - } - - if (lhs_pos + 1 == production->len) - break; - - if (node->is_leaf) { - if (node->u.leaf.utf8 != 0 || - node->u.leaf.keysym != XKB_KEY_NoSymbol) { - scanner_warn(s, "a sequence already exists which is a prefix of this sequence; overriding"); - node->u.leaf.utf8 = 0; - node->u.leaf.keysym = XKB_KEY_NoSymbol; - } - - { - uint32_t successor = add_node(table, production->lhs[lhs_pos + 1]); - /* Refetch since add_node could have realloc()ed. */ - node = &darray_item(table->nodes, curr); - node->is_leaf = false; - node->u.successor = successor; - } - } - - curr = node->u.successor; - node = &darray_item(table->nodes, curr); - } - - if (!node->is_leaf) { - scanner_warn(s, "this compose sequence is a prefix of another; skipping line"); - return; - } - - if (node->u.leaf.utf8 != 0 || node->u.leaf.keysym != XKB_KEY_NoSymbol) { - bool same_string = - (node->u.leaf.utf8 == 0 && !production->has_string) || - ( - node->u.leaf.utf8 != 0 && production->has_string && - streq(&darray_item(table->utf8, node->u.leaf.utf8), - production->string) - ); - bool same_keysym = - (node->u.leaf.keysym == XKB_KEY_NoSymbol && !production->has_keysym) || - ( - node->u.leaf.keysym != XKB_KEY_NoSymbol && production->has_keysym && - node->u.leaf.keysym == production->keysym - ); - if (same_string && same_keysym) { - scanner_warn(s, "this compose sequence is a duplicate of another; skipping line"); - return; - } - scanner_warn(s, "this compose sequence already exists; overriding"); - } - - if (production->has_string) { - node->u.leaf.utf8 = darray_size(table->utf8); - darray_append_items(table->utf8, production->string, - strlen(production->string) + 1); - } - if (production->has_keysym) { - node->u.leaf.keysym = production->keysym; - } -} - -/* Should match resolve_modifier(). */ -#define ALL_MODS_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)) - -static xkb_mod_index_t -resolve_modifier(const char *name) -{ - static const struct { - const char *name; - xkb_mod_index_t mod; - } mods[] = { - { "Shift", 0 }, - { "Ctrl", 2 }, - { "Alt", 3 }, - { "Meta", 3 }, - { "Lock", 1 }, - { "Caps", 1 }, - }; - - for (unsigned i = 0; i < ARRAY_SIZE(mods); i++) - if (streq(name, mods[i].name)) - return mods[i].mod; - - return XKB_MOD_INVALID; -} - -static bool -parse(struct xkb_compose_table *table, struct scanner *s, - unsigned include_depth); - -static bool -do_include(struct xkb_compose_table *table, struct scanner *s, - const char *path, unsigned include_depth) -{ - FILE *file; - bool ok; - char *string; - size_t size; - struct scanner new_s; - - if (include_depth >= MAX_INCLUDE_DEPTH) { - scanner_err(s, "maximum include depth (%d) exceeded; maybe there is an include loop?", - MAX_INCLUDE_DEPTH); - return false; - } - - file = fopen(path, "r"); - if (!file) { - scanner_err(s, "failed to open included Compose file \"%s\": %s", - path, strerror(errno)); - return false; - } - - ok = map_file(file, &string, &size); - if (!ok) { - scanner_err(s, "failed to read included Compose file \"%s\": %s", - path, strerror(errno)); - goto err_file; - } - - scanner_init(&new_s, table->ctx, string, size, path, s->priv); - - ok = parse(table, &new_s, include_depth + 1); - if (!ok) - goto err_unmap; - -err_unmap: - unmap_file(string, size); -err_file: - fclose(file); - return ok; -} - -static bool -parse(struct xkb_compose_table *table, struct scanner *s, - unsigned include_depth) -{ - enum rules_token tok; - union lvalue val; - xkb_keysym_t keysym; - struct production production; - enum { MAX_ERRORS = 10 }; - int num_errors = 0; - -initial: - production.len = 0; - production.has_keysym = false; - production.has_string = false; - production.mods = 0; - production.modmask = 0; - - /* fallthrough */ - -initial_eol: - switch (tok = lex(s, &val)) { - case TOK_END_OF_LINE: - goto initial_eol; - case TOK_END_OF_FILE: - goto finished; - case TOK_INCLUDE: - goto include; - default: - goto lhs_tok; - } - -include: - switch (tok = lex_include_string(s, table, &val)) { - case TOK_INCLUDE_STRING: - goto include_eol; - default: - goto unexpected; - } - -include_eol: - switch (tok = lex(s, &val)) { - case TOK_END_OF_LINE: - if (!do_include(table, s, val.string.str, include_depth)) - goto fail; - goto initial; - default: - goto unexpected; - } - -lhs: - tok = lex(s, &val); -lhs_tok: - switch (tok) { - case TOK_COLON: - if (production.len <= 0) { - scanner_warn(s, "expected at least one keysym on left-hand side; skipping line"); - goto skip; - } - goto rhs; - case TOK_IDENT: - if (streq(val.string.str, "None")) { - production.mods = 0; - production.modmask = ALL_MODS_MASK; - goto lhs_keysym; - } - goto lhs_mod_list_tok; - case TOK_TILDE: - goto lhs_mod_list_tok; - case TOK_BANG: - production.modmask = ALL_MODS_MASK; - goto lhs_mod_list; - default: - goto lhs_keysym_tok; - } - -lhs_keysym: - tok = lex(s, &val); -lhs_keysym_tok: - switch (tok) { - case TOK_LHS_KEYSYM: - keysym = xkb_keysym_from_name(val.string.str, XKB_KEYSYM_NO_FLAGS); - if (keysym == XKB_KEY_NoSymbol) { - scanner_err(s, "unrecognized keysym \"%s\" on left-hand side", - val.string.str); - goto error; - } - if (production.len + 1 > MAX_LHS_LEN) { - scanner_warn(s, "too many keysyms (%d) on left-hand side; skipping line", - MAX_LHS_LEN + 1); - goto skip; - } - production.lhs[production.len++] = keysym; - production.mods = 0; - production.modmask = 0; - goto lhs; - default: - goto unexpected; - } - -lhs_mod_list: - tok = lex(s, &val); -lhs_mod_list_tok: { - bool tilde = false; - xkb_mod_index_t mod; - - if (tok != TOK_TILDE && tok != TOK_IDENT) - goto lhs_keysym_tok; - - if (tok == TOK_TILDE) { - tilde = true; - tok = lex(s, &val); - } - - if (tok != TOK_IDENT) - goto unexpected; - - mod = resolve_modifier(val.string.str); - if (mod == XKB_MOD_INVALID) { - scanner_err(s, "unrecognized modifier \"%s\"", - val.string.str); - goto error; - } - - production.modmask |= 1 << mod; - if (tilde) - production.mods &= ~(1 << mod); - else - production.mods |= 1 << mod; - - goto lhs_mod_list; - } - -rhs: - switch (tok = lex(s, &val)) { - case TOK_STRING: - if (production.has_string) { - scanner_warn(s, "right-hand side can have at most one string; skipping line"); - goto skip; - } - if (val.string.len <= 0) { - scanner_warn(s, "right-hand side string must not be empty; skipping line"); - goto skip; - } - if (val.string.len >= sizeof(production.string)) { - scanner_warn(s, "right-hand side string is too long; skipping line"); - goto skip; - } - strcpy(production.string, val.string.str); - production.has_string = true; - goto rhs; - case TOK_IDENT: - keysym = xkb_keysym_from_name(val.string.str, XKB_KEYSYM_NO_FLAGS); - if (keysym == XKB_KEY_NoSymbol) { - scanner_err(s, "unrecognized keysym \"%s\" on right-hand side", - val.string.str); - goto error; - } - if (production.has_keysym) { - scanner_warn(s, "right-hand side can have at most one keysym; skipping line"); - goto skip; - } - production.keysym = keysym; - production.has_keysym = true; - /* fallthrough */ - case TOK_END_OF_LINE: - if (!production.has_string && !production.has_keysym) { - scanner_warn(s, "right-hand side must have at least one of string or keysym; skipping line"); - goto skip; - } - add_production(table, s, &production); - goto initial; - default: - goto unexpected; - } - -unexpected: - if (tok != TOK_ERROR) - scanner_err(s, "unexpected token"); -error: - num_errors++; - if (num_errors <= MAX_ERRORS) - goto skip; - - scanner_err(s, "too many errors"); - goto fail; - -fail: - scanner_err(s, "failed to parse file"); - return false; - -skip: - while (tok != TOK_END_OF_LINE && tok != TOK_END_OF_FILE) - tok = lex(s, &val); - goto initial; - -finished: - return true; -} - -bool -parse_string(struct xkb_compose_table *table, const char *string, size_t len, - const char *file_name) -{ - struct scanner s; - scanner_init(&s, table->ctx, string, len, file_name, NULL); - if (!parse(table, &s, 0)) - return false; - /* Maybe the allocator can use the excess space. */ - darray_shrink(table->nodes); - darray_shrink(table->utf8); - return true; -} - -bool -parse_file(struct xkb_compose_table *table, FILE *file, const char *file_name) -{ - bool ok; - char *string; - size_t size; - - ok = map_file(file, &string, &size); - if (!ok) { - log_err(table->ctx, "Couldn't read Compose file %s: %s\n", - file_name, strerror(errno)); - return false; - } - - ok = parse_string(table, string, size, file_name); - unmap_file(string, size); - return ok; -} diff --git a/src/3rdparty/xkbcommon/src/compose/parser.h b/src/3rdparty/xkbcommon/src/compose/parser.h deleted file mode 100644 index 3f64a07402..0000000000 --- a/src/3rdparty/xkbcommon/src/compose/parser.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright © 2013 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef COMPOSE_PARSER_H -#define COMPOSE_PARSER_H - -bool -parse_string(struct xkb_compose_table *table, - const char *string, size_t len, - const char *file_name); - -bool -parse_file(struct xkb_compose_table *table, - FILE *file, const char *file_name); - -#endif diff --git a/src/3rdparty/xkbcommon/src/compose/paths.c b/src/3rdparty/xkbcommon/src/compose/paths.c deleted file mode 100644 index e9d43d7e44..0000000000 --- a/src/3rdparty/xkbcommon/src/compose/paths.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright © 2014 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "utils.h" -#include "paths.h" - -enum resolve_name_direction { - LEFT_TO_RIGHT, - RIGHT_TO_LEFT, -}; - -const char * -get_xlocaledir_path(void) -{ - const char *dir = secure_getenv("XLOCALEDIR"); - if (!dir) - dir = XLOCALEDIR; - return dir; -} - -/* - * Files like compose.dir have the format LEFT: RIGHT. Lookup @name in - * such a file and return its matching value, according to @direction. - * @filename is relative to the xlocaledir. - */ -static char * -resolve_name(const char *filename, enum resolve_name_direction direction, - const char *name) -{ - int ret; - bool ok; - const char *xlocaledir; - char path[512]; - FILE *file; - char *string; - size_t string_size; - const char *end; - const char *s, *left, *right; - char *match; - size_t left_len, right_len, name_len; - - xlocaledir = get_xlocaledir_path(); - - ret = snprintf(path, sizeof(path), "%s/%s", xlocaledir, filename); - if (ret < 0 || (size_t) ret >= sizeof(path)) - return false; - - file = fopen(path, "r"); - if (!file) - return false; - - ok = map_file(file, &string, &string_size); - fclose(file); - if (!ok) - return false; - - s = string; - end = string + string_size; - name_len = strlen(name); - match = NULL; - - while (s < end) { - /* Skip spaces. */ - while (s < end && is_space(*s)) - s++; - - /* Skip comments. */ - if (s < end && *s == '#') { - while (s < end && *s != '\n') - s++; - continue; - } - - /* Get the left value. */ - left = s; - while (s < end && !is_space(*s) && *s != ':') - s++; - left_len = s - left; - - /* There's an optional colon between left and right. */ - if (s < end && *s == ':') - s++; - - /* Skip spaces. */ - while (s < end && is_space(*s)) - s++; - - /* Get the right value. */ - right = s; - while (s < end && !is_space(*s)) - s++; - right_len = s - right; - - /* Discard rest of line. */ - while (s < end && *s != '\n') - s++; - - if (direction == LEFT_TO_RIGHT) { - if (left_len == name_len && memcmp(left, name, left_len) == 0) { - match = strndup(right, right_len); - break; - } - } - else if (direction == RIGHT_TO_LEFT) { - if (right_len == name_len && memcmp(right, name, right_len) == 0) { - match = strndup(left, left_len); - break; - } - } - } - - unmap_file(string, string_size); - return match; -} - -char * -resolve_locale(const char *locale) -{ - char *alias = resolve_name("locale.alias", LEFT_TO_RIGHT, locale); - return alias ? alias : strdup(locale); -} - -const char * -get_xcomposefile_path(void) -{ - return secure_getenv("XCOMPOSEFILE"); -} - -char * -get_home_xcompose_file_path(void) -{ - int ret; - const char *home; - char *path; - - home = secure_getenv("HOME"); - if (!home) - return NULL; - - ret = asprintf(&path, "%s/.XCompose", home); - if (ret <0) - return NULL; - - return path; -} - -char * -get_locale_compose_file_path(const char *locale) -{ - char *resolved; - char *path; - - /* - * WARNING: Random workaround ahead. - * - * We currently do not support non-UTF-8 Compose files. The C/POSIX - * locale is specified to be the default fallback locale with an - * ASCII charset. But for some reason the compose.dir points the C - * locale to the iso8859-1/Compose file, which is not ASCII but - * ISO8859-1. Since this is bound to happen a lot, and since our API - * is UTF-8 based, and since 99% of the time a C locale is really just - * a misconfiguration for UTF-8, let's do the most helpful thing. - */ - if (streq(locale, "C")) - locale = "en_US.UTF-8"; - - resolved = resolve_name("compose.dir", RIGHT_TO_LEFT, locale); - if (!resolved) - return NULL; - - if (resolved[0] == '/') { - path = resolved; - } - else { - const char *xlocaledir = get_xlocaledir_path(); - int ret = asprintf(&path, "%s/%s", xlocaledir, resolved); - free(resolved); - if (ret < 0) - return NULL; - } - - return path; -} diff --git a/src/3rdparty/xkbcommon/src/compose/paths.h b/src/3rdparty/xkbcommon/src/compose/paths.h deleted file mode 100644 index 1d719af1b9..0000000000 --- a/src/3rdparty/xkbcommon/src/compose/paths.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright © 2014 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef COMPOSE_RESOLVE_H -#define COMPOSE_RESOLVE_H - -char * -resolve_locale(const char *locale); - -const char * -get_xlocaledir_path(void); - -const char * -get_xcomposefile_path(void); - -char * -get_home_xcompose_file_path(void); - -char * -get_locale_compose_file_path(const char *locale); - -#endif diff --git a/src/3rdparty/xkbcommon/src/compose/table.c b/src/3rdparty/xkbcommon/src/compose/table.c deleted file mode 100644 index 5cd8415850..0000000000 --- a/src/3rdparty/xkbcommon/src/compose/table.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright © 2013 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "utils.h" -#include "table.h" -#include "parser.h" -#include "paths.h" - -static struct xkb_compose_table * -xkb_compose_table_new(struct xkb_context *ctx, - const char *locale, - enum xkb_compose_format format, - enum xkb_compose_compile_flags flags) -{ - char *resolved_locale; - struct xkb_compose_table *table; - struct compose_node root; - - resolved_locale = resolve_locale(locale); - if (!resolved_locale) - return NULL; - - table = calloc(1, sizeof(*table)); - if (!table) { - free(resolved_locale); - return NULL; - } - - table->refcnt = 1; - table->ctx = xkb_context_ref(ctx); - - table->locale = resolved_locale; - table->format = format; - table->flags = flags; - - darray_init(table->nodes); - darray_init(table->utf8); - - root.keysym = XKB_KEY_NoSymbol; - root.next = 0; - root.is_leaf = true; - root.u.leaf.utf8 = 0; - root.u.leaf.keysym = XKB_KEY_NoSymbol; - darray_append(table->nodes, root); - - darray_append(table->utf8, '\0'); - - return table; -} - -XKB_EXPORT struct xkb_compose_table * -xkb_compose_table_ref(struct xkb_compose_table *table) -{ - table->refcnt++; - return table; -} - -XKB_EXPORT void -xkb_compose_table_unref(struct xkb_compose_table *table) -{ - if (!table || --table->refcnt > 0) - return; - free(table->locale); - darray_free(table->nodes); - darray_free(table->utf8); - xkb_context_unref(table->ctx); - free(table); -} - -XKB_EXPORT struct xkb_compose_table * -xkb_compose_table_new_from_file(struct xkb_context *ctx, - FILE *file, - const char *locale, - enum xkb_compose_format format, - enum xkb_compose_compile_flags flags) -{ - struct xkb_compose_table *table; - bool ok; - - if (flags & ~(XKB_COMPOSE_COMPILE_NO_FLAGS)) { - log_err_func(ctx, "unrecognized flags: %#x\n", flags); - return NULL; - } - - if (format != XKB_COMPOSE_FORMAT_TEXT_V1) { - log_err_func(ctx, "unsupported compose format: %d\n", format); - return NULL; - } - - table = xkb_compose_table_new(ctx, locale, format, flags); - if (!table) - return NULL; - - ok = parse_file(table, file, "(unknown file)"); - if (!ok) { - xkb_compose_table_unref(table); - return NULL; - } - - return table; -} - -XKB_EXPORT struct xkb_compose_table * -xkb_compose_table_new_from_buffer(struct xkb_context *ctx, - const char *buffer, size_t length, - const char *locale, - enum xkb_compose_format format, - enum xkb_compose_compile_flags flags) -{ - struct xkb_compose_table *table; - bool ok; - - if (flags & ~(XKB_COMPOSE_COMPILE_NO_FLAGS)) { - log_err_func(ctx, "unrecognized flags: %#x\n", flags); - return NULL; - } - - if (format != XKB_COMPOSE_FORMAT_TEXT_V1) { - log_err_func(ctx, "unsupported compose format: %d\n", format); - return NULL; - } - - table = xkb_compose_table_new(ctx, locale, format, flags); - if (!table) - return NULL; - - ok = parse_string(table, buffer, length, "(input string)"); - if (!ok) { - xkb_compose_table_unref(table); - return NULL; - } - - return table; -} - -XKB_EXPORT struct xkb_compose_table * -xkb_compose_table_new_from_locale(struct xkb_context *ctx, - const char *locale, - enum xkb_compose_compile_flags flags) -{ - struct xkb_compose_table *table; - char *path = NULL; - const char *cpath; - FILE *file; - bool ok; - - if (flags & ~(XKB_COMPOSE_COMPILE_NO_FLAGS)) { - log_err_func(ctx, "unrecognized flags: %#x\n", flags); - return NULL; - } - - table = xkb_compose_table_new(ctx, locale, XKB_COMPOSE_FORMAT_TEXT_V1, - flags); - if (!table) - return NULL; - - cpath = get_xcomposefile_path(); - if (cpath) { - file = fopen(cpath, "r"); - if (file) - goto found_path; - } - - cpath = path = get_home_xcompose_file_path(); - if (path) { - file = fopen(path, "r"); - if (file) - goto found_path; - } - free(path); - path = NULL; - - cpath = path = get_locale_compose_file_path(table->locale); - if (path) { - file = fopen(path, "r"); - if (file) - goto found_path; - } - free(path); - path = NULL; - - log_err(ctx, "couldn't find a Compose file for locale \"%s\"\n", locale); - xkb_compose_table_unref(table); - return NULL; - -found_path: - ok = parse_file(table, file, cpath); - fclose(file); - if (!ok) { - xkb_compose_table_unref(table); - return NULL; - } - - log_dbg(ctx, "created compose table from locale %s with path %s\n", - table->locale, path); - - free(path); - return table; -} diff --git a/src/3rdparty/xkbcommon/src/compose/table.h b/src/3rdparty/xkbcommon/src/compose/table.h deleted file mode 100644 index 05a415ffa3..0000000000 --- a/src/3rdparty/xkbcommon/src/compose/table.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright © 2013 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef COMPOSE_COMPOSE_H -#define COMPOSE_COMPOSE_H - -#include "xkbcommon/xkbcommon-compose.h" -#include "utils.h" -#include "context.h" - -/* - * The compose table data structure is a simple trie. An example will - * help. Given these sequences: - * - * : "first" dead_a - * : "second" dead_b - * : "third" dead_c - * - * the trie would look like: - * - * [root] ---> [] -----------------> [] -# - * | | | - * # v v - * [] ---> [] -# [] -# - * | | - - * # v # - * [] -# - * | - * # - * where: - * - [root] is a special empty root node. - * - [] is a node for a sequence keysym . - * - right arrows are `next` pointers. - * - down arrows are `successor` pointers. - * - # is a nil pointer. - * - * The nodes are all kept in a contiguous array. Pointers are represented - * as integer offsets into this array. A nil pointer is represented as 0 - * (which, helpfully, is the offset of the empty root node). - * - * Nodes without a successor are leaf nodes. Since a sequence cannot be a - * prefix of another, these are exactly the nodes which terminate the - * sequences (in a bijective manner). - * - * A leaf contains the result data of its sequence. The result keysym is - * contained in the node struct itself; the result UTF-8 string is a byte - * offset into an array of the form "\0first\0second\0third" (the initial - * \0 is so offset 0 points to an empty string). - */ - -struct compose_node { - xkb_keysym_t keysym; - /* Offset into xkb_compose_table::nodes. */ - unsigned int next:31; - bool is_leaf:1; - - union { - /* Offset into xkb_compose_table::nodes. */ - uint32_t successor; - struct { - /* Offset into xkb_compose_table::utf8. */ - uint32_t utf8; - xkb_keysym_t keysym; - } leaf; - } u; -}; - -struct xkb_compose_table { - int refcnt; - enum xkb_compose_format format; - enum xkb_compose_compile_flags flags; - struct xkb_context *ctx; - - char *locale; - - darray_char utf8; - darray(struct compose_node) nodes; -}; - -#endif diff --git a/src/3rdparty/xkbcommon/src/context-priv.c b/src/3rdparty/xkbcommon/src/context-priv.c deleted file mode 100644 index c934201685..0000000000 --- a/src/3rdparty/xkbcommon/src/context-priv.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright © 2012 Intel Corporation - * Copyright © 2012 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Daniel Stone - */ - -#include -#include -#include -#include - -#include "xkbcommon/xkbcommon.h" -#include "utils.h" -#include "context.h" - -unsigned int -xkb_context_num_failed_include_paths(struct xkb_context *ctx) -{ - return darray_size(ctx->failed_includes); -} - -const char * -xkb_context_failed_include_path_get(struct xkb_context *ctx, - unsigned int idx) -{ - if (idx >= xkb_context_num_failed_include_paths(ctx)) - return NULL; - - return darray_item(ctx->failed_includes, idx); -} - -xkb_atom_t -xkb_atom_lookup(struct xkb_context *ctx, const char *string) -{ - return atom_lookup(ctx->atom_table, string, strlen(string)); -} - -xkb_atom_t -xkb_atom_intern(struct xkb_context *ctx, const char *string, size_t len) -{ - return atom_intern(ctx->atom_table, string, len, false); -} - -xkb_atom_t -xkb_atom_steal(struct xkb_context *ctx, char *string) -{ - return atom_intern(ctx->atom_table, string, strlen(string), true); -} - -const char * -xkb_atom_text(struct xkb_context *ctx, xkb_atom_t atom) -{ - return atom_text(ctx->atom_table, atom); -} - -void -xkb_log(struct xkb_context *ctx, enum xkb_log_level level, int verbosity, - const char *fmt, ...) -{ - va_list args; - - if (ctx->log_level < level || ctx->log_verbosity < verbosity) - return; - - va_start(args, fmt); - ctx->log_fn(ctx, level, fmt, args); - va_end(args); -} - -char * -xkb_context_get_buffer(struct xkb_context *ctx, size_t size) -{ - char *rtrn; - - if (size >= sizeof(ctx->text_buffer)) - return NULL; - - if (sizeof(ctx->text_buffer) - ctx->text_next <= size) - ctx->text_next = 0; - - rtrn = &ctx->text_buffer[ctx->text_next]; - ctx->text_next += size; - - return rtrn; -} - -#ifndef DEFAULT_XKB_VARIANT -#define DEFAULT_XKB_VARIANT NULL -#endif - -#ifndef DEFAULT_XKB_OPTIONS -#define DEFAULT_XKB_OPTIONS NULL -#endif - -static const char * -xkb_context_get_default_rules(struct xkb_context *ctx) -{ - const char *env = NULL; - - if (ctx->use_environment_names) - env = secure_getenv("XKB_DEFAULT_RULES"); - - return env ? env : DEFAULT_XKB_RULES; -} - -static const char * -xkb_context_get_default_model(struct xkb_context *ctx) -{ - const char *env = NULL; - - if (ctx->use_environment_names) - env = secure_getenv("XKB_DEFAULT_MODEL"); - - return env ? env : DEFAULT_XKB_MODEL; -} - -static const char * -xkb_context_get_default_layout(struct xkb_context *ctx) -{ - const char *env = NULL; - - if (ctx->use_environment_names) - env = secure_getenv("XKB_DEFAULT_LAYOUT"); - - return env ? env : DEFAULT_XKB_LAYOUT; -} - -static const char * -xkb_context_get_default_variant(struct xkb_context *ctx) -{ - const char *env = NULL; - const char *layout = secure_getenv("XKB_DEFAULT_LAYOUT"); - - /* We don't want to inherit the variant if they haven't also set a - * layout, since they're so closely paired. */ - if (layout && ctx->use_environment_names) - env = secure_getenv("XKB_DEFAULT_VARIANT"); - - return env ? env : DEFAULT_XKB_VARIANT; -} - -static const char * -xkb_context_get_default_options(struct xkb_context *ctx) -{ - const char *env = NULL; - - if (ctx->use_environment_names) - env = secure_getenv("XKB_DEFAULT_OPTIONS"); - - return env ? env : DEFAULT_XKB_OPTIONS; -} - -void -xkb_context_sanitize_rule_names(struct xkb_context *ctx, - struct xkb_rule_names *rmlvo) -{ - if (isempty(rmlvo->rules)) - rmlvo->rules = xkb_context_get_default_rules(ctx); - if (isempty(rmlvo->model)) - rmlvo->model = xkb_context_get_default_model(ctx); - /* Layout and variant are tied together, so don't try to use one from - * the caller and one from the environment. */ - if (isempty(rmlvo->layout)) { - rmlvo->layout = xkb_context_get_default_layout(ctx); - rmlvo->variant = xkb_context_get_default_variant(ctx); - } - /* Options can be empty, so respect that if passed in. */ - if (rmlvo->options == NULL) - rmlvo->options = xkb_context_get_default_options(ctx); -} diff --git a/src/3rdparty/xkbcommon/src/context.c b/src/3rdparty/xkbcommon/src/context.c deleted file mode 100644 index 50993e108a..0000000000 --- a/src/3rdparty/xkbcommon/src/context.c +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright © 2012 Intel Corporation - * Copyright © 2012 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Daniel Stone - */ - -#include -#include -#include -#include - -#include "xkbcommon/xkbcommon.h" -#include "utils.h" -#include "context.h" - -/** - * Append one directory to the context's include path. - */ -XKB_EXPORT int -xkb_context_include_path_append(struct xkb_context *ctx, const char *path) -{ - struct stat stat_buf; - int err; - char *tmp; - - tmp = strdup(path); - if (!tmp) - goto err; - - err = stat(path, &stat_buf); - if (err != 0) - goto err; - if (!S_ISDIR(stat_buf.st_mode)) - goto err; - -#if defined(HAVE_EACCESS) - if (eaccess(path, R_OK | X_OK) != 0) - goto err; -#elif defined(HAVE_EUIDACCESS) - if (euidaccess(path, R_OK | X_OK) != 0) - goto err; -#endif - - darray_append(ctx->includes, tmp); - return 1; - -err: - darray_append(ctx->failed_includes, tmp); - return 0; -} - -/** - * Append the default include directories to the context. - */ -XKB_EXPORT int -xkb_context_include_path_append_default(struct xkb_context *ctx) -{ - const char *home, *root; - char *user_path; - int err; - int ret = 0; - - root = secure_getenv("XKB_CONFIG_ROOT"); - if (root != NULL) - ret |= xkb_context_include_path_append(ctx, root); - else - ret |= xkb_context_include_path_append(ctx, DFLT_XKB_CONFIG_ROOT); - - home = secure_getenv("HOME"); - if (!home) - return ret; - err = asprintf(&user_path, "%s/.xkb", home); - if (err <= 0) - return ret; - ret |= xkb_context_include_path_append(ctx, user_path); - free(user_path); - - return ret; -} - -/** - * Remove all entries in the context's include path. - */ -XKB_EXPORT void -xkb_context_include_path_clear(struct xkb_context *ctx) -{ - char **path; - - darray_foreach(path, ctx->includes) - free(*path); - darray_free(ctx->includes); - - darray_foreach(path, ctx->failed_includes) - free(*path); - darray_free(ctx->failed_includes); -} - -/** - * xkb_context_include_path_clear() + xkb_context_include_path_append_default() - */ -XKB_EXPORT int -xkb_context_include_path_reset_defaults(struct xkb_context *ctx) -{ - xkb_context_include_path_clear(ctx); - return xkb_context_include_path_append_default(ctx); -} - -/** - * Returns the number of entries in the context's include path. - */ -XKB_EXPORT unsigned int -xkb_context_num_include_paths(struct xkb_context *ctx) -{ - return darray_size(ctx->includes); -} - -/** - * Returns the given entry in the context's include path, or NULL if an - * invalid index is passed. - */ -XKB_EXPORT const char * -xkb_context_include_path_get(struct xkb_context *ctx, unsigned int idx) -{ - if (idx >= xkb_context_num_include_paths(ctx)) - return NULL; - - return darray_item(ctx->includes, idx); -} - -/** - * Take a new reference on the context. - */ -XKB_EXPORT struct xkb_context * -xkb_context_ref(struct xkb_context *ctx) -{ - ctx->refcnt++; - return ctx; -} - -/** - * Drop an existing reference on the context, and free it if the refcnt is - * now 0. - */ -XKB_EXPORT void -xkb_context_unref(struct xkb_context *ctx) -{ - if (!ctx || --ctx->refcnt > 0) - return; - - xkb_context_include_path_clear(ctx); - atom_table_free(ctx->atom_table); - free(ctx); -} - -static const char * -log_level_to_prefix(enum xkb_log_level level) -{ - switch (level) { - case XKB_LOG_LEVEL_DEBUG: - return "xkbcommon: DEBUG: "; - case XKB_LOG_LEVEL_INFO: - return "xkbcommon: INFO: "; - case XKB_LOG_LEVEL_WARNING: - return "xkbcommon: WARNING: "; - case XKB_LOG_LEVEL_ERROR: - return "xkbcommon: ERROR: "; - case XKB_LOG_LEVEL_CRITICAL: - return "xkbcommon: CRITICAL: "; - default: - return NULL; - } -} - -ATTR_PRINTF(3, 0) static void -default_log_fn(struct xkb_context *ctx, enum xkb_log_level level, - const char *fmt, va_list args) -{ - const char *prefix = log_level_to_prefix(level); - - if (prefix) - fprintf(stderr, "%s", prefix); - vfprintf(stderr, fmt, args); -} - -static enum xkb_log_level -log_level(const char *level) { - char *endptr; - enum xkb_log_level lvl; - - errno = 0; - lvl = strtol(level, &endptr, 10); - if (errno == 0 && (endptr[0] == '\0' || is_space(endptr[0]))) - return lvl; - if (istreq_prefix("crit", level)) - return XKB_LOG_LEVEL_CRITICAL; - if (istreq_prefix("err", level)) - return XKB_LOG_LEVEL_ERROR; - if (istreq_prefix("warn", level)) - return XKB_LOG_LEVEL_WARNING; - if (istreq_prefix("info", level)) - return XKB_LOG_LEVEL_INFO; - if (istreq_prefix("debug", level) || istreq_prefix("dbg", level)) - return XKB_LOG_LEVEL_DEBUG; - - return XKB_LOG_LEVEL_ERROR; -} - -static int -log_verbosity(const char *verbosity) { - char *endptr; - int v; - - errno = 0; - v = strtol(verbosity, &endptr, 10); - if (errno == 0) - return v; - - return 0; -} - -/** - * Create a new context. - */ -XKB_EXPORT struct xkb_context * -xkb_context_new(enum xkb_context_flags flags) -{ - const char *env; - struct xkb_context *ctx = calloc(1, sizeof(*ctx)); - - if (!ctx) - return NULL; - - ctx->refcnt = 1; - ctx->log_fn = default_log_fn; - ctx->log_level = XKB_LOG_LEVEL_ERROR; - ctx->log_verbosity = 0; - - /* Environment overwrites defaults. */ - env = secure_getenv("XKB_LOG_LEVEL"); - if (env) - xkb_context_set_log_level(ctx, log_level(env)); - - env = secure_getenv("XKB_LOG_VERBOSITY"); - if (env) - xkb_context_set_log_verbosity(ctx, log_verbosity(env)); - - if (!(flags & XKB_CONTEXT_NO_DEFAULT_INCLUDES) && - !xkb_context_include_path_append_default(ctx)) { - log_err(ctx, "failed to add default include path %s\n", - DFLT_XKB_CONFIG_ROOT); - xkb_context_unref(ctx); - return NULL; - } - - ctx->use_environment_names = !(flags & XKB_CONTEXT_NO_ENVIRONMENT_NAMES); - - ctx->atom_table = atom_table_new(); - if (!ctx->atom_table) { - xkb_context_unref(ctx); - return NULL; - } - - return ctx; -} - -XKB_EXPORT void -xkb_context_set_log_fn(struct xkb_context *ctx, - void (*log_fn)(struct xkb_context *ctx, - enum xkb_log_level level, - const char *fmt, va_list args)) -{ - ctx->log_fn = (log_fn ? log_fn : default_log_fn); -} - -XKB_EXPORT enum xkb_log_level -xkb_context_get_log_level(struct xkb_context *ctx) -{ - return ctx->log_level; -} - -XKB_EXPORT void -xkb_context_set_log_level(struct xkb_context *ctx, enum xkb_log_level level) -{ - ctx->log_level = level; -} - -XKB_EXPORT int -xkb_context_get_log_verbosity(struct xkb_context *ctx) -{ - return ctx->log_verbosity; -} - -XKB_EXPORT void -xkb_context_set_log_verbosity(struct xkb_context *ctx, int verbosity) -{ - ctx->log_verbosity = verbosity; -} - -XKB_EXPORT void * -xkb_context_get_user_data(struct xkb_context *ctx) -{ - if (ctx) - return ctx->user_data; - return NULL; -} - -XKB_EXPORT void -xkb_context_set_user_data(struct xkb_context *ctx, void *user_data) -{ - ctx->user_data = user_data; -} diff --git a/src/3rdparty/xkbcommon/src/context.h b/src/3rdparty/xkbcommon/src/context.h deleted file mode 100644 index 03e6d50abb..0000000000 --- a/src/3rdparty/xkbcommon/src/context.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright © 2012 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Daniel Stone - */ - -#ifndef CONTEXT_H -#define CONTEXT_H - -#include "atom.h" - -struct xkb_context { - int refcnt; - - ATTR_PRINTF(3, 0) void (*log_fn)(struct xkb_context *ctx, - enum xkb_log_level level, - const char *fmt, va_list args); - enum xkb_log_level log_level; - int log_verbosity; - void *user_data; - - struct xkb_rule_names names_dflt; - - darray(char *) includes; - darray(char *) failed_includes; - - struct atom_table *atom_table; - - /* Buffer for the *Text() functions. */ - char text_buffer[2048]; - size_t text_next; - - unsigned int use_environment_names : 1; -}; - -unsigned int -xkb_context_num_failed_include_paths(struct xkb_context *ctx); - -const char * -xkb_context_failed_include_path_get(struct xkb_context *ctx, - unsigned int idx); - -/* - * Returns XKB_ATOM_NONE if @string was not previously interned, - * otherwise returns the atom. - */ -xkb_atom_t -xkb_atom_lookup(struct xkb_context *ctx, const char *string); - -xkb_atom_t -xkb_atom_intern(struct xkb_context *ctx, const char *string, size_t len); - -#define xkb_atom_intern_literal(ctx, literal) \ - xkb_atom_intern((ctx), (literal), sizeof(literal) - 1) - -/** - * If @string is dynamically allocated, NUL-terminated, free'd immediately - * after being interned, and not used afterwards, use this function - * instead of xkb_atom_intern to avoid some unnecessary allocations. - * The caller should not use or free the passed in string afterwards. - */ -xkb_atom_t -xkb_atom_steal(struct xkb_context *ctx, char *string); - -const char * -xkb_atom_text(struct xkb_context *ctx, xkb_atom_t atom); - -char * -xkb_context_get_buffer(struct xkb_context *ctx, size_t size); - -ATTR_PRINTF(4, 5) void -xkb_log(struct xkb_context *ctx, enum xkb_log_level level, int verbosity, - const char *fmt, ...); - -void -xkb_context_sanitize_rule_names(struct xkb_context *ctx, - struct xkb_rule_names *rmlvo); - -/* - * The format is not part of the argument list in order to avoid the - * "ISO C99 requires rest arguments to be used" warning when only the - * format is supplied without arguments. Not supplying it would still - * result in an error, though. - */ -#define log_dbg(ctx, ...) \ - xkb_log((ctx), XKB_LOG_LEVEL_DEBUG, 0, __VA_ARGS__) -#define log_info(ctx, ...) \ - xkb_log((ctx), XKB_LOG_LEVEL_INFO, 0, __VA_ARGS__) -#define log_warn(ctx, ...) \ - xkb_log((ctx), XKB_LOG_LEVEL_WARNING, 0, __VA_ARGS__) -#define log_err(ctx, ...) \ - xkb_log((ctx), XKB_LOG_LEVEL_ERROR, 0, __VA_ARGS__) -#define log_wsgo(ctx, ...) \ - xkb_log((ctx), XKB_LOG_LEVEL_CRITICAL, 0, __VA_ARGS__) -#define log_vrb(ctx, vrb, ...) \ - xkb_log((ctx), XKB_LOG_LEVEL_WARNING, (vrb), __VA_ARGS__) - -/* - * Variants which are prefixed by the name of the function they're - * called from. - * Here we must have the silly 1 variant. - */ -#define log_err_func(ctx, fmt, ...) \ - log_err(ctx, "%s: " fmt, __func__, __VA_ARGS__) -#define log_err_func1(ctx, fmt) \ - log_err(ctx, "%s: " fmt, __func__) - -#endif diff --git a/src/3rdparty/xkbcommon/src/darray.h b/src/3rdparty/xkbcommon/src/darray.h deleted file mode 100644 index 8e87c942ee..0000000000 --- a/src/3rdparty/xkbcommon/src/darray.h +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright (C) 2011 Joseph Adams - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef CCAN_DARRAY_H -#define CCAN_DARRAY_H - -/* Originally taken from: https://ccodearchive.net/info/darray.html - * But modified for libxkbcommon. */ - -#include -#include -#include -#include - -#define darray(type) struct { type *item; unsigned size; unsigned alloc; } - -#define darray_new() { 0, 0, 0 } - -#define darray_init(arr) do { \ - (arr).item = 0; (arr).size = 0; (arr).alloc = 0; \ -} while (0) - -#define darray_free(arr) do { \ - free((arr).item); \ - darray_init(arr); \ -} while (0) - -#define darray_steal(arr, to, to_size) do { \ - *(to) = (arr).item; \ - if (to_size) \ - *(unsigned int *) (to_size) = (arr).size; \ - darray_init(arr); \ -} while (0) - -/* - * Typedefs for darrays of common types. These are useful - * when you want to pass a pointer to an darray(T) around. - * - * The following will produce an incompatible pointer warning: - * - * void foo(darray(int) *arr); - * darray(int) arr = darray_new(); - * foo(&arr); - * - * The workaround: - * - * void foo(darray_int *arr); - * darray_int arr = darray_new(); - * foo(&arr); - */ - -typedef darray (char) darray_char; -typedef darray (signed char) darray_schar; -typedef darray (unsigned char) darray_uchar; - -typedef darray (short) darray_short; -typedef darray (int) darray_int; -typedef darray (long) darray_long; - -typedef darray (unsigned short) darray_ushort; -typedef darray (unsigned int) darray_uint; -typedef darray (unsigned long) darray_ulong; - -/*** Access ***/ - -#define darray_item(arr, i) ((arr).item[i]) -#define darray_size(arr) ((arr).size) -#define darray_empty(arr) ((arr).size == 0) - -/*** Insertion (single item) ***/ - -#define darray_append(arr, ...) do { \ - darray_resize(arr, (arr).size + 1); \ - (arr).item[(arr).size - 1] = (__VA_ARGS__); \ -} while (0) - -/*** Insertion (multiple items) ***/ - -#define darray_append_items(arr, items, count) do { \ - unsigned __count = (count), __oldSize = (arr).size; \ - darray_resize(arr, __oldSize + __count); \ - memcpy((arr).item + __oldSize, items, __count * sizeof(*(arr).item)); \ -} while (0) - -#define darray_from_items(arr, items, count) do { \ - unsigned __count = (count); \ - darray_resize(arr, __count); \ - if (__count != 0) \ - memcpy((arr).item, items, __count * sizeof(*(arr).item)); \ -} while (0) - -#define darray_copy(arr_to, arr_from) \ - darray_from_items((arr_to), (arr_from).item, (arr_from).size) - -#define darray_concat(arr_to, arr_from) \ - darray_append_items((arr_to), (arr_from).item, (arr_from).size) - -/*** String buffer ***/ - -#define darray_append_string(arr, str) do { \ - const char *__str = (str); \ - darray_append_items(arr, __str, strlen(__str) + 1); \ - (arr).size--; \ -} while (0) - -#define darray_append_lit(arr, stringLiteral) do { \ - darray_append_items(arr, stringLiteral, sizeof(stringLiteral)); \ - (arr).size--; \ -} while (0) - -#define darray_appends_nullterminate(arr, items, count) do { \ - unsigned __count = (count), __oldSize = (arr).size; \ - darray_resize(arr, __oldSize + __count + 1); \ - memcpy((arr).item + __oldSize, items, __count * sizeof(*(arr).item)); \ - (arr).item[--(arr).size] = 0; \ -} while (0) - -#define darray_prepends_nullterminate(arr, items, count) do { \ - unsigned __count = (count), __oldSize = (arr).size; \ - darray_resize(arr, __count + __oldSize + 1); \ - memmove((arr).item + __count, (arr).item, \ - __oldSize * sizeof(*(arr).item)); \ - memcpy((arr).item, items, __count * sizeof(*(arr).item)); \ - (arr).item[--(arr).size] = 0; \ -} while (0) - -/*** Size management ***/ - -#define darray_resize(arr, newSize) \ - darray_growalloc(arr, (arr).size = (newSize)) - -#define darray_resize0(arr, newSize) do { \ - unsigned __oldSize = (arr).size, __newSize = (newSize); \ - (arr).size = __newSize; \ - if (__newSize > __oldSize) { \ - darray_growalloc(arr, __newSize); \ - memset(&(arr).item[__oldSize], 0, \ - (__newSize - __oldSize) * sizeof(*(arr).item)); \ - } \ -} while (0) - -#define darray_realloc(arr, newAlloc) do { \ - (arr).item = realloc((arr).item, \ - ((arr).alloc = (newAlloc)) * sizeof(*(arr).item)); \ -} while (0) - -#define darray_growalloc(arr, need) do { \ - unsigned __need = (need); \ - if (__need > (arr).alloc) \ - darray_realloc(arr, darray_next_alloc((arr).alloc, __need, \ - sizeof(*(arr).item))); \ -} while (0) - -#define darray_shrink(arr) do { \ - if ((arr).size > 0) \ - (arr).item = realloc((arr).item, \ - ((arr).alloc = (arr).size) * sizeof(*(arr).item)); \ -} while (0) - -static inline unsigned -darray_next_alloc(unsigned alloc, unsigned need, unsigned itemSize) -{ - assert(need < UINT_MAX / itemSize / 2); /* Overflow. */ - if (alloc == 0) - alloc = 4; - while (alloc < need) - alloc *= 2; - return alloc; -} - -/*** Traversal ***/ - -#define darray_foreach(i, arr) \ - for ((i) = &(arr).item[0]; (i) < &(arr).item[(arr).size]; (i)++) - -#define darray_foreach_from(i, arr, from) \ - for ((i) = &(arr).item[from]; (i) < &(arr).item[(arr).size]; (i)++) - -/* Iterate on index and value at the same time, like Python's enumerate. */ -#define darray_enumerate(idx, val, arr) \ - for ((idx) = 0, (val) = &(arr).item[0]; \ - (idx) < (arr).size; \ - (idx)++, (val)++) - -#define darray_enumerate_from(idx, val, arr, from) \ - for ((idx) = (from), (val) = &(arr).item[0]; \ - (idx) < (arr).size; \ - (idx)++, (val)++) - -#endif /* CCAN_DARRAY_H */ diff --git a/src/3rdparty/xkbcommon/src/keymap-priv.c b/src/3rdparty/xkbcommon/src/keymap-priv.c deleted file mode 100644 index fffb2fd30d..0000000000 --- a/src/3rdparty/xkbcommon/src/keymap-priv.c +++ /dev/null @@ -1,150 +0,0 @@ -/** - * Copyright © 2012 Intel Corporation - * Copyright © 2012 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Daniel Stone - */ - -#include "keymap.h" - -static void -update_builtin_keymap_fields(struct xkb_keymap *keymap) -{ - /* Predefined (AKA real, core, X11) modifiers. The order is important! */ - static const char *const builtin_mods[] = { - [0] = "Shift", - [1] = "Lock", - [2] = "Control", - [3] = "Mod1", - [4] = "Mod2", - [5] = "Mod3", - [6] = "Mod4", - [7] = "Mod5" - }; - - for (unsigned i = 0; i < ARRAY_SIZE(builtin_mods); i++) { - keymap->mods.mods[i].name = xkb_atom_intern(keymap->ctx, - builtin_mods[i], - strlen(builtin_mods[i])); - keymap->mods.mods[i].type = MOD_REAL; - } - keymap->mods.num_mods = ARRAY_SIZE(builtin_mods); -} - -struct xkb_keymap * -xkb_keymap_new(struct xkb_context *ctx, - enum xkb_keymap_format format, - enum xkb_keymap_compile_flags flags) -{ - struct xkb_keymap *keymap; - - keymap = calloc(1, sizeof(*keymap)); - if (!keymap) - return NULL; - - keymap->refcnt = 1; - keymap->ctx = xkb_context_ref(ctx); - - keymap->format = format; - keymap->flags = flags; - - update_builtin_keymap_fields(keymap); - - return keymap; -} - -struct xkb_key * -XkbKeyByName(struct xkb_keymap *keymap, xkb_atom_t name, bool use_aliases) -{ - struct xkb_key *key; - - xkb_keys_foreach(key, keymap) - if (key->name == name) - return key; - - if (use_aliases) { - xkb_atom_t new_name = XkbResolveKeyAlias(keymap, name); - if (new_name != XKB_ATOM_NONE) - return XkbKeyByName(keymap, new_name, false); - } - - return NULL; -} - -xkb_atom_t -XkbResolveKeyAlias(const struct xkb_keymap *keymap, xkb_atom_t name) -{ - for (unsigned i = 0; i < keymap->num_key_aliases; i++) - if (keymap->key_aliases[i].alias == name) - return keymap->key_aliases[i].real; - - return XKB_ATOM_NONE; -} - -void -XkbEscapeMapName(char *name) -{ - /* - * All latin-1 alphanumerics, plus parens, slash, minus, underscore and - * wildcards. - */ - static const unsigned char legal[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x83, - 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff - }; - - if (!name) - return; - - while (*name) { - unsigned char c = *name; - if (!(legal[c / 8] & (1 << (c % 8)))) - *name = '_'; - name++; - } -} - -xkb_mod_index_t -XkbModNameToIndex(const struct xkb_mod_set *mods, xkb_atom_t name, - enum mod_type type) -{ - xkb_mod_index_t i; - const struct xkb_mod *mod; - - xkb_mods_enumerate(i, mod, mods) - if ((mod->type & type) && name == mod->name) - return i; - - return XKB_MOD_INVALID; -} - -bool -XkbLevelsSameSyms(const struct xkb_level *a, const struct xkb_level *b) -{ - if (a->num_syms != b->num_syms) - return false; - if (a->num_syms <= 1) - return a->u.sym == b->u.sym; - return memcmp(a->u.syms, b->u.syms, sizeof(*a->u.syms) * a->num_syms) == 0; -} diff --git a/src/3rdparty/xkbcommon/src/keymap.c b/src/3rdparty/xkbcommon/src/keymap.c deleted file mode 100644 index 859c64a556..0000000000 --- a/src/3rdparty/xkbcommon/src/keymap.c +++ /dev/null @@ -1,519 +0,0 @@ -/** - * Copyright © 2012 Intel Corporation - * Copyright © 2012 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Daniel Stone - */ - -/************************************************************ - * Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting - * documentation, and that the name of Silicon Graphics not be - * used in advertising or publicity pertaining to distribution - * of the software without specific prior written permission. - * Silicon Graphics makes no representation about the suitability - * of this software for any purpose. It is provided "as is" - * without any express or implied warranty. - * - * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - * THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * ********************************************************/ - -#include "keymap.h" -#include "text.h" - -XKB_EXPORT struct xkb_keymap * -xkb_keymap_ref(struct xkb_keymap *keymap) -{ - keymap->refcnt++; - return keymap; -} - -XKB_EXPORT void -xkb_keymap_unref(struct xkb_keymap *keymap) -{ - if (!keymap || --keymap->refcnt > 0) - return; - - if (keymap->keys) { - struct xkb_key *key; - xkb_keys_foreach(key, keymap) { - if (key->groups) { - for (unsigned i = 0; i < key->num_groups; i++) { - if (key->groups[i].levels) { - for (unsigned j = 0; j < XkbKeyNumLevels(key, i); j++) - if (key->groups[i].levels[j].num_syms > 1) - free(key->groups[i].levels[j].u.syms); - free(key->groups[i].levels); - } - } - free(key->groups); - } - } - free(keymap->keys); - } - if (keymap->types) { - for (unsigned i = 0; i < keymap->num_types; i++) { - free(keymap->types[i].entries); - free(keymap->types[i].level_names); - } - free(keymap->types); - } - free(keymap->sym_interprets); - free(keymap->key_aliases); - free(keymap->group_names); - free(keymap->keycodes_section_name); - free(keymap->symbols_section_name); - free(keymap->types_section_name); - free(keymap->compat_section_name); - xkb_context_unref(keymap->ctx); - free(keymap); -} - -static const struct xkb_keymap_format_ops * -get_keymap_format_ops(enum xkb_keymap_format format) -{ - static const struct xkb_keymap_format_ops *keymap_format_ops[] = { - [XKB_KEYMAP_FORMAT_TEXT_V1] = &text_v1_keymap_format_ops, - }; - - if ((int) format < 0 || (int) format >= (int) ARRAY_SIZE(keymap_format_ops)) - return NULL; - - return keymap_format_ops[(int) format]; -} - -XKB_EXPORT struct xkb_keymap * -xkb_keymap_new_from_names(struct xkb_context *ctx, - const struct xkb_rule_names *rmlvo_in, - enum xkb_keymap_compile_flags flags) -{ - struct xkb_keymap *keymap; - struct xkb_rule_names rmlvo; - const enum xkb_keymap_format format = XKB_KEYMAP_FORMAT_TEXT_V1; - const struct xkb_keymap_format_ops *ops; - - ops = get_keymap_format_ops(format); - if (!ops || !ops->keymap_new_from_names) { - log_err_func(ctx, "unsupported keymap format: %d\n", format); - return NULL; - } - - if (flags & ~(XKB_KEYMAP_COMPILE_NO_FLAGS)) { - log_err_func(ctx, "unrecognized flags: %#x\n", flags); - return NULL; - } - - keymap = xkb_keymap_new(ctx, format, flags); - if (!keymap) - return NULL; - - if (rmlvo_in) - rmlvo = *rmlvo_in; - else - memset(&rmlvo, 0, sizeof(rmlvo)); - xkb_context_sanitize_rule_names(ctx, &rmlvo); - - if (!ops->keymap_new_from_names(keymap, &rmlvo)) { - xkb_keymap_unref(keymap); - return NULL; - } - - return keymap; -} - -XKB_EXPORT struct xkb_keymap * -xkb_keymap_new_from_string(struct xkb_context *ctx, - const char *string, - enum xkb_keymap_format format, - enum xkb_keymap_compile_flags flags) -{ - return xkb_keymap_new_from_buffer(ctx, string, strlen(string), - format, flags); -} - -XKB_EXPORT struct xkb_keymap * -xkb_keymap_new_from_buffer(struct xkb_context *ctx, - const char *buffer, size_t length, - enum xkb_keymap_format format, - enum xkb_keymap_compile_flags flags) -{ - struct xkb_keymap *keymap; - const struct xkb_keymap_format_ops *ops; - - ops = get_keymap_format_ops(format); - if (!ops || !ops->keymap_new_from_string) { - log_err_func(ctx, "unsupported keymap format: %d\n", format); - return NULL; - } - - if (flags & ~(XKB_KEYMAP_COMPILE_NO_FLAGS)) { - log_err_func(ctx, "unrecognized flags: %#x\n", flags); - return NULL; - } - - if (!buffer) { - log_err_func1(ctx, "no buffer specified\n"); - return NULL; - } - - keymap = xkb_keymap_new(ctx, format, flags); - if (!keymap) - return NULL; - - if (!ops->keymap_new_from_string(keymap, buffer, length)) { - xkb_keymap_unref(keymap); - return NULL; - } - - return keymap; -} - -XKB_EXPORT struct xkb_keymap * -xkb_keymap_new_from_file(struct xkb_context *ctx, - FILE *file, - enum xkb_keymap_format format, - enum xkb_keymap_compile_flags flags) -{ - struct xkb_keymap *keymap; - const struct xkb_keymap_format_ops *ops; - - ops = get_keymap_format_ops(format); - if (!ops || !ops->keymap_new_from_file) { - log_err_func(ctx, "unsupported keymap format: %d\n", format); - return NULL; - } - - if (flags & ~(XKB_KEYMAP_COMPILE_NO_FLAGS)) { - log_err_func(ctx, "unrecognized flags: %#x\n", flags); - return NULL; - } - - if (!file) { - log_err_func1(ctx, "no file specified\n"); - return NULL; - } - - keymap = xkb_keymap_new(ctx, format, flags); - if (!keymap) - return NULL; - - if (!ops->keymap_new_from_file(keymap, file)) { - xkb_keymap_unref(keymap); - return NULL; - } - - return keymap; -} - -XKB_EXPORT char * -xkb_keymap_get_as_string(struct xkb_keymap *keymap, - enum xkb_keymap_format format) -{ - const struct xkb_keymap_format_ops *ops; - - if (format == XKB_KEYMAP_USE_ORIGINAL_FORMAT) - format = keymap->format; - - ops = get_keymap_format_ops(format); - if (!ops || !ops->keymap_get_as_string) { - log_err_func(keymap->ctx, "unsupported keymap format: %d\n", format); - return NULL; - } - - return ops->keymap_get_as_string(keymap); -} - -/** - * Returns the total number of modifiers active in the keymap. - */ -XKB_EXPORT xkb_mod_index_t -xkb_keymap_num_mods(struct xkb_keymap *keymap) -{ - return keymap->mods.num_mods; -} - -/** - * Return the name for a given modifier. - */ -XKB_EXPORT const char * -xkb_keymap_mod_get_name(struct xkb_keymap *keymap, xkb_mod_index_t idx) -{ - if (idx >= keymap->mods.num_mods) - return NULL; - - return xkb_atom_text(keymap->ctx, keymap->mods.mods[idx].name); -} - -/** - * Returns the index for a named modifier. - */ -XKB_EXPORT xkb_mod_index_t -xkb_keymap_mod_get_index(struct xkb_keymap *keymap, const char *name) -{ - xkb_atom_t atom; - - atom = xkb_atom_lookup(keymap->ctx, name); - if (atom == XKB_ATOM_NONE) - return XKB_MOD_INVALID; - - return XkbModNameToIndex(&keymap->mods, atom, MOD_BOTH); -} - -/** - * Return the total number of active groups in the keymap. - */ -XKB_EXPORT xkb_layout_index_t -xkb_keymap_num_layouts(struct xkb_keymap *keymap) -{ - return keymap->num_groups; -} - -/** - * Returns the name for a given group. - */ -XKB_EXPORT const char * -xkb_keymap_layout_get_name(struct xkb_keymap *keymap, xkb_layout_index_t idx) -{ - if (idx >= keymap->num_group_names) - return NULL; - - return xkb_atom_text(keymap->ctx, keymap->group_names[idx]); -} - -/** - * Returns the index for a named layout. - */ -XKB_EXPORT xkb_layout_index_t -xkb_keymap_layout_get_index(struct xkb_keymap *keymap, const char *name) -{ - xkb_atom_t atom = xkb_atom_lookup(keymap->ctx, name); - xkb_layout_index_t i; - - if (atom == XKB_ATOM_NONE) - return XKB_LAYOUT_INVALID; - - for (i = 0; i < keymap->num_group_names; i++) - if (keymap->group_names[i] == atom) - return i; - - return XKB_LAYOUT_INVALID; -} - -/** - * Returns the number of layouts active for a particular key. - */ -XKB_EXPORT xkb_layout_index_t -xkb_keymap_num_layouts_for_key(struct xkb_keymap *keymap, xkb_keycode_t kc) -{ - const struct xkb_key *key = XkbKey(keymap, kc); - - if (!key) - return 0; - - return key->num_groups; -} - -/** - * Returns the number of levels active for a particular key and layout. - */ -XKB_EXPORT xkb_level_index_t -xkb_keymap_num_levels_for_key(struct xkb_keymap *keymap, xkb_keycode_t kc, - xkb_layout_index_t layout) -{ - const struct xkb_key *key = XkbKey(keymap, kc); - - if (!key) - return 0; - - layout = XkbWrapGroupIntoRange(layout, key->num_groups, - key->out_of_range_group_action, - key->out_of_range_group_number); - if (layout == XKB_LAYOUT_INVALID) - return 0; - - return XkbKeyNumLevels(key, layout); -} - -/** - * Return the total number of LEDs in the keymap. - */ -XKB_EXPORT xkb_led_index_t -xkb_keymap_num_leds(struct xkb_keymap *keymap) -{ - return keymap->num_leds; -} - -/** - * Returns the name for a given LED. - */ -XKB_EXPORT const char * -xkb_keymap_led_get_name(struct xkb_keymap *keymap, xkb_led_index_t idx) -{ - if (idx >= keymap->num_leds) - return NULL; - - return xkb_atom_text(keymap->ctx, keymap->leds[idx].name); -} - -/** - * Returns the index for a named LED. - */ -XKB_EXPORT xkb_led_index_t -xkb_keymap_led_get_index(struct xkb_keymap *keymap, const char *name) -{ - xkb_atom_t atom = xkb_atom_lookup(keymap->ctx, name); - xkb_led_index_t i; - const struct xkb_led *led; - - if (atom == XKB_ATOM_NONE) - return XKB_LED_INVALID; - - xkb_leds_enumerate(i, led, keymap) - if (led->name == atom) - return i; - - return XKB_LED_INVALID; -} - -/** - * As below, but takes an explicit layout/level rather than state. - */ -XKB_EXPORT int -xkb_keymap_key_get_syms_by_level(struct xkb_keymap *keymap, - xkb_keycode_t kc, - xkb_layout_index_t layout, - xkb_level_index_t level, - const xkb_keysym_t **syms_out) -{ - const struct xkb_key *key = XkbKey(keymap, kc); - int num_syms; - - if (!key) - goto err; - - layout = XkbWrapGroupIntoRange(layout, key->num_groups, - key->out_of_range_group_action, - key->out_of_range_group_number); - if (layout == XKB_LAYOUT_INVALID) - goto err; - - if (level >= XkbKeyNumLevels(key, layout)) - goto err; - - num_syms = key->groups[layout].levels[level].num_syms; - if (num_syms == 0) - goto err; - - if (num_syms == 1) - *syms_out = &key->groups[layout].levels[level].u.sym; - else - *syms_out = key->groups[layout].levels[level].u.syms; - - return num_syms; - -err: - *syms_out = NULL; - return 0; -} - -XKB_EXPORT xkb_keycode_t -xkb_keymap_min_keycode(struct xkb_keymap *keymap) -{ - return keymap->min_key_code; -} - -XKB_EXPORT xkb_keycode_t -xkb_keymap_max_keycode(struct xkb_keymap *keymap) -{ - return keymap->max_key_code; -} - -XKB_EXPORT void -xkb_keymap_key_for_each(struct xkb_keymap *keymap, xkb_keymap_key_iter_t iter, - void *data) -{ - struct xkb_key *key; - - xkb_keys_foreach(key, keymap) - iter(keymap, key->keycode, data); -} - -XKB_EXPORT const char * -xkb_keymap_key_get_name(struct xkb_keymap *keymap, xkb_keycode_t kc) -{ - const struct xkb_key *key = XkbKey(keymap, kc); - - if (!key) - return NULL; - - return xkb_atom_text(keymap->ctx, key->name); -} - -XKB_EXPORT xkb_keycode_t -xkb_keymap_key_by_name(struct xkb_keymap *keymap, const char *name) -{ - struct xkb_key *key; - xkb_atom_t atom; - - atom = xkb_atom_lookup(keymap->ctx, name); - if (atom) { - xkb_atom_t ratom = XkbResolveKeyAlias(keymap, atom); - if (ratom) - atom = ratom; - } - if (!atom) - return XKB_KEYCODE_INVALID; - - xkb_keys_foreach(key, keymap) { - if (key->name == atom) - return key->keycode; - } - - return XKB_KEYCODE_INVALID; -} - -/** - * Simple boolean specifying whether or not the key should repeat. - */ -XKB_EXPORT int -xkb_keymap_key_repeats(struct xkb_keymap *keymap, xkb_keycode_t kc) -{ - const struct xkb_key *key = XkbKey(keymap, kc); - - if (!key) - return 0; - - return key->repeats; -} diff --git a/src/3rdparty/xkbcommon/src/keymap.h b/src/3rdparty/xkbcommon/src/keymap.h deleted file mode 100644 index c15052bc7f..0000000000 --- a/src/3rdparty/xkbcommon/src/keymap.h +++ /dev/null @@ -1,482 +0,0 @@ -/* - * Copyright 1985, 1987, 1990, 1998 The Open Group - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the names of the authors or their - * institutions shall not be used in advertising or otherwise to promote the - * sale, use or other dealings in this Software without prior written - * authorization from the authors. - */ - -/************************************************************ - * Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting - * documentation, and that the name of Silicon Graphics not be - * used in advertising or publicity pertaining to distribution - * of the software without specific prior written permission. - * Silicon Graphics makes no representation about the suitability - * of this software for any purpose. It is provided "as is" - * without any express or implied warranty. - * - * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - * THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - ********************************************************/ - -/* - * Copyright © 2009 Dan Nicholson - * Copyright © 2012 Intel Corporation - * Copyright © 2012 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Daniel Stone - * Dan Nicholson - */ - -#ifndef KEYMAP_H -#define KEYMAP_H - - /* Don't use compat names in internal code. */ -#define _XKBCOMMON_COMPAT_H -#include "xkbcommon/xkbcommon.h" - -#include "utils.h" -#include "context.h" - -/* This limit is artificially enforced, we do not depend on it any where. - * The reason it's still here is that the rules file format does not - * support multiple groups very well, and the rules shipped with - * xkeyboard-config (see rules/evdev) depend on this limit extensively. - * So just lifting this limit would cause problems for people who will use - * more than 4 layouts. - * TODO: Fix the group index syntax in the rules format, preferably in a - * backwards compatible way. - * See e.g. https://bugs.freedesktop.org/show_bug.cgi?id=14372 - * Note: A limit on the number of groups we *do* depend on is imposed by - * the size of the xkb_layout_mask_t type (32). This is more than enough - * though. - */ -#define XKB_MAX_GROUPS 4 - -/* Don't allow more modifiers than we can hold in xkb_mod_mask_t. */ -#define XKB_MAX_MODS ((xkb_mod_index_t) (sizeof(xkb_mod_mask_t) * 8)) - -/* Don't allow more leds than we can hold in xkb_led_mask_t. */ -#define XKB_MAX_LEDS ((xkb_led_index_t) (sizeof(xkb_led_mask_t) * 8)) - -/* These should all go away. */ -enum mod_type { - MOD_REAL = (1 << 0), - MOD_VIRT = (1 << 1), - MOD_BOTH = (MOD_REAL | MOD_VIRT), -}; -#define MOD_REAL_MASK_ALL ((xkb_mod_mask_t) 0x000000ff) - -enum xkb_action_type { - ACTION_TYPE_NONE = 0, - ACTION_TYPE_MOD_SET, - ACTION_TYPE_MOD_LATCH, - ACTION_TYPE_MOD_LOCK, - ACTION_TYPE_GROUP_SET, - ACTION_TYPE_GROUP_LATCH, - ACTION_TYPE_GROUP_LOCK, - ACTION_TYPE_PTR_MOVE, - ACTION_TYPE_PTR_BUTTON, - ACTION_TYPE_PTR_LOCK, - ACTION_TYPE_PTR_DEFAULT, - ACTION_TYPE_TERMINATE, - ACTION_TYPE_SWITCH_VT, - ACTION_TYPE_CTRL_SET, - ACTION_TYPE_CTRL_LOCK, - ACTION_TYPE_PRIVATE, - _ACTION_TYPE_NUM_ENTRIES -}; - -enum xkb_action_flags { - ACTION_LOCK_CLEAR = (1 << 0), - ACTION_LATCH_TO_LOCK = (1 << 1), - ACTION_LOCK_NO_LOCK = (1 << 2), - ACTION_LOCK_NO_UNLOCK = (1 << 3), - ACTION_MODS_LOOKUP_MODMAP = (1 << 4), - ACTION_ABSOLUTE_SWITCH = (1 << 5), - ACTION_ABSOLUTE_X = (1 << 6), - ACTION_ABSOLUTE_Y = (1 << 7), - ACTION_ACCEL = (1 << 8), - ACTION_SAME_SCREEN = (1 << 9), -}; - -enum xkb_action_controls { - CONTROL_REPEAT = (1 << 0), - CONTROL_SLOW = (1 << 1), - CONTROL_DEBOUNCE = (1 << 2), - CONTROL_STICKY = (1 << 3), - CONTROL_MOUSEKEYS = (1 << 4), - CONTROL_MOUSEKEYS_ACCEL = (1 << 5), - CONTROL_AX = (1 << 6), - CONTROL_AX_TIMEOUT = (1 << 7), - CONTROL_AX_FEEDBACK = (1 << 8), - CONTROL_BELL = (1 << 9), - CONTROL_IGNORE_GROUP_LOCK = (1 << 10), - CONTROL_ALL = \ - (CONTROL_REPEAT | CONTROL_SLOW | CONTROL_DEBOUNCE | CONTROL_STICKY | \ - CONTROL_MOUSEKEYS | CONTROL_MOUSEKEYS_ACCEL | CONTROL_AX | \ - CONTROL_AX_TIMEOUT | CONTROL_AX_FEEDBACK | CONTROL_BELL | \ - CONTROL_IGNORE_GROUP_LOCK) -}; - -enum xkb_match_operation { - MATCH_NONE, - MATCH_ANY_OR_NONE, - MATCH_ANY, - MATCH_ALL, - MATCH_EXACTLY, -}; - -struct xkb_mods { - xkb_mod_mask_t mods; /* original real+virtual mods in definition */ - xkb_mod_mask_t mask; /* computed effective mask */ -}; - -struct xkb_mod_action { - enum xkb_action_type type; - enum xkb_action_flags flags; - struct xkb_mods mods; -}; - -struct xkb_group_action { - enum xkb_action_type type; - enum xkb_action_flags flags; - int32_t group; -}; - -struct xkb_controls_action { - enum xkb_action_type type; - enum xkb_action_flags flags; - enum xkb_action_controls ctrls; -}; - -struct xkb_pointer_default_action { - enum xkb_action_type type; - enum xkb_action_flags flags; - int8_t value; -}; - -struct xkb_switch_screen_action { - enum xkb_action_type type; - enum xkb_action_flags flags; - int8_t screen; -}; - -struct xkb_pointer_action { - enum xkb_action_type type; - enum xkb_action_flags flags; - int16_t x; - int16_t y; -}; - -struct xkb_pointer_button_action { - enum xkb_action_type type; - enum xkb_action_flags flags; - uint8_t count; - uint8_t button; -}; - -struct xkb_private_action { - enum xkb_action_type type; - uint8_t data[7]; -}; - -union xkb_action { - enum xkb_action_type type; - struct xkb_mod_action mods; - struct xkb_group_action group; - struct xkb_controls_action ctrls; - struct xkb_pointer_default_action dflt; - struct xkb_switch_screen_action screen; - struct xkb_pointer_action ptr; - struct xkb_pointer_button_action btn; - struct xkb_private_action priv; -}; - -struct xkb_key_type_entry { - xkb_level_index_t level; - struct xkb_mods mods; - struct xkb_mods preserve; -}; - -struct xkb_key_type { - xkb_atom_t name; - struct xkb_mods mods; - xkb_level_index_t num_levels; - unsigned int num_level_names; - xkb_atom_t *level_names; - unsigned int num_entries; - struct xkb_key_type_entry *entries; -}; - -struct xkb_sym_interpret { - xkb_keysym_t sym; - enum xkb_match_operation match; - xkb_mod_mask_t mods; - xkb_mod_index_t virtual_mod; - union xkb_action action; - bool level_one_only; - bool repeat; -}; - -struct xkb_led { - xkb_atom_t name; - enum xkb_state_component which_groups; - xkb_layout_mask_t groups; - enum xkb_state_component which_mods; - struct xkb_mods mods; - enum xkb_action_controls ctrls; -}; - -struct xkb_key_alias { - xkb_atom_t real; - xkb_atom_t alias; -}; - -struct xkb_controls { - unsigned char groups_wrap; - struct xkb_mods internal; - struct xkb_mods ignore_lock; - unsigned short repeat_delay; - unsigned short repeat_interval; - unsigned short slow_keys_delay; - unsigned short debounce_delay; - unsigned short ax_options; - unsigned short ax_timeout; - unsigned short axt_opts_mask; - unsigned short axt_opts_values; - unsigned int axt_ctrls_mask; - unsigned int axt_ctrls_values; -}; - -/* Such an awkward name. Oh well. */ -enum xkb_range_exceed_type { - RANGE_WRAP = 0, - RANGE_SATURATE, - RANGE_REDIRECT, -}; - -enum xkb_explicit_components { - EXPLICIT_INTERP = (1 << 0), - EXPLICIT_VMODMAP = (1 << 1), - EXPLICIT_REPEAT = (1 << 2), -}; - -struct xkb_level { - union xkb_action action; - unsigned int num_syms; - union { - xkb_keysym_t sym; /* num_syms == 1 */ - xkb_keysym_t *syms; /* num_syms > 1 */ - } u; -}; - -struct xkb_group { - bool explicit_type; - /* Points to a type in keymap->types. */ - const struct xkb_key_type *type; - /* Use XkbKeyNumLevels for the number of levels. */ - struct xkb_level *levels; -}; - -struct xkb_key { - xkb_keycode_t keycode; - xkb_atom_t name; - - enum xkb_explicit_components explicit; - - xkb_mod_mask_t modmap; - xkb_mod_mask_t vmodmap; - - bool repeats; - - enum xkb_range_exceed_type out_of_range_group_action; - xkb_layout_index_t out_of_range_group_number; - - xkb_layout_index_t num_groups; - struct xkb_group *groups; -}; - -struct xkb_mod { - xkb_atom_t name; - enum mod_type type; - xkb_mod_mask_t mapping; /* vmod -> real mod mapping */ -}; - -struct xkb_mod_set { - struct xkb_mod mods[XKB_MAX_MODS]; - unsigned int num_mods; -}; - -/* Common keyboard description structure */ -struct xkb_keymap { - struct xkb_context *ctx; - - int refcnt; - enum xkb_keymap_compile_flags flags; - enum xkb_keymap_format format; - - enum xkb_action_controls enabled_ctrls; - - xkb_keycode_t min_key_code; - xkb_keycode_t max_key_code; - struct xkb_key *keys; - - /* aliases in no particular order */ - unsigned int num_key_aliases; - struct xkb_key_alias *key_aliases; - - struct xkb_key_type *types; - unsigned int num_types; - - unsigned int num_sym_interprets; - struct xkb_sym_interpret *sym_interprets; - - struct xkb_mod_set mods; - - /* Number of groups in the key with the most groups. */ - xkb_layout_index_t num_groups; - /* Not all groups must have names. */ - xkb_layout_index_t num_group_names; - xkb_atom_t *group_names; - - struct xkb_led leds[XKB_MAX_LEDS]; - unsigned int num_leds; - - char *keycodes_section_name; - char *symbols_section_name; - char *types_section_name; - char *compat_section_name; -}; - -#define xkb_keys_foreach(iter, keymap) \ - for ((iter) = (keymap)->keys + (keymap)->min_key_code; \ - (iter) <= (keymap)->keys + (keymap)->max_key_code; \ - (iter)++) - -#define xkb_mods_foreach(iter, mods_) \ - for ((iter) = (mods_)->mods; \ - (iter) < (mods_)->mods + (mods_)->num_mods; \ - (iter)++) - -#define xkb_mods_enumerate(idx, iter, mods_) \ - for ((idx) = 0, (iter) = (mods_)->mods; \ - (idx) < (mods_)->num_mods; \ - (idx)++, (iter)++) - -#define xkb_leds_foreach(iter, keymap) \ - for ((iter) = (keymap)->leds; \ - (iter) < (keymap)->leds + (keymap)->num_leds; \ - (iter)++) - -#define xkb_leds_enumerate(idx, iter, keymap) \ - for ((idx) = 0, (iter) = (keymap)->leds; \ - (idx) < (keymap)->num_leds; \ - (idx)++, (iter)++) - -static inline const struct xkb_key * -XkbKey(struct xkb_keymap *keymap, xkb_keycode_t kc) -{ - if (kc < keymap->min_key_code || kc > keymap->max_key_code) - return NULL; - return &keymap->keys[kc]; -} - -static inline xkb_level_index_t -XkbKeyNumLevels(const struct xkb_key *key, xkb_layout_index_t layout) -{ - return key->groups[layout].type->num_levels; -} - -struct xkb_keymap * -xkb_keymap_new(struct xkb_context *ctx, - enum xkb_keymap_format format, - enum xkb_keymap_compile_flags flags); - -struct xkb_key * -XkbKeyByName(struct xkb_keymap *keymap, xkb_atom_t name, bool use_aliases); - -xkb_atom_t -XkbResolveKeyAlias(const struct xkb_keymap *keymap, xkb_atom_t name); - -void -XkbEscapeMapName(char *name); - -xkb_mod_index_t -XkbModNameToIndex(const struct xkb_mod_set *mods, xkb_atom_t name, - enum mod_type type); - -bool -XkbLevelsSameSyms(const struct xkb_level *a, const struct xkb_level *b); - -xkb_layout_index_t -XkbWrapGroupIntoRange(int32_t group, - xkb_layout_index_t num_groups, - enum xkb_range_exceed_type out_of_range_group_action, - xkb_layout_index_t out_of_range_group_number); - -xkb_mod_mask_t -mod_mask_get_effective(struct xkb_keymap *keymap, xkb_mod_mask_t mods); - -struct xkb_keymap_format_ops { - bool (*keymap_new_from_names)(struct xkb_keymap *keymap, - const struct xkb_rule_names *names); - bool (*keymap_new_from_string)(struct xkb_keymap *keymap, - const char *string, size_t length); - bool (*keymap_new_from_file)(struct xkb_keymap *keymap, FILE *file); - char *(*keymap_get_as_string)(struct xkb_keymap *keymap); -}; - -extern const struct xkb_keymap_format_ops text_v1_keymap_format_ops; - -#endif diff --git a/src/3rdparty/xkbcommon/src/keysym-utf.c b/src/3rdparty/xkbcommon/src/keysym-utf.c deleted file mode 100644 index c0e76f54da..0000000000 --- a/src/3rdparty/xkbcommon/src/keysym-utf.c +++ /dev/null @@ -1,937 +0,0 @@ -/* The table and comments below along with the function xkb_keysym_to_ucs4 - * are under the public domain and are derived as described below. - */ -/* This module converts keysym values into the corresponding ISO 10646 - * (UCS, Unicode) values. - * - * The array keysymtab[] contains pairs of X11 keysym values for graphical - * characters and the corresponding Unicode value. The function - * keysym2ucs() maps a keysym onto a Unicode value using a binary search, - * therefore keysymtab[] must remain SORTED by keysym value. - * - * The keysym -> UTF-8 conversion will hopefully one day be provided - * by Xlib via XmbLookupString() and should ideally not have to be - * done in X applications. But we are not there yet. - * - * We allow to represent any UCS character in the range U-00000000 to - * U-00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff. - * This admittedly does not cover the entire 31-bit space of UCS, but - * it does cover all of the characters up to U-10FFFF, which can be - * represented by UTF-16, and more, and it is very unlikely that higher - * UCS codes will ever be assigned by ISO. So to get Unicode character - * U+ABCD you can directly use keysym 0x0100abcd. - * - * NOTE: The comments in the table below contain the actual character - * encoded in UTF-8, so for viewing and editing best use an editor in - * UTF-8 mode. - * - * Author: Markus G. Kuhn , - * University of Cambridge, April 2001 - * - * Special thanks to Richard Verhoeven for preparing - * an initial draft of the mapping table. - * - * This software is in the public domain. Share and enjoy! - * - */ - -#include "xkbcommon/xkbcommon.h" -#include "utils.h" -#include "utf8.h" - -/* We don't use the uint32_t types here, to save some space. */ -struct codepair { - uint16_t keysym; - uint16_t ucs; -}; - -static const struct codepair keysymtab[] = { - { 0x01a1, 0x0104 }, /* Aogonek Ą LATIN CAPITAL LETTER A WITH OGONEK */ - { 0x01a2, 0x02d8 }, /* breve ˘ BREVE */ - { 0x01a3, 0x0141 }, /* Lstroke Ł LATIN CAPITAL LETTER L WITH STROKE */ - { 0x01a5, 0x013d }, /* Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON */ - { 0x01a6, 0x015a }, /* Sacute Ś LATIN CAPITAL LETTER S WITH ACUTE */ - { 0x01a9, 0x0160 }, /* Scaron Š LATIN CAPITAL LETTER S WITH CARON */ - { 0x01aa, 0x015e }, /* Scedilla Ş LATIN CAPITAL LETTER S WITH CEDILLA */ - { 0x01ab, 0x0164 }, /* Tcaron Ť LATIN CAPITAL LETTER T WITH CARON */ - { 0x01ac, 0x0179 }, /* Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE */ - { 0x01ae, 0x017d }, /* Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON */ - { 0x01af, 0x017b }, /* Zabovedot Ż LATIN CAPITAL LETTER Z WITH DOT ABOVE */ - { 0x01b1, 0x0105 }, /* aogonek ą LATIN SMALL LETTER A WITH OGONEK */ - { 0x01b2, 0x02db }, /* ogonek ˛ OGONEK */ - { 0x01b3, 0x0142 }, /* lstroke ł LATIN SMALL LETTER L WITH STROKE */ - { 0x01b5, 0x013e }, /* lcaron ľ LATIN SMALL LETTER L WITH CARON */ - { 0x01b6, 0x015b }, /* sacute ś LATIN SMALL LETTER S WITH ACUTE */ - { 0x01b7, 0x02c7 }, /* caron ˇ CARON */ - { 0x01b9, 0x0161 }, /* scaron š LATIN SMALL LETTER S WITH CARON */ - { 0x01ba, 0x015f }, /* scedilla ş LATIN SMALL LETTER S WITH CEDILLA */ - { 0x01bb, 0x0165 }, /* tcaron ť LATIN SMALL LETTER T WITH CARON */ - { 0x01bc, 0x017a }, /* zacute ź LATIN SMALL LETTER Z WITH ACUTE */ - { 0x01bd, 0x02dd }, /* doubleacute ˝ DOUBLE ACUTE ACCENT */ - { 0x01be, 0x017e }, /* zcaron ž LATIN SMALL LETTER Z WITH CARON */ - { 0x01bf, 0x017c }, /* zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE */ - { 0x01c0, 0x0154 }, /* Racute Ŕ LATIN CAPITAL LETTER R WITH ACUTE */ - { 0x01c3, 0x0102 }, /* Abreve Ă LATIN CAPITAL LETTER A WITH BREVE */ - { 0x01c5, 0x0139 }, /* Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE */ - { 0x01c6, 0x0106 }, /* Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE */ - { 0x01c8, 0x010c }, /* Ccaron Č LATIN CAPITAL LETTER C WITH CARON */ - { 0x01ca, 0x0118 }, /* Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK */ - { 0x01cc, 0x011a }, /* Ecaron Ě LATIN CAPITAL LETTER E WITH CARON */ - { 0x01cf, 0x010e }, /* Dcaron Ď LATIN CAPITAL LETTER D WITH CARON */ - { 0x01d0, 0x0110 }, /* Dstroke Đ LATIN CAPITAL LETTER D WITH STROKE */ - { 0x01d1, 0x0143 }, /* Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE */ - { 0x01d2, 0x0147 }, /* Ncaron Ň LATIN CAPITAL LETTER N WITH CARON */ - { 0x01d5, 0x0150 }, /* Odoubleacute Ő LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */ - { 0x01d8, 0x0158 }, /* Rcaron Ř LATIN CAPITAL LETTER R WITH CARON */ - { 0x01d9, 0x016e }, /* Uring Ů LATIN CAPITAL LETTER U WITH RING ABOVE */ - { 0x01db, 0x0170 }, /* Udoubleacute Ű LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */ - { 0x01de, 0x0162 }, /* Tcedilla Ţ LATIN CAPITAL LETTER T WITH CEDILLA */ - { 0x01e0, 0x0155 }, /* racute ŕ LATIN SMALL LETTER R WITH ACUTE */ - { 0x01e3, 0x0103 }, /* abreve ă LATIN SMALL LETTER A WITH BREVE */ - { 0x01e5, 0x013a }, /* lacute ĺ LATIN SMALL LETTER L WITH ACUTE */ - { 0x01e6, 0x0107 }, /* cacute ć LATIN SMALL LETTER C WITH ACUTE */ - { 0x01e8, 0x010d }, /* ccaron č LATIN SMALL LETTER C WITH CARON */ - { 0x01ea, 0x0119 }, /* eogonek ę LATIN SMALL LETTER E WITH OGONEK */ - { 0x01ec, 0x011b }, /* ecaron ě LATIN SMALL LETTER E WITH CARON */ - { 0x01ef, 0x010f }, /* dcaron ď LATIN SMALL LETTER D WITH CARON */ - { 0x01f0, 0x0111 }, /* dstroke đ LATIN SMALL LETTER D WITH STROKE */ - { 0x01f1, 0x0144 }, /* nacute ń LATIN SMALL LETTER N WITH ACUTE */ - { 0x01f2, 0x0148 }, /* ncaron ň LATIN SMALL LETTER N WITH CARON */ - { 0x01f5, 0x0151 }, /* odoubleacute ő LATIN SMALL LETTER O WITH DOUBLE ACUTE */ - { 0x01f8, 0x0159 }, /* rcaron ř LATIN SMALL LETTER R WITH CARON */ - { 0x01f9, 0x016f }, /* uring ů LATIN SMALL LETTER U WITH RING ABOVE */ - { 0x01fb, 0x0171 }, /* udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE */ - { 0x01fe, 0x0163 }, /* tcedilla ţ LATIN SMALL LETTER T WITH CEDILLA */ - { 0x01ff, 0x02d9 }, /* abovedot ˙ DOT ABOVE */ - { 0x02a1, 0x0126 }, /* Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE */ - { 0x02a6, 0x0124 }, /* Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX */ - { 0x02a9, 0x0130 }, /* Iabovedot İ LATIN CAPITAL LETTER I WITH DOT ABOVE */ - { 0x02ab, 0x011e }, /* Gbreve Ğ LATIN CAPITAL LETTER G WITH BREVE */ - { 0x02ac, 0x0134 }, /* Jcircumflex Ĵ LATIN CAPITAL LETTER J WITH CIRCUMFLEX */ - { 0x02b1, 0x0127 }, /* hstroke ħ LATIN SMALL LETTER H WITH STROKE */ - { 0x02b6, 0x0125 }, /* hcircumflex ĥ LATIN SMALL LETTER H WITH CIRCUMFLEX */ - { 0x02b9, 0x0131 }, /* idotless ı LATIN SMALL LETTER DOTLESS I */ - { 0x02bb, 0x011f }, /* gbreve ğ LATIN SMALL LETTER G WITH BREVE */ - { 0x02bc, 0x0135 }, /* jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX */ - { 0x02c5, 0x010a }, /* Cabovedot Ċ LATIN CAPITAL LETTER C WITH DOT ABOVE */ - { 0x02c6, 0x0108 }, /* Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX */ - { 0x02d5, 0x0120 }, /* Gabovedot Ġ LATIN CAPITAL LETTER G WITH DOT ABOVE */ - { 0x02d8, 0x011c }, /* Gcircumflex Ĝ LATIN CAPITAL LETTER G WITH CIRCUMFLEX */ - { 0x02dd, 0x016c }, /* Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE */ - { 0x02de, 0x015c }, /* Scircumflex Ŝ LATIN CAPITAL LETTER S WITH CIRCUMFLEX */ - { 0x02e5, 0x010b }, /* cabovedot ċ LATIN SMALL LETTER C WITH DOT ABOVE */ - { 0x02e6, 0x0109 }, /* ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX */ - { 0x02f5, 0x0121 }, /* gabovedot ġ LATIN SMALL LETTER G WITH DOT ABOVE */ - { 0x02f8, 0x011d }, /* gcircumflex ĝ LATIN SMALL LETTER G WITH CIRCUMFLEX */ - { 0x02fd, 0x016d }, /* ubreve ŭ LATIN SMALL LETTER U WITH BREVE */ - { 0x02fe, 0x015d }, /* scircumflex ŝ LATIN SMALL LETTER S WITH CIRCUMFLEX */ - { 0x03a2, 0x0138 }, /* kra ĸ LATIN SMALL LETTER KRA */ - { 0x03a3, 0x0156 }, /* Rcedilla Ŗ LATIN CAPITAL LETTER R WITH CEDILLA */ - { 0x03a5, 0x0128 }, /* Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE */ - { 0x03a6, 0x013b }, /* Lcedilla Ļ LATIN CAPITAL LETTER L WITH CEDILLA */ - { 0x03aa, 0x0112 }, /* Emacron Ē LATIN CAPITAL LETTER E WITH MACRON */ - { 0x03ab, 0x0122 }, /* Gcedilla Ģ LATIN CAPITAL LETTER G WITH CEDILLA */ - { 0x03ac, 0x0166 }, /* Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE */ - { 0x03b3, 0x0157 }, /* rcedilla ŗ LATIN SMALL LETTER R WITH CEDILLA */ - { 0x03b5, 0x0129 }, /* itilde ĩ LATIN SMALL LETTER I WITH TILDE */ - { 0x03b6, 0x013c }, /* lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA */ - { 0x03ba, 0x0113 }, /* emacron ē LATIN SMALL LETTER E WITH MACRON */ - { 0x03bb, 0x0123 }, /* gcedilla ģ LATIN SMALL LETTER G WITH CEDILLA */ - { 0x03bc, 0x0167 }, /* tslash ŧ LATIN SMALL LETTER T WITH STROKE */ - { 0x03bd, 0x014a }, /* ENG Ŋ LATIN CAPITAL LETTER ENG */ - { 0x03bf, 0x014b }, /* eng ŋ LATIN SMALL LETTER ENG */ - { 0x03c0, 0x0100 }, /* Amacron Ā LATIN CAPITAL LETTER A WITH MACRON */ - { 0x03c7, 0x012e }, /* Iogonek Į LATIN CAPITAL LETTER I WITH OGONEK */ - { 0x03cc, 0x0116 }, /* Eabovedot Ė LATIN CAPITAL LETTER E WITH DOT ABOVE */ - { 0x03cf, 0x012a }, /* Imacron Ī LATIN CAPITAL LETTER I WITH MACRON */ - { 0x03d1, 0x0145 }, /* Ncedilla Ņ LATIN CAPITAL LETTER N WITH CEDILLA */ - { 0x03d2, 0x014c }, /* Omacron Ō LATIN CAPITAL LETTER O WITH MACRON */ - { 0x03d3, 0x0136 }, /* Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA */ - { 0x03d9, 0x0172 }, /* Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK */ - { 0x03dd, 0x0168 }, /* Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE */ - { 0x03de, 0x016a }, /* Umacron Ū LATIN CAPITAL LETTER U WITH MACRON */ - { 0x03e0, 0x0101 }, /* amacron ā LATIN SMALL LETTER A WITH MACRON */ - { 0x03e7, 0x012f }, /* iogonek į LATIN SMALL LETTER I WITH OGONEK */ - { 0x03ec, 0x0117 }, /* eabovedot ė LATIN SMALL LETTER E WITH DOT ABOVE */ - { 0x03ef, 0x012b }, /* imacron ī LATIN SMALL LETTER I WITH MACRON */ - { 0x03f1, 0x0146 }, /* ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA */ - { 0x03f2, 0x014d }, /* omacron ō LATIN SMALL LETTER O WITH MACRON */ - { 0x03f3, 0x0137 }, /* kcedilla ķ LATIN SMALL LETTER K WITH CEDILLA */ - { 0x03f9, 0x0173 }, /* uogonek ų LATIN SMALL LETTER U WITH OGONEK */ - { 0x03fd, 0x0169 }, /* utilde ũ LATIN SMALL LETTER U WITH TILDE */ - { 0x03fe, 0x016b }, /* umacron ū LATIN SMALL LETTER U WITH MACRON */ - { 0x047e, 0x203e }, /* overline ‾ OVERLINE */ - { 0x04a1, 0x3002 }, /* kana_fullstop 。 IDEOGRAPHIC FULL STOP */ - { 0x04a2, 0x300c }, /* kana_openingbracket 「 LEFT CORNER BRACKET */ - { 0x04a3, 0x300d }, /* kana_closingbracket 」 RIGHT CORNER BRACKET */ - { 0x04a4, 0x3001 }, /* kana_comma 、 IDEOGRAPHIC COMMA */ - { 0x04a5, 0x30fb }, /* kana_conjunctive ・ KATAKANA MIDDLE DOT */ - { 0x04a6, 0x30f2 }, /* kana_WO ヲ KATAKANA LETTER WO */ - { 0x04a7, 0x30a1 }, /* kana_a ァ KATAKANA LETTER SMALL A */ - { 0x04a8, 0x30a3 }, /* kana_i ィ KATAKANA LETTER SMALL I */ - { 0x04a9, 0x30a5 }, /* kana_u ゥ KATAKANA LETTER SMALL U */ - { 0x04aa, 0x30a7 }, /* kana_e ェ KATAKANA LETTER SMALL E */ - { 0x04ab, 0x30a9 }, /* kana_o ォ KATAKANA LETTER SMALL O */ - { 0x04ac, 0x30e3 }, /* kana_ya ャ KATAKANA LETTER SMALL YA */ - { 0x04ad, 0x30e5 }, /* kana_yu ュ KATAKANA LETTER SMALL YU */ - { 0x04ae, 0x30e7 }, /* kana_yo ョ KATAKANA LETTER SMALL YO */ - { 0x04af, 0x30c3 }, /* kana_tsu ッ KATAKANA LETTER SMALL TU */ - { 0x04b0, 0x30fc }, /* prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK */ - { 0x04b1, 0x30a2 }, /* kana_A ア KATAKANA LETTER A */ - { 0x04b2, 0x30a4 }, /* kana_I イ KATAKANA LETTER I */ - { 0x04b3, 0x30a6 }, /* kana_U ウ KATAKANA LETTER U */ - { 0x04b4, 0x30a8 }, /* kana_E エ KATAKANA LETTER E */ - { 0x04b5, 0x30aa }, /* kana_O オ KATAKANA LETTER O */ - { 0x04b6, 0x30ab }, /* kana_KA カ KATAKANA LETTER KA */ - { 0x04b7, 0x30ad }, /* kana_KI キ KATAKANA LETTER KI */ - { 0x04b8, 0x30af }, /* kana_KU ク KATAKANA LETTER KU */ - { 0x04b9, 0x30b1 }, /* kana_KE ケ KATAKANA LETTER KE */ - { 0x04ba, 0x30b3 }, /* kana_KO コ KATAKANA LETTER KO */ - { 0x04bb, 0x30b5 }, /* kana_SA サ KATAKANA LETTER SA */ - { 0x04bc, 0x30b7 }, /* kana_SHI シ KATAKANA LETTER SI */ - { 0x04bd, 0x30b9 }, /* kana_SU ス KATAKANA LETTER SU */ - { 0x04be, 0x30bb }, /* kana_SE セ KATAKANA LETTER SE */ - { 0x04bf, 0x30bd }, /* kana_SO ソ KATAKANA LETTER SO */ - { 0x04c0, 0x30bf }, /* kana_TA タ KATAKANA LETTER TA */ - { 0x04c1, 0x30c1 }, /* kana_CHI チ KATAKANA LETTER TI */ - { 0x04c2, 0x30c4 }, /* kana_TSU ツ KATAKANA LETTER TU */ - { 0x04c3, 0x30c6 }, /* kana_TE テ KATAKANA LETTER TE */ - { 0x04c4, 0x30c8 }, /* kana_TO ト KATAKANA LETTER TO */ - { 0x04c5, 0x30ca }, /* kana_NA ナ KATAKANA LETTER NA */ - { 0x04c6, 0x30cb }, /* kana_NI ニ KATAKANA LETTER NI */ - { 0x04c7, 0x30cc }, /* kana_NU ヌ KATAKANA LETTER NU */ - { 0x04c8, 0x30cd }, /* kana_NE ネ KATAKANA LETTER NE */ - { 0x04c9, 0x30ce }, /* kana_NO ノ KATAKANA LETTER NO */ - { 0x04ca, 0x30cf }, /* kana_HA ハ KATAKANA LETTER HA */ - { 0x04cb, 0x30d2 }, /* kana_HI ヒ KATAKANA LETTER HI */ - { 0x04cc, 0x30d5 }, /* kana_FU フ KATAKANA LETTER HU */ - { 0x04cd, 0x30d8 }, /* kana_HE ヘ KATAKANA LETTER HE */ - { 0x04ce, 0x30db }, /* kana_HO ホ KATAKANA LETTER HO */ - { 0x04cf, 0x30de }, /* kana_MA マ KATAKANA LETTER MA */ - { 0x04d0, 0x30df }, /* kana_MI ミ KATAKANA LETTER MI */ - { 0x04d1, 0x30e0 }, /* kana_MU ム KATAKANA LETTER MU */ - { 0x04d2, 0x30e1 }, /* kana_ME メ KATAKANA LETTER ME */ - { 0x04d3, 0x30e2 }, /* kana_MO モ KATAKANA LETTER MO */ - { 0x04d4, 0x30e4 }, /* kana_YA ヤ KATAKANA LETTER YA */ - { 0x04d5, 0x30e6 }, /* kana_YU ユ KATAKANA LETTER YU */ - { 0x04d6, 0x30e8 }, /* kana_YO ヨ KATAKANA LETTER YO */ - { 0x04d7, 0x30e9 }, /* kana_RA ラ KATAKANA LETTER RA */ - { 0x04d8, 0x30ea }, /* kana_RI リ KATAKANA LETTER RI */ - { 0x04d9, 0x30eb }, /* kana_RU ル KATAKANA LETTER RU */ - { 0x04da, 0x30ec }, /* kana_RE レ KATAKANA LETTER RE */ - { 0x04db, 0x30ed }, /* kana_RO ロ KATAKANA LETTER RO */ - { 0x04dc, 0x30ef }, /* kana_WA ワ KATAKANA LETTER WA */ - { 0x04dd, 0x30f3 }, /* kana_N ン KATAKANA LETTER N */ - { 0x04de, 0x309b }, /* voicedsound ゛ KATAKANA-HIRAGANA VOICED SOUND MARK */ - { 0x04df, 0x309c }, /* semivoicedsound ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ - { 0x05ac, 0x060c }, /* Arabic_comma ، ARABIC COMMA */ - { 0x05bb, 0x061b }, /* Arabic_semicolon ؛ ARABIC SEMICOLON */ - { 0x05bf, 0x061f }, /* Arabic_question_mark ؟ ARABIC QUESTION MARK */ - { 0x05c1, 0x0621 }, /* Arabic_hamza ء ARABIC LETTER HAMZA */ - { 0x05c2, 0x0622 }, /* Arabic_maddaonalef آ ARABIC LETTER ALEF WITH MADDA ABOVE */ - { 0x05c3, 0x0623 }, /* Arabic_hamzaonalef أ ARABIC LETTER ALEF WITH HAMZA ABOVE */ - { 0x05c4, 0x0624 }, /* Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE */ - { 0x05c5, 0x0625 }, /* Arabic_hamzaunderalef إ ARABIC LETTER ALEF WITH HAMZA BELOW */ - { 0x05c6, 0x0626 }, /* Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE */ - { 0x05c7, 0x0627 }, /* Arabic_alef ا ARABIC LETTER ALEF */ - { 0x05c8, 0x0628 }, /* Arabic_beh ب ARABIC LETTER BEH */ - { 0x05c9, 0x0629 }, /* Arabic_tehmarbuta ة ARABIC LETTER TEH MARBUTA */ - { 0x05ca, 0x062a }, /* Arabic_teh ت ARABIC LETTER TEH */ - { 0x05cb, 0x062b }, /* Arabic_theh ث ARABIC LETTER THEH */ - { 0x05cc, 0x062c }, /* Arabic_jeem ج ARABIC LETTER JEEM */ - { 0x05cd, 0x062d }, /* Arabic_hah ح ARABIC LETTER HAH */ - { 0x05ce, 0x062e }, /* Arabic_khah خ ARABIC LETTER KHAH */ - { 0x05cf, 0x062f }, /* Arabic_dal د ARABIC LETTER DAL */ - { 0x05d0, 0x0630 }, /* Arabic_thal ذ ARABIC LETTER THAL */ - { 0x05d1, 0x0631 }, /* Arabic_ra ر ARABIC LETTER REH */ - { 0x05d2, 0x0632 }, /* Arabic_zain ز ARABIC LETTER ZAIN */ - { 0x05d3, 0x0633 }, /* Arabic_seen س ARABIC LETTER SEEN */ - { 0x05d4, 0x0634 }, /* Arabic_sheen ش ARABIC LETTER SHEEN */ - { 0x05d5, 0x0635 }, /* Arabic_sad ص ARABIC LETTER SAD */ - { 0x05d6, 0x0636 }, /* Arabic_dad ض ARABIC LETTER DAD */ - { 0x05d7, 0x0637 }, /* Arabic_tah ط ARABIC LETTER TAH */ - { 0x05d8, 0x0638 }, /* Arabic_zah ظ ARABIC LETTER ZAH */ - { 0x05d9, 0x0639 }, /* Arabic_ain ع ARABIC LETTER AIN */ - { 0x05da, 0x063a }, /* Arabic_ghain غ ARABIC LETTER GHAIN */ - { 0x05e0, 0x0640 }, /* Arabic_tatweel ـ ARABIC TATWEEL */ - { 0x05e1, 0x0641 }, /* Arabic_feh ف ARABIC LETTER FEH */ - { 0x05e2, 0x0642 }, /* Arabic_qaf ق ARABIC LETTER QAF */ - { 0x05e3, 0x0643 }, /* Arabic_kaf ك ARABIC LETTER KAF */ - { 0x05e4, 0x0644 }, /* Arabic_lam ل ARABIC LETTER LAM */ - { 0x05e5, 0x0645 }, /* Arabic_meem م ARABIC LETTER MEEM */ - { 0x05e6, 0x0646 }, /* Arabic_noon ن ARABIC LETTER NOON */ - { 0x05e7, 0x0647 }, /* Arabic_ha ه ARABIC LETTER HEH */ - { 0x05e8, 0x0648 }, /* Arabic_waw و ARABIC LETTER WAW */ - { 0x05e9, 0x0649 }, /* Arabic_alefmaksura ى ARABIC LETTER ALEF MAKSURA */ - { 0x05ea, 0x064a }, /* Arabic_yeh ي ARABIC LETTER YEH */ - { 0x05eb, 0x064b }, /* Arabic_fathatan ً ARABIC FATHATAN */ - { 0x05ec, 0x064c }, /* Arabic_dammatan ٌ ARABIC DAMMATAN */ - { 0x05ed, 0x064d }, /* Arabic_kasratan ٍ ARABIC KASRATAN */ - { 0x05ee, 0x064e }, /* Arabic_fatha َ ARABIC FATHA */ - { 0x05ef, 0x064f }, /* Arabic_damma ُ ARABIC DAMMA */ - { 0x05f0, 0x0650 }, /* Arabic_kasra ِ ARABIC KASRA */ - { 0x05f1, 0x0651 }, /* Arabic_shadda ّ ARABIC SHADDA */ - { 0x05f2, 0x0652 }, /* Arabic_sukun ْ ARABIC SUKUN */ - { 0x06a1, 0x0452 }, /* Serbian_dje ђ CYRILLIC SMALL LETTER DJE */ - { 0x06a2, 0x0453 }, /* Macedonia_gje ѓ CYRILLIC SMALL LETTER GJE */ - { 0x06a3, 0x0451 }, /* Cyrillic_io ё CYRILLIC SMALL LETTER IO */ - { 0x06a4, 0x0454 }, /* Ukrainian_ie є CYRILLIC SMALL LETTER UKRAINIAN IE */ - { 0x06a5, 0x0455 }, /* Macedonia_dse ѕ CYRILLIC SMALL LETTER DZE */ - { 0x06a6, 0x0456 }, /* Ukrainian_i і CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */ - { 0x06a7, 0x0457 }, /* Ukrainian_yi ї CYRILLIC SMALL LETTER YI */ - { 0x06a8, 0x0458 }, /* Cyrillic_je ј CYRILLIC SMALL LETTER JE */ - { 0x06a9, 0x0459 }, /* Cyrillic_lje љ CYRILLIC SMALL LETTER LJE */ - { 0x06aa, 0x045a }, /* Cyrillic_nje њ CYRILLIC SMALL LETTER NJE */ - { 0x06ab, 0x045b }, /* Serbian_tshe ћ CYRILLIC SMALL LETTER TSHE */ - { 0x06ac, 0x045c }, /* Macedonia_kje ќ CYRILLIC SMALL LETTER KJE */ - { 0x06ad, 0x0491 }, /* Ukrainian_ghe_with_upturn ґ CYRILLIC SMALL LETTER GHE WITH UPTURN */ - { 0x06ae, 0x045e }, /* Byelorussian_shortu ў CYRILLIC SMALL LETTER SHORT U */ - { 0x06af, 0x045f }, /* Cyrillic_dzhe џ CYRILLIC SMALL LETTER DZHE */ - { 0x06b0, 0x2116 }, /* numerosign № NUMERO SIGN */ - { 0x06b1, 0x0402 }, /* Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE */ - { 0x06b2, 0x0403 }, /* Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE */ - { 0x06b3, 0x0401 }, /* Cyrillic_IO Ё CYRILLIC CAPITAL LETTER IO */ - { 0x06b4, 0x0404 }, /* Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE */ - { 0x06b5, 0x0405 }, /* Macedonia_DSE Ѕ CYRILLIC CAPITAL LETTER DZE */ - { 0x06b6, 0x0406 }, /* Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */ - { 0x06b7, 0x0407 }, /* Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI */ - { 0x06b8, 0x0408 }, /* Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE */ - { 0x06b9, 0x0409 }, /* Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE */ - { 0x06ba, 0x040a }, /* Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE */ - { 0x06bb, 0x040b }, /* Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE */ - { 0x06bc, 0x040c }, /* Macedonia_KJE Ќ CYRILLIC CAPITAL LETTER KJE */ - { 0x06bd, 0x0490 }, /* Ukrainian_GHE_WITH_UPTURN Ґ CYRILLIC CAPITAL LETTER GHE WITH UPTURN */ - { 0x06be, 0x040e }, /* Byelorussian_SHORTU Ў CYRILLIC CAPITAL LETTER SHORT U */ - { 0x06bf, 0x040f }, /* Cyrillic_DZHE Џ CYRILLIC CAPITAL LETTER DZHE */ - { 0x06c0, 0x044e }, /* Cyrillic_yu ю CYRILLIC SMALL LETTER YU */ - { 0x06c1, 0x0430 }, /* Cyrillic_a а CYRILLIC SMALL LETTER A */ - { 0x06c2, 0x0431 }, /* Cyrillic_be б CYRILLIC SMALL LETTER BE */ - { 0x06c3, 0x0446 }, /* Cyrillic_tse ц CYRILLIC SMALL LETTER TSE */ - { 0x06c4, 0x0434 }, /* Cyrillic_de д CYRILLIC SMALL LETTER DE */ - { 0x06c5, 0x0435 }, /* Cyrillic_ie е CYRILLIC SMALL LETTER IE */ - { 0x06c6, 0x0444 }, /* Cyrillic_ef ф CYRILLIC SMALL LETTER EF */ - { 0x06c7, 0x0433 }, /* Cyrillic_ghe г CYRILLIC SMALL LETTER GHE */ - { 0x06c8, 0x0445 }, /* Cyrillic_ha х CYRILLIC SMALL LETTER HA */ - { 0x06c9, 0x0438 }, /* Cyrillic_i и CYRILLIC SMALL LETTER I */ - { 0x06ca, 0x0439 }, /* Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I */ - { 0x06cb, 0x043a }, /* Cyrillic_ka к CYRILLIC SMALL LETTER KA */ - { 0x06cc, 0x043b }, /* Cyrillic_el л CYRILLIC SMALL LETTER EL */ - { 0x06cd, 0x043c }, /* Cyrillic_em м CYRILLIC SMALL LETTER EM */ - { 0x06ce, 0x043d }, /* Cyrillic_en н CYRILLIC SMALL LETTER EN */ - { 0x06cf, 0x043e }, /* Cyrillic_o о CYRILLIC SMALL LETTER O */ - { 0x06d0, 0x043f }, /* Cyrillic_pe п CYRILLIC SMALL LETTER PE */ - { 0x06d1, 0x044f }, /* Cyrillic_ya я CYRILLIC SMALL LETTER YA */ - { 0x06d2, 0x0440 }, /* Cyrillic_er р CYRILLIC SMALL LETTER ER */ - { 0x06d3, 0x0441 }, /* Cyrillic_es с CYRILLIC SMALL LETTER ES */ - { 0x06d4, 0x0442 }, /* Cyrillic_te т CYRILLIC SMALL LETTER TE */ - { 0x06d5, 0x0443 }, /* Cyrillic_u у CYRILLIC SMALL LETTER U */ - { 0x06d6, 0x0436 }, /* Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE */ - { 0x06d7, 0x0432 }, /* Cyrillic_ve в CYRILLIC SMALL LETTER VE */ - { 0x06d8, 0x044c }, /* Cyrillic_softsign ь CYRILLIC SMALL LETTER SOFT SIGN */ - { 0x06d9, 0x044b }, /* Cyrillic_yeru ы CYRILLIC SMALL LETTER YERU */ - { 0x06da, 0x0437 }, /* Cyrillic_ze з CYRILLIC SMALL LETTER ZE */ - { 0x06db, 0x0448 }, /* Cyrillic_sha ш CYRILLIC SMALL LETTER SHA */ - { 0x06dc, 0x044d }, /* Cyrillic_e э CYRILLIC SMALL LETTER E */ - { 0x06dd, 0x0449 }, /* Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA */ - { 0x06de, 0x0447 }, /* Cyrillic_che ч CYRILLIC SMALL LETTER CHE */ - { 0x06df, 0x044a }, /* Cyrillic_hardsign ъ CYRILLIC SMALL LETTER HARD SIGN */ - { 0x06e0, 0x042e }, /* Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU */ - { 0x06e1, 0x0410 }, /* Cyrillic_A А CYRILLIC CAPITAL LETTER A */ - { 0x06e2, 0x0411 }, /* Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE */ - { 0x06e3, 0x0426 }, /* Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE */ - { 0x06e4, 0x0414 }, /* Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE */ - { 0x06e5, 0x0415 }, /* Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE */ - { 0x06e6, 0x0424 }, /* Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF */ - { 0x06e7, 0x0413 }, /* Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE */ - { 0x06e8, 0x0425 }, /* Cyrillic_HA Х CYRILLIC CAPITAL LETTER HA */ - { 0x06e9, 0x0418 }, /* Cyrillic_I И CYRILLIC CAPITAL LETTER I */ - { 0x06ea, 0x0419 }, /* Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I */ - { 0x06eb, 0x041a }, /* Cyrillic_KA К CYRILLIC CAPITAL LETTER KA */ - { 0x06ec, 0x041b }, /* Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL */ - { 0x06ed, 0x041c }, /* Cyrillic_EM М CYRILLIC CAPITAL LETTER EM */ - { 0x06ee, 0x041d }, /* Cyrillic_EN Н CYRILLIC CAPITAL LETTER EN */ - { 0x06ef, 0x041e }, /* Cyrillic_O О CYRILLIC CAPITAL LETTER O */ - { 0x06f0, 0x041f }, /* Cyrillic_PE П CYRILLIC CAPITAL LETTER PE */ - { 0x06f1, 0x042f }, /* Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA */ - { 0x06f2, 0x0420 }, /* Cyrillic_ER Р CYRILLIC CAPITAL LETTER ER */ - { 0x06f3, 0x0421 }, /* Cyrillic_ES С CYRILLIC CAPITAL LETTER ES */ - { 0x06f4, 0x0422 }, /* Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE */ - { 0x06f5, 0x0423 }, /* Cyrillic_U У CYRILLIC CAPITAL LETTER U */ - { 0x06f6, 0x0416 }, /* Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE */ - { 0x06f7, 0x0412 }, /* Cyrillic_VE В CYRILLIC CAPITAL LETTER VE */ - { 0x06f8, 0x042c }, /* Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN */ - { 0x06f9, 0x042b }, /* Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU */ - { 0x06fa, 0x0417 }, /* Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE */ - { 0x06fb, 0x0428 }, /* Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA */ - { 0x06fc, 0x042d }, /* Cyrillic_E Э CYRILLIC CAPITAL LETTER E */ - { 0x06fd, 0x0429 }, /* Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA */ - { 0x06fe, 0x0427 }, /* Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE */ - { 0x06ff, 0x042a }, /* Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN */ - { 0x07a1, 0x0386 }, /* Greek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS */ - { 0x07a2, 0x0388 }, /* Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */ - { 0x07a3, 0x0389 }, /* Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */ - { 0x07a4, 0x038a }, /* Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */ - { 0x07a5, 0x03aa }, /* Greek_IOTAdiaeresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */ - { 0x07a7, 0x038c }, /* Greek_OMICRONaccent Ό GREEK CAPITAL LETTER OMICRON WITH TONOS */ - { 0x07a8, 0x038e }, /* Greek_UPSILONaccent Ύ GREEK CAPITAL LETTER UPSILON WITH TONOS */ - { 0x07a9, 0x03ab }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */ - { 0x07ab, 0x038f }, /* Greek_OMEGAaccent Ώ GREEK CAPITAL LETTER OMEGA WITH TONOS */ - { 0x07ae, 0x0385 }, /* Greek_accentdieresis ΅ GREEK DIALYTIKA TONOS */ - { 0x07af, 0x2015 }, /* Greek_horizbar ― HORIZONTAL BAR */ - { 0x07b1, 0x03ac }, /* Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */ - { 0x07b2, 0x03ad }, /* Greek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS */ - { 0x07b3, 0x03ae }, /* Greek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS */ - { 0x07b4, 0x03af }, /* Greek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS */ - { 0x07b5, 0x03ca }, /* Greek_iotadieresis ϊ GREEK SMALL LETTER IOTA WITH DIALYTIKA */ - { 0x07b6, 0x0390 }, /* Greek_iotaaccentdieresis ΐ GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ - { 0x07b7, 0x03cc }, /* Greek_omicronaccent ό GREEK SMALL LETTER OMICRON WITH TONOS */ - { 0x07b8, 0x03cd }, /* Greek_upsilonaccent ύ GREEK SMALL LETTER UPSILON WITH TONOS */ - { 0x07b9, 0x03cb }, /* Greek_upsilondieresis ϋ GREEK SMALL LETTER UPSILON WITH DIALYTIKA */ - { 0x07ba, 0x03b0 }, /* Greek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ - { 0x07bb, 0x03ce }, /* Greek_omegaaccent ώ GREEK SMALL LETTER OMEGA WITH TONOS */ - { 0x07c1, 0x0391 }, /* Greek_ALPHA Α GREEK CAPITAL LETTER ALPHA */ - { 0x07c2, 0x0392 }, /* Greek_BETA Β GREEK CAPITAL LETTER BETA */ - { 0x07c3, 0x0393 }, /* Greek_GAMMA Γ GREEK CAPITAL LETTER GAMMA */ - { 0x07c4, 0x0394 }, /* Greek_DELTA Δ GREEK CAPITAL LETTER DELTA */ - { 0x07c5, 0x0395 }, /* Greek_EPSILON Ε GREEK CAPITAL LETTER EPSILON */ - { 0x07c6, 0x0396 }, /* Greek_ZETA Ζ GREEK CAPITAL LETTER ZETA */ - { 0x07c7, 0x0397 }, /* Greek_ETA Η GREEK CAPITAL LETTER ETA */ - { 0x07c8, 0x0398 }, /* Greek_THETA Θ GREEK CAPITAL LETTER THETA */ - { 0x07c9, 0x0399 }, /* Greek_IOTA Ι GREEK CAPITAL LETTER IOTA */ - { 0x07ca, 0x039a }, /* Greek_KAPPA Κ GREEK CAPITAL LETTER KAPPA */ - { 0x07cb, 0x039b }, /* Greek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA */ - { 0x07cc, 0x039c }, /* Greek_MU Μ GREEK CAPITAL LETTER MU */ - { 0x07cd, 0x039d }, /* Greek_NU Ν GREEK CAPITAL LETTER NU */ - { 0x07ce, 0x039e }, /* Greek_XI Ξ GREEK CAPITAL LETTER XI */ - { 0x07cf, 0x039f }, /* Greek_OMICRON Ο GREEK CAPITAL LETTER OMICRON */ - { 0x07d0, 0x03a0 }, /* Greek_PI Π GREEK CAPITAL LETTER PI */ - { 0x07d1, 0x03a1 }, /* Greek_RHO Ρ GREEK CAPITAL LETTER RHO */ - { 0x07d2, 0x03a3 }, /* Greek_SIGMA Σ GREEK CAPITAL LETTER SIGMA */ - { 0x07d4, 0x03a4 }, /* Greek_TAU Τ GREEK CAPITAL LETTER TAU */ - { 0x07d5, 0x03a5 }, /* Greek_UPSILON Υ GREEK CAPITAL LETTER UPSILON */ - { 0x07d6, 0x03a6 }, /* Greek_PHI Φ GREEK CAPITAL LETTER PHI */ - { 0x07d7, 0x03a7 }, /* Greek_CHI Χ GREEK CAPITAL LETTER CHI */ - { 0x07d8, 0x03a8 }, /* Greek_PSI Ψ GREEK CAPITAL LETTER PSI */ - { 0x07d9, 0x03a9 }, /* Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */ - { 0x07e1, 0x03b1 }, /* Greek_alpha α GREEK SMALL LETTER ALPHA */ - { 0x07e2, 0x03b2 }, /* Greek_beta β GREEK SMALL LETTER BETA */ - { 0x07e3, 0x03b3 }, /* Greek_gamma γ GREEK SMALL LETTER GAMMA */ - { 0x07e4, 0x03b4 }, /* Greek_delta δ GREEK SMALL LETTER DELTA */ - { 0x07e5, 0x03b5 }, /* Greek_epsilon ε GREEK SMALL LETTER EPSILON */ - { 0x07e6, 0x03b6 }, /* Greek_zeta ζ GREEK SMALL LETTER ZETA */ - { 0x07e7, 0x03b7 }, /* Greek_eta η GREEK SMALL LETTER ETA */ - { 0x07e8, 0x03b8 }, /* Greek_theta θ GREEK SMALL LETTER THETA */ - { 0x07e9, 0x03b9 }, /* Greek_iota ι GREEK SMALL LETTER IOTA */ - { 0x07ea, 0x03ba }, /* Greek_kappa κ GREEK SMALL LETTER KAPPA */ - { 0x07eb, 0x03bb }, /* Greek_lambda λ GREEK SMALL LETTER LAMDA */ - { 0x07ec, 0x03bc }, /* Greek_mu μ GREEK SMALL LETTER MU */ - { 0x07ed, 0x03bd }, /* Greek_nu ν GREEK SMALL LETTER NU */ - { 0x07ee, 0x03be }, /* Greek_xi ξ GREEK SMALL LETTER XI */ - { 0x07ef, 0x03bf }, /* Greek_omicron ο GREEK SMALL LETTER OMICRON */ - { 0x07f0, 0x03c0 }, /* Greek_pi π GREEK SMALL LETTER PI */ - { 0x07f1, 0x03c1 }, /* Greek_rho ρ GREEK SMALL LETTER RHO */ - { 0x07f2, 0x03c3 }, /* Greek_sigma σ GREEK SMALL LETTER SIGMA */ - { 0x07f3, 0x03c2 }, /* Greek_finalsmallsigma ς GREEK SMALL LETTER FINAL SIGMA */ - { 0x07f4, 0x03c4 }, /* Greek_tau τ GREEK SMALL LETTER TAU */ - { 0x07f5, 0x03c5 }, /* Greek_upsilon υ GREEK SMALL LETTER UPSILON */ - { 0x07f6, 0x03c6 }, /* Greek_phi φ GREEK SMALL LETTER PHI */ - { 0x07f7, 0x03c7 }, /* Greek_chi χ GREEK SMALL LETTER CHI */ - { 0x07f8, 0x03c8 }, /* Greek_psi ψ GREEK SMALL LETTER PSI */ - { 0x07f9, 0x03c9 }, /* Greek_omega ω GREEK SMALL LETTER OMEGA */ - { 0x08a1, 0x23b7 }, /* leftradical ⎷ ??? */ - { 0x08a2, 0x250c }, /* topleftradical ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */ - { 0x08a3, 0x2500 }, /* horizconnector ─ BOX DRAWINGS LIGHT HORIZONTAL */ - { 0x08a4, 0x2320 }, /* topintegral ⌠ TOP HALF INTEGRAL */ - { 0x08a5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */ - { 0x08a6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */ - { 0x08a7, 0x23a1 }, /* topleftsqbracket ⎡ ??? */ - { 0x08a8, 0x23a3 }, /* botleftsqbracket ⎣ ??? */ - { 0x08a9, 0x23a4 }, /* toprightsqbracket ⎤ ??? */ - { 0x08aa, 0x23a6 }, /* botrightsqbracket ⎦ ??? */ - { 0x08ab, 0x239b }, /* topleftparens ⎛ ??? */ - { 0x08ac, 0x239d }, /* botleftparens ⎝ ??? */ - { 0x08ad, 0x239e }, /* toprightparens ⎞ ??? */ - { 0x08ae, 0x23a0 }, /* botrightparens ⎠ ??? */ - { 0x08af, 0x23a8 }, /* leftmiddlecurlybrace ⎨ ??? */ - { 0x08b0, 0x23ac }, /* rightmiddlecurlybrace ⎬ ??? */ - /* 0x08b1 topleftsummation ? ??? */ - /* 0x08b2 botleftsummation ? ??? */ - /* 0x08b3 topvertsummationconnector ? ??? */ - /* 0x08b4 botvertsummationconnector ? ??? */ - /* 0x08b5 toprightsummation ? ??? */ - /* 0x08b6 botrightsummation ? ??? */ - /* 0x08b7 rightmiddlesummation ? ??? */ - { 0x08bc, 0x2264 }, /* lessthanequal ≤ LESS-THAN OR EQUAL TO */ - { 0x08bd, 0x2260 }, /* notequal ≠ NOT EQUAL TO */ - { 0x08be, 0x2265 }, /* greaterthanequal ≥ GREATER-THAN OR EQUAL TO */ - { 0x08bf, 0x222b }, /* integral ∫ INTEGRAL */ - { 0x08c0, 0x2234 }, /* therefore ∴ THEREFORE */ - { 0x08c1, 0x221d }, /* variation ∝ PROPORTIONAL TO */ - { 0x08c2, 0x221e }, /* infinity ∞ INFINITY */ - { 0x08c5, 0x2207 }, /* nabla ∇ NABLA */ - { 0x08c8, 0x223c }, /* approximate ∼ TILDE OPERATOR */ - { 0x08c9, 0x2243 }, /* similarequal ≃ ASYMPTOTICALLY EQUAL TO */ - { 0x08cd, 0x21d4 }, /* ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */ - { 0x08ce, 0x21d2 }, /* implies ⇒ RIGHTWARDS DOUBLE ARROW */ - { 0x08cf, 0x2261 }, /* identical ≡ IDENTICAL TO */ - { 0x08d6, 0x221a }, /* radical √ SQUARE ROOT */ - { 0x08da, 0x2282 }, /* includedin ⊂ SUBSET OF */ - { 0x08db, 0x2283 }, /* includes ⊃ SUPERSET OF */ - { 0x08dc, 0x2229 }, /* intersection ∩ INTERSECTION */ - { 0x08dd, 0x222a }, /* union ∪ UNION */ - { 0x08de, 0x2227 }, /* logicaland ∧ LOGICAL AND */ - { 0x08df, 0x2228 }, /* logicalor ∨ LOGICAL OR */ - { 0x08ef, 0x2202 }, /* partialderivative ∂ PARTIAL DIFFERENTIAL */ - { 0x08f6, 0x0192 }, /* function ƒ LATIN SMALL LETTER F WITH HOOK */ - { 0x08fb, 0x2190 }, /* leftarrow ← LEFTWARDS ARROW */ - { 0x08fc, 0x2191 }, /* uparrow ↑ UPWARDS ARROW */ - { 0x08fd, 0x2192 }, /* rightarrow → RIGHTWARDS ARROW */ - { 0x08fe, 0x2193 }, /* downarrow ↓ DOWNWARDS ARROW */ -/* 0x09df blank ? ??? */ - { 0x09e0, 0x25c6 }, /* soliddiamond ◆ BLACK DIAMOND */ - { 0x09e1, 0x2592 }, /* checkerboard ▒ MEDIUM SHADE */ - { 0x09e2, 0x2409 }, /* ht ␉ SYMBOL FOR HORIZONTAL TABULATION */ - { 0x09e3, 0x240c }, /* ff ␌ SYMBOL FOR FORM FEED */ - { 0x09e4, 0x240d }, /* cr ␍ SYMBOL FOR CARRIAGE RETURN */ - { 0x09e5, 0x240a }, /* lf ␊ SYMBOL FOR LINE FEED */ - { 0x09e8, 0x2424 }, /* nl ␤ SYMBOL FOR NEWLINE */ - { 0x09e9, 0x240b }, /* vt ␋ SYMBOL FOR VERTICAL TABULATION */ - { 0x09ea, 0x2518 }, /* lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT */ - { 0x09eb, 0x2510 }, /* uprightcorner ┐ BOX DRAWINGS LIGHT DOWN AND LEFT */ - { 0x09ec, 0x250c }, /* upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */ - { 0x09ed, 0x2514 }, /* lowleftcorner └ BOX DRAWINGS LIGHT UP AND RIGHT */ - { 0x09ee, 0x253c }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */ - { 0x09ef, 0x23ba }, /* horizlinescan1 ⎺ HORIZONTAL SCAN LINE-1 (Unicode 3.2 draft) */ - { 0x09f0, 0x23bb }, /* horizlinescan3 ⎻ HORIZONTAL SCAN LINE-3 (Unicode 3.2 draft) */ - { 0x09f1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */ - { 0x09f2, 0x23bc }, /* horizlinescan7 ⎼ HORIZONTAL SCAN LINE-7 (Unicode 3.2 draft) */ - { 0x09f3, 0x23bd }, /* horizlinescan9 ⎽ HORIZONTAL SCAN LINE-9 (Unicode 3.2 draft) */ - { 0x09f4, 0x251c }, /* leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ - { 0x09f5, 0x2524 }, /* rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */ - { 0x09f6, 0x2534 }, /* bott ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL */ - { 0x09f7, 0x252c }, /* topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */ - { 0x09f8, 0x2502 }, /* vertbar │ BOX DRAWINGS LIGHT VERTICAL */ - { 0x0aa1, 0x2003 }, /* emspace   EM SPACE */ - { 0x0aa2, 0x2002 }, /* enspace   EN SPACE */ - { 0x0aa3, 0x2004 }, /* em3space   THREE-PER-EM SPACE */ - { 0x0aa4, 0x2005 }, /* em4space   FOUR-PER-EM SPACE */ - { 0x0aa5, 0x2007 }, /* digitspace   FIGURE SPACE */ - { 0x0aa6, 0x2008 }, /* punctspace   PUNCTUATION SPACE */ - { 0x0aa7, 0x2009 }, /* thinspace   THIN SPACE */ - { 0x0aa8, 0x200a }, /* hairspace   HAIR SPACE */ - { 0x0aa9, 0x2014 }, /* emdash — EM DASH */ - { 0x0aaa, 0x2013 }, /* endash – EN DASH */ - { 0x0aac, 0x2423 }, /* signifblank ␣ OPEN BOX */ - { 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */ - { 0x0aaf, 0x2025 }, /* doubbaselinedot ‥ TWO DOT LEADER */ - { 0x0ab0, 0x2153 }, /* onethird ⅓ VULGAR FRACTION ONE THIRD */ - { 0x0ab1, 0x2154 }, /* twothirds ⅔ VULGAR FRACTION TWO THIRDS */ - { 0x0ab2, 0x2155 }, /* onefifth ⅕ VULGAR FRACTION ONE FIFTH */ - { 0x0ab3, 0x2156 }, /* twofifths ⅖ VULGAR FRACTION TWO FIFTHS */ - { 0x0ab4, 0x2157 }, /* threefifths ⅗ VULGAR FRACTION THREE FIFTHS */ - { 0x0ab5, 0x2158 }, /* fourfifths ⅘ VULGAR FRACTION FOUR FIFTHS */ - { 0x0ab6, 0x2159 }, /* onesixth ⅙ VULGAR FRACTION ONE SIXTH */ - { 0x0ab7, 0x215a }, /* fivesixths ⅚ VULGAR FRACTION FIVE SIXTHS */ - { 0x0ab8, 0x2105 }, /* careof ℅ CARE OF */ - { 0x0abb, 0x2012 }, /* figdash ‒ FIGURE DASH */ - { 0x0abc, 0x27e8 }, /* leftanglebracket ⟨ MATHEMATICAL LEFT ANGLE BRACKET */ - { 0x0abd, 0x002e }, /* decimalpoint . FULL STOP */ - { 0x0abe, 0x27e9 }, /* rightanglebracket ⟩ MATHEMATICAL RIGHT ANGLE BRACKET */ - /* 0x0abf marker ? ??? */ - { 0x0ac3, 0x215b }, /* oneeighth ⅛ VULGAR FRACTION ONE EIGHTH */ - { 0x0ac4, 0x215c }, /* threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS */ - { 0x0ac5, 0x215d }, /* fiveeighths ⅝ VULGAR FRACTION FIVE EIGHTHS */ - { 0x0ac6, 0x215e }, /* seveneighths ⅞ VULGAR FRACTION SEVEN EIGHTHS */ - { 0x0ac9, 0x2122 }, /* trademark ™ TRADE MARK SIGN */ - { 0x0aca, 0x2613 }, /* signaturemark ☓ SALTIRE */ - /* 0x0acb trademarkincircle ? ??? */ - { 0x0acc, 0x25c1 }, /* leftopentriangle ◁ WHITE LEFT-POINTING TRIANGLE */ - { 0x0acd, 0x25b7 }, /* rightopentriangle ▷ WHITE RIGHT-POINTING TRIANGLE */ - { 0x0ace, 0x25cb }, /* emopencircle ○ WHITE CIRCLE */ - { 0x0acf, 0x25af }, /* emopenrectangle ▯ WHITE VERTICAL RECTANGLE */ - { 0x0ad0, 0x2018 }, /* leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK */ - { 0x0ad1, 0x2019 }, /* rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK */ - { 0x0ad2, 0x201c }, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */ - { 0x0ad3, 0x201d }, /* rightdoublequotemark ” RIGHT DOUBLE QUOTATION MARK */ - { 0x0ad4, 0x211e }, /* prescription ℞ PRESCRIPTION TAKE */ - { 0x0ad5, 0x2030 }, /* permille ‰ PER MILLE SIGN */ - { 0x0ad6, 0x2032 }, /* minutes ′ PRIME */ - { 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */ - { 0x0ad9, 0x271d }, /* latincross ✝ LATIN CROSS */ - /* 0x0ada hexagram ? ??? */ - { 0x0adb, 0x25ac }, /* filledrectbullet ▬ BLACK RECTANGLE */ - { 0x0adc, 0x25c0 }, /* filledlefttribullet ◀ BLACK LEFT-POINTING TRIANGLE */ - { 0x0add, 0x25b6 }, /* filledrighttribullet ▶ BLACK RIGHT-POINTING TRIANGLE */ - { 0x0ade, 0x25cf }, /* emfilledcircle ● BLACK CIRCLE */ - { 0x0adf, 0x25ae }, /* emfilledrect ▮ BLACK VERTICAL RECTANGLE */ - { 0x0ae0, 0x25e6 }, /* enopencircbullet ◦ WHITE BULLET */ - { 0x0ae1, 0x25ab }, /* enopensquarebullet ▫ WHITE SMALL SQUARE */ - { 0x0ae2, 0x25ad }, /* openrectbullet ▭ WHITE RECTANGLE */ - { 0x0ae3, 0x25b3 }, /* opentribulletup △ WHITE UP-POINTING TRIANGLE */ - { 0x0ae4, 0x25bd }, /* opentribulletdown ▽ WHITE DOWN-POINTING TRIANGLE */ - { 0x0ae5, 0x2606 }, /* openstar ☆ WHITE STAR */ - { 0x0ae6, 0x2022 }, /* enfilledcircbullet • BULLET */ - { 0x0ae7, 0x25aa }, /* enfilledsqbullet ▪ BLACK SMALL SQUARE */ - { 0x0ae8, 0x25b2 }, /* filledtribulletup ▲ BLACK UP-POINTING TRIANGLE */ - { 0x0ae9, 0x25bc }, /* filledtribulletdown ▼ BLACK DOWN-POINTING TRIANGLE */ - { 0x0aea, 0x261c }, /* leftpointer ☜ WHITE LEFT POINTING INDEX */ - { 0x0aeb, 0x261e }, /* rightpointer ☞ WHITE RIGHT POINTING INDEX */ - { 0x0aec, 0x2663 }, /* club ♣ BLACK CLUB SUIT */ - { 0x0aed, 0x2666 }, /* diamond ♦ BLACK DIAMOND SUIT */ - { 0x0aee, 0x2665 }, /* heart ♥ BLACK HEART SUIT */ - { 0x0af0, 0x2720 }, /* maltesecross ✠ MALTESE CROSS */ - { 0x0af1, 0x2020 }, /* dagger † DAGGER */ - { 0x0af2, 0x2021 }, /* doubledagger ‡ DOUBLE DAGGER */ - { 0x0af3, 0x2713 }, /* checkmark ✓ CHECK MARK */ - { 0x0af4, 0x2717 }, /* ballotcross ✗ BALLOT X */ - { 0x0af5, 0x266f }, /* musicalsharp ♯ MUSIC SHARP SIGN */ - { 0x0af6, 0x266d }, /* musicalflat ♭ MUSIC FLAT SIGN */ - { 0x0af7, 0x2642 }, /* malesymbol ♂ MALE SIGN */ - { 0x0af8, 0x2640 }, /* femalesymbol ♀ FEMALE SIGN */ - { 0x0af9, 0x260e }, /* telephone ☎ BLACK TELEPHONE */ - { 0x0afa, 0x2315 }, /* telephonerecorder ⌕ TELEPHONE RECORDER */ - { 0x0afb, 0x2117 }, /* phonographcopyright ℗ SOUND RECORDING COPYRIGHT */ - { 0x0afc, 0x2038 }, /* caret ‸ CARET */ - { 0x0afd, 0x201a }, /* singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK */ - { 0x0afe, 0x201e }, /* doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK */ - /* 0x0aff cursor ? ??? */ - { 0x0ba3, 0x003c }, /* leftcaret < LESS-THAN SIGN */ - { 0x0ba6, 0x003e }, /* rightcaret > GREATER-THAN SIGN */ - { 0x0ba8, 0x2228 }, /* downcaret ∨ LOGICAL OR */ - { 0x0ba9, 0x2227 }, /* upcaret ∧ LOGICAL AND */ - { 0x0bc0, 0x00af }, /* overbar ¯ MACRON */ - { 0x0bc2, 0x22a4 }, /* downtack ⊤ DOWN TACK */ - { 0x0bc3, 0x2229 }, /* upshoe ∩ INTERSECTION */ - { 0x0bc4, 0x230a }, /* downstile ⌊ LEFT FLOOR */ - { 0x0bc6, 0x005f }, /* underbar _ LOW LINE */ - { 0x0bca, 0x2218 }, /* jot ∘ RING OPERATOR */ - { 0x0bcc, 0x2395 }, /* quad ⎕ APL FUNCTIONAL SYMBOL QUAD (Unicode 3.0) */ - { 0x0bce, 0x22a5 }, /* uptack ⊥ UP TACK */ - { 0x0bcf, 0x25cb }, /* circle ○ WHITE CIRCLE */ - { 0x0bd3, 0x2308 }, /* upstile ⌈ LEFT CEILING */ - { 0x0bd6, 0x222a }, /* downshoe ∪ UNION */ - { 0x0bd8, 0x2283 }, /* rightshoe ⊃ SUPERSET OF */ - { 0x0bda, 0x2282 }, /* leftshoe ⊂ SUBSET OF */ - { 0x0bdc, 0x22a2 }, /* lefttack ⊢ RIGHT TACK */ - { 0x0bfc, 0x22a3 }, /* righttack ⊣ LEFT TACK */ - { 0x0cdf, 0x2017 }, /* hebrew_doublelowline ‗ DOUBLE LOW LINE */ - { 0x0ce0, 0x05d0 }, /* hebrew_aleph א HEBREW LETTER ALEF */ - { 0x0ce1, 0x05d1 }, /* hebrew_bet ב HEBREW LETTER BET */ - { 0x0ce2, 0x05d2 }, /* hebrew_gimel ג HEBREW LETTER GIMEL */ - { 0x0ce3, 0x05d3 }, /* hebrew_dalet ד HEBREW LETTER DALET */ - { 0x0ce4, 0x05d4 }, /* hebrew_he ה HEBREW LETTER HE */ - { 0x0ce5, 0x05d5 }, /* hebrew_waw ו HEBREW LETTER VAV */ - { 0x0ce6, 0x05d6 }, /* hebrew_zain ז HEBREW LETTER ZAYIN */ - { 0x0ce7, 0x05d7 }, /* hebrew_chet ח HEBREW LETTER HET */ - { 0x0ce8, 0x05d8 }, /* hebrew_tet ט HEBREW LETTER TET */ - { 0x0ce9, 0x05d9 }, /* hebrew_yod י HEBREW LETTER YOD */ - { 0x0cea, 0x05da }, /* hebrew_finalkaph ך HEBREW LETTER FINAL KAF */ - { 0x0ceb, 0x05db }, /* hebrew_kaph כ HEBREW LETTER KAF */ - { 0x0cec, 0x05dc }, /* hebrew_lamed ל HEBREW LETTER LAMED */ - { 0x0ced, 0x05dd }, /* hebrew_finalmem ם HEBREW LETTER FINAL MEM */ - { 0x0cee, 0x05de }, /* hebrew_mem מ HEBREW LETTER MEM */ - { 0x0cef, 0x05df }, /* hebrew_finalnun ן HEBREW LETTER FINAL NUN */ - { 0x0cf0, 0x05e0 }, /* hebrew_nun נ HEBREW LETTER NUN */ - { 0x0cf1, 0x05e1 }, /* hebrew_samech ס HEBREW LETTER SAMEKH */ - { 0x0cf2, 0x05e2 }, /* hebrew_ayin ע HEBREW LETTER AYIN */ - { 0x0cf3, 0x05e3 }, /* hebrew_finalpe ף HEBREW LETTER FINAL PE */ - { 0x0cf4, 0x05e4 }, /* hebrew_pe פ HEBREW LETTER PE */ - { 0x0cf5, 0x05e5 }, /* hebrew_finalzade ץ HEBREW LETTER FINAL TSADI */ - { 0x0cf6, 0x05e6 }, /* hebrew_zade צ HEBREW LETTER TSADI */ - { 0x0cf7, 0x05e7 }, /* hebrew_qoph ק HEBREW LETTER QOF */ - { 0x0cf8, 0x05e8 }, /* hebrew_resh ר HEBREW LETTER RESH */ - { 0x0cf9, 0x05e9 }, /* hebrew_shin ש HEBREW LETTER SHIN */ - { 0x0cfa, 0x05ea }, /* hebrew_taw ת HEBREW LETTER TAV */ - { 0x0da1, 0x0e01 }, /* Thai_kokai ก THAI CHARACTER KO KAI */ - { 0x0da2, 0x0e02 }, /* Thai_khokhai ข THAI CHARACTER KHO KHAI */ - { 0x0da3, 0x0e03 }, /* Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT */ - { 0x0da4, 0x0e04 }, /* Thai_khokhwai ค THAI CHARACTER KHO KHWAI */ - { 0x0da5, 0x0e05 }, /* Thai_khokhon ฅ THAI CHARACTER KHO KHON */ - { 0x0da6, 0x0e06 }, /* Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG */ - { 0x0da7, 0x0e07 }, /* Thai_ngongu ง THAI CHARACTER NGO NGU */ - { 0x0da8, 0x0e08 }, /* Thai_chochan จ THAI CHARACTER CHO CHAN */ - { 0x0da9, 0x0e09 }, /* Thai_choching ฉ THAI CHARACTER CHO CHING */ - { 0x0daa, 0x0e0a }, /* Thai_chochang ช THAI CHARACTER CHO CHANG */ - { 0x0dab, 0x0e0b }, /* Thai_soso ซ THAI CHARACTER SO SO */ - { 0x0dac, 0x0e0c }, /* Thai_chochoe ฌ THAI CHARACTER CHO CHOE */ - { 0x0dad, 0x0e0d }, /* Thai_yoying ญ THAI CHARACTER YO YING */ - { 0x0dae, 0x0e0e }, /* Thai_dochada ฎ THAI CHARACTER DO CHADA */ - { 0x0daf, 0x0e0f }, /* Thai_topatak ฏ THAI CHARACTER TO PATAK */ - { 0x0db0, 0x0e10 }, /* Thai_thothan ฐ THAI CHARACTER THO THAN */ - { 0x0db1, 0x0e11 }, /* Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO */ - { 0x0db2, 0x0e12 }, /* Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO */ - { 0x0db3, 0x0e13 }, /* Thai_nonen ณ THAI CHARACTER NO NEN */ - { 0x0db4, 0x0e14 }, /* Thai_dodek ด THAI CHARACTER DO DEK */ - { 0x0db5, 0x0e15 }, /* Thai_totao ต THAI CHARACTER TO TAO */ - { 0x0db6, 0x0e16 }, /* Thai_thothung ถ THAI CHARACTER THO THUNG */ - { 0x0db7, 0x0e17 }, /* Thai_thothahan ท THAI CHARACTER THO THAHAN */ - { 0x0db8, 0x0e18 }, /* Thai_thothong ธ THAI CHARACTER THO THONG */ - { 0x0db9, 0x0e19 }, /* Thai_nonu น THAI CHARACTER NO NU */ - { 0x0dba, 0x0e1a }, /* Thai_bobaimai บ THAI CHARACTER BO BAIMAI */ - { 0x0dbb, 0x0e1b }, /* Thai_popla ป THAI CHARACTER PO PLA */ - { 0x0dbc, 0x0e1c }, /* Thai_phophung ผ THAI CHARACTER PHO PHUNG */ - { 0x0dbd, 0x0e1d }, /* Thai_fofa ฝ THAI CHARACTER FO FA */ - { 0x0dbe, 0x0e1e }, /* Thai_phophan พ THAI CHARACTER PHO PHAN */ - { 0x0dbf, 0x0e1f }, /* Thai_fofan ฟ THAI CHARACTER FO FAN */ - { 0x0dc0, 0x0e20 }, /* Thai_phosamphao ภ THAI CHARACTER PHO SAMPHAO */ - { 0x0dc1, 0x0e21 }, /* Thai_moma ม THAI CHARACTER MO MA */ - { 0x0dc2, 0x0e22 }, /* Thai_yoyak ย THAI CHARACTER YO YAK */ - { 0x0dc3, 0x0e23 }, /* Thai_rorua ร THAI CHARACTER RO RUA */ - { 0x0dc4, 0x0e24 }, /* Thai_ru ฤ THAI CHARACTER RU */ - { 0x0dc5, 0x0e25 }, /* Thai_loling ล THAI CHARACTER LO LING */ - { 0x0dc6, 0x0e26 }, /* Thai_lu ฦ THAI CHARACTER LU */ - { 0x0dc7, 0x0e27 }, /* Thai_wowaen ว THAI CHARACTER WO WAEN */ - { 0x0dc8, 0x0e28 }, /* Thai_sosala ศ THAI CHARACTER SO SALA */ - { 0x0dc9, 0x0e29 }, /* Thai_sorusi ษ THAI CHARACTER SO RUSI */ - { 0x0dca, 0x0e2a }, /* Thai_sosua ส THAI CHARACTER SO SUA */ - { 0x0dcb, 0x0e2b }, /* Thai_hohip ห THAI CHARACTER HO HIP */ - { 0x0dcc, 0x0e2c }, /* Thai_lochula ฬ THAI CHARACTER LO CHULA */ - { 0x0dcd, 0x0e2d }, /* Thai_oang อ THAI CHARACTER O ANG */ - { 0x0dce, 0x0e2e }, /* Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK */ - { 0x0dcf, 0x0e2f }, /* Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI */ - { 0x0dd0, 0x0e30 }, /* Thai_saraa ะ THAI CHARACTER SARA A */ - { 0x0dd1, 0x0e31 }, /* Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT */ - { 0x0dd2, 0x0e32 }, /* Thai_saraaa า THAI CHARACTER SARA AA */ - { 0x0dd3, 0x0e33 }, /* Thai_saraam ำ THAI CHARACTER SARA AM */ - { 0x0dd4, 0x0e34 }, /* Thai_sarai ิ THAI CHARACTER SARA I */ - { 0x0dd5, 0x0e35 }, /* Thai_saraii ี THAI CHARACTER SARA II */ - { 0x0dd6, 0x0e36 }, /* Thai_saraue ึ THAI CHARACTER SARA UE */ - { 0x0dd7, 0x0e37 }, /* Thai_sarauee ื THAI CHARACTER SARA UEE */ - { 0x0dd8, 0x0e38 }, /* Thai_sarau ุ THAI CHARACTER SARA U */ - { 0x0dd9, 0x0e39 }, /* Thai_sarauu ู THAI CHARACTER SARA UU */ - { 0x0dda, 0x0e3a }, /* Thai_phinthu ฺ THAI CHARACTER PHINTHU */ - { 0x0dde, 0x0e3e }, /* Thai_maihanakat_maitho ฾ ??? */ - { 0x0ddf, 0x0e3f }, /* Thai_baht ฿ THAI CURRENCY SYMBOL BAHT */ - { 0x0de0, 0x0e40 }, /* Thai_sarae เ THAI CHARACTER SARA E */ - { 0x0de1, 0x0e41 }, /* Thai_saraae แ THAI CHARACTER SARA AE */ - { 0x0de2, 0x0e42 }, /* Thai_sarao โ THAI CHARACTER SARA O */ - { 0x0de3, 0x0e43 }, /* Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN */ - { 0x0de4, 0x0e44 }, /* Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI */ - { 0x0de5, 0x0e45 }, /* Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO */ - { 0x0de6, 0x0e46 }, /* Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK */ - { 0x0de7, 0x0e47 }, /* Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU */ - { 0x0de8, 0x0e48 }, /* Thai_maiek ่ THAI CHARACTER MAI EK */ - { 0x0de9, 0x0e49 }, /* Thai_maitho ้ THAI CHARACTER MAI THO */ - { 0x0dea, 0x0e4a }, /* Thai_maitri ๊ THAI CHARACTER MAI TRI */ - { 0x0deb, 0x0e4b }, /* Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA */ - { 0x0dec, 0x0e4c }, /* Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT */ - { 0x0ded, 0x0e4d }, /* Thai_nikhahit ํ THAI CHARACTER NIKHAHIT */ - { 0x0df0, 0x0e50 }, /* Thai_leksun ๐ THAI DIGIT ZERO */ - { 0x0df1, 0x0e51 }, /* Thai_leknung ๑ THAI DIGIT ONE */ - { 0x0df2, 0x0e52 }, /* Thai_leksong ๒ THAI DIGIT TWO */ - { 0x0df3, 0x0e53 }, /* Thai_leksam ๓ THAI DIGIT THREE */ - { 0x0df4, 0x0e54 }, /* Thai_leksi ๔ THAI DIGIT FOUR */ - { 0x0df5, 0x0e55 }, /* Thai_lekha ๕ THAI DIGIT FIVE */ - { 0x0df6, 0x0e56 }, /* Thai_lekhok ๖ THAI DIGIT SIX */ - { 0x0df7, 0x0e57 }, /* Thai_lekchet ๗ THAI DIGIT SEVEN */ - { 0x0df8, 0x0e58 }, /* Thai_lekpaet ๘ THAI DIGIT EIGHT */ - { 0x0df9, 0x0e59 }, /* Thai_lekkao ๙ THAI DIGIT NINE */ - { 0x0ea1, 0x3131 }, /* Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK */ - { 0x0ea2, 0x3132 }, /* Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK */ - { 0x0ea3, 0x3133 }, /* Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS */ - { 0x0ea4, 0x3134 }, /* Hangul_Nieun ㄴ HANGUL LETTER NIEUN */ - { 0x0ea5, 0x3135 }, /* Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC */ - { 0x0ea6, 0x3136 }, /* Hangul_NieunHieuh ㄶ HANGUL LETTER NIEUN-HIEUH */ - { 0x0ea7, 0x3137 }, /* Hangul_Dikeud ㄷ HANGUL LETTER TIKEUT */ - { 0x0ea8, 0x3138 }, /* Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT */ - { 0x0ea9, 0x3139 }, /* Hangul_Rieul ㄹ HANGUL LETTER RIEUL */ - { 0x0eaa, 0x313a }, /* Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK */ - { 0x0eab, 0x313b }, /* Hangul_RieulMieum ㄻ HANGUL LETTER RIEUL-MIEUM */ - { 0x0eac, 0x313c }, /* Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP */ - { 0x0ead, 0x313d }, /* Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS */ - { 0x0eae, 0x313e }, /* Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH */ - { 0x0eaf, 0x313f }, /* Hangul_RieulPhieuf ㄿ HANGUL LETTER RIEUL-PHIEUPH */ - { 0x0eb0, 0x3140 }, /* Hangul_RieulHieuh ㅀ HANGUL LETTER RIEUL-HIEUH */ - { 0x0eb1, 0x3141 }, /* Hangul_Mieum ㅁ HANGUL LETTER MIEUM */ - { 0x0eb2, 0x3142 }, /* Hangul_Pieub ㅂ HANGUL LETTER PIEUP */ - { 0x0eb3, 0x3143 }, /* Hangul_SsangPieub ㅃ HANGUL LETTER SSANGPIEUP */ - { 0x0eb4, 0x3144 }, /* Hangul_PieubSios ㅄ HANGUL LETTER PIEUP-SIOS */ - { 0x0eb5, 0x3145 }, /* Hangul_Sios ㅅ HANGUL LETTER SIOS */ - { 0x0eb6, 0x3146 }, /* Hangul_SsangSios ㅆ HANGUL LETTER SSANGSIOS */ - { 0x0eb7, 0x3147 }, /* Hangul_Ieung ㅇ HANGUL LETTER IEUNG */ - { 0x0eb8, 0x3148 }, /* Hangul_Jieuj ㅈ HANGUL LETTER CIEUC */ - { 0x0eb9, 0x3149 }, /* Hangul_SsangJieuj ㅉ HANGUL LETTER SSANGCIEUC */ - { 0x0eba, 0x314a }, /* Hangul_Cieuc ㅊ HANGUL LETTER CHIEUCH */ - { 0x0ebb, 0x314b }, /* Hangul_Khieuq ㅋ HANGUL LETTER KHIEUKH */ - { 0x0ebc, 0x314c }, /* Hangul_Tieut ㅌ HANGUL LETTER THIEUTH */ - { 0x0ebd, 0x314d }, /* Hangul_Phieuf ㅍ HANGUL LETTER PHIEUPH */ - { 0x0ebe, 0x314e }, /* Hangul_Hieuh ㅎ HANGUL LETTER HIEUH */ - { 0x0ebf, 0x314f }, /* Hangul_A ㅏ HANGUL LETTER A */ - { 0x0ec0, 0x3150 }, /* Hangul_AE ㅐ HANGUL LETTER AE */ - { 0x0ec1, 0x3151 }, /* Hangul_YA ㅑ HANGUL LETTER YA */ - { 0x0ec2, 0x3152 }, /* Hangul_YAE ㅒ HANGUL LETTER YAE */ - { 0x0ec3, 0x3153 }, /* Hangul_EO ㅓ HANGUL LETTER EO */ - { 0x0ec4, 0x3154 }, /* Hangul_E ㅔ HANGUL LETTER E */ - { 0x0ec5, 0x3155 }, /* Hangul_YEO ㅕ HANGUL LETTER YEO */ - { 0x0ec6, 0x3156 }, /* Hangul_YE ㅖ HANGUL LETTER YE */ - { 0x0ec7, 0x3157 }, /* Hangul_O ㅗ HANGUL LETTER O */ - { 0x0ec8, 0x3158 }, /* Hangul_WA ㅘ HANGUL LETTER WA */ - { 0x0ec9, 0x3159 }, /* Hangul_WAE ㅙ HANGUL LETTER WAE */ - { 0x0eca, 0x315a }, /* Hangul_OE ㅚ HANGUL LETTER OE */ - { 0x0ecb, 0x315b }, /* Hangul_YO ㅛ HANGUL LETTER YO */ - { 0x0ecc, 0x315c }, /* Hangul_U ㅜ HANGUL LETTER U */ - { 0x0ecd, 0x315d }, /* Hangul_WEO ㅝ HANGUL LETTER WEO */ - { 0x0ece, 0x315e }, /* Hangul_WE ㅞ HANGUL LETTER WE */ - { 0x0ecf, 0x315f }, /* Hangul_WI ㅟ HANGUL LETTER WI */ - { 0x0ed0, 0x3160 }, /* Hangul_YU ㅠ HANGUL LETTER YU */ - { 0x0ed1, 0x3161 }, /* Hangul_EU ㅡ HANGUL LETTER EU */ - { 0x0ed2, 0x3162 }, /* Hangul_YI ㅢ HANGUL LETTER YI */ - { 0x0ed3, 0x3163 }, /* Hangul_I ㅣ HANGUL LETTER I */ - { 0x0ed4, 0x11a8 }, /* Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK */ - { 0x0ed5, 0x11a9 }, /* Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK */ - { 0x0ed6, 0x11aa }, /* Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS */ - { 0x0ed7, 0x11ab }, /* Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN */ - { 0x0ed8, 0x11ac }, /* Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC */ - { 0x0ed9, 0x11ad }, /* Hangul_J_NieunHieuh ᆭ HANGUL JONGSEONG NIEUN-HIEUH */ - { 0x0eda, 0x11ae }, /* Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT */ - { 0x0edb, 0x11af }, /* Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL */ - { 0x0edc, 0x11b0 }, /* Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK */ - { 0x0edd, 0x11b1 }, /* Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM */ - { 0x0ede, 0x11b2 }, /* Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP */ - { 0x0edf, 0x11b3 }, /* Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS */ - { 0x0ee0, 0x11b4 }, /* Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH */ - { 0x0ee1, 0x11b5 }, /* Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH */ - { 0x0ee2, 0x11b6 }, /* Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH */ - { 0x0ee3, 0x11b7 }, /* Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM */ - { 0x0ee4, 0x11b8 }, /* Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP */ - { 0x0ee5, 0x11b9 }, /* Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS */ - { 0x0ee6, 0x11ba }, /* Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS */ - { 0x0ee7, 0x11bb }, /* Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS */ - { 0x0ee8, 0x11bc }, /* Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG */ - { 0x0ee9, 0x11bd }, /* Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC */ - { 0x0eea, 0x11be }, /* Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH */ - { 0x0eeb, 0x11bf }, /* Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH */ - { 0x0eec, 0x11c0 }, /* Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH */ - { 0x0eed, 0x11c1 }, /* Hangul_J_Phieuf ᇁ HANGUL JONGSEONG PHIEUPH */ - { 0x0eee, 0x11c2 }, /* Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */ - { 0x0eef, 0x316d }, /* Hangul_RieulYeorinHieuh ㅭ HANGUL LETTER RIEUL-YEORINHIEUH */ - { 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ㅱ HANGUL LETTER KAPYEOUNMIEUM */ - { 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ㅸ HANGUL LETTER KAPYEOUNPIEUP */ - { 0x0ef2, 0x317f }, /* Hangul_PanSios ㅿ HANGUL LETTER PANSIOS */ -/* 0x0ef3 Hangul_KkogjiDalrinIeung ? ??? */ - { 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */ - { 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */ - { 0x0ef6, 0x318d }, /* Hangul_AraeA ㆍ HANGUL LETTER ARAEA */ - { 0x0ef7, 0x318e }, /* Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */ - { 0x0ef8, 0x11eb }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */ - { 0x0ef9, 0x11f0 }, /* Hangul_J_KkogjiDalrinIeung ᇰ HANGUL JONGSEONG YESIEUNG */ - { 0x0efa, 0x11f9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */ - { 0x0eff, 0x20a9 }, /* Korean_Won ₩ WON SIGN */ - { 0x13a4, 0x20ac }, /* Euro € EURO SIGN */ - { 0x13bc, 0x0152 }, /* OE Œ LATIN CAPITAL LIGATURE OE */ - { 0x13bd, 0x0153 }, /* oe œ LATIN SMALL LIGATURE OE */ - { 0x13be, 0x0178 }, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */ - { 0x20a0, 0x20a0 }, /* EcuSign ₠ EURO-CURRENCY SIGN */ - { 0x20a1, 0x20a1 }, /* ColonSign ₡ COLON SIGN */ - { 0x20a2, 0x20a2 }, /* CruzeiroSign ₢ CRUZEIRO SIGN */ - { 0x20a3, 0x20a3 }, /* FFrancSign ₣ FRENCH FRANC SIGN */ - { 0x20a4, 0x20a4 }, /* LiraSign ₤ LIRA SIGN */ - { 0x20a5, 0x20a5 }, /* MillSign ₥ MILL SIGN */ - { 0x20a6, 0x20a6 }, /* NairaSign ₦ NAIRA SIGN */ - { 0x20a7, 0x20a7 }, /* PesetaSign ₧ PESETA SIGN */ - { 0x20a8, 0x20a8 }, /* RupeeSign ₨ RUPEE SIGN */ - { 0x20a9, 0x20a9 }, /* WonSign ₩ WON SIGN */ - { 0x20aa, 0x20aa }, /* NewSheqelSign ₪ NEW SHEQEL SIGN */ - { 0x20ab, 0x20ab }, /* DongSign ₫ DONG SIGN */ - { 0x20ac, 0x20ac }, /* EuroSign € EURO SIGN */ -}; - -/* binary search with range check */ -static uint32_t -bin_search(const struct codepair *table, size_t length, xkb_keysym_t keysym) -{ - size_t first = 0; - size_t last = length; - - if (keysym < table[0].keysym || keysym > table[length].keysym) - return 0; - - /* binary search in table */ - while (last >= first) { - size_t mid = (first + last) / 2; - if (table[mid].keysym < keysym) - first = mid + 1; - else if (table[mid].keysym > keysym) - last = mid - 1; - else /* found it */ - return table[mid].ucs; - } - - /* no matching Unicode value found in table */ - return 0; -} - -XKB_EXPORT uint32_t -xkb_keysym_to_utf32(xkb_keysym_t keysym) -{ - /* first check for Latin-1 characters (1:1 mapping) */ - if ((keysym >= 0x0020 && keysym <= 0x007e) || - (keysym >= 0x00a0 && keysym <= 0x00ff)) - return keysym; - - /* patch encoding botch */ - if (keysym == XKB_KEY_KP_Space) - return XKB_KEY_space & 0x7f; - - /* special keysyms */ - if ((keysym >= XKB_KEY_BackSpace && keysym <= XKB_KEY_Clear) || - (keysym >= XKB_KEY_KP_Multiply && keysym <= XKB_KEY_KP_9) || - keysym == XKB_KEY_Return || keysym == XKB_KEY_Escape || - keysym == XKB_KEY_Delete || keysym == XKB_KEY_KP_Tab || - keysym == XKB_KEY_KP_Enter || keysym == XKB_KEY_KP_Equal) - return keysym & 0x7f; - - /* also check for directly encoded Unicode codepoints */ - /* - * In theory, this is supposed to start from 0x100100, such that the ASCII - * range, which is already covered by 0x00-0xff, can't be encoded in two - * ways. However, changing this after a couple of decades probably won't - * go well, so it stays as it is. - */ - if (0x01000000 <= keysym && keysym <= 0x0110ffff) - return keysym - 0x01000000; - - /* search main table */ - return bin_search(keysymtab, ARRAY_SIZE(keysymtab) - 1, keysym); -} - -/* - * Copyright © 2012 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Rob Bradford - */ - -XKB_EXPORT int -xkb_keysym_to_utf8(xkb_keysym_t keysym, char *buffer, size_t size) -{ - uint32_t codepoint; - - if (size < 7) - return -1; - - codepoint = xkb_keysym_to_utf32(keysym); - - if (codepoint == 0) - return 0; - - return utf32_to_utf8(codepoint, buffer); -} diff --git a/src/3rdparty/xkbcommon/src/keysym.c b/src/3rdparty/xkbcommon/src/keysym.c deleted file mode 100644 index 6d06de0bf0..0000000000 --- a/src/3rdparty/xkbcommon/src/keysym.c +++ /dev/null @@ -1,762 +0,0 @@ -/* - * Copyright 1985, 1987, 1990, 1998 The Open Group - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the names of the authors or their - * institutions shall not be used in advertising or otherwise to promote the - * sale, use or other dealings in this Software without prior written - * authorization from the authors. - */ - -/* - * Copyright © 2009 Dan Nicholson - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include -#include "xkbcommon/xkbcommon.h" -#include "utils.h" -#include "keysym.h" -#include "ks_tables.h" - -static inline const char * -get_name(const struct name_keysym *entry) -{ - return keysym_names + entry->offset; -} - -static int -compare_by_keysym(const void *a, const void *b) -{ - const xkb_keysym_t *key = a; - const struct name_keysym *entry = b; - if (*key < entry->keysym) - return -1; - if (*key > entry->keysym) - return 1; - return 0; -} - -static int -compare_by_name(const void *a, const void *b) -{ - const char *key = a; - const struct name_keysym *entry = b; - return istrcmp(key, get_name(entry)); -} - -XKB_EXPORT int -xkb_keysym_get_name(xkb_keysym_t ks, char *buffer, size_t size) -{ - const struct name_keysym *entry; - - if ((ks & ((unsigned long) ~0x1fffffff)) != 0) { - snprintf(buffer, size, "Invalid"); - return -1; - } - - entry = bsearch(&ks, keysym_to_name, - ARRAY_SIZE(keysym_to_name), - sizeof(*keysym_to_name), - compare_by_keysym); - if (entry) - return snprintf(buffer, size, "%s", get_name(entry)); - - /* Unnamed Unicode codepoint. */ - if (ks >= 0x01000100 && ks <= 0x0110ffff) { - const int width = (ks & 0xff0000UL) ? 8 : 4; - return snprintf(buffer, size, "U%0*lX", width, ks & 0xffffffUL); - } - - /* Unnamed, non-Unicode, symbol (shouldn't generally happen). */ - return snprintf(buffer, size, "0x%08x", ks); -} - -/* - * Find the correct keysym if one case-insensitive match is given. - * - * The name_to_keysym table is sorted by istrcmp(). So bsearch() may return - * _any_ of all possible case-insensitive duplicates. This function searches the - * returned entry @entry, all previous and all next entries that match by - * case-insensitive comparison and returns the exact match to @name. If @icase - * is true, then this returns the best case-insensitive match instead of a - * correct match. - * The "best" case-insensitive match is the lower-case keysym which we find with - * the help of xkb_keysym_is_lower(). - * The only keysyms that only differ by letter-case are keysyms that are - * available as lower-case and upper-case variant (like KEY_a and KEY_A). So - * returning the first lower-case match is enough in this case. - */ -static const struct name_keysym * -find_sym(const struct name_keysym *entry, const char *name, bool icase) -{ - const struct name_keysym *iter, *last; - size_t len = ARRAY_SIZE(name_to_keysym); - - if (!entry) - return NULL; - - if (!icase && strcmp(get_name(entry), name) == 0) - return entry; - if (icase && xkb_keysym_is_lower(entry->keysym)) - return entry; - - for (iter = entry - 1; iter >= name_to_keysym; --iter) { - if (!icase && strcmp(get_name(iter), name) == 0) - return iter; - if (istrcmp(get_name(iter), get_name(entry)) != 0) - break; - if (icase && xkb_keysym_is_lower(iter->keysym)) - return iter; - } - - last = name_to_keysym + len; - for (iter = entry + 1; iter < last; ++iter) { - if (!icase && strcmp(get_name(iter), name) == 0) - return iter; - if (istrcmp(get_name(iter), get_name(entry)) != 0) - break; - if (icase && xkb_keysym_is_lower(iter->keysym)) - return iter; - } - - if (icase) - return entry; - return NULL; -} - -XKB_EXPORT xkb_keysym_t -xkb_keysym_from_name(const char *s, enum xkb_keysym_flags flags) -{ - const struct name_keysym *entry; - char *tmp; - xkb_keysym_t val; - bool icase = (flags & XKB_KEYSYM_CASE_INSENSITIVE); - - if (flags & ~XKB_KEYSYM_CASE_INSENSITIVE) - return XKB_KEY_NoSymbol; - - entry = bsearch(s, name_to_keysym, - ARRAY_SIZE(name_to_keysym), - sizeof(*name_to_keysym), - compare_by_name); - entry = find_sym(entry, s, icase); - if (entry) - return entry->keysym; - - if (*s == 'U' || (icase && *s == 'u')) { - val = strtoul(&s[1], &tmp, 16); - if (tmp && *tmp != '\0') - return XKB_KEY_NoSymbol; - - if (val < 0x20 || (val > 0x7e && val < 0xa0)) - return XKB_KEY_NoSymbol; - if (val < 0x100) - return val; - if (val > 0x10ffff) - return XKB_KEY_NoSymbol; - return val | 0x01000000; - } - else if (s[0] == '0' && (s[1] == 'x' || (icase && s[1] == 'X'))) { - val = strtoul(&s[2], &tmp, 16); - if (tmp && *tmp != '\0') - return XKB_KEY_NoSymbol; - - return val; - } - - /* Stupid inconsistency between the headers and XKeysymDB: the former has - * no separating underscore, while some XF86* syms in the latter did. - * As a last ditch effort, try without. */ - if (strncmp(s, "XF86_", 5) == 0 || - (icase && strncasecmp(s, "XF86_", 5) == 0)) { - xkb_keysym_t ret; - tmp = strdup(s); - if (!tmp) - return XKB_KEY_NoSymbol; - memmove(&tmp[4], &tmp[5], strlen(s) - 5 + 1); - ret = xkb_keysym_from_name(tmp, flags); - free(tmp); - return ret; - } - - return XKB_KEY_NoSymbol; -} - -bool -xkb_keysym_is_keypad(xkb_keysym_t keysym) -{ - return keysym >= XKB_KEY_KP_Space && keysym <= XKB_KEY_KP_Equal; -} - - -bool -xkb_keysym_is_modifier(xkb_keysym_t keysym) -{ - return - (keysym >= XKB_KEY_Shift_L && keysym <= XKB_KEY_Hyper_R) || - /* libX11 only goes upto XKB_KEY_ISO_Level5_Lock. */ - (keysym >= XKB_KEY_ISO_Lock && keysym <= XKB_KEY_ISO_Last_Group_Lock) || - keysym == XKB_KEY_Mode_switch || - keysym == XKB_KEY_Num_Lock; -} - -static void -XConvertCase(xkb_keysym_t sym, xkb_keysym_t *lower, xkb_keysym_t *upper); - -bool -xkb_keysym_is_lower(xkb_keysym_t ks) -{ - xkb_keysym_t lower, upper; - - XConvertCase(ks, &lower, &upper); - - if (lower == upper) - return false; - - return (ks == lower ? true : false); -} - -bool -xkb_keysym_is_upper(xkb_keysym_t ks) -{ - xkb_keysym_t lower, upper; - - XConvertCase(ks, &lower, &upper); - - if (lower == upper) - return false; - - return (ks == upper ? true : false); -} - -XKB_EXPORT xkb_keysym_t -xkb_keysym_to_lower(xkb_keysym_t ks) -{ - xkb_keysym_t lower, upper; - - XConvertCase(ks, &lower, &upper); - - return lower; -} - -XKB_EXPORT xkb_keysym_t -xkb_keysym_to_upper(xkb_keysym_t ks) -{ - xkb_keysym_t lower, upper; - - XConvertCase(ks, &lower, &upper); - - return upper; -} - -/* - * The following is copied verbatim from libX11:src/KeyBind.c, commit - * d45b3fc19fbe95c41afc4e51d768df6d42332010, with the following changes: - * - unsigned -> uint32_t - * - unsigend short -> uint16_t - * - s/XK_/XKB_KEY_ - * - * XXX: If newlocale() and iswlower_l()/iswupper_l() interface ever - * become portable, we should use that in conjunction with - * xkb_keysym_to_utf32(), instead of all this stuff. We should - * be sure to give the same results as libX11, though, and be - * locale independent; this information is used by xkbcomp to - * find the automatic type to assign to key groups. - */ - -static void -UCSConvertCase(uint32_t code, xkb_keysym_t *lower, xkb_keysym_t *upper) -{ - /* Case conversion for UCS, as in Unicode Data version 4.0.0 */ - /* NB: Only converts simple one-to-one mappings. */ - - /* Tables are used where they take less space than */ - /* the code to work out the mappings. Zero values mean */ - /* undefined code points. */ - - static uint16_t const IPAExt_upper_mapping[] = { /* part only */ - 0x0181, 0x0186, 0x0255, 0x0189, 0x018A, - 0x0258, 0x018F, 0x025A, 0x0190, 0x025C, 0x025D, 0x025E, 0x025F, - 0x0193, 0x0261, 0x0262, 0x0194, 0x0264, 0x0265, 0x0266, 0x0267, - 0x0197, 0x0196, 0x026A, 0x026B, 0x026C, 0x026D, 0x026E, 0x019C, - 0x0270, 0x0271, 0x019D, 0x0273, 0x0274, 0x019F, 0x0276, 0x0277, - 0x0278, 0x0279, 0x027A, 0x027B, 0x027C, 0x027D, 0x027E, 0x027F, - 0x01A6, 0x0281, 0x0282, 0x01A9, 0x0284, 0x0285, 0x0286, 0x0287, - 0x01AE, 0x0289, 0x01B1, 0x01B2, 0x028C, 0x028D, 0x028E, 0x028F, - 0x0290, 0x0291, 0x01B7 - }; - - static uint16_t const LatinExtB_upper_mapping[] = { /* first part only */ - 0x0180, 0x0181, 0x0182, 0x0182, 0x0184, 0x0184, 0x0186, 0x0187, - 0x0187, 0x0189, 0x018A, 0x018B, 0x018B, 0x018D, 0x018E, 0x018F, - 0x0190, 0x0191, 0x0191, 0x0193, 0x0194, 0x01F6, 0x0196, 0x0197, - 0x0198, 0x0198, 0x019A, 0x019B, 0x019C, 0x019D, 0x0220, 0x019F, - 0x01A0, 0x01A0, 0x01A2, 0x01A2, 0x01A4, 0x01A4, 0x01A6, 0x01A7, - 0x01A7, 0x01A9, 0x01AA, 0x01AB, 0x01AC, 0x01AC, 0x01AE, 0x01AF, - 0x01AF, 0x01B1, 0x01B2, 0x01B3, 0x01B3, 0x01B5, 0x01B5, 0x01B7, - 0x01B8, 0x01B8, 0x01BA, 0x01BB, 0x01BC, 0x01BC, 0x01BE, 0x01F7, - 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C4, 0x01C4, 0x01C4, 0x01C7, - 0x01C7, 0x01C7, 0x01CA, 0x01CA, 0x01CA - }; - - static uint16_t const LatinExtB_lower_mapping[] = { /* first part only */ - 0x0180, 0x0253, 0x0183, 0x0183, 0x0185, 0x0185, 0x0254, 0x0188, - 0x0188, 0x0256, 0x0257, 0x018C, 0x018C, 0x018D, 0x01DD, 0x0259, - 0x025B, 0x0192, 0x0192, 0x0260, 0x0263, 0x0195, 0x0269, 0x0268, - 0x0199, 0x0199, 0x019A, 0x019B, 0x026F, 0x0272, 0x019E, 0x0275, - 0x01A1, 0x01A1, 0x01A3, 0x01A3, 0x01A5, 0x01A5, 0x0280, 0x01A8, - 0x01A8, 0x0283, 0x01AA, 0x01AB, 0x01AD, 0x01AD, 0x0288, 0x01B0, - 0x01B0, 0x028A, 0x028B, 0x01B4, 0x01B4, 0x01B6, 0x01B6, 0x0292, - 0x01B9, 0x01B9, 0x01BA, 0x01BB, 0x01BD, 0x01BD, 0x01BE, 0x01BF, - 0x01C0, 0x01C1, 0x01C2, 0x01C3, 0x01C6, 0x01C6, 0x01C6, 0x01C9, - 0x01C9, 0x01C9, 0x01CC, 0x01CC, 0x01CC - }; - - static uint16_t const Greek_upper_mapping[] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0374, 0x0375, 0x0000, 0x0000, - 0x0000, 0x0000, 0x037A, 0x0000, 0x0000, 0x0000, 0x037E, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0384, 0x0385, 0x0386, 0x0387, - 0x0388, 0x0389, 0x038A, 0x0000, 0x038C, 0x0000, 0x038E, 0x038F, - 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, - 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, - 0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, - 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x0386, 0x0388, 0x0389, 0x038A, - 0x03B0, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, - 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, - 0x03A0, 0x03A1, 0x03A3, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, - 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x038C, 0x038E, 0x038F, 0x0000, - 0x0392, 0x0398, 0x03D2, 0x03D3, 0x03D4, 0x03A6, 0x03A0, 0x03D7, - 0x03D8, 0x03D8, 0x03DA, 0x03DA, 0x03DC, 0x03DC, 0x03DE, 0x03DE, - 0x03E0, 0x03E0, 0x03E2, 0x03E2, 0x03E4, 0x03E4, 0x03E6, 0x03E6, - 0x03E8, 0x03E8, 0x03EA, 0x03EA, 0x03EC, 0x03EC, 0x03EE, 0x03EE, - 0x039A, 0x03A1, 0x03F9, 0x03F3, 0x03F4, 0x0395, 0x03F6, 0x03F7, - 0x03F7, 0x03F9, 0x03FA, 0x03FA, 0x0000, 0x0000, 0x0000, 0x0000 - }; - - static uint16_t const Greek_lower_mapping[] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0374, 0x0375, 0x0000, 0x0000, - 0x0000, 0x0000, 0x037A, 0x0000, 0x0000, 0x0000, 0x037E, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0384, 0x0385, 0x03AC, 0x0387, - 0x03AD, 0x03AE, 0x03AF, 0x0000, 0x03CC, 0x0000, 0x03CD, 0x03CE, - 0x0390, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, - 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, - 0x03C0, 0x03C1, 0x0000, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, - 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03AC, 0x03AD, 0x03AE, 0x03AF, - 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, - 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, - 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, - 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000, - 0x03D0, 0x03D1, 0x03D2, 0x03D3, 0x03D4, 0x03D5, 0x03D6, 0x03D7, - 0x03D9, 0x03D9, 0x03DB, 0x03DB, 0x03DD, 0x03DD, 0x03DF, 0x03DF, - 0x03E1, 0x03E1, 0x03E3, 0x03E3, 0x03E5, 0x03E5, 0x03E7, 0x03E7, - 0x03E9, 0x03E9, 0x03EB, 0x03EB, 0x03ED, 0x03ED, 0x03EF, 0x03EF, - 0x03F0, 0x03F1, 0x03F2, 0x03F3, 0x03B8, 0x03F5, 0x03F6, 0x03F8, - 0x03F8, 0x03F2, 0x03FB, 0x03FB, 0x0000, 0x0000, 0x0000, 0x0000 - }; - - static uint16_t const GreekExt_lower_mapping[] = { - 0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07, - 0x1F00, 0x1F01, 0x1F02, 0x1F03, 0x1F04, 0x1F05, 0x1F06, 0x1F07, - 0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x0000, 0x0000, - 0x1F10, 0x1F11, 0x1F12, 0x1F13, 0x1F14, 0x1F15, 0x0000, 0x0000, - 0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27, - 0x1F20, 0x1F21, 0x1F22, 0x1F23, 0x1F24, 0x1F25, 0x1F26, 0x1F27, - 0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37, - 0x1F30, 0x1F31, 0x1F32, 0x1F33, 0x1F34, 0x1F35, 0x1F36, 0x1F37, - 0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x0000, 0x0000, - 0x1F40, 0x1F41, 0x1F42, 0x1F43, 0x1F44, 0x1F45, 0x0000, 0x0000, - 0x1F50, 0x1F51, 0x1F52, 0x1F53, 0x1F54, 0x1F55, 0x1F56, 0x1F57, - 0x0000, 0x1F51, 0x0000, 0x1F53, 0x0000, 0x1F55, 0x0000, 0x1F57, - 0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67, - 0x1F60, 0x1F61, 0x1F62, 0x1F63, 0x1F64, 0x1F65, 0x1F66, 0x1F67, - 0x1F70, 0x1F71, 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1F76, 0x1F77, - 0x1F78, 0x1F79, 0x1F7A, 0x1F7B, 0x1F7C, 0x1F7D, 0x0000, 0x0000, - 0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87, - 0x1F80, 0x1F81, 0x1F82, 0x1F83, 0x1F84, 0x1F85, 0x1F86, 0x1F87, - 0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97, - 0x1F90, 0x1F91, 0x1F92, 0x1F93, 0x1F94, 0x1F95, 0x1F96, 0x1F97, - 0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7, - 0x1FA0, 0x1FA1, 0x1FA2, 0x1FA3, 0x1FA4, 0x1FA5, 0x1FA6, 0x1FA7, - 0x1FB0, 0x1FB1, 0x1FB2, 0x1FB3, 0x1FB4, 0x0000, 0x1FB6, 0x1FB7, - 0x1FB0, 0x1FB1, 0x1F70, 0x1F71, 0x1FB3, 0x1FBD, 0x1FBE, 0x1FBF, - 0x1FC0, 0x1FC1, 0x1FC2, 0x1FC3, 0x1FC4, 0x0000, 0x1FC6, 0x1FC7, - 0x1F72, 0x1F73, 0x1F74, 0x1F75, 0x1FC3, 0x1FCD, 0x1FCE, 0x1FCF, - 0x1FD0, 0x1FD1, 0x1FD2, 0x1FD3, 0x0000, 0x0000, 0x1FD6, 0x1FD7, - 0x1FD0, 0x1FD1, 0x1F76, 0x1F77, 0x0000, 0x1FDD, 0x1FDE, 0x1FDF, - 0x1FE0, 0x1FE1, 0x1FE2, 0x1FE3, 0x1FE4, 0x1FE5, 0x1FE6, 0x1FE7, - 0x1FE0, 0x1FE1, 0x1F7A, 0x1F7B, 0x1FE5, 0x1FED, 0x1FEE, 0x1FEF, - 0x0000, 0x0000, 0x1FF2, 0x1FF3, 0x1FF4, 0x0000, 0x1FF6, 0x1FF7, - 0x1F78, 0x1F79, 0x1F7C, 0x1F7D, 0x1FF3, 0x1FFD, 0x1FFE, 0x0000 - }; - - static uint16_t const GreekExt_upper_mapping[] = { - 0x1F08, 0x1F09, 0x1F0A, 0x1F0B, 0x1F0C, 0x1F0D, 0x1F0E, 0x1F0F, - 0x1F08, 0x1F09, 0x1F0A, 0x1F0B, 0x1F0C, 0x1F0D, 0x1F0E, 0x1F0F, - 0x1F18, 0x1F19, 0x1F1A, 0x1F1B, 0x1F1C, 0x1F1D, 0x0000, 0x0000, - 0x1F18, 0x1F19, 0x1F1A, 0x1F1B, 0x1F1C, 0x1F1D, 0x0000, 0x0000, - 0x1F28, 0x1F29, 0x1F2A, 0x1F2B, 0x1F2C, 0x1F2D, 0x1F2E, 0x1F2F, - 0x1F28, 0x1F29, 0x1F2A, 0x1F2B, 0x1F2C, 0x1F2D, 0x1F2E, 0x1F2F, - 0x1F38, 0x1F39, 0x1F3A, 0x1F3B, 0x1F3C, 0x1F3D, 0x1F3E, 0x1F3F, - 0x1F38, 0x1F39, 0x1F3A, 0x1F3B, 0x1F3C, 0x1F3D, 0x1F3E, 0x1F3F, - 0x1F48, 0x1F49, 0x1F4A, 0x1F4B, 0x1F4C, 0x1F4D, 0x0000, 0x0000, - 0x1F48, 0x1F49, 0x1F4A, 0x1F4B, 0x1F4C, 0x1F4D, 0x0000, 0x0000, - 0x1F50, 0x1F59, 0x1F52, 0x1F5B, 0x1F54, 0x1F5D, 0x1F56, 0x1F5F, - 0x0000, 0x1F59, 0x0000, 0x1F5B, 0x0000, 0x1F5D, 0x0000, 0x1F5F, - 0x1F68, 0x1F69, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F6E, 0x1F6F, - 0x1F68, 0x1F69, 0x1F6A, 0x1F6B, 0x1F6C, 0x1F6D, 0x1F6E, 0x1F6F, - 0x1FBA, 0x1FBB, 0x1FC8, 0x1FC9, 0x1FCA, 0x1FCB, 0x1FDA, 0x1FDB, - 0x1FF8, 0x1FF9, 0x1FEA, 0x1FEB, 0x1FFA, 0x1FFB, 0x0000, 0x0000, - 0x1F88, 0x1F89, 0x1F8A, 0x1F8B, 0x1F8C, 0x1F8D, 0x1F8E, 0x1F8F, - 0x1F88, 0x1F89, 0x1F8A, 0x1F8B, 0x1F8C, 0x1F8D, 0x1F8E, 0x1F8F, - 0x1F98, 0x1F99, 0x1F9A, 0x1F9B, 0x1F9C, 0x1F9D, 0x1F9E, 0x1F9F, - 0x1F98, 0x1F99, 0x1F9A, 0x1F9B, 0x1F9C, 0x1F9D, 0x1F9E, 0x1F9F, - 0x1FA8, 0x1FA9, 0x1FAA, 0x1FAB, 0x1FAC, 0x1FAD, 0x1FAE, 0x1FAF, - 0x1FA8, 0x1FA9, 0x1FAA, 0x1FAB, 0x1FAC, 0x1FAD, 0x1FAE, 0x1FAF, - 0x1FB8, 0x1FB9, 0x1FB2, 0x1FBC, 0x1FB4, 0x0000, 0x1FB6, 0x1FB7, - 0x1FB8, 0x1FB9, 0x1FBA, 0x1FBB, 0x1FBC, 0x1FBD, 0x0399, 0x1FBF, - 0x1FC0, 0x1FC1, 0x1FC2, 0x1FCC, 0x1FC4, 0x0000, 0x1FC6, 0x1FC7, - 0x1FC8, 0x1FC9, 0x1FCA, 0x1FCB, 0x1FCC, 0x1FCD, 0x1FCE, 0x1FCF, - 0x1FD8, 0x1FD9, 0x1FD2, 0x1FD3, 0x0000, 0x0000, 0x1FD6, 0x1FD7, - 0x1FD8, 0x1FD9, 0x1FDA, 0x1FDB, 0x0000, 0x1FDD, 0x1FDE, 0x1FDF, - 0x1FE8, 0x1FE9, 0x1FE2, 0x1FE3, 0x1FE4, 0x1FEC, 0x1FE6, 0x1FE7, - 0x1FE8, 0x1FE9, 0x1FEA, 0x1FEB, 0x1FEC, 0x1FED, 0x1FEE, 0x1FEF, - 0x0000, 0x0000, 0x1FF2, 0x1FFC, 0x1FF4, 0x0000, 0x1FF6, 0x1FF7, - 0x1FF8, 0x1FF9, 0x1FFA, 0x1FFB, 0x1FFC, 0x1FFD, 0x1FFE, 0x0000 - }; - - *lower = code; - *upper = code; - - /* Basic Latin and Latin-1 Supplement, U+0000 to U+00FF */ - if (code <= 0x00ff) { - if (code >= 0x0041 && code <= 0x005a) /* A-Z */ - *lower += 0x20; - else if (code >= 0x0061 && code <= 0x007a) /* a-z */ - *upper -= 0x20; - else if ( (code >= 0x00c0 && code <= 0x00d6) || - (code >= 0x00d8 && code <= 0x00de) ) - *lower += 0x20; - else if ( (code >= 0x00e0 && code <= 0x00f6) || - (code >= 0x00f8 && code <= 0x00fe) ) - *upper -= 0x20; - else if (code == 0x00ff) /* y with diaeresis */ - *upper = 0x0178; - else if (code == 0x00b5) /* micro sign */ - *upper = 0x039c; - return; - } - - /* Latin Extended-A, U+0100 to U+017F */ - if (code >= 0x0100 && code <= 0x017f) { - if ( (code >= 0x0100 && code <= 0x012f) || - (code >= 0x0132 && code <= 0x0137) || - (code >= 0x014a && code <= 0x0177) ) { - *upper = code & ~1; - *lower = code | 1; - } - else if ( (code >= 0x0139 && code <= 0x0148) || - (code >= 0x0179 && code <= 0x017e) ) { - if (code & 1) - *lower += 1; - else - *upper -= 1; - } - else if (code == 0x0130) - *lower = 0x0069; - else if (code == 0x0131) - *upper = 0x0049; - else if (code == 0x0178) - *lower = 0x00ff; - else if (code == 0x017f) - *upper = 0x0053; - return; - } - - /* Latin Extended-B, U+0180 to U+024F */ - if (code >= 0x0180 && code <= 0x024f) { - if (code >= 0x01cd && code <= 0x01dc) { - if (code & 1) - *lower += 1; - else - *upper -= 1; - } - else if ( (code >= 0x01de && code <= 0x01ef) || - (code >= 0x01f4 && code <= 0x01f5) || - (code >= 0x01f8 && code <= 0x021f) || - (code >= 0x0222 && code <= 0x0233) ) { - *lower |= 1; - *upper &= ~1; - } - else if (code >= 0x0180 && code <= 0x01cc) { - *lower = LatinExtB_lower_mapping[code - 0x0180]; - *upper = LatinExtB_upper_mapping[code - 0x0180]; - } - else if (code == 0x01dd) - *upper = 0x018e; - else if (code == 0x01f1 || code == 0x01f2) { - *lower = 0x01f3; - *upper = 0x01f1; - } - else if (code == 0x01f3) - *upper = 0x01f1; - else if (code == 0x01f6) - *lower = 0x0195; - else if (code == 0x01f7) - *lower = 0x01bf; - else if (code == 0x0220) - *lower = 0x019e; - return; - } - - /* IPA Extensions, U+0250 to U+02AF */ - if (code >= 0x0253 && code <= 0x0292) { - *upper = IPAExt_upper_mapping[code - 0x0253]; - } - - /* Combining Diacritical Marks, U+0300 to U+036F */ - if (code == 0x0345) { - *upper = 0x0399; - } - - /* Greek and Coptic, U+0370 to U+03FF */ - if (code >= 0x0370 && code <= 0x03ff) { - *lower = Greek_lower_mapping[code - 0x0370]; - *upper = Greek_upper_mapping[code - 0x0370]; - if (*upper == 0) - *upper = code; - if (*lower == 0) - *lower = code; - } - - /* Cyrillic and Cyrillic Supplementary, U+0400 to U+052F */ - if ( (code >= 0x0400 && code <= 0x04ff) || - (code >= 0x0500 && code <= 0x052f) ) { - if (code >= 0x0400 && code <= 0x040f) - *lower += 0x50; - else if (code >= 0x0410 && code <= 0x042f) - *lower += 0x20; - else if (code >= 0x0430 && code <= 0x044f) - *upper -= 0x20; - else if (code >= 0x0450 && code <= 0x045f) - *upper -= 0x50; - else if ( (code >= 0x0460 && code <= 0x0481) || - (code >= 0x048a && code <= 0x04bf) || - (code >= 0x04d0 && code <= 0x04f5) || - (code >= 0x04f8 && code <= 0x04f9) || - (code >= 0x0500 && code <= 0x050f) ) { - *upper &= ~1; - *lower |= 1; - } - else if (code >= 0x04c1 && code <= 0x04ce) { - if (code & 1) - *lower += 1; - else - *upper -= 1; - } - } - - /* Armenian, U+0530 to U+058F */ - if (code >= 0x0530 && code <= 0x058f) { - if (code >= 0x0531 && code <= 0x0556) - *lower += 0x30; - else if (code >=0x0561 && code <= 0x0586) - *upper -= 0x30; - } - - /* Latin Extended Additional, U+1E00 to U+1EFF */ - if (code >= 0x1e00 && code <= 0x1eff) { - if ( (code >= 0x1e00 && code <= 0x1e95) || - (code >= 0x1ea0 && code <= 0x1ef9) ) { - *upper &= ~1; - *lower |= 1; - } - else if (code == 0x1e9b) - *upper = 0x1e60; - } - - /* Greek Extended, U+1F00 to U+1FFF */ - if (code >= 0x1f00 && code <= 0x1fff) { - *lower = GreekExt_lower_mapping[code - 0x1f00]; - *upper = GreekExt_upper_mapping[code - 0x1f00]; - if (*upper == 0) - *upper = code; - if (*lower == 0) - *lower = code; - } - - /* Letterlike Symbols, U+2100 to U+214F */ - if (code >= 0x2100 && code <= 0x214f) { - switch (code) { - case 0x2126: *lower = 0x03c9; break; - case 0x212a: *lower = 0x006b; break; - case 0x212b: *lower = 0x00e5; break; - } - } - /* Number Forms, U+2150 to U+218F */ - else if (code >= 0x2160 && code <= 0x216f) - *lower += 0x10; - else if (code >= 0x2170 && code <= 0x217f) - *upper -= 0x10; - /* Enclosed Alphanumerics, U+2460 to U+24FF */ - else if (code >= 0x24b6 && code <= 0x24cf) - *lower += 0x1a; - else if (code >= 0x24d0 && code <= 0x24e9) - *upper -= 0x1a; - /* Halfwidth and Fullwidth Forms, U+FF00 to U+FFEF */ - else if (code >= 0xff21 && code <= 0xff3a) - *lower += 0x20; - else if (code >= 0xff41 && code <= 0xff5a) - *upper -= 0x20; - /* Deseret, U+10400 to U+104FF */ - else if (code >= 0x10400 && code <= 0x10427) - *lower += 0x28; - else if (code >= 0x10428 && code <= 0x1044f) - *upper -= 0x28; -} - -static void -XConvertCase(xkb_keysym_t sym, xkb_keysym_t *lower, xkb_keysym_t *upper) -{ - /* Latin 1 keysym */ - if (sym < 0x100) { - UCSConvertCase(sym, lower, upper); - return; - } - - /* Unicode keysym */ - if ((sym & 0xff000000) == 0x01000000) { - UCSConvertCase((sym & 0x00ffffff), lower, upper); - *upper |= 0x01000000; - *lower |= 0x01000000; - return; - } - - /* Legacy keysym */ - - *lower = sym; - *upper = sym; - - switch(sym >> 8) { - case 1: /* Latin 2 */ - /* Assume the KeySym is a legal value (ignore discontinuities) */ - if (sym == XKB_KEY_Aogonek) - *lower = XKB_KEY_aogonek; - else if (sym >= XKB_KEY_Lstroke && sym <= XKB_KEY_Sacute) - *lower += (XKB_KEY_lstroke - XKB_KEY_Lstroke); - else if (sym >= XKB_KEY_Scaron && sym <= XKB_KEY_Zacute) - *lower += (XKB_KEY_scaron - XKB_KEY_Scaron); - else if (sym >= XKB_KEY_Zcaron && sym <= XKB_KEY_Zabovedot) - *lower += (XKB_KEY_zcaron - XKB_KEY_Zcaron); - else if (sym == XKB_KEY_aogonek) - *upper = XKB_KEY_Aogonek; - else if (sym >= XKB_KEY_lstroke && sym <= XKB_KEY_sacute) - *upper -= (XKB_KEY_lstroke - XKB_KEY_Lstroke); - else if (sym >= XKB_KEY_scaron && sym <= XKB_KEY_zacute) - *upper -= (XKB_KEY_scaron - XKB_KEY_Scaron); - else if (sym >= XKB_KEY_zcaron && sym <= XKB_KEY_zabovedot) - *upper -= (XKB_KEY_zcaron - XKB_KEY_Zcaron); - else if (sym >= XKB_KEY_Racute && sym <= XKB_KEY_Tcedilla) - *lower += (XKB_KEY_racute - XKB_KEY_Racute); - else if (sym >= XKB_KEY_racute && sym <= XKB_KEY_tcedilla) - *upper -= (XKB_KEY_racute - XKB_KEY_Racute); - break; - case 2: /* Latin 3 */ - /* Assume the KeySym is a legal value (ignore discontinuities) */ - if (sym >= XKB_KEY_Hstroke && sym <= XKB_KEY_Hcircumflex) - *lower += (XKB_KEY_hstroke - XKB_KEY_Hstroke); - else if (sym >= XKB_KEY_Gbreve && sym <= XKB_KEY_Jcircumflex) - *lower += (XKB_KEY_gbreve - XKB_KEY_Gbreve); - else if (sym >= XKB_KEY_hstroke && sym <= XKB_KEY_hcircumflex) - *upper -= (XKB_KEY_hstroke - XKB_KEY_Hstroke); - else if (sym >= XKB_KEY_gbreve && sym <= XKB_KEY_jcircumflex) - *upper -= (XKB_KEY_gbreve - XKB_KEY_Gbreve); - else if (sym >= XKB_KEY_Cabovedot && sym <= XKB_KEY_Scircumflex) - *lower += (XKB_KEY_cabovedot - XKB_KEY_Cabovedot); - else if (sym >= XKB_KEY_cabovedot && sym <= XKB_KEY_scircumflex) - *upper -= (XKB_KEY_cabovedot - XKB_KEY_Cabovedot); - break; - case 3: /* Latin 4 */ - /* Assume the KeySym is a legal value (ignore discontinuities) */ - if (sym >= XKB_KEY_Rcedilla && sym <= XKB_KEY_Tslash) - *lower += (XKB_KEY_rcedilla - XKB_KEY_Rcedilla); - else if (sym >= XKB_KEY_rcedilla && sym <= XKB_KEY_tslash) - *upper -= (XKB_KEY_rcedilla - XKB_KEY_Rcedilla); - else if (sym == XKB_KEY_ENG) - *lower = XKB_KEY_eng; - else if (sym == XKB_KEY_eng) - *upper = XKB_KEY_ENG; - else if (sym >= XKB_KEY_Amacron && sym <= XKB_KEY_Umacron) - *lower += (XKB_KEY_amacron - XKB_KEY_Amacron); - else if (sym >= XKB_KEY_amacron && sym <= XKB_KEY_umacron) - *upper -= (XKB_KEY_amacron - XKB_KEY_Amacron); - break; - case 6: /* Cyrillic */ - /* Assume the KeySym is a legal value (ignore discontinuities) */ - if (sym >= XKB_KEY_Serbian_DJE && sym <= XKB_KEY_Serbian_DZE) - *lower -= (XKB_KEY_Serbian_DJE - XKB_KEY_Serbian_dje); - else if (sym >= XKB_KEY_Serbian_dje && sym <= XKB_KEY_Serbian_dze) - *upper += (XKB_KEY_Serbian_DJE - XKB_KEY_Serbian_dje); - else if (sym >= XKB_KEY_Cyrillic_YU && sym <= XKB_KEY_Cyrillic_HARDSIGN) - *lower -= (XKB_KEY_Cyrillic_YU - XKB_KEY_Cyrillic_yu); - else if (sym >= XKB_KEY_Cyrillic_yu && sym <= XKB_KEY_Cyrillic_hardsign) - *upper += (XKB_KEY_Cyrillic_YU - XKB_KEY_Cyrillic_yu); - break; - case 7: /* Greek */ - /* Assume the KeySym is a legal value (ignore discontinuities) */ - if (sym >= XKB_KEY_Greek_ALPHAaccent && sym <= XKB_KEY_Greek_OMEGAaccent) - *lower += (XKB_KEY_Greek_alphaaccent - XKB_KEY_Greek_ALPHAaccent); - else if (sym >= XKB_KEY_Greek_alphaaccent && sym <= XKB_KEY_Greek_omegaaccent && - sym != XKB_KEY_Greek_iotaaccentdieresis && - sym != XKB_KEY_Greek_upsilonaccentdieresis) - *upper -= (XKB_KEY_Greek_alphaaccent - XKB_KEY_Greek_ALPHAaccent); - else if (sym >= XKB_KEY_Greek_ALPHA && sym <= XKB_KEY_Greek_OMEGA) - *lower += (XKB_KEY_Greek_alpha - XKB_KEY_Greek_ALPHA); - else if (sym >= XKB_KEY_Greek_alpha && sym <= XKB_KEY_Greek_omega && - sym != XKB_KEY_Greek_finalsmallsigma) - *upper -= (XKB_KEY_Greek_alpha - XKB_KEY_Greek_ALPHA); - break; - case 0x13: /* Latin 9 */ - if (sym == XKB_KEY_OE) - *lower = XKB_KEY_oe; - else if (sym == XKB_KEY_oe) - *upper = XKB_KEY_OE; - else if (sym == XKB_KEY_Ydiaeresis) - *lower = XKB_KEY_ydiaeresis; - break; - } -} diff --git a/src/3rdparty/xkbcommon/src/keysym.h b/src/3rdparty/xkbcommon/src/keysym.h deleted file mode 100644 index 26339632ee..0000000000 --- a/src/3rdparty/xkbcommon/src/keysym.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 1985, 1987, 1990, 1998 The Open Group - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the names of the authors or their - * institutions shall not be used in advertising or otherwise to promote the - * sale, use or other dealings in this Software without prior written - * authorization from the authors. - */ - -/* - * Copyright © 2009 Dan Nicholson - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef KEYSYM_H -#define KEYSYM_H - -bool -xkb_keysym_is_lower(xkb_keysym_t keysym); - -bool -xkb_keysym_is_upper(xkb_keysym_t keysym); - -bool -xkb_keysym_is_keypad(xkb_keysym_t keysym); - -bool -xkb_keysym_is_modifier(xkb_keysym_t keysym); - -#endif diff --git a/src/3rdparty/xkbcommon/src/ks_tables.h b/src/3rdparty/xkbcommon/src/ks_tables.h deleted file mode 100644 index aa55fc1df0..0000000000 --- a/src/3rdparty/xkbcommon/src/ks_tables.h +++ /dev/null @@ -1,7116 +0,0 @@ - -/** - * This file comes from libxkbcommon and was generated by makekeys.py - * You can always fetch the latest version from: - * https://raw.github.com/xkbcommon/libxkbcommon/master/src/ks_tables.h - */ - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Woverlength-strings" -static const char *keysym_names = - "0\0" - "1\0" - "2\0" - "3\0" - "3270_AltCursor\0" - "3270_Attn\0" - "3270_BackTab\0" - "3270_ChangeScreen\0" - "3270_Copy\0" - "3270_CursorBlink\0" - "3270_CursorSelect\0" - "3270_DeleteWord\0" - "3270_Duplicate\0" - "3270_Enter\0" - "3270_EraseEOF\0" - "3270_EraseInput\0" - "3270_ExSelect\0" - "3270_FieldMark\0" - "3270_Ident\0" - "3270_Jump\0" - "3270_KeyClick\0" - "3270_Left2\0" - "3270_PA1\0" - "3270_PA2\0" - "3270_PA3\0" - "3270_Play\0" - "3270_PrintScreen\0" - "3270_Quit\0" - "3270_Record\0" - "3270_Reset\0" - "3270_Right2\0" - "3270_Rule\0" - "3270_Setup\0" - "3270_Test\0" - "4\0" - "5\0" - "6\0" - "7\0" - "8\0" - "9\0" - "A\0" - "a\0" - "Aacute\0" - "aacute\0" - "Abelowdot\0" - "abelowdot\0" - "abovedot\0" - "Abreve\0" - "abreve\0" - "Abreveacute\0" - "abreveacute\0" - "Abrevebelowdot\0" - "abrevebelowdot\0" - "Abrevegrave\0" - "abrevegrave\0" - "Abrevehook\0" - "abrevehook\0" - "Abrevetilde\0" - "abrevetilde\0" - "AccessX_Enable\0" - "AccessX_Feedback_Enable\0" - "Acircumflex\0" - "acircumflex\0" - "Acircumflexacute\0" - "acircumflexacute\0" - "Acircumflexbelowdot\0" - "acircumflexbelowdot\0" - "Acircumflexgrave\0" - "acircumflexgrave\0" - "Acircumflexhook\0" - "acircumflexhook\0" - "Acircumflextilde\0" - "acircumflextilde\0" - "acute\0" - "Adiaeresis\0" - "adiaeresis\0" - "AE\0" - "ae\0" - "Agrave\0" - "agrave\0" - "Ahook\0" - "ahook\0" - "Alt_L\0" - "Alt_R\0" - "Amacron\0" - "amacron\0" - "ampersand\0" - "Aogonek\0" - "aogonek\0" - "apostrophe\0" - "approxeq\0" - "approximate\0" - "Arabic_0\0" - "Arabic_1\0" - "Arabic_2\0" - "Arabic_3\0" - "Arabic_4\0" - "Arabic_5\0" - "Arabic_6\0" - "Arabic_7\0" - "Arabic_8\0" - "Arabic_9\0" - "Arabic_ain\0" - "Arabic_alef\0" - "Arabic_alefmaksura\0" - "Arabic_beh\0" - "Arabic_comma\0" - "Arabic_dad\0" - "Arabic_dal\0" - "Arabic_damma\0" - "Arabic_dammatan\0" - "Arabic_ddal\0" - "Arabic_farsi_yeh\0" - "Arabic_fatha\0" - "Arabic_fathatan\0" - "Arabic_feh\0" - "Arabic_fullstop\0" - "Arabic_gaf\0" - "Arabic_ghain\0" - "Arabic_ha\0" - "Arabic_hah\0" - "Arabic_hamza\0" - "Arabic_hamza_above\0" - "Arabic_hamza_below\0" - "Arabic_hamzaonalef\0" - "Arabic_hamzaonwaw\0" - "Arabic_hamzaonyeh\0" - "Arabic_hamzaunderalef\0" - "Arabic_heh\0" - "Arabic_heh_doachashmee\0" - "Arabic_heh_goal\0" - "Arabic_jeem\0" - "Arabic_jeh\0" - "Arabic_kaf\0" - "Arabic_kasra\0" - "Arabic_kasratan\0" - "Arabic_keheh\0" - "Arabic_khah\0" - "Arabic_lam\0" - "Arabic_madda_above\0" - "Arabic_maddaonalef\0" - "Arabic_meem\0" - "Arabic_noon\0" - "Arabic_noon_ghunna\0" - "Arabic_peh\0" - "Arabic_percent\0" - "Arabic_qaf\0" - "Arabic_question_mark\0" - "Arabic_ra\0" - "Arabic_rreh\0" - "Arabic_sad\0" - "Arabic_seen\0" - "Arabic_semicolon\0" - "Arabic_shadda\0" - "Arabic_sheen\0" - "Arabic_sukun\0" - "Arabic_superscript_alef\0" - "Arabic_switch\0" - "Arabic_tah\0" - "Arabic_tatweel\0" - "Arabic_tcheh\0" - "Arabic_teh\0" - "Arabic_tehmarbuta\0" - "Arabic_thal\0" - "Arabic_theh\0" - "Arabic_tteh\0" - "Arabic_veh\0" - "Arabic_waw\0" - "Arabic_yeh\0" - "Arabic_yeh_baree\0" - "Arabic_zah\0" - "Arabic_zain\0" - "Aring\0" - "aring\0" - "Armenian_accent\0" - "Armenian_amanak\0" - "Armenian_apostrophe\0" - "Armenian_AT\0" - "Armenian_at\0" - "Armenian_AYB\0" - "Armenian_ayb\0" - "Armenian_BEN\0" - "Armenian_ben\0" - "Armenian_but\0" - "Armenian_CHA\0" - "Armenian_cha\0" - "Armenian_DA\0" - "Armenian_da\0" - "Armenian_DZA\0" - "Armenian_dza\0" - "Armenian_E\0" - "Armenian_e\0" - "Armenian_exclam\0" - "Armenian_FE\0" - "Armenian_fe\0" - "Armenian_full_stop\0" - "Armenian_GHAT\0" - "Armenian_ghat\0" - "Armenian_GIM\0" - "Armenian_gim\0" - "Armenian_HI\0" - "Armenian_hi\0" - "Armenian_HO\0" - "Armenian_ho\0" - "Armenian_hyphen\0" - "Armenian_INI\0" - "Armenian_ini\0" - "Armenian_JE\0" - "Armenian_je\0" - "Armenian_KE\0" - "Armenian_ke\0" - "Armenian_KEN\0" - "Armenian_ken\0" - "Armenian_KHE\0" - "Armenian_khe\0" - "Armenian_ligature_ew\0" - "Armenian_LYUN\0" - "Armenian_lyun\0" - "Armenian_MEN\0" - "Armenian_men\0" - "Armenian_NU\0" - "Armenian_nu\0" - "Armenian_O\0" - "Armenian_o\0" - "Armenian_paruyk\0" - "Armenian_PE\0" - "Armenian_pe\0" - "Armenian_PYUR\0" - "Armenian_pyur\0" - "Armenian_question\0" - "Armenian_RA\0" - "Armenian_ra\0" - "Armenian_RE\0" - "Armenian_re\0" - "Armenian_SE\0" - "Armenian_se\0" - "Armenian_separation_mark\0" - "Armenian_SHA\0" - "Armenian_sha\0" - "Armenian_shesht\0" - "Armenian_TCHE\0" - "Armenian_tche\0" - "Armenian_TO\0" - "Armenian_to\0" - "Armenian_TSA\0" - "Armenian_tsa\0" - "Armenian_TSO\0" - "Armenian_tso\0" - "Armenian_TYUN\0" - "Armenian_tyun\0" - "Armenian_verjaket\0" - "Armenian_VEV\0" - "Armenian_vev\0" - "Armenian_VO\0" - "Armenian_vo\0" - "Armenian_VYUN\0" - "Armenian_vyun\0" - "Armenian_YECH\0" - "Armenian_yech\0" - "Armenian_yentamna\0" - "Armenian_ZA\0" - "Armenian_za\0" - "Armenian_ZHE\0" - "Armenian_zhe\0" - "asciicircum\0" - "asciitilde\0" - "asterisk\0" - "at\0" - "Atilde\0" - "atilde\0" - "AudibleBell_Enable\0" - "B\0" - "b\0" - "Babovedot\0" - "babovedot\0" - "backslash\0" - "BackSpace\0" - "BackTab\0" - "ballotcross\0" - "bar\0" - "because\0" - "Begin\0" - "blank\0" - "block\0" - "botintegral\0" - "botleftparens\0" - "botleftsqbracket\0" - "botleftsummation\0" - "botrightparens\0" - "botrightsqbracket\0" - "botrightsummation\0" - "bott\0" - "botvertsummationconnector\0" - "BounceKeys_Enable\0" - "braceleft\0" - "braceright\0" - "bracketleft\0" - "bracketright\0" - "braille_blank\0" - "braille_dot_1\0" - "braille_dot_10\0" - "braille_dot_2\0" - "braille_dot_3\0" - "braille_dot_4\0" - "braille_dot_5\0" - "braille_dot_6\0" - "braille_dot_7\0" - "braille_dot_8\0" - "braille_dot_9\0" - "braille_dots_1\0" - "braille_dots_12\0" - "braille_dots_123\0" - "braille_dots_1234\0" - "braille_dots_12345\0" - "braille_dots_123456\0" - "braille_dots_1234567\0" - "braille_dots_12345678\0" - "braille_dots_1234568\0" - "braille_dots_123457\0" - "braille_dots_1234578\0" - "braille_dots_123458\0" - "braille_dots_12346\0" - "braille_dots_123467\0" - "braille_dots_1234678\0" - "braille_dots_123468\0" - "braille_dots_12347\0" - "braille_dots_123478\0" - "braille_dots_12348\0" - "braille_dots_1235\0" - "braille_dots_12356\0" - "braille_dots_123567\0" - "braille_dots_1235678\0" - "braille_dots_123568\0" - "braille_dots_12357\0" - "braille_dots_123578\0" - "braille_dots_12358\0" - "braille_dots_1236\0" - "braille_dots_12367\0" - "braille_dots_123678\0" - "braille_dots_12368\0" - "braille_dots_1237\0" - "braille_dots_12378\0" - "braille_dots_1238\0" - "braille_dots_124\0" - "braille_dots_1245\0" - "braille_dots_12456\0" - "braille_dots_124567\0" - "braille_dots_1245678\0" - "braille_dots_124568\0" - "braille_dots_12457\0" - "braille_dots_124578\0" - "braille_dots_12458\0" - "braille_dots_1246\0" - "braille_dots_12467\0" - "braille_dots_124678\0" - "braille_dots_12468\0" - "braille_dots_1247\0" - "braille_dots_12478\0" - "braille_dots_1248\0" - "braille_dots_125\0" - "braille_dots_1256\0" - "braille_dots_12567\0" - "braille_dots_125678\0" - "braille_dots_12568\0" - "braille_dots_1257\0" - "braille_dots_12578\0" - "braille_dots_1258\0" - "braille_dots_126\0" - "braille_dots_1267\0" - "braille_dots_12678\0" - "braille_dots_1268\0" - "braille_dots_127\0" - "braille_dots_1278\0" - "braille_dots_128\0" - "braille_dots_13\0" - "braille_dots_134\0" - "braille_dots_1345\0" - "braille_dots_13456\0" - "braille_dots_134567\0" - "braille_dots_1345678\0" - "braille_dots_134568\0" - "braille_dots_13457\0" - "braille_dots_134578\0" - "braille_dots_13458\0" - "braille_dots_1346\0" - "braille_dots_13467\0" - "braille_dots_134678\0" - "braille_dots_13468\0" - "braille_dots_1347\0" - "braille_dots_13478\0" - "braille_dots_1348\0" - "braille_dots_135\0" - "braille_dots_1356\0" - "braille_dots_13567\0" - "braille_dots_135678\0" - "braille_dots_13568\0" - "braille_dots_1357\0" - "braille_dots_13578\0" - "braille_dots_1358\0" - "braille_dots_136\0" - "braille_dots_1367\0" - "braille_dots_13678\0" - "braille_dots_1368\0" - "braille_dots_137\0" - "braille_dots_1378\0" - "braille_dots_138\0" - "braille_dots_14\0" - "braille_dots_145\0" - "braille_dots_1456\0" - "braille_dots_14567\0" - "braille_dots_145678\0" - "braille_dots_14568\0" - "braille_dots_1457\0" - "braille_dots_14578\0" - "braille_dots_1458\0" - "braille_dots_146\0" - "braille_dots_1467\0" - "braille_dots_14678\0" - "braille_dots_1468\0" - "braille_dots_147\0" - "braille_dots_1478\0" - "braille_dots_148\0" - "braille_dots_15\0" - "braille_dots_156\0" - "braille_dots_1567\0" - "braille_dots_15678\0" - "braille_dots_1568\0" - "braille_dots_157\0" - "braille_dots_1578\0" - "braille_dots_158\0" - "braille_dots_16\0" - "braille_dots_167\0" - "braille_dots_1678\0" - "braille_dots_168\0" - "braille_dots_17\0" - "braille_dots_178\0" - "braille_dots_18\0" - "braille_dots_2\0" - "braille_dots_23\0" - "braille_dots_234\0" - "braille_dots_2345\0" - "braille_dots_23456\0" - "braille_dots_234567\0" - "braille_dots_2345678\0" - "braille_dots_234568\0" - "braille_dots_23457\0" - "braille_dots_234578\0" - "braille_dots_23458\0" - "braille_dots_2346\0" - "braille_dots_23467\0" - "braille_dots_234678\0" - "braille_dots_23468\0" - "braille_dots_2347\0" - "braille_dots_23478\0" - "braille_dots_2348\0" - "braille_dots_235\0" - "braille_dots_2356\0" - "braille_dots_23567\0" - "braille_dots_235678\0" - "braille_dots_23568\0" - "braille_dots_2357\0" - "braille_dots_23578\0" - "braille_dots_2358\0" - "braille_dots_236\0" - "braille_dots_2367\0" - "braille_dots_23678\0" - "braille_dots_2368\0" - "braille_dots_237\0" - "braille_dots_2378\0" - "braille_dots_238\0" - "braille_dots_24\0" - "braille_dots_245\0" - "braille_dots_2456\0" - "braille_dots_24567\0" - "braille_dots_245678\0" - "braille_dots_24568\0" - "braille_dots_2457\0" - "braille_dots_24578\0" - "braille_dots_2458\0" - "braille_dots_246\0" - "braille_dots_2467\0" - "braille_dots_24678\0" - "braille_dots_2468\0" - "braille_dots_247\0" - "braille_dots_2478\0" - "braille_dots_248\0" - "braille_dots_25\0" - "braille_dots_256\0" - "braille_dots_2567\0" - "braille_dots_25678\0" - "braille_dots_2568\0" - "braille_dots_257\0" - "braille_dots_2578\0" - "braille_dots_258\0" - "braille_dots_26\0" - "braille_dots_267\0" - "braille_dots_2678\0" - "braille_dots_268\0" - "braille_dots_27\0" - "braille_dots_278\0" - "braille_dots_28\0" - "braille_dots_3\0" - "braille_dots_34\0" - "braille_dots_345\0" - "braille_dots_3456\0" - "braille_dots_34567\0" - "braille_dots_345678\0" - "braille_dots_34568\0" - "braille_dots_3457\0" - "braille_dots_34578\0" - "braille_dots_3458\0" - "braille_dots_346\0" - "braille_dots_3467\0" - "braille_dots_34678\0" - "braille_dots_3468\0" - "braille_dots_347\0" - "braille_dots_3478\0" - "braille_dots_348\0" - "braille_dots_35\0" - "braille_dots_356\0" - "braille_dots_3567\0" - "braille_dots_35678\0" - "braille_dots_3568\0" - "braille_dots_357\0" - "braille_dots_3578\0" - "braille_dots_358\0" - "braille_dots_36\0" - "braille_dots_367\0" - "braille_dots_3678\0" - "braille_dots_368\0" - "braille_dots_37\0" - "braille_dots_378\0" - "braille_dots_38\0" - "braille_dots_4\0" - "braille_dots_45\0" - "braille_dots_456\0" - "braille_dots_4567\0" - "braille_dots_45678\0" - "braille_dots_4568\0" - "braille_dots_457\0" - "braille_dots_4578\0" - "braille_dots_458\0" - "braille_dots_46\0" - "braille_dots_467\0" - "braille_dots_4678\0" - "braille_dots_468\0" - "braille_dots_47\0" - "braille_dots_478\0" - "braille_dots_48\0" - "braille_dots_5\0" - "braille_dots_56\0" - "braille_dots_567\0" - "braille_dots_5678\0" - "braille_dots_568\0" - "braille_dots_57\0" - "braille_dots_578\0" - "braille_dots_58\0" - "braille_dots_6\0" - "braille_dots_67\0" - "braille_dots_678\0" - "braille_dots_68\0" - "braille_dots_7\0" - "braille_dots_78\0" - "braille_dots_8\0" - "Break\0" - "breve\0" - "brokenbar\0" - "Byelorussian_shortu\0" - "Byelorussian_SHORTU\0" - "C\0" - "c\0" - "c_h\0" - "C_h\0" - "C_H\0" - "Cabovedot\0" - "cabovedot\0" - "Cacute\0" - "cacute\0" - "Cancel\0" - "Caps_Lock\0" - "careof\0" - "caret\0" - "caron\0" - "Ccaron\0" - "ccaron\0" - "Ccedilla\0" - "ccedilla\0" - "Ccircumflex\0" - "ccircumflex\0" - "cedilla\0" - "cent\0" - "ch\0" - "Ch\0" - "CH\0" - "checkerboard\0" - "checkmark\0" - "circle\0" - "Clear\0" - "ClearLine\0" - "club\0" - "Codeinput\0" - "colon\0" - "ColonSign\0" - "comma\0" - "containsas\0" - "Control_L\0" - "Control_R\0" - "copyright\0" - "cr\0" - "crossinglines\0" - "CruzeiroSign\0" - "cuberoot\0" - "currency\0" - "cursor\0" - "Cyrillic_a\0" - "Cyrillic_A\0" - "Cyrillic_be\0" - "Cyrillic_BE\0" - "Cyrillic_che\0" - "Cyrillic_CHE\0" - "Cyrillic_CHE_descender\0" - "Cyrillic_che_descender\0" - "Cyrillic_CHE_vertstroke\0" - "Cyrillic_che_vertstroke\0" - "Cyrillic_de\0" - "Cyrillic_DE\0" - "Cyrillic_dzhe\0" - "Cyrillic_DZHE\0" - "Cyrillic_e\0" - "Cyrillic_E\0" - "Cyrillic_ef\0" - "Cyrillic_EF\0" - "Cyrillic_el\0" - "Cyrillic_EL\0" - "Cyrillic_em\0" - "Cyrillic_EM\0" - "Cyrillic_en\0" - "Cyrillic_EN\0" - "Cyrillic_EN_descender\0" - "Cyrillic_en_descender\0" - "Cyrillic_er\0" - "Cyrillic_ER\0" - "Cyrillic_es\0" - "Cyrillic_ES\0" - "Cyrillic_ghe\0" - "Cyrillic_GHE\0" - "Cyrillic_GHE_bar\0" - "Cyrillic_ghe_bar\0" - "Cyrillic_ha\0" - "Cyrillic_HA\0" - "Cyrillic_HA_descender\0" - "Cyrillic_ha_descender\0" - "Cyrillic_hardsign\0" - "Cyrillic_HARDSIGN\0" - "Cyrillic_i\0" - "Cyrillic_I\0" - "Cyrillic_I_macron\0" - "Cyrillic_i_macron\0" - "Cyrillic_ie\0" - "Cyrillic_IE\0" - "Cyrillic_io\0" - "Cyrillic_IO\0" - "Cyrillic_je\0" - "Cyrillic_JE\0" - "Cyrillic_ka\0" - "Cyrillic_KA\0" - "Cyrillic_KA_descender\0" - "Cyrillic_ka_descender\0" - "Cyrillic_KA_vertstroke\0" - "Cyrillic_ka_vertstroke\0" - "Cyrillic_lje\0" - "Cyrillic_LJE\0" - "Cyrillic_nje\0" - "Cyrillic_NJE\0" - "Cyrillic_o\0" - "Cyrillic_O\0" - "Cyrillic_O_bar\0" - "Cyrillic_o_bar\0" - "Cyrillic_pe\0" - "Cyrillic_PE\0" - "Cyrillic_SCHWA\0" - "Cyrillic_schwa\0" - "Cyrillic_sha\0" - "Cyrillic_SHA\0" - "Cyrillic_shcha\0" - "Cyrillic_SHCHA\0" - "Cyrillic_SHHA\0" - "Cyrillic_shha\0" - "Cyrillic_shorti\0" - "Cyrillic_SHORTI\0" - "Cyrillic_softsign\0" - "Cyrillic_SOFTSIGN\0" - "Cyrillic_te\0" - "Cyrillic_TE\0" - "Cyrillic_tse\0" - "Cyrillic_TSE\0" - "Cyrillic_u\0" - "Cyrillic_U\0" - "Cyrillic_U_macron\0" - "Cyrillic_u_macron\0" - "Cyrillic_U_straight\0" - "Cyrillic_u_straight\0" - "Cyrillic_U_straight_bar\0" - "Cyrillic_u_straight_bar\0" - "Cyrillic_ve\0" - "Cyrillic_VE\0" - "Cyrillic_ya\0" - "Cyrillic_YA\0" - "Cyrillic_yeru\0" - "Cyrillic_YERU\0" - "Cyrillic_yu\0" - "Cyrillic_YU\0" - "Cyrillic_ze\0" - "Cyrillic_ZE\0" - "Cyrillic_zhe\0" - "Cyrillic_ZHE\0" - "Cyrillic_ZHE_descender\0" - "Cyrillic_zhe_descender\0" - "D\0" - "d\0" - "Dabovedot\0" - "dabovedot\0" - "Dacute_accent\0" - "dagger\0" - "Dcaron\0" - "dcaron\0" - "Dcedilla_accent\0" - "Dcircumflex_accent\0" - "Ddiaeresis\0" - "dead_a\0" - "dead_A\0" - "dead_abovecomma\0" - "dead_abovedot\0" - "dead_abovereversedcomma\0" - "dead_abovering\0" - "dead_aboveverticalline\0" - "dead_acute\0" - "dead_belowbreve\0" - "dead_belowcircumflex\0" - "dead_belowcomma\0" - "dead_belowdiaeresis\0" - "dead_belowdot\0" - "dead_belowmacron\0" - "dead_belowring\0" - "dead_belowtilde\0" - "dead_belowverticalline\0" - "dead_breve\0" - "dead_capital_schwa\0" - "dead_caron\0" - "dead_cedilla\0" - "dead_circumflex\0" - "dead_currency\0" - "dead_dasia\0" - "dead_diaeresis\0" - "dead_doubleacute\0" - "dead_doublegrave\0" - "dead_e\0" - "dead_E\0" - "dead_grave\0" - "dead_greek\0" - "dead_hook\0" - "dead_horn\0" - "dead_i\0" - "dead_I\0" - "dead_invertedbreve\0" - "dead_iota\0" - "dead_longsolidusoverlay\0" - "dead_lowline\0" - "dead_macron\0" - "dead_o\0" - "dead_O\0" - "dead_ogonek\0" - "dead_perispomeni\0" - "dead_psili\0" - "dead_semivoiced_sound\0" - "dead_small_schwa\0" - "dead_stroke\0" - "dead_tilde\0" - "dead_u\0" - "dead_U\0" - "dead_voiced_sound\0" - "decimalpoint\0" - "degree\0" - "Delete\0" - "DeleteChar\0" - "DeleteLine\0" - "Dgrave_accent\0" - "diaeresis\0" - "diamond\0" - "digitspace\0" - "dintegral\0" - "division\0" - "dollar\0" - "DongSign\0" - "doubbaselinedot\0" - "doubleacute\0" - "doubledagger\0" - "doublelowquotemark\0" - "Down\0" - "downarrow\0" - "downcaret\0" - "downshoe\0" - "downstile\0" - "downtack\0" - "DRemove\0" - "Dring_accent\0" - "Dstroke\0" - "dstroke\0" - "Dtilde\0" - "E\0" - "e\0" - "Eabovedot\0" - "eabovedot\0" - "Eacute\0" - "eacute\0" - "Ebelowdot\0" - "ebelowdot\0" - "Ecaron\0" - "ecaron\0" - "Ecircumflex\0" - "ecircumflex\0" - "Ecircumflexacute\0" - "ecircumflexacute\0" - "Ecircumflexbelowdot\0" - "ecircumflexbelowdot\0" - "Ecircumflexgrave\0" - "ecircumflexgrave\0" - "Ecircumflexhook\0" - "ecircumflexhook\0" - "Ecircumflextilde\0" - "ecircumflextilde\0" - "EcuSign\0" - "Ediaeresis\0" - "ediaeresis\0" - "Egrave\0" - "egrave\0" - "Ehook\0" - "ehook\0" - "eightsubscript\0" - "eightsuperior\0" - "Eisu_Shift\0" - "Eisu_toggle\0" - "elementof\0" - "ellipsis\0" - "em3space\0" - "em4space\0" - "Emacron\0" - "emacron\0" - "emdash\0" - "emfilledcircle\0" - "emfilledrect\0" - "emopencircle\0" - "emopenrectangle\0" - "emptyset\0" - "emspace\0" - "End\0" - "endash\0" - "enfilledcircbullet\0" - "enfilledsqbullet\0" - "ENG\0" - "eng\0" - "enopencircbullet\0" - "enopensquarebullet\0" - "enspace\0" - "Eogonek\0" - "eogonek\0" - "equal\0" - "Escape\0" - "ETH\0" - "Eth\0" - "eth\0" - "Etilde\0" - "etilde\0" - "EuroSign\0" - "exclam\0" - "exclamdown\0" - "Execute\0" - "Ext16bit_L\0" - "Ext16bit_R\0" - "EZH\0" - "ezh\0" - "F\0" - "f\0" - "F1\0" - "F10\0" - "F11\0" - "F12\0" - "F13\0" - "F14\0" - "F15\0" - "F16\0" - "F17\0" - "F18\0" - "F19\0" - "F2\0" - "F20\0" - "F21\0" - "F22\0" - "F23\0" - "F24\0" - "F25\0" - "F26\0" - "F27\0" - "F28\0" - "F29\0" - "F3\0" - "F30\0" - "F31\0" - "F32\0" - "F33\0" - "F34\0" - "F35\0" - "F4\0" - "F5\0" - "F6\0" - "F7\0" - "F8\0" - "F9\0" - "Fabovedot\0" - "fabovedot\0" - "Farsi_0\0" - "Farsi_1\0" - "Farsi_2\0" - "Farsi_3\0" - "Farsi_4\0" - "Farsi_5\0" - "Farsi_6\0" - "Farsi_7\0" - "Farsi_8\0" - "Farsi_9\0" - "Farsi_yeh\0" - "femalesymbol\0" - "ff\0" - "FFrancSign\0" - "figdash\0" - "filledlefttribullet\0" - "filledrectbullet\0" - "filledrighttribullet\0" - "filledtribulletdown\0" - "filledtribulletup\0" - "Find\0" - "First_Virtual_Screen\0" - "fiveeighths\0" - "fivesixths\0" - "fivesubscript\0" - "fivesuperior\0" - "fourfifths\0" - "foursubscript\0" - "foursuperior\0" - "fourthroot\0" - "function\0" - "G\0" - "g\0" - "Gabovedot\0" - "gabovedot\0" - "Gbreve\0" - "gbreve\0" - "Gcaron\0" - "gcaron\0" - "Gcedilla\0" - "gcedilla\0" - "Gcircumflex\0" - "gcircumflex\0" - "Georgian_an\0" - "Georgian_ban\0" - "Georgian_can\0" - "Georgian_char\0" - "Georgian_chin\0" - "Georgian_cil\0" - "Georgian_don\0" - "Georgian_en\0" - "Georgian_fi\0" - "Georgian_gan\0" - "Georgian_ghan\0" - "Georgian_hae\0" - "Georgian_har\0" - "Georgian_he\0" - "Georgian_hie\0" - "Georgian_hoe\0" - "Georgian_in\0" - "Georgian_jhan\0" - "Georgian_jil\0" - "Georgian_kan\0" - "Georgian_khar\0" - "Georgian_las\0" - "Georgian_man\0" - "Georgian_nar\0" - "Georgian_on\0" - "Georgian_par\0" - "Georgian_phar\0" - "Georgian_qar\0" - "Georgian_rae\0" - "Georgian_san\0" - "Georgian_shin\0" - "Georgian_tan\0" - "Georgian_tar\0" - "Georgian_un\0" - "Georgian_vin\0" - "Georgian_we\0" - "Georgian_xan\0" - "Georgian_zen\0" - "Georgian_zhar\0" - "grave\0" - "greater\0" - "greaterthanequal\0" - "Greek_accentdieresis\0" - "Greek_ALPHA\0" - "Greek_alpha\0" - "Greek_ALPHAaccent\0" - "Greek_alphaaccent\0" - "Greek_BETA\0" - "Greek_beta\0" - "Greek_CHI\0" - "Greek_chi\0" - "Greek_DELTA\0" - "Greek_delta\0" - "Greek_EPSILON\0" - "Greek_epsilon\0" - "Greek_EPSILONaccent\0" - "Greek_epsilonaccent\0" - "Greek_ETA\0" - "Greek_eta\0" - "Greek_ETAaccent\0" - "Greek_etaaccent\0" - "Greek_finalsmallsigma\0" - "Greek_GAMMA\0" - "Greek_gamma\0" - "Greek_horizbar\0" - "Greek_IOTA\0" - "Greek_iota\0" - "Greek_IOTAaccent\0" - "Greek_iotaaccent\0" - "Greek_iotaaccentdieresis\0" - "Greek_IOTAdiaeresis\0" - "Greek_IOTAdieresis\0" - "Greek_iotadieresis\0" - "Greek_KAPPA\0" - "Greek_kappa\0" - "Greek_LAMBDA\0" - "Greek_lambda\0" - "Greek_LAMDA\0" - "Greek_lamda\0" - "Greek_MU\0" - "Greek_mu\0" - "Greek_NU\0" - "Greek_nu\0" - "Greek_OMEGA\0" - "Greek_omega\0" - "Greek_OMEGAaccent\0" - "Greek_omegaaccent\0" - "Greek_OMICRON\0" - "Greek_omicron\0" - "Greek_OMICRONaccent\0" - "Greek_omicronaccent\0" - "Greek_PHI\0" - "Greek_phi\0" - "Greek_PI\0" - "Greek_pi\0" - "Greek_PSI\0" - "Greek_psi\0" - "Greek_RHO\0" - "Greek_rho\0" - "Greek_SIGMA\0" - "Greek_sigma\0" - "Greek_switch\0" - "Greek_TAU\0" - "Greek_tau\0" - "Greek_THETA\0" - "Greek_theta\0" - "Greek_UPSILON\0" - "Greek_upsilon\0" - "Greek_UPSILONaccent\0" - "Greek_upsilonaccent\0" - "Greek_upsilonaccentdieresis\0" - "Greek_UPSILONdieresis\0" - "Greek_upsilondieresis\0" - "Greek_XI\0" - "Greek_xi\0" - "Greek_ZETA\0" - "Greek_zeta\0" - "guilder\0" - "guillemotleft\0" - "guillemotright\0" - "H\0" - "h\0" - "hairspace\0" - "Hangul\0" - "Hangul_A\0" - "Hangul_AE\0" - "Hangul_AraeA\0" - "Hangul_AraeAE\0" - "Hangul_Banja\0" - "Hangul_Cieuc\0" - "Hangul_Codeinput\0" - "Hangul_Dikeud\0" - "Hangul_E\0" - "Hangul_End\0" - "Hangul_EO\0" - "Hangul_EU\0" - "Hangul_Hanja\0" - "Hangul_Hieuh\0" - "Hangul_I\0" - "Hangul_Ieung\0" - "Hangul_J_Cieuc\0" - "Hangul_J_Dikeud\0" - "Hangul_J_Hieuh\0" - "Hangul_J_Ieung\0" - "Hangul_J_Jieuj\0" - "Hangul_J_Khieuq\0" - "Hangul_J_Kiyeog\0" - "Hangul_J_KiyeogSios\0" - "Hangul_J_KkogjiDalrinIeung\0" - "Hangul_J_Mieum\0" - "Hangul_J_Nieun\0" - "Hangul_J_NieunHieuh\0" - "Hangul_J_NieunJieuj\0" - "Hangul_J_PanSios\0" - "Hangul_J_Phieuf\0" - "Hangul_J_Pieub\0" - "Hangul_J_PieubSios\0" - "Hangul_J_Rieul\0" - "Hangul_J_RieulHieuh\0" - "Hangul_J_RieulKiyeog\0" - "Hangul_J_RieulMieum\0" - "Hangul_J_RieulPhieuf\0" - "Hangul_J_RieulPieub\0" - "Hangul_J_RieulSios\0" - "Hangul_J_RieulTieut\0" - "Hangul_J_Sios\0" - "Hangul_J_SsangKiyeog\0" - "Hangul_J_SsangSios\0" - "Hangul_J_Tieut\0" - "Hangul_J_YeorinHieuh\0" - "Hangul_Jamo\0" - "Hangul_Jeonja\0" - "Hangul_Jieuj\0" - "Hangul_Khieuq\0" - "Hangul_Kiyeog\0" - "Hangul_KiyeogSios\0" - "Hangul_KkogjiDalrinIeung\0" - "Hangul_Mieum\0" - "Hangul_MultipleCandidate\0" - "Hangul_Nieun\0" - "Hangul_NieunHieuh\0" - "Hangul_NieunJieuj\0" - "Hangul_O\0" - "Hangul_OE\0" - "Hangul_PanSios\0" - "Hangul_Phieuf\0" - "Hangul_Pieub\0" - "Hangul_PieubSios\0" - "Hangul_PostHanja\0" - "Hangul_PreHanja\0" - "Hangul_PreviousCandidate\0" - "Hangul_Rieul\0" - "Hangul_RieulHieuh\0" - "Hangul_RieulKiyeog\0" - "Hangul_RieulMieum\0" - "Hangul_RieulPhieuf\0" - "Hangul_RieulPieub\0" - "Hangul_RieulSios\0" - "Hangul_RieulTieut\0" - "Hangul_RieulYeorinHieuh\0" - "Hangul_Romaja\0" - "Hangul_SingleCandidate\0" - "Hangul_Sios\0" - "Hangul_Special\0" - "Hangul_SsangDikeud\0" - "Hangul_SsangJieuj\0" - "Hangul_SsangKiyeog\0" - "Hangul_SsangPieub\0" - "Hangul_SsangSios\0" - "Hangul_Start\0" - "Hangul_SunkyeongeumMieum\0" - "Hangul_SunkyeongeumPhieuf\0" - "Hangul_SunkyeongeumPieub\0" - "Hangul_switch\0" - "Hangul_Tieut\0" - "Hangul_U\0" - "Hangul_WA\0" - "Hangul_WAE\0" - "Hangul_WE\0" - "Hangul_WEO\0" - "Hangul_WI\0" - "Hangul_YA\0" - "Hangul_YAE\0" - "Hangul_YE\0" - "Hangul_YEO\0" - "Hangul_YeorinHieuh\0" - "Hangul_YI\0" - "Hangul_YO\0" - "Hangul_YU\0" - "Hankaku\0" - "Hcircumflex\0" - "hcircumflex\0" - "heart\0" - "hebrew_aleph\0" - "hebrew_ayin\0" - "hebrew_bet\0" - "hebrew_beth\0" - "hebrew_chet\0" - "hebrew_dalet\0" - "hebrew_daleth\0" - "hebrew_doublelowline\0" - "hebrew_finalkaph\0" - "hebrew_finalmem\0" - "hebrew_finalnun\0" - "hebrew_finalpe\0" - "hebrew_finalzade\0" - "hebrew_finalzadi\0" - "hebrew_gimel\0" - "hebrew_gimmel\0" - "hebrew_he\0" - "hebrew_het\0" - "hebrew_kaph\0" - "hebrew_kuf\0" - "hebrew_lamed\0" - "hebrew_mem\0" - "hebrew_nun\0" - "hebrew_pe\0" - "hebrew_qoph\0" - "hebrew_resh\0" - "hebrew_samech\0" - "hebrew_samekh\0" - "hebrew_shin\0" - "Hebrew_switch\0" - "hebrew_taf\0" - "hebrew_taw\0" - "hebrew_tet\0" - "hebrew_teth\0" - "hebrew_waw\0" - "hebrew_yod\0" - "hebrew_zade\0" - "hebrew_zadi\0" - "hebrew_zain\0" - "hebrew_zayin\0" - "Help\0" - "Henkan\0" - "Henkan_Mode\0" - "hexagram\0" - "Hiragana\0" - "Hiragana_Katakana\0" - "Home\0" - "horizconnector\0" - "horizlinescan1\0" - "horizlinescan3\0" - "horizlinescan5\0" - "horizlinescan7\0" - "horizlinescan9\0" - "hpBackTab\0" - "hpblock\0" - "hpClearLine\0" - "hpDeleteChar\0" - "hpDeleteLine\0" - "hpguilder\0" - "hpInsertChar\0" - "hpInsertLine\0" - "hpIO\0" - "hpKP_BackTab\0" - "hplira\0" - "hplongminus\0" - "hpModelock1\0" - "hpModelock2\0" - "hpmute_acute\0" - "hpmute_asciicircum\0" - "hpmute_asciitilde\0" - "hpmute_diaeresis\0" - "hpmute_grave\0" - "hpReset\0" - "hpSystem\0" - "hpUser\0" - "hpYdiaeresis\0" - "Hstroke\0" - "hstroke\0" - "ht\0" - "Hyper_L\0" - "Hyper_R\0" - "hyphen\0" - "I\0" - "i\0" - "Iabovedot\0" - "Iacute\0" - "iacute\0" - "Ibelowdot\0" - "ibelowdot\0" - "Ibreve\0" - "ibreve\0" - "Icircumflex\0" - "icircumflex\0" - "identical\0" - "Idiaeresis\0" - "idiaeresis\0" - "idotless\0" - "ifonlyif\0" - "Igrave\0" - "igrave\0" - "Ihook\0" - "ihook\0" - "Imacron\0" - "imacron\0" - "implies\0" - "includedin\0" - "includes\0" - "infinity\0" - "Insert\0" - "InsertChar\0" - "InsertLine\0" - "integral\0" - "intersection\0" - "IO\0" - "Iogonek\0" - "iogonek\0" - "ISO_Center_Object\0" - "ISO_Continuous_Underline\0" - "ISO_Discontinuous_Underline\0" - "ISO_Emphasize\0" - "ISO_Enter\0" - "ISO_Fast_Cursor_Down\0" - "ISO_Fast_Cursor_Left\0" - "ISO_Fast_Cursor_Right\0" - "ISO_Fast_Cursor_Up\0" - "ISO_First_Group\0" - "ISO_First_Group_Lock\0" - "ISO_Group_Latch\0" - "ISO_Group_Lock\0" - "ISO_Group_Shift\0" - "ISO_Last_Group\0" - "ISO_Last_Group_Lock\0" - "ISO_Left_Tab\0" - "ISO_Level2_Latch\0" - "ISO_Level3_Latch\0" - "ISO_Level3_Lock\0" - "ISO_Level3_Shift\0" - "ISO_Level5_Latch\0" - "ISO_Level5_Lock\0" - "ISO_Level5_Shift\0" - "ISO_Lock\0" - "ISO_Move_Line_Down\0" - "ISO_Move_Line_Up\0" - "ISO_Next_Group\0" - "ISO_Next_Group_Lock\0" - "ISO_Partial_Line_Down\0" - "ISO_Partial_Line_Up\0" - "ISO_Partial_Space_Left\0" - "ISO_Partial_Space_Right\0" - "ISO_Prev_Group\0" - "ISO_Prev_Group_Lock\0" - "ISO_Release_Both_Margins\0" - "ISO_Release_Margin_Left\0" - "ISO_Release_Margin_Right\0" - "ISO_Set_Margin_Left\0" - "ISO_Set_Margin_Right\0" - "Itilde\0" - "itilde\0" - "J\0" - "j\0" - "Jcircumflex\0" - "jcircumflex\0" - "jot\0" - "K\0" - "k\0" - "kana_a\0" - "kana_A\0" - "kana_CHI\0" - "kana_closingbracket\0" - "kana_comma\0" - "kana_conjunctive\0" - "kana_e\0" - "kana_E\0" - "kana_FU\0" - "kana_fullstop\0" - "kana_HA\0" - "kana_HE\0" - "kana_HI\0" - "kana_HO\0" - "kana_HU\0" - "kana_i\0" - "kana_I\0" - "kana_KA\0" - "kana_KE\0" - "kana_KI\0" - "kana_KO\0" - "kana_KU\0" - "Kana_Lock\0" - "kana_MA\0" - "kana_ME\0" - "kana_MI\0" - "kana_middledot\0" - "kana_MO\0" - "kana_MU\0" - "kana_N\0" - "kana_NA\0" - "kana_NE\0" - "kana_NI\0" - "kana_NO\0" - "kana_NU\0" - "kana_o\0" - "kana_O\0" - "kana_openingbracket\0" - "kana_RA\0" - "kana_RE\0" - "kana_RI\0" - "kana_RO\0" - "kana_RU\0" - "kana_SA\0" - "kana_SE\0" - "kana_SHI\0" - "Kana_Shift\0" - "kana_SO\0" - "kana_SU\0" - "kana_switch\0" - "kana_TA\0" - "kana_TE\0" - "kana_TI\0" - "kana_TO\0" - "kana_tsu\0" - "kana_TSU\0" - "kana_tu\0" - "kana_TU\0" - "kana_u\0" - "kana_U\0" - "kana_WA\0" - "kana_WO\0" - "kana_ya\0" - "kana_YA\0" - "kana_yo\0" - "kana_YO\0" - "kana_yu\0" - "kana_YU\0" - "Kanji\0" - "Kanji_Bangou\0" - "kappa\0" - "Katakana\0" - "Kcedilla\0" - "kcedilla\0" - "Korean_Won\0" - "KP_0\0" - "KP_1\0" - "KP_2\0" - "KP_3\0" - "KP_4\0" - "KP_5\0" - "KP_6\0" - "KP_7\0" - "KP_8\0" - "KP_9\0" - "KP_Add\0" - "KP_BackTab\0" - "KP_Begin\0" - "KP_Decimal\0" - "KP_Delete\0" - "KP_Divide\0" - "KP_Down\0" - "KP_End\0" - "KP_Enter\0" - "KP_Equal\0" - "KP_F1\0" - "KP_F2\0" - "KP_F3\0" - "KP_F4\0" - "KP_Home\0" - "KP_Insert\0" - "KP_Left\0" - "KP_Multiply\0" - "KP_Next\0" - "KP_Page_Down\0" - "KP_Page_Up\0" - "KP_Prior\0" - "KP_Right\0" - "KP_Separator\0" - "KP_Space\0" - "KP_Subtract\0" - "KP_Tab\0" - "KP_Up\0" - "kra\0" - "L\0" - "l\0" - "L1\0" - "L10\0" - "L2\0" - "L3\0" - "L4\0" - "L5\0" - "L6\0" - "L7\0" - "L8\0" - "L9\0" - "Lacute\0" - "lacute\0" - "Last_Virtual_Screen\0" - "latincross\0" - "Lbelowdot\0" - "lbelowdot\0" - "Lcaron\0" - "lcaron\0" - "Lcedilla\0" - "lcedilla\0" - "Left\0" - "leftanglebracket\0" - "leftarrow\0" - "leftcaret\0" - "leftdoublequotemark\0" - "leftmiddlecurlybrace\0" - "leftopentriangle\0" - "leftpointer\0" - "leftradical\0" - "leftshoe\0" - "leftsinglequotemark\0" - "leftt\0" - "lefttack\0" - "less\0" - "lessthanequal\0" - "lf\0" - "Linefeed\0" - "lira\0" - "LiraSign\0" - "logicaland\0" - "logicalor\0" - "longminus\0" - "lowleftcorner\0" - "lowrightcorner\0" - "Lstroke\0" - "lstroke\0" - "M\0" - "m\0" - "Mabovedot\0" - "mabovedot\0" - "Macedonia_dse\0" - "Macedonia_DSE\0" - "Macedonia_gje\0" - "Macedonia_GJE\0" - "Macedonia_kje\0" - "Macedonia_KJE\0" - "macron\0" - "Mae_Koho\0" - "malesymbol\0" - "maltesecross\0" - "marker\0" - "masculine\0" - "Massyo\0" - "Menu\0" - "Meta_L\0" - "Meta_R\0" - "MillSign\0" - "minus\0" - "minutes\0" - "Mode_switch\0" - "MouseKeys_Accel_Enable\0" - "MouseKeys_Enable\0" - "mu\0" - "Muhenkan\0" - "Multi_key\0" - "MultipleCandidate\0" - "multiply\0" - "musicalflat\0" - "musicalsharp\0" - "mute_acute\0" - "mute_asciicircum\0" - "mute_asciitilde\0" - "mute_diaeresis\0" - "mute_grave\0" - "N\0" - "n\0" - "nabla\0" - "Nacute\0" - "nacute\0" - "NairaSign\0" - "Ncaron\0" - "ncaron\0" - "Ncedilla\0" - "ncedilla\0" - "NewSheqelSign\0" - "Next\0" - "Next_Virtual_Screen\0" - "ninesubscript\0" - "ninesuperior\0" - "nl\0" - "nobreakspace\0" - "NoSymbol\0" - "notapproxeq\0" - "notelementof\0" - "notequal\0" - "notidentical\0" - "notsign\0" - "Ntilde\0" - "ntilde\0" - "Num_Lock\0" - "numbersign\0" - "numerosign\0" - "O\0" - "o\0" - "Oacute\0" - "oacute\0" - "Obarred\0" - "obarred\0" - "Obelowdot\0" - "obelowdot\0" - "Ocaron\0" - "ocaron\0" - "Ocircumflex\0" - "ocircumflex\0" - "Ocircumflexacute\0" - "ocircumflexacute\0" - "Ocircumflexbelowdot\0" - "ocircumflexbelowdot\0" - "Ocircumflexgrave\0" - "ocircumflexgrave\0" - "Ocircumflexhook\0" - "ocircumflexhook\0" - "Ocircumflextilde\0" - "ocircumflextilde\0" - "Odiaeresis\0" - "odiaeresis\0" - "Odoubleacute\0" - "odoubleacute\0" - "OE\0" - "oe\0" - "ogonek\0" - "Ograve\0" - "ograve\0" - "Ohook\0" - "ohook\0" - "Ohorn\0" - "ohorn\0" - "Ohornacute\0" - "ohornacute\0" - "Ohornbelowdot\0" - "ohornbelowdot\0" - "Ohorngrave\0" - "ohorngrave\0" - "Ohornhook\0" - "ohornhook\0" - "Ohorntilde\0" - "ohorntilde\0" - "Omacron\0" - "omacron\0" - "oneeighth\0" - "onefifth\0" - "onehalf\0" - "onequarter\0" - "onesixth\0" - "onesubscript\0" - "onesuperior\0" - "onethird\0" - "Ooblique\0" - "ooblique\0" - "openrectbullet\0" - "openstar\0" - "opentribulletdown\0" - "opentribulletup\0" - "ordfeminine\0" - "osfActivate\0" - "osfAddMode\0" - "osfBackSpace\0" - "osfBackTab\0" - "osfBeginData\0" - "osfBeginLine\0" - "osfCancel\0" - "osfClear\0" - "osfCopy\0" - "osfCut\0" - "osfDelete\0" - "osfDeselectAll\0" - "osfDown\0" - "osfEndData\0" - "osfEndLine\0" - "osfEscape\0" - "osfExtend\0" - "osfHelp\0" - "osfInsert\0" - "osfLeft\0" - "osfMenu\0" - "osfMenuBar\0" - "osfNextField\0" - "osfNextMenu\0" - "osfPageDown\0" - "osfPageLeft\0" - "osfPageRight\0" - "osfPageUp\0" - "osfPaste\0" - "osfPrevField\0" - "osfPrevMenu\0" - "osfPrimaryPaste\0" - "osfQuickPaste\0" - "osfReselect\0" - "osfRestore\0" - "osfRight\0" - "osfSelect\0" - "osfSelectAll\0" - "osfUndo\0" - "osfUp\0" - "Oslash\0" - "oslash\0" - "Otilde\0" - "otilde\0" - "overbar\0" - "Overlay1_Enable\0" - "Overlay2_Enable\0" - "overline\0" - "P\0" - "p\0" - "Pabovedot\0" - "pabovedot\0" - "Page_Down\0" - "Page_Up\0" - "paragraph\0" - "parenleft\0" - "parenright\0" - "partdifferential\0" - "partialderivative\0" - "Pause\0" - "percent\0" - "period\0" - "periodcentered\0" - "permille\0" - "PesetaSign\0" - "phonographcopyright\0" - "plus\0" - "plusminus\0" - "Pointer_Accelerate\0" - "Pointer_Button1\0" - "Pointer_Button2\0" - "Pointer_Button3\0" - "Pointer_Button4\0" - "Pointer_Button5\0" - "Pointer_Button_Dflt\0" - "Pointer_DblClick1\0" - "Pointer_DblClick2\0" - "Pointer_DblClick3\0" - "Pointer_DblClick4\0" - "Pointer_DblClick5\0" - "Pointer_DblClick_Dflt\0" - "Pointer_DfltBtnNext\0" - "Pointer_DfltBtnPrev\0" - "Pointer_Down\0" - "Pointer_DownLeft\0" - "Pointer_DownRight\0" - "Pointer_Drag1\0" - "Pointer_Drag2\0" - "Pointer_Drag3\0" - "Pointer_Drag4\0" - "Pointer_Drag5\0" - "Pointer_Drag_Dflt\0" - "Pointer_EnableKeys\0" - "Pointer_Left\0" - "Pointer_Right\0" - "Pointer_Up\0" - "Pointer_UpLeft\0" - "Pointer_UpRight\0" - "prescription\0" - "Prev_Virtual_Screen\0" - "PreviousCandidate\0" - "Print\0" - "Prior\0" - "prolongedsound\0" - "punctspace\0" - "Q\0" - "q\0" - "quad\0" - "question\0" - "questiondown\0" - "quotedbl\0" - "quoteleft\0" - "quoteright\0" - "R\0" - "r\0" - "R1\0" - "R10\0" - "R11\0" - "R12\0" - "R13\0" - "R14\0" - "R15\0" - "R2\0" - "R3\0" - "R4\0" - "R5\0" - "R6\0" - "R7\0" - "R8\0" - "R9\0" - "Racute\0" - "racute\0" - "radical\0" - "Rcaron\0" - "rcaron\0" - "Rcedilla\0" - "rcedilla\0" - "Redo\0" - "registered\0" - "RepeatKeys_Enable\0" - "Reset\0" - "Return\0" - "Right\0" - "rightanglebracket\0" - "rightarrow\0" - "rightcaret\0" - "rightdoublequotemark\0" - "rightmiddlecurlybrace\0" - "rightmiddlesummation\0" - "rightopentriangle\0" - "rightpointer\0" - "rightshoe\0" - "rightsinglequotemark\0" - "rightt\0" - "righttack\0" - "Romaji\0" - "RupeeSign\0" - "S\0" - "s\0" - "Sabovedot\0" - "sabovedot\0" - "Sacute\0" - "sacute\0" - "Scaron\0" - "scaron\0" - "Scedilla\0" - "scedilla\0" - "SCHWA\0" - "schwa\0" - "Scircumflex\0" - "scircumflex\0" - "script_switch\0" - "Scroll_Lock\0" - "seconds\0" - "section\0" - "Select\0" - "semicolon\0" - "semivoicedsound\0" - "Serbian_dje\0" - "Serbian_DJE\0" - "Serbian_dze\0" - "Serbian_DZE\0" - "Serbian_je\0" - "Serbian_JE\0" - "Serbian_lje\0" - "Serbian_LJE\0" - "Serbian_nje\0" - "Serbian_NJE\0" - "Serbian_tshe\0" - "Serbian_TSHE\0" - "seveneighths\0" - "sevensubscript\0" - "sevensuperior\0" - "Shift_L\0" - "Shift_Lock\0" - "Shift_R\0" - "signaturemark\0" - "signifblank\0" - "similarequal\0" - "SingleCandidate\0" - "singlelowquotemark\0" - "Sinh_a\0" - "Sinh_aa\0" - "Sinh_aa2\0" - "Sinh_ae\0" - "Sinh_ae2\0" - "Sinh_aee\0" - "Sinh_aee2\0" - "Sinh_ai\0" - "Sinh_ai2\0" - "Sinh_al\0" - "Sinh_au\0" - "Sinh_au2\0" - "Sinh_ba\0" - "Sinh_bha\0" - "Sinh_ca\0" - "Sinh_cha\0" - "Sinh_dda\0" - "Sinh_ddha\0" - "Sinh_dha\0" - "Sinh_dhha\0" - "Sinh_e\0" - "Sinh_e2\0" - "Sinh_ee\0" - "Sinh_ee2\0" - "Sinh_fa\0" - "Sinh_ga\0" - "Sinh_gha\0" - "Sinh_h2\0" - "Sinh_ha\0" - "Sinh_i\0" - "Sinh_i2\0" - "Sinh_ii\0" - "Sinh_ii2\0" - "Sinh_ja\0" - "Sinh_jha\0" - "Sinh_jnya\0" - "Sinh_ka\0" - "Sinh_kha\0" - "Sinh_kunddaliya\0" - "Sinh_la\0" - "Sinh_lla\0" - "Sinh_lu\0" - "Sinh_lu2\0" - "Sinh_luu\0" - "Sinh_luu2\0" - "Sinh_ma\0" - "Sinh_mba\0" - "Sinh_na\0" - "Sinh_ndda\0" - "Sinh_ndha\0" - "Sinh_ng\0" - "Sinh_ng2\0" - "Sinh_nga\0" - "Sinh_nja\0" - "Sinh_nna\0" - "Sinh_nya\0" - "Sinh_o\0" - "Sinh_o2\0" - "Sinh_oo\0" - "Sinh_oo2\0" - "Sinh_pa\0" - "Sinh_pha\0" - "Sinh_ra\0" - "Sinh_ri\0" - "Sinh_rii\0" - "Sinh_ru2\0" - "Sinh_ruu2\0" - "Sinh_sa\0" - "Sinh_sha\0" - "Sinh_ssha\0" - "Sinh_tha\0" - "Sinh_thha\0" - "Sinh_tta\0" - "Sinh_ttha\0" - "Sinh_u\0" - "Sinh_u2\0" - "Sinh_uu\0" - "Sinh_uu2\0" - "Sinh_va\0" - "Sinh_ya\0" - "sixsubscript\0" - "sixsuperior\0" - "slash\0" - "SlowKeys_Enable\0" - "soliddiamond\0" - "space\0" - "squareroot\0" - "ssharp\0" - "sterling\0" - "StickyKeys_Enable\0" - "stricteq\0" - "SunAgain\0" - "SunAltGraph\0" - "SunAudioLowerVolume\0" - "SunAudioMute\0" - "SunAudioRaiseVolume\0" - "SunCompose\0" - "SunCopy\0" - "SunCut\0" - "SunF36\0" - "SunF37\0" - "SunFA_Acute\0" - "SunFA_Cedilla\0" - "SunFA_Circum\0" - "SunFA_Diaeresis\0" - "SunFA_Grave\0" - "SunFA_Tilde\0" - "SunFind\0" - "SunFront\0" - "SunOpen\0" - "SunPageDown\0" - "SunPageUp\0" - "SunPaste\0" - "SunPowerSwitch\0" - "SunPowerSwitchShift\0" - "SunPrint_Screen\0" - "SunProps\0" - "SunStop\0" - "SunSys_Req\0" - "SunUndo\0" - "SunVideoDegauss\0" - "SunVideoLowerBrightness\0" - "SunVideoRaiseBrightness\0" - "Super_L\0" - "Super_R\0" - "Sys_Req\0" - "System\0" - "T\0" - "t\0" - "Tab\0" - "Tabovedot\0" - "tabovedot\0" - "Tcaron\0" - "tcaron\0" - "Tcedilla\0" - "tcedilla\0" - "telephone\0" - "telephonerecorder\0" - "Terminate_Server\0" - "Thai_baht\0" - "Thai_bobaimai\0" - "Thai_chochan\0" - "Thai_chochang\0" - "Thai_choching\0" - "Thai_chochoe\0" - "Thai_dochada\0" - "Thai_dodek\0" - "Thai_fofa\0" - "Thai_fofan\0" - "Thai_hohip\0" - "Thai_honokhuk\0" - "Thai_khokhai\0" - "Thai_khokhon\0" - "Thai_khokhuat\0" - "Thai_khokhwai\0" - "Thai_khorakhang\0" - "Thai_kokai\0" - "Thai_lakkhangyao\0" - "Thai_lekchet\0" - "Thai_lekha\0" - "Thai_lekhok\0" - "Thai_lekkao\0" - "Thai_leknung\0" - "Thai_lekpaet\0" - "Thai_leksam\0" - "Thai_leksi\0" - "Thai_leksong\0" - "Thai_leksun\0" - "Thai_lochula\0" - "Thai_loling\0" - "Thai_lu\0" - "Thai_maichattawa\0" - "Thai_maiek\0" - "Thai_maihanakat\0" - "Thai_maihanakat_maitho\0" - "Thai_maitaikhu\0" - "Thai_maitho\0" - "Thai_maitri\0" - "Thai_maiyamok\0" - "Thai_moma\0" - "Thai_ngongu\0" - "Thai_nikhahit\0" - "Thai_nonen\0" - "Thai_nonu\0" - "Thai_oang\0" - "Thai_paiyannoi\0" - "Thai_phinthu\0" - "Thai_phophan\0" - "Thai_phophung\0" - "Thai_phosamphao\0" - "Thai_popla\0" - "Thai_rorua\0" - "Thai_ru\0" - "Thai_saraa\0" - "Thai_saraaa\0" - "Thai_saraae\0" - "Thai_saraaimaimalai\0" - "Thai_saraaimaimuan\0" - "Thai_saraam\0" - "Thai_sarae\0" - "Thai_sarai\0" - "Thai_saraii\0" - "Thai_sarao\0" - "Thai_sarau\0" - "Thai_saraue\0" - "Thai_sarauee\0" - "Thai_sarauu\0" - "Thai_sorusi\0" - "Thai_sosala\0" - "Thai_soso\0" - "Thai_sosua\0" - "Thai_thanthakhat\0" - "Thai_thonangmontho\0" - "Thai_thophuthao\0" - "Thai_thothahan\0" - "Thai_thothan\0" - "Thai_thothong\0" - "Thai_thothung\0" - "Thai_topatak\0" - "Thai_totao\0" - "Thai_wowaen\0" - "Thai_yoyak\0" - "Thai_yoying\0" - "therefore\0" - "thinspace\0" - "THORN\0" - "Thorn\0" - "thorn\0" - "threeeighths\0" - "threefifths\0" - "threequarters\0" - "threesubscript\0" - "threesuperior\0" - "tintegral\0" - "topintegral\0" - "topleftparens\0" - "topleftradical\0" - "topleftsqbracket\0" - "topleftsummation\0" - "toprightparens\0" - "toprightsqbracket\0" - "toprightsummation\0" - "topt\0" - "topvertsummationconnector\0" - "Touroku\0" - "trademark\0" - "trademarkincircle\0" - "Tslash\0" - "tslash\0" - "twofifths\0" - "twosubscript\0" - "twosuperior\0" - "twothirds\0" - "U\0" - "u\0" - "Uacute\0" - "uacute\0" - "Ubelowdot\0" - "ubelowdot\0" - "Ubreve\0" - "ubreve\0" - "Ucircumflex\0" - "ucircumflex\0" - "Udiaeresis\0" - "udiaeresis\0" - "Udoubleacute\0" - "udoubleacute\0" - "Ugrave\0" - "ugrave\0" - "Uhook\0" - "uhook\0" - "Uhorn\0" - "uhorn\0" - "Uhornacute\0" - "uhornacute\0" - "Uhornbelowdot\0" - "uhornbelowdot\0" - "Uhorngrave\0" - "uhorngrave\0" - "Uhornhook\0" - "uhornhook\0" - "Uhorntilde\0" - "uhorntilde\0" - "Ukrainian_ghe_with_upturn\0" - "Ukrainian_GHE_WITH_UPTURN\0" - "Ukrainian_i\0" - "Ukrainian_I\0" - "Ukrainian_ie\0" - "Ukrainian_IE\0" - "Ukrainian_yi\0" - "Ukrainian_YI\0" - "Ukranian_i\0" - "Ukranian_I\0" - "Ukranian_je\0" - "Ukranian_JE\0" - "Ukranian_yi\0" - "Ukranian_YI\0" - "Umacron\0" - "umacron\0" - "underbar\0" - "underscore\0" - "Undo\0" - "union\0" - "Uogonek\0" - "uogonek\0" - "Up\0" - "uparrow\0" - "upcaret\0" - "upleftcorner\0" - "uprightcorner\0" - "upshoe\0" - "upstile\0" - "uptack\0" - "Uring\0" - "uring\0" - "User\0" - "Utilde\0" - "utilde\0" - "V\0" - "v\0" - "variation\0" - "vertbar\0" - "vertconnector\0" - "voicedsound\0" - "VoidSymbol\0" - "vt\0" - "W\0" - "w\0" - "Wacute\0" - "wacute\0" - "Wcircumflex\0" - "wcircumflex\0" - "Wdiaeresis\0" - "wdiaeresis\0" - "Wgrave\0" - "wgrave\0" - "WonSign\0" - "X\0" - "x\0" - "Xabovedot\0" - "xabovedot\0" - "XF86AddFavorite\0" - "XF86ApplicationLeft\0" - "XF86ApplicationRight\0" - "XF86AudioCycleTrack\0" - "XF86AudioForward\0" - "XF86AudioLowerVolume\0" - "XF86AudioMedia\0" - "XF86AudioMicMute\0" - "XF86AudioMute\0" - "XF86AudioNext\0" - "XF86AudioPause\0" - "XF86AudioPlay\0" - "XF86AudioPreset\0" - "XF86AudioPrev\0" - "XF86AudioRaiseVolume\0" - "XF86AudioRandomPlay\0" - "XF86AudioRecord\0" - "XF86AudioRepeat\0" - "XF86AudioRewind\0" - "XF86AudioStop\0" - "XF86Away\0" - "XF86Back\0" - "XF86BackForward\0" - "XF86Battery\0" - "XF86Blue\0" - "XF86Bluetooth\0" - "XF86Book\0" - "XF86BrightnessAdjust\0" - "XF86Calculater\0" - "XF86Calculator\0" - "XF86Calendar\0" - "XF86CD\0" - "XF86Clear\0" - "XF86ClearGrab\0" - "XF86Close\0" - "XF86Community\0" - "XF86ContrastAdjust\0" - "XF86Copy\0" - "XF86Cut\0" - "XF86CycleAngle\0" - "XF86Display\0" - "XF86Documents\0" - "XF86DOS\0" - "XF86Eject\0" - "XF86Excel\0" - "XF86Explorer\0" - "XF86Favorites\0" - "XF86Finance\0" - "XF86Forward\0" - "XF86FrameBack\0" - "XF86FrameForward\0" - "XF86Game\0" - "XF86Go\0" - "XF86Green\0" - "XF86Hibernate\0" - "XF86History\0" - "XF86HomePage\0" - "XF86HotLinks\0" - "XF86iTouch\0" - "XF86KbdBrightnessDown\0" - "XF86KbdBrightnessUp\0" - "XF86KbdLightOnOff\0" - "XF86Keyboard\0" - "XF86Launch0\0" - "XF86Launch1\0" - "XF86Launch2\0" - "XF86Launch3\0" - "XF86Launch4\0" - "XF86Launch5\0" - "XF86Launch6\0" - "XF86Launch7\0" - "XF86Launch8\0" - "XF86Launch9\0" - "XF86LaunchA\0" - "XF86LaunchB\0" - "XF86LaunchC\0" - "XF86LaunchD\0" - "XF86LaunchE\0" - "XF86LaunchF\0" - "XF86LightBulb\0" - "XF86LogGrabInfo\0" - "XF86LogOff\0" - "XF86LogWindowTree\0" - "XF86Mail\0" - "XF86MailForward\0" - "XF86Market\0" - "XF86Meeting\0" - "XF86Memo\0" - "XF86MenuKB\0" - "XF86MenuPB\0" - "XF86Messenger\0" - "XF86ModeLock\0" - "XF86MonBrightnessDown\0" - "XF86MonBrightnessUp\0" - "XF86Music\0" - "XF86MyComputer\0" - "XF86MySites\0" - "XF86New\0" - "XF86News\0" - "XF86Next_VMode\0" - "XF86OfficeHome\0" - "XF86Open\0" - "XF86OpenURL\0" - "XF86Option\0" - "XF86Paste\0" - "XF86Phone\0" - "XF86Pictures\0" - "XF86PowerDown\0" - "XF86PowerOff\0" - "XF86Prev_VMode\0" - "XF86Q\0" - "XF86Red\0" - "XF86Refresh\0" - "XF86Reload\0" - "XF86Reply\0" - "XF86RFKill\0" - "XF86RockerDown\0" - "XF86RockerEnter\0" - "XF86RockerUp\0" - "XF86RotateWindows\0" - "XF86RotationKB\0" - "XF86RotationPB\0" - "XF86Save\0" - "XF86ScreenSaver\0" - "XF86ScrollClick\0" - "XF86ScrollDown\0" - "XF86ScrollUp\0" - "XF86Search\0" - "XF86Select\0" - "XF86Send\0" - "XF86Shop\0" - "XF86Sleep\0" - "XF86Spell\0" - "XF86SplitScreen\0" - "XF86Standby\0" - "XF86Start\0" - "XF86Stop\0" - "XF86Subtitle\0" - "XF86Support\0" - "XF86Suspend\0" - "XF86Switch_VT_1\0" - "XF86Switch_VT_10\0" - "XF86Switch_VT_11\0" - "XF86Switch_VT_12\0" - "XF86Switch_VT_2\0" - "XF86Switch_VT_3\0" - "XF86Switch_VT_4\0" - "XF86Switch_VT_5\0" - "XF86Switch_VT_6\0" - "XF86Switch_VT_7\0" - "XF86Switch_VT_8\0" - "XF86Switch_VT_9\0" - "XF86TaskPane\0" - "XF86Terminal\0" - "XF86Time\0" - "XF86ToDoList\0" - "XF86Tools\0" - "XF86TopMenu\0" - "XF86TouchpadOff\0" - "XF86TouchpadOn\0" - "XF86TouchpadToggle\0" - "XF86Travel\0" - "XF86Ungrab\0" - "XF86User1KB\0" - "XF86User2KB\0" - "XF86UserPB\0" - "XF86UWB\0" - "XF86VendorHome\0" - "XF86Video\0" - "XF86View\0" - "XF86WakeUp\0" - "XF86WebCam\0" - "XF86WheelButton\0" - "XF86WLAN\0" - "XF86Word\0" - "XF86WWAN\0" - "XF86WWW\0" - "XF86Xfer\0" - "XF86Yellow\0" - "XF86ZoomIn\0" - "XF86ZoomOut\0" - "Y\0" - "y\0" - "Yacute\0" - "yacute\0" - "Ybelowdot\0" - "ybelowdot\0" - "Ycircumflex\0" - "ycircumflex\0" - "ydiaeresis\0" - "Ydiaeresis\0" - "yen\0" - "Ygrave\0" - "ygrave\0" - "Yhook\0" - "yhook\0" - "Ytilde\0" - "ytilde\0" - "Z\0" - "z\0" - "Zabovedot\0" - "zabovedot\0" - "Zacute\0" - "zacute\0" - "Zcaron\0" - "zcaron\0" - "Zen_Koho\0" - "Zenkaku\0" - "Zenkaku_Hankaku\0" - "zerosubscript\0" - "zerosuperior\0" - "Zstroke\0" - "zstroke\0" -; -#pragma GCC diagnostic pop - -struct name_keysym { - xkb_keysym_t keysym; - uint32_t offset; -}; - -static const struct name_keysym name_to_keysym[] = { - { 0x00000030, 0 }, /* 0 */ - { 0x00000031, 2 }, /* 1 */ - { 0x00000032, 4 }, /* 2 */ - { 0x00000033, 6 }, /* 3 */ - { 0x0000fd10, 8 }, /* 3270_AltCursor */ - { 0x0000fd0e, 23 }, /* 3270_Attn */ - { 0x0000fd05, 33 }, /* 3270_BackTab */ - { 0x0000fd19, 46 }, /* 3270_ChangeScreen */ - { 0x0000fd15, 64 }, /* 3270_Copy */ - { 0x0000fd0f, 74 }, /* 3270_CursorBlink */ - { 0x0000fd1c, 91 }, /* 3270_CursorSelect */ - { 0x0000fd1a, 109 }, /* 3270_DeleteWord */ - { 0x0000fd01, 125 }, /* 3270_Duplicate */ - { 0x0000fd1e, 140 }, /* 3270_Enter */ - { 0x0000fd06, 151 }, /* 3270_EraseEOF */ - { 0x0000fd07, 165 }, /* 3270_EraseInput */ - { 0x0000fd1b, 181 }, /* 3270_ExSelect */ - { 0x0000fd02, 195 }, /* 3270_FieldMark */ - { 0x0000fd13, 210 }, /* 3270_Ident */ - { 0x0000fd12, 221 }, /* 3270_Jump */ - { 0x0000fd11, 231 }, /* 3270_KeyClick */ - { 0x0000fd04, 245 }, /* 3270_Left2 */ - { 0x0000fd0a, 256 }, /* 3270_PA1 */ - { 0x0000fd0b, 265 }, /* 3270_PA2 */ - { 0x0000fd0c, 274 }, /* 3270_PA3 */ - { 0x0000fd16, 283 }, /* 3270_Play */ - { 0x0000fd1d, 293 }, /* 3270_PrintScreen */ - { 0x0000fd09, 310 }, /* 3270_Quit */ - { 0x0000fd18, 320 }, /* 3270_Record */ - { 0x0000fd08, 332 }, /* 3270_Reset */ - { 0x0000fd03, 343 }, /* 3270_Right2 */ - { 0x0000fd14, 355 }, /* 3270_Rule */ - { 0x0000fd17, 365 }, /* 3270_Setup */ - { 0x0000fd0d, 376 }, /* 3270_Test */ - { 0x00000034, 386 }, /* 4 */ - { 0x00000035, 388 }, /* 5 */ - { 0x00000036, 390 }, /* 6 */ - { 0x00000037, 392 }, /* 7 */ - { 0x00000038, 394 }, /* 8 */ - { 0x00000039, 396 }, /* 9 */ - { 0x00000041, 398 }, /* A */ - { 0x00000061, 400 }, /* a */ - { 0x000000c1, 402 }, /* Aacute */ - { 0x000000e1, 409 }, /* aacute */ - { 0x01001ea0, 416 }, /* Abelowdot */ - { 0x01001ea1, 426 }, /* abelowdot */ - { 0x000001ff, 436 }, /* abovedot */ - { 0x000001c3, 445 }, /* Abreve */ - { 0x000001e3, 452 }, /* abreve */ - { 0x01001eae, 459 }, /* Abreveacute */ - { 0x01001eaf, 471 }, /* abreveacute */ - { 0x01001eb6, 483 }, /* Abrevebelowdot */ - { 0x01001eb7, 498 }, /* abrevebelowdot */ - { 0x01001eb0, 513 }, /* Abrevegrave */ - { 0x01001eb1, 525 }, /* abrevegrave */ - { 0x01001eb2, 537 }, /* Abrevehook */ - { 0x01001eb3, 548 }, /* abrevehook */ - { 0x01001eb4, 559 }, /* Abrevetilde */ - { 0x01001eb5, 571 }, /* abrevetilde */ - { 0x0000fe70, 583 }, /* AccessX_Enable */ - { 0x0000fe71, 598 }, /* AccessX_Feedback_Enable */ - { 0x000000c2, 622 }, /* Acircumflex */ - { 0x000000e2, 634 }, /* acircumflex */ - { 0x01001ea4, 646 }, /* Acircumflexacute */ - { 0x01001ea5, 663 }, /* acircumflexacute */ - { 0x01001eac, 680 }, /* Acircumflexbelowdot */ - { 0x01001ead, 700 }, /* acircumflexbelowdot */ - { 0x01001ea6, 720 }, /* Acircumflexgrave */ - { 0x01001ea7, 737 }, /* acircumflexgrave */ - { 0x01001ea8, 754 }, /* Acircumflexhook */ - { 0x01001ea9, 770 }, /* acircumflexhook */ - { 0x01001eaa, 786 }, /* Acircumflextilde */ - { 0x01001eab, 803 }, /* acircumflextilde */ - { 0x000000b4, 820 }, /* acute */ - { 0x000000c4, 826 }, /* Adiaeresis */ - { 0x000000e4, 837 }, /* adiaeresis */ - { 0x000000c6, 848 }, /* AE */ - { 0x000000e6, 851 }, /* ae */ - { 0x000000c0, 854 }, /* Agrave */ - { 0x000000e0, 861 }, /* agrave */ - { 0x01001ea2, 868 }, /* Ahook */ - { 0x01001ea3, 874 }, /* ahook */ - { 0x0000ffe9, 880 }, /* Alt_L */ - { 0x0000ffea, 886 }, /* Alt_R */ - { 0x000003c0, 892 }, /* Amacron */ - { 0x000003e0, 900 }, /* amacron */ - { 0x00000026, 908 }, /* ampersand */ - { 0x000001a1, 918 }, /* Aogonek */ - { 0x000001b1, 926 }, /* aogonek */ - { 0x00000027, 934 }, /* apostrophe */ - { 0x01002248, 945 }, /* approxeq */ - { 0x000008c8, 954 }, /* approximate */ - { 0x01000660, 966 }, /* Arabic_0 */ - { 0x01000661, 975 }, /* Arabic_1 */ - { 0x01000662, 984 }, /* Arabic_2 */ - { 0x01000663, 993 }, /* Arabic_3 */ - { 0x01000664, 1002 }, /* Arabic_4 */ - { 0x01000665, 1011 }, /* Arabic_5 */ - { 0x01000666, 1020 }, /* Arabic_6 */ - { 0x01000667, 1029 }, /* Arabic_7 */ - { 0x01000668, 1038 }, /* Arabic_8 */ - { 0x01000669, 1047 }, /* Arabic_9 */ - { 0x000005d9, 1056 }, /* Arabic_ain */ - { 0x000005c7, 1067 }, /* Arabic_alef */ - { 0x000005e9, 1079 }, /* Arabic_alefmaksura */ - { 0x000005c8, 1098 }, /* Arabic_beh */ - { 0x000005ac, 1109 }, /* Arabic_comma */ - { 0x000005d6, 1122 }, /* Arabic_dad */ - { 0x000005cf, 1133 }, /* Arabic_dal */ - { 0x000005ef, 1144 }, /* Arabic_damma */ - { 0x000005ec, 1157 }, /* Arabic_dammatan */ - { 0x01000688, 1173 }, /* Arabic_ddal */ - { 0x010006cc, 1185 }, /* Arabic_farsi_yeh */ - { 0x000005ee, 1202 }, /* Arabic_fatha */ - { 0x000005eb, 1215 }, /* Arabic_fathatan */ - { 0x000005e1, 1231 }, /* Arabic_feh */ - { 0x010006d4, 1242 }, /* Arabic_fullstop */ - { 0x010006af, 1258 }, /* Arabic_gaf */ - { 0x000005da, 1269 }, /* Arabic_ghain */ - { 0x000005e7, 1282 }, /* Arabic_ha */ - { 0x000005cd, 1292 }, /* Arabic_hah */ - { 0x000005c1, 1303 }, /* Arabic_hamza */ - { 0x01000654, 1316 }, /* Arabic_hamza_above */ - { 0x01000655, 1335 }, /* Arabic_hamza_below */ - { 0x000005c3, 1354 }, /* Arabic_hamzaonalef */ - { 0x000005c4, 1373 }, /* Arabic_hamzaonwaw */ - { 0x000005c6, 1391 }, /* Arabic_hamzaonyeh */ - { 0x000005c5, 1409 }, /* Arabic_hamzaunderalef */ - { 0x000005e7, 1431 }, /* Arabic_heh */ - { 0x010006be, 1442 }, /* Arabic_heh_doachashmee */ - { 0x010006c1, 1465 }, /* Arabic_heh_goal */ - { 0x000005cc, 1481 }, /* Arabic_jeem */ - { 0x01000698, 1493 }, /* Arabic_jeh */ - { 0x000005e3, 1504 }, /* Arabic_kaf */ - { 0x000005f0, 1515 }, /* Arabic_kasra */ - { 0x000005ed, 1528 }, /* Arabic_kasratan */ - { 0x010006a9, 1544 }, /* Arabic_keheh */ - { 0x000005ce, 1557 }, /* Arabic_khah */ - { 0x000005e4, 1569 }, /* Arabic_lam */ - { 0x01000653, 1580 }, /* Arabic_madda_above */ - { 0x000005c2, 1599 }, /* Arabic_maddaonalef */ - { 0x000005e5, 1618 }, /* Arabic_meem */ - { 0x000005e6, 1630 }, /* Arabic_noon */ - { 0x010006ba, 1642 }, /* Arabic_noon_ghunna */ - { 0x0100067e, 1661 }, /* Arabic_peh */ - { 0x0100066a, 1672 }, /* Arabic_percent */ - { 0x000005e2, 1687 }, /* Arabic_qaf */ - { 0x000005bf, 1698 }, /* Arabic_question_mark */ - { 0x000005d1, 1719 }, /* Arabic_ra */ - { 0x01000691, 1729 }, /* Arabic_rreh */ - { 0x000005d5, 1741 }, /* Arabic_sad */ - { 0x000005d3, 1752 }, /* Arabic_seen */ - { 0x000005bb, 1764 }, /* Arabic_semicolon */ - { 0x000005f1, 1781 }, /* Arabic_shadda */ - { 0x000005d4, 1795 }, /* Arabic_sheen */ - { 0x000005f2, 1808 }, /* Arabic_sukun */ - { 0x01000670, 1821 }, /* Arabic_superscript_alef */ - { 0x0000ff7e, 1845 }, /* Arabic_switch */ - { 0x000005d7, 1859 }, /* Arabic_tah */ - { 0x000005e0, 1870 }, /* Arabic_tatweel */ - { 0x01000686, 1885 }, /* Arabic_tcheh */ - { 0x000005ca, 1898 }, /* Arabic_teh */ - { 0x000005c9, 1909 }, /* Arabic_tehmarbuta */ - { 0x000005d0, 1927 }, /* Arabic_thal */ - { 0x000005cb, 1939 }, /* Arabic_theh */ - { 0x01000679, 1951 }, /* Arabic_tteh */ - { 0x010006a4, 1963 }, /* Arabic_veh */ - { 0x000005e8, 1974 }, /* Arabic_waw */ - { 0x000005ea, 1985 }, /* Arabic_yeh */ - { 0x010006d2, 1996 }, /* Arabic_yeh_baree */ - { 0x000005d8, 2013 }, /* Arabic_zah */ - { 0x000005d2, 2024 }, /* Arabic_zain */ - { 0x000000c5, 2036 }, /* Aring */ - { 0x000000e5, 2042 }, /* aring */ - { 0x0100055b, 2048 }, /* Armenian_accent */ - { 0x0100055c, 2064 }, /* Armenian_amanak */ - { 0x0100055a, 2080 }, /* Armenian_apostrophe */ - { 0x01000538, 2100 }, /* Armenian_AT */ - { 0x01000568, 2112 }, /* Armenian_at */ - { 0x01000531, 2124 }, /* Armenian_AYB */ - { 0x01000561, 2137 }, /* Armenian_ayb */ - { 0x01000532, 2150 }, /* Armenian_BEN */ - { 0x01000562, 2163 }, /* Armenian_ben */ - { 0x0100055d, 2176 }, /* Armenian_but */ - { 0x01000549, 2189 }, /* Armenian_CHA */ - { 0x01000579, 2202 }, /* Armenian_cha */ - { 0x01000534, 2215 }, /* Armenian_DA */ - { 0x01000564, 2227 }, /* Armenian_da */ - { 0x01000541, 2239 }, /* Armenian_DZA */ - { 0x01000571, 2252 }, /* Armenian_dza */ - { 0x01000537, 2265 }, /* Armenian_E */ - { 0x01000567, 2276 }, /* Armenian_e */ - { 0x0100055c, 2287 }, /* Armenian_exclam */ - { 0x01000556, 2303 }, /* Armenian_FE */ - { 0x01000586, 2315 }, /* Armenian_fe */ - { 0x01000589, 2327 }, /* Armenian_full_stop */ - { 0x01000542, 2346 }, /* Armenian_GHAT */ - { 0x01000572, 2360 }, /* Armenian_ghat */ - { 0x01000533, 2374 }, /* Armenian_GIM */ - { 0x01000563, 2387 }, /* Armenian_gim */ - { 0x01000545, 2400 }, /* Armenian_HI */ - { 0x01000575, 2412 }, /* Armenian_hi */ - { 0x01000540, 2424 }, /* Armenian_HO */ - { 0x01000570, 2436 }, /* Armenian_ho */ - { 0x0100058a, 2448 }, /* Armenian_hyphen */ - { 0x0100053b, 2464 }, /* Armenian_INI */ - { 0x0100056b, 2477 }, /* Armenian_ini */ - { 0x0100054b, 2490 }, /* Armenian_JE */ - { 0x0100057b, 2502 }, /* Armenian_je */ - { 0x01000554, 2514 }, /* Armenian_KE */ - { 0x01000584, 2526 }, /* Armenian_ke */ - { 0x0100053f, 2538 }, /* Armenian_KEN */ - { 0x0100056f, 2551 }, /* Armenian_ken */ - { 0x0100053d, 2564 }, /* Armenian_KHE */ - { 0x0100056d, 2577 }, /* Armenian_khe */ - { 0x01000587, 2590 }, /* Armenian_ligature_ew */ - { 0x0100053c, 2611 }, /* Armenian_LYUN */ - { 0x0100056c, 2625 }, /* Armenian_lyun */ - { 0x01000544, 2639 }, /* Armenian_MEN */ - { 0x01000574, 2652 }, /* Armenian_men */ - { 0x01000546, 2665 }, /* Armenian_NU */ - { 0x01000576, 2677 }, /* Armenian_nu */ - { 0x01000555, 2689 }, /* Armenian_O */ - { 0x01000585, 2700 }, /* Armenian_o */ - { 0x0100055e, 2711 }, /* Armenian_paruyk */ - { 0x0100054a, 2727 }, /* Armenian_PE */ - { 0x0100057a, 2739 }, /* Armenian_pe */ - { 0x01000553, 2751 }, /* Armenian_PYUR */ - { 0x01000583, 2765 }, /* Armenian_pyur */ - { 0x0100055e, 2779 }, /* Armenian_question */ - { 0x0100054c, 2797 }, /* Armenian_RA */ - { 0x0100057c, 2809 }, /* Armenian_ra */ - { 0x01000550, 2821 }, /* Armenian_RE */ - { 0x01000580, 2833 }, /* Armenian_re */ - { 0x0100054d, 2845 }, /* Armenian_SE */ - { 0x0100057d, 2857 }, /* Armenian_se */ - { 0x0100055d, 2869 }, /* Armenian_separation_mark */ - { 0x01000547, 2894 }, /* Armenian_SHA */ - { 0x01000577, 2907 }, /* Armenian_sha */ - { 0x0100055b, 2920 }, /* Armenian_shesht */ - { 0x01000543, 2936 }, /* Armenian_TCHE */ - { 0x01000573, 2950 }, /* Armenian_tche */ - { 0x01000539, 2964 }, /* Armenian_TO */ - { 0x01000569, 2976 }, /* Armenian_to */ - { 0x0100053e, 2988 }, /* Armenian_TSA */ - { 0x0100056e, 3001 }, /* Armenian_tsa */ - { 0x01000551, 3014 }, /* Armenian_TSO */ - { 0x01000581, 3027 }, /* Armenian_tso */ - { 0x0100054f, 3040 }, /* Armenian_TYUN */ - { 0x0100057f, 3054 }, /* Armenian_tyun */ - { 0x01000589, 3068 }, /* Armenian_verjaket */ - { 0x0100054e, 3086 }, /* Armenian_VEV */ - { 0x0100057e, 3099 }, /* Armenian_vev */ - { 0x01000548, 3112 }, /* Armenian_VO */ - { 0x01000578, 3124 }, /* Armenian_vo */ - { 0x01000552, 3136 }, /* Armenian_VYUN */ - { 0x01000582, 3150 }, /* Armenian_vyun */ - { 0x01000535, 3164 }, /* Armenian_YECH */ - { 0x01000565, 3178 }, /* Armenian_yech */ - { 0x0100058a, 3192 }, /* Armenian_yentamna */ - { 0x01000536, 3210 }, /* Armenian_ZA */ - { 0x01000566, 3222 }, /* Armenian_za */ - { 0x0100053a, 3234 }, /* Armenian_ZHE */ - { 0x0100056a, 3247 }, /* Armenian_zhe */ - { 0x0000005e, 3260 }, /* asciicircum */ - { 0x0000007e, 3272 }, /* asciitilde */ - { 0x0000002a, 3283 }, /* asterisk */ - { 0x00000040, 3292 }, /* at */ - { 0x000000c3, 3295 }, /* Atilde */ - { 0x000000e3, 3302 }, /* atilde */ - { 0x0000fe7a, 3309 }, /* AudibleBell_Enable */ - { 0x00000042, 3328 }, /* B */ - { 0x00000062, 3330 }, /* b */ - { 0x01001e02, 3332 }, /* Babovedot */ - { 0x01001e03, 3342 }, /* babovedot */ - { 0x0000005c, 3352 }, /* backslash */ - { 0x0000ff08, 3362 }, /* BackSpace */ - { 0x1000ff74, 3372 }, /* BackTab */ - { 0x00000af4, 3380 }, /* ballotcross */ - { 0x0000007c, 3392 }, /* bar */ - { 0x01002235, 3396 }, /* because */ - { 0x0000ff58, 3404 }, /* Begin */ - { 0x000009df, 3410 }, /* blank */ - { 0x100000fc, 3416 }, /* block */ - { 0x000008a5, 3422 }, /* botintegral */ - { 0x000008ac, 3434 }, /* botleftparens */ - { 0x000008a8, 3448 }, /* botleftsqbracket */ - { 0x000008b2, 3465 }, /* botleftsummation */ - { 0x000008ae, 3482 }, /* botrightparens */ - { 0x000008aa, 3497 }, /* botrightsqbracket */ - { 0x000008b6, 3515 }, /* botrightsummation */ - { 0x000009f6, 3533 }, /* bott */ - { 0x000008b4, 3538 }, /* botvertsummationconnector */ - { 0x0000fe74, 3564 }, /* BounceKeys_Enable */ - { 0x0000007b, 3582 }, /* braceleft */ - { 0x0000007d, 3592 }, /* braceright */ - { 0x0000005b, 3603 }, /* bracketleft */ - { 0x0000005d, 3615 }, /* bracketright */ - { 0x01002800, 3628 }, /* braille_blank */ - { 0x0000fff1, 3642 }, /* braille_dot_1 */ - { 0x0000fffa, 3656 }, /* braille_dot_10 */ - { 0x0000fff2, 3671 }, /* braille_dot_2 */ - { 0x0000fff3, 3685 }, /* braille_dot_3 */ - { 0x0000fff4, 3699 }, /* braille_dot_4 */ - { 0x0000fff5, 3713 }, /* braille_dot_5 */ - { 0x0000fff6, 3727 }, /* braille_dot_6 */ - { 0x0000fff7, 3741 }, /* braille_dot_7 */ - { 0x0000fff8, 3755 }, /* braille_dot_8 */ - { 0x0000fff9, 3769 }, /* braille_dot_9 */ - { 0x01002801, 3783 }, /* braille_dots_1 */ - { 0x01002803, 3798 }, /* braille_dots_12 */ - { 0x01002807, 3814 }, /* braille_dots_123 */ - { 0x0100280f, 3831 }, /* braille_dots_1234 */ - { 0x0100281f, 3849 }, /* braille_dots_12345 */ - { 0x0100283f, 3868 }, /* braille_dots_123456 */ - { 0x0100287f, 3888 }, /* braille_dots_1234567 */ - { 0x010028ff, 3909 }, /* braille_dots_12345678 */ - { 0x010028bf, 3931 }, /* braille_dots_1234568 */ - { 0x0100285f, 3952 }, /* braille_dots_123457 */ - { 0x010028df, 3972 }, /* braille_dots_1234578 */ - { 0x0100289f, 3993 }, /* braille_dots_123458 */ - { 0x0100282f, 4013 }, /* braille_dots_12346 */ - { 0x0100286f, 4032 }, /* braille_dots_123467 */ - { 0x010028ef, 4052 }, /* braille_dots_1234678 */ - { 0x010028af, 4073 }, /* braille_dots_123468 */ - { 0x0100284f, 4093 }, /* braille_dots_12347 */ - { 0x010028cf, 4112 }, /* braille_dots_123478 */ - { 0x0100288f, 4132 }, /* braille_dots_12348 */ - { 0x01002817, 4151 }, /* braille_dots_1235 */ - { 0x01002837, 4169 }, /* braille_dots_12356 */ - { 0x01002877, 4188 }, /* braille_dots_123567 */ - { 0x010028f7, 4208 }, /* braille_dots_1235678 */ - { 0x010028b7, 4229 }, /* braille_dots_123568 */ - { 0x01002857, 4249 }, /* braille_dots_12357 */ - { 0x010028d7, 4268 }, /* braille_dots_123578 */ - { 0x01002897, 4288 }, /* braille_dots_12358 */ - { 0x01002827, 4307 }, /* braille_dots_1236 */ - { 0x01002867, 4325 }, /* braille_dots_12367 */ - { 0x010028e7, 4344 }, /* braille_dots_123678 */ - { 0x010028a7, 4364 }, /* braille_dots_12368 */ - { 0x01002847, 4383 }, /* braille_dots_1237 */ - { 0x010028c7, 4401 }, /* braille_dots_12378 */ - { 0x01002887, 4420 }, /* braille_dots_1238 */ - { 0x0100280b, 4438 }, /* braille_dots_124 */ - { 0x0100281b, 4455 }, /* braille_dots_1245 */ - { 0x0100283b, 4473 }, /* braille_dots_12456 */ - { 0x0100287b, 4492 }, /* braille_dots_124567 */ - { 0x010028fb, 4512 }, /* braille_dots_1245678 */ - { 0x010028bb, 4533 }, /* braille_dots_124568 */ - { 0x0100285b, 4553 }, /* braille_dots_12457 */ - { 0x010028db, 4572 }, /* braille_dots_124578 */ - { 0x0100289b, 4592 }, /* braille_dots_12458 */ - { 0x0100282b, 4611 }, /* braille_dots_1246 */ - { 0x0100286b, 4629 }, /* braille_dots_12467 */ - { 0x010028eb, 4648 }, /* braille_dots_124678 */ - { 0x010028ab, 4668 }, /* braille_dots_12468 */ - { 0x0100284b, 4687 }, /* braille_dots_1247 */ - { 0x010028cb, 4705 }, /* braille_dots_12478 */ - { 0x0100288b, 4724 }, /* braille_dots_1248 */ - { 0x01002813, 4742 }, /* braille_dots_125 */ - { 0x01002833, 4759 }, /* braille_dots_1256 */ - { 0x01002873, 4777 }, /* braille_dots_12567 */ - { 0x010028f3, 4796 }, /* braille_dots_125678 */ - { 0x010028b3, 4816 }, /* braille_dots_12568 */ - { 0x01002853, 4835 }, /* braille_dots_1257 */ - { 0x010028d3, 4853 }, /* braille_dots_12578 */ - { 0x01002893, 4872 }, /* braille_dots_1258 */ - { 0x01002823, 4890 }, /* braille_dots_126 */ - { 0x01002863, 4907 }, /* braille_dots_1267 */ - { 0x010028e3, 4925 }, /* braille_dots_12678 */ - { 0x010028a3, 4944 }, /* braille_dots_1268 */ - { 0x01002843, 4962 }, /* braille_dots_127 */ - { 0x010028c3, 4979 }, /* braille_dots_1278 */ - { 0x01002883, 4997 }, /* braille_dots_128 */ - { 0x01002805, 5014 }, /* braille_dots_13 */ - { 0x0100280d, 5030 }, /* braille_dots_134 */ - { 0x0100281d, 5047 }, /* braille_dots_1345 */ - { 0x0100283d, 5065 }, /* braille_dots_13456 */ - { 0x0100287d, 5084 }, /* braille_dots_134567 */ - { 0x010028fd, 5104 }, /* braille_dots_1345678 */ - { 0x010028bd, 5125 }, /* braille_dots_134568 */ - { 0x0100285d, 5145 }, /* braille_dots_13457 */ - { 0x010028dd, 5164 }, /* braille_dots_134578 */ - { 0x0100289d, 5184 }, /* braille_dots_13458 */ - { 0x0100282d, 5203 }, /* braille_dots_1346 */ - { 0x0100286d, 5221 }, /* braille_dots_13467 */ - { 0x010028ed, 5240 }, /* braille_dots_134678 */ - { 0x010028ad, 5260 }, /* braille_dots_13468 */ - { 0x0100284d, 5279 }, /* braille_dots_1347 */ - { 0x010028cd, 5297 }, /* braille_dots_13478 */ - { 0x0100288d, 5316 }, /* braille_dots_1348 */ - { 0x01002815, 5334 }, /* braille_dots_135 */ - { 0x01002835, 5351 }, /* braille_dots_1356 */ - { 0x01002875, 5369 }, /* braille_dots_13567 */ - { 0x010028f5, 5388 }, /* braille_dots_135678 */ - { 0x010028b5, 5408 }, /* braille_dots_13568 */ - { 0x01002855, 5427 }, /* braille_dots_1357 */ - { 0x010028d5, 5445 }, /* braille_dots_13578 */ - { 0x01002895, 5464 }, /* braille_dots_1358 */ - { 0x01002825, 5482 }, /* braille_dots_136 */ - { 0x01002865, 5499 }, /* braille_dots_1367 */ - { 0x010028e5, 5517 }, /* braille_dots_13678 */ - { 0x010028a5, 5536 }, /* braille_dots_1368 */ - { 0x01002845, 5554 }, /* braille_dots_137 */ - { 0x010028c5, 5571 }, /* braille_dots_1378 */ - { 0x01002885, 5589 }, /* braille_dots_138 */ - { 0x01002809, 5606 }, /* braille_dots_14 */ - { 0x01002819, 5622 }, /* braille_dots_145 */ - { 0x01002839, 5639 }, /* braille_dots_1456 */ - { 0x01002879, 5657 }, /* braille_dots_14567 */ - { 0x010028f9, 5676 }, /* braille_dots_145678 */ - { 0x010028b9, 5696 }, /* braille_dots_14568 */ - { 0x01002859, 5715 }, /* braille_dots_1457 */ - { 0x010028d9, 5733 }, /* braille_dots_14578 */ - { 0x01002899, 5752 }, /* braille_dots_1458 */ - { 0x01002829, 5770 }, /* braille_dots_146 */ - { 0x01002869, 5787 }, /* braille_dots_1467 */ - { 0x010028e9, 5805 }, /* braille_dots_14678 */ - { 0x010028a9, 5824 }, /* braille_dots_1468 */ - { 0x01002849, 5842 }, /* braille_dots_147 */ - { 0x010028c9, 5859 }, /* braille_dots_1478 */ - { 0x01002889, 5877 }, /* braille_dots_148 */ - { 0x01002811, 5894 }, /* braille_dots_15 */ - { 0x01002831, 5910 }, /* braille_dots_156 */ - { 0x01002871, 5927 }, /* braille_dots_1567 */ - { 0x010028f1, 5945 }, /* braille_dots_15678 */ - { 0x010028b1, 5964 }, /* braille_dots_1568 */ - { 0x01002851, 5982 }, /* braille_dots_157 */ - { 0x010028d1, 5999 }, /* braille_dots_1578 */ - { 0x01002891, 6017 }, /* braille_dots_158 */ - { 0x01002821, 6034 }, /* braille_dots_16 */ - { 0x01002861, 6050 }, /* braille_dots_167 */ - { 0x010028e1, 6067 }, /* braille_dots_1678 */ - { 0x010028a1, 6085 }, /* braille_dots_168 */ - { 0x01002841, 6102 }, /* braille_dots_17 */ - { 0x010028c1, 6118 }, /* braille_dots_178 */ - { 0x01002881, 6135 }, /* braille_dots_18 */ - { 0x01002802, 6151 }, /* braille_dots_2 */ - { 0x01002806, 6166 }, /* braille_dots_23 */ - { 0x0100280e, 6182 }, /* braille_dots_234 */ - { 0x0100281e, 6199 }, /* braille_dots_2345 */ - { 0x0100283e, 6217 }, /* braille_dots_23456 */ - { 0x0100287e, 6236 }, /* braille_dots_234567 */ - { 0x010028fe, 6256 }, /* braille_dots_2345678 */ - { 0x010028be, 6277 }, /* braille_dots_234568 */ - { 0x0100285e, 6297 }, /* braille_dots_23457 */ - { 0x010028de, 6316 }, /* braille_dots_234578 */ - { 0x0100289e, 6336 }, /* braille_dots_23458 */ - { 0x0100282e, 6355 }, /* braille_dots_2346 */ - { 0x0100286e, 6373 }, /* braille_dots_23467 */ - { 0x010028ee, 6392 }, /* braille_dots_234678 */ - { 0x010028ae, 6412 }, /* braille_dots_23468 */ - { 0x0100284e, 6431 }, /* braille_dots_2347 */ - { 0x010028ce, 6449 }, /* braille_dots_23478 */ - { 0x0100288e, 6468 }, /* braille_dots_2348 */ - { 0x01002816, 6486 }, /* braille_dots_235 */ - { 0x01002836, 6503 }, /* braille_dots_2356 */ - { 0x01002876, 6521 }, /* braille_dots_23567 */ - { 0x010028f6, 6540 }, /* braille_dots_235678 */ - { 0x010028b6, 6560 }, /* braille_dots_23568 */ - { 0x01002856, 6579 }, /* braille_dots_2357 */ - { 0x010028d6, 6597 }, /* braille_dots_23578 */ - { 0x01002896, 6616 }, /* braille_dots_2358 */ - { 0x01002826, 6634 }, /* braille_dots_236 */ - { 0x01002866, 6651 }, /* braille_dots_2367 */ - { 0x010028e6, 6669 }, /* braille_dots_23678 */ - { 0x010028a6, 6688 }, /* braille_dots_2368 */ - { 0x01002846, 6706 }, /* braille_dots_237 */ - { 0x010028c6, 6723 }, /* braille_dots_2378 */ - { 0x01002886, 6741 }, /* braille_dots_238 */ - { 0x0100280a, 6758 }, /* braille_dots_24 */ - { 0x0100281a, 6774 }, /* braille_dots_245 */ - { 0x0100283a, 6791 }, /* braille_dots_2456 */ - { 0x0100287a, 6809 }, /* braille_dots_24567 */ - { 0x010028fa, 6828 }, /* braille_dots_245678 */ - { 0x010028ba, 6848 }, /* braille_dots_24568 */ - { 0x0100285a, 6867 }, /* braille_dots_2457 */ - { 0x010028da, 6885 }, /* braille_dots_24578 */ - { 0x0100289a, 6904 }, /* braille_dots_2458 */ - { 0x0100282a, 6922 }, /* braille_dots_246 */ - { 0x0100286a, 6939 }, /* braille_dots_2467 */ - { 0x010028ea, 6957 }, /* braille_dots_24678 */ - { 0x010028aa, 6976 }, /* braille_dots_2468 */ - { 0x0100284a, 6994 }, /* braille_dots_247 */ - { 0x010028ca, 7011 }, /* braille_dots_2478 */ - { 0x0100288a, 7029 }, /* braille_dots_248 */ - { 0x01002812, 7046 }, /* braille_dots_25 */ - { 0x01002832, 7062 }, /* braille_dots_256 */ - { 0x01002872, 7079 }, /* braille_dots_2567 */ - { 0x010028f2, 7097 }, /* braille_dots_25678 */ - { 0x010028b2, 7116 }, /* braille_dots_2568 */ - { 0x01002852, 7134 }, /* braille_dots_257 */ - { 0x010028d2, 7151 }, /* braille_dots_2578 */ - { 0x01002892, 7169 }, /* braille_dots_258 */ - { 0x01002822, 7186 }, /* braille_dots_26 */ - { 0x01002862, 7202 }, /* braille_dots_267 */ - { 0x010028e2, 7219 }, /* braille_dots_2678 */ - { 0x010028a2, 7237 }, /* braille_dots_268 */ - { 0x01002842, 7254 }, /* braille_dots_27 */ - { 0x010028c2, 7270 }, /* braille_dots_278 */ - { 0x01002882, 7287 }, /* braille_dots_28 */ - { 0x01002804, 7303 }, /* braille_dots_3 */ - { 0x0100280c, 7318 }, /* braille_dots_34 */ - { 0x0100281c, 7334 }, /* braille_dots_345 */ - { 0x0100283c, 7351 }, /* braille_dots_3456 */ - { 0x0100287c, 7369 }, /* braille_dots_34567 */ - { 0x010028fc, 7388 }, /* braille_dots_345678 */ - { 0x010028bc, 7408 }, /* braille_dots_34568 */ - { 0x0100285c, 7427 }, /* braille_dots_3457 */ - { 0x010028dc, 7445 }, /* braille_dots_34578 */ - { 0x0100289c, 7464 }, /* braille_dots_3458 */ - { 0x0100282c, 7482 }, /* braille_dots_346 */ - { 0x0100286c, 7499 }, /* braille_dots_3467 */ - { 0x010028ec, 7517 }, /* braille_dots_34678 */ - { 0x010028ac, 7536 }, /* braille_dots_3468 */ - { 0x0100284c, 7554 }, /* braille_dots_347 */ - { 0x010028cc, 7571 }, /* braille_dots_3478 */ - { 0x0100288c, 7589 }, /* braille_dots_348 */ - { 0x01002814, 7606 }, /* braille_dots_35 */ - { 0x01002834, 7622 }, /* braille_dots_356 */ - { 0x01002874, 7639 }, /* braille_dots_3567 */ - { 0x010028f4, 7657 }, /* braille_dots_35678 */ - { 0x010028b4, 7676 }, /* braille_dots_3568 */ - { 0x01002854, 7694 }, /* braille_dots_357 */ - { 0x010028d4, 7711 }, /* braille_dots_3578 */ - { 0x01002894, 7729 }, /* braille_dots_358 */ - { 0x01002824, 7746 }, /* braille_dots_36 */ - { 0x01002864, 7762 }, /* braille_dots_367 */ - { 0x010028e4, 7779 }, /* braille_dots_3678 */ - { 0x010028a4, 7797 }, /* braille_dots_368 */ - { 0x01002844, 7814 }, /* braille_dots_37 */ - { 0x010028c4, 7830 }, /* braille_dots_378 */ - { 0x01002884, 7847 }, /* braille_dots_38 */ - { 0x01002808, 7863 }, /* braille_dots_4 */ - { 0x01002818, 7878 }, /* braille_dots_45 */ - { 0x01002838, 7894 }, /* braille_dots_456 */ - { 0x01002878, 7911 }, /* braille_dots_4567 */ - { 0x010028f8, 7929 }, /* braille_dots_45678 */ - { 0x010028b8, 7948 }, /* braille_dots_4568 */ - { 0x01002858, 7966 }, /* braille_dots_457 */ - { 0x010028d8, 7983 }, /* braille_dots_4578 */ - { 0x01002898, 8001 }, /* braille_dots_458 */ - { 0x01002828, 8018 }, /* braille_dots_46 */ - { 0x01002868, 8034 }, /* braille_dots_467 */ - { 0x010028e8, 8051 }, /* braille_dots_4678 */ - { 0x010028a8, 8069 }, /* braille_dots_468 */ - { 0x01002848, 8086 }, /* braille_dots_47 */ - { 0x010028c8, 8102 }, /* braille_dots_478 */ - { 0x01002888, 8119 }, /* braille_dots_48 */ - { 0x01002810, 8135 }, /* braille_dots_5 */ - { 0x01002830, 8150 }, /* braille_dots_56 */ - { 0x01002870, 8166 }, /* braille_dots_567 */ - { 0x010028f0, 8183 }, /* braille_dots_5678 */ - { 0x010028b0, 8201 }, /* braille_dots_568 */ - { 0x01002850, 8218 }, /* braille_dots_57 */ - { 0x010028d0, 8234 }, /* braille_dots_578 */ - { 0x01002890, 8251 }, /* braille_dots_58 */ - { 0x01002820, 8267 }, /* braille_dots_6 */ - { 0x01002860, 8282 }, /* braille_dots_67 */ - { 0x010028e0, 8298 }, /* braille_dots_678 */ - { 0x010028a0, 8315 }, /* braille_dots_68 */ - { 0x01002840, 8331 }, /* braille_dots_7 */ - { 0x010028c0, 8346 }, /* braille_dots_78 */ - { 0x01002880, 8362 }, /* braille_dots_8 */ - { 0x0000ff6b, 8377 }, /* Break */ - { 0x000001a2, 8383 }, /* breve */ - { 0x000000a6, 8389 }, /* brokenbar */ - { 0x000006ae, 8399 }, /* Byelorussian_shortu */ - { 0x000006be, 8419 }, /* Byelorussian_SHORTU */ - { 0x00000043, 8439 }, /* C */ - { 0x00000063, 8441 }, /* c */ - { 0x0000fea3, 8443 }, /* c_h */ - { 0x0000fea4, 8447 }, /* C_h */ - { 0x0000fea5, 8451 }, /* C_H */ - { 0x000002c5, 8455 }, /* Cabovedot */ - { 0x000002e5, 8465 }, /* cabovedot */ - { 0x000001c6, 8475 }, /* Cacute */ - { 0x000001e6, 8482 }, /* cacute */ - { 0x0000ff69, 8489 }, /* Cancel */ - { 0x0000ffe5, 8496 }, /* Caps_Lock */ - { 0x00000ab8, 8506 }, /* careof */ - { 0x00000afc, 8513 }, /* caret */ - { 0x000001b7, 8519 }, /* caron */ - { 0x000001c8, 8525 }, /* Ccaron */ - { 0x000001e8, 8532 }, /* ccaron */ - { 0x000000c7, 8539 }, /* Ccedilla */ - { 0x000000e7, 8548 }, /* ccedilla */ - { 0x000002c6, 8557 }, /* Ccircumflex */ - { 0x000002e6, 8569 }, /* ccircumflex */ - { 0x000000b8, 8581 }, /* cedilla */ - { 0x000000a2, 8589 }, /* cent */ - { 0x0000fea0, 8594 }, /* ch */ - { 0x0000fea1, 8597 }, /* Ch */ - { 0x0000fea2, 8600 }, /* CH */ - { 0x000009e1, 8603 }, /* checkerboard */ - { 0x00000af3, 8616 }, /* checkmark */ - { 0x00000bcf, 8626 }, /* circle */ - { 0x0000ff0b, 8633 }, /* Clear */ - { 0x1000ff6f, 8639 }, /* ClearLine */ - { 0x00000aec, 8649 }, /* club */ - { 0x0000ff37, 8654 }, /* Codeinput */ - { 0x0000003a, 8664 }, /* colon */ - { 0x010020a1, 8670 }, /* ColonSign */ - { 0x0000002c, 8680 }, /* comma */ - { 0x0100220b, 8686 }, /* containsas */ - { 0x0000ffe3, 8697 }, /* Control_L */ - { 0x0000ffe4, 8707 }, /* Control_R */ - { 0x000000a9, 8717 }, /* copyright */ - { 0x000009e4, 8727 }, /* cr */ - { 0x000009ee, 8730 }, /* crossinglines */ - { 0x010020a2, 8744 }, /* CruzeiroSign */ - { 0x0100221b, 8757 }, /* cuberoot */ - { 0x000000a4, 8766 }, /* currency */ - { 0x00000aff, 8775 }, /* cursor */ - { 0x000006c1, 8782 }, /* Cyrillic_a */ - { 0x000006e1, 8793 }, /* Cyrillic_A */ - { 0x000006c2, 8804 }, /* Cyrillic_be */ - { 0x000006e2, 8816 }, /* Cyrillic_BE */ - { 0x000006de, 8828 }, /* Cyrillic_che */ - { 0x000006fe, 8841 }, /* Cyrillic_CHE */ - { 0x010004b6, 8854 }, /* Cyrillic_CHE_descender */ - { 0x010004b7, 8877 }, /* Cyrillic_che_descender */ - { 0x010004b8, 8900 }, /* Cyrillic_CHE_vertstroke */ - { 0x010004b9, 8924 }, /* Cyrillic_che_vertstroke */ - { 0x000006c4, 8948 }, /* Cyrillic_de */ - { 0x000006e4, 8960 }, /* Cyrillic_DE */ - { 0x000006af, 8972 }, /* Cyrillic_dzhe */ - { 0x000006bf, 8986 }, /* Cyrillic_DZHE */ - { 0x000006dc, 9000 }, /* Cyrillic_e */ - { 0x000006fc, 9011 }, /* Cyrillic_E */ - { 0x000006c6, 9022 }, /* Cyrillic_ef */ - { 0x000006e6, 9034 }, /* Cyrillic_EF */ - { 0x000006cc, 9046 }, /* Cyrillic_el */ - { 0x000006ec, 9058 }, /* Cyrillic_EL */ - { 0x000006cd, 9070 }, /* Cyrillic_em */ - { 0x000006ed, 9082 }, /* Cyrillic_EM */ - { 0x000006ce, 9094 }, /* Cyrillic_en */ - { 0x000006ee, 9106 }, /* Cyrillic_EN */ - { 0x010004a2, 9118 }, /* Cyrillic_EN_descender */ - { 0x010004a3, 9140 }, /* Cyrillic_en_descender */ - { 0x000006d2, 9162 }, /* Cyrillic_er */ - { 0x000006f2, 9174 }, /* Cyrillic_ER */ - { 0x000006d3, 9186 }, /* Cyrillic_es */ - { 0x000006f3, 9198 }, /* Cyrillic_ES */ - { 0x000006c7, 9210 }, /* Cyrillic_ghe */ - { 0x000006e7, 9223 }, /* Cyrillic_GHE */ - { 0x01000492, 9236 }, /* Cyrillic_GHE_bar */ - { 0x01000493, 9253 }, /* Cyrillic_ghe_bar */ - { 0x000006c8, 9270 }, /* Cyrillic_ha */ - { 0x000006e8, 9282 }, /* Cyrillic_HA */ - { 0x010004b2, 9294 }, /* Cyrillic_HA_descender */ - { 0x010004b3, 9316 }, /* Cyrillic_ha_descender */ - { 0x000006df, 9338 }, /* Cyrillic_hardsign */ - { 0x000006ff, 9356 }, /* Cyrillic_HARDSIGN */ - { 0x000006c9, 9374 }, /* Cyrillic_i */ - { 0x000006e9, 9385 }, /* Cyrillic_I */ - { 0x010004e2, 9396 }, /* Cyrillic_I_macron */ - { 0x010004e3, 9414 }, /* Cyrillic_i_macron */ - { 0x000006c5, 9432 }, /* Cyrillic_ie */ - { 0x000006e5, 9444 }, /* Cyrillic_IE */ - { 0x000006a3, 9456 }, /* Cyrillic_io */ - { 0x000006b3, 9468 }, /* Cyrillic_IO */ - { 0x000006a8, 9480 }, /* Cyrillic_je */ - { 0x000006b8, 9492 }, /* Cyrillic_JE */ - { 0x000006cb, 9504 }, /* Cyrillic_ka */ - { 0x000006eb, 9516 }, /* Cyrillic_KA */ - { 0x0100049a, 9528 }, /* Cyrillic_KA_descender */ - { 0x0100049b, 9550 }, /* Cyrillic_ka_descender */ - { 0x0100049c, 9572 }, /* Cyrillic_KA_vertstroke */ - { 0x0100049d, 9595 }, /* Cyrillic_ka_vertstroke */ - { 0x000006a9, 9618 }, /* Cyrillic_lje */ - { 0x000006b9, 9631 }, /* Cyrillic_LJE */ - { 0x000006aa, 9644 }, /* Cyrillic_nje */ - { 0x000006ba, 9657 }, /* Cyrillic_NJE */ - { 0x000006cf, 9670 }, /* Cyrillic_o */ - { 0x000006ef, 9681 }, /* Cyrillic_O */ - { 0x010004e8, 9692 }, /* Cyrillic_O_bar */ - { 0x010004e9, 9707 }, /* Cyrillic_o_bar */ - { 0x000006d0, 9722 }, /* Cyrillic_pe */ - { 0x000006f0, 9734 }, /* Cyrillic_PE */ - { 0x010004d8, 9746 }, /* Cyrillic_SCHWA */ - { 0x010004d9, 9761 }, /* Cyrillic_schwa */ - { 0x000006db, 9776 }, /* Cyrillic_sha */ - { 0x000006fb, 9789 }, /* Cyrillic_SHA */ - { 0x000006dd, 9802 }, /* Cyrillic_shcha */ - { 0x000006fd, 9817 }, /* Cyrillic_SHCHA */ - { 0x010004ba, 9832 }, /* Cyrillic_SHHA */ - { 0x010004bb, 9846 }, /* Cyrillic_shha */ - { 0x000006ca, 9860 }, /* Cyrillic_shorti */ - { 0x000006ea, 9876 }, /* Cyrillic_SHORTI */ - { 0x000006d8, 9892 }, /* Cyrillic_softsign */ - { 0x000006f8, 9910 }, /* Cyrillic_SOFTSIGN */ - { 0x000006d4, 9928 }, /* Cyrillic_te */ - { 0x000006f4, 9940 }, /* Cyrillic_TE */ - { 0x000006c3, 9952 }, /* Cyrillic_tse */ - { 0x000006e3, 9965 }, /* Cyrillic_TSE */ - { 0x000006d5, 9978 }, /* Cyrillic_u */ - { 0x000006f5, 9989 }, /* Cyrillic_U */ - { 0x010004ee, 10000 }, /* Cyrillic_U_macron */ - { 0x010004ef, 10018 }, /* Cyrillic_u_macron */ - { 0x010004ae, 10036 }, /* Cyrillic_U_straight */ - { 0x010004af, 10056 }, /* Cyrillic_u_straight */ - { 0x010004b0, 10076 }, /* Cyrillic_U_straight_bar */ - { 0x010004b1, 10100 }, /* Cyrillic_u_straight_bar */ - { 0x000006d7, 10124 }, /* Cyrillic_ve */ - { 0x000006f7, 10136 }, /* Cyrillic_VE */ - { 0x000006d1, 10148 }, /* Cyrillic_ya */ - { 0x000006f1, 10160 }, /* Cyrillic_YA */ - { 0x000006d9, 10172 }, /* Cyrillic_yeru */ - { 0x000006f9, 10186 }, /* Cyrillic_YERU */ - { 0x000006c0, 10200 }, /* Cyrillic_yu */ - { 0x000006e0, 10212 }, /* Cyrillic_YU */ - { 0x000006da, 10224 }, /* Cyrillic_ze */ - { 0x000006fa, 10236 }, /* Cyrillic_ZE */ - { 0x000006d6, 10248 }, /* Cyrillic_zhe */ - { 0x000006f6, 10261 }, /* Cyrillic_ZHE */ - { 0x01000496, 10274 }, /* Cyrillic_ZHE_descender */ - { 0x01000497, 10297 }, /* Cyrillic_zhe_descender */ - { 0x00000044, 10320 }, /* D */ - { 0x00000064, 10322 }, /* d */ - { 0x01001e0a, 10324 }, /* Dabovedot */ - { 0x01001e0b, 10334 }, /* dabovedot */ - { 0x1000fe27, 10344 }, /* Dacute_accent */ - { 0x00000af1, 10358 }, /* dagger */ - { 0x000001cf, 10365 }, /* Dcaron */ - { 0x000001ef, 10372 }, /* dcaron */ - { 0x1000fe2c, 10379 }, /* Dcedilla_accent */ - { 0x1000fe5e, 10395 }, /* Dcircumflex_accent */ - { 0x1000fe22, 10414 }, /* Ddiaeresis */ - { 0x0000fe80, 10425 }, /* dead_a */ - { 0x0000fe81, 10432 }, /* dead_A */ - { 0x0000fe64, 10439 }, /* dead_abovecomma */ - { 0x0000fe56, 10455 }, /* dead_abovedot */ - { 0x0000fe65, 10469 }, /* dead_abovereversedcomma */ - { 0x0000fe58, 10493 }, /* dead_abovering */ - { 0x0000fe91, 10508 }, /* dead_aboveverticalline */ - { 0x0000fe51, 10531 }, /* dead_acute */ - { 0x0000fe6b, 10542 }, /* dead_belowbreve */ - { 0x0000fe69, 10558 }, /* dead_belowcircumflex */ - { 0x0000fe6e, 10579 }, /* dead_belowcomma */ - { 0x0000fe6c, 10595 }, /* dead_belowdiaeresis */ - { 0x0000fe60, 10615 }, /* dead_belowdot */ - { 0x0000fe68, 10629 }, /* dead_belowmacron */ - { 0x0000fe67, 10646 }, /* dead_belowring */ - { 0x0000fe6a, 10661 }, /* dead_belowtilde */ - { 0x0000fe92, 10677 }, /* dead_belowverticalline */ - { 0x0000fe55, 10700 }, /* dead_breve */ - { 0x0000fe8b, 10711 }, /* dead_capital_schwa */ - { 0x0000fe5a, 10730 }, /* dead_caron */ - { 0x0000fe5b, 10741 }, /* dead_cedilla */ - { 0x0000fe52, 10754 }, /* dead_circumflex */ - { 0x0000fe6f, 10770 }, /* dead_currency */ - { 0x0000fe65, 10784 }, /* dead_dasia */ - { 0x0000fe57, 10795 }, /* dead_diaeresis */ - { 0x0000fe59, 10810 }, /* dead_doubleacute */ - { 0x0000fe66, 10827 }, /* dead_doublegrave */ - { 0x0000fe82, 10844 }, /* dead_e */ - { 0x0000fe83, 10851 }, /* dead_E */ - { 0x0000fe50, 10858 }, /* dead_grave */ - { 0x0000fe8c, 10869 }, /* dead_greek */ - { 0x0000fe61, 10880 }, /* dead_hook */ - { 0x0000fe62, 10890 }, /* dead_horn */ - { 0x0000fe84, 10900 }, /* dead_i */ - { 0x0000fe85, 10907 }, /* dead_I */ - { 0x0000fe6d, 10914 }, /* dead_invertedbreve */ - { 0x0000fe5d, 10933 }, /* dead_iota */ - { 0x0000fe93, 10943 }, /* dead_longsolidusoverlay */ - { 0x0000fe90, 10967 }, /* dead_lowline */ - { 0x0000fe54, 10980 }, /* dead_macron */ - { 0x0000fe86, 10992 }, /* dead_o */ - { 0x0000fe87, 10999 }, /* dead_O */ - { 0x0000fe5c, 11006 }, /* dead_ogonek */ - { 0x0000fe53, 11018 }, /* dead_perispomeni */ - { 0x0000fe64, 11035 }, /* dead_psili */ - { 0x0000fe5f, 11046 }, /* dead_semivoiced_sound */ - { 0x0000fe8a, 11068 }, /* dead_small_schwa */ - { 0x0000fe63, 11085 }, /* dead_stroke */ - { 0x0000fe53, 11097 }, /* dead_tilde */ - { 0x0000fe88, 11108 }, /* dead_u */ - { 0x0000fe89, 11115 }, /* dead_U */ - { 0x0000fe5e, 11122 }, /* dead_voiced_sound */ - { 0x00000abd, 11140 }, /* decimalpoint */ - { 0x000000b0, 11153 }, /* degree */ - { 0x0000ffff, 11160 }, /* Delete */ - { 0x1000ff73, 11167 }, /* DeleteChar */ - { 0x1000ff71, 11178 }, /* DeleteLine */ - { 0x1000fe60, 11189 }, /* Dgrave_accent */ - { 0x000000a8, 11203 }, /* diaeresis */ - { 0x00000aed, 11213 }, /* diamond */ - { 0x00000aa5, 11221 }, /* digitspace */ - { 0x0100222c, 11232 }, /* dintegral */ - { 0x000000f7, 11242 }, /* division */ - { 0x00000024, 11251 }, /* dollar */ - { 0x010020ab, 11258 }, /* DongSign */ - { 0x00000aaf, 11267 }, /* doubbaselinedot */ - { 0x000001bd, 11283 }, /* doubleacute */ - { 0x00000af2, 11295 }, /* doubledagger */ - { 0x00000afe, 11308 }, /* doublelowquotemark */ - { 0x0000ff54, 11327 }, /* Down */ - { 0x000008fe, 11332 }, /* downarrow */ - { 0x00000ba8, 11342 }, /* downcaret */ - { 0x00000bd6, 11352 }, /* downshoe */ - { 0x00000bc4, 11361 }, /* downstile */ - { 0x00000bc2, 11371 }, /* downtack */ - { 0x1000ff00, 11380 }, /* DRemove */ - { 0x1000feb0, 11388 }, /* Dring_accent */ - { 0x000001d0, 11401 }, /* Dstroke */ - { 0x000001f0, 11409 }, /* dstroke */ - { 0x1000fe7e, 11417 }, /* Dtilde */ - { 0x00000045, 11424 }, /* E */ - { 0x00000065, 11426 }, /* e */ - { 0x000003cc, 11428 }, /* Eabovedot */ - { 0x000003ec, 11438 }, /* eabovedot */ - { 0x000000c9, 11448 }, /* Eacute */ - { 0x000000e9, 11455 }, /* eacute */ - { 0x01001eb8, 11462 }, /* Ebelowdot */ - { 0x01001eb9, 11472 }, /* ebelowdot */ - { 0x000001cc, 11482 }, /* Ecaron */ - { 0x000001ec, 11489 }, /* ecaron */ - { 0x000000ca, 11496 }, /* Ecircumflex */ - { 0x000000ea, 11508 }, /* ecircumflex */ - { 0x01001ebe, 11520 }, /* Ecircumflexacute */ - { 0x01001ebf, 11537 }, /* ecircumflexacute */ - { 0x01001ec6, 11554 }, /* Ecircumflexbelowdot */ - { 0x01001ec7, 11574 }, /* ecircumflexbelowdot */ - { 0x01001ec0, 11594 }, /* Ecircumflexgrave */ - { 0x01001ec1, 11611 }, /* ecircumflexgrave */ - { 0x01001ec2, 11628 }, /* Ecircumflexhook */ - { 0x01001ec3, 11644 }, /* ecircumflexhook */ - { 0x01001ec4, 11660 }, /* Ecircumflextilde */ - { 0x01001ec5, 11677 }, /* ecircumflextilde */ - { 0x010020a0, 11694 }, /* EcuSign */ - { 0x000000cb, 11702 }, /* Ediaeresis */ - { 0x000000eb, 11713 }, /* ediaeresis */ - { 0x000000c8, 11724 }, /* Egrave */ - { 0x000000e8, 11731 }, /* egrave */ - { 0x01001eba, 11738 }, /* Ehook */ - { 0x01001ebb, 11744 }, /* ehook */ - { 0x01002088, 11750 }, /* eightsubscript */ - { 0x01002078, 11765 }, /* eightsuperior */ - { 0x0000ff2f, 11779 }, /* Eisu_Shift */ - { 0x0000ff30, 11790 }, /* Eisu_toggle */ - { 0x01002208, 11802 }, /* elementof */ - { 0x00000aae, 11812 }, /* ellipsis */ - { 0x00000aa3, 11821 }, /* em3space */ - { 0x00000aa4, 11830 }, /* em4space */ - { 0x000003aa, 11839 }, /* Emacron */ - { 0x000003ba, 11847 }, /* emacron */ - { 0x00000aa9, 11855 }, /* emdash */ - { 0x00000ade, 11862 }, /* emfilledcircle */ - { 0x00000adf, 11877 }, /* emfilledrect */ - { 0x00000ace, 11890 }, /* emopencircle */ - { 0x00000acf, 11903 }, /* emopenrectangle */ - { 0x01002205, 11919 }, /* emptyset */ - { 0x00000aa1, 11928 }, /* emspace */ - { 0x0000ff57, 11936 }, /* End */ - { 0x00000aaa, 11940 }, /* endash */ - { 0x00000ae6, 11947 }, /* enfilledcircbullet */ - { 0x00000ae7, 11966 }, /* enfilledsqbullet */ - { 0x000003bd, 11983 }, /* ENG */ - { 0x000003bf, 11987 }, /* eng */ - { 0x00000ae0, 11991 }, /* enopencircbullet */ - { 0x00000ae1, 12008 }, /* enopensquarebullet */ - { 0x00000aa2, 12027 }, /* enspace */ - { 0x000001ca, 12035 }, /* Eogonek */ - { 0x000001ea, 12043 }, /* eogonek */ - { 0x0000003d, 12051 }, /* equal */ - { 0x0000ff1b, 12057 }, /* Escape */ - { 0x000000d0, 12064 }, /* ETH */ - { 0x000000d0, 12068 }, /* Eth */ - { 0x000000f0, 12072 }, /* eth */ - { 0x01001ebc, 12076 }, /* Etilde */ - { 0x01001ebd, 12083 }, /* etilde */ - { 0x000020ac, 12090 }, /* EuroSign */ - { 0x00000021, 12099 }, /* exclam */ - { 0x000000a1, 12106 }, /* exclamdown */ - { 0x0000ff62, 12117 }, /* Execute */ - { 0x1000ff76, 12125 }, /* Ext16bit_L */ - { 0x1000ff77, 12136 }, /* Ext16bit_R */ - { 0x010001b7, 12147 }, /* EZH */ - { 0x01000292, 12151 }, /* ezh */ - { 0x00000046, 12155 }, /* F */ - { 0x00000066, 12157 }, /* f */ - { 0x0000ffbe, 12159 }, /* F1 */ - { 0x0000ffc7, 12162 }, /* F10 */ - { 0x0000ffc8, 12166 }, /* F11 */ - { 0x0000ffc9, 12170 }, /* F12 */ - { 0x0000ffca, 12174 }, /* F13 */ - { 0x0000ffcb, 12178 }, /* F14 */ - { 0x0000ffcc, 12182 }, /* F15 */ - { 0x0000ffcd, 12186 }, /* F16 */ - { 0x0000ffce, 12190 }, /* F17 */ - { 0x0000ffcf, 12194 }, /* F18 */ - { 0x0000ffd0, 12198 }, /* F19 */ - { 0x0000ffbf, 12202 }, /* F2 */ - { 0x0000ffd1, 12205 }, /* F20 */ - { 0x0000ffd2, 12209 }, /* F21 */ - { 0x0000ffd3, 12213 }, /* F22 */ - { 0x0000ffd4, 12217 }, /* F23 */ - { 0x0000ffd5, 12221 }, /* F24 */ - { 0x0000ffd6, 12225 }, /* F25 */ - { 0x0000ffd7, 12229 }, /* F26 */ - { 0x0000ffd8, 12233 }, /* F27 */ - { 0x0000ffd9, 12237 }, /* F28 */ - { 0x0000ffda, 12241 }, /* F29 */ - { 0x0000ffc0, 12245 }, /* F3 */ - { 0x0000ffdb, 12248 }, /* F30 */ - { 0x0000ffdc, 12252 }, /* F31 */ - { 0x0000ffdd, 12256 }, /* F32 */ - { 0x0000ffde, 12260 }, /* F33 */ - { 0x0000ffdf, 12264 }, /* F34 */ - { 0x0000ffe0, 12268 }, /* F35 */ - { 0x0000ffc1, 12272 }, /* F4 */ - { 0x0000ffc2, 12275 }, /* F5 */ - { 0x0000ffc3, 12278 }, /* F6 */ - { 0x0000ffc4, 12281 }, /* F7 */ - { 0x0000ffc5, 12284 }, /* F8 */ - { 0x0000ffc6, 12287 }, /* F9 */ - { 0x01001e1e, 12290 }, /* Fabovedot */ - { 0x01001e1f, 12300 }, /* fabovedot */ - { 0x010006f0, 12310 }, /* Farsi_0 */ - { 0x010006f1, 12318 }, /* Farsi_1 */ - { 0x010006f2, 12326 }, /* Farsi_2 */ - { 0x010006f3, 12334 }, /* Farsi_3 */ - { 0x010006f4, 12342 }, /* Farsi_4 */ - { 0x010006f5, 12350 }, /* Farsi_5 */ - { 0x010006f6, 12358 }, /* Farsi_6 */ - { 0x010006f7, 12366 }, /* Farsi_7 */ - { 0x010006f8, 12374 }, /* Farsi_8 */ - { 0x010006f9, 12382 }, /* Farsi_9 */ - { 0x010006cc, 12390 }, /* Farsi_yeh */ - { 0x00000af8, 12400 }, /* femalesymbol */ - { 0x000009e3, 12413 }, /* ff */ - { 0x010020a3, 12416 }, /* FFrancSign */ - { 0x00000abb, 12427 }, /* figdash */ - { 0x00000adc, 12435 }, /* filledlefttribullet */ - { 0x00000adb, 12455 }, /* filledrectbullet */ - { 0x00000add, 12472 }, /* filledrighttribullet */ - { 0x00000ae9, 12493 }, /* filledtribulletdown */ - { 0x00000ae8, 12513 }, /* filledtribulletup */ - { 0x0000ff68, 12531 }, /* Find */ - { 0x0000fed0, 12536 }, /* First_Virtual_Screen */ - { 0x00000ac5, 12557 }, /* fiveeighths */ - { 0x00000ab7, 12569 }, /* fivesixths */ - { 0x01002085, 12580 }, /* fivesubscript */ - { 0x01002075, 12594 }, /* fivesuperior */ - { 0x00000ab5, 12607 }, /* fourfifths */ - { 0x01002084, 12618 }, /* foursubscript */ - { 0x01002074, 12632 }, /* foursuperior */ - { 0x0100221c, 12645 }, /* fourthroot */ - { 0x000008f6, 12656 }, /* function */ - { 0x00000047, 12665 }, /* G */ - { 0x00000067, 12667 }, /* g */ - { 0x000002d5, 12669 }, /* Gabovedot */ - { 0x000002f5, 12679 }, /* gabovedot */ - { 0x000002ab, 12689 }, /* Gbreve */ - { 0x000002bb, 12696 }, /* gbreve */ - { 0x010001e6, 12703 }, /* Gcaron */ - { 0x010001e7, 12710 }, /* gcaron */ - { 0x000003ab, 12717 }, /* Gcedilla */ - { 0x000003bb, 12726 }, /* gcedilla */ - { 0x000002d8, 12735 }, /* Gcircumflex */ - { 0x000002f8, 12747 }, /* gcircumflex */ - { 0x010010d0, 12759 }, /* Georgian_an */ - { 0x010010d1, 12771 }, /* Georgian_ban */ - { 0x010010ea, 12784 }, /* Georgian_can */ - { 0x010010ed, 12797 }, /* Georgian_char */ - { 0x010010e9, 12811 }, /* Georgian_chin */ - { 0x010010ec, 12825 }, /* Georgian_cil */ - { 0x010010d3, 12838 }, /* Georgian_don */ - { 0x010010d4, 12851 }, /* Georgian_en */ - { 0x010010f6, 12863 }, /* Georgian_fi */ - { 0x010010d2, 12875 }, /* Georgian_gan */ - { 0x010010e6, 12888 }, /* Georgian_ghan */ - { 0x010010f0, 12902 }, /* Georgian_hae */ - { 0x010010f4, 12915 }, /* Georgian_har */ - { 0x010010f1, 12928 }, /* Georgian_he */ - { 0x010010f2, 12940 }, /* Georgian_hie */ - { 0x010010f5, 12953 }, /* Georgian_hoe */ - { 0x010010d8, 12966 }, /* Georgian_in */ - { 0x010010ef, 12978 }, /* Georgian_jhan */ - { 0x010010eb, 12992 }, /* Georgian_jil */ - { 0x010010d9, 13005 }, /* Georgian_kan */ - { 0x010010e5, 13018 }, /* Georgian_khar */ - { 0x010010da, 13032 }, /* Georgian_las */ - { 0x010010db, 13045 }, /* Georgian_man */ - { 0x010010dc, 13058 }, /* Georgian_nar */ - { 0x010010dd, 13071 }, /* Georgian_on */ - { 0x010010de, 13083 }, /* Georgian_par */ - { 0x010010e4, 13096 }, /* Georgian_phar */ - { 0x010010e7, 13110 }, /* Georgian_qar */ - { 0x010010e0, 13123 }, /* Georgian_rae */ - { 0x010010e1, 13136 }, /* Georgian_san */ - { 0x010010e8, 13149 }, /* Georgian_shin */ - { 0x010010d7, 13163 }, /* Georgian_tan */ - { 0x010010e2, 13176 }, /* Georgian_tar */ - { 0x010010e3, 13189 }, /* Georgian_un */ - { 0x010010d5, 13201 }, /* Georgian_vin */ - { 0x010010f3, 13214 }, /* Georgian_we */ - { 0x010010ee, 13226 }, /* Georgian_xan */ - { 0x010010d6, 13239 }, /* Georgian_zen */ - { 0x010010df, 13252 }, /* Georgian_zhar */ - { 0x00000060, 13266 }, /* grave */ - { 0x0000003e, 13272 }, /* greater */ - { 0x000008be, 13280 }, /* greaterthanequal */ - { 0x000007ae, 13297 }, /* Greek_accentdieresis */ - { 0x000007c1, 13318 }, /* Greek_ALPHA */ - { 0x000007e1, 13330 }, /* Greek_alpha */ - { 0x000007a1, 13342 }, /* Greek_ALPHAaccent */ - { 0x000007b1, 13360 }, /* Greek_alphaaccent */ - { 0x000007c2, 13378 }, /* Greek_BETA */ - { 0x000007e2, 13389 }, /* Greek_beta */ - { 0x000007d7, 13400 }, /* Greek_CHI */ - { 0x000007f7, 13410 }, /* Greek_chi */ - { 0x000007c4, 13420 }, /* Greek_DELTA */ - { 0x000007e4, 13432 }, /* Greek_delta */ - { 0x000007c5, 13444 }, /* Greek_EPSILON */ - { 0x000007e5, 13458 }, /* Greek_epsilon */ - { 0x000007a2, 13472 }, /* Greek_EPSILONaccent */ - { 0x000007b2, 13492 }, /* Greek_epsilonaccent */ - { 0x000007c7, 13512 }, /* Greek_ETA */ - { 0x000007e7, 13522 }, /* Greek_eta */ - { 0x000007a3, 13532 }, /* Greek_ETAaccent */ - { 0x000007b3, 13548 }, /* Greek_etaaccent */ - { 0x000007f3, 13564 }, /* Greek_finalsmallsigma */ - { 0x000007c3, 13586 }, /* Greek_GAMMA */ - { 0x000007e3, 13598 }, /* Greek_gamma */ - { 0x000007af, 13610 }, /* Greek_horizbar */ - { 0x000007c9, 13625 }, /* Greek_IOTA */ - { 0x000007e9, 13636 }, /* Greek_iota */ - { 0x000007a4, 13647 }, /* Greek_IOTAaccent */ - { 0x000007b4, 13664 }, /* Greek_iotaaccent */ - { 0x000007b6, 13681 }, /* Greek_iotaaccentdieresis */ - { 0x000007a5, 13706 }, /* Greek_IOTAdiaeresis */ - { 0x000007a5, 13726 }, /* Greek_IOTAdieresis */ - { 0x000007b5, 13745 }, /* Greek_iotadieresis */ - { 0x000007ca, 13764 }, /* Greek_KAPPA */ - { 0x000007ea, 13776 }, /* Greek_kappa */ - { 0x000007cb, 13788 }, /* Greek_LAMBDA */ - { 0x000007eb, 13801 }, /* Greek_lambda */ - { 0x000007cb, 13814 }, /* Greek_LAMDA */ - { 0x000007eb, 13826 }, /* Greek_lamda */ - { 0x000007cc, 13838 }, /* Greek_MU */ - { 0x000007ec, 13847 }, /* Greek_mu */ - { 0x000007cd, 13856 }, /* Greek_NU */ - { 0x000007ed, 13865 }, /* Greek_nu */ - { 0x000007d9, 13874 }, /* Greek_OMEGA */ - { 0x000007f9, 13886 }, /* Greek_omega */ - { 0x000007ab, 13898 }, /* Greek_OMEGAaccent */ - { 0x000007bb, 13916 }, /* Greek_omegaaccent */ - { 0x000007cf, 13934 }, /* Greek_OMICRON */ - { 0x000007ef, 13948 }, /* Greek_omicron */ - { 0x000007a7, 13962 }, /* Greek_OMICRONaccent */ - { 0x000007b7, 13982 }, /* Greek_omicronaccent */ - { 0x000007d6, 14002 }, /* Greek_PHI */ - { 0x000007f6, 14012 }, /* Greek_phi */ - { 0x000007d0, 14022 }, /* Greek_PI */ - { 0x000007f0, 14031 }, /* Greek_pi */ - { 0x000007d8, 14040 }, /* Greek_PSI */ - { 0x000007f8, 14050 }, /* Greek_psi */ - { 0x000007d1, 14060 }, /* Greek_RHO */ - { 0x000007f1, 14070 }, /* Greek_rho */ - { 0x000007d2, 14080 }, /* Greek_SIGMA */ - { 0x000007f2, 14092 }, /* Greek_sigma */ - { 0x0000ff7e, 14104 }, /* Greek_switch */ - { 0x000007d4, 14117 }, /* Greek_TAU */ - { 0x000007f4, 14127 }, /* Greek_tau */ - { 0x000007c8, 14137 }, /* Greek_THETA */ - { 0x000007e8, 14149 }, /* Greek_theta */ - { 0x000007d5, 14161 }, /* Greek_UPSILON */ - { 0x000007f5, 14175 }, /* Greek_upsilon */ - { 0x000007a8, 14189 }, /* Greek_UPSILONaccent */ - { 0x000007b8, 14209 }, /* Greek_upsilonaccent */ - { 0x000007ba, 14229 }, /* Greek_upsilonaccentdieresis */ - { 0x000007a9, 14257 }, /* Greek_UPSILONdieresis */ - { 0x000007b9, 14279 }, /* Greek_upsilondieresis */ - { 0x000007ce, 14301 }, /* Greek_XI */ - { 0x000007ee, 14310 }, /* Greek_xi */ - { 0x000007c6, 14319 }, /* Greek_ZETA */ - { 0x000007e6, 14330 }, /* Greek_zeta */ - { 0x100000be, 14341 }, /* guilder */ - { 0x000000ab, 14349 }, /* guillemotleft */ - { 0x000000bb, 14363 }, /* guillemotright */ - { 0x00000048, 14378 }, /* H */ - { 0x00000068, 14380 }, /* h */ - { 0x00000aa8, 14382 }, /* hairspace */ - { 0x0000ff31, 14392 }, /* Hangul */ - { 0x00000ebf, 14399 }, /* Hangul_A */ - { 0x00000ec0, 14408 }, /* Hangul_AE */ - { 0x00000ef6, 14418 }, /* Hangul_AraeA */ - { 0x00000ef7, 14431 }, /* Hangul_AraeAE */ - { 0x0000ff39, 14445 }, /* Hangul_Banja */ - { 0x00000eba, 14458 }, /* Hangul_Cieuc */ - { 0x0000ff37, 14471 }, /* Hangul_Codeinput */ - { 0x00000ea7, 14488 }, /* Hangul_Dikeud */ - { 0x00000ec4, 14502 }, /* Hangul_E */ - { 0x0000ff33, 14511 }, /* Hangul_End */ - { 0x00000ec3, 14522 }, /* Hangul_EO */ - { 0x00000ed1, 14532 }, /* Hangul_EU */ - { 0x0000ff34, 14542 }, /* Hangul_Hanja */ - { 0x00000ebe, 14555 }, /* Hangul_Hieuh */ - { 0x00000ed3, 14568 }, /* Hangul_I */ - { 0x00000eb7, 14577 }, /* Hangul_Ieung */ - { 0x00000eea, 14590 }, /* Hangul_J_Cieuc */ - { 0x00000eda, 14605 }, /* Hangul_J_Dikeud */ - { 0x00000eee, 14621 }, /* Hangul_J_Hieuh */ - { 0x00000ee8, 14636 }, /* Hangul_J_Ieung */ - { 0x00000ee9, 14651 }, /* Hangul_J_Jieuj */ - { 0x00000eeb, 14666 }, /* Hangul_J_Khieuq */ - { 0x00000ed4, 14682 }, /* Hangul_J_Kiyeog */ - { 0x00000ed6, 14698 }, /* Hangul_J_KiyeogSios */ - { 0x00000ef9, 14718 }, /* Hangul_J_KkogjiDalrinIeung */ - { 0x00000ee3, 14745 }, /* Hangul_J_Mieum */ - { 0x00000ed7, 14760 }, /* Hangul_J_Nieun */ - { 0x00000ed9, 14775 }, /* Hangul_J_NieunHieuh */ - { 0x00000ed8, 14795 }, /* Hangul_J_NieunJieuj */ - { 0x00000ef8, 14815 }, /* Hangul_J_PanSios */ - { 0x00000eed, 14832 }, /* Hangul_J_Phieuf */ - { 0x00000ee4, 14848 }, /* Hangul_J_Pieub */ - { 0x00000ee5, 14863 }, /* Hangul_J_PieubSios */ - { 0x00000edb, 14882 }, /* Hangul_J_Rieul */ - { 0x00000ee2, 14897 }, /* Hangul_J_RieulHieuh */ - { 0x00000edc, 14917 }, /* Hangul_J_RieulKiyeog */ - { 0x00000edd, 14938 }, /* Hangul_J_RieulMieum */ - { 0x00000ee1, 14958 }, /* Hangul_J_RieulPhieuf */ - { 0x00000ede, 14979 }, /* Hangul_J_RieulPieub */ - { 0x00000edf, 14999 }, /* Hangul_J_RieulSios */ - { 0x00000ee0, 15018 }, /* Hangul_J_RieulTieut */ - { 0x00000ee6, 15038 }, /* Hangul_J_Sios */ - { 0x00000ed5, 15052 }, /* Hangul_J_SsangKiyeog */ - { 0x00000ee7, 15073 }, /* Hangul_J_SsangSios */ - { 0x00000eec, 15092 }, /* Hangul_J_Tieut */ - { 0x00000efa, 15107 }, /* Hangul_J_YeorinHieuh */ - { 0x0000ff35, 15128 }, /* Hangul_Jamo */ - { 0x0000ff38, 15140 }, /* Hangul_Jeonja */ - { 0x00000eb8, 15154 }, /* Hangul_Jieuj */ - { 0x00000ebb, 15167 }, /* Hangul_Khieuq */ - { 0x00000ea1, 15181 }, /* Hangul_Kiyeog */ - { 0x00000ea3, 15195 }, /* Hangul_KiyeogSios */ - { 0x00000ef3, 15213 }, /* Hangul_KkogjiDalrinIeung */ - { 0x00000eb1, 15238 }, /* Hangul_Mieum */ - { 0x0000ff3d, 15251 }, /* Hangul_MultipleCandidate */ - { 0x00000ea4, 15276 }, /* Hangul_Nieun */ - { 0x00000ea6, 15289 }, /* Hangul_NieunHieuh */ - { 0x00000ea5, 15307 }, /* Hangul_NieunJieuj */ - { 0x00000ec7, 15325 }, /* Hangul_O */ - { 0x00000eca, 15334 }, /* Hangul_OE */ - { 0x00000ef2, 15344 }, /* Hangul_PanSios */ - { 0x00000ebd, 15359 }, /* Hangul_Phieuf */ - { 0x00000eb2, 15373 }, /* Hangul_Pieub */ - { 0x00000eb4, 15386 }, /* Hangul_PieubSios */ - { 0x0000ff3b, 15403 }, /* Hangul_PostHanja */ - { 0x0000ff3a, 15420 }, /* Hangul_PreHanja */ - { 0x0000ff3e, 15436 }, /* Hangul_PreviousCandidate */ - { 0x00000ea9, 15461 }, /* Hangul_Rieul */ - { 0x00000eb0, 15474 }, /* Hangul_RieulHieuh */ - { 0x00000eaa, 15492 }, /* Hangul_RieulKiyeog */ - { 0x00000eab, 15511 }, /* Hangul_RieulMieum */ - { 0x00000eaf, 15529 }, /* Hangul_RieulPhieuf */ - { 0x00000eac, 15548 }, /* Hangul_RieulPieub */ - { 0x00000ead, 15566 }, /* Hangul_RieulSios */ - { 0x00000eae, 15583 }, /* Hangul_RieulTieut */ - { 0x00000eef, 15601 }, /* Hangul_RieulYeorinHieuh */ - { 0x0000ff36, 15625 }, /* Hangul_Romaja */ - { 0x0000ff3c, 15639 }, /* Hangul_SingleCandidate */ - { 0x00000eb5, 15662 }, /* Hangul_Sios */ - { 0x0000ff3f, 15674 }, /* Hangul_Special */ - { 0x00000ea8, 15689 }, /* Hangul_SsangDikeud */ - { 0x00000eb9, 15708 }, /* Hangul_SsangJieuj */ - { 0x00000ea2, 15726 }, /* Hangul_SsangKiyeog */ - { 0x00000eb3, 15745 }, /* Hangul_SsangPieub */ - { 0x00000eb6, 15763 }, /* Hangul_SsangSios */ - { 0x0000ff32, 15780 }, /* Hangul_Start */ - { 0x00000ef0, 15793 }, /* Hangul_SunkyeongeumMieum */ - { 0x00000ef4, 15818 }, /* Hangul_SunkyeongeumPhieuf */ - { 0x00000ef1, 15844 }, /* Hangul_SunkyeongeumPieub */ - { 0x0000ff7e, 15869 }, /* Hangul_switch */ - { 0x00000ebc, 15883 }, /* Hangul_Tieut */ - { 0x00000ecc, 15896 }, /* Hangul_U */ - { 0x00000ec8, 15905 }, /* Hangul_WA */ - { 0x00000ec9, 15915 }, /* Hangul_WAE */ - { 0x00000ece, 15926 }, /* Hangul_WE */ - { 0x00000ecd, 15936 }, /* Hangul_WEO */ - { 0x00000ecf, 15947 }, /* Hangul_WI */ - { 0x00000ec1, 15957 }, /* Hangul_YA */ - { 0x00000ec2, 15967 }, /* Hangul_YAE */ - { 0x00000ec6, 15978 }, /* Hangul_YE */ - { 0x00000ec5, 15988 }, /* Hangul_YEO */ - { 0x00000ef5, 15999 }, /* Hangul_YeorinHieuh */ - { 0x00000ed2, 16018 }, /* Hangul_YI */ - { 0x00000ecb, 16028 }, /* Hangul_YO */ - { 0x00000ed0, 16038 }, /* Hangul_YU */ - { 0x0000ff29, 16048 }, /* Hankaku */ - { 0x000002a6, 16056 }, /* Hcircumflex */ - { 0x000002b6, 16068 }, /* hcircumflex */ - { 0x00000aee, 16080 }, /* heart */ - { 0x00000ce0, 16086 }, /* hebrew_aleph */ - { 0x00000cf2, 16099 }, /* hebrew_ayin */ - { 0x00000ce1, 16111 }, /* hebrew_bet */ - { 0x00000ce1, 16122 }, /* hebrew_beth */ - { 0x00000ce7, 16134 }, /* hebrew_chet */ - { 0x00000ce3, 16146 }, /* hebrew_dalet */ - { 0x00000ce3, 16159 }, /* hebrew_daleth */ - { 0x00000cdf, 16173 }, /* hebrew_doublelowline */ - { 0x00000cea, 16194 }, /* hebrew_finalkaph */ - { 0x00000ced, 16211 }, /* hebrew_finalmem */ - { 0x00000cef, 16227 }, /* hebrew_finalnun */ - { 0x00000cf3, 16243 }, /* hebrew_finalpe */ - { 0x00000cf5, 16258 }, /* hebrew_finalzade */ - { 0x00000cf5, 16275 }, /* hebrew_finalzadi */ - { 0x00000ce2, 16292 }, /* hebrew_gimel */ - { 0x00000ce2, 16305 }, /* hebrew_gimmel */ - { 0x00000ce4, 16319 }, /* hebrew_he */ - { 0x00000ce7, 16329 }, /* hebrew_het */ - { 0x00000ceb, 16340 }, /* hebrew_kaph */ - { 0x00000cf7, 16352 }, /* hebrew_kuf */ - { 0x00000cec, 16363 }, /* hebrew_lamed */ - { 0x00000cee, 16376 }, /* hebrew_mem */ - { 0x00000cf0, 16387 }, /* hebrew_nun */ - { 0x00000cf4, 16398 }, /* hebrew_pe */ - { 0x00000cf7, 16408 }, /* hebrew_qoph */ - { 0x00000cf8, 16420 }, /* hebrew_resh */ - { 0x00000cf1, 16432 }, /* hebrew_samech */ - { 0x00000cf1, 16446 }, /* hebrew_samekh */ - { 0x00000cf9, 16460 }, /* hebrew_shin */ - { 0x0000ff7e, 16472 }, /* Hebrew_switch */ - { 0x00000cfa, 16486 }, /* hebrew_taf */ - { 0x00000cfa, 16497 }, /* hebrew_taw */ - { 0x00000ce8, 16508 }, /* hebrew_tet */ - { 0x00000ce8, 16519 }, /* hebrew_teth */ - { 0x00000ce5, 16531 }, /* hebrew_waw */ - { 0x00000ce9, 16542 }, /* hebrew_yod */ - { 0x00000cf6, 16553 }, /* hebrew_zade */ - { 0x00000cf6, 16565 }, /* hebrew_zadi */ - { 0x00000ce6, 16577 }, /* hebrew_zain */ - { 0x00000ce6, 16589 }, /* hebrew_zayin */ - { 0x0000ff6a, 16602 }, /* Help */ - { 0x0000ff23, 16607 }, /* Henkan */ - { 0x0000ff23, 16614 }, /* Henkan_Mode */ - { 0x00000ada, 16626 }, /* hexagram */ - { 0x0000ff25, 16635 }, /* Hiragana */ - { 0x0000ff27, 16644 }, /* Hiragana_Katakana */ - { 0x0000ff50, 16662 }, /* Home */ - { 0x000008a3, 16667 }, /* horizconnector */ - { 0x000009ef, 16682 }, /* horizlinescan1 */ - { 0x000009f0, 16697 }, /* horizlinescan3 */ - { 0x000009f1, 16712 }, /* horizlinescan5 */ - { 0x000009f2, 16727 }, /* horizlinescan7 */ - { 0x000009f3, 16742 }, /* horizlinescan9 */ - { 0x1000ff74, 16757 }, /* hpBackTab */ - { 0x100000fc, 16767 }, /* hpblock */ - { 0x1000ff6f, 16775 }, /* hpClearLine */ - { 0x1000ff73, 16787 }, /* hpDeleteChar */ - { 0x1000ff71, 16800 }, /* hpDeleteLine */ - { 0x100000be, 16813 }, /* hpguilder */ - { 0x1000ff72, 16823 }, /* hpInsertChar */ - { 0x1000ff70, 16836 }, /* hpInsertLine */ - { 0x100000ee, 16849 }, /* hpIO */ - { 0x1000ff75, 16854 }, /* hpKP_BackTab */ - { 0x100000af, 16867 }, /* hplira */ - { 0x100000f6, 16874 }, /* hplongminus */ - { 0x1000ff48, 16886 }, /* hpModelock1 */ - { 0x1000ff49, 16898 }, /* hpModelock2 */ - { 0x100000a8, 16910 }, /* hpmute_acute */ - { 0x100000aa, 16923 }, /* hpmute_asciicircum */ - { 0x100000ac, 16942 }, /* hpmute_asciitilde */ - { 0x100000ab, 16960 }, /* hpmute_diaeresis */ - { 0x100000a9, 16977 }, /* hpmute_grave */ - { 0x1000ff6c, 16990 }, /* hpReset */ - { 0x1000ff6d, 16998 }, /* hpSystem */ - { 0x1000ff6e, 17007 }, /* hpUser */ - { 0x100000ee, 17014 }, /* hpYdiaeresis */ - { 0x000002a1, 17027 }, /* Hstroke */ - { 0x000002b1, 17035 }, /* hstroke */ - { 0x000009e2, 17043 }, /* ht */ - { 0x0000ffed, 17046 }, /* Hyper_L */ - { 0x0000ffee, 17054 }, /* Hyper_R */ - { 0x000000ad, 17062 }, /* hyphen */ - { 0x00000049, 17069 }, /* I */ - { 0x00000069, 17071 }, /* i */ - { 0x000002a9, 17073 }, /* Iabovedot */ - { 0x000000cd, 17083 }, /* Iacute */ - { 0x000000ed, 17090 }, /* iacute */ - { 0x01001eca, 17097 }, /* Ibelowdot */ - { 0x01001ecb, 17107 }, /* ibelowdot */ - { 0x0100012c, 17117 }, /* Ibreve */ - { 0x0100012d, 17124 }, /* ibreve */ - { 0x000000ce, 17131 }, /* Icircumflex */ - { 0x000000ee, 17143 }, /* icircumflex */ - { 0x000008cf, 17155 }, /* identical */ - { 0x000000cf, 17165 }, /* Idiaeresis */ - { 0x000000ef, 17176 }, /* idiaeresis */ - { 0x000002b9, 17187 }, /* idotless */ - { 0x000008cd, 17196 }, /* ifonlyif */ - { 0x000000cc, 17205 }, /* Igrave */ - { 0x000000ec, 17212 }, /* igrave */ - { 0x01001ec8, 17219 }, /* Ihook */ - { 0x01001ec9, 17225 }, /* ihook */ - { 0x000003cf, 17231 }, /* Imacron */ - { 0x000003ef, 17239 }, /* imacron */ - { 0x000008ce, 17247 }, /* implies */ - { 0x000008da, 17255 }, /* includedin */ - { 0x000008db, 17266 }, /* includes */ - { 0x000008c2, 17275 }, /* infinity */ - { 0x0000ff63, 17284 }, /* Insert */ - { 0x1000ff72, 17291 }, /* InsertChar */ - { 0x1000ff70, 17302 }, /* InsertLine */ - { 0x000008bf, 17313 }, /* integral */ - { 0x000008dc, 17322 }, /* intersection */ - { 0x100000ee, 17335 }, /* IO */ - { 0x000003c7, 17338 }, /* Iogonek */ - { 0x000003e7, 17346 }, /* iogonek */ - { 0x0000fe33, 17354 }, /* ISO_Center_Object */ - { 0x0000fe30, 17372 }, /* ISO_Continuous_Underline */ - { 0x0000fe31, 17397 }, /* ISO_Discontinuous_Underline */ - { 0x0000fe32, 17425 }, /* ISO_Emphasize */ - { 0x0000fe34, 17439 }, /* ISO_Enter */ - { 0x0000fe2f, 17449 }, /* ISO_Fast_Cursor_Down */ - { 0x0000fe2c, 17470 }, /* ISO_Fast_Cursor_Left */ - { 0x0000fe2d, 17491 }, /* ISO_Fast_Cursor_Right */ - { 0x0000fe2e, 17513 }, /* ISO_Fast_Cursor_Up */ - { 0x0000fe0c, 17532 }, /* ISO_First_Group */ - { 0x0000fe0d, 17548 }, /* ISO_First_Group_Lock */ - { 0x0000fe06, 17569 }, /* ISO_Group_Latch */ - { 0x0000fe07, 17585 }, /* ISO_Group_Lock */ - { 0x0000ff7e, 17600 }, /* ISO_Group_Shift */ - { 0x0000fe0e, 17616 }, /* ISO_Last_Group */ - { 0x0000fe0f, 17631 }, /* ISO_Last_Group_Lock */ - { 0x0000fe20, 17651 }, /* ISO_Left_Tab */ - { 0x0000fe02, 17664 }, /* ISO_Level2_Latch */ - { 0x0000fe04, 17681 }, /* ISO_Level3_Latch */ - { 0x0000fe05, 17698 }, /* ISO_Level3_Lock */ - { 0x0000fe03, 17714 }, /* ISO_Level3_Shift */ - { 0x0000fe12, 17731 }, /* ISO_Level5_Latch */ - { 0x0000fe13, 17748 }, /* ISO_Level5_Lock */ - { 0x0000fe11, 17764 }, /* ISO_Level5_Shift */ - { 0x0000fe01, 17781 }, /* ISO_Lock */ - { 0x0000fe22, 17790 }, /* ISO_Move_Line_Down */ - { 0x0000fe21, 17809 }, /* ISO_Move_Line_Up */ - { 0x0000fe08, 17826 }, /* ISO_Next_Group */ - { 0x0000fe09, 17841 }, /* ISO_Next_Group_Lock */ - { 0x0000fe24, 17861 }, /* ISO_Partial_Line_Down */ - { 0x0000fe23, 17883 }, /* ISO_Partial_Line_Up */ - { 0x0000fe25, 17903 }, /* ISO_Partial_Space_Left */ - { 0x0000fe26, 17926 }, /* ISO_Partial_Space_Right */ - { 0x0000fe0a, 17950 }, /* ISO_Prev_Group */ - { 0x0000fe0b, 17965 }, /* ISO_Prev_Group_Lock */ - { 0x0000fe2b, 17985 }, /* ISO_Release_Both_Margins */ - { 0x0000fe29, 18010 }, /* ISO_Release_Margin_Left */ - { 0x0000fe2a, 18034 }, /* ISO_Release_Margin_Right */ - { 0x0000fe27, 18059 }, /* ISO_Set_Margin_Left */ - { 0x0000fe28, 18079 }, /* ISO_Set_Margin_Right */ - { 0x000003a5, 18100 }, /* Itilde */ - { 0x000003b5, 18107 }, /* itilde */ - { 0x0000004a, 18114 }, /* J */ - { 0x0000006a, 18116 }, /* j */ - { 0x000002ac, 18118 }, /* Jcircumflex */ - { 0x000002bc, 18130 }, /* jcircumflex */ - { 0x00000bca, 18142 }, /* jot */ - { 0x0000004b, 18146 }, /* K */ - { 0x0000006b, 18148 }, /* k */ - { 0x000004a7, 18150 }, /* kana_a */ - { 0x000004b1, 18157 }, /* kana_A */ - { 0x000004c1, 18164 }, /* kana_CHI */ - { 0x000004a3, 18173 }, /* kana_closingbracket */ - { 0x000004a4, 18193 }, /* kana_comma */ - { 0x000004a5, 18204 }, /* kana_conjunctive */ - { 0x000004aa, 18221 }, /* kana_e */ - { 0x000004b4, 18228 }, /* kana_E */ - { 0x000004cc, 18235 }, /* kana_FU */ - { 0x000004a1, 18243 }, /* kana_fullstop */ - { 0x000004ca, 18257 }, /* kana_HA */ - { 0x000004cd, 18265 }, /* kana_HE */ - { 0x000004cb, 18273 }, /* kana_HI */ - { 0x000004ce, 18281 }, /* kana_HO */ - { 0x000004cc, 18289 }, /* kana_HU */ - { 0x000004a8, 18297 }, /* kana_i */ - { 0x000004b2, 18304 }, /* kana_I */ - { 0x000004b6, 18311 }, /* kana_KA */ - { 0x000004b9, 18319 }, /* kana_KE */ - { 0x000004b7, 18327 }, /* kana_KI */ - { 0x000004ba, 18335 }, /* kana_KO */ - { 0x000004b8, 18343 }, /* kana_KU */ - { 0x0000ff2d, 18351 }, /* Kana_Lock */ - { 0x000004cf, 18361 }, /* kana_MA */ - { 0x000004d2, 18369 }, /* kana_ME */ - { 0x000004d0, 18377 }, /* kana_MI */ - { 0x000004a5, 18385 }, /* kana_middledot */ - { 0x000004d3, 18400 }, /* kana_MO */ - { 0x000004d1, 18408 }, /* kana_MU */ - { 0x000004dd, 18416 }, /* kana_N */ - { 0x000004c5, 18423 }, /* kana_NA */ - { 0x000004c8, 18431 }, /* kana_NE */ - { 0x000004c6, 18439 }, /* kana_NI */ - { 0x000004c9, 18447 }, /* kana_NO */ - { 0x000004c7, 18455 }, /* kana_NU */ - { 0x000004ab, 18463 }, /* kana_o */ - { 0x000004b5, 18470 }, /* kana_O */ - { 0x000004a2, 18477 }, /* kana_openingbracket */ - { 0x000004d7, 18497 }, /* kana_RA */ - { 0x000004da, 18505 }, /* kana_RE */ - { 0x000004d8, 18513 }, /* kana_RI */ - { 0x000004db, 18521 }, /* kana_RO */ - { 0x000004d9, 18529 }, /* kana_RU */ - { 0x000004bb, 18537 }, /* kana_SA */ - { 0x000004be, 18545 }, /* kana_SE */ - { 0x000004bc, 18553 }, /* kana_SHI */ - { 0x0000ff2e, 18562 }, /* Kana_Shift */ - { 0x000004bf, 18573 }, /* kana_SO */ - { 0x000004bd, 18581 }, /* kana_SU */ - { 0x0000ff7e, 18589 }, /* kana_switch */ - { 0x000004c0, 18601 }, /* kana_TA */ - { 0x000004c3, 18609 }, /* kana_TE */ - { 0x000004c1, 18617 }, /* kana_TI */ - { 0x000004c4, 18625 }, /* kana_TO */ - { 0x000004af, 18633 }, /* kana_tsu */ - { 0x000004c2, 18642 }, /* kana_TSU */ - { 0x000004af, 18651 }, /* kana_tu */ - { 0x000004c2, 18659 }, /* kana_TU */ - { 0x000004a9, 18667 }, /* kana_u */ - { 0x000004b3, 18674 }, /* kana_U */ - { 0x000004dc, 18681 }, /* kana_WA */ - { 0x000004a6, 18689 }, /* kana_WO */ - { 0x000004ac, 18697 }, /* kana_ya */ - { 0x000004d4, 18705 }, /* kana_YA */ - { 0x000004ae, 18713 }, /* kana_yo */ - { 0x000004d6, 18721 }, /* kana_YO */ - { 0x000004ad, 18729 }, /* kana_yu */ - { 0x000004d5, 18737 }, /* kana_YU */ - { 0x0000ff21, 18745 }, /* Kanji */ - { 0x0000ff37, 18751 }, /* Kanji_Bangou */ - { 0x000003a2, 18764 }, /* kappa */ - { 0x0000ff26, 18770 }, /* Katakana */ - { 0x000003d3, 18779 }, /* Kcedilla */ - { 0x000003f3, 18788 }, /* kcedilla */ - { 0x00000eff, 18797 }, /* Korean_Won */ - { 0x0000ffb0, 18808 }, /* KP_0 */ - { 0x0000ffb1, 18813 }, /* KP_1 */ - { 0x0000ffb2, 18818 }, /* KP_2 */ - { 0x0000ffb3, 18823 }, /* KP_3 */ - { 0x0000ffb4, 18828 }, /* KP_4 */ - { 0x0000ffb5, 18833 }, /* KP_5 */ - { 0x0000ffb6, 18838 }, /* KP_6 */ - { 0x0000ffb7, 18843 }, /* KP_7 */ - { 0x0000ffb8, 18848 }, /* KP_8 */ - { 0x0000ffb9, 18853 }, /* KP_9 */ - { 0x0000ffab, 18858 }, /* KP_Add */ - { 0x1000ff75, 18865 }, /* KP_BackTab */ - { 0x0000ff9d, 18876 }, /* KP_Begin */ - { 0x0000ffae, 18885 }, /* KP_Decimal */ - { 0x0000ff9f, 18896 }, /* KP_Delete */ - { 0x0000ffaf, 18906 }, /* KP_Divide */ - { 0x0000ff99, 18916 }, /* KP_Down */ - { 0x0000ff9c, 18924 }, /* KP_End */ - { 0x0000ff8d, 18931 }, /* KP_Enter */ - { 0x0000ffbd, 18940 }, /* KP_Equal */ - { 0x0000ff91, 18949 }, /* KP_F1 */ - { 0x0000ff92, 18955 }, /* KP_F2 */ - { 0x0000ff93, 18961 }, /* KP_F3 */ - { 0x0000ff94, 18967 }, /* KP_F4 */ - { 0x0000ff95, 18973 }, /* KP_Home */ - { 0x0000ff9e, 18981 }, /* KP_Insert */ - { 0x0000ff96, 18991 }, /* KP_Left */ - { 0x0000ffaa, 18999 }, /* KP_Multiply */ - { 0x0000ff9b, 19011 }, /* KP_Next */ - { 0x0000ff9b, 19019 }, /* KP_Page_Down */ - { 0x0000ff9a, 19032 }, /* KP_Page_Up */ - { 0x0000ff9a, 19043 }, /* KP_Prior */ - { 0x0000ff98, 19052 }, /* KP_Right */ - { 0x0000ffac, 19061 }, /* KP_Separator */ - { 0x0000ff80, 19074 }, /* KP_Space */ - { 0x0000ffad, 19083 }, /* KP_Subtract */ - { 0x0000ff89, 19095 }, /* KP_Tab */ - { 0x0000ff97, 19102 }, /* KP_Up */ - { 0x000003a2, 19108 }, /* kra */ - { 0x0000004c, 19112 }, /* L */ - { 0x0000006c, 19114 }, /* l */ - { 0x0000ffc8, 19116 }, /* L1 */ - { 0x0000ffd1, 19119 }, /* L10 */ - { 0x0000ffc9, 19123 }, /* L2 */ - { 0x0000ffca, 19126 }, /* L3 */ - { 0x0000ffcb, 19129 }, /* L4 */ - { 0x0000ffcc, 19132 }, /* L5 */ - { 0x0000ffcd, 19135 }, /* L6 */ - { 0x0000ffce, 19138 }, /* L7 */ - { 0x0000ffcf, 19141 }, /* L8 */ - { 0x0000ffd0, 19144 }, /* L9 */ - { 0x000001c5, 19147 }, /* Lacute */ - { 0x000001e5, 19154 }, /* lacute */ - { 0x0000fed4, 19161 }, /* Last_Virtual_Screen */ - { 0x00000ad9, 19181 }, /* latincross */ - { 0x01001e36, 19192 }, /* Lbelowdot */ - { 0x01001e37, 19202 }, /* lbelowdot */ - { 0x000001a5, 19212 }, /* Lcaron */ - { 0x000001b5, 19219 }, /* lcaron */ - { 0x000003a6, 19226 }, /* Lcedilla */ - { 0x000003b6, 19235 }, /* lcedilla */ - { 0x0000ff51, 19244 }, /* Left */ - { 0x00000abc, 19249 }, /* leftanglebracket */ - { 0x000008fb, 19266 }, /* leftarrow */ - { 0x00000ba3, 19276 }, /* leftcaret */ - { 0x00000ad2, 19286 }, /* leftdoublequotemark */ - { 0x000008af, 19306 }, /* leftmiddlecurlybrace */ - { 0x00000acc, 19327 }, /* leftopentriangle */ - { 0x00000aea, 19344 }, /* leftpointer */ - { 0x000008a1, 19356 }, /* leftradical */ - { 0x00000bda, 19368 }, /* leftshoe */ - { 0x00000ad0, 19377 }, /* leftsinglequotemark */ - { 0x000009f4, 19397 }, /* leftt */ - { 0x00000bdc, 19403 }, /* lefttack */ - { 0x0000003c, 19412 }, /* less */ - { 0x000008bc, 19417 }, /* lessthanequal */ - { 0x000009e5, 19431 }, /* lf */ - { 0x0000ff0a, 19434 }, /* Linefeed */ - { 0x100000af, 19443 }, /* lira */ - { 0x010020a4, 19448 }, /* LiraSign */ - { 0x000008de, 19457 }, /* logicaland */ - { 0x000008df, 19468 }, /* logicalor */ - { 0x100000f6, 19478 }, /* longminus */ - { 0x000009ed, 19488 }, /* lowleftcorner */ - { 0x000009ea, 19502 }, /* lowrightcorner */ - { 0x000001a3, 19517 }, /* Lstroke */ - { 0x000001b3, 19525 }, /* lstroke */ - { 0x0000004d, 19533 }, /* M */ - { 0x0000006d, 19535 }, /* m */ - { 0x01001e40, 19537 }, /* Mabovedot */ - { 0x01001e41, 19547 }, /* mabovedot */ - { 0x000006a5, 19557 }, /* Macedonia_dse */ - { 0x000006b5, 19571 }, /* Macedonia_DSE */ - { 0x000006a2, 19585 }, /* Macedonia_gje */ - { 0x000006b2, 19599 }, /* Macedonia_GJE */ - { 0x000006ac, 19613 }, /* Macedonia_kje */ - { 0x000006bc, 19627 }, /* Macedonia_KJE */ - { 0x000000af, 19641 }, /* macron */ - { 0x0000ff3e, 19648 }, /* Mae_Koho */ - { 0x00000af7, 19657 }, /* malesymbol */ - { 0x00000af0, 19668 }, /* maltesecross */ - { 0x00000abf, 19681 }, /* marker */ - { 0x000000ba, 19688 }, /* masculine */ - { 0x0000ff2c, 19698 }, /* Massyo */ - { 0x0000ff67, 19705 }, /* Menu */ - { 0x0000ffe7, 19710 }, /* Meta_L */ - { 0x0000ffe8, 19717 }, /* Meta_R */ - { 0x010020a5, 19724 }, /* MillSign */ - { 0x0000002d, 19733 }, /* minus */ - { 0x00000ad6, 19739 }, /* minutes */ - { 0x0000ff7e, 19747 }, /* Mode_switch */ - { 0x0000fe77, 19759 }, /* MouseKeys_Accel_Enable */ - { 0x0000fe76, 19782 }, /* MouseKeys_Enable */ - { 0x000000b5, 19799 }, /* mu */ - { 0x0000ff22, 19802 }, /* Muhenkan */ - { 0x0000ff20, 19811 }, /* Multi_key */ - { 0x0000ff3d, 19821 }, /* MultipleCandidate */ - { 0x000000d7, 19839 }, /* multiply */ - { 0x00000af6, 19848 }, /* musicalflat */ - { 0x00000af5, 19860 }, /* musicalsharp */ - { 0x100000a8, 19873 }, /* mute_acute */ - { 0x100000aa, 19884 }, /* mute_asciicircum */ - { 0x100000ac, 19901 }, /* mute_asciitilde */ - { 0x100000ab, 19917 }, /* mute_diaeresis */ - { 0x100000a9, 19932 }, /* mute_grave */ - { 0x0000004e, 19943 }, /* N */ - { 0x0000006e, 19945 }, /* n */ - { 0x000008c5, 19947 }, /* nabla */ - { 0x000001d1, 19953 }, /* Nacute */ - { 0x000001f1, 19960 }, /* nacute */ - { 0x010020a6, 19967 }, /* NairaSign */ - { 0x000001d2, 19977 }, /* Ncaron */ - { 0x000001f2, 19984 }, /* ncaron */ - { 0x000003d1, 19991 }, /* Ncedilla */ - { 0x000003f1, 20000 }, /* ncedilla */ - { 0x010020aa, 20009 }, /* NewSheqelSign */ - { 0x0000ff56, 20023 }, /* Next */ - { 0x0000fed2, 20028 }, /* Next_Virtual_Screen */ - { 0x01002089, 20048 }, /* ninesubscript */ - { 0x01002079, 20062 }, /* ninesuperior */ - { 0x000009e8, 20075 }, /* nl */ - { 0x000000a0, 20078 }, /* nobreakspace */ - { 0x00000000, 20091 }, /* NoSymbol */ - { 0x01002247, 20100 }, /* notapproxeq */ - { 0x01002209, 20112 }, /* notelementof */ - { 0x000008bd, 20125 }, /* notequal */ - { 0x01002262, 20134 }, /* notidentical */ - { 0x000000ac, 20147 }, /* notsign */ - { 0x000000d1, 20155 }, /* Ntilde */ - { 0x000000f1, 20162 }, /* ntilde */ - { 0x0000ff7f, 20169 }, /* Num_Lock */ - { 0x00000023, 20178 }, /* numbersign */ - { 0x000006b0, 20189 }, /* numerosign */ - { 0x0000004f, 20200 }, /* O */ - { 0x0000006f, 20202 }, /* o */ - { 0x000000d3, 20204 }, /* Oacute */ - { 0x000000f3, 20211 }, /* oacute */ - { 0x0100019f, 20218 }, /* Obarred */ - { 0x01000275, 20226 }, /* obarred */ - { 0x01001ecc, 20234 }, /* Obelowdot */ - { 0x01001ecd, 20244 }, /* obelowdot */ - { 0x010001d1, 20254 }, /* Ocaron */ - { 0x010001d2, 20261 }, /* ocaron */ - { 0x000000d4, 20268 }, /* Ocircumflex */ - { 0x000000f4, 20280 }, /* ocircumflex */ - { 0x01001ed0, 20292 }, /* Ocircumflexacute */ - { 0x01001ed1, 20309 }, /* ocircumflexacute */ - { 0x01001ed8, 20326 }, /* Ocircumflexbelowdot */ - { 0x01001ed9, 20346 }, /* ocircumflexbelowdot */ - { 0x01001ed2, 20366 }, /* Ocircumflexgrave */ - { 0x01001ed3, 20383 }, /* ocircumflexgrave */ - { 0x01001ed4, 20400 }, /* Ocircumflexhook */ - { 0x01001ed5, 20416 }, /* ocircumflexhook */ - { 0x01001ed6, 20432 }, /* Ocircumflextilde */ - { 0x01001ed7, 20449 }, /* ocircumflextilde */ - { 0x000000d6, 20466 }, /* Odiaeresis */ - { 0x000000f6, 20477 }, /* odiaeresis */ - { 0x000001d5, 20488 }, /* Odoubleacute */ - { 0x000001f5, 20501 }, /* odoubleacute */ - { 0x000013bc, 20514 }, /* OE */ - { 0x000013bd, 20517 }, /* oe */ - { 0x000001b2, 20520 }, /* ogonek */ - { 0x000000d2, 20527 }, /* Ograve */ - { 0x000000f2, 20534 }, /* ograve */ - { 0x01001ece, 20541 }, /* Ohook */ - { 0x01001ecf, 20547 }, /* ohook */ - { 0x010001a0, 20553 }, /* Ohorn */ - { 0x010001a1, 20559 }, /* ohorn */ - { 0x01001eda, 20565 }, /* Ohornacute */ - { 0x01001edb, 20576 }, /* ohornacute */ - { 0x01001ee2, 20587 }, /* Ohornbelowdot */ - { 0x01001ee3, 20601 }, /* ohornbelowdot */ - { 0x01001edc, 20615 }, /* Ohorngrave */ - { 0x01001edd, 20626 }, /* ohorngrave */ - { 0x01001ede, 20637 }, /* Ohornhook */ - { 0x01001edf, 20647 }, /* ohornhook */ - { 0x01001ee0, 20657 }, /* Ohorntilde */ - { 0x01001ee1, 20668 }, /* ohorntilde */ - { 0x000003d2, 20679 }, /* Omacron */ - { 0x000003f2, 20687 }, /* omacron */ - { 0x00000ac3, 20695 }, /* oneeighth */ - { 0x00000ab2, 20705 }, /* onefifth */ - { 0x000000bd, 20714 }, /* onehalf */ - { 0x000000bc, 20722 }, /* onequarter */ - { 0x00000ab6, 20733 }, /* onesixth */ - { 0x01002081, 20742 }, /* onesubscript */ - { 0x000000b9, 20755 }, /* onesuperior */ - { 0x00000ab0, 20767 }, /* onethird */ - { 0x000000d8, 20776 }, /* Ooblique */ - { 0x000000f8, 20785 }, /* ooblique */ - { 0x00000ae2, 20794 }, /* openrectbullet */ - { 0x00000ae5, 20809 }, /* openstar */ - { 0x00000ae4, 20818 }, /* opentribulletdown */ - { 0x00000ae3, 20836 }, /* opentribulletup */ - { 0x000000aa, 20852 }, /* ordfeminine */ - { 0x1004ff44, 20864 }, /* osfActivate */ - { 0x1004ff31, 20876 }, /* osfAddMode */ - { 0x1004ff08, 20887 }, /* osfBackSpace */ - { 0x1004ff07, 20900 }, /* osfBackTab */ - { 0x1004ff5a, 20911 }, /* osfBeginData */ - { 0x1004ff58, 20924 }, /* osfBeginLine */ - { 0x1004ff69, 20937 }, /* osfCancel */ - { 0x1004ff0b, 20947 }, /* osfClear */ - { 0x1004ff02, 20956 }, /* osfCopy */ - { 0x1004ff03, 20964 }, /* osfCut */ - { 0x1004ffff, 20971 }, /* osfDelete */ - { 0x1004ff72, 20981 }, /* osfDeselectAll */ - { 0x1004ff54, 20996 }, /* osfDown */ - { 0x1004ff59, 21004 }, /* osfEndData */ - { 0x1004ff57, 21015 }, /* osfEndLine */ - { 0x1004ff1b, 21026 }, /* osfEscape */ - { 0x1004ff74, 21036 }, /* osfExtend */ - { 0x1004ff6a, 21046 }, /* osfHelp */ - { 0x1004ff63, 21054 }, /* osfInsert */ - { 0x1004ff51, 21064 }, /* osfLeft */ - { 0x1004ff67, 21072 }, /* osfMenu */ - { 0x1004ff45, 21080 }, /* osfMenuBar */ - { 0x1004ff5e, 21091 }, /* osfNextField */ - { 0x1004ff5c, 21104 }, /* osfNextMenu */ - { 0x1004ff42, 21116 }, /* osfPageDown */ - { 0x1004ff40, 21128 }, /* osfPageLeft */ - { 0x1004ff43, 21140 }, /* osfPageRight */ - { 0x1004ff41, 21153 }, /* osfPageUp */ - { 0x1004ff04, 21163 }, /* osfPaste */ - { 0x1004ff5d, 21172 }, /* osfPrevField */ - { 0x1004ff5b, 21185 }, /* osfPrevMenu */ - { 0x1004ff32, 21197 }, /* osfPrimaryPaste */ - { 0x1004ff33, 21213 }, /* osfQuickPaste */ - { 0x1004ff73, 21227 }, /* osfReselect */ - { 0x1004ff78, 21239 }, /* osfRestore */ - { 0x1004ff53, 21250 }, /* osfRight */ - { 0x1004ff60, 21259 }, /* osfSelect */ - { 0x1004ff71, 21269 }, /* osfSelectAll */ - { 0x1004ff65, 21282 }, /* osfUndo */ - { 0x1004ff52, 21290 }, /* osfUp */ - { 0x000000d8, 21296 }, /* Oslash */ - { 0x000000f8, 21303 }, /* oslash */ - { 0x000000d5, 21310 }, /* Otilde */ - { 0x000000f5, 21317 }, /* otilde */ - { 0x00000bc0, 21324 }, /* overbar */ - { 0x0000fe78, 21332 }, /* Overlay1_Enable */ - { 0x0000fe79, 21348 }, /* Overlay2_Enable */ - { 0x0000047e, 21364 }, /* overline */ - { 0x00000050, 21373 }, /* P */ - { 0x00000070, 21375 }, /* p */ - { 0x01001e56, 21377 }, /* Pabovedot */ - { 0x01001e57, 21387 }, /* pabovedot */ - { 0x0000ff56, 21397 }, /* Page_Down */ - { 0x0000ff55, 21407 }, /* Page_Up */ - { 0x000000b6, 21415 }, /* paragraph */ - { 0x00000028, 21425 }, /* parenleft */ - { 0x00000029, 21435 }, /* parenright */ - { 0x01002202, 21446 }, /* partdifferential */ - { 0x000008ef, 21463 }, /* partialderivative */ - { 0x0000ff13, 21481 }, /* Pause */ - { 0x00000025, 21487 }, /* percent */ - { 0x0000002e, 21495 }, /* period */ - { 0x000000b7, 21502 }, /* periodcentered */ - { 0x00000ad5, 21517 }, /* permille */ - { 0x010020a7, 21526 }, /* PesetaSign */ - { 0x00000afb, 21537 }, /* phonographcopyright */ - { 0x0000002b, 21557 }, /* plus */ - { 0x000000b1, 21562 }, /* plusminus */ - { 0x0000fefa, 21572 }, /* Pointer_Accelerate */ - { 0x0000fee9, 21591 }, /* Pointer_Button1 */ - { 0x0000feea, 21607 }, /* Pointer_Button2 */ - { 0x0000feeb, 21623 }, /* Pointer_Button3 */ - { 0x0000feec, 21639 }, /* Pointer_Button4 */ - { 0x0000feed, 21655 }, /* Pointer_Button5 */ - { 0x0000fee8, 21671 }, /* Pointer_Button_Dflt */ - { 0x0000feef, 21691 }, /* Pointer_DblClick1 */ - { 0x0000fef0, 21709 }, /* Pointer_DblClick2 */ - { 0x0000fef1, 21727 }, /* Pointer_DblClick3 */ - { 0x0000fef2, 21745 }, /* Pointer_DblClick4 */ - { 0x0000fef3, 21763 }, /* Pointer_DblClick5 */ - { 0x0000feee, 21781 }, /* Pointer_DblClick_Dflt */ - { 0x0000fefb, 21803 }, /* Pointer_DfltBtnNext */ - { 0x0000fefc, 21823 }, /* Pointer_DfltBtnPrev */ - { 0x0000fee3, 21843 }, /* Pointer_Down */ - { 0x0000fee6, 21856 }, /* Pointer_DownLeft */ - { 0x0000fee7, 21873 }, /* Pointer_DownRight */ - { 0x0000fef5, 21891 }, /* Pointer_Drag1 */ - { 0x0000fef6, 21905 }, /* Pointer_Drag2 */ - { 0x0000fef7, 21919 }, /* Pointer_Drag3 */ - { 0x0000fef8, 21933 }, /* Pointer_Drag4 */ - { 0x0000fefd, 21947 }, /* Pointer_Drag5 */ - { 0x0000fef4, 21961 }, /* Pointer_Drag_Dflt */ - { 0x0000fef9, 21979 }, /* Pointer_EnableKeys */ - { 0x0000fee0, 21998 }, /* Pointer_Left */ - { 0x0000fee1, 22011 }, /* Pointer_Right */ - { 0x0000fee2, 22025 }, /* Pointer_Up */ - { 0x0000fee4, 22036 }, /* Pointer_UpLeft */ - { 0x0000fee5, 22051 }, /* Pointer_UpRight */ - { 0x00000ad4, 22067 }, /* prescription */ - { 0x0000fed1, 22080 }, /* Prev_Virtual_Screen */ - { 0x0000ff3e, 22100 }, /* PreviousCandidate */ - { 0x0000ff61, 22118 }, /* Print */ - { 0x0000ff55, 22124 }, /* Prior */ - { 0x000004b0, 22130 }, /* prolongedsound */ - { 0x00000aa6, 22145 }, /* punctspace */ - { 0x00000051, 22156 }, /* Q */ - { 0x00000071, 22158 }, /* q */ - { 0x00000bcc, 22160 }, /* quad */ - { 0x0000003f, 22165 }, /* question */ - { 0x000000bf, 22174 }, /* questiondown */ - { 0x00000022, 22187 }, /* quotedbl */ - { 0x00000060, 22196 }, /* quoteleft */ - { 0x00000027, 22206 }, /* quoteright */ - { 0x00000052, 22217 }, /* R */ - { 0x00000072, 22219 }, /* r */ - { 0x0000ffd2, 22221 }, /* R1 */ - { 0x0000ffdb, 22224 }, /* R10 */ - { 0x0000ffdc, 22228 }, /* R11 */ - { 0x0000ffdd, 22232 }, /* R12 */ - { 0x0000ffde, 22236 }, /* R13 */ - { 0x0000ffdf, 22240 }, /* R14 */ - { 0x0000ffe0, 22244 }, /* R15 */ - { 0x0000ffd3, 22248 }, /* R2 */ - { 0x0000ffd4, 22251 }, /* R3 */ - { 0x0000ffd5, 22254 }, /* R4 */ - { 0x0000ffd6, 22257 }, /* R5 */ - { 0x0000ffd7, 22260 }, /* R6 */ - { 0x0000ffd8, 22263 }, /* R7 */ - { 0x0000ffd9, 22266 }, /* R8 */ - { 0x0000ffda, 22269 }, /* R9 */ - { 0x000001c0, 22272 }, /* Racute */ - { 0x000001e0, 22279 }, /* racute */ - { 0x000008d6, 22286 }, /* radical */ - { 0x000001d8, 22294 }, /* Rcaron */ - { 0x000001f8, 22301 }, /* rcaron */ - { 0x000003a3, 22308 }, /* Rcedilla */ - { 0x000003b3, 22317 }, /* rcedilla */ - { 0x0000ff66, 22326 }, /* Redo */ - { 0x000000ae, 22331 }, /* registered */ - { 0x0000fe72, 22342 }, /* RepeatKeys_Enable */ - { 0x1000ff6c, 22360 }, /* Reset */ - { 0x0000ff0d, 22366 }, /* Return */ - { 0x0000ff53, 22373 }, /* Right */ - { 0x00000abe, 22379 }, /* rightanglebracket */ - { 0x000008fd, 22397 }, /* rightarrow */ - { 0x00000ba6, 22408 }, /* rightcaret */ - { 0x00000ad3, 22419 }, /* rightdoublequotemark */ - { 0x000008b0, 22440 }, /* rightmiddlecurlybrace */ - { 0x000008b7, 22462 }, /* rightmiddlesummation */ - { 0x00000acd, 22483 }, /* rightopentriangle */ - { 0x00000aeb, 22501 }, /* rightpointer */ - { 0x00000bd8, 22514 }, /* rightshoe */ - { 0x00000ad1, 22524 }, /* rightsinglequotemark */ - { 0x000009f5, 22545 }, /* rightt */ - { 0x00000bfc, 22552 }, /* righttack */ - { 0x0000ff24, 22562 }, /* Romaji */ - { 0x010020a8, 22569 }, /* RupeeSign */ - { 0x00000053, 22579 }, /* S */ - { 0x00000073, 22581 }, /* s */ - { 0x01001e60, 22583 }, /* Sabovedot */ - { 0x01001e61, 22593 }, /* sabovedot */ - { 0x000001a6, 22603 }, /* Sacute */ - { 0x000001b6, 22610 }, /* sacute */ - { 0x000001a9, 22617 }, /* Scaron */ - { 0x000001b9, 22624 }, /* scaron */ - { 0x000001aa, 22631 }, /* Scedilla */ - { 0x000001ba, 22640 }, /* scedilla */ - { 0x0100018f, 22649 }, /* SCHWA */ - { 0x01000259, 22655 }, /* schwa */ - { 0x000002de, 22661 }, /* Scircumflex */ - { 0x000002fe, 22673 }, /* scircumflex */ - { 0x0000ff7e, 22685 }, /* script_switch */ - { 0x0000ff14, 22699 }, /* Scroll_Lock */ - { 0x00000ad7, 22711 }, /* seconds */ - { 0x000000a7, 22719 }, /* section */ - { 0x0000ff60, 22727 }, /* Select */ - { 0x0000003b, 22734 }, /* semicolon */ - { 0x000004df, 22744 }, /* semivoicedsound */ - { 0x000006a1, 22760 }, /* Serbian_dje */ - { 0x000006b1, 22772 }, /* Serbian_DJE */ - { 0x000006af, 22784 }, /* Serbian_dze */ - { 0x000006bf, 22796 }, /* Serbian_DZE */ - { 0x000006a8, 22808 }, /* Serbian_je */ - { 0x000006b8, 22819 }, /* Serbian_JE */ - { 0x000006a9, 22830 }, /* Serbian_lje */ - { 0x000006b9, 22842 }, /* Serbian_LJE */ - { 0x000006aa, 22854 }, /* Serbian_nje */ - { 0x000006ba, 22866 }, /* Serbian_NJE */ - { 0x000006ab, 22878 }, /* Serbian_tshe */ - { 0x000006bb, 22891 }, /* Serbian_TSHE */ - { 0x00000ac6, 22904 }, /* seveneighths */ - { 0x01002087, 22917 }, /* sevensubscript */ - { 0x01002077, 22932 }, /* sevensuperior */ - { 0x0000ffe1, 22946 }, /* Shift_L */ - { 0x0000ffe6, 22954 }, /* Shift_Lock */ - { 0x0000ffe2, 22965 }, /* Shift_R */ - { 0x00000aca, 22973 }, /* signaturemark */ - { 0x00000aac, 22987 }, /* signifblank */ - { 0x000008c9, 22999 }, /* similarequal */ - { 0x0000ff3c, 23012 }, /* SingleCandidate */ - { 0x00000afd, 23028 }, /* singlelowquotemark */ - { 0x01000d85, 23047 }, /* Sinh_a */ - { 0x01000d86, 23054 }, /* Sinh_aa */ - { 0x01000dcf, 23062 }, /* Sinh_aa2 */ - { 0x01000d87, 23071 }, /* Sinh_ae */ - { 0x01000dd0, 23079 }, /* Sinh_ae2 */ - { 0x01000d88, 23088 }, /* Sinh_aee */ - { 0x01000dd1, 23097 }, /* Sinh_aee2 */ - { 0x01000d93, 23107 }, /* Sinh_ai */ - { 0x01000ddb, 23115 }, /* Sinh_ai2 */ - { 0x01000dca, 23124 }, /* Sinh_al */ - { 0x01000d96, 23132 }, /* Sinh_au */ - { 0x01000dde, 23140 }, /* Sinh_au2 */ - { 0x01000db6, 23149 }, /* Sinh_ba */ - { 0x01000db7, 23157 }, /* Sinh_bha */ - { 0x01000da0, 23166 }, /* Sinh_ca */ - { 0x01000da1, 23174 }, /* Sinh_cha */ - { 0x01000da9, 23183 }, /* Sinh_dda */ - { 0x01000daa, 23192 }, /* Sinh_ddha */ - { 0x01000daf, 23202 }, /* Sinh_dha */ - { 0x01000db0, 23211 }, /* Sinh_dhha */ - { 0x01000d91, 23221 }, /* Sinh_e */ - { 0x01000dd9, 23228 }, /* Sinh_e2 */ - { 0x01000d92, 23236 }, /* Sinh_ee */ - { 0x01000dda, 23244 }, /* Sinh_ee2 */ - { 0x01000dc6, 23253 }, /* Sinh_fa */ - { 0x01000d9c, 23261 }, /* Sinh_ga */ - { 0x01000d9d, 23269 }, /* Sinh_gha */ - { 0x01000d83, 23278 }, /* Sinh_h2 */ - { 0x01000dc4, 23286 }, /* Sinh_ha */ - { 0x01000d89, 23294 }, /* Sinh_i */ - { 0x01000dd2, 23301 }, /* Sinh_i2 */ - { 0x01000d8a, 23309 }, /* Sinh_ii */ - { 0x01000dd3, 23317 }, /* Sinh_ii2 */ - { 0x01000da2, 23326 }, /* Sinh_ja */ - { 0x01000da3, 23334 }, /* Sinh_jha */ - { 0x01000da5, 23343 }, /* Sinh_jnya */ - { 0x01000d9a, 23353 }, /* Sinh_ka */ - { 0x01000d9b, 23361 }, /* Sinh_kha */ - { 0x01000df4, 23370 }, /* Sinh_kunddaliya */ - { 0x01000dbd, 23386 }, /* Sinh_la */ - { 0x01000dc5, 23394 }, /* Sinh_lla */ - { 0x01000d8f, 23403 }, /* Sinh_lu */ - { 0x01000ddf, 23411 }, /* Sinh_lu2 */ - { 0x01000d90, 23420 }, /* Sinh_luu */ - { 0x01000df3, 23429 }, /* Sinh_luu2 */ - { 0x01000db8, 23439 }, /* Sinh_ma */ - { 0x01000db9, 23447 }, /* Sinh_mba */ - { 0x01000db1, 23456 }, /* Sinh_na */ - { 0x01000dac, 23464 }, /* Sinh_ndda */ - { 0x01000db3, 23474 }, /* Sinh_ndha */ - { 0x01000d82, 23484 }, /* Sinh_ng */ - { 0x01000d9e, 23492 }, /* Sinh_ng2 */ - { 0x01000d9f, 23501 }, /* Sinh_nga */ - { 0x01000da6, 23510 }, /* Sinh_nja */ - { 0x01000dab, 23519 }, /* Sinh_nna */ - { 0x01000da4, 23528 }, /* Sinh_nya */ - { 0x01000d94, 23537 }, /* Sinh_o */ - { 0x01000ddc, 23544 }, /* Sinh_o2 */ - { 0x01000d95, 23552 }, /* Sinh_oo */ - { 0x01000ddd, 23560 }, /* Sinh_oo2 */ - { 0x01000db4, 23569 }, /* Sinh_pa */ - { 0x01000db5, 23577 }, /* Sinh_pha */ - { 0x01000dbb, 23586 }, /* Sinh_ra */ - { 0x01000d8d, 23594 }, /* Sinh_ri */ - { 0x01000d8e, 23602 }, /* Sinh_rii */ - { 0x01000dd8, 23611 }, /* Sinh_ru2 */ - { 0x01000df2, 23620 }, /* Sinh_ruu2 */ - { 0x01000dc3, 23630 }, /* Sinh_sa */ - { 0x01000dc1, 23638 }, /* Sinh_sha */ - { 0x01000dc2, 23647 }, /* Sinh_ssha */ - { 0x01000dad, 23657 }, /* Sinh_tha */ - { 0x01000dae, 23666 }, /* Sinh_thha */ - { 0x01000da7, 23676 }, /* Sinh_tta */ - { 0x01000da8, 23685 }, /* Sinh_ttha */ - { 0x01000d8b, 23695 }, /* Sinh_u */ - { 0x01000dd4, 23702 }, /* Sinh_u2 */ - { 0x01000d8c, 23710 }, /* Sinh_uu */ - { 0x01000dd6, 23718 }, /* Sinh_uu2 */ - { 0x01000dc0, 23727 }, /* Sinh_va */ - { 0x01000dba, 23735 }, /* Sinh_ya */ - { 0x01002086, 23743 }, /* sixsubscript */ - { 0x01002076, 23756 }, /* sixsuperior */ - { 0x0000002f, 23768 }, /* slash */ - { 0x0000fe73, 23774 }, /* SlowKeys_Enable */ - { 0x000009e0, 23790 }, /* soliddiamond */ - { 0x00000020, 23803 }, /* space */ - { 0x0100221a, 23809 }, /* squareroot */ - { 0x000000df, 23820 }, /* ssharp */ - { 0x000000a3, 23827 }, /* sterling */ - { 0x0000fe75, 23836 }, /* StickyKeys_Enable */ - { 0x01002263, 23854 }, /* stricteq */ - { 0x0000ff66, 23863 }, /* SunAgain */ - { 0x0000ff7e, 23872 }, /* SunAltGraph */ - { 0x1005ff77, 23884 }, /* SunAudioLowerVolume */ - { 0x1005ff78, 23904 }, /* SunAudioMute */ - { 0x1005ff79, 23917 }, /* SunAudioRaiseVolume */ - { 0x0000ff20, 23937 }, /* SunCompose */ - { 0x1005ff72, 23948 }, /* SunCopy */ - { 0x1005ff75, 23956 }, /* SunCut */ - { 0x1005ff10, 23963 }, /* SunF36 */ - { 0x1005ff11, 23970 }, /* SunF37 */ - { 0x1005ff03, 23977 }, /* SunFA_Acute */ - { 0x1005ff05, 23989 }, /* SunFA_Cedilla */ - { 0x1005ff01, 24003 }, /* SunFA_Circum */ - { 0x1005ff04, 24016 }, /* SunFA_Diaeresis */ - { 0x1005ff00, 24032 }, /* SunFA_Grave */ - { 0x1005ff02, 24044 }, /* SunFA_Tilde */ - { 0x0000ff68, 24056 }, /* SunFind */ - { 0x1005ff71, 24064 }, /* SunFront */ - { 0x1005ff73, 24073 }, /* SunOpen */ - { 0x0000ff56, 24081 }, /* SunPageDown */ - { 0x0000ff55, 24093 }, /* SunPageUp */ - { 0x1005ff74, 24103 }, /* SunPaste */ - { 0x1005ff76, 24112 }, /* SunPowerSwitch */ - { 0x1005ff7d, 24127 }, /* SunPowerSwitchShift */ - { 0x0000ff61, 24147 }, /* SunPrint_Screen */ - { 0x1005ff70, 24163 }, /* SunProps */ - { 0x0000ff69, 24172 }, /* SunStop */ - { 0x1005ff60, 24180 }, /* SunSys_Req */ - { 0x0000ff65, 24191 }, /* SunUndo */ - { 0x1005ff7a, 24199 }, /* SunVideoDegauss */ - { 0x1005ff7b, 24215 }, /* SunVideoLowerBrightness */ - { 0x1005ff7c, 24239 }, /* SunVideoRaiseBrightness */ - { 0x0000ffeb, 24263 }, /* Super_L */ - { 0x0000ffec, 24271 }, /* Super_R */ - { 0x0000ff15, 24279 }, /* Sys_Req */ - { 0x1000ff6d, 24287 }, /* System */ - { 0x00000054, 24294 }, /* T */ - { 0x00000074, 24296 }, /* t */ - { 0x0000ff09, 24298 }, /* Tab */ - { 0x01001e6a, 24302 }, /* Tabovedot */ - { 0x01001e6b, 24312 }, /* tabovedot */ - { 0x000001ab, 24322 }, /* Tcaron */ - { 0x000001bb, 24329 }, /* tcaron */ - { 0x000001de, 24336 }, /* Tcedilla */ - { 0x000001fe, 24345 }, /* tcedilla */ - { 0x00000af9, 24354 }, /* telephone */ - { 0x00000afa, 24364 }, /* telephonerecorder */ - { 0x0000fed5, 24382 }, /* Terminate_Server */ - { 0x00000ddf, 24399 }, /* Thai_baht */ - { 0x00000dba, 24409 }, /* Thai_bobaimai */ - { 0x00000da8, 24423 }, /* Thai_chochan */ - { 0x00000daa, 24436 }, /* Thai_chochang */ - { 0x00000da9, 24450 }, /* Thai_choching */ - { 0x00000dac, 24464 }, /* Thai_chochoe */ - { 0x00000dae, 24477 }, /* Thai_dochada */ - { 0x00000db4, 24490 }, /* Thai_dodek */ - { 0x00000dbd, 24501 }, /* Thai_fofa */ - { 0x00000dbf, 24511 }, /* Thai_fofan */ - { 0x00000dcb, 24522 }, /* Thai_hohip */ - { 0x00000dce, 24533 }, /* Thai_honokhuk */ - { 0x00000da2, 24547 }, /* Thai_khokhai */ - { 0x00000da5, 24560 }, /* Thai_khokhon */ - { 0x00000da3, 24573 }, /* Thai_khokhuat */ - { 0x00000da4, 24587 }, /* Thai_khokhwai */ - { 0x00000da6, 24601 }, /* Thai_khorakhang */ - { 0x00000da1, 24617 }, /* Thai_kokai */ - { 0x00000de5, 24628 }, /* Thai_lakkhangyao */ - { 0x00000df7, 24645 }, /* Thai_lekchet */ - { 0x00000df5, 24658 }, /* Thai_lekha */ - { 0x00000df6, 24669 }, /* Thai_lekhok */ - { 0x00000df9, 24681 }, /* Thai_lekkao */ - { 0x00000df1, 24693 }, /* Thai_leknung */ - { 0x00000df8, 24706 }, /* Thai_lekpaet */ - { 0x00000df3, 24719 }, /* Thai_leksam */ - { 0x00000df4, 24731 }, /* Thai_leksi */ - { 0x00000df2, 24742 }, /* Thai_leksong */ - { 0x00000df0, 24755 }, /* Thai_leksun */ - { 0x00000dcc, 24767 }, /* Thai_lochula */ - { 0x00000dc5, 24780 }, /* Thai_loling */ - { 0x00000dc6, 24792 }, /* Thai_lu */ - { 0x00000deb, 24800 }, /* Thai_maichattawa */ - { 0x00000de8, 24817 }, /* Thai_maiek */ - { 0x00000dd1, 24828 }, /* Thai_maihanakat */ - { 0x00000dde, 24844 }, /* Thai_maihanakat_maitho */ - { 0x00000de7, 24867 }, /* Thai_maitaikhu */ - { 0x00000de9, 24882 }, /* Thai_maitho */ - { 0x00000dea, 24894 }, /* Thai_maitri */ - { 0x00000de6, 24906 }, /* Thai_maiyamok */ - { 0x00000dc1, 24920 }, /* Thai_moma */ - { 0x00000da7, 24930 }, /* Thai_ngongu */ - { 0x00000ded, 24942 }, /* Thai_nikhahit */ - { 0x00000db3, 24956 }, /* Thai_nonen */ - { 0x00000db9, 24967 }, /* Thai_nonu */ - { 0x00000dcd, 24977 }, /* Thai_oang */ - { 0x00000dcf, 24987 }, /* Thai_paiyannoi */ - { 0x00000dda, 25002 }, /* Thai_phinthu */ - { 0x00000dbe, 25015 }, /* Thai_phophan */ - { 0x00000dbc, 25028 }, /* Thai_phophung */ - { 0x00000dc0, 25042 }, /* Thai_phosamphao */ - { 0x00000dbb, 25058 }, /* Thai_popla */ - { 0x00000dc3, 25069 }, /* Thai_rorua */ - { 0x00000dc4, 25080 }, /* Thai_ru */ - { 0x00000dd0, 25088 }, /* Thai_saraa */ - { 0x00000dd2, 25099 }, /* Thai_saraaa */ - { 0x00000de1, 25111 }, /* Thai_saraae */ - { 0x00000de4, 25123 }, /* Thai_saraaimaimalai */ - { 0x00000de3, 25143 }, /* Thai_saraaimaimuan */ - { 0x00000dd3, 25162 }, /* Thai_saraam */ - { 0x00000de0, 25174 }, /* Thai_sarae */ - { 0x00000dd4, 25185 }, /* Thai_sarai */ - { 0x00000dd5, 25196 }, /* Thai_saraii */ - { 0x00000de2, 25208 }, /* Thai_sarao */ - { 0x00000dd8, 25219 }, /* Thai_sarau */ - { 0x00000dd6, 25230 }, /* Thai_saraue */ - { 0x00000dd7, 25242 }, /* Thai_sarauee */ - { 0x00000dd9, 25255 }, /* Thai_sarauu */ - { 0x00000dc9, 25267 }, /* Thai_sorusi */ - { 0x00000dc8, 25279 }, /* Thai_sosala */ - { 0x00000dab, 25291 }, /* Thai_soso */ - { 0x00000dca, 25301 }, /* Thai_sosua */ - { 0x00000dec, 25312 }, /* Thai_thanthakhat */ - { 0x00000db1, 25329 }, /* Thai_thonangmontho */ - { 0x00000db2, 25348 }, /* Thai_thophuthao */ - { 0x00000db7, 25364 }, /* Thai_thothahan */ - { 0x00000db0, 25379 }, /* Thai_thothan */ - { 0x00000db8, 25392 }, /* Thai_thothong */ - { 0x00000db6, 25406 }, /* Thai_thothung */ - { 0x00000daf, 25420 }, /* Thai_topatak */ - { 0x00000db5, 25433 }, /* Thai_totao */ - { 0x00000dc7, 25444 }, /* Thai_wowaen */ - { 0x00000dc2, 25456 }, /* Thai_yoyak */ - { 0x00000dad, 25467 }, /* Thai_yoying */ - { 0x000008c0, 25479 }, /* therefore */ - { 0x00000aa7, 25489 }, /* thinspace */ - { 0x000000de, 25499 }, /* THORN */ - { 0x000000de, 25505 }, /* Thorn */ - { 0x000000fe, 25511 }, /* thorn */ - { 0x00000ac4, 25517 }, /* threeeighths */ - { 0x00000ab4, 25530 }, /* threefifths */ - { 0x000000be, 25542 }, /* threequarters */ - { 0x01002083, 25556 }, /* threesubscript */ - { 0x000000b3, 25571 }, /* threesuperior */ - { 0x0100222d, 25585 }, /* tintegral */ - { 0x000008a4, 25595 }, /* topintegral */ - { 0x000008ab, 25607 }, /* topleftparens */ - { 0x000008a2, 25621 }, /* topleftradical */ - { 0x000008a7, 25636 }, /* topleftsqbracket */ - { 0x000008b1, 25653 }, /* topleftsummation */ - { 0x000008ad, 25670 }, /* toprightparens */ - { 0x000008a9, 25685 }, /* toprightsqbracket */ - { 0x000008b5, 25703 }, /* toprightsummation */ - { 0x000009f7, 25721 }, /* topt */ - { 0x000008b3, 25726 }, /* topvertsummationconnector */ - { 0x0000ff2b, 25752 }, /* Touroku */ - { 0x00000ac9, 25760 }, /* trademark */ - { 0x00000acb, 25770 }, /* trademarkincircle */ - { 0x000003ac, 25788 }, /* Tslash */ - { 0x000003bc, 25795 }, /* tslash */ - { 0x00000ab3, 25802 }, /* twofifths */ - { 0x01002082, 25812 }, /* twosubscript */ - { 0x000000b2, 25825 }, /* twosuperior */ - { 0x00000ab1, 25837 }, /* twothirds */ - { 0x00000055, 25847 }, /* U */ - { 0x00000075, 25849 }, /* u */ - { 0x000000da, 25851 }, /* Uacute */ - { 0x000000fa, 25858 }, /* uacute */ - { 0x01001ee4, 25865 }, /* Ubelowdot */ - { 0x01001ee5, 25875 }, /* ubelowdot */ - { 0x000002dd, 25885 }, /* Ubreve */ - { 0x000002fd, 25892 }, /* ubreve */ - { 0x000000db, 25899 }, /* Ucircumflex */ - { 0x000000fb, 25911 }, /* ucircumflex */ - { 0x000000dc, 25923 }, /* Udiaeresis */ - { 0x000000fc, 25934 }, /* udiaeresis */ - { 0x000001db, 25945 }, /* Udoubleacute */ - { 0x000001fb, 25958 }, /* udoubleacute */ - { 0x000000d9, 25971 }, /* Ugrave */ - { 0x000000f9, 25978 }, /* ugrave */ - { 0x01001ee6, 25985 }, /* Uhook */ - { 0x01001ee7, 25991 }, /* uhook */ - { 0x010001af, 25997 }, /* Uhorn */ - { 0x010001b0, 26003 }, /* uhorn */ - { 0x01001ee8, 26009 }, /* Uhornacute */ - { 0x01001ee9, 26020 }, /* uhornacute */ - { 0x01001ef0, 26031 }, /* Uhornbelowdot */ - { 0x01001ef1, 26045 }, /* uhornbelowdot */ - { 0x01001eea, 26059 }, /* Uhorngrave */ - { 0x01001eeb, 26070 }, /* uhorngrave */ - { 0x01001eec, 26081 }, /* Uhornhook */ - { 0x01001eed, 26091 }, /* uhornhook */ - { 0x01001eee, 26101 }, /* Uhorntilde */ - { 0x01001eef, 26112 }, /* uhorntilde */ - { 0x000006ad, 26123 }, /* Ukrainian_ghe_with_upturn */ - { 0x000006bd, 26149 }, /* Ukrainian_GHE_WITH_UPTURN */ - { 0x000006a6, 26175 }, /* Ukrainian_i */ - { 0x000006b6, 26187 }, /* Ukrainian_I */ - { 0x000006a4, 26199 }, /* Ukrainian_ie */ - { 0x000006b4, 26212 }, /* Ukrainian_IE */ - { 0x000006a7, 26225 }, /* Ukrainian_yi */ - { 0x000006b7, 26238 }, /* Ukrainian_YI */ - { 0x000006a6, 26251 }, /* Ukranian_i */ - { 0x000006b6, 26262 }, /* Ukranian_I */ - { 0x000006a4, 26273 }, /* Ukranian_je */ - { 0x000006b4, 26285 }, /* Ukranian_JE */ - { 0x000006a7, 26297 }, /* Ukranian_yi */ - { 0x000006b7, 26309 }, /* Ukranian_YI */ - { 0x000003de, 26321 }, /* Umacron */ - { 0x000003fe, 26329 }, /* umacron */ - { 0x00000bc6, 26337 }, /* underbar */ - { 0x0000005f, 26346 }, /* underscore */ - { 0x0000ff65, 26357 }, /* Undo */ - { 0x000008dd, 26362 }, /* union */ - { 0x000003d9, 26368 }, /* Uogonek */ - { 0x000003f9, 26376 }, /* uogonek */ - { 0x0000ff52, 26384 }, /* Up */ - { 0x000008fc, 26387 }, /* uparrow */ - { 0x00000ba9, 26395 }, /* upcaret */ - { 0x000009ec, 26403 }, /* upleftcorner */ - { 0x000009eb, 26416 }, /* uprightcorner */ - { 0x00000bc3, 26430 }, /* upshoe */ - { 0x00000bd3, 26437 }, /* upstile */ - { 0x00000bce, 26445 }, /* uptack */ - { 0x000001d9, 26452 }, /* Uring */ - { 0x000001f9, 26458 }, /* uring */ - { 0x1000ff6e, 26464 }, /* User */ - { 0x000003dd, 26469 }, /* Utilde */ - { 0x000003fd, 26476 }, /* utilde */ - { 0x00000056, 26483 }, /* V */ - { 0x00000076, 26485 }, /* v */ - { 0x000008c1, 26487 }, /* variation */ - { 0x000009f8, 26497 }, /* vertbar */ - { 0x000008a6, 26505 }, /* vertconnector */ - { 0x000004de, 26519 }, /* voicedsound */ - { 0x00ffffff, 26531 }, /* VoidSymbol */ - { 0x000009e9, 26542 }, /* vt */ - { 0x00000057, 26545 }, /* W */ - { 0x00000077, 26547 }, /* w */ - { 0x01001e82, 26549 }, /* Wacute */ - { 0x01001e83, 26556 }, /* wacute */ - { 0x01000174, 26563 }, /* Wcircumflex */ - { 0x01000175, 26575 }, /* wcircumflex */ - { 0x01001e84, 26587 }, /* Wdiaeresis */ - { 0x01001e85, 26598 }, /* wdiaeresis */ - { 0x01001e80, 26609 }, /* Wgrave */ - { 0x01001e81, 26616 }, /* wgrave */ - { 0x010020a9, 26623 }, /* WonSign */ - { 0x00000058, 26631 }, /* X */ - { 0x00000078, 26633 }, /* x */ - { 0x01001e8a, 26635 }, /* Xabovedot */ - { 0x01001e8b, 26645 }, /* xabovedot */ - { 0x1008ff39, 26655 }, /* XF86AddFavorite */ - { 0x1008ff50, 26671 }, /* XF86ApplicationLeft */ - { 0x1008ff51, 26691 }, /* XF86ApplicationRight */ - { 0x1008ff9b, 26712 }, /* XF86AudioCycleTrack */ - { 0x1008ff97, 26732 }, /* XF86AudioForward */ - { 0x1008ff11, 26749 }, /* XF86AudioLowerVolume */ - { 0x1008ff32, 26770 }, /* XF86AudioMedia */ - { 0x1008ffb2, 26785 }, /* XF86AudioMicMute */ - { 0x1008ff12, 26802 }, /* XF86AudioMute */ - { 0x1008ff17, 26816 }, /* XF86AudioNext */ - { 0x1008ff31, 26830 }, /* XF86AudioPause */ - { 0x1008ff14, 26845 }, /* XF86AudioPlay */ - { 0x1008ffb6, 26859 }, /* XF86AudioPreset */ - { 0x1008ff16, 26875 }, /* XF86AudioPrev */ - { 0x1008ff13, 26889 }, /* XF86AudioRaiseVolume */ - { 0x1008ff99, 26910 }, /* XF86AudioRandomPlay */ - { 0x1008ff1c, 26930 }, /* XF86AudioRecord */ - { 0x1008ff98, 26946 }, /* XF86AudioRepeat */ - { 0x1008ff3e, 26962 }, /* XF86AudioRewind */ - { 0x1008ff15, 26978 }, /* XF86AudioStop */ - { 0x1008ff8d, 26992 }, /* XF86Away */ - { 0x1008ff26, 27001 }, /* XF86Back */ - { 0x1008ff3f, 27010 }, /* XF86BackForward */ - { 0x1008ff93, 27026 }, /* XF86Battery */ - { 0x1008ffa6, 27038 }, /* XF86Blue */ - { 0x1008ff94, 27047 }, /* XF86Bluetooth */ - { 0x1008ff52, 27061 }, /* XF86Book */ - { 0x1008ff3b, 27070 }, /* XF86BrightnessAdjust */ - { 0x1008ff54, 27091 }, /* XF86Calculater */ - { 0x1008ff1d, 27106 }, /* XF86Calculator */ - { 0x1008ff20, 27121 }, /* XF86Calendar */ - { 0x1008ff53, 27134 }, /* XF86CD */ - { 0x1008ff55, 27141 }, /* XF86Clear */ - { 0x1008fe21, 27151 }, /* XF86ClearGrab */ - { 0x1008ff56, 27165 }, /* XF86Close */ - { 0x1008ff3d, 27175 }, /* XF86Community */ - { 0x1008ff22, 27189 }, /* XF86ContrastAdjust */ - { 0x1008ff57, 27208 }, /* XF86Copy */ - { 0x1008ff58, 27217 }, /* XF86Cut */ - { 0x1008ff9c, 27225 }, /* XF86CycleAngle */ - { 0x1008ff59, 27240 }, /* XF86Display */ - { 0x1008ff5b, 27252 }, /* XF86Documents */ - { 0x1008ff5a, 27266 }, /* XF86DOS */ - { 0x1008ff2c, 27274 }, /* XF86Eject */ - { 0x1008ff5c, 27284 }, /* XF86Excel */ - { 0x1008ff5d, 27294 }, /* XF86Explorer */ - { 0x1008ff30, 27307 }, /* XF86Favorites */ - { 0x1008ff3c, 27321 }, /* XF86Finance */ - { 0x1008ff27, 27333 }, /* XF86Forward */ - { 0x1008ff9d, 27345 }, /* XF86FrameBack */ - { 0x1008ff9e, 27359 }, /* XF86FrameForward */ - { 0x1008ff5e, 27376 }, /* XF86Game */ - { 0x1008ff5f, 27385 }, /* XF86Go */ - { 0x1008ffa4, 27392 }, /* XF86Green */ - { 0x1008ffa8, 27402 }, /* XF86Hibernate */ - { 0x1008ff37, 27416 }, /* XF86History */ - { 0x1008ff18, 27428 }, /* XF86HomePage */ - { 0x1008ff3a, 27441 }, /* XF86HotLinks */ - { 0x1008ff60, 27454 }, /* XF86iTouch */ - { 0x1008ff06, 27465 }, /* XF86KbdBrightnessDown */ - { 0x1008ff05, 27487 }, /* XF86KbdBrightnessUp */ - { 0x1008ff04, 27507 }, /* XF86KbdLightOnOff */ - { 0x1008ffb3, 27525 }, /* XF86Keyboard */ - { 0x1008ff40, 27538 }, /* XF86Launch0 */ - { 0x1008ff41, 27550 }, /* XF86Launch1 */ - { 0x1008ff42, 27562 }, /* XF86Launch2 */ - { 0x1008ff43, 27574 }, /* XF86Launch3 */ - { 0x1008ff44, 27586 }, /* XF86Launch4 */ - { 0x1008ff45, 27598 }, /* XF86Launch5 */ - { 0x1008ff46, 27610 }, /* XF86Launch6 */ - { 0x1008ff47, 27622 }, /* XF86Launch7 */ - { 0x1008ff48, 27634 }, /* XF86Launch8 */ - { 0x1008ff49, 27646 }, /* XF86Launch9 */ - { 0x1008ff4a, 27658 }, /* XF86LaunchA */ - { 0x1008ff4b, 27670 }, /* XF86LaunchB */ - { 0x1008ff4c, 27682 }, /* XF86LaunchC */ - { 0x1008ff4d, 27694 }, /* XF86LaunchD */ - { 0x1008ff4e, 27706 }, /* XF86LaunchE */ - { 0x1008ff4f, 27718 }, /* XF86LaunchF */ - { 0x1008ff35, 27730 }, /* XF86LightBulb */ - { 0x1008fe25, 27744 }, /* XF86LogGrabInfo */ - { 0x1008ff61, 27760 }, /* XF86LogOff */ - { 0x1008fe24, 27771 }, /* XF86LogWindowTree */ - { 0x1008ff19, 27789 }, /* XF86Mail */ - { 0x1008ff90, 27798 }, /* XF86MailForward */ - { 0x1008ff62, 27814 }, /* XF86Market */ - { 0x1008ff63, 27825 }, /* XF86Meeting */ - { 0x1008ff1e, 27837 }, /* XF86Memo */ - { 0x1008ff65, 27846 }, /* XF86MenuKB */ - { 0x1008ff66, 27857 }, /* XF86MenuPB */ - { 0x1008ff8e, 27868 }, /* XF86Messenger */ - { 0x1008ff01, 27882 }, /* XF86ModeLock */ - { 0x1008ff03, 27895 }, /* XF86MonBrightnessDown */ - { 0x1008ff02, 27917 }, /* XF86MonBrightnessUp */ - { 0x1008ff92, 27937 }, /* XF86Music */ - { 0x1008ff33, 27947 }, /* XF86MyComputer */ - { 0x1008ff67, 27962 }, /* XF86MySites */ - { 0x1008ff68, 27974 }, /* XF86New */ - { 0x1008ff69, 27982 }, /* XF86News */ - { 0x1008fe22, 27991 }, /* XF86Next_VMode */ - { 0x1008ff6a, 28006 }, /* XF86OfficeHome */ - { 0x1008ff6b, 28021 }, /* XF86Open */ - { 0x1008ff38, 28030 }, /* XF86OpenURL */ - { 0x1008ff6c, 28042 }, /* XF86Option */ - { 0x1008ff6d, 28053 }, /* XF86Paste */ - { 0x1008ff6e, 28063 }, /* XF86Phone */ - { 0x1008ff91, 28073 }, /* XF86Pictures */ - { 0x1008ff21, 28086 }, /* XF86PowerDown */ - { 0x1008ff2a, 28100 }, /* XF86PowerOff */ - { 0x1008fe23, 28113 }, /* XF86Prev_VMode */ - { 0x1008ff70, 28128 }, /* XF86Q */ - { 0x1008ffa3, 28134 }, /* XF86Red */ - { 0x1008ff29, 28142 }, /* XF86Refresh */ - { 0x1008ff73, 28154 }, /* XF86Reload */ - { 0x1008ff72, 28165 }, /* XF86Reply */ - { 0x1008ffb5, 28175 }, /* XF86RFKill */ - { 0x1008ff24, 28186 }, /* XF86RockerDown */ - { 0x1008ff25, 28201 }, /* XF86RockerEnter */ - { 0x1008ff23, 28217 }, /* XF86RockerUp */ - { 0x1008ff74, 28230 }, /* XF86RotateWindows */ - { 0x1008ff76, 28248 }, /* XF86RotationKB */ - { 0x1008ff75, 28263 }, /* XF86RotationPB */ - { 0x1008ff77, 28278 }, /* XF86Save */ - { 0x1008ff2d, 28287 }, /* XF86ScreenSaver */ - { 0x1008ff7a, 28303 }, /* XF86ScrollClick */ - { 0x1008ff79, 28319 }, /* XF86ScrollDown */ - { 0x1008ff78, 28334 }, /* XF86ScrollUp */ - { 0x1008ff1b, 28347 }, /* XF86Search */ - { 0x1008ffa0, 28358 }, /* XF86Select */ - { 0x1008ff7b, 28369 }, /* XF86Send */ - { 0x1008ff36, 28378 }, /* XF86Shop */ - { 0x1008ff2f, 28387 }, /* XF86Sleep */ - { 0x1008ff7c, 28397 }, /* XF86Spell */ - { 0x1008ff7d, 28407 }, /* XF86SplitScreen */ - { 0x1008ff10, 28423 }, /* XF86Standby */ - { 0x1008ff1a, 28435 }, /* XF86Start */ - { 0x1008ff28, 28445 }, /* XF86Stop */ - { 0x1008ff9a, 28454 }, /* XF86Subtitle */ - { 0x1008ff7e, 28467 }, /* XF86Support */ - { 0x1008ffa7, 28479 }, /* XF86Suspend */ - { 0x1008fe01, 28491 }, /* XF86Switch_VT_1 */ - { 0x1008fe0a, 28507 }, /* XF86Switch_VT_10 */ - { 0x1008fe0b, 28524 }, /* XF86Switch_VT_11 */ - { 0x1008fe0c, 28541 }, /* XF86Switch_VT_12 */ - { 0x1008fe02, 28558 }, /* XF86Switch_VT_2 */ - { 0x1008fe03, 28574 }, /* XF86Switch_VT_3 */ - { 0x1008fe04, 28590 }, /* XF86Switch_VT_4 */ - { 0x1008fe05, 28606 }, /* XF86Switch_VT_5 */ - { 0x1008fe06, 28622 }, /* XF86Switch_VT_6 */ - { 0x1008fe07, 28638 }, /* XF86Switch_VT_7 */ - { 0x1008fe08, 28654 }, /* XF86Switch_VT_8 */ - { 0x1008fe09, 28670 }, /* XF86Switch_VT_9 */ - { 0x1008ff7f, 28686 }, /* XF86TaskPane */ - { 0x1008ff80, 28699 }, /* XF86Terminal */ - { 0x1008ff9f, 28712 }, /* XF86Time */ - { 0x1008ff1f, 28721 }, /* XF86ToDoList */ - { 0x1008ff81, 28734 }, /* XF86Tools */ - { 0x1008ffa2, 28744 }, /* XF86TopMenu */ - { 0x1008ffb1, 28756 }, /* XF86TouchpadOff */ - { 0x1008ffb0, 28772 }, /* XF86TouchpadOn */ - { 0x1008ffa9, 28787 }, /* XF86TouchpadToggle */ - { 0x1008ff82, 28806 }, /* XF86Travel */ - { 0x1008fe20, 28817 }, /* XF86Ungrab */ - { 0x1008ff85, 28828 }, /* XF86User1KB */ - { 0x1008ff86, 28840 }, /* XF86User2KB */ - { 0x1008ff84, 28852 }, /* XF86UserPB */ - { 0x1008ff96, 28863 }, /* XF86UWB */ - { 0x1008ff34, 28871 }, /* XF86VendorHome */ - { 0x1008ff87, 28886 }, /* XF86Video */ - { 0x1008ffa1, 28896 }, /* XF86View */ - { 0x1008ff2b, 28905 }, /* XF86WakeUp */ - { 0x1008ff8f, 28916 }, /* XF86WebCam */ - { 0x1008ff88, 28927 }, /* XF86WheelButton */ - { 0x1008ff95, 28943 }, /* XF86WLAN */ - { 0x1008ff89, 28952 }, /* XF86Word */ - { 0x1008ffb4, 28961 }, /* XF86WWAN */ - { 0x1008ff2e, 28970 }, /* XF86WWW */ - { 0x1008ff8a, 28978 }, /* XF86Xfer */ - { 0x1008ffa5, 28987 }, /* XF86Yellow */ - { 0x1008ff8b, 28998 }, /* XF86ZoomIn */ - { 0x1008ff8c, 29009 }, /* XF86ZoomOut */ - { 0x00000059, 29021 }, /* Y */ - { 0x00000079, 29023 }, /* y */ - { 0x000000dd, 29025 }, /* Yacute */ - { 0x000000fd, 29032 }, /* yacute */ - { 0x01001ef4, 29039 }, /* Ybelowdot */ - { 0x01001ef5, 29049 }, /* ybelowdot */ - { 0x01000176, 29059 }, /* Ycircumflex */ - { 0x01000177, 29071 }, /* ycircumflex */ - { 0x000000ff, 29083 }, /* ydiaeresis */ - { 0x000013be, 29094 }, /* Ydiaeresis */ - { 0x000000a5, 29105 }, /* yen */ - { 0x01001ef2, 29109 }, /* Ygrave */ - { 0x01001ef3, 29116 }, /* ygrave */ - { 0x01001ef6, 29123 }, /* Yhook */ - { 0x01001ef7, 29129 }, /* yhook */ - { 0x01001ef8, 29135 }, /* Ytilde */ - { 0x01001ef9, 29142 }, /* ytilde */ - { 0x0000005a, 29149 }, /* Z */ - { 0x0000007a, 29151 }, /* z */ - { 0x000001af, 29153 }, /* Zabovedot */ - { 0x000001bf, 29163 }, /* zabovedot */ - { 0x000001ac, 29173 }, /* Zacute */ - { 0x000001bc, 29180 }, /* zacute */ - { 0x000001ae, 29187 }, /* Zcaron */ - { 0x000001be, 29194 }, /* zcaron */ - { 0x0000ff3d, 29201 }, /* Zen_Koho */ - { 0x0000ff28, 29210 }, /* Zenkaku */ - { 0x0000ff2a, 29218 }, /* Zenkaku_Hankaku */ - { 0x01002080, 29234 }, /* zerosubscript */ - { 0x01002070, 29248 }, /* zerosuperior */ - { 0x010001b5, 29261 }, /* Zstroke */ - { 0x010001b6, 29269 }, /* zstroke */ -}; - -static const struct name_keysym keysym_to_name[] = { - { 0x00000000, 20091 }, /* NoSymbol */ - { 0x00000020, 23803 }, /* space */ - { 0x00000021, 12099 }, /* exclam */ - { 0x00000022, 22187 }, /* quotedbl */ - { 0x00000023, 20178 }, /* numbersign */ - { 0x00000024, 11251 }, /* dollar */ - { 0x00000025, 21487 }, /* percent */ - { 0x00000026, 908 }, /* ampersand */ - { 0x00000027, 934 }, /* apostrophe */ - { 0x00000028, 21425 }, /* parenleft */ - { 0x00000029, 21435 }, /* parenright */ - { 0x0000002a, 3283 }, /* asterisk */ - { 0x0000002b, 21557 }, /* plus */ - { 0x0000002c, 8680 }, /* comma */ - { 0x0000002d, 19733 }, /* minus */ - { 0x0000002e, 21495 }, /* period */ - { 0x0000002f, 23768 }, /* slash */ - { 0x00000030, 0 }, /* 0 */ - { 0x00000031, 2 }, /* 1 */ - { 0x00000032, 4 }, /* 2 */ - { 0x00000033, 6 }, /* 3 */ - { 0x00000034, 386 }, /* 4 */ - { 0x00000035, 388 }, /* 5 */ - { 0x00000036, 390 }, /* 6 */ - { 0x00000037, 392 }, /* 7 */ - { 0x00000038, 394 }, /* 8 */ - { 0x00000039, 396 }, /* 9 */ - { 0x0000003a, 8664 }, /* colon */ - { 0x0000003b, 22734 }, /* semicolon */ - { 0x0000003c, 19412 }, /* less */ - { 0x0000003d, 12051 }, /* equal */ - { 0x0000003e, 13272 }, /* greater */ - { 0x0000003f, 22165 }, /* question */ - { 0x00000040, 3292 }, /* at */ - { 0x00000041, 398 }, /* A */ - { 0x00000042, 3328 }, /* B */ - { 0x00000043, 8439 }, /* C */ - { 0x00000044, 10320 }, /* D */ - { 0x00000045, 11424 }, /* E */ - { 0x00000046, 12155 }, /* F */ - { 0x00000047, 12665 }, /* G */ - { 0x00000048, 14378 }, /* H */ - { 0x00000049, 17069 }, /* I */ - { 0x0000004a, 18114 }, /* J */ - { 0x0000004b, 18146 }, /* K */ - { 0x0000004c, 19112 }, /* L */ - { 0x0000004d, 19533 }, /* M */ - { 0x0000004e, 19943 }, /* N */ - { 0x0000004f, 20200 }, /* O */ - { 0x00000050, 21373 }, /* P */ - { 0x00000051, 22156 }, /* Q */ - { 0x00000052, 22217 }, /* R */ - { 0x00000053, 22579 }, /* S */ - { 0x00000054, 24294 }, /* T */ - { 0x00000055, 25847 }, /* U */ - { 0x00000056, 26483 }, /* V */ - { 0x00000057, 26545 }, /* W */ - { 0x00000058, 26631 }, /* X */ - { 0x00000059, 29021 }, /* Y */ - { 0x0000005a, 29149 }, /* Z */ - { 0x0000005b, 3603 }, /* bracketleft */ - { 0x0000005c, 3352 }, /* backslash */ - { 0x0000005d, 3615 }, /* bracketright */ - { 0x0000005e, 3260 }, /* asciicircum */ - { 0x0000005f, 26346 }, /* underscore */ - { 0x00000060, 13266 }, /* grave */ - { 0x00000061, 400 }, /* a */ - { 0x00000062, 3330 }, /* b */ - { 0x00000063, 8441 }, /* c */ - { 0x00000064, 10322 }, /* d */ - { 0x00000065, 11426 }, /* e */ - { 0x00000066, 12157 }, /* f */ - { 0x00000067, 12667 }, /* g */ - { 0x00000068, 14380 }, /* h */ - { 0x00000069, 17071 }, /* i */ - { 0x0000006a, 18116 }, /* j */ - { 0x0000006b, 18148 }, /* k */ - { 0x0000006c, 19114 }, /* l */ - { 0x0000006d, 19535 }, /* m */ - { 0x0000006e, 19945 }, /* n */ - { 0x0000006f, 20202 }, /* o */ - { 0x00000070, 21375 }, /* p */ - { 0x00000071, 22158 }, /* q */ - { 0x00000072, 22219 }, /* r */ - { 0x00000073, 22581 }, /* s */ - { 0x00000074, 24296 }, /* t */ - { 0x00000075, 25849 }, /* u */ - { 0x00000076, 26485 }, /* v */ - { 0x00000077, 26547 }, /* w */ - { 0x00000078, 26633 }, /* x */ - { 0x00000079, 29023 }, /* y */ - { 0x0000007a, 29151 }, /* z */ - { 0x0000007b, 3582 }, /* braceleft */ - { 0x0000007c, 3392 }, /* bar */ - { 0x0000007d, 3592 }, /* braceright */ - { 0x0000007e, 3272 }, /* asciitilde */ - { 0x000000a0, 20078 }, /* nobreakspace */ - { 0x000000a1, 12106 }, /* exclamdown */ - { 0x000000a2, 8589 }, /* cent */ - { 0x000000a3, 23827 }, /* sterling */ - { 0x000000a4, 8766 }, /* currency */ - { 0x000000a5, 29105 }, /* yen */ - { 0x000000a6, 8389 }, /* brokenbar */ - { 0x000000a7, 22719 }, /* section */ - { 0x000000a8, 11203 }, /* diaeresis */ - { 0x000000a9, 8717 }, /* copyright */ - { 0x000000aa, 20852 }, /* ordfeminine */ - { 0x000000ab, 14349 }, /* guillemotleft */ - { 0x000000ac, 20147 }, /* notsign */ - { 0x000000ad, 17062 }, /* hyphen */ - { 0x000000ae, 22331 }, /* registered */ - { 0x000000af, 19641 }, /* macron */ - { 0x000000b0, 11153 }, /* degree */ - { 0x000000b1, 21562 }, /* plusminus */ - { 0x000000b2, 25825 }, /* twosuperior */ - { 0x000000b3, 25571 }, /* threesuperior */ - { 0x000000b4, 820 }, /* acute */ - { 0x000000b5, 19799 }, /* mu */ - { 0x000000b6, 21415 }, /* paragraph */ - { 0x000000b7, 21502 }, /* periodcentered */ - { 0x000000b8, 8581 }, /* cedilla */ - { 0x000000b9, 20755 }, /* onesuperior */ - { 0x000000ba, 19688 }, /* masculine */ - { 0x000000bb, 14363 }, /* guillemotright */ - { 0x000000bc, 20722 }, /* onequarter */ - { 0x000000bd, 20714 }, /* onehalf */ - { 0x000000be, 25542 }, /* threequarters */ - { 0x000000bf, 22174 }, /* questiondown */ - { 0x000000c0, 854 }, /* Agrave */ - { 0x000000c1, 402 }, /* Aacute */ - { 0x000000c2, 622 }, /* Acircumflex */ - { 0x000000c3, 3295 }, /* Atilde */ - { 0x000000c4, 826 }, /* Adiaeresis */ - { 0x000000c5, 2036 }, /* Aring */ - { 0x000000c6, 848 }, /* AE */ - { 0x000000c7, 8539 }, /* Ccedilla */ - { 0x000000c8, 11724 }, /* Egrave */ - { 0x000000c9, 11448 }, /* Eacute */ - { 0x000000ca, 11496 }, /* Ecircumflex */ - { 0x000000cb, 11702 }, /* Ediaeresis */ - { 0x000000cc, 17205 }, /* Igrave */ - { 0x000000cd, 17083 }, /* Iacute */ - { 0x000000ce, 17131 }, /* Icircumflex */ - { 0x000000cf, 17165 }, /* Idiaeresis */ - { 0x000000d0, 12064 }, /* ETH */ - { 0x000000d1, 20155 }, /* Ntilde */ - { 0x000000d2, 20527 }, /* Ograve */ - { 0x000000d3, 20204 }, /* Oacute */ - { 0x000000d4, 20268 }, /* Ocircumflex */ - { 0x000000d5, 21310 }, /* Otilde */ - { 0x000000d6, 20466 }, /* Odiaeresis */ - { 0x000000d7, 19839 }, /* multiply */ - { 0x000000d8, 21296 }, /* Oslash */ - { 0x000000d9, 25971 }, /* Ugrave */ - { 0x000000da, 25851 }, /* Uacute */ - { 0x000000db, 25899 }, /* Ucircumflex */ - { 0x000000dc, 25923 }, /* Udiaeresis */ - { 0x000000dd, 29025 }, /* Yacute */ - { 0x000000de, 25499 }, /* THORN */ - { 0x000000df, 23820 }, /* ssharp */ - { 0x000000e0, 861 }, /* agrave */ - { 0x000000e1, 409 }, /* aacute */ - { 0x000000e2, 634 }, /* acircumflex */ - { 0x000000e3, 3302 }, /* atilde */ - { 0x000000e4, 837 }, /* adiaeresis */ - { 0x000000e5, 2042 }, /* aring */ - { 0x000000e6, 851 }, /* ae */ - { 0x000000e7, 8548 }, /* ccedilla */ - { 0x000000e8, 11731 }, /* egrave */ - { 0x000000e9, 11455 }, /* eacute */ - { 0x000000ea, 11508 }, /* ecircumflex */ - { 0x000000eb, 11713 }, /* ediaeresis */ - { 0x000000ec, 17212 }, /* igrave */ - { 0x000000ed, 17090 }, /* iacute */ - { 0x000000ee, 17143 }, /* icircumflex */ - { 0x000000ef, 17176 }, /* idiaeresis */ - { 0x000000f0, 12072 }, /* eth */ - { 0x000000f1, 20162 }, /* ntilde */ - { 0x000000f2, 20534 }, /* ograve */ - { 0x000000f3, 20211 }, /* oacute */ - { 0x000000f4, 20280 }, /* ocircumflex */ - { 0x000000f5, 21317 }, /* otilde */ - { 0x000000f6, 20477 }, /* odiaeresis */ - { 0x000000f7, 11242 }, /* division */ - { 0x000000f8, 21303 }, /* oslash */ - { 0x000000f9, 25978 }, /* ugrave */ - { 0x000000fa, 25858 }, /* uacute */ - { 0x000000fb, 25911 }, /* ucircumflex */ - { 0x000000fc, 25934 }, /* udiaeresis */ - { 0x000000fd, 29032 }, /* yacute */ - { 0x000000fe, 25511 }, /* thorn */ - { 0x000000ff, 29083 }, /* ydiaeresis */ - { 0x000001a1, 918 }, /* Aogonek */ - { 0x000001a2, 8383 }, /* breve */ - { 0x000001a3, 19517 }, /* Lstroke */ - { 0x000001a5, 19212 }, /* Lcaron */ - { 0x000001a6, 22603 }, /* Sacute */ - { 0x000001a9, 22617 }, /* Scaron */ - { 0x000001aa, 22631 }, /* Scedilla */ - { 0x000001ab, 24322 }, /* Tcaron */ - { 0x000001ac, 29173 }, /* Zacute */ - { 0x000001ae, 29187 }, /* Zcaron */ - { 0x000001af, 29153 }, /* Zabovedot */ - { 0x000001b1, 926 }, /* aogonek */ - { 0x000001b2, 20520 }, /* ogonek */ - { 0x000001b3, 19525 }, /* lstroke */ - { 0x000001b5, 19219 }, /* lcaron */ - { 0x000001b6, 22610 }, /* sacute */ - { 0x000001b7, 8519 }, /* caron */ - { 0x000001b9, 22624 }, /* scaron */ - { 0x000001ba, 22640 }, /* scedilla */ - { 0x000001bb, 24329 }, /* tcaron */ - { 0x000001bc, 29180 }, /* zacute */ - { 0x000001bd, 11283 }, /* doubleacute */ - { 0x000001be, 29194 }, /* zcaron */ - { 0x000001bf, 29163 }, /* zabovedot */ - { 0x000001c0, 22272 }, /* Racute */ - { 0x000001c3, 445 }, /* Abreve */ - { 0x000001c5, 19147 }, /* Lacute */ - { 0x000001c6, 8475 }, /* Cacute */ - { 0x000001c8, 8525 }, /* Ccaron */ - { 0x000001ca, 12035 }, /* Eogonek */ - { 0x000001cc, 11482 }, /* Ecaron */ - { 0x000001cf, 10365 }, /* Dcaron */ - { 0x000001d0, 11401 }, /* Dstroke */ - { 0x000001d1, 19953 }, /* Nacute */ - { 0x000001d2, 19977 }, /* Ncaron */ - { 0x000001d5, 20488 }, /* Odoubleacute */ - { 0x000001d8, 22294 }, /* Rcaron */ - { 0x000001d9, 26452 }, /* Uring */ - { 0x000001db, 25945 }, /* Udoubleacute */ - { 0x000001de, 24336 }, /* Tcedilla */ - { 0x000001e0, 22279 }, /* racute */ - { 0x000001e3, 452 }, /* abreve */ - { 0x000001e5, 19154 }, /* lacute */ - { 0x000001e6, 8482 }, /* cacute */ - { 0x000001e8, 8532 }, /* ccaron */ - { 0x000001ea, 12043 }, /* eogonek */ - { 0x000001ec, 11489 }, /* ecaron */ - { 0x000001ef, 10372 }, /* dcaron */ - { 0x000001f0, 11409 }, /* dstroke */ - { 0x000001f1, 19960 }, /* nacute */ - { 0x000001f2, 19984 }, /* ncaron */ - { 0x000001f5, 20501 }, /* odoubleacute */ - { 0x000001f8, 22301 }, /* rcaron */ - { 0x000001f9, 26458 }, /* uring */ - { 0x000001fb, 25958 }, /* udoubleacute */ - { 0x000001fe, 24345 }, /* tcedilla */ - { 0x000001ff, 436 }, /* abovedot */ - { 0x000002a1, 17027 }, /* Hstroke */ - { 0x000002a6, 16056 }, /* Hcircumflex */ - { 0x000002a9, 17073 }, /* Iabovedot */ - { 0x000002ab, 12689 }, /* Gbreve */ - { 0x000002ac, 18118 }, /* Jcircumflex */ - { 0x000002b1, 17035 }, /* hstroke */ - { 0x000002b6, 16068 }, /* hcircumflex */ - { 0x000002b9, 17187 }, /* idotless */ - { 0x000002bb, 12696 }, /* gbreve */ - { 0x000002bc, 18130 }, /* jcircumflex */ - { 0x000002c5, 8455 }, /* Cabovedot */ - { 0x000002c6, 8557 }, /* Ccircumflex */ - { 0x000002d5, 12669 }, /* Gabovedot */ - { 0x000002d8, 12735 }, /* Gcircumflex */ - { 0x000002dd, 25885 }, /* Ubreve */ - { 0x000002de, 22661 }, /* Scircumflex */ - { 0x000002e5, 8465 }, /* cabovedot */ - { 0x000002e6, 8569 }, /* ccircumflex */ - { 0x000002f5, 12679 }, /* gabovedot */ - { 0x000002f8, 12747 }, /* gcircumflex */ - { 0x000002fd, 25892 }, /* ubreve */ - { 0x000002fe, 22673 }, /* scircumflex */ - { 0x000003a2, 19108 }, /* kra */ - { 0x000003a3, 22308 }, /* Rcedilla */ - { 0x000003a5, 18100 }, /* Itilde */ - { 0x000003a6, 19226 }, /* Lcedilla */ - { 0x000003aa, 11839 }, /* Emacron */ - { 0x000003ab, 12717 }, /* Gcedilla */ - { 0x000003ac, 25788 }, /* Tslash */ - { 0x000003b3, 22317 }, /* rcedilla */ - { 0x000003b5, 18107 }, /* itilde */ - { 0x000003b6, 19235 }, /* lcedilla */ - { 0x000003ba, 11847 }, /* emacron */ - { 0x000003bb, 12726 }, /* gcedilla */ - { 0x000003bc, 25795 }, /* tslash */ - { 0x000003bd, 11983 }, /* ENG */ - { 0x000003bf, 11987 }, /* eng */ - { 0x000003c0, 892 }, /* Amacron */ - { 0x000003c7, 17338 }, /* Iogonek */ - { 0x000003cc, 11428 }, /* Eabovedot */ - { 0x000003cf, 17231 }, /* Imacron */ - { 0x000003d1, 19991 }, /* Ncedilla */ - { 0x000003d2, 20679 }, /* Omacron */ - { 0x000003d3, 18779 }, /* Kcedilla */ - { 0x000003d9, 26368 }, /* Uogonek */ - { 0x000003dd, 26469 }, /* Utilde */ - { 0x000003de, 26321 }, /* Umacron */ - { 0x000003e0, 900 }, /* amacron */ - { 0x000003e7, 17346 }, /* iogonek */ - { 0x000003ec, 11438 }, /* eabovedot */ - { 0x000003ef, 17239 }, /* imacron */ - { 0x000003f1, 20000 }, /* ncedilla */ - { 0x000003f2, 20687 }, /* omacron */ - { 0x000003f3, 18788 }, /* kcedilla */ - { 0x000003f9, 26376 }, /* uogonek */ - { 0x000003fd, 26476 }, /* utilde */ - { 0x000003fe, 26329 }, /* umacron */ - { 0x0000047e, 21364 }, /* overline */ - { 0x000004a1, 18243 }, /* kana_fullstop */ - { 0x000004a2, 18477 }, /* kana_openingbracket */ - { 0x000004a3, 18173 }, /* kana_closingbracket */ - { 0x000004a4, 18193 }, /* kana_comma */ - { 0x000004a5, 18204 }, /* kana_conjunctive */ - { 0x000004a6, 18689 }, /* kana_WO */ - { 0x000004a7, 18150 }, /* kana_a */ - { 0x000004a8, 18297 }, /* kana_i */ - { 0x000004a9, 18667 }, /* kana_u */ - { 0x000004aa, 18221 }, /* kana_e */ - { 0x000004ab, 18463 }, /* kana_o */ - { 0x000004ac, 18697 }, /* kana_ya */ - { 0x000004ad, 18729 }, /* kana_yu */ - { 0x000004ae, 18713 }, /* kana_yo */ - { 0x000004af, 18633 }, /* kana_tsu */ - { 0x000004b0, 22130 }, /* prolongedsound */ - { 0x000004b1, 18157 }, /* kana_A */ - { 0x000004b2, 18304 }, /* kana_I */ - { 0x000004b3, 18674 }, /* kana_U */ - { 0x000004b4, 18228 }, /* kana_E */ - { 0x000004b5, 18470 }, /* kana_O */ - { 0x000004b6, 18311 }, /* kana_KA */ - { 0x000004b7, 18327 }, /* kana_KI */ - { 0x000004b8, 18343 }, /* kana_KU */ - { 0x000004b9, 18319 }, /* kana_KE */ - { 0x000004ba, 18335 }, /* kana_KO */ - { 0x000004bb, 18537 }, /* kana_SA */ - { 0x000004bc, 18553 }, /* kana_SHI */ - { 0x000004bd, 18581 }, /* kana_SU */ - { 0x000004be, 18545 }, /* kana_SE */ - { 0x000004bf, 18573 }, /* kana_SO */ - { 0x000004c0, 18601 }, /* kana_TA */ - { 0x000004c1, 18164 }, /* kana_CHI */ - { 0x000004c2, 18642 }, /* kana_TSU */ - { 0x000004c3, 18609 }, /* kana_TE */ - { 0x000004c4, 18625 }, /* kana_TO */ - { 0x000004c5, 18423 }, /* kana_NA */ - { 0x000004c6, 18439 }, /* kana_NI */ - { 0x000004c7, 18455 }, /* kana_NU */ - { 0x000004c8, 18431 }, /* kana_NE */ - { 0x000004c9, 18447 }, /* kana_NO */ - { 0x000004ca, 18257 }, /* kana_HA */ - { 0x000004cb, 18273 }, /* kana_HI */ - { 0x000004cc, 18235 }, /* kana_FU */ - { 0x000004cd, 18265 }, /* kana_HE */ - { 0x000004ce, 18281 }, /* kana_HO */ - { 0x000004cf, 18361 }, /* kana_MA */ - { 0x000004d0, 18377 }, /* kana_MI */ - { 0x000004d1, 18408 }, /* kana_MU */ - { 0x000004d2, 18369 }, /* kana_ME */ - { 0x000004d3, 18400 }, /* kana_MO */ - { 0x000004d4, 18705 }, /* kana_YA */ - { 0x000004d5, 18737 }, /* kana_YU */ - { 0x000004d6, 18721 }, /* kana_YO */ - { 0x000004d7, 18497 }, /* kana_RA */ - { 0x000004d8, 18513 }, /* kana_RI */ - { 0x000004d9, 18529 }, /* kana_RU */ - { 0x000004da, 18505 }, /* kana_RE */ - { 0x000004db, 18521 }, /* kana_RO */ - { 0x000004dc, 18681 }, /* kana_WA */ - { 0x000004dd, 18416 }, /* kana_N */ - { 0x000004de, 26519 }, /* voicedsound */ - { 0x000004df, 22744 }, /* semivoicedsound */ - { 0x000005ac, 1109 }, /* Arabic_comma */ - { 0x000005bb, 1764 }, /* Arabic_semicolon */ - { 0x000005bf, 1698 }, /* Arabic_question_mark */ - { 0x000005c1, 1303 }, /* Arabic_hamza */ - { 0x000005c2, 1599 }, /* Arabic_maddaonalef */ - { 0x000005c3, 1354 }, /* Arabic_hamzaonalef */ - { 0x000005c4, 1373 }, /* Arabic_hamzaonwaw */ - { 0x000005c5, 1409 }, /* Arabic_hamzaunderalef */ - { 0x000005c6, 1391 }, /* Arabic_hamzaonyeh */ - { 0x000005c7, 1067 }, /* Arabic_alef */ - { 0x000005c8, 1098 }, /* Arabic_beh */ - { 0x000005c9, 1909 }, /* Arabic_tehmarbuta */ - { 0x000005ca, 1898 }, /* Arabic_teh */ - { 0x000005cb, 1939 }, /* Arabic_theh */ - { 0x000005cc, 1481 }, /* Arabic_jeem */ - { 0x000005cd, 1292 }, /* Arabic_hah */ - { 0x000005ce, 1557 }, /* Arabic_khah */ - { 0x000005cf, 1133 }, /* Arabic_dal */ - { 0x000005d0, 1927 }, /* Arabic_thal */ - { 0x000005d1, 1719 }, /* Arabic_ra */ - { 0x000005d2, 2024 }, /* Arabic_zain */ - { 0x000005d3, 1752 }, /* Arabic_seen */ - { 0x000005d4, 1795 }, /* Arabic_sheen */ - { 0x000005d5, 1741 }, /* Arabic_sad */ - { 0x000005d6, 1122 }, /* Arabic_dad */ - { 0x000005d7, 1859 }, /* Arabic_tah */ - { 0x000005d8, 2013 }, /* Arabic_zah */ - { 0x000005d9, 1056 }, /* Arabic_ain */ - { 0x000005da, 1269 }, /* Arabic_ghain */ - { 0x000005e0, 1870 }, /* Arabic_tatweel */ - { 0x000005e1, 1231 }, /* Arabic_feh */ - { 0x000005e2, 1687 }, /* Arabic_qaf */ - { 0x000005e3, 1504 }, /* Arabic_kaf */ - { 0x000005e4, 1569 }, /* Arabic_lam */ - { 0x000005e5, 1618 }, /* Arabic_meem */ - { 0x000005e6, 1630 }, /* Arabic_noon */ - { 0x000005e7, 1282 }, /* Arabic_ha */ - { 0x000005e8, 1974 }, /* Arabic_waw */ - { 0x000005e9, 1079 }, /* Arabic_alefmaksura */ - { 0x000005ea, 1985 }, /* Arabic_yeh */ - { 0x000005eb, 1215 }, /* Arabic_fathatan */ - { 0x000005ec, 1157 }, /* Arabic_dammatan */ - { 0x000005ed, 1528 }, /* Arabic_kasratan */ - { 0x000005ee, 1202 }, /* Arabic_fatha */ - { 0x000005ef, 1144 }, /* Arabic_damma */ - { 0x000005f0, 1515 }, /* Arabic_kasra */ - { 0x000005f1, 1781 }, /* Arabic_shadda */ - { 0x000005f2, 1808 }, /* Arabic_sukun */ - { 0x000006a1, 22760 }, /* Serbian_dje */ - { 0x000006a2, 19585 }, /* Macedonia_gje */ - { 0x000006a3, 9456 }, /* Cyrillic_io */ - { 0x000006a4, 26199 }, /* Ukrainian_ie */ - { 0x000006a5, 19557 }, /* Macedonia_dse */ - { 0x000006a6, 26175 }, /* Ukrainian_i */ - { 0x000006a7, 26225 }, /* Ukrainian_yi */ - { 0x000006a8, 9480 }, /* Cyrillic_je */ - { 0x000006a9, 9618 }, /* Cyrillic_lje */ - { 0x000006aa, 9644 }, /* Cyrillic_nje */ - { 0x000006ab, 22878 }, /* Serbian_tshe */ - { 0x000006ac, 19613 }, /* Macedonia_kje */ - { 0x000006ad, 26123 }, /* Ukrainian_ghe_with_upturn */ - { 0x000006ae, 8399 }, /* Byelorussian_shortu */ - { 0x000006af, 8972 }, /* Cyrillic_dzhe */ - { 0x000006b0, 20189 }, /* numerosign */ - { 0x000006b1, 22772 }, /* Serbian_DJE */ - { 0x000006b2, 19599 }, /* Macedonia_GJE */ - { 0x000006b3, 9468 }, /* Cyrillic_IO */ - { 0x000006b4, 26212 }, /* Ukrainian_IE */ - { 0x000006b5, 19571 }, /* Macedonia_DSE */ - { 0x000006b6, 26187 }, /* Ukrainian_I */ - { 0x000006b7, 26238 }, /* Ukrainian_YI */ - { 0x000006b8, 9492 }, /* Cyrillic_JE */ - { 0x000006b9, 9631 }, /* Cyrillic_LJE */ - { 0x000006ba, 9657 }, /* Cyrillic_NJE */ - { 0x000006bb, 22891 }, /* Serbian_TSHE */ - { 0x000006bc, 19627 }, /* Macedonia_KJE */ - { 0x000006bd, 26149 }, /* Ukrainian_GHE_WITH_UPTURN */ - { 0x000006be, 8419 }, /* Byelorussian_SHORTU */ - { 0x000006bf, 8986 }, /* Cyrillic_DZHE */ - { 0x000006c0, 10200 }, /* Cyrillic_yu */ - { 0x000006c1, 8782 }, /* Cyrillic_a */ - { 0x000006c2, 8804 }, /* Cyrillic_be */ - { 0x000006c3, 9952 }, /* Cyrillic_tse */ - { 0x000006c4, 8948 }, /* Cyrillic_de */ - { 0x000006c5, 9432 }, /* Cyrillic_ie */ - { 0x000006c6, 9022 }, /* Cyrillic_ef */ - { 0x000006c7, 9210 }, /* Cyrillic_ghe */ - { 0x000006c8, 9270 }, /* Cyrillic_ha */ - { 0x000006c9, 9374 }, /* Cyrillic_i */ - { 0x000006ca, 9860 }, /* Cyrillic_shorti */ - { 0x000006cb, 9504 }, /* Cyrillic_ka */ - { 0x000006cc, 9046 }, /* Cyrillic_el */ - { 0x000006cd, 9070 }, /* Cyrillic_em */ - { 0x000006ce, 9094 }, /* Cyrillic_en */ - { 0x000006cf, 9670 }, /* Cyrillic_o */ - { 0x000006d0, 9722 }, /* Cyrillic_pe */ - { 0x000006d1, 10148 }, /* Cyrillic_ya */ - { 0x000006d2, 9162 }, /* Cyrillic_er */ - { 0x000006d3, 9186 }, /* Cyrillic_es */ - { 0x000006d4, 9928 }, /* Cyrillic_te */ - { 0x000006d5, 9978 }, /* Cyrillic_u */ - { 0x000006d6, 10248 }, /* Cyrillic_zhe */ - { 0x000006d7, 10124 }, /* Cyrillic_ve */ - { 0x000006d8, 9892 }, /* Cyrillic_softsign */ - { 0x000006d9, 10172 }, /* Cyrillic_yeru */ - { 0x000006da, 10224 }, /* Cyrillic_ze */ - { 0x000006db, 9776 }, /* Cyrillic_sha */ - { 0x000006dc, 9000 }, /* Cyrillic_e */ - { 0x000006dd, 9802 }, /* Cyrillic_shcha */ - { 0x000006de, 8828 }, /* Cyrillic_che */ - { 0x000006df, 9338 }, /* Cyrillic_hardsign */ - { 0x000006e0, 10212 }, /* Cyrillic_YU */ - { 0x000006e1, 8793 }, /* Cyrillic_A */ - { 0x000006e2, 8816 }, /* Cyrillic_BE */ - { 0x000006e3, 9965 }, /* Cyrillic_TSE */ - { 0x000006e4, 8960 }, /* Cyrillic_DE */ - { 0x000006e5, 9444 }, /* Cyrillic_IE */ - { 0x000006e6, 9034 }, /* Cyrillic_EF */ - { 0x000006e7, 9223 }, /* Cyrillic_GHE */ - { 0x000006e8, 9282 }, /* Cyrillic_HA */ - { 0x000006e9, 9385 }, /* Cyrillic_I */ - { 0x000006ea, 9876 }, /* Cyrillic_SHORTI */ - { 0x000006eb, 9516 }, /* Cyrillic_KA */ - { 0x000006ec, 9058 }, /* Cyrillic_EL */ - { 0x000006ed, 9082 }, /* Cyrillic_EM */ - { 0x000006ee, 9106 }, /* Cyrillic_EN */ - { 0x000006ef, 9681 }, /* Cyrillic_O */ - { 0x000006f0, 9734 }, /* Cyrillic_PE */ - { 0x000006f1, 10160 }, /* Cyrillic_YA */ - { 0x000006f2, 9174 }, /* Cyrillic_ER */ - { 0x000006f3, 9198 }, /* Cyrillic_ES */ - { 0x000006f4, 9940 }, /* Cyrillic_TE */ - { 0x000006f5, 9989 }, /* Cyrillic_U */ - { 0x000006f6, 10261 }, /* Cyrillic_ZHE */ - { 0x000006f7, 10136 }, /* Cyrillic_VE */ - { 0x000006f8, 9910 }, /* Cyrillic_SOFTSIGN */ - { 0x000006f9, 10186 }, /* Cyrillic_YERU */ - { 0x000006fa, 10236 }, /* Cyrillic_ZE */ - { 0x000006fb, 9789 }, /* Cyrillic_SHA */ - { 0x000006fc, 9011 }, /* Cyrillic_E */ - { 0x000006fd, 9817 }, /* Cyrillic_SHCHA */ - { 0x000006fe, 8841 }, /* Cyrillic_CHE */ - { 0x000006ff, 9356 }, /* Cyrillic_HARDSIGN */ - { 0x000007a1, 13342 }, /* Greek_ALPHAaccent */ - { 0x000007a2, 13472 }, /* Greek_EPSILONaccent */ - { 0x000007a3, 13532 }, /* Greek_ETAaccent */ - { 0x000007a4, 13647 }, /* Greek_IOTAaccent */ - { 0x000007a5, 13726 }, /* Greek_IOTAdieresis */ - { 0x000007a7, 13962 }, /* Greek_OMICRONaccent */ - { 0x000007a8, 14189 }, /* Greek_UPSILONaccent */ - { 0x000007a9, 14257 }, /* Greek_UPSILONdieresis */ - { 0x000007ab, 13898 }, /* Greek_OMEGAaccent */ - { 0x000007ae, 13297 }, /* Greek_accentdieresis */ - { 0x000007af, 13610 }, /* Greek_horizbar */ - { 0x000007b1, 13360 }, /* Greek_alphaaccent */ - { 0x000007b2, 13492 }, /* Greek_epsilonaccent */ - { 0x000007b3, 13548 }, /* Greek_etaaccent */ - { 0x000007b4, 13664 }, /* Greek_iotaaccent */ - { 0x000007b5, 13745 }, /* Greek_iotadieresis */ - { 0x000007b6, 13681 }, /* Greek_iotaaccentdieresis */ - { 0x000007b7, 13982 }, /* Greek_omicronaccent */ - { 0x000007b8, 14209 }, /* Greek_upsilonaccent */ - { 0x000007b9, 14279 }, /* Greek_upsilondieresis */ - { 0x000007ba, 14229 }, /* Greek_upsilonaccentdieresis */ - { 0x000007bb, 13916 }, /* Greek_omegaaccent */ - { 0x000007c1, 13318 }, /* Greek_ALPHA */ - { 0x000007c2, 13378 }, /* Greek_BETA */ - { 0x000007c3, 13586 }, /* Greek_GAMMA */ - { 0x000007c4, 13420 }, /* Greek_DELTA */ - { 0x000007c5, 13444 }, /* Greek_EPSILON */ - { 0x000007c6, 14319 }, /* Greek_ZETA */ - { 0x000007c7, 13512 }, /* Greek_ETA */ - { 0x000007c8, 14137 }, /* Greek_THETA */ - { 0x000007c9, 13625 }, /* Greek_IOTA */ - { 0x000007ca, 13764 }, /* Greek_KAPPA */ - { 0x000007cb, 13814 }, /* Greek_LAMDA */ - { 0x000007cc, 13838 }, /* Greek_MU */ - { 0x000007cd, 13856 }, /* Greek_NU */ - { 0x000007ce, 14301 }, /* Greek_XI */ - { 0x000007cf, 13934 }, /* Greek_OMICRON */ - { 0x000007d0, 14022 }, /* Greek_PI */ - { 0x000007d1, 14060 }, /* Greek_RHO */ - { 0x000007d2, 14080 }, /* Greek_SIGMA */ - { 0x000007d4, 14117 }, /* Greek_TAU */ - { 0x000007d5, 14161 }, /* Greek_UPSILON */ - { 0x000007d6, 14002 }, /* Greek_PHI */ - { 0x000007d7, 13400 }, /* Greek_CHI */ - { 0x000007d8, 14040 }, /* Greek_PSI */ - { 0x000007d9, 13874 }, /* Greek_OMEGA */ - { 0x000007e1, 13330 }, /* Greek_alpha */ - { 0x000007e2, 13389 }, /* Greek_beta */ - { 0x000007e3, 13598 }, /* Greek_gamma */ - { 0x000007e4, 13432 }, /* Greek_delta */ - { 0x000007e5, 13458 }, /* Greek_epsilon */ - { 0x000007e6, 14330 }, /* Greek_zeta */ - { 0x000007e7, 13522 }, /* Greek_eta */ - { 0x000007e8, 14149 }, /* Greek_theta */ - { 0x000007e9, 13636 }, /* Greek_iota */ - { 0x000007ea, 13776 }, /* Greek_kappa */ - { 0x000007eb, 13826 }, /* Greek_lamda */ - { 0x000007ec, 13847 }, /* Greek_mu */ - { 0x000007ed, 13865 }, /* Greek_nu */ - { 0x000007ee, 14310 }, /* Greek_xi */ - { 0x000007ef, 13948 }, /* Greek_omicron */ - { 0x000007f0, 14031 }, /* Greek_pi */ - { 0x000007f1, 14070 }, /* Greek_rho */ - { 0x000007f2, 14092 }, /* Greek_sigma */ - { 0x000007f3, 13564 }, /* Greek_finalsmallsigma */ - { 0x000007f4, 14127 }, /* Greek_tau */ - { 0x000007f5, 14175 }, /* Greek_upsilon */ - { 0x000007f6, 14012 }, /* Greek_phi */ - { 0x000007f7, 13410 }, /* Greek_chi */ - { 0x000007f8, 14050 }, /* Greek_psi */ - { 0x000007f9, 13886 }, /* Greek_omega */ - { 0x000008a1, 19356 }, /* leftradical */ - { 0x000008a2, 25621 }, /* topleftradical */ - { 0x000008a3, 16667 }, /* horizconnector */ - { 0x000008a4, 25595 }, /* topintegral */ - { 0x000008a5, 3422 }, /* botintegral */ - { 0x000008a6, 26505 }, /* vertconnector */ - { 0x000008a7, 25636 }, /* topleftsqbracket */ - { 0x000008a8, 3448 }, /* botleftsqbracket */ - { 0x000008a9, 25685 }, /* toprightsqbracket */ - { 0x000008aa, 3497 }, /* botrightsqbracket */ - { 0x000008ab, 25607 }, /* topleftparens */ - { 0x000008ac, 3434 }, /* botleftparens */ - { 0x000008ad, 25670 }, /* toprightparens */ - { 0x000008ae, 3482 }, /* botrightparens */ - { 0x000008af, 19306 }, /* leftmiddlecurlybrace */ - { 0x000008b0, 22440 }, /* rightmiddlecurlybrace */ - { 0x000008b1, 25653 }, /* topleftsummation */ - { 0x000008b2, 3465 }, /* botleftsummation */ - { 0x000008b3, 25726 }, /* topvertsummationconnector */ - { 0x000008b4, 3538 }, /* botvertsummationconnector */ - { 0x000008b5, 25703 }, /* toprightsummation */ - { 0x000008b6, 3515 }, /* botrightsummation */ - { 0x000008b7, 22462 }, /* rightmiddlesummation */ - { 0x000008bc, 19417 }, /* lessthanequal */ - { 0x000008bd, 20125 }, /* notequal */ - { 0x000008be, 13280 }, /* greaterthanequal */ - { 0x000008bf, 17313 }, /* integral */ - { 0x000008c0, 25479 }, /* therefore */ - { 0x000008c1, 26487 }, /* variation */ - { 0x000008c2, 17275 }, /* infinity */ - { 0x000008c5, 19947 }, /* nabla */ - { 0x000008c8, 954 }, /* approximate */ - { 0x000008c9, 22999 }, /* similarequal */ - { 0x000008cd, 17196 }, /* ifonlyif */ - { 0x000008ce, 17247 }, /* implies */ - { 0x000008cf, 17155 }, /* identical */ - { 0x000008d6, 22286 }, /* radical */ - { 0x000008da, 17255 }, /* includedin */ - { 0x000008db, 17266 }, /* includes */ - { 0x000008dc, 17322 }, /* intersection */ - { 0x000008dd, 26362 }, /* union */ - { 0x000008de, 19457 }, /* logicaland */ - { 0x000008df, 19468 }, /* logicalor */ - { 0x000008ef, 21463 }, /* partialderivative */ - { 0x000008f6, 12656 }, /* function */ - { 0x000008fb, 19266 }, /* leftarrow */ - { 0x000008fc, 26387 }, /* uparrow */ - { 0x000008fd, 22397 }, /* rightarrow */ - { 0x000008fe, 11332 }, /* downarrow */ - { 0x000009df, 3410 }, /* blank */ - { 0x000009e0, 23790 }, /* soliddiamond */ - { 0x000009e1, 8603 }, /* checkerboard */ - { 0x000009e2, 17043 }, /* ht */ - { 0x000009e3, 12413 }, /* ff */ - { 0x000009e4, 8727 }, /* cr */ - { 0x000009e5, 19431 }, /* lf */ - { 0x000009e8, 20075 }, /* nl */ - { 0x000009e9, 26542 }, /* vt */ - { 0x000009ea, 19502 }, /* lowrightcorner */ - { 0x000009eb, 26416 }, /* uprightcorner */ - { 0x000009ec, 26403 }, /* upleftcorner */ - { 0x000009ed, 19488 }, /* lowleftcorner */ - { 0x000009ee, 8730 }, /* crossinglines */ - { 0x000009ef, 16682 }, /* horizlinescan1 */ - { 0x000009f0, 16697 }, /* horizlinescan3 */ - { 0x000009f1, 16712 }, /* horizlinescan5 */ - { 0x000009f2, 16727 }, /* horizlinescan7 */ - { 0x000009f3, 16742 }, /* horizlinescan9 */ - { 0x000009f4, 19397 }, /* leftt */ - { 0x000009f5, 22545 }, /* rightt */ - { 0x000009f6, 3533 }, /* bott */ - { 0x000009f7, 25721 }, /* topt */ - { 0x000009f8, 26497 }, /* vertbar */ - { 0x00000aa1, 11928 }, /* emspace */ - { 0x00000aa2, 12027 }, /* enspace */ - { 0x00000aa3, 11821 }, /* em3space */ - { 0x00000aa4, 11830 }, /* em4space */ - { 0x00000aa5, 11221 }, /* digitspace */ - { 0x00000aa6, 22145 }, /* punctspace */ - { 0x00000aa7, 25489 }, /* thinspace */ - { 0x00000aa8, 14382 }, /* hairspace */ - { 0x00000aa9, 11855 }, /* emdash */ - { 0x00000aaa, 11940 }, /* endash */ - { 0x00000aac, 22987 }, /* signifblank */ - { 0x00000aae, 11812 }, /* ellipsis */ - { 0x00000aaf, 11267 }, /* doubbaselinedot */ - { 0x00000ab0, 20767 }, /* onethird */ - { 0x00000ab1, 25837 }, /* twothirds */ - { 0x00000ab2, 20705 }, /* onefifth */ - { 0x00000ab3, 25802 }, /* twofifths */ - { 0x00000ab4, 25530 }, /* threefifths */ - { 0x00000ab5, 12607 }, /* fourfifths */ - { 0x00000ab6, 20733 }, /* onesixth */ - { 0x00000ab7, 12569 }, /* fivesixths */ - { 0x00000ab8, 8506 }, /* careof */ - { 0x00000abb, 12427 }, /* figdash */ - { 0x00000abc, 19249 }, /* leftanglebracket */ - { 0x00000abd, 11140 }, /* decimalpoint */ - { 0x00000abe, 22379 }, /* rightanglebracket */ - { 0x00000abf, 19681 }, /* marker */ - { 0x00000ac3, 20695 }, /* oneeighth */ - { 0x00000ac4, 25517 }, /* threeeighths */ - { 0x00000ac5, 12557 }, /* fiveeighths */ - { 0x00000ac6, 22904 }, /* seveneighths */ - { 0x00000ac9, 25760 }, /* trademark */ - { 0x00000aca, 22973 }, /* signaturemark */ - { 0x00000acb, 25770 }, /* trademarkincircle */ - { 0x00000acc, 19327 }, /* leftopentriangle */ - { 0x00000acd, 22483 }, /* rightopentriangle */ - { 0x00000ace, 11890 }, /* emopencircle */ - { 0x00000acf, 11903 }, /* emopenrectangle */ - { 0x00000ad0, 19377 }, /* leftsinglequotemark */ - { 0x00000ad1, 22524 }, /* rightsinglequotemark */ - { 0x00000ad2, 19286 }, /* leftdoublequotemark */ - { 0x00000ad3, 22419 }, /* rightdoublequotemark */ - { 0x00000ad4, 22067 }, /* prescription */ - { 0x00000ad5, 21517 }, /* permille */ - { 0x00000ad6, 19739 }, /* minutes */ - { 0x00000ad7, 22711 }, /* seconds */ - { 0x00000ad9, 19181 }, /* latincross */ - { 0x00000ada, 16626 }, /* hexagram */ - { 0x00000adb, 12455 }, /* filledrectbullet */ - { 0x00000adc, 12435 }, /* filledlefttribullet */ - { 0x00000add, 12472 }, /* filledrighttribullet */ - { 0x00000ade, 11862 }, /* emfilledcircle */ - { 0x00000adf, 11877 }, /* emfilledrect */ - { 0x00000ae0, 11991 }, /* enopencircbullet */ - { 0x00000ae1, 12008 }, /* enopensquarebullet */ - { 0x00000ae2, 20794 }, /* openrectbullet */ - { 0x00000ae3, 20836 }, /* opentribulletup */ - { 0x00000ae4, 20818 }, /* opentribulletdown */ - { 0x00000ae5, 20809 }, /* openstar */ - { 0x00000ae6, 11947 }, /* enfilledcircbullet */ - { 0x00000ae7, 11966 }, /* enfilledsqbullet */ - { 0x00000ae8, 12513 }, /* filledtribulletup */ - { 0x00000ae9, 12493 }, /* filledtribulletdown */ - { 0x00000aea, 19344 }, /* leftpointer */ - { 0x00000aeb, 22501 }, /* rightpointer */ - { 0x00000aec, 8649 }, /* club */ - { 0x00000aed, 11213 }, /* diamond */ - { 0x00000aee, 16080 }, /* heart */ - { 0x00000af0, 19668 }, /* maltesecross */ - { 0x00000af1, 10358 }, /* dagger */ - { 0x00000af2, 11295 }, /* doubledagger */ - { 0x00000af3, 8616 }, /* checkmark */ - { 0x00000af4, 3380 }, /* ballotcross */ - { 0x00000af5, 19860 }, /* musicalsharp */ - { 0x00000af6, 19848 }, /* musicalflat */ - { 0x00000af7, 19657 }, /* malesymbol */ - { 0x00000af8, 12400 }, /* femalesymbol */ - { 0x00000af9, 24354 }, /* telephone */ - { 0x00000afa, 24364 }, /* telephonerecorder */ - { 0x00000afb, 21537 }, /* phonographcopyright */ - { 0x00000afc, 8513 }, /* caret */ - { 0x00000afd, 23028 }, /* singlelowquotemark */ - { 0x00000afe, 11308 }, /* doublelowquotemark */ - { 0x00000aff, 8775 }, /* cursor */ - { 0x00000ba3, 19276 }, /* leftcaret */ - { 0x00000ba6, 22408 }, /* rightcaret */ - { 0x00000ba8, 11342 }, /* downcaret */ - { 0x00000ba9, 26395 }, /* upcaret */ - { 0x00000bc0, 21324 }, /* overbar */ - { 0x00000bc2, 11371 }, /* downtack */ - { 0x00000bc3, 26430 }, /* upshoe */ - { 0x00000bc4, 11361 }, /* downstile */ - { 0x00000bc6, 26337 }, /* underbar */ - { 0x00000bca, 18142 }, /* jot */ - { 0x00000bcc, 22160 }, /* quad */ - { 0x00000bce, 26445 }, /* uptack */ - { 0x00000bcf, 8626 }, /* circle */ - { 0x00000bd3, 26437 }, /* upstile */ - { 0x00000bd6, 11352 }, /* downshoe */ - { 0x00000bd8, 22514 }, /* rightshoe */ - { 0x00000bda, 19368 }, /* leftshoe */ - { 0x00000bdc, 19403 }, /* lefttack */ - { 0x00000bfc, 22552 }, /* righttack */ - { 0x00000cdf, 16173 }, /* hebrew_doublelowline */ - { 0x00000ce0, 16086 }, /* hebrew_aleph */ - { 0x00000ce1, 16111 }, /* hebrew_bet */ - { 0x00000ce2, 16292 }, /* hebrew_gimel */ - { 0x00000ce3, 16146 }, /* hebrew_dalet */ - { 0x00000ce4, 16319 }, /* hebrew_he */ - { 0x00000ce5, 16531 }, /* hebrew_waw */ - { 0x00000ce6, 16577 }, /* hebrew_zain */ - { 0x00000ce7, 16134 }, /* hebrew_chet */ - { 0x00000ce8, 16508 }, /* hebrew_tet */ - { 0x00000ce9, 16542 }, /* hebrew_yod */ - { 0x00000cea, 16194 }, /* hebrew_finalkaph */ - { 0x00000ceb, 16340 }, /* hebrew_kaph */ - { 0x00000cec, 16363 }, /* hebrew_lamed */ - { 0x00000ced, 16211 }, /* hebrew_finalmem */ - { 0x00000cee, 16376 }, /* hebrew_mem */ - { 0x00000cef, 16227 }, /* hebrew_finalnun */ - { 0x00000cf0, 16387 }, /* hebrew_nun */ - { 0x00000cf1, 16432 }, /* hebrew_samech */ - { 0x00000cf2, 16099 }, /* hebrew_ayin */ - { 0x00000cf3, 16243 }, /* hebrew_finalpe */ - { 0x00000cf4, 16398 }, /* hebrew_pe */ - { 0x00000cf5, 16258 }, /* hebrew_finalzade */ - { 0x00000cf6, 16553 }, /* hebrew_zade */ - { 0x00000cf7, 16408 }, /* hebrew_qoph */ - { 0x00000cf8, 16420 }, /* hebrew_resh */ - { 0x00000cf9, 16460 }, /* hebrew_shin */ - { 0x00000cfa, 16497 }, /* hebrew_taw */ - { 0x00000da1, 24617 }, /* Thai_kokai */ - { 0x00000da2, 24547 }, /* Thai_khokhai */ - { 0x00000da3, 24573 }, /* Thai_khokhuat */ - { 0x00000da4, 24587 }, /* Thai_khokhwai */ - { 0x00000da5, 24560 }, /* Thai_khokhon */ - { 0x00000da6, 24601 }, /* Thai_khorakhang */ - { 0x00000da7, 24930 }, /* Thai_ngongu */ - { 0x00000da8, 24423 }, /* Thai_chochan */ - { 0x00000da9, 24450 }, /* Thai_choching */ - { 0x00000daa, 24436 }, /* Thai_chochang */ - { 0x00000dab, 25291 }, /* Thai_soso */ - { 0x00000dac, 24464 }, /* Thai_chochoe */ - { 0x00000dad, 25467 }, /* Thai_yoying */ - { 0x00000dae, 24477 }, /* Thai_dochada */ - { 0x00000daf, 25420 }, /* Thai_topatak */ - { 0x00000db0, 25379 }, /* Thai_thothan */ - { 0x00000db1, 25329 }, /* Thai_thonangmontho */ - { 0x00000db2, 25348 }, /* Thai_thophuthao */ - { 0x00000db3, 24956 }, /* Thai_nonen */ - { 0x00000db4, 24490 }, /* Thai_dodek */ - { 0x00000db5, 25433 }, /* Thai_totao */ - { 0x00000db6, 25406 }, /* Thai_thothung */ - { 0x00000db7, 25364 }, /* Thai_thothahan */ - { 0x00000db8, 25392 }, /* Thai_thothong */ - { 0x00000db9, 24967 }, /* Thai_nonu */ - { 0x00000dba, 24409 }, /* Thai_bobaimai */ - { 0x00000dbb, 25058 }, /* Thai_popla */ - { 0x00000dbc, 25028 }, /* Thai_phophung */ - { 0x00000dbd, 24501 }, /* Thai_fofa */ - { 0x00000dbe, 25015 }, /* Thai_phophan */ - { 0x00000dbf, 24511 }, /* Thai_fofan */ - { 0x00000dc0, 25042 }, /* Thai_phosamphao */ - { 0x00000dc1, 24920 }, /* Thai_moma */ - { 0x00000dc2, 25456 }, /* Thai_yoyak */ - { 0x00000dc3, 25069 }, /* Thai_rorua */ - { 0x00000dc4, 25080 }, /* Thai_ru */ - { 0x00000dc5, 24780 }, /* Thai_loling */ - { 0x00000dc6, 24792 }, /* Thai_lu */ - { 0x00000dc7, 25444 }, /* Thai_wowaen */ - { 0x00000dc8, 25279 }, /* Thai_sosala */ - { 0x00000dc9, 25267 }, /* Thai_sorusi */ - { 0x00000dca, 25301 }, /* Thai_sosua */ - { 0x00000dcb, 24522 }, /* Thai_hohip */ - { 0x00000dcc, 24767 }, /* Thai_lochula */ - { 0x00000dcd, 24977 }, /* Thai_oang */ - { 0x00000dce, 24533 }, /* Thai_honokhuk */ - { 0x00000dcf, 24987 }, /* Thai_paiyannoi */ - { 0x00000dd0, 25088 }, /* Thai_saraa */ - { 0x00000dd1, 24828 }, /* Thai_maihanakat */ - { 0x00000dd2, 25099 }, /* Thai_saraaa */ - { 0x00000dd3, 25162 }, /* Thai_saraam */ - { 0x00000dd4, 25185 }, /* Thai_sarai */ - { 0x00000dd5, 25196 }, /* Thai_saraii */ - { 0x00000dd6, 25230 }, /* Thai_saraue */ - { 0x00000dd7, 25242 }, /* Thai_sarauee */ - { 0x00000dd8, 25219 }, /* Thai_sarau */ - { 0x00000dd9, 25255 }, /* Thai_sarauu */ - { 0x00000dda, 25002 }, /* Thai_phinthu */ - { 0x00000dde, 24844 }, /* Thai_maihanakat_maitho */ - { 0x00000ddf, 24399 }, /* Thai_baht */ - { 0x00000de0, 25174 }, /* Thai_sarae */ - { 0x00000de1, 25111 }, /* Thai_saraae */ - { 0x00000de2, 25208 }, /* Thai_sarao */ - { 0x00000de3, 25143 }, /* Thai_saraaimaimuan */ - { 0x00000de4, 25123 }, /* Thai_saraaimaimalai */ - { 0x00000de5, 24628 }, /* Thai_lakkhangyao */ - { 0x00000de6, 24906 }, /* Thai_maiyamok */ - { 0x00000de7, 24867 }, /* Thai_maitaikhu */ - { 0x00000de8, 24817 }, /* Thai_maiek */ - { 0x00000de9, 24882 }, /* Thai_maitho */ - { 0x00000dea, 24894 }, /* Thai_maitri */ - { 0x00000deb, 24800 }, /* Thai_maichattawa */ - { 0x00000dec, 25312 }, /* Thai_thanthakhat */ - { 0x00000ded, 24942 }, /* Thai_nikhahit */ - { 0x00000df0, 24755 }, /* Thai_leksun */ - { 0x00000df1, 24693 }, /* Thai_leknung */ - { 0x00000df2, 24742 }, /* Thai_leksong */ - { 0x00000df3, 24719 }, /* Thai_leksam */ - { 0x00000df4, 24731 }, /* Thai_leksi */ - { 0x00000df5, 24658 }, /* Thai_lekha */ - { 0x00000df6, 24669 }, /* Thai_lekhok */ - { 0x00000df7, 24645 }, /* Thai_lekchet */ - { 0x00000df8, 24706 }, /* Thai_lekpaet */ - { 0x00000df9, 24681 }, /* Thai_lekkao */ - { 0x00000ea1, 15181 }, /* Hangul_Kiyeog */ - { 0x00000ea2, 15726 }, /* Hangul_SsangKiyeog */ - { 0x00000ea3, 15195 }, /* Hangul_KiyeogSios */ - { 0x00000ea4, 15276 }, /* Hangul_Nieun */ - { 0x00000ea5, 15307 }, /* Hangul_NieunJieuj */ - { 0x00000ea6, 15289 }, /* Hangul_NieunHieuh */ - { 0x00000ea7, 14488 }, /* Hangul_Dikeud */ - { 0x00000ea8, 15689 }, /* Hangul_SsangDikeud */ - { 0x00000ea9, 15461 }, /* Hangul_Rieul */ - { 0x00000eaa, 15492 }, /* Hangul_RieulKiyeog */ - { 0x00000eab, 15511 }, /* Hangul_RieulMieum */ - { 0x00000eac, 15548 }, /* Hangul_RieulPieub */ - { 0x00000ead, 15566 }, /* Hangul_RieulSios */ - { 0x00000eae, 15583 }, /* Hangul_RieulTieut */ - { 0x00000eaf, 15529 }, /* Hangul_RieulPhieuf */ - { 0x00000eb0, 15474 }, /* Hangul_RieulHieuh */ - { 0x00000eb1, 15238 }, /* Hangul_Mieum */ - { 0x00000eb2, 15373 }, /* Hangul_Pieub */ - { 0x00000eb3, 15745 }, /* Hangul_SsangPieub */ - { 0x00000eb4, 15386 }, /* Hangul_PieubSios */ - { 0x00000eb5, 15662 }, /* Hangul_Sios */ - { 0x00000eb6, 15763 }, /* Hangul_SsangSios */ - { 0x00000eb7, 14577 }, /* Hangul_Ieung */ - { 0x00000eb8, 15154 }, /* Hangul_Jieuj */ - { 0x00000eb9, 15708 }, /* Hangul_SsangJieuj */ - { 0x00000eba, 14458 }, /* Hangul_Cieuc */ - { 0x00000ebb, 15167 }, /* Hangul_Khieuq */ - { 0x00000ebc, 15883 }, /* Hangul_Tieut */ - { 0x00000ebd, 15359 }, /* Hangul_Phieuf */ - { 0x00000ebe, 14555 }, /* Hangul_Hieuh */ - { 0x00000ebf, 14399 }, /* Hangul_A */ - { 0x00000ec0, 14408 }, /* Hangul_AE */ - { 0x00000ec1, 15957 }, /* Hangul_YA */ - { 0x00000ec2, 15967 }, /* Hangul_YAE */ - { 0x00000ec3, 14522 }, /* Hangul_EO */ - { 0x00000ec4, 14502 }, /* Hangul_E */ - { 0x00000ec5, 15988 }, /* Hangul_YEO */ - { 0x00000ec6, 15978 }, /* Hangul_YE */ - { 0x00000ec7, 15325 }, /* Hangul_O */ - { 0x00000ec8, 15905 }, /* Hangul_WA */ - { 0x00000ec9, 15915 }, /* Hangul_WAE */ - { 0x00000eca, 15334 }, /* Hangul_OE */ - { 0x00000ecb, 16028 }, /* Hangul_YO */ - { 0x00000ecc, 15896 }, /* Hangul_U */ - { 0x00000ecd, 15936 }, /* Hangul_WEO */ - { 0x00000ece, 15926 }, /* Hangul_WE */ - { 0x00000ecf, 15947 }, /* Hangul_WI */ - { 0x00000ed0, 16038 }, /* Hangul_YU */ - { 0x00000ed1, 14532 }, /* Hangul_EU */ - { 0x00000ed2, 16018 }, /* Hangul_YI */ - { 0x00000ed3, 14568 }, /* Hangul_I */ - { 0x00000ed4, 14682 }, /* Hangul_J_Kiyeog */ - { 0x00000ed5, 15052 }, /* Hangul_J_SsangKiyeog */ - { 0x00000ed6, 14698 }, /* Hangul_J_KiyeogSios */ - { 0x00000ed7, 14760 }, /* Hangul_J_Nieun */ - { 0x00000ed8, 14795 }, /* Hangul_J_NieunJieuj */ - { 0x00000ed9, 14775 }, /* Hangul_J_NieunHieuh */ - { 0x00000eda, 14605 }, /* Hangul_J_Dikeud */ - { 0x00000edb, 14882 }, /* Hangul_J_Rieul */ - { 0x00000edc, 14917 }, /* Hangul_J_RieulKiyeog */ - { 0x00000edd, 14938 }, /* Hangul_J_RieulMieum */ - { 0x00000ede, 14979 }, /* Hangul_J_RieulPieub */ - { 0x00000edf, 14999 }, /* Hangul_J_RieulSios */ - { 0x00000ee0, 15018 }, /* Hangul_J_RieulTieut */ - { 0x00000ee1, 14958 }, /* Hangul_J_RieulPhieuf */ - { 0x00000ee2, 14897 }, /* Hangul_J_RieulHieuh */ - { 0x00000ee3, 14745 }, /* Hangul_J_Mieum */ - { 0x00000ee4, 14848 }, /* Hangul_J_Pieub */ - { 0x00000ee5, 14863 }, /* Hangul_J_PieubSios */ - { 0x00000ee6, 15038 }, /* Hangul_J_Sios */ - { 0x00000ee7, 15073 }, /* Hangul_J_SsangSios */ - { 0x00000ee8, 14636 }, /* Hangul_J_Ieung */ - { 0x00000ee9, 14651 }, /* Hangul_J_Jieuj */ - { 0x00000eea, 14590 }, /* Hangul_J_Cieuc */ - { 0x00000eeb, 14666 }, /* Hangul_J_Khieuq */ - { 0x00000eec, 15092 }, /* Hangul_J_Tieut */ - { 0x00000eed, 14832 }, /* Hangul_J_Phieuf */ - { 0x00000eee, 14621 }, /* Hangul_J_Hieuh */ - { 0x00000eef, 15601 }, /* Hangul_RieulYeorinHieuh */ - { 0x00000ef0, 15793 }, /* Hangul_SunkyeongeumMieum */ - { 0x00000ef1, 15844 }, /* Hangul_SunkyeongeumPieub */ - { 0x00000ef2, 15344 }, /* Hangul_PanSios */ - { 0x00000ef3, 15213 }, /* Hangul_KkogjiDalrinIeung */ - { 0x00000ef4, 15818 }, /* Hangul_SunkyeongeumPhieuf */ - { 0x00000ef5, 15999 }, /* Hangul_YeorinHieuh */ - { 0x00000ef6, 14418 }, /* Hangul_AraeA */ - { 0x00000ef7, 14431 }, /* Hangul_AraeAE */ - { 0x00000ef8, 14815 }, /* Hangul_J_PanSios */ - { 0x00000ef9, 14718 }, /* Hangul_J_KkogjiDalrinIeung */ - { 0x00000efa, 15107 }, /* Hangul_J_YeorinHieuh */ - { 0x00000eff, 18797 }, /* Korean_Won */ - { 0x000013bc, 20514 }, /* OE */ - { 0x000013bd, 20517 }, /* oe */ - { 0x000013be, 29094 }, /* Ydiaeresis */ - { 0x000020ac, 12090 }, /* EuroSign */ - { 0x0000fd01, 125 }, /* 3270_Duplicate */ - { 0x0000fd02, 195 }, /* 3270_FieldMark */ - { 0x0000fd03, 343 }, /* 3270_Right2 */ - { 0x0000fd04, 245 }, /* 3270_Left2 */ - { 0x0000fd05, 33 }, /* 3270_BackTab */ - { 0x0000fd06, 151 }, /* 3270_EraseEOF */ - { 0x0000fd07, 165 }, /* 3270_EraseInput */ - { 0x0000fd08, 332 }, /* 3270_Reset */ - { 0x0000fd09, 310 }, /* 3270_Quit */ - { 0x0000fd0a, 256 }, /* 3270_PA1 */ - { 0x0000fd0b, 265 }, /* 3270_PA2 */ - { 0x0000fd0c, 274 }, /* 3270_PA3 */ - { 0x0000fd0d, 376 }, /* 3270_Test */ - { 0x0000fd0e, 23 }, /* 3270_Attn */ - { 0x0000fd0f, 74 }, /* 3270_CursorBlink */ - { 0x0000fd10, 8 }, /* 3270_AltCursor */ - { 0x0000fd11, 231 }, /* 3270_KeyClick */ - { 0x0000fd12, 221 }, /* 3270_Jump */ - { 0x0000fd13, 210 }, /* 3270_Ident */ - { 0x0000fd14, 355 }, /* 3270_Rule */ - { 0x0000fd15, 64 }, /* 3270_Copy */ - { 0x0000fd16, 283 }, /* 3270_Play */ - { 0x0000fd17, 365 }, /* 3270_Setup */ - { 0x0000fd18, 320 }, /* 3270_Record */ - { 0x0000fd19, 46 }, /* 3270_ChangeScreen */ - { 0x0000fd1a, 109 }, /* 3270_DeleteWord */ - { 0x0000fd1b, 181 }, /* 3270_ExSelect */ - { 0x0000fd1c, 91 }, /* 3270_CursorSelect */ - { 0x0000fd1d, 293 }, /* 3270_PrintScreen */ - { 0x0000fd1e, 140 }, /* 3270_Enter */ - { 0x0000fe01, 17781 }, /* ISO_Lock */ - { 0x0000fe02, 17664 }, /* ISO_Level2_Latch */ - { 0x0000fe03, 17714 }, /* ISO_Level3_Shift */ - { 0x0000fe04, 17681 }, /* ISO_Level3_Latch */ - { 0x0000fe05, 17698 }, /* ISO_Level3_Lock */ - { 0x0000fe06, 17569 }, /* ISO_Group_Latch */ - { 0x0000fe07, 17585 }, /* ISO_Group_Lock */ - { 0x0000fe08, 17826 }, /* ISO_Next_Group */ - { 0x0000fe09, 17841 }, /* ISO_Next_Group_Lock */ - { 0x0000fe0a, 17950 }, /* ISO_Prev_Group */ - { 0x0000fe0b, 17965 }, /* ISO_Prev_Group_Lock */ - { 0x0000fe0c, 17532 }, /* ISO_First_Group */ - { 0x0000fe0d, 17548 }, /* ISO_First_Group_Lock */ - { 0x0000fe0e, 17616 }, /* ISO_Last_Group */ - { 0x0000fe0f, 17631 }, /* ISO_Last_Group_Lock */ - { 0x0000fe11, 17764 }, /* ISO_Level5_Shift */ - { 0x0000fe12, 17731 }, /* ISO_Level5_Latch */ - { 0x0000fe13, 17748 }, /* ISO_Level5_Lock */ - { 0x0000fe20, 17651 }, /* ISO_Left_Tab */ - { 0x0000fe21, 17809 }, /* ISO_Move_Line_Up */ - { 0x0000fe22, 17790 }, /* ISO_Move_Line_Down */ - { 0x0000fe23, 17883 }, /* ISO_Partial_Line_Up */ - { 0x0000fe24, 17861 }, /* ISO_Partial_Line_Down */ - { 0x0000fe25, 17903 }, /* ISO_Partial_Space_Left */ - { 0x0000fe26, 17926 }, /* ISO_Partial_Space_Right */ - { 0x0000fe27, 18059 }, /* ISO_Set_Margin_Left */ - { 0x0000fe28, 18079 }, /* ISO_Set_Margin_Right */ - { 0x0000fe29, 18010 }, /* ISO_Release_Margin_Left */ - { 0x0000fe2a, 18034 }, /* ISO_Release_Margin_Right */ - { 0x0000fe2b, 17985 }, /* ISO_Release_Both_Margins */ - { 0x0000fe2c, 17470 }, /* ISO_Fast_Cursor_Left */ - { 0x0000fe2d, 17491 }, /* ISO_Fast_Cursor_Right */ - { 0x0000fe2e, 17513 }, /* ISO_Fast_Cursor_Up */ - { 0x0000fe2f, 17449 }, /* ISO_Fast_Cursor_Down */ - { 0x0000fe30, 17372 }, /* ISO_Continuous_Underline */ - { 0x0000fe31, 17397 }, /* ISO_Discontinuous_Underline */ - { 0x0000fe32, 17425 }, /* ISO_Emphasize */ - { 0x0000fe33, 17354 }, /* ISO_Center_Object */ - { 0x0000fe34, 17439 }, /* ISO_Enter */ - { 0x0000fe50, 10858 }, /* dead_grave */ - { 0x0000fe51, 10531 }, /* dead_acute */ - { 0x0000fe52, 10754 }, /* dead_circumflex */ - { 0x0000fe53, 11097 }, /* dead_tilde */ - { 0x0000fe54, 10980 }, /* dead_macron */ - { 0x0000fe55, 10700 }, /* dead_breve */ - { 0x0000fe56, 10455 }, /* dead_abovedot */ - { 0x0000fe57, 10795 }, /* dead_diaeresis */ - { 0x0000fe58, 10493 }, /* dead_abovering */ - { 0x0000fe59, 10810 }, /* dead_doubleacute */ - { 0x0000fe5a, 10730 }, /* dead_caron */ - { 0x0000fe5b, 10741 }, /* dead_cedilla */ - { 0x0000fe5c, 11006 }, /* dead_ogonek */ - { 0x0000fe5d, 10933 }, /* dead_iota */ - { 0x0000fe5e, 11122 }, /* dead_voiced_sound */ - { 0x0000fe5f, 11046 }, /* dead_semivoiced_sound */ - { 0x0000fe60, 10615 }, /* dead_belowdot */ - { 0x0000fe61, 10880 }, /* dead_hook */ - { 0x0000fe62, 10890 }, /* dead_horn */ - { 0x0000fe63, 11085 }, /* dead_stroke */ - { 0x0000fe64, 10439 }, /* dead_abovecomma */ - { 0x0000fe65, 10469 }, /* dead_abovereversedcomma */ - { 0x0000fe66, 10827 }, /* dead_doublegrave */ - { 0x0000fe67, 10646 }, /* dead_belowring */ - { 0x0000fe68, 10629 }, /* dead_belowmacron */ - { 0x0000fe69, 10558 }, /* dead_belowcircumflex */ - { 0x0000fe6a, 10661 }, /* dead_belowtilde */ - { 0x0000fe6b, 10542 }, /* dead_belowbreve */ - { 0x0000fe6c, 10595 }, /* dead_belowdiaeresis */ - { 0x0000fe6d, 10914 }, /* dead_invertedbreve */ - { 0x0000fe6e, 10579 }, /* dead_belowcomma */ - { 0x0000fe6f, 10770 }, /* dead_currency */ - { 0x0000fe70, 583 }, /* AccessX_Enable */ - { 0x0000fe71, 598 }, /* AccessX_Feedback_Enable */ - { 0x0000fe72, 22342 }, /* RepeatKeys_Enable */ - { 0x0000fe73, 23774 }, /* SlowKeys_Enable */ - { 0x0000fe74, 3564 }, /* BounceKeys_Enable */ - { 0x0000fe75, 23836 }, /* StickyKeys_Enable */ - { 0x0000fe76, 19782 }, /* MouseKeys_Enable */ - { 0x0000fe77, 19759 }, /* MouseKeys_Accel_Enable */ - { 0x0000fe78, 21332 }, /* Overlay1_Enable */ - { 0x0000fe79, 21348 }, /* Overlay2_Enable */ - { 0x0000fe7a, 3309 }, /* AudibleBell_Enable */ - { 0x0000fe80, 10425 }, /* dead_a */ - { 0x0000fe81, 10432 }, /* dead_A */ - { 0x0000fe82, 10844 }, /* dead_e */ - { 0x0000fe83, 10851 }, /* dead_E */ - { 0x0000fe84, 10900 }, /* dead_i */ - { 0x0000fe85, 10907 }, /* dead_I */ - { 0x0000fe86, 10992 }, /* dead_o */ - { 0x0000fe87, 10999 }, /* dead_O */ - { 0x0000fe88, 11108 }, /* dead_u */ - { 0x0000fe89, 11115 }, /* dead_U */ - { 0x0000fe8a, 11068 }, /* dead_small_schwa */ - { 0x0000fe8b, 10711 }, /* dead_capital_schwa */ - { 0x0000fe8c, 10869 }, /* dead_greek */ - { 0x0000fe90, 10967 }, /* dead_lowline */ - { 0x0000fe91, 10508 }, /* dead_aboveverticalline */ - { 0x0000fe92, 10677 }, /* dead_belowverticalline */ - { 0x0000fe93, 10943 }, /* dead_longsolidusoverlay */ - { 0x0000fea0, 8594 }, /* ch */ - { 0x0000fea1, 8597 }, /* Ch */ - { 0x0000fea2, 8600 }, /* CH */ - { 0x0000fea3, 8443 }, /* c_h */ - { 0x0000fea4, 8447 }, /* C_h */ - { 0x0000fea5, 8451 }, /* C_H */ - { 0x0000fed0, 12536 }, /* First_Virtual_Screen */ - { 0x0000fed1, 22080 }, /* Prev_Virtual_Screen */ - { 0x0000fed2, 20028 }, /* Next_Virtual_Screen */ - { 0x0000fed4, 19161 }, /* Last_Virtual_Screen */ - { 0x0000fed5, 24382 }, /* Terminate_Server */ - { 0x0000fee0, 21998 }, /* Pointer_Left */ - { 0x0000fee1, 22011 }, /* Pointer_Right */ - { 0x0000fee2, 22025 }, /* Pointer_Up */ - { 0x0000fee3, 21843 }, /* Pointer_Down */ - { 0x0000fee4, 22036 }, /* Pointer_UpLeft */ - { 0x0000fee5, 22051 }, /* Pointer_UpRight */ - { 0x0000fee6, 21856 }, /* Pointer_DownLeft */ - { 0x0000fee7, 21873 }, /* Pointer_DownRight */ - { 0x0000fee8, 21671 }, /* Pointer_Button_Dflt */ - { 0x0000fee9, 21591 }, /* Pointer_Button1 */ - { 0x0000feea, 21607 }, /* Pointer_Button2 */ - { 0x0000feeb, 21623 }, /* Pointer_Button3 */ - { 0x0000feec, 21639 }, /* Pointer_Button4 */ - { 0x0000feed, 21655 }, /* Pointer_Button5 */ - { 0x0000feee, 21781 }, /* Pointer_DblClick_Dflt */ - { 0x0000feef, 21691 }, /* Pointer_DblClick1 */ - { 0x0000fef0, 21709 }, /* Pointer_DblClick2 */ - { 0x0000fef1, 21727 }, /* Pointer_DblClick3 */ - { 0x0000fef2, 21745 }, /* Pointer_DblClick4 */ - { 0x0000fef3, 21763 }, /* Pointer_DblClick5 */ - { 0x0000fef4, 21961 }, /* Pointer_Drag_Dflt */ - { 0x0000fef5, 21891 }, /* Pointer_Drag1 */ - { 0x0000fef6, 21905 }, /* Pointer_Drag2 */ - { 0x0000fef7, 21919 }, /* Pointer_Drag3 */ - { 0x0000fef8, 21933 }, /* Pointer_Drag4 */ - { 0x0000fef9, 21979 }, /* Pointer_EnableKeys */ - { 0x0000fefa, 21572 }, /* Pointer_Accelerate */ - { 0x0000fefb, 21803 }, /* Pointer_DfltBtnNext */ - { 0x0000fefc, 21823 }, /* Pointer_DfltBtnPrev */ - { 0x0000fefd, 21947 }, /* Pointer_Drag5 */ - { 0x0000ff08, 3362 }, /* BackSpace */ - { 0x0000ff09, 24298 }, /* Tab */ - { 0x0000ff0a, 19434 }, /* Linefeed */ - { 0x0000ff0b, 8633 }, /* Clear */ - { 0x0000ff0d, 22366 }, /* Return */ - { 0x0000ff13, 21481 }, /* Pause */ - { 0x0000ff14, 22699 }, /* Scroll_Lock */ - { 0x0000ff15, 24279 }, /* Sys_Req */ - { 0x0000ff1b, 12057 }, /* Escape */ - { 0x0000ff20, 19811 }, /* Multi_key */ - { 0x0000ff21, 18745 }, /* Kanji */ - { 0x0000ff22, 19802 }, /* Muhenkan */ - { 0x0000ff23, 16614 }, /* Henkan_Mode */ - { 0x0000ff24, 22562 }, /* Romaji */ - { 0x0000ff25, 16635 }, /* Hiragana */ - { 0x0000ff26, 18770 }, /* Katakana */ - { 0x0000ff27, 16644 }, /* Hiragana_Katakana */ - { 0x0000ff28, 29210 }, /* Zenkaku */ - { 0x0000ff29, 16048 }, /* Hankaku */ - { 0x0000ff2a, 29218 }, /* Zenkaku_Hankaku */ - { 0x0000ff2b, 25752 }, /* Touroku */ - { 0x0000ff2c, 19698 }, /* Massyo */ - { 0x0000ff2d, 18351 }, /* Kana_Lock */ - { 0x0000ff2e, 18562 }, /* Kana_Shift */ - { 0x0000ff2f, 11779 }, /* Eisu_Shift */ - { 0x0000ff30, 11790 }, /* Eisu_toggle */ - { 0x0000ff31, 14392 }, /* Hangul */ - { 0x0000ff32, 15780 }, /* Hangul_Start */ - { 0x0000ff33, 14511 }, /* Hangul_End */ - { 0x0000ff34, 14542 }, /* Hangul_Hanja */ - { 0x0000ff35, 15128 }, /* Hangul_Jamo */ - { 0x0000ff36, 15625 }, /* Hangul_Romaja */ - { 0x0000ff37, 8654 }, /* Codeinput */ - { 0x0000ff38, 15140 }, /* Hangul_Jeonja */ - { 0x0000ff39, 14445 }, /* Hangul_Banja */ - { 0x0000ff3a, 15420 }, /* Hangul_PreHanja */ - { 0x0000ff3b, 15403 }, /* Hangul_PostHanja */ - { 0x0000ff3c, 23012 }, /* SingleCandidate */ - { 0x0000ff3d, 19821 }, /* MultipleCandidate */ - { 0x0000ff3e, 22100 }, /* PreviousCandidate */ - { 0x0000ff3f, 15674 }, /* Hangul_Special */ - { 0x0000ff50, 16662 }, /* Home */ - { 0x0000ff51, 19244 }, /* Left */ - { 0x0000ff52, 26384 }, /* Up */ - { 0x0000ff53, 22373 }, /* Right */ - { 0x0000ff54, 11327 }, /* Down */ - { 0x0000ff55, 22124 }, /* Prior */ - { 0x0000ff56, 20023 }, /* Next */ - { 0x0000ff57, 11936 }, /* End */ - { 0x0000ff58, 3404 }, /* Begin */ - { 0x0000ff60, 22727 }, /* Select */ - { 0x0000ff61, 22118 }, /* Print */ - { 0x0000ff62, 12117 }, /* Execute */ - { 0x0000ff63, 17284 }, /* Insert */ - { 0x0000ff65, 26357 }, /* Undo */ - { 0x0000ff66, 22326 }, /* Redo */ - { 0x0000ff67, 19705 }, /* Menu */ - { 0x0000ff68, 12531 }, /* Find */ - { 0x0000ff69, 8489 }, /* Cancel */ - { 0x0000ff6a, 16602 }, /* Help */ - { 0x0000ff6b, 8377 }, /* Break */ - { 0x0000ff7e, 19747 }, /* Mode_switch */ - { 0x0000ff7f, 20169 }, /* Num_Lock */ - { 0x0000ff80, 19074 }, /* KP_Space */ - { 0x0000ff89, 19095 }, /* KP_Tab */ - { 0x0000ff8d, 18931 }, /* KP_Enter */ - { 0x0000ff91, 18949 }, /* KP_F1 */ - { 0x0000ff92, 18955 }, /* KP_F2 */ - { 0x0000ff93, 18961 }, /* KP_F3 */ - { 0x0000ff94, 18967 }, /* KP_F4 */ - { 0x0000ff95, 18973 }, /* KP_Home */ - { 0x0000ff96, 18991 }, /* KP_Left */ - { 0x0000ff97, 19102 }, /* KP_Up */ - { 0x0000ff98, 19052 }, /* KP_Right */ - { 0x0000ff99, 18916 }, /* KP_Down */ - { 0x0000ff9a, 19043 }, /* KP_Prior */ - { 0x0000ff9b, 19011 }, /* KP_Next */ - { 0x0000ff9c, 18924 }, /* KP_End */ - { 0x0000ff9d, 18876 }, /* KP_Begin */ - { 0x0000ff9e, 18981 }, /* KP_Insert */ - { 0x0000ff9f, 18896 }, /* KP_Delete */ - { 0x0000ffaa, 18999 }, /* KP_Multiply */ - { 0x0000ffab, 18858 }, /* KP_Add */ - { 0x0000ffac, 19061 }, /* KP_Separator */ - { 0x0000ffad, 19083 }, /* KP_Subtract */ - { 0x0000ffae, 18885 }, /* KP_Decimal */ - { 0x0000ffaf, 18906 }, /* KP_Divide */ - { 0x0000ffb0, 18808 }, /* KP_0 */ - { 0x0000ffb1, 18813 }, /* KP_1 */ - { 0x0000ffb2, 18818 }, /* KP_2 */ - { 0x0000ffb3, 18823 }, /* KP_3 */ - { 0x0000ffb4, 18828 }, /* KP_4 */ - { 0x0000ffb5, 18833 }, /* KP_5 */ - { 0x0000ffb6, 18838 }, /* KP_6 */ - { 0x0000ffb7, 18843 }, /* KP_7 */ - { 0x0000ffb8, 18848 }, /* KP_8 */ - { 0x0000ffb9, 18853 }, /* KP_9 */ - { 0x0000ffbd, 18940 }, /* KP_Equal */ - { 0x0000ffbe, 12159 }, /* F1 */ - { 0x0000ffbf, 12202 }, /* F2 */ - { 0x0000ffc0, 12245 }, /* F3 */ - { 0x0000ffc1, 12272 }, /* F4 */ - { 0x0000ffc2, 12275 }, /* F5 */ - { 0x0000ffc3, 12278 }, /* F6 */ - { 0x0000ffc4, 12281 }, /* F7 */ - { 0x0000ffc5, 12284 }, /* F8 */ - { 0x0000ffc6, 12287 }, /* F9 */ - { 0x0000ffc7, 12162 }, /* F10 */ - { 0x0000ffc8, 12166 }, /* F11 */ - { 0x0000ffc9, 12170 }, /* F12 */ - { 0x0000ffca, 12174 }, /* F13 */ - { 0x0000ffcb, 12178 }, /* F14 */ - { 0x0000ffcc, 12182 }, /* F15 */ - { 0x0000ffcd, 12186 }, /* F16 */ - { 0x0000ffce, 12190 }, /* F17 */ - { 0x0000ffcf, 12194 }, /* F18 */ - { 0x0000ffd0, 12198 }, /* F19 */ - { 0x0000ffd1, 12205 }, /* F20 */ - { 0x0000ffd2, 12209 }, /* F21 */ - { 0x0000ffd3, 12213 }, /* F22 */ - { 0x0000ffd4, 12217 }, /* F23 */ - { 0x0000ffd5, 12221 }, /* F24 */ - { 0x0000ffd6, 12225 }, /* F25 */ - { 0x0000ffd7, 12229 }, /* F26 */ - { 0x0000ffd8, 12233 }, /* F27 */ - { 0x0000ffd9, 12237 }, /* F28 */ - { 0x0000ffda, 12241 }, /* F29 */ - { 0x0000ffdb, 12248 }, /* F30 */ - { 0x0000ffdc, 12252 }, /* F31 */ - { 0x0000ffdd, 12256 }, /* F32 */ - { 0x0000ffde, 12260 }, /* F33 */ - { 0x0000ffdf, 12264 }, /* F34 */ - { 0x0000ffe0, 12268 }, /* F35 */ - { 0x0000ffe1, 22946 }, /* Shift_L */ - { 0x0000ffe2, 22965 }, /* Shift_R */ - { 0x0000ffe3, 8697 }, /* Control_L */ - { 0x0000ffe4, 8707 }, /* Control_R */ - { 0x0000ffe5, 8496 }, /* Caps_Lock */ - { 0x0000ffe6, 22954 }, /* Shift_Lock */ - { 0x0000ffe7, 19710 }, /* Meta_L */ - { 0x0000ffe8, 19717 }, /* Meta_R */ - { 0x0000ffe9, 880 }, /* Alt_L */ - { 0x0000ffea, 886 }, /* Alt_R */ - { 0x0000ffeb, 24263 }, /* Super_L */ - { 0x0000ffec, 24271 }, /* Super_R */ - { 0x0000ffed, 17046 }, /* Hyper_L */ - { 0x0000ffee, 17054 }, /* Hyper_R */ - { 0x0000fff1, 3642 }, /* braille_dot_1 */ - { 0x0000fff2, 3671 }, /* braille_dot_2 */ - { 0x0000fff3, 3685 }, /* braille_dot_3 */ - { 0x0000fff4, 3699 }, /* braille_dot_4 */ - { 0x0000fff5, 3713 }, /* braille_dot_5 */ - { 0x0000fff6, 3727 }, /* braille_dot_6 */ - { 0x0000fff7, 3741 }, /* braille_dot_7 */ - { 0x0000fff8, 3755 }, /* braille_dot_8 */ - { 0x0000fff9, 3769 }, /* braille_dot_9 */ - { 0x0000fffa, 3656 }, /* braille_dot_10 */ - { 0x0000ffff, 11160 }, /* Delete */ - { 0x00ffffff, 26531 }, /* VoidSymbol */ - { 0x0100012c, 17117 }, /* Ibreve */ - { 0x0100012d, 17124 }, /* ibreve */ - { 0x01000174, 26563 }, /* Wcircumflex */ - { 0x01000175, 26575 }, /* wcircumflex */ - { 0x01000176, 29059 }, /* Ycircumflex */ - { 0x01000177, 29071 }, /* ycircumflex */ - { 0x0100018f, 22649 }, /* SCHWA */ - { 0x0100019f, 20218 }, /* Obarred */ - { 0x010001a0, 20553 }, /* Ohorn */ - { 0x010001a1, 20559 }, /* ohorn */ - { 0x010001af, 25997 }, /* Uhorn */ - { 0x010001b0, 26003 }, /* uhorn */ - { 0x010001b5, 29261 }, /* Zstroke */ - { 0x010001b6, 29269 }, /* zstroke */ - { 0x010001b7, 12147 }, /* EZH */ - { 0x010001d1, 20254 }, /* Ocaron */ - { 0x010001d2, 20261 }, /* ocaron */ - { 0x010001e6, 12703 }, /* Gcaron */ - { 0x010001e7, 12710 }, /* gcaron */ - { 0x01000259, 22655 }, /* schwa */ - { 0x01000275, 20226 }, /* obarred */ - { 0x01000292, 12151 }, /* ezh */ - { 0x01000492, 9236 }, /* Cyrillic_GHE_bar */ - { 0x01000493, 9253 }, /* Cyrillic_ghe_bar */ - { 0x01000496, 10274 }, /* Cyrillic_ZHE_descender */ - { 0x01000497, 10297 }, /* Cyrillic_zhe_descender */ - { 0x0100049a, 9528 }, /* Cyrillic_KA_descender */ - { 0x0100049b, 9550 }, /* Cyrillic_ka_descender */ - { 0x0100049c, 9572 }, /* Cyrillic_KA_vertstroke */ - { 0x0100049d, 9595 }, /* Cyrillic_ka_vertstroke */ - { 0x010004a2, 9118 }, /* Cyrillic_EN_descender */ - { 0x010004a3, 9140 }, /* Cyrillic_en_descender */ - { 0x010004ae, 10036 }, /* Cyrillic_U_straight */ - { 0x010004af, 10056 }, /* Cyrillic_u_straight */ - { 0x010004b0, 10076 }, /* Cyrillic_U_straight_bar */ - { 0x010004b1, 10100 }, /* Cyrillic_u_straight_bar */ - { 0x010004b2, 9294 }, /* Cyrillic_HA_descender */ - { 0x010004b3, 9316 }, /* Cyrillic_ha_descender */ - { 0x010004b6, 8854 }, /* Cyrillic_CHE_descender */ - { 0x010004b7, 8877 }, /* Cyrillic_che_descender */ - { 0x010004b8, 8900 }, /* Cyrillic_CHE_vertstroke */ - { 0x010004b9, 8924 }, /* Cyrillic_che_vertstroke */ - { 0x010004ba, 9832 }, /* Cyrillic_SHHA */ - { 0x010004bb, 9846 }, /* Cyrillic_shha */ - { 0x010004d8, 9746 }, /* Cyrillic_SCHWA */ - { 0x010004d9, 9761 }, /* Cyrillic_schwa */ - { 0x010004e2, 9396 }, /* Cyrillic_I_macron */ - { 0x010004e3, 9414 }, /* Cyrillic_i_macron */ - { 0x010004e8, 9692 }, /* Cyrillic_O_bar */ - { 0x010004e9, 9707 }, /* Cyrillic_o_bar */ - { 0x010004ee, 10000 }, /* Cyrillic_U_macron */ - { 0x010004ef, 10018 }, /* Cyrillic_u_macron */ - { 0x01000531, 2124 }, /* Armenian_AYB */ - { 0x01000532, 2150 }, /* Armenian_BEN */ - { 0x01000533, 2374 }, /* Armenian_GIM */ - { 0x01000534, 2215 }, /* Armenian_DA */ - { 0x01000535, 3164 }, /* Armenian_YECH */ - { 0x01000536, 3210 }, /* Armenian_ZA */ - { 0x01000537, 2265 }, /* Armenian_E */ - { 0x01000538, 2100 }, /* Armenian_AT */ - { 0x01000539, 2964 }, /* Armenian_TO */ - { 0x0100053a, 3234 }, /* Armenian_ZHE */ - { 0x0100053b, 2464 }, /* Armenian_INI */ - { 0x0100053c, 2611 }, /* Armenian_LYUN */ - { 0x0100053d, 2564 }, /* Armenian_KHE */ - { 0x0100053e, 2988 }, /* Armenian_TSA */ - { 0x0100053f, 2538 }, /* Armenian_KEN */ - { 0x01000540, 2424 }, /* Armenian_HO */ - { 0x01000541, 2239 }, /* Armenian_DZA */ - { 0x01000542, 2346 }, /* Armenian_GHAT */ - { 0x01000543, 2936 }, /* Armenian_TCHE */ - { 0x01000544, 2639 }, /* Armenian_MEN */ - { 0x01000545, 2400 }, /* Armenian_HI */ - { 0x01000546, 2665 }, /* Armenian_NU */ - { 0x01000547, 2894 }, /* Armenian_SHA */ - { 0x01000548, 3112 }, /* Armenian_VO */ - { 0x01000549, 2189 }, /* Armenian_CHA */ - { 0x0100054a, 2727 }, /* Armenian_PE */ - { 0x0100054b, 2490 }, /* Armenian_JE */ - { 0x0100054c, 2797 }, /* Armenian_RA */ - { 0x0100054d, 2845 }, /* Armenian_SE */ - { 0x0100054e, 3086 }, /* Armenian_VEV */ - { 0x0100054f, 3040 }, /* Armenian_TYUN */ - { 0x01000550, 2821 }, /* Armenian_RE */ - { 0x01000551, 3014 }, /* Armenian_TSO */ - { 0x01000552, 3136 }, /* Armenian_VYUN */ - { 0x01000553, 2751 }, /* Armenian_PYUR */ - { 0x01000554, 2514 }, /* Armenian_KE */ - { 0x01000555, 2689 }, /* Armenian_O */ - { 0x01000556, 2303 }, /* Armenian_FE */ - { 0x0100055a, 2080 }, /* Armenian_apostrophe */ - { 0x0100055b, 2048 }, /* Armenian_accent */ - { 0x0100055c, 2287 }, /* Armenian_exclam */ - { 0x0100055d, 2869 }, /* Armenian_separation_mark */ - { 0x0100055e, 2779 }, /* Armenian_question */ - { 0x01000561, 2137 }, /* Armenian_ayb */ - { 0x01000562, 2163 }, /* Armenian_ben */ - { 0x01000563, 2387 }, /* Armenian_gim */ - { 0x01000564, 2227 }, /* Armenian_da */ - { 0x01000565, 3178 }, /* Armenian_yech */ - { 0x01000566, 3222 }, /* Armenian_za */ - { 0x01000567, 2276 }, /* Armenian_e */ - { 0x01000568, 2112 }, /* Armenian_at */ - { 0x01000569, 2976 }, /* Armenian_to */ - { 0x0100056a, 3247 }, /* Armenian_zhe */ - { 0x0100056b, 2477 }, /* Armenian_ini */ - { 0x0100056c, 2625 }, /* Armenian_lyun */ - { 0x0100056d, 2577 }, /* Armenian_khe */ - { 0x0100056e, 3001 }, /* Armenian_tsa */ - { 0x0100056f, 2551 }, /* Armenian_ken */ - { 0x01000570, 2436 }, /* Armenian_ho */ - { 0x01000571, 2252 }, /* Armenian_dza */ - { 0x01000572, 2360 }, /* Armenian_ghat */ - { 0x01000573, 2950 }, /* Armenian_tche */ - { 0x01000574, 2652 }, /* Armenian_men */ - { 0x01000575, 2412 }, /* Armenian_hi */ - { 0x01000576, 2677 }, /* Armenian_nu */ - { 0x01000577, 2907 }, /* Armenian_sha */ - { 0x01000578, 3124 }, /* Armenian_vo */ - { 0x01000579, 2202 }, /* Armenian_cha */ - { 0x0100057a, 2739 }, /* Armenian_pe */ - { 0x0100057b, 2502 }, /* Armenian_je */ - { 0x0100057c, 2809 }, /* Armenian_ra */ - { 0x0100057d, 2857 }, /* Armenian_se */ - { 0x0100057e, 3099 }, /* Armenian_vev */ - { 0x0100057f, 3054 }, /* Armenian_tyun */ - { 0x01000580, 2833 }, /* Armenian_re */ - { 0x01000581, 3027 }, /* Armenian_tso */ - { 0x01000582, 3150 }, /* Armenian_vyun */ - { 0x01000583, 2765 }, /* Armenian_pyur */ - { 0x01000584, 2526 }, /* Armenian_ke */ - { 0x01000585, 2700 }, /* Armenian_o */ - { 0x01000586, 2315 }, /* Armenian_fe */ - { 0x01000587, 2590 }, /* Armenian_ligature_ew */ - { 0x01000589, 2327 }, /* Armenian_full_stop */ - { 0x0100058a, 2448 }, /* Armenian_hyphen */ - { 0x01000653, 1580 }, /* Arabic_madda_above */ - { 0x01000654, 1316 }, /* Arabic_hamza_above */ - { 0x01000655, 1335 }, /* Arabic_hamza_below */ - { 0x01000660, 966 }, /* Arabic_0 */ - { 0x01000661, 975 }, /* Arabic_1 */ - { 0x01000662, 984 }, /* Arabic_2 */ - { 0x01000663, 993 }, /* Arabic_3 */ - { 0x01000664, 1002 }, /* Arabic_4 */ - { 0x01000665, 1011 }, /* Arabic_5 */ - { 0x01000666, 1020 }, /* Arabic_6 */ - { 0x01000667, 1029 }, /* Arabic_7 */ - { 0x01000668, 1038 }, /* Arabic_8 */ - { 0x01000669, 1047 }, /* Arabic_9 */ - { 0x0100066a, 1672 }, /* Arabic_percent */ - { 0x01000670, 1821 }, /* Arabic_superscript_alef */ - { 0x01000679, 1951 }, /* Arabic_tteh */ - { 0x0100067e, 1661 }, /* Arabic_peh */ - { 0x01000686, 1885 }, /* Arabic_tcheh */ - { 0x01000688, 1173 }, /* Arabic_ddal */ - { 0x01000691, 1729 }, /* Arabic_rreh */ - { 0x01000698, 1493 }, /* Arabic_jeh */ - { 0x010006a4, 1963 }, /* Arabic_veh */ - { 0x010006a9, 1544 }, /* Arabic_keheh */ - { 0x010006af, 1258 }, /* Arabic_gaf */ - { 0x010006ba, 1642 }, /* Arabic_noon_ghunna */ - { 0x010006be, 1442 }, /* Arabic_heh_doachashmee */ - { 0x010006c1, 1465 }, /* Arabic_heh_goal */ - { 0x010006cc, 12390 }, /* Farsi_yeh */ - { 0x010006d2, 1996 }, /* Arabic_yeh_baree */ - { 0x010006d4, 1242 }, /* Arabic_fullstop */ - { 0x010006f0, 12310 }, /* Farsi_0 */ - { 0x010006f1, 12318 }, /* Farsi_1 */ - { 0x010006f2, 12326 }, /* Farsi_2 */ - { 0x010006f3, 12334 }, /* Farsi_3 */ - { 0x010006f4, 12342 }, /* Farsi_4 */ - { 0x010006f5, 12350 }, /* Farsi_5 */ - { 0x010006f6, 12358 }, /* Farsi_6 */ - { 0x010006f7, 12366 }, /* Farsi_7 */ - { 0x010006f8, 12374 }, /* Farsi_8 */ - { 0x010006f9, 12382 }, /* Farsi_9 */ - { 0x01000d82, 23484 }, /* Sinh_ng */ - { 0x01000d83, 23278 }, /* Sinh_h2 */ - { 0x01000d85, 23047 }, /* Sinh_a */ - { 0x01000d86, 23054 }, /* Sinh_aa */ - { 0x01000d87, 23071 }, /* Sinh_ae */ - { 0x01000d88, 23088 }, /* Sinh_aee */ - { 0x01000d89, 23294 }, /* Sinh_i */ - { 0x01000d8a, 23309 }, /* Sinh_ii */ - { 0x01000d8b, 23695 }, /* Sinh_u */ - { 0x01000d8c, 23710 }, /* Sinh_uu */ - { 0x01000d8d, 23594 }, /* Sinh_ri */ - { 0x01000d8e, 23602 }, /* Sinh_rii */ - { 0x01000d8f, 23403 }, /* Sinh_lu */ - { 0x01000d90, 23420 }, /* Sinh_luu */ - { 0x01000d91, 23221 }, /* Sinh_e */ - { 0x01000d92, 23236 }, /* Sinh_ee */ - { 0x01000d93, 23107 }, /* Sinh_ai */ - { 0x01000d94, 23537 }, /* Sinh_o */ - { 0x01000d95, 23552 }, /* Sinh_oo */ - { 0x01000d96, 23132 }, /* Sinh_au */ - { 0x01000d9a, 23353 }, /* Sinh_ka */ - { 0x01000d9b, 23361 }, /* Sinh_kha */ - { 0x01000d9c, 23261 }, /* Sinh_ga */ - { 0x01000d9d, 23269 }, /* Sinh_gha */ - { 0x01000d9e, 23492 }, /* Sinh_ng2 */ - { 0x01000d9f, 23501 }, /* Sinh_nga */ - { 0x01000da0, 23166 }, /* Sinh_ca */ - { 0x01000da1, 23174 }, /* Sinh_cha */ - { 0x01000da2, 23326 }, /* Sinh_ja */ - { 0x01000da3, 23334 }, /* Sinh_jha */ - { 0x01000da4, 23528 }, /* Sinh_nya */ - { 0x01000da5, 23343 }, /* Sinh_jnya */ - { 0x01000da6, 23510 }, /* Sinh_nja */ - { 0x01000da7, 23676 }, /* Sinh_tta */ - { 0x01000da8, 23685 }, /* Sinh_ttha */ - { 0x01000da9, 23183 }, /* Sinh_dda */ - { 0x01000daa, 23192 }, /* Sinh_ddha */ - { 0x01000dab, 23519 }, /* Sinh_nna */ - { 0x01000dac, 23464 }, /* Sinh_ndda */ - { 0x01000dad, 23657 }, /* Sinh_tha */ - { 0x01000dae, 23666 }, /* Sinh_thha */ - { 0x01000daf, 23202 }, /* Sinh_dha */ - { 0x01000db0, 23211 }, /* Sinh_dhha */ - { 0x01000db1, 23456 }, /* Sinh_na */ - { 0x01000db3, 23474 }, /* Sinh_ndha */ - { 0x01000db4, 23569 }, /* Sinh_pa */ - { 0x01000db5, 23577 }, /* Sinh_pha */ - { 0x01000db6, 23149 }, /* Sinh_ba */ - { 0x01000db7, 23157 }, /* Sinh_bha */ - { 0x01000db8, 23439 }, /* Sinh_ma */ - { 0x01000db9, 23447 }, /* Sinh_mba */ - { 0x01000dba, 23735 }, /* Sinh_ya */ - { 0x01000dbb, 23586 }, /* Sinh_ra */ - { 0x01000dbd, 23386 }, /* Sinh_la */ - { 0x01000dc0, 23727 }, /* Sinh_va */ - { 0x01000dc1, 23638 }, /* Sinh_sha */ - { 0x01000dc2, 23647 }, /* Sinh_ssha */ - { 0x01000dc3, 23630 }, /* Sinh_sa */ - { 0x01000dc4, 23286 }, /* Sinh_ha */ - { 0x01000dc5, 23394 }, /* Sinh_lla */ - { 0x01000dc6, 23253 }, /* Sinh_fa */ - { 0x01000dca, 23124 }, /* Sinh_al */ - { 0x01000dcf, 23062 }, /* Sinh_aa2 */ - { 0x01000dd0, 23079 }, /* Sinh_ae2 */ - { 0x01000dd1, 23097 }, /* Sinh_aee2 */ - { 0x01000dd2, 23301 }, /* Sinh_i2 */ - { 0x01000dd3, 23317 }, /* Sinh_ii2 */ - { 0x01000dd4, 23702 }, /* Sinh_u2 */ - { 0x01000dd6, 23718 }, /* Sinh_uu2 */ - { 0x01000dd8, 23611 }, /* Sinh_ru2 */ - { 0x01000dd9, 23228 }, /* Sinh_e2 */ - { 0x01000dda, 23244 }, /* Sinh_ee2 */ - { 0x01000ddb, 23115 }, /* Sinh_ai2 */ - { 0x01000ddc, 23544 }, /* Sinh_o2 */ - { 0x01000ddd, 23560 }, /* Sinh_oo2 */ - { 0x01000dde, 23140 }, /* Sinh_au2 */ - { 0x01000ddf, 23411 }, /* Sinh_lu2 */ - { 0x01000df2, 23620 }, /* Sinh_ruu2 */ - { 0x01000df3, 23429 }, /* Sinh_luu2 */ - { 0x01000df4, 23370 }, /* Sinh_kunddaliya */ - { 0x010010d0, 12759 }, /* Georgian_an */ - { 0x010010d1, 12771 }, /* Georgian_ban */ - { 0x010010d2, 12875 }, /* Georgian_gan */ - { 0x010010d3, 12838 }, /* Georgian_don */ - { 0x010010d4, 12851 }, /* Georgian_en */ - { 0x010010d5, 13201 }, /* Georgian_vin */ - { 0x010010d6, 13239 }, /* Georgian_zen */ - { 0x010010d7, 13163 }, /* Georgian_tan */ - { 0x010010d8, 12966 }, /* Georgian_in */ - { 0x010010d9, 13005 }, /* Georgian_kan */ - { 0x010010da, 13032 }, /* Georgian_las */ - { 0x010010db, 13045 }, /* Georgian_man */ - { 0x010010dc, 13058 }, /* Georgian_nar */ - { 0x010010dd, 13071 }, /* Georgian_on */ - { 0x010010de, 13083 }, /* Georgian_par */ - { 0x010010df, 13252 }, /* Georgian_zhar */ - { 0x010010e0, 13123 }, /* Georgian_rae */ - { 0x010010e1, 13136 }, /* Georgian_san */ - { 0x010010e2, 13176 }, /* Georgian_tar */ - { 0x010010e3, 13189 }, /* Georgian_un */ - { 0x010010e4, 13096 }, /* Georgian_phar */ - { 0x010010e5, 13018 }, /* Georgian_khar */ - { 0x010010e6, 12888 }, /* Georgian_ghan */ - { 0x010010e7, 13110 }, /* Georgian_qar */ - { 0x010010e8, 13149 }, /* Georgian_shin */ - { 0x010010e9, 12811 }, /* Georgian_chin */ - { 0x010010ea, 12784 }, /* Georgian_can */ - { 0x010010eb, 12992 }, /* Georgian_jil */ - { 0x010010ec, 12825 }, /* Georgian_cil */ - { 0x010010ed, 12797 }, /* Georgian_char */ - { 0x010010ee, 13226 }, /* Georgian_xan */ - { 0x010010ef, 12978 }, /* Georgian_jhan */ - { 0x010010f0, 12902 }, /* Georgian_hae */ - { 0x010010f1, 12928 }, /* Georgian_he */ - { 0x010010f2, 12940 }, /* Georgian_hie */ - { 0x010010f3, 13214 }, /* Georgian_we */ - { 0x010010f4, 12915 }, /* Georgian_har */ - { 0x010010f5, 12953 }, /* Georgian_hoe */ - { 0x010010f6, 12863 }, /* Georgian_fi */ - { 0x01001e02, 3332 }, /* Babovedot */ - { 0x01001e03, 3342 }, /* babovedot */ - { 0x01001e0a, 10324 }, /* Dabovedot */ - { 0x01001e0b, 10334 }, /* dabovedot */ - { 0x01001e1e, 12290 }, /* Fabovedot */ - { 0x01001e1f, 12300 }, /* fabovedot */ - { 0x01001e36, 19192 }, /* Lbelowdot */ - { 0x01001e37, 19202 }, /* lbelowdot */ - { 0x01001e40, 19537 }, /* Mabovedot */ - { 0x01001e41, 19547 }, /* mabovedot */ - { 0x01001e56, 21377 }, /* Pabovedot */ - { 0x01001e57, 21387 }, /* pabovedot */ - { 0x01001e60, 22583 }, /* Sabovedot */ - { 0x01001e61, 22593 }, /* sabovedot */ - { 0x01001e6a, 24302 }, /* Tabovedot */ - { 0x01001e6b, 24312 }, /* tabovedot */ - { 0x01001e80, 26609 }, /* Wgrave */ - { 0x01001e81, 26616 }, /* wgrave */ - { 0x01001e82, 26549 }, /* Wacute */ - { 0x01001e83, 26556 }, /* wacute */ - { 0x01001e84, 26587 }, /* Wdiaeresis */ - { 0x01001e85, 26598 }, /* wdiaeresis */ - { 0x01001e8a, 26635 }, /* Xabovedot */ - { 0x01001e8b, 26645 }, /* xabovedot */ - { 0x01001ea0, 416 }, /* Abelowdot */ - { 0x01001ea1, 426 }, /* abelowdot */ - { 0x01001ea2, 868 }, /* Ahook */ - { 0x01001ea3, 874 }, /* ahook */ - { 0x01001ea4, 646 }, /* Acircumflexacute */ - { 0x01001ea5, 663 }, /* acircumflexacute */ - { 0x01001ea6, 720 }, /* Acircumflexgrave */ - { 0x01001ea7, 737 }, /* acircumflexgrave */ - { 0x01001ea8, 754 }, /* Acircumflexhook */ - { 0x01001ea9, 770 }, /* acircumflexhook */ - { 0x01001eaa, 786 }, /* Acircumflextilde */ - { 0x01001eab, 803 }, /* acircumflextilde */ - { 0x01001eac, 680 }, /* Acircumflexbelowdot */ - { 0x01001ead, 700 }, /* acircumflexbelowdot */ - { 0x01001eae, 459 }, /* Abreveacute */ - { 0x01001eaf, 471 }, /* abreveacute */ - { 0x01001eb0, 513 }, /* Abrevegrave */ - { 0x01001eb1, 525 }, /* abrevegrave */ - { 0x01001eb2, 537 }, /* Abrevehook */ - { 0x01001eb3, 548 }, /* abrevehook */ - { 0x01001eb4, 559 }, /* Abrevetilde */ - { 0x01001eb5, 571 }, /* abrevetilde */ - { 0x01001eb6, 483 }, /* Abrevebelowdot */ - { 0x01001eb7, 498 }, /* abrevebelowdot */ - { 0x01001eb8, 11462 }, /* Ebelowdot */ - { 0x01001eb9, 11472 }, /* ebelowdot */ - { 0x01001eba, 11738 }, /* Ehook */ - { 0x01001ebb, 11744 }, /* ehook */ - { 0x01001ebc, 12076 }, /* Etilde */ - { 0x01001ebd, 12083 }, /* etilde */ - { 0x01001ebe, 11520 }, /* Ecircumflexacute */ - { 0x01001ebf, 11537 }, /* ecircumflexacute */ - { 0x01001ec0, 11594 }, /* Ecircumflexgrave */ - { 0x01001ec1, 11611 }, /* ecircumflexgrave */ - { 0x01001ec2, 11628 }, /* Ecircumflexhook */ - { 0x01001ec3, 11644 }, /* ecircumflexhook */ - { 0x01001ec4, 11660 }, /* Ecircumflextilde */ - { 0x01001ec5, 11677 }, /* ecircumflextilde */ - { 0x01001ec6, 11554 }, /* Ecircumflexbelowdot */ - { 0x01001ec7, 11574 }, /* ecircumflexbelowdot */ - { 0x01001ec8, 17219 }, /* Ihook */ - { 0x01001ec9, 17225 }, /* ihook */ - { 0x01001eca, 17097 }, /* Ibelowdot */ - { 0x01001ecb, 17107 }, /* ibelowdot */ - { 0x01001ecc, 20234 }, /* Obelowdot */ - { 0x01001ecd, 20244 }, /* obelowdot */ - { 0x01001ece, 20541 }, /* Ohook */ - { 0x01001ecf, 20547 }, /* ohook */ - { 0x01001ed0, 20292 }, /* Ocircumflexacute */ - { 0x01001ed1, 20309 }, /* ocircumflexacute */ - { 0x01001ed2, 20366 }, /* Ocircumflexgrave */ - { 0x01001ed3, 20383 }, /* ocircumflexgrave */ - { 0x01001ed4, 20400 }, /* Ocircumflexhook */ - { 0x01001ed5, 20416 }, /* ocircumflexhook */ - { 0x01001ed6, 20432 }, /* Ocircumflextilde */ - { 0x01001ed7, 20449 }, /* ocircumflextilde */ - { 0x01001ed8, 20326 }, /* Ocircumflexbelowdot */ - { 0x01001ed9, 20346 }, /* ocircumflexbelowdot */ - { 0x01001eda, 20565 }, /* Ohornacute */ - { 0x01001edb, 20576 }, /* ohornacute */ - { 0x01001edc, 20615 }, /* Ohorngrave */ - { 0x01001edd, 20626 }, /* ohorngrave */ - { 0x01001ede, 20637 }, /* Ohornhook */ - { 0x01001edf, 20647 }, /* ohornhook */ - { 0x01001ee0, 20657 }, /* Ohorntilde */ - { 0x01001ee1, 20668 }, /* ohorntilde */ - { 0x01001ee2, 20587 }, /* Ohornbelowdot */ - { 0x01001ee3, 20601 }, /* ohornbelowdot */ - { 0x01001ee4, 25865 }, /* Ubelowdot */ - { 0x01001ee5, 25875 }, /* ubelowdot */ - { 0x01001ee6, 25985 }, /* Uhook */ - { 0x01001ee7, 25991 }, /* uhook */ - { 0x01001ee8, 26009 }, /* Uhornacute */ - { 0x01001ee9, 26020 }, /* uhornacute */ - { 0x01001eea, 26059 }, /* Uhorngrave */ - { 0x01001eeb, 26070 }, /* uhorngrave */ - { 0x01001eec, 26081 }, /* Uhornhook */ - { 0x01001eed, 26091 }, /* uhornhook */ - { 0x01001eee, 26101 }, /* Uhorntilde */ - { 0x01001eef, 26112 }, /* uhorntilde */ - { 0x01001ef0, 26031 }, /* Uhornbelowdot */ - { 0x01001ef1, 26045 }, /* uhornbelowdot */ - { 0x01001ef2, 29109 }, /* Ygrave */ - { 0x01001ef3, 29116 }, /* ygrave */ - { 0x01001ef4, 29039 }, /* Ybelowdot */ - { 0x01001ef5, 29049 }, /* ybelowdot */ - { 0x01001ef6, 29123 }, /* Yhook */ - { 0x01001ef7, 29129 }, /* yhook */ - { 0x01001ef8, 29135 }, /* Ytilde */ - { 0x01001ef9, 29142 }, /* ytilde */ - { 0x01002070, 29248 }, /* zerosuperior */ - { 0x01002074, 12632 }, /* foursuperior */ - { 0x01002075, 12594 }, /* fivesuperior */ - { 0x01002076, 23756 }, /* sixsuperior */ - { 0x01002077, 22932 }, /* sevensuperior */ - { 0x01002078, 11765 }, /* eightsuperior */ - { 0x01002079, 20062 }, /* ninesuperior */ - { 0x01002080, 29234 }, /* zerosubscript */ - { 0x01002081, 20742 }, /* onesubscript */ - { 0x01002082, 25812 }, /* twosubscript */ - { 0x01002083, 25556 }, /* threesubscript */ - { 0x01002084, 12618 }, /* foursubscript */ - { 0x01002085, 12580 }, /* fivesubscript */ - { 0x01002086, 23743 }, /* sixsubscript */ - { 0x01002087, 22917 }, /* sevensubscript */ - { 0x01002088, 11750 }, /* eightsubscript */ - { 0x01002089, 20048 }, /* ninesubscript */ - { 0x010020a0, 11694 }, /* EcuSign */ - { 0x010020a1, 8670 }, /* ColonSign */ - { 0x010020a2, 8744 }, /* CruzeiroSign */ - { 0x010020a3, 12416 }, /* FFrancSign */ - { 0x010020a4, 19448 }, /* LiraSign */ - { 0x010020a5, 19724 }, /* MillSign */ - { 0x010020a6, 19967 }, /* NairaSign */ - { 0x010020a7, 21526 }, /* PesetaSign */ - { 0x010020a8, 22569 }, /* RupeeSign */ - { 0x010020a9, 26623 }, /* WonSign */ - { 0x010020aa, 20009 }, /* NewSheqelSign */ - { 0x010020ab, 11258 }, /* DongSign */ - { 0x01002202, 21446 }, /* partdifferential */ - { 0x01002205, 11919 }, /* emptyset */ - { 0x01002208, 11802 }, /* elementof */ - { 0x01002209, 20112 }, /* notelementof */ - { 0x0100220b, 8686 }, /* containsas */ - { 0x0100221a, 23809 }, /* squareroot */ - { 0x0100221b, 8757 }, /* cuberoot */ - { 0x0100221c, 12645 }, /* fourthroot */ - { 0x0100222c, 11232 }, /* dintegral */ - { 0x0100222d, 25585 }, /* tintegral */ - { 0x01002235, 3396 }, /* because */ - { 0x01002247, 20100 }, /* notapproxeq */ - { 0x01002248, 945 }, /* approxeq */ - { 0x01002262, 20134 }, /* notidentical */ - { 0x01002263, 23854 }, /* stricteq */ - { 0x01002800, 3628 }, /* braille_blank */ - { 0x01002801, 3783 }, /* braille_dots_1 */ - { 0x01002802, 6151 }, /* braille_dots_2 */ - { 0x01002803, 3798 }, /* braille_dots_12 */ - { 0x01002804, 7303 }, /* braille_dots_3 */ - { 0x01002805, 5014 }, /* braille_dots_13 */ - { 0x01002806, 6166 }, /* braille_dots_23 */ - { 0x01002807, 3814 }, /* braille_dots_123 */ - { 0x01002808, 7863 }, /* braille_dots_4 */ - { 0x01002809, 5606 }, /* braille_dots_14 */ - { 0x0100280a, 6758 }, /* braille_dots_24 */ - { 0x0100280b, 4438 }, /* braille_dots_124 */ - { 0x0100280c, 7318 }, /* braille_dots_34 */ - { 0x0100280d, 5030 }, /* braille_dots_134 */ - { 0x0100280e, 6182 }, /* braille_dots_234 */ - { 0x0100280f, 3831 }, /* braille_dots_1234 */ - { 0x01002810, 8135 }, /* braille_dots_5 */ - { 0x01002811, 5894 }, /* braille_dots_15 */ - { 0x01002812, 7046 }, /* braille_dots_25 */ - { 0x01002813, 4742 }, /* braille_dots_125 */ - { 0x01002814, 7606 }, /* braille_dots_35 */ - { 0x01002815, 5334 }, /* braille_dots_135 */ - { 0x01002816, 6486 }, /* braille_dots_235 */ - { 0x01002817, 4151 }, /* braille_dots_1235 */ - { 0x01002818, 7878 }, /* braille_dots_45 */ - { 0x01002819, 5622 }, /* braille_dots_145 */ - { 0x0100281a, 6774 }, /* braille_dots_245 */ - { 0x0100281b, 4455 }, /* braille_dots_1245 */ - { 0x0100281c, 7334 }, /* braille_dots_345 */ - { 0x0100281d, 5047 }, /* braille_dots_1345 */ - { 0x0100281e, 6199 }, /* braille_dots_2345 */ - { 0x0100281f, 3849 }, /* braille_dots_12345 */ - { 0x01002820, 8267 }, /* braille_dots_6 */ - { 0x01002821, 6034 }, /* braille_dots_16 */ - { 0x01002822, 7186 }, /* braille_dots_26 */ - { 0x01002823, 4890 }, /* braille_dots_126 */ - { 0x01002824, 7746 }, /* braille_dots_36 */ - { 0x01002825, 5482 }, /* braille_dots_136 */ - { 0x01002826, 6634 }, /* braille_dots_236 */ - { 0x01002827, 4307 }, /* braille_dots_1236 */ - { 0x01002828, 8018 }, /* braille_dots_46 */ - { 0x01002829, 5770 }, /* braille_dots_146 */ - { 0x0100282a, 6922 }, /* braille_dots_246 */ - { 0x0100282b, 4611 }, /* braille_dots_1246 */ - { 0x0100282c, 7482 }, /* braille_dots_346 */ - { 0x0100282d, 5203 }, /* braille_dots_1346 */ - { 0x0100282e, 6355 }, /* braille_dots_2346 */ - { 0x0100282f, 4013 }, /* braille_dots_12346 */ - { 0x01002830, 8150 }, /* braille_dots_56 */ - { 0x01002831, 5910 }, /* braille_dots_156 */ - { 0x01002832, 7062 }, /* braille_dots_256 */ - { 0x01002833, 4759 }, /* braille_dots_1256 */ - { 0x01002834, 7622 }, /* braille_dots_356 */ - { 0x01002835, 5351 }, /* braille_dots_1356 */ - { 0x01002836, 6503 }, /* braille_dots_2356 */ - { 0x01002837, 4169 }, /* braille_dots_12356 */ - { 0x01002838, 7894 }, /* braille_dots_456 */ - { 0x01002839, 5639 }, /* braille_dots_1456 */ - { 0x0100283a, 6791 }, /* braille_dots_2456 */ - { 0x0100283b, 4473 }, /* braille_dots_12456 */ - { 0x0100283c, 7351 }, /* braille_dots_3456 */ - { 0x0100283d, 5065 }, /* braille_dots_13456 */ - { 0x0100283e, 6217 }, /* braille_dots_23456 */ - { 0x0100283f, 3868 }, /* braille_dots_123456 */ - { 0x01002840, 8331 }, /* braille_dots_7 */ - { 0x01002841, 6102 }, /* braille_dots_17 */ - { 0x01002842, 7254 }, /* braille_dots_27 */ - { 0x01002843, 4962 }, /* braille_dots_127 */ - { 0x01002844, 7814 }, /* braille_dots_37 */ - { 0x01002845, 5554 }, /* braille_dots_137 */ - { 0x01002846, 6706 }, /* braille_dots_237 */ - { 0x01002847, 4383 }, /* braille_dots_1237 */ - { 0x01002848, 8086 }, /* braille_dots_47 */ - { 0x01002849, 5842 }, /* braille_dots_147 */ - { 0x0100284a, 6994 }, /* braille_dots_247 */ - { 0x0100284b, 4687 }, /* braille_dots_1247 */ - { 0x0100284c, 7554 }, /* braille_dots_347 */ - { 0x0100284d, 5279 }, /* braille_dots_1347 */ - { 0x0100284e, 6431 }, /* braille_dots_2347 */ - { 0x0100284f, 4093 }, /* braille_dots_12347 */ - { 0x01002850, 8218 }, /* braille_dots_57 */ - { 0x01002851, 5982 }, /* braille_dots_157 */ - { 0x01002852, 7134 }, /* braille_dots_257 */ - { 0x01002853, 4835 }, /* braille_dots_1257 */ - { 0x01002854, 7694 }, /* braille_dots_357 */ - { 0x01002855, 5427 }, /* braille_dots_1357 */ - { 0x01002856, 6579 }, /* braille_dots_2357 */ - { 0x01002857, 4249 }, /* braille_dots_12357 */ - { 0x01002858, 7966 }, /* braille_dots_457 */ - { 0x01002859, 5715 }, /* braille_dots_1457 */ - { 0x0100285a, 6867 }, /* braille_dots_2457 */ - { 0x0100285b, 4553 }, /* braille_dots_12457 */ - { 0x0100285c, 7427 }, /* braille_dots_3457 */ - { 0x0100285d, 5145 }, /* braille_dots_13457 */ - { 0x0100285e, 6297 }, /* braille_dots_23457 */ - { 0x0100285f, 3952 }, /* braille_dots_123457 */ - { 0x01002860, 8282 }, /* braille_dots_67 */ - { 0x01002861, 6050 }, /* braille_dots_167 */ - { 0x01002862, 7202 }, /* braille_dots_267 */ - { 0x01002863, 4907 }, /* braille_dots_1267 */ - { 0x01002864, 7762 }, /* braille_dots_367 */ - { 0x01002865, 5499 }, /* braille_dots_1367 */ - { 0x01002866, 6651 }, /* braille_dots_2367 */ - { 0x01002867, 4325 }, /* braille_dots_12367 */ - { 0x01002868, 8034 }, /* braille_dots_467 */ - { 0x01002869, 5787 }, /* braille_dots_1467 */ - { 0x0100286a, 6939 }, /* braille_dots_2467 */ - { 0x0100286b, 4629 }, /* braille_dots_12467 */ - { 0x0100286c, 7499 }, /* braille_dots_3467 */ - { 0x0100286d, 5221 }, /* braille_dots_13467 */ - { 0x0100286e, 6373 }, /* braille_dots_23467 */ - { 0x0100286f, 4032 }, /* braille_dots_123467 */ - { 0x01002870, 8166 }, /* braille_dots_567 */ - { 0x01002871, 5927 }, /* braille_dots_1567 */ - { 0x01002872, 7079 }, /* braille_dots_2567 */ - { 0x01002873, 4777 }, /* braille_dots_12567 */ - { 0x01002874, 7639 }, /* braille_dots_3567 */ - { 0x01002875, 5369 }, /* braille_dots_13567 */ - { 0x01002876, 6521 }, /* braille_dots_23567 */ - { 0x01002877, 4188 }, /* braille_dots_123567 */ - { 0x01002878, 7911 }, /* braille_dots_4567 */ - { 0x01002879, 5657 }, /* braille_dots_14567 */ - { 0x0100287a, 6809 }, /* braille_dots_24567 */ - { 0x0100287b, 4492 }, /* braille_dots_124567 */ - { 0x0100287c, 7369 }, /* braille_dots_34567 */ - { 0x0100287d, 5084 }, /* braille_dots_134567 */ - { 0x0100287e, 6236 }, /* braille_dots_234567 */ - { 0x0100287f, 3888 }, /* braille_dots_1234567 */ - { 0x01002880, 8362 }, /* braille_dots_8 */ - { 0x01002881, 6135 }, /* braille_dots_18 */ - { 0x01002882, 7287 }, /* braille_dots_28 */ - { 0x01002883, 4997 }, /* braille_dots_128 */ - { 0x01002884, 7847 }, /* braille_dots_38 */ - { 0x01002885, 5589 }, /* braille_dots_138 */ - { 0x01002886, 6741 }, /* braille_dots_238 */ - { 0x01002887, 4420 }, /* braille_dots_1238 */ - { 0x01002888, 8119 }, /* braille_dots_48 */ - { 0x01002889, 5877 }, /* braille_dots_148 */ - { 0x0100288a, 7029 }, /* braille_dots_248 */ - { 0x0100288b, 4724 }, /* braille_dots_1248 */ - { 0x0100288c, 7589 }, /* braille_dots_348 */ - { 0x0100288d, 5316 }, /* braille_dots_1348 */ - { 0x0100288e, 6468 }, /* braille_dots_2348 */ - { 0x0100288f, 4132 }, /* braille_dots_12348 */ - { 0x01002890, 8251 }, /* braille_dots_58 */ - { 0x01002891, 6017 }, /* braille_dots_158 */ - { 0x01002892, 7169 }, /* braille_dots_258 */ - { 0x01002893, 4872 }, /* braille_dots_1258 */ - { 0x01002894, 7729 }, /* braille_dots_358 */ - { 0x01002895, 5464 }, /* braille_dots_1358 */ - { 0x01002896, 6616 }, /* braille_dots_2358 */ - { 0x01002897, 4288 }, /* braille_dots_12358 */ - { 0x01002898, 8001 }, /* braille_dots_458 */ - { 0x01002899, 5752 }, /* braille_dots_1458 */ - { 0x0100289a, 6904 }, /* braille_dots_2458 */ - { 0x0100289b, 4592 }, /* braille_dots_12458 */ - { 0x0100289c, 7464 }, /* braille_dots_3458 */ - { 0x0100289d, 5184 }, /* braille_dots_13458 */ - { 0x0100289e, 6336 }, /* braille_dots_23458 */ - { 0x0100289f, 3993 }, /* braille_dots_123458 */ - { 0x010028a0, 8315 }, /* braille_dots_68 */ - { 0x010028a1, 6085 }, /* braille_dots_168 */ - { 0x010028a2, 7237 }, /* braille_dots_268 */ - { 0x010028a3, 4944 }, /* braille_dots_1268 */ - { 0x010028a4, 7797 }, /* braille_dots_368 */ - { 0x010028a5, 5536 }, /* braille_dots_1368 */ - { 0x010028a6, 6688 }, /* braille_dots_2368 */ - { 0x010028a7, 4364 }, /* braille_dots_12368 */ - { 0x010028a8, 8069 }, /* braille_dots_468 */ - { 0x010028a9, 5824 }, /* braille_dots_1468 */ - { 0x010028aa, 6976 }, /* braille_dots_2468 */ - { 0x010028ab, 4668 }, /* braille_dots_12468 */ - { 0x010028ac, 7536 }, /* braille_dots_3468 */ - { 0x010028ad, 5260 }, /* braille_dots_13468 */ - { 0x010028ae, 6412 }, /* braille_dots_23468 */ - { 0x010028af, 4073 }, /* braille_dots_123468 */ - { 0x010028b0, 8201 }, /* braille_dots_568 */ - { 0x010028b1, 5964 }, /* braille_dots_1568 */ - { 0x010028b2, 7116 }, /* braille_dots_2568 */ - { 0x010028b3, 4816 }, /* braille_dots_12568 */ - { 0x010028b4, 7676 }, /* braille_dots_3568 */ - { 0x010028b5, 5408 }, /* braille_dots_13568 */ - { 0x010028b6, 6560 }, /* braille_dots_23568 */ - { 0x010028b7, 4229 }, /* braille_dots_123568 */ - { 0x010028b8, 7948 }, /* braille_dots_4568 */ - { 0x010028b9, 5696 }, /* braille_dots_14568 */ - { 0x010028ba, 6848 }, /* braille_dots_24568 */ - { 0x010028bb, 4533 }, /* braille_dots_124568 */ - { 0x010028bc, 7408 }, /* braille_dots_34568 */ - { 0x010028bd, 5125 }, /* braille_dots_134568 */ - { 0x010028be, 6277 }, /* braille_dots_234568 */ - { 0x010028bf, 3931 }, /* braille_dots_1234568 */ - { 0x010028c0, 8346 }, /* braille_dots_78 */ - { 0x010028c1, 6118 }, /* braille_dots_178 */ - { 0x010028c2, 7270 }, /* braille_dots_278 */ - { 0x010028c3, 4979 }, /* braille_dots_1278 */ - { 0x010028c4, 7830 }, /* braille_dots_378 */ - { 0x010028c5, 5571 }, /* braille_dots_1378 */ - { 0x010028c6, 6723 }, /* braille_dots_2378 */ - { 0x010028c7, 4401 }, /* braille_dots_12378 */ - { 0x010028c8, 8102 }, /* braille_dots_478 */ - { 0x010028c9, 5859 }, /* braille_dots_1478 */ - { 0x010028ca, 7011 }, /* braille_dots_2478 */ - { 0x010028cb, 4705 }, /* braille_dots_12478 */ - { 0x010028cc, 7571 }, /* braille_dots_3478 */ - { 0x010028cd, 5297 }, /* braille_dots_13478 */ - { 0x010028ce, 6449 }, /* braille_dots_23478 */ - { 0x010028cf, 4112 }, /* braille_dots_123478 */ - { 0x010028d0, 8234 }, /* braille_dots_578 */ - { 0x010028d1, 5999 }, /* braille_dots_1578 */ - { 0x010028d2, 7151 }, /* braille_dots_2578 */ - { 0x010028d3, 4853 }, /* braille_dots_12578 */ - { 0x010028d4, 7711 }, /* braille_dots_3578 */ - { 0x010028d5, 5445 }, /* braille_dots_13578 */ - { 0x010028d6, 6597 }, /* braille_dots_23578 */ - { 0x010028d7, 4268 }, /* braille_dots_123578 */ - { 0x010028d8, 7983 }, /* braille_dots_4578 */ - { 0x010028d9, 5733 }, /* braille_dots_14578 */ - { 0x010028da, 6885 }, /* braille_dots_24578 */ - { 0x010028db, 4572 }, /* braille_dots_124578 */ - { 0x010028dc, 7445 }, /* braille_dots_34578 */ - { 0x010028dd, 5164 }, /* braille_dots_134578 */ - { 0x010028de, 6316 }, /* braille_dots_234578 */ - { 0x010028df, 3972 }, /* braille_dots_1234578 */ - { 0x010028e0, 8298 }, /* braille_dots_678 */ - { 0x010028e1, 6067 }, /* braille_dots_1678 */ - { 0x010028e2, 7219 }, /* braille_dots_2678 */ - { 0x010028e3, 4925 }, /* braille_dots_12678 */ - { 0x010028e4, 7779 }, /* braille_dots_3678 */ - { 0x010028e5, 5517 }, /* braille_dots_13678 */ - { 0x010028e6, 6669 }, /* braille_dots_23678 */ - { 0x010028e7, 4344 }, /* braille_dots_123678 */ - { 0x010028e8, 8051 }, /* braille_dots_4678 */ - { 0x010028e9, 5805 }, /* braille_dots_14678 */ - { 0x010028ea, 6957 }, /* braille_dots_24678 */ - { 0x010028eb, 4648 }, /* braille_dots_124678 */ - { 0x010028ec, 7517 }, /* braille_dots_34678 */ - { 0x010028ed, 5240 }, /* braille_dots_134678 */ - { 0x010028ee, 6392 }, /* braille_dots_234678 */ - { 0x010028ef, 4052 }, /* braille_dots_1234678 */ - { 0x010028f0, 8183 }, /* braille_dots_5678 */ - { 0x010028f1, 5945 }, /* braille_dots_15678 */ - { 0x010028f2, 7097 }, /* braille_dots_25678 */ - { 0x010028f3, 4796 }, /* braille_dots_125678 */ - { 0x010028f4, 7657 }, /* braille_dots_35678 */ - { 0x010028f5, 5388 }, /* braille_dots_135678 */ - { 0x010028f6, 6540 }, /* braille_dots_235678 */ - { 0x010028f7, 4208 }, /* braille_dots_1235678 */ - { 0x010028f8, 7929 }, /* braille_dots_45678 */ - { 0x010028f9, 5676 }, /* braille_dots_145678 */ - { 0x010028fa, 6828 }, /* braille_dots_245678 */ - { 0x010028fb, 4512 }, /* braille_dots_1245678 */ - { 0x010028fc, 7388 }, /* braille_dots_345678 */ - { 0x010028fd, 5104 }, /* braille_dots_1345678 */ - { 0x010028fe, 6256 }, /* braille_dots_2345678 */ - { 0x010028ff, 3909 }, /* braille_dots_12345678 */ - { 0x100000a8, 16910 }, /* hpmute_acute */ - { 0x100000a9, 16977 }, /* hpmute_grave */ - { 0x100000aa, 16923 }, /* hpmute_asciicircum */ - { 0x100000ab, 16960 }, /* hpmute_diaeresis */ - { 0x100000ac, 16942 }, /* hpmute_asciitilde */ - { 0x100000af, 16867 }, /* hplira */ - { 0x100000be, 16813 }, /* hpguilder */ - { 0x100000ee, 17014 }, /* hpYdiaeresis */ - { 0x100000f6, 16874 }, /* hplongminus */ - { 0x100000fc, 16767 }, /* hpblock */ - { 0x1000fe22, 10414 }, /* Ddiaeresis */ - { 0x1000fe27, 10344 }, /* Dacute_accent */ - { 0x1000fe2c, 10379 }, /* Dcedilla_accent */ - { 0x1000fe5e, 10395 }, /* Dcircumflex_accent */ - { 0x1000fe60, 11189 }, /* Dgrave_accent */ - { 0x1000fe7e, 11417 }, /* Dtilde */ - { 0x1000feb0, 11388 }, /* Dring_accent */ - { 0x1000ff00, 11380 }, /* DRemove */ - { 0x1000ff48, 16886 }, /* hpModelock1 */ - { 0x1000ff49, 16898 }, /* hpModelock2 */ - { 0x1000ff6c, 16990 }, /* hpReset */ - { 0x1000ff6d, 16998 }, /* hpSystem */ - { 0x1000ff6e, 17007 }, /* hpUser */ - { 0x1000ff6f, 16775 }, /* hpClearLine */ - { 0x1000ff70, 16836 }, /* hpInsertLine */ - { 0x1000ff71, 16800 }, /* hpDeleteLine */ - { 0x1000ff72, 16823 }, /* hpInsertChar */ - { 0x1000ff73, 16787 }, /* hpDeleteChar */ - { 0x1000ff74, 16757 }, /* hpBackTab */ - { 0x1000ff75, 16854 }, /* hpKP_BackTab */ - { 0x1000ff76, 12125 }, /* Ext16bit_L */ - { 0x1000ff77, 12136 }, /* Ext16bit_R */ - { 0x1004ff02, 20956 }, /* osfCopy */ - { 0x1004ff03, 20964 }, /* osfCut */ - { 0x1004ff04, 21163 }, /* osfPaste */ - { 0x1004ff07, 20900 }, /* osfBackTab */ - { 0x1004ff08, 20887 }, /* osfBackSpace */ - { 0x1004ff0b, 20947 }, /* osfClear */ - { 0x1004ff1b, 21026 }, /* osfEscape */ - { 0x1004ff31, 20876 }, /* osfAddMode */ - { 0x1004ff32, 21197 }, /* osfPrimaryPaste */ - { 0x1004ff33, 21213 }, /* osfQuickPaste */ - { 0x1004ff40, 21128 }, /* osfPageLeft */ - { 0x1004ff41, 21153 }, /* osfPageUp */ - { 0x1004ff42, 21116 }, /* osfPageDown */ - { 0x1004ff43, 21140 }, /* osfPageRight */ - { 0x1004ff44, 20864 }, /* osfActivate */ - { 0x1004ff45, 21080 }, /* osfMenuBar */ - { 0x1004ff51, 21064 }, /* osfLeft */ - { 0x1004ff52, 21290 }, /* osfUp */ - { 0x1004ff53, 21250 }, /* osfRight */ - { 0x1004ff54, 20996 }, /* osfDown */ - { 0x1004ff57, 21015 }, /* osfEndLine */ - { 0x1004ff58, 20924 }, /* osfBeginLine */ - { 0x1004ff59, 21004 }, /* osfEndData */ - { 0x1004ff5a, 20911 }, /* osfBeginData */ - { 0x1004ff5b, 21185 }, /* osfPrevMenu */ - { 0x1004ff5c, 21104 }, /* osfNextMenu */ - { 0x1004ff5d, 21172 }, /* osfPrevField */ - { 0x1004ff5e, 21091 }, /* osfNextField */ - { 0x1004ff60, 21259 }, /* osfSelect */ - { 0x1004ff63, 21054 }, /* osfInsert */ - { 0x1004ff65, 21282 }, /* osfUndo */ - { 0x1004ff67, 21072 }, /* osfMenu */ - { 0x1004ff69, 20937 }, /* osfCancel */ - { 0x1004ff6a, 21046 }, /* osfHelp */ - { 0x1004ff71, 21269 }, /* osfSelectAll */ - { 0x1004ff72, 20981 }, /* osfDeselectAll */ - { 0x1004ff73, 21227 }, /* osfReselect */ - { 0x1004ff74, 21036 }, /* osfExtend */ - { 0x1004ff78, 21239 }, /* osfRestore */ - { 0x1004ffff, 20971 }, /* osfDelete */ - { 0x1005ff00, 24032 }, /* SunFA_Grave */ - { 0x1005ff01, 24003 }, /* SunFA_Circum */ - { 0x1005ff02, 24044 }, /* SunFA_Tilde */ - { 0x1005ff03, 23977 }, /* SunFA_Acute */ - { 0x1005ff04, 24016 }, /* SunFA_Diaeresis */ - { 0x1005ff05, 23989 }, /* SunFA_Cedilla */ - { 0x1005ff10, 23963 }, /* SunF36 */ - { 0x1005ff11, 23970 }, /* SunF37 */ - { 0x1005ff60, 24180 }, /* SunSys_Req */ - { 0x1005ff70, 24163 }, /* SunProps */ - { 0x1005ff71, 24064 }, /* SunFront */ - { 0x1005ff72, 23948 }, /* SunCopy */ - { 0x1005ff73, 24073 }, /* SunOpen */ - { 0x1005ff74, 24103 }, /* SunPaste */ - { 0x1005ff75, 23956 }, /* SunCut */ - { 0x1005ff76, 24112 }, /* SunPowerSwitch */ - { 0x1005ff77, 23884 }, /* SunAudioLowerVolume */ - { 0x1005ff78, 23904 }, /* SunAudioMute */ - { 0x1005ff79, 23917 }, /* SunAudioRaiseVolume */ - { 0x1005ff7a, 24199 }, /* SunVideoDegauss */ - { 0x1005ff7b, 24215 }, /* SunVideoLowerBrightness */ - { 0x1005ff7c, 24239 }, /* SunVideoRaiseBrightness */ - { 0x1005ff7d, 24127 }, /* SunPowerSwitchShift */ - { 0x1008fe01, 28491 }, /* XF86Switch_VT_1 */ - { 0x1008fe02, 28558 }, /* XF86Switch_VT_2 */ - { 0x1008fe03, 28574 }, /* XF86Switch_VT_3 */ - { 0x1008fe04, 28590 }, /* XF86Switch_VT_4 */ - { 0x1008fe05, 28606 }, /* XF86Switch_VT_5 */ - { 0x1008fe06, 28622 }, /* XF86Switch_VT_6 */ - { 0x1008fe07, 28638 }, /* XF86Switch_VT_7 */ - { 0x1008fe08, 28654 }, /* XF86Switch_VT_8 */ - { 0x1008fe09, 28670 }, /* XF86Switch_VT_9 */ - { 0x1008fe0a, 28507 }, /* XF86Switch_VT_10 */ - { 0x1008fe0b, 28524 }, /* XF86Switch_VT_11 */ - { 0x1008fe0c, 28541 }, /* XF86Switch_VT_12 */ - { 0x1008fe20, 28817 }, /* XF86Ungrab */ - { 0x1008fe21, 27151 }, /* XF86ClearGrab */ - { 0x1008fe22, 27991 }, /* XF86Next_VMode */ - { 0x1008fe23, 28113 }, /* XF86Prev_VMode */ - { 0x1008fe24, 27771 }, /* XF86LogWindowTree */ - { 0x1008fe25, 27744 }, /* XF86LogGrabInfo */ - { 0x1008ff01, 27882 }, /* XF86ModeLock */ - { 0x1008ff02, 27917 }, /* XF86MonBrightnessUp */ - { 0x1008ff03, 27895 }, /* XF86MonBrightnessDown */ - { 0x1008ff04, 27507 }, /* XF86KbdLightOnOff */ - { 0x1008ff05, 27487 }, /* XF86KbdBrightnessUp */ - { 0x1008ff06, 27465 }, /* XF86KbdBrightnessDown */ - { 0x1008ff10, 28423 }, /* XF86Standby */ - { 0x1008ff11, 26749 }, /* XF86AudioLowerVolume */ - { 0x1008ff12, 26802 }, /* XF86AudioMute */ - { 0x1008ff13, 26889 }, /* XF86AudioRaiseVolume */ - { 0x1008ff14, 26845 }, /* XF86AudioPlay */ - { 0x1008ff15, 26978 }, /* XF86AudioStop */ - { 0x1008ff16, 26875 }, /* XF86AudioPrev */ - { 0x1008ff17, 26816 }, /* XF86AudioNext */ - { 0x1008ff18, 27428 }, /* XF86HomePage */ - { 0x1008ff19, 27789 }, /* XF86Mail */ - { 0x1008ff1a, 28435 }, /* XF86Start */ - { 0x1008ff1b, 28347 }, /* XF86Search */ - { 0x1008ff1c, 26930 }, /* XF86AudioRecord */ - { 0x1008ff1d, 27106 }, /* XF86Calculator */ - { 0x1008ff1e, 27837 }, /* XF86Memo */ - { 0x1008ff1f, 28721 }, /* XF86ToDoList */ - { 0x1008ff20, 27121 }, /* XF86Calendar */ - { 0x1008ff21, 28086 }, /* XF86PowerDown */ - { 0x1008ff22, 27189 }, /* XF86ContrastAdjust */ - { 0x1008ff23, 28217 }, /* XF86RockerUp */ - { 0x1008ff24, 28186 }, /* XF86RockerDown */ - { 0x1008ff25, 28201 }, /* XF86RockerEnter */ - { 0x1008ff26, 27001 }, /* XF86Back */ - { 0x1008ff27, 27333 }, /* XF86Forward */ - { 0x1008ff28, 28445 }, /* XF86Stop */ - { 0x1008ff29, 28142 }, /* XF86Refresh */ - { 0x1008ff2a, 28100 }, /* XF86PowerOff */ - { 0x1008ff2b, 28905 }, /* XF86WakeUp */ - { 0x1008ff2c, 27274 }, /* XF86Eject */ - { 0x1008ff2d, 28287 }, /* XF86ScreenSaver */ - { 0x1008ff2e, 28970 }, /* XF86WWW */ - { 0x1008ff2f, 28387 }, /* XF86Sleep */ - { 0x1008ff30, 27307 }, /* XF86Favorites */ - { 0x1008ff31, 26830 }, /* XF86AudioPause */ - { 0x1008ff32, 26770 }, /* XF86AudioMedia */ - { 0x1008ff33, 27947 }, /* XF86MyComputer */ - { 0x1008ff34, 28871 }, /* XF86VendorHome */ - { 0x1008ff35, 27730 }, /* XF86LightBulb */ - { 0x1008ff36, 28378 }, /* XF86Shop */ - { 0x1008ff37, 27416 }, /* XF86History */ - { 0x1008ff38, 28030 }, /* XF86OpenURL */ - { 0x1008ff39, 26655 }, /* XF86AddFavorite */ - { 0x1008ff3a, 27441 }, /* XF86HotLinks */ - { 0x1008ff3b, 27070 }, /* XF86BrightnessAdjust */ - { 0x1008ff3c, 27321 }, /* XF86Finance */ - { 0x1008ff3d, 27175 }, /* XF86Community */ - { 0x1008ff3e, 26962 }, /* XF86AudioRewind */ - { 0x1008ff3f, 27010 }, /* XF86BackForward */ - { 0x1008ff40, 27538 }, /* XF86Launch0 */ - { 0x1008ff41, 27550 }, /* XF86Launch1 */ - { 0x1008ff42, 27562 }, /* XF86Launch2 */ - { 0x1008ff43, 27574 }, /* XF86Launch3 */ - { 0x1008ff44, 27586 }, /* XF86Launch4 */ - { 0x1008ff45, 27598 }, /* XF86Launch5 */ - { 0x1008ff46, 27610 }, /* XF86Launch6 */ - { 0x1008ff47, 27622 }, /* XF86Launch7 */ - { 0x1008ff48, 27634 }, /* XF86Launch8 */ - { 0x1008ff49, 27646 }, /* XF86Launch9 */ - { 0x1008ff4a, 27658 }, /* XF86LaunchA */ - { 0x1008ff4b, 27670 }, /* XF86LaunchB */ - { 0x1008ff4c, 27682 }, /* XF86LaunchC */ - { 0x1008ff4d, 27694 }, /* XF86LaunchD */ - { 0x1008ff4e, 27706 }, /* XF86LaunchE */ - { 0x1008ff4f, 27718 }, /* XF86LaunchF */ - { 0x1008ff50, 26671 }, /* XF86ApplicationLeft */ - { 0x1008ff51, 26691 }, /* XF86ApplicationRight */ - { 0x1008ff52, 27061 }, /* XF86Book */ - { 0x1008ff53, 27134 }, /* XF86CD */ - { 0x1008ff54, 27091 }, /* XF86Calculater */ - { 0x1008ff55, 27141 }, /* XF86Clear */ - { 0x1008ff56, 27165 }, /* XF86Close */ - { 0x1008ff57, 27208 }, /* XF86Copy */ - { 0x1008ff58, 27217 }, /* XF86Cut */ - { 0x1008ff59, 27240 }, /* XF86Display */ - { 0x1008ff5a, 27266 }, /* XF86DOS */ - { 0x1008ff5b, 27252 }, /* XF86Documents */ - { 0x1008ff5c, 27284 }, /* XF86Excel */ - { 0x1008ff5d, 27294 }, /* XF86Explorer */ - { 0x1008ff5e, 27376 }, /* XF86Game */ - { 0x1008ff5f, 27385 }, /* XF86Go */ - { 0x1008ff60, 27454 }, /* XF86iTouch */ - { 0x1008ff61, 27760 }, /* XF86LogOff */ - { 0x1008ff62, 27814 }, /* XF86Market */ - { 0x1008ff63, 27825 }, /* XF86Meeting */ - { 0x1008ff65, 27846 }, /* XF86MenuKB */ - { 0x1008ff66, 27857 }, /* XF86MenuPB */ - { 0x1008ff67, 27962 }, /* XF86MySites */ - { 0x1008ff68, 27974 }, /* XF86New */ - { 0x1008ff69, 27982 }, /* XF86News */ - { 0x1008ff6a, 28006 }, /* XF86OfficeHome */ - { 0x1008ff6b, 28021 }, /* XF86Open */ - { 0x1008ff6c, 28042 }, /* XF86Option */ - { 0x1008ff6d, 28053 }, /* XF86Paste */ - { 0x1008ff6e, 28063 }, /* XF86Phone */ - { 0x1008ff70, 28128 }, /* XF86Q */ - { 0x1008ff72, 28165 }, /* XF86Reply */ - { 0x1008ff73, 28154 }, /* XF86Reload */ - { 0x1008ff74, 28230 }, /* XF86RotateWindows */ - { 0x1008ff75, 28263 }, /* XF86RotationPB */ - { 0x1008ff76, 28248 }, /* XF86RotationKB */ - { 0x1008ff77, 28278 }, /* XF86Save */ - { 0x1008ff78, 28334 }, /* XF86ScrollUp */ - { 0x1008ff79, 28319 }, /* XF86ScrollDown */ - { 0x1008ff7a, 28303 }, /* XF86ScrollClick */ - { 0x1008ff7b, 28369 }, /* XF86Send */ - { 0x1008ff7c, 28397 }, /* XF86Spell */ - { 0x1008ff7d, 28407 }, /* XF86SplitScreen */ - { 0x1008ff7e, 28467 }, /* XF86Support */ - { 0x1008ff7f, 28686 }, /* XF86TaskPane */ - { 0x1008ff80, 28699 }, /* XF86Terminal */ - { 0x1008ff81, 28734 }, /* XF86Tools */ - { 0x1008ff82, 28806 }, /* XF86Travel */ - { 0x1008ff84, 28852 }, /* XF86UserPB */ - { 0x1008ff85, 28828 }, /* XF86User1KB */ - { 0x1008ff86, 28840 }, /* XF86User2KB */ - { 0x1008ff87, 28886 }, /* XF86Video */ - { 0x1008ff88, 28927 }, /* XF86WheelButton */ - { 0x1008ff89, 28952 }, /* XF86Word */ - { 0x1008ff8a, 28978 }, /* XF86Xfer */ - { 0x1008ff8b, 28998 }, /* XF86ZoomIn */ - { 0x1008ff8c, 29009 }, /* XF86ZoomOut */ - { 0x1008ff8d, 26992 }, /* XF86Away */ - { 0x1008ff8e, 27868 }, /* XF86Messenger */ - { 0x1008ff8f, 28916 }, /* XF86WebCam */ - { 0x1008ff90, 27798 }, /* XF86MailForward */ - { 0x1008ff91, 28073 }, /* XF86Pictures */ - { 0x1008ff92, 27937 }, /* XF86Music */ - { 0x1008ff93, 27026 }, /* XF86Battery */ - { 0x1008ff94, 27047 }, /* XF86Bluetooth */ - { 0x1008ff95, 28943 }, /* XF86WLAN */ - { 0x1008ff96, 28863 }, /* XF86UWB */ - { 0x1008ff97, 26732 }, /* XF86AudioForward */ - { 0x1008ff98, 26946 }, /* XF86AudioRepeat */ - { 0x1008ff99, 26910 }, /* XF86AudioRandomPlay */ - { 0x1008ff9a, 28454 }, /* XF86Subtitle */ - { 0x1008ff9b, 26712 }, /* XF86AudioCycleTrack */ - { 0x1008ff9c, 27225 }, /* XF86CycleAngle */ - { 0x1008ff9d, 27345 }, /* XF86FrameBack */ - { 0x1008ff9e, 27359 }, /* XF86FrameForward */ - { 0x1008ff9f, 28712 }, /* XF86Time */ - { 0x1008ffa0, 28358 }, /* XF86Select */ - { 0x1008ffa1, 28896 }, /* XF86View */ - { 0x1008ffa2, 28744 }, /* XF86TopMenu */ - { 0x1008ffa3, 28134 }, /* XF86Red */ - { 0x1008ffa4, 27392 }, /* XF86Green */ - { 0x1008ffa5, 28987 }, /* XF86Yellow */ - { 0x1008ffa6, 27038 }, /* XF86Blue */ - { 0x1008ffa7, 28479 }, /* XF86Suspend */ - { 0x1008ffa8, 27402 }, /* XF86Hibernate */ - { 0x1008ffa9, 28787 }, /* XF86TouchpadToggle */ - { 0x1008ffb0, 28772 }, /* XF86TouchpadOn */ - { 0x1008ffb1, 28756 }, /* XF86TouchpadOff */ - { 0x1008ffb2, 26785 }, /* XF86AudioMicMute */ - { 0x1008ffb3, 27525 }, /* XF86Keyboard */ - { 0x1008ffb4, 28961 }, /* XF86WWAN */ - { 0x1008ffb5, 28175 }, /* XF86RFKill */ - { 0x1008ffb6, 26859 }, /* XF86AudioPreset */ -}; diff --git a/src/3rdparty/xkbcommon/src/scanner-utils.h b/src/3rdparty/xkbcommon/src/scanner-utils.h deleted file mode 100644 index 5fdb22ae9a..0000000000 --- a/src/3rdparty/xkbcommon/src/scanner-utils.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright © 2012 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef XKBCOMP_SCANNER_UTILS_H -#define XKBCOMP_SCANNER_UTILS_H - -/* Point to some substring in the file; used to avoid copying. */ -struct sval { - const char *start; - unsigned int len; -}; -typedef darray(struct sval) darray_sval; - -static inline bool -svaleq(struct sval s1, struct sval s2) -{ - return s1.len == s2.len && memcmp(s1.start, s2.start, s1.len) == 0; -} - -static inline bool -svaleq_prefix(struct sval s1, struct sval s2) -{ - return s1.len <= s2.len && memcmp(s1.start, s2.start, s1.len) == 0; -} - -struct scanner { - const char *s; - size_t pos; - size_t len; - char buf[1024]; - size_t buf_pos; - unsigned line, column; - /* The line/column of the start of the current token. */ - unsigned token_line, token_column; - const char *file_name; - struct xkb_context *ctx; - void *priv; -}; - -#define scanner_log(scanner, level, fmt, ...) \ - xkb_log((scanner)->ctx, (level), 0, \ - "%s:%u:%u: " fmt "\n", \ - (scanner)->file_name, \ - (scanner)->token_line, (scanner)->token_column, ##__VA_ARGS__) - -#define scanner_err(scanner, fmt, ...) \ - scanner_log(scanner, XKB_LOG_LEVEL_ERROR, fmt, ##__VA_ARGS__) - -#define scanner_warn(scanner, fmt, ...) \ - scanner_log(scanner, XKB_LOG_LEVEL_WARNING, fmt, ##__VA_ARGS__) - -static inline void -scanner_init(struct scanner *s, struct xkb_context *ctx, - const char *string, size_t len, const char *file_name, - void *priv) -{ - s->s = string; - s->len = len; - s->pos = 0; - s->line = s->column = 1; - s->token_line = s->token_column = 1; - s->file_name = file_name; - s->ctx = ctx; - s->priv = priv; -} - -static inline char -peek(struct scanner *s) -{ - if (unlikely(s->pos >= s->len)) - return '\0'; - return s->s[s->pos]; -} - -static inline bool -eof(struct scanner *s) -{ - return s->pos >= s->len; -} - -static inline bool -eol(struct scanner *s) -{ - return peek(s) == '\n'; -} - -static inline void -skip_to_eol(struct scanner *s) -{ - const char *nl = memchr(s->s + s->pos, '\n', s->len - s->pos); - const size_t new_pos = nl ? (size_t) (nl - s->s) : s->len; - s->column += new_pos - s->pos; - s->pos = new_pos; -} - -static inline char -next(struct scanner *s) -{ - if (unlikely(eof(s))) - return '\0'; - if (unlikely(eol(s))) { - s->line++; - s->column = 1; - } - else { - s->column++; - } - return s->s[s->pos++]; -} - -static inline bool -chr(struct scanner *s, char ch) -{ - if (likely(peek(s) != ch)) - return false; - s->pos++; s->column++; - return true; -} - -static inline bool -str(struct scanner *s, const char *string, size_t len) -{ - if (s->len - s->pos < len) - return false; - if (memcmp(s->s + s->pos, string, len) != 0) - return false; - s->pos += len; s->column += len; - return true; -} - -#define lit(s, literal) str(s, literal, sizeof(literal) - 1) - -static inline bool -buf_append(struct scanner *s, char ch) -{ - if (s->buf_pos + 1 >= sizeof(s->buf)) - return false; - s->buf[s->buf_pos++] = ch; - return true; -} - -static inline bool -buf_appends(struct scanner *s, const char *str) -{ - int ret; - ret = snprintf(s->buf + s->buf_pos, sizeof(s->buf) - s->buf_pos, "%s", str); - if (ret < 0 || (size_t) ret >= sizeof(s->buf) - s->buf_pos) - return false; - s->buf_pos += ret; - return true; -} - -static inline bool -oct(struct scanner *s, uint8_t *out) -{ - int i; - for (i = 0, *out = 0; peek(s) >= '0' && peek(s) <= '7' && i < 3; i++) - *out = *out * 8 + next(s) - '0'; - return i > 0; -} - -static inline bool -hex(struct scanner *s, uint8_t *out) -{ - int i; - for (i = 0, *out = 0; is_xdigit(peek(s)) && i < 2; i++) { - const char c = next(s); - const char offset = (c >= '0' && c <= '9' ? '0' : - c >= 'a' && c <= 'f' ? 'a' - 10 : 'A' - 10); - *out = *out * 16 + c - offset; - } - return i > 0; -} - -#endif diff --git a/src/3rdparty/xkbcommon/src/state.c b/src/3rdparty/xkbcommon/src/state.c deleted file mode 100644 index 16a4caa23d..0000000000 --- a/src/3rdparty/xkbcommon/src/state.c +++ /dev/null @@ -1,1446 +0,0 @@ -/************************************************************ - * Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting - * documentation, and that the name of Silicon Graphics not be - * used in advertising or publicity pertaining to distribution - * of the software without specific prior written permission. - * Silicon Graphics makes no representation about the suitability - * of this software for any purpose. It is provided "as is" - * without any express or implied warranty. - * - * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - * THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - ********************************************************/ - -/* - * Copyright © 2012 Intel Corporation - * Copyright © 2012 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Daniel Stone - */ - -/* - * This is a bastardised version of xkbActions.c from the X server which - * does not support, for the moment: - * - AccessX sticky/debounce/etc (will come later) - * - pointer keys (may come later) - * - key redirects (unlikely) - * - messages (very unlikely) - */ - -#include "keymap.h" -#include "keysym.h" -#include "utf8.h" - -struct xkb_filter { - union xkb_action action; - const struct xkb_key *key; - uint32_t priv; - bool (*func)(struct xkb_state *state, - struct xkb_filter *filter, - const struct xkb_key *key, - enum xkb_key_direction direction); - int refcnt; -}; - -struct state_components { - /* These may be negative, because of -1 group actions. */ - int32_t base_group; /**< depressed */ - int32_t latched_group; - int32_t locked_group; - xkb_layout_index_t group; /**< effective */ - - xkb_mod_mask_t base_mods; /**< depressed */ - xkb_mod_mask_t latched_mods; - xkb_mod_mask_t locked_mods; - xkb_mod_mask_t mods; /**< effective */ - - xkb_led_mask_t leds; -}; - -struct xkb_state { - /* - * Before updating the state, we keep a copy of just this struct. This - * allows us to report which components of the state have changed. - */ - struct state_components components; - - /* - * At each event, we accumulate all the needed modifications to the base - * modifiers, and apply them at the end. These keep track of this state. - */ - xkb_mod_mask_t set_mods; - xkb_mod_mask_t clear_mods; - - /* - * We mustn't clear a base modifier if there's another depressed key - * which affects it, e.g. given this sequence - * < Left Shift down, Right Shift down, Left Shift Up > - * the modifier should still be set. This keeps the count. - */ - int16_t mod_key_count[XKB_MAX_MODS]; - - int refcnt; - darray(struct xkb_filter) filters; - struct xkb_keymap *keymap; -}; - -/* - * If the virtual modifiers are not bound to anything, the entry - * is not active and should be skipped. xserver does this with - * cached entry->active field. - */ -static bool -entry_is_active(const struct xkb_key_type_entry *entry) -{ - return entry->mods.mods == 0 || entry->mods.mask != 0; -} - -static const struct xkb_key_type_entry * -get_entry_for_mods(const struct xkb_key_type *type, xkb_mod_mask_t mods) -{ - for (unsigned i = 0; i < type->num_entries; i++) - if (entry_is_active(&type->entries[i]) && - type->entries[i].mods.mask == mods) - return &type->entries[i]; - return NULL; -} - -static const struct xkb_key_type_entry * -get_entry_for_key_state(struct xkb_state *state, const struct xkb_key *key, - xkb_layout_index_t group) -{ - const struct xkb_key_type *type = key->groups[group].type; - xkb_mod_mask_t active_mods = state->components.mods & type->mods.mask; - return get_entry_for_mods(type, active_mods); -} - -/** - * Returns the level to use for the given key and state, or - * XKB_LEVEL_INVALID. - */ -XKB_EXPORT xkb_level_index_t -xkb_state_key_get_level(struct xkb_state *state, xkb_keycode_t kc, - xkb_layout_index_t layout) -{ - const struct xkb_key *key = XkbKey(state->keymap, kc); - const struct xkb_key_type_entry *entry; - - if (!key || layout >= key->num_groups) - return XKB_LEVEL_INVALID; - - /* If we don't find an explicit match the default is 0. */ - entry = get_entry_for_key_state(state, key, layout); - if (!entry) - return 0; - - return entry->level; -} - -xkb_layout_index_t -XkbWrapGroupIntoRange(int32_t group, - xkb_layout_index_t num_groups, - enum xkb_range_exceed_type out_of_range_group_action, - xkb_layout_index_t out_of_range_group_number) -{ - if (num_groups == 0) - return XKB_LAYOUT_INVALID; - - if (group >= 0 && (xkb_layout_index_t) group < num_groups) - return group; - - switch (out_of_range_group_action) { - case RANGE_REDIRECT: - if (out_of_range_group_number >= num_groups) - return 0; - return out_of_range_group_number; - - case RANGE_SATURATE: - if (group < 0) - return 0; - else - return num_groups - 1; - - case RANGE_WRAP: - default: - /* - * C99 says a negative dividend in a modulo operation always - * gives a negative result. - */ - if (group < 0) - return ((int) num_groups + (group % (int) num_groups)); - else - return group % num_groups; - } -} - -/** - * Returns the layout to use for the given key and state, taking - * wrapping/clamping/etc into account, or XKB_LAYOUT_INVALID. - */ -XKB_EXPORT xkb_layout_index_t -xkb_state_key_get_layout(struct xkb_state *state, xkb_keycode_t kc) -{ - const struct xkb_key *key = XkbKey(state->keymap, kc); - - if (!key) - return XKB_LAYOUT_INVALID; - - return XkbWrapGroupIntoRange(state->components.group, key->num_groups, - key->out_of_range_group_action, - key->out_of_range_group_number); -} - -static const union xkb_action * -xkb_key_get_action(struct xkb_state *state, const struct xkb_key *key) -{ - static const union xkb_action dummy = { .type = ACTION_TYPE_NONE }; - - xkb_layout_index_t layout; - xkb_level_index_t level; - - layout = xkb_state_key_get_layout(state, key->keycode); - if (layout == XKB_LAYOUT_INVALID) - return &dummy; - - level = xkb_state_key_get_level(state, key->keycode, layout); - if (level == XKB_LEVEL_INVALID) - return &dummy; - - return &key->groups[layout].levels[level].action; -} - -static struct xkb_filter * -xkb_filter_new(struct xkb_state *state) -{ - struct xkb_filter *filter = NULL, *iter; - - darray_foreach(iter, state->filters) { - if (iter->func) - continue; - filter = iter; - break; - } - - if (!filter) { - darray_resize0(state->filters, darray_size(state->filters) + 1); - filter = &darray_item(state->filters, darray_size(state->filters) -1); - } - - filter->refcnt = 1; - return filter; -} - -/***====================================================================***/ - -enum xkb_filter_result { - /* - * The event is consumed by the filters. - * - * An event is always processed by all filters, but any filter can - * prevent it from being processed further by consuming it. - */ - XKB_FILTER_CONSUME, - /* - * The event may continue to be processed as far as this filter is - * concerned. - */ - XKB_FILTER_CONTINUE, -}; - -static void -xkb_filter_group_set_new(struct xkb_state *state, struct xkb_filter *filter) -{ - filter->priv = state->components.base_group; - if (filter->action.group.flags & ACTION_ABSOLUTE_SWITCH) - state->components.base_group = filter->action.group.group; - else - state->components.base_group += filter->action.group.group; -} - -static bool -xkb_filter_group_set_func(struct xkb_state *state, - struct xkb_filter *filter, - const struct xkb_key *key, - enum xkb_key_direction direction) -{ - if (key != filter->key) { - filter->action.group.flags &= ~ACTION_LOCK_CLEAR; - return XKB_FILTER_CONTINUE; - } - - if (direction == XKB_KEY_DOWN) { - filter->refcnt++; - return XKB_FILTER_CONSUME; - } - else if (--filter->refcnt > 0) { - return XKB_FILTER_CONSUME; - } - - state->components.base_group = filter->priv; - - if (filter->action.group.flags & ACTION_LOCK_CLEAR) - state->components.locked_group = 0; - - filter->func = NULL; - return XKB_FILTER_CONTINUE; -} - -static void -xkb_filter_group_lock_new(struct xkb_state *state, struct xkb_filter *filter) -{ - if (filter->action.group.flags & ACTION_ABSOLUTE_SWITCH) - state->components.locked_group = filter->action.group.group; - else - state->components.locked_group += filter->action.group.group; -} - -static bool -xkb_filter_group_lock_func(struct xkb_state *state, - struct xkb_filter *filter, - const struct xkb_key *key, - enum xkb_key_direction direction) -{ - if (key != filter->key) - return XKB_FILTER_CONTINUE; - - if (direction == XKB_KEY_DOWN) { - filter->refcnt++; - return XKB_FILTER_CONSUME; - } - if (--filter->refcnt > 0) - return XKB_FILTER_CONSUME; - - filter->func = NULL; - return XKB_FILTER_CONTINUE; -} - -static void -xkb_filter_mod_set_new(struct xkb_state *state, struct xkb_filter *filter) -{ - state->set_mods = filter->action.mods.mods.mask; -} - -static bool -xkb_filter_mod_set_func(struct xkb_state *state, - struct xkb_filter *filter, - const struct xkb_key *key, - enum xkb_key_direction direction) -{ - if (key != filter->key) { - filter->action.mods.flags &= ~ACTION_LOCK_CLEAR; - return XKB_FILTER_CONTINUE; - } - - if (direction == XKB_KEY_DOWN) { - filter->refcnt++; - return XKB_FILTER_CONSUME; - } - else if (--filter->refcnt > 0) { - return XKB_FILTER_CONSUME; - } - - state->clear_mods = filter->action.mods.mods.mask; - if (filter->action.mods.flags & ACTION_LOCK_CLEAR) - state->components.locked_mods &= ~filter->action.mods.mods.mask; - - filter->func = NULL; - return XKB_FILTER_CONTINUE; -} - -static void -xkb_filter_mod_lock_new(struct xkb_state *state, struct xkb_filter *filter) -{ - filter->priv = (state->components.locked_mods & - filter->action.mods.mods.mask); - state->set_mods |= filter->action.mods.mods.mask; - if (!(filter->action.mods.flags & ACTION_LOCK_NO_LOCK)) - state->components.locked_mods |= filter->action.mods.mods.mask; -} - -static bool -xkb_filter_mod_lock_func(struct xkb_state *state, - struct xkb_filter *filter, - const struct xkb_key *key, - enum xkb_key_direction direction) -{ - if (key != filter->key) - return XKB_FILTER_CONTINUE; - - if (direction == XKB_KEY_DOWN) { - filter->refcnt++; - return XKB_FILTER_CONSUME; - } - if (--filter->refcnt > 0) - return XKB_FILTER_CONSUME; - - state->clear_mods |= filter->action.mods.mods.mask; - if (!(filter->action.mods.flags & ACTION_LOCK_NO_UNLOCK)) - state->components.locked_mods &= ~filter->priv; - - filter->func = NULL; - return XKB_FILTER_CONTINUE; -} - -enum xkb_key_latch_state { - NO_LATCH, - LATCH_KEY_DOWN, - LATCH_PENDING, -}; - -static bool -xkb_action_breaks_latch(const union xkb_action *action) -{ - switch (action->type) { - case ACTION_TYPE_NONE: - case ACTION_TYPE_PTR_BUTTON: - case ACTION_TYPE_PTR_LOCK: - case ACTION_TYPE_CTRL_SET: - case ACTION_TYPE_CTRL_LOCK: - case ACTION_TYPE_SWITCH_VT: - case ACTION_TYPE_TERMINATE: - return true; - default: - return false; - } -} - -static void -xkb_filter_mod_latch_new(struct xkb_state *state, struct xkb_filter *filter) -{ - filter->priv = LATCH_KEY_DOWN; - state->set_mods = filter->action.mods.mods.mask; -} - -static bool -xkb_filter_mod_latch_func(struct xkb_state *state, - struct xkb_filter *filter, - const struct xkb_key *key, - enum xkb_key_direction direction) -{ - enum xkb_key_latch_state latch = filter->priv; - - if (direction == XKB_KEY_DOWN && latch == LATCH_PENDING) { - /* If this is a new keypress and we're awaiting our single latched - * keypress, then either break the latch if any random key is pressed, - * or promote it to a lock or plain base set if it's the same - * modifier. */ - const union xkb_action *action = xkb_key_get_action(state, key); - if (action->type == ACTION_TYPE_MOD_LATCH && - action->mods.flags == filter->action.mods.flags && - action->mods.mods.mask == filter->action.mods.mods.mask) { - filter->action = *action; - if (filter->action.mods.flags & ACTION_LATCH_TO_LOCK) { - filter->action.type = ACTION_TYPE_MOD_LOCK; - filter->func = xkb_filter_mod_lock_func; - state->components.locked_mods |= filter->action.mods.mods.mask; - } - else { - filter->action.type = ACTION_TYPE_MOD_SET; - filter->func = xkb_filter_mod_set_func; - state->set_mods = filter->action.mods.mods.mask; - } - filter->key = key; - state->components.latched_mods &= ~filter->action.mods.mods.mask; - /* XXX beep beep! */ - return XKB_FILTER_CONSUME; - } - else if (xkb_action_breaks_latch(action)) { - /* XXX: This may be totally broken, we might need to break the - * latch in the next run after this press? */ - state->components.latched_mods &= ~filter->action.mods.mods.mask; - filter->func = NULL; - return XKB_FILTER_CONTINUE; - } - } - else if (direction == XKB_KEY_UP && key == filter->key) { - /* Our key got released. If we've set it to clear locks, and we - * currently have the same modifiers locked, then release them and - * don't actually latch. Else we've actually hit the latching - * stage, so set PENDING and move our modifier from base to - * latched. */ - if (latch == NO_LATCH || - ((filter->action.mods.flags & ACTION_LOCK_CLEAR) && - (state->components.locked_mods & filter->action.mods.mods.mask) == - filter->action.mods.mods.mask)) { - /* XXX: We might be a bit overenthusiastic about clearing - * mods other filters have set here? */ - if (latch == LATCH_PENDING) - state->components.latched_mods &= - ~filter->action.mods.mods.mask; - else - state->clear_mods = filter->action.mods.mods.mask; - state->components.locked_mods &= ~filter->action.mods.mods.mask; - filter->func = NULL; - } - else { - latch = LATCH_PENDING; - state->clear_mods = filter->action.mods.mods.mask; - state->components.latched_mods |= filter->action.mods.mods.mask; - /* XXX beep beep! */ - } - } - else if (direction == XKB_KEY_DOWN && latch == LATCH_KEY_DOWN) { - /* Someone's pressed another key while we've still got the latching - * key held down, so keep the base modifier state active (from - * xkb_filter_mod_latch_new), but don't trip the latch, just clear - * it as soon as the modifier gets released. */ - latch = NO_LATCH; - } - - filter->priv = latch; - - return XKB_FILTER_CONTINUE; -} - -static const struct { - void (*new)(struct xkb_state *state, struct xkb_filter *filter); - bool (*func)(struct xkb_state *state, struct xkb_filter *filter, - const struct xkb_key *key, enum xkb_key_direction direction); -} filter_action_funcs[_ACTION_TYPE_NUM_ENTRIES] = { - [ACTION_TYPE_MOD_SET] = { xkb_filter_mod_set_new, - xkb_filter_mod_set_func }, - [ACTION_TYPE_MOD_LATCH] = { xkb_filter_mod_latch_new, - xkb_filter_mod_latch_func }, - [ACTION_TYPE_MOD_LOCK] = { xkb_filter_mod_lock_new, - xkb_filter_mod_lock_func }, - [ACTION_TYPE_GROUP_SET] = { xkb_filter_group_set_new, - xkb_filter_group_set_func }, - [ACTION_TYPE_GROUP_LOCK] = { xkb_filter_group_lock_new, - xkb_filter_group_lock_func }, -}; - -/** - * Applies any relevant filters to the key, first from the list of filters - * that are currently active, then if no filter has claimed the key, possibly - * apply a new filter from the key action. - */ -static void -xkb_filter_apply_all(struct xkb_state *state, - const struct xkb_key *key, - enum xkb_key_direction direction) -{ - struct xkb_filter *filter; - const union xkb_action *action; - bool consumed; - - /* First run through all the currently active filters and see if any of - * them have consumed this event. */ - consumed = false; - darray_foreach(filter, state->filters) { - if (!filter->func) - continue; - - if (filter->func(state, filter, key, direction) == XKB_FILTER_CONSUME) - consumed = true; - } - if (consumed || direction == XKB_KEY_UP) - return; - - action = xkb_key_get_action(state, key); - - /* - * It's possible for the keymap to set action->type explicitly, like so: - * interpret XF86_Next_VMode { - * action = Private(type=0x86, data="+VMode"); - * }; - * We don't handle those. - */ - if (action->type >= _ACTION_TYPE_NUM_ENTRIES) - return; - - if (!filter_action_funcs[action->type].new) - return; - - filter = xkb_filter_new(state); - filter->key = key; - filter->func = filter_action_funcs[action->type].func; - filter->action = *action; - filter_action_funcs[action->type].new(state, filter); -} - -XKB_EXPORT struct xkb_state * -xkb_state_new(struct xkb_keymap *keymap) -{ - struct xkb_state *ret; - - ret = calloc(sizeof(*ret), 1); - if (!ret) - return NULL; - - ret->refcnt = 1; - ret->keymap = xkb_keymap_ref(keymap); - - return ret; -} - -XKB_EXPORT struct xkb_state * -xkb_state_ref(struct xkb_state *state) -{ - state->refcnt++; - return state; -} - -XKB_EXPORT void -xkb_state_unref(struct xkb_state *state) -{ - if (!state || --state->refcnt > 0) - return; - - xkb_keymap_unref(state->keymap); - darray_free(state->filters); - free(state); -} - -XKB_EXPORT struct xkb_keymap * -xkb_state_get_keymap(struct xkb_state *state) -{ - return state->keymap; -} - -/** - * Update the LED state to match the rest of the xkb_state. - */ -static void -xkb_state_led_update_all(struct xkb_state *state) -{ - xkb_led_index_t idx; - const struct xkb_led *led; - - state->components.leds = 0; - - xkb_leds_enumerate(idx, led, state->keymap) { - xkb_mod_mask_t mod_mask = 0; - xkb_layout_mask_t group_mask = 0; - - if (led->which_mods != 0 && led->mods.mask != 0) { - if (led->which_mods & XKB_STATE_MODS_EFFECTIVE) - mod_mask |= state->components.mods; - if (led->which_mods & XKB_STATE_MODS_DEPRESSED) - mod_mask |= state->components.base_mods; - if (led->which_mods & XKB_STATE_MODS_LATCHED) - mod_mask |= state->components.latched_mods; - if (led->which_mods & XKB_STATE_MODS_LOCKED) - mod_mask |= state->components.locked_mods; - - if (led->mods.mask & mod_mask) { - state->components.leds |= (1u << idx); - continue; - } - } - - if (led->which_groups != 0 && led->groups != 0) { - if (led->which_groups & XKB_STATE_LAYOUT_EFFECTIVE) - group_mask |= (1u << state->components.group); - if (led->which_groups & XKB_STATE_LAYOUT_DEPRESSED) - group_mask |= (1u << state->components.base_group); - if (led->which_groups & XKB_STATE_LAYOUT_LATCHED) - group_mask |= (1u << state->components.latched_group); - if (led->which_groups & XKB_STATE_LAYOUT_LOCKED) - group_mask |= (1u << state->components.locked_group); - - if (led->groups & group_mask) { - state->components.leds |= (1u << idx); - continue; - } - } - - if (led->ctrls & state->keymap->enabled_ctrls) { - state->components.leds |= (1u << idx); - continue; - } - } -} - -/** - * Calculates the derived state (effective mods/group and LEDs) from an - * up-to-date xkb_state. - */ -static void -xkb_state_update_derived(struct xkb_state *state) -{ - xkb_layout_index_t wrapped; - - state->components.mods = (state->components.base_mods | - state->components.latched_mods | - state->components.locked_mods); - - /* TODO: Use groups_wrap control instead of always RANGE_WRAP. */ - - wrapped = XkbWrapGroupIntoRange(state->components.locked_group, - state->keymap->num_groups, - RANGE_WRAP, 0); - state->components.locked_group = - (wrapped == XKB_LAYOUT_INVALID ? 0 : wrapped); - - wrapped = XkbWrapGroupIntoRange(state->components.base_group + - state->components.latched_group + - state->components.locked_group, - state->keymap->num_groups, - RANGE_WRAP, 0); - state->components.group = - (wrapped == XKB_LAYOUT_INVALID ? 0 : wrapped); - - xkb_state_led_update_all(state); -} - -static enum xkb_state_component -get_state_component_changes(const struct state_components *a, - const struct state_components *b) -{ - xkb_mod_mask_t mask = 0; - - if (a->group != b->group) - mask |= XKB_STATE_LAYOUT_EFFECTIVE; - if (a->base_group != b->base_group) - mask |= XKB_STATE_LAYOUT_DEPRESSED; - if (a->latched_group != b->latched_group) - mask |= XKB_STATE_LAYOUT_LATCHED; - if (a->locked_group != b->locked_group) - mask |= XKB_STATE_LAYOUT_LOCKED; - if (a->mods != b->mods) - mask |= XKB_STATE_MODS_EFFECTIVE; - if (a->base_mods != b->base_mods) - mask |= XKB_STATE_MODS_DEPRESSED; - if (a->latched_mods != b->latched_mods) - mask |= XKB_STATE_MODS_LATCHED; - if (a->locked_mods != b->locked_mods) - mask |= XKB_STATE_MODS_LOCKED; - if (a->leds != b->leds) - mask |= XKB_STATE_LEDS; - - return mask; -} - -/** - * Given a particular key event, updates the state structure to reflect the - * new modifiers. - */ -XKB_EXPORT enum xkb_state_component -xkb_state_update_key(struct xkb_state *state, xkb_keycode_t kc, - enum xkb_key_direction direction) -{ - xkb_mod_index_t i; - xkb_mod_mask_t bit; - struct state_components prev_components; - const struct xkb_key *key = XkbKey(state->keymap, kc); - - if (!key) - return 0; - - prev_components = state->components; - - state->set_mods = 0; - state->clear_mods = 0; - - xkb_filter_apply_all(state, key, direction); - - for (i = 0, bit = 1; state->set_mods; i++, bit <<= 1) { - if (state->set_mods & bit) { - state->mod_key_count[i]++; - state->components.base_mods |= bit; - state->set_mods &= ~bit; - } - } - - for (i = 0, bit = 1; state->clear_mods; i++, bit <<= 1) { - if (state->clear_mods & bit) { - state->mod_key_count[i]--; - if (state->mod_key_count[i] <= 0) { - state->components.base_mods &= ~bit; - state->mod_key_count[i] = 0; - } - state->clear_mods &= ~bit; - } - } - - xkb_state_update_derived(state); - - return get_state_component_changes(&prev_components, &state->components); -} - -/** - * Updates the state from a set of explicit masks as gained from - * xkb_state_serialize_mods and xkb_state_serialize_groups. As noted in the - * documentation for these functions in xkbcommon.h, this round-trip is - * lossy, and should only be used to update a slave state mirroring the - * master, e.g. in a client/server window system. - */ -XKB_EXPORT enum xkb_state_component -xkb_state_update_mask(struct xkb_state *state, - xkb_mod_mask_t base_mods, - xkb_mod_mask_t latched_mods, - xkb_mod_mask_t locked_mods, - xkb_layout_index_t base_group, - xkb_layout_index_t latched_group, - xkb_layout_index_t locked_group) -{ - struct state_components prev_components; - xkb_mod_mask_t mask; - - prev_components = state->components; - - /* Only include modifiers which exist in the keymap. */ - mask = (xkb_mod_mask_t) ((1ull << xkb_keymap_num_mods(state->keymap)) - 1u); - - state->components.base_mods = base_mods & mask; - state->components.latched_mods = latched_mods & mask; - state->components.locked_mods = locked_mods & mask; - - /* Make sure the mods are fully resolved - since we get arbitrary - * input, they might not be. - * - * It might seem more reasonable to do this only for components.mods - * in xkb_state_update_derived(), rather than for each component - * seperately. That would allow to distinguish between "really" - * depressed mods (would be in MODS_DEPRESSED) and indirectly - * depressed to to a mapping (would only be in MODS_EFFECTIVE). - * However, the traditional behavior of xkb_state_update_key() is that - * if a vmod is depressed, its mappings are depressed with it; so we're - * expected to do the same here. Also, LEDs (usually) look if a real - * mod is locked, not just effective; otherwise it won't be lit. - * - * We OR here because mod_mask_get_effective() drops vmods. */ - state->components.base_mods |= - mod_mask_get_effective(state->keymap, state->components.base_mods); - state->components.latched_mods |= - mod_mask_get_effective(state->keymap, state->components.latched_mods); - state->components.locked_mods |= - mod_mask_get_effective(state->keymap, state->components.locked_mods); - - state->components.base_group = base_group; - state->components.latched_group = latched_group; - state->components.locked_group = locked_group; - - xkb_state_update_derived(state); - - return get_state_component_changes(&prev_components, &state->components); -} - -/** - * Provides the symbols to use for the given key and state. Returns the - * number of symbols pointed to in syms_out. - */ -XKB_EXPORT int -xkb_state_key_get_syms(struct xkb_state *state, xkb_keycode_t kc, - const xkb_keysym_t **syms_out) -{ - xkb_layout_index_t layout; - xkb_level_index_t level; - - layout = xkb_state_key_get_layout(state, kc); - if (layout == XKB_LAYOUT_INVALID) - goto err; - - level = xkb_state_key_get_level(state, kc, layout); - if (level == XKB_LEVEL_INVALID) - goto err; - - return xkb_keymap_key_get_syms_by_level(state->keymap, kc, layout, level, - syms_out); - -err: - *syms_out = NULL; - return 0; -} - -/* - * https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Lock_Modifier - */ -static bool -should_do_caps_transformation(struct xkb_state *state, xkb_keycode_t kc) -{ - xkb_mod_index_t caps = - xkb_keymap_mod_get_index(state->keymap, XKB_MOD_NAME_CAPS); - - return - xkb_state_mod_index_is_active(state, caps, XKB_STATE_MODS_EFFECTIVE) > 0 && - xkb_state_mod_index_is_consumed(state, kc, caps) == 0; -} - -/* - * https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Control_Modifier - */ -static bool -should_do_ctrl_transformation(struct xkb_state *state, xkb_keycode_t kc) -{ - xkb_mod_index_t ctrl = - xkb_keymap_mod_get_index(state->keymap, XKB_MOD_NAME_CTRL); - - return - xkb_state_mod_index_is_active(state, ctrl, XKB_STATE_MODS_EFFECTIVE) > 0 && - xkb_state_mod_index_is_consumed(state, kc, ctrl) == 0; -} - -/* Verbatim from libX11:src/xkb/XKBBind.c */ -static char -XkbToControl(char ch) -{ - char c = ch; - - if ((c >= '@' && c < '\177') || c == ' ') - c &= 0x1F; - else if (c == '2') - c = '\000'; - else if (c >= '3' && c <= '7') - c -= ('3' - '\033'); - else if (c == '8') - c = '\177'; - else if (c == '/') - c = '_' & 0x1F; - return c; -} - -/** - * Provides either exactly one symbol, or XKB_KEY_NoSymbol. - */ -XKB_EXPORT xkb_keysym_t -xkb_state_key_get_one_sym(struct xkb_state *state, xkb_keycode_t kc) -{ - const xkb_keysym_t *syms; - xkb_keysym_t sym; - int num_syms; - - num_syms = xkb_state_key_get_syms(state, kc, &syms); - if (num_syms != 1) - return XKB_KEY_NoSymbol; - - sym = syms[0]; - - if (should_do_caps_transformation(state, kc)) - sym = xkb_keysym_to_upper(sym); - - return sym; -} - -/* - * The caps and ctrl transformations require some special handling, - * so we cannot simply use xkb_state_get_one_sym() for them. - * In particular, if Control is set, we must try very hard to find - * some layout in which the keysym is ASCII and thus can be (maybe) - * converted to a control character. libX11 allows to disable this - * behavior with the XkbLC_ControlFallback (see XkbSetXlibControls(3)), - * but it is enabled by default, yippee. - */ -static xkb_keysym_t -get_one_sym_for_string(struct xkb_state *state, xkb_keycode_t kc) -{ - xkb_level_index_t level; - xkb_layout_index_t layout, num_layouts; - const xkb_keysym_t *syms; - int nsyms; - xkb_keysym_t sym; - - layout = xkb_state_key_get_layout(state, kc); - num_layouts = xkb_keymap_num_layouts_for_key(state->keymap, kc); - level = xkb_state_key_get_level(state, kc, layout); - if (layout == XKB_LAYOUT_INVALID || num_layouts == 0 || - level == XKB_LEVEL_INVALID) - return XKB_KEY_NoSymbol; - - nsyms = xkb_keymap_key_get_syms_by_level(state->keymap, kc, - layout, level, &syms); - if (nsyms != 1) - return XKB_KEY_NoSymbol; - sym = syms[0]; - - if (should_do_ctrl_transformation(state, kc) && sym > 127u) { - for (xkb_layout_index_t i = 0; i < num_layouts; i++) { - level = xkb_state_key_get_level(state, kc, i); - if (level == XKB_LEVEL_INVALID) - continue; - - nsyms = xkb_keymap_key_get_syms_by_level(state->keymap, kc, - i, level, &syms); - if (nsyms == 1 && syms[0] <= 127u) { - sym = syms[0]; - break; - } - } - } - - if (should_do_caps_transformation(state, kc)) { - sym = xkb_keysym_to_upper(sym); - } - - return sym; -} - -XKB_EXPORT int -xkb_state_key_get_utf8(struct xkb_state *state, xkb_keycode_t kc, - char *buffer, size_t size) -{ - xkb_keysym_t sym; - const xkb_keysym_t *syms; - int nsyms; - int offset; - char tmp[7]; - - sym = get_one_sym_for_string(state, kc); - if (sym != XKB_KEY_NoSymbol) { - nsyms = 1; syms = &sym; - } - else { - nsyms = xkb_state_key_get_syms(state, kc, &syms); - } - - /* Make sure not to truncate in the middle of a UTF-8 sequence. */ - offset = 0; - for (int i = 0; i < nsyms; i++) { - int ret = xkb_keysym_to_utf8(syms[i], tmp, sizeof(tmp)); - if (ret <= 0) - goto err_bad; - - ret--; - if ((size_t) (offset + ret) <= size) - memcpy(buffer + offset, tmp, ret); - offset += ret; - } - - if ((size_t) offset >= size) - goto err_trunc; - buffer[offset] = '\0'; - - if (!is_valid_utf8(buffer, offset)) - goto err_bad; - - if (offset == 1 && (unsigned int) buffer[0] <= 127u && - should_do_ctrl_transformation(state, kc)) - buffer[0] = XkbToControl(buffer[0]); - - return offset; - -err_trunc: - if (size > 0) - buffer[size - 1] = '\0'; - return offset; - -err_bad: - if (size > 0) - buffer[0] = '\0'; - return 0; -} - -XKB_EXPORT uint32_t -xkb_state_key_get_utf32(struct xkb_state *state, xkb_keycode_t kc) -{ - xkb_keysym_t sym; - uint32_t cp; - - sym = get_one_sym_for_string(state, kc); - cp = xkb_keysym_to_utf32(sym); - - if (cp <= 127u && should_do_ctrl_transformation(state, kc)) - cp = (uint32_t) XkbToControl((char) cp); - - return cp; -} - -/** - * Serialises the requested modifier state into an xkb_mod_mask_t, with all - * the same disclaimers as in xkb_state_update_mask. - */ -XKB_EXPORT xkb_mod_mask_t -xkb_state_serialize_mods(struct xkb_state *state, - enum xkb_state_component type) -{ - xkb_mod_mask_t ret = 0; - - if (type & XKB_STATE_MODS_EFFECTIVE) - return state->components.mods; - - if (type & XKB_STATE_MODS_DEPRESSED) - ret |= state->components.base_mods; - if (type & XKB_STATE_MODS_LATCHED) - ret |= state->components.latched_mods; - if (type & XKB_STATE_MODS_LOCKED) - ret |= state->components.locked_mods; - - return ret; -} - -/** - * Serialises the requested group state, with all the same disclaimers as - * in xkb_state_update_mask. - */ -XKB_EXPORT xkb_layout_index_t -xkb_state_serialize_layout(struct xkb_state *state, - enum xkb_state_component type) -{ - xkb_layout_index_t ret = 0; - - if (type & XKB_STATE_LAYOUT_EFFECTIVE) - return state->components.group; - - if (type & XKB_STATE_LAYOUT_DEPRESSED) - ret += state->components.base_group; - if (type & XKB_STATE_LAYOUT_LATCHED) - ret += state->components.latched_group; - if (type & XKB_STATE_LAYOUT_LOCKED) - ret += state->components.locked_group; - - return ret; -} - -/** - * Gets a modifier mask and returns the resolved effective mask; this - * is needed because some modifiers can also map to other modifiers, e.g. - * the "NumLock" modifier usually also sets the "Mod2" modifier. - */ -xkb_mod_mask_t -mod_mask_get_effective(struct xkb_keymap *keymap, xkb_mod_mask_t mods) -{ - const struct xkb_mod *mod; - xkb_mod_index_t i; - xkb_mod_mask_t mask; - - /* The effective mask is only real mods for now. */ - mask = mods & MOD_REAL_MASK_ALL; - - xkb_mods_enumerate(i, mod, &keymap->mods) - if (mods & (1u << i)) - mask |= mod->mapping; - - return mask; -} - -/** - * Returns 1 if the given modifier is active with the specified type(s), 0 if - * not, or -1 if the modifier is invalid. - */ -XKB_EXPORT int -xkb_state_mod_index_is_active(struct xkb_state *state, - xkb_mod_index_t idx, - enum xkb_state_component type) -{ - if (idx >= xkb_keymap_num_mods(state->keymap)) - return -1; - - return !!(xkb_state_serialize_mods(state, type) & (1u << idx)); -} - -/** - * Helper function for xkb_state_mod_indices_are_active and - * xkb_state_mod_names_are_active. - */ -static bool -match_mod_masks(struct xkb_state *state, - enum xkb_state_component type, - enum xkb_state_match match, - xkb_mod_mask_t wanted) -{ - xkb_mod_mask_t active = xkb_state_serialize_mods(state, type); - - if (!(match & XKB_STATE_MATCH_NON_EXCLUSIVE) && (active & ~wanted)) - return false; - - if (match & XKB_STATE_MATCH_ANY) - return active & wanted; - - return (active & wanted) == wanted; -} - -/** - * Returns 1 if the modifiers are active with the specified type(s), 0 if - * not, or -1 if any of the modifiers are invalid. - */ -XKB_EXPORT int -xkb_state_mod_indices_are_active(struct xkb_state *state, - enum xkb_state_component type, - enum xkb_state_match match, - ...) -{ - va_list ap; - xkb_mod_mask_t wanted = 0; - int ret = 0; - xkb_mod_index_t num_mods = xkb_keymap_num_mods(state->keymap); - - va_start(ap, match); - while (1) { - xkb_mod_index_t idx = va_arg(ap, xkb_mod_index_t); - if (idx == XKB_MOD_INVALID) - break; - if (idx >= num_mods) { - ret = -1; - break; - } - wanted |= (1u << idx); - } - va_end(ap); - - if (ret == -1) - return ret; - - return match_mod_masks(state, type, match, wanted); -} - -/** - * Returns 1 if the given modifier is active with the specified type(s), 0 if - * not, or -1 if the modifier is invalid. - */ -XKB_EXPORT int -xkb_state_mod_name_is_active(struct xkb_state *state, const char *name, - enum xkb_state_component type) -{ - xkb_mod_index_t idx = xkb_keymap_mod_get_index(state->keymap, name); - - if (idx == XKB_MOD_INVALID) - return -1; - - return xkb_state_mod_index_is_active(state, idx, type); -} - -/** - * Returns 1 if the modifiers are active with the specified type(s), 0 if - * not, or -1 if any of the modifiers are invalid. - */ -XKB_EXPORT ATTR_NULL_SENTINEL int -xkb_state_mod_names_are_active(struct xkb_state *state, - enum xkb_state_component type, - enum xkb_state_match match, - ...) -{ - va_list ap; - xkb_mod_mask_t wanted = 0; - int ret = 0; - - va_start(ap, match); - while (1) { - xkb_mod_index_t idx; - const char *str = va_arg(ap, const char *); - if (str == NULL) - break; - idx = xkb_keymap_mod_get_index(state->keymap, str); - if (idx == XKB_MOD_INVALID) { - ret = -1; - break; - } - wanted |= (1u << idx); - } - va_end(ap); - - if (ret == -1) - return ret; - - return match_mod_masks(state, type, match, wanted); -} - -/** - * Returns 1 if the given group is active with the specified type(s), 0 if - * not, or -1 if the group is invalid. - */ -XKB_EXPORT int -xkb_state_layout_index_is_active(struct xkb_state *state, - xkb_layout_index_t idx, - enum xkb_state_component type) -{ - int ret = 0; - - if (idx >= state->keymap->num_groups) - return -1; - - if (type & XKB_STATE_LAYOUT_EFFECTIVE) - ret |= (state->components.group == idx); - if (type & XKB_STATE_LAYOUT_DEPRESSED) - ret |= (state->components.base_group == (int32_t) idx); - if (type & XKB_STATE_LAYOUT_LATCHED) - ret |= (state->components.latched_group == (int32_t) idx); - if (type & XKB_STATE_LAYOUT_LOCKED) - ret |= (state->components.locked_group == (int32_t) idx); - - return ret; -} - -/** - * Returns 1 if the given modifier is active with the specified type(s), 0 if - * not, or -1 if the modifier is invalid. - */ -XKB_EXPORT int -xkb_state_layout_name_is_active(struct xkb_state *state, const char *name, - enum xkb_state_component type) -{ - xkb_layout_index_t idx = xkb_keymap_layout_get_index(state->keymap, name); - - if (idx == XKB_LAYOUT_INVALID) - return -1; - - return xkb_state_layout_index_is_active(state, idx, type); -} - -/** - * Returns 1 if the given LED is active, 0 if not, or -1 if the LED is invalid. - */ -XKB_EXPORT int -xkb_state_led_index_is_active(struct xkb_state *state, xkb_led_index_t idx) -{ - if (idx >= state->keymap->num_leds || - state->keymap->leds[idx].name == XKB_ATOM_NONE) - return -1; - - return !!(state->components.leds & (1u << idx)); -} - -/** - * Returns 1 if the given LED is active, 0 if not, or -1 if the LED is invalid. - */ -XKB_EXPORT int -xkb_state_led_name_is_active(struct xkb_state *state, const char *name) -{ - xkb_led_index_t idx = xkb_keymap_led_get_index(state->keymap, name); - - if (idx == XKB_LED_INVALID) - return -1; - - return xkb_state_led_index_is_active(state, idx); -} - -/** - * See: - * - XkbTranslateKeyCode(3), mod_rtrn return value, from libX11. - * - MyEnhancedXkbTranslateKeyCode(), a modification of the above, from GTK+. - */ -static xkb_mod_mask_t -key_get_consumed(struct xkb_state *state, const struct xkb_key *key, - enum xkb_consumed_mode mode) -{ - const struct xkb_key_type *type; - const struct xkb_key_type_entry *matching_entry; - xkb_mod_mask_t preserve = 0; - xkb_layout_index_t group; - xkb_mod_mask_t consumed = 0; - - group = xkb_state_key_get_layout(state, key->keycode); - if (group == XKB_LAYOUT_INVALID) - return 0; - - type = key->groups[group].type; - - matching_entry = get_entry_for_key_state(state, key, group); - if (matching_entry) - preserve = matching_entry->preserve.mask; - - switch (mode) { - case XKB_CONSUMED_MODE_XKB: - consumed = type->mods.mask; - break; - - case XKB_CONSUMED_MODE_GTK: { - const struct xkb_key_type_entry *no_mods_entry; - xkb_level_index_t no_mods_leveli; - const struct xkb_level *no_mods_level, *level; - - no_mods_entry = get_entry_for_mods(type, 0); - no_mods_leveli = no_mods_entry ? no_mods_entry->level : 0; - no_mods_level = &key->groups[group].levels[no_mods_leveli]; - - for (unsigned i = 0; i < type->num_entries; i++) { - const struct xkb_key_type_entry *entry = &type->entries[i]; - if (!entry_is_active(entry)) - continue; - - level = &key->groups[group].levels[entry->level]; - if (XkbLevelsSameSyms(level, no_mods_level)) - continue; - - if (entry == matching_entry || my_popcount(entry->mods.mask) == 1) - consumed |= entry->mods.mask & ~entry->preserve.mask; - } - break; - } - } - - return consumed & ~preserve; -} - -XKB_EXPORT int -xkb_state_mod_index_is_consumed2(struct xkb_state *state, xkb_keycode_t kc, - xkb_mod_index_t idx, - enum xkb_consumed_mode mode) -{ - const struct xkb_key *key = XkbKey(state->keymap, kc); - - if (!key || idx >= xkb_keymap_num_mods(state->keymap)) - return -1; - - return !!((1u << idx) & key_get_consumed(state, key, mode)); -} - -XKB_EXPORT int -xkb_state_mod_index_is_consumed(struct xkb_state *state, xkb_keycode_t kc, - xkb_mod_index_t idx) -{ - return xkb_state_mod_index_is_consumed2(state, kc, idx, - XKB_CONSUMED_MODE_XKB); -} - -XKB_EXPORT xkb_mod_mask_t -xkb_state_mod_mask_remove_consumed(struct xkb_state *state, xkb_keycode_t kc, - xkb_mod_mask_t mask) -{ - const struct xkb_key *key = XkbKey(state->keymap, kc); - - if (!key) - return 0; - - return mask & ~key_get_consumed(state, key, XKB_CONSUMED_MODE_XKB); -} - -XKB_EXPORT xkb_mod_mask_t -xkb_state_key_get_consumed_mods2(struct xkb_state *state, xkb_keycode_t kc, - enum xkb_consumed_mode mode) -{ - const struct xkb_key *key; - - switch (mode) { - case XKB_CONSUMED_MODE_XKB: - case XKB_CONSUMED_MODE_GTK: - break; - default: - log_err_func(state->keymap->ctx, - "unrecognized consumed modifiers mode: %d\n", mode); - return 0; - } - - key = XkbKey(state->keymap, kc); - if (!key) - return 0; - - return key_get_consumed(state, key, mode); -} - -XKB_EXPORT xkb_mod_mask_t -xkb_state_key_get_consumed_mods(struct xkb_state *state, xkb_keycode_t kc) -{ - return xkb_state_key_get_consumed_mods2(state, kc, XKB_CONSUMED_MODE_XKB); -} diff --git a/src/3rdparty/xkbcommon/src/text.c b/src/3rdparty/xkbcommon/src/text.c deleted file mode 100644 index 1a44de47b4..0000000000 --- a/src/3rdparty/xkbcommon/src/text.c +++ /dev/null @@ -1,346 +0,0 @@ -/************************************************************ - * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting - * documentation, and that the name of Silicon Graphics not be - * used in advertising or publicity pertaining to distribution - * of the software without specific prior written permission. - * Silicon Graphics makes no representation about the suitability - * of this software for any purpose. It is provided "as is" - * without any express or implied warranty. - * - * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - * THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - ********************************************************/ - -#include "keymap.h" -#include "text.h" - -bool -LookupString(const LookupEntry tab[], const char *string, - unsigned int *value_rtrn) -{ - if (!string) - return false; - - for (const LookupEntry *entry = tab; entry->name; entry++) { - if (istreq(entry->name, string)) { - *value_rtrn = entry->value; - return true; - } - } - - return false; -} - -const char * -LookupValue(const LookupEntry tab[], unsigned int value) -{ - for (const LookupEntry *entry = tab; entry->name; entry++) - if (entry->value == value) - return entry->name; - - return NULL; -} - -const LookupEntry ctrlMaskNames[] = { - { "RepeatKeys", CONTROL_REPEAT }, - { "Repeat", CONTROL_REPEAT }, - { "AutoRepeat", CONTROL_REPEAT }, - { "SlowKeys", CONTROL_SLOW }, - { "BounceKeys", CONTROL_DEBOUNCE }, - { "StickyKeys", CONTROL_STICKY }, - { "MouseKeys", CONTROL_MOUSEKEYS }, - { "MouseKeysAccel", CONTROL_MOUSEKEYS_ACCEL }, - { "AccessXKeys", CONTROL_AX }, - { "AccessXTimeout", CONTROL_AX_TIMEOUT }, - { "AccessXFeedback", CONTROL_AX_FEEDBACK }, - { "AudibleBell", CONTROL_BELL }, - { "IgnoreGroupLock", CONTROL_IGNORE_GROUP_LOCK }, - { "all", CONTROL_ALL }, - { "none", 0 }, - { "Overlay1", 0 }, - { "Overlay2", 0 }, - { NULL, 0 } -}; - -const LookupEntry modComponentMaskNames[] = { - { "base", XKB_STATE_MODS_DEPRESSED }, - { "latched", XKB_STATE_MODS_LATCHED }, - { "locked", XKB_STATE_MODS_LOCKED }, - { "effective", XKB_STATE_MODS_EFFECTIVE }, - { "compat", XKB_STATE_MODS_EFFECTIVE }, - { "any", XKB_STATE_MODS_EFFECTIVE }, - { "none", 0 }, - { NULL, 0 } -}; - -const LookupEntry groupComponentMaskNames[] = { - { "base", XKB_STATE_LAYOUT_DEPRESSED }, - { "latched", XKB_STATE_LAYOUT_LATCHED }, - { "locked", XKB_STATE_LAYOUT_LOCKED }, - { "effective", XKB_STATE_LAYOUT_EFFECTIVE }, - { "any", XKB_STATE_LAYOUT_EFFECTIVE }, - { "none", 0 }, - { NULL, 0 } -}; - -const LookupEntry groupMaskNames[] = { - { "Group1", 0x01 }, - { "Group2", 0x02 }, - { "Group3", 0x04 }, - { "Group4", 0x08 }, - { "Group5", 0x10 }, - { "Group6", 0x20 }, - { "Group7", 0x40 }, - { "Group8", 0x80 }, - { "none", 0x00 }, - { "all", 0xff }, - { NULL, 0 } -}; - -const LookupEntry groupNames[] = { - { "Group1", 1 }, - { "Group2", 2 }, - { "Group3", 3 }, - { "Group4", 4 }, - { "Group5", 5 }, - { "Group6", 6 }, - { "Group7", 7 }, - { "Group8", 8 }, - { NULL, 0 } -}; - -const LookupEntry levelNames[] = { - { "Level1", 1 }, - { "Level2", 2 }, - { "Level3", 3 }, - { "Level4", 4 }, - { "Level5", 5 }, - { "Level6", 6 }, - { "Level7", 7 }, - { "Level8", 8 }, - { NULL, 0 } -}; - -const LookupEntry buttonNames[] = { - { "Button1", 1 }, - { "Button2", 2 }, - { "Button3", 3 }, - { "Button4", 4 }, - { "Button5", 5 }, - { "default", 0 }, - { NULL, 0 } -}; - -const LookupEntry useModMapValueNames[] = { - { "LevelOne", 1 }, - { "Level1", 1 }, - { "AnyLevel", 0 }, - { "any", 0 }, - { NULL, 0 } -}; - -const LookupEntry actionTypeNames[] = { - { "NoAction", ACTION_TYPE_NONE }, - { "SetMods", ACTION_TYPE_MOD_SET }, - { "LatchMods", ACTION_TYPE_MOD_LATCH }, - { "LockMods", ACTION_TYPE_MOD_LOCK }, - { "SetGroup", ACTION_TYPE_GROUP_SET }, - { "LatchGroup", ACTION_TYPE_GROUP_LATCH }, - { "LockGroup", ACTION_TYPE_GROUP_LOCK }, - { "MovePtr", ACTION_TYPE_PTR_MOVE }, - { "MovePointer", ACTION_TYPE_PTR_MOVE }, - { "PtrBtn", ACTION_TYPE_PTR_BUTTON }, - { "PointerButton", ACTION_TYPE_PTR_BUTTON }, - { "LockPtrBtn", ACTION_TYPE_PTR_LOCK }, - { "LockPtrButton", ACTION_TYPE_PTR_LOCK }, - { "LockPointerButton", ACTION_TYPE_PTR_LOCK }, - { "LockPointerBtn", ACTION_TYPE_PTR_LOCK }, - { "SetPtrDflt", ACTION_TYPE_PTR_DEFAULT }, - { "SetPointerDefault", ACTION_TYPE_PTR_DEFAULT }, - { "Terminate", ACTION_TYPE_TERMINATE }, - { "TerminateServer", ACTION_TYPE_TERMINATE }, - { "SwitchScreen", ACTION_TYPE_SWITCH_VT }, - { "SetControls", ACTION_TYPE_CTRL_SET }, - { "LockControls", ACTION_TYPE_CTRL_LOCK }, - { "Private", ACTION_TYPE_PRIVATE }, - /* deprecated actions below here - unused */ - { "RedirectKey", ACTION_TYPE_NONE }, - { "Redirect", ACTION_TYPE_NONE }, - { "ISOLock", ACTION_TYPE_NONE }, - { "ActionMessage", ACTION_TYPE_NONE }, - { "MessageAction", ACTION_TYPE_NONE }, - { "Message", ACTION_TYPE_NONE }, - { "DeviceBtn", ACTION_TYPE_NONE }, - { "DevBtn", ACTION_TYPE_NONE }, - { "DevButton", ACTION_TYPE_NONE }, - { "DeviceButton", ACTION_TYPE_NONE }, - { "LockDeviceBtn", ACTION_TYPE_NONE }, - { "LockDevBtn", ACTION_TYPE_NONE }, - { "LockDevButton", ACTION_TYPE_NONE }, - { "LockDeviceButton", ACTION_TYPE_NONE }, - { "DeviceValuator", ACTION_TYPE_NONE }, - { "DevVal", ACTION_TYPE_NONE }, - { "DeviceVal", ACTION_TYPE_NONE }, - { "DevValuator", ACTION_TYPE_NONE }, - { NULL, 0 }, -}; - -const LookupEntry symInterpretMatchMaskNames[] = { - { "NoneOf", MATCH_NONE }, - { "AnyOfOrNone", MATCH_ANY_OR_NONE }, - { "AnyOf", MATCH_ANY }, - { "AllOf", MATCH_ALL }, - { "Exactly", MATCH_EXACTLY }, - { NULL, 0 }, -}; - -const char * -ModIndexText(struct xkb_context *ctx, const struct xkb_mod_set *mods, - xkb_mod_index_t ndx) -{ - if (ndx == XKB_MOD_INVALID) - return "none"; - - if (ndx >= mods->num_mods) - return NULL; - - return xkb_atom_text(ctx, mods->mods[ndx].name); -} - -const char * -ActionTypeText(enum xkb_action_type type) -{ - const char *name = LookupValue(actionTypeNames, type); - return name ? name : "Private"; -} - -const char * -KeysymText(struct xkb_context *ctx, xkb_keysym_t sym) -{ - char *buffer = xkb_context_get_buffer(ctx, 64); - xkb_keysym_get_name(sym, buffer, 64); - return buffer; -} - -const char * -KeyNameText(struct xkb_context *ctx, xkb_atom_t name) -{ - const char *sname = xkb_atom_text(ctx, name); - size_t len = strlen_safe(sname) + 3; - char *buf = xkb_context_get_buffer(ctx, len); - snprintf(buf, len, "<%s>", strempty(sname)); - return buf; -} - -const char * -SIMatchText(enum xkb_match_operation type) -{ - return LookupValue(symInterpretMatchMaskNames, type); -} - -const char * -ModMaskText(struct xkb_context *ctx, const struct xkb_mod_set *mods, - xkb_mod_mask_t mask) -{ - char buf[1024] = {0}; - size_t pos = 0; - xkb_mod_index_t i; - const struct xkb_mod *mod; - - if (mask == 0) - return "none"; - - if (mask == MOD_REAL_MASK_ALL) - return "all"; - - xkb_mods_enumerate(i, mod, mods) { - int ret; - - if (!(mask & (1u << i))) - continue; - - ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s", - pos == 0 ? "" : "+", - xkb_atom_text(ctx, mod->name)); - if (ret <= 0 || pos + ret >= sizeof(buf)) - break; - else - pos += ret; - } - - return strcpy(xkb_context_get_buffer(ctx, pos + 1), buf); -} - -const char * -LedStateMaskText(struct xkb_context *ctx, enum xkb_state_component mask) -{ - char buf[1024]; - size_t pos = 0; - - if (mask == 0) - return "0"; - - for (unsigned i = 0; mask; i++) { - int ret; - - if (!(mask & (1u << i))) - continue; - - mask &= ~(1u << i); - - ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s", - pos == 0 ? "" : "+", - LookupValue(modComponentMaskNames, 1u << i)); - if (ret <= 0 || pos + ret >= sizeof(buf)) - break; - else - pos += ret; - } - - return strcpy(xkb_context_get_buffer(ctx, pos + 1), buf); -} - -const char * -ControlMaskText(struct xkb_context *ctx, enum xkb_action_controls mask) -{ - char buf[1024]; - size_t pos = 0; - - if (mask == 0) - return "none"; - - if (mask == CONTROL_ALL) - return "all"; - - for (unsigned i = 0; mask; i++) { - int ret; - - if (!(mask & (1u << i))) - continue; - - mask &= ~(1u << i); - - ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s", - pos == 0 ? "" : "+", - LookupValue(ctrlMaskNames, 1u << i)); - if (ret <= 0 || pos + ret >= sizeof(buf)) - break; - else - pos += ret; - } - - return strcpy(xkb_context_get_buffer(ctx, pos + 1), buf); -} diff --git a/src/3rdparty/xkbcommon/src/text.h b/src/3rdparty/xkbcommon/src/text.h deleted file mode 100644 index 584dea62d7..0000000000 --- a/src/3rdparty/xkbcommon/src/text.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright © 2009 Dan Nicholson - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef TEXT_H -#define TEXT_H - -typedef struct { - const char *name; - unsigned int value; -} LookupEntry; - -bool -LookupString(const LookupEntry tab[], const char *string, - unsigned int *value_rtrn); - -const char * -LookupValue(const LookupEntry tab[], unsigned int value); - -extern const LookupEntry ctrlMaskNames[]; -extern const LookupEntry modComponentMaskNames[]; -extern const LookupEntry groupComponentMaskNames[]; -extern const LookupEntry groupMaskNames[]; -extern const LookupEntry groupNames[]; -extern const LookupEntry levelNames[]; -extern const LookupEntry buttonNames[]; -extern const LookupEntry useModMapValueNames[]; -extern const LookupEntry actionTypeNames[]; -extern const LookupEntry symInterpretMatchMaskNames[]; - -const char * -ModMaskText(struct xkb_context *ctx, const struct xkb_mod_set *mods, - xkb_mod_mask_t mask); - -const char * -ModIndexText(struct xkb_context *ctx, const struct xkb_mod_set *mods, - xkb_mod_index_t ndx); - -const char * -ActionTypeText(enum xkb_action_type type); - -const char * -KeysymText(struct xkb_context *ctx, xkb_keysym_t sym); - -const char * -KeyNameText(struct xkb_context *ctx, xkb_atom_t name); - -const char * -SIMatchText(enum xkb_match_operation type); - -const char * -LedStateMaskText(struct xkb_context *ctx, enum xkb_state_component mask); - -const char * -ControlMaskText(struct xkb_context *ctx, enum xkb_action_controls mask); - -#endif /* TEXT_H */ diff --git a/src/3rdparty/xkbcommon/src/utf8.c b/src/3rdparty/xkbcommon/src/utf8.c deleted file mode 100644 index a76b001bab..0000000000 --- a/src/3rdparty/xkbcommon/src/utf8.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright © 2012 Intel Corporation - * Copyright © 2014 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Rob Bradford - */ - -#include -#include -#include - -#include "utf8.h" - -int -utf32_to_utf8(uint32_t unichar, char *buffer) -{ - int count, shift, length; - uint8_t head; - - if (unichar <= 0x007f) { - buffer[0] = unichar; - buffer[1] = '\0'; - return 2; - } - else if (unichar <= 0x07FF) { - length = 2; - head = 0xc0; - } - else if (unichar <= 0xffff) { - length = 3; - head = 0xe0; - } - else if (unichar <= 0x10ffff) { - length = 4; - head = 0xf0; - } - else { - buffer[0] = '\0'; - return 0; - } - - for (count = length - 1, shift = 0; count > 0; count--, shift += 6) - buffer[count] = 0x80 | ((unichar >> shift) & 0x3f); - - buffer[0] = head | ((unichar >> shift) & 0x3f); - buffer[length] = '\0'; - - return length + 1; -} - -bool -is_valid_utf8(const char *ss, size_t len) -{ - size_t i = 0; - size_t tail_bytes = 0; - const uint8_t *s = (const uint8_t *) ss; - - /* This beauty is from: - * The Unicode Standard Version 6.2 - Core Specification, Table 3.7 - * https://www.unicode.org/versions/Unicode6.2.0/ch03.pdf#G7404 - * We can optimize if needed. */ - while (i < len) - { - if (s[i] <= 0x7F) { - tail_bytes = 0; - } - else if (s[i] >= 0xC2 && s[i] <= 0xDF) { - tail_bytes = 1; - } - else if (s[i] == 0xE0) { - i++; - if (i >= len || !(s[i] >= 0xA0 && s[i] <= 0xBF)) - return false; - tail_bytes = 1; - } - else if (s[i] >= 0xE1 && s[i] <= 0xEC) { - tail_bytes = 2; - } - else if (s[i] == 0xED) { - i++; - if (i >= len || !(s[i] >= 0x80 && s[i] <= 0x9F)) - return false; - tail_bytes = 1; - } - else if (s[i] >= 0xEE && s[i] <= 0xEF) { - tail_bytes = 2; - } - else if (s[i] == 0xF0) { - i++; - if (i >= len || !(s[i] >= 0x90 && s[i] <= 0xBF)) - return false; - tail_bytes = 2; - } - else if (s[i] >= 0xF1 && s[i] <= 0xF3) { - tail_bytes = 3; - } - else if (s[i] == 0xF4) { - i++; - if (i >= len || !(s[i] >= 0x80 && s[i] <= 0x8F)) - return false; - tail_bytes = 2; - } - else { - return false; - } - - i++; - - while (i < len && tail_bytes > 0 && s[i] >= 0x80 && s[i] <= 0xBF) { - i++; - tail_bytes--; - } - - if (tail_bytes != 0) - return false; - } - - return true; -} diff --git a/src/3rdparty/xkbcommon/src/utf8.h b/src/3rdparty/xkbcommon/src/utf8.h deleted file mode 100644 index 6371cb5596..0000000000 --- a/src/3rdparty/xkbcommon/src/utf8.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright © 2012 Intel Corporation - * Copyright © 2014 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Rob Bradford - */ - -#ifndef XKBCOMMON_UTF8_H -#define XKBCOMMON_UTF8_H - -int -utf32_to_utf8(uint32_t unichar, char *buffer); - -bool -is_valid_utf8(const char *ss, size_t len); - -#endif diff --git a/src/3rdparty/xkbcommon/src/utils.c b/src/3rdparty/xkbcommon/src/utils.c deleted file mode 100644 index a71b570b34..0000000000 --- a/src/3rdparty/xkbcommon/src/utils.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright © 2013 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "utils.h" - -#ifdef HAVE_MMAP - -#include -#include -#include -#include -#include - -bool -map_file(FILE *file, char **string_out, size_t *size_out) -{ - struct stat stat_buf; - int fd; - char *string; - - /* Make sure to keep the errno on failure! */ - fd = fileno(file); - if (fd < 0) - return false; - - if (fstat(fd, &stat_buf) != 0) - return false; - - string = mmap(NULL, stat_buf.st_size, PROT_READ, MAP_SHARED, fd, 0); - if (string == MAP_FAILED) - return false; - - *string_out = string; - *size_out = stat_buf.st_size; - return true; -} - -void -unmap_file(char *str, size_t size) -{ - munmap(str, size); -} - -#else - -bool -map_file(FILE *file, char **string_out, size_t *size_out) -{ - long ret; - size_t ret_s; - char *string; - size_t size; - - /* Make sure to keep the errno on failure! */ - - ret = fseek(file, 0, SEEK_END); - if (ret != 0) - return false; - - ret = ftell(file); - if (ret < 0) - return false; - size = (size_t) ret; - - ret = fseek(file, 0, SEEK_SET); - if (ret < 0) - return false; - - string = malloc(size); - if (!string) - return false; - - ret_s = fread(string, 1, size, file); - if (ret_s < size) { - free(string); - return false; - } - - *string_out = string; - *size_out = size; - return true; -} - -void -unmap_file(char *str, size_t size) -{ - free(str); -} - -#endif - -// ASCII lower-case map. -static const unsigned char lower_map[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, - 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, - 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, - 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, - 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, - 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, - 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 -}; - -// ASCII tolower (to avoid locale issues). -char -to_lower(char c) -{ - return (char) lower_map[(unsigned char) c]; -} - -// ASCII strcasecmp (to avoid locale issues). -int -istrcmp(const char *a, const char *b) -{ - for (size_t i = 0; ; i++) { - if (to_lower(a[i]) != to_lower(b[i])) - return (int) to_lower(a[i]) - (int) to_lower(b[i]); - if (!a[i]) - break; - } - return 0; -} - -// ASCII strncasecmp (to avoid locale issues). -int -istrncmp(const char *a, const char *b, size_t n) -{ - for (size_t i = 0; i < n; i++) { - if (to_lower(a[i]) != to_lower(b[i])) - return (int) to_lower(a[i]) - (int) to_lower(b[i]); - if (!a[i]) - break; - } - return 0; -} diff --git a/src/3rdparty/xkbcommon/src/utils.h b/src/3rdparty/xkbcommon/src/utils.h deleted file mode 100644 index cb98e8e11a..0000000000 --- a/src/3rdparty/xkbcommon/src/utils.h +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright © 2012 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef UTILS_H -#define UTILS_H 1 - -#include -#include -#include -#include -#include - -#include "darray.h" - -/* - * We sometimes malloc strings and then expose them as const char*'s. This - * macro is used when we free these strings in order to avoid -Wcast-qual - * errors. - */ -#define UNCONSTIFY(const_ptr) ((void *) (uintptr_t) (const_ptr)) - -#define STATIC_ASSERT(expr, message) do { \ - switch (0) { case 0: case (expr): ; } \ -} while (0) - -char -to_lower(char c); - -int -istrcmp(const char *a, const char *b); - -int -istrncmp(const char *a, const char *b, size_t n); - -static inline bool -streq(const char *s1, const char *s2) -{ - return strcmp(s1, s2) == 0; -} - -static inline bool -streq_not_null(const char *s1, const char *s2) -{ - if (!s1 || !s2) - return false; - return streq(s1, s2); -} - -static inline bool -istreq(const char *s1, const char *s2) -{ - return istrcmp(s1, s2) == 0; -} - -static inline bool -istreq_prefix(const char *s1, const char *s2) -{ - return istrncmp(s1, s2, strlen(s1)) == 0; -} - -static inline char * -strdup_safe(const char *s) -{ - return s ? strdup(s) : NULL; -} - -static inline size_t -strlen_safe(const char *s) -{ - return s ? strlen(s) : 0; -} - -static inline bool -isempty(const char *s) -{ - return s == NULL || s[0] == '\0'; -} - -static inline const char * -strnull(const char *s) -{ - return s ? s : "(null)"; -} - -static inline const char * -strempty(const char *s) -{ - return s ? s : ""; -} - -static inline void * -memdup(const void *mem, size_t nmemb, size_t size) -{ - void *p = calloc(nmemb, size); - if (p) - memcpy(p, mem, nmemb * size); - return p; -} - -static inline int -min(int misc, int other) -{ - return (misc < other) ? misc : other; -} - -static inline int -max(int misc, int other) -{ - return (misc > other) ? misc : other; -} - -/* ctype.h is locale-dependent and has other oddities. */ -static inline bool -is_space(char ch) -{ - return ch == ' ' || (ch >= '\t' && ch <= '\r'); -} - -static inline bool -is_alpha(char ch) -{ - return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'); -} - -static inline bool -is_digit(char ch) -{ - return ch >= '0' && ch <= '9'; -} - -static inline bool -is_alnum(char ch) -{ - return is_alpha(ch) || is_digit(ch); -} - -static inline bool -is_xdigit(char ch) -{ - return - (ch >= '0' && ch <= '9') || - (ch >= 'a' && ch <= 'f') || - (ch >= 'A' && ch <= 'F'); -} - -static inline bool -is_graph(char ch) -{ - /* See table in ascii(7). */ - return ch >= '!' && ch <= '~'; -} - -/* - * Return the bit position of the most significant bit. - * Note: this is 1-based! It's more useful this way, and returns 0 when - * mask is all 0s. - */ -static inline unsigned -msb_pos(uint32_t mask) -{ - unsigned pos = 0; - while (mask) { - pos++; - mask >>= 1u; - } - return pos; -} - -// Avoid conflict with other popcount()s. -static inline int -my_popcount(uint32_t x) -{ - int count; -#if defined(HAVE___BUILTIN_POPCOUNT) - count = __builtin_popcount(x); -#else - for (count = 0; x; count++) - x &= x - 1; -#endif - return count; -} - -bool -map_file(FILE *file, char **string_out, size_t *size_out); - -void -unmap_file(char *string, size_t size); - -#define ARRAY_SIZE(arr) ((sizeof(arr) / sizeof(*(arr)))) - -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define MIN3(a, b, c) MIN(MIN((a), (b)), (c)) -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#define MAX3(a, b, c) MAX(MAX((a), (b)), (c)) - -/* Round up @a so it's divisible by @b. */ -#define ROUNDUP(a, b) (((a) + (b) - 1) / (b) * (b)) - -#if defined(HAVE_SECURE_GETENV) -# define secure_getenv secure_getenv -#elif defined(HAVE___SECURE_GETENV) -# define secure_getenv __secure_getenv -#else -# define secure_getenv getenv -#endif - -#if defined(HAVE___BUILTIN_EXPECT) -# define likely(x) __builtin_expect(!!(x), 1) -# define unlikely(x) __builtin_expect(!!(x), 0) -#else -# define likely(x) (x) -# define unlikely(x) (x) -#endif - -/* Compiler Attributes */ - -#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__CYGWIN__) -# define XKB_EXPORT __attribute__((visibility("default"))) -#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) -# define XKB_EXPORT __global -#else /* not gcc >= 4 and not Sun Studio >= 8 */ -# define XKB_EXPORT -#endif - -#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203) -# define ATTR_PRINTF(x,y) __attribute__((__format__(__printf__, x, y))) -#else /* not gcc >= 2.3 */ -# define ATTR_PRINTF(x,y) -#endif - -#if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)) \ - || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) -# define ATTR_NORETURN __attribute__((__noreturn__)) -#else -# define ATTR_NORETURN -#endif /* GNUC */ - -#if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 296) -#define ATTR_MALLOC __attribute__((__malloc__)) -#else -#define ATTR_MALLOC -#endif - -#if defined(__GNUC__) && (__GNUC__ >= 4) -# define ATTR_NULL_SENTINEL __attribute__((__sentinel__)) -#else -# define ATTR_NULL_SENTINEL -#endif /* GNUC >= 4 */ - -#if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 295) -#define ATTR_PACKED __attribute__((__packed__)) -#else -#define ATTR_PACKED -#endif - -#endif /* UTILS_H */ diff --git a/src/3rdparty/xkbcommon/src/x11/util.c b/src/3rdparty/xkbcommon/src/x11/util.c deleted file mode 100644 index c41f1d6cd9..0000000000 --- a/src/3rdparty/xkbcommon/src/x11/util.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright © 2013 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "x11-priv.h" - -XKB_EXPORT int -xkb_x11_setup_xkb_extension(xcb_connection_t *conn, - uint16_t major_xkb_version, - uint16_t minor_xkb_version, - enum xkb_x11_setup_xkb_extension_flags flags, - uint16_t *major_xkb_version_out, - uint16_t *minor_xkb_version_out, - uint8_t *base_event_out, - uint8_t *base_error_out) -{ - uint8_t base_event, base_error; - uint16_t server_major, server_minor; - - if (flags & ~(XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS)) { - /* log_err_func(ctx, "unrecognized flags: %#x\n", flags); */ - return 0; - } - - { - const xcb_query_extension_reply_t *reply = - xcb_get_extension_data(conn, &xcb_xkb_id); - if (!reply) { - /* log_err_func(ctx, "failed to query for XKB extension\n"); */ - return 0; - } - - if (!reply->present) { - /* log_err_func(ctx, "failed to start using XKB extension: not available in server\n"); */ - return 0; - } - - base_event = reply->first_event; - base_error = reply->first_error; - } - - { - xcb_generic_error_t *error = NULL; - xcb_xkb_use_extension_cookie_t cookie = - xcb_xkb_use_extension(conn, major_xkb_version, minor_xkb_version); - xcb_xkb_use_extension_reply_t *reply = - xcb_xkb_use_extension_reply(conn, cookie, &error); - - if (!reply) { - /* log_err_func(ctx, */ - /* "failed to start using XKB extension: error code %d\n", */ - /* error ? error->error_code : -1); */ - free(error); - return 0; - } - - if (!reply->supported) { - /* log_err_func(ctx, */ - /* "failed to start using XKB extension: server doesn't support version %d.%d\n", */ - /* major_xkb_version, minor_xkb_version); */ - free(reply); - return 0; - } - - server_major = reply->serverMajor; - server_minor = reply->serverMinor; - - free(reply); - } - - /* - * The XkbUseExtension() in libX11 has a *bunch* of legacy stuff, but - * it doesn't seem like any of it is useful to us. - */ - - if (major_xkb_version_out) - *major_xkb_version_out = server_major; - if (minor_xkb_version_out) - *minor_xkb_version_out = server_minor; - if (base_event_out) - *base_event_out = base_event; - if (base_error_out) - *base_error_out = base_error; - - return 1; -} - -XKB_EXPORT int32_t -xkb_x11_get_core_keyboard_device_id(xcb_connection_t *conn) -{ - int32_t device_id; - xcb_xkb_get_device_info_cookie_t cookie = - xcb_xkb_get_device_info(conn, XCB_XKB_ID_USE_CORE_KBD, - 0, 0, 0, 0, 0, 0); - xcb_xkb_get_device_info_reply_t *reply = - xcb_xkb_get_device_info_reply(conn, cookie, NULL); - - if (!reply) - return -1; - - device_id = reply->deviceID; - free(reply); - return device_id; -} - -bool -get_atom_name(xcb_connection_t *conn, xcb_atom_t atom, char **out) -{ - xcb_get_atom_name_cookie_t cookie; - xcb_get_atom_name_reply_t *reply; - int length; - char *name; - - if (atom == 0) { - *out = NULL; - return true; - } - - cookie = xcb_get_atom_name(conn, atom); - reply = xcb_get_atom_name_reply(conn, cookie, NULL); - if (!reply) - return false; - - length = xcb_get_atom_name_name_length(reply); - name = xcb_get_atom_name_name(reply); - - *out = strndup(name, length); - if (!*out) { - free(reply); - return false; - } - - free(reply); - return true; -} - -bool -adopt_atoms(struct xkb_context *ctx, xcb_connection_t *conn, - const xcb_atom_t *from, xkb_atom_t *to, const size_t count) -{ - enum { SIZE = 128 }; - xcb_get_atom_name_cookie_t cookies[SIZE]; - const size_t num_batches = ROUNDUP(count, SIZE) / SIZE; - - /* Send and collect the atoms in batches of reasonable SIZE. */ - for (size_t batch = 0; batch < num_batches; batch++) { - const size_t start = batch * SIZE; - const size_t stop = min((batch + 1) * SIZE, count); - - /* Send. */ - for (size_t i = start; i < stop; i++) - if (from[i] != XCB_ATOM_NONE) - cookies[i % SIZE] = xcb_get_atom_name(conn, from[i]); - - /* Collect. */ - for (size_t i = start; i < stop; i++) { - xcb_get_atom_name_reply_t *reply; - - if (from[i] == XCB_ATOM_NONE) { - to[i] = XKB_ATOM_NONE; - continue; - } - - reply = xcb_get_atom_name_reply(conn, cookies[i % SIZE], NULL); - if (!reply) - goto err_discard; - - to[i] = xkb_atom_intern(ctx, - xcb_get_atom_name_name(reply), - xcb_get_atom_name_name_length(reply)); - free(reply); - - if (to[i] == XKB_ATOM_NONE) - goto err_discard; - - continue; - - /* - * If we don't discard the uncollected replies, they just - * sit in the XCB queue waiting forever. Sad. - */ -err_discard: - for (size_t j = i + 1; j < stop; j++) - if (from[j] != XCB_ATOM_NONE) - xcb_discard_reply(conn, cookies[j % SIZE].sequence); - return false; - } - } - - return true; -} - -bool -adopt_atom(struct xkb_context *ctx, xcb_connection_t *conn, xcb_atom_t atom, - xkb_atom_t *out) -{ - return adopt_atoms(ctx, conn, &atom, out, 1); -} diff --git a/src/3rdparty/xkbcommon/src/x11/x11-keymap.c b/src/3rdparty/xkbcommon/src/x11/x11-keymap.c deleted file mode 100644 index 701b614b2f..0000000000 --- a/src/3rdparty/xkbcommon/src/x11/x11-keymap.c +++ /dev/null @@ -1,1177 +0,0 @@ -/* - * Copyright © 2013 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "x11-priv.h" - -/* - * References for the lonesome traveler: - * Xkb protocol specification: - * https://www.x.org/releases/current/doc/kbproto/xkbproto.html - * The XCB xkb XML protocol file: - * /user/share/xcb/xkb.xml - * The XCB xkb header file: - * /usr/include/xcb/xkb.h - * The old kbproto header files: - * /usr/include/X11/extensions/XKB{,proto,str}.h - * Xlib XKB source code: - * /src/xkb/XKBGetMap.c (and friends) - * X server XKB protocol handling: - * /xkb/xkb.c - * Man pages: - * XkbGetMap(3), XkbGetCompatMap(3), etc. - */ - -/* Constants from /usr/include/X11/extensions/XKB.h */ -/* XkbNumModifiers. */ -#define NUM_REAL_MODS 8u -/* XkbNumVirtualMods. */ -#define NUM_VMODS 16u -/* XkbNoModifier. */ -#define NO_MODIFIER 0xff -/* XkbNumIndicators. */ -#define NUM_INDICATORS 32u -/* XkbAllIndicatorsMask. */ -#define ALL_INDICATORS_MASK 0xffffffff - -/* Some macros. Not very nice but it'd be worse without them. */ - -/* - * We try not to trust the server too much and be paranoid. If we get - * something which we definitely shouldn't, we fail. - */ -#define STRINGIFY(expr) #expr -#define FAIL_UNLESS(expr) do { \ - if (!(expr)) { \ - log_err(keymap->ctx, \ - "x11: failed to get keymap from X server: unmet condition in %s(): %s\n", \ - __func__, STRINGIFY(expr)); \ - goto fail; \ - } \ -} while (0) - -#define FAIL_IF_BAD_REPLY(reply, request_name) do { \ - if (!reply) { \ - log_err(keymap->ctx, \ - "x11: failed to get keymap from X server: %s request failed\n", \ - (request_name)); \ - goto fail; \ - } \ -} while (0) - -#define ALLOC_OR_FAIL(arr, nmemb) do { \ - if ((nmemb) > 0) { \ - (arr) = calloc((nmemb), sizeof(*(arr))); \ - if (!(arr)) \ - goto fail; \ - } \ -} while (0) - - -static xkb_mod_mask_t -translate_mods(uint8_t rmods, uint16_t vmods_low, uint16_t vmods_high) -{ - /* We represent mod masks in a single uint32_t value, with real mods - * first and vmods after (though we don't make these distinctions). */ - return - ((xkb_mod_mask_t) rmods) | - ((xkb_mod_mask_t) vmods_low << 8) | - ((xkb_mod_mask_t) vmods_high << 16); -} - -static enum xkb_action_controls -translate_controls_mask(uint32_t wire) -{ - enum xkb_action_controls ret = 0; - if (wire & XCB_XKB_BOOL_CTRL_REPEAT_KEYS) - ret |= CONTROL_REPEAT; - if (wire & XCB_XKB_BOOL_CTRL_SLOW_KEYS) - ret |= CONTROL_SLOW; - if (wire & XCB_XKB_BOOL_CTRL_BOUNCE_KEYS) - ret |= CONTROL_DEBOUNCE; - if (wire & XCB_XKB_BOOL_CTRL_STICKY_KEYS) - ret |= CONTROL_STICKY; - if (wire & XCB_XKB_BOOL_CTRL_MOUSE_KEYS) - ret |= CONTROL_MOUSEKEYS; - if (wire & XCB_XKB_BOOL_CTRL_MOUSE_KEYS_ACCEL) - ret |= CONTROL_MOUSEKEYS_ACCEL; - if (wire & XCB_XKB_BOOL_CTRL_ACCESS_X_KEYS) - ret |= CONTROL_AX; - if (wire & XCB_XKB_BOOL_CTRL_ACCESS_X_TIMEOUT_MASK) - ret |= CONTROL_AX_TIMEOUT; - if (wire & XCB_XKB_BOOL_CTRL_ACCESS_X_FEEDBACK_MASK) - ret |= CONTROL_AX_FEEDBACK; - if (wire & XCB_XKB_BOOL_CTRL_AUDIBLE_BELL_MASK) - ret |= CONTROL_BELL; - if (wire & XCB_XKB_BOOL_CTRL_IGNORE_GROUP_LOCK_MASK) - ret |= CONTROL_IGNORE_GROUP_LOCK; - /* Some controls are not supported and don't appear here. */ - return ret; -} - -static void -translate_action(union xkb_action *action, const xcb_xkb_action_t *wire) -{ - switch (wire->type) { - case XCB_XKB_SA_TYPE_SET_MODS: - action->type = ACTION_TYPE_MOD_SET; - - action->mods.mods.mods = translate_mods(wire->setmods.realMods, - wire->setmods.vmodsLow, - wire->setmods.vmodsHigh); - action->mods.mods.mask = translate_mods(wire->setmods.mask, 0, 0); - - if (wire->setmods.flags & XCB_XKB_SA_CLEAR_LOCKS) - action->mods.flags |= ACTION_LOCK_CLEAR; - if (wire->setmods.flags & XCB_XKB_SA_LATCH_TO_LOCK) - action->mods.flags |= ACTION_LATCH_TO_LOCK; - if (wire->setmods.flags & XCB_XKB_SA_USE_MOD_MAP_MODS) - action->mods.flags |= ACTION_MODS_LOOKUP_MODMAP; - - break; - case XCB_XKB_SA_TYPE_LATCH_MODS: - action->type = ACTION_TYPE_MOD_LATCH; - - action->mods.mods.mods = translate_mods(wire->latchmods.realMods, - wire->latchmods.vmodsLow, - wire->latchmods.vmodsHigh); - action->mods.mods.mask = translate_mods(wire->latchmods.mask, 0, 0); - - if (wire->latchmods.flags & XCB_XKB_SA_CLEAR_LOCKS) - action->mods.flags |= ACTION_LOCK_CLEAR; - if (wire->latchmods.flags & XCB_XKB_SA_LATCH_TO_LOCK) - action->mods.flags |= ACTION_LATCH_TO_LOCK; - if (wire->latchmods.flags & XCB_XKB_SA_USE_MOD_MAP_MODS) - action->mods.flags |= ACTION_MODS_LOOKUP_MODMAP; - - break; - case XCB_XKB_SA_TYPE_LOCK_MODS: - action->type = ACTION_TYPE_MOD_LOCK; - - action->mods.mods.mods = translate_mods(wire->lockmods.realMods, - wire->lockmods.vmodsLow, - wire->lockmods.vmodsHigh); - action->mods.mods.mask = translate_mods(wire->lockmods.mask, 0, 0); - - if (wire->lockmods.flags & XCB_XKB_SA_ISO_LOCK_FLAG_NO_LOCK) - action->mods.flags |= ACTION_LOCK_NO_LOCK; - if (wire->lockmods.flags & XCB_XKB_SA_ISO_LOCK_FLAG_NO_UNLOCK) - action->mods.flags |= ACTION_LOCK_NO_UNLOCK; - if (wire->lockmods.flags & XCB_XKB_SA_USE_MOD_MAP_MODS) - action->mods.flags |= ACTION_MODS_LOOKUP_MODMAP; - - break; - case XCB_XKB_SA_TYPE_SET_GROUP: - action->type = ACTION_TYPE_GROUP_SET; - - action->group.group = wire->setgroup.group; - - if (wire->setmods.flags & XCB_XKB_SA_CLEAR_LOCKS) - action->group.flags |= ACTION_LOCK_CLEAR; - if (wire->setmods.flags & XCB_XKB_SA_LATCH_TO_LOCK) - action->group.flags |= ACTION_LATCH_TO_LOCK; - if (wire->setmods.flags & XCB_XKB_SA_ISO_LOCK_FLAG_GROUP_ABSOLUTE) - action->group.flags |= ACTION_ABSOLUTE_SWITCH; - - break; - case XCB_XKB_SA_TYPE_LATCH_GROUP: - action->type = ACTION_TYPE_GROUP_LATCH; - - action->group.group = wire->latchgroup.group; - - if (wire->latchmods.flags & XCB_XKB_SA_CLEAR_LOCKS) - action->group.flags |= ACTION_LOCK_CLEAR; - if (wire->latchmods.flags & XCB_XKB_SA_LATCH_TO_LOCK) - action->group.flags |= ACTION_LATCH_TO_LOCK; - if (wire->latchmods.flags & XCB_XKB_SA_ISO_LOCK_FLAG_GROUP_ABSOLUTE) - action->group.flags |= ACTION_ABSOLUTE_SWITCH; - - break; - case XCB_XKB_SA_TYPE_LOCK_GROUP: - action->type = ACTION_TYPE_GROUP_LOCK; - - action->group.group = wire->lockgroup.group; - - if (wire->lockgroup.flags & XCB_XKB_SA_ISO_LOCK_FLAG_GROUP_ABSOLUTE) - action->group.flags |= ACTION_ABSOLUTE_SWITCH; - - break; - case XCB_XKB_SA_TYPE_MOVE_PTR: - action->type = ACTION_TYPE_PTR_MOVE; - - action->ptr.x = (int16_t) (wire->moveptr.xLow | ((uint16_t) wire->moveptr.xHigh << 8)); - action->ptr.y = (int16_t) (wire->moveptr.yLow | ((uint16_t) wire->moveptr.yHigh << 8)); - - if (!(wire->moveptr.flags & XCB_XKB_SA_MOVE_PTR_FLAG_NO_ACCELERATION)) - action->ptr.flags |= ACTION_ACCEL; - if (wire->moveptr.flags & XCB_XKB_SA_MOVE_PTR_FLAG_MOVE_ABSOLUTE_X) - action->ptr.flags |= ACTION_ABSOLUTE_X; - if (wire->moveptr.flags & XCB_XKB_SA_MOVE_PTR_FLAG_MOVE_ABSOLUTE_Y) - action->ptr.flags |= ACTION_ABSOLUTE_Y; - - break; - case XCB_XKB_SA_TYPE_PTR_BTN: - action->type = ACTION_TYPE_PTR_BUTTON; - - action->btn.count = wire->ptrbtn.count; - action->btn.button = wire->ptrbtn.button; - action->btn.flags = 0; - - break; - case XCB_XKB_SA_TYPE_LOCK_PTR_BTN: - action->type = ACTION_TYPE_PTR_LOCK; - - action->btn.button = wire->lockptrbtn.button; - - if (wire->lockptrbtn.flags & XCB_XKB_SA_ISO_LOCK_FLAG_NO_LOCK) - action->btn.flags |= ACTION_LOCK_NO_LOCK; - if (wire->lockptrbtn.flags & XCB_XKB_SA_ISO_LOCK_FLAG_NO_UNLOCK) - action->btn.flags |= ACTION_LOCK_NO_UNLOCK; - - break; - case XCB_XKB_SA_TYPE_SET_PTR_DFLT: - action->type = ACTION_TYPE_PTR_DEFAULT; - - action->dflt.value = wire->setptrdflt.value; - - if (wire->setptrdflt.flags & XCB_XKB_SA_SET_PTR_DFLT_FLAG_DFLT_BTN_ABSOLUTE) - action->dflt.flags |= ACTION_ABSOLUTE_SWITCH; - - break; - case XCB_XKB_SA_TYPE_TERMINATE: - action->type = ACTION_TYPE_TERMINATE; - - break; - case XCB_XKB_SA_TYPE_SWITCH_SCREEN: - action->type = ACTION_TYPE_SWITCH_VT; - - action->screen.screen = wire->switchscreen.newScreen; - - if (!(wire->switchscreen.flags & XCB_XKB_SWITCH_SCREEN_FLAG_APPLICATION)) - action->screen.flags |= ACTION_SAME_SCREEN; - if (wire->switchscreen.flags & XCB_XKB_SWITCH_SCREEN_FLAG_ABSOLUTE) - action->screen.flags |= ACTION_ABSOLUTE_SWITCH; - - break; - case XCB_XKB_SA_TYPE_SET_CONTROLS: - action->type = ACTION_TYPE_CTRL_SET; - { - const uint16_t mask = (wire->setcontrols.boolCtrlsLow | - (wire->setcontrols.boolCtrlsHigh << 8)); - action->ctrls.ctrls = translate_controls_mask(mask); - } - break; - case XCB_XKB_SA_TYPE_LOCK_CONTROLS: - action->type = ACTION_TYPE_CTRL_LOCK; - { - const uint16_t mask = (wire->lockcontrols.boolCtrlsLow | - (wire->lockcontrols.boolCtrlsHigh << 8)); - action->ctrls.ctrls = translate_controls_mask(mask); - } - break; - - case XCB_XKB_SA_TYPE_NO_ACTION: - /* We don't support these. */ - case XCB_XKB_SA_TYPE_ISO_LOCK: - case XCB_XKB_SA_TYPE_REDIRECT_KEY: - case XCB_XKB_SA_TYPE_ACTION_MESSAGE: - case XCB_XKB_SA_TYPE_DEVICE_BTN: - case XCB_XKB_SA_TYPE_LOCK_DEVICE_BTN: - case XCB_XKB_SA_TYPE_DEVICE_VALUATOR: - action->type = ACTION_TYPE_NONE; - break; - - default: - if (wire->type < ACTION_TYPE_PRIVATE) { - action->type = ACTION_TYPE_NONE; - break; - } - - /* Treat high unknown actions as Private actions. */ - action->priv.type = wire->noaction.type; - STATIC_ASSERT(sizeof(action->priv.data) == 7 && - sizeof(wire->noaction.pad0) == 7, - "The private action data must be 7 bytes long!"); - memcpy(action->priv.data, wire->noaction.pad0, 7); - break; - } -} - -static bool -get_types(struct xkb_keymap *keymap, xcb_connection_t *conn, - xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map) -{ - int types_length = xcb_xkb_get_map_map_types_rtrn_length(reply, map); - xcb_xkb_key_type_iterator_t types_iter = - xcb_xkb_get_map_map_types_rtrn_iterator(reply, map); - - FAIL_UNLESS(reply->firstType == 0); - - keymap->num_types = reply->nTypes; - ALLOC_OR_FAIL(keymap->types, keymap->num_types); - - for (int i = 0; i < types_length; i++) { - xcb_xkb_key_type_t *wire_type = types_iter.data; - struct xkb_key_type *type = &keymap->types[i]; - - FAIL_UNLESS(wire_type->numLevels > 0); - - type->mods.mods = translate_mods(wire_type->mods_mods, - wire_type->mods_vmods, 0); - type->mods.mask = translate_mods(wire_type->mods_mask, 0, 0); - type->num_levels = wire_type->numLevels; - - { - int entries_length = xcb_xkb_key_type_map_length(wire_type); - xcb_xkb_kt_map_entry_iterator_t entries_iter = - xcb_xkb_key_type_map_iterator(wire_type); - - type->num_entries = wire_type->nMapEntries; - ALLOC_OR_FAIL(type->entries, type->num_entries); - - for (int j = 0; j < entries_length; j++) { - xcb_xkb_kt_map_entry_t *wire_entry = entries_iter.data; - struct xkb_key_type_entry *entry = &type->entries[j]; - - FAIL_UNLESS(wire_entry->level < type->num_levels); - - entry->level = wire_entry->level; - entry->mods.mods = translate_mods(wire_entry->mods_mods, - wire_entry->mods_vmods, 0); - entry->mods.mask = translate_mods(wire_entry->mods_mask, 0, 0); - - xcb_xkb_kt_map_entry_next(&entries_iter); - } - } - - { - int preserves_length = xcb_xkb_key_type_preserve_length(wire_type); - xcb_xkb_mod_def_iterator_t preserves_iter = - xcb_xkb_key_type_preserve_iterator(wire_type); - - FAIL_UNLESS((unsigned) preserves_length <= type->num_entries); - - for (int j = 0; j < preserves_length; j++) { - xcb_xkb_mod_def_t *wire_preserve = preserves_iter.data; - struct xkb_key_type_entry *entry = &type->entries[j]; - - entry->preserve.mods = translate_mods(wire_preserve->realMods, - wire_preserve->vmods, 0); - entry->preserve.mask = translate_mods(wire_preserve->mask, 0, 0); - - xcb_xkb_mod_def_next(&preserves_iter); - } - } - - xcb_xkb_key_type_next(&types_iter); - } - - return true; - -fail: - return false; -} - -static bool -get_sym_maps(struct xkb_keymap *keymap, xcb_connection_t *conn, - xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map) -{ - int sym_maps_length = xcb_xkb_get_map_map_syms_rtrn_length(reply, map); - xcb_xkb_key_sym_map_iterator_t sym_maps_iter = - xcb_xkb_get_map_map_syms_rtrn_iterator(reply, map); - - FAIL_UNLESS(reply->minKeyCode <= reply->maxKeyCode); - FAIL_UNLESS(reply->firstKeySym >= reply->minKeyCode); - FAIL_UNLESS(reply->firstKeySym + reply->nKeySyms <= reply->maxKeyCode + 1); - - keymap->min_key_code = reply->minKeyCode; - keymap->max_key_code = reply->maxKeyCode; - - ALLOC_OR_FAIL(keymap->keys, keymap->max_key_code + 1); - - for (xkb_keycode_t kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++) - keymap->keys[kc].keycode = kc; - - for (int i = 0; i < sym_maps_length; i++) { - xcb_xkb_key_sym_map_t *wire_sym_map = sym_maps_iter.data; - struct xkb_key *key = &keymap->keys[reply->firstKeySym + i]; - - key->num_groups = wire_sym_map->groupInfo & 0x0f; - FAIL_UNLESS(key->num_groups <= ARRAY_SIZE(wire_sym_map->kt_index)); - ALLOC_OR_FAIL(key->groups, key->num_groups); - - for (unsigned j = 0; j < key->num_groups; j++) { - FAIL_UNLESS(wire_sym_map->kt_index[j] < keymap->num_types); - key->groups[j].type = &keymap->types[wire_sym_map->kt_index[j]]; - - ALLOC_OR_FAIL(key->groups[j].levels, key->groups[j].type->num_levels); - } - - key->out_of_range_group_number = (wire_sym_map->groupInfo & 0x30) >> 4; - - FAIL_UNLESS(key->out_of_range_group_number <= key->num_groups); - - if (wire_sym_map->groupInfo & XCB_XKB_GROUPS_WRAP_CLAMP_INTO_RANGE) - key->out_of_range_group_action = RANGE_SATURATE; - else if (wire_sym_map->groupInfo & XCB_XKB_GROUPS_WRAP_REDIRECT_INTO_RANGE) - key->out_of_range_group_action = RANGE_REDIRECT; - else - key->out_of_range_group_action = RANGE_WRAP; - - { - int syms_length = xcb_xkb_key_sym_map_syms_length(wire_sym_map); - xcb_keysym_t *syms_iter = xcb_xkb_key_sym_map_syms(wire_sym_map); - - FAIL_UNLESS((unsigned) syms_length == wire_sym_map->width * key->num_groups); - - for (int j = 0; j < syms_length; j++) { - xcb_keysym_t wire_keysym = *syms_iter; - const xkb_layout_index_t group = j / wire_sym_map->width; - const xkb_level_index_t level = j % wire_sym_map->width; - - assert(key->groups[group].type != NULL); - if (level < key->groups[group].type->num_levels && - wire_keysym != XKB_KEY_NoSymbol) { - key->groups[group].levels[level].num_syms = 1; - key->groups[group].levels[level].u.sym = wire_keysym; - } - - syms_iter++; - } - } - - xcb_xkb_key_sym_map_next(&sym_maps_iter); - } - - return true; - -fail: - return false; -} - -static bool -get_actions(struct xkb_keymap *keymap, xcb_connection_t *conn, - xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map) -{ - int acts_count_length = - xcb_xkb_get_map_map_acts_rtrn_count_length(reply, map); - uint8_t *acts_count_iter = xcb_xkb_get_map_map_acts_rtrn_count(map); - xcb_xkb_action_iterator_t acts_iter = - xcb_xkb_get_map_map_acts_rtrn_acts_iterator(reply, map); - xcb_xkb_key_sym_map_iterator_t sym_maps_iter = - xcb_xkb_get_map_map_syms_rtrn_iterator(reply, map); - - FAIL_UNLESS(reply->firstKeyAction == keymap->min_key_code); - FAIL_UNLESS(reply->firstKeyAction + reply->nKeyActions == - keymap->max_key_code + 1); - - for (int i = 0; i < acts_count_length; i++) { - xcb_xkb_key_sym_map_t *wire_sym_map = sym_maps_iter.data; - int syms_length = xcb_xkb_key_sym_map_syms_length(wire_sym_map); - uint8_t wire_count = *acts_count_iter; - struct xkb_key *key = &keymap->keys[reply->firstKeyAction + i]; - - FAIL_UNLESS(wire_count == 0 || wire_count == syms_length); - - for (int j = 0; j < wire_count; j++) { - xcb_xkb_action_t *wire_action = acts_iter.data; - const xkb_layout_index_t group = j / wire_sym_map->width; - const xkb_level_index_t level = j % wire_sym_map->width; - - if (level < key->groups[group].type->num_levels) { - union xkb_action *action = - &key->groups[group].levels[level].action; - - translate_action(action, wire_action); - } - - xcb_xkb_action_next(&acts_iter); - } - - acts_count_iter++; - xcb_xkb_key_sym_map_next(&sym_maps_iter); - } - - return true; - -fail: - return false; -} - -static bool -get_vmods(struct xkb_keymap *keymap, xcb_connection_t *conn, - xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map) -{ - uint8_t *iter = xcb_xkb_get_map_map_vmods_rtrn(map); - - keymap->mods.num_mods = - NUM_REAL_MODS + MIN(msb_pos(reply->virtualMods), NUM_VMODS); - - for (unsigned i = 0; i < NUM_VMODS; i++) { - if (reply->virtualMods & (1u << i)) { - uint8_t wire = *iter; - struct xkb_mod *mod = &keymap->mods.mods[NUM_REAL_MODS + i]; - - mod->type = MOD_VIRT; - mod->mapping = translate_mods(wire, 0, 0); - - iter++; - } - } - - return true; -} - -static bool -get_explicits(struct xkb_keymap *keymap, xcb_connection_t *conn, - xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map) -{ - int length = xcb_xkb_get_map_map_explicit_rtrn_length(reply, map); - xcb_xkb_set_explicit_iterator_t iter = - xcb_xkb_get_map_map_explicit_rtrn_iterator(reply, map); - - for (int i = 0; i < length; i++) { - xcb_xkb_set_explicit_t *wire = iter.data; - struct xkb_key *key; - - FAIL_UNLESS(wire->keycode >= keymap->min_key_code && - wire->keycode <= keymap->max_key_code); - - key = &keymap->keys[wire->keycode]; - - if ((wire->explicit & XCB_XKB_EXPLICIT_KEY_TYPE_1) && - key->num_groups > 0) - key->groups[0].explicit_type = true; - if ((wire->explicit & XCB_XKB_EXPLICIT_KEY_TYPE_2) && - key->num_groups > 1) - key->groups[1].explicit_type = true; - if ((wire->explicit & XCB_XKB_EXPLICIT_KEY_TYPE_3) && - key->num_groups > 2) - key->groups[2].explicit_type = true; - if ((wire->explicit & XCB_XKB_EXPLICIT_KEY_TYPE_4) && - key->num_groups > 3) - key->groups[3].explicit_type = true; - if (wire->explicit & XCB_XKB_EXPLICIT_INTERPRET) - key->explicit |= EXPLICIT_INTERP; - if (wire->explicit & XCB_XKB_EXPLICIT_AUTO_REPEAT) - key->explicit |= EXPLICIT_REPEAT; - if (wire->explicit & XCB_XKB_EXPLICIT_V_MOD_MAP) - key->explicit |= EXPLICIT_VMODMAP; - - xcb_xkb_set_explicit_next(&iter); - } - - return true; - -fail: - return false; -} - -static bool -get_modmaps(struct xkb_keymap *keymap, xcb_connection_t *conn, - xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map) -{ - int length = xcb_xkb_get_map_map_modmap_rtrn_length(reply, map); - xcb_xkb_key_mod_map_iterator_t iter = - xcb_xkb_get_map_map_modmap_rtrn_iterator(reply, map); - - for (int i = 0; i < length; i++) { - xcb_xkb_key_mod_map_t *wire = iter.data; - struct xkb_key *key; - - FAIL_UNLESS(wire->keycode >= keymap->min_key_code && - wire->keycode <= keymap->max_key_code); - - key = &keymap->keys[wire->keycode]; - key->modmap = wire->mods; - - xcb_xkb_key_mod_map_next(&iter); - } - - return true; - -fail: - return false; -} - -static bool -get_vmodmaps(struct xkb_keymap *keymap, xcb_connection_t *conn, - xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map) -{ - int length = xcb_xkb_get_map_map_vmodmap_rtrn_length(reply, map); - xcb_xkb_key_v_mod_map_iterator_t iter = - xcb_xkb_get_map_map_vmodmap_rtrn_iterator(reply, map); - - for (int i = 0; i < length; i++) { - xcb_xkb_key_v_mod_map_t *wire = iter.data; - struct xkb_key *key; - - FAIL_UNLESS(wire->keycode >= keymap->min_key_code && - wire->keycode <= keymap->max_key_code); - - key = &keymap->keys[wire->keycode]; - key->vmodmap = translate_mods(0, wire->vmods, 0); - - xcb_xkb_key_v_mod_map_next(&iter); - } - - return true; - -fail: - return false; -} - -static bool -get_map(struct xkb_keymap *keymap, xcb_connection_t *conn, uint16_t device_id) -{ - static const xcb_xkb_map_part_t required_components = - (XCB_XKB_MAP_PART_KEY_TYPES | - XCB_XKB_MAP_PART_KEY_SYMS | - XCB_XKB_MAP_PART_MODIFIER_MAP | - XCB_XKB_MAP_PART_EXPLICIT_COMPONENTS | - XCB_XKB_MAP_PART_KEY_ACTIONS | - XCB_XKB_MAP_PART_VIRTUAL_MODS | - XCB_XKB_MAP_PART_VIRTUAL_MOD_MAP); - - xcb_xkb_get_map_cookie_t cookie = - xcb_xkb_get_map(conn, device_id, required_components, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - xcb_xkb_get_map_reply_t *reply = xcb_xkb_get_map_reply(conn, cookie, NULL); - xcb_xkb_get_map_map_t map; - - FAIL_IF_BAD_REPLY(reply, "XkbGetMap"); - - if ((reply->present & required_components) != required_components) - goto fail; - - xcb_xkb_get_map_map_unpack(xcb_xkb_get_map_map(reply), - reply->nTypes, - reply->nKeySyms, - reply->nKeyActions, - reply->totalActions, - reply->totalKeyBehaviors, - reply->virtualMods, - reply->totalKeyExplicit, - reply->totalModMapKeys, - reply->totalVModMapKeys, - reply->present, - &map); - - if (!get_types(keymap, conn, reply, &map) || - !get_sym_maps(keymap, conn, reply, &map) || - !get_actions(keymap, conn, reply, &map) || - !get_vmods(keymap, conn, reply, &map) || - !get_explicits(keymap, conn, reply, &map) || - !get_modmaps(keymap, conn, reply, &map) || - !get_vmodmaps(keymap, conn, reply, &map)) - goto fail; - - free(reply); - return true; - -fail: - free(reply); - return false; -} - -static bool -get_indicators(struct xkb_keymap *keymap, xcb_connection_t *conn, - xcb_xkb_get_indicator_map_reply_t *reply) -{ - xcb_xkb_indicator_map_iterator_t iter = - xcb_xkb_get_indicator_map_maps_iterator(reply); - - keymap->num_leds = msb_pos(reply->which); - - for (unsigned i = 0; i < NUM_INDICATORS; i++) { - if (reply->which & (1u << i)) { - xcb_xkb_indicator_map_t *wire = iter.data; - struct xkb_led *led = &keymap->leds[i]; - - if (wire->whichGroups & XCB_XKB_IM_GROUPS_WHICH_USE_BASE) - led->which_groups |= XKB_STATE_LAYOUT_DEPRESSED; - if (wire->whichGroups & XCB_XKB_IM_GROUPS_WHICH_USE_LATCHED) - led->which_groups |= XKB_STATE_LAYOUT_LATCHED; - if (wire->whichGroups & XCB_XKB_IM_GROUPS_WHICH_USE_LOCKED) - led->which_groups |= XKB_STATE_LAYOUT_LOCKED; - if (wire->whichGroups & XCB_XKB_IM_GROUPS_WHICH_USE_EFFECTIVE) - led->which_groups |= XKB_STATE_LAYOUT_EFFECTIVE; - if (wire->whichGroups & XCB_XKB_IM_GROUPS_WHICH_USE_COMPAT) - led->which_groups |= XKB_STATE_LAYOUT_EFFECTIVE; - - led->groups = wire->groups; - - if (wire->whichMods & XCB_XKB_IM_MODS_WHICH_USE_BASE) - led->which_mods |= XKB_STATE_MODS_DEPRESSED; - if (wire->whichMods & XCB_XKB_IM_MODS_WHICH_USE_LATCHED) - led->which_mods |= XKB_STATE_MODS_LATCHED; - if (wire->whichMods & XCB_XKB_IM_MODS_WHICH_USE_LOCKED) - led->which_mods |= XKB_STATE_MODS_LOCKED; - if (wire->whichMods & XCB_XKB_IM_MODS_WHICH_USE_EFFECTIVE) - led->which_mods |= XKB_STATE_MODS_EFFECTIVE; - if (wire->whichMods & XCB_XKB_IM_MODS_WHICH_USE_COMPAT) - led->which_mods |= XKB_STATE_MODS_EFFECTIVE; - - led->mods.mods = translate_mods(wire->realMods, wire->vmods, 0); - led->mods.mask = translate_mods(wire->mods, 0, 0); - - led->ctrls = translate_controls_mask(wire->ctrls); - - xcb_xkb_indicator_map_next(&iter); - } - } - - return true; -} - -static bool -get_indicator_map(struct xkb_keymap *keymap, xcb_connection_t *conn, - uint16_t device_id) -{ - xcb_xkb_get_indicator_map_cookie_t cookie = - xcb_xkb_get_indicator_map(conn, device_id, ALL_INDICATORS_MASK); - xcb_xkb_get_indicator_map_reply_t *reply = - xcb_xkb_get_indicator_map_reply(conn, cookie, NULL); - - FAIL_IF_BAD_REPLY(reply, "XkbGetIndicatorMap"); - - if (!get_indicators(keymap, conn, reply)) - goto fail; - - free(reply); - return true; - -fail: - free(reply); - return false; -} - -static bool -get_sym_interprets(struct xkb_keymap *keymap, xcb_connection_t *conn, - xcb_xkb_get_compat_map_reply_t *reply) -{ - int length = xcb_xkb_get_compat_map_si_rtrn_length(reply); - xcb_xkb_sym_interpret_iterator_t iter = - xcb_xkb_get_compat_map_si_rtrn_iterator(reply); - - FAIL_UNLESS(reply->firstSIRtrn == 0); - FAIL_UNLESS(reply->nSIRtrn == reply->nTotalSI); - - keymap->num_sym_interprets = reply->nSIRtrn; - ALLOC_OR_FAIL(keymap->sym_interprets, keymap->num_sym_interprets); - - for (int i = 0; i < length; i++) { - xcb_xkb_sym_interpret_t *wire = iter.data; - struct xkb_sym_interpret *sym_interpret = &keymap->sym_interprets[i]; - - sym_interpret->sym = wire->sym; - - switch (wire->match & XCB_XKB_SYM_INTERP_MATCH_OP_MASK) { - case XCB_XKB_SYM_INTERPRET_MATCH_NONE_OF: - sym_interpret->match = MATCH_NONE; - break; - case XCB_XKB_SYM_INTERPRET_MATCH_ANY_OF_OR_NONE: - sym_interpret->match = MATCH_ANY_OR_NONE; - break; - case XCB_XKB_SYM_INTERPRET_MATCH_ANY_OF: - sym_interpret->match = MATCH_ANY; - break; - case XCB_XKB_SYM_INTERPRET_MATCH_ALL_OF: - sym_interpret->match = MATCH_ALL; - break; - case XCB_XKB_SYM_INTERPRET_MATCH_EXACTLY: - sym_interpret->match = MATCH_EXACTLY; - break; - } - - sym_interpret->level_one_only = - (wire->match & XCB_XKB_SYM_INTERP_MATCH_LEVEL_ONE_ONLY); - sym_interpret->mods = wire->mods; - - if (wire->virtualMod == NO_MODIFIER) - sym_interpret->virtual_mod = XKB_MOD_INVALID; - else - sym_interpret->virtual_mod = NUM_REAL_MODS + wire->virtualMod; - - sym_interpret->repeat = (wire->flags & 0x01); - translate_action(&sym_interpret->action, - (xcb_xkb_action_t *) &wire->action); - - xcb_xkb_sym_interpret_next(&iter); - } - - return true; - -fail: - return false; -} - -static bool -get_compat_map(struct xkb_keymap *keymap, xcb_connection_t *conn, - uint16_t device_id) -{ - xcb_xkb_get_compat_map_cookie_t cookie = - xcb_xkb_get_compat_map(conn, device_id, 0, true, 0, 0); - xcb_xkb_get_compat_map_reply_t *reply = - xcb_xkb_get_compat_map_reply(conn, cookie, NULL); - - FAIL_IF_BAD_REPLY(reply, "XkbGetCompatMap"); - - if (!get_sym_interprets(keymap, conn, reply)) - goto fail; - - free(reply); - return true; - -fail: - free(reply); - return false; -} - -static bool -get_type_names(struct xkb_keymap *keymap, xcb_connection_t *conn, - xcb_xkb_get_names_reply_t *reply, - xcb_xkb_get_names_value_list_t *list) -{ - int key_type_names_length = - xcb_xkb_get_names_value_list_type_names_length(reply, list); - xcb_atom_t *key_type_names_iter = - xcb_xkb_get_names_value_list_type_names(list); - int n_levels_per_type_length = - xcb_xkb_get_names_value_list_n_levels_per_type_length(reply, list); - uint8_t *n_levels_per_type_iter = - xcb_xkb_get_names_value_list_n_levels_per_type(list); - xcb_atom_t *kt_level_names_iter = - xcb_xkb_get_names_value_list_kt_level_names(list); - - FAIL_UNLESS(reply->nTypes == keymap->num_types); - FAIL_UNLESS(key_type_names_length == n_levels_per_type_length); - - for (int i = 0; i < key_type_names_length; i++) { - xcb_atom_t wire_type_name = *key_type_names_iter; - uint8_t wire_num_levels = *n_levels_per_type_iter; - struct xkb_key_type *type = &keymap->types[i]; - - /* Levels must have names. */ - FAIL_UNLESS(type->num_levels == wire_num_levels); - - ALLOC_OR_FAIL(type->level_names, type->num_levels); - - if (!adopt_atom(keymap->ctx, conn, wire_type_name, &type->name)) - goto fail; - - if (!adopt_atoms(keymap->ctx, conn, - kt_level_names_iter, type->level_names, - wire_num_levels)) - goto fail; - - kt_level_names_iter += wire_num_levels; - key_type_names_iter++; - n_levels_per_type_iter++; - } - - return true; - -fail: - return false; -} - -static bool -get_indicator_names(struct xkb_keymap *keymap, xcb_connection_t *conn, - xcb_xkb_get_names_reply_t *reply, - xcb_xkb_get_names_value_list_t *list) -{ - xcb_atom_t *iter = xcb_xkb_get_names_value_list_indicator_names(list); - - FAIL_UNLESS(msb_pos(reply->indicators) <= keymap->num_leds); - - for (unsigned i = 0; i < NUM_INDICATORS; i++) { - if (reply->indicators & (1u << i)) { - xcb_atom_t wire = *iter; - struct xkb_led *led = &keymap->leds[i]; - - if (!adopt_atom(keymap->ctx, conn, wire, &led->name)) - return false; - - iter++; - } - } - - return true; - -fail: - return false; -} - -static bool -get_vmod_names(struct xkb_keymap *keymap, xcb_connection_t *conn, - xcb_xkb_get_names_reply_t *reply, - xcb_xkb_get_names_value_list_t *list) -{ - xcb_atom_t *iter = xcb_xkb_get_names_value_list_virtual_mod_names(list); - - /* - * GetMap's reply->virtualMods is always 0xffff. This one really - * tells us which vmods exist (a vmod must have a name), so we fix - * up the size here. - */ - keymap->mods.num_mods = - NUM_REAL_MODS + MIN(msb_pos(reply->virtualMods), NUM_VMODS); - - for (unsigned i = 0; i < NUM_VMODS; i++) { - if (reply->virtualMods & (1u << i)) { - xcb_atom_t wire = *iter; - struct xkb_mod *mod = &keymap->mods.mods[NUM_REAL_MODS + i]; - - if (!adopt_atom(keymap->ctx, conn, wire, &mod->name)) - return false; - - iter++; - } - } - - return true; -} - -static bool -get_group_names(struct xkb_keymap *keymap, xcb_connection_t *conn, - xcb_xkb_get_names_reply_t *reply, - xcb_xkb_get_names_value_list_t *list) -{ - int length = xcb_xkb_get_names_value_list_groups_length(reply, list); - xcb_atom_t *iter = xcb_xkb_get_names_value_list_groups(list); - - keymap->num_group_names = msb_pos(reply->groupNames); - ALLOC_OR_FAIL(keymap->group_names, keymap->num_group_names); - - if (!adopt_atoms(keymap->ctx, conn, - iter, keymap->group_names, length)) - goto fail; - - return true; - -fail: - return false; -} - -static bool -get_key_names(struct xkb_keymap *keymap, xcb_connection_t *conn, - xcb_xkb_get_names_reply_t *reply, - xcb_xkb_get_names_value_list_t *list) -{ - int length = xcb_xkb_get_names_value_list_key_names_length(reply, list); - xcb_xkb_key_name_iterator_t iter = - xcb_xkb_get_names_value_list_key_names_iterator(reply, list); - - FAIL_UNLESS(reply->minKeyCode == keymap->min_key_code); - FAIL_UNLESS(reply->maxKeyCode == keymap->max_key_code); - FAIL_UNLESS(reply->firstKey == keymap->min_key_code); - FAIL_UNLESS(reply->firstKey + reply->nKeys - 1U == keymap->max_key_code); - - for (int i = 0; i < length; i++) { - xcb_xkb_key_name_t *wire = iter.data; - xkb_atom_t *key_name = &keymap->keys[reply->firstKey + i].name; - - if (wire->name[0] == '\0') { - *key_name = XKB_ATOM_NONE; - } - else { - *key_name = xkb_atom_intern(keymap->ctx, wire->name, - strnlen(wire->name, - XCB_XKB_CONST_KEY_NAME_LENGTH)); - if (!*key_name) - return false; - } - - xcb_xkb_key_name_next(&iter); - } - - return true; - -fail: - return false; -} - -static bool -get_aliases(struct xkb_keymap *keymap, xcb_connection_t *conn, - xcb_xkb_get_names_reply_t *reply, - xcb_xkb_get_names_value_list_t *list) -{ - int length = xcb_xkb_get_names_value_list_key_aliases_length(reply, list); - xcb_xkb_key_alias_iterator_t iter = - xcb_xkb_get_names_value_list_key_aliases_iterator(reply, list); - - keymap->num_key_aliases = reply->nKeyAliases; - ALLOC_OR_FAIL(keymap->key_aliases, keymap->num_key_aliases); - - for (int i = 0; i < length; i++) { - xcb_xkb_key_alias_t *wire = iter.data; - struct xkb_key_alias *alias = &keymap->key_aliases[i]; - - alias->real = - xkb_atom_intern(keymap->ctx, wire->real, - strnlen(wire->real, XCB_XKB_CONST_KEY_NAME_LENGTH)); - alias->alias = - xkb_atom_intern(keymap->ctx, wire->alias, - strnlen(wire->alias, XCB_XKB_CONST_KEY_NAME_LENGTH)); - if (!alias->real || !alias->alias) - goto fail; - - xcb_xkb_key_alias_next(&iter); - } - - return true; - -fail: - return false; -} - -static bool -get_names(struct xkb_keymap *keymap, xcb_connection_t *conn, - uint16_t device_id) -{ - static const xcb_xkb_name_detail_t wanted = - (XCB_XKB_NAME_DETAIL_KEYCODES | - XCB_XKB_NAME_DETAIL_SYMBOLS | - XCB_XKB_NAME_DETAIL_TYPES | - XCB_XKB_NAME_DETAIL_COMPAT | - XCB_XKB_NAME_DETAIL_KEY_TYPE_NAMES | - XCB_XKB_NAME_DETAIL_KT_LEVEL_NAMES | - XCB_XKB_NAME_DETAIL_INDICATOR_NAMES | - XCB_XKB_NAME_DETAIL_KEY_NAMES | - XCB_XKB_NAME_DETAIL_KEY_ALIASES | - XCB_XKB_NAME_DETAIL_VIRTUAL_MOD_NAMES | - XCB_XKB_NAME_DETAIL_GROUP_NAMES); - static const xcb_xkb_name_detail_t required = - (XCB_XKB_NAME_DETAIL_KEY_TYPE_NAMES | - XCB_XKB_NAME_DETAIL_KT_LEVEL_NAMES | - XCB_XKB_NAME_DETAIL_KEY_NAMES | - XCB_XKB_NAME_DETAIL_VIRTUAL_MOD_NAMES); - - xcb_xkb_get_names_cookie_t cookie = - xcb_xkb_get_names(conn, device_id, wanted); - xcb_xkb_get_names_reply_t *reply = - xcb_xkb_get_names_reply(conn, cookie, NULL); - xcb_xkb_get_names_value_list_t list; - - FAIL_IF_BAD_REPLY(reply, "XkbGetNames"); - - FAIL_UNLESS((reply->which & required) == required); - - xcb_xkb_get_names_value_list_unpack(xcb_xkb_get_names_value_list(reply), - reply->nTypes, - reply->indicators, - reply->virtualMods, - reply->groupNames, - reply->nKeys, - reply->nKeyAliases, - reply->nRadioGroups, - reply->which, - &list); - - if (!get_atom_name(conn, list.keycodesName, &keymap->keycodes_section_name) || - !get_atom_name(conn, list.symbolsName, &keymap->symbols_section_name) || - !get_atom_name(conn, list.typesName, &keymap->types_section_name) || - !get_atom_name(conn, list.compatName, &keymap->compat_section_name) || - !get_type_names(keymap, conn, reply, &list) || - !get_indicator_names(keymap, conn, reply, &list) || - !get_vmod_names(keymap, conn, reply, &list) || - !get_group_names(keymap, conn, reply, &list) || - !get_key_names(keymap, conn, reply, &list) || - !get_aliases(keymap, conn, reply, &list)) - goto fail; - - XkbEscapeMapName(keymap->keycodes_section_name); - XkbEscapeMapName(keymap->symbols_section_name); - XkbEscapeMapName(keymap->types_section_name); - XkbEscapeMapName(keymap->compat_section_name); - - free(reply); - return true; - -fail: - free(reply); - return false; -} - -static bool -get_controls(struct xkb_keymap *keymap, xcb_connection_t *conn, - uint16_t device_id) -{ - xcb_xkb_get_controls_cookie_t cookie = - xcb_xkb_get_controls(conn, device_id); - xcb_xkb_get_controls_reply_t *reply = - xcb_xkb_get_controls_reply(conn, cookie, NULL); - - FAIL_IF_BAD_REPLY(reply, "XkbGetControls"); - FAIL_UNLESS(reply->numGroups > 0 && reply->numGroups <= 4); - - keymap->enabled_ctrls = translate_controls_mask(reply->enabledControls); - keymap->num_groups = reply->numGroups; - - FAIL_UNLESS(keymap->max_key_code < XCB_XKB_CONST_PER_KEY_BIT_ARRAY_SIZE * 8); - - for (xkb_keycode_t i = keymap->min_key_code; i <= keymap->max_key_code; i++) - keymap->keys[i].repeats = (reply->perKeyRepeat[i / 8] & (1 << (i % 8))); - - free(reply); - return true; - -fail: - free(reply); - return false; -} - -XKB_EXPORT struct xkb_keymap * -xkb_x11_keymap_new_from_device(struct xkb_context *ctx, - xcb_connection_t *conn, - int32_t device_id, - enum xkb_keymap_compile_flags flags) -{ - struct xkb_keymap *keymap; - const enum xkb_keymap_format format = XKB_KEYMAP_FORMAT_TEXT_V1; - - if (flags & ~(XKB_KEYMAP_COMPILE_NO_FLAGS)) { - log_err_func(ctx, "unrecognized flags: %#x\n", flags); - return NULL; - } - - if (device_id < 0 || device_id > 127) { - log_err_func(ctx, "illegal device ID: %d\n", device_id); - return NULL; - } - - keymap = xkb_keymap_new(ctx, format, flags); - if (!keymap) - return NULL; - - if (!get_map(keymap, conn, device_id) || - !get_indicator_map(keymap, conn, device_id) || - !get_compat_map(keymap, conn, device_id) || - !get_names(keymap, conn, device_id) || - !get_controls(keymap, conn, device_id)) { - xkb_keymap_unref(keymap); - return NULL; - } - - return keymap; -} diff --git a/src/3rdparty/xkbcommon/src/x11/x11-priv.h b/src/3rdparty/xkbcommon/src/x11/x11-priv.h deleted file mode 100644 index 3a19e99c04..0000000000 --- a/src/3rdparty/xkbcommon/src/x11/x11-priv.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright © 2013 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef _XKBCOMMON_X11_PRIV_H -#define _XKBCOMMON_X11_PRIV_H - -#include - -#include "keymap.h" -#include "xkbcommon/xkbcommon-x11.h" - -/* Get a strdup'd name of an X atom. */ -bool -get_atom_name(xcb_connection_t *conn, xcb_atom_t atom, char **out); - -/* - * Make a xkb_atom_t's from X atoms (prefer to send as many as possible - * at once, to avoid many roundtrips). - * - * TODO: We can make this more flexible, such that @to doesn't have to - * be sequential. Then we can convert most adopt_atom() calls to - * adopt_atoms(). - * Atom caching would also likely be useful for avoiding quite a - * few requests. - */ -bool -adopt_atoms(struct xkb_context *ctx, xcb_connection_t *conn, - const xcb_atom_t *from, xkb_atom_t *to, size_t count); - -bool -adopt_atom(struct xkb_context *ctx, xcb_connection_t *conn, xcb_atom_t atom, - xkb_atom_t *out); - -#endif diff --git a/src/3rdparty/xkbcommon/src/x11/x11-state.c b/src/3rdparty/xkbcommon/src/x11/x11-state.c deleted file mode 100644 index da7dcc23c2..0000000000 --- a/src/3rdparty/xkbcommon/src/x11/x11-state.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright © 2013 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "x11-priv.h" - -static bool -update_initial_state(struct xkb_state *state, xcb_connection_t *conn, - uint16_t device_id) -{ - xcb_xkb_get_state_cookie_t cookie = - xcb_xkb_get_state(conn, device_id); - xcb_xkb_get_state_reply_t *reply = - xcb_xkb_get_state_reply(conn, cookie, NULL); - - if (!reply) - return false; - - xkb_state_update_mask(state, - reply->baseMods, - reply->latchedMods, - reply->lockedMods, - reply->baseGroup, - reply->latchedGroup, - reply->lockedGroup); - - free(reply); - return true; -} - -XKB_EXPORT struct xkb_state * -xkb_x11_state_new_from_device(struct xkb_keymap *keymap, - xcb_connection_t *conn, int32_t device_id) -{ - struct xkb_state *state; - - if (device_id < 0 || device_id > 255) { - log_err_func(keymap->ctx, "illegal device ID: %d", device_id); - return NULL; - } - - state = xkb_state_new(keymap); - if (!state) - return NULL; - - if (!update_initial_state(state, conn, device_id)) { - xkb_state_unref(state); - return NULL; - } - - return state; -} diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/action.c b/src/3rdparty/xkbcommon/src/xkbcomp/action.c deleted file mode 100644 index f99a850083..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/action.c +++ /dev/null @@ -1,871 +0,0 @@ -/************************************************************ - * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting - * documentation, and that the name of Silicon Graphics not be - * used in advertising or publicity pertaining to distribution - * of the software without specific prior written permission. - * Silicon Graphics makes no representation about the suitability - * of this software for any purpose. It is provided "as is" - * without any express or implied warranty. - * - * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - * THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - ********************************************************/ - -/* - * Copyright © 2012 Intel Corporation - * Copyright © 2012 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Daniel Stone - * Ran Benita - */ - -#include "xkbcomp-priv.h" -#include "text.h" -#include "expr.h" -#include "action.h" - -static const ExprBoolean constTrue = { - .expr = { - .common = { .type = STMT_EXPR, .next = NULL }, - .op = EXPR_VALUE, - .value_type = EXPR_TYPE_BOOLEAN, - }, - .set = true, -}; - -static const ExprBoolean constFalse = { - .expr = { - .common = { .type = STMT_EXPR, .next = NULL }, - .op = EXPR_VALUE, - .value_type = EXPR_TYPE_BOOLEAN, - }, - .set = false, -}; - -enum action_field { - ACTION_FIELD_CLEAR_LOCKS, - ACTION_FIELD_LATCH_TO_LOCK, - ACTION_FIELD_GEN_KEY_EVENT, - ACTION_FIELD_REPORT, - ACTION_FIELD_DEFAULT, - ACTION_FIELD_AFFECT, - ACTION_FIELD_INCREMENT, - ACTION_FIELD_MODIFIERS, - ACTION_FIELD_GROUP, - ACTION_FIELD_X, - ACTION_FIELD_Y, - ACTION_FIELD_ACCEL, - ACTION_FIELD_BUTTON, - ACTION_FIELD_VALUE, - ACTION_FIELD_CONTROLS, - ACTION_FIELD_TYPE, - ACTION_FIELD_COUNT, - ACTION_FIELD_SCREEN, - ACTION_FIELD_SAME, - ACTION_FIELD_DATA, - ACTION_FIELD_DEVICE, - ACTION_FIELD_KEYCODE, - ACTION_FIELD_MODS_TO_CLEAR, -}; - -ActionsInfo * -NewActionsInfo(void) -{ - enum xkb_action_type type; - ActionsInfo *info; - - info = calloc(1, sizeof(*info)); - if (!info) - return NULL; - - for (type = 0; type < _ACTION_TYPE_NUM_ENTRIES; type++) - info->actions[type].type = type; - - /* Apply some "factory defaults". */ - - /* Increment default button. */ - info->actions[ACTION_TYPE_PTR_DEFAULT].dflt.flags = 0; - info->actions[ACTION_TYPE_PTR_DEFAULT].dflt.value = 1; - info->actions[ACTION_TYPE_PTR_MOVE].ptr.flags = ACTION_ACCEL; - info->actions[ACTION_TYPE_SWITCH_VT].screen.flags = ACTION_SAME_SCREEN; - - return info; -} - -void -FreeActionsInfo(ActionsInfo *info) -{ - free(info); -} - -static const LookupEntry fieldStrings[] = { - { "clearLocks", ACTION_FIELD_CLEAR_LOCKS }, - { "latchToLock", ACTION_FIELD_LATCH_TO_LOCK }, - { "genKeyEvent", ACTION_FIELD_GEN_KEY_EVENT }, - { "generateKeyEvent", ACTION_FIELD_GEN_KEY_EVENT }, - { "report", ACTION_FIELD_REPORT }, - { "default", ACTION_FIELD_DEFAULT }, - { "affect", ACTION_FIELD_AFFECT }, - { "increment", ACTION_FIELD_INCREMENT }, - { "modifiers", ACTION_FIELD_MODIFIERS }, - { "mods", ACTION_FIELD_MODIFIERS }, - { "group", ACTION_FIELD_GROUP }, - { "x", ACTION_FIELD_X }, - { "y", ACTION_FIELD_Y }, - { "accel", ACTION_FIELD_ACCEL }, - { "accelerate", ACTION_FIELD_ACCEL }, - { "repeat", ACTION_FIELD_ACCEL }, - { "button", ACTION_FIELD_BUTTON }, - { "value", ACTION_FIELD_VALUE }, - { "controls", ACTION_FIELD_CONTROLS }, - { "ctrls", ACTION_FIELD_CONTROLS }, - { "type", ACTION_FIELD_TYPE }, - { "count", ACTION_FIELD_COUNT }, - { "screen", ACTION_FIELD_SCREEN }, - { "same", ACTION_FIELD_SAME }, - { "sameServer", ACTION_FIELD_SAME }, - { "data", ACTION_FIELD_DATA }, - { "device", ACTION_FIELD_DEVICE }, - { "dev", ACTION_FIELD_DEVICE }, - { "key", ACTION_FIELD_KEYCODE }, - { "keycode", ACTION_FIELD_KEYCODE }, - { "kc", ACTION_FIELD_KEYCODE }, - { "clearmods", ACTION_FIELD_MODS_TO_CLEAR }, - { "clearmodifiers", ACTION_FIELD_MODS_TO_CLEAR }, - { NULL, 0 } -}; - -static bool -stringToAction(const char *str, enum xkb_action_type *type_rtrn) -{ - return LookupString(actionTypeNames, str, type_rtrn); -} - -static bool -stringToField(const char *str, enum action_field *field_rtrn) -{ - return LookupString(fieldStrings, str, field_rtrn); -} - -static const char * -fieldText(enum action_field field) -{ - return LookupValue(fieldStrings, field); -} - -/***====================================================================***/ - -static inline bool -ReportMismatch(struct xkb_context *ctx, enum xkb_action_type action, - enum action_field field, const char *type) -{ - log_err(ctx, - "Value of %s field must be of type %s; " - "Action %s definition ignored\n", - fieldText(field), type, ActionTypeText(action)); - return false; -} - -static inline bool -ReportIllegal(struct xkb_context *ctx, enum xkb_action_type action, - enum action_field field) -{ - log_err(ctx, - "Field %s is not defined for an action of type %s; " - "Action definition ignored\n", - fieldText(field), ActionTypeText(action)); - return false; -} - -static inline bool -ReportActionNotArray(struct xkb_context *ctx, enum xkb_action_type action, - enum action_field field) -{ - log_err(ctx, - "The %s field in the %s action is not an array; " - "Action definition ignored\n", - fieldText(field), ActionTypeText(action)); - return false; -} - -static bool -HandleNoAction(struct xkb_context *ctx, const struct xkb_mod_set *mods, - union xkb_action *action, enum action_field field, - const ExprDef *array_ndx, const ExprDef *value) - -{ - return true; -} - -static bool -CheckBooleanFlag(struct xkb_context *ctx, enum xkb_action_type action, - enum action_field field, enum xkb_action_flags flag, - const ExprDef *array_ndx, const ExprDef *value, - enum xkb_action_flags *flags_inout) -{ - bool set; - - if (array_ndx) - return ReportActionNotArray(ctx, action, field); - - if (!ExprResolveBoolean(ctx, value, &set)) - return ReportMismatch(ctx, action, field, "boolean"); - - if (set) - *flags_inout |= flag; - else - *flags_inout &= ~flag; - - return true; -} - -static bool -CheckModifierField(struct xkb_context *ctx, const struct xkb_mod_set *mods, - enum xkb_action_type action, const ExprDef *array_ndx, - const ExprDef *value, enum xkb_action_flags *flags_inout, - xkb_mod_mask_t *mods_rtrn) -{ - if (array_ndx) - return ReportActionNotArray(ctx, action, ACTION_FIELD_MODIFIERS); - - if (value->expr.op == EXPR_IDENT) { - const char *valStr; - valStr = xkb_atom_text(ctx, value->ident.ident); - if (valStr && (istreq(valStr, "usemodmapmods") || - istreq(valStr, "modmapmods"))) { - *mods_rtrn = 0; - *flags_inout |= ACTION_MODS_LOOKUP_MODMAP; - return true; - } - } - - if (!ExprResolveModMask(ctx, value, MOD_BOTH, mods, mods_rtrn)) - return ReportMismatch(ctx, action, - ACTION_FIELD_MODIFIERS, "modifier mask"); - - *flags_inout &= ~ACTION_MODS_LOOKUP_MODMAP; - return true; -} - -static const LookupEntry lockWhich[] = { - { "both", 0 }, - { "lock", ACTION_LOCK_NO_UNLOCK }, - { "neither", (ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK) }, - { "unlock", ACTION_LOCK_NO_LOCK }, - { NULL, 0 } -}; - -static bool -CheckAffectField(struct xkb_context *ctx, enum xkb_action_type action, - const ExprDef *array_ndx, const ExprDef *value, - enum xkb_action_flags *flags_inout) -{ - enum xkb_action_flags flags; - - if (array_ndx) - return ReportActionNotArray(ctx, action, ACTION_FIELD_AFFECT); - - if (!ExprResolveEnum(ctx, value, &flags, lockWhich)) - return ReportMismatch(ctx, action, ACTION_FIELD_AFFECT, - "lock, unlock, both, neither"); - - *flags_inout &= ~(ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK); - *flags_inout |= flags; - return true; -} - -static bool -HandleSetLatchLockMods(struct xkb_context *ctx, const struct xkb_mod_set *mods, - union xkb_action *action, enum action_field field, - const ExprDef *array_ndx, const ExprDef *value) -{ - struct xkb_mod_action *act = &action->mods; - const enum xkb_action_type type = action->type; - - if (field == ACTION_FIELD_MODIFIERS) - return CheckModifierField(ctx, mods, action->type, array_ndx, value, - &act->flags, &act->mods.mods); - if ((type == ACTION_TYPE_MOD_SET || type == ACTION_TYPE_MOD_LATCH) && - field == ACTION_FIELD_CLEAR_LOCKS) - return CheckBooleanFlag(ctx, action->type, field, - ACTION_LOCK_CLEAR, array_ndx, value, - &act->flags); - if (type == ACTION_TYPE_MOD_LATCH && - field == ACTION_FIELD_LATCH_TO_LOCK) - return CheckBooleanFlag(ctx, action->type, field, - ACTION_LATCH_TO_LOCK, array_ndx, value, - &act->flags); - if (type == ACTION_TYPE_MOD_LOCK && - field == ACTION_FIELD_AFFECT) - return CheckAffectField(ctx, action->type, array_ndx, value, - &act->flags); - - return ReportIllegal(ctx, action->type, field); -} - -static bool -CheckGroupField(struct xkb_context *ctx, enum xkb_action_type action, - const ExprDef *array_ndx, const ExprDef *value, - enum xkb_action_flags *flags_inout, int32_t *group_rtrn) -{ - const ExprDef *spec; - xkb_layout_index_t idx; - enum xkb_action_flags flags = *flags_inout; - - if (array_ndx) - return ReportActionNotArray(ctx, action, ACTION_FIELD_GROUP); - - if (value->expr.op == EXPR_NEGATE || value->expr.op == EXPR_UNARY_PLUS) { - flags &= ~ACTION_ABSOLUTE_SWITCH; - spec = value->unary.child; - } - else { - flags |= ACTION_ABSOLUTE_SWITCH; - spec = value; - } - - if (!ExprResolveGroup(ctx, spec, &idx)) - return ReportMismatch(ctx, action, ACTION_FIELD_GROUP, - "integer (range 1..8)"); - - /* +n, -n are relative, n is absolute. */ - if (value->expr.op == EXPR_NEGATE || value->expr.op == EXPR_UNARY_PLUS) { - *group_rtrn = (int32_t) idx; - if (value->expr.op == EXPR_NEGATE) - *group_rtrn = -*group_rtrn; - } - else { - *group_rtrn = (int32_t) (idx - 1); - } - *flags_inout = flags; - return true; -} - -static bool -HandleSetLatchLockGroup(struct xkb_context *ctx, const struct xkb_mod_set *mods, - union xkb_action *action, enum action_field field, - const ExprDef *array_ndx, const ExprDef *value) -{ - struct xkb_group_action *act = &action->group; - const enum xkb_action_type type = action->type; - - if (field == ACTION_FIELD_GROUP) - return CheckGroupField(ctx, action->type, array_ndx, value, - &act->flags, &act->group); - if ((type == ACTION_TYPE_GROUP_SET || type == ACTION_TYPE_GROUP_LATCH) && - field == ACTION_FIELD_CLEAR_LOCKS) - return CheckBooleanFlag(ctx, action->type, field, - ACTION_LOCK_CLEAR, array_ndx, value, - &act->flags); - if (type == ACTION_TYPE_GROUP_LATCH && - field == ACTION_FIELD_LATCH_TO_LOCK) - return CheckBooleanFlag(ctx, action->type, field, - ACTION_LATCH_TO_LOCK, array_ndx, value, - &act->flags); - - return ReportIllegal(ctx, action->type, field); -} - -static bool -HandleMovePtr(struct xkb_context *ctx, const struct xkb_mod_set *mods, - union xkb_action *action, enum action_field field, - const ExprDef *array_ndx, const ExprDef *value) -{ - struct xkb_pointer_action *act = &action->ptr; - - if (field == ACTION_FIELD_X || field == ACTION_FIELD_Y) { - int val; - const bool absolute = (value->expr.op != EXPR_NEGATE && - value->expr.op != EXPR_UNARY_PLUS); - - if (array_ndx) - return ReportActionNotArray(ctx, action->type, field); - - if (!ExprResolveInteger(ctx, value, &val)) - return ReportMismatch(ctx, action->type, field, "integer"); - - if (val < INT16_MIN || val > INT16_MAX) { - log_err(ctx, - "The %s field in the %s action must be in range %d..%d; " - "Action definition ignored\n", - fieldText(field), ActionTypeText(action->type), - INT16_MIN, INT16_MAX); - return false; - } - - if (field == ACTION_FIELD_X) { - if (absolute) - act->flags |= ACTION_ABSOLUTE_X; - act->x = (int16_t) val; - } - else { - if (absolute) - act->flags |= ACTION_ABSOLUTE_Y; - act->y = (int16_t) val; - } - - return true; - } - else if (field == ACTION_FIELD_ACCEL) { - return CheckBooleanFlag(ctx, action->type, field, - ACTION_ACCEL, array_ndx, value, &act->flags); - } - - return ReportIllegal(ctx, action->type, field); -} - -static bool -HandlePtrBtn(struct xkb_context *ctx, const struct xkb_mod_set *mods, - union xkb_action *action, enum action_field field, - const ExprDef *array_ndx, const ExprDef *value) -{ - struct xkb_pointer_button_action *act = &action->btn; - - if (field == ACTION_FIELD_BUTTON) { - int btn; - - if (array_ndx) - return ReportActionNotArray(ctx, action->type, field); - - if (!ExprResolveButton(ctx, value, &btn)) - return ReportMismatch(ctx, action->type, field, - "integer (range 1..5)"); - - if (btn < 0 || btn > 5) { - log_err(ctx, - "Button must specify default or be in the range 1..5; " - "Illegal button value %d ignored\n", btn); - return false; - } - - act->button = btn; - return true; - } - else if (action->type == ACTION_TYPE_PTR_LOCK && - field == ACTION_FIELD_AFFECT) { - return CheckAffectField(ctx, action->type, array_ndx, value, - &act->flags); - } - else if (field == ACTION_FIELD_COUNT) { - int val; - - if (array_ndx) - return ReportActionNotArray(ctx, action->type, field); - - if (!ExprResolveInteger(ctx, value, &val)) - return ReportMismatch(ctx, action->type, field, "integer"); - - if (val < 0 || val > 255) { - log_err(ctx, - "The count field must have a value in the range 0..255; " - "Illegal count %d ignored\n", val); - return false; - } - - act->count = (uint8_t) val; - return true; - } - - return ReportIllegal(ctx, action->type, field); -} - -static const LookupEntry ptrDflts[] = { - { "dfltbtn", 1 }, - { "defaultbutton", 1 }, - { "button", 1 }, - { NULL, 0 } -}; - -static bool -HandleSetPtrDflt(struct xkb_context *ctx, const struct xkb_mod_set *mods, - union xkb_action *action, enum action_field field, - const ExprDef *array_ndx, const ExprDef *value) -{ - struct xkb_pointer_default_action *act = &action->dflt; - - if (field == ACTION_FIELD_AFFECT) { - unsigned int val; - - if (array_ndx) - return ReportActionNotArray(ctx, action->type, field); - - if (!ExprResolveEnum(ctx, value, &val, ptrDflts)) - return ReportMismatch(ctx, action->type, field, - "pointer component"); - return true; - } - else if (field == ACTION_FIELD_BUTTON || field == ACTION_FIELD_VALUE) { - const ExprDef *button; - int btn; - - if (array_ndx) - return ReportActionNotArray(ctx, action->type, field); - - if (value->expr.op == EXPR_NEGATE || - value->expr.op == EXPR_UNARY_PLUS) { - act->flags &= ~ACTION_ABSOLUTE_SWITCH; - button = value->unary.child; - } - else { - act->flags |= ACTION_ABSOLUTE_SWITCH; - button = value; - } - - if (!ExprResolveButton(ctx, button, &btn)) - return ReportMismatch(ctx, action->type, field, - "integer (range 1..5)"); - - if (btn < 0 || btn > 5) { - log_err(ctx, - "New default button value must be in the range 1..5; " - "Illegal default button value %d ignored\n", btn); - return false; - } - if (btn == 0) { - log_err(ctx, - "Cannot set default pointer button to \"default\"; " - "Illegal default button setting ignored\n"); - return false; - } - - act->value = (value->expr.op == EXPR_NEGATE ? -btn: btn); - return true; - } - - return ReportIllegal(ctx, action->type, field); -} - -static bool -HandleSwitchScreen(struct xkb_context *ctx, const struct xkb_mod_set *mods, - union xkb_action *action, enum action_field field, - const ExprDef *array_ndx, const ExprDef *value) -{ - struct xkb_switch_screen_action *act = &action->screen; - - if (field == ACTION_FIELD_SCREEN) { - const ExprDef *scrn; - int val; - - if (array_ndx) - return ReportActionNotArray(ctx, action->type, field); - - if (value->expr.op == EXPR_NEGATE || - value->expr.op == EXPR_UNARY_PLUS) { - act->flags &= ~ACTION_ABSOLUTE_SWITCH; - scrn = value->unary.child; - } - else { - act->flags |= ACTION_ABSOLUTE_SWITCH; - scrn = value; - } - - if (!ExprResolveInteger(ctx, scrn, &val)) - return ReportMismatch(ctx, action->type, field, - "integer (0..255)"); - - if (val < 0 || val > 255) { - log_err(ctx, - "Screen index must be in the range 1..255; " - "Illegal screen value %d ignored\n", val); - return false; - } - - act->screen = (value->expr.op == EXPR_NEGATE ? -val : val); - return true; - } - else if (field == ACTION_FIELD_SAME) { - return CheckBooleanFlag(ctx, action->type, field, - ACTION_SAME_SCREEN, array_ndx, value, - &act->flags); - } - - return ReportIllegal(ctx, action->type, field); -} - -static bool -HandleSetLockControls(struct xkb_context *ctx, const struct xkb_mod_set *mods, - union xkb_action *action, enum action_field field, - const ExprDef *array_ndx, const ExprDef *value) -{ - struct xkb_controls_action *act = &action->ctrls; - - if (field == ACTION_FIELD_CONTROLS) { - enum xkb_action_controls mask; - - if (array_ndx) - return ReportActionNotArray(ctx, action->type, field); - - if (!ExprResolveMask(ctx, value, &mask, ctrlMaskNames)) - return ReportMismatch(ctx, action->type, field, - "controls mask"); - - act->ctrls = mask; - return true; - } - else if (field == ACTION_FIELD_AFFECT) { - return CheckAffectField(ctx, action->type, array_ndx, value, - &act->flags); - } - - return ReportIllegal(ctx, action->type, field); -} - -static bool -HandlePrivate(struct xkb_context *ctx, const struct xkb_mod_set *mods, - union xkb_action *action, enum action_field field, - const ExprDef *array_ndx, const ExprDef *value) -{ - struct xkb_private_action *act = &action->priv; - - if (field == ACTION_FIELD_TYPE) { - int type; - - if (array_ndx) - return ReportActionNotArray(ctx, action->type, field); - - if (!ExprResolveInteger(ctx, value, &type)) - return ReportMismatch(ctx, ACTION_TYPE_PRIVATE, field, "integer"); - - if (type < 0 || type > 255) { - log_err(ctx, - "Private action type must be in the range 0..255; " - "Illegal type %d ignored\n", type); - return false; - } - - /* - * It's possible for someone to write something like this: - * actions = [ Private(type=3,data[0]=1,data[1]=3,data[2]=3) ] - * where the type refers to some existing action type, e.g. LockMods. - * This assumes that this action's struct is laid out in memory - * exactly as described in the XKB specification and libraries. - * We, however, have changed these structs in various ways, so this - * assumption is no longer true. Since this is a lousy "feature", we - * make actions like these no-ops for now. - */ - if (type < ACTION_TYPE_PRIVATE) { - log_info(ctx, - "Private actions of type %s are not supported; Ignored\n", - ActionTypeText(type)); - act->type = ACTION_TYPE_NONE; - } - else { - act->type = (enum xkb_action_type) type; - } - - return true; - } - else if (field == ACTION_FIELD_DATA) { - if (array_ndx == NULL) { - xkb_atom_t val; - const char *str; - size_t len; - - if (!ExprResolveString(ctx, value, &val)) - return ReportMismatch(ctx, action->type, field, "string"); - - str = xkb_atom_text(ctx, val); - len = strlen(str); - if (len < 1 || len > 7) { - log_warn(ctx, - "A private action has 7 data bytes; " - "Illegal data ignored\n"); - return false; - } - - /* act->data may not be null-terminated, this is intentional */ - strncpy((char *) act->data, str, sizeof(act->data)); - return true; - } - else { - int ndx, datum; - - if (!ExprResolveInteger(ctx, array_ndx, &ndx)) { - log_err(ctx, - "Array subscript must be integer; " - "Illegal subscript ignored\n"); - return false; - } - - if (ndx < 0 || (size_t) ndx >= sizeof(act->data)) { - log_err(ctx, - "The data for a private action is %lu bytes long; " - "Attempt to use data[%d] ignored\n", - (unsigned long) sizeof(act->data), ndx); - return false; - } - - if (!ExprResolveInteger(ctx, value, &datum)) - return ReportMismatch(ctx, act->type, field, "integer"); - - if (datum < 0 || datum > 255) { - log_err(ctx, - "All data for a private action must be 0..255; " - "Illegal datum %d ignored\n", datum); - return false; - } - - act->data[ndx] = (uint8_t) datum; - return true; - } - } - - return ReportIllegal(ctx, ACTION_TYPE_NONE, field); -} - -typedef bool (*actionHandler)(struct xkb_context *ctx, - const struct xkb_mod_set *mods, - union xkb_action *action, - enum action_field field, - const ExprDef *array_ndx, - const ExprDef *value); - -static const actionHandler handleAction[_ACTION_TYPE_NUM_ENTRIES] = { - [ACTION_TYPE_NONE] = HandleNoAction, - [ACTION_TYPE_MOD_SET] = HandleSetLatchLockMods, - [ACTION_TYPE_MOD_LATCH] = HandleSetLatchLockMods, - [ACTION_TYPE_MOD_LOCK] = HandleSetLatchLockMods, - [ACTION_TYPE_GROUP_SET] = HandleSetLatchLockGroup, - [ACTION_TYPE_GROUP_LATCH] = HandleSetLatchLockGroup, - [ACTION_TYPE_GROUP_LOCK] = HandleSetLatchLockGroup, - [ACTION_TYPE_PTR_MOVE] = HandleMovePtr, - [ACTION_TYPE_PTR_BUTTON] = HandlePtrBtn, - [ACTION_TYPE_PTR_LOCK] = HandlePtrBtn, - [ACTION_TYPE_PTR_DEFAULT] = HandleSetPtrDflt, - [ACTION_TYPE_TERMINATE] = HandleNoAction, - [ACTION_TYPE_SWITCH_VT] = HandleSwitchScreen, - [ACTION_TYPE_CTRL_SET] = HandleSetLockControls, - [ACTION_TYPE_CTRL_LOCK] = HandleSetLockControls, - [ACTION_TYPE_PRIVATE] = HandlePrivate, -}; - -/***====================================================================***/ - -bool -HandleActionDef(struct xkb_context *ctx, ActionsInfo *info, - const struct xkb_mod_set *mods, ExprDef *def, - union xkb_action *action) -{ - ExprDef *arg; - const char *str; - enum xkb_action_type handler_type; - - if (def->expr.op != EXPR_ACTION_DECL) { - log_err(ctx, "Expected an action definition, found %s\n", - expr_op_type_to_string(def->expr.op)); - return false; - } - - str = xkb_atom_text(ctx, def->action.name); - if (!stringToAction(str, &handler_type)) { - log_err(ctx, "Unknown action %s\n", str); - return false; - } - - /* - * Get the default values for this action type, as modified by - * statements such as: - * latchMods.clearLocks = True; - */ - *action = info->actions[handler_type]; - - /* - * Now change the action properties as specified for this - * particular instance, e.g. "modifiers" and "clearLocks" in: - * SetMods(modifiers=Alt,clearLocks); - */ - for (arg = def->action.args; arg != NULL; - arg = (ExprDef *) arg->common.next) { - const ExprDef *value; - ExprDef *field, *arrayRtrn; - const char *elemRtrn, *fieldRtrn; - enum action_field fieldNdx; - - if (arg->expr.op == EXPR_ASSIGN) { - field = arg->binary.left; - value = arg->binary.right; - } - else if (arg->expr.op == EXPR_NOT || arg->expr.op == EXPR_INVERT) { - field = arg->unary.child; - value = (const ExprDef *) &constFalse; - } - else { - field = arg; - value = (const ExprDef *) &constTrue; - } - - if (!ExprResolveLhs(ctx, field, &elemRtrn, &fieldRtrn, &arrayRtrn)) - return false; - - if (elemRtrn) { - log_err(ctx, - "Cannot change defaults in an action definition; " - "Ignoring attempt to change %s.%s\n", - elemRtrn, fieldRtrn); - return false; - } - - if (!stringToField(fieldRtrn, &fieldNdx)) { - log_err(ctx, "Unknown field name %s\n", fieldRtrn); - return false; - } - - if (!handleAction[handler_type](ctx, mods, action, fieldNdx, - arrayRtrn, value)) - return false; - } - - return true; -} - -bool -SetActionField(struct xkb_context *ctx, ActionsInfo *info, - struct xkb_mod_set *mods, const char *elem, - const char *field, ExprDef *array_ndx, ExprDef *value) -{ - enum xkb_action_type action; - enum action_field action_field; - - if (!stringToAction(elem, &action)) - return false; - - if (!stringToField(field, &action_field)) { - log_err(ctx, "\"%s\" is not a legal field name\n", field); - return false; - } - - return handleAction[action](ctx, mods, &info->actions[action], - action_field, array_ndx, value); -} diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/action.h b/src/3rdparty/xkbcommon/src/xkbcomp/action.h deleted file mode 100644 index 1f92e7b38e..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/action.h +++ /dev/null @@ -1,56 +0,0 @@ -/************************************************************ - * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting - * documentation, and that the name of Silicon Graphics not be - * used in advertising or publicity pertaining to distribution - * of the software without specific prior written permission. - * Silicon Graphics makes no representation about the suitability - * of this software for any purpose. It is provided "as is" - * without any express or implied warranty. - * - * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - * THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - ********************************************************/ - -#ifndef XKBCOMP_ACTION_H -#define XKBCOMP_ACTION_H - -/* - * This struct contains the default values which every new action - * (e.g. in an interpret statement) starts off with. It can be - * modified within the files (see calls to SetActionField). - */ -typedef struct { - union xkb_action actions[_ACTION_TYPE_NUM_ENTRIES]; -} ActionsInfo; - -ActionsInfo * -NewActionsInfo(void); - -void -FreeActionsInfo(ActionsInfo *info); - -bool -HandleActionDef(struct xkb_context *ctx, ActionsInfo *info, - const struct xkb_mod_set *mods, ExprDef *def, - union xkb_action *action); - -bool -SetActionField(struct xkb_context *ctx, ActionsInfo *info, - struct xkb_mod_set *mods, const char *elem, - const char *field, ExprDef *array_ndx, ExprDef *value); - - -#endif diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c b/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c deleted file mode 100644 index 365ff51c5f..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c +++ /dev/null @@ -1,806 +0,0 @@ -/************************************************************ - * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting - * documentation, and that the name of Silicon Graphics not be - * used in advertising or publicity pertaining to distribution - * of the software without specific prior written permission. - * Silicon Graphics makes no representation about the suitability - * of this software for any purpose. It is provided "as is" - * without any express or implied warranty. - * - * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - * THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - ********************************************************/ - -/* - * Copyright © 2012 Intel Corporation - * Copyright © 2012 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Daniel Stone - * Ran Benita - */ - -#include "xkbcomp-priv.h" -#include "ast-build.h" -#include "include.h" - -ParseCommon * -AppendStmt(ParseCommon *to, ParseCommon *append) -{ - ParseCommon *iter; - - if (!to) - return append; - - for (iter = to; iter->next; iter = iter->next); - - iter->next = append; - return to; -} - -static ExprDef * -ExprCreate(enum expr_op_type op, enum expr_value_type type, size_t size) -{ - ExprDef *expr = malloc(size); - if (!expr) - return NULL; - - expr->common.type = STMT_EXPR; - expr->common.next = NULL; - expr->expr.op = op; - expr->expr.value_type = type; - - return expr; -} - -#define EXPR_CREATE(type_, name_, op_, value_type_) \ - ExprDef *name_ = ExprCreate(op_, value_type_, sizeof(type_)); \ - if (!name_) \ - return NULL; - -ExprDef * -ExprCreateString(xkb_atom_t str) -{ - EXPR_CREATE(ExprString, expr, EXPR_VALUE, EXPR_TYPE_STRING); - expr->string.str = str; - return expr; -} - -ExprDef * -ExprCreateInteger(int ival) -{ - EXPR_CREATE(ExprInteger, expr, EXPR_VALUE, EXPR_TYPE_INT); - expr->integer.ival = ival; - return expr; -} - -ExprDef * -ExprCreateFloat(void) -{ - EXPR_CREATE(ExprFloat, expr, EXPR_VALUE, EXPR_TYPE_FLOAT); - return expr; -} - -ExprDef * -ExprCreateBoolean(bool set) -{ - EXPR_CREATE(ExprBoolean, expr, EXPR_VALUE, EXPR_TYPE_BOOLEAN); - expr->boolean.set = set; - return expr; -} - -ExprDef * -ExprCreateKeyName(xkb_atom_t key_name) -{ - EXPR_CREATE(ExprKeyName, expr, EXPR_VALUE, EXPR_TYPE_KEYNAME); - expr->key_name.key_name = key_name; - return expr; -} - -ExprDef * -ExprCreateIdent(xkb_atom_t ident) -{ - EXPR_CREATE(ExprIdent, expr, EXPR_IDENT, EXPR_TYPE_UNKNOWN); - expr->ident.ident = ident; - return expr; -} - -ExprDef * -ExprCreateUnary(enum expr_op_type op, enum expr_value_type type, - ExprDef *child) -{ - EXPR_CREATE(ExprUnary, expr, op, type); - expr->unary.child = child; - return expr; -} - -ExprDef * -ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right) -{ - EXPR_CREATE(ExprBinary, expr, op, EXPR_TYPE_UNKNOWN); - - if (op == EXPR_ASSIGN || left->expr.value_type == EXPR_TYPE_UNKNOWN) - expr->expr.value_type = right->expr.value_type; - else if (left->expr.value_type == right->expr.value_type || - right->expr.value_type == EXPR_TYPE_UNKNOWN) - expr->expr.value_type = left->expr.value_type; - expr->binary.left = left; - expr->binary.right = right; - - return expr; -} - -ExprDef * -ExprCreateFieldRef(xkb_atom_t element, xkb_atom_t field) -{ - EXPR_CREATE(ExprFieldRef, expr, EXPR_FIELD_REF, EXPR_TYPE_UNKNOWN); - expr->field_ref.element = element; - expr->field_ref.field = field; - return expr; -} - -ExprDef * -ExprCreateArrayRef(xkb_atom_t element, xkb_atom_t field, ExprDef *entry) -{ - EXPR_CREATE(ExprArrayRef, expr, EXPR_ARRAY_REF, EXPR_TYPE_UNKNOWN); - expr->array_ref.element = element; - expr->array_ref.field = field; - expr->array_ref.entry = entry; - return expr; -} - -ExprDef * -ExprCreateAction(xkb_atom_t name, ExprDef *args) -{ - EXPR_CREATE(ExprAction, expr, EXPR_ACTION_DECL, EXPR_TYPE_UNKNOWN); - expr->action.name = name; - expr->action.args = args; - return expr; -} - -ExprDef * -ExprCreateKeysymList(xkb_keysym_t sym) -{ - EXPR_CREATE(ExprKeysymList, expr, EXPR_KEYSYM_LIST, EXPR_TYPE_SYMBOLS); - - darray_init(expr->keysym_list.syms); - darray_init(expr->keysym_list.symsMapIndex); - darray_init(expr->keysym_list.symsNumEntries); - - darray_append(expr->keysym_list.syms, sym); - darray_append(expr->keysym_list.symsMapIndex, 0); - darray_append(expr->keysym_list.symsNumEntries, 1); - - return expr; -} - -ExprDef * -ExprCreateMultiKeysymList(ExprDef *expr) -{ - unsigned nLevels = darray_size(expr->keysym_list.symsMapIndex); - - darray_resize(expr->keysym_list.symsMapIndex, 1); - darray_resize(expr->keysym_list.symsNumEntries, 1); - darray_item(expr->keysym_list.symsMapIndex, 0) = 0; - darray_item(expr->keysym_list.symsNumEntries, 0) = nLevels; - - return expr; -} - -ExprDef * -ExprAppendKeysymList(ExprDef *expr, xkb_keysym_t sym) -{ - unsigned nSyms = darray_size(expr->keysym_list.syms); - - darray_append(expr->keysym_list.symsMapIndex, nSyms); - darray_append(expr->keysym_list.symsNumEntries, 1); - darray_append(expr->keysym_list.syms, sym); - - return expr; -} - -ExprDef * -ExprAppendMultiKeysymList(ExprDef *expr, ExprDef *append) -{ - unsigned nSyms = darray_size(expr->keysym_list.syms); - unsigned numEntries = darray_size(append->keysym_list.syms); - - darray_append(expr->keysym_list.symsMapIndex, nSyms); - darray_append(expr->keysym_list.symsNumEntries, numEntries); - darray_concat(expr->keysym_list.syms, append->keysym_list.syms); - - FreeStmt((ParseCommon *) append); - - return expr; -} - -KeycodeDef * -KeycodeCreate(xkb_atom_t name, int64_t value) -{ - KeycodeDef *def = malloc(sizeof(*def)); - if (!def) - return NULL; - - def->common.type = STMT_KEYCODE; - def->common.next = NULL; - def->name = name; - def->value = value; - - return def; -} - -KeyAliasDef * -KeyAliasCreate(xkb_atom_t alias, xkb_atom_t real) -{ - KeyAliasDef *def = malloc(sizeof(*def)); - if (!def) - return NULL; - - def->common.type = STMT_ALIAS; - def->common.next = NULL; - def->alias = alias; - def->real = real; - - return def; -} - -VModDef * -VModCreate(xkb_atom_t name, ExprDef *value) -{ - VModDef *def = malloc(sizeof(*def)); - if (!def) - return NULL; - - def->common.type = STMT_VMOD; - def->common.next = NULL; - def->name = name; - def->value = value; - - return def; -} - -VarDef * -VarCreate(ExprDef *name, ExprDef *value) -{ - VarDef *def = malloc(sizeof(*def)); - if (!def) - return NULL; - - def->common.type = STMT_VAR; - def->common.next = NULL; - def->name = name; - def->value = value; - - return def; -} - -VarDef * -BoolVarCreate(xkb_atom_t ident, bool set) -{ - ExprDef *name, *value; - VarDef *def; - if (!(name = ExprCreateIdent(ident))) { - return NULL; - } - if (!(value = ExprCreateBoolean(set))) { - FreeStmt((ParseCommon *) name); - return NULL; - } - if (!(def = VarCreate(name, value))) { - FreeStmt((ParseCommon *) name); - FreeStmt((ParseCommon *) value); - return NULL; - } - return def; -} - -InterpDef * -InterpCreate(xkb_keysym_t sym, ExprDef *match) -{ - InterpDef *def = malloc(sizeof(*def)); - if (!def) - return NULL; - - def->common.type = STMT_INTERP; - def->common.next = NULL; - def->sym = sym; - def->match = match; - def->def = NULL; - - return def; -} - -KeyTypeDef * -KeyTypeCreate(xkb_atom_t name, VarDef *body) -{ - KeyTypeDef *def = malloc(sizeof(*def)); - if (!def) - return NULL; - - def->common.type = STMT_TYPE; - def->common.next = NULL; - def->merge = MERGE_DEFAULT; - def->name = name; - def->body = body; - - return def; -} - -SymbolsDef * -SymbolsCreate(xkb_atom_t keyName, VarDef *symbols) -{ - SymbolsDef *def = malloc(sizeof(*def)); - if (!def) - return NULL; - - def->common.type = STMT_SYMBOLS; - def->common.next = NULL; - def->merge = MERGE_DEFAULT; - def->keyName = keyName; - def->symbols = symbols; - - return def; -} - -GroupCompatDef * -GroupCompatCreate(unsigned group, ExprDef *val) -{ - GroupCompatDef *def = malloc(sizeof(*def)); - if (!def) - return NULL; - - def->common.type = STMT_GROUP_COMPAT; - def->common.next = NULL; - def->merge = MERGE_DEFAULT; - def->group = group; - def->def = val; - - return def; -} - -ModMapDef * -ModMapCreate(xkb_atom_t modifier, ExprDef *keys) -{ - ModMapDef *def = malloc(sizeof(*def)); - if (!def) - return NULL; - - def->common.type = STMT_MODMAP; - def->common.next = NULL; - def->merge = MERGE_DEFAULT; - def->modifier = modifier; - def->keys = keys; - - return def; -} - -LedMapDef * -LedMapCreate(xkb_atom_t name, VarDef *body) -{ - LedMapDef *def = malloc(sizeof(*def)); - if (!def) - return NULL; - - def->common.type = STMT_LED_MAP; - def->common.next = NULL; - def->merge = MERGE_DEFAULT; - def->name = name; - def->body = body; - - return def; -} - -LedNameDef * -LedNameCreate(unsigned ndx, ExprDef *name, bool virtual) -{ - LedNameDef *def = malloc(sizeof(*def)); - if (!def) - return NULL; - - def->common.type = STMT_LED_NAME; - def->common.next = NULL; - def->merge = MERGE_DEFAULT; - def->ndx = ndx; - def->name = name; - def->virtual = virtual; - - return def; -} - -static void -FreeInclude(IncludeStmt *incl); - -IncludeStmt * -IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge) -{ - IncludeStmt *incl, *first; - char *file, *map, *stmt, *tmp, *extra_data; - char nextop; - - incl = first = NULL; - file = map = NULL; - tmp = str; - stmt = strdup_safe(str); - while (tmp && *tmp) - { - if (!ParseIncludeMap(&tmp, &file, &map, &nextop, &extra_data)) - goto err; - - /* - * Given an RMLVO (here layout) like 'us,,fr', the rules parser - * will give out something like 'pc+us+:2+fr:3+inet(evdev)'. - * We should just skip the ':2' in this case and leave it to the - * appropriate section to deal with the empty group. - */ - if (isempty(file)) { - free(file); - free(map); - free(extra_data); - continue; - } - - if (first == NULL) { - first = incl = malloc(sizeof(*first)); - } else { - incl->next_incl = malloc(sizeof(*first)); - incl = incl->next_incl; - } - - if (!incl) - break; - - incl->common.type = STMT_INCLUDE; - incl->common.next = NULL; - incl->merge = merge; - incl->stmt = NULL; - incl->file = file; - incl->map = map; - incl->modifier = extra_data; - incl->next_incl = NULL; - - if (nextop == '|') - merge = MERGE_AUGMENT; - else - merge = MERGE_OVERRIDE; - } - - if (first) - first->stmt = stmt; - else - free(stmt); - - return first; - -err: - log_err(ctx, "Illegal include statement \"%s\"; Ignored\n", stmt); - FreeInclude(first); - free(stmt); - return NULL; -} - -XkbFile * -XkbFileCreate(enum xkb_file_type type, char *name, ParseCommon *defs, - enum xkb_map_flags flags) -{ - XkbFile *file; - - file = calloc(1, sizeof(*file)); - if (!file) - return NULL; - - XkbEscapeMapName(name); - file->file_type = type; - file->name = name ? name : strdup("(unnamed)"); - file->defs = defs; - file->flags = flags; - - return file; -} - -XkbFile * -XkbFileFromComponents(struct xkb_context *ctx, - const struct xkb_component_names *kkctgs) -{ - char *const components[] = { - kkctgs->keycodes, kkctgs->types, - kkctgs->compat, kkctgs->symbols, - }; - enum xkb_file_type type; - IncludeStmt *include = NULL; - XkbFile *file = NULL; - ParseCommon *defs = NULL; - - for (type = FIRST_KEYMAP_FILE_TYPE; type <= LAST_KEYMAP_FILE_TYPE; type++) { - include = IncludeCreate(ctx, components[type], MERGE_DEFAULT); - if (!include) - goto err; - - file = XkbFileCreate(type, NULL, (ParseCommon *) include, 0); - if (!file) { - FreeInclude(include); - goto err; - } - - defs = AppendStmt(defs, &file->common); - } - - file = XkbFileCreate(FILE_TYPE_KEYMAP, NULL, defs, 0); - if (!file) - goto err; - - return file; - -err: - FreeXkbFile((XkbFile *) defs); - return NULL; -} - -static void -FreeExpr(ExprDef *expr) -{ - if (!expr) - return; - - switch (expr->expr.op) { - case EXPR_ACTION_LIST: - case EXPR_NEGATE: - case EXPR_UNARY_PLUS: - case EXPR_NOT: - case EXPR_INVERT: - FreeStmt((ParseCommon *) expr->unary.child); - break; - - case EXPR_DIVIDE: - case EXPR_ADD: - case EXPR_SUBTRACT: - case EXPR_MULTIPLY: - case EXPR_ASSIGN: - FreeStmt((ParseCommon *) expr->binary.left); - FreeStmt((ParseCommon *) expr->binary.right); - break; - - case EXPR_ACTION_DECL: - FreeStmt((ParseCommon *) expr->action.args); - break; - - case EXPR_ARRAY_REF: - FreeStmt((ParseCommon *) expr->array_ref.entry); - break; - - case EXPR_KEYSYM_LIST: - darray_free(expr->keysym_list.syms); - darray_free(expr->keysym_list.symsMapIndex); - darray_free(expr->keysym_list.symsNumEntries); - break; - - default: - break; - } -} - -static void -FreeInclude(IncludeStmt *incl) -{ - IncludeStmt *next; - - while (incl) - { - next = incl->next_incl; - - free(incl->file); - free(incl->map); - free(incl->modifier); - free(incl->stmt); - - free(incl); - incl = next; - } -} - -void -FreeStmt(ParseCommon *stmt) -{ - ParseCommon *next; - - while (stmt) - { - next = stmt->next; - - switch (stmt->type) { - case STMT_INCLUDE: - FreeInclude((IncludeStmt *) stmt); - /* stmt is already free'd here. */ - stmt = NULL; - break; - case STMT_EXPR: - FreeExpr((ExprDef *) stmt); - break; - case STMT_VAR: - FreeStmt((ParseCommon *) ((VarDef *) stmt)->name); - FreeStmt((ParseCommon *) ((VarDef *) stmt)->value); - break; - case STMT_TYPE: - FreeStmt((ParseCommon *) ((KeyTypeDef *) stmt)->body); - break; - case STMT_INTERP: - FreeStmt((ParseCommon *) ((InterpDef *) stmt)->match); - FreeStmt((ParseCommon *) ((InterpDef *) stmt)->def); - break; - case STMT_VMOD: - FreeStmt((ParseCommon *) ((VModDef *) stmt)->value); - break; - case STMT_SYMBOLS: - FreeStmt((ParseCommon *) ((SymbolsDef *) stmt)->symbols); - break; - case STMT_MODMAP: - FreeStmt((ParseCommon *) ((ModMapDef *) stmt)->keys); - break; - case STMT_GROUP_COMPAT: - FreeStmt((ParseCommon *) ((GroupCompatDef *) stmt)->def); - break; - case STMT_LED_MAP: - FreeStmt((ParseCommon *) ((LedMapDef *) stmt)->body); - break; - case STMT_LED_NAME: - FreeStmt((ParseCommon *) ((LedNameDef *) stmt)->name); - break; - default: - break; - } - - free(stmt); - stmt = next; - } -} - -void -FreeXkbFile(XkbFile *file) -{ - XkbFile *next; - - while (file) - { - next = (XkbFile *) file->common.next; - - switch (file->file_type) { - case FILE_TYPE_KEYMAP: - FreeXkbFile((XkbFile *) file->defs); - break; - - case FILE_TYPE_TYPES: - case FILE_TYPE_COMPAT: - case FILE_TYPE_SYMBOLS: - case FILE_TYPE_KEYCODES: - case FILE_TYPE_GEOMETRY: - FreeStmt(file->defs); - break; - - default: - break; - } - - free(file->name); - free(file); - file = next; - } -} - -static const char *xkb_file_type_strings[_FILE_TYPE_NUM_ENTRIES] = { - [FILE_TYPE_KEYCODES] = "xkb_keycodes", - [FILE_TYPE_TYPES] = "xkb_types", - [FILE_TYPE_COMPAT] = "xkb_compatibility", - [FILE_TYPE_SYMBOLS] = "xkb_symbols", - [FILE_TYPE_GEOMETRY] = "xkb_geometry", - [FILE_TYPE_KEYMAP] = "xkb_keymap", - [FILE_TYPE_RULES] = "rules", -}; - -const char * -xkb_file_type_to_string(enum xkb_file_type type) -{ - if (type >= _FILE_TYPE_NUM_ENTRIES) - return "unknown"; - return xkb_file_type_strings[type]; -} - -static const char *stmt_type_strings[_STMT_NUM_VALUES] = { - [STMT_UNKNOWN] = "unknown statement", - [STMT_INCLUDE] = "include statement", - [STMT_KEYCODE] = "key name definition", - [STMT_ALIAS] = "key alias definition", - [STMT_EXPR] = "expression", - [STMT_VAR] = "variable definition", - [STMT_TYPE] = "key type definition", - [STMT_INTERP] = "symbol interpretation definition", - [STMT_VMOD] = "virtual modifiers definition", - [STMT_SYMBOLS] = "key symbols definition", - [STMT_MODMAP] = "modifier map declaration", - [STMT_GROUP_COMPAT] = "group declaration", - [STMT_LED_MAP] = "indicator map declaration", - [STMT_LED_NAME] = "indicator name declaration", -}; - -const char * -stmt_type_to_string(enum stmt_type type) -{ - if (type >= _STMT_NUM_VALUES) - return NULL; - return stmt_type_strings[type]; -} - -static const char *expr_op_type_strings[_EXPR_NUM_VALUES] = { - [EXPR_VALUE] = "literal", - [EXPR_IDENT] = "identifier", - [EXPR_ACTION_DECL] = "action declaration", - [EXPR_FIELD_REF] = "field reference", - [EXPR_ARRAY_REF] = "array reference", - [EXPR_KEYSYM_LIST] = "list of keysyms", - [EXPR_ACTION_LIST] = "list of actions", - [EXPR_ADD] = "addition", - [EXPR_SUBTRACT] = "subtraction", - [EXPR_MULTIPLY] = "multiplication", - [EXPR_DIVIDE] = "division", - [EXPR_ASSIGN] = "assignment", - [EXPR_NOT] = "logical negation", - [EXPR_NEGATE] = "arithmetic negation", - [EXPR_INVERT] = "bitwise inversion", - [EXPR_UNARY_PLUS] = "unary plus", -}; - -const char * -expr_op_type_to_string(enum expr_op_type type) -{ - if (type >= _EXPR_NUM_VALUES) - return NULL; - return expr_op_type_strings[type]; -} - -static const char *expr_value_type_strings[_EXPR_TYPE_NUM_VALUES] = { - [EXPR_TYPE_UNKNOWN] = "unknown", - [EXPR_TYPE_BOOLEAN] = "boolean", - [EXPR_TYPE_INT] = "int", - [EXPR_TYPE_FLOAT] = "float", - [EXPR_TYPE_STRING] = "string", - [EXPR_TYPE_ACTION] = "action", - [EXPR_TYPE_KEYNAME] = "keyname", - [EXPR_TYPE_SYMBOLS] = "symbols", -}; - -const char * -expr_value_type_to_string(enum expr_value_type type) -{ - if (type >= _EXPR_TYPE_NUM_VALUES) - return NULL; - return expr_value_type_strings[type]; -} diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h b/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h deleted file mode 100644 index 6c76f381ac..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h +++ /dev/null @@ -1,125 +0,0 @@ -/************************************************************ - * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting - * documentation, and that the name of Silicon Graphics not be - * used in advertising or publicity pertaining to distribution - * of the software without specific prior written permission. - * Silicon Graphics makes no representation about the suitability - * of this software for any purpose. It is provided "as is" - * without any express or implied warranty. - * - * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - * THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - ********************************************************/ - -#ifndef XKBCOMP_AST_BUILD_H -#define XKBCOMP_AST_BUILD_H - -ParseCommon * -AppendStmt(ParseCommon *to, ParseCommon *append); - -ExprDef * -ExprCreateString(xkb_atom_t str); - -ExprDef * -ExprCreateInteger(int ival); - -ExprDef * -ExprCreateFloat(void); - -ExprDef * -ExprCreateBoolean(bool set); - -ExprDef * -ExprCreateKeyName(xkb_atom_t key_name); - -ExprDef * -ExprCreateIdent(xkb_atom_t ident); - -ExprDef * -ExprCreateUnary(enum expr_op_type op, enum expr_value_type type, - ExprDef *child); - -ExprDef * -ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right); - -ExprDef * -ExprCreateFieldRef(xkb_atom_t element, xkb_atom_t field); - -ExprDef * -ExprCreateArrayRef(xkb_atom_t element, xkb_atom_t field, ExprDef *entry); - -ExprDef * -ExprCreateAction(xkb_atom_t name, ExprDef *args); - -ExprDef * -ExprCreateMultiKeysymList(ExprDef *list); - -ExprDef * -ExprCreateKeysymList(xkb_keysym_t sym); - -ExprDef * -ExprAppendMultiKeysymList(ExprDef *list, ExprDef *append); - -ExprDef * -ExprAppendKeysymList(ExprDef *list, xkb_keysym_t sym); - -KeycodeDef * -KeycodeCreate(xkb_atom_t name, int64_t value); - -KeyAliasDef * -KeyAliasCreate(xkb_atom_t alias, xkb_atom_t real); - -VModDef * -VModCreate(xkb_atom_t name, ExprDef *value); - -VarDef * -VarCreate(ExprDef *name, ExprDef *value); - -VarDef * -BoolVarCreate(xkb_atom_t ident, bool set); - -InterpDef * -InterpCreate(xkb_keysym_t sym, ExprDef *match); - -KeyTypeDef * -KeyTypeCreate(xkb_atom_t name, VarDef *body); - -SymbolsDef * -SymbolsCreate(xkb_atom_t keyName, VarDef *symbols); - -GroupCompatDef * -GroupCompatCreate(unsigned group, ExprDef *def); - -ModMapDef * -ModMapCreate(xkb_atom_t modifier, ExprDef *keys); - -LedMapDef * -LedMapCreate(xkb_atom_t name, VarDef *body); - -LedNameDef * -LedNameCreate(unsigned ndx, ExprDef *name, bool virtual); - -IncludeStmt * -IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge); - -XkbFile * -XkbFileCreate(enum xkb_file_type type, char *name, ParseCommon *defs, - enum xkb_map_flags flags); - -void -FreeStmt(ParseCommon *stmt); - -#endif diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/ast.h b/src/3rdparty/xkbcommon/src/xkbcomp/ast.h deleted file mode 100644 index 49c5ada457..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/ast.h +++ /dev/null @@ -1,353 +0,0 @@ -/************************************************************ - * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting - * documentation, and that the name of Silicon Graphics not be - * used in advertising or publicity pertaining to distribution - * of the software without specific prior written permission. - * Silicon Graphics makes no representation about the suitability - * of this software for any purpose. It is provided "as is" - * without any express or implied warranty. - * - * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - * THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - ********************************************************/ - -/* - * Copyright © 2012 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef XKBCOMP_AST_H -#define XKBCOMP_AST_H - -enum xkb_file_type { - /* Component files, by order of compilation. */ - FILE_TYPE_KEYCODES = 0, - FILE_TYPE_TYPES = 1, - FILE_TYPE_COMPAT = 2, - FILE_TYPE_SYMBOLS = 3, - /* Geometry is not compiled any more. */ - FILE_TYPE_GEOMETRY = 4, - - /* A top level file which includes the above files. */ - FILE_TYPE_KEYMAP, - -/* File types which must be found in a keymap file. */ -#define FIRST_KEYMAP_FILE_TYPE FILE_TYPE_KEYCODES -#define LAST_KEYMAP_FILE_TYPE FILE_TYPE_SYMBOLS - - /* This one doesn't mix with the others, but useful here as well. */ - FILE_TYPE_RULES, - - _FILE_TYPE_NUM_ENTRIES -}; - -enum stmt_type { - STMT_UNKNOWN = 0, - STMT_INCLUDE, - STMT_KEYCODE, - STMT_ALIAS, - STMT_EXPR, - STMT_VAR, - STMT_TYPE, - STMT_INTERP, - STMT_VMOD, - STMT_SYMBOLS, - STMT_MODMAP, - STMT_GROUP_COMPAT, - STMT_LED_MAP, - STMT_LED_NAME, - - _STMT_NUM_VALUES -}; - -enum expr_value_type { - EXPR_TYPE_UNKNOWN = 0, - EXPR_TYPE_BOOLEAN, - EXPR_TYPE_INT, - EXPR_TYPE_FLOAT, - EXPR_TYPE_STRING, - EXPR_TYPE_ACTION, - EXPR_TYPE_KEYNAME, - EXPR_TYPE_SYMBOLS, - - _EXPR_TYPE_NUM_VALUES -}; - -enum expr_op_type { - EXPR_VALUE, - EXPR_IDENT, - EXPR_ACTION_DECL, - EXPR_FIELD_REF, - EXPR_ARRAY_REF, - EXPR_KEYSYM_LIST, - EXPR_ACTION_LIST, - EXPR_ADD, - EXPR_SUBTRACT, - EXPR_MULTIPLY, - EXPR_DIVIDE, - EXPR_ASSIGN, - EXPR_NOT, - EXPR_NEGATE, - EXPR_INVERT, - EXPR_UNARY_PLUS, - - _EXPR_NUM_VALUES -}; - -enum merge_mode { - MERGE_DEFAULT, - MERGE_AUGMENT, - MERGE_OVERRIDE, - MERGE_REPLACE, -}; - -const char * -xkb_file_type_to_string(enum xkb_file_type type); - -const char * -stmt_type_to_string(enum stmt_type type); - -const char * -expr_op_type_to_string(enum expr_op_type type); - -const char * -expr_value_type_to_string(enum expr_value_type type); - -typedef struct _ParseCommon { - struct _ParseCommon *next; - enum stmt_type type; -} ParseCommon; - -typedef struct _IncludeStmt { - ParseCommon common; - enum merge_mode merge; - char *stmt; - char *file; - char *map; - char *modifier; - struct _IncludeStmt *next_incl; -} IncludeStmt; - -typedef struct { - ParseCommon common; - enum expr_op_type op; - enum expr_value_type value_type; -} ExprCommon; - -typedef union ExprDef ExprDef; - -typedef struct { - ExprCommon expr; - xkb_atom_t ident; -} ExprIdent; - -typedef struct { - ExprCommon expr; - xkb_atom_t str; -} ExprString; - -typedef struct { - ExprCommon expr; - bool set; -} ExprBoolean; - -typedef struct { - ExprCommon expr; - int ival; -} ExprInteger; - -typedef struct { - ExprCommon expr; - /* We don't support floats, but we still represnt them in the AST, in - * order to provide proper error messages. */ -} ExprFloat; - -typedef struct { - ExprCommon expr; - xkb_atom_t key_name; -} ExprKeyName; - -typedef struct { - ExprCommon expr; - ExprDef *left; - ExprDef *right; -} ExprBinary; - -typedef struct { - ExprCommon expr; - ExprDef *child; -} ExprUnary; - -typedef struct { - ExprCommon expr; - xkb_atom_t element; - xkb_atom_t field; -} ExprFieldRef; - -typedef struct { - ExprCommon expr; - xkb_atom_t element; - xkb_atom_t field; - ExprDef *entry; -} ExprArrayRef; - -typedef struct { - ExprCommon expr; - xkb_atom_t name; - ExprDef *args; -} ExprAction; - -typedef struct { - ExprCommon expr; - darray(xkb_keysym_t) syms; - darray(unsigned int) symsMapIndex; - darray(unsigned int) symsNumEntries; -} ExprKeysymList; - -union ExprDef { - ParseCommon common; - /* Maybe someday we can use C11 anonymous struct for ExprCommon here. */ - ExprCommon expr; - ExprIdent ident; - ExprString string; - ExprBoolean boolean; - ExprInteger integer; - ExprKeyName key_name; - ExprBinary binary; - ExprUnary unary; - ExprFieldRef field_ref; - ExprArrayRef array_ref; - ExprAction action; - ExprKeysymList keysym_list; -}; - -typedef struct { - ParseCommon common; - enum merge_mode merge; - ExprDef *name; - ExprDef *value; -} VarDef; - -typedef struct { - ParseCommon common; - enum merge_mode merge; - xkb_atom_t name; - ExprDef *value; -} VModDef; - -typedef struct { - ParseCommon common; - enum merge_mode merge; - xkb_atom_t name; - int64_t value; -} KeycodeDef; - -typedef struct { - ParseCommon common; - enum merge_mode merge; - xkb_atom_t alias; - xkb_atom_t real; -} KeyAliasDef; - -typedef struct { - ParseCommon common; - enum merge_mode merge; - xkb_atom_t name; - VarDef *body; -} KeyTypeDef; - -typedef struct { - ParseCommon common; - enum merge_mode merge; - xkb_atom_t keyName; - VarDef *symbols; -} SymbolsDef; - -typedef struct { - ParseCommon common; - enum merge_mode merge; - xkb_atom_t modifier; - ExprDef *keys; -} ModMapDef; - -typedef struct { - ParseCommon common; - enum merge_mode merge; - unsigned group; - ExprDef *def; -} GroupCompatDef; - -typedef struct { - ParseCommon common; - enum merge_mode merge; - xkb_keysym_t sym; - ExprDef *match; - VarDef *def; -} InterpDef; - -typedef struct { - ParseCommon common; - enum merge_mode merge; - unsigned ndx; - ExprDef *name; - bool virtual; -} LedNameDef; - -typedef struct { - ParseCommon common; - enum merge_mode merge; - xkb_atom_t name; - VarDef *body; -} LedMapDef; - -enum xkb_map_flags { - MAP_IS_DEFAULT = (1 << 0), - MAP_IS_PARTIAL = (1 << 1), - MAP_IS_HIDDEN = (1 << 2), - MAP_HAS_ALPHANUMERIC = (1 << 3), - MAP_HAS_MODIFIER = (1 << 4), - MAP_HAS_KEYPAD = (1 << 5), - MAP_HAS_FN = (1 << 6), - MAP_IS_ALTGR = (1 << 7), -}; - -typedef struct { - ParseCommon common; - enum xkb_file_type file_type; - char *name; - ParseCommon *defs; - enum xkb_map_flags flags; -} XkbFile; - -#endif diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/compat.c b/src/3rdparty/xkbcommon/src/xkbcomp/compat.c deleted file mode 100644 index bd587c8db9..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/compat.c +++ /dev/null @@ -1,932 +0,0 @@ -/************************************************************ - * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting - * documentation, and that the name of Silicon Graphics not be - * used in advertising or publicity pertaining to distribution - * of the software without specific prior written permission. - * Silicon Graphics makes no representation about the suitability - * of this software for any purpose. It is provided "as is" - * without any express or implied warranty. - * - * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - * THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - ********************************************************/ - -/* - * Copyright © 2012 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "xkbcomp-priv.h" -#include "text.h" -#include "expr.h" -#include "action.h" -#include "vmod.h" -#include "include.h" - -enum si_field { - SI_FIELD_VIRTUAL_MOD = (1 << 0), - SI_FIELD_ACTION = (1 << 1), - SI_FIELD_AUTO_REPEAT = (1 << 2), - SI_FIELD_LEVEL_ONE_ONLY = (1 << 3), -}; - -typedef struct { - enum si_field defined; - enum merge_mode merge; - - struct xkb_sym_interpret interp; -} SymInterpInfo; - -enum led_field { - LED_FIELD_MODS = (1 << 0), - LED_FIELD_GROUPS = (1 << 1), - LED_FIELD_CTRLS = (1 << 2), -}; - -typedef struct { - enum led_field defined; - enum merge_mode merge; - - struct xkb_led led; -} LedInfo; - -typedef struct { - char *name; - int errorCount; - SymInterpInfo default_interp; - darray(SymInterpInfo) interps; - LedInfo default_led; - LedInfo leds[XKB_MAX_LEDS]; - unsigned int num_leds; - ActionsInfo *actions; - struct xkb_mod_set mods; - - struct xkb_context *ctx; -} CompatInfo; - -static const char * -siText(SymInterpInfo *si, CompatInfo *info) -{ - char *buf = xkb_context_get_buffer(info->ctx, 128); - - if (si == &info->default_interp) - return "default"; - - snprintf(buf, 128, "%s+%s(%s)", - KeysymText(info->ctx, si->interp.sym), - SIMatchText(si->interp.match), - ModMaskText(info->ctx, &info->mods, si->interp.mods)); - - return buf; -} - -static inline bool -ReportSINotArray(CompatInfo *info, SymInterpInfo *si, const char *field) -{ - return ReportNotArray(info->ctx, "symbol interpretation", field, - siText(si, info)); -} - -static inline bool -ReportSIBadType(CompatInfo *info, SymInterpInfo *si, const char *field, - const char *wanted) -{ - return ReportBadType(info->ctx, "symbol interpretation", field, - siText(si, info), wanted); -} - -static inline bool -ReportLedBadType(CompatInfo *info, LedInfo *ledi, const char *field, - const char *wanted) -{ - return ReportBadType(info->ctx, "indicator map", field, - xkb_atom_text(info->ctx, ledi->led.name), - wanted); -} - -static inline bool -ReportLedNotArray(CompatInfo *info, LedInfo *ledi, const char *field) -{ - return ReportNotArray(info->ctx, "indicator map", field, - xkb_atom_text(info->ctx, ledi->led.name)); -} - -static void -InitCompatInfo(CompatInfo *info, struct xkb_context *ctx, - ActionsInfo *actions, const struct xkb_mod_set *mods) -{ - memset(info, 0, sizeof(*info)); - info->ctx = ctx; - info->actions = actions; - info->mods = *mods; - info->default_interp.merge = MERGE_OVERRIDE; - info->default_interp.interp.virtual_mod = XKB_MOD_INVALID; - info->default_led.merge = MERGE_OVERRIDE; -} - -static void -ClearCompatInfo(CompatInfo *info) -{ - free(info->name); - darray_free(info->interps); -} - -static SymInterpInfo * -FindMatchingInterp(CompatInfo *info, SymInterpInfo *new) -{ - SymInterpInfo *old; - - darray_foreach(old, info->interps) - if (old->interp.sym == new->interp.sym && - old->interp.mods == new->interp.mods && - old->interp.match == new->interp.match) - return old; - - return NULL; -} - -static bool -UseNewInterpField(enum si_field field, SymInterpInfo *old, SymInterpInfo *new, - bool report, enum si_field *collide) -{ - if (!(old->defined & field)) - return true; - - if (new->defined & field) { - if (report) - *collide |= field; - - if (new->merge != MERGE_AUGMENT) - return true; - } - - return false; -} - -static bool -AddInterp(CompatInfo *info, SymInterpInfo *new, bool same_file) -{ - SymInterpInfo *old = FindMatchingInterp(info, new); - if (old) { - const int verbosity = xkb_context_get_log_verbosity(info->ctx); - const bool report = (same_file && verbosity > 0) || verbosity > 9; - enum si_field collide = 0; - - if (new->merge == MERGE_REPLACE) { - if (report) - log_warn(info->ctx, - "Multiple definitions for \"%s\"; " - "Earlier interpretation ignored\n", - siText(new, info)); - *old = *new; - return true; - } - - if (UseNewInterpField(SI_FIELD_VIRTUAL_MOD, old, new, report, - &collide)) { - old->interp.virtual_mod = new->interp.virtual_mod; - old->defined |= SI_FIELD_VIRTUAL_MOD; - } - if (UseNewInterpField(SI_FIELD_ACTION, old, new, report, - &collide)) { - old->interp.action = new->interp.action; - old->defined |= SI_FIELD_ACTION; - } - if (UseNewInterpField(SI_FIELD_AUTO_REPEAT, old, new, report, - &collide)) { - old->interp.repeat = new->interp.repeat; - old->defined |= SI_FIELD_AUTO_REPEAT; - } - if (UseNewInterpField(SI_FIELD_LEVEL_ONE_ONLY, old, new, report, - &collide)) { - old->interp.level_one_only = new->interp.level_one_only; - old->defined |= SI_FIELD_LEVEL_ONE_ONLY; - } - - if (collide) { - log_warn(info->ctx, - "Multiple interpretations of \"%s\"; " - "Using %s definition for duplicate fields\n", - siText(new, info), - (new->merge != MERGE_AUGMENT ? "last" : "first")); - } - - return true; - } - - darray_append(info->interps, *new); - return true; -} - -/***====================================================================***/ - -static bool -ResolveStateAndPredicate(ExprDef *expr, enum xkb_match_operation *pred_rtrn, - xkb_mod_mask_t *mods_rtrn, CompatInfo *info) -{ - if (expr == NULL) { - *pred_rtrn = MATCH_ANY_OR_NONE; - *mods_rtrn = MOD_REAL_MASK_ALL; - return true; - } - - *pred_rtrn = MATCH_EXACTLY; - if (expr->expr.op == EXPR_ACTION_DECL) { - const char *pred_txt = xkb_atom_text(info->ctx, expr->action.name); - if (!LookupString(symInterpretMatchMaskNames, pred_txt, pred_rtrn) || - !expr->action.args) { - log_err(info->ctx, - "Illegal modifier predicate \"%s\"; Ignored\n", pred_txt); - return false; - } - expr = expr->action.args; - } - else if (expr->expr.op == EXPR_IDENT) { - const char *pred_txt = xkb_atom_text(info->ctx, expr->ident.ident); - if (pred_txt && istreq(pred_txt, "any")) { - *pred_rtrn = MATCH_ANY; - *mods_rtrn = MOD_REAL_MASK_ALL; - return true; - } - } - - return ExprResolveModMask(info->ctx, expr, MOD_REAL, &info->mods, - mods_rtrn); -} - -/***====================================================================***/ - -static bool -UseNewLEDField(enum led_field field, LedInfo *old, LedInfo *new, - bool report, enum led_field *collide) -{ - if (!(old->defined & field)) - return true; - - if (new->defined & field) { - if (report) - *collide |= field; - - if (new->merge != MERGE_AUGMENT) - return true; - } - - return false; -} - -static bool -AddLedMap(CompatInfo *info, LedInfo *new, bool same_file) -{ - enum led_field collide; - const int verbosity = xkb_context_get_log_verbosity(info->ctx); - const bool report = (same_file && verbosity > 0) || verbosity > 9; - - for (xkb_led_index_t i = 0; i < info->num_leds; i++) { - LedInfo *old = &info->leds[i]; - - if (old->led.name != new->led.name) - continue; - - if (old->led.mods.mods == new->led.mods.mods && - old->led.groups == new->led.groups && - old->led.ctrls == new->led.ctrls && - old->led.which_mods == new->led.which_mods && - old->led.which_groups == new->led.which_groups) { - old->defined |= new->defined; - return true; - } - - if (new->merge == MERGE_REPLACE) { - if (report) - log_warn(info->ctx, - "Map for indicator %s redefined; " - "Earlier definition ignored\n", - xkb_atom_text(info->ctx, old->led.name)); - *old = *new; - return true; - } - - collide = 0; - if (UseNewLEDField(LED_FIELD_MODS, old, new, report, &collide)) { - old->led.which_mods = new->led.which_mods; - old->led.mods = new->led.mods; - old->defined |= LED_FIELD_MODS; - } - if (UseNewLEDField(LED_FIELD_GROUPS, old, new, report, &collide)) { - old->led.which_groups = new->led.which_groups; - old->led.groups = new->led.groups; - old->defined |= LED_FIELD_GROUPS; - } - if (UseNewLEDField(LED_FIELD_CTRLS, old, new, report, &collide)) { - old->led.ctrls = new->led.ctrls; - old->defined |= LED_FIELD_CTRLS; - } - - if (collide) { - log_warn(info->ctx, - "Map for indicator %s redefined; " - "Using %s definition for duplicate fields\n", - xkb_atom_text(info->ctx, old->led.name), - (new->merge == MERGE_AUGMENT ? "first" : "last")); - } - - return true; - } - - if (info->num_leds >= XKB_MAX_LEDS) { - log_err(info->ctx, - "Too many LEDs defined (maximum %d)\n", - XKB_MAX_LEDS); - return false; - } - info->leds[info->num_leds++] = *new; - return true; -} - -static void -MergeIncludedCompatMaps(CompatInfo *into, CompatInfo *from, - enum merge_mode merge) -{ - if (from->errorCount > 0) { - into->errorCount += from->errorCount; - return; - } - - into->mods = from->mods; - - if (into->name == NULL) { - into->name = from->name; - from->name = NULL; - } - - if (darray_empty(into->interps)) { - into->interps = from->interps; - darray_init(from->interps); - } - else { - SymInterpInfo *si; - darray_foreach(si, from->interps) { - si->merge = (merge == MERGE_DEFAULT ? si->merge : merge); - if (!AddInterp(into, si, false)) - into->errorCount++; - } - } - - if (into->num_leds == 0) { - memcpy(into->leds, from->leds, sizeof(*from->leds) * from->num_leds); - into->num_leds = from->num_leds; - from->num_leds = 0; - } - else { - for (xkb_led_index_t i = 0; i < from->num_leds; i++) { - LedInfo *ledi = &from->leds[i]; - ledi->merge = (merge == MERGE_DEFAULT ? ledi->merge : merge); - if (!AddLedMap(into, ledi, false)) - into->errorCount++; - } - } -} - -static void -HandleCompatMapFile(CompatInfo *info, XkbFile *file, enum merge_mode merge); - -static bool -HandleIncludeCompatMap(CompatInfo *info, IncludeStmt *include) -{ - CompatInfo included; - - InitCompatInfo(&included, info->ctx, info->actions, &info->mods); - included.name = include->stmt; - include->stmt = NULL; - - for (IncludeStmt *stmt = include; stmt; stmt = stmt->next_incl) { - CompatInfo next_incl; - XkbFile *file; - - file = ProcessIncludeFile(info->ctx, stmt, FILE_TYPE_COMPAT); - if (!file) { - info->errorCount += 10; - ClearCompatInfo(&included); - return false; - } - - InitCompatInfo(&next_incl, info->ctx, info->actions, &included.mods); - next_incl.default_interp = info->default_interp; - next_incl.default_interp.merge = stmt->merge; - next_incl.default_led = info->default_led; - next_incl.default_led.merge = stmt->merge; - - HandleCompatMapFile(&next_incl, file, MERGE_OVERRIDE); - - MergeIncludedCompatMaps(&included, &next_incl, stmt->merge); - - ClearCompatInfo(&next_incl); - FreeXkbFile(file); - } - - MergeIncludedCompatMaps(info, &included, include->merge); - ClearCompatInfo(&included); - - return (info->errorCount == 0); -} - -static bool -SetInterpField(CompatInfo *info, SymInterpInfo *si, const char *field, - ExprDef *arrayNdx, ExprDef *value) -{ - xkb_mod_index_t ndx; - - if (istreq(field, "action")) { - if (arrayNdx) - return ReportSINotArray(info, si, field); - - if (!HandleActionDef(info->ctx, info->actions, &info->mods, - value, &si->interp.action)) - return false; - - si->defined |= SI_FIELD_ACTION; - } - else if (istreq(field, "virtualmodifier") || - istreq(field, "virtualmod")) { - if (arrayNdx) - return ReportSINotArray(info, si, field); - - if (!ExprResolveMod(info->ctx, value, MOD_VIRT, &info->mods, &ndx)) - return ReportSIBadType(info, si, field, "virtual modifier"); - - si->interp.virtual_mod = ndx; - si->defined |= SI_FIELD_VIRTUAL_MOD; - } - else if (istreq(field, "repeat")) { - bool set; - - if (arrayNdx) - return ReportSINotArray(info, si, field); - - if (!ExprResolveBoolean(info->ctx, value, &set)) - return ReportSIBadType(info, si, field, "boolean"); - - si->interp.repeat = set; - - si->defined |= SI_FIELD_AUTO_REPEAT; - } - else if (istreq(field, "locking")) { - log_dbg(info->ctx, - "The \"locking\" field in symbol interpretation is unsupported; " - "Ignored\n"); - } - else if (istreq(field, "usemodmap") || - istreq(field, "usemodmapmods")) { - unsigned int val; - - if (arrayNdx) - return ReportSINotArray(info, si, field); - - if (!ExprResolveEnum(info->ctx, value, &val, useModMapValueNames)) - return ReportSIBadType(info, si, field, "level specification"); - - si->interp.level_one_only = val; - si->defined |= SI_FIELD_LEVEL_ONE_ONLY; - } - else { - return ReportBadField(info->ctx, "symbol interpretation", field, - siText(si, info)); - } - - return true; -} - -static bool -SetLedMapField(CompatInfo *info, LedInfo *ledi, const char *field, - ExprDef *arrayNdx, ExprDef *value) -{ - bool ok = true; - - if (istreq(field, "modifiers") || istreq(field, "mods")) { - if (arrayNdx) - return ReportLedNotArray(info, ledi, field); - - if (!ExprResolveModMask(info->ctx, value, MOD_BOTH, - &info->mods, &ledi->led.mods.mods)) - return ReportLedBadType(info, ledi, field, "modifier mask"); - - ledi->defined |= LED_FIELD_MODS; - } - else if (istreq(field, "groups")) { - unsigned int mask; - - if (arrayNdx) - return ReportLedNotArray(info, ledi, field); - - if (!ExprResolveMask(info->ctx, value, &mask, groupMaskNames)) - return ReportLedBadType(info, ledi, field, "group mask"); - - ledi->led.groups = mask; - ledi->defined |= LED_FIELD_GROUPS; - } - else if (istreq(field, "controls") || istreq(field, "ctrls")) { - unsigned int mask; - - if (arrayNdx) - return ReportLedNotArray(info, ledi, field); - - if (!ExprResolveMask(info->ctx, value, &mask, ctrlMaskNames)) - return ReportLedBadType(info, ledi, field, "controls mask"); - - ledi->led.ctrls = mask; - ledi->defined |= LED_FIELD_CTRLS; - } - else if (istreq(field, "allowexplicit")) { - log_dbg(info->ctx, - "The \"allowExplicit\" field in indicator statements is unsupported; " - "Ignored\n"); - } - else if (istreq(field, "whichmodstate") || - istreq(field, "whichmodifierstate")) { - unsigned int mask; - - if (arrayNdx) - return ReportLedNotArray(info, ledi, field); - - if (!ExprResolveMask(info->ctx, value, &mask, - modComponentMaskNames)) - return ReportLedBadType(info, ledi, field, - "mask of modifier state components"); - - ledi->led.which_mods = mask; - } - else if (istreq(field, "whichgroupstate")) { - unsigned mask; - - if (arrayNdx) - return ReportLedNotArray(info, ledi, field); - - if (!ExprResolveMask(info->ctx, value, &mask, - groupComponentMaskNames)) - return ReportLedBadType(info, ledi, field, - "mask of group state components"); - - ledi->led.which_groups = mask; - } - else if (istreq(field, "driveskbd") || - istreq(field, "driveskeyboard") || - istreq(field, "leddriveskbd") || - istreq(field, "leddriveskeyboard") || - istreq(field, "indicatordriveskbd") || - istreq(field, "indicatordriveskeyboard")) { - log_dbg(info->ctx, - "The \"%s\" field in indicator statements is unsupported; " - "Ignored\n", field); - } - else if (istreq(field, "index")) { - /* Users should see this, it might cause unexpected behavior. */ - log_err(info->ctx, - "The \"index\" field in indicator statements is unsupported; " - "Ignored\n"); - } - else { - log_err(info->ctx, - "Unknown field %s in map for %s indicator; " - "Definition ignored\n", - field, xkb_atom_text(info->ctx, ledi->led.name)); - ok = false; - } - - return ok; -} - -static bool -HandleGlobalVar(CompatInfo *info, VarDef *stmt) -{ - const char *elem, *field; - ExprDef *ndx; - bool ret; - - if (!ExprResolveLhs(info->ctx, stmt->name, &elem, &field, &ndx)) - ret = false; - else if (elem && istreq(elem, "interpret")) - ret = SetInterpField(info, &info->default_interp, field, ndx, - stmt->value); - else if (elem && istreq(elem, "indicator")) - ret = SetLedMapField(info, &info->default_led, field, ndx, - stmt->value); - else - ret = SetActionField(info->ctx, info->actions, &info->mods, - elem, field, ndx, stmt->value); - return ret; -} - -static bool -HandleInterpBody(CompatInfo *info, VarDef *def, SymInterpInfo *si) -{ - bool ok = true; - const char *elem, *field; - ExprDef *arrayNdx; - - for (; def; def = (VarDef *) def->common.next) { - if (def->name && def->name->expr.op == EXPR_FIELD_REF) { - log_err(info->ctx, - "Cannot set a global default value from within an interpret statement; " - "Move statements to the global file scope\n"); - ok = false; - continue; - } - - ok = ExprResolveLhs(info->ctx, def->name, &elem, &field, &arrayNdx); - if (!ok) - continue; - - ok = SetInterpField(info, si, field, arrayNdx, def->value); - } - - return ok; -} - -static bool -HandleInterpDef(CompatInfo *info, InterpDef *def, enum merge_mode merge) -{ - enum xkb_match_operation pred; - xkb_mod_mask_t mods; - SymInterpInfo si; - - if (!ResolveStateAndPredicate(def->match, &pred, &mods, info)) { - log_err(info->ctx, - "Couldn't determine matching modifiers; " - "Symbol interpretation ignored\n"); - return false; - } - - si = info->default_interp; - si.merge = merge = (def->merge == MERGE_DEFAULT ? merge : def->merge); - si.interp.sym = def->sym; - si.interp.match = pred; - si.interp.mods = mods; - - if (!HandleInterpBody(info, def->def, &si)) { - info->errorCount++; - return false; - } - - if (!AddInterp(info, &si, true)) { - info->errorCount++; - return false; - } - - return true; -} - -static bool -HandleLedMapDef(CompatInfo *info, LedMapDef *def, enum merge_mode merge) -{ - LedInfo ledi; - VarDef *var; - bool ok; - - if (def->merge != MERGE_DEFAULT) - merge = def->merge; - - ledi = info->default_led; - ledi.merge = merge; - ledi.led.name = def->name; - - ok = true; - for (var = def->body; var != NULL; var = (VarDef *) var->common.next) { - const char *elem, *field; - ExprDef *arrayNdx; - if (!ExprResolveLhs(info->ctx, var->name, &elem, &field, &arrayNdx)) { - ok = false; - continue; - } - - if (elem) { - log_err(info->ctx, - "Cannot set defaults for \"%s\" element in indicator map; " - "Assignment to %s.%s ignored\n", elem, elem, field); - ok = false; - } - else { - ok = SetLedMapField(info, &ledi, field, arrayNdx, var->value) && ok; - } - } - - if (ok) - return AddLedMap(info, &ledi, true); - - return false; -} - -static void -HandleCompatMapFile(CompatInfo *info, XkbFile *file, enum merge_mode merge) -{ - bool ok; - - merge = (merge == MERGE_DEFAULT ? MERGE_AUGMENT : merge); - - free(info->name); - info->name = strdup_safe(file->name); - - for (ParseCommon *stmt = file->defs; stmt; stmt = stmt->next) { - switch (stmt->type) { - case STMT_INCLUDE: - ok = HandleIncludeCompatMap(info, (IncludeStmt *) stmt); - break; - case STMT_INTERP: - ok = HandleInterpDef(info, (InterpDef *) stmt, merge); - break; - case STMT_GROUP_COMPAT: - log_dbg(info->ctx, - "The \"group\" statement in compat is unsupported; " - "Ignored\n"); - ok = true; - break; - case STMT_LED_MAP: - ok = HandleLedMapDef(info, (LedMapDef *) stmt, merge); - break; - case STMT_VAR: - ok = HandleGlobalVar(info, (VarDef *) stmt); - break; - case STMT_VMOD: - ok = HandleVModDef(info->ctx, &info->mods, (VModDef *) stmt, merge); - break; - default: - log_err(info->ctx, - "Compat files may not include other types; " - "Ignoring %s\n", stmt_type_to_string(stmt->type)); - ok = false; - break; - } - - if (!ok) - info->errorCount++; - - if (info->errorCount > 10) { - log_err(info->ctx, - "Abandoning compatibility map \"%s\"\n", file->name); - break; - } - } -} - -/* Temporary struct for CopyInterps. */ -struct collect { - darray(struct xkb_sym_interpret) sym_interprets; -}; - -static void -CopyInterps(CompatInfo *info, bool needSymbol, enum xkb_match_operation pred, - struct collect *collect) -{ - SymInterpInfo *si; - - darray_foreach(si, info->interps) - if (si->interp.match == pred && - (si->interp.sym != XKB_KEY_NoSymbol) == needSymbol) - darray_append(collect->sym_interprets, si->interp); -} - -static void -CopyLedMapDefsToKeymap(struct xkb_keymap *keymap, CompatInfo *info) -{ - for (xkb_led_index_t idx = 0; idx < info->num_leds; idx++) { - LedInfo *ledi = &info->leds[idx]; - xkb_led_index_t i; - struct xkb_led *led; - - /* - * Find the LED with the given name, if it was already declared - * in keycodes. - */ - xkb_leds_enumerate(i, led, keymap) - if (led->name == ledi->led.name) - break; - - /* Not previously declared; create it with next free index. */ - if (i >= keymap->num_leds) { - log_dbg(keymap->ctx, - "Indicator name \"%s\" was not declared in the keycodes section; " - "Adding new indicator\n", - xkb_atom_text(keymap->ctx, ledi->led.name)); - - xkb_leds_enumerate(i, led, keymap) - if (led->name == XKB_ATOM_NONE) - break; - - if (i >= keymap->num_leds) { - /* Not place to put it; ignore. */ - if (i >= XKB_MAX_LEDS) { - log_err(keymap->ctx, - "Too many indicators (maximum is %d); " - "Indicator name \"%s\" ignored\n", - XKB_MAX_LEDS, - xkb_atom_text(keymap->ctx, ledi->led.name)); - continue; - } - - /* Add a new LED. */ - led = &keymap->leds[keymap->num_leds++]; - } - } - - *led = ledi->led; - if (led->groups != 0 && led->which_groups == 0) - led->which_groups = XKB_STATE_LAYOUT_EFFECTIVE; - if (led->mods.mods != 0 && led->which_mods == 0) - led->which_mods = XKB_STATE_MODS_EFFECTIVE; - } -} - -static bool -CopyCompatToKeymap(struct xkb_keymap *keymap, CompatInfo *info) -{ - keymap->compat_section_name = strdup_safe(info->name); - XkbEscapeMapName(keymap->compat_section_name); - - keymap->mods = info->mods; - - if (!darray_empty(info->interps)) { - struct collect collect; - darray_init(collect.sym_interprets); - - /* Most specific to least specific. */ - CopyInterps(info, true, MATCH_EXACTLY, &collect); - CopyInterps(info, true, MATCH_ALL, &collect); - CopyInterps(info, true, MATCH_NONE, &collect); - CopyInterps(info, true, MATCH_ANY, &collect); - CopyInterps(info, true, MATCH_ANY_OR_NONE, &collect); - CopyInterps(info, false, MATCH_EXACTLY, &collect); - CopyInterps(info, false, MATCH_ALL, &collect); - CopyInterps(info, false, MATCH_NONE, &collect); - CopyInterps(info, false, MATCH_ANY, &collect); - CopyInterps(info, false, MATCH_ANY_OR_NONE, &collect); - - darray_steal(collect.sym_interprets, - &keymap->sym_interprets, &keymap->num_sym_interprets); - } - - CopyLedMapDefsToKeymap(keymap, info); - - return true; -} - -bool -CompileCompatMap(XkbFile *file, struct xkb_keymap *keymap, - enum merge_mode merge) -{ - CompatInfo info; - ActionsInfo *actions; - - actions = NewActionsInfo(); - if (!actions) - return false; - - InitCompatInfo(&info, keymap->ctx, actions, &keymap->mods); - info.default_interp.merge = merge; - info.default_led.merge = merge; - - HandleCompatMapFile(&info, file, merge); - if (info.errorCount != 0) - goto err_info; - - if (!CopyCompatToKeymap(keymap, &info)) - goto err_info; - - ClearCompatInfo(&info); - FreeActionsInfo(actions); - return true; - -err_info: - ClearCompatInfo(&info); - FreeActionsInfo(actions); - return false; -} diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/expr.c b/src/3rdparty/xkbcommon/src/xkbcomp/expr.c deleted file mode 100644 index b2567de3eb..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/expr.c +++ /dev/null @@ -1,686 +0,0 @@ -/************************************************************ - * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting - * documentation, and that the name of Silicon Graphics not be - * used in advertising or publicity pertaining to distribution - * of the software without specific prior written permission. - * Silicon Graphics makes no representation about the suitability - * of this software for any purpose. It is provided "as is" - * without any express or implied warranty. - * - * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - * THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - ********************************************************/ - -#include "xkbcomp-priv.h" -#include "text.h" -#include "expr.h" - -typedef bool (*IdentLookupFunc)(struct xkb_context *ctx, const void *priv, - xkb_atom_t field, enum expr_value_type type, - unsigned int *val_rtrn); - -bool -ExprResolveLhs(struct xkb_context *ctx, const ExprDef *expr, - const char **elem_rtrn, const char **field_rtrn, - ExprDef **index_rtrn) -{ - switch (expr->expr.op) { - case EXPR_IDENT: - *elem_rtrn = NULL; - *field_rtrn = xkb_atom_text(ctx, expr->ident.ident); - *index_rtrn = NULL; - return (*field_rtrn != NULL); - case EXPR_FIELD_REF: - *elem_rtrn = xkb_atom_text(ctx, expr->field_ref.element); - *field_rtrn = xkb_atom_text(ctx, expr->field_ref.field); - *index_rtrn = NULL; - return (*elem_rtrn != NULL && *field_rtrn != NULL); - case EXPR_ARRAY_REF: - *elem_rtrn = xkb_atom_text(ctx, expr->array_ref.element); - *field_rtrn = xkb_atom_text(ctx, expr->array_ref.field); - *index_rtrn = expr->array_ref.entry; - if (expr->array_ref.element != XKB_ATOM_NONE && *elem_rtrn == NULL) - return false; - if (*field_rtrn == NULL) - return false; - return true; - default: - break; - } - log_wsgo(ctx, "Unexpected operator %d in ResolveLhs\n", expr->expr.op); - return false; -} - -static bool -SimpleLookup(struct xkb_context *ctx, const void *priv, xkb_atom_t field, - enum expr_value_type type, unsigned int *val_rtrn) -{ - const LookupEntry *entry; - const char *str; - - if (!priv || field == XKB_ATOM_NONE || type != EXPR_TYPE_INT) - return false; - - str = xkb_atom_text(ctx, field); - for (entry = priv; entry && entry->name; entry++) { - if (istreq(str, entry->name)) { - *val_rtrn = entry->value; - return true; - } - } - - return false; -} - -/* Data passed in the *priv argument for LookupModMask. */ -typedef struct { - const struct xkb_mod_set *mods; - enum mod_type mod_type; -} LookupModMaskPriv; - -static bool -LookupModMask(struct xkb_context *ctx, const void *priv, xkb_atom_t field, - enum expr_value_type type, xkb_mod_mask_t *val_rtrn) -{ - const char *str; - xkb_mod_index_t ndx; - const LookupModMaskPriv *arg = priv; - const struct xkb_mod_set *mods = arg->mods; - enum mod_type mod_type = arg->mod_type; - - if (type != EXPR_TYPE_INT) - return false; - - str = xkb_atom_text(ctx, field); - if (!str) - return false; - - if (istreq(str, "all")) { - *val_rtrn = MOD_REAL_MASK_ALL; - return true; - } - - if (istreq(str, "none")) { - *val_rtrn = 0; - return true; - } - - ndx = XkbModNameToIndex(mods, field, mod_type); - if (ndx == XKB_MOD_INVALID) - return false; - - *val_rtrn = (1u << ndx); - return true; -} - -bool -ExprResolveBoolean(struct xkb_context *ctx, const ExprDef *expr, - bool *set_rtrn) -{ - bool ok = false; - const char *ident; - - switch (expr->expr.op) { - case EXPR_VALUE: - if (expr->expr.value_type != EXPR_TYPE_BOOLEAN) { - log_err(ctx, - "Found constant of type %s where boolean was expected\n", - expr_value_type_to_string(expr->expr.value_type)); - return false; - } - *set_rtrn = expr->boolean.set; - return true; - - case EXPR_IDENT: - ident = xkb_atom_text(ctx, expr->ident.ident); - if (ident) { - if (istreq(ident, "true") || - istreq(ident, "yes") || - istreq(ident, "on")) { - *set_rtrn = true; - return true; - } - else if (istreq(ident, "false") || - istreq(ident, "no") || - istreq(ident, "off")) { - *set_rtrn = false; - return true; - } - } - log_err(ctx, "Identifier \"%s\" of type boolean is unknown\n", ident); - return false; - - case EXPR_FIELD_REF: - log_err(ctx, "Default \"%s.%s\" of type boolean is unknown\n", - xkb_atom_text(ctx, expr->field_ref.element), - xkb_atom_text(ctx, expr->field_ref.field)); - return false; - - case EXPR_INVERT: - case EXPR_NOT: - ok = ExprResolveBoolean(ctx, expr->unary.child, set_rtrn); - if (ok) - *set_rtrn = !*set_rtrn; - return ok; - case EXPR_ADD: - case EXPR_SUBTRACT: - case EXPR_MULTIPLY: - case EXPR_DIVIDE: - case EXPR_ASSIGN: - case EXPR_NEGATE: - case EXPR_UNARY_PLUS: - log_err(ctx, "%s of boolean values not permitted\n", - expr_op_type_to_string(expr->expr.op)); - break; - - default: - log_wsgo(ctx, "Unknown operator %d in ResolveBoolean\n", - expr->expr.op); - break; - } - - return false; -} - -bool -ExprResolveKeyCode(struct xkb_context *ctx, const ExprDef *expr, - xkb_keycode_t *kc) -{ - xkb_keycode_t leftRtrn, rightRtrn; - - switch (expr->expr.op) { - case EXPR_VALUE: - if (expr->expr.value_type != EXPR_TYPE_INT) { - log_err(ctx, - "Found constant of type %s where an int was expected\n", - expr_value_type_to_string(expr->expr.value_type)); - return false; - } - - *kc = (xkb_keycode_t) expr->integer.ival; - return true; - - case EXPR_ADD: - case EXPR_SUBTRACT: - case EXPR_MULTIPLY: - case EXPR_DIVIDE: - if (!ExprResolveKeyCode(ctx, expr->binary.left, &leftRtrn) || - !ExprResolveKeyCode(ctx, expr->binary.right, &rightRtrn)) - return false; - - switch (expr->expr.op) { - case EXPR_ADD: - *kc = leftRtrn + rightRtrn; - break; - case EXPR_SUBTRACT: - *kc = leftRtrn - rightRtrn; - break; - case EXPR_MULTIPLY: - *kc = leftRtrn * rightRtrn; - break; - case EXPR_DIVIDE: - if (rightRtrn == 0) { - log_err(ctx, "Cannot divide by zero: %d / %d\n", - leftRtrn, rightRtrn); - return false; - } - - *kc = leftRtrn / rightRtrn; - break; - default: - break; - } - - return true; - - case EXPR_NEGATE: - if (!ExprResolveKeyCode(ctx, expr->unary.child, &leftRtrn)) - return false; - - *kc = ~leftRtrn; - return true; - - case EXPR_UNARY_PLUS: - return ExprResolveKeyCode(ctx, expr->unary.child, kc); - - default: - log_wsgo(ctx, "Unknown operator %d in ResolveKeyCode\n", - expr->expr.op); - break; - } - - return false; -} - -/** - * This function returns ... something. It's a bit of a guess, really. - * - * If an integer is given in value ctx, it will be returned in ival. - * If an ident or field reference is given, the lookup function (if given) - * will be called. At the moment, only SimpleLookup use this, and they both - * return the results in uval. And don't support field references. - * - * Cool. - */ -static bool -ExprResolveIntegerLookup(struct xkb_context *ctx, const ExprDef *expr, - int *val_rtrn, IdentLookupFunc lookup, - const void *lookupPriv) -{ - bool ok = false; - int l, r; - unsigned u; - ExprDef *left, *right; - - switch (expr->expr.op) { - case EXPR_VALUE: - if (expr->expr.value_type != EXPR_TYPE_INT) { - log_err(ctx, - "Found constant of type %s where an int was expected\n", - expr_value_type_to_string(expr->expr.value_type)); - return false; - } - - *val_rtrn = expr->integer.ival; - return true; - - case EXPR_IDENT: - if (lookup) - ok = lookup(ctx, lookupPriv, expr->ident.ident, EXPR_TYPE_INT, &u); - - if (!ok) - log_err(ctx, "Identifier \"%s\" of type int is unknown\n", - xkb_atom_text(ctx, expr->ident.ident)); - else - *val_rtrn = (int) u; - - return ok; - - case EXPR_FIELD_REF: - log_err(ctx, "Default \"%s.%s\" of type int is unknown\n", - xkb_atom_text(ctx, expr->field_ref.element), - xkb_atom_text(ctx, expr->field_ref.field)); - return false; - - case EXPR_ADD: - case EXPR_SUBTRACT: - case EXPR_MULTIPLY: - case EXPR_DIVIDE: - left = expr->binary.left; - right = expr->binary.right; - if (!ExprResolveIntegerLookup(ctx, left, &l, lookup, lookupPriv) || - !ExprResolveIntegerLookup(ctx, right, &r, lookup, lookupPriv)) - return false; - - switch (expr->expr.op) { - case EXPR_ADD: - *val_rtrn = l + r; - break; - case EXPR_SUBTRACT: - *val_rtrn = l - r; - break; - case EXPR_MULTIPLY: - *val_rtrn = l * r; - break; - case EXPR_DIVIDE: - if (r == 0) { - log_err(ctx, "Cannot divide by zero: %d / %d\n", l, r); - return false; - } - *val_rtrn = l / r; - break; - default: - log_err(ctx, "%s of integers not permitted\n", - expr_op_type_to_string(expr->expr.op)); - return false; - } - - return true; - - case EXPR_ASSIGN: - log_wsgo(ctx, "Assignment operator not implemented yet\n"); - break; - - case EXPR_NOT: - log_err(ctx, "The ! operator cannot be applied to an integer\n"); - return false; - - case EXPR_INVERT: - case EXPR_NEGATE: - left = expr->unary.child; - if (!ExprResolveIntegerLookup(ctx, left, &l, lookup, lookupPriv)) - return false; - - *val_rtrn = (expr->expr.op == EXPR_NEGATE ? -l : ~l); - return true; - - case EXPR_UNARY_PLUS: - left = expr->unary.child; - return ExprResolveIntegerLookup(ctx, left, val_rtrn, lookup, - lookupPriv); - - default: - log_wsgo(ctx, "Unknown operator %d in ResolveInteger\n", - expr->expr.op); - break; - } - - return false; -} - -bool -ExprResolveInteger(struct xkb_context *ctx, const ExprDef *expr, - int *val_rtrn) -{ - return ExprResolveIntegerLookup(ctx, expr, val_rtrn, NULL, NULL); -} - -bool -ExprResolveGroup(struct xkb_context *ctx, const ExprDef *expr, - xkb_layout_index_t *group_rtrn) -{ - bool ok; - int result; - - ok = ExprResolveIntegerLookup(ctx, expr, &result, SimpleLookup, - groupNames); - if (!ok) - return false; - - if (result <= 0 || result > XKB_MAX_GROUPS) { - log_err(ctx, "Group index %u is out of range (1..%d)\n", - result, XKB_MAX_GROUPS); - return false; - } - - *group_rtrn = (xkb_layout_index_t) result; - return true; -} - -bool -ExprResolveLevel(struct xkb_context *ctx, const ExprDef *expr, - xkb_level_index_t *level_rtrn) -{ - bool ok; - int result; - - ok = ExprResolveIntegerLookup(ctx, expr, &result, SimpleLookup, - levelNames); - if (!ok) - return false; - - if (result < 1) { - log_err(ctx, "Shift level %d is out of range\n", result); - return false; - } - - /* Level is zero-indexed from now on. */ - *level_rtrn = (unsigned int) (result - 1); - return true; -} - -bool -ExprResolveButton(struct xkb_context *ctx, const ExprDef *expr, int *btn_rtrn) -{ - return ExprResolveIntegerLookup(ctx, expr, btn_rtrn, SimpleLookup, - buttonNames); -} - -bool -ExprResolveString(struct xkb_context *ctx, const ExprDef *expr, - xkb_atom_t *val_rtrn) -{ - switch (expr->expr.op) { - case EXPR_VALUE: - if (expr->expr.value_type != EXPR_TYPE_STRING) { - log_err(ctx, "Found constant of type %s, expected a string\n", - expr_value_type_to_string(expr->expr.value_type)); - return false; - } - - *val_rtrn = expr->string.str; - return true; - - case EXPR_IDENT: - log_err(ctx, "Identifier \"%s\" of type string not found\n", - xkb_atom_text(ctx, expr->ident.ident)); - return false; - - case EXPR_FIELD_REF: - log_err(ctx, "Default \"%s.%s\" of type string not found\n", - xkb_atom_text(ctx, expr->field_ref.element), - xkb_atom_text(ctx, expr->field_ref.field)); - return false; - - case EXPR_ADD: - case EXPR_SUBTRACT: - case EXPR_MULTIPLY: - case EXPR_DIVIDE: - case EXPR_ASSIGN: - case EXPR_NEGATE: - case EXPR_INVERT: - case EXPR_NOT: - case EXPR_UNARY_PLUS: - log_err(ctx, "%s of strings not permitted\n", - expr_op_type_to_string(expr->expr.op)); - return false; - - default: - log_wsgo(ctx, "Unknown operator %d in ResolveString\n", - expr->expr.op); - break; - } - return false; -} - -bool -ExprResolveEnum(struct xkb_context *ctx, const ExprDef *expr, - unsigned int *val_rtrn, const LookupEntry *values) -{ - if (expr->expr.op != EXPR_IDENT) { - log_err(ctx, "Found a %s where an enumerated value was expected\n", - expr_op_type_to_string(expr->expr.op)); - return false; - } - - if (!SimpleLookup(ctx, values, expr->ident.ident, EXPR_TYPE_INT, - val_rtrn)) { - log_err(ctx, "Illegal identifier %s; expected one of:\n", - xkb_atom_text(ctx, expr->ident.ident)); - while (values && values->name) - { - log_err(ctx, "\t%s\n", values->name); - values++; - } - return false; - } - - return true; -} - -static bool -ExprResolveMaskLookup(struct xkb_context *ctx, const ExprDef *expr, - unsigned int *val_rtrn, IdentLookupFunc lookup, - const void *lookupPriv) -{ - bool ok = false; - unsigned int l = 0, r = 0; - int v; - ExprDef *left, *right; - const char *bogus = NULL; - - switch (expr->expr.op) { - case EXPR_VALUE: - if (expr->expr.value_type != EXPR_TYPE_INT) { - log_err(ctx, - "Found constant of type %s where a mask was expected\n", - expr_value_type_to_string(expr->expr.value_type)); - return false; - } - *val_rtrn = (unsigned int) expr->integer.ival; - return true; - - case EXPR_IDENT: - ok = lookup(ctx, lookupPriv, expr->ident.ident, EXPR_TYPE_INT, - val_rtrn); - if (!ok) - log_err(ctx, "Identifier \"%s\" of type int is unknown\n", - xkb_atom_text(ctx, expr->ident.ident)); - return ok; - - case EXPR_FIELD_REF: - log_err(ctx, "Default \"%s.%s\" of type int is unknown\n", - xkb_atom_text(ctx, expr->field_ref.element), - xkb_atom_text(ctx, expr->field_ref.field)); - return false; - - case EXPR_ARRAY_REF: - bogus = "array reference"; - /* fallthrough */ - case EXPR_ACTION_DECL: - if (bogus == NULL) - bogus = "function use"; - log_err(ctx, - "Unexpected %s in mask expression; Expression Ignored\n", - bogus); - return false; - - case EXPR_ADD: - case EXPR_SUBTRACT: - case EXPR_MULTIPLY: - case EXPR_DIVIDE: - left = expr->binary.left; - right = expr->binary.right; - if (!ExprResolveMaskLookup(ctx, left, &l, lookup, lookupPriv) || - !ExprResolveMaskLookup(ctx, right, &r, lookup, lookupPriv)) - return false; - - switch (expr->expr.op) { - case EXPR_ADD: - *val_rtrn = l | r; - break; - case EXPR_SUBTRACT: - *val_rtrn = l & (~r); - break; - case EXPR_MULTIPLY: - case EXPR_DIVIDE: - log_err(ctx, "Cannot %s masks; Illegal operation ignored\n", - (expr->expr.op == EXPR_DIVIDE ? "divide" : "multiply")); - return false; - default: - break; - } - - return true; - - case EXPR_ASSIGN: - log_wsgo(ctx, "Assignment operator not implemented yet\n"); - break; - - case EXPR_INVERT: - left = expr->unary.child; - if (!ExprResolveIntegerLookup(ctx, left, &v, lookup, lookupPriv)) - return false; - - *val_rtrn = ~v; - return true; - - case EXPR_UNARY_PLUS: - case EXPR_NEGATE: - case EXPR_NOT: - left = expr->unary.child; - if (!ExprResolveIntegerLookup(ctx, left, &v, lookup, lookupPriv)) - log_err(ctx, "The %s operator cannot be used with a mask\n", - (expr->expr.op == EXPR_NEGATE ? "-" : "!")); - return false; - - default: - log_wsgo(ctx, "Unknown operator %d in ResolveMask\n", - expr->expr.op); - break; - } - - return false; -} - -bool -ExprResolveMask(struct xkb_context *ctx, const ExprDef *expr, - unsigned int *mask_rtrn, const LookupEntry *values) -{ - return ExprResolveMaskLookup(ctx, expr, mask_rtrn, SimpleLookup, values); -} - -bool -ExprResolveModMask(struct xkb_context *ctx, const ExprDef *expr, - enum mod_type mod_type, const struct xkb_mod_set *mods, - xkb_mod_mask_t *mask_rtrn) -{ - LookupModMaskPriv priv = { .mods = mods, .mod_type = mod_type }; - return ExprResolveMaskLookup(ctx, expr, mask_rtrn, LookupModMask, &priv); -} - -bool -ExprResolveKeySym(struct xkb_context *ctx, const ExprDef *expr, - xkb_keysym_t *sym_rtrn) -{ - int val; - - if (expr->expr.op == EXPR_IDENT) { - const char *str = xkb_atom_text(ctx, expr->ident.ident); - *sym_rtrn = xkb_keysym_from_name(str, 0); - if (*sym_rtrn != XKB_KEY_NoSymbol) - return true; - } - - if (!ExprResolveInteger(ctx, expr, &val)) - return false; - - if (val < 0 || val >= 10) - return false; - - *sym_rtrn = XKB_KEY_0 + (xkb_keysym_t) val; - return true; -} - -bool -ExprResolveMod(struct xkb_context *ctx, const ExprDef *def, - enum mod_type mod_type, const struct xkb_mod_set *mods, - xkb_mod_index_t *ndx_rtrn) -{ - xkb_mod_index_t ndx; - xkb_atom_t name; - - if (def->expr.op != EXPR_IDENT) { - log_err(ctx, - "Cannot resolve virtual modifier: " - "found %s where a virtual modifier name was expected\n", - expr_op_type_to_string(def->expr.op)); - return false; - } - - name = def->ident.ident; - ndx = XkbModNameToIndex(mods, name, mod_type); - if (ndx == XKB_MOD_INVALID) { - log_err(ctx, - "Cannot resolve virtual modifier: " - "\"%s\" was not previously declared\n", - xkb_atom_text(ctx, name)); - return false; - } - - *ndx_rtrn = ndx; - return true; -} diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/expr.h b/src/3rdparty/xkbcommon/src/xkbcomp/expr.h deleted file mode 100644 index 9882b8cce5..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/expr.h +++ /dev/null @@ -1,85 +0,0 @@ -/************************************************************ - * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting - * documentation, and that the name of Silicon Graphics not be - * used in advertising or publicity pertaining to distribution - * of the software without specific prior written permission. - * Silicon Graphics makes no representation about the suitability - * of this software for any purpose. It is provided "as is" - * without any express or implied warranty. - * - * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - * THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - ********************************************************/ - -#ifndef XKBCOMP_EXPR_H -#define XKBCOMP_EXPR_H - -bool -ExprResolveLhs(struct xkb_context *ctx, const ExprDef *expr, - const char **elem_rtrn, const char **field_rtrn, - ExprDef **index_rtrn); - -bool -ExprResolveModMask(struct xkb_context *ctx, const ExprDef *expr, - enum mod_type mod_type, const struct xkb_mod_set *mods, - xkb_mod_mask_t *mask_rtrn); - -bool -ExprResolveMod(struct xkb_context *ctx, const ExprDef *def, - enum mod_type mod_type, const struct xkb_mod_set *mods, - xkb_mod_index_t *ndx_rtrn); - -bool -ExprResolveBoolean(struct xkb_context *ctx, const ExprDef *expr, - bool *set_rtrn); - -bool -ExprResolveKeyCode(struct xkb_context *ctx, const ExprDef *expr, - xkb_keycode_t *kc); - -bool -ExprResolveInteger(struct xkb_context *ctx, const ExprDef *expr, - int *val_rtrn); - -bool -ExprResolveLevel(struct xkb_context *ctx, const ExprDef *expr, - xkb_level_index_t *level_rtrn); - -bool -ExprResolveGroup(struct xkb_context *ctx, const ExprDef *expr, - xkb_layout_index_t *group_rtrn); - -bool -ExprResolveButton(struct xkb_context *ctx, const ExprDef *expr, - int *btn_rtrn); - -bool -ExprResolveString(struct xkb_context *ctx, const ExprDef *expr, - xkb_atom_t *val_rtrn); - -bool -ExprResolveEnum(struct xkb_context *ctx, const ExprDef *expr, - unsigned int *val_rtrn, const LookupEntry *values); - -bool -ExprResolveMask(struct xkb_context *ctx, const ExprDef *expr, - unsigned int *mask_rtrn, const LookupEntry *values); - -bool -ExprResolveKeySym(struct xkb_context *ctx, const ExprDef *expr, - xkb_keysym_t *sym_rtrn); - -#endif diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/include.c b/src/3rdparty/xkbcommon/src/xkbcomp/include.c deleted file mode 100644 index dc3f1e49bd..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/include.c +++ /dev/null @@ -1,309 +0,0 @@ -/************************************************************ - * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting - * documentation, and that the name of Silicon Graphics not be - * used in advertising or publicity pertaining to distribution - * of the software without specific prior written permission. - * Silicon Graphics makes no representation about the suitability - * of this software for any purpose. It is provided "as is" - * without any express or implied warranty. - * - * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - * THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - ********************************************************/ - -/* - * Copyright © 2012 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include - -#include "xkbcomp-priv.h" -#include "include.h" - -/** - * Parse an include statement. Each call returns a file name, along with - * (possibly) a specific map in the file, an explicit group designator, and - * the separator from the next file, used to determine the merge mode. - * - * @param str_inout Input statement, modified in-place. Should be passed in - * repeatedly. If str_inout is NULL, the parsing has completed. - * - * @param file_rtrn Set to the name of the include file to be used. Combined - * with an enum xkb_file_type, this determines which file to look for in the - * include path. - * - * @param map_rtrn Set to the string between '(' and ')', if any. This will - * result in the compilation of a specific named map within the file (e.g. - * xkb_symbols "basic" { ... }) , as opposed to the default map of the file. - * - * @param nextop_rtrn Set to the next operation in the complete statement, - * which is '\0' if it's the last file or '+' or '|' if there are more. - * Separating the files with '+' sets the merge mode to MERGE_MODE_OVERRIDE, - * while '|' sets the merge mode to MERGE_MODE_AUGMENT. - * - * @param extra_data Set to the string after ':', if any. Currently the - * extra data is only used for setting an explicit group index for a symbols - * file. - * - * @return true if parsing was successful, false for an illegal string. - * - * Example: "evdev+aliases(qwerty):2" - * str_inout = "aliases(qwerty):2" - * file_rtrn = "evdev" - * map_rtrn = NULL - * nextop_retrn = "+" - * extra_data = NULL - * - * 2nd run with "aliases(qwerty):2" - * str_inout = NULL - * file_rtrn = "aliases" - * map_rtrn = "qwerty" - * nextop_retrn = "" - * extra_data = "2" - * - */ -bool -ParseIncludeMap(char **str_inout, char **file_rtrn, char **map_rtrn, - char *nextop_rtrn, char **extra_data) -{ - char *tmp, *str, *next; - - str = *str_inout; - - /* - * Find the position in the string where the next file is included, - * if there is more than one left in the statement. - */ - next = strpbrk(str, "|+"); - if (next) { - /* Got more files, this function will be called again. */ - *nextop_rtrn = *next; - /* Separate the string, for strchr etc. to work on this file only. */ - *next++ = '\0'; - } - else { - /* This is the last file in this statement, won't be called again. */ - *nextop_rtrn = '\0'; - next = NULL; - } - - /* - * Search for the explicit group designator, if any. If it's there, - * it goes after the file name and map. - */ - tmp = strchr(str, ':'); - if (tmp != NULL) { - *tmp++ = '\0'; - *extra_data = strdup(tmp); - } - else { - *extra_data = NULL; - } - - /* Look for a map, if any. */ - tmp = strchr(str, '('); - if (tmp == NULL) { - /* No map. */ - *file_rtrn = strdup(str); - *map_rtrn = NULL; - } - else if (str[0] == '(') { - /* Map without file - invalid. */ - free(*extra_data); - return false; - } - else { - /* Got a map; separate the file and the map for the strdup's. */ - *tmp++ = '\0'; - *file_rtrn = strdup(str); - str = tmp; - tmp = strchr(str, ')'); - if (tmp == NULL || tmp[1] != '\0') { - free(*file_rtrn); - free(*extra_data); - return false; - } - *tmp++ = '\0'; - *map_rtrn = strdup(str); - } - - /* Set up the next file for the next call, if any. */ - if (*nextop_rtrn == '\0') - *str_inout = NULL; - else if (*nextop_rtrn == '|' || *nextop_rtrn == '+') - *str_inout = next; - else - return false; - - return true; -} - -static const char *xkb_file_type_include_dirs[_FILE_TYPE_NUM_ENTRIES] = { - [FILE_TYPE_KEYCODES] = "keycodes", - [FILE_TYPE_TYPES] = "types", - [FILE_TYPE_COMPAT] = "compat", - [FILE_TYPE_SYMBOLS] = "symbols", - [FILE_TYPE_GEOMETRY] = "geometry", - [FILE_TYPE_KEYMAP] = "keymap", - [FILE_TYPE_RULES] = "rules", -}; - -/** - * Return the xkb directory based on the type. - */ -static const char * -DirectoryForInclude(enum xkb_file_type type) -{ - if (type >= _FILE_TYPE_NUM_ENTRIES) - return ""; - return xkb_file_type_include_dirs[type]; -} - -FILE * -FindFileInXkbPath(struct xkb_context *ctx, const char *name, - enum xkb_file_type type, char **pathRtrn) -{ - unsigned int i; - FILE *file = NULL; - char *buf = NULL; - const char *typeDir; - size_t buf_size = 0, typeDirLen, name_len; - - typeDir = DirectoryForInclude(type); - typeDirLen = strlen(typeDir); - name_len = strlen(name); - - for (i = 0; i < xkb_context_num_include_paths(ctx); i++) { - size_t new_buf_size = strlen(xkb_context_include_path_get(ctx, i)) + - typeDirLen + name_len + 3; - int ret; - if (new_buf_size > buf_size) { - void *buf_new = realloc(buf, new_buf_size); - if (buf_new) { - buf_size = new_buf_size; - buf = buf_new; - } else { - log_err(ctx, "Cannot realloc for name (%s/%s/%s)\n", - xkb_context_include_path_get(ctx, i), typeDir, name); - continue; - } - } - ret = snprintf(buf, buf_size, "%s/%s/%s", - xkb_context_include_path_get(ctx, i), - typeDir, name); - if (ret < 0) { - log_err(ctx, "snprintf error (%s/%s/%s)\n", - xkb_context_include_path_get(ctx, i), typeDir, name); - continue; - } - - file = fopen(buf, "r"); - if (file) - break; - } - - if (!file) { - log_err(ctx, "Couldn't find file \"%s/%s\" in include paths\n", - typeDir, name); - - if (xkb_context_num_include_paths(ctx) > 0) { - log_err(ctx, "%d include paths searched:\n", - xkb_context_num_include_paths(ctx)); - for (i = 0; i < xkb_context_num_include_paths(ctx); i++) - log_err(ctx, "\t%s\n", - xkb_context_include_path_get(ctx, i)); - } - else { - log_err(ctx, "There are no include paths to search\n"); - } - - if (xkb_context_num_failed_include_paths(ctx) > 0) { - log_err(ctx, "%d include paths could not be added:\n", - xkb_context_num_failed_include_paths(ctx)); - for (i = 0; i < xkb_context_num_failed_include_paths(ctx); i++) - log_err(ctx, "\t%s\n", - xkb_context_failed_include_path_get(ctx, i)); - } - - free(buf); - return NULL; - } - - if (pathRtrn) - *pathRtrn = buf; - else - free(buf); - return file; -} - -XkbFile * -ProcessIncludeFile(struct xkb_context *ctx, IncludeStmt *stmt, - enum xkb_file_type file_type) -{ - FILE *file; - XkbFile *xkb_file; - - file = FindFileInXkbPath(ctx, stmt->file, file_type, NULL); - if (!file) - return false; - - xkb_file = XkbParseFile(ctx, file, stmt->file, stmt->map); - fclose(file); - if (!xkb_file) { - if (stmt->map) - log_err(ctx, "Couldn't process include statement for '%s(%s)'\n", - stmt->file, stmt->map); - else - log_err(ctx, "Couldn't process include statement for '%s'\n", - stmt->file); - return NULL; - } - - if (xkb_file->file_type != file_type) { - log_err(ctx, - "Include file of wrong type (expected %s, got %s); " - "Include file \"%s\" ignored\n", - xkb_file_type_to_string(file_type), - xkb_file_type_to_string(xkb_file->file_type), stmt->file); - FreeXkbFile(xkb_file); - return NULL; - } - - /* FIXME: we have to check recursive includes here (or somewhere) */ - - return xkb_file; -} diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/include.h b/src/3rdparty/xkbcommon/src/xkbcomp/include.h deleted file mode 100644 index 03e76ed5ce..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/include.h +++ /dev/null @@ -1,42 +0,0 @@ -/************************************************************ - * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting - * documentation, and that the name of Silicon Graphics not be - * used in advertising or publicity pertaining to distribution - * of the software without specific prior written permission. - * Silicon Graphics makes no representation about the suitability - * of this software for any purpose. It is provided "as is" - * without any express or implied warranty. - * - * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - * THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - ********************************************************/ - -#ifndef XKBCOMP_INCLUDE_H -#define XKBCOMP_INCLUDE_H - -bool -ParseIncludeMap(char **str_inout, char **file_rtrn, char **map_rtrn, - char *nextop_rtrn, char **extra_data); - -FILE * -FindFileInXkbPath(struct xkb_context *ctx, const char *name, - enum xkb_file_type type, char **pathRtrn); - -XkbFile * -ProcessIncludeFile(struct xkb_context *ctx, IncludeStmt *stmt, - enum xkb_file_type file_type); - -#endif diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c b/src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c deleted file mode 100644 index 491da51067..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c +++ /dev/null @@ -1,668 +0,0 @@ -/************************************************************ - * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting - * documentation, and that the name of Silicon Graphics not be - * used in advertising or publicity pertaining to distribution - * of the software without specific prior written permission. - * Silicon Graphics makes no representation about the suitability - * of this software for any purpose. It is provided "as is" - * without any express or implied warranty. - * - * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - * THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - ********************************************************/ - -#include "xkbcomp-priv.h" -#include "text.h" -#include "expr.h" -#include "include.h" - -typedef struct { - enum merge_mode merge; - - xkb_atom_t alias; - xkb_atom_t real; -} AliasInfo; - -typedef struct { - enum merge_mode merge; - - xkb_atom_t name; -} LedNameInfo; - -typedef struct { - char *name; - int errorCount; - - xkb_keycode_t min_key_code; - xkb_keycode_t max_key_code; - darray(xkb_atom_t) key_names; - LedNameInfo led_names[XKB_MAX_LEDS]; - unsigned int num_led_names; - darray(AliasInfo) aliases; - - struct xkb_context *ctx; -} KeyNamesInfo; - -/***====================================================================***/ - -static void -InitAliasInfo(AliasInfo *info, enum merge_mode merge, - xkb_atom_t alias, xkb_atom_t real) -{ - memset(info, 0, sizeof(*info)); - info->merge = merge; - info->alias = alias; - info->real = real; -} - -static LedNameInfo * -FindLedByName(KeyNamesInfo *info, xkb_atom_t name, - xkb_led_index_t *idx_out) -{ - for (xkb_led_index_t idx = 0; idx < info->num_led_names; idx++) { - LedNameInfo *ledi = &info->led_names[idx]; - if (ledi->name == name) { - *idx_out = idx; - return ledi; - } - } - - return NULL; -} - -static bool -AddLedName(KeyNamesInfo *info, enum merge_mode merge, bool same_file, - LedNameInfo *new, xkb_led_index_t new_idx) -{ - xkb_led_index_t old_idx; - LedNameInfo *old; - const int verbosity = xkb_context_get_log_verbosity(info->ctx); - const bool report = (same_file && verbosity > 0) || verbosity > 9; - const bool replace = (merge == MERGE_REPLACE || merge == MERGE_OVERRIDE); - - /* LED with the same name already exists. */ - old = FindLedByName(info, new->name, &old_idx); - if (old) { - if (old_idx == new_idx) { - log_warn(info->ctx, - "Multiple indicators named \"%s\"; " - "Identical definitions ignored\n", - xkb_atom_text(info->ctx, new->name)); - return true; - } - - if (report) { - xkb_led_index_t use = (replace ? new_idx + 1 : old_idx + 1); - xkb_led_index_t ignore = (replace ? old_idx + 1 : new_idx + 1); - log_warn(info->ctx, - "Multiple indicators named %s; Using %d, ignoring %d\n", - xkb_atom_text(info->ctx, new->name), use, ignore); - } - - if (replace) - *old = *new; - - return true; - } - - if (new_idx >= info->num_led_names) - info->num_led_names = new_idx + 1; - - /* LED with the same index already exists. */ - old = &info->led_names[new_idx]; - if (old->name != XKB_ATOM_NONE) { - if (report) { - const xkb_atom_t use = (replace ? new->name : old->name); - const xkb_atom_t ignore = (replace ? old->name : new->name); - log_warn(info->ctx, "Multiple names for indicator %d; " - "Using %s, ignoring %s\n", new_idx + 1, - xkb_atom_text(info->ctx, use), - xkb_atom_text(info->ctx, ignore)); - } - - if (replace) - *old = *new; - - return true; - } - - *old = *new; - return true; -} - -static void -ClearKeyNamesInfo(KeyNamesInfo *info) -{ - free(info->name); - darray_free(info->key_names); - darray_free(info->aliases); -} - -static void -InitKeyNamesInfo(KeyNamesInfo *info, struct xkb_context *ctx) -{ - memset(info, 0, sizeof(*info)); - info->ctx = ctx; - info->min_key_code = XKB_KEYCODE_INVALID; -#if XKB_KEYCODE_INVALID < XKB_KEYCODE_MAX -#error "Hey, you can't be changing stuff like that." -#endif -} - -static xkb_keycode_t -FindKeyByName(KeyNamesInfo *info, xkb_atom_t name) -{ - xkb_keycode_t i; - - for (i = info->min_key_code; i <= info->max_key_code; i++) - if (darray_item(info->key_names, i) == name) - return i; - - return XKB_KEYCODE_INVALID; -} - -static bool -AddKeyName(KeyNamesInfo *info, xkb_keycode_t kc, xkb_atom_t name, - enum merge_mode merge, bool same_file, bool report) -{ - xkb_atom_t old_name; - xkb_keycode_t old_kc; - const int verbosity = xkb_context_get_log_verbosity(info->ctx); - - report = report && ((same_file && verbosity > 0) || verbosity > 7); - - if (kc >= darray_size(info->key_names)) - darray_resize0(info->key_names, kc + 1); - - info->min_key_code = MIN(info->min_key_code, kc); - info->max_key_code = MAX(info->max_key_code, kc); - - /* There's already a key with this keycode. */ - old_name = darray_item(info->key_names, kc); - if (old_name != XKB_ATOM_NONE) { - const char *lname = KeyNameText(info->ctx, old_name); - const char *kname = KeyNameText(info->ctx, name); - - if (old_name == name) { - if (report) - log_warn(info->ctx, - "Multiple identical key name definitions; " - "Later occurrences of \"%s = %d\" ignored\n", - lname, kc); - return true; - } - else if (merge == MERGE_AUGMENT) { - if (report) - log_warn(info->ctx, - "Multiple names for keycode %d; " - "Using %s, ignoring %s\n", kc, lname, kname); - return true; - } - else { - if (report) - log_warn(info->ctx, - "Multiple names for keycode %d; " - "Using %s, ignoring %s\n", kc, kname, lname); - darray_item(info->key_names, kc) = XKB_ATOM_NONE; - } - } - - /* There's already a key with this name. */ - old_kc = FindKeyByName(info, name); - if (old_kc != XKB_KEYCODE_INVALID && old_kc != kc) { - const char *kname = KeyNameText(info->ctx, name); - - if (merge == MERGE_OVERRIDE) { - darray_item(info->key_names, old_kc) = XKB_ATOM_NONE; - if (report) - log_warn(info->ctx, - "Key name %s assigned to multiple keys; " - "Using %d, ignoring %d\n", kname, kc, old_kc); - } - else { - if (report) - log_vrb(info->ctx, 3, - "Key name %s assigned to multiple keys; " - "Using %d, ignoring %d\n", kname, old_kc, kc); - return true; - } - } - - darray_item(info->key_names, kc) = name; - return true; -} - -/***====================================================================***/ - -static bool -HandleAliasDef(KeyNamesInfo *info, KeyAliasDef *def, enum merge_mode merge); - -static void -MergeIncludedKeycodes(KeyNamesInfo *into, KeyNamesInfo *from, - enum merge_mode merge) -{ - if (from->errorCount > 0) { - into->errorCount += from->errorCount; - return; - } - - if (into->name == NULL) { - into->name = from->name; - from->name = NULL; - } - - /* Merge key names. */ - if (darray_empty(into->key_names)) { - into->key_names = from->key_names; - darray_init(from->key_names); - into->min_key_code = from->min_key_code; - into->max_key_code = from->max_key_code; - } - else { - if (darray_size(into->key_names) < darray_size(from->key_names)) - darray_resize0(into->key_names, darray_size(from->key_names)); - - for (unsigned i = from->min_key_code; i <= from->max_key_code; i++) { - xkb_atom_t name = darray_item(from->key_names, i); - if (name == XKB_ATOM_NONE) - continue; - - if (!AddKeyName(into, i, name, merge, true, false)) - into->errorCount++; - } - } - - /* Merge key aliases. */ - if (darray_empty(into->aliases)) { - into->aliases = from->aliases; - darray_init(from->aliases); - } - else { - AliasInfo *alias; - - darray_foreach(alias, from->aliases) { - KeyAliasDef def; - - def.merge = (merge == MERGE_DEFAULT ? alias->merge : merge); - def.alias = alias->alias; - def.real = alias->real; - - if (!HandleAliasDef(into, &def, def.merge)) - into->errorCount++; - } - } - - /* Merge LED names. */ - if (into->num_led_names == 0) { - memcpy(into->led_names, from->led_names, - sizeof(*from->led_names) * from->num_led_names); - into->num_led_names = from->num_led_names; - from->num_led_names = 0; - } - else { - for (xkb_led_index_t idx = 0; idx < from->num_led_names; idx++) { - LedNameInfo *ledi = &from->led_names[idx]; - - if (ledi->name == XKB_ATOM_NONE) - continue; - - ledi->merge = (merge == MERGE_DEFAULT ? ledi->merge : merge); - if (!AddLedName(into, ledi->merge, false, ledi, idx)) - into->errorCount++; - } - } -} - -static void -HandleKeycodesFile(KeyNamesInfo *info, XkbFile *file, enum merge_mode merge); - -static bool -HandleIncludeKeycodes(KeyNamesInfo *info, IncludeStmt *include) -{ - KeyNamesInfo included; - - InitKeyNamesInfo(&included, info->ctx); - included.name = include->stmt; - include->stmt = NULL; - - for (IncludeStmt *stmt = include; stmt; stmt = stmt->next_incl) { - KeyNamesInfo next_incl; - XkbFile *file; - - file = ProcessIncludeFile(info->ctx, stmt, FILE_TYPE_KEYCODES); - if (!file) { - info->errorCount += 10; - ClearKeyNamesInfo(&included); - return false; - } - - InitKeyNamesInfo(&next_incl, info->ctx); - - HandleKeycodesFile(&next_incl, file, MERGE_OVERRIDE); - - MergeIncludedKeycodes(&included, &next_incl, stmt->merge); - - ClearKeyNamesInfo(&next_incl); - FreeXkbFile(file); - } - - MergeIncludedKeycodes(info, &included, include->merge); - ClearKeyNamesInfo(&included); - - return (info->errorCount == 0); -} - -static bool -HandleKeycodeDef(KeyNamesInfo *info, KeycodeDef *stmt, enum merge_mode merge) -{ - if (stmt->merge != MERGE_DEFAULT) { - if (stmt->merge == MERGE_REPLACE) - merge = MERGE_OVERRIDE; - else - merge = stmt->merge; - } - - if (stmt->value < 0 || stmt->value > XKB_KEYCODE_MAX) { - log_err(info->ctx, - "Illegal keycode %lld: must be between 0..%u; " - "Key ignored\n", (long long) stmt->value, XKB_KEYCODE_MAX); - return false; - } - - return AddKeyName(info, stmt->value, stmt->name, merge, false, true); -} - -static bool -HandleAliasDef(KeyNamesInfo *info, KeyAliasDef *def, enum merge_mode merge) -{ - AliasInfo *old, new; - - darray_foreach(old, info->aliases) { - if (old->alias == def->alias) { - if (def->real == old->real) { - log_vrb(info->ctx, 1, - "Alias of %s for %s declared more than once; " - "First definition ignored\n", - KeyNameText(info->ctx, def->alias), - KeyNameText(info->ctx, def->real)); - } - else { - xkb_atom_t use, ignore; - - use = (merge == MERGE_AUGMENT ? old->real : def->real); - ignore = (merge == MERGE_AUGMENT ? def->real : old->real); - - log_warn(info->ctx, - "Multiple definitions for alias %s; " - "Using %s, ignoring %s\n", - KeyNameText(info->ctx, old->alias), - KeyNameText(info->ctx, use), - KeyNameText(info->ctx, ignore)); - - old->real = use; - } - - old->merge = merge; - return true; - } - } - - InitAliasInfo(&new, merge, def->alias, def->real); - darray_append(info->aliases, new); - return true; -} - -static bool -HandleKeyNameVar(KeyNamesInfo *info, VarDef *stmt) -{ - const char *elem, *field; - ExprDef *arrayNdx; - - if (!ExprResolveLhs(info->ctx, stmt->name, &elem, &field, &arrayNdx)) - return false; - - if (elem) { - log_err(info->ctx, "Unknown element %s encountered; " - "Default for field %s ignored\n", elem, field); - return false; - } - - if (!istreq(field, "minimum") && !istreq(field, "maximum")) { - log_err(info->ctx, "Unknown field encountered; " - "Assignment to field %s ignored\n", field); - return false; - } - - /* We ignore explicit min/max statements, we always use computed. */ - return true; -} - -static bool -HandleLedNameDef(KeyNamesInfo *info, LedNameDef *def, - enum merge_mode merge) -{ - LedNameInfo ledi; - xkb_atom_t name; - - if (def->ndx < 1 || def->ndx > XKB_MAX_LEDS) { - info->errorCount++; - log_err(info->ctx, - "Illegal indicator index (%d) specified; must be between 1 .. %d; " - "Ignored\n", def->ndx, XKB_MAX_LEDS); - return false; - } - - if (!ExprResolveString(info->ctx, def->name, &name)) { - char buf[20]; - snprintf(buf, sizeof(buf), "%u", def->ndx); - info->errorCount++; - return ReportBadType(info->ctx, "indicator", "name", buf, "string"); - } - - ledi.merge = merge; - ledi.name = name; - return AddLedName(info, merge, true, &ledi, def->ndx - 1); -} - -static void -HandleKeycodesFile(KeyNamesInfo *info, XkbFile *file, enum merge_mode merge) -{ - bool ok; - - free(info->name); - info->name = strdup_safe(file->name); - - for (ParseCommon *stmt = file->defs; stmt; stmt = stmt->next) { - switch (stmt->type) { - case STMT_INCLUDE: - ok = HandleIncludeKeycodes(info, (IncludeStmt *) stmt); - break; - case STMT_KEYCODE: - ok = HandleKeycodeDef(info, (KeycodeDef *) stmt, merge); - break; - case STMT_ALIAS: - ok = HandleAliasDef(info, (KeyAliasDef *) stmt, merge); - break; - case STMT_VAR: - ok = HandleKeyNameVar(info, (VarDef *) stmt); - break; - case STMT_LED_NAME: - ok = HandleLedNameDef(info, (LedNameDef *) stmt, merge); - break; - default: - log_err(info->ctx, - "Keycode files may define key and indicator names only; " - "Ignoring %s\n", stmt_type_to_string(stmt->type)); - ok = false; - break; - } - - if (!ok) - info->errorCount++; - - if (info->errorCount > 10) { - log_err(info->ctx, "Abandoning keycodes file \"%s\"\n", - file->name); - break; - } - } -} - -/***====================================================================***/ - -static bool -CopyKeyNamesToKeymap(struct xkb_keymap *keymap, KeyNamesInfo *info) -{ - struct xkb_key *keys; - xkb_keycode_t min_key_code, max_key_code, kc; - - min_key_code = info->min_key_code; - max_key_code = info->max_key_code; - /* If the keymap has no keys, let's just use the safest pair we know. */ - if (min_key_code == XKB_KEYCODE_INVALID) { - min_key_code = 8; - max_key_code = 255; - } - - keys = calloc(max_key_code + 1, sizeof(*keys)); - if (!keys) - return false; - - for (kc = min_key_code; kc <= max_key_code; kc++) - keys[kc].keycode = kc; - - for (kc = info->min_key_code; kc <= info->max_key_code; kc++) - keys[kc].name = darray_item(info->key_names, kc); - - keymap->min_key_code = min_key_code; - keymap->max_key_code = max_key_code; - keymap->keys = keys; - return true; -} - -static bool -CopyKeyAliasesToKeymap(struct xkb_keymap *keymap, KeyNamesInfo *info) -{ - AliasInfo *alias; - unsigned i, num_key_aliases; - struct xkb_key_alias *key_aliases; - - /* - * Do some sanity checking on the aliases. We can't do it before - * because keys and their aliases may be added out-of-order. - */ - num_key_aliases = 0; - darray_foreach(alias, info->aliases) { - /* Check that ->real is a key. */ - if (!XkbKeyByName(keymap, alias->real, false)) { - log_vrb(info->ctx, 5, - "Attempt to alias %s to non-existent key %s; Ignored\n", - KeyNameText(info->ctx, alias->alias), - KeyNameText(info->ctx, alias->real)); - alias->real = XKB_ATOM_NONE; - continue; - } - - /* Check that ->alias is not a key. */ - if (XkbKeyByName(keymap, alias->alias, false)) { - log_vrb(info->ctx, 5, - "Attempt to create alias with the name of a real key; " - "Alias \"%s = %s\" ignored\n", - KeyNameText(info->ctx, alias->alias), - KeyNameText(info->ctx, alias->real)); - alias->real = XKB_ATOM_NONE; - continue; - } - - num_key_aliases++; - } - - /* Copy key aliases. */ - key_aliases = NULL; - if (num_key_aliases > 0) { - key_aliases = calloc(num_key_aliases, sizeof(*key_aliases)); - if (!key_aliases) - return false; - - i = 0; - darray_foreach(alias, info->aliases) { - if (alias->real != XKB_ATOM_NONE) { - key_aliases[i].alias = alias->alias; - key_aliases[i].real = alias->real; - i++; - } - } - } - - keymap->num_key_aliases = num_key_aliases; - keymap->key_aliases = key_aliases; - return true; -} - -static bool -CopyLedNamesToKeymap(struct xkb_keymap *keymap, KeyNamesInfo *info) -{ - keymap->num_leds = info->num_led_names; - for (xkb_led_index_t idx = 0; idx < info->num_led_names; idx++) { - LedNameInfo *ledi = &info->led_names[idx]; - - if (ledi->name == XKB_ATOM_NONE) - continue; - - keymap->leds[idx].name = ledi->name; - } - - return true; -} - -static bool -CopyKeyNamesInfoToKeymap(struct xkb_keymap *keymap, KeyNamesInfo *info) -{ - /* This function trashes keymap on error, but that's OK. */ - if (!CopyKeyNamesToKeymap(keymap, info) || - !CopyKeyAliasesToKeymap(keymap, info) || - !CopyLedNamesToKeymap(keymap, info)) - return false; - - keymap->keycodes_section_name = strdup_safe(info->name); - XkbEscapeMapName(keymap->keycodes_section_name); - return true; -} - -/***====================================================================***/ - -bool -CompileKeycodes(XkbFile *file, struct xkb_keymap *keymap, - enum merge_mode merge) -{ - KeyNamesInfo info; - - InitKeyNamesInfo(&info, keymap->ctx); - - HandleKeycodesFile(&info, file, merge); - if (info.errorCount != 0) - goto err_info; - - if (!CopyKeyNamesInfoToKeymap(keymap, &info)) - goto err_info; - - ClearKeyNamesInfo(&info); - return true; - -err_info: - ClearKeyNamesInfo(&info); - return false; -} diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c b/src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c deleted file mode 100644 index 2ed591c661..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c +++ /dev/null @@ -1,664 +0,0 @@ -/************************************************************ - * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting - * documentation, and that the name of Silicon Graphics not be - * used in advertising or publicity pertaining to distribution - * of the software without specific prior written permission. - * Silicon Graphics makes no representation about the suitability - * of this software for any purpose. It is provided "as is" - * without any express or implied warranty. - * - * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - * THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - ********************************************************/ - -/* - * Copyright © 2012 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Daniel Stone - */ - -#include "xkbcomp-priv.h" -#include "text.h" - -#define BUF_CHUNK_SIZE 4096 - -struct buf { - char *buf; - size_t size; - size_t alloc; -}; - -static bool -do_realloc(struct buf *buf, size_t at_least) -{ - char *new; - - buf->alloc += BUF_CHUNK_SIZE; - if (at_least >= BUF_CHUNK_SIZE) - buf->alloc += at_least; - - new = realloc(buf->buf, buf->alloc); - if (!new) - return false; - - buf->buf = new; - return true; -} - -ATTR_PRINTF(2, 3) static bool -check_write_buf(struct buf *buf, const char *fmt, ...) -{ - va_list args; - int printed; - size_t available; - - available = buf->alloc - buf->size; - va_start(args, fmt); - printed = vsnprintf(buf->buf + buf->size, available, fmt, args); - va_end(args); - - if (printed < 0) - goto err; - - if ((size_t) printed >= available) - if (!do_realloc(buf, printed)) - goto err; - - /* The buffer has enough space now. */ - - available = buf->alloc - buf->size; - va_start(args, fmt); - printed = vsnprintf(buf->buf + buf->size, available, fmt, args); - va_end(args); - - if (printed < 0 || (size_t) printed >= available) - goto err; - - buf->size += printed; - return true; - -err: - free(buf->buf); - buf->buf = NULL; - return false; -} - -#define write_buf(buf, ...) do { \ - if (!check_write_buf(buf, __VA_ARGS__)) \ - return false; \ -} while (0) - -static bool -write_vmods(struct xkb_keymap *keymap, struct buf *buf) -{ - const struct xkb_mod *mod; - xkb_mod_index_t num_vmods = 0; - - xkb_mods_foreach(mod, &keymap->mods) { - if (mod->type != MOD_VIRT) - continue; - - if (num_vmods == 0) - write_buf(buf, "\tvirtual_modifiers "); - else - write_buf(buf, ","); - write_buf(buf, "%s", xkb_atom_text(keymap->ctx, mod->name)); - num_vmods++; - } - - if (num_vmods > 0) - write_buf(buf, ";\n\n"); - - return true; -} - -static bool -write_keycodes(struct xkb_keymap *keymap, struct buf *buf) -{ - const struct xkb_key *key; - xkb_led_index_t idx; - const struct xkb_led *led; - - if (keymap->keycodes_section_name) - write_buf(buf, "xkb_keycodes \"%s\" {\n", - keymap->keycodes_section_name); - else - write_buf(buf, "xkb_keycodes {\n"); - - /* xkbcomp and X11 really want to see keymaps with a minimum of 8, and - * a maximum of at least 255, else XWayland really starts hating life. - * If this is a problem and people really need strictly bounded keymaps, - * we should probably control this with a flag. */ - write_buf(buf, "\tminimum = %u;\n", min(keymap->min_key_code, 8)); - write_buf(buf, "\tmaximum = %u;\n", max(keymap->max_key_code, 255)); - - xkb_keys_foreach(key, keymap) { - if (key->name == XKB_ATOM_NONE) - continue; - - write_buf(buf, "\t%-20s = %u;\n", - KeyNameText(keymap->ctx, key->name), key->keycode); - } - - xkb_leds_enumerate(idx, led, keymap) - if (led->name != XKB_ATOM_NONE) - write_buf(buf, "\tindicator %u = \"%s\";\n", - idx + 1, xkb_atom_text(keymap->ctx, led->name)); - - - for (unsigned i = 0; i < keymap->num_key_aliases; i++) - write_buf(buf, "\talias %-14s = %s;\n", - KeyNameText(keymap->ctx, keymap->key_aliases[i].alias), - KeyNameText(keymap->ctx, keymap->key_aliases[i].real)); - - write_buf(buf, "};\n\n"); - return true; -} - -static bool -write_types(struct xkb_keymap *keymap, struct buf *buf) -{ - if (keymap->types_section_name) - write_buf(buf, "xkb_types \"%s\" {\n", - keymap->types_section_name); - else - write_buf(buf, "xkb_types {\n"); - - write_vmods(keymap, buf); - - for (unsigned i = 0; i < keymap->num_types; i++) { - const struct xkb_key_type *type = &keymap->types[i]; - - write_buf(buf, "\ttype \"%s\" {\n", - xkb_atom_text(keymap->ctx, type->name)); - - write_buf(buf, "\t\tmodifiers= %s;\n", - ModMaskText(keymap->ctx, &keymap->mods, type->mods.mods)); - - for (unsigned j = 0; j < type->num_entries; j++) { - const char *str; - const struct xkb_key_type_entry *entry = &type->entries[j]; - - /* - * Printing level 1 entries is redundant, it's the default, - * unless there's preserve info. - */ - if (entry->level == 0 && entry->preserve.mods == 0) - continue; - - str = ModMaskText(keymap->ctx, &keymap->mods, entry->mods.mods); - write_buf(buf, "\t\tmap[%s]= Level%u;\n", - str, entry->level + 1); - - if (entry->preserve.mods) - write_buf(buf, "\t\tpreserve[%s]= %s;\n", - str, ModMaskText(keymap->ctx, &keymap->mods, - entry->preserve.mods)); - } - - for (xkb_level_index_t n = 0; n < type->num_level_names; n++) - if (type->level_names[n]) - write_buf(buf, "\t\tlevel_name[Level%u]= \"%s\";\n", n + 1, - xkb_atom_text(keymap->ctx, type->level_names[n])); - - write_buf(buf, "\t};\n"); - } - - write_buf(buf, "};\n\n"); - return true; -} - -static bool -write_led_map(struct xkb_keymap *keymap, struct buf *buf, - const struct xkb_led *led) -{ - write_buf(buf, "\tindicator \"%s\" {\n", - xkb_atom_text(keymap->ctx, led->name)); - - if (led->which_groups) { - if (led->which_groups != XKB_STATE_LAYOUT_EFFECTIVE) { - write_buf(buf, "\t\twhichGroupState= %s;\n", - LedStateMaskText(keymap->ctx, led->which_groups)); - } - write_buf(buf, "\t\tgroups= 0x%02x;\n", - led->groups); - } - - if (led->which_mods) { - if (led->which_mods != XKB_STATE_MODS_EFFECTIVE) { - write_buf(buf, "\t\twhichModState= %s;\n", - LedStateMaskText(keymap->ctx, led->which_mods)); - } - write_buf(buf, "\t\tmodifiers= %s;\n", - ModMaskText(keymap->ctx, &keymap->mods, led->mods.mods)); - } - - if (led->ctrls) { - write_buf(buf, "\t\tcontrols= %s;\n", - ControlMaskText(keymap->ctx, led->ctrls)); - } - - write_buf(buf, "\t};\n"); - return true; -} - -static const char * -affect_lock_text(enum xkb_action_flags flags) -{ - switch (flags & (ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK)) { - case ACTION_LOCK_NO_UNLOCK: - return ",affect=lock"; - case ACTION_LOCK_NO_LOCK: - return ",affect=unlock"; - case ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK: - return ",affect=neither"; - } - return ""; -} - -static bool -write_action(struct xkb_keymap *keymap, struct buf *buf, - const union xkb_action *action, - const char *prefix, const char *suffix) -{ - const char *type; - const char *args = NULL; - - if (!prefix) - prefix = ""; - if (!suffix) - suffix = ""; - - type = ActionTypeText(action->type); - - switch (action->type) { - case ACTION_TYPE_MOD_SET: - case ACTION_TYPE_MOD_LATCH: - case ACTION_TYPE_MOD_LOCK: - if (action->mods.flags & ACTION_MODS_LOOKUP_MODMAP) - args = "modMapMods"; - else - args = ModMaskText(keymap->ctx, &keymap->mods, - action->mods.mods.mods); - write_buf(buf, "%s%s(modifiers=%s%s%s%s)%s", prefix, type, args, - (action->type != ACTION_TYPE_MOD_LOCK && (action->mods.flags & ACTION_LOCK_CLEAR)) ? ",clearLocks" : "", - (action->type != ACTION_TYPE_MOD_LOCK && (action->mods.flags & ACTION_LATCH_TO_LOCK)) ? ",latchToLock" : "", - (action->type == ACTION_TYPE_MOD_LOCK) ? affect_lock_text(action->mods.flags) : "", - suffix); - break; - - case ACTION_TYPE_GROUP_SET: - case ACTION_TYPE_GROUP_LATCH: - case ACTION_TYPE_GROUP_LOCK: - write_buf(buf, "%s%s(group=%s%d%s%s)%s", prefix, type, - (!(action->group.flags & ACTION_ABSOLUTE_SWITCH) && action->group.group > 0) ? "+" : "", - (action->group.flags & ACTION_ABSOLUTE_SWITCH) ? action->group.group + 1 : action->group.group, - (action->type != ACTION_TYPE_GROUP_LOCK && (action->group.flags & ACTION_LOCK_CLEAR)) ? ",clearLocks" : "", - (action->type != ACTION_TYPE_GROUP_LOCK && (action->group.flags & ACTION_LATCH_TO_LOCK)) ? ",latchToLock" : "", - suffix); - break; - - case ACTION_TYPE_TERMINATE: - write_buf(buf, "%s%s()%s", prefix, type, suffix); - break; - - case ACTION_TYPE_PTR_MOVE: - write_buf(buf, "%s%s(x=%s%d,y=%s%d%s)%s", prefix, type, - (!(action->ptr.flags & ACTION_ABSOLUTE_X) && action->ptr.x >= 0) ? "+" : "", - action->ptr.x, - (!(action->ptr.flags & ACTION_ABSOLUTE_Y) && action->ptr.y >= 0) ? "+" : "", - action->ptr.y, - (action->ptr.flags & ACTION_ACCEL) ? "" : ",!accel", - suffix); - break; - - case ACTION_TYPE_PTR_LOCK: - args = affect_lock_text(action->btn.flags); - /* fallthrough */ - case ACTION_TYPE_PTR_BUTTON: - write_buf(buf, "%s%s(button=", prefix, type); - if (action->btn.button > 0 && action->btn.button <= 5) - write_buf(buf, "%d", action->btn.button); - else - write_buf(buf, "default"); - if (action->btn.count) - write_buf(buf, ",count=%d", action->btn.count); - if (args) - write_buf(buf, "%s", args); - write_buf(buf, ")%s", suffix); - break; - - case ACTION_TYPE_PTR_DEFAULT: - write_buf(buf, "%s%s(", prefix, type); - write_buf(buf, "affect=button,button=%s%d", - (!(action->dflt.flags & ACTION_ABSOLUTE_SWITCH) && action->dflt.value >= 0) ? "+" : "", - action->dflt.value); - write_buf(buf, ")%s", suffix); - break; - - case ACTION_TYPE_SWITCH_VT: - write_buf(buf, "%s%s(screen=%s%d,%ssame)%s", prefix, type, - (!(action->screen.flags & ACTION_ABSOLUTE_SWITCH) && action->screen.screen >= 0) ? "+" : "", - action->screen.screen, - (action->screen.flags & ACTION_SAME_SCREEN) ? "" : "!", - suffix); - break; - - case ACTION_TYPE_CTRL_SET: - case ACTION_TYPE_CTRL_LOCK: - write_buf(buf, "%s%s(controls=%s%s)%s", prefix, type, - ControlMaskText(keymap->ctx, action->ctrls.ctrls), - (action->type == ACTION_TYPE_CTRL_LOCK) ? affect_lock_text(action->ctrls.flags) : "", - suffix); - break; - - case ACTION_TYPE_NONE: - write_buf(buf, "%sNoAction()%s", prefix, suffix); - break; - - default: - write_buf(buf, - "%s%s(type=0x%02x,data[0]=0x%02x,data[1]=0x%02x,data[2]=0x%02x,data[3]=0x%02x,data[4]=0x%02x,data[5]=0x%02x,data[6]=0x%02x)%s", - prefix, type, action->type, action->priv.data[0], - action->priv.data[1], action->priv.data[2], - action->priv.data[3], action->priv.data[4], - action->priv.data[5], action->priv.data[6], - suffix); - break; - } - - return true; -} - -static bool -write_compat(struct xkb_keymap *keymap, struct buf *buf) -{ - const struct xkb_led *led; - - if (keymap->compat_section_name) - write_buf(buf, "xkb_compatibility \"%s\" {\n", - keymap->compat_section_name); - else - write_buf(buf, "xkb_compatibility {\n"); - - write_vmods(keymap, buf); - - write_buf(buf, "\tinterpret.useModMapMods= AnyLevel;\n"); - write_buf(buf, "\tinterpret.repeat= False;\n"); - - for (unsigned i = 0; i < keymap->num_sym_interprets; i++) { - const struct xkb_sym_interpret *si = &keymap->sym_interprets[i]; - - write_buf(buf, "\tinterpret %s+%s(%s) {\n", - si->sym ? KeysymText(keymap->ctx, si->sym) : "Any", - SIMatchText(si->match), - ModMaskText(keymap->ctx, &keymap->mods, si->mods)); - - if (si->virtual_mod != XKB_MOD_INVALID) - write_buf(buf, "\t\tvirtualModifier= %s;\n", - ModIndexText(keymap->ctx, &keymap->mods, - si->virtual_mod)); - - if (si->level_one_only) - write_buf(buf, "\t\tuseModMapMods=level1;\n"); - - if (si->repeat) - write_buf(buf, "\t\trepeat= True;\n"); - - write_action(keymap, buf, &si->action, "\t\taction= ", ";\n"); - write_buf(buf, "\t};\n"); - } - - xkb_leds_foreach(led, keymap) - if (led->which_groups || led->groups || led->which_mods || - led->mods.mods || led->ctrls) - write_led_map(keymap, buf, led); - - write_buf(buf, "};\n\n"); - - return true; -} - -static bool -write_keysyms(struct xkb_keymap *keymap, struct buf *buf, - const struct xkb_key *key, xkb_layout_index_t group) -{ - for (xkb_level_index_t level = 0; level < XkbKeyNumLevels(key, group); - level++) { - const xkb_keysym_t *syms; - int num_syms; - - if (level != 0) - write_buf(buf, ", "); - - num_syms = xkb_keymap_key_get_syms_by_level(keymap, key->keycode, - group, level, &syms); - if (num_syms == 0) { - write_buf(buf, "%15s", "NoSymbol"); - } - else if (num_syms == 1) { - write_buf(buf, "%15s", KeysymText(keymap->ctx, syms[0])); - } - else { - write_buf(buf, "{ "); - for (int s = 0; s < num_syms; s++) { - if (s != 0) - write_buf(buf, ", "); - write_buf(buf, "%s", KeysymText(keymap->ctx, syms[s])); - } - write_buf(buf, " }"); - } - } - - return true; -} - -static bool -write_key(struct xkb_keymap *keymap, struct buf *buf, - const struct xkb_key *key) -{ - xkb_layout_index_t group; - bool simple = true; - bool explicit_types = false; - bool multi_type = false; - bool show_actions; - - write_buf(buf, "\tkey %-20s {", KeyNameText(keymap->ctx, key->name)); - - for (group = 0; group < key->num_groups; group++) { - if (key->groups[group].explicit_type) - explicit_types = true; - - if (group != 0 && key->groups[group].type != key->groups[0].type) - multi_type = true; - } - - if (explicit_types) { - const struct xkb_key_type *type; - simple = false; - - if (multi_type) { - for (group = 0; group < key->num_groups; group++) { - if (!key->groups[group].explicit_type) - continue; - - type = key->groups[group].type; - write_buf(buf, "\n\t\ttype[group%u]= \"%s\",", - group + 1, - xkb_atom_text(keymap->ctx, type->name)); - } - } - else { - type = key->groups[0].type; - write_buf(buf, "\n\t\ttype= \"%s\",", - xkb_atom_text(keymap->ctx, type->name)); - } - } - - if (key->explicit & EXPLICIT_REPEAT) { - if (key->repeats) - write_buf(buf, "\n\t\trepeat= Yes,"); - else - write_buf(buf, "\n\t\trepeat= No,"); - simple = false; - } - - if (key->vmodmap && (key->explicit & EXPLICIT_VMODMAP)) - write_buf(buf, "\n\t\tvirtualMods= %s,", - ModMaskText(keymap->ctx, &keymap->mods, key->vmodmap)); - - switch (key->out_of_range_group_action) { - case RANGE_SATURATE: - write_buf(buf, "\n\t\tgroupsClamp,"); - break; - - case RANGE_REDIRECT: - write_buf(buf, "\n\t\tgroupsRedirect= Group%u,", - key->out_of_range_group_number + 1); - break; - - default: - break; - } - - show_actions = (key->explicit & EXPLICIT_INTERP); - - if (key->num_groups > 1 || show_actions) - simple = false; - - if (simple) { - write_buf(buf, "\t[ "); - if (!write_keysyms(keymap, buf, key, 0)) - return false; - write_buf(buf, " ] };\n"); - } - else { - xkb_level_index_t level; - - for (group = 0; group < key->num_groups; group++) { - if (group != 0) - write_buf(buf, ","); - write_buf(buf, "\n\t\tsymbols[Group%u]= [ ", group + 1); - if (!write_keysyms(keymap, buf, key, group)) - return false; - write_buf(buf, " ]"); - if (show_actions) { - write_buf(buf, ",\n\t\tactions[Group%u]= [ ", group + 1); - for (level = 0; level < XkbKeyNumLevels(key, group); level++) { - if (level != 0) - write_buf(buf, ", "); - write_action(keymap, buf, - &key->groups[group].levels[level].action, - NULL, NULL); - } - write_buf(buf, " ]"); - } - } - write_buf(buf, "\n\t};\n"); - } - - return true; -} - -static bool -write_symbols(struct xkb_keymap *keymap, struct buf *buf) -{ - const struct xkb_key *key; - xkb_layout_index_t group; - xkb_mod_index_t i; - const struct xkb_mod *mod; - - if (keymap->symbols_section_name) - write_buf(buf, "xkb_symbols \"%s\" {\n", - keymap->symbols_section_name); - else - write_buf(buf, "xkb_symbols {\n"); - - for (group = 0; group < keymap->num_group_names; group++) - if (keymap->group_names[group]) - write_buf(buf, - "\tname[group%u]=\"%s\";\n", group + 1, - xkb_atom_text(keymap->ctx, keymap->group_names[group])); - if (group > 0) - write_buf(buf, "\n"); - - xkb_keys_foreach(key, keymap) - if (key->num_groups > 0) - write_key(keymap, buf, key); - - xkb_mods_enumerate(i, mod, &keymap->mods) { - bool had_any = false; - xkb_keys_foreach(key, keymap) { - if (key->modmap & (1u << i)) { - if (!had_any) - write_buf(buf, "\tmodifier_map %s { ", - xkb_atom_text(keymap->ctx, mod->name)); - write_buf(buf, "%s%s", - had_any ? ", " : "", - KeyNameText(keymap->ctx, key->name)); - had_any = true; - } - } - if (had_any) - write_buf(buf, " };\n"); - } - - write_buf(buf, "};\n\n"); - return true; -} - -static bool -write_keymap(struct xkb_keymap *keymap, struct buf *buf) -{ - return (check_write_buf(buf, "xkb_keymap {\n") && - write_keycodes(keymap, buf) && - write_types(keymap, buf) && - write_compat(keymap, buf) && - write_symbols(keymap, buf) && - check_write_buf(buf, "};\n")); -} - -char * -text_v1_keymap_get_as_string(struct xkb_keymap *keymap) -{ - struct buf buf = { NULL, 0, 0 }; - - if (!write_keymap(keymap, &buf)) { - free(buf.buf); - return NULL; - } - - return buf.buf; -} diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/keywords.c b/src/3rdparty/xkbcommon/src/xkbcomp/keywords.c deleted file mode 100644 index abab7fe266..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/keywords.c +++ /dev/null @@ -1,348 +0,0 @@ -/* ANSI-C code produced by gperf version 3.0.4 */ -/* Command-line: gperf */ -/* Computed positions: -k'1-2,5' */ - -#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ - && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ - && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ - && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ - && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ - && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ - && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ - && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ - && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ - && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ - && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ - && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ - && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ - && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ - && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ - && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ - && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ - && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ - && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ - && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ - && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ - && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ - && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) -/* The character set is not based on ISO-646. */ -#error "gperf generated tables don't work with this execution character set. Please report a bug to ." -#endif - - -#include "xkbcomp-priv.h" -#include "parser-priv.h" - -static unsigned int -keyword_gperf_hash(const char *str, unsigned int len); - -static const struct keyword_tok * -keyword_gperf_lookup(const char *str, unsigned int len); -struct keyword_tok { int name; int tok; }; -#include -/* maximum key range = 70, duplicates = 0 */ - -#ifndef GPERF_DOWNCASE -#define GPERF_DOWNCASE 1 -static unsigned char gperf_downcase[256] = - { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, - 122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, - 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, - 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, - 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, - 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, - 255 - }; -#endif - -#ifndef GPERF_CASE_STRCMP -#define GPERF_CASE_STRCMP 1 -static int -gperf_case_strcmp (register const char *s1, register const char *s2) -{ - for (;;) - { - unsigned char c1 = gperf_downcase[(unsigned char)*s1++]; - unsigned char c2 = gperf_downcase[(unsigned char)*s2++]; - if (c1 != 0 && c1 == c2) - continue; - return (int)c1 - (int)c2; - } -} -#endif - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static unsigned int -keyword_gperf_hash (register const char *str, register unsigned int len) -{ - static const unsigned char asso_values[] = - { - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 0, 73, 5, 36, 0, - 10, 1, 15, 15, 73, 0, 10, 20, 35, 20, - 50, 73, 10, 10, 5, 0, 15, 73, 0, 15, - 73, 73, 73, 73, 73, 73, 73, 0, 73, 5, - 36, 0, 10, 1, 15, 15, 73, 0, 10, 20, - 35, 20, 50, 73, 10, 10, 5, 0, 15, 73, - 0, 15, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73 - }; - register int hval = len; - - switch (hval) - { - default: - hval += asso_values[(unsigned char)str[4]]; - /*FALLTHROUGH*/ - case 4: - case 3: - case 2: - hval += asso_values[(unsigned char)str[1]]; - /*FALLTHROUGH*/ - case 1: - hval += asso_values[(unsigned char)str[0]]; - break; - } - return hval; -} - -struct stringpool_t - { - char stringpool_str3[sizeof("key")]; - char stringpool_str4[sizeof("keys")]; - char stringpool_str7[sizeof("augment")]; - char stringpool_str9[sizeof("text")]; - char stringpool_str10[sizeof("xkb_keymap")]; - char stringpool_str11[sizeof("keypad_keys")]; - char stringpool_str12[sizeof("xkb_keycodes")]; - char stringpool_str13[sizeof("xkb_geometry")]; - char stringpool_str14[sizeof("xkb_types")]; - char stringpool_str15[sizeof("xkb_compat")]; - char stringpool_str17[sizeof("replace")]; - char stringpool_str19[sizeof("xkb_compat_map")]; - char stringpool_str20[sizeof("xkb_layout")]; - char stringpool_str21[sizeof("xkb_symbols")]; - char stringpool_str22[sizeof("xkb_compatibility")]; - char stringpool_str23[sizeof("xkb_semantics")]; - char stringpool_str24[sizeof("type")]; - char stringpool_str25[sizeof("alias")]; - char stringpool_str26[sizeof("xkb_compatibility_map")]; - char stringpool_str27[sizeof("alphanumeric_keys")]; - char stringpool_str28[sizeof("function_keys")]; - char stringpool_str29[sizeof("alternate")]; - char stringpool_str30[sizeof("shape")]; - char stringpool_str31[sizeof("action")]; - char stringpool_str32[sizeof("section")]; - char stringpool_str33[sizeof("row")]; - char stringpool_str34[sizeof("logo")]; - char stringpool_str35[sizeof("alternate_group")]; - char stringpool_str36[sizeof("hidden")]; - char stringpool_str37[sizeof("virtual")]; - char stringpool_str42[sizeof("outline")]; - char stringpool_str43[sizeof("default")]; - char stringpool_str46[sizeof("modmap")]; - char stringpool_str47[sizeof("virtual_modifiers")]; - char stringpool_str52[sizeof("overlay")]; - char stringpool_str53[sizeof("override")]; - char stringpool_str57[sizeof("include")]; - char stringpool_str62[sizeof("modifier_map")]; - char stringpool_str63[sizeof("modifier_keys")]; - char stringpool_str64[sizeof("indicator")]; - char stringpool_str66[sizeof("group")]; - char stringpool_str67[sizeof("mod_map")]; - char stringpool_str69[sizeof("interpret")]; - char stringpool_str71[sizeof("solid")]; - char stringpool_str72[sizeof("partial")]; - }; -static const struct stringpool_t stringpool_contents = - { - "key", - "keys", - "augment", - "text", - "xkb_keymap", - "keypad_keys", - "xkb_keycodes", - "xkb_geometry", - "xkb_types", - "xkb_compat", - "replace", - "xkb_compat_map", - "xkb_layout", - "xkb_symbols", - "xkb_compatibility", - "xkb_semantics", - "type", - "alias", - "xkb_compatibility_map", - "alphanumeric_keys", - "function_keys", - "alternate", - "shape", - "action", - "section", - "row", - "logo", - "alternate_group", - "hidden", - "virtual", - "outline", - "default", - "modmap", - "virtual_modifiers", - "overlay", - "override", - "include", - "modifier_map", - "modifier_keys", - "indicator", - "group", - "mod_map", - "interpret", - "solid", - "partial" - }; -#define stringpool ((const char *) &stringpool_contents) -#ifdef __GNUC__ -__inline -#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ -__attribute__ ((__gnu_inline__)) -#endif -#endif -const struct keyword_tok * -keyword_gperf_lookup (register const char *str, register unsigned int len) -{ - enum - { - TOTAL_KEYWORDS = 45, - MIN_WORD_LENGTH = 3, - MAX_WORD_LENGTH = 21, - MIN_HASH_VALUE = 3, - MAX_HASH_VALUE = 72 - }; - - static const struct keyword_tok wordlist[] = - { - {-1}, {-1}, {-1}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str3, KEY}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str4, KEYS}, - {-1}, {-1}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str7, AUGMENT}, - {-1}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str9, TEXT}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str10, XKB_KEYMAP}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str11, KEYPAD_KEYS}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str12, XKB_KEYCODES}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str13, XKB_GEOMETRY}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str14, XKB_TYPES}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str15, XKB_COMPATMAP}, - {-1}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str17, REPLACE}, - {-1}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str19, XKB_COMPATMAP}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str20, XKB_LAYOUT}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str21, XKB_SYMBOLS}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str22, XKB_COMPATMAP}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str23, XKB_SEMANTICS}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str24, TYPE}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str25, ALIAS}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str26, XKB_COMPATMAP}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str27, ALPHANUMERIC_KEYS}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str28, FUNCTION_KEYS}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str29, ALTERNATE}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str30, SHAPE}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str31, ACTION_TOK}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str32, SECTION}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str33, ROW}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str34, LOGO}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str35, ALTERNATE_GROUP}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str36, HIDDEN}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str37, VIRTUAL}, - {-1}, {-1}, {-1}, {-1}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str42, OUTLINE}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str43, DEFAULT}, - {-1}, {-1}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str46, MODIFIER_MAP}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str47, VIRTUAL_MODS}, - {-1}, {-1}, {-1}, {-1}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str52, OVERLAY}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str53, OVERRIDE}, - {-1}, {-1}, {-1}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str57, INCLUDE}, - {-1}, {-1}, {-1}, {-1}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str62, MODIFIER_MAP}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str63, MODIFIER_KEYS}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str64, INDICATOR}, - {-1}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str66, GROUP}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str67, MODIFIER_MAP}, - {-1}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str69, INTERPRET}, - {-1}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str71, SOLID}, - {(int)(long)&((struct stringpool_t *)0)->stringpool_str72, PARTIAL} - }; - - if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) - { - register int key = keyword_gperf_hash (str, len); - - if (key <= MAX_HASH_VALUE && key >= 0) - { - register int o = wordlist[key].name; - if (o >= 0) - { - register const char *s = o + stringpool; - - if ((((unsigned char)*str ^ (unsigned char)*s) & ~32) == 0 && !gperf_case_strcmp (str, s)) - return &wordlist[key]; - } - } - } - return 0; -} - - -int -keyword_to_token(const char *string, unsigned int len) -{ - const struct keyword_tok *kt = keyword_gperf_lookup(string, len); - if (!kt) - return -1; - return kt->tok; -} diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h b/src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h deleted file mode 100644 index 76b5047eb6..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h +++ /dev/null @@ -1,44 +0,0 @@ -/************************************************************ - * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting - * documentation, and that the name of Silicon Graphics not be - * used in advertising or publicity pertaining to distribution - * of the software without specific prior written permission. - * Silicon Graphics makes no representation about the suitability - * of this software for any purpose. It is provided "as is" - * without any express or implied warranty. - * - * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - * THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - ********************************************************/ - -#ifndef XKBCOMP_PARSER_PRIV_H -#define XKBCOMP_PARSER_PRIV_H - -struct parser_param; -struct scanner; - -#include "parser.h" - -int -_xkbcommon_lex(YYSTYPE *yylval, struct scanner *scanner); - -XkbFile * -parse(struct xkb_context *ctx, struct scanner *scanner, const char *map); - -int -keyword_to_token(const char *string, unsigned int len); - -#endif diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/parser.h b/src/3rdparty/xkbcommon/src/xkbcomp/parser.h deleted file mode 100644 index 655eca3133..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/parser.h +++ /dev/null @@ -1,157 +0,0 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ - -/* Bison interface for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -#ifndef YY__XKBCOMMON_XKBCOMMON_INTERNAL_STA_PARSER_H_INCLUDED -# define YY__XKBCOMMON_XKBCOMMON_INTERNAL_STA_PARSER_H_INCLUDED -/* Debug traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int _xkbcommon_debug; -#endif - -/* Token type. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - enum yytokentype - { - END_OF_FILE = 0, - ERROR_TOK = 255, - XKB_KEYMAP = 1, - XKB_KEYCODES = 2, - XKB_TYPES = 3, - XKB_SYMBOLS = 4, - XKB_COMPATMAP = 5, - XKB_GEOMETRY = 6, - XKB_SEMANTICS = 7, - XKB_LAYOUT = 8, - INCLUDE = 10, - OVERRIDE = 11, - AUGMENT = 12, - REPLACE = 13, - ALTERNATE = 14, - VIRTUAL_MODS = 20, - TYPE = 21, - INTERPRET = 22, - ACTION_TOK = 23, - KEY = 24, - ALIAS = 25, - GROUP = 26, - MODIFIER_MAP = 27, - INDICATOR = 28, - SHAPE = 29, - KEYS = 30, - ROW = 31, - SECTION = 32, - OVERLAY = 33, - TEXT = 34, - OUTLINE = 35, - SOLID = 36, - LOGO = 37, - VIRTUAL = 38, - EQUALS = 40, - PLUS = 41, - MINUS = 42, - DIVIDE = 43, - TIMES = 44, - OBRACE = 45, - CBRACE = 46, - OPAREN = 47, - CPAREN = 48, - OBRACKET = 49, - CBRACKET = 50, - DOT = 51, - COMMA = 52, - SEMI = 53, - EXCLAM = 54, - INVERT = 55, - STRING = 60, - INTEGER = 61, - FLOAT = 62, - IDENT = 63, - KEYNAME = 64, - PARTIAL = 70, - DEFAULT = 71, - HIDDEN = 72, - ALPHANUMERIC_KEYS = 73, - MODIFIER_KEYS = 74, - KEYPAD_KEYS = 75, - FUNCTION_KEYS = 76, - ALTERNATE_GROUP = 77 - }; -#endif - -/* Value type. */ -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED - -union YYSTYPE -{ -#line 162 "../src/xkbcomp/parser.y" /* yacc.c:1909 */ - - int ival; - int64_t num; - enum xkb_file_type file_type; - char *str; - xkb_atom_t atom; - enum merge_mode merge; - enum xkb_map_flags mapFlags; - xkb_keysym_t keysym; - ParseCommon *any; - ExprDef *expr; - VarDef *var; - VModDef *vmod; - InterpDef *interp; - KeyTypeDef *keyType; - SymbolsDef *syms; - ModMapDef *modMask; - GroupCompatDef *groupCompat; - LedMapDef *ledMap; - LedNameDef *ledName; - KeycodeDef *keyCode; - KeyAliasDef *keyAlias; - void *geom; - XkbFile *file; - -#line 146 "xkbcommon-internal@sta/parser.h" /* yacc.c:1909 */ -}; - -typedef union YYSTYPE YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define YYSTYPE_IS_DECLARED 1 -#endif - - - -int _xkbcommon_parse (struct parser_param *param); - -#endif /* !YY__XKBCOMMON_XKBCOMMON_INTERNAL_STA_PARSER_H_INCLUDED */ diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/rules.c b/src/3rdparty/xkbcommon/src/xkbcomp/rules.c deleted file mode 100644 index 2a364c8aed..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/rules.c +++ /dev/null @@ -1,1037 +0,0 @@ -/************************************************************ - * Copyright (c) 1996 by Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting - * documentation, and that the name of Silicon Graphics not be - * used in advertising or publicity pertaining to distribution - * of the software without specific prior written permission. - * Silicon Graphics makes no representation about the suitability - * of this software for any purpose. It is provided "as is" - * without any express or implied warranty. - * - * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - * THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - ********************************************************/ - -/* - * Copyright © 2012 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "xkbcomp-priv.h" -#include "rules.h" -#include "include.h" -#include "scanner-utils.h" - -/* Scanner / Lexer */ - -/* Values returned with some tokens, like yylval. */ -union lvalue { - struct sval string; -}; - -enum rules_token { - TOK_END_OF_FILE = 0, - TOK_END_OF_LINE, - TOK_IDENTIFIER, - TOK_GROUP_NAME, - TOK_BANG, - TOK_EQUALS, - TOK_STAR, - TOK_ERROR -}; - -static inline bool -is_ident(char ch) -{ - return is_graph(ch) && ch != '\\'; -} - -static enum rules_token -lex(struct scanner *s, union lvalue *val) -{ -skip_more_whitespace_and_comments: - /* Skip spaces. */ - while (chr(s, ' ') || chr(s, '\t')); - - /* Skip comments. */ - if (lit(s, "//")) { - skip_to_eol(s); - } - - /* New line. */ - if (eol(s)) { - while (eol(s)) next(s); - return TOK_END_OF_LINE; - } - - /* Escaped line continuation. */ - if (chr(s, '\\')) { - if (!eol(s)) { - scanner_err(s, "illegal new line escape; must appear at end of line"); - return TOK_ERROR; - } - next(s); - goto skip_more_whitespace_and_comments; - } - - /* See if we're done. */ - if (eof(s)) return TOK_END_OF_FILE; - - /* New token. */ - s->token_line = s->line; - s->token_column = s->column; - - /* Operators and punctuation. */ - if (chr(s, '!')) return TOK_BANG; - if (chr(s, '=')) return TOK_EQUALS; - if (chr(s, '*')) return TOK_STAR; - - /* Group name. */ - if (chr(s, '$')) { - val->string.start = s->s + s->pos; - val->string.len = 0; - while (is_ident(peek(s))) { - next(s); - val->string.len++; - } - if (val->string.len == 0) { - scanner_err(s, "unexpected character after \'$\'; expected name"); - return TOK_ERROR; - } - return TOK_GROUP_NAME; - } - - /* Identifier. */ - if (is_ident(peek(s))) { - val->string.start = s->s + s->pos; - val->string.len = 0; - while (is_ident(peek(s))) { - next(s); - val->string.len++; - } - return TOK_IDENTIFIER; - } - - scanner_err(s, "unrecognized token"); - return TOK_ERROR; -} - -/***====================================================================***/ - -enum rules_mlvo { - MLVO_MODEL, - MLVO_LAYOUT, - MLVO_VARIANT, - MLVO_OPTION, - _MLVO_NUM_ENTRIES -}; - -#define SVAL_LIT(literal) { literal, sizeof(literal) - 1 } - -static const struct sval rules_mlvo_svals[_MLVO_NUM_ENTRIES] = { - [MLVO_MODEL] = SVAL_LIT("model"), - [MLVO_LAYOUT] = SVAL_LIT("layout"), - [MLVO_VARIANT] = SVAL_LIT("variant"), - [MLVO_OPTION] = SVAL_LIT("option"), -}; - -enum rules_kccgst { - KCCGST_KEYCODES, - KCCGST_TYPES, - KCCGST_COMPAT, - KCCGST_SYMBOLS, - KCCGST_GEOMETRY, - _KCCGST_NUM_ENTRIES -}; - -static const struct sval rules_kccgst_svals[_KCCGST_NUM_ENTRIES] = { - [KCCGST_KEYCODES] = SVAL_LIT("keycodes"), - [KCCGST_TYPES] = SVAL_LIT("types"), - [KCCGST_COMPAT] = SVAL_LIT("compat"), - [KCCGST_SYMBOLS] = SVAL_LIT("symbols"), - [KCCGST_GEOMETRY] = SVAL_LIT("geometry"), -}; - -/* We use this to keep score whether an mlvo was matched or not; if not, - * we warn the user that his preference was ignored. */ -struct matched_sval { - struct sval sval; - bool matched; -}; -typedef darray(struct matched_sval) darray_matched_sval; - -/* - * A broken-down version of xkb_rule_names (without the rules, - * obviously). - */ -struct rule_names { - struct matched_sval model; - darray_matched_sval layouts; - darray_matched_sval variants; - darray_matched_sval options; -}; - -struct group { - struct sval name; - darray_sval elements; -}; - -struct mapping { - int mlvo_at_pos[_MLVO_NUM_ENTRIES]; - unsigned int num_mlvo; - unsigned int defined_mlvo_mask; - xkb_layout_index_t layout_idx, variant_idx; - int kccgst_at_pos[_KCCGST_NUM_ENTRIES]; - unsigned int num_kccgst; - unsigned int defined_kccgst_mask; - bool skip; -}; - -enum mlvo_match_type { - MLVO_MATCH_NORMAL = 0, - MLVO_MATCH_WILDCARD, - MLVO_MATCH_GROUP, -}; - -struct rule { - struct sval mlvo_value_at_pos[_MLVO_NUM_ENTRIES]; - enum mlvo_match_type match_type_at_pos[_MLVO_NUM_ENTRIES]; - unsigned int num_mlvo_values; - struct sval kccgst_value_at_pos[_KCCGST_NUM_ENTRIES]; - unsigned int num_kccgst_values; - bool skip; -}; - -/* - * This is the main object used to match a given RMLVO against a rules - * file and aggragate the results in a KcCGST. It goes through a simple - * matching state machine, with tokens as transitions (see - * matcher_match()). - */ -struct matcher { - struct xkb_context *ctx; - /* Input.*/ - struct rule_names rmlvo; - union lvalue val; - struct scanner scanner; - darray(struct group) groups; - /* Current mapping. */ - struct mapping mapping; - /* Current rule. */ - struct rule rule; - /* Output. */ - darray_char kccgst[_KCCGST_NUM_ENTRIES]; -}; - -static struct sval -strip_spaces(struct sval v) -{ - while (v.len > 0 && is_space(v.start[0])) { v.len--; v.start++; } - while (v.len > 0 && is_space(v.start[v.len - 1])) v.len--; - return v; -} - -static darray_matched_sval -split_comma_separated_mlvo(const char *s) -{ - darray_matched_sval arr = darray_new(); - - /* - * Make sure the array returned by this function always includes at - * least one value, e.g. "" -> { "" } and "," -> { "", "" }. - */ - - if (!s) { - struct matched_sval val = { .sval = { NULL, 0 } }; - darray_append(arr, val); - return arr; - } - - while (true) { - struct matched_sval val = { .sval = { s, 0 } }; - while (*s != '\0' && *s != ',') { s++; val.sval.len++; } - val.sval = strip_spaces(val.sval); - darray_append(arr, val); - if (*s == '\0') break; - if (*s == ',') s++; - } - - return arr; -} - -static struct matcher * -matcher_new(struct xkb_context *ctx, - const struct xkb_rule_names *rmlvo) -{ - struct matcher *m = calloc(1, sizeof(*m)); - if (!m) - return NULL; - - m->ctx = ctx; - m->rmlvo.model.sval.start = rmlvo->model; - m->rmlvo.model.sval.len = strlen_safe(rmlvo->model); - m->rmlvo.layouts = split_comma_separated_mlvo(rmlvo->layout); - m->rmlvo.variants = split_comma_separated_mlvo(rmlvo->variant); - m->rmlvo.options = split_comma_separated_mlvo(rmlvo->options); - - return m; -} - -static void -matcher_free(struct matcher *m) -{ - struct group *group; - if (!m) - return; - darray_free(m->rmlvo.layouts); - darray_free(m->rmlvo.variants); - darray_free(m->rmlvo.options); - darray_foreach(group, m->groups) - darray_free(group->elements); - for (int i = 0; i < _KCCGST_NUM_ENTRIES; i++) - darray_free(m->kccgst[i]); - darray_free(m->groups); - free(m); -} - -#define matcher_err(matcher, fmt, ...) \ - scanner_err(&(matcher)->scanner, fmt, ## __VA_ARGS__) - -static void -matcher_group_start_new(struct matcher *m, struct sval name) -{ - struct group group = { .name = name, .elements = darray_new() }; - darray_append(m->groups, group); -} - -static void -matcher_group_add_element(struct matcher *m, struct sval element) -{ - darray_append(darray_item(m->groups, darray_size(m->groups) - 1).elements, - element); -} - -static void -matcher_mapping_start_new(struct matcher *m) -{ - for (unsigned i = 0; i < _MLVO_NUM_ENTRIES; i++) - m->mapping.mlvo_at_pos[i] = -1; - for (unsigned i = 0; i < _KCCGST_NUM_ENTRIES; i++) - m->mapping.kccgst_at_pos[i] = -1; - m->mapping.layout_idx = m->mapping.variant_idx = XKB_LAYOUT_INVALID; - m->mapping.num_mlvo = m->mapping.num_kccgst = 0; - m->mapping.defined_mlvo_mask = 0; - m->mapping.defined_kccgst_mask = 0; - m->mapping.skip = false; -} - -static int -extract_layout_index(const char *s, size_t max_len, xkb_layout_index_t *out) -{ - /* This function is pretty stupid, but works for now. */ - *out = XKB_LAYOUT_INVALID; - if (max_len < 3) - return -1; - if (s[0] != '[' || !is_digit(s[1]) || s[2] != ']') - return -1; - if (s[1] - '0' < 1 || s[1] - '0' > XKB_MAX_GROUPS) - return -1; - /* To zero-based index. */ - *out = s[1] - '0' - 1; - return 3; -} - -static void -matcher_mapping_set_mlvo(struct matcher *m, struct sval ident) -{ - enum rules_mlvo mlvo; - struct sval mlvo_sval; - - for (mlvo = 0; mlvo < _MLVO_NUM_ENTRIES; mlvo++) { - mlvo_sval = rules_mlvo_svals[mlvo]; - - if (svaleq_prefix(mlvo_sval, ident)) - break; - } - - /* Not found. */ - if (mlvo >= _MLVO_NUM_ENTRIES) { - matcher_err(m, "invalid mapping: %.*s is not a valid value here; ignoring rule set", - ident.len, ident.start); - m->mapping.skip = true; - return; - } - - if (m->mapping.defined_mlvo_mask & (1u << mlvo)) { - matcher_err(m, "invalid mapping: %.*s appears twice on the same line; ignoring rule set", - mlvo_sval.len, mlvo_sval.start); - m->mapping.skip = true; - return; - } - - /* If there are leftovers still, it must be an index. */ - if (mlvo_sval.len < ident.len) { - xkb_layout_index_t idx; - int consumed = extract_layout_index(ident.start + mlvo_sval.len, - ident.len - mlvo_sval.len, &idx); - if ((int) (ident.len - mlvo_sval.len) != consumed) { - matcher_err(m, "invalid mapping: \"%.*s\" may only be followed by a valid group index; ignoring rule set", - mlvo_sval.len, mlvo_sval.start); - m->mapping.skip = true; - return; - } - - if (mlvo == MLVO_LAYOUT) { - m->mapping.layout_idx = idx; - } - else if (mlvo == MLVO_VARIANT) { - m->mapping.variant_idx = idx; - } - else { - matcher_err(m, "invalid mapping: \"%.*s\" cannot be followed by a group index; ignoring rule set", - mlvo_sval.len, mlvo_sval.start); - m->mapping.skip = true; - return; - } - } - - m->mapping.mlvo_at_pos[m->mapping.num_mlvo] = mlvo; - m->mapping.defined_mlvo_mask |= 1u << mlvo; - m->mapping.num_mlvo++; -} - -static void -matcher_mapping_set_kccgst(struct matcher *m, struct sval ident) -{ - enum rules_kccgst kccgst; - struct sval kccgst_sval; - - for (kccgst = 0; kccgst < _KCCGST_NUM_ENTRIES; kccgst++) { - kccgst_sval = rules_kccgst_svals[kccgst]; - - if (svaleq(rules_kccgst_svals[kccgst], ident)) - break; - } - - /* Not found. */ - if (kccgst >= _KCCGST_NUM_ENTRIES) { - matcher_err(m, "invalid mapping: %.*s is not a valid value here; ignoring rule set", - ident.len, ident.start); - m->mapping.skip = true; - return; - } - - if (m->mapping.defined_kccgst_mask & (1u << kccgst)) { - matcher_err(m, "invalid mapping: %.*s appears twice on the same line; ignoring rule set", - kccgst_sval.len, kccgst_sval.start); - m->mapping.skip = true; - return; - } - - m->mapping.kccgst_at_pos[m->mapping.num_kccgst] = kccgst; - m->mapping.defined_kccgst_mask |= 1u << kccgst; - m->mapping.num_kccgst++; -} - -static void -matcher_mapping_verify(struct matcher *m) -{ - if (m->mapping.num_mlvo == 0) { - matcher_err(m, "invalid mapping: must have at least one value on the left hand side; ignoring rule set"); - goto skip; - } - - if (m->mapping.num_kccgst == 0) { - matcher_err(m, "invalid mapping: must have at least one value on the right hand side; ignoring rule set"); - goto skip; - } - - /* - * This following is very stupid, but this is how it works. - * See the "Notes" section in the overview above. - */ - - if (m->mapping.defined_mlvo_mask & (1u << MLVO_LAYOUT)) { - if (m->mapping.layout_idx == XKB_LAYOUT_INVALID) { - if (darray_size(m->rmlvo.layouts) > 1) - goto skip; - } - else { - if (darray_size(m->rmlvo.layouts) == 1 || - m->mapping.layout_idx >= darray_size(m->rmlvo.layouts)) - goto skip; - } - } - - if (m->mapping.defined_mlvo_mask & (1u << MLVO_VARIANT)) { - if (m->mapping.variant_idx == XKB_LAYOUT_INVALID) { - if (darray_size(m->rmlvo.variants) > 1) - goto skip; - } - else { - if (darray_size(m->rmlvo.variants) == 1 || - m->mapping.variant_idx >= darray_size(m->rmlvo.variants)) - goto skip; - } - } - - return; - -skip: - m->mapping.skip = true; -} - -static void -matcher_rule_start_new(struct matcher *m) -{ - memset(&m->rule, 0, sizeof(m->rule)); - m->rule.skip = m->mapping.skip; -} - -static void -matcher_rule_set_mlvo_common(struct matcher *m, struct sval ident, - enum mlvo_match_type match_type) -{ - if (m->rule.num_mlvo_values + 1 > m->mapping.num_mlvo) { - matcher_err(m, "invalid rule: has more values than the mapping line; ignoring rule"); - m->rule.skip = true; - return; - } - m->rule.match_type_at_pos[m->rule.num_mlvo_values] = match_type; - m->rule.mlvo_value_at_pos[m->rule.num_mlvo_values] = ident; - m->rule.num_mlvo_values++; -} - -static void -matcher_rule_set_mlvo_wildcard(struct matcher *m) -{ - struct sval dummy = { NULL, 0 }; - matcher_rule_set_mlvo_common(m, dummy, MLVO_MATCH_WILDCARD); -} - -static void -matcher_rule_set_mlvo_group(struct matcher *m, struct sval ident) -{ - matcher_rule_set_mlvo_common(m, ident, MLVO_MATCH_GROUP); -} - -static void -matcher_rule_set_mlvo(struct matcher *m, struct sval ident) -{ - matcher_rule_set_mlvo_common(m, ident, MLVO_MATCH_NORMAL); -} - -static void -matcher_rule_set_kccgst(struct matcher *m, struct sval ident) -{ - if (m->rule.num_kccgst_values + 1 > m->mapping.num_kccgst) { - matcher_err(m, "invalid rule: has more values than the mapping line; ignoring rule"); - m->rule.skip = true; - return; - } - m->rule.kccgst_value_at_pos[m->rule.num_kccgst_values] = ident; - m->rule.num_kccgst_values++; -} - -static bool -match_group(struct matcher *m, struct sval group_name, struct sval to) -{ - struct group *group; - struct sval *element; - bool found = false; - - darray_foreach(group, m->groups) { - if (svaleq(group->name, group_name)) { - found = true; - break; - } - } - - if (!found) { - /* - * rules/evdev intentionally uses some undeclared group names - * in rules (e.g. commented group definitions which may be - * uncommented if needed). So we continue silently. - */ - return false; - } - - darray_foreach(element, group->elements) - if (svaleq(to, *element)) - return true; - - return false; -} - -static bool -match_value(struct matcher *m, struct sval val, struct sval to, - enum mlvo_match_type match_type) -{ - if (match_type == MLVO_MATCH_WILDCARD) - return true; - if (match_type == MLVO_MATCH_GROUP) - return match_group(m, val, to); - return svaleq(val, to); -} - -static bool -match_value_and_mark(struct matcher *m, struct sval val, - struct matched_sval *to, enum mlvo_match_type match_type) -{ - bool matched = match_value(m, val, to->sval, match_type); - if (matched) - to->matched = true; - return matched; -} - -/* - * This function performs %-expansion on @value (see overview above), - * and appends the result to @to. - */ -static bool -append_expanded_kccgst_value(struct matcher *m, darray_char *to, - struct sval value) -{ - const char *s = value.start; - darray_char expanded = darray_new(); - char ch; - bool expanded_plus, to_plus; - - /* - * Some ugly hand-lexing here, but going through the scanner is more - * trouble than it's worth, and the format is ugly on its own merit. - */ - for (unsigned i = 0; i < value.len; ) { - enum rules_mlvo mlv; - xkb_layout_index_t idx; - char pfx, sfx; - struct matched_sval *expanded_value; - - /* Check if that's a start of an expansion. */ - if (s[i] != '%') { - /* Just a normal character. */ - darray_appends_nullterminate(expanded, &s[i++], 1); - continue; - } - if (++i >= value.len) goto error; - - pfx = sfx = 0; - - /* Check for prefix. */ - if (s[i] == '(' || s[i] == '+' || s[i] == '|' || - s[i] == '_' || s[i] == '-') { - pfx = s[i]; - if (s[i] == '(') sfx = ')'; - if (++i >= value.len) goto error; - } - - /* Mandatory model/layout/variant specifier. */ - switch (s[i++]) { - case 'm': mlv = MLVO_MODEL; break; - case 'l': mlv = MLVO_LAYOUT; break; - case 'v': mlv = MLVO_VARIANT; break; - default: goto error; - } - - /* Check for index. */ - idx = XKB_LAYOUT_INVALID; - if (i < value.len && s[i] == '[') { - int consumed; - - if (mlv != MLVO_LAYOUT && mlv != MLVO_VARIANT) { - matcher_err(m, "invalid index in %%-expansion; may only index layout or variant"); - goto error; - } - - consumed = extract_layout_index(s + i, value.len - i, &idx); - if (consumed == -1) goto error; - i += consumed; - } - - /* Check for suffix, if there supposed to be one. */ - if (sfx != 0) { - if (i >= value.len) goto error; - if (s[i++] != sfx) goto error; - } - - /* Get the expanded value. */ - expanded_value = NULL; - - if (mlv == MLVO_LAYOUT) { - if (idx != XKB_LAYOUT_INVALID && - idx < darray_size(m->rmlvo.layouts) && - darray_size(m->rmlvo.layouts) > 1) - expanded_value = &darray_item(m->rmlvo.layouts, idx); - else if (idx == XKB_LAYOUT_INVALID && - darray_size(m->rmlvo.layouts) == 1) - expanded_value = &darray_item(m->rmlvo.layouts, 0); - } - else if (mlv == MLVO_VARIANT) { - if (idx != XKB_LAYOUT_INVALID && - idx < darray_size(m->rmlvo.variants) && - darray_size(m->rmlvo.variants) > 1) - expanded_value = &darray_item(m->rmlvo.variants, idx); - else if (idx == XKB_LAYOUT_INVALID && - darray_size(m->rmlvo.variants) == 1) - expanded_value = &darray_item(m->rmlvo.variants, 0); - } - else if (mlv == MLVO_MODEL) { - expanded_value = &m->rmlvo.model; - } - - /* If we didn't get one, skip silently. */ - if (!expanded_value || expanded_value->sval.len == 0) - continue; - - if (pfx != 0) - darray_appends_nullterminate(expanded, &pfx, 1); - darray_appends_nullterminate(expanded, - expanded_value->sval.start, - expanded_value->sval.len); - if (sfx != 0) - darray_appends_nullterminate(expanded, &sfx, 1); - expanded_value->matched = true; - } - - /* - * Appending bar to foo -> foo (not an error if this happens) - * Appending +bar to foo -> foo+bar - * Appending bar to +foo -> bar+foo - * Appending +bar to +foo -> +foo+bar - */ - - ch = (darray_empty(expanded) ? '\0' : darray_item(expanded, 0)); - expanded_plus = (ch == '+' || ch == '|'); - ch = (darray_empty(*to) ? '\0' : darray_item(*to, 0)); - to_plus = (ch == '+' || ch == '|'); - - if (expanded_plus || darray_empty(*to)) - darray_appends_nullterminate(*to, expanded.item, expanded.size); - else if (to_plus) - darray_prepends_nullterminate(*to, expanded.item, expanded.size); - - darray_free(expanded); - return true; - -error: - darray_free(expanded); - matcher_err(m, "invalid %%-expansion in value; not used"); - return false; -} - -static void -matcher_rule_verify(struct matcher *m) -{ - if (m->rule.num_mlvo_values != m->mapping.num_mlvo || - m->rule.num_kccgst_values != m->mapping.num_kccgst) { - matcher_err(m, "invalid rule: must have same number of values as mapping line; ignoring rule"); - m->rule.skip = true; - } -} - -static void -matcher_rule_apply_if_matches(struct matcher *m) -{ - for (unsigned i = 0; i < m->mapping.num_mlvo; i++) { - enum rules_mlvo mlvo = m->mapping.mlvo_at_pos[i]; - struct sval value = m->rule.mlvo_value_at_pos[i]; - enum mlvo_match_type match_type = m->rule.match_type_at_pos[i]; - struct matched_sval *to; - bool matched = false; - - if (mlvo == MLVO_MODEL) { - to = &m->rmlvo.model; - matched = match_value_and_mark(m, value, to, match_type); - } - else if (mlvo == MLVO_LAYOUT) { - xkb_layout_index_t idx = m->mapping.layout_idx; - idx = (idx == XKB_LAYOUT_INVALID ? 0 : idx); - to = &darray_item(m->rmlvo.layouts, idx); - matched = match_value_and_mark(m, value, to, match_type); - } - else if (mlvo == MLVO_VARIANT) { - xkb_layout_index_t idx = m->mapping.layout_idx; - idx = (idx == XKB_LAYOUT_INVALID ? 0 : idx); - to = &darray_item(m->rmlvo.variants, idx); - matched = match_value_and_mark(m, value, to, match_type); - } - else if (mlvo == MLVO_OPTION) { - darray_foreach(to, m->rmlvo.options) { - matched = match_value_and_mark(m, value, to, match_type); - if (matched) - break; - } - } - - if (!matched) - return; - } - - for (unsigned i = 0; i < m->mapping.num_kccgst; i++) { - enum rules_kccgst kccgst = m->mapping.kccgst_at_pos[i]; - struct sval value = m->rule.kccgst_value_at_pos[i]; - append_expanded_kccgst_value(m, &m->kccgst[kccgst], value); - } - - /* - * If a rule matches in a rule set, the rest of the set should be - * skipped. However, rule sets matching against options may contain - * several legitimate rules, so they are processed entirely. - */ - if (!(m->mapping.defined_mlvo_mask & (1 << MLVO_OPTION))) - m->mapping.skip = true; -} - -static enum rules_token -gettok(struct matcher *m) -{ - return lex(&m->scanner, &m->val); -} - -static bool -matcher_match(struct matcher *m, const char *string, size_t len, - const char *file_name, struct xkb_component_names *out) -{ - enum rules_token tok; - struct matched_sval *mval; - - if (!m) - return false; - - scanner_init(&m->scanner, m->ctx, string, len, file_name, NULL); - -initial: - switch (tok = gettok(m)) { - case TOK_BANG: - goto bang; - case TOK_END_OF_LINE: - goto initial; - case TOK_END_OF_FILE: - goto finish; - default: - goto unexpected; - } - -bang: - switch (tok = gettok(m)) { - case TOK_GROUP_NAME: - matcher_group_start_new(m, m->val.string); - goto group_name; - case TOK_IDENTIFIER: - matcher_mapping_start_new(m); - matcher_mapping_set_mlvo(m, m->val.string); - goto mapping_mlvo; - default: - goto unexpected; - } - -group_name: - switch (tok = gettok(m)) { - case TOK_EQUALS: - goto group_element; - default: - goto unexpected; - } - -group_element: - switch (tok = gettok(m)) { - case TOK_IDENTIFIER: - matcher_group_add_element(m, m->val.string); - goto group_element; - case TOK_END_OF_LINE: - goto initial; - default: - goto unexpected; - } - -mapping_mlvo: - switch (tok = gettok(m)) { - case TOK_IDENTIFIER: - if (!m->mapping.skip) - matcher_mapping_set_mlvo(m, m->val.string); - goto mapping_mlvo; - case TOK_EQUALS: - goto mapping_kccgst; - default: - goto unexpected; - } - -mapping_kccgst: - switch (tok = gettok(m)) { - case TOK_IDENTIFIER: - if (!m->mapping.skip) - matcher_mapping_set_kccgst(m, m->val.string); - goto mapping_kccgst; - case TOK_END_OF_LINE: - if (!m->mapping.skip) - matcher_mapping_verify(m); - goto rule_mlvo_first; - default: - goto unexpected; - } - -rule_mlvo_first: - switch (tok = gettok(m)) { - case TOK_BANG: - goto bang; - case TOK_END_OF_LINE: - goto rule_mlvo_first; - case TOK_END_OF_FILE: - goto finish; - default: - matcher_rule_start_new(m); - goto rule_mlvo_no_tok; - } - -rule_mlvo: - tok = gettok(m); -rule_mlvo_no_tok: - switch (tok) { - case TOK_IDENTIFIER: - if (!m->rule.skip) - matcher_rule_set_mlvo(m, m->val.string); - goto rule_mlvo; - case TOK_STAR: - if (!m->rule.skip) - matcher_rule_set_mlvo_wildcard(m); - goto rule_mlvo; - case TOK_GROUP_NAME: - if (!m->rule.skip) - matcher_rule_set_mlvo_group(m, m->val.string); - goto rule_mlvo; - case TOK_EQUALS: - goto rule_kccgst; - default: - goto unexpected; - } - -rule_kccgst: - switch (tok = gettok(m)) { - case TOK_IDENTIFIER: - if (!m->rule.skip) - matcher_rule_set_kccgst(m, m->val.string); - goto rule_kccgst; - case TOK_END_OF_LINE: - if (!m->rule.skip) - matcher_rule_verify(m); - if (!m->rule.skip) - matcher_rule_apply_if_matches(m); - goto rule_mlvo_first; - default: - goto unexpected; - } - -unexpected: - switch (tok) { - case TOK_ERROR: - goto error; - default: - goto state_error; - } - -finish: - if (darray_empty(m->kccgst[KCCGST_KEYCODES]) || - darray_empty(m->kccgst[KCCGST_TYPES]) || - darray_empty(m->kccgst[KCCGST_COMPAT]) || - /* darray_empty(m->kccgst[KCCGST_GEOMETRY]) || */ - darray_empty(m->kccgst[KCCGST_SYMBOLS])) - goto error; - - darray_steal(m->kccgst[KCCGST_KEYCODES], &out->keycodes, NULL); - darray_steal(m->kccgst[KCCGST_TYPES], &out->types, NULL); - darray_steal(m->kccgst[KCCGST_COMPAT], &out->compat, NULL); - darray_steal(m->kccgst[KCCGST_SYMBOLS], &out->symbols, NULL); - darray_free(m->kccgst[KCCGST_GEOMETRY]); - - - mval = &m->rmlvo.model; - if (!mval->matched && mval->sval.len > 0) - log_err(m->ctx, "Unrecognized RMLVO model \"%.*s\" was ignored\n", - mval->sval.len, mval->sval.start); - darray_foreach(mval, m->rmlvo.layouts) - if (!mval->matched && mval->sval.len > 0) - log_err(m->ctx, "Unrecognized RMLVO layout \"%.*s\" was ignored\n", - mval->sval.len, mval->sval.start); - darray_foreach(mval, m->rmlvo.variants) - if (!mval->matched && mval->sval.len > 0) - log_err(m->ctx, "Unrecognized RMLVO variant \"%.*s\" was ignored\n", - mval->sval.len, mval->sval.start); - darray_foreach(mval, m->rmlvo.options) - if (!mval->matched && mval->sval.len > 0) - log_err(m->ctx, "Unrecognized RMLVO option \"%.*s\" was ignored\n", - mval->sval.len, mval->sval.start); - - return true; - -state_error: - matcher_err(m, "unexpected token"); -error: - return false; -} - -bool -xkb_components_from_rules(struct xkb_context *ctx, - const struct xkb_rule_names *rmlvo, - struct xkb_component_names *out) -{ - bool ret = false; - FILE *file; - char *path; - char *string; - size_t size; - struct matcher *matcher; - - file = FindFileInXkbPath(ctx, rmlvo->rules, FILE_TYPE_RULES, &path); - if (!file) - goto err_out; - - ret = map_file(file, &string, &size); - if (!ret) { - log_err(ctx, "Couldn't read rules file \"%s\": %s\n", - path, strerror(errno)); - goto err_file; - } - - matcher = matcher_new(ctx, rmlvo); - ret = matcher_match(matcher, string, size, path, out); - if (!ret) - log_err(ctx, "No components returned from XKB rules \"%s\"\n", path); - matcher_free(matcher); - - unmap_file(string, size); -err_file: - free(path); - fclose(file); -err_out: - return ret; -} diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/rules.h b/src/3rdparty/xkbcommon/src/xkbcomp/rules.h deleted file mode 100644 index 5381b1562f..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/rules.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright © 2009 Dan Nicholson - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef XKBCOMP_RULES_H -#define XKBCOMP_RULES_H - -bool -xkb_components_from_rules(struct xkb_context *ctx, - const struct xkb_rule_names *rmlvo, - struct xkb_component_names *out); - -#endif diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/scanner.c b/src/3rdparty/xkbcommon/src/xkbcomp/scanner.c deleted file mode 100644 index 1ce6137bf3..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/scanner.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright © 2012 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "xkbcomp-priv.h" -#include "parser-priv.h" -#include "scanner-utils.h" - -static bool -number(struct scanner *s, int64_t *out, int *out_tok) -{ - bool is_float = false, is_hex = false; - const char *start = s->s + s->pos; - char *end; - - if (lit(s, "0x")) { - while (is_xdigit(peek(s))) next(s); - is_hex = true; - } - else { - while (is_digit(peek(s))) next(s); - is_float = chr(s, '.'); - while (is_digit(peek(s))) next(s); - } - if (s->s + s->pos == start) - return false; - - errno = 0; - if (is_hex) - *out = strtoul(start, &end, 16); - else if (is_float) - *out = strtod(start, &end); - else - *out = strtoul(start, &end, 10); - if (errno != 0 || s->s + s->pos != end) - *out_tok = ERROR_TOK; - else - *out_tok = (is_float ? FLOAT : INTEGER); - return true; -} - -int -_xkbcommon_lex(YYSTYPE *yylval, struct scanner *s) -{ - int tok; - -skip_more_whitespace_and_comments: - /* Skip spaces. */ - while (is_space(peek(s))) next(s); - - /* Skip comments. */ - if (lit(s, "//") || chr(s, '#')) { - skip_to_eol(s); - goto skip_more_whitespace_and_comments; - } - - /* See if we're done. */ - if (eof(s)) return END_OF_FILE; - - /* New token. */ - s->token_line = s->line; - s->token_column = s->column; - s->buf_pos = 0; - - /* String literal. */ - if (chr(s, '\"')) { - while (!eof(s) && !eol(s) && peek(s) != '\"') { - if (chr(s, '\\')) { - uint8_t o; - if (chr(s, '\\')) buf_append(s, '\\'); - else if (chr(s, 'n')) buf_append(s, '\n'); - else if (chr(s, 't')) buf_append(s, '\t'); - else if (chr(s, 'r')) buf_append(s, '\r'); - else if (chr(s, 'b')) buf_append(s, '\b'); - else if (chr(s, 'f')) buf_append(s, '\f'); - else if (chr(s, 'v')) buf_append(s, '\v'); - else if (chr(s, 'e')) buf_append(s, '\033'); - else if (oct(s, &o)) buf_append(s, (char) o); - else { - scanner_warn(s, "unknown escape sequence in string literal"); - /* Ignore. */ - } - } else { - buf_append(s, next(s)); - } - } - if (!buf_append(s, '\0') || !chr(s, '\"')) { - scanner_err(s, "unterminated string literal"); - return ERROR_TOK; - } - yylval->str = strdup(s->buf); - if (!yylval->str) - return ERROR_TOK; - return STRING; - } - - /* Key name literal. */ - if (chr(s, '<')) { - while (is_graph(peek(s)) && peek(s) != '>') - buf_append(s, next(s)); - if (!buf_append(s, '\0') || !chr(s, '>')) { - scanner_err(s, "unterminated key name literal"); - return ERROR_TOK; - } - /* Empty key name literals are allowed. */ - yylval->atom = xkb_atom_intern(s->ctx, s->buf, s->buf_pos - 1); - return KEYNAME; - } - - /* Operators and punctuation. */ - if (chr(s, ';')) return SEMI; - if (chr(s, '{')) return OBRACE; - if (chr(s, '}')) return CBRACE; - if (chr(s, '=')) return EQUALS; - if (chr(s, '[')) return OBRACKET; - if (chr(s, ']')) return CBRACKET; - if (chr(s, '(')) return OPAREN; - if (chr(s, ')')) return CPAREN; - if (chr(s, '.')) return DOT; - if (chr(s, ',')) return COMMA; - if (chr(s, '+')) return PLUS; - if (chr(s, '-')) return MINUS; - if (chr(s, '*')) return TIMES; - if (chr(s, '/')) return DIVIDE; - if (chr(s, '!')) return EXCLAM; - if (chr(s, '~')) return INVERT; - - /* Identifier. */ - if (is_alpha(peek(s)) || peek(s) == '_') { - s->buf_pos = 0; - while (is_alnum(peek(s)) || peek(s) == '_') - buf_append(s, next(s)); - if (!buf_append(s, '\0')) { - scanner_err(s, "identifier too long"); - return ERROR_TOK; - } - - /* Keyword. */ - tok = keyword_to_token(s->buf, s->buf_pos - 1); - if (tok != -1) return tok; - - yylval->str = strdup(s->buf); - if (!yylval->str) - return ERROR_TOK; - return IDENT; - } - - /* Number literal (hexadecimal / decimal / float). */ - if (number(s, &yylval->num, &tok)) { - if (tok == ERROR_TOK) { - scanner_err(s, "malformed number literal"); - return ERROR_TOK; - } - return tok; - } - - scanner_err(s, "unrecognized token"); - return ERROR_TOK; -} - -XkbFile * -XkbParseString(struct xkb_context *ctx, const char *string, size_t len, - const char *file_name, const char *map) -{ - struct scanner scanner; - scanner_init(&scanner, ctx, string, len, file_name, NULL); - return parse(ctx, &scanner, map); -} - -XkbFile * -XkbParseFile(struct xkb_context *ctx, FILE *file, - const char *file_name, const char *map) -{ - bool ok; - XkbFile *xkb_file; - char *string; - size_t size; - - ok = map_file(file, &string, &size); - if (!ok) { - log_err(ctx, "Couldn't read XKB file %s: %s\n", - file_name, strerror(errno)); - return NULL; - } - - xkb_file = XkbParseString(ctx, string, size, file_name, map); - unmap_file(string, size); - return xkb_file; -} diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/symbols.c b/src/3rdparty/xkbcommon/src/xkbcomp/symbols.c deleted file mode 100644 index 9b05ec924f..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/symbols.c +++ /dev/null @@ -1,1595 +0,0 @@ -/************************************************************ - * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting - * documentation, and that the name of Silicon Graphics not be - * used in advertising or publicity pertaining to distribution - * of the software without specific prior written permission. - * Silicon Graphics makes no representation about the suitability - * of this software for any purpose. It is provided "as is" - * without any express or implied warranty. - * - * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - * THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - ********************************************************/ - -/* - * Copyright © 2012 Intel Corporation - * Copyright © 2012 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Daniel Stone - * Ran Benita - */ - -#include "xkbcomp-priv.h" -#include "text.h" -#include "expr.h" -#include "action.h" -#include "vmod.h" -#include "include.h" -#include "keysym.h" - -enum key_repeat { - KEY_REPEAT_UNDEFINED = 0, - KEY_REPEAT_YES = 1, - KEY_REPEAT_NO = 2, -}; - -enum group_field { - GROUP_FIELD_SYMS = (1 << 0), - GROUP_FIELD_ACTS = (1 << 1), - GROUP_FIELD_TYPE = (1 << 2), -}; - -enum key_field { - KEY_FIELD_REPEAT = (1 << 0), - KEY_FIELD_DEFAULT_TYPE = (1 << 1), - KEY_FIELD_GROUPINFO = (1 << 2), - KEY_FIELD_VMODMAP = (1 << 3), -}; - -typedef struct { - enum group_field defined; - darray(struct xkb_level) levels; - xkb_atom_t type; -} GroupInfo; - -typedef struct { - enum key_field defined; - enum merge_mode merge; - - xkb_atom_t name; - - darray(GroupInfo) groups; - - enum key_repeat repeat; - xkb_mod_mask_t vmodmap; - xkb_atom_t default_type; - - enum xkb_range_exceed_type out_of_range_group_action; - xkb_layout_index_t out_of_range_group_number; -} KeyInfo; - -static void -ClearLevelInfo(struct xkb_level *leveli) -{ - if (leveli->num_syms > 1) - free(leveli->u.syms); -} - -static void -InitGroupInfo(GroupInfo *groupi) -{ - memset(groupi, 0, sizeof(*groupi)); -} - -static void -ClearGroupInfo(GroupInfo *groupi) -{ - struct xkb_level *leveli; - darray_foreach(leveli, groupi->levels) - ClearLevelInfo(leveli); - darray_free(groupi->levels); -} - -static void -CopyGroupInfo(GroupInfo *to, const GroupInfo *from) -{ - to->defined = from->defined; - to->type = from->type; - darray_init(to->levels); - darray_copy(to->levels, from->levels); - for (xkb_level_index_t j = 0; j < darray_size(to->levels); j++) - if (darray_item(from->levels, j).num_syms > 1) - darray_item(to->levels, j).u.syms = - memdup(darray_item(from->levels, j).u.syms, - darray_item(from->levels, j).num_syms, - sizeof(xkb_keysym_t)); -} - -static void -InitKeyInfo(struct xkb_context *ctx, KeyInfo *keyi) -{ - memset(keyi, 0, sizeof(*keyi)); - keyi->merge = MERGE_OVERRIDE; - keyi->name = xkb_atom_intern_literal(ctx, "*"); - keyi->out_of_range_group_action = RANGE_WRAP; -} - -static void -ClearKeyInfo(KeyInfo *keyi) -{ - GroupInfo *groupi; - darray_foreach(groupi, keyi->groups) - ClearGroupInfo(groupi); - darray_free(keyi->groups); -} - -/***====================================================================***/ - -typedef struct { - enum merge_mode merge; - bool haveSymbol; - xkb_mod_index_t modifier; - union { - xkb_atom_t keyName; - xkb_keysym_t keySym; - } u; -} ModMapEntry; - -typedef struct { - char *name; /* e.g. pc+us+inet(evdev) */ - int errorCount; - enum merge_mode merge; - xkb_layout_index_t explicit_group; - darray(KeyInfo) keys; - KeyInfo default_key; - ActionsInfo *actions; - darray(xkb_atom_t) group_names; - darray(ModMapEntry) modmaps; - struct xkb_mod_set mods; - - struct xkb_context *ctx; - /* Needed for AddKeySymbols. */ - const struct xkb_keymap *keymap; -} SymbolsInfo; - -static void -InitSymbolsInfo(SymbolsInfo *info, const struct xkb_keymap *keymap, - ActionsInfo *actions, const struct xkb_mod_set *mods) -{ - memset(info, 0, sizeof(*info)); - info->ctx = keymap->ctx; - info->keymap = keymap; - info->merge = MERGE_OVERRIDE; - InitKeyInfo(keymap->ctx, &info->default_key); - info->actions = actions; - info->mods = *mods; - info->explicit_group = XKB_LAYOUT_INVALID; -} - -static void -ClearSymbolsInfo(SymbolsInfo *info) -{ - KeyInfo *keyi; - free(info->name); - darray_foreach(keyi, info->keys) - ClearKeyInfo(keyi); - darray_free(info->keys); - darray_free(info->group_names); - darray_free(info->modmaps); - ClearKeyInfo(&info->default_key); -} - -static const char * -KeyInfoText(SymbolsInfo *info, KeyInfo *keyi) -{ - return KeyNameText(info->ctx, keyi->name); -} - -static bool -MergeGroups(SymbolsInfo *info, GroupInfo *into, GroupInfo *from, bool clobber, - bool report, xkb_layout_index_t group, xkb_atom_t key_name) -{ - xkb_level_index_t i, levels_in_both; - struct xkb_level *level; - - /* First find the type of the merged group. */ - if (into->type != from->type) { - if (from->type == XKB_ATOM_NONE) { - } - else if (into->type == XKB_ATOM_NONE) { - into->type = from->type; - } - else { - xkb_atom_t use = (clobber ? from->type : into->type); - xkb_atom_t ignore = (clobber ? into->type : from->type); - - if (report) - log_warn(info->ctx, - "Multiple definitions for group %d type of key %s; " - "Using %s, ignoring %s\n", - group + 1, KeyNameText(info->ctx, key_name), - xkb_atom_text(info->ctx, use), - xkb_atom_text(info->ctx, ignore)); - - into->type = use; - } - } - into->defined |= (from->defined & GROUP_FIELD_TYPE); - - /* Now look at the levels. */ - - if (darray_empty(from->levels)) { - InitGroupInfo(from); - return true; - } - - if (darray_empty(into->levels)) { - from->type = into->type; - *into = *from; - InitGroupInfo(from); - return true; - } - - /* Merge the actions and syms. */ - levels_in_both = MIN(darray_size(into->levels), darray_size(from->levels)); - for (i = 0; i < levels_in_both; i++) { - struct xkb_level *intoLevel = &darray_item(into->levels, i); - struct xkb_level *fromLevel = &darray_item(from->levels, i); - - if (fromLevel->action.type == ACTION_TYPE_NONE) { - } - else if (intoLevel->action.type == ACTION_TYPE_NONE) { - intoLevel->action = fromLevel->action; - } - else { - union xkb_action *use, *ignore; - use = (clobber ? &fromLevel->action : &intoLevel->action); - ignore = (clobber ? &intoLevel->action : &fromLevel->action); - - if (report) - log_warn(info->ctx, - "Multiple actions for level %d/group %u on key %s; " - "Using %s, ignoring %s\n", - i + 1, group + 1, KeyNameText(info->ctx, key_name), - ActionTypeText(use->type), - ActionTypeText(ignore->type)); - - intoLevel->action = *use; - } - - if (fromLevel->num_syms == 0) { - } - else if (intoLevel->num_syms == 0) { - intoLevel->num_syms = fromLevel->num_syms; - if (fromLevel->num_syms > 1) - intoLevel->u.syms = fromLevel->u.syms; - else - intoLevel->u.sym = fromLevel->u.sym; - fromLevel->num_syms = 0; - } - else if (!XkbLevelsSameSyms(fromLevel, intoLevel)) { - if (report) - log_warn(info->ctx, - "Multiple symbols for level %d/group %u on key %s; " - "Using %s, ignoring %s\n", - i + 1, group + 1, KeyNameText(info->ctx, key_name), - (clobber ? "from" : "to"), - (clobber ? "to" : "from")); - - if (clobber) { - ClearLevelInfo(intoLevel); - intoLevel->num_syms = fromLevel->num_syms; - if (fromLevel->num_syms > 1) - intoLevel->u.syms = fromLevel->u.syms; - else - intoLevel->u.sym = fromLevel->u.sym; - fromLevel->num_syms = 0; - } - } - } - /* If @from has extra levels, get them as well. */ - darray_foreach_from(level, from->levels, levels_in_both) { - darray_append(into->levels, *level); - level->num_syms = 0; - } - into->defined |= (from->defined & GROUP_FIELD_ACTS); - into->defined |= (from->defined & GROUP_FIELD_SYMS); - - return true; -} - -static bool -UseNewKeyField(enum key_field field, enum key_field old, enum key_field new, - bool clobber, bool report, enum key_field *collide) -{ - if (!(old & field)) - return (new & field); - - if (new & field) { - if (report) - *collide |= field; - - if (clobber) - return true; - } - - return false; -} - -static bool -MergeKeys(SymbolsInfo *info, KeyInfo *into, KeyInfo *from, bool same_file) -{ - xkb_layout_index_t i; - xkb_layout_index_t groups_in_both; - enum key_field collide = 0; - const int verbosity = xkb_context_get_log_verbosity(info->ctx); - const bool clobber = (from->merge != MERGE_AUGMENT); - const bool report = (same_file && verbosity > 0) || verbosity > 9; - - if (from->merge == MERGE_REPLACE) { - ClearKeyInfo(into); - *into = *from; - InitKeyInfo(info->ctx, from); - return true; - } - - groups_in_both = MIN(darray_size(into->groups), darray_size(from->groups)); - for (i = 0; i < groups_in_both; i++) - MergeGroups(info, - &darray_item(into->groups, i), - &darray_item(from->groups, i), - clobber, report, i, into->name); - /* If @from has extra groups, just move them to @into. */ - for (i = groups_in_both; i < darray_size(from->groups); i++) { - darray_append(into->groups, darray_item(from->groups, i)); - InitGroupInfo(&darray_item(from->groups, i)); - } - - if (UseNewKeyField(KEY_FIELD_VMODMAP, into->defined, from->defined, - clobber, report, &collide)) { - into->vmodmap = from->vmodmap; - into->defined |= KEY_FIELD_VMODMAP; - } - if (UseNewKeyField(KEY_FIELD_REPEAT, into->defined, from->defined, - clobber, report, &collide)) { - into->repeat = from->repeat; - into->defined |= KEY_FIELD_REPEAT; - } - if (UseNewKeyField(KEY_FIELD_DEFAULT_TYPE, into->defined, from->defined, - clobber, report, &collide)) { - into->default_type = from->default_type; - into->defined |= KEY_FIELD_DEFAULT_TYPE; - } - if (UseNewKeyField(KEY_FIELD_GROUPINFO, into->defined, from->defined, - clobber, report, &collide)) { - into->out_of_range_group_action = from->out_of_range_group_action; - into->out_of_range_group_number = from->out_of_range_group_number; - into->defined |= KEY_FIELD_GROUPINFO; - } - - if (collide) - log_warn(info->ctx, - "Symbol map for key %s redefined; " - "Using %s definition for conflicting fields\n", - KeyNameText(info->ctx, into->name), - (clobber ? "first" : "last")); - - ClearKeyInfo(from); - InitKeyInfo(info->ctx, from); - return true; -} - -/* TODO: Make it so this function doesn't need the entire keymap. */ -static bool -AddKeySymbols(SymbolsInfo *info, KeyInfo *keyi, bool same_file) -{ - xkb_atom_t real_name; - KeyInfo *iter; - - /* - * Don't keep aliases in the keys array; this guarantees that - * searching for keys to merge with by straight comparison (see the - * following loop) is enough, and we won't get multiple KeyInfo's - * for the same key because of aliases. - */ - real_name = XkbResolveKeyAlias(info->keymap, keyi->name); - if (real_name != XKB_ATOM_NONE) - keyi->name = real_name; - - darray_foreach(iter, info->keys) - if (iter->name == keyi->name) - return MergeKeys(info, iter, keyi, same_file); - - darray_append(info->keys, *keyi); - InitKeyInfo(info->ctx, keyi); - return true; -} - -static bool -AddModMapEntry(SymbolsInfo *info, ModMapEntry *new) -{ - ModMapEntry *old; - bool clobber = (new->merge != MERGE_AUGMENT); - - darray_foreach(old, info->modmaps) { - xkb_mod_index_t use, ignore; - - if ((new->haveSymbol != old->haveSymbol) || - (new->haveSymbol && new->u.keySym != old->u.keySym) || - (!new->haveSymbol && new->u.keyName != old->u.keyName)) - continue; - - if (new->modifier == old->modifier) - return true; - - use = (clobber ? new->modifier : old->modifier); - ignore = (clobber ? old->modifier : new->modifier); - - if (new->haveSymbol) - log_err(info->ctx, - "Symbol \"%s\" added to modifier map for multiple modifiers; " - "Using %s, ignoring %s\n", - KeysymText(info->ctx, new->u.keySym), - ModIndexText(info->ctx, &info->mods, use), - ModIndexText(info->ctx, &info->mods, ignore)); - else - log_err(info->ctx, - "Key \"%s\" added to modifier map for multiple modifiers; " - "Using %s, ignoring %s\n", - KeyNameText(info->ctx, new->u.keyName), - ModIndexText(info->ctx, &info->mods, use), - ModIndexText(info->ctx, &info->mods, ignore)); - - old->modifier = use; - return true; - } - - darray_append(info->modmaps, *new); - return true; -} - -/***====================================================================***/ - -static void -MergeIncludedSymbols(SymbolsInfo *into, SymbolsInfo *from, - enum merge_mode merge) -{ - xkb_atom_t *group_name; - xkb_layout_index_t group_names_in_both; - - if (from->errorCount > 0) { - into->errorCount += from->errorCount; - return; - } - - into->mods = from->mods; - - if (into->name == NULL) { - into->name = from->name; - from->name = NULL; - } - - group_names_in_both = MIN(darray_size(into->group_names), - darray_size(from->group_names)); - for (xkb_layout_index_t i = 0; i < group_names_in_both; i++) { - if (!darray_item(from->group_names, i)) - continue; - - if (merge == MERGE_AUGMENT && darray_item(into->group_names, i)) - continue; - - darray_item(into->group_names, i) = darray_item(from->group_names, i); - } - /* If @from has more, get them as well. */ - darray_foreach_from(group_name, from->group_names, group_names_in_both) - darray_append(into->group_names, *group_name); - - if (darray_empty(into->keys)) { - into->keys = from->keys; - darray_init(from->keys); - } - else { - KeyInfo *keyi; - darray_foreach(keyi, from->keys) { - keyi->merge = (merge == MERGE_DEFAULT ? keyi->merge : merge); - if (!AddKeySymbols(into, keyi, false)) - into->errorCount++; - } - } - - if (darray_empty(into->modmaps)) { - into->modmaps = from->modmaps; - darray_init(from->modmaps); - } - else { - ModMapEntry *mm; - darray_foreach(mm, from->modmaps) { - mm->merge = (merge == MERGE_DEFAULT ? mm->merge : merge); - if (!AddModMapEntry(into, mm)) - into->errorCount++; - } - } -} - -static void -HandleSymbolsFile(SymbolsInfo *info, XkbFile *file, enum merge_mode merge); - -static bool -HandleIncludeSymbols(SymbolsInfo *info, IncludeStmt *include) -{ - SymbolsInfo included; - - InitSymbolsInfo(&included, info->keymap, info->actions, &info->mods); - included.name = include->stmt; - include->stmt = NULL; - - for (IncludeStmt *stmt = include; stmt; stmt = stmt->next_incl) { - SymbolsInfo next_incl; - XkbFile *file; - - file = ProcessIncludeFile(info->ctx, stmt, FILE_TYPE_SYMBOLS); - if (!file) { - info->errorCount += 10; - ClearSymbolsInfo(&included); - return false; - } - - InitSymbolsInfo(&next_incl, info->keymap, info->actions, - &included.mods); - if (stmt->modifier) { - next_incl.explicit_group = atoi(stmt->modifier) - 1; - if (next_incl.explicit_group >= XKB_MAX_GROUPS) { - log_err(info->ctx, - "Cannot set explicit group to %d - must be between 1..%d; " - "Ignoring group number\n", - next_incl.explicit_group + 1, XKB_MAX_GROUPS); - next_incl.explicit_group = info->explicit_group; - } - } - else { - next_incl.explicit_group = info->explicit_group; - } - - HandleSymbolsFile(&next_incl, file, MERGE_OVERRIDE); - - MergeIncludedSymbols(&included, &next_incl, stmt->merge); - - ClearSymbolsInfo(&next_incl); - FreeXkbFile(file); - } - - MergeIncludedSymbols(info, &included, include->merge); - ClearSymbolsInfo(&included); - - return (info->errorCount == 0); -} - -#define SYMBOLS 1 -#define ACTIONS 2 - -static bool -GetGroupIndex(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx, - unsigned what, xkb_layout_index_t *ndx_rtrn) -{ - const char *name = (what == SYMBOLS ? "symbols" : "actions"); - - if (arrayNdx == NULL) { - xkb_layout_index_t i; - GroupInfo *groupi; - enum group_field field = (what == SYMBOLS ? - GROUP_FIELD_SYMS : GROUP_FIELD_ACTS); - - darray_enumerate(i, groupi, keyi->groups) { - if (!(groupi->defined & field)) { - *ndx_rtrn = i; - return true; - } - } - - if (i >= XKB_MAX_GROUPS) { - log_err(info->ctx, - "Too many groups of %s for key %s (max %u); " - "Ignoring %s defined for extra groups\n", - name, KeyInfoText(info, keyi), XKB_MAX_GROUPS, name); - return false; - } - - darray_resize0(keyi->groups, darray_size(keyi->groups) + 1); - *ndx_rtrn = darray_size(keyi->groups) - 1; - return true; - } - - if (!ExprResolveGroup(info->ctx, arrayNdx, ndx_rtrn)) { - log_err(info->ctx, - "Illegal group index for %s of key %s\n" - "Definition with non-integer array index ignored\n", - name, KeyInfoText(info, keyi)); - return false; - } - - (*ndx_rtrn)--; - if (*ndx_rtrn >= darray_size(keyi->groups)) - darray_resize0(keyi->groups, *ndx_rtrn + 1); - - return true; -} - -static bool -AddSymbolsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx, - ExprDef *value) -{ - xkb_layout_index_t ndx; - GroupInfo *groupi; - xkb_level_index_t nLevels; - - if (!GetGroupIndex(info, keyi, arrayNdx, SYMBOLS, &ndx)) - return false; - - groupi = &darray_item(keyi->groups, ndx); - - if (value == NULL) { - groupi->defined |= GROUP_FIELD_SYMS; - return true; - } - - if (value->expr.op != EXPR_KEYSYM_LIST) { - log_err(info->ctx, - "Expected a list of symbols, found %s; " - "Ignoring symbols for group %u of %s\n", - expr_op_type_to_string(value->expr.op), ndx + 1, - KeyInfoText(info, keyi)); - return false; - } - - if (groupi->defined & GROUP_FIELD_SYMS) { - log_err(info->ctx, - "Symbols for key %s, group %u already defined; " - "Ignoring duplicate definition\n", - KeyInfoText(info, keyi), ndx + 1); - return false; - } - - nLevels = darray_size(value->keysym_list.symsMapIndex); - if (darray_size(groupi->levels) < nLevels) - darray_resize0(groupi->levels, nLevels); - - groupi->defined |= GROUP_FIELD_SYMS; - - for (xkb_level_index_t i = 0; i < nLevels; i++) { - unsigned int sym_index; - struct xkb_level *leveli = &darray_item(groupi->levels, i); - - sym_index = darray_item(value->keysym_list.symsMapIndex, i); - leveli->num_syms = darray_item(value->keysym_list.symsNumEntries, i); - if (leveli->num_syms > 1) - leveli->u.syms = calloc(leveli->num_syms, sizeof(*leveli->u.syms)); - - for (unsigned j = 0; j < leveli->num_syms; j++) { - xkb_keysym_t keysym = darray_item(value->keysym_list.syms, - sym_index + j); - - if (leveli->num_syms == 1) { - if (keysym == XKB_KEY_NoSymbol) - leveli->num_syms = 0; - else - leveli->u.sym = keysym; - } - else if (leveli->num_syms > 1) { - leveli->u.syms[j] = keysym; - } - } - } - - return true; -} - -static bool -AddActionsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx, - ExprDef *value) -{ - xkb_layout_index_t ndx; - GroupInfo *groupi; - unsigned int nActs; - ExprDef *act; - - if (!GetGroupIndex(info, keyi, arrayNdx, ACTIONS, &ndx)) - return false; - - groupi = &darray_item(keyi->groups, ndx); - - if (value == NULL) { - groupi->defined |= GROUP_FIELD_ACTS; - return true; - } - - if (value->expr.op != EXPR_ACTION_LIST) { - log_wsgo(info->ctx, - "Bad expression type (%d) for action list value; " - "Ignoring actions for group %u of %s\n", - value->expr.op, ndx, KeyInfoText(info, keyi)); - return false; - } - - if (groupi->defined & GROUP_FIELD_ACTS) { - log_wsgo(info->ctx, - "Actions for key %s, group %u already defined\n", - KeyInfoText(info, keyi), ndx); - return false; - } - - nActs = 0; - for (act = value->unary.child; act; act = (ExprDef *) act->common.next) - nActs++; - - if (darray_size(groupi->levels) < nActs) - darray_resize0(groupi->levels, nActs); - - groupi->defined |= GROUP_FIELD_ACTS; - - act = value->unary.child; - for (unsigned i = 0; i < nActs; i++) { - union xkb_action *toAct = &darray_item(groupi->levels, i).action; - - if (!HandleActionDef(info->ctx, info->actions, &info->mods, act, toAct)) - log_err(info->ctx, - "Illegal action definition for %s; " - "Action for group %u/level %u ignored\n", - KeyInfoText(info, keyi), ndx + 1, i + 1); - - act = (ExprDef *) act->common.next; - } - - return true; -} - -static const LookupEntry repeatEntries[] = { - { "true", KEY_REPEAT_YES }, - { "yes", KEY_REPEAT_YES }, - { "on", KEY_REPEAT_YES }, - { "false", KEY_REPEAT_NO }, - { "no", KEY_REPEAT_NO }, - { "off", KEY_REPEAT_NO }, - { "default", KEY_REPEAT_UNDEFINED }, - { NULL, 0 } -}; - -static bool -SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field, - ExprDef *arrayNdx, ExprDef *value) -{ - if (istreq(field, "type")) { - xkb_layout_index_t ndx; - xkb_atom_t val; - - if (!ExprResolveString(info->ctx, value, &val)) { - log_err(info->ctx, - "The type field of a key symbol map must be a string; " - "Ignoring illegal type definition\n"); - return false; - } - - if (!arrayNdx) { - keyi->default_type = val; - keyi->defined |= KEY_FIELD_DEFAULT_TYPE; - } - else if (!ExprResolveGroup(info->ctx, arrayNdx, &ndx)) { - log_err(info->ctx, - "Illegal group index for type of key %s; " - "Definition with non-integer array index ignored\n", - KeyInfoText(info, keyi)); - return false; - } - else { - ndx--; - if (ndx >= darray_size(keyi->groups)) - darray_resize0(keyi->groups, ndx + 1); - darray_item(keyi->groups, ndx).type = val; - darray_item(keyi->groups, ndx).defined |= GROUP_FIELD_TYPE; - } - } - else if (istreq(field, "symbols")) { - return AddSymbolsToKey(info, keyi, arrayNdx, value); - } - else if (istreq(field, "actions")) { - return AddActionsToKey(info, keyi, arrayNdx, value); - } - else if (istreq(field, "vmods") || - istreq(field, "virtualmods") || - istreq(field, "virtualmodifiers")) { - xkb_mod_mask_t mask; - - if (!ExprResolveModMask(info->ctx, value, MOD_VIRT, &info->mods, - &mask)) { - log_err(info->ctx, - "Expected a virtual modifier mask, found %s; " - "Ignoring virtual modifiers definition for key %s\n", - expr_op_type_to_string(value->expr.op), - KeyInfoText(info, keyi)); - return false; - } - - keyi->vmodmap = mask; - keyi->defined |= KEY_FIELD_VMODMAP; - } - else if (istreq(field, "locking") || - istreq(field, "lock") || - istreq(field, "locks")) { - log_vrb(info->ctx, 1, - "Key behaviors not supported; " - "Ignoring locking specification for key %s\n", - KeyInfoText(info, keyi)); - } - else if (istreq(field, "radiogroup") || - istreq(field, "permanentradiogroup") || - istreq(field, "allownone")) { - log_vrb(info->ctx, 1, - "Radio groups not supported; " - "Ignoring radio group specification for key %s\n", - KeyInfoText(info, keyi)); - } - else if (istreq_prefix("overlay", field) || - istreq_prefix("permanentoverlay", field)) { - log_vrb(info->ctx, 1, - "Overlays not supported; " - "Ignoring overlay specification for key %s\n", - KeyInfoText(info, keyi)); - } - else if (istreq(field, "repeating") || - istreq(field, "repeats") || - istreq(field, "repeat")) { - unsigned int val; - - if (!ExprResolveEnum(info->ctx, value, &val, repeatEntries)) { - log_err(info->ctx, - "Illegal repeat setting for %s; " - "Non-boolean repeat setting ignored\n", - KeyInfoText(info, keyi)); - return false; - } - - keyi->repeat = val; - keyi->defined |= KEY_FIELD_REPEAT; - } - else if (istreq(field, "groupswrap") || - istreq(field, "wrapgroups")) { - bool set; - - if (!ExprResolveBoolean(info->ctx, value, &set)) { - log_err(info->ctx, - "Illegal groupsWrap setting for %s; " - "Non-boolean value ignored\n", - KeyInfoText(info, keyi)); - return false; - } - - keyi->out_of_range_group_action = (set ? RANGE_WRAP : RANGE_SATURATE); - keyi->defined |= KEY_FIELD_GROUPINFO; - } - else if (istreq(field, "groupsclamp") || - istreq(field, "clampgroups")) { - bool set; - - if (!ExprResolveBoolean(info->ctx, value, &set)) { - log_err(info->ctx, - "Illegal groupsClamp setting for %s; " - "Non-boolean value ignored\n", - KeyInfoText(info, keyi)); - return false; - } - - keyi->out_of_range_group_action = (set ? RANGE_SATURATE : RANGE_WRAP); - keyi->defined |= KEY_FIELD_GROUPINFO; - } - else if (istreq(field, "groupsredirect") || - istreq(field, "redirectgroups")) { - xkb_layout_index_t grp; - - if (!ExprResolveGroup(info->ctx, value, &grp)) { - log_err(info->ctx, - "Illegal group index for redirect of key %s; " - "Definition with non-integer group ignored\n", - KeyInfoText(info, keyi)); - return false; - } - - keyi->out_of_range_group_action = RANGE_REDIRECT; - keyi->out_of_range_group_number = grp - 1; - keyi->defined |= KEY_FIELD_GROUPINFO; - } - else { - log_err(info->ctx, - "Unknown field %s in a symbol interpretation; " - "Definition ignored\n", - field); - return false; - } - - return true; -} - -static bool -SetGroupName(SymbolsInfo *info, ExprDef *arrayNdx, ExprDef *value) -{ - xkb_layout_index_t group, group_to_use; - xkb_atom_t name; - - if (!arrayNdx) { - log_vrb(info->ctx, 1, - "You must specify an index when specifying a group name; " - "Group name definition without array subscript ignored\n"); - return false; - } - - if (!ExprResolveGroup(info->ctx, arrayNdx, &group)) { - log_err(info->ctx, - "Illegal index in group name definition; " - "Definition with non-integer array index ignored\n"); - return false; - } - - if (!ExprResolveString(info->ctx, value, &name)) { - log_err(info->ctx, - "Group name must be a string; " - "Illegal name for group %d ignored\n", group); - return false; - } - - if (info->explicit_group == XKB_LAYOUT_INVALID) { - group_to_use = group - 1; - } - else if (group - 1 == 0) { - group_to_use = info->explicit_group; - } - else { - log_warn(info->ctx, - "An explicit group was specified for the '%s' map, " - "but it provides a name for a group other than Group1 (%d); " - "Ignoring group name '%s'\n", - info->name, group, - xkb_atom_text(info->ctx, name)); - return false; - } - - if (group_to_use >= darray_size(info->group_names)) - darray_resize0(info->group_names, group_to_use + 1); - darray_item(info->group_names, group_to_use) = name; - - return true; -} - -static bool -HandleGlobalVar(SymbolsInfo *info, VarDef *stmt) -{ - const char *elem, *field; - ExprDef *arrayNdx; - bool ret; - - if (!ExprResolveLhs(info->ctx, stmt->name, &elem, &field, &arrayNdx)) - return false; - - if (elem && istreq(elem, "key")) { - ret = SetSymbolsField(info, &info->default_key, field, arrayNdx, - stmt->value); - } - else if (!elem && (istreq(field, "name") || - istreq(field, "groupname"))) { - ret = SetGroupName(info, arrayNdx, stmt->value); - } - else if (!elem && (istreq(field, "groupswrap") || - istreq(field, "wrapgroups"))) { - log_err(info->ctx, - "Global \"groupswrap\" not supported; Ignored\n"); - ret = true; - } - else if (!elem && (istreq(field, "groupsclamp") || - istreq(field, "clampgroups"))) { - log_err(info->ctx, - "Global \"groupsclamp\" not supported; Ignored\n"); - ret = true; - } - else if (!elem && (istreq(field, "groupsredirect") || - istreq(field, "redirectgroups"))) { - log_err(info->ctx, - "Global \"groupsredirect\" not supported; Ignored\n"); - ret = true; - } - else if (!elem && istreq(field, "allownone")) { - log_err(info->ctx, - "Radio groups not supported; " - "Ignoring \"allownone\" specification\n"); - ret = true; - } - else { - ret = SetActionField(info->ctx, info->actions, &info->mods, - elem, field, arrayNdx, stmt->value); - } - - return ret; -} - -static bool -HandleSymbolsBody(SymbolsInfo *info, VarDef *def, KeyInfo *keyi) -{ - bool ok = true; - const char *elem, *field; - ExprDef *arrayNdx; - - for (; def; def = (VarDef *) def->common.next) { - if (def->name && def->name->expr.op == EXPR_FIELD_REF) { - log_err(info->ctx, - "Cannot set a global default value from within a key statement; " - "Move statements to the global file scope\n"); - continue; - } - - if (!def->name) { - if (!def->value || def->value->expr.op == EXPR_KEYSYM_LIST) - field = "symbols"; - else - field = "actions"; - arrayNdx = NULL; - } - else { - ok = ExprResolveLhs(info->ctx, def->name, &elem, &field, - &arrayNdx); - } - - if (ok) - ok = SetSymbolsField(info, keyi, field, arrayNdx, def->value); - } - - return ok; -} - -static bool -SetExplicitGroup(SymbolsInfo *info, KeyInfo *keyi) -{ - xkb_layout_index_t i; - GroupInfo *groupi; - bool warn = false; - - if (info->explicit_group == XKB_LAYOUT_INVALID) - return true; - - darray_enumerate_from(i, groupi, keyi->groups, 1) { - if (groupi->defined) { - warn = true; - ClearGroupInfo(groupi); - InitGroupInfo(groupi); - } - } - - if (warn) - log_warn(info->ctx, - "For the map %s an explicit group specified, " - "but key %s has more than one group defined; " - "All groups except first one will be ignored\n", - info->name, KeyInfoText(info, keyi)); - - darray_resize0(keyi->groups, info->explicit_group + 1); - if (info->explicit_group > 0) { - darray_item(keyi->groups, info->explicit_group) = - darray_item(keyi->groups, 0); - InitGroupInfo(&darray_item(keyi->groups, 0)); - } - - return true; -} - -static bool -HandleSymbolsDef(SymbolsInfo *info, SymbolsDef *stmt) -{ - KeyInfo keyi; - - keyi = info->default_key; - darray_init(keyi.groups); - darray_copy(keyi.groups, info->default_key.groups); - for (xkb_layout_index_t i = 0; i < darray_size(keyi.groups); i++) - CopyGroupInfo(&darray_item(keyi.groups, i), - &darray_item(info->default_key.groups, i)); - keyi.merge = stmt->merge; - keyi.name = stmt->keyName; - - if (!HandleSymbolsBody(info, stmt->symbols, &keyi)) { - info->errorCount++; - return false; - } - - if (!SetExplicitGroup(info, &keyi)) { - info->errorCount++; - return false; - } - - if (!AddKeySymbols(info, &keyi, true)) { - info->errorCount++; - return false; - } - - return true; -} - -static bool -HandleModMapDef(SymbolsInfo *info, ModMapDef *def) -{ - ModMapEntry tmp; - xkb_mod_index_t ndx; - bool ok; - struct xkb_context *ctx = info->ctx; - - ndx = XkbModNameToIndex(&info->mods, def->modifier, MOD_REAL); - if (ndx == XKB_MOD_INVALID) { - log_err(info->ctx, - "Illegal modifier map definition; " - "Ignoring map for non-modifier \"%s\"\n", - xkb_atom_text(ctx, def->modifier)); - return false; - } - - ok = true; - tmp.modifier = ndx; - tmp.merge = def->merge; - - for (ExprDef *key = def->keys; key; key = (ExprDef *) key->common.next) { - xkb_keysym_t sym; - - if (key->expr.op == EXPR_VALUE && - key->expr.value_type == EXPR_TYPE_KEYNAME) { - tmp.haveSymbol = false; - tmp.u.keyName = key->key_name.key_name; - } - else if (ExprResolveKeySym(ctx, key, &sym)) { - tmp.haveSymbol = true; - tmp.u.keySym = sym; - } - else { - log_err(info->ctx, - "Modmap entries may contain only key names or keysyms; " - "Illegal definition for %s modifier ignored\n", - ModIndexText(info->ctx, &info->mods, tmp.modifier)); - continue; - } - - ok = AddModMapEntry(info, &tmp) && ok; - } - return ok; -} - -static void -HandleSymbolsFile(SymbolsInfo *info, XkbFile *file, enum merge_mode merge) -{ - bool ok; - - free(info->name); - info->name = strdup_safe(file->name); - - for (ParseCommon *stmt = file->defs; stmt; stmt = stmt->next) { - switch (stmt->type) { - case STMT_INCLUDE: - ok = HandleIncludeSymbols(info, (IncludeStmt *) stmt); - break; - case STMT_SYMBOLS: - ok = HandleSymbolsDef(info, (SymbolsDef *) stmt); - break; - case STMT_VAR: - ok = HandleGlobalVar(info, (VarDef *) stmt); - break; - case STMT_VMOD: - ok = HandleVModDef(info->ctx, &info->mods, (VModDef *) stmt, merge); - break; - case STMT_MODMAP: - ok = HandleModMapDef(info, (ModMapDef *) stmt); - break; - default: - log_err(info->ctx, - "Symbols files may not include other types; " - "Ignoring %s\n", stmt_type_to_string(stmt->type)); - ok = false; - break; - } - - if (!ok) - info->errorCount++; - - if (info->errorCount > 10) { - log_err(info->ctx, "Abandoning symbols file \"%s\"\n", - file->name); - break; - } - } -} - -/** - * Given a keysym @sym, return a key which generates it, or NULL. - * This is used for example in a modifier map definition, such as: - * modifier_map Lock { Caps_Lock }; - * where we want to add the Lock modifier to the modmap of the key - * which matches the keysym Caps_Lock. - * Since there can be many keys which generates the keysym, the key - * is chosen first by lowest group in which the keysym appears, than - * by lowest level and than by lowest key code. - */ -static struct xkb_key * -FindKeyForSymbol(struct xkb_keymap *keymap, xkb_keysym_t sym) -{ - struct xkb_key *key; - xkb_layout_index_t group; - bool got_one_group, got_one_level; - - group = 0; - do { - xkb_level_index_t level = 0; - got_one_group = false; - do { - got_one_level = false; - xkb_keys_foreach(key, keymap) { - if (group < key->num_groups && - level < XkbKeyNumLevels(key, group)) { - got_one_group = got_one_level = true; - if (key->groups[group].levels[level].num_syms == 1 && - key->groups[group].levels[level].u.sym == sym) - return key; - } - } - level++; - } while (got_one_level); - group++; - } while (got_one_group); - - return NULL; -} - -/* - * Find an appropriate type for a group and return its name. - * - * Simple recipe: - * - ONE_LEVEL for width 0/1 - * - ALPHABETIC for 2 shift levels, with lower/upercase keysyms - * - KEYPAD for keypad keys. - * - TWO_LEVEL for other 2 shift level keys. - * and the same for four level keys. - * - * FIXME: Decide how to handle multiple-syms-per-level, and do it. - */ -static xkb_atom_t -FindAutomaticType(struct xkb_context *ctx, GroupInfo *groupi) -{ - xkb_keysym_t sym0, sym1; - const xkb_level_index_t width = darray_size(groupi->levels); - -#define GET_SYM(level) \ - (darray_item(groupi->levels, level).num_syms == 0 ? \ - XKB_KEY_NoSymbol : \ - darray_item(groupi->levels, level).num_syms == 1 ? \ - darray_item(groupi->levels, level).u.sym : \ - /* num_syms > 1 */ \ - darray_item(groupi->levels, level).u.syms[0]) - - if (width == 1 || width <= 0) - return xkb_atom_intern_literal(ctx, "ONE_LEVEL"); - - sym0 = GET_SYM(0); - sym1 = GET_SYM(1); - - if (width == 2) { - if (xkb_keysym_is_lower(sym0) && xkb_keysym_is_upper(sym1)) - return xkb_atom_intern_literal(ctx, "ALPHABETIC"); - - if (xkb_keysym_is_keypad(sym0) || xkb_keysym_is_keypad(sym1)) - return xkb_atom_intern_literal(ctx, "KEYPAD"); - - return xkb_atom_intern_literal(ctx, "TWO_LEVEL"); - } - - if (width <= 4) { - if (xkb_keysym_is_lower(sym0) && xkb_keysym_is_upper(sym1)) { - xkb_keysym_t sym2, sym3; - sym2 = GET_SYM(2); - sym3 = (width == 4 ? GET_SYM(3) : XKB_KEY_NoSymbol); - - if (xkb_keysym_is_lower(sym2) && xkb_keysym_is_upper(sym3)) - return xkb_atom_intern_literal(ctx, "FOUR_LEVEL_ALPHABETIC"); - - return xkb_atom_intern_literal(ctx, "FOUR_LEVEL_SEMIALPHABETIC"); - } - - if (xkb_keysym_is_keypad(sym0) || xkb_keysym_is_keypad(sym1)) - return xkb_atom_intern_literal(ctx, "FOUR_LEVEL_KEYPAD"); - - return xkb_atom_intern_literal(ctx, "FOUR_LEVEL"); - } - - return XKB_ATOM_NONE; - -#undef GET_SYM -} - -static const struct xkb_key_type * -FindTypeForGroup(struct xkb_keymap *keymap, KeyInfo *keyi, - xkb_layout_index_t group, bool *explicit_type) -{ - unsigned int i; - GroupInfo *groupi = &darray_item(keyi->groups, group); - xkb_atom_t type_name = groupi->type; - - *explicit_type = true; - - if (type_name == XKB_ATOM_NONE) { - if (keyi->default_type != XKB_ATOM_NONE) { - type_name = keyi->default_type; - } - else { - type_name = FindAutomaticType(keymap->ctx, groupi); - if (type_name != XKB_ATOM_NONE) - *explicit_type = false; - } - } - - if (type_name == XKB_ATOM_NONE) { - log_warn(keymap->ctx, - "Couldn't find an automatic type for key '%s' group %d with %lu levels; " - "Using the default type\n", - KeyNameText(keymap->ctx, keyi->name), group + 1, - (unsigned long) darray_size(groupi->levels)); - goto use_default; - } - - for (i = 0; i < keymap->num_types; i++) - if (keymap->types[i].name == type_name) - break; - - if (i >= keymap->num_types) { - log_warn(keymap->ctx, - "The type \"%s\" for key '%s' group %d was not previously defined; " - "Using the default type\n", - xkb_atom_text(keymap->ctx, type_name), - KeyNameText(keymap->ctx, keyi->name), group + 1); - goto use_default; - } - - return &keymap->types[i]; - -use_default: - /* - * Index 0 is guaranteed to contain something, usually - * ONE_LEVEL or at least some default one-level type. - */ - return &keymap->types[0]; -} - -static bool -CopySymbolsDefToKeymap(struct xkb_keymap *keymap, SymbolsInfo *info, - KeyInfo *keyi) -{ - struct xkb_key *key; - GroupInfo *groupi; - const GroupInfo *group0; - xkb_layout_index_t i; - - /* - * The name is guaranteed to be real and not an alias (see - * AddKeySymbols), so 'false' is safe here. - */ - key = XkbKeyByName(keymap, keyi->name, false); - if (!key) { - log_vrb(info->ctx, 5, - "Key %s not found in keycodes; Symbols ignored\n", - KeyInfoText(info, keyi)); - return false; - } - - /* Find the range of groups we need. */ - key->num_groups = 0; - darray_enumerate(i, groupi, keyi->groups) - if (groupi->defined) - key->num_groups = i + 1; - - if (key->num_groups <= 0) - return false; /* WSGO */ - - darray_resize(keyi->groups, key->num_groups); - - /* - * If there are empty groups between non-empty ones, fill them with data - * from the first group. - * We can make a wrong assumption here. But leaving gaps is worse. - */ - group0 = &darray_item(keyi->groups, 0); - darray_foreach_from(groupi, keyi->groups, 1) { - if (groupi->defined) - continue; - - CopyGroupInfo(groupi, group0); - } - - key->groups = calloc(key->num_groups, sizeof(*key->groups)); - - /* Find and assign the groups' types in the keymap. */ - darray_enumerate(i, groupi, keyi->groups) { - const struct xkb_key_type *type; - bool explicit_type; - - type = FindTypeForGroup(keymap, keyi, i, &explicit_type); - - /* Always have as many levels as the type specifies. */ - if (type->num_levels < darray_size(groupi->levels)) { - struct xkb_level *leveli; - - log_vrb(info->ctx, 1, - "Type \"%s\" has %d levels, but %s has %d levels; " - "Ignoring extra symbols\n", - xkb_atom_text(keymap->ctx, type->name), type->num_levels, - KeyInfoText(info, keyi), - (int) darray_size(groupi->levels)); - - darray_foreach_from(leveli, groupi->levels, type->num_levels) - ClearLevelInfo(leveli); - } - darray_resize0(groupi->levels, type->num_levels); - - key->groups[i].explicit_type = explicit_type; - key->groups[i].type = type; - } - - /* Copy levels. */ - darray_enumerate(i, groupi, keyi->groups) - darray_steal(groupi->levels, &key->groups[i].levels, NULL); - - key->out_of_range_group_number = keyi->out_of_range_group_number; - key->out_of_range_group_action = keyi->out_of_range_group_action; - - if (keyi->defined & KEY_FIELD_VMODMAP) { - key->vmodmap = keyi->vmodmap; - key->explicit |= EXPLICIT_VMODMAP; - } - - if (keyi->repeat != KEY_REPEAT_UNDEFINED) { - key->repeats = (keyi->repeat == KEY_REPEAT_YES); - key->explicit |= EXPLICIT_REPEAT; - } - - darray_foreach(groupi, keyi->groups) { - if (groupi->defined & GROUP_FIELD_ACTS) { - key->explicit |= EXPLICIT_INTERP; - break; - } - } - - return true; -} - -static bool -CopyModMapDefToKeymap(struct xkb_keymap *keymap, SymbolsInfo *info, - ModMapEntry *entry) -{ - struct xkb_key *key; - - if (!entry->haveSymbol) { - key = XkbKeyByName(keymap, entry->u.keyName, true); - if (!key) { - log_vrb(info->ctx, 5, - "Key %s not found in keycodes; " - "Modifier map entry for %s not updated\n", - KeyNameText(info->ctx, entry->u.keyName), - ModIndexText(info->ctx, &info->mods, entry->modifier)); - return false; - } - } - else { - key = FindKeyForSymbol(keymap, entry->u.keySym); - if (!key) { - log_vrb(info->ctx, 5, - "Key \"%s\" not found in symbol map; " - "Modifier map entry for %s not updated\n", - KeysymText(info->ctx, entry->u.keySym), - ModIndexText(info->ctx, &info->mods, entry->modifier)); - return false; - } - } - - key->modmap |= (1u << entry->modifier); - return true; -} - -static bool -CopySymbolsToKeymap(struct xkb_keymap *keymap, SymbolsInfo *info) -{ - KeyInfo *keyi; - ModMapEntry *mm; - - keymap->symbols_section_name = strdup_safe(info->name); - XkbEscapeMapName(keymap->symbols_section_name); - - keymap->mods = info->mods; - - darray_steal(info->group_names, - &keymap->group_names, &keymap->num_group_names); - - darray_foreach(keyi, info->keys) - if (!CopySymbolsDefToKeymap(keymap, info, keyi)) - info->errorCount++; - - if (xkb_context_get_log_verbosity(keymap->ctx) > 3) { - struct xkb_key *key; - - xkb_keys_foreach(key, keymap) { - if (key->name == XKB_ATOM_NONE) - continue; - - if (key->num_groups < 1) - log_info(info->ctx, - "No symbols defined for %s\n", - KeyNameText(info->ctx, key->name)); - } - } - - darray_foreach(mm, info->modmaps) - if (!CopyModMapDefToKeymap(keymap, info, mm)) - info->errorCount++; - - /* XXX: If we don't ignore errorCount, things break. */ - return true; -} - -bool -CompileSymbols(XkbFile *file, struct xkb_keymap *keymap, - enum merge_mode merge) -{ - SymbolsInfo info; - ActionsInfo *actions; - - actions = NewActionsInfo(); - if (!actions) - return false; - - InitSymbolsInfo(&info, keymap, actions, &keymap->mods); - info.default_key.merge = merge; - - HandleSymbolsFile(&info, file, merge); - - if (info.errorCount != 0) - goto err_info; - - if (!CopySymbolsToKeymap(keymap, &info)) - goto err_info; - - ClearSymbolsInfo(&info); - FreeActionsInfo(actions); - return true; - -err_info: - FreeActionsInfo(actions); - ClearSymbolsInfo(&info); - return false; -} diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/types.c b/src/3rdparty/xkbcommon/src/xkbcomp/types.c deleted file mode 100644 index e85b67e893..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/types.c +++ /dev/null @@ -1,742 +0,0 @@ -/************************************************************ - * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting - * documentation, and that the name of Silicon Graphics not be - * used in advertising or publicity pertaining to distribution - * of the software without specific prior written permission. - * Silicon Graphics makes no representation about the suitability - * of this software for any purpose. It is provided "as is" - * without any express or implied warranty. - * - * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - * THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - ********************************************************/ - -#include "xkbcomp-priv.h" -#include "text.h" -#include "vmod.h" -#include "expr.h" -#include "include.h" - -enum type_field { - TYPE_FIELD_MASK = (1 << 0), - TYPE_FIELD_MAP = (1 << 1), - TYPE_FIELD_PRESERVE = (1 << 2), - TYPE_FIELD_LEVEL_NAME = (1 << 3), -}; - -typedef struct { - enum type_field defined; - enum merge_mode merge; - - xkb_atom_t name; - xkb_mod_mask_t mods; - xkb_level_index_t num_levels; - darray(struct xkb_key_type_entry) entries; - darray(xkb_atom_t) level_names; -} KeyTypeInfo; - -typedef struct { - char *name; - int errorCount; - - darray(KeyTypeInfo) types; - struct xkb_mod_set mods; - - struct xkb_context *ctx; -} KeyTypesInfo; - -/***====================================================================***/ - -static inline const char * -MapEntryTxt(KeyTypesInfo *info, struct xkb_key_type_entry *entry) -{ - return ModMaskText(info->ctx, &info->mods, entry->mods.mods); -} - -static inline const char * -TypeTxt(KeyTypesInfo *info, KeyTypeInfo *type) -{ - return xkb_atom_text(info->ctx, type->name); -} - -static inline const char * -TypeMaskTxt(KeyTypesInfo *info, KeyTypeInfo *type) -{ - return ModMaskText(info->ctx, &info->mods, type->mods); -} - -static inline bool -ReportTypeShouldBeArray(KeyTypesInfo *info, KeyTypeInfo *type, - const char *field) -{ - return ReportShouldBeArray(info->ctx, "key type", field, - TypeTxt(info, type)); -} - -static inline bool -ReportTypeBadType(KeyTypesInfo *info, KeyTypeInfo *type, - const char *field, const char *wanted) -{ - return ReportBadType(info->ctx, "key type", field, - TypeTxt(info, type), wanted); -} - -/***====================================================================***/ - -static void -InitKeyTypesInfo(KeyTypesInfo *info, struct xkb_context *ctx, - const struct xkb_mod_set *mods) -{ - memset(info, 0, sizeof(*info)); - info->ctx = ctx; - info->mods = *mods; -} - -static void -ClearKeyTypeInfo(KeyTypeInfo *type) -{ - darray_free(type->entries); - darray_free(type->level_names); -} - -static void -ClearKeyTypesInfo(KeyTypesInfo *info) -{ - free(info->name); - darray_free(info->types); -} - -static KeyTypeInfo * -FindMatchingKeyType(KeyTypesInfo *info, xkb_atom_t name) -{ - KeyTypeInfo *old; - - darray_foreach(old, info->types) - if (old->name == name) - return old; - - return NULL; -} - -static bool -AddKeyType(KeyTypesInfo *info, KeyTypeInfo *new, bool same_file) -{ - KeyTypeInfo *old; - const int verbosity = xkb_context_get_log_verbosity(info->ctx); - - old = FindMatchingKeyType(info, new->name); - if (old) { - if (new->merge == MERGE_REPLACE || new->merge == MERGE_OVERRIDE) { - if ((same_file && verbosity > 0) || verbosity > 9) { - log_warn(info->ctx, - "Multiple definitions of the %s key type; " - "Earlier definition ignored\n", - xkb_atom_text(info->ctx, new->name)); - } - - ClearKeyTypeInfo(old); - *old = *new; - darray_init(new->entries); - darray_init(new->level_names); - return true; - } - - if (same_file) - log_vrb(info->ctx, 4, - "Multiple definitions of the %s key type; " - "Later definition ignored\n", - xkb_atom_text(info->ctx, new->name)); - - ClearKeyTypeInfo(new); - return true; - } - - darray_append(info->types, *new); - return true; -} - -/***====================================================================***/ - -static void -MergeIncludedKeyTypes(KeyTypesInfo *into, KeyTypesInfo *from, - enum merge_mode merge) -{ - if (from->errorCount > 0) { - into->errorCount += from->errorCount; - return; - } - - into->mods = from->mods; - - if (into->name == NULL) { - into->name = from->name; - from->name = NULL; - } - - if (darray_empty(into->types)) { - into->types = from->types; - darray_init(from->types); - } - else { - KeyTypeInfo *type; - darray_foreach(type, from->types) { - type->merge = (merge == MERGE_DEFAULT ? type->merge : merge); - if (!AddKeyType(into, type, false)) - into->errorCount++; - } - } -} - -static void -HandleKeyTypesFile(KeyTypesInfo *info, XkbFile *file, enum merge_mode merge); - -static bool -HandleIncludeKeyTypes(KeyTypesInfo *info, IncludeStmt *include) -{ - KeyTypesInfo included; - - InitKeyTypesInfo(&included, info->ctx, &info->mods); - included.name = include->stmt; - include->stmt = NULL; - - for (IncludeStmt *stmt = include; stmt; stmt = stmt->next_incl) { - KeyTypesInfo next_incl; - XkbFile *file; - - file = ProcessIncludeFile(info->ctx, stmt, FILE_TYPE_TYPES); - if (!file) { - info->errorCount += 10; - ClearKeyTypesInfo(&included); - return false; - } - - InitKeyTypesInfo(&next_incl, info->ctx, &included.mods); - - HandleKeyTypesFile(&next_incl, file, stmt->merge); - - MergeIncludedKeyTypes(&included, &next_incl, stmt->merge); - - ClearKeyTypesInfo(&next_incl); - FreeXkbFile(file); - } - - MergeIncludedKeyTypes(info, &included, include->merge); - ClearKeyTypesInfo(&included); - - return (info->errorCount == 0); -} - -/***====================================================================***/ - -static bool -SetModifiers(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx, - ExprDef *value) -{ - xkb_mod_mask_t mods; - - if (arrayNdx) - log_warn(info->ctx, - "The modifiers field of a key type is not an array; " - "Illegal array subscript ignored\n"); - - if (!ExprResolveModMask(info->ctx, value, MOD_BOTH, &info->mods, &mods)) { - log_err(info->ctx, - "Key type mask field must be a modifier mask; " - "Key type definition ignored\n"); - return false; - } - - if (type->defined & TYPE_FIELD_MASK) { - log_warn(info->ctx, - "Multiple modifier mask definitions for key type %s; " - "Using %s, ignoring %s\n", - xkb_atom_text(info->ctx, type->name), - TypeMaskTxt(info, type), - ModMaskText(info->ctx, &info->mods, mods)); - return false; - } - - type->mods = mods; - return true; -} - -/***====================================================================***/ - -static struct xkb_key_type_entry * -FindMatchingMapEntry(KeyTypeInfo *type, xkb_mod_mask_t mods) -{ - struct xkb_key_type_entry *entry; - - darray_foreach(entry, type->entries) - if (entry->mods.mods == mods) - return entry; - - return NULL; -} - -static bool -AddMapEntry(KeyTypesInfo *info, KeyTypeInfo *type, - struct xkb_key_type_entry *new, bool clobber, bool report) -{ - struct xkb_key_type_entry *old; - - old = FindMatchingMapEntry(type, new->mods.mods); - if (old) { - if (report && old->level != new->level) { - log_warn(info->ctx, - "Multiple map entries for %s in %s; " - "Using %d, ignoring %d\n", - MapEntryTxt(info, new), TypeTxt(info, type), - (clobber ? new->level : old->level) + 1, - (clobber ? old->level : new->level) + 1); - } - else { - log_vrb(info->ctx, 10, - "Multiple occurrences of map[%s]= %d in %s; Ignored\n", - MapEntryTxt(info, new), new->level + 1, - TypeTxt(info, type)); - return true; - } - - if (clobber) { - if (new->level >= type->num_levels) - type->num_levels = new->level + 1; - old->level = new->level; - } - - return true; - } - - if (new->level >= type->num_levels) - type->num_levels = new->level + 1; - - darray_append(type->entries, *new); - return true; -} - -static bool -SetMapEntry(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx, - ExprDef *value) -{ - struct xkb_key_type_entry entry; - - if (arrayNdx == NULL) - return ReportTypeShouldBeArray(info, type, "map entry"); - - if (!ExprResolveModMask(info->ctx, arrayNdx, MOD_BOTH, &info->mods, - &entry.mods.mods)) - return ReportTypeBadType(info, type, "map entry", "modifier mask"); - - if (entry.mods.mods & (~type->mods)) { - log_vrb(info->ctx, 1, - "Map entry for unused modifiers in %s; " - "Using %s instead of %s\n", - TypeTxt(info, type), - ModMaskText(info->ctx, &info->mods, - entry.mods.mods & type->mods), - MapEntryTxt(info, &entry)); - entry.mods.mods &= type->mods; - } - - if (!ExprResolveLevel(info->ctx, value, &entry.level)) { - log_err(info->ctx, - "Level specifications in a key type must be integer; " - "Ignoring malformed level specification\n"); - return false; - } - - entry.preserve.mods = 0; - - return AddMapEntry(info, type, &entry, true, true); -} - -/***====================================================================***/ - -static bool -AddPreserve(KeyTypesInfo *info, KeyTypeInfo *type, - xkb_mod_mask_t mods, xkb_mod_mask_t preserve_mods) -{ - struct xkb_key_type_entry *entry; - struct xkb_key_type_entry new; - - darray_foreach(entry, type->entries) { - if (entry->mods.mods != mods) - continue; - - /* Map exists without previous preserve (or "None"); override. */ - if (entry->preserve.mods == 0) { - entry->preserve.mods = preserve_mods; - return true; - } - - /* Map exists with same preserve; do nothing. */ - if (entry->preserve.mods == preserve_mods) { - log_vrb(info->ctx, 10, - "Identical definitions for preserve[%s] in %s; " - "Ignored\n", - ModMaskText(info->ctx, &info->mods, mods), - TypeTxt(info, type)); - return true; - } - - /* Map exists with different preserve; latter wins. */ - log_vrb(info->ctx, 1, - "Multiple definitions for preserve[%s] in %s; " - "Using %s, ignoring %s\n", - ModMaskText(info->ctx, &info->mods, mods), - TypeTxt(info, type), - ModMaskText(info->ctx, &info->mods, preserve_mods), - ModMaskText(info->ctx, &info->mods, entry->preserve.mods)); - - entry->preserve.mods = preserve_mods; - return true; - } - - /* - * Map does not exist, i.e. preserve[] came before map[]. - * Create a map with the specified mask mapping to Level1. The level - * may be overridden later with an explicit map[] statement. - */ - new.level = 0; - new.mods.mods = mods; - new.preserve.mods = preserve_mods; - darray_append(type->entries, new); - return true; -} - -static bool -SetPreserve(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx, - ExprDef *value) -{ - xkb_mod_mask_t mods, preserve_mods; - - if (arrayNdx == NULL) - return ReportTypeShouldBeArray(info, type, "preserve entry"); - - if (!ExprResolveModMask(info->ctx, arrayNdx, MOD_BOTH, &info->mods, &mods)) - return ReportTypeBadType(info, type, "preserve entry", - "modifier mask"); - - if (mods & ~type->mods) { - const char *before, *after; - - before = ModMaskText(info->ctx, &info->mods, mods); - mods &= type->mods; - after = ModMaskText(info->ctx, &info->mods, mods); - - log_vrb(info->ctx, 1, - "Preserve for modifiers not used by the %s type; " - "Index %s converted to %s\n", - TypeTxt(info, type), before, after); - } - - if (!ExprResolveModMask(info->ctx, value, MOD_BOTH, &info->mods, - &preserve_mods)) { - log_err(info->ctx, - "Preserve value in a key type is not a modifier mask; " - "Ignoring preserve[%s] in type %s\n", - ModMaskText(info->ctx, &info->mods, mods), - TypeTxt(info, type)); - return false; - } - - if (preserve_mods & ~mods) { - const char *before, *after; - - before = ModMaskText(info->ctx, &info->mods, preserve_mods); - preserve_mods &= mods; - after = ModMaskText(info->ctx, &info->mods, preserve_mods); - - log_vrb(info->ctx, 1, - "Illegal value for preserve[%s] in type %s; " - "Converted %s to %s\n", - ModMaskText(info->ctx, &info->mods, mods), - TypeTxt(info, type), before, after); - } - - return AddPreserve(info, type, mods, preserve_mods); -} - -/***====================================================================***/ - -static bool -AddLevelName(KeyTypesInfo *info, KeyTypeInfo *type, - xkb_level_index_t level, xkb_atom_t name, bool clobber) -{ - /* New name. */ - if (level >= darray_size(type->level_names)) { - darray_resize0(type->level_names, level + 1); - goto finish; - } - - /* Same level, same name. */ - if (darray_item(type->level_names, level) == name) { - log_vrb(info->ctx, 10, - "Duplicate names for level %d of key type %s; Ignored\n", - level + 1, TypeTxt(info, type)); - return true; - } - - /* Same level, different name. */ - if (darray_item(type->level_names, level) != XKB_ATOM_NONE) { - const char *old, *new; - old = xkb_atom_text(info->ctx, - darray_item(type->level_names, level)); - new = xkb_atom_text(info->ctx, name); - log_vrb(info->ctx, 1, - "Multiple names for level %d of key type %s; " - "Using %s, ignoring %s\n", - level + 1, TypeTxt(info, type), - (clobber ? new : old), (clobber ? old : new)); - - if (!clobber) - return true; - } - - /* XXX: What about different level, same name? */ - -finish: - darray_item(type->level_names, level) = name; - return true; -} - -static bool -SetLevelName(KeyTypesInfo *info, KeyTypeInfo *type, ExprDef *arrayNdx, - ExprDef *value) -{ - xkb_level_index_t level; - xkb_atom_t level_name; - - if (arrayNdx == NULL) - return ReportTypeShouldBeArray(info, type, "level name"); - - if (!ExprResolveLevel(info->ctx, arrayNdx, &level)) - return ReportTypeBadType(info, type, "level name", "integer"); - - if (!ExprResolveString(info->ctx, value, &level_name)) { - log_err(info->ctx, - "Non-string name for level %d in key type %s; " - "Ignoring illegal level name definition\n", - level + 1, xkb_atom_text(info->ctx, type->name)); - return false; - } - - return AddLevelName(info, type, level, level_name, true); -} - -/***====================================================================***/ - -static bool -SetKeyTypeField(KeyTypesInfo *info, KeyTypeInfo *type, - const char *field, ExprDef *arrayNdx, ExprDef *value) -{ - bool ok = false; - enum type_field type_field = 0; - - if (istreq(field, "modifiers")) { - type_field = TYPE_FIELD_MASK; - ok = SetModifiers(info, type, arrayNdx, value); - } - else if (istreq(field, "map")) { - type_field = TYPE_FIELD_MAP; - ok = SetMapEntry(info, type, arrayNdx, value); - } - else if (istreq(field, "preserve")) { - type_field = TYPE_FIELD_PRESERVE; - ok = SetPreserve(info, type, arrayNdx, value); - } - else if (istreq(field, "levelname") || istreq(field, "level_name")) { - type_field = TYPE_FIELD_LEVEL_NAME; - ok = SetLevelName(info, type, arrayNdx, value); - } else { - log_err(info->ctx, - "Unknown field %s in key type %s; Definition ignored\n", - field, TypeTxt(info, type)); - } - - type->defined |= type_field; - return ok; -} - -static bool -HandleKeyTypeBody(KeyTypesInfo *info, VarDef *def, KeyTypeInfo *type) -{ - bool ok = true; - const char *elem, *field; - ExprDef *arrayNdx; - - for (; def; def = (VarDef *) def->common.next) { - ok = ExprResolveLhs(info->ctx, def->name, &elem, &field, - &arrayNdx); - if (!ok) - continue; - - if (elem && istreq(elem, "type")) { - log_err(info->ctx, - "Support for changing the default type has been removed; " - "Statement ignored\n"); - continue; - } - - ok = SetKeyTypeField(info, type, field, arrayNdx, def->value); - } - - return ok; -} - -static bool -HandleKeyTypeDef(KeyTypesInfo *info, KeyTypeDef *def, enum merge_mode merge) -{ - KeyTypeInfo type = { - .defined = 0, - .merge = (def->merge == MERGE_DEFAULT ? merge : def->merge), - .name = def->name, - .mods = 0, - .num_levels = 1, - .entries = darray_new(), - .level_names = darray_new(), - }; - - if (!HandleKeyTypeBody(info, def->body, &type)) { - info->errorCount++; - return false; - } - - if (!AddKeyType(info, &type, true)) { - info->errorCount++; - return false; - } - - return true; -} - -static void -HandleKeyTypesFile(KeyTypesInfo *info, XkbFile *file, enum merge_mode merge) -{ - bool ok; - - free(info->name); - info->name = strdup_safe(file->name); - - for (ParseCommon *stmt = file->defs; stmt; stmt = stmt->next) { - switch (stmt->type) { - case STMT_INCLUDE: - ok = HandleIncludeKeyTypes(info, (IncludeStmt *) stmt); - break; - case STMT_TYPE: - ok = HandleKeyTypeDef(info, (KeyTypeDef *) stmt, merge); - break; - case STMT_VAR: - log_err(info->ctx, - "Support for changing the default type has been removed; " - "Statement ignored\n"); - ok = true; - break; - case STMT_VMOD: - ok = HandleVModDef(info->ctx, &info->mods, (VModDef *) stmt, merge); - break; - default: - log_err(info->ctx, - "Key type files may not include other declarations; " - "Ignoring %s\n", stmt_type_to_string(stmt->type)); - ok = false; - break; - } - - if (!ok) - info->errorCount++; - - if (info->errorCount > 10) { - log_err(info->ctx, - "Abandoning keytypes file \"%s\"\n", file->name); - break; - } - } -} - -/***====================================================================***/ - -static bool -CopyKeyTypesToKeymap(struct xkb_keymap *keymap, KeyTypesInfo *info) -{ - unsigned num_types; - struct xkb_key_type *types; - - num_types = darray_empty(info->types) ? 1 : darray_size(info->types); - types = calloc(num_types, sizeof(*types)); - if (!types) - return false; - - /* - * If no types were specified, a default unnamed one-level type is - * used for all keys. - */ - if (darray_empty(info->types)) { - struct xkb_key_type *type = &types[0]; - - type->mods.mods = 0; - type->num_levels = 1; - type->entries = NULL; - type->num_entries = 0; - type->name = xkb_atom_intern_literal(keymap->ctx, "default"); - type->level_names = NULL; - type->num_level_names = 0; - } - else { - for (unsigned i = 0; i < num_types; i++) { - KeyTypeInfo *def = &darray_item(info->types, i); - struct xkb_key_type *type = &types[i]; - - type->name = def->name; - type->mods.mods = def->mods; - type->num_levels = def->num_levels; - darray_steal(def->level_names, &type->level_names, &type->num_level_names); - darray_steal(def->entries, &type->entries, &type->num_entries); - } - } - - keymap->types_section_name = strdup_safe(info->name); - XkbEscapeMapName(keymap->types_section_name); - keymap->num_types = num_types; - keymap->types = types; - keymap->mods = info->mods; - return true; -} - -/***====================================================================***/ - -bool -CompileKeyTypes(XkbFile *file, struct xkb_keymap *keymap, - enum merge_mode merge) -{ - KeyTypesInfo info; - - InitKeyTypesInfo(&info, keymap->ctx, &keymap->mods); - - HandleKeyTypesFile(&info, file, merge); - if (info.errorCount != 0) - goto err_info; - - if (!CopyKeyTypesToKeymap(keymap, &info)) - goto err_info; - - ClearKeyTypesInfo(&info); - return true; - -err_info: - ClearKeyTypesInfo(&info); - return false; -} diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/vmod.c b/src/3rdparty/xkbcommon/src/xkbcomp/vmod.c deleted file mode 100644 index a0b029af4f..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/vmod.c +++ /dev/null @@ -1,105 +0,0 @@ -/************************************************************ - * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting - * documentation, and that the name of Silicon Graphics not be - * used in advertising or publicity pertaining to distribution - * of the software without specific prior written permission. - * Silicon Graphics makes no representation about the suitability - * of this software for any purpose. It is provided "as is" - * without any express or implied warranty. - * - * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - * THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - ********************************************************/ - -#include "xkbcomp-priv.h" -#include "text.h" -#include "expr.h" -#include "vmod.h" - -bool -HandleVModDef(struct xkb_context *ctx, struct xkb_mod_set *mods, - VModDef *stmt, enum merge_mode merge) -{ - xkb_mod_index_t i; - struct xkb_mod *mod; - xkb_mod_mask_t mapping; - - merge = (merge == MERGE_DEFAULT ? stmt->merge : merge); - - if (stmt->value) { - /* - * This is a statement such as 'virtualModifiers NumLock = Mod1'; - * it sets the vmod-to-real-mod[s] mapping directly instead of going - * through modifier_map or some such. - */ - if (!ExprResolveModMask(ctx, stmt->value, MOD_REAL, mods, &mapping)) { - log_err(ctx, - "Declaration of %s ignored\n", - xkb_atom_text(ctx, stmt->name)); - return false; - } - } - else { - mapping = 0; - } - - xkb_mods_enumerate(i, mod, mods) { - if (mod->name == stmt->name) { - if (mod->type != MOD_VIRT) { - log_err(ctx, - "Can't add a virtual modifier named \"%s\"; " - "there is already a non-virtual modifier with this name! Ignored\n", - xkb_atom_text(ctx, mod->name)); - return false; - } - - if (mod->mapping == mapping) - return true; - - if (mod->mapping != 0) { - xkb_mod_mask_t use, ignore; - - use = (merge == MERGE_OVERRIDE ? mapping : mod->mapping); - ignore = (merge == MERGE_OVERRIDE ? mod->mapping : mapping); - - log_warn(ctx, - "Virtual modifier %s defined multiple times; " - "Using %s, ignoring %s\n", - xkb_atom_text(ctx, stmt->name), - ModMaskText(ctx, mods, use), - ModMaskText(ctx, mods, ignore)); - - mapping = use; - } - - mod->mapping = mapping; - return true; - } - } - - if (mods->num_mods >= XKB_MAX_MODS) { - log_err(ctx, - "Too many modifiers defined (maximum %d)\n", - XKB_MAX_MODS); - return false; - } - - mods->mods[mods->num_mods].name = stmt->name; - mods->mods[mods->num_mods].type = MOD_VIRT; - mods->mods[mods->num_mods].mapping = mapping; - mods->num_mods++; - return true; -} diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/vmod.h b/src/3rdparty/xkbcommon/src/xkbcomp/vmod.h deleted file mode 100644 index 546cf7ee42..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/vmod.h +++ /dev/null @@ -1,34 +0,0 @@ -/************************************************************ - * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting - * documentation, and that the name of Silicon Graphics not be - * used in advertising or publicity pertaining to distribution - * of the software without specific prior written permission. - * Silicon Graphics makes no representation about the suitability - * of this software for any purpose. It is provided "as is" - * without any express or implied warranty. - * - * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - * THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - ********************************************************/ - -#ifndef XKBCOMP_VMOD_H -#define XKBCOMP_VMOD_H - -bool -HandleVModDef(struct xkb_context *ctx, struct xkb_mod_set *mods, - VModDef *stmt, enum merge_mode merge); - -#endif diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp-keymap.c b/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp-keymap.c deleted file mode 100644 index e95e50c371..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp-keymap.c +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright © 2009 Dan Nicholson - * Copyright © 2012 Intel Corporation - * Copyright © 2012 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Dan Nicholson - * Daniel Stone - * Ran Benita - */ - -#include "xkbcomp-priv.h" - -static void -ComputeEffectiveMask(struct xkb_keymap *keymap, struct xkb_mods *mods) -{ - mods->mask = mod_mask_get_effective(keymap, mods->mods); -} - -static void -UpdateActionMods(struct xkb_keymap *keymap, union xkb_action *act, - xkb_mod_mask_t modmap) -{ - switch (act->type) { - case ACTION_TYPE_MOD_SET: - case ACTION_TYPE_MOD_LATCH: - case ACTION_TYPE_MOD_LOCK: - if (act->mods.flags & ACTION_MODS_LOOKUP_MODMAP) - act->mods.mods.mods = modmap; - ComputeEffectiveMask(keymap, &act->mods.mods); - break; - default: - break; - } -} - -static const struct xkb_sym_interpret default_interpret = { - .sym = XKB_KEY_NoSymbol, - .repeat = true, - .match = MATCH_ANY_OR_NONE, - .mods = 0, - .virtual_mod = XKB_MOD_INVALID, - .action = { .type = ACTION_TYPE_NONE }, -}; - -/** - * Find an interpretation which applies to this particular level, either by - * finding an exact match for the symbol and modifier combination, or a - * generic XKB_KEY_NoSymbol match. - */ -static const struct xkb_sym_interpret * -FindInterpForKey(struct xkb_keymap *keymap, const struct xkb_key *key, - xkb_layout_index_t group, xkb_level_index_t level) -{ - const xkb_keysym_t *syms; - int num_syms; - - num_syms = xkb_keymap_key_get_syms_by_level(keymap, key->keycode, group, - level, &syms); - if (num_syms == 0) - return NULL; - - /* - * There may be multiple matchings interprets; we should always return - * the most specific. Here we rely on compat.c to set up the - * sym_interprets array from the most specific to the least specific, - * such that when we find a match we return immediately. - */ - for (unsigned i = 0; i < keymap->num_sym_interprets; i++) { - const struct xkb_sym_interpret *interp = &keymap->sym_interprets[i]; - - xkb_mod_mask_t mods; - bool found = false; - - if ((num_syms > 1 || interp->sym != syms[0]) && - interp->sym != XKB_KEY_NoSymbol) - continue; - - if (interp->level_one_only && level != 0) - mods = 0; - else - mods = key->modmap; - - switch (interp->match) { - case MATCH_NONE: - found = !(interp->mods & mods); - break; - case MATCH_ANY_OR_NONE: - found = (!mods || (interp->mods & mods)); - break; - case MATCH_ANY: - found = (interp->mods & mods); - break; - case MATCH_ALL: - found = ((interp->mods & mods) == interp->mods); - break; - case MATCH_EXACTLY: - found = (interp->mods == mods); - break; - } - - if (found) - return interp; - } - - return &default_interpret; -} - -static bool -ApplyInterpsToKey(struct xkb_keymap *keymap, struct xkb_key *key) -{ - xkb_mod_mask_t vmodmap = 0; - xkb_layout_index_t group; - xkb_level_index_t level; - - /* If we've been told not to bind interps to this key, then don't. */ - if (key->explicit & EXPLICIT_INTERP) - return true; - - for (group = 0; group < key->num_groups; group++) { - for (level = 0; level < XkbKeyNumLevels(key, group); level++) { - const struct xkb_sym_interpret *interp; - - interp = FindInterpForKey(keymap, key, group, level); - if (!interp) - continue; - - /* Infer default key behaviours from the base level. */ - if (group == 0 && level == 0) - if (!(key->explicit & EXPLICIT_REPEAT) && interp->repeat) - key->repeats = true; - - if ((group == 0 && level == 0) || !interp->level_one_only) - if (interp->virtual_mod != XKB_MOD_INVALID) - vmodmap |= (1u << interp->virtual_mod); - - if (interp->action.type != ACTION_TYPE_NONE) - key->groups[group].levels[level].action = interp->action; - } - } - - if (!(key->explicit & EXPLICIT_VMODMAP)) - key->vmodmap = vmodmap; - - return true; -} - -/** - * This collects a bunch of disparate functions which was done in the server - * at various points that really should've been done within xkbcomp. Turns out - * your actions and types are a lot more useful when any of your modifiers - * other than Shift actually do something ... - */ -static bool -UpdateDerivedKeymapFields(struct xkb_keymap *keymap) -{ - struct xkb_key *key; - struct xkb_mod *mod; - struct xkb_led *led; - unsigned int i, j; - - /* Find all the interprets for the key and bind them to actions, - * which will also update the vmodmap. */ - xkb_keys_foreach(key, keymap) - if (!ApplyInterpsToKey(keymap, key)) - return false; - - /* Update keymap->mods, the virtual -> real mod mapping. */ - xkb_keys_foreach(key, keymap) - xkb_mods_enumerate(i, mod, &keymap->mods) - if (key->vmodmap & (1u << i)) - mod->mapping |= key->modmap; - - /* Now update the level masks for all the types to reflect the vmods. */ - for (i = 0; i < keymap->num_types; i++) { - ComputeEffectiveMask(keymap, &keymap->types[i].mods); - - for (j = 0; j < keymap->types[i].num_entries; j++) { - ComputeEffectiveMask(keymap, &keymap->types[i].entries[j].mods); - ComputeEffectiveMask(keymap, &keymap->types[i].entries[j].preserve); - } - } - - /* Update action modifiers. */ - xkb_keys_foreach(key, keymap) - for (i = 0; i < key->num_groups; i++) - for (j = 0; j < XkbKeyNumLevels(key, i); j++) - UpdateActionMods(keymap, &key->groups[i].levels[j].action, - key->modmap); - - /* Update vmod -> led maps. */ - xkb_leds_foreach(led, keymap) - ComputeEffectiveMask(keymap, &led->mods); - - /* Find maximum number of groups out of all keys in the keymap. */ - xkb_keys_foreach(key, keymap) - keymap->num_groups = MAX(keymap->num_groups, key->num_groups); - - return true; -} - -typedef bool (*compile_file_fn)(XkbFile *file, - struct xkb_keymap *keymap, - enum merge_mode merge); - -static const compile_file_fn compile_file_fns[LAST_KEYMAP_FILE_TYPE + 1] = { - [FILE_TYPE_KEYCODES] = CompileKeycodes, - [FILE_TYPE_TYPES] = CompileKeyTypes, - [FILE_TYPE_COMPAT] = CompileCompatMap, - [FILE_TYPE_SYMBOLS] = CompileSymbols, -}; - -bool -CompileKeymap(XkbFile *file, struct xkb_keymap *keymap, enum merge_mode merge) -{ - bool ok; - XkbFile *files[LAST_KEYMAP_FILE_TYPE + 1] = { NULL }; - enum xkb_file_type type; - struct xkb_context *ctx = keymap->ctx; - - /* Collect section files and check for duplicates. */ - for (file = (XkbFile *) file->defs; file; - file = (XkbFile *) file->common.next) { - if (file->file_type < FIRST_KEYMAP_FILE_TYPE || - file->file_type > LAST_KEYMAP_FILE_TYPE) { - if (file->file_type == FILE_TYPE_GEOMETRY) { - log_vrb(ctx, 1, - "Geometry sections are not supported; ignoring\n"); - } else { - log_err(ctx, "Cannot define %s in a keymap file\n", - xkb_file_type_to_string(file->file_type)); - } - continue; - } - - if (files[file->file_type]) { - log_err(ctx, - "More than one %s section in keymap file; " - "All sections after the first ignored\n", - xkb_file_type_to_string(file->file_type)); - continue; - } - - files[file->file_type] = file; - } - - /* - * Check that all required section were provided. - * Report everything before failing. - */ - ok = true; - for (type = FIRST_KEYMAP_FILE_TYPE; - type <= LAST_KEYMAP_FILE_TYPE; - type++) { - if (files[type] == NULL) { - log_err(ctx, "Required section %s missing from keymap\n", - xkb_file_type_to_string(type)); - ok = false; - } - } - if (!ok) - return false; - - /* Compile sections. */ - for (type = FIRST_KEYMAP_FILE_TYPE; - type <= LAST_KEYMAP_FILE_TYPE; - type++) { - log_dbg(ctx, "Compiling %s \"%s\"\n", - xkb_file_type_to_string(type), files[type]->name); - - ok = compile_file_fns[type](files[type], keymap, merge); - if (!ok) { - log_err(ctx, "Failed to compile %s\n", - xkb_file_type_to_string(type)); - return false; - } - } - - return UpdateDerivedKeymapFields(keymap); -} diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp-parser.c b/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp-parser.c deleted file mode 100644 index 520cc5b9c5..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp-parser.c +++ /dev/null @@ -1,3392 +0,0 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ - -/* Bison implementation for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Bison version. */ -#define YYBISON_VERSION "3.0.4" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 1 - -/* Push parsers. */ -#define YYPUSH 0 - -/* Pull parsers. */ -#define YYPULL 1 - - -/* Substitute the variable and function names. */ -#define yyparse _xkbcommon_parse -#define yylex _xkbcommon_lex -#define yyerror _xkbcommon_error -#define yydebug _xkbcommon_debug -#define yynerrs _xkbcommon_nerrs - - -/* Copy the first part of user declarations. */ -#line 33 "../src/xkbcomp/parser.y" /* yacc.c:339 */ - -#include "xkbcomp/xkbcomp-priv.h" -#include "xkbcomp/ast-build.h" -#include "xkbcomp/parser-priv.h" -#include "scanner-utils.h" - -struct parser_param { - struct xkb_context *ctx; - struct scanner *scanner; - XkbFile *rtrn; - bool more_maps; -}; - -#define parser_err(param, fmt, ...) \ - scanner_err((param)->scanner, fmt, ##__VA_ARGS__) - -#define parser_warn(param, fmt, ...) \ - scanner_warn((param)->scanner, fmt, ##__VA_ARGS__) - -static void -_xkbcommon_error(struct parser_param *param, const char *msg) -{ - parser_err(param, "%s", msg); -} - -static bool -resolve_keysym(const char *name, xkb_keysym_t *sym_rtrn) -{ - xkb_keysym_t sym; - - if (!name || istreq(name, "any") || istreq(name, "nosymbol")) { - *sym_rtrn = XKB_KEY_NoSymbol; - return true; - } - - if (istreq(name, "none") || istreq(name, "voidsymbol")) { - *sym_rtrn = XKB_KEY_VoidSymbol; - return true; - } - - sym = xkb_keysym_from_name(name, XKB_KEYSYM_NO_FLAGS); - if (sym != XKB_KEY_NoSymbol) { - *sym_rtrn = sym; - return true; - } - - return false; -} - -#define param_scanner param->scanner - -#line 124 "xkbcommon-internal@sta/parser.c" /* yacc.c:339 */ - -# ifndef YY_NULLPTR -# if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULLPTR nullptr -# else -# define YY_NULLPTR 0 -# endif -# endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -/* In a future release of Bison, this section will be replaced - by #include "parser.h". */ -#ifndef YY__XKBCOMMON_XKBCOMMON_INTERNAL_STA_PARSER_H_INCLUDED -# define YY__XKBCOMMON_XKBCOMMON_INTERNAL_STA_PARSER_H_INCLUDED -/* Debug traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int _xkbcommon_debug; -#endif - -/* Token type. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - enum yytokentype - { - END_OF_FILE = 0, - ERROR_TOK = 255, - XKB_KEYMAP = 1, - XKB_KEYCODES = 2, - XKB_TYPES = 3, - XKB_SYMBOLS = 4, - XKB_COMPATMAP = 5, - XKB_GEOMETRY = 6, - XKB_SEMANTICS = 7, - XKB_LAYOUT = 8, - INCLUDE = 10, - OVERRIDE = 11, - AUGMENT = 12, - REPLACE = 13, - ALTERNATE = 14, - VIRTUAL_MODS = 20, - TYPE = 21, - INTERPRET = 22, - ACTION_TOK = 23, - KEY = 24, - ALIAS = 25, - GROUP = 26, - MODIFIER_MAP = 27, - INDICATOR = 28, - SHAPE = 29, - KEYS = 30, - ROW = 31, - SECTION = 32, - OVERLAY = 33, - TEXT = 34, - OUTLINE = 35, - SOLID = 36, - LOGO = 37, - VIRTUAL = 38, - EQUALS = 40, - PLUS = 41, - MINUS = 42, - DIVIDE = 43, - TIMES = 44, - OBRACE = 45, - CBRACE = 46, - OPAREN = 47, - CPAREN = 48, - OBRACKET = 49, - CBRACKET = 50, - DOT = 51, - COMMA = 52, - SEMI = 53, - EXCLAM = 54, - INVERT = 55, - STRING = 60, - INTEGER = 61, - FLOAT = 62, - IDENT = 63, - KEYNAME = 64, - PARTIAL = 70, - DEFAULT = 71, - HIDDEN = 72, - ALPHANUMERIC_KEYS = 73, - MODIFIER_KEYS = 74, - KEYPAD_KEYS = 75, - FUNCTION_KEYS = 76, - ALTERNATE_GROUP = 77 - }; -#endif - -/* Value type. */ -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED - -union YYSTYPE -{ -#line 162 "../src/xkbcomp/parser.y" /* yacc.c:355 */ - - int ival; - int64_t num; - enum xkb_file_type file_type; - char *str; - xkb_atom_t atom; - enum merge_mode merge; - enum xkb_map_flags mapFlags; - xkb_keysym_t keysym; - ParseCommon *any; - ExprDef *expr; - VarDef *var; - VModDef *vmod; - InterpDef *interp; - KeyTypeDef *keyType; - SymbolsDef *syms; - ModMapDef *modMask; - GroupCompatDef *groupCompat; - LedMapDef *ledMap; - LedNameDef *ledName; - KeycodeDef *keyCode; - KeyAliasDef *keyAlias; - void *geom; - XkbFile *file; - -#line 256 "xkbcommon-internal@sta/parser.c" /* yacc.c:355 */ -}; - -typedef union YYSTYPE YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define YYSTYPE_IS_DECLARED 1 -#endif - - - -int _xkbcommon_parse (struct parser_param *param); - -#endif /* !YY__XKBCOMMON_XKBCOMMON_INTERNAL_STA_PARSER_H_INCLUDED */ - -/* Copy the second part of user declarations. */ - -#line 272 "xkbcommon-internal@sta/parser.c" /* yacc.c:358 */ - -#ifdef short -# undef short -#endif - -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#else -typedef signed char yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if defined YYENABLE_NLS && YYENABLE_NLS -# if ENABLE_NLS -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_(Msgid) dgettext ("bison-runtime", Msgid) -# endif -# endif -# ifndef YY_ -# define YY_(Msgid) Msgid -# endif -#endif - -#ifndef YY_ATTRIBUTE -# if (defined __GNUC__ \ - && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ - || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C -# define YY_ATTRIBUTE(Spec) __attribute__(Spec) -# else -# define YY_ATTRIBUTE(Spec) /* empty */ -# endif -#endif - -#ifndef YY_ATTRIBUTE_PURE -# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) -#endif - -#ifndef YY_ATTRIBUTE_UNUSED -# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) -#endif - -#if !defined _Noreturn \ - && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) -# if defined _MSC_VER && 1200 <= _MSC_VER -# define _Noreturn __declspec (noreturn) -# else -# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(E) ((void) (E)) -#else -# define YYUSE(E) /* empty */ -#endif - -#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ -/* Suppress an incorrect diagnostic about yylval being uninitialized. */ -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ - _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") -# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ - _Pragma ("GCC diagnostic pop") -#else -# define YY_INITIAL_VALUE(Value) Value -#endif -#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_END -#endif -#ifndef YY_INITIAL_VALUE -# define YY_INITIAL_VALUE(Value) /* Nothing. */ -#endif - - -#if ! defined yyoverflow || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS -# include /* INFRINGES ON USER NAME SPACE */ - /* Use EXIT_SUCCESS as a witness for stdlib.h. */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's 'empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined EXIT_SUCCESS \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined EXIT_SUCCESS -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined EXIT_SUCCESS -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss_alloc; - YYSTYPE yyvs_alloc; -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -# define YYCOPY_NEEDED 1 - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (0) - -#endif - -#if defined YYCOPY_NEEDED && YYCOPY_NEEDED -/* Copy COUNT objects from SRC to DST. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(Dst, Src, Count) \ - __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) -# else -# define YYCOPY(Dst, Src, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (Dst)[yyi] = (Src)[yyi]; \ - } \ - while (0) -# endif -# endif -#endif /* !YYCOPY_NEEDED */ - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 16 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 735 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 65 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 72 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 184 -/* YYNSTATES -- Number of states. */ -#define YYNSTATES 334 - -/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned - by yylex, with out-of-bounds checking. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 257 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM - as returned by yylex, without out-of-bounds checking. */ -static const yytype_uint8 yytranslate[] = -{ - 0, 4, 5, 6, 7, 8, 9, 10, 11, 2, - 12, 13, 14, 15, 16, 2, 2, 2, 2, 2, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 2, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 2, 2, 2, 2, - 52, 53, 54, 55, 56, 2, 2, 2, 2, 2, - 57, 58, 59, 60, 61, 62, 63, 64, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 3, 1, 2 -}; - -#if YYDEBUG - /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ -static const yytype_uint16 yyrline[] = -{ - 0, 241, 241, 243, 245, 249, 255, 256, 257, 260, - 268, 272, 280, 281, 282, 283, 284, 287, 288, 291, - 292, 295, 296, 297, 298, 299, 300, 301, 302, 305, - 307, 310, 315, 320, 325, 330, 335, 340, 345, 350, - 355, 360, 365, 366, 367, 368, 375, 377, 379, 383, - 387, 391, 395, 398, 402, 404, 408, 414, 416, 420, - 423, 427, 433, 439, 442, 444, 447, 448, 449, 450, - 451, 454, 456, 460, 464, 468, 472, 474, 478, 480, - 484, 488, 489, 492, 494, 496, 498, 500, 504, 505, - 508, 509, 513, 514, 517, 519, 523, 527, 528, 531, - 534, 536, 540, 542, 544, 548, 550, 554, 558, 562, - 563, 564, 565, 568, 569, 572, 574, 576, 578, 580, - 582, 584, 586, 588, 590, 592, 596, 597, 600, 601, - 602, 603, 604, 614, 615, 618, 621, 625, 627, 629, - 631, 633, 635, 639, 641, 643, 645, 647, 649, 651, - 653, 657, 660, 664, 668, 670, 672, 674, 678, 680, - 682, 684, 688, 689, 692, 694, 696, 698, 702, 706, - 712, 713, 733, 734, 737, 738, 741, 744, 747, 750, - 751, 754, 757, 758, 761 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || 0 -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "END_OF_FILE", "error", "$undefined", "ERROR_TOK", "XKB_KEYMAP", - "XKB_KEYCODES", "XKB_TYPES", "XKB_SYMBOLS", "XKB_COMPATMAP", - "XKB_GEOMETRY", "XKB_SEMANTICS", "XKB_LAYOUT", "INCLUDE", "OVERRIDE", - "AUGMENT", "REPLACE", "ALTERNATE", "VIRTUAL_MODS", "TYPE", "INTERPRET", - "ACTION_TOK", "KEY", "ALIAS", "GROUP", "MODIFIER_MAP", "INDICATOR", - "SHAPE", "KEYS", "ROW", "SECTION", "OVERLAY", "TEXT", "OUTLINE", "SOLID", - "LOGO", "VIRTUAL", "EQUALS", "PLUS", "MINUS", "DIVIDE", "TIMES", - "OBRACE", "CBRACE", "OPAREN", "CPAREN", "OBRACKET", "CBRACKET", "DOT", - "COMMA", "SEMI", "EXCLAM", "INVERT", "STRING", "INTEGER", "FLOAT", - "IDENT", "KEYNAME", "PARTIAL", "DEFAULT", "HIDDEN", "ALPHANUMERIC_KEYS", - "MODIFIER_KEYS", "KEYPAD_KEYS", "FUNCTION_KEYS", "ALTERNATE_GROUP", - "$accept", "XkbFile", "XkbCompositeMap", "XkbCompositeType", - "XkbMapConfigList", "XkbMapConfig", "FileType", "OptFlags", "Flags", - "Flag", "DeclList", "Decl", "VarDecl", "KeyNameDecl", "KeyAliasDecl", - "VModDecl", "VModDefList", "VModDef", "InterpretDecl", "InterpretMatch", - "VarDeclList", "KeyTypeDecl", "SymbolsDecl", "SymbolsBody", - "SymbolsVarDecl", "ArrayInit", "GroupCompatDecl", "ModMapDecl", - "LedMapDecl", "LedNameDecl", "ShapeDecl", "SectionDecl", "SectionBody", - "SectionBodyItem", "RowBody", "RowBodyItem", "Keys", "Key", - "OverlayDecl", "OverlayKeyList", "OverlayKey", "OutlineList", - "OutlineInList", "CoordList", "Coord", "DoodadDecl", "DoodadType", - "FieldSpec", "Element", "OptMergeMode", "MergeMode", "OptExprList", - "ExprList", "Expr", "Term", "ActionList", "Action", "Lhs", "Terminal", - "OptKeySymList", "KeySymList", "KeySyms", "KeySym", "SignedNumber", - "Number", "Float", "Integer", "KeyCode", "Ident", "String", "OptMapName", - "MapName", YY_NULLPTR -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[NUM] -- (External) token number corresponding to the - (internal) symbol number NUM (which must be that of a token). */ -static const yytype_uint16 yytoknum[] = -{ - 0, 256, 257, 255, 1, 2, 3, 4, 5, 6, - 7, 8, 10, 11, 12, 13, 14, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 60, 61, 62, 63, 64, 70, 71, 72, - 73, 74, 75, 76, 77 -}; -# endif - -#define YYPACT_NINF -182 - -#define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-182))) - -#define YYTABLE_NINF -180 - -#define yytable_value_is_error(Yytable_value) \ - 0 - - /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -static const yytype_int16 yypact[] = -{ - 176, -182, -182, -182, -182, -182, -182, -182, -182, -182, - 6, -182, -182, 271, 227, -182, -182, -182, -182, -182, - -182, -182, -182, -182, -182, -38, -38, -182, -182, -24, - -182, 33, 227, -182, 210, -182, 353, 44, 5, -182, - -182, -182, -182, -182, -182, 32, -182, 13, 41, -182, - -182, -48, 55, 11, -182, 79, 87, 58, -48, -2, - 55, -182, 55, 72, -182, -182, -182, 107, -48, -182, - 110, -182, -182, -182, -182, -182, -182, -182, -182, -182, - -182, -182, -182, -182, -182, -182, 55, -18, -182, 127, - 121, -182, 66, -182, 138, -182, 136, -182, -182, -182, - 144, 147, -182, 152, 180, 182, 178, 184, 187, 188, - 190, 58, 198, 201, 214, 367, 677, 367, -182, -48, - -182, 367, 663, 663, 367, 494, 200, 367, 367, 367, - 663, 68, 449, 223, -182, -182, 212, 663, -182, -182, - -182, -182, -182, -182, -182, -182, -182, 367, 367, 367, - 367, 367, -182, -182, 57, 157, -182, 224, -182, -182, - -182, -182, -182, 218, 91, -182, 333, -182, 509, 537, - 333, 552, -48, 1, -182, -182, 228, 40, 216, 143, - 70, 333, 150, 593, 247, -30, 97, -182, 105, -182, - 261, 55, 259, 55, -182, -182, 408, -182, -182, -182, - 367, -182, 608, -182, -182, -182, 287, -182, -182, 367, - 367, 367, 367, 367, -182, 367, 367, -182, 252, -182, - 253, 264, 24, 269, 272, 163, -182, 273, 270, -182, - -182, -182, 280, 494, 285, -182, -182, 283, 367, -182, - 284, 112, 8, -182, -182, 294, -182, 299, -36, 304, - 247, 326, 649, 279, 307, -182, 204, 316, -182, 322, - 320, 111, 111, -182, -182, 333, 211, -182, -182, 116, - 367, -182, 677, -182, 24, -182, -182, -182, 333, -182, - 333, -182, -182, -182, -30, -182, -182, -182, -182, 247, - 333, 334, -182, 466, -182, 318, -182, -182, -182, -182, - -182, -182, 339, -182, -182, -182, 343, 120, 14, 345, - -182, 361, 124, -182, -182, -182, -182, 367, -182, 131, - -182, -182, 344, 350, 318, 166, 352, 14, -182, -182, - -182, -182, -182, -182 -}; - - /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE does not specify something else to do. Zero - means the default is an error. */ -static const yytype_uint8 yydefact[] = -{ - 18, 4, 21, 22, 23, 24, 25, 26, 27, 28, - 0, 2, 3, 0, 17, 20, 1, 6, 12, 13, - 15, 14, 16, 7, 8, 183, 183, 19, 184, 0, - 182, 0, 18, 30, 18, 10, 0, 127, 0, 9, - 128, 130, 129, 131, 132, 0, 29, 0, 126, 5, - 11, 0, 117, 116, 115, 118, 0, 119, 120, 121, - 122, 123, 124, 125, 110, 111, 112, 0, 0, 179, - 0, 180, 31, 34, 35, 32, 33, 36, 37, 39, - 38, 40, 41, 42, 43, 44, 0, 154, 114, 0, - 113, 45, 0, 53, 54, 181, 0, 170, 177, 169, - 0, 58, 171, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 47, 0, - 51, 0, 0, 0, 0, 65, 0, 0, 0, 0, - 0, 0, 0, 0, 48, 178, 0, 0, 117, 116, - 118, 119, 120, 121, 122, 124, 125, 0, 0, 0, - 0, 0, 176, 161, 154, 0, 142, 147, 149, 160, - 159, 113, 158, 155, 0, 52, 55, 60, 0, 0, - 57, 163, 0, 0, 64, 70, 0, 113, 0, 0, - 0, 136, 0, 0, 0, 0, 0, 101, 0, 106, - 0, 121, 123, 0, 84, 86, 0, 82, 87, 85, - 0, 49, 0, 144, 147, 143, 0, 145, 146, 134, - 0, 0, 0, 0, 156, 0, 0, 46, 0, 59, - 0, 170, 0, 169, 0, 0, 152, 0, 162, 167, - 166, 69, 0, 0, 0, 50, 73, 0, 0, 76, - 0, 0, 0, 175, 174, 0, 173, 0, 0, 0, - 0, 0, 0, 0, 0, 81, 0, 0, 150, 0, - 133, 138, 139, 137, 140, 141, 0, 61, 56, 0, - 134, 72, 0, 71, 0, 62, 63, 67, 66, 74, - 135, 75, 102, 172, 0, 78, 100, 79, 105, 0, - 104, 0, 91, 0, 89, 0, 80, 77, 108, 148, - 157, 168, 0, 151, 165, 164, 0, 0, 0, 0, - 88, 0, 0, 98, 153, 107, 103, 0, 94, 0, - 93, 83, 0, 0, 0, 0, 0, 0, 99, 96, - 97, 95, 90, 92 -}; - - /* YYPGOTO[NTERM-NUM]. */ -static const yytype_int16 yypgoto[] = -{ - -182, -182, -182, -182, -182, 181, -182, 402, -182, 389, - -182, -182, -35, -182, -182, -182, -182, 288, -182, -182, - -50, -182, -182, -182, 173, 174, -182, -182, 362, -182, - -182, -182, -182, 215, -182, 119, -182, 86, -182, -182, - 90, -182, 167, -181, 185, 369, -182, -27, -182, -182, - -182, 154, -126, 83, 76, -182, 158, -31, -182, -182, - 221, 170, -52, 161, 205, -182, -44, -182, -47, -34, - 420, -182 -}; - - /* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int16 yydefgoto[] = -{ - -1, 10, 11, 25, 34, 12, 26, 36, 14, 15, - 37, 46, 167, 73, 74, 75, 92, 93, 76, 100, - 168, 77, 78, 173, 174, 175, 79, 80, 195, 82, - 83, 84, 196, 197, 293, 294, 319, 320, 198, 312, - 313, 186, 187, 188, 189, 199, 86, 154, 88, 47, - 48, 259, 260, 181, 156, 225, 226, 157, 158, 227, - 228, 229, 230, 245, 246, 159, 160, 136, 161, 162, - 29, 30 -}; - - /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule whose - number is the opposite. If YYTABLE_NINF, syntax error. */ -static const yytype_int16 yytable[] = -{ - 90, 101, 180, 241, 94, 184, 16, 69, 242, 102, - 71, 106, 72, 105, 28, 107, 89, 32, 96, 69, - 87, 112, 71, 243, 244, 108, 109, 115, 110, 116, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 97, 61, 62, 232, 63, 64, 65, 66, 67, 233, - 95, 98, 114, 97, 49, 317, 40, 41, 42, 43, - 44, 243, 244, 68, 98, 222, 99, 133, 69, 70, - 318, 71, 94, 169, 33, 90, 90, 98, 177, 99, - 183, 50, -68, 90, 190, 90, 45, 202, -68, 163, - 90, 89, 89, 91, 176, 87, 87, 194, 87, 89, - 209, 89, 115, 87, 116, 87, 89, 95, 307, 184, - 87, 98, 237, 185, 119, 120, 204, 204, 238, 204, - 204, 90, 90, 69, -109, 231, 71, 102, 210, 211, - 212, 213, 111, 219, 219, 103, 90, 89, 89, 247, - 217, 87, 87, 104, 224, 248, 113, 249, 219, 90, - 212, 213, 89, 250, 282, 90, 87, 108, 301, 253, - 250, 194, 316, 117, 274, 89, 323, 219, 250, 87, - 118, 89, 324, 326, 121, 87, 1, 122, 102, 327, - 210, 211, 212, 213, 124, 123, 177, 210, 211, 212, - 213, 325, 236, 125, 210, 211, 212, 213, 155, 239, - 164, 190, 176, 214, 166, 90, 87, 170, 331, 271, - 179, 272, 182, 35, 238, 39, 126, 292, 127, 128, - 129, 89, 305, 203, 205, 87, 207, 208, 130, 131, - 102, 132, 206, 2, 3, 4, 5, 6, 7, 8, - 9, 210, 211, 212, 213, 224, 90, 134, 210, 211, - 212, 213, 38, 297, 135, 137, 178, 300, 292, 200, - 215, 201, 89, 216, 234, 235, 87, 2, 3, 4, - 5, 6, 7, 8, 9, 17, 18, 19, 20, 21, - 22, 23, 24, 256, 2, 3, 4, 5, 6, 7, - 8, 9, 185, 261, 262, 263, 264, 251, 265, 266, - 252, 267, 268, 138, 139, 54, 140, -124, 141, 142, - 143, 144, -179, 61, 145, 270, 146, 278, 274, 273, - 295, 280, 147, 148, 210, 211, 212, 213, 149, 275, - 171, 258, 279, 281, 290, 150, 151, 95, 98, 152, - 69, 153, 284, 71, 138, 139, 54, 140, 285, 141, - 142, 143, 144, 287, 61, 145, 296, 146, 18, 19, - 20, 21, 22, 147, 148, 298, 299, 289, 238, 149, - 210, 211, 212, 213, 311, 308, 150, 151, 95, 98, - 152, 69, 153, 314, 71, 138, 139, 54, 140, 315, - 141, 142, 143, 144, 321, 61, 145, 322, 146, 329, - 328, 332, 13, 27, 147, 148, 276, 165, 277, 81, - 149, 255, 310, 333, 330, 286, 85, 150, 151, 95, - 98, 152, 69, 153, 302, 71, 138, 139, 54, 140, - 303, 141, 142, 191, 144, 288, 192, 145, 193, 63, - 64, 65, 66, 269, 304, 306, 31, 283, 0, 0, - 254, 0, 0, 0, 0, 0, 0, 0, 68, 0, - 0, 0, 0, 69, 0, 0, 71, 138, 139, 54, - 140, 0, 141, 142, 191, 144, 0, 192, 145, 193, - 63, 64, 65, 66, 138, 139, 54, 140, 0, 141, - 142, 143, 144, 291, 61, 145, 0, 146, 0, 68, - 0, 0, 0, 0, 69, 0, 0, 71, 309, 0, - 0, 0, 138, 139, 54, 140, 68, 141, 142, 143, - 144, 69, 61, 145, 71, 146, 0, 138, 139, 54, - 140, 0, 141, 142, 143, 144, 0, 61, 145, 171, - 146, 0, 0, 0, 172, 0, 0, 0, 0, 69, - 0, 218, 71, 0, 0, 138, 139, 54, 140, 68, - 141, 142, 143, 144, 69, 61, 145, 71, 146, 0, - 138, 139, 54, 140, 0, 141, 142, 143, 144, 220, - 61, 221, 0, 146, 0, 0, 0, 68, 0, 0, - 0, 0, 69, 222, 0, 71, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 98, 0, 223, 0, 0, - 71, 138, 139, 54, 140, 0, 141, 142, 143, 144, - 0, 61, 145, 0, 146, 0, 138, 139, 54, 140, - 0, 141, 142, 143, 144, 240, 61, 145, 0, 146, - 0, 0, 0, 68, 0, 0, 0, 0, 69, 0, - 257, 71, 0, 0, 0, 0, 0, 0, 68, 0, - 0, 0, 0, 69, 0, 0, 71, 138, 139, 54, - 140, 0, 141, 142, 143, 144, 291, 61, 145, 0, - 146, 138, 139, 54, 140, 0, 141, 142, 143, 144, - 0, 61, 145, 0, 146, 138, 139, 54, 140, 68, - 141, 142, 143, 144, 69, 61, 145, 71, 146, 0, - 0, 0, 0, 68, 0, 0, 0, 0, 69, 0, - 0, 71, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 69, 0, 0, 71 -}; - -static const yytype_int16 yycheck[] = -{ - 47, 53, 128, 184, 51, 41, 0, 55, 38, 53, - 58, 58, 47, 57, 52, 59, 47, 41, 52, 55, - 47, 68, 58, 53, 54, 59, 60, 45, 62, 47, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 29, 28, 29, 42, 31, 32, 33, 34, 35, 48, - 52, 53, 86, 29, 49, 41, 12, 13, 14, 15, - 16, 53, 54, 50, 53, 41, 55, 111, 55, 56, - 56, 58, 119, 123, 41, 122, 123, 53, 125, 55, - 130, 49, 42, 130, 131, 132, 42, 137, 48, 116, - 137, 122, 123, 52, 125, 122, 123, 132, 125, 130, - 43, 132, 45, 130, 47, 132, 137, 52, 289, 41, - 137, 53, 42, 45, 48, 49, 147, 148, 48, 150, - 151, 168, 169, 55, 52, 172, 58, 171, 37, 38, - 39, 40, 25, 168, 169, 56, 183, 168, 169, 42, - 49, 168, 169, 56, 171, 48, 36, 42, 183, 196, - 39, 40, 183, 48, 42, 202, 183, 191, 42, 193, - 48, 196, 42, 36, 48, 196, 42, 202, 48, 196, - 49, 202, 48, 42, 36, 202, 0, 41, 222, 48, - 37, 38, 39, 40, 37, 41, 233, 37, 38, 39, - 40, 317, 49, 41, 37, 38, 39, 40, 115, 49, - 117, 248, 233, 46, 121, 252, 233, 124, 42, 46, - 127, 48, 129, 32, 48, 34, 36, 252, 36, 41, - 36, 252, 274, 147, 148, 252, 150, 151, 41, 41, - 274, 41, 149, 57, 58, 59, 60, 61, 62, 63, - 64, 37, 38, 39, 40, 272, 293, 49, 37, 38, - 39, 40, 42, 49, 53, 41, 56, 46, 293, 36, - 36, 49, 293, 45, 36, 49, 293, 57, 58, 59, - 60, 61, 62, 63, 64, 4, 5, 6, 7, 8, - 9, 10, 11, 200, 57, 58, 59, 60, 61, 62, - 63, 64, 45, 210, 211, 212, 213, 36, 215, 216, - 41, 49, 49, 18, 19, 20, 21, 43, 23, 24, - 25, 26, 43, 28, 29, 43, 31, 234, 48, 46, - 41, 238, 37, 38, 37, 38, 39, 40, 43, 49, - 45, 44, 49, 49, 251, 50, 51, 52, 53, 54, - 55, 56, 48, 58, 18, 19, 20, 21, 49, 23, - 24, 25, 26, 49, 28, 29, 49, 31, 5, 6, - 7, 8, 9, 37, 38, 49, 44, 41, 48, 43, - 37, 38, 39, 40, 56, 41, 50, 51, 52, 53, - 54, 55, 56, 44, 58, 18, 19, 20, 21, 46, - 23, 24, 25, 26, 49, 28, 29, 36, 31, 49, - 56, 49, 0, 14, 37, 38, 233, 119, 234, 47, - 43, 196, 293, 327, 324, 248, 47, 50, 51, 52, - 53, 54, 55, 56, 270, 58, 18, 19, 20, 21, - 272, 23, 24, 25, 26, 250, 28, 29, 30, 31, - 32, 33, 34, 222, 274, 284, 26, 242, -1, -1, - 42, -1, -1, -1, -1, -1, -1, -1, 50, -1, - -1, -1, -1, 55, -1, -1, 58, 18, 19, 20, - 21, -1, 23, 24, 25, 26, -1, 28, 29, 30, - 31, 32, 33, 34, 18, 19, 20, 21, -1, 23, - 24, 25, 26, 27, 28, 29, -1, 31, -1, 50, - -1, -1, -1, -1, 55, -1, -1, 58, 42, -1, - -1, -1, 18, 19, 20, 21, 50, 23, 24, 25, - 26, 55, 28, 29, 58, 31, -1, 18, 19, 20, - 21, -1, 23, 24, 25, 26, -1, 28, 29, 45, - 31, -1, -1, -1, 50, -1, -1, -1, -1, 55, - -1, 42, 58, -1, -1, 18, 19, 20, 21, 50, - 23, 24, 25, 26, 55, 28, 29, 58, 31, -1, - 18, 19, 20, 21, -1, 23, 24, 25, 26, 42, - 28, 29, -1, 31, -1, -1, -1, 50, -1, -1, - -1, -1, 55, 41, -1, 58, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 53, -1, 55, -1, -1, - 58, 18, 19, 20, 21, -1, 23, 24, 25, 26, - -1, 28, 29, -1, 31, -1, 18, 19, 20, 21, - -1, 23, 24, 25, 26, 42, 28, 29, -1, 31, - -1, -1, -1, 50, -1, -1, -1, -1, 55, -1, - 42, 58, -1, -1, -1, -1, -1, -1, 50, -1, - -1, -1, -1, 55, -1, -1, 58, 18, 19, 20, - 21, -1, 23, 24, 25, 26, 27, 28, 29, -1, - 31, 18, 19, 20, 21, -1, 23, 24, 25, 26, - -1, 28, 29, -1, 31, 18, 19, 20, 21, 50, - 23, 24, 25, 26, 55, 28, 29, 58, 31, -1, - -1, -1, -1, 50, -1, -1, -1, -1, 55, -1, - -1, 58, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 55, -1, -1, 58 -}; - - /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint8 yystos[] = -{ - 0, 0, 57, 58, 59, 60, 61, 62, 63, 64, - 66, 67, 70, 72, 73, 74, 0, 4, 5, 6, - 7, 8, 9, 10, 11, 68, 71, 74, 52, 135, - 136, 135, 41, 41, 69, 70, 72, 75, 42, 70, - 12, 13, 14, 15, 16, 42, 76, 114, 115, 49, - 49, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 28, 29, 31, 32, 33, 34, 35, 50, 55, - 56, 58, 77, 78, 79, 80, 83, 86, 87, 91, - 92, 93, 94, 95, 96, 110, 111, 112, 113, 122, - 133, 52, 81, 82, 133, 52, 134, 29, 53, 55, - 84, 127, 131, 56, 56, 131, 133, 131, 134, 134, - 134, 25, 133, 36, 134, 45, 47, 36, 49, 48, - 49, 36, 41, 41, 37, 41, 36, 36, 41, 36, - 41, 41, 41, 131, 49, 53, 132, 41, 18, 19, - 21, 23, 24, 25, 26, 29, 31, 37, 38, 43, - 50, 51, 54, 56, 112, 118, 119, 122, 123, 130, - 131, 133, 134, 112, 118, 82, 118, 77, 85, 85, - 118, 45, 50, 88, 89, 90, 122, 133, 56, 118, - 117, 118, 118, 85, 41, 45, 106, 107, 108, 109, - 133, 25, 28, 30, 77, 93, 97, 98, 103, 110, - 36, 49, 85, 119, 122, 119, 118, 119, 119, 43, - 37, 38, 39, 40, 46, 36, 45, 49, 42, 77, - 42, 29, 41, 55, 112, 120, 121, 124, 125, 126, - 127, 133, 42, 48, 36, 49, 49, 42, 48, 49, - 42, 108, 38, 53, 54, 128, 129, 42, 48, 42, - 48, 36, 41, 134, 42, 98, 118, 42, 44, 116, - 117, 118, 118, 118, 118, 118, 118, 49, 49, 125, - 43, 46, 48, 46, 48, 49, 89, 90, 118, 49, - 118, 49, 42, 129, 48, 49, 107, 49, 109, 41, - 118, 27, 77, 99, 100, 41, 49, 49, 49, 44, - 46, 42, 116, 121, 126, 127, 128, 108, 41, 42, - 100, 56, 104, 105, 44, 46, 42, 41, 56, 101, - 102, 49, 36, 42, 48, 117, 42, 48, 56, 49, - 105, 42, 49, 102 -}; - - /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 0, 65, 66, 66, 66, 67, 68, 68, 68, 69, - 69, 70, 71, 71, 71, 71, 71, 72, 72, 73, - 73, 74, 74, 74, 74, 74, 74, 74, 74, 75, - 75, 76, 76, 76, 76, 76, 76, 76, 76, 76, - 76, 76, 76, 76, 76, 76, 77, 77, 77, 78, - 79, 80, 81, 81, 82, 82, 83, 84, 84, 85, - 85, 86, 87, 88, 88, 88, 89, 89, 89, 89, - 89, 90, 90, 91, 92, 93, 94, 94, 95, 95, - 96, 97, 97, 98, 98, 98, 98, 98, 99, 99, - 100, 100, 101, 101, 102, 102, 103, 104, 104, 105, - 106, 106, 107, 107, 107, 108, 108, 109, 110, 111, - 111, 111, 111, 112, 112, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 114, 114, 115, 115, - 115, 115, 115, 116, 116, 117, 117, 118, 118, 118, - 118, 118, 118, 119, 119, 119, 119, 119, 119, 119, - 119, 120, 120, 121, 122, 122, 122, 122, 123, 123, - 123, 123, 124, 124, 125, 125, 125, 125, 126, 127, - 127, 127, 128, 128, 129, 129, 130, 131, 132, 133, - 133, 134, 135, 135, 136 -}; - - /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 1, 1, 1, 7, 1, 1, 1, 2, - 1, 7, 1, 1, 1, 1, 1, 1, 0, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 4, 2, 3, 4, - 5, 3, 3, 1, 1, 3, 6, 3, 1, 2, - 1, 6, 6, 3, 1, 0, 3, 3, 1, 2, - 1, 3, 3, 5, 6, 6, 5, 6, 6, 6, - 6, 2, 1, 5, 1, 1, 1, 1, 2, 1, - 5, 1, 3, 1, 1, 3, 6, 3, 1, 3, - 3, 1, 3, 5, 3, 3, 1, 5, 6, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, - 1, 1, 1, 1, 0, 3, 1, 3, 3, 3, - 3, 3, 1, 2, 2, 2, 2, 1, 4, 1, - 3, 3, 1, 4, 1, 3, 4, 6, 1, 1, - 1, 1, 1, 0, 3, 3, 1, 1, 3, 1, - 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 0, 1 -}; - - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (param, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (0) - -/* Error token number */ -#define YYTERROR 1 -#define YYERRCODE 256 - - - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (0) - -/* This macro is provided for backward compatibility. */ -#ifndef YY_LOCATION_PRINT -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -#endif - - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value, param); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (0) - - -/*----------------------------------------. -| Print this symbol's value on YYOUTPUT. | -`----------------------------------------*/ - -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, struct parser_param *param) -{ - FILE *yyo = yyoutput; - YYUSE (yyo); - YYUSE (param); - if (!yyvaluep) - return; -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# endif - YYUSE (yytype); -} - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, struct parser_param *param) -{ - YYFPRINTF (yyoutput, "%s %s (", - yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); - - yy_symbol_value_print (yyoutput, yytype, yyvaluep, param); - YYFPRINTF (yyoutput, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (0) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -static void -yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, struct parser_param *param) -{ - unsigned long int yylno = yyrline[yyrule]; - int yynrhs = yyr2[yyrule]; - int yyi; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, - yystos[yyssp[yyi + 1 - yynrhs]], - &(yyvsp[(yyi + 1) - (yynrhs)]) - , param); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyssp, yyvsp, Rule, param); \ -} while (0) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -static YYSIZE_T -yystrlen (const char *yystr) -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif - -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -static char * -yystpcpy (char *yydest, const char *yysrc) -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message - about the unexpected token YYTOKEN for the state stack whose top is - YYSSP. - - Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is - not large enough to hold the message. In that case, also set - *YYMSG_ALLOC to the required number of bytes. Return 2 if the - required number of bytes is too large to store. */ -static int -yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - yytype_int16 *yyssp, int yytoken) -{ - YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); - YYSIZE_T yysize = yysize0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - /* Internationalized format string. */ - const char *yyformat = YY_NULLPTR; - /* Arguments of yyformat. */ - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - /* Number of reported tokens (one for the "unexpected", one per - "expected"). */ - int yycount = 0; - - /* There are many possibilities here to consider: - - If this state is a consistent state with a default action, then - the only way this function was invoked is if the default action - is an error action. In that case, don't check for expected - tokens because there are none. - - The only way there can be no lookahead present (in yychar) is if - this state is a consistent state with a default action. Thus, - detecting the absence of a lookahead is sufficient to determine - that there is no unexpected or expected token to report. In that - case, just report a simple "syntax error". - - Don't assume there isn't a lookahead just because this state is a - consistent state with a default action. There might have been a - previous inconsistent state, consistent state with a non-default - action, or user semantic action that manipulated yychar. - - Of course, the expected token list depends on states to have - correct lookahead information, and it depends on the parser not - to perform extra reductions after fetching a lookahead from the - scanner and before detecting a syntax error. Thus, state merging - (from LALR or IELR) and default reductions corrupt the expected - token list. However, the list is correct for canonical LR with - one exception: it will still contain any token that will not be - accepted due to an error action in a later state. - */ - if (yytoken != YYEMPTY) - { - int yyn = yypact[*yyssp]; - yyarg[yycount++] = yytname[yytoken]; - if (!yypact_value_is_default (yyn)) - { - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. In other words, skip the first -YYN actions for - this state because they are default actions. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yyx; - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR - && !yytable_value_is_error (yytable[yyx + yyn])) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - break; - } - yyarg[yycount++] = yytname[yyx]; - { - YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - } - } - } - - switch (yycount) - { -# define YYCASE_(N, S) \ - case N: \ - yyformat = S; \ - break - YYCASE_(0, YY_("syntax error")); - YYCASE_(1, YY_("syntax error, unexpected %s")); - YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); - YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); - YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); - YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); -# undef YYCASE_ - } - - { - YYSIZE_T yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - - if (*yymsg_alloc < yysize) - { - *yymsg_alloc = 2 * yysize; - if (! (yysize <= *yymsg_alloc - && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) - *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; - return 1; - } - - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - { - char *yyp = *yymsg; - int yyi = 0; - while ((*yyp = *yyformat) != '\0') - if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyformat += 2; - } - else - { - yyp++; - yyformat++; - } - } - return 0; -} -#endif /* YYERROR_VERBOSE */ - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, struct parser_param *param) -{ - YYUSE (yyvaluep); - YYUSE (param); - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - switch (yytype) - { - case 52: /* STRING */ -#line 225 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { free(((*yyvaluep).str)); } -#line 1429 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 55: /* IDENT */ -#line 225 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { free(((*yyvaluep).str)); } -#line 1435 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 66: /* XkbFile */ -#line 224 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { if (!param->rtrn) FreeXkbFile(((*yyvaluep).file)); } -#line 1441 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 67: /* XkbCompositeMap */ -#line 224 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { if (!param->rtrn) FreeXkbFile(((*yyvaluep).file)); } -#line 1447 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 69: /* XkbMapConfigList */ -#line 224 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { if (!param->rtrn) FreeXkbFile(((*yyvaluep).file)); } -#line 1453 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 70: /* XkbMapConfig */ -#line 224 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { if (!param->rtrn) FreeXkbFile(((*yyvaluep).file)); } -#line 1459 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 75: /* DeclList */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).any)); } -#line 1465 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 76: /* Decl */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).any)); } -#line 1471 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 77: /* VarDecl */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).var)); } -#line 1477 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 78: /* KeyNameDecl */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).keyCode)); } -#line 1483 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 79: /* KeyAliasDecl */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).keyAlias)); } -#line 1489 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 80: /* VModDecl */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).vmod)); } -#line 1495 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 81: /* VModDefList */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).vmod)); } -#line 1501 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 82: /* VModDef */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).vmod)); } -#line 1507 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 83: /* InterpretDecl */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).interp)); } -#line 1513 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 84: /* InterpretMatch */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).interp)); } -#line 1519 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 85: /* VarDeclList */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).var)); } -#line 1525 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 86: /* KeyTypeDecl */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).keyType)); } -#line 1531 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 87: /* SymbolsDecl */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).syms)); } -#line 1537 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 88: /* SymbolsBody */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).var)); } -#line 1543 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 89: /* SymbolsVarDecl */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).var)); } -#line 1549 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 90: /* ArrayInit */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).expr)); } -#line 1555 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 91: /* GroupCompatDecl */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).groupCompat)); } -#line 1561 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 92: /* ModMapDecl */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).modMask)); } -#line 1567 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 93: /* LedMapDecl */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).ledMap)); } -#line 1573 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 94: /* LedNameDecl */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).ledName)); } -#line 1579 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 108: /* CoordList */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).expr)); } -#line 1585 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 109: /* Coord */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).expr)); } -#line 1591 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 116: /* OptExprList */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).expr)); } -#line 1597 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 117: /* ExprList */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).expr)); } -#line 1603 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 118: /* Expr */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).expr)); } -#line 1609 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 119: /* Term */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).expr)); } -#line 1615 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 120: /* ActionList */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).expr)); } -#line 1621 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 121: /* Action */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).expr)); } -#line 1627 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 122: /* Lhs */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).expr)); } -#line 1633 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 123: /* Terminal */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).expr)); } -#line 1639 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 124: /* OptKeySymList */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).expr)); } -#line 1645 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 125: /* KeySymList */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).expr)); } -#line 1651 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 126: /* KeySyms */ -#line 219 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { FreeStmt((ParseCommon *) ((*yyvaluep).expr)); } -#line 1657 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 135: /* OptMapName */ -#line 225 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { free(((*yyvaluep).str)); } -#line 1663 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - case 136: /* MapName */ -#line 225 "../src/xkbcomp/parser.y" /* yacc.c:1257 */ - { free(((*yyvaluep).str)); } -#line 1669 "xkbcommon-internal@sta/parser.c" /* yacc.c:1257 */ - break; - - - default: - break; - } - YY_IGNORE_MAYBE_UNINITIALIZED_END -} - - - - -/*----------. -| yyparse. | -`----------*/ - -int -yyparse (struct parser_param *param) -{ -/* The lookahead symbol. */ -int yychar; - - -/* The semantic value of the lookahead symbol. */ -/* Default value used for initialization, for pacifying older GCCs - or non-GCC compilers. */ -YY_INITIAL_VALUE (static YYSTYPE yyval_default;) -YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); - - /* Number of syntax errors so far. */ - int yynerrs; - - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: - 'yyss': related to states. - 'yyvs': related to semantic values. - - Refer to the stacks through separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - - YYSIZE_T yystacksize; - - int yyn; - int yyresult; - /* Lookahead token as an internal (translated) token number. */ - int yytoken = 0; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - yyssp = yyss = yyssa; - yyvsp = yyvs = yyvsa; - yystacksize = YYINITDEPTH; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yystacksize); - - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - if (yystate == YYFINAL) - YYACCEPT; - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yypact_value_is_default (yyn)) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = yylex (&yylval, param_scanner); - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yytable_value_is_error (yyn)) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token. */ - yychar = YYEMPTY; - - yystate = yyn; - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - '$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: -#line 242 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.file) = param->rtrn = (yyvsp[0].file); param->more_maps = !!param->rtrn; } -#line 1937 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 3: -#line 244 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.file) = param->rtrn = (yyvsp[0].file); param->more_maps = !!param->rtrn; YYACCEPT; } -#line 1943 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 4: -#line 246 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.file) = param->rtrn = NULL; param->more_maps = false; } -#line 1949 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 5: -#line 252 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.file) = XkbFileCreate((yyvsp[-5].file_type), (yyvsp[-4].str), (ParseCommon *) (yyvsp[-2].file), (yyvsp[-6].mapFlags)); } -#line 1955 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 6: -#line 255 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.file_type) = FILE_TYPE_KEYMAP; } -#line 1961 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 7: -#line 256 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.file_type) = FILE_TYPE_KEYMAP; } -#line 1967 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 8: -#line 257 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.file_type) = FILE_TYPE_KEYMAP; } -#line 1973 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 9: -#line 261 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { - if (!(yyvsp[0].file)) - (yyval.file) = (yyvsp[-1].file); - else - (yyval.file) = (XkbFile *) AppendStmt((ParseCommon *) (yyvsp[-1].file), - (ParseCommon *) (yyvsp[0].file)); - } -#line 1985 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 10: -#line 269 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.file) = (yyvsp[0].file); } -#line 1991 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 11: -#line 275 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { - (yyval.file) = XkbFileCreate((yyvsp[-5].file_type), (yyvsp[-4].str), (yyvsp[-2].any), (yyvsp[-6].mapFlags)); - } -#line 1999 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 12: -#line 280 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.file_type) = FILE_TYPE_KEYCODES; } -#line 2005 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 13: -#line 281 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.file_type) = FILE_TYPE_TYPES; } -#line 2011 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 14: -#line 282 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.file_type) = FILE_TYPE_COMPAT; } -#line 2017 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 15: -#line 283 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.file_type) = FILE_TYPE_SYMBOLS; } -#line 2023 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 16: -#line 284 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.file_type) = FILE_TYPE_GEOMETRY; } -#line 2029 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 17: -#line 287 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.mapFlags) = (yyvsp[0].mapFlags); } -#line 2035 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 18: -#line 288 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.mapFlags) = 0; } -#line 2041 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 19: -#line 291 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.mapFlags) = ((yyvsp[-1].mapFlags) | (yyvsp[0].mapFlags)); } -#line 2047 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 20: -#line 292 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.mapFlags) = (yyvsp[0].mapFlags); } -#line 2053 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 21: -#line 295 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.mapFlags) = MAP_IS_PARTIAL; } -#line 2059 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 22: -#line 296 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.mapFlags) = MAP_IS_DEFAULT; } -#line 2065 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 23: -#line 297 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.mapFlags) = MAP_IS_HIDDEN; } -#line 2071 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 24: -#line 298 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.mapFlags) = MAP_HAS_ALPHANUMERIC; } -#line 2077 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 25: -#line 299 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.mapFlags) = MAP_HAS_MODIFIER; } -#line 2083 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 26: -#line 300 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.mapFlags) = MAP_HAS_KEYPAD; } -#line 2089 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 27: -#line 301 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.mapFlags) = MAP_HAS_FN; } -#line 2095 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 28: -#line 302 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.mapFlags) = MAP_IS_ALTGR; } -#line 2101 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 29: -#line 306 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.any) = AppendStmt((yyvsp[-1].any), (yyvsp[0].any)); } -#line 2107 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 30: -#line 307 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.any) = NULL; } -#line 2113 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 31: -#line 311 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { - (yyvsp[0].var)->merge = (yyvsp[-1].merge); - (yyval.any) = (ParseCommon *) (yyvsp[0].var); - } -#line 2122 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 32: -#line 316 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { - (yyvsp[0].vmod)->merge = (yyvsp[-1].merge); - (yyval.any) = (ParseCommon *) (yyvsp[0].vmod); - } -#line 2131 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 33: -#line 321 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { - (yyvsp[0].interp)->merge = (yyvsp[-1].merge); - (yyval.any) = (ParseCommon *) (yyvsp[0].interp); - } -#line 2140 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 34: -#line 326 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { - (yyvsp[0].keyCode)->merge = (yyvsp[-1].merge); - (yyval.any) = (ParseCommon *) (yyvsp[0].keyCode); - } -#line 2149 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 35: -#line 331 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { - (yyvsp[0].keyAlias)->merge = (yyvsp[-1].merge); - (yyval.any) = (ParseCommon *) (yyvsp[0].keyAlias); - } -#line 2158 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 36: -#line 336 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { - (yyvsp[0].keyType)->merge = (yyvsp[-1].merge); - (yyval.any) = (ParseCommon *) (yyvsp[0].keyType); - } -#line 2167 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 37: -#line 341 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { - (yyvsp[0].syms)->merge = (yyvsp[-1].merge); - (yyval.any) = (ParseCommon *) (yyvsp[0].syms); - } -#line 2176 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 38: -#line 346 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { - (yyvsp[0].modMask)->merge = (yyvsp[-1].merge); - (yyval.any) = (ParseCommon *) (yyvsp[0].modMask); - } -#line 2185 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 39: -#line 351 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { - (yyvsp[0].groupCompat)->merge = (yyvsp[-1].merge); - (yyval.any) = (ParseCommon *) (yyvsp[0].groupCompat); - } -#line 2194 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 40: -#line 356 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { - (yyvsp[0].ledMap)->merge = (yyvsp[-1].merge); - (yyval.any) = (ParseCommon *) (yyvsp[0].ledMap); - } -#line 2203 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 41: -#line 361 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { - (yyvsp[0].ledName)->merge = (yyvsp[-1].merge); - (yyval.any) = (ParseCommon *) (yyvsp[0].ledName); - } -#line 2212 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 42: -#line 365 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.any) = NULL; } -#line 2218 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 43: -#line 366 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.any) = NULL; } -#line 2224 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 44: -#line 367 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.any) = NULL; } -#line 2230 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 45: -#line 369 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { - (yyval.any) = (ParseCommon *) IncludeCreate(param->ctx, (yyvsp[0].str), (yyvsp[-1].merge)); - free((yyvsp[0].str)); - } -#line 2239 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 46: -#line 376 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.var) = VarCreate((yyvsp[-3].expr), (yyvsp[-1].expr)); } -#line 2245 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 47: -#line 378 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.var) = BoolVarCreate((yyvsp[-1].atom), true); } -#line 2251 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 48: -#line 380 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.var) = BoolVarCreate((yyvsp[-1].atom), false); } -#line 2257 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 49: -#line 384 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.keyCode) = KeycodeCreate((yyvsp[-3].atom), (yyvsp[-1].num)); } -#line 2263 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 50: -#line 388 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.keyAlias) = KeyAliasCreate((yyvsp[-3].atom), (yyvsp[-1].atom)); } -#line 2269 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 51: -#line 392 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.vmod) = (yyvsp[-1].vmod); } -#line 2275 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 52: -#line 396 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.vmod) = (VModDef *) AppendStmt((ParseCommon *) (yyvsp[-2].vmod), - (ParseCommon *) (yyvsp[0].vmod)); } -#line 2282 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 53: -#line 399 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.vmod) = (yyvsp[0].vmod); } -#line 2288 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 54: -#line 403 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.vmod) = VModCreate((yyvsp[0].atom), NULL); } -#line 2294 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 55: -#line 405 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.vmod) = VModCreate((yyvsp[-2].atom), (yyvsp[0].expr)); } -#line 2300 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 56: -#line 411 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyvsp[-4].interp)->def = (yyvsp[-2].var); (yyval.interp) = (yyvsp[-4].interp); } -#line 2306 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 57: -#line 415 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.interp) = InterpCreate((yyvsp[-2].keysym), (yyvsp[0].expr)); } -#line 2312 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 58: -#line 417 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.interp) = InterpCreate((yyvsp[0].keysym), NULL); } -#line 2318 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 59: -#line 421 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.var) = (VarDef *) AppendStmt((ParseCommon *) (yyvsp[-1].var), - (ParseCommon *) (yyvsp[0].var)); } -#line 2325 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 60: -#line 424 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.var) = (yyvsp[0].var); } -#line 2331 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 61: -#line 430 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.keyType) = KeyTypeCreate((yyvsp[-4].atom), (yyvsp[-2].var)); } -#line 2337 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 62: -#line 436 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.syms) = SymbolsCreate((yyvsp[-4].atom), (yyvsp[-2].var)); } -#line 2343 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 63: -#line 440 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.var) = (VarDef *) AppendStmt((ParseCommon *) (yyvsp[-2].var), - (ParseCommon *) (yyvsp[0].var)); } -#line 2350 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 64: -#line 443 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.var) = (yyvsp[0].var); } -#line 2356 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 65: -#line 444 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.var) = NULL; } -#line 2362 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 66: -#line 447 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.var) = VarCreate((yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 2368 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 67: -#line 448 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.var) = VarCreate((yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 2374 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 68: -#line 449 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.var) = BoolVarCreate((yyvsp[0].atom), true); } -#line 2380 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 69: -#line 450 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.var) = BoolVarCreate((yyvsp[0].atom), false); } -#line 2386 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 70: -#line 451 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.var) = VarCreate(NULL, (yyvsp[0].expr)); } -#line 2392 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 71: -#line 455 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = (yyvsp[-1].expr); } -#line 2398 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 72: -#line 457 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = ExprCreateUnary(EXPR_ACTION_LIST, EXPR_TYPE_ACTION, (yyvsp[-1].expr)); } -#line 2404 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 73: -#line 461 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.groupCompat) = GroupCompatCreate((yyvsp[-3].ival), (yyvsp[-1].expr)); } -#line 2410 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 74: -#line 465 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.modMask) = ModMapCreate((yyvsp[-4].atom), (yyvsp[-2].expr)); } -#line 2416 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 75: -#line 469 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.ledMap) = LedMapCreate((yyvsp[-4].atom), (yyvsp[-2].var)); } -#line 2422 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 76: -#line 473 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.ledName) = LedNameCreate((yyvsp[-3].ival), (yyvsp[-1].expr), false); } -#line 2428 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 77: -#line 475 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.ledName) = LedNameCreate((yyvsp[-3].ival), (yyvsp[-1].expr), true); } -#line 2434 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 78: -#line 479 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.geom) = NULL; } -#line 2440 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 79: -#line 481 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (void) (yyvsp[-2].expr); (yyval.geom) = NULL; } -#line 2446 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 80: -#line 485 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.geom) = NULL; } -#line 2452 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 81: -#line 488 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.geom) = NULL;} -#line 2458 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 82: -#line 489 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.geom) = NULL; } -#line 2464 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 83: -#line 493 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.geom) = NULL; } -#line 2470 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 84: -#line 495 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { FreeStmt((ParseCommon *) (yyvsp[0].var)); (yyval.geom) = NULL; } -#line 2476 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 85: -#line 497 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.geom) = NULL; } -#line 2482 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 86: -#line 499 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { FreeStmt((ParseCommon *) (yyvsp[0].ledMap)); (yyval.geom) = NULL; } -#line 2488 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 87: -#line 501 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.geom) = NULL; } -#line 2494 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 88: -#line 504 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.geom) = NULL;} -#line 2500 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 89: -#line 505 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.geom) = NULL; } -#line 2506 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 90: -#line 508 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.geom) = NULL; } -#line 2512 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 91: -#line 510 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { FreeStmt((ParseCommon *) (yyvsp[0].var)); (yyval.geom) = NULL; } -#line 2518 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 92: -#line 513 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.geom) = NULL; } -#line 2524 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 93: -#line 514 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.geom) = NULL; } -#line 2530 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 94: -#line 518 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.geom) = NULL; } -#line 2536 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 95: -#line 520 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { FreeStmt((ParseCommon *) (yyvsp[-1].expr)); (yyval.geom) = NULL; } -#line 2542 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 96: -#line 524 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.geom) = NULL; } -#line 2548 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 97: -#line 527 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.geom) = NULL; } -#line 2554 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 98: -#line 528 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.geom) = NULL; } -#line 2560 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 99: -#line 531 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.geom) = NULL; } -#line 2566 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 100: -#line 535 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.geom) = NULL;} -#line 2572 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 101: -#line 537 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.geom) = NULL; } -#line 2578 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 102: -#line 541 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (void) (yyvsp[-1].expr); (yyval.geom) = NULL; } -#line 2584 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 103: -#line 543 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (void) (yyvsp[-1].expr); (yyval.geom) = NULL; } -#line 2590 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 104: -#line 545 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { FreeStmt((ParseCommon *) (yyvsp[0].expr)); (yyval.geom) = NULL; } -#line 2596 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 105: -#line 549 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (void) (yyvsp[-2].expr); (void) (yyvsp[0].expr); (yyval.expr) = NULL; } -#line 2602 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 106: -#line 551 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (void) (yyvsp[0].expr); (yyval.expr) = NULL; } -#line 2608 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 107: -#line 555 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = NULL; } -#line 2614 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 108: -#line 559 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { FreeStmt((ParseCommon *) (yyvsp[-2].var)); (yyval.geom) = NULL; } -#line 2620 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 109: -#line 562 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.ival) = 0; } -#line 2626 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 110: -#line 563 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.ival) = 0; } -#line 2632 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 111: -#line 564 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.ival) = 0; } -#line 2638 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 112: -#line 565 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.ival) = 0; } -#line 2644 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 113: -#line 568 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.atom) = (yyvsp[0].atom); } -#line 2650 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 114: -#line 569 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.atom) = (yyvsp[0].atom); } -#line 2656 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 115: -#line 573 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.atom) = xkb_atom_intern_literal(param->ctx, "action"); } -#line 2662 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 116: -#line 575 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.atom) = xkb_atom_intern_literal(param->ctx, "interpret"); } -#line 2668 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 117: -#line 577 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.atom) = xkb_atom_intern_literal(param->ctx, "type"); } -#line 2674 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 118: -#line 579 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.atom) = xkb_atom_intern_literal(param->ctx, "key"); } -#line 2680 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 119: -#line 581 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.atom) = xkb_atom_intern_literal(param->ctx, "group"); } -#line 2686 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 120: -#line 583 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - {(yyval.atom) = xkb_atom_intern_literal(param->ctx, "modifier_map");} -#line 2692 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 121: -#line 585 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.atom) = xkb_atom_intern_literal(param->ctx, "indicator"); } -#line 2698 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 122: -#line 587 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.atom) = xkb_atom_intern_literal(param->ctx, "shape"); } -#line 2704 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 123: -#line 589 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.atom) = xkb_atom_intern_literal(param->ctx, "row"); } -#line 2710 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 124: -#line 591 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.atom) = xkb_atom_intern_literal(param->ctx, "section"); } -#line 2716 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 125: -#line 593 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.atom) = xkb_atom_intern_literal(param->ctx, "text"); } -#line 2722 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 126: -#line 596 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.merge) = (yyvsp[0].merge); } -#line 2728 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 127: -#line 597 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.merge) = MERGE_DEFAULT; } -#line 2734 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 128: -#line 600 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.merge) = MERGE_DEFAULT; } -#line 2740 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 129: -#line 601 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.merge) = MERGE_AUGMENT; } -#line 2746 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 130: -#line 602 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.merge) = MERGE_OVERRIDE; } -#line 2752 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 131: -#line 603 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.merge) = MERGE_REPLACE; } -#line 2758 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 132: -#line 605 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { - /* - * This used to be MERGE_ALT_FORM. This functionality was - * unused and has been removed. - */ - (yyval.merge) = MERGE_DEFAULT; - } -#line 2770 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 133: -#line 614 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = (yyvsp[0].expr); } -#line 2776 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 134: -#line 615 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = NULL; } -#line 2782 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 135: -#line 619 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = (ExprDef *) AppendStmt((ParseCommon *) (yyvsp[-2].expr), - (ParseCommon *) (yyvsp[0].expr)); } -#line 2789 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 136: -#line 622 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = (yyvsp[0].expr); } -#line 2795 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 137: -#line 626 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = ExprCreateBinary(EXPR_DIVIDE, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 2801 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 138: -#line 628 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = ExprCreateBinary(EXPR_ADD, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 2807 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 139: -#line 630 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = ExprCreateBinary(EXPR_SUBTRACT, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 2813 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 140: -#line 632 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = ExprCreateBinary(EXPR_MULTIPLY, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 2819 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 141: -#line 634 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = ExprCreateBinary(EXPR_ASSIGN, (yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 2825 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 142: -#line 636 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = (yyvsp[0].expr); } -#line 2831 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 143: -#line 640 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = ExprCreateUnary(EXPR_NEGATE, (yyvsp[0].expr)->expr.value_type, (yyvsp[0].expr)); } -#line 2837 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 144: -#line 642 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = ExprCreateUnary(EXPR_UNARY_PLUS, (yyvsp[0].expr)->expr.value_type, (yyvsp[0].expr)); } -#line 2843 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 145: -#line 644 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = ExprCreateUnary(EXPR_NOT, EXPR_TYPE_BOOLEAN, (yyvsp[0].expr)); } -#line 2849 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 146: -#line 646 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = ExprCreateUnary(EXPR_INVERT, (yyvsp[0].expr)->expr.value_type, (yyvsp[0].expr)); } -#line 2855 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 147: -#line 648 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = (yyvsp[0].expr); } -#line 2861 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 148: -#line 650 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = ExprCreateAction((yyvsp[-3].atom), (yyvsp[-1].expr)); } -#line 2867 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 149: -#line 652 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = (yyvsp[0].expr); } -#line 2873 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 150: -#line 654 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = (yyvsp[-1].expr); } -#line 2879 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 151: -#line 658 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = (ExprDef *) AppendStmt((ParseCommon *) (yyvsp[-2].expr), - (ParseCommon *) (yyvsp[0].expr)); } -#line 2886 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 152: -#line 661 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = (yyvsp[0].expr); } -#line 2892 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 153: -#line 665 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = ExprCreateAction((yyvsp[-3].atom), (yyvsp[-1].expr)); } -#line 2898 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 154: -#line 669 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = ExprCreateIdent((yyvsp[0].atom)); } -#line 2904 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 155: -#line 671 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = ExprCreateFieldRef((yyvsp[-2].atom), (yyvsp[0].atom)); } -#line 2910 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 156: -#line 673 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = ExprCreateArrayRef(XKB_ATOM_NONE, (yyvsp[-3].atom), (yyvsp[-1].expr)); } -#line 2916 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 157: -#line 675 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = ExprCreateArrayRef((yyvsp[-5].atom), (yyvsp[-3].atom), (yyvsp[-1].expr)); } -#line 2922 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 158: -#line 679 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = ExprCreateString((yyvsp[0].atom)); } -#line 2928 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 159: -#line 681 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = ExprCreateInteger((yyvsp[0].ival)); } -#line 2934 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 160: -#line 683 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = ExprCreateFloat(/* Discard $1 */); } -#line 2940 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 161: -#line 685 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = ExprCreateKeyName((yyvsp[0].atom)); } -#line 2946 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 162: -#line 688 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = (yyvsp[0].expr); } -#line 2952 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 163: -#line 689 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = NULL; } -#line 2958 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 164: -#line 693 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = ExprAppendKeysymList((yyvsp[-2].expr), (yyvsp[0].keysym)); } -#line 2964 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 165: -#line 695 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = ExprAppendMultiKeysymList((yyvsp[-2].expr), (yyvsp[0].expr)); } -#line 2970 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 166: -#line 697 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = ExprCreateKeysymList((yyvsp[0].keysym)); } -#line 2976 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 167: -#line 699 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = ExprCreateMultiKeysymList((yyvsp[0].expr)); } -#line 2982 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 168: -#line 703 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.expr) = (yyvsp[-1].expr); } -#line 2988 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 169: -#line 707 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { - if (!resolve_keysym((yyvsp[0].str), &(yyval.keysym))) - parser_warn(param, "unrecognized keysym \"%s\"", (yyvsp[0].str)); - free((yyvsp[0].str)); - } -#line 2998 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 170: -#line 712 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.keysym) = XKB_KEY_section; } -#line 3004 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 171: -#line 714 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { - if ((yyvsp[0].ival) < 0) { - parser_warn(param, "unrecognized keysym \"%d\"", (yyvsp[0].ival)); - (yyval.keysym) = XKB_KEY_NoSymbol; - } - else if ((yyvsp[0].ival) < 10) { /* XKB_KEY_0 .. XKB_KEY_9 */ - (yyval.keysym) = XKB_KEY_0 + (xkb_keysym_t) (yyvsp[0].ival); - } - else { - char buf[17]; - snprintf(buf, sizeof(buf), "0x%x", (yyvsp[0].ival)); - if (!resolve_keysym(buf, &(yyval.keysym))) { - parser_warn(param, "unrecognized keysym \"%s\"", buf); - (yyval.keysym) = XKB_KEY_NoSymbol; - } - } - } -#line 3026 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 172: -#line 733 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.ival) = -(yyvsp[0].ival); } -#line 3032 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 173: -#line 734 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.ival) = (yyvsp[0].ival); } -#line 3038 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 174: -#line 737 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.ival) = (yyvsp[0].num); } -#line 3044 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 175: -#line 738 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.ival) = (yyvsp[0].num); } -#line 3050 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 176: -#line 741 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.ival) = 0; } -#line 3056 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 177: -#line 744 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.ival) = (yyvsp[0].num); } -#line 3062 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 178: -#line 747 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.num) = (yyvsp[0].num); } -#line 3068 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 179: -#line 750 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.atom) = xkb_atom_steal(param->ctx, (yyvsp[0].str)); } -#line 3074 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 180: -#line 751 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.atom) = xkb_atom_intern_literal(param->ctx, "default"); } -#line 3080 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 181: -#line 754 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.atom) = xkb_atom_steal(param->ctx, (yyvsp[0].str)); } -#line 3086 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 182: -#line 757 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 3092 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 183: -#line 758 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.str) = NULL; } -#line 3098 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - case 184: -#line 761 "../src/xkbcomp/parser.y" /* yacc.c:1646 */ - { (yyval.str) = (yyvsp[0].str); } -#line 3104 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - break; - - -#line 3108 "xkbcommon-internal@sta/parser.c" /* yacc.c:1646 */ - default: break; - } - /* User semantic actions sometimes alter yychar, and that requires - that yytoken be updated with the new translation. We take the - approach of translating immediately before every use of yytoken. - One alternative is translating here after every semantic action, - but that translation would be missed if the semantic action invokes - YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or - if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an - incorrect destructor might then be invoked immediately. In the - case of YYERROR or YYBACKUP, subsequent parser actions might lead - to an incorrect destructor call or verbose syntax error message - before the lookahead is translated. */ - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - - /* Now 'shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*--------------------------------------. -| yyerrlab -- here on detecting error. | -`--------------------------------------*/ -yyerrlab: - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); - - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (param, YY_("syntax error")); -#else -# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ - yyssp, yytoken) - { - char const *yymsgp = YY_("syntax error"); - int yysyntax_error_status; - yysyntax_error_status = YYSYNTAX_ERROR; - if (yysyntax_error_status == 0) - yymsgp = yymsg; - else if (yysyntax_error_status == 1) - { - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); - if (!yymsg) - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - yysyntax_error_status = 2; - } - else - { - yysyntax_error_status = YYSYNTAX_ERROR; - yymsgp = yymsg; - } - } - yyerror (param, yymsgp); - if (yysyntax_error_status == 2) - goto yyexhaustedlab; - } -# undef YYSYNTAX_ERROR -#endif - } - - - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval, param); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - - /* Do not reclaim the symbols of the rule whose action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (!yypact_value_is_default (yyn)) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - - yydestruct ("Error: popping", - yystos[yystate], yyvsp, param); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#if !defined yyoverflow || YYERROR_VERBOSE -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (param, YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEMPTY) - { - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = YYTRANSLATE (yychar); - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval, param); - } - /* Do not reclaim the symbols of the rule whose action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp, param); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - return yyresult; -} -#line 764 "../src/xkbcomp/parser.y" /* yacc.c:1906 */ - - -XkbFile * -parse(struct xkb_context *ctx, struct scanner *scanner, const char *map) -{ - int ret; - XkbFile *first = NULL; - struct parser_param param = { - .scanner = scanner, - .ctx = ctx, - .rtrn = NULL, - .more_maps = false, - }; - - /* - * If we got a specific map, we look for it exclusively and return - * immediately upon finding it. Otherwise, we need to get the - * default map. If we find a map marked as default, we return it - * immediately. If there are no maps marked as default, we return - * the first map in the file. - */ - - while ((ret = yyparse(¶m)) == 0 && param.more_maps) { - if (map) { - if (streq_not_null(map, param.rtrn->name)) - return param.rtrn; - else - FreeXkbFile(param.rtrn); - } - else { - if (param.rtrn->flags & MAP_IS_DEFAULT) { - FreeXkbFile(first); - return param.rtrn; - } - else if (!first) { - first = param.rtrn; - } - else { - FreeXkbFile(param.rtrn); - } - } - param.rtrn = NULL; - } - - if (ret != 0) { - FreeXkbFile(first); - return NULL; - } - - if (first) - log_vrb(ctx, 5, - "No map in include statement, but \"%s\" contains several; " - "Using first defined map, \"%s\"\n", - scanner->file_name, first->name); - - return first; -} diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp-priv.h b/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp-priv.h deleted file mode 100644 index 6cb774da17..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp-priv.h +++ /dev/null @@ -1,124 +0,0 @@ -/************************************************************ - * Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting - * documentation, and that the name of Silicon Graphics not be - * used in advertising or publicity pertaining to distribution - * of the software without specific prior written permission. - * Silicon Graphics makes no representation about the suitability - * of this software for any purpose. It is provided "as is" - * without any express or implied warranty. - * - * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - * THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - ********************************************************/ - -#ifndef XKBCOMP_PRIV_H -#define XKBCOMP_PRIV_H - -#include "keymap.h" -#include "ast.h" - -struct xkb_component_names { - char *keycodes; - char *types; - char *compat; - char *symbols; -}; - -char * -text_v1_keymap_get_as_string(struct xkb_keymap *keymap); - -XkbFile * -XkbParseFile(struct xkb_context *ctx, FILE *file, - const char *file_name, const char *map); - -XkbFile * -XkbParseString(struct xkb_context *ctx, - const char *string, size_t len, - const char *file_name, const char *map); - -void -FreeXkbFile(XkbFile *file); - -XkbFile * -XkbFileFromComponents(struct xkb_context *ctx, - const struct xkb_component_names *kkctgs); - -bool -CompileKeycodes(XkbFile *file, struct xkb_keymap *keymap, - enum merge_mode merge); - -bool -CompileKeyTypes(XkbFile *file, struct xkb_keymap *keymap, - enum merge_mode merge); - -bool -CompileCompatMap(XkbFile *file, struct xkb_keymap *keymap, - enum merge_mode merge); - -bool -CompileSymbols(XkbFile *file, struct xkb_keymap *keymap, - enum merge_mode merge); - -bool -CompileKeymap(XkbFile *file, struct xkb_keymap *keymap, - enum merge_mode merge); - -/***====================================================================***/ - -static inline bool -ReportNotArray(struct xkb_context *ctx, const char *type, const char *field, - const char *name) -{ - log_err(ctx, - "The %s %s field is not an array; " - "Ignoring illegal assignment in %s\n", - type, field, name); - return false; -} - -static inline bool -ReportShouldBeArray(struct xkb_context *ctx, const char *type, - const char *field, const char *name) -{ - log_err(ctx, - "Missing subscript for %s %s; " - "Ignoring illegal assignment in %s\n", - type, field, name); - return false; -} - -static inline bool -ReportBadType(struct xkb_context *ctx, const char *type, const char *field, - const char *name, const char *wanted) -{ - log_err(ctx, "The %s %s field must be a %s; " - "Ignoring illegal assignment in %s\n", - type, field, wanted, name); - return false; -} - -static inline bool -ReportBadField(struct xkb_context *ctx, const char *type, const char *field, - const char *name) -{ - log_err(ctx, - "Unknown %s field %s in %s; " - "Ignoring assignment to unknown field in %s\n", - type, field, name, name); - return false; -} - -#endif diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp.c b/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp.c deleted file mode 100644 index 007e3f73e8..0000000000 --- a/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright © 2009 Dan Nicholson - * Copyright © 2012 Intel Corporation - * Copyright © 2012 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Authors: Dan Nicholson - * Ran Benita - * Daniel Stone - */ - -#include "xkbcomp-priv.h" -#include "rules.h" - -static bool -compile_keymap_file(struct xkb_keymap *keymap, XkbFile *file) -{ - if (file->file_type != FILE_TYPE_KEYMAP) { - log_err(keymap->ctx, - "Cannot compile a %s file alone into a keymap\n", - xkb_file_type_to_string(file->file_type)); - return false; - } - - if (!CompileKeymap(file, keymap, MERGE_OVERRIDE)) { - log_err(keymap->ctx, - "Failed to compile keymap\n"); - return false; - } - - return true; -} - -static bool -text_v1_keymap_new_from_names(struct xkb_keymap *keymap, - const struct xkb_rule_names *rmlvo) -{ - bool ok; - struct xkb_component_names kccgst; - XkbFile *file; - - log_dbg(keymap->ctx, - "Compiling from RMLVO: rules '%s', model '%s', layout '%s', " - "variant '%s', options '%s'\n", - rmlvo->rules, rmlvo->model, rmlvo->layout, rmlvo->variant, - rmlvo->options); - - ok = xkb_components_from_rules(keymap->ctx, rmlvo, &kccgst); - if (!ok) { - log_err(keymap->ctx, - "Couldn't look up rules '%s', model '%s', layout '%s', " - "variant '%s', options '%s'\n", - rmlvo->rules, rmlvo->model, rmlvo->layout, rmlvo->variant, - rmlvo->options); - return false; - } - - log_dbg(keymap->ctx, - "Compiling from KcCGST: keycodes '%s', types '%s', " - "compat '%s', symbols '%s'\n", - kccgst.keycodes, kccgst.types, kccgst.compat, kccgst.symbols); - - file = XkbFileFromComponents(keymap->ctx, &kccgst); - - free(kccgst.keycodes); - free(kccgst.types); - free(kccgst.compat); - free(kccgst.symbols); - - if (!file) { - log_err(keymap->ctx, - "Failed to generate parsed XKB file from components\n"); - return false; - } - - ok = compile_keymap_file(keymap, file); - FreeXkbFile(file); - return ok; -} - -static bool -text_v1_keymap_new_from_string(struct xkb_keymap *keymap, - const char *string, size_t len) -{ - bool ok; - XkbFile *xkb_file; - - xkb_file = XkbParseString(keymap->ctx, string, len, "(input string)", NULL); - if (!xkb_file) { - log_err(keymap->ctx, "Failed to parse input xkb string\n"); - return NULL; - } - - ok = compile_keymap_file(keymap, xkb_file); - FreeXkbFile(xkb_file); - return ok; -} - -static bool -text_v1_keymap_new_from_file(struct xkb_keymap *keymap, FILE *file) -{ - bool ok; - XkbFile *xkb_file; - - xkb_file = XkbParseFile(keymap->ctx, file, "(unknown file)", NULL); - if (!xkb_file) { - log_err(keymap->ctx, "Failed to parse input xkb file\n"); - return false; - } - - ok = compile_keymap_file(keymap, xkb_file); - FreeXkbFile(xkb_file); - return ok; -} - -const struct xkb_keymap_format_ops text_v1_keymap_format_ops = { - .keymap_new_from_names = text_v1_keymap_new_from_names, - .keymap_new_from_string = text_v1_keymap_new_from_string, - .keymap_new_from_file = text_v1_keymap_new_from_file, - .keymap_get_as_string = text_v1_keymap_get_as_string, -}; diff --git a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-compat.h b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-compat.h deleted file mode 100644 index 299732fdc3..0000000000 --- a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-compat.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright © 2012 Daniel Stone - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Daniel Stone - */ - -#ifndef _XKBCOMMON_COMPAT_H -#define _XKBCOMMON_COMPAT_H - -/** - * Renamed keymap API. - */ -#define xkb_group_index_t xkb_layout_index_t -#define xkb_group_mask_t xkb_layout_mask_t -#define xkb_map_compile_flags xkb_keymap_compile_flags -#define XKB_GROUP_INVALID XKB_LAYOUT_INVALID - -#define XKB_STATE_DEPRESSED \ - (XKB_STATE_MODS_DEPRESSED | XKB_STATE_LAYOUT_DEPRESSED) -#define XKB_STATE_LATCHED \ - (XKB_STATE_MODS_LATCHED | XKB_STATE_LAYOUT_LATCHED) -#define XKB_STATE_LOCKED \ - (XKB_STATE_MODS_LOCKED | XKB_STATE_LAYOUT_LOCKED) -#define XKB_STATE_EFFECTIVE \ - (XKB_STATE_DEPRESSED | XKB_STATE_LATCHED | XKB_STATE_LOCKED | \ - XKB_STATE_MODS_EFFECTIVE | XKB_STATE_LAYOUT_EFFECTIVE) - -#define xkb_map_new_from_names(context, names, flags) \ - xkb_keymap_new_from_names(context, names, flags) -#define xkb_map_new_from_file(context, file, format, flags) \ - xkb_keymap_new_from_file(context, file, format, flags) -#define xkb_map_new_from_string(context, string, format, flags) \ - xkb_keymap_new_from_string(context, string, format, flags) -#define xkb_map_get_as_string(keymap) \ - xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1) -#define xkb_map_ref(keymap) xkb_keymap_ref(keymap) -#define xkb_map_unref(keymap) xkb_keymap_unref(keymap) - -#define xkb_map_num_mods(keymap) xkb_keymap_num_mods(keymap) -#define xkb_map_mod_get_name(keymap, idx) xkb_keymap_mod_get_name(keymap, idx) -#define xkb_map_mod_get_index(keymap, str) xkb_keymap_mod_get_index(keymap, str) -#define xkb_key_mod_index_is_consumed(state, key, mod) \ - xkb_state_mod_index_is_consumed(state, key, mod) -#define xkb_key_mod_mask_remove_consumed(state, key, modmask) \ - xkb_state_mod_mask_remove_consumed(state, key, modmask) - -#define xkb_map_num_groups(keymap) xkb_keymap_num_layouts(keymap) -#define xkb_key_num_groups(keymap, key) \ - xkb_keymap_num_layouts_for_key(keymap, key) -#define xkb_map_group_get_name(keymap, idx) \ - xkb_keymap_layout_get_name(keymap, idx) -#define xkb_map_group_get_index(keymap, str) \ - xkb_keymap_layout_get_index(keymap, str) - -#define xkb_map_num_leds(keymap) xkb_keymap_num_leds(keymap) -#define xkb_map_led_get_name(keymap, idx) xkb_keymap_led_get_name(keymap, idx) -#define xkb_map_led_get_index(keymap, str) \ - xkb_keymap_led_get_index(keymap, str) - -#define xkb_key_repeats(keymap, key) xkb_keymap_key_repeats(keymap, key) - -#define xkb_key_get_syms(state, key, syms_out) \ - xkb_state_key_get_syms(state, key, syms_out) - -#define xkb_state_group_name_is_active(state, name, type) \ - xkb_state_layout_name_is_active(state, name, type) -#define xkb_state_group_index_is_active(state, idx, type) \ - xkb_state_layout_index_is_active(state, idx, type) - -#define xkb_state_serialize_group(state, component) \ - xkb_state_serialize_layout(state, component) - -#define xkb_state_get_map(state) xkb_state_get_keymap(state) - -/* Not needed anymore, since there's NO_FLAGS. */ -#define XKB_MAP_COMPILE_PLACEHOLDER XKB_KEYMAP_COMPILE_NO_FLAGS -#define XKB_MAP_COMPILE_NO_FLAGS XKB_KEYMAP_COMPILE_NO_FLAGS - -#endif diff --git a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-compose.h b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-compose.h deleted file mode 100644 index 25894b9394..0000000000 --- a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-compose.h +++ /dev/null @@ -1,493 +0,0 @@ -/* - * Copyright © 2013 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef _XKBCOMMON_COMPOSE_H -#define _XKBCOMMON_COMPOSE_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @file - * libxkbcommon Compose API - support for Compose and dead-keys. - */ - -/** - * @defgroup compose Compose and dead-keys support - * Support for Compose and dead-keys. - * @since 0.5.0 - * - * @{ - */ - -/** - * @page compose-overview Overview - * @parblock - * - * Compose and dead-keys are a common feature of many keyboard input - * systems. They extend the range of the keysysm that can be produced - * directly from a keyboard by using a sequence of key strokes, instead - * of just one. - * - * Here are some example sequences, in the libX11 Compose file format: - * - * : "á" aacute # LATIN SMALL LETTER A WITH ACUTE - * : "@" at # COMMERCIAL AT - * - * When the user presses a key which produces the `` keysym, - * nothing initially happens (thus the key is dubbed a "dead-key"). But - * when the user enters ``, "á" is "composed", in place of "a". If - * instead the user had entered a keysym which does not follow - * `` in any compose sequence, the sequence is said to be - * "cancelled". - * - * Compose files define many such sequences. For a description of the - * common file format for Compose files, see the Compose(5) man page. - * - * A successfuly-composed sequence has two results: a keysym and a UTF-8 - * string. At least one of the two is defined for each sequence. If only - * a keysym is given, the keysym's string representation is used for the - * result string (using xkb_keysym_to_utf8()). - * - * This library provides low-level support for Compose file parsing and - * processing. Higher-level APIs (such as libX11's `Xutf8LookupString`(3)) - * may be built upon it, or it can be used directly. - * - * @endparblock - */ - -/** - * @page compose-conflicting Conflicting Sequences - * @parblock - * - * To avoid ambiguity, a sequence is not allowed to be a prefix of another. - * In such a case, the conflict is resolved thus: - * - * 1. A longer sequence overrides a shorter one. - * 2. An equal sequence overrides an existing one. - * 3. A shorter sequence does not override a longer one. - * - * Sequences of length 1 are allowed. - * - * @endparblock - */ - -/** - * @page compose-cancellation Cancellation Behavior - * @parblock - * - * What should happen when a sequence is cancelled? For example, consider - * there are only the above sequences, and the input keysyms are - * ` `. There are a few approaches: - * - * 1. Swallow the cancelling keysym; that is, no keysym is produced. - * This is the approach taken by libX11. - * 2. Let the cancelling keysym through; that is, `` is produced. - * 3. Replay the entire sequence; that is, ` ` is produced. - * This is the approach taken by Microsoft Windows (approximately; - * instead of ``, the underlying key is used. This is - * difficult to simulate with XKB keymaps). - * - * You can program whichever approach best fits users' expectations. - * - * @endparblock - */ - -/** - * @struct xkb_compose_table - * Opaque Compose table object. - * - * The compose table holds the definitions of the Compose sequences, as - * gathered from Compose files. It is immutable. - */ -struct xkb_compose_table; - -/** - * @struct xkb_compose_state - * Opaque Compose state object. - * - * The compose state maintains state for compose sequence matching, such - * as which possible sequences are being matched, and the position within - * these sequences. It acts as a simple state machine wherein keysyms are - * the input, and composed keysyms and strings are the output. - * - * The compose state is usually associated with a keyboard device. - */ -struct xkb_compose_state; - -/** Flags affecting Compose file compilation. */ -enum xkb_compose_compile_flags { - /** Do not apply any flags. */ - XKB_COMPOSE_COMPILE_NO_FLAGS = 0 -}; - -/** The recognized Compose file formats. */ -enum xkb_compose_format { - /** The classic libX11 Compose text format, described in Compose(5). */ - XKB_COMPOSE_FORMAT_TEXT_V1 = 1 -}; - -/** - * @page compose-locale Compose Locale - * @parblock - * - * Compose files are locale dependent: - * - Compose files are written for a locale, and the locale is used when - * searching for the appropriate file to use. - * - Compose files may reference the locale internally, with directives - * such as \%L. - * - * As such, functions like xkb_compose_table_new_from_locale() require - * a `locale` parameter. This will usually be the current locale (see - * locale(7) for more details). You may also want to allow the user to - * explicitly configure it, so he can use the Compose file of a given - * locale, but not use that locale for other things. - * - * You may query the current locale as follows: - * @code - * const char *locale; - * locale = setlocale(LC_CTYPE, NULL); - * @endcode - * - * This will only give useful results if the program had previously set - * the current locale using setlocale(3), with `LC_CTYPE` or `LC_ALL` - * and a non-NULL argument. - * - * If you prefer not to use the locale system of the C runtime library, - * you may nevertheless obtain the user's locale directly using - * environment variables, as described in locale(7). For example, - * @code - * const char *locale; - * locale = getenv("LC_ALL"); - * if (!locale || !*locale) - * locale = getenv("LC_CTYPE"); - * if (!locale || !*locale) - * locale = getenv("LANG"); - * if (!locale || !*locale) - * locale = "C"; - * @endcode - * - * Note that some locales supported by the C standard library may not - * have a Compose file assigned. - * - * @endparblock - */ - -/** - * Create a compose table for a given locale. - * - * The locale is used for searching the file-system for an appropriate - * Compose file. The search order is described in Compose(5). It is - * affected by the following environment variables: - * - * 1. `XCOMPOSEFILE` - see Compose(5). - * 2. `HOME` - see Compose(5). - * 3. `XLOCALEDIR` - if set, used as the base directory for the system's - * X locale files, e.g. `/usr/share/X11/locale`, instead of the - * preconfigured directory. - * - * @param context - * The library context in which to create the compose table. - * @param locale - * The current locale. See @ref compose-locale.\n - * - * The value is copied, so it is safe to pass the result of getenv(3) - * (or similar) without fear of it being invalidated by a subsequent - * setenv(3) (or similar). - * @param flags - * Optional flags for the compose table, or 0. - * - * @returns A compose table for the given locale, or NULL if the - * compilation failed or a Compose file was not found. - * - * @memberof xkb_compose_table - */ -struct xkb_compose_table * -xkb_compose_table_new_from_locale(struct xkb_context *context, - const char *locale, - enum xkb_compose_compile_flags flags); - -/** - * Create a new compose table from a Compose file. - * - * @param context - * The library context in which to create the compose table. - * @param file - * The Compose file to compile. - * @param locale - * The current locale. See @ref compose-locale. - * @param format - * The text format of the Compose file to compile. - * @param flags - * Optional flags for the compose table, or 0. - * - * @returns A compose table compiled from the given file, or NULL if - * the compilation failed. - * - * @memberof xkb_compose_table - */ -struct xkb_compose_table * -xkb_compose_table_new_from_file(struct xkb_context *context, - FILE *file, - const char *locale, - enum xkb_compose_format format, - enum xkb_compose_compile_flags flags); - -/** - * Create a new compose table from a memory buffer. - * - * This is just like xkb_compose_table_new_from_file(), but instead of - * a file, gets the table as one enormous string. - * - * @see xkb_compose_table_new_from_file() - * @memberof xkb_compose_table - */ -struct xkb_compose_table * -xkb_compose_table_new_from_buffer(struct xkb_context *context, - const char *buffer, size_t length, - const char *locale, - enum xkb_compose_format format, - enum xkb_compose_compile_flags flags); - -/** - * Take a new reference on a compose table. - * - * @returns The passed in object. - * - * @memberof xkb_compose_table - */ -struct xkb_compose_table * -xkb_compose_table_ref(struct xkb_compose_table *table); - -/** - * Release a reference on a compose table, and possibly free it. - * - * @param table The object. If it is NULL, this function does nothing. - * - * @memberof xkb_compose_table - */ -void -xkb_compose_table_unref(struct xkb_compose_table *table); - -/** Flags for compose state creation. */ -enum xkb_compose_state_flags { - /** Do not apply any flags. */ - XKB_COMPOSE_STATE_NO_FLAGS = 0 -}; - -/** - * Create a new compose state object. - * - * @param table - * The compose table the state will use. - * @param flags - * Optional flags for the compose state, or 0. - * - * @returns A new compose state, or NULL on failure. - * - * @memberof xkb_compose_state - */ -struct xkb_compose_state * -xkb_compose_state_new(struct xkb_compose_table *table, - enum xkb_compose_state_flags flags); - -/** - * Take a new reference on a compose state object. - * - * @returns The passed in object. - * - * @memberof xkb_compose_state - */ -struct xkb_compose_state * -xkb_compose_state_ref(struct xkb_compose_state *state); - -/** - * Release a reference on a compose state object, and possibly free it. - * - * @param state The object. If NULL, do nothing. - * - * @memberof xkb_compose_state - */ -void -xkb_compose_state_unref(struct xkb_compose_state *state); - -/** - * Get the compose table which a compose state object is using. - * - * @returns The compose table which was passed to xkb_compose_state_new() - * when creating this state object. - * - * This function does not take a new reference on the compose table; you - * must explicitly reference it yourself if you plan to use it beyond the - * lifetime of the state. - * - * @memberof xkb_compose_state - */ -struct xkb_compose_table * -xkb_compose_state_get_compose_table(struct xkb_compose_state *state); - -/** Status of the Compose sequence state machine. */ -enum xkb_compose_status { - /** The initial state; no sequence has started yet. */ - XKB_COMPOSE_NOTHING, - /** In the middle of a sequence. */ - XKB_COMPOSE_COMPOSING, - /** A complete sequence has been matched. */ - XKB_COMPOSE_COMPOSED, - /** The last sequence was cancelled due to an unmatched keysym. */ - XKB_COMPOSE_CANCELLED -}; - -/** The effect of a keysym fed to xkb_compose_state_feed(). */ -enum xkb_compose_feed_result { - /** The keysym had no effect - it did not affect the status. */ - XKB_COMPOSE_FEED_IGNORED, - /** The keysym started, advanced or cancelled a sequence. */ - XKB_COMPOSE_FEED_ACCEPTED -}; - -/** - * Feed one keysym to the Compose sequence state machine. - * - * This function can advance into a compose sequence, cancel a sequence, - * start a new sequence, or do nothing in particular. The resulting - * status may be observed with xkb_compose_state_get_status(). - * - * Some keysyms, such as keysyms for modifier keys, are ignored - they - * have no effect on the status or otherwise. - * - * The following is a description of the possible status transitions, in - * the format CURRENT STATUS => NEXT STATUS, given a non-ignored input - * keysym `keysym`: - * - @verbatim - NOTHING or CANCELLED or COMPOSED => - NOTHING if keysym does not start a sequence. - COMPOSING if keysym starts a sequence. - COMPOSED if keysym starts and terminates a single-keysym sequence. - - COMPOSING => - COMPOSING if keysym advances any of the currently possible - sequences but does not terminate any of them. - COMPOSED if keysym terminates one of the currently possible - sequences. - CANCELLED if keysym does not advance any of the currently - possible sequences. - @endverbatim - * - * The current Compose formats do not support multiple-keysyms. - * Therefore, if you are using a function such as xkb_state_key_get_syms() - * and it returns more than one keysym, consider feeding XKB_KEY_NoSymbol - * instead. - * - * @param state - * The compose state object. - * @param keysym - * A keysym, usually obtained after a key-press event, with a - * function such as xkb_state_key_get_one_sym(). - * - * @returns Whether the keysym was ignored. This is useful, for example, - * if you want to keep a record of the sequence matched thus far. - * - * @memberof xkb_compose_state - */ -enum xkb_compose_feed_result -xkb_compose_state_feed(struct xkb_compose_state *state, - xkb_keysym_t keysym); - -/** - * Reset the Compose sequence state machine. - * - * The status is set to XKB_COMPOSE_NOTHING, and the current sequence - * is discarded. - * - * @memberof xkb_compose_state - */ -void -xkb_compose_state_reset(struct xkb_compose_state *state); - -/** - * Get the current status of the compose state machine. - * - * @see xkb_compose_status - * @memberof xkb_compose_state - **/ -enum xkb_compose_status -xkb_compose_state_get_status(struct xkb_compose_state *state); - -/** - * Get the result Unicode/UTF-8 string for a composed sequence. - * - * See @ref compose-overview for more details. This function is only - * useful when the status is XKB_COMPOSE_COMPOSED. - * - * @param[in] state - * The compose state. - * @param[out] buffer - * A buffer to write the string into. - * @param[in] size - * Size of the buffer. - * - * @warning If the buffer passed is too small, the string is truncated - * (though still NUL-terminated). - * - * @returns - * The number of bytes required for the string, excluding the NUL byte. - * If the sequence is not complete, or does not have a viable result - * string, returns 0, and sets `buffer` to the empty string (if possible). - * @returns - * You may check if truncation has occurred by comparing the return value - * with the size of `buffer`, similarly to the `snprintf`(3) function. - * You may safely pass NULL and 0 to `buffer` and `size` to find the - * required size (without the NUL-byte). - * - * @memberof xkb_compose_state - **/ -int -xkb_compose_state_get_utf8(struct xkb_compose_state *state, - char *buffer, size_t size); - -/** - * Get the result keysym for a composed sequence. - * - * See @ref compose-overview for more details. This function is only - * useful when the status is XKB_COMPOSE_COMPOSED. - * - * @returns The result keysym. If the sequence is not complete, or does - * not specify a result keysym, returns XKB_KEY_NoSymbol. - * - * @memberof xkb_compose_state - **/ -xkb_keysym_t -xkb_compose_state_get_one_sym(struct xkb_compose_state *state); - -/** @} */ - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* _XKBCOMMON_COMPOSE_H */ diff --git a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-keysyms.h b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-keysyms.h deleted file mode 100644 index bd172a6efc..0000000000 --- a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-keysyms.h +++ /dev/null @@ -1,3004 +0,0 @@ -#ifndef _XKBCOMMON_KEYSYMS_H -#define _XKBCOMMON_KEYSYMS_H - -/* This file is autogenerated; please do not commit directly. */ - -#define XKB_KEY_NoSymbol 0x000000 /* Special KeySym */ - -/*********************************************************** -Copyright 1987, 1994, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from The Open Group. - - -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -******************************************************************/ - -/* - * The "X11 Window System Protocol" standard defines in Appendix A the - * keysym codes. These 29-bit integer values identify characters or - * functions associated with each key (e.g., via the visible - * engraving) of a keyboard layout. This file assigns mnemonic macro - * names for these keysyms. - * - * This file is also compiled (by src/util/makekeys.c in libX11) into - * hash tables that can be accessed with X11 library functions such as - * XStringToKeysym() and XKeysymToString(). - * - * Where a keysym corresponds one-to-one to an ISO 10646 / Unicode - * character, this is noted in a comment that provides both the U+xxxx - * Unicode position, as well as the official Unicode name of the - * character. - * - * Where the correspondence is either not one-to-one or semantically - * unclear, the Unicode position and name are enclosed in - * parentheses. Such legacy keysyms should be considered deprecated - * and are not recommended for use in future keyboard mappings. - * - * For any future extension of the keysyms with characters already - * found in ISO 10646 / Unicode, the following algorithm shall be - * used. The new keysym code position will simply be the character's - * Unicode number plus 0x01000000. The keysym values in the range - * 0x01000100 to 0x0110ffff are reserved to represent Unicode - * characters in the range U+0100 to U+10FFFF. - * - * While most newer Unicode-based X11 clients do already accept - * Unicode-mapped keysyms in the range 0x01000100 to 0x0110ffff, it - * will remain necessary for clients -- in the interest of - * compatibility with existing servers -- to also understand the - * existing legacy keysym values in the range 0x0100 to 0x20ff. - * - * Where several mnemonic names are defined for the same keysym in this - * file, all but the first one listed should be considered deprecated. - * - * Mnemonic names for keysyms are defined in this file with lines - * that match one of these Perl regular expressions: - * - * /^\#define XKB_KEY_([a-zA-Z_0-9]+)\s+0x([0-9a-f]+)\s*\/\* U+([0-9A-F]{4,6}) (.*) \*\/\s*$/ - * /^\#define XKB_KEY_([a-zA-Z_0-9]+)\s+0x([0-9a-f]+)\s*\/\*\(U+([0-9A-F]{4,6}) (.*)\)\*\/\s*$/ - * /^\#define XKB_KEY_([a-zA-Z_0-9]+)\s+0x([0-9a-f]+)\s*(\/\*\s*(.*)\s*\*\/)?\s*$/ - * - * Before adding new keysyms, please do consider the following: In - * addition to the keysym names defined in this file, the - * XStringToKeysym() and XKeysymToString() functions will also handle - * any keysym string of the form "U0020" to "U007E" and "U00A0" to - * "U10FFFF" for all possible Unicode characters. In other words, - * every possible Unicode character has already a keysym string - * defined algorithmically, even if it is not listed here. Therefore, - * defining an additional keysym macro is only necessary where a - * non-hexadecimal mnemonic name is needed, or where the new keysym - * does not represent any existing Unicode character. - * - * When adding new keysyms to this file, do not forget to also update the - * following as needed: - * - * - the mappings in src/KeyBind.c in the repo - * git://anongit.freedesktop.org/xorg/lib/libX11.git - * - * - the protocol specification in specs/keysyms.xml - * in the repo git://anongit.freedesktop.org/xorg/proto/x11proto.git - * - */ - -#define XKB_KEY_VoidSymbol 0xffffff /* Void symbol */ - -/* - * TTY function keys, cleverly chosen to map to ASCII, for convenience of - * programming, but could have been arbitrary (at the cost of lookup - * tables in client code). - */ - -#define XKB_KEY_BackSpace 0xff08 /* Back space, back char */ -#define XKB_KEY_Tab 0xff09 -#define XKB_KEY_Linefeed 0xff0a /* Linefeed, LF */ -#define XKB_KEY_Clear 0xff0b -#define XKB_KEY_Return 0xff0d /* Return, enter */ -#define XKB_KEY_Pause 0xff13 /* Pause, hold */ -#define XKB_KEY_Scroll_Lock 0xff14 -#define XKB_KEY_Sys_Req 0xff15 -#define XKB_KEY_Escape 0xff1b -#define XKB_KEY_Delete 0xffff /* Delete, rubout */ - - - -/* International & multi-key character composition */ - -#define XKB_KEY_Multi_key 0xff20 /* Multi-key character compose */ -#define XKB_KEY_Codeinput 0xff37 -#define XKB_KEY_SingleCandidate 0xff3c -#define XKB_KEY_MultipleCandidate 0xff3d -#define XKB_KEY_PreviousCandidate 0xff3e - -/* Japanese keyboard support */ - -#define XKB_KEY_Kanji 0xff21 /* Kanji, Kanji convert */ -#define XKB_KEY_Muhenkan 0xff22 /* Cancel Conversion */ -#define XKB_KEY_Henkan_Mode 0xff23 /* Start/Stop Conversion */ -#define XKB_KEY_Henkan 0xff23 /* Alias for Henkan_Mode */ -#define XKB_KEY_Romaji 0xff24 /* to Romaji */ -#define XKB_KEY_Hiragana 0xff25 /* to Hiragana */ -#define XKB_KEY_Katakana 0xff26 /* to Katakana */ -#define XKB_KEY_Hiragana_Katakana 0xff27 /* Hiragana/Katakana toggle */ -#define XKB_KEY_Zenkaku 0xff28 /* to Zenkaku */ -#define XKB_KEY_Hankaku 0xff29 /* to Hankaku */ -#define XKB_KEY_Zenkaku_Hankaku 0xff2a /* Zenkaku/Hankaku toggle */ -#define XKB_KEY_Touroku 0xff2b /* Add to Dictionary */ -#define XKB_KEY_Massyo 0xff2c /* Delete from Dictionary */ -#define XKB_KEY_Kana_Lock 0xff2d /* Kana Lock */ -#define XKB_KEY_Kana_Shift 0xff2e /* Kana Shift */ -#define XKB_KEY_Eisu_Shift 0xff2f /* Alphanumeric Shift */ -#define XKB_KEY_Eisu_toggle 0xff30 /* Alphanumeric toggle */ -#define XKB_KEY_Kanji_Bangou 0xff37 /* Codeinput */ -#define XKB_KEY_Zen_Koho 0xff3d /* Multiple/All Candidate(s) */ -#define XKB_KEY_Mae_Koho 0xff3e /* Previous Candidate */ - -/* 0xff31 thru 0xff3f are under XK_KOREAN */ - -/* Cursor control & motion */ - -#define XKB_KEY_Home 0xff50 -#define XKB_KEY_Left 0xff51 /* Move left, left arrow */ -#define XKB_KEY_Up 0xff52 /* Move up, up arrow */ -#define XKB_KEY_Right 0xff53 /* Move right, right arrow */ -#define XKB_KEY_Down 0xff54 /* Move down, down arrow */ -#define XKB_KEY_Prior 0xff55 /* Prior, previous */ -#define XKB_KEY_Page_Up 0xff55 -#define XKB_KEY_Next 0xff56 /* Next */ -#define XKB_KEY_Page_Down 0xff56 -#define XKB_KEY_End 0xff57 /* EOL */ -#define XKB_KEY_Begin 0xff58 /* BOL */ - - -/* Misc functions */ - -#define XKB_KEY_Select 0xff60 /* Select, mark */ -#define XKB_KEY_Print 0xff61 -#define XKB_KEY_Execute 0xff62 /* Execute, run, do */ -#define XKB_KEY_Insert 0xff63 /* Insert, insert here */ -#define XKB_KEY_Undo 0xff65 -#define XKB_KEY_Redo 0xff66 /* Redo, again */ -#define XKB_KEY_Menu 0xff67 -#define XKB_KEY_Find 0xff68 /* Find, search */ -#define XKB_KEY_Cancel 0xff69 /* Cancel, stop, abort, exit */ -#define XKB_KEY_Help 0xff6a /* Help */ -#define XKB_KEY_Break 0xff6b -#define XKB_KEY_Mode_switch 0xff7e /* Character set switch */ -#define XKB_KEY_script_switch 0xff7e /* Alias for mode_switch */ -#define XKB_KEY_Num_Lock 0xff7f - -/* Keypad functions, keypad numbers cleverly chosen to map to ASCII */ - -#define XKB_KEY_KP_Space 0xff80 /* Space */ -#define XKB_KEY_KP_Tab 0xff89 -#define XKB_KEY_KP_Enter 0xff8d /* Enter */ -#define XKB_KEY_KP_F1 0xff91 /* PF1, KP_A, ... */ -#define XKB_KEY_KP_F2 0xff92 -#define XKB_KEY_KP_F3 0xff93 -#define XKB_KEY_KP_F4 0xff94 -#define XKB_KEY_KP_Home 0xff95 -#define XKB_KEY_KP_Left 0xff96 -#define XKB_KEY_KP_Up 0xff97 -#define XKB_KEY_KP_Right 0xff98 -#define XKB_KEY_KP_Down 0xff99 -#define XKB_KEY_KP_Prior 0xff9a -#define XKB_KEY_KP_Page_Up 0xff9a -#define XKB_KEY_KP_Next 0xff9b -#define XKB_KEY_KP_Page_Down 0xff9b -#define XKB_KEY_KP_End 0xff9c -#define XKB_KEY_KP_Begin 0xff9d -#define XKB_KEY_KP_Insert 0xff9e -#define XKB_KEY_KP_Delete 0xff9f -#define XKB_KEY_KP_Equal 0xffbd /* Equals */ -#define XKB_KEY_KP_Multiply 0xffaa -#define XKB_KEY_KP_Add 0xffab -#define XKB_KEY_KP_Separator 0xffac /* Separator, often comma */ -#define XKB_KEY_KP_Subtract 0xffad -#define XKB_KEY_KP_Decimal 0xffae -#define XKB_KEY_KP_Divide 0xffaf - -#define XKB_KEY_KP_0 0xffb0 -#define XKB_KEY_KP_1 0xffb1 -#define XKB_KEY_KP_2 0xffb2 -#define XKB_KEY_KP_3 0xffb3 -#define XKB_KEY_KP_4 0xffb4 -#define XKB_KEY_KP_5 0xffb5 -#define XKB_KEY_KP_6 0xffb6 -#define XKB_KEY_KP_7 0xffb7 -#define XKB_KEY_KP_8 0xffb8 -#define XKB_KEY_KP_9 0xffb9 - - - -/* - * Auxiliary functions; note the duplicate definitions for left and right - * function keys; Sun keyboards and a few other manufacturers have such - * function key groups on the left and/or right sides of the keyboard. - * We've not found a keyboard with more than 35 function keys total. - */ - -#define XKB_KEY_F1 0xffbe -#define XKB_KEY_F2 0xffbf -#define XKB_KEY_F3 0xffc0 -#define XKB_KEY_F4 0xffc1 -#define XKB_KEY_F5 0xffc2 -#define XKB_KEY_F6 0xffc3 -#define XKB_KEY_F7 0xffc4 -#define XKB_KEY_F8 0xffc5 -#define XKB_KEY_F9 0xffc6 -#define XKB_KEY_F10 0xffc7 -#define XKB_KEY_F11 0xffc8 -#define XKB_KEY_L1 0xffc8 -#define XKB_KEY_F12 0xffc9 -#define XKB_KEY_L2 0xffc9 -#define XKB_KEY_F13 0xffca -#define XKB_KEY_L3 0xffca -#define XKB_KEY_F14 0xffcb -#define XKB_KEY_L4 0xffcb -#define XKB_KEY_F15 0xffcc -#define XKB_KEY_L5 0xffcc -#define XKB_KEY_F16 0xffcd -#define XKB_KEY_L6 0xffcd -#define XKB_KEY_F17 0xffce -#define XKB_KEY_L7 0xffce -#define XKB_KEY_F18 0xffcf -#define XKB_KEY_L8 0xffcf -#define XKB_KEY_F19 0xffd0 -#define XKB_KEY_L9 0xffd0 -#define XKB_KEY_F20 0xffd1 -#define XKB_KEY_L10 0xffd1 -#define XKB_KEY_F21 0xffd2 -#define XKB_KEY_R1 0xffd2 -#define XKB_KEY_F22 0xffd3 -#define XKB_KEY_R2 0xffd3 -#define XKB_KEY_F23 0xffd4 -#define XKB_KEY_R3 0xffd4 -#define XKB_KEY_F24 0xffd5 -#define XKB_KEY_R4 0xffd5 -#define XKB_KEY_F25 0xffd6 -#define XKB_KEY_R5 0xffd6 -#define XKB_KEY_F26 0xffd7 -#define XKB_KEY_R6 0xffd7 -#define XKB_KEY_F27 0xffd8 -#define XKB_KEY_R7 0xffd8 -#define XKB_KEY_F28 0xffd9 -#define XKB_KEY_R8 0xffd9 -#define XKB_KEY_F29 0xffda -#define XKB_KEY_R9 0xffda -#define XKB_KEY_F30 0xffdb -#define XKB_KEY_R10 0xffdb -#define XKB_KEY_F31 0xffdc -#define XKB_KEY_R11 0xffdc -#define XKB_KEY_F32 0xffdd -#define XKB_KEY_R12 0xffdd -#define XKB_KEY_F33 0xffde -#define XKB_KEY_R13 0xffde -#define XKB_KEY_F34 0xffdf -#define XKB_KEY_R14 0xffdf -#define XKB_KEY_F35 0xffe0 -#define XKB_KEY_R15 0xffe0 - -/* Modifiers */ - -#define XKB_KEY_Shift_L 0xffe1 /* Left shift */ -#define XKB_KEY_Shift_R 0xffe2 /* Right shift */ -#define XKB_KEY_Control_L 0xffe3 /* Left control */ -#define XKB_KEY_Control_R 0xffe4 /* Right control */ -#define XKB_KEY_Caps_Lock 0xffe5 /* Caps lock */ -#define XKB_KEY_Shift_Lock 0xffe6 /* Shift lock */ - -#define XKB_KEY_Meta_L 0xffe7 /* Left meta */ -#define XKB_KEY_Meta_R 0xffe8 /* Right meta */ -#define XKB_KEY_Alt_L 0xffe9 /* Left alt */ -#define XKB_KEY_Alt_R 0xffea /* Right alt */ -#define XKB_KEY_Super_L 0xffeb /* Left super */ -#define XKB_KEY_Super_R 0xffec /* Right super */ -#define XKB_KEY_Hyper_L 0xffed /* Left hyper */ -#define XKB_KEY_Hyper_R 0xffee /* Right hyper */ - -/* - * Keyboard (XKB) Extension function and modifier keys - * (from Appendix C of "The X Keyboard Extension: Protocol Specification") - * Byte 3 = 0xfe - */ - -#define XKB_KEY_ISO_Lock 0xfe01 -#define XKB_KEY_ISO_Level2_Latch 0xfe02 -#define XKB_KEY_ISO_Level3_Shift 0xfe03 -#define XKB_KEY_ISO_Level3_Latch 0xfe04 -#define XKB_KEY_ISO_Level3_Lock 0xfe05 -#define XKB_KEY_ISO_Level5_Shift 0xfe11 -#define XKB_KEY_ISO_Level5_Latch 0xfe12 -#define XKB_KEY_ISO_Level5_Lock 0xfe13 -#define XKB_KEY_ISO_Group_Shift 0xff7e /* Alias for mode_switch */ -#define XKB_KEY_ISO_Group_Latch 0xfe06 -#define XKB_KEY_ISO_Group_Lock 0xfe07 -#define XKB_KEY_ISO_Next_Group 0xfe08 -#define XKB_KEY_ISO_Next_Group_Lock 0xfe09 -#define XKB_KEY_ISO_Prev_Group 0xfe0a -#define XKB_KEY_ISO_Prev_Group_Lock 0xfe0b -#define XKB_KEY_ISO_First_Group 0xfe0c -#define XKB_KEY_ISO_First_Group_Lock 0xfe0d -#define XKB_KEY_ISO_Last_Group 0xfe0e -#define XKB_KEY_ISO_Last_Group_Lock 0xfe0f - -#define XKB_KEY_ISO_Left_Tab 0xfe20 -#define XKB_KEY_ISO_Move_Line_Up 0xfe21 -#define XKB_KEY_ISO_Move_Line_Down 0xfe22 -#define XKB_KEY_ISO_Partial_Line_Up 0xfe23 -#define XKB_KEY_ISO_Partial_Line_Down 0xfe24 -#define XKB_KEY_ISO_Partial_Space_Left 0xfe25 -#define XKB_KEY_ISO_Partial_Space_Right 0xfe26 -#define XKB_KEY_ISO_Set_Margin_Left 0xfe27 -#define XKB_KEY_ISO_Set_Margin_Right 0xfe28 -#define XKB_KEY_ISO_Release_Margin_Left 0xfe29 -#define XKB_KEY_ISO_Release_Margin_Right 0xfe2a -#define XKB_KEY_ISO_Release_Both_Margins 0xfe2b -#define XKB_KEY_ISO_Fast_Cursor_Left 0xfe2c -#define XKB_KEY_ISO_Fast_Cursor_Right 0xfe2d -#define XKB_KEY_ISO_Fast_Cursor_Up 0xfe2e -#define XKB_KEY_ISO_Fast_Cursor_Down 0xfe2f -#define XKB_KEY_ISO_Continuous_Underline 0xfe30 -#define XKB_KEY_ISO_Discontinuous_Underline 0xfe31 -#define XKB_KEY_ISO_Emphasize 0xfe32 -#define XKB_KEY_ISO_Center_Object 0xfe33 -#define XKB_KEY_ISO_Enter 0xfe34 - -#define XKB_KEY_dead_grave 0xfe50 -#define XKB_KEY_dead_acute 0xfe51 -#define XKB_KEY_dead_circumflex 0xfe52 -#define XKB_KEY_dead_tilde 0xfe53 -#define XKB_KEY_dead_perispomeni 0xfe53 /* alias for dead_tilde */ -#define XKB_KEY_dead_macron 0xfe54 -#define XKB_KEY_dead_breve 0xfe55 -#define XKB_KEY_dead_abovedot 0xfe56 -#define XKB_KEY_dead_diaeresis 0xfe57 -#define XKB_KEY_dead_abovering 0xfe58 -#define XKB_KEY_dead_doubleacute 0xfe59 -#define XKB_KEY_dead_caron 0xfe5a -#define XKB_KEY_dead_cedilla 0xfe5b -#define XKB_KEY_dead_ogonek 0xfe5c -#define XKB_KEY_dead_iota 0xfe5d -#define XKB_KEY_dead_voiced_sound 0xfe5e -#define XKB_KEY_dead_semivoiced_sound 0xfe5f -#define XKB_KEY_dead_belowdot 0xfe60 -#define XKB_KEY_dead_hook 0xfe61 -#define XKB_KEY_dead_horn 0xfe62 -#define XKB_KEY_dead_stroke 0xfe63 -#define XKB_KEY_dead_abovecomma 0xfe64 -#define XKB_KEY_dead_psili 0xfe64 /* alias for dead_abovecomma */ -#define XKB_KEY_dead_abovereversedcomma 0xfe65 -#define XKB_KEY_dead_dasia 0xfe65 /* alias for dead_abovereversedcomma */ -#define XKB_KEY_dead_doublegrave 0xfe66 -#define XKB_KEY_dead_belowring 0xfe67 -#define XKB_KEY_dead_belowmacron 0xfe68 -#define XKB_KEY_dead_belowcircumflex 0xfe69 -#define XKB_KEY_dead_belowtilde 0xfe6a -#define XKB_KEY_dead_belowbreve 0xfe6b -#define XKB_KEY_dead_belowdiaeresis 0xfe6c -#define XKB_KEY_dead_invertedbreve 0xfe6d -#define XKB_KEY_dead_belowcomma 0xfe6e -#define XKB_KEY_dead_currency 0xfe6f - -/* extra dead elements for German T3 layout */ -#define XKB_KEY_dead_lowline 0xfe90 -#define XKB_KEY_dead_aboveverticalline 0xfe91 -#define XKB_KEY_dead_belowverticalline 0xfe92 -#define XKB_KEY_dead_longsolidusoverlay 0xfe93 - -/* dead vowels for universal syllable entry */ -#define XKB_KEY_dead_a 0xfe80 -#define XKB_KEY_dead_A 0xfe81 -#define XKB_KEY_dead_e 0xfe82 -#define XKB_KEY_dead_E 0xfe83 -#define XKB_KEY_dead_i 0xfe84 -#define XKB_KEY_dead_I 0xfe85 -#define XKB_KEY_dead_o 0xfe86 -#define XKB_KEY_dead_O 0xfe87 -#define XKB_KEY_dead_u 0xfe88 -#define XKB_KEY_dead_U 0xfe89 -#define XKB_KEY_dead_small_schwa 0xfe8a -#define XKB_KEY_dead_capital_schwa 0xfe8b - -#define XKB_KEY_dead_greek 0xfe8c - -#define XKB_KEY_First_Virtual_Screen 0xfed0 -#define XKB_KEY_Prev_Virtual_Screen 0xfed1 -#define XKB_KEY_Next_Virtual_Screen 0xfed2 -#define XKB_KEY_Last_Virtual_Screen 0xfed4 -#define XKB_KEY_Terminate_Server 0xfed5 - -#define XKB_KEY_AccessX_Enable 0xfe70 -#define XKB_KEY_AccessX_Feedback_Enable 0xfe71 -#define XKB_KEY_RepeatKeys_Enable 0xfe72 -#define XKB_KEY_SlowKeys_Enable 0xfe73 -#define XKB_KEY_BounceKeys_Enable 0xfe74 -#define XKB_KEY_StickyKeys_Enable 0xfe75 -#define XKB_KEY_MouseKeys_Enable 0xfe76 -#define XKB_KEY_MouseKeys_Accel_Enable 0xfe77 -#define XKB_KEY_Overlay1_Enable 0xfe78 -#define XKB_KEY_Overlay2_Enable 0xfe79 -#define XKB_KEY_AudibleBell_Enable 0xfe7a - -#define XKB_KEY_Pointer_Left 0xfee0 -#define XKB_KEY_Pointer_Right 0xfee1 -#define XKB_KEY_Pointer_Up 0xfee2 -#define XKB_KEY_Pointer_Down 0xfee3 -#define XKB_KEY_Pointer_UpLeft 0xfee4 -#define XKB_KEY_Pointer_UpRight 0xfee5 -#define XKB_KEY_Pointer_DownLeft 0xfee6 -#define XKB_KEY_Pointer_DownRight 0xfee7 -#define XKB_KEY_Pointer_Button_Dflt 0xfee8 -#define XKB_KEY_Pointer_Button1 0xfee9 -#define XKB_KEY_Pointer_Button2 0xfeea -#define XKB_KEY_Pointer_Button3 0xfeeb -#define XKB_KEY_Pointer_Button4 0xfeec -#define XKB_KEY_Pointer_Button5 0xfeed -#define XKB_KEY_Pointer_DblClick_Dflt 0xfeee -#define XKB_KEY_Pointer_DblClick1 0xfeef -#define XKB_KEY_Pointer_DblClick2 0xfef0 -#define XKB_KEY_Pointer_DblClick3 0xfef1 -#define XKB_KEY_Pointer_DblClick4 0xfef2 -#define XKB_KEY_Pointer_DblClick5 0xfef3 -#define XKB_KEY_Pointer_Drag_Dflt 0xfef4 -#define XKB_KEY_Pointer_Drag1 0xfef5 -#define XKB_KEY_Pointer_Drag2 0xfef6 -#define XKB_KEY_Pointer_Drag3 0xfef7 -#define XKB_KEY_Pointer_Drag4 0xfef8 -#define XKB_KEY_Pointer_Drag5 0xfefd - -#define XKB_KEY_Pointer_EnableKeys 0xfef9 -#define XKB_KEY_Pointer_Accelerate 0xfefa -#define XKB_KEY_Pointer_DfltBtnNext 0xfefb -#define XKB_KEY_Pointer_DfltBtnPrev 0xfefc - -/* Single-Stroke Multiple-Character N-Graph Keysyms For The X Input Method */ - -#define XKB_KEY_ch 0xfea0 -#define XKB_KEY_Ch 0xfea1 -#define XKB_KEY_CH 0xfea2 -#define XKB_KEY_c_h 0xfea3 -#define XKB_KEY_C_h 0xfea4 -#define XKB_KEY_C_H 0xfea5 - - -/* - * 3270 Terminal Keys - * Byte 3 = 0xfd - */ - -#define XKB_KEY_3270_Duplicate 0xfd01 -#define XKB_KEY_3270_FieldMark 0xfd02 -#define XKB_KEY_3270_Right2 0xfd03 -#define XKB_KEY_3270_Left2 0xfd04 -#define XKB_KEY_3270_BackTab 0xfd05 -#define XKB_KEY_3270_EraseEOF 0xfd06 -#define XKB_KEY_3270_EraseInput 0xfd07 -#define XKB_KEY_3270_Reset 0xfd08 -#define XKB_KEY_3270_Quit 0xfd09 -#define XKB_KEY_3270_PA1 0xfd0a -#define XKB_KEY_3270_PA2 0xfd0b -#define XKB_KEY_3270_PA3 0xfd0c -#define XKB_KEY_3270_Test 0xfd0d -#define XKB_KEY_3270_Attn 0xfd0e -#define XKB_KEY_3270_CursorBlink 0xfd0f -#define XKB_KEY_3270_AltCursor 0xfd10 -#define XKB_KEY_3270_KeyClick 0xfd11 -#define XKB_KEY_3270_Jump 0xfd12 -#define XKB_KEY_3270_Ident 0xfd13 -#define XKB_KEY_3270_Rule 0xfd14 -#define XKB_KEY_3270_Copy 0xfd15 -#define XKB_KEY_3270_Play 0xfd16 -#define XKB_KEY_3270_Setup 0xfd17 -#define XKB_KEY_3270_Record 0xfd18 -#define XKB_KEY_3270_ChangeScreen 0xfd19 -#define XKB_KEY_3270_DeleteWord 0xfd1a -#define XKB_KEY_3270_ExSelect 0xfd1b -#define XKB_KEY_3270_CursorSelect 0xfd1c -#define XKB_KEY_3270_PrintScreen 0xfd1d -#define XKB_KEY_3270_Enter 0xfd1e - -/* - * Latin 1 - * (ISO/IEC 8859-1 = Unicode U+0020..U+00FF) - * Byte 3 = 0 - */ -#define XKB_KEY_space 0x0020 /* U+0020 SPACE */ -#define XKB_KEY_exclam 0x0021 /* U+0021 EXCLAMATION MARK */ -#define XKB_KEY_quotedbl 0x0022 /* U+0022 QUOTATION MARK */ -#define XKB_KEY_numbersign 0x0023 /* U+0023 NUMBER SIGN */ -#define XKB_KEY_dollar 0x0024 /* U+0024 DOLLAR SIGN */ -#define XKB_KEY_percent 0x0025 /* U+0025 PERCENT SIGN */ -#define XKB_KEY_ampersand 0x0026 /* U+0026 AMPERSAND */ -#define XKB_KEY_apostrophe 0x0027 /* U+0027 APOSTROPHE */ -#define XKB_KEY_quoteright 0x0027 /* deprecated */ -#define XKB_KEY_parenleft 0x0028 /* U+0028 LEFT PARENTHESIS */ -#define XKB_KEY_parenright 0x0029 /* U+0029 RIGHT PARENTHESIS */ -#define XKB_KEY_asterisk 0x002a /* U+002A ASTERISK */ -#define XKB_KEY_plus 0x002b /* U+002B PLUS SIGN */ -#define XKB_KEY_comma 0x002c /* U+002C COMMA */ -#define XKB_KEY_minus 0x002d /* U+002D HYPHEN-MINUS */ -#define XKB_KEY_period 0x002e /* U+002E FULL STOP */ -#define XKB_KEY_slash 0x002f /* U+002F SOLIDUS */ -#define XKB_KEY_0 0x0030 /* U+0030 DIGIT ZERO */ -#define XKB_KEY_1 0x0031 /* U+0031 DIGIT ONE */ -#define XKB_KEY_2 0x0032 /* U+0032 DIGIT TWO */ -#define XKB_KEY_3 0x0033 /* U+0033 DIGIT THREE */ -#define XKB_KEY_4 0x0034 /* U+0034 DIGIT FOUR */ -#define XKB_KEY_5 0x0035 /* U+0035 DIGIT FIVE */ -#define XKB_KEY_6 0x0036 /* U+0036 DIGIT SIX */ -#define XKB_KEY_7 0x0037 /* U+0037 DIGIT SEVEN */ -#define XKB_KEY_8 0x0038 /* U+0038 DIGIT EIGHT */ -#define XKB_KEY_9 0x0039 /* U+0039 DIGIT NINE */ -#define XKB_KEY_colon 0x003a /* U+003A COLON */ -#define XKB_KEY_semicolon 0x003b /* U+003B SEMICOLON */ -#define XKB_KEY_less 0x003c /* U+003C LESS-THAN SIGN */ -#define XKB_KEY_equal 0x003d /* U+003D EQUALS SIGN */ -#define XKB_KEY_greater 0x003e /* U+003E GREATER-THAN SIGN */ -#define XKB_KEY_question 0x003f /* U+003F QUESTION MARK */ -#define XKB_KEY_at 0x0040 /* U+0040 COMMERCIAL AT */ -#define XKB_KEY_A 0x0041 /* U+0041 LATIN CAPITAL LETTER A */ -#define XKB_KEY_B 0x0042 /* U+0042 LATIN CAPITAL LETTER B */ -#define XKB_KEY_C 0x0043 /* U+0043 LATIN CAPITAL LETTER C */ -#define XKB_KEY_D 0x0044 /* U+0044 LATIN CAPITAL LETTER D */ -#define XKB_KEY_E 0x0045 /* U+0045 LATIN CAPITAL LETTER E */ -#define XKB_KEY_F 0x0046 /* U+0046 LATIN CAPITAL LETTER F */ -#define XKB_KEY_G 0x0047 /* U+0047 LATIN CAPITAL LETTER G */ -#define XKB_KEY_H 0x0048 /* U+0048 LATIN CAPITAL LETTER H */ -#define XKB_KEY_I 0x0049 /* U+0049 LATIN CAPITAL LETTER I */ -#define XKB_KEY_J 0x004a /* U+004A LATIN CAPITAL LETTER J */ -#define XKB_KEY_K 0x004b /* U+004B LATIN CAPITAL LETTER K */ -#define XKB_KEY_L 0x004c /* U+004C LATIN CAPITAL LETTER L */ -#define XKB_KEY_M 0x004d /* U+004D LATIN CAPITAL LETTER M */ -#define XKB_KEY_N 0x004e /* U+004E LATIN CAPITAL LETTER N */ -#define XKB_KEY_O 0x004f /* U+004F LATIN CAPITAL LETTER O */ -#define XKB_KEY_P 0x0050 /* U+0050 LATIN CAPITAL LETTER P */ -#define XKB_KEY_Q 0x0051 /* U+0051 LATIN CAPITAL LETTER Q */ -#define XKB_KEY_R 0x0052 /* U+0052 LATIN CAPITAL LETTER R */ -#define XKB_KEY_S 0x0053 /* U+0053 LATIN CAPITAL LETTER S */ -#define XKB_KEY_T 0x0054 /* U+0054 LATIN CAPITAL LETTER T */ -#define XKB_KEY_U 0x0055 /* U+0055 LATIN CAPITAL LETTER U */ -#define XKB_KEY_V 0x0056 /* U+0056 LATIN CAPITAL LETTER V */ -#define XKB_KEY_W 0x0057 /* U+0057 LATIN CAPITAL LETTER W */ -#define XKB_KEY_X 0x0058 /* U+0058 LATIN CAPITAL LETTER X */ -#define XKB_KEY_Y 0x0059 /* U+0059 LATIN CAPITAL LETTER Y */ -#define XKB_KEY_Z 0x005a /* U+005A LATIN CAPITAL LETTER Z */ -#define XKB_KEY_bracketleft 0x005b /* U+005B LEFT SQUARE BRACKET */ -#define XKB_KEY_backslash 0x005c /* U+005C REVERSE SOLIDUS */ -#define XKB_KEY_bracketright 0x005d /* U+005D RIGHT SQUARE BRACKET */ -#define XKB_KEY_asciicircum 0x005e /* U+005E CIRCUMFLEX ACCENT */ -#define XKB_KEY_underscore 0x005f /* U+005F LOW LINE */ -#define XKB_KEY_grave 0x0060 /* U+0060 GRAVE ACCENT */ -#define XKB_KEY_quoteleft 0x0060 /* deprecated */ -#define XKB_KEY_a 0x0061 /* U+0061 LATIN SMALL LETTER A */ -#define XKB_KEY_b 0x0062 /* U+0062 LATIN SMALL LETTER B */ -#define XKB_KEY_c 0x0063 /* U+0063 LATIN SMALL LETTER C */ -#define XKB_KEY_d 0x0064 /* U+0064 LATIN SMALL LETTER D */ -#define XKB_KEY_e 0x0065 /* U+0065 LATIN SMALL LETTER E */ -#define XKB_KEY_f 0x0066 /* U+0066 LATIN SMALL LETTER F */ -#define XKB_KEY_g 0x0067 /* U+0067 LATIN SMALL LETTER G */ -#define XKB_KEY_h 0x0068 /* U+0068 LATIN SMALL LETTER H */ -#define XKB_KEY_i 0x0069 /* U+0069 LATIN SMALL LETTER I */ -#define XKB_KEY_j 0x006a /* U+006A LATIN SMALL LETTER J */ -#define XKB_KEY_k 0x006b /* U+006B LATIN SMALL LETTER K */ -#define XKB_KEY_l 0x006c /* U+006C LATIN SMALL LETTER L */ -#define XKB_KEY_m 0x006d /* U+006D LATIN SMALL LETTER M */ -#define XKB_KEY_n 0x006e /* U+006E LATIN SMALL LETTER N */ -#define XKB_KEY_o 0x006f /* U+006F LATIN SMALL LETTER O */ -#define XKB_KEY_p 0x0070 /* U+0070 LATIN SMALL LETTER P */ -#define XKB_KEY_q 0x0071 /* U+0071 LATIN SMALL LETTER Q */ -#define XKB_KEY_r 0x0072 /* U+0072 LATIN SMALL LETTER R */ -#define XKB_KEY_s 0x0073 /* U+0073 LATIN SMALL LETTER S */ -#define XKB_KEY_t 0x0074 /* U+0074 LATIN SMALL LETTER T */ -#define XKB_KEY_u 0x0075 /* U+0075 LATIN SMALL LETTER U */ -#define XKB_KEY_v 0x0076 /* U+0076 LATIN SMALL LETTER V */ -#define XKB_KEY_w 0x0077 /* U+0077 LATIN SMALL LETTER W */ -#define XKB_KEY_x 0x0078 /* U+0078 LATIN SMALL LETTER X */ -#define XKB_KEY_y 0x0079 /* U+0079 LATIN SMALL LETTER Y */ -#define XKB_KEY_z 0x007a /* U+007A LATIN SMALL LETTER Z */ -#define XKB_KEY_braceleft 0x007b /* U+007B LEFT CURLY BRACKET */ -#define XKB_KEY_bar 0x007c /* U+007C VERTICAL LINE */ -#define XKB_KEY_braceright 0x007d /* U+007D RIGHT CURLY BRACKET */ -#define XKB_KEY_asciitilde 0x007e /* U+007E TILDE */ - -#define XKB_KEY_nobreakspace 0x00a0 /* U+00A0 NO-BREAK SPACE */ -#define XKB_KEY_exclamdown 0x00a1 /* U+00A1 INVERTED EXCLAMATION MARK */ -#define XKB_KEY_cent 0x00a2 /* U+00A2 CENT SIGN */ -#define XKB_KEY_sterling 0x00a3 /* U+00A3 POUND SIGN */ -#define XKB_KEY_currency 0x00a4 /* U+00A4 CURRENCY SIGN */ -#define XKB_KEY_yen 0x00a5 /* U+00A5 YEN SIGN */ -#define XKB_KEY_brokenbar 0x00a6 /* U+00A6 BROKEN BAR */ -#define XKB_KEY_section 0x00a7 /* U+00A7 SECTION SIGN */ -#define XKB_KEY_diaeresis 0x00a8 /* U+00A8 DIAERESIS */ -#define XKB_KEY_copyright 0x00a9 /* U+00A9 COPYRIGHT SIGN */ -#define XKB_KEY_ordfeminine 0x00aa /* U+00AA FEMININE ORDINAL INDICATOR */ -#define XKB_KEY_guillemotleft 0x00ab /* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ -#define XKB_KEY_notsign 0x00ac /* U+00AC NOT SIGN */ -#define XKB_KEY_hyphen 0x00ad /* U+00AD SOFT HYPHEN */ -#define XKB_KEY_registered 0x00ae /* U+00AE REGISTERED SIGN */ -#define XKB_KEY_macron 0x00af /* U+00AF MACRON */ -#define XKB_KEY_degree 0x00b0 /* U+00B0 DEGREE SIGN */ -#define XKB_KEY_plusminus 0x00b1 /* U+00B1 PLUS-MINUS SIGN */ -#define XKB_KEY_twosuperior 0x00b2 /* U+00B2 SUPERSCRIPT TWO */ -#define XKB_KEY_threesuperior 0x00b3 /* U+00B3 SUPERSCRIPT THREE */ -#define XKB_KEY_acute 0x00b4 /* U+00B4 ACUTE ACCENT */ -#define XKB_KEY_mu 0x00b5 /* U+00B5 MICRO SIGN */ -#define XKB_KEY_paragraph 0x00b6 /* U+00B6 PILCROW SIGN */ -#define XKB_KEY_periodcentered 0x00b7 /* U+00B7 MIDDLE DOT */ -#define XKB_KEY_cedilla 0x00b8 /* U+00B8 CEDILLA */ -#define XKB_KEY_onesuperior 0x00b9 /* U+00B9 SUPERSCRIPT ONE */ -#define XKB_KEY_masculine 0x00ba /* U+00BA MASCULINE ORDINAL INDICATOR */ -#define XKB_KEY_guillemotright 0x00bb /* U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ -#define XKB_KEY_onequarter 0x00bc /* U+00BC VULGAR FRACTION ONE QUARTER */ -#define XKB_KEY_onehalf 0x00bd /* U+00BD VULGAR FRACTION ONE HALF */ -#define XKB_KEY_threequarters 0x00be /* U+00BE VULGAR FRACTION THREE QUARTERS */ -#define XKB_KEY_questiondown 0x00bf /* U+00BF INVERTED QUESTION MARK */ -#define XKB_KEY_Agrave 0x00c0 /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE */ -#define XKB_KEY_Aacute 0x00c1 /* U+00C1 LATIN CAPITAL LETTER A WITH ACUTE */ -#define XKB_KEY_Acircumflex 0x00c2 /* U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX */ -#define XKB_KEY_Atilde 0x00c3 /* U+00C3 LATIN CAPITAL LETTER A WITH TILDE */ -#define XKB_KEY_Adiaeresis 0x00c4 /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */ -#define XKB_KEY_Aring 0x00c5 /* U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE */ -#define XKB_KEY_AE 0x00c6 /* U+00C6 LATIN CAPITAL LETTER AE */ -#define XKB_KEY_Ccedilla 0x00c7 /* U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA */ -#define XKB_KEY_Egrave 0x00c8 /* U+00C8 LATIN CAPITAL LETTER E WITH GRAVE */ -#define XKB_KEY_Eacute 0x00c9 /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */ -#define XKB_KEY_Ecircumflex 0x00ca /* U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX */ -#define XKB_KEY_Ediaeresis 0x00cb /* U+00CB LATIN CAPITAL LETTER E WITH DIAERESIS */ -#define XKB_KEY_Igrave 0x00cc /* U+00CC LATIN CAPITAL LETTER I WITH GRAVE */ -#define XKB_KEY_Iacute 0x00cd /* U+00CD LATIN CAPITAL LETTER I WITH ACUTE */ -#define XKB_KEY_Icircumflex 0x00ce /* U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX */ -#define XKB_KEY_Idiaeresis 0x00cf /* U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS */ -#define XKB_KEY_ETH 0x00d0 /* U+00D0 LATIN CAPITAL LETTER ETH */ -#define XKB_KEY_Eth 0x00d0 /* deprecated */ -#define XKB_KEY_Ntilde 0x00d1 /* U+00D1 LATIN CAPITAL LETTER N WITH TILDE */ -#define XKB_KEY_Ograve 0x00d2 /* U+00D2 LATIN CAPITAL LETTER O WITH GRAVE */ -#define XKB_KEY_Oacute 0x00d3 /* U+00D3 LATIN CAPITAL LETTER O WITH ACUTE */ -#define XKB_KEY_Ocircumflex 0x00d4 /* U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX */ -#define XKB_KEY_Otilde 0x00d5 /* U+00D5 LATIN CAPITAL LETTER O WITH TILDE */ -#define XKB_KEY_Odiaeresis 0x00d6 /* U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS */ -#define XKB_KEY_multiply 0x00d7 /* U+00D7 MULTIPLICATION SIGN */ -#define XKB_KEY_Oslash 0x00d8 /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ -#define XKB_KEY_Ooblique 0x00d8 /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ -#define XKB_KEY_Ugrave 0x00d9 /* U+00D9 LATIN CAPITAL LETTER U WITH GRAVE */ -#define XKB_KEY_Uacute 0x00da /* U+00DA LATIN CAPITAL LETTER U WITH ACUTE */ -#define XKB_KEY_Ucircumflex 0x00db /* U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX */ -#define XKB_KEY_Udiaeresis 0x00dc /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */ -#define XKB_KEY_Yacute 0x00dd /* U+00DD LATIN CAPITAL LETTER Y WITH ACUTE */ -#define XKB_KEY_THORN 0x00de /* U+00DE LATIN CAPITAL LETTER THORN */ -#define XKB_KEY_Thorn 0x00de /* deprecated */ -#define XKB_KEY_ssharp 0x00df /* U+00DF LATIN SMALL LETTER SHARP S */ -#define XKB_KEY_agrave 0x00e0 /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */ -#define XKB_KEY_aacute 0x00e1 /* U+00E1 LATIN SMALL LETTER A WITH ACUTE */ -#define XKB_KEY_acircumflex 0x00e2 /* U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX */ -#define XKB_KEY_atilde 0x00e3 /* U+00E3 LATIN SMALL LETTER A WITH TILDE */ -#define XKB_KEY_adiaeresis 0x00e4 /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */ -#define XKB_KEY_aring 0x00e5 /* U+00E5 LATIN SMALL LETTER A WITH RING ABOVE */ -#define XKB_KEY_ae 0x00e6 /* U+00E6 LATIN SMALL LETTER AE */ -#define XKB_KEY_ccedilla 0x00e7 /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */ -#define XKB_KEY_egrave 0x00e8 /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */ -#define XKB_KEY_eacute 0x00e9 /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */ -#define XKB_KEY_ecircumflex 0x00ea /* U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX */ -#define XKB_KEY_ediaeresis 0x00eb /* U+00EB LATIN SMALL LETTER E WITH DIAERESIS */ -#define XKB_KEY_igrave 0x00ec /* U+00EC LATIN SMALL LETTER I WITH GRAVE */ -#define XKB_KEY_iacute 0x00ed /* U+00ED LATIN SMALL LETTER I WITH ACUTE */ -#define XKB_KEY_icircumflex 0x00ee /* U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX */ -#define XKB_KEY_idiaeresis 0x00ef /* U+00EF LATIN SMALL LETTER I WITH DIAERESIS */ -#define XKB_KEY_eth 0x00f0 /* U+00F0 LATIN SMALL LETTER ETH */ -#define XKB_KEY_ntilde 0x00f1 /* U+00F1 LATIN SMALL LETTER N WITH TILDE */ -#define XKB_KEY_ograve 0x00f2 /* U+00F2 LATIN SMALL LETTER O WITH GRAVE */ -#define XKB_KEY_oacute 0x00f3 /* U+00F3 LATIN SMALL LETTER O WITH ACUTE */ -#define XKB_KEY_ocircumflex 0x00f4 /* U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX */ -#define XKB_KEY_otilde 0x00f5 /* U+00F5 LATIN SMALL LETTER O WITH TILDE */ -#define XKB_KEY_odiaeresis 0x00f6 /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */ -#define XKB_KEY_division 0x00f7 /* U+00F7 DIVISION SIGN */ -#define XKB_KEY_oslash 0x00f8 /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ -#define XKB_KEY_ooblique 0x00f8 /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ -#define XKB_KEY_ugrave 0x00f9 /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */ -#define XKB_KEY_uacute 0x00fa /* U+00FA LATIN SMALL LETTER U WITH ACUTE */ -#define XKB_KEY_ucircumflex 0x00fb /* U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX */ -#define XKB_KEY_udiaeresis 0x00fc /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */ -#define XKB_KEY_yacute 0x00fd /* U+00FD LATIN SMALL LETTER Y WITH ACUTE */ -#define XKB_KEY_thorn 0x00fe /* U+00FE LATIN SMALL LETTER THORN */ -#define XKB_KEY_ydiaeresis 0x00ff /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */ - -/* - * Latin 2 - * Byte 3 = 1 - */ - -#define XKB_KEY_Aogonek 0x01a1 /* U+0104 LATIN CAPITAL LETTER A WITH OGONEK */ -#define XKB_KEY_breve 0x01a2 /* U+02D8 BREVE */ -#define XKB_KEY_Lstroke 0x01a3 /* U+0141 LATIN CAPITAL LETTER L WITH STROKE */ -#define XKB_KEY_Lcaron 0x01a5 /* U+013D LATIN CAPITAL LETTER L WITH CARON */ -#define XKB_KEY_Sacute 0x01a6 /* U+015A LATIN CAPITAL LETTER S WITH ACUTE */ -#define XKB_KEY_Scaron 0x01a9 /* U+0160 LATIN CAPITAL LETTER S WITH CARON */ -#define XKB_KEY_Scedilla 0x01aa /* U+015E LATIN CAPITAL LETTER S WITH CEDILLA */ -#define XKB_KEY_Tcaron 0x01ab /* U+0164 LATIN CAPITAL LETTER T WITH CARON */ -#define XKB_KEY_Zacute 0x01ac /* U+0179 LATIN CAPITAL LETTER Z WITH ACUTE */ -#define XKB_KEY_Zcaron 0x01ae /* U+017D LATIN CAPITAL LETTER Z WITH CARON */ -#define XKB_KEY_Zabovedot 0x01af /* U+017B LATIN CAPITAL LETTER Z WITH DOT ABOVE */ -#define XKB_KEY_aogonek 0x01b1 /* U+0105 LATIN SMALL LETTER A WITH OGONEK */ -#define XKB_KEY_ogonek 0x01b2 /* U+02DB OGONEK */ -#define XKB_KEY_lstroke 0x01b3 /* U+0142 LATIN SMALL LETTER L WITH STROKE */ -#define XKB_KEY_lcaron 0x01b5 /* U+013E LATIN SMALL LETTER L WITH CARON */ -#define XKB_KEY_sacute 0x01b6 /* U+015B LATIN SMALL LETTER S WITH ACUTE */ -#define XKB_KEY_caron 0x01b7 /* U+02C7 CARON */ -#define XKB_KEY_scaron 0x01b9 /* U+0161 LATIN SMALL LETTER S WITH CARON */ -#define XKB_KEY_scedilla 0x01ba /* U+015F LATIN SMALL LETTER S WITH CEDILLA */ -#define XKB_KEY_tcaron 0x01bb /* U+0165 LATIN SMALL LETTER T WITH CARON */ -#define XKB_KEY_zacute 0x01bc /* U+017A LATIN SMALL LETTER Z WITH ACUTE */ -#define XKB_KEY_doubleacute 0x01bd /* U+02DD DOUBLE ACUTE ACCENT */ -#define XKB_KEY_zcaron 0x01be /* U+017E LATIN SMALL LETTER Z WITH CARON */ -#define XKB_KEY_zabovedot 0x01bf /* U+017C LATIN SMALL LETTER Z WITH DOT ABOVE */ -#define XKB_KEY_Racute 0x01c0 /* U+0154 LATIN CAPITAL LETTER R WITH ACUTE */ -#define XKB_KEY_Abreve 0x01c3 /* U+0102 LATIN CAPITAL LETTER A WITH BREVE */ -#define XKB_KEY_Lacute 0x01c5 /* U+0139 LATIN CAPITAL LETTER L WITH ACUTE */ -#define XKB_KEY_Cacute 0x01c6 /* U+0106 LATIN CAPITAL LETTER C WITH ACUTE */ -#define XKB_KEY_Ccaron 0x01c8 /* U+010C LATIN CAPITAL LETTER C WITH CARON */ -#define XKB_KEY_Eogonek 0x01ca /* U+0118 LATIN CAPITAL LETTER E WITH OGONEK */ -#define XKB_KEY_Ecaron 0x01cc /* U+011A LATIN CAPITAL LETTER E WITH CARON */ -#define XKB_KEY_Dcaron 0x01cf /* U+010E LATIN CAPITAL LETTER D WITH CARON */ -#define XKB_KEY_Dstroke 0x01d0 /* U+0110 LATIN CAPITAL LETTER D WITH STROKE */ -#define XKB_KEY_Nacute 0x01d1 /* U+0143 LATIN CAPITAL LETTER N WITH ACUTE */ -#define XKB_KEY_Ncaron 0x01d2 /* U+0147 LATIN CAPITAL LETTER N WITH CARON */ -#define XKB_KEY_Odoubleacute 0x01d5 /* U+0150 LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */ -#define XKB_KEY_Rcaron 0x01d8 /* U+0158 LATIN CAPITAL LETTER R WITH CARON */ -#define XKB_KEY_Uring 0x01d9 /* U+016E LATIN CAPITAL LETTER U WITH RING ABOVE */ -#define XKB_KEY_Udoubleacute 0x01db /* U+0170 LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */ -#define XKB_KEY_Tcedilla 0x01de /* U+0162 LATIN CAPITAL LETTER T WITH CEDILLA */ -#define XKB_KEY_racute 0x01e0 /* U+0155 LATIN SMALL LETTER R WITH ACUTE */ -#define XKB_KEY_abreve 0x01e3 /* U+0103 LATIN SMALL LETTER A WITH BREVE */ -#define XKB_KEY_lacute 0x01e5 /* U+013A LATIN SMALL LETTER L WITH ACUTE */ -#define XKB_KEY_cacute 0x01e6 /* U+0107 LATIN SMALL LETTER C WITH ACUTE */ -#define XKB_KEY_ccaron 0x01e8 /* U+010D LATIN SMALL LETTER C WITH CARON */ -#define XKB_KEY_eogonek 0x01ea /* U+0119 LATIN SMALL LETTER E WITH OGONEK */ -#define XKB_KEY_ecaron 0x01ec /* U+011B LATIN SMALL LETTER E WITH CARON */ -#define XKB_KEY_dcaron 0x01ef /* U+010F LATIN SMALL LETTER D WITH CARON */ -#define XKB_KEY_dstroke 0x01f0 /* U+0111 LATIN SMALL LETTER D WITH STROKE */ -#define XKB_KEY_nacute 0x01f1 /* U+0144 LATIN SMALL LETTER N WITH ACUTE */ -#define XKB_KEY_ncaron 0x01f2 /* U+0148 LATIN SMALL LETTER N WITH CARON */ -#define XKB_KEY_odoubleacute 0x01f5 /* U+0151 LATIN SMALL LETTER O WITH DOUBLE ACUTE */ -#define XKB_KEY_rcaron 0x01f8 /* U+0159 LATIN SMALL LETTER R WITH CARON */ -#define XKB_KEY_uring 0x01f9 /* U+016F LATIN SMALL LETTER U WITH RING ABOVE */ -#define XKB_KEY_udoubleacute 0x01fb /* U+0171 LATIN SMALL LETTER U WITH DOUBLE ACUTE */ -#define XKB_KEY_tcedilla 0x01fe /* U+0163 LATIN SMALL LETTER T WITH CEDILLA */ -#define XKB_KEY_abovedot 0x01ff /* U+02D9 DOT ABOVE */ - -/* - * Latin 3 - * Byte 3 = 2 - */ - -#define XKB_KEY_Hstroke 0x02a1 /* U+0126 LATIN CAPITAL LETTER H WITH STROKE */ -#define XKB_KEY_Hcircumflex 0x02a6 /* U+0124 LATIN CAPITAL LETTER H WITH CIRCUMFLEX */ -#define XKB_KEY_Iabovedot 0x02a9 /* U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE */ -#define XKB_KEY_Gbreve 0x02ab /* U+011E LATIN CAPITAL LETTER G WITH BREVE */ -#define XKB_KEY_Jcircumflex 0x02ac /* U+0134 LATIN CAPITAL LETTER J WITH CIRCUMFLEX */ -#define XKB_KEY_hstroke 0x02b1 /* U+0127 LATIN SMALL LETTER H WITH STROKE */ -#define XKB_KEY_hcircumflex 0x02b6 /* U+0125 LATIN SMALL LETTER H WITH CIRCUMFLEX */ -#define XKB_KEY_idotless 0x02b9 /* U+0131 LATIN SMALL LETTER DOTLESS I */ -#define XKB_KEY_gbreve 0x02bb /* U+011F LATIN SMALL LETTER G WITH BREVE */ -#define XKB_KEY_jcircumflex 0x02bc /* U+0135 LATIN SMALL LETTER J WITH CIRCUMFLEX */ -#define XKB_KEY_Cabovedot 0x02c5 /* U+010A LATIN CAPITAL LETTER C WITH DOT ABOVE */ -#define XKB_KEY_Ccircumflex 0x02c6 /* U+0108 LATIN CAPITAL LETTER C WITH CIRCUMFLEX */ -#define XKB_KEY_Gabovedot 0x02d5 /* U+0120 LATIN CAPITAL LETTER G WITH DOT ABOVE */ -#define XKB_KEY_Gcircumflex 0x02d8 /* U+011C LATIN CAPITAL LETTER G WITH CIRCUMFLEX */ -#define XKB_KEY_Ubreve 0x02dd /* U+016C LATIN CAPITAL LETTER U WITH BREVE */ -#define XKB_KEY_Scircumflex 0x02de /* U+015C LATIN CAPITAL LETTER S WITH CIRCUMFLEX */ -#define XKB_KEY_cabovedot 0x02e5 /* U+010B LATIN SMALL LETTER C WITH DOT ABOVE */ -#define XKB_KEY_ccircumflex 0x02e6 /* U+0109 LATIN SMALL LETTER C WITH CIRCUMFLEX */ -#define XKB_KEY_gabovedot 0x02f5 /* U+0121 LATIN SMALL LETTER G WITH DOT ABOVE */ -#define XKB_KEY_gcircumflex 0x02f8 /* U+011D LATIN SMALL LETTER G WITH CIRCUMFLEX */ -#define XKB_KEY_ubreve 0x02fd /* U+016D LATIN SMALL LETTER U WITH BREVE */ -#define XKB_KEY_scircumflex 0x02fe /* U+015D LATIN SMALL LETTER S WITH CIRCUMFLEX */ - - -/* - * Latin 4 - * Byte 3 = 3 - */ - -#define XKB_KEY_kra 0x03a2 /* U+0138 LATIN SMALL LETTER KRA */ -#define XKB_KEY_kappa 0x03a2 /* deprecated */ -#define XKB_KEY_Rcedilla 0x03a3 /* U+0156 LATIN CAPITAL LETTER R WITH CEDILLA */ -#define XKB_KEY_Itilde 0x03a5 /* U+0128 LATIN CAPITAL LETTER I WITH TILDE */ -#define XKB_KEY_Lcedilla 0x03a6 /* U+013B LATIN CAPITAL LETTER L WITH CEDILLA */ -#define XKB_KEY_Emacron 0x03aa /* U+0112 LATIN CAPITAL LETTER E WITH MACRON */ -#define XKB_KEY_Gcedilla 0x03ab /* U+0122 LATIN CAPITAL LETTER G WITH CEDILLA */ -#define XKB_KEY_Tslash 0x03ac /* U+0166 LATIN CAPITAL LETTER T WITH STROKE */ -#define XKB_KEY_rcedilla 0x03b3 /* U+0157 LATIN SMALL LETTER R WITH CEDILLA */ -#define XKB_KEY_itilde 0x03b5 /* U+0129 LATIN SMALL LETTER I WITH TILDE */ -#define XKB_KEY_lcedilla 0x03b6 /* U+013C LATIN SMALL LETTER L WITH CEDILLA */ -#define XKB_KEY_emacron 0x03ba /* U+0113 LATIN SMALL LETTER E WITH MACRON */ -#define XKB_KEY_gcedilla 0x03bb /* U+0123 LATIN SMALL LETTER G WITH CEDILLA */ -#define XKB_KEY_tslash 0x03bc /* U+0167 LATIN SMALL LETTER T WITH STROKE */ -#define XKB_KEY_ENG 0x03bd /* U+014A LATIN CAPITAL LETTER ENG */ -#define XKB_KEY_eng 0x03bf /* U+014B LATIN SMALL LETTER ENG */ -#define XKB_KEY_Amacron 0x03c0 /* U+0100 LATIN CAPITAL LETTER A WITH MACRON */ -#define XKB_KEY_Iogonek 0x03c7 /* U+012E LATIN CAPITAL LETTER I WITH OGONEK */ -#define XKB_KEY_Eabovedot 0x03cc /* U+0116 LATIN CAPITAL LETTER E WITH DOT ABOVE */ -#define XKB_KEY_Imacron 0x03cf /* U+012A LATIN CAPITAL LETTER I WITH MACRON */ -#define XKB_KEY_Ncedilla 0x03d1 /* U+0145 LATIN CAPITAL LETTER N WITH CEDILLA */ -#define XKB_KEY_Omacron 0x03d2 /* U+014C LATIN CAPITAL LETTER O WITH MACRON */ -#define XKB_KEY_Kcedilla 0x03d3 /* U+0136 LATIN CAPITAL LETTER K WITH CEDILLA */ -#define XKB_KEY_Uogonek 0x03d9 /* U+0172 LATIN CAPITAL LETTER U WITH OGONEK */ -#define XKB_KEY_Utilde 0x03dd /* U+0168 LATIN CAPITAL LETTER U WITH TILDE */ -#define XKB_KEY_Umacron 0x03de /* U+016A LATIN CAPITAL LETTER U WITH MACRON */ -#define XKB_KEY_amacron 0x03e0 /* U+0101 LATIN SMALL LETTER A WITH MACRON */ -#define XKB_KEY_iogonek 0x03e7 /* U+012F LATIN SMALL LETTER I WITH OGONEK */ -#define XKB_KEY_eabovedot 0x03ec /* U+0117 LATIN SMALL LETTER E WITH DOT ABOVE */ -#define XKB_KEY_imacron 0x03ef /* U+012B LATIN SMALL LETTER I WITH MACRON */ -#define XKB_KEY_ncedilla 0x03f1 /* U+0146 LATIN SMALL LETTER N WITH CEDILLA */ -#define XKB_KEY_omacron 0x03f2 /* U+014D LATIN SMALL LETTER O WITH MACRON */ -#define XKB_KEY_kcedilla 0x03f3 /* U+0137 LATIN SMALL LETTER K WITH CEDILLA */ -#define XKB_KEY_uogonek 0x03f9 /* U+0173 LATIN SMALL LETTER U WITH OGONEK */ -#define XKB_KEY_utilde 0x03fd /* U+0169 LATIN SMALL LETTER U WITH TILDE */ -#define XKB_KEY_umacron 0x03fe /* U+016B LATIN SMALL LETTER U WITH MACRON */ - -/* - * Latin 8 - */ -#define XKB_KEY_Wcircumflex 0x1000174 /* U+0174 LATIN CAPITAL LETTER W WITH CIRCUMFLEX */ -#define XKB_KEY_wcircumflex 0x1000175 /* U+0175 LATIN SMALL LETTER W WITH CIRCUMFLEX */ -#define XKB_KEY_Ycircumflex 0x1000176 /* U+0176 LATIN CAPITAL LETTER Y WITH CIRCUMFLEX */ -#define XKB_KEY_ycircumflex 0x1000177 /* U+0177 LATIN SMALL LETTER Y WITH CIRCUMFLEX */ -#define XKB_KEY_Babovedot 0x1001e02 /* U+1E02 LATIN CAPITAL LETTER B WITH DOT ABOVE */ -#define XKB_KEY_babovedot 0x1001e03 /* U+1E03 LATIN SMALL LETTER B WITH DOT ABOVE */ -#define XKB_KEY_Dabovedot 0x1001e0a /* U+1E0A LATIN CAPITAL LETTER D WITH DOT ABOVE */ -#define XKB_KEY_dabovedot 0x1001e0b /* U+1E0B LATIN SMALL LETTER D WITH DOT ABOVE */ -#define XKB_KEY_Fabovedot 0x1001e1e /* U+1E1E LATIN CAPITAL LETTER F WITH DOT ABOVE */ -#define XKB_KEY_fabovedot 0x1001e1f /* U+1E1F LATIN SMALL LETTER F WITH DOT ABOVE */ -#define XKB_KEY_Mabovedot 0x1001e40 /* U+1E40 LATIN CAPITAL LETTER M WITH DOT ABOVE */ -#define XKB_KEY_mabovedot 0x1001e41 /* U+1E41 LATIN SMALL LETTER M WITH DOT ABOVE */ -#define XKB_KEY_Pabovedot 0x1001e56 /* U+1E56 LATIN CAPITAL LETTER P WITH DOT ABOVE */ -#define XKB_KEY_pabovedot 0x1001e57 /* U+1E57 LATIN SMALL LETTER P WITH DOT ABOVE */ -#define XKB_KEY_Sabovedot 0x1001e60 /* U+1E60 LATIN CAPITAL LETTER S WITH DOT ABOVE */ -#define XKB_KEY_sabovedot 0x1001e61 /* U+1E61 LATIN SMALL LETTER S WITH DOT ABOVE */ -#define XKB_KEY_Tabovedot 0x1001e6a /* U+1E6A LATIN CAPITAL LETTER T WITH DOT ABOVE */ -#define XKB_KEY_tabovedot 0x1001e6b /* U+1E6B LATIN SMALL LETTER T WITH DOT ABOVE */ -#define XKB_KEY_Wgrave 0x1001e80 /* U+1E80 LATIN CAPITAL LETTER W WITH GRAVE */ -#define XKB_KEY_wgrave 0x1001e81 /* U+1E81 LATIN SMALL LETTER W WITH GRAVE */ -#define XKB_KEY_Wacute 0x1001e82 /* U+1E82 LATIN CAPITAL LETTER W WITH ACUTE */ -#define XKB_KEY_wacute 0x1001e83 /* U+1E83 LATIN SMALL LETTER W WITH ACUTE */ -#define XKB_KEY_Wdiaeresis 0x1001e84 /* U+1E84 LATIN CAPITAL LETTER W WITH DIAERESIS */ -#define XKB_KEY_wdiaeresis 0x1001e85 /* U+1E85 LATIN SMALL LETTER W WITH DIAERESIS */ -#define XKB_KEY_Ygrave 0x1001ef2 /* U+1EF2 LATIN CAPITAL LETTER Y WITH GRAVE */ -#define XKB_KEY_ygrave 0x1001ef3 /* U+1EF3 LATIN SMALL LETTER Y WITH GRAVE */ - -/* - * Latin 9 - * Byte 3 = 0x13 - */ - -#define XKB_KEY_OE 0x13bc /* U+0152 LATIN CAPITAL LIGATURE OE */ -#define XKB_KEY_oe 0x13bd /* U+0153 LATIN SMALL LIGATURE OE */ -#define XKB_KEY_Ydiaeresis 0x13be /* U+0178 LATIN CAPITAL LETTER Y WITH DIAERESIS */ - -/* - * Katakana - * Byte 3 = 4 - */ - -#define XKB_KEY_overline 0x047e /* U+203E OVERLINE */ -#define XKB_KEY_kana_fullstop 0x04a1 /* U+3002 IDEOGRAPHIC FULL STOP */ -#define XKB_KEY_kana_openingbracket 0x04a2 /* U+300C LEFT CORNER BRACKET */ -#define XKB_KEY_kana_closingbracket 0x04a3 /* U+300D RIGHT CORNER BRACKET */ -#define XKB_KEY_kana_comma 0x04a4 /* U+3001 IDEOGRAPHIC COMMA */ -#define XKB_KEY_kana_conjunctive 0x04a5 /* U+30FB KATAKANA MIDDLE DOT */ -#define XKB_KEY_kana_middledot 0x04a5 /* deprecated */ -#define XKB_KEY_kana_WO 0x04a6 /* U+30F2 KATAKANA LETTER WO */ -#define XKB_KEY_kana_a 0x04a7 /* U+30A1 KATAKANA LETTER SMALL A */ -#define XKB_KEY_kana_i 0x04a8 /* U+30A3 KATAKANA LETTER SMALL I */ -#define XKB_KEY_kana_u 0x04a9 /* U+30A5 KATAKANA LETTER SMALL U */ -#define XKB_KEY_kana_e 0x04aa /* U+30A7 KATAKANA LETTER SMALL E */ -#define XKB_KEY_kana_o 0x04ab /* U+30A9 KATAKANA LETTER SMALL O */ -#define XKB_KEY_kana_ya 0x04ac /* U+30E3 KATAKANA LETTER SMALL YA */ -#define XKB_KEY_kana_yu 0x04ad /* U+30E5 KATAKANA LETTER SMALL YU */ -#define XKB_KEY_kana_yo 0x04ae /* U+30E7 KATAKANA LETTER SMALL YO */ -#define XKB_KEY_kana_tsu 0x04af /* U+30C3 KATAKANA LETTER SMALL TU */ -#define XKB_KEY_kana_tu 0x04af /* deprecated */ -#define XKB_KEY_prolongedsound 0x04b0 /* U+30FC KATAKANA-HIRAGANA PROLONGED SOUND MARK */ -#define XKB_KEY_kana_A 0x04b1 /* U+30A2 KATAKANA LETTER A */ -#define XKB_KEY_kana_I 0x04b2 /* U+30A4 KATAKANA LETTER I */ -#define XKB_KEY_kana_U 0x04b3 /* U+30A6 KATAKANA LETTER U */ -#define XKB_KEY_kana_E 0x04b4 /* U+30A8 KATAKANA LETTER E */ -#define XKB_KEY_kana_O 0x04b5 /* U+30AA KATAKANA LETTER O */ -#define XKB_KEY_kana_KA 0x04b6 /* U+30AB KATAKANA LETTER KA */ -#define XKB_KEY_kana_KI 0x04b7 /* U+30AD KATAKANA LETTER KI */ -#define XKB_KEY_kana_KU 0x04b8 /* U+30AF KATAKANA LETTER KU */ -#define XKB_KEY_kana_KE 0x04b9 /* U+30B1 KATAKANA LETTER KE */ -#define XKB_KEY_kana_KO 0x04ba /* U+30B3 KATAKANA LETTER KO */ -#define XKB_KEY_kana_SA 0x04bb /* U+30B5 KATAKANA LETTER SA */ -#define XKB_KEY_kana_SHI 0x04bc /* U+30B7 KATAKANA LETTER SI */ -#define XKB_KEY_kana_SU 0x04bd /* U+30B9 KATAKANA LETTER SU */ -#define XKB_KEY_kana_SE 0x04be /* U+30BB KATAKANA LETTER SE */ -#define XKB_KEY_kana_SO 0x04bf /* U+30BD KATAKANA LETTER SO */ -#define XKB_KEY_kana_TA 0x04c0 /* U+30BF KATAKANA LETTER TA */ -#define XKB_KEY_kana_CHI 0x04c1 /* U+30C1 KATAKANA LETTER TI */ -#define XKB_KEY_kana_TI 0x04c1 /* deprecated */ -#define XKB_KEY_kana_TSU 0x04c2 /* U+30C4 KATAKANA LETTER TU */ -#define XKB_KEY_kana_TU 0x04c2 /* deprecated */ -#define XKB_KEY_kana_TE 0x04c3 /* U+30C6 KATAKANA LETTER TE */ -#define XKB_KEY_kana_TO 0x04c4 /* U+30C8 KATAKANA LETTER TO */ -#define XKB_KEY_kana_NA 0x04c5 /* U+30CA KATAKANA LETTER NA */ -#define XKB_KEY_kana_NI 0x04c6 /* U+30CB KATAKANA LETTER NI */ -#define XKB_KEY_kana_NU 0x04c7 /* U+30CC KATAKANA LETTER NU */ -#define XKB_KEY_kana_NE 0x04c8 /* U+30CD KATAKANA LETTER NE */ -#define XKB_KEY_kana_NO 0x04c9 /* U+30CE KATAKANA LETTER NO */ -#define XKB_KEY_kana_HA 0x04ca /* U+30CF KATAKANA LETTER HA */ -#define XKB_KEY_kana_HI 0x04cb /* U+30D2 KATAKANA LETTER HI */ -#define XKB_KEY_kana_FU 0x04cc /* U+30D5 KATAKANA LETTER HU */ -#define XKB_KEY_kana_HU 0x04cc /* deprecated */ -#define XKB_KEY_kana_HE 0x04cd /* U+30D8 KATAKANA LETTER HE */ -#define XKB_KEY_kana_HO 0x04ce /* U+30DB KATAKANA LETTER HO */ -#define XKB_KEY_kana_MA 0x04cf /* U+30DE KATAKANA LETTER MA */ -#define XKB_KEY_kana_MI 0x04d0 /* U+30DF KATAKANA LETTER MI */ -#define XKB_KEY_kana_MU 0x04d1 /* U+30E0 KATAKANA LETTER MU */ -#define XKB_KEY_kana_ME 0x04d2 /* U+30E1 KATAKANA LETTER ME */ -#define XKB_KEY_kana_MO 0x04d3 /* U+30E2 KATAKANA LETTER MO */ -#define XKB_KEY_kana_YA 0x04d4 /* U+30E4 KATAKANA LETTER YA */ -#define XKB_KEY_kana_YU 0x04d5 /* U+30E6 KATAKANA LETTER YU */ -#define XKB_KEY_kana_YO 0x04d6 /* U+30E8 KATAKANA LETTER YO */ -#define XKB_KEY_kana_RA 0x04d7 /* U+30E9 KATAKANA LETTER RA */ -#define XKB_KEY_kana_RI 0x04d8 /* U+30EA KATAKANA LETTER RI */ -#define XKB_KEY_kana_RU 0x04d9 /* U+30EB KATAKANA LETTER RU */ -#define XKB_KEY_kana_RE 0x04da /* U+30EC KATAKANA LETTER RE */ -#define XKB_KEY_kana_RO 0x04db /* U+30ED KATAKANA LETTER RO */ -#define XKB_KEY_kana_WA 0x04dc /* U+30EF KATAKANA LETTER WA */ -#define XKB_KEY_kana_N 0x04dd /* U+30F3 KATAKANA LETTER N */ -#define XKB_KEY_voicedsound 0x04de /* U+309B KATAKANA-HIRAGANA VOICED SOUND MARK */ -#define XKB_KEY_semivoicedsound 0x04df /* U+309C KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ -#define XKB_KEY_kana_switch 0xff7e /* Alias for mode_switch */ - -/* - * Arabic - * Byte 3 = 5 - */ - -#define XKB_KEY_Farsi_0 0x10006f0 /* U+06F0 EXTENDED ARABIC-INDIC DIGIT ZERO */ -#define XKB_KEY_Farsi_1 0x10006f1 /* U+06F1 EXTENDED ARABIC-INDIC DIGIT ONE */ -#define XKB_KEY_Farsi_2 0x10006f2 /* U+06F2 EXTENDED ARABIC-INDIC DIGIT TWO */ -#define XKB_KEY_Farsi_3 0x10006f3 /* U+06F3 EXTENDED ARABIC-INDIC DIGIT THREE */ -#define XKB_KEY_Farsi_4 0x10006f4 /* U+06F4 EXTENDED ARABIC-INDIC DIGIT FOUR */ -#define XKB_KEY_Farsi_5 0x10006f5 /* U+06F5 EXTENDED ARABIC-INDIC DIGIT FIVE */ -#define XKB_KEY_Farsi_6 0x10006f6 /* U+06F6 EXTENDED ARABIC-INDIC DIGIT SIX */ -#define XKB_KEY_Farsi_7 0x10006f7 /* U+06F7 EXTENDED ARABIC-INDIC DIGIT SEVEN */ -#define XKB_KEY_Farsi_8 0x10006f8 /* U+06F8 EXTENDED ARABIC-INDIC DIGIT EIGHT */ -#define XKB_KEY_Farsi_9 0x10006f9 /* U+06F9 EXTENDED ARABIC-INDIC DIGIT NINE */ -#define XKB_KEY_Arabic_percent 0x100066a /* U+066A ARABIC PERCENT SIGN */ -#define XKB_KEY_Arabic_superscript_alef 0x1000670 /* U+0670 ARABIC LETTER SUPERSCRIPT ALEF */ -#define XKB_KEY_Arabic_tteh 0x1000679 /* U+0679 ARABIC LETTER TTEH */ -#define XKB_KEY_Arabic_peh 0x100067e /* U+067E ARABIC LETTER PEH */ -#define XKB_KEY_Arabic_tcheh 0x1000686 /* U+0686 ARABIC LETTER TCHEH */ -#define XKB_KEY_Arabic_ddal 0x1000688 /* U+0688 ARABIC LETTER DDAL */ -#define XKB_KEY_Arabic_rreh 0x1000691 /* U+0691 ARABIC LETTER RREH */ -#define XKB_KEY_Arabic_comma 0x05ac /* U+060C ARABIC COMMA */ -#define XKB_KEY_Arabic_fullstop 0x10006d4 /* U+06D4 ARABIC FULL STOP */ -#define XKB_KEY_Arabic_0 0x1000660 /* U+0660 ARABIC-INDIC DIGIT ZERO */ -#define XKB_KEY_Arabic_1 0x1000661 /* U+0661 ARABIC-INDIC DIGIT ONE */ -#define XKB_KEY_Arabic_2 0x1000662 /* U+0662 ARABIC-INDIC DIGIT TWO */ -#define XKB_KEY_Arabic_3 0x1000663 /* U+0663 ARABIC-INDIC DIGIT THREE */ -#define XKB_KEY_Arabic_4 0x1000664 /* U+0664 ARABIC-INDIC DIGIT FOUR */ -#define XKB_KEY_Arabic_5 0x1000665 /* U+0665 ARABIC-INDIC DIGIT FIVE */ -#define XKB_KEY_Arabic_6 0x1000666 /* U+0666 ARABIC-INDIC DIGIT SIX */ -#define XKB_KEY_Arabic_7 0x1000667 /* U+0667 ARABIC-INDIC DIGIT SEVEN */ -#define XKB_KEY_Arabic_8 0x1000668 /* U+0668 ARABIC-INDIC DIGIT EIGHT */ -#define XKB_KEY_Arabic_9 0x1000669 /* U+0669 ARABIC-INDIC DIGIT NINE */ -#define XKB_KEY_Arabic_semicolon 0x05bb /* U+061B ARABIC SEMICOLON */ -#define XKB_KEY_Arabic_question_mark 0x05bf /* U+061F ARABIC QUESTION MARK */ -#define XKB_KEY_Arabic_hamza 0x05c1 /* U+0621 ARABIC LETTER HAMZA */ -#define XKB_KEY_Arabic_maddaonalef 0x05c2 /* U+0622 ARABIC LETTER ALEF WITH MADDA ABOVE */ -#define XKB_KEY_Arabic_hamzaonalef 0x05c3 /* U+0623 ARABIC LETTER ALEF WITH HAMZA ABOVE */ -#define XKB_KEY_Arabic_hamzaonwaw 0x05c4 /* U+0624 ARABIC LETTER WAW WITH HAMZA ABOVE */ -#define XKB_KEY_Arabic_hamzaunderalef 0x05c5 /* U+0625 ARABIC LETTER ALEF WITH HAMZA BELOW */ -#define XKB_KEY_Arabic_hamzaonyeh 0x05c6 /* U+0626 ARABIC LETTER YEH WITH HAMZA ABOVE */ -#define XKB_KEY_Arabic_alef 0x05c7 /* U+0627 ARABIC LETTER ALEF */ -#define XKB_KEY_Arabic_beh 0x05c8 /* U+0628 ARABIC LETTER BEH */ -#define XKB_KEY_Arabic_tehmarbuta 0x05c9 /* U+0629 ARABIC LETTER TEH MARBUTA */ -#define XKB_KEY_Arabic_teh 0x05ca /* U+062A ARABIC LETTER TEH */ -#define XKB_KEY_Arabic_theh 0x05cb /* U+062B ARABIC LETTER THEH */ -#define XKB_KEY_Arabic_jeem 0x05cc /* U+062C ARABIC LETTER JEEM */ -#define XKB_KEY_Arabic_hah 0x05cd /* U+062D ARABIC LETTER HAH */ -#define XKB_KEY_Arabic_khah 0x05ce /* U+062E ARABIC LETTER KHAH */ -#define XKB_KEY_Arabic_dal 0x05cf /* U+062F ARABIC LETTER DAL */ -#define XKB_KEY_Arabic_thal 0x05d0 /* U+0630 ARABIC LETTER THAL */ -#define XKB_KEY_Arabic_ra 0x05d1 /* U+0631 ARABIC LETTER REH */ -#define XKB_KEY_Arabic_zain 0x05d2 /* U+0632 ARABIC LETTER ZAIN */ -#define XKB_KEY_Arabic_seen 0x05d3 /* U+0633 ARABIC LETTER SEEN */ -#define XKB_KEY_Arabic_sheen 0x05d4 /* U+0634 ARABIC LETTER SHEEN */ -#define XKB_KEY_Arabic_sad 0x05d5 /* U+0635 ARABIC LETTER SAD */ -#define XKB_KEY_Arabic_dad 0x05d6 /* U+0636 ARABIC LETTER DAD */ -#define XKB_KEY_Arabic_tah 0x05d7 /* U+0637 ARABIC LETTER TAH */ -#define XKB_KEY_Arabic_zah 0x05d8 /* U+0638 ARABIC LETTER ZAH */ -#define XKB_KEY_Arabic_ain 0x05d9 /* U+0639 ARABIC LETTER AIN */ -#define XKB_KEY_Arabic_ghain 0x05da /* U+063A ARABIC LETTER GHAIN */ -#define XKB_KEY_Arabic_tatweel 0x05e0 /* U+0640 ARABIC TATWEEL */ -#define XKB_KEY_Arabic_feh 0x05e1 /* U+0641 ARABIC LETTER FEH */ -#define XKB_KEY_Arabic_qaf 0x05e2 /* U+0642 ARABIC LETTER QAF */ -#define XKB_KEY_Arabic_kaf 0x05e3 /* U+0643 ARABIC LETTER KAF */ -#define XKB_KEY_Arabic_lam 0x05e4 /* U+0644 ARABIC LETTER LAM */ -#define XKB_KEY_Arabic_meem 0x05e5 /* U+0645 ARABIC LETTER MEEM */ -#define XKB_KEY_Arabic_noon 0x05e6 /* U+0646 ARABIC LETTER NOON */ -#define XKB_KEY_Arabic_ha 0x05e7 /* U+0647 ARABIC LETTER HEH */ -#define XKB_KEY_Arabic_heh 0x05e7 /* deprecated */ -#define XKB_KEY_Arabic_waw 0x05e8 /* U+0648 ARABIC LETTER WAW */ -#define XKB_KEY_Arabic_alefmaksura 0x05e9 /* U+0649 ARABIC LETTER ALEF MAKSURA */ -#define XKB_KEY_Arabic_yeh 0x05ea /* U+064A ARABIC LETTER YEH */ -#define XKB_KEY_Arabic_fathatan 0x05eb /* U+064B ARABIC FATHATAN */ -#define XKB_KEY_Arabic_dammatan 0x05ec /* U+064C ARABIC DAMMATAN */ -#define XKB_KEY_Arabic_kasratan 0x05ed /* U+064D ARABIC KASRATAN */ -#define XKB_KEY_Arabic_fatha 0x05ee /* U+064E ARABIC FATHA */ -#define XKB_KEY_Arabic_damma 0x05ef /* U+064F ARABIC DAMMA */ -#define XKB_KEY_Arabic_kasra 0x05f0 /* U+0650 ARABIC KASRA */ -#define XKB_KEY_Arabic_shadda 0x05f1 /* U+0651 ARABIC SHADDA */ -#define XKB_KEY_Arabic_sukun 0x05f2 /* U+0652 ARABIC SUKUN */ -#define XKB_KEY_Arabic_madda_above 0x1000653 /* U+0653 ARABIC MADDAH ABOVE */ -#define XKB_KEY_Arabic_hamza_above 0x1000654 /* U+0654 ARABIC HAMZA ABOVE */ -#define XKB_KEY_Arabic_hamza_below 0x1000655 /* U+0655 ARABIC HAMZA BELOW */ -#define XKB_KEY_Arabic_jeh 0x1000698 /* U+0698 ARABIC LETTER JEH */ -#define XKB_KEY_Arabic_veh 0x10006a4 /* U+06A4 ARABIC LETTER VEH */ -#define XKB_KEY_Arabic_keheh 0x10006a9 /* U+06A9 ARABIC LETTER KEHEH */ -#define XKB_KEY_Arabic_gaf 0x10006af /* U+06AF ARABIC LETTER GAF */ -#define XKB_KEY_Arabic_noon_ghunna 0x10006ba /* U+06BA ARABIC LETTER NOON GHUNNA */ -#define XKB_KEY_Arabic_heh_doachashmee 0x10006be /* U+06BE ARABIC LETTER HEH DOACHASHMEE */ -#define XKB_KEY_Farsi_yeh 0x10006cc /* U+06CC ARABIC LETTER FARSI YEH */ -#define XKB_KEY_Arabic_farsi_yeh 0x10006cc /* U+06CC ARABIC LETTER FARSI YEH */ -#define XKB_KEY_Arabic_yeh_baree 0x10006d2 /* U+06D2 ARABIC LETTER YEH BARREE */ -#define XKB_KEY_Arabic_heh_goal 0x10006c1 /* U+06C1 ARABIC LETTER HEH GOAL */ -#define XKB_KEY_Arabic_switch 0xff7e /* Alias for mode_switch */ - -/* - * Cyrillic - * Byte 3 = 6 - */ -#define XKB_KEY_Cyrillic_GHE_bar 0x1000492 /* U+0492 CYRILLIC CAPITAL LETTER GHE WITH STROKE */ -#define XKB_KEY_Cyrillic_ghe_bar 0x1000493 /* U+0493 CYRILLIC SMALL LETTER GHE WITH STROKE */ -#define XKB_KEY_Cyrillic_ZHE_descender 0x1000496 /* U+0496 CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER */ -#define XKB_KEY_Cyrillic_zhe_descender 0x1000497 /* U+0497 CYRILLIC SMALL LETTER ZHE WITH DESCENDER */ -#define XKB_KEY_Cyrillic_KA_descender 0x100049a /* U+049A CYRILLIC CAPITAL LETTER KA WITH DESCENDER */ -#define XKB_KEY_Cyrillic_ka_descender 0x100049b /* U+049B CYRILLIC SMALL LETTER KA WITH DESCENDER */ -#define XKB_KEY_Cyrillic_KA_vertstroke 0x100049c /* U+049C CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE */ -#define XKB_KEY_Cyrillic_ka_vertstroke 0x100049d /* U+049D CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE */ -#define XKB_KEY_Cyrillic_EN_descender 0x10004a2 /* U+04A2 CYRILLIC CAPITAL LETTER EN WITH DESCENDER */ -#define XKB_KEY_Cyrillic_en_descender 0x10004a3 /* U+04A3 CYRILLIC SMALL LETTER EN WITH DESCENDER */ -#define XKB_KEY_Cyrillic_U_straight 0x10004ae /* U+04AE CYRILLIC CAPITAL LETTER STRAIGHT U */ -#define XKB_KEY_Cyrillic_u_straight 0x10004af /* U+04AF CYRILLIC SMALL LETTER STRAIGHT U */ -#define XKB_KEY_Cyrillic_U_straight_bar 0x10004b0 /* U+04B0 CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE */ -#define XKB_KEY_Cyrillic_u_straight_bar 0x10004b1 /* U+04B1 CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE */ -#define XKB_KEY_Cyrillic_HA_descender 0x10004b2 /* U+04B2 CYRILLIC CAPITAL LETTER HA WITH DESCENDER */ -#define XKB_KEY_Cyrillic_ha_descender 0x10004b3 /* U+04B3 CYRILLIC SMALL LETTER HA WITH DESCENDER */ -#define XKB_KEY_Cyrillic_CHE_descender 0x10004b6 /* U+04B6 CYRILLIC CAPITAL LETTER CHE WITH DESCENDER */ -#define XKB_KEY_Cyrillic_che_descender 0x10004b7 /* U+04B7 CYRILLIC SMALL LETTER CHE WITH DESCENDER */ -#define XKB_KEY_Cyrillic_CHE_vertstroke 0x10004b8 /* U+04B8 CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE */ -#define XKB_KEY_Cyrillic_che_vertstroke 0x10004b9 /* U+04B9 CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE */ -#define XKB_KEY_Cyrillic_SHHA 0x10004ba /* U+04BA CYRILLIC CAPITAL LETTER SHHA */ -#define XKB_KEY_Cyrillic_shha 0x10004bb /* U+04BB CYRILLIC SMALL LETTER SHHA */ - -#define XKB_KEY_Cyrillic_SCHWA 0x10004d8 /* U+04D8 CYRILLIC CAPITAL LETTER SCHWA */ -#define XKB_KEY_Cyrillic_schwa 0x10004d9 /* U+04D9 CYRILLIC SMALL LETTER SCHWA */ -#define XKB_KEY_Cyrillic_I_macron 0x10004e2 /* U+04E2 CYRILLIC CAPITAL LETTER I WITH MACRON */ -#define XKB_KEY_Cyrillic_i_macron 0x10004e3 /* U+04E3 CYRILLIC SMALL LETTER I WITH MACRON */ -#define XKB_KEY_Cyrillic_O_bar 0x10004e8 /* U+04E8 CYRILLIC CAPITAL LETTER BARRED O */ -#define XKB_KEY_Cyrillic_o_bar 0x10004e9 /* U+04E9 CYRILLIC SMALL LETTER BARRED O */ -#define XKB_KEY_Cyrillic_U_macron 0x10004ee /* U+04EE CYRILLIC CAPITAL LETTER U WITH MACRON */ -#define XKB_KEY_Cyrillic_u_macron 0x10004ef /* U+04EF CYRILLIC SMALL LETTER U WITH MACRON */ - -#define XKB_KEY_Serbian_dje 0x06a1 /* U+0452 CYRILLIC SMALL LETTER DJE */ -#define XKB_KEY_Macedonia_gje 0x06a2 /* U+0453 CYRILLIC SMALL LETTER GJE */ -#define XKB_KEY_Cyrillic_io 0x06a3 /* U+0451 CYRILLIC SMALL LETTER IO */ -#define XKB_KEY_Ukrainian_ie 0x06a4 /* U+0454 CYRILLIC SMALL LETTER UKRAINIAN IE */ -#define XKB_KEY_Ukranian_je 0x06a4 /* deprecated */ -#define XKB_KEY_Macedonia_dse 0x06a5 /* U+0455 CYRILLIC SMALL LETTER DZE */ -#define XKB_KEY_Ukrainian_i 0x06a6 /* U+0456 CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */ -#define XKB_KEY_Ukranian_i 0x06a6 /* deprecated */ -#define XKB_KEY_Ukrainian_yi 0x06a7 /* U+0457 CYRILLIC SMALL LETTER YI */ -#define XKB_KEY_Ukranian_yi 0x06a7 /* deprecated */ -#define XKB_KEY_Cyrillic_je 0x06a8 /* U+0458 CYRILLIC SMALL LETTER JE */ -#define XKB_KEY_Serbian_je 0x06a8 /* deprecated */ -#define XKB_KEY_Cyrillic_lje 0x06a9 /* U+0459 CYRILLIC SMALL LETTER LJE */ -#define XKB_KEY_Serbian_lje 0x06a9 /* deprecated */ -#define XKB_KEY_Cyrillic_nje 0x06aa /* U+045A CYRILLIC SMALL LETTER NJE */ -#define XKB_KEY_Serbian_nje 0x06aa /* deprecated */ -#define XKB_KEY_Serbian_tshe 0x06ab /* U+045B CYRILLIC SMALL LETTER TSHE */ -#define XKB_KEY_Macedonia_kje 0x06ac /* U+045C CYRILLIC SMALL LETTER KJE */ -#define XKB_KEY_Ukrainian_ghe_with_upturn 0x06ad /* U+0491 CYRILLIC SMALL LETTER GHE WITH UPTURN */ -#define XKB_KEY_Byelorussian_shortu 0x06ae /* U+045E CYRILLIC SMALL LETTER SHORT U */ -#define XKB_KEY_Cyrillic_dzhe 0x06af /* U+045F CYRILLIC SMALL LETTER DZHE */ -#define XKB_KEY_Serbian_dze 0x06af /* deprecated */ -#define XKB_KEY_numerosign 0x06b0 /* U+2116 NUMERO SIGN */ -#define XKB_KEY_Serbian_DJE 0x06b1 /* U+0402 CYRILLIC CAPITAL LETTER DJE */ -#define XKB_KEY_Macedonia_GJE 0x06b2 /* U+0403 CYRILLIC CAPITAL LETTER GJE */ -#define XKB_KEY_Cyrillic_IO 0x06b3 /* U+0401 CYRILLIC CAPITAL LETTER IO */ -#define XKB_KEY_Ukrainian_IE 0x06b4 /* U+0404 CYRILLIC CAPITAL LETTER UKRAINIAN IE */ -#define XKB_KEY_Ukranian_JE 0x06b4 /* deprecated */ -#define XKB_KEY_Macedonia_DSE 0x06b5 /* U+0405 CYRILLIC CAPITAL LETTER DZE */ -#define XKB_KEY_Ukrainian_I 0x06b6 /* U+0406 CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */ -#define XKB_KEY_Ukranian_I 0x06b6 /* deprecated */ -#define XKB_KEY_Ukrainian_YI 0x06b7 /* U+0407 CYRILLIC CAPITAL LETTER YI */ -#define XKB_KEY_Ukranian_YI 0x06b7 /* deprecated */ -#define XKB_KEY_Cyrillic_JE 0x06b8 /* U+0408 CYRILLIC CAPITAL LETTER JE */ -#define XKB_KEY_Serbian_JE 0x06b8 /* deprecated */ -#define XKB_KEY_Cyrillic_LJE 0x06b9 /* U+0409 CYRILLIC CAPITAL LETTER LJE */ -#define XKB_KEY_Serbian_LJE 0x06b9 /* deprecated */ -#define XKB_KEY_Cyrillic_NJE 0x06ba /* U+040A CYRILLIC CAPITAL LETTER NJE */ -#define XKB_KEY_Serbian_NJE 0x06ba /* deprecated */ -#define XKB_KEY_Serbian_TSHE 0x06bb /* U+040B CYRILLIC CAPITAL LETTER TSHE */ -#define XKB_KEY_Macedonia_KJE 0x06bc /* U+040C CYRILLIC CAPITAL LETTER KJE */ -#define XKB_KEY_Ukrainian_GHE_WITH_UPTURN 0x06bd /* U+0490 CYRILLIC CAPITAL LETTER GHE WITH UPTURN */ -#define XKB_KEY_Byelorussian_SHORTU 0x06be /* U+040E CYRILLIC CAPITAL LETTER SHORT U */ -#define XKB_KEY_Cyrillic_DZHE 0x06bf /* U+040F CYRILLIC CAPITAL LETTER DZHE */ -#define XKB_KEY_Serbian_DZE 0x06bf /* deprecated */ -#define XKB_KEY_Cyrillic_yu 0x06c0 /* U+044E CYRILLIC SMALL LETTER YU */ -#define XKB_KEY_Cyrillic_a 0x06c1 /* U+0430 CYRILLIC SMALL LETTER A */ -#define XKB_KEY_Cyrillic_be 0x06c2 /* U+0431 CYRILLIC SMALL LETTER BE */ -#define XKB_KEY_Cyrillic_tse 0x06c3 /* U+0446 CYRILLIC SMALL LETTER TSE */ -#define XKB_KEY_Cyrillic_de 0x06c4 /* U+0434 CYRILLIC SMALL LETTER DE */ -#define XKB_KEY_Cyrillic_ie 0x06c5 /* U+0435 CYRILLIC SMALL LETTER IE */ -#define XKB_KEY_Cyrillic_ef 0x06c6 /* U+0444 CYRILLIC SMALL LETTER EF */ -#define XKB_KEY_Cyrillic_ghe 0x06c7 /* U+0433 CYRILLIC SMALL LETTER GHE */ -#define XKB_KEY_Cyrillic_ha 0x06c8 /* U+0445 CYRILLIC SMALL LETTER HA */ -#define XKB_KEY_Cyrillic_i 0x06c9 /* U+0438 CYRILLIC SMALL LETTER I */ -#define XKB_KEY_Cyrillic_shorti 0x06ca /* U+0439 CYRILLIC SMALL LETTER SHORT I */ -#define XKB_KEY_Cyrillic_ka 0x06cb /* U+043A CYRILLIC SMALL LETTER KA */ -#define XKB_KEY_Cyrillic_el 0x06cc /* U+043B CYRILLIC SMALL LETTER EL */ -#define XKB_KEY_Cyrillic_em 0x06cd /* U+043C CYRILLIC SMALL LETTER EM */ -#define XKB_KEY_Cyrillic_en 0x06ce /* U+043D CYRILLIC SMALL LETTER EN */ -#define XKB_KEY_Cyrillic_o 0x06cf /* U+043E CYRILLIC SMALL LETTER O */ -#define XKB_KEY_Cyrillic_pe 0x06d0 /* U+043F CYRILLIC SMALL LETTER PE */ -#define XKB_KEY_Cyrillic_ya 0x06d1 /* U+044F CYRILLIC SMALL LETTER YA */ -#define XKB_KEY_Cyrillic_er 0x06d2 /* U+0440 CYRILLIC SMALL LETTER ER */ -#define XKB_KEY_Cyrillic_es 0x06d3 /* U+0441 CYRILLIC SMALL LETTER ES */ -#define XKB_KEY_Cyrillic_te 0x06d4 /* U+0442 CYRILLIC SMALL LETTER TE */ -#define XKB_KEY_Cyrillic_u 0x06d5 /* U+0443 CYRILLIC SMALL LETTER U */ -#define XKB_KEY_Cyrillic_zhe 0x06d6 /* U+0436 CYRILLIC SMALL LETTER ZHE */ -#define XKB_KEY_Cyrillic_ve 0x06d7 /* U+0432 CYRILLIC SMALL LETTER VE */ -#define XKB_KEY_Cyrillic_softsign 0x06d8 /* U+044C CYRILLIC SMALL LETTER SOFT SIGN */ -#define XKB_KEY_Cyrillic_yeru 0x06d9 /* U+044B CYRILLIC SMALL LETTER YERU */ -#define XKB_KEY_Cyrillic_ze 0x06da /* U+0437 CYRILLIC SMALL LETTER ZE */ -#define XKB_KEY_Cyrillic_sha 0x06db /* U+0448 CYRILLIC SMALL LETTER SHA */ -#define XKB_KEY_Cyrillic_e 0x06dc /* U+044D CYRILLIC SMALL LETTER E */ -#define XKB_KEY_Cyrillic_shcha 0x06dd /* U+0449 CYRILLIC SMALL LETTER SHCHA */ -#define XKB_KEY_Cyrillic_che 0x06de /* U+0447 CYRILLIC SMALL LETTER CHE */ -#define XKB_KEY_Cyrillic_hardsign 0x06df /* U+044A CYRILLIC SMALL LETTER HARD SIGN */ -#define XKB_KEY_Cyrillic_YU 0x06e0 /* U+042E CYRILLIC CAPITAL LETTER YU */ -#define XKB_KEY_Cyrillic_A 0x06e1 /* U+0410 CYRILLIC CAPITAL LETTER A */ -#define XKB_KEY_Cyrillic_BE 0x06e2 /* U+0411 CYRILLIC CAPITAL LETTER BE */ -#define XKB_KEY_Cyrillic_TSE 0x06e3 /* U+0426 CYRILLIC CAPITAL LETTER TSE */ -#define XKB_KEY_Cyrillic_DE 0x06e4 /* U+0414 CYRILLIC CAPITAL LETTER DE */ -#define XKB_KEY_Cyrillic_IE 0x06e5 /* U+0415 CYRILLIC CAPITAL LETTER IE */ -#define XKB_KEY_Cyrillic_EF 0x06e6 /* U+0424 CYRILLIC CAPITAL LETTER EF */ -#define XKB_KEY_Cyrillic_GHE 0x06e7 /* U+0413 CYRILLIC CAPITAL LETTER GHE */ -#define XKB_KEY_Cyrillic_HA 0x06e8 /* U+0425 CYRILLIC CAPITAL LETTER HA */ -#define XKB_KEY_Cyrillic_I 0x06e9 /* U+0418 CYRILLIC CAPITAL LETTER I */ -#define XKB_KEY_Cyrillic_SHORTI 0x06ea /* U+0419 CYRILLIC CAPITAL LETTER SHORT I */ -#define XKB_KEY_Cyrillic_KA 0x06eb /* U+041A CYRILLIC CAPITAL LETTER KA */ -#define XKB_KEY_Cyrillic_EL 0x06ec /* U+041B CYRILLIC CAPITAL LETTER EL */ -#define XKB_KEY_Cyrillic_EM 0x06ed /* U+041C CYRILLIC CAPITAL LETTER EM */ -#define XKB_KEY_Cyrillic_EN 0x06ee /* U+041D CYRILLIC CAPITAL LETTER EN */ -#define XKB_KEY_Cyrillic_O 0x06ef /* U+041E CYRILLIC CAPITAL LETTER O */ -#define XKB_KEY_Cyrillic_PE 0x06f0 /* U+041F CYRILLIC CAPITAL LETTER PE */ -#define XKB_KEY_Cyrillic_YA 0x06f1 /* U+042F CYRILLIC CAPITAL LETTER YA */ -#define XKB_KEY_Cyrillic_ER 0x06f2 /* U+0420 CYRILLIC CAPITAL LETTER ER */ -#define XKB_KEY_Cyrillic_ES 0x06f3 /* U+0421 CYRILLIC CAPITAL LETTER ES */ -#define XKB_KEY_Cyrillic_TE 0x06f4 /* U+0422 CYRILLIC CAPITAL LETTER TE */ -#define XKB_KEY_Cyrillic_U 0x06f5 /* U+0423 CYRILLIC CAPITAL LETTER U */ -#define XKB_KEY_Cyrillic_ZHE 0x06f6 /* U+0416 CYRILLIC CAPITAL LETTER ZHE */ -#define XKB_KEY_Cyrillic_VE 0x06f7 /* U+0412 CYRILLIC CAPITAL LETTER VE */ -#define XKB_KEY_Cyrillic_SOFTSIGN 0x06f8 /* U+042C CYRILLIC CAPITAL LETTER SOFT SIGN */ -#define XKB_KEY_Cyrillic_YERU 0x06f9 /* U+042B CYRILLIC CAPITAL LETTER YERU */ -#define XKB_KEY_Cyrillic_ZE 0x06fa /* U+0417 CYRILLIC CAPITAL LETTER ZE */ -#define XKB_KEY_Cyrillic_SHA 0x06fb /* U+0428 CYRILLIC CAPITAL LETTER SHA */ -#define XKB_KEY_Cyrillic_E 0x06fc /* U+042D CYRILLIC CAPITAL LETTER E */ -#define XKB_KEY_Cyrillic_SHCHA 0x06fd /* U+0429 CYRILLIC CAPITAL LETTER SHCHA */ -#define XKB_KEY_Cyrillic_CHE 0x06fe /* U+0427 CYRILLIC CAPITAL LETTER CHE */ -#define XKB_KEY_Cyrillic_HARDSIGN 0x06ff /* U+042A CYRILLIC CAPITAL LETTER HARD SIGN */ - -/* - * Greek - * (based on an early draft of, and not quite identical to, ISO/IEC 8859-7) - * Byte 3 = 7 - */ - -#define XKB_KEY_Greek_ALPHAaccent 0x07a1 /* U+0386 GREEK CAPITAL LETTER ALPHA WITH TONOS */ -#define XKB_KEY_Greek_EPSILONaccent 0x07a2 /* U+0388 GREEK CAPITAL LETTER EPSILON WITH TONOS */ -#define XKB_KEY_Greek_ETAaccent 0x07a3 /* U+0389 GREEK CAPITAL LETTER ETA WITH TONOS */ -#define XKB_KEY_Greek_IOTAaccent 0x07a4 /* U+038A GREEK CAPITAL LETTER IOTA WITH TONOS */ -#define XKB_KEY_Greek_IOTAdieresis 0x07a5 /* U+03AA GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */ -#define XKB_KEY_Greek_IOTAdiaeresis 0x07a5 /* old typo */ -#define XKB_KEY_Greek_OMICRONaccent 0x07a7 /* U+038C GREEK CAPITAL LETTER OMICRON WITH TONOS */ -#define XKB_KEY_Greek_UPSILONaccent 0x07a8 /* U+038E GREEK CAPITAL LETTER UPSILON WITH TONOS */ -#define XKB_KEY_Greek_UPSILONdieresis 0x07a9 /* U+03AB GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */ -#define XKB_KEY_Greek_OMEGAaccent 0x07ab /* U+038F GREEK CAPITAL LETTER OMEGA WITH TONOS */ -#define XKB_KEY_Greek_accentdieresis 0x07ae /* U+0385 GREEK DIALYTIKA TONOS */ -#define XKB_KEY_Greek_horizbar 0x07af /* U+2015 HORIZONTAL BAR */ -#define XKB_KEY_Greek_alphaaccent 0x07b1 /* U+03AC GREEK SMALL LETTER ALPHA WITH TONOS */ -#define XKB_KEY_Greek_epsilonaccent 0x07b2 /* U+03AD GREEK SMALL LETTER EPSILON WITH TONOS */ -#define XKB_KEY_Greek_etaaccent 0x07b3 /* U+03AE GREEK SMALL LETTER ETA WITH TONOS */ -#define XKB_KEY_Greek_iotaaccent 0x07b4 /* U+03AF GREEK SMALL LETTER IOTA WITH TONOS */ -#define XKB_KEY_Greek_iotadieresis 0x07b5 /* U+03CA GREEK SMALL LETTER IOTA WITH DIALYTIKA */ -#define XKB_KEY_Greek_iotaaccentdieresis 0x07b6 /* U+0390 GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ -#define XKB_KEY_Greek_omicronaccent 0x07b7 /* U+03CC GREEK SMALL LETTER OMICRON WITH TONOS */ -#define XKB_KEY_Greek_upsilonaccent 0x07b8 /* U+03CD GREEK SMALL LETTER UPSILON WITH TONOS */ -#define XKB_KEY_Greek_upsilondieresis 0x07b9 /* U+03CB GREEK SMALL LETTER UPSILON WITH DIALYTIKA */ -#define XKB_KEY_Greek_upsilonaccentdieresis 0x07ba /* U+03B0 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ -#define XKB_KEY_Greek_omegaaccent 0x07bb /* U+03CE GREEK SMALL LETTER OMEGA WITH TONOS */ -#define XKB_KEY_Greek_ALPHA 0x07c1 /* U+0391 GREEK CAPITAL LETTER ALPHA */ -#define XKB_KEY_Greek_BETA 0x07c2 /* U+0392 GREEK CAPITAL LETTER BETA */ -#define XKB_KEY_Greek_GAMMA 0x07c3 /* U+0393 GREEK CAPITAL LETTER GAMMA */ -#define XKB_KEY_Greek_DELTA 0x07c4 /* U+0394 GREEK CAPITAL LETTER DELTA */ -#define XKB_KEY_Greek_EPSILON 0x07c5 /* U+0395 GREEK CAPITAL LETTER EPSILON */ -#define XKB_KEY_Greek_ZETA 0x07c6 /* U+0396 GREEK CAPITAL LETTER ZETA */ -#define XKB_KEY_Greek_ETA 0x07c7 /* U+0397 GREEK CAPITAL LETTER ETA */ -#define XKB_KEY_Greek_THETA 0x07c8 /* U+0398 GREEK CAPITAL LETTER THETA */ -#define XKB_KEY_Greek_IOTA 0x07c9 /* U+0399 GREEK CAPITAL LETTER IOTA */ -#define XKB_KEY_Greek_KAPPA 0x07ca /* U+039A GREEK CAPITAL LETTER KAPPA */ -#define XKB_KEY_Greek_LAMDA 0x07cb /* U+039B GREEK CAPITAL LETTER LAMDA */ -#define XKB_KEY_Greek_LAMBDA 0x07cb /* U+039B GREEK CAPITAL LETTER LAMDA */ -#define XKB_KEY_Greek_MU 0x07cc /* U+039C GREEK CAPITAL LETTER MU */ -#define XKB_KEY_Greek_NU 0x07cd /* U+039D GREEK CAPITAL LETTER NU */ -#define XKB_KEY_Greek_XI 0x07ce /* U+039E GREEK CAPITAL LETTER XI */ -#define XKB_KEY_Greek_OMICRON 0x07cf /* U+039F GREEK CAPITAL LETTER OMICRON */ -#define XKB_KEY_Greek_PI 0x07d0 /* U+03A0 GREEK CAPITAL LETTER PI */ -#define XKB_KEY_Greek_RHO 0x07d1 /* U+03A1 GREEK CAPITAL LETTER RHO */ -#define XKB_KEY_Greek_SIGMA 0x07d2 /* U+03A3 GREEK CAPITAL LETTER SIGMA */ -#define XKB_KEY_Greek_TAU 0x07d4 /* U+03A4 GREEK CAPITAL LETTER TAU */ -#define XKB_KEY_Greek_UPSILON 0x07d5 /* U+03A5 GREEK CAPITAL LETTER UPSILON */ -#define XKB_KEY_Greek_PHI 0x07d6 /* U+03A6 GREEK CAPITAL LETTER PHI */ -#define XKB_KEY_Greek_CHI 0x07d7 /* U+03A7 GREEK CAPITAL LETTER CHI */ -#define XKB_KEY_Greek_PSI 0x07d8 /* U+03A8 GREEK CAPITAL LETTER PSI */ -#define XKB_KEY_Greek_OMEGA 0x07d9 /* U+03A9 GREEK CAPITAL LETTER OMEGA */ -#define XKB_KEY_Greek_alpha 0x07e1 /* U+03B1 GREEK SMALL LETTER ALPHA */ -#define XKB_KEY_Greek_beta 0x07e2 /* U+03B2 GREEK SMALL LETTER BETA */ -#define XKB_KEY_Greek_gamma 0x07e3 /* U+03B3 GREEK SMALL LETTER GAMMA */ -#define XKB_KEY_Greek_delta 0x07e4 /* U+03B4 GREEK SMALL LETTER DELTA */ -#define XKB_KEY_Greek_epsilon 0x07e5 /* U+03B5 GREEK SMALL LETTER EPSILON */ -#define XKB_KEY_Greek_zeta 0x07e6 /* U+03B6 GREEK SMALL LETTER ZETA */ -#define XKB_KEY_Greek_eta 0x07e7 /* U+03B7 GREEK SMALL LETTER ETA */ -#define XKB_KEY_Greek_theta 0x07e8 /* U+03B8 GREEK SMALL LETTER THETA */ -#define XKB_KEY_Greek_iota 0x07e9 /* U+03B9 GREEK SMALL LETTER IOTA */ -#define XKB_KEY_Greek_kappa 0x07ea /* U+03BA GREEK SMALL LETTER KAPPA */ -#define XKB_KEY_Greek_lamda 0x07eb /* U+03BB GREEK SMALL LETTER LAMDA */ -#define XKB_KEY_Greek_lambda 0x07eb /* U+03BB GREEK SMALL LETTER LAMDA */ -#define XKB_KEY_Greek_mu 0x07ec /* U+03BC GREEK SMALL LETTER MU */ -#define XKB_KEY_Greek_nu 0x07ed /* U+03BD GREEK SMALL LETTER NU */ -#define XKB_KEY_Greek_xi 0x07ee /* U+03BE GREEK SMALL LETTER XI */ -#define XKB_KEY_Greek_omicron 0x07ef /* U+03BF GREEK SMALL LETTER OMICRON */ -#define XKB_KEY_Greek_pi 0x07f0 /* U+03C0 GREEK SMALL LETTER PI */ -#define XKB_KEY_Greek_rho 0x07f1 /* U+03C1 GREEK SMALL LETTER RHO */ -#define XKB_KEY_Greek_sigma 0x07f2 /* U+03C3 GREEK SMALL LETTER SIGMA */ -#define XKB_KEY_Greek_finalsmallsigma 0x07f3 /* U+03C2 GREEK SMALL LETTER FINAL SIGMA */ -#define XKB_KEY_Greek_tau 0x07f4 /* U+03C4 GREEK SMALL LETTER TAU */ -#define XKB_KEY_Greek_upsilon 0x07f5 /* U+03C5 GREEK SMALL LETTER UPSILON */ -#define XKB_KEY_Greek_phi 0x07f6 /* U+03C6 GREEK SMALL LETTER PHI */ -#define XKB_KEY_Greek_chi 0x07f7 /* U+03C7 GREEK SMALL LETTER CHI */ -#define XKB_KEY_Greek_psi 0x07f8 /* U+03C8 GREEK SMALL LETTER PSI */ -#define XKB_KEY_Greek_omega 0x07f9 /* U+03C9 GREEK SMALL LETTER OMEGA */ -#define XKB_KEY_Greek_switch 0xff7e /* Alias for mode_switch */ - -/* - * Technical - * (from the DEC VT330/VT420 Technical Character Set, http://vt100.net/charsets/technical.html) - * Byte 3 = 8 - */ - -#define XKB_KEY_leftradical 0x08a1 /* U+23B7 RADICAL SYMBOL BOTTOM */ -#define XKB_KEY_topleftradical 0x08a2 /*(U+250C BOX DRAWINGS LIGHT DOWN AND RIGHT)*/ -#define XKB_KEY_horizconnector 0x08a3 /*(U+2500 BOX DRAWINGS LIGHT HORIZONTAL)*/ -#define XKB_KEY_topintegral 0x08a4 /* U+2320 TOP HALF INTEGRAL */ -#define XKB_KEY_botintegral 0x08a5 /* U+2321 BOTTOM HALF INTEGRAL */ -#define XKB_KEY_vertconnector 0x08a6 /*(U+2502 BOX DRAWINGS LIGHT VERTICAL)*/ -#define XKB_KEY_topleftsqbracket 0x08a7 /* U+23A1 LEFT SQUARE BRACKET UPPER CORNER */ -#define XKB_KEY_botleftsqbracket 0x08a8 /* U+23A3 LEFT SQUARE BRACKET LOWER CORNER */ -#define XKB_KEY_toprightsqbracket 0x08a9 /* U+23A4 RIGHT SQUARE BRACKET UPPER CORNER */ -#define XKB_KEY_botrightsqbracket 0x08aa /* U+23A6 RIGHT SQUARE BRACKET LOWER CORNER */ -#define XKB_KEY_topleftparens 0x08ab /* U+239B LEFT PARENTHESIS UPPER HOOK */ -#define XKB_KEY_botleftparens 0x08ac /* U+239D LEFT PARENTHESIS LOWER HOOK */ -#define XKB_KEY_toprightparens 0x08ad /* U+239E RIGHT PARENTHESIS UPPER HOOK */ -#define XKB_KEY_botrightparens 0x08ae /* U+23A0 RIGHT PARENTHESIS LOWER HOOK */ -#define XKB_KEY_leftmiddlecurlybrace 0x08af /* U+23A8 LEFT CURLY BRACKET MIDDLE PIECE */ -#define XKB_KEY_rightmiddlecurlybrace 0x08b0 /* U+23AC RIGHT CURLY BRACKET MIDDLE PIECE */ -#define XKB_KEY_topleftsummation 0x08b1 -#define XKB_KEY_botleftsummation 0x08b2 -#define XKB_KEY_topvertsummationconnector 0x08b3 -#define XKB_KEY_botvertsummationconnector 0x08b4 -#define XKB_KEY_toprightsummation 0x08b5 -#define XKB_KEY_botrightsummation 0x08b6 -#define XKB_KEY_rightmiddlesummation 0x08b7 -#define XKB_KEY_lessthanequal 0x08bc /* U+2264 LESS-THAN OR EQUAL TO */ -#define XKB_KEY_notequal 0x08bd /* U+2260 NOT EQUAL TO */ -#define XKB_KEY_greaterthanequal 0x08be /* U+2265 GREATER-THAN OR EQUAL TO */ -#define XKB_KEY_integral 0x08bf /* U+222B INTEGRAL */ -#define XKB_KEY_therefore 0x08c0 /* U+2234 THEREFORE */ -#define XKB_KEY_variation 0x08c1 /* U+221D PROPORTIONAL TO */ -#define XKB_KEY_infinity 0x08c2 /* U+221E INFINITY */ -#define XKB_KEY_nabla 0x08c5 /* U+2207 NABLA */ -#define XKB_KEY_approximate 0x08c8 /* U+223C TILDE OPERATOR */ -#define XKB_KEY_similarequal 0x08c9 /* U+2243 ASYMPTOTICALLY EQUAL TO */ -#define XKB_KEY_ifonlyif 0x08cd /* U+21D4 LEFT RIGHT DOUBLE ARROW */ -#define XKB_KEY_implies 0x08ce /* U+21D2 RIGHTWARDS DOUBLE ARROW */ -#define XKB_KEY_identical 0x08cf /* U+2261 IDENTICAL TO */ -#define XKB_KEY_radical 0x08d6 /* U+221A SQUARE ROOT */ -#define XKB_KEY_includedin 0x08da /* U+2282 SUBSET OF */ -#define XKB_KEY_includes 0x08db /* U+2283 SUPERSET OF */ -#define XKB_KEY_intersection 0x08dc /* U+2229 INTERSECTION */ -#define XKB_KEY_union 0x08dd /* U+222A UNION */ -#define XKB_KEY_logicaland 0x08de /* U+2227 LOGICAL AND */ -#define XKB_KEY_logicalor 0x08df /* U+2228 LOGICAL OR */ -#define XKB_KEY_partialderivative 0x08ef /* U+2202 PARTIAL DIFFERENTIAL */ -#define XKB_KEY_function 0x08f6 /* U+0192 LATIN SMALL LETTER F WITH HOOK */ -#define XKB_KEY_leftarrow 0x08fb /* U+2190 LEFTWARDS ARROW */ -#define XKB_KEY_uparrow 0x08fc /* U+2191 UPWARDS ARROW */ -#define XKB_KEY_rightarrow 0x08fd /* U+2192 RIGHTWARDS ARROW */ -#define XKB_KEY_downarrow 0x08fe /* U+2193 DOWNWARDS ARROW */ - -/* - * Special - * (from the DEC VT100 Special Graphics Character Set) - * Byte 3 = 9 - */ - -#define XKB_KEY_blank 0x09df -#define XKB_KEY_soliddiamond 0x09e0 /* U+25C6 BLACK DIAMOND */ -#define XKB_KEY_checkerboard 0x09e1 /* U+2592 MEDIUM SHADE */ -#define XKB_KEY_ht 0x09e2 /* U+2409 SYMBOL FOR HORIZONTAL TABULATION */ -#define XKB_KEY_ff 0x09e3 /* U+240C SYMBOL FOR FORM FEED */ -#define XKB_KEY_cr 0x09e4 /* U+240D SYMBOL FOR CARRIAGE RETURN */ -#define XKB_KEY_lf 0x09e5 /* U+240A SYMBOL FOR LINE FEED */ -#define XKB_KEY_nl 0x09e8 /* U+2424 SYMBOL FOR NEWLINE */ -#define XKB_KEY_vt 0x09e9 /* U+240B SYMBOL FOR VERTICAL TABULATION */ -#define XKB_KEY_lowrightcorner 0x09ea /* U+2518 BOX DRAWINGS LIGHT UP AND LEFT */ -#define XKB_KEY_uprightcorner 0x09eb /* U+2510 BOX DRAWINGS LIGHT DOWN AND LEFT */ -#define XKB_KEY_upleftcorner 0x09ec /* U+250C BOX DRAWINGS LIGHT DOWN AND RIGHT */ -#define XKB_KEY_lowleftcorner 0x09ed /* U+2514 BOX DRAWINGS LIGHT UP AND RIGHT */ -#define XKB_KEY_crossinglines 0x09ee /* U+253C BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */ -#define XKB_KEY_horizlinescan1 0x09ef /* U+23BA HORIZONTAL SCAN LINE-1 */ -#define XKB_KEY_horizlinescan3 0x09f0 /* U+23BB HORIZONTAL SCAN LINE-3 */ -#define XKB_KEY_horizlinescan5 0x09f1 /* U+2500 BOX DRAWINGS LIGHT HORIZONTAL */ -#define XKB_KEY_horizlinescan7 0x09f2 /* U+23BC HORIZONTAL SCAN LINE-7 */ -#define XKB_KEY_horizlinescan9 0x09f3 /* U+23BD HORIZONTAL SCAN LINE-9 */ -#define XKB_KEY_leftt 0x09f4 /* U+251C BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ -#define XKB_KEY_rightt 0x09f5 /* U+2524 BOX DRAWINGS LIGHT VERTICAL AND LEFT */ -#define XKB_KEY_bott 0x09f6 /* U+2534 BOX DRAWINGS LIGHT UP AND HORIZONTAL */ -#define XKB_KEY_topt 0x09f7 /* U+252C BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */ -#define XKB_KEY_vertbar 0x09f8 /* U+2502 BOX DRAWINGS LIGHT VERTICAL */ - -/* - * Publishing - * (these are probably from a long forgotten DEC Publishing - * font that once shipped with DECwrite) - * Byte 3 = 0x0a - */ - -#define XKB_KEY_emspace 0x0aa1 /* U+2003 EM SPACE */ -#define XKB_KEY_enspace 0x0aa2 /* U+2002 EN SPACE */ -#define XKB_KEY_em3space 0x0aa3 /* U+2004 THREE-PER-EM SPACE */ -#define XKB_KEY_em4space 0x0aa4 /* U+2005 FOUR-PER-EM SPACE */ -#define XKB_KEY_digitspace 0x0aa5 /* U+2007 FIGURE SPACE */ -#define XKB_KEY_punctspace 0x0aa6 /* U+2008 PUNCTUATION SPACE */ -#define XKB_KEY_thinspace 0x0aa7 /* U+2009 THIN SPACE */ -#define XKB_KEY_hairspace 0x0aa8 /* U+200A HAIR SPACE */ -#define XKB_KEY_emdash 0x0aa9 /* U+2014 EM DASH */ -#define XKB_KEY_endash 0x0aaa /* U+2013 EN DASH */ -#define XKB_KEY_signifblank 0x0aac /*(U+2423 OPEN BOX)*/ -#define XKB_KEY_ellipsis 0x0aae /* U+2026 HORIZONTAL ELLIPSIS */ -#define XKB_KEY_doubbaselinedot 0x0aaf /* U+2025 TWO DOT LEADER */ -#define XKB_KEY_onethird 0x0ab0 /* U+2153 VULGAR FRACTION ONE THIRD */ -#define XKB_KEY_twothirds 0x0ab1 /* U+2154 VULGAR FRACTION TWO THIRDS */ -#define XKB_KEY_onefifth 0x0ab2 /* U+2155 VULGAR FRACTION ONE FIFTH */ -#define XKB_KEY_twofifths 0x0ab3 /* U+2156 VULGAR FRACTION TWO FIFTHS */ -#define XKB_KEY_threefifths 0x0ab4 /* U+2157 VULGAR FRACTION THREE FIFTHS */ -#define XKB_KEY_fourfifths 0x0ab5 /* U+2158 VULGAR FRACTION FOUR FIFTHS */ -#define XKB_KEY_onesixth 0x0ab6 /* U+2159 VULGAR FRACTION ONE SIXTH */ -#define XKB_KEY_fivesixths 0x0ab7 /* U+215A VULGAR FRACTION FIVE SIXTHS */ -#define XKB_KEY_careof 0x0ab8 /* U+2105 CARE OF */ -#define XKB_KEY_figdash 0x0abb /* U+2012 FIGURE DASH */ -#define XKB_KEY_leftanglebracket 0x0abc /*(U+27E8 MATHEMATICAL LEFT ANGLE BRACKET)*/ -#define XKB_KEY_decimalpoint 0x0abd /*(U+002E FULL STOP)*/ -#define XKB_KEY_rightanglebracket 0x0abe /*(U+27E9 MATHEMATICAL RIGHT ANGLE BRACKET)*/ -#define XKB_KEY_marker 0x0abf -#define XKB_KEY_oneeighth 0x0ac3 /* U+215B VULGAR FRACTION ONE EIGHTH */ -#define XKB_KEY_threeeighths 0x0ac4 /* U+215C VULGAR FRACTION THREE EIGHTHS */ -#define XKB_KEY_fiveeighths 0x0ac5 /* U+215D VULGAR FRACTION FIVE EIGHTHS */ -#define XKB_KEY_seveneighths 0x0ac6 /* U+215E VULGAR FRACTION SEVEN EIGHTHS */ -#define XKB_KEY_trademark 0x0ac9 /* U+2122 TRADE MARK SIGN */ -#define XKB_KEY_signaturemark 0x0aca /*(U+2613 SALTIRE)*/ -#define XKB_KEY_trademarkincircle 0x0acb -#define XKB_KEY_leftopentriangle 0x0acc /*(U+25C1 WHITE LEFT-POINTING TRIANGLE)*/ -#define XKB_KEY_rightopentriangle 0x0acd /*(U+25B7 WHITE RIGHT-POINTING TRIANGLE)*/ -#define XKB_KEY_emopencircle 0x0ace /*(U+25CB WHITE CIRCLE)*/ -#define XKB_KEY_emopenrectangle 0x0acf /*(U+25AF WHITE VERTICAL RECTANGLE)*/ -#define XKB_KEY_leftsinglequotemark 0x0ad0 /* U+2018 LEFT SINGLE QUOTATION MARK */ -#define XKB_KEY_rightsinglequotemark 0x0ad1 /* U+2019 RIGHT SINGLE QUOTATION MARK */ -#define XKB_KEY_leftdoublequotemark 0x0ad2 /* U+201C LEFT DOUBLE QUOTATION MARK */ -#define XKB_KEY_rightdoublequotemark 0x0ad3 /* U+201D RIGHT DOUBLE QUOTATION MARK */ -#define XKB_KEY_prescription 0x0ad4 /* U+211E PRESCRIPTION TAKE */ -#define XKB_KEY_permille 0x0ad5 /* U+2030 PER MILLE SIGN */ -#define XKB_KEY_minutes 0x0ad6 /* U+2032 PRIME */ -#define XKB_KEY_seconds 0x0ad7 /* U+2033 DOUBLE PRIME */ -#define XKB_KEY_latincross 0x0ad9 /* U+271D LATIN CROSS */ -#define XKB_KEY_hexagram 0x0ada -#define XKB_KEY_filledrectbullet 0x0adb /*(U+25AC BLACK RECTANGLE)*/ -#define XKB_KEY_filledlefttribullet 0x0adc /*(U+25C0 BLACK LEFT-POINTING TRIANGLE)*/ -#define XKB_KEY_filledrighttribullet 0x0add /*(U+25B6 BLACK RIGHT-POINTING TRIANGLE)*/ -#define XKB_KEY_emfilledcircle 0x0ade /*(U+25CF BLACK CIRCLE)*/ -#define XKB_KEY_emfilledrect 0x0adf /*(U+25AE BLACK VERTICAL RECTANGLE)*/ -#define XKB_KEY_enopencircbullet 0x0ae0 /*(U+25E6 WHITE BULLET)*/ -#define XKB_KEY_enopensquarebullet 0x0ae1 /*(U+25AB WHITE SMALL SQUARE)*/ -#define XKB_KEY_openrectbullet 0x0ae2 /*(U+25AD WHITE RECTANGLE)*/ -#define XKB_KEY_opentribulletup 0x0ae3 /*(U+25B3 WHITE UP-POINTING TRIANGLE)*/ -#define XKB_KEY_opentribulletdown 0x0ae4 /*(U+25BD WHITE DOWN-POINTING TRIANGLE)*/ -#define XKB_KEY_openstar 0x0ae5 /*(U+2606 WHITE STAR)*/ -#define XKB_KEY_enfilledcircbullet 0x0ae6 /*(U+2022 BULLET)*/ -#define XKB_KEY_enfilledsqbullet 0x0ae7 /*(U+25AA BLACK SMALL SQUARE)*/ -#define XKB_KEY_filledtribulletup 0x0ae8 /*(U+25B2 BLACK UP-POINTING TRIANGLE)*/ -#define XKB_KEY_filledtribulletdown 0x0ae9 /*(U+25BC BLACK DOWN-POINTING TRIANGLE)*/ -#define XKB_KEY_leftpointer 0x0aea /*(U+261C WHITE LEFT POINTING INDEX)*/ -#define XKB_KEY_rightpointer 0x0aeb /*(U+261E WHITE RIGHT POINTING INDEX)*/ -#define XKB_KEY_club 0x0aec /* U+2663 BLACK CLUB SUIT */ -#define XKB_KEY_diamond 0x0aed /* U+2666 BLACK DIAMOND SUIT */ -#define XKB_KEY_heart 0x0aee /* U+2665 BLACK HEART SUIT */ -#define XKB_KEY_maltesecross 0x0af0 /* U+2720 MALTESE CROSS */ -#define XKB_KEY_dagger 0x0af1 /* U+2020 DAGGER */ -#define XKB_KEY_doubledagger 0x0af2 /* U+2021 DOUBLE DAGGER */ -#define XKB_KEY_checkmark 0x0af3 /* U+2713 CHECK MARK */ -#define XKB_KEY_ballotcross 0x0af4 /* U+2717 BALLOT X */ -#define XKB_KEY_musicalsharp 0x0af5 /* U+266F MUSIC SHARP SIGN */ -#define XKB_KEY_musicalflat 0x0af6 /* U+266D MUSIC FLAT SIGN */ -#define XKB_KEY_malesymbol 0x0af7 /* U+2642 MALE SIGN */ -#define XKB_KEY_femalesymbol 0x0af8 /* U+2640 FEMALE SIGN */ -#define XKB_KEY_telephone 0x0af9 /* U+260E BLACK TELEPHONE */ -#define XKB_KEY_telephonerecorder 0x0afa /* U+2315 TELEPHONE RECORDER */ -#define XKB_KEY_phonographcopyright 0x0afb /* U+2117 SOUND RECORDING COPYRIGHT */ -#define XKB_KEY_caret 0x0afc /* U+2038 CARET */ -#define XKB_KEY_singlelowquotemark 0x0afd /* U+201A SINGLE LOW-9 QUOTATION MARK */ -#define XKB_KEY_doublelowquotemark 0x0afe /* U+201E DOUBLE LOW-9 QUOTATION MARK */ -#define XKB_KEY_cursor 0x0aff - -/* - * APL - * Byte 3 = 0x0b - */ - -#define XKB_KEY_leftcaret 0x0ba3 /*(U+003C LESS-THAN SIGN)*/ -#define XKB_KEY_rightcaret 0x0ba6 /*(U+003E GREATER-THAN SIGN)*/ -#define XKB_KEY_downcaret 0x0ba8 /*(U+2228 LOGICAL OR)*/ -#define XKB_KEY_upcaret 0x0ba9 /*(U+2227 LOGICAL AND)*/ -#define XKB_KEY_overbar 0x0bc0 /*(U+00AF MACRON)*/ -#define XKB_KEY_downtack 0x0bc2 /* U+22A4 DOWN TACK */ -#define XKB_KEY_upshoe 0x0bc3 /*(U+2229 INTERSECTION)*/ -#define XKB_KEY_downstile 0x0bc4 /* U+230A LEFT FLOOR */ -#define XKB_KEY_underbar 0x0bc6 /*(U+005F LOW LINE)*/ -#define XKB_KEY_jot 0x0bca /* U+2218 RING OPERATOR */ -#define XKB_KEY_quad 0x0bcc /* U+2395 APL FUNCTIONAL SYMBOL QUAD */ -#define XKB_KEY_uptack 0x0bce /* U+22A5 UP TACK */ -#define XKB_KEY_circle 0x0bcf /* U+25CB WHITE CIRCLE */ -#define XKB_KEY_upstile 0x0bd3 /* U+2308 LEFT CEILING */ -#define XKB_KEY_downshoe 0x0bd6 /*(U+222A UNION)*/ -#define XKB_KEY_rightshoe 0x0bd8 /*(U+2283 SUPERSET OF)*/ -#define XKB_KEY_leftshoe 0x0bda /*(U+2282 SUBSET OF)*/ -#define XKB_KEY_lefttack 0x0bdc /* U+22A3 LEFT TACK */ -#define XKB_KEY_righttack 0x0bfc /* U+22A2 RIGHT TACK */ - -/* - * Hebrew - * Byte 3 = 0x0c - */ - -#define XKB_KEY_hebrew_doublelowline 0x0cdf /* U+2017 DOUBLE LOW LINE */ -#define XKB_KEY_hebrew_aleph 0x0ce0 /* U+05D0 HEBREW LETTER ALEF */ -#define XKB_KEY_hebrew_bet 0x0ce1 /* U+05D1 HEBREW LETTER BET */ -#define XKB_KEY_hebrew_beth 0x0ce1 /* deprecated */ -#define XKB_KEY_hebrew_gimel 0x0ce2 /* U+05D2 HEBREW LETTER GIMEL */ -#define XKB_KEY_hebrew_gimmel 0x0ce2 /* deprecated */ -#define XKB_KEY_hebrew_dalet 0x0ce3 /* U+05D3 HEBREW LETTER DALET */ -#define XKB_KEY_hebrew_daleth 0x0ce3 /* deprecated */ -#define XKB_KEY_hebrew_he 0x0ce4 /* U+05D4 HEBREW LETTER HE */ -#define XKB_KEY_hebrew_waw 0x0ce5 /* U+05D5 HEBREW LETTER VAV */ -#define XKB_KEY_hebrew_zain 0x0ce6 /* U+05D6 HEBREW LETTER ZAYIN */ -#define XKB_KEY_hebrew_zayin 0x0ce6 /* deprecated */ -#define XKB_KEY_hebrew_chet 0x0ce7 /* U+05D7 HEBREW LETTER HET */ -#define XKB_KEY_hebrew_het 0x0ce7 /* deprecated */ -#define XKB_KEY_hebrew_tet 0x0ce8 /* U+05D8 HEBREW LETTER TET */ -#define XKB_KEY_hebrew_teth 0x0ce8 /* deprecated */ -#define XKB_KEY_hebrew_yod 0x0ce9 /* U+05D9 HEBREW LETTER YOD */ -#define XKB_KEY_hebrew_finalkaph 0x0cea /* U+05DA HEBREW LETTER FINAL KAF */ -#define XKB_KEY_hebrew_kaph 0x0ceb /* U+05DB HEBREW LETTER KAF */ -#define XKB_KEY_hebrew_lamed 0x0cec /* U+05DC HEBREW LETTER LAMED */ -#define XKB_KEY_hebrew_finalmem 0x0ced /* U+05DD HEBREW LETTER FINAL MEM */ -#define XKB_KEY_hebrew_mem 0x0cee /* U+05DE HEBREW LETTER MEM */ -#define XKB_KEY_hebrew_finalnun 0x0cef /* U+05DF HEBREW LETTER FINAL NUN */ -#define XKB_KEY_hebrew_nun 0x0cf0 /* U+05E0 HEBREW LETTER NUN */ -#define XKB_KEY_hebrew_samech 0x0cf1 /* U+05E1 HEBREW LETTER SAMEKH */ -#define XKB_KEY_hebrew_samekh 0x0cf1 /* deprecated */ -#define XKB_KEY_hebrew_ayin 0x0cf2 /* U+05E2 HEBREW LETTER AYIN */ -#define XKB_KEY_hebrew_finalpe 0x0cf3 /* U+05E3 HEBREW LETTER FINAL PE */ -#define XKB_KEY_hebrew_pe 0x0cf4 /* U+05E4 HEBREW LETTER PE */ -#define XKB_KEY_hebrew_finalzade 0x0cf5 /* U+05E5 HEBREW LETTER FINAL TSADI */ -#define XKB_KEY_hebrew_finalzadi 0x0cf5 /* deprecated */ -#define XKB_KEY_hebrew_zade 0x0cf6 /* U+05E6 HEBREW LETTER TSADI */ -#define XKB_KEY_hebrew_zadi 0x0cf6 /* deprecated */ -#define XKB_KEY_hebrew_qoph 0x0cf7 /* U+05E7 HEBREW LETTER QOF */ -#define XKB_KEY_hebrew_kuf 0x0cf7 /* deprecated */ -#define XKB_KEY_hebrew_resh 0x0cf8 /* U+05E8 HEBREW LETTER RESH */ -#define XKB_KEY_hebrew_shin 0x0cf9 /* U+05E9 HEBREW LETTER SHIN */ -#define XKB_KEY_hebrew_taw 0x0cfa /* U+05EA HEBREW LETTER TAV */ -#define XKB_KEY_hebrew_taf 0x0cfa /* deprecated */ -#define XKB_KEY_Hebrew_switch 0xff7e /* Alias for mode_switch */ - -/* - * Thai - * Byte 3 = 0x0d - */ - -#define XKB_KEY_Thai_kokai 0x0da1 /* U+0E01 THAI CHARACTER KO KAI */ -#define XKB_KEY_Thai_khokhai 0x0da2 /* U+0E02 THAI CHARACTER KHO KHAI */ -#define XKB_KEY_Thai_khokhuat 0x0da3 /* U+0E03 THAI CHARACTER KHO KHUAT */ -#define XKB_KEY_Thai_khokhwai 0x0da4 /* U+0E04 THAI CHARACTER KHO KHWAI */ -#define XKB_KEY_Thai_khokhon 0x0da5 /* U+0E05 THAI CHARACTER KHO KHON */ -#define XKB_KEY_Thai_khorakhang 0x0da6 /* U+0E06 THAI CHARACTER KHO RAKHANG */ -#define XKB_KEY_Thai_ngongu 0x0da7 /* U+0E07 THAI CHARACTER NGO NGU */ -#define XKB_KEY_Thai_chochan 0x0da8 /* U+0E08 THAI CHARACTER CHO CHAN */ -#define XKB_KEY_Thai_choching 0x0da9 /* U+0E09 THAI CHARACTER CHO CHING */ -#define XKB_KEY_Thai_chochang 0x0daa /* U+0E0A THAI CHARACTER CHO CHANG */ -#define XKB_KEY_Thai_soso 0x0dab /* U+0E0B THAI CHARACTER SO SO */ -#define XKB_KEY_Thai_chochoe 0x0dac /* U+0E0C THAI CHARACTER CHO CHOE */ -#define XKB_KEY_Thai_yoying 0x0dad /* U+0E0D THAI CHARACTER YO YING */ -#define XKB_KEY_Thai_dochada 0x0dae /* U+0E0E THAI CHARACTER DO CHADA */ -#define XKB_KEY_Thai_topatak 0x0daf /* U+0E0F THAI CHARACTER TO PATAK */ -#define XKB_KEY_Thai_thothan 0x0db0 /* U+0E10 THAI CHARACTER THO THAN */ -#define XKB_KEY_Thai_thonangmontho 0x0db1 /* U+0E11 THAI CHARACTER THO NANGMONTHO */ -#define XKB_KEY_Thai_thophuthao 0x0db2 /* U+0E12 THAI CHARACTER THO PHUTHAO */ -#define XKB_KEY_Thai_nonen 0x0db3 /* U+0E13 THAI CHARACTER NO NEN */ -#define XKB_KEY_Thai_dodek 0x0db4 /* U+0E14 THAI CHARACTER DO DEK */ -#define XKB_KEY_Thai_totao 0x0db5 /* U+0E15 THAI CHARACTER TO TAO */ -#define XKB_KEY_Thai_thothung 0x0db6 /* U+0E16 THAI CHARACTER THO THUNG */ -#define XKB_KEY_Thai_thothahan 0x0db7 /* U+0E17 THAI CHARACTER THO THAHAN */ -#define XKB_KEY_Thai_thothong 0x0db8 /* U+0E18 THAI CHARACTER THO THONG */ -#define XKB_KEY_Thai_nonu 0x0db9 /* U+0E19 THAI CHARACTER NO NU */ -#define XKB_KEY_Thai_bobaimai 0x0dba /* U+0E1A THAI CHARACTER BO BAIMAI */ -#define XKB_KEY_Thai_popla 0x0dbb /* U+0E1B THAI CHARACTER PO PLA */ -#define XKB_KEY_Thai_phophung 0x0dbc /* U+0E1C THAI CHARACTER PHO PHUNG */ -#define XKB_KEY_Thai_fofa 0x0dbd /* U+0E1D THAI CHARACTER FO FA */ -#define XKB_KEY_Thai_phophan 0x0dbe /* U+0E1E THAI CHARACTER PHO PHAN */ -#define XKB_KEY_Thai_fofan 0x0dbf /* U+0E1F THAI CHARACTER FO FAN */ -#define XKB_KEY_Thai_phosamphao 0x0dc0 /* U+0E20 THAI CHARACTER PHO SAMPHAO */ -#define XKB_KEY_Thai_moma 0x0dc1 /* U+0E21 THAI CHARACTER MO MA */ -#define XKB_KEY_Thai_yoyak 0x0dc2 /* U+0E22 THAI CHARACTER YO YAK */ -#define XKB_KEY_Thai_rorua 0x0dc3 /* U+0E23 THAI CHARACTER RO RUA */ -#define XKB_KEY_Thai_ru 0x0dc4 /* U+0E24 THAI CHARACTER RU */ -#define XKB_KEY_Thai_loling 0x0dc5 /* U+0E25 THAI CHARACTER LO LING */ -#define XKB_KEY_Thai_lu 0x0dc6 /* U+0E26 THAI CHARACTER LU */ -#define XKB_KEY_Thai_wowaen 0x0dc7 /* U+0E27 THAI CHARACTER WO WAEN */ -#define XKB_KEY_Thai_sosala 0x0dc8 /* U+0E28 THAI CHARACTER SO SALA */ -#define XKB_KEY_Thai_sorusi 0x0dc9 /* U+0E29 THAI CHARACTER SO RUSI */ -#define XKB_KEY_Thai_sosua 0x0dca /* U+0E2A THAI CHARACTER SO SUA */ -#define XKB_KEY_Thai_hohip 0x0dcb /* U+0E2B THAI CHARACTER HO HIP */ -#define XKB_KEY_Thai_lochula 0x0dcc /* U+0E2C THAI CHARACTER LO CHULA */ -#define XKB_KEY_Thai_oang 0x0dcd /* U+0E2D THAI CHARACTER O ANG */ -#define XKB_KEY_Thai_honokhuk 0x0dce /* U+0E2E THAI CHARACTER HO NOKHUK */ -#define XKB_KEY_Thai_paiyannoi 0x0dcf /* U+0E2F THAI CHARACTER PAIYANNOI */ -#define XKB_KEY_Thai_saraa 0x0dd0 /* U+0E30 THAI CHARACTER SARA A */ -#define XKB_KEY_Thai_maihanakat 0x0dd1 /* U+0E31 THAI CHARACTER MAI HAN-AKAT */ -#define XKB_KEY_Thai_saraaa 0x0dd2 /* U+0E32 THAI CHARACTER SARA AA */ -#define XKB_KEY_Thai_saraam 0x0dd3 /* U+0E33 THAI CHARACTER SARA AM */ -#define XKB_KEY_Thai_sarai 0x0dd4 /* U+0E34 THAI CHARACTER SARA I */ -#define XKB_KEY_Thai_saraii 0x0dd5 /* U+0E35 THAI CHARACTER SARA II */ -#define XKB_KEY_Thai_saraue 0x0dd6 /* U+0E36 THAI CHARACTER SARA UE */ -#define XKB_KEY_Thai_sarauee 0x0dd7 /* U+0E37 THAI CHARACTER SARA UEE */ -#define XKB_KEY_Thai_sarau 0x0dd8 /* U+0E38 THAI CHARACTER SARA U */ -#define XKB_KEY_Thai_sarauu 0x0dd9 /* U+0E39 THAI CHARACTER SARA UU */ -#define XKB_KEY_Thai_phinthu 0x0dda /* U+0E3A THAI CHARACTER PHINTHU */ -#define XKB_KEY_Thai_maihanakat_maitho 0x0dde -#define XKB_KEY_Thai_baht 0x0ddf /* U+0E3F THAI CURRENCY SYMBOL BAHT */ -#define XKB_KEY_Thai_sarae 0x0de0 /* U+0E40 THAI CHARACTER SARA E */ -#define XKB_KEY_Thai_saraae 0x0de1 /* U+0E41 THAI CHARACTER SARA AE */ -#define XKB_KEY_Thai_sarao 0x0de2 /* U+0E42 THAI CHARACTER SARA O */ -#define XKB_KEY_Thai_saraaimaimuan 0x0de3 /* U+0E43 THAI CHARACTER SARA AI MAIMUAN */ -#define XKB_KEY_Thai_saraaimaimalai 0x0de4 /* U+0E44 THAI CHARACTER SARA AI MAIMALAI */ -#define XKB_KEY_Thai_lakkhangyao 0x0de5 /* U+0E45 THAI CHARACTER LAKKHANGYAO */ -#define XKB_KEY_Thai_maiyamok 0x0de6 /* U+0E46 THAI CHARACTER MAIYAMOK */ -#define XKB_KEY_Thai_maitaikhu 0x0de7 /* U+0E47 THAI CHARACTER MAITAIKHU */ -#define XKB_KEY_Thai_maiek 0x0de8 /* U+0E48 THAI CHARACTER MAI EK */ -#define XKB_KEY_Thai_maitho 0x0de9 /* U+0E49 THAI CHARACTER MAI THO */ -#define XKB_KEY_Thai_maitri 0x0dea /* U+0E4A THAI CHARACTER MAI TRI */ -#define XKB_KEY_Thai_maichattawa 0x0deb /* U+0E4B THAI CHARACTER MAI CHATTAWA */ -#define XKB_KEY_Thai_thanthakhat 0x0dec /* U+0E4C THAI CHARACTER THANTHAKHAT */ -#define XKB_KEY_Thai_nikhahit 0x0ded /* U+0E4D THAI CHARACTER NIKHAHIT */ -#define XKB_KEY_Thai_leksun 0x0df0 /* U+0E50 THAI DIGIT ZERO */ -#define XKB_KEY_Thai_leknung 0x0df1 /* U+0E51 THAI DIGIT ONE */ -#define XKB_KEY_Thai_leksong 0x0df2 /* U+0E52 THAI DIGIT TWO */ -#define XKB_KEY_Thai_leksam 0x0df3 /* U+0E53 THAI DIGIT THREE */ -#define XKB_KEY_Thai_leksi 0x0df4 /* U+0E54 THAI DIGIT FOUR */ -#define XKB_KEY_Thai_lekha 0x0df5 /* U+0E55 THAI DIGIT FIVE */ -#define XKB_KEY_Thai_lekhok 0x0df6 /* U+0E56 THAI DIGIT SIX */ -#define XKB_KEY_Thai_lekchet 0x0df7 /* U+0E57 THAI DIGIT SEVEN */ -#define XKB_KEY_Thai_lekpaet 0x0df8 /* U+0E58 THAI DIGIT EIGHT */ -#define XKB_KEY_Thai_lekkao 0x0df9 /* U+0E59 THAI DIGIT NINE */ - -/* - * Korean - * Byte 3 = 0x0e - */ - - -#define XKB_KEY_Hangul 0xff31 /* Hangul start/stop(toggle) */ -#define XKB_KEY_Hangul_Start 0xff32 /* Hangul start */ -#define XKB_KEY_Hangul_End 0xff33 /* Hangul end, English start */ -#define XKB_KEY_Hangul_Hanja 0xff34 /* Start Hangul->Hanja Conversion */ -#define XKB_KEY_Hangul_Jamo 0xff35 /* Hangul Jamo mode */ -#define XKB_KEY_Hangul_Romaja 0xff36 /* Hangul Romaja mode */ -#define XKB_KEY_Hangul_Codeinput 0xff37 /* Hangul code input mode */ -#define XKB_KEY_Hangul_Jeonja 0xff38 /* Jeonja mode */ -#define XKB_KEY_Hangul_Banja 0xff39 /* Banja mode */ -#define XKB_KEY_Hangul_PreHanja 0xff3a /* Pre Hanja conversion */ -#define XKB_KEY_Hangul_PostHanja 0xff3b /* Post Hanja conversion */ -#define XKB_KEY_Hangul_SingleCandidate 0xff3c /* Single candidate */ -#define XKB_KEY_Hangul_MultipleCandidate 0xff3d /* Multiple candidate */ -#define XKB_KEY_Hangul_PreviousCandidate 0xff3e /* Previous candidate */ -#define XKB_KEY_Hangul_Special 0xff3f /* Special symbols */ -#define XKB_KEY_Hangul_switch 0xff7e /* Alias for mode_switch */ - -/* Hangul Consonant Characters */ -#define XKB_KEY_Hangul_Kiyeog 0x0ea1 -#define XKB_KEY_Hangul_SsangKiyeog 0x0ea2 -#define XKB_KEY_Hangul_KiyeogSios 0x0ea3 -#define XKB_KEY_Hangul_Nieun 0x0ea4 -#define XKB_KEY_Hangul_NieunJieuj 0x0ea5 -#define XKB_KEY_Hangul_NieunHieuh 0x0ea6 -#define XKB_KEY_Hangul_Dikeud 0x0ea7 -#define XKB_KEY_Hangul_SsangDikeud 0x0ea8 -#define XKB_KEY_Hangul_Rieul 0x0ea9 -#define XKB_KEY_Hangul_RieulKiyeog 0x0eaa -#define XKB_KEY_Hangul_RieulMieum 0x0eab -#define XKB_KEY_Hangul_RieulPieub 0x0eac -#define XKB_KEY_Hangul_RieulSios 0x0ead -#define XKB_KEY_Hangul_RieulTieut 0x0eae -#define XKB_KEY_Hangul_RieulPhieuf 0x0eaf -#define XKB_KEY_Hangul_RieulHieuh 0x0eb0 -#define XKB_KEY_Hangul_Mieum 0x0eb1 -#define XKB_KEY_Hangul_Pieub 0x0eb2 -#define XKB_KEY_Hangul_SsangPieub 0x0eb3 -#define XKB_KEY_Hangul_PieubSios 0x0eb4 -#define XKB_KEY_Hangul_Sios 0x0eb5 -#define XKB_KEY_Hangul_SsangSios 0x0eb6 -#define XKB_KEY_Hangul_Ieung 0x0eb7 -#define XKB_KEY_Hangul_Jieuj 0x0eb8 -#define XKB_KEY_Hangul_SsangJieuj 0x0eb9 -#define XKB_KEY_Hangul_Cieuc 0x0eba -#define XKB_KEY_Hangul_Khieuq 0x0ebb -#define XKB_KEY_Hangul_Tieut 0x0ebc -#define XKB_KEY_Hangul_Phieuf 0x0ebd -#define XKB_KEY_Hangul_Hieuh 0x0ebe - -/* Hangul Vowel Characters */ -#define XKB_KEY_Hangul_A 0x0ebf -#define XKB_KEY_Hangul_AE 0x0ec0 -#define XKB_KEY_Hangul_YA 0x0ec1 -#define XKB_KEY_Hangul_YAE 0x0ec2 -#define XKB_KEY_Hangul_EO 0x0ec3 -#define XKB_KEY_Hangul_E 0x0ec4 -#define XKB_KEY_Hangul_YEO 0x0ec5 -#define XKB_KEY_Hangul_YE 0x0ec6 -#define XKB_KEY_Hangul_O 0x0ec7 -#define XKB_KEY_Hangul_WA 0x0ec8 -#define XKB_KEY_Hangul_WAE 0x0ec9 -#define XKB_KEY_Hangul_OE 0x0eca -#define XKB_KEY_Hangul_YO 0x0ecb -#define XKB_KEY_Hangul_U 0x0ecc -#define XKB_KEY_Hangul_WEO 0x0ecd -#define XKB_KEY_Hangul_WE 0x0ece -#define XKB_KEY_Hangul_WI 0x0ecf -#define XKB_KEY_Hangul_YU 0x0ed0 -#define XKB_KEY_Hangul_EU 0x0ed1 -#define XKB_KEY_Hangul_YI 0x0ed2 -#define XKB_KEY_Hangul_I 0x0ed3 - -/* Hangul syllable-final (JongSeong) Characters */ -#define XKB_KEY_Hangul_J_Kiyeog 0x0ed4 -#define XKB_KEY_Hangul_J_SsangKiyeog 0x0ed5 -#define XKB_KEY_Hangul_J_KiyeogSios 0x0ed6 -#define XKB_KEY_Hangul_J_Nieun 0x0ed7 -#define XKB_KEY_Hangul_J_NieunJieuj 0x0ed8 -#define XKB_KEY_Hangul_J_NieunHieuh 0x0ed9 -#define XKB_KEY_Hangul_J_Dikeud 0x0eda -#define XKB_KEY_Hangul_J_Rieul 0x0edb -#define XKB_KEY_Hangul_J_RieulKiyeog 0x0edc -#define XKB_KEY_Hangul_J_RieulMieum 0x0edd -#define XKB_KEY_Hangul_J_RieulPieub 0x0ede -#define XKB_KEY_Hangul_J_RieulSios 0x0edf -#define XKB_KEY_Hangul_J_RieulTieut 0x0ee0 -#define XKB_KEY_Hangul_J_RieulPhieuf 0x0ee1 -#define XKB_KEY_Hangul_J_RieulHieuh 0x0ee2 -#define XKB_KEY_Hangul_J_Mieum 0x0ee3 -#define XKB_KEY_Hangul_J_Pieub 0x0ee4 -#define XKB_KEY_Hangul_J_PieubSios 0x0ee5 -#define XKB_KEY_Hangul_J_Sios 0x0ee6 -#define XKB_KEY_Hangul_J_SsangSios 0x0ee7 -#define XKB_KEY_Hangul_J_Ieung 0x0ee8 -#define XKB_KEY_Hangul_J_Jieuj 0x0ee9 -#define XKB_KEY_Hangul_J_Cieuc 0x0eea -#define XKB_KEY_Hangul_J_Khieuq 0x0eeb -#define XKB_KEY_Hangul_J_Tieut 0x0eec -#define XKB_KEY_Hangul_J_Phieuf 0x0eed -#define XKB_KEY_Hangul_J_Hieuh 0x0eee - -/* Ancient Hangul Consonant Characters */ -#define XKB_KEY_Hangul_RieulYeorinHieuh 0x0eef -#define XKB_KEY_Hangul_SunkyeongeumMieum 0x0ef0 -#define XKB_KEY_Hangul_SunkyeongeumPieub 0x0ef1 -#define XKB_KEY_Hangul_PanSios 0x0ef2 -#define XKB_KEY_Hangul_KkogjiDalrinIeung 0x0ef3 -#define XKB_KEY_Hangul_SunkyeongeumPhieuf 0x0ef4 -#define XKB_KEY_Hangul_YeorinHieuh 0x0ef5 - -/* Ancient Hangul Vowel Characters */ -#define XKB_KEY_Hangul_AraeA 0x0ef6 -#define XKB_KEY_Hangul_AraeAE 0x0ef7 - -/* Ancient Hangul syllable-final (JongSeong) Characters */ -#define XKB_KEY_Hangul_J_PanSios 0x0ef8 -#define XKB_KEY_Hangul_J_KkogjiDalrinIeung 0x0ef9 -#define XKB_KEY_Hangul_J_YeorinHieuh 0x0efa - -/* Korean currency symbol */ -#define XKB_KEY_Korean_Won 0x0eff /*(U+20A9 WON SIGN)*/ - - -/* - * Armenian - */ - -#define XKB_KEY_Armenian_ligature_ew 0x1000587 /* U+0587 ARMENIAN SMALL LIGATURE ECH YIWN */ -#define XKB_KEY_Armenian_full_stop 0x1000589 /* U+0589 ARMENIAN FULL STOP */ -#define XKB_KEY_Armenian_verjaket 0x1000589 /* U+0589 ARMENIAN FULL STOP */ -#define XKB_KEY_Armenian_separation_mark 0x100055d /* U+055D ARMENIAN COMMA */ -#define XKB_KEY_Armenian_but 0x100055d /* U+055D ARMENIAN COMMA */ -#define XKB_KEY_Armenian_hyphen 0x100058a /* U+058A ARMENIAN HYPHEN */ -#define XKB_KEY_Armenian_yentamna 0x100058a /* U+058A ARMENIAN HYPHEN */ -#define XKB_KEY_Armenian_exclam 0x100055c /* U+055C ARMENIAN EXCLAMATION MARK */ -#define XKB_KEY_Armenian_amanak 0x100055c /* U+055C ARMENIAN EXCLAMATION MARK */ -#define XKB_KEY_Armenian_accent 0x100055b /* U+055B ARMENIAN EMPHASIS MARK */ -#define XKB_KEY_Armenian_shesht 0x100055b /* U+055B ARMENIAN EMPHASIS MARK */ -#define XKB_KEY_Armenian_question 0x100055e /* U+055E ARMENIAN QUESTION MARK */ -#define XKB_KEY_Armenian_paruyk 0x100055e /* U+055E ARMENIAN QUESTION MARK */ -#define XKB_KEY_Armenian_AYB 0x1000531 /* U+0531 ARMENIAN CAPITAL LETTER AYB */ -#define XKB_KEY_Armenian_ayb 0x1000561 /* U+0561 ARMENIAN SMALL LETTER AYB */ -#define XKB_KEY_Armenian_BEN 0x1000532 /* U+0532 ARMENIAN CAPITAL LETTER BEN */ -#define XKB_KEY_Armenian_ben 0x1000562 /* U+0562 ARMENIAN SMALL LETTER BEN */ -#define XKB_KEY_Armenian_GIM 0x1000533 /* U+0533 ARMENIAN CAPITAL LETTER GIM */ -#define XKB_KEY_Armenian_gim 0x1000563 /* U+0563 ARMENIAN SMALL LETTER GIM */ -#define XKB_KEY_Armenian_DA 0x1000534 /* U+0534 ARMENIAN CAPITAL LETTER DA */ -#define XKB_KEY_Armenian_da 0x1000564 /* U+0564 ARMENIAN SMALL LETTER DA */ -#define XKB_KEY_Armenian_YECH 0x1000535 /* U+0535 ARMENIAN CAPITAL LETTER ECH */ -#define XKB_KEY_Armenian_yech 0x1000565 /* U+0565 ARMENIAN SMALL LETTER ECH */ -#define XKB_KEY_Armenian_ZA 0x1000536 /* U+0536 ARMENIAN CAPITAL LETTER ZA */ -#define XKB_KEY_Armenian_za 0x1000566 /* U+0566 ARMENIAN SMALL LETTER ZA */ -#define XKB_KEY_Armenian_E 0x1000537 /* U+0537 ARMENIAN CAPITAL LETTER EH */ -#define XKB_KEY_Armenian_e 0x1000567 /* U+0567 ARMENIAN SMALL LETTER EH */ -#define XKB_KEY_Armenian_AT 0x1000538 /* U+0538 ARMENIAN CAPITAL LETTER ET */ -#define XKB_KEY_Armenian_at 0x1000568 /* U+0568 ARMENIAN SMALL LETTER ET */ -#define XKB_KEY_Armenian_TO 0x1000539 /* U+0539 ARMENIAN CAPITAL LETTER TO */ -#define XKB_KEY_Armenian_to 0x1000569 /* U+0569 ARMENIAN SMALL LETTER TO */ -#define XKB_KEY_Armenian_ZHE 0x100053a /* U+053A ARMENIAN CAPITAL LETTER ZHE */ -#define XKB_KEY_Armenian_zhe 0x100056a /* U+056A ARMENIAN SMALL LETTER ZHE */ -#define XKB_KEY_Armenian_INI 0x100053b /* U+053B ARMENIAN CAPITAL LETTER INI */ -#define XKB_KEY_Armenian_ini 0x100056b /* U+056B ARMENIAN SMALL LETTER INI */ -#define XKB_KEY_Armenian_LYUN 0x100053c /* U+053C ARMENIAN CAPITAL LETTER LIWN */ -#define XKB_KEY_Armenian_lyun 0x100056c /* U+056C ARMENIAN SMALL LETTER LIWN */ -#define XKB_KEY_Armenian_KHE 0x100053d /* U+053D ARMENIAN CAPITAL LETTER XEH */ -#define XKB_KEY_Armenian_khe 0x100056d /* U+056D ARMENIAN SMALL LETTER XEH */ -#define XKB_KEY_Armenian_TSA 0x100053e /* U+053E ARMENIAN CAPITAL LETTER CA */ -#define XKB_KEY_Armenian_tsa 0x100056e /* U+056E ARMENIAN SMALL LETTER CA */ -#define XKB_KEY_Armenian_KEN 0x100053f /* U+053F ARMENIAN CAPITAL LETTER KEN */ -#define XKB_KEY_Armenian_ken 0x100056f /* U+056F ARMENIAN SMALL LETTER KEN */ -#define XKB_KEY_Armenian_HO 0x1000540 /* U+0540 ARMENIAN CAPITAL LETTER HO */ -#define XKB_KEY_Armenian_ho 0x1000570 /* U+0570 ARMENIAN SMALL LETTER HO */ -#define XKB_KEY_Armenian_DZA 0x1000541 /* U+0541 ARMENIAN CAPITAL LETTER JA */ -#define XKB_KEY_Armenian_dza 0x1000571 /* U+0571 ARMENIAN SMALL LETTER JA */ -#define XKB_KEY_Armenian_GHAT 0x1000542 /* U+0542 ARMENIAN CAPITAL LETTER GHAD */ -#define XKB_KEY_Armenian_ghat 0x1000572 /* U+0572 ARMENIAN SMALL LETTER GHAD */ -#define XKB_KEY_Armenian_TCHE 0x1000543 /* U+0543 ARMENIAN CAPITAL LETTER CHEH */ -#define XKB_KEY_Armenian_tche 0x1000573 /* U+0573 ARMENIAN SMALL LETTER CHEH */ -#define XKB_KEY_Armenian_MEN 0x1000544 /* U+0544 ARMENIAN CAPITAL LETTER MEN */ -#define XKB_KEY_Armenian_men 0x1000574 /* U+0574 ARMENIAN SMALL LETTER MEN */ -#define XKB_KEY_Armenian_HI 0x1000545 /* U+0545 ARMENIAN CAPITAL LETTER YI */ -#define XKB_KEY_Armenian_hi 0x1000575 /* U+0575 ARMENIAN SMALL LETTER YI */ -#define XKB_KEY_Armenian_NU 0x1000546 /* U+0546 ARMENIAN CAPITAL LETTER NOW */ -#define XKB_KEY_Armenian_nu 0x1000576 /* U+0576 ARMENIAN SMALL LETTER NOW */ -#define XKB_KEY_Armenian_SHA 0x1000547 /* U+0547 ARMENIAN CAPITAL LETTER SHA */ -#define XKB_KEY_Armenian_sha 0x1000577 /* U+0577 ARMENIAN SMALL LETTER SHA */ -#define XKB_KEY_Armenian_VO 0x1000548 /* U+0548 ARMENIAN CAPITAL LETTER VO */ -#define XKB_KEY_Armenian_vo 0x1000578 /* U+0578 ARMENIAN SMALL LETTER VO */ -#define XKB_KEY_Armenian_CHA 0x1000549 /* U+0549 ARMENIAN CAPITAL LETTER CHA */ -#define XKB_KEY_Armenian_cha 0x1000579 /* U+0579 ARMENIAN SMALL LETTER CHA */ -#define XKB_KEY_Armenian_PE 0x100054a /* U+054A ARMENIAN CAPITAL LETTER PEH */ -#define XKB_KEY_Armenian_pe 0x100057a /* U+057A ARMENIAN SMALL LETTER PEH */ -#define XKB_KEY_Armenian_JE 0x100054b /* U+054B ARMENIAN CAPITAL LETTER JHEH */ -#define XKB_KEY_Armenian_je 0x100057b /* U+057B ARMENIAN SMALL LETTER JHEH */ -#define XKB_KEY_Armenian_RA 0x100054c /* U+054C ARMENIAN CAPITAL LETTER RA */ -#define XKB_KEY_Armenian_ra 0x100057c /* U+057C ARMENIAN SMALL LETTER RA */ -#define XKB_KEY_Armenian_SE 0x100054d /* U+054D ARMENIAN CAPITAL LETTER SEH */ -#define XKB_KEY_Armenian_se 0x100057d /* U+057D ARMENIAN SMALL LETTER SEH */ -#define XKB_KEY_Armenian_VEV 0x100054e /* U+054E ARMENIAN CAPITAL LETTER VEW */ -#define XKB_KEY_Armenian_vev 0x100057e /* U+057E ARMENIAN SMALL LETTER VEW */ -#define XKB_KEY_Armenian_TYUN 0x100054f /* U+054F ARMENIAN CAPITAL LETTER TIWN */ -#define XKB_KEY_Armenian_tyun 0x100057f /* U+057F ARMENIAN SMALL LETTER TIWN */ -#define XKB_KEY_Armenian_RE 0x1000550 /* U+0550 ARMENIAN CAPITAL LETTER REH */ -#define XKB_KEY_Armenian_re 0x1000580 /* U+0580 ARMENIAN SMALL LETTER REH */ -#define XKB_KEY_Armenian_TSO 0x1000551 /* U+0551 ARMENIAN CAPITAL LETTER CO */ -#define XKB_KEY_Armenian_tso 0x1000581 /* U+0581 ARMENIAN SMALL LETTER CO */ -#define XKB_KEY_Armenian_VYUN 0x1000552 /* U+0552 ARMENIAN CAPITAL LETTER YIWN */ -#define XKB_KEY_Armenian_vyun 0x1000582 /* U+0582 ARMENIAN SMALL LETTER YIWN */ -#define XKB_KEY_Armenian_PYUR 0x1000553 /* U+0553 ARMENIAN CAPITAL LETTER PIWR */ -#define XKB_KEY_Armenian_pyur 0x1000583 /* U+0583 ARMENIAN SMALL LETTER PIWR */ -#define XKB_KEY_Armenian_KE 0x1000554 /* U+0554 ARMENIAN CAPITAL LETTER KEH */ -#define XKB_KEY_Armenian_ke 0x1000584 /* U+0584 ARMENIAN SMALL LETTER KEH */ -#define XKB_KEY_Armenian_O 0x1000555 /* U+0555 ARMENIAN CAPITAL LETTER OH */ -#define XKB_KEY_Armenian_o 0x1000585 /* U+0585 ARMENIAN SMALL LETTER OH */ -#define XKB_KEY_Armenian_FE 0x1000556 /* U+0556 ARMENIAN CAPITAL LETTER FEH */ -#define XKB_KEY_Armenian_fe 0x1000586 /* U+0586 ARMENIAN SMALL LETTER FEH */ -#define XKB_KEY_Armenian_apostrophe 0x100055a /* U+055A ARMENIAN APOSTROPHE */ - -/* - * Georgian - */ - -#define XKB_KEY_Georgian_an 0x10010d0 /* U+10D0 GEORGIAN LETTER AN */ -#define XKB_KEY_Georgian_ban 0x10010d1 /* U+10D1 GEORGIAN LETTER BAN */ -#define XKB_KEY_Georgian_gan 0x10010d2 /* U+10D2 GEORGIAN LETTER GAN */ -#define XKB_KEY_Georgian_don 0x10010d3 /* U+10D3 GEORGIAN LETTER DON */ -#define XKB_KEY_Georgian_en 0x10010d4 /* U+10D4 GEORGIAN LETTER EN */ -#define XKB_KEY_Georgian_vin 0x10010d5 /* U+10D5 GEORGIAN LETTER VIN */ -#define XKB_KEY_Georgian_zen 0x10010d6 /* U+10D6 GEORGIAN LETTER ZEN */ -#define XKB_KEY_Georgian_tan 0x10010d7 /* U+10D7 GEORGIAN LETTER TAN */ -#define XKB_KEY_Georgian_in 0x10010d8 /* U+10D8 GEORGIAN LETTER IN */ -#define XKB_KEY_Georgian_kan 0x10010d9 /* U+10D9 GEORGIAN LETTER KAN */ -#define XKB_KEY_Georgian_las 0x10010da /* U+10DA GEORGIAN LETTER LAS */ -#define XKB_KEY_Georgian_man 0x10010db /* U+10DB GEORGIAN LETTER MAN */ -#define XKB_KEY_Georgian_nar 0x10010dc /* U+10DC GEORGIAN LETTER NAR */ -#define XKB_KEY_Georgian_on 0x10010dd /* U+10DD GEORGIAN LETTER ON */ -#define XKB_KEY_Georgian_par 0x10010de /* U+10DE GEORGIAN LETTER PAR */ -#define XKB_KEY_Georgian_zhar 0x10010df /* U+10DF GEORGIAN LETTER ZHAR */ -#define XKB_KEY_Georgian_rae 0x10010e0 /* U+10E0 GEORGIAN LETTER RAE */ -#define XKB_KEY_Georgian_san 0x10010e1 /* U+10E1 GEORGIAN LETTER SAN */ -#define XKB_KEY_Georgian_tar 0x10010e2 /* U+10E2 GEORGIAN LETTER TAR */ -#define XKB_KEY_Georgian_un 0x10010e3 /* U+10E3 GEORGIAN LETTER UN */ -#define XKB_KEY_Georgian_phar 0x10010e4 /* U+10E4 GEORGIAN LETTER PHAR */ -#define XKB_KEY_Georgian_khar 0x10010e5 /* U+10E5 GEORGIAN LETTER KHAR */ -#define XKB_KEY_Georgian_ghan 0x10010e6 /* U+10E6 GEORGIAN LETTER GHAN */ -#define XKB_KEY_Georgian_qar 0x10010e7 /* U+10E7 GEORGIAN LETTER QAR */ -#define XKB_KEY_Georgian_shin 0x10010e8 /* U+10E8 GEORGIAN LETTER SHIN */ -#define XKB_KEY_Georgian_chin 0x10010e9 /* U+10E9 GEORGIAN LETTER CHIN */ -#define XKB_KEY_Georgian_can 0x10010ea /* U+10EA GEORGIAN LETTER CAN */ -#define XKB_KEY_Georgian_jil 0x10010eb /* U+10EB GEORGIAN LETTER JIL */ -#define XKB_KEY_Georgian_cil 0x10010ec /* U+10EC GEORGIAN LETTER CIL */ -#define XKB_KEY_Georgian_char 0x10010ed /* U+10ED GEORGIAN LETTER CHAR */ -#define XKB_KEY_Georgian_xan 0x10010ee /* U+10EE GEORGIAN LETTER XAN */ -#define XKB_KEY_Georgian_jhan 0x10010ef /* U+10EF GEORGIAN LETTER JHAN */ -#define XKB_KEY_Georgian_hae 0x10010f0 /* U+10F0 GEORGIAN LETTER HAE */ -#define XKB_KEY_Georgian_he 0x10010f1 /* U+10F1 GEORGIAN LETTER HE */ -#define XKB_KEY_Georgian_hie 0x10010f2 /* U+10F2 GEORGIAN LETTER HIE */ -#define XKB_KEY_Georgian_we 0x10010f3 /* U+10F3 GEORGIAN LETTER WE */ -#define XKB_KEY_Georgian_har 0x10010f4 /* U+10F4 GEORGIAN LETTER HAR */ -#define XKB_KEY_Georgian_hoe 0x10010f5 /* U+10F5 GEORGIAN LETTER HOE */ -#define XKB_KEY_Georgian_fi 0x10010f6 /* U+10F6 GEORGIAN LETTER FI */ - -/* - * Azeri (and other Turkic or Caucasian languages) - */ - -/* latin */ -#define XKB_KEY_Xabovedot 0x1001e8a /* U+1E8A LATIN CAPITAL LETTER X WITH DOT ABOVE */ -#define XKB_KEY_Ibreve 0x100012c /* U+012C LATIN CAPITAL LETTER I WITH BREVE */ -#define XKB_KEY_Zstroke 0x10001b5 /* U+01B5 LATIN CAPITAL LETTER Z WITH STROKE */ -#define XKB_KEY_Gcaron 0x10001e6 /* U+01E6 LATIN CAPITAL LETTER G WITH CARON */ -#define XKB_KEY_Ocaron 0x10001d1 /* U+01D2 LATIN CAPITAL LETTER O WITH CARON */ -#define XKB_KEY_Obarred 0x100019f /* U+019F LATIN CAPITAL LETTER O WITH MIDDLE TILDE */ -#define XKB_KEY_xabovedot 0x1001e8b /* U+1E8B LATIN SMALL LETTER X WITH DOT ABOVE */ -#define XKB_KEY_ibreve 0x100012d /* U+012D LATIN SMALL LETTER I WITH BREVE */ -#define XKB_KEY_zstroke 0x10001b6 /* U+01B6 LATIN SMALL LETTER Z WITH STROKE */ -#define XKB_KEY_gcaron 0x10001e7 /* U+01E7 LATIN SMALL LETTER G WITH CARON */ -#define XKB_KEY_ocaron 0x10001d2 /* U+01D2 LATIN SMALL LETTER O WITH CARON */ -#define XKB_KEY_obarred 0x1000275 /* U+0275 LATIN SMALL LETTER BARRED O */ -#define XKB_KEY_SCHWA 0x100018f /* U+018F LATIN CAPITAL LETTER SCHWA */ -#define XKB_KEY_schwa 0x1000259 /* U+0259 LATIN SMALL LETTER SCHWA */ -#define XKB_KEY_EZH 0x10001b7 /* U+01B7 LATIN CAPITAL LETTER EZH */ -#define XKB_KEY_ezh 0x1000292 /* U+0292 LATIN SMALL LETTER EZH */ -/* those are not really Caucasus */ -/* For Inupiak */ -#define XKB_KEY_Lbelowdot 0x1001e36 /* U+1E36 LATIN CAPITAL LETTER L WITH DOT BELOW */ -#define XKB_KEY_lbelowdot 0x1001e37 /* U+1E37 LATIN SMALL LETTER L WITH DOT BELOW */ - -/* - * Vietnamese - */ - -#define XKB_KEY_Abelowdot 0x1001ea0 /* U+1EA0 LATIN CAPITAL LETTER A WITH DOT BELOW */ -#define XKB_KEY_abelowdot 0x1001ea1 /* U+1EA1 LATIN SMALL LETTER A WITH DOT BELOW */ -#define XKB_KEY_Ahook 0x1001ea2 /* U+1EA2 LATIN CAPITAL LETTER A WITH HOOK ABOVE */ -#define XKB_KEY_ahook 0x1001ea3 /* U+1EA3 LATIN SMALL LETTER A WITH HOOK ABOVE */ -#define XKB_KEY_Acircumflexacute 0x1001ea4 /* U+1EA4 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE */ -#define XKB_KEY_acircumflexacute 0x1001ea5 /* U+1EA5 LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE */ -#define XKB_KEY_Acircumflexgrave 0x1001ea6 /* U+1EA6 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE */ -#define XKB_KEY_acircumflexgrave 0x1001ea7 /* U+1EA7 LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE */ -#define XKB_KEY_Acircumflexhook 0x1001ea8 /* U+1EA8 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */ -#define XKB_KEY_acircumflexhook 0x1001ea9 /* U+1EA9 LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */ -#define XKB_KEY_Acircumflextilde 0x1001eaa /* U+1EAA LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE */ -#define XKB_KEY_acircumflextilde 0x1001eab /* U+1EAB LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE */ -#define XKB_KEY_Acircumflexbelowdot 0x1001eac /* U+1EAC LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW */ -#define XKB_KEY_acircumflexbelowdot 0x1001ead /* U+1EAD LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW */ -#define XKB_KEY_Abreveacute 0x1001eae /* U+1EAE LATIN CAPITAL LETTER A WITH BREVE AND ACUTE */ -#define XKB_KEY_abreveacute 0x1001eaf /* U+1EAF LATIN SMALL LETTER A WITH BREVE AND ACUTE */ -#define XKB_KEY_Abrevegrave 0x1001eb0 /* U+1EB0 LATIN CAPITAL LETTER A WITH BREVE AND GRAVE */ -#define XKB_KEY_abrevegrave 0x1001eb1 /* U+1EB1 LATIN SMALL LETTER A WITH BREVE AND GRAVE */ -#define XKB_KEY_Abrevehook 0x1001eb2 /* U+1EB2 LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE */ -#define XKB_KEY_abrevehook 0x1001eb3 /* U+1EB3 LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE */ -#define XKB_KEY_Abrevetilde 0x1001eb4 /* U+1EB4 LATIN CAPITAL LETTER A WITH BREVE AND TILDE */ -#define XKB_KEY_abrevetilde 0x1001eb5 /* U+1EB5 LATIN SMALL LETTER A WITH BREVE AND TILDE */ -#define XKB_KEY_Abrevebelowdot 0x1001eb6 /* U+1EB6 LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW */ -#define XKB_KEY_abrevebelowdot 0x1001eb7 /* U+1EB7 LATIN SMALL LETTER A WITH BREVE AND DOT BELOW */ -#define XKB_KEY_Ebelowdot 0x1001eb8 /* U+1EB8 LATIN CAPITAL LETTER E WITH DOT BELOW */ -#define XKB_KEY_ebelowdot 0x1001eb9 /* U+1EB9 LATIN SMALL LETTER E WITH DOT BELOW */ -#define XKB_KEY_Ehook 0x1001eba /* U+1EBA LATIN CAPITAL LETTER E WITH HOOK ABOVE */ -#define XKB_KEY_ehook 0x1001ebb /* U+1EBB LATIN SMALL LETTER E WITH HOOK ABOVE */ -#define XKB_KEY_Etilde 0x1001ebc /* U+1EBC LATIN CAPITAL LETTER E WITH TILDE */ -#define XKB_KEY_etilde 0x1001ebd /* U+1EBD LATIN SMALL LETTER E WITH TILDE */ -#define XKB_KEY_Ecircumflexacute 0x1001ebe /* U+1EBE LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE */ -#define XKB_KEY_ecircumflexacute 0x1001ebf /* U+1EBF LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE */ -#define XKB_KEY_Ecircumflexgrave 0x1001ec0 /* U+1EC0 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE */ -#define XKB_KEY_ecircumflexgrave 0x1001ec1 /* U+1EC1 LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE */ -#define XKB_KEY_Ecircumflexhook 0x1001ec2 /* U+1EC2 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */ -#define XKB_KEY_ecircumflexhook 0x1001ec3 /* U+1EC3 LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */ -#define XKB_KEY_Ecircumflextilde 0x1001ec4 /* U+1EC4 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE */ -#define XKB_KEY_ecircumflextilde 0x1001ec5 /* U+1EC5 LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE */ -#define XKB_KEY_Ecircumflexbelowdot 0x1001ec6 /* U+1EC6 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW */ -#define XKB_KEY_ecircumflexbelowdot 0x1001ec7 /* U+1EC7 LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW */ -#define XKB_KEY_Ihook 0x1001ec8 /* U+1EC8 LATIN CAPITAL LETTER I WITH HOOK ABOVE */ -#define XKB_KEY_ihook 0x1001ec9 /* U+1EC9 LATIN SMALL LETTER I WITH HOOK ABOVE */ -#define XKB_KEY_Ibelowdot 0x1001eca /* U+1ECA LATIN CAPITAL LETTER I WITH DOT BELOW */ -#define XKB_KEY_ibelowdot 0x1001ecb /* U+1ECB LATIN SMALL LETTER I WITH DOT BELOW */ -#define XKB_KEY_Obelowdot 0x1001ecc /* U+1ECC LATIN CAPITAL LETTER O WITH DOT BELOW */ -#define XKB_KEY_obelowdot 0x1001ecd /* U+1ECD LATIN SMALL LETTER O WITH DOT BELOW */ -#define XKB_KEY_Ohook 0x1001ece /* U+1ECE LATIN CAPITAL LETTER O WITH HOOK ABOVE */ -#define XKB_KEY_ohook 0x1001ecf /* U+1ECF LATIN SMALL LETTER O WITH HOOK ABOVE */ -#define XKB_KEY_Ocircumflexacute 0x1001ed0 /* U+1ED0 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE */ -#define XKB_KEY_ocircumflexacute 0x1001ed1 /* U+1ED1 LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE */ -#define XKB_KEY_Ocircumflexgrave 0x1001ed2 /* U+1ED2 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE */ -#define XKB_KEY_ocircumflexgrave 0x1001ed3 /* U+1ED3 LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE */ -#define XKB_KEY_Ocircumflexhook 0x1001ed4 /* U+1ED4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */ -#define XKB_KEY_ocircumflexhook 0x1001ed5 /* U+1ED5 LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */ -#define XKB_KEY_Ocircumflextilde 0x1001ed6 /* U+1ED6 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE */ -#define XKB_KEY_ocircumflextilde 0x1001ed7 /* U+1ED7 LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE */ -#define XKB_KEY_Ocircumflexbelowdot 0x1001ed8 /* U+1ED8 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW */ -#define XKB_KEY_ocircumflexbelowdot 0x1001ed9 /* U+1ED9 LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW */ -#define XKB_KEY_Ohornacute 0x1001eda /* U+1EDA LATIN CAPITAL LETTER O WITH HORN AND ACUTE */ -#define XKB_KEY_ohornacute 0x1001edb /* U+1EDB LATIN SMALL LETTER O WITH HORN AND ACUTE */ -#define XKB_KEY_Ohorngrave 0x1001edc /* U+1EDC LATIN CAPITAL LETTER O WITH HORN AND GRAVE */ -#define XKB_KEY_ohorngrave 0x1001edd /* U+1EDD LATIN SMALL LETTER O WITH HORN AND GRAVE */ -#define XKB_KEY_Ohornhook 0x1001ede /* U+1EDE LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE */ -#define XKB_KEY_ohornhook 0x1001edf /* U+1EDF LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE */ -#define XKB_KEY_Ohorntilde 0x1001ee0 /* U+1EE0 LATIN CAPITAL LETTER O WITH HORN AND TILDE */ -#define XKB_KEY_ohorntilde 0x1001ee1 /* U+1EE1 LATIN SMALL LETTER O WITH HORN AND TILDE */ -#define XKB_KEY_Ohornbelowdot 0x1001ee2 /* U+1EE2 LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW */ -#define XKB_KEY_ohornbelowdot 0x1001ee3 /* U+1EE3 LATIN SMALL LETTER O WITH HORN AND DOT BELOW */ -#define XKB_KEY_Ubelowdot 0x1001ee4 /* U+1EE4 LATIN CAPITAL LETTER U WITH DOT BELOW */ -#define XKB_KEY_ubelowdot 0x1001ee5 /* U+1EE5 LATIN SMALL LETTER U WITH DOT BELOW */ -#define XKB_KEY_Uhook 0x1001ee6 /* U+1EE6 LATIN CAPITAL LETTER U WITH HOOK ABOVE */ -#define XKB_KEY_uhook 0x1001ee7 /* U+1EE7 LATIN SMALL LETTER U WITH HOOK ABOVE */ -#define XKB_KEY_Uhornacute 0x1001ee8 /* U+1EE8 LATIN CAPITAL LETTER U WITH HORN AND ACUTE */ -#define XKB_KEY_uhornacute 0x1001ee9 /* U+1EE9 LATIN SMALL LETTER U WITH HORN AND ACUTE */ -#define XKB_KEY_Uhorngrave 0x1001eea /* U+1EEA LATIN CAPITAL LETTER U WITH HORN AND GRAVE */ -#define XKB_KEY_uhorngrave 0x1001eeb /* U+1EEB LATIN SMALL LETTER U WITH HORN AND GRAVE */ -#define XKB_KEY_Uhornhook 0x1001eec /* U+1EEC LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE */ -#define XKB_KEY_uhornhook 0x1001eed /* U+1EED LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE */ -#define XKB_KEY_Uhorntilde 0x1001eee /* U+1EEE LATIN CAPITAL LETTER U WITH HORN AND TILDE */ -#define XKB_KEY_uhorntilde 0x1001eef /* U+1EEF LATIN SMALL LETTER U WITH HORN AND TILDE */ -#define XKB_KEY_Uhornbelowdot 0x1001ef0 /* U+1EF0 LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW */ -#define XKB_KEY_uhornbelowdot 0x1001ef1 /* U+1EF1 LATIN SMALL LETTER U WITH HORN AND DOT BELOW */ -#define XKB_KEY_Ybelowdot 0x1001ef4 /* U+1EF4 LATIN CAPITAL LETTER Y WITH DOT BELOW */ -#define XKB_KEY_ybelowdot 0x1001ef5 /* U+1EF5 LATIN SMALL LETTER Y WITH DOT BELOW */ -#define XKB_KEY_Yhook 0x1001ef6 /* U+1EF6 LATIN CAPITAL LETTER Y WITH HOOK ABOVE */ -#define XKB_KEY_yhook 0x1001ef7 /* U+1EF7 LATIN SMALL LETTER Y WITH HOOK ABOVE */ -#define XKB_KEY_Ytilde 0x1001ef8 /* U+1EF8 LATIN CAPITAL LETTER Y WITH TILDE */ -#define XKB_KEY_ytilde 0x1001ef9 /* U+1EF9 LATIN SMALL LETTER Y WITH TILDE */ -#define XKB_KEY_Ohorn 0x10001a0 /* U+01A0 LATIN CAPITAL LETTER O WITH HORN */ -#define XKB_KEY_ohorn 0x10001a1 /* U+01A1 LATIN SMALL LETTER O WITH HORN */ -#define XKB_KEY_Uhorn 0x10001af /* U+01AF LATIN CAPITAL LETTER U WITH HORN */ -#define XKB_KEY_uhorn 0x10001b0 /* U+01B0 LATIN SMALL LETTER U WITH HORN */ - - -#define XKB_KEY_EcuSign 0x10020a0 /* U+20A0 EURO-CURRENCY SIGN */ -#define XKB_KEY_ColonSign 0x10020a1 /* U+20A1 COLON SIGN */ -#define XKB_KEY_CruzeiroSign 0x10020a2 /* U+20A2 CRUZEIRO SIGN */ -#define XKB_KEY_FFrancSign 0x10020a3 /* U+20A3 FRENCH FRANC SIGN */ -#define XKB_KEY_LiraSign 0x10020a4 /* U+20A4 LIRA SIGN */ -#define XKB_KEY_MillSign 0x10020a5 /* U+20A5 MILL SIGN */ -#define XKB_KEY_NairaSign 0x10020a6 /* U+20A6 NAIRA SIGN */ -#define XKB_KEY_PesetaSign 0x10020a7 /* U+20A7 PESETA SIGN */ -#define XKB_KEY_RupeeSign 0x10020a8 /* U+20A8 RUPEE SIGN */ -#define XKB_KEY_WonSign 0x10020a9 /* U+20A9 WON SIGN */ -#define XKB_KEY_NewSheqelSign 0x10020aa /* U+20AA NEW SHEQEL SIGN */ -#define XKB_KEY_DongSign 0x10020ab /* U+20AB DONG SIGN */ -#define XKB_KEY_EuroSign 0x20ac /* U+20AC EURO SIGN */ - -/* one, two and three are defined above. */ -#define XKB_KEY_zerosuperior 0x1002070 /* U+2070 SUPERSCRIPT ZERO */ -#define XKB_KEY_foursuperior 0x1002074 /* U+2074 SUPERSCRIPT FOUR */ -#define XKB_KEY_fivesuperior 0x1002075 /* U+2075 SUPERSCRIPT FIVE */ -#define XKB_KEY_sixsuperior 0x1002076 /* U+2076 SUPERSCRIPT SIX */ -#define XKB_KEY_sevensuperior 0x1002077 /* U+2077 SUPERSCRIPT SEVEN */ -#define XKB_KEY_eightsuperior 0x1002078 /* U+2078 SUPERSCRIPT EIGHT */ -#define XKB_KEY_ninesuperior 0x1002079 /* U+2079 SUPERSCRIPT NINE */ -#define XKB_KEY_zerosubscript 0x1002080 /* U+2080 SUBSCRIPT ZERO */ -#define XKB_KEY_onesubscript 0x1002081 /* U+2081 SUBSCRIPT ONE */ -#define XKB_KEY_twosubscript 0x1002082 /* U+2082 SUBSCRIPT TWO */ -#define XKB_KEY_threesubscript 0x1002083 /* U+2083 SUBSCRIPT THREE */ -#define XKB_KEY_foursubscript 0x1002084 /* U+2084 SUBSCRIPT FOUR */ -#define XKB_KEY_fivesubscript 0x1002085 /* U+2085 SUBSCRIPT FIVE */ -#define XKB_KEY_sixsubscript 0x1002086 /* U+2086 SUBSCRIPT SIX */ -#define XKB_KEY_sevensubscript 0x1002087 /* U+2087 SUBSCRIPT SEVEN */ -#define XKB_KEY_eightsubscript 0x1002088 /* U+2088 SUBSCRIPT EIGHT */ -#define XKB_KEY_ninesubscript 0x1002089 /* U+2089 SUBSCRIPT NINE */ -#define XKB_KEY_partdifferential 0x1002202 /* U+2202 PARTIAL DIFFERENTIAL */ -#define XKB_KEY_emptyset 0x1002205 /* U+2205 NULL SET */ -#define XKB_KEY_elementof 0x1002208 /* U+2208 ELEMENT OF */ -#define XKB_KEY_notelementof 0x1002209 /* U+2209 NOT AN ELEMENT OF */ -#define XKB_KEY_containsas 0x100220B /* U+220B CONTAINS AS MEMBER */ -#define XKB_KEY_squareroot 0x100221A /* U+221A SQUARE ROOT */ -#define XKB_KEY_cuberoot 0x100221B /* U+221B CUBE ROOT */ -#define XKB_KEY_fourthroot 0x100221C /* U+221C FOURTH ROOT */ -#define XKB_KEY_dintegral 0x100222C /* U+222C DOUBLE INTEGRAL */ -#define XKB_KEY_tintegral 0x100222D /* U+222D TRIPLE INTEGRAL */ -#define XKB_KEY_because 0x1002235 /* U+2235 BECAUSE */ -#define XKB_KEY_approxeq 0x1002248 /* U+2245 ALMOST EQUAL TO */ -#define XKB_KEY_notapproxeq 0x1002247 /* U+2247 NOT ALMOST EQUAL TO */ -#define XKB_KEY_notidentical 0x1002262 /* U+2262 NOT IDENTICAL TO */ -#define XKB_KEY_stricteq 0x1002263 /* U+2263 STRICTLY EQUIVALENT TO */ - -#define XKB_KEY_braille_dot_1 0xfff1 -#define XKB_KEY_braille_dot_2 0xfff2 -#define XKB_KEY_braille_dot_3 0xfff3 -#define XKB_KEY_braille_dot_4 0xfff4 -#define XKB_KEY_braille_dot_5 0xfff5 -#define XKB_KEY_braille_dot_6 0xfff6 -#define XKB_KEY_braille_dot_7 0xfff7 -#define XKB_KEY_braille_dot_8 0xfff8 -#define XKB_KEY_braille_dot_9 0xfff9 -#define XKB_KEY_braille_dot_10 0xfffa -#define XKB_KEY_braille_blank 0x1002800 /* U+2800 BRAILLE PATTERN BLANK */ -#define XKB_KEY_braille_dots_1 0x1002801 /* U+2801 BRAILLE PATTERN DOTS-1 */ -#define XKB_KEY_braille_dots_2 0x1002802 /* U+2802 BRAILLE PATTERN DOTS-2 */ -#define XKB_KEY_braille_dots_12 0x1002803 /* U+2803 BRAILLE PATTERN DOTS-12 */ -#define XKB_KEY_braille_dots_3 0x1002804 /* U+2804 BRAILLE PATTERN DOTS-3 */ -#define XKB_KEY_braille_dots_13 0x1002805 /* U+2805 BRAILLE PATTERN DOTS-13 */ -#define XKB_KEY_braille_dots_23 0x1002806 /* U+2806 BRAILLE PATTERN DOTS-23 */ -#define XKB_KEY_braille_dots_123 0x1002807 /* U+2807 BRAILLE PATTERN DOTS-123 */ -#define XKB_KEY_braille_dots_4 0x1002808 /* U+2808 BRAILLE PATTERN DOTS-4 */ -#define XKB_KEY_braille_dots_14 0x1002809 /* U+2809 BRAILLE PATTERN DOTS-14 */ -#define XKB_KEY_braille_dots_24 0x100280a /* U+280a BRAILLE PATTERN DOTS-24 */ -#define XKB_KEY_braille_dots_124 0x100280b /* U+280b BRAILLE PATTERN DOTS-124 */ -#define XKB_KEY_braille_dots_34 0x100280c /* U+280c BRAILLE PATTERN DOTS-34 */ -#define XKB_KEY_braille_dots_134 0x100280d /* U+280d BRAILLE PATTERN DOTS-134 */ -#define XKB_KEY_braille_dots_234 0x100280e /* U+280e BRAILLE PATTERN DOTS-234 */ -#define XKB_KEY_braille_dots_1234 0x100280f /* U+280f BRAILLE PATTERN DOTS-1234 */ -#define XKB_KEY_braille_dots_5 0x1002810 /* U+2810 BRAILLE PATTERN DOTS-5 */ -#define XKB_KEY_braille_dots_15 0x1002811 /* U+2811 BRAILLE PATTERN DOTS-15 */ -#define XKB_KEY_braille_dots_25 0x1002812 /* U+2812 BRAILLE PATTERN DOTS-25 */ -#define XKB_KEY_braille_dots_125 0x1002813 /* U+2813 BRAILLE PATTERN DOTS-125 */ -#define XKB_KEY_braille_dots_35 0x1002814 /* U+2814 BRAILLE PATTERN DOTS-35 */ -#define XKB_KEY_braille_dots_135 0x1002815 /* U+2815 BRAILLE PATTERN DOTS-135 */ -#define XKB_KEY_braille_dots_235 0x1002816 /* U+2816 BRAILLE PATTERN DOTS-235 */ -#define XKB_KEY_braille_dots_1235 0x1002817 /* U+2817 BRAILLE PATTERN DOTS-1235 */ -#define XKB_KEY_braille_dots_45 0x1002818 /* U+2818 BRAILLE PATTERN DOTS-45 */ -#define XKB_KEY_braille_dots_145 0x1002819 /* U+2819 BRAILLE PATTERN DOTS-145 */ -#define XKB_KEY_braille_dots_245 0x100281a /* U+281a BRAILLE PATTERN DOTS-245 */ -#define XKB_KEY_braille_dots_1245 0x100281b /* U+281b BRAILLE PATTERN DOTS-1245 */ -#define XKB_KEY_braille_dots_345 0x100281c /* U+281c BRAILLE PATTERN DOTS-345 */ -#define XKB_KEY_braille_dots_1345 0x100281d /* U+281d BRAILLE PATTERN DOTS-1345 */ -#define XKB_KEY_braille_dots_2345 0x100281e /* U+281e BRAILLE PATTERN DOTS-2345 */ -#define XKB_KEY_braille_dots_12345 0x100281f /* U+281f BRAILLE PATTERN DOTS-12345 */ -#define XKB_KEY_braille_dots_6 0x1002820 /* U+2820 BRAILLE PATTERN DOTS-6 */ -#define XKB_KEY_braille_dots_16 0x1002821 /* U+2821 BRAILLE PATTERN DOTS-16 */ -#define XKB_KEY_braille_dots_26 0x1002822 /* U+2822 BRAILLE PATTERN DOTS-26 */ -#define XKB_KEY_braille_dots_126 0x1002823 /* U+2823 BRAILLE PATTERN DOTS-126 */ -#define XKB_KEY_braille_dots_36 0x1002824 /* U+2824 BRAILLE PATTERN DOTS-36 */ -#define XKB_KEY_braille_dots_136 0x1002825 /* U+2825 BRAILLE PATTERN DOTS-136 */ -#define XKB_KEY_braille_dots_236 0x1002826 /* U+2826 BRAILLE PATTERN DOTS-236 */ -#define XKB_KEY_braille_dots_1236 0x1002827 /* U+2827 BRAILLE PATTERN DOTS-1236 */ -#define XKB_KEY_braille_dots_46 0x1002828 /* U+2828 BRAILLE PATTERN DOTS-46 */ -#define XKB_KEY_braille_dots_146 0x1002829 /* U+2829 BRAILLE PATTERN DOTS-146 */ -#define XKB_KEY_braille_dots_246 0x100282a /* U+282a BRAILLE PATTERN DOTS-246 */ -#define XKB_KEY_braille_dots_1246 0x100282b /* U+282b BRAILLE PATTERN DOTS-1246 */ -#define XKB_KEY_braille_dots_346 0x100282c /* U+282c BRAILLE PATTERN DOTS-346 */ -#define XKB_KEY_braille_dots_1346 0x100282d /* U+282d BRAILLE PATTERN DOTS-1346 */ -#define XKB_KEY_braille_dots_2346 0x100282e /* U+282e BRAILLE PATTERN DOTS-2346 */ -#define XKB_KEY_braille_dots_12346 0x100282f /* U+282f BRAILLE PATTERN DOTS-12346 */ -#define XKB_KEY_braille_dots_56 0x1002830 /* U+2830 BRAILLE PATTERN DOTS-56 */ -#define XKB_KEY_braille_dots_156 0x1002831 /* U+2831 BRAILLE PATTERN DOTS-156 */ -#define XKB_KEY_braille_dots_256 0x1002832 /* U+2832 BRAILLE PATTERN DOTS-256 */ -#define XKB_KEY_braille_dots_1256 0x1002833 /* U+2833 BRAILLE PATTERN DOTS-1256 */ -#define XKB_KEY_braille_dots_356 0x1002834 /* U+2834 BRAILLE PATTERN DOTS-356 */ -#define XKB_KEY_braille_dots_1356 0x1002835 /* U+2835 BRAILLE PATTERN DOTS-1356 */ -#define XKB_KEY_braille_dots_2356 0x1002836 /* U+2836 BRAILLE PATTERN DOTS-2356 */ -#define XKB_KEY_braille_dots_12356 0x1002837 /* U+2837 BRAILLE PATTERN DOTS-12356 */ -#define XKB_KEY_braille_dots_456 0x1002838 /* U+2838 BRAILLE PATTERN DOTS-456 */ -#define XKB_KEY_braille_dots_1456 0x1002839 /* U+2839 BRAILLE PATTERN DOTS-1456 */ -#define XKB_KEY_braille_dots_2456 0x100283a /* U+283a BRAILLE PATTERN DOTS-2456 */ -#define XKB_KEY_braille_dots_12456 0x100283b /* U+283b BRAILLE PATTERN DOTS-12456 */ -#define XKB_KEY_braille_dots_3456 0x100283c /* U+283c BRAILLE PATTERN DOTS-3456 */ -#define XKB_KEY_braille_dots_13456 0x100283d /* U+283d BRAILLE PATTERN DOTS-13456 */ -#define XKB_KEY_braille_dots_23456 0x100283e /* U+283e BRAILLE PATTERN DOTS-23456 */ -#define XKB_KEY_braille_dots_123456 0x100283f /* U+283f BRAILLE PATTERN DOTS-123456 */ -#define XKB_KEY_braille_dots_7 0x1002840 /* U+2840 BRAILLE PATTERN DOTS-7 */ -#define XKB_KEY_braille_dots_17 0x1002841 /* U+2841 BRAILLE PATTERN DOTS-17 */ -#define XKB_KEY_braille_dots_27 0x1002842 /* U+2842 BRAILLE PATTERN DOTS-27 */ -#define XKB_KEY_braille_dots_127 0x1002843 /* U+2843 BRAILLE PATTERN DOTS-127 */ -#define XKB_KEY_braille_dots_37 0x1002844 /* U+2844 BRAILLE PATTERN DOTS-37 */ -#define XKB_KEY_braille_dots_137 0x1002845 /* U+2845 BRAILLE PATTERN DOTS-137 */ -#define XKB_KEY_braille_dots_237 0x1002846 /* U+2846 BRAILLE PATTERN DOTS-237 */ -#define XKB_KEY_braille_dots_1237 0x1002847 /* U+2847 BRAILLE PATTERN DOTS-1237 */ -#define XKB_KEY_braille_dots_47 0x1002848 /* U+2848 BRAILLE PATTERN DOTS-47 */ -#define XKB_KEY_braille_dots_147 0x1002849 /* U+2849 BRAILLE PATTERN DOTS-147 */ -#define XKB_KEY_braille_dots_247 0x100284a /* U+284a BRAILLE PATTERN DOTS-247 */ -#define XKB_KEY_braille_dots_1247 0x100284b /* U+284b BRAILLE PATTERN DOTS-1247 */ -#define XKB_KEY_braille_dots_347 0x100284c /* U+284c BRAILLE PATTERN DOTS-347 */ -#define XKB_KEY_braille_dots_1347 0x100284d /* U+284d BRAILLE PATTERN DOTS-1347 */ -#define XKB_KEY_braille_dots_2347 0x100284e /* U+284e BRAILLE PATTERN DOTS-2347 */ -#define XKB_KEY_braille_dots_12347 0x100284f /* U+284f BRAILLE PATTERN DOTS-12347 */ -#define XKB_KEY_braille_dots_57 0x1002850 /* U+2850 BRAILLE PATTERN DOTS-57 */ -#define XKB_KEY_braille_dots_157 0x1002851 /* U+2851 BRAILLE PATTERN DOTS-157 */ -#define XKB_KEY_braille_dots_257 0x1002852 /* U+2852 BRAILLE PATTERN DOTS-257 */ -#define XKB_KEY_braille_dots_1257 0x1002853 /* U+2853 BRAILLE PATTERN DOTS-1257 */ -#define XKB_KEY_braille_dots_357 0x1002854 /* U+2854 BRAILLE PATTERN DOTS-357 */ -#define XKB_KEY_braille_dots_1357 0x1002855 /* U+2855 BRAILLE PATTERN DOTS-1357 */ -#define XKB_KEY_braille_dots_2357 0x1002856 /* U+2856 BRAILLE PATTERN DOTS-2357 */ -#define XKB_KEY_braille_dots_12357 0x1002857 /* U+2857 BRAILLE PATTERN DOTS-12357 */ -#define XKB_KEY_braille_dots_457 0x1002858 /* U+2858 BRAILLE PATTERN DOTS-457 */ -#define XKB_KEY_braille_dots_1457 0x1002859 /* U+2859 BRAILLE PATTERN DOTS-1457 */ -#define XKB_KEY_braille_dots_2457 0x100285a /* U+285a BRAILLE PATTERN DOTS-2457 */ -#define XKB_KEY_braille_dots_12457 0x100285b /* U+285b BRAILLE PATTERN DOTS-12457 */ -#define XKB_KEY_braille_dots_3457 0x100285c /* U+285c BRAILLE PATTERN DOTS-3457 */ -#define XKB_KEY_braille_dots_13457 0x100285d /* U+285d BRAILLE PATTERN DOTS-13457 */ -#define XKB_KEY_braille_dots_23457 0x100285e /* U+285e BRAILLE PATTERN DOTS-23457 */ -#define XKB_KEY_braille_dots_123457 0x100285f /* U+285f BRAILLE PATTERN DOTS-123457 */ -#define XKB_KEY_braille_dots_67 0x1002860 /* U+2860 BRAILLE PATTERN DOTS-67 */ -#define XKB_KEY_braille_dots_167 0x1002861 /* U+2861 BRAILLE PATTERN DOTS-167 */ -#define XKB_KEY_braille_dots_267 0x1002862 /* U+2862 BRAILLE PATTERN DOTS-267 */ -#define XKB_KEY_braille_dots_1267 0x1002863 /* U+2863 BRAILLE PATTERN DOTS-1267 */ -#define XKB_KEY_braille_dots_367 0x1002864 /* U+2864 BRAILLE PATTERN DOTS-367 */ -#define XKB_KEY_braille_dots_1367 0x1002865 /* U+2865 BRAILLE PATTERN DOTS-1367 */ -#define XKB_KEY_braille_dots_2367 0x1002866 /* U+2866 BRAILLE PATTERN DOTS-2367 */ -#define XKB_KEY_braille_dots_12367 0x1002867 /* U+2867 BRAILLE PATTERN DOTS-12367 */ -#define XKB_KEY_braille_dots_467 0x1002868 /* U+2868 BRAILLE PATTERN DOTS-467 */ -#define XKB_KEY_braille_dots_1467 0x1002869 /* U+2869 BRAILLE PATTERN DOTS-1467 */ -#define XKB_KEY_braille_dots_2467 0x100286a /* U+286a BRAILLE PATTERN DOTS-2467 */ -#define XKB_KEY_braille_dots_12467 0x100286b /* U+286b BRAILLE PATTERN DOTS-12467 */ -#define XKB_KEY_braille_dots_3467 0x100286c /* U+286c BRAILLE PATTERN DOTS-3467 */ -#define XKB_KEY_braille_dots_13467 0x100286d /* U+286d BRAILLE PATTERN DOTS-13467 */ -#define XKB_KEY_braille_dots_23467 0x100286e /* U+286e BRAILLE PATTERN DOTS-23467 */ -#define XKB_KEY_braille_dots_123467 0x100286f /* U+286f BRAILLE PATTERN DOTS-123467 */ -#define XKB_KEY_braille_dots_567 0x1002870 /* U+2870 BRAILLE PATTERN DOTS-567 */ -#define XKB_KEY_braille_dots_1567 0x1002871 /* U+2871 BRAILLE PATTERN DOTS-1567 */ -#define XKB_KEY_braille_dots_2567 0x1002872 /* U+2872 BRAILLE PATTERN DOTS-2567 */ -#define XKB_KEY_braille_dots_12567 0x1002873 /* U+2873 BRAILLE PATTERN DOTS-12567 */ -#define XKB_KEY_braille_dots_3567 0x1002874 /* U+2874 BRAILLE PATTERN DOTS-3567 */ -#define XKB_KEY_braille_dots_13567 0x1002875 /* U+2875 BRAILLE PATTERN DOTS-13567 */ -#define XKB_KEY_braille_dots_23567 0x1002876 /* U+2876 BRAILLE PATTERN DOTS-23567 */ -#define XKB_KEY_braille_dots_123567 0x1002877 /* U+2877 BRAILLE PATTERN DOTS-123567 */ -#define XKB_KEY_braille_dots_4567 0x1002878 /* U+2878 BRAILLE PATTERN DOTS-4567 */ -#define XKB_KEY_braille_dots_14567 0x1002879 /* U+2879 BRAILLE PATTERN DOTS-14567 */ -#define XKB_KEY_braille_dots_24567 0x100287a /* U+287a BRAILLE PATTERN DOTS-24567 */ -#define XKB_KEY_braille_dots_124567 0x100287b /* U+287b BRAILLE PATTERN DOTS-124567 */ -#define XKB_KEY_braille_dots_34567 0x100287c /* U+287c BRAILLE PATTERN DOTS-34567 */ -#define XKB_KEY_braille_dots_134567 0x100287d /* U+287d BRAILLE PATTERN DOTS-134567 */ -#define XKB_KEY_braille_dots_234567 0x100287e /* U+287e BRAILLE PATTERN DOTS-234567 */ -#define XKB_KEY_braille_dots_1234567 0x100287f /* U+287f BRAILLE PATTERN DOTS-1234567 */ -#define XKB_KEY_braille_dots_8 0x1002880 /* U+2880 BRAILLE PATTERN DOTS-8 */ -#define XKB_KEY_braille_dots_18 0x1002881 /* U+2881 BRAILLE PATTERN DOTS-18 */ -#define XKB_KEY_braille_dots_28 0x1002882 /* U+2882 BRAILLE PATTERN DOTS-28 */ -#define XKB_KEY_braille_dots_128 0x1002883 /* U+2883 BRAILLE PATTERN DOTS-128 */ -#define XKB_KEY_braille_dots_38 0x1002884 /* U+2884 BRAILLE PATTERN DOTS-38 */ -#define XKB_KEY_braille_dots_138 0x1002885 /* U+2885 BRAILLE PATTERN DOTS-138 */ -#define XKB_KEY_braille_dots_238 0x1002886 /* U+2886 BRAILLE PATTERN DOTS-238 */ -#define XKB_KEY_braille_dots_1238 0x1002887 /* U+2887 BRAILLE PATTERN DOTS-1238 */ -#define XKB_KEY_braille_dots_48 0x1002888 /* U+2888 BRAILLE PATTERN DOTS-48 */ -#define XKB_KEY_braille_dots_148 0x1002889 /* U+2889 BRAILLE PATTERN DOTS-148 */ -#define XKB_KEY_braille_dots_248 0x100288a /* U+288a BRAILLE PATTERN DOTS-248 */ -#define XKB_KEY_braille_dots_1248 0x100288b /* U+288b BRAILLE PATTERN DOTS-1248 */ -#define XKB_KEY_braille_dots_348 0x100288c /* U+288c BRAILLE PATTERN DOTS-348 */ -#define XKB_KEY_braille_dots_1348 0x100288d /* U+288d BRAILLE PATTERN DOTS-1348 */ -#define XKB_KEY_braille_dots_2348 0x100288e /* U+288e BRAILLE PATTERN DOTS-2348 */ -#define XKB_KEY_braille_dots_12348 0x100288f /* U+288f BRAILLE PATTERN DOTS-12348 */ -#define XKB_KEY_braille_dots_58 0x1002890 /* U+2890 BRAILLE PATTERN DOTS-58 */ -#define XKB_KEY_braille_dots_158 0x1002891 /* U+2891 BRAILLE PATTERN DOTS-158 */ -#define XKB_KEY_braille_dots_258 0x1002892 /* U+2892 BRAILLE PATTERN DOTS-258 */ -#define XKB_KEY_braille_dots_1258 0x1002893 /* U+2893 BRAILLE PATTERN DOTS-1258 */ -#define XKB_KEY_braille_dots_358 0x1002894 /* U+2894 BRAILLE PATTERN DOTS-358 */ -#define XKB_KEY_braille_dots_1358 0x1002895 /* U+2895 BRAILLE PATTERN DOTS-1358 */ -#define XKB_KEY_braille_dots_2358 0x1002896 /* U+2896 BRAILLE PATTERN DOTS-2358 */ -#define XKB_KEY_braille_dots_12358 0x1002897 /* U+2897 BRAILLE PATTERN DOTS-12358 */ -#define XKB_KEY_braille_dots_458 0x1002898 /* U+2898 BRAILLE PATTERN DOTS-458 */ -#define XKB_KEY_braille_dots_1458 0x1002899 /* U+2899 BRAILLE PATTERN DOTS-1458 */ -#define XKB_KEY_braille_dots_2458 0x100289a /* U+289a BRAILLE PATTERN DOTS-2458 */ -#define XKB_KEY_braille_dots_12458 0x100289b /* U+289b BRAILLE PATTERN DOTS-12458 */ -#define XKB_KEY_braille_dots_3458 0x100289c /* U+289c BRAILLE PATTERN DOTS-3458 */ -#define XKB_KEY_braille_dots_13458 0x100289d /* U+289d BRAILLE PATTERN DOTS-13458 */ -#define XKB_KEY_braille_dots_23458 0x100289e /* U+289e BRAILLE PATTERN DOTS-23458 */ -#define XKB_KEY_braille_dots_123458 0x100289f /* U+289f BRAILLE PATTERN DOTS-123458 */ -#define XKB_KEY_braille_dots_68 0x10028a0 /* U+28a0 BRAILLE PATTERN DOTS-68 */ -#define XKB_KEY_braille_dots_168 0x10028a1 /* U+28a1 BRAILLE PATTERN DOTS-168 */ -#define XKB_KEY_braille_dots_268 0x10028a2 /* U+28a2 BRAILLE PATTERN DOTS-268 */ -#define XKB_KEY_braille_dots_1268 0x10028a3 /* U+28a3 BRAILLE PATTERN DOTS-1268 */ -#define XKB_KEY_braille_dots_368 0x10028a4 /* U+28a4 BRAILLE PATTERN DOTS-368 */ -#define XKB_KEY_braille_dots_1368 0x10028a5 /* U+28a5 BRAILLE PATTERN DOTS-1368 */ -#define XKB_KEY_braille_dots_2368 0x10028a6 /* U+28a6 BRAILLE PATTERN DOTS-2368 */ -#define XKB_KEY_braille_dots_12368 0x10028a7 /* U+28a7 BRAILLE PATTERN DOTS-12368 */ -#define XKB_KEY_braille_dots_468 0x10028a8 /* U+28a8 BRAILLE PATTERN DOTS-468 */ -#define XKB_KEY_braille_dots_1468 0x10028a9 /* U+28a9 BRAILLE PATTERN DOTS-1468 */ -#define XKB_KEY_braille_dots_2468 0x10028aa /* U+28aa BRAILLE PATTERN DOTS-2468 */ -#define XKB_KEY_braille_dots_12468 0x10028ab /* U+28ab BRAILLE PATTERN DOTS-12468 */ -#define XKB_KEY_braille_dots_3468 0x10028ac /* U+28ac BRAILLE PATTERN DOTS-3468 */ -#define XKB_KEY_braille_dots_13468 0x10028ad /* U+28ad BRAILLE PATTERN DOTS-13468 */ -#define XKB_KEY_braille_dots_23468 0x10028ae /* U+28ae BRAILLE PATTERN DOTS-23468 */ -#define XKB_KEY_braille_dots_123468 0x10028af /* U+28af BRAILLE PATTERN DOTS-123468 */ -#define XKB_KEY_braille_dots_568 0x10028b0 /* U+28b0 BRAILLE PATTERN DOTS-568 */ -#define XKB_KEY_braille_dots_1568 0x10028b1 /* U+28b1 BRAILLE PATTERN DOTS-1568 */ -#define XKB_KEY_braille_dots_2568 0x10028b2 /* U+28b2 BRAILLE PATTERN DOTS-2568 */ -#define XKB_KEY_braille_dots_12568 0x10028b3 /* U+28b3 BRAILLE PATTERN DOTS-12568 */ -#define XKB_KEY_braille_dots_3568 0x10028b4 /* U+28b4 BRAILLE PATTERN DOTS-3568 */ -#define XKB_KEY_braille_dots_13568 0x10028b5 /* U+28b5 BRAILLE PATTERN DOTS-13568 */ -#define XKB_KEY_braille_dots_23568 0x10028b6 /* U+28b6 BRAILLE PATTERN DOTS-23568 */ -#define XKB_KEY_braille_dots_123568 0x10028b7 /* U+28b7 BRAILLE PATTERN DOTS-123568 */ -#define XKB_KEY_braille_dots_4568 0x10028b8 /* U+28b8 BRAILLE PATTERN DOTS-4568 */ -#define XKB_KEY_braille_dots_14568 0x10028b9 /* U+28b9 BRAILLE PATTERN DOTS-14568 */ -#define XKB_KEY_braille_dots_24568 0x10028ba /* U+28ba BRAILLE PATTERN DOTS-24568 */ -#define XKB_KEY_braille_dots_124568 0x10028bb /* U+28bb BRAILLE PATTERN DOTS-124568 */ -#define XKB_KEY_braille_dots_34568 0x10028bc /* U+28bc BRAILLE PATTERN DOTS-34568 */ -#define XKB_KEY_braille_dots_134568 0x10028bd /* U+28bd BRAILLE PATTERN DOTS-134568 */ -#define XKB_KEY_braille_dots_234568 0x10028be /* U+28be BRAILLE PATTERN DOTS-234568 */ -#define XKB_KEY_braille_dots_1234568 0x10028bf /* U+28bf BRAILLE PATTERN DOTS-1234568 */ -#define XKB_KEY_braille_dots_78 0x10028c0 /* U+28c0 BRAILLE PATTERN DOTS-78 */ -#define XKB_KEY_braille_dots_178 0x10028c1 /* U+28c1 BRAILLE PATTERN DOTS-178 */ -#define XKB_KEY_braille_dots_278 0x10028c2 /* U+28c2 BRAILLE PATTERN DOTS-278 */ -#define XKB_KEY_braille_dots_1278 0x10028c3 /* U+28c3 BRAILLE PATTERN DOTS-1278 */ -#define XKB_KEY_braille_dots_378 0x10028c4 /* U+28c4 BRAILLE PATTERN DOTS-378 */ -#define XKB_KEY_braille_dots_1378 0x10028c5 /* U+28c5 BRAILLE PATTERN DOTS-1378 */ -#define XKB_KEY_braille_dots_2378 0x10028c6 /* U+28c6 BRAILLE PATTERN DOTS-2378 */ -#define XKB_KEY_braille_dots_12378 0x10028c7 /* U+28c7 BRAILLE PATTERN DOTS-12378 */ -#define XKB_KEY_braille_dots_478 0x10028c8 /* U+28c8 BRAILLE PATTERN DOTS-478 */ -#define XKB_KEY_braille_dots_1478 0x10028c9 /* U+28c9 BRAILLE PATTERN DOTS-1478 */ -#define XKB_KEY_braille_dots_2478 0x10028ca /* U+28ca BRAILLE PATTERN DOTS-2478 */ -#define XKB_KEY_braille_dots_12478 0x10028cb /* U+28cb BRAILLE PATTERN DOTS-12478 */ -#define XKB_KEY_braille_dots_3478 0x10028cc /* U+28cc BRAILLE PATTERN DOTS-3478 */ -#define XKB_KEY_braille_dots_13478 0x10028cd /* U+28cd BRAILLE PATTERN DOTS-13478 */ -#define XKB_KEY_braille_dots_23478 0x10028ce /* U+28ce BRAILLE PATTERN DOTS-23478 */ -#define XKB_KEY_braille_dots_123478 0x10028cf /* U+28cf BRAILLE PATTERN DOTS-123478 */ -#define XKB_KEY_braille_dots_578 0x10028d0 /* U+28d0 BRAILLE PATTERN DOTS-578 */ -#define XKB_KEY_braille_dots_1578 0x10028d1 /* U+28d1 BRAILLE PATTERN DOTS-1578 */ -#define XKB_KEY_braille_dots_2578 0x10028d2 /* U+28d2 BRAILLE PATTERN DOTS-2578 */ -#define XKB_KEY_braille_dots_12578 0x10028d3 /* U+28d3 BRAILLE PATTERN DOTS-12578 */ -#define XKB_KEY_braille_dots_3578 0x10028d4 /* U+28d4 BRAILLE PATTERN DOTS-3578 */ -#define XKB_KEY_braille_dots_13578 0x10028d5 /* U+28d5 BRAILLE PATTERN DOTS-13578 */ -#define XKB_KEY_braille_dots_23578 0x10028d6 /* U+28d6 BRAILLE PATTERN DOTS-23578 */ -#define XKB_KEY_braille_dots_123578 0x10028d7 /* U+28d7 BRAILLE PATTERN DOTS-123578 */ -#define XKB_KEY_braille_dots_4578 0x10028d8 /* U+28d8 BRAILLE PATTERN DOTS-4578 */ -#define XKB_KEY_braille_dots_14578 0x10028d9 /* U+28d9 BRAILLE PATTERN DOTS-14578 */ -#define XKB_KEY_braille_dots_24578 0x10028da /* U+28da BRAILLE PATTERN DOTS-24578 */ -#define XKB_KEY_braille_dots_124578 0x10028db /* U+28db BRAILLE PATTERN DOTS-124578 */ -#define XKB_KEY_braille_dots_34578 0x10028dc /* U+28dc BRAILLE PATTERN DOTS-34578 */ -#define XKB_KEY_braille_dots_134578 0x10028dd /* U+28dd BRAILLE PATTERN DOTS-134578 */ -#define XKB_KEY_braille_dots_234578 0x10028de /* U+28de BRAILLE PATTERN DOTS-234578 */ -#define XKB_KEY_braille_dots_1234578 0x10028df /* U+28df BRAILLE PATTERN DOTS-1234578 */ -#define XKB_KEY_braille_dots_678 0x10028e0 /* U+28e0 BRAILLE PATTERN DOTS-678 */ -#define XKB_KEY_braille_dots_1678 0x10028e1 /* U+28e1 BRAILLE PATTERN DOTS-1678 */ -#define XKB_KEY_braille_dots_2678 0x10028e2 /* U+28e2 BRAILLE PATTERN DOTS-2678 */ -#define XKB_KEY_braille_dots_12678 0x10028e3 /* U+28e3 BRAILLE PATTERN DOTS-12678 */ -#define XKB_KEY_braille_dots_3678 0x10028e4 /* U+28e4 BRAILLE PATTERN DOTS-3678 */ -#define XKB_KEY_braille_dots_13678 0x10028e5 /* U+28e5 BRAILLE PATTERN DOTS-13678 */ -#define XKB_KEY_braille_dots_23678 0x10028e6 /* U+28e6 BRAILLE PATTERN DOTS-23678 */ -#define XKB_KEY_braille_dots_123678 0x10028e7 /* U+28e7 BRAILLE PATTERN DOTS-123678 */ -#define XKB_KEY_braille_dots_4678 0x10028e8 /* U+28e8 BRAILLE PATTERN DOTS-4678 */ -#define XKB_KEY_braille_dots_14678 0x10028e9 /* U+28e9 BRAILLE PATTERN DOTS-14678 */ -#define XKB_KEY_braille_dots_24678 0x10028ea /* U+28ea BRAILLE PATTERN DOTS-24678 */ -#define XKB_KEY_braille_dots_124678 0x10028eb /* U+28eb BRAILLE PATTERN DOTS-124678 */ -#define XKB_KEY_braille_dots_34678 0x10028ec /* U+28ec BRAILLE PATTERN DOTS-34678 */ -#define XKB_KEY_braille_dots_134678 0x10028ed /* U+28ed BRAILLE PATTERN DOTS-134678 */ -#define XKB_KEY_braille_dots_234678 0x10028ee /* U+28ee BRAILLE PATTERN DOTS-234678 */ -#define XKB_KEY_braille_dots_1234678 0x10028ef /* U+28ef BRAILLE PATTERN DOTS-1234678 */ -#define XKB_KEY_braille_dots_5678 0x10028f0 /* U+28f0 BRAILLE PATTERN DOTS-5678 */ -#define XKB_KEY_braille_dots_15678 0x10028f1 /* U+28f1 BRAILLE PATTERN DOTS-15678 */ -#define XKB_KEY_braille_dots_25678 0x10028f2 /* U+28f2 BRAILLE PATTERN DOTS-25678 */ -#define XKB_KEY_braille_dots_125678 0x10028f3 /* U+28f3 BRAILLE PATTERN DOTS-125678 */ -#define XKB_KEY_braille_dots_35678 0x10028f4 /* U+28f4 BRAILLE PATTERN DOTS-35678 */ -#define XKB_KEY_braille_dots_135678 0x10028f5 /* U+28f5 BRAILLE PATTERN DOTS-135678 */ -#define XKB_KEY_braille_dots_235678 0x10028f6 /* U+28f6 BRAILLE PATTERN DOTS-235678 */ -#define XKB_KEY_braille_dots_1235678 0x10028f7 /* U+28f7 BRAILLE PATTERN DOTS-1235678 */ -#define XKB_KEY_braille_dots_45678 0x10028f8 /* U+28f8 BRAILLE PATTERN DOTS-45678 */ -#define XKB_KEY_braille_dots_145678 0x10028f9 /* U+28f9 BRAILLE PATTERN DOTS-145678 */ -#define XKB_KEY_braille_dots_245678 0x10028fa /* U+28fa BRAILLE PATTERN DOTS-245678 */ -#define XKB_KEY_braille_dots_1245678 0x10028fb /* U+28fb BRAILLE PATTERN DOTS-1245678 */ -#define XKB_KEY_braille_dots_345678 0x10028fc /* U+28fc BRAILLE PATTERN DOTS-345678 */ -#define XKB_KEY_braille_dots_1345678 0x10028fd /* U+28fd BRAILLE PATTERN DOTS-1345678 */ -#define XKB_KEY_braille_dots_2345678 0x10028fe /* U+28fe BRAILLE PATTERN DOTS-2345678 */ -#define XKB_KEY_braille_dots_12345678 0x10028ff /* U+28ff BRAILLE PATTERN DOTS-12345678 */ - -/* - * Sinhala (http://unicode.org/charts/PDF/U0D80.pdf) - * http://www.nongnu.org/sinhala/doc/transliteration/sinhala-transliteration_6.html - */ - -#define XKB_KEY_Sinh_ng 0x1000d82 /* U+0D82 SINHALA ANUSVARAYA */ -#define XKB_KEY_Sinh_h2 0x1000d83 /* U+0D83 SINHALA VISARGAYA */ -#define XKB_KEY_Sinh_a 0x1000d85 /* U+0D85 SINHALA AYANNA */ -#define XKB_KEY_Sinh_aa 0x1000d86 /* U+0D86 SINHALA AAYANNA */ -#define XKB_KEY_Sinh_ae 0x1000d87 /* U+0D87 SINHALA AEYANNA */ -#define XKB_KEY_Sinh_aee 0x1000d88 /* U+0D88 SINHALA AEEYANNA */ -#define XKB_KEY_Sinh_i 0x1000d89 /* U+0D89 SINHALA IYANNA */ -#define XKB_KEY_Sinh_ii 0x1000d8a /* U+0D8A SINHALA IIYANNA */ -#define XKB_KEY_Sinh_u 0x1000d8b /* U+0D8B SINHALA UYANNA */ -#define XKB_KEY_Sinh_uu 0x1000d8c /* U+0D8C SINHALA UUYANNA */ -#define XKB_KEY_Sinh_ri 0x1000d8d /* U+0D8D SINHALA IRUYANNA */ -#define XKB_KEY_Sinh_rii 0x1000d8e /* U+0D8E SINHALA IRUUYANNA */ -#define XKB_KEY_Sinh_lu 0x1000d8f /* U+0D8F SINHALA ILUYANNA */ -#define XKB_KEY_Sinh_luu 0x1000d90 /* U+0D90 SINHALA ILUUYANNA */ -#define XKB_KEY_Sinh_e 0x1000d91 /* U+0D91 SINHALA EYANNA */ -#define XKB_KEY_Sinh_ee 0x1000d92 /* U+0D92 SINHALA EEYANNA */ -#define XKB_KEY_Sinh_ai 0x1000d93 /* U+0D93 SINHALA AIYANNA */ -#define XKB_KEY_Sinh_o 0x1000d94 /* U+0D94 SINHALA OYANNA */ -#define XKB_KEY_Sinh_oo 0x1000d95 /* U+0D95 SINHALA OOYANNA */ -#define XKB_KEY_Sinh_au 0x1000d96 /* U+0D96 SINHALA AUYANNA */ -#define XKB_KEY_Sinh_ka 0x1000d9a /* U+0D9A SINHALA KAYANNA */ -#define XKB_KEY_Sinh_kha 0x1000d9b /* U+0D9B SINHALA MAHA. KAYANNA */ -#define XKB_KEY_Sinh_ga 0x1000d9c /* U+0D9C SINHALA GAYANNA */ -#define XKB_KEY_Sinh_gha 0x1000d9d /* U+0D9D SINHALA MAHA. GAYANNA */ -#define XKB_KEY_Sinh_ng2 0x1000d9e /* U+0D9E SINHALA KANTAJA NAASIKYAYA */ -#define XKB_KEY_Sinh_nga 0x1000d9f /* U+0D9F SINHALA SANYAKA GAYANNA */ -#define XKB_KEY_Sinh_ca 0x1000da0 /* U+0DA0 SINHALA CAYANNA */ -#define XKB_KEY_Sinh_cha 0x1000da1 /* U+0DA1 SINHALA MAHA. CAYANNA */ -#define XKB_KEY_Sinh_ja 0x1000da2 /* U+0DA2 SINHALA JAYANNA */ -#define XKB_KEY_Sinh_jha 0x1000da3 /* U+0DA3 SINHALA MAHA. JAYANNA */ -#define XKB_KEY_Sinh_nya 0x1000da4 /* U+0DA4 SINHALA TAALUJA NAASIKYAYA */ -#define XKB_KEY_Sinh_jnya 0x1000da5 /* U+0DA5 SINHALA TAALUJA SANYOOGA NAASIKYAYA */ -#define XKB_KEY_Sinh_nja 0x1000da6 /* U+0DA6 SINHALA SANYAKA JAYANNA */ -#define XKB_KEY_Sinh_tta 0x1000da7 /* U+0DA7 SINHALA TTAYANNA */ -#define XKB_KEY_Sinh_ttha 0x1000da8 /* U+0DA8 SINHALA MAHA. TTAYANNA */ -#define XKB_KEY_Sinh_dda 0x1000da9 /* U+0DA9 SINHALA DDAYANNA */ -#define XKB_KEY_Sinh_ddha 0x1000daa /* U+0DAA SINHALA MAHA. DDAYANNA */ -#define XKB_KEY_Sinh_nna 0x1000dab /* U+0DAB SINHALA MUURDHAJA NAYANNA */ -#define XKB_KEY_Sinh_ndda 0x1000dac /* U+0DAC SINHALA SANYAKA DDAYANNA */ -#define XKB_KEY_Sinh_tha 0x1000dad /* U+0DAD SINHALA TAYANNA */ -#define XKB_KEY_Sinh_thha 0x1000dae /* U+0DAE SINHALA MAHA. TAYANNA */ -#define XKB_KEY_Sinh_dha 0x1000daf /* U+0DAF SINHALA DAYANNA */ -#define XKB_KEY_Sinh_dhha 0x1000db0 /* U+0DB0 SINHALA MAHA. DAYANNA */ -#define XKB_KEY_Sinh_na 0x1000db1 /* U+0DB1 SINHALA DANTAJA NAYANNA */ -#define XKB_KEY_Sinh_ndha 0x1000db3 /* U+0DB3 SINHALA SANYAKA DAYANNA */ -#define XKB_KEY_Sinh_pa 0x1000db4 /* U+0DB4 SINHALA PAYANNA */ -#define XKB_KEY_Sinh_pha 0x1000db5 /* U+0DB5 SINHALA MAHA. PAYANNA */ -#define XKB_KEY_Sinh_ba 0x1000db6 /* U+0DB6 SINHALA BAYANNA */ -#define XKB_KEY_Sinh_bha 0x1000db7 /* U+0DB7 SINHALA MAHA. BAYANNA */ -#define XKB_KEY_Sinh_ma 0x1000db8 /* U+0DB8 SINHALA MAYANNA */ -#define XKB_KEY_Sinh_mba 0x1000db9 /* U+0DB9 SINHALA AMBA BAYANNA */ -#define XKB_KEY_Sinh_ya 0x1000dba /* U+0DBA SINHALA YAYANNA */ -#define XKB_KEY_Sinh_ra 0x1000dbb /* U+0DBB SINHALA RAYANNA */ -#define XKB_KEY_Sinh_la 0x1000dbd /* U+0DBD SINHALA DANTAJA LAYANNA */ -#define XKB_KEY_Sinh_va 0x1000dc0 /* U+0DC0 SINHALA VAYANNA */ -#define XKB_KEY_Sinh_sha 0x1000dc1 /* U+0DC1 SINHALA TAALUJA SAYANNA */ -#define XKB_KEY_Sinh_ssha 0x1000dc2 /* U+0DC2 SINHALA MUURDHAJA SAYANNA */ -#define XKB_KEY_Sinh_sa 0x1000dc3 /* U+0DC3 SINHALA DANTAJA SAYANNA */ -#define XKB_KEY_Sinh_ha 0x1000dc4 /* U+0DC4 SINHALA HAYANNA */ -#define XKB_KEY_Sinh_lla 0x1000dc5 /* U+0DC5 SINHALA MUURDHAJA LAYANNA */ -#define XKB_KEY_Sinh_fa 0x1000dc6 /* U+0DC6 SINHALA FAYANNA */ -#define XKB_KEY_Sinh_al 0x1000dca /* U+0DCA SINHALA AL-LAKUNA */ -#define XKB_KEY_Sinh_aa2 0x1000dcf /* U+0DCF SINHALA AELA-PILLA */ -#define XKB_KEY_Sinh_ae2 0x1000dd0 /* U+0DD0 SINHALA AEDA-PILLA */ -#define XKB_KEY_Sinh_aee2 0x1000dd1 /* U+0DD1 SINHALA DIGA AEDA-PILLA */ -#define XKB_KEY_Sinh_i2 0x1000dd2 /* U+0DD2 SINHALA IS-PILLA */ -#define XKB_KEY_Sinh_ii2 0x1000dd3 /* U+0DD3 SINHALA DIGA IS-PILLA */ -#define XKB_KEY_Sinh_u2 0x1000dd4 /* U+0DD4 SINHALA PAA-PILLA */ -#define XKB_KEY_Sinh_uu2 0x1000dd6 /* U+0DD6 SINHALA DIGA PAA-PILLA */ -#define XKB_KEY_Sinh_ru2 0x1000dd8 /* U+0DD8 SINHALA GAETTA-PILLA */ -#define XKB_KEY_Sinh_e2 0x1000dd9 /* U+0DD9 SINHALA KOMBUVA */ -#define XKB_KEY_Sinh_ee2 0x1000dda /* U+0DDA SINHALA DIGA KOMBUVA */ -#define XKB_KEY_Sinh_ai2 0x1000ddb /* U+0DDB SINHALA KOMBU DEKA */ -#define XKB_KEY_Sinh_o2 0x1000ddc /* U+0DDC SINHALA KOMBUVA HAA AELA-PILLA*/ -#define XKB_KEY_Sinh_oo2 0x1000ddd /* U+0DDD SINHALA KOMBUVA HAA DIGA AELA-PILLA*/ -#define XKB_KEY_Sinh_au2 0x1000dde /* U+0DDE SINHALA KOMBUVA HAA GAYANUKITTA */ -#define XKB_KEY_Sinh_lu2 0x1000ddf /* U+0DDF SINHALA GAYANUKITTA */ -#define XKB_KEY_Sinh_ruu2 0x1000df2 /* U+0DF2 SINHALA DIGA GAETTA-PILLA */ -#define XKB_KEY_Sinh_luu2 0x1000df3 /* U+0DF3 SINHALA DIGA GAYANUKITTA */ -#define XKB_KEY_Sinh_kunddaliya 0x1000df4 /* U+0DF4 SINHALA KUNDDALIYA */ -/* - * XFree86 vendor specific keysyms. - * - * The XFree86 keysym range is 0x10080001 - 0x1008FFFF. - * - * X.Org will not be adding to the XF86 set of keysyms, though they have - * been adopted and are considered a "standard" part of X keysym definitions. - * XFree86 never properly commented these keysyms, so we have done our - * best to explain the semantic meaning of these keys. - * - * XFree86 has removed their mail archives of the period, that might have - * shed more light on some of these definitions. Until/unless we resurrect - * these archives, these are from memory and usage. - */ - -/* - * ModeLock - * - * This one is old, and not really used any more since XKB offers this - * functionality. - */ - -#define XKB_KEY_XF86ModeLock 0x1008FF01 /* Mode Switch Lock */ - -/* Backlight controls. */ -#define XKB_KEY_XF86MonBrightnessUp 0x1008FF02 /* Monitor/panel brightness */ -#define XKB_KEY_XF86MonBrightnessDown 0x1008FF03 /* Monitor/panel brightness */ -#define XKB_KEY_XF86KbdLightOnOff 0x1008FF04 /* Keyboards may be lit */ -#define XKB_KEY_XF86KbdBrightnessUp 0x1008FF05 /* Keyboards may be lit */ -#define XKB_KEY_XF86KbdBrightnessDown 0x1008FF06 /* Keyboards may be lit */ - -/* - * Keys found on some "Internet" keyboards. - */ -#define XKB_KEY_XF86Standby 0x1008FF10 /* System into standby mode */ -#define XKB_KEY_XF86AudioLowerVolume 0x1008FF11 /* Volume control down */ -#define XKB_KEY_XF86AudioMute 0x1008FF12 /* Mute sound from the system */ -#define XKB_KEY_XF86AudioRaiseVolume 0x1008FF13 /* Volume control up */ -#define XKB_KEY_XF86AudioPlay 0x1008FF14 /* Start playing of audio > */ -#define XKB_KEY_XF86AudioStop 0x1008FF15 /* Stop playing audio */ -#define XKB_KEY_XF86AudioPrev 0x1008FF16 /* Previous track */ -#define XKB_KEY_XF86AudioNext 0x1008FF17 /* Next track */ -#define XKB_KEY_XF86HomePage 0x1008FF18 /* Display user's home page */ -#define XKB_KEY_XF86Mail 0x1008FF19 /* Invoke user's mail program */ -#define XKB_KEY_XF86Start 0x1008FF1A /* Start application */ -#define XKB_KEY_XF86Search 0x1008FF1B /* Search */ -#define XKB_KEY_XF86AudioRecord 0x1008FF1C /* Record audio application */ - -/* These are sometimes found on PDA's (e.g. Palm, PocketPC or elsewhere) */ -#define XKB_KEY_XF86Calculator 0x1008FF1D /* Invoke calculator program */ -#define XKB_KEY_XF86Memo 0x1008FF1E /* Invoke Memo taking program */ -#define XKB_KEY_XF86ToDoList 0x1008FF1F /* Invoke To Do List program */ -#define XKB_KEY_XF86Calendar 0x1008FF20 /* Invoke Calendar program */ -#define XKB_KEY_XF86PowerDown 0x1008FF21 /* Deep sleep the system */ -#define XKB_KEY_XF86ContrastAdjust 0x1008FF22 /* Adjust screen contrast */ -#define XKB_KEY_XF86RockerUp 0x1008FF23 /* Rocker switches exist up */ -#define XKB_KEY_XF86RockerDown 0x1008FF24 /* and down */ -#define XKB_KEY_XF86RockerEnter 0x1008FF25 /* and let you press them */ - -/* Some more "Internet" keyboard symbols */ -#define XKB_KEY_XF86Back 0x1008FF26 /* Like back on a browser */ -#define XKB_KEY_XF86Forward 0x1008FF27 /* Like forward on a browser */ -#define XKB_KEY_XF86Stop 0x1008FF28 /* Stop current operation */ -#define XKB_KEY_XF86Refresh 0x1008FF29 /* Refresh the page */ -#define XKB_KEY_XF86PowerOff 0x1008FF2A /* Power off system entirely */ -#define XKB_KEY_XF86WakeUp 0x1008FF2B /* Wake up system from sleep */ -#define XKB_KEY_XF86Eject 0x1008FF2C /* Eject device (e.g. DVD) */ -#define XKB_KEY_XF86ScreenSaver 0x1008FF2D /* Invoke screensaver */ -#define XKB_KEY_XF86WWW 0x1008FF2E /* Invoke web browser */ -#define XKB_KEY_XF86Sleep 0x1008FF2F /* Put system to sleep */ -#define XKB_KEY_XF86Favorites 0x1008FF30 /* Show favorite locations */ -#define XKB_KEY_XF86AudioPause 0x1008FF31 /* Pause audio playing */ -#define XKB_KEY_XF86AudioMedia 0x1008FF32 /* Launch media collection app */ -#define XKB_KEY_XF86MyComputer 0x1008FF33 /* Display "My Computer" window */ -#define XKB_KEY_XF86VendorHome 0x1008FF34 /* Display vendor home web site */ -#define XKB_KEY_XF86LightBulb 0x1008FF35 /* Light bulb keys exist */ -#define XKB_KEY_XF86Shop 0x1008FF36 /* Display shopping web site */ -#define XKB_KEY_XF86History 0x1008FF37 /* Show history of web surfing */ -#define XKB_KEY_XF86OpenURL 0x1008FF38 /* Open selected URL */ -#define XKB_KEY_XF86AddFavorite 0x1008FF39 /* Add URL to favorites list */ -#define XKB_KEY_XF86HotLinks 0x1008FF3A /* Show "hot" links */ -#define XKB_KEY_XF86BrightnessAdjust 0x1008FF3B /* Invoke brightness adj. UI */ -#define XKB_KEY_XF86Finance 0x1008FF3C /* Display financial site */ -#define XKB_KEY_XF86Community 0x1008FF3D /* Display user's community */ -#define XKB_KEY_XF86AudioRewind 0x1008FF3E /* "rewind" audio track */ -#define XKB_KEY_XF86BackForward 0x1008FF3F /* ??? */ -#define XKB_KEY_XF86Launch0 0x1008FF40 /* Launch Application */ -#define XKB_KEY_XF86Launch1 0x1008FF41 /* Launch Application */ -#define XKB_KEY_XF86Launch2 0x1008FF42 /* Launch Application */ -#define XKB_KEY_XF86Launch3 0x1008FF43 /* Launch Application */ -#define XKB_KEY_XF86Launch4 0x1008FF44 /* Launch Application */ -#define XKB_KEY_XF86Launch5 0x1008FF45 /* Launch Application */ -#define XKB_KEY_XF86Launch6 0x1008FF46 /* Launch Application */ -#define XKB_KEY_XF86Launch7 0x1008FF47 /* Launch Application */ -#define XKB_KEY_XF86Launch8 0x1008FF48 /* Launch Application */ -#define XKB_KEY_XF86Launch9 0x1008FF49 /* Launch Application */ -#define XKB_KEY_XF86LaunchA 0x1008FF4A /* Launch Application */ -#define XKB_KEY_XF86LaunchB 0x1008FF4B /* Launch Application */ -#define XKB_KEY_XF86LaunchC 0x1008FF4C /* Launch Application */ -#define XKB_KEY_XF86LaunchD 0x1008FF4D /* Launch Application */ -#define XKB_KEY_XF86LaunchE 0x1008FF4E /* Launch Application */ -#define XKB_KEY_XF86LaunchF 0x1008FF4F /* Launch Application */ - -#define XKB_KEY_XF86ApplicationLeft 0x1008FF50 /* switch to application, left */ -#define XKB_KEY_XF86ApplicationRight 0x1008FF51 /* switch to application, right*/ -#define XKB_KEY_XF86Book 0x1008FF52 /* Launch bookreader */ -#define XKB_KEY_XF86CD 0x1008FF53 /* Launch CD/DVD player */ -#define XKB_KEY_XF86Calculater 0x1008FF54 /* Launch Calculater */ -#define XKB_KEY_XF86Clear 0x1008FF55 /* Clear window, screen */ -#define XKB_KEY_XF86Close 0x1008FF56 /* Close window */ -#define XKB_KEY_XF86Copy 0x1008FF57 /* Copy selection */ -#define XKB_KEY_XF86Cut 0x1008FF58 /* Cut selection */ -#define XKB_KEY_XF86Display 0x1008FF59 /* Output switch key */ -#define XKB_KEY_XF86DOS 0x1008FF5A /* Launch DOS (emulation) */ -#define XKB_KEY_XF86Documents 0x1008FF5B /* Open documents window */ -#define XKB_KEY_XF86Excel 0x1008FF5C /* Launch spread sheet */ -#define XKB_KEY_XF86Explorer 0x1008FF5D /* Launch file explorer */ -#define XKB_KEY_XF86Game 0x1008FF5E /* Launch game */ -#define XKB_KEY_XF86Go 0x1008FF5F /* Go to URL */ -#define XKB_KEY_XF86iTouch 0x1008FF60 /* Logitch iTouch- don't use */ -#define XKB_KEY_XF86LogOff 0x1008FF61 /* Log off system */ -#define XKB_KEY_XF86Market 0x1008FF62 /* ?? */ -#define XKB_KEY_XF86Meeting 0x1008FF63 /* enter meeting in calendar */ -#define XKB_KEY_XF86MenuKB 0x1008FF65 /* distingush keyboard from PB */ -#define XKB_KEY_XF86MenuPB 0x1008FF66 /* distinuish PB from keyboard */ -#define XKB_KEY_XF86MySites 0x1008FF67 /* Favourites */ -#define XKB_KEY_XF86New 0x1008FF68 /* New (folder, document... */ -#define XKB_KEY_XF86News 0x1008FF69 /* News */ -#define XKB_KEY_XF86OfficeHome 0x1008FF6A /* Office home (old Staroffice)*/ -#define XKB_KEY_XF86Open 0x1008FF6B /* Open */ -#define XKB_KEY_XF86Option 0x1008FF6C /* ?? */ -#define XKB_KEY_XF86Paste 0x1008FF6D /* Paste */ -#define XKB_KEY_XF86Phone 0x1008FF6E /* Launch phone; dial number */ -#define XKB_KEY_XF86Q 0x1008FF70 /* Compaq's Q - don't use */ -#define XKB_KEY_XF86Reply 0x1008FF72 /* Reply e.g., mail */ -#define XKB_KEY_XF86Reload 0x1008FF73 /* Reload web page, file, etc. */ -#define XKB_KEY_XF86RotateWindows 0x1008FF74 /* Rotate windows e.g. xrandr */ -#define XKB_KEY_XF86RotationPB 0x1008FF75 /* don't use */ -#define XKB_KEY_XF86RotationKB 0x1008FF76 /* don't use */ -#define XKB_KEY_XF86Save 0x1008FF77 /* Save (file, document, state */ -#define XKB_KEY_XF86ScrollUp 0x1008FF78 /* Scroll window/contents up */ -#define XKB_KEY_XF86ScrollDown 0x1008FF79 /* Scrool window/contentd down */ -#define XKB_KEY_XF86ScrollClick 0x1008FF7A /* Use XKB mousekeys instead */ -#define XKB_KEY_XF86Send 0x1008FF7B /* Send mail, file, object */ -#define XKB_KEY_XF86Spell 0x1008FF7C /* Spell checker */ -#define XKB_KEY_XF86SplitScreen 0x1008FF7D /* Split window or screen */ -#define XKB_KEY_XF86Support 0x1008FF7E /* Get support (??) */ -#define XKB_KEY_XF86TaskPane 0x1008FF7F /* Show tasks */ -#define XKB_KEY_XF86Terminal 0x1008FF80 /* Launch terminal emulator */ -#define XKB_KEY_XF86Tools 0x1008FF81 /* toolbox of desktop/app. */ -#define XKB_KEY_XF86Travel 0x1008FF82 /* ?? */ -#define XKB_KEY_XF86UserPB 0x1008FF84 /* ?? */ -#define XKB_KEY_XF86User1KB 0x1008FF85 /* ?? */ -#define XKB_KEY_XF86User2KB 0x1008FF86 /* ?? */ -#define XKB_KEY_XF86Video 0x1008FF87 /* Launch video player */ -#define XKB_KEY_XF86WheelButton 0x1008FF88 /* button from a mouse wheel */ -#define XKB_KEY_XF86Word 0x1008FF89 /* Launch word processor */ -#define XKB_KEY_XF86Xfer 0x1008FF8A -#define XKB_KEY_XF86ZoomIn 0x1008FF8B /* zoom in view, map, etc. */ -#define XKB_KEY_XF86ZoomOut 0x1008FF8C /* zoom out view, map, etc. */ - -#define XKB_KEY_XF86Away 0x1008FF8D /* mark yourself as away */ -#define XKB_KEY_XF86Messenger 0x1008FF8E /* as in instant messaging */ -#define XKB_KEY_XF86WebCam 0x1008FF8F /* Launch web camera app. */ -#define XKB_KEY_XF86MailForward 0x1008FF90 /* Forward in mail */ -#define XKB_KEY_XF86Pictures 0x1008FF91 /* Show pictures */ -#define XKB_KEY_XF86Music 0x1008FF92 /* Launch music application */ - -#define XKB_KEY_XF86Battery 0x1008FF93 /* Display battery information */ -#define XKB_KEY_XF86Bluetooth 0x1008FF94 /* Enable/disable Bluetooth */ -#define XKB_KEY_XF86WLAN 0x1008FF95 /* Enable/disable WLAN */ -#define XKB_KEY_XF86UWB 0x1008FF96 /* Enable/disable UWB */ - -#define XKB_KEY_XF86AudioForward 0x1008FF97 /* fast-forward audio track */ -#define XKB_KEY_XF86AudioRepeat 0x1008FF98 /* toggle repeat mode */ -#define XKB_KEY_XF86AudioRandomPlay 0x1008FF99 /* toggle shuffle mode */ -#define XKB_KEY_XF86Subtitle 0x1008FF9A /* cycle through subtitle */ -#define XKB_KEY_XF86AudioCycleTrack 0x1008FF9B /* cycle through audio tracks */ -#define XKB_KEY_XF86CycleAngle 0x1008FF9C /* cycle through angles */ -#define XKB_KEY_XF86FrameBack 0x1008FF9D /* video: go one frame back */ -#define XKB_KEY_XF86FrameForward 0x1008FF9E /* video: go one frame forward */ -#define XKB_KEY_XF86Time 0x1008FF9F /* display, or shows an entry for time seeking */ -#define XKB_KEY_XF86Select 0x1008FFA0 /* Select button on joypads and remotes */ -#define XKB_KEY_XF86View 0x1008FFA1 /* Show a view options/properties */ -#define XKB_KEY_XF86TopMenu 0x1008FFA2 /* Go to a top-level menu in a video */ - -#define XKB_KEY_XF86Red 0x1008FFA3 /* Red button */ -#define XKB_KEY_XF86Green 0x1008FFA4 /* Green button */ -#define XKB_KEY_XF86Yellow 0x1008FFA5 /* Yellow button */ -#define XKB_KEY_XF86Blue 0x1008FFA6 /* Blue button */ - -#define XKB_KEY_XF86Suspend 0x1008FFA7 /* Sleep to RAM */ -#define XKB_KEY_XF86Hibernate 0x1008FFA8 /* Sleep to disk */ -#define XKB_KEY_XF86TouchpadToggle 0x1008FFA9 /* Toggle between touchpad/trackstick */ -#define XKB_KEY_XF86TouchpadOn 0x1008FFB0 /* The touchpad got switched on */ -#define XKB_KEY_XF86TouchpadOff 0x1008FFB1 /* The touchpad got switched off */ - -#define XKB_KEY_XF86AudioMicMute 0x1008FFB2 /* Mute the Mic from the system */ - -#define XKB_KEY_XF86Keyboard 0x1008FFB3 /* User defined keyboard related action */ - -#define XKB_KEY_XF86WWAN 0x1008FFB4 /* Toggle WWAN (LTE, UMTS, etc.) radio */ -#define XKB_KEY_XF86RFKill 0x1008FFB5 /* Toggle radios on/off */ - -#define XKB_KEY_XF86AudioPreset 0x1008FFB6 /* Select equalizer preset, e.g. theatre-mode */ - -/* Keys for special action keys (hot keys) */ -/* Virtual terminals on some operating systems */ -#define XKB_KEY_XF86Switch_VT_1 0x1008FE01 -#define XKB_KEY_XF86Switch_VT_2 0x1008FE02 -#define XKB_KEY_XF86Switch_VT_3 0x1008FE03 -#define XKB_KEY_XF86Switch_VT_4 0x1008FE04 -#define XKB_KEY_XF86Switch_VT_5 0x1008FE05 -#define XKB_KEY_XF86Switch_VT_6 0x1008FE06 -#define XKB_KEY_XF86Switch_VT_7 0x1008FE07 -#define XKB_KEY_XF86Switch_VT_8 0x1008FE08 -#define XKB_KEY_XF86Switch_VT_9 0x1008FE09 -#define XKB_KEY_XF86Switch_VT_10 0x1008FE0A -#define XKB_KEY_XF86Switch_VT_11 0x1008FE0B -#define XKB_KEY_XF86Switch_VT_12 0x1008FE0C - -#define XKB_KEY_XF86Ungrab 0x1008FE20 /* force ungrab */ -#define XKB_KEY_XF86ClearGrab 0x1008FE21 /* kill application with grab */ -#define XKB_KEY_XF86Next_VMode 0x1008FE22 /* next video mode available */ -#define XKB_KEY_XF86Prev_VMode 0x1008FE23 /* prev. video mode available */ -#define XKB_KEY_XF86LogWindowTree 0x1008FE24 /* print window tree to log */ -#define XKB_KEY_XF86LogGrabInfo 0x1008FE25 /* print all active grabs to log */ -/* - * Copyright (c) 1991, Oracle and/or its affiliates. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ -/************************************************************ - -Copyright 1991, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - -***********************************************************/ - -/* - * Floating Accent - */ - -#define XKB_KEY_SunFA_Grave 0x1005FF00 -#define XKB_KEY_SunFA_Circum 0x1005FF01 -#define XKB_KEY_SunFA_Tilde 0x1005FF02 -#define XKB_KEY_SunFA_Acute 0x1005FF03 -#define XKB_KEY_SunFA_Diaeresis 0x1005FF04 -#define XKB_KEY_SunFA_Cedilla 0x1005FF05 - -/* - * Miscellaneous Functions - */ - -#define XKB_KEY_SunF36 0x1005FF10 /* Labeled F11 */ -#define XKB_KEY_SunF37 0x1005FF11 /* Labeled F12 */ - -#define XKB_KEY_SunSys_Req 0x1005FF60 -#define XKB_KEY_SunPrint_Screen 0x0000FF61 /* Same as XK_Print */ - -/* - * International & Multi-Key Character Composition - */ - -#define XKB_KEY_SunCompose 0x0000FF20 /* Same as XK_Multi_key */ -#define XKB_KEY_SunAltGraph 0x0000FF7E /* Same as XK_Mode_switch */ - -/* - * Cursor Control - */ - -#define XKB_KEY_SunPageUp 0x0000FF55 /* Same as XK_Prior */ -#define XKB_KEY_SunPageDown 0x0000FF56 /* Same as XK_Next */ - -/* - * Open Look Functions - */ - -#define XKB_KEY_SunUndo 0x0000FF65 /* Same as XK_Undo */ -#define XKB_KEY_SunAgain 0x0000FF66 /* Same as XK_Redo */ -#define XKB_KEY_SunFind 0x0000FF68 /* Same as XK_Find */ -#define XKB_KEY_SunStop 0x0000FF69 /* Same as XK_Cancel */ -#define XKB_KEY_SunProps 0x1005FF70 -#define XKB_KEY_SunFront 0x1005FF71 -#define XKB_KEY_SunCopy 0x1005FF72 -#define XKB_KEY_SunOpen 0x1005FF73 -#define XKB_KEY_SunPaste 0x1005FF74 -#define XKB_KEY_SunCut 0x1005FF75 - -#define XKB_KEY_SunPowerSwitch 0x1005FF76 -#define XKB_KEY_SunAudioLowerVolume 0x1005FF77 -#define XKB_KEY_SunAudioMute 0x1005FF78 -#define XKB_KEY_SunAudioRaiseVolume 0x1005FF79 -#define XKB_KEY_SunVideoDegauss 0x1005FF7A -#define XKB_KEY_SunVideoLowerBrightness 0x1005FF7B -#define XKB_KEY_SunVideoRaiseBrightness 0x1005FF7C -#define XKB_KEY_SunPowerSwitchShift 0x1005FF7D -/*********************************************************** - -Copyright 1988, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - - -Copyright 1988 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -******************************************************************/ - -/* - * DEC private keysyms - * (29th bit set) - */ - -/* two-key compose sequence initiators, chosen to map to Latin1 characters */ - -#define XKB_KEY_Dring_accent 0x1000FEB0 -#define XKB_KEY_Dcircumflex_accent 0x1000FE5E -#define XKB_KEY_Dcedilla_accent 0x1000FE2C -#define XKB_KEY_Dacute_accent 0x1000FE27 -#define XKB_KEY_Dgrave_accent 0x1000FE60 -#define XKB_KEY_Dtilde 0x1000FE7E -#define XKB_KEY_Ddiaeresis 0x1000FE22 - -/* special keysym for LK2** "Remove" key on editing keypad */ - -#define XKB_KEY_DRemove 0x1000FF00 /* Remove */ -/* - -Copyright 1987, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall -not be used in advertising or otherwise to promote the sale, use or -other dealings in this Software without prior written authorization -from The Open Group. - -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the names of Hewlett Packard -or Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD -TO THIS SOFWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. Hewlett-Packard shall not be liable for errors -contained herein or direct, indirect, special, incidental or -consequential damages in connection with the furnishing, -performance, or use of this material. - -*/ - - - -#define XKB_KEY_hpClearLine 0x1000FF6F -#define XKB_KEY_hpInsertLine 0x1000FF70 -#define XKB_KEY_hpDeleteLine 0x1000FF71 -#define XKB_KEY_hpInsertChar 0x1000FF72 -#define XKB_KEY_hpDeleteChar 0x1000FF73 -#define XKB_KEY_hpBackTab 0x1000FF74 -#define XKB_KEY_hpKP_BackTab 0x1000FF75 -#define XKB_KEY_hpModelock1 0x1000FF48 -#define XKB_KEY_hpModelock2 0x1000FF49 -#define XKB_KEY_hpReset 0x1000FF6C -#define XKB_KEY_hpSystem 0x1000FF6D -#define XKB_KEY_hpUser 0x1000FF6E -#define XKB_KEY_hpmute_acute 0x100000A8 -#define XKB_KEY_hpmute_grave 0x100000A9 -#define XKB_KEY_hpmute_asciicircum 0x100000AA -#define XKB_KEY_hpmute_diaeresis 0x100000AB -#define XKB_KEY_hpmute_asciitilde 0x100000AC -#define XKB_KEY_hplira 0x100000AF -#define XKB_KEY_hpguilder 0x100000BE -#define XKB_KEY_hpYdiaeresis 0x100000EE -#define XKB_KEY_hpIO 0x100000EE -#define XKB_KEY_hplongminus 0x100000F6 -#define XKB_KEY_hpblock 0x100000FC - - - -#define XKB_KEY_osfCopy 0x1004FF02 -#define XKB_KEY_osfCut 0x1004FF03 -#define XKB_KEY_osfPaste 0x1004FF04 -#define XKB_KEY_osfBackTab 0x1004FF07 -#define XKB_KEY_osfBackSpace 0x1004FF08 -#define XKB_KEY_osfClear 0x1004FF0B -#define XKB_KEY_osfEscape 0x1004FF1B -#define XKB_KEY_osfAddMode 0x1004FF31 -#define XKB_KEY_osfPrimaryPaste 0x1004FF32 -#define XKB_KEY_osfQuickPaste 0x1004FF33 -#define XKB_KEY_osfPageLeft 0x1004FF40 -#define XKB_KEY_osfPageUp 0x1004FF41 -#define XKB_KEY_osfPageDown 0x1004FF42 -#define XKB_KEY_osfPageRight 0x1004FF43 -#define XKB_KEY_osfActivate 0x1004FF44 -#define XKB_KEY_osfMenuBar 0x1004FF45 -#define XKB_KEY_osfLeft 0x1004FF51 -#define XKB_KEY_osfUp 0x1004FF52 -#define XKB_KEY_osfRight 0x1004FF53 -#define XKB_KEY_osfDown 0x1004FF54 -#define XKB_KEY_osfEndLine 0x1004FF57 -#define XKB_KEY_osfBeginLine 0x1004FF58 -#define XKB_KEY_osfEndData 0x1004FF59 -#define XKB_KEY_osfBeginData 0x1004FF5A -#define XKB_KEY_osfPrevMenu 0x1004FF5B -#define XKB_KEY_osfNextMenu 0x1004FF5C -#define XKB_KEY_osfPrevField 0x1004FF5D -#define XKB_KEY_osfNextField 0x1004FF5E -#define XKB_KEY_osfSelect 0x1004FF60 -#define XKB_KEY_osfInsert 0x1004FF63 -#define XKB_KEY_osfUndo 0x1004FF65 -#define XKB_KEY_osfMenu 0x1004FF67 -#define XKB_KEY_osfCancel 0x1004FF69 -#define XKB_KEY_osfHelp 0x1004FF6A -#define XKB_KEY_osfSelectAll 0x1004FF71 -#define XKB_KEY_osfDeselectAll 0x1004FF72 -#define XKB_KEY_osfReselect 0x1004FF73 -#define XKB_KEY_osfExtend 0x1004FF74 -#define XKB_KEY_osfRestore 0x1004FF78 -#define XKB_KEY_osfDelete 0x1004FFFF - - - -/************************************************************** - * The use of the following macros is deprecated. - * They are listed below only for backwards compatibility. - */ -#define XKB_KEY_Reset 0x1000FF6C -#define XKB_KEY_System 0x1000FF6D -#define XKB_KEY_User 0x1000FF6E -#define XKB_KEY_ClearLine 0x1000FF6F -#define XKB_KEY_InsertLine 0x1000FF70 -#define XKB_KEY_DeleteLine 0x1000FF71 -#define XKB_KEY_InsertChar 0x1000FF72 -#define XKB_KEY_DeleteChar 0x1000FF73 -#define XKB_KEY_BackTab 0x1000FF74 -#define XKB_KEY_KP_BackTab 0x1000FF75 -#define XKB_KEY_Ext16bit_L 0x1000FF76 -#define XKB_KEY_Ext16bit_R 0x1000FF77 -#define XKB_KEY_mute_acute 0x100000a8 -#define XKB_KEY_mute_grave 0x100000a9 -#define XKB_KEY_mute_asciicircum 0x100000aa -#define XKB_KEY_mute_diaeresis 0x100000ab -#define XKB_KEY_mute_asciitilde 0x100000ac -#define XKB_KEY_lira 0x100000af -#define XKB_KEY_guilder 0x100000be -#define XKB_KEY_IO 0x100000ee -#define XKB_KEY_longminus 0x100000f6 -#define XKB_KEY_block 0x100000fc - - - -#endif diff --git a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-names.h b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-names.h deleted file mode 100644 index ecb551ff10..0000000000 --- a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-names.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright © 2012 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Daniel Stone - */ - -#ifndef _XKBCOMMON_NAMES_H -#define _XKBCOMMON_NAMES_H - -/** - * @file - * @brief Predefined names for common modifiers and LEDs. - */ - -#define XKB_MOD_NAME_SHIFT "Shift" -#define XKB_MOD_NAME_CAPS "Lock" -#define XKB_MOD_NAME_CTRL "Control" -#define XKB_MOD_NAME_ALT "Mod1" -#define XKB_MOD_NAME_NUM "Mod2" -#define XKB_MOD_NAME_LOGO "Mod4" - -#define XKB_LED_NAME_CAPS "Caps Lock" -#define XKB_LED_NAME_NUM "Num Lock" -#define XKB_LED_NAME_SCROLL "Scroll Lock" - -#endif diff --git a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-x11.h b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-x11.h deleted file mode 100644 index cf244d2559..0000000000 --- a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-x11.h +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright © 2013 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef _XKBCOMMON_X11_H -#define _XKBCOMMON_X11_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @file - * libxkbcommon-x11 API - Additional X11 support for xkbcommon. - */ - -/** - * @defgroup x11 X11 support - * Additional X11 support for xkbcommon. - * @since 0.4.0 - * - * @{ - */ - -/** - * @page x11-overview Overview - * @parblock - * - * The xkbcommon-x11 module provides a means for creating an xkb_keymap - * corresponding to the currently active keymap on the X server. To do - * so, it queries the XKB X11 extension using the xcb-xkb library. It - * can be used as a replacement for Xlib's keyboard handling. - * - * Following is an example workflow using xkbcommon-x11. A complete - * example may be found in the test/interactive-x11.c file in the - * xkbcommon source repository. On startup: - * - * 1. Connect to the X server using xcb_connect(). - * 2. Setup the XKB X11 extension. You can do this either by using the - * xcb_xkb_use_extension() request directly, or by using the - * xkb_x11_setup_xkb_extension() helper function. - * - * The XKB extension supports using separate keymaps and states for - * different keyboard devices. The devices are identified by an integer - * device ID and are managed by another X11 extension, XInput. The - * original X11 protocol only had one keyboard device, called the "core - * keyboard", which is still supported as a "virtual device". - * - * 3. We will use the core keyboard as an example. To get its device ID, - * use either the xcb_xkb_get_device_info() request directly, or the - * xkb_x11_get_core_keyboard_device_id() helper function. - * 4. Create an initial xkb_keymap for this device, using the - * xkb_x11_keymap_new_from_device() function. - * 5. Create an initial xkb_state for this device, using the - * xkb_x11_state_new_from_device() function. - * - * @note At this point, you may consider setting various XKB controls and - * XKB per-client flags. For example, enabling detectable autorepeat: \n - * https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Detectable_Autorepeat - * - * Next, you need to react to state changes (e.g. a modifier was pressed, - * the layout was changed) and to keymap changes (e.g. a tool like xkbcomp, - * setxkbmap or xmodmap was used): - * - * 6. Select to listen to at least the following XKB events: - * NewKeyboardNotify, MapNotify, StateNotify; using the - * xcb_xkb_select_events_aux() request. - * 7. When NewKeyboardNotify or MapNotify are received, recreate the - * xkb_keymap and xkb_state as described above. - * 8. When StateNotify is received, update the xkb_state accordingly - * using the xkb_state_update_mask() function. - * - * @note It is also possible to use the KeyPress/KeyRelease @p state - * field to find the effective modifier and layout state, instead of - * using XkbStateNotify: \n - * https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Computing_A_State_Field_from_an_XKB_State - * \n However, XkbStateNotify is more accurate. - * - * @note There is no need to call xkb_state_update_key(); the state is - * already synchronized. - * - * Finally, when a key event is received, you can use ordinary xkbcommon - * functions, like xkb_state_key_get_one_sym() and xkb_state_key_get_utf8(), - * as you normally would. - * - * @endparblock - */ - -/** - * The minimal compatible major version of the XKB X11 extension which - * this library can use. - */ -#define XKB_X11_MIN_MAJOR_XKB_VERSION 1 -/** - * The minimal compatible minor version of the XKB X11 extension which - * this library can use (for the minimal major version). - */ -#define XKB_X11_MIN_MINOR_XKB_VERSION 0 - -/** Flags for the xkb_x11_setup_xkb_extension() function. */ -enum xkb_x11_setup_xkb_extension_flags { - /** Do not apply any flags. */ - XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS = 0 -}; - -/** - * Setup the XKB X11 extension for this X client. - * - * The xkbcommon-x11 library uses various XKB requests. Before doing so, - * an X client must notify the server that it will be using the extension. - * This function (or an XCB equivalent) must be called before any other - * function in this library is used. - * - * Some X servers may not support or disable the XKB extension. If you - * want to support such servers, you need to use a different fallback. - * - * You may call this function several times; it is idempotent. - * - * @param connection - * An XCB connection to the X server. - * @param major_xkb_version - * See @p minor_xkb_version. - * @param minor_xkb_version - * The XKB extension version to request. To operate correctly, you - * must have (major_xkb_version, minor_xkb_version) >= - * (XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION), - * though this is not enforced. - * @param flags - * Optional flags, or 0. - * @param[out] major_xkb_version_out - * See @p minor_xkb_version_out. - * @param[out] minor_xkb_version_out - * Backfilled with the compatible XKB extension version numbers picked - * by the server. Can be NULL. - * @param[out] base_event_out - * Backfilled with the XKB base (also known as first) event code, needed - * to distinguish XKB events. Can be NULL. - * @param[out] base_error_out - * Backfilled with the XKB base (also known as first) error code, needed - * to distinguish XKB errors. Can be NULL. - * - * @returns 1 on success, or 0 on failure. - */ -int -xkb_x11_setup_xkb_extension(xcb_connection_t *connection, - uint16_t major_xkb_version, - uint16_t minor_xkb_version, - enum xkb_x11_setup_xkb_extension_flags flags, - uint16_t *major_xkb_version_out, - uint16_t *minor_xkb_version_out, - uint8_t *base_event_out, - uint8_t *base_error_out); - -/** - * Get the keyboard device ID of the core X11 keyboard. - * - * @param connection An XCB connection to the X server. - * - * @returns A device ID which may be used with other xkb_x11_* functions, - * or -1 on failure. - */ -int32_t -xkb_x11_get_core_keyboard_device_id(xcb_connection_t *connection); - -/** - * Create a keymap from an X11 keyboard device. - * - * This function queries the X server with various requests, fetches the - * details of the active keymap on a keyboard device, and creates an - * xkb_keymap from these details. - * - * @param context - * The context in which to create the keymap. - * @param connection - * An XCB connection to the X server. - * @param device_id - * An XInput device ID (in the range 0-127) with input class KEY. - * Passing values outside of this range is an error (the XKB protocol - * predates the XInput2 protocol, which first allowed IDs > 127). - * @param flags - * Optional flags for the keymap, or 0. - * - * @returns A keymap retrieved from the X server, or NULL on failure. - * - * @memberof xkb_keymap - */ -struct xkb_keymap * -xkb_x11_keymap_new_from_device(struct xkb_context *context, - xcb_connection_t *connection, - int32_t device_id, - enum xkb_keymap_compile_flags flags); - -/** - * Create a new keyboard state object from an X11 keyboard device. - * - * This function is the same as xkb_state_new(), only pre-initialized - * with the state of the device at the time this function is called. - * - * @param keymap - * The keymap for which to create the state. - * @param connection - * An XCB connection to the X server. - * @param device_id - * An XInput 1 device ID (in the range 0-255) with input class KEY. - * Passing values outside of this range is an error. - * - * @returns A new keyboard state object, or NULL on failure. - * - * @memberof xkb_state - */ -struct xkb_state * -xkb_x11_state_new_from_device(struct xkb_keymap *keymap, - xcb_connection_t *connection, - int32_t device_id); - -/** @} */ - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* _XKBCOMMON_X11_H */ diff --git a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon.h b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon.h deleted file mode 100644 index c28123f95e..0000000000 --- a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon.h +++ /dev/null @@ -1,1868 +0,0 @@ -/* - * Copyright 1985, 1987, 1990, 1998 The Open Group - * Copyright 2008 Dan Nicholson - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the names of the authors or their - * institutions shall not be used in advertising or otherwise to promote the - * sale, use or other dealings in this Software without prior written - * authorization from the authors. - */ - -/************************************************************ - * Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting - * documentation, and that the name of Silicon Graphics not be - * used in advertising or publicity pertaining to distribution - * of the software without specific prior written permission. - * Silicon Graphics makes no representation about the suitability - * of this software for any purpose. It is provided "as is" - * without any express or implied warranty. - * - * SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON - * GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH - * THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - ********************************************************/ - -/* - * Copyright © 2009-2012 Daniel Stone - * Copyright © 2012 Intel Corporation - * Copyright © 2012 Ran Benita - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Daniel Stone - */ - -#ifndef _XKBCOMMON_H_ -#define _XKBCOMMON_H_ - -#include -#include -#include - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @file - * Main libxkbcommon API. - */ - -/** - * @struct xkb_context - * Opaque top level library context object. - * - * The context contains various general library data and state, like - * logging level and include paths. - * - * Objects are created in a specific context, and multiple contexts may - * coexist simultaneously. Objects from different contexts are completely - * separated and do not share any memory or state. - */ -struct xkb_context; - -/** - * @struct xkb_keymap - * Opaque compiled keymap object. - * - * The keymap object holds all of the static keyboard information obtained - * from compiling XKB files. - * - * A keymap is immutable after it is created (besides reference counts, etc.); - * if you need to change it, you must create a new one. - */ -struct xkb_keymap; - -/** - * @struct xkb_state - * Opaque keyboard state object. - * - * State objects contain the active state of a keyboard (or keyboards), such - * as the currently effective layout and the active modifiers. It acts as a - * simple state machine, wherein key presses and releases are the input, and - * key symbols (keysyms) are the output. - */ -struct xkb_state; - -/** - * A number used to represent a physical key on a keyboard. - * - * A standard PC-compatible keyboard might have 102 keys. An appropriate - * keymap would assign each of them a keycode, by which the user should - * refer to the key throughout the library. - * - * Historically, the X11 protocol, and consequentially the XKB protocol, - * assign only 8 bits for keycodes. This limits the number of different - * keys that can be used simultaneously in a single keymap to 256 - * (disregarding other limitations). This library does not share this limit; - * keycodes beyond 255 ('extended keycodes') are not treated specially. - * Keymaps and applications which are compatible with X11 should not use - * these keycodes. - * - * The values of specific keycodes are determined by the keymap and the - * underlying input system. For example, with an X11-compatible keymap - * and Linux evdev scan codes (see linux/input.h), a fixed offset is used: - * - * The keymap defines a canonical name for each key, plus possible aliases. - * Historically, the XKB protocol restricts these names to at most 4 (ASCII) - * characters, but this library does not share this limit. - * - * @code - * xkb_keycode_t keycode_A = KEY_A + 8; - * @endcode - * - * @sa xkb_keycode_is_legal_ext() xkb_keycode_is_legal_x11() - */ -typedef uint32_t xkb_keycode_t; - -/** - * A number used to represent the symbols generated from a key on a keyboard. - * - * A key, represented by a keycode, may generate different symbols according - * to keyboard state. For example, on a QWERTY keyboard, pressing the key - * labled \ generates the symbol 'a'. If the Shift key is held, it - * generates the symbol 'A'. If a different layout is used, say Greek, - * it generates the symbol 'α'. And so on. - * - * Each such symbol is represented by a keysym. Note that keysyms are - * somewhat more general, in that they can also represent some "function", - * such as "Left" or "Right" for the arrow keys. For more information, - * see: - * https://www.x.org/releases/current/doc/xproto/x11protocol.html#keysym_encoding - * - * Specifically named keysyms can be found in the - * xkbcommon/xkbcommon-keysyms.h header file. Their name does not include - * the XKB_KEY_ prefix. - * - * Besides those, any Unicode/ISO 10646 character in the range U0100 to - * U10FFFF can be represented by a keysym value in the range 0x01000100 to - * 0x0110FFFF. The name of Unicode keysyms is "U", e.g. "UA1B2". - * - * The name of other unnamed keysyms is the hexadecimal representation of - * their value, e.g. "0xabcd1234". - * - * Keysym names are case-sensitive. - */ -typedef uint32_t xkb_keysym_t; - -/** - * Index of a keyboard layout. - * - * The layout index is a state component which detemines which keyboard - * layout is active. These may be different alphabets, different key - * arrangements, etc. - * - * Layout indices are consecutive. The first layout has index 0. - * - * Each layout is not required to have a name, and the names are not - * guaranteed to be unique (though they are usually provided and unique). - * Therefore, it is not safe to use the name as a unique identifier for a - * layout. Layout names are case-sensitive. - * - * Layouts are also called "groups" by XKB. - * - * @sa xkb_keymap_num_layouts() xkb_keymap_num_layouts_for_key() - */ -typedef uint32_t xkb_layout_index_t; -/** A mask of layout indices. */ -typedef uint32_t xkb_layout_mask_t; - -/** - * Index of a shift level. - * - * Any key, in any layout, can have several shift levels. Each - * shift level can assign different keysyms to the key. The shift level - * to use is chosen according to the current keyboard state; for example, - * if no keys are pressed, the first level may be used; if the Left Shift - * key is pressed, the second; if Num Lock is pressed, the third; and - * many such combinations are possible (see xkb_mod_index_t). - * - * Level indices are consecutive. The first level has index 0. - */ -typedef uint32_t xkb_level_index_t; - -/** - * Index of a modifier. - * - * A @e modifier is a state component which changes the way keys are - * interpreted. A keymap defines a set of modifiers, such as Alt, Shift, - * Num Lock or Meta, and specifies which keys may @e activate which - * modifiers (in a many-to-many relationship, i.e. a key can activate - * several modifiers, and a modifier may be activated by several keys. - * Different keymaps do this differently). - * - * When retrieving the keysyms for a key, the active modifier set is - * consulted; this detemines the correct shift level to use within the - * currently active layout (see xkb_level_index_t). - * - * Modifier indices are consecutive. The first modifier has index 0. - * - * Each modifier must have a name, and the names are unique. Therefore, it - * is safe to use the name as a unique identifier for a modifier. The names - * of some common modifiers are provided in the xkbcommon/xkbcommon-names.h - * header file. Modifier names are case-sensitive. - * - * @sa xkb_keymap_num_mods() - */ -typedef uint32_t xkb_mod_index_t; -/** A mask of modifier indices. */ -typedef uint32_t xkb_mod_mask_t; - -/** - * Index of a keyboard LED. - * - * LEDs are logical objects which may be @e active or @e inactive. They - * typically correspond to the lights on the keyboard. Their state is - * determined by the current keyboard state. - * - * LED indices are non-consecutive. The first LED has index 0. - * - * Each LED must have a name, and the names are unique. Therefore, - * it is safe to use the name as a unique identifier for a LED. The names - * of some common LEDs are provided in the xkbcommon/xkbcommon-names.h - * header file. LED names are case-sensitive. - * - * @warning A given keymap may specify an exact index for a given LED. - * Therefore, LED indexing is not necessarily sequential, as opposed to - * modifiers and layouts. This means that when iterating over the LEDs - * in a keymap using e.g. xkb_keymap_num_leds(), some indices might be - * invalid. Given such an index, functions like xkb_keymap_led_get_name() - * will return NULL, and xkb_state_led_index_is_active() will return -1. - * - * LEDs are also called "indicators" by XKB. - * - * @sa xkb_keymap_num_leds() - */ -typedef uint32_t xkb_led_index_t; -/** A mask of LED indices. */ -typedef uint32_t xkb_led_mask_t; - -#define XKB_KEYCODE_INVALID (0xffffffff) -#define XKB_LAYOUT_INVALID (0xffffffff) -#define XKB_LEVEL_INVALID (0xffffffff) -#define XKB_MOD_INVALID (0xffffffff) -#define XKB_LED_INVALID (0xffffffff) - -#define XKB_KEYCODE_MAX (0xffffffff - 1) - -/** - * Test whether a value is a valid extended keycode. - * @sa xkb_keycode_t - **/ -#define xkb_keycode_is_legal_ext(key) (key <= XKB_KEYCODE_MAX) - -/** - * Test whether a value is a valid X11 keycode. - * @sa xkb_keycode_t - */ -#define xkb_keycode_is_legal_x11(key) (key >= 8 && key <= 255) - -/** - * Names to compile a keymap with, also known as RMLVO. - * - * The names are the common configuration values by which a user picks - * a keymap. - * - * If the entire struct is NULL, then each field is taken to be NULL. - * You should prefer passing NULL instead of choosing your own defaults. - */ -struct xkb_rule_names { - /** - * The rules file to use. The rules file describes how to interpret - * the values of the model, layout, variant and options fields. - * - * If NULL or the empty string "", a default value is used. - * If the XKB_DEFAULT_RULES environment variable is set, it is used - * as the default. Otherwise the system default is used. - */ - const char *rules; - /** - * The keyboard model by which to interpret keycodes and LEDs. - * - * If NULL or the empty string "", a default value is used. - * If the XKB_DEFAULT_MODEL environment variable is set, it is used - * as the default. Otherwise the system default is used. - */ - const char *model; - /** - * A comma separated list of layouts (languages) to include in the - * keymap. - * - * If NULL or the empty string "", a default value is used. - * If the XKB_DEFAULT_LAYOUT environment variable is set, it is used - * as the default. Otherwise the system default is used. - */ - const char *layout; - /** - * A comma separated list of variants, one per layout, which may - * modify or augment the respective layout in various ways. - * - * If NULL or the empty string "", and a default value is also used - * for the layout, a default value is used. Otherwise no variant is - * used. - * If the XKB_DEFAULT_VARIANT environment variable is set, it is used - * as the default. Otherwise the system default is used. - */ - const char *variant; - /** - * A comma separated list of options, through which the user specifies - * non-layout related preferences, like which key combinations are used - * for switching layouts, or which key is the Compose key. - * - * If NULL, a default value is used. If the empty string "", no - * options are used. - * If the XKB_DEFAULT_OPTIONS environment variable is set, it is used - * as the default. Otherwise the system default is used. - */ - const char *options; -}; - -/** - * @defgroup keysyms Keysyms - * Utility functions related to keysyms. - * - * @{ - */ - -/** - * @page keysym-transformations Keysym Transformations - * - * Keysym translation is subject to several "keysym transformations", - * as described in the XKB specification. These are: - * - * - Capitalization transformation. If the Caps Lock modifier is - * active and was not consumed by the translation process, a single - * keysym is transformed to its upper-case form (if applicable). - * Similarly, the UTF-8/UTF-32 string produced is capitalized. - * - * This is described in: - * https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Lock_Modifier - * - * - Control transformation. If the Control modifier is active and - * was not consumed by the translation process, the string produced - * is transformed to its matching ASCII control character (if - * applicable). Keysyms are not affected. - * - * This is described in: - * https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Control_Modifier - * - * Each relevant function discusses which transformations it performs. - * - * These transformations are not applicable when a key produces multiple - * keysyms. - */ - - -/** - * Get the name of a keysym. - * - * For a description of how keysyms are named, see @ref xkb_keysym_t. - * - * @param[in] keysym The keysym. - * @param[out] buffer A string buffer to write the name into. - * @param[in] size Size of the buffer. - * - * @warning If the buffer passed is too small, the string is truncated - * (though still NUL-terminated); a size of at least 64 bytes is recommended. - * - * @returns The number of bytes in the name, excluding the NUL byte. If - * the keysym is invalid, returns -1. - * - * You may check if truncation has occurred by comparing the return value - * with the length of buffer, similarly to the snprintf(3) function. - * - * @sa xkb_keysym_t - */ -int -xkb_keysym_get_name(xkb_keysym_t keysym, char *buffer, size_t size); - -/** Flags for xkb_keysym_from_name(). */ -enum xkb_keysym_flags { - /** Do not apply any flags. */ - XKB_KEYSYM_NO_FLAGS = 0, - /** Find keysym by case-insensitive search. */ - XKB_KEYSYM_CASE_INSENSITIVE = (1 << 0) -}; - -/** - * Get a keysym from its name. - * - * @param name The name of a keysym. See remarks in xkb_keysym_get_name(); - * this function will accept any name returned by that function. - * @param flags A set of flags controlling how the search is done. If - * invalid flags are passed, this will fail with XKB_KEY_NoSymbol. - * - * If you use the XKB_KEYSYM_CASE_INSENSITIVE flag and two keysym names - * differ only by case, then the lower-case keysym is returned. For - * instance, for KEY_a and KEY_A, this function would return KEY_a for the - * case-insensitive search. If this functionality is needed, it is - * recommended to first call this function without this flag; and if that - * fails, only then to try with this flag, while possibly warning the user - * he had misspelled the name, and might get wrong results. - * - * Case folding is done according to the C locale; the current locale is not - * consulted. - * - * @returns The keysym. If the name is invalid, returns XKB_KEY_NoSymbol. - * - * @sa xkb_keysym_t - */ -xkb_keysym_t -xkb_keysym_from_name(const char *name, enum xkb_keysym_flags flags); - -/** - * Get the Unicode/UTF-8 representation of a keysym. - * - * @param[in] keysym The keysym. - * @param[out] buffer A buffer to write the UTF-8 string into. - * @param[in] size The size of buffer. Must be at least 7. - * - * @returns The number of bytes written to the buffer (including the - * terminating byte). If the keysym does not have a Unicode - * representation, returns 0. If the buffer is too small, returns -1. - * - * This function does not perform any @ref keysym-transformations. - * Therefore, prefer to use xkb_state_key_get_utf8() if possible. - * - * @sa xkb_state_key_get_utf8() - */ -int -xkb_keysym_to_utf8(xkb_keysym_t keysym, char *buffer, size_t size); - -/** - * Get the Unicode/UTF-32 representation of a keysym. - * - * @returns The Unicode/UTF-32 representation of keysym, which is also - * compatible with UCS-4. If the keysym does not have a Unicode - * representation, returns 0. - * - * This function does not perform any @ref keysym-transformations. - * Therefore, prefer to use xkb_state_key_get_utf32() if possible. - * - * @sa xkb_state_key_get_utf32() - */ -uint32_t -xkb_keysym_to_utf32(xkb_keysym_t keysym); - -/** - * Convert a keysym to its uppercase form. - * - * If there is no such form, the keysym is returned unchanged. - * - * The conversion rules may be incomplete; prefer to work with the Unicode - * representation instead, when possible. - */ -xkb_keysym_t -xkb_keysym_to_upper(xkb_keysym_t ks); - -/** - * Convert a keysym to its lowercase form. - * - * The conversion rules may be incomplete; prefer to work with the Unicode - * representation instead, when possible. - */ -xkb_keysym_t -xkb_keysym_to_lower(xkb_keysym_t ks); - -/** @} */ - -/** - * @defgroup context Library Context - * Creating, destroying and using library contexts. - * - * Every keymap compilation request must have a context associated with - * it. The context keeps around state such as the include path. - * - * @{ - */ - -/** - * @page envvars Environment Variables - * - * The user may set some environment variables which affect the library: - * - * - `XKB_CONFIG_ROOT`, `HOME` - see @ref include-path. - * - `XKB_LOG_LEVEL` - see xkb_context_set_log_level(). - * - `XKB_LOG_VERBOSITY` - see xkb_context_set_log_verbosity(). - * - `XKB_DEFAULT_RULES`, `XKB_DEFAULT_MODEL`, `XKB_DEFAULT_LAYOUT`, - * `XKB_DEFAULT_VARIANT`, `XKB_DEFAULT_OPTIONS` - see xkb_rule_names. - */ - -/** Flags for context creation. */ -enum xkb_context_flags { - /** Do not apply any context flags. */ - XKB_CONTEXT_NO_FLAGS = 0, - /** Create this context with an empty include path. */ - XKB_CONTEXT_NO_DEFAULT_INCLUDES = (1 << 0), - /** - * Don't take RMLVO names from the environment. - * @since 0.3.0 - */ - XKB_CONTEXT_NO_ENVIRONMENT_NAMES = (1 << 1) -}; - -/** - * Create a new context. - * - * @param flags Optional flags for the context, or 0. - * - * @returns A new context, or NULL on failure. - * - * @memberof xkb_context - */ -struct xkb_context * -xkb_context_new(enum xkb_context_flags flags); - -/** - * Take a new reference on a context. - * - * @returns The passed in context. - * - * @memberof xkb_context - */ -struct xkb_context * -xkb_context_ref(struct xkb_context *context); - -/** - * Release a reference on a context, and possibly free it. - * - * @param context The context. If it is NULL, this function does nothing. - * - * @memberof xkb_context - */ -void -xkb_context_unref(struct xkb_context *context); - -/** - * Store custom user data in the context. - * - * This may be useful in conjunction with xkb_context_set_log_fn() or other - * callbacks. - * - * @memberof xkb_context - */ -void -xkb_context_set_user_data(struct xkb_context *context, void *user_data); - -/** - * Retrieves stored user data from the context. - * - * @returns The stored user data. If the user data wasn't set, or the - * passed in context is NULL, returns NULL. - * - * This may be useful to access private user data from callbacks like a - * custom logging function. - * - * @memberof xkb_context - **/ -void * -xkb_context_get_user_data(struct xkb_context *context); - -/** @} */ - -/** - * @defgroup include-path Include Paths - * Manipulating the include paths in a context. - * - * The include paths are the file-system paths that are searched when an - * include statement is encountered during keymap compilation. - * - * The default include paths are: - * - The system XKB root, defined at library configuration time. - * If * the `XKB_CONFIG_ROOT` environment is defined, it is used instead. - * - The path `$HOME/.xkb`, where $HOME is the value of the environment - * variable `HOME`. - * - * @{ - */ - -/** - * Append a new entry to the context's include path. - * - * @returns 1 on success, or 0 if the include path could not be added or is - * inaccessible. - * - * @memberof xkb_context - */ -int -xkb_context_include_path_append(struct xkb_context *context, const char *path); - -/** - * Append the default include paths to the context's include path. - * - * @returns 1 on success, or 0 if the primary include path could not be added. - * - * @memberof xkb_context - */ -int -xkb_context_include_path_append_default(struct xkb_context *context); - -/** - * Reset the context's include path to the default. - * - * Removes all entries from the context's include path, and inserts the - * default paths. - * - * @returns 1 on success, or 0 if the primary include path could not be added. - * - * @memberof xkb_context - */ -int -xkb_context_include_path_reset_defaults(struct xkb_context *context); - -/** - * Remove all entries from the context's include path. - * - * @memberof xkb_context - */ -void -xkb_context_include_path_clear(struct xkb_context *context); - -/** - * Get the number of paths in the context's include path. - * - * @memberof xkb_context - */ -unsigned int -xkb_context_num_include_paths(struct xkb_context *context); - -/** - * Get a specific include path from the context's include path. - * - * @returns The include path at the specified index. If the index is - * invalid, returns NULL. - * - * @memberof xkb_context - */ -const char * -xkb_context_include_path_get(struct xkb_context *context, unsigned int index); - -/** @} */ - -/** - * @defgroup logging Logging Handling - * Manipulating how logging from this library is handled. - * - * @{ - */ - -/** Specifies a logging level. */ -enum xkb_log_level { - XKB_LOG_LEVEL_CRITICAL = 10, /**< Log critical internal errors only. */ - XKB_LOG_LEVEL_ERROR = 20, /**< Log all errors. */ - XKB_LOG_LEVEL_WARNING = 30, /**< Log warnings and errors. */ - XKB_LOG_LEVEL_INFO = 40, /**< Log information, warnings, and errors. */ - XKB_LOG_LEVEL_DEBUG = 50 /**< Log everything. */ -}; - -/** - * Set the current logging level. - * - * @param context The context in which to set the logging level. - * @param level The logging level to use. Only messages from this level - * and below will be logged. - * - * The default level is XKB_LOG_LEVEL_ERROR. The environment variable - * XKB_LOG_LEVEL, if set in the time the context was created, overrides the - * default value. It may be specified as a level number or name. - * - * @memberof xkb_context - */ -void -xkb_context_set_log_level(struct xkb_context *context, - enum xkb_log_level level); - -/** - * Get the current logging level. - * - * @memberof xkb_context - */ -enum xkb_log_level -xkb_context_get_log_level(struct xkb_context *context); - -/** - * Sets the current logging verbosity. - * - * The library can generate a number of warnings which are not helpful to - * ordinary users of the library. The verbosity may be increased if more - * information is desired (e.g. when developing a new keymap). - * - * The default verbosity is 0. The environment variable XKB_LOG_VERBOSITY, - * if set in the time the context was created, overrides the default value. - * - * @param context The context in which to use the set verbosity. - * @param verbosity The verbosity to use. Currently used values are - * 1 to 10, higher values being more verbose. 0 would result in no verbose - * messages being logged. - * - * Most verbose messages are of level XKB_LOG_LEVEL_WARNING or lower. - * - * @memberof xkb_context - */ -void -xkb_context_set_log_verbosity(struct xkb_context *context, int verbosity); - -/** - * Get the current logging verbosity of the context. - * - * @memberof xkb_context - */ -int -xkb_context_get_log_verbosity(struct xkb_context *context); - -/** - * Set a custom function to handle logging messages. - * - * @param context The context in which to use the set logging function. - * @param log_fn The function that will be called for logging messages. - * Passing NULL restores the default function, which logs to stderr. - * - * By default, log messages from this library are printed to stderr. This - * function allows you to replace the default behavior with a custom - * handler. The handler is only called with messages which match the - * current logging level and verbosity settings for the context. - * level is the logging level of the message. @a format and @a args are - * the same as in the vprintf(3) function. - * - * You may use xkb_context_set_user_data() on the context, and then call - * xkb_context_get_user_data() from within the logging function to provide - * it with additional private context. - * - * @memberof xkb_context - */ -void -xkb_context_set_log_fn(struct xkb_context *context, - void (*log_fn)(struct xkb_context *context, - enum xkb_log_level level, - const char *format, va_list args)); - -/** @} */ - -/** - * @defgroup keymap Keymap Creation - * Creating and destroying keymaps. - * - * @{ - */ - -/** Flags for keymap compilation. */ -enum xkb_keymap_compile_flags { - /** Do not apply any flags. */ - XKB_KEYMAP_COMPILE_NO_FLAGS = 0 -}; - -/** - * Create a keymap from RMLVO names. - * - * The primary keymap entry point: creates a new XKB keymap from a set of - * RMLVO (Rules + Model + Layouts + Variants + Options) names. - * - * @param context The context in which to create the keymap. - * @param names The RMLVO names to use. See xkb_rule_names. - * @param flags Optional flags for the keymap, or 0. - * - * @returns A keymap compiled according to the RMLVO names, or NULL if - * the compilation failed. - * - * @sa xkb_rule_names - * @memberof xkb_keymap - */ -struct xkb_keymap * -xkb_keymap_new_from_names(struct xkb_context *context, - const struct xkb_rule_names *names, - enum xkb_keymap_compile_flags flags); - -/** The possible keymap formats. */ -enum xkb_keymap_format { - /** The current/classic XKB text format, as generated by xkbcomp -xkb. */ - XKB_KEYMAP_FORMAT_TEXT_V1 = 1 -}; - -/** - * Create a keymap from a keymap file. - * - * @param context The context in which to create the keymap. - * @param file The keymap file to compile. - * @param format The text format of the keymap file to compile. - * @param flags Optional flags for the keymap, or 0. - * - * @returns A keymap compiled from the given XKB keymap file, or NULL if - * the compilation failed. - * - * The file must contain a complete keymap. For example, in the - * XKB_KEYMAP_FORMAT_TEXT_V1 format, this means the file must contain one - * top level '%xkb_keymap' section, which in turn contains other required - * sections. - * - * @memberof xkb_keymap - */ -struct xkb_keymap * -xkb_keymap_new_from_file(struct xkb_context *context, FILE *file, - enum xkb_keymap_format format, - enum xkb_keymap_compile_flags flags); - -/** - * Create a keymap from a keymap string. - * - * This is just like xkb_keymap_new_from_file(), but instead of a file, gets - * the keymap as one enormous string. - * - * @see xkb_keymap_new_from_file() - * @memberof xkb_keymap - */ -struct xkb_keymap * -xkb_keymap_new_from_string(struct xkb_context *context, const char *string, - enum xkb_keymap_format format, - enum xkb_keymap_compile_flags flags); - -/** - * Create a keymap from a memory buffer. - * - * This is just like xkb_keymap_new_from_string(), but takes a length argument - * so the input string does not have to be zero-terminated. - * - * @see xkb_keymap_new_from_string() - * @memberof xkb_keymap - * @since 0.3.0 - */ -struct xkb_keymap * -xkb_keymap_new_from_buffer(struct xkb_context *context, const char *buffer, - size_t length, enum xkb_keymap_format format, - enum xkb_keymap_compile_flags flags); - -/** - * Take a new reference on a keymap. - * - * @returns The passed in keymap. - * - * @memberof xkb_keymap - */ -struct xkb_keymap * -xkb_keymap_ref(struct xkb_keymap *keymap); - -/** - * Release a reference on a keymap, and possibly free it. - * - * @param keymap The keymap. If it is NULL, this function does nothing. - * - * @memberof xkb_keymap - */ -void -xkb_keymap_unref(struct xkb_keymap *keymap); - -/** - * Get the keymap as a string in the format from which it was created. - * @sa xkb_keymap_get_as_string() - **/ -#define XKB_KEYMAP_USE_ORIGINAL_FORMAT ((enum xkb_keymap_format) -1) - -/** - * Get the compiled keymap as a string. - * - * @param keymap The keymap to get as a string. - * @param format The keymap format to use for the string. You can pass - * in the special value XKB_KEYMAP_USE_ORIGINAL_FORMAT to use the format - * from which the keymap was originally created. - * - * @returns The keymap as a NUL-terminated string, or NULL if unsuccessful. - * - * The returned string may be fed back into xkb_keymap_new_from_string() to get - * the exact same keymap (possibly in another process, etc.). - * - * The returned string is dynamically allocated and should be freed by the - * caller. - * - * @memberof xkb_keymap - */ -char * -xkb_keymap_get_as_string(struct xkb_keymap *keymap, - enum xkb_keymap_format format); - -/** @} */ - -/** - * @defgroup components Keymap Components - * Enumeration of state components in a keymap. - * - * @{ - */ - -/** - * Get the minimum keycode in the keymap. - * - * @sa xkb_keycode_t - * @memberof xkb_keymap - * @since 0.3.1 - */ -xkb_keycode_t -xkb_keymap_min_keycode(struct xkb_keymap *keymap); - -/** - * Get the maximum keycode in the keymap. - * - * @sa xkb_keycode_t - * @memberof xkb_keymap - * @since 0.3.1 - */ -xkb_keycode_t -xkb_keymap_max_keycode(struct xkb_keymap *keymap); - -/** - * The iterator used by xkb_keymap_key_for_each(). - * - * @sa xkb_keymap_key_for_each - * @memberof xkb_keymap - * @since 0.3.1 - */ -typedef void -(*xkb_keymap_key_iter_t)(struct xkb_keymap *keymap, xkb_keycode_t key, - void *data); - -/** - * Run a specified function for every valid keycode in the keymap. If a - * keymap is sparse, this function may be called fewer than - * (max_keycode - min_keycode + 1) times. - * - * @sa xkb_keymap_min_keycode() xkb_keymap_max_keycode() xkb_keycode_t - * @memberof xkb_keymap - * @since 0.3.1 - */ -void -xkb_keymap_key_for_each(struct xkb_keymap *keymap, xkb_keymap_key_iter_t iter, - void *data); - -/** - * Find the name of the key with the given keycode. - * - * This function always returns the canonical name of the key (see - * description in xkb_keycode_t). - * - * @returns The key name. If no key with this keycode exists, - * returns NULL. - * - * @sa xkb_keycode_t - * @memberof xkb_keymap - * @since 0.6.0 - */ -const char * -xkb_keymap_key_get_name(struct xkb_keymap *keymap, xkb_keycode_t key); - -/** - * Find the keycode of the key with the given name. - * - * The name can be either a canonical name or an alias. - * - * @returns The keycode. If no key with this name exists, - * returns XKB_KEYCODE_INVALID. - * - * @sa xkb_keycode_t - * @memberof xkb_keymap - * @since 0.6.0 - */ -xkb_keycode_t -xkb_keymap_key_by_name(struct xkb_keymap *keymap, const char *name); - -/** - * Get the number of modifiers in the keymap. - * - * @sa xkb_mod_index_t - * @memberof xkb_keymap - */ -xkb_mod_index_t -xkb_keymap_num_mods(struct xkb_keymap *keymap); - -/** - * Get the name of a modifier by index. - * - * @returns The name. If the index is invalid, returns NULL. - * - * @sa xkb_mod_index_t - * @memberof xkb_keymap - */ -const char * -xkb_keymap_mod_get_name(struct xkb_keymap *keymap, xkb_mod_index_t idx); - -/** - * Get the index of a modifier by name. - * - * @returns The index. If no modifier with this name exists, returns - * XKB_MOD_INVALID. - * - * @sa xkb_mod_index_t - * @memberof xkb_keymap - */ -xkb_mod_index_t -xkb_keymap_mod_get_index(struct xkb_keymap *keymap, const char *name); - -/** - * Get the number of layouts in the keymap. - * - * @sa xkb_layout_index_t xkb_rule_names xkb_keymap_num_layouts_for_key() - * @memberof xkb_keymap - */ -xkb_layout_index_t -xkb_keymap_num_layouts(struct xkb_keymap *keymap); - -/** - * Get the name of a layout by index. - * - * @returns The name. If the index is invalid, or the layout does not have - * a name, returns NULL. - * - * @sa xkb_layout_index_t - * @memberof xkb_keymap - */ -const char * -xkb_keymap_layout_get_name(struct xkb_keymap *keymap, xkb_layout_index_t idx); - -/** - * Get the index of a layout by name. - * - * @returns The index. If no layout exists with this name, returns - * XKB_LAYOUT_INVALID. If more than one layout in the keymap has this name, - * returns the lowest index among them. - * - * @memberof xkb_keymap - */ -xkb_layout_index_t -xkb_keymap_layout_get_index(struct xkb_keymap *keymap, const char *name); - -/** - * Get the number of LEDs in the keymap. - * - * @warning The range [ 0...xkb_keymap_num_leds() ) includes all of the LEDs - * in the keymap, but may also contain inactive LEDs. When iterating over - * this range, you need the handle this case when calling functions such as - * xkb_keymap_led_get_name() or xkb_state_led_index_is_active(). - * - * @sa xkb_led_index_t - * @memberof xkb_keymap - */ -xkb_led_index_t -xkb_keymap_num_leds(struct xkb_keymap *keymap); - -/** - * Get the name of a LED by index. - * - * @returns The name. If the index is invalid, returns NULL. - * - * @memberof xkb_keymap - */ -const char * -xkb_keymap_led_get_name(struct xkb_keymap *keymap, xkb_led_index_t idx); - -/** - * Get the index of a LED by name. - * - * @returns The index. If no LED with this name exists, returns - * XKB_LED_INVALID. - * - * @memberof xkb_keymap - */ -xkb_led_index_t -xkb_keymap_led_get_index(struct xkb_keymap *keymap, const char *name); - -/** - * Get the number of layouts for a specific key. - * - * This number can be different from xkb_keymap_num_layouts(), but is always - * smaller. It is the appropriate value to use when iterating over the - * layouts of a key. - * - * @sa xkb_layout_index_t - * @memberof xkb_keymap - */ -xkb_layout_index_t -xkb_keymap_num_layouts_for_key(struct xkb_keymap *keymap, xkb_keycode_t key); - -/** - * Get the number of shift levels for a specific key and layout. - * - * If @c layout is out of range for this key (that is, larger or equal to - * the value returned by xkb_keymap_num_layouts_for_key()), it is brought - * back into range in a manner consistent with xkb_state_key_get_layout(). - * - * @sa xkb_level_index_t - * @memberof xkb_keymap - */ -xkb_level_index_t -xkb_keymap_num_levels_for_key(struct xkb_keymap *keymap, xkb_keycode_t key, - xkb_layout_index_t layout); - -/** - * Get the keysyms obtained from pressing a key in a given layout and - * shift level. - * - * This function is like xkb_state_key_get_syms(), only the layout and - * shift level are not derived from the keyboard state but are instead - * specified explicitly. - * - * @param[in] keymap The keymap. - * @param[in] key The keycode of the key. - * @param[in] layout The layout for which to get the keysyms. - * @param[in] level The shift level in the layout for which to get the - * keysyms. This must be smaller than: - * @code xkb_keymap_num_levels_for_key(keymap, key) @endcode - * @param[out] syms_out An immutable array of keysyms corresponding to the - * key in the given layout and shift level. - * - * If @c layout is out of range for this key (that is, larger or equal to - * the value returned by xkb_keymap_num_layouts_for_key()), it is brought - * back into range in a manner consistent with xkb_state_key_get_layout(). - * - * @returns The number of keysyms in the syms_out array. If no keysyms - * are produced by the key in the given layout and shift level, returns 0 - * and sets syms_out to NULL. - * - * @sa xkb_state_key_get_syms() - * @memberof xkb_keymap - */ -int -xkb_keymap_key_get_syms_by_level(struct xkb_keymap *keymap, - xkb_keycode_t key, - xkb_layout_index_t layout, - xkb_level_index_t level, - const xkb_keysym_t **syms_out); - -/** - * Determine whether a key should repeat or not. - * - * A keymap may specify different repeat behaviors for different keys. - * Most keys should generally exhibit repeat behavior; for example, holding - * the 'a' key down in a text editor should normally insert a single 'a' - * character every few milliseconds, until the key is released. However, - * there are keys which should not or do not need to be repeated. For - * example, repeating modifier keys such as Left/Right Shift or Caps Lock - * is not generally useful or desired. - * - * @returns 1 if the key should repeat, 0 otherwise. - * - * @memberof xkb_keymap - */ -int -xkb_keymap_key_repeats(struct xkb_keymap *keymap, xkb_keycode_t key); - -/** @} */ - -/** - * @defgroup state Keyboard State - * Creating, destroying and manipulating keyboard state objects. - * - * @{ - */ - -/** - * Create a new keyboard state object. - * - * @param keymap The keymap which the state will use. - * - * @returns A new keyboard state object, or NULL on failure. - * - * @memberof xkb_state - */ -struct xkb_state * -xkb_state_new(struct xkb_keymap *keymap); - -/** - * Take a new reference on a keyboard state object. - * - * @returns The passed in object. - * - * @memberof xkb_state - */ -struct xkb_state * -xkb_state_ref(struct xkb_state *state); - -/** - * Release a reference on a keybaord state object, and possibly free it. - * - * @param state The state. If it is NULL, this function does nothing. - * - * @memberof xkb_state - */ -void -xkb_state_unref(struct xkb_state *state); - -/** - * Get the keymap which a keyboard state object is using. - * - * @returns The keymap which was passed to xkb_state_new() when creating - * this state object. - * - * This function does not take a new reference on the keymap; you must - * explicitly reference it yourself if you plan to use it beyond the - * lifetime of the state. - * - * @memberof xkb_state - */ -struct xkb_keymap * -xkb_state_get_keymap(struct xkb_state *state); - -/** Specifies the direction of the key (press / release). */ -enum xkb_key_direction { - XKB_KEY_UP, /**< The key was released. */ - XKB_KEY_DOWN /**< The key was pressed. */ -}; - -/** - * Modifier and layout types for state objects. This enum is bitmaskable, - * e.g. (XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED) is valid to - * exclude locked modifiers. - * - * In XKB, the DEPRESSED components are also known as 'base'. - */ -enum xkb_state_component { - /** Depressed modifiers, i.e. a key is physically holding them. */ - XKB_STATE_MODS_DEPRESSED = (1 << 0), - /** Latched modifiers, i.e. will be unset after the next non-modifier - * key press. */ - XKB_STATE_MODS_LATCHED = (1 << 1), - /** Locked modifiers, i.e. will be unset after the key provoking the - * lock has been pressed again. */ - XKB_STATE_MODS_LOCKED = (1 << 2), - /** Effective modifiers, i.e. currently active and affect key - * processing (derived from the other state components). - * Use this unless you explictly care how the state came about. */ - XKB_STATE_MODS_EFFECTIVE = (1 << 3), - /** Depressed layout, i.e. a key is physically holding it. */ - XKB_STATE_LAYOUT_DEPRESSED = (1 << 4), - /** Latched layout, i.e. will be unset after the next non-modifier - * key press. */ - XKB_STATE_LAYOUT_LATCHED = (1 << 5), - /** Locked layout, i.e. will be unset after the key provoking the lock - * has been pressed again. */ - XKB_STATE_LAYOUT_LOCKED = (1 << 6), - /** Effective layout, i.e. currently active and affects key processing - * (derived from the other state components). - * Use this unless you explictly care how the state came about. */ - XKB_STATE_LAYOUT_EFFECTIVE = (1 << 7), - /** LEDs (derived from the other state components). */ - XKB_STATE_LEDS = (1 << 8) -}; - -/** - * Update the keyboard state to reflect a given key being pressed or - * released. - * - * This entry point is intended for programs which track the keyboard state - * explictly (like an evdev client). If the state is serialized to you by - * a master process (like a Wayland compositor) using functions like - * xkb_state_serialize_mods(), you should use xkb_state_update_mask() instead. - * The two functins should not generally be used together. - * - * A series of calls to this function should be consistent; that is, a call - * with XKB_KEY_DOWN for a key should be matched by an XKB_KEY_UP; if a key - * is pressed twice, it should be released twice; etc. Otherwise (e.g. due - * to missed input events), situations like "stuck modifiers" may occur. - * - * This function is often used in conjunction with the function - * xkb_state_key_get_syms() (or xkb_state_key_get_one_sym()), for example, - * when handling a key event. In this case, you should prefer to get the - * keysyms *before* updating the key, such that the keysyms reported for - * the key event are not affected by the event itself. This is the - * conventional behavior. - * - * @returns A mask of state components that have changed as a result of - * the update. If nothing in the state has changed, returns 0. - * - * @memberof xkb_state - * - * @sa xkb_state_update_mask() - */ -enum xkb_state_component -xkb_state_update_key(struct xkb_state *state, xkb_keycode_t key, - enum xkb_key_direction direction); - -/** - * Update a keyboard state from a set of explicit masks. - * - * This entry point is intended for window systems and the like, where a - * master process holds an xkb_state, then serializes it over a wire - * protocol, and clients then use the serialization to feed in to their own - * xkb_state. - * - * All parameters must always be passed, or the resulting state may be - * incoherent. - * - * The serialization is lossy and will not survive round trips; it must only - * be used to feed slave state objects, and must not be used to update the - * master state. - * - * If you do not fit the description above, you should use - * xkb_state_update_key() instead. The two functions should not generally be - * used together. - * - * @returns A mask of state components that have changed as a result of - * the update. If nothing in the state has changed, returns 0. - * - * @memberof xkb_state - * - * @sa xkb_state_component - * @sa xkb_state_update_key - */ -enum xkb_state_component -xkb_state_update_mask(struct xkb_state *state, - xkb_mod_mask_t depressed_mods, - xkb_mod_mask_t latched_mods, - xkb_mod_mask_t locked_mods, - xkb_layout_index_t depressed_layout, - xkb_layout_index_t latched_layout, - xkb_layout_index_t locked_layout); - -/** - * Get the keysyms obtained from pressing a particular key in a given - * keyboard state. - * - * Get the keysyms for a key according to the current active layout, - * modifiers and shift level for the key, as determined by a keyboard - * state. - * - * @param[in] state The keyboard state object. - * @param[in] key The keycode of the key. - * @param[out] syms_out An immutable array of keysyms corresponding the - * key in the given keyboard state. - * - * As an extension to XKB, this function can return more than one keysym. - * If you do not want to handle this case, you can use - * xkb_state_key_get_one_sym() for a simpler interface. - * - * This function does not perform any @ref keysym-transformations. - * (This might change). - * - * @returns The number of keysyms in the syms_out array. If no keysyms - * are produced by the key in the given keyboard state, returns 0 and sets - * syms_out to NULL. - * - * @memberof xkb_state - */ -int -xkb_state_key_get_syms(struct xkb_state *state, xkb_keycode_t key, - const xkb_keysym_t **syms_out); - -/** - * Get the Unicode/UTF-8 string obtained from pressing a particular key - * in a given keyboard state. - * - * @param[in] state The keyboard state object. - * @param[in] key The keycode of the key. - * @param[out] buffer A buffer to write the string into. - * @param[in] size Size of the buffer. - * - * @warning If the buffer passed is too small, the string is truncated - * (though still NUL-terminated). - * - * @returns The number of bytes required for the string, excluding the - * NUL byte. If there is nothing to write, returns 0. - * - * You may check if truncation has occurred by comparing the return value - * with the size of @p buffer, similarly to the snprintf(3) function. - * You may safely pass NULL and 0 to @p buffer and @p size to find the - * required size (without the NUL-byte). - * - * This function performs Capitalization and Control @ref - * keysym-transformations. - * - * @memberof xkb_state - * @since 0.4.1 - */ -int -xkb_state_key_get_utf8(struct xkb_state *state, xkb_keycode_t key, - char *buffer, size_t size); - -/** - * Get the Unicode/UTF-32 codepoint obtained from pressing a particular - * key in a a given keyboard state. - * - * @returns The UTF-32 representation for the key, if it consists of only - * a single codepoint. Otherwise, returns 0. - * - * This function performs Capitalization and Control @ref - * keysym-transformations. - * - * @memberof xkb_state - * @since 0.4.1 - */ -uint32_t -xkb_state_key_get_utf32(struct xkb_state *state, xkb_keycode_t key); - -/** - * Get the single keysym obtained from pressing a particular key in a - * given keyboard state. - * - * This function is similar to xkb_state_key_get_syms(), but intended - * for users which cannot or do not want to handle the case where - * multiple keysyms are returned (in which case this function is - * preferred). - * - * @returns The keysym. If the key does not have exactly one keysym, - * returns XKB_KEY_NoSymbol - * - * This function performs Capitalization @ref keysym-transformations. - * - * @sa xkb_state_key_get_syms() - * @memberof xkb_state - */ -xkb_keysym_t -xkb_state_key_get_one_sym(struct xkb_state *state, xkb_keycode_t key); - -/** - * Get the effective layout index for a key in a given keyboard state. - * - * @returns The layout index for the key in the given keyboard state. If - * the given keycode is invalid, or if the key is not included in any - * layout at all, returns XKB_LAYOUT_INVALID. - * - * @invariant If the returned layout is valid, the following always holds: - * @code - * xkb_state_key_get_layout(state, key) < xkb_keymap_num_layouts_for_key(keymap, key) - * @endcode - * - * @memberof xkb_state - */ -xkb_layout_index_t -xkb_state_key_get_layout(struct xkb_state *state, xkb_keycode_t key); - -/** - * Get the effective shift level for a key in a given keyboard state and - * layout. - * - * @param state The keyboard state. - * @param key The keycode of the key. - * @param layout The layout for which to get the shift level. This must be - * smaller than: - * @code xkb_keymap_num_layouts_for_key(keymap, key) @endcode - * usually it would be: - * @code xkb_state_key_get_layout(state, key) @endcode - * - * @return The shift level index. If the key or layout are invalid, - * returns XKB_LEVEL_INVALID. - * - * @invariant If the returned level is valid, the following always holds: - * @code - * xkb_state_key_get_level(state, key, layout) < xkb_keymap_num_levels_for_key(keymap, key, layout) - * @endcode - * - * @memberof xkb_state - */ -xkb_level_index_t -xkb_state_key_get_level(struct xkb_state *state, xkb_keycode_t key, - xkb_layout_index_t layout); - -/** - * Match flags for xkb_state_mod_indices_are_active() and - * xkb_state_mod_names_are_active(), specifying the conditions for a - * successful match. XKB_STATE_MATCH_NON_EXCLUSIVE is bitmaskable with - * the other modes. - */ -enum xkb_state_match { - /** Returns true if any of the modifiers are active. */ - XKB_STATE_MATCH_ANY = (1 << 0), - /** Returns true if all of the modifiers are active. */ - XKB_STATE_MATCH_ALL = (1 << 1), - /** Makes matching non-exclusive, i.e. will not return false if a - * modifier not specified in the arguments is active. */ - XKB_STATE_MATCH_NON_EXCLUSIVE = (1 << 16) -}; - -/** - * The counterpart to xkb_state_update_mask for modifiers, to be used on - * the server side of serialization. - * - * @param state The keyboard state. - * @param components A mask of the modifier state components to serialize. - * State components other than XKB_STATE_MODS_* are ignored. - * If XKB_STATE_MODS_EFFECTIVE is included, all other state components are - * ignored. - * - * @returns A xkb_mod_mask_t representing the given components of the - * modifier state. - * - * This function should not be used in regular clients; please use the - * xkb_state_mod_*_is_active API instead. - * - * @memberof xkb_state - */ -xkb_mod_mask_t -xkb_state_serialize_mods(struct xkb_state *state, - enum xkb_state_component components); - -/** - * The counterpart to xkb_state_update_mask for layouts, to be used on - * the server side of serialization. - * - * @param state The keyboard state. - * @param components A mask of the layout state components to serialize. - * State components other than XKB_STATE_LAYOUT_* are ignored. - * If XKB_STATE_LAYOUT_EFFECTIVE is included, all other state components are - * ignored. - * - * @returns A layout index representing the given components of the - * layout state. - * - * This function should not be used in regular clients; please use the - * xkb_state_layout_*_is_active API instead. - * - * @memberof xkb_state - */ -xkb_layout_index_t -xkb_state_serialize_layout(struct xkb_state *state, - enum xkb_state_component components); - -/** - * Test whether a modifier is active in a given keyboard state by name. - * - * @returns 1 if the modifier is active, 0 if it is not. If the modifier - * name does not exist in the keymap, returns -1. - * - * @memberof xkb_state - */ -int -xkb_state_mod_name_is_active(struct xkb_state *state, const char *name, - enum xkb_state_component type); - -/** - * Test whether a set of modifiers are active in a given keyboard state by - * name. - * - * @param state The keyboard state. - * @param type The component of the state against which to match the - * given modifiers. - * @param match The manner by which to match the state against the - * given modifiers. - * @param ... The set of of modifier names to test, terminated by a NULL - * argument (sentinel). - * - * @returns 1 if the modifiers are active, 0 if they are not. If any of - * the modifier names do not exist in the keymap, returns -1. - * - * @memberof xkb_state - */ -int -xkb_state_mod_names_are_active(struct xkb_state *state, - enum xkb_state_component type, - enum xkb_state_match match, - ...); - -/** - * Test whether a modifier is active in a given keyboard state by index. - * - * @returns 1 if the modifier is active, 0 if it is not. If the modifier - * index is invalid in the keymap, returns -1. - * - * @memberof xkb_state - */ -int -xkb_state_mod_index_is_active(struct xkb_state *state, xkb_mod_index_t idx, - enum xkb_state_component type); - -/** - * Test whether a set of modifiers are active in a given keyboard state by - * index. - * - * @param state The keyboard state. - * @param type The component of the state against which to match the - * given modifiers. - * @param match The manner by which to match the state against the - * given modifiers. - * @param ... The set of of modifier indices to test, terminated by a - * XKB_MOD_INVALID argument (sentinel). - * - * @returns 1 if the modifiers are active, 0 if they are not. If any of - * the modifier indices are invalid in the keymap, returns -1. - * - * @memberof xkb_state - */ -int -xkb_state_mod_indices_are_active(struct xkb_state *state, - enum xkb_state_component type, - enum xkb_state_match match, - ...); - -/** - * @page consumed-modifiers Consumed Modifiers - * @parblock - * - * Some functions, like xkb_state_key_get_syms(), look at the state of - * the modifiers in the keymap and derive from it the correct shift level - * to use for the key. For example, in a US layout, pressing the key - * labeled \ while the Shift modifier is active, generates the keysym - * 'A'. In this case, the Shift modifier is said to be "consumed". - * However, the Num Lock modifier does not affect this translation at all, - * even if it is active, so it is not consumed by this translation. - * - * It may be desirable for some application to not reuse consumed modifiers - * for further processing, e.g. for hotkeys or keyboard shortcuts. To - * understand why, consider some requirements from a standard shortcut - * mechanism, and how they are implemented: - * - * 1. The shortcut's modifiers must match exactly to the state. For - * example, it is possible to bind separate actions to \\ - * and to \\\. Further, if only \\ is - * bound to an action, pressing \\\ should not - * trigger the shortcut. - * Effectively, this means that the modifiers are compared using the - * equality operator (==). - * - * 2. Only relevant modifiers are considered for the matching. For example, - * Caps Lock and Num Lock should not generally affect the matching, e.g. - * when matching \\ against the state, it does not matter - * whether Num Lock is active or not. These relevant, or "significant", - * modifiers usually include Alt, Control, Shift, Super and similar. - * Effectively, this means that non-significant modifiers are masked out, - * before doing the comparison as described above. - * - * 3. The matching must be independent of the layout/keymap. For example, - * the \ (+) symbol is found on the first level on some layouts, - * but requires holding Shift on others. If you simply bind the action - * to the \ keysym, it would work for the unshifted kind, but - * not for the others, because the match against Shift would fail. If - * you bind the action to \\, only the shifted kind would - * work. So what is needed is to recognize that Shift is used up in the - * translation of the keysym itself, and therefore should not be included - * in the matching. - * Effectively, this means that consumed modifiers (Shift in this example) - * are masked out as well, before doing the comparison. - * - * In summary, this is approximately how the matching would be performed: - * @code - * (keysym == shortcut_keysym) && - * ((state_mods & ~consumed_mods & significant_mods) == shortcut_mods) - * @endcode - * - * @c state_mods are the modifiers reported by - * xkb_state_mod_index_is_active() and similar functions. - * @c consumed_mods are the modifiers reported by - * xkb_state_mod_index_is_consumed() and similar functions. - * @c significant_mods are decided upon by the application/toolkit/user; - * it is up to them to decide whether these are configurable or hard-coded. - * - * @endparblock - */ - -/** - * Consumed modifiers mode. - * - * There are several possible methods for deciding which modifiers are - * consumed and which are not, each applicable for different systems or - * situations. The mode selects the method to use. - * - * Keep in mind that in all methods, the keymap may decide to "preserve" - * a modifier, meaning it is not reported as consumed even if it would - * have otherwise. - */ -enum xkb_consumed_mode { - /** - * This is the mode defined in the XKB specification and used by libX11. - * - * A modifier is consumed if and only if it *may affect* key translation. - * - * For example, if `Control+Alt+` produces some assigned keysym, - * then when pressing just ``, `Control` and `Alt` are consumed, - * even though they are not active, since if they *were* active they would - * have affected key translation. - */ - XKB_CONSUMED_MODE_XKB, - /** - * This is the mode used by the GTK+ toolkit. - * - * The mode consists of the following two independent heuristics: - * - * - The currently active set of modifiers, excluding modifiers which do - * not affect the key (as described for @ref XKB_CONSUMED_MODE_XKB), are - * considered consumed, if the keysyms produced when all of them are - * active are different from the keysyms produced when no modifiers are - * active. - * - * - A single modifier is considered consumed if the keysyms produced for - * the key when it is the only active modifier are different from the - * keysyms produced when no modifiers are active. - */ - XKB_CONSUMED_MODE_GTK -}; - -/** - * Get the mask of modifiers consumed by translating a given key. - * - * @param state The keyboard state. - * @param key The keycode of the key. - * @param mode The consumed modifiers mode to use; see enum description. - * - * @returns a mask of the consumed modifiers. - * - * @memberof xkb_state - * @since 0.7.0 - */ -xkb_mod_mask_t -xkb_state_key_get_consumed_mods2(struct xkb_state *state, xkb_keycode_t key, - enum xkb_consumed_mode mode); - -/** - * Same as xkb_state_key_get_consumed_mods2() with mode XKB_CONSUMED_MODE_XKB. - * - * @memberof xkb_state - * @since 0.4.1 - */ -xkb_mod_mask_t -xkb_state_key_get_consumed_mods(struct xkb_state *state, xkb_keycode_t key); - -/** - * Test whether a modifier is consumed by keyboard state translation for - * a key. - * - * @param state The keyboard state. - * @param key The keycode of the key. - * @param idx The index of the modifier to check. - * @param mode The consumed modifiers mode to use; see enum description. - * - * @returns 1 if the modifier is consumed, 0 if it is not. If the modifier - * index is not valid in the keymap, returns -1. - * - * @sa xkb_state_mod_mask_remove_consumed() - * @sa xkb_state_key_get_consumed_mods() - * @memberof xkb_state - * @since 0.7.0 - */ -int -xkb_state_mod_index_is_consumed2(struct xkb_state *state, - xkb_keycode_t key, - xkb_mod_index_t idx, - enum xkb_consumed_mode mode); - -/** - * Same as xkb_state_mod_index_is_consumed2() with mode XKB_CONSUMED_MOD_XKB. - * - * @memberof xkb_state - * @since 0.4.1 - */ -int -xkb_state_mod_index_is_consumed(struct xkb_state *state, xkb_keycode_t key, - xkb_mod_index_t idx); - -/** - * Remove consumed modifiers from a modifier mask for a key. - * - * @deprecated Use xkb_state_key_get_consumed_mods2() instead. - * - * Takes the given modifier mask, and removes all modifiers which are - * consumed for that particular key (as in xkb_state_mod_index_is_consumed()). - * - * @sa xkb_state_mod_index_is_consumed() - * @memberof xkb_state - */ -xkb_mod_mask_t -xkb_state_mod_mask_remove_consumed(struct xkb_state *state, xkb_keycode_t key, - xkb_mod_mask_t mask); - -/** - * Test whether a layout is active in a given keyboard state by name. - * - * @returns 1 if the layout is active, 0 if it is not. If no layout with - * this name exists in the keymap, return -1. - * - * If multiple layouts in the keymap have this name, the one with the lowest - * index is tested. - * - * @sa xkb_layout_index_t - * @memberof xkb_state - */ -int -xkb_state_layout_name_is_active(struct xkb_state *state, const char *name, - enum xkb_state_component type); - -/** - * Test whether a layout is active in a given keyboard state by index. - * - * @returns 1 if the layout is active, 0 if it is not. If the layout index - * is not valid in the keymap, returns -1. - * - * @sa xkb_layout_index_t - * @memberof xkb_state - */ -int -xkb_state_layout_index_is_active(struct xkb_state *state, - xkb_layout_index_t idx, - enum xkb_state_component type); - -/** - * Test whether a LED is active in a given keyboard state by name. - * - * @returns 1 if the LED is active, 0 if it not. If no LED with this name - * exists in the keymap, returns -1. - * - * @sa xkb_led_index_t - * @memberof xkb_state - */ -int -xkb_state_led_name_is_active(struct xkb_state *state, const char *name); - -/** - * Test whether a LED is active in a given keyboard state by index. - * - * @returns 1 if the LED is active, 0 if it not. If the LED index is not - * valid in the keymap, returns -1. - * - * @sa xkb_led_index_t - * @memberof xkb_state - */ -int -xkb_state_led_index_is_active(struct xkb_state *state, xkb_led_index_t idx); - -/** @} */ - -/* Leave this include last, so it can pick up our types, etc. */ -#include - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* _XKBCOMMON_H_ */ diff --git a/src/gui/configure.json b/src/gui/configure.json index 0332631ec8..590e52d258 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -46,9 +46,7 @@ "xcb-xlib": "boolean", "xcb-xinput": "boolean", "xkb": "boolean", - "xkbcommon": { "type": "enum", "values": [ "no", "qt", "system" ] }, - "xkbcommon-evdev": "boolean", - "xkbcommon-x11": { "type": "enum", "name": "xkbcommon", "values": [ "no", "qt", "system" ] } + "xkbcommon": "boolean" } }, @@ -606,21 +604,33 @@ ] }, "xkbcommon": { - "label": "xkbcommon", - "export": "xkbcommon_evdev", + "label": "xkbcommon >= 0.5.0", "test": { - "include": [ "xkbcommon/xkbcommon.h", "xkbcommon/xkbcommon-keysyms.h", "xkbcommon/xkbcommon-names.h" ], + "include": [ "xkbcommon/xkbcommon.h" ], "main": "xkb_context_new(XKB_CONTEXT_NO_FLAGS);" }, "sources": [ - { "type": "pkgConfig", "args": "xkbcommon" } + { "type": "pkgConfig", "args": "xkbcommon >= 0.5.0" } ] }, "xkbcommon_x11": { - "label": "xkbcommon-x11 >= 0.4.1", - "export": "xkbcommon", + "label": "xkbcommon-x11", + "test": { + "include": [ "xkbcommon/xkbcommon-x11.h" ], + "main": "xkb_x11_get_core_keyboard_device_id(nullptr);" + }, "sources": [ - { "type": "pkgConfig", "args": "xkbcommon xkbcommon-x11 >= 0.4.1" } + { "type": "pkgConfig", "args": "xkbcommon-x11" } + ] + }, + "xkbcommon_evdev": { + "label": "xkbcommon_evdev TRANSITION HACK", + "test": { + "include": [ "xkbcommon/xkbcommon.h" ], + "main": "xkb_context_new(XKB_CONTEXT_NO_FLAGS);" + }, + "sources": [ + { "type": "pkgConfig", "args": "xkbcommon >= 0.5.0" } ] }, "xrender": { @@ -1091,7 +1101,7 @@ "label": "Mir client", "section": "Platform plugins", "autoDetect": false, - "condition": "libs.mirclient", + "condition": "libs.mirclient && features.xkbcommon", "output": [ "privateFeature" ] }, "mtdev": { @@ -1304,7 +1314,7 @@ "section": "Platform plugins", "autoDetect": "!config.darwin", "enable": "input.xcb == 'system' || input.xcb == 'qt' || input.xcb == 'yes'", - "condition": "features.thread && libs.xcb", + "condition": "features.thread && features.xkbcommon && libs.xcb", "output": [ "privateFeature" ] }, "system-xcb": { @@ -1347,7 +1357,7 @@ "xkb": { "label": "XCB XKB", "emitIf": "features.xcb", - "condition": "!features.system-xcb || libs.xcb_xkb", + "condition": "(!features.system-xcb || libs.xcb_xkb) && libs.xkbcommon_x11", "output": [ "privateFeature" ] }, "xcb-xlib": { @@ -1368,17 +1378,14 @@ "condition": "!features.system-xcb || libs.xcb_xinput", "output": [ "privateFeature" ] }, - "xkbcommon-evdev": { - "label": "xkbcommon-evdev", + "xkbcommon": { + "label": "xkbcommon", "condition": "libs.xkbcommon", "output": [ "privateFeature" ] }, - "xkbcommon-system": { - "label": "Using system-provided xkbcommon", - "emitIf": "features.xcb", - "enable": "input.xkbcommon == 'system'", - "disable": "input.xkbcommon == 'qt' || input.xkbcommon == 'no'", - "condition": "libs.xkbcommon_x11", + "xkbcommon-evdev": { + "label": "xkbcommon-evdev TRANSITION HACK", + "condition": "libs.xkbcommon_evdev", "output": [ "privateFeature" ] }, "xlib": { @@ -1594,7 +1601,7 @@ { "type": "error", "condition": "input.xcb != '' && input.xcb != 'no' && input.xkbcommon == 'no'", - "message": "XCB plugin requires libxkbcommon. See -qt-xkbcommon-x11 and -system-xkbcommon-x11." + "message": "XCB plugin requires xkbcommon, but -no-xkbcommon was provided." } ], @@ -1705,7 +1712,7 @@ QMAKE_LIBDIR_OPENGL[_ES2] and QMAKE_LIBS_OPENGL[_ES2] in the mkspec for your pla "integrityhid", "mtdev", "tslib", - "xkbcommon-evdev" + "xkbcommon" ] }, { @@ -1736,7 +1743,7 @@ QMAKE_LIBDIR_OPENGL[_ES2] and QMAKE_LIBS_OPENGL[_ES2] in the mkspec for your pla "section": "X11", "condition": "features.xcb", "entries": [ - "system-xcb", "egl_x11", "xkb", "xlib", "xcb-render", "xcb-glx", "xcb-xinput", "xcb-xlib", "xkbcommon-system", "xcb-native-painting" + "system-xcb", "egl_x11", "xkb", "xlib", "xcb-render", "xcb-glx", "xcb-xinput", "xcb-xlib", "xcb-native-painting" ] }, { diff --git a/src/platformsupport/input/libinput/libinput.pri b/src/platformsupport/input/libinput/libinput.pri index f922769a37..476f20c1b8 100644 --- a/src/platformsupport/input/libinput/libinput.pri +++ b/src/platformsupport/input/libinput/libinput.pri @@ -14,7 +14,4 @@ QMAKE_USE_PRIVATE += libudev libinput INCLUDEPATH += $$PWD/../shared -qtConfig(xkbcommon-evdev): \ - QMAKE_USE_PRIVATE += xkbcommon_evdev -else: \ - DEFINES += QT_NO_XKBCOMMON_EVDEV +qtConfig(xkbcommon): QMAKE_USE_PRIVATE += xkbcommon diff --git a/src/platformsupport/input/libinput/qlibinputkeyboard.cpp b/src/platformsupport/input/libinput/qlibinputkeyboard.cpp index 2524066301..baef769bc9 100644 --- a/src/platformsupport/input/libinput/qlibinputkeyboard.cpp +++ b/src/platformsupport/input/libinput/qlibinputkeyboard.cpp @@ -44,7 +44,7 @@ #include #include #include -#ifndef QT_NO_XKBCOMMON_EVDEV +#if QT_CONFIG(xkbcommon) #include #include #endif @@ -56,7 +56,7 @@ Q_DECLARE_LOGGING_CATEGORY(qLcLibInput) const int REPEAT_DELAY = 500; const int REPEAT_RATE = 100; -#ifndef QT_NO_XKBCOMMON_EVDEV +#if QT_CONFIG(xkbcommon) struct KeyTabEntry { int xkbkey; int qtkey; @@ -132,14 +132,14 @@ static const KeyTabEntry keyTab[] = { #endif QLibInputKeyboard::QLibInputKeyboard() -#ifndef QT_NO_XKBCOMMON_EVDEV +#if QT_CONFIG(xkbcommon) : m_ctx(0), m_keymap(0), m_state(0), m_mods(Qt::NoModifier) #endif { -#ifndef QT_NO_XKBCOMMON_EVDEV +#if QT_CONFIG(xkbcommon) qCDebug(qLcLibInput) << "Using xkbcommon for key mapping"; m_ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS); if (!m_ctx) { @@ -164,13 +164,13 @@ QLibInputKeyboard::QLibInputKeyboard() m_repeatTimer.setSingleShot(true); connect(&m_repeatTimer, &QTimer::timeout, this, &QLibInputKeyboard::handleRepeat); #else - qCWarning(qLcLibInput) << "X-less xkbcommon not available, not performing key mapping"; + qCWarning(qLcLibInput) << "xkbcommon not available, not performing key mapping"; #endif } QLibInputKeyboard::~QLibInputKeyboard() { -#ifndef QT_NO_XKBCOMMON_EVDEV +#if QT_CONFIG(xkbcommon) if (m_state) xkb_state_unref(m_state); if (m_keymap) @@ -182,7 +182,7 @@ QLibInputKeyboard::~QLibInputKeyboard() void QLibInputKeyboard::processKey(libinput_event_keyboard *e) { -#ifndef QT_NO_XKBCOMMON_EVDEV +#if QT_CONFIG(xkbcommon) if (!m_ctx || !m_keymap || !m_state) return; @@ -245,7 +245,7 @@ void QLibInputKeyboard::processKey(libinput_event_keyboard *e) #endif } -#ifndef QT_NO_XKBCOMMON_EVDEV +#if QT_CONFIG(xkbcommon) void QLibInputKeyboard::handleRepeat() { QWindowSystemInterface::handleExtendedKeyEvent(nullptr, QEvent::KeyPress, diff --git a/src/plugins/platforminputcontexts/compose/compose.pro b/src/plugins/platforminputcontexts/compose/compose.pro index 2f53c5b416..68bc2c3466 100644 --- a/src/plugins/platforminputcontexts/compose/compose.pro +++ b/src/plugins/platforminputcontexts/compose/compose.pro @@ -9,12 +9,7 @@ SOURCES += $$PWD/qcomposeplatforminputcontextmain.cpp \ HEADERS += $$PWD/qcomposeplatforminputcontext.h \ $$PWD/generator/qtablegenerator.h \ -# libxkbcommon -!qtConfig(xkbcommon-system) { - include(../../../3rdparty/xkbcommon.pri) -} else { - QMAKE_USE += xkbcommon -} +QMAKE_USE_PRIVATE += xkbcommon include($$OUT_PWD/../../../gui/qtgui-config.pri) diff --git a/src/plugins/platforms/mirclient/mirclient.pro b/src/plugins/platforms/mirclient/mirclient.pro index d2da7e6ca0..d9eb069200 100644 --- a/src/plugins/platforms/mirclient/mirclient.pro +++ b/src/plugins/platforms/mirclient/mirclient.pro @@ -53,12 +53,7 @@ HEADERS = \ qmirclienttheme.h \ qmirclientwindow.h -# libxkbcommon -!qtConfig(xkbcommon-system) { - include(../../../3rdparty/xkbcommon.pri) -} else { - QMAKE_USE += xkbcommon -} +QMAKE_USE_PRIVATE += xkbcommon PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = MirServerIntegrationPlugin diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro index c65b145fb6..9883617ab6 100644 --- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro +++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro @@ -97,21 +97,15 @@ qtConfig(vulkan) { !qtConfig(system-xcb) { QMAKE_USE += xcb-static xcb } else { - qtConfig(xkb): QMAKE_USE += xcb_xkb qtConfig(xcb-render): QMAKE_USE += xcb_render qtConfig(xcb-xinput): QMAKE_USE += xcb_xinput QMAKE_USE += xcb_syslibs } -# libxkbcommon -!qtConfig(xkbcommon-system) { - qtConfig(xkb) { - include(../../../3rdparty/xkbcommon-x11.pri) - } else { - include(../../../3rdparty/xkbcommon.pri) - } -} else { - QMAKE_USE += xkbcommon +QMAKE_USE += xkbcommon +qtConfig(xkb) { + QMAKE_USE += xkbcommon_x11 + qtConfig(system-xcb): QMAKE_USE += xcb_xkb } qtConfig(dlopen): QMAKE_USE += libdl From 7aaf54f5725c65bf830088a9cfd104ef4817f256 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 12 Nov 2018 15:18:12 +0100 Subject: [PATCH 0468/1650] Codecs example: Add a dialog for showing common C++ encodings Add a dialog where the user can enter a line of text, which is then displayed in several encodings with special characters converted suitable for C++/Python string literals. Task-number: QTBUG-60635 Change-Id: Ibd436f9f76e128c93cbb581235c730d636641d8a Reviewed-by: Andy Shaw --- examples/widgets/tools/codecs/codecs.pro | 9 +- examples/widgets/tools/codecs/codecs.qrc | 5 + .../widgets/tools/codecs/encodingdialog.cpp | 333 ++++++++++++++++++ .../widgets/tools/codecs/encodingdialog.h | 73 ++++ .../widgets/tools/codecs/images/editcopy.png | Bin 0 -> 1325 bytes examples/widgets/tools/codecs/mainwindow.cpp | 19 + examples/widgets/tools/codecs/mainwindow.h | 4 + 7 files changed, 441 insertions(+), 2 deletions(-) create mode 100644 examples/widgets/tools/codecs/codecs.qrc create mode 100644 examples/widgets/tools/codecs/encodingdialog.cpp create mode 100644 examples/widgets/tools/codecs/encodingdialog.h create mode 100644 examples/widgets/tools/codecs/images/editcopy.png diff --git a/examples/widgets/tools/codecs/codecs.pro b/examples/widgets/tools/codecs/codecs.pro index 13daa79237..6f4b0742a9 100644 --- a/examples/widgets/tools/codecs/codecs.pro +++ b/examples/widgets/tools/codecs/codecs.pro @@ -2,10 +2,15 @@ QT += widgets requires(qtConfig(filedialog)) HEADERS += mainwindow.h \ - previewform.h + previewform.h \ + encodingdialog.h + SOURCES += main.cpp \ mainwindow.cpp \ - previewform.cpp + previewform.cpp \ + encodingdialog.cpp + +RESOURCES += codecs.qrc EXAMPLE_FILES = encodedfiles diff --git a/examples/widgets/tools/codecs/codecs.qrc b/examples/widgets/tools/codecs/codecs.qrc new file mode 100644 index 0000000000..65fa1aa64d --- /dev/null +++ b/examples/widgets/tools/codecs/codecs.qrc @@ -0,0 +1,5 @@ + + + images/editcopy.png + + diff --git a/examples/widgets/tools/codecs/encodingdialog.cpp b/examples/widgets/tools/codecs/encodingdialog.cpp new file mode 100644 index 0000000000..ca4b56db9e --- /dev/null +++ b/examples/widgets/tools/codecs/encodingdialog.cpp @@ -0,0 +1,333 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "encodingdialog.h" + +#if QT_CONFIG(action) +# include +#endif +#include +#include +#include +#include +#include + +#if QT_CONFIG(clipboard) +# include +# include +#endif + +#include + +// Helpers for formatting character sequences + +// Format a special character like '\x0a' +template +static void formatEscapedNumber(QTextStream &str, Int value, int base, + int width = 0,char prefix = 0) +{ + str << '\\'; + if (prefix) + str << prefix; + const auto oldPadChar = str.padChar(); + const auto oldFieldWidth = str.fieldWidth(); + const auto oldFieldAlignment = str.fieldAlignment(); + const auto oldIntegerBase = str.integerBase(); + str.setPadChar(QLatin1Char('0')); + str.setFieldWidth(width); + str.setFieldAlignment(QTextStream::AlignRight); + str.setIntegerBase(base); + str << value; + str.setIntegerBase(oldIntegerBase); + str.setFieldAlignment(oldFieldAlignment); + str.setFieldWidth(oldFieldWidth); + str.setPadChar(oldPadChar); +} + +template +static bool formatSpecialCharacter(QTextStream &str, Int value) +{ + bool result = true; + switch (value) { + case '\\': + str << "\\\\"; + break; + case '\"': + str << "\\\""; + break; + case '\n': + str << "\\n"; + break; + default: + result = false; + break; + } + return result; +} + +// Format a sequence of characters (QChar, ushort (UTF-16), uint (UTF-32) +// or just char (Latin1, Utf-8)) with the help of traits specifying +// how to obtain the code for checking the printable-ness and how to +// stream out the plain ASCII values. + +template +struct FormattingTraits +{ +}; + +template <> +struct FormattingTraits +{ + static ushort code(QChar c) { return c.unicode(); } + static char toAscii(QChar c) { return c.toLatin1(); } +}; + +template <> +struct FormattingTraits +{ + static ushort code(char c) { return uchar(c); } + static char toAscii(char c) { return c; } +}; + +template <> +struct FormattingTraits +{ + static ushort code(ushort c) { return c; } + static char toAscii(ushort c) { return char(c); } +}; + +template <> +struct FormattingTraits +{ + static uint code(uint c) { return c; } + static char toAscii(uint c) { return char(c); } +}; + +template <> +struct FormattingTraits +{ + static uchar code(char c) { return uchar(c); } + static char toAscii(char c) { return c; } +}; + +static bool isHexDigit(char c) +{ + return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') + || (c >= 'A' && c <= 'F'); +} + +template +static void formatStringSequence(QTextStream &str, Iterator i1, Iterator i2, + int escapeIntegerBase, int escapeWidth, + char escapePrefix = 0) +{ + str << '"'; + bool separateHexEscape = false; + for (; i1 != i2; ++i1) { + const auto code = FormattingTraits::code(*i1); + if (code >= 0x80) { + formatEscapedNumber(str, code, escapeIntegerBase, escapeWidth, escapePrefix); + separateHexEscape = escapeIntegerBase == 16 && escapeWidth == 0; + } else { + if (!formatSpecialCharacter(str, code)) { + const char c = FormattingTraits::toAscii(*i1); + // For variable width/hex: Terminate the literal to stop digit parsing + // ("\x12" "34..."). + if (separateHexEscape && isHexDigit(c)) + str << "\" \""; + str << c; + } + separateHexEscape = false; + } + } + str << '"'; +} + +static QString encodedString(const QString &value, EncodingDialog::Encoding e) +{ + QString result; + QTextStream str(&result); + switch (e) { + case EncodingDialog::Unicode: + formatStringSequence(str, value.cbegin(), value.cend(), + 16, 4, 'u'); + break; + case EncodingDialog::Utf8: { + const QByteArray utf8 = value.toUtf8(); + str << "u8"; + formatStringSequence(str, utf8.cbegin(), utf8.cend(), + 8, 3); + } + break; + case EncodingDialog::Utf16: { + auto utf16 = value.utf16(); + auto utf16End = utf16 + value.size(); + str << 'u'; + formatStringSequence(str, utf16, utf16End, + 16, 0, 'x'); + } + break; + case EncodingDialog::Utf32: { + auto utf32 = value.toUcs4(); + str << 'U'; + formatStringSequence(str, utf32.cbegin(), utf32.cend(), + 16, 0, 'x'); + } + break; + case EncodingDialog::Latin1: { + const QByteArray latin1 = value.toLatin1(); + formatStringSequence(str, latin1.cbegin(), latin1.cend(), + 16, 0, 'x'); + } + break; + case EncodingDialog::EncodingCount: + break; + } + return result; +} + +// Dialog helpers + +static const char *encodingLabels[] +{ + QT_TRANSLATE_NOOP("EncodingDialog", "Unicode:"), + QT_TRANSLATE_NOOP("EncodingDialog", "UTF-8:"), + QT_TRANSLATE_NOOP("EncodingDialog", "UTF-16:"), + QT_TRANSLATE_NOOP("EncodingDialog", "UTF-32:"), + QT_TRANSLATE_NOOP("EncodingDialog", "Latin1:") +}; + +static const char *encodingToolTips[] +{ + QT_TRANSLATE_NOOP("EncodingDialog", "Unicode points for use with any encoding (C++, Python)"), + QT_TRANSLATE_NOOP("EncodingDialog", "QString::fromUtf8()"), + QT_TRANSLATE_NOOP("EncodingDialog", "QStringViewLiteral(), wchar_t on Windows"), + QT_TRANSLATE_NOOP("EncodingDialog", "wchar_t on Unix (Ucs4)"), + QT_TRANSLATE_NOOP("EncodingDialog", "QLatin1String") +}; + +// A read-only line edit with a tool button to copy the contents +class DisplayLineEdit : public QLineEdit +{ + Q_OBJECT +public: + explicit DisplayLineEdit(const QIcon &icon, QWidget *parent = nullptr); + +public slots: + void copyAll(); +}; + +DisplayLineEdit::DisplayLineEdit(const QIcon &icon, QWidget *parent) : + QLineEdit(parent) +{ + setReadOnly(true); +#if QT_CONFIG(clipboard) && QT_CONFIG(action) + auto copyAction = addAction(icon, QLineEdit::TrailingPosition); + connect(copyAction, &QAction::triggered, this, &DisplayLineEdit::copyAll); +#endif +} + +void DisplayLineEdit::copyAll() +{ +#if QT_CONFIG(clipboard) + QGuiApplication::clipboard()->setText(text()); +#endif +} + +static void addFormLayoutRow(QFormLayout *formLayout, const QString &text, + QWidget *w, const QString &toolTip) +{ + auto label = new QLabel(text); + label->setToolTip(toolTip); + w->setToolTip(toolTip); + label->setBuddy(w); + formLayout->addRow(label, w); +} + +EncodingDialog::EncodingDialog(QWidget *parent) : + QDialog(parent) +{ + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + setWindowTitle(tr("Encodings")); + + auto formLayout = new QFormLayout; + auto sourceLineEdit = new QLineEdit(this); + sourceLineEdit->setClearButtonEnabled(true); + connect(sourceLineEdit, &QLineEdit::textChanged, this, &EncodingDialog::textChanged); + + addFormLayoutRow(formLayout, tr("&Source:"), sourceLineEdit, tr("Enter text")); + + const auto copyIcon = QIcon::fromTheme(QLatin1String("edit-copy"), + QIcon(QLatin1String(":/images/editcopy"))); + for (int i = 0; i < EncodingCount; ++i) { + m_lineEdits[i] = new DisplayLineEdit(copyIcon, this); + addFormLayoutRow(formLayout, tr(encodingLabels[i]), + m_lineEdits[i], tr(encodingToolTips[i])); + } + + auto mainLayout = new QVBoxLayout(this); + mainLayout->addLayout(formLayout); + auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); + connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); + mainLayout->addWidget(buttonBox); +} + +void EncodingDialog::textChanged(const QString &t) +{ + if (t.isEmpty()) { + for (auto lineEdit : m_lineEdits) + lineEdit->clear(); + } else { + for (int i = 0; i < EncodingCount; ++i) + m_lineEdits[i]->setText(encodedString(t, static_cast(i))); + } +} + +#include "encodingdialog.moc" diff --git a/examples/widgets/tools/codecs/encodingdialog.h b/examples/widgets/tools/codecs/encodingdialog.h new file mode 100644 index 0000000000..3f82da84af --- /dev/null +++ b/examples/widgets/tools/codecs/encodingdialog.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ENCODINGDIALOG_H +#define ENCODINGDIALOG_H + +#include + +QT_FORWARD_DECLARE_CLASS(QLineEdit) + +class EncodingDialog : public QDialog +{ + Q_OBJECT +public: + explicit EncodingDialog(QWidget *parent = nullptr); + + enum Encoding { Unicode, Utf8, Utf16, Utf32, Latin1, EncodingCount }; + +private slots: + void textChanged(const QString &t); + +private: + QLineEdit *m_lineEdits[EncodingCount]; +}; + +#endif // ENCODINGDIALOG_H diff --git a/examples/widgets/tools/codecs/images/editcopy.png b/examples/widgets/tools/codecs/images/editcopy.png new file mode 100644 index 0000000000000000000000000000000000000000..1121b47d8b6b48f6cdf525851e7c0f502454ffe1 GIT binary patch literal 1325 zcmV+|1=9M7P)+{buk{F=nCJX#i^AQGtBfP^U9E=s!&EKn3+*9AyOC5y5_m4HQB2~pH` zRYX%2)m58>DgqW&sAx;EBU4=37{7w!SM2eOJs!`@eVlXtjqY3tTS5?(-{yaHb@l)B zec!pdSBVIB!=;~|e%P7xymRJ$5osgh_&4efy`JyCUMhx9Kk}ogMRI&{UihAR)H(VP z5`ixu00_b{5e5q-zVY>M|NPMBA38(Y-oZLchI61bL7|V$#mUE~-@NcRpbiK;|6O(N zfk%J%Y@t+fHjUDudrucpC_qYs_XMTNy?z?C^q*foM`|MO`|`smOlCq5Y$|AffYRZk z1m#2g^824X`-5laF9IMU{OT;%tWD%U5hqqQHn+rzNOfaXUit9}xpwhevNrpY)K=e+ z>e6d6H~pftTia5-{gJHQcvaqe>5RPb)EA!+5j21}j7vL!fJ7h$Fxhq7s2$=XbQ*apq!syTR7h7DJ;ak=_$L@YoY5qR0x4qnI>JyURTfv?kuG)9hFQ(Bzig%{x2T0Vw))rZsUuJTqc?}RB zayzmI$t>XKE_%9=#B-p^;FY>ji9xH7Anaju4o)p z9%uqB5oz!1paas%Pl^wu;12>?@7Wcg0d(Zx zhlqm$W(R^Xh!-Io1+@po6A*q0JdbvDCs~`i(%Gx6@WB#qEmxCq5xK#C!6ygR1K}{F z4Jh9Og<%N$=~Oqu`pG7hW&{7(U;2z<{$co^Ef>^0+f z`TE<9*>|q)G;S}O%acqlZ1T6YZ9d*=aWjvj1$6F8Kzppmtr|VSaptG4)aU>DhsN&h zS#$oPdv2-51h5X&^WrRbO)e0I{N~r^&-Nf3pIBgF>R(LU+~oac!W>Y~iu;rt_-#>2 jRe%!E1{&Go|C3Ju!Z7S4^>URZ00000NkvXXu0mjfFDrHZ literal 0 HcmV?d00001 diff --git a/examples/widgets/tools/codecs/mainwindow.cpp b/examples/widgets/tools/codecs/mainwindow.cpp index 28f904d1a7..229c2ccfd4 100644 --- a/examples/widgets/tools/codecs/mainwindow.cpp +++ b/examples/widgets/tools/codecs/mainwindow.cpp @@ -51,6 +51,7 @@ #include #include "mainwindow.h" +#include "encodingdialog.h" #include "previewform.h" MainWindow::MainWindow() @@ -188,9 +189,27 @@ void MainWindow::createMenus() QAction *exitAct = fileMenu->addAction(tr("E&xit"), this, &QWidget::close); exitAct->setShortcuts(QKeySequence::Quit); + auto toolMenu = menuBar()->addMenu(tr("&Tools")); + auto encodingAction = toolMenu->addAction(tr("Encodings"), this, &MainWindow::encodingDialog); + encodingAction->setShortcut(Qt::CTRL + Qt::Key_E); + encodingAction->setToolTip(tr("Shows a dialog allowing to convert to common encoding in programming languages.")); + + menuBar()->addSeparator(); QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); helpMenu->addAction(tr("&About"), this, &MainWindow::about); helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt); } + +void MainWindow::encodingDialog() +{ + if (!m_encodingDialog) { + m_encodingDialog = new EncodingDialog(this); + const QRect screenGeometry = QApplication::desktop()->screenGeometry(this); + m_encodingDialog->setMinimumWidth(screenGeometry.width() / 4); + } + m_encodingDialog->show(); + m_encodingDialog->raise(); + +} diff --git a/examples/widgets/tools/codecs/mainwindow.h b/examples/widgets/tools/codecs/mainwindow.h index 7121c0b122..64494d1960 100644 --- a/examples/widgets/tools/codecs/mainwindow.h +++ b/examples/widgets/tools/codecs/mainwindow.h @@ -59,6 +59,8 @@ class QAction; class QTextCodec; class QPlainTextEdit; QT_END_NAMESPACE + +class EncodingDialog; class PreviewForm; class MainWindow : public QMainWindow @@ -73,6 +75,7 @@ private slots: void save(); void about(); void aboutToShowSaveAsMenu(); + void encodingDialog(); private: void findCodecs(); @@ -82,6 +85,7 @@ private: QPlainTextEdit *textEdit; PreviewForm *previewForm; QList codecs; + EncodingDialog *m_encodingDialog = nullptr; }; #endif From eab84914f1a31984f4698bcbca170556a56fd6fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 27 Sep 2018 12:26:36 +0200 Subject: [PATCH 0469/1650] macOS: make QScreen::grabWindow() fast again MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 17b73b0d2b8 regressed performance by grabbing the entire screen and then copying the grab region. Move back to grabbing a minimal rectangle instead. Also handle multi-screen grabs at different device pixel ratios. Multi-screen grabbing is handled by grabbing each screen individually, and then stitching together the result. The returned pixmap is created using the highest DPR available, upscaling lower resolution parts as needed. Change-Id: I9d45c5f7ec7b342360b745f49ef2939dc588f40b Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoascreen.mm | 93 +++++++++++---------- 1 file changed, 49 insertions(+), 44 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoascreen.mm b/src/plugins/platforms/cocoa/qcocoascreen.mm index 0d6567070e..afe14e623c 100644 --- a/src/plugins/platforms/cocoa/qcocoascreen.mm +++ b/src/plugins/platforms/cocoa/qcocoascreen.mm @@ -428,66 +428,71 @@ QWindow *QCocoaScreen::topLevelAt(const QPoint &point) const return window; } -QPixmap QCocoaScreen::grabWindow(WId window, int x, int y, int width, int height) const +QPixmap QCocoaScreen::grabWindow(WId view, int x, int y, int width, int height) const { - // TODO window should be handled - Q_UNUSED(window) + // Determine the grab rect. FIXME: The rect should be bounded by the view's + // geometry, but note that for the pixeltool use case that window will be the + // desktop widgets's view, which currently gets resized to fit one screen + // only, since its NSWindow has the NSWindowStyleMaskTitled flag set. + Q_UNUSED(view); + QRect grabRect = QRect(x, y, width, height); + qCDebug(lcQpaScreen) << "input grab rect" << grabRect; - const int maxDisplays = 128; // 128 displays should be enough for everyone. + // Find which displays to grab from, or all of them if the grab size is unspecified + const int maxDisplays = 128; CGDirectDisplayID displays[maxDisplays]; CGDisplayCount displayCount; - CGRect cgRect; - - if (width < 0 || height < 0) { - // get all displays - cgRect = CGRectInfinite; - } else { - cgRect = CGRectMake(x, y, width, height); - } + CGRect cgRect = (width < 0 || height < 0) ? CGRectInfinite : grabRect.toCGRect(); const CGDisplayErr err = CGGetDisplaysWithRect(cgRect, maxDisplays, displays, &displayCount); - - if (err && displayCount == 0) + if (err || displayCount == 0) return QPixmap(); - // calculate pixmap size - QSize windowSize(width, height); + // If the grab size is not specified, set it to be the bounding box of all screens, if (width < 0 || height < 0) { QRect windowRect; for (uint i = 0; i < displayCount; ++i) { - const CGRect cgRect = CGDisplayBounds(displays[i]); - QRect qRect(cgRect.origin.x, cgRect.origin.y, cgRect.size.width, cgRect.size.height); - windowRect = windowRect.united(qRect); + QRect displayBounds = QRectF::fromCGRect(CGDisplayBounds(displays[i])).toRect(); + windowRect = windowRect.united(displayBounds); } - if (width < 0) - windowSize.setWidth(windowRect.width()); - if (height < 0) - windowSize.setHeight(windowRect.height()); + if (grabRect.width() < 0) + grabRect.setWidth(windowRect.width()); + if (grabRect.height() < 0) + grabRect.setHeight(windowRect.height()); } - const qreal dpr = devicePixelRatio(); - QPixmap windowPixmap(windowSize * dpr); + qCDebug(lcQpaScreen) << "final grab rect" << grabRect << "from" << displayCount << "displays"; + + // Grab images from each display + QVector images; + QVector destinations; + for (uint i = 0; i < displayCount; ++i) { + auto display = displays[i]; + QRect displayBounds = QRectF::fromCGRect(CGDisplayBounds(display)).toRect(); + QRect grabBounds = displayBounds.intersected(grabRect); + QRect displayLocalGrabBounds = QRect(QPoint(grabBounds.topLeft() - displayBounds.topLeft()), grabBounds.size()); + QImage displayImage = qt_mac_toQImage(QCFType(CGDisplayCreateImageForRect(display, displayLocalGrabBounds.toCGRect()))); + displayImage.setDevicePixelRatio(displayImage.size().width() / displayLocalGrabBounds.size().width()); + images.append(displayImage); + QRect destBounds = QRect(QPoint(grabBounds.topLeft() - grabRect.topLeft()), grabBounds.size()); + destinations.append(destBounds); + qCDebug(lcQpaScreen) << "grab display" << i << "global" << grabBounds << "local" << displayLocalGrabBounds + << "grab image size" << displayImage.size() << "devicePixelRatio" << displayImage.devicePixelRatio(); + } + + // Determine the highest dpr, which becomes the dpr for the returned pixmap. + qreal dpr = 1.0; + for (uint i = 0; i < displayCount; ++i) + dpr = qMax(dpr, images.at(i).devicePixelRatio()); + + // Alocate target pixmap and draw each screen's content + qCDebug(lcQpaScreen) << "Create grap pixmap" << grabRect.size() << "at devicePixelRatio" << dpr; + QPixmap windowPixmap(grabRect.size() * dpr); windowPixmap.setDevicePixelRatio(dpr); windowPixmap.fill(Qt::transparent); + QPainter painter(&windowPixmap); + for (uint i = 0; i < displayCount; ++i) + painter.drawImage(destinations.at(i), images.at(i)); - for (uint i = 0; i < displayCount; ++i) { - const CGRect bounds = CGDisplayBounds(displays[i]); - - // Calculate the position and size of the requested area - QPoint pos(qAbs(bounds.origin.x - x), qAbs(bounds.origin.y - y)); - QSize size(qMin(width, qRound(bounds.size.width)), - qMin(height, qRound(bounds.size.height))); - pos *= dpr; - size *= dpr; - - // Take the whole screen and crop it afterwards, because CGDisplayCreateImageForRect - // has a strange behavior when mixing highDPI and non-highDPI displays - QCFType cgImage = CGDisplayCreateImage(displays[i]); - const QImage image = qt_mac_toQImage(cgImage); - - // Draw into windowPixmap only the requested size - QPainter painter(&windowPixmap); - painter.drawImage(windowPixmap.rect(), image, QRect(pos, size)); - } return windowPixmap; } From b926d5f919d2564cfdece497a87111a02e927db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 26 Nov 2018 23:01:50 +0100 Subject: [PATCH 0470/1650] CoreText: Remove handling of QFontEngineMulti's highByte MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's a leftover from when the Cocoa plugin used QFontEngineMulti exclusively. Nowadays QFontEngineMulti will strip out the highByte before calling into the real engine. Left an assert just in case.. Change-Id: I6cb26d20a908d7c3aaf096297fca160805fdb85b Reviewed-by: Simon Hausmann Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Tor Arne Vestbø --- src/gui/text/qfontengine.cpp | 2 +- src/gui/text/qfontengine_p.h | 2 ++ .../fontdatabases/mac/qfontengine_coretext.mm | 17 +++++------------ 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 9b0b0ec0d5..eb7e416dd1 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -1755,7 +1755,7 @@ QImage QFontEngineBox::alphaMapForGlyph(glyph_t) // Multi engine // ------------------------------------------------------------------ -static inline uchar highByte(glyph_t glyph) +uchar QFontEngineMulti::highByte(glyph_t glyph) { return glyph >> 24; } // strip high byte from glyph diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index a411e9ce4c..708c79c2ae 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -485,6 +485,8 @@ public: void setFallbackFamiliesList(const QStringList &fallbackFamilies); + static uchar highByte(glyph_t glyph); // Used for determining engine + inline QFontEngine *engine(int at) const { Q_ASSERT(at < m_engines.size()); return m_engines.at(at); } diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index 7fb22c0675..0f8727a13c 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -885,10 +885,8 @@ void QCoreTextFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::Shap QVarLengthArray cgGlyphs(numGlyphs); for (int i = 0; i < numGlyphs; ++i) { - if (glyphs->glyphs[i] & 0xff000000) - cgGlyphs[i] = 0; - else - cgGlyphs[i] = glyphs->glyphs[i]; + Q_ASSERT(!QFontEngineMulti::highByte(glyphs->glyphs[i])); + cgGlyphs[i] = glyphs->glyphs[i]; } loadAdvancesForGlyphs(cgGlyphs, glyphs); @@ -901,14 +899,9 @@ void QCoreTextFontEngine::loadAdvancesForGlyphs(QVarLengthArray &cgGlyp CTFontGetAdvancesForGlyphs(ctfont, kCTFontOrientationHorizontal, cgGlyphs.data(), advances.data(), numGlyphs); for (int i = 0; i < numGlyphs; ++i) { - if (glyphs->glyphs[i] & 0xff000000) - continue; - glyphs->advances[i] = QFixed::fromReal(advances[i].width); - } - - if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { - for (int i = 0; i < numGlyphs; ++i) - glyphs->advances[i] = glyphs->advances[i].round(); + QFixed advance = QFixed::fromReal(advances[i].width); + glyphs->advances[i] = fontDef.styleStrategy & QFont::ForceIntegerMetrics + ? advance.round() : advance; } } From dae2e6be939e5efcb48bcbfa872d07727dffacb2 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Wed, 28 Nov 2018 19:19:13 +0100 Subject: [PATCH 0471/1650] Fusion style - avoid a warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ... printed by QPainter when it gets a pixmap with one or both of dimensions equal to 0 (and a nullptr as a paintEngine). Task-number: QTBUG-71806 Change-Id: I978f56c843daab307042e34390fc33f338ce8cf5 Reviewed-by: Tor Arne Vestbø --- src/widgets/styles/qfusionstyle.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp index 5231f04df9..df151067df 100644 --- a/src/widgets/styles/qfusionstyle.cpp +++ b/src/widgets/styles/qfusionstyle.cpp @@ -247,6 +247,9 @@ static QLinearGradient qt_fusion_gradient(const QRect &rect, const QBrush &baseC static void qt_fusion_draw_arrow(Qt::ArrowType type, QPainter *painter, const QStyleOption *option, const QRect &rect, const QColor &color) { + if (rect.isEmpty()) + return; + const int arrowWidth = QStyleHelper::dpiScaled(14); const int arrowHeight = QStyleHelper::dpiScaled(8); From 64037f18d308c936848b7db2324bdb5dadb85a09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 30 Nov 2018 12:03:58 +0100 Subject: [PATCH 0472/1650] CoreText: Respect QFont::NoSubpixelAntialias when deciding glyph format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I846758bce2fd7536f9941b11f23fc0e5d5bc6f1b Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Tor Arne Vestbø --- src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index 0f8727a13c..a1299154cb 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -235,7 +235,7 @@ void QCoreTextFontEngine::init() if (traits & kCTFontColorGlyphsTrait) glyphFormat = QFontEngine::Format_ARGB; - else if (fontSmoothing() == FontSmoothing::Subpixel) + else if (shouldSmoothFont() && fontSmoothing() == FontSmoothing::Subpixel) glyphFormat = QFontEngine::Format_A32; else glyphFormat = QFontEngine::Format_A8; From 10f9bd82ea12f6015543d334bf6ac9c06b19667f Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Wed, 28 Nov 2018 12:32:00 +0100 Subject: [PATCH 0473/1650] ctest: Make cmake test pass if it has been run before We have to check if the directory exists before calling mkdir or the test will fail on every run but the first one. Change-Id: I36f10cfc18b3cb99990dc96190349ee00a0c1c4e Reviewed-by: Oswald Buddenhagen --- mkspecs/features/ctest_testcase_common.prf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mkspecs/features/ctest_testcase_common.prf b/mkspecs/features/ctest_testcase_common.prf index 63e31f5415..ea90bf89cd 100644 --- a/mkspecs/features/ctest_testcase_common.prf +++ b/mkspecs/features/ctest_testcase_common.prf @@ -65,7 +65,8 @@ for (MODULE_UNDER_TEST, CMAKE_QT_MODULES_UNDER_TEST) { CMAKE_MODULES_UNDER_TEST = $$join(CMAKE_MODULES_UNDER_TEST, ;) check.commands = \ - $(MKDIR) $$BUILD_DIR && $$QMAKE_CD $$BUILD_DIR && \ + $$sprintf($$QMAKE_MKDIR_CMD, $$BUILD_DIR) $$escape_expand(\\n\\t) \ + $$QMAKE_CD $$BUILD_DIR && \ cmake $$CMAKE_TEST_LOCATION $$CMAKE_GENERATOR \ -DCMAKE_C_COMPILER=$$QMAKE_CC \ -DCMAKE_CXX_COMPILER=$$QMAKE_CXX \ From e11a3b3f3e41050e048a586a8de2bd68c5ed3cc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 28 Nov 2018 12:17:58 +0100 Subject: [PATCH 0474/1650] CoreText: Base glyph fill color logic on font smoothing algorithm Change-Id: I22be1efb1f91048745008ea1b49186b39367d122 Reviewed-by: Lars Knoll --- .../fontdatabases/mac/qfontengine_coretext.mm | 57 +++++++++++-------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index a1299154cb..3dd3f468f2 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -748,37 +748,44 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition if (!im.width() || !im.height()) return im; -#if defined(Q_OS_MACOS) - CGColorRef glyphColor = CGColorGetConstantColor(kCGColorWhite); - if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave) { - // macOS 10.14 uses a new font smoothing algorithm that takes the fill color into - // account. This means our default approach of drawing white on black to produce - // the alpha map will result in non-native looking text when then drawn as black - // on white during the final blit. As a workaround we use the application's current - // appearance to decide whether to draw with white or black fill, and then invert - // the glyph image in the latter case, producing an alpha map. This covers the - // most common use-cases, but longer term we should propagate the fill color all - // the way from the paint engine, and include it in the key for the glyph cache. - if (!qt_mac_applicationIsInDarkMode()) - glyphColor = CGColorGetConstantColor(kCGColorBlack); - } - const bool blackOnWhiteGlyphs = !hasColorGlyphs() - && CGColorEqualToColor(glyphColor, CGColorGetConstantColor(kCGColorBlack)); - if (blackOnWhiteGlyphs) - im.fill(Qt::white); - else -#endif - im.fill(0); // Faster than Qt::black - QCFType colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); QCFType ctx = CGBitmapContextCreate(im.bits(), im.width(), im.height(), 8, im.bytesPerLine(), colorspace, qt_mac_bitmapInfoForImage(im)); Q_ASSERT(ctx); - CGContextSetFontSize(ctx, fontDef.pixelSize); CGContextSetShouldAntialias(ctx, shouldAntialias()); - CGContextSetShouldSmoothFonts(ctx, shouldSmoothFont()); + + const bool shouldSmooth = shouldSmoothFont(); + CGContextSetShouldSmoothFonts(ctx, shouldSmooth); + +#if defined(Q_OS_MACOS) + auto glyphColor = [&] { + if (shouldSmooth && fontSmoothing() == Grayscale) { + // The grayscale font smoothing algorithm introduced in macOS Mojave (10.14) adjusts + // its dilation (stem darkening) parameters based on the fill color. This means our + // default approach of drawing white on black to produce the alpha map will result + // in non-native looking text when then drawn as black on white during the final blit. + // As a workaround we use the application's current appearance to decide whether to + // draw with white or black fill, and then invert the glyph image in the latter case, + // producing an alpha map. This covers the most common use-cases, but longer term we + // should propagate the fill color all the way from the paint engine, and include it + //in the key for the glyph cache. + + if (!qt_mac_applicationIsInDarkMode()) + return kCGColorBlack; + } + return kCGColorWhite; + }(); + + const bool blackOnWhiteGlyphs = glyphColor == kCGColorBlack; + if (blackOnWhiteGlyphs) + im.fill(Qt::white); + else +#endif + im.fill(0); + + CGContextSetFontSize(ctx, fontDef.pixelSize); CGAffineTransform cgMatrix = CGAffineTransformIdentity; @@ -798,7 +805,7 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition if (!hasColorGlyphs()) { CGContextSetTextMatrix(ctx, cgMatrix); #if defined(Q_OS_MACOS) - CGContextSetFillColorWithColor(ctx, glyphColor); + CGContextSetFillColorWithColor(ctx, CGColorGetConstantColor(glyphColor)); #else CGContextSetRGBFillColor(ctx, 1, 1, 1, 1); #endif From 0de4b326d8e02c228ebefcac1abe069c45cbb5c4 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Mon, 26 Nov 2018 15:23:27 +0100 Subject: [PATCH 0475/1650] xcb: fix issue with dialogs hidden by other windows This was a regression from Qt4, due to not setting the window group leader in WM_HINTS property. Qt4 did set this property. It was not obvious that something was missing because of the similarly named WM_CLIENT_LEADER property, which we do set. Testing revealed that setting WM_CLIENT_LEADER is sufficient on some DEs, e.g. KDE, Unity, but did not have the desired effect on e.g Gnome and XFCE. EWMH/ICCCM specs are known to be ambiguous, WM_CLIENT_LEADER is only mentioned in the section on the session management, so it is not surprising that there is this inconsistency between various WMs. This patch merely restores a lost WM hint. This solves the reported issues on major desktops. If we support calling show() on a dialog before its parent has been shown is still an open question, which should be handled in QTBUG-72040. Task-number: QTBUG-56829 Fixes: QTBUG-46626 Fixes: QTBUG-70756 Task-number: QTBUG-72040 Change-Id: Id2c575850e5f4f5af3e57963c577d33572e30b6e Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbwindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 891fe6b155..65e1c71531 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -501,6 +501,8 @@ void QXcbWindow::create() // from various setter functions for adjusting the hints. xcb_wm_hints_t hints; memset(&hints, 0, sizeof(hints)); + hints.flags = XCB_ICCCM_WM_HINT_WINDOW_GROUP; + hints.window_group = connection()->clientLeader(); xcb_set_wm_hints(xcb_connection(), m_window, &hints); xcb_window_t leader = connection()->clientLeader(); From f2b4462f84d0b8b28da50141163890bbf7fe6174 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Thu, 1 Nov 2018 15:29:35 +0100 Subject: [PATCH 0476/1650] xcb: remove old work-around for building with util-wm Commits that added this code: 7ce8491280990350162933a0716d1b014f65aeb6 and f005dee1b3692a09e47782dcff9b5b07aa659b51 I guess this was a work-around, before we started bundling XCB libs a year later in 21bd66e1ea06e466754ab06ee2c5f8b737bb4bd7 0.3.8 was released in 2011-04-26 and we are bundling 0.3.9, so it is safe to remove the include work-around as well. Change-Id: I5794f40d86e10ebdad984aa4b61311979aaadcf3 Reviewed-by: Oswald Buddenhagen Reviewed-by: Frederik Gladhorn Reviewed-by: Shawn Rutledge --- src/gui/configure.json | 9 +-- src/plugins/platforms/xcb/qxcbwindow.cpp | 83 +++++++++--------------- 2 files changed, 31 insertions(+), 61 deletions(-) diff --git a/src/gui/configure.json b/src/gui/configure.json index 590e52d258..25ff553876 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -484,13 +484,8 @@ "xcb/xinerama.h", "xcb/sync.h", "xcb/randr.h", - "xcb/shm.h" - ], - "tail": [ - "// This workaround can be removed for xcb-icccm > 3.8", - "#define class class_name", - "#include ", - "#undef class" + "xcb/shm.h", + "xcb/xcb_icccm.h" ], "main": [ "int primaryScreen = 0;", diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 65e1c71531..3bfcbf2adb 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -64,38 +64,13 @@ #include -// FIXME This workaround can be removed for xcb-icccm > 3.8 -#define class class_name #include -#undef class #include #include #if QT_CONFIG(xcb_xinput) #include #endif -// xcb-icccm 3.8 support -#ifdef XCB_ICCCM_NUM_WM_SIZE_HINTS_ELEMENTS -#define xcb_get_wm_hints_reply xcb_icccm_get_wm_hints_reply -#define xcb_get_wm_hints xcb_icccm_get_wm_hints -#define xcb_get_wm_hints_unchecked xcb_icccm_get_wm_hints_unchecked -#define xcb_set_wm_hints xcb_icccm_set_wm_hints -#define xcb_set_wm_normal_hints xcb_icccm_set_wm_normal_hints -#define xcb_size_hints_set_base_size xcb_icccm_size_hints_set_base_size -#define xcb_size_hints_set_max_size xcb_icccm_size_hints_set_max_size -#define xcb_size_hints_set_min_size xcb_icccm_size_hints_set_min_size -#define xcb_size_hints_set_position xcb_icccm_size_hints_set_position -#define xcb_size_hints_set_resize_inc xcb_icccm_size_hints_set_resize_inc -#define xcb_size_hints_set_size xcb_icccm_size_hints_set_size -#define xcb_size_hints_set_win_gravity xcb_icccm_size_hints_set_win_gravity -#define xcb_wm_hints_set_iconic xcb_icccm_wm_hints_set_iconic -#define xcb_wm_hints_set_normal xcb_icccm_wm_hints_set_normal -#define xcb_wm_hints_set_input xcb_icccm_wm_hints_set_input -#define xcb_wm_hints_t xcb_icccm_wm_hints_t -#define XCB_WM_STATE_ICONIC XCB_ICCCM_WM_STATE_ICONIC -#define XCB_WM_STATE_WITHDRAWN XCB_ICCCM_WM_STATE_WITHDRAWN -#endif - #include #include @@ -497,13 +472,13 @@ void QXcbWindow::create() clientMachine.size(), clientMachine.constData()); } - // Create WM_HINTS property on the window, so we can xcb_get_wm_hints*() + // Create WM_HINTS property on the window, so we can xcb_icccm_get_wm_hints*() // from various setter functions for adjusting the hints. - xcb_wm_hints_t hints; + xcb_icccm_wm_hints_t hints; memset(&hints, 0, sizeof(hints)); hints.flags = XCB_ICCCM_WM_HINT_WINDOW_GROUP; hints.window_group = connection()->clientLeader(); - xcb_set_wm_hints(xcb_connection(), m_window, &hints); + xcb_icccm_set_wm_hints(xcb_connection(), m_window, &hints); xcb_window_t leader = connection()->clientLeader(); xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, @@ -1200,7 +1175,7 @@ void QXcbWindow::setWindowState(Qt::WindowStates state) event.sequence = 0; event.window = m_window; event.type = atom(QXcbAtom::WM_CHANGE_STATE); - event.data.data32[0] = XCB_WM_STATE_ICONIC; + event.data.data32[0] = XCB_ICCCM_WM_STATE_ICONIC; event.data.data32[1] = 0; event.data.data32[2] = 0; event.data.data32[3] = 0; @@ -1214,14 +1189,14 @@ void QXcbWindow::setWindowState(Qt::WindowStates state) setNetWmState(state); - xcb_get_property_cookie_t cookie = xcb_get_wm_hints_unchecked(xcb_connection(), m_window); - xcb_wm_hints_t hints; - if (xcb_get_wm_hints_reply(xcb_connection(), cookie, &hints, nullptr)) { + xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_hints_unchecked(xcb_connection(), m_window); + xcb_icccm_wm_hints_t hints; + if (xcb_icccm_get_wm_hints_reply(xcb_connection(), cookie, &hints, nullptr)) { if (state & Qt::WindowMinimized) - xcb_wm_hints_set_iconic(&hints); + xcb_icccm_wm_hints_set_iconic(&hints); else - xcb_wm_hints_set_normal(&hints); - xcb_set_wm_hints(xcb_connection(), m_window, &hints); + xcb_icccm_wm_hints_set_normal(&hints); + xcb_icccm_set_wm_hints(xcb_connection(), m_window, &hints); } connection()->sync(); @@ -1302,14 +1277,14 @@ void QXcbWindow::setTransparentForMouseEvents(bool transparent) void QXcbWindow::updateDoesNotAcceptFocus(bool doesNotAcceptFocus) { - xcb_get_property_cookie_t cookie = xcb_get_wm_hints_unchecked(xcb_connection(), m_window); + xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_hints_unchecked(xcb_connection(), m_window); - xcb_wm_hints_t hints; - if (!xcb_get_wm_hints_reply(xcb_connection(), cookie, &hints, nullptr)) + xcb_icccm_wm_hints_t hints; + if (!xcb_icccm_get_wm_hints_reply(xcb_connection(), cookie, &hints, nullptr)) return; - xcb_wm_hints_set_input(&hints, !doesNotAcceptFocus); - xcb_set_wm_hints(xcb_connection(), m_window, &hints); + xcb_icccm_wm_hints_set_input(&hints, !doesNotAcceptFocus); + xcb_icccm_set_wm_hints(xcb_connection(), m_window, &hints); } WId QXcbWindow::winId() const @@ -1417,9 +1392,9 @@ void QXcbWindow::propagateSizeHints() QWindowPrivate *win = qt_window_private(window()); if (!win->positionAutomatic) - xcb_size_hints_set_position(&hints, true, rect.x(), rect.y()); + xcb_icccm_size_hints_set_position(&hints, true, rect.x(), rect.y()); if (rect.width() < QWINDOWSIZE_MAX || rect.height() < QWINDOWSIZE_MAX) - xcb_size_hints_set_size(&hints, true, rect.width(), rect.height()); + xcb_icccm_size_hints_set_size(&hints, true, rect.width(), rect.height()); /* Gravity describes how to interpret x and y values the next time window needs to be positioned on a screen. @@ -1428,7 +1403,7 @@ void QXcbWindow::propagateSizeHints() auto gravity = win->positionPolicy == QWindowPrivate::WindowFrameInclusive ? XCB_GRAVITY_NORTH_WEST : XCB_GRAVITY_STATIC; - xcb_size_hints_set_win_gravity(&hints, gravity); + xcb_icccm_size_hints_set_win_gravity(&hints, gravity); QSize minimumSize = windowMinimumSize(); QSize maximumSize = windowMaximumSize(); @@ -1436,21 +1411,21 @@ void QXcbWindow::propagateSizeHints() QSize sizeIncrement = windowSizeIncrement(); if (minimumSize.width() > 0 || minimumSize.height() > 0) - xcb_size_hints_set_min_size(&hints, - qMin(XCOORD_MAX,minimumSize.width()), - qMin(XCOORD_MAX,minimumSize.height())); + xcb_icccm_size_hints_set_min_size(&hints, + qMin(XCOORD_MAX,minimumSize.width()), + qMin(XCOORD_MAX,minimumSize.height())); if (maximumSize.width() < QWINDOWSIZE_MAX || maximumSize.height() < QWINDOWSIZE_MAX) - xcb_size_hints_set_max_size(&hints, - qMin(XCOORD_MAX, maximumSize.width()), - qMin(XCOORD_MAX, maximumSize.height())); + xcb_icccm_size_hints_set_max_size(&hints, + qMin(XCOORD_MAX, maximumSize.width()), + qMin(XCOORD_MAX, maximumSize.height())); if (sizeIncrement.width() > 0 || sizeIncrement.height() > 0) { - xcb_size_hints_set_base_size(&hints, baseSize.width(), baseSize.height()); - xcb_size_hints_set_resize_inc(&hints, sizeIncrement.width(), sizeIncrement.height()); + xcb_icccm_size_hints_set_base_size(&hints, baseSize.width(), baseSize.height()); + xcb_icccm_size_hints_set_resize_inc(&hints, sizeIncrement.width(), sizeIncrement.height()); } - xcb_set_wm_normal_hints(xcb_connection(), m_window, &hints); + xcb_icccm_set_wm_normal_hints(xcb_connection(), m_window, &hints); } void QXcbWindow::requestActivateWindow() @@ -2257,8 +2232,8 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev if (reply && reply->format == 32 && reply->type == atom(QXcbAtom::WM_STATE)) { const quint32 *data = (const quint32 *)xcb_get_property_value(reply.get()); if (reply->length != 0) - m_minimized = (data[0] == XCB_WM_STATE_ICONIC - || (data[0] == XCB_WM_STATE_WITHDRAWN && m_minimized)); + m_minimized = (data[0] == XCB_ICCCM_WM_STATE_ICONIC + || (data[0] == XCB_ICCCM_WM_STATE_WITHDRAWN && m_minimized)); } } if (m_minimized) From 042707a6339cff6795d8d2ea08f927924f218a7b Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 22 Nov 2018 17:17:21 +0100 Subject: [PATCH 0477/1650] Avoid invalid qmake code in macOS-specific pluginloader test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit You cannot manipulate variables in custom target dependencies, so the following code was invalid: i386_d.depends = EXPORT_VALID_ARCHS=i386 In order to still build the fat binary, we split the project in four, one for each architecture, plus one to create the final package. Change-Id: If08cf54e2e4098a7e10df41b7ea8d2bf699f58be Reviewed-by: Oswald Buddenhagen Reviewed-by: Tor Arne Vestbø --- .../qpluginloader/machtest/machtest.pri | 13 ++++ .../qpluginloader/machtest/machtest.pro | 73 +++---------------- .../qpluginloader/machtest/machtest_fat.pro | 41 +++++++++++ .../qpluginloader/machtest/machtest_i386.pro | 3 + .../qpluginloader/machtest/machtest_ppc64.pro | 9 +++ .../machtest/machtest_x86_64.pro | 2 + 6 files changed, 80 insertions(+), 61 deletions(-) create mode 100644 tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pri create mode 100644 tests/auto/corelib/plugin/qpluginloader/machtest/machtest_fat.pro create mode 100644 tests/auto/corelib/plugin/qpluginloader/machtest/machtest_i386.pro create mode 100644 tests/auto/corelib/plugin/qpluginloader/machtest/machtest_ppc64.pro create mode 100644 tests/auto/corelib/plugin/qpluginloader/machtest/machtest_x86_64.pro diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pri b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pri new file mode 100644 index 0000000000..ca4a0a07e9 --- /dev/null +++ b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pri @@ -0,0 +1,13 @@ +TEMPLATE = aux + +# Needs explicit load()ing due to aux template. Relies on QT being non-empty. +load(qt) + +goodlib.target = good.$${QMAKE_APPLE_DEVICE_ARCHS}.dylib +goodlib.commands = $(CXX) $(CXXFLAGS) -shared -o $@ -I$(INCPATH) $< +goodlib.depends += $$PWD/../fakeplugin.cpp + +all.depends += goodlib + +QMAKE_EXTRA_TARGETS += goodlib all +QMAKE_CLEAN += $$goodlib.target diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pro b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pro index 7f7caa7f76..795dd89895 100644 --- a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pro +++ b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pro @@ -1,64 +1,15 @@ -TEMPLATE = aux -OTHER_FILES += \ - ppcconverter.pl \ - generate-bad.pl +TEMPLATE = subdirs -# Needs explicit load()ing due to aux template. Relies on QT being non-empty. -load(qt) - -i386_d.target = good.i386.dylib -i386_d.depends = EXPORT_VALID_ARCHS=i386 -i386.target = good.i386.dylib -i386.commands = $(CXX) $(CXXFLAGS) -shared -o $@ -I$(INCPATH) $< -i386.depends += $$PWD/../fakeplugin.cpp - -x86_64_d.target = good.x86_64.dylib -x86_64_d.depends = EXPORT_VALID_ARCHS=x86_64 -x86_64.target = good.x86_64.dylib -x86_64.commands = $(CXX) $(CXXFLAGS) -shared -o $@ -I$(INCPATH) $< -x86_64.depends += $$PWD/../fakeplugin.cpp - -# Current Mac OS X toolchains have no compiler for PPC anymore -# So we fake it by converting an x86-64 binary to (little-endian!) PPC64 -ppc64.target = good.ppc64.dylib -ppc64.commands = $$PWD/ppcconverter.pl $< $@ -ppc64.depends = x86_64 $$PWD/ppcconverter.pl - -# Generate a fat binary with three architectures -fat_all.target = good.fat.all.dylib -fat_all.commands = lipo -create -output $@ \ - -arch ppc64 $$ppc64.target \ - -arch i386 $$i386.target \ - -arch x86_64 $$x86_64.target -fat_all.depends += i386 x86_64 ppc64 - -fat_no_i386.target = good.fat.no-i386.dylib -fat_no_i386.commands = lipo -create -output $@ -arch x86_64 $$x86_64.target -arch ppc64 $$ppc64.target -fat_no_i386.depends += x86_64 ppc64 - -fat_no_x86_64.target = good.fat.no-x86_64.dylib -fat_no_x86_64.commands = lipo -create -output $@ -arch i386 $$i386.target -arch ppc64 $$ppc64.target -fat_no_x86_64.depends += i386 ppc64 - -fat_stub_i386.target = good.fat.stub-i386.dylib -fat_stub_i386.commands = lipo -create -output $@ -arch ppc64 $$ppc64.target -arch_blank i386 -fat_stub_i386.depends += x86_64 ppc64 - -fat_stub_x86_64.target = good.fat.stub-x86_64.dylib -fat_stub_x86_64.commands = lipo -create -output $@ -arch ppc64 $$ppc64.target -arch_blank x86_64 -fat_stub_x86_64.depends += i386 ppc64 - -bad.commands = $$PWD/generate-bad.pl -bad.depends += $$PWD/generate-bad.pl - -MYTARGETS = $$fat_all.depends fat_all fat_no_x86_64 fat_no_i386 \ - fat_stub_i386 fat_stub_x86_64 bad -all.depends += $$MYTARGETS -QMAKE_EXTRA_TARGETS += i386_d x86_64_d $$MYTARGETS all - -QMAKE_CLEAN += $$i386.target $$x86_64.target $$ppc64.target $$fat_all.target \ - $$fat_no_i386.target $$fat_no_x86_64.target \ - $$fat_stub_i386.target $$fat_stub_x86_64.target \ - "bad*.dylib" +SUBDIRS = \ + machtest_i386.pro \ + machtest_x86_64.pro \ + machtest_ppc64.pro \ + machtest_fat.pro +machtest_fat-pro.depends = \ + machtest_i386.pro \ + machtest_x86_64.pro \ + machtest_ppc64.pro +machtest_ppc64-pro.depends = \ + machtest_x86_64.pro diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_fat.pro b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_fat.pro new file mode 100644 index 0000000000..8daa343e2b --- /dev/null +++ b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_fat.pro @@ -0,0 +1,41 @@ +TEMPLATE = aux +OTHER_FILES += generate-bad.pl + +# Needs explicit load()ing due to aux template. Relies on QT being non-empty. +load(qt) + +# Generate a fat binary with three architectures +fat_all.target = good.fat.all.dylib +fat_all.commands = lipo -create -output $@ \ + -arch ppc64 good.ppc64.dylib \ + -arch i386 good.i386.dylib \ + -arch x86_64 good.x86_64.dylib +fat_all.depends += good.i386.dylib good.x86_64.dylib good.ppc64.dylib + +fat_no_i386.target = good.fat.no-i386.dylib +fat_no_i386.commands = lipo -create -output $@ -arch x86_64 good.x86_64.dylib -arch ppc64 good.ppc64.dylib +fat_no_i386.depends += good.x86_64.dylib good.ppc64.dylib + +fat_no_x86_64.target = good.fat.no-x86_64.dylib +fat_no_x86_64.commands = lipo -create -output $@ -arch i386 good.i386.dylib -arch ppc64 good.ppc64.dylib +fat_no_x86_64.depends += good.i386.dylib good.ppc64.dylib + +fat_stub_i386.target = good.fat.stub-i386.dylib +fat_stub_i386.commands = lipo -create -output $@ -arch ppc64 good.ppc64.dylib -arch_blank i386 +fat_stub_i386.depends += good.x86_64.dylib good.ppc64.dylib + +fat_stub_x86_64.target = good.fat.stub-x86_64.dylib +fat_stub_x86_64.commands = lipo -create -output $@ -arch ppc64 good.ppc64.dylib -arch_blank x86_64 +fat_stub_x86_64.depends += good.i386.dylib good.ppc64.dylib + +bad.commands = $$PWD/generate-bad.pl +bad.depends += $$PWD/generate-bad.pl + +MYTARGETS = $$fat_all.depends fat_all fat_no_x86_64 fat_no_i386 \ + fat_stub_i386 fat_stub_x86_64 bad +all.depends += $$MYTARGETS +QMAKE_EXTRA_TARGETS += $$MYTARGETS all + +QMAKE_CLEAN += $$fat_all.target $$fat_no_i386.target $$fat_no_x86_64.target \ + $$fat_stub_i386.target $$fat_stub_x86_64.target \ + "bad*.dylib" diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_i386.pro b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_i386.pro new file mode 100644 index 0000000000..bfb2e0930c --- /dev/null +++ b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_i386.pro @@ -0,0 +1,3 @@ +QMAKE_APPLE_DEVICE_ARCHS = i386 +include(machtest.pri) + diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_ppc64.pro b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_ppc64.pro new file mode 100644 index 0000000000..a73f97ccc6 --- /dev/null +++ b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_ppc64.pro @@ -0,0 +1,9 @@ +QMAKE_APPLE_DEVICE_ARCHS = ppc64 +include(machtest.pri) + +OTHER_FILES += ppcconverter.pl + +# Current macOS toolchains have no compiler for PPC anymore +# So we fake it by converting an x86-64 binary to (little-endian!) PPC64 +goodlib.commands = $$PWD/ppcconverter.pl $< $@ +goodlib.depends = good.x86_64.dylib $$PWD/ppcconverter.pl diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_x86_64.pro b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_x86_64.pro new file mode 100644 index 0000000000..9dbae5c4ee --- /dev/null +++ b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_x86_64.pro @@ -0,0 +1,2 @@ +QMAKE_APPLE_DEVICE_ARCHS = x86_64 +include(machtest.pri) From 2afe4a1a074096a3a6476aae21e732c418717da7 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 28 Nov 2018 14:56:45 +0100 Subject: [PATCH 0478/1650] Android: Don't use blocking queued when suspending the application If the application gets suspended when a blocking queued connection is made then it will cause the application to hang when being resumed. Therefore a check is needed to still post the event to the other thread but in a non blocking manner so that it does not cause a hang on return. Fixes: QTBUG-72101 Change-Id: I6d53c97ed6d9d500559da2a9fd195226d1fc9905 Reviewed-by: BogDan Vatra --- src/plugins/platforms/android/qandroidinputcontext.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp index c5cd0b92d9..7b3546f9bb 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.cpp +++ b/src/plugins/platforms/android/qandroidinputcontext.cpp @@ -99,9 +99,13 @@ static jfieldID m_selectionStartFieldID = 0; static jfieldID m_startOffsetFieldID = 0; static jfieldID m_textFieldID = 0; +Q_DECLARE_METATYPE(std::function) + static void runOnQtThread(const std::function &func) { - QMetaObject::invokeMethod(m_androidInputContext, "safeCall", Qt::BlockingQueuedConnection, Q_ARG(std::function, func)); + const bool block = QGuiApplication::applicationState() >= Qt::ApplicationInactive; + QMetaObject::invokeMethod(m_androidInputContext, "safeCall", + block ? Qt::BlockingQueuedConnection : Qt::QueuedConnection, Q_ARG(std::function, func)); } static jboolean beginBatchEdit(JNIEnv */*env*/, jobject /*thiz*/) @@ -512,6 +516,7 @@ QAndroidInputContext::QAndroidInputContext() m_handleMode = Hidden; updateSelectionHandles(); }); + qRegisterMetaType>(); } QAndroidInputContext::~QAndroidInputContext() From 5ed471a80a5a88b26db31adf7bc673b5026cc907 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 5 Nov 2018 15:13:22 +0100 Subject: [PATCH 0479/1650] qmake: Escape '=' in dependency paths for unix make '=' cannot be handled in the same manner as other "critical" characters as no amount of backslashes will escape it. Use a variable instead. The documentation for nmake suggests that '=' in file names is not among the "Special Characters in a Makefile". Therefore, we assume nmake can handle it and don't escape it. Fixes: QTBUG-67262 Change-Id: Ib60f808d7d4e981c98f7d8bf2075d55b2b7f3b7d Reviewed-by: Oswald Buddenhagen Reviewed-by: Michael Brasser --- qmake/generators/makefile.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index b7e591d2ab..7247d1f8df 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -2325,6 +2325,7 @@ MakefileGenerator::writeHeader(QTextStream &t) if (ofile.lastIndexOf(Option::dir_sep) != -1) ofile.remove(0, ofile.lastIndexOf(Option::dir_sep) +1); t << "MAKEFILE = " << escapeFilePath(ofile) << endl << endl; + t << "EQ = =\n\n"; } QList @@ -2869,6 +2870,7 @@ MakefileGenerator::escapeDependencyPath(const QString &path) const static const QRegExp criticalChars(QStringLiteral("([\t #])")); #endif ret.replace(criticalChars, QStringLiteral("\\\\1")); + ret.replace(QLatin1Char('='), QStringLiteral("$(EQ)")); debug_msg(2, "escapeDependencyPath: %s -> %s", path.toLatin1().constData(), ret.toLatin1().constData()); } return ret; From 58e66a2573e40cc3e12a5479575a8ecbef1be6d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 27 Nov 2018 19:13:54 +0100 Subject: [PATCH 0480/1650] CoreText: Define font smoothing gamma along with rest of relevant code Change-Id: I57909603732de6c1a91c744a358968941e64acdf Reviewed-by: Lars Knoll --- .../fontdatabases/mac/qfontengine_coretext.mm | 5 +++++ .../fontdatabases/mac/qfontengine_coretext_p.h | 1 + src/plugins/platforms/cocoa/qcocoaintegration.mm | 4 +++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index 3dd3f468f2..19b450b643 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -739,6 +739,11 @@ bool QCoreTextFontEngine::expectsGammaCorrectedBlending() const return shouldSmoothFont(); } +qreal QCoreTextFontEngine::fontSmoothingGamma() +{ + return 2.0; +} + QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &matrix) { glyph_metrics_t br = alphaMapBoundingBox(glyph, subPixelPosition, matrix, glyphFormat); diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h index 28810f13bc..4064507058 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h @@ -127,6 +127,7 @@ public: Q_ENUM(FontSmoothing); static FontSmoothing fontSmoothing(); + static qreal fontSmoothingGamma(); static bool ct_getSfntTable(void *user_data, uint tag, uchar *buffer, uint *length); static QFont::Weight qtWeightFromCFWeight(float value); diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 1bd1029863..f6a49dd74f 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -63,6 +63,8 @@ #include +#include + #ifdef QT_WIDGETS_LIB #include #if QT_CONFIG(filedialog) @@ -477,7 +479,7 @@ QCocoaServices *QCocoaIntegration::services() const QVariant QCocoaIntegration::styleHint(StyleHint hint) const { if (hint == QPlatformIntegration::FontSmoothingGamma) - return 2.0; + return QCoreTextFontEngine::fontSmoothingGamma(); return QPlatformIntegration::styleHint(hint); } From c0dd44556454ce0fa451f83decdad3931a6deaec Mon Sep 17 00:00:00 2001 From: Ville Voutilainen Date: Fri, 30 Nov 2018 12:49:01 +0200 Subject: [PATCH 0481/1650] Fix a nullptr compile error with gcc 4.8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit template argument deduction/substitution failed: qtbase/tests/auto/corelib/kernel/qobject/tst_qobject.cpp:6756:71: note: mismatched types ‘const typename QtPrivate::FunctionPointer::Object*’ and ‘std::nullptr_t’ Change-Id: I8e7872457d1fc30c4b29e96c16091915264f9bce Reviewed-by: Simon Hausmann --- tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index effc82261b..06254091cd 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -6750,16 +6750,16 @@ void tst_QObject::connectWarnings() r1.reset(); QTest::ignoreMessage(QtWarningMsg, "QObject::connect(SenderObject, ReceiverObject): invalid null parameter"); - connect(nullptr, &SubSender::signal1, &r1, &ReceiverObject::slot1); + connect(static_cast(nullptr), &SubSender::signal1, &r1, &ReceiverObject::slot1); QTest::ignoreMessage(QtWarningMsg, "QObject::connect(SubSender, Unknown): invalid null parameter"); - connect(&sub, &SubSender::signal1, nullptr, &ReceiverObject::slot1); + connect(&sub, &SubSender::signal1, static_cast(nullptr), &ReceiverObject::slot1); QTest::ignoreMessage(QtWarningMsg, "QObject::connect(SenderObject, ReceiverObject): invalid null parameter"); - connect(nullptr, &SenderObject::signal1, &r1, &ReceiverObject::slot1); + connect(static_cast(nullptr), &SenderObject::signal1, &r1, &ReceiverObject::slot1); QTest::ignoreMessage(QtWarningMsg, "QObject::connect(SenderObject, Unknown): invalid null parameter"); - connect(&obj, &SenderObject::signal1, nullptr, &ReceiverObject::slot1); + connect(&obj, &SenderObject::signal1, static_cast(nullptr), &ReceiverObject::slot1); } struct QmlReceiver : public QtPrivate::QSlotObjectBase From 096d87c8b01a32083d6819516be17050b0f183a9 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Fri, 30 Nov 2018 14:15:45 +0100 Subject: [PATCH 0482/1650] OpenSSL context (1.1) - make the if-fery/switch less ugly no need in duplicating DTLS-specific cases. Change-Id: I475c6fb53daa44d60a5054bf3acc8474355b2186 Reviewed-by: Edward Welbourne --- src/network/ssl/qsslcontext_openssl11.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/network/ssl/qsslcontext_openssl11.cpp b/src/network/ssl/qsslcontext_openssl11.cpp index 02ce466c80..c96a48dac1 100644 --- a/src/network/ssl/qsslcontext_openssl11.cpp +++ b/src/network/ssl/qsslcontext_openssl11.cpp @@ -97,24 +97,20 @@ init_context: unsupportedProtocol = true; } else { switch (sslContext->sslConfiguration.protocol()) { -#if QT_CONFIG(dtls) case QSsl::DtlsV1_0: case QSsl::DtlsV1_0OrLater: case QSsl::DtlsV1_2: case QSsl::DtlsV1_2OrLater: +#if QT_CONFIG(dtls) isDtls = true; sslContext->ctx = q_SSL_CTX_new(client ? q_DTLS_client_method() : q_DTLS_server_method()); - break; #else // dtls - case QSsl::DtlsV1_0: - case QSsl::DtlsV1_0OrLater: - case QSsl::DtlsV1_2: - case QSsl::DtlsV1_2OrLater: sslContext->ctx = nullptr; unsupportedProtocol = true; qCWarning(lcSsl, "DTLS protocol requested, but feature 'dtls' is disabled"); - break; + #endif // dtls + break; case QSsl::TlsV1_3: case QSsl::TlsV1_3OrLater: #if !defined(TLS1_3_VERSION) From d23d146175d6fab2ede50818777afe248ca0be23 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 29 Nov 2018 11:57:51 +0100 Subject: [PATCH 0483/1650] Fix alignment of temporary QRgba64 buffers on win32 The alignment of long long on 32-bit windows is only 32-bits, but we should be safe to assume it is aligned at 64-bit. Since QRgba64 is a public type, we can't fix the alignment there without breaking ABI, so instead fix it where temporary buffers are allocated. At the same time be consistent about using QRgba64 so we can switch to it enforcing alignment in Qt6. Change-Id: Ie15c305bc867c62a13df8eb2b1678e92174e1f97 Reviewed-by: Thiago Macieira --- src/gui/painting/qdrawhelper.cpp | 64 ++++++++++++++++---------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index bbeb9fd9ea..ca3590e280 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -3500,8 +3500,8 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64_uint32(QRgba64 *buf uint sbuf1[BufferSize]; uint sbuf2[BufferSize]; - QRgba64 buf1[BufferSize]; - QRgba64 buf2[BufferSize]; + alignas(8) QRgba64 buf1[BufferSize]; + alignas(8) QRgba64 buf2[BufferSize]; QRgba64 *end = buffer + length; QRgba64 *b = buffer; @@ -3658,8 +3658,8 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64_uint64(QRgba64 *buf const qreal cx = x + qreal(0.5); const qreal cy = y + qreal(0.5); - QRgba64 buf1[BufferSize]; - QRgba64 buf2[BufferSize]; + alignas(8) QRgba64 buf1[BufferSize]; + alignas(8) QRgba64 buf2[BufferSize]; QRgba64 *end = buffer + length; QRgba64 *b = buffer; @@ -4371,7 +4371,7 @@ void blend_color_generic_rgb64(int count, const QSpan *spans, void *userData) return blend_color_generic(count, spans, userData); } - quint64 buffer[BufferSize]; + alignas(8) QRgba64 buffer[BufferSize]; const QRgba64 color = data->solid.color; bool solidFill = data->rasterBuffer->compositionMode == QPainter::CompositionMode_Source || (data->rasterBuffer->compositionMode == QPainter::CompositionMode_SourceOver && color.isOpaque()); @@ -4392,7 +4392,7 @@ void blend_color_generic_rgb64(int count, const QSpan *spans, void *userData) while (length) { int l = qMin(BufferSize, length); - QRgba64 *dest = op.destFetch64((QRgba64 *)buffer, data->rasterBuffer, x, spans->y, l); + QRgba64 *dest = op.destFetch64(buffer, data->rasterBuffer, x, spans->y, l); op.funcSolid64(dest, l, color, spans->coverage); if (op.destStore64) op.destStore64(data->rasterBuffer, x, spans->y, dest, l); @@ -4544,8 +4544,8 @@ struct QBlendBase BlendType *dest; - BlendType buffer[BufferSize]; - BlendType src_buffer[BufferSize]; + alignas(8) BlendType buffer[BufferSize]; + alignas(8) BlendType src_buffer[BufferSize]; }; class BlendSrcGeneric : public QBlendBase @@ -4574,11 +4574,11 @@ public: } }; -class BlendSrcGenericRGB64 : public QBlendBase +class BlendSrcGenericRGB64 : public QBlendBase { public: BlendSrcGenericRGB64(QSpanData *d, const Operator &o) - : QBlendBase(d, o) + : QBlendBase(d, o) { } @@ -4587,21 +4587,21 @@ public: return op.func64 && op.destFetch64; } - const quint64 *fetch(int x, int y, int len) + const QRgba64 *fetch(int x, int y, int len) { - dest = (quint64 *)op.destFetch64((QRgba64 *)buffer, data->rasterBuffer, x, y, len); - return (const quint64 *)op.srcFetch64((QRgba64 *)src_buffer, &op, data, y, x, len); + dest = op.destFetch64(buffer, data->rasterBuffer, x, y, len); + return op.srcFetch64(src_buffer, &op, data, y, x, len); } - void process(int, int, int len, int coverage, const quint64 *src, int offset) + void process(int, int, int len, int coverage, const QRgba64 *src, int offset) { - op.func64((QRgba64 *)dest + offset, (const QRgba64 *)src + offset, len, coverage); + op.func64(dest + offset, src + offset, len, coverage); } void store(int x, int y, int len) { if (op.destStore64) - op.destStore64(data->rasterBuffer, x, y, (QRgba64 *)dest, len); + op.destStore64(data->rasterBuffer, x, y, dest, len); } }; @@ -4680,8 +4680,8 @@ static void blend_untransformed_generic_rgb64(int count, const QSpan *spans, voi qCDebug(lcQtGuiDrawHelper, "blend_untransformed_generic_rgb64: unsupported 64-bit blend attempted, falling back to 32-bit"); return blend_untransformed_generic(count, spans, userData); } - quint64 buffer[BufferSize]; - quint64 src_buffer[BufferSize]; + alignas(8) QRgba64 buffer[BufferSize]; + alignas(8) QRgba64 src_buffer[BufferSize]; const int image_width = data->texture.width; const int image_height = data->texture.height; @@ -4705,8 +4705,8 @@ static void blend_untransformed_generic_rgb64(int count, const QSpan *spans, voi const int coverage = (spans->coverage * data->texture.const_alpha) >> 8; while (length) { int l = qMin(BufferSize, length); - const QRgba64 *src = op.srcFetch64((QRgba64 *)src_buffer, &op, data, sy, sx, l); - QRgba64 *dest = op.destFetch64((QRgba64 *)buffer, data->rasterBuffer, x, spans->y, l); + const QRgba64 *src = op.srcFetch64(src_buffer, &op, data, sy, sx, l); + QRgba64 *dest = op.destFetch64(buffer, data->rasterBuffer, x, spans->y, l); op.func64(dest, src, l, coverage); if (op.destStore64) op.destStore64(data->rasterBuffer, x, spans->y, dest, l); @@ -4922,8 +4922,8 @@ static void blend_tiled_generic_rgb64(int count, const QSpan *spans, void *userD qCDebug(lcQtGuiDrawHelper, "blend_tiled_generic_rgb64: unsupported 64-bit blend attempted, falling back to 32-bit"); return blend_tiled_generic(count, spans, userData); } - quint64 buffer[BufferSize]; - quint64 src_buffer[BufferSize]; + alignas(8) QRgba64 buffer[BufferSize]; + alignas(8) QRgba64 src_buffer[BufferSize]; const int image_width = data->texture.width; const int image_height = data->texture.height; @@ -4952,7 +4952,7 @@ static void blend_tiled_generic_rgb64(int count, const QSpan *spans, void *userD int sl = qMin(image_width, length); if (sx > 0 && sl > 0) { int l = qMin(image_width - sx, sl); - const QRgba64 *src = op.srcFetch64((QRgba64 *)src_buffer, &op, data, sy, sx, l); + const QRgba64 *src = op.srcFetch64(src_buffer, &op, data, sy, sx, l); op.destStore64(data->rasterBuffer, x, y, src, l); x += l; sx += l; @@ -4962,7 +4962,7 @@ static void blend_tiled_generic_rgb64(int count, const QSpan *spans, void *userD } if (sl > 0) { Q_ASSERT(sx == 0); - const QRgba64 *src = op.srcFetch64((QRgba64 *)src_buffer, &op, data, sy, sx, sl); + const QRgba64 *src = op.srcFetch64(src_buffer, &op, data, sy, sx, sl); op.destStore64(data->rasterBuffer, x, y, src, sl); x += sl; sx += sl; @@ -4994,8 +4994,8 @@ static void blend_tiled_generic_rgb64(int count, const QSpan *spans, void *userD int l = qMin(image_width - sx, length); if (BufferSize < l) l = BufferSize; - const QRgba64 *src = op.srcFetch64((QRgba64 *)src_buffer, &op, data, sy, sx, l); - QRgba64 *dest = op.destFetch64((QRgba64 *)buffer, data->rasterBuffer, x, spans->y, l); + const QRgba64 *src = op.srcFetch64(src_buffer, &op, data, sy, sx, l); + QRgba64 *dest = op.destFetch64(buffer, data->rasterBuffer, x, spans->y, l); op.func64(dest, src, l, coverage); if (op.destStore64) op.destStore64(data->rasterBuffer, x, spans->y, dest, l); @@ -5472,7 +5472,7 @@ static void qt_alphamapblit_generic(QRasterBuffer *rasterBuffer, srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied(); } - quint64 buffer[BufferSize]; + alignas(8) QRgba64 buffer[BufferSize]; const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format]; const DestStoreProc64 destStore64 = destStoreProc64[rasterBuffer->format]; @@ -5482,7 +5482,7 @@ static void qt_alphamapblit_generic(QRasterBuffer *rasterBuffer, int length = mapWidth; while (length > 0) { int l = qMin(BufferSize, length); - QRgba64 *dest = destFetch64((QRgba64*)buffer, rasterBuffer, i, y + ly, l); + QRgba64 *dest = destFetch64(buffer, rasterBuffer, i, y + ly, l); for (int j=0; j < l; ++j) { const int coverage = map[j + (i - x)]; alphamapblend_generic(coverage, dest, j, srcColor, color, colorProfile); @@ -5512,7 +5512,7 @@ static void qt_alphamapblit_generic(QRasterBuffer *rasterBuffer, if (end <= start) continue; Q_ASSERT(end - start <= BufferSize); - QRgba64 *dest = destFetch64((QRgba64*)buffer, rasterBuffer, start, clip.y, end - start); + QRgba64 *dest = destFetch64(buffer, rasterBuffer, start, clip.y, end - start); for (int xp=start; xptoLinear(srcColor.unpremultiplied()).premultiplied(); } - quint64 buffer[BufferSize]; + alignas(8) QRgba64 buffer[BufferSize]; const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format]; const DestStoreProc64 destStore64 = destStoreProc64[rasterBuffer->format]; @@ -5801,7 +5801,7 @@ static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer, int length = mapWidth; while (length > 0) { int l = qMin(BufferSize, length); - QRgba64 *dest = destFetch64((QRgba64*)buffer, rasterBuffer, i, y + ly, l); + QRgba64 *dest = destFetch64(buffer, rasterBuffer, i, y + ly, l); for (int j=0; j < l; ++j) { const uint coverage = src[j + (i - x)]; alphargbblend_generic(coverage, dest, j, srcColor, color, colorProfile); @@ -5831,7 +5831,7 @@ static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer, if (end <= start) continue; Q_ASSERT(end - start <= BufferSize); - QRgba64 *dest = destFetch64((QRgba64*)buffer, rasterBuffer, start, clip.y, end - start); + QRgba64 *dest = destFetch64(buffer, rasterBuffer, start, clip.y, end - start); for (int xp=start; xp Date: Fri, 9 Nov 2018 17:56:08 +0100 Subject: [PATCH 0484/1650] Read font selection flags and use them when querying for metrics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Certain fonts with multiple styles have the same family name. When loading these as application fonts we were not specific enough when querying for the text metrics. This meant that e.g. the bold version in a font family would get the metrics of the regular one. Fixes: QTBUG-67273 Change-Id: Ic988d62cddde0a1f77ddcaf2891cadc21c9b31e6 Reviewed-by: Mårten Nordheim Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../windows/qwindowsfontdatabase.cpp | 39 +++++++++++++++--- .../windows/qwindowsfontdatabase_p.h | 8 ++++ .../auto/gui/text/qfontdatabase/testdata.qrc | 1 + .../text/qfontdatabase/tst_qfontdatabase.cpp | 29 +++++++++++++ .../auto/shared/resources/testfont_italic.ttf | Bin 0 -> 64136 bytes 5 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 tests/auto/shared/resources/testfont_italic.ttf diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp index c70d507b99..9ff50bdf05 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp @@ -1490,7 +1490,8 @@ static void getFontTable(const uchar *fileBegin, const uchar *data, quint32 tag, static void getFamiliesAndSignatures(const QByteArray &fontData, QList *families, - QVector *signatures) + QVector *signatures, + QVector *values) { const uchar *data = reinterpret_cast(fontData.constData()); @@ -1511,9 +1512,25 @@ static void getFamiliesAndSignatures(const QByteArray &fontData, families->append(qMove(names)); + if (values || signatures) + getFontTable(data, font, MAKE_TAG('O', 'S', '/', '2'), &table, &length); + + if (values) { + QFontValues fontValues; + if (table && length >= 64) { + // Read in some details about the font, offset calculated based on the specification + fontValues.weight = qFromBigEndian(table + 4); + + quint16 fsSelection = qFromBigEndian(table + 62); + fontValues.isItalic = (fsSelection & 1) != 0; + fontValues.isUnderlined = (fsSelection & (1 << 1)) != 0; + fontValues.isOverstruck = (fsSelection & (1 << 4)) != 0; + } + values->append(std::move(fontValues)); + } + if (signatures) { FONTSIGNATURE signature; - getFontTable(data, font, MAKE_TAG('O', 'S', '/', '2'), &table, &length); if (table && length >= 86) { // Offsets taken from OS/2 table in the TrueType spec signature.fsUsb[0] = qFromBigEndian(table + 42); @@ -1536,11 +1553,12 @@ QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData, WinApplicationFont font; font.fileName = fileName; QVector signatures; + QVector fontValues; QList families; QStringList familyNames; if (!fontData.isEmpty()) { - getFamiliesAndSignatures(fontData, &families, &signatures); + getFamiliesAndSignatures(fontData, &families, &signatures, &fontValues); if (families.isEmpty()) return familyNames; @@ -1553,14 +1571,23 @@ QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData, // Memory fonts won't show up in enumeration, so do add them the hard way. for (int j = 0; j < families.count(); ++j) { - const QString familyName = families.at(j).name; - const QString styleName = families.at(j).style; + const auto &family = families.at(j); + const QString &familyName = family.name; + const QString &styleName = family.style; familyNames << familyName; HDC hdc = GetDC(0); LOGFONT lf; memset(&lf, 0, sizeof(LOGFONT)); memcpy(lf.lfFaceName, familyName.utf16(), sizeof(wchar_t) * qMin(LF_FACESIZE - 1, familyName.size())); lf.lfCharSet = DEFAULT_CHARSET; + const QFontValues &values = fontValues.at(j); + lf.lfWeight = values.weight; + if (values.isItalic) + lf.lfItalic = TRUE; + if (values.isOverstruck) + lf.lfStrikeOut = TRUE; + if (values.isUnderlined) + lf.lfUnderline = TRUE; HFONT hfont = CreateFontIndirect(&lf); HGDIOBJ oldobj = SelectObject(hdc, hfont); @@ -1581,7 +1608,7 @@ QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData, QByteArray data = f.readAll(); f.close(); - getFamiliesAndSignatures(data, &families, 0); + getFamiliesAndSignatures(data, &families, nullptr, nullptr); if (families.isEmpty()) return QStringList(); diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h index ab6d6307c7..9d0aa7f723 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h @@ -177,6 +177,14 @@ struct QFontNames QString preferredStyle; // e.g. "Condensed Italic" }; +struct QFontValues +{ + quint16 weight = 0; + bool isItalic = false; + bool isOverstruck = false; + bool isUnderlined = false; +}; + bool qt_localizedName(const QString &name); QString qt_getEnglishName(const QString &familyName, bool includeStyle = false); QFontNames qt_getCanonicalFontNames(const LOGFONT &lf); diff --git a/tests/auto/gui/text/qfontdatabase/testdata.qrc b/tests/auto/gui/text/qfontdatabase/testdata.qrc index 81a0b5b0bf..224e845601 100644 --- a/tests/auto/gui/text/qfontdatabase/testdata.qrc +++ b/tests/auto/gui/text/qfontdatabase/testdata.qrc @@ -3,5 +3,6 @@ LED_REAL.TTF ../../../shared/resources/testfont.ttf ../../../shared/resources/testfont_condensed.ttf + ../../../shared/resources/testfont_italic.ttf diff --git a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp index da2f100c0b..68664cdd2f 100644 --- a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp +++ b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp @@ -61,6 +61,8 @@ private slots: void addAppFont_data(); void addAppFont(); + void addTwoAppFontsFromFamily(); + void aliases(); void fallbackFonts(); @@ -75,6 +77,7 @@ private: QString m_ledFont; QString m_testFont; QString m_testFontCondensed; + QString m_testFontItalic; }; tst_QFontDatabase::tst_QFontDatabase() @@ -86,9 +89,11 @@ void tst_QFontDatabase::initTestCase() m_ledFont = QFINDTESTDATA("LED_REAL.TTF"); m_testFont = QFINDTESTDATA("testfont.ttf"); m_testFontCondensed = QFINDTESTDATA("testfont_condensed.ttf"); + m_testFontItalic = QFINDTESTDATA("testfont_italic.ttf"); QVERIFY(!m_ledFont.isEmpty()); QVERIFY(!m_testFont.isEmpty()); QVERIFY(!m_testFontCondensed.isEmpty()); + QVERIFY(!m_testFontItalic.isEmpty()); } void tst_QFontDatabase::styles_data() @@ -259,6 +264,30 @@ void tst_QFontDatabase::addAppFont() QCOMPARE(db.families(), oldFamilies); } +void tst_QFontDatabase::addTwoAppFontsFromFamily() +{ + int regularId = QFontDatabase::addApplicationFont(m_testFont); + if (regularId == -1) + QSKIP("Skip the test since app fonts are not supported on this system"); + + int italicId = QFontDatabase::addApplicationFont(m_testFontItalic); + QVERIFY(italicId != -1); + + QVERIFY(!QFontDatabase::applicationFontFamilies(regularId).isEmpty()); + QVERIFY(!QFontDatabase::applicationFontFamilies(italicId).isEmpty()); + + QString regularFontName = QFontDatabase::applicationFontFamilies(regularId).first(); + QString italicFontName = QFontDatabase::applicationFontFamilies(italicId).first(); + QCOMPARE(regularFontName, italicFontName); + + QFont italicFont = QFontDatabase().font(italicFontName, + QString::fromLatin1("Italic"), 14); + QVERIFY(italicFont.italic()); + + QFontDatabase::removeApplicationFont(regularId); + QFontDatabase::removeApplicationFont(italicId); +} + void tst_QFontDatabase::aliases() { QFontDatabase db; diff --git a/tests/auto/shared/resources/testfont_italic.ttf b/tests/auto/shared/resources/testfont_italic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..0a01f883f4820bd90e39bddc406e676c6053d162 GIT binary patch literal 64136 zcmc${36x}6SuT3cKJz@siFuwQGBPqUGa~1#tjwCLt83`$uBz^?o|~rUE}EukplJpf zTDTWMgp2E9i-71tZJvPO6~!m=e2ChDa%Irxa7ExESMLQCu`A!V_lc}-yl*LMJ=d~2 zPR4X1;_QF_!}ovxzjt#y$8kRXh+KK+%#lNQh9_UV0r%>modX9sm-{h1za7t0hfZF7 z=H_2Ldm7JQ&T-{$9y)V&|Ghu*@PFjEf4mFtm#;oEJG$qoo4$sx_yC^YeA|7uJXlq; z4{)6DNsc4;-uB4DWv-3?I8(*@>YWe1;J(UtfBz#KC-*r{`s@qted(Rw{K@E>9B1w0 zxOd)s*B!UqE_`?H621@bbK|@4g8WPT6L?Oqr+(Lc4?p@pzqa}mz8l}ifApR^F5Ul@ zhhBAno+-T-{Eq? z*YFDWTVGzr7&-2bnjevNAHDpvctW^~Bb zk8$7Tvg|qiC5}pJ?<+V#SmWQqNt{T2g*=J(-jv+)f6R@ze`IH0`J?jeQ~Qz^PM$w~ z2H#%U-JM>;UHnPBQ=#wj-zLAp&LaG`>D6)X#BmVEdvQFA<06hTIIhC+I$?{qaJ&nn z_#B?U2Zx435VlAU_us&KIo$sc?$6==%eXgj6!7?V93R4QH;z>tAH?xTIR1S4`~$du z0_Wb99Nh2Xp2s2M*uZ-i@SESp{RBsh1MhP`jpJb)M{rIa_pinAIF7gB+&{*>GJWl> zxId0#KaTI=+!XF#jpGG4zJQ~TXD()%n0QU@cE%!d|7H)@o8$aQG2h;WpcO8Ee^O@TH z4*x}d%olhYmUM*sE*EqAcE61GF7g`pAh*hWp1Y5$aj)Zw+(E9-?dQ7O!tUQ;R&L?` zE0^E>#oecNzrRO*+c<~2i~AckcM|>zIH-+?INpX?(RavcfX3` zzwPe8&fmhm5!N)-(;^Y&HZV6Y*LtAA|;Y@bUr`TT(*PZCz2JST+ zo700{`92)@6?_|qYfBEQ$_H^!ouwl@H9b_^!xM4W;F#bzJ3Z)#uf_2=jujlgHa#FA z=@}fK!*fVX`aF(r;PGu7FAQ-|&-ZfNA7%%~y$tt9a2&G~F;Q+i^WV z2%}V-&SZ1>La|h?RBQD{Q*5<6-5%-B3}%OOqxpr!u{v2==2uqN);BiyZSCKNyFGOH z$kAiRuR3w{$y2A#Tyyr?>&~6OaQzK8UcBk%TW^Cyr=2|a zA)fya=Rd~p{?Ny`ox;a4kHSqCXFdiuT`nJZ;m*_i&3Hokc%fUtBcWeD__WYCc=}xJ zeEG@plSgiUvV5?7*Dbd{EjHLa-niq*^RwlrxijZph`-mIt318$eD2D_JIHp)7<$dpQPV;=3K4v^b=1$nR^oB zm_Gj)_sM_u0?+;P7xqnGfF$r8ki>zH@lTw@m*K8f$((eg}BC-NMwIZH*J|92F5;rm2h{Fg;ux-t-4 zbs3jmVj{2n8;QL7gNVHL1BtwTtoxwDel}No7fSMtzI=^Xj*?9o^PX=$G_&>7OyG#?P83EZ2I{ z_U%tP2c6Hl54+#+?)N_DZ}?C6e-QjicyHuKuSg6HD^ya2tIyxqEsSX5agejfx5%e}-_BrU12%$6ie7e5+p1~GWz@`hJES{>dztQ|UZs3r!oA+z@cNz#d-i?W<6=GDV*JRDzr=2+nK2JaF; zef%Tbd$|F*lUxSMeAje#lWD6}2c%Y|161T9p%XnG(CM2L>7>$k>4-N3%(T)RFSb%j z*yF2DbW?-4V?~x$dW{DZ}?1-!fIzGxnYT>;~Dv@_P1Wn)LtOGD2u$VnVPQKp(&R=JLLb&cP*#tRk~SM zkt_oFWpyn$sb?2*hR*9oI5X4pb=VWpRVyyE3b}Tr;7OjX z35s8WhoD*KMeZi@Me_5=_D*px-m?&y$(#8$Y9hQcUaXE&As#{68~h@(3~DUY79ig- zeC1T+)DaH&xVb>*fsg5#BsFy?O~sZJxyj$kR3Azzg_@Ddl_J+xRozOPB6LKMTvZi$ zk+)M>OHZXD&CeN%E2{kUYR2u)r&H}#F9(0)D!G|88*gTzG3F$_2Gcs@wSvWWTC+`eaoM%4L& zot4TL=K43>c)p`rx*&8fT)a3lIQyrfW2sPhVl8cL_^M0@^G3X2^hOK4JkRU!J7>5Z z@+$IaWVTm9f0^K5{!C<$PvUtTK1@YW-;^RVEvC*UPEFNRVm^clI0Zps4hB?t`7g?r z4EYc~w-9H`glu%nTLr_`H8@ow@~WtWKBjlPxn1sVyEYtkBMfFP-=oX2Z7$wFKKjFl znRE`l`N;UbyHrKjMbf*pe&oryW;+#Yo*SAmQHjDUMoy=-~@wzJH3 zNhF901`FrRtCAQ}Jt7$8DtR^eWw0OjT^TR4#_3@B+QN9=<{df`HrhlO7;=%vhy{f` zw*|?b2C5AjfUn%x_-V9C%=EL8qr$T|y+Ply1;3dKnvPL3a77YP1VJ!D1(zsbI+f~R z6!%vPLSWbGRgDPnOQt5Nm!DEyOOV}45DZ7d$SwH!jl7-lnQ+pTpmeyX1##AkTD8*8 z8HR2&FWz#o*__K8a9jbe5QT(_sgxi;)kqmp-dF6__G10S(XB{^@8vU*9lTVRMN5x* zLD)=-zyz8T*lH?K7a?tUVW?0yESFjxD#O=tHDN-&$_=KOO@r|{9_njf^?;LLgQsFgd_gD~`@APOD(px@?Byj$NJ-F<5%F@yGF|d@$+pzlGqaNI zXu|B7b=^pbaP+(Ya~0{p;iP%hMkIE~%QZyk*IfSIYncy!El+7RT;sdQgXDVh3}LH%P=3Cixi}WpN9V-%Ord`5VQf6aVZw!MH?T*_<nn)$Y0K;VJ9hXX4W$E=o$soHkGwd{N90ZW9QgwnFuSIU5QCS_87coC`l1^LxrNRi3HV z()@`$WEg_1`qgqJ(DM157IrgU*lAYNh9GM8?07You4N>+Z8!zXlX(mX7?XDN*GmgW{A7T?;AC|Q^9cu8Ezgn9ilX5t8i1&+ zgmI(>GlQP*yNVVMI!?{Y%>bi8Y(NWw;u!$33QShu)$r}Nz_wlz9uh)u_4`pH;3hJ)+~?mY z2B3mTZjB^q*dS2(`RaHyex7yFR3b>;NAeMm=OFY1jsgBMkKYL_Yw?!BHSamQc;6&H zFK7-_*)BJ#&g9<38-C&X(guI0rtyZR5mgZo`b}OEG^WZ?Af#f?5|EeD%)(F|-h`JE zfy3~Sx8uC&8+zd}HF8U*nmcdY*FIMFGteN#(#$CI^~P15LvKHv89fH6+aeJpNDu#L z29PRbMZwQx_-C1l5;-tLQBg%;F4Z&bjH`%poJ~PqJSXh_FLIpx6MPcapw`bYCiH6> zxaJe>#Hgsun5$r!I79X{Q>(&9?nyI=hI^?36*}@hi4M8n0*f#9b zi(@U{n_cVs{n^B`MBXc`v=3oxl3PW;JYux^G(fv=8rqREH;4;05EANmM_7-HEJMbktPJ<9N~| z_o7z$WzJ#|fki>&#E>0%o8()P=pU+iN)XMG-_kW=>a~F^6cmvL6`uPBCyNix&D7G4Eb{`U^x{r- zOrA+{%}ljncP`#~ORuY_g$2^cs{rLP4af~f1}>Y@yJg` zbe{K2EwL$fJyY{a0IEpQ6Y(_5lEbDM8K#k+KeInK%pzg8O@RqXi6%YWEOHEt|b+3%WNHm_|gK6xBpBYiAhvD)h zzd&4lUPwi5)=;xnGR) zkKPU%MKQX!-g!%#DNF5!TW%olrx&yQ!2J&_v+>YJe+4af<**O}eN*ifi~x-UJon|@ zpXM)eNAdd6WJJhAVH_Z8qXJYzs0`{ zSs&17V=uBp@1R}K#_?z}t}0M9{xCzLqN14D*i>>3g6rfMTfpCvOJqXJnL;|Kz zHDjlHs=W<3Ch}Xa*hwwS&-n<0M2hAYC+XpZ>o1Pf$;Pr^CZPxliW@Mws~0yas|=#8 zKfWF|n(bH>WJ}BR+U->D+_|$Yxi{Nn^5s5+81)g@?zz3|Wlk=+RLU?iUqizZuJTF@ z+DpbDHF`@R6E)zyo524a8;m^|HYKlOx{=E3p!PtUY3WqBwmxxG$I?lv=cH%sx^D-5 zIAdB_Ev=;B-3zJo#=(QdQq9y|T?97fwb(anzSSGAkk2He?T+WQ?7nR4cvJP%u-T~E zZibLlt?g4PMVWi`EAPUnMYTXA-ZWyn^@0a4&1cr)^stpCq!PQ$c0Z;0TK7b^u$}kU zRt69V;qKo37C8vNUx6p%5XKW$!M0(Gi=XC>8r25`8Sy|BI$GLPPUiU2r?tN zp=ws(iiNCWDq3L4;0CDjtKB?UKr=L4&roIR#AFYyP>cH+r{yVX;>~G>ESi`TJuNaj zX{mx?CRQCb!rK1Y+GFe4g=}t;)0}Jucvb_LtVrM?Scr1fK#_16UMdX$#;aOpoK8=& z_)z_D!>hs$R(JoNYytbwXuzaIht48bV!BlMaifA6PZq|o4tXycjEiDiB-3X})TV|) z!v6r$&Q3_pVtGflHQ?CD`j@g2FC(^L6swE41qS_qm{ z77?Lo+Ka@?N)6Jr7N{4~F`E6p@9LWDS+Zn?>B7;Sv5uSfz`SmHfdLK>2udPr%tiRsO4WC>w(c!w=PulM$7)o{rtQuM84eLsh6IZs z0{B|Gc2Xdtm`j@ z?W-GBZ?rg50TV*xawn+|eUOvLFOqN5&Xv7biz%4$%adW;Dk62F@{|#mX)aWRI2mwg z(J;Xb9wMz`cA7Yie+eADSNHwRofXs7%01Vw`Vnt#97v^>Z&=PADrVc&vI|V^sYbC{ zG1nisW+V+JMq1$0VKxeFQ0lzezIj0KWsdAs$bW+GB%UPMnre)e7EDW5@}L!#&)j*} z?Jd8ft6r(BFxpZq6hkR{^5SjhkAysLq%;NKDiVF);ziGZKtS)9u-`x0{b}-U@<-?c zq8{xEq!8j3n0IP@aA+8Djp`kEJ%x^MgCK)%jwvUBSoItTNkGe5aN&-{Hy8f50zxL;-e<$3Z@BSJ2WueTS;2ydn4_;}dn0bwhm~%1> zOcbF}bOwZ(ibE==>Bv!Xm{M`n)i+ys8PeN(n{puzUxhgLa&1!OPc!@R8j2z6B&hlE zOsk}(${w*K!?9+=_IS|E*+l`Qhmh0aYGbBq77R&MBp#eLJ{&A}kgOCmm6tnJM2FPk z(o)Waav=s2hq`o16!9#6elD<6*o_QlBHll zGhDiK&&7sSNIN9RSG+i%t%K^d%~+4qd^Vdub>^y=;eq^0t$%n>oz!hrN|pMwyi;At zA<6YxPC<|R`Rl&?c+?lbA|joY6fJYr4R_A@Gs9sR=R8BvZKxzhskugWb9JEUshPDr zLk#8lFjKVk)a+V5T%7Ny7(G!e$&^&nNN*p%y8iHo4^n9m?gP8K!dJ-Gxosv5Hkb-> zlqwC9Q>ie|y@vuBB;?~31ND1eJWe1UT+cK}@OLttP4XtvdrcEXCuesiv*T7gnj40_ zBQ4RiTs37$76^ERI!o5w{M?|Q4(I0Q)0>ZM#MR7o&mu(yLR`9Z=@J8o`qD!$x<5#Xwd$jp`9{=gb<@Lp<|WU?^u*1MP7!a|^K?1Cv9+(5>2=!C@w>1Udcm&1ZxhHo2g!~=(6YfQLk_?1O0PGVqVsF|pKgCtl93^^I zs)+(^N=`x{Wesr7?4E$ggUscG&6L-xg^D`bKDyCGQB}6KuD@rozFqFE7I{a|OxGB{ z;SG;7KhjGD_UA-aW(6= z-8KxtR#J;AYvfOo=r5>Jw%YRjV!l}I<>Hy_{OzX}M9?r=+}fDave{T|Z0{T!guP}F zS#JWwk#KcTd8{oDd%ZzU?F_m)Du%EtR|>Kg(VW8XmU5JZ~n z)h)wfG+Vh}EL>e9U^Au_aE3I-%cF#;xNwJ zyr>0gsuO!PkAb4|zi|Hi(-)XiKL7Oj>;I4IO$l6)fPha7!7aL^J=+#EQ3K`rY|4rJpfchLVs|CrkzWv5X8a zu5B>og0F^B!Pg+f^WWn^GgERMwKy6x84~1G%sc`AfPXTv@+hFkhAd|?{s9K#MNwpc zLkTrRS=k2N5(`mIRz*{Y%H(HtOF$ig7O9ZEpyG)P6*MO*R;Z)%D)B@=rCS9z)V28X z`xELz5^)&{Do!+l!`lj#P6urnL@Sju)SvwB?gxlTny90rUpKL$s!Stv1Yk{5G=&v# zX$_LXmknOn%QETQ+k9)xFbw~LGmE_Dzj6+3XV3ATT%q$n$s;Z+UAPk*nzd>C@R7pF6YN-STZ=O$q zUa*n*LU(!YgXC$lO*@JC@m_?aUSN|SMhL@j3D4cYGf_{_s=?TssI}5U8S@h~kdSxk z765zgz|K}NtVIH9^Tf7tTZO3Up!BYo2zm-=XAgZPGBB9yn~e^Leup@Qrq~X^+P+tj zO;NU7$?43_r5&{9Ul%`958*VEXC zjDq`X@-;%xRo%eI_DUYi+YM;Vmj$zAWSA?ewKD$%bLQ8)?+oL_&i>RVS&p;z*s2le zbec5WuRg|qDRCI$v{oyABYBQq3@~Uc{lL8n*=}&Rlm9}_absLT!i(+IUQt<+l*uTZ zr)=_=g1x=qI-%Dx;Q8O6%ou8Ko*mV)TBzxkym;jF;YG!T7Zp&LM-zpD3g95Olt;3o z=oxKrge*~VES<-HwPR(?gL_qS)mkYM8t`MVZXTxwjnFEZXqzaZ!DREzhzA!qN$`aZ z_tX^~ppjsDMM8w;B#4OBKWR*$b4|-hQ!|g;6G6r$3jqGLb79a=MM`2Ed1}IHh!PV^mc#6~7mh_mMnPQW1!! zT=Q+oE{0CgQ33}SVYP#NuaYs1X0PWJH_F}P%T-z=svYVVwp)vjKXP+gHZ`E|_HcxX z3ox5ru$yZED(XUf@0k;?f8>QjwUCeD(0QSRO9mb5f>|Z#0qJq@XFQG#s3d-dw zib%wzb#Tct;f+)TD?vgA!R$+j;8x+m;i3g3uQD$w5oVfql&YDr(ybWqCf&&H{1k66 zoYcNyo%zh+%_`$3XU^Yn^E_iRQQOOnGI6Wfh*ZhWF6C-l_1>wIC%f*TR~0oK5d=kP z1W7~{Xp){U77f86GiPTO?wT)-^W~kYXdq*qQCiAbn*Q)x+wz^IrOHzXh3Lk&^8qugS?uzv^j3-swU7b_SRdX)s!R|H+Q zDy#F|QXmjp@pi7ep`)Yi&nT@Gww4V6Z3kP&4_KMGWZf&!cKLeDucB zM%kI09~dh7RV3m>>Btkcyf#;oNT4>ATyu7DwHS?O(h3o4tdt_f;BGR#(J1s9e(&&7 zTW3tE77}r|&+WQKwN{i(j}J3WyW4gb?pnC&o$x&|*Cnq-KhFvH9_kF6;IQC2K%Am~ zlFAh_0^c&t2O$#*B}7D_#1kcMXM_gIQHngCI7T#PNt!OGs$v?go$l}jHy{UaDl@Y) z&i*%D4UR}8j7>LZ*S9xD*32ze50S4)QYxD>DkrWvKNEE$)HqV)SDDYGq$Sc?G!n$w zqvvj&OAoq@VkCv22SAUY4Gn~N0Df5(^w!3iMf9B7)oRJ89NC&f+9I&EB|PxLcZ40_ zrkgR&1PM&dh<5G(Gr;Fl)Re+druF!Z1XCl@A_zmZXy={ClHjR+jQ0$h{|^)(D0E9p~=-<>tx8}h#WYWJdbKug6x*_L!<7#$id(}rh!d>3l%rrJ;%d(zYIeXWO zSEIR6&sGJ?fqw$~gl5ku2MUZ(afM`fJ?eOr8_peqq z7uq<_i~}i6vWZZ;m!Ifl_&GPs;UJgM8+QCc*$^p-X!fdd2_B5AyhN*#!WCLzf)LL`nG*a>Q zk>;77IL$oAsh>P;ma0`dUKlh~QAd3Q4RR~YxeV^v&m#Tgev3`M64ji5Axr0~k-+U4IJi}dLvuw9#N9n z{L&j=b$5=n)@AN~;*Ad;x%>&{!gCq)hb6#P&@#Zad91bFfX}Y{b6*Cnq7I6wGL2tU zp(0wlD=*fps)H606>*9(iz+y7%RrsJwn#qAV$MfyY#eT;`mtN~*hTp@KQou9Y*lXf zD7B&2VwLWr+^MHFI9w z$<0 zTjg?IZSJdv6Q6OO<2(9Jt<^zKu`KCfvtF@h?xOSlw%xzrKTm$^%DnGM3LHYK2$%p@ znWEimxIMq2my%J5%-CO^|5;`ocG;@0w*791j2XxU(~N}7`Z zsBjBaJE|>o`hjxM_~4WFr!#RG=wR5UM`-erkDWmsc!3 zPPu}l`;pjI>ofDiu4%*5NwCcz69oN!*PC30^&coAcW=A%me%C<#q2npa?EC{3IZ=% zuN8o-hS%S4^J48#!!9})D?8g;t>yc@VP)~g^XG@6+3EN4lq+l34L+Vv=jP`Za_4>p zbE@qA1>)g%IqVI9JcETSOcsU-GWLqXBP`)DB(q0AV1>w@%$^URs2phcV>f)9g~_Rw zAlpRzT;Q>=Ko`?%1Ho}D@JJ|>hXY5~RM|(Sj_eGz3*w_yNL0Y5MtmzsyN+%*t#YSG z%?MpeR?F5MFB|GPBBV7VRB1;;UUfv(Q#8lv-`NJ2M9`;XNnlv4*gp9qCupA)TE0wO zs2r=Mx{+6gWue}$SaN;4*1D>-{Ls?E?Mq??g2^@x*RT7zYpIT1`*YVe4mEO<@nY5% zoUKPT&;In;`hg~BF+Z0tN4atC%zLjPSk^-Pjdc{#;2W_U!H9f_q9^`JFA#MI5Nc}y zx&vrHaRIGwN_&m)iQK?S;Uw~UMx%`$e$fk?8FU2C9J*m@r zH3S_+mt7c^nKHe@=Pp#yZ`@dEn8A23xb@CE$xkx!ObR;($MvJt!NIO>*~jmA(bymK z%7Wk$+KQl~$eZ@uxSEZZv+3D%<;Z3q&eXCNc1~Vxt&DZiUN`y1zy zl=8Z3&otwvi<%6GLCrJ|pFZx@mWqXCg(>#g_n*D)gV)KdWNQHYs%bkr9M0#`bK&|H za(<+g#4q-8UO$TJ^?Io10V%;eoO$1wv+t*Ip68AuX1;+u%e?{Pnf4{JOQsCzcyTgD zKPMtPRo}#~)6@{qEXKSsb~I!)n>~hv@u?U;ReHPzettspgAHmwi6vAi8dRRQ;N)KP zD{6s~nQ0ZRsO|!#(4_J*@K?7F75oxtM!c)|Xc+{=2lTOXky`I` zZ3uzY&SXPRFD=cvrJ93sub@^anJNbRwpT140LVlOZ>g1a5lna~8dvmOxfN+C6a7I7 z;J|e^UZ}1;x+c1`TxNJp*bFd|gqrr^&f&D5^NaKC92g%9Uxd!dm&pEKJ>M{86{29qxD4IiW*r}w74~VbJfoJDDy;jEJ zt00AEwQ|0!E6}C9Pb);#O?~ zIzVlJaNpxf;tBG{T!!vH0a?NKjOq|i;<6#QrU-dWR{%`85!gov*EO~NDFyTtzxM99 z-|eLsQ5*Mqz4$+0{*9MVY&ZYFI&s5{&Cm@>;Iuj_cnx>qMsg1`R8-;>fcXT^f+K+T z-b~%@lb8R;56kVDCX@vYUf@`hLM?LMm;85N-V{f`C%={Mra`M7-=`yV5eX7A^iZM9 zJiXLusG^IzV9rPl z4C8bZGd8k|+4Ra}#w=`Q8DzC9wVIQjogHRMGjmN(2k3$Anzqw(yJtETY`&5BuUGGW z9anjodkx10tegdJMICV|X?vu@Wzz`M4ZE3EO~mrZ4;1@F3|(2s1%(d%~qmx zC?Hig4c)9-VZmo~Pmm7{^aZ=7+j8}Ep&SGnT~5NN9k@8$%eJgzNs^piNLiYW5;8i} z%aO(ZK9gzhy6diK)hg()6pUh{R7z`T#a1ZI5XF(~_4;j-=$)CaDP)Tofmp<@Ibj`! zoo5sg?!Af^H2t^}yS{w0V=#DYEOsOLx+C4oxTUdvgEYM_!iL z&kK-5ln_JO&#S$`#U~a7>4P9j>NCt+QPe2VP=mQiZq$g_YQw2cq8Di&6)T#~5v?!~ zMNl%bf*O+Mph|;CUlem`ELf7r2T^njmp8YH>29l&Ni9zXnxD5--%!j-Ifb<#QKr-C zr1P7rWAcea1=q?KK5#}Uf%UUI+bY_$Xk!;`EU&%qPapLvjK||l zG}Ec-e$!{ICeAPyRI9ZpJsvM+3d^e~vJvhJTqqdiA5qhpgB2#U7}XFV>Eut!(k%bP zcqRS_rMUX-iU|BC7MmUZCr}athnlaq>lxw5Ee9thhKMUGNAEl?=NjF1o%}ko6RSNt zj1ZB6nO=Q|wIuLyrCG}ghaY+IYp!8{;M^Nt{<33ozR|8_a9w?Hd-sz+Q*>km~ z6nLG~6~df?+dakK1Nf7@mLJ5JS&XMdJAY_ikNJT=*>ffA0dp*Prxj0Emyh6cn!AnKa;z2wo6->lbtix@aB?x(ijuy5_s{@Jk_VEL^;oC9w<&^y@% zl_!!`RYOI}9d^dHc^5uiF83MD$Wf$XJQ3($zN~ zVNF{_SFf}|K9d9)y7Y$^ zQSA_#=$XN7eD`?ip7AsUA#D& zNV?UjtEIPa0ZW2e{EU(PVleUm5avpVq0SRQmgVn;9XJ%zIdP!nRL1}thvg*bIkF@8 zdukU^1`9Hbz_+nz-cmAJoOjX@`7(nI&66jNS7}wAuN*94Ka1RU0TB!9An;KvdVwRM zuo`-n13J+?KRrpAfl)ry-2PF_!+UrC0ps`_#qvqir>=_mAgbwf5-8S1w?L|fOeMkd zbbJ$K$Pg{{Us#{ce~>Bm`pf1mEMH7#^@U>@FucG&8Zt60)#n9Gs2pyv9+J{#(J6Vc zq&sTv;82TmWqwp;nVG~{M=h%{L2kl$*_qiKkLoXyZ)78iPc&|TzA~qV;VI!16}ylMn8`mIccDCz}UL$-07}V#ERc|4pc#Vlt;3T5~&Z} z!u*J`l5qo)E)~JQ(nfTJF03_)Qm1g%{A!1kdI&Cjt`r&_OBQ8$%4aq3_oI1z{*y4H^t z_tA(2REG7ssyp6)_|Rq?%?<~l?K|^Jb5`x}fz3>i=8Lsxd3EeJb_zYZci|(uf6af1 zJWac`A+qOcg-r8P5qf{2Fi7$k&V7D;mQEH$Oi3b0#m!_p8A!DzlOYW)sc?@yp>pK6 zDO(YBuu9C(ix%QJP%t5CR+U+472G;eKx~w|D=n{O`lh7liZQo!q6Kz>)nbe58>@Ll zeAHkyU76e0&!Z3zwN}MSf0;IB7-oew zYGC5Ps>CyKb$zae#yHiS4Z}gUxqqPs;y$r4f)(bKe3``MdNC9#tH)Y$shS6^k5rKN zszK{ed*emx<+GAbtKI^W{v3sdJ<5n^sAf_~a|t8_u3O6?TI|M@tnXNt(1Q z1a6Kt&%NiO~M27QpQ&oJ3%B#ku{p;gqfc*?`{TsV~PTmV2c=3PN z19qiTPJmA1WG@M&kH^!N3V3$dOJcxODNr3{wnNWhH}Z0t{@9sNPwS~t=yiSFvaGzI zcWIE4Y+0MzfArv*>lOB$u4~8zXk&z#vW9mauSEX#nH#Rz?;@yLq84XjO~=A>Q}-Hn z+;X*|;bq7t>5R8dwo~2I=+;sDs&;B71^m|AZqgX;VowcO%a5APtu9voT3D@()&|uR zU3>n_d~dT8NI3{S2(?19-mhZ2kyLf7I{(m2c9>~i1^K)i^ZOt9-(<)($qZ9;?-&%c zrnrgLJuuNgIS6s5sEG0l3*wQjwo@8c2oqOhDJvV!IimRmY-^me)H|j%!$Es8$G%+u1`A#G5!C%W5iTlS)xO8 zXu7DBO=+URv_OMT;`8+U1Q#UHmH#FpyzXE(9WReWp=5x_LhiS;F##=v`mL^DOBm{( z1uW6Wk|^|bZtrZQ(bJA4Y%I%$_a^nZ#UNX;vDu8Q36|^wIM^ujJ3P8_>x21pdOla1 z@r-n4^WZUll_44wfpp#N#8JImpj*L^Vyk7?%~s8T*#m7DSWadX2Bq!`?s-9{j4n+_ zigY7qu?$ELwN${nrdQ9D50%47aIrip*_ABz9xC?+UanUwId%mceRsKBSs9?32D!cr z^^V^|ZS5rW6Al1Ot_EIla0(&^5_60(6Ke^Ks3y zO5}qYI?0r!M^?99yMOq?5vVA~mJ4h7cs5i6&k)tg_NJr8SSFA_iP`aDm>s4NiKL}N zheFhfbk&{n-n{=c`^Qip6k4GB>*N~XDeyv9R=rUGuEYzh-j(!-1xz!T?T@Kjq*elu zIEI?hHG3$91OvKB2zmyQasa_00mO1MA+_|Mslua+&MZc$8n!M$H>TmZYPPco+w%%FN|3(`VWhxc?Una!aACBylIPzJudeZEBoi$^ zGQ+K{1?juyo!)=Vx3*qp<#DC;YV@K;Ue`Va9hX6_t(tPChidqcpt zBr!b5<^$2R)3^}$F@d{&_uKrF6l3tCQaS)b^&ZR=R*o$!3_Zg|l`vYEOcdHCnd%gn-WK}g6EsTQ_h0YZ zdSXAD*R3bE#`oQO-(@o?MHU-PhYiK=G>aM9EZM)ImFz)uBg6LGpCJz2hxK)+r98J~ z4i=r{39Y2Wxb8jYl*D3$qCE&k$1?@D&;edkUF?K%?K?I+aO2QNyd`6+nshzuQdkQY zAp(0#F0aQW6*~bqUM6&77^v3LKB-vxhn@3iJNO{`EA zr{jTJX6^;R3B6ZzasXASYoTvprf5=$)Qo}A#RY85*22T2Gw}N$En0HqHM)|QoDCUpX!9sc7w8u-Cck)1p&E|QfXAx^_Q+Uk2Hms{PjyTYuyPn^D{%k-gg;K2Tp32Ccf%|+eI1_nZbDdB~kYp>0cmwXd@wW(V3cx(3J z&`eu#56d2@UskbO^=pukUq$)PDT~I+i?pD&=bRDjinLFMxd19S$Tb1$cm*6MSgA{t zGt;q54|%^}d9H=VZJzH+>3qoyn$cj8tzgNAEWyQ?OfD9hdrf6wa~ZXhC{naCZA;;; zAc{kN$hb1AU=x%BdAZo?Hu9nZ2F+et8=GFnNUNe86ay@QC~uaT0O}jdlY&RmbmLXGi2v<<%6?U-S& zHxtc_8#%}vMS1}9bS+z2DSEj$ZO>6!2)oXImH#?+CVvpl3%WjynO8<^{8O#K6ZsNu{~5mAt2-k zk`J!S4QQH;v=M)02iU;2)iCb?D=^v{jU^$rl0jC9c0*xsVRjxp8-#oFe*$6K){WWGjOsMVz|A<^-47JC!hu}Hmo6mgRyB-0Nq8%uX`SV9`+Jp?Lqp|=9nKbPJnG~XZmh5 z!lLF_cS=?G9J=;4y^yg*=h;7F!Y41iDX7%D`Jm?dP-tBO)izUT%(sfz4)3y-?0|#b z0rd0Jm`f)Rf9Q%)Z1#!qLDA6Qg7p zgNmI08A=XR4rS4TO>2TY?_(vNSMLroVcG}6EBG|3YG%GvanSYdntr2JFw*UUi!Nwf z7}ndI;s1hq$7_G~y7sXabGG%h$x=D!wTrT7xGwfqVbN8u~iu^NHy#g@1dS`VaefVM?!si$R1LpeS8L-k`sR_H9zA;|V~4(P+9?+aJ_I3Z4xE!`W)B_NkCoMM zJ*F`TQxh<7N;;o6-Lm5pUAN>!0{=ZW6$TdnVu`Dr4opD8%y7oVrcq17GQzd2IDR&u zqOq{59jo8bB+?qD;Mc;Q?IP58gV&NUn2 zZ`1Jv6RdF;bT}U~04E*JMWy)|>(r50V`W-oI5Szh4E{p<->J!8KP$!r8ksPS6}|{ zoekNXc5~Tk@9vkpdYgXIskp0;jPt{SU9J?+scL#^ezdsW-1kbz-(@alArPo!UA-8VrUr5!7< zz^h?nD!G5>$jau+URcSvsAtn1_5k$o5qwU<8D<*Ge~MdM>p4A^g%E{FtopK>*focC z^XY+93N+Q`|A1wv`(C!T`O0~$hsH@*Q%C#0?AXMv5pL13s|Ki!SV=8SW{jOzZ28?z z%k>2(XBlOXr^pCV3ZqdD5QCscrlfbzoVliNp=&PhrDg~H$Q!M0SFu?cI97H3iOr2y zP`^gF_w9a_{5c?Fk!b@BUlc;@p@>9C$bXo4sYIzKry~10+kq`pFBP%J4R&fkl?_|n zV*A6i+Meso91JY`rjK7N%+@k0_2YV@KgwMEIR8l&KALB)J=Zl$$kYrPU?J?{pfrY+`3>%IQl&99(zrz%ISTJ1vNk>z`J26w+ddQZw?tlFoUcWy^H)UXfrolQ8J)*Tuc*~}Yed-Kl zZe>B+dE*=3umh&Kdu=Ow?C_d_g%geh3i=Mr;SOpZU*Nw7u9i~I45Y*>u-<9^eB!mH zz6%DUKrm=paCm@yI^UG213gRgrl}Rde8v-{iLMc}?^0f}N+FHFU}RFw;X_aoXWn^C zuAyFSMcHAlb*M3W(_D6xlQO7?f^`P86NS5;c>y-UrA?gJl|q&c`vt%Eg0!vWOGWeG z8}~I1bv0mVM}@cLK}j1Bxb3?~-~N79D*6U%m*GDRr*1Q}X@#h7QU&9;1C<$Cdsnj zc(#j$x$t*}9OQClAedN$BQ|G;t{Y;fC&5y!W@J^6c2i&ztgH+*2T7rh{xYT2uL%U( znIabpjR4pLUIN$!`KPEh7dObKlB!R+H}w5dv5ekk5K9#*axJPCv!>bXwhSWxjSlaG zh)(HlPc&1i)6e)_tT(`(a2aeUjNL$G@NI}Lh{d$KM~x-75#%<7_d|lCmNUva92&~0KIbX4Tv^Htz#|e28JDbt13uRl)&(Dub5V4wpq=W3R-;0q6 z>5@snc{>DcL5c|AjQAo)sCLJtiWXT&`(Q76ntXueHj-P)7Pf1C&Ccqm8`Eh)6R%~c zHd1A5!K|B>WRJ!R*dj(PG<<>fwSf&pmz5gVVkA0ISgYl7KDLxaz6Mjo<^w94S3T3o z{lA302YkC%dG~Eewk*rmvTVtcm%O(u*|OyQpWb_KXAwf0K>{Ixq$C6y3TXqBQ3!iJ z1qzhivZ3r!2&1epT6XADD4T~;-}n3do!kE;eLkP}ecSMp{5l1Nxb)GnKX&ODP-)dekIjwHBlhRXCa001ei?!#FiL=EY zYd7(=&B!ZLgN>0`bxkzV4M~qBuo_VgPd8BCnDo~Ua2$!kY+|_}nY%06(bboTHrH0O zZK?mmI!uW1(xyyRa{=*GlhIJ7&NoJ?Lg7F;yLhSY&eHf;AzhBlr>?BFKbvn>xE;SH z0|CI}s)Y06;kcUYKyNVG7WE^`HPbWY>Wh)ZQxKsIZg81ny{m8zHX{$3Ss1Sc?pg83+5%u|xf%6PARwY>~*8{NpN>a6k zDD$UUnm=ZCV}i**)47KFbF~!>sXDZ=x=FqgD%TCO4d$<-gM)n>fS0{#sQyAKm~iUV zP3O*?Yib;y7&n#N#_{p-M!0(C+<)rq)F8|=c@~xGlHP1jaaC7!$709w%T`QK$li48 zZ8txz2huY8yq*#hhvw~{ac<2SJxQ#@d&+6Jq!>OO-USn@<%#^~ab06h;PY38I31k8 z<}ddqIq!(-Qz%-AP%KeW-QeS}eRoB)HfWd*rP<*uWdyd9+gCaw6K94vj^52#1+34* zBNwLXdbWB4*<70DFm`^!Ik|ty+0nU2dC;S#Q$>}+!(LLuB;^-G zoLYxAa%9nSrry`Fl!3Go_6Jf;jTJq^eVvIwGknl!+=~?6m-JVV7)r;%d{a?R2Lr_6 zh`X3tUvt|)SG>2TVPvq^>CN?@|C6%Xdbq|g44FS`k`<|FurZYiFdwjun;deUXAsZC z6a5K})b+KtHI;!pT#3e%w=I(%&$f5P1Ac#%3g|qw zBN5B9OGRGWI8oD3=MQMJTDbpt(PR}Vx|(GUk3GnY3s;?TwJnuJdUD_3d6^^it> z!`S$ELo`1!7>2o7;$nj^TwC3r8)V|CI5DKr_0Wa3Il~?!3I;cz80O%T^6^xDugoYckm6qywq()Z}dwee2UBRS_y< z+QsIaz4F@0g}wabt!El1OrPqDKJUKVy=Ax-PN|bTjrt#lT9;;wWK_4bTJ`N%DQg05 zca=`5R;*;wcfHjFwyLghypv;C+ADZ`Lsc*m*3frxXo@?i2i&lhrEbVv&kjy}psyWG zP1~5e&uJ4imA;X4jYAP`Ey0D|9fqE`D>}%9%@a~JPTwvqhrjEsZS9G5oK4r#bnF)_ zT6O>0<8t;-AE}eUvuWm>jVyZ`X7ZI=I-|}wv)Sa3aG&Ozu_$MC?VE5Nfg;XXxoqLP zz5Q48wvIG~I-4Wx!IXIGf~kua&eX+Qla*}9F)016P=vOwU&5nJC4xxGFNq1)Ei}r_q63EM|#U+ZCaIc-cWf*UnYv6IyqMF z90O^lU*|Z7hBI|7Gwt!hU=KxPFMsO~Mr-QBb@K}sdDc%QYLQrZJnz0)#wa{~I5adm z81RKTJR1_^_VI3AaZMs#f|i;xcF1??qh^+N(zjB$a<1ZVG|-*yiv%+x6C>$BOi7-b z6Apb%i!F1{mmi?3{gAua{k)=Ujo!v27%a=YkK|ws(0Fc;z7}Ax;S~>0AaV`XXBy0| zI1Jr*DM{IBU4&)b=_qtI#}u}YO&UUmUs?vspwwSd%K=~2;Rew~IUbfdHq_OZuA-`X`E*@VA3 zp8SX-Ou+oga7#D_BEvyr_2UhGk~Yd89HYZ3rZ`wLGB&~~qKT%uGB}Mqr9e|G=hSgH z2|N4L#%nS)gI99MBR{RHrr0pQxmcO(Pn0E+Rb~to{Q<4*0B00-6N9|U1)Oj#Tj5)B zDPx-kms1{a#SGJtr44-bAe(BTSS~+M*>I+X{&g%h6uV;+XGSV1v&U!-f?Cd`FD{|1 z-ZI@Xc=cnh9t_r?mvs9Rs4~4{x7~W{SlQ56j(ZrlA9DSp`-wVNi!z$IhfX@CmPprT z?gjg5kVADWKsIAe%r{PLa_gY89c$(w6BPR|&xT_hFI`?2C`ayF4xJCiSD6Az5TG=x zg*Ei0%C>-)2Q%@ItXP8jL0xOSthueZEHO}H+>moLs(Si*s~aa9Ylh=q_-i7Nv5I6S zp~lN0PNptH&_JtHl4@`DRSpd0qOtkqsStY#+`tn0ch){}ecpXl(bdeWr%A9Gm1=tf zMKnXIr17K)&g^+=0#isl4PU08+##>Aj4~v4Rnjg)692OC%uro28AN(e%OQ12E_skz zNhr~p2u>|u43z4)eQ!x+O&|!_ekjaSj7o~b*+i5=SfZLIBB6zbxEk<8+?DO^O~L9$ zs^6-|dCC)AP4P76phzyG9+~gv*p+Ie|CKQv&U)tTL?YPT5(<>oQ_kVg>0Djvd_!uq z*_0@o#~Nd~L{)#bzp6Zys^NeTtEts9u(exM={o0(y`DPYz~$MgOve)YgcEuX}Y;(D1Vmy&1mG3ENifmnDEg@g&8CrltbD9N1uHWbx_)aq-FMi+YTM=aREs6q9_56>@+!`N zt4o!cYP7$-8x z2DXkXGCff9wQS~7RF)n-K!f|rbF|bylQQu~yf@$F#D$nni*0Gv@pP`gG0$HJq2obY z>#vFqwas4`iE)H(3Dn0z$Kdr>uEnW|A)3|`E>IK|$1_vyofk>A;_^)LO^)b9YNS0^ z7Lh)8sy{p48{|1j9K97}j;DUW&K?gEdxukj#FYBarIv)=!YN+aX;_Wvz z_boKkjRcxnI3|IaG1M4t9f)xz!9;y|W^^KHmQAsN0kpVvAqv?XR>AkiVkNDu;m(c} z#R}R-4Tym$e?Vqo|IYnccx2sXU&)k^s@k0j&cnH5hY6R}r4K*Kh$y7cddhEbl^MCB z+tV>7Ms-Eh-%wEseZ%aMcBDE8rJV4uN#}-t%UAZ9;V@chODczwdFsh;`^$qM{}m zmCrSGbJHH?NAYwf@o>o281wP}i%#@M4$q6VB%@v!CiQNf1(vRwfBu3=R2KefA=FLL z4i;B`fd|th8eW6fR+QIIj1MOvPL-534v(I9-^g@S(my&J9Ju+m+sBZh5b=!2m&r8j z8^7b$o3fe|2*+BkIGL{aN?*p3?vSI)Z$fik;)0#*a^lQJiu- zMDa%BfB9{QO+I9IkDCZlP`X@sEGJ`#nwy&MB%f zKj)i;S^8u{Ji5C&qa%NV#h!4qx{R#QU)|mkNkpo7DpZ-*>#|r?aRz3q-S} zW&lkB3WS&bGl{a9Jskh{cufg}B7<3|>W4JlS*Po7zNUZ>tSI+Z^NhwI4=vWDE4>@NNhbG1thXxKffk!`Uoc)B3)E~~ab=r{r-NHO88ngK z>}FOkqaB>DIB>^>_NDf|9qaQLFz8LBn~75%7o~wvbA@>{PkCc7-WO}`$5&hIpQ2_N z;GP|lDdT>WQk3JGP+^QATV1Mu;f|-&V>c5=jP5%&aW(`^=y062qrJi1(jIiT8ugKa zflHJU%8rSqp86P+uK@XeOMg?euRjy_SDu*Lo?baS*j_^x6)BH$Xp`n(W}xy|Nhy;F zlm(WJT7T3`Ubx^jVTRhbr#t}MVGABdfiReq@t}9cs*sV-#a50o>fgD z6Q~Q;o~<9h)j9vXZ?7*oo=gtK44MN&$G-5oJMki(<`1>bO(CaKQDT2(F=+`RP?c;PZoW)=vzgKRmSVNRkh?(S zqEf}15UiC_Z#F|Eox|bvuhSo1`kfx)hXu{&$W>He*JzRX2iZ?@Hp!La$bF-HneL8U zm{-H%;~N#bAN}5`LR`8f3`0o{oq5zj{k^B9z~+_ynlCj&g45P`qio4lh);^h?QJ>j z5>FR1@yhknU`Mz=)DgT`nubs9OGEbe_OqJrFXI-ZOUuH(H0tVfX=!=7yj;KGBV`a% z)2s=r^t;p$IzG1-9YPrayQgoUHju1HSJYN;Kyr5_$JTg50WSoSuA!#;^?9_T{lWU+ z2+tWydjqBVEXNg;_rt*MD&_Yx8(M#HRI9(4!XiMe9-T$*6&jDtE+91-ky#?w5_5%N|x;= zkL0kcAS{QrXrQB~H`2DcI-ffE7hQs@HfS1mB-vbZwfjRn za|K}r=ec=HqUD@uL}Ep$yo{*AS%<|{v8cPEiek3EG!o^(qsl}(HruFZS0R6xX&t#~ zM1f)SiDUeOy#bDzGR3@-a`*R5AgLY9a)!=oN8Mnex+l&N6?H@`cBDDO*410c6esfy z?W=9cf$Si8>NMwT-tB&{=sC(guqwlSy8*6cZda!t1>n|UZ`Xb3pFL^@-ZivC%qT zq%Pbt-IzMdBX;xzjk3PU`T3dJXugo)3BEjLqPjj%T3JdBgVKIYJnX8h$hiO339+iW zmIn*t`GB79>uQ^At8VAfF5&#}Kn45C#oVFFa9dkTuq#swtD@AM5b3!p80hS1)N@cM z+xoL3g>WPm36*z{XR;Yso2aUnf8u^I&!K89TEDb^L!H2x!ATWOxstHz#5m=a#-c0)oRD_v&5xSPhT4P0JH}C~ z$5OB}UF~N$;oncLt&P@9Qj z-WsMqfB)FUvqK)^odcI=Af$NR=bv@HX?$#~$t)3@#z!ZbFFfab-b%qz4(u+=;z z9M{QA8}F})wD4d!e4De9soHa3Q!zCizmLA3FDm1CCST_nT4aXRf@ppmDH5Cr7J2^RfAXWFYsVjnBWby=ezp$_m46a4RxHI+Hr2d zGUrm4f6UO`+&q(7Rr{Le_Hc#P$ehd^_n}nDp_?i8&JRTYoKXU zk#lGCcdQaQHMT!k)f?$fgfk5_lWk*98ZSI{uyCf9mia0w1F4B@<6Y*{m*^bCyd1pn z54fMDX9h&Qmy+X{F|3m6hSQ*i!JMf<$ACE2KAkGK1+Esu5Et#&c$#xxvfi}(?eyW- zLDvV$L!9%>fyz9xix}k&_I6a4x+`OGUnEi8obPL6$j9VloxM!xk!V9-TfK-bzFCh)jCnJpQetsW#$Q?1c&4$UEj`%4*49$5Pm>t0G!ia%`@`;wrX=ZuPE*yE z>1{4)zU<0QM0sU2 zbi;q%inpG*{Y-Lcb%t9Ljv=H| zNu!RhlW`)Ppg<6HH@3BuERa~0L^?X!f>qts&DGsi!M2W$$dAH2Hh$zu6TzBbur3gc zkzmDwr2PDQ;z=Xcll5yhHnkGwd4ry2&evz}nqA!z=|4d`^Jtr zHuPfEvGx{C$wN8q?heK9_0xEPCZ@VW&roBr#;+dPp3}Wze*xD*l{@IXK=&hy(ym~wr-I$yit<1w zC!8uF&~RtxNvy7t(#mM01i^fSYNjvBST7EGVpR=i>nb36u_;H;c*Oirf*OH*B;W&iN;u&aK6oVA8rKO*=UVDA=-RH}ERK6P z<0T90nd5j)7e{#|evjfFaMMoHJ5PaQe0i`eKZ)l}E%TJ$ewu8U=>96#Q&t#O49>u; z(dd-ab!LW!Y9Pz$csGY-<*oE<`re97lI0yM@5a_VR9W^9Eqje>{a7~=p6&QRom95HW4 zoFgv^X4V}U9vLWZu8p=;_RV%63Qg4WR1JwkD_h`waOzj*V~5+yVG-kS_#Gn!rFeoywG_@Nh|# zDcG49ILTiVtcVCYHvP1^h`*^G?)jmqgNEyas674QP|4V>>9$0zAxM^&@YtkKl{D(v&bWv9eUOa-rg`^)C2AUQgR-x;+x&p=K27A}N%j#fdY^TYd5VM1+NW=R|L+ zoNOO*y6oz&Z>?qx#o_UtdG~W16S7JV*SEB#{P+C(^~H5bQ#&my;n5%gfADetd`%>q z%Y;j!*q{IRx~n?kY_0L6w(jn9t&_}X+qMWIDBGjZb4s43;*Du!gE9WA-=` z^IN;iljIH@6A`_zzQ4Qd+GLZn8pS0?SB2{vD@tN6Uy3b*GM7IY5A{@+2Ey@>=}BPd z;?lzTxJh$sXO~x}3$D-8=Hi-$=3sK5e(=_bnk>glM~Z9e5+(U-Gfl(w<*9}k{F_(X ze{@-JMDL>2j|7+wT0W$773ro)W^?%*Nkbfhv6(=OlQ^p#uL(eAVM8yS-?D3pu!fJC zkb{IA!iuJxc38JeGo0R{?+$t<%oDtN^DT)$NtDCkTOiOfO}LtPc4n^*X3>ODQ5yEu z6>6(Hs(c9Bh~J(FL|a0+!&Tz3dI(-Pj1NL0)CVXhZeQWt*$9#uM36}~$I(r(&rUI; zBus9X>=~#G!lVup}=_usaUzEqW`kAzotCl z3-;x5(cxQfdm>N9eh^;QmpzwL^*b+((xoa0w!3sD(Iey%vtEdr+9|_Mah%iag7}UW zAJI$olS&LvE=*U{ONCyePY$8SDgRdD*;Fj~Lz+U5H0bfkODlta7Lx-y5E z^Y>h+A9cOjR6DwMwpLP!p&0ctvljE#rc(Z<)ty~y$}BGjA2axR*ZJ2g>wTT|q1O*S z#)-wp)_=Kw?8(4A;oKu8DcC;kLum~jx}=^v3ri}L0+r)#B~rvVh7%nJ&o-lxM2?z8ay{M*VMK!doJI_j6<$exGqnQQR*(|R6vfX(jmBtPSA?VcnC~% z;`ZBbpEPE_`jb~zj-MSx9?n!6ujt}&zLdhtn%debB7MDGb(}j^Qt2^6pN7i2X%2&AFXtt1i{n<8;r@phd^6A#k?=^j& zdCS{gJ?3udPcui3*x&c;x}Qwdy@}P)DHGSE;Tl2s8vi+kw5G(SG#GwnQh*TKk*rkKdf!Mj{1k1Ui`_%2KD@9n2klPUDLYy-XsEUm9Df6AdFSFHxob1Z&YeL-GI^1 z(ohL%$Iw|o@adnK0!5%V-Hzn2I$oOWOhnSE&Xx6z3`fnQkt%s`Wp}Ncw7RCOmfhT# z9^hTv)ZON~XbzH~{K~Q*R2v$2OpiMX;Rm+8&eN`R#r)kzgC%v%&F*`R4Im$tF%VJ} zgI5o>&9(cgynddENaz<+HRLT0C8N=9oC6sDv;!%*SIAGoIYf10)RLsOcV*ecn z(5Jhg)cYy%1j0e;TnF#iFUwEDCC4`!I2Za}_wP6>B&#alqvEoe)*dM~uyaJWi2hqdP#rXZ0}JX^tqEgxf-5^S8Y7y%x#lP_b>Hq^vEr`H+wpkSC%^( z#>U27&k~!XwttGFRbWKqSBE)g*A!=(I+_|LE-dwhTPsNfLXE+m`Lmpn-N!+5%7tHD zbiezP?q3z{ovuIBId!HgPi{wDnFRLq@M2}i#%;`u)8ILs^c7kO$ZXAN7m1+EEahIH zdnMs;m^x!IIz$ws9;Tz3iHUruA~iG`?i@|>w3N%QxpJn(lvzrvyT+&IS{T_i;o_=_ zs!WrKZgrFC>VSWEc70(q5Quj6yRV{`F36pnuEl9GI^mQWG$go|RI-kTclZj62ff*R zs5(2(#*nWpp6RMD55&u2<+0I`43rpVYu4sv)!prlnN--#v)xs-~=wlzfwIR zIvCD^bDK4bG@uhVW65ySoVkVtH{C{+@<{l2cp7s3fl$Xo<#@PTyt>NYwbPTmYQPh! zMC|SkL@G0WPJ;CULJikc-3V`>8`!q)f5w9@Lee4 z>{>Hc^Q1vq8xzE|Oi^Xkt@US`18tmv!-KHfgQs*Ui(jA6mIdaidT>F>KkJgool4_TjBOL?dEy*q(##osw4OKVnJno6Z z%~K^feY~-{X@2Xn{Opqk{8-mpKDjU-d+I-*FNNVtm6L-Os6Vmr2$HI{KlUllo^6~u zKMch#QX8zDoLcN0yLxZ6wYq_B5(9o=|Ev3jobf!MC&W0~DFwGj{v#~pRMIfv;o+e} z*DhsqniQbsR>2^}E3k_uJI!>A88QYr1o};#xYO9wP{EY$OCYd9g02D15GT`fN0Ui! zMWQSit43AUa1*{+UY_jj?MalD@>Fgi_QBjULH5oq~PNh8f|$Rg#+wSxnL z$=>ar`tkbIM2ay6J(%hqHFrJYIygKzTmg4k6pU;(drBiMYwzwtrVB5bBP7{=M4A_@ zZAihAj#Rg#nxZ~xzopuM< zW#0~V+usL!?0T@*?gRVG=hODfc;9cm2+Y{~VAd`M2W-BvXwZHwn6sY^4jIhbExa$- z{ot_uC*X*E6F6#*f@Ag@z;Sy3oUnu7q#XsP?DOEXY1@qTE#A-CmxFV*8=SX31}<3d z1sCnJ;F6_to0hF-fGhS@;HvdpaLv9KT({NV4Z9uOv~LBstY3iJrq?^xcX_{SKNj4x zpAYWahv0$zAb4m`fJgTI;IUnf*STn?8@pkz%{!QT(=Lv4eO`irhP5AWql3Yw%5QN>$Bjl^;K}sj)VKwUw{X8EqKTsaTgt# z&mUXgFX9=m_CJ7b`xek=e+BHMzdr2tVz9fY4D7K7!CreF?6W@&rtSBF{nnenjC~E5 zwVS{Jy8#@uKLqCNSAj$JyTQCY4i@YsaM*q#IASk@qxh;1fBP~xZmv6l-}= zeE8d~;0%`WVYkPDbKEr_cKZRiVChyMsS^x;=|u^ z;HLfO;Fk4kaNGVYxMQoQyY@Zcp8XbZ-+mr=0DH=Zzuf>H*`EZD@x4y$Rt>soNhfw| z20QI@V3(Z*yY0Kc9@^81zkLquvwOfaKG})gE`k|50cNd_fCJY1z(LyFiQV?VA?{r# z{`MuXVErdJYeTo0r%`_aNl|WJg|?!L&ilXc54HV8F5`jF6-T(+j1=7?_m z?E;vwYrrh`y&Jm;2kpDT95K9``1WfsPxR=t*$;rU7woaG1bZ2?J=pDcVA}o_*l+zCm?7fz5Z|`J0eb@+BqsD= zx1WJS_7A~46aSBStp*zJ4ZnrX?p{olObuwMvn+CKuf z%+Lo(>)v`y4Y<_hPsELASjQ`s}O0PUenY z>~|;sUhK97PLhH2GEQf~Y17V`lXvib)>;JTPW}%#Z@my) zIQeUEkzA!0yS)Tlww?*DFz@tYw`YNC_;xSj^a|4fE5NOjPlMZx{obOTlm7&F z84JBddzQX)-+C%|z%1X(IMw$b;oC3`t?D8&GW%xGZC?la@P|J9?O9-#!EXC|yzgO- z>%(qsV4wXLVA}p`u-|$qn6a-1v&7*({4D|w+Mfq=Sf&rVJq66$SRA{}fy4MlALH}` z;3#u?AO7}SaGW;xF;0H~PU5$H_}k;aX?qi#A(HgrZ@T&%KG}!ez5*^-zXcb$BYoKI z&ET^29dO0;Nb_kQ{`P8c-PRR1m?Qe|w@-pwj~yJ;cg+lqm`79PfY`a&>my&UXkjPx^~Dh6b&QgFa31_!Ob19Rq+ zLqykp<^{4A=7n)^*t!NBF;^V5vb-O|0{zSjL*Rr(K8@Wn;FPrlPFwrn46|oHovUJu(;oh)BC|Ks|?&` z#_wmG{t?`@t_JsrKmCkT_3Hqy?q{6RTgIur|JZ8dtYa559cuzUnZa&f1v{;~z%KHW zjLAbX*lm&by<`y??DiQjP3Az)hz}W)hh(tZDDMZX0yv28Ww4t*IfS2Nu-iUZVD`*l zx7ULsWNsP8>EpmL>&xIcaWaG5&V!TY=gLDe*zG=W#BU_ z+a5T<9G4}&&4W{{J+q9{MR3Nt4V)zoWU<>l;5_SsEOt{%7Kwpb#_9FovUMZ4!pxFo zoZbztG0LdTGoxj(+bh6LVrdq;y%^j!t=b_E&oWNWfqU2rR*h-Z0qg55cKZ@|WGrxu z%~?rXgP@yl8^GW280_{PunX@UV4VIH*mLrGu$Osc0DoHo)AV8hfBPbsv9`c0cVPg# zO@M<$tpWV)N8pgv3g#Id1NfW1ZJ2%y;BWfO=*gGCG5S7$zdZ+>II+P=a^nH)c0D+4 zt$;K5*Z_9BADm-E4`8<%aDjY#z>L!Y{O$X^Up}$G73Qn~{O#x98f)GG{OuudgE<-| zFFDKrcDn}Lw*EJ`gC7pyZ^Rn>?RIeg(_r3xNgJafA5V4miT78DyM31diFy0LSeBI6;+T5Pz!!r%bD+@$fSGfQQV9gZSH1!DIXu?YTiWzQKBz8cWXjTMoOG@V=W-lf!N= z1$(WxgMG}%%!gD7a@Z{nX2`U2*zG=WfS8cOZUrz$wx7dp`kp)$fE@nzNpP6Eki%|2 z07r?UIqarSj+F)%3-&4aKSnT7p;$jOI8A0 zw$!f`)1y_qJ%`!fx*e-Q@E_*zK!eCwavXc6%AvT~rD7Fe8%>l2egk*`EW`_J_fK=FK7e z?HOPen=^Wd07KaAQ((@19XMpZKW|U*zCbQIgumSej*w9dnfNw@-M+^Aan^T3*v$qf z4Nj5G4iVq}6r8~`hw!&2f^$@&hOpaDLDfTs@V7&737ZUIx7UL!rd6w^g=_XZ`N_Kd zH{b>lYzVul&0F~J5O(`AxWj602!H!4aL@E^-+n&t4~hcdA(_b#cKavrn7JU2-KIdd zbprbE?L7YWc(4o4&*N`bf<3JF^Z47B!9H?Dawx2n$8KX_hS;0O-`)TY5MA@wtrE=P znb?NPQXYT%AXu=z0S=QN=CK>AR{ZUc;22fMJpT3@aDp0F9=rV*oWgta*o`_AdB|tM zS#pCs{-&1C6aDh!A-dusRgOG%TLG7?GvJEt0auyd^Z1+EvyMIU_}gQ_P1d$~)(c++ zx5+2-*lh>gCHu`|w`y?TwDW*5p2y#Q0v?eG=kd1((BY|WN%fIl6tG(e>?DE}u-hEi z&C08Q-97;JQoSi)w?;6{d{n@0`(TFa7O>kl!2xVrz;5pWbKJWEb}I$**1v)UtX;rv zTi}TGPv9taE?_q)0>`mW0lWPJsC8C>__hd6Gp`l!w?BZh)WHh)TRAvy{&s;3vtaC2 zz;3tje%auPP5lMC-3G3a8x-)jSArXi&;tIZ>uxdb3fN8U+#z}wu$vp)GkxF3TMCR* zwf2xoX#u{x3}d$| zzzt@uVeGaAZkg}dW<@iMzr6|ErE)%u-KM~OW}IQ{b`^NYcpt`YWbOFdXNpFsm;V(= z?b%=t`*vE9H-oI(z%=KGjuiEigN1 zcLaaC0L~E`N2rIq7hGVSGQzW{XTT-)HAae-?dO6ka4ANLR=MvZT;mDgI@!nw{`M4b zlNo9RyG?@IMfZU__KU$?bFICi$MSx^=sNJA=m+2-?Hb{nj;Dgh>}InoLa*6RU|f&l zZ+C*7c>XB#O|YL88LI@c#8Le1W8eUp`6<@5~Xk zi1bwTNAb7sfCW~acoxxS6o303I7<8<#oulO$B6@@_}lZrN$&nA@lBtfW?YQoZ%+Yd ziNmABx3_@vmRh?&_Be{a{T^ImT{DWmje{#x+DGxXRd5ae8O7hod+@ghz)kXjQS5df zxXmaY#ot~5?lSsD@i+a|KJjN1e|sxi~V+oiY549VYBH z3wGNd2YZN$W7y3CmA{Q)H~m#VQF;u!wSieO>M`v00656ne+;|rfJ2N~W)Jd*G3=&q z7-mI3hTUETj+&p0QHL4BZa)Mk%+DwBhcWyu1WudppJ6yFC|NAPXI1 zKJ|c0RC~s-+XlEo_BDpxt_0V(k7L+v9o*pVk72hlaEofm7~<}< z&wU@mZvOxtvU@VdIDHa$OiUQZZZXhJ#gCm6?*2Ib_G_?WSu>%cxT zCF%s`Z~Lt(-e*|bj$^lb!2#B`(8o@R5SL^JWjbpbv!A&yoaqRYVaNGQRhbqK4@l7q+V@4P!zTE~M7;7A|b{=QF z@EY)#S)N@%BH;vfdjsfWq_9_Gk$tkx`ZCzfXqv!o_kg|ZOHN?7H-TyVVS;tme}EZk z9jsZcZE%2bL3U3RonW2yFW?YLEdX!KS3VyDsa(yKe%-AF>v|hJIqZ zHK3c?)Fk8d80@4v%{~mZxJmr&F0hC7<|KJ<9oUEWQlnzMKgl?K1(;#CZjyPS8XRCf zGRZjo2ACsCPclx~onoEU1QzTSaG1zUJSJ95lJ~MUAigbwGQxjX4Ogj?JMAdY1^W`!22ajS6pUwGs!r;3|yt=Fv&Q5CAe;X3fy3p zpTyt34Q`R`OfpX252{W+$v7ppGEQZaePYWb#u=M#KxiSt8FABjSEgE1D@r#8bgV+BQWCE5T)}4qRc3Owqy)aE*~ZMGM&*U_`tZ z++<&1iV^V+aGTs_ib(QdaM%1~k6d?(7V4W-v6-TUcY;Uc$y40f_c5DJardWb+ZEsp zE9+_6_IhxR*>D=K`y#kNFQ#c5eZcGf9$Y?oE4adJGL6^08(hPN)6A-00yoUJX;z)4 zZRfyk?!q)}qrObr7Qj6s-ZX7%0uSiRG;J#dkEl*e(>CrUZF?O!&B&dhZ5P2=a@`r) zb_F<(m1bxgyO^}?22hoU8QS)9P$Oc7w*44fBj=f+ZNCIJh#oVHh(Cf`M5h@ONoHu< zChvEN9y7G<%iuow^9*g%Hyko2&d|2cfydMhW@+1Vz-eqXOWRnZ(zdsObF2<#XP=2yS7eS=#n1aL1zNLfiEH zd(4}&wC&~K0kgm?ZF@X;L?oG|ZP$=DO%aXfXxn$e8GLMx5m5%tG2Z8lzs=FMyLrDz zzA=ZtwSmj5qvvSbufSD{eI`ak3S4Klnxk!>1vjbu&(XH`gWJr}bF}T{;I6sW9@+aG zZTlX0K>clww!IrXGT(EI*Ui(m4saUF&lBYy0B5avaPH*a!TFOQgiy${?ZS6{$xF95g6w->P6(?H$R1tN*QXP>!v0lU?M zhxBxTw*3Y?rZ0=M?G@lObrL+0d1sNfeH5Id(vF?10JuQ4d6BkV3u-JZVz(cIs=_T| zx9@?PRTr__FTf4@xJcW);1*uAh~0hz?l1}#Y1?DLJx1{&ZA*a%to{~hTMKx^?%1Lk z3q&AROiQ$lyTv{I9ym*@mbj-jIDhgHaN*>W;3Bih5^Z}CxP0W!km^ zPLppe)3#rNv&4#J>{brWpL_vaIQb#C$S7W>Z7&6v8Jo+rZ3|pIc?r0N<(FyOt3d5C zEYr64fm@b1d)wCEfIAla656%_?vYb1V>c=VwC&yCAu(Z@wmlitF2f3K({sqCPksi@ zoV)>?wVJ`Xlh1(jCr<|#*zZ^=TBMyTw2c{ywlPYJR);~wy*1iqgUjqaVJ+_38g2V8aE(#0#yE|D8{FA7#zF$zg5$Bq zIMvU0@W3_N_Ltxu+0hzp+Xat25tKTIKz0^U|wL)jJACNoF_lu zz;4e67g?)r5Z}&&%f!76GNmB6YJRdtRd55lT@I@9uz}sUyR_}I;5PZ#25oyixJ#XI zgZRe$f!!Vg4_KvcV7Cv0M?}R9+V%<7*;9DhCT+V8oZ*U_*zNDYIc9-P?DivYfed+* zw&CB{?PK8b$@{?-=JZYM_Gxg9O3Nm8dl1}Uk7EyZO;H#+0ERdZSMou$wszl+hf2@thzgWwK(H(Rvr5ZohfY|%FMmT23@ zK<$8R(Y6&2UO#CXxqJ@m_IwT?VVJ1 zrpOX^iM>AsXHMP%&SJ@3?Dj5j{^WLWff;Jo#9n5b6V-#3PpCo?d;br(dO~FlyS0Gp z+`(O9@8`fxM&B-W`!u*sA9u0a=fT~R--3H&^}CGI2f+ipYnO5QQSb0$r@q5_qdEf%Rx`*994K8u@J?uvG#BLV2YF!1cQHR;XZuHdnUL=hQ>W-HMED_ehu!Dx9>4d6W~4(U=O>sf`^RaJ=*plcucGIi6LHaniUz@ zF*)QuZHs_v+dgf3J*eH8eX1fcaEX@e(>A`B7;*+&#nbj_n^5<3pSC>&YIkOzw%rGA z!-v_YZSMqk*-6=_ZBGFAS>^51wl9E(_`p8*^cmnWclLm`T@Q*ebwJy`3eHj~I$$LT zvxEv^1-O9k9niMB!6j^aK-)eDu27+3o}spLK-(S!*X=ie8>~hTXxm-j7I)-;w*3*@ zp|uCJO@F&*e;3?`DSE*Fv(}<*`nDtc58$zV2NlC9qTC_(^mpJ4);Pr9z5vcy&jiJ~ zJfv+zZSLu}z$G$=L)u1uPuq&YRqHG$mhT~LD+f1-LWi`C9c9{f54cUFJ;ZJ=1$W81 z4{2Kx+_xLS1N%jwR;h=yja3cz^g-&FQ>-G7u-ip&hPuiTc6&TH$DKW*ZJz=csE-|C zH=R$sM65odZQlV`SdSmkwwHiwRPdO2?AL-DRKSjC+k3z*YL!Q{?Oosw^*zQ1dk06f z?Ot%7eZwQ#_I~h?`oIxwdm4Dm?$|MQ`y42{9n-dZz*(y3$Jp(;;5=FMF>SjYTqH6a z)3&qVvc)=$ws}CYqmOA@7r2g1jMp>vx9I< z+wKMr@zP`3#vTK9`wskkFPWUD2<<<0^E&?RymuE>@N_iiy+_ZpJbhnG{ruAVlA_!B zjq@2VKmRcK!!4+yu0<7bE%VORoI`XA>)^*1-N>s}VYhHX$MyW~Dr%?O{Qe1i;#%|j z6kG!MP5l4=+s~;=^2uBIs~f1c>u*z3<;Av3v6F6C6jT;3UF`zDznZJv!r$nVurc_4 zb}{*+_yg?sQoB!4#b;lb@4J>y{(rR|2HB%pFAa$KKRjc=dG~)I>T7ldI*VRg)Qp^r z$0%@};-V6)UCN$BS&<)pWd-|;LG~fS>?BkcMT@G?(#AOVpoViSlSQ>Ug@Sv~NGqFA zxVNIvYUgxI7{u&eh#M!CkopZvf}XKwNF|>NI(0&-ah!g6mUD~FQ@^>$Xr?a0%9?dE zYcbYU*pj@P9+Q`Grr$7SqhT){&XIGV)e;|xE)tDK`f1IWQcuCOcO zs&qwNRjz7R%oTUlxDu|UtJYQLsz>_O=t{YoT+OZ)SF5Yd)$ZzWb-KDZ$*9NG>*_-} z-tWq|vOJx2(3Nuyx$>Nk`J@}K%?w@4oW5pHUk6TK2Txyfr>{e&uldv0OMgFn`tOm` z*K?<@=TBcRoW5Q>eVsaeopxTQPOm?8di|->>rb6tf9mx5Q>WLTI=%kX>Gh{huRnEq z{i$=_CuK8(xnc7%m~mdR&dY%FGU&YIoR=ZzCGWfxoR`x-A94QWeCObK=U*3`my6EJ zl=CueUUJU$a?bT~&h>K6^>WVja?bT~&h>K6^>WUIa_8jGF5}h03iD2WuYXB{DVV_Kx7S_$1pUnU9M8rzV+O@fkt_9l^U0y2TU^ub8u!0@K3M#m zlFPjV94hxU-y6$r_b-+=l>egQ9|JE8J~lKQ_J_Y6d0XYvqU#9nepmgO>Mz8GW3P=@ z#BYuNTg`mUyAutGXC;1>JWPJ7HdFi3y5hPU>%LKczWyx@v4*EL{CneOb+vAzLZ)oTs#YQnY~Yyx0o8Qqb!oHNU9=filiu# zo=9pUX^EsHl8#6!B58=EAd-Ga>LF=|q#TlNNU9-ehNKvhUPx*oX@#T|l1@k}A!&r9 z5RyJf>L6)@qzsZSNU9)df}{wN9!Nbx4@3*KcOs^|bU;!8NdqJWkn}%N|492I<&Shf zQvFEtBgK#OK2rNg>od%pBAt&^KGOI|;Uj&I)IHMnNZBJ@k5oO<^hnVoJ&)8p((*{j zqpVHylxBA+c%wuhv5~??d|;_-q^*&%M!FiQYNV-=qDFcescEF8k&;F_ z8mVZcp;3>j=@D8UYWh;oNIRpQ2I*#`nvrHkiW%u;v|BH&jFd9c$w(z5jf@mB(#J?0 zBW=tm{7Uf|q>7OyMv55eVWftU7Dh@K>0p$PNdqGVjPx(ct)+dD@W*q z7pYyOb&=9VIv1&2q;ZkLMfw)0Tj&wFr?f3nwisOt_K~JViWccvq-K$pMM@UwSfpZ+ zhD8b%=~tv)k#-i%2UXrHFJQQi(_-B875!sBdJd^Mq~(y3LplzrIHci_fCx4A-3#ausu})m^cn2dIrj*jIKPuBLz)aJGNi|l z8bewPDKVtOkP1T@3@I?AzZmBpN_!zjkaQPPT}X2w#f9`1Qd>xCA*F?M7E)PAViM=A0c&wv=LH9NEabhgftP_S(F|^Y6xi| zq=e9ZqErylKu7_hRglyVPON)1_vi!MBX%Q*V^Taw?;y2CtW6qu;4V%+JytNOd61ffNVQ8%S*+t$~yVMrVL`NMj&{f%FC1 zO_#Pn$^z*Mq$-f6K#BtC38W^FmOx4Z=?J7EkcL1C0_g{&9*}lG$^q#Hq#BTBK#BqB z1*8^`RzNj;=>((_kVZfX0qFyz4v;oL$^hvCqzX{AUOhrP%WtIzkQzW*04I8*E+QgJ z10V%};s2ZHEhZ0qJMNWO|Kj|M@h`r=*#0BTMPmAk=P#DOIR0YzJJI_-?ok^(dJR1~ zPmfNxN9@yRXXE6v^ytI%=tcDC0eVE8m)1Jb`?K^&?1+cBM;-L&6{per+1w+l2+T6# z>x-=~uX`C@cM-3x{7;*wi;fqxb0%L zi`VW%hA{W&PVUh&xkq;p8FuN>Z@EYC*okxEu#3Si{<_%f;;xIiF5bFW>*B17u`a&4 z*y`e{i>WT2x>)MssEeU4e!AG{;--t4ZlX6cxH#!zq>GO(HoCazswawvE*82t=whIY ze=hdJp1D}&;+TtJZusTo0pga6SuS3=SmolB zi%~8<`8YX;xa5<(ibpOMxj5uvkc&Squ7#?TVvdV9F4nj><6?}9FD|yYxZIUCcDT6VVup(sE>^hi(fheachDmu1JPM*aB;!K1Q!onEO2qa#Q+!oTkLOf zzs3AEyl?(qoNqC{#rGE5+Zjh+;~tIDBY7R%4`xyEyT$Gnw_D6^@w%PdTQx)W8Hp@n zbBoI@CbxLpVsVSZEe5yv+hT8vyDjFnc-vxai?c1pw)ooW(G=t8gdU;#W-m@WZLze) z(H28n{A{ta#myEoTfA(svc<_3Birz?sjG^MEhe^j*kWOiv5FG|Tl{OWuf@F<^IE)X zv986r7UNocYq71xwHDJ_l{~Sm#jzH{TKsCUtHrGrvs%1rv8u(X7Nc4fJF%(7r52M~ zJ<^H~bu?o^9BMJB#h(^?THI+dr^TBVYg(LXF{Z_r7F$|eX)&b@PnuqfBQ1us_|axH zK@Y@?HdzpHPMl~lqQ!?68(LgwF`=Cv-9nFUp-1S!i9}*Qi~B6*vv|*9J&W@!#DbJ`Azgg^Naht_#7Oz>XW^tOuXcnK@Ss%Tf9-(caRbnxV z!z>1~;VnFpU2%5B*j10NqemU|=r6cOI(Y_FzWs4}^b>ky(Id@A*U_T` zdelabzC@26phr)pM?3WB272^MdSuZfomlZIybfkAxx6^IV&IB@EB39pw_@IkcPrMd zIJaWlif=2nt+=*g+KOi@maRCpV%UmbD|W58wPMzaS1VTSJ{A?DR(x8qX~m^gk7C5S z?~*f63o=+r=}J}-X_MW_@-i;ifbySsd%PhnTlg7hN<|aVwZ|rDrTv8rDBzeQz}NO z;gjN-&WexSYV0i*sW_x&#m9BT9u;>~%u(@1#Tpf7RE$yaMa32sS5!<rRirXn>r+A%W zb&As|MyL3kVsnbi>BPKq+^er}C3O2lEAcnQ-V}FJj0y2J#oE-BUdNT-Y%-UNuPL^s zxSC>Wil-@NnmC${SNxbOeVr@)k}JXDz|+Labo^W#joY}=m$?$VD~u)aFvY?Y2UAyi z4p(|TSITjvw{ay{Q`ES`yA|!|@ zjw3Yy@f*c%6t_{#M)4ZOY80nYj7ISp#by+jQA|c-Jz}9ajAAf~zbN*ixQn{dE4b31 zaV4?HKFXCY<4OVU6MRLk=6D3WH9qac2}QnNaHTuAl9wwzo<9ACE8WJGsOuBE_F;*L zk0>^xxQLfL;tW?3vy|#IR}lkI{6n!14fhb{p?HU49g1@(#-aFzVjGHUD5jx!hGH3t zVX7j6pBwMHletLViFo2AwDM#p%{eX4~jkL)E(YO zpZr|uZ|D=}N->X#FDSO4xPoE|iYKVLgRWF$ID%pbiXSL;ptylz28tIbR-oYo(suCy z#Rgobe_{fP2PhVxIDldRivK6}pSXWw{)zV|)}J_kx{_kVbGc7vxY9f66AVc!%zbL7 zPq%TUf8k1Bqff8kN^q*G}XpHFN)arwmL6OT_UK5_WO;M0{p z#Fbvlm9FPX-{(qqa-|loBwpOJxRQ3p;IaV5BVc!PL)V(E#aCx)K*d1B{@n$&aB=&*w_tU_70tPX*?VAmiyg zU>{=ghnBr%z9(PoJhw@8Lc@$d%y3(Gqdt#Do(MPAoWa;KYCv|ILZz@GQ6!y3##d z=~}L&Q*=~|(oVv!xe_X3bEQwvCn`61jyP^&xQX9pYEkr4%r^1b#A*|#O^i12*~DgZ z>KrfNN;~FC39i(_eY%S)RpRCBl%3qeeY(Jvis{p3+$VAU3S0?p6P6WQO#slOlDU#^`+%Nma#8AFa{&z>t(6ca^6@lZ6>tgL)AdO4_erW?r| k->+P?Ywt^uxt;x7(}CV6Jw{m^qG2 Date: Thu, 29 Nov 2018 22:07:51 +0100 Subject: [PATCH 0485/1650] QNetworkConfiguration: add missing timeout unit to setConnectTimeout doc Change-Id: I3738e989a41607244b55245222ec3c83dda68198 Reviewed-by: Alex Blasche --- src/network/bearer/qnetworkconfiguration.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/network/bearer/qnetworkconfiguration.cpp b/src/network/bearer/qnetworkconfiguration.cpp index 3367de80c8..e36903fc94 100644 --- a/src/network/bearer/qnetworkconfiguration.cpp +++ b/src/network/bearer/qnetworkconfiguration.cpp @@ -347,6 +347,8 @@ int QNetworkConfiguration::connectTimeout() const This allows control of the timeout used by \c QAbstractSocket to establish a connection. + \note \a timeout is in millisecond. + \warning This will have no effect if the bearer plugin doesn't have the CanStartAndStopInterfaces capability. From 86aabb500cce306d0729d159f82bfdcef9ac547a Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 9 Nov 2018 15:57:42 +0100 Subject: [PATCH 0486/1650] Add lancelot tests to verify vertical alignment of inline images Adds a test case for 199f9c54484b0dae3bc81f83c880a965192ecb24. Task-number: QTBUG-59310 Change-Id: Iee26f8bc21884da36471935f64524b62c3f79ff4 Reviewed-by: Eirik Aavitsland --- tests/auto/other/lancelot/paintcommands.cpp | 28 +++++++++++++++++++ tests/auto/other/lancelot/paintcommands.h | 1 + .../auto/other/lancelot/scripts/richtext.qps | 9 ++++++ 3 files changed, 38 insertions(+) create mode 100644 tests/auto/other/lancelot/scripts/richtext.qps diff --git a/tests/auto/other/lancelot/paintcommands.cpp b/tests/auto/other/lancelot/paintcommands.cpp index 65a688ec40..8aa3a035e3 100644 --- a/tests/auto/other/lancelot/paintcommands.cpp +++ b/tests/auto/other/lancelot/paintcommands.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #ifndef QT_NO_OPENGL @@ -441,6 +442,10 @@ void PaintCommands::staticInit() "^drawStaticText\\s+(-?\\w*)\\s+(-?\\w*)\\s+\"(.*)\"$", "drawStaticText ", "drawStaticText 10 10 \"my text\""); + DECL_PAINTCOMMAND("drawTextDocument", command_drawTextDocument, + "^drawTextDocument\\s+(-?\\w*)\\s+(-?\\w*)\\s+\"(.*)\"$", + "drawTextDocument ", + "drawTextDocument 10 10 \"html\""); DECL_PAINTCOMMAND("drawTiledPixmap", command_drawTiledPixmap, "^drawTiledPixmap\\s+([\\w.:\\/]*)" "\\s+(-?\\w*)\\s+(-?\\w*)\\s*(-?\\w*)\\s*(-?\\w*)" @@ -1295,6 +1300,29 @@ void PaintCommands::command_drawStaticText(QRegularExpressionMatch re) m_painter->drawStaticText(x, y, QStaticText(txt)); } +void PaintCommands::command_drawTextDocument(QRegularExpressionMatch re) +{ + if (!m_shouldDrawText) + return; + QStringList caps = re.capturedTexts(); + int x = convertToInt(caps.at(1)); + int y = convertToInt(caps.at(2)); + QString txt = caps.at(3); + + if (m_verboseMode) + printf(" -(lance) drawTextDocument(%d, %d, %s)\n", x, y, qPrintable(txt)); + + QTextDocument doc; + doc.setBaseUrl(QUrl::fromLocalFile(QDir::currentPath() + QLatin1String("/"))); + doc.setHtml(txt); + + m_painter->save(); + m_painter->translate(x, y); + doc.drawContents(m_painter); + m_painter->restore(); +} + + /***************************************************************************************************/ void PaintCommands::command_noop(QRegularExpressionMatch) { diff --git a/tests/auto/other/lancelot/paintcommands.h b/tests/auto/other/lancelot/paintcommands.h index 83e3bbc11c..79bdab634a 100644 --- a/tests/auto/other/lancelot/paintcommands.h +++ b/tests/auto/other/lancelot/paintcommands.h @@ -198,6 +198,7 @@ private: void command_drawRoundRect(QRegularExpressionMatch re); void command_drawText(QRegularExpressionMatch re); void command_drawStaticText(QRegularExpressionMatch re); + void command_drawTextDocument(QRegularExpressionMatch re); void command_drawTiledPixmap(QRegularExpressionMatch re); void command_path_addEllipse(QRegularExpressionMatch re); void command_path_addPolygon(QRegularExpressionMatch re); diff --git a/tests/auto/other/lancelot/scripts/richtext.qps b/tests/auto/other/lancelot/scripts/richtext.qps new file mode 100644 index 0000000000..787c97421b --- /dev/null +++ b/tests/auto/other/lancelot/scripts/richtext.qps @@ -0,0 +1,9 @@ +drawTextDocument 10 10 "Xy" +drawTextDocument 10 210 "Xy" +drawTextDocument 310 210 "Xy" +drawTextDocument 10 310 "Xy" + +drawTextDocument 10 410 "Xy" +drawTextDocument 10 510 "Xy" +drawTextDocument 310 410 "Xy" +drawTextDocument 310 510 "Xy" From c4daa2b5278bbc01adbb19cc12ee69fb0df79c19 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 19 Nov 2018 13:56:08 +0100 Subject: [PATCH 0487/1650] Fix compilation ::link() is defined in unistd.h, so include it. Change-Id: I58e99dbcdd64da6388f85d98e73e7d1bd56f4e37 Reviewed-by: Eirik Aavitsland --- tests/baselineserver/src/report.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/baselineserver/src/report.cpp b/tests/baselineserver/src/report.cpp index bef957ea35..5a55fe5b37 100644 --- a/tests/baselineserver/src/report.cpp +++ b/tests/baselineserver/src/report.cpp @@ -32,6 +32,7 @@ #include #include #include +#include Report::Report() : initialized(false), handler(0), written(false), numItems(0), numMismatches(0), settings(0), From 79e4fe54bfc1f36df6137cce84015dbb0a52639a Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 23 Nov 2018 14:22:03 +0100 Subject: [PATCH 0488/1650] WebAssembly: Fix compilation of application on Windows host MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When running configure on a Windows host, it would fail with the error that the copy statement was invalid, due to the forward slashes. This makes configure finish without errors. Task-number: QTBUG-72000 Change-Id: Id315d7436bbbfd2cd5c5f2dfcfe0c3dc3b9e34c2 Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Morten Johan Sørvig --- mkspecs/features/wasm/wasm.prf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/wasm/wasm.prf b/mkspecs/features/wasm/wasm.prf index 278a6719c7..13ac43443d 100644 --- a/mkspecs/features/wasm/wasm.prf +++ b/mkspecs/features/wasm/wasm.prf @@ -41,14 +41,14 @@ contains(TEMPLATE, .*app) { appjs.name = application qtloader.js appjs.output = $$DESTDIR/qtloader.js - appjs.commands = $$QMAKE_COPY $$WASM_PLUGIN_PATH/qtloader.js $$DESTDIR + appjs.commands = $$QMAKE_COPY $$shell_path($$WASM_PLUGIN_PATH/qtloader.js) $$shell_path($$DESTDIR) appjs.input = $$WASM_PLUGIN_PATH/qtloader.js appjs.depends = $$appjs.input QMAKE_EXTRA_COMPILERS += appjs appsvg.name = application qtlogo.svg appsvg.output = $$DESTDIR/qtlogo.svg - appsvg.commands = $$QMAKE_COPY $$WASM_PLUGIN_PATH/qtlogo.svg $$DESTDIR + appsvg.commands = $$QMAKE_COPY $$shell_path($$WASM_PLUGIN_PATH/qtlogo.svg) $$shell_path($$DESTDIR) appsvg.input = $$WASM_PLUGIN_PATH/qtlogo.svg appsvg.depends = $$appsvg.input QMAKE_EXTRA_COMPILERS += appsvg From c1fc47b06aa27e253271d59b6c1f11a6c4ab674a Mon Sep 17 00:00:00 2001 From: Ryan Chu Date: Thu, 29 Nov 2018 19:41:15 +0100 Subject: [PATCH 0489/1650] Disable Docker-based test servers on macOS temporarily MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tests of QNetworkReply keep failing due to VT-x is not available in Coin environment. The VT-x/AMD-v feature is necessary when starting the virtual machines. Before VT-X is added back to the CPU features, the macOS platform should keep using the remote test server. Task-number: QTQAINFRA-2288 Change-Id: Ib37d0e7a5fb1fb4ed5484f925f5023b19467e672 Reviewed-by: Edward Welbourne Reviewed-by: Friedemann Kleint Reviewed-by: Jędrzej Nowacki Reviewed-by: Frederik Gladhorn --- tests/auto/testserver.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/testserver.pri b/tests/auto/testserver.pri index 7dd32db0af..eefb29ab19 100644 --- a/tests/auto/testserver.pri +++ b/tests/auto/testserver.pri @@ -53,7 +53,7 @@ TESTSERVER_VERSION = $$system(docker-compose --version) -equals(QMAKE_HOST.os, Windows)|isEmpty(TESTSERVER_VERSION) { +equals(QMAKE_HOST.os, Darwin)|equals(QMAKE_HOST.os, Windows)|isEmpty(TESTSERVER_VERSION) { # Make check with server "qt-test-server.qt-test-net" as a fallback message("testserver: qt-test-server.qt-test-net") } else { From 5dde7bd92211c4049b75738b17532f6d6a66b37c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20=C4=8Cuki=C4=87?= Date: Mon, 8 Oct 2018 21:12:26 +0200 Subject: [PATCH 0490/1650] Erase password data on QLineEdit destruction The contents of a deleted QString can still remain in memory and can be accessible by tools that read the raw process memory. This means that a QLineEdit that serves as a password input field can leak the password after it is destroyed. With this patch, the contents of the m_text string member variable will be zeroed-out before the m_text is destructed. This is done only in the cases when the QLineEdit serves as a password field. [ChangeLog][QtWidgets][QWidgetLineControl/security] Zero-out the string that contains a password entered into the QLineEdit Change-Id: I8f88f952244bf8a0399c14acf0869439ca0a60ca Reviewed-by: Luca Beldi Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/widgets/widgets/qwidgetlinecontrol_p.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/widgets/widgets/qwidgetlinecontrol_p.h b/src/widgets/widgets/qwidgetlinecontrol_p.h index 3e33bc0605..b730b415f0 100644 --- a/src/widgets/widgets/qwidgetlinecontrol_p.h +++ b/src/widgets/widgets/qwidgetlinecontrol_p.h @@ -110,6 +110,12 @@ public: ~QWidgetLineControl() { + // If this control is used for password input, we don't want the + // password data to stay in the process memory, therefore we need + // to zero it out + if (m_echoMode != QLineEdit::Normal) + m_text.fill('\0'); + delete [] m_maskData; } From 416b4cf685030114837bd375664fd12047895a62 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 9 Nov 2018 10:04:54 +0100 Subject: [PATCH 0491/1650] Set correct vertical position for text following a very large image If the document is paged and contains an image spanning more than one page, correctly set the y position for everything following that image. Change-Id: I1c584c7a907c1728c2965f1dc3fdc56069ab3172 Fixes: QTBUG-59886 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qtextdocumentlayout.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index ebd7a7d69f..323253c70d 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -155,7 +155,7 @@ struct QTextLayoutStruct { { return pageHeight == 0 ? 0 : (absoluteY() / pageHeight).truncate(); } inline void newPage() - { if (pageHeight == QFIXED_MAX) return; pageBottom += pageHeight; y = pageBottom - pageHeight + pageBottomMargin + pageTopMargin - frameY; } + { if (pageHeight == QFIXED_MAX) return; pageBottom += pageHeight; y = qMax(y, pageBottom - pageHeight + pageBottomMargin + pageTopMargin - frameY); } }; class QTextTableData : public QTextFrameData @@ -2709,7 +2709,7 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi qreal(q->paintDevice()->logicalDpiY()) / qreal(qt_defaultDpi()) : 1; getLineHeightParams(blockFormat, line, scaling, &lineAdjustment, &lineBreakHeight, &lineHeight, &lineBottom); - if (layoutStruct->pageHeight > 0 && layoutStruct->absoluteY() + lineBreakHeight > layoutStruct->pageBottom && + while (layoutStruct->pageHeight > 0 && layoutStruct->absoluteY() + lineBreakHeight > layoutStruct->pageBottom && layoutStruct->pageHeight >= lineBreakHeight) { layoutStruct->newPage(); From 13ed06640c6cf32ea8c784c896c6bf017053edb3 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Mon, 3 Dec 2018 12:28:12 +0200 Subject: [PATCH 0492/1650] [Android] Fix the ability to override environment and arguments This mechanism should only be enabled only for debug deployments, but the check was removed by accident in ca139228abdd522a76b2750aed607440568eb7f3. Fixes: QTBUG-72230 Fixes: QTBUG-72132 Change-Id: I3378436e93314fdf254919aed066f1284a4581b3 Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../src/org/qtproject/qt5/android/QtActivityDelegate.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index 8f218d34f0..74b515ef5b 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -674,6 +674,13 @@ public class QtActivityDelegate Bundle extras = m_activity.getIntent().getExtras(); if (extras != null) { try { + // do NOT remove !!!! + final String dc = "--Added-by-androiddeployqt--/debugger.command"; + new BufferedReader(new InputStreamReader(m_activity.getAssets().open(dc))).readLine(); + // do NOT remove !!!! + // The previous lines are needed to check if the debug mode is enabled. + // We are not allowed to use extraenvvars or extraappparams in a non debuggable environment. + if (extras.containsKey("extraenvvars")) { try { m_environmentVariables += "\t" + new String(Base64.decode(extras.getString("extraenvvars"), Base64.DEFAULT), "UTF-8"); From 49319734c11206f6993aa12b42a663d3906da26e Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Tue, 27 Nov 2018 15:25:53 +0100 Subject: [PATCH 0493/1650] ico image handler: check for out of range image size Make the decoder fail early to avoid spending time and memory on attempting to decode a corrupt image file. Change-Id: I598db817c387867a449040f5be5427c8b8746483 Reviewed-by: Lars Knoll --- src/plugins/imageformats/ico/qicohandler.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/imageformats/ico/qicohandler.cpp b/src/plugins/imageformats/ico/qicohandler.cpp index e61173db30..30935cacda 100644 --- a/src/plugins/imageformats/ico/qicohandler.cpp +++ b/src/plugins/imageformats/ico/qicohandler.cpp @@ -506,6 +506,8 @@ QImage ICOReader::iconAt(int index) icoAttrib.h = iconEntry.bHeight; if (icoAttrib.h == 0) // means 256 pixels icoAttrib.h = header.biHeight/2; + if (icoAttrib.w > 256 || icoAttrib.h > 256) // Max ico size + return img; QImage::Format format = QImage::Format_ARGB32; if (icoAttrib.nbits == 24) From 46a2b44b2b7f50ced7f2c0731cc6224478d960c7 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 12 Oct 2018 14:41:41 +0200 Subject: [PATCH 0494/1650] qmake: fix QMAKE_DEFAULT_LIBDIRS detection on android amazingly enough, android has different sysroots for the compiler (shared includes full of #ifdefs) and the linker (per-platform libraries). this patch supports only clang for non-darwin, which notably covers all supported android ndks. with this fixed, we also remove the hard-coded setting of QMAKE_DEFAULT_*DIRS from the specs. amends 353fb118c. Change-Id: Ie0513de0f7123d7f5b8ca1ffcc72c017cddd126c Reviewed-by: Joerg Bornemann Reviewed-by: Oswald Buddenhagen --- mkspecs/common/android-base-tail.conf | 3 --- mkspecs/features/toolchain.prf | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/mkspecs/common/android-base-tail.conf b/mkspecs/common/android-base-tail.conf index 57f009f78f..f403ef9330 100644 --- a/mkspecs/common/android-base-tail.conf +++ b/mkspecs/common/android-base-tail.conf @@ -87,6 +87,3 @@ QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 !exists($$NDK_ROOT): error("You need to set the ANDROID_NDK_ROOT environment variable to point to your Android NDK.") load(qt_config) - -QMAKE_DEFAULT_LIBDIRS = $$QMAKE_LIBDIR -QMAKE_DEFAULT_INCDIRS = $$QMAKE_INCDIR diff --git a/mkspecs/features/toolchain.prf b/mkspecs/features/toolchain.prf index 4ecfb8d889..6039c52bd0 100644 --- a/mkspecs/features/toolchain.prf +++ b/mkspecs/features/toolchain.prf @@ -128,8 +128,8 @@ isEmpty($${target_prefix}.INCDIRS) { # paths, so it can't just be used in place of the above code). # What's more, -print-search-dirs can't be used on clang on Apple because it # won't print all the library paths (only the clang-internal ones). - output = $$system("$$cmd_prefix $$QMAKE_CXX -print-search-dirs", lines, ec) - !equals(ec, 0): qtCompilerErrror($$QMAKE_CXX, $$output) + output = $$system("$$cmd_prefix $$QMAKE_LINK $$QMAKE_LFLAGS -print-search-dirs", lines, ec) + !equals(ec, 0): qtCompilerErrror($$QMAKE_LINK, $$output) for (line, output) { contains(line, "^libraries: .*") { From 521a85395da1a2728902816c072ec46bcb0ad380 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 1 Dec 2017 20:13:08 +0100 Subject: [PATCH 0495/1650] configure: actually resolve libraries into full filepaths this considerably speeds up failures, as no doomed build is attempted, and produces more reliable results, as no second lookup (which would be subject to environment changes) is done any more during the build. in principle, this also opens up possibilities like selecting specific variants of dependencies, automatically extracting rpaths, etc. qt_helper_lib.prf also needs to create fully resolved library names now. Change-Id: I65f13564b635433030e40fa017427bbc72d1c130 Reviewed-by: Joerg Bornemann --- configure.json | 2 +- mkspecs/features/qmake_use.prf | 1 - mkspecs/features/qt_configure.prf | 171 +++++++++++++++++++++------ mkspecs/features/qt_helper_lib.prf | 19 ++- src/network/configure.json | 1 - src/network/configure.pri | 6 +- src/plugins/sqldrivers/configure.pri | 50 +++----- 7 files changed, 173 insertions(+), 77 deletions(-) diff --git a/configure.json b/configure.json index 7c79b5c582..69e058e0c2 100644 --- a/configure.json +++ b/configure.json @@ -211,7 +211,7 @@ "verifySpec": [ "shared", "use_gold_linker", "compiler-flags", "qmakeargs", "commit" ], "compile": [ "verifyspec" ], "detectPkgConfig": [ "cross_compile", "machineTuple" ], - "library": [ "pkg-config" ], + "library": [ "pkg-config", "compiler-flags" ], "getPkgConfigVariable": [ "pkg-config" ] }, diff --git a/mkspecs/features/qmake_use.prf b/mkspecs/features/qmake_use.prf index f81d1cece4..dba45de92a 100644 --- a/mkspecs/features/qmake_use.prf +++ b/mkspecs/features/qmake_use.prf @@ -9,7 +9,6 @@ for(ever) { error("Library '$$name' is not defined.") !contains(use, nolink) { - QMAKE_LIBDIR += $$eval(QMAKE_LIBDIR_$$nu) debug: \ LIBS$${suffix} += $$eval(QMAKE_LIBS_$${nu}_DEBUG) $$eval(QMAKE_LIBS_$$nu) else: \ diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index 65ee7df50b..44d8a3e639 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -365,9 +365,13 @@ defineTest(qtConfTest_linkerSupportsFlag) { } defineReplace(qtConfFindInPathList) { + # This nesting is consistent with Apple ld -search_paths_first, + # and presumably with GNU ld (no actual documentation found). for (dir, 2) { - exists("$$dir/$${1}"): \ - return("$$dir/$${1}") + for (file, 1) { + exists("$$dir/$$file"): \ + return("$$dir/$$file") + } } return() } @@ -488,6 +492,110 @@ defineTest(qtConfSetupLibraries) { } } +# libs-var, libs, in-paths, out-paths-var +defineTest(qtConfResolveLibs) { + ret = true + paths = $$3 + out = + copy = false + for (l, 2) { + $$copy { + copy = false + out += $$l + } else: equals(l, "-s") { + # em++ flag to link libraries from emscripten-ports; passed on literally. + copy = true + out += $$l + } else: contains(l, "^-L.*") { + lp = $$replace(l, "^-L", ) + !exists($$lp/.) { + qtLog("Library path $$val_escape(lp) is invalid.") + ret = false + } else { + paths += $$lp + } + } else: contains(l, "^-l.*") { + lib = $$replace(l, "^-l", ) + lcan = + unix { + # Under UNIX, we look for actual shared libraries, in addition + # to static ones. + lcan += \ + $${QMAKE_PREFIX_SHLIB}$${lib}.$${QMAKE_EXTENSION_SHLIB} \ + $${QMAKE_PREFIX_STATICLIB}$${lib}.$${QMAKE_EXTENSION_STATICLIB} + } else { + # Under Windows, we look only for static libraries, as even for DLLs + # one actually links against a static import library. + mingw { + lcan += \ + # MinGW supports UNIX-style library naming in addition to + # the MSVC style. + lib$${lib}.dll.a lib$${lib}.a \ + # Fun fact: prefix-less libraries are also supported. + $${lib}.dll.a $${lib}.a + } + lcan += $${lib}.lib + } + l = $$qtConfFindInPathList($$lcan, $$paths $$EXTRA_LIBDIR $$QMAKE_DEFAULT_LIBDIRS) + isEmpty(l) { + qtLog("None of [$$val_escape(lcan)] found in [$$val_escape(paths)] and global paths.") + ret = false + } else { + out += $$l + } + } else { + out += $$l + } + } + $$1 = $$out + export($$1) + !isEmpty(4) { + $$4 = $$paths + export($$4) + } + return($$ret) +} + +# source-var +defineTest(qtConfResolveAllLibs) { + ret = true + !qtConfResolveLibs($${1}.libs, $$eval($${1}.libs), , $${1}.libdirs): \ + ret = false + for (b, $${1}.builds._KEYS_): \ + !qtConfResolveLibs($${1}.builds.$${b}, $$eval($${1}.builds.$${b}), $$eval($${1}.libdirs), ): \ + ret = false + return($$ret) +} + +# libs-var, in-paths, libs +defineTest(qtConfResolvePathLibs) { + ret = true + for (libdir, 2) { + !exists($$libdir/.) { + qtLog("Library path $$val_escape(libdir) is invalid.") + ret = false + } + } + !qtConfResolveLibs($$1, $$3, $$2): \ + ret = false + return($$ret) +} + +# includes-var, includes +defineTest(qtConfResolvePathIncs) { + ret = true + for (incdir, 2) { + !exists($$incdir/.) { + qtLog("Include path $$val_escape(incdir) is invalid.") + ret = false + } + } + 2 -= $$QMAKE_DEFAULT_INCDIRS + $$1 = $$2 + export($$1) + return($$ret) +} + # the library is specified inline in a 'libs' field. # overrides from the command line are accepted. defineTest(qtConfLibrary_inline) { @@ -517,7 +625,6 @@ defineTest(qtConfLibrary_inline) { vars += $$eval(config.commandline.rev_assignments.$${iv}) defined(config.input.$${iv}, var) { eval($${1}.builds.$${b} = $$eval(config.input.$${iv})) - export($${1}.builds.$${b}) $${1}.builds._KEYS_ *= $${b} any = true } else { @@ -532,35 +639,30 @@ defineTest(qtConfLibrary_inline) { export($${1}.builds._KEYS_) # we also reset the generic libs, to avoid surprises. $${1}.libs = - export($${1}.libs) } # direct libs. overwrites inline libs. - defined(config.input.$${input}.libs, var) { + defined(config.input.$${input}.libs, var): \ eval($${1}.libs = $$eval(config.input.$${input}.libs)) - export($${1}.libs) - } + + includes = $$eval(config.input.$${input}.incdir) # prefix. prepends to (possibly overwritten) inline libs. prefix = $$eval(config.input.$${input}.prefix) !isEmpty(prefix) { - $${1}.includedir = $$prefix/include - export($${1}.includedir) + includes += $$prefix/include $${1}.libs = -L$$prefix/lib $$eval($${1}.libs) - export($${1}.libs) - } - - incdir = $$eval(config.input.$${input}.incdir) - !isEmpty(incdir) { - $${1}.includedir = $$incdir - export($${1}.includedir) } libdir = $$eval(config.input.$${input}.libdir) - !isEmpty(libdir) { + !isEmpty(libdir): \ $${1}.libs = -L$$libdir $$eval($${1}.libs) - export($${1}.libs) - } + + !qtConfResolveAllLibs($$1): \ + return(false) + + !qtConfResolvePathIncs($${1}.includedir, $$includes): \ + return(false) return(true) } @@ -572,17 +674,13 @@ defineTest(qtConfLibrary_makeSpec) { isEmpty(spec): \ error("makeSpec source in library '$$eval($${1}.library)' does not specify 'spec'.") - $${1}.includedir = $$eval(QMAKE_INCDIR_$$spec) - export($${1}.includedir) - $${1}.libs = - for (l, QMAKE_LIBDIR_$$spec): \ - $${1}.libs += -L$$l - $${1}.libs += $$eval(QMAKE_LIBS_$$spec) - export($${1}.libs) + !qtConfResolvePathLibs($${1}.libs, $$eval(QMAKE_LIBDIR_$$spec), $$eval(QMAKE_LIBS_$$spec)): \ + return(false) - # the library definition is always in scope, so no point in exporting it. - $${1}.export = false - export($${1}.export) + !qtConfResolvePathIncs($${1}.includedir, $$eval(QMAKE_INCDIR_$$spec)): \ + return(false) + + # note that the object is re-exported, because we resolve the libraries. return(true) } @@ -602,13 +700,15 @@ defineTest(qtConfLibrary_pkgConfig) { } qtRunLoggedCommand("$$pkg_config --modversion $$args", version)|return(false) - qtRunLoggedCommand("$$pkg_config --libs-only-L $$args", libpaths)|return(false) - qtRunLoggedCommand("$$pkg_config --libs-only-l $$args", libs)|return(false) version ~= s/[^0-9.].*$// $${1}.version = $$first(version) export($${1}.version) - eval($${1}.libs = $$libpaths $$libs) - export($${1}.libs) + + qtRunLoggedCommand("$$pkg_config --libs-only-L $$args", libpaths)|return(false) + qtRunLoggedCommand("$$pkg_config --libs-only-l $$args", libs)|return(false) + eval(libs = $$libpaths $$libs) + !qtConfResolveLibs($${1}.libs, $$libs): \ + return(false) qtRunLoggedCommand("$$pkg_config --cflags $$args", $${1}.cflags)|return(false) # Split CFLAGS into stuff that goes into DEFINES, INCLUDEPATH, and other stuff. @@ -633,10 +733,11 @@ defineTest(qtConfLibrary_pkgConfig) { } !isEmpty(ignored): \ qtLog("Note: Dropped compiler flags '$$ignored'.") + !qtConfResolvePathIncs($${1}.includedir, $$includes): \ + return(false) $${1}.defines = $$defines export($${1}.defines) - $${1}.includedir = $$includes - export($${1}.includedir) + return(true) } diff --git a/mkspecs/features/qt_helper_lib.prf b/mkspecs/features/qt_helper_lib.prf index b3e49e4626..1a8446acb4 100644 --- a/mkspecs/features/qt_helper_lib.prf +++ b/mkspecs/features/qt_helper_lib.prf @@ -34,19 +34,30 @@ THE_TARGET = $$qt5LibraryTarget($$TARGET) MODULE_PRI = $$MODULE_QMAKE_OUTDIR/mkspecs/modules/qt_ext_$${MODULE}.pri ucmodule = $$upper($$MODULE) + win32|CONFIG(static, static|shared) { + prefix = $$QMAKE_PREFIX_STATICLIB + suffix = $$QMAKE_EXTENSION_STATICLIB + } else { + prefix = $$QMAKE_PREFIX_SHLIB + suffix = $$QMAKE_EXTENSION_SHLIB + } MODULE_PRI_CONT = \ "QMAKE_INCDIR_$${ucmodule} = $$val_escape(MODULE_INCLUDEPATH)" \ "QMAKE_DEFINES_$${ucmodule} = $$val_escape(MODULE_DEFINES)" debug_and_release { - win32: MODULE_DEBUG_LIBS = -L$$DESTDIR -l$${TARGET}d - darwin: MODULE_DEBUG_LIBS = -L$$DESTDIR -l$${TARGET}_debug - MODULE_RELEASE_LIBS = -L$$DESTDIR -l$$TARGET + win32: \ + MODULE_DEBUG_LIBS = $$DESTDIR/$$prefix$${TARGET}d.$$suffix + else: darwin: \ + MODULE_DEBUG_LIBS = $$DESTDIR/$$prefix$${TARGET}_debug.$$suffix + else: \ + error("'$$QMAKE_PLATFORM' does not do debug_and_release.") + MODULE_RELEASE_LIBS = $$DESTDIR/$$prefix$${TARGET}.$$suffix MODULE_PRI_CONT += \ "QMAKE_LIBS_$${ucmodule} =" \ # Needed for the module to be recognized. "QMAKE_LIBS_$${ucmodule}_DEBUG = $$val_escape(MODULE_DEBUG_LIBS)" \ "QMAKE_LIBS_$${ucmodule}_RELEASE = $$val_escape(MODULE_RELEASE_LIBS)" } else { - MODULE_LIBS = -L$$DESTDIR -l$$THE_TARGET + MODULE_LIBS = $$DESTDIR/$$prefix$${THE_TARGET}.$$suffix MODULE_PRI_CONT += \ "QMAKE_LIBS_$${ucmodule} = $$val_escape(MODULE_LIBS)" } diff --git a/src/network/configure.json b/src/network/configure.json index 327131ba11..019f8378c7 100644 --- a/src/network/configure.json +++ b/src/network/configure.json @@ -32,7 +32,6 @@ ] }, "network": { - "export": "", "sources": [ { "type": "makeSpec", "spec": "NETWORK" } ] diff --git a/src/network/configure.pri b/src/network/configure.pri index fa502db1d1..ad4d711cba 100644 --- a/src/network/configure.pri +++ b/src/network/configure.pri @@ -1,10 +1,10 @@ # custom tests defineTest(qtConfLibrary_openssl) { - libs = $$getenv("OPENSSL_LIBS") + eval(libs = $$getenv("OPENSSL_LIBS")) !isEmpty(libs) { - eval($${1}.libs = $$libs) - export($${1}.libs) + !qtConfResolveLibs($${1}.libs, $$libs): \ + return(false) return(true) } qtLog("$OPENSSL_LIBS is not set.") diff --git a/src/plugins/sqldrivers/configure.pri b/src/plugins/sqldrivers/configure.pri index 24954e9514..747a47e7b8 100644 --- a/src/plugins/sqldrivers/configure.pri +++ b/src/plugins/sqldrivers/configure.pri @@ -1,29 +1,16 @@ # custom tests -defineReplace(filterLibraryPath) { - str = $${1} - for (l, QMAKE_DEFAULT_LIBDIRS): \ - str -= "-L$$l" - - return($$str) -} - defineTest(qtConfLibrary_psqlConfig) { pg_config = $$config.input.psql_config isEmpty(pg_config): \ pg_config = $$qtConfFindInPath("pg_config") !win32:!isEmpty(pg_config) { qtRunLoggedCommand("$$pg_config --libdir", libdir)|return(false) + !qtConfResolvePathLibs($${1}.libs, $$libdir, -lpq): \ + return(false) qtRunLoggedCommand("$$pg_config --includedir", includedir)|return(false) - libdir -= $$QMAKE_DEFAULT_LIBDIRS - libs = - !isEmpty(libdir): libs += "-L$$libdir" - libs += "-lpq" - $${1}.libs = $$libs - includedir -= $$QMAKE_DEFAULT_INCDIRS - $${1}.includedir = $$includedir - export($${1}.libs) - export($${1}.includedir) + !qtConfResolvePathIncs($${1}.includedir, $$includedir): \ + return(false) return(true) } qtLog("pg_config not found.") @@ -34,8 +21,9 @@ defineTest(qtConfLibrary_psqlEnv) { # Respect PSQL_LIBS if set PSQL_LIBS = $$getenv(PSQL_LIBS) !isEmpty(PSQL_LIBS) { - eval($${1}.libs = $$PSQL_LIBS) - export($${1}.libs) + eval(libs = $$PSQL_LIBS) + !qtConfResolveLibs($${1}.libs, $$libs): \ + return(false) } else { !qtConfLibrary_inline($$1, $$2): \ return(false) @@ -58,7 +46,6 @@ defineTest(qtConfLibrary_mysqlConfig) { qtRunLoggedCommand("$$mysql_config $$query", libs)|return(false) qtRunLoggedCommand("$$mysql_config --include", includedir)|return(false) eval(libs = $$libs) - libs = $$filterLibraryPath($$libs) # -rdynamic should not be returned by mysql_config, but is on RHEL 6.6 libs -= -rdynamic equals($${1}.cleanlibs, true) { @@ -69,16 +56,15 @@ defineTest(qtConfLibrary_mysqlConfig) { } libs = $$cleanlibs } - $${1}.libs = $$libs + !qtConfResolveLibs($${1}.libs, $$libs): \ + return(false) eval(rawincludedir = $$includedir) rawincludedir ~= s/^-I//g includedir = for (id, rawincludedir): \ includedir += $$clean_path($$id) - includedir -= $$QMAKE_DEFAULT_INCDIRS - $${1}.includedir = $$includedir - export($${1}.libs) - export($${1}.includedir) + !qtConfResolvePathIncs($${1}.includedir, $$includedir): \ + return(false) return(true) } qtLog("mysql_config not found.") @@ -86,14 +72,14 @@ defineTest(qtConfLibrary_mysqlConfig) { } defineTest(qtConfLibrary_sybaseEnv) { - libs = + libdir = sybase = $$getenv(SYBASE) !isEmpty(sybase): \ - libs += "-L$${sybase}/lib" - eval(libs += $$getenv(SYBASE_LIBS)) - !isEmpty(libs) { - $${1}.libs = $$libs - export($${1}.libs) - } + libdir += $${sybase}/lib + eval(libs = $$getenv(SYBASE_LIBS)) + isEmpty(libs): \ + libs = $$eval($${1}.libs) + !qtConfResolvePathLibs($${1}.libs, $$libdir, $$libs): \ + return(false) return(true) } From a8412dc020e82b45b54b0b6637b8b88b255c413a Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Thu, 25 Oct 2018 10:44:16 +0200 Subject: [PATCH 0496/1650] Enable OCSP stapling in QSslSocket MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch enables OCSP stapling in QSslSocket::SslClientMode (OpenSSL back-end only). OCSP stapling is described by RFC6066 and based on the original OCSP as defined by RFC2560. At the moment multiple certificate status protocol is not supported (not implemented in OpenSSL). SecureTransport does not support OCSP stapling at the moment. [ChangeLog][QtNetwork][TLS] Added OCSP-stapling support for OpenSSL backend Task-number: QTBUG-12812 Task-number: QTBUG-17158 Change-Id: Id2e0f4cc861311d1ece462864e5e30c76184af8c Reviewed-by: Edward Welbourne Reviewed-by: Mårten Nordheim --- src/network/configure.json | 26 ++ src/network/ssl/qsslconfiguration.cpp | 37 ++- src/network/ssl/qsslconfiguration.h | 3 + src/network/ssl/qsslconfiguration_p.h | 6 + src/network/ssl/qsslerror.cpp | 45 +++ src/network/ssl/qsslerror.h | 12 + src/network/ssl/qsslsocket.cpp | 6 + src/network/ssl/qsslsocket_openssl.cpp | 309 +++++++++++++++++- .../ssl/qsslsocket_openssl11_symbols_p.h | 4 + src/network/ssl/qsslsocket_openssl_p.h | 12 + .../ssl/qsslsocket_openssl_symbols.cpp | 48 ++- .../ssl/qsslsocket_openssl_symbols_p.h | 39 +++ 12 files changed, 540 insertions(+), 7 deletions(-) diff --git a/src/network/configure.json b/src/network/configure.json index 327131ba11..368209cd3f 100644 --- a/src/network/configure.json +++ b/src/network/configure.json @@ -15,6 +15,7 @@ "openssl-linked": { "type": "void", "name": "openssl", "value": "linked" }, "openssl-runtime": { "type": "void", "name": "openssl", "value": "runtime" }, "dtls": "boolean", + "ocsp": "boolean", "sctp": "boolean", "securetransport": "boolean", "ssl": "boolean", @@ -163,6 +164,23 @@ ] }, "use": "openssl" + }, + "ocsp": { + "label": "OCSP stapling support in OpenSSL", + "type": "compile", + "test": { + "include": ["openssl/ssl.h", "openssl/ocsp.h"], + "tail": [ + "#if defined(OPENSSL_NO_OCSP) || defined(OPENSSL_NO_TLSEXT)", + "# error OpenSSL without OCSP stapling", + "#endif" + ], + "main": [ + "(void)SSL_get_tlsext_status_ocsp_resp(nullptr, nullptr);", + "(void)d2i_OCSP_RESPONSE(nullptr, nullptr, 0);" + ] + }, + "use": "openssl" } }, @@ -237,6 +255,13 @@ "condition": "features.openssl && tests.dtls", "output": [ "publicFeature" ] }, + "ocsp": { + "label": "OCSP-stapling", + "purpose": "Provides OCSP stapling support", + "section": "Networking", + "condition": "features.opensslv11 && tests.ocsp", + "output": [ "publicFeature" ] + }, "opensslv11": { "label": "OpenSSL 1.1", "condition": "features.openssl && tests.openssl11", @@ -370,6 +395,7 @@ For example: "openssl-linked", "opensslv11", "dtls", + "ocsp", "sctp", "system-proxies" ] diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp index 3f732b4646..4697a5f90f 100644 --- a/src/network/ssl/qsslconfiguration.cpp +++ b/src/network/ssl/qsslconfiguration.cpp @@ -228,7 +228,8 @@ bool QSslConfiguration::operator==(const QSslConfiguration &other) const d->nextAllowedProtocols == other.d->nextAllowedProtocols && d->nextNegotiatedProtocol == other.d->nextNegotiatedProtocol && d->nextProtocolNegotiationStatus == other.d->nextProtocolNegotiationStatus && - d->dtlsCookieEnabled == other.d->dtlsCookieEnabled; + d->dtlsCookieEnabled == other.d->dtlsCookieEnabled && + d->ocspStaplingEnabled == other.d->ocspStaplingEnabled; } /*! @@ -272,7 +273,8 @@ bool QSslConfiguration::isNull() const d->preSharedKeyIdentityHint.isNull() && d->nextAllowedProtocols.isEmpty() && d->nextNegotiatedProtocol.isNull() && - d->nextProtocolNegotiationStatus == QSslConfiguration::NextProtocolNegotiationNone); + d->nextProtocolNegotiationStatus == QSslConfiguration::NextProtocolNegotiationNone && + d->ocspStaplingEnabled == false); } /*! @@ -1094,6 +1096,37 @@ void QSslConfiguration::setDefaultDtlsConfiguration(const QSslConfiguration &con #endif // dtls +/*! + \since 5.13 + If \a enabled is true, client QSslSocket will send a certificate status request + to its peer when initiating a handshake. During the handshake QSslSocket will + verify the server's response. This value must be set before the handshake + starts. + + \sa ocspStaplingEnabled() +*/ +void QSslConfiguration::setOcspStaplingEnabled(bool enabled) +{ +#if QT_CONFIG(ocsp) + d->ocspStaplingEnabled = enabled; +#else + if (enabled) + qCWarning(lcSsl, "Enabling OCSP-stapling requires the feature 'ocsp'"); +#endif // ocsp +} + +/*! + \since 5.13 + Returns true if OCSP stapling was enabled by setOCSPStaplingEnabled(), + otherwise false (which is the default value). + + \sa setOcspStaplingEnabled() +*/ +bool QSslConfiguration::ocspStaplingEnabled() const +{ + return d->ocspStaplingEnabled; +} + /*! \internal */ bool QSslConfigurationPrivate::peerSessionWasShared(const QSslConfiguration &configuration) { diff --git a/src/network/ssl/qsslconfiguration.h b/src/network/ssl/qsslconfiguration.h index 454ac0cee3..8f53e25a53 100644 --- a/src/network/ssl/qsslconfiguration.h +++ b/src/network/ssl/qsslconfiguration.h @@ -170,6 +170,9 @@ public: static void setDefaultDtlsConfiguration(const QSslConfiguration &configuration); #endif // dtls + void setOcspStaplingEnabled(bool enable); + bool ocspStaplingEnabled() const; + enum NextProtocolNegotiationStatus { NextProtocolNegotiationNone, NextProtocolNegotiationNegotiated, diff --git a/src/network/ssl/qsslconfiguration_p.h b/src/network/ssl/qsslconfiguration_p.h index 6c23165c6a..83126bb9a0 100644 --- a/src/network/ssl/qsslconfiguration_p.h +++ b/src/network/ssl/qsslconfiguration_p.h @@ -143,6 +143,12 @@ public: const bool dtlsCookieEnabled = false; #endif // dtls +#if QT_CONFIG(ocsp) + bool ocspStaplingEnabled = false; +#else + const bool ocspStaplingEnabled = false; +#endif + // in qsslsocket.cpp: static QSslConfiguration defaultConfiguration(); static void setDefaultConfiguration(const QSslConfiguration &configuration); diff --git a/src/network/ssl/qsslerror.cpp b/src/network/ssl/qsslerror.cpp index 3f79d1a037..74ff6987d2 100644 --- a/src/network/ssl/qsslerror.cpp +++ b/src/network/ssl/qsslerror.cpp @@ -86,6 +86,18 @@ \value UnspecifiedError \value NoSslSupport \value CertificateBlacklisted + \value OcspNoResponseFound + \value OcspMalformedRequest + \value OcspMalformedResponse + \value OcspInternalError + \value OcspTryLater + \value OcspSigRequred + \value OcspUnauthorized + \value OcspResponseCannotBeTrusted + \value OcspResponseCertIdUnknown + \value OcspResponseExpired + \value OcspStatusUnknown + \sa QSslError::errorString() */ @@ -292,6 +304,39 @@ QString QSslError::errorString() const case CertificateBlacklisted: errStr = QSslSocket::tr("The peer certificate is blacklisted"); break; + case OcspNoResponseFound: + errStr = QSslSocket::tr("No OCSP status response found"); + break; + case OcspMalformedRequest: + errStr = QSslSocket::tr("The OCSP status request had invalid syntax"); + break; + case OcspMalformedResponse: + errStr = QSslSocket::tr("OCSP response contains an unexpected number of SingleResponse structures"); + break; + case OcspInternalError: + errStr = QSslSocket::tr("OCSP responder reached an inconsistent internal state"); + break; + case OcspTryLater: + errStr = QSslSocket::tr("OCSP responder was unable to return a status for the requested certificate"); + break; + case OcspSigRequred: + errStr = QSslSocket::tr("The server requires the client to sign the OCSP request in order to construct a response"); + break; + case OcspUnauthorized: + errStr = QSslSocket::tr("The client is not authorized to request OCSP status from this server"); + break; + case OcspResponseCannotBeTrusted: + errStr = QSslSocket::tr("OCSP reponder's identity cannot be verified"); + break; + case OcspResponseCertIdUnknown: + errStr = QSslSocket::tr("The identity of a certificate in an OCSP response cannot be established"); + break; + case OcspResponseExpired: + errStr = QSslSocket::tr("The certificate status response has expired"); + break; + case OcspStatusUnknown: + errStr = QSslSocket::tr("The certificate's status is unknown"); + break; default: errStr = QSslSocket::tr("Unknown error"); break; diff --git a/src/network/ssl/qsslerror.h b/src/network/ssl/qsslerror.h index d7c959423d..513b8afd7f 100644 --- a/src/network/ssl/qsslerror.h +++ b/src/network/ssl/qsslerror.h @@ -80,6 +80,18 @@ public: HostNameMismatch, NoSslSupport, CertificateBlacklisted, + CertificateStatusUnknown, + OcspNoResponseFound, + OcspMalformedRequest, + OcspMalformedResponse, + OcspInternalError, + OcspTryLater, + OcspSigRequred, + OcspUnauthorized, + OcspResponseCannotBeTrusted, + OcspResponseCertIdUnknown, + OcspResponseExpired, + OcspStatusUnknown, UnspecifiedError = -1 }; diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 4a9d054c0d..270e81774d 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -952,6 +952,9 @@ void QSslSocket::setSslConfiguration(const QSslConfiguration &configuration) d->configuration.nextAllowedProtocols = configuration.allowedNextProtocols(); d->configuration.nextNegotiatedProtocol = configuration.nextNegotiatedProtocol(); d->configuration.nextProtocolNegotiationStatus = configuration.nextProtocolNegotiationStatus(); +#if QT_CONFIG(ocsp) + d->configuration.ocspStaplingEnabled = configuration.ocspStaplingEnabled(); +#endif // if the CA certificates were set explicitly (either via // QSslConfiguration::setCaCertificates() or QSslSocket::setCaCertificates(), @@ -2324,6 +2327,9 @@ void QSslConfigurationPrivate::deepCopyDefaultConfiguration(QSslConfigurationPri #if QT_CONFIG(dtls) ptr->dtlsCookieEnabled = global->dtlsCookieEnabled; #endif +#if QT_CONFIG(ocsp) + ptr->ocspStaplingEnabled = global->ocspStaplingEnabled; +#endif } /*! diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 5a49b56c9d..56764ebc7f 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -83,6 +83,10 @@ #include #include +#if QT_CONFIG(ocsp) +#include +#endif + #include QT_BEGIN_NAMESPACE @@ -198,8 +202,92 @@ QSslErrorEntry QSslErrorEntry::fromStoreContext(X509_STORE_CTX *ctx) }; } +#if QT_CONFIG(ocsp) + +QSslError qt_OCSP_response_status_to_QSslError(long code) +{ + switch (code) { + case OCSP_RESPONSE_STATUS_MALFORMEDREQUEST: + return QSslError::OcspMalformedRequest; + case OCSP_RESPONSE_STATUS_INTERNALERROR: + return QSslError::OcspInternalError; + case OCSP_RESPONSE_STATUS_TRYLATER: + return QSslError::OcspTryLater; + case OCSP_RESPONSE_STATUS_SIGREQUIRED: + return QSslError::OcspSigRequred; + case OCSP_RESPONSE_STATUS_UNAUTHORIZED: + return QSslError::OcspUnauthorized; + case OCSP_RESPONSE_STATUS_SUCCESSFUL: + default: + return {}; + } + Q_UNREACHABLE(); +} + +bool qt_OCSP_certificate_match(OCSP_SINGLERESP *singleResponse, X509 *peerCert, X509 *issuer) +{ + // OCSP_basic_verify does verify that the responder is legit, the response is + // correctly signed, CertID is correct. But it does not know which certificate + // we were presented with by our peer, so it does not check if it's a response + // for our peer's certificate. + Q_ASSERT(singleResponse && peerCert && issuer); + + const OCSP_CERTID *certId = q_OCSP_SINGLERESP_get0_id(singleResponse); // Does not increment refcount. + if (!certId) { + qCWarning(lcSsl, "A SingleResponse without CertID"); + return false; + } + + ASN1_OBJECT *md = nullptr; + ASN1_INTEGER *reportedSerialNumber = nullptr; + const int result = q_OCSP_id_get0_info(nullptr, &md, nullptr, &reportedSerialNumber, const_cast(certId)); + if (result != 1 || !md || !reportedSerialNumber) { + qCWarning(lcSsl, "Failed to extract a hash and serial number from CertID structure"); + return false; + } + + if (!q_X509_get_serialNumber(peerCert)) { + // Is this possible at all? But we have to check this, + // ASN1_INTEGER_cmp (called from OCSP_id_cmp) dereferences + // without any checks at all. + qCWarning(lcSsl, "No serial number in peer's ceritificate"); + return false; + } + + const int nid = q_OBJ_obj2nid(md); + if (nid == NID_undef) { + qCWarning(lcSsl, "Unknown hash algorithm in CertID"); + return false; + } + + const EVP_MD *digest = q_EVP_get_digestbynid(nid); // Does not increment refcount. + if (!digest) { + qCWarning(lcSsl) << "No digest for nid" << nid; + return false; + } + + OCSP_CERTID *recreatedId = q_OCSP_cert_to_id(digest, peerCert, issuer); + if (!recreatedId) { + qCWarning(lcSsl, "Failed to re-create CertID"); + return false; + } + const QSharedPointer guard(recreatedId, q_OCSP_CERTID_free); + + if (q_OCSP_id_cmp(const_cast(certId), recreatedId)) { + qDebug(lcSsl, "Certificate ID mismatch"); + return false; + } + // Bingo! + return true; +} + +#endif // ocsp + // ### This list is shared between all threads, and protected by a -// mutex. Investigate using thread local storage instead. +// mutex. Investigate using thread local storage instead. Or better properly +// use OpenSSL's ability to attach application data to an SSL/SSL_CTX +// and extract it in a callback. See how it's done, for example, in PSK +// callback or in DTLS verification callback. struct QSslErrorList { QMutex mutex; @@ -406,6 +494,21 @@ bool QSslSocketBackendPrivate::initSslContext() } #endif +#if QT_CONFIG(ocsp) + if (configuration.ocspStaplingEnabled) { + if (mode == QSslSocket::SslServerMode) { + setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError, + QSslSocket::tr("Server-side QSslSocket does not support OCSP stapling")); + return false; + } + if (q_SSL_set_tlsext_status_type(ssl, TLSEXT_STATUSTYPE_ocsp) != 1) { + setErrorAndEmit(QAbstractSocket::SslInternalError, + QSslSocket::tr("Failed to enable OCSP stapling")); + return false; + } + } +#endif // ocsp + return true; } @@ -993,9 +1096,33 @@ bool QSslSocketBackendPrivate::startHandshake() } } - bool doVerifyPeer = configuration.peerVerifyMode == QSslSocket::VerifyPeer - || (configuration.peerVerifyMode == QSslSocket::AutoVerifyPeer - && mode == QSslSocket::SslClientMode); + const bool doVerifyPeer = configuration.peerVerifyMode == QSslSocket::VerifyPeer + || (configuration.peerVerifyMode == QSslSocket::AutoVerifyPeer + && mode == QSslSocket::SslClientMode); + +#if QT_CONFIG(ocsp) + // For now it's always QSslSocket::SslClientMode - initSslContext() will bail out early, + // if it's enabled in QSslSocket::SslServerMode. This can change. + if (!configuration.peerCertificate.isNull() && configuration.ocspStaplingEnabled && doVerifyPeer) { + if (!checkOcspStatus()) { + if (ocspErrors.isEmpty()) { + { + const ScopedBool bg(inSetAndEmitError, true); + setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError, ocspErrorDescription); + } + q->abort(); + return false; + } + + for (const QSslError &error : ocspErrors) { + errors << error; + emit q->peerVerifyError(error); + if (q->state() != QAbstractSocket::ConnectedState) + return false; + } + } + } +#endif // ocsp // Check the peer certificate itself. First try the subject's common name // (CN) as a wildcard, then try all alternate subject name DNS entries the @@ -1242,6 +1369,180 @@ void QSslSocketBackendPrivate::_q_caRootLoaded(QSslCertificate cert, QSslCertifi #endif +#if QT_CONFIG(ocsp) + +bool QSslSocketBackendPrivate::checkOcspStatus() +{ + Q_ASSERT(ssl); + Q_ASSERT(mode == QSslSocket::SslClientMode); // See initSslContext() for SslServerMode + Q_ASSERT(configuration.peerVerifyMode != QSslSocket::VerifyNone); + + ocspErrorDescription.clear(); + ocspErrors.clear(); + + const unsigned char *responseData = nullptr; + const long responseLength = q_SSL_get_tlsext_status_ocsp_resp(ssl, &responseData); + if (responseLength <= 0 || !responseData) { + ocspErrors.push_back(QSslError::OcspNoResponseFound); + return false; + } + + OCSP_RESPONSE *response = q_d2i_OCSP_RESPONSE(nullptr, &responseData, responseLength); + if (!response) { + // Treat this as a fatal SslHandshakeError. + ocspErrorDescription = QSslSocket::tr("Failed to decode OCSP response"); + return false; + } + const QSharedPointer responseGuard(response, q_OCSP_RESPONSE_free); + + const int ocspStatus = q_OCSP_response_status(response); + if (ocspStatus != OCSP_RESPONSE_STATUS_SUCCESSFUL) { + // It's not a definitive response, it's an error message (not signed by the responder). + ocspErrors.push_back(qt_OCSP_response_status_to_QSslError(ocspStatus)); + return false; + } + + OCSP_BASICRESP *basicResponse = q_OCSP_response_get1_basic(response); + if (!basicResponse) { + // SslHandshakeError. + ocspErrorDescription = QSslSocket::tr("Failed to extract basic OCSP response"); + return false; + } + const QSharedPointer basicResponseGuard(basicResponse, q_OCSP_BASICRESP_free); + + SSL_CTX *ctx = q_SSL_get_SSL_CTX(ssl); // Does not increment refcount. + Q_ASSERT(ctx); + X509_STORE *store = q_SSL_CTX_get_cert_store(ctx); // Does not increment refcount. + if (!store) { + // SslHandshakeError. + ocspErrorDescription = QSslSocket::tr("No certificate verification store, cannot verify OCSP response"); + return false; + } + + STACK_OF(X509) *peerChain = q_SSL_get_peer_cert_chain(ssl); // Does not increment refcount. + X509 *peerX509 = q_SSL_get_peer_certificate(ssl); + Q_ASSERT(peerChain || peerX509); + const QSharedPointer peerX509Guard(peerX509, q_X509_free); + // OCSP_basic_verify with 0 as verificationFlags: + // + // 0) Tries to find the OCSP responder's certificate in either peerChain + // or basicResponse->certs. If not found, verification fails. + // 1) It checks the signature using the responder's public key. + // 2) Then it tries to validate the responder's cert (building a chain + // etc.) + // 3) It checks CertID in response. + // 4) Ensures the responder is authorized to sign the status respond. + // + // Here it's important to notice that it calls X509_cert_verify and + // as a result, possibly, our verification callback. Given this callback + // at the moment uses a global variable, we have to lock. This will change + // as soon as we fix our verification procedure. + // Also note, OpenSSL prior to 1.0.2b would only use bs->certs to + // verify the responder's chain (see their commit 4ba9a4265bd). + // Working this around - is too much fuss for ancient versions we + // are dropping quite soon anyway. + { + const unsigned long verificationFlags = 0; + const QMutexLocker locker(&_q_sslErrorList()->mutex); + // Before unlocking the mutex, startHandshake() stores errors (found in SSL_connect() + // or SSL_accept()) into the local variable, so it's safe to clear it here - as soon + // as we managed to lock, whoever had the lock before, already stored their own copy + // of errors. + _q_sslErrorList()->errors.clear(); + const int success = q_OCSP_basic_verify(basicResponse, peerChain, store, verificationFlags); + if (success <= 0 || _q_sslErrorList()->errors.size()) { + _q_sslErrorList()->errors.clear(); + ocspErrors.push_back(QSslError::OcspResponseCannotBeTrusted); + } + } + + if (q_OCSP_resp_count(basicResponse) != 1) { + ocspErrors.push_back(QSslError::OcspMalformedResponse); + return false; + } + + OCSP_SINGLERESP *singleResponse = q_OCSP_resp_get0(basicResponse, 0); + if (!singleResponse) { + ocspErrors.clear(); + // A fatal problem -> SslHandshakeError. + ocspErrorDescription = QSslSocket::tr("Failed to decode a SingleResponse from OCSP status response"); + return false; + } + + // Let's make sure the response is for the correct certificate - we + // can re-create this CertID using our peer's certificate and its + // issuer's public key. + + bool matchFound = false; + if (configuration.peerCertificate.isSelfSigned()) { + matchFound = qt_OCSP_certificate_match(singleResponse, peerX509, peerX509); + } else { + const STACK_OF(X509) *certs = q_SSL_get_peer_cert_chain(ssl); + if (!certs) // Oh, what a cataclysm! Last try: + certs = q_OCSP_resp_get0_certs(basicResponse); + if (certs) { + // It could be the first certificate in 'certs' is our peer's + // certificate. Since it was not captured by the 'self-signed' branch + // above, the CertID will not match and we'll just iterate on to the + // next certificate. So we start from 0, not 1. + for (int i = 0, e = q_sk_X509_num(certs); i < e; ++i) { + X509 *issuer = q_sk_X509_value(certs, i); + matchFound = qt_OCSP_certificate_match(singleResponse, peerX509, issuer); + if (matchFound) { + if (q_X509_check_issued(issuer, peerX509) == X509_V_OK) + break; + matchFound = false; + } + } + } + } + + if (!matchFound) + ocspErrors.push_back({QSslError::OcspResponseCertIdUnknown, configuration.peerCertificate}); + + // Check if the response is valid time-wise: + ASN1_GENERALIZEDTIME *revTime = nullptr; + ASN1_GENERALIZEDTIME *thisUpdate = nullptr; + ASN1_GENERALIZEDTIME *nextUpdate = nullptr; + int reason; + const int certStatus = q_OCSP_single_get0_status(singleResponse, &reason, &revTime, &thisUpdate, &nextUpdate); + if (!thisUpdate) { + // This is unexpected, treat as SslHandshakeError, OCSP_check_validity assumes this pointer + // to be != nullptr. + ocspErrors.clear(); + ocspErrorDescription = QSslSocket::tr("Failed to extract 'this update time' from the SingleResponse"); + return false; + } + + // OCSP_check_validity(this, next, nsec, maxsec) does this check: + // this <= now <= next. They allow some freedom to account + // for delays/time inaccuracy. + // this > now + nsec ? -> NOT_YET_VALID + // if maxsec >= 0: + // now - maxsec > this ? -> TOO_OLD + // now - nsec > next ? -> EXPIRED + // next < this ? -> NEXT_BEFORE_THIS + // OK. + if (!q_OCSP_check_validity(thisUpdate, nextUpdate, 60, -1)) + ocspErrors.push_back({QSslError::OcspResponseExpired, configuration.peerCertificate}); + + // And finally, the status: + switch (certStatus) { + case V_OCSP_CERTSTATUS_GOOD: + // This certificate was not found among the revoked ones. + break; + case V_OCSP_CERTSTATUS_REVOKED: + ocspErrors.push_back({QSslError::CertificateRevoked, configuration.peerCertificate}); + break; + case V_OCSP_CERTSTATUS_UNKNOWN: + ocspErrors.push_back({QSslError::OcspStatusUnknown, configuration.peerCertificate}); + } + + return !ocspErrors.size(); +} + +#endif // ocsp + void QSslSocketBackendPrivate::disconnectFromHost() { if (ssl) { diff --git a/src/network/ssl/qsslsocket_openssl11_symbols_p.h b/src/network/ssl/qsslsocket_openssl11_symbols_p.h index fae007e12d..b94b05b765 100644 --- a/src/network/ssl/qsslsocket_openssl11_symbols_p.h +++ b/src/network/ssl/qsslsocket_openssl11_symbols_p.h @@ -172,6 +172,10 @@ void q_BIO_set_init(BIO *a, int init); int q_BIO_get_shutdown(BIO *a); void q_BIO_set_shutdown(BIO *a, int shut); +#if QT_CONFIG(ocsp) +const OCSP_CERTID *q_OCSP_SINGLERESP_get0_id(const OCSP_SINGLERESP *x); +#endif // ocsp + #define q_SSL_CTX_set_min_proto_version(ctx, version) \ q_SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MIN_PROTO_VERSION, version, nullptr) diff --git a/src/network/ssl/qsslsocket_openssl_p.h b/src/network/ssl/qsslsocket_openssl_p.h index c16b9d5f76..6396b44808 100644 --- a/src/network/ssl/qsslsocket_openssl_p.h +++ b/src/network/ssl/qsslsocket_openssl_p.h @@ -69,6 +69,9 @@ #include #include "qsslsocket_p.h" +#include +#include + #ifdef Q_OS_WIN #include #if defined(OCSP_RESPONSE) @@ -152,6 +155,15 @@ public: void _q_caRootLoaded(QSslCertificate,QSslCertificate) override; #endif +#if QT_CONFIG(ocsp) + bool checkOcspStatus(); + + // This decription will go to setErrorAndEmit(SslHandshakeError, ocspErrorDescription) + QString ocspErrorDescription; + // These will go to sslErrors() + QVector ocspErrors; +#endif + Q_AUTOTEST_EXPORT static long setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions); static QSslCipher QSslCipher_from_SSL_CIPHER(const SSL_CIPHER *cipher); static QList STACKOFX509_to_QSslCertificates(STACK_OF(X509) *x509); diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index 75ed3c16e0..3688e8ffd3 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -199,6 +199,28 @@ DEFINEFUNC2(int, BIO_meth_set_create, BIO_METHOD *biom, biom, DgramCreateCallbac DEFINEFUNC2(int, BIO_meth_set_destroy, BIO_METHOD *biom, biom, DgramDestroyCallback dtr, dtr, return 0, return) #endif // dtls +#if QT_CONFIG(ocsp) +DEFINEFUNC(const OCSP_CERTID *, OCSP_SINGLERESP_get0_id, const OCSP_SINGLERESP *x, x, return nullptr, return) +DEFINEFUNC3(OCSP_RESPONSE *, d2i_OCSP_RESPONSE, OCSP_RESPONSE **a, a, const unsigned char **in, in, long len, len, return nullptr, return) +DEFINEFUNC(void, OCSP_RESPONSE_free, OCSP_RESPONSE *rs, rs, return, DUMMYARG) +DEFINEFUNC(OCSP_BASICRESP *, OCSP_response_get1_basic, OCSP_RESPONSE *resp, resp, return nullptr, return) +DEFINEFUNC(void, OCSP_BASICRESP_free, OCSP_BASICRESP *bs, bs, return, DUMMYARG) +DEFINEFUNC(int, OCSP_response_status, OCSP_RESPONSE *resp, resp, return OCSP_RESPONSE_STATUS_INTERNALERROR, return) +DEFINEFUNC4(int, OCSP_basic_verify, OCSP_BASICRESP *bs, bs, STACK_OF(X509) *certs, certs, X509_STORE *st, st, unsigned long flags, flags, return -1, return) +DEFINEFUNC(int, OCSP_resp_count, OCSP_BASICRESP *bs, bs, return 0, return) +DEFINEFUNC2(OCSP_SINGLERESP *, OCSP_resp_get0, OCSP_BASICRESP *bs, bs, int idx, idx, return nullptr, return) +DEFINEFUNC5(int, OCSP_single_get0_status, OCSP_SINGLERESP *single, single, int *reason, reason, ASN1_GENERALIZEDTIME **revtime, revtime, + ASN1_GENERALIZEDTIME **thisupd, thisupd, ASN1_GENERALIZEDTIME **nextupd, nextupd, return -1, return) +DEFINEFUNC4(int, OCSP_check_validity, ASN1_GENERALIZEDTIME *thisupd, thisupd, ASN1_GENERALIZEDTIME *nextupd, nextupd, long nsec, nsec, long maxsec, maxsec, return 0, return) +DEFINEFUNC3(OCSP_CERTID *, OCSP_cert_to_id, const EVP_MD *dgst, dgst, X509 *subject, subject, X509 *issuer, issuer, return nullptr, return) +DEFINEFUNC(void, OCSP_CERTID_free, OCSP_CERTID *cid, cid, return, DUMMYARG) +DEFINEFUNC5(int, OCSP_id_get0_info, ASN1_OCTET_STRING **piNameHash, piNameHash, ASN1_OBJECT **pmd, pmd, + ASN1_OCTET_STRING **piKeyHash, piKeyHash, ASN1_INTEGER **pserial, pserial, OCSP_CERTID *cid, cid, + return 0, return) +DEFINEFUNC(const STACK_OF(X509) *, OCSP_resp_get0_certs, const OCSP_BASICRESP *bs, bs, return nullptr, return) +DEFINEFUNC2(int, OCSP_id_cmp, OCSP_CERTID *a, a, OCSP_CERTID *b, b, return -1, return) +#endif // ocsp + DEFINEFUNC2(void, BIO_set_data, BIO *a, a, void *ptr, ptr, return, DUMMYARG) DEFINEFUNC(void *, BIO_get_data, BIO *a, a, return nullptr, return) DEFINEFUNC2(void, BIO_set_init, BIO *a, a, int init, init, return, DUMMYARG) @@ -329,6 +351,7 @@ DEFINEFUNC(const char *, SSLeay_version, int a, a, return nullptr, return) #endif // QT_CONFIG(opensslv11) DEFINEFUNC(long, ASN1_INTEGER_get, ASN1_INTEGER *a, a, return 0, return) +DEFINEFUNC2(int, ASN1_INTEGER_cmp, const ASN1_INTEGER *a, a, const ASN1_INTEGER *b, b, return 1, return) DEFINEFUNC(int, ASN1_STRING_length, ASN1_STRING *a, a, return 0, return) DEFINEFUNC2(int, ASN1_STRING_to_UTF8, unsigned char **a, a, ASN1_STRING *b, b, return 0, return) DEFINEFUNC4(long, BIO_ctrl, BIO *a, a, int b, b, long c, c, void *d, d, return -1, return) @@ -357,6 +380,7 @@ DEFINEFUNC5(int, EVP_CipherInit, EVP_CIPHER_CTX *ctx, ctx, const EVP_CIPHER *typ DEFINEFUNC6(int, EVP_CipherInit_ex, EVP_CIPHER_CTX *ctx, ctx, const EVP_CIPHER *cipher, cipher, ENGINE *impl, impl, const unsigned char *key, key, const unsigned char *iv, iv, int enc, enc, return 0, return) DEFINEFUNC5(int, EVP_CipherUpdate, EVP_CIPHER_CTX *ctx, ctx, unsigned char *out, out, int *outl, outl, const unsigned char *in, in, int inl, inl, return 0, return) DEFINEFUNC3(int, EVP_CipherFinal, EVP_CIPHER_CTX *ctx, ctx, unsigned char *out, out, int *outl, outl, return 0, return) +DEFINEFUNC(const EVP_MD *, EVP_get_digestbyname, const char *name, name, return nullptr, return) #ifndef OPENSSL_NO_DES DEFINEFUNC(const EVP_CIPHER *, EVP_des_cbc, DUMMYARG, DUMMYARG, return nullptr, return) DEFINEFUNC(const EVP_CIPHER *, EVP_des_ede3_cbc, DUMMYARG, DUMMYARG, return nullptr, return) @@ -473,6 +497,7 @@ DEFINEFUNC(long, SSL_get_verify_result, const SSL *a, a, return -1, return) DEFINEFUNC(long, SSL_get_verify_result, SSL *a, a, return -1, return) #endif DEFINEFUNC(SSL *, SSL_new, SSL_CTX *a, a, return nullptr, return) +DEFINEFUNC(SSL_CTX *, SSL_get_SSL_CTX, SSL *a, a, return nullptr, return) DEFINEFUNC4(long, SSL_ctrl, SSL *a, a, int cmd, cmd, long larg, larg, void *parg, parg, return -1, return) DEFINEFUNC3(int, SSL_read, SSL *a, a, void *b, b, int c, c, return -1, return) DEFINEFUNC3(void, SSL_set_bio, SSL *a, a, BIO *b, b, BIO *c, c, return, DUMMYARG) @@ -1020,7 +1045,25 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(BIO_meth_set_create) RESOLVEFUNC(BIO_meth_set_destroy) #endif // dtls - +#if QT_CONFIG(ocsp) + RESOLVEFUNC(OCSP_SINGLERESP_get0_id) + RESOLVEFUNC(d2i_OCSP_RESPONSE) + RESOLVEFUNC(OCSP_RESPONSE_free) + RESOLVEFUNC(OCSP_response_status) + RESOLVEFUNC(OCSP_response_get1_basic) + RESOLVEFUNC(OCSP_BASICRESP_free) + RESOLVEFUNC(OCSP_basic_verify) + RESOLVEFUNC(OCSP_resp_count) + RESOLVEFUNC(OCSP_resp_get0) + RESOLVEFUNC(OCSP_single_get0_status) + RESOLVEFUNC(OCSP_check_validity) + RESOLVEFUNC(OCSP_cert_to_id) + RESOLVEFUNC(OCSP_id_get0_info) + RESOLVEFUNC(OCSP_resp_get0_certs); + RESOLVEFUNC(OCSP_CERTID_free) + RESOLVEFUNC(OCSP_cert_to_id) + RESOLVEFUNC(OCSP_id_cmp) +#endif // ocsp RESOLVEFUNC(BIO_set_data) RESOLVEFUNC(BIO_get_data) RESOLVEFUNC(BIO_set_init) @@ -1127,6 +1170,7 @@ bool q_resolveOpenSslSymbols() #endif // !opensslv11 RESOLVEFUNC(ASN1_INTEGER_get) + RESOLVEFUNC(ASN1_INTEGER_cmp) RESOLVEFUNC(ASN1_STRING_length) RESOLVEFUNC(ASN1_STRING_to_UTF8) RESOLVEFUNC(BIO_ctrl) @@ -1163,6 +1207,7 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(EVP_CipherInit_ex) RESOLVEFUNC(EVP_CipherUpdate) RESOLVEFUNC(EVP_CipherFinal) + RESOLVEFUNC(EVP_get_digestbyname) #ifndef OPENSSL_NO_DES RESOLVEFUNC(EVP_des_cbc) RESOLVEFUNC(EVP_des_ede3_cbc) @@ -1265,6 +1310,7 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(SSL_get_peer_certificate) RESOLVEFUNC(SSL_get_verify_result) RESOLVEFUNC(SSL_new) + RESOLVEFUNC(SSL_get_SSL_CTX) RESOLVEFUNC(SSL_ctrl) RESOLVEFUNC(SSL_read) RESOLVEFUNC(SSL_set_accept_state) diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h index 7e759d3825..b5aac1c2ae 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols_p.h +++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h @@ -72,6 +72,10 @@ #include "qsslsocket_openssl_p.h" #include +#if QT_CONFIG(ocsp) +#include +#endif + QT_BEGIN_NAMESPACE #define DUMMYARG @@ -224,6 +228,7 @@ QT_BEGIN_NAMESPACE bool q_resolveOpenSslSymbols(); long q_ASN1_INTEGER_get(ASN1_INTEGER *a); +int q_ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y); int q_ASN1_STRING_length(ASN1_STRING *a); int q_ASN1_STRING_to_UTF8(unsigned char **a, ASN1_STRING *b); long q_BIO_ctrl(BIO *a, int b, long c, void *d); @@ -267,6 +272,8 @@ int q_EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, const unsigned int q_EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl, const unsigned char *key, const unsigned char *iv, int enc); int q_EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl); int q_EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); +const EVP_MD *q_EVP_get_digestbyname(const char *name); + #ifndef OPENSSL_NO_DES const EVP_CIPHER *q_EVP_des_cbc(); const EVP_CIPHER *q_EVP_des_ede3_cbc(); @@ -299,6 +306,7 @@ int q_OBJ_ln2nid(const char *s); int q_i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *obj); int q_OBJ_obj2txt(char *buf, int buf_len, ASN1_OBJECT *obj, int no_name); int q_OBJ_obj2nid(const ASN1_OBJECT *a); +#define q_EVP_get_digestbynid(a) q_EVP_get_digestbyname(q_OBJ_nid2sn(a)) #ifdef SSLEAY_MACROS // ### verify void *q_PEM_ASN1_read_bio(d2i_of_void *a, const char *b, BIO *c, void **d, pem_password_cb *e, @@ -385,6 +393,7 @@ STACK_OF(X509) *q_SSL_get_peer_cert_chain(SSL *a); X509 *q_SSL_get_peer_certificate(SSL *a); long q_SSL_get_verify_result(const SSL *a); SSL *q_SSL_new(SSL_CTX *a); +SSL_CTX *q_SSL_get_SSL_CTX(SSL *a); long q_SSL_ctrl(SSL *ssl,int cmd, long larg, void *parg); int q_SSL_read(SSL *a, void *b, int c); void q_SSL_set_bio(SSL *a, BIO *b, BIO *c); @@ -576,6 +585,36 @@ int q_BIO_set_ex_data(BIO *b, int idx, void *data); class QDateTime; QDateTime q_getTimeFromASN1(const ASN1_TIME *aTime); +#ifndef OPENSSL_NO_TLSEXT + +#define q_SSL_set_tlsext_status_type(ssl, type) q_SSL_ctrl((ssl), SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE, (type), nullptr) + +#endif // OPENSSL_NO_TLSEXT + +#if QT_CONFIG(ocsp) + +OCSP_RESPONSE *q_d2i_OCSP_RESPONSE(OCSP_RESPONSE **a, const unsigned char **in, long len); +void q_OCSP_RESPONSE_free(OCSP_RESPONSE *rs); +int q_OCSP_response_status(OCSP_RESPONSE *resp); +OCSP_BASICRESP *q_OCSP_response_get1_basic(OCSP_RESPONSE *resp); +void q_OCSP_BASICRESP_free(OCSP_BASICRESP *bs); +int q_OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, X509_STORE *st, unsigned long flags); +int q_OCSP_resp_count(OCSP_BASICRESP *bs); +OCSP_SINGLERESP *q_OCSP_resp_get0(OCSP_BASICRESP *bs, int idx); +int q_OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, ASN1_GENERALIZEDTIME **revtime, + ASN1_GENERALIZEDTIME **thisupd, ASN1_GENERALIZEDTIME **nextupd); +int q_OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, ASN1_GENERALIZEDTIME *nextupd, long nsec, long maxsec); +int q_OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd, ASN1_OCTET_STRING **pikeyHash, + ASN1_INTEGER **pserial, OCSP_CERTID *cid); +const STACK_OF(X509) *q_OCSP_resp_get0_certs(const OCSP_BASICRESP *bs); +OCSP_CERTID *q_OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer); +void q_OCSP_CERTID_free(OCSP_CERTID *cid); +int q_OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b); + +#define q_SSL_get_tlsext_status_ocsp_resp(ssl, arg) q_SSL_ctrl(ssl, SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP, 0, arg) + +#endif // ocsp + QT_END_NAMESPACE #endif From 4b1ce72c232b21fb1a8ae8ca86c2b8a7bc00b993 Mon Sep 17 00:00:00 2001 From: Ryan Chu Date: Mon, 3 Dec 2018 11:12:27 +0100 Subject: [PATCH 0497/1650] Disable Docker-based test servers on Linux temporarily MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To unlock dev branch, we need to disable the Docker-based test server on Linux for short-term. With this change, we can force update the SHA-1 of docker images in both qt5 and qtbase. During this transitional period, the Linux platform should keep using the remote test server. Change-Id: I4c07abf36154382e5d667ca733901b6d7fda9677 Reviewed-by: Jędrzej Nowacki --- tests/auto/testserver.pri | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/auto/testserver.pri b/tests/auto/testserver.pri index eefb29ab19..3289a14fd2 100644 --- a/tests/auto/testserver.pri +++ b/tests/auto/testserver.pri @@ -56,6 +56,9 @@ TESTSERVER_VERSION = $$system(docker-compose --version) equals(QMAKE_HOST.os, Darwin)|equals(QMAKE_HOST.os, Windows)|isEmpty(TESTSERVER_VERSION) { # Make check with server "qt-test-server.qt-test-net" as a fallback message("testserver: qt-test-server.qt-test-net") +} else:equals(QMAKE_HOST.os, Linux) { + # Disable Docker-based test server and use "qt-test-server.qt-test-net" server as a fallback + message("testserver: qt-test-server.qt-test-net") } else { # Make check with test servers equals(QMAKE_HOST.os, Darwin) { From 972f8845a85d6a07140025e4257cb8a1a2699b5d Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 8 Oct 2018 11:55:13 +0200 Subject: [PATCH 0498/1650] Invert include dependencies between QList and QVector This is a very slight source incompatibility, but required as a preparation for Qt 6, where QList should inherit QVector or share the implementation with it. This requires some special work to correctly instantiate and export QVector from Qt Core on MSVC. Change-Id: I1d042c5fafdde7afe59409eda2580871d4832fcd Reviewed-by: Thiago Macieira --- src/corelib/tools/qlist.cpp | 17 ++++++++++++++ src/corelib/tools/qlist.h | 32 ++++++++++++++++++++++++++ src/corelib/tools/qvector.h | 46 +++---------------------------------- 3 files changed, 52 insertions(+), 43 deletions(-) diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp index 17aba8035b..0eed4a619e 100644 --- a/src/corelib/tools/qlist.cpp +++ b/src/corelib/tools/qlist.cpp @@ -47,6 +47,23 @@ QT_BEGIN_NAMESPACE +/* + ### Qt 5: + ### This needs to be removed for next releases of Qt. It is a workaround for vc++ because + ### Qt exports QPolygon and QPolygonF that inherit QVector and + ### QVector respectively. +*/ + +#if defined(Q_CC_MSVC) && defined(QT_BUILD_CORE_LIB) +QT_BEGIN_INCLUDE_NAMESPACE +#include +QT_END_INCLUDE_NAMESPACE + +template class Q_CORE_EXPORT QVector; +template class Q_CORE_EXPORT QVector; +#endif + + /* QList as an array-list combines the easy-of-use of a random access interface with fast list operations and the low memory diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index 49ccbc9c9f..073993ee56 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -1051,6 +1052,37 @@ inline int QList::count_impl(const T &t, QListData::ArrayCompatibleLayout) co t)); } +template +Q_OUTOFLINE_TEMPLATE QVector QList::toVector() const +{ + QVector result(size()); + for (int i = 0; i < size(); ++i) + result[i] = at(i); + return result; +} + +template +QList QList::fromVector(const QVector &vector) +{ + return vector.toList(); +} + +template +Q_OUTOFLINE_TEMPLATE QList QVector::toList() const +{ + QList result; + result.reserve(size()); + for (int i = 0; i < size(); ++i) + result.append(at(i)); + return result; +} + +template +QVector QVector::fromList(const QList &list) +{ + return list.toVector(); +} + Q_DECLARE_SEQUENTIAL_ITERATOR(List) Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(List) diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 30fd7b2865..778bcb3745 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -42,7 +42,6 @@ #include #include -#include #include #include #include @@ -968,37 +967,6 @@ Q_OUTOFLINE_TEMPLATE QVector QVector::mid(int pos, int len) const return midResult; } -template -Q_OUTOFLINE_TEMPLATE QList QVector::toList() const -{ - QList result; - result.reserve(size()); - for (int i = 0; i < size(); ++i) - result.append(at(i)); - return result; -} - -template -Q_OUTOFLINE_TEMPLATE QVector QList::toVector() const -{ - QVector result(size()); - for (int i = 0; i < size(); ++i) - result[i] = at(i); - return result; -} - -template -QVector QVector::fromList(const QList &list) -{ - return list.toVector(); -} - -template -QList QList::fromVector(const QVector &vector) -{ - return vector.toList(); -} - Q_DECLARE_SEQUENTIAL_ITERATOR(Vector) Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(Vector) @@ -1046,20 +1014,12 @@ inline bool operator>=(const QVector &lhs, const QVector &rhs) ### QVector respectively. */ -#ifdef Q_CC_MSVC +#if defined(Q_CC_MSVC) && !defined(QT_BUILD_CORE_LIB) QT_BEGIN_INCLUDE_NAMESPACE #include QT_END_INCLUDE_NAMESPACE - -#ifndef Q_TEMPLATE_EXTERN -#if defined(QT_BUILD_CORE_LIB) -#define Q_TEMPLATE_EXTERN -#else -#define Q_TEMPLATE_EXTERN extern -#endif -#endif -Q_TEMPLATE_EXTERN template class Q_CORE_EXPORT QVector; -Q_TEMPLATE_EXTERN template class Q_CORE_EXPORT QVector; +extern template class Q_CORE_EXPORT QVector; +extern template class Q_CORE_EXPORT QVector; #endif QVector QStringView::toUcs4() const { return QtPrivate::convertToUcs4(*this); } From 7f4d0405b409b1d3aa9d91e31972669576ec698c Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 10 Oct 2018 18:58:22 +0200 Subject: [PATCH 0499/1650] Rename QList::swap(int, int) to swapItemsAt() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The old name was confusing as it conflicted with QList::swap(QList &other), that was doing something completely different. Rename the method to swapItemsAt() which is a lot clearer. Change-Id: Iac77a1e790a7256766f83a24d2a243c880d875f4 Reviewed-by: Jędrzej Nowacki --- .../doc/snippets/code/src_corelib_tools_qlistdata.cpp | 2 +- src/corelib/tools/qlist.cpp | 7 +++++++ src/corelib/tools/qlist.h | 8 ++++++-- src/corelib/tools/qstringlist.cpp | 2 +- src/gui/image/qimagereader.cpp | 2 +- src/gui/kernel/qplatformintegration.cpp | 2 +- src/plugins/platforms/xcb/qxcbconnection_screens.cpp | 4 ++-- src/widgets/graphicsview/qgraphicssceneindex_p.h | 2 +- 8 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qlistdata.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qlistdata.cpp index cc3f689710..0e746cd6e6 100644 --- a/src/corelib/doc/snippets/code/src_corelib_tools_qlistdata.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_tools_qlistdata.cpp @@ -146,7 +146,7 @@ list.move(1, 4); //! [12] QList list; list << "A" << "B" << "C" << "D" << "E" << "F"; -list.swap(1, 4); +list.swapItemsAt(1, 4); // list: ["A", "E", "C", "D", "B", "F"] //! [12] diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp index 0eed4a619e..1de93ff9e1 100644 --- a/src/corelib/tools/qlist.cpp +++ b/src/corelib/tools/qlist.cpp @@ -965,6 +965,13 @@ void **QListData::erase(void **xi) /*! \fn template void QList::swap(int i, int j) + \obsolete Use swapItemsAt() + + \sa move(), swapItemsAt() +*/ + +/*! \fn template void QList::swapItemsAt(int i, int j) + Exchange the item at index position \a i with the item at index position \a j. This function assumes that both \a i and \a j are at least 0 but less than size(). To avoid failure, test that both diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index 073993ee56..fe8a1407e2 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -214,7 +214,11 @@ public: T takeFirst(); T takeLast(); void move(int from, int to); - void swap(int i, int j); + void swapItemsAt(int i, int j); +#if QT_DEPRECATED_SINCE(5, 13) && QT_VERSION < QT_VERSION_CHECK(6,0,0) + QT_DEPRECATED_X("Use QList::swapItemsAt()") + void swap(int i, int j) { swapItemsAt(i, j); } +#endif int indexOf(const T &t, int from = 0) const; int lastIndexOf(const T &t, int from = -1) const; bool contains(const T &t) const; @@ -690,7 +694,7 @@ inline void QList::replace(int i, const T &t) } template -inline void QList::swap(int i, int j) +inline void QList::swapItemsAt(int i, int j) { Q_ASSERT_X(i >= 0 && i < p.size() && j >= 0 && j < p.size(), "QList::swap", "index out of range"); diff --git a/src/corelib/tools/qstringlist.cpp b/src/corelib/tools/qstringlist.cpp index cf150c2a1b..ec6de08805 100644 --- a/src/corelib/tools/qstringlist.cpp +++ b/src/corelib/tools/qstringlist.cpp @@ -780,7 +780,7 @@ int QtPrivate::QStringList_removeDuplicates(QStringList *that) continue; ++setSize; if (j != i) - that->swap(i, j); + that->swapItemsAt(i, j); ++j; } if (n != j) diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index 0fb1d808e5..3f1297c81a 100644 --- a/src/gui/image/qimagereader.cpp +++ b/src/gui/image/qimagereader.cpp @@ -526,7 +526,7 @@ bool QImageReaderPrivate::initHandler() // Try the most probable extension first int currentFormatIndex = extensions.indexOf(format.toLower()); if (currentFormatIndex > 0) - extensions.swap(0, currentFormatIndex); + extensions.swapItemsAt(0, currentFormatIndex); } int currentExtension = 0; diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp index 6e285a8fa5..9836f569fc 100644 --- a/src/gui/kernel/qplatformintegration.cpp +++ b/src/gui/kernel/qplatformintegration.cpp @@ -534,7 +534,7 @@ void QPlatformIntegration::setPrimaryScreen(QPlatformScreen *newPrimary) if (idx == 0) return; - QGuiApplicationPrivate::screen_list.swap(0, idx); + QGuiApplicationPrivate::screen_list.swapItemsAt(0, idx); emit qGuiApp->primaryScreenChanged(newPrimaryScreen); } diff --git a/src/plugins/platforms/xcb/qxcbconnection_screens.cpp b/src/plugins/platforms/xcb/qxcbconnection_screens.cpp index fe9e0be86d..1f44366aa0 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_screens.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_screens.cpp @@ -208,7 +208,7 @@ void QXcbConnection::updateScreen(QXcbScreen *screen, const xcb_randr_output_cha const int idx = m_screens.indexOf(screen); if (idx > 0) { qAsConst(m_screens).first()->setPrimary(false); - m_screens.swap(0, idx); + m_screens.swapItemsAt(0, idx); } screen->virtualDesktop()->setPrimaryScreen(screen); QXcbIntegration::instance()->setPrimaryScreen(screen); @@ -260,7 +260,7 @@ void QXcbConnection::destroyScreen(QXcbScreen *screen) newPrimary->setPrimary(true); const int idx = m_screens.indexOf(newPrimary); if (idx > 0) - m_screens.swap(0, idx); + m_screens.swapItemsAt(0, idx); QXcbIntegration::instance()->setPrimaryScreen(newPrimary); } diff --git a/src/widgets/graphicsview/qgraphicssceneindex_p.h b/src/widgets/graphicsview/qgraphicssceneindex_p.h index bdc57bd9ea..c86df0e209 100644 --- a/src/widgets/graphicsview/qgraphicssceneindex_p.h +++ b/src/widgets/graphicsview/qgraphicssceneindex_p.h @@ -151,7 +151,7 @@ inline void QGraphicsSceneIndexPrivate::items_helper(const QRectF &rect, QGraphi if (order == Qt::DescendingOrder) { const int n = items->size(); for (int i = 0; i < n / 2; ++i) - items->swap(i, n - i - 1); + items->swapItemsAt(i, n - i - 1); } } From 68fc972ac84539c642f8d3c1260db3175249efd9 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 27 Nov 2018 09:58:40 +0100 Subject: [PATCH 0500/1650] uic: Remove unused code Task-number: PYSIDE-797 Change-Id: I6958ad76c138dcb4126cda8b26f23311963d6d37 Reviewed-by: Jarek Kobus --- src/tools/uic/cpp/cppwriteinitialization.cpp | 21 +--------- src/tools/uic/cpp/cppwriteinitialization.h | 5 --- src/tools/uic/customwidgetsinfo.h | 6 --- src/tools/uic/databaseinfo.h | 6 --- src/tools/uic/driver.cpp | 39 ------------------- src/tools/uic/driver.h | 19 --------- src/tools/uic/globaldefs.h | 41 -------------------- src/tools/uic/treewalker.h | 1 - src/tools/uic/uic.cpp | 25 ------------ src/tools/uic/uic.h | 5 --- src/tools/uic/uic.pri | 1 - 11 files changed, 1 insertion(+), 168 deletions(-) delete mode 100644 src/tools/uic/globaldefs.h diff --git a/src/tools/uic/cpp/cppwriteinitialization.cpp b/src/tools/uic/cpp/cppwriteinitialization.cpp index 28e97f3bba..16fed64f5a 100644 --- a/src/tools/uic/cpp/cppwriteinitialization.cpp +++ b/src/tools/uic/cpp/cppwriteinitialization.cpp @@ -32,7 +32,6 @@ #include "utils.h" #include "uic.h" #include "databaseinfo.h" -#include "globaldefs.h" #include @@ -648,7 +647,7 @@ void WriteInitialization::acceptWidget(DomWidget *node) if (const DomWidget* parentWidget = m_widgetChain.top()) { const QString parentClass = parentWidget->attributeClass(); if (parentClass != QLatin1String("QMainWindow") - && !m_uic->isCustomWidgetContainer(parentClass) + && !m_uic->customWidgetsInfo()->isCustomWidgetContainer(parentClass) && !m_uic->isContainer(parentClass)) m_layoutWidget = true; } @@ -2427,12 +2426,6 @@ QTextStream &WriteInitialization::autoTrOutput(const DomString *str, const QStri return m_output; } -bool WriteInitialization::isValidObject(const QString &name) const -{ - return m_registeredWidgets.contains(name) - || m_registeredActions.contains(name); -} - QString WriteInitialization::findDeclaration(const QString &name) { const QString normalized = Driver::normalizedName(name); @@ -2465,18 +2458,6 @@ void WriteInitialization::acceptConnection(DomConnection *connection) << ");\n"; } -DomWidget *WriteInitialization::findWidget(QLatin1String widgetClass) -{ - for (int i = m_widgetChain.count() - 1; i >= 0; --i) { - DomWidget *widget = m_widgetChain.at(i); - - if (widget && m_uic->customWidgetsInfo()->extends(widget->attributeClass(), widgetClass)) - return widget; - } - - return 0; -} - static void generateMultiDirectiveBegin(QTextStream &outputStream, const QSet &directives) { if (directives.isEmpty()) diff --git a/src/tools/uic/cpp/cppwriteinitialization.h b/src/tools/uic/cpp/cppwriteinitialization.h index cce83bd677..c408c44b40 100644 --- a/src/tools/uic/cpp/cppwriteinitialization.h +++ b/src/tools/uic/cpp/cppwriteinitialization.h @@ -174,8 +174,6 @@ private: void writeRetranslateUi(const QString &parentPath); void addSetter(const QString &setter, const QString &directive = QString(), bool translatable = false); // don't call it if you already added *this as a child of another Item void addChild(Item *child); // all setters should already been added - int setupUiCount() const { return m_setupUiData.setters.count(); } - int retranslateUiCount() const { return m_retranslateUiData.setters.count(); } private: struct ItemData { @@ -223,9 +221,6 @@ private: void enableSorting(DomWidget *w, const QString &varName, const QString &tempName); QString findDeclaration(const QString &name); - DomWidget *findWidget(QLatin1String widgetClass); - - bool isValidObject(const QString &name) const; private: QString writeFontProperties(const DomFont *f); diff --git a/src/tools/uic/customwidgetsinfo.h b/src/tools/uic/customwidgetsinfo.h index 944ed59215..82e86a1266 100644 --- a/src/tools/uic/customwidgetsinfo.h +++ b/src/tools/uic/customwidgetsinfo.h @@ -48,12 +48,6 @@ public: void acceptCustomWidgets(DomCustomWidgets *node) override; void acceptCustomWidget(DomCustomWidget *node) override; - inline QStringList customWidgets() const - { return m_customWidgets.keys(); } - - inline bool hasCustomWidget(const QString &name) const - { return m_customWidgets.contains(name); } - inline DomCustomWidget *customWidget(const QString &name) const { return m_customWidgets.value(name); } diff --git a/src/tools/uic/databaseinfo.h b/src/tools/uic/databaseinfo.h index bebf139c5a..4015e39dbc 100644 --- a/src/tools/uic/databaseinfo.h +++ b/src/tools/uic/databaseinfo.h @@ -48,12 +48,6 @@ public: inline QStringList connections() const { return m_connections; } - inline QStringList cursors(const QString &connection) const - { return m_cursors.value(connection); } - - inline QStringList fields(const QString &connection) const - { return m_fields.value(connection); } - private: QStringList m_connections; QMap m_cursors; diff --git a/src/tools/uic/driver.cpp b/src/tools/uic/driver.cpp index 91a48815fd..748be9cece 100644 --- a/src/tools/uic/driver.cpp +++ b/src/tools/uic/driver.cpp @@ -306,50 +306,11 @@ bool Driver::uic(const QString &fileName, QTextStream *out) return rtn; } -void Driver::reset() -{ - Q_ASSERT( m_output == 0 ); - - m_option = Option(); - m_output = 0; - m_problems.clear(); - - QStringList m_problems; - - m_widgets.clear(); - m_spacers.clear(); - m_layouts.clear(); - m_actionGroups.clear(); - m_actions.clear(); - m_nameRepository.clear(); - m_pixmaps.clear(); -} - -void Driver::insertPixmap(const QString &pixmap) -{ - m_pixmaps.insert(pixmap, true); -} - -bool Driver::containsPixmap(const QString &pixmap) const -{ - return m_pixmaps.contains(pixmap); -} - DomWidget *Driver::widgetByName(const QString &name) const { return m_widgets.key(name); } -DomSpacer *Driver::spacerByName(const QString &name) const -{ - return m_spacers.key(name); -} - -DomLayout *Driver::layoutByName(const QString &name) const -{ - return m_layouts.key(name); -} - DomActionGroup *Driver::actionGroupByName(const QString &name) const { return m_actionGroups.key(name); diff --git a/src/tools/uic/driver.h b/src/tools/uic/driver.h index 1563bdbd83..8d497c39fd 100644 --- a/src/tools/uic/driver.h +++ b/src/tools/uic/driver.h @@ -63,13 +63,6 @@ public: inline QTextStream &output() const { return *m_output; } inline Option &option() { return m_option; } - // initialization - void reset(); - - // error - inline QStringList problems() { return m_problems; } - inline void addProblem(const QString &problem) { m_problems.append(problem); } - // utils static QString headerFileName(const QString &fileName); QString headerFileName() const; @@ -91,19 +84,10 @@ public: // Find a group by its non-uniqified name const DomButtonGroup *findButtonGroup(const QString &attributeName) const; - inline bool hasName(const QString &name) const - { return m_nameRepository.contains(name); } - DomWidget *widgetByName(const QString &name) const; - DomSpacer *spacerByName(const QString &name) const; - DomLayout *layoutByName(const QString &name) const; DomActionGroup *actionGroupByName(const QString &name) const; DomAction *actionByName(const QString &name) const; - // pixmap - void insertPixmap(const QString &pixmap); - bool containsPixmap(const QString &pixmap) const; - bool useIdBasedTranslations() const { return m_idBasedTranslations; } void setUseIdBasedTranslations(bool u) { m_idBasedTranslations = u; } @@ -112,8 +96,6 @@ private: QTextStream m_stdout; QTextStream *m_output; - QStringList m_problems; - // symbol tables QHash m_widgets; QHash m_spacers; @@ -123,7 +105,6 @@ private: ButtonGroupNameHash m_buttonGroups; QHash m_actions; QHash m_nameRepository; - QHash m_pixmaps; bool m_idBasedTranslations = false; }; diff --git a/src/tools/uic/globaldefs.h b/src/tools/uic/globaldefs.h deleted file mode 100644 index 5ad193c29a..0000000000 --- a/src/tools/uic/globaldefs.h +++ /dev/null @@ -1,41 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the tools applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef GLOBALDEFS_H -#define GLOBALDEFS_H - -#include - -QT_BEGIN_NAMESPACE - -enum { BOXLAYOUT_DEFAULT_MARGIN = 11 }; -enum { BOXLAYOUT_DEFAULT_SPACING = 6 }; - -QT_END_NAMESPACE - -#endif // GLOBALDEFS_H diff --git a/src/tools/uic/treewalker.h b/src/tools/uic/treewalker.h index 43d4633d83..7e8eda57d9 100644 --- a/src/tools/uic/treewalker.h +++ b/src/tools/uic/treewalker.h @@ -101,7 +101,6 @@ struct TreeWalker virtual void acceptTime(DomTime *time); virtual void acceptDateTime(DomDateTime *dateTime); virtual void acceptProperty(DomProperty *property); - typedef QVector DomScripts; typedef QVector DomWidgets; virtual void acceptIncludes(DomIncludes *includes); virtual void acceptInclude(DomInclude *incl); diff --git a/src/tools/uic/uic.cpp b/src/tools/uic/uic.cpp index a5b331192f..314989fbf9 100644 --- a/src/tools/uic/uic.cpp +++ b/src/tools/uic/uic.cpp @@ -243,16 +243,6 @@ void Uic::writeHeaderProtectionEnd() out << "#endif // " << h << "\n"; } -bool Uic::isMainWindow(const QString &className) const -{ - return customWidgetsInfo()->extends(className, QLatin1String("QMainWindow")); -} - -bool Uic::isToolBar(const QString &className) const -{ - return customWidgetsInfo()->extends(className, QLatin1String("QToolBar")); -} - bool Uic::isButton(const QString &className) const { return customWidgetsInfo()->extends(className, QLatin1String("QRadioButton")) @@ -273,21 +263,6 @@ bool Uic::isContainer(const QString &className) const || customWidgetsInfo()->extends(className, QLatin1String("QDockWidget")); } -bool Uic::isCustomWidgetContainer(const QString &className) const -{ - return customWidgetsInfo()->isCustomWidgetContainer(className); -} - -bool Uic::isStatusBar(const QString &className) const -{ - return customWidgetsInfo()->extends(className, QLatin1String("QStatusBar")); -} - -bool Uic::isMenuBar(const QString &className) const -{ - return customWidgetsInfo()->extends(className, QLatin1String("QMenuBar")); -} - bool Uic::isMenu(const QString &className) const { return customWidgetsInfo()->extends(className, QLatin1String("QMenu")) diff --git a/src/tools/uic/uic.h b/src/tools/uic/uic.h index 4c961aa0a5..17cb54515b 100644 --- a/src/tools/uic/uic.h +++ b/src/tools/uic/uic.h @@ -85,13 +85,8 @@ public: bool write(DomUI *ui); - bool isMainWindow(const QString &className) const; - bool isToolBar(const QString &className) const; - bool isStatusBar(const QString &className) const; bool isButton(const QString &className) const; bool isContainer(const QString &className) const; - bool isCustomWidgetContainer(const QString &className) const; - bool isMenuBar(const QString &className) const; bool isMenu(const QString &className) const; private: diff --git a/src/tools/uic/uic.pri b/src/tools/uic/uic.pri index 3f0bab05dd..1c9098dcf9 100644 --- a/src/tools/uic/uic.pri +++ b/src/tools/uic/uic.pri @@ -5,7 +5,6 @@ HEADERS += \ $$PWD/customwidgetsinfo.h \ $$PWD/databaseinfo.h \ $$PWD/driver.h \ - $$PWD/globaldefs.h \ $$PWD/option.h \ $$PWD/treewalker.h \ $$PWD/utils.h \ From f213e818f03d35cb82e3daf187415197fd156f8e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 27 Nov 2018 12:31:57 +0100 Subject: [PATCH 0501/1650] uic: Generate correctly qualified invocation of QCoreApplication::translate() Change QApplication::translate() to QCoreApplication::translate() in generator and tests. Task-number: PYSIDE-797 Change-Id: I0bbaf1f280b74b3b2a701a39203c059ab82fce1f Reviewed-by: Jarek Kobus --- src/tools/uic/cpp/cppwriteinitialization.cpp | 2 +- .../baseline/Dialog_with_Buttons_Bottom.ui.h | 2 +- .../baseline/Dialog_with_Buttons_Right.ui.h | 2 +- .../uic/baseline/Dialog_without_Buttons.ui.h | 2 +- .../auto/tools/uic/baseline/Main_Window.ui.h | 2 +- tests/auto/tools/uic/baseline/Widget.ui.h | 8 +- .../tools/uic/baseline/addlinkdialog.ui.h | 6 +- .../tools/uic/baseline/addtorrentform.ui.h | 34 +++--- .../uic/baseline/authenticationdialog.ui.h | 12 +- tests/auto/tools/uic/baseline/backside.ui.h | 38 +++--- .../tools/uic/baseline/batchtranslation.ui.h | 20 ++-- .../tools/uic/baseline/bookmarkdialog.ui.h | 12 +- tests/auto/tools/uic/baseline/bookwindow.ui.h | 16 +-- .../tools/uic/baseline/browserwidget.ui.h | 16 +-- .../uic/baseline/bug18156QTreeWidget.ui.h | 4 +- .../auto/tools/uic/baseline/buttongroup.ui.h | 16 +-- tests/auto/tools/uic/baseline/calculator.ui.h | 56 ++++----- .../tools/uic/baseline/calculatorform.ui.h | 14 +-- .../tools/uic/baseline/certificateinfo.ui.h | 6 +- tests/auto/tools/uic/baseline/chatdialog.ui.h | 4 +- .../tools/uic/baseline/chatmainwindow.ui.h | 24 ++-- .../tools/uic/baseline/chatsetnickname.ui.h | 8 +- tests/auto/tools/uic/baseline/config.ui.h | 74 ++++++------ .../tools/uic/baseline/connectdialog.ui.h | 12 +- tests/auto/tools/uic/baseline/controller.ui.h | 12 +- tests/auto/tools/uic/baseline/cookies.ui.h | 6 +- .../tools/uic/baseline/cookiesexceptions.ui.h | 18 +-- tests/auto/tools/uic/baseline/default.ui.h | 84 ++++++------- tests/auto/tools/uic/baseline/dialog.ui.h | 8 +- .../auto/tools/uic/baseline/downloaditem.ui.h | 12 +- tests/auto/tools/uic/baseline/downloads.ui.h | 6 +- .../tools/uic/baseline/embeddeddialog.ui.h | 14 +-- .../auto/tools/uic/baseline/enumnostdset.ui.h | 2 +- tests/auto/tools/uic/baseline/filespage.ui.h | 8 +- .../tools/uic/baseline/filternamedialog.ui.h | 4 +- tests/auto/tools/uic/baseline/filterpage.ui.h | 14 +-- tests/auto/tools/uic/baseline/finddialog.ui.h | 36 +++--- tests/auto/tools/uic/baseline/form.ui.h | 6 +- .../uic/baseline/formwindowsettings.ui.h | 22 ++-- .../auto/tools/uic/baseline/generalpage.ui.h | 6 +- .../tools/uic/baseline/gridalignment.ui.h | 10 +- tests/auto/tools/uic/baseline/gridpanel.ui.h | 16 +-- tests/auto/tools/uic/baseline/helpdialog.ui.h | 66 +++++------ tests/auto/tools/uic/baseline/history.ui.h | 6 +- tests/auto/tools/uic/baseline/icontheme.ui.h | 8 +- .../tools/uic/baseline/identifierpage.ui.h | 8 +- .../auto/tools/uic/baseline/imagedialog.ui.h | 16 +-- tests/auto/tools/uic/baseline/inputpage.ui.h | 6 +- .../tools/uic/baseline/installdialog.ui.h | 14 +-- .../tools/uic/baseline/languagesdialog.ui.h | 24 ++-- .../tools/uic/baseline/listwidgeteditor.ui.h | 24 ++-- tests/auto/tools/uic/baseline/mainwindow.ui.h | 48 ++++---- tests/auto/tools/uic/baseline/mydialog.ui.h | 8 +- tests/auto/tools/uic/baseline/myform.ui.h | 22 ++-- .../tools/uic/baseline/newactiondialog.ui.h | 8 +- .../baseline/newdynamicpropertydialog.ui.h | 6 +- tests/auto/tools/uic/baseline/newform.ui.h | 8 +- .../auto/tools/uic/baseline/orderdialog.ui.h | 8 +- tests/auto/tools/uic/baseline/outputpage.ui.h | 6 +- tests/auto/tools/uic/baseline/pagefold.ui.h | 88 +++++++------- .../tools/uic/baseline/paletteeditor.ui.h | 18 +-- .../tools/uic/baseline/passworddialog.ui.h | 10 +- tests/auto/tools/uic/baseline/pathpage.ui.h | 10 +- .../tools/uic/baseline/phrasebookbox.ui.h | 32 ++--- .../tools/uic/baseline/pixmapfunction.ui.h | 4 +- .../auto/tools/uic/baseline/plugindialog.ui.h | 8 +- .../tools/uic/baseline/preferencesdialog.ui.h | 10 +- .../baseline/previewconfigurationwidget.ui.h | 16 +-- .../tools/uic/baseline/previewdialogbase.ui.h | 8 +- .../tools/uic/baseline/previewwidget.ui.h | 22 ++-- tests/auto/tools/uic/baseline/proxy.ui.h | 10 +- .../auto/tools/uic/baseline/qfiledialog.ui.h | 16 +-- .../tools/uic/baseline/qpagesetupwidget.ui.h | 46 +++---- .../uic/baseline/qprintpropertieswidget.ui.h | 6 +- .../uic/baseline/qprintsettingsoutput.ui.h | 38 +++--- .../auto/tools/uic/baseline/qprintwidget.ui.h | 18 +-- .../uic/baseline/qsqlconnectiondialog.ui.h | 24 ++-- .../tools/uic/baseline/qtgradientdialog.ui.h | 2 +- .../tools/uic/baseline/qtgradienteditor.ui.h | 112 +++++++++--------- .../tools/uic/baseline/qtgradientview.ui.h | 10 +- .../uic/baseline/qtgradientviewdialog.ui.h | 2 +- .../uic/baseline/qtresourceeditordialog.ui.h | 22 ++-- .../tools/uic/baseline/qttoolbardialog.ui.h | 38 +++--- .../auto/tools/uic/baseline/querywidget.ui.h | 8 +- .../tools/uic/baseline/remotecontrol.ui.h | 26 ++-- .../uic/baseline/saveformastemplate.ui.h | 6 +- tests/auto/tools/uic/baseline/settings.ui.h | 14 +-- .../tools/uic/baseline/signalslotdialog.ui.h | 22 ++-- tests/auto/tools/uic/baseline/sslclient.ui.h | 22 ++-- tests/auto/tools/uic/baseline/sslerrors.ui.h | 10 +- tests/auto/tools/uic/baseline/statistics.ui.h | 26 ++-- .../tools/uic/baseline/stringlisteditor.ui.h | 22 ++-- .../tools/uic/baseline/stylesheeteditor.ui.h | 14 +-- .../tools/uic/baseline/tabbedbrowser.ui.h | 14 +-- .../tools/uic/baseline/tablewidgeteditor.ui.h | 52 ++++---- .../auto/tools/uic/baseline/tetrixwindow.ui.h | 16 +-- tests/auto/tools/uic/baseline/textfinder.ui.h | 6 +- .../auto/tools/uic/baseline/topicchooser.ui.h | 8 +- .../tools/uic/baseline/translatedialog.ui.h | 32 ++--- .../uic/baseline/translationsettings.ui.h | 8 +- .../tools/uic/baseline/treewidgeteditor.ui.h | 60 +++++----- .../tools/uic/baseline/trpreviewtool.ui.h | 26 ++-- tests/auto/tools/uic/baseline/validators.ui.h | 28 ++--- .../uic/baseline/wateringconfigdialog.ui.h | 46 +++---- 104 files changed, 998 insertions(+), 998 deletions(-) diff --git a/src/tools/uic/cpp/cppwriteinitialization.cpp b/src/tools/uic/cpp/cppwriteinitialization.cpp index 16fed64f5a..658cdd9567 100644 --- a/src/tools/uic/cpp/cppwriteinitialization.cpp +++ b/src/tools/uic/cpp/cppwriteinitialization.cpp @@ -2347,7 +2347,7 @@ QString WriteInitialization::trCall(const QString &str, const QString &commentHi if (idBasedTranslations || m_option.idBased) { result += QLatin1String("qtTrId("); } else { - result += QLatin1String("QApplication::translate(\"") + result += QLatin1String("QCoreApplication::translate(\"") + m_generatedClass + QLatin1String("\", "); } diff --git a/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Bottom.ui.h b/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Bottom.ui.h index 0da4e150ed..8b17acc1cd 100644 --- a/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Bottom.ui.h +++ b/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Bottom.ui.h @@ -41,7 +41,7 @@ public: void retranslateUi(QDialog *Dialog) { - Dialog->setWindowTitle(QApplication::translate("Dialog", "Dialog", nullptr)); + Dialog->setWindowTitle(QCoreApplication::translate("Dialog", "Dialog", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Right.ui.h b/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Right.ui.h index 5acbefd998..cdb12ec2b8 100644 --- a/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Right.ui.h +++ b/tests/auto/tools/uic/baseline/Dialog_with_Buttons_Right.ui.h @@ -41,7 +41,7 @@ public: void retranslateUi(QDialog *Dialog) { - Dialog->setWindowTitle(QApplication::translate("Dialog", "Dialog", nullptr)); + Dialog->setWindowTitle(QCoreApplication::translate("Dialog", "Dialog", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/Dialog_without_Buttons.ui.h b/tests/auto/tools/uic/baseline/Dialog_without_Buttons.ui.h index c9d803a090..abdeb5b823 100644 --- a/tests/auto/tools/uic/baseline/Dialog_without_Buttons.ui.h +++ b/tests/auto/tools/uic/baseline/Dialog_without_Buttons.ui.h @@ -32,7 +32,7 @@ public: void retranslateUi(QDialog *Dialog) { - Dialog->setWindowTitle(QApplication::translate("Dialog", "Dialog", nullptr)); + Dialog->setWindowTitle(QCoreApplication::translate("Dialog", "Dialog", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/Main_Window.ui.h b/tests/auto/tools/uic/baseline/Main_Window.ui.h index b0ab882a6f..b78a3df8af 100644 --- a/tests/auto/tools/uic/baseline/Main_Window.ui.h +++ b/tests/auto/tools/uic/baseline/Main_Window.ui.h @@ -47,7 +47,7 @@ public: void retranslateUi(QMainWindow *MainWindow) { - MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", nullptr)); + MainWindow->setWindowTitle(QCoreApplication::translate("MainWindow", "MainWindow", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/Widget.ui.h b/tests/auto/tools/uic/baseline/Widget.ui.h index bb62f52bb5..906f648533 100644 --- a/tests/auto/tools/uic/baseline/Widget.ui.h +++ b/tests/auto/tools/uic/baseline/Widget.ui.h @@ -57,13 +57,13 @@ public: void retranslateUi(QWidget *Form) { - Form->setWindowTitle(QApplication::translate("Form", "Form", nullptr)); - Alabel->setText(QApplication::translate("Form", "A label.\n" + Form->setWindowTitle(QCoreApplication::translate("Form", "Form", nullptr)); + Alabel->setText(QCoreApplication::translate("Form", "A label.\n" "One new line.\n" "Another new line.\n" "Last line.", nullptr)); - groupBox->setTitle(QApplication::translate("Form", "A Group Box", nullptr)); - pushButton->setText(QApplication::translate("Form", "PushButton", nullptr)); + groupBox->setTitle(QCoreApplication::translate("Form", "A Group Box", nullptr)); + pushButton->setText(QCoreApplication::translate("Form", "PushButton", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/addlinkdialog.ui.h b/tests/auto/tools/uic/baseline/addlinkdialog.ui.h index fced16ba64..2a0ef18fa7 100644 --- a/tests/auto/tools/uic/baseline/addlinkdialog.ui.h +++ b/tests/auto/tools/uic/baseline/addlinkdialog.ui.h @@ -97,9 +97,9 @@ public: void retranslateUi(QDialog *AddLinkDialog) { - AddLinkDialog->setWindowTitle(QApplication::translate("AddLinkDialog", "Insert Link", nullptr)); - label->setText(QApplication::translate("AddLinkDialog", "Title:", nullptr)); - label_2->setText(QApplication::translate("AddLinkDialog", "URL:", nullptr)); + AddLinkDialog->setWindowTitle(QCoreApplication::translate("AddLinkDialog", "Insert Link", nullptr)); + label->setText(QCoreApplication::translate("AddLinkDialog", "Title:", nullptr)); + label_2->setText(QCoreApplication::translate("AddLinkDialog", "URL:", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/addtorrentform.ui.h b/tests/auto/tools/uic/baseline/addtorrentform.ui.h index 5fd04eeb21..b357d708d5 100644 --- a/tests/auto/tools/uic/baseline/addtorrentform.ui.h +++ b/tests/auto/tools/uic/baseline/addtorrentform.ui.h @@ -209,23 +209,23 @@ public: void retranslateUi(QDialog *AddTorrentFile) { - AddTorrentFile->setWindowTitle(QApplication::translate("AddTorrentFile", "Add a torrent", nullptr)); - groupBox->setTitle(QApplication::translate("AddTorrentFile", "Select a torrent source", nullptr)); - label_4->setText(QApplication::translate("AddTorrentFile", "Destination:", nullptr)); - label_2->setText(QApplication::translate("AddTorrentFile", "Tracker URL:", nullptr)); - browseTorrents->setText(QApplication::translate("AddTorrentFile", "Browse", nullptr)); - label_5->setText(QApplication::translate("AddTorrentFile", "File(s):", nullptr)); - label_3->setText(QApplication::translate("AddTorrentFile", "Size:", nullptr)); - label_6->setText(QApplication::translate("AddTorrentFile", "Creator:", nullptr)); - announceUrl->setText(QApplication::translate("AddTorrentFile", "", nullptr)); - label->setText(QApplication::translate("AddTorrentFile", "Torrent file:", nullptr)); - browseDestination->setText(QApplication::translate("AddTorrentFile", "Browse", nullptr)); - label_7->setText(QApplication::translate("AddTorrentFile", "Comment:", nullptr)); - commentLabel->setText(QApplication::translate("AddTorrentFile", "", nullptr)); - creatorLabel->setText(QApplication::translate("AddTorrentFile", "", nullptr)); - sizeLabel->setText(QApplication::translate("AddTorrentFile", "0", nullptr)); - okButton->setText(QApplication::translate("AddTorrentFile", "&OK", nullptr)); - cancelButton->setText(QApplication::translate("AddTorrentFile", "&Cancel", nullptr)); + AddTorrentFile->setWindowTitle(QCoreApplication::translate("AddTorrentFile", "Add a torrent", nullptr)); + groupBox->setTitle(QCoreApplication::translate("AddTorrentFile", "Select a torrent source", nullptr)); + label_4->setText(QCoreApplication::translate("AddTorrentFile", "Destination:", nullptr)); + label_2->setText(QCoreApplication::translate("AddTorrentFile", "Tracker URL:", nullptr)); + browseTorrents->setText(QCoreApplication::translate("AddTorrentFile", "Browse", nullptr)); + label_5->setText(QCoreApplication::translate("AddTorrentFile", "File(s):", nullptr)); + label_3->setText(QCoreApplication::translate("AddTorrentFile", "Size:", nullptr)); + label_6->setText(QCoreApplication::translate("AddTorrentFile", "Creator:", nullptr)); + announceUrl->setText(QCoreApplication::translate("AddTorrentFile", "", nullptr)); + label->setText(QCoreApplication::translate("AddTorrentFile", "Torrent file:", nullptr)); + browseDestination->setText(QCoreApplication::translate("AddTorrentFile", "Browse", nullptr)); + label_7->setText(QCoreApplication::translate("AddTorrentFile", "Comment:", nullptr)); + commentLabel->setText(QCoreApplication::translate("AddTorrentFile", "", nullptr)); + creatorLabel->setText(QCoreApplication::translate("AddTorrentFile", "", nullptr)); + sizeLabel->setText(QCoreApplication::translate("AddTorrentFile", "0", nullptr)); + okButton->setText(QCoreApplication::translate("AddTorrentFile", "&OK", nullptr)); + cancelButton->setText(QCoreApplication::translate("AddTorrentFile", "&Cancel", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/authenticationdialog.ui.h b/tests/auto/tools/uic/baseline/authenticationdialog.ui.h index 888e381695..f8378b9a4e 100644 --- a/tests/auto/tools/uic/baseline/authenticationdialog.ui.h +++ b/tests/auto/tools/uic/baseline/authenticationdialog.ui.h @@ -103,12 +103,12 @@ public: void retranslateUi(QDialog *Dialog) { - Dialog->setWindowTitle(QApplication::translate("Dialog", "Http authentication required", nullptr)); - label->setText(QApplication::translate("Dialog", "You need to supply a Username and a Password to access this site", nullptr)); - label_2->setText(QApplication::translate("Dialog", "Username:", nullptr)); - label_3->setText(QApplication::translate("Dialog", "Password:", nullptr)); - label_4->setText(QApplication::translate("Dialog", "Site:", nullptr)); - siteDescription->setText(QApplication::translate("Dialog", "%1 at %2", nullptr)); + Dialog->setWindowTitle(QCoreApplication::translate("Dialog", "Http authentication required", nullptr)); + label->setText(QCoreApplication::translate("Dialog", "You need to supply a Username and a Password to access this site", nullptr)); + label_2->setText(QCoreApplication::translate("Dialog", "Username:", nullptr)); + label_3->setText(QCoreApplication::translate("Dialog", "Password:", nullptr)); + label_4->setText(QCoreApplication::translate("Dialog", "Site:", nullptr)); + siteDescription->setText(QCoreApplication::translate("Dialog", "%1 at %2", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/backside.ui.h b/tests/auto/tools/uic/baseline/backside.ui.h index b3e04dc810..7f2b3662f3 100644 --- a/tests/auto/tools/uic/baseline/backside.ui.h +++ b/tests/auto/tools/uic/baseline/backside.ui.h @@ -144,40 +144,40 @@ public: void retranslateUi(QWidget *BackSide) { - BackSide->setWindowTitle(QApplication::translate("BackSide", "BackSide", nullptr)); - groupBox->setTitle(QApplication::translate("BackSide", "Settings", nullptr)); - label->setText(QApplication::translate("BackSide", "Title:", nullptr)); - hostName->setText(QApplication::translate("BackSide", "Pad Navigator Example", nullptr)); - label_2->setText(QApplication::translate("BackSide", "Modified:", nullptr)); - label_3->setText(QApplication::translate("BackSide", "Extent", nullptr)); - groupBox_2->setTitle(QApplication::translate("BackSide", "Other input", nullptr)); + BackSide->setWindowTitle(QCoreApplication::translate("BackSide", "BackSide", nullptr)); + groupBox->setTitle(QCoreApplication::translate("BackSide", "Settings", nullptr)); + label->setText(QCoreApplication::translate("BackSide", "Title:", nullptr)); + hostName->setText(QCoreApplication::translate("BackSide", "Pad Navigator Example", nullptr)); + label_2->setText(QCoreApplication::translate("BackSide", "Modified:", nullptr)); + label_3->setText(QCoreApplication::translate("BackSide", "Extent", nullptr)); + groupBox_2->setTitle(QCoreApplication::translate("BackSide", "Other input", nullptr)); QTreeWidgetItem *___qtreewidgetitem = treeWidget->headerItem(); - ___qtreewidgetitem->setText(0, QApplication::translate("BackSide", "Widgets On Graphics View", nullptr)); + ___qtreewidgetitem->setText(0, QCoreApplication::translate("BackSide", "Widgets On Graphics View", nullptr)); const bool __sortingEnabled = treeWidget->isSortingEnabled(); treeWidget->setSortingEnabled(false); QTreeWidgetItem *___qtreewidgetitem1 = treeWidget->topLevelItem(0); - ___qtreewidgetitem1->setText(0, QApplication::translate("BackSide", "QGraphicsProxyWidget", nullptr)); + ___qtreewidgetitem1->setText(0, QCoreApplication::translate("BackSide", "QGraphicsProxyWidget", nullptr)); QTreeWidgetItem *___qtreewidgetitem2 = ___qtreewidgetitem1->child(0); - ___qtreewidgetitem2->setText(0, QApplication::translate("BackSide", "QGraphicsWidget", nullptr)); + ___qtreewidgetitem2->setText(0, QCoreApplication::translate("BackSide", "QGraphicsWidget", nullptr)); QTreeWidgetItem *___qtreewidgetitem3 = ___qtreewidgetitem2->child(0); - ___qtreewidgetitem3->setText(0, QApplication::translate("BackSide", "QObject", nullptr)); + ___qtreewidgetitem3->setText(0, QCoreApplication::translate("BackSide", "QObject", nullptr)); QTreeWidgetItem *___qtreewidgetitem4 = ___qtreewidgetitem2->child(1); - ___qtreewidgetitem4->setText(0, QApplication::translate("BackSide", "QGraphicsItem", nullptr)); + ___qtreewidgetitem4->setText(0, QCoreApplication::translate("BackSide", "QGraphicsItem", nullptr)); QTreeWidgetItem *___qtreewidgetitem5 = ___qtreewidgetitem2->child(2); - ___qtreewidgetitem5->setText(0, QApplication::translate("BackSide", "QGraphicsLayoutItem", nullptr)); + ___qtreewidgetitem5->setText(0, QCoreApplication::translate("BackSide", "QGraphicsLayoutItem", nullptr)); QTreeWidgetItem *___qtreewidgetitem6 = treeWidget->topLevelItem(1); - ___qtreewidgetitem6->setText(0, QApplication::translate("BackSide", "QGraphicsGridLayout", nullptr)); + ___qtreewidgetitem6->setText(0, QCoreApplication::translate("BackSide", "QGraphicsGridLayout", nullptr)); QTreeWidgetItem *___qtreewidgetitem7 = ___qtreewidgetitem6->child(0); - ___qtreewidgetitem7->setText(0, QApplication::translate("BackSide", "QGraphicsLayout", nullptr)); + ___qtreewidgetitem7->setText(0, QCoreApplication::translate("BackSide", "QGraphicsLayout", nullptr)); QTreeWidgetItem *___qtreewidgetitem8 = ___qtreewidgetitem7->child(0); - ___qtreewidgetitem8->setText(0, QApplication::translate("BackSide", "QGraphicsLayoutItem", nullptr)); + ___qtreewidgetitem8->setText(0, QCoreApplication::translate("BackSide", "QGraphicsLayoutItem", nullptr)); QTreeWidgetItem *___qtreewidgetitem9 = treeWidget->topLevelItem(2); - ___qtreewidgetitem9->setText(0, QApplication::translate("BackSide", "QGraphicsLinearLayout", nullptr)); + ___qtreewidgetitem9->setText(0, QCoreApplication::translate("BackSide", "QGraphicsLinearLayout", nullptr)); QTreeWidgetItem *___qtreewidgetitem10 = ___qtreewidgetitem9->child(0); - ___qtreewidgetitem10->setText(0, QApplication::translate("BackSide", "QGraphicsLayout", nullptr)); + ___qtreewidgetitem10->setText(0, QCoreApplication::translate("BackSide", "QGraphicsLayout", nullptr)); QTreeWidgetItem *___qtreewidgetitem11 = ___qtreewidgetitem10->child(0); - ___qtreewidgetitem11->setText(0, QApplication::translate("BackSide", "QGraphicsLayoutItem", nullptr)); + ___qtreewidgetitem11->setText(0, QCoreApplication::translate("BackSide", "QGraphicsLayoutItem", nullptr)); treeWidget->setSortingEnabled(__sortingEnabled); } // retranslateUi diff --git a/tests/auto/tools/uic/baseline/batchtranslation.ui.h b/tests/auto/tools/uic/baseline/batchtranslation.ui.h index fef162ead8..1ca39ce171 100644 --- a/tests/auto/tools/uic/baseline/batchtranslation.ui.h +++ b/tests/auto/tools/uic/baseline/batchtranslation.ui.h @@ -213,16 +213,16 @@ public: void retranslateUi(QDialog *databaseTranslationDialog) { - databaseTranslationDialog->setWindowTitle(QApplication::translate("databaseTranslationDialog", "Qt Linguist - Batch Translation", nullptr)); - groupBox->setTitle(QApplication::translate("databaseTranslationDialog", "Options", nullptr)); - ckOnlyUntranslated->setText(QApplication::translate("databaseTranslationDialog", "Only translate entries with no translation", nullptr)); - ckMarkFinished->setText(QApplication::translate("databaseTranslationDialog", "Set translated entries to finished", nullptr)); - groupBox_2->setTitle(QApplication::translate("databaseTranslationDialog", "Phrase book preference", nullptr)); - moveUpButton->setText(QApplication::translate("databaseTranslationDialog", "Move up", nullptr)); - moveDownButton->setText(QApplication::translate("databaseTranslationDialog", "Move down", nullptr)); - label->setText(QApplication::translate("databaseTranslationDialog", "The batch translator will search through the selected phrasebooks in the order given above.", nullptr)); - runButton->setText(QApplication::translate("databaseTranslationDialog", "&Run", nullptr)); - cancelButton->setText(QApplication::translate("databaseTranslationDialog", "&Cancel", nullptr)); + databaseTranslationDialog->setWindowTitle(QCoreApplication::translate("databaseTranslationDialog", "Qt Linguist - Batch Translation", nullptr)); + groupBox->setTitle(QCoreApplication::translate("databaseTranslationDialog", "Options", nullptr)); + ckOnlyUntranslated->setText(QCoreApplication::translate("databaseTranslationDialog", "Only translate entries with no translation", nullptr)); + ckMarkFinished->setText(QCoreApplication::translate("databaseTranslationDialog", "Set translated entries to finished", nullptr)); + groupBox_2->setTitle(QCoreApplication::translate("databaseTranslationDialog", "Phrase book preference", nullptr)); + moveUpButton->setText(QCoreApplication::translate("databaseTranslationDialog", "Move up", nullptr)); + moveDownButton->setText(QCoreApplication::translate("databaseTranslationDialog", "Move down", nullptr)); + label->setText(QCoreApplication::translate("databaseTranslationDialog", "The batch translator will search through the selected phrasebooks in the order given above.", nullptr)); + runButton->setText(QCoreApplication::translate("databaseTranslationDialog", "&Run", nullptr)); + cancelButton->setText(QCoreApplication::translate("databaseTranslationDialog", "&Cancel", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/bookmarkdialog.ui.h b/tests/auto/tools/uic/baseline/bookmarkdialog.ui.h index 0e2f10500b..11caa3f130 100644 --- a/tests/auto/tools/uic/baseline/bookmarkdialog.ui.h +++ b/tests/auto/tools/uic/baseline/bookmarkdialog.ui.h @@ -148,13 +148,13 @@ public: void retranslateUi(QDialog *BookmarkDialog) { - BookmarkDialog->setWindowTitle(QApplication::translate("BookmarkDialog", "Add Bookmark", nullptr)); - label->setText(QApplication::translate("BookmarkDialog", "Bookmark:", nullptr)); - label_2->setText(QApplication::translate("BookmarkDialog", "Add in Folder:", nullptr)); - toolButton->setText(QApplication::translate("BookmarkDialog", "+", nullptr)); + BookmarkDialog->setWindowTitle(QCoreApplication::translate("BookmarkDialog", "Add Bookmark", nullptr)); + label->setText(QCoreApplication::translate("BookmarkDialog", "Bookmark:", nullptr)); + label_2->setText(QCoreApplication::translate("BookmarkDialog", "Add in Folder:", nullptr)); + toolButton->setText(QCoreApplication::translate("BookmarkDialog", "+", nullptr)); QTreeWidgetItem *___qtreewidgetitem = bookmarkWidget->headerItem(); - ___qtreewidgetitem->setText(0, QApplication::translate("BookmarkDialog", "1", nullptr)); - newFolderButton->setText(QApplication::translate("BookmarkDialog", "New Folder", nullptr)); + ___qtreewidgetitem->setText(0, QCoreApplication::translate("BookmarkDialog", "1", nullptr)); + newFolderButton->setText(QCoreApplication::translate("BookmarkDialog", "New Folder", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/bookwindow.ui.h b/tests/auto/tools/uic/baseline/bookwindow.ui.h index b9af619991..fbdcb17bd2 100644 --- a/tests/auto/tools/uic/baseline/bookwindow.ui.h +++ b/tests/auto/tools/uic/baseline/bookwindow.ui.h @@ -157,15 +157,15 @@ public: void retranslateUi(QMainWindow *BookWindow) { - BookWindow->setWindowTitle(QApplication::translate("BookWindow", "Books", nullptr)); - groupBox->setTitle(QApplication::translate("BookWindow", "Books", nullptr)); - groupBox_2->setTitle(QApplication::translate("BookWindow", "Details", nullptr)); - label_5->setText(QApplication::translate("BookWindow", "Title:", nullptr)); - label_2_2_2_2->setText(QApplication::translate("BookWindow", "Author: ", nullptr)); - label_3->setText(QApplication::translate("BookWindow", "Genre:", nullptr)); - label_4->setText(QApplication::translate("BookWindow", "Year:", nullptr)); + BookWindow->setWindowTitle(QCoreApplication::translate("BookWindow", "Books", nullptr)); + groupBox->setTitle(QCoreApplication::translate("BookWindow", "Books", nullptr)); + groupBox_2->setTitle(QCoreApplication::translate("BookWindow", "Details", nullptr)); + label_5->setText(QCoreApplication::translate("BookWindow", "Title:", nullptr)); + label_2_2_2_2->setText(QCoreApplication::translate("BookWindow", "Author: ", nullptr)); + label_3->setText(QCoreApplication::translate("BookWindow", "Genre:", nullptr)); + label_4->setText(QCoreApplication::translate("BookWindow", "Year:", nullptr)); yearEdit->setPrefix(QString()); - label->setText(QApplication::translate("BookWindow", "Rating:", nullptr)); + label->setText(QCoreApplication::translate("BookWindow", "Rating:", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/browserwidget.ui.h b/tests/auto/tools/uic/baseline/browserwidget.ui.h index aab629f85b..09c70ee3da 100644 --- a/tests/auto/tools/uic/baseline/browserwidget.ui.h +++ b/tests/auto/tools/uic/baseline/browserwidget.ui.h @@ -155,18 +155,18 @@ public: void retranslateUi(QWidget *Browser) { - Browser->setWindowTitle(QApplication::translate("Browser", "Qt SQL Browser", nullptr)); - insertRowAction->setText(QApplication::translate("Browser", "&Insert Row", nullptr)); + Browser->setWindowTitle(QCoreApplication::translate("Browser", "Qt SQL Browser", nullptr)); + insertRowAction->setText(QCoreApplication::translate("Browser", "&Insert Row", nullptr)); #if QT_CONFIG(statustip) - insertRowAction->setStatusTip(QApplication::translate("Browser", "Inserts a new Row", nullptr)); + insertRowAction->setStatusTip(QCoreApplication::translate("Browser", "Inserts a new Row", nullptr)); #endif // QT_CONFIG(statustip) - deleteRowAction->setText(QApplication::translate("Browser", "&Delete Row", nullptr)); + deleteRowAction->setText(QCoreApplication::translate("Browser", "&Delete Row", nullptr)); #if QT_CONFIG(statustip) - deleteRowAction->setStatusTip(QApplication::translate("Browser", "Deletes the current Row", nullptr)); + deleteRowAction->setStatusTip(QCoreApplication::translate("Browser", "Deletes the current Row", nullptr)); #endif // QT_CONFIG(statustip) - groupBox->setTitle(QApplication::translate("Browser", "SQL Query", nullptr)); - clearButton->setText(QApplication::translate("Browser", "&Clear", nullptr)); - submitButton->setText(QApplication::translate("Browser", "&Submit", nullptr)); + groupBox->setTitle(QCoreApplication::translate("Browser", "SQL Query", nullptr)); + clearButton->setText(QCoreApplication::translate("Browser", "&Clear", nullptr)); + submitButton->setText(QCoreApplication::translate("Browser", "&Submit", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/bug18156QTreeWidget.ui.h b/tests/auto/tools/uic/baseline/bug18156QTreeWidget.ui.h index 1d090bcd86..4e7186041e 100644 --- a/tests/auto/tools/uic/baseline/bug18156QTreeWidget.ui.h +++ b/tests/auto/tools/uic/baseline/bug18156QTreeWidget.ui.h @@ -57,9 +57,9 @@ public: void retranslateUi(QDialog *Dialog) { - Dialog->setWindowTitle(QApplication::translate("Dialog", "Dialog", nullptr)); + Dialog->setWindowTitle(QCoreApplication::translate("Dialog", "Dialog", nullptr)); QTreeWidgetItem *___qtreewidgetitem = treeWidget->headerItem(); - ___qtreewidgetitem->setText(1, QApplication::translate("Dialog", "4", nullptr)); + ___qtreewidgetitem->setText(1, QCoreApplication::translate("Dialog", "4", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/buttongroup.ui.h b/tests/auto/tools/uic/baseline/buttongroup.ui.h index 87814dcba1..f48db1d593 100644 --- a/tests/auto/tools/uic/baseline/buttongroup.ui.h +++ b/tests/auto/tools/uic/baseline/buttongroup.ui.h @@ -195,14 +195,14 @@ public: void retranslateUi(QWidget *Form) { - Form->setWindowTitle(QApplication::translate("Form", "Easing curves", nullptr)); - groupBox_2->setTitle(QApplication::translate("Form", "Path type", nullptr)); - lineRadio->setText(QApplication::translate("Form", "Line", nullptr)); - circleRadio->setText(QApplication::translate("Form", "Circle", nullptr)); - groupBox->setTitle(QApplication::translate("Form", "Properties", nullptr)); - label->setText(QApplication::translate("Form", "Period", nullptr)); - label_3->setText(QApplication::translate("Form", "Overshoot", nullptr)); - label_2->setText(QApplication::translate("Form", "Amplitude", nullptr)); + Form->setWindowTitle(QCoreApplication::translate("Form", "Easing curves", nullptr)); + groupBox_2->setTitle(QCoreApplication::translate("Form", "Path type", nullptr)); + lineRadio->setText(QCoreApplication::translate("Form", "Line", nullptr)); + circleRadio->setText(QCoreApplication::translate("Form", "Circle", nullptr)); + groupBox->setTitle(QCoreApplication::translate("Form", "Properties", nullptr)); + label->setText(QCoreApplication::translate("Form", "Period", nullptr)); + label_3->setText(QCoreApplication::translate("Form", "Overshoot", nullptr)); + label_2->setText(QCoreApplication::translate("Form", "Amplitude", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/calculator.ui.h b/tests/auto/tools/uic/baseline/calculator.ui.h index 0a374ecf01..bfe272f8ea 100644 --- a/tests/auto/tools/uic/baseline/calculator.ui.h +++ b/tests/auto/tools/uic/baseline/calculator.ui.h @@ -156,34 +156,34 @@ public: void retranslateUi(QWidget *Calculator) { - Calculator->setWindowTitle(QApplication::translate("Calculator", "Calculator", nullptr)); - backspaceButton->setText(QApplication::translate("Calculator", "Backspace", nullptr)); - clearButton->setText(QApplication::translate("Calculator", "Clear", nullptr)); - clearAllButton->setText(QApplication::translate("Calculator", "Clear All", nullptr)); - clearMemoryButton->setText(QApplication::translate("Calculator", "MC", nullptr)); - readMemoryButton->setText(QApplication::translate("Calculator", "MR", nullptr)); - setMemoryButton->setText(QApplication::translate("Calculator", "MS", nullptr)); - addToMemoryButton->setText(QApplication::translate("Calculator", "M+", nullptr)); - sevenButton->setText(QApplication::translate("Calculator", "7", nullptr)); - eightButton->setText(QApplication::translate("Calculator", "8", nullptr)); - nineButton->setText(QApplication::translate("Calculator", "9", nullptr)); - fourButton->setText(QApplication::translate("Calculator", "4", nullptr)); - fiveButton->setText(QApplication::translate("Calculator", "5", nullptr)); - sixButton->setText(QApplication::translate("Calculator", "6", nullptr)); - oneButton->setText(QApplication::translate("Calculator", "1", nullptr)); - twoButton->setText(QApplication::translate("Calculator", "2", nullptr)); - threeButton->setText(QApplication::translate("Calculator", "3", nullptr)); - zeroButton->setText(QApplication::translate("Calculator", "0", nullptr)); - pointButton->setText(QApplication::translate("Calculator", ".", nullptr)); - changeSignButton->setText(QApplication::translate("Calculator", "+-", nullptr)); - plusButton->setText(QApplication::translate("Calculator", "+", nullptr)); - divisionButton->setText(QApplication::translate("Calculator", "/", nullptr)); - timesButton->setText(QApplication::translate("Calculator", "*", nullptr)); - minusButton->setText(QApplication::translate("Calculator", "-", nullptr)); - squareRootButton->setText(QApplication::translate("Calculator", "Sqrt", nullptr)); - powerButton->setText(QApplication::translate("Calculator", "x^2", nullptr)); - reciprocalButton->setText(QApplication::translate("Calculator", "1/x", nullptr)); - equalButton->setText(QApplication::translate("Calculator", "=", nullptr)); + Calculator->setWindowTitle(QCoreApplication::translate("Calculator", "Calculator", nullptr)); + backspaceButton->setText(QCoreApplication::translate("Calculator", "Backspace", nullptr)); + clearButton->setText(QCoreApplication::translate("Calculator", "Clear", nullptr)); + clearAllButton->setText(QCoreApplication::translate("Calculator", "Clear All", nullptr)); + clearMemoryButton->setText(QCoreApplication::translate("Calculator", "MC", nullptr)); + readMemoryButton->setText(QCoreApplication::translate("Calculator", "MR", nullptr)); + setMemoryButton->setText(QCoreApplication::translate("Calculator", "MS", nullptr)); + addToMemoryButton->setText(QCoreApplication::translate("Calculator", "M+", nullptr)); + sevenButton->setText(QCoreApplication::translate("Calculator", "7", nullptr)); + eightButton->setText(QCoreApplication::translate("Calculator", "8", nullptr)); + nineButton->setText(QCoreApplication::translate("Calculator", "9", nullptr)); + fourButton->setText(QCoreApplication::translate("Calculator", "4", nullptr)); + fiveButton->setText(QCoreApplication::translate("Calculator", "5", nullptr)); + sixButton->setText(QCoreApplication::translate("Calculator", "6", nullptr)); + oneButton->setText(QCoreApplication::translate("Calculator", "1", nullptr)); + twoButton->setText(QCoreApplication::translate("Calculator", "2", nullptr)); + threeButton->setText(QCoreApplication::translate("Calculator", "3", nullptr)); + zeroButton->setText(QCoreApplication::translate("Calculator", "0", nullptr)); + pointButton->setText(QCoreApplication::translate("Calculator", ".", nullptr)); + changeSignButton->setText(QCoreApplication::translate("Calculator", "+-", nullptr)); + plusButton->setText(QCoreApplication::translate("Calculator", "+", nullptr)); + divisionButton->setText(QCoreApplication::translate("Calculator", "/", nullptr)); + timesButton->setText(QCoreApplication::translate("Calculator", "*", nullptr)); + minusButton->setText(QCoreApplication::translate("Calculator", "-", nullptr)); + squareRootButton->setText(QCoreApplication::translate("Calculator", "Sqrt", nullptr)); + powerButton->setText(QCoreApplication::translate("Calculator", "x^2", nullptr)); + reciprocalButton->setText(QCoreApplication::translate("Calculator", "1/x", nullptr)); + equalButton->setText(QCoreApplication::translate("Calculator", "=", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/calculatorform.ui.h b/tests/auto/tools/uic/baseline/calculatorform.ui.h index 24027fd3fb..bb30479d1f 100644 --- a/tests/auto/tools/uic/baseline/calculatorform.ui.h +++ b/tests/auto/tools/uic/baseline/calculatorform.ui.h @@ -170,13 +170,13 @@ public: void retranslateUi(QWidget *CalculatorForm) { - CalculatorForm->setWindowTitle(QApplication::translate("CalculatorForm", "Calculator Builder", nullptr)); - label->setText(QApplication::translate("CalculatorForm", "Input 1", nullptr)); - label_3->setText(QApplication::translate("CalculatorForm", "+", nullptr)); - label_2->setText(QApplication::translate("CalculatorForm", "Input 2", nullptr)); - label_3_2->setText(QApplication::translate("CalculatorForm", "=", nullptr)); - label_2_2_2->setText(QApplication::translate("CalculatorForm", "Output", nullptr)); - outputWidget->setText(QApplication::translate("CalculatorForm", "0", nullptr)); + CalculatorForm->setWindowTitle(QCoreApplication::translate("CalculatorForm", "Calculator Builder", nullptr)); + label->setText(QCoreApplication::translate("CalculatorForm", "Input 1", nullptr)); + label_3->setText(QCoreApplication::translate("CalculatorForm", "+", nullptr)); + label_2->setText(QCoreApplication::translate("CalculatorForm", "Input 2", nullptr)); + label_3_2->setText(QCoreApplication::translate("CalculatorForm", "=", nullptr)); + label_2_2_2->setText(QCoreApplication::translate("CalculatorForm", "Output", nullptr)); + outputWidget->setText(QCoreApplication::translate("CalculatorForm", "0", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/certificateinfo.ui.h b/tests/auto/tools/uic/baseline/certificateinfo.ui.h index 75e4639d08..4a70f86c3b 100644 --- a/tests/auto/tools/uic/baseline/certificateinfo.ui.h +++ b/tests/auto/tools/uic/baseline/certificateinfo.ui.h @@ -90,9 +90,9 @@ public: void retranslateUi(QDialog *CertificateInfo) { - CertificateInfo->setWindowTitle(QApplication::translate("CertificateInfo", "Display Certificate Information", nullptr)); - groupBox->setTitle(QApplication::translate("CertificateInfo", "Certification Path", nullptr)); - groupBox_2->setTitle(QApplication::translate("CertificateInfo", "Certificate Information", nullptr)); + CertificateInfo->setWindowTitle(QCoreApplication::translate("CertificateInfo", "Display Certificate Information", nullptr)); + groupBox->setTitle(QCoreApplication::translate("CertificateInfo", "Certification Path", nullptr)); + groupBox_2->setTitle(QCoreApplication::translate("CertificateInfo", "Certificate Information", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/chatdialog.ui.h b/tests/auto/tools/uic/baseline/chatdialog.ui.h index 8138a2cdd8..2a1ba2e84c 100644 --- a/tests/auto/tools/uic/baseline/chatdialog.ui.h +++ b/tests/auto/tools/uic/baseline/chatdialog.ui.h @@ -97,8 +97,8 @@ public: void retranslateUi(QDialog *ChatDialog) { - ChatDialog->setWindowTitle(QApplication::translate("ChatDialog", "Chat", nullptr)); - label->setText(QApplication::translate("ChatDialog", "Message:", nullptr)); + ChatDialog->setWindowTitle(QCoreApplication::translate("ChatDialog", "Chat", nullptr)); + label->setText(QCoreApplication::translate("ChatDialog", "Message:", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/chatmainwindow.ui.h b/tests/auto/tools/uic/baseline/chatmainwindow.ui.h index a3cb6203a9..27e468cfa6 100644 --- a/tests/auto/tools/uic/baseline/chatmainwindow.ui.h +++ b/tests/auto/tools/uic/baseline/chatmainwindow.ui.h @@ -147,29 +147,29 @@ public: void retranslateUi(QMainWindow *ChatMainWindow) { - ChatMainWindow->setWindowTitle(QApplication::translate("ChatMainWindow", "Qt D-Bus Chat", nullptr)); - actionQuit->setText(QApplication::translate("ChatMainWindow", "Quit", nullptr)); + ChatMainWindow->setWindowTitle(QCoreApplication::translate("ChatMainWindow", "Qt D-Bus Chat", nullptr)); + actionQuit->setText(QCoreApplication::translate("ChatMainWindow", "Quit", nullptr)); #if QT_CONFIG(shortcut) - actionQuit->setShortcut(QApplication::translate("ChatMainWindow", "Ctrl+Q", nullptr)); + actionQuit->setShortcut(QCoreApplication::translate("ChatMainWindow", "Ctrl+Q", nullptr)); #endif // QT_CONFIG(shortcut) - actionAboutQt->setText(QApplication::translate("ChatMainWindow", "About Qt...", nullptr)); - actionChangeNickname->setText(QApplication::translate("ChatMainWindow", "Change nickname...", nullptr)); + actionAboutQt->setText(QCoreApplication::translate("ChatMainWindow", "About Qt...", nullptr)); + actionChangeNickname->setText(QCoreApplication::translate("ChatMainWindow", "Change nickname...", nullptr)); #if QT_CONFIG(shortcut) - actionChangeNickname->setShortcut(QApplication::translate("ChatMainWindow", "Ctrl+N", nullptr)); + actionChangeNickname->setShortcut(QCoreApplication::translate("ChatMainWindow", "Ctrl+N", nullptr)); #endif // QT_CONFIG(shortcut) #if QT_CONFIG(tooltip) - chatHistory->setToolTip(QApplication::translate("ChatMainWindow", "Messages sent and received from other users", nullptr)); + chatHistory->setToolTip(QCoreApplication::translate("ChatMainWindow", "Messages sent and received from other users", nullptr)); #endif // QT_CONFIG(tooltip) - label->setText(QApplication::translate("ChatMainWindow", "Message:", nullptr)); + label->setText(QCoreApplication::translate("ChatMainWindow", "Message:", nullptr)); #if QT_CONFIG(tooltip) - sendButton->setToolTip(QApplication::translate("ChatMainWindow", "Sends a message to other people", nullptr)); + sendButton->setToolTip(QCoreApplication::translate("ChatMainWindow", "Sends a message to other people", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(whatsthis) sendButton->setWhatsThis(QString()); #endif // QT_CONFIG(whatsthis) - sendButton->setText(QApplication::translate("ChatMainWindow", "Send", nullptr)); - menuQuit->setTitle(QApplication::translate("ChatMainWindow", "Help", nullptr)); - menuFile->setTitle(QApplication::translate("ChatMainWindow", "File", nullptr)); + sendButton->setText(QCoreApplication::translate("ChatMainWindow", "Send", nullptr)); + menuQuit->setTitle(QCoreApplication::translate("ChatMainWindow", "Help", nullptr)); + menuFile->setTitle(QCoreApplication::translate("ChatMainWindow", "File", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/chatsetnickname.ui.h b/tests/auto/tools/uic/baseline/chatsetnickname.ui.h index c735f4b889..cc11acb6da 100644 --- a/tests/auto/tools/uic/baseline/chatsetnickname.ui.h +++ b/tests/auto/tools/uic/baseline/chatsetnickname.ui.h @@ -112,10 +112,10 @@ public: void retranslateUi(QDialog *NicknameDialog) { - NicknameDialog->setWindowTitle(QApplication::translate("NicknameDialog", "Set nickname", nullptr)); - label->setText(QApplication::translate("NicknameDialog", "New nickname:", nullptr)); - okButton->setText(QApplication::translate("NicknameDialog", "OK", nullptr)); - cancelButton->setText(QApplication::translate("NicknameDialog", "Cancel", nullptr)); + NicknameDialog->setWindowTitle(QCoreApplication::translate("NicknameDialog", "Set nickname", nullptr)); + label->setText(QCoreApplication::translate("NicknameDialog", "New nickname:", nullptr)); + okButton->setText(QCoreApplication::translate("NicknameDialog", "OK", nullptr)); + cancelButton->setText(QCoreApplication::translate("NicknameDialog", "Cancel", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/config.ui.h b/tests/auto/tools/uic/baseline/config.ui.h index 71ac8535c7..153718aca1 100644 --- a/tests/auto/tools/uic/baseline/config.ui.h +++ b/tests/auto/tools/uic/baseline/config.ui.h @@ -706,44 +706,44 @@ public: void retranslateUi(QDialog *Config) { - Config->setWindowTitle(QApplication::translate("Config", "Configure", nullptr)); - ButtonGroup1->setTitle(QApplication::translate("Config", "Size", nullptr)); - size_176_220->setText(QApplication::translate("Config", "176x220 \"SmartPhone\"", nullptr)); - size_240_320->setText(QApplication::translate("Config", "240x320 \"PDA\"", nullptr)); - size_320_240->setText(QApplication::translate("Config", "320x240 \"TV\" / \"QVGA\"", nullptr)); - size_640_480->setText(QApplication::translate("Config", "640x480 \"VGA\"", nullptr)); - size_800_600->setText(QApplication::translate("Config", "800x600", nullptr)); - size_1024_768->setText(QApplication::translate("Config", "1024x768", nullptr)); - size_custom->setText(QApplication::translate("Config", "Custom", nullptr)); - ButtonGroup2->setTitle(QApplication::translate("Config", "Depth", nullptr)); - depth_1->setText(QApplication::translate("Config", "1 bit monochrome", nullptr)); - depth_4gray->setText(QApplication::translate("Config", "4 bit grayscale", nullptr)); - depth_8->setText(QApplication::translate("Config", "8 bit", nullptr)); - depth_12->setText(QApplication::translate("Config", "12 (16) bit", nullptr)); - depth_15->setText(QApplication::translate("Config", "15 bit", nullptr)); - depth_16->setText(QApplication::translate("Config", "16 bit", nullptr)); - depth_18->setText(QApplication::translate("Config", "18 bit", nullptr)); - depth_24->setText(QApplication::translate("Config", "24 bit", nullptr)); - depth_32->setText(QApplication::translate("Config", "32 bit", nullptr)); - depth_32_argb->setText(QApplication::translate("Config", "32 bit ARGB", nullptr)); - TextLabel1_3->setText(QApplication::translate("Config", "Skin", nullptr)); - skin->setItemText(0, QApplication::translate("Config", "None", nullptr)); + Config->setWindowTitle(QCoreApplication::translate("Config", "Configure", nullptr)); + ButtonGroup1->setTitle(QCoreApplication::translate("Config", "Size", nullptr)); + size_176_220->setText(QCoreApplication::translate("Config", "176x220 \"SmartPhone\"", nullptr)); + size_240_320->setText(QCoreApplication::translate("Config", "240x320 \"PDA\"", nullptr)); + size_320_240->setText(QCoreApplication::translate("Config", "320x240 \"TV\" / \"QVGA\"", nullptr)); + size_640_480->setText(QCoreApplication::translate("Config", "640x480 \"VGA\"", nullptr)); + size_800_600->setText(QCoreApplication::translate("Config", "800x600", nullptr)); + size_1024_768->setText(QCoreApplication::translate("Config", "1024x768", nullptr)); + size_custom->setText(QCoreApplication::translate("Config", "Custom", nullptr)); + ButtonGroup2->setTitle(QCoreApplication::translate("Config", "Depth", nullptr)); + depth_1->setText(QCoreApplication::translate("Config", "1 bit monochrome", nullptr)); + depth_4gray->setText(QCoreApplication::translate("Config", "4 bit grayscale", nullptr)); + depth_8->setText(QCoreApplication::translate("Config", "8 bit", nullptr)); + depth_12->setText(QCoreApplication::translate("Config", "12 (16) bit", nullptr)); + depth_15->setText(QCoreApplication::translate("Config", "15 bit", nullptr)); + depth_16->setText(QCoreApplication::translate("Config", "16 bit", nullptr)); + depth_18->setText(QCoreApplication::translate("Config", "18 bit", nullptr)); + depth_24->setText(QCoreApplication::translate("Config", "24 bit", nullptr)); + depth_32->setText(QCoreApplication::translate("Config", "32 bit", nullptr)); + depth_32_argb->setText(QCoreApplication::translate("Config", "32 bit ARGB", nullptr)); + TextLabel1_3->setText(QCoreApplication::translate("Config", "Skin", nullptr)); + skin->setItemText(0, QCoreApplication::translate("Config", "None", nullptr)); - touchScreen->setText(QApplication::translate("Config", "Emulate touch screen (no mouse move)", nullptr)); - lcdScreen->setText(QApplication::translate("Config", "Emulate LCD screen (Only with fixed zoom of 3.0 times magnification)", nullptr)); - TextLabel1->setText(QApplication::translate("Config", "

    Note that any applications using the virtual framebuffer will be terminated if you change the Size or Depth above. You may freely modify the Gamma below.", nullptr)); - GroupBox1->setTitle(QApplication::translate("Config", "Gamma", nullptr)); - TextLabel3->setText(QApplication::translate("Config", "Blue", nullptr)); - blabel->setText(QApplication::translate("Config", "1.0", nullptr)); - TextLabel2->setText(QApplication::translate("Config", "Green", nullptr)); - glabel->setText(QApplication::translate("Config", "1.0", nullptr)); - TextLabel7->setText(QApplication::translate("Config", "All", nullptr)); - TextLabel8->setText(QApplication::translate("Config", "1.0", nullptr)); - TextLabel1_2->setText(QApplication::translate("Config", "Red", nullptr)); - rlabel->setText(QApplication::translate("Config", "1.0", nullptr)); - PushButton3->setText(QApplication::translate("Config", "Set all to 1.0", nullptr)); - buttonOk->setText(QApplication::translate("Config", "&OK", nullptr)); - buttonCancel->setText(QApplication::translate("Config", "&Cancel", nullptr)); + touchScreen->setText(QCoreApplication::translate("Config", "Emulate touch screen (no mouse move)", nullptr)); + lcdScreen->setText(QCoreApplication::translate("Config", "Emulate LCD screen (Only with fixed zoom of 3.0 times magnification)", nullptr)); + TextLabel1->setText(QCoreApplication::translate("Config", "

    Note that any applications using the virtual framebuffer will be terminated if you change the Size or Depth above. You may freely modify the Gamma below.", nullptr)); + GroupBox1->setTitle(QCoreApplication::translate("Config", "Gamma", nullptr)); + TextLabel3->setText(QCoreApplication::translate("Config", "Blue", nullptr)); + blabel->setText(QCoreApplication::translate("Config", "1.0", nullptr)); + TextLabel2->setText(QCoreApplication::translate("Config", "Green", nullptr)); + glabel->setText(QCoreApplication::translate("Config", "1.0", nullptr)); + TextLabel7->setText(QCoreApplication::translate("Config", "All", nullptr)); + TextLabel8->setText(QCoreApplication::translate("Config", "1.0", nullptr)); + TextLabel1_2->setText(QCoreApplication::translate("Config", "Red", nullptr)); + rlabel->setText(QCoreApplication::translate("Config", "1.0", nullptr)); + PushButton3->setText(QCoreApplication::translate("Config", "Set all to 1.0", nullptr)); + buttonOk->setText(QCoreApplication::translate("Config", "&OK", nullptr)); + buttonCancel->setText(QCoreApplication::translate("Config", "&Cancel", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/connectdialog.ui.h b/tests/auto/tools/uic/baseline/connectdialog.ui.h index 55198d43f3..1e91b498f4 100644 --- a/tests/auto/tools/uic/baseline/connectdialog.ui.h +++ b/tests/auto/tools/uic/baseline/connectdialog.ui.h @@ -126,12 +126,12 @@ public: void retranslateUi(QDialog *ConnectDialog) { - ConnectDialog->setWindowTitle(QApplication::translate("ConnectDialog", "Configure Connection", nullptr)); - signalGroupBox->setTitle(QApplication::translate("ConnectDialog", "GroupBox", nullptr)); - editSignalsButton->setText(QApplication::translate("ConnectDialog", "Edit...", nullptr)); - slotGroupBox->setTitle(QApplication::translate("ConnectDialog", "GroupBox", nullptr)); - editSlotsButton->setText(QApplication::translate("ConnectDialog", "Edit...", nullptr)); - showAllCheckBox->setText(QApplication::translate("ConnectDialog", "Show signals and slots inherited from QWidget", nullptr)); + ConnectDialog->setWindowTitle(QCoreApplication::translate("ConnectDialog", "Configure Connection", nullptr)); + signalGroupBox->setTitle(QCoreApplication::translate("ConnectDialog", "GroupBox", nullptr)); + editSignalsButton->setText(QCoreApplication::translate("ConnectDialog", "Edit...", nullptr)); + slotGroupBox->setTitle(QCoreApplication::translate("ConnectDialog", "GroupBox", nullptr)); + editSlotsButton->setText(QCoreApplication::translate("ConnectDialog", "Edit...", nullptr)); + showAllCheckBox->setText(QCoreApplication::translate("ConnectDialog", "Show signals and slots inherited from QWidget", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/controller.ui.h b/tests/auto/tools/uic/baseline/controller.ui.h index 814a0c0430..3ebfad187f 100644 --- a/tests/auto/tools/uic/baseline/controller.ui.h +++ b/tests/auto/tools/uic/baseline/controller.ui.h @@ -75,12 +75,12 @@ public: void retranslateUi(QWidget *Controller) { - Controller->setWindowTitle(QApplication::translate("Controller", "Controller", nullptr)); - label->setText(QApplication::translate("Controller", "Controller", nullptr)); - decelerate->setText(QApplication::translate("Controller", "Decelerate", nullptr)); - accelerate->setText(QApplication::translate("Controller", "Accelerate", nullptr)); - right->setText(QApplication::translate("Controller", "Right", nullptr)); - left->setText(QApplication::translate("Controller", "Left", nullptr)); + Controller->setWindowTitle(QCoreApplication::translate("Controller", "Controller", nullptr)); + label->setText(QCoreApplication::translate("Controller", "Controller", nullptr)); + decelerate->setText(QCoreApplication::translate("Controller", "Decelerate", nullptr)); + accelerate->setText(QCoreApplication::translate("Controller", "Accelerate", nullptr)); + right->setText(QCoreApplication::translate("Controller", "Right", nullptr)); + left->setText(QCoreApplication::translate("Controller", "Left", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/cookies.ui.h b/tests/auto/tools/uic/baseline/cookies.ui.h index a3793f6def..2cc21888b1 100644 --- a/tests/auto/tools/uic/baseline/cookies.ui.h +++ b/tests/auto/tools/uic/baseline/cookies.ui.h @@ -91,9 +91,9 @@ public: void retranslateUi(QDialog *CookiesDialog) { - CookiesDialog->setWindowTitle(QApplication::translate("CookiesDialog", "Cookies", nullptr)); - removeButton->setText(QApplication::translate("CookiesDialog", "&Remove", nullptr)); - removeAllButton->setText(QApplication::translate("CookiesDialog", "Remove &All Cookies", nullptr)); + CookiesDialog->setWindowTitle(QCoreApplication::translate("CookiesDialog", "Cookies", nullptr)); + removeButton->setText(QCoreApplication::translate("CookiesDialog", "&Remove", nullptr)); + removeAllButton->setText(QCoreApplication::translate("CookiesDialog", "Remove &All Cookies", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/cookiesexceptions.ui.h b/tests/auto/tools/uic/baseline/cookiesexceptions.ui.h index 22b06f65a2..77212cf2f3 100644 --- a/tests/auto/tools/uic/baseline/cookiesexceptions.ui.h +++ b/tests/auto/tools/uic/baseline/cookiesexceptions.ui.h @@ -158,15 +158,15 @@ public: void retranslateUi(QDialog *CookiesExceptionsDialog) { - CookiesExceptionsDialog->setWindowTitle(QApplication::translate("CookiesExceptionsDialog", "Cookie Exceptions", nullptr)); - newExceptionGroupBox->setTitle(QApplication::translate("CookiesExceptionsDialog", "New Exception", nullptr)); - label->setText(QApplication::translate("CookiesExceptionsDialog", "Domain:", nullptr)); - blockButton->setText(QApplication::translate("CookiesExceptionsDialog", "Block", nullptr)); - allowForSessionButton->setText(QApplication::translate("CookiesExceptionsDialog", "Allow For Session", nullptr)); - allowButton->setText(QApplication::translate("CookiesExceptionsDialog", "Allow", nullptr)); - ExceptionsGroupBox->setTitle(QApplication::translate("CookiesExceptionsDialog", "Exceptions", nullptr)); - removeButton->setText(QApplication::translate("CookiesExceptionsDialog", "&Remove", nullptr)); - removeAllButton->setText(QApplication::translate("CookiesExceptionsDialog", "Remove &All", nullptr)); + CookiesExceptionsDialog->setWindowTitle(QCoreApplication::translate("CookiesExceptionsDialog", "Cookie Exceptions", nullptr)); + newExceptionGroupBox->setTitle(QCoreApplication::translate("CookiesExceptionsDialog", "New Exception", nullptr)); + label->setText(QCoreApplication::translate("CookiesExceptionsDialog", "Domain:", nullptr)); + blockButton->setText(QCoreApplication::translate("CookiesExceptionsDialog", "Block", nullptr)); + allowForSessionButton->setText(QCoreApplication::translate("CookiesExceptionsDialog", "Allow For Session", nullptr)); + allowButton->setText(QCoreApplication::translate("CookiesExceptionsDialog", "Allow", nullptr)); + ExceptionsGroupBox->setTitle(QCoreApplication::translate("CookiesExceptionsDialog", "Exceptions", nullptr)); + removeButton->setText(QCoreApplication::translate("CookiesExceptionsDialog", "&Remove", nullptr)); + removeAllButton->setText(QCoreApplication::translate("CookiesExceptionsDialog", "Remove &All", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/default.ui.h b/tests/auto/tools/uic/baseline/default.ui.h index af68bac7fd..fbbe81d0b8 100644 --- a/tests/auto/tools/uic/baseline/default.ui.h +++ b/tests/auto/tools/uic/baseline/default.ui.h @@ -226,84 +226,84 @@ public: void retranslateUi(QMainWindow *MainWindow) { - MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", nullptr)); - exitAction->setText(QApplication::translate("MainWindow", "&Exit", nullptr)); - aboutQtAction->setText(QApplication::translate("MainWindow", "About Qt", nullptr)); - editStyleAction->setText(QApplication::translate("MainWindow", "Edit &Style", nullptr)); - aboutAction->setText(QApplication::translate("MainWindow", "About", nullptr)); - nameLabel->setText(QApplication::translate("MainWindow", "&Name:", nullptr)); - nameCombo->setItemText(0, QApplication::translate("MainWindow", "Girish", nullptr)); - nameCombo->setItemText(1, QApplication::translate("MainWindow", "Jasmin", nullptr)); - nameCombo->setItemText(2, QApplication::translate("MainWindow", "Simon", nullptr)); - nameCombo->setItemText(3, QApplication::translate("MainWindow", "Zack", nullptr)); + MainWindow->setWindowTitle(QCoreApplication::translate("MainWindow", "MainWindow", nullptr)); + exitAction->setText(QCoreApplication::translate("MainWindow", "&Exit", nullptr)); + aboutQtAction->setText(QCoreApplication::translate("MainWindow", "About Qt", nullptr)); + editStyleAction->setText(QCoreApplication::translate("MainWindow", "Edit &Style", nullptr)); + aboutAction->setText(QCoreApplication::translate("MainWindow", "About", nullptr)); + nameLabel->setText(QCoreApplication::translate("MainWindow", "&Name:", nullptr)); + nameCombo->setItemText(0, QCoreApplication::translate("MainWindow", "Girish", nullptr)); + nameCombo->setItemText(1, QCoreApplication::translate("MainWindow", "Jasmin", nullptr)); + nameCombo->setItemText(2, QCoreApplication::translate("MainWindow", "Simon", nullptr)); + nameCombo->setItemText(3, QCoreApplication::translate("MainWindow", "Zack", nullptr)); #if QT_CONFIG(tooltip) - nameCombo->setToolTip(QApplication::translate("MainWindow", "Specify your name", nullptr)); + nameCombo->setToolTip(QCoreApplication::translate("MainWindow", "Specify your name", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(tooltip) - femaleRadioButton->setToolTip(QApplication::translate("MainWindow", "Check this if you are female", nullptr)); + femaleRadioButton->setToolTip(QCoreApplication::translate("MainWindow", "Check this if you are female", nullptr)); #endif // QT_CONFIG(tooltip) - femaleRadioButton->setText(QApplication::translate("MainWindow", "&Female", nullptr)); + femaleRadioButton->setText(QCoreApplication::translate("MainWindow", "&Female", nullptr)); #if QT_CONFIG(tooltip) - agreeCheckBox->setToolTip(QApplication::translate("MainWindow", "Please read the license before checking this", nullptr)); + agreeCheckBox->setToolTip(QCoreApplication::translate("MainWindow", "Please read the license before checking this", nullptr)); #endif // QT_CONFIG(tooltip) - agreeCheckBox->setText(QApplication::translate("MainWindow", "I &accept the terms and conditions", nullptr)); + agreeCheckBox->setText(QCoreApplication::translate("MainWindow", "I &accept the terms and conditions", nullptr)); #if QT_CONFIG(tooltip) - maleRadioButton->setToolTip(QApplication::translate("MainWindow", "Check this if you are male", nullptr)); + maleRadioButton->setToolTip(QCoreApplication::translate("MainWindow", "Check this if you are male", nullptr)); #endif // QT_CONFIG(tooltip) - maleRadioButton->setText(QApplication::translate("MainWindow", "&Male", nullptr)); - genderLabel->setText(QApplication::translate("MainWindow", "Gender:", nullptr)); + maleRadioButton->setText(QCoreApplication::translate("MainWindow", "&Male", nullptr)); + genderLabel->setText(QCoreApplication::translate("MainWindow", "Gender:", nullptr)); #if QT_CONFIG(tooltip) - ageSpinBox->setToolTip(QApplication::translate("MainWindow", "Specify your age", nullptr)); + ageSpinBox->setToolTip(QCoreApplication::translate("MainWindow", "Specify your age", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(statustip) - ageSpinBox->setStatusTip(QApplication::translate("MainWindow", "Specify your age here", nullptr)); + ageSpinBox->setStatusTip(QCoreApplication::translate("MainWindow", "Specify your age here", nullptr)); #endif // QT_CONFIG(statustip) - ageLabel->setText(QApplication::translate("MainWindow", "&Age:", nullptr)); - passwordLabel->setText(QApplication::translate("MainWindow", "&Password:", nullptr)); + ageLabel->setText(QCoreApplication::translate("MainWindow", "&Age:", nullptr)); + passwordLabel->setText(QCoreApplication::translate("MainWindow", "&Password:", nullptr)); #if QT_CONFIG(tooltip) - passwordEdit->setToolTip(QApplication::translate("MainWindow", "Specify your password", nullptr)); + passwordEdit->setToolTip(QCoreApplication::translate("MainWindow", "Specify your password", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(statustip) - passwordEdit->setStatusTip(QApplication::translate("MainWindow", "Specify your password here", nullptr)); + passwordEdit->setStatusTip(QCoreApplication::translate("MainWindow", "Specify your password here", nullptr)); #endif // QT_CONFIG(statustip) - passwordEdit->setText(QApplication::translate("MainWindow", "Password", nullptr)); - label->setText(QApplication::translate("MainWindow", "Profession", nullptr)); - countryLabel->setText(QApplication::translate("MainWindow", "&Country", nullptr)); + passwordEdit->setText(QCoreApplication::translate("MainWindow", "Password", nullptr)); + label->setText(QCoreApplication::translate("MainWindow", "Profession", nullptr)); + countryLabel->setText(QCoreApplication::translate("MainWindow", "&Country", nullptr)); const bool __sortingEnabled = professionList->isSortingEnabled(); professionList->setSortingEnabled(false); QListWidgetItem *___qlistwidgetitem = professionList->item(0); - ___qlistwidgetitem->setText(QApplication::translate("MainWindow", "Developer", nullptr)); + ___qlistwidgetitem->setText(QCoreApplication::translate("MainWindow", "Developer", nullptr)); QListWidgetItem *___qlistwidgetitem1 = professionList->item(1); - ___qlistwidgetitem1->setText(QApplication::translate("MainWindow", "Student", nullptr)); + ___qlistwidgetitem1->setText(QCoreApplication::translate("MainWindow", "Student", nullptr)); QListWidgetItem *___qlistwidgetitem2 = professionList->item(2); - ___qlistwidgetitem2->setText(QApplication::translate("MainWindow", "Fisherman", nullptr)); + ___qlistwidgetitem2->setText(QCoreApplication::translate("MainWindow", "Fisherman", nullptr)); professionList->setSortingEnabled(__sortingEnabled); #if QT_CONFIG(tooltip) - professionList->setToolTip(QApplication::translate("MainWindow", "Select your profession", nullptr)); + professionList->setToolTip(QCoreApplication::translate("MainWindow", "Select your profession", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(statustip) - professionList->setStatusTip(QApplication::translate("MainWindow", "Select your profession", nullptr)); + professionList->setStatusTip(QCoreApplication::translate("MainWindow", "Select your profession", nullptr)); #endif // QT_CONFIG(statustip) #if QT_CONFIG(whatsthis) - professionList->setWhatsThis(QApplication::translate("MainWindow", "Select your profession", nullptr)); + professionList->setWhatsThis(QCoreApplication::translate("MainWindow", "Select your profession", nullptr)); #endif // QT_CONFIG(whatsthis) - countryCombo->setItemText(0, QApplication::translate("MainWindow", "Germany", nullptr)); - countryCombo->setItemText(1, QApplication::translate("MainWindow", "India", nullptr)); - countryCombo->setItemText(2, QApplication::translate("MainWindow", "Norway", nullptr)); - countryCombo->setItemText(3, QApplication::translate("MainWindow", "United States Of America", nullptr)); - countryCombo->setItemText(4, QApplication::translate("MainWindow", "United Kingdom", nullptr)); + countryCombo->setItemText(0, QCoreApplication::translate("MainWindow", "Germany", nullptr)); + countryCombo->setItemText(1, QCoreApplication::translate("MainWindow", "India", nullptr)); + countryCombo->setItemText(2, QCoreApplication::translate("MainWindow", "Norway", nullptr)); + countryCombo->setItemText(3, QCoreApplication::translate("MainWindow", "United States Of America", nullptr)); + countryCombo->setItemText(4, QCoreApplication::translate("MainWindow", "United Kingdom", nullptr)); #if QT_CONFIG(tooltip) - countryCombo->setToolTip(QApplication::translate("MainWindow", "Specify your country", nullptr)); + countryCombo->setToolTip(QCoreApplication::translate("MainWindow", "Specify your country", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(statustip) - countryCombo->setStatusTip(QApplication::translate("MainWindow", "Specify your country here", nullptr)); + countryCombo->setStatusTip(QCoreApplication::translate("MainWindow", "Specify your country here", nullptr)); #endif // QT_CONFIG(statustip) - menu_File->setTitle(QApplication::translate("MainWindow", "&File", nullptr)); - menu_Help->setTitle(QApplication::translate("MainWindow", "&Help", nullptr)); + menu_File->setTitle(QCoreApplication::translate("MainWindow", "&File", nullptr)); + menu_Help->setTitle(QCoreApplication::translate("MainWindow", "&Help", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/dialog.ui.h b/tests/auto/tools/uic/baseline/dialog.ui.h index 4c0edf4127..aeed71d058 100644 --- a/tests/auto/tools/uic/baseline/dialog.ui.h +++ b/tests/auto/tools/uic/baseline/dialog.ui.h @@ -58,10 +58,10 @@ public: void retranslateUi(QDialog *Dialog) { - Dialog->setWindowTitle(QApplication::translate("Dialog", "Dialog", nullptr)); - loadFromFileButton->setText(QApplication::translate("Dialog", "Load Image From File...", nullptr)); - label->setText(QApplication::translate("Dialog", "Launch two of these dialogs. In the first, press the top button and load an image from a file. In the second, press the bottom button and display the loaded image from shared memory.", nullptr)); - loadFromSharedMemoryButton->setText(QApplication::translate("Dialog", "Display Image From Shared Memory", nullptr)); + Dialog->setWindowTitle(QCoreApplication::translate("Dialog", "Dialog", nullptr)); + loadFromFileButton->setText(QCoreApplication::translate("Dialog", "Load Image From File...", nullptr)); + label->setText(QCoreApplication::translate("Dialog", "Launch two of these dialogs. In the first, press the top button and load an image from a file. In the second, press the bottom button and display the loaded image from shared memory.", nullptr)); + loadFromSharedMemoryButton->setText(QCoreApplication::translate("Dialog", "Display Image From Shared Memory", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/downloaditem.ui.h b/tests/auto/tools/uic/baseline/downloaditem.ui.h index b4a5e23226..31d938f0eb 100644 --- a/tests/auto/tools/uic/baseline/downloaditem.ui.h +++ b/tests/auto/tools/uic/baseline/downloaditem.ui.h @@ -124,13 +124,13 @@ public: void retranslateUi(QWidget *DownloadItem) { - DownloadItem->setWindowTitle(QApplication::translate("DownloadItem", "Form", nullptr)); - fileIcon->setText(QApplication::translate("DownloadItem", "Ico", nullptr)); - fileNameLabel->setProperty("text", QVariant(QApplication::translate("DownloadItem", "Filename", nullptr))); + DownloadItem->setWindowTitle(QCoreApplication::translate("DownloadItem", "Form", nullptr)); + fileIcon->setText(QCoreApplication::translate("DownloadItem", "Ico", nullptr)); + fileNameLabel->setProperty("text", QVariant(QCoreApplication::translate("DownloadItem", "Filename", nullptr))); downloadInfoLabel->setProperty("text", QVariant(QString())); - tryAgainButton->setText(QApplication::translate("DownloadItem", "Try Again", nullptr)); - stopButton->setText(QApplication::translate("DownloadItem", "Stop", nullptr)); - openButton->setText(QApplication::translate("DownloadItem", "Open", nullptr)); + tryAgainButton->setText(QCoreApplication::translate("DownloadItem", "Try Again", nullptr)); + stopButton->setText(QCoreApplication::translate("DownloadItem", "Stop", nullptr)); + openButton->setText(QCoreApplication::translate("DownloadItem", "Open", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/downloads.ui.h b/tests/auto/tools/uic/baseline/downloads.ui.h index 5b9f405f8f..1b5b825792 100644 --- a/tests/auto/tools/uic/baseline/downloads.ui.h +++ b/tests/auto/tools/uic/baseline/downloads.ui.h @@ -79,9 +79,9 @@ public: void retranslateUi(QDialog *DownloadDialog) { - DownloadDialog->setWindowTitle(QApplication::translate("DownloadDialog", "Downloads", nullptr)); - cleanupButton->setText(QApplication::translate("DownloadDialog", "Clean up", nullptr)); - itemCount->setText(QApplication::translate("DownloadDialog", "0 Items", nullptr)); + DownloadDialog->setWindowTitle(QCoreApplication::translate("DownloadDialog", "Downloads", nullptr)); + cleanupButton->setText(QCoreApplication::translate("DownloadDialog", "Clean up", nullptr)); + itemCount->setText(QCoreApplication::translate("DownloadDialog", "0 Items", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/embeddeddialog.ui.h b/tests/auto/tools/uic/baseline/embeddeddialog.ui.h index eb07718da3..20d6567576 100644 --- a/tests/auto/tools/uic/baseline/embeddeddialog.ui.h +++ b/tests/auto/tools/uic/baseline/embeddeddialog.ui.h @@ -97,14 +97,14 @@ public: void retranslateUi(QDialog *embeddedDialog) { - embeddedDialog->setWindowTitle(QApplication::translate("embeddedDialog", "Embedded Dialog", nullptr)); - label->setText(QApplication::translate("embeddedDialog", "Layout Direction:", nullptr)); - layoutDirection->setItemText(0, QApplication::translate("embeddedDialog", "Left to Right", nullptr)); - layoutDirection->setItemText(1, QApplication::translate("embeddedDialog", "Right to Left", nullptr)); + embeddedDialog->setWindowTitle(QCoreApplication::translate("embeddedDialog", "Embedded Dialog", nullptr)); + label->setText(QCoreApplication::translate("embeddedDialog", "Layout Direction:", nullptr)); + layoutDirection->setItemText(0, QCoreApplication::translate("embeddedDialog", "Left to Right", nullptr)); + layoutDirection->setItemText(1, QCoreApplication::translate("embeddedDialog", "Right to Left", nullptr)); - label_2->setText(QApplication::translate("embeddedDialog", "Select Font:", nullptr)); - label_3->setText(QApplication::translate("embeddedDialog", "Style:", nullptr)); - label_4->setText(QApplication::translate("embeddedDialog", "Layout spacing:", nullptr)); + label_2->setText(QCoreApplication::translate("embeddedDialog", "Select Font:", nullptr)); + label_3->setText(QCoreApplication::translate("embeddedDialog", "Style:", nullptr)); + label_4->setText(QCoreApplication::translate("embeddedDialog", "Layout spacing:", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/enumnostdset.ui.h b/tests/auto/tools/uic/baseline/enumnostdset.ui.h index 233fc616ac..54ec7c4161 100644 --- a/tests/auto/tools/uic/baseline/enumnostdset.ui.h +++ b/tests/auto/tools/uic/baseline/enumnostdset.ui.h @@ -38,7 +38,7 @@ public: void retranslateUi(QWidget *Form) { - Form->setWindowTitle(QApplication::translate("Form", "Form", nullptr)); + Form->setWindowTitle(QCoreApplication::translate("Form", "Form", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/filespage.ui.h b/tests/auto/tools/uic/baseline/filespage.ui.h index 8738109bd5..327b2c571b 100644 --- a/tests/auto/tools/uic/baseline/filespage.ui.h +++ b/tests/auto/tools/uic/baseline/filespage.ui.h @@ -80,10 +80,10 @@ public: void retranslateUi(QWidget *FilesPage) { - FilesPage->setWindowTitle(QApplication::translate("FilesPage", "Form", nullptr)); - fileLabel->setText(QApplication::translate("FilesPage", "Files:", nullptr)); - removeButton->setText(QApplication::translate("FilesPage", "Remove", nullptr)); - removeAllButton->setText(QApplication::translate("FilesPage", "Remove All", nullptr)); + FilesPage->setWindowTitle(QCoreApplication::translate("FilesPage", "Form", nullptr)); + fileLabel->setText(QCoreApplication::translate("FilesPage", "Files:", nullptr)); + removeButton->setText(QCoreApplication::translate("FilesPage", "Remove", nullptr)); + removeAllButton->setText(QCoreApplication::translate("FilesPage", "Remove All", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/filternamedialog.ui.h b/tests/auto/tools/uic/baseline/filternamedialog.ui.h index 8e5782c387..0098282d59 100644 --- a/tests/auto/tools/uic/baseline/filternamedialog.ui.h +++ b/tests/auto/tools/uic/baseline/filternamedialog.ui.h @@ -76,8 +76,8 @@ public: void retranslateUi(QDialog *FilterNameDialogClass) { - FilterNameDialogClass->setWindowTitle(QApplication::translate("FilterNameDialogClass", "FilterNameDialog", nullptr)); - label->setText(QApplication::translate("FilterNameDialogClass", "Filter Name:", nullptr)); + FilterNameDialogClass->setWindowTitle(QCoreApplication::translate("FilterNameDialogClass", "FilterNameDialog", nullptr)); + label->setText(QCoreApplication::translate("FilterNameDialogClass", "Filter Name:", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/filterpage.ui.h b/tests/auto/tools/uic/baseline/filterpage.ui.h index a899938e33..1581c6554d 100644 --- a/tests/auto/tools/uic/baseline/filterpage.ui.h +++ b/tests/auto/tools/uic/baseline/filterpage.ui.h @@ -103,14 +103,14 @@ public: void retranslateUi(QWidget *FilterPage) { - FilterPage->setWindowTitle(QApplication::translate("FilterPage", "Form", nullptr)); - label->setText(QApplication::translate("FilterPage", "Filter attributes for current documentation (comma separated list):", nullptr)); - groupBox->setTitle(QApplication::translate("FilterPage", "Custom Filters", nullptr)); + FilterPage->setWindowTitle(QCoreApplication::translate("FilterPage", "Form", nullptr)); + label->setText(QCoreApplication::translate("FilterPage", "Filter attributes for current documentation (comma separated list):", nullptr)); + groupBox->setTitle(QCoreApplication::translate("FilterPage", "Custom Filters", nullptr)); QTreeWidgetItem *___qtreewidgetitem = customFilterWidget->headerItem(); - ___qtreewidgetitem->setText(1, QApplication::translate("FilterPage", "2", nullptr)); - ___qtreewidgetitem->setText(0, QApplication::translate("FilterPage", "1", nullptr)); - addButton->setText(QApplication::translate("FilterPage", "Add", nullptr)); - removeButton->setText(QApplication::translate("FilterPage", "Remove", nullptr)); + ___qtreewidgetitem->setText(1, QCoreApplication::translate("FilterPage", "2", nullptr)); + ___qtreewidgetitem->setText(0, QCoreApplication::translate("FilterPage", "1", nullptr)); + addButton->setText(QCoreApplication::translate("FilterPage", "Add", nullptr)); + removeButton->setText(QCoreApplication::translate("FilterPage", "Remove", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/finddialog.ui.h b/tests/auto/tools/uic/baseline/finddialog.ui.h index 843c747b72..f335eee2e4 100644 --- a/tests/auto/tools/uic/baseline/finddialog.ui.h +++ b/tests/auto/tools/uic/baseline/finddialog.ui.h @@ -193,40 +193,40 @@ public: void retranslateUi(QDialog *FindDialog) { - FindDialog->setWindowTitle(QApplication::translate("FindDialog", "Find", nullptr)); + FindDialog->setWindowTitle(QCoreApplication::translate("FindDialog", "Find", nullptr)); #if QT_CONFIG(whatsthis) - FindDialog->setWhatsThis(QApplication::translate("FindDialog", "This window allows you to search for some text in the translation source file.", nullptr)); + FindDialog->setWhatsThis(QCoreApplication::translate("FindDialog", "This window allows you to search for some text in the translation source file.", nullptr)); #endif // QT_CONFIG(whatsthis) - findWhat->setText(QApplication::translate("FindDialog", "&Find what:", nullptr)); + findWhat->setText(QCoreApplication::translate("FindDialog", "&Find what:", nullptr)); #if QT_CONFIG(whatsthis) - led->setWhatsThis(QApplication::translate("FindDialog", "Type in the text to search for.", nullptr)); + led->setWhatsThis(QCoreApplication::translate("FindDialog", "Type in the text to search for.", nullptr)); #endif // QT_CONFIG(whatsthis) - groupBox->setTitle(QApplication::translate("FindDialog", "Options", nullptr)); + groupBox->setTitle(QCoreApplication::translate("FindDialog", "Options", nullptr)); #if QT_CONFIG(whatsthis) - sourceText->setWhatsThis(QApplication::translate("FindDialog", "Source texts are searched when checked.", nullptr)); + sourceText->setWhatsThis(QCoreApplication::translate("FindDialog", "Source texts are searched when checked.", nullptr)); #endif // QT_CONFIG(whatsthis) - sourceText->setText(QApplication::translate("FindDialog", "&Source texts", nullptr)); + sourceText->setText(QCoreApplication::translate("FindDialog", "&Source texts", nullptr)); #if QT_CONFIG(whatsthis) - translations->setWhatsThis(QApplication::translate("FindDialog", "Translations are searched when checked.", nullptr)); + translations->setWhatsThis(QCoreApplication::translate("FindDialog", "Translations are searched when checked.", nullptr)); #endif // QT_CONFIG(whatsthis) - translations->setText(QApplication::translate("FindDialog", "&Translations", nullptr)); + translations->setText(QCoreApplication::translate("FindDialog", "&Translations", nullptr)); #if QT_CONFIG(whatsthis) - matchCase->setWhatsThis(QApplication::translate("FindDialog", "Texts such as 'TeX' and 'tex' are considered as different when checked.", nullptr)); + matchCase->setWhatsThis(QCoreApplication::translate("FindDialog", "Texts such as 'TeX' and 'tex' are considered as different when checked.", nullptr)); #endif // QT_CONFIG(whatsthis) - matchCase->setText(QApplication::translate("FindDialog", "&Match case", nullptr)); + matchCase->setText(QCoreApplication::translate("FindDialog", "&Match case", nullptr)); #if QT_CONFIG(whatsthis) - comments->setWhatsThis(QApplication::translate("FindDialog", "Comments and contexts are searched when checked.", nullptr)); + comments->setWhatsThis(QCoreApplication::translate("FindDialog", "Comments and contexts are searched when checked.", nullptr)); #endif // QT_CONFIG(whatsthis) - comments->setText(QApplication::translate("FindDialog", "&Comments", nullptr)); - ignoreAccelerators->setText(QApplication::translate("FindDialog", "Ignore &accelerators", nullptr)); + comments->setText(QCoreApplication::translate("FindDialog", "&Comments", nullptr)); + ignoreAccelerators->setText(QCoreApplication::translate("FindDialog", "Ignore &accelerators", nullptr)); #if QT_CONFIG(whatsthis) - findNxt->setWhatsThis(QApplication::translate("FindDialog", "Click here to find the next occurrence of the text you typed in.", nullptr)); + findNxt->setWhatsThis(QCoreApplication::translate("FindDialog", "Click here to find the next occurrence of the text you typed in.", nullptr)); #endif // QT_CONFIG(whatsthis) - findNxt->setText(QApplication::translate("FindDialog", "Find Next", nullptr)); + findNxt->setText(QCoreApplication::translate("FindDialog", "Find Next", nullptr)); #if QT_CONFIG(whatsthis) - cancel->setWhatsThis(QApplication::translate("FindDialog", "Click here to close this window.", nullptr)); + cancel->setWhatsThis(QCoreApplication::translate("FindDialog", "Click here to close this window.", nullptr)); #endif // QT_CONFIG(whatsthis) - cancel->setText(QApplication::translate("FindDialog", "Cancel", nullptr)); + cancel->setText(QCoreApplication::translate("FindDialog", "Cancel", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/form.ui.h b/tests/auto/tools/uic/baseline/form.ui.h index 9fda6daac4..df8163f726 100644 --- a/tests/auto/tools/uic/baseline/form.ui.h +++ b/tests/auto/tools/uic/baseline/form.ui.h @@ -123,9 +123,9 @@ public: void retranslateUi(QWidget *WorldTimeForm) { - WorldTimeForm->setWindowTitle(QApplication::translate("WorldTimeForm", "World Time Clock", nullptr)); - label->setText(QApplication::translate("WorldTimeForm", "Current time:", nullptr)); - label_2->setText(QApplication::translate("WorldTimeForm", "Set time zone:", nullptr)); + WorldTimeForm->setWindowTitle(QCoreApplication::translate("WorldTimeForm", "World Time Clock", nullptr)); + label->setText(QCoreApplication::translate("WorldTimeForm", "Current time:", nullptr)); + label_2->setText(QCoreApplication::translate("WorldTimeForm", "Set time zone:", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/formwindowsettings.ui.h b/tests/auto/tools/uic/baseline/formwindowsettings.ui.h index e18b72cb5b..17c301e959 100644 --- a/tests/auto/tools/uic/baseline/formwindowsettings.ui.h +++ b/tests/auto/tools/uic/baseline/formwindowsettings.ui.h @@ -271,17 +271,17 @@ public: void retranslateUi(QDialog *FormWindowSettings) { - FormWindowSettings->setWindowTitle(QApplication::translate("FormWindowSettings", "Form Settings", nullptr)); - layoutDefaultGroupBox->setTitle(QApplication::translate("FormWindowSettings", "Layout &Default", nullptr)); - label_2->setText(QApplication::translate("FormWindowSettings", "&Spacing:", nullptr)); - label->setText(QApplication::translate("FormWindowSettings", "&Margin:", nullptr)); - layoutFunctionGroupBox->setTitle(QApplication::translate("FormWindowSettings", "&Layout Function", nullptr)); - label_3->setText(QApplication::translate("FormWindowSettings", "Ma&rgin:", nullptr)); - label_3_2->setText(QApplication::translate("FormWindowSettings", "Spa&cing:", nullptr)); - pixmapFunctionGroupBox_2->setTitle(QApplication::translate("FormWindowSettings", "&Author", nullptr)); - includeHintsGroupBox->setTitle(QApplication::translate("FormWindowSettings", "&Include Hints", nullptr)); - pixmapFunctionGroupBox->setTitle(QApplication::translate("FormWindowSettings", "&Pixmap Function", nullptr)); - gridPanel->setTitle(QApplication::translate("FormWindowSettings", "Grid", nullptr)); + FormWindowSettings->setWindowTitle(QCoreApplication::translate("FormWindowSettings", "Form Settings", nullptr)); + layoutDefaultGroupBox->setTitle(QCoreApplication::translate("FormWindowSettings", "Layout &Default", nullptr)); + label_2->setText(QCoreApplication::translate("FormWindowSettings", "&Spacing:", nullptr)); + label->setText(QCoreApplication::translate("FormWindowSettings", "&Margin:", nullptr)); + layoutFunctionGroupBox->setTitle(QCoreApplication::translate("FormWindowSettings", "&Layout Function", nullptr)); + label_3->setText(QCoreApplication::translate("FormWindowSettings", "Ma&rgin:", nullptr)); + label_3_2->setText(QCoreApplication::translate("FormWindowSettings", "Spa&cing:", nullptr)); + pixmapFunctionGroupBox_2->setTitle(QCoreApplication::translate("FormWindowSettings", "&Author", nullptr)); + includeHintsGroupBox->setTitle(QCoreApplication::translate("FormWindowSettings", "&Include Hints", nullptr)); + pixmapFunctionGroupBox->setTitle(QCoreApplication::translate("FormWindowSettings", "&Pixmap Function", nullptr)); + gridPanel->setTitle(QCoreApplication::translate("FormWindowSettings", "Grid", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/generalpage.ui.h b/tests/auto/tools/uic/baseline/generalpage.ui.h index f13cc7faca..6488bfc061 100644 --- a/tests/auto/tools/uic/baseline/generalpage.ui.h +++ b/tests/auto/tools/uic/baseline/generalpage.ui.h @@ -73,9 +73,9 @@ public: void retranslateUi(QWidget *GeneralPage) { - GeneralPage->setWindowTitle(QApplication::translate("GeneralPage", "Form", nullptr)); - label->setText(QApplication::translate("GeneralPage", "Namespace:", nullptr)); - label_2->setText(QApplication::translate("GeneralPage", "Virtual Folder:", nullptr)); + GeneralPage->setWindowTitle(QCoreApplication::translate("GeneralPage", "Form", nullptr)); + label->setText(QCoreApplication::translate("GeneralPage", "Namespace:", nullptr)); + label_2->setText(QCoreApplication::translate("GeneralPage", "Virtual Folder:", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/gridalignment.ui.h b/tests/auto/tools/uic/baseline/gridalignment.ui.h index c8ce4bc477..f85ed818f7 100644 --- a/tests/auto/tools/uic/baseline/gridalignment.ui.h +++ b/tests/auto/tools/uic/baseline/gridalignment.ui.h @@ -61,11 +61,11 @@ public: void retranslateUi(QWidget *Form) { - Form->setWindowTitle(QApplication::translate("Form", "Form", nullptr)); - pushButton->setText(QApplication::translate("Form", "Left", nullptr)); - pushButton_3->setText(QApplication::translate("Form", "Top", nullptr)); - pushButton_2->setText(QApplication::translate("Form", "Right", nullptr)); - pushButton_4->setText(QApplication::translate("Form", "Bottom", nullptr)); + Form->setWindowTitle(QCoreApplication::translate("Form", "Form", nullptr)); + pushButton->setText(QCoreApplication::translate("Form", "Left", nullptr)); + pushButton_3->setText(QCoreApplication::translate("Form", "Top", nullptr)); + pushButton_2->setText(QCoreApplication::translate("Form", "Right", nullptr)); + pushButton_4->setText(QCoreApplication::translate("Form", "Bottom", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/gridpanel.ui.h b/tests/auto/tools/uic/baseline/gridpanel.ui.h index 22b639a95f..54c9a3b5de 100644 --- a/tests/auto/tools/uic/baseline/gridpanel.ui.h +++ b/tests/auto/tools/uic/baseline/gridpanel.ui.h @@ -132,14 +132,14 @@ public: void retranslateUi(QWidget *qdesigner_internal__GridPanel) { - qdesigner_internal__GridPanel->setWindowTitle(QApplication::translate("qdesigner_internal::GridPanel", "Form", nullptr)); - m_gridGroupBox->setTitle(QApplication::translate("qdesigner_internal::GridPanel", "Grid", nullptr)); - m_visibleCheckBox->setText(QApplication::translate("qdesigner_internal::GridPanel", "Visible", nullptr)); - label->setText(QApplication::translate("qdesigner_internal::GridPanel", "Grid &X", nullptr)); - m_snapXCheckBox->setText(QApplication::translate("qdesigner_internal::GridPanel", "Snap", nullptr)); - m_resetButton->setText(QApplication::translate("qdesigner_internal::GridPanel", "Reset", nullptr)); - label_2->setText(QApplication::translate("qdesigner_internal::GridPanel", "Grid &Y", nullptr)); - m_snapYCheckBox->setText(QApplication::translate("qdesigner_internal::GridPanel", "Snap", nullptr)); + qdesigner_internal__GridPanel->setWindowTitle(QCoreApplication::translate("qdesigner_internal::GridPanel", "Form", nullptr)); + m_gridGroupBox->setTitle(QCoreApplication::translate("qdesigner_internal::GridPanel", "Grid", nullptr)); + m_visibleCheckBox->setText(QCoreApplication::translate("qdesigner_internal::GridPanel", "Visible", nullptr)); + label->setText(QCoreApplication::translate("qdesigner_internal::GridPanel", "Grid &X", nullptr)); + m_snapXCheckBox->setText(QCoreApplication::translate("qdesigner_internal::GridPanel", "Snap", nullptr)); + m_resetButton->setText(QCoreApplication::translate("qdesigner_internal::GridPanel", "Reset", nullptr)); + label_2->setText(QCoreApplication::translate("qdesigner_internal::GridPanel", "Grid &Y", nullptr)); + m_snapYCheckBox->setText(QCoreApplication::translate("qdesigner_internal::GridPanel", "Snap", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/helpdialog.ui.h b/tests/auto/tools/uic/baseline/helpdialog.ui.h index 070f0484f1..1f6cf8783d 100644 --- a/tests/auto/tools/uic/baseline/helpdialog.ui.h +++ b/tests/auto/tools/uic/baseline/helpdialog.ui.h @@ -296,77 +296,77 @@ public: void retranslateUi(QWidget *HelpDialog) { - HelpDialog->setWindowTitle(QApplication::translate("HelpDialog", "Help", nullptr)); + HelpDialog->setWindowTitle(QCoreApplication::translate("HelpDialog", "Help", nullptr)); #if QT_CONFIG(whatsthis) - HelpDialog->setWhatsThis(QApplication::translate("HelpDialog", "Help

    Choose the topic you want help on from the contents list, or search the index for keywords.

    ", nullptr)); + HelpDialog->setWhatsThis(QCoreApplication::translate("HelpDialog", "Help

    Choose the topic you want help on from the contents list, or search the index for keywords.

    ", nullptr)); #endif // QT_CONFIG(whatsthis) #if QT_CONFIG(whatsthis) - tabWidget->setWhatsThis(QApplication::translate("HelpDialog", "Displays help topics organized by category, index or bookmarks. Another tab inherits the full text search.", nullptr)); + tabWidget->setWhatsThis(QCoreApplication::translate("HelpDialog", "Displays help topics organized by category, index or bookmarks. Another tab inherits the full text search.", nullptr)); #endif // QT_CONFIG(whatsthis) QTreeWidgetItem *___qtreewidgetitem = listContents->headerItem(); - ___qtreewidgetitem->setText(0, QApplication::translate("HelpDialog", "column 1", nullptr)); + ___qtreewidgetitem->setText(0, QCoreApplication::translate("HelpDialog", "column 1", nullptr)); #if QT_CONFIG(whatsthis) - listContents->setWhatsThis(QApplication::translate("HelpDialog", "Help topics organized by category.

    Double-click an item to see the topics in that category. To view a topic, just double-click it.

    ", nullptr)); + listContents->setWhatsThis(QCoreApplication::translate("HelpDialog", "Help topics organized by category.

    Double-click an item to see the topics in that category. To view a topic, just double-click it.

    ", nullptr)); #endif // QT_CONFIG(whatsthis) - tabWidget->setTabText(tabWidget->indexOf(contentPage), QApplication::translate("HelpDialog", "Con&tents", nullptr)); - TextLabel1->setText(QApplication::translate("HelpDialog", "&Look For:", nullptr)); + tabWidget->setTabText(tabWidget->indexOf(contentPage), QCoreApplication::translate("HelpDialog", "Con&tents", nullptr)); + TextLabel1->setText(QCoreApplication::translate("HelpDialog", "&Look For:", nullptr)); #if QT_CONFIG(tooltip) - editIndex->setToolTip(QApplication::translate("HelpDialog", "Enter keyword", nullptr)); + editIndex->setToolTip(QCoreApplication::translate("HelpDialog", "Enter keyword", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(whatsthis) - editIndex->setWhatsThis(QApplication::translate("HelpDialog", "Enter a keyword.

    The list will select an item that matches the entered string best.

    ", nullptr)); + editIndex->setWhatsThis(QCoreApplication::translate("HelpDialog", "Enter a keyword.

    The list will select an item that matches the entered string best.

    ", nullptr)); #endif // QT_CONFIG(whatsthis) #if QT_CONFIG(whatsthis) - listIndex->setWhatsThis(QApplication::translate("HelpDialog", "List of available help topics.

    Double-click on an item to open its help page. If more than one is found, you must specify which page you want.

    ", nullptr)); + listIndex->setWhatsThis(QCoreApplication::translate("HelpDialog", "List of available help topics.

    Double-click on an item to open its help page. If more than one is found, you must specify which page you want.

    ", nullptr)); #endif // QT_CONFIG(whatsthis) - tabWidget->setTabText(tabWidget->indexOf(indexPage), QApplication::translate("HelpDialog", "&Index", nullptr)); + tabWidget->setTabText(tabWidget->indexOf(indexPage), QCoreApplication::translate("HelpDialog", "&Index", nullptr)); QTreeWidgetItem *___qtreewidgetitem1 = listBookmarks->headerItem(); - ___qtreewidgetitem1->setText(0, QApplication::translate("HelpDialog", "column 1", nullptr)); + ___qtreewidgetitem1->setText(0, QCoreApplication::translate("HelpDialog", "column 1", nullptr)); #if QT_CONFIG(whatsthis) - listBookmarks->setWhatsThis(QApplication::translate("HelpDialog", "Displays the list of bookmarks.", nullptr)); + listBookmarks->setWhatsThis(QCoreApplication::translate("HelpDialog", "Displays the list of bookmarks.", nullptr)); #endif // QT_CONFIG(whatsthis) #if QT_CONFIG(tooltip) - buttonAdd->setToolTip(QApplication::translate("HelpDialog", "Add new bookmark", nullptr)); + buttonAdd->setToolTip(QCoreApplication::translate("HelpDialog", "Add new bookmark", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(whatsthis) - buttonAdd->setWhatsThis(QApplication::translate("HelpDialog", "Add the currently displayed page as a new bookmark.", nullptr)); + buttonAdd->setWhatsThis(QCoreApplication::translate("HelpDialog", "Add the currently displayed page as a new bookmark.", nullptr)); #endif // QT_CONFIG(whatsthis) - buttonAdd->setText(QApplication::translate("HelpDialog", "&New", nullptr)); + buttonAdd->setText(QCoreApplication::translate("HelpDialog", "&New", nullptr)); #if QT_CONFIG(tooltip) - buttonRemove->setToolTip(QApplication::translate("HelpDialog", "Delete bookmark", nullptr)); + buttonRemove->setToolTip(QCoreApplication::translate("HelpDialog", "Delete bookmark", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(whatsthis) - buttonRemove->setWhatsThis(QApplication::translate("HelpDialog", "Delete the selected bookmark.", nullptr)); + buttonRemove->setWhatsThis(QCoreApplication::translate("HelpDialog", "Delete the selected bookmark.", nullptr)); #endif // QT_CONFIG(whatsthis) - buttonRemove->setText(QApplication::translate("HelpDialog", "&Delete", nullptr)); - tabWidget->setTabText(tabWidget->indexOf(bookmarkPage), QApplication::translate("HelpDialog", "&Bookmarks", nullptr)); - TextLabel1_2->setText(QApplication::translate("HelpDialog", "Searching f&or:", nullptr)); + buttonRemove->setText(QCoreApplication::translate("HelpDialog", "&Delete", nullptr)); + tabWidget->setTabText(tabWidget->indexOf(bookmarkPage), QCoreApplication::translate("HelpDialog", "&Bookmarks", nullptr)); + TextLabel1_2->setText(QCoreApplication::translate("HelpDialog", "Searching f&or:", nullptr)); #if QT_CONFIG(tooltip) - termsEdit->setToolTip(QApplication::translate("HelpDialog", "Enter searchword(s).", nullptr)); + termsEdit->setToolTip(QCoreApplication::translate("HelpDialog", "Enter searchword(s).", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(whatsthis) - termsEdit->setWhatsThis(QApplication::translate("HelpDialog", "Enter search word(s).

    Enter here the word(s) you are looking for. The words may contain wildcards (*). For a sequence of words quote them.

    ", nullptr)); + termsEdit->setWhatsThis(QCoreApplication::translate("HelpDialog", "Enter search word(s).

    Enter here the word(s) you are looking for. The words may contain wildcards (*). For a sequence of words quote them.

    ", nullptr)); #endif // QT_CONFIG(whatsthis) #if QT_CONFIG(whatsthis) - resultBox->setWhatsThis(QApplication::translate("HelpDialog", "Found documents

    This list contains all found documents from the last search. The documents are ordered, i.e. the first document has the most matches.

    ", nullptr)); + resultBox->setWhatsThis(QCoreApplication::translate("HelpDialog", "Found documents

    This list contains all found documents from the last search. The documents are ordered, i.e. the first document has the most matches.

    ", nullptr)); #endif // QT_CONFIG(whatsthis) - TextLabel2->setText(QApplication::translate("HelpDialog", "Found &Documents:", nullptr)); + TextLabel2->setText(QCoreApplication::translate("HelpDialog", "Found &Documents:", nullptr)); #if QT_CONFIG(tooltip) - helpButton->setToolTip(QApplication::translate("HelpDialog", "Display the help page.", nullptr)); + helpButton->setToolTip(QCoreApplication::translate("HelpDialog", "Display the help page.", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(whatsthis) - helpButton->setWhatsThis(QApplication::translate("HelpDialog", "Display the help page for the full text search.", nullptr)); + helpButton->setWhatsThis(QCoreApplication::translate("HelpDialog", "Display the help page for the full text search.", nullptr)); #endif // QT_CONFIG(whatsthis) - helpButton->setText(QApplication::translate("HelpDialog", "He&lp", nullptr)); + helpButton->setText(QCoreApplication::translate("HelpDialog", "He&lp", nullptr)); #if QT_CONFIG(tooltip) - searchButton->setToolTip(QApplication::translate("HelpDialog", "Start searching.", nullptr)); + searchButton->setToolTip(QCoreApplication::translate("HelpDialog", "Start searching.", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(whatsthis) - searchButton->setWhatsThis(QApplication::translate("HelpDialog", "Pressing this button starts the search.", nullptr)); + searchButton->setWhatsThis(QCoreApplication::translate("HelpDialog", "Pressing this button starts the search.", nullptr)); #endif // QT_CONFIG(whatsthis) - searchButton->setText(QApplication::translate("HelpDialog", "&Search", nullptr)); - tabWidget->setTabText(tabWidget->indexOf(searchPage), QApplication::translate("HelpDialog", "&Search", nullptr)); - labelPrepare->setText(QApplication::translate("HelpDialog", "Preparing...", nullptr)); + searchButton->setText(QCoreApplication::translate("HelpDialog", "&Search", nullptr)); + tabWidget->setTabText(tabWidget->indexOf(searchPage), QCoreApplication::translate("HelpDialog", "&Search", nullptr)); + labelPrepare->setText(QCoreApplication::translate("HelpDialog", "Preparing...", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/history.ui.h b/tests/auto/tools/uic/baseline/history.ui.h index 30477b8fb6..7f48fb9f54 100644 --- a/tests/auto/tools/uic/baseline/history.ui.h +++ b/tests/auto/tools/uic/baseline/history.ui.h @@ -91,9 +91,9 @@ public: void retranslateUi(QDialog *HistoryDialog) { - HistoryDialog->setWindowTitle(QApplication::translate("HistoryDialog", "History", nullptr)); - removeButton->setText(QApplication::translate("HistoryDialog", "&Remove", nullptr)); - removeAllButton->setText(QApplication::translate("HistoryDialog", "Remove &All", nullptr)); + HistoryDialog->setWindowTitle(QCoreApplication::translate("HistoryDialog", "History", nullptr)); + removeButton->setText(QCoreApplication::translate("HistoryDialog", "&Remove", nullptr)); + removeAllButton->setText(QCoreApplication::translate("HistoryDialog", "Remove &All", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/icontheme.ui.h b/tests/auto/tools/uic/baseline/icontheme.ui.h index 3baf5539ee..f1f6e42a02 100644 --- a/tests/auto/tools/uic/baseline/icontheme.ui.h +++ b/tests/auto/tools/uic/baseline/icontheme.ui.h @@ -75,10 +75,10 @@ public: void retranslateUi(QWidget *Form) { - Form->setWindowTitle(QApplication::translate("Form", "Form", nullptr)); - fileicon->setText(QApplication::translate("Form", "fileicon", nullptr)); - fileandthemeicon->setText(QApplication::translate("Form", "PushButton", nullptr)); - themeicon->setText(QApplication::translate("Form", "PushButton", nullptr)); + Form->setWindowTitle(QCoreApplication::translate("Form", "Form", nullptr)); + fileicon->setText(QCoreApplication::translate("Form", "fileicon", nullptr)); + fileandthemeicon->setText(QCoreApplication::translate("Form", "PushButton", nullptr)); + themeicon->setText(QCoreApplication::translate("Form", "PushButton", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/identifierpage.ui.h b/tests/auto/tools/uic/baseline/identifierpage.ui.h index c0d86de1b3..420d668fe9 100644 --- a/tests/auto/tools/uic/baseline/identifierpage.ui.h +++ b/tests/auto/tools/uic/baseline/identifierpage.ui.h @@ -89,10 +89,10 @@ public: void retranslateUi(QWidget *IdentifierPage) { - IdentifierPage->setWindowTitle(QApplication::translate("IdentifierPage", "Form", nullptr)); - identifierCheckBox->setText(QApplication::translate("IdentifierPage", "Create identifiers", nullptr)); - globalButton->setText(QApplication::translate("IdentifierPage", "Global prefix:", nullptr)); - fileNameButton->setText(QApplication::translate("IdentifierPage", "Inherit prefix from file names", nullptr)); + IdentifierPage->setWindowTitle(QCoreApplication::translate("IdentifierPage", "Form", nullptr)); + identifierCheckBox->setText(QCoreApplication::translate("IdentifierPage", "Create identifiers", nullptr)); + globalButton->setText(QCoreApplication::translate("IdentifierPage", "Global prefix:", nullptr)); + fileNameButton->setText(QCoreApplication::translate("IdentifierPage", "Inherit prefix from file names", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/imagedialog.ui.h b/tests/auto/tools/uic/baseline/imagedialog.ui.h index 78384a21e4..993652222d 100644 --- a/tests/auto/tools/uic/baseline/imagedialog.ui.h +++ b/tests/auto/tools/uic/baseline/imagedialog.ui.h @@ -196,14 +196,14 @@ public: void retranslateUi(QDialog *dialog) { - dialog->setWindowTitle(QApplication::translate("ImageDialog", "Create Image", nullptr)); - widthLabel->setText(QApplication::translate("ImageDialog", "Width:", nullptr)); - heightLabel->setText(QApplication::translate("ImageDialog", "Height:", nullptr)); - nameLineEdit->setText(QApplication::translate("ImageDialog", "Untitled image", nullptr)); - nameLabel->setText(QApplication::translate("ImageDialog", "Name:", nullptr)); - colorDepthLabel->setText(QApplication::translate("ImageDialog", "Color depth:", nullptr)); - okButton->setText(QApplication::translate("ImageDialog", "OK", nullptr)); - cancelButton->setText(QApplication::translate("ImageDialog", "Cancel", nullptr)); + dialog->setWindowTitle(QCoreApplication::translate("ImageDialog", "Create Image", nullptr)); + widthLabel->setText(QCoreApplication::translate("ImageDialog", "Width:", nullptr)); + heightLabel->setText(QCoreApplication::translate("ImageDialog", "Height:", nullptr)); + nameLineEdit->setText(QCoreApplication::translate("ImageDialog", "Untitled image", nullptr)); + nameLabel->setText(QCoreApplication::translate("ImageDialog", "Name:", nullptr)); + colorDepthLabel->setText(QCoreApplication::translate("ImageDialog", "Color depth:", nullptr)); + okButton->setText(QCoreApplication::translate("ImageDialog", "OK", nullptr)); + cancelButton->setText(QCoreApplication::translate("ImageDialog", "Cancel", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/inputpage.ui.h b/tests/auto/tools/uic/baseline/inputpage.ui.h index 26bcca1ca4..0cb4cce4f2 100644 --- a/tests/auto/tools/uic/baseline/inputpage.ui.h +++ b/tests/auto/tools/uic/baseline/inputpage.ui.h @@ -81,9 +81,9 @@ public: void retranslateUi(QWidget *InputPage) { - InputPage->setWindowTitle(QApplication::translate("InputPage", "Form", nullptr)); - label->setText(QApplication::translate("InputPage", "File name:", nullptr)); - browseButton->setText(QApplication::translate("InputPage", "...", nullptr)); + InputPage->setWindowTitle(QCoreApplication::translate("InputPage", "Form", nullptr)); + label->setText(QCoreApplication::translate("InputPage", "File name:", nullptr)); + browseButton->setText(QCoreApplication::translate("InputPage", "...", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/installdialog.ui.h b/tests/auto/tools/uic/baseline/installdialog.ui.h index 45a0431f15..b452971f19 100644 --- a/tests/auto/tools/uic/baseline/installdialog.ui.h +++ b/tests/auto/tools/uic/baseline/installdialog.ui.h @@ -120,13 +120,13 @@ public: void retranslateUi(QDialog *InstallDialog) { - InstallDialog->setWindowTitle(QApplication::translate("InstallDialog", "Install Documentation", nullptr)); - label->setText(QApplication::translate("InstallDialog", "Available Documentation:", nullptr)); - installButton->setText(QApplication::translate("InstallDialog", "Install", nullptr)); - cancelButton->setText(QApplication::translate("InstallDialog", "Cancel", nullptr)); - closeButton->setText(QApplication::translate("InstallDialog", "Close", nullptr)); - label_4->setText(QApplication::translate("InstallDialog", "Installation Path:", nullptr)); - browseButton->setText(QApplication::translate("InstallDialog", "...", nullptr)); + InstallDialog->setWindowTitle(QCoreApplication::translate("InstallDialog", "Install Documentation", nullptr)); + label->setText(QCoreApplication::translate("InstallDialog", "Available Documentation:", nullptr)); + installButton->setText(QCoreApplication::translate("InstallDialog", "Install", nullptr)); + cancelButton->setText(QCoreApplication::translate("InstallDialog", "Cancel", nullptr)); + closeButton->setText(QCoreApplication::translate("InstallDialog", "Close", nullptr)); + label_4->setText(QCoreApplication::translate("InstallDialog", "Installation Path:", nullptr)); + browseButton->setText(QCoreApplication::translate("InstallDialog", "...", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/languagesdialog.ui.h b/tests/auto/tools/uic/baseline/languagesdialog.ui.h index b04d8f1766..f605d942d4 100644 --- a/tests/auto/tools/uic/baseline/languagesdialog.ui.h +++ b/tests/auto/tools/uic/baseline/languagesdialog.ui.h @@ -108,39 +108,39 @@ public: void retranslateUi(QDialog *LanguagesDialog) { - LanguagesDialog->setWindowTitle(QApplication::translate("LanguagesDialog", "Auxiliary Languages", nullptr)); + LanguagesDialog->setWindowTitle(QCoreApplication::translate("LanguagesDialog", "Auxiliary Languages", nullptr)); QTreeWidgetItem *___qtreewidgetitem = languagesList->headerItem(); - ___qtreewidgetitem->setText(1, QApplication::translate("LanguagesDialog", "File", nullptr)); - ___qtreewidgetitem->setText(0, QApplication::translate("LanguagesDialog", "Locale", nullptr)); + ___qtreewidgetitem->setText(1, QCoreApplication::translate("LanguagesDialog", "File", nullptr)); + ___qtreewidgetitem->setText(0, QCoreApplication::translate("LanguagesDialog", "Locale", nullptr)); #if QT_CONFIG(tooltip) - upButton->setToolTip(QApplication::translate("LanguagesDialog", "\n" "

    Move selected language up

    ", nullptr)); #endif // QT_CONFIG(tooltip) - upButton->setText(QApplication::translate("LanguagesDialog", "up", nullptr)); + upButton->setText(QCoreApplication::translate("LanguagesDialog", "up", nullptr)); #if QT_CONFIG(tooltip) - downButton->setToolTip(QApplication::translate("LanguagesDialog", "\n" "

    Move selected language down

    ", nullptr)); #endif // QT_CONFIG(tooltip) - downButton->setText(QApplication::translate("LanguagesDialog", "down", nullptr)); + downButton->setText(QCoreApplication::translate("LanguagesDialog", "down", nullptr)); #if QT_CONFIG(tooltip) - removeButton->setToolTip(QApplication::translate("LanguagesDialog", "\n" "

    Remove selected language

    ", nullptr)); #endif // QT_CONFIG(tooltip) - removeButton->setText(QApplication::translate("LanguagesDialog", "remove", nullptr)); + removeButton->setText(QCoreApplication::translate("LanguagesDialog", "remove", nullptr)); #if QT_CONFIG(tooltip) - openFileButton->setToolTip(QApplication::translate("LanguagesDialog", "\n" "

    Open auxiliary language files

    ", nullptr)); #endif // QT_CONFIG(tooltip) - openFileButton->setText(QApplication::translate("LanguagesDialog", "...", nullptr)); - okButton->setText(QApplication::translate("LanguagesDialog", "OK", nullptr)); + openFileButton->setText(QCoreApplication::translate("LanguagesDialog", "...", nullptr)); + okButton->setText(QCoreApplication::translate("LanguagesDialog", "OK", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/listwidgeteditor.ui.h b/tests/auto/tools/uic/baseline/listwidgeteditor.ui.h index 56df9f1beb..721d4c9950 100644 --- a/tests/auto/tools/uic/baseline/listwidgeteditor.ui.h +++ b/tests/auto/tools/uic/baseline/listwidgeteditor.ui.h @@ -172,28 +172,28 @@ public: void retranslateUi(QDialog *qdesigner_internal__ListWidgetEditor) { - qdesigner_internal__ListWidgetEditor->setWindowTitle(QApplication::translate("qdesigner_internal::ListWidgetEditor", "Dialog", nullptr)); - groupBox->setTitle(QApplication::translate("qdesigner_internal::ListWidgetEditor", "Items List", nullptr)); + qdesigner_internal__ListWidgetEditor->setWindowTitle(QCoreApplication::translate("qdesigner_internal::ListWidgetEditor", "Dialog", nullptr)); + groupBox->setTitle(QCoreApplication::translate("qdesigner_internal::ListWidgetEditor", "Items List", nullptr)); #if QT_CONFIG(tooltip) - listWidget->setToolTip(QApplication::translate("qdesigner_internal::ListWidgetEditor", "Items List", nullptr)); + listWidget->setToolTip(QCoreApplication::translate("qdesigner_internal::ListWidgetEditor", "Items List", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(tooltip) - newItemButton->setToolTip(QApplication::translate("qdesigner_internal::ListWidgetEditor", "New Item", nullptr)); + newItemButton->setToolTip(QCoreApplication::translate("qdesigner_internal::ListWidgetEditor", "New Item", nullptr)); #endif // QT_CONFIG(tooltip) - newItemButton->setText(QApplication::translate("qdesigner_internal::ListWidgetEditor", "&New", nullptr)); + newItemButton->setText(QCoreApplication::translate("qdesigner_internal::ListWidgetEditor", "&New", nullptr)); #if QT_CONFIG(tooltip) - deleteItemButton->setToolTip(QApplication::translate("qdesigner_internal::ListWidgetEditor", "Delete Item", nullptr)); + deleteItemButton->setToolTip(QCoreApplication::translate("qdesigner_internal::ListWidgetEditor", "Delete Item", nullptr)); #endif // QT_CONFIG(tooltip) - deleteItemButton->setText(QApplication::translate("qdesigner_internal::ListWidgetEditor", "&Delete", nullptr)); + deleteItemButton->setText(QCoreApplication::translate("qdesigner_internal::ListWidgetEditor", "&Delete", nullptr)); #if QT_CONFIG(tooltip) - moveItemUpButton->setToolTip(QApplication::translate("qdesigner_internal::ListWidgetEditor", "Move Item Up", nullptr)); + moveItemUpButton->setToolTip(QCoreApplication::translate("qdesigner_internal::ListWidgetEditor", "Move Item Up", nullptr)); #endif // QT_CONFIG(tooltip) - moveItemUpButton->setText(QApplication::translate("qdesigner_internal::ListWidgetEditor", "U", nullptr)); + moveItemUpButton->setText(QCoreApplication::translate("qdesigner_internal::ListWidgetEditor", "U", nullptr)); #if QT_CONFIG(tooltip) - moveItemDownButton->setToolTip(QApplication::translate("qdesigner_internal::ListWidgetEditor", "Move Item Down", nullptr)); + moveItemDownButton->setToolTip(QCoreApplication::translate("qdesigner_internal::ListWidgetEditor", "Move Item Down", nullptr)); #endif // QT_CONFIG(tooltip) - moveItemDownButton->setText(QApplication::translate("qdesigner_internal::ListWidgetEditor", "D", nullptr)); - label->setText(QApplication::translate("qdesigner_internal::ListWidgetEditor", "Icon", nullptr)); + moveItemDownButton->setText(QCoreApplication::translate("qdesigner_internal::ListWidgetEditor", "D", nullptr)); + label->setText(QCoreApplication::translate("qdesigner_internal::ListWidgetEditor", "Icon", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/mainwindow.ui.h b/tests/auto/tools/uic/baseline/mainwindow.ui.h index ed13a49860..df61d57ceb 100644 --- a/tests/auto/tools/uic/baseline/mainwindow.ui.h +++ b/tests/auto/tools/uic/baseline/mainwindow.ui.h @@ -361,30 +361,30 @@ public: void retranslateUi(QMainWindow *MainWindow) { - MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MakeQPF", nullptr)); - actionAdd_Custom_Font->setText(QApplication::translate("MainWindow", "&Add Custom Font...", nullptr)); - action_Exit->setText(QApplication::translate("MainWindow", "&Exit", nullptr)); - groupBox->setTitle(QApplication::translate("MainWindow", "Font Properties", nullptr)); - label->setText(QApplication::translate("MainWindow", "Family:", nullptr)); - label_2->setText(QApplication::translate("MainWindow", "Pixel Size:", nullptr)); - label_7->setText(QApplication::translate("MainWindow", "Weight:", nullptr)); - italic->setText(QApplication::translate("MainWindow", "Italic", nullptr)); - groupBox_2->setTitle(QApplication::translate("MainWindow", "Glyph Coverage", nullptr)); - chooseFromCodePoints->setText(QApplication::translate("MainWindow", "Choose from Unicode Codepoints:", nullptr)); - selectAll->setText(QApplication::translate("MainWindow", "Select &All", nullptr)); - deselectAll->setText(QApplication::translate("MainWindow", "&Deselect All", nullptr)); - invertSelection->setText(QApplication::translate("MainWindow", "&Invert Selection", nullptr)); - chooseFromSampleFile->setText(QApplication::translate("MainWindow", "Choose from Sample Text File (UTF-8 Encoded):", nullptr)); - label_5->setText(QApplication::translate("MainWindow", "Path:", nullptr)); - browseSampleFile->setText(QApplication::translate("MainWindow", "Browse...", nullptr)); - charCount->setText(QApplication::translate("MainWindow", "TextLabel", nullptr)); - groupBox_3->setTitle(QApplication::translate("MainWindow", "Preview", nullptr)); - groupBox_4->setTitle(QApplication::translate("MainWindow", "Output Options", nullptr)); - label_3->setText(QApplication::translate("MainWindow", "Path:", nullptr)); - browsePath->setText(QApplication::translate("MainWindow", "Browse...", nullptr)); - label_4->setText(QApplication::translate("MainWindow", "Filename:", nullptr)); - generate->setText(QApplication::translate("MainWindow", "Generate Pre-Rendered Font...", nullptr)); - menuFile->setTitle(QApplication::translate("MainWindow", "File", nullptr)); + MainWindow->setWindowTitle(QCoreApplication::translate("MainWindow", "MakeQPF", nullptr)); + actionAdd_Custom_Font->setText(QCoreApplication::translate("MainWindow", "&Add Custom Font...", nullptr)); + action_Exit->setText(QCoreApplication::translate("MainWindow", "&Exit", nullptr)); + groupBox->setTitle(QCoreApplication::translate("MainWindow", "Font Properties", nullptr)); + label->setText(QCoreApplication::translate("MainWindow", "Family:", nullptr)); + label_2->setText(QCoreApplication::translate("MainWindow", "Pixel Size:", nullptr)); + label_7->setText(QCoreApplication::translate("MainWindow", "Weight:", nullptr)); + italic->setText(QCoreApplication::translate("MainWindow", "Italic", nullptr)); + groupBox_2->setTitle(QCoreApplication::translate("MainWindow", "Glyph Coverage", nullptr)); + chooseFromCodePoints->setText(QCoreApplication::translate("MainWindow", "Choose from Unicode Codepoints:", nullptr)); + selectAll->setText(QCoreApplication::translate("MainWindow", "Select &All", nullptr)); + deselectAll->setText(QCoreApplication::translate("MainWindow", "&Deselect All", nullptr)); + invertSelection->setText(QCoreApplication::translate("MainWindow", "&Invert Selection", nullptr)); + chooseFromSampleFile->setText(QCoreApplication::translate("MainWindow", "Choose from Sample Text File (UTF-8 Encoded):", nullptr)); + label_5->setText(QCoreApplication::translate("MainWindow", "Path:", nullptr)); + browseSampleFile->setText(QCoreApplication::translate("MainWindow", "Browse...", nullptr)); + charCount->setText(QCoreApplication::translate("MainWindow", "TextLabel", nullptr)); + groupBox_3->setTitle(QCoreApplication::translate("MainWindow", "Preview", nullptr)); + groupBox_4->setTitle(QCoreApplication::translate("MainWindow", "Output Options", nullptr)); + label_3->setText(QCoreApplication::translate("MainWindow", "Path:", nullptr)); + browsePath->setText(QCoreApplication::translate("MainWindow", "Browse...", nullptr)); + label_4->setText(QCoreApplication::translate("MainWindow", "Filename:", nullptr)); + generate->setText(QCoreApplication::translate("MainWindow", "Generate Pre-Rendered Font...", nullptr)); + menuFile->setTitle(QCoreApplication::translate("MainWindow", "File", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/mydialog.ui.h b/tests/auto/tools/uic/baseline/mydialog.ui.h index 940e13484a..e71927092f 100644 --- a/tests/auto/tools/uic/baseline/mydialog.ui.h +++ b/tests/auto/tools/uic/baseline/mydialog.ui.h @@ -56,11 +56,11 @@ public: void retranslateUi(QDialog *MyDialog) { - MyDialog->setWindowTitle(QApplication::translate("MyDialog", "Mach 2!", nullptr)); - aLabel->setText(QApplication::translate("MyDialog", "Join the life in the fastlane; - PCH enable your project today! -", nullptr)); - aButton->setText(QApplication::translate("MyDialog", "&Quit", nullptr)); + MyDialog->setWindowTitle(QCoreApplication::translate("MyDialog", "Mach 2!", nullptr)); + aLabel->setText(QCoreApplication::translate("MyDialog", "Join the life in the fastlane; - PCH enable your project today! -", nullptr)); + aButton->setText(QCoreApplication::translate("MyDialog", "&Quit", nullptr)); #if QT_CONFIG(shortcut) - aButton->setShortcut(QApplication::translate("MyDialog", "Alt+Q", nullptr)); + aButton->setShortcut(QCoreApplication::translate("MyDialog", "Alt+Q", nullptr)); #endif // QT_CONFIG(shortcut) } // retranslateUi diff --git a/tests/auto/tools/uic/baseline/myform.ui.h b/tests/auto/tools/uic/baseline/myform.ui.h index 20de979fb5..87d88e8246 100644 --- a/tests/auto/tools/uic/baseline/myform.ui.h +++ b/tests/auto/tools/uic/baseline/myform.ui.h @@ -120,17 +120,17 @@ public: void retranslateUi(QWidget *Form) { - Form->setWindowTitle(QApplication::translate("Form", "Export Document", nullptr)); - groupBox->setTitle(QApplication::translate("Form", "Export Options", nullptr)); - radioButton_2->setText(QApplication::translate("Form", "&DocBook", nullptr)); - radioButton->setText(QApplication::translate("Form", "&LaTeX", nullptr)); - checkBox_2->setText(QApplication::translate("Form", "Include p&ictures", nullptr)); - checkBox->setText(QApplication::translate("Form", "&Compress", nullptr)); - radioButton_2_2->setText(QApplication::translate("Form", "&HTML", nullptr)); - radioButton_3->setText(QApplication::translate("Form", "&PostScript", nullptr)); - radioButton_4->setText(QApplication::translate("Form", "PD&F", nullptr)); - checkBox_3->setText(QApplication::translate("Form", "Include &metadata", nullptr)); - checkBox_4->setText(QApplication::translate("Form", "Create inde&x", nullptr)); + Form->setWindowTitle(QCoreApplication::translate("Form", "Export Document", nullptr)); + groupBox->setTitle(QCoreApplication::translate("Form", "Export Options", nullptr)); + radioButton_2->setText(QCoreApplication::translate("Form", "&DocBook", nullptr)); + radioButton->setText(QCoreApplication::translate("Form", "&LaTeX", nullptr)); + checkBox_2->setText(QCoreApplication::translate("Form", "Include p&ictures", nullptr)); + checkBox->setText(QCoreApplication::translate("Form", "&Compress", nullptr)); + radioButton_2_2->setText(QCoreApplication::translate("Form", "&HTML", nullptr)); + radioButton_3->setText(QCoreApplication::translate("Form", "&PostScript", nullptr)); + radioButton_4->setText(QCoreApplication::translate("Form", "PD&F", nullptr)); + checkBox_3->setText(QCoreApplication::translate("Form", "Include &metadata", nullptr)); + checkBox_4->setText(QCoreApplication::translate("Form", "Create inde&x", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/newactiondialog.ui.h b/tests/auto/tools/uic/baseline/newactiondialog.ui.h index 6b8f8bb9d7..4b3b6bcf1a 100644 --- a/tests/auto/tools/uic/baseline/newactiondialog.ui.h +++ b/tests/auto/tools/uic/baseline/newactiondialog.ui.h @@ -159,10 +159,10 @@ public: void retranslateUi(QDialog *qdesigner_internal__NewActionDialog) { - qdesigner_internal__NewActionDialog->setWindowTitle(QApplication::translate("qdesigner_internal::NewActionDialog", "New Action...", nullptr)); - label->setText(QApplication::translate("qdesigner_internal::NewActionDialog", "&Text:", nullptr)); - label_3->setText(QApplication::translate("qdesigner_internal::NewActionDialog", "Object &name:", nullptr)); - label_2->setText(QApplication::translate("qdesigner_internal::NewActionDialog", "&Icon:", nullptr)); + qdesigner_internal__NewActionDialog->setWindowTitle(QCoreApplication::translate("qdesigner_internal::NewActionDialog", "New Action...", nullptr)); + label->setText(QCoreApplication::translate("qdesigner_internal::NewActionDialog", "&Text:", nullptr)); + label_3->setText(QCoreApplication::translate("qdesigner_internal::NewActionDialog", "Object &name:", nullptr)); + label_2->setText(QCoreApplication::translate("qdesigner_internal::NewActionDialog", "&Icon:", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/newdynamicpropertydialog.ui.h b/tests/auto/tools/uic/baseline/newdynamicpropertydialog.ui.h index 96b52a6549..406f8bc1a3 100644 --- a/tests/auto/tools/uic/baseline/newdynamicpropertydialog.ui.h +++ b/tests/auto/tools/uic/baseline/newdynamicpropertydialog.ui.h @@ -108,9 +108,9 @@ public: void retranslateUi(QDialog *qdesigner_internal__NewDynamicPropertyDialog) { - qdesigner_internal__NewDynamicPropertyDialog->setWindowTitle(QApplication::translate("qdesigner_internal::NewDynamicPropertyDialog", "Create Dynamic Property", nullptr)); - label->setText(QApplication::translate("qdesigner_internal::NewDynamicPropertyDialog", "Property Name", nullptr)); - label_2->setText(QApplication::translate("qdesigner_internal::NewDynamicPropertyDialog", "Property Type", nullptr)); + qdesigner_internal__NewDynamicPropertyDialog->setWindowTitle(QCoreApplication::translate("qdesigner_internal::NewDynamicPropertyDialog", "Create Dynamic Property", nullptr)); + label->setText(QCoreApplication::translate("qdesigner_internal::NewDynamicPropertyDialog", "Property Name", nullptr)); + label_2->setText(QCoreApplication::translate("qdesigner_internal::NewDynamicPropertyDialog", "Property Type", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/newform.ui.h b/tests/auto/tools/uic/baseline/newform.ui.h index ff4746a500..2f680f822f 100644 --- a/tests/auto/tools/uic/baseline/newform.ui.h +++ b/tests/auto/tools/uic/baseline/newform.ui.h @@ -132,11 +132,11 @@ public: void retranslateUi(QDialog *NewForm) { - NewForm->setWindowTitle(QApplication::translate("NewForm", "New Form", nullptr)); + NewForm->setWindowTitle(QCoreApplication::translate("NewForm", "New Form", nullptr)); QTreeWidgetItem *___qtreewidgetitem = treeWidget->headerItem(); - ___qtreewidgetitem->setText(0, QApplication::translate("NewForm", "0", nullptr)); - lblPreview->setText(QApplication::translate("NewForm", "Choose a template for a preview", nullptr)); - chkShowOnStartup->setText(QApplication::translate("NewForm", "Show this Dialog on Startup", nullptr)); + ___qtreewidgetitem->setText(0, QCoreApplication::translate("NewForm", "0", nullptr)); + lblPreview->setText(QCoreApplication::translate("NewForm", "Choose a template for a preview", nullptr)); + chkShowOnStartup->setText(QCoreApplication::translate("NewForm", "Show this Dialog on Startup", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/orderdialog.ui.h b/tests/auto/tools/uic/baseline/orderdialog.ui.h index 26dbacf133..532ec2d41c 100644 --- a/tests/auto/tools/uic/baseline/orderdialog.ui.h +++ b/tests/auto/tools/uic/baseline/orderdialog.ui.h @@ -130,13 +130,13 @@ public: void retranslateUi(QDialog *qdesigner_internal__OrderDialog) { - qdesigner_internal__OrderDialog->setWindowTitle(QApplication::translate("qdesigner_internal::OrderDialog", "Change Page Order", nullptr)); - groupBox->setTitle(QApplication::translate("qdesigner_internal::OrderDialog", "Page Order", nullptr)); + qdesigner_internal__OrderDialog->setWindowTitle(QCoreApplication::translate("qdesigner_internal::OrderDialog", "Change Page Order", nullptr)); + groupBox->setTitle(QCoreApplication::translate("qdesigner_internal::OrderDialog", "Page Order", nullptr)); #if QT_CONFIG(tooltip) - upButton->setToolTip(QApplication::translate("qdesigner_internal::OrderDialog", "Move page up", nullptr)); + upButton->setToolTip(QCoreApplication::translate("qdesigner_internal::OrderDialog", "Move page up", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(tooltip) - downButton->setToolTip(QApplication::translate("qdesigner_internal::OrderDialog", "Move page down", nullptr)); + downButton->setToolTip(QCoreApplication::translate("qdesigner_internal::OrderDialog", "Move page down", nullptr)); #endif // QT_CONFIG(tooltip) } // retranslateUi diff --git a/tests/auto/tools/uic/baseline/outputpage.ui.h b/tests/auto/tools/uic/baseline/outputpage.ui.h index 127f20d9fe..9d2593dc77 100644 --- a/tests/auto/tools/uic/baseline/outputpage.ui.h +++ b/tests/auto/tools/uic/baseline/outputpage.ui.h @@ -87,9 +87,9 @@ public: void retranslateUi(QWidget *OutputPage) { - OutputPage->setWindowTitle(QApplication::translate("OutputPage", "Form", nullptr)); - label->setText(QApplication::translate("OutputPage", "Project file name:", nullptr)); - label_2->setText(QApplication::translate("OutputPage", "Collection file name:", nullptr)); + OutputPage->setWindowTitle(QCoreApplication::translate("OutputPage", "Form", nullptr)); + label->setText(QCoreApplication::translate("OutputPage", "Project file name:", nullptr)); + label_2->setText(QCoreApplication::translate("OutputPage", "Collection file name:", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/pagefold.ui.h b/tests/auto/tools/uic/baseline/pagefold.ui.h index bcd11c14ff..a0594b7ec7 100644 --- a/tests/auto/tools/uic/baseline/pagefold.ui.h +++ b/tests/auto/tools/uic/baseline/pagefold.ui.h @@ -242,84 +242,84 @@ public: void retranslateUi(QMainWindow *MainWindow) { - MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", nullptr)); - exitAction->setText(QApplication::translate("MainWindow", "&Exit", nullptr)); - aboutQtAction->setText(QApplication::translate("MainWindow", "About Qt", nullptr)); - editStyleAction->setText(QApplication::translate("MainWindow", "Edit &Style", nullptr)); - aboutAction->setText(QApplication::translate("MainWindow", "About", nullptr)); - nameCombo->setItemText(0, QApplication::translate("MainWindow", "Girish", nullptr)); - nameCombo->setItemText(1, QApplication::translate("MainWindow", "Jasmin", nullptr)); - nameCombo->setItemText(2, QApplication::translate("MainWindow", "Simon", nullptr)); - nameCombo->setItemText(3, QApplication::translate("MainWindow", "Zack", nullptr)); + MainWindow->setWindowTitle(QCoreApplication::translate("MainWindow", "MainWindow", nullptr)); + exitAction->setText(QCoreApplication::translate("MainWindow", "&Exit", nullptr)); + aboutQtAction->setText(QCoreApplication::translate("MainWindow", "About Qt", nullptr)); + editStyleAction->setText(QCoreApplication::translate("MainWindow", "Edit &Style", nullptr)); + aboutAction->setText(QCoreApplication::translate("MainWindow", "About", nullptr)); + nameCombo->setItemText(0, QCoreApplication::translate("MainWindow", "Girish", nullptr)); + nameCombo->setItemText(1, QCoreApplication::translate("MainWindow", "Jasmin", nullptr)); + nameCombo->setItemText(2, QCoreApplication::translate("MainWindow", "Simon", nullptr)); + nameCombo->setItemText(3, QCoreApplication::translate("MainWindow", "Zack", nullptr)); #if QT_CONFIG(tooltip) - nameCombo->setToolTip(QApplication::translate("MainWindow", "Specify your name", nullptr)); + nameCombo->setToolTip(QCoreApplication::translate("MainWindow", "Specify your name", nullptr)); #endif // QT_CONFIG(tooltip) - femaleRadioButton->setStyleSheet(QApplication::translate("MainWindow", "Check this if you are female", nullptr)); - femaleRadioButton->setText(QApplication::translate("MainWindow", "&Female", nullptr)); - genderLabel->setText(QApplication::translate("MainWindow", "Gender:", nullptr)); - ageLabel->setText(QApplication::translate("MainWindow", "&Age:", nullptr)); + femaleRadioButton->setStyleSheet(QCoreApplication::translate("MainWindow", "Check this if you are female", nullptr)); + femaleRadioButton->setText(QCoreApplication::translate("MainWindow", "&Female", nullptr)); + genderLabel->setText(QCoreApplication::translate("MainWindow", "Gender:", nullptr)); + ageLabel->setText(QCoreApplication::translate("MainWindow", "&Age:", nullptr)); #if QT_CONFIG(tooltip) - maleRadioButton->setToolTip(QApplication::translate("MainWindow", "Check this if you are male", nullptr)); + maleRadioButton->setToolTip(QCoreApplication::translate("MainWindow", "Check this if you are male", nullptr)); #endif // QT_CONFIG(tooltip) - maleRadioButton->setText(QApplication::translate("MainWindow", "&Male", nullptr)); - nameLabel->setText(QApplication::translate("MainWindow", "&Name:", nullptr)); - passwordLabel->setText(QApplication::translate("MainWindow", "&Password:", nullptr)); + maleRadioButton->setText(QCoreApplication::translate("MainWindow", "&Male", nullptr)); + nameLabel->setText(QCoreApplication::translate("MainWindow", "&Name:", nullptr)); + passwordLabel->setText(QCoreApplication::translate("MainWindow", "&Password:", nullptr)); #if QT_CONFIG(tooltip) - ageSpinBox->setToolTip(QApplication::translate("MainWindow", "Specify your age", nullptr)); + ageSpinBox->setToolTip(QCoreApplication::translate("MainWindow", "Specify your age", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(statustip) - ageSpinBox->setStatusTip(QApplication::translate("MainWindow", "Specify your age", nullptr)); + ageSpinBox->setStatusTip(QCoreApplication::translate("MainWindow", "Specify your age", nullptr)); #endif // QT_CONFIG(statustip) #if QT_CONFIG(tooltip) - agreeCheckBox->setToolTip(QApplication::translate("MainWindow", "Please read the LICENSE file before checking", nullptr)); + agreeCheckBox->setToolTip(QCoreApplication::translate("MainWindow", "Please read the LICENSE file before checking", nullptr)); #endif // QT_CONFIG(tooltip) - agreeCheckBox->setText(QApplication::translate("MainWindow", "I &accept the terms and &conditions", nullptr)); + agreeCheckBox->setText(QCoreApplication::translate("MainWindow", "I &accept the terms and &conditions", nullptr)); #if QT_CONFIG(tooltip) - passwordEdit->setToolTip(QApplication::translate("MainWindow", "Specify your password", nullptr)); + passwordEdit->setToolTip(QCoreApplication::translate("MainWindow", "Specify your password", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(statustip) - passwordEdit->setStatusTip(QApplication::translate("MainWindow", "Specify your password", nullptr)); + passwordEdit->setStatusTip(QCoreApplication::translate("MainWindow", "Specify your password", nullptr)); #endif // QT_CONFIG(statustip) - passwordEdit->setText(QApplication::translate("MainWindow", "Password", nullptr)); + passwordEdit->setText(QCoreApplication::translate("MainWindow", "Password", nullptr)); const bool __sortingEnabled = professionList->isSortingEnabled(); professionList->setSortingEnabled(false); QListWidgetItem *___qlistwidgetitem = professionList->item(0); - ___qlistwidgetitem->setText(QApplication::translate("MainWindow", "Developer", nullptr)); + ___qlistwidgetitem->setText(QCoreApplication::translate("MainWindow", "Developer", nullptr)); QListWidgetItem *___qlistwidgetitem1 = professionList->item(1); - ___qlistwidgetitem1->setText(QApplication::translate("MainWindow", "Student", nullptr)); + ___qlistwidgetitem1->setText(QCoreApplication::translate("MainWindow", "Student", nullptr)); QListWidgetItem *___qlistwidgetitem2 = professionList->item(2); - ___qlistwidgetitem2->setText(QApplication::translate("MainWindow", "Fisherman", nullptr)); + ___qlistwidgetitem2->setText(QCoreApplication::translate("MainWindow", "Fisherman", nullptr)); professionList->setSortingEnabled(__sortingEnabled); #if QT_CONFIG(tooltip) - professionList->setToolTip(QApplication::translate("MainWindow", "Select your profession", nullptr)); + professionList->setToolTip(QCoreApplication::translate("MainWindow", "Select your profession", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(statustip) - professionList->setStatusTip(QApplication::translate("MainWindow", "Specify your name here", nullptr)); + professionList->setStatusTip(QCoreApplication::translate("MainWindow", "Specify your name here", nullptr)); #endif // QT_CONFIG(statustip) #if QT_CONFIG(whatsthis) - professionList->setWhatsThis(QApplication::translate("MainWindow", "Specify your name here", nullptr)); + professionList->setWhatsThis(QCoreApplication::translate("MainWindow", "Specify your name here", nullptr)); #endif // QT_CONFIG(whatsthis) - label->setText(QApplication::translate("MainWindow", "Profession:", nullptr)); - countryCombo->setItemText(0, QApplication::translate("MainWindow", "Egypt", nullptr)); - countryCombo->setItemText(1, QApplication::translate("MainWindow", "France", nullptr)); - countryCombo->setItemText(2, QApplication::translate("MainWindow", "Germany", nullptr)); - countryCombo->setItemText(3, QApplication::translate("MainWindow", "India", nullptr)); - countryCombo->setItemText(4, QApplication::translate("MainWindow", "Italy", nullptr)); - countryCombo->setItemText(5, QApplication::translate("MainWindow", "Korea", nullptr)); - countryCombo->setItemText(6, QApplication::translate("MainWindow", "Norway", nullptr)); + label->setText(QCoreApplication::translate("MainWindow", "Profession:", nullptr)); + countryCombo->setItemText(0, QCoreApplication::translate("MainWindow", "Egypt", nullptr)); + countryCombo->setItemText(1, QCoreApplication::translate("MainWindow", "France", nullptr)); + countryCombo->setItemText(2, QCoreApplication::translate("MainWindow", "Germany", nullptr)); + countryCombo->setItemText(3, QCoreApplication::translate("MainWindow", "India", nullptr)); + countryCombo->setItemText(4, QCoreApplication::translate("MainWindow", "Italy", nullptr)); + countryCombo->setItemText(5, QCoreApplication::translate("MainWindow", "Korea", nullptr)); + countryCombo->setItemText(6, QCoreApplication::translate("MainWindow", "Norway", nullptr)); #if QT_CONFIG(tooltip) - countryCombo->setToolTip(QApplication::translate("MainWindow", "Specify country of origin", nullptr)); + countryCombo->setToolTip(QCoreApplication::translate("MainWindow", "Specify country of origin", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(statustip) - countryCombo->setStatusTip(QApplication::translate("MainWindow", "Specify country of origin", nullptr)); + countryCombo->setStatusTip(QCoreApplication::translate("MainWindow", "Specify country of origin", nullptr)); #endif // QT_CONFIG(statustip) - countryLabel->setText(QApplication::translate("MainWindow", "Pro&fession", nullptr)); - menu_File->setTitle(QApplication::translate("MainWindow", "&File", nullptr)); - menu_Help->setTitle(QApplication::translate("MainWindow", "&Help", nullptr)); + countryLabel->setText(QCoreApplication::translate("MainWindow", "Pro&fession", nullptr)); + menu_File->setTitle(QCoreApplication::translate("MainWindow", "&File", nullptr)); + menu_Help->setTitle(QCoreApplication::translate("MainWindow", "&Help", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/paletteeditor.ui.h b/tests/auto/tools/uic/baseline/paletteeditor.ui.h index 9be067eec3..0d0ef75cf9 100644 --- a/tests/auto/tools/uic/baseline/paletteeditor.ui.h +++ b/tests/auto/tools/uic/baseline/paletteeditor.ui.h @@ -197,16 +197,16 @@ public: void retranslateUi(QDialog *qdesigner_internal__PaletteEditor) { - qdesigner_internal__PaletteEditor->setWindowTitle(QApplication::translate("qdesigner_internal::PaletteEditor", "Edit Palette", nullptr)); - advancedBox->setTitle(QApplication::translate("qdesigner_internal::PaletteEditor", "Tune Palette", nullptr)); + qdesigner_internal__PaletteEditor->setWindowTitle(QCoreApplication::translate("qdesigner_internal::PaletteEditor", "Edit Palette", nullptr)); + advancedBox->setTitle(QCoreApplication::translate("qdesigner_internal::PaletteEditor", "Tune Palette", nullptr)); buildButton->setText(QString()); - detailsRadio->setText(QApplication::translate("qdesigner_internal::PaletteEditor", "Show Details", nullptr)); - computeRadio->setText(QApplication::translate("qdesigner_internal::PaletteEditor", "Compute Details", nullptr)); - label->setText(QApplication::translate("qdesigner_internal::PaletteEditor", "Quick", nullptr)); - GroupBox126->setTitle(QApplication::translate("qdesigner_internal::PaletteEditor", "Preview", nullptr)); - disabledRadio->setText(QApplication::translate("qdesigner_internal::PaletteEditor", "Disabled", nullptr)); - inactiveRadio->setText(QApplication::translate("qdesigner_internal::PaletteEditor", "Inactive", nullptr)); - activeRadio->setText(QApplication::translate("qdesigner_internal::PaletteEditor", "Active", nullptr)); + detailsRadio->setText(QCoreApplication::translate("qdesigner_internal::PaletteEditor", "Show Details", nullptr)); + computeRadio->setText(QCoreApplication::translate("qdesigner_internal::PaletteEditor", "Compute Details", nullptr)); + label->setText(QCoreApplication::translate("qdesigner_internal::PaletteEditor", "Quick", nullptr)); + GroupBox126->setTitle(QCoreApplication::translate("qdesigner_internal::PaletteEditor", "Preview", nullptr)); + disabledRadio->setText(QCoreApplication::translate("qdesigner_internal::PaletteEditor", "Disabled", nullptr)); + inactiveRadio->setText(QCoreApplication::translate("qdesigner_internal::PaletteEditor", "Inactive", nullptr)); + activeRadio->setText(QCoreApplication::translate("qdesigner_internal::PaletteEditor", "Active", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/passworddialog.ui.h b/tests/auto/tools/uic/baseline/passworddialog.ui.h index 4f59efabb9..0542098ec2 100644 --- a/tests/auto/tools/uic/baseline/passworddialog.ui.h +++ b/tests/auto/tools/uic/baseline/passworddialog.ui.h @@ -98,11 +98,11 @@ public: void retranslateUi(QDialog *PasswordDialog) { - PasswordDialog->setWindowTitle(QApplication::translate("PasswordDialog", "Authentication Required", nullptr)); - iconLabel->setText(QApplication::translate("PasswordDialog", "DUMMY ICON", nullptr)); - introLabel->setText(QApplication::translate("PasswordDialog", "INTRO TEXT DUMMY", nullptr)); - label->setText(QApplication::translate("PasswordDialog", "Username:", nullptr)); - lblPassword->setText(QApplication::translate("PasswordDialog", "Password:", nullptr)); + PasswordDialog->setWindowTitle(QCoreApplication::translate("PasswordDialog", "Authentication Required", nullptr)); + iconLabel->setText(QCoreApplication::translate("PasswordDialog", "DUMMY ICON", nullptr)); + introLabel->setText(QCoreApplication::translate("PasswordDialog", "INTRO TEXT DUMMY", nullptr)); + label->setText(QCoreApplication::translate("PasswordDialog", "Username:", nullptr)); + lblPassword->setText(QCoreApplication::translate("PasswordDialog", "Password:", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/pathpage.ui.h b/tests/auto/tools/uic/baseline/pathpage.ui.h index b71f76e3a5..bc9f254965 100644 --- a/tests/auto/tools/uic/baseline/pathpage.ui.h +++ b/tests/auto/tools/uic/baseline/pathpage.ui.h @@ -104,11 +104,11 @@ public: void retranslateUi(QWidget *PathPage) { - PathPage->setWindowTitle(QApplication::translate("PathPage", "Form", nullptr)); - label_2->setText(QApplication::translate("PathPage", "File filters:", nullptr)); - label->setText(QApplication::translate("PathPage", "Documentation source file paths:", nullptr)); - addButton->setText(QApplication::translate("PathPage", "Add", nullptr)); - removeButton->setText(QApplication::translate("PathPage", "Remove", nullptr)); + PathPage->setWindowTitle(QCoreApplication::translate("PathPage", "Form", nullptr)); + label_2->setText(QCoreApplication::translate("PathPage", "File filters:", nullptr)); + label->setText(QCoreApplication::translate("PathPage", "Documentation source file paths:", nullptr)); + addButton->setText(QCoreApplication::translate("PathPage", "Add", nullptr)); + removeButton->setText(QCoreApplication::translate("PathPage", "Remove", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/phrasebookbox.ui.h b/tests/auto/tools/uic/baseline/phrasebookbox.ui.h index 9d7d5e8983..25989c4bd3 100644 --- a/tests/auto/tools/uic/baseline/phrasebookbox.ui.h +++ b/tests/auto/tools/uic/baseline/phrasebookbox.ui.h @@ -184,38 +184,38 @@ public: void retranslateUi(QDialog *PhraseBookBox) { - PhraseBookBox->setWindowTitle(QApplication::translate("PhraseBookBox", "Edit Phrase Book", nullptr)); + PhraseBookBox->setWindowTitle(QCoreApplication::translate("PhraseBookBox", "Edit Phrase Book", nullptr)); #if QT_CONFIG(whatsthis) - PhraseBookBox->setWhatsThis(QApplication::translate("PhraseBookBox", "This window allows you to add, modify, or delete phrases in a phrase book.", nullptr)); + PhraseBookBox->setWhatsThis(QCoreApplication::translate("PhraseBookBox", "This window allows you to add, modify, or delete phrases in a phrase book.", nullptr)); #endif // QT_CONFIG(whatsthis) - target->setText(QApplication::translate("PhraseBookBox", "&Translation:", nullptr)); + target->setText(QCoreApplication::translate("PhraseBookBox", "&Translation:", nullptr)); #if QT_CONFIG(whatsthis) - targetLed->setWhatsThis(QApplication::translate("PhraseBookBox", "This is the phrase in the target language corresponding to the source phrase.", nullptr)); + targetLed->setWhatsThis(QCoreApplication::translate("PhraseBookBox", "This is the phrase in the target language corresponding to the source phrase.", nullptr)); #endif // QT_CONFIG(whatsthis) - source->setText(QApplication::translate("PhraseBookBox", "S&ource phrase:", nullptr)); + source->setText(QCoreApplication::translate("PhraseBookBox", "S&ource phrase:", nullptr)); #if QT_CONFIG(whatsthis) - definitionLed->setWhatsThis(QApplication::translate("PhraseBookBox", "This is a definition for the source phrase.", nullptr)); + definitionLed->setWhatsThis(QCoreApplication::translate("PhraseBookBox", "This is a definition for the source phrase.", nullptr)); #endif // QT_CONFIG(whatsthis) #if QT_CONFIG(whatsthis) - sourceLed->setWhatsThis(QApplication::translate("PhraseBookBox", "This is the phrase in the source language.", nullptr)); + sourceLed->setWhatsThis(QCoreApplication::translate("PhraseBookBox", "This is the phrase in the source language.", nullptr)); #endif // QT_CONFIG(whatsthis) - definition->setText(QApplication::translate("PhraseBookBox", "&Definition:", nullptr)); + definition->setText(QCoreApplication::translate("PhraseBookBox", "&Definition:", nullptr)); #if QT_CONFIG(whatsthis) - newBut->setWhatsThis(QApplication::translate("PhraseBookBox", "Click here to add the phrase to the phrase book.", nullptr)); + newBut->setWhatsThis(QCoreApplication::translate("PhraseBookBox", "Click here to add the phrase to the phrase book.", nullptr)); #endif // QT_CONFIG(whatsthis) - newBut->setText(QApplication::translate("PhraseBookBox", "&New Phrase", nullptr)); + newBut->setText(QCoreApplication::translate("PhraseBookBox", "&New Phrase", nullptr)); #if QT_CONFIG(whatsthis) - removeBut->setWhatsThis(QApplication::translate("PhraseBookBox", "Click here to remove the phrase from the phrase book.", nullptr)); + removeBut->setWhatsThis(QCoreApplication::translate("PhraseBookBox", "Click here to remove the phrase from the phrase book.", nullptr)); #endif // QT_CONFIG(whatsthis) - removeBut->setText(QApplication::translate("PhraseBookBox", "&Remove Phrase", nullptr)); + removeBut->setText(QCoreApplication::translate("PhraseBookBox", "&Remove Phrase", nullptr)); #if QT_CONFIG(whatsthis) - saveBut->setWhatsThis(QApplication::translate("PhraseBookBox", "Click here to save the changes made.", nullptr)); + saveBut->setWhatsThis(QCoreApplication::translate("PhraseBookBox", "Click here to save the changes made.", nullptr)); #endif // QT_CONFIG(whatsthis) - saveBut->setText(QApplication::translate("PhraseBookBox", "&Save", nullptr)); + saveBut->setText(QCoreApplication::translate("PhraseBookBox", "&Save", nullptr)); #if QT_CONFIG(whatsthis) - closeBut->setWhatsThis(QApplication::translate("PhraseBookBox", "Click here to close this window.", nullptr)); + closeBut->setWhatsThis(QCoreApplication::translate("PhraseBookBox", "Click here to close this window.", nullptr)); #endif // QT_CONFIG(whatsthis) - closeBut->setText(QApplication::translate("PhraseBookBox", "Close", nullptr)); + closeBut->setText(QCoreApplication::translate("PhraseBookBox", "Close", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/pixmapfunction.ui.h b/tests/auto/tools/uic/baseline/pixmapfunction.ui.h index 1644380c15..5a24aeeded 100644 --- a/tests/auto/tools/uic/baseline/pixmapfunction.ui.h +++ b/tests/auto/tools/uic/baseline/pixmapfunction.ui.h @@ -58,9 +58,9 @@ public: void retranslateUi(QWidget *Form) { - Form->setWindowTitle(QApplication::translate("Form", "Form", nullptr)); + Form->setWindowTitle(QCoreApplication::translate("Form", "Form", nullptr)); label->setText(QString()); - pushButton->setText(QApplication::translate("Form", "PushButton", nullptr)); + pushButton->setText(QCoreApplication::translate("Form", "PushButton", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/plugindialog.ui.h b/tests/auto/tools/uic/baseline/plugindialog.ui.h index d25bfd1316..72e4d22b78 100644 --- a/tests/auto/tools/uic/baseline/plugindialog.ui.h +++ b/tests/auto/tools/uic/baseline/plugindialog.ui.h @@ -111,11 +111,11 @@ public: void retranslateUi(QDialog *PluginDialog) { - PluginDialog->setWindowTitle(QApplication::translate("PluginDialog", "Plugin Information", nullptr)); - label->setText(QApplication::translate("PluginDialog", "TextLabel", nullptr)); + PluginDialog->setWindowTitle(QCoreApplication::translate("PluginDialog", "Plugin Information", nullptr)); + label->setText(QCoreApplication::translate("PluginDialog", "TextLabel", nullptr)); QTreeWidgetItem *___qtreewidgetitem = treeWidget->headerItem(); - ___qtreewidgetitem->setText(0, QApplication::translate("PluginDialog", "1", nullptr)); - message->setText(QApplication::translate("PluginDialog", "TextLabel", nullptr)); + ___qtreewidgetitem->setText(0, QCoreApplication::translate("PluginDialog", "1", nullptr)); + message->setText(QCoreApplication::translate("PluginDialog", "TextLabel", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/preferencesdialog.ui.h b/tests/auto/tools/uic/baseline/preferencesdialog.ui.h index d81823fe75..c4002eaff7 100644 --- a/tests/auto/tools/uic/baseline/preferencesdialog.ui.h +++ b/tests/auto/tools/uic/baseline/preferencesdialog.ui.h @@ -150,11 +150,11 @@ public: void retranslateUi(QDialog *PreferencesDialog) { - PreferencesDialog->setWindowTitle(QApplication::translate("PreferencesDialog", "Preferences", nullptr)); - m_uiModeGroupBox->setTitle(QApplication::translate("PreferencesDialog", "User Interface Mode", nullptr)); - m_templatePathGroupBox->setTitle(QApplication::translate("PreferencesDialog", "Additional Template Paths", nullptr)); - m_addTemplatePathButton->setText(QApplication::translate("PreferencesDialog", "...", nullptr)); - m_removeTemplatePathButton->setText(QApplication::translate("PreferencesDialog", "...", nullptr)); + PreferencesDialog->setWindowTitle(QCoreApplication::translate("PreferencesDialog", "Preferences", nullptr)); + m_uiModeGroupBox->setTitle(QCoreApplication::translate("PreferencesDialog", "User Interface Mode", nullptr)); + m_templatePathGroupBox->setTitle(QCoreApplication::translate("PreferencesDialog", "Additional Template Paths", nullptr)); + m_addTemplatePathButton->setText(QCoreApplication::translate("PreferencesDialog", "...", nullptr)); + m_removeTemplatePathButton->setText(QCoreApplication::translate("PreferencesDialog", "...", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/previewconfigurationwidget.ui.h b/tests/auto/tools/uic/baseline/previewconfigurationwidget.ui.h index cabdedeb97..71e8605832 100644 --- a/tests/auto/tools/uic/baseline/previewconfigurationwidget.ui.h +++ b/tests/auto/tools/uic/baseline/previewconfigurationwidget.ui.h @@ -108,14 +108,14 @@ public: void retranslateUi(QGroupBox *PreviewConfigurationWidget) { - PreviewConfigurationWidget->setWindowTitle(QApplication::translate("PreviewConfigurationWidget", "Form", nullptr)); - PreviewConfigurationWidget->setTitle(QApplication::translate("PreviewConfigurationWidget", "Print/Preview Configuration", nullptr)); - m_styleLabel->setText(QApplication::translate("PreviewConfigurationWidget", "Style", nullptr)); - m_appStyleSheetLabel->setText(QApplication::translate("PreviewConfigurationWidget", "Style sheet", nullptr)); - m_appStyleSheetChangeButton->setText(QApplication::translate("PreviewConfigurationWidget", "...", nullptr)); - m_appStyleSheetClearButton->setText(QApplication::translate("PreviewConfigurationWidget", "...", nullptr)); - m_skinLabel->setText(QApplication::translate("PreviewConfigurationWidget", "Device skin", nullptr)); - m_skinRemoveButton->setText(QApplication::translate("PreviewConfigurationWidget", "...", nullptr)); + PreviewConfigurationWidget->setWindowTitle(QCoreApplication::translate("PreviewConfigurationWidget", "Form", nullptr)); + PreviewConfigurationWidget->setTitle(QCoreApplication::translate("PreviewConfigurationWidget", "Print/Preview Configuration", nullptr)); + m_styleLabel->setText(QCoreApplication::translate("PreviewConfigurationWidget", "Style", nullptr)); + m_appStyleSheetLabel->setText(QCoreApplication::translate("PreviewConfigurationWidget", "Style sheet", nullptr)); + m_appStyleSheetChangeButton->setText(QCoreApplication::translate("PreviewConfigurationWidget", "...", nullptr)); + m_appStyleSheetClearButton->setText(QCoreApplication::translate("PreviewConfigurationWidget", "...", nullptr)); + m_skinLabel->setText(QCoreApplication::translate("PreviewConfigurationWidget", "Device skin", nullptr)); + m_skinRemoveButton->setText(QCoreApplication::translate("PreviewConfigurationWidget", "...", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/previewdialogbase.ui.h b/tests/auto/tools/uic/baseline/previewdialogbase.ui.h index 7c86215077..25017bced0 100644 --- a/tests/auto/tools/uic/baseline/previewdialogbase.ui.h +++ b/tests/auto/tools/uic/baseline/previewdialogbase.ui.h @@ -170,11 +170,11 @@ public: void retranslateUi(QDialog *PreviewDialogBase) { - PreviewDialogBase->setWindowTitle(QApplication::translate("PreviewDialogBase", "Print Preview", nullptr)); - label->setText(QApplication::translate("PreviewDialogBase", "&Paper Size:", nullptr)); - label_2->setText(QApplication::translate("PreviewDialogBase", "&Orientation:", nullptr)); + PreviewDialogBase->setWindowTitle(QCoreApplication::translate("PreviewDialogBase", "Print Preview", nullptr)); + label->setText(QCoreApplication::translate("PreviewDialogBase", "&Paper Size:", nullptr)); + label_2->setText(QCoreApplication::translate("PreviewDialogBase", "&Orientation:", nullptr)); QTreeWidgetItem *___qtreewidgetitem = pageList->headerItem(); - ___qtreewidgetitem->setText(0, QApplication::translate("PreviewDialogBase", "1", nullptr)); + ___qtreewidgetitem->setText(0, QCoreApplication::translate("PreviewDialogBase", "1", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/previewwidget.ui.h b/tests/auto/tools/uic/baseline/previewwidget.ui.h index a423ee7ff4..2d883e984f 100644 --- a/tests/auto/tools/uic/baseline/previewwidget.ui.h +++ b/tests/auto/tools/uic/baseline/previewwidget.ui.h @@ -235,18 +235,18 @@ public: void retranslateUi(QWidget *qdesigner_internal__PreviewWidget) { - qdesigner_internal__PreviewWidget->setWindowTitle(QApplication::translate("qdesigner_internal::PreviewWidget", "Preview Window", nullptr)); - LineEdit1->setText(QApplication::translate("qdesigner_internal::PreviewWidget", "LineEdit", nullptr)); - ComboBox1->setItemText(0, QApplication::translate("qdesigner_internal::PreviewWidget", "ComboBox", nullptr)); + qdesigner_internal__PreviewWidget->setWindowTitle(QCoreApplication::translate("qdesigner_internal::PreviewWidget", "Preview Window", nullptr)); + LineEdit1->setText(QCoreApplication::translate("qdesigner_internal::PreviewWidget", "LineEdit", nullptr)); + ComboBox1->setItemText(0, QCoreApplication::translate("qdesigner_internal::PreviewWidget", "ComboBox", nullptr)); - PushButton1->setText(QApplication::translate("qdesigner_internal::PreviewWidget", "PushButton", nullptr)); - ButtonGroup2->setTitle(QApplication::translate("qdesigner_internal::PreviewWidget", "ButtonGroup2", nullptr)); - CheckBox1->setText(QApplication::translate("qdesigner_internal::PreviewWidget", "CheckBox1", nullptr)); - CheckBox2->setText(QApplication::translate("qdesigner_internal::PreviewWidget", "CheckBox2", nullptr)); - ButtonGroup1->setTitle(QApplication::translate("qdesigner_internal::PreviewWidget", "ButtonGroup", nullptr)); - RadioButton1->setText(QApplication::translate("qdesigner_internal::PreviewWidget", "RadioButton1", nullptr)); - RadioButton2->setText(QApplication::translate("qdesigner_internal::PreviewWidget", "RadioButton2", nullptr)); - RadioButton3->setText(QApplication::translate("qdesigner_internal::PreviewWidget", "RadioButton3", nullptr)); + PushButton1->setText(QCoreApplication::translate("qdesigner_internal::PreviewWidget", "PushButton", nullptr)); + ButtonGroup2->setTitle(QCoreApplication::translate("qdesigner_internal::PreviewWidget", "ButtonGroup2", nullptr)); + CheckBox1->setText(QCoreApplication::translate("qdesigner_internal::PreviewWidget", "CheckBox1", nullptr)); + CheckBox2->setText(QCoreApplication::translate("qdesigner_internal::PreviewWidget", "CheckBox2", nullptr)); + ButtonGroup1->setTitle(QCoreApplication::translate("qdesigner_internal::PreviewWidget", "ButtonGroup", nullptr)); + RadioButton1->setText(QCoreApplication::translate("qdesigner_internal::PreviewWidget", "RadioButton1", nullptr)); + RadioButton2->setText(QCoreApplication::translate("qdesigner_internal::PreviewWidget", "RadioButton2", nullptr)); + RadioButton3->setText(QCoreApplication::translate("qdesigner_internal::PreviewWidget", "RadioButton3", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/proxy.ui.h b/tests/auto/tools/uic/baseline/proxy.ui.h index 47a15cc31b..1ecea389f3 100644 --- a/tests/auto/tools/uic/baseline/proxy.ui.h +++ b/tests/auto/tools/uic/baseline/proxy.ui.h @@ -87,11 +87,11 @@ public: void retranslateUi(QDialog *ProxyDialog) { - ProxyDialog->setWindowTitle(QApplication::translate("ProxyDialog", "Proxy Authentication", nullptr)); - iconLabel->setText(QApplication::translate("ProxyDialog", "ICON", nullptr)); - introLabel->setText(QApplication::translate("ProxyDialog", "Connect to proxy", nullptr)); - usernameLabel->setText(QApplication::translate("ProxyDialog", "Username:", nullptr)); - passwordLabel->setText(QApplication::translate("ProxyDialog", "Password:", nullptr)); + ProxyDialog->setWindowTitle(QCoreApplication::translate("ProxyDialog", "Proxy Authentication", nullptr)); + iconLabel->setText(QCoreApplication::translate("ProxyDialog", "ICON", nullptr)); + introLabel->setText(QCoreApplication::translate("ProxyDialog", "Connect to proxy", nullptr)); + usernameLabel->setText(QCoreApplication::translate("ProxyDialog", "Username:", nullptr)); + passwordLabel->setText(QCoreApplication::translate("ProxyDialog", "Password:", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/qfiledialog.ui.h b/tests/auto/tools/uic/baseline/qfiledialog.ui.h index a544afa31d..9e51ee6a7c 100644 --- a/tests/auto/tools/uic/baseline/qfiledialog.ui.h +++ b/tests/auto/tools/uic/baseline/qfiledialog.ui.h @@ -271,26 +271,26 @@ public: void retranslateUi(QDialog *QFileDialog) { - lookInLabel->setText(QApplication::translate("QFileDialog", "Look in:", nullptr)); + lookInLabel->setText(QCoreApplication::translate("QFileDialog", "Look in:", nullptr)); #if QT_CONFIG(tooltip) - backButton->setToolTip(QApplication::translate("QFileDialog", "Back", nullptr)); + backButton->setToolTip(QCoreApplication::translate("QFileDialog", "Back", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(tooltip) - forwardButton->setToolTip(QApplication::translate("QFileDialog", "Forward", nullptr)); + forwardButton->setToolTip(QCoreApplication::translate("QFileDialog", "Forward", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(tooltip) - toParentButton->setToolTip(QApplication::translate("QFileDialog", "Parent Directory", nullptr)); + toParentButton->setToolTip(QCoreApplication::translate("QFileDialog", "Parent Directory", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(tooltip) - newFolderButton->setToolTip(QApplication::translate("QFileDialog", "Create New Folder", nullptr)); + newFolderButton->setToolTip(QCoreApplication::translate("QFileDialog", "Create New Folder", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(tooltip) - listModeButton->setToolTip(QApplication::translate("QFileDialog", "List View", nullptr)); + listModeButton->setToolTip(QCoreApplication::translate("QFileDialog", "List View", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(tooltip) - detailModeButton->setToolTip(QApplication::translate("QFileDialog", "Detail View", nullptr)); + detailModeButton->setToolTip(QCoreApplication::translate("QFileDialog", "Detail View", nullptr)); #endif // QT_CONFIG(tooltip) - fileTypeLabel->setText(QApplication::translate("QFileDialog", "Files of type:", nullptr)); + fileTypeLabel->setText(QCoreApplication::translate("QFileDialog", "Files of type:", nullptr)); Q_UNUSED(QFileDialog); } // retranslateUi diff --git a/tests/auto/tools/uic/baseline/qpagesetupwidget.ui.h b/tests/auto/tools/uic/baseline/qpagesetupwidget.ui.h index 4227f38187..d21d6da972 100644 --- a/tests/auto/tools/uic/baseline/qpagesetupwidget.ui.h +++ b/tests/auto/tools/uic/baseline/qpagesetupwidget.ui.h @@ -304,45 +304,45 @@ public: void retranslateUi(QWidget *QPageSetupWidget) { - QPageSetupWidget->setWindowTitle(QApplication::translate("QPageSetupWidget", "Form", nullptr)); - groupBox_2->setTitle(QApplication::translate("QPageSetupWidget", "Paper", nullptr)); - pageSizeLabel->setText(QApplication::translate("QPageSetupWidget", "Page size:", nullptr)); - widthLabel->setText(QApplication::translate("QPageSetupWidget", "Width:", nullptr)); - heightLabel->setText(QApplication::translate("QPageSetupWidget", "Height:", nullptr)); - paperSourceLabel->setText(QApplication::translate("QPageSetupWidget", "Paper source:", nullptr)); - groupBox_3->setTitle(QApplication::translate("QPageSetupWidget", "Orientation", nullptr)); - portrait->setText(QApplication::translate("QPageSetupWidget", "Portrait", nullptr)); - landscape->setText(QApplication::translate("QPageSetupWidget", "Landscape", nullptr)); - reverseLandscape->setText(QApplication::translate("QPageSetupWidget", "Reverse landscape", nullptr)); - reversePortrait->setText(QApplication::translate("QPageSetupWidget", "Reverse portrait", nullptr)); - groupBox->setTitle(QApplication::translate("QPageSetupWidget", "Margins", nullptr)); + QPageSetupWidget->setWindowTitle(QCoreApplication::translate("QPageSetupWidget", "Form", nullptr)); + groupBox_2->setTitle(QCoreApplication::translate("QPageSetupWidget", "Paper", nullptr)); + pageSizeLabel->setText(QCoreApplication::translate("QPageSetupWidget", "Page size:", nullptr)); + widthLabel->setText(QCoreApplication::translate("QPageSetupWidget", "Width:", nullptr)); + heightLabel->setText(QCoreApplication::translate("QPageSetupWidget", "Height:", nullptr)); + paperSourceLabel->setText(QCoreApplication::translate("QPageSetupWidget", "Paper source:", nullptr)); + groupBox_3->setTitle(QCoreApplication::translate("QPageSetupWidget", "Orientation", nullptr)); + portrait->setText(QCoreApplication::translate("QPageSetupWidget", "Portrait", nullptr)); + landscape->setText(QCoreApplication::translate("QPageSetupWidget", "Landscape", nullptr)); + reverseLandscape->setText(QCoreApplication::translate("QPageSetupWidget", "Reverse landscape", nullptr)); + reversePortrait->setText(QCoreApplication::translate("QPageSetupWidget", "Reverse portrait", nullptr)); + groupBox->setTitle(QCoreApplication::translate("QPageSetupWidget", "Margins", nullptr)); #if QT_CONFIG(tooltip) - topMargin->setToolTip(QApplication::translate("QPageSetupWidget", "top margin", nullptr)); + topMargin->setToolTip(QCoreApplication::translate("QPageSetupWidget", "top margin", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(accessibility) - topMargin->setAccessibleName(QApplication::translate("QPageSetupWidget", "top margin", nullptr)); + topMargin->setAccessibleName(QCoreApplication::translate("QPageSetupWidget", "top margin", nullptr)); #endif // QT_CONFIG(accessibility) #if QT_CONFIG(tooltip) - leftMargin->setToolTip(QApplication::translate("QPageSetupWidget", "left margin", nullptr)); + leftMargin->setToolTip(QCoreApplication::translate("QPageSetupWidget", "left margin", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(accessibility) - leftMargin->setAccessibleName(QApplication::translate("QPageSetupWidget", "left margin", nullptr)); + leftMargin->setAccessibleName(QCoreApplication::translate("QPageSetupWidget", "left margin", nullptr)); #endif // QT_CONFIG(accessibility) #if QT_CONFIG(tooltip) - rightMargin->setToolTip(QApplication::translate("QPageSetupWidget", "right margin", nullptr)); + rightMargin->setToolTip(QCoreApplication::translate("QPageSetupWidget", "right margin", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(accessibility) - rightMargin->setAccessibleName(QApplication::translate("QPageSetupWidget", "right margin", nullptr)); + rightMargin->setAccessibleName(QCoreApplication::translate("QPageSetupWidget", "right margin", nullptr)); #endif // QT_CONFIG(accessibility) #if QT_CONFIG(tooltip) - bottomMargin->setToolTip(QApplication::translate("QPageSetupWidget", "bottom margin", nullptr)); + bottomMargin->setToolTip(QCoreApplication::translate("QPageSetupWidget", "bottom margin", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(accessibility) - bottomMargin->setAccessibleName(QApplication::translate("QPageSetupWidget", "bottom margin", nullptr)); + bottomMargin->setAccessibleName(QCoreApplication::translate("QPageSetupWidget", "bottom margin", nullptr)); #endif // QT_CONFIG(accessibility) - pagesPerSheetButtonGroup->setTitle(QApplication::translate("QPageSetupWidget", "Page Layout", nullptr)); - label->setText(QApplication::translate("QPageSetupWidget", "Page order:", nullptr)); - label_2->setText(QApplication::translate("QPageSetupWidget", "Pages per sheet:", nullptr)); + pagesPerSheetButtonGroup->setTitle(QCoreApplication::translate("QPageSetupWidget", "Page Layout", nullptr)); + label->setText(QCoreApplication::translate("QPageSetupWidget", "Page order:", nullptr)); + label_2->setText(QCoreApplication::translate("QPageSetupWidget", "Pages per sheet:", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/qprintpropertieswidget.ui.h b/tests/auto/tools/uic/baseline/qprintpropertieswidget.ui.h index bedb6e184d..f0e06548b5 100644 --- a/tests/auto/tools/uic/baseline/qprintpropertieswidget.ui.h +++ b/tests/auto/tools/uic/baseline/qprintpropertieswidget.ui.h @@ -79,9 +79,9 @@ public: void retranslateUi(QWidget *QPrintPropertiesWidget) { - QPrintPropertiesWidget->setWindowTitle(QApplication::translate("QPrintPropertiesWidget", "Form", nullptr)); - tabs->setTabText(tabs->indexOf(tabPage), QApplication::translate("QPrintPropertiesWidget", "Page", nullptr)); - tabs->setTabText(tabs->indexOf(cupsPropertiesPage), QApplication::translate("QPrintPropertiesWidget", "Advanced", nullptr)); + QPrintPropertiesWidget->setWindowTitle(QCoreApplication::translate("QPrintPropertiesWidget", "Form", nullptr)); + tabs->setTabText(tabs->indexOf(tabPage), QCoreApplication::translate("QPrintPropertiesWidget", "Page", nullptr)); + tabs->setTabText(tabs->indexOf(cupsPropertiesPage), QCoreApplication::translate("QPrintPropertiesWidget", "Advanced", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/qprintsettingsoutput.ui.h b/tests/auto/tools/uic/baseline/qprintsettingsoutput.ui.h index 2bf7584a61..3d37a55548 100644 --- a/tests/auto/tools/uic/baseline/qprintsettingsoutput.ui.h +++ b/tests/auto/tools/uic/baseline/qprintsettingsoutput.ui.h @@ -276,25 +276,25 @@ public: void retranslateUi(QWidget *QPrintSettingsOutput) { - QPrintSettingsOutput->setWindowTitle(QApplication::translate("QPrintSettingsOutput", "Form", nullptr)); - gbPrintRange->setTitle(QApplication::translate("QPrintSettingsOutput", "Print range", nullptr)); - printAll->setText(QApplication::translate("QPrintSettingsOutput", "Print all", nullptr)); - printRange->setText(QApplication::translate("QPrintSettingsOutput", "Pages from", nullptr)); - label_3->setText(QApplication::translate("QPrintSettingsOutput", "to", nullptr)); - printSelection->setText(QApplication::translate("QPrintSettingsOutput", "Selection", nullptr)); - groupBox->setTitle(QApplication::translate("QPrintSettingsOutput", "Output Settings", nullptr)); - label->setText(QApplication::translate("QPrintSettingsOutput", "Copies:", nullptr)); - collate->setText(QApplication::translate("QPrintSettingsOutput", "Collate", nullptr)); - reverse->setText(QApplication::translate("QPrintSettingsOutput", "Reverse", nullptr)); - tabs->setTabText(tabs->indexOf(copiesTab), QApplication::translate("QPrintSettingsOutput", "Copies", nullptr)); - colorMode->setTitle(QApplication::translate("QPrintSettingsOutput", "Color Mode", nullptr)); - color->setText(QApplication::translate("QPrintSettingsOutput", "Color", nullptr)); - grayscale->setText(QApplication::translate("QPrintSettingsOutput", "Grayscale", nullptr)); - duplex->setTitle(QApplication::translate("QPrintSettingsOutput", "Duplex Printing", nullptr)); - noDuplex->setText(QApplication::translate("QPrintSettingsOutput", "None", nullptr)); - duplexLong->setText(QApplication::translate("QPrintSettingsOutput", "Long side", nullptr)); - duplexShort->setText(QApplication::translate("QPrintSettingsOutput", "Short side", nullptr)); - tabs->setTabText(tabs->indexOf(optionsTab), QApplication::translate("QPrintSettingsOutput", "Options", nullptr)); + QPrintSettingsOutput->setWindowTitle(QCoreApplication::translate("QPrintSettingsOutput", "Form", nullptr)); + gbPrintRange->setTitle(QCoreApplication::translate("QPrintSettingsOutput", "Print range", nullptr)); + printAll->setText(QCoreApplication::translate("QPrintSettingsOutput", "Print all", nullptr)); + printRange->setText(QCoreApplication::translate("QPrintSettingsOutput", "Pages from", nullptr)); + label_3->setText(QCoreApplication::translate("QPrintSettingsOutput", "to", nullptr)); + printSelection->setText(QCoreApplication::translate("QPrintSettingsOutput", "Selection", nullptr)); + groupBox->setTitle(QCoreApplication::translate("QPrintSettingsOutput", "Output Settings", nullptr)); + label->setText(QCoreApplication::translate("QPrintSettingsOutput", "Copies:", nullptr)); + collate->setText(QCoreApplication::translate("QPrintSettingsOutput", "Collate", nullptr)); + reverse->setText(QCoreApplication::translate("QPrintSettingsOutput", "Reverse", nullptr)); + tabs->setTabText(tabs->indexOf(copiesTab), QCoreApplication::translate("QPrintSettingsOutput", "Copies", nullptr)); + colorMode->setTitle(QCoreApplication::translate("QPrintSettingsOutput", "Color Mode", nullptr)); + color->setText(QCoreApplication::translate("QPrintSettingsOutput", "Color", nullptr)); + grayscale->setText(QCoreApplication::translate("QPrintSettingsOutput", "Grayscale", nullptr)); + duplex->setTitle(QCoreApplication::translate("QPrintSettingsOutput", "Duplex Printing", nullptr)); + noDuplex->setText(QCoreApplication::translate("QPrintSettingsOutput", "None", nullptr)); + duplexLong->setText(QCoreApplication::translate("QPrintSettingsOutput", "Long side", nullptr)); + duplexShort->setText(QCoreApplication::translate("QPrintSettingsOutput", "Short side", nullptr)); + tabs->setTabText(tabs->indexOf(optionsTab), QCoreApplication::translate("QPrintSettingsOutput", "Options", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/qprintwidget.ui.h b/tests/auto/tools/uic/baseline/qprintwidget.ui.h index d624e28297..5b1d921173 100644 --- a/tests/auto/tools/uic/baseline/qprintwidget.ui.h +++ b/tests/auto/tools/uic/baseline/qprintwidget.ui.h @@ -140,15 +140,15 @@ public: void retranslateUi(QWidget *QPrintWidget) { - QPrintWidget->setWindowTitle(QApplication::translate("QPrintWidget", "Form", nullptr)); - printerGroup->setTitle(QApplication::translate("QPrintWidget", "Printer", nullptr)); - label->setText(QApplication::translate("QPrintWidget", "&Name:", nullptr)); - properties->setText(QApplication::translate("QPrintWidget", "P&roperties", nullptr)); - label_2->setText(QApplication::translate("QPrintWidget", "Location:", nullptr)); - preview->setText(QApplication::translate("QPrintWidget", "Preview", nullptr)); - label_3->setText(QApplication::translate("QPrintWidget", "Type:", nullptr)); - lOutput->setText(QApplication::translate("QPrintWidget", "Output &file:", nullptr)); - fileBrowser->setText(QApplication::translate("QPrintWidget", "...", nullptr)); + QPrintWidget->setWindowTitle(QCoreApplication::translate("QPrintWidget", "Form", nullptr)); + printerGroup->setTitle(QCoreApplication::translate("QPrintWidget", "Printer", nullptr)); + label->setText(QCoreApplication::translate("QPrintWidget", "&Name:", nullptr)); + properties->setText(QCoreApplication::translate("QPrintWidget", "P&roperties", nullptr)); + label_2->setText(QCoreApplication::translate("QPrintWidget", "Location:", nullptr)); + preview->setText(QCoreApplication::translate("QPrintWidget", "Preview", nullptr)); + label_3->setText(QCoreApplication::translate("QPrintWidget", "Type:", nullptr)); + lOutput->setText(QCoreApplication::translate("QPrintWidget", "Output &file:", nullptr)); + fileBrowser->setText(QCoreApplication::translate("QPrintWidget", "...", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/qsqlconnectiondialog.ui.h b/tests/auto/tools/uic/baseline/qsqlconnectiondialog.ui.h index 557918375a..681c1f97da 100644 --- a/tests/auto/tools/uic/baseline/qsqlconnectiondialog.ui.h +++ b/tests/auto/tools/uic/baseline/qsqlconnectiondialog.ui.h @@ -206,18 +206,18 @@ public: void retranslateUi(QDialog *QSqlConnectionDialogUi) { - QSqlConnectionDialogUi->setWindowTitle(QApplication::translate("QSqlConnectionDialogUi", "Connect...", nullptr)); - connGroupBox->setTitle(QApplication::translate("QSqlConnectionDialogUi", "Connection settings", nullptr)); - textLabel4->setText(QApplication::translate("QSqlConnectionDialogUi", "&Username:", nullptr)); - textLabel2->setText(QApplication::translate("QSqlConnectionDialogUi", "D&river", nullptr)); - portSpinBox->setSpecialValueText(QApplication::translate("QSqlConnectionDialogUi", "Default", nullptr)); - textLabel3->setText(QApplication::translate("QSqlConnectionDialogUi", "Database Name:", nullptr)); - textLabel5->setText(QApplication::translate("QSqlConnectionDialogUi", "&Hostname:", nullptr)); - textLabel5_2->setText(QApplication::translate("QSqlConnectionDialogUi", "P&ort:", nullptr)); - textLabel4_2->setText(QApplication::translate("QSqlConnectionDialogUi", "&Password:", nullptr)); - dbCheckBox->setText(QApplication::translate("QSqlConnectionDialogUi", "Us&e predefined in-memory database", nullptr)); - okButton->setText(QApplication::translate("QSqlConnectionDialogUi", "&OK", nullptr)); - cancelButton->setText(QApplication::translate("QSqlConnectionDialogUi", "&Cancel", nullptr)); + QSqlConnectionDialogUi->setWindowTitle(QCoreApplication::translate("QSqlConnectionDialogUi", "Connect...", nullptr)); + connGroupBox->setTitle(QCoreApplication::translate("QSqlConnectionDialogUi", "Connection settings", nullptr)); + textLabel4->setText(QCoreApplication::translate("QSqlConnectionDialogUi", "&Username:", nullptr)); + textLabel2->setText(QCoreApplication::translate("QSqlConnectionDialogUi", "D&river", nullptr)); + portSpinBox->setSpecialValueText(QCoreApplication::translate("QSqlConnectionDialogUi", "Default", nullptr)); + textLabel3->setText(QCoreApplication::translate("QSqlConnectionDialogUi", "Database Name:", nullptr)); + textLabel5->setText(QCoreApplication::translate("QSqlConnectionDialogUi", "&Hostname:", nullptr)); + textLabel5_2->setText(QCoreApplication::translate("QSqlConnectionDialogUi", "P&ort:", nullptr)); + textLabel4_2->setText(QCoreApplication::translate("QSqlConnectionDialogUi", "&Password:", nullptr)); + dbCheckBox->setText(QCoreApplication::translate("QSqlConnectionDialogUi", "Us&e predefined in-memory database", nullptr)); + okButton->setText(QCoreApplication::translate("QSqlConnectionDialogUi", "&OK", nullptr)); + cancelButton->setText(QCoreApplication::translate("QSqlConnectionDialogUi", "&Cancel", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/qtgradientdialog.ui.h b/tests/auto/tools/uic/baseline/qtgradientdialog.ui.h index 8ef2e5f6de..5c09962572 100644 --- a/tests/auto/tools/uic/baseline/qtgradientdialog.ui.h +++ b/tests/auto/tools/uic/baseline/qtgradientdialog.ui.h @@ -89,7 +89,7 @@ public: void retranslateUi(QDialog *QtGradientDialog) { - QtGradientDialog->setWindowTitle(QApplication::translate("QtGradientDialog", "Edit Gradient", nullptr)); + QtGradientDialog->setWindowTitle(QCoreApplication::translate("QtGradientDialog", "Edit Gradient", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/qtgradienteditor.ui.h b/tests/auto/tools/uic/baseline/qtgradienteditor.ui.h index 814adff7bd..7ca14d6ef4 100644 --- a/tests/auto/tools/uic/baseline/qtgradienteditor.ui.h +++ b/tests/auto/tools/uic/baseline/qtgradienteditor.ui.h @@ -583,119 +583,119 @@ public: void retranslateUi(QWidget *QtGradientEditor) { - QtGradientEditor->setWindowTitle(QApplication::translate("QtGradientEditor", "Form", nullptr)); + QtGradientEditor->setWindowTitle(QCoreApplication::translate("QtGradientEditor", "Form", nullptr)); #if QT_CONFIG(tooltip) - gradientWidget->setToolTip(QApplication::translate("QtGradientEditor", "Gradient Editor", nullptr)); + gradientWidget->setToolTip(QCoreApplication::translate("QtGradientEditor", "Gradient Editor", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(whatsthis) - gradientWidget->setWhatsThis(QApplication::translate("QtGradientEditor", "This area shows a preview of the gradient being edited. It also allows you to edit parameters specific to the gradient's type such as start and final point, radius, etc. by drag & drop.", nullptr)); + gradientWidget->setWhatsThis(QCoreApplication::translate("QtGradientEditor", "This area shows a preview of the gradient being edited. It also allows you to edit parameters specific to the gradient's type such as start and final point, radius, etc. by drag & drop.", nullptr)); #endif // QT_CONFIG(whatsthis) - label1->setText(QApplication::translate("QtGradientEditor", "1", nullptr)); - label2->setText(QApplication::translate("QtGradientEditor", "2", nullptr)); - label3->setText(QApplication::translate("QtGradientEditor", "3", nullptr)); - label4->setText(QApplication::translate("QtGradientEditor", "4", nullptr)); - label5->setText(QApplication::translate("QtGradientEditor", "5", nullptr)); + label1->setText(QCoreApplication::translate("QtGradientEditor", "1", nullptr)); + label2->setText(QCoreApplication::translate("QtGradientEditor", "2", nullptr)); + label3->setText(QCoreApplication::translate("QtGradientEditor", "3", nullptr)); + label4->setText(QCoreApplication::translate("QtGradientEditor", "4", nullptr)); + label5->setText(QCoreApplication::translate("QtGradientEditor", "5", nullptr)); #if QT_CONFIG(tooltip) - gradientStopsWidget->setToolTip(QApplication::translate("QtGradientEditor", "Gradient Stops Editor", nullptr)); + gradientStopsWidget->setToolTip(QCoreApplication::translate("QtGradientEditor", "Gradient Stops Editor", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(whatsthis) - gradientStopsWidget->setWhatsThis(QApplication::translate("QtGradientEditor", "This area allows you to edit gradient stops. Double click on the existing stop handle to duplicate it. Double click outside of the existing stop handles to create a new stop. Drag & drop the handle to reposition it. Use right mouse button to popup context menu with extra actions.", nullptr)); + gradientStopsWidget->setWhatsThis(QCoreApplication::translate("QtGradientEditor", "This area allows you to edit gradient stops. Double click on the existing stop handle to duplicate it. Double click outside of the existing stop handles to create a new stop. Drag & drop the handle to reposition it. Use right mouse button to popup context menu with extra actions.", nullptr)); #endif // QT_CONFIG(whatsthis) - zoomLabel->setText(QApplication::translate("QtGradientEditor", "Zoom", nullptr)); + zoomLabel->setText(QCoreApplication::translate("QtGradientEditor", "Zoom", nullptr)); #if QT_CONFIG(tooltip) - zoomAllButton->setToolTip(QApplication::translate("QtGradientEditor", "Reset Zoom", nullptr)); + zoomAllButton->setToolTip(QCoreApplication::translate("QtGradientEditor", "Reset Zoom", nullptr)); #endif // QT_CONFIG(tooltip) - zoomAllButton->setText(QApplication::translate("QtGradientEditor", "Reset Zoom", nullptr)); - positionLabel->setText(QApplication::translate("QtGradientEditor", "Position", nullptr)); + zoomAllButton->setText(QCoreApplication::translate("QtGradientEditor", "Reset Zoom", nullptr)); + positionLabel->setText(QCoreApplication::translate("QtGradientEditor", "Position", nullptr)); #if QT_CONFIG(tooltip) - hLabel->setToolTip(QApplication::translate("QtGradientEditor", "Hue", nullptr)); + hLabel->setToolTip(QCoreApplication::translate("QtGradientEditor", "Hue", nullptr)); #endif // QT_CONFIG(tooltip) - hLabel->setText(QApplication::translate("QtGradientEditor", "H", nullptr)); + hLabel->setText(QCoreApplication::translate("QtGradientEditor", "H", nullptr)); #if QT_CONFIG(tooltip) - hueColorLine->setToolTip(QApplication::translate("QtGradientEditor", "Hue", nullptr)); + hueColorLine->setToolTip(QCoreApplication::translate("QtGradientEditor", "Hue", nullptr)); #endif // QT_CONFIG(tooltip) - hueLabel->setText(QApplication::translate("QtGradientEditor", "Hue", nullptr)); + hueLabel->setText(QCoreApplication::translate("QtGradientEditor", "Hue", nullptr)); #if QT_CONFIG(tooltip) - sLabel->setToolTip(QApplication::translate("QtGradientEditor", "Saturation", nullptr)); + sLabel->setToolTip(QCoreApplication::translate("QtGradientEditor", "Saturation", nullptr)); #endif // QT_CONFIG(tooltip) - sLabel->setText(QApplication::translate("QtGradientEditor", "S", nullptr)); + sLabel->setText(QCoreApplication::translate("QtGradientEditor", "S", nullptr)); #if QT_CONFIG(tooltip) - saturationColorLine->setToolTip(QApplication::translate("QtGradientEditor", "Saturation", nullptr)); + saturationColorLine->setToolTip(QCoreApplication::translate("QtGradientEditor", "Saturation", nullptr)); #endif // QT_CONFIG(tooltip) - saturationLabel->setText(QApplication::translate("QtGradientEditor", "Sat", nullptr)); + saturationLabel->setText(QCoreApplication::translate("QtGradientEditor", "Sat", nullptr)); #if QT_CONFIG(tooltip) - vLabel->setToolTip(QApplication::translate("QtGradientEditor", "Value", nullptr)); + vLabel->setToolTip(QCoreApplication::translate("QtGradientEditor", "Value", nullptr)); #endif // QT_CONFIG(tooltip) - vLabel->setText(QApplication::translate("QtGradientEditor", "V", nullptr)); + vLabel->setText(QCoreApplication::translate("QtGradientEditor", "V", nullptr)); #if QT_CONFIG(tooltip) - valueColorLine->setToolTip(QApplication::translate("QtGradientEditor", "Value", nullptr)); + valueColorLine->setToolTip(QCoreApplication::translate("QtGradientEditor", "Value", nullptr)); #endif // QT_CONFIG(tooltip) - valueLabel->setText(QApplication::translate("QtGradientEditor", "Val", nullptr)); + valueLabel->setText(QCoreApplication::translate("QtGradientEditor", "Val", nullptr)); #if QT_CONFIG(tooltip) - aLabel->setToolTip(QApplication::translate("QtGradientEditor", "Alpha", nullptr)); + aLabel->setToolTip(QCoreApplication::translate("QtGradientEditor", "Alpha", nullptr)); #endif // QT_CONFIG(tooltip) - aLabel->setText(QApplication::translate("QtGradientEditor", "A", nullptr)); + aLabel->setText(QCoreApplication::translate("QtGradientEditor", "A", nullptr)); #if QT_CONFIG(tooltip) - alphaColorLine->setToolTip(QApplication::translate("QtGradientEditor", "Alpha", nullptr)); + alphaColorLine->setToolTip(QCoreApplication::translate("QtGradientEditor", "Alpha", nullptr)); #endif // QT_CONFIG(tooltip) - alphaLabel->setText(QApplication::translate("QtGradientEditor", "Alpha", nullptr)); + alphaLabel->setText(QCoreApplication::translate("QtGradientEditor", "Alpha", nullptr)); #if QT_CONFIG(tooltip) - typeComboBox->setToolTip(QApplication::translate("QtGradientEditor", "Type", nullptr)); + typeComboBox->setToolTip(QCoreApplication::translate("QtGradientEditor", "Type", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(tooltip) - spreadComboBox->setToolTip(QApplication::translate("QtGradientEditor", "Spread", nullptr)); + spreadComboBox->setToolTip(QCoreApplication::translate("QtGradientEditor", "Spread", nullptr)); #endif // QT_CONFIG(tooltip) - colorLabel->setText(QApplication::translate("QtGradientEditor", "Color", nullptr)); + colorLabel->setText(QCoreApplication::translate("QtGradientEditor", "Color", nullptr)); #if QT_CONFIG(tooltip) - colorButton->setToolTip(QApplication::translate("QtGradientEditor", "Current stop's color", nullptr)); + colorButton->setToolTip(QCoreApplication::translate("QtGradientEditor", "Current stop's color", nullptr)); #endif // QT_CONFIG(tooltip) colorButton->setText(QString()); #if QT_CONFIG(tooltip) - hsvRadioButton->setToolTip(QApplication::translate("QtGradientEditor", "Show HSV specification", nullptr)); + hsvRadioButton->setToolTip(QCoreApplication::translate("QtGradientEditor", "Show HSV specification", nullptr)); #endif // QT_CONFIG(tooltip) - hsvRadioButton->setText(QApplication::translate("QtGradientEditor", "HSV", nullptr)); + hsvRadioButton->setText(QCoreApplication::translate("QtGradientEditor", "HSV", nullptr)); #if QT_CONFIG(tooltip) - rgbRadioButton->setToolTip(QApplication::translate("QtGradientEditor", "Show RGB specification", nullptr)); + rgbRadioButton->setToolTip(QCoreApplication::translate("QtGradientEditor", "Show RGB specification", nullptr)); #endif // QT_CONFIG(tooltip) - rgbRadioButton->setText(QApplication::translate("QtGradientEditor", "RGB", nullptr)); + rgbRadioButton->setText(QCoreApplication::translate("QtGradientEditor", "RGB", nullptr)); #if QT_CONFIG(tooltip) - positionSpinBox->setToolTip(QApplication::translate("QtGradientEditor", "Current stop's position", nullptr)); + positionSpinBox->setToolTip(QCoreApplication::translate("QtGradientEditor", "Current stop's position", nullptr)); #endif // QT_CONFIG(tooltip) - zoomSpinBox->setSuffix(QApplication::translate("QtGradientEditor", "%", nullptr)); + zoomSpinBox->setSuffix(QCoreApplication::translate("QtGradientEditor", "%", nullptr)); #if QT_CONFIG(tooltip) - zoomInButton->setToolTip(QApplication::translate("QtGradientEditor", "Zoom In", nullptr)); + zoomInButton->setToolTip(QCoreApplication::translate("QtGradientEditor", "Zoom In", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(tooltip) - zoomOutButton->setToolTip(QApplication::translate("QtGradientEditor", "Zoom Out", nullptr)); + zoomOutButton->setToolTip(QCoreApplication::translate("QtGradientEditor", "Zoom Out", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(tooltip) - detailsButton->setToolTip(QApplication::translate("QtGradientEditor", "Toggle details extension", nullptr)); + detailsButton->setToolTip(QCoreApplication::translate("QtGradientEditor", "Toggle details extension", nullptr)); #endif // QT_CONFIG(tooltip) - detailsButton->setText(QApplication::translate("QtGradientEditor", ">", nullptr)); + detailsButton->setText(QCoreApplication::translate("QtGradientEditor", ">", nullptr)); #if QT_CONFIG(tooltip) - linearButton->setToolTip(QApplication::translate("QtGradientEditor", "Linear Type", nullptr)); + linearButton->setToolTip(QCoreApplication::translate("QtGradientEditor", "Linear Type", nullptr)); #endif // QT_CONFIG(tooltip) - linearButton->setText(QApplication::translate("QtGradientEditor", "...", nullptr)); + linearButton->setText(QCoreApplication::translate("QtGradientEditor", "...", nullptr)); #if QT_CONFIG(tooltip) - radialButton->setToolTip(QApplication::translate("QtGradientEditor", "Radial Type", nullptr)); + radialButton->setToolTip(QCoreApplication::translate("QtGradientEditor", "Radial Type", nullptr)); #endif // QT_CONFIG(tooltip) - radialButton->setText(QApplication::translate("QtGradientEditor", "...", nullptr)); + radialButton->setText(QCoreApplication::translate("QtGradientEditor", "...", nullptr)); #if QT_CONFIG(tooltip) - conicalButton->setToolTip(QApplication::translate("QtGradientEditor", "Conical Type", nullptr)); + conicalButton->setToolTip(QCoreApplication::translate("QtGradientEditor", "Conical Type", nullptr)); #endif // QT_CONFIG(tooltip) - conicalButton->setText(QApplication::translate("QtGradientEditor", "...", nullptr)); + conicalButton->setText(QCoreApplication::translate("QtGradientEditor", "...", nullptr)); #if QT_CONFIG(tooltip) - padButton->setToolTip(QApplication::translate("QtGradientEditor", "Pad Spread", nullptr)); + padButton->setToolTip(QCoreApplication::translate("QtGradientEditor", "Pad Spread", nullptr)); #endif // QT_CONFIG(tooltip) - padButton->setText(QApplication::translate("QtGradientEditor", "...", nullptr)); + padButton->setText(QCoreApplication::translate("QtGradientEditor", "...", nullptr)); #if QT_CONFIG(tooltip) - repeatButton->setToolTip(QApplication::translate("QtGradientEditor", "Repeat Spread", nullptr)); + repeatButton->setToolTip(QCoreApplication::translate("QtGradientEditor", "Repeat Spread", nullptr)); #endif // QT_CONFIG(tooltip) - repeatButton->setText(QApplication::translate("QtGradientEditor", "...", nullptr)); + repeatButton->setText(QCoreApplication::translate("QtGradientEditor", "...", nullptr)); #if QT_CONFIG(tooltip) - reflectButton->setToolTip(QApplication::translate("QtGradientEditor", "Reflect Spread", nullptr)); + reflectButton->setToolTip(QCoreApplication::translate("QtGradientEditor", "Reflect Spread", nullptr)); #endif // QT_CONFIG(tooltip) - reflectButton->setText(QApplication::translate("QtGradientEditor", "...", nullptr)); + reflectButton->setText(QCoreApplication::translate("QtGradientEditor", "...", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/qtgradientview.ui.h b/tests/auto/tools/uic/baseline/qtgradientview.ui.h index 5e2ff941b7..494324b00f 100644 --- a/tests/auto/tools/uic/baseline/qtgradientview.ui.h +++ b/tests/auto/tools/uic/baseline/qtgradientview.ui.h @@ -105,11 +105,11 @@ public: void retranslateUi(QWidget *QtGradientView) { - QtGradientView->setWindowTitle(QApplication::translate("QtGradientView", "Gradient View", nullptr)); - newButton->setText(QApplication::translate("QtGradientView", "New...", nullptr)); - editButton->setText(QApplication::translate("QtGradientView", "Edit...", nullptr)); - renameButton->setText(QApplication::translate("QtGradientView", "Rename", nullptr)); - removeButton->setText(QApplication::translate("QtGradientView", "Remove", nullptr)); + QtGradientView->setWindowTitle(QCoreApplication::translate("QtGradientView", "Gradient View", nullptr)); + newButton->setText(QCoreApplication::translate("QtGradientView", "New...", nullptr)); + editButton->setText(QCoreApplication::translate("QtGradientView", "Edit...", nullptr)); + renameButton->setText(QCoreApplication::translate("QtGradientView", "Rename", nullptr)); + removeButton->setText(QCoreApplication::translate("QtGradientView", "Remove", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/qtgradientviewdialog.ui.h b/tests/auto/tools/uic/baseline/qtgradientviewdialog.ui.h index 567ec0b5e5..f6369c8c5f 100644 --- a/tests/auto/tools/uic/baseline/qtgradientviewdialog.ui.h +++ b/tests/auto/tools/uic/baseline/qtgradientviewdialog.ui.h @@ -89,7 +89,7 @@ public: void retranslateUi(QDialog *QtGradientViewDialog) { - QtGradientViewDialog->setWindowTitle(QApplication::translate("QtGradientViewDialog", "Select Gradient", nullptr)); + QtGradientViewDialog->setWindowTitle(QCoreApplication::translate("QtGradientViewDialog", "Select Gradient", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/qtresourceeditordialog.ui.h b/tests/auto/tools/uic/baseline/qtresourceeditordialog.ui.h index 6b394d7e8e..7428778a9c 100644 --- a/tests/auto/tools/uic/baseline/qtresourceeditordialog.ui.h +++ b/tests/auto/tools/uic/baseline/qtresourceeditordialog.ui.h @@ -141,25 +141,25 @@ public: void retranslateUi(QDialog *QtResourceEditorDialog) { - QtResourceEditorDialog->setWindowTitle(QApplication::translate("QtResourceEditorDialog", "Dialog", nullptr)); + QtResourceEditorDialog->setWindowTitle(QCoreApplication::translate("QtResourceEditorDialog", "Dialog", nullptr)); #if QT_CONFIG(tooltip) - newQrcButton->setToolTip(QApplication::translate("QtResourceEditorDialog", "New File", nullptr)); + newQrcButton->setToolTip(QCoreApplication::translate("QtResourceEditorDialog", "New File", nullptr)); #endif // QT_CONFIG(tooltip) - newQrcButton->setText(QApplication::translate("QtResourceEditorDialog", "N", nullptr)); + newQrcButton->setText(QCoreApplication::translate("QtResourceEditorDialog", "N", nullptr)); #if QT_CONFIG(tooltip) - removeQrcButton->setToolTip(QApplication::translate("QtResourceEditorDialog", "Remove File", nullptr)); + removeQrcButton->setToolTip(QCoreApplication::translate("QtResourceEditorDialog", "Remove File", nullptr)); #endif // QT_CONFIG(tooltip) - removeQrcButton->setText(QApplication::translate("QtResourceEditorDialog", "R", nullptr)); - importQrcButton->setText(QApplication::translate("QtResourceEditorDialog", "I", nullptr)); + removeQrcButton->setText(QCoreApplication::translate("QtResourceEditorDialog", "R", nullptr)); + importQrcButton->setText(QCoreApplication::translate("QtResourceEditorDialog", "I", nullptr)); #if QT_CONFIG(tooltip) - newResourceButton->setToolTip(QApplication::translate("QtResourceEditorDialog", "New Resource", nullptr)); + newResourceButton->setToolTip(QCoreApplication::translate("QtResourceEditorDialog", "New Resource", nullptr)); #endif // QT_CONFIG(tooltip) - newResourceButton->setText(QApplication::translate("QtResourceEditorDialog", "N", nullptr)); - addResourceButton->setText(QApplication::translate("QtResourceEditorDialog", "A", nullptr)); + newResourceButton->setText(QCoreApplication::translate("QtResourceEditorDialog", "N", nullptr)); + addResourceButton->setText(QCoreApplication::translate("QtResourceEditorDialog", "A", nullptr)); #if QT_CONFIG(tooltip) - removeResourceButton->setToolTip(QApplication::translate("QtResourceEditorDialog", "Remove Resource or File", nullptr)); + removeResourceButton->setToolTip(QCoreApplication::translate("QtResourceEditorDialog", "Remove Resource or File", nullptr)); #endif // QT_CONFIG(tooltip) - removeResourceButton->setText(QApplication::translate("QtResourceEditorDialog", "R", nullptr)); + removeResourceButton->setText(QCoreApplication::translate("QtResourceEditorDialog", "R", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/qttoolbardialog.ui.h b/tests/auto/tools/uic/baseline/qttoolbardialog.ui.h index 7d8f91067c..bfaeb99af2 100644 --- a/tests/auto/tools/uic/baseline/qttoolbardialog.ui.h +++ b/tests/auto/tools/uic/baseline/qttoolbardialog.ui.h @@ -178,40 +178,40 @@ public: void retranslateUi(QDialog *QtToolBarDialog) { - QtToolBarDialog->setWindowTitle(QApplication::translate("QtToolBarDialog", "Customize Toolbars", nullptr)); + QtToolBarDialog->setWindowTitle(QCoreApplication::translate("QtToolBarDialog", "Customize Toolbars", nullptr)); QTreeWidgetItem *___qtreewidgetitem = actionTree->headerItem(); - ___qtreewidgetitem->setText(0, QApplication::translate("QtToolBarDialog", "1", nullptr)); - label->setText(QApplication::translate("QtToolBarDialog", "Actions", nullptr)); - label_2->setText(QApplication::translate("QtToolBarDialog", "Toolbars", nullptr)); + ___qtreewidgetitem->setText(0, QCoreApplication::translate("QtToolBarDialog", "1", nullptr)); + label->setText(QCoreApplication::translate("QtToolBarDialog", "Actions", nullptr)); + label_2->setText(QCoreApplication::translate("QtToolBarDialog", "Toolbars", nullptr)); #if QT_CONFIG(tooltip) - newButton->setToolTip(QApplication::translate("QtToolBarDialog", "Add new toolbar", nullptr)); + newButton->setToolTip(QCoreApplication::translate("QtToolBarDialog", "Add new toolbar", nullptr)); #endif // QT_CONFIG(tooltip) - newButton->setText(QApplication::translate("QtToolBarDialog", "New", nullptr)); + newButton->setText(QCoreApplication::translate("QtToolBarDialog", "New", nullptr)); #if QT_CONFIG(tooltip) - removeButton->setToolTip(QApplication::translate("QtToolBarDialog", "Remove selected toolbar", nullptr)); + removeButton->setToolTip(QCoreApplication::translate("QtToolBarDialog", "Remove selected toolbar", nullptr)); #endif // QT_CONFIG(tooltip) - removeButton->setText(QApplication::translate("QtToolBarDialog", "Remove", nullptr)); + removeButton->setText(QCoreApplication::translate("QtToolBarDialog", "Remove", nullptr)); #if QT_CONFIG(tooltip) - renameButton->setToolTip(QApplication::translate("QtToolBarDialog", "Rename toolbar", nullptr)); + renameButton->setToolTip(QCoreApplication::translate("QtToolBarDialog", "Rename toolbar", nullptr)); #endif // QT_CONFIG(tooltip) - renameButton->setText(QApplication::translate("QtToolBarDialog", "Rename", nullptr)); + renameButton->setText(QCoreApplication::translate("QtToolBarDialog", "Rename", nullptr)); #if QT_CONFIG(tooltip) - upButton->setToolTip(QApplication::translate("QtToolBarDialog", "Move action up", nullptr)); + upButton->setToolTip(QCoreApplication::translate("QtToolBarDialog", "Move action up", nullptr)); #endif // QT_CONFIG(tooltip) - upButton->setText(QApplication::translate("QtToolBarDialog", "Up", nullptr)); + upButton->setText(QCoreApplication::translate("QtToolBarDialog", "Up", nullptr)); #if QT_CONFIG(tooltip) - leftButton->setToolTip(QApplication::translate("QtToolBarDialog", "Remove action from toolbar", nullptr)); + leftButton->setToolTip(QCoreApplication::translate("QtToolBarDialog", "Remove action from toolbar", nullptr)); #endif // QT_CONFIG(tooltip) - leftButton->setText(QApplication::translate("QtToolBarDialog", "<-", nullptr)); + leftButton->setText(QCoreApplication::translate("QtToolBarDialog", "<-", nullptr)); #if QT_CONFIG(tooltip) - rightButton->setToolTip(QApplication::translate("QtToolBarDialog", "Add action to toolbar", nullptr)); + rightButton->setToolTip(QCoreApplication::translate("QtToolBarDialog", "Add action to toolbar", nullptr)); #endif // QT_CONFIG(tooltip) - rightButton->setText(QApplication::translate("QtToolBarDialog", "->", nullptr)); + rightButton->setText(QCoreApplication::translate("QtToolBarDialog", "->", nullptr)); #if QT_CONFIG(tooltip) - downButton->setToolTip(QApplication::translate("QtToolBarDialog", "Move action down", nullptr)); + downButton->setToolTip(QCoreApplication::translate("QtToolBarDialog", "Move action down", nullptr)); #endif // QT_CONFIG(tooltip) - downButton->setText(QApplication::translate("QtToolBarDialog", "Down", nullptr)); - label_3->setText(QApplication::translate("QtToolBarDialog", "Current Toolbar Actions", nullptr)); + downButton->setText(QCoreApplication::translate("QtToolBarDialog", "Down", nullptr)); + label_3->setText(QCoreApplication::translate("QtToolBarDialog", "Current Toolbar Actions", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/querywidget.ui.h b/tests/auto/tools/uic/baseline/querywidget.ui.h index f1403d829d..a92c60f4fe 100644 --- a/tests/auto/tools/uic/baseline/querywidget.ui.h +++ b/tests/auto/tools/uic/baseline/querywidget.ui.h @@ -153,10 +153,10 @@ public: void retranslateUi(QMainWindow *QueryWidget) { - QueryWidget->setWindowTitle(QApplication::translate("QueryWidget", "Recipes XQuery Example", nullptr)); - inputGroupBox->setTitle(QApplication::translate("QueryWidget", "Input Document", nullptr)); - queryGroupBox->setTitle(QApplication::translate("QueryWidget", "Select your query:", nullptr)); - outputGroupBox->setTitle(QApplication::translate("QueryWidget", "Output Document", nullptr)); + QueryWidget->setWindowTitle(QCoreApplication::translate("QueryWidget", "Recipes XQuery Example", nullptr)); + inputGroupBox->setTitle(QCoreApplication::translate("QueryWidget", "Input Document", nullptr)); + queryGroupBox->setTitle(QCoreApplication::translate("QueryWidget", "Select your query:", nullptr)); + outputGroupBox->setTitle(QCoreApplication::translate("QueryWidget", "Output Document", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/remotecontrol.ui.h b/tests/auto/tools/uic/baseline/remotecontrol.ui.h index aa4238c612..5b7c6c42c2 100644 --- a/tests/auto/tools/uic/baseline/remotecontrol.ui.h +++ b/tests/auto/tools/uic/baseline/remotecontrol.ui.h @@ -222,22 +222,22 @@ public: void retranslateUi(QMainWindow *RemoteControlClass) { - RemoteControlClass->setWindowTitle(QApplication::translate("RemoteControlClass", "RemoteControl", nullptr)); - actionQuit->setText(QApplication::translate("RemoteControlClass", "Quit", nullptr)); - label->setText(QApplication::translate("RemoteControlClass", "Start URL:", nullptr)); - launchButton->setText(QApplication::translate("RemoteControlClass", "Launch Qt HelpViewer", nullptr)); - actionGroupBox->setTitle(QApplication::translate("RemoteControlClass", "Actions", nullptr)); - label_2->setText(QApplication::translate("RemoteControlClass", "Search in Index:", nullptr)); + RemoteControlClass->setWindowTitle(QCoreApplication::translate("RemoteControlClass", "RemoteControl", nullptr)); + actionQuit->setText(QCoreApplication::translate("RemoteControlClass", "Quit", nullptr)); + label->setText(QCoreApplication::translate("RemoteControlClass", "Start URL:", nullptr)); + launchButton->setText(QCoreApplication::translate("RemoteControlClass", "Launch Qt HelpViewer", nullptr)); + actionGroupBox->setTitle(QCoreApplication::translate("RemoteControlClass", "Actions", nullptr)); + label_2->setText(QCoreApplication::translate("RemoteControlClass", "Search in Index:", nullptr)); indexButton->setText(QString()); - label_4->setText(QApplication::translate("RemoteControlClass", "Identifier:", nullptr)); + label_4->setText(QCoreApplication::translate("RemoteControlClass", "Identifier:", nullptr)); identifierButton->setText(QString()); - label_3->setText(QApplication::translate("RemoteControlClass", "Show URL:", nullptr)); + label_3->setText(QCoreApplication::translate("RemoteControlClass", "Show URL:", nullptr)); urlButton->setText(QString()); - syncContentsButton->setText(QApplication::translate("RemoteControlClass", "Sync Contents", nullptr)); - contentsCheckBox->setText(QApplication::translate("RemoteControlClass", "Show Contents", nullptr)); - indexCheckBox->setText(QApplication::translate("RemoteControlClass", "Show Index", nullptr)); - bookmarksCheckBox->setText(QApplication::translate("RemoteControlClass", "Show Bookmarks", nullptr)); - menuFile->setTitle(QApplication::translate("RemoteControlClass", "File", nullptr)); + syncContentsButton->setText(QCoreApplication::translate("RemoteControlClass", "Sync Contents", nullptr)); + contentsCheckBox->setText(QCoreApplication::translate("RemoteControlClass", "Show Contents", nullptr)); + indexCheckBox->setText(QCoreApplication::translate("RemoteControlClass", "Show Index", nullptr)); + bookmarksCheckBox->setText(QCoreApplication::translate("RemoteControlClass", "Show Bookmarks", nullptr)); + menuFile->setTitle(QCoreApplication::translate("RemoteControlClass", "File", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/saveformastemplate.ui.h b/tests/auto/tools/uic/baseline/saveformastemplate.ui.h index 3beff599a8..6829958463 100644 --- a/tests/auto/tools/uic/baseline/saveformastemplate.ui.h +++ b/tests/auto/tools/uic/baseline/saveformastemplate.ui.h @@ -131,10 +131,10 @@ public: void retranslateUi(QDialog *SaveFormAsTemplate) { - SaveFormAsTemplate->setWindowTitle(QApplication::translate("SaveFormAsTemplate", "Save Form As Template", nullptr)); - label->setText(QApplication::translate("SaveFormAsTemplate", "&Name:", nullptr)); + SaveFormAsTemplate->setWindowTitle(QCoreApplication::translate("SaveFormAsTemplate", "Save Form As Template", nullptr)); + label->setText(QCoreApplication::translate("SaveFormAsTemplate", "&Name:", nullptr)); templateNameEdit->setText(QString()); - label_2->setText(QApplication::translate("SaveFormAsTemplate", "&Category:", nullptr)); + label_2->setText(QCoreApplication::translate("SaveFormAsTemplate", "&Category:", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/settings.ui.h b/tests/auto/tools/uic/baseline/settings.ui.h index d17b935239..6a1adb2d2c 100644 --- a/tests/auto/tools/uic/baseline/settings.ui.h +++ b/tests/auto/tools/uic/baseline/settings.ui.h @@ -182,13 +182,13 @@ public: void retranslateUi(QDialog *Dialog) { - Dialog->setWindowTitle(QApplication::translate("Dialog", "Dialog", nullptr)); - label->setText(QApplication::translate("Dialog", "Audio device:", nullptr)); - label_6->setText(QApplication::translate("Dialog", "Audio effect:", nullptr)); - crossFadeLabel->setText(QApplication::translate("Dialog", "Cross fade:", nullptr)); - label_3->setText(QApplication::translate("Dialog", "-10 Sec", nullptr)); - label_5->setText(QApplication::translate("Dialog", "0", nullptr)); - label_4->setText(QApplication::translate("Dialog", "10 Sec", nullptr)); + Dialog->setWindowTitle(QCoreApplication::translate("Dialog", "Dialog", nullptr)); + label->setText(QCoreApplication::translate("Dialog", "Audio device:", nullptr)); + label_6->setText(QCoreApplication::translate("Dialog", "Audio effect:", nullptr)); + crossFadeLabel->setText(QCoreApplication::translate("Dialog", "Cross fade:", nullptr)); + label_3->setText(QCoreApplication::translate("Dialog", "-10 Sec", nullptr)); + label_5->setText(QCoreApplication::translate("Dialog", "0", nullptr)); + label_4->setText(QCoreApplication::translate("Dialog", "10 Sec", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/signalslotdialog.ui.h b/tests/auto/tools/uic/baseline/signalslotdialog.ui.h index 984198ba83..143e281a24 100644 --- a/tests/auto/tools/uic/baseline/signalslotdialog.ui.h +++ b/tests/auto/tools/uic/baseline/signalslotdialog.ui.h @@ -133,25 +133,25 @@ public: void retranslateUi(QDialog *SignalSlotDialogClass) { - SignalSlotDialogClass->setWindowTitle(QApplication::translate("SignalSlotDialogClass", "Signals and slots", nullptr)); - slotGroupBox->setTitle(QApplication::translate("SignalSlotDialogClass", "Slots", nullptr)); + SignalSlotDialogClass->setWindowTitle(QCoreApplication::translate("SignalSlotDialogClass", "Signals and slots", nullptr)); + slotGroupBox->setTitle(QCoreApplication::translate("SignalSlotDialogClass", "Slots", nullptr)); #if QT_CONFIG(tooltip) - addSlotButton->setToolTip(QApplication::translate("SignalSlotDialogClass", "Add", nullptr)); + addSlotButton->setToolTip(QCoreApplication::translate("SignalSlotDialogClass", "Add", nullptr)); #endif // QT_CONFIG(tooltip) - addSlotButton->setText(QApplication::translate("SignalSlotDialogClass", "...", nullptr)); + addSlotButton->setText(QCoreApplication::translate("SignalSlotDialogClass", "...", nullptr)); #if QT_CONFIG(tooltip) - removeSlotButton->setToolTip(QApplication::translate("SignalSlotDialogClass", "Delete", nullptr)); + removeSlotButton->setToolTip(QCoreApplication::translate("SignalSlotDialogClass", "Delete", nullptr)); #endif // QT_CONFIG(tooltip) - removeSlotButton->setText(QApplication::translate("SignalSlotDialogClass", "...", nullptr)); - signalGroupBox->setTitle(QApplication::translate("SignalSlotDialogClass", "Signals", nullptr)); + removeSlotButton->setText(QCoreApplication::translate("SignalSlotDialogClass", "...", nullptr)); + signalGroupBox->setTitle(QCoreApplication::translate("SignalSlotDialogClass", "Signals", nullptr)); #if QT_CONFIG(tooltip) - addSignalButton->setToolTip(QApplication::translate("SignalSlotDialogClass", "Add", nullptr)); + addSignalButton->setToolTip(QCoreApplication::translate("SignalSlotDialogClass", "Add", nullptr)); #endif // QT_CONFIG(tooltip) - addSignalButton->setText(QApplication::translate("SignalSlotDialogClass", "...", nullptr)); + addSignalButton->setText(QCoreApplication::translate("SignalSlotDialogClass", "...", nullptr)); #if QT_CONFIG(tooltip) - removeSignalButton->setToolTip(QApplication::translate("SignalSlotDialogClass", "Delete", nullptr)); + removeSignalButton->setToolTip(QCoreApplication::translate("SignalSlotDialogClass", "Delete", nullptr)); #endif // QT_CONFIG(tooltip) - removeSignalButton->setText(QApplication::translate("SignalSlotDialogClass", "...", nullptr)); + removeSignalButton->setText(QCoreApplication::translate("SignalSlotDialogClass", "...", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/sslclient.ui.h b/tests/auto/tools/uic/baseline/sslclient.ui.h index 794577d3d9..755ea7827b 100644 --- a/tests/auto/tools/uic/baseline/sslclient.ui.h +++ b/tests/auto/tools/uic/baseline/sslclient.ui.h @@ -155,20 +155,20 @@ public: void retranslateUi(QWidget *Form) { - Form->setWindowTitle(QApplication::translate("Form", "Secure Socket Client", nullptr)); - hostNameLabel->setText(QApplication::translate("Form", "Host name:", nullptr)); - hostNameEdit->setText(QApplication::translate("Form", "imap.example.com", nullptr)); - portLabel->setText(QApplication::translate("Form", "Port:", nullptr)); - connectButton->setText(QApplication::translate("Form", "Connect to host", nullptr)); - sessionBox->setTitle(QApplication::translate("Form", "Active session", nullptr)); - cipherText->setText(QApplication::translate("Form", "Cryptographic Cipher:", nullptr)); - cipherLabel->setText(QApplication::translate("Form", "", nullptr)); - sessionOutput->setHtml(QApplication::translate("Form", "\n" "

    ", nullptr)); - sessionInputLabel->setText(QApplication::translate("Form", "Input:", nullptr)); - sendButton->setText(QApplication::translate("Form", "&Send", nullptr)); + sessionInputLabel->setText(QCoreApplication::translate("Form", "Input:", nullptr)); + sendButton->setText(QCoreApplication::translate("Form", "&Send", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/sslerrors.ui.h b/tests/auto/tools/uic/baseline/sslerrors.ui.h index a5c9b1b697..ac40fe8244 100644 --- a/tests/auto/tools/uic/baseline/sslerrors.ui.h +++ b/tests/auto/tools/uic/baseline/sslerrors.ui.h @@ -86,14 +86,14 @@ public: void retranslateUi(QDialog *SslErrors) { - SslErrors->setWindowTitle(QApplication::translate("SslErrors", "Unable To Validate The Connection", nullptr)); - label->setText(QApplication::translate("SslErrors", "\n" "

    Warning: One or more errors with this connection prevent validating the authenticity of the host you are connecting to. Please review the following list of errors, and click Ignore to continue, or Cancel to abort the connection.

    ", nullptr)); - certificateChainButton->setText(QApplication::translate("SslErrors", "View Certificate Chain", nullptr)); - pushButton->setText(QApplication::translate("SslErrors", "Ignore", nullptr)); - pushButton_2->setText(QApplication::translate("SslErrors", "Cancel", nullptr)); + certificateChainButton->setText(QCoreApplication::translate("SslErrors", "View Certificate Chain", nullptr)); + pushButton->setText(QCoreApplication::translate("SslErrors", "Ignore", nullptr)); + pushButton_2->setText(QCoreApplication::translate("SslErrors", "Cancel", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/statistics.ui.h b/tests/auto/tools/uic/baseline/statistics.ui.h index 02bd4cdfd1..6bbb6dbc32 100644 --- a/tests/auto/tools/uic/baseline/statistics.ui.h +++ b/tests/auto/tools/uic/baseline/statistics.ui.h @@ -179,19 +179,19 @@ public: void retranslateUi(QDialog *Statistics) { - Statistics->setWindowTitle(QApplication::translate("Statistics", "Statistics", nullptr)); - closeBtn->setText(QApplication::translate("Statistics", "&Close", nullptr)); - textLabel4->setText(QApplication::translate("Statistics", "Translation", nullptr)); - textLabel5->setText(QApplication::translate("Statistics", "Source", nullptr)); - untrWords->setText(QApplication::translate("Statistics", "0", nullptr)); - trWords->setText(QApplication::translate("Statistics", "0", nullptr)); - textLabel1->setText(QApplication::translate("Statistics", "Words:", nullptr)); - trChars->setText(QApplication::translate("Statistics", "0", nullptr)); - untrChars->setText(QApplication::translate("Statistics", "0", nullptr)); - textLabel3->setText(QApplication::translate("Statistics", "Characters:", nullptr)); - textLabel6->setText(QApplication::translate("Statistics", "Characters (with spaces):", nullptr)); - trCharsSpc->setText(QApplication::translate("Statistics", "0", nullptr)); - untrCharsSpc->setText(QApplication::translate("Statistics", "0", nullptr)); + Statistics->setWindowTitle(QCoreApplication::translate("Statistics", "Statistics", nullptr)); + closeBtn->setText(QCoreApplication::translate("Statistics", "&Close", nullptr)); + textLabel4->setText(QCoreApplication::translate("Statistics", "Translation", nullptr)); + textLabel5->setText(QCoreApplication::translate("Statistics", "Source", nullptr)); + untrWords->setText(QCoreApplication::translate("Statistics", "0", nullptr)); + trWords->setText(QCoreApplication::translate("Statistics", "0", nullptr)); + textLabel1->setText(QCoreApplication::translate("Statistics", "Words:", nullptr)); + trChars->setText(QCoreApplication::translate("Statistics", "0", nullptr)); + untrChars->setText(QCoreApplication::translate("Statistics", "0", nullptr)); + textLabel3->setText(QCoreApplication::translate("Statistics", "Characters:", nullptr)); + textLabel6->setText(QCoreApplication::translate("Statistics", "Characters (with spaces):", nullptr)); + trCharsSpc->setText(QCoreApplication::translate("Statistics", "0", nullptr)); + untrCharsSpc->setText(QCoreApplication::translate("Statistics", "0", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/stringlisteditor.ui.h b/tests/auto/tools/uic/baseline/stringlisteditor.ui.h index 2baab1b90d..91e7198793 100644 --- a/tests/auto/tools/uic/baseline/stringlisteditor.ui.h +++ b/tests/auto/tools/uic/baseline/stringlisteditor.ui.h @@ -214,25 +214,25 @@ public: void retranslateUi(QDialog *qdesigner_internal__Dialog) { - qdesigner_internal__Dialog->setWindowTitle(QApplication::translate("qdesigner_internal::Dialog", "Dialog", nullptr)); - groupBox->setTitle(QApplication::translate("qdesigner_internal::Dialog", "StringList", nullptr)); + qdesigner_internal__Dialog->setWindowTitle(QCoreApplication::translate("qdesigner_internal::Dialog", "Dialog", nullptr)); + groupBox->setTitle(QCoreApplication::translate("qdesigner_internal::Dialog", "StringList", nullptr)); #if QT_CONFIG(tooltip) - newButton->setToolTip(QApplication::translate("qdesigner_internal::Dialog", "New String", nullptr)); + newButton->setToolTip(QCoreApplication::translate("qdesigner_internal::Dialog", "New String", nullptr)); #endif // QT_CONFIG(tooltip) - newButton->setText(QApplication::translate("qdesigner_internal::Dialog", "&New", nullptr)); + newButton->setText(QCoreApplication::translate("qdesigner_internal::Dialog", "&New", nullptr)); #if QT_CONFIG(tooltip) - deleteButton->setToolTip(QApplication::translate("qdesigner_internal::Dialog", "Delete String", nullptr)); + deleteButton->setToolTip(QCoreApplication::translate("qdesigner_internal::Dialog", "Delete String", nullptr)); #endif // QT_CONFIG(tooltip) - deleteButton->setText(QApplication::translate("qdesigner_internal::Dialog", "&Delete", nullptr)); - label->setText(QApplication::translate("qdesigner_internal::Dialog", "&Value:", nullptr)); + deleteButton->setText(QCoreApplication::translate("qdesigner_internal::Dialog", "&Delete", nullptr)); + label->setText(QCoreApplication::translate("qdesigner_internal::Dialog", "&Value:", nullptr)); #if QT_CONFIG(tooltip) - upButton->setToolTip(QApplication::translate("qdesigner_internal::Dialog", "Move String Up", nullptr)); + upButton->setToolTip(QCoreApplication::translate("qdesigner_internal::Dialog", "Move String Up", nullptr)); #endif // QT_CONFIG(tooltip) - upButton->setText(QApplication::translate("qdesigner_internal::Dialog", "Up", nullptr)); + upButton->setText(QCoreApplication::translate("qdesigner_internal::Dialog", "Up", nullptr)); #if QT_CONFIG(tooltip) - downButton->setToolTip(QApplication::translate("qdesigner_internal::Dialog", "Move String Down", nullptr)); + downButton->setToolTip(QCoreApplication::translate("qdesigner_internal::Dialog", "Move String Down", nullptr)); #endif // QT_CONFIG(tooltip) - downButton->setText(QApplication::translate("qdesigner_internal::Dialog", "Down", nullptr)); + downButton->setText(QCoreApplication::translate("qdesigner_internal::Dialog", "Down", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/stylesheeteditor.ui.h b/tests/auto/tools/uic/baseline/stylesheeteditor.ui.h index 4206f35857..2e73926c0c 100644 --- a/tests/auto/tools/uic/baseline/stylesheeteditor.ui.h +++ b/tests/auto/tools/uic/baseline/stylesheeteditor.ui.h @@ -130,14 +130,14 @@ public: void retranslateUi(QWidget *StyleSheetEditor) { - StyleSheetEditor->setWindowTitle(QApplication::translate("StyleSheetEditor", "Style Editor", nullptr)); - styleSheetCombo->setItemText(0, QApplication::translate("StyleSheetEditor", "Default", nullptr)); - styleSheetCombo->setItemText(1, QApplication::translate("StyleSheetEditor", "Coffee", nullptr)); - styleSheetCombo->setItemText(2, QApplication::translate("StyleSheetEditor", "Pagefold", nullptr)); + StyleSheetEditor->setWindowTitle(QCoreApplication::translate("StyleSheetEditor", "Style Editor", nullptr)); + styleSheetCombo->setItemText(0, QCoreApplication::translate("StyleSheetEditor", "Default", nullptr)); + styleSheetCombo->setItemText(1, QCoreApplication::translate("StyleSheetEditor", "Coffee", nullptr)); + styleSheetCombo->setItemText(2, QCoreApplication::translate("StyleSheetEditor", "Pagefold", nullptr)); - label_7->setText(QApplication::translate("StyleSheetEditor", "Style:", nullptr)); - applyButton->setText(QApplication::translate("StyleSheetEditor", "&Apply", nullptr)); - label_8->setText(QApplication::translate("StyleSheetEditor", "Style Sheet:", nullptr)); + label_7->setText(QCoreApplication::translate("StyleSheetEditor", "Style:", nullptr)); + applyButton->setText(QCoreApplication::translate("StyleSheetEditor", "&Apply", nullptr)); + label_8->setText(QCoreApplication::translate("StyleSheetEditor", "Style Sheet:", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/tabbedbrowser.ui.h b/tests/auto/tools/uic/baseline/tabbedbrowser.ui.h index d657a6cfcc..18a62df44a 100644 --- a/tests/auto/tools/uic/baseline/tabbedbrowser.ui.h +++ b/tests/auto/tools/uic/baseline/tabbedbrowser.ui.h @@ -181,14 +181,14 @@ public: void retranslateUi(QWidget *TabbedBrowser) { - TabbedBrowser->setWindowTitle(QApplication::translate("TabbedBrowser", "TabbedBrowser", nullptr)); - tab->setTabText(tab->indexOf(frontpage), QApplication::translate("TabbedBrowser", "Untitled", nullptr)); + TabbedBrowser->setWindowTitle(QCoreApplication::translate("TabbedBrowser", "TabbedBrowser", nullptr)); + tab->setTabText(tab->indexOf(frontpage), QCoreApplication::translate("TabbedBrowser", "Untitled", nullptr)); toolClose->setText(QString()); - toolPrevious->setText(QApplication::translate("TabbedBrowser", "Previous", nullptr)); - toolNext->setText(QApplication::translate("TabbedBrowser", "Next", nullptr)); - checkCase->setText(QApplication::translate("TabbedBrowser", "Case Sensitive", nullptr)); - checkWholeWords->setText(QApplication::translate("TabbedBrowser", "Whole words", nullptr)); - labelWrapped->setText(QApplication::translate("TabbedBrowser", " Search wrapped", nullptr)); + toolPrevious->setText(QCoreApplication::translate("TabbedBrowser", "Previous", nullptr)); + toolNext->setText(QCoreApplication::translate("TabbedBrowser", "Next", nullptr)); + checkCase->setText(QCoreApplication::translate("TabbedBrowser", "Case Sensitive", nullptr)); + checkWholeWords->setText(QCoreApplication::translate("TabbedBrowser", "Whole words", nullptr)); + labelWrapped->setText(QCoreApplication::translate("TabbedBrowser", " Search wrapped", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/tablewidgeteditor.ui.h b/tests/auto/tools/uic/baseline/tablewidgeteditor.ui.h index f108c05fbd..4559bd910b 100644 --- a/tests/auto/tools/uic/baseline/tablewidgeteditor.ui.h +++ b/tests/auto/tools/uic/baseline/tablewidgeteditor.ui.h @@ -311,54 +311,54 @@ public: void retranslateUi(QDialog *qdesigner_internal__TableWidgetEditor) { - qdesigner_internal__TableWidgetEditor->setWindowTitle(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Edit Table Widget", nullptr)); - itemsBox->setTitle(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Table Items", nullptr)); + qdesigner_internal__TableWidgetEditor->setWindowTitle(QCoreApplication::translate("qdesigner_internal::TableWidgetEditor", "Edit Table Widget", nullptr)); + itemsBox->setTitle(QCoreApplication::translate("qdesigner_internal::TableWidgetEditor", "Table Items", nullptr)); #if QT_CONFIG(tooltip) - tableWidget->setToolTip(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Table Items", nullptr)); + tableWidget->setToolTip(QCoreApplication::translate("qdesigner_internal::TableWidgetEditor", "Table Items", nullptr)); #endif // QT_CONFIG(tooltip) - label_3->setText(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Icon", nullptr)); - columnsBox->setTitle(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Columns", nullptr)); + label_3->setText(QCoreApplication::translate("qdesigner_internal::TableWidgetEditor", "Icon", nullptr)); + columnsBox->setTitle(QCoreApplication::translate("qdesigner_internal::TableWidgetEditor", "Columns", nullptr)); #if QT_CONFIG(tooltip) - columnsListWidget->setToolTip(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Table Columns", nullptr)); + columnsListWidget->setToolTip(QCoreApplication::translate("qdesigner_internal::TableWidgetEditor", "Table Columns", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(tooltip) - newColumnButton->setToolTip(QApplication::translate("qdesigner_internal::TableWidgetEditor", "New Column", nullptr)); + newColumnButton->setToolTip(QCoreApplication::translate("qdesigner_internal::TableWidgetEditor", "New Column", nullptr)); #endif // QT_CONFIG(tooltip) - newColumnButton->setText(QApplication::translate("qdesigner_internal::TableWidgetEditor", "New", nullptr)); + newColumnButton->setText(QCoreApplication::translate("qdesigner_internal::TableWidgetEditor", "New", nullptr)); #if QT_CONFIG(tooltip) - deleteColumnButton->setToolTip(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Delete Column", nullptr)); + deleteColumnButton->setToolTip(QCoreApplication::translate("qdesigner_internal::TableWidgetEditor", "Delete Column", nullptr)); #endif // QT_CONFIG(tooltip) - deleteColumnButton->setText(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Delete", nullptr)); + deleteColumnButton->setText(QCoreApplication::translate("qdesigner_internal::TableWidgetEditor", "Delete", nullptr)); #if QT_CONFIG(tooltip) - moveColumnUpButton->setToolTip(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Move Column Up", nullptr)); + moveColumnUpButton->setToolTip(QCoreApplication::translate("qdesigner_internal::TableWidgetEditor", "Move Column Up", nullptr)); #endif // QT_CONFIG(tooltip) - moveColumnUpButton->setText(QApplication::translate("qdesigner_internal::TableWidgetEditor", "U", nullptr)); + moveColumnUpButton->setText(QCoreApplication::translate("qdesigner_internal::TableWidgetEditor", "U", nullptr)); #if QT_CONFIG(tooltip) - moveColumnDownButton->setToolTip(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Move Column Down", nullptr)); + moveColumnDownButton->setToolTip(QCoreApplication::translate("qdesigner_internal::TableWidgetEditor", "Move Column Down", nullptr)); #endif // QT_CONFIG(tooltip) - moveColumnDownButton->setText(QApplication::translate("qdesigner_internal::TableWidgetEditor", "D", nullptr)); - label->setText(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Icon", nullptr)); - rowsBox->setTitle(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Rows", nullptr)); + moveColumnDownButton->setText(QCoreApplication::translate("qdesigner_internal::TableWidgetEditor", "D", nullptr)); + label->setText(QCoreApplication::translate("qdesigner_internal::TableWidgetEditor", "Icon", nullptr)); + rowsBox->setTitle(QCoreApplication::translate("qdesigner_internal::TableWidgetEditor", "Rows", nullptr)); #if QT_CONFIG(tooltip) - rowsListWidget->setToolTip(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Table Rows", nullptr)); + rowsListWidget->setToolTip(QCoreApplication::translate("qdesigner_internal::TableWidgetEditor", "Table Rows", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(tooltip) - newRowButton->setToolTip(QApplication::translate("qdesigner_internal::TableWidgetEditor", "New Row", nullptr)); + newRowButton->setToolTip(QCoreApplication::translate("qdesigner_internal::TableWidgetEditor", "New Row", nullptr)); #endif // QT_CONFIG(tooltip) - newRowButton->setText(QApplication::translate("qdesigner_internal::TableWidgetEditor", "New", nullptr)); + newRowButton->setText(QCoreApplication::translate("qdesigner_internal::TableWidgetEditor", "New", nullptr)); #if QT_CONFIG(tooltip) - deleteRowButton->setToolTip(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Delete Row", nullptr)); + deleteRowButton->setToolTip(QCoreApplication::translate("qdesigner_internal::TableWidgetEditor", "Delete Row", nullptr)); #endif // QT_CONFIG(tooltip) - deleteRowButton->setText(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Delete", nullptr)); + deleteRowButton->setText(QCoreApplication::translate("qdesigner_internal::TableWidgetEditor", "Delete", nullptr)); #if QT_CONFIG(tooltip) - moveRowUpButton->setToolTip(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Move Row Up", nullptr)); + moveRowUpButton->setToolTip(QCoreApplication::translate("qdesigner_internal::TableWidgetEditor", "Move Row Up", nullptr)); #endif // QT_CONFIG(tooltip) - moveRowUpButton->setText(QApplication::translate("qdesigner_internal::TableWidgetEditor", "U", nullptr)); + moveRowUpButton->setText(QCoreApplication::translate("qdesigner_internal::TableWidgetEditor", "U", nullptr)); #if QT_CONFIG(tooltip) - moveRowDownButton->setToolTip(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Move Row Down", nullptr)); + moveRowDownButton->setToolTip(QCoreApplication::translate("qdesigner_internal::TableWidgetEditor", "Move Row Down", nullptr)); #endif // QT_CONFIG(tooltip) - moveRowDownButton->setText(QApplication::translate("qdesigner_internal::TableWidgetEditor", "D", nullptr)); - label_2->setText(QApplication::translate("qdesigner_internal::TableWidgetEditor", "Icon", nullptr)); + moveRowDownButton->setText(QCoreApplication::translate("qdesigner_internal::TableWidgetEditor", "D", nullptr)); + label_2->setText(QCoreApplication::translate("qdesigner_internal::TableWidgetEditor", "Icon", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/tetrixwindow.ui.h b/tests/auto/tools/uic/baseline/tetrixwindow.ui.h index 53d94b7f50..340acbd9f2 100644 --- a/tests/auto/tools/uic/baseline/tetrixwindow.ui.h +++ b/tests/auto/tools/uic/baseline/tetrixwindow.ui.h @@ -147,15 +147,15 @@ public: void retranslateUi(QWidget *TetrixWindow) { - TetrixWindow->setWindowTitle(QApplication::translate("TetrixWindow", "Tetrix", nullptr)); - startButton->setText(QApplication::translate("TetrixWindow", "&Start", nullptr)); - linesRemovedLabel->setText(QApplication::translate("TetrixWindow", "LINES REMOVED", nullptr)); - pauseButton->setText(QApplication::translate("TetrixWindow", "&Pause", nullptr)); - levelLabel->setText(QApplication::translate("TetrixWindow", "LEVEL", nullptr)); - nextLabel->setText(QApplication::translate("TetrixWindow", "NEXT", nullptr)); - scoreLabel->setText(QApplication::translate("TetrixWindow", "SCORE", nullptr)); + TetrixWindow->setWindowTitle(QCoreApplication::translate("TetrixWindow", "Tetrix", nullptr)); + startButton->setText(QCoreApplication::translate("TetrixWindow", "&Start", nullptr)); + linesRemovedLabel->setText(QCoreApplication::translate("TetrixWindow", "LINES REMOVED", nullptr)); + pauseButton->setText(QCoreApplication::translate("TetrixWindow", "&Pause", nullptr)); + levelLabel->setText(QCoreApplication::translate("TetrixWindow", "LEVEL", nullptr)); + nextLabel->setText(QCoreApplication::translate("TetrixWindow", "NEXT", nullptr)); + scoreLabel->setText(QCoreApplication::translate("TetrixWindow", "SCORE", nullptr)); nextPieceLabel->setText(QString()); - quitButton->setText(QApplication::translate("TetrixWindow", "&Quit", nullptr)); + quitButton->setText(QCoreApplication::translate("TetrixWindow", "&Quit", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/textfinder.ui.h b/tests/auto/tools/uic/baseline/textfinder.ui.h index 1cc082b34c..38bdf756c2 100644 --- a/tests/auto/tools/uic/baseline/textfinder.ui.h +++ b/tests/auto/tools/uic/baseline/textfinder.ui.h @@ -93,9 +93,9 @@ public: void retranslateUi(QWidget *Form) { - Form->setWindowTitle(QApplication::translate("Form", "Find Text", nullptr)); - searchLabel->setText(QApplication::translate("Form", "&Keyword:", nullptr)); - findButton->setText(QApplication::translate("Form", "&Find", nullptr)); + Form->setWindowTitle(QCoreApplication::translate("Form", "Find Text", nullptr)); + searchLabel->setText(QCoreApplication::translate("Form", "&Keyword:", nullptr)); + findButton->setText(QCoreApplication::translate("Form", "&Find", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/topicchooser.ui.h b/tests/auto/tools/uic/baseline/topicchooser.ui.h index 00e30bd546..a89f62c4b5 100644 --- a/tests/auto/tools/uic/baseline/topicchooser.ui.h +++ b/tests/auto/tools/uic/baseline/topicchooser.ui.h @@ -100,10 +100,10 @@ public: void retranslateUi(QDialog *TopicChooser) { - TopicChooser->setWindowTitle(QApplication::translate("TopicChooser", "Choose Topic", nullptr)); - label->setText(QApplication::translate("TopicChooser", "&Topics", nullptr)); - buttonDisplay->setText(QApplication::translate("TopicChooser", "&Display", nullptr)); - buttonCancel->setText(QApplication::translate("TopicChooser", "&Close", nullptr)); + TopicChooser->setWindowTitle(QCoreApplication::translate("TopicChooser", "Choose Topic", nullptr)); + label->setText(QCoreApplication::translate("TopicChooser", "&Topics", nullptr)); + buttonDisplay->setText(QCoreApplication::translate("TopicChooser", "&Display", nullptr)); + buttonCancel->setText(QCoreApplication::translate("TopicChooser", "&Close", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/translatedialog.ui.h b/tests/auto/tools/uic/baseline/translatedialog.ui.h index dec725ac8f..10390c62df 100644 --- a/tests/auto/tools/uic/baseline/translatedialog.ui.h +++ b/tests/auto/tools/uic/baseline/translatedialog.ui.h @@ -205,34 +205,34 @@ public: void retranslateUi(QDialog *TranslateDialog) { - TranslateDialog->setWindowTitle(QApplication::translate("TranslateDialog", "Qt Linguist", nullptr)); + TranslateDialog->setWindowTitle(QCoreApplication::translate("TranslateDialog", "Qt Linguist", nullptr)); #if QT_CONFIG(whatsthis) - TranslateDialog->setWhatsThis(QApplication::translate("TranslateDialog", "This window allows you to search for some text in the translation source file.", nullptr)); + TranslateDialog->setWhatsThis(QCoreApplication::translate("TranslateDialog", "This window allows you to search for some text in the translation source file.", nullptr)); #endif // QT_CONFIG(whatsthis) #if QT_CONFIG(whatsthis) - ledTranslateTo->setWhatsThis(QApplication::translate("TranslateDialog", "Type in the text to search for.", nullptr)); + ledTranslateTo->setWhatsThis(QCoreApplication::translate("TranslateDialog", "Type in the text to search for.", nullptr)); #endif // QT_CONFIG(whatsthis) - findWhat->setText(QApplication::translate("TranslateDialog", "Find &source text:", nullptr)); - translateTo->setText(QApplication::translate("TranslateDialog", "&Translate to:", nullptr)); + findWhat->setText(QCoreApplication::translate("TranslateDialog", "Find &source text:", nullptr)); + translateTo->setText(QCoreApplication::translate("TranslateDialog", "&Translate to:", nullptr)); #if QT_CONFIG(whatsthis) - ledFindWhat->setWhatsThis(QApplication::translate("TranslateDialog", "Type in the text to search for.", nullptr)); + ledFindWhat->setWhatsThis(QCoreApplication::translate("TranslateDialog", "Type in the text to search for.", nullptr)); #endif // QT_CONFIG(whatsthis) - groupBox->setTitle(QApplication::translate("TranslateDialog", "Search options", nullptr)); + groupBox->setTitle(QCoreApplication::translate("TranslateDialog", "Search options", nullptr)); #if QT_CONFIG(whatsthis) - ckMatchCase->setWhatsThis(QApplication::translate("TranslateDialog", "Texts such as 'TeX' and 'tex' are considered as different when checked.", nullptr)); + ckMatchCase->setWhatsThis(QCoreApplication::translate("TranslateDialog", "Texts such as 'TeX' and 'tex' are considered as different when checked.", nullptr)); #endif // QT_CONFIG(whatsthis) - ckMatchCase->setText(QApplication::translate("TranslateDialog", "Match &case", nullptr)); - ckMarkFinished->setText(QApplication::translate("TranslateDialog", "Mark new translation as &finished", nullptr)); + ckMatchCase->setText(QCoreApplication::translate("TranslateDialog", "Match &case", nullptr)); + ckMarkFinished->setText(QCoreApplication::translate("TranslateDialog", "Mark new translation as &finished", nullptr)); #if QT_CONFIG(whatsthis) - findNxt->setWhatsThis(QApplication::translate("TranslateDialog", "Click here to find the next occurrence of the text you typed in.", nullptr)); + findNxt->setWhatsThis(QCoreApplication::translate("TranslateDialog", "Click here to find the next occurrence of the text you typed in.", nullptr)); #endif // QT_CONFIG(whatsthis) - findNxt->setText(QApplication::translate("TranslateDialog", "Find Next", nullptr)); - translate->setText(QApplication::translate("TranslateDialog", "Translate", nullptr)); - translateAll->setText(QApplication::translate("TranslateDialog", "Translate All", nullptr)); + findNxt->setText(QCoreApplication::translate("TranslateDialog", "Find Next", nullptr)); + translate->setText(QCoreApplication::translate("TranslateDialog", "Translate", nullptr)); + translateAll->setText(QCoreApplication::translate("TranslateDialog", "Translate All", nullptr)); #if QT_CONFIG(whatsthis) - cancel->setWhatsThis(QApplication::translate("TranslateDialog", "Click here to close this window.", nullptr)); + cancel->setWhatsThis(QCoreApplication::translate("TranslateDialog", "Click here to close this window.", nullptr)); #endif // QT_CONFIG(whatsthis) - cancel->setText(QApplication::translate("TranslateDialog", "Cancel", nullptr)); + cancel->setText(QCoreApplication::translate("TranslateDialog", "Cancel", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/translationsettings.ui.h b/tests/auto/tools/uic/baseline/translationsettings.ui.h index 88b0128e1b..5e0f1520a0 100644 --- a/tests/auto/tools/uic/baseline/translationsettings.ui.h +++ b/tests/auto/tools/uic/baseline/translationsettings.ui.h @@ -99,10 +99,10 @@ public: void retranslateUi(QDialog *TranslationSettings) { - TranslationSettings->setWindowTitle(QApplication::translate("TranslationSettings", "Qt Linguist - Translation file settings", nullptr)); - groupBox->setTitle(QApplication::translate("TranslationSettings", "Target language", nullptr)); - label->setText(QApplication::translate("TranslationSettings", "Language", nullptr)); - lblCountry->setText(QApplication::translate("TranslationSettings", "Country/Region", nullptr)); + TranslationSettings->setWindowTitle(QCoreApplication::translate("TranslationSettings", "Qt Linguist - Translation file settings", nullptr)); + groupBox->setTitle(QCoreApplication::translate("TranslationSettings", "Target language", nullptr)); + label->setText(QCoreApplication::translate("TranslationSettings", "Language", nullptr)); + lblCountry->setText(QCoreApplication::translate("TranslationSettings", "Country/Region", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/treewidgeteditor.ui.h b/tests/auto/tools/uic/baseline/treewidgeteditor.ui.h index 57347f2464..395d66a999 100644 --- a/tests/auto/tools/uic/baseline/treewidgeteditor.ui.h +++ b/tests/auto/tools/uic/baseline/treewidgeteditor.ui.h @@ -276,63 +276,63 @@ public: void retranslateUi(QDialog *qdesigner_internal__TreeWidgetEditor) { - qdesigner_internal__TreeWidgetEditor->setWindowTitle(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Edit Tree Widget", nullptr)); - itemsBox->setTitle(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Tree Items", nullptr)); + qdesigner_internal__TreeWidgetEditor->setWindowTitle(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "Edit Tree Widget", nullptr)); + itemsBox->setTitle(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "Tree Items", nullptr)); QTreeWidgetItem *___qtreewidgetitem = treeWidget->headerItem(); - ___qtreewidgetitem->setText(0, QApplication::translate("qdesigner_internal::TreeWidgetEditor", "1", nullptr)); + ___qtreewidgetitem->setText(0, QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "1", nullptr)); #if QT_CONFIG(tooltip) - treeWidget->setToolTip(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Tree Items", nullptr)); + treeWidget->setToolTip(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "Tree Items", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(tooltip) - newItemButton->setToolTip(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "New Item", nullptr)); + newItemButton->setToolTip(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "New Item", nullptr)); #endif // QT_CONFIG(tooltip) - newItemButton->setText(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "&New", nullptr)); + newItemButton->setText(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "&New", nullptr)); #if QT_CONFIG(tooltip) - newSubItemButton->setToolTip(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "New Subitem", nullptr)); + newSubItemButton->setToolTip(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "New Subitem", nullptr)); #endif // QT_CONFIG(tooltip) - newSubItemButton->setText(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "New &Subitem", nullptr)); + newSubItemButton->setText(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "New &Subitem", nullptr)); #if QT_CONFIG(tooltip) - deleteItemButton->setToolTip(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Delete Item", nullptr)); + deleteItemButton->setToolTip(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "Delete Item", nullptr)); #endif // QT_CONFIG(tooltip) - deleteItemButton->setText(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "&Delete", nullptr)); + deleteItemButton->setText(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "&Delete", nullptr)); #if QT_CONFIG(tooltip) - moveItemLeftButton->setToolTip(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Move Item Left (before Parent Item)", nullptr)); + moveItemLeftButton->setToolTip(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "Move Item Left (before Parent Item)", nullptr)); #endif // QT_CONFIG(tooltip) - moveItemLeftButton->setText(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "L", nullptr)); + moveItemLeftButton->setText(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "L", nullptr)); #if QT_CONFIG(tooltip) - moveItemRightButton->setToolTip(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Move Item Right (as a First Subitem of the Next Sibling Item)", nullptr)); + moveItemRightButton->setToolTip(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "Move Item Right (as a First Subitem of the Next Sibling Item)", nullptr)); #endif // QT_CONFIG(tooltip) - moveItemRightButton->setText(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "R", nullptr)); + moveItemRightButton->setText(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "R", nullptr)); #if QT_CONFIG(tooltip) - moveItemUpButton->setToolTip(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Move Item Up", nullptr)); + moveItemUpButton->setToolTip(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "Move Item Up", nullptr)); #endif // QT_CONFIG(tooltip) - moveItemUpButton->setText(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "U", nullptr)); + moveItemUpButton->setText(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "U", nullptr)); #if QT_CONFIG(tooltip) - moveItemDownButton->setToolTip(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Move Item Down", nullptr)); + moveItemDownButton->setToolTip(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "Move Item Down", nullptr)); #endif // QT_CONFIG(tooltip) - moveItemDownButton->setText(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "D", nullptr)); - label_2->setText(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Icon", nullptr)); - columnsBox->setTitle(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Columns", nullptr)); + moveItemDownButton->setText(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "D", nullptr)); + label_2->setText(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "Icon", nullptr)); + columnsBox->setTitle(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "Columns", nullptr)); #if QT_CONFIG(tooltip) - listWidget->setToolTip(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Tree Columns", nullptr)); + listWidget->setToolTip(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "Tree Columns", nullptr)); #endif // QT_CONFIG(tooltip) #if QT_CONFIG(tooltip) - newColumnButton->setToolTip(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "New Column", nullptr)); + newColumnButton->setToolTip(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "New Column", nullptr)); #endif // QT_CONFIG(tooltip) - newColumnButton->setText(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "New", nullptr)); + newColumnButton->setText(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "New", nullptr)); #if QT_CONFIG(tooltip) - deleteColumnButton->setToolTip(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Delete Column", nullptr)); + deleteColumnButton->setToolTip(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "Delete Column", nullptr)); #endif // QT_CONFIG(tooltip) - deleteColumnButton->setText(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Delete", nullptr)); + deleteColumnButton->setText(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "Delete", nullptr)); #if QT_CONFIG(tooltip) - moveColumnUpButton->setToolTip(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Move Column Up", nullptr)); + moveColumnUpButton->setToolTip(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "Move Column Up", nullptr)); #endif // QT_CONFIG(tooltip) - moveColumnUpButton->setText(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "U", nullptr)); + moveColumnUpButton->setText(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "U", nullptr)); #if QT_CONFIG(tooltip) - moveColumnDownButton->setToolTip(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Move Column Down", nullptr)); + moveColumnDownButton->setToolTip(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "Move Column Down", nullptr)); #endif // QT_CONFIG(tooltip) - moveColumnDownButton->setText(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "D", nullptr)); - label->setText(QApplication::translate("qdesigner_internal::TreeWidgetEditor", "Icon", nullptr)); + moveColumnDownButton->setText(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "D", nullptr)); + label->setText(QCoreApplication::translate("qdesigner_internal::TreeWidgetEditor", "Icon", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/trpreviewtool.ui.h b/tests/auto/tools/uic/baseline/trpreviewtool.ui.h index e99bf81a4c..95ebed0f6f 100644 --- a/tests/auto/tools/uic/baseline/trpreviewtool.ui.h +++ b/tests/auto/tools/uic/baseline/trpreviewtool.ui.h @@ -162,21 +162,21 @@ public: void retranslateUi(QMainWindow *TrPreviewToolClass) { - TrPreviewToolClass->setWindowTitle(QApplication::translate("TrPreviewToolClass", "Qt Translation Preview Tool", nullptr)); - actionOpenForm->setText(QApplication::translate("TrPreviewToolClass", "&Open Form...", nullptr)); - actionLoadTranslation->setText(QApplication::translate("TrPreviewToolClass", "&Load Translation...", nullptr)); - actionReloadTranslations->setText(QApplication::translate("TrPreviewToolClass", "&Reload Translations", nullptr)); + TrPreviewToolClass->setWindowTitle(QCoreApplication::translate("TrPreviewToolClass", "Qt Translation Preview Tool", nullptr)); + actionOpenForm->setText(QCoreApplication::translate("TrPreviewToolClass", "&Open Form...", nullptr)); + actionLoadTranslation->setText(QCoreApplication::translate("TrPreviewToolClass", "&Load Translation...", nullptr)); + actionReloadTranslations->setText(QCoreApplication::translate("TrPreviewToolClass", "&Reload Translations", nullptr)); #if QT_CONFIG(shortcut) - actionReloadTranslations->setShortcut(QApplication::translate("TrPreviewToolClass", "F5", nullptr)); + actionReloadTranslations->setShortcut(QCoreApplication::translate("TrPreviewToolClass", "F5", nullptr)); #endif // QT_CONFIG(shortcut) - actionClose->setText(QApplication::translate("TrPreviewToolClass", "&Close", nullptr)); - actionAbout->setText(QApplication::translate("TrPreviewToolClass", "About", nullptr)); - actionAbout_Qt->setText(QApplication::translate("TrPreviewToolClass", "About Qt", nullptr)); - menuView->setTitle(QApplication::translate("TrPreviewToolClass", "&View", nullptr)); - menuViewViews->setTitle(QApplication::translate("TrPreviewToolClass", "&Views", nullptr)); - menuHelp->setTitle(QApplication::translate("TrPreviewToolClass", "&Help", nullptr)); - menuFile->setTitle(QApplication::translate("TrPreviewToolClass", "&File", nullptr)); - dwForms->setWindowTitle(QApplication::translate("TrPreviewToolClass", "Forms", nullptr)); + actionClose->setText(QCoreApplication::translate("TrPreviewToolClass", "&Close", nullptr)); + actionAbout->setText(QCoreApplication::translate("TrPreviewToolClass", "About", nullptr)); + actionAbout_Qt->setText(QCoreApplication::translate("TrPreviewToolClass", "About Qt", nullptr)); + menuView->setTitle(QCoreApplication::translate("TrPreviewToolClass", "&View", nullptr)); + menuViewViews->setTitle(QCoreApplication::translate("TrPreviewToolClass", "&Views", nullptr)); + menuHelp->setTitle(QCoreApplication::translate("TrPreviewToolClass", "&Help", nullptr)); + menuFile->setTitle(QCoreApplication::translate("TrPreviewToolClass", "&File", nullptr)); + dwForms->setWindowTitle(QCoreApplication::translate("TrPreviewToolClass", "Forms", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/validators.ui.h b/tests/auto/tools/uic/baseline/validators.ui.h index d0ae777f65..45d9c5aac6 100644 --- a/tests/auto/tools/uic/baseline/validators.ui.h +++ b/tests/auto/tools/uic/baseline/validators.ui.h @@ -375,22 +375,22 @@ public: void retranslateUi(QWidget *ValidatorsForm) { - ValidatorsForm->setWindowTitle(QApplication::translate("ValidatorsForm", "Form", nullptr)); - groupBox->setTitle(QApplication::translate("ValidatorsForm", "QIntValidator", nullptr)); - label->setText(QApplication::translate("ValidatorsForm", "Min:", nullptr)); - label_2->setText(QApplication::translate("ValidatorsForm", "Max:", nullptr)); - label_7->setText(QApplication::translate("ValidatorsForm", "editingFinished()", nullptr)); - groupBox_2->setTitle(QApplication::translate("ValidatorsForm", "QDoubleValidator", nullptr)); - label_3->setText(QApplication::translate("ValidatorsForm", "Min:", nullptr)); - label_5->setText(QApplication::translate("ValidatorsForm", "Format:", nullptr)); - doubleFormat->setItemText(0, QApplication::translate("ValidatorsForm", "Standard", nullptr)); - doubleFormat->setItemText(1, QApplication::translate("ValidatorsForm", "Scientific", nullptr)); + ValidatorsForm->setWindowTitle(QCoreApplication::translate("ValidatorsForm", "Form", nullptr)); + groupBox->setTitle(QCoreApplication::translate("ValidatorsForm", "QIntValidator", nullptr)); + label->setText(QCoreApplication::translate("ValidatorsForm", "Min:", nullptr)); + label_2->setText(QCoreApplication::translate("ValidatorsForm", "Max:", nullptr)); + label_7->setText(QCoreApplication::translate("ValidatorsForm", "editingFinished()", nullptr)); + groupBox_2->setTitle(QCoreApplication::translate("ValidatorsForm", "QDoubleValidator", nullptr)); + label_3->setText(QCoreApplication::translate("ValidatorsForm", "Min:", nullptr)); + label_5->setText(QCoreApplication::translate("ValidatorsForm", "Format:", nullptr)); + doubleFormat->setItemText(0, QCoreApplication::translate("ValidatorsForm", "Standard", nullptr)); + doubleFormat->setItemText(1, QCoreApplication::translate("ValidatorsForm", "Scientific", nullptr)); - label_4->setText(QApplication::translate("ValidatorsForm", "Max:", nullptr)); - label_6->setText(QApplication::translate("ValidatorsForm", "Decimals:", nullptr)); + label_4->setText(QCoreApplication::translate("ValidatorsForm", "Max:", nullptr)); + label_6->setText(QCoreApplication::translate("ValidatorsForm", "Decimals:", nullptr)); doubleLedWidget->setText(QString()); - label_8->setText(QApplication::translate("ValidatorsForm", "editingFinished()", nullptr)); - pushButton->setText(QApplication::translate("ValidatorsForm", "Quit", nullptr)); + label_8->setText(QCoreApplication::translate("ValidatorsForm", "editingFinished()", nullptr)); + pushButton->setText(QCoreApplication::translate("ValidatorsForm", "Quit", nullptr)); } // retranslateUi }; diff --git a/tests/auto/tools/uic/baseline/wateringconfigdialog.ui.h b/tests/auto/tools/uic/baseline/wateringconfigdialog.ui.h index 822a22336d..aa005593c0 100644 --- a/tests/auto/tools/uic/baseline/wateringconfigdialog.ui.h +++ b/tests/auto/tools/uic/baseline/wateringconfigdialog.ui.h @@ -250,34 +250,34 @@ public: void retranslateUi(QDialog *WateringConfigDialog) { - WateringConfigDialog->setWindowTitle(QApplication::translate("WateringConfigDialog", "Watering Configuration", nullptr)); - label_3->setText(QApplication::translate("WateringConfigDialog", "Plant:", nullptr)); - plantComboBox->setItemText(0, QApplication::translate("WateringConfigDialog", "Squash", nullptr)); - plantComboBox->setItemText(1, QApplication::translate("WateringConfigDialog", "Bean", nullptr)); - plantComboBox->setItemText(2, QApplication::translate("WateringConfigDialog", "Carrot", nullptr)); - plantComboBox->setItemText(3, QApplication::translate("WateringConfigDialog", "Strawberry", nullptr)); - plantComboBox->setItemText(4, QApplication::translate("WateringConfigDialog", "Raspberry", nullptr)); - plantComboBox->setItemText(5, QApplication::translate("WateringConfigDialog", "Blueberry", nullptr)); + WateringConfigDialog->setWindowTitle(QCoreApplication::translate("WateringConfigDialog", "Watering Configuration", nullptr)); + label_3->setText(QCoreApplication::translate("WateringConfigDialog", "Plant:", nullptr)); + plantComboBox->setItemText(0, QCoreApplication::translate("WateringConfigDialog", "Squash", nullptr)); + plantComboBox->setItemText(1, QCoreApplication::translate("WateringConfigDialog", "Bean", nullptr)); + plantComboBox->setItemText(2, QCoreApplication::translate("WateringConfigDialog", "Carrot", nullptr)); + plantComboBox->setItemText(3, QCoreApplication::translate("WateringConfigDialog", "Strawberry", nullptr)); + plantComboBox->setItemText(4, QCoreApplication::translate("WateringConfigDialog", "Raspberry", nullptr)); + plantComboBox->setItemText(5, QCoreApplication::translate("WateringConfigDialog", "Blueberry", nullptr)); - label_2->setText(QApplication::translate("WateringConfigDialog", "Water when:", nullptr)); - temperatureCheckBox->setText(QApplication::translate("WateringConfigDialog", "Temperature is higher than:", nullptr)); + label_2->setText(QCoreApplication::translate("WateringConfigDialog", "Water when:", nullptr)); + temperatureCheckBox->setText(QCoreApplication::translate("WateringConfigDialog", "Temperature is higher than:", nullptr)); temperatureSpinBox->setSpecialValueText(QString()); - temperatureSpinBox->setSuffix(QApplication::translate("WateringConfigDialog", "C", nullptr)); - rainCheckBox->setText(QApplication::translate("WateringConfigDialog", "Rain less than:", nullptr)); + temperatureSpinBox->setSuffix(QCoreApplication::translate("WateringConfigDialog", "C", nullptr)); + rainCheckBox->setText(QCoreApplication::translate("WateringConfigDialog", "Rain less than:", nullptr)); rainSpinBox->setSpecialValueText(QString()); - rainSpinBox->setSuffix(QApplication::translate("WateringConfigDialog", "mm", nullptr)); - label->setText(QApplication::translate("WateringConfigDialog", "Starting Time:", nullptr)); - label_4->setText(QApplication::translate("WateringConfigDialog", "Amount:", nullptr)); - amountSpinBox->setSuffix(QApplication::translate("WateringConfigDialog", "l", nullptr)); - label_5->setText(QApplication::translate("WateringConfigDialog", "Source:", nullptr)); - sourceComboBox->setItemText(0, QApplication::translate("WateringConfigDialog", "Foundain", nullptr)); - sourceComboBox->setItemText(1, QApplication::translate("WateringConfigDialog", "River", nullptr)); - sourceComboBox->setItemText(2, QApplication::translate("WateringConfigDialog", "Lake", nullptr)); - sourceComboBox->setItemText(3, QApplication::translate("WateringConfigDialog", "Public Water System", nullptr)); + rainSpinBox->setSuffix(QCoreApplication::translate("WateringConfigDialog", "mm", nullptr)); + label->setText(QCoreApplication::translate("WateringConfigDialog", "Starting Time:", nullptr)); + label_4->setText(QCoreApplication::translate("WateringConfigDialog", "Amount:", nullptr)); + amountSpinBox->setSuffix(QCoreApplication::translate("WateringConfigDialog", "l", nullptr)); + label_5->setText(QCoreApplication::translate("WateringConfigDialog", "Source:", nullptr)); + sourceComboBox->setItemText(0, QCoreApplication::translate("WateringConfigDialog", "Foundain", nullptr)); + sourceComboBox->setItemText(1, QCoreApplication::translate("WateringConfigDialog", "River", nullptr)); + sourceComboBox->setItemText(2, QCoreApplication::translate("WateringConfigDialog", "Lake", nullptr)); + sourceComboBox->setItemText(3, QCoreApplication::translate("WateringConfigDialog", "Public Water System", nullptr)); - label_6->setText(QApplication::translate("WateringConfigDialog", "Filter:", nullptr)); + label_6->setText(QCoreApplication::translate("WateringConfigDialog", "Filter:", nullptr)); filterCheckBox->setText(QString()); - helpLabel->setText(QApplication::translate("WateringConfigDialog", "
    Show Details", nullptr)); + helpLabel->setText(QCoreApplication::translate("WateringConfigDialog", "Show Details", nullptr)); } // retranslateUi }; From 1314d2688c6eab24d33e2a558403fa6e2482f849 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 30 Nov 2018 15:28:13 +0100 Subject: [PATCH 0502/1650] macOS: Fix Objective-C namespaceing with Xcode 10 Xcode 10 ships version 921.0.1 of cctools, which otool is part of. The defaults have changed in that version to no longer print verbosely (symbolically), which we relied on. We now request it explicitly. Change-Id: Ifbe0c97462b9f78cf128c820847eff9c72f17065 Reviewed-by: Timur Pocheptsov Reviewed-by: Tim Blechmann --- mkspecs/features/data/mac/objc_namespace.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/data/mac/objc_namespace.sh b/mkspecs/features/data/mac/objc_namespace.sh index 6ac004fe2d..ceff2df324 100755 --- a/mkspecs/features/data/mac/objc_namespace.sh +++ b/mkspecs/features/data/mac/objc_namespace.sh @@ -146,7 +146,7 @@ inspect_binary() { echo "found namespaced class names, updating class entries..." fi - classes=$(otool -o "$target" | grep class_ro_t) + classes=$(otool -o -v "$target" | grep class_ro_t) while read -a class; do address="$(sanitize_address ${class[1]})" From b82559244e2dc03f1ceff66bb67630df4300dc7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 30 Nov 2018 14:51:18 +0100 Subject: [PATCH 0503/1650] macOS: Account for LC_BUILD_VERSION when checking SDK version and deployment target MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The more modern LC_BUILD_VERSION load command was introduced in the 10.13 SDK to unify the various versions of the LC_*_VERSION_MIN command. When building with a deployment target of 10.14, the linker will use this load command instead. Change-Id: Ic3571fdbfdf4dfb9346128c6f6e75d1e06f86cd2 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoahelpers.mm | 25 +++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index 36841c77ab..d86e935788 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -402,23 +402,30 @@ QOperatingSystemVersion QMacVersion::currentRuntime() QMacVersion::VersionTuple QMacVersion::versionsForImage(const mach_header *machHeader) { + static auto makeVersionTuple = [](uint32_t dt, uint32_t sdk) { + return qMakePair( + QOperatingSystemVersion(QOperatingSystemVersion::MacOS, + dt >> 16 & 0xffff, dt >> 8 & 0xff, dt & 0xff), + QOperatingSystemVersion(QOperatingSystemVersion::MacOS, + sdk >> 16 & 0xffff, sdk >> 8 & 0xff, sdk & 0xff) + ); + }; + auto commandCursor = uintptr_t(machHeader) + sizeof(mach_header_64); for (uint32_t i = 0; i < machHeader->ncmds; ++i) { load_command *loadCommand = reinterpret_cast(commandCursor); if (loadCommand->cmd == LC_VERSION_MIN_MACOSX) { auto versionCommand = reinterpret_cast(loadCommand); - uint32_t dt = versionCommand->version; // Deployment target - uint32_t sdk = versionCommand->sdk; // Build SDK - return qMakePair( - QOperatingSystemVersion(QOperatingSystemVersion::MacOS, - dt >> 16 & 0xffff, dt >> 8 & 0xff, dt & 0xff), - QOperatingSystemVersion(QOperatingSystemVersion::MacOS, - sdk >> 16 & 0xffff, sdk >> 8 & 0xff, sdk & 0xff) - ); + return makeVersionTuple(versionCommand->version, versionCommand->sdk); +#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_13) + } else if (loadCommand->cmd == LC_BUILD_VERSION) { + auto versionCommand = reinterpret_cast(loadCommand); + return makeVersionTuple(versionCommand->minos, versionCommand->sdk); +#endif } commandCursor += loadCommand->cmdsize; } - Q_ASSERT_X(false, "QCocoaIntegration", "Could not find version-min load command"); + Q_ASSERT_X(false, "QCocoaIntegration", "Could not find any version load command"); Q_UNREACHABLE(); } From ffeefaac6273b8bdb81876a5cc26e15cb9353955 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 31 Oct 2018 10:33:07 +0100 Subject: [PATCH 0504/1650] Support style name property in QTextCharFormat The support for setting the style name in the QTextDocument API was never added, as revealed by the example in the linked bug report. The actual bug reported there (style names not working with some Helvetica Neue) is not reproducible anymore. [ChangeLog][QtGui][Text] Added support for setting the font's style name in QTextCharFormat. Task-number: QTBUG-22813 Change-Id: I8f4d12151c3611aa30965fd963bc93f7c4264e23 Reviewed-by: Lars Knoll --- src/gui/text/qtextformat.cpp | 25 +++++++++++++++++++++++++ src/gui/text/qtextformat.h | 6 ++++++ 2 files changed, 31 insertions(+) diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index e814f4f718..136e7dc140 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -364,6 +364,9 @@ void QTextFormatPrivate::recalcFont() const case QTextFormat::FontFamilies: f.setFamilies(props.at(i).value.toStringList()); break; + case QTextFormat::FontStyleName: + f.setStyleName(props.at(i).value.toString()); + break; case QTextFormat::FontPointSize: f.setPointSizeF(props.at(i).value.toReal()); break; @@ -566,6 +569,7 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt) \value FontFamily \value FontFamilies + \value FontStyleName \value FontPointSize \value FontPixelSize \value FontSizeAdjustment Specifies the change in size given to the fontsize already set using @@ -1412,6 +1416,25 @@ QTextCharFormat::QTextCharFormat(const QTextFormat &fmt) \sa font() */ + +/*! + \fn void QTextCharFormat::setFontStyleName(const QString &styleName) + \since 5.13 + + Sets the text format's font \a style name. + + \sa setFont(), QFont::setStyleName() +*/ + +/*! + \fn QStringList QTextCharFormat::fontStyleName() const + \since 5.13 + + Returns the text format's font style name. + + \sa font(), QFont::styleName() +*/ + /*! \fn void QTextCharFormat::setFontPointSize(qreal size) @@ -1942,6 +1965,8 @@ void QTextCharFormat::setFont(const QFont &font, FontPropertiesInheritanceBehavi setFontFamily(font.family()); if (mask & QFont::FamiliesResolved) setFontFamilies(font.families()); + if (mask & QFont::StyleNameResolved) + setFontStyleName(font.styleName()); if (mask & QFont::SizeResolved) { const qreal pointSize = font.pointSizeF(); diff --git a/src/gui/text/qtextformat.h b/src/gui/text/qtextformat.h index d27d2e7f17..f292feabe8 100644 --- a/src/gui/text/qtextformat.h +++ b/src/gui/text/qtextformat.h @@ -189,6 +189,7 @@ public: FontKerning = 0x1FE5, FontHintingPreference = 0x1FE6, FontFamilies = 0x1FE7, + FontStyleName = 0x1FE8, FontFamily = 0x2000, FontPointSize = 0x2001, FontSizeAdjustment = 0x2002, @@ -434,6 +435,11 @@ public: inline QVariant fontFamilies() const { return property(FontFamilies); } + inline void setFontStyleName(const QString &styleName) + { setProperty(FontStyleName, styleName); } + inline QVariant fontStyleName() const + { return property(FontStyleName); } + inline void setFontPointSize(qreal size) { setProperty(FontPointSize, size); } inline qreal fontPointSize() const From 121b0bfed51641ddae0585377471aeecdfec5d02 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 6 Nov 2018 14:44:05 -0800 Subject: [PATCH 0505/1650] Make qDetectCpuFeatures() return the CPU features it detected Micro (nano?) optimization. Change-Id: Iba4b5c183776497d8ee1fffd1564aa53056f343d Reviewed-by: Allan Sandfeld Jensen --- src/corelib/tools/qsimd.cpp | 3 ++- src/corelib/tools/qsimd_p.h | 8 ++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp index 07a8b022bc..4a44cf02e0 100644 --- a/src/corelib/tools/qsimd.cpp +++ b/src/corelib/tools/qsimd.cpp @@ -529,7 +529,7 @@ Q_CORE_EXPORT QBasicAtomicInteger qt_cpu_features[1] = { Q_BASIC_ATOMIC Q_CORE_EXPORT QBasicAtomicInteger qt_cpu_features[2] = { Q_BASIC_ATOMIC_INITIALIZER(0), Q_BASIC_ATOMIC_INITIALIZER(0) }; #endif -void qDetectCpuFeatures() +quint64 qDetectCpuFeatures() { quint64 f = detectProcessorFeatures(); QByteArray disable = qgetenv("QT_NO_CPU_FEATURE"); @@ -563,6 +563,7 @@ void qDetectCpuFeatures() #ifndef Q_ATOMIC_INT64_IS_SUPPORTED qt_cpu_features[1].store(f >> 32); #endif + return f; } void qDumpCPUFeatures() diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h index 9f1321df94..c36e1e484f 100644 --- a/src/corelib/tools/qsimd_p.h +++ b/src/corelib/tools/qsimd_p.h @@ -344,7 +344,7 @@ extern Q_CORE_EXPORT QBasicAtomicInteger qt_cpu_features[1]; #else extern Q_CORE_EXPORT QBasicAtomicInteger qt_cpu_features[2]; #endif -Q_CORE_EXPORT void qDetectCpuFeatures(); +Q_CORE_EXPORT quint64 qDetectCpuFeatures(); static inline quint64 qCpuFeatures() { @@ -353,11 +353,7 @@ static inline quint64 qCpuFeatures() features |= quint64(qt_cpu_features[1].load()) << 32; #endif if (Q_UNLIKELY(features == 0)) { - qDetectCpuFeatures(); - features = qt_cpu_features[0].load(); -#ifndef Q_ATOMIC_INT64_IS_SUPPORTED - features |= quint64(qt_cpu_features[1].load()) << 32; -#endif + features = qDetectCpuFeatures(); Q_ASSUME(features != 0); } return features; From 652098d40fab7c1085b913487809c6237eb2d49d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 19 Nov 2018 11:00:51 -0800 Subject: [PATCH 0506/1650] QTranslator: add initial largefile support Using QT_MMAP macro instead of mmap() so we could map more than 2 GB of the file. Not that the file format supports such a thing, but just in case. Change-Id: Iae320a2868db402a993dfffd15689bba1d667c7d Reviewed-by: Lars Knoll Reviewed-by: Thiago Macieira --- src/corelib/kernel/qtranslator.cpp | 33 ++++++++++++------------------ 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp index 744bbfbff5..dc39490ab0 100644 --- a/src/corelib/kernel/qtranslator.cpp +++ b/src/corelib/kernel/qtranslator.cpp @@ -61,14 +61,8 @@ #if defined(Q_OS_UNIX) && !defined(Q_OS_INTEGRITY) #define QT_USE_MMAP #include "private/qcore_unix_p.h" -#endif - -// most of the headers below are already included in qplatformdefs.h -// also this lacks Large File support but that's probably irrelevant -#if defined(QT_USE_MMAP) // for mmap #include -#include #endif #include @@ -302,7 +296,7 @@ public: bool used_mmap : 1; #endif char *unmapPointer; // used memory (mmap, new or resource file) - quint32 unmapLength; + qsizetype unmapLength; // The resource object in case we loaded the translations from a resource QResource *resource; @@ -322,7 +316,7 @@ public: uint numerusRulesLength; bool do_load(const QString &filename, const QString &directory); - bool do_load(const uchar *data, int len, const QString &directory); + bool do_load(const uchar *data, qsizetype len, const QString &directory); QString do_translate(const char *context, const char *sourceText, const char *comment, int n) const; void clear(); @@ -553,7 +547,7 @@ bool QTranslatorPrivate::do_load(const QString &realname, const QString &directo return false; qint64 fileSize = file.size(); - if (fileSize < MagicLength || quint32(-1) <= fileSize) + if (fileSize < MagicLength || fileSize > std::numeric_limits::max()) return false; { @@ -563,7 +557,7 @@ bool QTranslatorPrivate::do_load(const QString &realname, const QString &directo return false; } - d->unmapLength = quint32(fileSize); + d->unmapLength = qsizetype(fileSize); #ifdef QT_USE_MMAP @@ -571,21 +565,20 @@ bool QTranslatorPrivate::do_load(const QString &realname, const QString &directo #define MAP_FILE 0 #endif #ifndef MAP_FAILED -#define MAP_FAILED -1 +#define MAP_FAILED reinterpret_cast(-1) #endif int fd = file.handle(); if (fd >= 0) { - char *ptr; - ptr = reinterpret_cast( - mmap(0, d->unmapLength, // any address, whole file - PROT_READ, // read-only memory - MAP_FILE | MAP_PRIVATE, // swap-backed map from file - fd, 0)); // from offset 0 of fd - if (ptr && ptr != reinterpret_cast(MAP_FAILED)) { + int protection = PROT_READ; // read-only memory + int flags = MAP_FILE | MAP_PRIVATE; // swap-backed map from file + void *ptr = QT_MMAP(nullptr, d->unmapLength,// any address, whole file + protection, flags, + fd, 0); // from offset 0 of fd + if (ptr != MAP_FAILED) { file.close(); d->used_mmap = true; - d->unmapPointer = ptr; + d->unmapPointer = static_cast(ptr); ok = true; } } @@ -815,7 +808,7 @@ static quint32 read32(const uchar *data) return qFromBigEndian(data); } -bool QTranslatorPrivate::do_load(const uchar *data, int len, const QString &directory) +bool QTranslatorPrivate::do_load(const uchar *data, qsizetype len, const QString &directory) { bool ok = true; const uchar *end = data + len; From 8c38b08343b226883ef368d31a085b0a620f7995 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 23 Nov 2018 22:05:04 +0100 Subject: [PATCH 0507/1650] QFormLayout: Fix width calculation when a row has no label The calculation of the minimum width assumes that when there is no label for a row, the field occupies the full row. But this is only true when QFormLayout::SpanningRole is set for this row. This lead to a to small minimum size for the row / truncated widgets when the row in question is the longest one in the form layout. Fix it by checking if it is a spanned row instead if there is not label when calculating the sizes. Fixes: QTBUG-18308 Fixes: QTBUG-60800 Change-Id: I1a610c93ab5c7f9cac503721ae99b36f2710c634 Reviewed-by: Richard Moe Gustavsen --- src/widgets/kernel/qformlayout.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/widgets/kernel/qformlayout.cpp b/src/widgets/kernel/qformlayout.cpp index 66e8858e21..101ce8b64c 100644 --- a/src/widgets/kernel/qformlayout.cpp +++ b/src/widgets/kernel/qformlayout.cpp @@ -419,13 +419,15 @@ void QFormLayoutPrivate::updateSizes() if (label) { maxMinLblWidth = qMax(maxMinLblWidth, label->minSize.width()); maxShLblWidth = qMax(maxShLblWidth, label->sizeHint.width()); - if (field) { + } + if (field) { + if (field->fullRow) { + maxMinIfldWidth = qMax(maxMinIfldWidth, field->minSize.width()); + maxShIfldWidth = qMax(maxShIfldWidth, field->sizeHint.width()); + } else { maxMinFldWidth = qMax(maxMinFldWidth, field->minSize.width() + field->sbsHSpace); maxShFldWidth = qMax(maxShFldWidth, field->sizeHint.width() + field->sbsHSpace); } - } else if (field) { - maxMinIfldWidth = qMax(maxMinIfldWidth, field->minSize.width()); - maxShIfldWidth = qMax(maxShIfldWidth, field->sizeHint.width()); } prevLbl = label; From 51f6d5d8c261fb94adc9bf5754cabf8e37236af5 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Mon, 12 Nov 2018 21:20:34 +0100 Subject: [PATCH 0508/1650] Cleanup Addressbook example Cleanup the Addressbook example: - use nullptr - use for instead foreach - don't use public members but setters/getters - use QVector instead QList - make user-visible translatable Change-Id: Ie7bdad8a2799c8fa6f634659b51c3064cc8a04ce Reviewed-by: Samuel Gaist Reviewed-by: Sze Howe Koh Reviewed-by: Paul Wicking Reviewed-by: Luca Beldi --- examples/widgets/doc/src/addressbook.qdoc | 11 ++- .../itemviews/addressbook/adddialog.cpp | 38 +++++++--- .../widgets/itemviews/addressbook/adddialog.h | 14 ++-- .../itemviews/addressbook/addresswidget.cpp | 69 ++++++++----------- .../itemviews/addressbook/addresswidget.h | 5 +- .../itemviews/addressbook/mainwindow.cpp | 18 ++--- .../itemviews/addressbook/mainwindow.h | 6 -- .../itemviews/addressbook/newaddresstab.cpp | 21 +++--- .../itemviews/addressbook/newaddresstab.h | 10 +-- .../itemviews/addressbook/tablemodel.cpp | 52 +++++++------- .../itemviews/addressbook/tablemodel.h | 10 +-- 11 files changed, 120 insertions(+), 134 deletions(-) diff --git a/examples/widgets/doc/src/addressbook.qdoc b/examples/widgets/doc/src/addressbook.qdoc index 1fa0bfa9d4..e5e7fe5c2c 100644 --- a/examples/widgets/doc/src/addressbook.qdoc +++ b/examples/widgets/doc/src/addressbook.qdoc @@ -90,8 +90,8 @@ \snippet itemviews/addressbook/tablemodel.h 0 Two constructors are used, a default constructor which uses - \c TableModel's own \c {QList} and one that takes - \c {QList} as an argument, for convenience. + \c TableModel's own \c {QVector} and one that takes + \c {QVector} as an argument, for convenience. \section1 TableModel Class Implementation @@ -108,9 +108,6 @@ \c columnCount()'s value is always 2 because we only need space for the \b Name and \b Address columns. - \note The \c Q_UNUSED() macro prevents the compiler from - generating warnings regarding unused parameters. - \snippet itemviews/addressbook/tablemodel.cpp 1 The \c data() function returns either a \b Name or @@ -164,7 +161,7 @@ them here so that we can reuse the model in other programs. The last function in \c {TableModel}, \c getContacts() returns the - QList object that holds all the contacts in the address + QVector object that holds all the contacts in the address book. We use this function later to obtain the list of contacts to check for existing entries, write the contacts to a file and read them back. Further explanation is given with \c AddressWidget. @@ -233,7 +230,7 @@ \image addressbook-signals.png Signals and Slots Connections - We provide 2 \c addEntry() functions: 1 which is intended to be + We provide two \c addEntry() functions: One which is intended to be used to accept user input, and the other which performs the actual task of adding new entries to the address book. We divide the responsibility of adding entries into two parts to allow diff --git a/examples/widgets/itemviews/addressbook/adddialog.cpp b/examples/widgets/itemviews/addressbook/adddialog.cpp index 1ce2d3110a..bf87307253 100644 --- a/examples/widgets/itemviews/addressbook/adddialog.cpp +++ b/examples/widgets/itemviews/addressbook/adddialog.cpp @@ -54,17 +54,16 @@ //! [0] AddDialog::AddDialog(QWidget *parent) - : QDialog(parent) + : QDialog(parent), + nameText(new QLineEdit), + addressText(new QTextEdit) { - nameLabel = new QLabel("Name"); - addressLabel = new QLabel("Address"); - okButton = new QPushButton("OK"); - cancelButton = new QPushButton("Cancel"); + auto nameLabel = new QLabel(tr("Name")); + auto addressLabel = new QLabel(tr("Address")); + auto okButton = new QPushButton(tr("OK")); + auto cancelButton = new QPushButton(tr("Cancel")); - nameText = new QLineEdit; - addressText = new QTextEdit; - - QGridLayout *gLayout = new QGridLayout; + auto gLayout = new QGridLayout; gLayout->setColumnStretch(1, 2); gLayout->addWidget(nameLabel, 0, 0); gLayout->addWidget(nameText, 0, 1); @@ -72,13 +71,13 @@ AddDialog::AddDialog(QWidget *parent) gLayout->addWidget(addressLabel, 1, 0, Qt::AlignLeft|Qt::AlignTop); gLayout->addWidget(addressText, 1, 1, Qt::AlignLeft); - QHBoxLayout *buttonLayout = new QHBoxLayout; + auto buttonLayout = new QHBoxLayout; buttonLayout->addWidget(okButton); buttonLayout->addWidget(cancelButton); gLayout->addLayout(buttonLayout, 2, 1, Qt::AlignRight); - QVBoxLayout *mainLayout = new QVBoxLayout; + auto mainLayout = new QVBoxLayout; mainLayout->addLayout(gLayout); setLayout(mainLayout); @@ -87,4 +86,21 @@ AddDialog::AddDialog(QWidget *parent) setWindowTitle(tr("Add a Contact")); } + +QString AddDialog::name() const +{ + return nameText->text(); +} + +QString AddDialog::address() const +{ + return addressText->toPlainText(); +} + +void AddDialog::editAddress(const QString &name, const QString &address) +{ + nameText->setReadOnly(true); + nameText->setText(name); + addressText->setPlainText(address); +} //! [0] diff --git a/examples/widgets/itemviews/addressbook/adddialog.h b/examples/widgets/itemviews/addressbook/adddialog.h index 16fa7bc650..2867034122 100644 --- a/examples/widgets/itemviews/addressbook/adddialog.h +++ b/examples/widgets/itemviews/addressbook/adddialog.h @@ -66,15 +66,15 @@ class AddDialog : public QDialog Q_OBJECT public: - AddDialog(QWidget *parent = 0); - QLineEdit *nameText; - QTextEdit *addressText; + AddDialog(QWidget *parent = nullptr); + + QString name() const; + QString address() const; + void editAddress(const QString &name, const QString &address); private: - QLabel *nameLabel; - QLabel *addressLabel; - QPushButton *okButton; - QPushButton *cancelButton; + QLineEdit *nameText; + QTextEdit *addressText; }; //! [0] diff --git a/examples/widgets/itemviews/addressbook/addresswidget.cpp b/examples/widgets/itemviews/addressbook/addresswidget.cpp index 143f6266dd..b1b65174ee 100644 --- a/examples/widgets/itemviews/addressbook/addresswidget.cpp +++ b/examples/widgets/itemviews/addressbook/addresswidget.cpp @@ -48,21 +48,21 @@ ** ****************************************************************************/ -#include "adddialog.h" #include "addresswidget.h" +#include "adddialog.h" #include //! [0] AddressWidget::AddressWidget(QWidget *parent) - : QTabWidget(parent) + : QTabWidget(parent), + table(new TableModel(this)), + newAddressTab(new NewAddressTab(this)) { - table = new TableModel(this); - newAddressTab = new NewAddressTab(this); connect(newAddressTab, &NewAddressTab::sendDetails, this, &AddressWidget::addEntry); - addTab(newAddressTab, "Address Book"); + addTab(newAddressTab, tr("Address Book")); setupTabs(); } @@ -73,17 +73,13 @@ void AddressWidget::showAddEntryDialog() { AddDialog aDialog; - if (aDialog.exec()) { - QString name = aDialog.nameText->text(); - QString address = aDialog.addressText->toPlainText(); - - addEntry(name, address); - } + if (aDialog.exec()) + addEntry(aDialog.name(), aDialog.address()); } //! [2] //! [3] -void AddressWidget::addEntry(QString name, QString address) +void AddressWidget::addEntry(const QString &name, const QString &address) { if (!table->getContacts().contains({ name, address })) { table->insertRows(0, 1, QModelIndex()); @@ -107,12 +103,12 @@ void AddressWidget::editEntry() QSortFilterProxyModel *proxy = static_cast(temp->model()); QItemSelectionModel *selectionModel = temp->selectionModel(); - QModelIndexList indexes = selectionModel->selectedRows(); + const QModelIndexList indexes = selectionModel->selectedRows(); QString name; QString address; int row = -1; - foreach (QModelIndex index, indexes) { + for (const QModelIndex &index : indexes) { row = proxy->mapToSource(index).row(); QModelIndex nameIndex = table->index(row, 0, QModelIndex()); QVariant varName = table->data(nameIndex, Qt::DisplayRole); @@ -127,15 +123,12 @@ void AddressWidget::editEntry() //! [4b] AddDialog aDialog; aDialog.setWindowTitle(tr("Edit a Contact")); - - aDialog.nameText->setReadOnly(true); - aDialog.nameText->setText(name); - aDialog.addressText->setText(address); + aDialog.editAddress(name, address); if (aDialog.exec()) { - QString newAddress = aDialog.addressText->toPlainText(); + const QString newAddress = aDialog.address(); if (newAddress != address) { - QModelIndex index = table->index(row, 1, QModelIndex()); + const QModelIndex index = table->index(row, 1, QModelIndex()); table->setData(index, newAddress, Qt::EditRole); } } @@ -149,52 +142,46 @@ void AddressWidget::removeEntry() QSortFilterProxyModel *proxy = static_cast(temp->model()); QItemSelectionModel *selectionModel = temp->selectionModel(); - QModelIndexList indexes = selectionModel->selectedRows(); + const QModelIndexList indexes = selectionModel->selectedRows(); - foreach (QModelIndex index, indexes) { + for (QModelIndex index : indexes) { int row = proxy->mapToSource(index).row(); table->removeRows(row, 1, QModelIndex()); } - if (table->rowCount(QModelIndex()) == 0) { - insertTab(0, newAddressTab, "Address Book"); - } + if (table->rowCount(QModelIndex()) == 0) + insertTab(0, newAddressTab, tr("Address Book")); } //! [5] //! [1] void AddressWidget::setupTabs() { - QStringList groups; - groups << "ABC" << "DEF" << "GHI" << "JKL" << "MNO" << "PQR" << "STU" << "VW" << "XYZ"; + const auto groups = { "ABC", "DEF", "GHI", "JKL", "MNO", "PQR", "STU", "VW", "XYZ" }; - for (int i = 0; i < groups.size(); ++i) { - QString str = groups.at(i); - QString regExp = QString("^[%1].*").arg(str); + for (const QString &str : groups) { + const auto regExp = QRegularExpression(QString("^[%1].*").arg(str), + QRegularExpression::CaseInsensitiveOption); - proxyModel = new QSortFilterProxyModel(this); + auto proxyModel = new QSortFilterProxyModel(this); proxyModel->setSourceModel(table); - proxyModel->setFilterRegExp(QRegExp(regExp, Qt::CaseInsensitive)); + proxyModel->setFilterRegularExpression(regExp); proxyModel->setFilterKeyColumn(0); QTableView *tableView = new QTableView; tableView->setModel(proxyModel); - tableView->setSelectionBehavior(QAbstractItemView::SelectRows); tableView->horizontalHeader()->setStretchLastSection(true); tableView->verticalHeader()->hide(); tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); tableView->setSelectionMode(QAbstractItemView::SingleSelection); - tableView->setSortingEnabled(true); - connect(tableView->selectionModel(), - &QItemSelectionModel::selectionChanged, - this, &AddressWidget::selectionChanged); + connect(tableView->selectionModel(), &QItemSelectionModel::selectionChanged, + this, &AddressWidget::selectionChanged); - connect(this, &QTabWidget::currentChanged, this, [this](int tabIndex) { - auto *tableView = qobject_cast(widget(tabIndex)); - if (tableView) + connect(this, &QTabWidget::currentChanged, this, [this, tableView](int tabIndex) { + if (widget(tabIndex) == tableView) emit selectionChanged(tableView->selectionModel()->selection()); }); @@ -214,7 +201,7 @@ void AddressWidget::readFromFile(const QString &fileName) return; } - QList contacts; + QVector contacts; QDataStream in(&file); in >> contacts; diff --git a/examples/widgets/itemviews/addressbook/addresswidget.h b/examples/widgets/itemviews/addressbook/addresswidget.h index de5a2da766..111ea98328 100644 --- a/examples/widgets/itemviews/addressbook/addresswidget.h +++ b/examples/widgets/itemviews/addressbook/addresswidget.h @@ -68,13 +68,13 @@ class AddressWidget : public QTabWidget Q_OBJECT public: - AddressWidget(QWidget *parent = 0); + AddressWidget(QWidget *parent = nullptr); void readFromFile(const QString &fileName); void writeToFile(const QString &fileName); public slots: void showAddEntryDialog(); - void addEntry(QString name, QString address); + void addEntry(const QString &name, const QString &address); void editEntry(); void removeEntry(); @@ -86,7 +86,6 @@ private: TableModel *table; NewAddressTab *newAddressTab; - QSortFilterProxyModel *proxyModel; }; //! [0] diff --git a/examples/widgets/itemviews/addressbook/mainwindow.cpp b/examples/widgets/itemviews/addressbook/mainwindow.cpp index 6d8b15b032..42966de375 100644 --- a/examples/widgets/itemviews/addressbook/mainwindow.cpp +++ b/examples/widgets/itemviews/addressbook/mainwindow.cpp @@ -56,8 +56,9 @@ //! [0] MainWindow::MainWindow() + : QMainWindow(), + addressWidget(new AddressWidget) { - addressWidget = new AddressWidget; setCentralWidget(addressWidget); createMenus(); setWindowTitle(tr("Address Book")); @@ -67,28 +68,29 @@ MainWindow::MainWindow() //! [1a] void MainWindow::createMenus() { - fileMenu = menuBar()->addMenu(tr("&File")); + QMenu *fileMenu = menuBar()->addMenu(tr("&File")); - openAct = new QAction(tr("&Open..."), this); + QAction *openAct = new QAction(tr("&Open..."), this); fileMenu->addAction(openAct); connect(openAct, &QAction::triggered, this, &MainWindow::openFile); //! [1a] - saveAct = new QAction(tr("&Save As..."), this); + QAction *saveAct = new QAction(tr("&Save As..."), this); fileMenu->addAction(saveAct); connect(saveAct, &QAction::triggered, this, &MainWindow::saveFile); fileMenu->addSeparator(); - exitAct = new QAction(tr("E&xit"), this); + QAction *exitAct = new QAction(tr("E&xit"), this); fileMenu->addAction(exitAct); connect(exitAct, &QAction::triggered, this, &QWidget::close); - toolMenu = menuBar()->addMenu(tr("&Tools")); + QMenu *toolMenu = menuBar()->addMenu(tr("&Tools")); - addAct = new QAction(tr("&Add Entry..."), this); + QAction *addAct = new QAction(tr("&Add Entry..."), this); toolMenu->addAction(addAct); - connect(addAct, &QAction::triggered, addressWidget, &AddressWidget::showAddEntryDialog); + connect(addAct, &QAction::triggered, + addressWidget, &AddressWidget::showAddEntryDialog); //! [1b] editAct = new QAction(tr("&Edit Entry..."), this); diff --git a/examples/widgets/itemviews/addressbook/mainwindow.h b/examples/widgets/itemviews/addressbook/mainwindow.h index 3d323e5799..fca5934e68 100644 --- a/examples/widgets/itemviews/addressbook/mainwindow.h +++ b/examples/widgets/itemviews/addressbook/mainwindow.h @@ -72,12 +72,6 @@ private: void createMenus(); AddressWidget *addressWidget; - QMenu *fileMenu; - QMenu *toolMenu; - QAction *openAct; - QAction *saveAct; - QAction *exitAct; - QAction *addAct; QAction *editAct; QAction *removeAct; }; diff --git a/examples/widgets/itemviews/addressbook/newaddresstab.cpp b/examples/widgets/itemviews/addressbook/newaddresstab.cpp index f0a7369796..ef725d723f 100644 --- a/examples/widgets/itemviews/addressbook/newaddresstab.cpp +++ b/examples/widgets/itemviews/addressbook/newaddresstab.cpp @@ -48,24 +48,23 @@ ** ****************************************************************************/ -#include "adddialog.h" #include "newaddresstab.h" +#include "adddialog.h" #include //! [0] NewAddressTab::NewAddressTab(QWidget *parent) + : QWidget(parent) { - Q_UNUSED(parent); + auto descriptionLabel = new QLabel(tr("There are currently no contacts in your address book. " + "\nClick Add to add new contacts.")); - descriptionLabel = new QLabel(tr("There are currently no contacts in your address book. " - "\nClick Add to add new contacts.")); - - addButton = new QPushButton(tr("Add")); + auto addButton = new QPushButton(tr("Add")); connect(addButton, &QAbstractButton::clicked, this, &NewAddressTab::addEntry); - mainLayout = new QVBoxLayout; + auto mainLayout = new QVBoxLayout; mainLayout->addWidget(descriptionLabel); mainLayout->addWidget(addButton, 0, Qt::AlignCenter); @@ -78,11 +77,7 @@ void NewAddressTab::addEntry() { AddDialog aDialog; - if (aDialog.exec()) { - QString name = aDialog.nameText->text(); - QString address = aDialog.addressText->toPlainText(); - - emit sendDetails(name, address); - } + if (aDialog.exec()) + emit sendDetails(aDialog.name(), aDialog.address()); } //! [1] diff --git a/examples/widgets/itemviews/addressbook/newaddresstab.h b/examples/widgets/itemviews/addressbook/newaddresstab.h index 05c7a8dada..6a147e3c7c 100644 --- a/examples/widgets/itemviews/addressbook/newaddresstab.h +++ b/examples/widgets/itemviews/addressbook/newaddresstab.h @@ -65,19 +65,13 @@ class NewAddressTab : public QWidget Q_OBJECT public: - NewAddressTab(QWidget *parent = 0); + NewAddressTab(QWidget *parent = nullptr); public slots: void addEntry(); signals: - void sendDetails(QString name, QString address); - -private: - QLabel *descriptionLabel; - QPushButton *addButton; - QVBoxLayout *mainLayout; - + void sendDetails(const QString &name, const QString &address); }; //! [0] diff --git a/examples/widgets/itemviews/addressbook/tablemodel.cpp b/examples/widgets/itemviews/addressbook/tablemodel.cpp index b3704f857e..ddf79a3fa3 100644 --- a/examples/widgets/itemviews/addressbook/tablemodel.cpp +++ b/examples/widgets/itemviews/addressbook/tablemodel.cpp @@ -56,9 +56,9 @@ TableModel::TableModel(QObject *parent) { } -TableModel::TableModel(QList contacts, QObject *parent) - : QAbstractTableModel(parent) - , contacts(contacts) +TableModel::TableModel(const QVector &contacts, QObject *parent) + : QAbstractTableModel(parent), + contacts(contacts) { } //! [0] @@ -66,14 +66,12 @@ TableModel::TableModel(QList contacts, QObject *parent) //! [1] int TableModel::rowCount(const QModelIndex &parent) const { - Q_UNUSED(parent); - return contacts.size(); + return parent.isValid() ? 0 : contacts.size(); } int TableModel::columnCount(const QModelIndex &parent) const { - Q_UNUSED(parent); - return 2; + return parent.isValid() ? 0 : 2; } //! [1] @@ -89,10 +87,14 @@ QVariant TableModel::data(const QModelIndex &index, int role) const if (role == Qt::DisplayRole) { const auto &contact = contacts.at(index.row()); - if (index.column() == 0) - return contact.name; - else if (index.column() == 1) - return contact.address; + switch (index.column()) { + case 0: + return contact.name; + case 1: + return contact.address; + default: + break; + } } return QVariant(); } @@ -108,12 +110,10 @@ QVariant TableModel::headerData(int section, Qt::Orientation orientation, int ro switch (section) { case 0: return tr("Name"); - case 1: return tr("Address"); - default: - return QVariant(); + break; } } return QVariant(); @@ -152,19 +152,21 @@ bool TableModel::removeRows(int position, int rows, const QModelIndex &index) bool TableModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (index.isValid() && role == Qt::EditRole) { - int row = index.row(); - + const int row = index.row(); auto contact = contacts.value(row); - if (index.column() == 0) - contact.name = value.toString(); - else if (index.column() == 1) - contact.address = value.toString(); - else - return false; - + switch (index.column()) { + case 0: + contact.name = value.toString(); + break; + case 1: + contact.address = value.toString(); + break; + default: + return false; + } contacts.replace(row, contact); - emit dataChanged(index, index, {role}); + emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole}); return true; } @@ -184,7 +186,7 @@ Qt::ItemFlags TableModel::flags(const QModelIndex &index) const //! [7] //! [8] -QList TableModel::getContacts() const +const QVector &TableModel::getContacts() const { return contacts; } diff --git a/examples/widgets/itemviews/addressbook/tablemodel.h b/examples/widgets/itemviews/addressbook/tablemodel.h index 1004a35d31..e4025fc734 100644 --- a/examples/widgets/itemviews/addressbook/tablemodel.h +++ b/examples/widgets/itemviews/addressbook/tablemodel.h @@ -52,7 +52,7 @@ #define TABLEMODEL_H #include -#include +#include //! [0] @@ -82,8 +82,8 @@ class TableModel : public QAbstractTableModel Q_OBJECT public: - TableModel(QObject *parent = 0); - TableModel(QList contacts, QObject *parent = 0); + TableModel(QObject *parent = nullptr); + TableModel(const QVector &contacts, QObject *parent = nullptr); int rowCount(const QModelIndex &parent) const override; int columnCount(const QModelIndex &parent) const override; @@ -93,10 +93,10 @@ public: bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex()) override; bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex()) override; - QList getContacts() const; + const QVector &getContacts() const; private: - QList contacts; + QVector contacts; }; //! [0] From 1cfe064632099e036f964832c23afe266e54d59e Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Thu, 22 Nov 2018 21:21:25 +0100 Subject: [PATCH 0509/1650] Cleanup StarDelegate example Cleanup the StarDelegate example: - use QStyledItemDelegate instead QItemDelegate - use nullptr and other useful c++11 constructs - include the correct headers Change-Id: If2f65fe7cbdcdd4571d10ffa98d36eeab7836bbb Reviewed-by: Sze Howe Koh Reviewed-by: Paul Wicking Reviewed-by: Luca Beldi --- examples/widgets/doc/src/stardelegate.qdoc | 14 +++++----- .../widgets/itemviews/stardelegate/main.cpp | 5 +--- .../itemviews/stardelegate/stardelegate.cpp | 8 +++--- .../itemviews/stardelegate/stardelegate.h | 3 +-- .../itemviews/stardelegate/stareditor.cpp | 20 +++++++------- .../itemviews/stardelegate/stareditor.h | 5 ++-- .../itemviews/stardelegate/starrating.cpp | 27 ++++++++----------- .../itemviews/stardelegate/starrating.h | 8 +++--- 8 files changed, 40 insertions(+), 50 deletions(-) diff --git a/examples/widgets/doc/src/stardelegate.qdoc b/examples/widgets/doc/src/stardelegate.qdoc index 44d17662ca..0b91723a51 100644 --- a/examples/widgets/doc/src/stardelegate.qdoc +++ b/examples/widgets/doc/src/stardelegate.qdoc @@ -42,11 +42,11 @@ editing takes place. Delegates are subclasses of QAbstractItemDelegate. Qt provides - QItemDelegate, which inherits QAbstractItemDelegate and handles + QStyledItemDelegate, which inherits QAbstractItemDelegate and handles the most common data types (notably \c int and QString). If we need to support custom data types, or want to customize the rendering or the editing for existing data types, we can subclass - QAbstractItemDelegate or QItemDelegate. See \l{Delegate Classes} + QAbstractItemDelegate or QStyledItemDelegate. See \l{Delegate Classes} for more information about delegates, and \l{Model/View Programming} if you need a high-level introduction to Qt's model/view architecture (including delegates). @@ -62,9 +62,9 @@ expressed as stars, such as "2 out of 5 stars" or "5 out of 6 stars". - \li \c StarDelegate inherits QItemDelegate and provides support + \li \c StarDelegate inherits QStyledItemDelegate and provides support for \c StarRating (in addition to the data types already - handled by QItemDelegate). + handled by QStyledItemDelegate). \li \c StarEditor inherits QWidget and is used by \c StarDelegate to let the user edit a star rating using the mouse. @@ -80,12 +80,12 @@ \snippet itemviews/stardelegate/stardelegate.h 0 All public functions are reimplemented virtual functions from - QItemDelegate to provide custom rendering and editing. + QStyledItemDelegate to provide custom rendering and editing. \section1 StarDelegate Class Implementation The \l{QAbstractItemDelegate::}{paint()} function is - reimplemented from QItemDelegate and is called whenever the view + reimplemented from QStyledItemDelegate and is called whenever the view needs to repaint an item: \snippet itemviews/stardelegate/stardelegate.cpp 0 @@ -93,7 +93,7 @@ The function is invoked once for each item, represented by a QModelIndex object from the model. If the data stored in the item is a \c StarRating, we paint it ourselves; otherwise, we let - QItemDelegate paint it for us. This ensures that the \c + QStyledItemDelegate paint it for us. This ensures that the \c StarDelegate can handle the most common data types. If the item is a \c StarRating, we draw the background if the diff --git a/examples/widgets/itemviews/stardelegate/main.cpp b/examples/widgets/itemviews/stardelegate/main.cpp index 51ca30c73a..452976bba0 100644 --- a/examples/widgets/itemviews/stardelegate/main.cpp +++ b/examples/widgets/itemviews/stardelegate/main.cpp @@ -101,10 +101,7 @@ int main(int argc, char *argv[]) tableWidget.setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::SelectedClicked); tableWidget.setSelectionBehavior(QAbstractItemView::SelectRows); - - QStringList headerLabels; - headerLabels << "Title" << "Genre" << "Artist" << "Rating"; - tableWidget.setHorizontalHeaderLabels(headerLabels); + tableWidget.setHorizontalHeaderLabels({"Title", "Genre", "Artist", "Rating"}); populateTableWidget(&tableWidget); diff --git a/examples/widgets/itemviews/stardelegate/stardelegate.cpp b/examples/widgets/itemviews/stardelegate/stardelegate.cpp index da5902a160..41ae5a920f 100644 --- a/examples/widgets/itemviews/stardelegate/stardelegate.cpp +++ b/examples/widgets/itemviews/stardelegate/stardelegate.cpp @@ -65,7 +65,7 @@ void StarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, painter->fillRect(option.rect, option.palette.highlight()); starRating.paint(painter, option.rect, option.palette, - StarRating::ReadOnly); + StarRating::EditMode::ReadOnly); } else { QStyledItemDelegate::paint(painter, option, index); } @@ -79,9 +79,8 @@ QSize StarDelegate::sizeHint(const QStyleOptionViewItem &option, if (index.data().canConvert()) { StarRating starRating = qvariant_cast(index.data()); return starRating.sizeHint(); - } else { - return QStyledItemDelegate::sizeHint(option, index); } + return QStyledItemDelegate::sizeHint(option, index); } //! [1] @@ -96,9 +95,8 @@ QWidget *StarDelegate::createEditor(QWidget *parent, connect(editor, &StarEditor::editingFinished, this, &StarDelegate::commitAndCloseEditor); return editor; - } else { - return QStyledItemDelegate::createEditor(parent, option, index); } + return QStyledItemDelegate::createEditor(parent, option, index); } //! [2] diff --git a/examples/widgets/itemviews/stardelegate/stardelegate.h b/examples/widgets/itemviews/stardelegate/stardelegate.h index ffc65fbedd..1fc31f8ee8 100644 --- a/examples/widgets/itemviews/stardelegate/stardelegate.h +++ b/examples/widgets/itemviews/stardelegate/stardelegate.h @@ -57,9 +57,8 @@ class StarDelegate : public QStyledItemDelegate { Q_OBJECT - public: - StarDelegate(QWidget *parent = 0) : QStyledItemDelegate(parent) {} + using QStyledItemDelegate::QStyledItemDelegate; void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; diff --git a/examples/widgets/itemviews/stardelegate/stareditor.cpp b/examples/widgets/itemviews/stardelegate/stareditor.cpp index 19a4b54d9e..43706eeae0 100644 --- a/examples/widgets/itemviews/stardelegate/stareditor.cpp +++ b/examples/widgets/itemviews/stardelegate/stareditor.cpp @@ -48,11 +48,11 @@ ** ****************************************************************************/ -#include - #include "stareditor.h" #include "starrating.h" +#include + //! [0] StarEditor::StarEditor(QWidget *parent) : QWidget(parent) @@ -71,35 +71,37 @@ QSize StarEditor::sizeHint() const void StarEditor::paintEvent(QPaintEvent *) { QPainter painter(this); - myStarRating.paint(&painter, rect(), this->palette(), - StarRating::Editable); + myStarRating.paint(&painter, rect(), palette(), + StarRating::EditMode::Editable); } //! [1] //! [2] void StarEditor::mouseMoveEvent(QMouseEvent *event) { - int star = starAtPosition(event->x()); + const int star = starAtPosition(event->x()); if (star != myStarRating.starCount() && star != -1) { myStarRating.setStarCount(star); update(); } + QWidget::mouseMoveEvent(event); } //! [2] //! [3] -void StarEditor::mouseReleaseEvent(QMouseEvent * /* event */) +void StarEditor::mouseReleaseEvent(QMouseEvent *event) { emit editingFinished(); + QWidget::mouseReleaseEvent(event); } //! [3] //! [4] -int StarEditor::starAtPosition(int x) +int StarEditor::starAtPosition(int x) const { - int star = (x / (myStarRating.sizeHint().width() - / myStarRating.maxStarCount())) + 1; + const int star = (x / (myStarRating.sizeHint().width() + / myStarRating.maxStarCount())) + 1; if (star <= 0 || star > myStarRating.maxStarCount()) return -1; diff --git a/examples/widgets/itemviews/stardelegate/stareditor.h b/examples/widgets/itemviews/stardelegate/stareditor.h index 4a4c3a4954..8b1bf2efed 100644 --- a/examples/widgets/itemviews/stardelegate/stareditor.h +++ b/examples/widgets/itemviews/stardelegate/stareditor.h @@ -59,9 +59,8 @@ class StarEditor : public QWidget { Q_OBJECT - public: - StarEditor(QWidget *parent = 0); + StarEditor(QWidget *parent = nullptr); QSize sizeHint() const override; void setStarRating(const StarRating &starRating) { @@ -78,7 +77,7 @@ protected: void mouseReleaseEvent(QMouseEvent *event) override; private: - int starAtPosition(int x); + int starAtPosition(int x) const; StarRating myStarRating; }; diff --git a/examples/widgets/itemviews/stardelegate/starrating.cpp b/examples/widgets/itemviews/stardelegate/starrating.cpp index 845e474de9..15e14965e3 100644 --- a/examples/widgets/itemviews/stardelegate/starrating.cpp +++ b/examples/widgets/itemviews/stardelegate/starrating.cpp @@ -48,19 +48,18 @@ ** ****************************************************************************/ +#include "starrating.h" + #include #include -#include "starrating.h" - -const int PaintingScaleFactor = 20; +constexpr int PaintingScaleFactor = 20; //! [0] StarRating::StarRating(int starCount, int maxStarCount) + : myStarCount(starCount), + myMaxStarCount(maxStarCount) { - myStarCount = starCount; - myMaxStarCount = maxStarCount; - starPolygon << QPointF(1.0, 0.5); for (int i = 1; i < 5; ++i) starPolygon << QPointF(0.5 + 0.5 * std::cos(0.8 * i * 3.14), @@ -87,23 +86,19 @@ void StarRating::paint(QPainter *painter, const QRect &rect, painter->setRenderHint(QPainter::Antialiasing, true); painter->setPen(Qt::NoPen); + painter->setBrush(mode == EditMode::Editable ? + palette.highlight() : + palette.foreground()); - if (mode == Editable) { - painter->setBrush(palette.highlight()); - } else { - painter->setBrush(palette.foreground()); - } - - int yOffset = (rect.height() - PaintingScaleFactor) / 2; + const int yOffset = (rect.height() - PaintingScaleFactor) / 2; painter->translate(rect.x(), rect.y() + yOffset); painter->scale(PaintingScaleFactor, PaintingScaleFactor); for (int i = 0; i < myMaxStarCount; ++i) { - if (i < myStarCount) { + if (i < myStarCount) painter->drawPolygon(starPolygon, Qt::WindingFill); - } else if (mode == Editable) { + else if (mode == EditMode::Editable) painter->drawPolygon(diamondPolygon, Qt::WindingFill); - } painter->translate(1.0, 0.0); } diff --git a/examples/widgets/itemviews/stardelegate/starrating.h b/examples/widgets/itemviews/stardelegate/starrating.h index fa77311914..fc3028db58 100644 --- a/examples/widgets/itemviews/stardelegate/starrating.h +++ b/examples/widgets/itemviews/stardelegate/starrating.h @@ -51,15 +51,15 @@ #ifndef STARRATING_H #define STARRATING_H -#include -#include -#include +#include +#include +#include //! [0] class StarRating { public: - enum EditMode { Editable, ReadOnly }; + enum class EditMode { Editable, ReadOnly }; explicit StarRating(int starCount = 1, int maxStarCount = 5); From b5e0d854bd22e56e1567d0e6dd89e9eb7035338f Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 23 Nov 2018 19:33:22 +0100 Subject: [PATCH 0510/1650] Cleanup SimpleDomModel example Cleanup the SimpleDomModel example: - include own headers first - use nullptr - use const where possible - init members in initialization list Change-Id: If7029a774793927b9a3a9115ea4a7053402a86a1 Reviewed-by: Sze Howe Koh Reviewed-by: Luca Beldi --- .../itemviews/simpledommodel/domitem.cpp | 30 +++++++------- .../itemviews/simpledommodel/domitem.h | 6 +-- .../itemviews/simpledommodel/dommodel.cpp | 40 ++++++++++--------- .../itemviews/simpledommodel/dommodel.h | 2 +- .../itemviews/simpledommodel/mainwindow.cpp | 9 +++-- .../itemviews/simpledommodel/mainwindow.h | 2 +- 6 files changed, 45 insertions(+), 44 deletions(-) diff --git a/examples/widgets/itemviews/simpledommodel/domitem.cpp b/examples/widgets/itemviews/simpledommodel/domitem.cpp index c8b35b2e0a..a2dc9530f0 100644 --- a/examples/widgets/itemviews/simpledommodel/domitem.cpp +++ b/examples/widgets/itemviews/simpledommodel/domitem.cpp @@ -53,23 +53,20 @@ #include //! [0] -DomItem::DomItem(QDomNode &node, int row, DomItem *parent) -{ - domNode = node; +DomItem::DomItem(const QDomNode &node, int row, DomItem *parent) + : domNode(node), //! [0] - // Record the item's location within its parent. + // Record the item's location within its parent. //! [1] - rowNumber = row; - parentItem = parent; -} + parentItem(parent), + rowNumber(row) +{} //! [1] //! [2] DomItem::~DomItem() { - QHash::iterator it; - for (it = childItems.begin(); it != childItems.end(); ++it) - delete it.value(); + qDeleteAll(childItems); } //! [2] @@ -90,21 +87,22 @@ DomItem *DomItem::parent() //! [5] DomItem *DomItem::child(int i) { - if (childItems.contains(i)) - return childItems[i]; + DomItem *childItem = childItems.value(i); + if (childItem) + return childItem; + // if child does not yet exist, create it if (i >= 0 && i < domNode.childNodes().count()) { QDomNode childNode = domNode.childNodes().item(i); - DomItem *childItem = new DomItem(childNode, i, this); + childItem = new DomItem(childNode, i, this); childItems[i] = childItem; - return childItem; } - return 0; + return childItem; } //! [5] //! [6] -int DomItem::row() +int DomItem::row() const { return rowNumber; } diff --git a/examples/widgets/itemviews/simpledommodel/domitem.h b/examples/widgets/itemviews/simpledommodel/domitem.h index b5db16009c..4a74db5139 100644 --- a/examples/widgets/itemviews/simpledommodel/domitem.h +++ b/examples/widgets/itemviews/simpledommodel/domitem.h @@ -58,16 +58,16 @@ class DomItem { public: - DomItem(QDomNode &node, int row, DomItem *parent = 0); + DomItem(const QDomNode &node, int row, DomItem *parent = nullptr); ~DomItem(); DomItem *child(int i); DomItem *parent(); QDomNode node() const; - int row(); + int row() const; private: QDomNode domNode; - QHash childItems; + QHash childItems; DomItem *parentItem; int rowNumber; }; diff --git a/examples/widgets/itemviews/simpledommodel/dommodel.cpp b/examples/widgets/itemviews/simpledommodel/dommodel.cpp index f9ba0b5801..8e15252ebb 100644 --- a/examples/widgets/itemviews/simpledommodel/dommodel.cpp +++ b/examples/widgets/itemviews/simpledommodel/dommodel.cpp @@ -48,16 +48,17 @@ ** ****************************************************************************/ -#include "domitem.h" #include "dommodel.h" +#include "domitem.h" #include //! [0] -DomModel::DomModel(QDomDocument document, QObject *parent) - : QAbstractItemModel(parent), domDocument(document) +DomModel::DomModel(const QDomDocument &document, QObject *parent) + : QAbstractItemModel(parent), + domDocument(document), + rootItem(new DomItem(domDocument, 0)) { - rootItem = new DomItem(domDocument, 0); } //! [0] @@ -69,8 +70,9 @@ DomModel::~DomModel() //! [1] //! [2] -int DomModel::columnCount(const QModelIndex &/*parent*/) const +int DomModel::columnCount(const QModelIndex &parent) const { + Q_UNUSED(parent); return 3; } //! [2] @@ -84,28 +86,31 @@ QVariant DomModel::data(const QModelIndex &index, int role) const if (role != Qt::DisplayRole) return QVariant(); - DomItem *item = static_cast(index.internalPointer()); + const DomItem *item = static_cast(index.internalPointer()); - QDomNode node = item->node(); + const QDomNode node = item->node(); //! [3] //! [4] - QStringList attributes; - QDomNamedNodeMap attributeMap = node.attributes(); switch (index.column()) { case 0: return node.nodeName(); case 1: + { + const QDomNamedNodeMap attributeMap = node.attributes(); + QStringList attributes; for (int i = 0; i < attributeMap.count(); ++i) { QDomNode attribute = attributeMap.item(i); attributes << attribute.nodeName() + "=\"" - +attribute.nodeValue() + '"'; + + attribute.nodeValue() + '"'; } return attributes.join(' '); + } case 2: - return node.nodeValue().split("\n").join(' '); + return node.nodeValue().split('\n').join(' '); default: - return QVariant(); + break; } + return QVariant(); } //! [4] @@ -113,7 +118,7 @@ QVariant DomModel::data(const QModelIndex &index, int role) const Qt::ItemFlags DomModel::flags(const QModelIndex &index) const { if (!index.isValid()) - return 0; + return Qt::NoItemFlags; return QAbstractItemModel::flags(index); } @@ -132,17 +137,15 @@ QVariant DomModel::headerData(int section, Qt::Orientation orientation, case 2: return tr("Value"); default: - return QVariant(); + break; } } - return QVariant(); } //! [6] //! [7] -QModelIndex DomModel::index(int row, int column, const QModelIndex &parent) - const +QModelIndex DomModel::index(int row, int column, const QModelIndex &parent) const { if (!hasIndex(row, column, parent)) return QModelIndex(); @@ -159,8 +162,7 @@ QModelIndex DomModel::index(int row, int column, const QModelIndex &parent) DomItem *childItem = parentItem->child(row); if (childItem) return createIndex(row, column, childItem); - else - return QModelIndex(); + return QModelIndex(); } //! [8] diff --git a/examples/widgets/itemviews/simpledommodel/dommodel.h b/examples/widgets/itemviews/simpledommodel/dommodel.h index 411f58295c..a91bb33cf9 100644 --- a/examples/widgets/itemviews/simpledommodel/dommodel.h +++ b/examples/widgets/itemviews/simpledommodel/dommodel.h @@ -63,7 +63,7 @@ class DomModel : public QAbstractItemModel Q_OBJECT public: - explicit DomModel(QDomDocument document, QObject *parent = 0); + explicit DomModel(const QDomDocument &document, QObject *parent = nullptr); ~DomModel(); QVariant data(const QModelIndex &index, int role) const override; diff --git a/examples/widgets/itemviews/simpledommodel/mainwindow.cpp b/examples/widgets/itemviews/simpledommodel/mainwindow.cpp index 7d43d0fc02..86543b07a6 100644 --- a/examples/widgets/itemviews/simpledommodel/mainwindow.cpp +++ b/examples/widgets/itemviews/simpledommodel/mainwindow.cpp @@ -48,22 +48,23 @@ ** ****************************************************************************/ -#include "dommodel.h" #include "mainwindow.h" +#include "dommodel.h" #include #include #include #include -MainWindow::MainWindow() : QMainWindow(), model(0) +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent), + model(new DomModel(QDomDocument(), this)), + view(new QTreeView(this)) { fileMenu = menuBar()->addMenu(tr("&File")); fileMenu->addAction(tr("&Open..."), this, &MainWindow::openFile, QKeySequence::Open); fileMenu->addAction(tr("E&xit"), this, &QWidget::close, QKeySequence::Quit); - model = new DomModel(QDomDocument(), this); - view = new QTreeView(this); view->setModel(model); setCentralWidget(view); diff --git a/examples/widgets/itemviews/simpledommodel/mainwindow.h b/examples/widgets/itemviews/simpledommodel/mainwindow.h index 938a1c54c1..b3f8d77f35 100644 --- a/examples/widgets/itemviews/simpledommodel/mainwindow.h +++ b/examples/widgets/itemviews/simpledommodel/mainwindow.h @@ -65,7 +65,7 @@ class MainWindow : public QMainWindow Q_OBJECT public: - MainWindow(); + MainWindow(QWidget *parent = nullptr); public slots: void openFile(); From 4c585690852e2c3e3700c2060ef0408a7e533d4e Mon Sep 17 00:00:00 2001 From: Nick D'Ademo Date: Sat, 3 Nov 2018 13:58:09 +0800 Subject: [PATCH 0511/1650] QMdiArea: Take scroll bars into account when tiling subwindows QMdiAreaPrivate::resizeToMinimumTileSize() does not take into account scroll bars when calculating the minimum size for the QMdiArea widget. As a result, if scroll bars are enabled or showing during a tiling operation, the top-level widget incorrectly expands in size (instead of utilizing the scroll bars). Therefore, we should only resize the top-level widget if scroll bars are disabled. Fixes: QTBUG-40821 Change-Id: I3a8b7582d23fdf12d2b09f3740eea6b60bb395c3 Reviewed-by: Richard Moe Gustavsen --- src/widgets/widgets/qmdiarea.cpp | 6 +++++- .../widgets/widgets/qmdiarea/tst_qmdiarea.cpp | 15 +++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/widgets/widgets/qmdiarea.cpp b/src/widgets/widgets/qmdiarea.cpp index c1817060dd..cdc1291511 100644 --- a/src/widgets/widgets/qmdiarea.cpp +++ b/src/widgets/widgets/qmdiarea.cpp @@ -1296,7 +1296,11 @@ QRect QMdiAreaPrivate::resizeToMinimumTileSize(const QSize &minSubWindowSize, in minAreaHeight += 2 * frame; } const QSize diff = QSize(minAreaWidth, minAreaHeight).expandedTo(q->size()) - q->size(); - topLevel->resize(topLevel->size() + diff); + // Only resize topLevel widget if scroll bars are disabled. + if (hbarpolicy == Qt::ScrollBarAlwaysOff) + topLevel->resize(topLevel->size().width() + diff.width(), topLevel->size().height()); + if (vbarpolicy == Qt::ScrollBarAlwaysOff) + topLevel->resize(topLevel->size().width(), topLevel->size().height() + diff.height()); } QRect domain = viewport->rect(); diff --git a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp index 6cc19051d2..8b470fb579 100644 --- a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp +++ b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp @@ -1713,6 +1713,8 @@ void tst_QMdiArea::tileSubWindows() // Prevent scrollbars from messing up the expected viewport calculation below workspace.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); workspace.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + QCOMPARE(workspace.horizontalScrollBarPolicy(), Qt::ScrollBarAlwaysOff); + QCOMPARE(workspace.verticalScrollBarPolicy(), Qt::ScrollBarAlwaysOff); workspace.tileSubWindows(); // The sub-windows are now tiled like this: @@ -1731,9 +1733,11 @@ void tst_QMdiArea::tileSubWindows() const QSize expectedViewportSize(3 * minSize.width() + spacing, 3 * minSize.height() + spacing); QTRY_COMPARE(workspace.viewport()->rect().size(), expectedViewportSize); - // Restore original scrollbar behavior for test below + // Enable scroll bar for test below (default property for QMdiArea is Qt::ScrollBarAlwaysOff) workspace.setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); workspace.setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); + QCOMPARE(workspace.horizontalScrollBarPolicy(), Qt::ScrollBarAsNeeded); + QCOMPARE(workspace.verticalScrollBarPolicy(), Qt::ScrollBarAsNeeded); // Not enough space for all sub-windows to be visible -> provide scroll bars. workspace.resize(160, 150); @@ -1754,13 +1758,16 @@ void tst_QMdiArea::tileSubWindows() QCOMPARE(vBar->value(), 0); QCOMPARE(vBar->minimum(), 0); + // Tile windows with scroll bars enabled. workspace.tileSubWindows(); QVERIFY(QTest::qWaitForWindowExposed(&workspace)); qApp->processEvents(); - QTRY_VERIFY(workspace.size() != QSize(150, 150)); - QTRY_VERIFY(!vBar->isVisible()); - QTRY_VERIFY(!hBar->isVisible()); + // Workspace should not have changed size after tile. + QTRY_VERIFY(workspace.size() == QSize(160, 150)); + // Scroll bars should be visible. + QTRY_VERIFY(vBar->isVisible()); + QTRY_VERIFY(hBar->isVisible()); } void tst_QMdiArea::cascadeAndTileSubWindows() From f5cfc36e3e47d59ebce8f6b8c6d75b2724e985c7 Mon Sep 17 00:00:00 2001 From: Ivan Komissarov Date: Sun, 21 Oct 2018 15:48:41 +0200 Subject: [PATCH 0512/1650] qgraphicslayoutstyleinfo: Remove useless check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no sense in testing the 'm_widget' pointer against null, as the memory was allocated using the 'new' operator. The exception will be generated in the case of memory allocation error. Task-number: QTBUG-71156 Change-Id: I898bac6d9b51b2abd7a5311aa71ac2492c7c042c Reviewed-by: Jan Arve Sæther --- src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp b/src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp index af969b346d..8b4861bf45 100644 --- a/src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp +++ b/src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp @@ -51,8 +51,7 @@ QGraphicsLayoutStyleInfo::QGraphicsLayoutStyleInfo(const QGraphicsLayoutPrivate : m_layout(layout), m_style(0) { m_widget = new QWidget; // pixelMetric might need a widget ptr - if (m_widget) - m_styleOption.initFrom(m_widget); + m_styleOption.initFrom(m_widget); m_isWindow = m_styleOption.state & QStyle::State_Window; } From 37f773a754cd8c6a9ce05a67ae2a59cea4b4cc4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Tue, 16 Oct 2018 12:30:02 +0200 Subject: [PATCH 0513/1650] _q_makePkcs12: clean up Remove braces for single-line bodies, space around binary operators Change-Id: I958396772966428dcd9694279175fd61d6109b40 Reviewed-by: Timur Pocheptsov Reviewed-by: Edward Welbourne --- src/network/ssl/qsslsocket_qt.cpp | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/network/ssl/qsslsocket_qt.cpp b/src/network/ssl/qsslsocket_qt.cpp index 2c78f0f4e7..da865c476c 100644 --- a/src/network/ssl/qsslsocket_qt.cpp +++ b/src/network/ssl/qsslsocket_qt.cpp @@ -92,14 +92,12 @@ static QByteArray _q_PKCS12_keygen(char id, const QByteArray &salt, const QStrin QByteArray S, P; const int sSize = v * ((salt.size() + v - 1) / v); S.resize(sSize); - for (int i = 0; i < sSize; ++i) { + for (int i = 0; i < sSize; ++i) S[i] = salt[i % salt.size()]; - } const int pSize = v * ((passUnicode.size() + v - 1) / v); P.resize(pSize); - for (int i = 0; i < pSize; ++i) { + for (int i = 0; i < pSize; ++i) P[i] = passUnicode[i % passUnicode.size()]; - } QByteArray I = S + P; // apply hashing @@ -117,16 +115,15 @@ static QByteArray _q_PKCS12_keygen(char id, const QByteArray &salt, const QStrin Ai = hash.result(); } - for (int j = 0; j < v; ++j) { + for (int j = 0; j < v; ++j) B[j] = Ai[j % u]; - } // modify I as Ij = (Ij + B + 1) modulo 2^v for (int p = 0; p < I.size(); p += v) { quint8 carry = 1; for (int j = v - 1; j >= 0; --j) { - quint16 v = quint8(I[p+j]) + quint8(B[j]) + carry; - I[p+j] = v & 0xff; + quint16 v = quint8(I[p + j]) + quint8(B[j]) + carry; + I[p + j] = v & 0xff; carry = (v & 0xff00) >> 8; } } @@ -139,9 +136,8 @@ static QByteArray _q_PKCS12_salt() { QByteArray salt; salt.resize(8); - for (int i = 0; i < salt.size(); ++i) { + for (int i = 0; i < salt.size(); ++i) salt[i] = (qrand() & 0xff); - } return salt; } @@ -203,7 +199,7 @@ static QByteArray _q_PKCS12_shroudedKeyBag(const QSslKey &key, const QString &pa QDataStream plainStream(&plain, QIODevice::WriteOnly); _q_PKCS12_key(key).write(plainStream); QByteArray crypted = QSslKeyPrivate::encrypt(QSslKeyPrivate::DesEde3Cbc, - plain, cKey, cIv); + plain, cKey, cIv); QVector items; items << QAsn1Element::fromObjectId("1.2.840.113549.1.12.10.1.2"); From e19df161cdc14f834a278fe0939d50475864a78c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Tue, 16 Oct 2018 12:21:59 +0200 Subject: [PATCH 0514/1650] _q_makePkcs12: Don't embed a key if we don't have one Usually we embed the private key for the leaf certificate, but in Schannel _q_makePkcs12 is also used to create a certificate store for our CA certificates, which we don't have any private key for. So lift this restriction. Change-Id: Ic86a2a6725f2c8272c951148eb97e18a964a36f2 Reviewed-by: Edward Welbourne Reviewed-by: Timur Pocheptsov --- src/network/ssl/qsslsocket_qt.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/network/ssl/qsslsocket_qt.cpp b/src/network/ssl/qsslsocket_qt.cpp index da865c476c..b0fb60ea76 100644 --- a/src/network/ssl/qsslsocket_qt.cpp +++ b/src/network/ssl/qsslsocket_qt.cpp @@ -242,8 +242,10 @@ static QByteArray _q_PKCS12_bag(const QList &certs, const QSslK items << _q_PKCS7_data(_q_PKCS12_certBag(certs[i])); // key - const QByteArray localKeyId = certs.first().digest(QCryptographicHash::Sha1); - items << _q_PKCS7_data(_q_PKCS12_shroudedKeyBag(key, passPhrase, localKeyId)); + if (!key.isNull()) { + const QByteArray localKeyId = certs.first().digest(QCryptographicHash::Sha1); + items << _q_PKCS7_data(_q_PKCS12_shroudedKeyBag(key, passPhrase, localKeyId)); + } // dump QAsn1Element root = QAsn1Element::fromVector(items); From e2f473f4d43afc0c2b8d6256b57ea74ad256e437 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Wed, 31 Oct 2018 20:11:58 +0100 Subject: [PATCH 0515/1650] QListWidget: mark (is|set)Item(Selected|Hidden) as deprecated QListWidget::(is|set)Item(Selected|Hidden)() are deprecated for a long time but not marked as such. Therefore explicitly mark them as deprecated so they can get removed with Qt6. Change-Id: I4567e740f1ebb5841b2e5b50c601fb83a782950c Reviewed-by: Konstantin Shegunov Reviewed-by: Samuel Gaist Reviewed-by: Richard Moe Gustavsen --- src/widgets/itemviews/qlistwidget.cpp | 85 +++++++++++-------- src/widgets/itemviews/qlistwidget.h | 23 ++--- .../itemviews/qlistwidget/tst_qlistwidget.cpp | 26 +++--- 3 files changed, 77 insertions(+), 57 deletions(-) diff --git a/src/widgets/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp index 6e0bdb3f22..ea92c5605b 100644 --- a/src/widgets/itemviews/qlistwidget.cpp +++ b/src/widgets/itemviews/qlistwidget.cpp @@ -582,24 +582,6 @@ Qt::DropActions QListModel::supportedDropActions() const Returns the list widget containing the item. */ -/*! - \fn void QListWidgetItem::setSelected(bool select) - \since 4.2 - - Sets the selected state of the item to \a select. - - \sa isSelected() -*/ - -/*! - \fn bool QListWidgetItem::isSelected() const - \since 4.2 - - Returns \c true if the item is selected; otherwise returns \c false. - - \sa setSelected() -*/ - /*! \fn void QListWidgetItem::setHidden(bool hide) \since 4.2 @@ -1001,6 +983,50 @@ QDataStream &operator>>(QDataStream &in, QListWidgetItem &item) the item delegate will compute the size hint based on the item data. */ +/*! + \fn void QListWidgetItem::setSelected(bool select) + \since 4.2 + + Sets the selected state of the item to \a select. + + \sa isSelected() +*/ +void QListWidgetItem::setSelected(bool select) +{ + const QListModel *model = listModel(); + if (!model || !view->selectionModel()) + return; + const QAbstractItemView::SelectionMode selectionMode = view->selectionMode(); + if (selectionMode == QAbstractItemView::NoSelection) + return; + const QModelIndex index = model->index(this); + if (selectionMode == QAbstractItemView::SingleSelection) + view->selectionModel()->select(index, select + ? QItemSelectionModel::ClearAndSelect + : QItemSelectionModel::Deselect); + else + view->selectionModel()->select(index, select + ? QItemSelectionModel::Select + : QItemSelectionModel::Deselect); +} + +/*! + \fn bool QListWidgetItem::isSelected() const + \since 4.2 + + Returns \c true if the item is selected; otherwise returns \c false. + + \sa setSelected() +*/ +bool QListWidgetItem::isSelected() const +{ + const QListModel *model = listModel(); + if (!model || !view->selectionModel()) + return false; + const QModelIndex index = model->index(this); + return view->selectionModel()->isSelected(index); +} + /*! \fn void QListWidgetItem::setFlags(Qt::ItemFlags flags) @@ -1743,6 +1769,7 @@ void QListWidget::setItemWidget(QListWidgetItem *item, QWidget *widget) QAbstractItemView::setIndexWidget(index, widget); } +#if QT_DEPRECATED_SINCE(5, 13) /*! Returns \c true if \a item is selected; otherwise returns \c false. @@ -1752,9 +1779,7 @@ void QListWidget::setItemWidget(QListWidgetItem *item, QWidget *widget) */ bool QListWidget::isItemSelected(const QListWidgetItem *item) const { - Q_D(const QListWidget); - QModelIndex index = d->listModel()->index(const_cast(item)); - return selectionModel()->isSelected(index); + return ((item && item->listWidget() == this) ? item->isSelected() : false); } /*! @@ -1767,20 +1792,10 @@ bool QListWidget::isItemSelected(const QListWidgetItem *item) const */ void QListWidget::setItemSelected(const QListWidgetItem *item, bool select) { - Q_D(QListWidget); - QModelIndex index = d->listModel()->index(const_cast(item)); - - if (d->selectionMode == SingleSelection) { - selectionModel()->select(index, select - ? QItemSelectionModel::ClearAndSelect - : QItemSelectionModel::Deselect); - } else if (d->selectionMode != NoSelection) { - selectionModel()->select(index, select - ? QItemSelectionModel::Select - : QItemSelectionModel::Deselect); - } - + if (item && item->listWidget() == this) + const_cast(item)->setSelected(select); } +#endif /*! Returns a list of all selected items in the list widget. @@ -1816,6 +1831,7 @@ QList QListWidget::findItems(const QString &text, Qt::MatchFla return items; } +#if QT_DEPRECATED_SINCE(5, 13) /*! Returns \c true if the \a item is explicitly hidden; otherwise returns \c false. @@ -1839,6 +1855,7 @@ void QListWidget::setItemHidden(const QListWidgetItem *item, bool hide) { setRowHidden(row(item), hide); } +#endif /*! Scrolls the view if necessary to ensure that the \a item is visible. diff --git a/src/widgets/itemviews/qlistwidget.h b/src/widgets/itemviews/qlistwidget.h index e96f639502..c093d13e6d 100644 --- a/src/widgets/itemviews/qlistwidget.h +++ b/src/widgets/itemviews/qlistwidget.h @@ -72,8 +72,8 @@ public: inline QListWidget *listWidget() const { return view; } - inline void setSelected(bool select); - inline bool isSelected() const; + void setSelected(bool select); + bool isSelected() const; inline void setHidden(bool hide); inline bool isHidden() const; @@ -167,7 +167,6 @@ public: private: QListModel *listModel() const; -private: int rtti; QVector dummy; QListWidget *view; @@ -256,13 +255,21 @@ public: void setItemWidget(QListWidgetItem *item, QWidget *widget); inline void removeItemWidget(QListWidgetItem *item); +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X ("Use QListWidgetItem::isSelected() instead") bool isItemSelected(const QListWidgetItem *item) const; + QT_DEPRECATED_X ("Use QListWidgetItem::setSelected() instead") void setItemSelected(const QListWidgetItem *item, bool select); +#endif QList selectedItems() const; QList findItems(const QString &text, Qt::MatchFlags flags) const; +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X ("Use QListWidgetItem::isHidden() instead") bool isItemHidden(const QListWidgetItem *item) const; + QT_DEPRECATED_X ("Use QListWidgetItem::setHidden() instead") void setItemHidden(const QListWidgetItem *item, bool hide); +#endif #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) protected: #endif @@ -341,17 +348,11 @@ inline void QListWidget::addItem(QListWidgetItem *aitem) inline QListWidgetItem *QListWidget::itemAt(int ax, int ay) const { return itemAt(QPoint(ax, ay)); } -inline void QListWidgetItem::setSelected(bool aselect) -{ if (view) view->setItemSelected(this, aselect); } - -inline bool QListWidgetItem::isSelected() const -{ return (view ? view->isItemSelected(this) : false); } - inline void QListWidgetItem::setHidden(bool ahide) -{ if (view) view->setItemHidden(this, ahide); } +{ if (view) view->setRowHidden(view->row(this), ahide); } inline bool QListWidgetItem::isHidden() const -{ return (view ? view->isItemHidden(this) : false); } +{ return (view ? view->isRowHidden(view->row(this)) : false); } QT_END_NAMESPACE diff --git a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp index d8e14df353..0c1b20d61a 100644 --- a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp +++ b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp @@ -344,7 +344,7 @@ void tst_QListWidget::addItem2() testWidget->addItem(item); QCOMPARE(testWidget->count(), ++count); QCOMPARE(testWidget->item(testWidget->count()-1), item); - QCOMPARE(testWidget->isItemHidden(item), false); + QCOMPARE(item->isHidden(), false); } void tst_QListWidget::addItems() @@ -402,9 +402,11 @@ void tst_QListWidget::closePersistentEditor() void tst_QListWidget::setItemHidden() { +#if QT_DEPRECATED_SINCE(5, 13) // Boundary checking testWidget->setItemHidden(0, true); testWidget->setItemHidden(0, false); +#endif int totalHidden = 0; for (int i = 0; i < testWidget->model()->rowCount(); ++i) @@ -421,27 +423,27 @@ void tst_QListWidget::setItemHidden() newTotal++; QCOMPARE(newTotal, totalHidden); - testWidget->setItemHidden(item, true); - QCOMPARE(testWidget->isItemHidden(item), true); + item->setHidden(true); + QCOMPARE(item->isHidden(), true); // Check that nothing else changed newTotal = 0; for (int i = 0; i < testWidget->model()->rowCount(); ++i) - if (testWidget->isItemHidden(testWidget->item(i))) + if (testWidget->item(i)->isHidden()) newTotal++; QCOMPARE(newTotal, totalHidden + 1); - testWidget->setItemHidden(item, false); - QCOMPARE(testWidget->isItemHidden(item), false); + item->setHidden(false); + QCOMPARE(item->isHidden(), false); // Check that nothing else changed newTotal = 0; for (int i = 0; i < testWidget->model()->rowCount(); ++i) - if (testWidget->isItemHidden(testWidget->item(i))) + if (testWidget->item(i)->isHidden()) newTotal++; QCOMPARE(newTotal, totalHidden); - testWidget->setItemHidden(item, true); + item->setHidden(true); } void tst_QListWidget::setCurrentItem_data() @@ -847,7 +849,7 @@ void tst_QListWidget::selectedItems() testWidget->setSelectionMode(QListWidget::SingleSelection); for (int i=0; iitem(i); - testWidget->setItemSelected(item, true); + item->setSelected(true); QVERIFY(item->isSelected()); QCOMPARE(testWidget->selectedItems().count(), 1); } @@ -860,10 +862,10 @@ void tst_QListWidget::selectedItems() QCOMPARE(testWidget->count(), itemCount); // hide items foreach (int row, hiddenRows) - testWidget->setItemHidden(testWidget->item(row), true); + testWidget->item(row)->setHidden(true); // select items foreach (int row, selectedRows) - testWidget->setItemSelected(testWidget->item(row), true); + testWidget->item(row)->setSelected(true); // check that the correct number of items and the expected items are there QList selectedItems = testWidget->selectedItems(); @@ -874,7 +876,7 @@ void tst_QListWidget::selectedItems() //check that isSelected agrees with selectedItems for (int i=0; iitem(i); - if (testWidget->isItemSelected(item)) + if (item->isSelected()) QVERIFY(selectedItems.contains(item)); } } From 0669cafac7be2a1a57c33491c729907337223f8f Mon Sep 17 00:00:00 2001 From: Sergio Martins Date: Thu, 29 Nov 2018 18:57:34 +0000 Subject: [PATCH 0516/1650] Enable Werror for clang 7.0 too Change-Id: Idc8d39d198500632cfb7a3ec6b471ba6ec1ce4ee Reviewed-by: Thiago Macieira --- mkspecs/features/qt_common.prf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/qt_common.prf b/mkspecs/features/qt_common.prf index 4ad9946ae0..cc50f0dd1d 100644 --- a/mkspecs/features/qt_common.prf +++ b/mkspecs/features/qt_common.prf @@ -97,10 +97,10 @@ warnings_are_errors:warning_clean { # compiler. clang { # Apple clang 4.0-4.2,5.0-5.1,6.0-6.4,7.0-7.3,8.0-8.3,9.0-9.2 - # Regular clang 3.x-6.0 + # Regular clang 3.x-7.0 apple_ver = $${QT_APPLE_CLANG_MAJOR_VERSION}.$${QT_APPLE_CLANG_MINOR_VERSION} reg_ver = $${QT_CLANG_MAJOR_VERSION}.$${QT_CLANG_MINOR_VERSION} - contains(apple_ver, "4\\.[012]|5\\.[01]|6\\.[01234]|7\\.[0123]|8\\.[0123]|9\\.[012]")|contains(reg_ver, "[345]\\.|6\\.0") { + contains(apple_ver, "4\\.[012]|5\\.[01]|6\\.[01234]|7\\.[0123]|8\\.[0123]|9\\.[012]")|contains(reg_ver, "[345]\\.|[67]\\.0") { QMAKE_CXXFLAGS_WARN_ON += -Werror -Wno-error=\\$${LITERAL_HASH}warnings -Wno-error=deprecated-declarations $$WERROR } } else:intel_icc:linux { From f5654d909a7081fcc9f1091b2132fdcb07419776 Mon Sep 17 00:00:00 2001 From: Sergio Martins Date: Mon, 3 Dec 2018 22:58:29 +0000 Subject: [PATCH 0517/1650] Pass non-trivial types by const-ref in range-loop [-Wclazy-range-loop] corelib/serialization/qcbormap.h:176:14: warning: Missing reference in range-for with non trivial type (QPair) corelib/serialization/qjsoncbor.cpp:820:10: warning: Missing reference in range-for with non trivial type (QJsonValue) gui/kernel/qguiapplication.cpp:1171:10: warning: Missing reference in range-for with non trivial type (QString) printsupport/dialogs/qprintdialog_unix.cpp:741:10: warning: Missing reference in range-for with non trivial type (QString) printsupport/kernel/qprinter.cpp:1851:10: warning: Missing reference in range-for with non trivial type (QVariant) tools/qlalr/cppgenerator.cpp:463:8: warning: Missing reference in range-for with non trivial type (Name) Change-Id: I327b0f116e329e55952ed5740a5f5af4b2918392 Reviewed-by: Friedemann Kleint Reviewed-by: Thiago Macieira --- src/corelib/serialization/qcbormap.h | 2 +- src/corelib/serialization/qjsoncbor.cpp | 2 +- src/gui/kernel/qguiapplication.cpp | 2 +- src/printsupport/dialogs/qprintdialog_unix.cpp | 2 +- src/printsupport/kernel/qprinter.cpp | 2 +- src/tools/qlalr/cppgenerator.cpp | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/corelib/serialization/qcbormap.h b/src/corelib/serialization/qcbormap.h index 15a3bcdcef..4aea901eef 100644 --- a/src/corelib/serialization/qcbormap.h +++ b/src/corelib/serialization/qcbormap.h @@ -173,7 +173,7 @@ public: : QCborMap() { detach(args.size()); - for (auto pair : args) + for (const auto &pair : args) insert(pair.first, pair.second); } ~QCborMap(); diff --git a/src/corelib/serialization/qjsoncbor.cpp b/src/corelib/serialization/qjsoncbor.cpp index 158f1950d0..b4d3b4db18 100644 --- a/src/corelib/serialization/qjsoncbor.cpp +++ b/src/corelib/serialization/qjsoncbor.cpp @@ -817,7 +817,7 @@ QCborArray QCborArray::fromJsonArray(const QJsonArray &array) { QCborArray a; a.detach(array.size()); - for (const QJsonValue v : array) { + for (const QJsonValue &v : array) { if (v.isString()) a.d->append(v.toString()); else diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index f4e2dda05a..b5e9b233e1 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1168,7 +1168,7 @@ static void init_platform(const QString &pluginNamesWithArguments, const QString QStringList plugins = pluginNamesWithArguments.split(QLatin1Char(';')); QStringList platformArguments; QStringList availablePlugins = QPlatformIntegrationFactory::keys(platformPluginPath); - for (auto pluginArgument : plugins) { + for (const auto &pluginArgument : plugins) { // Split into platform name and arguments QStringList arguments = pluginArgument.split(QLatin1Char(':')); const QString name = arguments.takeFirst().toLower(); diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp index 5390a8b2f2..9fb9d6c55e 100644 --- a/src/printsupport/dialogs/qprintdialog_unix.cpp +++ b/src/printsupport/dialogs/qprintdialog_unix.cpp @@ -738,7 +738,7 @@ static std::vector> pageRangesFromString(const QString &page { std::vector> result; const QStringList items = pagesString.split(','); - for (const QString item : items) { + for (const QString &item : items) { if (item.isEmpty()) return {}; diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp index 829a13863b..ddcd8c4702 100644 --- a/src/printsupport/kernel/qprinter.cpp +++ b/src/printsupport/kernel/qprinter.cpp @@ -1848,7 +1848,7 @@ QList QPrinter::supportedResolutions() const = d->printEngine->property(QPrintEngine::PPK_SupportedResolutions).toList(); QList intlist; intlist.reserve(varlist.size()); - for (auto var : varlist) + for (const auto &var : varlist) intlist << var.toInt(); return intlist; } diff --git a/src/tools/qlalr/cppgenerator.cpp b/src/tools/qlalr/cppgenerator.cpp index b14c73a8fe..508db696b1 100644 --- a/src/tools/qlalr/cppgenerator.cpp +++ b/src/tools/qlalr/cppgenerator.cpp @@ -460,7 +460,7 @@ void CppGenerator::generateDecl (QTextStream &out) << "public:" << endl << " enum VariousConstants {" << endl; - for (Name t : qAsConst(grammar.terminals)) + for (const Name &t : qAsConst(grammar.terminals)) { QString name = *t; int value = std::distance (grammar.names.begin (), t); From 83bf7d82609b45a76c91c2a869cfbcbcbb9e0995 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Wed, 5 Dec 2018 13:37:00 +0100 Subject: [PATCH 0518/1650] doc: Let qdoc ignore Q_DECLARE_INTERFACE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This macro declares three template functions that are different for each use of the macro. The functions are in the public API but they are not meant to be documented. This update just defines the macro to be empty so clang in qdoc will ignore it. Without this, clang reports a lot of errors incorrectly, but if we let clang process the macro, it declares all those extra functions which then must be documented with \internal in the cpp files, and we don't want to do that. This will probably be redone in a later version using a custom annotation attribute. Change-Id: I78ae4bcc98a3844b803d7ef7b1eba5d5539b043f Reviewed-by: Tor Arne Vestbø --- src/corelib/kernel/qobject.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index aac9bcdee9..9ae6155f52 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -517,7 +517,10 @@ inline T qobject_cast(const QObject *object) template inline const char * qobject_interface_iid() { return nullptr; } -#if !defined(Q_MOC_RUN) && !defined(Q_CLANG_QDOC) + +#if defined(Q_CLANG_QDOC) +# define Q_DECLARE_INTERFACE(IFace, IId) +#elif !defined(Q_MOC_RUN) # define Q_DECLARE_INTERFACE(IFace, IId) \ template <> inline const char *qobject_interface_iid() \ { return IId; } \ From a8dae3ad0bc6377c695326e48d3c0db9f73107db Mon Sep 17 00:00:00 2001 From: Ivan Komissarov Date: Mon, 22 Oct 2018 19:53:53 +0200 Subject: [PATCH 0519/1650] qgraphicslayoutstyleinfo: Improve memory handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I3d699a89e8833570132cbd03aa575e4f4cf9249b Reviewed-by: Jan Arve Sæther --- src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp | 7 +++---- src/widgets/graphicsview/qgraphicslayoutstyleinfo_p.h | 4 +++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp b/src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp index 8b4861bf45..da2510a8cb 100644 --- a/src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp +++ b/src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp @@ -50,14 +50,13 @@ QT_BEGIN_NAMESPACE QGraphicsLayoutStyleInfo::QGraphicsLayoutStyleInfo(const QGraphicsLayoutPrivate *layout) : m_layout(layout), m_style(0) { - m_widget = new QWidget; // pixelMetric might need a widget ptr - m_styleOption.initFrom(m_widget); + m_widget.reset(new QWidget); // pixelMetric might need a widget ptr + m_styleOption.initFrom(m_widget.get()); m_isWindow = m_styleOption.state & QStyle::State_Window; } QGraphicsLayoutStyleInfo::~QGraphicsLayoutStyleInfo() { - delete m_widget; } qreal QGraphicsLayoutStyleInfo::combinedLayoutSpacing(QLayoutPolicy::ControlTypes controls1, @@ -92,7 +91,7 @@ qreal QGraphicsLayoutStyleInfo::windowMargin(Qt::Orientation orientation) const const_cast(&m_styleOption), widget()); } -QWidget *QGraphicsLayoutStyleInfo::widget() const { return m_widget; } +QWidget *QGraphicsLayoutStyleInfo::widget() const { return m_widget.get(); } QStyle *QGraphicsLayoutStyleInfo::style() const { diff --git a/src/widgets/graphicsview/qgraphicslayoutstyleinfo_p.h b/src/widgets/graphicsview/qgraphicslayoutstyleinfo_p.h index 7886de432c..c3af9f4554 100644 --- a/src/widgets/graphicsview/qgraphicslayoutstyleinfo_p.h +++ b/src/widgets/graphicsview/qgraphicslayoutstyleinfo_p.h @@ -54,6 +54,8 @@ #include #include +#include + QT_REQUIRE_CONFIG(graphicsview); QT_BEGIN_NAMESPACE @@ -93,7 +95,7 @@ private: const QGraphicsLayoutPrivate *m_layout; mutable QStyle *m_style; QStyleOption m_styleOption; - QWidget *m_widget; + std::unique_ptr m_widget; }; QT_END_NAMESPACE From 6a28f6767754f427eb29a266f38252bdf23123c6 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Tue, 13 Nov 2018 15:25:25 +0100 Subject: [PATCH 0520/1650] Add tst_QOcsp auto-test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch introduces a private 'API' to enable server-side OCSP responses and implements a simple OCSP responder, tests OCSP status on a client side (the test is pretty basic, but for now should suffice). Change-Id: I4c6cacd4a1b949dd0ef5e6b59322fb0967d02120 Reviewed-by: Mårten Nordheim --- src/network/ssl/qsslcontext_openssl.cpp | 24 +- src/network/ssl/qsslsocket_openssl.cpp | 52 ++ .../ssl/qsslsocket_openssl11_symbols_p.h | 13 +- src/network/ssl/qsslsocket_openssl_p.h | 3 +- .../ssl/qsslsocket_openssl_symbols.cpp | 25 +- .../ssl/qsslsocket_openssl_symbols_p.h | 45 +- tests/auto/network/ssl/qocsp/certs/alice.crt | 24 + tests/auto/network/ssl/qocsp/certs/alice.key | 28 + tests/auto/network/ssl/qocsp/certs/ca1.crt | 24 + tests/auto/network/ssl/qocsp/certs/ca1.key | 28 + tests/auto/network/ssl/qocsp/certs/infbob.key | 28 + .../network/ssl/qocsp/certs/infbobchain.crt | 49 ++ .../network/ssl/qocsp/certs/ss1-private.key | 28 + tests/auto/network/ssl/qocsp/certs/ss1.crt | 25 + tests/auto/network/ssl/qocsp/qocsp.pro | 15 + tests/auto/network/ssl/qocsp/tst_qocsp.cpp | 823 ++++++++++++++++++ tests/auto/network/ssl/ssl.pro | 2 + 17 files changed, 1216 insertions(+), 20 deletions(-) create mode 100644 tests/auto/network/ssl/qocsp/certs/alice.crt create mode 100644 tests/auto/network/ssl/qocsp/certs/alice.key create mode 100644 tests/auto/network/ssl/qocsp/certs/ca1.crt create mode 100644 tests/auto/network/ssl/qocsp/certs/ca1.key create mode 100644 tests/auto/network/ssl/qocsp/certs/infbob.key create mode 100644 tests/auto/network/ssl/qocsp/certs/infbobchain.crt create mode 100644 tests/auto/network/ssl/qocsp/certs/ss1-private.key create mode 100644 tests/auto/network/ssl/qocsp/certs/ss1.crt create mode 100644 tests/auto/network/ssl/qocsp/qocsp.pro create mode 100644 tests/auto/network/ssl/qocsp/tst_qocsp.cpp diff --git a/src/network/ssl/qsslcontext_openssl.cpp b/src/network/ssl/qsslcontext_openssl.cpp index 35cca9f01a..e81e5582f4 100644 --- a/src/network/ssl/qsslcontext_openssl.cpp +++ b/src/network/ssl/qsslcontext_openssl.cpp @@ -243,12 +243,28 @@ QString QSslContext::errorString() const return errorStr; } +#if QT_CONFIG(ocsp) +extern "C" int qt_OCSP_status_server_callback(SSL *ssl, void *); // Defined in qsslsocket_openssl.cpp. +#endif // ocsp // static void QSslContext::applyBackendConfig(QSslContext *sslContext) { - if (sslContext->sslConfiguration.backendConfiguration().isEmpty()) + const QMap &conf = sslContext->sslConfiguration.backendConfiguration(); + if (conf.isEmpty()) return; +#if QT_CONFIG(ocsp) + auto ocspResponsePos = conf.find("Qt-OCSP-response"); + if (ocspResponsePos != conf.end()) { + // This is our private, undocumented configuration option, existing only for + // the purpose of testing OCSP status responses. We don't even check this + // callback was set. If no - the test must fail. + q_SSL_CTX_set_tlsext_status_cb(sslContext->ctx, qt_OCSP_status_server_callback); + if (conf.size() == 1) + return; + } +#endif // ocsp + #if OPENSSL_VERSION_NUMBER >= 0x10002000L if (QSslSocket::sslLibraryVersionNumber() >= 0x10002000L) { QSharedPointer cctx(q_SSL_CONF_CTX_new(), &q_SSL_CONF_CTX_free); @@ -256,8 +272,10 @@ void QSslContext::applyBackendConfig(QSslContext *sslContext) q_SSL_CONF_CTX_set_ssl_ctx(cctx.data(), sslContext->ctx); q_SSL_CONF_CTX_set_flags(cctx.data(), SSL_CONF_FLAG_FILE); - const auto &backendConfig = sslContext->sslConfiguration.backendConfiguration(); - for (auto i = backendConfig.constBegin(); i != backendConfig.constEnd(); ++i) { + for (auto i = conf.constBegin(); i != conf.constEnd(); ++i) { + if (i.key() == "Qt-OCSP-response") // This never goes to SSL_CONF_cmd(). + continue; + if (!i.value().canConvert(QMetaType::QByteArray)) { sslContext->errorCode = QSslError::UnspecifiedError; sslContext->errorStr = msgErrorSettingBackendConfig( diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 56764ebc7f..f6ee067c15 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -87,6 +87,8 @@ #include #endif +#include + #include QT_BEGIN_NAMESPACE @@ -135,6 +137,37 @@ static unsigned int q_ssl_psk_server_callback(SSL *ssl, return d->tlsPskServerCallback(identity, psk, max_psk_len); } #endif + +#if QT_CONFIG(ocsp) + +int qt_OCSP_status_server_callback(SSL *ssl, void *ocspRequest) +{ + Q_UNUSED(ocspRequest) + if (!ssl) + return SSL_TLSEXT_ERR_ALERT_FATAL; + + auto d = static_cast(q_SSL_get_ex_data(ssl, QSslSocketBackendPrivate::s_indexForSSLExtraData)); + if (!d) + return SSL_TLSEXT_ERR_ALERT_FATAL; + + Q_ASSERT(d->mode == QSslSocket::SslServerMode); + const QByteArray &response = d->ocspResponseDer; + Q_ASSERT(response.size()); + + unsigned char *derCopy = static_cast(q_OPENSSL_malloc(size_t(response.size()))); + if (!derCopy) + return SSL_TLSEXT_ERR_ALERT_FATAL; + + std::copy(response.data(), response.data() + response.size(), derCopy); + // We don't check the return value: internally OpenSSL simply assignes the + // pointer (it assumes it now owns this memory btw!) and the length. + q_SSL_set_tlsext_status_ocsp_resp(ssl, derCopy, response.size()); + + return SSL_TLSEXT_ERR_OK; +} + +#endif // ocsp + } // extern "C" QSslSocketBackendPrivate::QSslSocketBackendPrivate() @@ -507,6 +540,25 @@ bool QSslSocketBackendPrivate::initSslContext() return false; } } + + ocspResponseDer.clear(); + auto responsePos = configuration.backendConfig.find("Qt-OCSP-response"); + if (responsePos != configuration.backendConfig.end()) { + // This is our private, undocumented 'API' we use for the auto-testing of + // OCSP-stapling. It must be a der-encoded OCSP response, presumably set + // by tst_QOcsp. + const QVariant data(responsePos.value()); + if (data.canConvert()) + ocspResponseDer = data.toByteArray(); + } + + if (ocspResponseDer.size()) { + if (mode != QSslSocket::SslServerMode) { + setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError, + QSslSocket::tr("Client-side sockets do not send OCSP responses")); + return false; + } + } #endif // ocsp return true; diff --git a/src/network/ssl/qsslsocket_openssl11_symbols_p.h b/src/network/ssl/qsslsocket_openssl11_symbols_p.h index b94b05b765..a44d00a830 100644 --- a/src/network/ssl/qsslsocket_openssl11_symbols_p.h +++ b/src/network/ssl/qsslsocket_openssl11_symbols_p.h @@ -84,12 +84,12 @@ int q_DSA_bits(DSA *a); int q_EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *c); int q_EVP_PKEY_base_id(EVP_PKEY *a); int q_RSA_bits(RSA *a); -int q_OPENSSL_sk_num(OPENSSL_STACK *a); -void q_OPENSSL_sk_pop_free(OPENSSL_STACK *a, void (*b)(void *)); -OPENSSL_STACK *q_OPENSSL_sk_new_null(); -void q_OPENSSL_sk_push(OPENSSL_STACK *st, void *data); -void q_OPENSSL_sk_free(OPENSSL_STACK *a); -void * q_OPENSSL_sk_value(OPENSSL_STACK *a, int b); +Q_AUTOTEST_EXPORT int q_OPENSSL_sk_num(OPENSSL_STACK *a); +Q_AUTOTEST_EXPORT void q_OPENSSL_sk_pop_free(OPENSSL_STACK *a, void (*b)(void *)); +Q_AUTOTEST_EXPORT OPENSSL_STACK *q_OPENSSL_sk_new_null(); +Q_AUTOTEST_EXPORT void q_OPENSSL_sk_push(OPENSSL_STACK *st, void *data); +Q_AUTOTEST_EXPORT void q_OPENSSL_sk_free(OPENSSL_STACK *a); +Q_AUTOTEST_EXPORT void * q_OPENSSL_sk_value(OPENSSL_STACK *a, int b); int q_SSL_session_reused(SSL *a); unsigned long q_SSL_CTX_set_options(SSL_CTX *ctx, unsigned long op); int q_OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings); @@ -102,6 +102,7 @@ const SSL_METHOD *q_TLS_server_method(); ASN1_TIME *q_X509_getm_notBefore(X509 *a); ASN1_TIME *q_X509_getm_notAfter(X509 *a); +Q_AUTOTEST_EXPORT void q_X509_up_ref(X509 *a); long q_X509_get_version(X509 *a); EVP_PKEY *q_X509_get_pubkey(X509 *a); void q_X509_STORE_set_verify_cb(X509_STORE *ctx, X509_STORE_CTX_verify_cb verify_cb); diff --git a/src/network/ssl/qsslsocket_openssl_p.h b/src/network/ssl/qsslsocket_openssl_p.h index 6396b44808..c23234e291 100644 --- a/src/network/ssl/qsslsocket_openssl_p.h +++ b/src/network/ssl/qsslsocket_openssl_p.h @@ -157,12 +157,13 @@ public: #if QT_CONFIG(ocsp) bool checkOcspStatus(); +#endif // This decription will go to setErrorAndEmit(SslHandshakeError, ocspErrorDescription) QString ocspErrorDescription; // These will go to sslErrors() QVector ocspErrors; -#endif + QByteArray ocspResponseDer; Q_AUTOTEST_EXPORT static long setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions); static QSslCipher QSslCipher_from_SSL_CIPHER(const SSL_CIPHER *cipher); diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index 3688e8ffd3..f9e8f01222 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -172,6 +172,7 @@ DEFINEFUNC2(unsigned long, SSL_set_options, SSL *ssl, ssl, unsigned long op, op, DEFINEFUNC(const SSL_METHOD *, TLS_method, DUMMYARG, DUMMYARG, return nullptr, return) DEFINEFUNC(const SSL_METHOD *, TLS_client_method, DUMMYARG, DUMMYARG, return nullptr, return) DEFINEFUNC(const SSL_METHOD *, TLS_server_method, DUMMYARG, DUMMYARG, return nullptr, return) +DEFINEFUNC(void, X509_up_ref, X509 *a, a, return, DUMMYARG) DEFINEFUNC(ASN1_TIME *, X509_getm_notBefore, X509 *a, a, return nullptr, return) DEFINEFUNC(ASN1_TIME *, X509_getm_notAfter, X509 *a, a, return nullptr, return) DEFINEFUNC(long, X509_get_version, X509 *a, a, return -1, return) @@ -217,8 +218,15 @@ DEFINEFUNC(void, OCSP_CERTID_free, OCSP_CERTID *cid, cid, return, DUMMYARG) DEFINEFUNC5(int, OCSP_id_get0_info, ASN1_OCTET_STRING **piNameHash, piNameHash, ASN1_OBJECT **pmd, pmd, ASN1_OCTET_STRING **piKeyHash, piKeyHash, ASN1_INTEGER **pserial, pserial, OCSP_CERTID *cid, cid, return 0, return) +DEFINEFUNC2(OCSP_RESPONSE *, OCSP_response_create, int status, status, OCSP_BASICRESP *bs, bs, return nullptr, return) DEFINEFUNC(const STACK_OF(X509) *, OCSP_resp_get0_certs, const OCSP_BASICRESP *bs, bs, return nullptr, return) DEFINEFUNC2(int, OCSP_id_cmp, OCSP_CERTID *a, a, OCSP_CERTID *b, b, return -1, return) +DEFINEFUNC7(OCSP_SINGLERESP *, OCSP_basic_add1_status, OCSP_BASICRESP *r, r, OCSP_CERTID *c, c, int s, s, + int re, re, ASN1_TIME *rt, rt, ASN1_TIME *t, t, ASN1_TIME *n, n, return nullptr, return) +DEFINEFUNC(OCSP_BASICRESP *, OCSP_BASICRESP_new, DUMMYARG, DUMMYARG, return nullptr, return) +DEFINEFUNC2(int, i2d_OCSP_RESPONSE, OCSP_RESPONSE *r, r, unsigned char **ppout, ppout, return 0, return) +DEFINEFUNC6(int, OCSP_basic_sign, OCSP_BASICRESP *br, br, X509 *signer, signer, EVP_PKEY *key, key, + const EVP_MD *dg, dg, STACK_OF(X509) *cs, cs, unsigned long flags, flags, return 0, return) #endif // ocsp DEFINEFUNC2(void, BIO_set_data, BIO *a, a, void *ptr, ptr, return, DUMMYARG) @@ -462,6 +470,7 @@ DEFINEFUNC(SSL_CTX *, SSL_CTX_new, const SSL_METHOD *a, a, return nullptr, retur DEFINEFUNC(SSL_CTX *, SSL_CTX_new, SSL_METHOD *a, a, return nullptr, return) #endif DEFINEFUNC2(int, SSL_CTX_set_cipher_list, SSL_CTX *a, a, const char *b, b, return -1, return) +DEFINEFUNC3(long, SSL_CTX_callback_ctrl, SSL_CTX *ctx, ctx, int dst, dst, GenericCallbackType cb, cb, return 0, return) DEFINEFUNC(int, SSL_CTX_set_default_verify_paths, SSL_CTX *a, a, return -1, return) DEFINEFUNC3(void, SSL_CTX_set_verify, SSL_CTX *a, a, int b, b, int (*c)(int, X509_STORE_CTX *), c, return, DUMMYARG) DEFINEFUNC2(void, SSL_CTX_set_verify_depth, SSL_CTX *a, a, int b, b, return, DUMMYARG) @@ -527,6 +536,9 @@ DEFINEFUNC(X509 *, X509_dup, X509 *a, a, return nullptr, return) DEFINEFUNC2(void, X509_print, BIO *a, a, X509 *b, b, return, DUMMYARG); DEFINEFUNC(ASN1_OBJECT *, X509_EXTENSION_get_object, X509_EXTENSION *a, a, return nullptr, return) DEFINEFUNC(void, X509_free, X509 *a, a, return, DUMMYARG) +//Q_AUTOTEST_EXPORT ASN1_TIME *q_X509_gmtime_adj(ASN1_TIME *s, long adj); +DEFINEFUNC2(ASN1_TIME *, X509_gmtime_adj, ASN1_TIME *s, s, long adj, adj, return nullptr, return) +DEFINEFUNC(void, ASN1_TIME_free, ASN1_TIME *t, t, return, DUMMYARG) DEFINEFUNC2(X509_EXTENSION *, X509_get_ext, X509 *a, a, int b, b, return nullptr, return) DEFINEFUNC(int, X509_get_ext_count, X509 *a, a, return 0, return) DEFINEFUNC4(void *, X509_get_ext_d2i, X509 *a, a, int b, b, int *c, c, int *d, d, return nullptr, return) @@ -606,6 +618,7 @@ DEFINEFUNC2(void, BIO_clear_flags, BIO *b, b, int flags, flags, return, DUMMYARG DEFINEFUNC2(void *, BIO_get_ex_data, BIO *b, b, int idx, idx, return nullptr, return) DEFINEFUNC3(int, BIO_set_ex_data, BIO *b, b, int idx, idx, void *data, data, return -1, return) +DEFINEFUNC3(void *, CRYPTO_malloc, size_t num, num, const char *file, file, int line, line, return nullptr, return) DEFINEFUNC(DH *, DH_new, DUMMYARG, DUMMYARG, return nullptr, return) DEFINEFUNC(void, DH_free, DH *dh, dh, return, DUMMYARG) DEFINEFUNC3(DH *, d2i_DHparams, DH**a, a, const unsigned char **pp, pp, long length, length, return nullptr, return) @@ -1010,6 +1023,7 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(TLS_method) RESOLVEFUNC(TLS_client_method) RESOLVEFUNC(TLS_server_method) + RESOLVEFUNC(X509_up_ref) RESOLVEFUNC(X509_STORE_CTX_get0_chain) RESOLVEFUNC(X509_getm_notBefore) RESOLVEFUNC(X509_getm_notAfter) @@ -1059,7 +1073,12 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(OCSP_check_validity) RESOLVEFUNC(OCSP_cert_to_id) RESOLVEFUNC(OCSP_id_get0_info) - RESOLVEFUNC(OCSP_resp_get0_certs); + RESOLVEFUNC(OCSP_resp_get0_certs) + RESOLVEFUNC(OCSP_basic_sign) + RESOLVEFUNC(OCSP_response_create) + RESOLVEFUNC(i2d_OCSP_RESPONSE) + RESOLVEFUNC(OCSP_basic_add1_status) + RESOLVEFUNC(OCSP_BASICRESP_new) RESOLVEFUNC(OCSP_CERTID_free) RESOLVEFUNC(OCSP_cert_to_id) RESOLVEFUNC(OCSP_id_cmp) @@ -1281,6 +1300,7 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(SSL_CTX_free) RESOLVEFUNC(SSL_CTX_new) RESOLVEFUNC(SSL_CTX_set_cipher_list) + RESOLVEFUNC(SSL_CTX_callback_ctrl) RESOLVEFUNC(SSL_CTX_set_default_verify_paths) RESOLVEFUNC(SSL_CTX_set_verify) RESOLVEFUNC(SSL_CTX_set_verify_depth) @@ -1358,6 +1378,8 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(X509_digest) RESOLVEFUNC(X509_EXTENSION_get_object) RESOLVEFUNC(X509_free) + RESOLVEFUNC(X509_gmtime_adj) + RESOLVEFUNC(ASN1_TIME_free) RESOLVEFUNC(X509_get_ext) RESOLVEFUNC(X509_get_ext_count) RESOLVEFUNC(X509_get_ext_d2i) @@ -1395,6 +1417,7 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(DTLS_server_method) RESOLVEFUNC(DTLS_client_method) #endif // dtls + RESOLVEFUNC(CRYPTO_malloc) RESOLVEFUNC(DH_new) RESOLVEFUNC(DH_free) RESOLVEFUNC(d2i_DHparams) diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h index b5aac1c2ae..27e317ab1f 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols_p.h +++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h @@ -281,7 +281,7 @@ const EVP_CIPHER *q_EVP_des_ede3_cbc(); #ifndef OPENSSL_NO_RC2 const EVP_CIPHER *q_EVP_rc2_cbc(); #endif -const EVP_MD *q_EVP_sha1(); +Q_AUTOTEST_EXPORT const EVP_MD *q_EVP_sha1(); int q_EVP_PKEY_assign(EVP_PKEY *a, int b, char *c); Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_RSA(EVP_PKEY *a, RSA *b); int q_EVP_PKEY_set1_DSA(EVP_PKEY *a, DSA *b); @@ -289,7 +289,7 @@ int q_EVP_PKEY_set1_DH(EVP_PKEY *a, DH *b); #ifndef OPENSSL_NO_EC int q_EVP_PKEY_set1_EC_KEY(EVP_PKEY *a, EC_KEY *b); #endif -void q_EVP_PKEY_free(EVP_PKEY *a); +Q_AUTOTEST_EXPORT void q_EVP_PKEY_free(EVP_PKEY *a); RSA *q_EVP_PKEY_get1_RSA(EVP_PKEY *a); DSA *q_EVP_PKEY_get1_DSA(EVP_PKEY *a); DH *q_EVP_PKEY_get1_DH(EVP_PKEY *a); @@ -366,6 +366,10 @@ int q_SSL_CTX_set_cipher_list(SSL_CTX *a, const char *b); int q_SSL_CTX_set_default_verify_paths(SSL_CTX *a); void q_SSL_CTX_set_verify(SSL_CTX *a, int b, int (*c)(int, X509_STORE_CTX *)); void q_SSL_CTX_set_verify_depth(SSL_CTX *a, int b); +extern "C" { +typedef void (*GenericCallbackType)(); +} +long q_SSL_CTX_callback_ctrl(SSL_CTX *, int, GenericCallbackType); int q_SSL_CTX_use_certificate(SSL_CTX *a, X509 *b); int q_SSL_CTX_use_certificate_file(SSL_CTX *a, const char *b, int c); int q_SSL_CTX_use_PrivateKey(SSL_CTX *a, EVP_PKEY *b); @@ -428,7 +432,9 @@ X509 *q_X509_dup(X509 *a); void q_X509_print(BIO *a, X509*b); int q_X509_digest(const X509 *x509, const EVP_MD *type, unsigned char *md, unsigned int *len); ASN1_OBJECT *q_X509_EXTENSION_get_object(X509_EXTENSION *a); -void q_X509_free(X509 *a); +Q_AUTOTEST_EXPORT void q_X509_free(X509 *a); +Q_AUTOTEST_EXPORT ASN1_TIME *q_X509_gmtime_adj(ASN1_TIME *s, long adj); +Q_AUTOTEST_EXPORT void q_ASN1_TIME_free(ASN1_TIME *t); X509_EXTENSION *q_X509_get_ext(X509 *a, int b); int q_X509_get_ext_count(X509 *a); void *q_X509_get_ext_d2i(X509 *a, int b, int *c, int *d); @@ -587,17 +593,26 @@ QDateTime q_getTimeFromASN1(const ASN1_TIME *aTime); #ifndef OPENSSL_NO_TLSEXT -#define q_SSL_set_tlsext_status_type(ssl, type) q_SSL_ctrl((ssl), SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE, (type), nullptr) +#define q_SSL_set_tlsext_status_type(ssl, type) \ + q_SSL_ctrl((ssl), SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE, (type), nullptr) #endif // OPENSSL_NO_TLSEXT #if QT_CONFIG(ocsp) OCSP_RESPONSE *q_d2i_OCSP_RESPONSE(OCSP_RESPONSE **a, const unsigned char **in, long len); -void q_OCSP_RESPONSE_free(OCSP_RESPONSE *rs); +Q_AUTOTEST_EXPORT int q_i2d_OCSP_RESPONSE(OCSP_RESPONSE *r, unsigned char **ppout); +Q_AUTOTEST_EXPORT OCSP_RESPONSE *q_OCSP_response_create(int status, OCSP_BASICRESP *bs); +Q_AUTOTEST_EXPORT void q_OCSP_RESPONSE_free(OCSP_RESPONSE *rs); int q_OCSP_response_status(OCSP_RESPONSE *resp); OCSP_BASICRESP *q_OCSP_response_get1_basic(OCSP_RESPONSE *resp); -void q_OCSP_BASICRESP_free(OCSP_BASICRESP *bs); +Q_AUTOTEST_EXPORT OCSP_SINGLERESP *q_OCSP_basic_add1_status(OCSP_BASICRESP *rsp, OCSP_CERTID *cid, + int status, int reason, ASN1_TIME *revtime, + ASN1_TIME *thisupd, ASN1_TIME *nextupd); +Q_AUTOTEST_EXPORT int q_OCSP_basic_sign(OCSP_BASICRESP *brsp, X509 *signer, EVP_PKEY *key, const EVP_MD *dgst, + STACK_OF(X509) *certs, unsigned long flags); +Q_AUTOTEST_EXPORT OCSP_BASICRESP *q_OCSP_BASICRESP_new(); +Q_AUTOTEST_EXPORT void q_OCSP_BASICRESP_free(OCSP_BASICRESP *bs); int q_OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, X509_STORE *st, unsigned long flags); int q_OCSP_resp_count(OCSP_BASICRESP *bs); OCSP_SINGLERESP *q_OCSP_resp_get0(OCSP_BASICRESP *bs, int idx); @@ -606,15 +621,27 @@ int q_OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, ASN1_GENERAL int q_OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, ASN1_GENERALIZEDTIME *nextupd, long nsec, long maxsec); int q_OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd, ASN1_OCTET_STRING **pikeyHash, ASN1_INTEGER **pserial, OCSP_CERTID *cid); + const STACK_OF(X509) *q_OCSP_resp_get0_certs(const OCSP_BASICRESP *bs); -OCSP_CERTID *q_OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer); -void q_OCSP_CERTID_free(OCSP_CERTID *cid); +Q_AUTOTEST_EXPORT OCSP_CERTID *q_OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer); +Q_AUTOTEST_EXPORT void q_OCSP_CERTID_free(OCSP_CERTID *cid); int q_OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b); -#define q_SSL_get_tlsext_status_ocsp_resp(ssl, arg) q_SSL_ctrl(ssl, SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP, 0, arg) +#define q_SSL_get_tlsext_status_ocsp_resp(ssl, arg) \ + q_SSL_ctrl(ssl, SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP, 0, arg) + +#define q_SSL_CTX_set_tlsext_status_cb(ssl, cb) \ + q_SSL_CTX_callback_ctrl(ssl, SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB, GenericCallbackType(cb)) + +# define q_SSL_set_tlsext_status_ocsp_resp(ssl, arg, arglen) \ + q_SSL_ctrl(ssl, SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP, arglen, arg) #endif // ocsp + +void *q_CRYPTO_malloc(size_t num, const char *file, int line); +#define q_OPENSSL_malloc(num) q_CRYPTO_malloc(num, "", 0) + QT_END_NAMESPACE #endif diff --git a/tests/auto/network/ssl/qocsp/certs/alice.crt b/tests/auto/network/ssl/qocsp/certs/alice.crt new file mode 100644 index 0000000000..02df86a517 --- /dev/null +++ b/tests/auto/network/ssl/qocsp/certs/alice.crt @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEGDCCAwCgAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBjjELMAkGA1UEBhMCTk8x +DTALBgNVBAgMBE9zbG8xEjAQBgNVBAcMCU9zbG8gQ2l0eTETMBEGA1UECgwKVGhl +IFF0IENBMTENMAsGA1UECwwEUVRDTjERMA8GA1UEAwwIY2ExcXQuaW8xJTAjBgkq +hkiG9w0BCQEWFnRpbXVyLnBvY2hlcHRzb3ZAcXQuaW8wHhcNMTgxMTIyMTEwNjE4 +WhcNMjgxMTE5MTEwNjE4WjCBkjELMAkGA1UEBhMCTk8xDTALBgNVBAgMBE9zbG8x +EjAQBgNVBAcMCU9zbG8gQ2l0eTEdMBsGA1UECgwUVGhlIEZhbW91cyBBbGljZSBM +dGQxDTALBgNVBAsMBEdPQUExEjAQBgNVBAMMCWFsaWNlLm9yZzEeMBwGCSqGSIb3 +DQEJARYPYWxpY2VAYWxpY2Uub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAtuGDR9oIEkK57xlxq/xc3u7B1ni4pdoyhf9r+pkgmu591qp2kl3Xcq3W +Ve5Z553orAUCAExPlKfFV+CYYAedSgsDYlKk8DN+f/n+hkG6Wl2qyFzHgl+mvPwa +eDqdVMIcDHGhSljALi9AqsN4lbrUhSxiyuPhAwl82WB0EIucmBs1NxSSZgFPRBLG +Uzy9WvtQFq1qtn795PVIUsNg68qZQ9BvRduOQAr3bg3anoYqytthWnzLWKri2QR4 +Z4Y0mvcbT/PZwhtcFZzDXG3Hvc7k3AroAbWoSghMEgok9TW9grKYkW2d5cpQTP+l +ptkB6yZ06MY9/uCdYzhm8eu2RgVndwIDAQABo3sweTAJBgNVHRMEAjAAMCwGCWCG +SAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4E +FgQUQz2PuE4VuqHtZYTvVLr4+0IuHTUwHwYDVR0jBBgwFoAUeBcnAkU7sTqm7i2Q +vTxwgr0nQ0QwDQYJKoZIhvcNAQELBQADggEBABGGmo1vUAXKQm9kowvUtjDpEIIY +TpT+KqiUBOgJg5fGn6a63vBn5GMA6eT948ywi9ZU2M9dIXJCM+bdqjXeOtt4bBPZ +xz6DcBPW9CoTR4CV1muNa95WIXzAHatq3XYG041ddMf41WG7QIdQsojBYEG0IYlv +PQx+B+m2cu7A04aI2tCS8aUh7Xc9wRilJ+h/FlYFFQzgyEKsd7CFgkyxG/sLyFNH +skYYk/DLlmaWa+YScHYB5kAk8StoETeMI2LLs7rgJmchi8eAxjLroYDUhQclUjqz +vlNM+4GvcF5RluyuEXFOZVdmQahkXcyu0Q3yxvsBbnDglmbb2YHPl/blB7w= +-----END CERTIFICATE----- diff --git a/tests/auto/network/ssl/qocsp/certs/alice.key b/tests/auto/network/ssl/qocsp/certs/alice.key new file mode 100644 index 0000000000..6f2666ebde --- /dev/null +++ b/tests/auto/network/ssl/qocsp/certs/alice.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC24YNH2ggSQrnv +GXGr/Fze7sHWeLil2jKF/2v6mSCa7n3WqnaSXddyrdZV7lnnneisBQIATE+Up8VX +4JhgB51KCwNiUqTwM35/+f6GQbpaXarIXMeCX6a8/Bp4Op1UwhwMcaFKWMAuL0Cq +w3iVutSFLGLK4+EDCXzZYHQQi5yYGzU3FJJmAU9EEsZTPL1a+1AWrWq2fv3k9UhS +w2DryplD0G9F245ACvduDdqehirK22FafMtYquLZBHhnhjSa9xtP89nCG1wVnMNc +bce9zuTcCugBtahKCEwSCiT1Nb2CspiRbZ3lylBM/6Wm2QHrJnToxj3+4J1jOGbx +67ZGBWd3AgMBAAECggEADbzU+sHDF3QRuYdExbGYXFq9DtpUrIi+gNhWCSYVj+3Y +YBa//3CzLXcngZ78++wdvUZHBzS0SatspJRHffc0doprP6iLoUuM9hoWZ4lqcT1W +BeUKS53ZzZp2do+Yn/RQ3RJwFkCidxWvmuRCG6VEL5jM9wa1MWA2E7IuJcwHAFny +WIByosje5Qrd7eXDuVoqr1hjJ2UxIjIJ8Zgg3EE9wVUyJE3PU1HLz2AefonYRwbL +XlzNgnj0c9Ti9ejfyon+jTnpslLKtPal2kxyGoKPAngadAhCzqSaCWggACm7R8Ge +pZ0Y0pV7QReEgjfFd4D3qOqLRQZVJOMDb3vJu2/rsQKBgQDfKjfSpUweBM9li7GS +xXbDpC3Y8zQ2VY+2SvgYoYiYU/Y6YenxhKM1XDbWZxhxS8GVfCUAESFDOTZcMvdi +QEbG1uEmuCn1ksvrC2y54rtd8WDppcS0vJxCrU4nZG0v9IjVKp67B8EpBpAQeNb1 +tR6ByT2fLJu5+WU2S7OxqX7uLwKBgQDRyfKvrCQgdJOQlJlHOv1y1hN8WY51A8P/ +JbDXoun3PCPd+JczvFXCUh3ZLXqUEAX2qDOBD1pBM62EN6/A9ukO4mcMd8uYIet6 +nR4nVqXUjWuzXe6eo913lTDQrIOGWpViTc8fnvFlwBPfwzxbZNx38HZbw0L0nT7d +8TE/JxLROQKBgQC4Kzo4b8vadjPGZLueGbICkQp5IXR0ZrYcRdBrW1vEAn6Q/d84 +PzMFxV1IIXrNfSx8NiC+5mQh+yQ+gJ0iC1OdoxXag1+1V3lMN3h6C4B/bcWB7Rjh +40m9yRJXdgyZ59/Is8ydIzAosE7SGTelPNy5VR+yrfiySPxbC6x3MR8cZwKBgQCq +PVTg1bIjXDZ7NvsDYI1XaP07BXmi30FnhXByLFPsOzNn51jbtNNq8zQhjtRP3ojY +VjolWw4EpykBiCbpUfRiDbtN1NC0TaJHR8S2a4v6ZiCl123R8mu/pKOOUtAQcOWU +dkvD/zkpNqtqA4axK7H06n9Bi7yDwC7J7/Xkp5KPkQKBgFDprXrXg4zvIsxbXYZ3 +2bCaxyhBXNKcGwtWbbLfJcOwHJPns/abGkYIJ0NbMZX1LwTDfQWmC+8YKKvIlbKG +S2uk5H4qzupR4XN6YJ7SCHlGv2z0vxVjV7aWc1TME2iZQoBuO1urxPZwHd/euruo +kluWh1KV5XnWjBSYjZpiXxWl +-----END PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qocsp/certs/ca1.crt b/tests/auto/network/ssl/qocsp/certs/ca1.crt new file mode 100644 index 0000000000..b5ae194fab --- /dev/null +++ b/tests/auto/network/ssl/qocsp/certs/ca1.crt @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID9DCCAtygAwIBAgIJAMQbE3657KDYMA0GCSqGSIb3DQEBCwUAMIGOMQswCQYD +VQQGEwJOTzENMAsGA1UECAwET3NsbzESMBAGA1UEBwwJT3NsbyBDaXR5MRMwEQYD +VQQKDApUaGUgUXQgQ0ExMQ0wCwYDVQQLDARRVENOMREwDwYDVQQDDAhjYTFxdC5p +bzElMCMGCSqGSIb3DQEJARYWdGltdXIucG9jaGVwdHNvdkBxdC5pbzAeFw0xODEx +MjIxMDIxMTNaFw0yODExMTkxMDIxMTNaMIGOMQswCQYDVQQGEwJOTzENMAsGA1UE +CAwET3NsbzESMBAGA1UEBwwJT3NsbyBDaXR5MRMwEQYDVQQKDApUaGUgUXQgQ0Ex +MQ0wCwYDVQQLDARRVENOMREwDwYDVQQDDAhjYTFxdC5pbzElMCMGCSqGSIb3DQEJ +ARYWdGltdXIucG9jaGVwdHNvdkBxdC5pbzCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAOCs3AV7sDKHJUJcm7a0OqnShIvoB1qv6UcOmlBmUzGl5GzX90Jz +7jYJoOPjxjNyRxMOsOReB1ZcSuIAjkdAEfFMaVe6j7qKTJ5ycTVY/fVoxyxsSNuI +xOJ6RCEjLHcxONEbkN/xI8LMdVko3m4P10r5GxwrgyPvpa87Yq5+XJ1BPWJyKbD7 +Tqpn3dvZUj0/POsMUTT7Q7VXOfDlZj58XWAC6ECTqJauhGFMhiwgqOn2Qo1W0QjV +DkGqRTdgIAM6Rv2cSRxgnflwW5QZ8kWUV81h/yx4cck/D9TcVxjr3Pvy6aJ/U41u +d4XJQgwCj4LJi4msw1S0CvZWmz+2BKxcbRsCAwEAAaNTMFEwHQYDVR0OBBYEFHgX +JwJFO7E6pu4tkL08cIK9J0NEMB8GA1UdIwQYMBaAFHgXJwJFO7E6pu4tkL08cIK9 +J0NEMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADp1kqDRcyVG +BdMge+Il10IjbpzzSjAoZiqiw69V99LiHW9ePbxG4AmliE6Za60GE5PCXOLjJh/5 +efgnIbybbyIOIT9iK4TXWLw2XW+rMY51c0RAxp2h/sc+5CZ0F0I811F5VUHXg2qR +U7C2zbzqAimN8TBm6FRe7NFQfqLCrsuFJjSc3obrqKQcpvRwxMk6NpkdoemzqLmY +lrBrTaeVbZ4ix3srVPvXRm9TdiC+JuuFmvulMfe+/wwnhb+dwT3JUC+EIq/Uf5Wb +g8lvB4ntitL8NLQ2hFGqYuoFNIGs6tRN71ohk+/ONqe9wJhcI9QAruPOvsg+8J0H +uGooX7PUNHg= +-----END CERTIFICATE----- diff --git a/tests/auto/network/ssl/qocsp/certs/ca1.key b/tests/auto/network/ssl/qocsp/certs/ca1.key new file mode 100644 index 0000000000..4ee080f706 --- /dev/null +++ b/tests/auto/network/ssl/qocsp/certs/ca1.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDgrNwFe7AyhyVC +XJu2tDqp0oSL6Adar+lHDppQZlMxpeRs1/dCc+42CaDj48YzckcTDrDkXgdWXEri +AI5HQBHxTGlXuo+6ikyecnE1WP31aMcsbEjbiMTiekQhIyx3MTjRG5Df8SPCzHVZ +KN5uD9dK+RscK4Mj76WvO2KuflydQT1icimw+06qZ93b2VI9PzzrDFE0+0O1Vznw +5WY+fF1gAuhAk6iWroRhTIYsIKjp9kKNVtEI1Q5BqkU3YCADOkb9nEkcYJ35cFuU +GfJFlFfNYf8seHHJPw/U3FcY69z78umif1ONbneFyUIMAo+CyYuJrMNUtAr2Vps/ +tgSsXG0bAgMBAAECggEBAL1RCwjXw42gEUZM8KzQS0pD6IpXVrMU3ZWReXhb8Kg6 +KDOK+3+UXlpMXLUKfj1lgvxM+cNEdBxSIoszerARDc1s3KseufOui4dL2ZbhSQVc +Z9BH4lCSe4x3CCeAEvzQjhatirMY51BCpnMdm+fUE07KfwyKobNLQSpZ+Pod4f5i +oQbOiZYfRfU2quaWIsVb/a5IiUD0gG0KS9O5wX6VigVeFRpOPHT4YCQ1qds4HqQq +PKQtkLq0mo6beXCfXWrJ5Nc0QOIFlgSAHkeRR7zLK8MlaerwZ5YdeJIWuPM9l9H+ +34FVkHle1rPN6dJf7EPwWxn1PceFe3QYn1GHoiMmXfkCgYEA/U6iQypbLEKLmLbt +XTvhV1FVDQM42BX+ATNQ8Wro0ybdyzM+d4271uAUGTF1Zvxndv22p+JOmldWveAR +0iVK4mvrs25ACg27Bz3LiUaQB2OyYrj9M7TLgQ47gYEhwgnsSniFyrMcptNyIfW5 +GoB1N00EKiCvHyWo5LK6kRZt5QcCgYEA4xBOC/Otc9lTp24iSVA8Y7XJ+nlypFtc +pehf262jH11wEkWskmc9aP/kpxt9fUrDxf3YIOqITR4mMNn184P1WywHAQF7Adfd +3r5YBMVaanuaMsSuAZOJGyvuk2BE6328IKdE+3emndzXuQdDf0X2TUznwdKe9AzZ +qadCBLfUpk0CgYAgDKbzIJTQkMrg06RMu5rTVXMRZmr2zDGLLVb8dK5oqO4/G4i3 +z7MIiOmCFoPoN99PauKFc1jGpm5PL96RXC6RX14/IZ/wpbQYQnVSNR9cD/0uCIHg +3OsytP5KcHA5ANBoy78B2o+xe+dg7JozBDXQfWodem0t37Hy3bpFSTU2WQKBgETY +qcFn9hydNYcblpvCDz1wXjhq4H7DENlhFseF42LcMuHnbEbLtMwEYrDkXe1CYQ/E +QubgFcnELXI8dB2M0jT9qXX9m+1YJXanIgr4R8zngz6HcfcaY8TwUhsvYlZAvmzs +KrdQdR2CW4pHkIijjuWrPs3+7aEz0D9nblX94yU1AoGATVCfQOwmEMFHg33luMMt +0lTOHsar6g1O5vz0ZPZ1NjJF9Qe3+T7B4n4gq9pLwfi7Ohoa4CDmt0nKmy56dBha +5LM8mzw+PaH9a3pP93caS6k/X68TLOp7fwvnzP6HTjtis2sdYzVma6ghEF0zRdQr +6nWMI6Kx2kFaNdzKSHzxP5A= +-----END PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qocsp/certs/infbob.key b/tests/auto/network/ssl/qocsp/certs/infbob.key new file mode 100644 index 0000000000..7878339151 --- /dev/null +++ b/tests/auto/network/ssl/qocsp/certs/infbob.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDkF2BuPlkQa3Ox +JxnbQ+gy1mAxaGGzfnmGocraxVSKSssX3zSkeIrWB1kW3diOtIZ1jovYftHGsqoB +F5k6fN9dr37mFIZnilF6Bq0seYjNUl6I0d7Cf3NJSf7TG5+P+dAyNLN8aXILctY8 +krlSe4ysb++9xgawt2DYL3I0LBd+W27hd2BlfcmB4g2X3zOasjZM8F5HSBxF5e7f +fVaUmCC8S4jdXUQEbUNFk6HufDwDhP1gMtoGKHusWOdI5O6cQAfUUmRLSfi/jWoe +KLPafbj7KIcA8+YojOvub2guNpO42h9fc83/gCkkBJhwXNdIQjRUnz6Lu05kDTG9 +X28gbX9TAgMBAAECggEBAN9xCxVUXJmaOb6ciFblIi3TFm6wS62zw0chbgB8eQH0 +nRoonYBVWeSrVBnzf7bkoCe/Wb3fFo+o7KOfQ4spUwOK7SxlhPkfZgu9SJ4d/Obu +vw8XUTqF8iEkrM6P6/L2DX9xYzcIcSFIARlbvtJPmBJAocHtoRYyvltpt13mp6kt +/LVYR4qFAWRpPR6rnjlXEjfrE9taHWgIJEjwMj+IcTjnGiS1rX1T/JNhjRxsRJwU +qxqhYmeenNymyUJxS2B806EcG3UAJu63dK61VXN1dtPhS3FqjeR//GRlmy14n7RW +ZQAuT9dPB/WzUZVzEcOgTwe/+XsPTSfz7gpaoffgMJECgYEA/43xZRi48Dfp3tdq +qwwLf6Ya9pB2zb3XE8MUQhxsrygzL5ngZhmr2m0LgGCf5fXa983G6wzA6sOdpvve +jFAlBZYbWaYnvog9QIFcTj0S6PahGTBaR7PSNzK0UzoHYexYVCkyzQl1O2hktazd +Cankh/6IlAFkKbUSDqAwc07jNCkCgYEA5H0tNXpcDN6JTgKNe8YHM0GjZB+qGEoL +7YZbFlANjO9pOPY6JMQ3+DbOoruIH97CIyVYokuH0qRAfjm5LNiVYECFVFZRnGFb +BNPOPAnPJPISDF66zjW0KLMYCykJAHQ4SpHUPcJ6JnfBr76s/xSbNI9qnhpy3QYI +ATkqOrP25xsCgYEAy3pjmJGEv5BloM942VSv2yWRFn2UeuELXWrYuIMVbqndh6tH +50PNeA+XNtK4vktx3Bl2pzTybnrvDkRBwQsXT0lj4Y/Q2X509uWJb6plYiTtxLah +S7I8UUMIHbR4qFmdQvXCw0sikvjeJ2HKZaVml3ntmZs5+5N3GzolGcrYUXECgYEA +pPsBnsCoIJ66s7pCIKIfZtI5QT1f20P0EuDVemn5Ls9bwcaAuzV3WGFymKwiISj+ +MtRviFhTTTROYRYa8Be+3A4ad4gQS4M8bmLlYhKPIJUtlQL9jZHXcR/H9578ofhJ +AQcFIkb/XjFQiC58yX4+hxgbGufsEk2dkAyPwm1ZlQsCgYBTjnraJbYSz1v3MQKx +fHm9eHki/ODR3lWiCYYnnW3AwRa7AXS4ZiSw78wzkUX2XTJbE6JlEUH4M9DMzr4y +QBwKmx+3u+Im4WcZ889jo6XrF0X9mXRmY25+gr2ypTbKZjT8FCYcXIgiOxITLXZh +Bmn7KZcsdaPxSFn05ASEanLNqA== +-----END PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qocsp/certs/infbobchain.crt b/tests/auto/network/ssl/qocsp/certs/infbobchain.crt new file mode 100644 index 0000000000..7ed13c2856 --- /dev/null +++ b/tests/auto/network/ssl/qocsp/certs/infbobchain.crt @@ -0,0 +1,49 @@ +-----BEGIN CERTIFICATE----- +MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQsFADCBjjELMAkGA1UEBhMCTk8x +DTALBgNVBAgMBE9zbG8xEjAQBgNVBAcMCU9zbG8gQ2l0eTETMBEGA1UECgwKVGhl +IFF0IENBMTENMAsGA1UECwwEUVRDTjERMA8GA1UEAwwIY2ExcXQuaW8xJTAjBgkq +hkiG9w0BCQEWFnRpbXVyLnBvY2hlcHRzb3ZAcXQuaW8wHhcNMTgxMTIyMTAyOTM3 +WhcNMjgxMTE5MTAyOTM3WjCBmDELMAkGA1UEBhMCTk8xDTALBgNVBAgMBE9zbG8x +EjAQBgNVBAcMCU9zbG8gQ2l0eTEkMCIGA1UECgwbVGhlIEluZmFtb3VzIFNuZWFr +eSBCb2IgTHRkMQwwCgYDVQQLDANCREExEzARBgNVBAMMCmluZmJvYi5jb20xHTAb +BgkqhkiG9w0BCQEWDmJvYkBpbmZib2IuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA5Bdgbj5ZEGtzsScZ20PoMtZgMWhhs355hqHK2sVUikrLF980 +pHiK1gdZFt3YjrSGdY6L2H7RxrKqAReZOnzfXa9+5hSGZ4pRegatLHmIzVJeiNHe +wn9zSUn+0xufj/nQMjSzfGlyC3LWPJK5UnuMrG/vvcYGsLdg2C9yNCwXfltu4Xdg +ZX3JgeINl98zmrI2TPBeR0gcReXu331WlJggvEuI3V1EBG1DRZOh7nw8A4T9YDLa +Bih7rFjnSOTunEAH1FJkS0n4v41qHiiz2n24+yiHAPPmKIzr7m9oLjaTuNofX3PN +/4ApJASYcFzXSEI0VJ8+i7tOZA0xvV9vIG1/UwIDAQABo3sweTAJBgNVHRMEAjAA +MCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAd +BgNVHQ4EFgQUloqk6Iihkkcxp85jAzeUPGVmapkwHwYDVR0jBBgwFoAUeBcnAkU7 +sTqm7i2QvTxwgr0nQ0QwDQYJKoZIhvcNAQELBQADggEBAGCdYFNskTzMilRtmw+v +oJQM3mc6LdYYuADCuh8O/GKaqUnE7V2XnMBYWMN93eeN9VXmK2yAZaQU1J6ruP1S +pLMzJ8hbQej+sm+XAHVxAtr34KmEC50gIn1cB/sRKxHMombbNl7EK44puFU7q58P +zBz5lTXXTfA954D/ijEMMSDvIZ25me6vrGPMj1LX/wC6CWadSr9IxAO9HQVQQqwv +AbbqrCvMSMv633/f1EYU8Q6jhUCTlnin4pXtriOnqi+6MZICaYRCUgV224Rs3OUS +jmrbOeoaZUpmOVmuoYXWeexe229G2KGiEIgnSBEk5OLFHCeZ8++WJ5/SLHt8MBLc +O0w= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIID9DCCAtygAwIBAgIJAMQbE3657KDYMA0GCSqGSIb3DQEBCwUAMIGOMQswCQYD +VQQGEwJOTzENMAsGA1UECAwET3NsbzESMBAGA1UEBwwJT3NsbyBDaXR5MRMwEQYD +VQQKDApUaGUgUXQgQ0ExMQ0wCwYDVQQLDARRVENOMREwDwYDVQQDDAhjYTFxdC5p +bzElMCMGCSqGSIb3DQEJARYWdGltdXIucG9jaGVwdHNvdkBxdC5pbzAeFw0xODEx +MjIxMDIxMTNaFw0yODExMTkxMDIxMTNaMIGOMQswCQYDVQQGEwJOTzENMAsGA1UE +CAwET3NsbzESMBAGA1UEBwwJT3NsbyBDaXR5MRMwEQYDVQQKDApUaGUgUXQgQ0Ex +MQ0wCwYDVQQLDARRVENOMREwDwYDVQQDDAhjYTFxdC5pbzElMCMGCSqGSIb3DQEJ +ARYWdGltdXIucG9jaGVwdHNvdkBxdC5pbzCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAOCs3AV7sDKHJUJcm7a0OqnShIvoB1qv6UcOmlBmUzGl5GzX90Jz +7jYJoOPjxjNyRxMOsOReB1ZcSuIAjkdAEfFMaVe6j7qKTJ5ycTVY/fVoxyxsSNuI +xOJ6RCEjLHcxONEbkN/xI8LMdVko3m4P10r5GxwrgyPvpa87Yq5+XJ1BPWJyKbD7 +Tqpn3dvZUj0/POsMUTT7Q7VXOfDlZj58XWAC6ECTqJauhGFMhiwgqOn2Qo1W0QjV +DkGqRTdgIAM6Rv2cSRxgnflwW5QZ8kWUV81h/yx4cck/D9TcVxjr3Pvy6aJ/U41u +d4XJQgwCj4LJi4msw1S0CvZWmz+2BKxcbRsCAwEAAaNTMFEwHQYDVR0OBBYEFHgX +JwJFO7E6pu4tkL08cIK9J0NEMB8GA1UdIwQYMBaAFHgXJwJFO7E6pu4tkL08cIK9 +J0NEMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADp1kqDRcyVG +BdMge+Il10IjbpzzSjAoZiqiw69V99LiHW9ePbxG4AmliE6Za60GE5PCXOLjJh/5 +efgnIbybbyIOIT9iK4TXWLw2XW+rMY51c0RAxp2h/sc+5CZ0F0I811F5VUHXg2qR +U7C2zbzqAimN8TBm6FRe7NFQfqLCrsuFJjSc3obrqKQcpvRwxMk6NpkdoemzqLmY +lrBrTaeVbZ4ix3srVPvXRm9TdiC+JuuFmvulMfe+/wwnhb+dwT3JUC+EIq/Uf5Wb +g8lvB4ntitL8NLQ2hFGqYuoFNIGs6tRN71ohk+/ONqe9wJhcI9QAruPOvsg+8J0H +uGooX7PUNHg= +-----END CERTIFICATE----- diff --git a/tests/auto/network/ssl/qocsp/certs/ss1-private.key b/tests/auto/network/ssl/qocsp/certs/ss1-private.key new file mode 100644 index 0000000000..1c42daaf9f --- /dev/null +++ b/tests/auto/network/ssl/qocsp/certs/ss1-private.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC4bXcfIjweShLx +6jBTKu/i5sXmlwTH9Z4PTzQ1VteKyEIDlnW5ocVWqRgBrvz3NlTFkDKkQXshkXyE +JyVZFbAPCfGsroZVISpFhUmJbPMBNn3SyGEU+sxWIpOZOKmG5tel6B4Bt5TWsRHL +mtU8Pv/APsz+i9JhgE25ksGhx16MqvdRv/xNGleF8qe+hDOeiNF3/lNv2hYb/MvD +1F73FBoDVnqty/VXXOJFb7elLE4ArXsTN/hip42Lbl1guYvnqnTZFhCHwMzRu4qc +3FTlemumfJpacpRnqVw2TURA5SdpTp9NYIxygEGNY201meNEjAEyg8GeFkAgu99R +LPQT+rTNAgMBAAECggEAPQEIfCXo2OQLrDWY0onLW7SWFZYyoKngJJRAYrxdA60G +GQW13zdhfS7ln/jv+B3ioI74EVkPj6T+GQCR3AvOdssFQ+dey93yi5hxIKIHJ4mM +ySI66qOi34MEa5RQjyzgfCJxeoPtGa7sgfqvOgRkuISNbk11w4abLx0aK5c08TY0 +JdeoWWhATaFZXl782Aw2FwGPTwOIf7GB09BJS3qUqlMT9fowLmWO10jOKkNtvcnT +2mAqT5cdZG1ffT5+f0JETPCbBPhhyE7VyYEVQfqTkRnEoz3hcZvjx91jD527+CSL +Qhg7zZu2oakyJQvpHETZ6cgrs7uDEiol7ARANezwyQKBgQDmapxV/qIOd5WFDVXw +lGt+dsELBBdMhvzr4A9eZdIZiXu48rdFG0XoECo5BKpXa1+ISr2od0U0YODrJrws +OHxHhlxGjJFs8kFteUPHyEZv6/rvkbA+xc0Uw04NnDRHBLK8VvX7MBWfvTqLN4bK +sZsMblscRBtEpFpN1fiJgnNASwKBgQDM56lBugtueBV9M4C/JF2is96d14ue3Y4i +SgMnHY18D3ru+KDuxPYoIs5Yos2vDWK2k8754WZ+WNXokjRoYPiFbeBPpI9NudJs +BUJz/sLJHjs3a4HrQs3hCuufczNxq9wQnALQHCMEqeBUTYCu/1+zYgwAu3Z/R8rJ +jKgexl+gRwKBgGrLCNCWpze7VzKGvsk1kSjZE5nueHoAqqMMgzMGUD2DyjMrU6QV +Au6O53Lr5aOE4Y9CzOqS9SFUsYprtpVsTLW94XDVX+W11ntN1At5mKPxJKn6xUwi +022HI9sNBfHQjKLcTz/vxmX2B3dU8gVqEenOEC5mppjG8A/ZV0ssigxHAoGAfGsG +OSSwoElGMxm8yVNZj9vMBufEnZhGH8f1FiE5seTsboKFpbXvCfvoc6WXYv2rvNUP +TmdxBrMGYAu2ytJm1Q4cr/9qDHYSsQiYizpcKCa1KjebUbDktgsde1pGGHWUUHmK +s7cCBGjqEAZnZtslzxRv2Vn639pF5hAEXXtywS0CgYAUIjhp43qgtbQdZMX7xbVR +lT26aq7NguCtt7njpgkhqc0HThb3I8ImrhNSDcS0/T9dPU70vt0ceruyRXmwX5hA +l28i5GzF5ufaRQdcsSR9u+P67nD5sTZBesbejXFySis5EC/97A4XZvkSfY4DQSZ+ +u8JJPZUlb2kGAHRpmxvpDA== +-----END PRIVATE KEY----- diff --git a/tests/auto/network/ssl/qocsp/certs/ss1.crt b/tests/auto/network/ssl/qocsp/certs/ss1.crt new file mode 100644 index 0000000000..43ca8316c2 --- /dev/null +++ b/tests/auto/network/ssl/qocsp/certs/ss1.crt @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIEKzCCAxOgAwIBAgIJAOO/b5uLSmT8MA0GCSqGSIb3DQEBBQUAMIGqMQswCQYD +VQQGEwJOTzENMAsGA1UECAwET3NsbzENMAsGA1UEBwwET3NsbzESMBAGA1UECgwJ +VGhlIFF0IENBMScwJQYDVQQLDB5SJkQgKGZha2UgY2VydGlmaWNhdGVzIGlzc3Vl +cikxGTAXBgNVBAMMEFRpbXVyIFBvY2hlcHRzb3YxJTAjBgkqhkiG9w0BCQEWFnRp +bXVyLnBvY2hlcHRzb3ZAcXQuaW8wIBcNMTgxMTE3MDUxNDA1WhgPMjExODEwMjQw +NTE0MDVaMIGqMQswCQYDVQQGEwJOTzENMAsGA1UECAwET3NsbzENMAsGA1UEBwwE +T3NsbzESMBAGA1UECgwJVGhlIFF0IENBMScwJQYDVQQLDB5SJkQgKGZha2UgY2Vy +dGlmaWNhdGVzIGlzc3VlcikxGTAXBgNVBAMMEFRpbXVyIFBvY2hlcHRzb3YxJTAj +BgkqhkiG9w0BCQEWFnRpbXVyLnBvY2hlcHRzb3ZAcXQuaW8wggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC4bXcfIjweShLx6jBTKu/i5sXmlwTH9Z4PTzQ1 +VteKyEIDlnW5ocVWqRgBrvz3NlTFkDKkQXshkXyEJyVZFbAPCfGsroZVISpFhUmJ +bPMBNn3SyGEU+sxWIpOZOKmG5tel6B4Bt5TWsRHLmtU8Pv/APsz+i9JhgE25ksGh +x16MqvdRv/xNGleF8qe+hDOeiNF3/lNv2hYb/MvD1F73FBoDVnqty/VXXOJFb7el +LE4ArXsTN/hip42Lbl1guYvnqnTZFhCHwMzRu4qc3FTlemumfJpacpRnqVw2TURA +5SdpTp9NYIxygEGNY201meNEjAEyg8GeFkAgu99RLPQT+rTNAgMBAAGjUDBOMB0G +A1UdDgQWBBSyHPlJr6BrpwMY7Sxg2R3CpQR7UzAfBgNVHSMEGDAWgBSyHPlJr6Br +pwMY7Sxg2R3CpQR7UzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQBD +o86xp1WwvX6mYzF94ifZlkq1aDN6/njj2B9fvJCtygfqq6b9BrQJ0hNeqRh8OaIh +v2YmjbdUaoYguHmUxL+SeS67Sp8QBoSwdU5x0i8ygrigBrbb3myNqN6hGvpGy9E0 +B8PnVDt9DaOCunaMyGNPMLNPVGYULmberGtxV9wilcH4Q6WZrk9IhuyfqeBZtBYM +IcjV3OKdUv/ggu2IZSN7njKcgr+uyPt0Ymo9GozJSTdnN/E4hsRgzcgzCMf2fxzj +nGcsDRQ4L1R8p1zDlduxmmk42zGCGz3duFX7dijAxJWirS8Zsea4aooLgDQYT/zI +8hKd3KC3knLhPcxFKiUg +-----END CERTIFICATE----- diff --git a/tests/auto/network/ssl/qocsp/qocsp.pro b/tests/auto/network/ssl/qocsp/qocsp.pro new file mode 100644 index 0000000000..f4e846f39b --- /dev/null +++ b/tests/auto/network/ssl/qocsp/qocsp.pro @@ -0,0 +1,15 @@ +CONFIG += testcase + +SOURCES += tst_qocsp.cpp +QT = core network network-private testlib + +TARGET = tst_qocsp + +win32 { + CONFIG(debug, debug|release) { + DESTDIR = debug + } else { + DESTDIR = release + } +} + diff --git a/tests/auto/network/ssl/qocsp/tst_qocsp.cpp b/tests/auto/network/ssl/qocsp/tst_qocsp.cpp new file mode 100644 index 0000000000..9716c04bbb --- /dev/null +++ b/tests/auto/network/ssl/qocsp/tst_qocsp.cpp @@ -0,0 +1,823 @@ +/**************************************************************************** + ** + ** Copyright (C) 2018 The Qt Company Ltd. + ** Contact: https://www.qt.io/licensing/ + ** + ** This file is part of the test suite of the Qt Toolkit. + ** + ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ + ** Commercial License Usage + ** Licensees holding valid commercial Qt licenses may use this file in + ** accordance with the commercial license agreement provided with the + ** Software or, alternatively, in accordance with the terms contained in + ** a written agreement between you and The Qt Company. For licensing terms + ** and conditions see https://www.qt.io/terms-conditions. For further + ** information use the contact form at https://www.qt.io/contact-us. + ** + ** GNU General Public License Usage + ** Alternatively, this file may be used under the terms of the GNU + ** General Public License version 3 as published by the Free Software + ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT + ** included in the packaging of this file. Please review the following + ** information to ensure the GNU General Public License requirements will + ** be met: https://www.gnu.org/licenses/gpl-3.0.html. + ** + ** $QT_END_LICENSE$ + ** + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +// NOTE: the word 'subject' in the code below means the subject of a status request, +// so in general it's our peer's certificate we are asking about. + +using SslError = QT_PREPEND_NAMESPACE(QSslError); +using VectorOfErrors = QT_PREPEND_NAMESPACE(QVector); +using Latin1String = QT_PREPEND_NAMESPACE(QLatin1String); + +Q_DECLARE_METATYPE(SslError) +Q_DECLARE_METATYPE(VectorOfErrors) +Q_DECLARE_METATYPE(Latin1String) + +QT_BEGIN_NAMESPACE + +namespace { + +using OcspResponse = QSharedPointer; +using BasicResponse = QSharedPointer; +using SingleResponse = QSharedPointer; +using CertId = QSharedPointer; +using EvpKey = QSharedPointer; +using Asn1Time = QSharedPointer; +using CertificateChain = QList; + +using NativeX509Ptr = X509 *; + +class X509Stack { +public: + explicit X509Stack(const QList &chain); + + ~X509Stack(); + + int size() const; + X509 *operator[](int index) const; + operator STACK_OF(X509) *() const; + +private: + OPENSSL_STACK *stack = nullptr; + + Q_DISABLE_COPY(X509Stack) +}; + +X509Stack::X509Stack(const QList &chain) +{ + if (!chain.size()) + return; + + stack = q_OPENSSL_sk_new_null(); + if (!stack) + return; + + for (const QSslCertificate &cert : chain) { + X509 *nativeCert = NativeX509Ptr(cert.handle()); + if (!nativeCert) + continue; + q_OPENSSL_sk_push(stack, nativeCert); + q_X509_up_ref(nativeCert); + } +} + +X509Stack::~X509Stack() +{ + if (stack) + q_OPENSSL_sk_pop_free(stack, reinterpret_cast(q_X509_free)); +} + +int X509Stack::size() const +{ + if (stack) + return q_OPENSSL_sk_num(stack); + return 0; +} + +X509 *X509Stack::operator[](int index) const +{ + return NativeX509Ptr(q_OPENSSL_sk_value(stack, index)); +} + +X509Stack::operator STACK_OF(X509) *() const +{ + return reinterpret_cast(stack); +} + +struct OcspTimeStamp +{ + OcspTimeStamp() = default; + OcspTimeStamp(long secondsBeforeNow, long secondsAfterNow); + + static Asn1Time timeToAsn1Time(long adjustment); + + Asn1Time thisUpdate; + Asn1Time nextUpdate; +}; + +OcspTimeStamp::OcspTimeStamp(long secondsBeforeNow, long secondsAfterNow) +{ + Asn1Time start = timeToAsn1Time(secondsBeforeNow); + Asn1Time end = timeToAsn1Time(secondsAfterNow); + if (start.data() && end.data()) { + thisUpdate.swap(start); + nextUpdate.swap(end); + } +} + +Asn1Time OcspTimeStamp::timeToAsn1Time(long adjustment) +{ + if (ASN1_TIME *adjusted = q_X509_gmtime_adj(nullptr, adjustment)) + return Asn1Time(adjusted, q_ASN1_TIME_free); + return Asn1Time{}; +} + +struct OcspResponder +{ + OcspResponder(const OcspTimeStamp &stamp, const CertificateChain &subjs, + const CertificateChain &respChain, const QSslKey &respPKey); + + QByteArray buildResponse(int responseStatus, int certificateStatus) const; + static EvpKey privateKeyToEVP_PKEY(const QSslKey &privateKey); + static CertId certificateToCertId(X509 *subject, X509 *issuer); + static QByteArray responseToDer(OCSP_RESPONSE *response); + + OcspTimeStamp timeStamp; + // Plural, we can send a 'wrong' BasicResponse containing more than + // 1 SingleResponse. + X509Stack subjects; + X509Stack responderChain; + QSslKey responderKey; +}; + +OcspResponder::OcspResponder(const OcspTimeStamp &stamp, const CertificateChain &subjs, + const CertificateChain &respChain, const QSslKey &respPKey) + : timeStamp(stamp), + subjects(subjs), + responderChain(respChain), + responderKey(respPKey) +{ +} + +QByteArray OcspResponder::buildResponse(int responseStatus, int certificateStatus) const +{ + if (responseStatus != OCSP_RESPONSE_STATUS_SUCCESSFUL) { + OCSP_RESPONSE *response = q_OCSP_response_create(responseStatus, nullptr); + if (!response) + return {}; + const OcspResponse rGuard(response, q_OCSP_RESPONSE_free); + return responseToDer(response); + } + + Q_ASSERT(subjects.size() && responderChain.size() && responderKey.handle()); + + const EvpKey nativeKey = privateKeyToEVP_PKEY(responderKey); + if (!nativeKey.data()) + return {}; + + OCSP_BASICRESP *basicResponse = q_OCSP_BASICRESP_new(); + if (!basicResponse) + return {}; + const BasicResponse brGuard(basicResponse, q_OCSP_BASICRESP_free); + + for (int i = 0, e = subjects.size(); i < e; ++i) { + X509 *subject = subjects[i]; + Q_ASSERT(subject); + CertId certId = certificateToCertId(subject, responderChain[0]); + if (!certId.data()) + return {}; + + // NOTE: we do not own this 'singleResponse': + ASN1_TIME *revisionTime = certificateStatus == V_OCSP_CERTSTATUS_REVOKED ? + timeStamp.thisUpdate.data() : nullptr; + + if (!q_OCSP_basic_add1_status(basicResponse, certId.data(), certificateStatus, 0, revisionTime, + timeStamp.thisUpdate.data(), timeStamp.nextUpdate.data())) { + return {}; + } + } + + if (q_OCSP_basic_sign(basicResponse, responderChain[0], nativeKey.data(), q_EVP_sha1(), + responderChain, 0) != 1) { + return {}; + } + + OCSP_RESPONSE *ocspResponse = q_OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, basicResponse); + if (!ocspResponse) + return {}; + const OcspResponse rGuard(ocspResponse, q_OCSP_RESPONSE_free); + return responseToDer(ocspResponse); +} + +EvpKey OcspResponder::privateKeyToEVP_PKEY(const QSslKey &privateKey) +{ + const EvpKey nullKey; + if (privateKey.isNull() || privateKey.algorithm() != QSsl::Rsa) { + // We use only RSA keys in this auto-test, since we test OCSP only, + // not handshake/TLS in general. + return nullKey; + } + + EVP_PKEY *nativeKey = q_EVP_PKEY_new(); + if (!nativeKey) + return nullKey; + + const EvpKey keyGuard(nativeKey, q_EVP_PKEY_free); + if (!q_EVP_PKEY_set1_RSA(nativeKey, reinterpret_cast(privateKey.handle()))) + return nullKey; + + return keyGuard; +} + +CertId OcspResponder::certificateToCertId(X509 *subject, X509 *issuer) +{ + const CertId nullId; + if (!subject || !issuer) + return nullId; + + const EVP_MD *digest = q_EVP_sha1(); + if (!digest) + return nullId; + + OCSP_CERTID *certId = q_OCSP_cert_to_id(digest, subject, issuer); + if (!certId) + return nullId; + + return CertId(certId, q_OCSP_CERTID_free); +} + +QByteArray OcspResponder::responseToDer(OCSP_RESPONSE *response) +{ + if (!response) + return {}; + + const int derSize = q_i2d_OCSP_RESPONSE(response, nullptr); + if (derSize <= 0) + return {}; + + QByteArray derData(derSize, Qt::Uninitialized); + unsigned char *pData = reinterpret_cast(derData.data()); + const int serializedSize = q_i2d_OCSP_RESPONSE(response, &pData); + if (serializedSize != derSize) + return {}; + + return derData; +} + +// The QTcpServer capable of sending OCSP status responses. +class OcspServer : public QTcpServer +{ + Q_OBJECT + +public: + OcspServer(const CertificateChain &serverChain, const QSslKey &privateKey); + + void configureResponse(const QByteArray &responseDer); + QString hostName() const; + QString peerVerifyName() const; + +Q_SIGNALS: + void internalServerError(); + +private: + void incomingConnection(qintptr descriptor) override; + +public: + QSslConfiguration serverConfig; + QSslSocket serverSocket; +}; + +OcspServer::OcspServer(const CertificateChain &serverChain, const QSslKey &privateKey) +{ + Q_ASSERT(serverChain.size()); + Q_ASSERT(!privateKey.isNull()); + + serverConfig = QSslConfiguration::defaultConfiguration(); + serverConfig.setLocalCertificateChain(serverChain); + serverConfig.setPrivateKey(privateKey); +} + +void OcspServer::configureResponse(const QByteArray &responseDer) +{ + serverConfig.setBackendConfigurationOption("Qt-OCSP-response", responseDer); +} + +QString OcspServer::hostName() const +{ + // It's 'name' and not 'address' to be consistent with QSslSocket's naming style, + // where it's connectToHostEncrypted(hostName, ...) + const QHostAddress &addr = serverAddress(); + if (addr == QHostAddress::Any || addr == QHostAddress::AnyIPv4) + return QStringLiteral("127.0.0.1"); + if (addr == QHostAddress::AnyIPv6) + return QStringLiteral("::1"); + return addr.toString(); +} + +QString OcspServer::peerVerifyName() const +{ + const CertificateChain &localChain = serverConfig.localCertificateChain(); + if (localChain.isEmpty()) + return {}; + const auto cert = localChain.first(); + if (cert.isNull()) + return {}; + + const QStringList &names = cert.subjectInfo(QSslCertificate::CommonName); + return names.isEmpty() ? QString{} : names.first(); +} + +void OcspServer::incomingConnection(qintptr socketDescriptor) +{ + close(); + + if (!serverSocket.setSocketDescriptor(socketDescriptor)) { + emit internalServerError(); + return; + } + + serverSocket.setSslConfiguration(serverConfig); + // Since we test a client, not a server, we don't care about any + // possible errors on the server (QAbstractSocket or QSslSocket-related). + // Thus, we don't connect to any error signal. + serverSocket.startServerEncryption(); +} + +} // unnamed namespace + +class tst_QOcsp : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + +private slots: + void connectSelfSigned(); + void badStatus_data(); + void badStatus(); + void multipleSingleResponses(); + void malformedResponse(); + void expiredResponse_data(); + void expiredResponse(); + void noNextUpdate(); + void wrongCertificateInResponse_data(); + void wrongCertificateInResponse(); + void untrustedResponder(); + + // OCSPTODO: more tests in future ... + +private: + void setupOcspClient(QSslSocket &clientSocket, const CertificateChain &trustedCAs, + const QString &peerName); + bool containsOcspErrors(const QList &errorsFound) const; + static bool containsError(const QList &errors, QSslError::SslError code); + static QByteArray goodResponse(const CertificateChain &subject, const CertificateChain &responder, + const QSslKey &privateKey, long beforeNow = -1000, long afterNow = 1000); + static bool loadPrivateKey(const QString &keyName, QSslKey &key); + static CertificateChain issuerToChain(const CertificateChain &chain); + static CertificateChain subjectToChain(const CertificateChain &chain); + + static QString certDirPath; + + void (QSslSocket::*socketErrorSignal)(QAbstractSocket::SocketError) = &QAbstractSocket::error; + void (QSslSocket::*tlsErrorsSignal)(const QList &) = &QSslSocket::sslErrors; + void (QTestEventLoop::*exitLoopSlot)() = &QTestEventLoop::exitLoop; + + const int handshakeTimeoutMS = 500; + QTestEventLoop loop; + + std::vector ocspErrorCodes = {QSslError::OcspNoResponseFound, + QSslError::OcspMalformedRequest, + QSslError::OcspMalformedResponse, + QSslError::OcspInternalError, + QSslError::OcspTryLater, + QSslError::OcspSigRequred, + QSslError::OcspUnauthorized, + QSslError::OcspResponseCannotBeTrusted, + QSslError::OcspResponseCertIdUnknown, + QSslError::OcspResponseExpired, + QSslError::OcspStatusUnknown}; +}; + +#define QCOMPARE_SINGLE_ERROR(sslSocket, expectedError) \ + const auto &tlsErrors = sslSocket.sslErrors(); \ + QCOMPARE(tlsErrors.size(), 1); \ + QCOMPARE(tlsErrors[0].error(), expectedError) + +#define QVERIFY_HANDSHAKE_WITHOUT_ERRORS(sslSocket) \ + QVERIFY(sslSocket.isEncrypted()); \ + QCOMPARE(sslSocket.state(), QAbstractSocket::ConnectedState); \ + QVERIFY(sslSocket.sslErrors().isEmpty()) + +#define QDECLARE_CHAIN(object, chainFileName) \ + CertificateChain object = QSslCertificate::fromPath(certDirPath + QLatin1String(chainFileName)); \ + QVERIFY(object.size()) + +#define QDECLARE_PRIVATE_KEY(key, keyFileName) \ + QSslKey key; \ + QVERIFY(loadPrivateKey(QLatin1String(keyFileName), key)) + +QString tst_QOcsp::certDirPath; + +void tst_QOcsp::initTestCase() +{ + QVERIFY(QSslSocket::supportsSsl()); + + certDirPath = QFileInfo(QFINDTESTDATA("certs")).absolutePath(); + QVERIFY(certDirPath.size() > 0); + certDirPath += QDir::separator() + QStringLiteral("certs") + QDir::separator(); +} + +void tst_QOcsp::connectSelfSigned() +{ + // This test may look a bit confusing, since we have essentially 1 + // self-signed certificate, which we trust for the purpose of this test, + // but we also request its (the certificate's) status and then we sign + // the status response using the same certificate and the corresponding + // private key. Anyway, we test the very basic things here: we send + // an OCSP status request, we verify the response (if server has sent it), + // and detect errors (if any). + QDECLARE_CHAIN(subjectChain, "ss1.crt"); + QDECLARE_CHAIN(responderChain, "ss1.crt"); + QDECLARE_PRIVATE_KEY(privateKey, "ss1-private.key"); + { + // This server ignores our status request: + const QSslError::SslError expectedError = QSslError::OcspNoResponseFound; + + OcspServer server(subjectChain, privateKey); + QVERIFY(server.listen()); + connect(&server, &OcspServer::internalServerError, &loop, exitLoopSlot); + + QSslSocket clientSocket; + QSslConfiguration clientConfig = QSslConfiguration::defaultConfiguration(); + auto roots = clientConfig.caCertificates(); + setupOcspClient(clientSocket, issuerToChain(subjectChain), server.peerVerifyName()); + clientSocket.connectToHostEncrypted(server.hostName(), server.serverPort()); + loop.enterLoopMSecs(handshakeTimeoutMS); + + QVERIFY(!clientSocket.isEncrypted()); + QCOMPARE_SINGLE_ERROR(clientSocket, expectedError); + } + { + // Now the server will send a valid 'status: good' response. + OcspServer server(subjectChain, privateKey); + const QByteArray response(goodResponse(subjectChain, responderChain, privateKey)); + QVERIFY(response.size()); + server.configureResponse(response); + QVERIFY(server.listen()); + + QSslSocket clientSocket; + setupOcspClient(clientSocket, issuerToChain(subjectChain), server.peerVerifyName()); + clientSocket.connectToHostEncrypted(server.hostName(), server.serverPort()); + loop.enterLoopMSecs(handshakeTimeoutMS); + + QVERIFY_HANDSHAKE_WITHOUT_ERRORS(clientSocket); + } +} + +void tst_QOcsp::badStatus_data() +{ + QTest::addColumn("responseStatus"); + QTest::addColumn("certificateStatus"); + QTest::addColumn("expectedError"); + + QTest::addRow("malformed-request") << OCSP_RESPONSE_STATUS_MALFORMEDREQUEST << 1 << QSslError(QSslError::OcspMalformedRequest); + QTest::addRow("internal-error") << OCSP_RESPONSE_STATUS_INTERNALERROR << 2 << QSslError(QSslError::OcspInternalError); + QTest::addRow("try-later") << OCSP_RESPONSE_STATUS_TRYLATER << 3 << QSslError(QSslError::OcspTryLater); + QTest::addRow("signed-request-require") << OCSP_RESPONSE_STATUS_SIGREQUIRED << 2 << QSslError(QSslError::OcspSigRequred); + QTest::addRow("unauthorized-request") << OCSP_RESPONSE_STATUS_UNAUTHORIZED << 1 <("beforeNow"); + QTest::addColumn("afterNow"); + + QTest::addRow("expired") << -2000L << -1000L; + QTest::addRow("not-valid-yet") << 5000L << 10000L; + QTest::addRow("next-before-this") << -1000L << -2000L; +} + +void tst_QOcsp::expiredResponse() +{ + // We report different kinds of problems with [thisUpdate, nextUpdate] + // as 'expired' (to keep it simple): + const QSslError::SslError expectedError = QSslError::OcspResponseExpired; + + QFETCH(const long, beforeNow); + QFETCH(const long, afterNow); + + QDECLARE_CHAIN(subjectChain, "ss1.crt"); + QDECLARE_CHAIN(responderChain, "ss1.crt"); + QDECLARE_PRIVATE_KEY(privateKey, "ss1-private.key"); + + OcspServer server(subjectChain, privateKey); + const QByteArray response(goodResponse(subjectChain, responderChain, privateKey, beforeNow, afterNow)); + QVERIFY(response.size()); + server.configureResponse(response); + QVERIFY(server.listen()); + connect(&server, &OcspServer::internalServerError, &loop, exitLoopSlot); + + QSslSocket clientSocket; + setupOcspClient(clientSocket, issuerToChain(subjectChain), server.peerVerifyName()); + clientSocket.connectToHostEncrypted(server.hostName(), server.serverPort()); + loop.enterLoopMSecs(handshakeTimeoutMS); + + QVERIFY(!clientSocket.isEncrypted()); + QCOMPARE_SINGLE_ERROR(clientSocket, expectedError); +} + +void tst_QOcsp::noNextUpdate() +{ + // RFC2560, 2.4: + // "If nextUpdate is not set, the responder is indicating that newer + // revocation information is available all the time." + // + // This test is just to verify that we correctly handle such responses. + QDECLARE_CHAIN(subjectChain, "ss1.crt"); + QDECLARE_CHAIN(responderChain, "ss1.crt"); + QDECLARE_PRIVATE_KEY(privateKey, "ss1-private.key"); + + OcspServer server(subjectChain, privateKey); + OcspTimeStamp openRange(-1000, 0); + openRange.nextUpdate.clear(); + const OcspResponder responder(openRange, subjectChain, responderChain, privateKey); + const QByteArray response(responder.buildResponse(OCSP_RESPONSE_STATUS_SUCCESSFUL, + V_OCSP_CERTSTATUS_GOOD)); + QVERIFY(response.size()); + server.configureResponse(response); + QVERIFY(server.listen()); + connect(&server, &OcspServer::internalServerError, &loop, exitLoopSlot); + + QSslSocket clientSocket; + setupOcspClient(clientSocket, issuerToChain(subjectChain), server.peerVerifyName()); + clientSocket.connectToHostEncrypted(server.hostName(), server.serverPort()); + loop.enterLoopMSecs(handshakeTimeoutMS); + + QVERIFY_HANDSHAKE_WITHOUT_ERRORS(clientSocket); +} + +void tst_QOcsp::wrongCertificateInResponse_data() +{ + QTest::addColumn("respChainName"); + QTest::addColumn("respKeyName"); + QTest::addColumn("wrongChainName"); + + QTest::addRow("same-CA-wrong-subject") << QLatin1String("ca1.crt") << QLatin1String("ca1.key") + << QLatin1String("alice.crt"); + QTest::addRow("wrong-CA-same-subject") << QLatin1String("ss1.crt") << QLatin1String("ss1-private.key") + << QLatin1String("alice.crt"); + QTest::addRow("wrong-CA-wrong-subject") << QLatin1String("ss1.crt") << QLatin1String("ss1-private.key") + << QLatin1String("ss1.crt"); +} + +void tst_QOcsp::wrongCertificateInResponse() +{ + QFETCH(const QLatin1String, respChainName); + QFETCH(const QLatin1String, respKeyName); + QFETCH(const QLatin1String, wrongChainName); + // In this test, the server will send a valid response (correctly signed + // by a trusted key/cert) but for a wrong certificate (not the one the + // server presented to the client in the server's 'Certificate' message). + const QSslError::SslError expectedError = QSslError::OcspResponseCertIdUnknown; + + QDECLARE_CHAIN(subjectChain, "infbobchain.crt"); + QDECLARE_PRIVATE_KEY(subjectKey, "infbob.key"); + QDECLARE_CHAIN(responderChain, respChainName); + QDECLARE_PRIVATE_KEY(responderKey, respKeyName); + + QDECLARE_CHAIN(wrongChain, wrongChainName); + + OcspServer server(subjectToChain(subjectChain), subjectKey); + const QByteArray wrongResponse(goodResponse(wrongChain, responderChain, responderKey)); + QVERIFY(wrongResponse.size()); + server.configureResponse(wrongResponse); + QVERIFY(server.listen()); + connect(&server, &OcspServer::internalServerError, &loop, exitLoopSlot); + + QSslSocket clientSocket; + setupOcspClient(clientSocket, issuerToChain(subjectChain), server.peerVerifyName()); + clientSocket.connectToHostEncrypted(server.hostName(), server.serverPort()); + loop.enterLoopMSecs(handshakeTimeoutMS); + + QVERIFY(!clientSocket.isEncrypted()); + QVERIFY(containsError(clientSocket.sslErrors(), expectedError)); +} + +void tst_QOcsp::untrustedResponder() +{ + const QSslError::SslError expectedError = QSslError::OcspResponseCannotBeTrusted; + + QDECLARE_CHAIN(subjectChain, "infbobchain.crt"); + QDECLARE_PRIVATE_KEY(subjectKey, "infbob.key"); + QDECLARE_CHAIN(responderChain, "ca1.crt"); + QDECLARE_PRIVATE_KEY(responderKey, "ca1.key"); + + OcspServer server(subjectChain, subjectKey); + const QByteArray response(goodResponse(subjectToChain(subjectChain), responderChain, responderKey)); + QVERIFY(response.size()); + server.configureResponse(response); + QVERIFY(server.listen()); + connect(&server, &OcspServer::internalServerError, &loop, exitLoopSlot); + + QSslSocket clientSocket; + setupOcspClient(clientSocket, {}, server.peerVerifyName()); + clientSocket.connectToHostEncrypted(server.hostName(), server.serverPort()); + loop.enterLoopMSecs(handshakeTimeoutMS); + + QVERIFY(!clientSocket.isEncrypted()); + QVERIFY(containsError(clientSocket.sslErrors(), expectedError)); +} + +void tst_QOcsp::setupOcspClient(QSslSocket &clientSocket, const CertificateChain &caCerts, const QString &name) +{ + QSslConfiguration clientConfig = QSslConfiguration::defaultConfiguration(); + clientConfig.setOcspStaplingEnabled(true); + + if (caCerts.size()) { + auto roots = clientConfig.caCertificates(); + roots.append(caCerts); + clientConfig.setCaCertificates(roots); + } + + clientSocket.setSslConfiguration(clientConfig); + clientSocket.setPeerVerifyName(name); + + connect(&clientSocket, socketErrorSignal, &loop, exitLoopSlot); + connect(&clientSocket, tlsErrorsSignal, &loop, exitLoopSlot); + connect(&clientSocket, &QSslSocket::encrypted, &loop, exitLoopSlot); +} + +bool tst_QOcsp::containsOcspErrors(const QList &errorsFound) const +{ + for (auto code : ocspErrorCodes) { + if (containsError(errorsFound, code)) + return true; + } + return false; +} + +bool tst_QOcsp::containsError(const QList &errors, QSslError::SslError code) +{ + const auto it = std::find_if(errors.begin(), errors.end(), + [&code](const QSslError &other){return other.error() == code;}); + return it != errors.end(); +} + +QByteArray tst_QOcsp::goodResponse(const CertificateChain &subject, const CertificateChain &responder, + const QSslKey &privateKey, long beforeNow, long afterNow) +{ + const OcspResponder builder(OcspTimeStamp(beforeNow, afterNow), subject, responder, privateKey); + return builder.buildResponse(OCSP_RESPONSE_STATUS_SUCCESSFUL, V_OCSP_CERTSTATUS_GOOD); +} + +bool tst_QOcsp::loadPrivateKey(const QString &keyFileName, QSslKey &key) +{ + QFile keyFile(certDirPath + keyFileName); + if (!keyFile.open(QIODevice::ReadOnly)) + return false; + key = QSslKey(keyFile.readAll(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey); + return !key.isNull(); +} + +CertificateChain tst_QOcsp::issuerToChain(const CertificateChain &chain) +{ + // Here we presume that, if the chain isn't a single self-signed certificate, its second + // entry is the issuer. + const int length = chain.size(); + Q_ASSERT(length > 0); + return CertificateChain() << chain[length > 1 ? 1 : 0]; +} + +CertificateChain tst_QOcsp::subjectToChain(const CertificateChain &chain) +{ + Q_ASSERT(chain.size()); + return CertificateChain() << chain[0]; +} + +QT_END_NAMESPACE + +QTEST_MAIN(tst_QOcsp) + +#include "tst_qocsp.moc" diff --git a/tests/auto/network/ssl/ssl.pro b/tests/auto/network/ssl/ssl.pro index e89443ef4e..169e9bce83 100644 --- a/tests/auto/network/ssl/ssl.pro +++ b/tests/auto/network/ssl/ssl.pro @@ -21,6 +21,8 @@ qtConfig(ssl) { qdtlscookie \ qdtls } + + qtConfig(ocsp): SUBDIRS += qocsp } } From 01301b0b340df736dd1b0a54b3026e00b49c5ea3 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 8 Oct 2018 18:07:32 +0200 Subject: [PATCH 0521/1650] Don't require a default constructor for storing items in a QVector MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ChangeLog][QtCore][QVector] QVector does not require a default constructor for its template argument anymore. Change-Id: Idd256dd756829561c21bd9e1e693f2918f1e3247 Reviewed-by: Luca Beldi Reviewed-by: Samuel Gaist Reviewed-by: Mårten Nordheim --- src/corelib/tools/qvector.h | 139 ++++++++++++++++++++++++++++-------- 1 file changed, 110 insertions(+), 29 deletions(-) diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 778bcb3745..b51cd819c5 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -93,7 +93,13 @@ public: void reserve(int size); inline void squeeze() { - reallocData(d->size, d->size); + if (d->size < int(d->alloc)) { + if (!d->size) { + *this = QVector(); + return; + } + realloc(d->size); + } if (d->capacityReserved) { // capacity reserved in a read only memory would be useless // this checks avoid writing to such memory. @@ -296,9 +302,10 @@ public: inline std::vector toStdVector() const { return std::vector(d->begin(), d->end()); } private: - // ### Qt6: remove const from int parameters + // ### Qt6: remove methods, they are unused void reallocData(const int size, const int alloc, QArrayData::AllocationOptions options = QArrayData::Default); void reallocData(const int sz) { reallocData(sz, d->alloc); } + void realloc(int alloc, QArrayData::AllocationOptions options = QArrayData::Default); void freeData(Data *d); void defaultConstruct(T *from, T *to); void copyConstruct(const T *srcFrom, const T *srcTo, T *dstFrom); @@ -386,7 +393,7 @@ void QVector::detach() d = Data::unsharableEmpty(); else #endif - reallocData(d->size, int(d->alloc)); + realloc(int(d->alloc)); } Q_ASSERT(isDetached()); } @@ -395,7 +402,7 @@ template void QVector::reserve(int asize) { if (asize > int(d->alloc)) - reallocData(d->size, asize); + realloc(asize); if (isDetached() #if !defined(QT_NO_UNSHARABLE_CONTAINERS) && d != Data::unsharableEmpty() @@ -408,21 +415,26 @@ void QVector::reserve(int asize) template void QVector::resize(int asize) { - int newAlloc; - const int oldAlloc = int(d->alloc); - QArrayData::AllocationOptions opt; - - if (asize > oldAlloc) { // there is not enough space - newAlloc = asize; - opt = QArrayData::Grow; - } else { - newAlloc = oldAlloc; + if (asize == d->size) + return; + if (asize > int(d->alloc) || !isDetached()) { // there is not enough space + QArrayData::AllocationOptions opt = asize > int(d->alloc) ? QArrayData::Grow : QArrayData::Default; + realloc(qMax(int(d->alloc), asize), opt); } - reallocData(asize, newAlloc, opt); + if (asize < d->size) + destruct(begin() + asize, end()); + else + defaultConstruct(end(), begin() + asize); + d->size = asize; } template inline void QVector::clear() -{ resize(0); } +{ + if (!d->size) + return; + destruct(begin(), end()); + d->size = 0; +} template inline const T &QVector::at(int i) const { Q_ASSERT_X(i >= 0 && i < d->size, "QVector::at", "index out of range"); @@ -653,6 +665,77 @@ void QVector::reallocData(const int asize, const int aalloc, QArrayData::Allo Q_ASSERT(d->size == asize); } +template +void QVector::realloc(int aalloc, QArrayData::AllocationOptions options) +{ + Q_ASSERT(aalloc >= d->size); + Data *x = d; + + const bool isShared = d->ref.isShared(); + Q_ASSERT(aalloc != int(d->alloc) || isShared); + + QT_TRY { + // allocate memory + x = Data::allocate(aalloc, options); + Q_CHECK_PTR(x); + // aalloc is bigger then 0 so it is not [un]sharedEmpty +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) + Q_ASSERT(x->ref.isSharable() || options.testFlag(QArrayData::Unsharable)); +#endif + Q_ASSERT(!x->ref.isStatic()); + x->size = d->size; + + T *srcBegin = d->begin(); + T *srcEnd = d->end(); + T *dst = x->begin(); + + if (!QTypeInfoQuery::isRelocatable || (isShared && QTypeInfo::isComplex)) { + QT_TRY { + if (isShared || !std::is_nothrow_move_constructible::value) { + // we can not move the data, we need to copy construct it + while (srcBegin != srcEnd) + new (dst++) T(*srcBegin++); + } else { + while (srcBegin != srcEnd) + new (dst++) T(std::move(*srcBegin++)); + } + } QT_CATCH (...) { + // destruct already copied objects + destruct(x->begin(), dst); + QT_RETHROW; + } + } else { + ::memcpy(static_cast(dst), static_cast(srcBegin), (srcEnd - srcBegin) * sizeof(T)); + dst += srcEnd - srcBegin; + } + + } QT_CATCH (...) { + Data::deallocate(x); + QT_RETHROW; + } + x->capacityReserved = d->capacityReserved; + + Q_ASSERT(d != x); + if (!d->ref.deref()) { + if (!QTypeInfoQuery::isRelocatable || !aalloc || (isShared && QTypeInfo::isComplex)) { + // data was copy constructed, we need to call destructors + // or if !alloc we did nothing to the old 'd'. + freeData(d); + } else { + Data::deallocate(d); + } + } + d = x; + + Q_ASSERT(d->data()); + Q_ASSERT(uint(d->size) <= d->alloc); +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) + Q_ASSERT(d != Data::unsharableEmpty()); +#endif + Q_ASSERT(d != Data::sharedNull()); + Q_ASSERT(d->alloc >= uint(aalloc)); +} + #if defined(Q_CC_MSVC) QT_WARNING_POP #endif @@ -678,7 +761,7 @@ void QVector::append(const T &t) if (!isDetached() || isTooSmall) { T copy(t); QArrayData::AllocationOptions opt(isTooSmall ? QArrayData::Grow : QArrayData::Default); - reallocData(d->size, isTooSmall ? d->size + 1 : d->alloc, opt); + realloc(isTooSmall ? d->size + 1 : d->alloc, opt); if (QTypeInfo::isComplex) new (d->end()) T(qMove(copy)); @@ -701,7 +784,7 @@ void QVector::append(T &&t) const bool isTooSmall = uint(d->size + 1) > d->alloc; if (!isDetached() || isTooSmall) { QArrayData::AllocationOptions opt(isTooSmall ? QArrayData::Grow : QArrayData::Default); - reallocData(d->size, isTooSmall ? d->size + 1 : d->alloc, opt); + realloc(isTooSmall ? d->size + 1 : d->alloc, opt); } new (d->end()) T(std::move(t)); @@ -716,13 +799,11 @@ void QVector::removeLast() Q_ASSERT(!isEmpty()); Q_ASSERT(d->alloc); - if (!d->ref.isShared()) { - --d->size; - if (QTypeInfo::isComplex) - (d->data() + d->size)->~T(); - } else { - reallocData(d->size - 1); - } + if (d->ref.isShared()) + detach(); + --d->size; + if (QTypeInfo::isComplex) + (d->data() + d->size)->~T(); } template @@ -734,7 +815,7 @@ typename QVector::iterator QVector::insert(iterator before, size_type n, c if (n != 0) { const T copy(t); if (!isDetached() || d->size + n > int(d->alloc)) - reallocData(d->size, d->size + n, QArrayData::Grow); + realloc(d->size + n, QArrayData::Grow); if (!QTypeInfoQuery::isRelocatable) { T *b = d->end(); T *i = d->end() + n; @@ -767,7 +848,7 @@ typename QVector::iterator QVector::insert(iterator before, T &&t) const auto offset = std::distance(d->begin(), before); if (!isDetached() || d->size + 1 > int(d->alloc)) - reallocData(d->size, d->size + 1, QArrayData::Grow); + realloc(d->size + 1, QArrayData::Grow); if (!QTypeInfoQuery::isRelocatable) { T *i = d->end(); T *j = i + 1; @@ -869,14 +950,14 @@ QVector &QVector::fill(const T &from, int asize) template QVector &QVector::operator+=(const QVector &l) { - if (d == Data::sharedNull()) { + if (d->size == 0) { *this = l; } else { uint newSize = d->size + l.d->size; const bool isTooSmall = newSize > d->alloc; if (!isDetached() || isTooSmall) { QArrayData::AllocationOptions opt(isTooSmall ? QArrayData::Grow : QArrayData::Default); - reallocData(d->size, isTooSmall ? newSize : d->alloc, opt); + realloc(isTooSmall ? newSize : d->alloc, opt); } if (d->alloc) { @@ -959,7 +1040,7 @@ Q_OUTOFLINE_TEMPLATE QVector QVector::mid(int pos, int len) const } QVector midResult; - midResult.reallocData(0, len); + midResult.realloc(len); T *srcFrom = d->begin() + pos; T *srcTo = d->begin() + pos + len; midResult.copyConstruct(srcFrom, srcTo, midResult.data()); From 19863922558987136c320a08f46e3c3239094b7c Mon Sep 17 00:00:00 2001 From: Nick D'Ademo Date: Sat, 3 Nov 2018 20:11:53 +0800 Subject: [PATCH 0522/1650] QMdiArea: Do not move active subwindow after tile rearrange Currently, a tile rearrange will move the active subwindow (if any) to position zero (top-left). This ignores any tiling order set via setActivationOrder(). This change removes this move so that the set tiling order is respected when a tile operation is performed. Fixes: QTBUG-43356 Change-Id: I2c481f0ffe45e42e811c6b6d476eb4cb65aa5d1f Reviewed-by: Richard Moe Gustavsen --- src/widgets/widgets/qmdiarea.cpp | 8 -------- tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp | 10 ++++++---- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/widgets/widgets/qmdiarea.cpp b/src/widgets/widgets/qmdiarea.cpp index cdc1291511..104cbdbcda 100644 --- a/src/widgets/widgets/qmdiarea.cpp +++ b/src/widgets/widgets/qmdiarea.cpp @@ -954,14 +954,6 @@ void QMdiAreaPrivate::rearrange(Rearranger *rearranger) } } - if (active && rearranger->type() == Rearranger::RegularTiler && !tileCalledFromResizeEvent) { - // Move active window in front if necessary. That's the case if we - // have any windows with staysOnTopHint set. - int indexToActive = widgets.indexOf((QWidget *)active); - if (indexToActive > 0) - widgets.move(indexToActive, 0); - } - QRect domain = viewport->rect(); if (rearranger->type() == Rearranger::RegularTiler && !widgets.isEmpty()) domain = resizeToMinimumTileSize(minSubWindowSize, widgets.count()); diff --git a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp index 8b470fb579..67b79e3faf 100644 --- a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp +++ b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp @@ -1689,14 +1689,16 @@ void tst_QMdiArea::tileSubWindows() workspace.setActiveSubWindow(0); QVERIFY(workspace.viewport()->childrenRect() != workspace.viewport()->rect()); - // Make sure the active window is placed in top left corner regardless + // Make sure the active window does not move position after a tile regardless // of whether we have any windows with staysOnTopHint or not. + workspace.tileSubWindows(); windows.at(3)->setWindowFlags(windows.at(3)->windowFlags() | Qt::WindowStaysOnTopHint); QMdiSubWindow *activeSubWindow = windows.at(6); workspace.setActiveSubWindow(activeSubWindow); QCOMPARE(workspace.activeSubWindow(), activeSubWindow); + QPoint pos = activeSubWindow->geometry().topLeft(); workspace.tileSubWindows(); - QCOMPARE(activeSubWindow->geometry().topLeft(), QPoint(0, 0)); + QCOMPARE(activeSubWindow->geometry().topLeft(), pos); // Verify that we try to resize the area such that all sub-windows are visible. // It's important that tiled windows are NOT overlapping. @@ -2187,7 +2189,7 @@ void tst_QMdiArea::setActivationOrder_data() list << 2 << 1 << 0 << 1 << 2 << 3 << 4; list2 << 0 << 1 << 2 << 3 << 4; - list3 << 1 << 4 << 3 << 1 << 2 << 0; + list3 << 4 << 3 << 2 << 4 << 1 << 0; // Most recently created window is in top-left position QTest::newRow("CreationOrder") << QMdiArea::CreationOrder << 5 << 3 << 1 << list << list2 << list3; list = QList(); @@ -2195,7 +2197,7 @@ void tst_QMdiArea::setActivationOrder_data() list2 = QList(); list2 << 0 << 2 << 4 << 1 << 3; list3 = QList(); - list3 << 1 << 3 << 4 << 1 << 2 << 0; + list3 << 3 << 1 << 4 << 3 << 2 << 0; // Window with "stays-on-top" flag set will be in the top-left position QTest::newRow("StackingOrder") << QMdiArea::StackingOrder << 5 << 3 << 1 << list << list2 << list3; list = QList(); From 97d8be10cd97cf997286ed0ca0a5d8b360fa942e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Vr=C3=A1til?= Date: Sat, 1 Dec 2018 17:56:41 +0100 Subject: [PATCH 0523/1650] MySQL: Free the results when QSqlQuery::finished() is called Calling mysql_stmt_free_result() frees the results of the last executed query while keeping the prepared statement valid. This allows to keep around prepared QSqlQueries without the overhead of keeping all the results in memory. Change-Id: I4589e90857cc4e9a6f9612799bfca967a67e2ab2 Reviewed-by: Thiago Macieira Reviewed-by: Andy Shaw --- src/plugins/sqldrivers/mysql/qsql_mysql.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp index f2ae3fbc47..80c0c9c522 100644 --- a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp +++ b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp @@ -197,6 +197,7 @@ protected: QSqlRecord record() const override; void virtual_hook(int id, void *data) override; bool nextResult() override; + void detachFromResultSet() override; #if MYSQL_VERSION_ID >= 40108 bool prepare(const QString &stmt) override; @@ -804,6 +805,15 @@ int QMYSQLResult::numRowsAffected() return d->rowsAffected; } +void QMYSQLResult::detachFromResultSet() +{ + Q_D(QMYSQLResult); + + if (d->preparedQuery) { + mysql_stmt_free_result(d->stmt); + } +} + QVariant QMYSQLResult::lastInsertId() const { Q_D(const QMYSQLResult); From e61028281f44b0434c8e792235417cae3d1f49b0 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Wed, 21 Nov 2018 10:11:13 +0100 Subject: [PATCH 0524/1650] macOS accessibility: Rename parentElement to accessibilityParent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The NSAccessibility protocol has a property accessibilityParent. This adds the implementation. The protocol will be adopted in a follow-up commit. Change-Id: I648cdc201950159e8268743a7fcdd24beb58c1c6 Reviewed-by: Tor Arne Vestbø --- .../platforms/cocoa/qcocoaaccessibilityelement.mm | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index f9a03e5b58..f82662bdcb 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -241,7 +241,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of return [attributes autorelease]; } -- (id)parentElement { +- (id)accessibilityParent { QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); if (!iface || !iface->isValid()) return nil; @@ -254,7 +254,7 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of if (QAccessibleInterface *parent = iface->parent()) { if (parent->role() != QAccessible::Application) { QAccessible::Id parentId = QAccessible::uniqueId(parent); - return [QMacAccessibilityElement elementWithId: parentId]; + return NSAccessibilityUnignoredAncestor([QMacAccessibilityElement elementWithId: parentId]); } } @@ -262,13 +262,12 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of QPlatformWindow *platformWindow = window->handle(); if (platformWindow) { QCocoaWindow *win = static_cast(platformWindow); - return qnsview_cast(win->view()); + return NSAccessibilityUnignoredAncestor(qnsview_cast(win->view())); } } return nil; } - - (id) minValueAttribute:(QAccessibleInterface*)iface { if (QAccessibleValueInterface *val = iface->valueInterface()) return @(val->minimumValue().toDouble()); @@ -301,13 +300,13 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of id focusedElement = [NSApp accessibilityAttributeValue:NSAccessibilityFocusedUIElementAttribute]; return @([focusedElement isEqual:self]); } else if ([attribute isEqualToString:NSAccessibilityParentAttribute]) { - return NSAccessibilityUnignoredAncestor([self parentElement]); + return self.accessibilityParent; } else if ([attribute isEqualToString:NSAccessibilityWindowAttribute]) { // We're in the same window as our parent. - return [[self parentElement] accessibilityAttributeValue:NSAccessibilityWindowAttribute]; + return [[self accessibilityParent] accessibilityAttributeValue:NSAccessibilityWindowAttribute]; } else if ([attribute isEqualToString:NSAccessibilityTopLevelUIElementAttribute]) { // We're in the same top level element as our parent. - return [[self parentElement] accessibilityAttributeValue:NSAccessibilityTopLevelUIElementAttribute]; + return [[self accessibilityParent] accessibilityAttributeValue:NSAccessibilityTopLevelUIElementAttribute]; } else if ([attribute isEqualToString:NSAccessibilityPositionAttribute]) { // The position in points of the element's lower-left corner in screen-relative coordinates QPointF qtPosition = QRectF(iface->rect()).bottomLeft(); From dfcb7fce358269bb71e701efe17e5b3beddac951 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 11 Oct 2018 17:26:57 +0200 Subject: [PATCH 0525/1650] Test that mismatches of datatype in test data columns are rejected MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit One test for bad data for the column, another for a bad QFETCH. Incidentally extend blacklist testing by blacklisting them. Reorganise a QEMU condition that needed extended as part of this. Task-number: QTPM-1385 Change-Id: Iac72ada19760321c5c9264ddfff7740d1fdd0700 Reviewed-by: Jędrzej Nowacki --- .../selftests/expected_faildatatype.lightxml | 22 +++++++ .../selftests/expected_faildatatype.tap | 16 ++++++ .../selftests/expected_faildatatype.teamcity | 8 +++ .../selftests/expected_faildatatype.txt | 9 +++ .../selftests/expected_faildatatype.xml | 25 ++++++++ .../selftests/expected_faildatatype.xunitxml | 18 ++++++ .../selftests/expected_failfetchtype.lightxml | 21 +++++++ .../selftests/expected_failfetchtype.tap | 15 +++++ .../selftests/expected_failfetchtype.teamcity | 8 +++ .../selftests/expected_failfetchtype.txt | 8 +++ .../selftests/expected_failfetchtype.xml | 24 ++++++++ .../selftests/expected_failfetchtype.xunitxml | 16 ++++++ .../testlib/selftests/faildatatype/BLACKLIST | 4 ++ .../selftests/faildatatype/faildatatype.pro | 9 +++ .../faildatatype/tst_faildatatype.cpp | 57 +++++++++++++++++++ .../testlib/selftests/failfetchtype/BLACKLIST | 4 ++ .../selftests/failfetchtype/failfetchtype.pro | 9 +++ .../failfetchtype/tst_failfetchtype.cpp | 55 ++++++++++++++++++ .../selftests/generate_expected_output.py | 4 +- tests/auto/testlib/selftests/selftests.pri | 2 + .../auto/testlib/selftests/tst_selftests.cpp | 23 +++++--- 21 files changed, 347 insertions(+), 10 deletions(-) create mode 100644 tests/auto/testlib/selftests/expected_faildatatype.lightxml create mode 100644 tests/auto/testlib/selftests/expected_faildatatype.tap create mode 100644 tests/auto/testlib/selftests/expected_faildatatype.teamcity create mode 100644 tests/auto/testlib/selftests/expected_faildatatype.txt create mode 100644 tests/auto/testlib/selftests/expected_faildatatype.xml create mode 100644 tests/auto/testlib/selftests/expected_faildatatype.xunitxml create mode 100644 tests/auto/testlib/selftests/expected_failfetchtype.lightxml create mode 100644 tests/auto/testlib/selftests/expected_failfetchtype.tap create mode 100644 tests/auto/testlib/selftests/expected_failfetchtype.teamcity create mode 100644 tests/auto/testlib/selftests/expected_failfetchtype.txt create mode 100644 tests/auto/testlib/selftests/expected_failfetchtype.xml create mode 100644 tests/auto/testlib/selftests/expected_failfetchtype.xunitxml create mode 100644 tests/auto/testlib/selftests/faildatatype/BLACKLIST create mode 100644 tests/auto/testlib/selftests/faildatatype/faildatatype.pro create mode 100644 tests/auto/testlib/selftests/faildatatype/tst_faildatatype.cpp create mode 100644 tests/auto/testlib/selftests/failfetchtype/BLACKLIST create mode 100644 tests/auto/testlib/selftests/failfetchtype/failfetchtype.pro create mode 100644 tests/auto/testlib/selftests/failfetchtype/tst_failfetchtype.cpp diff --git a/tests/auto/testlib/selftests/expected_faildatatype.lightxml b/tests/auto/testlib/selftests/expected_faildatatype.lightxml new file mode 100644 index 0000000000..24992b78af --- /dev/null +++ b/tests/auto/testlib/selftests/expected_faildatatype.lightxml @@ -0,0 +1,22 @@ + + @INSERT_QT_VERSION_HERE@ + + @INSERT_QT_VERSION_HERE@ + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/testlib/selftests/expected_faildatatype.tap b/tests/auto/testlib/selftests/expected_faildatatype.tap new file mode 100644 index 0000000000..684cea4126 --- /dev/null +++ b/tests/auto/testlib/selftests/expected_faildatatype.tap @@ -0,0 +1,16 @@ +TAP version 13 +# tst_FailDataType +ok 1 - initTestCase() +# expected data of type 'QString', got 'bool' for element 0 of data with tag 'bool-as-string' +# ASSERT: "false" in file qtbase/src/testlib/qtestdata.cpp, line 0 +not ok 2 - value() + --- + # Received a fatal error. + at: tst_FailDataType::value() (Unknown file:0) + file: Unknown file + line: 0 + ... +1..2 +# tests 2 +# pass 1 +# fail 1 diff --git a/tests/auto/testlib/selftests/expected_faildatatype.teamcity b/tests/auto/testlib/selftests/expected_faildatatype.teamcity new file mode 100644 index 0000000000..82731ae09e --- /dev/null +++ b/tests/auto/testlib/selftests/expected_faildatatype.teamcity @@ -0,0 +1,8 @@ +##teamcity[testSuiteStarted name='tst_FailDataType' flowId='tst_FailDataType'] +##teamcity[testStarted name='initTestCase()' flowId='tst_FailDataType'] +##teamcity[testFinished name='initTestCase()' flowId='tst_FailDataType'] +##teamcity[testStarted name='value()' flowId='tst_FailDataType'] +##teamcity[testFailed name='value()' message='Failure! |[Loc: Unknown file(0)|]' details='Received a fatal error.' flowId='tst_FailDataType'] +##teamcity[testStdOut name='value()' out='QDEBUG: expected data of type |'QString|', got |'bool|' for element 0 of data with tag |'bool-as-string|'|nQFATAL: ASSERT: "false" in file qtbase/src/testlib/qtestdata.cpp, line 0' flowId='tst_FailDataType'] +##teamcity[testFinished name='value()' flowId='tst_FailDataType'] +##teamcity[testSuiteFinished name='tst_FailDataType' flowId='tst_FailDataType'] diff --git a/tests/auto/testlib/selftests/expected_faildatatype.txt b/tests/auto/testlib/selftests/expected_faildatatype.txt new file mode 100644 index 0000000000..4cfe3b7654 --- /dev/null +++ b/tests/auto/testlib/selftests/expected_faildatatype.txt @@ -0,0 +1,9 @@ +********* Start testing of tst_FailDataType ********* +Config: Using QtTest library +PASS : tst_FailDataType::initTestCase() +QDEBUG : tst_FailDataType::value() expected data of type 'QString', got 'bool' for element 0 of data with tag 'bool-as-string' +QFATAL : tst_FailDataType::value() ASSERT: "false" in file qtbase/src/testlib/qtestdata.cpp, line 0 +FAIL! : tst_FailDataType::value() Received a fatal error. + Loc: [Unknown file(0)] +Totals: 1 passed, 1 failed, 0 skipped, 0 blacklisted, 0ms +********* Finished testing of tst_FailDataType ********* diff --git a/tests/auto/testlib/selftests/expected_faildatatype.xml b/tests/auto/testlib/selftests/expected_faildatatype.xml new file mode 100644 index 0000000000..8812bfab71 --- /dev/null +++ b/tests/auto/testlib/selftests/expected_faildatatype.xml @@ -0,0 +1,25 @@ + + + + @INSERT_QT_VERSION_HERE@ + + @INSERT_QT_VERSION_HERE@ + + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/testlib/selftests/expected_faildatatype.xunitxml b/tests/auto/testlib/selftests/expected_faildatatype.xunitxml new file mode 100644 index 0000000000..fcc0db3892 --- /dev/null +++ b/tests/auto/testlib/selftests/expected_faildatatype.xunitxml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/testlib/selftests/expected_failfetchtype.lightxml b/tests/auto/testlib/selftests/expected_failfetchtype.lightxml new file mode 100644 index 0000000000..f7c84a1876 --- /dev/null +++ b/tests/auto/testlib/selftests/expected_failfetchtype.lightxml @@ -0,0 +1,21 @@ + + @INSERT_QT_VERSION_HERE@ + + @INSERT_QT_VERSION_HERE@ + + + + + + + + + + + + + + + + + diff --git a/tests/auto/testlib/selftests/expected_failfetchtype.tap b/tests/auto/testlib/selftests/expected_failfetchtype.tap new file mode 100644 index 0000000000..94c3b6e1b2 --- /dev/null +++ b/tests/auto/testlib/selftests/expected_failfetchtype.tap @@ -0,0 +1,15 @@ +TAP version 13 +# tst_FailFetchType +ok 1 - initTestCase() +# Requested type 'QString' does not match available type 'bool'. +not ok 2 - fetch(bool) + --- + # Received a fatal error. + at: tst_FailFetchType::fetch() (Unknown file:0) + file: Unknown file + line: 0 + ... +1..2 +# tests 2 +# pass 1 +# fail 1 diff --git a/tests/auto/testlib/selftests/expected_failfetchtype.teamcity b/tests/auto/testlib/selftests/expected_failfetchtype.teamcity new file mode 100644 index 0000000000..91cf0c6ae8 --- /dev/null +++ b/tests/auto/testlib/selftests/expected_failfetchtype.teamcity @@ -0,0 +1,8 @@ +##teamcity[testSuiteStarted name='tst_FailFetchType' flowId='tst_FailFetchType'] +##teamcity[testStarted name='initTestCase()' flowId='tst_FailFetchType'] +##teamcity[testFinished name='initTestCase()' flowId='tst_FailFetchType'] +##teamcity[testStarted name='fetch(bool)' flowId='tst_FailFetchType'] +##teamcity[testFailed name='fetch(bool)' message='Failure! |[Loc: Unknown file(0)|]' details='Received a fatal error.' flowId='tst_FailFetchType'] +##teamcity[testStdOut name='fetch(bool)' out='QFATAL: Requested type |'QString|' does not match available type |'bool|'.' flowId='tst_FailFetchType'] +##teamcity[testFinished name='fetch(bool)' flowId='tst_FailFetchType'] +##teamcity[testSuiteFinished name='tst_FailFetchType' flowId='tst_FailFetchType'] diff --git a/tests/auto/testlib/selftests/expected_failfetchtype.txt b/tests/auto/testlib/selftests/expected_failfetchtype.txt new file mode 100644 index 0000000000..d12cf0dc7d --- /dev/null +++ b/tests/auto/testlib/selftests/expected_failfetchtype.txt @@ -0,0 +1,8 @@ +********* Start testing of tst_FailFetchType ********* +Config: Using QtTest library +PASS : tst_FailFetchType::initTestCase() +QFATAL : tst_FailFetchType::fetch(bool) Requested type 'QString' does not match available type 'bool'. +FAIL! : tst_FailFetchType::fetch(bool) Received a fatal error. + Loc: [Unknown file(0)] +Totals: 1 passed, 1 failed, 0 skipped, 0 blacklisted, 0ms +********* Finished testing of tst_FailFetchType ********* diff --git a/tests/auto/testlib/selftests/expected_failfetchtype.xml b/tests/auto/testlib/selftests/expected_failfetchtype.xml new file mode 100644 index 0000000000..a349baa710 --- /dev/null +++ b/tests/auto/testlib/selftests/expected_failfetchtype.xml @@ -0,0 +1,24 @@ + + + + @INSERT_QT_VERSION_HERE@ + + @INSERT_QT_VERSION_HERE@ + + + + + + + + + + + + + + + + + + diff --git a/tests/auto/testlib/selftests/expected_failfetchtype.xunitxml b/tests/auto/testlib/selftests/expected_failfetchtype.xunitxml new file mode 100644 index 0000000000..a54a37a913 --- /dev/null +++ b/tests/auto/testlib/selftests/expected_failfetchtype.xunitxml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/tests/auto/testlib/selftests/faildatatype/BLACKLIST b/tests/auto/testlib/selftests/faildatatype/BLACKLIST new file mode 100644 index 0000000000..bb1cae98e5 --- /dev/null +++ b/tests/auto/testlib/selftests/faildatatype/BLACKLIST @@ -0,0 +1,4 @@ +# See qtbase/src/testlib/qtestblacklist.cpp for format +# Incidental test: exercise more of the blacklisting code +[value:bool-as-string] +* diff --git a/tests/auto/testlib/selftests/faildatatype/faildatatype.pro b/tests/auto/testlib/selftests/faildatatype/faildatatype.pro new file mode 100644 index 0000000000..4ff7352555 --- /dev/null +++ b/tests/auto/testlib/selftests/faildatatype/faildatatype.pro @@ -0,0 +1,9 @@ +SOURCES += tst_faildatatype.cpp +QT = core testlib + +darwin: CONFIG -= app_bundle +CONFIG -= debug_and_release_target + +TARGET = faildatatype + +include($$QT_SOURCE_TREE/src/testlib/selfcover.pri) diff --git a/tests/auto/testlib/selftests/faildatatype/tst_faildatatype.cpp b/tests/auto/testlib/selftests/faildatatype/tst_faildatatype.cpp new file mode 100644 index 0000000000..b49c7723ef --- /dev/null +++ b/tests/auto/testlib/selftests/faildatatype/tst_faildatatype.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include + +class tst_FailDataType: public QObject +{ +Q_OBJECT +private slots: + void value_data() const; + void value() const; +}; + +void tst_FailDataType::value_data() const +{ + QTest::addColumn("value"); + + QTest::newRow("bool-as-string") << true; // assertion should fail here +} + +/*! \internal + This function should never be run because its _data() fails. + */ +void tst_FailDataType::value() const +{ + QFAIL("ERROR: this function is NOT supposed to be run."); +} + +QTEST_APPLESS_MAIN(tst_FailDataType) + +#include "tst_faildatatype.moc" diff --git a/tests/auto/testlib/selftests/failfetchtype/BLACKLIST b/tests/auto/testlib/selftests/failfetchtype/BLACKLIST new file mode 100644 index 0000000000..20a502724a --- /dev/null +++ b/tests/auto/testlib/selftests/failfetchtype/BLACKLIST @@ -0,0 +1,4 @@ +# See qtbase/src/testlib/qtestblacklist.cpp for format +# Incidental test: exercise more of the blacklisting code +[fetch:no-such-dataset] +* diff --git a/tests/auto/testlib/selftests/failfetchtype/failfetchtype.pro b/tests/auto/testlib/selftests/failfetchtype/failfetchtype.pro new file mode 100644 index 0000000000..5821018af4 --- /dev/null +++ b/tests/auto/testlib/selftests/failfetchtype/failfetchtype.pro @@ -0,0 +1,9 @@ +SOURCES += tst_failfetchtype.cpp +QT = core testlib + +darwin: CONFIG -= app_bundle +CONFIG -= debug_and_release_target + +TARGET = failfetchtype + +include($$QT_SOURCE_TREE/src/testlib/selfcover.pri) diff --git a/tests/auto/testlib/selftests/failfetchtype/tst_failfetchtype.cpp b/tests/auto/testlib/selftests/failfetchtype/tst_failfetchtype.cpp new file mode 100644 index 0000000000..2dd32a5a5e --- /dev/null +++ b/tests/auto/testlib/selftests/failfetchtype/tst_failfetchtype.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include + +class tst_FailFetchType: public QObject +{ +Q_OBJECT +private slots: + void fetch_data() const; + void fetch() const; +}; + +void tst_FailFetchType::fetch_data() const +{ + QTest::addColumn("value"); + + QTest::newRow("bool") << true; +} + +void tst_FailFetchType::fetch() const +{ + QFETCH(QString, value); // assertion should fail here + QFAIL("ERROR: this function is NOT supposed to be run."); +} + +QTEST_APPLESS_MAIN(tst_FailFetchType) + +#include "tst_failfetchtype.moc" diff --git a/tests/auto/testlib/selftests/generate_expected_output.py b/tests/auto/testlib/selftests/generate_expected_output.py index 3c5f922c75..cbec0c4ebf 100755 --- a/tests/auto/testlib/selftests/generate_expected_output.py +++ b/tests/auto/testlib/selftests/generate_expected_output.py @@ -244,8 +244,8 @@ def generateTestData(testname, clean, }, # These are actually *other* crashers, beside those in extraEnv; # must match tst_Selftests::runSubTest_data(): - crashers = ("assert", "blacklisted", "crashedterminate", - "exceptionthrow", "fetchbogus", "silent")): + crashers = ("assert", "blacklisted", "crashedterminate", "exceptionthrow", + "faildatatype", "failfetchtype", "fetchbogus", "silent")): """Run one test and save its cleaned results. Required arguments are the name of the test directory (the binary diff --git a/tests/auto/testlib/selftests/selftests.pri b/tests/auto/testlib/selftests/selftests.pri index 05ed6d9905..08d6d633f0 100644 --- a/tests/auto/testlib/selftests/selftests.pri +++ b/tests/auto/testlib/selftests/selftests.pri @@ -21,6 +21,8 @@ SUBPROGRAMS = \ exceptionthrow \ expectfail \ failcleanup \ + faildatatype \ + failfetchtype \ failinit \ failinitdata \ fetchbogus \ diff --git a/tests/auto/testlib/selftests/tst_selftests.cpp b/tests/auto/testlib/selftests/tst_selftests.cpp index f460ca3963..5c97ad01d1 100644 --- a/tests/auto/testlib/selftests/tst_selftests.cpp +++ b/tests/auto/testlib/selftests/tst_selftests.cpp @@ -468,10 +468,13 @@ void tst_Selftests::runSubTest_data() #endif << "expectfail" << "failcleanup" +#ifndef Q_OS_WIN // these assert, by design; so same problem as "assert" + << "faildatatype" + << "failfetchtype" +#endif << "failinit" << "failinitdata" -#if !defined(Q_OS_WIN) - // Disable this test on Windows, as the run-time will popup dialogs with warnings +#ifndef Q_OS_WIN // asserts, by design; so same problem as "assert" << "fetchbogus" #endif << "findtestdata" @@ -616,6 +619,7 @@ void tst_Selftests::runSubTest_data() // Keep in sync with generateTestData()'s crashers in generate_expected_output.py: const bool crashes = subtest == QLatin1String("assert") || subtest == QLatin1String("exceptionthrow") || subtest == QLatin1String("fetchbogus") || subtest == QLatin1String("crashedterminate") + || subtest == QLatin1String("faildatatype") || subtest == QLatin1String("failfetchtype") || subtest == QLatin1String("crashes") || subtest == QLatin1String("silent") || subtest == QLatin1String("blacklisted"); QTest::newRow(qPrintable(QString("%1 %2").arg(subtest).arg(loggerSet.name))) @@ -745,11 +749,13 @@ void tst_Selftests::doRunSubTest(QString const& subdir, QStringList const& logge #endif #ifdef Q_OS_LINUX // QEMU outputs to stderr about uncaught signals - && (!EmulationDetector::isRunningArmOnX86() || - (subdir != QLatin1String("blacklisted") - && subdir != QLatin1String("silent") - && subdir != QLatin1String("assert") - && subdir != QLatin1String("crashes") + && !(EmulationDetector::isRunningArmOnX86() && + (subdir == QLatin1String("assert") + || subdir == QLatin1String("blacklisted") + || subdir == QLatin1String("crashes") + || subdir == QLatin1String("faildatatype") + || subdir == QLatin1String("failfetchtype") + || subdir == QLatin1String("silent") ) ) #endif @@ -902,7 +908,8 @@ bool tst_Selftests::compareLine(const QString &logger, const QString &subdir, if (actualLine == expectedLine) return true; - if (subdir == QLatin1String("assert") + if ((subdir == QLatin1String("assert") + || subdir == QLatin1String("faildatatype") || subdir == QLatin1String("failfetchtype")) && actualLine.contains(QLatin1String("ASSERT: ")) && expectedLine.contains(QLatin1String("ASSERT: "))) { // Q_ASSERT uses __FILE__, the exact contents of which are From c3e6551d4d6712668e5fc8e307b3425db80af96d Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 13 Nov 2018 20:10:19 +0100 Subject: [PATCH 0526/1650] generate_expected_output.py: refine environment used for subtests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Match the environment tst_selftests.cpp uses for subtests more faithfully. Extends b22e50acda. In the process, tweak how crashers are handling, in preparation for the watchdog test. Change-Id: I09a046460f6f3bff0b12069fad6c1437d89572ce Reviewed-by: Jędrzej Nowacki --- .../selftests/generate_expected_output.py | 90 +++++++++++++------ 1 file changed, 64 insertions(+), 26 deletions(-) diff --git a/tests/auto/testlib/selftests/generate_expected_output.py b/tests/auto/testlib/selftests/generate_expected_output.py index cbec0c4ebf..175b5756a3 100755 --- a/tests/auto/testlib/selftests/generate_expected_output.py +++ b/tests/auto/testlib/selftests/generate_expected_output.py @@ -221,6 +221,65 @@ class Scanner (object): print('tst_selftests.cpp names', d, "as a test, but it doesn't exist") del re +# Keep in sync with tst_selftests.cpp's processEnvironment(): +def baseEnv(platname=None, + keep=('PATH', 'QT_QPA_PLATFORM'), + posix=('HOME', 'USER', 'QEMU_SET_ENV', 'QEMU_LD_PREFIX'), + nonapple=('DISPLAY', 'XAUTHLOCALHOSTNAME'), # and XDG_* + # Don't actually know how to test for QNX, so this is ignored: + qnx=('GRAPHICS_ROOT', 'TZ'), + # Probably not actually relevant + preserveLib=('QT_PLUGIN_PATH', 'LD_LIBRARY_PATH'), + # Shall be modified on first call (a *copy* is returned): + cached={}): + """Lazily-evaluated standard environment for sub-tests to run in. + + This prunes the parent process environment, selecting a only those + variables we chose to keep. The platname passed to the first call + helps select which variables to keep. The environment computed + then is cached: a copy of this is returned on that call and each + subsequent call.\n""" + + if not cached: + xdg = False + # The platform module may be more apt for the platform tests here. + if os.name == 'posix': + keep += posix + if platname != 'darwin': + keep += nonapple + xdg = True + if 'QT_PRESERVE_TESTLIB_PATH' in os.environ: + keep += preserveLib + + cached = dict( + LC_ALL = 'C', # Use standard locale + # Avoid interference from any qtlogging.ini files, e.g. in + # /etc/xdg/QtProject/, (must match tst_selftests.cpp's + # processEnvironment()'s value): + QT_LOGGING_RULES = '*.debug=true;qt.*=false') + + for k, v in os.environ.items(): + if k in keep or (xdg and k.startswith('XDG_')): + cached[k] = v + + return cached.copy() + +def testEnv(testname, + # Make sure this matches tst_Selftests::doRunSubTest(): + extraEnv = { + "crashers": { "QTEST_DISABLE_CORE_DUMP": "1", "QTEST_DISABLE_STACK_DUMP": "1" }, + }, + # Must match tst_Selftests::runSubTest_data(): + crashers = ("assert", "blacklisted", "crashes", "crashedterminate", "exceptionthrow", + "faildatatype", "failfetchtype", "fetchbogus", "silent")): + """Determine the environment in which to run a test.""" + data = baseEnv() + if testname in crashers: + data.update(extraEnv["crashers"]) + if testname in extraEnv: + data.update(extraEnv[testname]) + return data + def generateTestData(testname, clean, formats = ('xml', 'txt', 'xunitxml', 'lightxml', 'teamcity', 'tap'), # Make sure this matches tst_Selftests::runSubTest_data(): @@ -237,15 +296,7 @@ def generateTestData(testname, clean, "silent": "-silent", "verbose1": "-v1", "verbose2": "-v2", - }, - # Make sure this matches tst_Selftests::doRunSubTest(): - extraEnv = { - "crashes": { "QTEST_DISABLE_CORE_DUMP": "1", "QTEST_DISABLE_STACK_DUMP": "1" }, - }, - # These are actually *other* crashers, beside those in extraEnv; - # must match tst_Selftests::runSubTest_data(): - crashers = ("assert", "blacklisted", "crashedterminate", "exceptionthrow", - "faildatatype", "failfetchtype", "fetchbogus", "silent")): + }): """Run one test and save its cleaned results. Required arguments are the name of the test directory (the binary @@ -257,16 +308,9 @@ def generateTestData(testname, clean, if not os.path.isfile(path): print("Warning: directory", testname, "contains no test executable") return - env = None - try: - env = extraEnv[testname] - except KeyError: - if env in crashers: - env = extraEnv["crashes"] - if env: - data = os.environ.copy() - data.update(env) - env = data + + # Prepare environment in which to run tests: + env = testEnv(testname) print(" running", testname) for format in formats: @@ -281,13 +325,6 @@ def generateTestData(testname, clean, def main(name, *args): """Minimal argument parsing and driver for the real work""" - os.environ.update( - LC_ALL = 'C', # Use standard locale - # Avoid interference from any qtlogging.ini files, e.g. in - # /etc/xdg/QtProject/, (must match tst_selftests.cpp's - # processEnvironment()'s value): - QT_LOGGING_RULES = '*.debug=true;qt.*=false') - herePath = os.getcwd() cleaner = Cleaner(herePath, name) @@ -299,6 +336,7 @@ def main(name, *args): if __name__ == '__main__': # Executed when script is run, not when imported (e.g. to debug) import sys + baseEnv(sys.platform) # initializes its cache if sys.platform.startswith('win'): print("This script does not work on Windows.") From 7c7e007794fb6dc34c7c816732d2ba0a911e488c Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 15 Oct 2018 17:47:42 +0200 Subject: [PATCH 0527/1650] Add a testlib selftest for the watchdog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Verify that it does cut in after the specified time has elapsed. Task-number: QTPM-1385 Change-Id: Ib18e8d6af28339f79cca4d62b869287ce07b8cc1 Reviewed-by: Jędrzej Nowacki --- .../selftests/expected_watchdog.lightxml | 19 +++++++ .../testlib/selftests/expected_watchdog.tap | 15 ++++++ .../selftests/expected_watchdog.teamcity | 8 +++ .../testlib/selftests/expected_watchdog.txt | 8 +++ .../testlib/selftests/expected_watchdog.xml | 22 ++++++++ .../selftests/expected_watchdog.xunitxml | 16 ++++++ .../selftests/generate_expected_output.py | 9 ++-- tests/auto/testlib/selftests/selftests.pri | 1 + .../auto/testlib/selftests/tst_selftests.cpp | 6 ++- .../selftests/watchdog/tst_watchdog.cpp | 51 +++++++++++++++++++ .../testlib/selftests/watchdog/watchdog.pro | 14 +++++ 11 files changed, 165 insertions(+), 4 deletions(-) create mode 100644 tests/auto/testlib/selftests/expected_watchdog.lightxml create mode 100644 tests/auto/testlib/selftests/expected_watchdog.tap create mode 100644 tests/auto/testlib/selftests/expected_watchdog.teamcity create mode 100644 tests/auto/testlib/selftests/expected_watchdog.txt create mode 100644 tests/auto/testlib/selftests/expected_watchdog.xml create mode 100644 tests/auto/testlib/selftests/expected_watchdog.xunitxml create mode 100644 tests/auto/testlib/selftests/watchdog/tst_watchdog.cpp create mode 100644 tests/auto/testlib/selftests/watchdog/watchdog.pro diff --git a/tests/auto/testlib/selftests/expected_watchdog.lightxml b/tests/auto/testlib/selftests/expected_watchdog.lightxml new file mode 100644 index 0000000000..1070324f2a --- /dev/null +++ b/tests/auto/testlib/selftests/expected_watchdog.lightxml @@ -0,0 +1,19 @@ + + @INSERT_QT_VERSION_HERE@ + + @INSERT_QT_VERSION_HERE@ + + + + + + + + + + + + + + + diff --git a/tests/auto/testlib/selftests/expected_watchdog.tap b/tests/auto/testlib/selftests/expected_watchdog.tap new file mode 100644 index 0000000000..3d4890b67e --- /dev/null +++ b/tests/auto/testlib/selftests/expected_watchdog.tap @@ -0,0 +1,15 @@ +TAP version 13 +# tst_Watchdog +ok 1 - initTestCase() +# Test function timed out +not ok 2 - delay() + --- + # Received a fatal error. + at: tst_Watchdog::delay() (Unknown file:0) + file: Unknown file + line: 0 + ... +1..2 +# tests 2 +# pass 1 +# fail 1 diff --git a/tests/auto/testlib/selftests/expected_watchdog.teamcity b/tests/auto/testlib/selftests/expected_watchdog.teamcity new file mode 100644 index 0000000000..0d77bf70d5 --- /dev/null +++ b/tests/auto/testlib/selftests/expected_watchdog.teamcity @@ -0,0 +1,8 @@ +##teamcity[testSuiteStarted name='tst_Watchdog' flowId='tst_Watchdog'] +##teamcity[testStarted name='initTestCase()' flowId='tst_Watchdog'] +##teamcity[testFinished name='initTestCase()' flowId='tst_Watchdog'] +##teamcity[testStarted name='delay()' flowId='tst_Watchdog'] +##teamcity[testFailed name='delay()' message='Failure! |[Loc: Unknown file(0)|]' details='Received a fatal error.' flowId='tst_Watchdog'] +##teamcity[testStdOut name='delay()' out='QFATAL: Test function timed out' flowId='tst_Watchdog'] +##teamcity[testFinished name='delay()' flowId='tst_Watchdog'] +##teamcity[testSuiteFinished name='tst_Watchdog' flowId='tst_Watchdog'] diff --git a/tests/auto/testlib/selftests/expected_watchdog.txt b/tests/auto/testlib/selftests/expected_watchdog.txt new file mode 100644 index 0000000000..4c9cde4ea2 --- /dev/null +++ b/tests/auto/testlib/selftests/expected_watchdog.txt @@ -0,0 +1,8 @@ +********* Start testing of tst_Watchdog ********* +Config: Using QtTest library +PASS : tst_Watchdog::initTestCase() +QFATAL : tst_Watchdog::delay() Test function timed out +FAIL! : tst_Watchdog::delay() Received a fatal error. + Loc: [Unknown file(0)] +Totals: 1 passed, 1 failed, 0 skipped, 0 blacklisted, 0ms +********* Finished testing of tst_Watchdog ********* diff --git a/tests/auto/testlib/selftests/expected_watchdog.xml b/tests/auto/testlib/selftests/expected_watchdog.xml new file mode 100644 index 0000000000..f1642fba79 --- /dev/null +++ b/tests/auto/testlib/selftests/expected_watchdog.xml @@ -0,0 +1,22 @@ + + + + @INSERT_QT_VERSION_HERE@ + + @INSERT_QT_VERSION_HERE@ + + + + + + + + + + + + + + + + diff --git a/tests/auto/testlib/selftests/expected_watchdog.xunitxml b/tests/auto/testlib/selftests/expected_watchdog.xunitxml new file mode 100644 index 0000000000..7e16ab2c34 --- /dev/null +++ b/tests/auto/testlib/selftests/expected_watchdog.xunitxml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/tests/auto/testlib/selftests/generate_expected_output.py b/tests/auto/testlib/selftests/generate_expected_output.py index 175b5756a3..92588c614d 100755 --- a/tests/auto/testlib/selftests/generate_expected_output.py +++ b/tests/auto/testlib/selftests/generate_expected_output.py @@ -267,11 +267,14 @@ def baseEnv(platname=None, def testEnv(testname, # Make sure this matches tst_Selftests::doRunSubTest(): extraEnv = { - "crashers": { "QTEST_DISABLE_CORE_DUMP": "1", "QTEST_DISABLE_STACK_DUMP": "1" }, + "crashers": { "QTEST_DISABLE_CORE_DUMP": "1", + "QTEST_DISABLE_STACK_DUMP": "1" }, + "watchdog": { "QTEST_FUNCTION_TIMEOUT": "100" }, }, # Must match tst_Selftests::runSubTest_data(): - crashers = ("assert", "blacklisted", "crashes", "crashedterminate", "exceptionthrow", - "faildatatype", "failfetchtype", "fetchbogus", "silent")): + crashers = ("assert", "blacklisted", "crashes", "crashedterminate", + "exceptionthrow", "faildatatype", "failfetchtype", + "fetchbogus", "silent", "watchdog")): """Determine the environment in which to run a test.""" data = baseEnv() if testname in crashers: diff --git a/tests/auto/testlib/selftests/selftests.pri b/tests/auto/testlib/selftests/selftests.pri index 08d6d633f0..bc5a74a20a 100644 --- a/tests/auto/testlib/selftests/selftests.pri +++ b/tests/auto/testlib/selftests/selftests.pri @@ -50,6 +50,7 @@ SUBPROGRAMS = \ verbose2 \ verifyexceptionthrown \ warnings \ + watchdog \ xunit qtHaveModule(gui): SUBPROGRAMS += \ diff --git a/tests/auto/testlib/selftests/tst_selftests.cpp b/tests/auto/testlib/selftests/tst_selftests.cpp index 5c97ad01d1..a5094c8b9e 100644 --- a/tests/auto/testlib/selftests/tst_selftests.cpp +++ b/tests/auto/testlib/selftests/tst_selftests.cpp @@ -505,6 +505,7 @@ void tst_Selftests::runSubTest_data() << "verifyexceptionthrown" #endif //!QT_NO_EXCEPTIONS << "warnings" + << "watchdog" << "xunit" ; @@ -621,7 +622,7 @@ void tst_Selftests::runSubTest_data() || subtest == QLatin1String("fetchbogus") || subtest == QLatin1String("crashedterminate") || subtest == QLatin1String("faildatatype") || subtest == QLatin1String("failfetchtype") || subtest == QLatin1String("crashes") || subtest == QLatin1String("silent") - || subtest == QLatin1String("blacklisted"); + || subtest == QLatin1String("blacklisted") || subtest == QLatin1String("watchdog"); QTest::newRow(qPrintable(QString("%1 %2").arg(subtest).arg(loggerSet.name))) << subtest << loggers @@ -700,6 +701,8 @@ void tst_Selftests::doRunSubTest(QString const& subdir, QStringList const& logge if (crashes) { environment.insert("QTEST_DISABLE_CORE_DUMP", "1"); environment.insert("QTEST_DISABLE_STACK_DUMP", "1"); + if (subdir == QLatin1String("watchdog")) + environment.insert("QTEST_FUNCTION_TIMEOUT", "100"); } proc.setProcessEnvironment(environment); const QString path = subdir + QLatin1Char('/') + subdir; @@ -742,6 +745,7 @@ void tst_Selftests::doRunSubTest(QString const& subdir, QStringList const& logge if (subdir != QLatin1String("exceptionthrow") && subdir != QLatin1String("cmptest") // QImage comparison requires QGuiApplication && subdir != QLatin1String("fetchbogus") + && subdir != QLatin1String("watchdog") && subdir != QLatin1String("xunit") #ifdef Q_CC_MINGW && subdir != QLatin1String("blacklisted") // calls qFatal() diff --git a/tests/auto/testlib/selftests/watchdog/tst_watchdog.cpp b/tests/auto/testlib/selftests/watchdog/tst_watchdog.cpp new file mode 100644 index 0000000000..2f29609f71 --- /dev/null +++ b/tests/auto/testlib/selftests/watchdog/tst_watchdog.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +class tst_Watchdog : public QObject +{ + Q_OBJECT +private slots: + void delay() const; +}; + +void tst_Watchdog::delay() const +{ + bool ok = false; + const int fiveMinutes = 5 * 60 * 1000; + // Use the same env.var as the watch-dog and add a little to it: + const int timeout = qEnvironmentVariableIntValue("QTEST_FUNCTION_TIMEOUT", &ok); + QTest::qSleep(5000 + (ok && timeout > 0 ? timeout : fiveMinutes)); + // The watchdog timer should have interrupted us by now. + QFAIL("ERROR: this function should be interrupted."); +} + +QTEST_APPLESS_MAIN(tst_Watchdog) + +#include "tst_watchdog.moc" diff --git a/tests/auto/testlib/selftests/watchdog/watchdog.pro b/tests/auto/testlib/selftests/watchdog/watchdog.pro new file mode 100644 index 0000000000..ddcc3f6ca2 --- /dev/null +++ b/tests/auto/testlib/selftests/watchdog/watchdog.pro @@ -0,0 +1,14 @@ +SOURCES += tst_watchdog.cpp +QT = core testlib + +darwin: CONFIG -= app_bundle +CONFIG -= debug_and_release_target + +TARGET = watchdog + +# The test deliberately times out; so tell it to do so quickly +checkenv.name = QTEST_FUNCTION_TIMEOUT +checkenv.value = 100 +QT_TOOL_ENV += checkenv + +include($$QT_SOURCE_TREE/src/testlib/selfcover.pri) From 4da0c669d3b942003d6d6b88b8cebcf5d8df1967 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 3 Dec 2018 11:47:04 +0100 Subject: [PATCH 0528/1650] QTextCodec::codecForLocale(): clarify and update documentation Change-Id: If3eec8cfc90cadcbd418807891ccf19b796f4006 Reviewed-by: Thiago Macieira --- src/corelib/codecs/qtextcodec.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp index 3fc199c0a1..804e0b2935 100644 --- a/src/corelib/codecs/qtextcodec.cpp +++ b/src/corelib/codecs/qtextcodec.cpp @@ -695,11 +695,9 @@ void QTextCodec::setCodecForLocale(QTextCodec *c) \threadsafe Returns a pointer to the codec most suitable for this locale. - On Windows, the codec will be based on a system locale. On Unix - systems, the codec will might fall back to using the \e iconv - library if no builtin codec for the locale can be found. - - Note that in these cases the codec's name will be "System". + The codec will be retrieved from ICU where that backend is in use, otherwise + it may be obtained from an OS-specific API. In the latter case, the codec's + name may be "System". */ QTextCodec* QTextCodec::codecForLocale() From f7019fa43bca4ec26f76a4c4975cbb53b2886902 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Fri, 7 Dec 2018 09:46:22 +0100 Subject: [PATCH 0529/1650] ANGLE: Set ANGLE_COMMIT_HASH and ANGLE_COMMIT_DATE Fixes: QTBUG-72371 Change-Id: Ia03447b77d4f88eefc760e9bee14dbf3dd79d5a5 Reviewed-by: Friedemann Kleint --- src/3rdparty/angle/id/commit.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/3rdparty/angle/id/commit.h b/src/3rdparty/angle/id/commit.h index 4c89a657c5..d5446432f7 100644 --- a/src/3rdparty/angle/id/commit.h +++ b/src/3rdparty/angle/id/commit.h @@ -7,8 +7,8 @@ // This is a default commit hash header, when git is not available. // -#define ANGLE_COMMIT_HASH "unknown hash" +#define ANGLE_COMMIT_HASH "57ea533f79a7" #define ANGLE_COMMIT_HASH_SIZE 12 -#define ANGLE_COMMIT_DATE "unknown date" +#define ANGLE_COMMIT_DATE "2017-11-22 14:04:48 -0800" #define ANGLE_DISABLE_PROGRAM_BINARY_LOAD From 0023948f831f0303618fdb94935de9a560de5553 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 26 Nov 2018 09:56:42 +0100 Subject: [PATCH 0530/1650] Remove the model pointer from QPersistentModelIndexData MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It can be just as well received from the QModelIndex member. Change-Id: I72f930206ca2afed730009778ded0e56e4e6f278 Reviewed-by: Jędrzej Nowacki --- src/corelib/itemmodels/qabstractitemmodel.cpp | 13 ++----------- src/corelib/itemmodels/qabstractitemmodel_p.h | 5 ++--- src/widgets/itemviews/qdirmodel.cpp | 3 +-- 3 files changed, 5 insertions(+), 16 deletions(-) diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp index e816add91d..af08867dd4 100644 --- a/src/corelib/itemmodels/qabstractitemmodel.cpp +++ b/src/corelib/itemmodels/qabstractitemmodel.cpp @@ -77,7 +77,7 @@ void QPersistentModelIndexData::destroy(QPersistentModelIndexData *data) { Q_ASSERT(data); Q_ASSERT(data->ref.load() == 0); - QAbstractItemModel *model = const_cast(data->model); + QAbstractItemModel *model = const_cast(data->index.model()); // a valid persistent model index with a null model pointer can only happen if the model was destroyed if (model) { QAbstractItemModelPrivate *p = model->d_func(); @@ -512,10 +512,8 @@ QAbstractItemModel *QAbstractItemModelPrivate::staticEmptyModel() void QAbstractItemModelPrivate::invalidatePersistentIndexes() { - for (QPersistentModelIndexData *data : qAsConst(persistent.indexes)) { + for (QPersistentModelIndexData *data : qAsConst(persistent.indexes)) data->index = QModelIndex(); - data->model = 0; - } persistent.indexes.clear(); } @@ -530,7 +528,6 @@ void QAbstractItemModelPrivate::invalidatePersistentIndex(const QModelIndex &ind QPersistentModelIndexData *data = *it; persistent.indexes.erase(it); data->index = QModelIndex(); - data->model = 0; } } @@ -863,7 +860,6 @@ void QAbstractItemModelPrivate::rowsRemoved(const QModelIndex &parent, QPersistentModelIndexData *data = *it; persistent.indexes.erase(persistent.indexes.constFind(data->index)); data->index = QModelIndex(); - data->model = 0; } } @@ -958,7 +954,6 @@ void QAbstractItemModelPrivate::columnsRemoved(const QModelIndex &parent, QPersistentModelIndexData *data = *it; persistent.indexes.erase(persistent.indexes.constFind(data->index)); data->index = QModelIndex(); - data->model = 0; } } @@ -3294,8 +3289,6 @@ void QAbstractItemModel::changePersistentIndex(const QModelIndex &from, const QM data->index = to; if (to.isValid()) d->persistent.insertMultiAtEnd(to, data); - else - data->model = 0; } } @@ -3328,8 +3321,6 @@ void QAbstractItemModel::changePersistentIndexList(const QModelIndexList &from, data->index = to.at(i); if (data->index.isValid()) toBeReinserted << data; - else - data->model = 0; } } diff --git a/src/corelib/itemmodels/qabstractitemmodel_p.h b/src/corelib/itemmodels/qabstractitemmodel_p.h index 12fd93d217..94f1b41d50 100644 --- a/src/corelib/itemmodels/qabstractitemmodel_p.h +++ b/src/corelib/itemmodels/qabstractitemmodel_p.h @@ -65,11 +65,10 @@ QT_REQUIRE_CONFIG(itemmodel); class QPersistentModelIndexData { public: - QPersistentModelIndexData() : model(0) {} - QPersistentModelIndexData(const QModelIndex &idx) : index(idx), model(idx.model()) {} + QPersistentModelIndexData() {} + QPersistentModelIndexData(const QModelIndex &idx) : index(idx) {} QModelIndex index; QAtomicInt ref; - const QAbstractItemModel *model; static QPersistentModelIndexData *create(const QModelIndex &index); static void destroy(QPersistentModelIndexData *data); }; diff --git a/src/widgets/itemviews/qdirmodel.cpp b/src/widgets/itemviews/qdirmodel.cpp index 78fc623fb5..b94c31fb42 100644 --- a/src/widgets/itemviews/qdirmodel.cpp +++ b/src/widgets/itemviews/qdirmodel.cpp @@ -1252,11 +1252,10 @@ void QDirModelPrivate::restorePersistentIndexes() for (const SavedPersistent &sp : qAsConst(savedPersistent)) { QPersistentModelIndexData *data = sp.data; QModelIndex idx = q->index(sp.path, sp.column); - if (idx != data->index || data->model == 0) { + if (idx != data->index || data->index.model() == nullptr) { //data->model may be equal to 0 if the model is getting destroyed persistent.indexes.remove(data->index); data->index = idx; - data->model = q; if (idx.isValid()) persistent.indexes.insert(idx, data); } From 01a70da3e7432914b59a36c27d2a51b0cf6f876f Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 26 Nov 2018 10:15:56 +0100 Subject: [PATCH 0531/1650] QNetworkCacheMetaData::AttributesMap is not a multi hash And having duplicated entries in the hash doesn't make any sense. So use regular iteration and insert for streaming the data in and out. Change-Id: Ic3983010bdb9e17b207c6038fdccf43659da0e23 Reviewed-by: Timur Pocheptsov --- src/network/access/qabstractnetworkcache.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/network/access/qabstractnetworkcache.cpp b/src/network/access/qabstractnetworkcache.cpp index 2b670b2cce..1008b8e7f0 100644 --- a/src/network/access/qabstractnetworkcache.cpp +++ b/src/network/access/qabstractnetworkcache.cpp @@ -331,11 +331,11 @@ QDataStream &operator<<(QDataStream &out, const QNetworkCacheMetaData &metaData) static inline QDataStream &operator<<(QDataStream &out, const QNetworkCacheMetaData::AttributesMap &hash) { out << quint32(hash.size()); - QNetworkCacheMetaData::AttributesMap::ConstIterator it = hash.end(); - QNetworkCacheMetaData::AttributesMap::ConstIterator begin = hash.begin(); - while (it != begin) { - --it; + QNetworkCacheMetaData::AttributesMap::ConstIterator it = hash.begin(); + QNetworkCacheMetaData::AttributesMap::ConstIterator end = hash.end(); + while (it != end) { out << int(it.key()) << it.value(); + ++it; } return out; } @@ -383,7 +383,7 @@ static inline QDataStream &operator>>(QDataStream &in, QNetworkCacheMetaData::At int k; QVariant t; in >> k >> t; - hash.insertMulti(QNetworkRequest::Attribute(k), t); + hash.insert(QNetworkRequest::Attribute(k), t); } if (in.status() != QDataStream::Ok) From 6d38a1711c7e52c425101d57dd576c7015f39120 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 3 Dec 2018 10:46:44 +0100 Subject: [PATCH 0532/1650] Use a QMultiHash to store persistent model indices Because insertMulti() is deprecated. Change-Id: I47208c281209f19045caa15ea748a2986c2cc0cf Reviewed-by: David Faure --- src/corelib/itemmodels/qabstractitemmodel.cpp | 8 ++++---- src/corelib/itemmodels/qabstractitemmodel_p.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp index af08867dd4..75e13ff994 100644 --- a/src/corelib/itemmodels/qabstractitemmodel.cpp +++ b/src/corelib/itemmodels/qabstractitemmodel.cpp @@ -3950,7 +3950,7 @@ bool QAbstractListModel::dropMimeData(const QMimeData *data, Qt::DropAction acti /*! \internal - QHash::insertMulti insert the value before the old value. and find() return the new value. + QMultiHash::insert inserts the value before the old value. and find() return the new value. We need insertMultiAtEnd because we don't want to overwrite the old one, which should be removed later There should be only one instance QPersistentModelIndexData per index, but in some intermediate state there may be @@ -3960,9 +3960,9 @@ bool QAbstractListModel::dropMimeData(const QMimeData *data, Qt::DropAction acti */ void QAbstractItemModelPrivate::Persistent::insertMultiAtEnd(const QModelIndex& key, QPersistentModelIndexData *data) { - QHash::iterator newIt = - indexes.insertMulti(key, data); - QHash::iterator it = newIt + 1; + QHash::iterator newIt = indexes.insert(key, data); + QHash::iterator it = newIt; + ++it; while (it != indexes.end() && it.key() == key) { qSwap(*newIt,*it); newIt = it; diff --git a/src/corelib/itemmodels/qabstractitemmodel_p.h b/src/corelib/itemmodels/qabstractitemmodel_p.h index 94f1b41d50..e6085eca94 100644 --- a/src/corelib/itemmodels/qabstractitemmodel_p.h +++ b/src/corelib/itemmodels/qabstractitemmodel_p.h @@ -141,7 +141,7 @@ public: struct Persistent { Persistent() {} - QHash indexes; + QMultiHash indexes; QStack > moved; QStack > invalidated; void insertMultiAtEnd(const QModelIndex& key, QPersistentModelIndexData *data); From 70a5fc15fdff380eab3f136eba9992f1d2263957 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 3 Dec 2018 14:55:40 +0100 Subject: [PATCH 0533/1650] Use a QMultiMap for the fontengine cache Cosmetic, so we can avoid using QMap::insertMulti(). Change-Id: If7c971e127af0537dd28bd25f7803804e7e01170 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfont.cpp | 4 ++-- src/gui/text/qfont_p.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 3654c28fc5..38462c6e24 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -2950,9 +2950,9 @@ void QFontCache::insertEngine(const Key &key, QFontEngine *engine, bool insertMu data.timestamp = ++current_timestamp; if (insertMulti) - engineCache.insertMulti(key, data); - else engineCache.insert(key, data); + else + engineCache.replace(key, data); // only increase the cost if this is the first time we insert the engine if (++engineCacheCount[engine] == 1) increaseCost(engine->cache_cost); diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h index 09c18de5a6..14c01766ba 100644 --- a/src/gui/text/qfont_p.h +++ b/src/gui/text/qfont_p.h @@ -274,7 +274,7 @@ public: uint hits; }; - typedef QMap EngineCache; + typedef QMultiMap EngineCache; EngineCache engineCache; QHash engineCacheCount; From 90507f53c0a3a0be48cfe022f6063b770560ecbd Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 4 Dec 2017 17:36:11 +0100 Subject: [PATCH 0534/1650] configure: query pkg-config for deps of static libs note that pkg-config is a tad stupid: it won't tell us if the package is built statically, but one needs to explicitly ask it to output transitive deps for static packages. we can do that, as we resolve the pkg-config output to actual libraries, so we know if they are static. always asking it would print the transitive deps also if we found a dynamically linked library, which would inappropriately extend the link interface. the latter actually happens on windows (because we can't easily tell apart real static libs from import libs), but that doesn't matter, as under windows, the linker transitively resolves dlls anyway. Change-Id: If1be3b3df476374d5c8e62f4b185477c988223b3 Reviewed-by: Joerg Bornemann --- mkspecs/features/qt_configure.prf | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index 44d8a3e639..d75365cd0a 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -709,6 +709,13 @@ defineTest(qtConfLibrary_pkgConfig) { eval(libs = $$libpaths $$libs) !qtConfResolveLibs($${1}.libs, $$libs): \ return(false) + contains($${1}.libs, ".*\\.$${QMAKE_EXTENSION_STATICLIB}$") { + qtRunLoggedCommand("$$pkg_config --static --libs-only-L $$args", libpaths)|return(false) + qtRunLoggedCommand("$$pkg_config --static --libs-only-l $$args", libs)|return(false) + eval(libs = $$libpaths $$libs) + !qtConfResolveLibs($${1}.libs, $$libs): \ + return(false) + } qtRunLoggedCommand("$$pkg_config --cflags $$args", $${1}.cflags)|return(false) # Split CFLAGS into stuff that goes into DEFINES, INCLUDEPATH, and other stuff. From b91e6befebe908dd40ed2249b3c6f5dfec02c340 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20=C4=8Cuki=C4=87?= Date: Mon, 3 Dec 2018 22:22:14 +0100 Subject: [PATCH 0535/1650] Preallocate buffer for QLineEdit when used for password input While the user is entering the password, the string variable that stores the value might have to reallocate its content from time to time (when the string needs to grow beyond its current capacity). When the reallocation happens, the old buffer is freed, but its data is not zeroed-out. This means that a QLineEdit that serves as a password input field might leak chunks of the password during its lifetime, and the leaks will persist after its destruction. Since the QLineEdit can not control the behavior of the QString it uses to store the entered value, the only thing it can do is try to make the reallocations rare. This patch reserves the space for 30 characters for the string which stores the QLineEdit value when said QLineEdit is used for password input. This is enough to make sure no reallocation happens in majority of cases as barely anyone uses passwords longer than 30 characters. [ChangeLog][QtWidgets][QWidgetLineControl/security] Preallocate a buffer for the string that contains the entered value when the QLineEdit serves as a password input field to minimize reallocations. Change-Id: I3e695db93e34c93335c3bf9dbcbac832fc18b62d Reviewed-by: Richard Moe Gustavsen --- src/widgets/widgets/qwidgetlinecontrol_p.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/widgets/widgets/qwidgetlinecontrol_p.h b/src/widgets/widgets/qwidgetlinecontrol_p.h index b730b415f0..f4df95865d 100644 --- a/src/widgets/widgets/qwidgetlinecontrol_p.h +++ b/src/widgets/widgets/qwidgetlinecontrol_p.h @@ -280,6 +280,13 @@ public: cancelPasswordEchoTimer(); m_echoMode = mode; m_passwordEchoEditing = false; + + // If this control is used for password input, we want to minimize + // the possibility of string reallocation not to leak (parts of) + // the password. + if (m_echoMode != QLineEdit::Normal) + m_text.reserve(30); + updateDisplayText(); } From f184f1a4817f868bd17280c95b4117f48c9b4c23 Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Mon, 3 Dec 2018 20:49:06 +0100 Subject: [PATCH 0536/1650] Windows QPA: Fix QDockWindow Drag & Drop Pointer messages should not be handled when we are inside a move/resize modal loop. DefWindowProc() should handle this case instead. Fixes: QTBUG-72078 Change-Id: I5ad7283bcf0cfe0ff7d21cf5640270c361b8ad8d Reviewed-by: Friedemann Kleint --- .../windows/qwindowspointerhandler.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp index 0bac382a90..14559d726a 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp @@ -187,6 +187,12 @@ static bool draggingActive() bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result) { *result = 0; + + // If we are inside the move/resize modal loop, let DefWindowProc() handle it (but process NC button release). + QWindowsWindow *platformWindow = static_cast(window->handle()); + if (msg.message != WM_NCPOINTERUP && platformWindow->testFlag(QWindowsWindow::ResizeMoveActive)) + return false; + const quint32 pointerId = GET_POINTERID_WPARAM(msg.wParam); POINTER_INPUT_TYPE pointerType; @@ -195,6 +201,18 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q return false; } + // Handle non-client pen/touch as generic mouse events for compatibility with QDockWindow. + if ((pointerType == QT_PT_TOUCH || pointerType == QT_PT_PEN) && (et & QtWindows::NonClientEventFlag)) { + POINTER_INFO pointerInfo; + if (!QWindowsContext::user32dll.getPointerInfo(pointerId, &pointerInfo)) { + qWarning() << "GetPointerInfo() failed:" << qt_error_string(); + return false; + } + if (pointerInfo.pointerFlags & (POINTER_FLAG_UP | POINTER_FLAG_DOWN)) + return translateMouseTouchPadEvent(window, hwnd, et, msg, &pointerInfo); + return false; + } + switch (pointerType) { case QT_PT_POINTER: case QT_PT_MOUSE: From b60c642ec0532c108abcf57a42e214f44595ef93 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 4 Dec 2018 11:35:06 +0100 Subject: [PATCH 0537/1650] Revise filtering of Content-Length in HTTP cache control MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We filter out Content-Length from the cache metadata due to IIS sending it bogusly on 304 responses; however, we were only doing this if the cached response had a Content-Length header, which doesn't happen when the original request was delivered chunked. Furthermore, the filtering wasn't limited to the case of 304 responses. So skip the "had it previously" requirement and only do this for 304s. Fixes: QTBUG-72035 Change-Id: Ie5d858e0f0205bf68f0a13a9c9d4a6e844cb3568 Reviewed-by: Joni Poikelin Reviewed-by: Mårten Nordheim Reviewed-by: Timur Pocheptsov --- src/network/access/qnetworkreplyhttpimpl.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index 8750a841f6..ed2235ad28 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -1676,13 +1676,13 @@ QNetworkCacheMetaData QNetworkReplyHttpImplPrivate::fetchCacheMetaData(const QNe || header == "content-range" || header == "content-type") continue; - - // For MS servers that send "Content-Length: 0" on 304 responses - // ignore this too - if (header == "content-length") - continue; } + // IIS has been known to send "Content-Length: 0" on 304 responses, so + // ignore this too + if (header == "content-length" && statusCode == 304) + continue; + #if defined(QNETWORKACCESSHTTPBACKEND_DEBUG) QByteArray n = q->rawHeader(header); QByteArray o; From 4ee59cf96d80c752ebfa127792d65d7b84abbd74 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 6 Dec 2018 13:11:25 +0100 Subject: [PATCH 0538/1650] Remove one out-of-date comment, refine another that was imprecise The former is a follow-up to c17563eca8. Change-Id: I3cd41e6e38f740de67605f785a804ffd879b9e67 Reviewed-by: Thiago Macieira --- tests/auto/corelib/tools/qcollator/tst_qcollator.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tests/auto/corelib/tools/qcollator/tst_qcollator.cpp b/tests/auto/corelib/tools/qcollator/tst_qcollator.cpp index 00b22dab6c..2d65d3433f 100644 --- a/tests/auto/corelib/tools/qcollator/tst_qcollator.cpp +++ b/tests/auto/corelib/tools/qcollator/tst_qcollator.cpp @@ -95,11 +95,6 @@ void tst_QCollator::compare_data() QTest::addColumn("ignorePunctuation"); QTest::addColumn("punctuationResult"); - /* - A few tests below are commented out on the mac. It's unclear why they fail, - as it looks like the collator for the locale is created correctly. - */ - /* It's hard to test English, because it's treated differently on different platforms. For example, on Linux, it uses the @@ -164,7 +159,7 @@ void tst_QCollator::compare_data() QTest::newRow("german13") << QString("de_DE") << QString("test.19") << QString("test,19") << 1 << 1 << true << true << 0; /* - French sorting of e and e with accent + French sorting of e and e with acute accent */ QTest::newRow("french1") << QString("fr_FR") << QString::fromLatin1("\xe9") << QString::fromLatin1("e") << 1 << 1 << false << false << 1; QTest::newRow("french2") << QString("fr_FR") << QString::fromLatin1("\xe9t") << QString::fromLatin1("et") << 1 << 1 << false << false << 1; From 0088f760439b4f6f98342d3e22ecadbb13aaf06a Mon Sep 17 00:00:00 2001 From: Vitaly Fanaskov Date: Fri, 30 Nov 2018 16:10:37 +0100 Subject: [PATCH 0539/1650] Fix inability to edit lines in QGraphicsTextItem when pageSize is set Previous implementation relies on the fact that the only text document with height -1 can grow or shrink vertically, and, hence, a bounding rect should be updated under this circumstances. But method QTextDocument::setPageSize might set a height different from -1, and QGraphicsTextItem will be growing/shrinking vertically as well. So, we have to relax condition to cover all use cases. Bounding rect will be updated if new size is different from current size. This also doesn't affect performance. Fixes: QTBUG-55527 Change-Id: Id2c8e15d859aff9dde62c8ee14a6859c0c03f0d4 Reviewed-by: Lars Knoll --- src/widgets/graphicsview/qgraphicsitem.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp index e81eab4c46..3a9bfab298 100644 --- a/src/widgets/graphicsview/qgraphicsitem.cpp +++ b/src/widgets/graphicsview/qgraphicsitem.cpp @@ -10569,14 +10569,11 @@ void QGraphicsTextItemPrivate::_q_update(QRectF rect) */ void QGraphicsTextItemPrivate::_q_updateBoundingRect(const QSizeF &size) { - if (!control) return; // can't happen - const QSizeF pageSize = control->document()->pageSize(); - // paged items have a constant (page) size - if (size == boundingRect.size() || pageSize.height() != -1) - return; - qq->prepareGeometryChange(); - boundingRect.setSize(size); - qq->update(); + if (size != boundingRect.size()) { + qq->prepareGeometryChange(); + boundingRect.setSize(size); + qq->update(); + } } /*! From 326658cfcd75dcfbb6dcb92045ac8b417c6d13c3 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Mon, 3 Dec 2018 14:08:31 +0100 Subject: [PATCH 0540/1650] libinput: use QT_CONFIG(xkbcommon) macro This patch amends c3a963da1f9e7b1d37e63eedded61da4fbdaaf9a Change-Id: I9e66aac4f0f45714343c585c79f37bd76683e103 Reviewed-by: Oswald Buddenhagen Reviewed-by: Gatis Paeglis --- src/platformsupport/input/libinput/qlibinputkeyboard_p.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/platformsupport/input/libinput/qlibinputkeyboard_p.h b/src/platformsupport/input/libinput/qlibinputkeyboard_p.h index 9e09bccd79..14ae71b545 100644 --- a/src/platformsupport/input/libinput/qlibinputkeyboard_p.h +++ b/src/platformsupport/input/libinput/qlibinputkeyboard_p.h @@ -43,7 +43,9 @@ #include #include -#ifndef QT_NO_XKBCOMMON_EVDEV +#include + +#if QT_CONFIG(xkbcommon) #include #endif @@ -70,7 +72,7 @@ public: void processKey(libinput_event_keyboard *e); -#ifndef QT_NO_XKBCOMMON_EVDEV +#if QT_CONFIG(xkbcommon) void handleRepeat(); private: From 28fd625873f9bb191cb10a2a36a1b974c6e8c97e Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Wed, 5 Dec 2018 17:06:51 +0100 Subject: [PATCH 0541/1650] configure: remove xkbcommon_evdev transition hack It was added in c3a963da1f9e7b1d37e63eedded61da4fbdaaf9a. wayland was updated in a8fed20181729cae70de43079c4a34ad1780cfd7. Change-Id: Ibf458815c3b61c5f936f147086db3d2b5782c175 Reviewed-by: Oswald Buddenhagen --- src/gui/configure.json | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/gui/configure.json b/src/gui/configure.json index 25ff553876..6a2f1fe434 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -618,16 +618,6 @@ { "type": "pkgConfig", "args": "xkbcommon-x11" } ] }, - "xkbcommon_evdev": { - "label": "xkbcommon_evdev TRANSITION HACK", - "test": { - "include": [ "xkbcommon/xkbcommon.h" ], - "main": "xkb_context_new(XKB_CONTEXT_NO_FLAGS);" - }, - "sources": [ - { "type": "pkgConfig", "args": "xkbcommon >= 0.5.0" } - ] - }, "xrender": { "label": "XRender for native painting", "test": "x11/xrender", @@ -1378,11 +1368,6 @@ "condition": "libs.xkbcommon", "output": [ "privateFeature" ] }, - "xkbcommon-evdev": { - "label": "xkbcommon-evdev TRANSITION HACK", - "condition": "libs.xkbcommon_evdev", - "output": [ "privateFeature" ] - }, "xlib": { "label": "XLib", "autoDetect": "!config.darwin || features.xcb", From ec31953007126a6e0f9f3ca16b64bdfdcdf3d7b6 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 21 Nov 2018 11:25:57 -0800 Subject: [PATCH 0542/1650] Fix build using Windows SDK 10.0.17763 c:\qt\qt5\qtbase\src\3rdparty\libjpeg\src\jmorecfg.h(242): error C2371: 'boolean': redefinition; different basic types c:\program files (x86)\windows kits\10\include\10.0.17763.0\shared\rpcndr.h(193): note: see declaration of 'boolean' Instead of trying to guess if a certain header has been #included and whether that header does typedef something to boolean, let's just use the preprocessor to hide, like some people do for X11/Xlib.h's Bool (see qmetatype.h where we refused). Change-Id: I05b8d7ba19004af99f3cfffd15693a87e175f05d Reviewed-by: Eirik Aavitsland --- src/plugins/imageformats/jpeg/qjpeghandler.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp index e52a19703c..54fe857908 100644 --- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp +++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp @@ -56,13 +56,12 @@ // including jpeglib.h seems to be a little messy extern "C" { -// mingw includes rpcndr.h but does not define boolean -#if defined(Q_OS_WIN) && defined(Q_CC_GNU) -# if defined(__RPCNDR_H__) && !defined(boolean) - typedef unsigned char boolean; -# define HAVE_BOOLEAN -# endif +// jpeglib.h->jmorecfg.h tries to typedef int boolean; but this conflicts with +// some Windows headers that may or may not have been included +#ifdef HAVE_BOOLEAN +# undef HAVE_BOOLEAN #endif +#define boolean jboolean #define XMD_H // shut JPEGlib up #include From ea9f11b0382933a8092f948063ad9d5179743a8c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 27 Nov 2018 19:27:15 -0800 Subject: [PATCH 0543/1650] Add a note about virtual_hook Change-Id: I1ff3b344ec5a4499bb25fffd156b2bf6a7d88625 Reviewed-by: Allan Sandfeld Jensen --- src/gui/image/qiconengine.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/image/qiconengine.h b/src/gui/image/qiconengine.h index 0c67ef2686..0c5b51dc71 100644 --- a/src/gui/image/qiconengine.h +++ b/src/gui/image/qiconengine.h @@ -90,6 +90,7 @@ public: QPixmap pixmap; }; + // ### Qt6: move content to proper virtual functions virtual void virtual_hook(int id, void *data); private: From aa18467442011a8ad26ca6396c2bb44f44aba569 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 13 Nov 2018 07:41:45 -0800 Subject: [PATCH 0544/1650] Doc: update docs for the sleeping functions' accuracy And take the opportunity to tell people not to sleep. It's always wrong. Fixes: QTBUG-71757 Change-Id: I36203b7dac414e3eb9effffd1566b956dd05f32a Reviewed-by: Lars Knoll --- src/corelib/thread/qthread.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index d3f60eea4f..05bc064005 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -650,6 +650,13 @@ QThread::Priority QThread::priority() const Forces the current thread to sleep for \a secs seconds. + Avoid using this function if you need to wait for a given condition to + change. Instead, connect a slot to the signal that indicates the change or + use an event handler (see \l QObject::event()). + + \note This function does not guarantee accuracy. The application may sleep + longer than \a secs under heavy load conditions. + \sa msleep(), usleep() */ @@ -658,6 +665,14 @@ QThread::Priority QThread::priority() const Forces the current thread to sleep for \a msecs milliseconds. + Avoid using this function if you need to wait for a given condition to + change. Instead, connect a slot to the signal that indicates the change or + use an event handler (see \l QObject::event()). + + \note This function does not guarantee accuracy. The application may sleep + longer than \a msecs under heavy load conditions. Some OSes might round \a + msecs up to 10 ms or 15 ms. + \sa sleep(), usleep() */ @@ -666,6 +681,15 @@ QThread::Priority QThread::priority() const Forces the current thread to sleep for \a usecs microseconds. + Avoid using this function if you need to wait for a given condition to + change. Instead, connect a slot to the signal that indicates the change or + use an event handler (see \l QObject::event()). + + \note This function does not guarantee accuracy. The application may sleep + longer than \a usecs under heavy load conditions. Some OSes might round \a + usecs up to 10 ms or 15 ms; on Windows, it will be rounded up to a multiple + of 1 ms. + \sa sleep(), msleep() */ From 9d4406f49af21a57b6df3ee8f42f682a04bd2edd Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 16 Sep 2018 10:27:38 -0700 Subject: [PATCH 0545/1650] QTest: Make QCOMPARE of QCborError produce output I was getting: Actual (reader.validate()) : Expected (QCborError::NoError): NoError Change-Id: Ib47c56818178458a88b4fffd1554f1751f447086 Reviewed-by: Edward Welbourne --- src/testlib/qtest.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/testlib/qtest.h b/src/testlib/qtest.h index 2578037946..28b62129b6 100644 --- a/src/testlib/qtest.h +++ b/src/testlib/qtest.h @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -110,6 +111,12 @@ template<> inline char *toString(const QDateTime &dateTime) } #endif // datestring +template<> inline char *toString(const QCborError &c) +{ + // use the Q_ENUM formatting + return toString(c.c); +} + template<> inline char *toString(const QChar &c) { const ushort uc = c.unicode(); From 962bded90f0ffb7390b4a2a1a5a895156aa5f541 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 1 Dec 2018 18:02:52 -0600 Subject: [PATCH 0546/1650] Fix QSettings parsing of spaces after comment lines [ChangeLog][QtCore][QSettings] Fixed QSettings parsing of blank spaces after comment lines in INI-style configuration files. Fixes: QTBUG-72007 Change-Id: Idd0c85a4e7b64f9c9c7dfffd156c5b219f3b5c0a Reviewed-by: Oliver Wolff --- src/corelib/io/qsettings.cpp | 2 ++ tests/auto/corelib/io/qsettings/qsettings.qrc | 1 + .../corelib/io/qsettings/tst_qsettings.cpp | 29 +++++++++++++++++++ .../corelib/io/qsettings/withcomments.ini | 19 ++++++++++++ 4 files changed, 51 insertions(+) create mode 100644 tests/auto/corelib/io/qsettings/withcomments.ini diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index a0de5ac2b1..ab8fd6510a 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -1634,6 +1634,8 @@ bool QConfFileSettingsPrivate::readIniLine(const QByteArray &data, int &dataPos, char ch; while (i < dataLen && (((ch = data.at(i)) != '\n') && ch != '\r')) ++i; + while (i < dataLen && charTraits[uchar(data.at(i))] & Space) + ++i; lineStart = i; } else if (!inQuotes) { --i; diff --git a/tests/auto/corelib/io/qsettings/qsettings.qrc b/tests/auto/corelib/io/qsettings/qsettings.qrc index c664a6f68c..db1d8c663f 100644 --- a/tests/auto/corelib/io/qsettings/qsettings.qrc +++ b/tests/auto/corelib/io/qsettings/qsettings.qrc @@ -7,5 +7,6 @@ resourcefile5.ini resourcefile6.plist bom.ini + withcomments.ini diff --git a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp index 5357194406..8b69518ef7 100644 --- a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp +++ b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp @@ -187,6 +187,7 @@ private slots: void bom(); void embeddedZeroByte_data(); void embeddedZeroByte(); + void spaceAfterComment(); void testXdg(); private: @@ -764,6 +765,34 @@ void tst_QSettings::embeddedZeroByte() } } +void tst_QSettings::spaceAfterComment() +{ + QSettings settings(QFINDTESTDATA("withcomments.ini"), QSettings::IniFormat); + QCOMPARE(settings.status(), QSettings::NoError); + + QStringList groups = settings.childGroups(); + QVERIFY(groups.contains("Regular")); + QVERIFY(groups.contains("WithSpaces")); + QVERIFY(groups.contains("WithTab")); + QVERIFY(groups.contains("SpacedGroup")); + + settings.beginGroup("Regular"); + QCOMPARE(settings.value("bar"), QVariant(2)); + settings.endGroup(); + + settings.beginGroup("WithSpaces"); + QCOMPARE(settings.value("bar"), QVariant(4)); + settings.endGroup(); + + settings.beginGroup("WithTab"); + QCOMPARE(settings.value("bar"), QVariant(6)); + settings.endGroup(); + + settings.beginGroup("SpacedGroup"); + QCOMPARE(settings.value("bar"), QVariant(7)); + settings.endGroup(); +} + void tst_QSettings::testErrorHandling_data() { QTest::addColumn("filePerms"); // -1 means file should not exist diff --git a/tests/auto/corelib/io/qsettings/withcomments.ini b/tests/auto/corelib/io/qsettings/withcomments.ini new file mode 100644 index 0000000000..d2de3a356b --- /dev/null +++ b/tests/auto/corelib/io/qsettings/withcomments.ini @@ -0,0 +1,19 @@ +; -*- conf -*- +; If you edit this file, make sure, that "WithSpaces" has spaces and that +; "WithTab" has one tab + +[Regular] +;bar = 1 +bar = 2 + +[WithSpaces] +;bar = 3 + bar = 4 + +[WithTab] +;bar = 5 + bar = 6 + +; [SpacedGroup] + [SpacedGroup] + bar = 7 From 90c1107698fdd19f0b2b75923ad08046d7c65966 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 1 Dec 2018 18:09:26 -0600 Subject: [PATCH 0547/1650] QSettings: quick refactor for readability MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Helps with debugging the code too, as you can follow what's on the file with the "ch" variable. Change-Id: Idd0c85a4e7b64f9c9c7dfffd156c5b7d76cf657b Reviewed-by: Tor Arne Vestbø Reviewed-by: Friedemann Kleint --- src/corelib/io/qsettings.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index ab8fd6510a..0d2bd72d75 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -1599,12 +1599,14 @@ bool QConfFileSettingsPrivate::readIniLine(const QByteArray &data, int &dataPos, int i = lineStart; while (i < dataLen) { - while (!(charTraits[uint(uchar(data.at(i)))] & Special)) { + char ch = data.at(i); + while (!(charTraits[uchar(ch)] & Special)) { if (++i == dataLen) goto break_out_of_outer_loop; + ch = data.at(i); } - char ch = data.at(i++); + ++i; if (ch == '=') { if (!inQuotes && equalsPos == -1) equalsPos = i - 1; @@ -1631,7 +1633,6 @@ bool QConfFileSettingsPrivate::readIniLine(const QByteArray &data, int &dataPos, Q_ASSERT(ch == ';'); if (i == lineStart + 1) { - char ch; while (i < dataLen && (((ch = data.at(i)) != '\n') && ch != '\r')) ++i; while (i < dataLen && charTraits[uchar(data.at(i))] & Space) From e27f52a09893cf494fc9b93452ed160f2effb94b Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 7 Dec 2018 09:25:02 +0100 Subject: [PATCH 0548/1650] QScroller: Fix crash when multiple scrollers are registered Ensure the scroller cannot be added multiple times to the list of active scrollers. Patch as contributed on bug report. Amends 8b8e53f7267911c4f406f5c6f54e4a60a0f32112. Change-Id: Ic4e7d3e981f36e330dfd28d468288c5ef4b74a4c Fixes: QTBUG-72244 Reviewed-by: Shawn Rutledge --- src/widgets/util/qscroller.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/widgets/util/qscroller.cpp b/src/widgets/util/qscroller.cpp index e229a885a8..abb203b8cc 100644 --- a/src/widgets/util/qscroller.cpp +++ b/src/widgets/util/qscroller.cpp @@ -1725,10 +1725,12 @@ void QScrollerPrivate::setState(QScroller::State newstate) sendEvent(target, &se); firstScroll = true; } - if (state == QScroller::Dragging || state == QScroller::Scrolling) - qt_activeScrollers()->push_back(q); - else + if (state == QScroller::Dragging || state == QScroller::Scrolling) { + if (!qt_activeScrollers()->contains(q)) + qt_activeScrollers()->push_back(q); + } else { qt_activeScrollers()->removeOne(q); + } emit q->stateChanged(state); } From eda28621f6c1a68774719f382be53ec109123b18 Mon Sep 17 00:00:00 2001 From: Kyle Edwards Date: Tue, 16 Oct 2018 12:58:22 -0400 Subject: [PATCH 0549/1650] Add support for linking against static builds in CMake This change reinstates functionality that was removed in commit 102e1822ffcdc9954d3c698f863734a8083e349c. However, it differs from the original implementation in several ways: * It uses the QMAKE_PRL_LIBS variable, replacing whitespace with semicolons, rather than using a dedicated QMAKE_PRL_LIBS_FOR_CMAKE variable. * More importantly, it parses the -L and -l flags and uses CMake's find_library() command to look for the libraries in the specified search paths, and then converts them to absolute paths. This is the same approach that CMake's own FindPkgConfig module uses to find libraries specified in this form. Any other flags not of the form -L or -l (for instance, -s flags passed to Emscripten) are added to the new INTERFACE_LINK_OPTIONS target property if the CMake version is 3.13 or newer. The original implementation of this functionality was removed because of the lack of absolute library paths. At the time, it was believed that qmake would have to be modified to do its own equivalent of find_library() to get the absolute paths to the libraries. However, the approach taken by FindPkgConfig has proven robust enough to be used here, allowing CMake to find the absolute paths to the libraries without having to modify qmake. [ChangeLog][CMake] Added support for automatic linking of transitive dependencies in static builds Fixes: QTBUG-38913 Change-Id: I7d9cdb0d339c6ef697b04099d129481c770fc0fc Reviewed-by: Oswald Buddenhagen Reviewed-by: Simon Hausmann --- .../data/cmake/Qt5BasicConfig.cmake.in | 95 ++++++++++++++++++- 1 file changed, 93 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in b/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in index 3ed6dd5889..acd302d4b2 100644 --- a/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in +++ b/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in @@ -48,6 +48,49 @@ but not all the files it references. endif() endmacro() +!!IF !isEmpty(CMAKE_STATIC_TYPE) +function(_qt5_$${CMAKE_MODULE_NAME}_process_prl_file prl_file_location Configuration lib_deps link_flags) + set(_lib_deps) + set(_link_flags) + if(EXISTS \"${prl_file_location}\") + file(STRINGS \"${prl_file_location}\" _prl_strings REGEX \"QMAKE_PRL_LIBS[ \\t]*=\") + string(REGEX REPLACE \"QMAKE_PRL_LIBS[ \\t]*=[ \\t]*([^\\n]*)\" \"\\\\1\" _static_depends ${_prl_strings}) + string(REGEX REPLACE \"[ \\t]+\" \";\" _static_depends ${_static_depends}) + set(_search_paths) + foreach(_flag ${_static_depends}) + if(_flag MATCHES \"^-l(.*)$\") + set(_lib \"${CMAKE_MATCH_1}\") + if(_lib MATCHES \"^pthread$\") + find_package(Threads REQUIRED) + list(APPEND _lib_deps Threads::Threads) + else() + if(_search_paths) + find_library(_Qt5$${CMAKE_MODULE_NAME}_${Configuration}_${_lib}_PATH ${_lib} HINTS ${_search_paths} NO_DEFAULT_PATH) + endif() + find_library(_Qt5$${CMAKE_MODULE_NAME}_${Configuration}_${_lib}_PATH ${_lib}) + mark_as_advanced(_Qt5$${CMAKE_MODULE_NAME}_${Configuration}_${_lib}_PATH) + if(_Qt5$${CMAKE_MODULE_NAME}_${Configuration}_${_lib}_PATH) + list(APPEND _lib_deps + ${_Qt5$${CMAKE_MODULE_NAME}_${Configuration}_${_lib}_PATH} + ) + else() + message(FATAL_ERROR \"Library not found: ${_lib}\") + endif() + endif() + elseif(_flag MATCHES \"^-L(.*)$\") + list(APPEND _search_paths \"${CMAKE_MATCH_1}\") + else() + list(APPEND _link_flags ${_flag}) + endif() + endforeach() + endif() + + string(REPLACE \";\" \" \" _link_flags \"${_link_flags}\") + set(${lib_deps} ${_lib_deps} PARENT_SCOPE) + set(${link_flags} \"SHELL:${_link_flags}\" PARENT_SCOPE) +endfunction() +!!ENDIF + !!IF !equals(TEMPLATE, aux) macro(_populate_$${CMAKE_MODULE_NAME}_target_properties Configuration LIB_LOCATION IMPLIB_LOCATION) set_property(TARGET Qt5::$${CMAKE_MODULE_NAME} APPEND PROPERTY IMPORTED_CONFIGURATIONS ${Configuration}) @@ -58,15 +101,29 @@ macro(_populate_$${CMAKE_MODULE_NAME}_target_properties Configuration LIB_LOCATI set(imported_location \"$${CMAKE_DLL_DIR}${LIB_LOCATION}\") !!ENDIF _qt5_$${CMAKE_MODULE_NAME}_check_file_exists(${imported_location}) + set(_deps + ${_Qt5$${CMAKE_MODULE_NAME}_LIB_DEPENDENCIES} +!!IF !isEmpty(CMAKE_STATIC_TYPE) + ${_Qt5$${CMAKE_MODULE_NAME}_STATIC_${Configuration}_LIB_DEPENDENCIES} +!!ENDIF + ) set_target_properties(Qt5::$${CMAKE_MODULE_NAME} PROPERTIES - \"INTERFACE_LINK_LIBRARIES\" \"${_Qt5$${CMAKE_MODULE_NAME}_LIB_DEPENDENCIES}\" + \"INTERFACE_LINK_LIBRARIES\" \"${_deps}\" \"IMPORTED_LOCATION_${Configuration}\" ${imported_location} !!IF !isEmpty(CMAKE_LIB_SONAME) \"IMPORTED_SONAME_${Configuration}\" \"$${CMAKE_LIB_SONAME}\" !!ENDIF # For backward compatibility with CMake < 2.8.12 - \"IMPORTED_LINK_INTERFACE_LIBRARIES_${Configuration}\" \"${_Qt5$${CMAKE_MODULE_NAME}_LIB_DEPENDENCIES}\" + \"IMPORTED_LINK_INTERFACE_LIBRARIES_${Configuration}\" \"${_deps}\" ) +!!IF !isEmpty(CMAKE_STATIC_TYPE) + + if(NOT CMAKE_VERSION VERSION_LESS \"3.13\") + set_target_properties(Qt5::$${CMAKE_MODULE_NAME} PROPERTIES + \"INTERFACE_LINK_OPTIONS\" \"${_Qt5$${CMAKE_MODULE_NAME}_STATIC_${Configuration}_LINK_FLAGS}\" + ) + endif() +!!ENDIF !!IF !isEmpty(CMAKE_WINDOWS_BUILD) !!IF isEmpty(CMAKE_LIB_DIR_IS_ABSOLUTE) @@ -215,6 +272,40 @@ if (NOT TARGET Qt5::$${CMAKE_MODULE_NAME}) !!ENDIF !!IF !isEmpty(CMAKE_STATIC_TYPE) + if(NOT Qt5_EXCLUDE_STATIC_DEPENDENCIES) +!!IF !isEmpty(CMAKE_DEBUG_TYPE) +!!IF isEmpty(CMAKE_LIB_DIR_IS_ABSOLUTE) + _qt5_$${CMAKE_MODULE_NAME}_process_prl_file( + \"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/$${CMAKE_LIB_DIR}$${CMAKE_PRL_FILE_LOCATION_DEBUG}\" DEBUG + _Qt5$${CMAKE_MODULE_NAME}_STATIC_DEBUG_LIB_DEPENDENCIES + _Qt5$${CMAKE_MODULE_NAME}_STATIC_DEBUG_LINK_FLAGS + ) +!!ELSE + _qt5_$${CMAKE_MODULE_NAME}_process_prl_file( + \"$${CMAKE_LIB_DIR}$${CMAKE_PRL_FILE_LOCATION_DEBUG}\" DEBUG + _Qt5$${CMAKE_MODULE_NAME}_STATIC_DEBUG_LIB_DEPENDENCIES + _Qt5$${CMAKE_MODULE_NAME}_STATIC_DEBUG_LINK_FLAGS + ) +!!ENDIF +!!ENDIF + +!!IF !isEmpty(CMAKE_RELEASE_TYPE) +!!IF isEmpty(CMAKE_LIB_DIR_IS_ABSOLUTE) + _qt5_$${CMAKE_MODULE_NAME}_process_prl_file( + \"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/$${CMAKE_LIB_DIR}$${CMAKE_PRL_FILE_LOCATION_RELEASE}\" RELEASE + _Qt5$${CMAKE_MODULE_NAME}_STATIC_RELEASE_LIB_DEPENDENCIES + _Qt5$${CMAKE_MODULE_NAME}_STATIC_RELEASE_LINK_FLAGS + ) +!!ELSE + _qt5_$${CMAKE_MODULE_NAME}_process_prl_file( + \"$${CMAKE_LIB_DIR}$${CMAKE_PRL_FILE_LOCATION_RELEASE}\" RELEASE + _Qt5$${CMAKE_MODULE_NAME}_STATIC_RELEASE_LIB_DEPENDENCIES + _Qt5$${CMAKE_MODULE_NAME}_STATIC_RELEASE_LINK_FLAGS + ) +!!ENDIF +!!ENDIF + endif() + add_library(Qt5::$${CMAKE_MODULE_NAME} STATIC IMPORTED) set_property(TARGET Qt5::$${CMAKE_MODULE_NAME} PROPERTY IMPORTED_LINK_INTERFACE_LANGUAGES "CXX") !!ELSE From d941ebc1505cc45c7d6f8e1b2abdd2e2d9c3afae Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 4 Dec 2018 13:33:10 +0100 Subject: [PATCH 0550/1650] qmake: fix QMAKE_DEFAULT_LIBDIRS detection for android on windows clearly, nobody told clang that on windows you're supposed to use semicolons instead of colons to separate elements of a path list ... Fixes: QTBUG-72268 Change-Id: Ia7adc8de3bca586d4c15b069cb04e4cb647ae823 Reviewed-by: Liang Qi Reviewed-by: Joerg Bornemann --- mkspecs/features/toolchain.prf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mkspecs/features/toolchain.prf b/mkspecs/features/toolchain.prf index 6039c52bd0..55295f271f 100644 --- a/mkspecs/features/toolchain.prf +++ b/mkspecs/features/toolchain.prf @@ -134,6 +134,8 @@ isEmpty($${target_prefix}.INCDIRS) { for (line, output) { contains(line, "^libraries: .*") { line ~= s,^libraries: ,, + # clang (7.x) on Windows uses the wrong path list separator ... + equals(QMAKE_HOST.os, Windows): line ~= s,:(?![/\\\\]),;, paths = $$split(line, $$QMAKE_DIRLIST_SEP) for (path, paths): \ QMAKE_DEFAULT_LIBDIRS += $$clean_path($$replace(path, ^=, $$[SYSROOT])) From 33276e1cf14095c681ef87f1b44809b5ee1e771f Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 17 Apr 2018 19:17:25 +0200 Subject: [PATCH 0551/1650] add support for transitive deps to QMAKE_USE we already knew the dependencies (as they are declared in the json files), but failed to export them in any way, which made linking against statically built external deps which have deps in turn fail (unless the project happened to pull in the dep anyway, as is the case with qtcore + zlib). the previous assumption was that the USE-able library objects would be self-contained, but that is conceptually unclean. instead, properly export the raw dependencies and resolve them only in qmake_use.prf. note that pkg-config produces self-contained output, so we need to actively subtract the dependencies we know. Change-Id: I4b41a7efc05bbd309a6d66275d7557a80efd5af4 Reviewed-by: Joerg Bornemann Reviewed-by: Oswald Buddenhagen --- mkspecs/features/qmake_use.prf | 32 +++++++++------ mkspecs/features/qt_configure.prf | 62 ++++++++++++++++++++++++++--- mkspecs/features/qt_helper_lib.prf | 13 ++++++ mkspecs/features/qt_module_pris.prf | 1 + 4 files changed, 90 insertions(+), 18 deletions(-) diff --git a/mkspecs/features/qmake_use.prf b/mkspecs/features/qmake_use.prf index dba45de92a..8159e471a2 100644 --- a/mkspecs/features/qmake_use.prf +++ b/mkspecs/features/qmake_use.prf @@ -1,23 +1,31 @@ suffix = for(ever) { - QMAKE_USE$${suffix} = $$unique(QMAKE_USE$${suffix}) + CC_USES = + LD_USES = for (use, QMAKE_USE$${suffix}) { use = $$split(use, /) name = $$take_first(use) nu = $$upper($$name) + !contains(use, linkonly): CC_USES += $$nu + !contains(use, nolink): LD_USES += $$nu + } + CC_USES = $$resolve_depends(CC_USES, QMAKE_DEPENDS_, _CC) + for (nu, CC_USES) { !defined(QMAKE_LIBS_$$nu, var): \ - error("Library '$$name' is not defined.") + error("Library '$$lower($$nu)' is not defined.") - !contains(use, nolink) { - debug: \ - LIBS$${suffix} += $$eval(QMAKE_LIBS_$${nu}_DEBUG) $$eval(QMAKE_LIBS_$$nu) - else: \ - LIBS$${suffix} += $$eval(QMAKE_LIBS_$${nu}_RELEASE) $$eval(QMAKE_LIBS_$$nu) - } - !contains(use, linkonly) { - DEFINES += $$eval(QMAKE_DEFINES_$${nu}) - INCLUDEPATH += $$eval(QMAKE_INCDIR_$${nu}) - } + DEFINES += $$eval(QMAKE_DEFINES_$${nu}) + INCLUDEPATH += $$eval(QMAKE_INCDIR_$${nu}) + } + LD_USES = $$resolve_depends(LD_USES, QMAKE_DEPENDS_, _LD) + for (nu, LD_USES) { + !defined(QMAKE_LIBS_$$nu, var): \ + error("Library '$$lower($$nu)' is not defined.") + + debug: \ + LIBS$${suffix} += $$eval(QMAKE_LIBS_$${nu}_DEBUG) $$eval(QMAKE_LIBS_$$nu) + else: \ + LIBS$${suffix} += $$eval(QMAKE_LIBS_$${nu}_RELEASE) $$eval(QMAKE_LIBS_$$nu) } !isEmpty(suffix): break() suffix = "_PRIVATE" diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index d75365cd0a..d8f5af5404 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -743,6 +743,21 @@ defineTest(qtConfLibrary_pkgConfig) { !qtConfResolvePathIncs($${1}.includedir, $$includes): \ return(false) $${1}.defines = $$defines + + # now remove the content of the transitive deps we know about. + largs = $$qtConfAllLibraryArgs($$eval($${2}.dependencies)) + for (la, largs): \ + eval("$$la") + USES = $$eval($$list($$upper($$QMAKE_USE))) + # _CC == _LD for configure's library sources, so pick first arbitrarily. + DEPS = $$resolve_depends(USES, QMAKE_DEPENDS_, _CC) + for (DEP, DEPS) { + $${1}.libs -= $$eval(QMAKE_LIBS_$${DEP}) + $${1}.includedir -= $$eval(QMAKE_INCDIR_$${DEP}) + $${1}.defines -= $$eval(QMAKE_DEFINES_$${DEP}) + } + export($${1}.libs) + export($${1}.includedir) export($${1}.defines) return(true) @@ -776,20 +791,36 @@ defineReplace(qtConfLibraryArgs) { defines = $$eval($${1}.defines) !isEmpty(defines): \ qmake_args += "QMAKE_DEFINES_$${NAME} = $$val_escape(defines)" + depends = $$eval($${2}.dependencies) + !isEmpty(depends) { + dep_uses = + for (use, depends): \ + dep_uses += $$section(use, :, 1, 1) + qmake_args += \ + "QMAKE_DEPENDS_$${NAME}_CC = $$upper($$dep_uses)" \ + "QMAKE_DEPENDS_$${NAME}_LD = $$upper($$dep_uses)" + } return($$qmake_args) } defineReplace(qtConfAllLibraryArgs) { isEmpty(1): return() dep_uses = + for (use, 1): \ + dep_uses += $$section(use, :, 1, 1) dep_args = - for (use, 1) { + seen = + for(ever) { + isEmpty(1): break() + use = $$take_last(1) + contains(seen, $$use): next() + seen += $$use use_cfg = $$section(use, :, 0, 0) - use_lib = $$section(use, :, 1, 1) - dep_uses += $$use_lib !isEmpty(use_cfg) { + use_lib = $$section(use, :, 1, 1) lpfx = $${use_cfg}.libraries.$$use_lib - dep_args += $$qtConfLibraryArgs($${lpfx}.sources.$$eval($${lpfx}.source)) + dep_args += $$qtConfLibraryArgs($${lpfx}.sources.$$eval($${lpfx}.source), $$lpfx) + 1 += $$eval($${lpfx}.dependencies) } } return("QMAKE_USE += $$dep_uses" $$dep_args) @@ -818,6 +849,24 @@ defineTest(qtConfExportLibrary) { !isEmpty(defines): qtConfOutputVar(assign, $$output, QMAKE_DEFINES_$$NAME, $$defines) includes = $$eval($${spfx}.includedir) !isEmpty(includes): qtConfOutputVar(assign, $$output, QMAKE_INCDIR_$$NAME, $$includes) + uses = $$eval($${lpfx}.dependencies) + !isEmpty(uses) { + # FIXME: ideally, we would export transitive deps only for static + # libs, to not extend the link interface unduly. however, the system + # does currently not differentiate between public and private deps. + depends = + for (use, uses) { + use_cfg = $$section(use, :, 0, 0) + use_lib = $$section(use, :, 1, 1) + !isEmpty(use_cfg): \ + depends += $$upper($$eval($${use_cfg}.libraries.$${use_lib}.export)) + else: \ + depends += $$upper($$use_lib) + } + # we use suffixes instead of infixes, because $$resolve_depends() demands it. + qtConfOutputVar(assign, $$output, QMAKE_DEPENDS_$${NAME}_CC, $$depends) + qtConfOutputVar(assign, $$output, QMAKE_DEPENDS_$${NAME}_LD, $$depends) + } !isEmpty($${currentConfig}.module): \ qtConfExtendVar($$output, "QT.$${currentModule}_private.libraries", $$name) } @@ -843,7 +892,8 @@ defineTest(qtConfHandleLibrary) { export($${lpfx}.result) return() } - resolved_uses = $$eval($${lpfx}.resolved_uses) + $${lpfx}.dependencies = $$eval($${lpfx}.resolved_uses) + export($${lpfx}.dependencies) qtConfLoadResult($${lpfx}, $$1, "library") { $$eval($${lpfx}.result): \ @@ -881,7 +931,7 @@ defineTest(qtConfHandleLibrary) { # if the library defines a test, use it to verify the source. !isEmpty($${lpfx}.test)|!isEmpty($${lpfx}.test._KEYS_) { - $${lpfx}.resolved_uses = $$currentConfig:$$1 $$resolved_uses + $${lpfx}.resolved_uses = $$currentConfig:$$1 $${lpfx}.host = $$eval($${spfx}.host) !qtConfTest_compile($$lpfx) { qtLog(" => source failed verification.") diff --git a/mkspecs/features/qt_helper_lib.prf b/mkspecs/features/qt_helper_lib.prf index 1a8446acb4..05d3b941bd 100644 --- a/mkspecs/features/qt_helper_lib.prf +++ b/mkspecs/features/qt_helper_lib.prf @@ -41,7 +41,20 @@ THE_TARGET = $$qt5LibraryTarget($$TARGET) prefix = $$QMAKE_PREFIX_SHLIB suffix = $$QMAKE_EXTENSION_SHLIB } + CC_USES = + LD_USES = + for (use, QMAKE_USE) { + use = $$split(use, /) + name = $$take_first(use) + nu = $$upper($$name) + !contains(use, linkonly): CC_USES += $$nu + !contains(use, nolink): LD_USES += $$nu + } + CC_USES = $$unique(CC_USES) + LD_USES = $$unique(LD_USES) MODULE_PRI_CONT = \ + "QMAKE_DEPENDS_$${ucmodule}_CC =$$join(CC_USES, " ", " ")" \ + "QMAKE_DEPENDS_$${ucmodule}_LD =$$join(LD_USES, " ", " ")" \ "QMAKE_INCDIR_$${ucmodule} = $$val_escape(MODULE_INCLUDEPATH)" \ "QMAKE_DEFINES_$${ucmodule} = $$val_escape(MODULE_DEFINES)" debug_and_release { diff --git a/mkspecs/features/qt_module_pris.prf b/mkspecs/features/qt_module_pris.prf index 163f52f23f..e0556ce960 100644 --- a/mkspecs/features/qt_module_pris.prf +++ b/mkspecs/features/qt_module_pris.prf @@ -56,6 +56,7 @@ defineReplace(qtExportLibsForModule) { for (lib, QT.$${1}.libraries) { NAME = $$upper($$lib) vars = \ + QMAKE_DEPENDS_$${NAME}_CC QMAKE_DEPENDS_$${NAME}_LD \ QMAKE_LIBS_$$NAME QMAKE_LIBS_$${NAME}_DEBUG QMAKE_LIBS_$${NAME}_RELEASE \ QMAKE_DEFINES_$$NAME QMAKE_INCDIR_$$NAME for (var, vars) { From fc2c4edcbda8be88900201383b5113e234b09d71 Mon Sep 17 00:00:00 2001 From: Tim Blechmann Date: Wed, 10 May 2017 12:56:51 +0200 Subject: [PATCH 0552/1650] configure: fix linking with statically linked freetype freetype depends on zlib. using statically linked freetype as system library lacks the usage requirement to link with zlib. so we need to add this manually. Task-number: QTBUG-63115 Change-Id: Iaf0f3027bd9d1386fcc1ecfbfbe07ab09b2d0bb9 Reviewed-by: Oswald Buddenhagen Reviewed-by: Joerg Bornemann --- src/gui/configure.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/configure.json b/src/gui/configure.json index 6a2f1fe434..0d4f167d47 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -164,6 +164,9 @@ { "type": "pkgConfig", "args": "freetype2" }, { "type": "freetype", "libs": "-lfreetype", "condition": "!config.wasm" }, { "type": "freetype", "libs": "-s USE_FREETYPE=1", "condition": "config.wasm" } + ], + "use": [ + { "lib": "zlib", "condition": "features.system-zlib" } ] }, "fontconfig": { From b6737b7ecd54484eda471b905d25cc1a17c4e072 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 19 Oct 2018 19:30:33 +0200 Subject: [PATCH 0553/1650] wasm: fix freetype library source Change-Id: Ib99c4c178808c7325e55e85a1548542ae3c57524 Reviewed-by: Lorn Potter --- src/gui/configure.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/configure.json b/src/gui/configure.json index 0d4f167d47..3d0f75254a 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -163,7 +163,7 @@ "sources": [ { "type": "pkgConfig", "args": "freetype2" }, { "type": "freetype", "libs": "-lfreetype", "condition": "!config.wasm" }, - { "type": "freetype", "libs": "-s USE_FREETYPE=1", "condition": "config.wasm" } + { "libs": "-s USE_FREETYPE=1", "condition": "config.wasm" } ], "use": [ { "lib": "zlib", "condition": "features.system-zlib" } From 118b456c6b6bb81b879b4c8940414c0c10a57d4a Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 1 Dec 2017 19:25:43 +0100 Subject: [PATCH 0554/1650] configure: convert xlib to a proper library definition Change-Id: I1623aee9e8632e4bfd466e09e275cc23f94c6dab Reviewed-by: Gatis Paeglis --- config.tests/x11/xrender/xrender.pro | 1 - src/gui/configure.json | 30 ++++++++++--------- .../eglconvenience/eglconvenience.pro | 2 +- .../glxconvenience/glxconvenience.pro | 2 +- 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/config.tests/x11/xrender/xrender.pro b/config.tests/x11/xrender/xrender.pro index ab5c5efa77..6244ae6b47 100644 --- a/config.tests/x11/xrender/xrender.pro +++ b/config.tests/x11/xrender/xrender.pro @@ -1,3 +1,2 @@ SOURCES = xrender.cpp -CONFIG += x11 CONFIG -= qt diff --git a/src/gui/configure.json b/src/gui/configure.json index 3d0f75254a..123ef208a2 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -454,6 +454,19 @@ { "type": "pkgConfig", "args": "wayland-server" } ] }, + "xlib": { + "label": "XLib", + "test": { + "include": "X11/Xlib.h", + "main": [ + "Display *d = XOpenDisplay(NULL);", + "XCloseDisplay(d);" + ] + }, + "sources": [ + { "type": "makeSpec", "spec": "X11" } + ] + }, "x11sm": { "label": "X11 session management", "sources": [ @@ -626,7 +639,8 @@ "test": "x11/xrender", "sources": [ "-lXrender" - ] + ], + "use": "xlib" } }, @@ -913,18 +927,6 @@ "pkg-config-variable": "prefix", "value": "/usr", "log": "value" - }, - "xlib": { - "label": "XLib", - "type": "compile", - "test": { - "include": "X11/Xlib.h", - "main": [ - "Display *d = XOpenDisplay(NULL);", - "XCloseDisplay(d);" - ], - "qmake": "CONFIG += x11" - } } }, @@ -1374,7 +1376,7 @@ "xlib": { "label": "XLib", "autoDetect": "!config.darwin || features.xcb", - "condition": "tests.xlib", + "condition": "libs.xlib", "output": [ "privateFeature" ] }, "texthtmlparser": { diff --git a/src/platformsupport/eglconvenience/eglconvenience.pro b/src/platformsupport/eglconvenience/eglconvenience.pro index 4301d63574..aae72e8e27 100644 --- a/src/platformsupport/eglconvenience/eglconvenience.pro +++ b/src/platformsupport/eglconvenience/eglconvenience.pro @@ -34,7 +34,7 @@ qtConfig(xlib) { qxlibeglintegration_p.h SOURCES += \ qxlibeglintegration.cpp - LIBS_PRIVATE += $$QMAKE_LIBS_X11 + QMAKE_USE_PRIVATE += xlib } CONFIG += egl diff --git a/src/platformsupport/glxconvenience/glxconvenience.pro b/src/platformsupport/glxconvenience/glxconvenience.pro index 58fa9fc479..8367dc5e31 100644 --- a/src/platformsupport/glxconvenience/glxconvenience.pro +++ b/src/platformsupport/glxconvenience/glxconvenience.pro @@ -6,7 +6,7 @@ CONFIG += static internal_module DEFINES += QT_NO_CAST_FROM_ASCII -LIBS_PRIVATE += $$QMAKE_LIBS_X11 +QMAKE_USE_PRIVATE += xlib HEADERS += qglxconvenience_p.h SOURCES += qglxconvenience.cpp From 3ee7aa72b78d892153439b668aa9f0a786d9f70e Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 21 Dec 2017 18:26:22 +0100 Subject: [PATCH 0555/1650] configure: atomize xcb-* tests properly xcb is a dependency which should be detected upfront. same for xlib. this also removes calls to functions coming from the dependencies from the tests (both because these calls prove nothing, and because at some point we will stop linking transitive deps). Change-Id: Iac77305eab33ea8ff5c71302cef980eb908d8403 Reviewed-by: Gatis Paeglis --- src/gui/configure.json | 55 ++++++++++--------- .../deviceintegration/eglfs_x11/eglfs_x11.pro | 2 +- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/gui/configure.json b/src/gui/configure.json index 123ef208a2..7b78954038 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -517,16 +517,14 @@ "xcb_xlib": { "label": "XCB Xlib", "test": { - "include": [ "xcb/xcb.h", "X11/Xlib.h", "X11/Xlib-xcb.h" ], - "main": [ - "Display *dpy = XOpenDisplay(\"\");", - "(void) XGetXCBConnection(dpy);" - ] + "include": "X11/Xlib-xcb.h", + "main": "(void) XGetXCBConnection((Display *)0);" }, "sources": [ - { "type": "pkgConfig", "args": "x11-xcb x11 xcb" }, - "-lxcb -lX11 -lX11-xcb" - ] + { "type": "pkgConfig", "args": "x11-xcb" }, + "-lX11-xcb" + ], + "use": "xcb xlib" }, "xcb_xkb": { "label": "XCB XKB >= 1.10", @@ -543,14 +541,15 @@ ] }, "sources": [ - { "type": "pkgConfig", "args": "xcb-xkb >= 1.10 xcb" }, - "-lxcb-xkb -lxcb" - ] + { "type": "pkgConfig", "args": "xcb-xkb >= 1.10" }, + "-lxcb-xkb" + ], + "use": "xcb" }, "xcb_render": { "label": "XCB XRender", "test": { - "include": [ "xcb/xcb.h", "xcb/render.h" ], + "include": "xcb/render.h", "tail": [ "// 'template' is used as a function argument name in xcb_renderutil.h", "#define template template_param", @@ -563,7 +562,7 @@ "main": [ "int primaryScreen = 0;", "xcb_generic_error_t *error = 0;", - "xcb_connection_t *connection = xcb_connect(\"\", &primaryScreen);", + "xcb_connection_t *connection = 0;", "xcb_render_query_pict_formats_cookie_t formatsCookie =", " xcb_render_query_pict_formats(connection);", "xcb_render_query_pict_formats_reply_t *formatsReply =", @@ -574,17 +573,18 @@ ] }, "sources": [ - { "type": "pkgConfig", "args": "xcb-renderutil xcb-render xcb" }, - "-lxcb-render-util -lxcb-render -lxcb" - ] + { "type": "pkgConfig", "args": "xcb-renderutil xcb-render" }, + "-lxcb-render-util -lxcb-render" + ], + "use": "xcb" }, "xcb_glx": { "label": "XCB GLX", "test": { - "include": [ "xcb/xcb.h", "xcb/glx.h" ], + "include": "xcb/glx.h", "main": [ "int primaryScreen = 0;", - "xcb_connection_t *connection = xcb_connect(\"\", &primaryScreen);", + "xcb_connection_t *connection = 0;", "xcb_generic_error_t *error = 0;", "xcb_glx_query_version_cookie_t xglx_query_cookie = xcb_glx_query_version(", " connection, XCB_GLX_MAJOR_VERSION, XCB_GLX_MINOR_VERSION);", @@ -592,17 +592,17 @@ ] }, "sources": [ - { "type": "pkgConfig", "args": "xcb-glx xcb" }, - "-lxcb-glx -lxcb" - ] + { "type": "pkgConfig", "args": "xcb-glx" }, + "-lxcb-glx" + ], + "use": "xcb" }, "xcb_xinput": { "label": "XCB XInput", "test": { - "include": [ "xcb/xcb.h", "xcb/xinput.h" ], + "include": "xcb/xinput.h", "main": [ - "int primaryScreen = 0;", - "xcb_connection_t *connection = xcb_connect(\"\", &primaryScreen);", + "xcb_connection_t *connection = 0;", "xcb_generic_error_t *error = 0;", "xcb_input_xi_query_version_cookie_t xinput_query_cookie = xcb_input_xi_query_version(", " connection, XCB_INPUT_MAJOR_VERSION, XCB_INPUT_MINOR_VERSION);", @@ -610,9 +610,10 @@ ] }, "sources": [ - { "type": "pkgConfig", "args": "xcb-xinput >= 1.12 xcb" }, - "-lxcb-xinput -lxcb" - ] + { "type": "pkgConfig", "args": "xcb-xinput >= 1.12" }, + "-lxcb-xinput" + ], + "use": "xcb" }, "xkbcommon": { "label": "xkbcommon >= 0.5.0", diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro index acbd1cc785..6b55918f03 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro @@ -8,7 +8,7 @@ DEFINES += QT_EGL_NO_X11 INCLUDEPATH += $$PWD/../../api CONFIG += egl -QMAKE_USE += xcb_xlib +QMAKE_USE += xcb_xlib xcb xlib SOURCES += $$PWD/qeglfsx11main.cpp \ $$PWD/qeglfsx11integration.cpp From 501ff0a18cff37cf0d237cd2b04b35fff1bd0837 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 21 Dec 2017 20:33:20 +0100 Subject: [PATCH 0556/1650] untangle the egl-x11 relationship in the build system egl-x11 is used in two places: - the eglfs-x11 plugin, which has a hard dependency on xcb-xlib - the xcb-egl plugin, which has a soft dependency on xcb-xlib that means that the egl-x11 configure test needs to be untangled from xcb, and that eglfs-x11 should be a separate feature with a proper dependency declaration. when the plugins that need egl-x11 are not built, it also makes no sense to build the respective integration in the egl_support module (even if it's possible to coax it into building), so adjust things accordingly. Change-Id: Ic729d0b7c893dd00844567329205c24ea2703033 Reviewed-by: Gatis Paeglis --- src/gui/configure.json | 11 ++++++++--- src/platformsupport/eglconvenience/eglconvenience.pro | 8 ++++---- .../eglfs/deviceintegration/deviceintegration.pro | 2 +- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/gui/configure.json b/src/gui/configure.json index 7b78954038..7585e9c8d4 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -715,7 +715,7 @@ "// window and pixmap types will be different than what an X-based platform", "// plugin would expect." ], - "include": [ "EGL/egl.h", "xcb/xcb.h", "X11/Xlib.h", "X11/Xlib-xcb.h" ], + "include": [ "EGL/egl.h", "X11/Xlib.h" ], "main": [ "Display *dpy = EGL_DEFAULT_DISPLAY;", "EGLNativeDisplayType egldpy = XOpenDisplay(\"\");", @@ -725,7 +725,7 @@ "XCloseDisplay(dpy);" ] }, - "use": "egl xcb_xlib" + "use": "egl xlib" }, "egl-brcm": { "label": "Broadcom EGL (Raspberry Pi)", @@ -1229,6 +1229,11 @@ "condition": "config.integrity && features.eglfs && tests.egl-openwfd", "output": [ "privateFeature" ] }, + "eglfs_x11": { + "label": "EGLFS X11", + "condition": "features.eglfs && features.xcb && features.xcb-xlib && features.egl_x11", + "output": [ "privateFeature" ] + }, "gif": { "label": "GIF", "condition": "features.imageformatplugin", @@ -1709,7 +1714,7 @@ QMAKE_LIBDIR_OPENGL[_ES2] and QMAKE_LIBS_OPENGL[_ES2] in the mkspec for your pla "section": "EGLFS details", "condition": "features.eglfs", "entries": [ - "eglfs_openwfd", "eglfs_viv", "eglfs_viv_wl", "eglfs_rcar", "eglfs_egldevice", "eglfs_gbm", "eglfs_vsp2", "eglfs_mali", "eglfs_brcm", "egl_x11" + "eglfs_openwfd", "eglfs_viv", "eglfs_viv_wl", "eglfs_rcar", "eglfs_egldevice", "eglfs_gbm", "eglfs_vsp2", "eglfs_mali", "eglfs_brcm", "eglfs_x11" ] }, "linuxfb", "vnc", "mirclient", diff --git a/src/platformsupport/eglconvenience/eglconvenience.pro b/src/platformsupport/eglconvenience/eglconvenience.pro index aae72e8e27..df21f14697 100644 --- a/src/platformsupport/eglconvenience/eglconvenience.pro +++ b/src/platformsupport/eglconvenience/eglconvenience.pro @@ -26,15 +26,15 @@ qtConfig(opengl) { qeglpbuffer.cpp } -# Avoid X11 header collision, use generic EGL native types -DEFINES += QT_EGL_NO_X11 - -qtConfig(xlib) { +qtConfig(egl_x11) { HEADERS += \ qxlibeglintegration_p.h SOURCES += \ qxlibeglintegration.cpp QMAKE_USE_PRIVATE += xlib +} else { + # Avoid X11 header collision, use generic EGL native types + DEFINES += QT_EGL_NO_X11 } CONFIG += egl diff --git a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro index 919ecd01f6..360536d22f 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro @@ -1,7 +1,7 @@ TEMPLATE = subdirs QT_FOR_CONFIG += gui-private -qtConfig(egl_x11): SUBDIRS += eglfs_x11 +qtConfig(eglfs_x11): SUBDIRS += eglfs_x11 qtConfig(eglfs_gbm): SUBDIRS *= eglfs_kms_support eglfs_kms qtConfig(eglfs_egldevice): SUBDIRS *= eglfs_kms_support eglfs_kms_egldevice qtConfig(eglfs_vsp2): SUBDIRS += eglfs_kms_vsp2 From c4ee12589122923e680e8dd359c30f6dde370f54 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 27 Nov 2018 10:47:52 +0100 Subject: [PATCH 0557/1650] Set QScroller's parent to its widget, for memory management If the widget to which the scroller was assigned is deleted, the QScroller ought to be deleted too, to avoid filtering events and then following a dangling pointer while trying to react. Fixes: QTBUG-71232 Change-Id: I62680df8d84fb630df1bd8c482df099989457542 Reviewed-by: Friedemann Kleint Reviewed-by: Robert Griebl --- src/widgets/util/qscroller.cpp | 1 + .../widgets/util/qscroller/tst_qscroller.cpp | 38 ++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/widgets/util/qscroller.cpp b/src/widgets/util/qscroller.cpp index abb203b8cc..1e84237253 100644 --- a/src/widgets/util/qscroller.cpp +++ b/src/widgets/util/qscroller.cpp @@ -488,6 +488,7 @@ QScroller::QScroller(QObject *target) : d_ptr(new QScrollerPrivate(this, target)) { Q_ASSERT(target); // you can't create a scroller without a target in any normal way + setParent(target); Q_D(QScroller); d->init(); } diff --git a/tests/auto/widgets/util/qscroller/tst_qscroller.cpp b/tests/auto/widgets/util/qscroller/tst_qscroller.cpp index fac13c7074..8bdd4b4783 100644 --- a/tests/auto/widgets/util/qscroller/tst_qscroller.cpp +++ b/tests/auto/widgets/util/qscroller/tst_qscroller.cpp @@ -125,6 +125,7 @@ private slots: void scrollTo(); void scroll(); void overshoot(); + void multipleWindows(); private: QTouchDevice *m_touchScreen = QTest::createTouchDevice(); @@ -373,7 +374,7 @@ void tst_QScroller::scrollTo() void tst_QScroller::scroll() { -#ifndef QT_NO_GESTURES +#if QT_CONFIG(gestures) && QT_CONFIG(scroller) // -- good case. normal scroll tst_QScrollerWidget *sw = new tst_QScrollerWidget(); sw->scrollArea = QRectF(0, 0, 1000, 1000); @@ -413,7 +414,7 @@ void tst_QScroller::scroll() void tst_QScroller::overshoot() { -#ifndef QT_NO_GESTURES +#if QT_CONFIG(gestures) && QT_CONFIG(scroller) tst_QScrollerWidget *sw = new tst_QScrollerWidget(); sw->scrollArea = QRectF(0, 0, 1000, 1000); QScroller::grabGesture(sw, QScroller::TouchGesture); @@ -504,6 +505,39 @@ void tst_QScroller::overshoot() #endif } +void tst_QScroller::multipleWindows() +{ +#if QT_CONFIG(gestures) && QT_CONFIG(scroller) + QScopedPointer sw1(new tst_QScrollerWidget()); + sw1->scrollArea = QRectF(0, 0, 1000, 1000); + QScroller::grabGesture(sw1.data(), QScroller::TouchGesture); + sw1->setGeometry(100, 100, 400, 300); + QScroller *s1 = QScroller::scroller(sw1.data()); + kineticScroll(sw1.data(), QPointF(500, 500), QPoint(0, 0), QPoint(100, 100), QPoint(200, 200)); + // now we should be scrolling + QTRY_COMPARE( s1->state(), QScroller::Scrolling ); + + // That was fun! Do it again! + QScopedPointer sw2(new tst_QScrollerWidget()); + sw2->scrollArea = QRectF(0, 0, 1000, 1000); + QScroller::grabGesture(sw2.data(), QScroller::TouchGesture); + sw2->setGeometry(100, 100, 400, 300); + QScroller *s2 = QScroller::scroller(sw2.data()); + kineticScroll(sw2.data(), QPointF(500, 500), QPoint(0, 0), QPoint(100, 100), QPoint(200, 200)); + // now we should be scrolling + QTRY_COMPARE( s2->state(), QScroller::Scrolling ); + + // wait for both to stop + QTRY_VERIFY(s1->state() != QScroller::Scrolling); + QTRY_VERIFY(s2->state() != QScroller::Scrolling); + + sw1.reset(); // destroy one window + sw2->reset(); // reset the other scroller's internal state + // make sure we can still scroll the remaining one without crashing (QTBUG-71232) + kineticScroll(sw2.data(), QPointF(500, 500), QPoint(0, 0), QPoint(100, 100), QPoint(200, 200)); +#endif +} + QTEST_MAIN(tst_QScroller) #include "tst_qscroller.moc" From 25231c40489e54d57998fa44385ad832cc32b30d Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Mon, 3 Dec 2018 19:36:54 +0100 Subject: [PATCH 0558/1650] QToolButton: Don't elide text if an icon is present MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous fix which adds an automatic text elision when the QToolButton is not large enough brought up an inconsistency between QToolButton::sizeHint() and QCommonStyle::drawControl(). Fix it by syncing the magic numbers between QToolButton::sizeHint() and QCommonStyle::drawControl(). Fixes: QTBUG-72226 Change-Id: If4a76792cb97bcdb918e18c6b29cb637730acec0 Reviewed-by: André Hartmann Reviewed-by: Alessandro Portale Reviewed-by: Thorbjørn Lund Martsum --- src/widgets/styles/qcommonstyle.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index bb623d9c04..10dfad2754 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -1654,7 +1654,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, alignment |= Qt::TextHideMnemonic; if (toolbutton->toolButtonStyle == Qt::ToolButtonTextUnderIcon) { - pr.setHeight(pmSize.height() + 6); + pr.setHeight(pmSize.height() + 4); //### 4 is currently hardcoded in QToolButton::sizeHint() tr.adjust(0, pr.height() - 1, 0, -1); pr.translate(shiftX, shiftY); if (!hasArrow) { @@ -1664,7 +1664,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, } alignment |= Qt::AlignCenter; } else { - pr.setWidth(pmSize.width() + 8); + pr.setWidth(pmSize.width() + 4); //### 4 is currently hardcoded in QToolButton::sizeHint() tr.adjust(pr.width(), 0, 0, 0); pr.translate(shiftX, shiftY); if (!hasArrow) { From a71f50edc6431a7d5a8b4a4836e98ca59e6ad7ae Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 7 Dec 2018 12:07:53 +0000 Subject: [PATCH 0559/1650] Revert "Ensure alignment of image-data" This reverts commit ae8389e19c5804c867b2981311c623003a691474. The result of malloc should be aligned in any case, and this change conflicts with the use of realloc on the data elsewhere. Change-Id: I01773132b240614a2656dd3013490b0df9cd14a7 Reviewed-by: Kirill Burtsev Reviewed-by: Thiago Macieira --- src/gui/image/qimage.cpp | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index da963adae6..0105f1decd 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -149,10 +149,7 @@ QImageData * QImageData::create(const QSize &size, QImage::Format format) d->bytes_per_line = params.bytesPerLine; d->nbytes = params.totalSize; - if (depth == 64) - d->data = (uchar *)new (std::nothrow) quint64[d->nbytes / sizeof(quint64)]; - else // nbytes is known to already be a multipla of 4: - d->data = (uchar *)new (std::nothrow) quint32[d->nbytes / sizeof(quint32)]; + d->data = (uchar *)malloc(d->nbytes); if (!d->data) return nullptr; @@ -168,13 +165,8 @@ QImageData::~QImageData() if (is_cached) QImagePixmapCleanupHooks::executeImageHooks((((qint64) ser_no) << 32) | ((qint64) detach_no)); delete paintEngine; - if (data && own_data) { - // Casting to avoid being theoretically UB: - if (depth == 64) - delete[] (quint64 *)data; - else - delete[] (quint32 *)data; - } + if (data && own_data) + free(data); data = 0; } From e12aad05f039ddaefd444f80246845090ef9ce13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 28 Nov 2018 16:56:44 +0100 Subject: [PATCH 0560/1650] Add manual test case for verifying our text rendering Allows comparing Qt's text rendering to the native rendering. Change-Id: I56f015fb64df3f70c33db58891876c325cbbc55d Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../manual/textrendering/nativetext/main.cpp | 310 ++++++++++++++++++ .../textrendering/nativetext/nativetext.pro | 7 + tests/manual/textrendering/textrendering.pro | 3 +- 3 files changed, 319 insertions(+), 1 deletion(-) create mode 100644 tests/manual/textrendering/nativetext/main.cpp create mode 100644 tests/manual/textrendering/nativetext/nativetext.pro diff --git a/tests/manual/textrendering/nativetext/main.cpp b/tests/manual/textrendering/nativetext/main.cpp new file mode 100644 index 0000000000..5c7621e61f --- /dev/null +++ b/tests/manual/textrendering/nativetext/main.cpp @@ -0,0 +1,310 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#ifdef Q_OS_DARWIN +#include +#include +#include +#include +#include +#endif + +static int s_mode; +static QString s_text = QString::fromUtf8("The quick brown \xF0\x9F\xA6\x8A jumps over the lazy \xF0\x9F\x90\xB6"); + +class TextRenderer : public QWidget +{ + Q_OBJECT +public: + enum RenderingMode { QtRendering, NativeRendering }; + Q_ENUM(RenderingMode); + + TextRenderer(qreal pointSize, const QString &text, const QColor &textColor = QColor(), const QColor &bgColor = QColor()) + : m_text(text) + { + if (pointSize) { + QFont f = font(); + f.setPointSize(pointSize); + setFont(f); + } + + if (textColor.isValid()) { + QPalette p = palette(); + p.setColor(QPalette::Text, textColor); + setPalette(p); + } + + if (bgColor.isValid()) { + QPalette p = palette(); + p.setColor(QPalette::Window, bgColor); + setPalette(p); + } + } + + QString text() const + { + return !m_text.isNull() ? m_text : s_text; + } + + QSize sizeHint() const override + { + QFontMetrics fm = fontMetrics(); + return QSize(fm.boundingRect(text()).width(), fm.height()); + } + + bool event(QEvent * event) override + { + if (event->type() == QEvent::ToolTip) { + QString toolTip; + QDebug debug(&toolTip); + debug << "textColor =" << palette().color(QPalette::Text) << "bgColor =" << palette().color(QPalette::Window); + setToolTip(toolTip); + } + + return QWidget::event(event); + } + + void paintEvent(QPaintEvent *) override + { + QImage image(size() * devicePixelRatio(), QImage::Format_ARGB32_Premultiplied); + image.setDevicePixelRatio(devicePixelRatio()); + + QPainter p(&image); + p.fillRect(QRect(0, 0, image.width(), image.height()), palette().window().color()); + + const int ascent = fontMetrics().ascent(); + + p.setPen(Qt::magenta); + p.drawLine(QPoint(0, ascent), QPoint(width(), ascent)); + p.end(); + + if (s_mode == QtRendering) + renderQtText(image); + else + renderNativeText(image); + + QPainter wp(this); + wp.drawImage(QPoint(0, 0), image); + } + + void renderQtText(QImage &image) + { + QPainter p(&image); + + const int ascent = fontMetrics().ascent(); + + p.setPen(palette().text().color()); + + QFont f = font(); + f.resolve(-1); + p.setFont(f); + + p.drawText(QPoint(0, ascent), text()); + } + + void renderNativeText(QImage &image) + { +#ifdef Q_OS_DARWIN + QMacAutoReleasePool pool; + QMacCGContext ctx(&image); + + const auto *fontEngine = QFontPrivate::get(font())->engineForScript(QChar::Script_Common); + Q_ASSERT(fontEngine); + if (fontEngine->type() == QFontEngine::Multi) { + fontEngine = static_cast(fontEngine)->engine(0); + Q_ASSERT(fontEngine); + } + Q_ASSERT(fontEngine->type() == QFontEngine::Mac); + + QColor textColor = palette().text().color(); + auto nsColor = [NSColor colorWithSRGBRed:textColor.redF() + green:textColor.greenF() + blue:textColor.blueF() + alpha:textColor.alphaF()]; + + if (font().styleStrategy() & QFont::NoAntialias) + CGContextSetShouldAntialias(ctx, false); + + // Retain count already tracked by QMacCGContext above + NSGraphicsContext.currentContext = [NSGraphicsContext graphicsContextWithCGContext:ctx flipped:YES]; + [text().toNSString() drawAtPoint:CGPointZero withAttributes:@{ + NSFontAttributeName : (NSFont *)fontEngine->handle(), + NSForegroundColorAttributeName : nsColor + }]; + NSGraphicsContext.currentContext = nil; +#endif + } + +public: + + RenderingMode m_mode = QtRendering; + QString m_text; +}; + +class TestWidget : public QWidget +{ + Q_OBJECT +public: + TestWidget() + { + auto *mainLayout = new QVBoxLayout; + + m_previews = new QWidget; + m_previews->setLayout(new QHBoxLayout); + + for (int i = 0; i < 6; ++i) { + auto *layout = new QVBoxLayout; + QString text; + if (i > 0) + text = "ABC"; + + QPair color = [i] { + switch (i) { + case 0: return qMakePair(QColor(), QColor()); + case 1: return qMakePair(QColor(Qt::black), QColor(Qt::white)); + case 2: return qMakePair(QColor(Qt::white), QColor(Qt::black)); + case 3: return qMakePair(QColor(Qt::green), QColor(Qt::red)); + case 4: return qMakePair(QColor(0, 0, 0, 128), QColor(Qt::white)); + case 5: return qMakePair(QColor(255, 255, 255, 128), QColor(Qt::black)); + default: return qMakePair(QColor(), QColor()); + } + }(); + + layout->addWidget(new TextRenderer(12, text, color.first, color.second)); + layout->addWidget(new TextRenderer(24, text, color.first, color.second)); + layout->addWidget(new TextRenderer(36, text, color.first, color.second)); + layout->addWidget(new TextRenderer(48, text, color.first, color.second)); + static_cast(m_previews->layout())->addLayout(layout); + } + + mainLayout->addWidget(m_previews); + + auto *controls = new QHBoxLayout; + auto *lineEdit = new QLineEdit(s_text); + connect(lineEdit, &QLineEdit::textChanged, [&](const QString &text) { + s_text = text; + for (TextRenderer *renderer : m_previews->findChildren()) + renderer->updateGeometry(); + }); + controls->addWidget(lineEdit); + + auto *colorButton = new QPushButton("Color..."); + connect(colorButton, &QPushButton::clicked, [&] { + auto *colorDialog = new QColorDialog(this); + colorDialog->setOptions(QColorDialog::NoButtons | QColorDialog::ShowAlphaChannel); + colorDialog->setModal(false); + connect(colorDialog, &QColorDialog::currentColorChanged, [&](const QColor &color) { + QPalette p = palette(); + p.setColor(QPalette::Text, color); + setPalette(p); + }); + colorDialog->setCurrentColor(palette().text().color()); + colorDialog->setVisible(true); + }); + controls->addWidget(colorButton); + auto *fontButton = new QPushButton("Font..."); + connect(fontButton, &QPushButton::clicked, [&] { + auto *fontDialog = new QFontDialog(this); + fontDialog->setOptions(QFontDialog::NoButtons); + fontDialog->setModal(false); + fontDialog->setCurrentFont(m_previews->font()); + connect(fontDialog, &QFontDialog::currentFontChanged, [&](const QFont &font) { + m_previews->setFont(font); + }); + fontDialog->setVisible(true); + }); + controls->addWidget(fontButton); + + auto *aaButton = new QCheckBox("NoAntialias"); + connect(aaButton, &QCheckBox::stateChanged, [&] { + for (TextRenderer *renderer : m_previews->findChildren()) { + QFont font = renderer->font(); + font.setStyleStrategy(QFont::StyleStrategy(font.styleStrategy() ^ QFont::NoAntialias)); + renderer->setFont(font); + } + }); + controls->addWidget(aaButton); + + auto *subpixelAAButton = new QCheckBox("NoSubpixelAntialias"); + connect(subpixelAAButton, &QCheckBox::stateChanged, [&] { + for (TextRenderer *renderer : m_previews->findChildren()) { + QFont font = renderer->font(); + font.setStyleStrategy(QFont::StyleStrategy(font.styleStrategy() ^ QFont::NoSubpixelAntialias)); + renderer->setFont(font); + } + }); + controls->addWidget(subpixelAAButton); + controls->addStretch(); + + mainLayout->addLayout(controls); + + mainLayout->setSizeConstraint(QLayout::SetFixedSize); + setLayout(mainLayout); + + setMode(TextRenderer::QtRendering); + setFocusPolicy(Qt::StrongFocus); + setFocus(); + } + + void setMode(TextRenderer::RenderingMode mode) + { + s_mode = mode; + setWindowTitle(s_mode == TextRenderer::QtRendering ? "Qt" : "Native"); + + for (TextRenderer *renderer : m_previews->findChildren()) + renderer->update(); + } + + void mousePressEvent(QMouseEvent *) override + { + setMode(TextRenderer::RenderingMode(!s_mode)); + } + + void keyPressEvent(QKeyEvent *e) override + { + if (e->key() == Qt::Key_Space) + setMode(TextRenderer::RenderingMode(!s_mode)); + } + + QWidget *m_previews; +}; + +int main(int argc, char **argv) +{ + qputenv("QT_MAX_CACHED_GLYPH_SIZE", "97"); + QApplication app(argc, argv); + + TestWidget widget; + widget.show(); + return app.exec(); +} + +#include "main.moc" + diff --git a/tests/manual/textrendering/nativetext/nativetext.pro b/tests/manual/textrendering/nativetext/nativetext.pro new file mode 100644 index 0000000000..fb3e3799e7 --- /dev/null +++ b/tests/manual/textrendering/nativetext/nativetext.pro @@ -0,0 +1,7 @@ +QT += widgets core-private gui-private +SOURCES += main.cpp +CONFIG -= app_bundle +darwin { + QMAKE_CXXFLAGS += -x objective-c++ + LIBS += -framework Foundation -framework CoreGraphics -framework AppKit +} diff --git a/tests/manual/textrendering/textrendering.pro b/tests/manual/textrendering/textrendering.pro index 92f0741bf3..14806e416c 100644 --- a/tests/manual/textrendering/textrendering.pro +++ b/tests/manual/textrendering/textrendering.pro @@ -1,4 +1,5 @@ TEMPLATE=subdirs SUBDIRS = glyphshaping \ - textperformance + textperformance \ + nativetext From 2e715c31ed3a37fc196e97d4c58d0e277b1b9215 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 5 Dec 2018 17:10:34 +0100 Subject: [PATCH 0561/1650] Allow overriding the maximum cached glyph size via the environment Useful for testing. Change-Id: I8cfd4453018cba0301287ad6a1c15a88cdc33c1c Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/painting/qpaintengineex.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 9f07af92e4..f4cbf15fc7 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -1090,9 +1090,14 @@ bool QPaintEngineEx::shouldDrawCachedGlyphs(QFontEngine *fontEngine, const QTran if (fontEngine->glyphFormat == QFontEngine::Format_ARGB) return true; + static const int maxCachedGlyphSizeSquared = std::pow([]{ + if (int env = qEnvironmentVariableIntValue("QT_MAX_CACHED_GLYPH_SIZE")) + return env; + return QT_MAX_CACHED_GLYPH_SIZE; + }(), 2); + qreal pixelSize = fontEngine->fontDef.pixelSize; - return (pixelSize * pixelSize * qAbs(m.determinant())) < - QT_MAX_CACHED_GLYPH_SIZE * QT_MAX_CACHED_GLYPH_SIZE; + return (pixelSize * pixelSize * qAbs(m.determinant())) < maxCachedGlyphSizeSquared; } QT_END_NAMESPACE From d36a4fc19709e6047fe846b36731b59909218b6d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 12 Sep 2018 23:06:40 -0700 Subject: [PATCH 0562/1650] Optimize further the loading of 8 Latin 1 characters This is important when AVX is enabled, which makes the VMOVQ load and the VPMOVZXBW instruction be combined into a single VPMOVZXBW with direct memory access. This is guaranteed to only read 8 bytes, so it's safe even close to the end of a page. Clang and ICC do combine the instructions like we want and I have filed a request for GCC to do so too[1]. AVX was first introduced in 2011, so plenty of computers today would benefit from this. [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87317 Change-Id: I8f261579aad648fdb4f0fffd1553e08e90df3171 Reviewed-by: Allan Sandfeld Jensen --- src/corelib/tools/qstring.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index edb9983c33..d20c46774d 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -415,6 +415,21 @@ static bool simdTestMask(const char *&ptr, const char *end, quint32 maskval) return true; } + +static Q_ALWAYS_INLINE __m128i mm_load8_zero_extend(const void *ptr) +{ + const __m128i *dataptr = static_cast(ptr); +#if defined(__SSE4_1__) + // use a MOVQ followed by PMOVZXBW + // if AVX2 is present, these should combine into a single VPMOVZXBW instruction + __m128i data = _mm_loadl_epi64(dataptr); + return _mm_cvtepu8_epi16(data); +# else + // use MOVQ followed by PUNPCKLBW + __m128i data = _mm_loadl_epi64(dataptr); + return _mm_unpacklo_epi8(data, _mm_setzero_si128()); +# endif +} #endif // Note: ptr on output may be off by one and point to a preceding US-ASCII @@ -585,8 +600,7 @@ void qt_from_latin1(ushort *dst, const char *str, size_t size) Q_DECL_NOTHROW // we're going to read str[offset..offset+7] (8 bytes) if (str + offset + 7 < e) { - const __m128i chunk = _mm_loadl_epi64(reinterpret_cast(str + offset)); - const __m128i unpacked = _mm_unpacklo_epi8(chunk, _mm_setzero_si128()); + const __m128i unpacked = mm_load8_zero_extend(str + offset); _mm_storeu_si128(reinterpret_cast<__m128i *>(dst + offset), unpacked); offset += 8; } @@ -1044,8 +1058,7 @@ static int ucstrncmp(const QChar *a, const uchar *c, size_t l) // we'll read uc[offset..offset+7] (16 bytes) and c[offset..offset+7] (8 bytes) if (uc + offset + 7 < e) { // same, but we're using an 8-byte load - __m128i chunk = _mm_loadl_epi64((const __m128i*)(c + offset)); - __m128i secondHalf = _mm_unpacklo_epi8(chunk, nullmask); + __m128i secondHalf = mm_load8_zero_extend(c + offset); __m128i ucdata = _mm_loadu_si128((const __m128i*)(uc + offset)); __m128i result = _mm_cmpeq_epi16(secondHalf, ucdata); From b2297e595c43a5986a082c40443576436f8497d0 Mon Sep 17 00:00:00 2001 From: Samuel Gaist Date: Mon, 19 Nov 2018 21:37:37 +0100 Subject: [PATCH 0563/1650] QUrlQuery: Implement initializer list constructor [ChangeLog][QtCore][QUrlQuery] QUrlQuery now provides an initializer list constructor. It can be created using a list of key/value pairs. Fixes: QTBUG-68645 Change-Id: Ief5939aa477718f6dd3580f2c60f95ff3aa892ae Reviewed-by: Thiago Macieira --- src/corelib/io/qurlquery.cpp | 8 ++++++++ src/corelib/io/qurlquery.h | 9 +++++++++ tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp | 8 ++++++++ 3 files changed, 25 insertions(+) diff --git a/src/corelib/io/qurlquery.cpp b/src/corelib/io/qurlquery.cpp index 97e7b8a4eb..10c3f836c8 100644 --- a/src/corelib/io/qurlquery.cpp +++ b/src/corelib/io/qurlquery.cpp @@ -145,6 +145,14 @@ QT_BEGIN_NAMESPACE \since 5.2 */ +/*! + \fn QUrlQuery(std::initializer_list> list) + + \since 5.13 + + Constructs a QUrlQuery object from the \a list of key/value pair. +*/ + typedef QList > Map; class QUrlQueryPrivate : public QSharedData diff --git a/src/corelib/io/qurlquery.h b/src/corelib/io/qurlquery.h index 092d002543..e3688aae2c 100644 --- a/src/corelib/io/qurlquery.h +++ b/src/corelib/io/qurlquery.h @@ -48,6 +48,8 @@ #include #endif +#include + QT_BEGIN_NAMESPACE Q_CORE_EXPORT uint qHash(const QUrlQuery &key, uint seed = 0) Q_DECL_NOTHROW; @@ -59,6 +61,13 @@ public: QUrlQuery(); explicit QUrlQuery(const QUrl &url); explicit QUrlQuery(const QString &queryString); + QUrlQuery(std::initializer_list> list) + : QUrlQuery() + { + for (const QPair &item : list) + addQueryItem(item.first, item.second); + } + QUrlQuery(const QUrlQuery &other); QUrlQuery &operator=(const QUrlQuery &other); #ifdef Q_COMPILER_RVALUE_REFS diff --git a/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp b/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp index d839141091..25d392b37e 100644 --- a/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp +++ b/tests/auto/corelib/io/qurlquery/tst_qurlquery.cpp @@ -233,6 +233,14 @@ void tst_QUrlQuery::constructing() query += qMakePair(QString("prosent"), QString("%")); copy.setQueryItems(query); QVERIFY(!copy.isEmpty()); + + QUrlQuery fromList = { + {QString("type"), QString("login")}, + {QString("name"), QString::fromUtf8("åge nissemannsen")}, + {QString("ole&du"), QString::fromUtf8("anne+jørgen=sant")}, + {QString("prosent"), QString("%")} + }; + QCOMPARE(fromList, copy); } void tst_QUrlQuery::addRemove() From 8d7542acad18a2f1be701242d655015263f3147a Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Wed, 5 Dec 2018 16:32:12 +0300 Subject: [PATCH 0564/1650] Do not use arc4random_buf() on GNU/kFreeBSD It is not available in the GNU C Library. Change-Id: I36dc92fca283c126669885b75406c8e57f563ce3 Reviewed-by: Thiago Macieira --- src/corelib/global/qrandom.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp index 03534cf453..6195c324e7 100644 --- a/src/corelib/global/qrandom.cpp +++ b/src/corelib/global/qrandom.cpp @@ -48,7 +48,7 @@ #include -#if !QT_CONFIG(getentropy) && !defined(Q_OS_BSD4) && !defined(Q_OS_WIN) +#if !QT_CONFIG(getentropy) && (!defined(Q_OS_BSD4) || defined(__GLIBC__)) && !defined(Q_OS_WIN) # include "qdeadlinetimer.h" # include "qhashfunctions.h" @@ -259,7 +259,7 @@ static void fallback_fill(quint32 *, qsizetype) Q_DECL_NOTHROW // no fallback necessary, getentropy cannot fail under normal circumstances Q_UNREACHABLE(); } -#elif defined(Q_OS_BSD4) +#elif defined(Q_OS_BSD4) && !defined(__GLIBC__) static void fallback_update_seed(unsigned) {} static void fallback_fill(quint32 *ptr, qsizetype left) Q_DECL_NOTHROW { From 161c5693143783e0364d32c587497669747efc45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 6 Dec 2018 14:46:26 +0100 Subject: [PATCH 0565/1650] macOS: Reset font glyph caches when application theme changes Our glyph caches on 10.14 are based on the application appearance, so when the application goes from dark to light or light to dark, we need to reset and re-populate the glyph-caches to account for the new appearance. Change-Id: If019d8cfa33ffb2b14747444b2ff74b288992f55 Fixes: QTBUG-71018 Reviewed-by: Timur Pocheptsov --- src/gui/text/qfont_p.h | 2 +- src/plugins/platforms/cocoa/qcocoatheme.mm | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h index 350ba7ce3c..c5847f532b 100644 --- a/src/gui/text/qfont_p.h +++ b/src/gui/text/qfont_p.h @@ -210,7 +210,7 @@ private: }; -class Q_AUTOTEST_EXPORT QFontCache : public QObject +class Q_GUI_EXPORT QFontCache : public QObject { public: // note: these static functions work on a per-thread basis diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm index a2229159b5..240deeddbd 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.mm +++ b/src/plugins/platforms/cocoa/qcocoatheme.mm @@ -53,11 +53,13 @@ #include "qcocoahelpers.h" #include +#include #include #include #include #include #include +#include #include #include #include @@ -162,6 +164,11 @@ void QCocoaTheme::handleSystemThemeChange() m_systemPalette = qt_mac_createSystemPalette(); m_palettes = qt_mac_createRolePalettes(); + if (QCoreTextFontEngine::fontSmoothing() == QCoreTextFontEngine::FontSmoothing::Grayscale) { + // Re-populate glyph caches based on the new appearance's assumed text fill color + QFontCache::instance()->clear(); + } + QWindowSystemInterface::handleThemeChange(nullptr); } From ba304af284f4cbb579d35046c0cf4c1537af0fec Mon Sep 17 00:00:00 2001 From: Steve Mokris Date: Sat, 8 Dec 2018 12:28:02 -0500 Subject: [PATCH 0566/1650] Refresh QGuiApplication's devicePixelRatio cache when screens change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-63548 Change-Id: Id934cda6e15449c00c80a646055899f49580da88 Reviewed-by: Tor Arne Vestbø --- src/gui/kernel/qguiapplication.cpp | 24 ++++++++++++++++-------- src/gui/kernel/qguiapplication_p.h | 6 ++++++ src/gui/kernel/qplatformintegration.cpp | 5 +++++ 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index b5e9b233e1..8f4c674952 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -208,6 +208,8 @@ bool QGuiApplicationPrivate::obey_desktop_settings = true; QInputDeviceManager *QGuiApplicationPrivate::m_inputDeviceManager = 0; +qreal QGuiApplicationPrivate::m_maxDevicePixelRatio = 0.0; + static qreal fontSmoothingGamma = 1.7; extern void qRegisterGuiVariant(); @@ -1093,17 +1095,19 @@ QScreen *QGuiApplication::screenAt(const QPoint &point) */ qreal QGuiApplication::devicePixelRatio() const { - // Cache topDevicePixelRatio, iterate through the screen list once only. - static qreal topDevicePixelRatio = 0.0; - if (!qFuzzyIsNull(topDevicePixelRatio)) { - return topDevicePixelRatio; - } + if (!qFuzzyIsNull(QGuiApplicationPrivate::m_maxDevicePixelRatio)) + return QGuiApplicationPrivate::m_maxDevicePixelRatio; - topDevicePixelRatio = 1.0; // make sure we never return 0. + QGuiApplicationPrivate::m_maxDevicePixelRatio = 1.0; // make sure we never return 0. for (QScreen *screen : qAsConst(QGuiApplicationPrivate::screen_list)) - topDevicePixelRatio = qMax(topDevicePixelRatio, screen->devicePixelRatio()); + QGuiApplicationPrivate::m_maxDevicePixelRatio = qMax(QGuiApplicationPrivate::m_maxDevicePixelRatio, screen->devicePixelRatio()); - return topDevicePixelRatio; + return QGuiApplicationPrivate::m_maxDevicePixelRatio; +} + +void QGuiApplicationPrivate::resetCachedDevicePixelRatio() +{ + m_maxDevicePixelRatio = 0.0; } /*! @@ -3000,6 +3004,8 @@ void QGuiApplicationPrivate::processScreenGeometryChange(QWindowSystemInterfaceP for (QScreen* sibling : siblings) emit sibling->virtualGeometryChanged(sibling->virtualGeometry()); } + + resetCachedDevicePixelRatio(); } void QGuiApplicationPrivate::processScreenLogicalDotsPerInchChange(QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *e) @@ -3015,6 +3021,8 @@ void QGuiApplicationPrivate::processScreenLogicalDotsPerInchChange(QWindowSystem s->d_func()->logicalDpi = QDpi(e->dpiX, e->dpiY); emit s->logicalDotsPerInchChanged(s->logicalDotsPerInch()); + + resetCachedDevicePixelRatio(); } void QGuiApplicationPrivate::processScreenRefreshRateChange(QWindowSystemInterfacePrivate::ScreenRefreshRateEvent *e) diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index 79c1a1c820..a5f3f99a31 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -311,6 +311,8 @@ public: static void setApplicationState(Qt::ApplicationState state, bool forcePropagate = false); + static void resetCachedDevicePixelRatio(); + protected: virtual void notifyThemeChanged(); bool tryCloseRemainingWindows(QWindowList processedWindows); @@ -330,6 +332,10 @@ private: bool ownGlobalShareContext; static QInputDeviceManager *m_inputDeviceManager; + + // Cache the maximum device pixel ratio, to iterate through the screen list + // only the first time it's required, or when devices are added or removed. + static qreal m_maxDevicePixelRatio; }; Q_GUI_EXPORT uint qHash(const QGuiApplicationPrivate::ActiveTouchPointsKey &k); diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp index 9836f569fc..bff1c907d6 100644 --- a/src/gui/kernel/qplatformintegration.cpp +++ b/src/gui/kernel/qplatformintegration.cpp @@ -482,6 +482,9 @@ void QPlatformIntegration::screenAdded(QPlatformScreen *ps, bool isPrimary) } else { QGuiApplicationPrivate::screen_list.append(screen); } + + QGuiApplicationPrivate::resetCachedDevicePixelRatio(); + emit qGuiApp->screenAdded(screen); if (isPrimary) @@ -499,6 +502,8 @@ void QPlatformIntegration::removeScreen(QScreen *screen) const bool wasPrimary = (!QGuiApplicationPrivate::screen_list.isEmpty() && QGuiApplicationPrivate::screen_list.at(0) == screen); QGuiApplicationPrivate::screen_list.removeOne(screen); + QGuiApplicationPrivate::resetCachedDevicePixelRatio(); + if (wasPrimary && qGuiApp && !QGuiApplicationPrivate::screen_list.isEmpty()) emit qGuiApp->primaryScreenChanged(QGuiApplicationPrivate::screen_list.at(0)); } From 45c358b0da4e8f629d9c70a32fe06a3fb1cb6ca8 Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Wed, 21 Nov 2018 17:08:49 +1000 Subject: [PATCH 0567/1650] threads: disable threads examples for nothread builds Change-Id: I2c253de973f5399c5ed68194b969ccebe457c689 Reviewed-by: Eskil Abrahamsen Blomfeldt --- examples/corelib/corelib.pro | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/corelib/corelib.pro b/examples/corelib/corelib.pro index 014e8af608..8caf2c16df 100644 --- a/examples/corelib/corelib.pro +++ b/examples/corelib/corelib.pro @@ -5,5 +5,6 @@ SUBDIRS = \ ipc \ mimetypes \ serialization \ - threads \ tools + +qtConfig(thread): SUBDIRS += threads From d391d4db49bd8a7da8516af9c8ff8083a927bf79 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 5 Dec 2018 10:28:17 +0100 Subject: [PATCH 0568/1650] Fusion: Don't draw the background of the lineedit when drawing the frame MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since only the frame is being drawn here, it should only draw the outline. Otherwise it will override any background drawing done via a stylesheet. Change-Id: I408fc44743747ad369c700b3d52935bfc8826f11 Fixes: QTBUG-71950 Reviewed-by: Friedemann Kleint Reviewed-by: Tor Arne Vestbø --- src/widgets/styles/qfusionstyle.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp index df151067df..c565932889 100644 --- a/src/widgets/styles/qfusionstyle.cpp +++ b/src/widgets/styles/qfusionstyle.cpp @@ -725,7 +725,6 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, // Draw Outline painter->setPen( QPen(hasFocus ? highlightedOutline : outline)); - painter->setBrush(option->palette.base()); painter->drawRoundedRect(r.adjusted(0, 0, -1, -1), 2, 2); if (hasFocus) { From ed90c306f2033eec4a6ac3aa356b2ea41e601160 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 4 Dec 2018 10:36:44 +0100 Subject: [PATCH 0569/1650] Fix addition of the wasm platform plugin Add the plugin; do not replace the whole SUBDIRS value. Fixes: QTBUG-70375 Change-Id: Id40a69f54dfde5eb88894323c7e1146b6cad5a75 Reviewed-by: Friedemann Kleint --- src/plugins/platforms/platforms.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro index 5bf2b77421..db2a31d1a5 100644 --- a/src/plugins/platforms/platforms.pro +++ b/src/plugins/platforms/platforms.pro @@ -46,7 +46,7 @@ haiku { SUBDIRS += haiku } -wasm: SUBDIRS = wasm +wasm: SUBDIRS += wasm qtConfig(mirclient): SUBDIRS += mirclient From 6a221f3d05b6d0e902d86d75428364747268c6c9 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Fri, 7 Dec 2018 10:36:08 +0100 Subject: [PATCH 0570/1650] Fix qmake's detection for conflicting source files for nmake Consider the following source tree: foo/narf.cpp bar/narf.c bar/gnampf.cpp The .pro file has SOURCES += foo/narf.cpp bar/gnampf.cpp The file bar/narf.c is not supposed to be built for whatever reason. QMake's nmake Makefile generator generates inference rules of the form {.\foo}.cpp{debug\}.obj:: ... for every source subdirectory and every source file extension. Thus, we have {.\foo}.cpp{debug\}.obj:: {.\bar}.cpp{debug\}.obj:: {.\bar}.c{debug\}.obj:: Depending on the exact execution order of the inference rules (which depends on the names of the files) the latter rule might get picked, and we're erronously compiling bar/narf.c even though it's not referenced in the .pro file. Conclusion: QMake's detection of conflicting source files must consider the base names of source files, and not the exact file names. Fixes: QTBUG-72059 Change-Id: I50c2725ae2a7421053369a10680230f571af00ea Reviewed-by: Oliver Wolff Reviewed-by: Oswald Buddenhagen --- qmake/generators/win32/msvc_nmake.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index 306ae57871..780f6bd4d8 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -553,12 +553,13 @@ void NmakeMakefileGenerator::writeImplicitRulesPart(QTextStream &t) QDirIterator dit(sourceDir, sourceFilesFilter, QDir::Files | QDir::NoDotAndDotDot); while (dit.hasNext()) { dit.next(); - QString &duplicate = fileNames[dit.fileName()]; + const QFileInfo fi = dit.fileInfo(); + QString &duplicate = fileNames[fi.completeBaseName()]; if (duplicate.isNull()) { - duplicate = dit.filePath(); + duplicate = fi.filePath(); } else { warn_msg(WarnLogic, "%s conflicts with %s", qPrintable(duplicate), - qPrintable(dit.filePath())); + qPrintable(fi.filePath())); duplicatesFound = true; } } From fc85a6b6b952aa619b87262d4187dc05865ab51a Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sat, 6 Oct 2018 22:33:57 +0200 Subject: [PATCH 0571/1650] QTypeInfo: use C++11 type traits to deduce if a type is static or complex All types that can be trivially copied and destructed are by definition relocatable, and we should apply those semantics when moving them in memory. Types that are trivial, are by definition not complex and should be treated as such. [ChangeLog][QtCore] Qt Containers and meta type system now use C++11 type traits (std::is_trivial, std::is_trivially_copyable and std::is_trivially_destructible) to detect the class of a type not explicitly set by Q_DECLARE_TYPEINFO. (Q_DECLARE_TYPEINFO is still needed for QList.) Done-with: Olivier Goffart (Woboq GmbH) Change-Id: Iebb87ece425ea919e86169d06cd509c54a074282 Reviewed-by: Thiago Macieira --- src/corelib/global/qglobal.cpp | 7 +++++ src/corelib/global/qtypeinfo.h | 28 ++++++++++++++++--- .../kernel/qmetatype/tst_qmetatype.cpp | 24 ++++++++++++---- tests/auto/corelib/tools/qpair/tst_qpair.cpp | 4 +-- 4 files changed, 51 insertions(+), 12 deletions(-) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 8da94c8624..c0d46b73d9 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -4103,6 +4103,13 @@ bool qunsetenv(const char *varName) Example of a movable type: \snippet code/src_corelib_global_qglobal.cpp 39 + + Qt will try to detect the class of a type using std::is_trivial or + std::is_trivially_copyable. Use this macro to tune the behavior. + For instance many types would be candidates for Q_MOVABLE_TYPE despite + not being trivially-copyable. For binary compatibility reasons, QList + optimizations are only enabled if there is an explicit + Q_DECLARE_TYPEINFO even for trivially-copyable types. */ /*! diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h index 4f79c48c51..567ff5c08e 100644 --- a/src/corelib/global/qtypeinfo.h +++ b/src/corelib/global/qtypeinfo.h @@ -49,6 +49,26 @@ QT_BEGIN_NAMESPACE QTypeInfo - type trait functionality */ +template +static constexpr bool qIsRelocatable() +{ +#if defined(Q_CC_CLANG) || !defined(Q_CC_GNU) || Q_CC_GNU >= 501 + return std::is_trivially_copyable::value && std::is_trivially_destructible::value; +#else + return std::is_enum::value || std::is_integral::value; +#endif +} + +template +static constexpr bool qIsTrivial() +{ +#if defined(Q_CC_CLANG) || !defined(Q_CC_GNU) || Q_CC_GNU >= 501 + return std::is_trivial::value; +#else + return std::is_enum::value || std::is_integral::value; +#endif +} + /* The catch-all template. */ @@ -61,9 +81,9 @@ public: isSpecialized = std::is_enum::value, // don't require every enum to be marked manually isPointer = false, isIntegral = std::is_integral::value, - isComplex = !isIntegral && !std::is_enum::value, + isComplex = !qIsTrivial(), isStatic = true, - isRelocatable = std::is_enum::value, + isRelocatable = qIsRelocatable(), isLarge = (sizeof(T)>sizeof(void*)), isDummy = false, //### Qt6: remove sizeOf = sizeof(T) @@ -248,9 +268,9 @@ class QTypeInfo \ public: \ enum { \ isSpecialized = true, \ - isComplex = (((FLAGS) & Q_PRIMITIVE_TYPE) == 0), \ + isComplex = (((FLAGS) & Q_PRIMITIVE_TYPE) == 0) && !qIsTrivial(), \ isStatic = (((FLAGS) & (Q_MOVABLE_TYPE | Q_PRIMITIVE_TYPE)) == 0), \ - isRelocatable = !isStatic || ((FLAGS) & Q_RELOCATABLE_TYPE), \ + isRelocatable = !isStatic || ((FLAGS) & Q_RELOCATABLE_TYPE) || qIsRelocatable(), \ isLarge = (sizeof(TYPE)>sizeof(void*)), \ isPointer = false, \ isIntegral = std::is_integral< TYPE >::value, \ diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index 0c328dff58..fb11e4c522 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -342,6 +342,7 @@ struct Bar ++failureCount; } } + ~Bar() {} public: static int failureCount; @@ -458,7 +459,7 @@ void tst_QMetaType::threadSafety() namespace TestSpace { - struct Foo { double d; }; + struct Foo { double d; public: ~Foo() {} }; struct QungTfu {}; } Q_DECLARE_METATYPE(TestSpace::Foo) @@ -515,11 +516,17 @@ void tst_QMetaType::properties() } template -struct Whity { T t; }; +struct Whity { T t; Whity() {} }; Q_DECLARE_METATYPE( Whity < int > ) Q_DECLARE_METATYPE(Whity) +#if !defined(Q_CC_CLANG) && defined(Q_CC_GNU) && Q_CC_GNU < 501 +QT_BEGIN_NAMESPACE +Q_DECLARE_TYPEINFO(Whity, Q_MOVABLE_TYPE); +QT_END_NAMESPACE +#endif + void tst_QMetaType::normalizedTypes() { int WhityIntId = ::qMetaTypeId >(); @@ -818,10 +825,13 @@ void tst_QMetaType::sizeOfStaticLess() QCOMPARE(size_t(QMetaType(type).sizeOf()), size); } -struct CustomMovable {}; +struct CustomMovable { CustomMovable() {} }; +#if !defined(Q_CC_CLANG) && defined(Q_CC_GNU) && Q_CC_GNU < 501 QT_BEGIN_NAMESPACE Q_DECLARE_TYPEINFO(CustomMovable, Q_MOVABLE_TYPE); QT_END_NAMESPACE +#endif + Q_DECLARE_METATYPE(CustomMovable); class CustomObject : public QObject @@ -850,13 +860,15 @@ public: }; Q_DECLARE_METATYPE(CustomMultiInheritanceObject*); -class C { char _[4]; }; -class M { char _[4]; }; +class C { char _[4]; public: C() = default; C(const C&) {} }; +class M { char _[4]; public: M() {} }; class P { char _[4]; }; QT_BEGIN_NAMESPACE +#if defined(Q_CC_GNU) && Q_CC_GNU < 501 Q_DECLARE_TYPEINFO(M, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(P, Q_PRIMITIVE_TYPE); +#endif QT_END_NAMESPACE // avoid the comma: @@ -902,7 +914,7 @@ QT_FOR_EACH_STATIC_PRIMITIVE_POINTER(ADD_METATYPE_TEST_ROW) QT_FOR_EACH_STATIC_CORE_POINTER(ADD_METATYPE_TEST_ROW) #undef ADD_METATYPE_TEST_ROW QTest::newRow("TestSpace::Foo") << ::qMetaTypeId() << false << true << false << false; - QTest::newRow("Whity") << ::qMetaTypeId >() << false << true << false << false; + QTest::newRow("Whity") << ::qMetaTypeId >() << true << true << false << false; QTest::newRow("CustomMovable") << ::qMetaTypeId() << true << true << false << false; QTest::newRow("CustomObject*") << ::qMetaTypeId() << true << false << true << false; QTest::newRow("CustomMultiInheritanceObject*") << ::qMetaTypeId() << true << false << true << false; diff --git a/tests/auto/corelib/tools/qpair/tst_qpair.cpp b/tests/auto/corelib/tools/qpair/tst_qpair.cpp index 1d5f7536c8..dedc353e67 100644 --- a/tests/auto/corelib/tools/qpair/tst_qpair.cpp +++ b/tests/auto/corelib/tools/qpair/tst_qpair.cpp @@ -41,8 +41,8 @@ private Q_SLOTS: void taskQTBUG_48780_pairContainingCArray(); }; -class C { char _[4]; }; -class M { char _[4]; }; +class C { C() {} char _[4]; }; +class M { M() {} char _[4]; }; class P { char _[4]; }; QT_BEGIN_NAMESPACE From 3464e1e5c7b5b01ae13c99e3529dd02af1d36958 Mon Sep 17 00:00:00 2001 From: Sergio Martins Date: Wed, 5 Dec 2018 19:48:05 +0000 Subject: [PATCH 0572/1650] Add a few qAsConst() to range-for to prevent detachments places indicated by clazy As a drive-by, fixed minor styling issues in the affected lines. Change-Id: I88d3fc0c8573cde0e61f19a18dd9ea697ee40c34 Reviewed-by: Thiago Macieira Reviewed-by: Luca Beldi Reviewed-by: Friedemann Kleint --- src/corelib/mimetypes/qmimeprovider.cpp | 4 ++-- .../bearer/networkmanager/qnetworkmanagerengine.cpp | 4 ++-- src/plugins/generic/tuiotouch/qtuiohandler.cpp | 10 +++++----- .../deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp | 2 +- src/plugins/platforms/vnc/qvnc.cpp | 10 ++++------ src/plugins/platforms/vnc/qvncscreen.cpp | 2 +- src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 6 +++--- src/printsupport/kernel/qplatformprintdevice.cpp | 10 +++++----- src/tools/moc/generator.cpp | 2 +- src/widgets/dialogs/qwizard.cpp | 2 +- 10 files changed, 25 insertions(+), 27 deletions(-) diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp index aac51184a4..d5b8825972 100644 --- a/src/corelib/mimetypes/qmimeprovider.cpp +++ b/src/corelib/mimetypes/qmimeprovider.cpp @@ -445,10 +445,10 @@ void QMimeBinaryProvider::addAllMimeTypes(QList &result) loadMimeTypeList(); if (result.isEmpty()) { result.reserve(m_mimetypeNames.count()); - for (const QString &name : m_mimetypeNames) + for (const QString &name : qAsConst(m_mimetypeNames)) result.append(mimeTypeForNameUnchecked(name)); } else { - for (const QString &name : m_mimetypeNames) + for (const QString &name : qAsConst(m_mimetypeNames)) if (std::find_if(result.constBegin(), result.constEnd(), [name](const QMimeType &mime) -> bool { return mime.name() == name; }) == result.constEnd()) result.append(mimeTypeForNameUnchecked(name)); diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp index 543e66491d..e74b1cf744 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerengine.cpp @@ -465,7 +465,7 @@ void QNetworkManagerEngine::newConnection(const QDBusObjectPath &path, cpPriv->state |= QNetworkConfiguration::Active; if (deviceType == DEVICE_TYPE_ETHERNET) { - for (const auto *interfaceDevice : interfaceDevices) { + for (auto interfaceDevice : qAsConst(interfaceDevices)) { if (interfaceDevice->deviceType() == deviceType) { auto *wiredDevice = wiredDevices.value(interfaceDevice->path()); if (wiredDevice && wiredDevice->carrier()) { @@ -716,7 +716,7 @@ QNetworkSession::State QNetworkManagerEngine::sessionStateForId(const QString &i if (!ptr->isValid) return QNetworkSession::Invalid; - for (QNetworkManagerConnectionActive *activeConnection : activeConnectionsList) { + for (QNetworkManagerConnectionActive *activeConnection : qAsConst(activeConnectionsList)) { const QString identifier = activeConnection->connection().path(); if (id == identifier) { diff --git a/src/plugins/generic/tuiotouch/qtuiohandler.cpp b/src/plugins/generic/tuiotouch/qtuiohandler.cpp index bb18ba5085..cb82672acd 100644 --- a/src/plugins/generic/tuiotouch/qtuiohandler.cpp +++ b/src/plugins/generic/tuiotouch/qtuiohandler.cpp @@ -169,7 +169,7 @@ void QTuioHandler::processPackets() messages.push_back(msg); } - for (const QOscMessage &message : messages) { + for (const QOscMessage &message : qAsConst(messages)) { if (message.addressPattern() == "/tuio/2Dcur") { QList arguments = message.arguments(); if (arguments.count() == 0) { @@ -368,12 +368,12 @@ void QTuioHandler::process2DCurFseq(const QOscMessage &message) QList tpl; tpl.reserve(m_activeCursors.size() + m_deadCursors.size()); - for (const QTuioCursor &tc : m_activeCursors) { + for (const QTuioCursor &tc : qAsConst(m_activeCursors)) { QWindowSystemInterface::TouchPoint tp = cursorToTouchPoint(tc, win); tpl.append(tp); } - for (const QTuioCursor &tc : m_deadCursors) { + for (const QTuioCursor &tc : qAsConst(m_deadCursors)) { QWindowSystemInterface::TouchPoint tp = cursorToTouchPoint(tc, win); tp.state = Qt::TouchPointReleased; tpl.append(tp); @@ -542,12 +542,12 @@ void QTuioHandler::process2DObjFseq(const QOscMessage &message) QList tpl; tpl.reserve(m_activeTokens.size() + m_deadTokens.size()); - for (const QTuioToken & t : m_activeTokens) { + for (const QTuioToken & t : qAsConst(m_activeTokens)) { QWindowSystemInterface::TouchPoint tp = tokenToTouchPoint(t, win); tpl.append(tp); } - for (const QTuioToken & t : m_deadTokens) { + for (const QTuioToken & t : qAsConst(m_deadTokens)) { QWindowSystemInterface::TouchPoint tp = tokenToTouchPoint(t, win); tp.state = Qt::TouchPointReleased; tp.velocity = QVector2D(); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp index 24f82e7843..24051c352e 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp @@ -423,7 +423,7 @@ void QEglFSKmsGbmScreen::updateFlipStatus() if (m_flipPending) return; - for (const CloneDestination &d : m_cloneDests) { + for (const CloneDestination &d : qAsConst(m_cloneDests)) { if (d.cloneFlipPending) return; } diff --git a/src/plugins/platforms/vnc/qvnc.cpp b/src/plugins/platforms/vnc/qvnc.cpp index ffe00de2b1..32114c6443 100644 --- a/src/plugins/platforms/vnc/qvnc.cpp +++ b/src/plugins/platforms/vnc/qvnc.cpp @@ -600,7 +600,7 @@ void QVncClientCursor::changeCursor(QCursor *widgetCursor, QWindow *window) cursor = *platformImage.image(); hotspot = platformImage.hotspot(); } - for (auto client : clients) + for (auto client : qAsConst(clients)) client->setDirtyCursor(); } @@ -638,16 +638,14 @@ void QVncServer::init() QVncServer::~QVncServer() { - for (auto client : clients) { - delete client; - } + qDeleteAll(clients); } void QVncServer::setDirty() { - for (auto client : clients) { + for (auto client : qAsConst(clients)) client->setDirty(qvnc_screen->dirtyRegion); - } + qvnc_screen->clearDirty(); } diff --git a/src/plugins/platforms/vnc/qvncscreen.cpp b/src/plugins/platforms/vnc/qvncscreen.cpp index 67d33de2f0..2eca18fb4d 100644 --- a/src/plugins/platforms/vnc/qvncscreen.cpp +++ b/src/plugins/platforms/vnc/qvncscreen.cpp @@ -75,7 +75,7 @@ bool QVncScreen::initialize() mDepth = 32; mPhysicalSize = QSizeF(mGeometry.width()/96.*25.4, mGeometry.height()/96.*25.4); - for (const QString &arg : mArgs) { + for (const QString &arg : qAsConst(mArgs)) { QRegularExpressionMatch match; if (arg.contains(mmSizeRx, &match)) { mPhysicalSize = QSizeF(match.captured("width").toDouble(), match.captured("height").toDouble()); diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index 04ddd3c98c..78ef7760af 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -637,7 +637,7 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo qreal nx = -1.0, ny = -1.0; qreal w = 0.0, h = 0.0; bool majorAxisIsY = touchPoint.area.height() > touchPoint.area.width(); - for (const TouchDeviceData::ValuatorClassInfo vci : dev->valuatorInfo) { + for (const TouchDeviceData::ValuatorClassInfo &vci : qAsConst(dev->valuatorInfo)) { double value; if (!xi2GetValuatorValueIfSet(xiDeviceEvent, vci.number, &value)) continue; @@ -823,7 +823,7 @@ bool QXcbConnection::xi2SetMouseGrabEnabled(xcb_window_t w, bool grab) | XCB_INPUT_XI_EVENT_MASK_TOUCH_UPDATE | XCB_INPUT_XI_EVENT_MASK_TOUCH_END; - for (int id : m_xiMasterPointerIds) { + for (int id : qAsConst(m_xiMasterPointerIds)) { xcb_generic_error_t *error = nullptr; auto cookie = xcb_input_xi_grab_device(xcb_connection(), w, XCB_CURRENT_TIME, XCB_CURSOR_NONE, id, XCB_INPUT_GRAB_MODE_22_ASYNC, XCB_INPUT_GRAB_MODE_22_ASYNC, @@ -841,7 +841,7 @@ bool QXcbConnection::xi2SetMouseGrabEnabled(xcb_window_t w, bool grab) free(reply); } } else { // ungrab - for (int id : m_xiMasterPointerIds) { + for (int id : qAsConst(m_xiMasterPointerIds)) { auto cookie = xcb_input_xi_ungrab_device_checked(xcb_connection(), XCB_CURRENT_TIME, id); xcb_generic_error_t *error = xcb_request_check(xcb_connection(), cookie); if (error) { diff --git a/src/printsupport/kernel/qplatformprintdevice.cpp b/src/printsupport/kernel/qplatformprintdevice.cpp index f778de8e71..3d76cad688 100644 --- a/src/printsupport/kernel/qplatformprintdevice.cpp +++ b/src/printsupport/kernel/qplatformprintdevice.cpp @@ -163,7 +163,7 @@ QPageSize QPlatformPrintDevice::supportedPageSize(const QPageSize &pageSize) con // e.g. Windows defines DMPAPER_11X17 and DMPAPER_TABLOID with names "11x17" and "Tabloid", but both // map to QPageSize::Tabloid / PPD Key "Tabloid" / ANSI B Tabloid if (pageSize.id() != QPageSize::Custom) { - for (const QPageSize &ps : m_pageSizes) { + for (const QPageSize &ps : qAsConst(m_pageSizes)) { if (ps.id() == pageSize.id() && ps.name() == pageSize.name()) return ps; } @@ -171,7 +171,7 @@ QPageSize QPlatformPrintDevice::supportedPageSize(const QPageSize &pageSize) con // Next try match on id only if not custom if (pageSize.id() != QPageSize::Custom) { - for (const QPageSize &ps : m_pageSizes) { + for (const QPageSize &ps : qAsConst(m_pageSizes)) { if (ps.id() == pageSize.id()) return ps; } @@ -186,7 +186,7 @@ QPageSize QPlatformPrintDevice::supportedPageSize(QPageSize::PageSizeId pageSize if (!m_havePageSizes) loadPageSizes(); - for (const QPageSize &ps : m_pageSizes) { + for (const QPageSize &ps : qAsConst(m_pageSizes)) { if (ps.id() == pageSizeId) return ps; } @@ -200,7 +200,7 @@ QPageSize QPlatformPrintDevice::supportedPageSize(const QString &pageName) const if (!m_havePageSizes) loadPageSizes(); - for (const QPageSize &ps : m_pageSizes) { + for (const QPageSize &ps : qAsConst(m_pageSizes)) { if (ps.name() == pageName) return ps; } @@ -233,7 +233,7 @@ QPageSize QPlatformPrintDevice::supportedPageSizeMatch(const QPageSize &pageSize return pageSize; // Try to find a supported page size based on point size - for (const QPageSize &ps : m_pageSizes) { + for (const QPageSize &ps : qAsConst(m_pageSizes)) { if (ps.sizePoints() == pageSize.sizePoints()) return ps; } diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index e5f1c61e3c..02c1fbd394 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -619,7 +619,7 @@ void Generator::generateCode() fprintf(out, "// a) You are using a NOTIFY signal that does not exist. Fix it.\n"); fprintf(out, "// b) You are using a NOTIFY signal that does exist (in a parent class) but has a non-empty parameter list. This is a moc limitation.\n"); fprintf(out, "Q_DECL_UNUSED static void checkNotifySignalValidity_%s(%s *t) {\n", qualifiedClassNameIdentifier.constData(), cdef->qualified.constData()); - for (const QByteArray &nonClassSignal : cdef->nonClassSignalList) + for (const QByteArray &nonClassSignal : qAsConst(cdef->nonClassSignalList)) fprintf(out, " t->%s();\n", nonClassSignal.constData()); fprintf(out, "}\n"); } diff --git a/src/widgets/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp index 3876cf16c6..59168ba14d 100644 --- a/src/widgets/dialogs/qwizard.cpp +++ b/src/widgets/dialogs/qwizard.cpp @@ -769,7 +769,7 @@ void QWizardPrivate::reset() for (int i = history.count() - 1; i >= 0; --i) q->cleanupPage(history.at(i)); history.clear(); - for (QWizardPage *page : pageMap) + for (QWizardPage *page : qAsConst(pageMap)) page->d_func()->initialized = false; current = -1; From e25d7b14416b2d0ac2598bc03a7c2b8d96e63d42 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Mon, 29 Oct 2018 15:08:30 +0100 Subject: [PATCH 0573/1650] Add a means to specify the protocol type, to aid websockets over proxy When a PAC script is used on macOS, it will only allow connections for http/https, although a proxy can be used for ws/wss. Therefore we need to add a means of setting the protocol type for this sort of connection so that we can pass on the necessary information to the PAC script. Change-Id: I3fa29fa85a529bd88d9565daa58fe9d748b61a92 Reviewed-by: Timur Pocheptsov --- src/network/socket/qabstractsocket.cpp | 34 +++++++++++++++++++++++++- src/network/socket/qabstractsocket.h | 2 ++ src/network/socket/qabstractsocket_p.h | 1 + src/network/ssl/qsslsocket.cpp | 1 + 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 2f93c5fa2b..e68c5076b3 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -914,7 +914,7 @@ void QAbstractSocketPrivate::resolveProxy(const QString &hostname, quint16 port) proxies << proxy; } else { // try the application settings instead - QNetworkProxyQuery query(hostname, port, QString(), + QNetworkProxyQuery query(hostname, port, protocolTag, socketType == QAbstractSocket::TcpSocket ? QNetworkProxyQuery::TcpSocket : socketType == QAbstractSocket::SctpSocket ? @@ -2959,6 +2959,38 @@ QNetworkProxy QAbstractSocket::proxy() const Q_D(const QAbstractSocket); return d->proxy; } + +/*! + \since 5.13 + + Returns the protocol tag for this socket. + If the protocol tag is set then this is passed to QNetworkProxyQuery + when this is created internally to indicate the protocol tag to be + used. + + \sa setProtocolTag(), QNetworkProxyQuery +*/ + +QString QAbstractSocket::protocolTag() const +{ + Q_D(const QAbstractSocket); + return d->protocolTag; +} + +/*! + \since 5.13 + + Sets the protocol tag for this socket to \a tag. + + \sa protocolTag() +*/ + +void QAbstractSocket::setProtocolTag(const QString &tag) +{ + Q_D(QAbstractSocket); + d->protocolTag = tag; +} + #endif // QT_NO_NETWORKPROXY #ifndef QT_NO_DEBUG_STREAM diff --git a/src/network/socket/qabstractsocket.h b/src/network/socket/qabstractsocket.h index 6d5e57ac52..de09195eeb 100644 --- a/src/network/socket/qabstractsocket.h +++ b/src/network/socket/qabstractsocket.h @@ -197,6 +197,8 @@ public: #ifndef QT_NO_NETWORKPROXY void setProxy(const QNetworkProxy &networkProxy); QNetworkProxy proxy() const; + QString protocolTag() const; + void setProtocolTag(const QString &tag); #endif Q_SIGNALS: diff --git a/src/network/socket/qabstractsocket_p.h b/src/network/socket/qabstractsocket_p.h index 066a35ff85..38c0caef49 100644 --- a/src/network/socket/qabstractsocket_p.h +++ b/src/network/socket/qabstractsocket_p.h @@ -124,6 +124,7 @@ public: #ifndef QT_NO_NETWORKPROXY QNetworkProxy proxy; QNetworkProxy proxyInUse; + QString protocolTag; void resolveProxy(const QString &hostName, quint16 port); #else inline void resolveProxy(const QString &, quint16) { } diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 270e81774d..8b7d48be15 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -1977,6 +1977,7 @@ void QSslSocket::connectToHost(const QString &hostName, quint16 port, OpenMode o d->createPlainSocket(openMode); } #ifndef QT_NO_NETWORKPROXY + d->plainSocket->setProtocolTag(d->protocolTag); d->plainSocket->setProxy(proxy()); #endif QIODevice::open(openMode); From 826b09f0c507fe5321a8534054a4f0b7bdd2699b Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 4 Dec 2018 12:00:37 +0100 Subject: [PATCH 0574/1650] Fix build of static plugins with resources This patch reverts 388c4ef9f78c8e. The reason is that it generates a symbol (resource_init_function) based on the name of the pro-file. But if different plugins are built from a pro-file with the same name, you end up linking in many symbols with the same name as well. Which one that ends up being used at runtime will typically depend on the linking order of the plugins. This problem will happen if you build an app for iOS that uses both controls 1 and controls 2. In that case, both QML plugins are built from a "controls.pro" file. At runtime, only one of the plugins will be imported correctly. This patch therefore reverts 388c4ef9f78c8e, but at the same time, to not re-introduce the problem it fixed, we instead genereate both a debug and release version of the plugin_resources.cpp file. That way we can still depend on the TARGET variable for generating both the resource_init_function symbol and the cpp file. Fixes: QTBUG-62647 Fixes: QTBUG-71386 Fixes: QTBUG-72108 Change-Id: I3d8c53132458b30ed9f47a259f1f8e4fa4d44130 Reviewed-by: Oswald Buddenhagen --- mkspecs/features/resources.prf | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/mkspecs/features/resources.prf b/mkspecs/features/resources.prf index a25846bd77..48e9f83885 100644 --- a/mkspecs/features/resources.prf +++ b/mkspecs/features/resources.prf @@ -73,17 +73,14 @@ for(resource, RESOURCES) { } !isEmpty(RESOURCES):contains(TEMPLATE, .*lib):plugin:static { - pluginName = $$lower($$replace(_PRO_FILE_, .*/([^/.]+)\\.[^/.]+, \\1)) - - resource_init_function = $${pluginName}_plugin_resource_init + resource_init_function = $$lower($$basename(TARGET))_plugin_resource_init DEFINES += "QT_PLUGIN_RESOURCE_INIT_FUNCTION=$$resource_init_function" - - RESOURCE_INIT_CPP = $$OUT_PWD/$${pluginName}_plugin_resources.cpp + RESOURCE_INIT_CPP = $$OUT_PWD/$$lower($$basename(TARGET))_plugin_resources.cpp GENERATED_SOURCES += $$RESOURCE_INIT_CPP QMAKE_DISTCLEAN += $$RESOURCE_INIT_CPP - !build_pass { + isEmpty(BUILDS)|build_pass { RESOURCE_INIT_CONT = \ "// This file is autogenerated by qmake. It contains a function that" \ "// references all resources the plugin includes and the function is" \ From 19d7bd3d638c8962343927a161ce3f1cfdcb3e6a Mon Sep 17 00:00:00 2001 From: Sergio Martins Date: Thu, 29 Nov 2018 13:23:00 +0000 Subject: [PATCH 0575/1650] Fix a couple of unused QStrings This is needed so we can add Q_WARN_UNUSED to QString. The xcb one might even be a bug. Change-Id: Ia2d2563bdd10aa747014410df4990597969f4634 Reviewed-by: Gatis Paeglis Reviewed-by: Andy Shaw --- src/plugins/platforms/xcb/qxcbnativeinterface.cpp | 2 +- src/plugins/sqldrivers/odbc/qsql_odbc.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp index 524af5a2a7..4d526a6bda 100644 --- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp @@ -304,7 +304,7 @@ QPlatformNativeInterface::NativeResourceForWindowFunction QXcbNativeInterface::n QPlatformNativeInterface::NativeResourceForBackingStoreFunction QXcbNativeInterface::nativeResourceFunctionForBackingStore(const QByteArray &resource) { const QByteArray lowerCaseResource = resource.toLower(); - NativeResourceForBackingStoreFunction func = handlerNativeResourceFunctionForBackingStore(resource); + NativeResourceForBackingStoreFunction func = handlerNativeResourceFunctionForBackingStore(lowerCaseResource); return func; } diff --git a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp index 1fbbcd0ef1..7f98efccba 100644 --- a/src/plugins/sqldrivers/odbc/qsql_odbc.cpp +++ b/src/plugins/sqldrivers/odbc/qsql_odbc.cpp @@ -345,7 +345,7 @@ static QSqlError qMakeError(const QString& err, QSqlError::ErrorType type, { int nativeCode = -1; QString message = qODBCWarn(p, &nativeCode); - return QSqlError(QLatin1String("QODBC3: ") + err, qODBCWarn(p), type, + return QSqlError(QLatin1String("QODBC3: ") + err, message, type, nativeCode != -1 ? QString::number(nativeCode) : QString()); } From f5ba938e1771040b076acc77b682bfb75d9b28f3 Mon Sep 17 00:00:00 2001 From: Sergio Martins Date: Wed, 21 Nov 2018 16:33:55 +0000 Subject: [PATCH 0576/1650] QtGui: Remove unused brushes [-Wclazy-unused-non-trivial-variable] Change-Id: If7e5340ec8acdfd70ea919286da5940db7a4def9 Reviewed-by: Friedemann Kleint Reviewed-by: Konstantin Ritt --- src/gui/painting/qpdf.cpp | 1 - src/gui/text/qtextlayout.cpp | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index 0811dd9918..83c7ba1add 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -856,7 +856,6 @@ void QPdfEngine::drawRects (const QRectF *rects, int rectCount) if (!d->hasPen && !d->hasBrush) return; - QBrush penBrush = d->pen.brush(); if (d->simplePen || !d->hasPen) { // draw strokes natively in this case for better output if(!d->simplePen && !d->stroker.matrix.isIdentity()) diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index e85b408db9..df4960e1ad 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1138,8 +1138,6 @@ void QTextLayout::draw(QPainter *p, const QPointF &pos, const QVector Date: Wed, 21 Nov 2018 16:11:14 +0000 Subject: [PATCH 0577/1650] QtDbus: Remove unused QStrings [-Wclazy-unused-non-trivial-variable] Change-Id: Iea776554aa5e01ecc6fa08ac2c8fb7b720d57126 Reviewed-by: Thiago Macieira --- src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp index 5b76502c94..360e3c8bc3 100644 --- a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp +++ b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp @@ -326,7 +326,6 @@ static void writeArgList(QTextStream &ts, const QStringList &argNames, // yes, starting from 1 for (int i = 1; i < outputArgs.count(); ++i) { const QDBusIntrospection::Argument &arg = outputArgs.at(i); - QString name = arg.name; if (!first) ts << ", "; @@ -531,8 +530,6 @@ static void writeProxy(const QString &filename, const QDBusIntrospection::Interf // properties: for (const QDBusIntrospection::Property &property : interface->properties) { QByteArray type = qtTypeName(property.type, property.annotations); - QString templateType = templateArg(type); - QString constRefType = constRefArg(type); QString getter = propertyGetter(property); QString setter = propertySetter(property); From d43ac840e5d5a0a2df9e8adce276c956c98be6aa Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 4 Dec 2018 18:42:54 +0100 Subject: [PATCH 0578/1650] Specify the date-time spec when setting max time QDateTimeEdit::setMaximumTime() constructed a QDateTime from the given time and its current max date without propagating its existing spec; it thus got a local time. All other QDateTimeEdit methods setting bounds do propagate the spec. So bring setMaximumTime() in line with the others. Fixes: QTBUG-71311 Change-Id: Ic97d22185f76bed46bc8d2884b131942874d9a0a Reviewed-by: Anton Kudryavtsev Reviewed-by: Konstantin Shegunov Reviewed-by: Thiago Macieira --- src/widgets/widgets/qdatetimeedit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp index 68bfd175ff..c66400f423 100644 --- a/src/widgets/widgets/qdatetimeedit.cpp +++ b/src/widgets/widgets/qdatetimeedit.cpp @@ -553,7 +553,7 @@ void QDateTimeEdit::setMaximumTime(const QTime &max) { Q_D(QDateTimeEdit); if (max.isValid()) { - const QDateTime m(d->maximum.toDate(), max); + const QDateTime m(d->maximum.toDate(), max, d->spec); setMaximumDateTime(m); } } From b688c7e99a8def9db836d1d6ab7388ae14a5d5b0 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Tue, 4 Dec 2018 17:44:20 +0100 Subject: [PATCH 0579/1650] DropSite example: fix documentation The DropSite documentation mentioned the foreach keyword which was removed some times ago in the code. Therefore also remove the corresponding documentation snippet. Change-Id: Id9dd3f01dbdd37eeda43fabe12b60ef9e0b32d10 Reviewed-by: Paul Wicking Reviewed-by: Friedemann Kleint --- examples/widgets/doc/dropsite.qdoc | 8 +-- .../draganddrop/dropsite/dropsitewindow.cpp | 3 +- .../code/doc_src_examples_dropsite.qdoc | 55 ------------------- 3 files changed, 3 insertions(+), 63 deletions(-) delete mode 100644 src/widgets/doc/snippets/code/doc_src_examples_dropsite.qdoc diff --git a/examples/widgets/doc/dropsite.qdoc b/examples/widgets/doc/dropsite.qdoc index 32bcfe8916..af8766a308 100644 --- a/examples/widgets/doc/dropsite.qdoc +++ b/examples/widgets/doc/dropsite.qdoc @@ -202,13 +202,7 @@ \snippet draganddrop/dropsite/dropsitewindow.cpp updateFormatsTable() part1 Once we are sure that \c mimeData is valid, we iterate through its - supported formats using the \l{The foreach Keyword}{foreach keyword}. - This keyword has the following format: - - \include code/doc_src_examples_dropsite.qdoc 0 - - In our example, \c format is the \a variable and the \a container is a - QStringList, obtained from \c mimeData->formats(). + supported formats. \note The \l{QMimeData::formats()}{formats()} function returns a QStringList object, containing all the formats supported by the diff --git a/examples/widgets/draganddrop/dropsite/dropsitewindow.cpp b/examples/widgets/draganddrop/dropsite/dropsitewindow.cpp index 28a42ee614..2dae83bb22 100644 --- a/examples/widgets/draganddrop/dropsite/dropsitewindow.cpp +++ b/examples/widgets/draganddrop/dropsite/dropsitewindow.cpp @@ -113,7 +113,8 @@ void DropSiteWindow::updateFormatsTable(const QMimeData *mimeData) //! [updateFormatsTable() part1] //! [updateFormatsTable() part2] - for (const QString &format : mimeData->formats()) { + const QStringList formats = mimeData->formats(); + for (const QString &format : formats) { QTableWidgetItem *formatItem = new QTableWidgetItem(format); formatItem->setFlags(Qt::ItemIsEnabled); formatItem->setTextAlignment(Qt::AlignTop | Qt::AlignLeft); diff --git a/src/widgets/doc/snippets/code/doc_src_examples_dropsite.qdoc b/src/widgets/doc/snippets/code/doc_src_examples_dropsite.qdoc deleted file mode 100644 index a91933cdce..0000000000 --- a/src/widgets/doc/snippets/code/doc_src_examples_dropsite.qdoc +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//! [0] -\code -foreach(variable, container) -\endcode -//! [0] From 177577932e89772ef7ab281dd5771d5c66ad3a93 Mon Sep 17 00:00:00 2001 From: Ivan Komissarov Date: Sun, 21 Oct 2018 16:01:26 +0200 Subject: [PATCH 0580/1650] qwindowsxpstyle: Add std::nothrow to new There is no sense in testing the 'buf' pointer against null, as the memory was allocated using the throwing 'new' operator. However, since this function already can fail in other cases, the 'buf' pointer can be checked for nullptr after the nothrow new. Task-number: QTBUG-71156 Change-Id: Ibca5d672544d3980dd8890474e3e2fbf7443e05d Reviewed-by: Thiago Macieira --- src/plugins/styles/windowsvista/qwindowsxpstyle.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp index 4b583e13d3..43e8b37f71 100644 --- a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp +++ b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp @@ -511,8 +511,8 @@ QRegion QWindowsXPStylePrivate::region(XPThemeData &themeData) if (numBytes == 0) return QRegion(); - char *buf = new char[numBytes]; - if (buf == 0) + char *buf = new (std::nothrow) char[numBytes]; + if (!buf) return QRegion(); RGNDATA *rd = reinterpret_cast(buf); From b3008f8e253f5fca2c7d3328badcfeb189181652 Mon Sep 17 00:00:00 2001 From: Jesus Fernandez Date: Thu, 4 Oct 2018 16:49:34 +0200 Subject: [PATCH 0581/1650] Use QScopedPointer instead of new/delete MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I0651ad0244c1b4d3126a1dd3304f247f92240ffa Reviewed-by: Mårten Nordheim Reviewed-by: Jędrzej Nowacki Reviewed-by: Edward Welbourne --- tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 68a92ebcc3..31268c5cf3 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #if QT_CONFIG(process) # include #endif @@ -500,14 +501,13 @@ void tst_QObject::connectSlotsByName() void tst_QObject::qobject_castTemplate() { - QObject *o = 0; - QVERIFY( !::qobject_cast(o) ); + QScopedPointer o; + QVERIFY(!::qobject_cast(o.data())); - o = new SenderObject; - QVERIFY( ::qobject_cast(o) ); - QVERIFY( ::qobject_cast(o) ); - QVERIFY( !::qobject_cast(o) ); - delete o; + o.reset(new SenderObject); + QVERIFY(::qobject_cast(o.data())); + QVERIFY(::qobject_cast(o.data())); + QVERIFY(!::qobject_cast(o.data())); } void tst_QObject::findChildren() From 75ee55e22a49327193aade21bf615efc7c879564 Mon Sep 17 00:00:00 2001 From: Ryan Chu Date: Mon, 3 Dec 2018 12:04:57 +0100 Subject: [PATCH 0582/1650] Docker Provisioning: Update the SHA-1 tag of server images MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This update is used to free the dependencies of the specific Ubuntu packages. It ensures that test server is using the latest version of the Ubuntu packages to test network changes. Change-Id: I3257f435e6da02e3c6d5a141ece9c5d025e13065 Reviewed-by: Jędrzej Nowacki --- tests/testserver/docker-compose-for-macOS.yml | 10 +++++----- tests/testserver/docker-compose.yml | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/testserver/docker-compose-for-macOS.yml b/tests/testserver/docker-compose-for-macOS.yml index f5d812511d..fcf0f73c7e 100644 --- a/tests/testserver/docker-compose-for-macOS.yml +++ b/tests/testserver/docker-compose-for-macOS.yml @@ -12,7 +12,7 @@ version: '3.4' services: apache2: - image: qt-test-server-apache2:cc9ea678b92bdda33acb9fa0159bb4ad0f3cd947 + image: qt-test-server-apache2:537fe302f61851d1663f41495230d8e3554a4a13 container_name: qt-test-server-apache2 domainname: test-net.qt.local volumes: @@ -23,7 +23,7 @@ services: network_mode: "host" squid: - image: qt-test-server-squid:577d99307eea9a8cccfec944d25be2bce2fe99cc + image: qt-test-server-squid:9c32f41b19aca3d778733c4d8fb0ecc5955e893c container_name: qt-test-server-squid domainname: test-net.qt.local depends_on: @@ -36,7 +36,7 @@ services: network_mode: "host" vsftpd: - image: qt-test-server-vsftpd:18896604c7e90b543e56d80c8a8aabdb65a590d0 + image: qt-test-server-vsftpd:f3a9c8d793a77cc007c0e4e481bec01f9e3eeb7e container_name: qt-test-server-vsftpd domainname: test-net.qt.local volumes: @@ -47,7 +47,7 @@ services: network_mode: "host" ftp-proxy: - image: qt-test-server-ftp-proxy:2c6c8f1ab6a364b540c43d705fb6f15a585cb2af + image: qt-test-server-ftp-proxy:d7de8b28392d173db512a558ccc84ead8bece2ae container_name: qt-test-server-ftp-proxy domainname: test-net.qt.local depends_on: @@ -60,7 +60,7 @@ services: network_mode: "host" danted: - image: qt-test-server-danted:2d5eea7356dd0ba25f3c12d1cba00d70770da1b0 + image: qt-test-server-danted:35607f9b790524cf9690c7d12a9a401696b7b6b5 container_name: qt-test-server-danted domainname: test-net.qt.local depends_on: diff --git a/tests/testserver/docker-compose.yml b/tests/testserver/docker-compose.yml index a151d6bfb0..50f56bbe4d 100644 --- a/tests/testserver/docker-compose.yml +++ b/tests/testserver/docker-compose.yml @@ -12,7 +12,7 @@ version: '3.4' services: apache2: - image: qt-test-server-apache2:cc9ea678b92bdda33acb9fa0159bb4ad0f3cd947 + image: qt-test-server-apache2:537fe302f61851d1663f41495230d8e3554a4a13 container_name: qt-test-server-apache2 domainname: test-net.qt.local hostname: apache2 @@ -23,7 +23,7 @@ services: command: [common/ssl.sh, service/apache2.sh] squid: - image: qt-test-server-squid:577d99307eea9a8cccfec944d25be2bce2fe99cc + image: qt-test-server-squid:9c32f41b19aca3d778733c4d8fb0ecc5955e893c container_name: qt-test-server-squid domainname: test-net.qt.local hostname: squid @@ -38,7 +38,7 @@ services: command: service/squid.sh vsftpd: - image: qt-test-server-vsftpd:18896604c7e90b543e56d80c8a8aabdb65a590d0 + image: qt-test-server-vsftpd:f3a9c8d793a77cc007c0e4e481bec01f9e3eeb7e container_name: qt-test-server-vsftpd domainname: test-net.qt.local hostname: vsftpd @@ -49,7 +49,7 @@ services: command: service/vsftpd.sh ftp-proxy: - image: qt-test-server-ftp-proxy:2c6c8f1ab6a364b540c43d705fb6f15a585cb2af + image: qt-test-server-ftp-proxy:d7de8b28392d173db512a558ccc84ead8bece2ae container_name: qt-test-server-ftp-proxy domainname: test-net.qt.local hostname: ftp-proxy @@ -64,7 +64,7 @@ services: command: service/ftp-proxy.sh danted: - image: qt-test-server-danted:327dd56c3c35db85b26fac93213a5a1918475bc7 + image: qt-test-server-danted:35607f9b790524cf9690c7d12a9a401696b7b6b5 container_name: qt-test-server-danted domainname: test-net.qt.local hostname: danted From 163b5c02785c0462a31b9a3f5f05cda54e03de78 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 31 Oct 2018 16:47:20 -0700 Subject: [PATCH 0583/1650] RCC: Modernize the compression algorithm selection Instead of using compression level -2 to indicate no compression, introduce CompressionAlgorithm::None and an equivalent XML attribute. This commit includes some extra error checking for RCC. Change-Id: I343f2beed55440a7ac0bfffd1562d64b024463ba Reviewed-by: Lars Knoll Reviewed-by: hjk Reviewed-by: Oswald Buddenhagen --- src/tools/rcc/main.cpp | 27 +++++++++-- src/tools/rcc/rcc.cpp | 102 ++++++++++++++++++++++++++++++++++------- src/tools/rcc/rcc.h | 16 ++++++- 3 files changed, 122 insertions(+), 23 deletions(-) diff --git a/src/tools/rcc/main.cpp b/src/tools/rcc/main.cpp index 12f986b1e2..0defb03057 100644 --- a/src/tools/rcc/main.cpp +++ b/src/tools/rcc/main.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2018 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the tools applications of the Qt Toolkit. @@ -127,10 +128,21 @@ int runRcc(int argc, char *argv[]) QCommandLineOption rootOption(QStringLiteral("root"), QStringLiteral("Prefix resource access path with root path."), QStringLiteral("path")); parser.addOption(rootOption); +#if !defined(QT_NO_COMPRESS) +# define ALGOS "[zlib], none" +#else +# define ALGOS "[none]" +#endif + const QString &algoDescription = + QStringLiteral("Compress input files using algorithm (" ALGOS ")."); + QCommandLineOption compressionAlgoOption(QStringLiteral("compress-algo"), algoDescription, QStringLiteral("algo")); + parser.addOption(compressionAlgoOption); +#undef ALGOS + QCommandLineOption compressOption(QStringLiteral("compress"), QStringLiteral("Compress input files by ."), QStringLiteral("level")); parser.addOption(compressOption); - QCommandLineOption nocompressOption(QStringLiteral("no-compress"), QStringLiteral("Disable all compression.")); + QCommandLineOption nocompressOption(QStringLiteral("no-compress"), QStringLiteral("Disable all compression. Same as --compress-algo=none.")); parser.addOption(nocompressOption); QCommandLineOption thresholdOption(QStringLiteral("threshold"), QStringLiteral("Threshold to consider compressing files."), QStringLiteral("level")); @@ -189,10 +201,15 @@ int runRcc(int argc, char *argv[]) || library.resourceRoot().at(0) != QLatin1Char('/')) errorMsg = QLatin1String("Root must start with a /"); } - if (parser.isSet(compressOption)) - library.setCompressLevel(parser.value(compressOption).toInt()); + + if (parser.isSet(compressionAlgoOption)) + library.setCompressionAlgorithm(RCCResourceLibrary::parseCompressionAlgorithm(parser.value(compressionAlgoOption), &errorMsg)); if (parser.isSet(nocompressOption)) - library.setCompressLevel(-2); + library.setCompressionAlgorithm(RCCResourceLibrary::CompressionAlgorithm::None); + if (parser.isSet(compressOption) && errorMsg.isEmpty()) { + int level = library.parseCompressionLevel(library.compressionAlgorithm(), parser.value(compressOption), &errorMsg); + library.setCompressLevel(level); + } if (parser.isSet(thresholdOption)) library.setCompressThreshold(parser.value(thresholdOption).toInt()); if (parser.isSet(binaryOption)) diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp index 1a7cab01df..69e92bdd2f 100644 --- a/src/tools/rcc/rcc.cpp +++ b/src/tools/rcc/rcc.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2018 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the tools applications of the Qt Toolkit. @@ -51,6 +52,11 @@ enum { CONSTANT_COMPRESSTHRESHOLD_DEFAULT = 70 }; +#if !defined(QT_NO_COMPRESS) +# define CONSTANT_COMPRESSALGO_DEFAULT RCCResourceLibrary::CompressionAlgorithm::Zlib +#else +# define CONSTANT_COMPRESSALGO_DEFAULT RCCResourceLibrary::CompressionAlgorithm::None +#endif #define writeString(s) write(s, sizeof(s)) @@ -97,6 +103,7 @@ public: QLocale::Language language = QLocale::C, QLocale::Country country = QLocale::AnyCountry, uint flags = NoFlags, + RCCResourceLibrary::CompressionAlgorithm compressAlgo = CONSTANT_COMPRESSALGO_DEFAULT, int compressLevel = CONSTANT_COMPRESSLEVEL_DEFAULT, int compressThreshold = CONSTANT_COMPRESSTHRESHOLD_DEFAULT); ~RCCFileInfo(); @@ -115,6 +122,7 @@ public: QFileInfo m_fileInfo; RCCFileInfo *m_parent; QHash m_children; + RCCResourceLibrary::CompressionAlgorithm m_compressAlgo; int m_compressLevel; int m_compressThreshold; @@ -125,7 +133,7 @@ public: RCCFileInfo::RCCFileInfo(const QString &name, const QFileInfo &fileInfo, QLocale::Language language, QLocale::Country country, uint flags, - int compressLevel, int compressThreshold) + RCCResourceLibrary::CompressionAlgorithm compressAlgo, int compressLevel, int compressThreshold) { m_name = name; m_fileInfo = fileInfo; @@ -136,6 +144,7 @@ RCCFileInfo::RCCFileInfo(const QString &name, const QFileInfo &fileInfo, m_nameOffset = 0; m_dataOffset = 0; m_childOffset = 0; + m_compressAlgo = compressAlgo; m_compressLevel = compressLevel; m_compressThreshold = compressThreshold; } @@ -236,16 +245,26 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset, } QByteArray data = file.readAll(); -#ifndef QT_NO_COMPRESS // Check if compression is useful for this file - if (m_compressLevel != 0 && data.size() != 0) { - QByteArray compressed = - qCompress(reinterpret_cast(data.data()), data.size(), m_compressLevel); + if (data.size() != 0) { +#ifndef QT_NO_COMPRESS + if (m_compressAlgo == RCCResourceLibrary::CompressionAlgorithm::Zlib) { + QByteArray compressed = + qCompress(reinterpret_cast(data.data()), data.size(), m_compressLevel); - int compressRatio = int(100.0 * (data.size() - compressed.size()) / data.size()); - if (compressRatio >= m_compressThreshold) { - data = compressed; - m_flags |= Compressed; + int compressRatio = int(100.0 * (data.size() - compressed.size()) / data.size()); + if (compressRatio >= m_compressThreshold) { + if (lib.verbose()) { + QString msg = QString::fromLatin1("%1: note: compressed using zlib (%2 -> %3)\n") + .arg(m_name).arg(data.size()).arg(compressed.size()); + lib.m_errorDevice->write(msg.toUtf8()); + } + data = compressed; + m_flags |= Compressed; + } else if (lib.verbose()) { + QString msg = QString::fromLatin1("%1: note: not compressed\n").arg(m_name); + lib.m_errorDevice->write(msg.toUtf8()); + } } } #endif // QT_NO_COMPRESS @@ -343,7 +362,8 @@ RCCResourceLibrary::Strings::Strings() : ATTRIBUTE_PREFIX(QLatin1String("prefix")), ATTRIBUTE_ALIAS(QLatin1String("alias")), ATTRIBUTE_THRESHOLD(QLatin1String("threshold")), - ATTRIBUTE_COMPRESS(QLatin1String("compress")) + ATTRIBUTE_COMPRESS(QLatin1String("compress")), + ATTRIBUTE_COMPRESSALGO(QStringLiteral("compression-algorithm")) { } @@ -351,6 +371,7 @@ RCCResourceLibrary::RCCResourceLibrary(quint8 formatVersion) : m_root(0), m_format(C_Code), m_verbose(false), + m_compressionAlgo(CONSTANT_COMPRESSALGO_DEFAULT), m_compressLevel(CONSTANT_COMPRESSLEVEL_DEFAULT), m_compressThreshold(CONSTANT_COMPRESSTHRESHOLD_DEFAULT), m_treeOffset(0), @@ -391,6 +412,7 @@ bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice, QLocale::Language language = QLocale::c().language(); QLocale::Country country = QLocale::c().country(); QString alias; + auto compressAlgo = m_compressionAlgo; int compressLevel = m_compressLevel; int compressThreshold = m_compressThreshold; @@ -444,17 +466,27 @@ bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice, if (attributes.hasAttribute(m_strings.ATTRIBUTE_ALIAS)) alias = attributes.value(m_strings.ATTRIBUTE_ALIAS).toString(); + compressAlgo = m_compressionAlgo; compressLevel = m_compressLevel; - if (attributes.hasAttribute(m_strings.ATTRIBUTE_COMPRESS)) - compressLevel = attributes.value(m_strings.ATTRIBUTE_COMPRESS).toString().toInt(); - compressThreshold = m_compressThreshold; + + QString errorString; + if (attributes.hasAttribute(m_strings.ATTRIBUTE_COMPRESSALGO)) + compressAlgo = parseCompressionAlgorithm(attributes.value(m_strings.ATTRIBUTE_COMPRESSALGO), &errorString); + if (errorString.isEmpty() && attributes.hasAttribute(m_strings.ATTRIBUTE_COMPRESS)) { + QString value = attributes.value(m_strings.ATTRIBUTE_COMPRESS).toString(); + compressLevel = parseCompressionLevel(compressAlgo, value, &errorString); + } + + // Special case for -no-compress + if (m_compressLevel == -2) + compressAlgo = CompressionAlgorithm::None; + if (attributes.hasAttribute(m_strings.ATTRIBUTE_THRESHOLD)) compressThreshold = attributes.value(m_strings.ATTRIBUTE_THRESHOLD).toString().toInt(); - // Special case for -no-compress. Overrides all other settings. - if (m_compressLevel == -2) - compressLevel = 0; + if (!errorString.isEmpty()) + reader.raiseError(errorString); } } else { reader.raiseError(QString(QLatin1String("unexpected tag: %1")).arg(reader.name().toString())); @@ -520,6 +552,7 @@ bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice, language, country, child.isDir() ? RCCFileInfo::Directory : RCCFileInfo::NoFlags, + compressAlgo, compressLevel, compressThreshold) ); @@ -535,6 +568,7 @@ bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice, language, country, RCCFileInfo::NoFlags, + compressAlgo, compressLevel, compressThreshold) ); @@ -729,6 +763,40 @@ RCCResourceLibrary::ResourceDataFileMap RCCResourceLibrary::resourceDataFileMap( return rc; } +RCCResourceLibrary::CompressionAlgorithm RCCResourceLibrary::parseCompressionAlgorithm(QStringView value, QString *errorMsg) +{ + if (value == QLatin1String("zlib")) { +#ifdef QT_NO_COMPRESS + *errorMsg = QLatin1String("zlib support not compiled in"); +#else + return CompressionAlgorithm::Zlib; +#endif + } else if (value != QLatin1String("none")) { + *errorMsg = QString::fromLatin1("Unknown compression algorithm '%1'").arg(value); + } + + return CompressionAlgorithm::None; +} + +int RCCResourceLibrary::parseCompressionLevel(CompressionAlgorithm algo, const QString &level, QString *errorMsg) +{ + bool ok; + int c = level.toInt(&ok); + if (ok) { + switch (algo) { + case CompressionAlgorithm::None: + return 0; + case CompressionAlgorithm::Zlib: + if (c >= 1 && c <= 9) + return c; + break; + } + } + + *errorMsg = QString::fromLatin1("invalid compression level '%1'").arg(level); + return 0; +} + bool RCCResourceLibrary::output(QIODevice &outDevice, QIODevice &tempDevice, QIODevice &errorDevice) { m_errorDevice = &errorDevice; diff --git a/src/tools/rcc/rcc.h b/src/tools/rcc/rcc.h index 36984cf38a..5c6823e56f 100644 --- a/src/tools/rcc/rcc.h +++ b/src/tools/rcc/rcc.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2018 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the tools applications of the Qt Toolkit. @@ -77,6 +78,17 @@ public: void setOutputName(const QString &name) { m_outputName = name; } QString outputName() const { return m_outputName; } + enum class CompressionAlgorithm { + Zlib, + + None = -1 + }; + + static CompressionAlgorithm parseCompressionAlgorithm(QStringView algo, QString *errorMsg); + void setCompressionAlgorithm(CompressionAlgorithm algo) { m_compressionAlgo = algo; } + CompressionAlgorithm compressionAlgorithm() const { return m_compressionAlgo; } + + static int parseCompressionLevel(CompressionAlgorithm algo, const QString &level, QString *errorMsg); void setCompressLevel(int c) { m_compressLevel = c; } int compressLevel() const { return m_compressLevel; } @@ -104,6 +116,7 @@ private: const QString ATTRIBUTE_ALIAS; const QString ATTRIBUTE_THRESHOLD; const QString ATTRIBUTE_COMPRESS; + const QString ATTRIBUTE_COMPRESSALGO; }; friend class RCCFileInfo; void reset(); @@ -133,6 +146,7 @@ private: QString m_outputName; Format m_format; bool m_verbose; + CompressionAlgorithm m_compressionAlgo; int m_compressLevel; int m_compressThreshold; int m_treeOffset; From f25bc30d8d9d13fffd34213dfbf5e7373a18222a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 31 Oct 2018 22:42:14 -0700 Subject: [PATCH 0584/1650] QResource: add support for resources compressed with Zstandard See next commit for details on why this is a good idea. [ChangeLog][Important Behavior Changes] The Qt resource system now supports compressing content using the Zstandard (https://zstd.net) algorithm. Compared to zlib, it compresses better for the same CPU time, so this algorithm is the default. QResource::isCompressed() returns true for either compression algorithm. Use QResource::compressionAlgorithm() to find out which algorithm to decompress. QFile will automatically decompress using the correct algorithm. Change-Id: I343f2beed55440a7ac0bfffd1562e9a8f94933a7 Reviewed-by: Oswald Buddenhagen Reviewed-by: Samuel Gaist Reviewed-by: Lars Knoll --- configure.json | 26 ++++- src/corelib/global/qconfig-bootstrapped.h | 1 + src/corelib/io/io.pri | 2 + src/corelib/io/qresource.cpp | 123 ++++++++++++++++++---- src/corelib/io/qresource.h | 7 ++ src/tools/rcc/rcc.cpp | 1 + 6 files changed, 140 insertions(+), 20 deletions(-) diff --git a/configure.json b/configure.json index e34a9cbad5..a2cc39d760 100644 --- a/configure.json +++ b/configure.json @@ -136,7 +136,8 @@ "Werror": { "type": "boolean", "name": "warnings_are_errors" }, "widgets": "boolean", "xplatform": "string", - "zlib": { "type": "enum", "name": "system-zlib", "values": { "system": "yes", "qt": "no" } } + "zlib": { "type": "enum", "name": "system-zlib", "values": { "system": "yes", "qt": "no" } }, + "zstd": "boolean" }, "prefix": { "D": "defines", @@ -167,6 +168,21 @@ { "libs": "-s USE_ZLIB=1", "condition": "config.wasm" } ] }, + "zstd": { + "label": "Zstandard", + "test": { + "include": "zstd.h", + "main": [ + "(void) ZSTD_compress(NULL, 0, NULL, 0, 1);", + "unsigned long long n = ZSTD_getFrameContentSize(NULL, 0);", + "(void) ZSTD_decompress(NULL, 0, NULL, n);" + ] + }, + "sources": [ + { "type": "pkgConfig", "args": "libzstd >= 1.3" }, + "-lzstd" + ] + }, "dbus": { "label": "D-Bus >= 1.2", "test": { @@ -1126,6 +1142,11 @@ "condition": "libs.zlib", "output": [ "privateFeature" ] }, + "zstd": { + "label": "Zstandard support", + "condition": "libs.zstd", + "output": [ "privateFeature" ] + }, "thread": { "label": "Thread support", "purpose": "Provides QThread and related classes.", @@ -1452,7 +1473,8 @@ Configure with '-qreal float' to create a build that is binary-compatible with 5 "entries": [ "pkg-config", "libudev", - "system-zlib" + "system-zlib", + "zstd" ] } ] diff --git a/src/corelib/global/qconfig-bootstrapped.h b/src/corelib/global/qconfig-bootstrapped.h index dfcc3c9c7f..bd35ae9712 100644 --- a/src/corelib/global/qconfig-bootstrapped.h +++ b/src/corelib/global/qconfig-bootstrapped.h @@ -121,6 +121,7 @@ #define QT_FEATURE_topleveldomain -1 #define QT_NO_TRANSLATION #define QT_FEATURE_translation -1 +#define QT_FEATURE_zstd -1 #ifdef QT_BUILD_QMAKE #define QT_FEATURE_commandlineparser -1 diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index 086d642c26..9b6044752f 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -79,6 +79,8 @@ SOURCES += \ io/qloggingcategory.cpp \ io/qloggingregistry.cpp +qtConfig(zstd): QMAKE_USE_PRIVATE += zstd + qtConfig(filesystemwatcher) { HEADERS += \ io/qfilesystemwatcher.h \ diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index 9cfaa4d623..0d3aa563c8 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2018 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -56,8 +57,13 @@ #include "private/qabstractfileengine_p.h" #include "private/qnumeric_p.h" #include "private/qsimd_p.h" +#include "private/qtools_p.h" #include "private/qsystemerror_p.h" +#if QT_CONFIG(zstd) +# include +#endif + #ifdef Q_OS_UNIX # include "private/qcore_unix_p.h" #endif @@ -100,8 +106,10 @@ class QResourceRoot { enum Flags { + // must match rcc.h Compressed = 0x01, - Directory = 0x02 + Directory = 0x02, + CompressedZstd = 0x04 }; const uchar *tree, *names, *payloads; int version; @@ -117,7 +125,15 @@ public: virtual ~QResourceRoot() { } int findNode(const QString &path, const QLocale &locale=QLocale()) const; inline bool isContainer(int node) const { return flags(node) & Directory; } - inline bool isCompressed(int node) const { return flags(node) & Compressed; } + QResource::Compression compressionAlgo(int node) + { + uint compressionFlags = flags(node) & (Compressed | CompressedZstd); + if (compressionFlags == Compressed) + return QResource::ZlibCompression; + if (compressionFlags == CompressedZstd) + return QResource::ZstdCompression; + return QResource::NoCompression; + } const uchar *data(int node, qint64 *size) const; quint64 lastModified(int node) const; QStringList children(int node) const; @@ -229,6 +245,23 @@ static inline QStringList *resourceSearchPaths() \sa {The Qt Resource System}, QFile, QDir, QFileInfo */ +/*! + \enum QResource::Compression + \since 5.13 + + This enum is used by compressionAlgorithm() to indicate which algorithm the + RCC tool used to compress the payload. + + \value NoCompression Contents are not compressed (isCompressed() is false). + \value ZlibCompression Contents are compressed using \l{zlib}{https://zlib.net} and can + be decompressed using the qUncompress() function. + \value ZstdCompression Contents are compressed using \l{zstd}{https://zstd.net}. To + decompress, use the \c{ZSTD_decompress} function from the zstd + library. + + \sa compressionAlgorithm(), isCopressed() +*/ + class QResourcePrivate { public: inline QResourcePrivate(QResource *_q) : q_ptr(_q) { clear(); } @@ -243,12 +276,13 @@ public: QLocale locale; QString fileName, absoluteFilePath; QList related; - uint container : 1; - mutable uint compressed : 1; mutable qint64 size; + mutable quint64 lastModified; mutable const uchar *data; mutable QStringList children; - mutable quint64 lastModified; + mutable quint8 compressionAlgo; + bool container; + /* 2 or 6 padding bytes */ QResource *q_ptr; Q_DECLARE_PUBLIC(QResource) @@ -258,7 +292,7 @@ void QResourcePrivate::clear() { absoluteFilePath.clear(); - compressed = 0; + compressionAlgo = QResource::NoCompression; data = 0; size = 0; children.clear(); @@ -287,11 +321,11 @@ QResourcePrivate::load(const QString &file) container = res->isContainer(node); if(!container) { data = res->data(node, &size); - compressed = res->isCompressed(node); + compressionAlgo = res->compressionAlgo(node); } else { - data = 0; + data = nullptr; size = 0; - compressed = 0; + compressionAlgo = QResource::NoCompression; } lastModified = res->lastModified(node); } else if(res->isContainer(node) != container) { @@ -301,9 +335,9 @@ QResourcePrivate::load(const QString &file) related.append(res); } else if(res->mappingRootSubdir(file)) { container = true; - data = 0; + data = nullptr; size = 0; - compressed = 0; + compressionAlgo = QResource::NoCompression; lastModified = 0; res->ref.ref(); related.append(res); @@ -493,16 +527,41 @@ bool QResource::isValid() const /*! Returns \c true if the resource represents a file and the data backing it - is in a compressed format, false otherwise. + is in a compressed format, false otherwise. If the data is compressed, + check compressionAlgorithm() to verify what algorithm to use to decompress + the data. - \sa data(), isFile() + \sa data(), compressionType(), isFile() */ bool QResource::isCompressed() const +{ + return compressionAlgorithm() != NoCompression; +} + +/*! + \since 5.13 + + Returns the compression type that this resource is compressed with, if any. + If it is not compressed, this function returns QResource::NoCompression. + + If this function returns QResource::ZlibCompression, you may decompress the + data using the qUncompress() function. Up until Qt 5.13, this was the only + possible compression algorithm. + + If this function returns QResource::ZstdCompression, you need to use the + Zstandard library functios (\c{ header). Qt does not provide a + wrapper. + + See \l{http://facebook.github.io/zstd/zstd_manual.html}{Zstandard manual}. + + \sa isCompressed(), data(), isFile() +*/ +QResource::Compression QResource::compressionAlgorithm() const { Q_D(const QResource); d->ensureInitialized(); - return d->compressed; + return Compression(d->compressionAlgo); } /*! @@ -1531,12 +1590,40 @@ bool QResourceFileEnginePrivate::unmap(uchar *ptr) void QResourceFileEnginePrivate::uncompress() const { - if (resource.isCompressed() && uncompressed.isEmpty() && resource.size()) { + if (uncompressed.isEmpty() && resource.size()) { + quint64 size; + switch (resource.compressionAlgorithm()) { + case QResource::NoCompression: + return; // nothing to do + + case QResource::ZlibCompression: #ifndef QT_NO_COMPRESS - uncompressed = qUncompress(resource.data(), resource.size()); + uncompressed = qUncompress(resource.data(), resource.size()); #else - Q_ASSERT(!"QResourceFileEngine::open: Qt built without support for compression"); + Q_ASSERT(!"QResourceFileEngine::open: Qt built without support for Zlib compression"); #endif + break; + + case QResource::ZstdCompression: +#if QT_CONFIG(zstd) + size = ZSTD_getFrameContentSize(resource.data(), resource.size()); + if (!ZSTD_isError(size)) { + if (size >= MaxAllocSize) { + qWarning("QResourceFileEngine::open: content bigger than memory (size %lld)", size); + } else { + uncompressed = QByteArray(size, Qt::Uninitialized); + size = ZSTD_decompress(const_cast(uncompressed.data()), size, + resource.data(), resource.size()); + } + } + if (ZSTD_isError(size)) + qWarning("QResourceFileEngine::open: error decoding: %s", ZSTD_getErrorName(size)); +#else + Q_UNUSED(size); + Q_ASSERT(!"QResourceFileEngine::open: Qt built without support for Zstd compression"); +#endif + break; + } } } diff --git a/src/corelib/io/qresource.h b/src/corelib/io/qresource.h index 895cf0456e..9aa17608ce 100644 --- a/src/corelib/io/qresource.h +++ b/src/corelib/io/qresource.h @@ -54,6 +54,12 @@ class QResourcePrivate; class Q_CORE_EXPORT QResource { public: + enum Compression { + NoCompression, + ZlibCompression, + ZstdCompression + }; + QResource(const QString &file=QString(), const QLocale &locale=QLocale()); ~QResource(); @@ -67,6 +73,7 @@ public: bool isValid() const; bool isCompressed() const; + Compression compressionAlgorithm() const; qint64 size() const; const uchar *data() const; QDateTime lastModified() const; diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp index 69e92bdd2f..a73220d05c 100644 --- a/src/tools/rcc/rcc.cpp +++ b/src/tools/rcc/rcc.cpp @@ -94,6 +94,7 @@ class RCCFileInfo public: enum Flags { + // must match qresource.cpp NoFlags = 0x00, Compressed = 0x01, Directory = 0x02 From 2c9ac4fc3fe0b8f39e7f7a93894b56e49fd3d887 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 31 Oct 2018 17:06:21 -0700 Subject: [PATCH 0585/1650] RCC: Add support for Zstandard compression [ChangeLog][RCC] RCC now supports compressing content using the Zstandard (https://zstd.net) algorithm. Compared to zlib, it compresses better for the same CPU time, so this algorithm is the default. To go back to the previous algorithm, pass command-line option --compress-algo=zlib. Compression levels range from 1 (fastest, least compression) to 19 (slowest, best compression). Level 0 tells the library to choose an implementation-defined default. \ The default compression level is "heuristic" (level -1): under this mode, RCC will attempt a very fast compression (level 1) and check if the file was sufficiently compressed. If it was, then RCC will compress again using an implementation-defined level. The following are the 4 biggest files we store as resources in qtbase: Orig Size Name 2197605 src/corelib/mimetypes/mime/packages/freedesktop.org.xml 2462423 tests/auto/corelib/tools/qchar/data/NormalizationTest.txt 6878748 tests/auto/other/qcomplextext/data/BidiCharacterTest.txt 7959972 tests/auto/other/qcomplextext/data/BidiTest.txt The current RCC (zlib, level -1 "default" and level 9), produces for those files: L(-1) Compr. L9 Compr. Decomp. Name Ratio CPU time Ratio CPU time CPU time BidiCharacterTest.txt 16.9:1 106.1ms 17.2:1 789.3ms 5.1ms BidiTest.txt 6.3:1 228.0ms 6.1:1 1646.3ms 10.9ms freedesktop.org.xml 7.0:1 17.5ms 7.1:1 53.6ms 2.6ms NormalizationTest.txt 5.8:1 41.2ms 5.9:1 256.4ms 3.4ms Zstandard produces the following for levels 1 ("check"), 14 ("store") and 19 ("best"): L1 Compr. L14 Compr. L19 Compr. Decomp Name Ratio time Ratio time Ratio CPU time time BidiCharacterTest.txt 15.8:1 8.0ms 26.1:1 168.9ms 49.2:1 2504.7ms 3.8ms BidiTest.txt 8.2:1 17.0ms 8.7:1 323.9ms 14.9:1 1700.9ms 12.1ms freedesktop.org.xml 6.7:1 4.0ms 8.7:1 63.3ms 9.5:1 642.5ms 1.7ms NormalizationTest.txt 5.7:1 5.0ms 7.5:1 54.0ms 8.4:1 447.3ms 3.0ms This shows use of zstd at the default RCC level settings always produce smaller outputs compared to the current zlib-based defaults, with roughly 50% CPU increase. It also produces better results at less CPU time than the best compression zlib has to offer. More importantly, the decompression time reduces in all cases (the numbers listed are for max compression, with slightly better results for the defaults). For the sake of comparison, the same files compressed with libxz at levels 3 and 6: Level 3 Level 6 Decompr. Name Ratio CPU Ratio CPU time BidiCharacterTest.txt 28.5:1 109.1ms 42.9:1 1390.5ms 16.7ms BidiTest.txt 10.7:1 281.0ms 18.4:1 2333.1ms 43.6ms freedesktop.org.xml 9.1:1 62.0ms 10.2:1 499.1ms 12.0ms NormalizationTest.txt 10.2:1 75.5ms 13.2:1 417.6ms 14.7ms LZMA at level 3 consumes roughly the same CPU time as Zstd at level 14 and produces incrementally smaller results, but the decompression time increases considerably. It's not a good trade-off for the Qt resource system. Change-Id: I343f2beed55440a7ac0bfffd1562d754bd71d964 Reviewed-by: Lars Knoll Reviewed-by: Oswald Buddenhagen --- src/corelib/doc/src/resource-system.qdoc | 67 +++++++++++++++++--- src/corelib/global/qconfig-bootstrapped.h | 4 ++ src/tools/rcc/main.cpp | 6 +- src/tools/rcc/rcc.cpp | 74 ++++++++++++++++++++++- src/tools/rcc/rcc.h | 7 +++ src/tools/rcc/rcc.pro | 11 ++++ 6 files changed, 157 insertions(+), 12 deletions(-) diff --git a/src/corelib/doc/src/resource-system.qdoc b/src/corelib/doc/src/resource-system.qdoc index 9b6b613f79..69ec5e556b 100644 --- a/src/corelib/doc/src/resource-system.qdoc +++ b/src/corelib/doc/src/resource-system.qdoc @@ -100,6 +100,9 @@ See the QLocale documentation for a description of the format to use for locale strings. + See QFileSelector for an additional mechanism to select locale-specific + resources, in addition to the ability to select OS-specific and other + features. \section2 External Binary Resources @@ -143,24 +146,70 @@ \section1 Compression - Resources are compressed by default (in the \c ZIP format). It is - possible to turn off compression. This can be useful if your - resources already contain a compressed format, such as \c .png - files. You do this by giving the \c {-no-compress} command line - argument. + \c rcc attempts to compress the content to optimize disk space usage in the + final binaries. By default, it will perform a heuristic check to determine + whether compressing is worth it and will store the content uncompressed if + it fails to sufficiently compress. To control the threshold, you can use + the \c {-threshold} option, which tells \c rcc the percentage of the + original file size that must be gained for it to store the file in + compressed form. + + \code + rcc -threshold 25 myresources.qrc + \endcode + + The default value is "70", indicating that the compressed file must be 70% + smaller than the original (no more than 30% of the original file size). + + It is possible to turn off compression, if desired. This can be useful if + your resources already contain a compressed format, such as \c .png files, + and you do not want to incur the CPU cost at build time to confirm that it + can't be compressed. Another reason is if disk usage is not a problem and + the application would prefer to keep the content as clean memory pages at + runtime. You do this by giving the \c {-no-compress} command line argument. \code rcc -no-compress myresources.qrc \endcode - \c rcc also gives you some control over the compression. You can - specify the compression level and the threshold level to consider - while compressing files, for example: + \c rcc also gives you some control over the compression level and + compression algorithm, for example: \code - rcc -compress 2 -threshold 3 myresources.qrc + rcc -compress 2 -compress-algo zlib myresources.qrc \endcode + \c rcc supports the following compression algorithms and compression + levels: + + \list + \li \c{best}: use the best algorithm among the ones below, at its highest + compression level, to achieve the most compression at the expense of + using a lot of CPU time during compilation. This value is useful in the + XML file to indicate a file should be most compressed, regardless of + which algorithms \c rcc supports. + + \li \c{zstd}: use the \l{Zstandard}{https://zstd.net} library to compress + contents. Valid compression levels range from 1 to 19, 1 is least + compression (least CPU time) and 19 is the most compression (most CPU + time). The default level is 14. A special value of 0 tells the \c{zstd} + library to choose an implementation-defined default. + + \li \c{zlib}: use the \l{zlib}{https://zlib.net} library to compress + contents. Valid compression levels range from 1 to 9, with 1the least + compression (least CPU time) and 9 the most compression (most CPU time). + The special value 0 means "no compression" and should not be used. The + default is implementation-defined, but usually is level 6. + + \li \c{none}: no compression. This is the same as the \c{-no-compress} + option. + \endlist + + Support for both Zstandard and zlib are optional. If a given library was + not detected at compile time, attempting to pass \c {-compress-algo} for + that library will result in an error. The default compression algorithm is + \c zstd if it is enabled, \c zlib if not. + \section1 Using Resources in the Application In the application, resource paths can be used in most places diff --git a/src/corelib/global/qconfig-bootstrapped.h b/src/corelib/global/qconfig-bootstrapped.h index bd35ae9712..10458e41d7 100644 --- a/src/corelib/global/qconfig-bootstrapped.h +++ b/src/corelib/global/qconfig-bootstrapped.h @@ -121,7 +121,11 @@ #define QT_FEATURE_topleveldomain -1 #define QT_NO_TRANSLATION #define QT_FEATURE_translation -1 + +// rcc.pro will DEFINES+= this +#ifndef QT_FEATURE_zstd #define QT_FEATURE_zstd -1 +#endif #ifdef QT_BUILD_QMAKE #define QT_FEATURE_commandlineparser -1 diff --git a/src/tools/rcc/main.cpp b/src/tools/rcc/main.cpp index 0defb03057..71836b81bd 100644 --- a/src/tools/rcc/main.cpp +++ b/src/tools/rcc/main.cpp @@ -128,7 +128,11 @@ int runRcc(int argc, char *argv[]) QCommandLineOption rootOption(QStringLiteral("root"), QStringLiteral("Prefix resource access path with root path."), QStringLiteral("path")); parser.addOption(rootOption); -#if !defined(QT_NO_COMPRESS) +#if QT_CONFIG(zstd) && !defined(QT_NO_COMPRESS) +# define ALGOS "[zstd], zlib, none" +#elif QT_CONFIG(zstd) +# define ALGOS "[zstd], none" +#elif !defined(QT_NO_COMPRESS) # define ALGOS "[zlib], none" #else # define ALGOS "[none]" diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp index a73220d05c..dfa62cea1b 100644 --- a/src/tools/rcc/rcc.cpp +++ b/src/tools/rcc/rcc.cpp @@ -42,6 +42,10 @@ #include +#if QT_CONFIG(zstd) +# include +#endif + // Note: A copy of this file is used in Qt Designer (qttools/src/designer/src/lib/shared/rcc.cpp) QT_BEGIN_NAMESPACE @@ -49,10 +53,14 @@ QT_BEGIN_NAMESPACE enum { CONSTANT_USENAMESPACE = 1, CONSTANT_COMPRESSLEVEL_DEFAULT = -1, + CONSTANT_ZSTDCOMPRESSLEVEL_CHECK = 1, // Zstd level to check if compressing is a good idea + CONSTANT_ZSTDCOMPRESSLEVEL_STORE = 14, // Zstd level to actually store the data CONSTANT_COMPRESSTHRESHOLD_DEFAULT = 70 }; -#if !defined(QT_NO_COMPRESS) +#if QT_CONFIG(zstd) +# define CONSTANT_COMPRESSALGO_DEFAULT RCCResourceLibrary::CompressionAlgorithm::Zstd +#elif !defined(QT_NO_COMPRESS) # define CONSTANT_COMPRESSALGO_DEFAULT RCCResourceLibrary::CompressionAlgorithm::Zlib #else # define CONSTANT_COMPRESSALGO_DEFAULT RCCResourceLibrary::CompressionAlgorithm::None @@ -97,7 +105,8 @@ public: // must match qresource.cpp NoFlags = 0x00, Compressed = 0x01, - Directory = 0x02 + Directory = 0x02, + CompressedZstd = 0x04 }; RCCFileInfo(const QString &name = QString(), const QFileInfo &fileInfo = QFileInfo(), @@ -248,6 +257,49 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset, // Check if compression is useful for this file if (data.size() != 0) { +#if QT_CONFIG(zstd) + if (m_compressAlgo == RCCResourceLibrary::CompressionAlgorithm::Zstd) { + if (lib.m_zstdCCtx == nullptr) + lib.m_zstdCCtx = ZSTD_createCCtx(); + qsizetype size = data.size(); + size = ZSTD_COMPRESSBOUND(size); + + int compressLevel = m_compressLevel; + if (compressLevel < 0) + compressLevel = CONSTANT_ZSTDCOMPRESSLEVEL_CHECK; + + QByteArray compressed(size, Qt::Uninitialized); + char *dst = const_cast(compressed.constData()); + size_t n = ZSTD_compressCCtx(lib.m_zstdCCtx, dst, size, + data.constData(), data.size(), + compressLevel); + if (n * 100.0 < data.size() * 1.0 * (100 - m_compressThreshold) ) { + // compressing is worth it + if (m_compressLevel < 0) { + // heuristic compression, so recompress + n = ZSTD_compressCCtx(lib.m_zstdCCtx, dst, size, + data.constData(), data.size(), + CONSTANT_ZSTDCOMPRESSLEVEL_STORE); + } + if (ZSTD_isError(n)) { + QString msg = QString::fromLatin1("%1: error: compression with zstd failed: %2\n") + .arg(m_name, QString::fromUtf8(ZSTD_getErrorName(n))); + lib.m_errorDevice->write(msg.toUtf8()); + } else if (lib.verbose()) { + QString msg = QString::fromLatin1("%1: note: compressed using zstd (%2 -> %3)\n") + .arg(m_name).arg(data.size()).arg(n); + lib.m_errorDevice->write(msg.toUtf8()); + } + + m_flags |= CompressedZstd; + data = std::move(compressed); + data.truncate(n); + } else if (lib.verbose()) { + QString msg = QString::fromLatin1("%1: note: not compressed\n").arg(m_name); + lib.m_errorDevice->write(msg.toUtf8()); + } + } +#endif #ifndef QT_NO_COMPRESS if (m_compressAlgo == RCCResourceLibrary::CompressionAlgorithm::Zlib) { QByteArray compressed = @@ -384,11 +436,17 @@ RCCResourceLibrary::RCCResourceLibrary(quint8 formatVersion) m_formatVersion(formatVersion) { m_out.reserve(30 * 1000 * 1000); +#if QT_CONFIG(zstd) + m_zstdCCtx = nullptr; +#endif } RCCResourceLibrary::~RCCResourceLibrary() { delete m_root; +#if QT_CONFIG(zstd) + ZSTD_freeCCtx(m_zstdCCtx); +#endif } enum RCCXmlTag { @@ -771,6 +829,12 @@ RCCResourceLibrary::CompressionAlgorithm RCCResourceLibrary::parseCompressionAlg *errorMsg = QLatin1String("zlib support not compiled in"); #else return CompressionAlgorithm::Zlib; +#endif + } else if (value == QLatin1String("zstd")) { +#if QT_CONFIG(zstd) + return CompressionAlgorithm::Zstd; +#else + *errorMsg = QLatin1String("Zstandard support not compiled in"); #endif } else if (value != QLatin1String("none")) { *errorMsg = QString::fromLatin1("Unknown compression algorithm '%1'").arg(value); @@ -791,6 +855,12 @@ int RCCResourceLibrary::parseCompressionLevel(CompressionAlgorithm algo, const Q if (c >= 1 && c <= 9) return c; break; + case CompressionAlgorithm::Zstd: +#if QT_CONFIG(zstd) + if (c >= 0 && c <= ZSTD_maxCLevel()) + return c; +#endif + break; } } diff --git a/src/tools/rcc/rcc.h b/src/tools/rcc/rcc.h index 5c6823e56f..fe8ed21fb3 100644 --- a/src/tools/rcc/rcc.h +++ b/src/tools/rcc/rcc.h @@ -36,6 +36,8 @@ #include #include +typedef struct ZSTD_CCtx_s ZSTD_CCtx; + QT_BEGIN_NAMESPACE class RCCFileInfo; @@ -80,6 +82,7 @@ public: enum class CompressionAlgorithm { Zlib, + Zstd, None = -1 }; @@ -138,6 +141,10 @@ private: void writeByteArray(const QByteArray &); void write(const char *, int len); +#if QT_CONFIG(zstd) + ZSTD_CCtx *m_zstdCCtx; +#endif + const Strings m_strings; RCCFileInfo *m_root; QStringList m_fileNames; diff --git a/src/tools/rcc/rcc.pro b/src/tools/rcc/rcc.pro index 208ec54a73..ae55b5d8af 100644 --- a/src/tools/rcc/rcc.pro +++ b/src/tools/rcc/rcc.pro @@ -8,3 +8,14 @@ SOURCES += main.cpp QMAKE_TARGET_DESCRIPTION = "Qt Resource Compiler" load(qt_tool) + +# RCC is a bootstrapped tool, so qglobal.h #includes qconfig-bootstrapped.h +# and that has a #define saying zstd isn't present (for qresource.cpp, which is +# part of the bootstrap lib). So we inform the presence of the feature in the +# command-line. +qtConfig(zstd):!cross_compile { + DEFINES += QT_FEATURE_zstd=1 + QMAKE_USE_PRIVATE += zstd +} else { + DEFINES += QT_FEATURE_zstd=-1 +} From 57b4b45cbdee00f7e38e5eb57d2bcf42201dc74e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 31 Oct 2018 19:13:29 -0700 Subject: [PATCH 0586/1650] RCC: introduce compression algorithm "best" This compression algorithm is permitted in the XML sources, which instructs RCC to apply the best compression algorithm it has available. If we have Zstandard available, that's its level 19 (levels 20 and up are experimental). If not, we apply zlib compression level 9. And apply this technique for the XDG MIME database that is built-in to QtCore. Payload size Compr. time Previously 313916 17.9ms Zlib -9 310899 53.6ms Zstd -14 253364 63.3ms (plus 4.0 ms on L1 heuristic check) Zstd -19 230647 642.5ms Change-Id: I343f2beed55440a7ac0bfffd1562de44dbaf09cd Reviewed-by: Oswald Buddenhagen Reviewed-by: Lars Knoll --- src/corelib/mimetypes/mimetypes.qrc | 2 +- src/tools/rcc/rcc.cpp | 11 +++++++++++ src/tools/rcc/rcc.h | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/corelib/mimetypes/mimetypes.qrc b/src/corelib/mimetypes/mimetypes.qrc index 19bc1d3e2a..4720bd302a 100644 --- a/src/corelib/mimetypes/mimetypes.qrc +++ b/src/corelib/mimetypes/mimetypes.qrc @@ -1,5 +1,5 @@ - mime/packages/freedesktop.org.xml + mime/packages/freedesktop.org.xml diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp index dfa62cea1b..5cbc771994 100644 --- a/src/tools/rcc/rcc.cpp +++ b/src/tools/rcc/rcc.cpp @@ -258,6 +258,10 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset, // Check if compression is useful for this file if (data.size() != 0) { #if QT_CONFIG(zstd) + if (m_compressAlgo == RCCResourceLibrary::CompressionAlgorithm::Best) { + m_compressAlgo = RCCResourceLibrary::CompressionAlgorithm::Zstd; + m_compressLevel = 19; // not ZSTD_maxCLevel(), as 20+ are experimental + } if (m_compressAlgo == RCCResourceLibrary::CompressionAlgorithm::Zstd) { if (lib.m_zstdCCtx == nullptr) lib.m_zstdCCtx = ZSTD_createCCtx(); @@ -301,6 +305,10 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset, } #endif #ifndef QT_NO_COMPRESS + if (m_compressAlgo == RCCResourceLibrary::CompressionAlgorithm::Best) { + m_compressAlgo = RCCResourceLibrary::CompressionAlgorithm::Zlib; + m_compressLevel = 9; + } if (m_compressAlgo == RCCResourceLibrary::CompressionAlgorithm::Zlib) { QByteArray compressed = qCompress(reinterpret_cast(data.data()), data.size(), m_compressLevel); @@ -824,6 +832,8 @@ RCCResourceLibrary::ResourceDataFileMap RCCResourceLibrary::resourceDataFileMap( RCCResourceLibrary::CompressionAlgorithm RCCResourceLibrary::parseCompressionAlgorithm(QStringView value, QString *errorMsg) { + if (value == QLatin1String("best")) + return CompressionAlgorithm::Best; if (value == QLatin1String("zlib")) { #ifdef QT_NO_COMPRESS *errorMsg = QLatin1String("zlib support not compiled in"); @@ -850,6 +860,7 @@ int RCCResourceLibrary::parseCompressionLevel(CompressionAlgorithm algo, const Q if (ok) { switch (algo) { case CompressionAlgorithm::None: + case CompressionAlgorithm::Best: return 0; case CompressionAlgorithm::Zlib: if (c >= 1 && c <= 9) diff --git a/src/tools/rcc/rcc.h b/src/tools/rcc/rcc.h index fe8ed21fb3..7603a41cde 100644 --- a/src/tools/rcc/rcc.h +++ b/src/tools/rcc/rcc.h @@ -84,6 +84,7 @@ public: Zlib, Zstd, + Best = 99, None = -1 }; From f56ca2c4f6c802236414b78cb517481a82df00ce Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 19 Nov 2018 10:39:51 -0800 Subject: [PATCH 0587/1650] QResource: de-inline registerSelf for files No other changes, aside from the coding style update to make sure the coding style bot won't complain. Change-Id: Iae320a2868db402a993dfffd15689a8a6ac202e8 Reviewed-by: Lars Knoll Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qresource.cpp | 114 ++++++++++++++++++----------------- 1 file changed, 58 insertions(+), 56 deletions(-) diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index 0d3aa563c8..4638de6520 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -1050,74 +1050,76 @@ public: QString mappingFile() const { return fileName; } ResourceRootType type() const override { return Resource_File; } - bool registerSelf(const QString &f) { - bool fromMM = false; - uchar *data = 0; - unsigned int data_len = 0; - -#ifdef QT_USE_MMAP + bool registerSelf(const QString &f); +}; #ifndef MAP_FILE -#define MAP_FILE 0 +# define MAP_FILE 0 #endif #ifndef MAP_FAILED -#define MAP_FAILED -1 +# define MAP_FAILED -1 #endif - int fd = QT_OPEN(QFile::encodeName(f), O_RDONLY, +bool QDynamicFileResourceRoot::registerSelf(const QString &f) +{ + bool fromMM = false; + uchar *data = 0; + unsigned int data_len = 0; + +#ifdef QT_USE_MMAP + int fd = QT_OPEN(QFile::encodeName(f), O_RDONLY, #if defined(Q_OS_WIN) - _S_IREAD | _S_IWRITE + _S_IREAD | _S_IWRITE #else - 0666 + 0666 #endif - ); - if (fd >= 0) { - QT_STATBUF st; - if (!QT_FSTAT(fd, &st)) { - uchar *ptr; - ptr = reinterpret_cast( - mmap(0, st.st_size, // any address, whole file - PROT_READ, // read-only memory - MAP_FILE | MAP_PRIVATE, // swap-backed map from file - fd, 0)); // from offset 0 of fd - if (ptr && ptr != reinterpret_cast(MAP_FAILED)) { - data = ptr; - data_len = st.st_size; - fromMM = true; - } + ); + if (fd >= 0) { + QT_STATBUF st; + if (!QT_FSTAT(fd, &st)) { + uchar *ptr; + ptr = reinterpret_cast( + mmap(0, st.st_size, // any address, whole file + PROT_READ, // read-only memory + MAP_FILE | MAP_PRIVATE, // swap-backed map from file + fd, 0)); // from offset 0 of fd + if (ptr && ptr != reinterpret_cast(MAP_FAILED)) { + data = ptr; + data_len = st.st_size; + fromMM = true; } - ::close(fd); } -#endif // QT_USE_MMAP - if(!data) { - QFile file(f); - if (!file.exists()) - return false; - data_len = file.size(); - data = new uchar[data_len]; - - bool ok = false; - if (file.open(QIODevice::ReadOnly)) - ok = (data_len == (uint)file.read((char*)data, data_len)); - if (!ok) { - delete [] data; - data = 0; - data_len = 0; - return false; - } - fromMM = false; - } - if (data && QDynamicBufferResourceRoot::registerSelf(data, data_len)) { - if(fromMM) { - unmapPointer = data; - unmapLength = data_len; - } - fileName = f; - return true; - } - return false; + ::close(fd); } -}; +#endif // QT_USE_MMAP + if (!data) { + QFile file(f); + if (!file.exists()) + return false; + data_len = file.size(); + data = new uchar[data_len]; + + bool ok = false; + if (file.open(QIODevice::ReadOnly)) + ok = (data_len == (uint)file.read((char*)data, data_len)); + if (!ok) { + delete [] data; + data = 0; + data_len = 0; + return false; + } + fromMM = false; + } + if (data && QDynamicBufferResourceRoot::registerSelf(data, data_len)) { + if (fromMM) { + unmapPointer = data; + unmapLength = data_len; + } + fileName = f; + return true; + } + return false; +} static QString qt_resource_fixResourceRoot(QString r) { if(!r.isEmpty()) { From e56c79dc9d71e84cfb1affd407c512189a549063 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 2 Nov 2018 21:48:52 +0100 Subject: [PATCH 0588/1650] QTreeWidget: mark is/setFirstItemColumnSpanned() as deprecated Deprecate the QTreeWidget functions is/setFirstItemColumnSpanned() to stay in sync with the other deprecated functions (selected/expanded/hidden) so they can get removed in Qt6. Also add a small unit test for them. Change-Id: Ie1cb5d7163c2d56d653c21e841ccaf7d38569787 Reviewed-by: Samuel Gaist Reviewed-by: Richard Moe Gustavsen --- src/widgets/itemviews/qtreewidget.cpp | 39 +++++++++++++------ src/widgets/itemviews/qtreewidget.h | 14 +++---- .../itemviews/qtreewidget/tst_qtreewidget.cpp | 23 +++++++++++ 3 files changed, 56 insertions(+), 20 deletions(-) diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp index acd6ad6e41..ac117b1c07 100644 --- a/src/widgets/itemviews/qtreewidget.cpp +++ b/src/widgets/itemviews/qtreewidget.cpp @@ -1127,6 +1127,14 @@ bool QTreeWidgetItem::isExpanded() const \sa isFirstColumnSpanned() */ +void QTreeWidgetItem::setFirstColumnSpanned(bool span) +{ + const QTreeModel *model = treeModel(); + if (!model || this == model->headerItem) + return; // We can't set the header items to spanning + const QModelIndex index = model->index(this, 0); + view->setFirstColumnSpanned(index.row(), index.parent(), span); +} /*! \fn bool QTreeWidgetItem::isFirstColumnSpanned() const @@ -1136,6 +1144,14 @@ bool QTreeWidgetItem::isExpanded() const \sa setFirstColumnSpanned() */ +bool QTreeWidgetItem::isFirstColumnSpanned() const +{ + const QTreeModel *model = treeModel(); + if (!model || this == model->headerItem) + return false; + const QModelIndex index = model->index(this, 0); + return view->isFirstColumnSpanned(index.row(), index.parent()); +} /*! \fn QString QTreeWidgetItem::text(int column) const @@ -3230,7 +3246,6 @@ void QTreeWidget::setItemExpanded(const QTreeWidgetItem *item, bool expand) if (item && item->treeWidget() == this) const_cast(item)->setExpanded(expand); } -#endif /*! \since 4.3 @@ -3239,14 +3254,14 @@ void QTreeWidget::setItemExpanded(const QTreeWidgetItem *item, bool expand) otherwise returns \c false. \sa setFirstItemColumnSpanned() + + \obsolete + + This function is deprecated. Use \l{QTreeWidgetItem::isFirstColumnSpanned()} instead. */ bool QTreeWidget::isFirstItemColumnSpanned(const QTreeWidgetItem *item) const { - Q_D(const QTreeWidget); - if (item == d->treeModel()->headerItem) - return false; // We can't set the header items to spanning - const QModelIndex index = d->index(item); - return isFirstColumnSpanned(index.row(), index.parent()); + return ((item && item->treeWidget() == this) ? item->isFirstColumnSpanned() : false); } /*! @@ -3256,15 +3271,17 @@ bool QTreeWidget::isFirstItemColumnSpanned(const QTreeWidgetItem *item) const otherwise the item will show one section per column. \sa isFirstItemColumnSpanned() + + \obsolete + + This function is deprecated. Use \l{QTreeWidgetItem::setFirstColumnSpanned()} instead. */ void QTreeWidget::setFirstItemColumnSpanned(const QTreeWidgetItem *item, bool span) { - Q_D(QTreeWidget); - if (item == d->treeModel()->headerItem) - return; // We can't set header items to spanning - const QModelIndex index = d->index(item); - setFirstColumnSpanned(index.row(), index.parent(), span); + if (item && item->treeWidget() == this) + const_cast(item)->setFirstColumnSpanned(span); } +#endif /*! \since 4.3 diff --git a/src/widgets/itemviews/qtreewidget.h b/src/widgets/itemviews/qtreewidget.h index 145b61ff9d..bed77b336d 100644 --- a/src/widgets/itemviews/qtreewidget.h +++ b/src/widgets/itemviews/qtreewidget.h @@ -88,8 +88,8 @@ public: void setExpanded(bool expand); bool isExpanded() const; - inline void setFirstColumnSpanned(bool span); - inline bool isFirstColumnSpanned() const; + void setFirstColumnSpanned(bool span); + bool isFirstColumnSpanned() const; inline void setDisabled(bool disabled); inline bool isDisabled() const; @@ -335,10 +335,12 @@ public: bool isItemExpanded(const QTreeWidgetItem *item) const; QT_DEPRECATED_X ("Use QTreeWidgetItem::setExpanded() instead") void setItemExpanded(const QTreeWidgetItem *item, bool expand); -#endif + QT_DEPRECATED_X ("Use QTreeWidgetItem::isFirstColumnSpanned() instead") bool isFirstItemColumnSpanned(const QTreeWidgetItem *item) const; + QT_DEPRECATED_X ("Use QTreeWidgetItem::setFirstColumnSpanned() instead") void setFirstItemColumnSpanned(const QTreeWidgetItem *item, bool span); +#endif QTreeWidgetItem *itemAbove(const QTreeWidgetItem *item) const; QTreeWidgetItem *itemBelow(const QTreeWidgetItem *item) const; @@ -423,12 +425,6 @@ inline QTreeWidgetItem *QTreeWidget::itemAt(int ax, int ay) const inline void QTreeWidget::setHeaderLabel(const QString &alabel) { setHeaderLabels(QStringList(alabel)); } -inline void QTreeWidgetItem::setFirstColumnSpanned(bool aspan) -{ if (view) view->setFirstItemColumnSpanned(this, aspan); } - -inline bool QTreeWidgetItem::isFirstColumnSpanned() const -{ return (view ? view->isFirstItemColumnSpanned(this) : false); } - inline void QTreeWidgetItem::setDisabled(bool disabled) { setFlags(disabled ? (flags() & ~Qt::ItemIsEnabled) : flags() | Qt::ItemIsEnabled); } diff --git a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp index d15a472072..ccae4ad626 100644 --- a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp +++ b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp @@ -140,6 +140,7 @@ private slots: void expandAndCallapse(); void itemData(); void setDisabled(); + void setSpanned(); void removeSelectedItem(); void removeCurrentItem(); void removeCurrentItem_task186451(); @@ -2818,6 +2819,28 @@ void tst_QTreeWidget::setDisabled() QCOMPARE(takenChildren.items[1]->isDisabled(), false); } +void tst_QTreeWidget::setSpanned() +{ + QTreeWidget w; + QTreeWidgetItem *i1 = new QTreeWidgetItem(); + QScopedPointer i2(new QTreeWidgetItem()); + + QTreeWidgetItem *top = new QTreeWidgetItem(&w); + top->addChild(i1); + + top->setFirstColumnSpanned(true); + QCOMPARE(top->isFirstColumnSpanned(), true); + QCOMPARE(i1->isFirstColumnSpanned(), false); + QCOMPARE(i2->isFirstColumnSpanned(), false); + + top->setFirstColumnSpanned(false); + i1->setFirstColumnSpanned(true); + i2->setFirstColumnSpanned(true); + QCOMPARE(top->isFirstColumnSpanned(), false); + QCOMPARE(i1->isFirstColumnSpanned(), true); + QCOMPARE(i2->isFirstColumnSpanned(), false); +} + void tst_QTreeWidget::removeSelectedItem() { const QScopedPointer w(new QTreeWidget); From d99b3c451b31b935be914e6238fa631dba0aafc6 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Mon, 10 Dec 2018 08:33:14 +0100 Subject: [PATCH 0589/1650] ANGLE: Dynamically load D3D compiler from a list If the default compiler cannot be found, load it from a list of DLL names, including a non-versioned proxy DLL provided by Qt. On Desktop Windows, the default compiler can also be specified by an environment variable, QT_D3DCOMPILER_DLL. Change-Id: I590bb11e58339451d187860c449b0209c1ca0578 Reviewed-by: Dmitry Kazakov Reviewed-by: Andre de la Rocha Reviewed-by: Ville Voutilainen --- .../libANGLE/renderer/d3d/HLSLCompiler.cpp | 25 ++++++++ ...ically-load-D3D-compiler-from-a-list.patch | 59 +++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 src/angle/patches/0012-ANGLE-Dynamically-load-D3D-compiler-from-a-list.patch diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp index b38765070b..5d47308d67 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp @@ -14,6 +14,10 @@ #include "libANGLE/histogram_macros.h" #include "third_party/trace_event/trace_event.h" +#ifndef QT_D3DCOMPILER_DLL +#define QT_D3DCOMPILER_DLL D3DCOMPILER_DLL +#endif + #if ANGLE_APPEND_ASSEMBLY_TO_SHADER_DEBUG_INFO == ANGLE_ENABLED namespace { @@ -130,6 +134,27 @@ gl::Error HLSLCompiler::ensureInitialized() } #endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES + // Load the compiler DLL specified by the environment, or default to QT_D3DCOMPILER_DLL + const wchar_t *defaultCompiler = _wgetenv(L"QT_D3DCOMPILER_DLL"); + if (!defaultCompiler) + defaultCompiler = QT_D3DCOMPILER_DLL; + + const wchar_t *compilerDlls[] = { + defaultCompiler, + L"d3dcompiler_47.dll", + L"d3dcompiler_46.dll", + L"d3dcompiler_43.dll", + 0 + }; + + // Load the first available known compiler DLL + for (int i = 0; compilerDlls[i]; ++i) + { + mD3DCompilerModule = LoadLibrary(compilerDlls[i]); + if (mD3DCompilerModule) + break; + } + if (!mD3DCompilerModule) { // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with. diff --git a/src/angle/patches/0012-ANGLE-Dynamically-load-D3D-compiler-from-a-list.patch b/src/angle/patches/0012-ANGLE-Dynamically-load-D3D-compiler-from-a-list.patch new file mode 100644 index 0000000000..7009dec1ba --- /dev/null +++ b/src/angle/patches/0012-ANGLE-Dynamically-load-D3D-compiler-from-a-list.patch @@ -0,0 +1,59 @@ +From dff9676c60c51fa7af0749e1cb54305f112183e3 Mon Sep 17 00:00:00 2001 +From: Oliver Wolff +Date: Mon, 10 Dec 2018 08:33:14 +0100 +Subject: [PATCH] ANGLE: Dynamically load D3D compiler from a list + +If the default compiler cannot be found, load it from a list of DLL names, +including a non-versioned proxy DLL provided by Qt. On Desktop Windows, +the default compiler can also be specified by an environment variable, +QT_D3DCOMPILER_DLL. +--- + src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp +index b38765070..5d47308d6 100644 +--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp ++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/HLSLCompiler.cpp +@@ -14,6 +14,10 @@ + #include "libANGLE/histogram_macros.h" + #include "third_party/trace_event/trace_event.h" + ++#ifndef QT_D3DCOMPILER_DLL ++#define QT_D3DCOMPILER_DLL D3DCOMPILER_DLL ++#endif ++ + #if ANGLE_APPEND_ASSEMBLY_TO_SHADER_DEBUG_INFO == ANGLE_ENABLED + namespace + { +@@ -130,6 +134,27 @@ gl::Error HLSLCompiler::ensureInitialized() + } + #endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES + ++ // Load the compiler DLL specified by the environment, or default to QT_D3DCOMPILER_DLL ++ const wchar_t *defaultCompiler = _wgetenv(L"QT_D3DCOMPILER_DLL"); ++ if (!defaultCompiler) ++ defaultCompiler = QT_D3DCOMPILER_DLL; ++ ++ const wchar_t *compilerDlls[] = { ++ defaultCompiler, ++ L"d3dcompiler_47.dll", ++ L"d3dcompiler_46.dll", ++ L"d3dcompiler_43.dll", ++ 0 ++ }; ++ ++ // Load the first available known compiler DLL ++ for (int i = 0; compilerDlls[i]; ++i) ++ { ++ mD3DCompilerModule = LoadLibrary(compilerDlls[i]); ++ if (mD3DCompilerModule) ++ break; ++ } ++ + if (!mD3DCompilerModule) + { + // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with. +-- +2.15.0.windows.1 + From 9400a120ead81b0fa63d968b8d9ac9bde8addc43 Mon Sep 17 00:00:00 2001 From: Paul Wicking Date: Tue, 11 Dec 2018 13:17:07 +0100 Subject: [PATCH 0590/1650] Doc: Fix typo in snippet Resolves "reference to non-static member function must be called" error. Fixes: QTBUG-72403 Change-Id: Iebd865ff553736df43548b72b45ed3f4711fffc1 Reviewed-by: Jesus Fernandez --- src/gui/doc/snippets/code/src_gui_vulkan_qvulkaninstance.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/doc/snippets/code/src_gui_vulkan_qvulkaninstance.cpp b/src/gui/doc/snippets/code/src_gui_vulkan_qvulkaninstance.cpp index 50afe7c0ff..c4dd9fea18 100644 --- a/src/gui/doc/snippets/code/src_gui_vulkan_qvulkaninstance.cpp +++ b/src/gui/doc/snippets/code/src_gui_vulkan_qvulkaninstance.cpp @@ -102,7 +102,7 @@ } bool event(QEvent *e) { - if (e->type == QEvent::UpdateRequest) + if (e->type() == QEvent::UpdateRequest) render(); return QWindow::event(e); } From 9ee29b826c20bf554563a7495ec2ab8ef636032a Mon Sep 17 00:00:00 2001 From: Alberto Mardegan Date: Sat, 8 Dec 2018 09:13:32 +0300 Subject: [PATCH 0591/1650] QCommonStyle: fetch `flat` property from style option The same information is available both from the QGroupBox API and from the QStyleOption; we should prefer the latter, because this makes it easier to use QStyle from QQuick.Controls (where a QGroupBox is not instantiated). Change-Id: I05ed1e3406676bde5d124d395d43caa0961c4f2d Reviewed-by: Richard Moe Gustavsen --- src/widgets/styles/qcommonstyle.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 9aec4f3aa4..fc48a8ca26 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -4921,8 +4921,8 @@ QSize QCommonStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, break; #if QT_CONFIG(groupbox) case CT_GroupBox: - if (const QGroupBox *grb = static_cast(widget)) - sz += QSize(!grb->isFlat() ? 16 : 0, 0); + if (const QStyleOptionGroupBox *styleOpt = qstyleoption_cast(opt)) + sz += QSize(styleOpt->features.testFlag(QStyleOptionFrame::Flat) ? 0 : 16, 0); break; #endif // QT_CONFIG(groupbox) case CT_MdiControls: From 76f11b0eda50f05fb0912738be41b4333a82f748 Mon Sep 17 00:00:00 2001 From: Ville Voutilainen Date: Mon, 10 Dec 2018 16:21:07 +0200 Subject: [PATCH 0592/1650] Silence GCC 9 warnings Change-Id: I5654881a3adac6f67a38837321c8e1c3ce1e2d8f Reviewed-by: Thiago Macieira --- mkspecs/features/qt_common.prf | 17 ++++++++++++++++- mkspecs/features/qt_module_headers.prf | 8 ++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/mkspecs/features/qt_common.prf b/mkspecs/features/qt_common.prf index 4ad9946ae0..e67b79acc3 100644 --- a/mkspecs/features/qt_common.prf +++ b/mkspecs/features/qt_common.prf @@ -89,6 +89,14 @@ clang { greaterThan(QT_GCC_MAJOR_VERSION, 5): QMAKE_CXXFLAGS_WARN_ON += -Wshift-overflow=2 -Wduplicated-cond # GCC 7 has a lot of false positives relating to this, so disable completely greaterThan(QT_GCC_MAJOR_VERSION, 6): QMAKE_CXXFLAGS_WARN_ON += -Wno-stringop-overflow + # GCC 9 has a lot of false positives relating to this, so disable completely + greaterThan(QT_GCC_MAJOR_VERSION, 8): QMAKE_CXXFLAGS_WARN_ON += -Wno-deprecated-copy + # GCC 9 introduced this + greaterThan(QT_GCC_MAJOR_VERSION, 8): QMAKE_CXXFLAGS_WARN_ON += -Wno-redundant-move + # GCC 9 introduced this + greaterThan(QT_GCC_MAJOR_VERSION, 8): QMAKE_CXXFLAGS_WARN_ON += -Wno-format-overflow + # GCC 9 introduced this + greaterThan(QT_GCC_MAJOR_VERSION, 8): QMAKE_CXXFLAGS_WARN_ON += -Wno-init-list-lifetime } warnings_are_errors:warning_clean { @@ -127,7 +135,14 @@ warnings_are_errors:warning_clean { # GCC 7 includes -Wimplicit-fallthrough in -Wextra, but Qt is not yet free of implicit fallthroughs. greaterThan(QT_GCC_MAJOR_VERSION, 6): QMAKE_CXXFLAGS_WARN_ON += -Wno-error=implicit-fallthrough - + # GCC 9 has a lot of false positives relating to this, so disable completely + greaterThan(QT_GCC_MAJOR_VERSION, 8): QMAKE_CXXFLAGS_WARN_ON += -Wno-deprecated-copy + # GCC 9 introduced this + greaterThan(QT_GCC_MAJOR_VERSION, 8): QMAKE_CXXFLAGS_WARN_ON += -Wno-redundant-move + # GCC 9 introduced this + greaterThan(QT_GCC_MAJOR_VERSION, 8): QMAKE_CXXFLAGS_WARN_ON += -Wno-format-overflow + # GCC 9 introduced this + greaterThan(QT_GCC_MAJOR_VERSION, 8): QMAKE_CXXFLAGS_WARN_ON += -Wno-init-list-lifetime # Work-around for bug https://code.google.com/p/android/issues/detail?id=58135 android: QMAKE_CXXFLAGS_WARN_ON += -Wno-error=literal-suffix } diff --git a/mkspecs/features/qt_module_headers.prf b/mkspecs/features/qt_module_headers.prf index 70d3520e5c..6b4b9143fa 100644 --- a/mkspecs/features/qt_module_headers.prf +++ b/mkspecs/features/qt_module_headers.prf @@ -239,6 +239,14 @@ headersclean:!internal_module { gcc_ver = $${QT_GCC_MAJOR_VERSION}.$${QT_GCC_MINOR_VERSION} versionAtLeast(gcc_ver, 4.5): hcleanFLAGS += -Wdouble-promotion versionAtLeast(gcc_ver, 4.9): hcleanFLAGS += -Wfloat-conversion + # GCC 9 has a lot of false positives relating to this, so disable completely + greaterThan(QT_GCC_MAJOR_VERSION, 8): hcleanFLAGS += -Wno-deprecated-copy + # GCC 9 introduced this + greaterThan(QT_GCC_MAJOR_VERSION, 8): hcleanFLAGS += -Wno-redundant-move + # GCC 9 introduced this + greaterThan(QT_GCC_MAJOR_VERSION, 8): hcleanFLAGS += -Wno-format-overflow + # GCC 9 introduced this + greaterThan(QT_GCC_MAJOR_VERSION, 8): hcleanFLAGS += -Wno-init-list-lifetime c++11 { # only enabled for actual c++11 builds due to From 9fbce8d5cbcc9d8d255328d6ec040db0510ca289 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 10 Dec 2018 11:06:26 +0100 Subject: [PATCH 0593/1650] Avoid crash in blitting or fast draw when QPointF is too big Change-Id: I88182d5d95fda15d33836f16dee78167685b3765 Fixes: QTBUG-72392 Reviewed-by: Friedemann Kleint Reviewed-by: Tim Jenssen --- src/gui/painting/qpaintengine_raster.cpp | 8 ++++++++ .../auto/gui/painting/qpainter/tst_qpainter.cpp | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 7caaf3a8fa..90b6d16551 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -997,6 +997,10 @@ void QRasterPaintEnginePrivate::drawImage(const QPointF &pt, { if (alpha == 0 || !clip.isValid()) return; + if (pt.x() > qreal(clip.right()) || pt.y() > qreal(clip.bottom())) + return; + if ((pt.x() + img.width()) < qreal(clip.left()) || (pt.y() + img.height()) < qreal(clip.top())) + return; Q_ASSERT(img.depth() >= 8); @@ -1063,6 +1067,10 @@ void QRasterPaintEnginePrivate::blitImage(const QPointF &pt, { if (!clip.isValid()) return; + if (pt.x() > qreal(clip.right()) || pt.y() > qreal(clip.bottom())) + return; + if ((pt.x() + img.width()) < qreal(clip.left()) || (pt.y() + img.height()) < qreal(clip.top())) + return; Q_ASSERT(img.depth() >= 8); diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp index 9bf9e99bf9..bc0baed15c 100644 --- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp +++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp @@ -299,6 +299,8 @@ private slots: void fillPolygon(); + void drawImageAtPointF(); + private: void fillData(); void setPenColor(QPainter& p); @@ -5292,6 +5294,20 @@ void tst_QPainter::fillPolygon() } } +void tst_QPainter::drawImageAtPointF() +{ + // Just test we do not crash + QImage image1(10, 10, QImage::Format_RGB32); + QImage image2(200, 200, QImage::Format_RGB32); + + QPainter paint(&image2); + paint.setClipRect(97, 46, 14, 14); + paint.setCompositionMode(QPainter::CompositionMode_Source); + paint.drawImage(QPointF(96, std::numeric_limits::max()), image1); + paint.drawImage(QPointF(std::numeric_limits::min(), 48), image1); + paint.end(); +} + QTEST_MAIN(tst_QPainter) #include "tst_qpainter.moc" From 6b52c1834daec628bab5a384e1dfd039937b375d Mon Sep 17 00:00:00 2001 From: "R.J.V. Bertin" Date: Wed, 5 Dec 2018 18:47:47 +0100 Subject: [PATCH 0594/1650] Offscreen QPA: use a CoreText font database on macOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without this applications using the Offscreen QPA don't have access to any fonts on macOS and thus cannot render text correctly. Task-number: QTBUG-72335 Change-Id: I8e58c066365d0231d0993ad3b480d957a32f7f7b Reviewed-by: Tor Arne Vestbø Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Friedemann Kleint --- src/plugins/platforms/offscreen/qoffscreenintegration.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp index 01cd254501..9815be16a3 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp +++ b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp @@ -45,6 +45,7 @@ #include #if defined(Q_OS_MAC) #include +#include #else #include #endif @@ -67,6 +68,8 @@ QT_BEGIN_NAMESPACE +class QCoreTextFontEngine; + template class QOffscreenEventDispatcher : public BaseEventDispatcher { @@ -101,7 +104,7 @@ QOffscreenIntegration::QOffscreenIntegration() { #if defined(Q_OS_UNIX) #if defined(Q_OS_MAC) - m_fontDatabase.reset(new QPlatformFontDatabase()); + m_fontDatabase.reset(new QCoreTextFontDatabaseEngineFactory); #else m_fontDatabase.reset(new QGenericUnixFontDatabase()); #endif From 63b0eb3a89049f3a9166a29e8c8275d77323ec52 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 3 Dec 2018 13:18:35 +0100 Subject: [PATCH 0595/1650] Include CLDR 34 update in change log Change-Id: I88ab9d48eaa0486cbd930166de601973be2e8e0f Reviewed-by: Thiago Macieira --- dist/changes-5.12.0 | 1 + 1 file changed, 1 insertion(+) diff --git a/dist/changes-5.12.0 b/dist/changes-5.12.0 index b5e664fc5a..15b12b60ab 100644 --- a/dist/changes-5.12.0 +++ b/dist/changes-5.12.0 @@ -48,6 +48,7 @@ information about a particular change. - The minimal required version of libxcb is now 1.9. Bundled xcb sources were updated to libxcb 1.9.1 built with xcb-proto 1.8. - [QTBUG-67654] Updated CLDR to version 33.1 + - [QTBUG-71144] Updated CLDR to version 34 - [QTBUG-66561][QTBUG-70008] double-conversion got updated to upstream version 3.1.1. - libjpeg-turbo was updated to version 2.0.0 From 12e843581adf156d30dd09579b53fa36a361c4c9 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 8 Nov 2018 12:26:46 -0800 Subject: [PATCH 0596/1650] QResource: quick refactor of registerSelf for files to support LFS This commit adds sufficient support for large files in resources, but not completely because the rest Qt is not ready for it (and not tested). We've had the QT_MMAP macro in qplatformdefs.h for a while, so let's use it and use qsizetype where we can. This also the check that the file existed before opening it (you can only open it if it exists), plus a few nullptr updates. Change-Id: I42a48bd64ccc41aebf84fffd15653ffdabb0e66b Reviewed-by: Lars Knoll --- src/corelib/io/qresource.cpp | 67 +++++++++++++++--------------------- 1 file changed, 28 insertions(+), 39 deletions(-) diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index 4638de6520..52a20191a9 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -68,6 +68,11 @@ # include "private/qcore_unix_p.h" #endif +#if defined(Q_OS_UNIX) && !defined(Q_OS_NACL) && !defined(Q_OS_INTEGRITY) +# define QT_USE_MMAP +# include +#endif + //#define DEBUG_RESOURCE_MATCH QT_BEGIN_NAMESPACE @@ -969,7 +974,7 @@ public: ResourceRootType type() const override { return Resource_Buffer; } // size == -1 means "unknown" - bool registerSelf(const uchar *b, int size) + bool registerSelf(const uchar *b, qsizetype size) { // 5 int "pointers" if (size >= 0 && size < 20) @@ -1010,28 +1015,12 @@ public: } }; -#if defined(Q_OS_UNIX) && !defined (Q_OS_NACL) && !defined(Q_OS_INTEGRITY) -#define QT_USE_MMAP -#endif - -// most of the headers below are already included in qplatformdefs.h -// also this lacks Large File support but that's probably irrelevant -#if defined(QT_USE_MMAP) -// for mmap -QT_BEGIN_INCLUDE_NAMESPACE -#include -#include -QT_END_INCLUDE_NAMESPACE -#endif - - - class QDynamicFileResourceRoot: public QDynamicBufferResourceRoot { QString fileName; // for mmap'ed files, this is what needs to be unmapped. uchar *unmapPointer; - unsigned int unmapLength; + qsizetype unmapLength; public: inline QDynamicFileResourceRoot(const QString &_root) : QDynamicBufferResourceRoot(_root), unmapPointer(0), unmapLength(0) { } @@ -1057,14 +1046,14 @@ public: # define MAP_FILE 0 #endif #ifndef MAP_FAILED -# define MAP_FAILED -1 +# define MAP_FAILED reinterpret_cast(-1) #endif bool QDynamicFileResourceRoot::registerSelf(const QString &f) { bool fromMM = false; - uchar *data = 0; - unsigned int data_len = 0; + uchar *data = nullptr; + qsizetype data_len = 0; #ifdef QT_USE_MMAP int fd = QT_OPEN(QFile::encodeName(f), O_RDONLY, @@ -1076,35 +1065,35 @@ bool QDynamicFileResourceRoot::registerSelf(const QString &f) ); if (fd >= 0) { QT_STATBUF st; - if (!QT_FSTAT(fd, &st)) { - uchar *ptr; - ptr = reinterpret_cast( - mmap(0, st.st_size, // any address, whole file - PROT_READ, // read-only memory - MAP_FILE | MAP_PRIVATE, // swap-backed map from file - fd, 0)); // from offset 0 of fd - if (ptr && ptr != reinterpret_cast(MAP_FAILED)) { - data = ptr; + if (!QT_FSTAT(fd, &st) && st.st_size <= std::numeric_limits::max()) { + int protection = PROT_READ; // read-only memory + int flags = MAP_FILE | MAP_PRIVATE; // swap-backed map from file + void *ptr = QT_MMAP(nullptr, st.st_size, // any address, whole file + protection, flags, + fd, 0); // from offset 0 of fd + if (ptr != MAP_FAILED) { + data = static_cast(ptr); data_len = st.st_size; fromMM = true; } } - ::close(fd); + QT_CLOSE(fd); } #endif // QT_USE_MMAP if (!data) { QFile file(f); - if (!file.exists()) - return false; - data_len = file.size(); - data = new uchar[data_len]; - bool ok = false; - if (file.open(QIODevice::ReadOnly)) - ok = (data_len == (uint)file.read((char*)data, data_len)); + if (file.open(QIODevice::ReadOnly)) { + qint64 fsize = file.size(); + if (fsize <= std::numeric_limits::max()) { + data_len = file.size(); + data = new uchar[data_len]; + ok = (data_len == file.read((char*)data, data_len)); + } + } if (!ok) { delete [] data; - data = 0; + data = nullptr; data_len = 0; return false; } From a440aada72f2ee78c5e27d70ecc79c0071673446 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 2 Nov 2018 15:35:43 -0700 Subject: [PATCH 0597/1650] Add SSE2 qt_memfill64 Implemented by merging with the qt_memfill32 implementation in a non-inlining function. Change-Id: I343f2beed55440a7ac0bfffd15636f8ba995a2bd Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qdrawhelper.cpp | 2 + src/gui/painting/qdrawhelper_p.h | 7 +++ src/gui/painting/qdrawhelper_sse2.cpp | 80 +++++++++++++++++++-------- src/gui/painting/qdrawhelper_x86_p.h | 1 + 4 files changed, 67 insertions(+), 23 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 783d2e40b0..d97ace7480 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -6260,10 +6260,12 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = }, }; +#if !defined(__SSE2__) void qt_memfill64(quint64 *dest, quint64 color, qsizetype count) { qt_memfill_template(dest, color, count); } +#endif void qt_memfill16(quint16 *dest, quint16 value, qsizetype count) { diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index e9a1e48e5f..8a26d884a5 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -70,10 +70,17 @@ QT_BEGIN_NAMESPACE #if defined(Q_CC_GNU) # define Q_DECL_RESTRICT __restrict__ +# if defined(Q_PROCESSOR_X86_32) && defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && !defined(Q_CC_INTEL) +# define Q_DECL_VECTORCALL __attribute__((sseregparm,regparm(3))) +# else +# define Q_DECL_VECTORCALL +# endif #elif defined(Q_CC_MSVC) # define Q_DECL_RESTRICT __restrict +# define Q_DECL_VECTORCALL __vectorcall #else # define Q_DECL_RESTRICT +# define Q_DECL_VECTORCALL #endif static const uint AMASK = 0xff000000; diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index 34bdf7909a..bf2e90f6af 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -233,19 +233,70 @@ void QT_FASTCALL comp_func_Source_sse2(uint *dst, const uint *src, int length, u } } +static Q_NEVER_INLINE +void Q_DECL_VECTORCALL qt_memfillXX_aligned(void *dest, __m128i value128, quintptr bytecount) +{ + __m128i *dst128 = reinterpret_cast<__m128i *>(dest); + __m128i *end128 = reinterpret_cast<__m128i *>(static_cast(dest) + bytecount); + + while (dst128 + 4 <= end128) { + _mm_store_si128(dst128 + 0, value128); + _mm_store_si128(dst128 + 1, value128); + _mm_store_si128(dst128 + 2, value128); + _mm_store_si128(dst128 + 3, value128); + dst128 += 4; + } + + bytecount %= 4 * sizeof(__m128i); + switch (bytecount / sizeof(__m128i)) { + case 3: _mm_store_si128(dst128++, value128); Q_FALLTHROUGH(); + case 2: _mm_store_si128(dst128++, value128); Q_FALLTHROUGH(); + case 1: _mm_store_si128(dst128++, value128); + } +} + +void qt_memfill64(quint64 *dest, quint64 value, qsizetype count) +{ + quintptr misaligned = quintptr(dest) % sizeof(__m128i); + if (misaligned && count) { +#if defined(Q_PROCESSOR_X86_32) + // Before SSE came out, the alignment of the stack used to be only 4 + // bytes and some OS/ABIs (notably, code generated by MSVC) still only + // align to that. In any case, we cannot count on the alignment of + // quint64 to be 8 -- see QtPrivate::AlignOf_WorkaroundForI386Abi in + // qglobal.h. + // + // If the pointer is not aligned to at least 8 bytes, then we'll never + // in turn hit a multiple of 16 for the qt_memfillXX_aligned call + // below. + if (Q_UNLIKELY(misaligned % sizeof(quint64))) + return qt_memfill_template(dest, value, count); +#endif + + *dest++ = value; + --count; + } + + if (count % 2) { + dest[count - 1] = value; + --count; + } + + qt_memfillXX_aligned(dest, _mm_set1_epi64x(value), count * sizeof(quint64)); +} + void qt_memfill32(quint32 *dest, quint32 value, qsizetype count) { - if (count < 7) { + if (count < 4) { + // this simplifies the code below: the first switch can fall through + // without checking the value of count switch (count) { - case 6: *dest++ = value; Q_FALLTHROUGH(); - case 5: *dest++ = value; Q_FALLTHROUGH(); - case 4: *dest++ = value; Q_FALLTHROUGH(); case 3: *dest++ = value; Q_FALLTHROUGH(); case 2: *dest++ = value; Q_FALLTHROUGH(); case 1: *dest = value; } return; - }; + } const int align = (quintptr)(dest) & 0xf; switch (align) { @@ -263,24 +314,7 @@ void qt_memfill32(quint32 *dest, quint32 value, qsizetype count) } } - int count128 = count / 4; - __m128i *dst128 = reinterpret_cast<__m128i*>(dest); - __m128i *end128 = dst128 + count128; - const __m128i value128 = _mm_set1_epi32(value); - - while (dst128 + 3 < end128) { - _mm_store_si128(dst128 + 0, value128); - _mm_store_si128(dst128 + 1, value128); - _mm_store_si128(dst128 + 2, value128); - _mm_store_si128(dst128 + 3, value128); - dst128 += 4; - } - - switch (count128 & 0x3) { - case 3: _mm_store_si128(dst128++, value128); Q_FALLTHROUGH(); - case 2: _mm_store_si128(dst128++, value128); Q_FALLTHROUGH(); - case 1: _mm_store_si128(dst128++, value128); - } + qt_memfillXX_aligned(dest, _mm_set1_epi32(value), count * sizeof(quint32)); } void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, uint color, uint const_alpha) diff --git a/src/gui/painting/qdrawhelper_x86_p.h b/src/gui/painting/qdrawhelper_x86_p.h index 12b95abe46..6f97242199 100644 --- a/src/gui/painting/qdrawhelper_x86_p.h +++ b/src/gui/painting/qdrawhelper_x86_p.h @@ -57,6 +57,7 @@ QT_BEGIN_NAMESPACE #ifdef __SSE2__ +void qt_memfill64(quint64 *dest, quint64 value, qsizetype count); void qt_memfill32(quint32 *dest, quint32 value, qsizetype count); void qt_bitmapblit32_sse2(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 &color, From 40894d1a60d357bc46364ae038ede0159f32261b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 2 Nov 2018 19:38:29 -0700 Subject: [PATCH 0598/1650] Add AVX2 versions of qt_memfill32 and qt_memfill64 The implementation is almost the same 4-way-unrolled loop, but because of the wider registers, we fill 128 bytes per loop. Unlike the SSE2 implementation, the AVX2 version uses unaligned stores and won't try to align in the prologue, matching glibc's __memset_avx2 (also unaligned). Change-Id: Iba4b5c183776497d8ee1fffd15637ccb2a7b83bc Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qdrawhelper.cpp | 10 +++++ src/gui/painting/qdrawhelper_avx2.cpp | 53 ++++++++++++++++++++++++++- src/gui/painting/qdrawhelper_p.h | 5 +++ src/gui/painting/qdrawhelper_sse2.cpp | 6 ++- src/gui/painting/qdrawhelper_x86_p.h | 7 +++- 5 files changed, 76 insertions(+), 5 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index d97ace7480..59b46b84ef 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -6288,6 +6288,10 @@ void qt_memfill32(quint32 *dest, quint32 color, qsizetype count) qt_memfill_template(dest, color, count); } #endif +#ifdef __SSE2__ +decltype(qt_memfill32_sse2) *qt_memfill32 = nullptr; +decltype(qt_memfill64_sse2) *qt_memfill64 = nullptr; +#endif #ifdef QT_COMPILER_SUPPORTS_SSE4_1 template void QT_FASTCALL storeA2RGB30PMFromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count, const QVector *, QDitherInfo *); @@ -6301,6 +6305,10 @@ static void qInitDrawhelperFunctions() qInitBlendFunctions(); #ifdef __SSE2__ +# ifndef __AVX2__ + qt_memfill32 = qt_memfill32_sse2; + qt_memfill64 = qt_memfill64_sse2; +# endif qDrawHelper[QImage::Format_RGB32].bitmapBlit = qt_bitmapblit32_sse2; qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_sse2; qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2; @@ -6407,6 +6415,8 @@ static void qInitDrawhelperFunctions() #if defined(QT_COMPILER_SUPPORTS_AVX2) if (qCpuHasFeature(ArchHaswell)) { + qt_memfill32 = qt_memfill32_avx2; + qt_memfill64 = qt_memfill64_avx2; extern void qt_blend_rgb32_on_rgb32_avx2(uchar *destPixels, int dbpl, const uchar *srcPixels, int sbpl, int w, int h, int const_alpha); diff --git a/src/gui/painting/qdrawhelper_avx2.cpp b/src/gui/painting/qdrawhelper_avx2.cpp index ec6643deed..adf11999bc 100644 --- a/src/gui/painting/qdrawhelper_avx2.cpp +++ b/src/gui/painting/qdrawhelper_avx2.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2018 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -38,6 +39,7 @@ ****************************************************************************/ #include "qdrawhelper_p.h" +#include "qdrawhelper_x86_p.h" #include "qdrawingprimitive_sse2_p.h" #include "qrgba64_p.h" @@ -316,6 +318,55 @@ void qt_blend_rgb32_on_rgb32_avx2(uchar *destPixels, int dbpl, } } +static Q_NEVER_INLINE +void Q_DECL_VECTORCALL qt_memfillXX_avx2(uchar *dest, __m256i value256, qsizetype bytes) +{ + __m128i value128 = _mm256_castsi256_si128(value256); + + // main body + __m256i *dst256 = reinterpret_cast<__m256i *>(dest); + uchar *end = dest + bytes; + while (reinterpret_cast(dst256 + 4) <= end) { + _mm256_storeu_si256(dst256 + 0, value256); + _mm256_storeu_si256(dst256 + 1, value256); + _mm256_storeu_si256(dst256 + 2, value256); + _mm256_storeu_si256(dst256 + 3, value256); + dst256 += 4; + } + + // first epilogue: fewer than 128 bytes / 32 entries + bytes = end - reinterpret_cast(dst256); + switch (bytes / sizeof(value256)) { + case 3: _mm256_storeu_si256(dst256++, value256); Q_FALLTHROUGH(); + case 2: _mm256_storeu_si256(dst256++, value256); Q_FALLTHROUGH(); + case 1: _mm256_storeu_si256(dst256++, value256); + } + + // second epilogue: fewer than 32 bytes + __m128i *dst128 = reinterpret_cast<__m128i *>(dst256); + if (bytes & sizeof(value128)) + _mm_storeu_si128(dst128++, value128); + + // third epilogue: fewer than 16 bytes + if (bytes & 8) + _mm_storel_epi64(reinterpret_cast<__m128i *>(end - 8), value128); +} + +void qt_memfill64_avx2(quint64 *dest, quint64 value, qsizetype count) +{ + qt_memfillXX_avx2(reinterpret_cast(dest), _mm256_set1_epi64x(value), count * sizeof(quint64)); +} + +void qt_memfill32_avx2(quint32 *dest, quint32 value, qsizetype count) +{ + if (count % 2) { + // odd number of pixels, round to even + *dest++ = value; + --count; + } + qt_memfillXX_avx2(reinterpret_cast(dest), _mm256_set1_epi32(value), count * sizeof(quint32)); +} + void QT_FASTCALL comp_func_SourceOver_avx2(uint *destPixels, const uint *srcPixels, int length, uint const_alpha) { Q_ASSERT(const_alpha < 256); diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 8a26d884a5..219734c430 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -167,8 +167,13 @@ extern DrawHelper qDrawHelper[QImage::NImageFormats]; void qBlendGradient(int count, const QSpan *spans, void *userData); void qBlendTexture(int count, const QSpan *spans, void *userData); +#ifdef __SSE2__ +extern void (*qt_memfill64)(quint64 *dest, quint64 value, qsizetype count); +extern void (*qt_memfill32)(quint32 *dest, quint32 value, qsizetype count); +#else extern void qt_memfill64(quint64 *dest, quint64 value, qsizetype count); extern void qt_memfill32(quint32 *dest, quint32 value, qsizetype count); +#endif extern void qt_memfill16(quint16 *dest, quint16 value, qsizetype count); typedef void (QT_FASTCALL *CompositionFunction)(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha); diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index bf2e90f6af..0ac9508264 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -233,6 +233,7 @@ void QT_FASTCALL comp_func_Source_sse2(uint *dst, const uint *src, int length, u } } +#ifndef __AVX2__ static Q_NEVER_INLINE void Q_DECL_VECTORCALL qt_memfillXX_aligned(void *dest, __m128i value128, quintptr bytecount) { @@ -255,7 +256,7 @@ void Q_DECL_VECTORCALL qt_memfillXX_aligned(void *dest, __m128i value128, quintp } } -void qt_memfill64(quint64 *dest, quint64 value, qsizetype count) +void qt_memfill64_sse2(quint64 *dest, quint64 value, qsizetype count) { quintptr misaligned = quintptr(dest) % sizeof(__m128i); if (misaligned && count) { @@ -285,7 +286,7 @@ void qt_memfill64(quint64 *dest, quint64 value, qsizetype count) qt_memfillXX_aligned(dest, _mm_set1_epi64x(value), count * sizeof(quint64)); } -void qt_memfill32(quint32 *dest, quint32 value, qsizetype count) +void qt_memfill32_sse2(quint32 *dest, quint32 value, qsizetype count) { if (count < 4) { // this simplifies the code below: the first switch can fall through @@ -316,6 +317,7 @@ void qt_memfill32(quint32 *dest, quint32 value, qsizetype count) qt_memfillXX_aligned(dest, _mm_set1_epi32(value), count * sizeof(quint32)); } +#endif // !__AVX2__ void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, uint color, uint const_alpha) { diff --git a/src/gui/painting/qdrawhelper_x86_p.h b/src/gui/painting/qdrawhelper_x86_p.h index 6f97242199..5749d8c9fb 100644 --- a/src/gui/painting/qdrawhelper_x86_p.h +++ b/src/gui/painting/qdrawhelper_x86_p.h @@ -57,8 +57,8 @@ QT_BEGIN_NAMESPACE #ifdef __SSE2__ -void qt_memfill64(quint64 *dest, quint64 value, qsizetype count); -void qt_memfill32(quint32 *dest, quint32 value, qsizetype count); +void qt_memfill64_sse2(quint64 *dest, quint64 value, qsizetype count); +void qt_memfill32_sse2(quint32 *dest, quint32 value, qsizetype count); void qt_bitmapblit32_sse2(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 &color, const uchar *src, int width, int height, int stride); @@ -79,6 +79,9 @@ void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl, extern CompositionFunction qt_functionForMode_SSE2[]; extern CompositionFunctionSolid qt_functionForModeSolid_SSE2[]; + +void qt_memfill64_avx2(quint64 *dest, quint64 value, qsizetype count); +void qt_memfill32_avx2(quint32 *dest, quint32 value, qsizetype count); #endif // __SSE2__ static const int numCompositionFunctions = 38; From 986e49992c88d9f324012551b5ad0eee4203ee34 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 6 Nov 2018 21:16:52 -0800 Subject: [PATCH 0599/1650] Use Q_DECL_VECTORCALL in a few more places There were a few functions that passed vectors in parameters but did not mark as vectorcall. I've taken the opportunity to de-macroify one macro, but I'm not going to do it for the rest. Change-Id: I42a48bd64ccc41aebf84fffd1564bfc21faa2a14 Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qdrawhelper_avx2.cpp | 17 ++-- src/gui/painting/qdrawhelper_sse2.cpp | 32 +++---- src/gui/painting/qdrawhelper_sse4.cpp | 2 +- src/gui/painting/qdrawhelper_ssse3.cpp | 101 ++++++++++---------- src/gui/painting/qdrawingprimitive_sse2_p.h | 4 +- src/gui/painting/qimagescale_sse4.cpp | 4 +- 6 files changed, 85 insertions(+), 75 deletions(-) diff --git a/src/gui/painting/qdrawhelper_avx2.cpp b/src/gui/painting/qdrawhelper_avx2.cpp index adf11999bc..3a37b85366 100644 --- a/src/gui/painting/qdrawhelper_avx2.cpp +++ b/src/gui/painting/qdrawhelper_avx2.cpp @@ -55,7 +55,8 @@ enum { // Vectorized blend functions: // See BYTE_MUL_SSE2 for details. -inline static void BYTE_MUL_AVX2(__m256i &pixelVector, const __m256i &alphaChannel, const __m256i &colorMask, const __m256i &half) +inline static void Q_DECL_VECTORCALL +BYTE_MUL_AVX2(__m256i &pixelVector, __m256i alphaChannel, __m256i colorMask, __m256i half) { __m256i pixelVectorAG = _mm256_srli_epi16(pixelVector, 8); __m256i pixelVectorRB = _mm256_and_si256(pixelVector, colorMask); @@ -74,7 +75,8 @@ inline static void BYTE_MUL_AVX2(__m256i &pixelVector, const __m256i &alphaChann pixelVector = _mm256_or_si256(pixelVectorAG, pixelVectorRB); } -inline static void BYTE_MUL_RGB64_AVX2(__m256i &pixelVector, const __m256i &alphaChannel, const __m256i &colorMask, const __m256i &half) +inline static void Q_DECL_VECTORCALL +BYTE_MUL_RGB64_AVX2(__m256i &pixelVector, __m256i alphaChannel, __m256i colorMask, __m256i half) { __m256i pixelVectorAG = _mm256_srli_epi32(pixelVector, 16); __m256i pixelVectorRB = _mm256_and_si256(pixelVector, colorMask); @@ -94,7 +96,8 @@ inline static void BYTE_MUL_RGB64_AVX2(__m256i &pixelVector, const __m256i &alph } // See INTERPOLATE_PIXEL_255_SSE2 for details. -inline static void INTERPOLATE_PIXEL_255_AVX2(const __m256i &srcVector, __m256i &dstVector, const __m256i &alphaChannel, const __m256i &oneMinusAlphaChannel, const __m256i &colorMask, const __m256i &half) +inline static void Q_DECL_VECTORCALL +INTERPOLATE_PIXEL_255_AVX2(__m256i srcVector, __m256i &dstVector, __m256i alphaChannel, __m256i oneMinusAlphaChannel, __m256i colorMask, __m256i half) { const __m256i srcVectorAG = _mm256_srli_epi16(srcVector, 8); const __m256i dstVectorAG = _mm256_srli_epi16(dstVector, 8); @@ -116,7 +119,8 @@ inline static void INTERPOLATE_PIXEL_255_AVX2(const __m256i &srcVector, __m256i dstVector = _mm256_or_si256(finalAG, finalRB); } -inline static void INTERPOLATE_PIXEL_RGB64_AVX2(const __m256i &srcVector, __m256i &dstVector, const __m256i &alphaChannel, const __m256i &oneMinusAlphaChannel, const __m256i &colorMask, const __m256i &half) +inline static void Q_DECL_VECTORCALL +INTERPOLATE_PIXEL_RGB64_AVX2(__m256i srcVector, __m256i &dstVector, __m256i alphaChannel, __m256i oneMinusAlphaChannel, __m256i colorMask, __m256i half) { const __m256i srcVectorAG = _mm256_srli_epi32(srcVector, 16); const __m256i dstVectorAG = _mm256_srli_epi32(dstVector, 16); @@ -140,7 +144,7 @@ inline static void INTERPOLATE_PIXEL_RGB64_AVX2(const __m256i &srcVector, __m256 // See BLEND_SOURCE_OVER_ARGB32_SSE2 for details. -inline static void BLEND_SOURCE_OVER_ARGB32_AVX2(quint32 *dst, const quint32 *src, const int length) +inline static void Q_DECL_VECTORCALL BLEND_SOURCE_OVER_ARGB32_AVX2(quint32 *dst, const quint32 *src, const int length) { const __m256i half = _mm256_set1_epi16(0x80); const __m256i one = _mm256_set1_epi16(0xff); @@ -211,7 +215,8 @@ inline static void BLEND_SOURCE_OVER_ARGB32_AVX2(quint32 *dst, const quint32 *sr // See BLEND_SOURCE_OVER_ARGB32_WITH_CONST_ALPHA_SSE2 for details. -inline static void BLEND_SOURCE_OVER_ARGB32_WITH_CONST_ALPHA_AVX2(quint32 *dst, const quint32 *src, const int length, const int const_alpha) +inline static void Q_DECL_VECTORCALL +BLEND_SOURCE_OVER_ARGB32_WITH_CONST_ALPHA_AVX2(quint32 *dst, const quint32 *src, const int length, const int const_alpha) { int x = 0; diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index 0ac9508264..c82f41ec88 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -454,30 +454,30 @@ public: union Vect_buffer_i { Int32x4 v; int i[4]; }; union Vect_buffer_f { Float32x4 v; float f[4]; }; - static inline Float32x4 v_dup(float x) { return _mm_set1_ps(x); } - static inline Float32x4 v_dup(double x) { return _mm_set1_ps(x); } - static inline Int32x4 v_dup(int x) { return _mm_set1_epi32(x); } - static inline Int32x4 v_dup(uint x) { return _mm_set1_epi32(x); } + static inline Float32x4 Q_DECL_VECTORCALL v_dup(float x) { return _mm_set1_ps(x); } + static inline Float32x4 Q_DECL_VECTORCALL v_dup(double x) { return _mm_set1_ps(x); } + static inline Int32x4 Q_DECL_VECTORCALL v_dup(int x) { return _mm_set1_epi32(x); } + static inline Int32x4 Q_DECL_VECTORCALL v_dup(uint x) { return _mm_set1_epi32(x); } - static inline Float32x4 v_add(Float32x4 a, Float32x4 b) { return _mm_add_ps(a, b); } - static inline Int32x4 v_add(Int32x4 a, Int32x4 b) { return _mm_add_epi32(a, b); } + static inline Float32x4 Q_DECL_VECTORCALL v_add(Float32x4 a, Float32x4 b) { return _mm_add_ps(a, b); } + static inline Int32x4 Q_DECL_VECTORCALL v_add(Int32x4 a, Int32x4 b) { return _mm_add_epi32(a, b); } - static inline Float32x4 v_max(Float32x4 a, Float32x4 b) { return _mm_max_ps(a, b); } - static inline Float32x4 v_min(Float32x4 a, Float32x4 b) { return _mm_min_ps(a, b); } - static inline Int32x4 v_min_16(Int32x4 a, Int32x4 b) { return _mm_min_epi16(a, b); } + static inline Float32x4 Q_DECL_VECTORCALL v_max(Float32x4 a, Float32x4 b) { return _mm_max_ps(a, b); } + static inline Float32x4 Q_DECL_VECTORCALL v_min(Float32x4 a, Float32x4 b) { return _mm_min_ps(a, b); } + static inline Int32x4 Q_DECL_VECTORCALL v_min_16(Int32x4 a, Int32x4 b) { return _mm_min_epi16(a, b); } - static inline Int32x4 v_and(Int32x4 a, Int32x4 b) { return _mm_and_si128(a, b); } + static inline Int32x4 Q_DECL_VECTORCALL v_and(Int32x4 a, Int32x4 b) { return _mm_and_si128(a, b); } - static inline Float32x4 v_sub(Float32x4 a, Float32x4 b) { return _mm_sub_ps(a, b); } - static inline Int32x4 v_sub(Int32x4 a, Int32x4 b) { return _mm_sub_epi32(a, b); } + static inline Float32x4 Q_DECL_VECTORCALL v_sub(Float32x4 a, Float32x4 b) { return _mm_sub_ps(a, b); } + static inline Int32x4 Q_DECL_VECTORCALL v_sub(Int32x4 a, Int32x4 b) { return _mm_sub_epi32(a, b); } - static inline Float32x4 v_mul(Float32x4 a, Float32x4 b) { return _mm_mul_ps(a, b); } + static inline Float32x4 Q_DECL_VECTORCALL v_mul(Float32x4 a, Float32x4 b) { return _mm_mul_ps(a, b); } - static inline Float32x4 v_sqrt(Float32x4 x) { return _mm_sqrt_ps(x); } + static inline Float32x4 Q_DECL_VECTORCALL v_sqrt(Float32x4 x) { return _mm_sqrt_ps(x); } - static inline Int32x4 v_toInt(Float32x4 x) { return _mm_cvttps_epi32(x); } + static inline Int32x4 Q_DECL_VECTORCALL v_toInt(Float32x4 x) { return _mm_cvttps_epi32(x); } - static inline Int32x4 v_greaterOrEqual(Float32x4 a, Float32x4 b) { return _mm_castps_si128(_mm_cmpgt_ps(a, b)); } + static inline Int32x4 Q_DECL_VECTORCALL v_greaterOrEqual(Float32x4 a, Float32x4 b) { return _mm_castps_si128(_mm_cmpgt_ps(a, b)); } }; const uint * QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer, const Operator *op, const QSpanData *data, diff --git a/src/gui/painting/qdrawhelper_sse4.cpp b/src/gui/painting/qdrawhelper_sse4.cpp index e3cc1dd43e..06bfd3465e 100644 --- a/src/gui/painting/qdrawhelper_sse4.cpp +++ b/src/gui/painting/qdrawhelper_sse4.cpp @@ -94,7 +94,7 @@ static void convertARGBToARGB32PM_sse4(uint *buffer, const uint *src, int count) } } -static inline __m128 reciprocal_mul_ps(__m128 a, float mul) +static inline __m128 Q_DECL_VECTORCALL reciprocal_mul_ps(__m128 a, float mul) { __m128 ia = _mm_rcp_ps(a); // Approximate 1/a // Improve precision of ia using Newton-Raphson diff --git a/src/gui/painting/qdrawhelper_ssse3.cpp b/src/gui/painting/qdrawhelper_ssse3.cpp index 42d760d5cc..0891cff8b8 100644 --- a/src/gui/painting/qdrawhelper_ssse3.cpp +++ b/src/gui/painting/qdrawhelper_ssse3.cpp @@ -79,55 +79,58 @@ QT_BEGIN_NAMESPACE // The computation being done is: // result = s + d * (1-alpha) // with shortcuts if fully opaque or fully transparent. -#define BLEND_SOURCE_OVER_ARGB32_SSSE3(dst, src, length, nullVector, half, one, colorMask, alphaMask) { \ - int x = 0; \ -\ - /* First, get dst aligned. */ \ - ALIGNMENT_PROLOGUE_16BYTES(dst, x, length) { \ - blend_pixel(dst[x], src[x]); \ - } \ -\ - const int minusOffsetToAlignSrcOn16Bytes = (reinterpret_cast(&(src[x])) >> 2) & 0x3;\ -\ - if (!minusOffsetToAlignSrcOn16Bytes) {\ - /* src is aligned, usual algorithm but with aligned operations.\ - See the SSE2 version for more documentation on the algorithm itself. */\ - const __m128i alphaShuffleMask = _mm_set_epi8(char(0xff),15,char(0xff),15,char(0xff),11,char(0xff),11,char(0xff),7,char(0xff),7,char(0xff),3,char(0xff),3);\ - for (; x < length-3; x += 4) { \ - const __m128i srcVector = _mm_load_si128((const __m128i *)&src[x]); \ - const __m128i srcVectorAlpha = _mm_and_si128(srcVector, alphaMask); \ - if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, alphaMask)) == 0xffff) { \ - _mm_store_si128((__m128i *)&dst[x], srcVector); \ - } else if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, nullVector)) != 0xffff) { \ - __m128i alphaChannel = _mm_shuffle_epi8(srcVector, alphaShuffleMask); \ - alphaChannel = _mm_sub_epi16(one, alphaChannel); \ - const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); \ - __m128i destMultipliedByOneMinusAlpha; \ - BYTE_MUL_SSE2(destMultipliedByOneMinusAlpha, dstVector, alphaChannel, colorMask, half); \ - const __m128i result = _mm_add_epi8(srcVector, destMultipliedByOneMinusAlpha); \ - _mm_store_si128((__m128i *)&dst[x], result); \ - } \ - } /* end for() */\ - } else if ((length - x) >= 8) {\ - /* We use two vectors to extract the src: prevLoaded for the first pixels, lastLoaded for the current pixels. */\ - __m128i srcVectorPrevLoaded = _mm_load_si128((const __m128i *)&src[x - minusOffsetToAlignSrcOn16Bytes]);\ - const int palignrOffset = minusOffsetToAlignSrcOn16Bytes << 2;\ -\ - const __m128i alphaShuffleMask = _mm_set_epi8(char(0xff),15,char(0xff),15,char(0xff),11,char(0xff),11,char(0xff),7,char(0xff),7,char(0xff),3,char(0xff),3);\ - switch (palignrOffset) {\ - case 4:\ - BLENDING_LOOP(4, length)\ - break;\ - case 8:\ - BLENDING_LOOP(8, length)\ - break;\ - case 12:\ - BLENDING_LOOP(12, length)\ - break;\ - }\ - }\ - for (; x < length; ++x) \ - blend_pixel(dst[x], src[x]); \ +static inline void Q_DECL_VECTORCALL +BLEND_SOURCE_OVER_ARGB32_SSSE3(quint32 *dst, const quint32 *src, int length, + __m128i nullVector, __m128i half, __m128i one, __m128i colorMask, __m128i alphaMask) +{ + int x = 0; + + /* First, get dst aligned. */ + ALIGNMENT_PROLOGUE_16BYTES(dst, x, length) { + blend_pixel(dst[x], src[x]); + } + + const int minusOffsetToAlignSrcOn16Bytes = (reinterpret_cast(&(src[x])) >> 2) & 0x3; + + if (!minusOffsetToAlignSrcOn16Bytes) { + /* src is aligned, usual algorithm but with aligned operations. + See the SSE2 version for more documentation on the algorithm itself. */ + const __m128i alphaShuffleMask = _mm_set_epi8(char(0xff),15,char(0xff),15,char(0xff),11,char(0xff),11,char(0xff),7,char(0xff),7,char(0xff),3,char(0xff),3); + for (; x < length-3; x += 4) { + const __m128i srcVector = _mm_load_si128((const __m128i *)&src[x]); + const __m128i srcVectorAlpha = _mm_and_si128(srcVector, alphaMask); + if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, alphaMask)) == 0xffff) { + _mm_store_si128((__m128i *)&dst[x], srcVector); + } else if (_mm_movemask_epi8(_mm_cmpeq_epi32(srcVectorAlpha, nullVector)) != 0xffff) { + __m128i alphaChannel = _mm_shuffle_epi8(srcVector, alphaShuffleMask); + alphaChannel = _mm_sub_epi16(one, alphaChannel); + const __m128i dstVector = _mm_load_si128((__m128i *)&dst[x]); + __m128i destMultipliedByOneMinusAlpha; + BYTE_MUL_SSE2(destMultipliedByOneMinusAlpha, dstVector, alphaChannel, colorMask, half); + const __m128i result = _mm_add_epi8(srcVector, destMultipliedByOneMinusAlpha); + _mm_store_si128((__m128i *)&dst[x], result); + } + } /* end for() */ + } else if ((length - x) >= 8) { + /* We use two vectors to extract the src: prevLoaded for the first pixels, lastLoaded for the current pixels. */ + __m128i srcVectorPrevLoaded = _mm_load_si128((const __m128i *)&src[x - minusOffsetToAlignSrcOn16Bytes]); + const int palignrOffset = minusOffsetToAlignSrcOn16Bytes << 2; + + const __m128i alphaShuffleMask = _mm_set_epi8(char(0xff),15,char(0xff),15,char(0xff),11,char(0xff),11,char(0xff),7,char(0xff),7,char(0xff),3,char(0xff),3); + switch (palignrOffset) { + case 4: + BLENDING_LOOP(4, length) + break; + case 8: + BLENDING_LOOP(8, length) + break; + case 12: + BLENDING_LOOP(12, length) + break; + } + } + for (; x < length; ++x) + blend_pixel(dst[x], src[x]); } void qt_blend_argb32_on_argb32_ssse3(uchar *destPixels, int dbpl, diff --git a/src/gui/painting/qdrawingprimitive_sse2_p.h b/src/gui/painting/qdrawingprimitive_sse2_p.h index b237ea1611..cc8d230fa8 100644 --- a/src/gui/painting/qdrawingprimitive_sse2_p.h +++ b/src/gui/painting/qdrawingprimitive_sse2_p.h @@ -42,7 +42,7 @@ #include #include -#include "qdrawhelper_p.h" +#include "qdrawhelper_x86_p.h" #include "qrgba64_p.h" #ifdef __SSE2__ @@ -232,7 +232,7 @@ QT_END_NAMESPACE QT_BEGIN_NAMESPACE #if QT_COMPILER_SUPPORTS_HERE(SSE4_1) QT_FUNCTION_TARGET(SSE2) -Q_ALWAYS_INLINE void reciprocal_mul_ss(__m128 &ia, const __m128 a, float mul) +Q_ALWAYS_INLINE void Q_DECL_VECTORCALL reciprocal_mul_ss(__m128 &ia, const __m128 a, float mul) { ia = _mm_rcp_ss(a); // Approximate 1/a // Improve precision of ia using Newton-Raphson diff --git a/src/gui/painting/qimagescale_sse4.cpp b/src/gui/painting/qimagescale_sse4.cpp index 34d6b3882e..5861a2e2ff 100644 --- a/src/gui/painting/qimagescale_sse4.cpp +++ b/src/gui/painting/qimagescale_sse4.cpp @@ -39,6 +39,7 @@ #include "qimagescale_p.h" #include "qimage.h" +#include #include #if defined(QT_COMPILER_SUPPORTS_SSE4_1) @@ -47,7 +48,8 @@ QT_BEGIN_NAMESPACE using namespace QImageScale; -inline static __m128i qt_qimageScaleAARGBA_helper(const unsigned int *pix, int xyap, int Cxy, int step, const __m128i vxyap, const __m128i vCxy) +inline static __m128i Q_DECL_VECTORCALL +qt_qimageScaleAARGBA_helper(const unsigned int *pix, int xyap, int Cxy, int step, const __m128i vxyap, const __m128i vCxy) { __m128i vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); __m128i vx = _mm_mullo_epi32(vpix, vxyap); From ab448f731ecd8437c7c5c8b96a0e7f419ec3a7ca Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 2 Oct 2018 19:02:29 +0200 Subject: [PATCH 0600/1650] Handle QCollator with locale C by delegating to QString Previously, the C locale was treated as English because each back-end takes the locale's bcp47Name(), which maps C to en. However, the C locale has its own rules; which QString helpfully implements; so we can delegate to it in this case. Extended this to sort keys, where possible. Clean up existing implementations in the process. Extended tst_QCollator::compare() with some cases to check this. That required wrapping the test's calls to collator.compare() in a sign canonicalizer, since it can return any -ve for < or +ve for >, not just -1 and +1 for these cases (and it'd be rash to hard-code specific negative and positive values, as they may vary between backends). [ChangeLog][QtCore][QCollator] Added support for collation in the C locale, albeit this is only well-defined for ASCII. Collation sort keys remain unsupported on Darwin. Fixes: QTBUG-58621 Change-Id: I327010d90f09bd1b1816f5590cb124e3d423e61d Reviewed-by: Thiago Macieira --- src/corelib/tools/qcollator.cpp | 3 +- src/corelib/tools/qcollator_icu.cpp | 4 ++ src/corelib/tools/qcollator_macx.cpp | 20 +++++++++ src/corelib/tools/qcollator_p.h | 1 + src/corelib/tools/qcollator_posix.cpp | 41 +++++++++++-------- src/corelib/tools/qcollator_win.cpp | 7 ++++ .../corelib/tools/qcollator/tst_qcollator.cpp | 18 +++++--- 7 files changed, 70 insertions(+), 24 deletions(-) diff --git a/src/corelib/tools/qcollator.cpp b/src/corelib/tools/qcollator.cpp index 1cf223aae6..4315d35a52 100644 --- a/src/corelib/tools/qcollator.cpp +++ b/src/corelib/tools/qcollator.cpp @@ -79,7 +79,6 @@ QT_BEGIN_NAMESPACE QCollator::QCollator(const QLocale &locale) : d(new QCollatorPrivate(locale)) { - d->init(); } /*! @@ -323,6 +322,8 @@ bool QCollator::ignorePunctuation() const methods directly. But if the string is compared repeatedly (e.g. when sorting a whole list of strings), it's usually faster to create the sort keys for each string and then sort using the keys. + + \note Not supported with the C (a.k.a. POSIX) locale on Darwin. */ /*! diff --git a/src/corelib/tools/qcollator_icu.cpp b/src/corelib/tools/qcollator_icu.cpp index fd621983d3..ab45b9a1a1 100644 --- a/src/corelib/tools/qcollator_icu.cpp +++ b/src/corelib/tools/qcollator_icu.cpp @@ -55,6 +55,8 @@ QT_BEGIN_NAMESPACE void QCollatorPrivate::init() { cleanup(); + if (isC()) + return; UErrorCode status = U_ZERO_ERROR; QByteArray name = QLocalePrivate::get(locale)->bcp47Name('_'); @@ -140,6 +142,8 @@ QCollatorSortKey QCollator::sortKey(const QString &string) const { if (d->dirty) d->init(); + if (d->isC()) + return QCollatorSortKey(new QCollatorSortKeyPrivate(string.toUtf8())); if (d->collator) { QByteArray result(16 + string.size() + (string.size() >> 2), Qt::Uninitialized); diff --git a/src/corelib/tools/qcollator_macx.cpp b/src/corelib/tools/qcollator_macx.cpp index 9aa59a81dc..42e67e0c12 100644 --- a/src/corelib/tools/qcollator_macx.cpp +++ b/src/corelib/tools/qcollator_macx.cpp @@ -55,6 +55,15 @@ QT_BEGIN_NAMESPACE void QCollatorPrivate::init() { cleanup(); + /* + LocaleRefFromLocaleString() will accept "POSIX" as the locale name, but + the locale it produces (named "pos") doesn't implement the [A-Z] < [a-z] + behavior we expect of the C locale. We can use QStringView to get round + that for collation, but this leaves no way to do a sort key. + */ + if (isC()) + return; + LocaleRef localeRef; int rc = LocaleRefFromLocaleString(QLocalePrivate::get(locale)->bcp47Name().constData(), &localeRef); if (rc != 0) @@ -92,6 +101,8 @@ int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) con { if (d->dirty) d->init(); + if (!d->collator) + return QStringView(s1, len1).compare(QStringView(s2, len2), caseSensitivity()); SInt32 result; Boolean equivalent; @@ -104,6 +115,7 @@ int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) con return 0; return result < 0 ? -1 : 1; } + int QCollator::compare(const QString &str1, const QString &str2) const { return compare(str1.constData(), str1.size(), str2.constData(), str2.size()); @@ -118,6 +130,11 @@ QCollatorSortKey QCollator::sortKey(const QString &string) const { if (d->dirty) d->init(); + if (!d->collator) { + // What should (or even *can*) we do here ? (See init()'s comment.) + qWarning("QCollator doesn't support sort keys for the C locale on Darwin"); + return QCollatorSortKey(nullptr); + } //Documentation recommends having it 5 times as big as the input QVector ret(string.size() * 5); @@ -136,6 +153,9 @@ QCollatorSortKey QCollator::sortKey(const QString &string) const int QCollatorSortKey::compare(const QCollatorSortKey &key) const { + if (!d.data()) + return 0; + SInt32 order; UCCompareCollationKeys(d->m_key.data(), d->m_key.size(), key.d->m_key.data(), key.d->m_key.size(), diff --git a/src/corelib/tools/qcollator_p.h b/src/corelib/tools/qcollator_p.h index e89c08447c..361c3fb987 100644 --- a/src/corelib/tools/qcollator_p.h +++ b/src/corelib/tools/qcollator_p.h @@ -110,6 +110,7 @@ public: QCollatorPrivate(const QLocale &locale) : locale(locale) {} ~QCollatorPrivate() { cleanup(); } + bool isC() { return locale.language() == QLocale::C; } void clear() { cleanup(); diff --git a/src/corelib/tools/qcollator_posix.cpp b/src/corelib/tools/qcollator_posix.cpp index 42413a4a82..81f97a02e1 100644 --- a/src/corelib/tools/qcollator_posix.cpp +++ b/src/corelib/tools/qcollator_posix.cpp @@ -48,10 +48,12 @@ QT_BEGIN_NAMESPACE void QCollatorPrivate::init() { - if (locale != QLocale()) - qWarning("Only default locale supported with the posix collation implementation"); - if (caseSensitivity != Qt::CaseSensitive) - qWarning("Case insensitive sorting unsupported in the posix collation implementation"); + if (!isC()) { + if (locale != QLocale()) + qWarning("Only C and default locale supported with the posix collation implementation"); + if (caseSensitivity != Qt::CaseSensitive) + qWarning("Case insensitive sorting unsupported in the posix collation implementation"); + } if (numericMode) qWarning("Numeric mode unsupported in the posix collation implementation"); if (ignorePunctuation) @@ -73,14 +75,16 @@ static void stringToWCharArray(QVarLengthArray &ret, const QString &str int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) const { - QVarLengthArray array1, array2; - stringToWCharArray(array1, QString(s1, len1)); - stringToWCharArray(array2, QString(s2, len2)); - return std::wcscoll(array1.constData(), array2.constData()); + return compare(QString::fromRawData(s1, len1), QString::fromRawData(s2, len2)); } int QCollator::compare(const QString &s1, const QString &s2) const { + if (d->isC()) + return s1.compare(s2, caseSensitivity()); + if (d->dirty) + d->init(); + QVarLengthArray array1, array2; stringToWCharArray(array1, s1); stringToWCharArray(array2, s2); @@ -89,10 +93,7 @@ int QCollator::compare(const QString &s1, const QString &s2) const int QCollator::compare(const QStringRef &s1, const QStringRef &s2) const { - if (d->dirty) - d->init(); - - return compare(s1.constData(), s1.size(), s2.constData(), s2.size()); + return compare(s1.toString(), s2.toString()); } QCollatorSortKey QCollator::sortKey(const QString &string) const @@ -102,14 +103,18 @@ QCollatorSortKey QCollator::sortKey(const QString &string) const QVarLengthArray original; stringToWCharArray(original, string); - QVector result(string.size()); - size_t size = std::wcsxfrm(result.data(), original.constData(), string.size()); - if (size > uint(result.size())) { + QVector result(original.size()); + if (d->isC()) { + std::copy(original.cbegin(), original.cend(), result.begin()); + } else { + size_t size = std::wcsxfrm(result.data(), original.constData(), string.size()); + if (size > uint(result.size())) { + result.resize(size+1); + size = std::wcsxfrm(result.data(), original.constData(), string.size()); + } result.resize(size+1); - size = std::wcsxfrm(result.data(), original.constData(), string.size()); + result[size] = 0; } - result.resize(size+1); - result[size] = 0; return QCollatorSortKey(new QCollatorSortKeyPrivate(std::move(result))); } diff --git a/src/corelib/tools/qcollator_win.cpp b/src/corelib/tools/qcollator_win.cpp index 5a838c1b50..35142bb8b8 100644 --- a/src/corelib/tools/qcollator_win.cpp +++ b/src/corelib/tools/qcollator_win.cpp @@ -60,6 +60,8 @@ extern LCID qt_inIsoNametoLCID(const char *name); void QCollatorPrivate::init() { collator = 0; + if (isC()) + return; #ifndef USE_COMPARESTRINGEX localeID = qt_inIsoNametoLCID(QLocalePrivate::get(locale)->bcp47Name().constData()); @@ -86,6 +88,9 @@ void QCollatorPrivate::cleanup() int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) const { + if (d->isC()) + return QString::compare_helper(s1, len1, s2, len2, d->caseSensitivity); + if (d->dirty) d->init(); @@ -119,6 +124,8 @@ QCollatorSortKey QCollator::sortKey(const QString &string) const { if (d->dirty) d->init(); + if (d->isC()) + return QCollatorSortKey(new QCollatorSortKeyPrivate(string)); #ifndef USE_COMPARESTRINGEX int size = LCMapStringW(d->localeID, LCMAP_SORTKEY | d->collator, diff --git a/tests/auto/corelib/tools/qcollator/tst_qcollator.cpp b/tests/auto/corelib/tools/qcollator/tst_qcollator.cpp index 2d65d3433f..72f88a235d 100644 --- a/tests/auto/corelib/tools/qcollator/tst_qcollator.cpp +++ b/tests/auto/corelib/tools/qcollator/tst_qcollator.cpp @@ -93,7 +93,7 @@ void tst_QCollator::compare_data() QTest::addColumn("caseInsensitiveResult"); QTest::addColumn("numericMode"); QTest::addColumn("ignorePunctuation"); - QTest::addColumn("punctuationResult"); + QTest::addColumn("punctuationResult"); // Test ignores punctuation *and case* /* It's hard to test English, because it's treated differently @@ -169,8 +169,12 @@ void tst_QCollator::compare_data() QTest::newRow("french6") << QString("fr_FR") << QString("Test 9") << QString("Test_19") << -1 << -1 << true << true << -1; QTest::newRow("french7") << QString("fr_FR") << QString("test_19") << QString("test 19") << 1 << 1 << true << false << 1; QTest::newRow("french8") << QString("fr_FR") << QString("test.19") << QString("test,19") << 1 << 1 << true << true << 0; -} + // C locale: case sensitive [A-Z] < [a-z] but case insensitive [Aa] < [Bb] <...< [Zz] + const QString C = QStringLiteral("C"); + QTest::newRow("C:ABBA:AaaA") << C << QStringLiteral("ABBA") << QStringLiteral("AaaA") << -1 << 1 << false << false << 1; + QTest::newRow("C:AZa:aAZ") << C << QStringLiteral("AZa") << QStringLiteral("aAZ") << -1 << 1 << false << false << 1; +} void tst_QCollator::compare() { @@ -184,6 +188,10 @@ void tst_QCollator::compare() QFETCH(int, punctuationResult); QCollator collator(locale); + // Need to canonicalize sign to -1, 0 or 1, as .compare() can produce any -ve for <, any +ve for >. + auto asSign = [](int compared) { + return compared < 0 ? -1 : compared > 0 ? 1 : 0; + }; #if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED) if (collator.locale() != QLocale()) @@ -193,12 +201,12 @@ void tst_QCollator::compare() if (numericMode) collator.setNumericMode(true); - QCOMPARE(collator.compare(s1, s2), result); + QCOMPARE(asSign(collator.compare(s1, s2)), result); collator.setCaseSensitivity(Qt::CaseInsensitive); - QCOMPARE(collator.compare(s1, s2), caseInsensitiveResult); + QCOMPARE(asSign(collator.compare(s1, s2)), caseInsensitiveResult); #if !QT_CONFIG(iconv) collator.setIgnorePunctuation(ignorePunctuation); - QCOMPARE(collator.compare(s1, s2), punctuationResult); + QCOMPARE(asSign(collator.compare(s1, s2)), punctuationResult); #endif } From db0616097f8a1658a6acf5798ead495999b24b87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 5 Dec 2018 17:17:49 +0100 Subject: [PATCH 0601/1650] Actually make QT_MAX_CACHED_GLYPH_SIZE the max glyph size This effectively means we'll start drawing text with a pixel size of 64 using cached glyphs, whereas before we would treat this as the cutoff and draw it using painter paths. Change-Id: Ie58212ef9217c8f8a69a92e48a8788f191b99415 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/painting/qpaintengineex.cpp | 2 +- src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 880423ca3b..22d3fb3001 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -1100,7 +1100,7 @@ bool QPaintEngineEx::shouldDrawCachedGlyphs(QFontEngine *fontEngine, const QTran }(), 2); qreal pixelSize = fontEngine->fontDef.pixelSize; - return (pixelSize * pixelSize * qAbs(m.determinant())) < maxCachedGlyphSizeSquared; + return (pixelSize * pixelSize * qAbs(m.determinant())) <= maxCachedGlyphSizeSquared; } QT_END_NAMESPACE diff --git a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp index 7b4f6aa107..654a603bce 100644 --- a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp +++ b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp @@ -1556,7 +1556,7 @@ QFontEngineFT::QGlyphSet *QFontEngineFT::loadGlyphSet(const QTransform &matrix) gs = &transformedGlyphSets[0]; gs->clear(); gs->transformationMatrix = m; - gs->outline_drawing = fontDef.pixelSize * fontDef.pixelSize * qAbs(matrix.det()) >= QT_MAX_CACHED_GLYPH_SIZE * QT_MAX_CACHED_GLYPH_SIZE; + gs->outline_drawing = fontDef.pixelSize * fontDef.pixelSize * qAbs(matrix.det()) > QT_MAX_CACHED_GLYPH_SIZE * QT_MAX_CACHED_GLYPH_SIZE; } Q_ASSERT(gs != 0); From f10b98084064f5d53717c8364048562d373a7f88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 10 Dec 2018 17:57:26 +0100 Subject: [PATCH 0602/1650] nativetext: Fix baseline positioning for CoreText The Qt and CoreText positioning is now in sync. Change-Id: I0cbb5b150d1bef732674b8d42c64a040773a62ab Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../manual/textrendering/nativetext/main.cpp | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/tests/manual/textrendering/nativetext/main.cpp b/tests/manual/textrendering/nativetext/main.cpp index 5c7621e61f..3fb78858f0 100644 --- a/tests/manual/textrendering/nativetext/main.cpp +++ b/tests/manual/textrendering/nativetext/main.cpp @@ -101,7 +101,9 @@ public: const int ascent = fontMetrics().ascent(); - p.setPen(Qt::magenta); + QPen metricsPen(Qt::magenta, 1.0); + metricsPen.setCosmetic(true); + p.setPen(metricsPen); p.drawLine(QPoint(0, ascent), QPoint(width(), ascent)); p.end(); @@ -152,13 +154,22 @@ public: if (font().styleStrategy() & QFont::NoAntialias) CGContextSetShouldAntialias(ctx, false); - // Retain count already tracked by QMacCGContext above - NSGraphicsContext.currentContext = [NSGraphicsContext graphicsContextWithCGContext:ctx flipped:YES]; - [text().toNSString() drawAtPoint:CGPointZero withAttributes:@{ - NSFontAttributeName : (NSFont *)fontEngine->handle(), - NSForegroundColorAttributeName : nsColor - }]; - NSGraphicsContext.currentContext = nil; + // Flip to what CT expects + CGContextScaleCTM(ctx, 1, -1); + CGContextTranslateCTM(ctx, 0, -height()); + + // Set up baseline + CGContextSetTextPosition(ctx, 0, height() - fontMetrics().ascent()); + + auto *attributedString = [[NSAttributedString alloc] initWithString:text().toNSString() + attributes:@{ + NSFontAttributeName : (NSFont *)fontEngine->handle(), + NSForegroundColorAttributeName : nsColor + } + ]; + + QCFType line = CTLineCreateWithAttributedString(CFAttributedStringRef([attributedString autorelease])); + CTLineDraw(line, ctx); #endif } From 33177b0456f50a1f3eae7a37b4ecc897aaf7125e Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 14 Nov 2018 14:17:38 +0100 Subject: [PATCH 0603/1650] Add a qt_memfill24 implementation This function gets called from qt_rectfill_quint24, which is used by the RGB666, ARGB6666_Premultiplied, ARGB8555_Premultiplied, and RGB888 formats. Together-with: Thiago Macieira Change-Id: Iba4b5c183776497d8ee1fffd1564585fdee835c2 Reviewed-by: Thiago Macieira --- src/gui/painting/qdrawhelper.cpp | 37 ++++++++++++++++++++++++++++ src/gui/painting/qdrawhelper_p.h | 41 +++++++++++++++++--------------- 2 files changed, 59 insertions(+), 19 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 59b46b84ef..95d14a4500 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -55,6 +55,7 @@ #endif #include #include +#include #include #include @@ -6267,6 +6268,42 @@ void qt_memfill64(quint64 *dest, quint64 color, qsizetype count) } #endif +void qt_memfill24(quint24 *dest, quint24 color, qsizetype count) +{ + const quint32 v = color; + quint24 *end = dest + count; + + // prolog: align dest to 32bit + while ((quintptr(dest) & 0x3) && dest < end) { + *dest++ = v; + } + if (dest >= end) + return; + + const uint val1 = qFromBigEndian((v << 8) | (v >> 16)); + const uint val2 = qFromBigEndian((v << 16) | (v >> 8)); + const uint val3 = qFromBigEndian((v << 24) | (v >> 0)); + + for ( ; dest <= (end - 4); dest += 4) { + quint32 *dst = reinterpret_cast(dest); + dst[0] = val1; + dst[1] = val2; + dst[2] = val3; + } + + // less than 4px left + switch (end - dest) { + case 3: + *dest++ = v; + Q_FALLTHROUGH(); + case 2: + *dest++ = v; + Q_FALLTHROUGH(); + case 1: + *dest++ = v; + } +} + void qt_memfill16(quint16 *dest, quint16 value, qsizetype count) { const int align = quintptr(dest) & 0x3; diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 219734c430..4dcfbc813b 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -165,6 +165,22 @@ extern SrcOverTransformFunc qTransformFunctions[QImage::NImageFormats][QImage::N extern DrawHelper qDrawHelper[QImage::NImageFormats]; +struct quint24 { + quint24() = default; + quint24(uint value) + { + data[0] = uchar(value >> 16); + data[1] = uchar(value >> 8); + data[2] = uchar(value); + } + operator uint() const + { + return data[2] | (data[1] << 8) | (data[0] << 16); + } + + uchar data[3]; +}; + void qBlendGradient(int count, const QSpan *spans, void *userData); void qBlendTexture(int count, const QSpan *spans, void *userData); #ifdef __SSE2__ @@ -174,6 +190,7 @@ extern void (*qt_memfill32)(quint32 *dest, quint32 value, qsizetype count); extern void qt_memfill64(quint64 *dest, quint64 value, qsizetype count); extern void qt_memfill32(quint32 *dest, quint32 value, qsizetype count); #endif +extern void qt_memfill24(quint24 *dest, quint24 value, qsizetype count); extern void qt_memfill16(quint16 *dest, quint16 value, qsizetype count); typedef void (QT_FASTCALL *CompositionFunction)(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha); @@ -872,25 +889,6 @@ static Q_ALWAYS_INLINE uint qAlphaRgb30(uint c) return a; } -struct quint24 { - quint24() = default; - quint24(uint value); - operator uint() const; - uchar data[3]; -}; - -inline quint24::quint24(uint value) -{ - data[0] = uchar(value >> 16); - data[1] = uchar(value >> 8); - data[2] = uchar(value); -} - -inline quint24::operator uint() const -{ - return data[2] | (data[1] << 8) | (data[0] << 16); -} - template inline void qt_memfill_template(T *dest, T color, qsizetype count) { if (!count) @@ -926,6 +924,11 @@ template<> inline void qt_memfill(quint32 *dest, quint32 color, qsizetype count) qt_memfill32(dest, color, count); } +template<> inline void qt_memfill(quint24 *dest, quint24 color, qsizetype count) +{ + qt_memfill24(dest, color, count); +} + template<> inline void qt_memfill(quint16 *dest, quint16 color, qsizetype count) { qt_memfill16(dest, color, count); From 3df79b2953aa9142d66bd57676c6308acde98b47 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 5 Nov 2018 19:12:21 -0800 Subject: [PATCH 0604/1650] Add an SSSE3 implementation of qt_memfill24 Brought to you by the PSHUFB instruction, introduced in SSSE3 (implementation also uses PALIGNR just because we can). The tail functionality makes use of the fact that the low half of "mval2" ends in the correct content, so we overwrite up to 8 bytes close to the end. Change-Id: Iba4b5c183776497d8ee1fffd15646a620829c335 Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qdrawhelper.cpp | 9 ++++ src/gui/painting/qdrawhelper_ssse3.cpp | 68 +++++++++++++++++++++++++- 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 95d14a4500..9ef210cc68 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -6268,8 +6268,17 @@ void qt_memfill64(quint64 *dest, quint64 color, qsizetype count) } #endif +#if defined(QT_COMPILER_SUPPORTS_SSSE3) && defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && !defined(Q_CC_CLANG) +__attribute__((optimize("no-tree-vectorize"))) +#endif void qt_memfill24(quint24 *dest, quint24 color, qsizetype count) { +# ifdef QT_COMPILER_SUPPORTS_SSSE3 + extern void qt_memfill24_ssse3(quint24 *, quint24, qsizetype); + if (qCpuHasFeature(SSSE3)) + return qt_memfill24_ssse3(dest, color, count); +# endif + const quint32 v = color; quint24 *end = dest + count; diff --git a/src/gui/painting/qdrawhelper_ssse3.cpp b/src/gui/painting/qdrawhelper_ssse3.cpp index 0891cff8b8..35d61c3e6c 100644 --- a/src/gui/painting/qdrawhelper_ssse3.cpp +++ b/src/gui/painting/qdrawhelper_ssse3.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2018 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -188,6 +189,71 @@ const uint * QT_FASTCALL qt_fetchUntransformed_888_ssse3(uint *buffer, const Ope return buffer; } +void qt_memfill24_ssse3(quint24 *dest, quint24 color, qsizetype count) +{ + // LCM of 12 and 16 bytes is 48 bytes (16 px) + quint32 v = color; + __m128i m = _mm_cvtsi32_si128(v); + quint24 *end = dest + count; + + constexpr uchar x = 2, y = 1, z = 0; + Q_DECL_ALIGN(__m128i) static const uchar + shuffleMask[16 + 1] = { x, y, z, x, y, z, x, y, z, x, y, z, x, y, z, x, y }; + + __m128i mval1 = _mm_shuffle_epi8(m, _mm_load_si128(reinterpret_cast(shuffleMask))); + __m128i mval2 = _mm_shuffle_epi8(m, _mm_loadu_si128(reinterpret_cast(shuffleMask + 1))); + __m128i mval3 = _mm_alignr_epi8(mval2, mval1, 2); + + for ( ; dest + 16 <= end; dest += 16) { +#ifdef __AVX__ + // Store using 32-byte AVX instruction + __m256 mval12 = _mm256_castps128_ps256(_mm_castsi128_ps(mval1)); + mval12 = _mm256_insertf128_ps(mval12, _mm_castsi128_ps(mval2), 1); + _mm256_storeu_ps(reinterpret_cast(dest), mval12); +#else + _mm_storeu_si128(reinterpret_cast<__m128i *>(dest) + 0, mval1); + _mm_storeu_si128(reinterpret_cast<__m128i *>(dest) + 1, mval2); +#endif + _mm_storeu_si128(reinterpret_cast<__m128i *>(dest) + 2, mval3); + } + + if (count < 3) { + if (count > 1) + end[-2] = v; + if (count) + end[-1] = v; + return; + } + + // less than 16px/48B left + uchar *ptr = reinterpret_cast(dest); + uchar *ptr_end = reinterpret_cast(end); + qptrdiff left = ptr_end - ptr; + if (left >= 24) { + // 8px/24B or more left + _mm_storeu_si128(reinterpret_cast<__m128i *>(ptr) + 0, mval1); + _mm_storel_epi64(reinterpret_cast<__m128i *>(ptr) + 1, mval2); + ptr += 24; + left -= 24; + } + + // less than 8px/24B left + + if (left >= 16) { + // but more than 5px/15B left + _mm_storeu_si128(reinterpret_cast<__m128i *>(ptr) , mval1); + } else if (left >= 8) { + // but more than 2px/6B left + _mm_storel_epi64(reinterpret_cast<__m128i *>(ptr), mval1); + } + + if (left) { + // 1 or 2px left + // store 8 bytes ending with the right values (will overwrite a bit) + _mm_storel_epi64(reinterpret_cast<__m128i *>(ptr_end - 8), mval2); + } +} + QT_END_NAMESPACE #endif // QT_COMPILER_SUPPORTS_SSSE3 From 58f2aa907f63bd0be61b2b6e55511c0867b42683 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 11 Nov 2018 18:57:12 -0800 Subject: [PATCH 0605/1650] Work around GCC bug in generating 64-bit population of SSE register We know what code we want it to generate, so I just replaced the _mm_set1_epi64x() with the code we want it to generate. Except that GCC sees through and tries to "optimize" my code... so that asm() statement makes it separate the two operations. This generates optimal code for both 32- and 64-bit. 64-bit: vmovq %rdi, %xmm0 vpbroadcastq %xmm0, %ymm0 32-bit: vmovq 8(%esp), %xmm0 vpbroadcastq %xmm0, %ymm0 See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80820 and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87976 Change-Id: I42a48bd64ccc41aebf84fffd15664109b97fe42b Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qdrawhelper_avx2.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/gui/painting/qdrawhelper_avx2.cpp b/src/gui/painting/qdrawhelper_avx2.cpp index 3a37b85366..2e36f538bd 100644 --- a/src/gui/painting/qdrawhelper_avx2.cpp +++ b/src/gui/painting/qdrawhelper_avx2.cpp @@ -359,7 +359,18 @@ void Q_DECL_VECTORCALL qt_memfillXX_avx2(uchar *dest, __m256i value256, qsizetyp void qt_memfill64_avx2(quint64 *dest, quint64 value, qsizetype count) { - qt_memfillXX_avx2(reinterpret_cast(dest), _mm256_set1_epi64x(value), count * sizeof(quint64)); +#if defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && !defined(Q_CC_INTEL) + // work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80820 + __m128i value64 = _mm_set_epi64x(0, value); // _mm_cvtsi64_si128(value); +# ifdef Q_PROCESSOR_X86_64 + asm ("" : "+x" (value64)); +# endif + __m256i value256 = _mm256_broadcastq_epi64(value64); +#else + __m256i value256 = _mm256_set1_epi64x(value); +#endif + + qt_memfillXX_avx2(reinterpret_cast(dest), value256, count * sizeof(quint64)); } void qt_memfill32_avx2(quint32 *dest, quint32 value, qsizetype count) From b28502182bc0a1103029724cfd6f8465d779aae4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Wed, 25 Jul 2018 13:22:49 +0200 Subject: [PATCH 0606/1650] Handle errors in moc generate.sh script The script was happily ignoring all errors, relaying on a user reading output. Change-Id: I85edd228a40b5459c4649ab0c0bbbe3042a3abf5 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/tools/moc/util/generate.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tools/moc/util/generate.sh b/src/tools/moc/util/generate.sh index 3894be1309..5460d28924 100755 --- a/src/tools/moc/util/generate.sh +++ b/src/tools/moc/util/generate.sh @@ -27,6 +27,8 @@ ## ############################################################################# +set -ex + qmake make cat licenseheader.txt > ../keywords.cpp From 589f9f179cd0f570db22f15941625d911f6b7721 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 4 Dec 2018 12:51:12 +0100 Subject: [PATCH 0607/1650] QFileDialog: Remember last visited directory correctly QFileDialogPrivate::init() sets the working directory derived from the URL passed in, causing the lastVisitedDir to be set. This in turn prevented the restoreState() logic from setting the directory retrieved from the file. Clear lastVisitedDir in init() in case the initial URL was invalid. Fixes: QTBUG-70798 Change-Id: I19084e24eb6d469330c4dd8c50495b4996279189 Reviewed-by: Richard Moe Gustavsen --- src/widgets/dialogs/qfiledialog.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 69496dbd29..eb3479b3e0 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -2866,7 +2866,11 @@ void QFileDialogPrivate::init(const QUrl &directory, const QString &nameFilter, q->setFileMode(QFileDialog::AnyFile); if (!nameFilter.isEmpty()) q->setNameFilter(nameFilter); + // QTBUG-70798, prevent the default blocking the restore logic. + const bool dontStoreDir = !directory.isValid() && !lastVisitedDir()->isValid(); q->setDirectoryUrl(workingDirectory(directory)); + if (dontStoreDir) + lastVisitedDir()->clear(); if (directory.isLocalFile()) q->selectFile(initialSelection(directory)); else From e2093219665b02e9ac2a416412a371aeb60c7750 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 16 Oct 2018 15:29:58 +0200 Subject: [PATCH 0608/1650] Use Q_DISABLE_COPY_MOVE for private classes Change-Id: I3cfcfba892ff4a0ab4e31f308620b445162bb17b Reviewed-by: Giuseppe D'Angelo --- src/corelib/io/qabstractfileengine_p.h | 4 ++-- src/corelib/io/qfilesystemiterator_p.h | 2 +- src/corelib/io/qwindowspipereader_p.h | 2 +- src/corelib/io/qwindowspipewriter_p.h | 2 +- src/corelib/kernel/qjni_p.h | 2 +- src/corelib/kernel/qmetaobjectbuilder_p.h | 2 +- src/corelib/kernel/qobject_p.h | 2 +- src/corelib/kernel/qobjectdefs_impl.h | 2 +- src/corelib/kernel/qppsobject_p.h | 2 +- src/corelib/mimetypes/qmimedatabase_p.h | 2 +- src/corelib/mimetypes/qmimetypeparser_p.h | 2 +- src/corelib/serialization/qjson_p.h | 2 +- src/corelib/statemachine/qsignaleventgenerator_p.h | 2 +- src/corelib/tools/qcollator_p.h | 4 ++-- src/corelib/tools/qfreelist_p.h | 2 +- src/dbus/qdbusargument_p.h | 4 ++-- src/dbus/qdbusconnection_p.h | 2 +- src/gui/image/qpaintengine_pic_p.h | 2 +- src/gui/image/qpixmap_win.cpp | 2 +- src/gui/kernel/qdnd_p.h | 2 +- src/gui/kernel/qkeymapper_p.h | 2 +- src/gui/kernel/qopenglcontext_p.h | 2 +- src/gui/kernel/qwindowsysteminterface_p.h | 2 +- src/gui/opengl/qopenglcustomshaderstage_p.h | 2 +- src/gui/opengl/qopenglpaintengine_p.h | 2 +- src/gui/painting/qdatabuffer_p.h | 2 +- src/gui/painting/qpainterpath_p.h | 2 +- src/gui/painting/qpathclipper_p.h | 2 +- src/gui/painting/qvectorpath_p.h | 2 +- src/gui/text/qfont_p.h | 2 +- src/gui/text/qtextdocumentfragment_p.h | 2 +- src/gui/text/qtextformat_p.h | 2 +- src/gui/text/qzipreader_p.h | 2 +- src/gui/text/qzipwriter_p.h | 2 +- src/network/access/http2/bitstreams_p.h | 2 +- src/network/access/http2/hpacktable_p.h | 2 +- src/network/access/qftp_p.h | 2 +- src/network/access/qhstsstore_p.h | 2 +- src/network/access/qhttpnetworkconnection_p.h | 2 +- src/network/bearer/qnetworkconfiguration_p.h | 2 +- src/network/kernel/qnetworkproxy_win.cpp | 4 ++-- src/network/socket/qabstractsocketengine_p.h | 2 +- src/network/socket/qhttpsocketengine_p.h | 2 +- src/network/socket/qnativesocketengine_p.h | 2 +- src/network/socket/qnativesocketengine_winrt_p.h | 2 +- src/network/socket/qsocks5socketengine_p.h | 2 +- src/network/ssl/qsslkey_p.h | 2 +- src/network/ssl/qsslsocket_mac.cpp | 2 +- src/network/ssl/qsslsocket_mac_p.h | 4 ++-- src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h | 2 +- src/opengl/qgraphicsshadereffect_p.h | 2 +- src/platformsupport/devicediscovery/qdevicediscovery_p.h | 2 +- .../fontdatabases/windows/qwindowsfontdatabase_p.h | 4 ++-- .../fontdatabases/windows/qwindowsfontengine_p.h | 2 +- .../windows/qwindowsfontenginedirectwrite.cpp | 2 +- .../windows/qwindowsfontenginedirectwrite_p.h | 2 +- .../fontdatabases/windows/qwindowsnativeimage_p.h | 2 +- .../input/evdevkeyboard/qevdevkeyboardhandler_p.h | 2 +- .../platforms/xcb/nativepainting/qpaintengine_x11_p.h | 2 +- src/plugins/platforms/xcb/qxcbsessionmanager.h | 2 -- .../xdgdesktopportal/qxdgdesktopportaltheme.h | 2 +- src/plugins/printsupport/cups/qcupsprintengine_p.h | 4 ++-- src/plugins/printsupport/windows/qwindowsprintersupport.h | 2 +- src/plugins/styles/android/qandroidstyle_p.h | 2 +- src/plugins/styles/mac/qmacstyle_mac_p.h | 2 +- src/plugins/styles/windowsvista/qwindowsvistastyle_p.h | 2 +- src/plugins/styles/windowsvista/qwindowsxpstyle_p.h | 2 +- src/printsupport/widgets/qcupsjobwidget_p.h | 2 +- src/testlib/qtestcase.cpp | 7 ++++--- src/tools/uic/driver.h | 2 +- src/tools/uic/uic.h | 2 +- src/widgets/dialogs/qfiledialog_p.h | 2 +- src/widgets/dialogs/qwizard_win_p.h | 2 +- src/widgets/effects/qgraphicseffect_p.h | 2 +- src/widgets/graphicsview/qgraphicsscenebsptreeindex_p.h | 2 +- src/widgets/graphicsview/qgraphicssceneindex_p.h | 2 +- src/widgets/graphicsview/qsimplex_p.h | 2 +- src/widgets/itemviews/qcolumnviewgrip_p.h | 2 +- src/widgets/kernel/qwidget_p.h | 2 +- src/widgets/kernel/qwidgetbackingstore_p.h | 2 +- src/widgets/statemachine/qbasickeyeventtransition_p.h | 2 +- src/widgets/statemachine/qbasicmouseeventtransition_p.h | 2 +- src/widgets/styles/qdrawutil.cpp | 2 +- src/widgets/styles/qstylesheetstyle_p.h | 2 +- src/widgets/styles/qwindowsstyle_p.h | 2 +- src/widgets/widgets/qmenu_p.h | 2 +- src/widgets/widgets/qwidgetresizehandler_p.h | 2 +- src/widgets/widgets/qwidgettextcontrol_p.h | 2 +- 88 files changed, 97 insertions(+), 98 deletions(-) diff --git a/src/corelib/io/qabstractfileengine_p.h b/src/corelib/io/qabstractfileengine_p.h index 00c415b521..4a7fe7bff5 100644 --- a/src/corelib/io/qabstractfileengine_p.h +++ b/src/corelib/io/qabstractfileengine_p.h @@ -208,7 +208,7 @@ protected: QScopedPointer d_ptr; private: Q_DECLARE_PRIVATE(QAbstractFileEngine) - Q_DISABLE_COPY(QAbstractFileEngine) + Q_DISABLE_COPY_MOVE(QAbstractFileEngine) }; Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractFileEngine::FileFlags) @@ -245,7 +245,7 @@ protected: virtual QVariant entryInfo(EntryInfoType type) const; private: - Q_DISABLE_COPY(QAbstractFileEngineIterator) + Q_DISABLE_COPY_MOVE(QAbstractFileEngineIterator) friend class QDirIterator; friend class QDirIteratorPrivate; void setPath(const QString &path); diff --git a/src/corelib/io/qfilesystemiterator_p.h b/src/corelib/io/qfilesystemiterator_p.h index 081487e66e..5e4e424e69 100644 --- a/src/corelib/io/qfilesystemiterator_p.h +++ b/src/corelib/io/qfilesystemiterator_p.h @@ -96,7 +96,7 @@ private: int lastError; #endif - Q_DISABLE_COPY(QFileSystemIterator) + Q_DISABLE_COPY_MOVE(QFileSystemIterator) }; QT_END_NAMESPACE diff --git a/src/corelib/io/qwindowspipereader_p.h b/src/corelib/io/qwindowspipereader_p.h index e52aa4c33d..c757753c9c 100644 --- a/src/corelib/io/qwindowspipereader_p.h +++ b/src/corelib/io/qwindowspipereader_p.h @@ -97,7 +97,7 @@ private: class Overlapped : public OVERLAPPED { - Q_DISABLE_COPY(Overlapped) + Q_DISABLE_COPY_MOVE(Overlapped) public: explicit Overlapped(QWindowsPipeReader *reader); void clear(); diff --git a/src/corelib/io/qwindowspipewriter_p.h b/src/corelib/io/qwindowspipewriter_p.h index d6671c3f27..6c269e86b7 100644 --- a/src/corelib/io/qwindowspipewriter_p.h +++ b/src/corelib/io/qwindowspipewriter_p.h @@ -134,7 +134,7 @@ private: class Overlapped : public OVERLAPPED { - Q_DISABLE_COPY(Overlapped) + Q_DISABLE_COPY_MOVE(Overlapped) public: explicit Overlapped(QWindowsPipeWriter *pipeWriter); void clear(); diff --git a/src/corelib/kernel/qjni_p.h b/src/corelib/kernel/qjni_p.h index 52abd51dc1..ec8525e6e1 100644 --- a/src/corelib/kernel/qjni_p.h +++ b/src/corelib/kernel/qjni_p.h @@ -76,7 +76,7 @@ public: private: friend class QAndroidJniEnvironment; - Q_DISABLE_COPY(QJNIEnvironmentPrivate) + Q_DISABLE_COPY_MOVE(QJNIEnvironmentPrivate) JNIEnv *jniEnv; }; diff --git a/src/corelib/kernel/qmetaobjectbuilder_p.h b/src/corelib/kernel/qmetaobjectbuilder_p.h index 115ec835aa..6100835bad 100644 --- a/src/corelib/kernel/qmetaobjectbuilder_p.h +++ b/src/corelib/kernel/qmetaobjectbuilder_p.h @@ -184,7 +184,7 @@ public: #endif private: - Q_DISABLE_COPY(QMetaObjectBuilder) + Q_DISABLE_COPY_MOVE(QMetaObjectBuilder) QMetaObjectBuilderPrivate *d; diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 9c6724d8ab..a762e6f529 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -407,7 +407,7 @@ private: class QBoolBlocker { - Q_DISABLE_COPY(QBoolBlocker) + Q_DISABLE_COPY_MOVE(QBoolBlocker) public: explicit inline QBoolBlocker(bool &b, bool value=true):block(b), reset(b){block = value;} inline ~QBoolBlocker(){block = reset; } diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h index 8afff1fb98..aa6bd84e95 100644 --- a/src/corelib/kernel/qobjectdefs_impl.h +++ b/src/corelib/kernel/qobjectdefs_impl.h @@ -395,7 +395,7 @@ namespace QtPrivate { protected: ~QSlotObjectBase() {} private: - Q_DISABLE_COPY(QSlotObjectBase) + Q_DISABLE_COPY_MOVE(QSlotObjectBase) }; // implementation of QSlotObjectBase for which the slot is a pointer to member function of a QObject diff --git a/src/corelib/kernel/qppsobject_p.h b/src/corelib/kernel/qppsobject_p.h index c7b99c8e42..a4649918fc 100644 --- a/src/corelib/kernel/qppsobject_p.h +++ b/src/corelib/kernel/qppsobject_p.h @@ -119,7 +119,7 @@ Q_SIGNALS: private: Q_DECLARE_PRIVATE(QPpsObject) - Q_DISABLE_COPY(QPpsObject) + Q_DISABLE_COPY_MOVE(QPpsObject) }; QT_END_NAMESPACE diff --git a/src/corelib/mimetypes/qmimedatabase_p.h b/src/corelib/mimetypes/qmimedatabase_p.h index 7bc1d41c4d..d9cf446d44 100644 --- a/src/corelib/mimetypes/qmimedatabase_p.h +++ b/src/corelib/mimetypes/qmimedatabase_p.h @@ -74,7 +74,7 @@ class QMimeProviderBase; class QMimeDatabasePrivate { public: - Q_DISABLE_COPY(QMimeDatabasePrivate) + Q_DISABLE_COPY_MOVE(QMimeDatabasePrivate) QMimeDatabasePrivate(); ~QMimeDatabasePrivate(); diff --git a/src/corelib/mimetypes/qmimetypeparser_p.h b/src/corelib/mimetypes/qmimetypeparser_p.h index 6e3f5fd556..d6a1444592 100644 --- a/src/corelib/mimetypes/qmimetypeparser_p.h +++ b/src/corelib/mimetypes/qmimetypeparser_p.h @@ -64,7 +64,7 @@ class QIODevice; class QMimeTypeParserBase { - Q_DISABLE_COPY(QMimeTypeParserBase) + Q_DISABLE_COPY_MOVE(QMimeTypeParserBase) public: QMimeTypeParserBase() {} diff --git a/src/corelib/serialization/qjson_p.h b/src/corelib/serialization/qjson_p.h index feba1faac6..40b2414e4a 100644 --- a/src/corelib/serialization/qjson_p.h +++ b/src/corelib/serialization/qjson_p.h @@ -746,7 +746,7 @@ public: bool valid() const; private: - Q_DISABLE_COPY(Data) + Q_DISABLE_COPY_MOVE(Data) }; } diff --git a/src/corelib/statemachine/qsignaleventgenerator_p.h b/src/corelib/statemachine/qsignaleventgenerator_p.h index 271f6317bd..72592b8731 100644 --- a/src/corelib/statemachine/qsignaleventgenerator_p.h +++ b/src/corelib/statemachine/qsignaleventgenerator_p.h @@ -71,7 +71,7 @@ private: void execute(void **_a); private: - Q_DISABLE_COPY(QSignalEventGenerator) + Q_DISABLE_COPY_MOVE(QSignalEventGenerator) }; QT_END_NAMESPACE diff --git a/src/corelib/tools/qcollator_p.h b/src/corelib/tools/qcollator_p.h index e89c08447c..321e846884 100644 --- a/src/corelib/tools/qcollator_p.h +++ b/src/corelib/tools/qcollator_p.h @@ -121,7 +121,7 @@ public: void cleanup(); private: - Q_DISABLE_COPY(QCollatorPrivate) + Q_DISABLE_COPY_MOVE(QCollatorPrivate) }; class QCollatorSortKeyPrivate : public QSharedData @@ -138,7 +138,7 @@ public: CollatorKeyType m_key; private: - Q_DISABLE_COPY(QCollatorSortKeyPrivate) + Q_DISABLE_COPY_MOVE(QCollatorSortKeyPrivate) }; diff --git a/src/corelib/tools/qfreelist_p.h b/src/corelib/tools/qfreelist_p.h index 2f98cf5cc1..63be0952ff 100644 --- a/src/corelib/tools/qfreelist_p.h +++ b/src/corelib/tools/qfreelist_p.h @@ -187,7 +187,7 @@ class QFreeList QAtomicInt _next; // QFreeList is not copyable - Q_DISABLE_COPY(QFreeList) + Q_DISABLE_COPY_MOVE(QFreeList) public: Q_DECL_CONSTEXPR inline QFreeList(); diff --git a/src/dbus/qdbusargument_p.h b/src/dbus/qdbusargument_p.h index 559f8b1186..b678b9606f 100644 --- a/src/dbus/qdbusargument_p.h +++ b/src/dbus/qdbusargument_p.h @@ -155,7 +155,7 @@ public: bool skipSignature; private: - Q_DISABLE_COPY(QDBusMarshaller) + Q_DISABLE_COPY_MOVE(QDBusMarshaller) }; class QDBusDemarshaller: public QDBusArgumentPrivate @@ -208,7 +208,7 @@ public: QDBusDemarshaller *parent; private: - Q_DISABLE_COPY(QDBusDemarshaller) + Q_DISABLE_COPY_MOVE(QDBusDemarshaller) QString toStringUnchecked(); QDBusObjectPath toObjectPathUnchecked(); QDBusSignature toSignatureUnchecked(); diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index 84ce21092a..7769b9ea71 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -94,7 +94,7 @@ class QDBusServer; class QDBusErrorInternal { mutable DBusError error; - Q_DISABLE_COPY(QDBusErrorInternal) + Q_DISABLE_COPY_MOVE(QDBusErrorInternal) public: inline QDBusErrorInternal() { q_dbus_error_init(&error); } inline ~QDBusErrorInternal() { q_dbus_error_free(&error); } diff --git a/src/gui/image/qpaintengine_pic_p.h b/src/gui/image/qpaintengine_pic_p.h index c3044796ad..c9e4b43197 100644 --- a/src/gui/image/qpaintengine_pic_p.h +++ b/src/gui/image/qpaintengine_pic_p.h @@ -103,7 +103,7 @@ protected: QPicturePaintEngine(QPaintEnginePrivate &dptr); private: - Q_DISABLE_COPY(QPicturePaintEngine) + Q_DISABLE_COPY_MOVE(QPicturePaintEngine) void writeCmdLength(int pos, const QRectF &r, bool corr); }; diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp index b8d13ac092..68d204d76e 100644 --- a/src/gui/image/qpixmap_win.cpp +++ b/src/gui/image/qpixmap_win.cpp @@ -210,7 +210,7 @@ static QImage copyImageData(const BITMAPINFOHEADER &header, const RGBQUAD *color class DisplayHdc { - Q_DISABLE_COPY(DisplayHdc) + Q_DISABLE_COPY_MOVE(DisplayHdc) public: DisplayHdc() : m_displayDc(GetDC(nullptr)) {} ~DisplayHdc() { ReleaseDC(nullptr, m_displayDc); } diff --git a/src/gui/kernel/qdnd_p.h b/src/gui/kernel/qdnd_p.h index 5f6db07987..8f8eb03f87 100644 --- a/src/gui/kernel/qdnd_p.h +++ b/src/gui/kernel/qdnd_p.h @@ -110,7 +110,7 @@ private: QDrag *m_object; static QDragManager *m_instance; - Q_DISABLE_COPY(QDragManager) + Q_DISABLE_COPY_MOVE(QDragManager) }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qkeymapper_p.h b/src/gui/kernel/qkeymapper_p.h index aeec7b7414..8364557020 100644 --- a/src/gui/kernel/qkeymapper_p.h +++ b/src/gui/kernel/qkeymapper_p.h @@ -76,7 +76,7 @@ public: private: friend QKeyMapperPrivate *qt_keymapper_private(); Q_DECLARE_PRIVATE(QKeyMapper) - Q_DISABLE_COPY(QKeyMapper) + Q_DISABLE_COPY_MOVE(QKeyMapper) }; struct KeyboardLayoutItem; diff --git a/src/gui/kernel/qopenglcontext_p.h b/src/gui/kernel/qopenglcontext_p.h index 1cb7390687..2849d0c58e 100644 --- a/src/gui/kernel/qopenglcontext_p.h +++ b/src/gui/kernel/qopenglcontext_p.h @@ -97,7 +97,7 @@ private: friend class QOpenGLContextGroupPrivate; friend class QOpenGLMultiGroupSharedResource; - Q_DISABLE_COPY(QOpenGLSharedResource) + Q_DISABLE_COPY_MOVE(QOpenGLSharedResource) }; class Q_GUI_EXPORT QOpenGLSharedResourceGuard : public QOpenGLSharedResource diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h index 9cb4e191cc..563ca8f922 100644 --- a/src/gui/kernel/qwindowsysteminterface_p.h +++ b/src/gui/kernel/qwindowsysteminterface_p.h @@ -508,7 +508,7 @@ public: } } private: - Q_DISABLE_COPY(WindowSystemEventList) + Q_DISABLE_COPY_MOVE(WindowSystemEventList) }; static WindowSystemEventList windowSystemEventQueue; diff --git a/src/gui/opengl/qopenglcustomshaderstage_p.h b/src/gui/opengl/qopenglcustomshaderstage_p.h index f4a71af88e..ce3e9efd23 100644 --- a/src/gui/opengl/qopenglcustomshaderstage_p.h +++ b/src/gui/opengl/qopenglcustomshaderstage_p.h @@ -80,7 +80,7 @@ protected: private: QOpenGLCustomShaderStagePrivate* d_ptr; - Q_DISABLE_COPY(QOpenGLCustomShaderStage) + Q_DISABLE_COPY_MOVE(QOpenGLCustomShaderStage) }; diff --git a/src/gui/opengl/qopenglpaintengine_p.h b/src/gui/opengl/qopenglpaintengine_p.h index 0541ce6168..15ac240b89 100644 --- a/src/gui/opengl/qopenglpaintengine_p.h +++ b/src/gui/opengl/qopenglpaintengine_p.h @@ -166,7 +166,7 @@ public: bool shouldDrawCachedGlyphs(QFontEngine *, const QTransform &) const override; private: - Q_DISABLE_COPY(QOpenGL2PaintEngineEx) + Q_DISABLE_COPY_MOVE(QOpenGL2PaintEngineEx) friend class QOpenGLEngineShaderManager; }; diff --git a/src/gui/painting/qdatabuffer_p.h b/src/gui/painting/qdatabuffer_p.h index 7cac2ac358..28d5f6d6c5 100644 --- a/src/gui/painting/qdatabuffer_p.h +++ b/src/gui/painting/qdatabuffer_p.h @@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE template class QDataBuffer { - Q_DISABLE_COPY(QDataBuffer) + Q_DISABLE_COPY_MOVE(QDataBuffer) public: QDataBuffer(int res) { diff --git a/src/gui/painting/qpainterpath_p.h b/src/gui/painting/qpainterpath_p.h index 92d9a4ea66..aab318bcab 100644 --- a/src/gui/painting/qpainterpath_p.h +++ b/src/gui/painting/qpainterpath_p.h @@ -157,7 +157,7 @@ public: QVectorPath path; private: - Q_DISABLE_COPY(QVectorPathConverter) + Q_DISABLE_COPY_MOVE(QVectorPathConverter) }; class QPainterPathData : public QPainterPathPrivate diff --git a/src/gui/painting/qpathclipper_p.h b/src/gui/painting/qpathclipper_p.h index 64e684e1ad..c25a479807 100644 --- a/src/gui/painting/qpathclipper_p.h +++ b/src/gui/painting/qpathclipper_p.h @@ -86,7 +86,7 @@ public: static QPainterPath intersect(const QPainterPath &path, const QRectF &rect); private: - Q_DISABLE_COPY(QPathClipper) + Q_DISABLE_COPY_MOVE(QPathClipper) enum ClipperMode { ClipMode, // do the full clip diff --git a/src/gui/painting/qvectorpath_p.h b/src/gui/painting/qvectorpath_p.h index 8580598784..1b649a5d2a 100644 --- a/src/gui/painting/qvectorpath_p.h +++ b/src/gui/painting/qvectorpath_p.h @@ -196,7 +196,7 @@ public: private: - Q_DISABLE_COPY(QVectorPath) + Q_DISABLE_COPY_MOVE(QVectorPath) const QPainterPath::ElementType *m_elements; const qreal *m_points; diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h index f8835dd513..e86ec31e47 100644 --- a/src/gui/text/qfont_p.h +++ b/src/gui/text/qfont_p.h @@ -165,7 +165,7 @@ public: QFontEngine *engines[QChar::ScriptCount]; private: - Q_DISABLE_COPY(QFontEngineData) + Q_DISABLE_COPY_MOVE(QFontEngineData) }; diff --git a/src/gui/text/qtextdocumentfragment_p.h b/src/gui/text/qtextdocumentfragment_p.h index 02a6a429fa..de01a02fbb 100644 --- a/src/gui/text/qtextdocumentfragment_p.h +++ b/src/gui/text/qtextdocumentfragment_p.h @@ -109,7 +109,7 @@ public: uint importedFromPlainText : 1; private: - Q_DISABLE_COPY(QTextDocumentFragmentPrivate) + Q_DISABLE_COPY_MOVE(QTextDocumentFragmentPrivate) }; #ifndef QT_NO_TEXTHTMLPARSER diff --git a/src/gui/text/qtextformat_p.h b/src/gui/text/qtextformat_p.h index 3557c17a97..001a243e84 100644 --- a/src/gui/text/qtextformat_p.h +++ b/src/gui/text/qtextformat_p.h @@ -104,7 +104,7 @@ public: private: QFont defaultFnt; - Q_DISABLE_COPY(QTextFormatCollection) + Q_DISABLE_COPY_MOVE(QTextFormatCollection) }; QT_END_NAMESPACE diff --git a/src/gui/text/qzipreader_p.h b/src/gui/text/qzipreader_p.h index eed6ee6a62..378072b366 100644 --- a/src/gui/text/qzipreader_p.h +++ b/src/gui/text/qzipreader_p.h @@ -116,7 +116,7 @@ public: private: QZipReaderPrivate *d; - Q_DISABLE_COPY(QZipReader) + Q_DISABLE_COPY_MOVE(QZipReader) }; Q_DECLARE_TYPEINFO(QZipReader::FileInfo, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(QZipReader::Status, Q_PRIMITIVE_TYPE); diff --git a/src/gui/text/qzipwriter_p.h b/src/gui/text/qzipwriter_p.h index 433bbab31e..b3bb5929cf 100644 --- a/src/gui/text/qzipwriter_p.h +++ b/src/gui/text/qzipwriter_p.h @@ -108,7 +108,7 @@ public: void close(); private: QZipWriterPrivate *d; - Q_DISABLE_COPY(QZipWriter) + Q_DISABLE_COPY_MOVE(QZipWriter) }; QT_END_NAMESPACE diff --git a/src/network/access/http2/bitstreams_p.h b/src/network/access/http2/bitstreams_p.h index 9eba319dc2..ca272062a6 100644 --- a/src/network/access/http2/bitstreams_p.h +++ b/src/network/access/http2/bitstreams_p.h @@ -89,7 +89,7 @@ public: void clear(); private: - Q_DISABLE_COPY(BitOStream); + Q_DISABLE_COPY_MOVE(BitOStream); std::vector &buffer; quint64 bitsSet; diff --git a/src/network/access/http2/hpacktable_p.h b/src/network/access/http2/hpacktable_p.h index aaea89b986..5eaccbffce 100644 --- a/src/network/access/http2/hpacktable_p.h +++ b/src/network/access/http2/hpacktable_p.h @@ -227,7 +227,7 @@ private: mutable QByteArray dummyDst; - Q_DISABLE_COPY(FieldLookupTable); + Q_DISABLE_COPY_MOVE(FieldLookupTable); }; } diff --git a/src/network/access/qftp_p.h b/src/network/access/qftp_p.h index bba1f9b09d..0516c3d1f9 100644 --- a/src/network/access/qftp_p.h +++ b/src/network/access/qftp_p.h @@ -158,7 +158,7 @@ Q_SIGNALS: void done(bool); private: - Q_DISABLE_COPY(QFtp) + Q_DISABLE_COPY_MOVE(QFtp) Q_DECLARE_PRIVATE(QFtp) Q_PRIVATE_SLOT(d_func(), void _q_startNextCommand()) diff --git a/src/network/access/qhstsstore_p.h b/src/network/access/qhstsstore_p.h index e82596b250..5338d15592 100644 --- a/src/network/access/qhstsstore_p.h +++ b/src/network/access/qhstsstore_p.h @@ -87,7 +87,7 @@ private: QVector observedPolicies; QSettings store; - Q_DISABLE_COPY(QHstsStore) + Q_DISABLE_COPY_MOVE(QHstsStore) }; QT_END_NAMESPACE diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h index 91827a6eb1..da54fbac2c 100644 --- a/src/network/access/qhttpnetworkconnection_p.h +++ b/src/network/access/qhttpnetworkconnection_p.h @@ -156,7 +156,7 @@ public: private: Q_DECLARE_PRIVATE(QHttpNetworkConnection) - Q_DISABLE_COPY(QHttpNetworkConnection) + Q_DISABLE_COPY_MOVE(QHttpNetworkConnection) friend class QHttpThreadDelegate; friend class QHttpNetworkReply; friend class QHttpNetworkReplyPrivate; diff --git a/src/network/bearer/qnetworkconfiguration_p.h b/src/network/bearer/qnetworkconfiguration_p.h index 2fdb490ea0..1b1ece39b7 100644 --- a/src/network/bearer/qnetworkconfiguration_p.h +++ b/src/network/bearer/qnetworkconfiguration_p.h @@ -97,7 +97,7 @@ public: static Q_CONSTEXPR int DefaultTimeout = 30000; private: - Q_DISABLE_COPY(QNetworkConfigurationPrivate) + Q_DISABLE_COPY_MOVE(QNetworkConfigurationPrivate) }; QT_END_NAMESPACE diff --git a/src/network/kernel/qnetworkproxy_win.cpp b/src/network/kernel/qnetworkproxy_win.cpp index db51732bd3..56397814b0 100644 --- a/src/network/kernel/qnetworkproxy_win.cpp +++ b/src/network/kernel/qnetworkproxy_win.cpp @@ -370,7 +370,7 @@ static QList parseServerList(const QNetworkProxyQuery &query, con #if !defined(Q_OS_WINRT) namespace { class QRegistryWatcher { - Q_DISABLE_COPY(QRegistryWatcher) + Q_DISABLE_COPY_MOVE(QRegistryWatcher) public: QRegistryWatcher() = default; @@ -425,7 +425,7 @@ private: class QWindowsSystemProxy { - Q_DISABLE_COPY(QWindowsSystemProxy) + Q_DISABLE_COPY_MOVE(QWindowsSystemProxy) public: QWindowsSystemProxy(); ~QWindowsSystemProxy(); diff --git a/src/network/socket/qabstractsocketengine_p.h b/src/network/socket/qabstractsocketengine_p.h index b15dd73c96..8eebb06a4d 100644 --- a/src/network/socket/qabstractsocketengine_p.h +++ b/src/network/socket/qabstractsocketengine_p.h @@ -215,7 +215,7 @@ protected: private: Q_DECLARE_PRIVATE(QAbstractSocketEngine) - Q_DISABLE_COPY(QAbstractSocketEngine) + Q_DISABLE_COPY_MOVE(QAbstractSocketEngine) }; class QAbstractSocketEnginePrivate : public QObjectPrivate diff --git a/src/network/socket/qhttpsocketengine_p.h b/src/network/socket/qhttpsocketengine_p.h index cb7798694a..bbcc09eee9 100644 --- a/src/network/socket/qhttpsocketengine_p.h +++ b/src/network/socket/qhttpsocketengine_p.h @@ -160,7 +160,7 @@ private: bool readHttpHeader(); Q_DECLARE_PRIVATE(QHttpSocketEngine) - Q_DISABLE_COPY(QHttpSocketEngine) + Q_DISABLE_COPY_MOVE(QHttpSocketEngine) }; diff --git a/src/network/socket/qnativesocketengine_p.h b/src/network/socket/qnativesocketengine_p.h index aa61b74823..2292566265 100644 --- a/src/network/socket/qnativesocketengine_p.h +++ b/src/network/socket/qnativesocketengine_p.h @@ -196,7 +196,7 @@ public Q_SLOTS: private: Q_DECLARE_PRIVATE(QNativeSocketEngine) - Q_DISABLE_COPY(QNativeSocketEngine) + Q_DISABLE_COPY_MOVE(QNativeSocketEngine) }; class QSocketNotifier; diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h index 6688bfe35c..e1fe58bb97 100644 --- a/src/network/socket/qnativesocketengine_winrt_p.h +++ b/src/network/socket/qnativesocketengine_winrt_p.h @@ -188,7 +188,7 @@ private slots: private: Q_DECLARE_PRIVATE(QNativeSocketEngine) - Q_DISABLE_COPY(QNativeSocketEngine) + Q_DISABLE_COPY_MOVE(QNativeSocketEngine) }; class QNativeSocketEnginePrivate : public QAbstractSocketEnginePrivate diff --git a/src/network/socket/qsocks5socketengine_p.h b/src/network/socket/qsocks5socketengine_p.h index 1942eff4ca..ef9d771753 100644 --- a/src/network/socket/qsocks5socketengine_p.h +++ b/src/network/socket/qsocks5socketengine_p.h @@ -127,7 +127,7 @@ public: private: Q_DECLARE_PRIVATE(QSocks5SocketEngine) - Q_DISABLE_COPY(QSocks5SocketEngine) + Q_DISABLE_COPY_MOVE(QSocks5SocketEngine) Q_PRIVATE_SLOT(d_func(), void _q_controlSocketConnected()) Q_PRIVATE_SLOT(d_func(), void _q_controlSocketReadNotification()) Q_PRIVATE_SLOT(d_func(), void _q_controlSocketError(QAbstractSocket::SocketError)) diff --git a/src/network/ssl/qsslkey_p.h b/src/network/ssl/qsslkey_p.h index 310553cab2..06403b5479 100644 --- a/src/network/ssl/qsslkey_p.h +++ b/src/network/ssl/qsslkey_p.h @@ -130,7 +130,7 @@ public: QAtomicInt ref; private: - Q_DISABLE_COPY(QSslKeyPrivate) + Q_DISABLE_COPY_MOVE(QSslKeyPrivate) }; QT_END_NAMESPACE diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp index 66623cebef..f92eaf872b 100644 --- a/src/network/ssl/qsslsocket_mac.cpp +++ b/src/network/ssl/qsslsocket_mac.cpp @@ -89,7 +89,7 @@ struct EphemeralSecKeychain ~EphemeralSecKeychain(); SecKeychainRef keychain = nullptr; - Q_DISABLE_COPY(EphemeralSecKeychain) + Q_DISABLE_COPY_MOVE(EphemeralSecKeychain) }; EphemeralSecKeychain::EphemeralSecKeychain() diff --git a/src/network/ssl/qsslsocket_mac_p.h b/src/network/ssl/qsslsocket_mac_p.h index e37171e56a..48aca964a1 100644 --- a/src/network/ssl/qsslsocket_mac_p.h +++ b/src/network/ssl/qsslsocket_mac_p.h @@ -75,7 +75,7 @@ public: private: SSLContextRef context; - Q_DISABLE_COPY(QSecureTransportContext) + Q_DISABLE_COPY_MOVE(QSecureTransportContext) }; class QSslSocketBackendPrivate : public QSslSocketPrivate @@ -129,7 +129,7 @@ private: QSecureTransportContext context; bool renegotiating = false; - Q_DISABLE_COPY(QSslSocketBackendPrivate) + Q_DISABLE_COPY_MOVE(QSslSocketBackendPrivate) }; QT_END_NAMESPACE diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index d1ed621790..abf5b8ea48 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -160,7 +160,7 @@ public: void setTranslateZ(GLfloat z); private: - Q_DISABLE_COPY(QGL2PaintEngineEx) + Q_DISABLE_COPY_MOVE(QGL2PaintEngineEx) }; class QGL2PaintEngineExPrivate : public QPaintEngineExPrivate, protected QOpenGLExtensions diff --git a/src/opengl/qgraphicsshadereffect_p.h b/src/opengl/qgraphicsshadereffect_p.h index 9efcecd25f..1a32f24d70 100644 --- a/src/opengl/qgraphicsshadereffect_p.h +++ b/src/opengl/qgraphicsshadereffect_p.h @@ -80,7 +80,7 @@ protected: private: Q_DECLARE_PRIVATE(QGraphicsShaderEffect) - Q_DISABLE_COPY(QGraphicsShaderEffect) + Q_DISABLE_COPY_MOVE(QGraphicsShaderEffect) friend class QGLCustomShaderEffectStage; }; diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_p.h b/src/platformsupport/devicediscovery/qdevicediscovery_p.h index e3c22b0b37..b1ce14b5c3 100644 --- a/src/platformsupport/devicediscovery/qdevicediscovery_p.h +++ b/src/platformsupport/devicediscovery/qdevicediscovery_p.h @@ -96,7 +96,7 @@ signals: protected: QDeviceDiscovery(QDeviceTypes types, QObject *parent) : QObject(parent), m_types(types) { } - Q_DISABLE_COPY(QDeviceDiscovery) + Q_DISABLE_COPY_MOVE(QDeviceDiscovery) QDeviceTypes m_types; }; diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h index 9d0aa7f723..4558496e63 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h @@ -67,7 +67,7 @@ Q_DECLARE_LOGGING_CATEGORY(lcQpaFonts) class QWindowsFontEngineData { - Q_DISABLE_COPY(QWindowsFontEngineData) + Q_DISABLE_COPY_MOVE(QWindowsFontEngineData) public: QWindowsFontEngineData(); ~QWindowsFontEngineData(); @@ -85,7 +85,7 @@ public: class QWindowsFontDatabase : public QPlatformFontDatabase { - Q_DISABLE_COPY(QWindowsFontDatabase) + Q_DISABLE_COPY_MOVE(QWindowsFontDatabase) public: enum FontOptions { // Relevant bits from QWindowsIntegration::Options diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontengine_p.h b/src/platformsupport/fontdatabases/windows/qwindowsfontengine_p.h index a151cf7343..19d8b98e8a 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontengine_p.h +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontengine_p.h @@ -66,7 +66,7 @@ class QWindowsFontEngineData; class QWindowsFontEngine : public QFontEngine { - Q_DISABLE_COPY(QWindowsFontEngine) + Q_DISABLE_COPY_MOVE(QWindowsFontEngine) friend class QWindowsMultiFontEngine; public: diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp index 57c41938bc..60a5896e7b 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp @@ -69,7 +69,7 @@ namespace { class GeometrySink: public IDWriteGeometrySink { - Q_DISABLE_COPY(GeometrySink) + Q_DISABLE_COPY_MOVE(GeometrySink) public: GeometrySink(QPainterPath *path) : m_refCount(0), m_path(path) diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h index 9326f5aece..3eaf8cf3d8 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h @@ -72,7 +72,7 @@ class QWindowsFontEngineData; class QWindowsFontEngineDirectWrite : public QFontEngine { - Q_DISABLE_COPY(QWindowsFontEngineDirectWrite) + Q_DISABLE_COPY_MOVE(QWindowsFontEngineDirectWrite) public: explicit QWindowsFontEngineDirectWrite(IDWriteFontFace *directWriteFontFace, qreal pixelSize, diff --git a/src/platformsupport/fontdatabases/windows/qwindowsnativeimage_p.h b/src/platformsupport/fontdatabases/windows/qwindowsnativeimage_p.h index 6c47a527d2..ed68ac2644 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsnativeimage_p.h +++ b/src/platformsupport/fontdatabases/windows/qwindowsnativeimage_p.h @@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE class QWindowsNativeImage { - Q_DISABLE_COPY(QWindowsNativeImage) + Q_DISABLE_COPY_MOVE(QWindowsNativeImage) public: QWindowsNativeImage(int width, int height, QImage::Format format); diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h index 7c64c4febb..c5821ae3ac 100644 --- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h +++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h @@ -132,7 +132,7 @@ inline QDataStream &operator<<(QDataStream &ds, const QEvdevKeyboardMap::Composi class QFdContainer { int m_fd; - Q_DISABLE_COPY(QFdContainer); + Q_DISABLE_COPY_MOVE(QFdContainer); public: explicit QFdContainer(int fd = -1) Q_DECL_NOTHROW : m_fd(fd) {} ~QFdContainer() { reset(); } diff --git a/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11_p.h b/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11_p.h index 9b01c0a3fc..bc82351283 100644 --- a/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11_p.h +++ b/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11_p.h @@ -116,7 +116,7 @@ protected: friend GC qt_x11_get_brush_gc(QPainter *); private: - Q_DISABLE_COPY(QX11PaintEngine) + Q_DISABLE_COPY_MOVE(QX11PaintEngine) }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbsessionmanager.h b/src/plugins/platforms/xcb/qxcbsessionmanager.h index 0ad9445361..79c587b38d 100644 --- a/src/plugins/platforms/xcb/qxcbsessionmanager.h +++ b/src/plugins/platforms/xcb/qxcbsessionmanager.h @@ -85,8 +85,6 @@ public: private: QEventLoop *m_eventLoop; - - Q_DISABLE_COPY(QXcbSessionManager) }; QT_END_NAMESPACE diff --git a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.h b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.h index b72e676419..2be88bb4c0 100644 --- a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.h +++ b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.h @@ -82,7 +82,7 @@ public: private: QScopedPointer d_ptr; - Q_DISABLE_COPY(QXdgDesktopPortalTheme) + Q_DISABLE_COPY_MOVE(QXdgDesktopPortalTheme) }; QT_END_NAMESPACE diff --git a/src/plugins/printsupport/cups/qcupsprintengine_p.h b/src/plugins/printsupport/cups/qcupsprintengine_p.h index 2a1a83b9d7..c021b0c643 100644 --- a/src/plugins/printsupport/cups/qcupsprintengine_p.h +++ b/src/plugins/printsupport/cups/qcupsprintengine_p.h @@ -77,7 +77,7 @@ public: // end reimplementations QPdfPrintEngine private: - Q_DISABLE_COPY(QCupsPrintEngine) + Q_DISABLE_COPY_MOVE(QCupsPrintEngine) }; class QCupsPrintEnginePrivate : public QPdfPrintEnginePrivate @@ -91,7 +91,7 @@ public: void closePrintDevice() override; private: - Q_DISABLE_COPY(QCupsPrintEnginePrivate) + Q_DISABLE_COPY_MOVE(QCupsPrintEnginePrivate) void changePrinter(const QString &newPrinter); void setPageSize(const QPageSize &pageSize); diff --git a/src/plugins/printsupport/windows/qwindowsprintersupport.h b/src/plugins/printsupport/windows/qwindowsprintersupport.h index 4267701145..400701628e 100644 --- a/src/plugins/printsupport/windows/qwindowsprintersupport.h +++ b/src/plugins/printsupport/windows/qwindowsprintersupport.h @@ -46,7 +46,7 @@ QT_BEGIN_NAMESPACE class QWindowsPrinterSupport : public QPlatformPrinterSupport { - Q_DISABLE_COPY(QWindowsPrinterSupport) + Q_DISABLE_COPY_MOVE(QWindowsPrinterSupport) public: QWindowsPrinterSupport(); ~QWindowsPrinterSupport() override; diff --git a/src/plugins/styles/android/qandroidstyle_p.h b/src/plugins/styles/android/qandroidstyle_p.h index 3faa08afb9..6cb30a2f79 100644 --- a/src/plugins/styles/android/qandroidstyle_p.h +++ b/src/plugins/styles/android/qandroidstyle_p.h @@ -371,7 +371,7 @@ public: void unpolish(QWidget *widget); private: - Q_DISABLE_COPY(QAndroidStyle) + Q_DISABLE_COPY_MOVE(QAndroidStyle) static ItemType qtControl(QStyle::ComplexControl control); static ItemType qtControl(QStyle::ContentsType contentsType); static ItemType qtControl(QStyle::ControlElement controlElement); diff --git a/src/plugins/styles/mac/qmacstyle_mac_p.h b/src/plugins/styles/mac/qmacstyle_mac_p.h index d6874001d3..88f104cccf 100644 --- a/src/plugins/styles/mac/qmacstyle_mac_p.h +++ b/src/plugins/styles/mac/qmacstyle_mac_p.h @@ -115,7 +115,7 @@ public: const QWidget *widget = 0) const; private: - Q_DISABLE_COPY(QMacStyle) + Q_DISABLE_COPY_MOVE(QMacStyle) Q_DECLARE_PRIVATE(QMacStyle) }; diff --git a/src/plugins/styles/windowsvista/qwindowsvistastyle_p.h b/src/plugins/styles/windowsvista/qwindowsvistastyle_p.h index 0ebb0eb41a..43a2a670f8 100644 --- a/src/plugins/styles/windowsvista/qwindowsvistastyle_p.h +++ b/src/plugins/styles/windowsvista/qwindowsvistastyle_p.h @@ -99,7 +99,7 @@ public: QPalette standardPalette() const override; private: - Q_DISABLE_COPY(QWindowsVistaStyle) + Q_DISABLE_COPY_MOVE(QWindowsVistaStyle) Q_DECLARE_PRIVATE(QWindowsVistaStyle) friend class QStyleFactory; }; diff --git a/src/plugins/styles/windowsvista/qwindowsxpstyle_p.h b/src/plugins/styles/windowsvista/qwindowsxpstyle_p.h index 7e9f4ddda6..0f70105b0e 100644 --- a/src/plugins/styles/windowsvista/qwindowsxpstyle_p.h +++ b/src/plugins/styles/windowsvista/qwindowsxpstyle_p.h @@ -96,7 +96,7 @@ public: const QWidget *widget = nullptr) const override; private: - Q_DISABLE_COPY(QWindowsXPStyle) + Q_DISABLE_COPY_MOVE(QWindowsXPStyle) Q_DECLARE_PRIVATE(QWindowsXPStyle) friend class QStyleFactory; }; diff --git a/src/printsupport/widgets/qcupsjobwidget_p.h b/src/printsupport/widgets/qcupsjobwidget_p.h index 4b6b047e26..42da9c7580 100644 --- a/src/printsupport/widgets/qcupsjobwidget_p.h +++ b/src/printsupport/widgets/qcupsjobwidget_p.h @@ -113,7 +113,7 @@ private: int m_savedPriority; QCUPSSupport::JobSheets m_savedJobSheets; - Q_DISABLE_COPY(QCupsJobWidget) + Q_DISABLE_COPY_MOVE(QCupsJobWidget) }; QT_END_NAMESPACE diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index ba03384db5..9f0cdb0109 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -294,8 +294,9 @@ IOPMAssertionID powerID; #endif class TestMethods { - Q_DISABLE_COPY(TestMethods) - public: +public: + Q_DISABLE_COPY_MOVE(TestMethods) + typedef std::vector MetaMethods; explicit TestMethods(const QObject *o, const MetaMethods &m = MetaMethods()); @@ -1605,7 +1606,7 @@ FatalSignalHandler::~FatalSignalHandler() // Helper class for resolving symbol names by dynamically loading "dbghelp.dll". class DebugSymbolResolver { - Q_DISABLE_COPY(DebugSymbolResolver) + Q_DISABLE_COPY_MOVE(DebugSymbolResolver) public: struct Symbol { Symbol() : name(nullptr), address(0) {} diff --git a/src/tools/uic/driver.h b/src/tools/uic/driver.h index 8d497c39fd..3808855783 100644 --- a/src/tools/uic/driver.h +++ b/src/tools/uic/driver.h @@ -49,7 +49,7 @@ class DomButtonGroup; class Driver { - Q_DISABLE_COPY(Driver) + Q_DISABLE_COPY_MOVE(Driver) public: Driver(); virtual ~Driver(); diff --git a/src/tools/uic/uic.h b/src/tools/uic/uic.h index 17cb54515b..af5f42c6db 100644 --- a/src/tools/uic/uic.h +++ b/src/tools/uic/uic.h @@ -53,7 +53,7 @@ struct Option; class Uic { - Q_DISABLE_COPY(Uic) + Q_DISABLE_COPY_MOVE(Uic) public: Uic(Driver *driver); ~Uic(); diff --git a/src/widgets/dialogs/qfiledialog_p.h b/src/widgets/dialogs/qfiledialog_p.h index 2e49696b77..96d0c1190e 100644 --- a/src/widgets/dialogs/qfiledialog_p.h +++ b/src/widgets/dialogs/qfiledialog_p.h @@ -290,7 +290,7 @@ private: virtual void helperPrepareShow(QPlatformDialogHelper *) override; virtual void helperDone(QDialog::DialogCode, QPlatformDialogHelper *) override; - Q_DISABLE_COPY(QFileDialogPrivate) + Q_DISABLE_COPY_MOVE(QFileDialogPrivate) }; class QFileDialogLineEdit : public QLineEdit diff --git a/src/widgets/dialogs/qwizard_win_p.h b/src/widgets/dialogs/qwizard_win_p.h index d302dedaa3..02c5e52c2c 100644 --- a/src/widgets/dialogs/qwizard_win_p.h +++ b/src/widgets/dialogs/qwizard_win_p.h @@ -84,7 +84,7 @@ class QWizard; class QVistaHelper : public QObject { - Q_DISABLE_COPY(QVistaHelper) + Q_DISABLE_COPY_MOVE(QVistaHelper) public: QVistaHelper(QWizard *wizard); ~QVistaHelper() override; diff --git a/src/widgets/effects/qgraphicseffect_p.h b/src/widgets/effects/qgraphicseffect_p.h index c5c7ff5900..2f3bd2f7fd 100644 --- a/src/widgets/effects/qgraphicseffect_p.h +++ b/src/widgets/effects/qgraphicseffect_p.h @@ -88,7 +88,7 @@ protected: private: Q_DECLARE_PRIVATE(QGraphicsEffectSource) - Q_DISABLE_COPY(QGraphicsEffectSource) + Q_DISABLE_COPY_MOVE(QGraphicsEffectSource) friend class QGraphicsEffect; friend class QGraphicsEffectPrivate; friend class QGraphicsScenePrivate; diff --git a/src/widgets/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/widgets/graphicsview/qgraphicsscenebsptreeindex_p.h index b6387a2c56..eb6bbbf49b 100644 --- a/src/widgets/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/widgets/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -99,7 +99,7 @@ protected: private : Q_DECLARE_PRIVATE(QGraphicsSceneBspTreeIndex) - Q_DISABLE_COPY(QGraphicsSceneBspTreeIndex) + Q_DISABLE_COPY_MOVE(QGraphicsSceneBspTreeIndex) Q_PRIVATE_SLOT(d_func(), void _q_updateSortCache()) Q_PRIVATE_SLOT(d_func(), void _q_updateIndex()) diff --git a/src/widgets/graphicsview/qgraphicssceneindex_p.h b/src/widgets/graphicsview/qgraphicssceneindex_p.h index c86df0e209..86637e836b 100644 --- a/src/widgets/graphicsview/qgraphicssceneindex_p.h +++ b/src/widgets/graphicsview/qgraphicssceneindex_p.h @@ -115,7 +115,7 @@ protected: friend class QGraphicsItemPrivate; friend class QGraphicsSceneBspTreeIndex; private: - Q_DISABLE_COPY(QGraphicsSceneIndex) + Q_DISABLE_COPY_MOVE(QGraphicsSceneIndex) Q_DECLARE_PRIVATE(QGraphicsSceneIndex) }; diff --git a/src/widgets/graphicsview/qsimplex_p.h b/src/widgets/graphicsview/qsimplex_p.h index 2342da2437..369f2f5f82 100644 --- a/src/widgets/graphicsview/qsimplex_p.h +++ b/src/widgets/graphicsview/qsimplex_p.h @@ -150,7 +150,7 @@ struct QSimplexConstraint class QSimplex { - Q_DISABLE_COPY(QSimplex) + Q_DISABLE_COPY_MOVE(QSimplex) public: QSimplex(); ~QSimplex(); diff --git a/src/widgets/itemviews/qcolumnviewgrip_p.h b/src/widgets/itemviews/qcolumnviewgrip_p.h index 7e2793074b..5eb8012204 100644 --- a/src/widgets/itemviews/qcolumnviewgrip_p.h +++ b/src/widgets/itemviews/qcolumnviewgrip_p.h @@ -82,7 +82,7 @@ protected: private: Q_DECLARE_PRIVATE(QColumnViewGrip) - Q_DISABLE_COPY(QColumnViewGrip) + Q_DISABLE_COPY_MOVE(QColumnViewGrip) }; class QColumnViewGripPrivate : public QWidgetPrivate diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 7ebc2cd58e..1f995278f4 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -150,7 +150,7 @@ public: } private: - Q_DISABLE_COPY(QWidgetBackingStoreTracker) + Q_DISABLE_COPY_MOVE(QWidgetBackingStoreTracker) private: QWidgetBackingStore* m_ptr; diff --git a/src/widgets/kernel/qwidgetbackingstore_p.h b/src/widgets/kernel/qwidgetbackingstore_p.h index 53ccda850a..41469a04bb 100644 --- a/src/widgets/kernel/qwidgetbackingstore_p.h +++ b/src/widgets/kernel/qwidgetbackingstore_p.h @@ -305,7 +305,7 @@ private: friend class QWidget; friend class QBackingStore; - Q_DISABLE_COPY(QWidgetBackingStore) + Q_DISABLE_COPY_MOVE(QWidgetBackingStore) }; QT_END_NAMESPACE diff --git a/src/widgets/statemachine/qbasickeyeventtransition_p.h b/src/widgets/statemachine/qbasickeyeventtransition_p.h index 5007b79739..7e1b978bba 100644 --- a/src/widgets/statemachine/qbasickeyeventtransition_p.h +++ b/src/widgets/statemachine/qbasickeyeventtransition_p.h @@ -84,7 +84,7 @@ protected: void onTransition(QEvent *) override; private: - Q_DISABLE_COPY(QBasicKeyEventTransition) + Q_DISABLE_COPY_MOVE(QBasicKeyEventTransition) Q_DECLARE_PRIVATE(QBasicKeyEventTransition) }; diff --git a/src/widgets/statemachine/qbasicmouseeventtransition_p.h b/src/widgets/statemachine/qbasicmouseeventtransition_p.h index 93d2a5ec61..132e223535 100644 --- a/src/widgets/statemachine/qbasicmouseeventtransition_p.h +++ b/src/widgets/statemachine/qbasicmouseeventtransition_p.h @@ -87,7 +87,7 @@ protected: void onTransition(QEvent *) override; private: - Q_DISABLE_COPY(QBasicMouseEventTransition) + Q_DISABLE_COPY_MOVE(QBasicMouseEventTransition) Q_DECLARE_PRIVATE(QBasicMouseEventTransition) }; diff --git a/src/widgets/styles/qdrawutil.cpp b/src/widgets/styles/qdrawutil.cpp index 299dbb9f82..d30b43a679 100644 --- a/src/widgets/styles/qdrawutil.cpp +++ b/src/widgets/styles/qdrawutil.cpp @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE namespace { class PainterStateGuard { - Q_DISABLE_COPY(PainterStateGuard) + Q_DISABLE_COPY_MOVE(PainterStateGuard) public: explicit PainterStateGuard(QPainter *p) : m_painter(p) {} ~PainterStateGuard() diff --git a/src/widgets/styles/qstylesheetstyle_p.h b/src/widgets/styles/qstylesheetstyle_p.h index d4edb83525..9c4b87fc32 100644 --- a/src/widgets/styles/qstylesheetstyle_p.h +++ b/src/widgets/styles/qstylesheetstyle_p.h @@ -173,7 +173,7 @@ public: static int numinstances; private: - Q_DISABLE_COPY(QStyleSheetStyle) + Q_DISABLE_COPY_MOVE(QStyleSheetStyle) Q_DECLARE_PRIVATE(QStyleSheetStyle) }; diff --git a/src/widgets/styles/qwindowsstyle_p.h b/src/widgets/styles/qwindowsstyle_p.h index 7993b9f1c6..47816ff651 100644 --- a/src/widgets/styles/qwindowsstyle_p.h +++ b/src/widgets/styles/qwindowsstyle_p.h @@ -102,7 +102,7 @@ protected: QWindowsStyle(QWindowsStylePrivate &dd); private: - Q_DISABLE_COPY(QWindowsStyle) + Q_DISABLE_COPY_MOVE(QWindowsStyle) Q_DECLARE_PRIVATE(QWindowsStyle) }; diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h index 721a35bf90..c39dd33b08 100644 --- a/src/widgets/widgets/qmenu_p.h +++ b/src/widgets/widgets/qmenu_p.h @@ -115,7 +115,7 @@ private: class QMenuSloppyState { - Q_DISABLE_COPY(QMenuSloppyState) + Q_DISABLE_COPY_MOVE(QMenuSloppyState) public: QMenuSloppyState() : m_enabled(false) diff --git a/src/widgets/widgets/qwidgetresizehandler_p.h b/src/widgets/widgets/qwidgetresizehandler_p.h index b87bbd6229..89bc759cc2 100644 --- a/src/widgets/widgets/qwidgetresizehandler_p.h +++ b/src/widgets/widgets/qwidgetresizehandler_p.h @@ -100,7 +100,7 @@ protected: void keyPressEvent(QKeyEvent *e); private: - Q_DISABLE_COPY(QWidgetResizeHandler) + Q_DISABLE_COPY_MOVE(QWidgetResizeHandler) enum MousePosition { Nowhere, diff --git a/src/widgets/widgets/qwidgettextcontrol_p.h b/src/widgets/widgets/qwidgettextcontrol_p.h index 5431298387..202ba36454 100644 --- a/src/widgets/widgets/qwidgettextcontrol_p.h +++ b/src/widgets/widgets/qwidgettextcontrol_p.h @@ -267,7 +267,7 @@ protected: virtual bool event(QEvent *e) override; private: - Q_DISABLE_COPY(QWidgetTextControl) + Q_DISABLE_COPY_MOVE(QWidgetTextControl) Q_PRIVATE_SLOT(d_func(), void _q_updateCurrentCharFormatAndSelection()) Q_PRIVATE_SLOT(d_func(), void _q_emitCursorPosChanged(const QTextCursor &)) Q_PRIVATE_SLOT(d_func(), void _q_deleteSelected()) From 384b9d8fedd3c32b4a8d05740cc1c4bd73e171d8 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Wed, 21 Nov 2018 11:30:37 +0100 Subject: [PATCH 0609/1650] macOS accessibility: Implement accessibilityFrame MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Id78d3826eb18ff5ca306ac190543a7ff37b2f014 Reviewed-by: Tor Arne Vestbø Reviewed-by: Jan Arve Sæther --- src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index f82662bdcb..38a402fb2f 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -268,6 +268,13 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of return nil; } +- (NSRect)accessibilityFrame { + QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); + if (!iface || !iface->isValid()) + return NSZeroRect; + return QCocoaScreen::mapToNative(iface->rect()); +} + - (id) minValueAttribute:(QAccessibleInterface*)iface { if (QAccessibleValueInterface *val = iface->valueInterface()) return @(val->minimumValue().toDouble()); From b86d0b62156993936bf93169a895a92ad60adf7d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 2 Nov 2018 11:27:46 +0100 Subject: [PATCH 0610/1650] uic: Small refactorings - Do not use QString::number() to stream numbers. - Do not use QLatin1String/Char to stream strings or characters. - Add a convenience methods to determine the container page add method for simple containers. - Similarly, extract a method to determine the layout method and simplify the code accordingly. - Fix Clang warnings about else if after return/continue. - Use QString::isEmpty() instead of size() to check emptiness. - Fix QHash-contains()/value() Antipattern Task-number: PYSIDE-797 Change-Id: I9c61d20f46c8d142b947126a27faaf54b41f9e0c Reviewed-by: Cristian Maureira-Fredes Reviewed-by: Jarek Kobus --- src/tools/uic/cpp/cppwriteincludes.cpp | 4 +- src/tools/uic/cpp/cppwriteinitialization.cpp | 167 +++++++++---------- src/tools/uic/customwidgetsinfo.cpp | 21 +++ src/tools/uic/customwidgetsinfo.h | 1 + src/tools/uic/driver.cpp | 37 ++-- src/tools/uic/main.cpp | 2 +- src/tools/uic/uic.cpp | 4 +- 7 files changed, 116 insertions(+), 120 deletions(-) diff --git a/src/tools/uic/cpp/cppwriteincludes.cpp b/src/tools/uic/cpp/cppwriteincludes.cpp index d51fddffea..74546bb01d 100644 --- a/src/tools/uic/cpp/cppwriteincludes.cpp +++ b/src/tools/uic/cpp/cppwriteincludes.cpp @@ -119,7 +119,7 @@ void WriteIncludes::acceptUI(DomUI *node) writeHeaders(m_globalIncludes, true); writeHeaders(m_localIncludes, false); - m_output << QLatin1Char('\n'); + m_output << '\n'; } void WriteIncludes::acceptWidget(DomWidget *node) @@ -314,7 +314,7 @@ void WriteIncludes::writeHeaders(const OrderedSet &headers, bool global) const QString value = m_oldHeaderToNewHeader.value(header, header); const auto trimmed = QStringRef(&value).trimmed(); if (!trimmed.isEmpty()) - m_output << "#include " << openingQuote << trimmed << closingQuote << QLatin1Char('\n'); + m_output << "#include " << openingQuote << trimmed << closingQuote << '\n'; } } diff --git a/src/tools/uic/cpp/cppwriteinitialization.cpp b/src/tools/uic/cpp/cppwriteinitialization.cpp index 658cdd9567..ab4882d1a0 100644 --- a/src/tools/uic/cpp/cppwriteinitialization.cpp +++ b/src/tools/uic/cpp/cppwriteinitialization.cpp @@ -527,7 +527,8 @@ void WriteInitialization::acceptUI(DomUI *node) qPrintable(m_option.messagePrefix()), b.objName.toLatin1().data()); continue; - } else if (!m_registeredWidgets.contains(b.buddy)) { + } + if (!m_registeredWidgets.contains(b.buddy)) { fprintf(stderr, "%s: Warning: Buddy assignment: '%s' is not a valid widget.\n", qPrintable(m_option.messagePrefix()), b.buddy.toLatin1().data()); @@ -542,7 +543,7 @@ void WriteInitialization::acceptUI(DomUI *node) if (node->elementTabStops()) acceptTabStops(node->elementTabStops()); - if (m_delayedActionInitialization.size()) + if (!m_delayedActionInitialization.isEmpty()) m_output << "\n" << m_delayedActionInitialization; m_output << "\n" << m_indent << "retranslateUi(" << varName << ");\n"; @@ -635,7 +636,8 @@ void WriteInitialization::acceptWidget(DomWidget *node) writeProperties(varName, className, node->elementProperty()); - if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QMenu")) && parentWidget.size()) { + if (!parentWidget.isEmpty() + && m_uic->customWidgetsInfo()->extends(className, QLatin1String("QMenu"))) { initializeMenu(node, parentWidget); } @@ -677,14 +679,10 @@ void WriteInitialization::acceptWidget(DomWidget *node) } } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QDockWidget"))) { - QString area; - if (DomProperty *pstyle = attributes.value(QLatin1String("dockWidgetArea"))) { - area += QLatin1String("static_cast("); - area += QString::number(pstyle->elementNumber()); - area += QLatin1String("), "); - } - - m_output << m_indent << parentWidget << "->addDockWidget(" << area << varName << ");\n"; + m_output << m_indent << parentWidget << "->addDockWidget("; + if (DomProperty *pstyle = attributes.value(QLatin1String("dockWidgetArea"))) + m_output << "static_cast(" << pstyle->elementNumber() << "), "; + m_output << varName << ");\n"; } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QStatusBar"))) { m_output << m_indent << parentWidget << "->setStatusBar(" << varName << ");\n"; } else { @@ -693,34 +691,21 @@ void WriteInitialization::acceptWidget(DomWidget *node) } // Check for addPageMethod of a custom plugin first - const QString addPageMethod = m_uic->customWidgetsInfo()->customWidgetAddPageMethod(parentClass); + QString addPageMethod = m_uic->customWidgetsInfo()->customWidgetAddPageMethod(parentClass); + if (addPageMethod.isEmpty()) + addPageMethod = m_uic->customWidgetsInfo()->simpleContainerAddPageMethod(parentClass); if (!addPageMethod.isEmpty()) { m_output << m_indent << parentWidget << "->" << addPageMethod << '(' << varName << ");\n"; - } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QStackedWidget"))) { - m_output << m_indent << parentWidget << "->addWidget(" << varName << ");\n"; - } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QToolBar"))) { - m_output << m_indent << parentWidget << "->addWidget(" << varName << ");\n"; - } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QDockWidget"))) { - m_output << m_indent << parentWidget << "->setWidget(" << varName << ");\n"; - } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QScrollArea"))) { - m_output << m_indent << parentWidget << "->setWidget(" << varName << ");\n"; - } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QSplitter"))) { - m_output << m_indent << parentWidget << "->addWidget(" << varName << ");\n"; - } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QMdiArea"))) { - m_output << m_indent << parentWidget << "->addSubWindow(" << varName << ");\n"; } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QWizard"))) { addWizardPage(varName, node, parentWidget); } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QToolBox"))) { - QString icon; - if (const DomProperty *picon = attributes.value(QLatin1String("icon"))) { - icon += QLatin1String(", ") ; - icon += iconCall(picon); - } - const DomProperty *plabel = attributes.value(QLatin1String("label")); DomString *plabelString = plabel ? plabel->elementString() : 0; - m_output << m_indent << parentWidget << "->addItem(" << varName << icon << ", " << noTrCall(plabelString, pageDefaultString) << ");\n"; + m_output << m_indent << parentWidget << "->addItem(" << varName; + if (const DomProperty *picon = attributes.value(QLatin1String("icon"))) + m_output << ", " << iconCall(picon); + m_output << ", " << noTrCall(plabelString, pageDefaultString) << ");\n"; autoTrOutput(plabelString, pageDefaultString) << m_indent << parentWidget << "->setItemText(" << parentWidget << "->indexOf(" << varName << "), " << autoTrCall(plabelString, pageDefaultString) << ");\n"; @@ -734,16 +719,13 @@ void WriteInitialization::acceptWidget(DomWidget *node) << language::closeQtConfig(toolTipConfigKey()); } } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QTabWidget"))) { - QString icon; - if (const DomProperty *picon = attributes.value(QLatin1String("icon"))) { - icon += QLatin1String(", "); - icon += iconCall(picon); - } - const DomProperty *ptitle = attributes.value(QLatin1String("title")); DomString *ptitleString = ptitle ? ptitle->elementString() : 0; - m_output << m_indent << parentWidget << "->addTab(" << varName << icon << ", " << "QString());\n"; + m_output << m_indent << parentWidget << "->addTab(" << varName; + if (const DomProperty *picon = attributes.value(QLatin1String("icon"))) + m_output << ", " << iconCall(picon); + m_output << ", " << "QString());\n"; autoTrOutput(ptitleString, pageDefaultString) << m_indent << parentWidget << "->setTabText(" << parentWidget << "->indexOf(" << varName << "), " << autoTrCall(ptitleString, pageDefaultString) << ");\n"; @@ -989,6 +971,24 @@ static inline QString formLayoutRole(int column, int colspan) return column == 0 ? QLatin1String("QFormLayout::LabelRole") : QLatin1String("QFormLayout::FieldRole"); } +static QString layoutAddMethod(DomLayoutItem::Kind kind, const QString &layoutClass) +{ + const QString methodPrefix = layoutClass == QLatin1String("QFormLayout") + ? QLatin1String("set") : QLatin1String("add"); + switch (kind) { + case DomLayoutItem::Widget: + return methodPrefix + QLatin1String("Widget"); + case DomLayoutItem::Layout: + return methodPrefix + QLatin1String("Layout"); + case DomLayoutItem::Spacer: + return methodPrefix + QLatin1String("Item"); + case DomLayoutItem::Unknown: + Q_ASSERT( false ); + break; + } + Q_UNREACHABLE(); +} + void WriteInitialization::acceptLayoutItem(DomLayoutItem *node) { TreeWalker::acceptLayoutItem(node); @@ -1001,47 +1001,27 @@ void WriteInitialization::acceptLayoutItem(DomLayoutItem *node) const QString layoutName = m_driver->findOrInsertLayout(layout); const QString itemName = m_driver->findOrInsertLayoutItem(node); - QString addArgs; - QString methodPrefix = QLatin1String("add"); //Consistent API-design galore! + m_output << "\n" << m_indent << layoutName << "->" + << layoutAddMethod(node->kind(), layout->attributeClass()) << '('; + if (layout->attributeClass() == QLatin1String("QGridLayout")) { const int row = node->attributeRow(); const int col = node->attributeColumn(); const int rowSpan = node->hasAttributeRowSpan() ? node->attributeRowSpan() : 1; const int colSpan = node->hasAttributeColSpan() ? node->attributeColSpan() : 1; - - addArgs = QString::fromLatin1("%1, %2, %3, %4, %5").arg(itemName).arg(row).arg(col).arg(rowSpan).arg(colSpan); + m_output << itemName << ", " << row << ", " << col << ", " << rowSpan << ", " << colSpan; if (!node->attributeAlignment().isEmpty()) - addArgs += QLatin1String(", ") + node->attributeAlignment(); + m_output << ", " << node->attributeAlignment(); + } else if (layout->attributeClass() == QLatin1String("QFormLayout")) { + const int row = node->attributeRow(); + const int colSpan = node->hasAttributeColSpan() ? node->attributeColSpan() : 1; + const QString role = formLayoutRole(node->attributeColumn(), colSpan); + m_output << row << ", " << role << ", " << itemName; } else { - if (layout->attributeClass() == QLatin1String("QFormLayout")) { - methodPrefix = QLatin1String("set"); - const int row = node->attributeRow(); - const int colSpan = node->hasAttributeColSpan() ? node->attributeColSpan() : 1; - const QString role = formLayoutRole(node->attributeColumn(), colSpan); - addArgs = QString::fromLatin1("%1, %2, %3").arg(row).arg(role, itemName); - } else { - addArgs = itemName; - if (layout->attributeClass().contains(QLatin1String("Box")) && !node->attributeAlignment().isEmpty()) - addArgs += QLatin1String(", 0, ") + node->attributeAlignment(); - } - } - - // figure out "add" method - m_output << "\n" << m_indent << layoutName << "->"; - switch (node->kind()) { - case DomLayoutItem::Widget: - m_output << methodPrefix << "Widget(" << addArgs; - break; - case DomLayoutItem::Layout: - m_output << methodPrefix << "Layout(" << addArgs; - break; - case DomLayoutItem::Spacer: - m_output << methodPrefix << "Item(" << addArgs; - break; - case DomLayoutItem::Unknown: - Q_ASSERT( 0 ); - break; + m_output << itemName; + if (layout->attributeClass().contains(QLatin1String("Box")) && !node->attributeAlignment().isEmpty()) + m_output << ", 0, " << node->attributeAlignment(); } m_output << ");\n\n"; } @@ -1081,16 +1061,16 @@ void WriteInitialization::acceptAction(DomAction *node) void WriteInitialization::acceptActionRef(DomActionRef *node) { QString actionName = node->attributeName(); + if (actionName.isEmpty() || !m_widgetChain.top() + || m_driver->actionGroupByName(actionName)) { + return; + } + + const QString varName = m_driver->findOrInsertWidget(m_widgetChain.top()); const bool isSeparator = actionName == QLatin1String("separator"); bool isMenu = false; - QString varName = m_driver->findOrInsertWidget(m_widgetChain.top()); - - if (actionName.isEmpty() || !m_widgetChain.top()) { - return; - } else if (m_driver->actionGroupByName(actionName)) { - return; - } else if (const DomWidget *w = m_driver->widgetByName(actionName)) { + if (const DomWidget *w = m_driver->widgetByName(actionName)) { isMenu = m_uic->isMenu(w->attributeClass()); } else if (!(m_driver->actionByName(actionName) || isSeparator)) { fprintf(stderr, "%s: Warning: action `%s' not declared\n", @@ -1483,7 +1463,7 @@ void WriteInitialization::writeProperties(const QString &varName, break; } - if (propertyValue.size()) { + if (!propertyValue.isEmpty()) { const QString configKey = configKeyForProperty(propertyName); QTextStream &o = delayProperty ? m_delayedOut : autoTrOutput(p); @@ -1505,11 +1485,9 @@ void WriteInitialization::writeProperties(const QString &varName, } } if (leftMargin != -1 || topMargin != -1 || rightMargin != -1 || bottomMargin != -1) { - m_output << m_indent << varName << QLatin1String("->setContentsMargins(") - << leftMargin << QLatin1String(", ") - << topMargin << QLatin1String(", ") - << rightMargin << QLatin1String(", ") - << bottomMargin << QLatin1String(");\n"); + m_output << m_indent << varName << "->setContentsMargins(" + << leftMargin << ", " << topMargin << ", " + << rightMargin << ", " << bottomMargin << ");\n"; } } @@ -1789,7 +1767,7 @@ void WriteInitialization::writeColorGroup(DomColorGroup *colorGroup, const QStri const DomColor *color = colors.at(i); m_output << m_indent << paletteName << ".setColor(" << group - << ", " << "static_cast(" << QString::number(i) << ')' + << ", " << "static_cast(" << i << ')' << ", " << domColor2QString(color) << ");\n"; } @@ -2055,10 +2033,15 @@ void WriteInitialization::enableSorting(DomWidget *w, const QString &varName, co void WriteInitialization::addInitializer(Item *item, const QString &name, int column, const QString &value, const QString &directive, bool translatable) const { - if (!value.isEmpty()) - item->addSetter(QLatin1String("->set") + name.at(0).toUpper() + name.midRef(1) + - QLatin1Char('(') + (column < 0 ? QString() : QString::number(column) + - QLatin1String(", ")) + value + QLatin1String(");"), directive, translatable); + if (!value.isEmpty()) { + QString setter; + QTextStream str(&setter); + str << "->set" << name.at(0).toUpper() << name.midRef(1) << '('; + if (column >= 0) + str << column << ", "; + str << value << ");"; + item->addSetter(setter, directive, translatable); + } } /*! @@ -2285,7 +2268,7 @@ void WriteInitialization::initializeTableWidget(DomWidget *w) QString itemName = item.writeSetupUi(QString(), Item::ConstructItemAndVariable); item.writeRetranslateUi(varName + QLatin1String("->horizontalHeaderItem(") + QString::number(i) + QLatin1Char(')')); - m_output << m_indent << varName << "->setHorizontalHeaderItem(" << QString::number(i) << ", " << itemName << ");\n"; + m_output << m_indent << varName << "->setHorizontalHeaderItem(" << i << ", " << itemName << ");\n"; } } @@ -2307,7 +2290,7 @@ void WriteInitialization::initializeTableWidget(DomWidget *w) QString itemName = item.writeSetupUi(QString(), Item::ConstructItemAndVariable); item.writeRetranslateUi(varName + QLatin1String("->verticalHeaderItem(") + QString::number(i) + QLatin1Char(')')); - m_output << m_indent << varName << "->setVerticalHeaderItem(" << QString::number(i) << ", " << itemName << ");\n"; + m_output << m_indent << varName << "->setVerticalHeaderItem(" << i << ", " << itemName << ");\n"; } } @@ -2328,7 +2311,7 @@ void WriteInitialization::initializeTableWidget(DomWidget *w) QString itemName = item.writeSetupUi(QString(), Item::ConstructItemAndVariable); item.writeRetranslateUi(varName + QLatin1String("->item(") + QString::number(r) + QLatin1String(", ") + QString::number(c) + QLatin1Char(')')); - m_output << m_indent << varName << "->setItem(" << QString::number(r) << ", " << QString::number(c) << ", " << itemName << ");\n"; + m_output << m_indent << varName << "->setItem(" << r << ", " << c << ", " << itemName << ");\n"; } } enableSorting(w, varName, tempName); diff --git a/src/tools/uic/customwidgetsinfo.cpp b/src/tools/uic/customwidgetsinfo.cpp index 0ac0c2b6a3..4afdf74d08 100644 --- a/src/tools/uic/customwidgetsinfo.cpp +++ b/src/tools/uic/customwidgetsinfo.cpp @@ -31,6 +31,8 @@ #include "ui4.h" #include "utils.h" +#include + QT_BEGIN_NAMESPACE CustomWidgetsInfo::CustomWidgetsInfo() = default; @@ -96,5 +98,24 @@ QString CustomWidgetsInfo::customWidgetAddPageMethod(const QString &name) const return QString(); } +// add page methods for simple containers taking only the widget parameter +QString CustomWidgetsInfo::simpleContainerAddPageMethod(const QString &name) const +{ + using AddPageMethod = std::pair; + + static AddPageMethod addPageMethods[] = { + {"QStackedWidget", "addWidget"}, + {"QToolBar", "addWidget"}, + {"QDockWidget", "setWidget"}, + {"QScrollArea", "setWidget"}, + {"QSplitter", "addWidget"}, + {"QMdiArea", "addSubWindow"} + }; + for (const auto &m : addPageMethods) { + if (extends(name, QLatin1String(m.first))) + return QLatin1String(m.second); + } + return QString(); +} QT_END_NAMESPACE diff --git a/src/tools/uic/customwidgetsinfo.h b/src/tools/uic/customwidgetsinfo.h index 82e86a1266..a4278b1aca 100644 --- a/src/tools/uic/customwidgetsinfo.h +++ b/src/tools/uic/customwidgetsinfo.h @@ -52,6 +52,7 @@ public: { return m_customWidgets.value(name); } QString customWidgetAddPageMethod(const QString &name) const; + QString simpleContainerAddPageMethod(const QString &name) const; QString realClassName(const QString &className) const; diff --git a/src/tools/uic/driver.cpp b/src/tools/uic/driver.cpp index 748be9cece..cf7e67305b 100644 --- a/src/tools/uic/driver.cpp +++ b/src/tools/uic/driver.cpp @@ -33,6 +33,8 @@ #include #include +#include + QT_BEGIN_NAMESPACE Driver::Driver() @@ -136,11 +138,9 @@ QString Driver::findOrInsertName(const QString &name) QString Driver::normalizedName(const QString &name) { QString result = name; - QChar *data = result.data(); - for (int i = name.size(); --i >= 0; ++data) { - if (!data->isLetterOrNumber()) - *data = QLatin1Char('_'); - } + std::replace_if(result.begin(), result.end(), + [] (QChar c) { return !c.isLetterOrNumber(); }, + QLatin1Char('_')); return result; } @@ -149,23 +149,21 @@ QString Driver::unique(const QString &instanceName, const QString &className) QString name; bool alreadyUsed = false; - if (instanceName.size()) { - int id = 1; - name = instanceName; - name = normalizedName(name); + if (!instanceName.isEmpty()) { + name = normalizedName(instanceName); QString base = name; - while (m_nameRepository.contains(name)) { + for (int id = 1; m_nameRepository.contains(name); ++id) { alreadyUsed = true; - name = base + QString::number(id++); + name = base + QString::number(id); } - } else if (className.size()) { + } else if (!className.isEmpty()) { name = unique(qtify(className)); } else { name = unique(QLatin1String("var")); } - if (alreadyUsed && className.size()) { + if (alreadyUsed && !className.isEmpty()) { fprintf(stderr, "%s: Warning: The name '%s' (%s) is already in use, defaulting to '%s'.\n", qPrintable(m_option.messagePrefix()), qPrintable(instanceName), qPrintable(className), @@ -181,17 +179,10 @@ QString Driver::qtify(const QString &name) QString qname = name; if (qname.at(0) == QLatin1Char('Q') || qname.at(0) == QLatin1Char('K')) - qname = qname.mid(1); + qname.remove(0, 1); - int i=0; - while (i < qname.length()) { - if (qname.at(i).toLower() != qname.at(i)) - qname[i] = qname.at(i).toLower(); - else - break; - - ++i; - } + for (int i = 0, size = qname.size(); i < size && qname.at(i).isUpper(); ++i) + qname[i] = qname.at(i).toLower(); return qname; } diff --git a/src/tools/uic/main.cpp b/src/tools/uic/main.cpp index 41bd62bbf4..0516b854ff 100644 --- a/src/tools/uic/main.cpp +++ b/src/tools/uic/main.cpp @@ -131,7 +131,7 @@ int runUic(int argc, char *argv[]) QTextStream *out = 0; QFile f; - if (driver.option().outputFile.size()) { + if (!driver.option().outputFile.isEmpty()) { f.setFileName(driver.option().outputFile); if (!f.open(QIODevice::WriteOnly | QFile::Text)) { fprintf(stderr, "Could not create output file\n"); diff --git a/src/tools/uic/uic.cpp b/src/tools/uic/uic.cpp index 314989fbf9..b426d33e5c 100644 --- a/src/tools/uic/uic.cpp +++ b/src/tools/uic/uic.cpp @@ -106,13 +106,13 @@ bool Uic::printDependencies() void Uic::writeCopyrightHeader(DomUI *ui) { QString comment = ui->elementComment(); - if (comment.size()) + if (!comment.isEmpty()) out << "/*\n" << comment << "\n*/\n\n"; out << "/********************************************************************************\n"; out << "** Form generated from reading UI file '" << QFileInfo(opt.inputFile).fileName() << "'\n"; out << "**\n"; - out << "** Created by: Qt User Interface Compiler version " << QLatin1String(QT_VERSION_STR) << "\n"; + out << "** Created by: Qt User Interface Compiler version " << QT_VERSION_STR << "\n"; out << "**\n"; out << "** WARNING! All changes made in this file will be lost when recompiling UI file!\n"; out << "********************************************************************************/\n\n"; From 5823d391b453704fb520a6adf2900f6f30c03dce Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 3 Dec 2018 13:46:25 +0100 Subject: [PATCH 0611/1650] Use QMultiMap::insert() instead of insertMulti() Change-Id: Idaeb99562d39abfd020ff81b1818cba825c4e802 Reviewed-by: Timur Pocheptsov --- src/network/access/qhttpnetworkconnection.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index c58fd24a44..9fd6acb26c 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -641,7 +641,7 @@ QHttpNetworkReply* QHttpNetworkConnectionPrivate::queueRequest(const QHttpNetwor else { // SPDY, HTTP/2 ('h2' mode) if (!pair.second->d_func()->requestIsPrepared) prepareRequest(pair); - channels[0].spdyRequestsToSend.insertMulti(request.priority(), pair); + channels[0].spdyRequestsToSend.insert(request.priority(), pair); } #ifndef Q_OS_WINRT @@ -677,7 +677,7 @@ void QHttpNetworkConnectionPrivate::fillHttp2Queue() for (auto &pair : highPriorityQueue) { if (!pair.second->d_func()->requestIsPrepared) prepareRequest(pair); - channels[0].spdyRequestsToSend.insertMulti(QHttpNetworkRequest::HighPriority, pair); + channels[0].spdyRequestsToSend.insert(QHttpNetworkRequest::HighPriority, pair); } highPriorityQueue.clear(); @@ -685,7 +685,7 @@ void QHttpNetworkConnectionPrivate::fillHttp2Queue() for (auto &pair : lowPriorityQueue) { if (!pair.second->d_func()->requestIsPrepared) prepareRequest(pair); - channels[0].spdyRequestsToSend.insertMulti(pair.first.priority(), pair); + channels[0].spdyRequestsToSend.insert(pair.first.priority(), pair); } lowPriorityQueue.clear(); From 4e507464e4f756ea7528fd8c2d228121a4aaf6c3 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 3 Dec 2018 13:50:45 +0100 Subject: [PATCH 0612/1650] Use a QMultiMap for issuer/subjectInfo The map can contain multiple entries for one key, so a multi map is the correct data structure. Change-Id: I852ba3548f46415d8078fd0e8fdd7953ec6c370b Reviewed-by: Timur Pocheptsov --- src/network/ssl/qsslcertificate_openssl.cpp | 8 ++++---- src/network/ssl/qsslcertificate_p.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/network/ssl/qsslcertificate_openssl.cpp b/src/network/ssl/qsslcertificate_openssl.cpp index fa87cfeaaf..57a4dca08f 100644 --- a/src/network/ssl/qsslcertificate_openssl.cpp +++ b/src/network/ssl/qsslcertificate_openssl.cpp @@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE // forward declaration -static QMap _q_mapFromX509Name(X509_NAME *name); +static QMultiMap _q_mapFromX509Name(X509_NAME *name); bool QSslCertificate::operator==(const QSslCertificate &other) const { @@ -615,16 +615,16 @@ QByteArray QSslCertificatePrivate::asn1ObjectName(ASN1_OBJECT *object) return asn1ObjectId(object); } -static QMap _q_mapFromX509Name(X509_NAME *name) +static QMultiMap _q_mapFromX509Name(X509_NAME *name) { - QMap info; + QMultiMap info; for (int i = 0; i < q_X509_NAME_entry_count(name); ++i) { X509_NAME_ENTRY *e = q_X509_NAME_get_entry(name, i); QByteArray name = QSslCertificatePrivate::asn1ObjectName(q_X509_NAME_ENTRY_get_object(e)); unsigned char *data = nullptr; int size = q_ASN1_STRING_to_UTF8(&data, q_X509_NAME_ENTRY_get_data(e)); - info.insertMulti(name, QString::fromUtf8((char*)data, size)); + info.insert(name, QString::fromUtf8((char*)data, size)); #if QT_CONFIG(opensslv11) q_CRYPTO_free(data, nullptr, 0); #else diff --git a/src/network/ssl/qsslcertificate_p.h b/src/network/ssl/qsslcertificate_p.h index dfdceab502..2dbc4145af 100644 --- a/src/network/ssl/qsslcertificate_p.h +++ b/src/network/ssl/qsslcertificate_p.h @@ -102,8 +102,8 @@ public: QByteArray versionString; QByteArray serialNumberString; - QMap issuerInfo; - QMap subjectInfo; + QMultiMap issuerInfo; + QMultiMap subjectInfo; QDateTime notValidAfter; QDateTime notValidBefore; From 51dc108e10563f3042f0a89f1d58f782fb41d09d Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 3 Dec 2018 13:55:45 +0100 Subject: [PATCH 0613/1650] Use QMultiMap::insert() instead of insertMulti() Change-Id: Ia989347730e68f9af0638292f76205bdca61d04f Reviewed-by: Richard Moe Gustavsen --- src/widgets/kernel/qgesturemanager.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp index c4188044cf..57d6994c88 100644 --- a/src/widgets/kernel/qgesturemanager.cpp +++ b/src/widgets/kernel/qgesturemanager.cpp @@ -136,7 +136,7 @@ Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *r ++m_lastCustomGestureId; type = Qt::GestureType(m_lastCustomGestureId); } - m_recognizers.insertMulti(type, recognizer); + m_recognizers.insert(type, recognizer); return type; } @@ -522,7 +522,7 @@ bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event) for(ContextIterator it = w->d_func()->gestureContext.constBegin(), e = w->d_func()->gestureContext.constEnd(); it != e; ++it) { types.insert(it.key(), 0); - contexts.insertMulti(w, it.key()); + contexts.insert(w, it.key()); } } // find all gesture contexts for the widget tree @@ -534,7 +534,7 @@ bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event) if (!(it.value() & Qt::DontStartGestureOnChildren)) { if (!types.contains(it.key())) { types.insert(it.key(), 0); - contexts.insertMulti(w, it.key()); + contexts.insert(w, it.key()); } } } @@ -556,7 +556,7 @@ bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event) for(ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.constBegin(), e = item->QGraphicsItem::d_func()->gestureContext.constEnd(); it != e; ++it) { types.insert(it.key(), 0); - contexts.insertMulti(item, it.key()); + contexts.insert(item, it.key()); } } // find all gesture contexts for the graphics object tree @@ -569,7 +569,7 @@ bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event) if (!(it.value() & Qt::DontStartGestureOnChildren)) { if (!types.contains(it.key())) { types.insert(it.key(), 0); - contexts.insertMulti(item, it.key()); + contexts.insert(item, it.key()); } } } From c47b3f61af4322717ec44c983eebda8eea6f4623 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 3 Dec 2018 13:03:17 +0100 Subject: [PATCH 0614/1650] Use a QMultiMap for the weighted rules and get rid of one usage of insertMulti() Change-Id: I26a61dcdd4d778590145c38ae7f39d77ad39a51f Reviewed-by: Simon Hausmann --- src/gui/text/qcssparser.cpp | 6 +++--- src/gui/text/qcssparser_p.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp index 91fa40eddf..dc7e128bcd 100644 --- a/src/gui/text/qcssparser.cpp +++ b/src/gui/text/qcssparser.cpp @@ -2008,7 +2008,7 @@ bool StyleSelector::basicSelectorMatches(const BasicSelector &sel, NodePtr node) } void StyleSelector::matchRule(NodePtr node, const StyleRule &rule, StyleSheetOrigin origin, - int depth, QMap *weightedRules) + int depth, QMultiMap *weightedRules) { for (int j = 0; j < rule.selectors.count(); ++j) { const Selector& selector = rule.selectors.at(j); @@ -2022,7 +2022,7 @@ void StyleSelector::matchRule(NodePtr node, const StyleRule &rule, StyleSheetOri newRule.selectors[0] = selector; } //We might have rules with the same weight if they came from a rule with several selectors - weightedRules->insertMulti(weight, newRule); + weightedRules->insert(weight, newRule); } } } @@ -2035,7 +2035,7 @@ QVector StyleSelector::styleRulesForNode(NodePtr node) if (styleSheets.isEmpty()) return rules; - QMap weightedRules; // (spec, rule) that will be sorted below + QMultiMap weightedRules; // (spec, rule) that will be sorted below //prune using indexed stylesheet for (int sheetIdx = 0; sheetIdx < styleSheets.count(); ++sheetIdx) { diff --git a/src/gui/text/qcssparser_p.h b/src/gui/text/qcssparser_p.h index 8f992f8c59..860bbe382a 100644 --- a/src/gui/text/qcssparser_p.h +++ b/src/gui/text/qcssparser_p.h @@ -674,7 +674,7 @@ public: Qt::CaseSensitivity nameCaseSensitivity; private: void matchRule(NodePtr node, const StyleRule &rules, StyleSheetOrigin origin, - int depth, QMap *weightedRules); + int depth, QMultiMap *weightedRules); bool selectorMatches(const Selector &rule, NodePtr node); bool basicSelectorMatches(const BasicSelector &rule, NodePtr node); }; From c820e0b11745750a18460f85b697230881438006 Mon Sep 17 00:00:00 2001 From: Ryan Chu Date: Tue, 11 Dec 2018 10:57:51 +0000 Subject: [PATCH 0615/1650] Revert "Disable Docker-based test servers on Linux temporarily" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 4b1ce72c232b21fb1a8ae8ca86c2b8a7bc00b993. The required SHA-1 updates were integrated as: qt/qt5 ce3791a214f69b6f0310bfe1d5bcc12ac6927c49 qt/qtbase 75ee55e22a49327193aade21bf615efc7c879564 Change-Id: Ic389128ea9b507c506b18a47090930329a4ff6a2 Reviewed-by: Edward Welbourne Reviewed-by: Jędrzej Nowacki --- tests/auto/testserver.pri | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/auto/testserver.pri b/tests/auto/testserver.pri index 3289a14fd2..eefb29ab19 100644 --- a/tests/auto/testserver.pri +++ b/tests/auto/testserver.pri @@ -56,9 +56,6 @@ TESTSERVER_VERSION = $$system(docker-compose --version) equals(QMAKE_HOST.os, Darwin)|equals(QMAKE_HOST.os, Windows)|isEmpty(TESTSERVER_VERSION) { # Make check with server "qt-test-server.qt-test-net" as a fallback message("testserver: qt-test-server.qt-test-net") -} else:equals(QMAKE_HOST.os, Linux) { - # Disable Docker-based test server and use "qt-test-server.qt-test-net" server as a fallback - message("testserver: qt-test-server.qt-test-net") } else { # Make check with test servers equals(QMAKE_HOST.os, Darwin) { From da37291f285403f748d8fd9f8103d341f3082d45 Mon Sep 17 00:00:00 2001 From: Sergio Martins Date: Sun, 11 Nov 2018 15:27:01 +0000 Subject: [PATCH 0616/1650] When warning about invalid style override also print available ones Change-Id: Ia017a342648a1f1e1185e74ddec1a77cb6dcfebe Reviewed-by: Friedemann Kleint --- src/widgets/kernel/qapplication.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 2410daf047..f9db6155af 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -1064,8 +1064,10 @@ QStyle *QApplication::style() if (!QApplicationPrivate::styleOverride.isEmpty()) { const QString style = QApplicationPrivate::styleOverride.toLower(); app_style = QStyleFactory::create(style); - if (!app_style) - qWarning("QApplication: invalid style override passed, ignoring it."); + if (Q_UNLIKELY(!app_style)) { + qWarning("QApplication: invalid style override passed, ignoring it.\n" + " Available styles: %s", qPrintable(QStyleFactory::keys().join(QLatin1String(", ")))); + } } if (!app_style) app_style = QStyleFactory::create(QApplicationPrivate::desktopStyleKey()); From ceebad9bd2c5ca35c09a17b0adc5e8ee140bdad2 Mon Sep 17 00:00:00 2001 From: Vitaly Fanaskov Date: Fri, 7 Dec 2018 17:21:50 +0100 Subject: [PATCH 0617/1650] tst_QMessageBox: Modernize and simplify code Changed 0 to nullptr, used more C++-style casts, simplified some code for searching a button, and changed foreach to range-based for loop. Task-number: QTBUG-44131 Change-Id: I211b12751b0e2591d1d14294c31b51d52bb4e3f6 Reviewed-by: Christian Ehrlicher --- .../dialogs/qmessagebox/tst_qmessagebox.cpp | 73 +++++++++---------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp index 049468fd7c..3b31a74adf 100644 --- a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp +++ b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp @@ -210,9 +210,9 @@ void tst_QMessageBox::button() { QMessageBox msgBox; msgBox.addButton("retry", QMessageBox::DestructiveRole); - QVERIFY(msgBox.button(QMessageBox::Ok) == 0); // not added yet + QVERIFY(msgBox.button(QMessageBox::Ok) == nullptr); // not added yet QPushButton *b1 = msgBox.addButton(QMessageBox::Ok); - QCOMPARE(msgBox.button(QMessageBox::Ok), (QAbstractButton *)b1); // just added + QCOMPARE(msgBox.button(QMessageBox::Ok), static_cast(b1)); // just added QCOMPARE(msgBox.standardButton(b1), QMessageBox::Ok); msgBox.addButton(QMessageBox::Cancel); QCOMPARE(msgBox.standardButtons(), QMessageBox::Ok | QMessageBox::Cancel); @@ -220,12 +220,12 @@ void tst_QMessageBox::button() // remove the cancel, should not exist anymore msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); QVERIFY(!msgBox.button(QMessageBox::Cancel)); - QVERIFY(msgBox.button(QMessageBox::Yes) != 0); + QVERIFY(msgBox.button(QMessageBox::Yes) != nullptr); // should not crash QPushButton *b4 = new QPushButton; msgBox.addButton(b4, QMessageBox::DestructiveRole); - msgBox.addButton(0, QMessageBox::ActionRole); + msgBox.addButton(nullptr, QMessageBox::ActionRole); } void tst_QMessageBox::defaultButton() @@ -237,7 +237,7 @@ void tst_QMessageBox::defaultButton() QVERIFY(!msgBox.defaultButton()); QPushButton pushButton; msgBox.setDefaultButton(&pushButton); - QVERIFY(msgBox.defaultButton() == 0); // we have not added it yet + QVERIFY(msgBox.defaultButton() == nullptr); // we have not added it yet QPushButton *retryButton = msgBox.addButton(QMessageBox::Retry); msgBox.setDefaultButton(retryButton); QCOMPARE(msgBox.defaultButton(), retryButton); @@ -248,11 +248,11 @@ void tst_QMessageBox::defaultButton() closeHelper.start(Qt::Key_Enter, &msgBox); msgBox.exec(); - QCOMPARE(msgBox.clickedButton(), (QAbstractButton *)retryButton); + QCOMPARE(msgBox.clickedButton(), static_cast(retryButton)); QAbstractButton *okButton = msgBox.button(QMessageBox::Ok); msgBox.setDefaultButton(QMessageBox::Ok); - QCOMPARE(msgBox.defaultButton(), (QPushButton *)okButton); + QCOMPARE(msgBox.defaultButton(), static_cast(okButton)); closeHelper.start(Qt::Key_Enter, &msgBox); msgBox.exec(); QCOMPARE(msgBox.clickedButton(), okButton); @@ -260,7 +260,7 @@ void tst_QMessageBox::defaultButton() QCOMPARE(msgBox.defaultButton(), okButton); msgBox.removeButton(okButton); delete okButton; - okButton = 0; + okButton = nullptr; QVERIFY(!msgBox.defaultButton()); msgBox.setDefaultButton(QMessageBox::Ok); QVERIFY(!msgBox.defaultButton()); @@ -287,7 +287,7 @@ void tst_QMessageBox::escapeButton() QVERIFY(msgBox.clickedButton() == msgBox.button(QMessageBox::Cancel)); // auto detected (cancel) msgBox.setEscapeButton(retryButton); - QCOMPARE(msgBox.escapeButton(), (QAbstractButton *)retryButton); + QCOMPARE(msgBox.escapeButton(), static_cast(retryButton)); // with escape closeHelper.start(Qt::Key_Escape, &msgBox); @@ -297,7 +297,7 @@ void tst_QMessageBox::escapeButton() // with close closeHelper.start(ExecCloseHelper::CloseWindow, &msgBox); msgBox.exec(); - QCOMPARE(msgBox.clickedButton(), (QAbstractButton *)retryButton); + QCOMPARE(msgBox.clickedButton(), static_cast(retryButton)); QAbstractButton *okButton = msgBox.button(QMessageBox::Ok); msgBox.setEscapeButton(QMessageBox::Ok); @@ -309,7 +309,7 @@ void tst_QMessageBox::escapeButton() QCOMPARE(msgBox.escapeButton(), okButton); msgBox.removeButton(okButton); delete okButton; - okButton = 0; + okButton = nullptr; QVERIFY(!msgBox.escapeButton()); msgBox.setEscapeButton(QMessageBox::Ok); QVERIFY(!msgBox.escapeButton()); @@ -353,28 +353,28 @@ void tst_QMessageBox::statics() ExecCloseHelper closeHelper; for (int i = 0; i < 4; i++) { closeHelper.start(Qt::Key_Escape); - QMessageBox::StandardButton sb = (*statics[i])(0, "caption", + QMessageBox::StandardButton sb = (*statics[i])(nullptr, "caption", "text", QMessageBox::Yes | QMessageBox::No | QMessageBox::Help | QMessageBox::Cancel, QMessageBox::NoButton); QCOMPARE(sb, QMessageBox::Cancel); QVERIFY(closeHelper.done()); closeHelper.start(ExecCloseHelper::CloseWindow); - sb = (*statics[i])(0, "caption", + sb = (*statics[i])(nullptr, "caption", "text", QMessageBox::Yes | QMessageBox::No | QMessageBox::Help | QMessageBox::Cancel, QMessageBox::NoButton); QCOMPARE(sb, QMessageBox::Cancel); QVERIFY(closeHelper.done()); closeHelper.start(Qt::Key_Enter); - sb = (*statics[i])(0, "caption", + sb = (*statics[i])(nullptr, "caption", "text", QMessageBox::Yes | QMessageBox::No | QMessageBox::Help, QMessageBox::Yes); QCOMPARE(sb, QMessageBox::Yes); QVERIFY(closeHelper.done()); closeHelper.start(Qt::Key_Enter); - sb = (*statics[i])(0, "caption", + sb = (*statics[i])(nullptr, "caption", "text", QMessageBox::Yes | QMessageBox::No | QMessageBox::Help, QMessageBox::No); QCOMPARE(sb, QMessageBox::No); @@ -400,7 +400,7 @@ void tst_QMessageBox::about() { ExecCloseHelper closeHelper; closeHelper.start(Qt::Key_Escape); - QMessageBox::about(0, "Caption", "This is an auto test"); + QMessageBox::about(nullptr, "Caption", "This is an auto test"); // On Mac, about and aboutQt are not modal, so we need to // explicitly run the event loop #ifdef Q_OS_MAC @@ -412,7 +412,7 @@ void tst_QMessageBox::about() const int keyToSend = Qt::Key_Enter; closeHelper.start(keyToSend); - QMessageBox::aboutQt(0, "Caption"); + QMessageBox::aboutQt(nullptr, "Caption"); #ifdef Q_OS_MAC QTRY_VERIFY(closeHelper.done()); #else @@ -427,7 +427,7 @@ void tst_QMessageBox::staticSourceCompat() // source compat tests for < 4.2 ExecCloseHelper closeHelper; closeHelper.start(Qt::Key_Enter); - ret = QMessageBox::information(0, "title", "text", QMessageBox::Yes, QMessageBox::No); + ret = QMessageBox::information(nullptr, "title", "text", QMessageBox::Yes, QMessageBox::No); int expectedButton = int(QMessageBox::Yes); if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { const int dialogButtonBoxLayout = theme->themeHint(QPlatformTheme::DialogButtonBoxLayout).toInt(); @@ -439,39 +439,39 @@ void tst_QMessageBox::staticSourceCompat() QVERIFY(closeHelper.done()); closeHelper.start(Qt::Key_Enter); - ret = QMessageBox::information(0, "title", "text", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No); + ret = QMessageBox::information(nullptr, "title", "text", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No); QCOMPARE(ret, int(QMessageBox::Yes)); QVERIFY(closeHelper.done()); closeHelper.start(Qt::Key_Enter); - ret = QMessageBox::information(0, "title", "text", QMessageBox::Yes, QMessageBox::No | QMessageBox::Default); + ret = QMessageBox::information(nullptr, "title", "text", QMessageBox::Yes, QMessageBox::No | QMessageBox::Default); QCOMPARE(ret, int(QMessageBox::No)); QVERIFY(closeHelper.done()); closeHelper.start(Qt::Key_Enter); - ret = QMessageBox::information(0, "title", "text", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No | QMessageBox::Escape); + ret = QMessageBox::information(nullptr, "title", "text", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No | QMessageBox::Escape); QCOMPARE(ret, int(QMessageBox::Yes)); QVERIFY(closeHelper.done()); closeHelper.start(Qt::Key_Enter); - ret = QMessageBox::information(0, "title", "text", QMessageBox::Yes | QMessageBox::Escape, QMessageBox::No | QMessageBox::Default); + ret = QMessageBox::information(nullptr, "title", "text", QMessageBox::Yes | QMessageBox::Escape, QMessageBox::No | QMessageBox::Default); QCOMPARE(ret, int(QMessageBox::No)); QVERIFY(closeHelper.done()); // the button text versions closeHelper.start(Qt::Key_Enter); - ret = QMessageBox::information(0, "title", "text", "Yes", "No", QString(), 1); + ret = QMessageBox::information(nullptr, "title", "text", "Yes", "No", QString(), 1); QCOMPARE(ret, 1); QVERIFY(closeHelper.done()); if (0) { // don't run these tests since the dialog won't close! closeHelper.start(Qt::Key_Escape); - ret = QMessageBox::information(0, "title", "text", "Yes", "No", QString(), 1); + ret = QMessageBox::information(nullptr, "title", "text", "Yes", "No", QString(), 1); QCOMPARE(ret, -1); QVERIFY(closeHelper.done()); closeHelper.start(Qt::Key_Escape); - ret = QMessageBox::information(0, "title", "text", "Yes", "No", QString(), 0, 1); + ret = QMessageBox::information(nullptr, "title", "text", "Yes", "No", QString(), 0, 1); QCOMPARE(ret, 1); QVERIFY(closeHelper.done()); } @@ -618,9 +618,8 @@ void tst_QMessageBox::detailsButtonText() QDialogButtonBox* bb = box.findChild("qt_msgbox_buttonbox"); QVERIFY(bb); //get the detail button - QList list = bb->buttons(); - QAbstractButton* btn = NULL; - foreach(btn, list) { + auto list = bb->buttons(); + for (auto btn : list) { if (btn && (btn->inherits("QPushButton"))) { if (btn->text().remove(QLatin1Char('&')) != QMessageBox::tr("OK") && btn->text() != QMessageBox::tr("Show Details...")) { @@ -640,12 +639,12 @@ void tst_QMessageBox::expandDetails_QTBUG_32473() QDialogButtonBox* bb = box.findChild("qt_msgbox_buttonbox"); QVERIFY(bb); - QList list = bb->buttons(); - QAbstractButton* moreButton = NULL; - foreach (QAbstractButton* btn, list) - if (btn && bb->buttonRole(btn) == QDialogButtonBox::ActionRole) - moreButton = btn; - QVERIFY(moreButton); + auto list = bb->buttons(); + auto it = std::find_if(list.rbegin(), list.rend(), [&](QAbstractButton *btn) { + return btn && bb->buttonRole(btn) == QDialogButtonBox::ActionRole; }); + QVERIFY(it != list.rend()); + auto moreButton = *it; + QVERIFY(QTest::qWaitForWindowExposed(&box)); QRect geom = box.geometry(); box.resized = false; @@ -667,19 +666,19 @@ void tst_QMessageBox::incorrectDefaultButton() closeHelper.start(Qt::Key_Escape); //Do not crash here QTest::ignoreMessage(QtWarningMsg, "QDialogButtonBox::createButton: Invalid ButtonRole, button not added"); - QMessageBox::question( 0, "", "I've been hit!",QMessageBox::Ok | QMessageBox::Cancel,QMessageBox::Save ); + QMessageBox::question(nullptr, "", "I've been hit!",QMessageBox::Ok | QMessageBox::Cancel,QMessageBox::Save); QVERIFY(closeHelper.done()); closeHelper.start(Qt::Key_Escape); QTest::ignoreMessage(QtWarningMsg, "QDialogButtonBox::createButton: Invalid ButtonRole, button not added"); - QMessageBox::question( 0, "", "I've been hit!",QFlag(QMessageBox::Ok | QMessageBox::Cancel),QMessageBox::Save ); + QMessageBox::question(nullptr, "", "I've been hit!",QFlag(QMessageBox::Ok | QMessageBox::Cancel),QMessageBox::Save); QVERIFY(closeHelper.done()); closeHelper.start(Qt::Key_Escape); QTest::ignoreMessage(QtWarningMsg, "QDialogButtonBox::createButton: Invalid ButtonRole, button not added"); QTest::ignoreMessage(QtWarningMsg, "QDialogButtonBox::createButton: Invalid ButtonRole, button not added"); //do not crash here -> call old function of QMessageBox in this case - QMessageBox::question( 0, "", "I've been hit!",QMessageBox::Ok | QMessageBox::Cancel,QMessageBox::Save | QMessageBox::Cancel,QMessageBox::Ok); + QMessageBox::question(nullptr, "", "I've been hit!",QMessageBox::Ok | QMessageBox::Cancel,QMessageBox::Save | QMessageBox::Cancel,QMessageBox::Ok); QVERIFY(closeHelper.done()); } From d1cafa3ebac00f60cab3ca2beed6ebf2e6579a94 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 12 Dec 2018 10:46:32 +0100 Subject: [PATCH 0618/1650] qt_imageFromWinHBITMAP(): Fix memory corruption when converting from bitmaps with low depths Insufficient memory was allocated when asking GetDIBits() to convert to 32bit. Fix allocation size and use a QScopedArrayPointer. Fixes: QTBUG-72343 Change-Id: I45f79c913a243316e01bc6efed08e50ccc7d25f4 Reviewed-by: Eirik Aavitsland --- src/gui/image/qpixmap_win.cpp | 7 +++++-- tests/auto/gui/image/qimage/tst_qimage.cpp | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/gui/image/qpixmap_win.cpp b/src/gui/image/qpixmap_win.cpp index b8d13ac092..b5f8d43041 100644 --- a/src/gui/image/qpixmap_win.cpp +++ b/src/gui/image/qpixmap_win.cpp @@ -422,8 +422,11 @@ static QImage imageFromWinHBITMAP_GetDiBits(HBITMAP bitmap, bool forceQuads, int if (info.bmiHeader.biHeight > 0) // Force top-down info.bmiHeader.biHeight = -info.bmiHeader.biHeight; info.bmiHeader.biCompression = BI_RGB; // Extract using no compression (can be BI_BITFIELD) - if (forceQuads) + size_t allocSize = info.bmiHeader.biSizeImage; + if (forceQuads) { info.bmiHeader.biBitCount = 32; + allocSize = info.bmiHeader.biWidth * qAbs(info.bmiHeader.biHeight) * 4; + } const QImage::Format imageFormat = imageFromWinHBITMAP_Format(info.bmiHeader, hbitmapFormat); if (imageFormat == QImage::Format_Invalid) { @@ -431,7 +434,7 @@ static QImage imageFromWinHBITMAP_GetDiBits(HBITMAP bitmap, bool forceQuads, int return QImage(); } - QScopedPointer data(new uchar[info.bmiHeader.biSizeImage]); + QScopedArrayPointer data(new uchar[allocSize]); if (!GetDIBits(displayDc, bitmap, 0, qAbs(info.bmiHeader.biHeight), data.data(), &info, DIB_RGB_COLORS)) { qErrnoWarning("%s: GetDIBits() failed to get data.", __FUNCTION__); return QImage(); diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 5ffd75f931..eded206d37 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -233,6 +233,7 @@ private slots: #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) void toWinHBITMAP_data(); void toWinHBITMAP(); + void fromMonoHBITMAP(); #endif // Q_OS_WIN && !Q_OS_WINRT private: @@ -3635,6 +3636,19 @@ void tst_QImage::toWinHBITMAP() DeleteDC(bitmapDc); ReleaseDC(0, displayDc); } + +void tst_QImage::fromMonoHBITMAP() // QTBUG-72343, corruption for mono bitmaps +{ + enum : int { width = 32, height = 32, size = width * height / 8 }; // 32x32 mono bitmap + char bitmapData[size]; + memset(bitmapData, 0, size); + const HBITMAP hbitmap = CreateBitmap(width, height, /* planes */ 1, /* bitcount */ 1, bitmapData); + const QImage image = qt_imageFromWinHBITMAP(hbitmap); + QCOMPARE(image.size(), QSize(width, height)); + QCOMPARE(image.scanLine(0)[0], 0u); + DeleteObject(hbitmap); +} + #endif // Q_OS_WIN && !Q_OS_WINRT QTEST_GUILESS_MAIN(tst_QImage) From 2c6ec2c653af7f04bb98c6403b2e406cd493a8ab Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 4 Dec 2018 14:02:26 -0800 Subject: [PATCH 0619/1650] Fix tautological compare in error checking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit size is size_t, so it's never less than zero. Fixes: QTBUG-72286 Change-Id: Idd0c85a4e7b64f9c9c7dfffd156d404d0de5ed8d Reviewed-by: Oliver Wolff Reviewed-by: Mårten Nordheim --- src/corelib/codecs/qwindowscodec.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/codecs/qwindowscodec.cpp b/src/corelib/codecs/qwindowscodec.cpp index 813d3c8153..6b703f7517 100644 --- a/src/corelib/codecs/qwindowscodec.cpp +++ b/src/corelib/codecs/qwindowscodec.cpp @@ -179,7 +179,7 @@ QString QWindowsLocalCodec::convertToUnicodeCharByChar(const char *chars, int le #else QString s; size_t size = mbstowcs(NULL, mb, length); - if (size < 0) { + if (size == size_t(-1)) { Q_ASSERT("Error in CE TextCodec"); return QString(); } From d20c9805763ab3dc504ebf2cefd33499d89ef22c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 8 Nov 2018 14:16:33 -0800 Subject: [PATCH 0620/1650] Resources: reject compressed content we can't decompress This solution is composed of two features: 1) C++ code generated by RCC uses two symbols exported from QtCore that are only present if the feature was compiled in. If the feature was not compiled in, this will cause a linker error either at build time or at load time (if they were functions, the error could be at runtime). 2) Binary files generated by RCC have a new header field containing flags. We're currently using two flags, one for Zlib and one for Zstandard. This means we now have binary RCC format version 3. Change-Id: I42a48bd64ccc41aebf84fffd156545fb6a4f72d9 Reviewed-by: Oswald Buddenhagen Reviewed-by: Lars Knoll --- src/corelib/io/qresource.cpp | 44 ++++++++++- src/tools/rcc/main.cpp | 6 +- src/tools/rcc/rcc.cpp | 78 ++++++++++++++++--- src/tools/rcc/rcc.h | 2 + .../tools/rcc/data/images/images.expected | 7 +- .../auto/tools/rcc/data/sizes/size-0.expected | 7 +- .../auto/tools/rcc/data/sizes/size-1.expected | 7 +- .../rcc/data/sizes/size-2-0-35-1.expected | 7 +- tests/auto/tools/rcc/tst_rcc.cpp | 8 +- 9 files changed, 136 insertions(+), 30 deletions(-) diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index 52a20191a9..804029725a 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -77,6 +77,26 @@ QT_BEGIN_NAMESPACE +// Symbols used by code generated by RCC. +// They cause compilation errors if the RCC content couldn't +// be interpreted by this QtCore version. +#if defined(__ELF__) || defined(__APPLE__) // same as RCC generates +# define RCC_FEATURE_SYMBOL(feature) \ + extern Q_CORE_EXPORT const quint8 qt_resourceFeature ## feature; \ + const quint8 qt_resourceFeature ## feature = 0; +#else +# define RCC_FEATURE_SYMBOL(feature) \ + Q_CORE_EXPORT quint8 qResourceFeature ## feature() { return 0; } +#endif + +#ifndef QT_NO_COMPRESS +RCC_FEATURE_SYMBOL(Zlib) +#endif +#if QT_CONFIG(zstd) +RCC_FEATURE_SYMBOL(Zstd) +#endif + +#undef RCC_FEATURE_SYMBOL class QStringSplitter { @@ -109,6 +129,7 @@ public: //resource glue class QResourceRoot { +public: enum Flags { // must match rcc.h @@ -116,6 +137,7 @@ class QResourceRoot Directory = 0x02, CompressedZstd = 0x04 }; +private: const uchar *tree, *names, *payloads; int version; inline int findOffset(int node) const { return node * (14 + (version >= 0x02 ? 8 : 0)); } //sizeof each tree element @@ -917,7 +939,7 @@ Q_CORE_EXPORT bool qRegisterResourceData(int version, const unsigned char *tree, const unsigned char *name, const unsigned char *data) { QMutexLocker lock(resourceMutex()); - if ((version == 0x01 || version == 0x2) && resourceList()) { + if (version >= 0x01 && version <= 0x3 && resourceList()) { bool found = false; QResourceRoot res(version, tree, name, data); for(int i = 0; i < resourceList()->size(); ++i) { @@ -943,7 +965,7 @@ Q_CORE_EXPORT bool qUnregisterResourceData(int version, const unsigned char *tre return false; QMutexLocker lock(resourceMutex()); - if ((version == 0x01 || version == 0x02) && resourceList()) { + if (version >= 0x01 && version <= 0x3 && resourceList()) { QResourceRoot res(version, tree, name, data); for(int i = 0; i < resourceList()->size(); ) { if(*resourceList()->at(i) == res) { @@ -1002,11 +1024,27 @@ public: const int name_offset = qFromBigEndian(b + offset); offset += 4; + quint32 file_flags = 0; + if (version >= 3) { + file_flags = qFromBigEndian(b + offset); + offset += 4; + } + // Some sanity checking for sizes. This is _not_ a security measure. if (size >= 0 && (tree_offset >= size || data_offset >= size || name_offset >= size)) return false; - if (version == 0x01 || version == 0x02) { + // And some sanity checking for features + quint32 acceptableFlags = 0; +#ifndef QT_NO_COMPRESS + acceptableFlags |= Compressed; +#endif + if (QT_CONFIG(zstd)) + acceptableFlags |= CompressedZstd; + if (file_flags & ~acceptableFlags) + return false; + + if (version >= 0x01 && version <= 0x03) { buffer = b; setSource(version, b+tree_offset, b+name_offset, b+data_offset); return true; diff --git a/src/tools/rcc/main.cpp b/src/tools/rcc/main.cpp index 71836b81bd..6e8c13be15 100644 --- a/src/tools/rcc/main.cpp +++ b/src/tools/rcc/main.cpp @@ -185,13 +185,13 @@ int runRcc(int argc, char *argv[]) QString errorMsg; - quint8 formatVersion = 2; + quint8 formatVersion = 3; if (parser.isSet(formatVersionOption)) { bool ok = false; formatVersion = parser.value(formatVersionOption).toUInt(&ok); if (!ok) { errorMsg = QLatin1String("Invalid format version specified"); - } else if (formatVersion != 1 && formatVersion != 2) { + } else if (formatVersion < 1 || formatVersion > 3) { errorMsg = QLatin1String("Unsupported format version specified"); } } @@ -208,6 +208,8 @@ int runRcc(int argc, char *argv[]) if (parser.isSet(compressionAlgoOption)) library.setCompressionAlgorithm(RCCResourceLibrary::parseCompressionAlgorithm(parser.value(compressionAlgoOption), &errorMsg)); + if (formatVersion < 3 && library.compressionAlgorithm() == RCCResourceLibrary::CompressionAlgorithm::Zstd) + errorMsg = QLatin1String("Zstandard compression requires format version 3 or higher"); if (parser.isSet(nocompressOption)) library.setCompressionAlgorithm(RCCResourceLibrary::CompressionAlgorithm::None); if (parser.isSet(compressOption) && errorMsg.isEmpty()) { diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp index 5cbc771994..f284749781 100644 --- a/src/tools/rcc/rcc.cpp +++ b/src/tools/rcc/rcc.cpp @@ -295,6 +295,7 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset, lib.m_errorDevice->write(msg.toUtf8()); } + lib.m_overallFlags |= CompressedZstd; m_flags |= CompressedZstd; data = std::move(compressed); data.truncate(n); @@ -321,6 +322,7 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset, lib.m_errorDevice->write(msg.toUtf8()); } data = compressed; + lib.m_overallFlags |= Compressed; m_flags |= Compressed; } else if (lib.verbose()) { QString msg = QString::fromLatin1("%1: note: not compressed\n").arg(m_name); @@ -438,6 +440,7 @@ RCCResourceLibrary::RCCResourceLibrary(quint8 formatVersion) m_treeOffset(0), m_namesOffset(0), m_dataOffset(0), + m_overallFlags(0), m_useNameSpace(CONSTANT_USENAMESPACE), m_errorDevice(0), m_outDevice(0), @@ -945,6 +948,14 @@ bool RCCResourceLibrary::output(QIODevice &outDevice, QIODevice &tempDevice, QIO return true; } +void RCCResourceLibrary::writeDecimal(int value) +{ + Q_ASSERT(m_format != RCCResourceLibrary::Binary); + char buf[std::numeric_limits::digits10 + 2]; + int n = snprintf(buf, sizeof(buf), "%d", value); + write(buf, n + 1); // write() takes a size including terminating NUL +} + void RCCResourceLibrary::writeHex(quint8 tmp) { const char digits[] = "0123456789abcdef"; @@ -1039,6 +1050,8 @@ bool RCCResourceLibrary::writeHeader() writeNumber4(0); writeNumber4(0); writeNumber4(0); + if (m_formatVersion >= 3) + writeNumber4(m_overallFlags); } return true; } @@ -1241,10 +1254,35 @@ bool RCCResourceLibrary::writeInitializer() if (m_root) { writeString("bool qRegisterResourceData" "(int, const unsigned char *, " - "const unsigned char *, const unsigned char *);\n\n"); + "const unsigned char *, const unsigned char *);\n"); writeString("bool qUnregisterResourceData" "(int, const unsigned char *, " "const unsigned char *, const unsigned char *);\n\n"); + + if (m_overallFlags & (RCCFileInfo::Compressed | RCCFileInfo::CompressedZstd)) { + // use variable relocations with ELF and Mach-O + writeString("#if defined(__ELF__) || defined(__APPLE__)\n"); + if (m_overallFlags & RCCFileInfo::Compressed) { + writeString("static inline unsigned char qResourceFeatureZlib()\n" + "{\n" + " extern const unsigned char qt_resourceFeatureZlib;\n" + " return qt_resourceFeatureZlib;\n" + "}\n"); + } + if (m_overallFlags & RCCFileInfo::CompressedZstd) { + writeString("static inline unsigned char qResourceFeatureZstd()\n" + "{\n" + " extern const unsigned char qt_resourceFeatureZstd;\n" + " return qt_resourceFeatureZstd;\n" + "}\n"); + } + writeString("#else\n"); + if (m_overallFlags & RCCFileInfo::Compressed) + writeString("unsigned char qResourceFeatureZlib();\n"); + if (m_overallFlags & RCCFileInfo::CompressedZstd) + writeString("unsigned char qResourceFeatureZstd();\n"); + writeString("#endif\n\n"); + } } if (m_useNameSpace) @@ -1263,12 +1301,12 @@ bool RCCResourceLibrary::writeInitializer() writeString("()\n{\n"); if (m_root) { - writeString(" "); + writeString(" int version = "); + writeDecimal(m_formatVersion); + writeString(";\n "); writeAddNamespaceFunction("qRegisterResourceData"); - writeString("\n ("); - writeHex(m_formatVersion); - writeString(" qt_resource_struct, " - "qt_resource_name, qt_resource_data);\n"); + writeString("\n (version, qt_resource_struct, " + "qt_resource_name, qt_resource_data);\n"); } writeString(" return 1;\n"); writeString("}\n\n"); @@ -1286,11 +1324,24 @@ bool RCCResourceLibrary::writeInitializer() writeMangleNamespaceFunction(cleanResources); writeString("()\n{\n"); if (m_root) { - writeString(" "); + writeString(" int version = "); + writeDecimal(m_formatVersion); + writeString(";\n "); + + // ODR-use certain symbols from QtCore if we require optional features + if (m_overallFlags & RCCFileInfo::Compressed) { + writeString("version += "); + writeAddNamespaceFunction("qResourceFeatureZlib()"); + writeString(";\n "); + } + if (m_overallFlags & RCCFileInfo::CompressedZstd) { + writeString("version += "); + writeAddNamespaceFunction("qResourceFeatureZstd()"); + writeString(";\n "); + } + writeAddNamespaceFunction("qUnregisterResourceData"); - writeString("\n ("); - writeHex(m_formatVersion); - writeString(" qt_resource_struct, " + writeString("\n (version, qt_resource_struct, " "qt_resource_name, qt_resource_data);\n"); } writeString(" return 1;\n"); @@ -1326,6 +1377,13 @@ bool RCCResourceLibrary::writeInitializer() p[i++] = (m_namesOffset >> 16) & 0xff; p[i++] = (m_namesOffset >> 8) & 0xff; p[i++] = (m_namesOffset >> 0) & 0xff; + + if (m_formatVersion >= 3) { + p[i++] = (m_overallFlags >> 24) & 0xff; + p[i++] = (m_overallFlags >> 16) & 0xff; + p[i++] = (m_overallFlags >> 8) & 0xff; + p[i++] = (m_overallFlags >> 0) & 0xff; + } } return true; } diff --git a/src/tools/rcc/rcc.h b/src/tools/rcc/rcc.h index 7603a41cde..ad1c5cd166 100644 --- a/src/tools/rcc/rcc.h +++ b/src/tools/rcc/rcc.h @@ -134,6 +134,7 @@ private: bool writeInitializer(); void writeMangleNamespaceFunction(const QByteArray &name); void writeAddNamespaceFunction(const QByteArray &name); + void writeDecimal(int value); void writeHex(quint8 number); void writeNumber2(quint16 number); void writeNumber4(quint32 number); @@ -160,6 +161,7 @@ private: int m_treeOffset; int m_namesOffset; int m_dataOffset; + quint32 m_overallFlags; bool m_useNameSpace; QStringList m_failedResources; QIODevice *m_errorDevice; diff --git a/tests/auto/tools/rcc/data/images/images.expected b/tests/auto/tools/rcc/data/images/images.expected index 45e96dccd0..2af071812e 100644 --- a/tests/auto/tools/rcc/data/images/images.expected +++ b/tests/auto/tools/rcc/data/images/images.expected @@ -115,7 +115,6 @@ namespace QT_NAMESPACE { #endif bool qRegisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *); - bool qUnregisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *); #ifdef QT_NAMESPACE @@ -125,16 +124,18 @@ bool qUnregisterResourceData(int, const unsigned char *, const unsigned char *, int QT_RCC_MANGLE_NAMESPACE(qInitResources)(); int QT_RCC_MANGLE_NAMESPACE(qInitResources)() { + int version = 3; QT_RCC_PREPEND_NAMESPACE(qRegisterResourceData) - (0x2, qt_resource_struct, qt_resource_name, qt_resource_data); + (version, qt_resource_struct, qt_resource_name, qt_resource_data); return 1; } int QT_RCC_MANGLE_NAMESPACE(qCleanupResources)(); int QT_RCC_MANGLE_NAMESPACE(qCleanupResources)() { + int version = 3; QT_RCC_PREPEND_NAMESPACE(qUnregisterResourceData) - (0x2, qt_resource_struct, qt_resource_name, qt_resource_data); + (version, qt_resource_struct, qt_resource_name, qt_resource_data); return 1; } diff --git a/tests/auto/tools/rcc/data/sizes/size-0.expected b/tests/auto/tools/rcc/data/sizes/size-0.expected index e862310153..2f70a607ab 100644 --- a/tests/auto/tools/rcc/data/sizes/size-0.expected +++ b/tests/auto/tools/rcc/data/sizes/size-0.expected @@ -57,7 +57,6 @@ namespace QT_NAMESPACE { #endif bool qRegisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *); - bool qUnregisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *); #ifdef QT_NAMESPACE @@ -67,16 +66,18 @@ bool qUnregisterResourceData(int, const unsigned char *, const unsigned char *, int QT_RCC_MANGLE_NAMESPACE(qInitResources)(); int QT_RCC_MANGLE_NAMESPACE(qInitResources)() { + int version = 3; QT_RCC_PREPEND_NAMESPACE(qRegisterResourceData) - (0x2, qt_resource_struct, qt_resource_name, qt_resource_data); + (version, qt_resource_struct, qt_resource_name, qt_resource_data); return 1; } int QT_RCC_MANGLE_NAMESPACE(qCleanupResources)(); int QT_RCC_MANGLE_NAMESPACE(qCleanupResources)() { + int version = 3; QT_RCC_PREPEND_NAMESPACE(qUnregisterResourceData) - (0x2, qt_resource_struct, qt_resource_name, qt_resource_data); + (version, qt_resource_struct, qt_resource_name, qt_resource_data); return 1; } diff --git a/tests/auto/tools/rcc/data/sizes/size-1.expected b/tests/auto/tools/rcc/data/sizes/size-1.expected index 9e5161272a..d1717a9255 100644 --- a/tests/auto/tools/rcc/data/sizes/size-1.expected +++ b/tests/auto/tools/rcc/data/sizes/size-1.expected @@ -58,7 +58,6 @@ namespace QT_NAMESPACE { #endif bool qRegisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *); - bool qUnregisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *); #ifdef QT_NAMESPACE @@ -68,16 +67,18 @@ bool qUnregisterResourceData(int, const unsigned char *, const unsigned char *, int QT_RCC_MANGLE_NAMESPACE(qInitResources)(); int QT_RCC_MANGLE_NAMESPACE(qInitResources)() { + int version = 3; QT_RCC_PREPEND_NAMESPACE(qRegisterResourceData) - (0x2, qt_resource_struct, qt_resource_name, qt_resource_data); + (version, qt_resource_struct, qt_resource_name, qt_resource_data); return 1; } int QT_RCC_MANGLE_NAMESPACE(qCleanupResources)(); int QT_RCC_MANGLE_NAMESPACE(qCleanupResources)() { + int version = 3; QT_RCC_PREPEND_NAMESPACE(qUnregisterResourceData) - (0x2, qt_resource_struct, qt_resource_name, qt_resource_data); + (version, qt_resource_struct, qt_resource_name, qt_resource_data); return 1; } diff --git a/tests/auto/tools/rcc/data/sizes/size-2-0-35-1.expected b/tests/auto/tools/rcc/data/sizes/size-2-0-35-1.expected index 0fc953351a..7a7cc93df1 100644 --- a/tests/auto/tools/rcc/data/sizes/size-2-0-35-1.expected +++ b/tests/auto/tools/rcc/data/sizes/size-2-0-35-1.expected @@ -95,7 +95,6 @@ namespace QT_NAMESPACE { #endif bool qRegisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *); - bool qUnregisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *); #ifdef QT_NAMESPACE @@ -105,16 +104,18 @@ bool qUnregisterResourceData(int, const unsigned char *, const unsigned char *, int QT_RCC_MANGLE_NAMESPACE(qInitResources)(); int QT_RCC_MANGLE_NAMESPACE(qInitResources)() { + int version = 3; QT_RCC_PREPEND_NAMESPACE(qRegisterResourceData) - (0x2, qt_resource_struct, qt_resource_name, qt_resource_data); + (version, qt_resource_struct, qt_resource_name, qt_resource_data); return 1; } int QT_RCC_MANGLE_NAMESPACE(qCleanupResources)(); int QT_RCC_MANGLE_NAMESPACE(qCleanupResources)() { + int version = 3; QT_RCC_PREPEND_NAMESPACE(qUnregisterResourceData) - (0x2, qt_resource_struct, qt_resource_name, qt_resource_data); + (version, qt_resource_struct, qt_resource_name, qt_resource_data); return 1; } diff --git a/tests/auto/tools/rcc/tst_rcc.cpp b/tests/auto/tools/rcc/tst_rcc.cpp index 0876af6759..c810c6e364 100644 --- a/tests/auto/tools/rcc/tst_rcc.cpp +++ b/tests/auto/tools/rcc/tst_rcc.cpp @@ -159,9 +159,10 @@ void tst_rcc::rcc() return; } - // Launch + // Launch; force no compression, otherwise the output would be different + // depending on the compression algorithm we're using QProcess process; - process.start(m_rcc, QStringList(qrcfile)); + process.start(m_rcc, { "-no-compress", qrcfile }); if (!process.waitForFinished()) { const QString path = QString::fromLocal8Bit(qgetenv("PATH")); QString message = QString::fromLatin1("'%1' could not be found when run from '%2'. Path: '%3' "). @@ -196,8 +197,9 @@ static void createRccBinaryData(const QString &rcc, const QString &baseDir, QString currentDir = QDir::currentPath(); QDir::setCurrent(baseDir); + // same as above: force no compression QProcess rccProcess; - rccProcess.start(rcc, QStringList() << "-binary" << "-o" << rccFileName << qrcFileName); + rccProcess.start(rcc, { "-binary", "-no-compress", "-o", rccFileName, qrcFileName }); bool ok = rccProcess.waitForFinished(); if (!ok) { QString errorString = QString::fromLatin1("Could not start rcc (is it in PATH?): %1").arg(rccProcess.errorString()); From bccb964b9a201a87080d524a0d3c11551f794901 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 19 Oct 2018 19:01:37 +0200 Subject: [PATCH 0621/1650] escape literal backslashes in qmake files Task-number: QTBUG-70765 Change-Id: I56abbf19be88d01b2964980fb741567f28e4f0fa Reviewed-by: Joerg Bornemann --- mkspecs/features/mac/asset_catalogs.prf | 2 +- mkspecs/features/mac/default_post.prf | 2 +- mkspecs/features/moc.prf | 2 +- mkspecs/features/qt_configure.prf | 38 ++++++++++++------------- mkspecs/features/qt_docs.prf | 2 +- mkspecs/features/static_runtime.prf | 4 +-- 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/mkspecs/features/mac/asset_catalogs.prf b/mkspecs/features/mac/asset_catalogs.prf index 123a0e0fcd..58211c13a2 100644 --- a/mkspecs/features/mac/asset_catalogs.prf +++ b/mkspecs/features/mac/asset_catalogs.prf @@ -110,7 +110,7 @@ # Backwards compatibility for (bundle_data, QMAKE_BUNDLE_DATA) { for (bundle_file, $${bundle_data}.files) { - !contains(bundle_file, .*\.xcassets$): next() + !contains(bundle_file, .*\\.xcassets$): next() warning("*.xcassets in QMAKE_BUNDLE_DATA is deprecated. Use QMAKE_ASSET_CATALOGS instead.") !exists($$absolute_path($$bundle_file/AppIcon.appiconset, $$_PRO_FILE_PWD_)): next() diff --git a/mkspecs/features/mac/default_post.prf b/mkspecs/features/mac/default_post.prf index c01e99fe8e..3881b432ef 100644 --- a/mkspecs/features/mac/default_post.prf +++ b/mkspecs/features/mac/default_post.prf @@ -21,7 +21,7 @@ contains(TEMPLATE, .*app) { !isEmpty($$list($$(QT_MAC_SDK_NO_VERSION_CHECK))): \ CONFIG += sdk_no_version_check - QMAKE_MAC_SDK_MAJOR_MINOR_VERSION = $$replace(QMAKE_MAC_SDK_VERSION, "(\d+)(\.\d+)(\.\d+)?", \1\2) + QMAKE_MAC_SDK_MAJOR_MINOR_VERSION = $$replace(QMAKE_MAC_SDK_VERSION, "(\\d+)(\\.\\d+)(\\.\\d+)?", \\1\\2) !sdk_no_version_check:!versionAtMost(QMAKE_MAC_SDK_MAJOR_MINOR_VERSION, $$QT_MAC_SDK_VERSION_MAX) { warning("Qt has only been tested with version $$QT_MAC_SDK_VERSION_MAX"\ diff --git a/mkspecs/features/moc.prf b/mkspecs/features/moc.prf index 5c7745e5bb..d075183028 100644 --- a/mkspecs/features/moc.prf +++ b/mkspecs/features/moc.prf @@ -38,7 +38,7 @@ if(gcc|intel_icl|msvc):!rim_qcc:!uikit:!no_moc_predefs:if(!macos|count(QMAKE_APP } else: error("Oops, I messed up") moc_predefs.output = $$MOC_DIR/moc_predefs.h moc_predefs.input = MOC_PREDEF_FILE - silent: moc_predefs.commands = @echo generating $$moc_predefs.output$$escape_expand(\n\t)@$$moc_predefs.commands + silent: moc_predefs.commands = @echo generating $$moc_predefs.output$$escape_expand(\\n\\t)@$$moc_predefs.commands QMAKE_EXTRA_COMPILERS += moc_predefs MOC_PREDEF_FILE = $$[QT_HOST_DATA/src]/mkspecs/features/data/dummy.cpp } diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index d8f5af5404..d071e51769 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -1196,9 +1196,9 @@ defineTest(qtConfTest_files) { for(i, $${1}.files._KEYS_) { f = $$eval($${1}.files.$${i}) qtLog("Searching for file $${f}.") - contains(f, ".*\.h") { + contains(f, ".*\\.h") { file = $$qtConfFindInPathList($$f, $$EXTRA_INCLUDEPATH $$QMAKE_DEFAULT_INCDIRS) - } else: contains(f, ".*\.(lib|so|a)") { + } else: contains(f, ".*\\.(lib|so|a)") { file = $$qtConfFindInPathList($$f, $$EXTRA_LIBDIR $$QMAKE_DEFAULT_LIBDIRS) } else { # assume we're looking for an executable @@ -1399,7 +1399,7 @@ defineReplace(qtConfEvaluate) { 1 ~= s/$$escape_expand(\\n) */ /g expr = $${1} expr ~= s/&&/ && /g - expr ~= s/\|\|/ || /g + expr ~= s/\\|\\|/ || /g expr ~= s/!/ ! /g expr ~= s/\\(/ ( /g expr ~= s/\\)/ ) /g @@ -1422,7 +1422,7 @@ defineReplace(qtConfEvaluateSingleExpression) { } else: contains(e, "^'.*'$") { # quoted literals result = $$replace(e, "^'(.*)'$", "\\1") - } else: contains(e, "^tests\..*") { + } else: contains(e, "^tests\\..*") { !qt_conf_tests_allowed: \ error("Expression '$${1}' refers to a test, which is not allowed at this stage of configuring.") test = $$section(e, ".", 1, 1) @@ -1433,7 +1433,7 @@ defineReplace(qtConfEvaluateSingleExpression) { error("Unknown test object $${test} in expression '$${1}'.") qtRunSingleTest($$test) result = $$eval($${currentConfig}.tests.$${test}.$${var}) - } else: contains(e, "^libs\..*") { + } else: contains(e, "^libs\\..*") { !qt_conf_tests_allowed: \ error("Expression '$${1}' refers to a library, which is not allowed at this stage of configuring.") lib = $$section(e, ".", 1, 1) @@ -1446,7 +1446,7 @@ defineReplace(qtConfEvaluateSingleExpression) { !defined($${currentConfig}.libraries.$${lib}.$${var}, var): \ var = sources.$$eval($${currentConfig}.libraries.$${lib}.source).$$var result = $$eval($${currentConfig}.libraries.$${lib}.$${var}) - } else: contains(e, "^features\..*") { + } else: contains(e, "^features\\..*") { feature = $$section(e, ".", 1, 1) var = $$section(e, ".", 2, -1) isEmpty(var): \ @@ -1470,33 +1470,33 @@ defineReplace(qtConfEvaluateSingleExpression) { !qtConfCheckFeature($$feature): \ error("Expression '$$1' is accessing non-emitted feature $${feature}.") result = $$eval($${currentConfig}.features.$${feature}.$${var}) - } else: contains(e, "^config\..*") { - var = $$replace(e, "^config\.", "") + } else: contains(e, "^config\\..*") { + var = $$replace(e, "^config\\.", "") result = false contains(CONFIG, $$var): result = true - } else: contains(e, "^module\..*") { - var = $$replace(e, "^module\.", "") + } else: contains(e, "^module\\..*") { + var = $$replace(e, "^module\\.", "") result = false qtConfHaveModule($$var): result = true - } else: contains(e, "^arch\..*") { - var = $$replace(e, "^arch\.", "") + } else: contains(e, "^arch\\..*") { + var = $$replace(e, "^arch\\.", "") result = false isEmpty(QT_ARCH): \ qtConfCheckFeature(architecture) contains(QT_ARCH, $$var): result = true - } else: contains(e, "^subarch\..*") { - var = $$replace(e, "^subarch\.", "") + } else: contains(e, "^subarch\\..*") { + var = $$replace(e, "^subarch\\.", "") result = false isEmpty(QT_ARCH): \ qtConfCheckFeature(architecture) contains(QT_CPU_FEATURES.$$QT_ARCH, $$var): result = true - } else: contains(e, "^input\..*") { + } else: contains(e, "^input\\..*") { result = $$eval(config.$$e) - } else: contains(e, "^var\..*") { - var = $$replace(e, "^var\.", "") + } else: contains(e, "^var\\..*") { + var = $$replace(e, "^var\\.", "") result = $$eval($$var) - } else: contains(e, "^call\..*") { - call = $$replace(e, "^call\.", "qtConfFunc_") + } else: contains(e, "^call\\..*") { + call = $$replace(e, "^call\\.", "qtConfFunc_") !defined($$call, replace): \ error("Call $$call referenced in expression '$${1}' does not exist") eval(result = \$\$"$$call"()) diff --git a/mkspecs/features/qt_docs.prf b/mkspecs/features/qt_docs.prf index 3139c443c6..3b74cd4dd5 100644 --- a/mkspecs/features/qt_docs.prf +++ b/mkspecs/features/qt_docs.prf @@ -18,7 +18,7 @@ isEmpty(qtver.value): error("No version for documentation specified.") qtmver.name = QT_VER qtmver.value = $$replace(qtver.value, ^(\\d+\\.\\d+).*$, \\1) qtvertag.name = QT_VERSION_TAG -qtvertag.value = $$replace(qtver.value, \.,) +qtvertag.value = $$replace(qtver.value, \\.,) qtdocs.name = QT_INSTALL_DOCS qtdocs.value = $$[QT_INSTALL_DOCS/src] builddir.name = BUILDDIR diff --git a/mkspecs/features/static_runtime.prf b/mkspecs/features/static_runtime.prf index 1af3236189..e20bfc4281 100644 --- a/mkspecs/features/static_runtime.prf +++ b/mkspecs/features/static_runtime.prf @@ -1,7 +1,7 @@ msvc { # -MD becomes -MT, -MDd becomes -MTd - QMAKE_CFLAGS ~= s,^-MD(d?)$,-MT\1,g - QMAKE_CXXFLAGS ~= s,^-MD(d?)$,-MT\1,g + QMAKE_CFLAGS ~= s,^-MD(d?)$,-MT\\1,g + QMAKE_CXXFLAGS ~= s,^-MD(d?)$,-MT\\1,g } else: mingw { QMAKE_LFLAGS += -static } From 4e54ac7c8951c87846dccd12b0801eb31fa9dd84 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Wed, 5 Dec 2018 13:32:19 +0100 Subject: [PATCH 0622/1650] Doc: correct syntax error in qmake manual Change-Id: I600f8c9ea8e55dad19345bd4d726cf8d5438e9ce Reviewed-by: Oswald Buddenhagen Reviewed-by: Paul Wicking --- qmake/doc/src/qmake-manual.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index 1a779a94b4..97744e7460 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -3406,7 +3406,7 @@ \snippet code/doc_src_qmake-manual.pro 72 Like \l {qmake-cat}{$$cat()}, the \a mode argument takes \c blob, \c lines, - \c true, and \false as value. However, the legacy word splitting rules + \c true, and \c false as value. However, the legacy word splitting rules (i.e. empty or \c true, and \c false) differ subtly. If you pass \c stsvar, the command's exit status will be stored in that From 69f6d3bd44e4e2d36ef741a1914227f804504141 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 27 Nov 2018 13:53:44 +0100 Subject: [PATCH 0623/1650] configure: fix $$qtConfFindInPath() on windows uses of this function (or the "files" stanza in configure.json) which don't explicitly target windows don't specify the .exe extension, so we need to add it automatically if it's missing. Task-number: QTBUG-57436 Change-Id: I1994378399bc3466c32ee065e752516f42652975 Reviewed-by: Joerg Bornemann --- mkspecs/features/qt_configure.prf | 1 + 1 file changed, 1 insertion(+) diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index d071e51769..e2e341770e 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -378,6 +378,7 @@ defineReplace(qtConfFindInPathList) { defineReplace(qtConfFindInPath) { ensurePathEnv() + equals(QMAKE_HOST.os, Windows):!contains(1, .*\\.exe): 1 = $${1}.exe return($$qtConfFindInPathList($$1, $$2 $$QMAKE_PATH_ENV)) } From bc997b856aa7b0b2137b568cd3fc6f190cd89f84 Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Wed, 12 Dec 2018 15:42:40 +0100 Subject: [PATCH 0624/1650] Windows QPA: Fix touch message queue handling In the handling of pointer messages for touchscreen we use a queue that is flushed when mouse messages synthesized by Windows are received. However, these fake mouse messages should be otherwise ignored. Their handling was causing issues with PointHandler in QtQuick. This change fixes the part of QTBUG-71431 that causes a single touch drag to behave unexpectedly with PointHandler. Task-number: QTBUG-71431 Change-Id: Iccdd554876f411bce2dd1f922a3d889e61b7bb1c Reviewed-by: Miguel Costa --- src/plugins/platforms/windows/qwindowspointerhandler.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp index 7935d0c36f..3534f06971 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp @@ -641,6 +641,7 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd, // Only the primary pointer will generate mouse messages. enqueueTouchEvent(window, touchPoints, QWindowsKeyMapper::queryKeyboardModifiers()); } else { + flushTouchEvents(m_touchDevice); QWindowSystemInterface::handleTouchEvent(window, m_touchDevice, touchPoints, QWindowsKeyMapper::queryKeyboardModifiers()); } @@ -766,6 +767,13 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtW if (et != QtWindows::MouseWheelEvent && msg.message != WM_MOUSELEAVE && msg.message != WM_MOUSEMOVE) return false; + // Ignore messages synthesized from touch/pen (only use them for flushing queues). + const quint64 signatureMask = 0xffffff00; + const quint64 miWpSignature = 0xff515700; + const quint64 extraInfo = quint64(GetMessageExtraInfo()); + if ((extraInfo & signatureMask) == miWpSignature) + return false; + const QPoint eventPos(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam)); QPoint localPos; QPoint globalPos; From fc2ec95587c431b1916ec5590b7ef634be96c985 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 20 Nov 2018 10:04:28 +0100 Subject: [PATCH 0625/1650] Add Grayscale16 Image Format [ChangeLog][QtGui][QImage] Added support for 16-bit grayscale format. Together-with: Aaron Linville Task-number: QTBUG-41176 Change-Id: I5fe4f54a55ebe1413aa71b882c19627fe22362ac Reviewed-by: Nick D'Ademo Reviewed-by: Lars Knoll --- src/gui/image/qimage.cpp | 25 ++- src/gui/image/qimage.h | 3 - src/gui/image/qimage_conversions.cpp | 209 +++++++++++++----- src/gui/image/qimage_p.h | 1 + src/gui/image/qpixmap_raster.cpp | 3 + src/gui/image/qpnghandler.cpp | 20 +- src/gui/opengl/qopenglpaintengine.cpp | 5 +- src/gui/opengl/qopengltextureuploader.cpp | 28 ++- src/gui/opengl/qopengltextureuploader_p.h | 2 +- src/gui/painting/qdrawhelper.cpp | 89 +++++++- src/gui/painting/qdrawhelper_p.h | 2 + tests/auto/gui/image/qimage/tst_qimage.cpp | 42 +++- .../image/qimagereader/tst_qimagereader.cpp | 2 +- .../image/qimagewriter/tst_qimagewriter.cpp | 6 +- 14 files changed, 348 insertions(+), 89 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 0105f1decd..b6d93331e6 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -288,6 +288,7 @@ bool QImageData::checkForAlphaPixels() const case QImage::Format_BGR30: case QImage::Format_RGB30: case QImage::Format_Grayscale8: + case QImage::Format_Grayscale16: case QImage::Format_RGBX64: break; case QImage::Format_Invalid: @@ -710,6 +711,7 @@ bool QImageData::checkForAlphaPixels() const \value Format_A2RGB30_Premultiplied The image is stored using a 32-bit premultiplied ARGB format (2-10-10-10). (added in Qt 5.4) \value Format_Alpha8 The image is stored using an 8-bit alpha only format. (added in Qt 5.5) \value Format_Grayscale8 The image is stored using an 8-bit grayscale format. (added in Qt 5.5) + \value Format_Grayscale16 The image is stored using an 16-bit grayscale format. (added in Qt 5.13) \value Format_RGBX64 The image is stored using a 64-bit halfword-ordered RGB(x) format (16-16-16-16). This is the same as the Format_RGBX64 except alpha must always be 65535. (added in Qt 5.12) \value Format_RGBA64 The image is stored using a 64-bit halfword-ordered RGBA format (16-16-16-16). (added in Qt 5.12) @@ -2038,6 +2040,7 @@ static bool highColorPrecision(QImage::Format format) case QImage::Format_RGBX64: case QImage::Format_RGBA64: case QImage::Format_RGBA64_Premultiplied: + case QImage::Format_Grayscale16: return true; default: break; @@ -2531,6 +2534,10 @@ QColor QImage::pixelColor(int x, int y) const case Format_RGBA64_Premultiplied: c = reinterpret_cast(s)[x]; break; + case Format_Grayscale16: { + quint16 v = reinterpret_cast(s)[x]; + return QColor(qRgba64(v, v, v, 0xffff)); + } default: c = QRgba64::fromArgb32(pixel(x, y)); break; @@ -2641,6 +2648,7 @@ bool QImage::allGray() const case Format_Alpha8: return false; case Format_Grayscale8: + case Format_Grayscale16: return true; case Format_RGB32: case Format_ARGB32: @@ -2707,7 +2715,7 @@ bool QImage::isGrayscale() const if (d->format == QImage::Format_Alpha8) return false; - if (d->format == QImage::Format_Grayscale8) + if (d->format == QImage::Format_Grayscale8 || d->format == QImage::Format_Grayscale16) return true; switch (depth()) { @@ -3341,6 +3349,7 @@ QImage QImage::rgbSwapped_helper() const break; case Format_Alpha8: case Format_Grayscale8: + case Format_Grayscale16: return *this; case Format_Mono: case Format_MonoLSB: @@ -3452,6 +3461,7 @@ void QImage::rgbSwapped_inplace() break; case Format_Alpha8: case Format_Grayscale8: + case Format_Grayscale16: return; case Format_Mono: case Format_MonoLSB: @@ -5349,6 +5359,19 @@ static Q_CONSTEXPR QPixelFormat pixelformats[] = { /*PREMULTIPLIED*/ QPixelFormat::Premultiplied, /*INTERPRETATION*/ QPixelFormat::UnsignedShort, /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_Grayscale16: + QPixelFormat(QPixelFormat::Grayscale, + /*GRAY*/ 16, + /*SECOND*/ 0, + /*THIRD*/ 0, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 0, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedShort, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), }; Q_STATIC_ASSERT(sizeof(pixelformats) / sizeof(*pixelformats) == QImage::NImageFormats); diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h index 4b7a3b1ead..7a1f37c5cf 100644 --- a/src/gui/image/qimage.h +++ b/src/gui/image/qimage.h @@ -128,10 +128,7 @@ public: Format_RGBX64, Format_RGBA64, Format_RGBA64_Premultiplied, -#if 0 - // reserved for future use Format_Grayscale16, -#endif #ifndef Q_QDOC NImageFormats #endif diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index 215dd33499..ea9347183e 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -1447,6 +1447,56 @@ static bool convert_RGBA64PM_to_RGBA64_inplace(QImageData *data, Qt::ImageConver return true; } +static void convert_gray16_to_RGBA64(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_Grayscale16); + Q_ASSERT(dest->format == QImage::Format_RGBA64 || dest->format == QImage::Format_RGBX64 || + dest->format == QImage::Format_RGBA64_Premultiplied); + Q_ASSERT(src->width == dest->width); + Q_ASSERT(src->height == dest->height); + + const qsizetype sbpl = src->bytes_per_line; + const qsizetype dbpl = dest->bytes_per_line; + const uchar *src_data = src->data; + uchar *dest_data = dest->data; + + for (int i = 0; i < src->height; ++i) { + const quint16 *src_line = reinterpret_cast(src_data); + QRgba64 *dest_line = reinterpret_cast(dest_data); + for (int j = 0; j < src->width; ++j) { + quint16 s = src_line[j]; + dest_line[j] = qRgba64(s, s, s, 0xFFFF); + } + src_data += sbpl; + dest_data += dbpl; + } +} + +static void convert_RGBA64_to_gray16(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(dest->format == QImage::Format_Grayscale16); + Q_ASSERT(src->format == QImage::Format_RGBX64 || + src->format == QImage::Format_RGBA64_Premultiplied); + Q_ASSERT(src->width == dest->width); + Q_ASSERT(src->height == dest->height); + + const qsizetype sbpl = src->bytes_per_line; + const qsizetype dbpl = dest->bytes_per_line; + const uchar *src_data = src->data; + uchar *dest_data = dest->data; + + for (int i = 0; i < src->height; ++i) { + const QRgba64 *src_line = reinterpret_cast(src_data); + quint16 *dest_line = reinterpret_cast(dest_data); + for (int j = 0; j < src->width; ++j) { + QRgba64 s = src_line[j].unpremultiplied(); + dest_line[j] = qGray(s.red(), s.green(), s.blue()); + } + src_data += sbpl; + dest_data += dbpl; + } +} + static QVector fix_color_table(const QVector &ctbl, QImage::Format format) { QVector colorTable = ctbl; @@ -2291,7 +2341,7 @@ static bool convert_Grayscale8_to_Indexed8_inplace(QImageData *data, Qt::ImageCo Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormats] = { { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, @@ -2312,7 +2362,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_Mono { @@ -2334,7 +2384,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_MonoLSB { @@ -2359,7 +2409,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, 0, 0, convert_Indexed8_to_Alpha8, convert_Indexed8_to_Grayscale8, - 0, 0, 0 + 0, 0, 0, 0 }, // Format_Indexed8 { @@ -2387,7 +2437,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_RGB_to_RGB30, 0, 0, 0, - 0, 0, 0 + 0, 0, 0, 0 }, // Format_RGB32 { @@ -2417,7 +2467,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, convert_ARGB32_to_RGBA64, - 0 + 0, 0 }, // Format_ARGB32 { @@ -2442,7 +2492,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_ARGB_to_RGBA, 0, 0, 0, 0, 0, 0, - 0, 0, 0 + 0, 0, 0, 0 }, // Format_ARGB32_Premultiplied { @@ -2464,7 +2514,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB16 { @@ -2486,7 +2536,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_ARGB8565_Premultiplied { @@ -2508,7 +2558,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB666 { @@ -2530,7 +2580,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_ARGB6666_Premultiplied { @@ -2552,7 +2602,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB555 { @@ -2574,7 +2624,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_ARGB8555_Premultiplied { @@ -2597,7 +2647,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_RGB888_to_RGB, convert_RGB888_to_RGB, convert_RGB888_to_RGB, - 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB888 { @@ -2619,7 +2669,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB444 { @@ -2640,7 +2690,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_ARGB4444_Premultiplied { 0, @@ -2667,7 +2717,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_RGB_to_RGB30, 0, 0, 0, - 0, 0, 0 + 0, 0, 0, 0 }, // Format_RGBX8888 { 0, @@ -2696,7 +2746,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, convert_ARGB32_to_RGBA64, - 0 + 0, 0 }, // Format_RGBA8888 { @@ -2718,7 +2768,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGBA8888_Premultiplied { @@ -2746,7 +2796,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_BGR30_to_RGB30, convert_BGR30_to_RGB30, 0, 0, - 0, 0, 0 + 0, 0, 0, 0 }, // Format_BGR30 { 0, @@ -2773,8 +2823,8 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_A2RGB30_PM_to_RGB30, convert_BGR30_to_RGB30, 0, 0, - 0, 0, 0 - }, // Format_BGR30A2_Premultiplied + 0, 0, 0, 0 + }, // Format_A2BGR30_Premultiplied { 0, 0, @@ -2799,7 +2849,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_BGR30_to_RGB30, 0, convert_passthrough, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0 }, // Format_RGB30 { 0, @@ -2826,8 +2876,8 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_A2RGB30_PM_to_RGB30, 0, 0, 0, - 0, 0, 0 - }, // Format_RGB30A2_Premultiplied + 0, 0, 0, 0 + }, // Format_A2RGB30_Premultiplied { 0, 0, @@ -2846,7 +2896,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_Alpha8 { 0, @@ -2872,7 +2922,8 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // self convert_passthrough, - convert_passthrough + convert_passthrough, + convert_RGBA64_to_gray16 }, // Format_RGBX64 { 0, @@ -2898,7 +2949,8 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, convert_RGBA64_to_RGBx64, 0, // self - convert_RGBA64_to_RGBA64PM + convert_RGBA64_to_RGBA64PM, + 0 }, // Format_RGBA64 { 0, @@ -2927,20 +2979,51 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, convert_RGBA64PM_to_RGBA64, convert_RGBA64PM_to_RGBA64, - 0 // self - } // Format_RGBA64_Premultiplied + 0, // self + convert_RGBA64_to_gray16 + }, // Format_RGBA64_Premultiplied + { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, 0, + convert_gray16_to_RGBA64, + convert_gray16_to_RGBA64, + convert_gray16_to_RGBA64, + 0 // self + }, // Format_Grayscale16 }; InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QImage::NImageFormats] = { { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_Mono { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_MonoLSB { 0, @@ -2964,7 +3047,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, 0, 0, convert_Indexed8_to_Alpha8_inplace, convert_Indexed8_to_Grayscale8_inplace, - 0, 0, 0 + 0, 0, 0, 0 }, // Format_Indexed8 { 0, @@ -2991,7 +3074,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma convert_RGB_to_RGB30_inplace, 0, 0, 0, - 0, 0, 0 + 0, 0, 0, 0 }, // Format_RGB32 { 0, @@ -3018,7 +3101,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma convert_RGB_to_RGB30_inplace, 0, 0, 0, - 0, 0, 0 + 0, 0, 0, 0 }, // Format_ARGB32 { 0, @@ -3042,34 +3125,34 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma convert_ARGB_to_RGBA_inplace, 0, 0, 0, 0, 0, 0, - 0, 0, 0 + 0, 0, 0, 0 }, // Format_ARGB32_Premultiplied { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB16 { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_ARGB8565_Premultiplied { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB666 { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_ARGB6666_Premultiplied { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB555 { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_ARGB8555_Premultiplied { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB888 { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB444 { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_ARGB4444_Premultiplied { 0, @@ -3096,7 +3179,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma convert_RGB_to_RGB30_inplace, 0, 0, 0, - 0, 0, 0 + 0, 0, 0, 0 }, // Format_RGBX8888 { 0, @@ -3123,7 +3206,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma convert_RGB_to_RGB30_inplace, 0, 0, 0, - 0, 0, 0 + 0, 0, 0, 0 }, // Format_RGBA8888 { 0, @@ -3145,7 +3228,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGBA8888_Premultiplied { 0, @@ -3172,7 +3255,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma convert_BGR30_to_RGB30_inplace, convert_BGR30_to_A2RGB30_inplace, 0, 0, - 0, 0, 0 + 0, 0, 0, 0 }, // Format_BGR30 { 0, @@ -3198,8 +3281,8 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, // self convert_A2RGB30_PM_to_RGB30_inplace, convert_BGR30_to_RGB30_inplace, - 0, 0, 0, 0, 0 - }, // Format_BGR30A2_Premultiplied + 0, 0, 0, 0, 0, 0 + }, // Format_A2BGR30_Premultiplied { 0, 0, @@ -3224,7 +3307,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma convert_BGR30_to_A2RGB30_inplace, 0, // self convert_passthrough_inplace, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0 }, // Format_RGB30 { 0, @@ -3251,8 +3334,8 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma convert_A2RGB30_PM_to_RGB30_inplace, 0, // self 0, 0, - 0, 0, 0 - }, // Format_RGB30A2_Premultiplied + 0, 0, 0, 0 + }, // Format_A2RGB30_Premultiplied { 0, 0, @@ -3276,7 +3359,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, 0, 0, // self 0, - 0, 0, 0 + 0, 0, 0, 0 }, // Format_Alpha8 { 0, @@ -3301,26 +3384,32 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, 0, 0, 0, // self - 0, 0, 0 + 0, 0, 0, 0 }, // Format_Grayscale8 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // self convert_passthrough_inplace, convert_passthrough_inplace, + 0 }, // Format_RGBX64 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, convert_RGBA64_to_RGBx64_inplace, 0, // self - convert_RGBA64_to_RGBA64PM_inplace + convert_RGBA64_to_RGBA64PM_inplace, + 0 }, // Format_RGBA64 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, convert_RGBA64PM_to_RGBA64_inplace, convert_RGBA64PM_to_RGBA64_inplace, - 0 // self - } // Format_RGBA64_Premultiplied + 0, // self + 0 + }, // Format_RGBA64_Premultiplied + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, // Format_Grayscale16 }; static void qInitImageConversions() diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h index e3a6c53833..de12a313e8 100644 --- a/src/gui/image/qimage_p.h +++ b/src/gui/image/qimage_p.h @@ -189,6 +189,7 @@ inline int qt_depthForFormat(QImage::Format format) case QImage::Format_RGB16: case QImage::Format_RGB444: case QImage::Format_ARGB4444_Premultiplied: + case QImage::Format_Grayscale16: depth = 16; break; case QImage::Format_RGB666: diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp index 13c1c29d5b..2732bbd197 100644 --- a/src/gui/image/qpixmap_raster.cpp +++ b/src/gui/image/qpixmap_raster.cpp @@ -203,6 +203,9 @@ void QRasterPlatformPixmap::fill(const QColor &color) pixel = qAlpha(color.rgba()); } else if (image.format() == QImage::Format_Grayscale8) { pixel = qGray(color.rgba()); + } else if (image.format() == QImage::Format_Grayscale16) { + QRgba64 c = color.rgba64(); + pixel = qGray(c.red(), c.green(), c.blue()); } else { pixel = 0; diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index 8ae03d5d38..3655c39326 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -266,6 +266,18 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scal else if (g == 1) image.setColor(0, qRgba(255, 255, 255, 0)); } + } else if (bit_depth == 16 + && png_get_channels(png_ptr, info_ptr) == 1 + && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { + if (image.size() != QSize(width, height) || image.format() != QImage::Format_Grayscale16) { + image = QImage(width, height, QImage::Format_Grayscale16); + if (image.isNull()) + return; + } + + png_read_update_info(png_ptr, info_ptr); + if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) + png_set_swap(png_ptr); } else if (bit_depth == 16) { bool hasMask = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS); if (!hasMask) @@ -687,7 +699,7 @@ QImage::Format QPngHandlerPrivate::readImageFormat() if (bit_depth == 1 && png_get_channels(png_ptr, info_ptr) == 1) { format = QImage::Format_Mono; } else if (bit_depth == 16) { - format = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) ? QImage::Format_RGBA64 : QImage::Format_RGBX64; + format = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) ? QImage::Format_RGBA64 : QImage::Format_Grayscale16; } else if (bit_depth == 8 && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { format = QImage::Format_Grayscale8; } else { @@ -861,7 +873,8 @@ bool QPNGImageWriter::writeImage(const QImage& image, volatile int compression_i else color_type = PNG_COLOR_TYPE_PALETTE; } - else if (image.format() == QImage::Format_Grayscale8) + else if (image.format() == QImage::Format_Grayscale8 + || image.format() == QImage::Format_Grayscale16) color_type = PNG_COLOR_TYPE_GRAY; else if (image.hasAlphaChannel()) color_type = PNG_COLOR_TYPE_RGB_ALPHA; @@ -877,6 +890,7 @@ bool QPNGImageWriter::writeImage(const QImage& image, volatile int compression_i case QImage::Format_RGBX64: case QImage::Format_RGBA64: case QImage::Format_RGBA64_Premultiplied: + case QImage::Format_Grayscale16: bpc = 16; break; default: @@ -988,6 +1002,7 @@ bool QPNGImageWriter::writeImage(const QImage& image, volatile int compression_i case QImage::Format_RGBX64: case QImage::Format_RGBA64: case QImage::Format_RGBA64_Premultiplied: + case QImage::Format_Grayscale16: png_set_swap(png_ptr); break; default: @@ -1018,6 +1033,7 @@ bool QPNGImageWriter::writeImage(const QImage& image, volatile int compression_i case QImage::Format_MonoLSB: case QImage::Format_Indexed8: case QImage::Format_Grayscale8: + case QImage::Format_Grayscale16: case QImage::Format_RGB32: case QImage::Format_ARGB32: case QImage::Format_RGB888: diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp index 001cb839fa..042b9ebd79 100644 --- a/src/gui/opengl/qopenglpaintengine.cpp +++ b/src/gui/opengl/qopenglpaintengine.cpp @@ -1574,14 +1574,15 @@ void QOpenGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, c case QImage::Format_Alpha8: if (ctx->functions()->hasOpenGLFeature(QOpenGLFunctions::TextureRGFormats)) { d->shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::AlphaImageSrc); - bindOption = QOpenGLTextureUploader::UseRedFor8BitBindOption; + bindOption = QOpenGLTextureUploader::UseRedForAlphaAndLuminanceBindOption; } else d->shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::ImageSrc); break; case QImage::Format_Grayscale8: + case QImage::Format_Grayscale16: if (ctx->functions()->hasOpenGLFeature(QOpenGLFunctions::TextureRGFormats)) { d->shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::GrayscaleImageSrc); - bindOption = QOpenGLTextureUploader::UseRedFor8BitBindOption; + bindOption = QOpenGLTextureUploader::UseRedForAlphaAndLuminanceBindOption; } else d->shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::ImageSrc); break; diff --git a/src/gui/opengl/qopengltextureuploader.cpp b/src/gui/opengl/qopengltextureuploader.cpp index 42e309b733..90253546c8 100644 --- a/src/gui/opengl/qopengltextureuploader.cpp +++ b/src/gui/opengl/qopengltextureuploader.cpp @@ -104,7 +104,7 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag const bool isOpenGLES3orBetter = context->isOpenGLES() && context->format().majorVersion() >= 3; const bool sRgbBinding = (options & SRgbBindOption); Q_ASSERT(isOpenGL12orBetter || context->isOpenGLES()); - Q_ASSERT((options & (SRgbBindOption | UseRedFor8BitBindOption)) != (SRgbBindOption | UseRedFor8BitBindOption)); + Q_ASSERT((options & (SRgbBindOption | UseRedForAlphaAndLuminanceBindOption)) != (SRgbBindOption | UseRedForAlphaAndLuminanceBindOption)); switch (image.format()) { case QImage::Format_RGB32: @@ -213,7 +213,7 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag if (sRgbBinding) { // Always needs conversion break; - } else if (options & UseRedFor8BitBindOption) { + } else if (options & UseRedForAlphaAndLuminanceBindOption) { externalFormat = internalFormat = GL_RED; pixelType = GL_UNSIGNED_BYTE; targetFormat = image.format(); @@ -223,7 +223,7 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag if (sRgbBinding) { // Always needs conversion break; - } else if (options & UseRedFor8BitBindOption) { + } else if (options & UseRedForAlphaAndLuminanceBindOption) { externalFormat = internalFormat = GL_RED; pixelType = GL_UNSIGNED_BYTE; targetFormat = image.format(); @@ -243,7 +243,7 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag if (sRgbBinding) { // Always needs conversion break; - } else if (options & UseRedFor8BitBindOption) { + } else if (options & UseRedForAlphaAndLuminanceBindOption) { externalFormat = internalFormat = GL_RED; pixelType = GL_UNSIGNED_BYTE; targetFormat = image.format(); @@ -259,6 +259,26 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag targetFormat = image.format(); } break; + case QImage::Format_Grayscale16: + if (sRgbBinding) { + // Always needs conversion + break; + } else if (options & UseRedForAlphaAndLuminanceBindOption) { + externalFormat = internalFormat = GL_RED; + pixelType = GL_UNSIGNED_SHORT; + targetFormat = image.format(); + } else if (context->isOpenGLES() || context->format().profile() != QSurfaceFormat::CoreProfile) { + externalFormat = internalFormat = GL_LUMINANCE; + pixelType = GL_UNSIGNED_SHORT; + targetFormat = image.format(); + } else if (funcs->hasOpenGLExtension(QOpenGLExtensions::TextureSwizzle)) { + GLint swizzle[4] = { GL_RED, GL_RED, GL_RED, GL_ONE }; + funcs->glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle); + externalFormat = internalFormat = GL_RED; + pixelType = GL_UNSIGNED_SHORT; + targetFormat = image.format(); + } + break; default: break; } diff --git a/src/gui/opengl/qopengltextureuploader_p.h b/src/gui/opengl/qopengltextureuploader_p.h index d758b3787b..0dcf709d7e 100644 --- a/src/gui/opengl/qopengltextureuploader_p.h +++ b/src/gui/opengl/qopengltextureuploader_p.h @@ -65,7 +65,7 @@ public: enum BindOption { NoBindOption = 0x0000, PremultipliedAlphaBindOption = 0x0001, - UseRedFor8BitBindOption = 0x0002, + UseRedForAlphaAndLuminanceBindOption = 0x0002, SRgbBindOption = 0x0004, PowerOfTwoBindOption = 0x0008 }; diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 9ef210cc68..af9375fcec 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -857,6 +857,44 @@ static const QRgba64 *QT_FASTCALL fetchGrayscale8ToRGB64(QRgba64 *buffer, const return buffer; } +static void QT_FASTCALL convertGrayscale16ToRGB32(uint *buffer, int count, const QVector *) +{ + for (int i = 0; i < count; ++i) { + const uint x = qt_div_257(buffer[i]); + buffer[i] = qRgb(x, x, x); + } +} + +static const uint *QT_FASTCALL fetchGrayscale16ToRGB32(uint *buffer, const uchar *src, int index, int count, + const QVector *, QDitherInfo *) +{ + const unsigned short *s = reinterpret_cast(src) + index; + for (int i = 0; i < count; ++i) { + const uint x = qt_div_257(s[i]); + buffer[i] = qRgb(x, x, x); + } + return buffer; +} + +static const QRgba64 *QT_FASTCALL convertGrayscale16ToRGBA64(QRgba64 *buffer, const uint *src, int count, + const QVector *, QDitherInfo *) +{ + const unsigned short *s = reinterpret_cast(src); + for (int i = 0; i < count; ++i) + buffer[i] = QRgba64::fromRgba64(s[i], s[i], s[i], 65535); + return buffer; +} + +static const QRgba64 *QT_FASTCALL fetchGrayscale16ToRGBA64(QRgba64 *buffer, const uchar *src, int index, int count, + const QVector *, QDitherInfo *) +{ + const unsigned short *s = reinterpret_cast(src) + index; + for (int i = 0; i < count; ++i) { + buffer[i] = QRgba64::fromRgba64(s[i], s[i], s[i], 65535); + } + return buffer; +} + static void QT_FASTCALL storeARGB32FromARGB32PM(uchar *dest, const uint *src, int index, int count, const QVector *, QDitherInfo *) { @@ -1362,6 +1400,22 @@ static void QT_FASTCALL storeGrayscale8FromARGB32PM(uchar *dest, const uint *src dest[index + i] = qGray(qUnpremultiply(src[i])); } +static void QT_FASTCALL storeGrayscale16FromRGB32(uchar *dest, const uint *src, int index, int count, + const QVector *, QDitherInfo *) +{ + unsigned short *d = reinterpret_cast(dest) + index; + for (int i = 0; i < count; ++i) + d[i] = qGray(src[i]) * 257; +} + +static void QT_FASTCALL storeGrayscale16FromARGB32PM(uchar *dest, const uint *src, int index, int count, + const QVector *, QDitherInfo *) +{ + unsigned short *d = reinterpret_cast(dest) + index; + for (int i = 0; i < count; ++i) + d[i] = qGray(qUnpremultiply(src[i])) * 257; +} + static const uint *QT_FASTCALL fetchRGB64ToRGB32(uint *buffer, const uchar *src, int index, int count, const QVector *, QDitherInfo *) { @@ -1488,7 +1542,11 @@ QPixelLayout qPixelLayouts[QImage::NImageFormats] = { { true, true, QPixelLayout::BPP64, nullptr, convertPassThrough, nullptr, fetchRGB64ToRGB32, fetchPassThrough64, - storeRGB64FromRGB32, storeRGB64FromRGB32 } // Format_RGBA64_Premultiplied + storeRGB64FromRGB32, storeRGB64FromRGB32 }, // Format_RGBA64_Premultiplied + { false, false, QPixelLayout::BPP16, nullptr, + convertGrayscale16ToRGB32, convertGrayscale16ToRGBA64, + fetchGrayscale16ToRGB32, fetchGrayscale16ToRGBA64, + storeGrayscale16FromARGB32PM, storeGrayscale16FromRGB32 } // Format_Grayscale16 }; Q_STATIC_ASSERT(sizeof(qPixelLayouts) / sizeof(*qPixelLayouts) == QImage::NImageFormats); @@ -1564,6 +1622,16 @@ static void QT_FASTCALL storeRGBA64PMFromRGBA64PM(uchar *dest, const QRgba64 *sr memcpy(d, src, count * sizeof(QRgba64)); } +static void QT_FASTCALL storeGray16FromRGBA64PM(uchar *dest, const QRgba64 *src, int index, int count, + const QVector *, QDitherInfo *) +{ + quint16 *d = reinterpret_cast(dest) + index; + for (int i = 0; i < count; ++i) { + QRgba64 s = src[i].unpremultiplied(); + d[i] = qGray(s.red(), s.green(), s.blue()); + } +} + ConvertAndStorePixelsFunc64 qStoreFromRGBA64PM[QImage::NImageFormats] = { nullptr, nullptr, @@ -1592,7 +1660,8 @@ ConvertAndStorePixelsFunc64 qStoreFromRGBA64PM[QImage::NImageFormats] = { storeGenericFromRGBA64PM, storeRGBX64FromRGBA64PM, storeRGBA64FromRGBA64PM, - storeRGBA64PMFromRGBA64PM + storeRGBA64PMFromRGBA64PM, + storeGray16FromRGBA64PM }; /* @@ -1696,6 +1765,7 @@ static DestFetchProc destFetchProc[QImage::NImageFormats] = destFetch, // Format_RGBX64 destFetch, // Format_RGBA64 destFetch, // Format_RGBA64_Premultiplied + destFetch, // Format_Grayscale16 }; static DestFetchProc64 destFetchProc64[QImage::NImageFormats] = @@ -1728,6 +1798,7 @@ static DestFetchProc64 destFetchProc64[QImage::NImageFormats] = destFetchRGB64, // Format_RGBX64 destFetch64, // Format_RGBA64 destFetchRGB64, // Format_RGBA64_Premultiplied + destFetch64, // Format_Grayscale16 }; /* @@ -1881,6 +1952,7 @@ static DestStoreProc destStoreProc[QImage::NImageFormats] = destStore, // Format_RGBX64 destStore, // Format_RGBA64 destStore, // Format_RGBA64_Premultiplied + destStore, // Format_Grayscale16 }; static DestStoreProc64 destStoreProc64[QImage::NImageFormats] = @@ -1912,7 +1984,8 @@ static DestStoreProc64 destStoreProc64[QImage::NImageFormats] = destStore64, // Format_Grayscale8 0, // Format_RGBX64 destStore64RGBA64, // Format_RGBA64 - 0 // Format_RGBA64_Premultiplied + 0, // Format_RGBA64_Premultiplied + destStore64, // Format_Grayscale16 }; /* @@ -3839,6 +3912,7 @@ static SourceFetchProc sourceFetchUntransformed[QImage::NImageFormats] = { fetchUntransformed, // RGBX64 fetchUntransformed, // RGBA64 fetchUntransformed, // RGBA64_Premultiplied + fetchUntransformed, // Grayscale16 }; static const SourceFetchProc sourceFetchGeneric[NBlendTypes] = { @@ -5253,6 +5327,7 @@ void qBlendTexture(int count, const QSpan *spans, void *userData) case QImage::Format_RGBX64: case QImage::Format_RGBA64: case QImage::Format_RGBA64_Premultiplied: + case QImage::Format_Grayscale16: proc = processTextureSpansGeneric64[blendType]; break; case QImage::Format_Invalid: @@ -6259,6 +6334,14 @@ DrawHelper qDrawHelper[QImage::NImageFormats] = qt_alphargbblit_generic, qt_rectfill_quint64 }, + // Format_Grayscale16 + { + blend_color_generic_rgb64, + 0, + qt_alphamapblit_generic, + qt_alphargbblit_generic, + qt_rectfill_quint16 + }, }; #if !defined(__SSE2__) diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 4dcfbc813b..37108949d6 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -879,6 +879,8 @@ static Q_ALWAYS_INLINE uint BYTE_MUL_RGB16_32(uint x, uint a) { // qt_div_255 is a fast rounded division by 255 using an approximation that is accurate for all positive 16-bit integers static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE int qt_div_255(int x) { return (x + (x>>8) + 0x80) >> 8; } +static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_div_257_floor(uint x) { return (x - (x >> 8)) >> 8; } +static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_div_257(uint x) { return qt_div_257_floor(x + 128); } static Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_div_65535(uint x) { return (x + (x>>16) + 0x8000U) >> 16; } static Q_ALWAYS_INLINE uint qAlphaRgb30(uint c) diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 5ffd75f931..2e2cb52b3e 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -298,6 +298,8 @@ static QLatin1String formatToString(QImage::Format format) return QLatin1String("RGBA64"); case QImage::Format_RGBA64_Premultiplied: return QLatin1String("RGBA64pm"); + case QImage::Format_Grayscale16: + return QLatin1String("Grayscale16"); default: break; }; @@ -2366,8 +2368,11 @@ void tst_QImage::rgbSwapped_data() QTest::addColumn("format"); for (int i = QImage::Format_Indexed8; i < QImage::NImageFormats; ++i) { - if (i == QImage::Format_Alpha8 || i == QImage::Format_Grayscale8) + if (i == QImage::Format_Alpha8 + || i == QImage::Format_Grayscale8 + || i == QImage::Format_Grayscale16) { continue; + } QTest::addRow("%s", formatToString(QImage::Format(i)).data()) << QImage::Format(i); } } @@ -2612,8 +2617,11 @@ void tst_QImage::inplaceMirrored_data() QTest::addColumn("swap_horizontal"); for (int i = QImage::Format_Mono; i < QImage::NImageFormats; ++i) { - if (i == QImage::Format_Alpha8 || i == QImage::Format_Grayscale8) + if (i == QImage::Format_Alpha8 + || i == QImage::Format_Grayscale8 + || i == QImage::Format_Grayscale16) { continue; + } if (i == QImage::Format_RGB444 || i == QImage::Format_ARGB4444_Premultiplied) continue; const auto fmt = formatToString(QImage::Format(i)); @@ -2785,11 +2793,11 @@ void tst_QImage::genericRgbConversion_data() QTest::addColumn("dest_format"); for (int i = QImage::Format_RGB32; i < QImage::NImageFormats; ++i) { - if (i == QImage::Format_Alpha8 || i == QImage::Format_Grayscale8) + if (i == QImage::Format_Alpha8) continue; const QLatin1String formatI = formatToString(QImage::Format(i)); for (int j = QImage::Format_RGB32; j < QImage::NImageFormats; ++j) { - if (j == QImage::Format_Alpha8 || j == QImage::Format_Grayscale8) + if (j == QImage::Format_Alpha8) continue; if (i == j) continue; @@ -2805,6 +2813,9 @@ void tst_QImage::genericRgbConversion() QFETCH(QImage::Format, format); QFETCH(QImage::Format, dest_format); + bool srcGrayscale = format == QImage::Format_Grayscale8 || format == QImage::Format_Grayscale16; + bool dstGrayscale = dest_format == QImage::Format_Grayscale8 || dest_format == QImage::Format_Grayscale16; + QImage image(16, 16, format); for (int i = 0; i < image.height(); ++i) @@ -2816,8 +2827,12 @@ void tst_QImage::genericRgbConversion() for (int i = 0; i < imageConverted.height(); ++i) { for (int j = 0; j < imageConverted.width(); ++j) { QRgb convertedColor = imageConverted.pixel(j,i); - QCOMPARE(qRed(convertedColor) & 0xF0, j * 16); - QCOMPARE(qGreen(convertedColor) & 0xF0, i * 16); + if (srcGrayscale || dstGrayscale) { + QVERIFY(qAbs(qGray(convertedColor) - qGray(qRgb(j*16, i*16, 0))) < 15); + } else { + QCOMPARE(qRed(convertedColor) & 0xF0, j * 16); + QCOMPARE(qGreen(convertedColor) & 0xF0, i * 16); + } } } } @@ -2828,11 +2843,17 @@ void tst_QImage::inplaceRgbConversion_data() QTest::addColumn("dest_format"); for (int i = QImage::Format_RGB32; i < QImage::NImageFormats; ++i) { - if (i == QImage::Format_Alpha8 || i == QImage::Format_Grayscale8) + if (i == QImage::Format_Alpha8 + || i == QImage::Format_Grayscale8 + || i == QImage::Format_Grayscale16) { continue; + } for (int j = QImage::Format_RGB32; j < QImage::NImageFormats; ++j) { - if (j == QImage::Format_Alpha8 || j == QImage::Format_Grayscale8) + if (j == QImage::Format_Alpha8 + || j == QImage::Format_Grayscale8 + || j == QImage::Format_Grayscale16) { continue; + } if (i == j) continue; QTest::addRow("%s -> %s", formatToString(QImage::Format(i)).data(), formatToString(QImage::Format(j)).data()) @@ -3002,8 +3023,11 @@ void tst_QImage::invertPixelsRGB_data() QTest::addColumn("image_format"); for (int i = QImage::Format_RGB32; i < QImage::NImageFormats; ++i) { - if (i == QImage::Format_Alpha8 || i == QImage::Format_Grayscale8) + if (i == QImage::Format_Alpha8 + || i == QImage::Format_Grayscale8 + || i == QImage::Format_Grayscale16) { continue; + } QTest::addRow("%s", formatToString(QImage::Format(i)).data()) << QImage::Format(i); } } diff --git a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp index c2ec5b8925..1cf01133b2 100644 --- a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp +++ b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp @@ -525,7 +525,7 @@ void tst_QImageReader::imageFormat_data() QTest::newRow("png") << QString("kollada.png") << QByteArray("png") << QImage::Format_ARGB32; QTest::newRow("png-2") << QString("YCbCr_cmyk.png") << QByteArray("png") << QImage::Format_RGB32; QTest::newRow("png-3") << QString("kollada-16bpc.png") << QByteArray("png") << QImage::Format_RGBA64; - QTest::newRow("png-4") << QString("basn0g16.png") << QByteArray("png") << QImage::Format_RGBX64; // Grayscale16 + QTest::newRow("png-4") << QString("basn0g16.png") << QByteArray("png") << QImage::Format_Grayscale16; QTest::newRow("png-5") << QString("basn2c16.png") << QByteArray("png") << QImage::Format_RGBX64; QTest::newRow("png-6") << QString("basn4a16.png") << QByteArray("png") << QImage::Format_RGBA64; // Grayscale16Alpha16 QTest::newRow("png-7") << QString("basn6a16.png") << QByteArray("png") << QImage::Format_RGBA64; diff --git a/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp b/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp index 77851cd7d0..aaa8475c74 100644 --- a/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp +++ b/tests/auto/gui/image/qimagewriter/tst_qimagewriter.cpp @@ -239,7 +239,7 @@ void tst_QImageWriter::writeImage2_data() // QLatin1String("jpeg"), }; - QImage image0(70, 70, QImage::Format_ARGB32); + QImage image0(70, 70, QImage::Format_RGB32); image0.fill(QColor(Qt::red).rgb()); QImage::Format imgFormat = QImage::Format_Mono; @@ -304,10 +304,10 @@ void tst_QImageWriter::writeImage2() if (!equalImageContents(written, image)) { qDebug() << "image" << image.format() << image.width() << image.height() << image.depth() - << hex << image.pixel(0, 0); + << image.pixelColor(0, 0); qDebug() << "written" << written.format() << written.width() << written.height() << written.depth() - << hex << written.pixel(0, 0); + << written.pixelColor(0, 0); } QVERIFY(equalImageContents(written, image)); From eaf4438b3511c8380b9b691b656a87a60e342e29 Mon Sep 17 00:00:00 2001 From: Joni Poikelin Date: Tue, 11 Dec 2018 11:42:34 +0200 Subject: [PATCH 0626/1650] Make url normalization closer to common browser behavior MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Firefox, Chrome and various http libraries normalize /./ and /../ from urls, but retain multiple adjacent slashes as is. Qt removes duplicated slashes which makes it impossible to access some web resources that rely on those. Fixes: QTBUG-71973 Change-Id: Ie18ae6ad3264acb252fcd87a754726a8c546e5ec Reviewed-by: Edward Welbourne Reviewed-by: Mårten Nordheim Reviewed-by: Thiago Macieira --- src/corelib/io/qdir.cpp | 64 +++++++++++++++++++++---- src/corelib/io/qdir_p.h | 12 +++++ src/corelib/io/qurl.cpp | 8 ++-- tests/auto/corelib/io/qdir/tst_qdir.cpp | 9 +--- tests/auto/corelib/io/qurl/tst_qurl.cpp | 36 +++++++++++++- 5 files changed, 106 insertions(+), 23 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 7df461ddce..405718aba8 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -2161,9 +2161,10 @@ bool QDir::match(const QString &filter, const QString &fileName) This method is shared with QUrl, so it doesn't deal with QDir::separator(), nor does it remove the trailing slash, if any. */ -Q_AUTOTEST_EXPORT QString qt_normalizePathSegments(const QString &name, bool allowUncPaths, - bool *ok = nullptr) +QString qt_normalizePathSegments(const QString &name, QDirPrivate::PathNormalizations flags, bool *ok) { + const bool allowUncPaths = QDirPrivate::AllowUncPaths & flags; + const bool isRemote = QDirPrivate::RemotePath & flags; const int len = name.length(); if (ok) @@ -2185,14 +2186,30 @@ Q_AUTOTEST_EXPORT QString qt_normalizePathSegments(const QString &name, bool all i -= prefixLength; // replicate trailing slash (i > 0 checks for emptiness of input string p) - if (i > 0 && p[i] == '/') { + // except for remote paths because there can be /../ or /./ ending + if (i > 0 && p[i] == '/' && !isRemote) { out[--used] = '/'; --i; } + auto isDot = [](const ushort *p, int i) { + return i > 1 && p[i - 1] == '.' && p[i - 2] == '/'; + }; + auto isDotDot = [](const ushort *p, int i) { + return i > 2 && p[i - 1] == '.' && p[i - 2] == '.' && p[i - 3] == '/'; + }; + while (i >= 0) { - // remove trailing slashes + // copy trailing slashes for remote urls if (p[i] == '/') { + if (isRemote && !up) { + if (isDot(p, i)) { + i -= 2; + continue; + } + out[--used] = p[i]; + } + --i; continue; } @@ -2204,10 +2221,17 @@ Q_AUTOTEST_EXPORT QString qt_normalizePathSegments(const QString &name, bool all } // detect up dir - if (i >= 1 && p[i] == '.' && p[i-1] == '.' - && (i == 1 || (i >= 2 && p[i-2] == '/'))) { + if (i >= 1 && p[i] == '.' && p[i-1] == '.' && (i < 2 || p[i - 2] == '/')) { ++up; - i -= 2; + i -= i >= 2 ? 3 : 2; + + if (isRemote) { + // moving up should consider empty path segments too (/path//../ -> /path/) + while (i > 0 && up && p[i] == '/') { + --up; + --i; + } + } continue; } @@ -2217,7 +2241,27 @@ Q_AUTOTEST_EXPORT QString qt_normalizePathSegments(const QString &name, bool all // skip or copy while (i >= 0) { - if (p[i] == '/') { // do not copy slashes + if (p[i] == '/') { + // copy all slashes as is for remote urls if they are not part of /./ or /../ + if (isRemote && !up) { + while (i > 0 && p[i] == '/' && !isDotDot(p, i)) { + + if (isDot(p, i)) { + i -= 2; + continue; + } + + out[--used] = p[i]; + --i; + } + + // in case of /./, jump over + if (isDot(p, i)) + i -= 2; + + break; + } + --i; break; } @@ -2238,7 +2282,7 @@ Q_AUTOTEST_EXPORT QString qt_normalizePathSegments(const QString &name, bool all *ok = prefixLength == 0 || up == 0; // add remaining '..' - while (up) { + while (up && !isRemote) { if (used != len && out[used] != '/') // is not empty and there isn't already a '/' out[--used] = '/'; out[--used] = '.'; @@ -2284,7 +2328,7 @@ static QString qt_cleanPath(const QString &path, bool *ok) if (dir_separator != QLatin1Char('/')) name.replace(dir_separator, QLatin1Char('/')); - QString ret = qt_normalizePathSegments(name, OSSupportsUncPaths, ok); + QString ret = qt_normalizePathSegments(name, OSSupportsUncPaths ? QDirPrivate::AllowUncPaths : QDirPrivate::DefaultNormalization, ok); // Strip away last slash except for root directories if (ret.length() > 1 && ret.endsWith(QLatin1Char('/'))) { diff --git a/src/corelib/io/qdir_p.h b/src/corelib/io/qdir_p.h index 85d915223c..0f3ab7f899 100644 --- a/src/corelib/io/qdir_p.h +++ b/src/corelib/io/qdir_p.h @@ -59,6 +59,14 @@ QT_BEGIN_NAMESPACE class QDirPrivate : public QSharedData { public: + enum PathNormalization { + DefaultNormalization = 0x00, + AllowUncPaths = 0x01, + RemotePath = 0x02 + }; + Q_DECLARE_FLAGS(PathNormalizations, PathNormalization) + Q_FLAGS(PathNormalizations) + explicit QDirPrivate(const QString &path, const QStringList &nameFilters_ = QStringList(), QDir::SortFlags sort_ = QDir::SortFlags(QDir::Name | QDir::IgnoreCase), QDir::Filters filters_ = QDir::AllEntries); @@ -97,6 +105,10 @@ public: mutable QFileSystemMetaData metaData; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QDirPrivate::PathNormalizations) + +Q_AUTOTEST_EXPORT QString qt_normalizePathSegments(const QString &name, QDirPrivate::PathNormalizations flags, bool *ok = nullptr); + QT_END_NAMESPACE #endif diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index b324df53b2..6d82981fd6 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -253,7 +253,8 @@ and contains no query or fragment, a local file path is returned. \value StripTrailingSlash The trailing slash is removed from the path, if one is present. \value NormalizePathSegments Modifies the path to remove redundant directory separators, - and to resolve "."s and ".."s (as far as possible). + and to resolve "."s and ".."s (as far as possible). For non-local paths, adjacent + slashes are preserved. Note that the case folding rules in \l{RFC 3491}{Nameprep}, which QUrl conforms to, require host names to always be converted to lower case, @@ -419,10 +420,9 @@ #endif #include "private/qipaddress_p.h" #include "qurlquery.h" +#include "private/qdir_p.h" QT_BEGIN_NAMESPACE -extern QString qt_normalizePathSegments(const QString &name, bool allowUncPaths, - bool *ok = nullptr); // qdir.cpp inline static bool isHex(char c) { @@ -930,7 +930,7 @@ inline void QUrlPrivate::appendPath(QString &appendTo, QUrl::FormattingOptions o { QString thePath = path; if (options & QUrl::NormalizePathSegments) { - thePath = qt_normalizePathSegments(path, false); + thePath = qt_normalizePathSegments(path, isLocalFile() ? QDirPrivate::DefaultNormalization : QDirPrivate::RemotePath); } QStringRef thePathRef(&thePath); diff --git a/tests/auto/corelib/io/qdir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/tst_qdir.cpp index 30f0e447ad..af9c6be432 100644 --- a/tests/auto/corelib/io/qdir/tst_qdir.cpp +++ b/tests/auto/corelib/io/qdir/tst_qdir.cpp @@ -62,12 +62,7 @@ #endif #ifdef QT_BUILD_INTERNAL - -QT_BEGIN_NAMESPACE -extern Q_AUTOTEST_EXPORT QString - qt_normalizePathSegments(const QString &path, bool allowUncPaths, bool *ok = nullptr); -QT_END_NAMESPACE - +#include "private/qdir_p.h" #endif static QByteArray msgDoesNotExist(const QString &name) @@ -1376,7 +1371,7 @@ void tst_QDir::normalizePathSegments() QFETCH(QString, path); QFETCH(UncHandling, uncHandling); QFETCH(QString, expected); - QString cleaned = qt_normalizePathSegments(path, uncHandling == HandleUnc); + QString cleaned = qt_normalizePathSegments(path, uncHandling == HandleUnc ? QDirPrivate::AllowUncPaths : QDirPrivate::DefaultNormalization); QCOMPARE(cleaned, expected); if (path == expected) QVERIFY2(path.isSharedWith(cleaned), "Strings are same but data is not shared"); diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 84af1c255a..4f173d2dfd 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -182,6 +182,8 @@ private slots: void matches(); void ipv6_zoneId_data(); void ipv6_zoneId(); + void normalizeRemotePaths_data(); + void normalizeRemotePaths(); private: void testThreadingHelper(); @@ -323,7 +325,7 @@ void tst_QUrl::comparison() QUrl url3bis = QUrl::fromEncoded("example://a/b/c/%7Bfoo%7D/"); QUrl url3bisNoSlash = QUrl::fromEncoded("example://a/b/c/%7Bfoo%7D"); - QUrl url4bis = QUrl::fromEncoded("example://a/.//b/../b/c//%7Bfoo%7D/"); + QUrl url4bis = QUrl::fromEncoded("example://a/./b/../b/c/%7Bfoo%7D/"); QCOMPARE(url4bis.adjusted(QUrl::NormalizePathSegments), url3bis); QCOMPARE(url4bis.adjusted(QUrl::NormalizePathSegments | QUrl::StripTrailingSlash), url3bisNoSlash); QVERIFY(url3bis.matches(url4bis, QUrl::NormalizePathSegments)); @@ -335,7 +337,7 @@ void tst_QUrl::comparison() QCOMPARE(url4EncodedDots.path(QUrl::FullyDecoded), QString("/.//b/..//b/c/")); QCOMPARE(QString::fromLatin1(url4EncodedDots.toEncoded()), QString::fromLatin1("example://a/.//b/..%2F/b/c/")); QCOMPARE(url4EncodedDots.toString(), QString("example://a/.//b/..%2F/b/c/")); - QCOMPARE(url4EncodedDots.adjusted(QUrl::NormalizePathSegments).toString(), QString("example://a/b/..%2F/b/c/")); + QCOMPARE(url4EncodedDots.adjusted(QUrl::NormalizePathSegments).toString(), QString("example://a//b/..%2F/b/c/")); // 6.2.2.1 Make sure hexdecimal characters in percent encoding are // treated case-insensitively @@ -4201,6 +4203,36 @@ void tst_QUrl::ipv6_zoneId() QCOMPARE(url.toString(QUrl::FullyEncoded), "x://[" + encodedHost + "]"); } +void tst_QUrl::normalizeRemotePaths_data() +{ + QTest::addColumn("url"); + QTest::addColumn("expected"); + + QTest::newRow("dotdot-slashslash") << QUrl("http://qt-project.org/some/long/..//path") << "http://qt-project.org/some//path"; + QTest::newRow("slashslash-dotdot") << QUrl("http://qt-project.org/some//../path") << "http://qt-project.org/some/path"; + QTest::newRow("slashslash-dotdot2") << QUrl("http://qt-project.org/some//path/../") << "http://qt-project.org/some//"; + QTest::newRow("dot-slash") << QUrl("http://qt-project.org/some/./path") << "http://qt-project.org/some/path"; + QTest::newRow("slashslash-dot-slashslash") << QUrl("http://qt-project.org/some//.//path") << "http://qt-project.org/some///path"; + QTest::newRow("dot-slashslash") << QUrl("http://qt-project.org/some/.//path") << "http://qt-project.org/some//path"; + QTest::newRow("multiple-slashes") << QUrl("http://qt-project.org/some//path") << "http://qt-project.org/some//path"; + QTest::newRow("multiple-slashes4") << QUrl("http://qt-project.org/some////path") << "http://qt-project.org/some////path"; + QTest::newRow("slashes-at-end") << QUrl("http://qt-project.org/some//") << "http://qt-project.org/some//"; + QTest::newRow("dot-dotdot") << QUrl("http://qt-project.org/path/./../") << "http://qt-project.org/"; + QTest::newRow("slash-dot-slash-dot-slash") << QUrl("http://qt-project.org/path//.//.//") << "http://qt-project.org/path////"; + QTest::newRow("dotdot") << QUrl("http://qt-project.org/../") << "http://qt-project.org/"; + QTest::newRow("dotdot-dotdot") << QUrl("http://qt-project.org/path/../../") << "http://qt-project.org/"; + QTest::newRow("dot-dotdot-tail") << QUrl("http://qt-project.org/stem/path/./../tail") << "http://qt-project.org/stem/tail"; + QTest::newRow("slash-dotdot-slash-tail") << QUrl("http://qt-project.org/stem/path//..//tail") << "http://qt-project.org/stem/path//tail"; +} + +void tst_QUrl::normalizeRemotePaths() +{ + QFETCH(QUrl, url); + QFETCH(QString, expected); + + QCOMPARE(url.adjusted(QUrl::NormalizePathSegments).toString(), expected); +} + QTEST_MAIN(tst_QUrl) #include "tst_qurl.moc" From 9ce4260d232d94a9c902333e4b894fc0514d9e6d Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 12 Dec 2018 08:00:55 +0100 Subject: [PATCH 0627/1650] QWindowsLocalCodec::convertToUnicode(): Fix remaining char conversion Prevent passing a zero argument to the cbMultiByte parameter of MultiByteToWideChar. According to the documentation this will always fail. This is triggered when calling convertToUnicode with a state having remainingChars of one and a length of one. The remaining chars will be completed and the length will be reduced to zero before the actual convert. Adding an early return after the completion to prevent calling MultiByteToWideChar with the invalid zero argument. Fixes: QTCREATORBUG-21622 Change-Id: Ic6a433dd929e97b1681583cb1b9a347afaa9a09f Reviewed-by: Edward Welbourne Reviewed-by: Thiago Macieira --- src/corelib/codecs/qwindowscodec.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/corelib/codecs/qwindowscodec.cpp b/src/corelib/codecs/qwindowscodec.cpp index 813d3c8153..37e1183fb6 100644 --- a/src/corelib/codecs/qwindowscodec.cpp +++ b/src/corelib/codecs/qwindowscodec.cpp @@ -83,8 +83,12 @@ QString QWindowsLocalCodec::convertToUnicode(const char *chars, int length, Conv len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, prev, 2, wc.data(), wc.length()); if (len) { - prepend = true; sp.append(QChar(wc[0])); + if (mblen == 1) { + state->remainingChars = 0; + return sp; + } + prepend = true; mb++; mblen--; wc[0] = 0; From ac7265e950664b2e1bc62124a20a72dc199413d8 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 4 Dec 2018 15:48:53 +0100 Subject: [PATCH 0628/1650] uic: No longer generate static_cast for enum values in legacy forms Add a lookup for the affected enum values and use the names instead. Task-number: PYSIDE-797 Change-Id: I6be166409000aff83d9465c9a3b2f37b44c5c085 Reviewed-by: Cristian Maureira-Fredes Reviewed-by: Jarek Kobus --- src/tools/uic/cpp/cppwriteinitialization.cpp | 39 +++----- src/tools/uic/shared/language.cpp | 91 +++++++++++++++++++ src/tools/uic/shared/language.h | 5 + .../tools/uic/baseline/batchtranslation.ui.h | 4 +- .../tools/uic/baseline/browserwidget.ui.h | 10 +- .../tools/uic/baseline/calculatorform.ui.h | 2 +- .../tools/uic/baseline/chatmainwindow.ui.h | 2 +- .../tools/uic/baseline/chatsetnickname.ui.h | 2 +- .../auto/tools/uic/baseline/imagedialog.ui.h | 4 +- tests/auto/tools/uic/baseline/newform.ui.h | 2 +- .../tools/uic/baseline/paletteeditor.ui.h | 6 +- .../tools/uic/baseline/previewdialogbase.ui.h | 6 +- .../tools/uic/baseline/previewwidget.ui.h | 2 +- .../tools/uic/baseline/stylesheeteditor.ui.h | 4 +- .../tools/uic/baseline/tabbedbrowser.ui.h | 2 +- .../tools/uic/baseline/trpreviewtool.ui.h | 4 +- 16 files changed, 136 insertions(+), 49 deletions(-) diff --git a/src/tools/uic/cpp/cppwriteinitialization.cpp b/src/tools/uic/cpp/cppwriteinitialization.cpp index ab4882d1a0..ca9b48ed9c 100644 --- a/src/tools/uic/cpp/cppwriteinitialization.cpp +++ b/src/tools/uic/cpp/cppwriteinitialization.cpp @@ -45,35 +45,26 @@ QT_BEGIN_NAMESPACE namespace { - // Fixup an enumeration name from class Qt. - // They are currently stored as "BottomToolBarArea" instead of "Qt::BottomToolBarArea". - // due to MO issues. This might be fixed in the future. - QLatin1String qtEnumerationPrefix(const QString &name) { - static const QLatin1String prefix("Qt::"); - if (name.indexOf(prefix) != 0) - return prefix; - return QLatin1String(); - } // figure out the toolbar area of a DOM attrib list. // By legacy, it is stored as an integer. As of 4.3.0, it is the enumeration value. QString toolBarAreaStringFromDOMAttributes(const CPP::WriteInitialization::DomPropertyMap &attributes) { const DomProperty *pstyle = attributes.value(QLatin1String("toolBarArea")); + QString result; if (!pstyle) - return QString(); - + return result; switch (pstyle->kind()) { - case DomProperty::Number: { - return QLatin1String("static_cast(") - + QString::number(pstyle->elementNumber()) + QLatin1String("), "); - } - case DomProperty::Enum: { - const QString area = pstyle->elementEnum(); - return qtEnumerationPrefix(area) + area + QLatin1String(", "); - } + case DomProperty::Number: + result = QLatin1String(language::toolbarArea(pstyle->elementNumber())); + break; + case DomProperty::Enum: + result = pstyle->elementEnum(); + break; default: break; } - return QString(); + if (!result.startsWith(QLatin1String("Qt::"))) + result.prepend(QLatin1String("Qt::")); + return result + QLatin1String(", "); } // Write a statement to create a spacer item. @@ -681,7 +672,7 @@ void WriteInitialization::acceptWidget(DomWidget *node) } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QDockWidget"))) { m_output << m_indent << parentWidget << "->addDockWidget("; if (DomProperty *pstyle = attributes.value(QLatin1String("dockWidgetArea"))) - m_output << "static_cast(" << pstyle->elementNumber() << "), "; + m_output << "Qt::" << language::dockWidgetArea(pstyle->elementNumber()) << ", "; m_output << varName << ");\n"; } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QStatusBar"))) { m_output << m_indent << parentWidget << "->setStatusBar(" << varName << ");\n"; @@ -1509,8 +1500,8 @@ QString WriteInitialization::writeSizePolicy(const DomSizePolicy *sp) m_output << m_indent << "QSizePolicy " << spName; do { if (sp->hasElementHSizeType() && sp->hasElementVSizeType()) { - m_output << "(static_cast(" << sp->elementHSizeType() - << "), static_cast(" << sp->elementVSizeType() << "));\n"; + m_output << "(QSizePolicy::" << language::sizePolicy(sp->elementHSizeType()) + << ", QSizePolicy::" << language::sizePolicy(sp->elementVSizeType()) << ");\n"; break; } if (sp->hasAttributeHSizeType() && sp->hasAttributeVSizeType()) { @@ -1767,7 +1758,7 @@ void WriteInitialization::writeColorGroup(DomColorGroup *colorGroup, const QStri const DomColor *color = colors.at(i); m_output << m_indent << paletteName << ".setColor(" << group - << ", " << "static_cast(" << i << ')' + << ", QPalette::" << language::paletteColorRole(i) << ", " << domColor2QString(color) << ");\n"; } diff --git a/src/tools/uic/shared/language.cpp b/src/tools/uic/shared/language.cpp index 2ab89c2d7b..730e1562bc 100644 --- a/src/tools/uic/shared/language.cpp +++ b/src/tools/uic/shared/language.cpp @@ -50,4 +50,95 @@ QTextStream &operator<<(QTextStream &str, const closeQtConfig &c) return str; } +struct EnumLookup +{ + int value; + const char *valueString; +}; + +template +const char *lookupEnum(const EnumLookup(&array)[N], int value, int defaultIndex = 0) +{ + for (int i = 0; i < N; ++i) { + if (value == array[i].value) + return array[i].valueString; + } + const char *defaultValue = array[defaultIndex].valueString; + qWarning("uic: Warning: Invalid enumeration value %d, defaulting to %s", + value, defaultValue); + return defaultValue; +} + +const char *toolbarArea(int v) +{ + static const EnumLookup toolBarAreas[] = + { + {0, "NoToolBarArea"}, + {0x1, "LeftToolBarArea"}, + {0x2, "RightToolBarArea"}, + {0x4, "TopToolBarArea"}, + {0x8, "BottomToolBarArea"}, + {0xf, "AllToolBarAreas"} + }; + return lookupEnum(toolBarAreas, v); +} + +const char *sizePolicy(int v) +{ + static const EnumLookup sizePolicies[] = + { + {0, "Fixed"}, + {0x1, "Minimum"}, + {0x4, "Maximum"}, + {0x5, "Preferred"}, + {0x3, "MinimumExpanding"}, + {0x7, "Expanding"}, + {0xD, "Ignored"} + }; + return lookupEnum(sizePolicies, v, 3); +} + +const char *dockWidgetArea(int v) +{ + static const EnumLookup dockWidgetAreas[] = + { + {0, "NoDockWidgetArea"}, + {0x1, "LeftDockWidgetArea"}, + {0x2, "RightDockWidgetArea"}, + {0x4, "TopDockWidgetArea"}, + {0x8, "BottomDockWidgetArea"}, + {0xf, "AllDockWidgetAreas"} + }; + return lookupEnum(dockWidgetAreas, v); +} + +const char *paletteColorRole(int v) +{ + static const EnumLookup colorRoles[] = + { + {0, "WindowText"}, + {1, "Button"}, + {2, "Light"}, + {3, "Midlight"}, + {4, "Dark"}, + {5, "Mid"}, + {6, "Text"}, + {7, "BrightText"}, + {8, "ButtonText"}, + {9, "Base"}, + {10, "Window"}, + {11, "Shadow"}, + {12, "Highlight"}, + {13, "HighlightedText"}, + {14, "Link"}, + {15, "LinkVisited"}, + {16, "AlternateBase"}, + {17, "NoRole"}, + {18, "ToolTipBase"}, + {19, "ToolTipText"}, + {20, "PlaceholderText"}, + }; + return lookupEnum(colorRoles, v); +} + } // namespace language diff --git a/src/tools/uic/shared/language.h b/src/tools/uic/shared/language.h index 71cfddd6b0..e7201b6529 100644 --- a/src/tools/uic/shared/language.h +++ b/src/tools/uic/shared/language.h @@ -71,6 +71,11 @@ public: QTextStream &operator<<(QTextStream &, const closeQtConfig &c); +const char *toolbarArea(int v); +const char *sizePolicy(int v); +const char *dockWidgetArea(int v); +const char *paletteColorRole(int v); + } // namespace language #endif // LANGUAGE_H diff --git a/tests/auto/tools/uic/baseline/batchtranslation.ui.h b/tests/auto/tools/uic/baseline/batchtranslation.ui.h index 1ca39ce171..5e7278a581 100644 --- a/tests/auto/tools/uic/baseline/batchtranslation.ui.h +++ b/tests/auto/tools/uic/baseline/batchtranslation.ui.h @@ -90,7 +90,7 @@ public: vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); groupBox = new QGroupBox(databaseTranslationDialog); groupBox->setObjectName(QString::fromUtf8("groupBox")); - QSizePolicy sizePolicy(static_cast(5), static_cast(4)); + QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); sizePolicy.setHeightForWidth(groupBox->sizePolicy().hasHeightForWidth()); @@ -120,7 +120,7 @@ public: groupBox_2 = new QGroupBox(databaseTranslationDialog); groupBox_2->setObjectName(QString::fromUtf8("groupBox_2")); - QSizePolicy sizePolicy1(static_cast(5), static_cast(1)); + QSizePolicy sizePolicy1(QSizePolicy::Preferred, QSizePolicy::Minimum); sizePolicy1.setHorizontalStretch(0); sizePolicy1.setVerticalStretch(0); sizePolicy1.setHeightForWidth(groupBox_2->sizePolicy().hasHeightForWidth()); diff --git a/tests/auto/tools/uic/baseline/browserwidget.ui.h b/tests/auto/tools/uic/baseline/browserwidget.ui.h index 09c70ee3da..7dcfb290f7 100644 --- a/tests/auto/tools/uic/baseline/browserwidget.ui.h +++ b/tests/auto/tools/uic/baseline/browserwidget.ui.h @@ -62,7 +62,7 @@ public: vboxLayout->setObjectName(QString::fromUtf8("vboxLayout")); splitter_2 = new QSplitter(Browser); splitter_2->setObjectName(QString::fromUtf8("splitter_2")); - QSizePolicy sizePolicy(static_cast(7), static_cast(7)); + QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); sizePolicy.setHeightForWidth(splitter_2->sizePolicy().hasHeightForWidth()); @@ -70,7 +70,7 @@ public: splitter_2->setOrientation(Qt::Horizontal); connectionWidget = new ConnectionWidget(splitter_2); connectionWidget->setObjectName(QString::fromUtf8("connectionWidget")); - QSizePolicy sizePolicy1(static_cast(13), static_cast(7)); + QSizePolicy sizePolicy1(QSizePolicy::Ignored, QSizePolicy::Expanding); sizePolicy1.setHorizontalStretch(1); sizePolicy1.setVerticalStretch(0); sizePolicy1.setHeightForWidth(connectionWidget->sizePolicy().hasHeightForWidth()); @@ -78,7 +78,7 @@ public: splitter_2->addWidget(connectionWidget); table = new QTableView(splitter_2); table->setObjectName(QString::fromUtf8("table")); - QSizePolicy sizePolicy2(static_cast(7), static_cast(7)); + QSizePolicy sizePolicy2(QSizePolicy::Expanding, QSizePolicy::Expanding); sizePolicy2.setHorizontalStretch(2); sizePolicy2.setVerticalStretch(0); sizePolicy2.setHeightForWidth(table->sizePolicy().hasHeightForWidth()); @@ -91,7 +91,7 @@ public: groupBox = new QGroupBox(Browser); groupBox->setObjectName(QString::fromUtf8("groupBox")); - QSizePolicy sizePolicy3(static_cast(5), static_cast(3)); + QSizePolicy sizePolicy3(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding); sizePolicy3.setHorizontalStretch(0); sizePolicy3.setVerticalStretch(0); sizePolicy3.setHeightForWidth(groupBox->sizePolicy().hasHeightForWidth()); @@ -107,7 +107,7 @@ public: vboxLayout1->setObjectName(QString::fromUtf8("vboxLayout1")); sqlEdit = new QTextEdit(groupBox); sqlEdit->setObjectName(QString::fromUtf8("sqlEdit")); - QSizePolicy sizePolicy4(static_cast(7), static_cast(3)); + QSizePolicy sizePolicy4(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding); sizePolicy4.setHorizontalStretch(0); sizePolicy4.setVerticalStretch(0); sizePolicy4.setHeightForWidth(sqlEdit->sizePolicy().hasHeightForWidth()); diff --git a/tests/auto/tools/uic/baseline/calculatorform.ui.h b/tests/auto/tools/uic/baseline/calculatorform.ui.h index bb30479d1f..ab55c8ad97 100644 --- a/tests/auto/tools/uic/baseline/calculatorform.ui.h +++ b/tests/auto/tools/uic/baseline/calculatorform.ui.h @@ -45,7 +45,7 @@ public: if (CalculatorForm->objectName().isEmpty()) CalculatorForm->setObjectName(QString::fromUtf8("CalculatorForm")); CalculatorForm->resize(276, 98); - QSizePolicy sizePolicy(static_cast(5), static_cast(5)); + QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); sizePolicy.setHeightForWidth(CalculatorForm->sizePolicy().hasHeightForWidth()); diff --git a/tests/auto/tools/uic/baseline/chatmainwindow.ui.h b/tests/auto/tools/uic/baseline/chatmainwindow.ui.h index 27e468cfa6..220d44300b 100644 --- a/tests/auto/tools/uic/baseline/chatmainwindow.ui.h +++ b/tests/auto/tools/uic/baseline/chatmainwindow.ui.h @@ -99,7 +99,7 @@ public: sendButton = new QPushButton(centralwidget); sendButton->setObjectName(QString::fromUtf8("sendButton")); - QSizePolicy sizePolicy(static_cast(1), static_cast(0)); + QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); sizePolicy.setHeightForWidth(sendButton->sizePolicy().hasHeightForWidth()); diff --git a/tests/auto/tools/uic/baseline/chatsetnickname.ui.h b/tests/auto/tools/uic/baseline/chatsetnickname.ui.h index cc11acb6da..0e93828c90 100644 --- a/tests/auto/tools/uic/baseline/chatsetnickname.ui.h +++ b/tests/auto/tools/uic/baseline/chatsetnickname.ui.h @@ -39,7 +39,7 @@ public: if (NicknameDialog->objectName().isEmpty()) NicknameDialog->setObjectName(QString::fromUtf8("NicknameDialog")); NicknameDialog->resize(396, 105); - QSizePolicy sizePolicy(static_cast(1), static_cast(1)); + QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); sizePolicy.setHeightForWidth(NicknameDialog->sizePolicy().hasHeightForWidth()); diff --git a/tests/auto/tools/uic/baseline/imagedialog.ui.h b/tests/auto/tools/uic/baseline/imagedialog.ui.h index 993652222d..eea8b6ee03 100644 --- a/tests/auto/tools/uic/baseline/imagedialog.ui.h +++ b/tests/auto/tools/uic/baseline/imagedialog.ui.h @@ -86,7 +86,7 @@ public: colorDepthCombo = new QComboBox(dialog); colorDepthCombo->setObjectName(QString::fromUtf8("colorDepthCombo")); colorDepthCombo->setGeometry(QRect(74, 83, 227, 22)); - QSizePolicy sizePolicy(static_cast(5), static_cast(0)); + QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); sizePolicy.setHeightForWidth(colorDepthCombo->sizePolicy().hasHeightForWidth()); @@ -98,7 +98,7 @@ public: nameLineEdit = new QLineEdit(dialog); nameLineEdit->setObjectName(QString::fromUtf8("nameLineEdit")); nameLineEdit->setGeometry(QRect(74, 83, 227, 22)); - QSizePolicy sizePolicy1(static_cast(5), static_cast(0)); + QSizePolicy sizePolicy1(QSizePolicy::Preferred, QSizePolicy::Fixed); sizePolicy1.setHorizontalStretch(1); sizePolicy1.setVerticalStretch(0); sizePolicy1.setHeightForWidth(nameLineEdit->sizePolicy().hasHeightForWidth()); diff --git a/tests/auto/tools/uic/baseline/newform.ui.h b/tests/auto/tools/uic/baseline/newform.ui.h index 2f680f822f..e0b5baef81 100644 --- a/tests/auto/tools/uic/baseline/newform.ui.h +++ b/tests/auto/tools/uic/baseline/newform.ui.h @@ -93,7 +93,7 @@ public: lblPreview = new QLabel(NewForm); lblPreview->setObjectName(QString::fromUtf8("lblPreview")); - QSizePolicy sizePolicy(static_cast(7), static_cast(5)); + QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); sizePolicy.setHeightForWidth(lblPreview->sizePolicy().hasHeightForWidth()); diff --git a/tests/auto/tools/uic/baseline/paletteeditor.ui.h b/tests/auto/tools/uic/baseline/paletteeditor.ui.h index 0d0ef75cf9..eb1cad8c3a 100644 --- a/tests/auto/tools/uic/baseline/paletteeditor.ui.h +++ b/tests/auto/tools/uic/baseline/paletteeditor.ui.h @@ -81,7 +81,7 @@ public: if (qdesigner_internal__PaletteEditor->objectName().isEmpty()) qdesigner_internal__PaletteEditor->setObjectName(QString::fromUtf8("qdesigner_internal__PaletteEditor")); qdesigner_internal__PaletteEditor->resize(365, 409); - QSizePolicy sizePolicy(static_cast(7), static_cast(7)); + QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); sizePolicy.setHeightForWidth(qdesigner_internal__PaletteEditor->sizePolicy().hasHeightForWidth()); @@ -108,7 +108,7 @@ public: gridLayout->setObjectName(QString::fromUtf8("gridLayout")); buildButton = new QtColorButton(advancedBox); buildButton->setObjectName(QString::fromUtf8("buildButton")); - QSizePolicy sizePolicy1(static_cast(7), static_cast(13)); + QSizePolicy sizePolicy1(QSizePolicy::Expanding, QSizePolicy::Ignored); sizePolicy1.setHorizontalStretch(0); sizePolicy1.setVerticalStretch(0); sizePolicy1.setHeightForWidth(buildButton->sizePolicy().hasHeightForWidth()); @@ -143,7 +143,7 @@ public: GroupBox126 = new QGroupBox(qdesigner_internal__PaletteEditor); GroupBox126->setObjectName(QString::fromUtf8("GroupBox126")); - QSizePolicy sizePolicy2(static_cast(5), static_cast(7)); + QSizePolicy sizePolicy2(QSizePolicy::Preferred, QSizePolicy::Expanding); sizePolicy2.setHorizontalStretch(0); sizePolicy2.setVerticalStretch(0); sizePolicy2.setHeightForWidth(GroupBox126->sizePolicy().hasHeightForWidth()); diff --git a/tests/auto/tools/uic/baseline/previewdialogbase.ui.h b/tests/auto/tools/uic/baseline/previewdialogbase.ui.h index 25017bced0..5ff155de13 100644 --- a/tests/auto/tools/uic/baseline/previewdialogbase.ui.h +++ b/tests/auto/tools/uic/baseline/previewdialogbase.ui.h @@ -70,7 +70,7 @@ public: paperSizeCombo = new QComboBox(PreviewDialogBase); paperSizeCombo->setObjectName(QString::fromUtf8("paperSizeCombo")); - QSizePolicy sizePolicy(static_cast(1), static_cast(0)); + QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); sizePolicy.setHeightForWidth(paperSizeCombo->sizePolicy().hasHeightForWidth()); @@ -115,7 +115,7 @@ public: previewArea = new QScrollArea(PreviewDialogBase); previewArea->setObjectName(QString::fromUtf8("previewArea")); - QSizePolicy sizePolicy1(static_cast(5), static_cast(5)); + QSizePolicy sizePolicy1(QSizePolicy::Preferred, QSizePolicy::Preferred); sizePolicy1.setHorizontalStretch(1); sizePolicy1.setVerticalStretch(0); sizePolicy1.setHeightForWidth(previewArea->sizePolicy().hasHeightForWidth()); @@ -135,7 +135,7 @@ public: progressBar = new QProgressBar(PreviewDialogBase); progressBar->setObjectName(QString::fromUtf8("progressBar")); progressBar->setEnabled(false); - QSizePolicy sizePolicy2(static_cast(7), static_cast(0)); + QSizePolicy sizePolicy2(QSizePolicy::Expanding, QSizePolicy::Fixed); sizePolicy2.setHorizontalStretch(1); sizePolicy2.setVerticalStretch(0); sizePolicy2.setHeightForWidth(progressBar->sizePolicy().hasHeightForWidth()); diff --git a/tests/auto/tools/uic/baseline/previewwidget.ui.h b/tests/auto/tools/uic/baseline/previewwidget.ui.h index 2d883e984f..47563587fb 100644 --- a/tests/auto/tools/uic/baseline/previewwidget.ui.h +++ b/tests/auto/tools/uic/baseline/previewwidget.ui.h @@ -92,7 +92,7 @@ public: if (qdesigner_internal__PreviewWidget->objectName().isEmpty()) qdesigner_internal__PreviewWidget->setObjectName(QString::fromUtf8("qdesigner_internal__PreviewWidget")); qdesigner_internal__PreviewWidget->resize(471, 251); - QSizePolicy sizePolicy(static_cast(1), static_cast(1)); + QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); sizePolicy.setHeightForWidth(qdesigner_internal__PreviewWidget->sizePolicy().hasHeightForWidth()); diff --git a/tests/auto/tools/uic/baseline/stylesheeteditor.ui.h b/tests/auto/tools/uic/baseline/stylesheeteditor.ui.h index 2e73926c0c..ecca62c867 100644 --- a/tests/auto/tools/uic/baseline/stylesheeteditor.ui.h +++ b/tests/auto/tools/uic/baseline/stylesheeteditor.ui.h @@ -73,7 +73,7 @@ public: styleCombo = new QComboBox(StyleSheetEditor); styleCombo->setObjectName(QString::fromUtf8("styleCombo")); - QSizePolicy sizePolicy(static_cast(5), static_cast(0)); + QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); sizePolicy.setHeightForWidth(styleCombo->sizePolicy().hasHeightForWidth()); @@ -83,7 +83,7 @@ public: label_7 = new QLabel(StyleSheetEditor); label_7->setObjectName(QString::fromUtf8("label_7")); - QSizePolicy sizePolicy1(static_cast(0), static_cast(5)); + QSizePolicy sizePolicy1(QSizePolicy::Fixed, QSizePolicy::Preferred); sizePolicy1.setHorizontalStretch(0); sizePolicy1.setVerticalStretch(0); sizePolicy1.setHeightForWidth(label_7->sizePolicy().hasHeightForWidth()); diff --git a/tests/auto/tools/uic/baseline/tabbedbrowser.ui.h b/tests/auto/tools/uic/baseline/tabbedbrowser.ui.h index 18a62df44a..4be294af37 100644 --- a/tests/auto/tools/uic/baseline/tabbedbrowser.ui.h +++ b/tests/auto/tools/uic/baseline/tabbedbrowser.ui.h @@ -117,7 +117,7 @@ public: editFind = new QLineEdit(frameFind); editFind->setObjectName(QString::fromUtf8("editFind")); - QSizePolicy sizePolicy(static_cast(0), static_cast(0)); + QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); sizePolicy.setHorizontalStretch(0); sizePolicy.setVerticalStretch(0); sizePolicy.setHeightForWidth(editFind->sizePolicy().hasHeightForWidth()); diff --git a/tests/auto/tools/uic/baseline/trpreviewtool.ui.h b/tests/auto/tools/uic/baseline/trpreviewtool.ui.h index 95ebed0f6f..612d7ad427 100644 --- a/tests/auto/tools/uic/baseline/trpreviewtool.ui.h +++ b/tests/auto/tools/uic/baseline/trpreviewtool.ui.h @@ -117,7 +117,7 @@ public: mainToolBar = new QToolBar(TrPreviewToolClass); mainToolBar->setObjectName(QString::fromUtf8("mainToolBar")); mainToolBar->setOrientation(Qt::Horizontal); - TrPreviewToolClass->addToolBar(static_cast(4), mainToolBar); + TrPreviewToolClass->addToolBar(Qt::TopToolBarArea, mainToolBar); statusBar = new QStatusBar(TrPreviewToolClass); statusBar->setObjectName(QString::fromUtf8("statusBar")); TrPreviewToolClass->setStatusBar(statusBar); @@ -138,7 +138,7 @@ public: vboxLayout->addWidget(viewForms); dwForms->setWidget(dockWidgetContents); - TrPreviewToolClass->addDockWidget(static_cast(1), dwForms); + TrPreviewToolClass->addDockWidget(Qt::LeftDockWidgetArea, dwForms); menuBar->addAction(menuFile->menuAction()); menuBar->addAction(menuView->menuAction()); From a0f3b2b50322a2aa40d4c688279cbef65791adcb Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 26 Nov 2018 11:03:36 +0100 Subject: [PATCH 0629/1650] QtGui: Use Q_DISABLE_COPY_MOVE for QPA interface classes Introduce Q_DISABLE_COPY_MOVE or replace existing Q_DISABLE_COPY and add default constructors where needed. Change-Id: Ibd14ee9d1d69e64f6289efe789d4b64a3d6cb998 Reviewed-by: Ulf Hermann --- src/gui/kernel/qplatformclipboard.h | 3 +++ src/gui/kernel/qplatformcursor.h | 2 ++ src/gui/kernel/qplatformdrag.h | 4 ++-- src/gui/kernel/qplatformintegration.h | 4 ++++ src/gui/kernel/qplatformscreen.h | 4 ++-- src/gui/kernel/qplatformservices.h | 2 ++ src/gui/kernel/qplatformsessionmanager.h | 4 ++-- src/gui/kernel/qplatformsurface.h | 2 ++ src/gui/kernel/qplatformtheme.h | 4 ++-- src/gui/kernel/qplatformwindow.h | 4 ++-- 10 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/gui/kernel/qplatformclipboard.h b/src/gui/kernel/qplatformclipboard.h index 60733b0a9f..3220201720 100644 --- a/src/gui/kernel/qplatformclipboard.h +++ b/src/gui/kernel/qplatformclipboard.h @@ -61,6 +61,9 @@ QT_BEGIN_NAMESPACE class Q_GUI_EXPORT QPlatformClipboard { public: + Q_DISABLE_COPY_MOVE(QPlatformClipboard) + + QPlatformClipboard() = default; virtual ~QPlatformClipboard(); virtual QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard); diff --git a/src/gui/kernel/qplatformcursor.h b/src/gui/kernel/qplatformcursor.h index 40e8a562f8..f36a73c861 100644 --- a/src/gui/kernel/qplatformcursor.h +++ b/src/gui/kernel/qplatformcursor.h @@ -78,6 +78,8 @@ private: class Q_GUI_EXPORT QPlatformCursor : public QObject { public: + Q_DISABLE_COPY_MOVE(QPlatformCursor) + enum Capability { OverrideCursor = 0x1 }; diff --git a/src/gui/kernel/qplatformdrag.h b/src/gui/kernel/qplatformdrag.h index 9d4e352b4b..0c99539357 100644 --- a/src/gui/kernel/qplatformdrag.h +++ b/src/gui/kernel/qplatformdrag.h @@ -91,6 +91,8 @@ class Q_GUI_EXPORT QPlatformDrag { Q_DECLARE_PRIVATE(QPlatformDrag) public: + Q_DISABLE_COPY_MOVE(QPlatformDrag) + QPlatformDrag(); virtual ~QPlatformDrag(); @@ -108,8 +110,6 @@ public: private: QPlatformDragPrivate *d_ptr; - - Q_DISABLE_COPY(QPlatformDrag) }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatformintegration.h b/src/gui/kernel/qplatformintegration.h index efb1481f6d..de5f9c1c9a 100644 --- a/src/gui/kernel/qplatformintegration.h +++ b/src/gui/kernel/qplatformintegration.h @@ -84,6 +84,8 @@ class QVulkanInstance; class Q_GUI_EXPORT QPlatformIntegration { public: + Q_DISABLE_COPY_MOVE(QPlatformIntegration) + enum Capability { ThreadedPixmaps = 1, OpenGL, @@ -199,6 +201,8 @@ public: #endif protected: + QPlatformIntegration() = default; + void screenAdded(QPlatformScreen *screen, bool isPrimary = false); void destroyScreen(QPlatformScreen *screen); void setPrimaryScreen(QPlatformScreen *newPrimary); diff --git a/src/gui/kernel/qplatformscreen.h b/src/gui/kernel/qplatformscreen.h index e9d64c8a29..b9ecc80320 100644 --- a/src/gui/kernel/qplatformscreen.h +++ b/src/gui/kernel/qplatformscreen.h @@ -80,6 +80,8 @@ class Q_GUI_EXPORT QPlatformScreen Q_DECLARE_PRIVATE(QPlatformScreen) public: + Q_DISABLE_COPY_MOVE(QPlatformScreen) + enum SubpixelAntialiasingType { // copied from qfontengine_p.h since we can't include private headers Subpixel_None, Subpixel_RGB, @@ -164,8 +166,6 @@ protected: QScopedPointer d_ptr; private: - Q_DISABLE_COPY(QPlatformScreen) - friend class QScreenPrivate; }; diff --git a/src/gui/kernel/qplatformservices.h b/src/gui/kernel/qplatformservices.h index 339bbfde3f..5de96cfa7d 100644 --- a/src/gui/kernel/qplatformservices.h +++ b/src/gui/kernel/qplatformservices.h @@ -58,6 +58,8 @@ class QUrl; class Q_GUI_EXPORT QPlatformServices { public: + Q_DISABLE_COPY_MOVE(QPlatformServices) + QPlatformServices(); virtual ~QPlatformServices() { } diff --git a/src/gui/kernel/qplatformsessionmanager.h b/src/gui/kernel/qplatformsessionmanager.h index ca7cab389b..c6c3984816 100644 --- a/src/gui/kernel/qplatformsessionmanager.h +++ b/src/gui/kernel/qplatformsessionmanager.h @@ -64,6 +64,8 @@ QT_BEGIN_NAMESPACE class Q_GUI_EXPORT QPlatformSessionManager { public: + Q_DISABLE_COPY_MOVE(QPlatformSessionManager) + explicit QPlatformSessionManager(const QString &id, const QString &key); virtual ~QPlatformSessionManager(); @@ -101,8 +103,6 @@ private: QStringList m_restartCommand; QStringList m_discardCommand; QSessionManager::RestartHint m_restartHint; - - Q_DISABLE_COPY(QPlatformSessionManager) }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatformsurface.h b/src/gui/kernel/qplatformsurface.h index 4d8854fb40..475f3ef330 100644 --- a/src/gui/kernel/qplatformsurface.h +++ b/src/gui/kernel/qplatformsurface.h @@ -65,6 +65,8 @@ class QDebug; class Q_GUI_EXPORT QPlatformSurface { public: + Q_DISABLE_COPY_MOVE(QPlatformSurface) + virtual ~QPlatformSurface(); virtual QSurfaceFormat format() const = 0; diff --git a/src/gui/kernel/qplatformtheme.h b/src/gui/kernel/qplatformtheme.h index 1d6049a98d..54c8c70025 100644 --- a/src/gui/kernel/qplatformtheme.h +++ b/src/gui/kernel/qplatformtheme.h @@ -76,6 +76,8 @@ class Q_GUI_EXPORT QPlatformTheme { Q_DECLARE_PRIVATE(QPlatformTheme) public: + Q_DISABLE_COPY_MOVE(QPlatformTheme) + enum ThemeHint { CursorFlashTime, KeyboardInputInterval, @@ -324,8 +326,6 @@ public: protected: explicit QPlatformTheme(QPlatformThemePrivate *priv); QScopedPointer d_ptr; -private: - Q_DISABLE_COPY(QPlatformTheme) }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h index 1590a10554..995ccad70e 100644 --- a/src/gui/kernel/qplatformwindow.h +++ b/src/gui/kernel/qplatformwindow.h @@ -71,6 +71,8 @@ class Q_GUI_EXPORT QPlatformWindow : public QPlatformSurface { Q_DECLARE_PRIVATE(QPlatformWindow) public: + Q_DISABLE_COPY_MOVE(QPlatformWindow) + explicit QPlatformWindow(QWindow *window); ~QPlatformWindow() override; @@ -164,8 +166,6 @@ protected: static QSize constrainWindowSize(const QSize &size); QScopedPointer d_ptr; -private: - Q_DISABLE_COPY(QPlatformWindow) }; QT_END_NAMESPACE From 4aac7b92c4a6cbcb0a12e6a209b210777fe610eb Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 12 Dec 2018 12:59:09 +0100 Subject: [PATCH 0630/1650] QFusionStyle: Fix deprecation warning about QFontMetrics::width() Fix an oversight of 4d88d79aa507777bce40740b21747f656efc074d. Change-Id: I03e403c6d6aefc4f3118ea8efd822fc563b7a514 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/widgets/styles/qfusionstyle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp index c565932889..85c7a35a72 100644 --- a/src/widgets/styles/qfusionstyle.cpp +++ b/src/widgets/styles/qfusionstyle.cpp @@ -3225,7 +3225,7 @@ QSize QFusionStyle::sizeFromContents(ContentsType type, const QStyleOption *opti QFont fontBold = menuItem->font; fontBold.setBold(true); QFontMetrics fmBold(fontBold); - w += fmBold.width(menuItem->text) - fm.horizontalAdvance(menuItem->text); + w += fmBold.horizontalAdvance(menuItem->text) - fm.horizontalAdvance(menuItem->text); } const int checkcol = qMax(maxpmw, QStyleHelper::dpiScaled(QFusionStylePrivate::menuCheckMarkWidth)); // Windows always shows a check column w += checkcol; From e6d1071dd32d653f40c54df4141f7bd41aea7ea0 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 29 Nov 2018 14:41:20 +0100 Subject: [PATCH 0631/1650] uic: Refactor DOM class lookup in class Driver Change the API to take const Dom * classes and use a helper function to do the insertion. Task-number: PYSIDE-797 Change-Id: I079f5c92bae85d6246c14077db06e381b572cda5 Reviewed-by: Jarek Kobus --- src/tools/uic/cpp/cppwriteinitialization.cpp | 4 +- src/tools/uic/driver.cpp | 77 +++++++++----------- src/tools/uic/driver.h | 36 +++++---- 3 files changed, 55 insertions(+), 62 deletions(-) diff --git a/src/tools/uic/cpp/cppwriteinitialization.cpp b/src/tools/uic/cpp/cppwriteinitialization.cpp index ca9b48ed9c..6313d6b2d3 100644 --- a/src/tools/uic/cpp/cppwriteinitialization.cpp +++ b/src/tools/uic/cpp/cppwriteinitialization.cpp @@ -2404,9 +2404,9 @@ QString WriteInitialization::findDeclaration(const QString &name) { const QString normalized = Driver::normalizedName(name); - if (DomWidget *widget = m_driver->widgetByName(normalized)) + if (const DomWidget *widget = m_driver->widgetByName(normalized)) return m_driver->findOrInsertWidget(widget); - if (DomAction *action = m_driver->actionByName(normalized)) + if (const DomAction *action = m_driver->actionByName(normalized)) return m_driver->findOrInsertAction(action); if (const DomButtonGroup *group = m_driver->findButtonGroup(normalized)) return m_driver->findOrInsertButtonGroup(group); diff --git a/src/tools/uic/driver.cpp b/src/tools/uic/driver.cpp index cf7e67305b..03fa1e17cf 100644 --- a/src/tools/uic/driver.cpp +++ b/src/tools/uic/driver.cpp @@ -45,39 +45,37 @@ Driver::Driver() Driver::~Driver() = default; -QString Driver::findOrInsertWidget(DomWidget *ui_widget) -{ - if (!m_widgets.contains(ui_widget)) - m_widgets.insert(ui_widget, unique(ui_widget->attributeName(), ui_widget->attributeClass())); +static inline QString spacerItemClass() { return QStringLiteral("QSpacerItem"); } +static inline QString actionGroupClass() { return QStringLiteral("QActionGroup"); } +static inline QString actionClass() { return QStringLiteral("QAction"); } +static inline QString buttonGroupClass() { return QStringLiteral("QButtonGroup"); } - return m_widgets.value(ui_widget); +template +QString Driver::findOrInsert(DomObjectHash *domHash, const DomClass *dom, + const QString &className) +{ + auto it = domHash->find(dom); + if (it == domHash->end()) + it = domHash->insert(dom, this->unique(dom->attributeName(), className)); + return it.value(); } -QString Driver::findOrInsertSpacer(DomSpacer *ui_spacer) +QString Driver::findOrInsertWidget(const DomWidget *ui_widget) { - if (!m_spacers.contains(ui_spacer)) { - QString name; - if (ui_spacer->hasAttributeName()) - name = ui_spacer->attributeName(); - m_spacers.insert(ui_spacer, unique(name, QLatin1String("QSpacerItem"))); - } - - return m_spacers.value(ui_spacer); + return findOrInsert(&m_widgets, ui_widget, ui_widget->attributeClass()); } -QString Driver::findOrInsertLayout(DomLayout *ui_layout) +QString Driver::findOrInsertSpacer(const DomSpacer *ui_spacer) { - if (!m_layouts.contains(ui_layout)) { - QString name; - if (ui_layout->hasAttributeName()) - name = ui_layout->attributeName(); - m_layouts.insert(ui_layout, unique(name, ui_layout->attributeClass())); - } - - return m_layouts.value(ui_layout); + return findOrInsert(&m_spacers, ui_spacer, spacerItemClass()); } -QString Driver::findOrInsertLayoutItem(DomLayoutItem *ui_layoutItem) +QString Driver::findOrInsertLayout(const DomLayout *ui_layout) +{ + return findOrInsert(&m_layouts, ui_layout, ui_layout->attributeClass()); +} + +QString Driver::findOrInsertLayoutItem(const DomLayoutItem *ui_layoutItem) { switch (ui_layoutItem->kind()) { case DomLayoutItem::Widget: @@ -95,38 +93,29 @@ QString Driver::findOrInsertLayoutItem(DomLayoutItem *ui_layoutItem) return QString(); } -QString Driver::findOrInsertActionGroup(DomActionGroup *ui_group) +QString Driver::findOrInsertActionGroup(const DomActionGroup *ui_group) { - if (!m_actionGroups.contains(ui_group)) - m_actionGroups.insert(ui_group, unique(ui_group->attributeName(), QLatin1String("QActionGroup"))); - - return m_actionGroups.value(ui_group); + return findOrInsert(&m_actionGroups, ui_group, actionGroupClass()); } -QString Driver::findOrInsertAction(DomAction *ui_action) +QString Driver::findOrInsertAction(const DomAction *ui_action) { - if (!m_actions.contains(ui_action)) - m_actions.insert(ui_action, unique(ui_action->attributeName(), QLatin1String("QAction"))); - - return m_actions.value(ui_action); + return findOrInsert(&m_actions, ui_action, actionClass()); } QString Driver::findOrInsertButtonGroup(const DomButtonGroup *ui_group) { - ButtonGroupNameHash::iterator it = m_buttonGroups.find(ui_group); - if (it == m_buttonGroups.end()) - it = m_buttonGroups.insert(ui_group, unique(ui_group->attributeName(), QLatin1String("QButtonGroup"))); - return it.value(); + return findOrInsert(&m_buttonGroups, ui_group, buttonGroupClass()); } // Find a group by its non-uniqified name const DomButtonGroup *Driver::findButtonGroup(const QString &attributeName) const { - const ButtonGroupNameHash::const_iterator cend = m_buttonGroups.constEnd(); - for (ButtonGroupNameHash::const_iterator it = m_buttonGroups.constBegin(); it != cend; ++it) + for (auto it = m_buttonGroups.cbegin(), end = m_buttonGroups.cend(); it != end; ++it) { if (it.key()->attributeName() == attributeName) return it.key(); - return 0; + } + return nullptr; } @@ -297,17 +286,17 @@ bool Driver::uic(const QString &fileName, QTextStream *out) return rtn; } -DomWidget *Driver::widgetByName(const QString &name) const +const DomWidget *Driver::widgetByName(const QString &name) const { return m_widgets.key(name); } -DomActionGroup *Driver::actionGroupByName(const QString &name) const +const DomActionGroup *Driver::actionGroupByName(const QString &name) const { return m_actionGroups.key(name); } -DomAction *Driver::actionByName(const QString &name) const +const DomAction *Driver::actionByName(const QString &name) const { return m_actions.key(name); } diff --git a/src/tools/uic/driver.h b/src/tools/uic/driver.h index 3808855783..1303d0bf8a 100644 --- a/src/tools/uic/driver.h +++ b/src/tools/uic/driver.h @@ -73,37 +73,41 @@ public: const QString &className=QString()); // symbol table - QString findOrInsertWidget(DomWidget *ui_widget); - QString findOrInsertSpacer(DomSpacer *ui_spacer); - QString findOrInsertLayout(DomLayout *ui_layout); - QString findOrInsertLayoutItem(DomLayoutItem *ui_layoutItem); + QString findOrInsertWidget(const DomWidget *ui_widget); + QString findOrInsertSpacer(const DomSpacer *ui_spacer); + QString findOrInsertLayout(const DomLayout *ui_layout); + QString findOrInsertLayoutItem(const DomLayoutItem *ui_layoutItem); QString findOrInsertName(const QString &name); - QString findOrInsertActionGroup(DomActionGroup *ui_group); - QString findOrInsertAction(DomAction *ui_action); + QString findOrInsertActionGroup(const DomActionGroup *ui_group); + QString findOrInsertAction(const DomAction *ui_action); QString findOrInsertButtonGroup(const DomButtonGroup *ui_group); // Find a group by its non-uniqified name const DomButtonGroup *findButtonGroup(const QString &attributeName) const; - DomWidget *widgetByName(const QString &name) const; - DomActionGroup *actionGroupByName(const QString &name) const; - DomAction *actionByName(const QString &name) const; + const DomWidget *widgetByName(const QString &name) const; + const DomActionGroup *actionGroupByName(const QString &name) const; + const DomAction *actionByName(const QString &name) const; bool useIdBasedTranslations() const { return m_idBasedTranslations; } void setUseIdBasedTranslations(bool u) { m_idBasedTranslations = u; } private: + template using DomObjectHash = QHash; + + template + QString findOrInsert(DomObjectHash *domHash, const DomClass *dom, const QString &className); + Option m_option; QTextStream m_stdout; QTextStream *m_output; // symbol tables - QHash m_widgets; - QHash m_spacers; - QHash m_layouts; - QHash m_actionGroups; - typedef QHash ButtonGroupNameHash; - ButtonGroupNameHash m_buttonGroups; - QHash m_actions; + DomObjectHash m_widgets; + DomObjectHash m_spacers; + DomObjectHash m_layouts; + DomObjectHash m_actionGroups; + DomObjectHash m_buttonGroups; + DomObjectHash m_actions; QHash m_nameRepository; bool m_idBasedTranslations = false; }; From 35602d75d37af5ffee41d78f8876506ce2c188bf Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Fri, 30 Nov 2018 15:41:43 +0100 Subject: [PATCH 0632/1650] Refactor tst_QAbstractSlider::keyPressed() Don't do several tests at once in the test function. Instead, move the extra tests to the data function. This makes it possible to easily add a self-contained test (i.e row) for an upcoming fix. Task-number: QTBUG-25988 Change-Id: I65c8d7620f01107f8f59c96896b1a641d97f5fdc Reviewed-by: Richard Moe Gustavsen --- .../qabstractslider/tst_qabstractslider.cpp | 639 +++++++++++++----- 1 file changed, 479 insertions(+), 160 deletions(-) diff --git a/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp b/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp index 70ae453896..089469f8dc 100644 --- a/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp +++ b/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp @@ -467,160 +467,517 @@ void tst_QAbstractSlider::keyPressed_data() QTest::addColumn("maximum"); QTest::addColumn("stepSize"); QTest::addColumn("pageSize"); + QTest::addColumn("invertedAppearance"); + QTest::addColumn("invertedControls"); QTest::addColumn >("keySequence"); - QTest::addColumn("expectedSliderPositionHorizontal"); - QTest::addColumn("expectedSliderPositionVertical"); - QTest::addColumn("expectedSliderPositionHorizontalInverted"); // :) - QTest::addColumn("expectedSliderPositionVerticalInverted"); - + QTest::addColumn("expectedSliderPosition"); QList list; - list << Qt::Key_Down; - QTest::newRow("Step down once 1") << 10 // initial position - << 0 // minimum - << 100 // maximum - << 3 // single step size - << 0 // page step size - << list // key sequence - << 7 // result in case of horizontal slider - << 7 // result in case of vertical slider - << 13 // result in case of inverted horiz. slider - << 13; // result in case of inverted vertical slider + QTest::newRow("Step down once 1, horizontal") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << false// inverted appearance + << false// inverted controls + << list // key sequence + << 7; // expected position + + QTest::newRow("Step down once 1, horizontal, both inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << true // inverted appearance + << true // inverted controls + << list // key sequence + << 13; // expected position + + QTest::newRow("Step down once 1, vertical") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << false// inverted appearance + << false// inverted controls + << list // key sequence + << 7; // expected position + + QTest::newRow("Step down once 1, vertical, both inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << true // inverted appearance + << true // inverted controls + << list // key sequence + << 13; // expected position list = QList(); list << Qt::Key_Up; - QTest::newRow("Step down once 2") << 10 // initial position - << 0 // minimum - << 100 // maximum - << 3 // single step size - << 0 // page step size - << list // key sequence - << 13 // result in case of horizontal slider - << 13 // result in case of vertical slider - << 7 // result in case of inverted horiz. slider - << 7; // result in case of inverted vertical slider + QTest::newRow("Step up once 2, horizontal") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << false// inverted appearance + << false// inverted controls + << list // key sequence + << 13; // expected position + QTest::newRow("Step up once 2, horizontal, both inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << true // inverted appearance + << true // inverted controls + << list // key sequence + << 7; // expected position + + QTest::newRow("Step up once 2, vertical") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << false// inverted appearance + << false// inverted controls + << list // key sequence + << 13; // expected position + + QTest::newRow("Step up once 2, vertical, both inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << true // inverted appearance + << true // inverted controls + << list // key sequence + << 7; // expected position list = QList(); list << Qt::Key_Left; - QTest::newRow("Step left once") << 10 // initial position - << 0 // minimum - << 100 // maximum - << 3 // single step size - << 0 // page step size - << list // key sequence - << 7 // result in case of horizontal slider - << 7 // result in case of vertical slider - << 13 // result in case of inverted horiz. slider - << 13; // result in case of inverted vertical slider + QTest::newRow("Step left once 2, horizontal") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << false// inverted appearance + << false// inverted controls + << list // key sequence + << 7; // expected position + + QTest::newRow("Step left once 2, horizontal, both inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << true // inverted appearance + << true // inverted controls + << list // key sequence + << 13; // expected position + + QTest::newRow("Step left once 2, vertical") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << false// inverted appearance + << false// inverted controls + << list // key sequence + << 7; // expected position + + QTest::newRow("Step left once 2, vertical, both inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << true // inverted appearance + << true // inverted controls + << list // key sequence + << 13; // expected position list = QList(); list << Qt::Key_Right; - QTest::newRow("Step right once") << 10 // initial position - << 0 // minimum - << 100 // maximum - << 3 // single step size - << 0 // page step size - << list // key sequence - << 13 // result in case of horizontal slider - << 13 // result in case of vertical slider - << 7 // result in case of inverted horiz. slider - << 7; // result in case of inverted vertical slider + QTest::newRow("Step right once 2, horizontal") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << false// inverted appearance + << false// inverted controls + << list // key sequence + << 13; // expected position + + QTest::newRow("Step right once 2, horizontal, both inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << true // inverted appearance + << true // inverted controls + << list // key sequence + << 7; // expected position + + QTest::newRow("Step right once 2, vertical") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << false// inverted appearance + << false// inverted controls + << list // key sequence + << 13; // expected position + + QTest::newRow("Step right once 2, vertical, both inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << true // inverted appearance + << true // inverted controls + << list // key sequence + << 7; // expected position list = QList(); list << Qt::Key_PageDown; - QTest::newRow("Page down once") << 10 // initial position - << 0 // minimum - << 100 // maximum - << 0 // single step size - << 3 // page step size - << list // key sequence - << 7 // result in case of horizontal slider - << 7 // result in case of vertical slider - << 13 // result in case of inverted horiz. slider - << 13; // result in case of inverted vertical slider + QTest::newRow("Page down once, horizontal") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << false// inverted appearance + << false// inverted controls + << list // key sequence + << 7; // expected position + + QTest::newRow("Page down once, horizontal, both inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << true // inverted appearance + << true // inverted controls + << list // key sequence + << 13; // expected position + + QTest::newRow("Page down once, vertical") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << false// inverted appearance + << false// inverted controls + << list // key sequence + << 7; // expected position + + QTest::newRow("Page down once, vertical, both inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << true // inverted appearance + << true // inverted controls + << list // key sequence + << 13; // expected position list = QList(); list << Qt::Key_PageUp; - QTest::newRow("Page up once") << 10 // initial position - << 0 // minimum - << 100 // maximum - << 0 // single step size - << 3 // page step size - << list // key sequence - << 13 // result in case of horizontal slider - << 13 // result in case of vertical slider - << 7 // result in case of inverted horiz. slider - << 7; // result in case of inverted vertical slider + QTest::newRow("Page up once, horizontal") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << false// inverted appearance + << false// inverted controls + << list // key sequence + << 13; // expected position + + QTest::newRow("Page up once, horizontal, both inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << true // inverted appearance + << true // inverted controls + << list // key sequence + << 7; // expected position + + QTest::newRow("Page up once, vertical") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << false// inverted appearance + << false// inverted controls + << list // key sequence + << 13; // expected position + + QTest::newRow("Page up once, vertical, both inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << true // inverted appearance + << true // inverted controls + << list // key sequence + << 7; // expected position list = QList(); list << Qt::Key_Up << Qt::Key_Up << Qt::Key_PageDown << Qt::Key_PageDown << Qt::Key_Left << Qt::Key_Left << Qt::Key_Right << Qt::Key_Down << Qt::Key_PageUp << Qt::Key_PageUp << Qt::Key_Down << Qt::Key_Right; - QTest::newRow("Symmetric seq") << 50 // initial position - << 0 // minimum - << 100 // maximum - << 3 // single step size - << 3 // page step size - << list // key sequence - << 50 // result in case of horizontal slider - << 50 // result in case of vertical slider - << 50 // result in case of inverted horiz. slider - << 50; // result in case of inverted vertical slider + QTest::newRow("Symmetric seq, horizontal") + << 50 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 3 // page step size + << false// inverted appearance + << false// inverted controls + << list // key sequence + << 50; // expected position + QTest::newRow("Symmetric seq, horizontal, both inverted") + << 50 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 3 // page step size + << true // inverted appearance + << true // inverted controls + << list // key sequence + << 50; // expected position + + QTest::newRow("Symmetric seq, vertical") + << 50 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 3 // page step size + << false// inverted appearance + << false// inverted controls + << list // key sequence + << 50; // expected position + + QTest::newRow("Symmetric seq, vertical, both inverted") + << 50 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 3 // page step size + << true // inverted appearance + << true // inverted controls + << list // key sequence + << 50; // expected position list = QList(); list << Qt::Key_Home; - QTest::newRow("Home") << 10 // initial position - << 0 // minimum - << 100 // maximum - << 0 // single step size - << 3 // page step size - << list // key sequence - << 0 // result in case of horizontal slider - << 0 // result in case of vertical slider - << 0 // result in case of inverted horiz. slider - << 0; // result in case of inverted vertical slider + QTest::newRow("Home, horizontal") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << false// inverted appearance + << false// inverted controls + << list // key sequence + << 0; // expected position + + QTest::newRow("Home, horizontal, both inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << true // inverted appearance + << true // inverted controls + << list // key sequence + << 0; // expected position + + QTest::newRow("Home, vertical") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << false// inverted appearance + << false// inverted controls + << list // key sequence + << 0; // expected position + + QTest::newRow("Home, vertical, both inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << true // inverted appearance + << true // inverted controls + << list // key sequence + << 0; // expected position list = QList(); list << Qt::Key_End; - QTest::newRow("End") << 10 // initial position - << 0 // minimum - << 100 // maximum - << 0 // single step size - << 3 // page step size - << list // key sequence - << 100 // result in case of horizontal slider - << 100 // result in case of vertical slider - << 100 // result in case of inverted horiz. slider - << 100; // result in case of inverted vertical slider + QTest::newRow("End, horizontal") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << false// inverted appearance + << false// inverted controls + << list // key sequence + << 100; // expected position + + QTest::newRow("End, horizontal, both inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << true // inverted appearance + << true // inverted controls + << list // key sequence + << 100; // expected position + + QTest::newRow("End, vertical") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << false// inverted appearance + << false// inverted controls + << list // key sequence + << 100; // expected position + + QTest::newRow("End, vertical, both inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << true // inverted appearance + << true // inverted controls + << list // key sequence + << 100; // expected position list = QList(); list << Qt::Key_End << Qt::Key_Up; - QTest::newRow("Past end")<< 10 // initial position - << 0 // minimum - << 100 // maximum - << 3 // single step size - << 3 // page step size - << list // key sequence - << 100 // result in case of horizontal slider - << 100 // result in case of vertical slider - << 97 // result in case of inverted horiz. slider - << 97; // result in case of inverted vertical slider + QTest::newRow("Past end, horizontal") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 3 // page step size + << false// inverted appearance + << false// inverted controls + << list // key sequence + << 100; // expected position + + QTest::newRow("Past end, horizontal, both inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 3 // page step size + << true // inverted appearance + << true // inverted controls + << list // key sequence + << 97; // expected position + + QTest::newRow("Past end, vertical") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 3 // page step size + << false// inverted appearance + << false// inverted controls + << list // key sequence + << 100; // expected position + + QTest::newRow("Past end, vertical, both inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 3 // page step size + << true // inverted appearance + << true // inverted controls + << list // key sequence + << 97; // expected position list = QList(); list << Qt::Key_Home << Qt::Key_Down; - QTest::newRow("Past home")<< 10 // initial position - << 0 // minimum - << 100 // maximum - << 3 // single step size - << 3 // page step size - << list // key sequence - << 0 // result in case of horizontal slider - << 0 // result in case of vertical slider - << 3 // result in case of inverted horiz. slider - << 3; // result in case of inverted vertical slider + QTest::newRow("Past home, horizontal") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 3 // page step size + << false// inverted appearance + << false// inverted controls + << list // key sequence + << 0; // expected position + QTest::newRow("Past home, horizontal, both inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 3 // page step size + << true // inverted appearance + << true // inverted controls + << list // key sequence + << 3; // expected position + + QTest::newRow("Past home, vertical") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 3 // page step size + << false// inverted appearance + << false// inverted controls + << list // key sequence + << 0; // expected position + + QTest::newRow("Past home, vertical, both inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 3 // page step size + << true // inverted appearance + << true // inverted controls + << list // key sequence + << 3; // expected position } void tst_QAbstractSlider::keyPressed() @@ -630,60 +987,22 @@ void tst_QAbstractSlider::keyPressed() QFETCH(int, maximum); QFETCH(int, stepSize); QFETCH(int, pageSize); + QFETCH(bool, invertedAppearance); + QFETCH(bool, invertedControls); QFETCH(QList, keySequence); - QFETCH(int, expectedSliderPositionHorizontal); - QFETCH(int, expectedSliderPositionVertical); - QFETCH(int, expectedSliderPositionHorizontalInverted); - QFETCH(int, expectedSliderPositionVerticalInverted); + QFETCH(int, expectedSliderPosition); - // Horizontal non-inverted slider->setRange(minimum,maximum); slider->setSliderPosition(initialSliderPosition); slider->setSingleStep(stepSize); slider->setPageStep(pageSize); slider->setOrientation(Qt::Horizontal); - slider->setInvertedAppearance(false); - slider->setInvertedControls(false); + slider->setInvertedAppearance(invertedAppearance); + slider->setInvertedControls(invertedControls); for (int i=0;isliderPosition(), expectedSliderPositionHorizontal); - - // Horizontal inverted - slider->setRange(minimum,maximum); - slider->setSliderPosition(initialSliderPosition); - slider->setSingleStep(stepSize); - slider->setPageStep(pageSize); - slider->setOrientation(Qt::Horizontal); - slider->setInvertedAppearance(true); - slider->setInvertedControls(true); - for (int i=0;isliderPosition(), expectedSliderPositionHorizontalInverted); - - // Vertical non-inverted - slider->setRange(minimum,maximum); - slider->setSliderPosition(initialSliderPosition); - slider->setSingleStep(stepSize); - slider->setPageStep(pageSize); - slider->setOrientation(Qt::Vertical); - slider->setInvertedAppearance(false); - slider->setInvertedControls(false); - for (int i=0;isliderPosition(), expectedSliderPositionVertical); - - // Vertical inverted - slider->setRange(minimum,maximum); - slider->setSliderPosition(initialSliderPosition); - slider->setSingleStep(stepSize); - slider->setPageStep(pageSize); - slider->setOrientation(Qt::Vertical); - slider->setInvertedAppearance(true); - slider->setInvertedControls(true); - for (int i=0;isliderPosition(), expectedSliderPositionVerticalInverted); + QCOMPARE(slider->sliderPosition(), expectedSliderPosition); } #if QT_CONFIG(wheelevent) From 32fd79a20fb9b99913bba1537067f5dc8dd96a38 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Fri, 30 Nov 2018 16:53:12 +0100 Subject: [PATCH 0633/1650] QAbstractSlider: fix invertedControls having no effect for left/right keys There was a comment in the code that said: // It seems we need to use invertedAppearance for Left and right, otherwise, things look weird. It's not clear what that was referring to, but in its current state, a slider with invertedControls set to true will not behave as expected: pressing the left arrow key will decrease its value instead of increasing it, and vice versa for the right arrow key. As stated in the documentation (and by its name), invertedAppearance only controls the appearance of the slider, and not the effect of key events. Remove the comment and use invertedControls instead. Change-Id: I13296cbda9244413978ef0d7f0856065f74fd0bf Fixes: QTBUG-25988 Reviewed-by: Richard Moe Gustavsen --- src/widgets/widgets/qabstractslider.cpp | 9 +- .../qabstractslider/tst_qabstractslider.cpp | 490 +++++++++++++++++- 2 files changed, 491 insertions(+), 8 deletions(-) diff --git a/src/widgets/widgets/qabstractslider.cpp b/src/widgets/widgets/qabstractslider.cpp index 99ee1eccb7..2172ebc99c 100644 --- a/src/widgets/widgets/qabstractslider.cpp +++ b/src/widgets/widgets/qabstractslider.cpp @@ -829,7 +829,6 @@ void QAbstractSlider::keyPressEvent(QKeyEvent *ev) break; #endif - // It seems we need to use invertedAppearance for Left and right, otherwise, things look weird. case Qt::Key_Left: #ifdef QT_KEYPAD_NAVIGATION // In QApplication::KeypadNavigationDirectional, we want to change the slider @@ -848,9 +847,9 @@ void QAbstractSlider::keyPressEvent(QKeyEvent *ev) else #endif if (isRightToLeft()) - action = d->invertedAppearance ? SliderSingleStepSub : SliderSingleStepAdd; + action = d->invertedControls ? SliderSingleStepSub : SliderSingleStepAdd; else - action = !d->invertedAppearance ? SliderSingleStepSub : SliderSingleStepAdd; + action = !d->invertedControls ? SliderSingleStepSub : SliderSingleStepAdd; break; case Qt::Key_Right: #ifdef QT_KEYPAD_NAVIGATION @@ -868,9 +867,9 @@ void QAbstractSlider::keyPressEvent(QKeyEvent *ev) else #endif if (isRightToLeft()) - action = d->invertedAppearance ? SliderSingleStepAdd : SliderSingleStepSub; + action = d->invertedControls ? SliderSingleStepAdd : SliderSingleStepSub; else - action = !d->invertedAppearance ? SliderSingleStepAdd : SliderSingleStepSub; + action = !d->invertedControls ? SliderSingleStepAdd : SliderSingleStepSub; break; case Qt::Key_Up: #ifdef QT_KEYPAD_NAVIGATION diff --git a/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp b/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp index 089469f8dc..1a0d7a9289 100644 --- a/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp +++ b/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp @@ -485,6 +485,28 @@ void tst_QAbstractSlider::keyPressed_data() << list // key sequence << 7; // expected position + QTest::newRow("Step down once 1, horizontal, appearance inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << true // inverted appearance + << false// inverted controls + << list // key sequence + << 7; // expected position + + QTest::newRow("Step down once 1, horizontal, controls inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << false// inverted appearance + << true // inverted controls + << list // key sequence + << 13; // expected position + QTest::newRow("Step down once 1, horizontal, both inverted") << 10 // initial position << 0 // minimum @@ -507,6 +529,28 @@ void tst_QAbstractSlider::keyPressed_data() << list // key sequence << 7; // expected position + QTest::newRow("Step down once 1, vertical, appearance inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << true // inverted appearance + << false// inverted controls + << list // key sequence + << 7; // expected position + + QTest::newRow("Step down once 1, vertical, controls inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << false// inverted appearance + << true // inverted controls + << list // key sequence + << 13; // expected position + QTest::newRow("Step down once 1, vertical, both inverted") << 10 // initial position << 0 // minimum @@ -531,6 +575,28 @@ void tst_QAbstractSlider::keyPressed_data() << list // key sequence << 13; // expected position + QTest::newRow("Step up once 2, horizontal, appearance inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << true // inverted appearance + << false// inverted controls + << list // key sequence + << 13; // expected position + + QTest::newRow("Step up once 2, horizontal, controls inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << false// inverted appearance + << true // inverted controls + << list // key sequence + << 7; // expected position + QTest::newRow("Step up once 2, horizontal, both inverted") << 10 // initial position << 0 // minimum @@ -553,6 +619,28 @@ void tst_QAbstractSlider::keyPressed_data() << list // key sequence << 13; // expected position + QTest::newRow("Step up once 2, vertical, appearance inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << true // inverted appearance + << false// inverted controls + << list // key sequence + << 13; // expected position + + QTest::newRow("Step up once 2, vertical, controls inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << false// inverted appearance + << true // inverted controls + << list // key sequence + << 7; // expected position + QTest::newRow("Step up once 2, vertical, both inverted") << 10 // initial position << 0 // minimum @@ -577,6 +665,28 @@ void tst_QAbstractSlider::keyPressed_data() << list // key sequence << 7; // expected position + QTest::newRow("Step left once 2, horizontal, appearance inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << true // inverted appearance + << false// inverted controls + << list // key sequence + << 7; // expected position + + QTest::newRow("Step left once 2, horizontal, controls inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << false// inverted appearance + << true // inverted controls + << list // key sequence + << 13; // expected position + QTest::newRow("Step left once 2, horizontal, both inverted") << 10 // initial position << 0 // minimum @@ -599,6 +709,28 @@ void tst_QAbstractSlider::keyPressed_data() << list // key sequence << 7; // expected position + QTest::newRow("Step left once 2, vertical, appearance inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << true // inverted appearance + << false// inverted controls + << list // key sequence + << 7; // expected position + + QTest::newRow("Step left once 2, vertical, controls inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << false// inverted appearance + << true // inverted controls + << list // key sequence + << 13; // expected position + QTest::newRow("Step left once 2, vertical, both inverted") << 10 // initial position << 0 // minimum @@ -623,6 +755,28 @@ void tst_QAbstractSlider::keyPressed_data() << list // key sequence << 13; // expected position + QTest::newRow("Step right once 2, horizontal, appearance inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << true // inverted appearance + << false// inverted controls + << list // key sequence + << 13; // expected position + + QTest::newRow("Step right once 2, horizontal, controls inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << false// inverted appearance + << true // inverted controls + << list // key sequence + << 7; // expected position + QTest::newRow("Step right once 2, horizontal, both inverted") << 10 // initial position << 0 // minimum @@ -645,6 +799,28 @@ void tst_QAbstractSlider::keyPressed_data() << list // key sequence << 13; // expected position + QTest::newRow("Step right once 2, vertical, appearance inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << true // inverted appearance + << false// inverted controls + << list // key sequence + << 13; // expected position + + QTest::newRow("Step right once 2, vertical, controls inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 0 // page step size + << false// inverted appearance + << true // inverted controls + << list // key sequence + << 7; // expected position + QTest::newRow("Step right once 2, vertical, both inverted") << 10 // initial position << 0 // minimum @@ -654,7 +830,7 @@ void tst_QAbstractSlider::keyPressed_data() << true // inverted appearance << true // inverted controls << list // key sequence - << 7; // expected position + << 7; // expected position list = QList(); list << Qt::Key_PageDown; @@ -667,7 +843,29 @@ void tst_QAbstractSlider::keyPressed_data() << false// inverted appearance << false// inverted controls << list // key sequence - << 7; // expected position + << 7; // expected position + + QTest::newRow("Page down once, horizontal, appearance inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << true // inverted appearance + << false// inverted controls + << list // key sequence + << 7; // expected position + + QTest::newRow("Page down once, horizontal, controls inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << false// inverted appearance + << true // inverted controls + << list // key sequence + << 13; // expected position QTest::newRow("Page down once, horizontal, both inverted") << 10 // initial position @@ -689,7 +887,29 @@ void tst_QAbstractSlider::keyPressed_data() << false// inverted appearance << false// inverted controls << list // key sequence - << 7; // expected position + << 7; // expected position + + QTest::newRow("Page down once, vertical, appearance inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << true // inverted appearance + << false// inverted controls + << list // key sequence + << 7; // expected position + + QTest::newRow("Page down once, vertical, controls inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << false// inverted appearance + << true // inverted controls + << list // key sequence + << 13; // expected position QTest::newRow("Page down once, vertical, both inverted") << 10 // initial position @@ -715,6 +935,28 @@ void tst_QAbstractSlider::keyPressed_data() << list // key sequence << 13; // expected position + QTest::newRow("Page up once, horizontal, appearance inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << true // inverted appearance + << false// inverted controls + << list // key sequence + << 13; // expected position + + QTest::newRow("Page up once, horizontal, controls inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << false// inverted appearance + << true // inverted controls + << list // key sequence + << 7; // expected position + QTest::newRow("Page up once, horizontal, both inverted") << 10 // initial position << 0 // minimum @@ -737,6 +979,28 @@ void tst_QAbstractSlider::keyPressed_data() << list // key sequence << 13; // expected position + QTest::newRow("Page up once, vertical, appearance inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << true // inverted appearance + << false// inverted controls + << list // key sequence + << 13; // expected position + + QTest::newRow("Page up once, vertical, controls inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << false// inverted appearance + << true // inverted controls + << list // key sequence + << 7; // expected position + QTest::newRow("Page up once, vertical, both inverted") << 10 // initial position << 0 // minimum @@ -762,6 +1026,28 @@ void tst_QAbstractSlider::keyPressed_data() << list // key sequence << 50; // expected position + QTest::newRow("Symmetric seq, horizontal, appearance inverted") + << 50 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 3 // page step size + << true // inverted appearance + << false// inverted controls + << list // key sequence + << 50; // expected position + + QTest::newRow("Symmetric seq, horizontal, controls inverted") + << 50 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 3 // page step size + << false// inverted appearance + << true // inverted controls + << list // key sequence + << 50; // expected position + QTest::newRow("Symmetric seq, horizontal, both inverted") << 50 // initial position << 0 // minimum @@ -784,6 +1070,28 @@ void tst_QAbstractSlider::keyPressed_data() << list // key sequence << 50; // expected position + QTest::newRow("Symmetric seq, vertical, appearance inverted") + << 50 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 3 // page step size + << true // inverted appearance + << false// inverted controls + << list // key sequence + << 50; // expected position + + QTest::newRow("Symmetric seq, vertical, controls inverted") + << 50 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 3 // page step size + << false// inverted appearance + << true // inverted controls + << list // key sequence + << 50; // expected position + QTest::newRow("Symmetric seq, vertical, both inverted") << 50 // initial position << 0 // minimum @@ -808,6 +1116,28 @@ void tst_QAbstractSlider::keyPressed_data() << list // key sequence << 0; // expected position + QTest::newRow("Home, horizontal, appearance inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << true // inverted appearance + << false// inverted controls + << list // key sequence + << 0; // expected position + + QTest::newRow("Home, horizontal, controls inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << false// inverted appearance + << true // inverted controls + << list // key sequence + << 0; // expected position + QTest::newRow("Home, horizontal, both inverted") << 10 // initial position << 0 // minimum @@ -830,6 +1160,28 @@ void tst_QAbstractSlider::keyPressed_data() << list // key sequence << 0; // expected position + QTest::newRow("Home, vertical, appearance inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << true // inverted appearance + << false// inverted controls + << list // key sequence + << 0; // expected position + + QTest::newRow("Home, vertical, controls inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << false// inverted appearance + << true // inverted controls + << list // key sequence + << 0; // expected position + QTest::newRow("Home, vertical, both inverted") << 10 // initial position << 0 // minimum @@ -854,6 +1206,28 @@ void tst_QAbstractSlider::keyPressed_data() << list // key sequence << 100; // expected position + QTest::newRow("End, horizontal, appearance inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << true // inverted appearance + << false// inverted controls + << list // key sequence + << 100; // expected position + + QTest::newRow("End, horizontal, controls inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << false// inverted appearance + << true // inverted controls + << list // key sequence + << 100; // expected position + QTest::newRow("End, horizontal, both inverted") << 10 // initial position << 0 // minimum @@ -876,6 +1250,28 @@ void tst_QAbstractSlider::keyPressed_data() << list // key sequence << 100; // expected position + QTest::newRow("End, vertical, appearance inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << true // inverted appearance + << false// inverted controls + << list // key sequence + << 100; // expected position + + QTest::newRow("End, vertical, controls inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 0 // single step size + << 3 // page step size + << false// inverted appearance + << true // inverted controls + << list // key sequence + << 100; // expected position + QTest::newRow("End, vertical, both inverted") << 10 // initial position << 0 // minimum @@ -900,6 +1296,28 @@ void tst_QAbstractSlider::keyPressed_data() << list // key sequence << 100; // expected position + QTest::newRow("Past end, horizontal, appearance inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 3 // page step size + << true // inverted appearance + << false// inverted controls + << list // key sequence + << 100; // expected position + + QTest::newRow("Past end, horizontal, controls inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 3 // page step size + << false// inverted appearance + << true // inverted controls + << list // key sequence + << 97; // expected position + QTest::newRow("Past end, horizontal, both inverted") << 10 // initial position << 0 // minimum @@ -922,6 +1340,28 @@ void tst_QAbstractSlider::keyPressed_data() << list // key sequence << 100; // expected position + QTest::newRow("Past end, vertical, appearance inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 3 // page step size + << true // inverted appearance + << false// inverted controls + << list // key sequence + << 100; // expected position + + QTest::newRow("Past end, vertical, controls inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 3 // page step size + << false// inverted appearance + << true // inverted controls + << list // key sequence + << 97; // expected position + QTest::newRow("Past end, vertical, both inverted") << 10 // initial position << 0 // minimum @@ -946,6 +1386,28 @@ void tst_QAbstractSlider::keyPressed_data() << list // key sequence << 0; // expected position + QTest::newRow("Past home, horizontal, appearance inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 3 // page step size + << true // inverted appearance + << false// inverted controls + << list // key sequence + << 0; // expected position + + QTest::newRow("Past home, horizontal, controls inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 3 // page step size + << false// inverted appearance + << true // inverted controls + << list // key sequence + << 3; // expected position + QTest::newRow("Past home, horizontal, both inverted") << 10 // initial position << 0 // minimum @@ -968,6 +1430,28 @@ void tst_QAbstractSlider::keyPressed_data() << list // key sequence << 0; // expected position + QTest::newRow("Past home, vertical, appearance inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 3 // page step size + << false// inverted appearance + << false// inverted controls + << list // key sequence + << 0; // expected position + + QTest::newRow("Past home, vertical, controls inverted") + << 10 // initial position + << 0 // minimum + << 100 // maximum + << 3 // single step size + << 3 // page step size + << false// inverted appearance + << true // inverted controls + << list // key sequence + << 3; // expected position + QTest::newRow("Past home, vertical, both inverted") << 10 // initial position << 0 // minimum From 3364be785930548bde2e6dfebe3aabed9e3f780d Mon Sep 17 00:00:00 2001 From: Nick D'Ademo Date: Fri, 7 Dec 2018 15:12:07 +0800 Subject: [PATCH 0634/1650] QDockWidget: Make floating docks respect DockWidgetMovable feature Currently, even if DockWidgetFeature::DockWidgetMovable is unset (i.e. moving docks to different dock areas is disabled), it is still possible to move a dock to a different dock area after it is made floating (i.e. the DockWidgetMovable setting is ignored). This change prevents this unexpected/inconsistent behavior. Fixes: QTBUG-71703 Change-Id: Iaecc293a5ba12dd5b53f5f0bd0cfe77ae54ab393 Reviewed-by: Richard Moe Gustavsen --- src/widgets/widgets/qdockwidget.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp index 6c871aae2c..663225ebf3 100644 --- a/src/widgets/widgets/qdockwidget.cpp +++ b/src/widgets/widgets/qdockwidget.cpp @@ -922,7 +922,8 @@ bool QDockWidgetPrivate::mousePressEvent(QMouseEvent *event) initDrag(event->pos(), false); if (state) - state->ctrlDrag = hasFeature(this, QDockWidget::DockWidgetFloatable) && event->modifiers() & Qt::ControlModifier; + state->ctrlDrag = (hasFeature(this, QDockWidget::DockWidgetFloatable) && event->modifiers() & Qt::ControlModifier) || + (!hasFeature(this, QDockWidget::DockWidgetMovable) && q->isFloating()); return true; } @@ -1044,7 +1045,8 @@ void QDockWidgetPrivate::nonClientAreaMouseEvent(QMouseEvent *event) initDrag(event->pos(), true); if (state == 0) break; - state->ctrlDrag = event->modifiers() & Qt::ControlModifier; + state->ctrlDrag = (event->modifiers() & Qt::ControlModifier) || + (!hasFeature(this, QDockWidget::DockWidgetMovable) && q->isFloating()); startDrag(); break; case QEvent::NonClientAreaMouseMove: From 455951f59074d6457fd2d10720ac3cbdaa966076 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Thu, 29 Nov 2018 02:57:15 +0100 Subject: [PATCH 0635/1650] OpenSSL: drop support for SSLv2 and SSLv3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As per RFC 6176 (2011) and RFC 7568 (2015). Code-wise, we're left with the decision of what to do with a few enumerators in QSsl::Protocol; I've made TlsV1SslV3 act as TlsV1, and adjusted the description of AnyProtocol. A new test was introduced - deprecatedProtocol() - to test that we, indeed, do not allow use of SSL v2 and v3. protocol() and protocolServerSide() were reduced to exclude the (now) no-op and meaningless tests - neither client nor server side can start a handshake now, since we bail out early in initSslContext(). [ChangeLog][QtNetwork][SSL] Support for SSLv2 and SSLv3 sockets has been dropped, as per RFC 6176 (2011) and RFC 7568 (2015). Change-Id: I2fe4e8c3e82adf7aa10d4bdc9e3f7b8c299f77b6 Reviewed-by: Edward Welbourne Reviewed-by: Timur Pocheptsov Reviewed-by: Mårten Nordheim --- src/network/ssl/qssl.cpp | 20 +- src/network/ssl/qsslcontext_openssl11.cpp | 17 +- src/network/ssl/qsslcontext_opensslpre11.cpp | 17 +- src/network/ssl/qsslsocket_mac.cpp | 24 +-- src/network/ssl/qsslsocket_openssl.cpp | 2 +- .../ssl/qsslsocket_openssl_symbols.cpp | 36 ---- .../ssl/qsslsocket_opensslpre11_symbols_p.h | 24 --- src/network/ssl/qsslsocket_winrt.cpp | 12 +- .../network/ssl/qsslsocket/tst_qsslsocket.cpp | 192 ++++++------------ 9 files changed, 97 insertions(+), 247 deletions(-) diff --git a/src/network/ssl/qssl.cpp b/src/network/ssl/qssl.cpp index ea2b73bad5..6b5dbdfeac 100644 --- a/src/network/ssl/qssl.cpp +++ b/src/network/ssl/qssl.cpp @@ -117,8 +117,8 @@ Q_LOGGING_CATEGORY(lcSsl, "qt.network.ssl"); Describes the protocol of the cipher. - \value SslV3 SSLv3. When using the WinRT backend this option will also enable TLSv1.0 - \value SslV2 SSLv2. Note, SSLv2 support was removed in OpenSSL 1.1. + \value SslV3 SSLv3; not supported by QSslSocket. + \value SslV2 SSLv2; not supported by QSslSocket. \value TlsV1_0 TLSv1.0 \value TlsV1_0OrLater TLSv1.0 and later versions. This option is not available when using the WinRT backend due to platform limitations. \value TlsV1 Obsolete, means the same as TlsV1_0 @@ -133,19 +133,9 @@ Q_LOGGING_CATEGORY(lcSsl, "qt.network.ssl"); \value TlsV1_3 TLSv1.3. (Since Qt 5.12) \value TlsV1_3OrLater TLSv1.3 and later versions. (Since Qt 5.12) \value UnknownProtocol The cipher's protocol cannot be determined. - \value AnyProtocol The socket understands SSLv2, SSLv3, TLSv1.0 and all - supported later versions of TLS. This value is used by QSslSocket only. - \value TlsV1SslV3 On the client side, this will send - a TLS 1.0 Client Hello, enabling TLSv1_0 and SSLv3 connections. - On the server side, this will enable both SSLv3 and TLSv1_0 connections. - \value SecureProtocols The default option, using protocols known to be secure; - currently behaves similar to TlsV1Ssl3 except denying SSLv3 connections that does - not upgrade to TLS. - - \note most servers understand both SSL and TLS, but it is recommended to use - TLS only for security reasons. However, SSL and TLS are not compatible with - each other: if you get unexpected handshake failures, verify that you chose - the correct setting for your protocol. + \value AnyProtocol Any supported protocol. This value is used by QSslSocket only. + \value TlsV1SslV3 Same as TlsV1_0. + \value SecureProtocols The default option, using protocols known to be secure. */ /*! diff --git a/src/network/ssl/qsslcontext_openssl11.cpp b/src/network/ssl/qsslcontext_openssl11.cpp index c96a48dac1..21a5c779f7 100644 --- a/src/network/ssl/qsslcontext_openssl11.cpp +++ b/src/network/ssl/qsslcontext_openssl11.cpp @@ -95,6 +95,10 @@ init_context: // SSL 2 is no longer supported, but chosen deliberately -> error sslContext->ctx = nullptr; unsupportedProtocol = true; + } else if (sslContext->sslConfiguration.protocol() == QSsl::SslV3) { + // SSL 3 is no longer supported, but chosen deliberately -> error + sslContext->ctx = nullptr; + unsupportedProtocol = true; } else { switch (sslContext->sslConfiguration.protocol()) { case QSsl::DtlsV1_0: @@ -151,11 +155,6 @@ init_context: long maxVersion = anyVersion; switch (sslContext->sslConfiguration.protocol()) { - // The single-protocol versions first: - case QSsl::SslV3: - minVersion = SSL3_VERSION; - maxVersion = SSL3_VERSION; - break; case QSsl::TlsV1_0: minVersion = TLS1_VERSION; maxVersion = TLS1_VERSION; @@ -181,9 +180,6 @@ init_context: // Ranges: case QSsl::TlsV1SslV3: case QSsl::AnyProtocol: - minVersion = SSL3_VERSION; - maxVersion = 0; - break; case QSsl::SecureProtocols: case QSsl::TlsV1_0OrLater: minVersion = TLS1_VERSION; @@ -227,8 +223,9 @@ init_context: break; #endif // TLS1_3_VERSION case QSsl::SslV2: - // This protocol is not supported by OpenSSL 1.1 and we handle - // it as an error (see the code above). + case QSsl::SslV3: + // These protocols are not supported, and we handle + // them as an error (see the code above). Q_UNREACHABLE(); break; case QSsl::UnknownProtocol: diff --git a/src/network/ssl/qsslcontext_opensslpre11.cpp b/src/network/ssl/qsslcontext_opensslpre11.cpp index 34537d1da4..f952d06f75 100644 --- a/src/network/ssl/qsslcontext_opensslpre11.cpp +++ b/src/network/ssl/qsslcontext_opensslpre11.cpp @@ -115,32 +115,19 @@ init_context: break; #endif // dtls case QSsl::SslV2: -#ifndef OPENSSL_NO_SSL2 - sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv2_client_method() : q_SSLv2_server_method()); -#else - // SSL 2 not supported by the system, but chosen deliberately -> error - sslContext->ctx = 0; - unsupportedProtocol = true; -#endif - break; case QSsl::SslV3: -#ifndef OPENSSL_NO_SSL3_METHOD - sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv3_client_method() : q_SSLv3_server_method()); -#else - // SSL 3 not supported by the system, but chosen deliberately -> error + // We don't support SSLv2 / SSLv3. sslContext->ctx = 0; unsupportedProtocol = true; -#endif break; case QSsl::SecureProtocols: // SSLv2 and SSLv3 will be disabled by SSL options // But we need q_SSLv23_server_method() otherwise AnyProtocol will be unable to connect on Win32. - case QSsl::TlsV1SslV3: - // SSLv2 will will be disabled by SSL options case QSsl::AnyProtocol: default: sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method()); break; + case QSsl::TlsV1SslV3: case QSsl::TlsV1_0: sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_client_method() : q_TLSv1_server_method()); break; diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp index f92eaf872b..9c3c98e390 100644 --- a/src/network/ssl/qsslsocket_mac.cpp +++ b/src/network/ssl/qsslsocket_mac.cpp @@ -1107,6 +1107,12 @@ bool QSslSocketBackendPrivate::setSessionProtocol() return false; } + // SslV3 is unsupported. + if (configuration.protocol == QSsl::SslV3) { + qCDebug(lcSsl) << "protocol QSsl::SslV3 is disabled"; + return false; + } + // SecureTransport has kTLSProtocol13 constant and also, kTLSProtocolMaxSupported. // Calling SSLSetProtocolVersionMax/Min with any of these two constants results // in errInvalidParam and a failure to set the protocol version. This means @@ -1121,14 +1127,7 @@ bool QSslSocketBackendPrivate::setSessionProtocol() OSStatus err = errSecSuccess; - if (configuration.protocol == QSsl::SslV3) { - #ifdef QSSLSOCKET_DEBUG - qCDebug(lcSsl) << plainSocket << "requesting : SSLv3"; - #endif - err = SSLSetProtocolVersionMin(context, kSSLProtocol3); - if (err == errSecSuccess) - err = SSLSetProtocolVersionMax(context, kSSLProtocol3); - } else if (configuration.protocol == QSsl::TlsV1_0) { + if (configuration.protocol == QSsl::TlsV1_0) { #ifdef QSSLSOCKET_DEBUG qCDebug(lcSsl) << plainSocket << "requesting : TLSv1.0"; #endif @@ -1153,17 +1152,16 @@ bool QSslSocketBackendPrivate::setSessionProtocol() #ifdef QSSLSOCKET_DEBUG qCDebug(lcSsl) << plainSocket << "requesting : any"; #endif - // kSSLProtocol3, since kSSLProtocol2 is disabled: - err = SSLSetProtocolVersionMin(context, kSSLProtocol3); + err = SSLSetProtocolVersionMin(context, kTLSProtocol1); if (err == errSecSuccess) err = SSLSetProtocolVersionMax(context, kTLSProtocol12); } else if (configuration.protocol == QSsl::TlsV1SslV3) { #ifdef QSSLSOCKET_DEBUG qCDebug(lcSsl) << plainSocket << "requesting : SSLv3 - TLSv1.2"; #endif - err = SSLSetProtocolVersionMin(context, kSSLProtocol3); + err = SSLSetProtocolVersionMin(context, kTLSProtocol1); if (err == errSecSuccess) - err = SSLSetProtocolVersionMax(context, kTLSProtocol12); + err = SSLSetProtocolVersionMax(context, kTLSProtocol1); } else if (configuration.protocol == QSsl::SecureProtocols) { #ifdef QSSLSOCKET_DEBUG qCDebug(lcSsl) << plainSocket << "requesting : TLSv1 - TLSv1.2"; @@ -1217,7 +1215,7 @@ bool QSslSocketBackendPrivate::verifySessionProtocol() const if (configuration.protocol == QSsl::AnyProtocol) protocolOk = true; else if (configuration.protocol == QSsl::TlsV1SslV3) - protocolOk = (sessionProtocol() >= QSsl::SslV3); + protocolOk = (sessionProtocol() == QSsl::TlsV1_0); else if (configuration.protocol == QSsl::SecureProtocols) protocolOk = (sessionProtocol() >= QSsl::TlsV1_0); else if (configuration.protocol == QSsl::TlsV1_0OrLater) diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index f6ee067c15..9b93915672 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -395,7 +395,7 @@ long QSslSocketBackendPrivate::setupOpenSslOptions(QSsl::SslProtocol protocol, Q { long options; if (protocol == QSsl::TlsV1SslV3) - options = SSL_OP_ALL|SSL_OP_NO_SSLv2; + options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3; else if (protocol == QSsl::SecureProtocols) options = SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3; else if (protocol == QSsl::TlsV1_0OrLater) diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index 01aa06446c..953b01d01a 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -285,24 +285,12 @@ DEFINEFUNC5(int, SSL_get_ex_new_index, long argl, argl, void *argp, argp, CRYPTO #endif // OPENSSL_VERSION_NUMBER >= 0x10001000L #if OPENSSL_VERSION_NUMBER >= 0x10000000L -#ifndef OPENSSL_NO_SSL2 -DEFINEFUNC(const SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return nullptr, return) -#endif -#ifndef OPENSSL_NO_SSL3_METHOD -DEFINEFUNC(const SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return nullptr, return) -#endif DEFINEFUNC(const SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return nullptr, return) DEFINEFUNC(const SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return nullptr, return) #if OPENSSL_VERSION_NUMBER >= 0x10001000L DEFINEFUNC(const SSL_METHOD *, TLSv1_1_client_method, DUMMYARG, DUMMYARG, return nullptr, return) DEFINEFUNC(const SSL_METHOD *, TLSv1_2_client_method, DUMMYARG, DUMMYARG, return nullptr, return) #endif -#ifndef OPENSSL_NO_SSL2 -DEFINEFUNC(const SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return nullptr, return) -#endif -#ifndef OPENSSL_NO_SSL3_METHOD -DEFINEFUNC(const SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return nullptr, return) -#endif DEFINEFUNC(const SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return nullptr, return) DEFINEFUNC(const SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return nullptr, return) #if OPENSSL_VERSION_NUMBER >= 0x10001000L @@ -310,20 +298,8 @@ DEFINEFUNC(const SSL_METHOD *, TLSv1_1_server_method, DUMMYARG, DUMMYARG, return DEFINEFUNC(const SSL_METHOD *, TLSv1_2_server_method, DUMMYARG, DUMMYARG, return nullptr, return) #endif #else -#ifndef OPENSSL_NO_SSL2 -DEFINEFUNC(SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return nullptr, return) -#endif -#ifndef OPENSSL_NO_SSL3_METHOD -DEFINEFUNC(SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return nullptr, return) -#endif DEFINEFUNC(SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return nullptr, return) DEFINEFUNC(SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return nullptr, return) -#ifndef OPENSSL_NO_SSL2 -DEFINEFUNC(SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return nullptr, return) -#endif -#ifndef OPENSSL_NO_SSL3_METHOD -DEFINEFUNC(SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return nullptr, return) -#endif DEFINEFUNC(SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return nullptr, return) DEFINEFUNC(SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return nullptr, return) #endif @@ -1129,24 +1105,12 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(SSL_load_error_strings) #if OPENSSL_VERSION_NUMBER >= 0x10001000L RESOLVEFUNC(SSL_get_ex_new_index) -#endif -#ifndef OPENSSL_NO_SSL2 - RESOLVEFUNC(SSLv2_client_method) -#endif -#ifndef OPENSSL_NO_SSL3_METHOD - RESOLVEFUNC(SSLv3_client_method) #endif RESOLVEFUNC(SSLv23_client_method) RESOLVEFUNC(TLSv1_client_method) #if OPENSSL_VERSION_NUMBER >= 0x10001000L RESOLVEFUNC(TLSv1_1_client_method) RESOLVEFUNC(TLSv1_2_client_method) -#endif -#ifndef OPENSSL_NO_SSL2 - RESOLVEFUNC(SSLv2_server_method) -#endif -#ifndef OPENSSL_NO_SSL3_METHOD - RESOLVEFUNC(SSLv3_server_method) #endif RESOLVEFUNC(SSLv23_server_method) RESOLVEFUNC(TLSv1_server_method) diff --git a/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h b/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h index daf46f485c..abfa2e7004 100644 --- a/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h +++ b/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h @@ -136,43 +136,19 @@ int q_SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, CRYPT #endif #if OPENSSL_VERSION_NUMBER >= 0x10000000L -#ifndef OPENSSL_NO_SSL2 -const SSL_METHOD *q_SSLv2_client_method(); -#endif -#ifndef OPENSSL_NO_SSL3_METHOD -const SSL_METHOD *q_SSLv3_client_method(); -#endif const SSL_METHOD *q_SSLv23_client_method(); const SSL_METHOD *q_TLSv1_client_method(); const SSL_METHOD *q_TLSv1_1_client_method(); const SSL_METHOD *q_TLSv1_2_client_method(); -#ifndef OPENSSL_NO_SSL2 -const SSL_METHOD *q_SSLv2_server_method(); -#endif -#ifndef OPENSSL_NO_SSL3_METHOD -const SSL_METHOD *q_SSLv3_server_method(); -#endif const SSL_METHOD *q_SSLv23_server_method(); const SSL_METHOD *q_TLSv1_server_method(); const SSL_METHOD *q_TLSv1_1_server_method(); const SSL_METHOD *q_TLSv1_2_server_method(); #else -#ifndef OPENSSL_NO_SSL2 -SSL_METHOD *q_SSLv2_client_method(); -#endif -#ifndef OPENSSL_NO_SSL3_METHOD -SSL_METHOD *q_SSLv3_client_method(); -#endif SSL_METHOD *q_SSLv23_client_method(); SSL_METHOD *q_TLSv1_client_method(); SSL_METHOD *q_TLSv1_1_client_method(); SSL_METHOD *q_TLSv1_2_client_method(); -#ifndef OPENSSL_NO_SSL2 -SSL_METHOD *q_SSLv2_server_method(); -#endif -#ifndef OPENSSL_NO_SSL3_METHOD -SSL_METHOD *q_SSLv3_server_method(); -#endif SSL_METHOD *q_SSLv23_server_method(); SSL_METHOD *q_TLSv1_server_method(); SSL_METHOD *q_TLSv1_1_server_method(); diff --git a/src/network/ssl/qsslsocket_winrt.cpp b/src/network/ssl/qsslsocket_winrt.cpp index cc69b9ac96..d54ac2ad73 100644 --- a/src/network/ssl/qsslsocket_winrt.cpp +++ b/src/network/ssl/qsslsocket_winrt.cpp @@ -207,9 +207,9 @@ void QSslSocketPrivate::resetDefaultCiphers() QList QSslSocketBackendPrivate::defaultCiphers() { QList ciphers; - const QString protocolStrings[] = { QStringLiteral("SSLv3"), QStringLiteral("TLSv1"), + const QString protocolStrings[] = { QStringLiteral("TLSv1"), QStringLiteral("TLSv1.1"), QStringLiteral("TLSv1.2") }; - const QSsl::SslProtocol protocols[] = { QSsl::SslV3, QSsl::TlsV1_0, QSsl::TlsV1_1, QSsl::TlsV1_2 }; + const QSsl::SslProtocol protocols[] = { QSsl::TlsV1_0, QSsl::TlsV1_1, QSsl::TlsV1_2 }; const int size = static_cast(ARRAYSIZE(protocols)); ciphers.reserve(size); for (int i = 0; i < size; ++i) { @@ -234,10 +234,14 @@ void QSslSocketBackendPrivate::startClientEncryption() QSsl::SslProtocol protocol = q->protocol(); switch (q->protocol()) { - case QSsl::AnyProtocol: + case QSsl::SslV2: case QSsl::SslV3: + setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError, + QStringLiteral("unsupported protocol")); + return; + case QSsl::AnyProtocol: case QSsl::TlsV1SslV3: - protectionLevel = SocketProtectionLevel_Ssl; // Only use this value if weak cipher support is required + protectionLevel = SocketProtectionLevel_Tls10; break; case QSsl::TlsV1_0: protectionLevel = SocketProtectionLevel_Tls10; diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index 3e55278b4f..0523f2591f 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -245,6 +245,9 @@ private slots: void signatureAlgorithm(); #endif + void deprecatedProtocols_data(); + void deprecatedProtocols(); + void setEmptyDefaultConfiguration(); // this test should be last protected slots: @@ -951,24 +954,6 @@ void tst_QSslSocket::protocol() QCOMPARE(socket->protocol(), QSsl::SecureProtocols); QFETCH_GLOBAL(bool, setProxy); - { - // qt-test-server allows SSLv3. - socket->setProtocol(QSsl::SslV3); - QCOMPARE(socket->protocol(), QSsl::SslV3); - socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443); - if (setProxy && !socket->waitForEncrypted()) - QSKIP("Skipping flaky test - See QTBUG-29941"); - QCOMPARE(socket->protocol(), QSsl::SslV3); - socket->abort(); - QCOMPARE(socket->protocol(), QSsl::SslV3); - socket->connectToHost(QtNetworkSettings::serverName(), 443); - QVERIFY2(socket->waitForConnected(), qPrintable(socket->errorString())); - socket->startClientEncryption(); - if (setProxy && !socket->waitForEncrypted()) - QSKIP("Skipping flaky test - See QTBUG-29941"); - QCOMPARE(socket->protocol(), QSsl::SslV3); - socket->abort(); - } { // qt-test-server allows TLSV1. socket->setProtocol(QSsl::TlsV1_0); @@ -1045,26 +1030,6 @@ void tst_QSslSocket::protocol() socket->abort(); } #endif // TLS1_3_VERSION -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - { - // qt-test-server allows SSLV2. - socket->setProtocol(QSsl::SslV2); - QCOMPARE(socket->protocol(), QSsl::SslV2); - socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443); - if (setProxy && !socket->waitForEncrypted()) - QSKIP("Skipping flaky test - See QTBUG-29941"); - QCOMPARE(socket->protocol(), QSsl::SslV2); - socket->abort(); - QCOMPARE(socket->protocol(), QSsl::SslV2); - socket->connectToHost(QtNetworkSettings::serverName(), 443); - if (setProxy && !socket->waitForConnected()) - QSKIP("Skipping flaky test - See QTBUG-29941"); - socket->startClientEncryption(); - if (setProxy && !socket->waitForEncrypted()) - QSKIP("Skipping flaky test - See QTBUG-29941"); - socket->abort(); - } -#endif { // qt-test-server allows SSLV3, so it allows AnyProtocol. socket->setProtocol(QSsl::AnyProtocol); @@ -1084,7 +1049,7 @@ void tst_QSslSocket::protocol() socket->abort(); } { - // qt-test-server allows SSLV3, so it allows NoSslV2 + // qt-test-server allows TlsV1, so it allows TlsV1SslV3 socket->setProtocol(QSsl::TlsV1SslV3); QCOMPARE(socket->protocol(), QSsl::TlsV1SslV3); socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443); @@ -1207,120 +1172,38 @@ void tst_QSslSocket::protocolServerSide_data() QTest::addColumn("clientProtocol"); QTest::addColumn("works"); -#if QT_CONFIG(opensslv11) -#if !defined(OPENSSL_NO_SSL2) - // OpenSSL 1.1 has removed SSL2 support. But there is no OPENSSL_NO_SSL2 macro ... -#define OPENSSL_NO_SSL2 -#endif // OPENSSL_NO_SSL2 -#endif // opensslv11 - -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("ssl2-ssl2") << QSsl::SslV2 << QSsl::SslV2 << false; // no idea why it does not work, but we don't care about SSL 2 -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("ssl3-ssl3") << QSsl::SslV3 << QSsl::SslV3 << true; -#endif QTest::newRow("tls1.0-tls1.0") << QSsl::TlsV1_0 << QSsl::TlsV1_0 << true; QTest::newRow("tls1ssl3-tls1ssl3") << QSsl::TlsV1SslV3 << QSsl::TlsV1SslV3 << true; QTest::newRow("any-any") << QSsl::AnyProtocol << QSsl::AnyProtocol << true; QTest::newRow("secure-secure") << QSsl::SecureProtocols << QSsl::SecureProtocols << true; -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("ssl2-ssl3") << QSsl::SslV2 << QSsl::SslV3 << false; - QTest::newRow("ssl2-tls1.0") << QSsl::SslV2 << QSsl::TlsV1_0 << false; - QTest::newRow("ssl2-tls1ssl3") << QSsl::SslV2 << QSsl::TlsV1SslV3 << false; - QTest::newRow("ssl2-secure") << QSsl::SslV2 << QSsl::SecureProtocols << false; - QTest::newRow("ssl2-any") << QSsl::SslV2 << QSsl::AnyProtocol << false; // no idea why it does not work, but we don't care about SSL 2 -#endif - -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) && !defined(OPENSSL_NO_SSL3) - QTest::newRow("ssl3-ssl2") << QSsl::SslV3 << QSsl::SslV2 << false; -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("ssl3-tls1.0") << QSsl::SslV3 << QSsl::TlsV1_0 << false; - QTest::newRow("ssl3-tls1ssl3") << QSsl::SslV3 << QSsl::TlsV1SslV3 << true; - QTest::newRow("ssl3-secure") << QSsl::SslV3 << QSsl::SecureProtocols << false; -#endif -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) && !defined(OPENSSL_NO_SSL3) - QTest::newRow("ssl3-any") << QSsl::SslV3 << QSsl::AnyProtocol << false; // we won't set a SNI header here because we connect to a - // numerical IP, so OpenSSL will send a SSL 2 handshake -#elif !defined(OPENSSL_NO_SSL3) - QTest::newRow("ssl3-any") << QSsl::SslV3 << QSsl::AnyProtocol << true; -#endif - -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("tls1.0-ssl2") << QSsl::TlsV1_0 << QSsl::SslV2 << false; -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("tls1.0-ssl3") << QSsl::TlsV1_0 << QSsl::SslV3 << false; -#endif QTest::newRow("tls1-tls1ssl3") << QSsl::TlsV1_0 << QSsl::TlsV1SslV3 << true; QTest::newRow("tls1.0-secure") << QSsl::TlsV1_0 << QSsl::SecureProtocols << true; -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("tls1.0-any") << QSsl::TlsV1_0 << QSsl::AnyProtocol << false; // we won't set a SNI header here because we connect to a - // numerical IP, so OpenSSL will send a SSL 2 handshake -#else QTest::newRow("tls1.0-any") << QSsl::TlsV1_0 << QSsl::AnyProtocol << true; -#endif -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("tls1ssl3-ssl2") << QSsl::TlsV1SslV3 << QSsl::SslV2 << false; -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("tls1ssl3-ssl3") << QSsl::TlsV1SslV3 << QSsl::SslV3 << true; -#endif QTest::newRow("tls1ssl3-tls1.0") << QSsl::TlsV1SslV3 << QSsl::TlsV1_0 << true; QTest::newRow("tls1ssl3-secure") << QSsl::TlsV1SslV3 << QSsl::SecureProtocols << true; QTest::newRow("tls1ssl3-any") << QSsl::TlsV1SslV3 << QSsl::AnyProtocol << true; -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("secure-ssl2") << QSsl::SecureProtocols << QSsl::SslV2 << false; -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("secure-ssl3") << QSsl::SecureProtocols << QSsl::SslV3 << false; -#endif QTest::newRow("secure-tls1.0") << QSsl::SecureProtocols << QSsl::TlsV1_0 << true; QTest::newRow("secure-tls1ssl3") << QSsl::SecureProtocols << QSsl::TlsV1SslV3 << true; QTest::newRow("secure-any") << QSsl::SecureProtocols << QSsl::AnyProtocol << true; -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("any-ssl2") << QSsl::AnyProtocol << QSsl::SslV2 << false; // no idea why it does not work, but we don't care about SSL 2 -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("any-ssl3") << QSsl::AnyProtocol << QSsl::SslV3 << true; -#endif - -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("tls1.0orlater-ssl2") << QSsl::TlsV1_0OrLater << QSsl::SslV2 << false; -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("tls1.0orlater-ssl3") << QSsl::TlsV1_0OrLater << QSsl::SslV3 << false; -#endif QTest::newRow("tls1.0orlater-tls1.0") << QSsl::TlsV1_0OrLater << QSsl::TlsV1_0 << true; QTest::newRow("tls1.0orlater-tls1.1") << QSsl::TlsV1_0OrLater << QSsl::TlsV1_1 << true; QTest::newRow("tls1.0orlater-tls1.2") << QSsl::TlsV1_0OrLater << QSsl::TlsV1_2 << true; #ifdef TLS1_3_VERSION QTest::newRow("tls1.0orlater-tls1.3") << QSsl::TlsV1_0OrLater << QSsl::TlsV1_3 << true; #endif -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("tls1.1orlater-ssl2") << QSsl::TlsV1_1OrLater << QSsl::SslV2 << false; -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("tls1.1orlater-ssl3") << QSsl::TlsV1_1OrLater << QSsl::SslV3 << false; -#endif QTest::newRow("tls1.1orlater-tls1.0") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_0 << false; QTest::newRow("tls1.1orlater-tls1.1") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_1 << true; QTest::newRow("tls1.1orlater-tls1.2") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_2 << true; + #ifdef TLS1_3_VERSION QTest::newRow("tls1.1orlater-tls1.3") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_3 << true; #endif -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("tls1.2orlater-ssl2") << QSsl::TlsV1_2OrLater << QSsl::SslV2 << false; -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("tls1.2orlater-ssl3") << QSsl::TlsV1_2OrLater << QSsl::SslV3 << false; -#endif + QTest::newRow("tls1.2orlater-tls1.0") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_0 << false; QTest::newRow("tls1.2orlater-tls1.1") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_1 << false; QTest::newRow("tls1.2orlater-tls1.2") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_2 << true; @@ -1328,12 +1211,6 @@ void tst_QSslSocket::protocolServerSide_data() QTest::newRow("tls1.2orlater-tls1.3") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_3 << true; #endif #ifdef TLS1_3_VERSION -#if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) - QTest::newRow("tls1.3orlater-ssl2") << QSsl::TlsV1_3OrLater << QSsl::SslV2 << false; -#endif -#if !defined(OPENSSL_NO_SSL3) - QTest::newRow("tls1.3orlater-ssl3") << QSsl::TlsV1_3OrLater << QSsl::SslV3 << false; -#endif QTest::newRow("tls1.3orlater-tls1.0") << QSsl::TlsV1_3OrLater << QSsl::TlsV1_0 << false; QTest::newRow("tls1.3orlater-tls1.1") << QSsl::TlsV1_3OrLater << QSsl::TlsV1_1 << false; QTest::newRow("tls1.3orlater-tls1.2") << QSsl::TlsV1_3OrLater << QSsl::TlsV1_2 << false; @@ -4174,6 +4051,63 @@ void tst_QSslSocket::forwardReadChannelFinished() #endif // QT_NO_OPENSSL +void tst_QSslSocket::deprecatedProtocols_data() +{ + QTest::addColumn("protocol"); + QTest::addColumn("succeeds"); + QTest::newRow("SecureProtocols") << QSsl::SecureProtocols << true; + QTest::newRow("SslV2") << QSsl::SslV2 << false; + QTest::newRow("SslV3") << QSsl::SslV3 << false; +} + +void tst_QSslSocket::deprecatedProtocols() +{ + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + QSKIP("This test does not work under a proxy"); + + QFETCH(QSsl::SslProtocol, protocol); + QFETCH(bool, succeeds); + + QSslSocket socket; + socket.setProtocol(protocol); + + QSignalSpy connectedSpy(&socket, &QSslSocket::connected); + QVERIFY(connectedSpy.isValid()); + + QSignalSpy encryptedSpy(&socket, &QSslSocket::encrypted); + QVERIFY(encryptedSpy.isValid()); + + QSignalSpy errorSpy(&socket, QOverload::of(&QSslSocket::error)); + QVERIFY(errorSpy.isValid()); + + connect(&socket, QOverload &>::of(&QSslSocket::sslErrors), + &socket, QOverload<>::of(&QSslSocket::ignoreSslErrors)); + + SslServer server; + QVERIFY(server.listen()); + + socket.connectToHost(server.serverAddress(), server.serverPort()); + + // Can't use waitForConnected / waitForEncrypted as they wait forever, + // so do this asynchronously via QTRY_ macros (QTBUG-72179) + QTRY_COMPARE(connectedSpy.size(), 1); + QCOMPARE(encryptedSpy.size(), 0); + QCOMPARE(errorSpy.size(), 0); + + socket.startClientEncryption(); + + if (succeeds) { + QTRY_COMPARE(encryptedSpy.size(), 1); + QCOMPARE(errorSpy.size(), 0); + } else { + // The various backends differ in the errors fired here (QTBUG-72196), + // so just check that we did get an error (and we're not encrypted) + QTRY_VERIFY(errorSpy.size() > 0); + QCOMPARE(encryptedSpy.size(), 0); + } +} + #endif // QT_NO_SSL QTEST_MAIN(tst_QSslSocket) From fd83e03e7f634cda97ab793d67deb0e0b2377562 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Thu, 29 Nov 2018 02:33:48 +0100 Subject: [PATCH 0636/1650] OpenSSL: remove some < 1.0 codepaths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We require OpenSSL >= 1.0 now. Change-Id: I6ffe8b2dd606d600671565ebc8bc8ac2b9e0d6c2 Reviewed-by: Mårten Nordheim Reviewed-by: Timur Pocheptsov --- src/network/ssl/qsslcontext_opensslpre11.cpp | 5 +---- src/network/ssl/qsslsocket_openssl.cpp | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/network/ssl/qsslcontext_opensslpre11.cpp b/src/network/ssl/qsslcontext_opensslpre11.cpp index f952d06f75..956c5c32ec 100644 --- a/src/network/ssl/qsslcontext_opensslpre11.cpp +++ b/src/network/ssl/qsslcontext_opensslpre11.cpp @@ -199,12 +199,9 @@ init_context: long options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions); q_SSL_CTX_set_options(sslContext->ctx, options); -#if OPENSSL_VERSION_NUMBER >= 0x10000000L // Tell OpenSSL to release memory early // http://www.openssl.org/docs/ssl/SSL_CTX_set_mode.html - if (q_SSLeay() >= 0x10000000L) - q_SSL_CTX_set_mode(sslContext->ctx, SSL_MODE_RELEASE_BUFFERS); -#endif + q_SSL_CTX_set_mode(sslContext->ctx, SSL_MODE_RELEASE_BUFFERS); // Initialize ciphers QByteArray cipherString; diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 9b93915672..d684100313 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -472,7 +472,7 @@ bool QSslSocketBackendPrivate::initSslContext() if (configuration.protocol != QSsl::SslV2 && configuration.protocol != QSsl::SslV3 && configuration.protocol != QSsl::UnknownProtocol && - mode == QSslSocket::SslClientMode && QSslSocket::sslLibraryVersionNumber() >= 0x00090806fL) { + mode == QSslSocket::SslClientMode) { // Set server hostname on TLS extension. RFC4366 section 3.1 requires it in ACE format. QString tlsHostName = verificationPeerName.isEmpty() ? q->peerName() : verificationPeerName; if (tlsHostName.isEmpty()) From 588bd92228efa7ed3a92929e0eb90c22be189e04 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sun, 2 Dec 2018 14:17:21 +0100 Subject: [PATCH 0637/1650] Cleanup Widgets examples - parent ctor Cleanup the Widgets examples - add missing parent parameter Change-Id: I5cd7aa333dbb8e6e4b7b9e05c085120733da83ec Reviewed-by: Samuel Gaist Reviewed-by: Konstantin Shegunov Reviewed-by: Richard Moe Gustavsen Reviewed-by: Paul Wicking --- examples/widgets/widgets/calendarwidget/window.cpp | 3 ++- examples/widgets/widgets/calendarwidget/window.h | 2 +- examples/widgets/widgets/charactermap/mainwindow.cpp | 3 ++- examples/widgets/widgets/charactermap/mainwindow.h | 2 +- examples/widgets/widgets/icons/mainwindow.cpp | 3 ++- examples/widgets/widgets/icons/mainwindow.h | 2 +- examples/widgets/widgets/imageviewer/imageviewer.cpp | 7 +++---- examples/widgets/widgets/imageviewer/imageviewer.h | 2 +- examples/widgets/widgets/lineedits/window.cpp | 3 ++- examples/widgets/widgets/lineedits/window.h | 2 +- examples/widgets/widgets/mousebuttons/buttontester.h | 5 +++-- examples/widgets/widgets/scribble/mainwindow.cpp | 4 ++-- examples/widgets/widgets/scribble/mainwindow.h | 2 +- examples/widgets/widgets/sliders/window.cpp | 3 ++- examples/widgets/widgets/sliders/window.h | 2 +- examples/widgets/widgets/spinboxes/window.cpp | 3 ++- examples/widgets/widgets/spinboxes/window.h | 2 +- examples/widgets/widgets/stylesheet/mainwindow.cpp | 3 ++- examples/widgets/widgets/stylesheet/mainwindow.h | 2 +- examples/widgets/widgets/tetrix/tetrixwindow.cpp | 3 ++- examples/widgets/widgets/tetrix/tetrixwindow.h | 2 +- examples/widgets/widgets/tooltips/sortingbox.cpp | 3 ++- examples/widgets/widgets/tooltips/sortingbox.h | 2 +- examples/widgets/widgets/windowflags/controllerwindow.cpp | 3 ++- examples/widgets/widgets/windowflags/controllerwindow.h | 2 +- 25 files changed, 40 insertions(+), 30 deletions(-) diff --git a/examples/widgets/widgets/calendarwidget/window.cpp b/examples/widgets/widgets/calendarwidget/window.cpp index c3a0e1e3f7..a1c1746786 100644 --- a/examples/widgets/widgets/calendarwidget/window.cpp +++ b/examples/widgets/widgets/calendarwidget/window.cpp @@ -53,7 +53,8 @@ #include "window.h" //! [0] -Window::Window() +Window::Window(QWidget *parent) + : QWidget(parent) { createPreviewGroupBox(); createGeneralOptionsGroupBox(); diff --git a/examples/widgets/widgets/calendarwidget/window.h b/examples/widgets/widgets/calendarwidget/window.h index fa01fc4db6..83ea494fc2 100644 --- a/examples/widgets/widgets/calendarwidget/window.h +++ b/examples/widgets/widgets/calendarwidget/window.h @@ -70,7 +70,7 @@ class Window : public QWidget Q_OBJECT public: - Window(); + Window(QWidget *parent = nullptr); private slots: void localeChanged(int index); diff --git a/examples/widgets/widgets/charactermap/mainwindow.cpp b/examples/widgets/widgets/charactermap/mainwindow.cpp index d3ac55483c..76bd8f7799 100644 --- a/examples/widgets/widgets/charactermap/mainwindow.cpp +++ b/examples/widgets/widgets/charactermap/mainwindow.cpp @@ -57,7 +57,8 @@ Q_DECLARE_METATYPE(QFontComboBox::FontFilter) -MainWindow::MainWindow() +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) { QMenu *fileMenu = menuBar()->addMenu(tr("File")); fileMenu->addAction(tr("Quit"), this, &QWidget::close); diff --git a/examples/widgets/widgets/charactermap/mainwindow.h b/examples/widgets/widgets/charactermap/mainwindow.h index eac16b35fa..79fe9f9cc8 100644 --- a/examples/widgets/widgets/charactermap/mainwindow.h +++ b/examples/widgets/widgets/charactermap/mainwindow.h @@ -70,7 +70,7 @@ class MainWindow : public QMainWindow Q_OBJECT public: - MainWindow(); + MainWindow(QWidget *parent = nullptr); public slots: void filterChanged(int); diff --git a/examples/widgets/widgets/icons/mainwindow.cpp b/examples/widgets/widgets/icons/mainwindow.cpp index f704b8306f..904245494c 100644 --- a/examples/widgets/widgets/icons/mainwindow.cpp +++ b/examples/widgets/widgets/icons/mainwindow.cpp @@ -60,7 +60,8 @@ enum { OtherSize = QStyle::PM_CustomBase }; //! [40] //! [0] -MainWindow::MainWindow() +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) { QWidget *centralWidget = new QWidget(this); setCentralWidget(centralWidget); diff --git a/examples/widgets/widgets/icons/mainwindow.h b/examples/widgets/widgets/icons/mainwindow.h index e3888e5fb1..1949bd235c 100644 --- a/examples/widgets/widgets/icons/mainwindow.h +++ b/examples/widgets/widgets/icons/mainwindow.h @@ -74,7 +74,7 @@ class MainWindow : public QMainWindow Q_OBJECT public: - MainWindow(); + MainWindow(QWidget *parent = nullptr); void loadImages(const QStringList &fileNames); diff --git a/examples/widgets/widgets/imageviewer/imageviewer.cpp b/examples/widgets/widgets/imageviewer/imageviewer.cpp index 327abf7e43..b1346d9ccb 100644 --- a/examples/widgets/widgets/imageviewer/imageviewer.cpp +++ b/examples/widgets/widgets/imageviewer/imageviewer.cpp @@ -59,10 +59,9 @@ #include "imageviewer.h" //! [0] -ImageViewer::ImageViewer() - : imageLabel(new QLabel) - , scrollArea(new QScrollArea) - , scaleFactor(1) +ImageViewer::ImageViewer(QWidget *parent) + : QMainWindow(parent), imageLabel(new QLabel), + scrollArea(new QScrollArea), scaleFactor(1) { imageLabel->setBackgroundRole(QPalette::Base); imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); diff --git a/examples/widgets/widgets/imageviewer/imageviewer.h b/examples/widgets/widgets/imageviewer/imageviewer.h index f4a62cafe9..7e53105b33 100644 --- a/examples/widgets/widgets/imageviewer/imageviewer.h +++ b/examples/widgets/widgets/imageviewer/imageviewer.h @@ -71,7 +71,7 @@ class ImageViewer : public QMainWindow Q_OBJECT public: - ImageViewer(); + ImageViewer(QWidget *parent = nullptr); bool loadFile(const QString &); private slots: diff --git a/examples/widgets/widgets/lineedits/window.cpp b/examples/widgets/widgets/lineedits/window.cpp index ffb1edc5ce..47324589b7 100644 --- a/examples/widgets/widgets/lineedits/window.cpp +++ b/examples/widgets/widgets/lineedits/window.cpp @@ -53,7 +53,8 @@ #include "window.h" //! [0] -Window::Window() +Window::Window(QWidget *parent) + : QWidget(parent) { QGroupBox *echoGroup = new QGroupBox(tr("Echo")); diff --git a/examples/widgets/widgets/lineedits/window.h b/examples/widgets/widgets/lineedits/window.h index 2070b3b84c..3231588f4f 100644 --- a/examples/widgets/widgets/lineedits/window.h +++ b/examples/widgets/widgets/lineedits/window.h @@ -64,7 +64,7 @@ class Window : public QWidget Q_OBJECT public: - Window(); + Window(QWidget *parent = nullptr); public slots: void echoChanged(int); diff --git a/examples/widgets/widgets/mousebuttons/buttontester.h b/examples/widgets/widgets/mousebuttons/buttontester.h index d99dcceb18..231733bd44 100644 --- a/examples/widgets/widgets/mousebuttons/buttontester.h +++ b/examples/widgets/widgets/mousebuttons/buttontester.h @@ -59,13 +59,14 @@ class ButtonTester : public QTextEdit { Q_OBJECT - +public: + using QTextEdit::QTextEdit; protected: void mousePressEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; void mouseDoubleClickEvent(QMouseEvent *event) override; #if QT_CONFIG(wheelevent) - void wheelEvent(QWheelEvent * event) override; + void wheelEvent(QWheelEvent *event) override; #endif int buttonByNumber(const Qt::MouseButton button); QString enumNameFromValue(const Qt::MouseButton button); diff --git a/examples/widgets/widgets/scribble/mainwindow.cpp b/examples/widgets/widgets/scribble/mainwindow.cpp index d54e5ce0f9..b8d01d505c 100644 --- a/examples/widgets/widgets/scribble/mainwindow.cpp +++ b/examples/widgets/widgets/scribble/mainwindow.cpp @@ -54,9 +54,9 @@ #include "scribblearea.h" //! [0] -MainWindow::MainWindow() +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent), scribbleArea(new ScribbleArea(this)) { - scribbleArea = new ScribbleArea; setCentralWidget(scribbleArea); createActions(); diff --git a/examples/widgets/widgets/scribble/mainwindow.h b/examples/widgets/widgets/scribble/mainwindow.h index 9e0ddaff71..e57ff065ac 100644 --- a/examples/widgets/widgets/scribble/mainwindow.h +++ b/examples/widgets/widgets/scribble/mainwindow.h @@ -62,7 +62,7 @@ class MainWindow : public QMainWindow Q_OBJECT public: - MainWindow(); + MainWindow(QWidget *parent = nullptr); protected: void closeEvent(QCloseEvent *event) override; diff --git a/examples/widgets/widgets/sliders/window.cpp b/examples/widgets/widgets/sliders/window.cpp index 16b60dde49..16467e71be 100644 --- a/examples/widgets/widgets/sliders/window.cpp +++ b/examples/widgets/widgets/sliders/window.cpp @@ -54,7 +54,8 @@ #include "window.h" //! [0] -Window::Window() +Window::Window(QWidget *parent) + : QWidget(parent) { horizontalSliders = new SlidersGroup(Qt::Horizontal, tr("Horizontal")); verticalSliders = new SlidersGroup(Qt::Vertical, tr("Vertical")); diff --git a/examples/widgets/widgets/sliders/window.h b/examples/widgets/widgets/sliders/window.h index 9c4c14fa37..4894781ac2 100644 --- a/examples/widgets/widgets/sliders/window.h +++ b/examples/widgets/widgets/sliders/window.h @@ -69,7 +69,7 @@ class Window : public QWidget Q_OBJECT public: - Window(); + Window(QWidget *parent = nullptr); private: void createControls(const QString &title); diff --git a/examples/widgets/widgets/spinboxes/window.cpp b/examples/widgets/widgets/spinboxes/window.cpp index 54604e35aa..eb660faace 100644 --- a/examples/widgets/widgets/spinboxes/window.cpp +++ b/examples/widgets/widgets/spinboxes/window.cpp @@ -53,7 +53,8 @@ #include "window.h" //! [0] -Window::Window() +Window::Window(QWidget *parent) + : QWidget(parent) { createSpinBoxes(); createDateTimeEdits(); diff --git a/examples/widgets/widgets/spinboxes/window.h b/examples/widgets/widgets/spinboxes/window.h index 97e9ac1083..138773a5aa 100644 --- a/examples/widgets/widgets/spinboxes/window.h +++ b/examples/widgets/widgets/spinboxes/window.h @@ -67,7 +67,7 @@ class Window : public QWidget Q_OBJECT public: - Window(); + Window(QWidget *parent = nullptr); public slots: void changePrecision(int decimals); diff --git a/examples/widgets/widgets/stylesheet/mainwindow.cpp b/examples/widgets/widgets/stylesheet/mainwindow.cpp index 9acd90658a..eb4b3a2424 100644 --- a/examples/widgets/widgets/stylesheet/mainwindow.cpp +++ b/examples/widgets/widgets/stylesheet/mainwindow.cpp @@ -53,7 +53,8 @@ #include "mainwindow.h" #include "stylesheeteditor.h" -MainWindow::MainWindow() +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) { ui.setupUi(this); diff --git a/examples/widgets/widgets/stylesheet/mainwindow.h b/examples/widgets/widgets/stylesheet/mainwindow.h index 46d3ecbb93..8af4c01da0 100644 --- a/examples/widgets/widgets/stylesheet/mainwindow.h +++ b/examples/widgets/widgets/stylesheet/mainwindow.h @@ -62,7 +62,7 @@ class MainWindow : public QMainWindow Q_OBJECT public: - MainWindow(); + MainWindow(QWidget *parent = nullptr); private slots: void on_editStyleAction_triggered(); diff --git a/examples/widgets/widgets/tetrix/tetrixwindow.cpp b/examples/widgets/widgets/tetrix/tetrixwindow.cpp index 7e951aceb8..970a38c1dc 100644 --- a/examples/widgets/widgets/tetrix/tetrixwindow.cpp +++ b/examples/widgets/widgets/tetrix/tetrixwindow.cpp @@ -54,7 +54,8 @@ #include "tetrixwindow.h" //! [0] -TetrixWindow::TetrixWindow() +TetrixWindow::TetrixWindow(QWidget *parent) + : QWidget(parent) { board = new TetrixBoard; //! [0] diff --git a/examples/widgets/widgets/tetrix/tetrixwindow.h b/examples/widgets/widgets/tetrix/tetrixwindow.h index a21cef2ecf..02226ffe1c 100644 --- a/examples/widgets/widgets/tetrix/tetrixwindow.h +++ b/examples/widgets/widgets/tetrix/tetrixwindow.h @@ -67,7 +67,7 @@ class TetrixWindow : public QWidget Q_OBJECT public: - TetrixWindow(); + TetrixWindow(QWidget *parent = nullptr); private: QLabel *createLabel(const QString &text); diff --git a/examples/widgets/widgets/tooltips/sortingbox.cpp b/examples/widgets/widgets/tooltips/sortingbox.cpp index 4769a30c64..766815e8e9 100644 --- a/examples/widgets/widgets/tooltips/sortingbox.cpp +++ b/examples/widgets/widgets/tooltips/sortingbox.cpp @@ -55,7 +55,8 @@ #include "sortingbox.h" //! [0] -SortingBox::SortingBox() +SortingBox::SortingBox(QWidget *parent) + : QWidget(parent) { //! [0] //! [1] setMouseTracking(true); diff --git a/examples/widgets/widgets/tooltips/sortingbox.h b/examples/widgets/widgets/tooltips/sortingbox.h index 2ac27614a5..12bdeff1f6 100644 --- a/examples/widgets/widgets/tooltips/sortingbox.h +++ b/examples/widgets/widgets/tooltips/sortingbox.h @@ -67,7 +67,7 @@ class SortingBox : public QWidget Q_OBJECT public: - SortingBox(); + SortingBox(QWidget *parent = nullptr); protected: bool event(QEvent *event) override; diff --git a/examples/widgets/widgets/windowflags/controllerwindow.cpp b/examples/widgets/widgets/windowflags/controllerwindow.cpp index 78323810ed..c19f23c513 100644 --- a/examples/widgets/widgets/windowflags/controllerwindow.cpp +++ b/examples/widgets/widgets/windowflags/controllerwindow.cpp @@ -53,7 +53,8 @@ #include "controllerwindow.h" //! [0] -ControllerWindow::ControllerWindow() +ControllerWindow::ControllerWindow(QWidget *parent) + : QWidget(parent) { previewWindow = new PreviewWindow(this); diff --git a/examples/widgets/widgets/windowflags/controllerwindow.h b/examples/widgets/widgets/windowflags/controllerwindow.h index cfb88ed20f..43ec67e27f 100644 --- a/examples/widgets/widgets/windowflags/controllerwindow.h +++ b/examples/widgets/widgets/windowflags/controllerwindow.h @@ -69,7 +69,7 @@ class ControllerWindow : public QWidget Q_OBJECT public: - ControllerWindow(); + ControllerWindow(QWidget *parent = nullptr); private slots: void updatePreview(); From 27d3c14ab6e8865d39f85792eb26c39b76ddf102 Mon Sep 17 00:00:00 2001 From: Daniel Wingerd Date: Wed, 12 Dec 2018 14:36:49 -0500 Subject: [PATCH 0638/1650] qmake: enable rtti config option for g++/clang Fixes: QTBUG-26595 Change-Id: Ic996c8e27ef4b79c91c5afa0ad55ef0fc07b6004 Reviewed-by: Oswald Buddenhagen --- mkspecs/common/g++-win32.conf | 2 -- mkspecs/common/gcc-base.conf | 2 ++ mkspecs/features/{win32 => }/rtti.prf | 0 mkspecs/features/{win32 => }/rtti_off.prf | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename mkspecs/features/{win32 => }/rtti.prf (100%) rename mkspecs/features/{win32 => }/rtti_off.prf (100%) diff --git a/mkspecs/common/g++-win32.conf b/mkspecs/common/g++-win32.conf index f0df324b64..c3a1f3a373 100644 --- a/mkspecs/common/g++-win32.conf +++ b/mkspecs/common/g++-win32.conf @@ -31,8 +31,6 @@ QMAKE_YACCFLAGS = -d QMAKE_CFLAGS_SSE2 += -mstackrealign -QMAKE_CXXFLAGS_RTTI_ON = -frtti -QMAKE_CXXFLAGS_RTTI_OFF = -fno-rtti QMAKE_CXXFLAGS_EXCEPTIONS_ON = -fexceptions -mthreads QMAKE_INCDIR = diff --git a/mkspecs/common/gcc-base.conf b/mkspecs/common/gcc-base.conf index c2669e4833..44b4267207 100644 --- a/mkspecs/common/gcc-base.conf +++ b/mkspecs/common/gcc-base.conf @@ -68,6 +68,8 @@ QMAKE_CXXFLAGS_APP += $$QMAKE_CFLAGS_APP QMAKE_CXXFLAGS_YACC += $$QMAKE_CFLAGS_YACC QMAKE_CXXFLAGS_HIDESYMS += $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden QMAKE_CXXFLAGS_EXCEPTIONS_OFF += $$QMAKE_CFLAGS_EXCEPTIONS_OFF +QMAKE_CXXFLAGS_RTTI_ON = -frtti +QMAKE_CXXFLAGS_RTTI_OFF = -fno-rtti QMAKE_CXXFLAGS_SPLIT_SECTIONS += $$QMAKE_CFLAGS_SPLIT_SECTIONS QMAKE_CXXFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG QMAKE_CXXFLAGS_LTCG_FATOBJECTS = $$QMAKE_CFLAGS_LTCG_FATOBJECTS diff --git a/mkspecs/features/win32/rtti.prf b/mkspecs/features/rtti.prf similarity index 100% rename from mkspecs/features/win32/rtti.prf rename to mkspecs/features/rtti.prf diff --git a/mkspecs/features/win32/rtti_off.prf b/mkspecs/features/rtti_off.prf similarity index 100% rename from mkspecs/features/win32/rtti_off.prf rename to mkspecs/features/rtti_off.prf From 193d19d86e2c5408c3691b47f2bc89df124112a5 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 12 Dec 2018 21:56:28 -0800 Subject: [PATCH 0639/1650] Add "Mojave" to QSysInfo::prettyProductName() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: QTBUG-72489 Change-Id: I4ac1156702324f0fb814fffd156fcecfa95a1a2d Reviewed-by: Timur Pocheptsov Reviewed-by: Tor Arne Vestbø --- src/corelib/global/qglobal.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 88d4877be5..b17125d4ab 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -2025,6 +2025,8 @@ static const char *osVer_helper(QOperatingSystemVersion version = QOperatingSyst return "Sierra"; case 13: return "High Sierra"; + case 14: + return "Mojave"; } } // unknown, future version From 13ba85a70dbd7161b1889b5265d052c5c69cc34c Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Thu, 29 Nov 2018 15:36:34 +0100 Subject: [PATCH 0640/1650] OpenSSL: remove some more pre-1.0 fallbacks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Again, 1.0 is required now. Change-Id: Icca5dc38eb33c1579653d96d6c079b335a401aad Reviewed-by: Mårten Nordheim Reviewed-by: Timur Pocheptsov --- .../ssl/qsslsocket_openssl_symbols.cpp | 31 ------------------- .../ssl/qsslsocket_openssl_symbols_p.h | 12 ------- .../ssl/qsslsocket_opensslpre11_symbols_p.h | 22 ------------- 3 files changed, 65 deletions(-) diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index 953b01d01a..aa1dc681e0 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -265,17 +265,10 @@ DEFINEFUNC6(void *, PEM_ASN1_write_bio, d2i_of_void *a, a, const char *b, b, BIO DEFINEFUNC(int, sk_num, STACK *a, a, return -1, return) DEFINEFUNC2(void, sk_pop_free, STACK *a, a, void (*b)(void*), b, return, DUMMYARG) -#if OPENSSL_VERSION_NUMBER >= 0x10000000L DEFINEFUNC(_STACK *, sk_new_null, DUMMYARG, DUMMYARG, return nullptr, return) DEFINEFUNC2(void, sk_push, _STACK *a, a, void *b, b, return, DUMMYARG) DEFINEFUNC(void, sk_free, _STACK *a, a, return, DUMMYARG) DEFINEFUNC2(void *, sk_value, STACK *a, a, int b, b, return nullptr, return) -#else -DEFINEFUNC(STACK *, sk_new_null, DUMMYARG, DUMMYARG, return nullptr, return) -DEFINEFUNC2(void, sk_push, STACK *a, a, char *b, b, return, DUMMYARG) -DEFINEFUNC(void, sk_free, STACK *a, a, return, DUMMYARG) -DEFINEFUNC2(char *, sk_value, STACK *a, a, int b, b, return nullptr, return) -#endif // OPENSSL_VERSION_NUMBER >= 0x10000000L DEFINEFUNC(int, SSL_library_init, void, DUMMYARG, return -1, return) DEFINEFUNC(void, SSL_load_error_strings, void, DUMMYARG, return, DUMMYARG) @@ -284,7 +277,6 @@ DEFINEFUNC(void, SSL_load_error_strings, void, DUMMYARG, return, DUMMYARG) DEFINEFUNC5(int, SSL_get_ex_new_index, long argl, argl, void *argp, argp, CRYPTO_EX_new *new_func, new_func, CRYPTO_EX_dup *dup_func, dup_func, CRYPTO_EX_free *free_func, free_func, return -1, return) #endif // OPENSSL_VERSION_NUMBER >= 0x10001000L -#if OPENSSL_VERSION_NUMBER >= 0x10000000L DEFINEFUNC(const SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return nullptr, return) DEFINEFUNC(const SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return nullptr, return) #if OPENSSL_VERSION_NUMBER >= 0x10001000L @@ -297,12 +289,6 @@ DEFINEFUNC(const SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return n DEFINEFUNC(const SSL_METHOD *, TLSv1_1_server_method, DUMMYARG, DUMMYARG, return nullptr, return) DEFINEFUNC(const SSL_METHOD *, TLSv1_2_server_method, DUMMYARG, DUMMYARG, return nullptr, return) #endif -#else -DEFINEFUNC(SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return nullptr, return) -DEFINEFUNC(SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return nullptr, return) -DEFINEFUNC(SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return nullptr, return) -DEFINEFUNC(SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return nullptr, return) -#endif DEFINEFUNC(STACK_OF(X509) *, X509_STORE_CTX_get_chain, X509_STORE_CTX *a, a, return nullptr, return) @@ -440,11 +426,7 @@ DEFINEFUNC(int, SSL_connect, SSL *a, a, return -1, return) DEFINEFUNC(int, SSL_CTX_check_private_key, const SSL_CTX *a, a, return -1, return) DEFINEFUNC4(long, SSL_CTX_ctrl, SSL_CTX *a, a, int b, b, long c, c, void *d, d, return -1, return) DEFINEFUNC(void, SSL_CTX_free, SSL_CTX *a, a, return, DUMMYARG) -#if OPENSSL_VERSION_NUMBER >= 0x10000000L DEFINEFUNC(SSL_CTX *, SSL_CTX_new, const SSL_METHOD *a, a, return nullptr, return) -#else -DEFINEFUNC(SSL_CTX *, SSL_CTX_new, SSL_METHOD *a, a, return nullptr, return) -#endif DEFINEFUNC2(int, SSL_CTX_set_cipher_list, SSL_CTX *a, a, const char *b, b, return -1, return) DEFINEFUNC3(long, SSL_CTX_callback_ctrl, SSL_CTX *ctx, ctx, int dst, dst, GenericCallbackType cb, cb, return 0, return) DEFINEFUNC(int, SSL_CTX_set_default_verify_paths, SSL_CTX *a, a, return -1, return) @@ -466,21 +448,12 @@ DEFINEFUNC3(int, SSL_CONF_cmd, SSL_CONF_CTX *a, a, const char *b, b, const char #endif DEFINEFUNC(void, SSL_free, SSL *a, a, return, DUMMYARG) DEFINEFUNC(STACK_OF(SSL_CIPHER) *, SSL_get_ciphers, const SSL *a, a, return nullptr, return) -#if OPENSSL_VERSION_NUMBER >= 0x10000000L DEFINEFUNC(const SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return nullptr, return) -#else -DEFINEFUNC(SSL_CIPHER *, SSL_get_current_cipher, SSL *a, a, return nullptr, return) -#endif DEFINEFUNC(int, SSL_version, const SSL *a, a, return 0, return) DEFINEFUNC2(int, SSL_get_error, SSL *a, a, int b, b, return -1, return) DEFINEFUNC(STACK_OF(X509) *, SSL_get_peer_cert_chain, SSL *a, a, return nullptr, return) DEFINEFUNC(X509 *, SSL_get_peer_certificate, SSL *a, a, return nullptr, return) -#if OPENSSL_VERSION_NUMBER >= 0x00908000L -// 0.9.8 broke SC and BC by changing this function's signature. DEFINEFUNC(long, SSL_get_verify_result, const SSL *a, a, return -1, return) -#else -DEFINEFUNC(long, SSL_get_verify_result, SSL *a, a, return -1, return) -#endif DEFINEFUNC(SSL *, SSL_new, SSL_CTX *a, a, return nullptr, return) DEFINEFUNC(SSL_CTX *, SSL_get_SSL_CTX, SSL *a, a, return nullptr, return) DEFINEFUNC4(long, SSL_ctrl, SSL *a, a, int cmd, cmd, long larg, larg, void *parg, parg, return -1, return) @@ -525,11 +498,7 @@ DEFINEFUNC(ASN1_OCTET_STRING *, X509_EXTENSION_get_data, X509_EXTENSION *a, a, r DEFINEFUNC(void, BASIC_CONSTRAINTS_free, BASIC_CONSTRAINTS *a, a, return, DUMMYARG) DEFINEFUNC(void, AUTHORITY_KEYID_free, AUTHORITY_KEYID *a, a, return, DUMMYARG) DEFINEFUNC(void, GENERAL_NAME_free, GENERAL_NAME *a, a, return, DUMMYARG) -#if OPENSSL_VERSION_NUMBER >= 0x10000000L DEFINEFUNC2(int, ASN1_STRING_print, BIO *a, a, const ASN1_STRING *b, b, return 0, return) -#else -DEFINEFUNC2(int, ASN1_STRING_print, BIO *a, a, ASN1_STRING *b, b, return 0, return) -#endif DEFINEFUNC2(int, X509_check_issued, X509 *a, a, X509 *b, b, return -1, return) DEFINEFUNC(X509_NAME *, X509_get_issuer_name, X509 *a, a, return nullptr, return) DEFINEFUNC(X509_NAME *, X509_get_subject_name, X509 *a, a, return nullptr, return) diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h index 27e317ab1f..cf426e2ed2 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols_p.h +++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h @@ -357,11 +357,7 @@ int q_SSL_connect(SSL *a); int q_SSL_CTX_check_private_key(const SSL_CTX *a); long q_SSL_CTX_ctrl(SSL_CTX *a, int b, long c, void *d); void q_SSL_CTX_free(SSL_CTX *a); -#if OPENSSL_VERSION_NUMBER >= 0x10000000L SSL_CTX *q_SSL_CTX_new(const SSL_METHOD *a); -#else -SSL_CTX *q_SSL_CTX_new(SSL_METHOD *a); -#endif int q_SSL_CTX_set_cipher_list(SSL_CTX *a, const char *b); int q_SSL_CTX_set_default_verify_paths(SSL_CTX *a); void q_SSL_CTX_set_verify(SSL_CTX *a, int b, int (*c)(int, X509_STORE_CTX *)); @@ -386,11 +382,7 @@ int q_SSL_CONF_cmd(SSL_CONF_CTX *a, const char *b, const char *c); #endif void q_SSL_free(SSL *a); STACK_OF(SSL_CIPHER) *q_SSL_get_ciphers(const SSL *a); -#if OPENSSL_VERSION_NUMBER >= 0x10000000L const SSL_CIPHER *q_SSL_get_current_cipher(SSL *a); -#else -SSL_CIPHER *q_SSL_get_current_cipher(SSL *a); -#endif int q_SSL_version(const SSL *a); int q_SSL_get_error(SSL *a, int b); STACK_OF(X509) *q_SSL_get_peer_cert_chain(SSL *a); @@ -444,11 +436,7 @@ int q_X509_EXTENSION_get_critical(X509_EXTENSION *a); ASN1_OCTET_STRING *q_X509_EXTENSION_get_data(X509_EXTENSION *a); void q_BASIC_CONSTRAINTS_free(BASIC_CONSTRAINTS *a); void q_AUTHORITY_KEYID_free(AUTHORITY_KEYID *a); -#if OPENSSL_VERSION_NUMBER >= 0x10000000L int q_ASN1_STRING_print(BIO *a, const ASN1_STRING *b); -#else -int q_ASN1_STRING_print(BIO *a, ASN1_STRING *b); -#endif int q_X509_check_issued(X509 *a, X509 *b); X509_NAME *q_X509_get_issuer_name(X509 *a); X509_NAME *q_X509_get_subject_name(X509 *a); diff --git a/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h b/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h index abfa2e7004..46b6505346 100644 --- a/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h +++ b/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h @@ -89,9 +89,7 @@ void q_ERR_free_strings(); void q_EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a); void q_EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a); -#if OPENSSL_VERSION_NUMBER >= 0x10000000L typedef _STACK STACK; -#endif // The typedef we use to make our pre 1.1 code look more like 1.1 (less ifdefs). typedef STACK OPENSSL_STACK; @@ -111,22 +109,13 @@ void q_sk_free(STACK *a); // address of this: #define q_OPENSSL_sk_free q_sk_free -#if OPENSSL_VERSION_NUMBER >= 0x10000000L void *q_sk_value(STACK *a, int b); void q_sk_push(STACK *st, void *data); -#else -char *q_sk_value(STACK *a, int b); -void q_sk_push(STACK *st, char *data); -#endif // OPENSSL_VERSION_NUMBER >= 0x10000000L #define q_OPENSSL_sk_value(a, b) q_sk_value(a, b) #define q_OPENSSL_sk_push(st, data) q_sk_push(st, data) -#if OPENSSL_VERSION_NUMBER >= 0x10000000L SSL_CTX *q_SSL_CTX_new(const SSL_METHOD *a); -#else -SSL_CTX *q_SSL_CTX_new(SSL_METHOD *a); -#endif int q_SSL_library_init(); void q_SSL_load_error_strings(); @@ -135,7 +124,6 @@ void q_SSL_load_error_strings(); int q_SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); #endif -#if OPENSSL_VERSION_NUMBER >= 0x10000000L const SSL_METHOD *q_SSLv23_client_method(); const SSL_METHOD *q_TLSv1_client_method(); const SSL_METHOD *q_TLSv1_1_client_method(); @@ -144,16 +132,6 @@ const SSL_METHOD *q_SSLv23_server_method(); const SSL_METHOD *q_TLSv1_server_method(); const SSL_METHOD *q_TLSv1_1_server_method(); const SSL_METHOD *q_TLSv1_2_server_method(); -#else -SSL_METHOD *q_SSLv23_client_method(); -SSL_METHOD *q_TLSv1_client_method(); -SSL_METHOD *q_TLSv1_1_client_method(); -SSL_METHOD *q_TLSv1_2_client_method(); -SSL_METHOD *q_SSLv23_server_method(); -SSL_METHOD *q_TLSv1_server_method(); -SSL_METHOD *q_TLSv1_1_server_method(); -SSL_METHOD *q_TLSv1_2_server_method(); -#endif STACK_OF(X509) *q_X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx); From 43720ec2003339918c51cddeee38c2b10ed27ddf Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 10 Dec 2018 14:58:18 +0100 Subject: [PATCH 0641/1650] Deprecate QObject::findChildren(const QRegExp &, ...) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the overload using QRegularExpression instead. Change-Id: I1bf468b248c0a3f5b2304b1831379a127093df06 Reviewed-by: Jędrzej Nowacki --- src/corelib/kernel/qobject.cpp | 3 +++ src/corelib/kernel/qobject.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index d2a3d957e9..36c108b697 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -1820,12 +1820,15 @@ void QObject::killTimer(int id) /*! \fn template QList QObject::findChildren(const QRegExp ®Exp, Qt::FindChildOptions options) const \overload findChildren() + \obsolete Returns the children of this object that can be cast to type T and that have names matching the regular expression \a regExp, or an empty list if there are no such objects. The search is performed recursively, unless \a options specifies the option FindDirectChildrenOnly. + + Use the findChildren overload taking a QRegularExpression instead. */ /*! diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index 9ae6155f52..52c1b8e555 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -176,7 +176,9 @@ public: } #ifndef QT_NO_REGEXP +#if QT_DEPRECATED_SINCE(5, 13) template + QT_DEPRECATED_X("Use findChildren(const RegularExpression &, ...) instead.") inline QList findChildren(const QRegExp &re, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const { typedef typename std::remove_cv::type>::type ObjType; @@ -186,6 +188,7 @@ public: return list; } #endif +#endif #if QT_CONFIG(regularexpression) template From 88d5eb13d7a996772f38e9c9ab90befb3ae0c80d Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 10 Dec 2018 15:03:51 +0100 Subject: [PATCH 0642/1650] Use QRegularExpression instead of QRegExp Change-Id: I14abbf81a9d0fb72f75417da06b6456b8f1a20a2 Reviewed-by: Samuel Gaist --- src/corelib/mimetypes/qmimeglobpattern.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/mimetypes/qmimeglobpattern.cpp b/src/corelib/mimetypes/qmimeglobpattern.cpp index cd42b4da83..fd06f6ab6b 100644 --- a/src/corelib/mimetypes/qmimeglobpattern.cpp +++ b/src/corelib/mimetypes/qmimeglobpattern.cpp @@ -39,7 +39,7 @@ #include "qmimeglobpattern_p.h" -#include +#include #include #include @@ -142,8 +142,8 @@ bool QMimeGlobPattern::matchFileName(const QString &inputFilename) const return (m_pattern == filename); // Other (quite rare) patterns, like "*.anim[1-9j]": use slow but correct method - QRegExp rx(m_pattern, Qt::CaseSensitive, QRegExp::WildcardUnix); - return rx.exactMatch(filename); + QRegularExpression rx(QRegularExpression::anchoredPattern(QRegularExpression::wildcardToRegularExpression(m_pattern))); + return rx.match(filename).hasMatch(); } static bool isFastPattern(const QString &pattern) From d545d36c8e11dcd974244a69d2beef726be9ed9d Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 12 Dec 2018 15:00:43 +0100 Subject: [PATCH 0643/1650] Remove QRegExp dependency from QtXml Use QRegularExpression instead. Change-Id: I6fc9400064ef6b7e425b140f5ffac0c9248c1ec0 Reviewed-by: Samuel Gaist --- src/xml/dom/qdom.cpp | 14 ++++++++------ src/xml/sax/qxml.cpp | 14 ++++++++++---- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp index 5893d8448e..a1f4d57da6 100644 --- a/src/xml/dom/qdom.cpp +++ b/src/xml/dom/qdom.cpp @@ -48,7 +48,9 @@ #include #include #include -#include +#if QT_CONFIG(regularexpression) +#include +#endif #if QT_CONFIG(textcodec) #include #endif @@ -6430,7 +6432,7 @@ void QDomDocumentPrivate::saveDocument(QTextStream& s, const int indent, QDomNod const QDomNodePrivate* n = first; if(encUsed == QDomNode::EncodingFromDocument) { -#if QT_CONFIG(textcodec) +#if QT_CONFIG(textcodec) && QT_CONFIG(regularexpression) const QDomNodePrivate* n = first; QTextCodec *codec = 0; @@ -6438,11 +6440,11 @@ void QDomDocumentPrivate::saveDocument(QTextStream& s, const int indent, QDomNod if (n && n->isProcessingInstruction() && n->nodeName() == QLatin1String("xml")) { // we have an XML declaration QString data = n->nodeValue(); - QRegExp encoding(QString::fromLatin1("encoding\\s*=\\s*((\"([^\"]*)\")|('([^']*)'))")); - encoding.indexIn(data); - QString enc = encoding.cap(3); + QRegularExpression encoding(QString::fromLatin1("encoding\\s*=\\s*((\"([^\"]*)\")|('([^']*)'))")); + auto match = encoding.match(data); + QString enc = match.captured(3); if (enc.isEmpty()) - enc = encoding.cap(5); + enc = match.captured(5); if (!enc.isEmpty()) codec = QTextCodec::codecForName(std::move(enc).toLatin1()); } diff --git a/src/xml/sax/qxml.cpp b/src/xml/sax/qxml.cpp index 7b6669b057..fa31e71cc1 100644 --- a/src/xml/sax/qxml.cpp +++ b/src/xml/sax/qxml.cpp @@ -43,7 +43,9 @@ #include "qtextcodec.h" #endif #include "qbuffer.h" -#include "qregexp.h" +#if QT_CONFIG(regularexpression) +#include "qregularexpression.h" +#endif #include "qmap.h" #include "qhash.h" #include "qstack.h" @@ -193,19 +195,23 @@ static const signed char charLookupTable[256]={ */ static bool stripTextDecl(QString& str) { - QString textDeclStart(QLatin1String("" - )); + )); QString strTmp = str.replace(textDecl, QLatin1String("")); if (strTmp.length() != str.length()) return false; // external entity has wrong TextDecl str = strTmp; +#else + return false; +#endif } return true; } From 81dd1bcad1d43350300c62466e3d9e56c2118148 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Mon, 10 Dec 2018 15:30:10 +0100 Subject: [PATCH 0644/1650] QSslSocket Doc: Don't refer to obsoleted functions Update references in documentation from the obsoleted/deprecated version because it doesn't make sense here to refer to these versions. Change-Id: I5e9bdf46191e3ba0c7d91855cb3ccc30097cd412 Reviewed-by: Timur Pocheptsov Reviewed-by: Edward Welbourne --- src/network/ssl/qsslsocket.cpp | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 8b7d48be15..068dfb9f2d 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -133,7 +133,8 @@ \list \li The socket's cryptographic cipher suite can be customized before - the handshake phase with setCiphers() and setDefaultCiphers(). + the handshake phase with QSslConfiguration::setCiphers() + and QSslConfiguration::setDefaultCiphers(). \li The socket's local certificate and private key can be customized before the handshake phase with setLocalCertificate() and setPrivateKey(). @@ -906,7 +907,8 @@ void QSslSocket::abort() time without notice. \sa localCertificate(), peerCertificate(), peerCertificateChain(), - sessionCipher(), privateKey(), ciphers(), caCertificates() + sessionCipher(), privateKey(), QSslConfiguration::ciphers(), + QSslConfiguration::caCertificates() */ QSslConfiguration QSslSocket::sslConfiguration() const { @@ -930,7 +932,8 @@ QSslConfiguration QSslSocket::sslConfiguration() const It is not possible to set the SSL-state related fields. - \sa setLocalCertificate(), setPrivateKey(), setCaCertificates(), setCiphers() + \sa setLocalCertificate(), setPrivateKey(), QSslConfiguration::setCaCertificates(), + QSslConfiguration::setCiphers() */ void QSslSocket::setSslConfiguration(const QSslConfiguration &configuration) { @@ -1116,8 +1119,10 @@ QList QSslSocket::peerCertificateChain() const session cipher. This ordered list must be in place before the handshake phase begins. - \sa ciphers(), setCiphers(), setDefaultCiphers(), defaultCiphers(), - supportedCiphers() + \sa QSslConfiguration::ciphers(), QSslConfiguration::setCiphers(), + QSslConfiguration::setDefaultCiphers(), + QSslConfiguration::defaultCiphers(), + QSslConfiguration::supportedCiphers() */ QSslCipher QSslSocket::sessionCipher() const { @@ -1379,7 +1384,8 @@ bool QSslSocket::addCaCertificates(const QString &path, QSsl::EncodingFormat for To add multiple certificates, use addCaCertificates(). - \sa caCertificates(), setCaCertificates() + \sa QSslConfiguration::caCertificates(), + QSslConfiguration::setCaCertificates() */ void QSslSocket::addCaCertificate(const QSslCertificate &certificate) { @@ -1394,7 +1400,7 @@ void QSslSocket::addCaCertificate(const QSslCertificate &certificate) For more precise control, use addCaCertificate(). - \sa caCertificates(), addDefaultCaCertificate() + \sa QSslConfiguration::caCertificates(), addDefaultCaCertificate() */ void QSslSocket::addCaCertificates(const QList &certificates) { @@ -1457,7 +1463,8 @@ QList QSslSocket::caCertificates() const Each SSL socket's CA certificate database is initialized to the default CA certificate database. - \sa defaultCaCertificates(), addCaCertificates(), addDefaultCaCertificate() + \sa QSslConfiguration::defaultCaCertificates(), addCaCertificates(), + addDefaultCaCertificate() */ bool QSslSocket::addDefaultCaCertificates(const QString &path, QSsl::EncodingFormat encoding, QRegExp::PatternSyntax syntax) @@ -1470,7 +1477,7 @@ bool QSslSocket::addDefaultCaCertificates(const QString &path, QSsl::EncodingFor SSL socket's CA certificate database is initialized to the default CA certificate database. - \sa defaultCaCertificates(), addCaCertificates() + \sa QSslConfiguration::defaultCaCertificates(), addCaCertificates() */ void QSslSocket::addDefaultCaCertificate(const QSslCertificate &certificate) { @@ -1482,7 +1489,7 @@ void QSslSocket::addDefaultCaCertificate(const QSslCertificate &certificate) SSL socket's CA certificate database is initialized to the default CA certificate database. - \sa defaultCaCertificates(), addCaCertificates() + \sa QSslConfiguration::defaultCaCertificates(), addCaCertificates() */ void QSslSocket::addDefaultCaCertificates(const QList &certificates) { From 1ffcca4cc208c48ddb06b6a23abf1756f9724351 Mon Sep 17 00:00:00 2001 From: "Bernhard M. Wiedemann" Date: Wed, 11 Jul 2018 10:05:55 +0200 Subject: [PATCH 0645/1650] rcc: Use SOURCE_DATE_EPOCH for mtime Use the standard variable name in addition to the QT-specific one to make builds reproducible out-of-the-box. See https://reproducible-builds.org/ for why this is good and https://reproducible-builds.org/specs/source-date-epoch/ for the definition of this variable. Task-number: QTBUG-62511 Change-Id: I401a2a9d258e751b83ae7b83f4100d9088b9ad71 Reviewed-by: Tobias Hunger Reviewed-by: Lars Knoll --- src/tools/rcc/rcc.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp index f284749781..a7919e31f9 100644 --- a/src/tools/rcc/rcc.cpp +++ b/src/tools/rcc/rcc.cpp @@ -230,6 +230,9 @@ void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib) static const quint64 sourceDate = 1000 * qgetenv("QT_RCC_SOURCE_DATE_OVERRIDE").toULongLong(); if (sourceDate != 0) lastmod = sourceDate; + static const quint64 sourceDate2 = 1000 * qgetenv("SOURCE_DATE_EPOCH").toULongLong(); + if (sourceDate2 != 0) + lastmod = sourceDate2; lib.writeNumber8(lastmod); if (text || pass1) lib.writeChar('\n'); From d9004632839a8cdb36f9bc82b7a7a3ad7d64d419 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Fri, 14 Dec 2018 10:56:30 +0100 Subject: [PATCH 0646/1650] Doc: Fix linking from Qt Test to Qt Quick Test Change-Id: I5552fde06f7cc383e1b16cd90ca9fe7cfeb3a436 Reviewed-by: Mitch Curtis --- src/testlib/doc/qttestlib.qdocconf | 2 +- src/testlib/doc/src/qttest-index.qdoc | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/testlib/doc/qttestlib.qdocconf b/src/testlib/doc/qttestlib.qdocconf index 1fdb136e78..6d5d3442a3 100644 --- a/src/testlib/doc/qttestlib.qdocconf +++ b/src/testlib/doc/qttestlib.qdocconf @@ -27,7 +27,7 @@ qhp.QtTestLib.subprojects.classes.sortPages = true tagfile = ../../../doc/qttestlib/qttestlib.tags -depends += qtcore qtdoc qtwidgets qtgui qmake qtquick +depends += qtcore qtdoc qtwidgets qtgui qmake qtqmltest headerdirs += .. diff --git a/src/testlib/doc/src/qttest-index.qdoc b/src/testlib/doc/src/qttest-index.qdoc index 6e4f954034..23be46b431 100644 --- a/src/testlib/doc/src/qttest-index.qdoc +++ b/src/testlib/doc/src/qttest-index.qdoc @@ -75,11 +75,15 @@ \section1 Reference - These are links to the API reference materials. + \list + \li \l{Qt Test C++ Classes} + \endlist + + The \l {Qt Quick Test} module enables unit testing Qt Quick applications. \list - \li \l{Qt Test C++ Classes}{C++ Classes} - \li \l{Qt Quick Test QML Types}{QML Types} + \li \l{Qt Quick Test QML Types} + \li \l{Qt Quick Test C++ API} \endlist */ From 9d76beee5be0812fdc8bd53c3145de95b45ab6a6 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 14 Dec 2018 14:18:39 +0100 Subject: [PATCH 0647/1650] qmake: don't mess up linking order of libraries ... which are specified by full filepath, by making the de-duplication consistent with that applied to libs specified with -l, that is, last one wins. the problem existed "forever", but it became more visible after the recent configure changes. fwiw, Win32MakefileGenerator is not affected, because it has the opposite problem: it de-duplicates everything (including object files) in "last one wins mode". it might make sense to change that as well. Change-Id: Id7ef1d394fcc9d444450672c06a6f11af2b19eab Reviewed-by: Robert Griebl --- qmake/generators/unix/unixmake.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp index 50ec8db79e..4cbe06d9dc 100644 --- a/qmake/generators/unix/unixmake.cpp +++ b/qmake/generators/unix/unixmake.cpp @@ -399,6 +399,8 @@ UnixMakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags) libdirs.append(QMakeLocalFileName(dlib.toQString())); frameworkdirs.append(QMakeLocalFileName("/System/Library/Frameworks")); frameworkdirs.append(QMakeLocalFileName("/Library/Frameworks")); + ProStringList extens; + extens << project->first("QMAKE_EXTENSION_SHLIB") << "a"; static const char * const lflags[] = { "LIBS", "LIBS_PRIVATE", "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", nullptr }; for (int i = 0; lflags[i]; i++) { @@ -417,8 +419,6 @@ UnixMakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags) libdirs.insert(libidx++, f); } else if(opt.startsWith("-l")) { QString lib = opt.mid(2); - ProStringList extens; - extens << project->first("QMAKE_EXTENSION_SHLIB") << "a"; for (QList::Iterator dep_it = libdirs.begin(); dep_it != libdirs.end(); ++dep_it) { QString libBase = (*dep_it).local() + '/' @@ -521,8 +521,18 @@ UnixMakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags) lflags[arch].append(opt); } } else if(!opt.isNull()) { + for (const ProString &ext : extens) { + if (opt.size() > ext.size() && opt.endsWith(ext) + && opt.at(opt.size() - ext.size() - 1) == '.') { + // Make sure we keep the dependency order of libraries + lflags[arch].removeAll(opt); + lflags[arch].append(opt); + goto found2; + } + } if(!lflags[arch].contains(opt)) lflags[arch].append(opt); + found2: ; } } From 74cdd89e0fd437ef4c4041f04c9aa522f2371615 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 13 Dec 2018 16:20:40 +0100 Subject: [PATCH 0648/1650] qmake: don't assign fallbacks for QMAKE_DEFAULT_{INC,LIB}DIRS in x-builds these cannot be possibly correct, and might mislead. Change-Id: Ie10531807978def04768e2429304949415cafb2a Reviewed-by: Joerg Bornemann --- mkspecs/features/toolchain.prf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/toolchain.prf b/mkspecs/features/toolchain.prf index 55295f271f..e8c3f81c8b 100644 --- a/mkspecs/features/toolchain.prf +++ b/mkspecs/features/toolchain.prf @@ -178,7 +178,7 @@ isEmpty($${target_prefix}.INCDIRS) { QMAKE_DEFAULT_INCDIRS = $$split(INCLUDE, $$QMAKE_DIRLIST_SEP) } - unix { + unix:if(!cross_compile|host_build) { isEmpty(QMAKE_DEFAULT_INCDIRS): QMAKE_DEFAULT_INCDIRS = /usr/include /usr/local/include isEmpty(QMAKE_DEFAULT_LIBDIRS): QMAKE_DEFAULT_LIBDIRS = /lib /usr/lib } From 852b1afa5658d410a270a09ee7b94572df52ccbe Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 13 Dec 2018 17:53:38 +0100 Subject: [PATCH 0649/1650] qmake: don't misuse cache() ... when QMAKE_DEFAULT_{INC,LIB}DIRS cannot be determined. it would have been nicer to actually persist empty results, but cache() won't do that, and fixing it doesn't seem worth the effort now. Change-Id: I95d5645e40a0da572f0def16462703373eaeb804 Reviewed-by: Joerg Bornemann --- mkspecs/features/toolchain.prf | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/toolchain.prf b/mkspecs/features/toolchain.prf index e8c3f81c8b..63f2f12e21 100644 --- a/mkspecs/features/toolchain.prf +++ b/mkspecs/features/toolchain.prf @@ -183,8 +183,11 @@ isEmpty($${target_prefix}.INCDIRS) { isEmpty(QMAKE_DEFAULT_LIBDIRS): QMAKE_DEFAULT_LIBDIRS = /lib /usr/lib } - cache($${target_prefix}.INCDIRS, set stash, QMAKE_DEFAULT_INCDIRS) - cache($${target_prefix}.LIBDIRS, set stash, QMAKE_DEFAULT_LIBDIRS) + # cache() complains about undefined variables and doesn't persist empty ones. + !isEmpty(QMAKE_DEFAULT_INCDIRS): \ + cache($${target_prefix}.INCDIRS, set stash, QMAKE_DEFAULT_INCDIRS) + !isEmpty(QMAKE_DEFAULT_LIBDIRS): \ + cache($${target_prefix}.LIBDIRS, set stash, QMAKE_DEFAULT_LIBDIRS) } else { QMAKE_DEFAULT_INCDIRS = $$eval($${target_prefix}.INCDIRS) QMAKE_DEFAULT_LIBDIRS = $$eval($${target_prefix}.LIBDIRS) From a8cb177d31d45a8cfee16b2c82131d1474d1d2e5 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 11 Dec 2018 15:02:16 +0100 Subject: [PATCH 0650/1650] Fix build with win32-clang-msvc and win32-icc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fbbe8aba9d70a3c13d1cd7797eb4dbbd1f05ade5 introduced a check for MSVC_VER to qmake, which is not set in win32-clang-msvc, causing the build to fail: Mkspec does not specify MSVC_VER. Cannot continue. Unable to generate output for: .../config.tests/verifyspec/Makefile Extract a minimal msvc-based-version.conf which determines MSVC_VER from QMAKE_MSC_VER for win32-clang-msvc and win32-icc. Task-number: QTBUG-63512 Change-Id: Ia6de8c4b1aae2ae1962cf4e60e3e6d51fdbbbabe Reviewed-by: Mårten Nordheim Reviewed-by: Thiago Macieira Reviewed-by: Oswald Buddenhagen --- mkspecs/common/msvc-based-version.conf | 32 ++++++++++++++++++++++++++ mkspecs/common/msvc-version.conf | 10 +++----- mkspecs/features/toolchain.prf | 6 ++++- 3 files changed, 40 insertions(+), 8 deletions(-) create mode 100644 mkspecs/common/msvc-based-version.conf diff --git a/mkspecs/common/msvc-based-version.conf b/mkspecs/common/msvc-based-version.conf new file mode 100644 index 0000000000..38aecbaf59 --- /dev/null +++ b/mkspecs/common/msvc-based-version.conf @@ -0,0 +1,32 @@ +# +# qmake configuration for Compilers based on the Microsoft Visual Studio +# C/C++ Compilers like win32-clang-msvc + +# +# Version-specific changes +# + +isEmpty(QMAKE_MSC_VER): error("msvc-based-version.conf loaded but QMAKE_MSC_VER isn't set") + +MSVC_VER = 14.0 +COMPAT_MKSPEC = win32-msvc2015 + +# -utf-8 compiler option for Visual Studio 2015 Update 2 +greaterThan(QMAKE_MSC_FULL_VER, 190023918):!intel_icl { + isEmpty(QT_CLANG_MAJOR_VERSION)|!lessThan(QT_CLANG_MAJOR_VERSION, 4) { + QMAKE_CFLAGS_UTF8_SOURCE = -utf-8 + } +} + +greaterThan(QMAKE_MSC_VER, 1909) { + # Visual Studio 2017 (15.0) / Visual C++ 19.10 and up + MSVC_VER = 15.0 + COMPAT_MKSPEC = win32-msvc2017 +} + +greaterThan(QMAKE_MSC_VER, 1910) { + # No compat spec past MSVC 2017 + COMPAT_MKSPEC = +} + +!isEmpty(COMPAT_MKSPEC):!$$COMPAT_MKSPEC: CONFIG += $$COMPAT_MKSPEC diff --git a/mkspecs/common/msvc-version.conf b/mkspecs/common/msvc-version.conf index 3fb55c9d81..de8ba56b7b 100644 --- a/mkspecs/common/msvc-version.conf +++ b/mkspecs/common/msvc-version.conf @@ -1,7 +1,6 @@ # # qmake configuration for Microsoft Visual Studio C/C++ Compiler -# This file is used by win32-msvc, win32-clang-msvc, and all -# winrt-XXX-msvcXXX specs +# This file is used by win32-msvc and all winrt-XXX-msvcXXX specs # # @@ -70,11 +69,8 @@ greaterThan(QMAKE_MSC_VER, 1899) { QMAKE_CXXFLAGS += -Zc:strictStrings -Zc:throwingNew QMAKE_CXXFLAGS_WARN_ON += -w44456 -w44457 -w44458 -wd4577 -wd4467 - greaterThan(QMAKE_MSC_FULL_VER, 190023918):!intel_icl { - isEmpty(QT_CLANG_MAJOR_VERSION)|!lessThan(QT_CLANG_MAJOR_VERSION, 4) { - QMAKE_CFLAGS_UTF8_SOURCE = -utf-8 - } - } + # -utf-8 compiler option for Visual Studio 2015 Update 2 + greaterThan(QMAKE_MSC_FULL_VER, 190023918): QMAKE_CFLAGS_UTF8_SOURCE = -utf-8 } greaterThan(QMAKE_MSC_VER, 1909) { diff --git a/mkspecs/features/toolchain.prf b/mkspecs/features/toolchain.prf index 63f2f12e21..c7ea20e180 100644 --- a/mkspecs/features/toolchain.prf +++ b/mkspecs/features/toolchain.prf @@ -281,4 +281,8 @@ QMAKE_COMPILER_DEFINES += __cplusplus=$$QT_COMPILER_STDCXX QMAKE_CFLAGS += $$QMAKE_CFLAGS_MSVC_COMPAT QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_MSVC_COMPAT -msvc:!intel_icl:!clang_cl: include(../common/msvc-version.conf) +clang_cl|intel_icl { + include(../common/msvc-based-version.conf) +} else: msvc { + include(../common/msvc-version.conf) +} From 3c3a2eb3cea0bbb0b45e43278421e051c253e434 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 14 Dec 2018 09:27:15 +0100 Subject: [PATCH 0651/1650] uic: Generate version check macros around newly introduced palette color role MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change ebd3a13b807c6af2684b42d3912549caf7ef82aa introduced a new QPaletter::PlaceholderText color role which causes the uic-generated code not to compile when using Qt Designer embedded in Qt Creator with older (5.9 LTS) kits. Generate a version check macro to fix this. Change-Id: I6d9f7edb0c6047c2f64ef3357b29f91655c52aac Fixes: QTBUG-72555 Reviewed-by: Lars Knoll Reviewed-by: Christian Ehrlicher Reviewed-by: André Hartmann --- src/tools/uic/cpp/cppwriteinitialization.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/tools/uic/cpp/cppwriteinitialization.cpp b/src/tools/uic/cpp/cppwriteinitialization.cpp index 4f6ac1eb97..7ab6c31cb2 100644 --- a/src/tools/uic/cpp/cppwriteinitialization.cpp +++ b/src/tools/uic/cpp/cppwriteinitialization.cpp @@ -35,6 +35,7 @@ #include "globaldefs.h" #include +#include #include #include @@ -1765,6 +1766,13 @@ QString WriteInitialization::domColor2QString(const DomColor *c) .arg(c->elementBlue()); } +static inline QVersionNumber colorRoleVersionAdded(const QString &roleName) +{ + if (roleName == QLatin1String("PlaceholderText")) + return QVersionNumber(5, 12, 0); + return QVersionNumber(); +} + void WriteInitialization::writeColorGroup(DomColorGroup *colorGroup, const QString &group, const QString &paletteName) { if (!colorGroup) @@ -1785,10 +1793,19 @@ void WriteInitialization::writeColorGroup(DomColorGroup *colorGroup, const QStri const auto &colorRoles = colorGroup->elementColorRole(); for (const DomColorRole *colorRole : colorRoles) { if (colorRole->hasAttributeRole()) { + const QString roleName = colorRole->attributeRole(); + const QVersionNumber versionAdded = colorRoleVersionAdded(roleName); const QString brushName = writeBrushInitialization(colorRole->elementBrush()); + if (!versionAdded.isNull()) { + m_output << "#if QT_VERSION >= QT_VERSION_CHECK(" + << versionAdded.majorVersion() << ", " << versionAdded.minorVersion() + << ", " << versionAdded.microVersion() << ")\n"; + } m_output << m_indent << paletteName << ".setBrush(" << group - << ", " << "QPalette::" << colorRole->attributeRole() + << ", " << "QPalette::" << roleName << ", " << brushName << ");\n"; + if (!versionAdded.isNull()) + m_output << "#endif\n"; } } } From 3e4f8aa8f434d791b3dfe9450bad85b82406d4b3 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 11 Dec 2018 12:48:12 -0800 Subject: [PATCH 0652/1650] Doc: fix null pointer passing to fprintf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When these docs were written, the context.file and context.function pointers were never null. But in commit d78fb442d750b33afe2e41f31588ec94 (Qt 5.4), we made the logging pass null pointers in release builds. The C standard does not say that passing null pointers is permitted. In fact, it says "If no l length modifier is present, the argument shall be a pointer to the initial element of an array of character type." and that's pretty explicit that it needs to point to the initial element of a string. Fixes: QTBUG-72478 Change-Id: I4ac1156702324f0fb814fffd156f624ffefa1445 Reviewed-by: Topi Reiniö --- .../doc/snippets/code/src_corelib_global_qglobal.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp index 0248640369..03904659f5 100644 --- a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp @@ -279,21 +279,23 @@ const TInputType &myMin(const TInputType &value1, const TInputType &value2) void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) { QByteArray localMsg = msg.toLocal8Bit(); + const char *file = context.file ? context.file : ""; + const char *function = context.function ? context.function : ""; switch (type) { case QtDebugMsg: - fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); + fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); break; case QtInfoMsg: - fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); + fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); break; case QtWarningMsg: - fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); + fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); break; case QtCriticalMsg: - fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); + fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); break; case QtFatalMsg: - fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function); + fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function); break; } } From e9c08f8287556742fbb927653b4c2d071923e5a7 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 22 May 2018 21:17:11 -0300 Subject: [PATCH 0653/1650] Mark ICC 18 & 19 as warning-free MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I052407b777ec43f78378fffd15311de83f978817 Reviewed-by: Sérgio Martins --- mkspecs/features/qt_common.prf | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mkspecs/features/qt_common.prf b/mkspecs/features/qt_common.prf index e67b79acc3..6cb2e78c1c 100644 --- a/mkspecs/features/qt_common.prf +++ b/mkspecs/features/qt_common.prf @@ -112,16 +112,17 @@ warnings_are_errors:warning_clean { QMAKE_CXXFLAGS_WARN_ON += -Werror -Wno-error=\\$${LITERAL_HASH}warnings -Wno-error=deprecated-declarations $$WERROR } } else:intel_icc:linux { - # Intel CC 13.0 - 17.0, on Linux only + # Intel CC 13.0 - 18.0, on Linux only ver = $${QT_ICC_MAJOR_VERSION}.$${QT_ICC_MINOR_VERSION} - linux:contains(ver, "(1[3456]\\.|17\\.0)") { + linux:contains(ver, "(1[345678]\\.|19\\.0)") { # 177: function "entity" was declared but never referenced # (too aggressive; ICC reports even for functions created due to template instantiation) # 1224: #warning directive # 1478: function "entity" (declared at line N) was declared deprecated + # 1786: function "entity" (declared at line N of "file") was declared deprecated ("message") # 1881: argument must be a constant null pointer value # (NULL in C++ is usually a literal 0) - QMAKE_CXXFLAGS_WARN_ON += -Werror -ww177,1224,1478,1881 $$WERROR + QMAKE_CXXFLAGS_WARN_ON += -Werror -ww177,1224,1478,1786,1881 $$WERROR } } else:gcc:!clang:!intel_icc:!rim_qcc { # GCC 4.6-4.9, 5.x, ... From e3d1f8d0753cc0f7486378bdc41fad9bde4b6d5c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 10 Dec 2018 18:55:09 -0800 Subject: [PATCH 0654/1650] Fix build in INTEGRITY: __mulh is not defined MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 6b875f0625acc6c6a4f8899b829176baaf7d8502 created a macro for it, but in the multiple updates to find the best solution, we forgot to use it. Fixes: QTBUG-72429 Change-Id: I4ac1156702324f0fb814fffd156f27c1789d1409 Reviewed-by: Thomas Miller Reviewed-by: Janne Koskinen Reviewed-by: Mårten Nordheim --- src/corelib/global/qnumeric_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h index 5326d9485b..dd59f97f8b 100644 --- a/src/corelib/global/qnumeric_p.h +++ b/src/corelib/global/qnumeric_p.h @@ -348,7 +348,7 @@ template <> inline bool mul_overflow(qint64 v1, qint64 v2, qint64 *r) // as signed for the low bits and use a signed right shift to verify that // 'high' is nothing but sign bits that match the sign of 'low'. - qint64 high = __mulh(v1, v2); + qint64 high = Q_SMULH(v1, v2); *r = qint64(quint64(v1) * quint64(v2)); return (*r >> 63) != high; } From 5384b1f2c8927856851a6e0a53c6fd6958232877 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 11 Sep 2018 19:13:59 -0700 Subject: [PATCH 0655/1650] Repack some classes in Moc to avoid padding holes Change-Id: I8f261579aad648fdb4f0fffd155385477abadf9e Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/tools/moc/moc.h | 68 +++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 36 deletions(-) diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h index d98c73e1a0..d6482f4e44 100644 --- a/src/tools/moc/moc.h +++ b/src/tools/moc/moc.h @@ -83,57 +83,53 @@ Q_DECLARE_TYPEINFO(ArgumentDef, Q_MOVABLE_TYPE); struct FunctionDef { - FunctionDef(): returnTypeIsVolatile(false), access(Private), isConst(false), isVirtual(false), isStatic(false), - inlineCode(false), wasCloned(false), isCompat(false), isInvokable(false), - isScriptable(false), isSlot(false), isSignal(false), isPrivateSignal(false), - isConstructor(false), isDestructor(false), isAbstract(false), revision(0) {} Type type; + QVector arguments; QByteArray normalizedType; QByteArray tag; QByteArray name; - bool returnTypeIsVolatile; - - QVector arguments; + QByteArray inPrivateClass; enum Access { Private, Protected, Public }; - Access access; - bool isConst; - bool isVirtual; - bool isStatic; - bool inlineCode; - bool wasCloned; + Access access = Private; + int revision = 0; - QByteArray inPrivateClass; - bool isCompat; - bool isInvokable; - bool isScriptable; - bool isSlot; - bool isSignal; - bool isPrivateSignal; - bool isConstructor; - bool isDestructor; - bool isAbstract; + bool isConst = false; + bool isVirtual = false; + bool isStatic = false; + bool inlineCode = false; + bool wasCloned = false; - int revision; + bool returnTypeIsVolatile = false; + + bool isCompat = false; + bool isInvokable = false; + bool isScriptable = false; + bool isSlot = false; + bool isSignal = false; + bool isPrivateSignal = false; + bool isConstructor = false; + bool isDestructor = false; + bool isAbstract = false; }; Q_DECLARE_TYPEINFO(FunctionDef, Q_MOVABLE_TYPE); struct PropertyDef { - PropertyDef():notifyId(-1), constant(false), final(false), gspec(ValueSpec), revision(0){} - QByteArray name, type, member, read, write, reset, designable, scriptable, editable, stored, user, notify, inPrivateClass; - int notifyId; // -1 means no notifyId, >= 0 means signal defined in this class, < -1 means signal not defined in this class - bool constant; - bool final; - enum Specification { ValueSpec, ReferenceSpec, PointerSpec }; - Specification gspec; bool stdCppSet() const { QByteArray s("set"); s += toupper(name[0]); s += name.mid(1); return (s == write); } - int revision; + + QByteArray name, type, member, read, write, reset, designable, scriptable, editable, stored, user, notify, inPrivateClass; + int notifyId = -1; // -1 means no notifyId, >= 0 means signal defined in this class, < -1 means signal not defined in this class + enum Specification { ValueSpec, ReferenceSpec, PointerSpec }; + Specification gspec = ValueSpec; + int revision = 0; + bool constant = false; + bool final = false; }; Q_DECLARE_TYPEINFO(PropertyDef, Q_MOVABLE_TYPE); @@ -169,9 +165,6 @@ struct ClassDef : BaseDef { }; QVector >interfaceList; - bool hasQObject = false; - bool hasQGadget = false; - struct PluginData { QByteArray iid; QMap metaArgs; @@ -181,11 +174,14 @@ struct ClassDef : BaseDef { QVector constructorList; QVector signalList, slotList, methodList, publicList; QVector nonClassSignalList; - int notifyableProperties = 0; QVector propertyList; + int notifyableProperties = 0; int revisionedMethods = 0; int revisionedProperties = 0; + bool hasQObject = false; + bool hasQGadget = false; + }; Q_DECLARE_TYPEINFO(ClassDef, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(ClassDef::Interface, Q_MOVABLE_TYPE); From a227ea5bd5af50ac6f874ecf764858a43c53cada Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 10 Dec 2018 15:18:07 +0100 Subject: [PATCH 0656/1650] Fix warnings building with --std=c++11 and gcc 8 Silence warnings about signed constants being shifted out of int range. Change-Id: I5dc397de71f4de09e54ce3cbc0f8e3a1cf977b03 Reviewed-by: Thiago Macieira --- src/corelib/io/qdebug.h | 2 +- src/opengl/qgl.cpp | 2 +- .../fontdatabases/freetype/qfontengine_ft.cpp | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h index ae1869f89e..9d1ce51da5 100644 --- a/src/corelib/io/qdebug.h +++ b/src/corelib/io/qdebug.h @@ -96,7 +96,7 @@ class Q_CORE_EXPORT QDebug void setVerbosity(int v) { if (context.version > 1) { - flags &= ~(VerbosityMask << VerbosityShift); + flags &= ~(uint(VerbosityMask) << VerbosityShift); flags |= (v & VerbosityMask) << VerbosityShift; } } diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index a5556ccee3..ba4a1dcaa1 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -157,7 +157,7 @@ class QGLDefaultOverlayFormat: public QGLFormat public: inline QGLDefaultOverlayFormat() { - setOption(QGL::FormatOption(0xffff << 16)); // turn off all options + setOption(QGL::FormatOption(0xffffU << 16)); // turn off all options setOption(QGL::DirectRendering); setPlane(1); } diff --git a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp index 7b4f6aa107..04a5026395 100644 --- a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp +++ b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp @@ -591,7 +591,7 @@ static void convertRGBToARGB_helper(const uchar *src, uint *dst, int width, int uchar green = src[x + 1]; uchar blue = src[x + 1 + offs]; LcdFilter::filterPixel(red, green, blue); - *dd++ = (0xFF << 24) | (red << 16) | (green << 8) | blue; + *dd++ = (0xFFU << 24) | (red << 16) | (green << 8) | blue; } dst += width; src += src_pitch; @@ -616,7 +616,7 @@ static void convertRGBToARGB_V_helper(const uchar *src, uint *dst, int width, in uchar green = src[x + src_pitch]; uchar blue = src[x + src_pitch + offs]; LcdFilter::filterPixel(red, green, blue); - *dst++ = (0XFF << 24) | (red << 16) | (green << 8) | blue; + *dst++ = (0XFFU << 24) | (red << 16) | (green << 8) | blue; } src += 3*src_pitch; } @@ -637,7 +637,7 @@ static inline void convertGRAYToARGB(const uchar *src, uint *dst, int width, int const uchar * const e = p + width; while (p < e) { uchar gray = *p++; - *dst++ = (0xFF << 24) | (gray << 16) | (gray << 8) | gray; + *dst++ = (0xFFU << 24) | (gray << 16) | (gray << 8) | gray; } src += src_pitch; } From e80bf655e922e9864f8843b5e7bbb47019a6d95a Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 7 Dec 2017 19:30:07 +0100 Subject: [PATCH 0657/1650] configure: verify header presence against sources in addition to the actual library resolution, also resolve the headers belonging to the library, to validate the include path, and possibly ensure that the right version of the library is present. the "include" entries were moved out of the "test" objects, and renamed to "headers". this cleanly permits libraries without compile tests. the headers were not put into the sources, because the variance among the includes is generally orthogonal to the variance among the libraries. note that this - like the library resolution - provides no support for darwin frameworks. consequently, the opengl libraries are excluded from the conversion on darwin. similarly, wasm is excluded (centrally), because emcc is magic and would need advanced wizardry to be dealt with. Change-Id: Ib390c75371efa2badcfec9b74274047ce67c3e5a Reviewed-by: Joerg Bornemann Reviewed-by: Paul Wicking --- configure.json | 6 +- mkspecs/features/qt_configure.prf | 58 ++++++++++++++++--- src/corelib/configure.json | 22 ++++---- src/gui/configure.json | 80 ++++++++++++++------------- src/network/configure.json | 2 +- src/plugins/sqldrivers/configure.json | 33 +++++------ src/plugins/sqldrivers/configure.pri | 4 +- src/printsupport/configure.json | 2 +- 8 files changed, 125 insertions(+), 82 deletions(-) diff --git a/configure.json b/configure.json index 69e058e0c2..2a717daf9a 100644 --- a/configure.json +++ b/configure.json @@ -152,13 +152,13 @@ "zlib": { "label": "zlib", "test": { - "include": "zlib.h", "main": [ "z_streamp stream = 0;", "(void) zlibVersion();", "(void) compress2(0, 0, 0, 0, 1); // compress2 was added in zlib version 1.0.8" ] }, + "headers": "zlib.h", "sources": [ { "libs": "-lzdll", "condition": "config.msvc" }, { "libs": "-lzlib", "condition": "config.msvc" }, @@ -169,9 +169,9 @@ "dbus": { "label": "D-Bus >= 1.2", "test": { - "include": "dbus/dbus.h", "main": "(void) dbus_bus_get_private(DBUS_BUS_SYSTEM, (DBusError *)NULL);" }, + "headers": "dbus/dbus.h", "sources": [ { "type": "pkgConfig", "args": "dbus-1 >= 1.2" }, { @@ -196,9 +196,9 @@ "libudev": { "label": "udev", "test": { - "include": "libudev.h", "main": "udev_unref(udev_new());" }, + "headers": "libudev.h", "sources": [ { "type": "pkgConfig", "args": "libudev" }, "-ludev" diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index e2e341770e..3483ddc5dc 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -582,7 +582,33 @@ defineTest(qtConfResolvePathLibs) { return($$ret) } -# includes-var, includes +defineReplace(qtConfGetTestIncludes) { + defined($${1}._KEYS_, var) { + 1st = $$first($${1}._KEYS_) + equals(1st, 0) { + # array; recurse for every element + ret = + for (k, $${1}._KEYS_): \ + ret += $$qtConfGetTestIncludes($${1}.$$k) + return($$ret) + } + # object; try condition and recurse + !defined($${1}.headers, var):!defined($${1}.headers._KEYS_, var): \ # just plain broken without it + error("headers object '$$1' has no nested headers entry") + cond = $$eval($${1}.condition) + isEmpty(cond): \ # would be pointless otherwise + error("headers object '$$1' has no condition") + !$$qtConfEvaluate($$cond) { + qtLog("header entry '$$1' failed condition '$$cond'.") + return() + } + qtLog("header entry '$$1' passed condition.") + return($$qtConfGetTestIncludes($${1}.headers)) + } + return($$eval($$1)) # plain string - or nothing (can happen for top-level call only) +} + +# includes-var, in-paths, test-object-var defineTest(qtConfResolvePathIncs) { ret = true for (incdir, 2) { @@ -594,6 +620,21 @@ defineTest(qtConfResolvePathIncs) { 2 -= $$QMAKE_DEFAULT_INCDIRS $$1 = $$2 export($$1) + wasm { + # FIXME: emcc downloads pre-built libraries and adds their include + # path to the clang call dynamically. it would be possible to parse + # the emcc -s USE_xyz=1 --cflags output to populate xzy_INCDIR and + # thus make the code below work. + return($$ret) + } + hdrs = $$qtConfGetTestIncludes($${3}.headers) + for (hdr, hdrs) { + h = $$qtConfFindInPathList($$hdr, $$2 $$EXTRA_INCLUDEPATH $$QMAKE_DEFAULT_INCDIRS) + isEmpty(h) { + qtLog("$$hdr not found in [$$val_escape(2)] and global paths.") + ret = false + } + } return($$ret) } @@ -662,7 +703,7 @@ defineTest(qtConfLibrary_inline) { !qtConfResolveAllLibs($$1): \ return(false) - !qtConfResolvePathIncs($${1}.includedir, $$includes): \ + !qtConfResolvePathIncs($${1}.includedir, $$includes, $$2): \ return(false) return(true) @@ -678,7 +719,7 @@ defineTest(qtConfLibrary_makeSpec) { !qtConfResolvePathLibs($${1}.libs, $$eval(QMAKE_LIBDIR_$$spec), $$eval(QMAKE_LIBS_$$spec)): \ return(false) - !qtConfResolvePathIncs($${1}.includedir, $$eval(QMAKE_INCDIR_$$spec)): \ + !qtConfResolvePathIncs($${1}.includedir, $$eval(QMAKE_INCDIR_$$spec), $$2): \ return(false) # note that the object is re-exported, because we resolve the libraries. @@ -741,7 +782,7 @@ defineTest(qtConfLibrary_pkgConfig) { } !isEmpty(ignored): \ qtLog("Note: Dropped compiler flags '$$ignored'.") - !qtConfResolvePathIncs($${1}.includedir, $$includes): \ + !qtConfResolvePathIncs($${1}.includedir, $$includes, $$2): \ return(false) $${1}.defines = $$defines @@ -1054,7 +1095,7 @@ defineTest(qtConfTestPrepare_compile) { } defineTest(qtConfPrepareCompileTestSource) { - test_dir = $$2 + test_dir = $$3 test_lang = $$eval($${1}.lang) isEmpty(test_lang): test_lang = "c++" @@ -1071,7 +1112,10 @@ defineTest(qtConfPrepareCompileTestSource) { for (ent, $$qtConfScalarOrList($${1}.head)): \ contents += $$ent # Includes - for (ent, $$qtConfScalarOrList($${1}.include)): \ + hdrs = $$qtConfGetTestIncludes($${1}.include) + isEmpty(hdrs): \ + hdrs = $$qtConfGetTestIncludes($$2) + for (ent, hdrs): \ contents += "$${LITERAL_HASH}include <$$ent>" # Custom code after includes for (ent, $$qtConfScalarOrList($${1}.tail)): \ @@ -1107,7 +1151,7 @@ defineTest(qtConfTest_compile) { isEmpty(test) { test_dir = $$test_base_out_dir/$$section(1, ".", -1) test_out_dir = $$test_dir - qtConfPrepareCompileTestSource($${1}.test, $$test_dir) + qtConfPrepareCompileTestSource($${1}.test, $${1}.headers, $$test_dir) } else { test_dir = $$QMAKE_CONFIG_TESTS_DIR/$$test test_out_dir = $$test_base_out_dir/$$test diff --git a/src/corelib/configure.json b/src/corelib/configure.json index 183eb3a13e..81448174b6 100644 --- a/src/corelib/configure.json +++ b/src/corelib/configure.json @@ -24,9 +24,9 @@ "doubleconversion": { "label": "DoubleConversion", "test": { - "include": "double-conversion/double-conversion.h", "main": "(void) double_conversion::StringToDoubleConverter::NO_FLAGS;" }, + "headers": "double-conversion/double-conversion.h", "sources": [ "-ldouble-conversion" ] @@ -35,7 +35,6 @@ "label": "GLib", "test": { "head": "typedef struct _GMainContext GMainContext;", - "include": "glib.h", "main": [ "g_thread_init(NULL);", "(void) g_main_context_default();", @@ -43,6 +42,7 @@ "g_source_add_poll(NULL, NULL);" ] }, + "headers": "glib.h", "sources": [ { "type": "pkgConfig", "args": "glib-2.0 gthread-2.0" } ] @@ -58,7 +58,6 @@ "icu": { "label": "ICU", "test": { - "include": [ "unicode/utypes.h", "unicode/ucol.h", "unicode/ustring.h" ], "main": [ "UErrorCode status = U_ZERO_ERROR;", "UCollator *collator = ucol_open(\"ru_RU\", &status);", @@ -66,6 +65,7 @@ " ucol_close(collator);" ] }, + "headers": [ "unicode/utypes.h", "unicode/ucol.h", "unicode/ustring.h" ], "sources": [ { "builds": { @@ -84,9 +84,9 @@ "journald": { "label": "journald", "test": { - "include": [ "systemd/sd-journal.h", "syslog.h" ], "main": "sd_journal_send(\"PRIORITY=%i\", LOG_INFO, NULL);" }, + "headers": [ "systemd/sd-journal.h", "syslog.h" ], "sources": [ { "type": "pkgConfig", "args": "libsystemd" }, { "type": "pkgConfig", "args": "libsystemd-journal" } @@ -95,7 +95,6 @@ "libatomic": { "label": "64 bit atomics", "test": { - "include": [ "atomic", "cstdint" ], "tail": [ "void test(volatile std::atomic &a)", "{", @@ -114,6 +113,7 @@ ], "qmake": "CONFIG += c++11" }, + "headers": [ "atomic", "cstdint" ], "sources": [ "", "-latomic" @@ -122,13 +122,13 @@ "libdl": { "label": "dlopen()", "test": { - "include": "dlfcn.h", "main": [ "dlclose(dlopen(0, 0));", "dlsym(RTLD_DEFAULT, 0);", "dlerror();" ] }, + "headers": "dlfcn.h", "sources": [ "", "-ldl" @@ -137,9 +137,9 @@ "librt": { "label": "clock_gettime()", "test": { - "include": [ "unistd.h", "time.h" ], "main": "timespec ts; clock_gettime(CLOCK_REALTIME, &ts);" }, + "headers": [ "unistd.h", "time.h" ], "sources": [ "", "-lrt" @@ -148,9 +148,9 @@ "lttng-ust": { "label": "lttng-ust", "test": { - "include": "lttng/ust-events.h", "main": "lttng_session_destroy(nullptr);" }, + "headers": "lttng/ust-events.h", "sources": [ { "type": "pkgConfig", "args": "lttng-ust" }, "-llttng-ust" @@ -161,13 +161,13 @@ "label": "PCRE2", "test": { "head": "#define PCRE2_CODE_UNIT_WIDTH 16", - "include": "pcre2.h", "tail": [ "#if (PCRE2_MAJOR < 10) || ((PCRE2_MAJOR == 10) && (PCRE2_MINOR < 20))", "# error This PCRE version is not supported", "#endif" ] }, + "headers": "pcre2.h", "sources": [ { "type": "pkgConfig", "args": "libpcre2-16" }, "-lpcre2-16" @@ -176,12 +176,12 @@ "pps": { "label": "PPS", "test": { - "include": "sys/pps.h", "main": [ "pps_decoder_t decoder;", "pps_decoder_initialize(&decoder, NULL);" ] }, + "headers": "sys/pps.h", "sources": [ "-lpps" ] @@ -189,10 +189,10 @@ "slog2": { "label": "slog2", "test": { - "include": "sys/slog2.h", "main": "slog2_set_default_buffer((slog2_buffer_t)-1);" }, "export": "", + "headers": "sys/slog2.h", "sources": [ "-lslog2" ] diff --git a/src/gui/configure.json b/src/gui/configure.json index 7585e9c8d4..d0cca08b75 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -67,7 +67,6 @@ "label": "Direct 2D", "export": "", "test": { - "include": [ "d3d11_1.h", "d2d1_1.h", "d2d1_1helper.h", "dxgi1_2.h", "wrl.h", "dwrite.h" ], "tail": "using Microsoft::WRL::ComPtr;", "main": [ "ComPtr d2dFactory;", @@ -76,6 +75,7 @@ "(void) surface;" ] }, + "headers": [ "d3d11_1.h", "d2d1_1.h", "d2d1_1helper.h", "dxgi1_2.h", "wrl.h", "dwrite.h" ], "sources": [ "-ld2d1 -ldwrite -ld3d11" ] @@ -83,13 +83,13 @@ "directfb": { "label": "DirectFB", "test": { - "include": "directfb.h", "tail": [ "#ifdef __typeof__", "# error DirectFB headers are unclean and cannot compile", "#endif" ] }, + "headers": "directfb.h", "sources": [ { "type": "pkgConfig", "args": "directfb" } ] @@ -98,13 +98,13 @@ "label": "DirectWrite", "export": "", "test": { - "include": [ "dwrite.h", "d2d1.h" ], "main": [ "IDWriteFactory *factory = 0;", "DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory),", " (IUnknown **)(&factory));" ] }, + "headers": [ "dwrite.h", "d2d1.h" ], "sources": [ "-ldwrite" ] @@ -117,15 +117,12 @@ "#include ", "extern \"C\" {" ], - "include": [ - "xf86drmMode.h", - "xf86drm.h" - ], "tail": [ "}" ], "main": "(void) drmModeGetCrtc(0, 0);" }, + "headers": [ "xf86drmMode.h", "xf86drm.h" ], "sources": [ { "type": "pkgConfig", "args": "libdrm" }, { "libs": "-ldrm", "condition": "!config.integrity" }, @@ -135,12 +132,12 @@ "egl": { "label": "EGL", "test": { - "include": "EGL/egl.h", "main": [ "EGLint x = 0; EGLDisplay dpy = 0; EGLContext ctx = 0;", "eglDestroyContext(dpy, ctx);" ] }, + "headers": "EGL/egl.h", "sources": [ { "type": "pkgConfig", "args": "egl" }, { "type": "makeSpec", "spec": "EGL" } @@ -149,7 +146,6 @@ "freetype": { "label": "FreeType", "test": { - "include": "ft2build.h", "tail": [ "#include FT_FREETYPE_H", "#if ((FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) < 20200)", @@ -160,6 +156,7 @@ "FT_Face face = 0;" ] }, + "headers": "ft2build.h", "sources": [ { "type": "pkgConfig", "args": "freetype2" }, { "type": "freetype", "libs": "-lfreetype", "condition": "!config.wasm" }, @@ -172,7 +169,6 @@ "fontconfig": { "label": "Fontconfig", "test": { - "include": "fontconfig/fontconfig.h", "tail": [ "#ifndef FC_RGBA_UNKNOWN", "# error This version of fontconfig is tool old, it is missing the FC_RGBA_UNKNOWN define", @@ -182,6 +178,7 @@ "FcPattern *pattern = 0;" ] }, + "headers": "fontconfig/fontconfig.h", "sources": [ { "type": "pkgConfig", "args": "fontconfig" }, { "type": "freetype", "libs": "-lfontconfig" } @@ -196,12 +193,12 @@ "#include ", "extern \"C\" {" ], - "include": "gbm.h", "tail": [ "}" ], "main": "gbm_surface *surface = 0;" }, + "headers": "gbm.h", "sources": [ { "type": "pkgConfig", "args": "gbm" } ] @@ -209,7 +206,6 @@ "harfbuzz": { "label": "HarfBuzz", "test": { - "include": "harfbuzz/hb.h", "tail": [ "#if !HB_VERSION_ATLEAST(1, 6, 0)", "# error This version of harfbuzz is too old.", @@ -224,6 +220,7 @@ "hb_buffer_destroy(buffer);" ] }, + "headers": "harfbuzz/hb.h", "sources": [ "-lharfbuzz" ] @@ -232,9 +229,9 @@ "label": "IMF", "export": "", "test": { - "include": "imf/imf_client.h", "main": "imf_client_init();" }, + "headers": "imf/imf_client.h", "sources": [ "-linput_client" ] @@ -242,9 +239,9 @@ "lgmon": { "label": "lgmon", "test": { - "include": "lgmon.h", "main": "lgmon_supported(getpid());" }, + "headers": "lgmon.h", "sources": [ "-llgmon" ] @@ -252,9 +249,9 @@ "libinput": { "label": "libinput", "test": { - "include": "libinput.h", "main": "libinput_udev_create_context(NULL, NULL, NULL);" }, + "headers": "libinput.h", "sources": [ { "type": "pkgConfig", "args": "libinput" } ] @@ -266,7 +263,6 @@ "#include ", "#include " ], - "include": "device/hiddriver.h", "main": [ "HIDDriver *driver;", "uintptr_t devicecontext;", @@ -274,6 +270,7 @@ "gh_hid_enum_devices(driver, &device_id, &devicecontext);" ] }, + "headers": "device/hiddriver.h", "sources": [ { "libs": "-lhiddev -lusbhid -lusb" } ] @@ -286,7 +283,6 @@ "#include ", "extern \"C\" {" ], - "include": "jpeglib.h", "tail": [ "}", "", @@ -294,6 +290,7 @@ ], "main": "jpeg_create_compress(cinfo);" }, + "headers": "jpeglib.h", "sources": [ { "libs": "-llibjpeg", "condition": "config.msvc" }, "-ljpeg" @@ -302,9 +299,9 @@ "libpng": { "label": "libpng", "test": { - "include": "png.h", "main": "(void) png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,0);" }, + "headers": "png.h", "sources": [ { "type": "pkgConfig", "args": "libpng" }, { "libs": "-llibpng16", "condition": "config.msvc" }, @@ -320,13 +317,13 @@ "mirclient": { "label": "Mir client libraries", "test": { - "include": [ "mir_toolkit/mir_client_library.h", "ubuntu/application/lifecycle_delegate.h", "EGL/egl.h" ], "tail": "static void surfaceCreateCallback(MirSurface*, void*) {}", "main": [ "u_application_lifecycle_delegate_new();", "mir_surface_create(0, surfaceCreateCallback, 0);" ] }, + "headers": [ "mir_toolkit/mir_client_library.h", "ubuntu/application/lifecycle_delegate.h", "EGL/egl.h" ], "sources": [ { "type": "pkgConfig", "args": "egl mirclient ubuntu-platform-api libcontent-hub >= 0.2.0" } ] @@ -334,12 +331,12 @@ "mtdev": { "label": "mtdev", "test": { - "include": "mtdev.h", "main": [ "mtdev m;", "mtdev_open(&m, 0);" ] }, + "headers": "mtdev.h", "sources": [ { "type": "pkgConfig", "args": "mtdev" } ] @@ -352,7 +349,6 @@ "# include ", "#else", "# define GL_GLEXT_PROTOTYPES", - "# include ", "#endif" ], "main": [ @@ -363,6 +359,12 @@ "glEnd();" ] }, + "headers": [ + { + "condition": "!config.darwin", + "headers": "GL/gl.h" + } + ], "sources": [ { "type": "pkgConfig", "args": "gl", "condition": "!config.darwin" }, { "type": "makeSpec", "spec": "OPENGL" } @@ -376,7 +378,6 @@ "# include ", "#else", "# define GL_GLEXT_PROTOTYPES", - "# include ", "#endif" ], "main": [ @@ -384,6 +385,12 @@ "glClear(GL_COLOR_BUFFER_BIT);" ] }, + "headers": [ + { + "condition": "!config.darwin", + "headers": "GLES2/gl2.h" + } + ], "sources": [ { "type": "pkgConfig", "args": "glesv2", "condition": "!config.darwin" }, { "type": "makeSpec", "spec": "OPENGL_ES2" } @@ -392,9 +399,9 @@ "openvg": { "label": "OpenVG", "test": { - "include": "VG/openvg.h", "main": "VGint i = 2; vgFlush();" }, + "headers": "VG/openvg.h", "sources": [ { "type": "pkgConfig", "args": "vg" }, { "type": "makeSpec", "spec": "OPENVG" } @@ -403,9 +410,9 @@ "tslib": { "label": "tslib", "test": { - "include": "tslib.h", "main": "ts_open(\"foo\", 0);" }, + "headers": "tslib.h", "sources": [ "-lts" ] @@ -417,10 +424,6 @@ "#include ", "extern \"C\" {" ], - "include": [ - "mediactl/mediactl.h", - "mediactl/v4l2subdev.h" - ], "tail": [ "}" ], @@ -431,6 +434,7 @@ "v4l2_subdev_set_format(nullptr, nullptr, 0, V4L2_SUBDEV_FORMAT_ACTIVE);" ] }, + "headers": [ "mediactl/mediactl.h", "mediactl/v4l2subdev.h" ], "sources": [ { "type": "pkgConfig", "args": "libv4l2 libmediactl" }, "-lmediactl -lv4l2 -lv4l2subdev" @@ -447,9 +451,9 @@ "wayland_server": { "label": "Wayland Server", "test": { - "include": "wayland-server.h", "main": "wl_display_create();" }, + "headers": "wayland-server.h", "sources": [ { "type": "pkgConfig", "args": "wayland-server" } ] @@ -457,12 +461,12 @@ "xlib": { "label": "XLib", "test": { - "include": "X11/Xlib.h", "main": [ "Display *d = XOpenDisplay(NULL);", "XCloseDisplay(d);" ] }, + "headers": "X11/Xlib.h", "sources": [ { "type": "makeSpec", "spec": "X11" } ] @@ -476,7 +480,6 @@ "xcb": { "label": "XCB >= 1.9 (core)", "test": { - "include": "xcb/xcb.h", "main": [ "int primaryScreen = 0;", "(void)xcb_connect(\"\", &primaryScreen);", @@ -484,6 +487,7 @@ "int xcbScreenError = XCB_CONN_CLOSED_INVALID_SCREEN;" ] }, + "headers": "xcb/xcb.h", "sources": [ { "type": "pkgConfig", "args": "xcb >= 1.9" }, "-lxcb" @@ -517,9 +521,9 @@ "xcb_xlib": { "label": "XCB Xlib", "test": { - "include": "X11/Xlib-xcb.h", "main": "(void) XGetXCBConnection((Display *)0);" }, + "headers": "X11/Xlib-xcb.h", "sources": [ { "type": "pkgConfig", "args": "x11-xcb" }, "-lX11-xcb" @@ -533,13 +537,13 @@ "// xkb.h is using a variable called 'explicit', which is a reserved keyword in C++", "#define explicit dont_use_cxx_explicit" ], - "include": "xcb/xkb.h", "tail": "#undef explicit", "main": [ "// This takes more arguments in xcb-xkb < 1.10.", "xcb_xkb_get_kbd_by_name_unchecked(NULL, 0, 0, 0, 0);" ] }, + "headers": "xcb/xkb.h", "sources": [ { "type": "pkgConfig", "args": "xcb-xkb >= 1.10" }, "-lxcb-xkb" @@ -549,7 +553,6 @@ "xcb_render": { "label": "XCB XRender", "test": { - "include": "xcb/render.h", "tail": [ "// 'template' is used as a function argument name in xcb_renderutil.h", "#define template template_param", @@ -572,6 +575,7 @@ " formatsReply, XCB_PICT_STANDARD_ARGB_32);" ] }, + "headers": "xcb/render.h", "sources": [ { "type": "pkgConfig", "args": "xcb-renderutil xcb-render" }, "-lxcb-render-util -lxcb-render" @@ -581,7 +585,6 @@ "xcb_glx": { "label": "XCB GLX", "test": { - "include": "xcb/glx.h", "main": [ "int primaryScreen = 0;", "xcb_connection_t *connection = 0;", @@ -591,6 +594,7 @@ "xcb_glx_query_version_reply(connection, xglx_query_cookie, &error);" ] }, + "headers": "xcb/glx.h", "sources": [ { "type": "pkgConfig", "args": "xcb-glx" }, "-lxcb-glx" @@ -600,7 +604,6 @@ "xcb_xinput": { "label": "XCB XInput", "test": { - "include": "xcb/xinput.h", "main": [ "xcb_connection_t *connection = 0;", "xcb_generic_error_t *error = 0;", @@ -609,6 +612,7 @@ "xcb_input_xi_query_version_reply(connection, xinput_query_cookie, &error);" ] }, + "headers": "xcb/xinput.h", "sources": [ { "type": "pkgConfig", "args": "xcb-xinput >= 1.12" }, "-lxcb-xinput" @@ -618,9 +622,9 @@ "xkbcommon": { "label": "xkbcommon >= 0.5.0", "test": { - "include": [ "xkbcommon/xkbcommon.h" ], "main": "xkb_context_new(XKB_CONTEXT_NO_FLAGS);" }, + "headers": [ "xkbcommon/xkbcommon.h" ], "sources": [ { "type": "pkgConfig", "args": "xkbcommon >= 0.5.0" } ] @@ -628,9 +632,9 @@ "xkbcommon_x11": { "label": "xkbcommon-x11", "test": { - "include": [ "xkbcommon/xkbcommon-x11.h" ], "main": "xkb_x11_get_core_keyboard_device_id(nullptr);" }, + "headers": [ "xkbcommon/xkbcommon-x11.h" ], "sources": [ { "type": "pkgConfig", "args": "xkbcommon-x11" } ] diff --git a/src/network/configure.json b/src/network/configure.json index 019f8378c7..01ed1249e0 100644 --- a/src/network/configure.json +++ b/src/network/configure.json @@ -39,13 +39,13 @@ "libproxy": { "label": "libproxy", "test": { - "include": [ "proxy.h" ], "main": [ "pxProxyFactory *factory = px_proxy_factory_new();", "px_proxy_factory_get_proxies(factory, \"http://qt-project.org\");", "px_proxy_factory_free(factory);" ] }, + "headers": "proxy.h", "sources": [ "-lproxy" ] diff --git a/src/plugins/sqldrivers/configure.json b/src/plugins/sqldrivers/configure.json index 4802d3b04d..cd20eef1df 100644 --- a/src/plugins/sqldrivers/configure.json +++ b/src/plugins/sqldrivers/configure.json @@ -39,9 +39,8 @@ "libraries": { "db2": { "label": "DB2 (IBM)", - "test": { - "include": [ "sqlcli.h", "sqlcli1.h" ] - }, + "test": {}, + "headers": [ "sqlcli.h", "sqlcli1.h" ], "sources": [ { "libs": "-ldb2cli", "condition": "config.win32" }, { "libs": "-ldb2", "condition": "!config.win32" } @@ -49,9 +48,8 @@ }, "ibase": { "label": "InterBase", - "test": { - "include": "ibase.h" - }, + "test": {}, + "headers": "ibase.h", "sources": [ { "libs": "-lgds32_ms", "condition": "config.win32" }, { "libs": "-lgds", "condition": "!config.win32" } @@ -65,9 +63,9 @@ "# include ", "#endif" ], - "include": "mysql.h", "main": "mysql_get_client_version();" }, + "headers": "mysql.h", "sources": [ { "type": "mysqlConfig", "query": "--libs_r", "cleanlibs": true }, { "type": "mysqlConfig", "query": "--libs", "cleanlibs": true }, @@ -81,12 +79,12 @@ "psql": { "label": "PostgreSQL", "test": { - "include": "libpq-fe.h", "main": [ "PQescapeBytea(0, 0, 0);", "PQunescapeBytea(0, 0);" ] }, + "headers": "libpq-fe.h", "sources": [ { "type": "pkgConfig", "args": "libpq" }, { "type": "psqlConfig" }, @@ -96,9 +94,8 @@ }, "tds": { "label": "TDS (Sybase)", - "test": { - "include": [ "sybfront.h", "sybdb.h" ] - }, + "test": {}, + "headers": [ "sybfront.h", "sybdb.h" ], "sources": [ { "type": "sybaseEnv", "libs": "-lNTWDBLIB", "condition": "config.win32" }, { "type": "sybaseEnv", "libs": "-lsybdb", "condition": "!config.win32" } @@ -106,9 +103,8 @@ }, "oci": { "label": "OCI (Oracle)", - "test": { - "include": "oci.h" - }, + "test": {}, + "headers": "oci.h", "sources": [ { "libs": "-loci", "condition": "config.win32" }, { "libs": "-lclntsh", "condition": "!config.win32" } @@ -122,12 +118,12 @@ "# include ", "#endif" ], - "include": [ "sql.h", "sqlext.h" ], "main": [ "SQLHANDLE env;", "SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);" ] }, + "headers": [ "sql.h", "sqlext.h" ], "sources": [ { "libs": "-lodbc32", "condition": "config.win32" }, { "libs": "-liodbc", "condition": "config.darwin" }, @@ -136,9 +132,8 @@ }, "sqlite2": { "label": "SQLite (version 2)", - "test": { - "include": "sqlite.h" - }, + "test": {}, + "headers": "sqlite.h", "sources": [ "-lsqlite" ] @@ -147,9 +142,9 @@ "label": "SQLite (version 3)", "export": "sqlite", "test": { - "include": "sqlite3.h", "main": "sqlite3_open_v2(0, 0, 0, 0);" }, + "headers": "sqlite3.h", "sources": [ { "type": "pkgConfig", "args": "sqlite3" }, "-lsqlite3" diff --git a/src/plugins/sqldrivers/configure.pri b/src/plugins/sqldrivers/configure.pri index 747a47e7b8..84c8114c7b 100644 --- a/src/plugins/sqldrivers/configure.pri +++ b/src/plugins/sqldrivers/configure.pri @@ -9,7 +9,7 @@ defineTest(qtConfLibrary_psqlConfig) { !qtConfResolvePathLibs($${1}.libs, $$libdir, -lpq): \ return(false) qtRunLoggedCommand("$$pg_config --includedir", includedir)|return(false) - !qtConfResolvePathIncs($${1}.includedir, $$includedir): \ + !qtConfResolvePathIncs($${1}.includedir, $$includedir, $$2): \ return(false) return(true) } @@ -63,7 +63,7 @@ defineTest(qtConfLibrary_mysqlConfig) { includedir = for (id, rawincludedir): \ includedir += $$clean_path($$id) - !qtConfResolvePathIncs($${1}.includedir, $$includedir): \ + !qtConfResolvePathIncs($${1}.includedir, $$includedir, $$2): \ return(false) return(true) } diff --git a/src/printsupport/configure.json b/src/printsupport/configure.json index abc704fa18..7183d2e737 100644 --- a/src/printsupport/configure.json +++ b/src/printsupport/configure.json @@ -17,9 +17,9 @@ "cups": { "label": "CUPS", "test": { - "include": "cups/cups.h", "main": "cupsGetNamedDest(CUPS_HTTP_DEFAULT, NULL, NULL); // CUPS 1.4 test" }, + "headers": "cups/cups.h", "sources": [ "-lcups" ] From 649ee12aba2ee92781f0ab888d21a1bdb440b7da Mon Sep 17 00:00:00 2001 From: Samuel Gaist Date: Fri, 14 Dec 2018 20:59:55 +0100 Subject: [PATCH 0658/1650] QRegularExpression: anchor wildcard pattern The current implementation of wildcardToRegularExpression doesn't anchor the pattern which makes it not narrow enough for globbing patterns. This patch fixes that by applying anchoredPattern before returning the wildcard pattern. [ChangeLog][QtCore][QRegularExpression] The wildcardToRegularExpression method now returns a properly anchored pattern. Change-Id: I7bee73389d408cf42499652e4fb854517a8125b5 Fixes: QTBUG-72539 Reviewed-by: Thiago Macieira --- src/corelib/io/qdir.cpp | 3 +- src/corelib/tools/qregularexpression.cpp | 2 +- src/widgets/dialogs/qfilesystemmodel.cpp | 3 +- .../tst_qregularexpression.cpp | 74 +++++++++---------- 4 files changed, 40 insertions(+), 42 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 7df461ddce..3007ffb958 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -2127,10 +2127,9 @@ QString QDir::rootPath() bool QDir::match(const QStringList &filters, const QString &fileName) { for (QStringList::ConstIterator sit = filters.constBegin(); sit != filters.constEnd(); ++sit) { - QString wildcard = QRegularExpression::wildcardToRegularExpression(*sit); // Insensitive exact match // (see Notes for QRegExp Users in QRegularExpression's documentation) - QRegularExpression rx(QRegularExpression::anchoredPattern(wildcard), + QRegularExpression rx(QRegularExpression::wildcardToRegularExpression(*sit), QRegularExpression::CaseInsensitiveOption); if (rx.match(fileName).hasMatch()) return true; diff --git a/src/corelib/tools/qregularexpression.cpp b/src/corelib/tools/qregularexpression.cpp index 908e7ff0d6..831fa28de0 100644 --- a/src/corelib/tools/qregularexpression.cpp +++ b/src/corelib/tools/qregularexpression.cpp @@ -1992,7 +1992,7 @@ QString QRegularExpression::wildcardToRegularExpression(const QString &pattern) } } - return rx; + return anchoredPattern(rx); } /*! diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp index 8b3549c3f5..d29f74e93d 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -2032,8 +2032,7 @@ bool QFileSystemModelPrivate::passNameFilters(const QFileSystemNode *node) const : QRegularExpression::CaseInsensitiveOption; for (const auto &nameFilter : nameFilters) { - const QString wildcard = QRegularExpression::wildcardToRegularExpression(nameFilter); - QRegularExpression rx(QRegularExpression::anchoredPattern(wildcard), options); + QRegularExpression rx(QRegularExpression::wildcardToRegularExpression(nameFilter), options); QRegularExpressionMatch match = rx.match(node->fileName); if (match.hasMatch()) return true; diff --git a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp b/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp index c23ee3b0ba..c02756d76a 100644 --- a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp +++ b/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp @@ -2169,47 +2169,47 @@ void tst_QRegularExpression::wildcard_data() addRow("*.html", "test.html", 0); addRow("*.html", "test.htm", -1); - addRow("bar*", "foobarbaz", 3); + addRow("*bar*", "foobarbaz", 0); addRow("*", "Qt Rocks!", 0); - addRow(".html", "test.html", 4); - addRow(".h", "test.cpp", -1); - addRow(".???l", "test.html", 4); - addRow("?", "test.html", 0); - addRow("?m", "test.html", 6); - addRow("[*]", "test.html", -1); - addRow("[?]","test.html", -1); - addRow("[?]","test.h?ml", 6); - addRow("[[]","test.h[ml", 6); - addRow("[]]","test.h]ml", 6); - addRow(".h[a-z]ml", "test.html", 4); - addRow(".h[A-Z]ml", "test.html", -1); - addRow(".h[A-Z]ml", "test.hTml", 4); - addRow(".h[!A-Z]ml", "test.hTml", -1); - addRow(".h[!A-Z]ml", "test.html", 4); - addRow(".h[!T]ml", "test.hTml", -1); - addRow(".h[!T]ml", "test.html", 4); - addRow(".h[!T]m[!L]", "test.htmL", -1); - addRow(".h[!T]m[!L]", "test.html", 4); - addRow(".h[][!]", "test.h]ml", 4); - addRow(".h[][!]", "test.h[ml", 4); - addRow(".h[][!]", "test.h!ml", 4); + addRow("*.html", "test.html", 0); + addRow("*.h", "test.cpp", -1); + addRow("*.???l", "test.html", 0); + addRow("*?", "test.html", 0); + addRow("*?ml", "test.html", 0); + addRow("*[*]", "test.html", -1); + addRow("*[?]","test.html", -1); + addRow("*[?]ml","test.h?ml", 0); + addRow("*[[]ml","test.h[ml", 0); + addRow("*[]]ml","test.h]ml", 0); + addRow("*.h[a-z]ml", "test.html", 0); + addRow("*.h[A-Z]ml", "test.html", -1); + addRow("*.h[A-Z]ml", "test.hTml", 0); + addRow("*.h[!A-Z]ml", "test.hTml", -1); + addRow("*.h[!A-Z]ml", "test.html", 0); + addRow("*.h[!T]ml", "test.hTml", -1); + addRow("*.h[!T]ml", "test.html", 0); + addRow("*.h[!T]m[!L]", "test.htmL", -1); + addRow("*.h[!T]m[!L]", "test.html", 0); + addRow("*.h[][!]ml", "test.h]ml", 0); + addRow("*.h[][!]ml", "test.h[ml", 0); + addRow("*.h[][!]ml", "test.h!ml", 0); - addRow("foo/*/bar", "Qt/foo/baz/bar", 3); - addRow("foo/(*)/bar", "Qt/foo/baz/bar", -1); - addRow("foo/(*)/bar", "Qt/foo/(baz)/bar", 3); - addRow("foo/?/bar", "Qt/foo/Q/bar", 3); - addRow("foo/?/bar", "Qt/foo/Qt/bar", -1); - addRow("foo/(?)/bar", "Qt/foo/Q/bar", -1); - addRow("foo/(?)/bar", "Qt/foo/(Q)/bar", 3); + addRow("foo/*/bar", "foo/baz/bar", 0); + addRow("foo/(*)/bar", "foo/baz/bar", -1); + addRow("foo/(*)/bar", "foo/(baz)/bar", 0); + addRow("foo/?/bar", "foo/Q/bar", 0); + addRow("foo/?/bar", "foo/Qt/bar", -1); + addRow("foo/(?)/bar", "foo/Q/bar", -1); + addRow("foo/(?)/bar", "foo/(Q)/bar", 0); #ifdef Q_OS_WIN - addRow("foo\\*\\bar", "Qt\\foo\\baz\\bar", 3); - addRow("foo\\(*)\\bar", "Qt\\foo\\baz\\bar", -1); - addRow("foo\\(*)\\bar", "Qt\\foo\\(baz)\\bar", 3); - addRow("foo\\?\\bar", "Qt\\foo\\Q\\bar", 3); - addRow("foo\\?\\bar", "Qt\\foo\\Qt\\bar", -1); - addRow("foo\\(?)\\bar", "Qt\\foo\\Q\\bar", -1); - addRow("foo\\(?)\\bar", "Qt\\foo\\(Q)\\bar", 3); + addRow("foo\\*\\bar", "foo\\baz\\bar", 0); + addRow("foo\\(*)\\bar", "foo\\baz\\bar", -1); + addRow("foo\\(*)\\bar", "foo\\(baz)\\bar", 0); + addRow("foo\\?\\bar", "foo\\Q\\bar", 0); + addRow("foo\\?\\bar", "foo\\Qt\\bar", -1); + addRow("foo\\(?)\\bar", "foo\\Q\\bar", -1); + addRow("foo\\(?)\\bar", "foo\\(Q)\\bar", 0); #endif } From 41c1866d3e8d30dfc1e7b29123ff2b834e7489f7 Mon Sep 17 00:00:00 2001 From: Samuel Gaist Date: Mon, 3 Dec 2018 13:39:15 +0100 Subject: [PATCH 0659/1650] Fix QRegularExpressionMatch capture-related documentation The documentation is not explicit enough about the content of the returned list of capturedList nor the element 0 when calling captured or its friends. The first element (aka element 0) is the whole string captured when one or more groups are used. Change-Id: I3c59ebfc9f6d762dd4d8aaf8f5c0de24359f53d7 Reviewed-by: Edward Welbourne Reviewed-by: Sze Howe Koh --- src/corelib/tools/qregularexpression.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qregularexpression.cpp b/src/corelib/tools/qregularexpression.cpp index 831fa28de0..bdaa2d3243 100644 --- a/src/corelib/tools/qregularexpression.cpp +++ b/src/corelib/tools/qregularexpression.cpp @@ -2138,6 +2138,9 @@ int QRegularExpressionMatch::lastCapturedIndex() const If the \a nth capturing group did not capture a string, or if there is no such capturing group, returns a null QString. + \note The implicit capturing group number 0 captures the substring matched + by the entire pattern. + \sa capturedRef(), capturedView(), lastCapturedIndex(), capturedStart(), capturedEnd(), capturedLength(), QString::isNull() */ @@ -2160,6 +2163,9 @@ QString QRegularExpressionMatch::captured(int nth) const If the \a nth capturing group did not capture a string, or if there is no such capturing group, returns a null QStringRef. + \note The implicit capturing group number 0 captures the substring matched + by the entire pattern. + \sa captured(), capturedView(), lastCapturedIndex(), capturedStart(), capturedEnd(), capturedLength(), QStringRef::isNull() */ @@ -2184,6 +2190,9 @@ QStringRef QRegularExpressionMatch::capturedRef(int nth) const If the \a nth capturing group did not capture a string, or if there is no such capturing group, returns a null QStringView. + \note The implicit capturing group number 0 captures the substring matched + by the entire pattern. + \sa captured(), capturedRef(), lastCapturedIndex(), capturedStart(), capturedEnd(), capturedLength(), QStringView::isNull() */ @@ -2296,7 +2305,9 @@ QStringView QRegularExpressionMatch::capturedView(QStringView name) const /*! Returns a list of all strings captured by capturing groups, in the order - the groups themselves appear in the pattern string. + the groups themselves appear in the pattern string. The list includes the + implicit capturing group number 0, capturing the substring matched by the + entire pattern. */ QStringList QRegularExpressionMatch::capturedTexts() const { From a5eabac96de54706de55497b16a46dc2223ac6e9 Mon Sep 17 00:00:00 2001 From: Samuel Gaist Date: Sun, 9 Dec 2018 08:38:57 +0100 Subject: [PATCH 0660/1650] moc: add support for C++11 enum struct C++11 added the new enum class key as well as enum struct. While the former is likely the most known and used, the later can be used in the same contexts and with the same effects. Currently moc doesn't parse enum struct while it does for enum class. This patch fixes this. [ChangeLog][moc] moc now parses enum struct the same way as enum class therefore that keyword can be used with the Q_ENUM macro as well as Q_FLAG and Q_DECLARE_FLAGS. Change-Id: Iaac3814ad63a15ee4d91b281d451e786b510449c Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Simon Hausmann --- src/tools/moc/moc.cpp | 2 +- tests/auto/tools/moc/cxx11-enums.h | 9 +++++++++ tests/auto/tools/moc/tst_moc.cpp | 3 +++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index 61a5542c83..7272df4265 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -260,7 +260,7 @@ bool Moc::parseEnum(EnumDef *def) { bool isTypdefEnum = false; // typedef enum { ... } Foo; - if (test(CLASS)) + if (test(CLASS) || test(STRUCT)) def->isEnumClass = true; if (test(IDENTIFIER)) { diff --git a/tests/auto/tools/moc/cxx11-enums.h b/tests/auto/tools/moc/cxx11-enums.h index 93ab16c157..cc14c0acda 100644 --- a/tests/auto/tools/moc/cxx11-enums.h +++ b/tests/auto/tools/moc/cxx11-enums.h @@ -40,13 +40,22 @@ public: enum class TypedEnumClass : char { C0, C1, C2, C3 }; enum NormalEnum { D2 = 2, D3, D0 =0 , D1 }; enum class ClassFlag { F0 = 1, F1 = 2, F2 = 4, F3 = 8}; + + enum struct EnumStruct { G0, G1, G2, G3 }; + enum struct TypedEnumStruct : char { H0, H1, H2, H3 }; + enum struct StructFlag { I0 = 1, I1 = 2, I2 = 4, I3 = 8}; + Q_DECLARE_FLAGS(ClassFlags, ClassFlag) + Q_DECLARE_FLAGS(StructFlags, StructFlag) Q_ENUM(EnumClass) Q_ENUM(TypedEnum) Q_ENUM(TypedEnumClass) Q_ENUM(NormalEnum) + Q_ENUM(EnumStruct) + Q_ENUM(TypedEnumStruct) Q_FLAG(ClassFlags) + Q_FLAG(StructFlags) }; // Also test the Q_ENUMS macro diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index 92a94055a4..293cbd8323 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -2266,6 +2266,9 @@ void tst_Moc::cxx11Enums_data() QTest::newRow("NormalEnum 2") << meta2 << QByteArray("NormalEnum") << QByteArray("NormalEnum") << 'D' << false; QTest::newRow("ClassFlags") << meta1 << QByteArray("ClassFlags") << QByteArray("ClassFlag") << 'F' << true; QTest::newRow("ClassFlags 2") << meta2 << QByteArray("ClassFlags") << QByteArray("ClassFlag") << 'F' << true; + QTest::newRow("EnumStruct") << meta1 << QByteArray("EnumStruct") << QByteArray("EnumStruct") << 'G' << true; + QTest::newRow("TypedEnumStruct") << meta1 << QByteArray("TypedEnumStruct") << QByteArray("TypedEnumStruct") << 'H' << true; + QTest::newRow("StructFlags") << meta1 << QByteArray("StructFlags") << QByteArray("StructFlag") << 'I' << true; } void tst_Moc::cxx11Enums() From 8571abc09720d17a60361b8ab88d5eb8110d9dea Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 14 Dec 2018 12:49:18 -0800 Subject: [PATCH 0661/1650] Remove "x" that was clearly a typo Or something I used for debugging. Change-Id: I61ce366d57bc46c89db5fffd15704e1d010749b6 Reviewed-by: Allan Sandfeld Jensen --- src/corelib/global/qnumeric_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h index 5326d9485b..0a6db9afcd 100644 --- a/src/corelib/global/qnumeric_p.h +++ b/src/corelib/global/qnumeric_p.h @@ -231,7 +231,7 @@ QT_WARNING_POP // size_t. Implementations for 8- and 16-bit types will work but may not be as // efficient. Implementations for 64-bit may be missing on 32-bit platforms. -#if (defined(Q_CC_GNU) && (Q_CC_GNU >= 500) || (defined(Q_CC_INTEL) && !defined(Q_OS_WIN))) || QT_HAS_BUILTIN(__builtin_add_overflowx) +#if (defined(Q_CC_GNU) && (Q_CC_GNU >= 500) || (defined(Q_CC_INTEL) && !defined(Q_OS_WIN))) || QT_HAS_BUILTIN(__builtin_add_overflow) // GCC 5, ICC 18, and Clang 3.8 have builtins to detect overflows template inline From b34143f8a19040a457d399a22f0bde53ac327ff1 Mon Sep 17 00:00:00 2001 From: Yuhang Zhao <2546789017@qq.com> Date: Tue, 11 Dec 2018 00:52:36 +0800 Subject: [PATCH 0662/1650] Fix clang LTCG config on Windows To enable LTCG, clang-cl.exe need "-flto" instead of "-GL". But if you enabled LTO, the lib tool will have to change to "llvm-lib.exe" and the link tool also need to change to "lld-link.exe", because msvc linker will see these lib files as corrupted files. Leave QMAKE_LFLAGS_LTCG empty because lld-link doesn't need any additional parameters. Fixes: QTBUG-72402 Change-Id: Ia34d98bd1ad919d542ea3eac83944bf8c40ce0cd Reviewed-by: Thiago Macieira Reviewed-by: Friedemann Kleint Reviewed-by: Oswald Buddenhagen --- mkspecs/win32-clang-msvc/qmake.conf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mkspecs/win32-clang-msvc/qmake.conf b/mkspecs/win32-clang-msvc/qmake.conf index ba9704e069..027f93ca6e 100644 --- a/mkspecs/win32-clang-msvc/qmake.conf +++ b/mkspecs/win32-clang-msvc/qmake.conf @@ -15,6 +15,14 @@ QMAKE_CFLAGS += -Wno-microsoft-enum-value QMAKE_CXXFLAGS += -Wno-microsoft-enum-value +QMAKE_LINK = lld-link +QMAKE_LIB = llvm-lib /NOLOGO + +QMAKE_CFLAGS_LTCG = -flto +QMAKE_CXXFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG +# Leave QMAKE_LFLAGS_LTCG empty because lld-link doesn't need any additional parameters +QMAKE_LFLAGS_LTCG = + # Precompiled headers are not supported yet by clang CONFIG -= precompile_header From 1f30434356603109ca8aa5edb720522cb6fceac0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 13 Dec 2018 16:02:50 +0100 Subject: [PATCH 0663/1650] nativewindow: Add additional test for 8pt font size Change-Id: I5012eb6ffee8f81da61a6fe611352ee5900a5eee Reviewed-by: Friedemann Kleint Reviewed-by: Simon Hausmann --- tests/manual/textrendering/nativetext/main.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/manual/textrendering/nativetext/main.cpp b/tests/manual/textrendering/nativetext/main.cpp index 3fb78858f0..7e98dd44d0 100644 --- a/tests/manual/textrendering/nativetext/main.cpp +++ b/tests/manual/textrendering/nativetext/main.cpp @@ -208,10 +208,9 @@ public: } }(); - layout->addWidget(new TextRenderer(12, text, color.first, color.second)); - layout->addWidget(new TextRenderer(24, text, color.first, color.second)); - layout->addWidget(new TextRenderer(36, text, color.first, color.second)); - layout->addWidget(new TextRenderer(48, text, color.first, color.second)); + for (int pointSize : {8, 12, 24, 36, 48}) + layout->addWidget(new TextRenderer(pointSize, text, color.first, color.second)); + static_cast(m_previews->layout())->addLayout(layout); } From ae825a48dcb702cef6b9b5dc0cb24c5192fc4b63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 14 Dec 2018 12:55:04 +0100 Subject: [PATCH 0664/1650] Set point size, not just pixel size, when creating HarfBuzz fonts for shaping Otherwise HarfBuzz will fall back to using default font sizes, e.g. 12.0 in the CoreText backend. hb_coretext_font_create() already does the right thing, but we're not using that function, we create the hb_font_t ourselves in _hb_qt_font_create(). The mismatch didn't matter for vector-based fonts as the metrics (presumably) scale linearly, but for bitmap-based font such as Emojis they don't, and we ended up with advances that were way too large (increasingly so the larger the font point size). Change-Id: I4781dda965c745853732026da91590d8506ec3f5 Reviewed-by: Simon Hausmann --- src/gui/text/qharfbuzzng.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/text/qharfbuzzng.cpp b/src/gui/text/qharfbuzzng.cpp index 21f880e7be..2f25aea92b 100644 --- a/src/gui/text/qharfbuzzng.cpp +++ b/src/gui/text/qharfbuzzng.cpp @@ -689,6 +689,8 @@ _hb_qt_font_create(QFontEngine *fe) hb_font_set_scale(font, QFixed(x_ppem).value(), -QFixed(y_ppem).value()); hb_font_set_ppem(font, x_ppem, y_ppem); + hb_font_set_ptem(font, fe->fontDef.pointSize); + return font; } From 9c2cb3d83eca9ac448ce7aac71285c819f7c00dd Mon Sep 17 00:00:00 2001 From: Sergio Martins Date: Sun, 9 Dec 2018 17:26:07 +0000 Subject: [PATCH 0665/1650] Remove x11Info() and x11PictureHandle() from QPixmap docs These functions were removed in Qt 5. Also removed old note about X11 QPixmap being invalid after QApplication is destroyed. It was redundant as that's the case with many other Qt classes. Change-Id: I9dfe2679057fbd4d7b69ca94affb673c383cf519 Reviewed-by: Christian Ehrlicher Reviewed-by: Gatis Paeglis --- src/gui/image/qpixmap.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 4b2334ae52..918e200549 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -1356,12 +1356,6 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode) The cacheKey() function returns a number that uniquely identifies the contents of the QPixmap object. - The x11Info() function returns information about the configuration - of the X display used by the screen to which the pixmap currently - belongs. The x11PictureHandle() function returns the X11 Picture - handle of the pixmap for XRender support. Note that the two latter - functions are only available on x11. - \endtable \section1 Pixmap Conversion @@ -1392,9 +1386,6 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode) function returns the actual matrix used for transforming the pixmap. - \note When using the native X11 graphics system, the pixmap - becomes invalid when the QApplication instance is destroyed. - \sa QBitmap, QImage, QImageReader, QImageWriter */ From 582237a593421b3e98470a03f29459d02662e9ec Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Mon, 26 Nov 2018 10:05:15 +1000 Subject: [PATCH 0666/1650] wasm: send mouse release to proper window MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the mouse is released, it gets the current window to send the event to from the pointer position. If the release happens out of the browser viewport, that window is null and the release event essentially gets ignored. This change keeps the last known QWindow object to send the event to until the release. Also replace hardcoded emscripten events with enum names. Task-number: QTBUG-71948 Change-Id: I354d14479a43489f210cca31d6b9e0f65d083bb0 Fixes: QTBUG-71948 Reviewed-by: Edward Welbourne Reviewed-by: Mikhail Svetkin Reviewed-by: Morten Johan Sørvig --- .../platforms/wasm/qwasmeventtranslator.cpp | 27 +++++++++++-------- .../platforms/wasm/qwasmeventtranslator.h | 1 + 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp index a3fdcd1025..8ab109f03c 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp @@ -63,6 +63,7 @@ EMSCRIPTEN_BINDINGS(mouse_module) { QWasmEventTranslator::QWasmEventTranslator(QObject *parent) : QObject(parent) , draggedWindow(nullptr) + , lastWindow(nullptr) , pressedButtons(Qt::NoButton) , resizeMode(QWasmWindow::ResizeNone) { @@ -370,15 +371,16 @@ void QWasmEventTranslator::processMouse(int eventType, const EmscriptenMouseEven Qt::KeyboardModifiers modifiers = translateMouseEventModifier(mouseEvent); QWindow *window2 = QWasmIntegration::get()->compositor()->windowAt(point, 5); + if (window2 != nullptr) + lastWindow = window2; + QWasmWindow *htmlWindow = static_cast(window2->handle()); - bool onFrame = false; - if (window2 && !window2->geometry().contains(point)) - onFrame = true; + + bool interior = window2 && window2->geometry().contains(point); QPoint localPoint(point.x() - window2->geometry().x(), point.y() - window2->geometry().y()); - switch (eventType) { - case 5: //down + case EMSCRIPTEN_EVENT_MOUSEDOWN: { if (window2) window2->raise(); @@ -403,7 +405,7 @@ void QWasmEventTranslator::processMouse(int eventType, const EmscriptenMouseEven htmlWindow->injectMousePressed(localPoint, point, button, modifiers); break; } - case 6: //up + case EMSCRIPTEN_EVENT_MOUSEUP: { pressedButtons.setFlag(translateMouseButton(mouseEvent->button), false); buttonEventType = QEvent::MouseButtonRelease; @@ -414,7 +416,6 @@ void QWasmEventTranslator::processMouse(int eventType, const EmscriptenMouseEven pressedWindow = nullptr; } - if (mouseEvent->button == 0) { draggedWindow = nullptr; resizeMode = QWasmWindow::ResizeNone; @@ -424,7 +425,7 @@ void QWasmEventTranslator::processMouse(int eventType, const EmscriptenMouseEven oldWindow->injectMouseReleased(localPoint, point, button, modifiers); break; } - case 8://move //drag event + case EMSCRIPTEN_EVENT_MOUSEMOVE: // drag event { buttonEventType = QEvent::MouseMove; if (!(htmlWindow->m_windowState & Qt::WindowFullScreen) && !(htmlWindow->m_windowState & Qt::WindowMaximized)) { @@ -440,11 +441,15 @@ void QWasmEventTranslator::processMouse(int eventType, const EmscriptenMouseEven } break; } - default: + default: // MOUSELEAVE MOUSEENTER break; }; - - if (window2 && !onFrame) { + if (!window2 && buttonEventType == QEvent::MouseButtonRelease) { + window2 = lastWindow; + lastWindow = nullptr; + interior = true; + } + if (window2 && interior) { QWindowSystemInterface::handleMouseEvent( window2, timestamp, localPoint, point, pressedButtons, button, buttonEventType, modifiers); } diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.h b/src/plugins/platforms/wasm/qwasmeventtranslator.h index 11430a57a2..f3dff8e48c 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.h +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.h @@ -197,6 +197,7 @@ private: private: QWindow *draggedWindow; QWindow *pressedWindow; + QWindow *lastWindow; Qt::MouseButtons pressedButtons; QWasmWindow::ResizeMode resizeMode; From 87b20009cc63d3a51e2eb93cd8492c77157b283b Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Tue, 11 Dec 2018 13:29:53 +1000 Subject: [PATCH 0667/1650] wasm: do not revise url of queries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I think this may have been for some POST method form queries, but obviously was missing something. Task-number: QTBUG-72382 Change-Id: I59016776aeedf4b5599b3b44af70610babb0a61e Reviewed-by: Edward Welbourne Reviewed-by: Morten Johan Sørvig Reviewed-by: Ryan Chu --- src/network/access/qnetworkreplywasmimpl.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/network/access/qnetworkreplywasmimpl.cpp b/src/network/access/qnetworkreplywasmimpl.cpp index 23ca62acd4..e8ca4d4084 100644 --- a/src/network/access/qnetworkreplywasmimpl.cpp +++ b/src/network/access/qnetworkreplywasmimpl.cpp @@ -315,17 +315,9 @@ void QNetworkReplyWasmImplPrivate::doSendRequest() val xhr = val::global("XMLHttpRequest").new_(); std::string verb = q->methodName().toStdString(); - QUrl url; QString extraDataString; - if (request.url().hasQuery()) { //strip query from url - extraDataString = request.url().query(QUrl::FullyEncoded); - QString urlStr = request.url().toString(); - url.setUrl(urlStr.left(urlStr.indexOf("?"))); - } else { - url = request.url(); - } - xhr.call("open", verb, url.toString().toStdString()); + xhr.call("open", verb, request.url().toString().toStdString()); xhr.set("onerror", val::module_property("QNetworkReplyWasmImplPrivate_requestErrorCallback")); xhr.set("onload", val::module_property("QNetworkReplyWasmImplPrivate_loadCallback")); From 3ccdeb4b58b681bb3a0a43f926f81fd94f527680 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 12 Dec 2018 11:54:54 +0100 Subject: [PATCH 0668/1650] Remove specialized multi font engine on Windows This was added as a platform-specific implementation of the multi engine in 2005, before this code was generalized, and it currently only has the purpose of special handling loadEngine(). The way this was special handled was by creating a new QFontEngine for every fallback family *every* time, never checking if the font engine already exists in the cache (like the superclass implementation does). The result of this was that if you had 500 fonts and each of them had 500 fallback fonts, and made a loop that would load all of them, then you would get 250000 font engines. At some point before this, we would run out of available handles and crash. There shouldn't be any need to have special handling of fallback font loading on Windows (i.e. all the platform specific parts should go through the normal mechanisms in QPA), so lets just go through the superclass implementation instead. [ChangeLog][Windows][Text] Reduced the number of font engines that are created when loading new fonts, fixing crashes in some special cases where a large number of fonts are created during a short period of time. Fixes: QTBUG-70032 Change-Id: I05040dd458e820510685e8c6df8f31876d9bdb89 Reviewed-by: Friedemann Kleint --- .../windows/qwindowsfontdatabase.cpp | 5 - .../windows/qwindowsfontdatabase_p.h | 1 - .../windows/qwindowsfontengine.cpp | 114 ------------------ .../windows/qwindowsfontengine_p.h | 10 -- 4 files changed, 130 deletions(-) diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp index 9ff50bdf05..40ac46df85 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp @@ -1264,11 +1264,6 @@ QWindowsFontDatabase::~QWindowsFontDatabase() removeApplicationFonts(); } -QFontEngineMulti *QWindowsFontDatabase::fontEngineMulti(QFontEngine *fontEngine, QChar::Script script) -{ - return new QWindowsMultiFontEngine(fontEngine, script); -} - QFontEngine * QWindowsFontDatabase::fontEngine(const QFontDef &fontDef, void *handle) { const QString faceName(static_cast(handle)); diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h index 9d0aa7f723..afba86bbe1 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_p.h @@ -98,7 +98,6 @@ public: void populateFontDatabase() override; void populateFamily(const QString &familyName) override; - QFontEngineMulti *fontEngineMulti(QFontEngine *fontEngine, QChar::Script script) override; QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) override; QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) override; QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const override; diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontengine.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontengine.cpp index 2a41209225..d1d11883c1 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontengine.cpp +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontengine.cpp @@ -1199,120 +1199,6 @@ void QWindowsFontEngine::initFontInfo(const QFontDef &request, } } -/*! - \class QWindowsMultiFontEngine - \brief Standard Windows Multi font engine. - \internal - \ingroup qt-lighthouse-win - - "Merges" several font engines that have gaps in the - supported writing systems. - - Will probably be superseded by a common Free Type font engine in Qt 5.X. -*/ -QWindowsMultiFontEngine::QWindowsMultiFontEngine(QFontEngine *fe, int script) - : QFontEngineMulti(fe, script) -{ -} - -#ifndef QT_NO_DIRECTWRITE -static QString msgDirectWriteFunctionFailed(HRESULT hr, const char *function, - const QString &fam, const QString &substitute) -{ - _com_error error(hr); - QString result; - QTextStream str(&result); - str << function << " failed for \"" << fam << '"'; - if (substitute != fam) - str << " (substitute: \"" << substitute << "\")"; - str << ": error " << hex << showbase << ulong(hr) << ' ' << noshowbase << dec - << ": " << QString::fromWCharArray(error.ErrorMessage()); - return result; -} -#endif // !QT_NO_DIRECTWRITE - -QFontEngine *QWindowsMultiFontEngine::loadEngine(int at) -{ - QFontEngine *fontEngine = engine(0); - QSharedPointer data; - LOGFONT lf; - -#ifndef QT_NO_DIRECTWRITE - if (fontEngine->type() == QFontEngine::DirectWrite) { - QWindowsFontEngineDirectWrite *fe = static_cast(fontEngine); - lf = QWindowsFontDatabase::fontDefToLOGFONT(fe->fontDef, QString()); - - data = fe->fontEngineData(); - } else -#endif - { - QWindowsFontEngine *fe = static_cast(fontEngine); - lf = fe->m_logfont; - - data = fe->fontEngineData(); - } - - const QString fam = fallbackFamilyAt(at - 1); - const int faceNameLength = qMin(fam.length(), LF_FACESIZE - 1); - memcpy(lf.lfFaceName, fam.utf16(), faceNameLength * sizeof(wchar_t)); - lf.lfFaceName[faceNameLength] = 0; - -#ifndef QT_NO_DIRECTWRITE - if (fontEngine->type() == QFontEngine::DirectWrite) { - const QString nameSubstitute = QWindowsFontEngineDirectWrite::fontNameSubstitute(fam); - if (nameSubstitute != fam) { - const int nameSubstituteLength = qMin(nameSubstitute.length(), LF_FACESIZE - 1); - memcpy(lf.lfFaceName, nameSubstitute.utf16(), nameSubstituteLength * sizeof(wchar_t)); - lf.lfFaceName[nameSubstituteLength] = 0; - } - - HFONT hfont = CreateFontIndirect(&lf); - if (hfont == nullptr) { - qErrnoWarning("%s: CreateFontIndirect failed", __FUNCTION__); - } else { - HGDIOBJ oldFont = SelectObject(data->hdc, hfont); - - IDWriteFontFace *directWriteFontFace = nullptr; - QWindowsFontEngineDirectWrite *fedw = nullptr; - HRESULT hr = data->directWriteGdiInterop->CreateFontFaceFromHdc(data->hdc, &directWriteFontFace); - if (SUCCEEDED(hr)) { - Q_ASSERT(directWriteFontFace); - fedw = new QWindowsFontEngineDirectWrite(directWriteFontFace, - fontEngine->fontDef.pixelSize, - data); - fedw->fontDef.weight = fontEngine->fontDef.weight; - if (fontEngine->fontDef.style > QFont::StyleNormal) - fedw->fontDef.style = fontEngine->fontDef.style; - fedw->fontDef.family = fam; - fedw->fontDef.hintingPreference = fontEngine->fontDef.hintingPreference; - fedw->fontDef.stretch = fontEngine->fontDef.stretch; - } else { - qWarning("%s: %s", __FUNCTION__, - qPrintable(msgDirectWriteFunctionFailed(hr, "CreateFontFace", fam, nameSubstitute))); - } - - SelectObject(data->hdc, oldFont); - DeleteObject(hfont); - - if (fedw != nullptr) - return fedw; - } - } -#endif - - // Get here if original font is not DirectWrite or DirectWrite creation failed for some - // reason - - QFontEngine *fe = new QWindowsFontEngine(fam, lf, data); - fe->fontDef.weight = fontEngine->fontDef.weight; - if (fontEngine->fontDef.style > QFont::StyleNormal) - fe->fontDef.style = fontEngine->fontDef.style; - fe->fontDef.family = fam; - fe->fontDef.hintingPreference = fontEngine->fontDef.hintingPreference; - fe->fontDef.stretch = fontEngine->fontDef.stretch; - return fe; -} - bool QWindowsFontEngine::supportsTransformation(const QTransform &transform) const { // Support all transformations for ttf files, and translations for raster fonts diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontengine_p.h b/src/platformsupport/fontdatabases/windows/qwindowsfontengine_p.h index a151cf7343..2b575a9b45 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontengine_p.h +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontengine_p.h @@ -67,8 +67,6 @@ class QWindowsFontEngineData; class QWindowsFontEngine : public QFontEngine { Q_DISABLE_COPY(QWindowsFontEngine) - friend class QWindowsMultiFontEngine; - public: QWindowsFontEngine(const QString &name, LOGFONT lf, const QSharedPointer &fontEngineData); @@ -169,14 +167,6 @@ private: mutable int designAdvancesSize = 0; }; -class QWindowsMultiFontEngine : public QFontEngineMulti -{ -public: - explicit QWindowsMultiFontEngine(QFontEngine *fe, int script); - - QFontEngine *loadEngine(int at) override; -}; - QT_END_NAMESPACE Q_DECLARE_METATYPE(HFONT) From 108f0cc998c4bb1f047b8a92ee7d5a2eb4f02ae6 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sun, 16 Dec 2018 13:24:26 +0100 Subject: [PATCH 0669/1650] Widgets: replace deprecated QPalette functions QPalette::foreground()/background() are deprecated since 5.13 - replace those functions with their successors. Change-Id: I80e49dadd7be1007d73ac920f6db2b8e608db06a Reviewed-by: Friedemann Kleint --- src/widgets/dialogs/qcolordialog.cpp | 4 ++-- src/widgets/itemviews/qtreeview.cpp | 2 +- src/widgets/widgets/qcombobox.cpp | 2 +- src/widgets/widgets/qcombobox_p.h | 2 +- src/widgets/widgets/qplaintextedit.cpp | 2 +- src/widgets/widgets/qstatusbar.cpp | 2 +- src/widgets/widgets/qtoolbar.cpp | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp index 93e49466cb..0a10f72d7b 100644 --- a/src/widgets/dialogs/qcolordialog.cpp +++ b/src/widgets/dialogs/qcolordialog.cpp @@ -842,8 +842,8 @@ void QColorLuminancePicker::paintEvent(QPaintEvent *) p.drawPixmap(1, coff, *pix); const QPalette &g = palette(); qDrawShadePanel(&p, r, g, true); - p.setPen(g.foreground().color()); - p.setBrush(g.foreground()); + p.setPen(g.windowText().color()); + p.setBrush(g.windowText()); QPolygon a; int y = val2y(val); a.setPoints(3, w, y, w+5, y+5, w+5, y-5); diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index e7196c9d5d..f37da86539 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -1766,7 +1766,7 @@ void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option, QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled) ? QPalette::Normal : QPalette::Disabled; o.backgroundColor = option.palette.color(cg, d->selectionModel->isSelected(index) - ? QPalette::Highlight : QPalette::Background); + ? QPalette::Highlight : QPalette::Window); int x = 0; if (!option.showDecorationSelected) x = header->sectionPosition(0) + d->indentationForItem(d->current); diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 645b1a8c9e..bb09b984a6 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -166,7 +166,7 @@ QStyleOptionMenuItem QComboMenuDelegate::getStyleOption(const QStyleOptionViewIt break; } if (index.data(Qt::BackgroundRole).canConvert()) { - menuOption.palette.setBrush(QPalette::All, QPalette::Background, + menuOption.palette.setBrush(QPalette::All, QPalette::Window, qvariant_cast(index.data(Qt::BackgroundRole))); } menuOption.text = index.model()->data(index, Qt::DisplayRole).toString() diff --git a/src/widgets/widgets/qcombobox_p.h b/src/widgets/widgets/qcombobox_p.h index 3f75a357e4..f76a95d2ae 100644 --- a/src/widgets/widgets/qcombobox_p.h +++ b/src/widgets/widgets/qcombobox_p.h @@ -277,7 +277,7 @@ protected: const QStyleOptionViewItem &option, const QModelIndex &index) const override { QStyleOptionMenuItem opt = getStyleOption(option, index); - painter->fillRect(option.rect, opt.palette.background()); + painter->fillRect(option.rect, opt.palette.window()); mCombo->style()->drawControl(QStyle::CE_MenuItem, &opt, painter, mCombo); } QSize sizeHint(const QStyleOptionViewItem &option, diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp index b498d5fe7a..0b79a990a9 100644 --- a/src/widgets/widgets/qplaintextedit.cpp +++ b/src/widgets/widgets/qplaintextedit.cpp @@ -2038,7 +2038,7 @@ void QPlainTextEdit::paintEvent(QPaintEvent *e) if (backgroundVisible() && !block.isValid() && offset.y() <= er.bottom() && (centerOnScroll() || verticalScrollBar()->maximum() == verticalScrollBar()->minimum())) { - painter.fillRect(QRect(QPoint((int)er.left(), (int)offset.y()), er.bottomRight()), palette().background()); + painter.fillRect(QRect(QPoint((int)er.left(), (int)offset.y()), er.bottomRight()), palette().window()); } } diff --git a/src/widgets/widgets/qstatusbar.cpp b/src/widgets/widgets/qstatusbar.cpp index ef98bb6950..ae67cbd890 100644 --- a/src/widgets/widgets/qstatusbar.cpp +++ b/src/widgets/widgets/qstatusbar.cpp @@ -689,7 +689,7 @@ void QStatusBar::paintEvent(QPaintEvent *event) } } if (haveMessage) { - p.setPen(palette().foreground().color()); + p.setPen(palette().windowText().color()); p.drawText(d->messageRect(), Qt::AlignLeading | Qt::AlignVCenter | Qt::TextSingleLine, d->tempItem); } } diff --git a/src/widgets/widgets/qtoolbar.cpp b/src/widgets/widgets/qtoolbar.cpp index 1cd30e4d0d..bcf5a40ae3 100644 --- a/src/widgets/widgets/qtoolbar.cpp +++ b/src/widgets/widgets/qtoolbar.cpp @@ -1045,7 +1045,7 @@ void QToolBar::paintEvent(QPaintEvent *) if (d->layout->expanded || d->layout->animating || isWindow()) { //if the toolbar is expended, we need to fill the background with the window color //because some styles may expects that. - p.fillRect(opt.rect, palette().background()); + p.fillRect(opt.rect, palette().window()); style->drawControl(QStyle::CE_ToolBar, &opt, &p, this); style->drawPrimitive(QStyle::PE_FrameMenu, &opt, &p, this); } else { From f4d72b3a123916feab4d785654d4e8fef9053969 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sun, 16 Dec 2018 13:22:02 +0100 Subject: [PATCH 0670/1650] Styles: replace deprecated QPalette functions QPalette::foreground()/background() are deprecated since 5.13 - replace those functions with their successors. Change-Id: I158b6403437d3d48c0859360823133ca4ced2c23 Reviewed-by: Friedemann Kleint --- src/widgets/styles/qcommonstyle.cpp | 26 ++++++------- src/widgets/styles/qfusionstyle.cpp | 54 +++++++++++++-------------- src/widgets/styles/qfusionstyle_p_p.h | 2 +- src/widgets/styles/qwindowsstyle.cpp | 44 +++++++++++----------- 4 files changed, 63 insertions(+), 63 deletions(-) diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index fc48a8ca26..01c69f1152 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -199,7 +199,7 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q break; case PE_IndicatorCheckBox: if (opt->state & State_NoChange) { - p->setPen(opt->palette.foreground().color()); + p->setPen(opt->palette.windowText().color()); p->fillRect(opt->rect, opt->palette.brush(QPalette::Button)); p->drawRect(opt->rect); p->drawLine(opt->rect.topLeft(), opt->rect.bottomRight()); @@ -215,7 +215,7 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q p->drawArc(opt->rect, 0, 5760); if (opt->state & (State_Sunken | State_On)) { ir.adjust(2, 2, -2, -2); - p->setBrush(opt->palette.foreground()); + p->setBrush(opt->palette.windowText()); bool oldQt4CompatiblePainting = p->testRenderHint(QPainter::Qt4CompatiblePainting); p->setRenderHint(QPainter::Qt4CompatiblePainting); p->drawEllipse(ir); @@ -234,7 +234,7 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q else p->setPen(Qt::white); } else { - p->setPen(opt->palette.foreground().color()); + p->setPen(opt->palette.windowText().color()); } QRect focusRect = opt->rect.adjusted(1, 1, -1, -1); p->drawRect(focusRect.adjusted(0, 0, -1, -1)); //draw pen inclusive @@ -281,7 +281,7 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q qDrawShadePanel(p, frame->rect, frame->palette, frame->state & State_Sunken, frame->lineWidth); } else { - qDrawPlainRect(p, frame->rect, frame->palette.foreground().color(), frame->lineWidth); + qDrawPlainRect(p, frame->rect, frame->palette.windowText().color(), frame->lineWidth); } } break; @@ -618,7 +618,7 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q } p->setPen(QPen(tab->palette.dark(), qreal(.8))); - p->setBrush(tab->palette.background()); + p->setBrush(tab->palette.window()); p->setRenderHint(QPainter::Antialiasing); p->drawPath(path); } @@ -1502,7 +1502,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, QPalette pal2 = pb->palette; // Correct the highlight color if it is the same as the background - if (pal2.highlight() == pal2.background()) + if (pal2.highlight() == pal2.window()) pal2.setColor(QPalette::Highlight, pb->palette.color(QPalette::Active, QPalette::Highlight)); bool reverse = ((!vertical && (pb->direction == Qt::RightToLeft)) || vertical); @@ -1790,14 +1790,14 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, } } - p->setPen(QPen(tab->palette.foreground(), 0)); + p->setPen(QPen(tab->palette.windowText(), 0)); if (selected) { p->setBrush(tab->palette.base()); } else { if (widget && widget->parentWidget()) - p->setBrush(widget->parentWidget()->palette().background()); + p->setBrush(widget->parentWidget()->palette().window()); else - p->setBrush(tab->palette.background()); + p->setBrush(tab->palette.window()); } int y; @@ -2121,7 +2121,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, } break; case CE_FocusFrame: - p->fillRect(opt->rect, opt->palette.foreground()); + p->fillRect(opt->rect, opt->palette.windowText()); break; case CE_HeaderSection: qDrawShadePanel(p, opt->rect, opt->palette, @@ -2129,7 +2129,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, &opt->palette.brush(QPalette::Button)); break; case CE_HeaderEmptyArea: - p->fillRect(opt->rect, opt->palette.background()); + p->fillRect(opt->rect, opt->palette.window()); break; #if QT_CONFIG(combobox) case CE_ComboBoxLabel: @@ -3193,7 +3193,7 @@ void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCompl // Since there is no subrect for tickmarks do a translation here. p->save(); p->translate(slider->rect.x(), slider->rect.y()); - p->setPen(slider->palette.foreground().color()); + p->setPen(slider->palette.windowText().color()); int v = slider->minimum; while (v <= slider->maximum + 1) { if (v == slider->maximum + 1 && interval == 1) @@ -3639,7 +3639,7 @@ void QCommonStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCompl QPalette pal = opt->palette; // draw notches if (dial->subControls & QStyle::SC_DialTickmarks) { - p->setPen(pal.foreground().color()); + p->setPen(pal.windowText().color()); p->drawLines(QStyleHelper::calcLines(dial)); } diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp index 85c7a35a72..cada64a646 100644 --- a/src/widgets/styles/qfusionstyle.cpp +++ b/src/widgets/styles/qfusionstyle.cpp @@ -539,7 +539,7 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, { if (option->rect.width() <= 1 || option->rect.height() <= 1) break; - QColor arrowColor = option->palette.foreground().color(); + QColor arrowColor = option->palette.windowText().color(); arrowColor.setAlpha(160); Qt::ArrowType arrow = Qt::UpArrow; switch (elem) { @@ -569,7 +569,7 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, case PE_IndicatorHeaderArrow: if (const QStyleOptionHeader *header = qstyleoption_cast(option)) { QRect r = header->rect; - QColor arrowColor = header->palette.foreground().color(); + QColor arrowColor = header->palette.windowText().color(); arrowColor.setAlpha(180); QPoint offset = QPoint(0, -2); @@ -598,24 +598,24 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, const int margin = 6; if (option->state & State_Horizontal) { const int offset = rect.width()/2; - painter->setPen(QPen(option->palette.background().color().darker(110))); + painter->setPen(QPen(option->palette.window().color().darker(110))); painter->drawLine(rect.bottomLeft().x() + offset, rect.bottomLeft().y() - margin, rect.topLeft().x() + offset, rect.topLeft().y() + margin); - painter->setPen(QPen(option->palette.background().color().lighter(110))); + painter->setPen(QPen(option->palette.window().color().lighter(110))); painter->drawLine(rect.bottomLeft().x() + offset + 1, rect.bottomLeft().y() - margin, rect.topLeft().x() + offset + 1, rect.topLeft().y() + margin); } else { //Draw vertical separator const int offset = rect.height()/2; - painter->setPen(QPen(option->palette.background().color().darker(110))); + painter->setPen(QPen(option->palette.window().color().darker(110))); painter->drawLine(rect.topLeft().x() + margin , rect.topLeft().y() + offset, rect.topRight().x() - margin, rect.topRight().y() + offset); - painter->setPen(QPen(option->palette.background().color().lighter(110))); + painter->setPen(QPen(option->palette.window().color().lighter(110))); painter->drawLine(rect.topLeft().x() + margin , rect.topLeft().y() + offset + 1, rect.topRight().x() - margin, @@ -642,8 +642,8 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, { painter->setPen(QPen(outline)); painter->drawRect(option->rect.adjusted(0, 0, -1, -1)); - QColor frameLight = option->palette.background().color().lighter(160); - QColor frameShadow = option->palette.background().color().darker(110); + QColor frameLight = option->palette.window().color().lighter(160); + QColor frameShadow = option->palette.window().color().darker(110); //paint beveleffect QRect frame = option->rect.adjusted(1, 1, -1, -1); @@ -661,14 +661,14 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, painter->save(); { - QColor softshadow = option->palette.background().color().darker(120); + QColor softshadow = option->palette.window().color().darker(120); QRect rect= option->rect; painter->setPen(softshadow); painter->drawRect(option->rect.adjusted(0, 0, -1, -1)); painter->setPen(QPen(option->palette.light(), 1)); painter->drawLine(QPoint(rect.left() + 1, rect.top() + 1), QPoint(rect.left() + 1, rect.bottom() - 1)); - painter->setPen(QPen(option->palette.background().color().darker(120))); + painter->setPen(QPen(option->palette.window().color().darker(120))); painter->drawLine(QPoint(rect.left() + 1, rect.bottom() - 1), QPoint(rect.right() - 2, rect.bottom() - 1)); painter->drawLine(QPoint(rect.right() - 1, rect.top() + 1), QPoint(rect.right() - 1, rect.bottom() - 1)); @@ -704,7 +704,7 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, painter->setPen(QPen(option->palette.light(), 1)); painter->drawLine(QPoint(rect.left() + 1, rect.top() + 1), QPoint(rect.left() + 1, rect.bottom() - 1)); - painter->setPen(QPen(option->palette.background().color().darker(120))); + painter->setPen(QPen(option->palette.window().color().darker(120))); painter->drawLine(QPoint(rect.left() + 1, rect.bottom() - 1), QPoint(rect.right() - 2, rect.bottom() - 1)); painter->drawLine(QPoint(rect.right() - 1, rect.top() + 1), @@ -748,7 +748,7 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, painter->translate(0.5, 0.5); rect = rect.adjusted(0, 0, -1, -1); - QColor pressedColor = mergedColors(option->palette.base().color(), option->palette.foreground().color(), 85); + QColor pressedColor = mergedColors(option->palette.base().color(), option->palette.windowText().color(), 85); painter->setBrush(Qt::NoBrush); // Gradient fill @@ -802,14 +802,14 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, case PE_IndicatorRadioButton: painter->save(); { - QColor pressedColor = mergedColors(option->palette.base().color(), option->palette.foreground().color(), 85); + QColor pressedColor = mergedColors(option->palette.base().color(), option->palette.windowText().color(), 85); painter->setBrush((state & State_Sunken) ? pressedColor : option->palette.base().color()); painter->setRenderHint(QPainter::Antialiasing, true); QPainterPath circle; const QPointF circleCenter = rect.center() + QPoint(1, 1); const qreal outlineRadius = (rect.width() + (rect.width() + 1) % 2) / 2.0 - 1; circle.addEllipse(circleCenter, outlineRadius, outlineRadius); - painter->setPen(QPen(option->palette.background().color().darker(150))); + painter->setPen(QPen(option->palette.window().color().darker(150))); if (option->state & State_HasFocus && option->state & State_KeyboardFocusChange) painter->setPen(QPen(highlightedOutline)); painter->drawPath(circle); @@ -991,7 +991,7 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, case PE_PanelMenu: { painter->save(); const QBrush menuBackground = option->palette.base().color().lighter(108); - QColor borderColor = option->palette.background().color().darker(160); + QColor borderColor = option->palette.window().color().darker(160); qDrawPlainRect(painter, option->rect, borderColor, 1, &menuBackground); painter->restore(); } @@ -1283,8 +1283,8 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio gradientStopColor = buttonColor.darker(102); QLinearGradient gradient(pixmapRect.topLeft(), pixmapRect.bottomLeft()); - if (option->palette.background().gradient()) { - gradient.setStops(option->palette.background().gradient()->stops()); + if (option->palette.window().gradient()) { + gradient.setStops(option->palette.window().gradient()->stops()); } else { QColor midColor1 = mergedColors(gradientStartColor, gradientStopColor, 60); QColor midColor2 = mergedColors(gradientStartColor, gradientStopColor, 40); @@ -1519,7 +1519,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio proxy()->drawItemText(painter, item.rect, alignment, mbi->palette, mbi->state & State_Enabled, mbi->text, textRole); } else { - QColor shadow = mergedColors(option->palette.background().color().darker(120), + QColor shadow = mergedColors(option->palette.window().color().darker(120), outline.lighter(140), 60); painter->setPen(QPen(shadow)); painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight()); @@ -1649,7 +1649,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio if (!ignoreCheckMark && checkable && checked) { QStyleOption opt = *option; if (act) { - QColor activeColor = mergedColors(option->palette.background().color(), + QColor activeColor = mergedColors(option->palette.window().color(), option->palette.highlight().color()); opt.palette.setBrush(QPalette::Button, activeColor); } @@ -1731,7 +1731,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio newMI.rect = vSubMenuRect; newMI.state = !enabled ? State_None : State_Enabled; if (selected) - newMI.palette.setColor(QPalette::Foreground, + newMI.palette.setColor(QPalette::WindowText, newMI.palette.highlightedText().color()); proxy()->drawPrimitive(arrow, &newMI, painter, widget); } @@ -1812,7 +1812,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio painter->save(); { painter->fillRect(rect, option->palette.window()); - QColor shadow = mergedColors(option->palette.background().color().darker(120), + QColor shadow = mergedColors(option->palette.window().color().darker(120), outline.lighter(140), 60); painter->setPen(QPen(shadow)); painter->drawLine(option->rect.bottomLeft(), option->rect.bottomRight()); @@ -1975,7 +1975,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption // ### backgroundrole/foregroundrole should be part of the style option alphaCornerColor = mergedColors(option->palette.color(widget->backgroundRole()), outline); } else { - alphaCornerColor = mergedColors(option->palette.background().color(), outline); + alphaCornerColor = mergedColors(option->palette.window().color(), outline); } switch (control) { @@ -2039,7 +2039,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption QRect rect = pixmapRect; QRect r = rect.adjusted(0, 1, 0, -1); QPainter cachePainter(&cache); - QColor arrowColor = spinBox->palette.foreground().color(); + QColor arrowColor = spinBox->palette.windowText().color(); arrowColor.setAlpha(160); bool isEnabled = (spinBox->state & State_Enabled); @@ -2174,13 +2174,13 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption QColor highlight = option->palette.highlight().color(); QColor titleBarFrameBorder(active ? highlight.darker(180): outline.darker(110)); - QColor titleBarHighlight(active ? highlight.lighter(120): palette.background().color().lighter(120)); + QColor titleBarHighlight(active ? highlight.lighter(120): palette.window().color().lighter(120)); QColor textColor(active ? 0xffffff : 0xff000000); QColor textAlphaColor(active ? 0xffffff : 0xff000000 ); { // Fill title bar gradient - QColor titlebarColor = QColor(active ? highlight: palette.background().color()); + QColor titlebarColor = QColor(active ? highlight: palette.window().color()); QLinearGradient gradient(option->rect.center().x(), option->rect.top(), option->rect.center().x(), option->rect.bottom()); @@ -2531,7 +2531,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption QColor alphaOutline = outline; alphaOutline.setAlpha(180); - QColor arrowColor = option->palette.foreground().color(); + QColor arrowColor = option->palette.windowText().color(); arrowColor.setAlpha(160); const QColor bgColor = QStyleHelper::backgroundColor(option->palette, widget); @@ -3705,7 +3705,7 @@ int QFusionStyle::styleHint(StyleHint hint, const QStyleOption *option, const QW return 0; case SH_Table_GridLineColor: - return option ? option->palette.background().color().darker(120).rgb() : 0; + return option ? option->palette.window().color().darker(120).rgb() : 0; case SH_MessageBox_TextInteractionFlags: return Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse; diff --git a/src/widgets/styles/qfusionstyle_p_p.h b/src/widgets/styles/qfusionstyle_p_p.h index 169fd9a407..a92041fcfe 100644 --- a/src/widgets/styles/qfusionstyle_p_p.h +++ b/src/widgets/styles/qfusionstyle_p_p.h @@ -113,7 +113,7 @@ public: QColor outline(const QPalette &pal) const { if (pal.window().style() == Qt::TexturePattern) return QColor(0, 0, 0, 160); - return pal.background().color().darker(140); + return pal.window().color().darker(140); } QColor highlightedOutline(const QPalette &pal) const { diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp index 12ca5201c1..5ad0666932 100644 --- a/src/widgets/styles/qwindowsstyle.cpp +++ b/src/widgets/styles/qwindowsstyle.cpp @@ -248,7 +248,7 @@ void QWindowsStyle::polish(QApplication *app) d->activeGradientCaptionColor = app->palette().highlight() .color(); d->inactiveCaptionColor = app->palette().dark().color(); d->inactiveGradientCaptionColor = app->palette().dark().color(); - d->inactiveCaptionText = app->palette().background().color(); + d->inactiveCaptionText = app->palette().window().color(); #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) //fetch native title bar colors if(app->desktopSettingsAware()){ @@ -817,7 +817,7 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, else if (opt->state & State_Enabled) fill = opt->palette.base(); else - fill = opt->palette.background(); + fill = opt->palette.window(); p->save(); doRestore = true; qDrawWinPanel(p, opt->rect, opt->palette, true, &fill); @@ -951,14 +951,14 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, if (frame->lineWidth == 2 || pe == PE_Frame) { QPalette popupPal = frame->palette; if (pe == PE_FrameMenu) { - popupPal.setColor(QPalette::Light, frame->palette.background().color()); + popupPal.setColor(QPalette::Light, frame->palette.window().color()); popupPal.setColor(QPalette::Midlight, frame->palette.light().color()); } if (pe == PE_Frame && (frame->state & State_Raised)) qDrawWinButton(p, frame->rect, popupPal, frame->state & State_Sunken); else if (pe == PE_Frame && (frame->state & State_Sunken)) { - popupPal.setColor(QPalette::Midlight, frame->palette.background().color()); + popupPal.setColor(QPalette::Midlight, frame->palette.window().color()); qDrawWinPanel(p, frame->rect, popupPal, frame->state & State_Sunken); } else @@ -968,7 +968,7 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, } } else { QPalette popupPal = opt->palette; - popupPal.setColor(QPalette::Light, opt->palette.background().color()); + popupPal.setColor(QPalette::Light, opt->palette.window().color()); popupPal.setColor(QPalette::Midlight, opt->palette.light().color()); qDrawWinPanel(p, opt->rect, popupPal, opt->state & State_Sunken); } @@ -996,7 +996,7 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, break; } case PE_FrameWindow: { QPalette popupPal = opt->palette; - popupPal.setColor(QPalette::Light, opt->palette.background().color()); + popupPal.setColor(QPalette::Light, opt->palette.window().color()); popupPal.setColor(QPalette::Midlight, opt->palette.light().color()); qDrawWinPanel(p, opt->rect, popupPal, opt->state & State_Sunken); break; } @@ -1315,12 +1315,12 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai x2 -= onlyOne || lastTab ? borderThinkness : 0; } - p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 2), tab->palette.background()); + p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 2), tab->palette.window()); // Delete border if (selected) { - p->fillRect(QRect(x1,y2-1,x2-x1,1), tab->palette.background()); - p->fillRect(QRect(x1,y2,x2-x1,1), tab->palette.background()); + p->fillRect(QRect(x1,y2-1,x2-x1,1), tab->palette.window()); + p->fillRect(QRect(x1,y2,x2-x1,1), tab->palette.window()); } // Left if (firstTab || selected || onlyOne || !previousSelected) { @@ -1351,12 +1351,12 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai x2 -= lastTab ? borderThinkness : 0; } - p->fillRect(QRect(x1 + 1, y1 + 2, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.background()); + p->fillRect(QRect(x1 + 1, y1 + 2, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.window()); // Delete border if (selected) { - p->fillRect(QRect(x1, y1 + 1, (x2 - 1)-x1, 1), tab->palette.background()); - p->fillRect(QRect(x1, y1, (x2 - 1)-x1, 1), tab->palette.background()); + p->fillRect(QRect(x1, y1 + 1, (x2 - 1)-x1, 1), tab->palette.window()); + p->fillRect(QRect(x1, y1, (x2 - 1)-x1, 1), tab->palette.window()); } // Left if (firstTab || selected || onlyOne || !previousSelected) { @@ -1389,12 +1389,12 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai y2 -= lastTab ? borderThinkness : 0; } - p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 2, (y2 - y1) - 1), tab->palette.background()); + p->fillRect(QRect(x1 + 1, y1 + 1, (x2 - x1) - 2, (y2 - y1) - 1), tab->palette.window()); // Delete border if (selected) { - p->fillRect(QRect(x2 - 1, y1, 1, y2-y1), tab->palette.background()); - p->fillRect(QRect(x2, y1, 1, y2-y1), tab->palette.background()); + p->fillRect(QRect(x2 - 1, y1, 1, y2-y1), tab->palette.window()); + p->fillRect(QRect(x2, y1, 1, y2-y1), tab->palette.window()); } // Top if (firstTab || selected || onlyOne || !previousSelected) { @@ -1427,12 +1427,12 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai y2 -= lastTab ? borderThinkness : 0; } - p->fillRect(QRect(x1 + 2, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.background()); + p->fillRect(QRect(x1 + 2, y1 + 1, (x2 - x1) - 1, (y2 - y1) - 1), tab->palette.window()); // Delete border if (selected) { - p->fillRect(QRect(x1 + 1, y1, 1, (y2 - 1)-y1),tab->palette.background()); - p->fillRect(QRect(x1, y1, 1, (y2-1)-y1), tab->palette.background()); + p->fillRect(QRect(x1 + 1, y1, 1, (y2 - 1)-y1),tab->palette.window()); + p->fillRect(QRect(x1, y1, 1, (y2-1)-y1), tab->palette.window()); } // Top if (firstTab || selected || onlyOne || !previousSelected) { @@ -1526,7 +1526,7 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai br = QBrush(paletteBrush.textureImage()); } else br = QBrush(opt->palette.light().color(), Qt::Dense4Pattern); - p->setBackground(opt->palette.background().color()); + p->setBackground(opt->palette.window().color()); p->setBrush(br); } p->drawRect(opt->rect); @@ -1693,7 +1693,7 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai } QPalette pal2 = pb->palette; // Correct the highlight color if it is the same as the background - if (pal2.highlight() == pal2.background()) + if (pal2.highlight() == pal2.window()) pal2.setColor(QPalette::Highlight, pb->palette.color(QPalette::Active, QPalette::Highlight)); bool reverse = ((!vertical && (pb->direction == Qt::RightToLeft)) || vertical); @@ -1843,7 +1843,7 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai p->setBackground(cb->palette.highlight()); } else { p->setPen(cb->palette.text().color()); - p->setBackground(cb->palette.background()); + p->setBackground(cb->palette.window()); } } QCommonStyle::drawControl(ce, opt, p, widget); @@ -2185,7 +2185,7 @@ void QWindowsStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComp } else { p->setPen(cmb->palette.text().color()); - p->setBackground(cmb->palette.background()); + p->setBackground(cmb->palette.window()); } if (cmb->state & State_HasFocus && !cmb->editable) { From 4c522e0226da1bcc67a585130e3b2a976be128fd Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sun, 16 Dec 2018 13:19:22 +0100 Subject: [PATCH 0671/1650] QPalette: mark foreground()/background() as deprecated MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QPalette::foreground()/background()/ColorRole::Foreground/Background are deprecated since Qt4 times. Therefore mark them as deprecated so they can be removed in Qt6. Change-Id: I24a47e080241b7f16b8adde1f9f16e29133462a7 Reviewed-by: Lars Knoll Reviewed-by: André Hartmann --- src/gui/kernel/qpalette.cpp | 2 +- src/gui/kernel/qpalette.h | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/gui/kernel/qpalette.cpp b/src/gui/kernel/qpalette.cpp index 9ccfb9b819..16b1f847bd 100644 --- a/src/gui/kernel/qpalette.cpp +++ b/src/gui/kernel/qpalette.cpp @@ -981,7 +981,7 @@ QPalette QPalette::resolve(const QPalette &other) const #ifndef QT_NO_DATASTREAM static const int NumOldRoles = 7; -static const int oldRoles[7] = { QPalette::Foreground, QPalette::Background, QPalette::Light, +static const int oldRoles[7] = { QPalette::WindowText, QPalette::Window, QPalette::Light, QPalette::Dark, QPalette::Mid, QPalette::Text, QPalette::Base }; /*! diff --git a/src/gui/kernel/qpalette.h b/src/gui/kernel/qpalette.h index 071eddbc4d..e931e01480 100644 --- a/src/gui/kernel/qpalette.h +++ b/src/gui/kernel/qpalette.h @@ -98,7 +98,10 @@ public: ToolTipBase, ToolTipText, PlaceholderText, NColorRoles = PlaceholderText + 1, - Foreground = WindowText, Background = Window +#if QT_DEPRECATED_SINCE(5, 13) + Foreground Q_DECL_ENUMERATOR_DEPRECATED_X("Use QPalette::WindowText instead") = WindowText, + Background Q_DECL_ENUMERATOR_DEPRECATED_X("Use QPalette::Window instead") = Window +#endif }; Q_ENUM(ColorRole) @@ -121,7 +124,6 @@ public: inline const QColor &color(ColorRole cr) const { return color(Current, cr); } inline const QBrush &brush(ColorRole cr) const { return brush(Current, cr); } - inline const QBrush &foreground() const { return brush(WindowText); } inline const QBrush &windowText() const { return brush(WindowText); } inline const QBrush &button() const { return brush(Button); } inline const QBrush &light() const { return brush(Light); } @@ -132,7 +134,6 @@ public: inline const QBrush &alternateBase() const { return brush(AlternateBase); } inline const QBrush &toolTipBase() const { return brush(ToolTipBase); } inline const QBrush &toolTipText() const { return brush(ToolTipText); } - inline const QBrush &background() const { return brush(Window); } inline const QBrush &window() const { return brush(Window); } inline const QBrush &midlight() const { return brush(Midlight); } inline const QBrush &brightText() const { return brush(BrightText); } @@ -143,6 +144,12 @@ public: inline const QBrush &link() const { return brush(Link); } inline const QBrush &linkVisited() const { return brush(LinkVisited); } inline const QBrush &placeholderText() const { return brush(PlaceholderText); } +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X("Use QPalette::windowText() instead") + inline const QBrush &foreground() const { return windowText(); } + QT_DEPRECATED_X("Use QPalette::window() instead") + inline const QBrush &background() const { return window(); } +#endif bool operator==(const QPalette &p) const; inline bool operator!=(const QPalette &p) const { return !(operator==(p)); } From 7ec7f338bc7c14cfd68be7d743bbffeb70c5e239 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sun, 16 Dec 2018 13:12:52 +0100 Subject: [PATCH 0672/1650] XCB plugin: replace deprecated QList::swap() QList::swap(int, int) was deprecated. Replace it with swapItemsAt() Change-Id: I077c5b7222e40b928ee9035b8cbf4ebcc91aa15e Reviewed-by: Lars Knoll --- src/plugins/platforms/xcb/qxcbscreen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index 57dbdc9bec..0fa0e8cd7b 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -147,7 +147,7 @@ void QXcbVirtualDesktop::setPrimaryScreen(QPlatformScreen *s) { const int idx = m_screens.indexOf(s); Q_ASSERT(idx > -1); - m_screens.swap(0, idx); + m_screens.swapItemsAt(0, idx); } QXcbXSettings *QXcbVirtualDesktop::xSettings() const From b8720e3e7a93121cd2e6dc081d872e8000ce81c9 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sun, 2 Dec 2018 14:39:55 +0100 Subject: [PATCH 0673/1650] Cleanup Widgets examples - Validator example Cleanup the widgets examples - move the ValidatorWidget class into its own source/header file instead of implementing it in main.cpp Change-Id: I2b74ca4f2491168453dc31e0631f31e3ac83123c Reviewed-by: Konstantin Shegunov Reviewed-by: Samuel Gaist Reviewed-by: Richard Moe Gustavsen --- examples/widgets/widgets/validators/main.cpp | 85 +----------- .../widgets/widgets/validators/validators.pro | 4 +- .../widgets/validators/validatorwidget.cpp | 122 ++++++++++++++++++ .../widgets/validators/validatorwidget.h | 64 +++++++++ 4 files changed, 190 insertions(+), 85 deletions(-) create mode 100644 examples/widgets/widgets/validators/validatorwidget.cpp create mode 100644 examples/widgets/widgets/validators/validatorwidget.h diff --git a/examples/widgets/widgets/validators/main.cpp b/examples/widgets/widgets/validators/main.cpp index d8ba2943d0..1fbf12410d 100644 --- a/examples/widgets/widgets/validators/main.cpp +++ b/examples/widgets/widgets/validators/main.cpp @@ -48,88 +48,9 @@ ** ****************************************************************************/ -#include +#include "validatorwidget.h" + #include -#include -#include - -#include "ui_validators.h" - -class ValidatorWidget : public QWidget, public Ui::ValidatorsForm -{ - Q_OBJECT -public: - ValidatorWidget(QWidget *parent = 0); - -private slots: - void updateValidator(); - void updateDoubleValidator(); - void _setLocale(const QLocale &l) { setLocale(l); updateValidator(); updateDoubleValidator(); } - -private: - QIntValidator *validator; - QDoubleValidator *doubleValidator; -}; - -ValidatorWidget::ValidatorWidget(QWidget *parent) - : QWidget(parent) -{ - setupUi(this); - - connect(localeSelector, SIGNAL(localeSelected(QLocale)), this, SLOT(_setLocale(QLocale))); - - connect(minVal, SIGNAL(editingFinished()), this, SLOT(updateValidator())); - connect(maxVal, SIGNAL(editingFinished()), this, SLOT(updateValidator())); - connect(editor, SIGNAL(editingFinished()), ledWidget, SLOT(flash())); - - connect(doubleMaxVal, SIGNAL(editingFinished()), this, SLOT(updateDoubleValidator())); - connect(doubleMinVal, SIGNAL(editingFinished()), this, SLOT(updateDoubleValidator())); - connect(doubleDecimals, SIGNAL(valueChanged(int)), this, SLOT(updateDoubleValidator())); - connect(doubleFormat, SIGNAL(activated(int)), this, SLOT(updateDoubleValidator())); - connect(doubleEditor, SIGNAL(editingFinished()), doubleLedWidget, SLOT(flash())); - - validator = 0; - doubleValidator = 0; - updateValidator(); - updateDoubleValidator(); -}; - -void ValidatorWidget::updateValidator() -{ - QIntValidator *v = new QIntValidator(minVal->value(), maxVal->value(), this); - v->setLocale(locale()); - editor->setValidator(v); - delete validator; - validator = v; - - QString s = editor->text(); - int i = 0; - if (validator->validate(s, i) == QValidator::Invalid) { - editor->clear(); - } else { - editor->setText(s); - } -} - -void ValidatorWidget::updateDoubleValidator() -{ - QDoubleValidator *v - = new QDoubleValidator(doubleMinVal->value(), doubleMaxVal->value(), - doubleDecimals->value(), this); - v->setNotation(static_cast(doubleFormat->currentIndex())); - v->setLocale(locale()); - doubleEditor->setValidator(v); - delete doubleValidator; - doubleValidator = v; - - QString s = doubleEditor->text(); - int i = 0; - if (doubleValidator->validate(s, i) == QValidator::Invalid) { - doubleEditor->clear(); - } else { - doubleEditor->setText(s); - } -} int main(int argc, char **argv) { @@ -142,5 +63,3 @@ int main(int argc, char **argv) return app.exec(); } - -#include "main.moc" diff --git a/examples/widgets/widgets/validators/validators.pro b/examples/widgets/widgets/validators/validators.pro index ab1eb7809b..029cf95aca 100644 --- a/examples/widgets/widgets/validators/validators.pro +++ b/examples/widgets/widgets/validators/validators.pro @@ -4,8 +4,8 @@ requires(qtConfig(combobox)) FORMS += validators.ui RESOURCES += validators.qrc -SOURCES += main.cpp ledwidget.cpp localeselector.cpp -HEADERS += ledwidget.h localeselector.h +SOURCES += main.cpp ledwidget.cpp localeselector.cpp validatorwidget.cpp +HEADERS += ledwidget.h localeselector.h validatorwidget.h # install target.path = $$[QT_INSTALL_EXAMPLES]/widgets/widgets/validators diff --git a/examples/widgets/widgets/validators/validatorwidget.cpp b/examples/widgets/widgets/validators/validatorwidget.cpp new file mode 100644 index 0000000000..fa0a55aa52 --- /dev/null +++ b/examples/widgets/widgets/validators/validatorwidget.cpp @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "validatorwidget.h" + +#include + +ValidatorWidget::ValidatorWidget(QWidget *parent) + : QWidget(parent) +{ + setupUi(this); + + connect(localeSelector, &LocaleSelector::localeSelected, + this, &ValidatorWidget::setLocale); + connect(localeSelector, &LocaleSelector::localeSelected, + this, &ValidatorWidget::updateValidator); + connect(localeSelector, &LocaleSelector::localeSelected, + this, &ValidatorWidget::updateDoubleValidator); + + connect(minVal, &QSpinBox::editingFinished, + this, &ValidatorWidget::updateValidator); + connect(maxVal, &QSpinBox::editingFinished, + this, &ValidatorWidget::updateValidator); + connect(editor, &QLineEdit::editingFinished, + ledWidget, &LEDWidget::flash); + + connect(doubleMaxVal, &QDoubleSpinBox::editingFinished, + this, &ValidatorWidget::updateDoubleValidator); + connect(doubleMinVal, &QDoubleSpinBox::editingFinished, + this, &ValidatorWidget::updateDoubleValidator); + connect(doubleDecimals, QOverload::of(&QSpinBox::valueChanged), + this, &ValidatorWidget::updateDoubleValidator); + connect(doubleFormat, QOverload::of(&QComboBox::activated), + this, &ValidatorWidget::updateDoubleValidator); + connect(doubleEditor, &QLineEdit::editingFinished, + doubleLedWidget, &LEDWidget::flash); + + updateValidator(); + updateDoubleValidator(); +} + +void ValidatorWidget::updateValidator() +{ + QIntValidator *v = new QIntValidator(minVal->value(), maxVal->value(), this); + v->setLocale(locale()); + delete editor->validator(); + editor->setValidator(v); + + QString s = editor->text(); + int i = 0; + if (v->validate(s, i) == QValidator::Invalid) { + editor->clear(); + } else { + editor->setText(s); + } +} + +void ValidatorWidget::updateDoubleValidator() +{ + QDoubleValidator *v + = new QDoubleValidator(doubleMinVal->value(), doubleMaxVal->value(), + doubleDecimals->value(), this); + v->setNotation(static_cast(doubleFormat->currentIndex())); + v->setLocale(locale()); + delete doubleEditor->validator(); + doubleEditor->setValidator(v); + + QString s = doubleEditor->text(); + int i = 0; + if (v->validate(s, i) == QValidator::Invalid) { + doubleEditor->clear(); + } else { + doubleEditor->setText(s); + } +} diff --git a/examples/widgets/widgets/validators/validatorwidget.h b/examples/widgets/widgets/validators/validatorwidget.h new file mode 100644 index 0000000000..bcc4a9b91e --- /dev/null +++ b/examples/widgets/widgets/validators/validatorwidget.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "ui_validators.h" + +class ValidatorWidget : public QWidget, public Ui::ValidatorsForm +{ + Q_OBJECT +public: + ValidatorWidget(QWidget *parent = nullptr); + +private slots: + void updateValidator(); + void updateDoubleValidator(); +}; From af84f12298e7ba51d4121f9dd7a1b6e3ba050266 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sat, 24 Nov 2018 17:29:15 +0100 Subject: [PATCH 0674/1650] Cleanup Itemviews examples Cleanup the Itemviews examples - use nullptr instead 0 - use for loop instead foreach - include own header first - remove uselss includes Change-Id: I32e9f64356e42038707d063dcad977239ce1fe9e Reviewed-by: Luca Beldi Reviewed-by: Sze Howe Koh --- .../coloreditorfactory/colorlisteditor.cpp | 10 ++++---- .../coloreditorfactory/colorlisteditor.h | 4 +-- .../itemviews/coloreditorfactory/window.cpp | 17 ++++++------- .../customsortfiltermodel/filterwidget.cpp | 5 ++-- .../customsortfiltermodel/filterwidget.h | 2 +- .../mysortfilterproxymodel.cpp | 6 ++--- .../customsortfiltermodel/window.cpp | 13 +++++++--- .../itemviews/fetchmore/filelistmodel.cpp | 25 +++++++++---------- .../itemviews/fetchmore/filelistmodel.h | 3 +-- .../widgets/itemviews/fetchmore/window.cpp | 4 +-- examples/widgets/itemviews/fetchmore/window.h | 2 +- .../widgets/itemviews/interview/model.cpp | 3 +-- examples/widgets/itemviews/interview/model.h | 4 +-- .../itemviews/pixelator/mainwindow.cpp | 2 +- .../itemviews/pixelator/pixeldelegate.cpp | 14 +++++------ .../itemviews/pixelator/pixeldelegate.h | 6 ++--- .../widgets/itemviews/puzzle/piecesmodel.cpp | 9 +++---- .../widgets/itemviews/puzzle/piecesmodel.h | 10 ++++---- .../itemviews/simplewidgetmapper/window.h | 2 +- .../itemviews/spinboxdelegate/delegate.cpp | 7 +++--- .../itemviews/spinboxdelegate/delegate.h | 6 ++--- .../widgets/itemviews/storageview/main.cpp | 7 +++--- .../itemviews/storageview/storagemodel.cpp | 8 ------ .../itemviews/storageview/storagemodel.h | 2 +- 24 files changed, 79 insertions(+), 92 deletions(-) diff --git a/examples/widgets/itemviews/coloreditorfactory/colorlisteditor.cpp b/examples/widgets/itemviews/coloreditorfactory/colorlisteditor.cpp index 75d809a44f..0b65c53477 100644 --- a/examples/widgets/itemviews/coloreditorfactory/colorlisteditor.cpp +++ b/examples/widgets/itemviews/coloreditorfactory/colorlisteditor.cpp @@ -48,10 +48,10 @@ ** ****************************************************************************/ -#include - #include "colorlisteditor.h" +#include + ColorListEditor::ColorListEditor(QWidget *widget) : QComboBox(widget) { populateList(); @@ -65,16 +65,16 @@ QColor ColorListEditor::color() const //! [0] //! [1] -void ColorListEditor::setColor(QColor color) +void ColorListEditor::setColor(const QColor &color) { - setCurrentIndex(findData(color, int(Qt::DecorationRole))); + setCurrentIndex(findData(color, Qt::DecorationRole)); } //! [1] //! [2] void ColorListEditor::populateList() { - QStringList colorNames = QColor::colorNames(); + const QStringList colorNames = QColor::colorNames(); for (int i = 0; i < colorNames.size(); ++i) { QColor color(colorNames[i]); diff --git a/examples/widgets/itemviews/coloreditorfactory/colorlisteditor.h b/examples/widgets/itemviews/coloreditorfactory/colorlisteditor.h index f284c07c89..f9d736d298 100644 --- a/examples/widgets/itemviews/coloreditorfactory/colorlisteditor.h +++ b/examples/widgets/itemviews/coloreditorfactory/colorlisteditor.h @@ -65,11 +65,11 @@ class ColorListEditor : public QComboBox Q_PROPERTY(QColor color READ color WRITE setColor USER true) public: - ColorListEditor(QWidget *widget = 0); + ColorListEditor(QWidget *widget = nullptr); public: QColor color() const; - void setColor(QColor c); + void setColor(const QColor &color); private: void populateList(); diff --git a/examples/widgets/itemviews/coloreditorfactory/window.cpp b/examples/widgets/itemviews/coloreditorfactory/window.cpp index f7ce821d31..e4a9379d8f 100644 --- a/examples/widgets/itemviews/coloreditorfactory/window.cpp +++ b/examples/widgets/itemviews/coloreditorfactory/window.cpp @@ -48,11 +48,11 @@ ** ****************************************************************************/ -#include - #include "window.h" #include "colorlisteditor.h" +#include + //! [0] Window::Window() { @@ -71,19 +71,18 @@ Window::Window() void Window::createGUI() { - QList > list; - list << QPair(tr("Alice"), QColor("aliceblue")) << - QPair(tr("Neptun"), QColor("aquamarine")) << - QPair(tr("Ferdinand"), QColor("springgreen")); + const QVector > list = + {{ tr("Alice"), QColor("aliceblue") }, + { tr("Neptun"), QColor("aquamarine") }, + { tr("Ferdinand"), QColor("springgreen") }}; QTableWidget *table = new QTableWidget(3, 2); - table->setHorizontalHeaderLabels(QStringList() << tr("Name") - << tr("Hair Color")); + table->setHorizontalHeaderLabels({ tr("Name"), tr("Hair Color") }); table->verticalHeader()->setVisible(false); table->resize(150, 50); for (int i = 0; i < 3; ++i) { - QPair pair = list.at(i); + const QPair &pair = list.at(i); QTableWidgetItem *nameItem = new QTableWidgetItem(pair.first); QTableWidgetItem *colorItem = new QTableWidgetItem; diff --git a/examples/widgets/itemviews/customsortfiltermodel/filterwidget.cpp b/examples/widgets/itemviews/customsortfiltermodel/filterwidget.cpp index 74d88caae6..302042a6b3 100644 --- a/examples/widgets/itemviews/customsortfiltermodel/filterwidget.cpp +++ b/examples/widgets/itemviews/customsortfiltermodel/filterwidget.cpp @@ -52,13 +52,11 @@ #include #include -#include #include #include #include #include #include -#include FilterWidget::FilterWidget(QWidget *parent) : QLineEdit(parent) @@ -127,7 +125,8 @@ QRegExp::PatternSyntax FilterWidget::patternSyntax() const void FilterWidget::setPatternSyntax(QRegExp::PatternSyntax s) { - foreach (QAction *a, m_patternGroup->actions()) { + const QList actions = m_patternGroup->actions(); + for (QAction *a : actions) { if (patternSyntaxFromAction(a) == s) { a->setChecked(true); break; diff --git a/examples/widgets/itemviews/customsortfiltermodel/filterwidget.h b/examples/widgets/itemviews/customsortfiltermodel/filterwidget.h index ea12954e52..70214b862e 100644 --- a/examples/widgets/itemviews/customsortfiltermodel/filterwidget.h +++ b/examples/widgets/itemviews/customsortfiltermodel/filterwidget.h @@ -67,7 +67,7 @@ class FilterWidget : public QLineEdit Q_PROPERTY(Qt::CaseSensitivity caseSensitivity READ caseSensitivity WRITE setCaseSensitivity) Q_PROPERTY(QRegExp::PatternSyntax patternSyntax READ patternSyntax WRITE setPatternSyntax) public: - explicit FilterWidget(QWidget *parent = 0); + explicit FilterWidget(QWidget *parent = nullptr); Qt::CaseSensitivity caseSensitivity() const; void setCaseSensitivity(Qt::CaseSensitivity); diff --git a/examples/widgets/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp b/examples/widgets/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp index 35426657d9..4753d04d9b 100644 --- a/examples/widgets/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp +++ b/examples/widgets/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp @@ -48,10 +48,10 @@ ** ****************************************************************************/ -#include - #include "mysortfilterproxymodel.h" +#include + //! [0] MySortFilterProxyModel::MySortFilterProxyModel(QObject *parent) : QSortFilterProxyModel(parent) @@ -77,7 +77,7 @@ void MySortFilterProxyModel::setFilterMaximumDate(const QDate &date) //! [3] bool MySortFilterProxyModel::filterAcceptsRow(int sourceRow, - const QModelIndex &sourceParent) const + const QModelIndex &sourceParent) const { QModelIndex index0 = sourceModel()->index(sourceRow, 0, sourceParent); QModelIndex index1 = sourceModel()->index(sourceRow, 1, sourceParent); diff --git a/examples/widgets/itemviews/customsortfiltermodel/window.cpp b/examples/widgets/itemviews/customsortfiltermodel/window.cpp index bfd2350da0..3356c971ad 100644 --- a/examples/widgets/itemviews/customsortfiltermodel/window.cpp +++ b/examples/widgets/itemviews/customsortfiltermodel/window.cpp @@ -48,12 +48,12 @@ ** ****************************************************************************/ -#include - -#include "mysortfilterproxymodel.h" #include "window.h" +#include "mysortfilterproxymodel.h" #include "filterwidget.h" +#include + //! [0] Window::Window() { @@ -75,7 +75,7 @@ Window::Window() //! [3] filterWidget = new FilterWidget; - filterWidget->setText("Grace|Sports"); + filterWidget->setText(tr("Grace|Sports")); connect(filterWidget, &FilterWidget::filterChanged, this, &Window::textFilterChanged); filterPatternLabel = new QLabel(tr("&Filter pattern:")); @@ -137,6 +137,11 @@ void Window::setSourceModel(QAbstractItemModel *model) { proxyModel->setSourceModel(model); sourceView->setModel(model); + + for (int i = 0; i < proxyModel->columnCount(); ++i) + proxyView->resizeColumnToContents(i); + for (int i = 0; i < model->columnCount(); ++i) + sourceView->resizeColumnToContents(i); } //! [7] diff --git a/examples/widgets/itemviews/fetchmore/filelistmodel.cpp b/examples/widgets/itemviews/fetchmore/filelistmodel.cpp index 086d45eca3..3ee80617c0 100644 --- a/examples/widgets/itemviews/fetchmore/filelistmodel.cpp +++ b/examples/widgets/itemviews/fetchmore/filelistmodel.cpp @@ -50,20 +50,18 @@ #include "filelistmodel.h" -#include -#include +#include #include #include FileListModel::FileListModel(QObject *parent) - : QAbstractListModel(parent) -{ -} + : QAbstractListModel(parent), fileCount(0) +{} //![4] -int FileListModel::rowCount(const QModelIndex & /* parent */) const +int FileListModel::rowCount(const QModelIndex &parent) const { - return fileCount; + return parent.isValid() ? 0 : fileCount; } QVariant FileListModel::data(const QModelIndex &index, int role) const @@ -88,25 +86,26 @@ QVariant FileListModel::data(const QModelIndex &index, int role) const //![4] //![1] -bool FileListModel::canFetchMore(const QModelIndex & /* index */) const +bool FileListModel::canFetchMore(const QModelIndex &parent) const { - if (fileCount < fileList.size()) - return true; - else + if (parent.isValid()) return false; + return (fileCount < fileList.size()); } //![1] //![2] -void FileListModel::fetchMore(const QModelIndex & /* index */) +void FileListModel::fetchMore(const QModelIndex &parent) { + if (parent.isValid()) + return; int remainder = fileList.size() - fileCount; int itemsToFetch = qMin(100, remainder); if (itemsToFetch <= 0) return; - beginInsertRows(QModelIndex(), fileCount, fileCount+itemsToFetch-1); + beginInsertRows(QModelIndex(), fileCount, fileCount + itemsToFetch - 1); fileCount += itemsToFetch; diff --git a/examples/widgets/itemviews/fetchmore/filelistmodel.h b/examples/widgets/itemviews/fetchmore/filelistmodel.h index 9251eaf959..35cf6f7b46 100644 --- a/examples/widgets/itemviews/fetchmore/filelistmodel.h +++ b/examples/widgets/itemviews/fetchmore/filelistmodel.h @@ -52,7 +52,6 @@ #define FILELISTMODEL_H #include -#include #include //![0] @@ -61,7 +60,7 @@ class FileListModel : public QAbstractListModel Q_OBJECT public: - FileListModel(QObject *parent = 0); + FileListModel(QObject *parent = nullptr); int rowCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; diff --git a/examples/widgets/itemviews/fetchmore/window.cpp b/examples/widgets/itemviews/fetchmore/window.cpp index 886f76d6ab..d71ac7059d 100644 --- a/examples/widgets/itemviews/fetchmore/window.cpp +++ b/examples/widgets/itemviews/fetchmore/window.cpp @@ -48,8 +48,8 @@ ** ****************************************************************************/ -#include "filelistmodel.h" #include "window.h" +#include "filelistmodel.h" #include @@ -66,7 +66,7 @@ Window::Window(QWidget *parent) QListView *view = new QListView; view->setModel(model); - logViewer = new QTextBrowser; + logViewer = new QTextBrowser(this); logViewer->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred)); connect(lineEdit, &QLineEdit::textChanged, diff --git a/examples/widgets/itemviews/fetchmore/window.h b/examples/widgets/itemviews/fetchmore/window.h index f234683785..61bcb94bde 100644 --- a/examples/widgets/itemviews/fetchmore/window.h +++ b/examples/widgets/itemviews/fetchmore/window.h @@ -62,7 +62,7 @@ class Window : public QWidget Q_OBJECT public: - Window(QWidget *parent = 0); + Window(QWidget *parent = nullptr); public slots: void updateLog(int number); diff --git a/examples/widgets/itemviews/interview/model.cpp b/examples/widgets/itemviews/interview/model.cpp index a8f3a6f31e..feaf8bb98c 100644 --- a/examples/widgets/itemviews/interview/model.cpp +++ b/examples/widgets/itemviews/interview/model.cpp @@ -50,14 +50,13 @@ #include "model.h" -#include #include Model::Model(int rows, int columns, QObject *parent) : QAbstractItemModel(parent), services(QPixmap(":/images/services.png")), rc(rows), cc(columns), - tree(new QVector(rows, Node(0))) + tree(new QVector(rows, Node())) { } diff --git a/examples/widgets/itemviews/interview/model.h b/examples/widgets/itemviews/interview/model.h index 969cf693b2..132f1d01aa 100644 --- a/examples/widgets/itemviews/interview/model.h +++ b/examples/widgets/itemviews/interview/model.h @@ -61,7 +61,7 @@ class Model : public QAbstractItemModel Q_OBJECT public: - Model(int rows, int columns, QObject *parent = 0); + Model(int rows, int columns, QObject *parent = nullptr); ~Model(); QModelIndex index(int row, int column, const QModelIndex &parent) const override; @@ -80,7 +80,7 @@ private: struct Node { - Node(Node *parent = 0) : parent(parent), children(0) {} + Node(Node *parent = nullptr) : parent(parent), children(nullptr) {} ~Node() { delete children; } Node *parent; QVector *children; diff --git a/examples/widgets/itemviews/pixelator/mainwindow.cpp b/examples/widgets/itemviews/pixelator/mainwindow.cpp index 63617f0169..f6b67e4dba 100644 --- a/examples/widgets/itemviews/pixelator/mainwindow.cpp +++ b/examples/widgets/itemviews/pixelator/mainwindow.cpp @@ -48,8 +48,8 @@ ** ****************************************************************************/ -#include "imagemodel.h" #include "mainwindow.h" +#include "imagemodel.h" #include "pixeldelegate.h" #include diff --git a/examples/widgets/itemviews/pixelator/pixeldelegate.cpp b/examples/widgets/itemviews/pixelator/pixeldelegate.cpp index ecf44c1224..dc8736c836 100644 --- a/examples/widgets/itemviews/pixelator/pixeldelegate.cpp +++ b/examples/widgets/itemviews/pixelator/pixeldelegate.cpp @@ -54,10 +54,8 @@ //! [0] PixelDelegate::PixelDelegate(QObject *parent) - : QAbstractItemDelegate(parent) -{ - pixelSize = 12; -} + : QAbstractItemDelegate(parent), pixelSize(12) +{} //! [0] //! [1] @@ -70,11 +68,11 @@ void PixelDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, //! [1] //! [3] - int size = qMin(option.rect.width(), option.rect.height()); + const int size = qMin(option.rect.width(), option.rect.height()); //! [3] //! [4] - int brightness = index.model()->data(index, Qt::DisplayRole).toInt(); - double radius = (size / 2.0) - (brightness / 255.0 * size / 2.0); - if (radius == 0.0) + const int brightness = index.model()->data(index, Qt::DisplayRole).toInt(); + const double radius = (size / 2.0) - (brightness / 255.0 * size / 2.0); + if (qFuzzyIsNull(radius)) return; //! [4] diff --git a/examples/widgets/itemviews/pixelator/pixeldelegate.h b/examples/widgets/itemviews/pixelator/pixeldelegate.h index d968d9e8d2..9f52221a28 100644 --- a/examples/widgets/itemviews/pixelator/pixeldelegate.h +++ b/examples/widgets/itemviews/pixelator/pixeldelegate.h @@ -61,7 +61,7 @@ class QObject; class QPainter; QT_END_NAMESPACE -static const int ItemSize = 256; +static constexpr int ItemSize = 256; //! [0] class PixelDelegate : public QAbstractItemDelegate @@ -69,13 +69,13 @@ class PixelDelegate : public QAbstractItemDelegate Q_OBJECT public: - PixelDelegate(QObject *parent = 0); + PixelDelegate(QObject *parent = nullptr); void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; QSize sizeHint(const QStyleOptionViewItem &option, - const QModelIndex &index ) const override; + const QModelIndex &index) const override; public slots: void setPixelSize(int size); diff --git a/examples/widgets/itemviews/puzzle/piecesmodel.cpp b/examples/widgets/itemviews/puzzle/piecesmodel.cpp index 28b46836f4..a9c53ed2cd 100644 --- a/examples/widgets/itemviews/puzzle/piecesmodel.cpp +++ b/examples/widgets/itemviews/puzzle/piecesmodel.cpp @@ -134,7 +134,7 @@ QMimeData *PiecesModel::mimeData(const QModelIndexList &indexes) const QDataStream stream(&encodedData, QIODevice::WriteOnly); - foreach (QModelIndex index, indexes) { + for (const QModelIndex &index : indexes) { if (index.isValid()) { QPixmap pixmap = qvariant_cast(data(index, Qt::UserRole)); QPoint location = data(index, Qt::UserRole+1).toPoint(); @@ -190,10 +190,7 @@ bool PiecesModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int PiecesModel::rowCount(const QModelIndex &parent) const { - if (parent.isValid()) - return 0; - else - return pixmaps.size(); + return parent.isValid() ? 0 : pixmaps.size(); } Qt::DropActions PiecesModel::supportedDropActions() const @@ -201,7 +198,7 @@ Qt::DropActions PiecesModel::supportedDropActions() const return Qt::CopyAction | Qt::MoveAction; } -void PiecesModel::addPieces(const QPixmap& pixmap) +void PiecesModel::addPieces(const QPixmap &pixmap) { if (!pixmaps.isEmpty()) { beginRemoveRows(QModelIndex(), 0, pixmaps.size() - 1); diff --git a/examples/widgets/itemviews/puzzle/piecesmodel.h b/examples/widgets/itemviews/puzzle/piecesmodel.h index bd979f4c7e..2a96603707 100644 --- a/examples/widgets/itemviews/puzzle/piecesmodel.h +++ b/examples/widgets/itemviews/puzzle/piecesmodel.h @@ -52,10 +52,10 @@ #define PIECESLIST_H #include -#include #include #include #include +#include QT_BEGIN_NAMESPACE class QMimeData; @@ -66,7 +66,7 @@ class PiecesModel : public QAbstractListModel Q_OBJECT public: - explicit PiecesModel(int pieceSize, QObject *parent = 0); + explicit PiecesModel(int pieceSize, QObject *parent = nullptr); QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; Qt::ItemFlags flags(const QModelIndex &index) const override; @@ -80,11 +80,11 @@ public: Qt::DropActions supportedDropActions() const override; void addPiece(const QPixmap &pixmap, const QPoint &location); - void addPieces(const QPixmap& pixmap); + void addPieces(const QPixmap &pixmap); private: - QList locations; - QList pixmaps; + QVector locations; + QVector pixmaps; int m_PieceSize; }; diff --git a/examples/widgets/itemviews/simplewidgetmapper/window.h b/examples/widgets/itemviews/simplewidgetmapper/window.h index baa087f8ae..d04b528e16 100644 --- a/examples/widgets/itemviews/simplewidgetmapper/window.h +++ b/examples/widgets/itemviews/simplewidgetmapper/window.h @@ -69,7 +69,7 @@ class Window : public QWidget Q_OBJECT public: - Window(QWidget *parent = 0); + Window(QWidget *parent = nullptr); private slots: void updateButtons(int row); diff --git a/examples/widgets/itemviews/spinboxdelegate/delegate.cpp b/examples/widgets/itemviews/spinboxdelegate/delegate.cpp index e7e03688c3..f0fe524a60 100644 --- a/examples/widgets/itemviews/spinboxdelegate/delegate.cpp +++ b/examples/widgets/itemviews/spinboxdelegate/delegate.cpp @@ -68,8 +68,8 @@ SpinBoxDelegate::SpinBoxDelegate(QObject *parent) //! [1] QWidget *SpinBoxDelegate::createEditor(QWidget *parent, - const QStyleOptionViewItem &/* option */, - const QModelIndex &/* index */) const + const QStyleOptionViewItem &/* option */, + const QModelIndex &/* index */) const { QSpinBox *editor = new QSpinBox(parent); editor->setFrame(false); @@ -105,7 +105,8 @@ void SpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, //! [4] void SpinBoxDelegate::updateEditorGeometry(QWidget *editor, - const QStyleOptionViewItem &option, const QModelIndex &/* index */) const + const QStyleOptionViewItem &option, + const QModelIndex &/* index */) const { editor->setGeometry(option.rect); } diff --git a/examples/widgets/itemviews/spinboxdelegate/delegate.h b/examples/widgets/itemviews/spinboxdelegate/delegate.h index 47ef1555f7..5dbdda9cd0 100644 --- a/examples/widgets/itemviews/spinboxdelegate/delegate.h +++ b/examples/widgets/itemviews/spinboxdelegate/delegate.h @@ -59,7 +59,7 @@ class SpinBoxDelegate : public QStyledItemDelegate Q_OBJECT public: - SpinBoxDelegate(QObject *parent = 0); + SpinBoxDelegate(QObject *parent = nullptr); QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; @@ -68,8 +68,8 @@ public: void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override; - void updateEditorGeometry(QWidget *editor, - const QStyleOptionViewItem &option, const QModelIndex &index) const override; + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, + const QModelIndex &index) const override; }; //! [0] diff --git a/examples/widgets/itemviews/storageview/main.cpp b/examples/widgets/itemviews/storageview/main.cpp index f349e58fad..8f23a4820a 100644 --- a/examples/widgets/itemviews/storageview/main.cpp +++ b/examples/widgets/itemviews/storageview/main.cpp @@ -49,10 +49,9 @@ ** ****************************************************************************/ -#include -#include -#include -#include +#include +#include +#include #include "storagemodel.h" diff --git a/examples/widgets/itemviews/storageview/storagemodel.cpp b/examples/widgets/itemviews/storageview/storagemodel.cpp index 063f126d86..b98fc8445c 100644 --- a/examples/widgets/itemviews/storageview/storagemodel.cpp +++ b/examples/widgets/itemviews/storageview/storagemodel.cpp @@ -53,14 +53,6 @@ #include #include -#include -#include -#include - -StorageModel::StorageModel(QObject *parent) : - QAbstractTableModel(parent) -{ -} void StorageModel::refresh() { diff --git a/examples/widgets/itemviews/storageview/storagemodel.h b/examples/widgets/itemviews/storageview/storagemodel.h index 787b2f04de..597218c220 100644 --- a/examples/widgets/itemviews/storageview/storagemodel.h +++ b/examples/widgets/itemviews/storageview/storagemodel.h @@ -74,7 +74,7 @@ public: ColumnCount }; - explicit StorageModel(QObject *parent = nullptr); + using QAbstractTableModel::QAbstractTableModel; int columnCount(const QModelIndex &parent) const override; int rowCount(const QModelIndex &parent) const override; From bd05a009f0f9119dccf912550a6b44f825a9400b Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 14 Dec 2018 16:11:01 +0100 Subject: [PATCH 0675/1650] configure: add "we mean it" blurb like all qt_*.prf files (exceptions prove the rule), the configure system counts as private api. Change-Id: Iea3057445e430029ecd8449e604e2d5c499ae10a Reviewed-by: Lars Knoll --- mkspecs/features/qt_configure.prf | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index 3483ddc5dc..c854a31f55 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -1,3 +1,13 @@ +# +# W A R N I N G +# ------------- +# +# This file is not part of the Qt API. It exists purely as an +# implementation detail. It may change from version to version +# without notice, or even be removed. +# +# We mean it. +# QT_CONFIGURE_REPORT = QT_CONFIGURE_NOTES = From 1ef9859e7e0b0d2a88acd287b5b1e4bea8b27ae8 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 12 Dec 2017 12:21:16 +0100 Subject: [PATCH 0676/1650] configure: refactor directx checks properly atomize the libraries and express their dependencies, and adjust the project files accordingly. note that we don't try to use any additional paths, as all SDKs we currently support have built-in directx 11 support: - msvc2013 comes with win sdk 8.1; that is also used for win7 targets - mingw-64 5.3 (though this one is missing fxc, which is why the code path for using an external sdk for that remains) Change-Id: Ib44e389ef46567308293c2bbcad20a96e8ef70c7 Reviewed-by: Joerg Bornemann Reviewed-by: Oliver Wolff --- src/angle/src/common/gles_common.pri | 6 +- src/angle/src/libEGL/libEGL.pro | 5 +- src/gui/configure.json | 177 ++++++++++++++---- src/gui/configure.pri | 19 +- .../fontdatabases/windows/windows.pri | 9 +- .../fontdatabases/winrt/winrt.pri | 4 +- src/plugins/platforms/direct2d/direct2d.pro | 3 +- src/plugins/platforms/platforms.pro | 6 +- src/plugins/platforms/windows/windows.pri | 2 + src/plugins/platforms/winrt/winrt.pro | 3 +- 10 files changed, 168 insertions(+), 66 deletions(-) diff --git a/src/angle/src/common/gles_common.pri b/src/angle/src/common/gles_common.pri index fdd0e45971..70b65dd4cc 100644 --- a/src/angle/src/common/gles_common.pri +++ b/src/angle/src/common/gles_common.pri @@ -8,11 +8,11 @@ INCLUDEPATH += \ # Remember to adapt src/gui/configure.* if the Direct X version changes. !winrt: \ - LIBS_PRIVATE += -ld3d9 + QMAKE_USE_PRIVATE += d3d9 winrt: \ - LIBS_PRIVATE += -ld3dcompiler -ldxgi -ld3d11 + QMAKE_USE_PRIVATE += d3dcompiler d3d11 dxgi -LIBS_PRIVATE += -ldxguid +QMAKE_USE_PRIVATE += dxguid STATICLIBS = translator preprocessor for(libname, STATICLIBS) { diff --git a/src/angle/src/libEGL/libEGL.pro b/src/angle/src/libEGL/libEGL.pro index 889f39890e..912ff7825e 100644 --- a/src/angle/src/libEGL/libEGL.pro +++ b/src/angle/src/libEGL/libEGL.pro @@ -1,9 +1,10 @@ include(../common/common.pri) DEF_FILE_TARGET = $${TARGET} TARGET = $$qtLibraryTarget($${LIBEGL_NAME}) -winrt: LIBS_PRIVATE += -ld3d11 +winrt: QMAKE_USE_PRIVATE += d3d11 +QMAKE_USE_PRIVATE += dxguid -LIBS_PRIVATE += -ldxguid -L$$QT_BUILD_TREE/lib -l$$qtLibraryTarget($${LIBGLESV2_NAME}) +LIBS_PRIVATE += -L$$QT_BUILD_TREE/lib -l$$qtLibraryTarget($${LIBGLESV2_NAME}) DEFINES += GL_APICALL= GL_GLEXT_PROTOTYPES= EGLAPI= LIBEGL_IMPLEMENTATION diff --git a/src/gui/configure.json b/src/gui/configure.json index d0cca08b75..dd48567cb9 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -63,21 +63,79 @@ "-lbcm_host" ] }, - "direct2d": { - "label": "Direct 2D", - "export": "", + "dxguid": { + "label": "DirectX GUID", + "sources": [ + "-ldxguid" + ] + }, + "dxgi": { + "label": "DirectX GI", + "headers": "dxgi.h", + "sources": [ + "-ldxgi" + ] + }, + "dxgi1_2": { + "label": "DirectX GI 1.2", "test": { - "tail": "using Microsoft::WRL::ComPtr;", "main": [ - "ComPtr d2dFactory;", - "D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, d2dFactory.ReleaseAndGetAddressOf());", - "ComPtr surface;", + "// fails with mingw-w64 5.4.0 - declaration is missing from header", + "IDXGISurface1 *surface;", "(void) surface;" ] }, - "headers": [ "d3d11_1.h", "d2d1_1.h", "d2d1_1helper.h", "dxgi1_2.h", "wrl.h", "dwrite.h" ], + "headers": "dxgi1_2.h", "sources": [ - "-ld2d1 -ldwrite -ld3d11" + "-ldxgi" + ] + }, + "d3d9": { + "label": "Direct3D 9", + "headers": "d3d9.h", + "sources": [ + "-ld3d9" + ] + }, + "d3d11": { + "label": "Direct3D 11", + "headers": "d3d11.h", + "sources": [ + "-ld3d11" + ] + }, + "d3d11_1": { + "label": "Direct3D 11.1", + "headers": "d3d11_1.h", + "sources": [ + "-ld3d11" + ] + }, + "d3dcompiler": { + "label": "Direct3D Shader Compiler Library", + "headers": "d3dcompiler.h", + "sources": [ + "-ld3dcompiler" + ] + }, + "d2d1": { + "label": "Direct2D 1", + "headers": [ "d2d1.h", "d2d1helper.h" ], + "sources": [ + "-ld2d1" + ] + }, + "d2d1_1": { + "label": "Direct2D 1.1", + "test": { + "main": [ + "ID2D1Factory1 *d2dFactory;", + "D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &d2dFactory);" + ] + }, + "headers": [ "d2d1_1.h", "d2d1_1helper.h" ], + "sources": [ + "-ld2d1" ] }, "directfb": { @@ -94,9 +152,8 @@ { "type": "pkgConfig", "args": "directfb" } ] }, - "directwrite": { + "dwrite": { "label": "DirectWrite", - "export": "", "test": { "main": [ "IDWriteFactory *factory = 0;", @@ -104,7 +161,29 @@ " (IUnknown **)(&factory));" ] }, - "headers": [ "dwrite.h", "d2d1.h" ], + "headers": "dwrite.h", + "sources": [ + "-ldwrite" + ] + }, + "dwrite_1": { + "label": "DirectWrite 1", + "headers": "dwrite_1.h", + "sources": [ + "-ldwrite" + ] + }, + "dwrite_2": { + "label": "DirectWrite 2", + "test": { + "main": [ + "IUnknown *factory = 0;", + "(void)(size_t(DWRITE_E_NOCOLOR) + sizeof(IDWriteFontFace2));", + "DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory2),", + " &factory);" + ] + }, + "headers": "dwrite_2.h", "sources": [ "-ldwrite" ] @@ -650,7 +729,7 @@ }, "testTypeAliases": { - "files": [ "directX" ] + "files": [ "fxc" ] }, "tests": { @@ -665,26 +744,10 @@ ] } }, - "directwrite2": { - "label": "DirectWrite 2", - "type": "compile", - "test": { - "include": [ "dwrite_2.h", "d2d1.h" ], - "main": [ - "IUnknown *factory = 0;", - "(void)(size_t(DWRITE_E_NOCOLOR) + sizeof(IDWriteFontFace2));", - "DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory2),", - " &factory);" - ] - }, - "use": "directwrite" - }, - "directx": { - "label": "DirectX SDK", - "type": "directX", + "fxc": { + "label": "Direct3D Shader Compiler", + "type": "fxc", "files": [ - "d3dcompiler.h", - "d3d11.lib", "fxc.exe" ] }, @@ -944,7 +1007,7 @@ "angle": { "label": "ANGLE", "autoDetect": "features.opengles2 || features.opengl-dynamic", - "condition": "config.win32 && tests.directx", + "condition": "features.dxguid && tests.fxc && (features.direct3d9 || (config.winrt && features.direct3d11 && libs.d3dcompiler))", "output": [ "publicFeature", { "type": "define", "name": "QT_OPENGL_ES_2_ANGLE" } @@ -971,19 +1034,59 @@ "directwrite": { "label": "DirectWrite", "emitIf": "config.win32", - "condition": "libs.directwrite", + "condition": "libs.dwrite", + "output": [ "privateFeature" ] + }, + "directwrite1": { + "label": "DirectWrite 1", + "emitIf": "config.win32", + "condition": "libs.dwrite_1", "output": [ "privateFeature" ] }, "directwrite2": { "label": "DirectWrite 2", "emitIf": "config.win32", - "condition": "features.directwrite && tests.directwrite2", + "condition": "features.directwrite1 && libs.dwrite_2", + "output": [ "privateFeature" ] + }, + "dxguid": { + "label": "DirectX GUID", + "condition": "config.win32 && libs.dxguid", + "output": [ "privateFeature" ] + }, + "direct3d9": { + "label": "Direct 3D 9", + "condition": "config.win32 && !config.winrt && libs.d3d9", + "output": [ "privateFeature" ] + }, + "dxgi": { + "label": "DirectX GI", + "condition": "config.win32 && libs.dxgi", + "output": [ "privateFeature" ] + }, + "dxgi1_2": { + "label": "DirectX GI 1.2", + "condition": "features.dxgi && libs.dxgi1_2", + "output": [ "privateFeature" ] + }, + "direct3d11": { + "label": "Direct 3D 11", + "condition": "features.dxgi && libs.d3d11", + "output": [ "privateFeature" ] + }, + "direct3d11_1": { + "label": "Direct 3D 11.1", + "condition": "features.direct3d11 && features.dxgi1_2 && libs.d3d11_1", "output": [ "privateFeature" ] }, "direct2d": { "label": "Direct 2D", - "section": "Platform plugins", - "condition": "config.win32 && !config.winrt && libs.direct2d", + "condition": "config.win32 && !config.winrt && features.direct3d11 && libs.d2d1", + "output": [ "privateFeature" ] + }, + "direct2d1_1": { + "label": "Direct 2D 1.1", + "condition": "features.direct2d && libs.d2d1_1", "output": [ "privateFeature" ] }, "evdev": { diff --git a/src/gui/configure.pri b/src/gui/configure.pri index e21489ec28..c264b387fc 100644 --- a/src/gui/configure.pri +++ b/src/gui/configure.pri @@ -15,29 +15,16 @@ defineTest(qtConfLibrary_freetype) { return(true) } -# Check for Direct X SDK (include, lib, and direct shader compiler 'fxc'). +# Check for Direct X shader compiler 'fxc'. # Up to Direct X SDK June 2010 and for MinGW, this is pointed to by the # DXSDK_DIR variable. Starting with Windows Kit 8, it is included in -# the Windows SDK. Checking for the header is not sufficient, since it -# is also present in MinGW. -defineTest(qtConfTest_directX) { +# the Windows SDK. +defineTest(qtConfTest_fxc) { dxdir = $$getenv("DXSDK_DIR") !isEmpty(dxdir) { - EXTRA_INCLUDEPATH += $$dxdir/include - equals(QT_ARCH, x86_64): \ - EXTRA_LIBDIR += $$dxdir/lib/x64 - else: \ - EXTRA_LIBDIR += $$dxdir/lib/x86 EXTRA_PATH += $$dxdir/Utilities/bin/x86 } - $$qtConfEvaluate("features.sse2") { - ky = $$size($${1}.files._KEYS_) - $${1}.files._KEYS_ += $$ky - # Not present on MinGW-32 - $${1}.files.$${ky} = "intrin.h" - } - qtConfTest_files($${1}): return(true) return(false) } diff --git a/src/platformsupport/fontdatabases/windows/windows.pri b/src/platformsupport/fontdatabases/windows/windows.pri index 0e64084cf1..9c529f55ea 100644 --- a/src/platformsupport/fontdatabases/windows/windows.pri +++ b/src/platformsupport/fontdatabases/windows/windows.pri @@ -15,9 +15,14 @@ qtConfig(freetype) { HEADERS += $$PWD/qwindowsfontdatabase_ft_p.h } -qtConfig(directwrite) { - qtConfig(directwrite2): \ +qtConfig(directwrite):qtConfig(direct2d) { + qtConfig(directwrite2) { + QMAKE_USE_PRIVATE += dwrite_2 DEFINES *= QT_USE_DIRECTWRITE2 + } else { + QMAKE_USE_PRIVATE += dwrite + } + QMAKE_USE_PRIVATE += d2d1 SOURCES += $$PWD/qwindowsfontenginedirectwrite.cpp HEADERS += $$PWD/qwindowsfontenginedirectwrite_p.h diff --git a/src/platformsupport/fontdatabases/winrt/winrt.pri b/src/platformsupport/fontdatabases/winrt/winrt.pri index 291ada220f..7617df2e7a 100644 --- a/src/platformsupport/fontdatabases/winrt/winrt.pri +++ b/src/platformsupport/fontdatabases/winrt/winrt.pri @@ -8,4 +8,6 @@ HEADERS += \ DEFINES += __WRL_NO_DEFAULT_LIB__ -LIBS += -lws2_32 -ldwrite +LIBS += -lws2_32 + +QMAKE_USE_PRIVATE += dwrite_1 diff --git a/src/plugins/platforms/direct2d/direct2d.pro b/src/plugins/platforms/direct2d/direct2d.pro index 3bfd02bdc8..9764272632 100644 --- a/src/plugins/platforms/direct2d/direct2d.pro +++ b/src/plugins/platforms/direct2d/direct2d.pro @@ -8,7 +8,8 @@ QT += \ qtConfig(accessibility): QT += accessibility_support-private qtConfig(vulkan): QT += vulkan_support-private -LIBS += -ldwmapi -ld2d1 -ld3d11 -ldwrite -lversion -lgdi32 +LIBS += -ldwmapi -lversion -lgdi32 +QMAKE_USE_PRIVATE += dwrite_1 d2d1_1 d3d11_1 dxgi1_2 include(../windows/windows.pri) diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro index db2a31d1a5..acc55adf6f 100644 --- a/src/plugins/platforms/platforms.pro +++ b/src/plugins/platforms/platforms.pro @@ -14,10 +14,10 @@ qtConfig(xcb) { uikit:!watchos: SUBDIRS += ios osx: SUBDIRS += cocoa -win32:!winrt: SUBDIRS += windows -winrt: SUBDIRS += winrt +win32:!winrt:qtConfig(direct3d9): SUBDIRS += windows +winrt:qtConfig(direct3d11): SUBDIRS += winrt -qtConfig(direct2d) { +qtConfig(direct3d11_1):qtConfig(direct2d1_1):qtConfig(directwrite1) { SUBDIRS += direct2d } diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri index db06a6a2a3..7004d7e854 100644 --- a/src/plugins/platforms/windows/windows.pri +++ b/src/plugins/platforms/windows/windows.pri @@ -9,6 +9,8 @@ mingw: LIBS *= -luuid # For the dialog helpers: LIBS += -lshlwapi -lshell32 -ladvapi32 -lwtsapi32 +QMAKE_USE_PRIVATE += d3d9/nolink + DEFINES *= QT_NO_CAST_FROM_ASCII QT_NO_FOREACH SOURCES += \ diff --git a/src/plugins/platforms/winrt/winrt.pro b/src/plugins/platforms/winrt/winrt.pro index 6a847465e4..43132a1a76 100644 --- a/src/plugins/platforms/winrt/winrt.pro +++ b/src/plugins/platforms/winrt/winrt.pro @@ -8,7 +8,8 @@ QT += \ DEFINES *= QT_NO_CAST_FROM_ASCII __WRL_NO_DEFAULT_LIB__ -LIBS += -lws2_32 -ld3d11 +LIBS += -lws2_32 +QMAKE_USE_PRIVATE += d3d11 SOURCES = \ main.cpp \ From 7a481fce28b0ffbb77f8631673009bf9bf615088 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Tue, 12 Dec 2017 20:02:55 +0100 Subject: [PATCH 0677/1650] configure: detect fxc.exe more thoroughly When building ANGLE, we need the shader compiler (fxc.exe), which is not shipped with MinGW. Previously, we required an installed DirectX SDK. For Windows versions >= 8, the DX SDK is also part of the Windows Kit, so we also allow the user to specify the location of the Windows Kit. We also detect fxc on 64-bit hosts now, and in newer SDK versions which version the binary directory. The detected binary is now exported by configure, so the ANGLE project file does not need to duplicate the logic anymore. Task-number: QTBUG-52487 Change-Id: I41a17992909041dd84291b69498195cc8b8fab8a Reviewed-by: Joerg Bornemann --- src/angle/src/common/common.pri | 16 +--------------- src/gui/configure.json | 11 +++-------- src/gui/configure.pri | 31 +++++++++++++++++++++++++++---- 3 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/angle/src/common/common.pri b/src/angle/src/common/common.pri index b64dbd3e36..df29269786 100644 --- a/src/angle/src/common/common.pri +++ b/src/angle/src/common/common.pri @@ -22,21 +22,7 @@ lib_replace.replace = \$\$\$\$[QT_INSTALL_LIBS] lib_replace.CONFIG = path QMAKE_PRL_INSTALL_REPLACE += lib_replace -# DirectX is included in the Windows 8 Kit, but everything else requires the DX SDK. -winrt|msvc { - FXC = fxc.exe -} else { - DX_DIR = $$(DXSDK_DIR) - isEmpty(DX_DIR) { - error("Cannot determine DirectX SDK location. Please set DXSDK_DIR environment variable.") - } - - equals(QMAKE_TARGET.arch, x86_64) { - FXC = \"$${DX_DIR}Utilities\\bin\\x64\\fxc.exe\" - } else { - FXC = \"$${DX_DIR}Utilities\\bin\\x86\\fxc.exe\" - } -} +FXC = $$shell_quote($$shell_path($$QMAKE_FXC_LOCATION)) win32 { VERSION = $$MODULE_VERSION diff --git a/src/gui/configure.json b/src/gui/configure.json index dd48567cb9..db78c7900c 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -728,10 +728,6 @@ } }, - "testTypeAliases": { - "files": [ "fxc" ] - }, - "tests": { "angle_d3d11_qdtd": { "label": "D3D11_QUERY_DATA_TIMESTAMP_DISJOINT", @@ -747,9 +743,7 @@ "fxc": { "label": "Direct3D Shader Compiler", "type": "fxc", - "files": [ - "fxc.exe" - ] + "log": "value" }, "drm_atomic": { "label": "DRM Atomic API", @@ -1010,7 +1004,8 @@ "condition": "features.dxguid && tests.fxc && (features.direct3d9 || (config.winrt && features.direct3d11 && libs.d3dcompiler))", "output": [ "publicFeature", - { "type": "define", "name": "QT_OPENGL_ES_2_ANGLE" } + { "type": "define", "name": "QT_OPENGL_ES_2_ANGLE" }, + { "type": "varAssign", "name": "QMAKE_FXC_LOCATION", "value": "tests.fxc.value" } ] }, "angle_d3d11_qdtd": { diff --git a/src/gui/configure.pri b/src/gui/configure.pri index c264b387fc..1b95449a10 100644 --- a/src/gui/configure.pri +++ b/src/gui/configure.pri @@ -20,12 +20,35 @@ defineTest(qtConfLibrary_freetype) { # DXSDK_DIR variable. Starting with Windows Kit 8, it is included in # the Windows SDK. defineTest(qtConfTest_fxc) { - dxdir = $$getenv("DXSDK_DIR") - !isEmpty(dxdir) { - EXTRA_PATH += $$dxdir/Utilities/bin/x86 + !mingw { + fxc = $$qtConfFindInPath("fxc.exe") + } else { + equals(QMAKE_HOST.arch, x86_64): \ + fns = x64/fxc.exe + else: \ + fns = x86/fxc.exe + dxdir = $$(DXSDK_DIR) + !isEmpty(dxdir) { + fxc = $$dxdir/Utilities/bin/$$fns + } else { + winkitbindir = $$(WindowsSdkVerBinPath) + !isEmpty(winkitbindir) { + fxc = $$winkitbindir/$$fns + } else { + winkitdir = $$(WindowsSdkDir) + !isEmpty(winkitdir): \ + fxc = $$winkitdir/bin/$$fns + } + } } - qtConfTest_files($${1}): return(true) + !isEmpty(fxc):exists($$fxc) { + $${1}.value = $$clean_path($$fxc) + export($${1}.value) + $${1}.cache += value + export($${1}.cache) + return(true) + } return(false) } From 65463764f24210c755d6f48930162e67a5de7e9b Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 17 Jan 2018 12:44:45 +0100 Subject: [PATCH 0678/1650] configure: properly atomize xcb-syslibs as it is now cheap to test for individual libraries and headers, split the xcb_syslibs monster-library into its parts. the compile test remains a single blob, though, as that didn't get any cheaper. whether it's worth keeping it in the first place is debatable. Change-Id: Id7cae7925bb4d77069437512abecf14feea749f2 Reviewed-by: Gatis Paeglis --- src/gui/configure.json | 129 +++++++++++++++++----- src/plugins/platforms/xcb/xcb_qpa_lib.pro | 5 +- 2 files changed, 107 insertions(+), 27 deletions(-) diff --git a/src/gui/configure.json b/src/gui/configure.json index db78c7900c..67378114ca 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -557,7 +557,7 @@ ] }, "xcb": { - "label": "XCB >= 1.9 (core)", + "label": "XCB >= 1.9", "test": { "main": [ "int primaryScreen = 0;", @@ -572,30 +572,86 @@ "-lxcb" ] }, - "xcb_syslibs": { - "label": "XCB (extensions)", - "test": { - "include": [ - "xcb/xcb.h", - "xcb/xfixes.h", - "xcb/xcb_image.h", - "xcb/xcb_keysyms.h", - "xcb/xinerama.h", - "xcb/sync.h", - "xcb/randr.h", - "xcb/shm.h", - "xcb/xcb_icccm.h" - ], - "main": [ - "int primaryScreen = 0;", - "(void) xcb_connect(\"\", &primaryScreen);" - ] - }, + "xcb_icccm": { + "label": "XCB ICCCM >= 0.3.9", + "headers": "xcb/xcb_icccm.h", "sources": [ - { "type": "pkgConfig", - "args": "xcb xcb-shm xcb-sync xcb-xfixes xcb-xinerama xcb-randr xcb-image xcb-keysyms xcb-icccm xcb-shape" }, - "-lxcb -lxcb-shm -lxcb-sync -lxcb-xfixes -lxcb-xinerama -lxcb-randr -lxcb-image -lxcb-keysyms -lxcb-icccm -lxcb-shape" - ] + { "type": "pkgConfig", "args": "xcb-icccm >= 0.3.9" }, + "-lxcb-icccm" + ], + "use": "xcb" + }, + "xcb_image": { + "label": "XCB Image >= 0.3.9", + "headers": "xcb/xcb_image.h", + "sources": [ + { "type": "pkgConfig", "args": "xcb-image >= 0.3.9" }, + "-lxcb-image" + ], + "use": "xcb_shm xcb" + }, + "xcb_keysyms": { + "label": "XCB Keysyms >= 0.3.9", + "headers": "xcb/xcb_keysyms.h", + "sources": [ + { "type": "pkgConfig", "args": "xcb-keysyms >= 0.3.9" }, + "-lxcb-keysyms" + ], + "use": "xcb" + }, + "xcb_randr": { + "label": "XCB RandR", + "headers": "xcb/randr.h", + "sources": [ + { "type": "pkgConfig", "args": "xcb-randr" }, + "-lxcb-randr" + ], + "use": "xcb" + }, + "xcb_shape": { + "label": "XCB Shape", + "headers": "xcb/shape.h", + "sources": [ + { "type": "pkgConfig", "args": "xcb-shape" }, + "-lxcb-shape" + ], + "use": "xcb" + }, + "xcb_shm": { + "label": "XCB SHM", + "headers": "xcb/shm.h", + "sources": [ + { "type": "pkgConfig", "args": "xcb-shm" }, + "-lxcb-shm" + ], + "use": "xcb" + }, + "xcb_sync": { + "label": "XCB Sync", + "headers": "xcb/sync.h", + "sources": [ + { "type": "pkgConfig", "args": "xcb-sync" }, + "-lxcb-sync" + ], + "use": "xcb" + }, + "xcb_xfixes": { + "label": "XCB Xfixes", + "headers": "xcb/xfixes.h", + "sources": [ + { "type": "pkgConfig", "args": "xcb-xfixes" }, + "-lxcb-xfixes" + ], + "use": "xcb" + }, + "xcb_xinerama": { + "label": "XCB Xinerama", + "headers": "xcb/xinerama.h", + "sources": [ + { "type": "pkgConfig", "args": "xcb-xinerama" }, + "-lxcb-xinerama" + ], + "use": "xcb" }, "xcb_xlib": { "label": "XCB Xlib", @@ -982,6 +1038,29 @@ "type": "qpaDefaultPlatform", "log": "value" }, + "xcb_syslibs": { + "label": "XCB (extensions)", + "type": "compile", + "test": { + "include": [ + "xcb/xcb.h", + "xcb/xcb_image.h", + "xcb/xcb_keysyms.h", + "xcb/randr.h", + "xcb/shape.h", + "xcb/shm.h", + "xcb/sync.h", + "xcb/xfixes.h", + "xcb/xinerama.h", + "xcb/xcb_icccm.h" + ], + "main": [ + "int primaryScreen = 0;", + "(void) xcb_connect(\"\", &primaryScreen);" + ] + }, + "use": "xcb_icccm xcb_image xcb_keysyms xcb_randr xcb_shape xcb_shm xcb_sync xcb_xfixes xcb_xinerama xcb" + }, "x11prefix": { "label": "X11 prefix", "type": "getPkgConfigVariable", @@ -1420,7 +1499,7 @@ "enable": "input.xcb == 'system'", "disable": "input.xcb == 'qt'", "autoDetect": "!config.darwin", - "condition": "features.xcb && libs.xcb_syslibs", + "condition": "features.xcb && tests.xcb_syslibs", "output": [ "privateFeature" ] }, "x11-prefix": { diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro index 9883617ab6..f4ca9cc81d 100644 --- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro +++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro @@ -95,12 +95,13 @@ qtConfig(vulkan) { } !qtConfig(system-xcb) { - QMAKE_USE += xcb-static xcb + QMAKE_USE += xcb-static } else { qtConfig(xcb-render): QMAKE_USE += xcb_render qtConfig(xcb-xinput): QMAKE_USE += xcb_xinput - QMAKE_USE += xcb_syslibs + QMAKE_USE += xcb_icccm xcb_image xcb_keysyms xcb_randr xcb_shape xcb_shm xcb_sync xcb_xfixes xcb_xinerama } +QMAKE_USE += xcb QMAKE_USE += xkbcommon qtConfig(xkb) { From cf51bcba10af20b6c603c34f0be99b7c34f6a8f7 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 3 May 2018 17:37:10 +0200 Subject: [PATCH 0679/1650] configure: allow libraries to create explicitly empty tests this allows compile-testing the specified headers with no further tests. Change-Id: I268ff328deee221d9b92386fe2bd133b19a6f8e2 Reviewed-by: Joerg Bornemann Reviewed-by: Oswald Buddenhagen --- mkspecs/features/qt_configure.prf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index c854a31f55..fe14ea1f40 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -982,7 +982,7 @@ defineTest(qtConfHandleLibrary) { export($${lpfx}.source) # if the library defines a test, use it to verify the source. - !isEmpty($${lpfx}.test)|!isEmpty($${lpfx}.test._KEYS_) { + defined($${lpfx}.test, var)|defined($${lpfx}.test._KEYS_, var) { $${lpfx}.resolved_uses = $$currentConfig:$$1 $${lpfx}.host = $$eval($${spfx}.host) !qtConfTest_compile($$lpfx) { From 5485a085e6d9af34a2ce0b86abf91b0b693b9d05 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 13 Jul 2018 18:56:22 +0200 Subject: [PATCH 0680/1650] configure: optimize the openssl feature structure don't run the openssl_headers test pointlessly when openssl-linked is selected but its test fails. implementing this cleanly required creating a separate openssl-runtime feature, including 'redirecting' the -openssl option (which is just an alias for -openssl-runtime) to it. simplify the openssl-linked conditions: while "anything but the value that enables it" in the 'disable' field effectively means "don't auto-detect it", it's better to be explicit about that. Change-Id: I6b117cc50711bb64d090fcfdb89ff009c60ed86c Reviewed-by: Timur Pocheptsov Reviewed-by: Joerg Bornemann --- src/network/configure.json | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/network/configure.json b/src/network/configure.json index 01ed1249e0..3f1cb7893b 100644 --- a/src/network/configure.json +++ b/src/network/configure.json @@ -195,20 +195,24 @@ }, "openssl": { "label": "OpenSSL", - "enable": "input.openssl == 'yes' || input.openssl == 'linked' || input.openssl == 'runtime'", - "disable": "input.openssl == 'no' || input.ssl == 'no'", - "autoDetect": "!config.winrt && !config.wasm", - "condition": "!features.securetransport && (features.openssl-linked || libs.openssl_headers)", + "enable": "false", + "condition": "features.openssl-runtime || features.openssl-linked", "output": [ "privateFeature", { "type": "publicQtConfig", "condition": "!features.openssl-linked" }, { "type": "define", "negative": true, "name": "QT_NO_OPENSSL" } ] }, + "openssl-runtime": { + "autoDetect": "!config.winrt && !config.wasm", + "enable": "input.openssl == 'yes' || input.openssl == 'runtime'", + "disable": "input.openssl == 'no' || input.openssl == 'linked' || input.ssl == 'no'", + "condition": "!features.securetransport && libs.openssl_headers" + }, "openssl-linked": { "label": " Qt directly linked to OpenSSL", + "autoDetect": false, "enable": "input.openssl == 'linked'", - "disable": "input.openssl != 'linked'", "condition": "!features.securetransport && libs.openssl", "output": [ "privateFeature", From c07ab93c204c134509032d7c3d50f31ee913c57c Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 3 May 2018 16:46:56 +0200 Subject: [PATCH 0681/1650] configure: adjust openssl lib names on mingw both the mingw and msvc build have a "lib" prefix on the libraries. this makes the msvc build unconventional, so it needs an extra source. for the mingw build, otoh, this is the expected setup, so the source used for unix will work just fine. this doesn't fix any actual bug, because mingw will apparently resolve -llibfoo to libfoo.a even though only liblibfoo.a and libfoo.lib are documented (on mingw.org). however, this mix of conventions is ugly and should be avoided. Change-Id: I32b1621e4ac15db1f071c08ced738bfdafdcc11b Reviewed-by: Timur Pocheptsov Reviewed-by: Joerg Bornemann --- src/network/configure.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/network/configure.json b/src/network/configure.json index 3f1cb7893b..4e4426342f 100644 --- a/src/network/configure.json +++ b/src/network/configure.json @@ -77,9 +77,12 @@ }, { "libs": "-llibssl -llibcrypto", - "condition": "config.win32" + "condition": "config.msvc" }, - { "libs": "-lssl -lcrypto", "condition": "!config.win32" } + { + "libs": "-lssl -lcrypto", + "condition": "!config.msvc" + } ] } }, From c15afc16ac0d71f1b61ad6154df3a7994e18cc26 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 3 May 2018 16:58:00 +0200 Subject: [PATCH 0682/1650] configure: remove openssl placeholder source there is no particular reason to exclude static builds from the default. misses are cheap now, so it's fine if nothing is found. this affects only the legacy pre-1.1 library names under windows. Change-Id: I998b9f7bfcce42ec990a236bb44372c4d6b3f631 Reviewed-by: Timur Pocheptsov --- src/network/configure.json | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/network/configure.json b/src/network/configure.json index 4e4426342f..076a1c24a7 100644 --- a/src/network/configure.json +++ b/src/network/configure.json @@ -66,14 +66,9 @@ "test": "openssl", "sources": [ { "type": "openssl" }, - { - "comment": "placeholder for OPENSSL_{PATH,LIBS{,_{DEBUG,RELEASE}}}", - "libs": "", - "condition": "config.win32 && !features.shared" - }, { "libs": "-lssleay32 -llibeay32", - "condition": "config.win32 && features.shared" + "condition": "config.win32" }, { "libs": "-llibssl -llibcrypto", From 10adbc4f0f2d60bc714b304266865bebcce0f909 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 13 Jul 2018 20:26:46 +0200 Subject: [PATCH 0683/1650] configure: inline corewlan test we have support for objc++ since 591edbb11. Change-Id: I5f430fd7c410913d4532627d18529b077f794035 Reviewed-by: Joerg Bornemann --- config.tests/corewlan/corewlan.pro | 1 - config.tests/corewlan/corewlantest.mm | 47 --------------------------- src/network/configure.json | 6 +++- 3 files changed, 5 insertions(+), 49 deletions(-) delete mode 100644 config.tests/corewlan/corewlan.pro delete mode 100644 config.tests/corewlan/corewlantest.mm diff --git a/config.tests/corewlan/corewlan.pro b/config.tests/corewlan/corewlan.pro deleted file mode 100644 index c19f0be4fd..0000000000 --- a/config.tests/corewlan/corewlan.pro +++ /dev/null @@ -1 +0,0 @@ -OBJECTIVE_SOURCES = corewlantest.mm diff --git a/config.tests/corewlan/corewlantest.mm b/config.tests/corewlan/corewlantest.mm deleted file mode 100644 index 73b4d0d145..0000000000 --- a/config.tests/corewlan/corewlantest.mm +++ /dev/null @@ -1,47 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the config.tests of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -int main() -{ - [CWInterface interfaceWithName:@"en2"]; - return 0; -} diff --git a/src/network/configure.json b/src/network/configure.json index 076a1c24a7..e823ed9d2f 100644 --- a/src/network/configure.json +++ b/src/network/configure.json @@ -26,7 +26,11 @@ "corewlan": { "label": "CoreWLan", "export": "", - "test": "corewlan", + "test": { + "lang": "objc++", + "main": "[CWInterface interfaceWithName:@\"en2\"];" + }, + "headers": [ "CoreWLAN/CoreWLAN.h", "CoreWLAN/CWInterface.h" ], "sources": [ "-framework CoreWLAN -framework Foundation" ] From 53ae00d03c4065ca2235dc41636be0274d074c57 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 13 Jul 2018 21:13:46 +0200 Subject: [PATCH 0684/1650] configure: inline a few more tests these were new on dev while the original migration happened on 5.9, or came from new changes which hadn't adapted yet. Change-Id: I5e48437061a97e6df6e93881c98471455e177631 Reviewed-by: Joerg Bornemann --- config.tests/qpa/vulkan/vulkan.cpp | 58 ------------------- config.tests/qpa/vulkan/vulkan.pro | 1 - .../unix/cxx11_random/cxx11_random.cpp | 35 ----------- .../unix/cxx11_random/cxx11_random.pro | 1 - config.tests/unix/futimens/futimens.cpp | 47 --------------- config.tests/unix/futimens/futimens.pro | 6 -- config.tests/unix/futimes/futimes.cpp | 47 --------------- config.tests/unix/futimes/futimes.pro | 1 - config.tests/unix/getauxval/getauxval.cpp | 34 ----------- config.tests/unix/getauxval/getauxval.pro | 1 - config.tests/unix/getentropy/getentropy.cpp | 35 ----------- config.tests/unix/getentropy/getentropy.pro | 1 - config.tests/unix/opengles32/opengles32.cpp | 47 --------------- config.tests/unix/opengles32/opengles32.pro | 7 --- config.tests/x11/xrender/xrender.cpp | 52 ----------------- config.tests/x11/xrender/xrender.pro | 2 - src/corelib/configure.json | 34 +++++++++-- src/gui/configure.json | 33 ++++++++++- 18 files changed, 59 insertions(+), 383 deletions(-) delete mode 100644 config.tests/qpa/vulkan/vulkan.cpp delete mode 100644 config.tests/qpa/vulkan/vulkan.pro delete mode 100644 config.tests/unix/cxx11_random/cxx11_random.cpp delete mode 100644 config.tests/unix/cxx11_random/cxx11_random.pro delete mode 100644 config.tests/unix/futimens/futimens.cpp delete mode 100644 config.tests/unix/futimens/futimens.pro delete mode 100644 config.tests/unix/futimes/futimes.cpp delete mode 100644 config.tests/unix/futimes/futimes.pro delete mode 100644 config.tests/unix/getauxval/getauxval.cpp delete mode 100644 config.tests/unix/getauxval/getauxval.pro delete mode 100644 config.tests/unix/getentropy/getentropy.cpp delete mode 100644 config.tests/unix/getentropy/getentropy.pro delete mode 100644 config.tests/unix/opengles32/opengles32.cpp delete mode 100644 config.tests/unix/opengles32/opengles32.pro delete mode 100644 config.tests/x11/xrender/xrender.cpp delete mode 100644 config.tests/x11/xrender/xrender.pro diff --git a/config.tests/qpa/vulkan/vulkan.cpp b/config.tests/qpa/vulkan/vulkan.cpp deleted file mode 100644 index 22f5edf9f2..0000000000 --- a/config.tests/qpa/vulkan/vulkan.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the config.tests of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// This is a header-only test. Qt does not rely on linking to a Vulkan library directly. - -#include - -// The pData parameter has changed from uint32_t* to void* at some point. -// Ensure the headers have the updated one to prevent compile errors later on. -PFN_vkCmdUpdateBuffer cmdUpdBuf; -void testUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData) -{ - cmdUpdBuf(commandBuffer, dstBuffer, dstOffset, dataSize, pData); -} - -int main(int, char **) -{ - VkInstanceCreateInfo info; - testUpdateBuffer(0, 0, 0, 0, 0); - - return 0; -} diff --git a/config.tests/qpa/vulkan/vulkan.pro b/config.tests/qpa/vulkan/vulkan.pro deleted file mode 100644 index 5f05bc49aa..0000000000 --- a/config.tests/qpa/vulkan/vulkan.pro +++ /dev/null @@ -1 +0,0 @@ -SOURCES = vulkan.cpp diff --git a/config.tests/unix/cxx11_random/cxx11_random.cpp b/config.tests/unix/cxx11_random/cxx11_random.cpp deleted file mode 100644 index d6872667fd..0000000000 --- a/config.tests/unix/cxx11_random/cxx11_random.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -int main() -{ - std::mt19937 mt(0); - return 0; -} diff --git a/config.tests/unix/cxx11_random/cxx11_random.pro b/config.tests/unix/cxx11_random/cxx11_random.pro deleted file mode 100644 index 0cd5fff9d9..0000000000 --- a/config.tests/unix/cxx11_random/cxx11_random.pro +++ /dev/null @@ -1 +0,0 @@ -SOURCES = cxx11_random.cpp diff --git a/config.tests/unix/futimens/futimens.cpp b/config.tests/unix/futimens/futimens.cpp deleted file mode 100644 index 1b66386ca1..0000000000 --- a/config.tests/unix/futimens/futimens.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 Raphael Gozzo -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the config.tests of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -int main(int, char **) -{ - futimens(-1,0); - return 0; -} - diff --git a/config.tests/unix/futimens/futimens.pro b/config.tests/unix/futimens/futimens.pro deleted file mode 100644 index 83a122252a..0000000000 --- a/config.tests/unix/futimens/futimens.pro +++ /dev/null @@ -1,6 +0,0 @@ -SOURCES += futimens.cpp - -# Block futimens() on Apple platforms unless it's available on ALL deployment -# targets. This simplifies the logic at the call site dramatically, as it isn't -# strictly needed compared to futimes(). -darwin: QMAKE_CXXFLAGS += -Werror=unguarded-availability diff --git a/config.tests/unix/futimes/futimes.cpp b/config.tests/unix/futimes/futimes.cpp deleted file mode 100644 index 553b39068e..0000000000 --- a/config.tests/unix/futimes/futimes.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 Raphael Gozzo -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the config.tests of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -int main(int, char **) -{ - futimes(-1,0); - return 0; -} - diff --git a/config.tests/unix/futimes/futimes.pro b/config.tests/unix/futimes/futimes.pro deleted file mode 100644 index 8e7f2c0f62..0000000000 --- a/config.tests/unix/futimes/futimes.pro +++ /dev/null @@ -1 +0,0 @@ -SOURCES += futimes.cpp diff --git a/config.tests/unix/getauxval/getauxval.cpp b/config.tests/unix/getauxval/getauxval.cpp deleted file mode 100644 index 62f71e95d2..0000000000 --- a/config.tests/unix/getauxval/getauxval.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -int main() -{ - return getauxval(AT_NULL); -} diff --git a/config.tests/unix/getauxval/getauxval.pro b/config.tests/unix/getauxval/getauxval.pro deleted file mode 100644 index ea46cb0bae..0000000000 --- a/config.tests/unix/getauxval/getauxval.pro +++ /dev/null @@ -1 +0,0 @@ -SOURCES = getauxval.cpp diff --git a/config.tests/unix/getentropy/getentropy.cpp b/config.tests/unix/getentropy/getentropy.cpp deleted file mode 100644 index 6cb4dc3a95..0000000000 --- a/config.tests/unix/getentropy/getentropy.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 Intel Corporation. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -int main() -{ - char buf[32]; - return getentropy(buf, sizeof(buf)); -} diff --git a/config.tests/unix/getentropy/getentropy.pro b/config.tests/unix/getentropy/getentropy.pro deleted file mode 100644 index bdd626b513..0000000000 --- a/config.tests/unix/getentropy/getentropy.pro +++ /dev/null @@ -1 +0,0 @@ -SOURCES = getentropy.cpp diff --git a/config.tests/unix/opengles32/opengles32.cpp b/config.tests/unix/opengles32/opengles32.cpp deleted file mode 100644 index 0505510464..0000000000 --- a/config.tests/unix/opengles32/opengles32.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the config.tests of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -int main(int, char **) -{ - glFramebufferTexture(GL_TEXTURE_2D, GL_DEPTH_STENCIL_ATTACHMENT, 1, 0); - - return 0; -} diff --git a/config.tests/unix/opengles32/opengles32.pro b/config.tests/unix/opengles32/opengles32.pro deleted file mode 100644 index c95ba83364..0000000000 --- a/config.tests/unix/opengles32/opengles32.pro +++ /dev/null @@ -1,7 +0,0 @@ -# The library is expected to be the same as in ES 2.0 (libGLESv2). -# The difference is the header and the presence of the functions in -# the library. - -SOURCES = opengles32.cpp - -CONFIG -= qt diff --git a/config.tests/x11/xrender/xrender.cpp b/config.tests/x11/xrender/xrender.cpp deleted file mode 100644 index 35203cc02c..0000000000 --- a/config.tests/x11/xrender/xrender.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the config.tests of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -#if RENDER_MAJOR == 0 && RENDER_MINOR < 5 -# error "Required Xrender version 0.6 not found." -#else -int main(int, char **) -{ - XRenderPictFormat *format; - format = 0; - return 0; -} -#endif diff --git a/config.tests/x11/xrender/xrender.pro b/config.tests/x11/xrender/xrender.pro deleted file mode 100644 index 6244ae6b47..0000000000 --- a/config.tests/x11/xrender/xrender.pro +++ /dev/null @@ -1,2 +0,0 @@ -SOURCES = xrender.cpp -CONFIG -= qt diff --git a/src/corelib/configure.json b/src/corelib/configure.json index 81448174b6..eb213398ca 100644 --- a/src/corelib/configure.json +++ b/src/corelib/configure.json @@ -277,7 +277,10 @@ "cxx11_random": { "label": "C++11 ", "type": "compile", - "test": "unix/cxx11_random" + "test": { + "include": "random", + "main": "std::mt19937 mt(0);" + } }, "eventfd": { "label": "eventfd", @@ -295,22 +298,43 @@ "futimens": { "label": "futimens()", "type": "compile", - "test": "unix/futimens" + "test": { + "include": "sys/stat.h", + "main": "futimens(-1, 0);", + "qmake": [ + "# Block futimens() on Apple platforms unless it's available on ALL", + "# deployment targets. This simplifies the logic at the call site", + "# dramatically, as it isn't strictly needed compared to futimes().", + "darwin: QMAKE_CXXFLAGS += -Werror=unguarded-availability" + ] + } }, "futimes": { "label": "futimes()", "type": "compile", - "test": "unix/futimes" + "test": { + "include": "sys/time.h", + "main": "futimes(-1, 0);" + } }, "getauxval": { "label": "getauxval()", "type": "compile", - "test": "unix/getauxval" + "test": { + "include": "sys/auxv.h", + "main": "(void) getauxval(AT_NULL);" + } }, "getentropy": { "label": "getentropy()", "type": "compile", - "test": "unix/getentropy" + "test": { + "include": "unistd.h", + "main": [ + "char buf[32];", + "(void) getentropy(buf, sizeof(buf));" + ] + } }, "posix-iconv": { "label": "POSIX iconv", diff --git a/src/gui/configure.json b/src/gui/configure.json index 67378114ca..caa6f065f0 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -521,7 +521,23 @@ }, "vulkan": { "label": "Vulkan", - "test": "qpa/vulkan", + "test": { + "comment": "Note: Qt does not rely on linking to a Vulkan library directly.", + "tail": [ + "// The pData parameter has changed from uint32_t* to void* at some point.", + "// Ensure the headers have the updated one to prevent compile errors later on.", + "PFN_vkCmdUpdateBuffer cmdUpdBuf;", + "void testUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData)", + "{", + " cmdUpdBuf(commandBuffer, dstBuffer, dstOffset, dataSize, pData);", + "}" + ], + "main": [ + "VkInstanceCreateInfo info;", + "testUpdateBuffer(0, 0, 0, 0, 0);" + ] + }, + "headers": "vulkan/vulkan.h", "sources": [ { "type": "pkgConfig", "args": "vulkan" }, { "type": "makeSpec", "spec": "VULKAN" } @@ -776,7 +792,15 @@ }, "xrender": { "label": "XRender for native painting", - "test": "x11/xrender", + "test": { + "tail": [ + "#if RENDER_MAJOR == 0 && RENDER_MINOR < 5", + "# error Required Xrender version 0.6 not found.", + "#endif" + ], + "main": "XRenderPictFormat *format = 0;" + }, + "headers": "X11/extensions/Xrender.h", "sources": [ "-lXrender" ], @@ -1030,7 +1054,10 @@ "opengles32": { "label": "OpenGL ES 3.2", "type": "compile", - "test": "unix/opengles32", + "test": { + "include": "GLES3/gl32.h", + "main": "glFramebufferTexture(GL_TEXTURE_2D, GL_DEPTH_STENCIL_ATTACHMENT, 1, 0);" + }, "use": "opengl_es2" }, "qpa_default_platform": { From 7863be311570fa219066df5fe8720d5b92ddb680 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sat, 8 Dec 2018 19:58:00 +0100 Subject: [PATCH 0685/1650] QTableView: Fix keyboard navigation with disabled rows The keyboard navigation with MovePageUp/Down and MoveEnd did not honor disabled cells in all cases which lead to inconsistencies in the navigation (esp. since MoveHome does honor them correctly). Therefore make sure that all four move operations work consistent by refactoring the code to use common functions. Fixes: QTBUG-72400 Change-Id: I63fa3b626510d21c66f4f9b2b1bfb3261728ecaf Reviewed-by: Friedemann Kleint Reviewed-by: Luca Beldi Reviewed-by: Samuel Gaist Reviewed-by: Richard Moe Gustavsen --- src/widgets/itemviews/qtableview.cpp | 103 ++++++++++++++---- src/widgets/itemviews/qtableview_p.h | 20 ++-- .../itemviews/qtableview/tst_qtableview.cpp | 40 ++++++- 3 files changed, 125 insertions(+), 38 deletions(-) diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp index 9725a768de..9c509583e6 100644 --- a/src/widgets/itemviews/qtableview.cpp +++ b/src/widgets/itemviews/qtableview.cpp @@ -764,6 +764,66 @@ bool QTableViewPrivate::spanContainsSection(const QHeaderView *header, int logic return false; } +/*! + \internal + Searches for the next cell which is available for e.g. keyboard navigation + The search is done by row +*/ +int QTableViewPrivate::nextActiveVisualRow(int rowToStart, int column, int limit, + SearchDirection searchDirection) const +{ + const int lc = logicalColumn(column); + int visualRow = rowToStart; + const auto isCellActive = [this](int vr, int lc) + { + const int lr = logicalRow(vr); + return !isRowHidden(lr) && isCellEnabled(lr, lc); + }; + switch (searchDirection) { + case SearchDirection::Increasing: + if (visualRow < limit) { + while (!isCellActive(visualRow, lc)) { + if (++visualRow == limit) + return rowToStart; + } + } + break; + case SearchDirection::Decreasing: + while (visualRow > limit && !isCellActive(visualRow, lc)) + --visualRow; + break; + } + return visualRow; +} + +/*! + \internal + Searches for the next cell which is available for e.g. keyboard navigation + The search is done by column +*/ +int QTableViewPrivate::nextActiveVisualColumn(int row, int columnToStart, int limit, + SearchDirection searchDirection) const +{ + const int lr = logicalRow(row); + int visualColumn = columnToStart; + const auto isCellActive = [this](int lr, int vc) + { + const int lc = logicalColumn(vc); + return !isColumnHidden(lc) && isCellEnabled(lr, lc); + }; + switch (searchDirection) { + case SearchDirection::Increasing: + while (visualColumn < limit && !isCellActive(lr, visualColumn)) + ++visualColumn; + break; + case SearchDirection::Decreasing: + while (visualColumn > limit && !isCellActive(lr, visualColumn)) + --visualColumn; + break; + } + return visualColumn; +} + /*! \internal Returns the visual rect for the given \a span. @@ -1800,35 +1860,34 @@ QModelIndex QTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifi break; } case MoveHome: - visualColumn = 0; - while (visualColumn < right && d->isVisualColumnHiddenOrDisabled(visualRow, visualColumn)) - ++visualColumn; - if (modifiers & Qt::ControlModifier) { - visualRow = 0; - while (visualRow < bottom && d->isVisualRowHiddenOrDisabled(visualRow, visualColumn)) - ++visualRow; - } + visualColumn = d->nextActiveVisualColumn(visualRow, 0, right, + QTableViewPrivate::SearchDirection::Increasing); + if (modifiers & Qt::ControlModifier) + visualRow = d->nextActiveVisualRow(0, visualColumn, bottom, + QTableViewPrivate::SearchDirection::Increasing); break; case MoveEnd: - visualColumn = right; + visualColumn = d->nextActiveVisualColumn(visualRow, right, -1, + QTableViewPrivate::SearchDirection::Decreasing); if (modifiers & Qt::ControlModifier) - visualRow = bottom; + visualRow = d->nextActiveVisualRow(bottom, current.column(), -1, + QTableViewPrivate::SearchDirection::Decreasing); break; case MovePageUp: { - int newRow = rowAt(visualRect(current).bottom() - d->viewport->height()); - if (newRow == -1) { - int visualRow = 0; - while (visualRow < bottom && isRowHidden(d->logicalRow(visualRow))) - ++visualRow; - newRow = d->logicalRow(visualRow); - } - return d->model->index(newRow, current.column(), d->root); + int newLogicalRow = rowAt(visualRect(current).bottom() - d->viewport->height()); + int visualRow = (newLogicalRow == -1 ? 0 : d->visualRow(newLogicalRow)); + visualRow = d->nextActiveVisualRow(visualRow, current.column(), bottom, + QTableViewPrivate::SearchDirection::Increasing); + newLogicalRow = d->logicalRow(visualRow); + return d->model->index(newLogicalRow, current.column(), d->root); } case MovePageDown: { - int newRow = rowAt(visualRect(current).top() + d->viewport->height()); - if (newRow == -1) - newRow = d->logicalRow(bottom); - return d->model->index(newRow, current.column(), d->root); + int newLogicalRow = rowAt(visualRect(current).top() + d->viewport->height()); + int visualRow = (newLogicalRow == -1 ? bottom : d->visualRow(newLogicalRow)); + visualRow = d->nextActiveVisualRow(visualRow, current.column(), -1, + QTableViewPrivate::SearchDirection::Decreasing); + newLogicalRow = d->logicalRow(visualRow); + return d->model->index(newLogicalRow, current.column(), d->root); }} d->visualCursor = QPoint(visualColumn, visualRow); diff --git a/src/widgets/itemviews/qtableview_p.h b/src/widgets/itemviews/qtableview_p.h index 805787597c..a50e6b6410 100644 --- a/src/widgets/itemviews/qtableview_p.h +++ b/src/widgets/itemviews/qtableview_p.h @@ -234,16 +234,16 @@ public: inline bool isCellEnabled(int row, int column) const { return isIndexEnabled(model->index(row, column, root)); } - inline bool isVisualRowHiddenOrDisabled(int row, int column) const { - int r = logicalRow(row); - int c = logicalColumn(column); - return isRowHidden(r) || !isCellEnabled(r, c); - } - inline bool isVisualColumnHiddenOrDisabled(int row, int column) const { - int r = logicalRow(row); - int c = logicalColumn(column); - return isColumnHidden(c) || !isCellEnabled(r, c); - } + + enum class SearchDirection + { + Increasing, + Decreasing + }; + int nextActiveVisualRow(int rowToStart, int column, int limit, + SearchDirection searchDirection) const; + int nextActiveVisualColumn(int row, int columnToStart, int limit, + SearchDirection searchDirection) const; QRect visualSpanRect(const QSpanCollection::Span &span) const; diff --git a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp index ab746dfee8..1b95b5a3ca 100644 --- a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp +++ b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp @@ -1264,19 +1264,47 @@ void tst_QTableView::moveCursorStrikesBack_data() for (int i = 0; i < 7; ++i) fullList << i; - QTest::newRow("All disabled, wrap forward. Timeout => FAIL") << -1 << -1 + QTest::newRow("All disabled, wrap forward. => invalid index") << -1 << -1 << fullList << fullList << QRect() << 1 << 0 << (IntList() << int(QtTestTableView::MoveNext)) - << 1 << 0; + << -1 << -1; - QTest::newRow("All disabled, wrap backwards. Timeout => FAIL") << -1 << -1 + QTest::newRow("All disabled, wrap backwards. => invalid index") << -1 << -1 << fullList << fullList << QRect() << 1 << 0 << (IntList() << int(QtTestTableView::MovePrevious)) + << -1 << -1; + + QTest::newRow("Last column disabled, MoveEnd. QTBUG-72400") << -1 << -1 + << IntList() + << (IntList() << 6) + << QRect() + << 0 << 0 << (IntList() << int(QtTestTableView::MoveEnd)) + << 0 << 5; + + QTest::newRow("First column disabled, MoveHome. QTBUG-72400") << -1 << -1 + << IntList() + << (IntList() << 0) + << QRect() + << 0 << 6 << (IntList() << int(QtTestTableView::MoveHome)) + << 0 << 1; + + QTest::newRow("First row disabled, MovePageUp. QTBUG-72400") << -1 << -1 + << (IntList() << 0) + << IntList() + << QRect() + << 2 << 0 << (IntList() << int(QtTestTableView::MovePageUp)) << 1 << 0; + + QTest::newRow("Last row disabled, MovePageDown. QTBUG-72400") << -1 << -1 + << (IntList() << 6) + << IntList() + << QRect() + << 4 << 0 << (IntList() << int(QtTestTableView::MovePageDown)) + << 5 << 0; } void tst_QTableView::moveCursorStrikesBack() @@ -1302,6 +1330,9 @@ void tst_QTableView::moveCursorStrikesBack() if (span.height() && span.width()) view.setSpan(span.top(), span.left(), span.height(), span.width()); view.show(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + // resize to make sure there are scrollbars + view.resize(view.columnWidth(0) * 7, view.rowHeight(0) * 7); QModelIndex index = model.index(startRow, startColumn); view.setCurrentIndex(index); @@ -1320,9 +1351,6 @@ void tst_QTableView::moveCursorStrikesBack() newColumn = newIndex.column(); } - // expected fails, task 119433 - if(newRow == -1) - return; QCOMPARE(newRow, expectedRow); QCOMPARE(newColumn, expectedColumn); } From 5fd48d78d59128cf57a1c4eae3980c23497a8def Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 17 Dec 2018 16:22:39 +0100 Subject: [PATCH 0686/1650] Bump copyright year to 2019 Task-number: QTBUG-72635 Change-Id: Idc9bd97fe873b332d7ff72cb44a00334a472404f Reviewed-by: Friedemann Kleint Reviewed-by: Alex Blasche Reviewed-by: Paul Wicking --- doc/global/config.qdocconf | 2 +- doc/global/html-footer-online.qdocconf | 2 +- doc/global/html-footer.qdocconf | 2 +- doc/global/qt-module-defaults-online.qdocconf | 2 +- mkspecs/features/qt_targets.prf | 2 +- src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp | 2 +- src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp | 2 +- src/widgets/dialogs/qmessagebox.cpp | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/global/config.qdocconf b/doc/global/config.qdocconf index 81190c2478..0b276c400f 100644 --- a/doc/global/config.qdocconf +++ b/doc/global/config.qdocconf @@ -3,7 +3,7 @@ dita.metadata.default.author = Qt Project dita.metadata.default.permissions = all dita.metadata.default.publisher = Qt Project -dita.metadata.default.copyryear = 2018 +dita.metadata.default.copyryear = 2019 dita.metadata.default.copyrholder = The Qt Company Ltd dita.metadata.default.audience = programmer diff --git a/doc/global/html-footer-online.qdocconf b/doc/global/html-footer-online.qdocconf index f2631555c1..c4465fce66 100644 --- a/doc/global/html-footer-online.qdocconf +++ b/doc/global/html-footer-online.qdocconf @@ -78,7 +78,7 @@ HTML.footer += \ " \n" \ "

    \n" \ "
    \n" \ diff --git a/doc/global/html-footer.qdocconf b/doc/global/html-footer.qdocconf index c0122a7c4f..04f7fa0d79 100644 --- a/doc/global/html-footer.qdocconf +++ b/doc/global/html-footer.qdocconf @@ -8,7 +8,7 @@ HTML.footer = \ "\n" \ "
    \n" \ "

    \n" \ - " © 2018 The Qt Company Ltd.\n" \ + " © 2019 The Qt Company Ltd.\n" \ " Documentation contributions included herein are the copyrights of\n" \ " their respective owners.
    " \ " The documentation provided herein is licensed under the terms of the" \ diff --git a/doc/global/qt-module-defaults-online.qdocconf b/doc/global/qt-module-defaults-online.qdocconf index 1bed0c7934..f2e897db65 100644 --- a/doc/global/qt-module-defaults-online.qdocconf +++ b/doc/global/qt-module-defaults-online.qdocconf @@ -5,7 +5,7 @@ HTML.footer = \ "

    \n" \ "

    \n" \ - " © 2018 The Qt Company Ltd.\n" \ + " © 2019 The Qt Company Ltd.\n" \ " Documentation contributions included herein are the copyrights of\n" \ " their respective owners. " \ " The documentation provided herein is licensed under the terms of the" \ diff --git a/mkspecs/features/qt_targets.prf b/mkspecs/features/qt_targets.prf index 317d975b71..b3c289a90b 100644 --- a/mkspecs/features/qt_targets.prf +++ b/mkspecs/features/qt_targets.prf @@ -1,4 +1,4 @@ QMAKE_TARGET_COMPANY = The Qt Company Ltd. isEmpty(QMAKE_TARGET_PRODUCT): QMAKE_TARGET_PRODUCT = Qt5 isEmpty(QMAKE_TARGET_DESCRIPTION): QMAKE_TARGET_DESCRIPTION = C++ Application Development Framework -QMAKE_TARGET_COPYRIGHT = Copyright (C) 2018 The Qt Company Ltd. +QMAKE_TARGET_COPYRIGHT = Copyright (C) 2019 The Qt Company Ltd. diff --git a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp index 738905a9a0..7c6f0bdeef 100644 --- a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp +++ b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp @@ -62,7 +62,7 @@ static const char docTypeHeader[] = #define PROGRAMNAME "qdbuscpp2xml" #define PROGRAMVERSION "0.2" -#define PROGRAMCOPYRIGHT "Copyright (C) 2018 The Qt Company Ltd." +#define PROGRAMCOPYRIGHT "Copyright (C) 2019 The Qt Company Ltd." static QString outputFile; static int flags; diff --git a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp index 5b76502c94..ab7726a01f 100644 --- a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp +++ b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp @@ -46,7 +46,7 @@ #define PROGRAMNAME "qdbusxml2cpp" #define PROGRAMVERSION "0.8" -#define PROGRAMCOPYRIGHT "Copyright (C) 2018 The Qt Company Ltd." +#define PROGRAMCOPYRIGHT "Copyright (C) 2019 The Qt Company Ltd." #define ANNOTATION_NO_WAIT "org.freedesktop.DBus.Method.NoReply" diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index ffbbe82856..e8f34ec946 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -1856,7 +1856,7 @@ void QMessageBox::aboutQt(QWidget *parent, const QString &title) "

    Qt and the Qt logo are trademarks of The Qt Company Ltd.

    " "

    Qt is The Qt Company Ltd product developed as an open source " "project. See %3 for more information.

    " - ).arg(QStringLiteral("2018"), + ).arg(QStringLiteral("2019"), QStringLiteral("qt.io/licensing"), QStringLiteral("qt.io")); QMessageBox *msgBox = new QMessageBox(parent); From 7fc427ba23a624a433d93e1c604d870656835305 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lund=20Martsum?= Date: Tue, 4 Dec 2018 13:31:39 +0100 Subject: [PATCH 0687/1650] QToolTip - set correct screen before resize In order to get a correctly not truncated size we need the hint to be calculated based on the screen it is about to be shown on. This patch places some code in QWidgetPrivate that is used by QMenu and QToolTip + can be used to solve similar problems in the future. Task-number: QTBUG-72306 Change-Id: I58c058761f71b4a7675b6a078be62aa813ead752 Reviewed-by: Morten Kristensen Reviewed-by: Oliver Wolff --- src/widgets/kernel/qtooltip.cpp | 9 +++++++++ src/widgets/kernel/qwidget.cpp | 21 +++++++++++++++++++++ src/widgets/kernel/qwidget_p.h | 2 ++ src/widgets/widgets/qmenu.cpp | 20 ++------------------ src/widgets/widgets/qmenu_p.h | 1 - 5 files changed, 34 insertions(+), 19 deletions(-) diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp index 2e6575c163..9d8b0062f5 100644 --- a/src/widgets/kernel/qtooltip.cpp +++ b/src/widgets/kernel/qtooltip.cpp @@ -41,6 +41,7 @@ #endif #include +#include #include #include @@ -127,6 +128,7 @@ public: ~QTipLabel(); static QTipLabel *instance; + void adjustTooltipScreen(const QPoint &pos); void updateSize(const QPoint &pos); bool eventFilter(QObject *, QEvent *) override; @@ -222,6 +224,12 @@ void QTipLabel::reuseTip(const QString &text, int msecDisplayTime, const QPoint void QTipLabel::updateSize(const QPoint &pos) { +#ifndef Q_OS_WINRT + // ### The code below does not always work well on WinRT + // (e.g COIN fails an auto test - tst_QToolTip::qtbug64550_stylesheet - QTBUG-72652) + d_func()->setScreenForPoint(pos); +#endif + // Ensure that we get correct sizeHints by placing this window on the right screen. QFontMetrics fm(font()); QSize extra(1, 0); // Make it look good with the default ToolTip font on Mac, which has a small descent. @@ -229,6 +237,7 @@ void QTipLabel::updateSize(const QPoint &pos) ++extra.rheight(); QSize sh = sizeHint(); if (wordWrap()) { + // ### When the above WinRT code is fixed, windowhandle should be used to find the screen. QScreen *screen = QGuiApplication::screenAt(pos); if (!screen) screen = QGuiApplication::primaryScreen(); diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index bcfae46155..2a94b25ec9 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -2571,6 +2571,27 @@ void QWidgetPrivate::createWinId() } } +/*! +\internal +Ensures that the widget is set on the screen point is on. This is handy getting a correct +size hint before a resize in e.g QMenu and QToolTip +*/ + +void QWidgetPrivate::setScreenForPoint(const QPoint &pos) +{ + Q_Q(QWidget); + if (!q->isWindow()) + return; + // Find the screen for pos and make the widget undertand it is on that screen. + const QScreen *currentScreen = windowHandle() ? windowHandle()->screen() : nullptr; + QScreen *actualScreen = QGuiApplication::screenAt(pos); + if (actualScreen && currentScreen != actualScreen) { + if (!windowHandle()) // Try to create a window handle if not created. + createWinId(); + if (windowHandle()) + windowHandle()->setScreen(actualScreen); + } +} /*! \internal diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index be45c4c868..6f1ce67c4c 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -355,6 +355,8 @@ public: void createRecursively(); void createWinId(); + void setScreenForPoint(const QPoint &pos); + void createTLExtra(); void createExtra(); void deleteExtra(); diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index c79e88f094..e3c29ff6ee 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -896,23 +896,6 @@ void QMenuPrivate::_q_overrideMenuActionDestroyed() menuAction=defaultMenuAction; } -void QMenuPrivate::adjustMenuScreen(const QPoint &p) -{ - Q_Q(QMenu); - // The windowHandle must point to the screen where the menu will be shown. - // The (item) size calculations depend on the menu screen, - // so a wrong screen would often cause wrong sizes (on high DPI) - const QScreen *currentScreen = q->windowHandle() ? q->windowHandle()->screen() : nullptr; - QScreen *actualScreen = QGuiApplication::screenAt(p); - if (actualScreen && currentScreen != actualScreen) { - if (!q->windowHandle()) // Try to create a window handle if not created. - createWinId(); - if (q->windowHandle()) - q->windowHandle()->setScreen(actualScreen); - itemsDirty = true; - } -} - void QMenuPrivate::updateLayoutDirection() { Q_Q(QMenu); @@ -2375,7 +2358,8 @@ void QMenu::popup(const QPoint &p, QAction *atAction) d->motions = 0; d->doChildEffects = true; d->updateLayoutDirection(); - d->adjustMenuScreen(p); + // Ensure that we get correct sizeHints by placing this window on the right screen. + d->setScreenForPoint(p); const bool contextMenu = d->isContextMenu(); if (d->lastContextMenu != contextMenu) { diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h index 721a35bf90..f740919dc7 100644 --- a/src/widgets/widgets/qmenu_p.h +++ b/src/widgets/widgets/qmenu_p.h @@ -456,7 +456,6 @@ public: bool hasMouseMoved(const QPoint &globalPos); - void adjustMenuScreen(const QPoint &p); void updateLayoutDirection(); QPointer platformMenu; From c68d83fd226813c86cd70a2018071b90e2bae0b3 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 17 Dec 2018 15:24:21 +0100 Subject: [PATCH 0688/1650] Update SQLite to 3.26.0 [ChangeLog][Third-Party Code] Updated bundled SQLite to version 3.26.0. Fixes: QTBUG-72631 Change-Id: Icbb1e2e247076d4ec1cea809f2940485c26c64ad Reviewed-by: Simon Hausmann Reviewed-by: Lars Knoll --- src/3rdparty/sqlite/qt_attribution.json | 4 +- src/3rdparty/sqlite/sqlite3.c | 2660 +++++++++++++++++------ src/3rdparty/sqlite/sqlite3.h | 142 +- 3 files changed, 2147 insertions(+), 659 deletions(-) diff --git a/src/3rdparty/sqlite/qt_attribution.json b/src/3rdparty/sqlite/qt_attribution.json index d00a95f1aa..542fa9efb9 100644 --- a/src/3rdparty/sqlite/qt_attribution.json +++ b/src/3rdparty/sqlite/qt_attribution.json @@ -6,8 +6,8 @@ "Description": "SQLite is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine.", "Homepage": "https://www.sqlite.org/", - "Version": "3.24.0", - "DownloadLocation": "https://www.sqlite.org/2018/sqlite-amalgamation-3240000.zip", + "Version": "3.26.0", + "DownloadLocation": "https://www.sqlite.org/2018/sqlite-amalgamation-3260000.zip", "License": "Public Domain", "Copyright": "The authors disclaim copyright to the source code. However, a license can be obtained if needed." } diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c index 7b525c36bb..d015df2c31 100644 --- a/src/3rdparty/sqlite/sqlite3.c +++ b/src/3rdparty/sqlite/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.25.2. By combining all the individual C code files into this +** version 3.26.0. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -260,6 +260,9 @@ static const char * const sqlite3azCompileOpt[] = { #if SQLITE_ENABLE_FTS5 "ENABLE_FTS5", #endif +#if SQLITE_ENABLE_GEOPOLY + "ENABLE_GEOPOLY", +#endif #if SQLITE_ENABLE_HIDDEN_COLUMNS "ENABLE_HIDDEN_COLUMNS", #endif @@ -290,6 +293,9 @@ static const char * const sqlite3azCompileOpt[] = { #if SQLITE_ENABLE_MULTIPLEX "ENABLE_MULTIPLEX", #endif +#if SQLITE_ENABLE_NORMALIZE + "ENABLE_NORMALIZE", +#endif #if SQLITE_ENABLE_NULL_TRIM "ENABLE_NULL_TRIM", #endif @@ -1156,9 +1162,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.25.2" -#define SQLITE_VERSION_NUMBER 3025002 -#define SQLITE_SOURCE_ID "2018-09-25 19:08:10 fb90e7189ae6d62e77ba3a308ca5d683f90bbe633cf681865365b8e92792d1c7" +#define SQLITE_VERSION "3.26.0" +#define SQLITE_VERSION_NUMBER 3026000 +#define SQLITE_SOURCE_ID "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -3050,6 +3056,7 @@ struct sqlite3_mem_methods { ** is invoked. ** **
    +** [[SQLITE_DBCONFIG_LOOKASIDE]] **
    SQLITE_DBCONFIG_LOOKASIDE
    **
    ^This option takes three additional arguments that determine the ** [lookaside memory allocator] configuration for the [database connection]. @@ -3072,6 +3079,7 @@ struct sqlite3_mem_methods { ** memory is in use leaves the configuration unchanged and returns ** [SQLITE_BUSY].)^
    ** +** [[SQLITE_DBCONFIG_ENABLE_FKEY]] **
    SQLITE_DBCONFIG_ENABLE_FKEY
    **
    ^This option is used to enable or disable the enforcement of ** [foreign key constraints]. There should be two additional arguments. @@ -3082,6 +3090,7 @@ struct sqlite3_mem_methods { ** following this call. The second parameter may be a NULL pointer, in ** which case the FK enforcement setting is not reported back.
    ** +** [[SQLITE_DBCONFIG_ENABLE_TRIGGER]] **
    SQLITE_DBCONFIG_ENABLE_TRIGGER
    **
    ^This option is used to enable or disable [CREATE TRIGGER | triggers]. ** There should be two additional arguments. @@ -3092,6 +3101,7 @@ struct sqlite3_mem_methods { ** following this call. The second parameter may be a NULL pointer, in ** which case the trigger setting is not reported back.
    ** +** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]] **
    SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER
    **
    ^This option is used to enable or disable the two-argument ** version of the [fts3_tokenizer()] function which is part of the @@ -3105,6 +3115,7 @@ struct sqlite3_mem_methods { ** following this call. The second parameter may be a NULL pointer, in ** which case the new setting is not reported back.
    ** +** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]] **
    SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION
    **
    ^This option is used to enable or disable the [sqlite3_load_extension()] ** interface independently of the [load_extension()] SQL function. @@ -3122,7 +3133,7 @@ struct sqlite3_mem_methods { ** be a NULL pointer, in which case the new setting is not reported back. **
    ** -**
    SQLITE_DBCONFIG_MAINDBNAME
    +** [[SQLITE_DBCONFIG_MAINDBNAME]]
    SQLITE_DBCONFIG_MAINDBNAME
    **
    ^This option is used to change the name of the "main" database ** schema. ^The sole argument is a pointer to a constant UTF8 string ** which will become the new schema name in place of "main". ^SQLite @@ -3131,6 +3142,7 @@ struct sqlite3_mem_methods { ** until after the database connection closes. **
    ** +** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]] **
    SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE
    **
    Usually, when a database in wal mode is closed or detached from a ** database handle, SQLite checks if this will mean that there are now no @@ -3144,7 +3156,7 @@ struct sqlite3_mem_methods { ** have been disabled - 0 if they are not disabled, 1 if they are. **
    ** -**
    SQLITE_DBCONFIG_ENABLE_QPSG
    +** [[SQLITE_DBCONFIG_ENABLE_QPSG]]
    SQLITE_DBCONFIG_ENABLE_QPSG
    **
    ^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates ** the [query planner stability guarantee] (QPSG). When the QPSG is active, ** a single SQL query statement will always use the same algorithm regardless @@ -3160,7 +3172,7 @@ struct sqlite3_mem_methods { ** following this call. **
    ** -**
    SQLITE_DBCONFIG_TRIGGER_EQP
    +** [[SQLITE_DBCONFIG_TRIGGER_EQP]]
    SQLITE_DBCONFIG_TRIGGER_EQP
    **
    By default, the output of EXPLAIN QUERY PLAN commands does not ** include output for any operations performed by trigger programs. This ** option is used to set or clear (the default) a flag that governs this @@ -3172,7 +3184,7 @@ struct sqlite3_mem_methods { ** it is not disabled, 1 if it is. **
    ** -**
    SQLITE_DBCONFIG_RESET_DATABASE
    +** [[SQLITE_DBCONFIG_RESET_DATABASE]]
    SQLITE_DBCONFIG_RESET_DATABASE
    **
    Set the SQLITE_DBCONFIG_RESET_DATABASE flag and then run ** [VACUUM] in order to reset a database back to an empty database ** with no schema and no content. The following process works even for @@ -3191,6 +3203,18 @@ struct sqlite3_mem_methods { ** Because resetting a database is destructive and irreversible, the ** process requires the use of this obscure API and multiple steps to help ** ensure that it does not happen by accident. +** +** [[SQLITE_DBCONFIG_DEFENSIVE]]
    SQLITE_DBCONFIG_DEFENSIVE
    +**
    The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the +** "defensive" flag for a database connection. When the defensive +** flag is enabled, language features that allow ordinary SQL to +** deliberately corrupt the database file are disabled. The disabled +** features include but are not limited to the following: +**
      +**
    • The [PRAGMA writable_schema=ON] statement. +**
    • Writes to the [sqlite_dbpage] virtual table. +**
    • Direct writes to [shadow tables]. +**
    **
    **
    */ @@ -3204,7 +3228,8 @@ struct sqlite3_mem_methods { #define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */ #define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */ #define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */ -#define SQLITE_DBCONFIG_MAX 1009 /* Largest DBCONFIG */ +#define SQLITE_DBCONFIG_DEFENSIVE 1010 /* int int* */ +#define SQLITE_DBCONFIG_MAX 1010 /* Largest DBCONFIG */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes @@ -4642,9 +4667,19 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** on this hint by avoiding the use of [lookaside memory] so as not to ** deplete the limited store of lookaside memory. Future versions of ** SQLite may act on this hint differently. +** +** [[SQLITE_PREPARE_NORMALIZE]] ^(
    SQLITE_PREPARE_NORMALIZE
    +**
    The SQLITE_PREPARE_NORMALIZE flag indicates that a normalized +** representation of the SQL statement should be calculated and then +** associated with the prepared statement, which can be obtained via +** the [sqlite3_normalized_sql()] interface.)^ The semantics used to +** normalize a SQL statement are unspecified and subject to change. +** At a minimum, literal values will be replaced with suitable +** placeholders. ** */ #define SQLITE_PREPARE_PERSISTENT 0x01 +#define SQLITE_PREPARE_NORMALIZE 0x02 /* ** CAPI3REF: Compiling An SQL Statement @@ -4802,6 +4837,11 @@ SQLITE_API int sqlite3_prepare16_v3( ** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8 ** string containing the SQL text of prepared statement P with ** [bound parameters] expanded. +** ^The sqlite3_normalized_sql(P) interface returns a pointer to a UTF-8 +** string containing the normalized SQL text of prepared statement P. The +** semantics used to normalize a SQL statement are unspecified and subject +** to change. At a minimum, literal values will be replaced with suitable +** placeholders. ** ** ^(For example, if a prepared statement is created using the SQL ** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345 @@ -4817,14 +4857,16 @@ SQLITE_API int sqlite3_prepare16_v3( ** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time ** option causes sqlite3_expanded_sql() to always return NULL. ** -** ^The string returned by sqlite3_sql(P) is managed by SQLite and is -** automatically freed when the prepared statement is finalized. +** ^The strings returned by sqlite3_sql(P) and sqlite3_normalized_sql(P) +** are managed by SQLite and are automatically freed when the prepared +** statement is finalized. ** ^The string returned by sqlite3_expanded_sql(P), on the other hand, ** is obtained from [sqlite3_malloc()] and must be free by the application ** by passing it to [sqlite3_free()]. */ SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt); SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt); +SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt); /* ** CAPI3REF: Determine If An SQL Statement Writes The Database @@ -7314,6 +7356,9 @@ struct sqlite3_module { int (*xSavepoint)(sqlite3_vtab *pVTab, int); int (*xRelease)(sqlite3_vtab *pVTab, int); int (*xRollbackTo)(sqlite3_vtab *pVTab, int); + /* The methods above are in versions 1 and 2 of the sqlite_module object. + ** Those below are for version 3 and greater. */ + int (*xShadowName)(const char*); }; /* @@ -8236,6 +8281,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ +#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */ #define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19 @@ -9648,6 +9694,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); ** can use to customize and optimize their behavior. ** **
    +** [[SQLITE_VTAB_CONSTRAINT_SUPPORT]] **
    SQLITE_VTAB_CONSTRAINT_SUPPORT **
    Calls of the form ** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported, @@ -10417,7 +10464,7 @@ struct sqlite3_rtree_query_info { sqlite3_int64 iRowid; /* Rowid for current entry */ sqlite3_rtree_dbl rParentScore; /* Score of parent node */ int eParentWithin; /* Visibility of parent node */ - int eWithin; /* OUT: Visiblity */ + int eWithin; /* OUT: Visibility */ sqlite3_rtree_dbl rScore; /* OUT: Write the score here */ /* The following fields are only available in 3.8.11 and later */ sqlite3_value **apSqlParam; /* Original SQL values of parameters */ @@ -10913,12 +10960,38 @@ SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession); ** consecutively. There is no chance that the iterator will visit a change ** the applies to table X, then one for table Y, and then later on visit ** another change for table X. +** +** The behavior of sqlite3changeset_start_v2() and its streaming equivalent +** may be modified by passing a combination of +** [SQLITE_CHANGESETSTART_INVERT | supported flags] as the 4th parameter. +** +** Note that the sqlite3changeset_start_v2() API is still experimental +** and therefore subject to change. */ SQLITE_API int sqlite3changeset_start( sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */ int nChangeset, /* Size of changeset blob in bytes */ void *pChangeset /* Pointer to blob containing changeset */ ); +SQLITE_API int sqlite3changeset_start_v2( + sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */ + int nChangeset, /* Size of changeset blob in bytes */ + void *pChangeset, /* Pointer to blob containing changeset */ + int flags /* SESSION_CHANGESETSTART_* flags */ +); + +/* +** CAPI3REF: Flags for sqlite3changeset_start_v2 +** +** The following flags may passed via the 4th parameter to +** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]: +** +**
    SQLITE_CHANGESETAPPLY_INVERT
    +** Invert the changeset while iterating through it. This is equivalent to +** inverting a changeset using sqlite3changeset_invert() before applying it. +** It is an error to specify this flag with a patchset. +*/ +#define SQLITE_CHANGESETSTART_INVERT 0x0002 /* @@ -11573,7 +11646,7 @@ SQLITE_API int sqlite3changeset_apply_v2( ), void *pCtx, /* First argument passed to xConflict */ void **ppRebase, int *pnRebase, /* OUT: Rebase data */ - int flags /* Combination of SESSION_APPLY_* flags */ + int flags /* SESSION_CHANGESETAPPLY_* flags */ ); /* @@ -11591,8 +11664,14 @@ SQLITE_API int sqlite3changeset_apply_v2( ** causes the sessions module to omit this savepoint. In this case, if the ** caller has an open transaction or savepoint when apply_v2() is called, ** it may revert the partially applied changeset by rolling it back. +** +**
    SQLITE_CHANGESETAPPLY_INVERT
    +** Invert the changeset before applying it. This is equivalent to inverting +** a changeset using sqlite3changeset_invert() before applying it. It is +** an error to specify this flag with a patchset. */ #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001 +#define SQLITE_CHANGESETAPPLY_INVERT 0x0002 /* ** CAPI3REF: Constants Passed To The Conflict Handler @@ -11986,6 +12065,12 @@ SQLITE_API int sqlite3changeset_start_strm( int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn ); +SQLITE_API int sqlite3changeset_start_v2_strm( + sqlite3_changeset_iter **pp, + int (*xInput)(void *pIn, void *pData, int *pnData), + void *pIn, + int flags +); SQLITE_API int sqlite3session_changeset_strm( sqlite3_session *pSession, int (*xOutput)(void *pOut, const void *pData, int nData), @@ -12012,6 +12097,45 @@ SQLITE_API int sqlite3rebaser_rebase_strm( void *pOut ); +/* +** CAPI3REF: Configure global parameters +** +** The sqlite3session_config() interface is used to make global configuration +** changes to the sessions module in order to tune it to the specific needs +** of the application. +** +** The sqlite3session_config() interface is not threadsafe. If it is invoked +** while any other thread is inside any other sessions method then the +** results are undefined. Furthermore, if it is invoked after any sessions +** related objects have been created, the results are also undefined. +** +** The first argument to the sqlite3session_config() function must be one +** of the SQLITE_SESSION_CONFIG_XXX constants defined below. The +** interpretation of the (void*) value passed as the second parameter and +** the effect of calling this function depends on the value of the first +** parameter. +** +**
    +**
    SQLITE_SESSION_CONFIG_STRMSIZE
    +** By default, the sessions module streaming interfaces attempt to input +** and output data in approximately 1 KiB chunks. This operand may be used +** to set and query the value of this configuration setting. The pointer +** passed as the second argument must point to a value of type (int). +** If this value is greater than 0, it is used as the new streaming data +** chunk size for both input and output. Before returning, the (int) value +** pointed to by pArg is set to the final value of the streaming interface +** chunk size. +**
    +** +** This function returns SQLITE_OK if successful, or an SQLite error code +** otherwise. +*/ +SQLITE_API int sqlite3session_config(int op, void *pArg); + +/* +** CAPI3REF: Values for sqlite3session_config(). +*/ +#define SQLITE_SESSION_CONFIG_STRMSIZE 1 /* ** Make sure we can call this stuff from C++. @@ -15277,9 +15401,6 @@ SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager); SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager); SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen); SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3*); -# ifdef SQLITE_DIRECT_OVERFLOW_READ -SQLITE_PRIVATE int sqlite3PagerUseWal(Pager *pPager, Pgno); -# endif # ifdef SQLITE_ENABLE_SNAPSHOT SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot); SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot); @@ -15287,8 +15408,10 @@ SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager); SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot); SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager); # endif -#else -# define sqlite3PagerUseWal(x,y) 0 +#endif + +#ifdef SQLITE_DIRECT_OVERFLOW_READ +SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno); #endif #ifdef SQLITE_ENABLE_ZIPVFS @@ -15533,6 +15656,10 @@ SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void); /* Number of dirty pages as a percentage of the configured cache size */ SQLITE_PRIVATE int sqlite3PCachePercentDirty(PCache*); +#ifdef SQLITE_DIRECT_OVERFLOW_READ +SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache); +#endif + #endif /* _PCACHE_H_ */ /************** End of pcache.h **********************************************/ @@ -16038,12 +16165,14 @@ struct LookasideSlot { ** functions use a regular table table from hash.h.) ** ** Hash each FuncDef structure into one of the FuncDefHash.a[] slots. -** Collisions are on the FuncDef.u.pHash chain. +** Collisions are on the FuncDef.u.pHash chain. Use the SQLITE_FUNC_HASH() +** macro to compute a hash on the function name. */ #define SQLITE_FUNC_HASH_SZ 23 struct FuncDefHash { FuncDef *a[SQLITE_FUNC_HASH_SZ]; /* Hash table for functions */ }; +#define SQLITE_FUNC_HASH(C,L) (((C)+(L))%SQLITE_FUNC_HASH_SZ) #ifdef SQLITE_USER_AUTHENTICATION /* @@ -16104,7 +16233,7 @@ struct sqlite3 { Db *aDb; /* All backends */ int nDb; /* Number of backends currently in use */ u32 mDbFlags; /* flags recording internal state */ - u32 flags; /* flags settable by pragmas. See below */ + u64 flags; /* flags settable by pragmas. See below */ i64 lastRowid; /* ROWID of most recent insert (see above) */ i64 szMmap; /* Default mmap_size setting */ u32 nSchemaLock; /* Do not reset the schema when non-zero */ @@ -16270,14 +16399,17 @@ struct sqlite3 { #define SQLITE_TriggerEQP 0x01000000 /* Show trigger EXPLAIN QUERY PLAN */ #define SQLITE_ResetDatabase 0x02000000 /* Reset the database */ #define SQLITE_LegacyAlter 0x04000000 /* Legacy ALTER TABLE behaviour */ +#define SQLITE_NoSchemaError 0x08000000 /* Do not report schema parse errors*/ +#define SQLITE_Defensive 0x10000000 /* Input SQL is likely hostile */ /* Flags used only if debugging */ +#define HI(X) ((u64)(X)<<32) #ifdef SQLITE_DEBUG -#define SQLITE_SqlTrace 0x08000000 /* Debug print SQL as it executes */ -#define SQLITE_VdbeListing 0x10000000 /* Debug listings of VDBE programs */ -#define SQLITE_VdbeTrace 0x20000000 /* True to trace VDBE execution */ -#define SQLITE_VdbeAddopTrace 0x40000000 /* Trace sqlite3VdbeAddOp() calls */ -#define SQLITE_VdbeEQP 0x80000000 /* Debug EXPLAIN QUERY PLAN */ +#define SQLITE_SqlTrace HI(0x0001) /* Debug print SQL as it executes */ +#define SQLITE_VdbeListing HI(0x0002) /* Debug listings of VDBE progs */ +#define SQLITE_VdbeTrace HI(0x0004) /* True to trace VDBE execution */ +#define SQLITE_VdbeAddopTrace HI(0x0008) /* Trace sqlite3VdbeAddOp() calls */ +#define SQLITE_VdbeEQP HI(0x0010) /* Debug EXPLAIN QUERY PLAN */ #endif /* @@ -16411,8 +16543,9 @@ struct FuncDestructor { ** single query - might change over time */ #define SQLITE_FUNC_AFFINITY 0x4000 /* Built-in affinity() function */ #define SQLITE_FUNC_OFFSET 0x8000 /* Built-in sqlite_offset() function */ -#define SQLITE_FUNC_WINDOW 0x10000 /* Built-in window-only function */ -#define SQLITE_FUNC_WINDOW_SIZE 0x20000 /* Requires partition size as arg. */ +#define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */ +#define SQLITE_FUNC_WINDOW_SIZE 0x20000 /* Requires partition size as arg. */ +#define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */ /* ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are @@ -16488,10 +16621,13 @@ struct FuncDestructor { #define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \ {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \ SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xFinal,0,#zName, {0}} - #define WAGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue, xInverse, f) \ {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|f, \ SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,xInverse,#zName, {0}} +#define INTERNAL_FUNCTION(zName, nArg, xFunc) \ + {nArg, SQLITE_FUNC_INTERNAL|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \ + 0, 0, xFunc, 0, 0, 0, #zName, {0} } + /* ** All current savepoints are stored in a linked list starting at @@ -16676,6 +16812,9 @@ struct VTable { struct Table { char *zName; /* Name of the table or view */ Column *aCol; /* Information about each column */ +#ifdef SQLITE_ENABLE_NORMALIZE + Hash *pColHash; /* All columns indexed by name */ +#endif Index *pIndex; /* List of SQL indexes on this table. */ Select *pSelect; /* NULL for tables. Points to definition if a view. */ FKey *pFKey; /* Linked list of all foreign keys in this table */ @@ -16726,6 +16865,7 @@ struct Table { #define TF_StatsUsed 0x0100 /* Query planner decisions affected by ** Index.aiRowLogEst[] values */ #define TF_HasNotNull 0x0200 /* Contains NOT NULL constraints */ +#define TF_Shadow 0x0400 /* True for a shadow table */ /* ** Test to see whether or not a table is a virtual table. This is @@ -17012,6 +17152,12 @@ struct IndexSample { tRowcnt *anDLt; /* Est. number of distinct keys less than this sample */ }; +/* +** Possible values to use within the flags argument to sqlite3GetToken(). +*/ +#define SQLITE_TOKEN_QUOTED 0x1 /* Token is a quoted identifier. */ +#define SQLITE_TOKEN_KEYWORD 0x2 /* Token is a keyword. */ + /* ** Each token coming out of the lexer is an instance of ** this structure. Tokens are also used as part of an expression. @@ -17193,11 +17339,11 @@ struct Expr { ** TK_COLUMN: the value of p5 for OP_Column ** TK_AGG_FUNCTION: nesting depth */ AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ - Table *pTab; /* Table for TK_COLUMN expressions. Can be NULL - ** for a column of an index on an expression */ -#ifndef SQLITE_OMIT_WINDOWFUNC - Window *pWin; /* Window definition for window functions */ -#endif + union { + Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL + ** for a column of an index on an expression */ + Window *pWin; /* TK_FUNCTION: Window definition for the func */ + } y; }; /* @@ -17227,6 +17373,7 @@ struct Expr { #define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */ #define EP_Alias 0x400000 /* Is an alias for a result set column */ #define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */ +#define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */ /* ** The EP_Propagate mask is a set of properties that automatically propagate @@ -17912,6 +18059,7 @@ struct AuthContext { */ #define OPFLAG_NCHANGE 0x01 /* OP_Insert: Set to update db->nChange */ /* Also used in P2 (not P5) of OP_Delete */ +#define OPFLAG_NOCHNG 0x01 /* OP_VColumn nochange for UPDATE */ #define OPFLAG_EPHEM 0x01 /* OP_Column: Ephemeral output is ok */ #define OPFLAG_LASTROWID 0x20 /* Set to update db->lastRowid */ #define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */ @@ -18130,6 +18278,7 @@ struct Sqlite3Config { int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */ #endif int bLocaltimeFault; /* True to fail localtime() calls */ + int bInternalFunctions; /* Internal SQL functions are visible */ int iOnceResetThreshold; /* When to reset OP_Once counters */ u32 szSorterRef; /* Min size in bytes to use sorter-refs */ }; @@ -18383,6 +18532,7 @@ SQLITE_PRIVATE int sqlite3IsIdChar(u8); */ SQLITE_PRIVATE int sqlite3StrICmp(const char*,const char*); SQLITE_PRIVATE int sqlite3Strlen30(const char*); +#define sqlite3Strlen30NN(C) (strlen(C)&0x3fffffff) SQLITE_PRIVATE char *sqlite3ColumnType(Column*,char*); #define sqlite3StrNICmp sqlite3_strnicmp @@ -18499,6 +18649,7 @@ SQLITE_PRIVATE void *sqlite3TestTextToPtr(const char*); SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView*, const Expr*, u8); SQLITE_PRIVATE void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*); SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*); +SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView*, const SrcList*); SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8); SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView*, const With*, u8); #ifndef SQLITE_OMIT_WINDOWFUNC @@ -18731,11 +18882,15 @@ SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*); SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*); SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); SQLITE_PRIVATE int sqlite3IsRowid(const char*); +#ifdef SQLITE_ENABLE_NORMALIZE +SQLITE_PRIVATE int sqlite3IsRowidN(const char*, int); +#endif SQLITE_PRIVATE void sqlite3GenerateRowDelete( Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int); SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int); SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int); SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse*,int); +SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn(Expr*,int*,int); SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int, u8,u8,int,int*,int*,Upsert*); #ifdef SQLITE_ENABLE_NULL_TRIM @@ -18756,6 +18911,9 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int); SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int); SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*); SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int); +#ifdef SQLITE_ENABLE_NORMALIZE +SQLITE_PRIVATE FuncDef *sqlite3FunctionSearchN(int,const char*,int); +#endif SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(FuncDef*,int); SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8); SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void); @@ -18913,6 +19071,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Toke SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*); SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*); SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *); +SQLITE_PRIVATE int sqlite3WritableSchema(sqlite3*); SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *, const char *); SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int); SQLITE_PRIVATE int sqlite3AddInt64(i64*,i64); @@ -18959,6 +19118,9 @@ SQLITE_PRIVATE void sqlite3AlterFunctions(void); SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*); SQLITE_PRIVATE void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*); SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *); +#ifdef SQLITE_ENABLE_NORMALIZE +SQLITE_PRIVATE int sqlite3GetTokenNormalized(const unsigned char *, int *, int *); +#endif SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...); SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*, int); SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr *, int, int); @@ -19116,6 +19278,9 @@ SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*); SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int); SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); SQLITE_PRIVATE void sqlite3ParserReset(Parse*); +#ifdef SQLITE_ENABLE_NORMALIZE +SQLITE_PRIVATE void sqlite3Normalize(Vdbe*, const char*, int, u8); +#endif SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*); SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*); SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *); @@ -19577,6 +19742,7 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { 0, /* xTestCallback */ #endif 0, /* bLocaltimeFault */ + 0, /* bInternalFunctions */ 0x7ffffffe, /* iOnceResetThreshold */ SQLITE_DEFAULT_SORTERREF_SIZE /* szSorterRef */ }; @@ -20068,6 +20234,9 @@ struct Vdbe { yDbMask lockMask; /* Subset of btreeMask that requires a lock */ u32 aCounter[7]; /* Counters used by sqlite3_stmt_status() */ char *zSql; /* Text of the SQL statement that generated this */ +#ifdef SQLITE_ENABLE_NORMALIZE + char *zNormSql; /* Normalization of the associated SQL statement */ +#endif void *pFree; /* Free this when deleting the vdbe */ VdbeFrame *pFrame; /* Parent frame */ VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */ @@ -20130,7 +20299,9 @@ int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*); SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*); SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*); +#ifndef SQLITE_OMIT_EXPLAIN SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*); +#endif SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*); SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int); SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*); @@ -20169,7 +20340,9 @@ SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*); #ifndef SQLITE_OMIT_WINDOWFUNC SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*); #endif +#ifndef SQLITE_OMIT_EXPLAIN SQLITE_PRIVATE const char *sqlite3OpcodeName(int); +#endif SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n); SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int); @@ -28296,6 +28469,42 @@ SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 m } } +/* +** Generate a human-readable description of a SrcList object. +*/ +SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ + int i; + for(i=0; inSrc; i++){ + const struct SrcList_item *pItem = &pSrc->a[i]; + StrAccum x; + char zLine[100]; + sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); + sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor); + if( pItem->zDatabase ){ + sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName); + }else if( pItem->zName ){ + sqlite3_str_appendf(&x, " %s", pItem->zName); + } + if( pItem->pTab ){ + sqlite3_str_appendf(&x, " tabname=%Q", pItem->pTab->zName); + } + if( pItem->zAlias ){ + sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias); + } + if( pItem->fg.jointype & JT_LEFT ){ + sqlite3_str_appendf(&x, " LEFT-JOIN"); + } + sqlite3StrAccumFinish(&x); + sqlite3TreeViewItem(pView, zLine, inSrc-1); + if( pItem->pSelect ){ + sqlite3TreeViewSelect(pView, pItem->pSelect, 0); + } + if( pItem->fg.isTabFunc ){ + sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); + } + sqlite3TreeViewPop(pView); + } +} /* ** Generate a human-readable description of a Select object. @@ -28350,39 +28559,9 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m } #endif if( p->pSrc && p->pSrc->nSrc ){ - int i; pView = sqlite3TreeViewPush(pView, (n--)>0); sqlite3TreeViewLine(pView, "FROM"); - for(i=0; ipSrc->nSrc; i++){ - struct SrcList_item *pItem = &p->pSrc->a[i]; - StrAccum x; - char zLine[100]; - sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); - sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor); - if( pItem->zDatabase ){ - sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName); - }else if( pItem->zName ){ - sqlite3_str_appendf(&x, " %s", pItem->zName); - } - if( pItem->pTab ){ - sqlite3_str_appendf(&x, " tabname=%Q", pItem->pTab->zName); - } - if( pItem->zAlias ){ - sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias); - } - if( pItem->fg.jointype & JT_LEFT ){ - sqlite3_str_appendf(&x, " LEFT-JOIN"); - } - sqlite3StrAccumFinish(&x); - sqlite3TreeViewItem(pView, zLine, ipSrc->nSrc-1); - if( pItem->pSelect ){ - sqlite3TreeViewSelect(pView, pItem->pSelect, 0); - } - if( pItem->fg.isTabFunc ){ - sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); - } - sqlite3TreeViewPop(pView); - } + sqlite3TreeViewSrcList(pView, p->pSrc); sqlite3TreeViewPop(pView); } if( p->pWhere ){ @@ -28672,7 +28851,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m }else{ pFarg = pExpr->x.pList; #ifndef SQLITE_OMIT_WINDOWFUNC - pWin = pExpr->pWin; + pWin = pExpr->y.pWin; #else pWin = 0; #endif @@ -31500,6 +31679,20 @@ static unsigned int strHash(const char *z){ } return h; } +#ifdef SQLITE_ENABLE_NORMALIZE +static unsigned int strHashN(const char *z, int n){ + unsigned int h = 0; + int i; + for(i=0; iht ){ /*OPTIMIZATION-IF-TRUE*/ + struct _ht *pEntry; + h = strHashN(pKey, nKey) % pH->htsize; + pEntry = &pH->ht[h]; + elem = pEntry->chain; + count = pEntry->count; + }else{ + h = 0; + elem = pH->first; + count = pH->count; + } + if( pHash ) *pHash = h; + while( count-- ){ + assert( elem!=0 ); + if( sqlite3StrNICmp(elem->pKey,pKey,nKey)==0 ){ + return elem; + } + elem = elem->next; + } + return &nullElement; +} +#endif /* SQLITE_ENABLE_NORMALIZE */ /* Remove a single entry from the hash table given a pointer to that ** element and a hash on the element's key. @@ -31655,6 +31882,14 @@ SQLITE_PRIVATE void *sqlite3HashFind(const Hash *pH, const char *pKey){ assert( pKey!=0 ); return findElementWithHash(pH, pKey, 0)->data; } +#ifdef SQLITE_ENABLE_NORMALIZE +SQLITE_PRIVATE void *sqlite3HashFindN(const Hash *pH, const char *pKey, int nKey){ + assert( pH!=0 ); + assert( pKey!=0 ); + assert( nKey>=0 ); + return findElementWithHashN(pH, pKey, nKey, 0)->data; +} +#endif /* SQLITE_ENABLE_NORMALIZE */ /* Insert an element into the hash table pH. The key is pKey ** and the data is "data". @@ -32037,12 +32272,10 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ #define SQLITE_FSFLAGS_IS_MSDOS 0x1 /* -** If we are to be thread-safe, include the pthreads header and define -** the SQLITE_UNIX_THREADS macro. +** If we are to be thread-safe, include the pthreads header. */ #if SQLITE_THREADSAFE /* # include */ -# define SQLITE_UNIX_THREADS 1 #endif /* @@ -33218,8 +33451,7 @@ struct unixFileId { /* ** An instance of the following structure is allocated for each open -** inode. Or, on LinuxThreads, there is one of these structures for -** each inode opened by each thread. +** inode. ** ** A single inode can have multiple file descriptors, so each unixFile ** structure contains a pointer to an instance of this object and this @@ -33265,13 +33497,16 @@ struct unixInodeInfo { /* ** A lists of all unixInodeInfo objects. +** +** Must hold unixBigLock in order to read or write this variable. */ static unixInodeInfo *inodeList = 0; /* All unixInodeInfo objects */ #ifdef SQLITE_DEBUG /* -** True if the inode mutex is held, or not. Used only within assert() -** to help verify correct mutex usage. +** True if the inode mutex (on the unixFile.pFileMutex field) is held, or not. +** This routine is used only within assert() to help verify correct mutex +** usage. */ int unixFileMutexHeld(unixFile *pFile){ assert( pFile->pInode ); @@ -33399,8 +33634,8 @@ static void closePendingFds(unixFile *pFile){ /* ** Release a unixInodeInfo structure previously allocated by findInodeInfo(). ** -** The mutex entered using the unixEnterMutex() function must be held -** when this function is called. +** The global mutex must be held when this routine is called, but the mutex +** on the inode being deleted must NOT be held. */ static void releaseInodeInfo(unixFile *pFile){ unixInodeInfo *pInode = pFile->pInode; @@ -33435,8 +33670,7 @@ static void releaseInodeInfo(unixFile *pFile){ ** describes that file descriptor. Create a new one if necessary. The ** return value might be uninitialized if an error occurs. ** -** The mutex entered using the unixEnterMutex() function must be held -** when this function is called. +** The global mutex must held when calling this routine. ** ** Return an appropriate error code. */ @@ -33497,6 +33731,7 @@ static int findInodeInfo( #else fileId.ino = (u64)statbuf.st_ino; #endif + assert( unixMutexHeld() ); pInode = inodeList; while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){ pInode = pInode->pNext; @@ -33516,6 +33751,7 @@ static int findInodeInfo( } } pInode->nRef = 1; + assert( unixMutexHeld() ); pInode->pNext = inodeList; pInode->pPrev = 0; if( inodeList ) inodeList->pPrev = pInode; @@ -36313,18 +36549,18 @@ static int unixGetpagesize(void){ ** ** The following fields are read-only after the object is created: ** -** fid +** hShm ** zFilename ** -** Either unixShmNode.mutex must be held or unixShmNode.nRef==0 and +** Either unixShmNode.pShmMutex must be held or unixShmNode.nRef==0 and ** unixMutexHeld() is true when reading or writing any other field ** in this structure. */ struct unixShmNode { unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */ - sqlite3_mutex *mutex; /* Mutex to access this object */ + sqlite3_mutex *pShmMutex; /* Mutex to access this object */ char *zFilename; /* Name of the mmapped file */ - int h; /* Open file descriptor */ + int hShm; /* Open file descriptor */ int szRegion; /* Size of shared-memory regions */ u16 nRegion; /* Size of array apRegion */ u8 isReadonly; /* True if read-only */ @@ -36346,16 +36582,16 @@ struct unixShmNode { ** The following fields are initialized when this object is created and ** are read-only thereafter: ** -** unixShm.pFile +** unixShm.pShmNode ** unixShm.id ** -** All other fields are read/write. The unixShm.pFile->mutex must be held -** while accessing any read/write fields. +** All other fields are read/write. The unixShm.pShmNode->pShmMutex must +** be held while accessing any read/write fields. */ struct unixShm { unixShmNode *pShmNode; /* The underlying unixShmNode object */ unixShm *pNext; /* Next unixShm with the same unixShmNode */ - u8 hasMutex; /* True if holding the unixShmNode mutex */ + u8 hasMutex; /* True if holding the unixShmNode->pShmMutex */ u8 id; /* Id of this connection within its unixShmNode */ u16 sharedMask; /* Mask of shared locks held */ u16 exclMask; /* Mask of exclusive locks held */ @@ -36385,7 +36621,8 @@ static int unixShmSystemLock( /* Access to the unixShmNode object is serialized by the caller */ pShmNode = pFile->pInode->pShmNode; - assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->mutex) ); + assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) ); + assert( pShmNode->nRef>0 || unixMutexHeld() ); /* Shared locks never span more than one byte */ assert( n==1 || lockType!=F_RDLCK ); @@ -36393,13 +36630,13 @@ static int unixShmSystemLock( /* Locks are within range */ assert( n>=1 && n<=SQLITE_SHM_NLOCK ); - if( pShmNode->h>=0 ){ + if( pShmNode->hShm>=0 ){ /* Initialize the locking parameters */ f.l_type = lockType; f.l_whence = SEEK_SET; f.l_start = ofst; f.l_len = n; - rc = osSetPosixAdvisoryLock(pShmNode->h, &f, pFile); + rc = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile); rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY; } @@ -36471,18 +36708,18 @@ static void unixShmPurge(unixFile *pFd){ int nShmPerMap = unixShmRegionPerMap(); int i; assert( p->pInode==pFd->pInode ); - sqlite3_mutex_free(p->mutex); + sqlite3_mutex_free(p->pShmMutex); for(i=0; inRegion; i+=nShmPerMap){ - if( p->h>=0 ){ + if( p->hShm>=0 ){ osMunmap(p->apRegion[i], p->szRegion); }else{ sqlite3_free(p->apRegion[i]); } } sqlite3_free(p->apRegion); - if( p->h>=0 ){ - robust_close(pFd, p->h, __LINE__); - p->h = -1; + if( p->hShm>=0 ){ + robust_close(pFd, p->hShm, __LINE__); + p->hShm = -1; } p->pInode->pShmNode = 0; sqlite3_free(p); @@ -36524,7 +36761,7 @@ static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){ lock.l_start = UNIX_SHM_DMS; lock.l_len = 1; lock.l_type = F_WRLCK; - if( osFcntl(pShmNode->h, F_GETLK, &lock)!=0 ) { + if( osFcntl(pShmNode->hShm, F_GETLK, &lock)!=0 ) { rc = SQLITE_IOERR_LOCK; }else if( lock.l_type==F_UNLCK ){ if( pShmNode->isReadonly ){ @@ -36532,7 +36769,12 @@ static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){ rc = SQLITE_READONLY_CANTINIT; }else{ rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1); - if( rc==SQLITE_OK && robust_ftruncate(pShmNode->h, 0) ){ + /* The first connection to attach must truncate the -shm file. We + ** truncate to 3 bytes (an arbitrary small number, less than the + ** -shm header size) rather than 0 as a system debugging aid, to + ** help detect if a -shm file truncation is legitimate or is the work + ** or a rogue process. */ + if( rc==SQLITE_OK && robust_ftruncate(pShmNode->hShm, 3) ){ rc = unixLogError(SQLITE_IOERR_SHMOPEN,"ftruncate",pShmNode->zFilename); } } @@ -36638,12 +36880,12 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ sqlite3_snprintf(nShmFilename, zShm, "%s-shm", zBasePath); sqlite3FileSuffix3(pDbFd->zPath, zShm); #endif - pShmNode->h = -1; + pShmNode->hShm = -1; pDbFd->pInode->pShmNode = pShmNode; pShmNode->pInode = pDbFd->pInode; if( sqlite3GlobalConfig.bCoreMutex ){ - pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); - if( pShmNode->mutex==0 ){ + pShmNode->pShmMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( pShmNode->pShmMutex==0 ){ rc = SQLITE_NOMEM_BKPT; goto shm_open_err; } @@ -36651,11 +36893,11 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ if( pInode->bProcessLock==0 ){ if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ - pShmNode->h = robust_open(zShm, O_RDWR|O_CREAT, (sStat.st_mode&0777)); + pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT,(sStat.st_mode&0777)); } - if( pShmNode->h<0 ){ - pShmNode->h = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777)); - if( pShmNode->h<0 ){ + if( pShmNode->hShm<0 ){ + pShmNode->hShm = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777)); + if( pShmNode->hShm<0 ){ rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShm); goto shm_open_err; } @@ -36666,7 +36908,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ ** is owned by the same user that owns the original database. Otherwise, ** the original owner will not be able to connect. */ - robustFchown(pShmNode->h, sStat.st_uid, sStat.st_gid); + robustFchown(pShmNode->hShm, sStat.st_uid, sStat.st_gid); rc = unixLockSharedMemory(pDbFd, pShmNode); if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err; @@ -36686,13 +36928,13 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ ** the cover of the unixEnterMutex() mutex and the pointer from the ** new (struct unixShm) object to the pShmNode has been set. All that is ** left to do is to link the new object into the linked list starting - ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex - ** mutex. + ** at pShmNode->pFirst. This must be done while holding the + ** pShmNode->pShmMutex. */ - sqlite3_mutex_enter(pShmNode->mutex); + sqlite3_mutex_enter(pShmNode->pShmMutex); p->pNext = pShmNode->pFirst; pShmNode->pFirst = p; - sqlite3_mutex_leave(pShmNode->mutex); + sqlite3_mutex_leave(pShmNode->pShmMutex); return rc; /* Jump here on any error */ @@ -36744,7 +36986,7 @@ static int unixShmMap( p = pDbFd->pShm; pShmNode = p->pShmNode; - sqlite3_mutex_enter(pShmNode->mutex); + sqlite3_mutex_enter(pShmNode->pShmMutex); if( pShmNode->isUnlocked ){ rc = unixLockSharedMemory(pDbFd, pShmNode); if( rc!=SQLITE_OK ) goto shmpage_out; @@ -36752,8 +36994,8 @@ static int unixShmMap( } assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); assert( pShmNode->pInode==pDbFd->pInode ); - assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 ); - assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 ); + assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 ); + assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 ); /* Minimum number of regions required to be mapped. */ nReqRegion = ((iRegion+nShmPerMap) / nShmPerMap) * nShmPerMap; @@ -36765,12 +37007,12 @@ static int unixShmMap( pShmNode->szRegion = szRegion; - if( pShmNode->h>=0 ){ + if( pShmNode->hShm>=0 ){ /* The requested region is not mapped into this processes address space. ** Check to see if it has been allocated (i.e. if the wal-index file is ** large enough to contain the requested region). */ - if( osFstat(pShmNode->h, &sStat) ){ + if( osFstat(pShmNode->hShm, &sStat) ){ rc = SQLITE_IOERR_SHMSIZE; goto shmpage_out; } @@ -36798,7 +37040,7 @@ static int unixShmMap( assert( (nByte % pgsz)==0 ); for(iPg=(sStat.st_size/pgsz); iPg<(nByte/pgsz); iPg++){ int x = 0; - if( seekAndWriteFd(pShmNode->h, iPg*pgsz + pgsz-1, "", 1, &x)!=1 ){ + if( seekAndWriteFd(pShmNode->hShm, iPg*pgsz + pgsz-1,"",1,&x)!=1 ){ const char *zFile = pShmNode->zFilename; rc = unixLogError(SQLITE_IOERR_SHMSIZE, "write", zFile); goto shmpage_out; @@ -36821,22 +37063,22 @@ static int unixShmMap( int nMap = szRegion*nShmPerMap; int i; void *pMem; - if( pShmNode->h>=0 ){ + if( pShmNode->hShm>=0 ){ pMem = osMmap(0, nMap, pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, - MAP_SHARED, pShmNode->h, szRegion*(i64)pShmNode->nRegion + MAP_SHARED, pShmNode->hShm, szRegion*(i64)pShmNode->nRegion ); if( pMem==MAP_FAILED ){ rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename); goto shmpage_out; } }else{ - pMem = sqlite3_malloc64(szRegion); + pMem = sqlite3_malloc64(nMap); if( pMem==0 ){ rc = SQLITE_NOMEM_BKPT; goto shmpage_out; } - memset(pMem, 0, szRegion); + memset(pMem, 0, nMap); } for(i=0; iisReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY; - sqlite3_mutex_leave(pShmNode->mutex); + sqlite3_mutex_leave(pShmNode->pShmMutex); return rc; } @@ -36887,12 +37129,12 @@ static int unixShmLock( || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED) || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); - assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 ); - assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 ); + assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 ); + assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 ); mask = (1<<(ofst+n)) - (1<1 || mask==(1<mutex); + sqlite3_mutex_enter(pShmNode->pShmMutex); if( flags & SQLITE_SHM_UNLOCK ){ u16 allMask = 0; /* Mask of locks held by siblings */ @@ -36965,7 +37207,7 @@ static int unixShmLock( } } } - sqlite3_mutex_leave(pShmNode->mutex); + sqlite3_mutex_leave(pShmNode->pShmMutex); OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n", p->id, osGetpid(0), p->sharedMask, p->exclMask)); return rc; @@ -37015,14 +37257,14 @@ static int unixShmUnmap( /* Remove connection p from the set of connections associated ** with pShmNode */ - sqlite3_mutex_enter(pShmNode->mutex); + sqlite3_mutex_enter(pShmNode->pShmMutex); for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){} *pp = p->pNext; /* Free the connection p */ sqlite3_free(p); pDbFd->pShm = 0; - sqlite3_mutex_leave(pShmNode->mutex); + sqlite3_mutex_leave(pShmNode->pShmMutex); /* If pShmNode->nRef has reached 0, then close the underlying ** shared-memory file, too */ @@ -37031,7 +37273,7 @@ static int unixShmUnmap( assert( pShmNode->nRef>0 ); pShmNode->nRef--; if( pShmNode->nRef==0 ){ - if( deleteFlag && pShmNode->h>=0 ){ + if( deleteFlag && pShmNode->hShm>=0 ){ osUnlink(pShmNode->zFilename); } unixShmPurge(pDbFd); @@ -40449,8 +40691,7 @@ struct winFile { int nFetchOut; /* Number of outstanding xFetch references */ HANDLE hMap; /* Handle for accessing memory mapping */ void *pMapRegion; /* Area memory mapped */ - sqlite3_int64 mmapSize; /* Usable size of mapped region */ - sqlite3_int64 mmapSizeActual; /* Actual size of mapped region */ + sqlite3_int64 mmapSize; /* Size of mapped region */ sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */ #endif }; @@ -43071,6 +43312,26 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ DWORD lastErrno; #if SQLITE_MAX_MMAP_SIZE>0 sqlite3_int64 oldMmapSize; + if( pFile->nFetchOut>0 ){ + /* File truncation is a no-op if there are outstanding memory mapped + ** pages. This is because truncating the file means temporarily unmapping + ** the file, and that might delete memory out from under existing cursors. + ** + ** This can result in incremental vacuum not truncating the file, + ** if there is an active read cursor when the incremental vacuum occurs. + ** No real harm comes of this - the database file is not corrupted, + ** though some folks might complain that the file is bigger than it + ** needs to be. + ** + ** The only feasible work-around is to defer the truncation until after + ** all references to memory-mapped content are closed. That is doable, + ** but involves adding a few branches in the common write code path which + ** could slow down normal operations slightly. Hence, we have decided for + ** now to simply make trancations a no-op if there are pending reads. We + ** can maybe revisit this decision in the future. + */ + return SQLITE_OK; + } #endif assert( pFile ); @@ -44499,9 +44760,9 @@ shmpage_out: static int winUnmapfile(winFile *pFile){ assert( pFile!=0 ); OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, pMapRegion=%p, " - "mmapSize=%lld, mmapSizeActual=%lld, mmapSizeMax=%lld\n", + "mmapSize=%lld, mmapSizeMax=%lld\n", osGetCurrentProcessId(), pFile, pFile->hMap, pFile->pMapRegion, - pFile->mmapSize, pFile->mmapSizeActual, pFile->mmapSizeMax)); + pFile->mmapSize, pFile->mmapSizeMax)); if( pFile->pMapRegion ){ if( !osUnmapViewOfFile(pFile->pMapRegion) ){ pFile->lastErrno = osGetLastError(); @@ -44513,7 +44774,6 @@ static int winUnmapfile(winFile *pFile){ } pFile->pMapRegion = 0; pFile->mmapSize = 0; - pFile->mmapSizeActual = 0; } if( pFile->hMap!=NULL ){ if( !osCloseHandle(pFile->hMap) ){ @@ -44624,7 +44884,6 @@ static int winMapfile(winFile *pFd, sqlite3_int64 nByte){ } pFd->pMapRegion = pNew; pFd->mmapSize = nMap; - pFd->mmapSizeActual = nMap; } OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n", @@ -45426,7 +45685,6 @@ static int winOpen( pFile->hMap = NULL; pFile->pMapRegion = 0; pFile->mmapSize = 0; - pFile->mmapSizeActual = 0; pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap; #endif @@ -47323,7 +47581,7 @@ bitvec_end: ** The PCache.pSynced variable is used to optimize searching for a dirty ** page to eject from the cache mid-transaction. It is better to eject ** a page that does not require a journal sync than one that does. -** Therefore, pSynced is maintained to that it *almost* always points +** Therefore, pSynced is maintained so that it *almost* always points ** to either the oldest page in the pDirty/pDirtyTail list that has a ** clear PGHDR_NEED_SYNC flag or to a page that is older than this one ** (so that the right page to eject can be found by following pDirtyPrev @@ -48147,6 +48405,15 @@ SQLITE_PRIVATE int sqlite3PCachePercentDirty(PCache *pCache){ return nCache ? (int)(((i64)nDirty * 100) / nCache) : 0; } +#ifdef SQLITE_DIRECT_OVERFLOW_READ +/* +** Return true if there are one or more dirty pages in the cache. Else false. +*/ +SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache){ + return (pCache->pDirty!=0); +} +#endif + #if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG) /* ** For all dirty pages currently in the cache, invoke the specified @@ -48270,7 +48537,8 @@ struct PgHdr1 { }; /* -** A page is pinned if it is no on the LRU list +** A page is pinned if it is not on the LRU list. To be "pinned" means +** that the page is in active use and must not be deallocated. */ #define PAGE_IS_PINNED(p) ((p)->pLruNext==0) #define PAGE_IS_UNPINNED(p) ((p)->pLruNext!=0) @@ -50910,19 +51178,30 @@ static const unsigned char aJournalMagic[] = { */ #define isOpen(pFd) ((pFd)->pMethods!=0) +#ifdef SQLITE_DIRECT_OVERFLOW_READ /* -** Return true if this pager uses a write-ahead log to read page pgno. -** Return false if the pager reads pgno directly from the database. +** Return true if page pgno can be read directly from the database file +** by the b-tree layer. This is the case if: +** +** * the database file is open, +** * there are no dirty pages in the cache, and +** * the desired page is not currently in the wal file. */ -#if !defined(SQLITE_OMIT_WAL) && defined(SQLITE_DIRECT_OVERFLOW_READ) -SQLITE_PRIVATE int sqlite3PagerUseWal(Pager *pPager, Pgno pgno){ - u32 iRead = 0; - int rc; - if( pPager->pWal==0 ) return 0; - rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead); - return rc || iRead; +SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){ + if( pPager->fd->pMethods==0 ) return 0; + if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; +#ifndef SQLITE_OMIT_WAL + if( pPager->pWal ){ + u32 iRead = 0; + int rc; + rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead); + return (rc==SQLITE_OK && iRead==0); + } +#endif + return 1; } #endif + #ifndef SQLITE_OMIT_WAL # define pagerUseWal(x) ((x)->pWal!=0) #else @@ -57106,7 +57385,11 @@ SQLITE_PRIVATE void sqlite3PagerSetCodec( void (*xCodecFree)(void*), void *pCodec ){ - if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec); + if( pPager->xCodecFree ){ + pPager->xCodecFree(pPager->pCodec); + }else{ + pager_reset(pPager); + } pPager->xCodec = pPager->memDb ? 0 : xCodec; pPager->xCodecSizeChng = xCodecSizeChng; pPager->xCodecFree = xCodecFree; @@ -65766,7 +66049,7 @@ static int lockBtree(BtShared *pBt){ pageSize-usableSize); return rc; } - if( (pBt->db->flags & SQLITE_WriteSchema)==0 && nPage>nPageFile ){ + if( sqlite3WritableSchema(pBt->db)==0 && nPage>nPageFile ){ rc = SQLITE_CORRUPT_BKPT; goto page1_init_failed; } @@ -66240,6 +66523,7 @@ static int relocatePage( eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ); assert( sqlite3_mutex_held(pBt->mutex) ); assert( pDbPage->pBt==pBt ); + if( iDbPage<3 ) return SQLITE_CORRUPT_BKPT; /* Move page iDbPage from its current location to page number iFreePage */ TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n", @@ -67411,9 +67695,6 @@ static int accessPayload( /* Need to read this page properly. It contains some of the ** range of data that is being read (eOp==0) or written (eOp!=0). */ -#ifdef SQLITE_DIRECT_OVERFLOW_READ - sqlite3_file *fd; /* File from which to do direct overflow read */ -#endif int a = amt; if( a + offset > ovflSize ){ a = ovflSize - offset; @@ -67424,7 +67705,7 @@ static int accessPayload( ** ** 1) this is a read operation, and ** 2) data is required from the start of this overflow page, and - ** 3) there is no open write-transaction, and + ** 3) there are no dirty pages in the page-cache ** 4) the database is file-backed, and ** 5) the page is not in the WAL file ** 6) at least 4 bytes have already been read into the output buffer @@ -67435,11 +67716,10 @@ static int accessPayload( */ if( eOp==0 /* (1) */ && offset==0 /* (2) */ - && pBt->inTransaction==TRANS_READ /* (3) */ - && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (4) */ - && 0==sqlite3PagerUseWal(pBt->pPager, nextPage) /* (5) */ + && sqlite3PagerDirectReadOk(pBt->pPager, nextPage) /* (3,4,5) */ && &pBuf[-4]>=pBufStart /* (6) */ ){ + sqlite3_file *fd = sqlite3PagerFile(pBt->pPager); u8 aSave[4]; u8 *aWrite = &pBuf[-4]; assert( aWrite>=pBufStart ); /* due to (6) */ @@ -74035,7 +74315,8 @@ SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){ assert( fg & MEM_Real ); sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r); } - pMem->n = sqlite3Strlen30(pMem->z); + assert( pMem->z!=0 ); + pMem->n = sqlite3Strlen30NN(pMem->z); pMem->enc = SQLITE_UTF8; pMem->flags |= MEM_Str|MEM_Term; if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real); @@ -75610,6 +75891,13 @@ SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, u8 prepFlag } assert( p->zSql==0 ); p->zSql = sqlite3DbStrNDup(p->db, z, n); +#ifdef SQLITE_ENABLE_NORMALIZE + assert( p->zNormSql==0 ); + if( p->zSql && (prepFlags & SQLITE_PREPARE_NORMALIZE)!=0 ){ + sqlite3Normalize(p, p->zSql, n, prepFlags); + assert( p->zNormSql!=0 || p->db->mallocFailed ); + } +#endif } /* @@ -75631,6 +75919,11 @@ SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){ zTmp = pA->zSql; pA->zSql = pB->zSql; pB->zSql = zTmp; +#ifdef SQLITE_ENABLE_NORMALIZE + zTmp = pA->zNormSql; + pA->zNormSql = pB->zNormSql; + pB->zNormSql = zTmp; +#endif pB->expmask = pA->expmask; pB->prepFlags = pA->prepFlags; memcpy(pB->aCounter, pA->aCounter, sizeof(pB->aCounter)); @@ -78702,6 +78995,9 @@ SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ vdbeFreeOpArray(db, p->aOp, p->nOp); sqlite3DbFree(db, p->aColName); sqlite3DbFree(db, p->zSql); +#ifdef SQLITE_ENABLE_NORMALIZE + sqlite3DbFree(db, p->zNormSql); +#endif #ifdef SQLITE_ENABLE_STMT_SCANSTATUS { int i; @@ -80103,7 +80399,9 @@ SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){ (void)getVarint32((u8*)m.z, szHdr); testcase( szHdr==3 ); testcase( szHdr==m.n ); - if( unlikely(szHdr<3 || (int)szHdr>m.n) ){ + testcase( szHdr>0x7fffffff ); + assert( m.n>=0 ); + if( unlikely(szHdr<3 || szHdr>(unsigned)m.n) ){ goto idx_rowid_corruption; } @@ -82114,6 +82412,16 @@ SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt){ #endif } +#ifdef SQLITE_ENABLE_NORMALIZE +/* +** Return the normalized SQL associated with a prepared statement. +*/ +SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt){ + Vdbe *p = (Vdbe *)pStmt; + return p ? p->zNormSql : 0; +} +#endif /* SQLITE_ENABLE_NORMALIZE */ + #ifdef SQLITE_ENABLE_PREUPDATE_HOOK /* ** Allocate and populate an UnpackedRecord structure based on the serialized @@ -85553,17 +85861,25 @@ case OP_MakeRecord: { if( nVarintdb->aLimit[SQLITE_LIMIT_LENGTH] ){ - goto too_big; - } /* Make sure the output register has a buffer large enough to store ** the new record. The output register (pOp->p3) is not allowed to ** be one of the input registers (because the following call to ** sqlite3VdbeMemClearAndResize() could clobber the value before it is used). */ - if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){ - goto no_mem; + if( nByte+nZero<=pOut->szMalloc ){ + /* The output register is already large enough to hold the record. + ** No error checks or buffer enlargement is required */ + pOut->z = pOut->zMalloc; + }else{ + /* Need to make sure that the output is not too big and then enlarge + ** the output register to hold the full result */ + if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + goto too_big; + } + if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){ + goto no_mem; + } } zNewRecord = (u8 *)pOut->z; @@ -88419,7 +88735,7 @@ case OP_ParseSchema: { { zMaster = MASTER_NAME; initData.db = db; - initData.iDb = pOp->p1; + initData.iDb = iDb; initData.pzErrMsg = &p->zErrMsg; initData.mInitFlags = 0; zSql = sqlite3MPrintf(db, @@ -89616,10 +89932,11 @@ case OP_VFilter: { /* jump */ ** ** If the VColumn opcode is being used to fetch the value of ** an unchanging column during an UPDATE operation, then the P5 -** value is 1. Otherwise, P5 is 0. The P5 value is returned -** by sqlite3_vtab_nochange() routine and can be used -** by virtual table implementations to return special "no-change" -** marks which can be more efficient, depending on the virtual table. +** value is OPFLAG_NOCHNG. This will cause the sqlite3_vtab_nochange() +** function to return true inside the xColumn method of the virtual +** table implementation. The P5 column might also contain other +** bits (OPFLAG_LENGTHARG or OPFLAG_TYPEOFARG) but those bits are +** unused by OP_VColumn. */ case OP_VColumn: { sqlite3_vtab *pVtab; @@ -89641,7 +89958,8 @@ case OP_VColumn: { assert( pModule->xColumn ); memset(&sContext, 0, sizeof(sContext)); sContext.pOut = pDest; - if( pOp->p5 ){ + testcase( (pOp->p5 & OPFLAG_NOCHNG)==0 && pOp->p5!=0 ); + if( pOp->p5 & OPFLAG_NOCHNG ){ sqlite3VdbeMemSetNull(pDest); pDest->flags = MEM_Null|MEM_Zero; pDest->u.nZero = 0; @@ -94000,8 +94318,8 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){ if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort; } #ifndef SQLITE_OMIT_WINDOWFUNC - if( !ExprHasProperty(pExpr, EP_Reduced) && pExpr->pWin ){ - Window *pWin = pExpr->pWin; + if( ExprHasProperty(pExpr, EP_WinFunc) ){ + Window *pWin = pExpr->y.pWin; if( sqlite3WalkExprList(pWalker, pWin->pPartition) ) return WRC_Abort; if( sqlite3WalkExprList(pWalker, pWin->pOrderBy) ) return WRC_Abort; if( sqlite3WalkExpr(pWalker, pWin->pFilter) ) return WRC_Abort; @@ -94274,7 +94592,7 @@ SQLITE_PRIVATE int sqlite3MatchSpanName( ** (even if X is implied). ** pExpr->iTable Set to the cursor number for the table obtained ** from pSrcList. -** pExpr->pTab Points to the Table structure of X.Y (even if +** pExpr->y.pTab Points to the Table structure of X.Y (even if ** X and/or Y are implied.) ** pExpr->iColumn Set to the column number within the table. ** pExpr->op Set to TK_COLUMN. @@ -94318,7 +94636,6 @@ static int lookupName( /* Initialize the node to no-match */ pExpr->iTable = -1; - pExpr->pTab = 0; ExprSetVVAProperty(pExpr, EP_NoReduce); /* Translate the schema name in zDb into a pointer to the corresponding @@ -94380,7 +94697,7 @@ static int lookupName( continue; } if( IN_RENAME_OBJECT && pItem->zAlias ){ - sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->pTab); + sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab); } } if( 0==(cntTab++) ){ @@ -94406,13 +94723,13 @@ static int lookupName( } if( pMatch ){ pExpr->iTable = pMatch->iCursor; - pExpr->pTab = pMatch->pTab; + pExpr->y.pTab = pMatch->pTab; /* RIGHT JOIN not (yet) supported */ assert( (pMatch->fg.jointype & JT_RIGHT)==0 ); if( (pMatch->fg.jointype & JT_LEFT)!=0 ){ ExprSetProperty(pExpr, EP_CanBeNull); } - pSchema = pExpr->pTab->pSchema; + pSchema = pExpr->y.pTab->pSchema; } } /* if( pSrcList ) */ @@ -94469,7 +94786,7 @@ static int lookupName( testcase( iCol==(-1) ); if( IN_RENAME_OBJECT ){ pExpr->iColumn = iCol; - pExpr->pTab = pTab; + pExpr->y.pTab = pTab; eNewExprOp = TK_COLUMN; }else{ pExpr->iTable = pNC->uNC.pUpsert->regData + iCol; @@ -94491,7 +94808,7 @@ static int lookupName( testcase( iCol==32 ); pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<pTab = pTab; + pExpr->y.pTab = pTab; pExpr->iColumn = (i16)iCol; eNewExprOp = TK_TRIGGER; #endif /* SQLITE_OMIT_TRIGGER */ @@ -94591,7 +94908,7 @@ static int lookupName( assert( pExpr->op==TK_ID ); if( ExprHasProperty(pExpr,EP_DblQuoted) ){ pExpr->op = TK_STRING; - pExpr->pTab = 0; + pExpr->y.pTab = 0; return WRC_Prune; } if( sqlite3ExprIdToTrueFalse(pExpr) ){ @@ -94669,9 +94986,9 @@ SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSr Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0); if( p ){ struct SrcList_item *pItem = &pSrc->a[iSrc]; - p->pTab = pItem->pTab; + p->y.pTab = pItem->pTab; p->iTable = pItem->iCursor; - if( p->pTab->iPKey==iCol ){ + if( p->y.pTab->iPKey==iCol ){ p->iColumn = -1; }else{ p->iColumn = (ynVar)iCol; @@ -94761,7 +95078,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ pItem = pSrcList->a; assert( HasRowid(pItem->pTab) && pItem->pTab->pSelect==0 ); pExpr->op = TK_COLUMN; - pExpr->pTab = pItem->pTab; + pExpr->y.pTab = pItem->pTab; pExpr->iTable = pItem->iCursor; pExpr->iColumn = -1; pExpr->affinity = SQLITE_AFF_INTEGER; @@ -94805,9 +95122,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ zColumn = pRight->u.zToken; if( IN_RENAME_OBJECT ){ sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight); - } - if( IN_RENAME_OBJECT ){ - sqlite3RenameTokenRemap(pParse, (void*)&pExpr->pTab, (void*)pLeft); + sqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft); } } return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr); @@ -94889,6 +95204,15 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ notValid(pParse, pNC, "non-deterministic functions", NC_IdxExpr|NC_PartIdx); } + if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0 + && pParse->nested==0 + && sqlite3Config.bInternalFunctions==0 + ){ + /* Internal-use-only functions are disallowed unless the + ** SQL is being compiled using sqlite3NestedParse() */ + no_such_func = 1; + pDef = 0; + } } if( 0==IN_RENAME_OBJECT ){ @@ -94897,18 +95221,18 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ || (pDef->xValue==0 && pDef->xInverse==0) || (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize) ); - if( pDef && pDef->xValue==0 && pExpr->pWin ){ + if( pDef && pDef->xValue==0 && ExprHasProperty(pExpr, EP_WinFunc) ){ sqlite3ErrorMsg(pParse, "%.*s() may not be used as a window function", nId, zId ); pNC->nErr++; }else if( (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) - || (is_agg && (pDef->funcFlags & SQLITE_FUNC_WINDOW) && !pExpr->pWin) - || (is_agg && pExpr->pWin && (pNC->ncFlags & NC_AllowWin)==0) + || (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pExpr->y.pWin) + || (is_agg && pExpr->y.pWin && (pNC->ncFlags & NC_AllowWin)==0) ){ const char *zType; - if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->pWin ){ + if( (pDef->funcFlags & SQLITE_FUNC_WINDOW) || pExpr->y.pWin ){ zType = "window"; }else{ zType = "aggregate"; @@ -94938,7 +95262,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ } if( is_agg ){ #ifndef SQLITE_OMIT_WINDOWFUNC - pNC->ncFlags &= ~(pExpr->pWin ? NC_AllowWin : NC_AllowAgg); + pNC->ncFlags &= ~(pExpr->y.pWin ? NC_AllowWin : NC_AllowAgg); #else pNC->ncFlags &= ~NC_AllowAgg; #endif @@ -94947,17 +95271,17 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ sqlite3WalkExprList(pWalker, pList); if( is_agg ){ #ifndef SQLITE_OMIT_WINDOWFUNC - if( pExpr->pWin ){ + if( pExpr->y.pWin ){ Select *pSel = pNC->pWinSelect; - sqlite3WalkExprList(pWalker, pExpr->pWin->pPartition); - sqlite3WalkExprList(pWalker, pExpr->pWin->pOrderBy); - sqlite3WalkExpr(pWalker, pExpr->pWin->pFilter); - sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->pWin, pDef); + sqlite3WalkExprList(pWalker, pExpr->y.pWin->pPartition); + sqlite3WalkExprList(pWalker, pExpr->y.pWin->pOrderBy); + sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter); + sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef); if( 0==pSel->pWin - || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->pWin) + || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->y.pWin) ){ - pExpr->pWin->pNextWin = pSel->pWin; - pSel->pWin = pExpr->pWin; + pExpr->y.pWin->pNextWin = pSel->pWin; + pSel->pWin = pExpr->y.pWin; } pNC->ncFlags |= NC_AllowWin; }else @@ -95380,13 +95704,13 @@ static int resolveOrderGroupBy( for(j=0; jpEList->nExpr; j++){ if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){ #ifndef SQLITE_OMIT_WINDOWFUNC - if( pE->pWin ){ + if( ExprHasProperty(pE, EP_WinFunc) ){ /* Since this window function is being changed into a reference ** to the same window function the result set, remove the instance ** of this window function from the Select.pWin list. */ Window **pp; for(pp=&pSelect->pWin; *pp; pp=&(*pp)->pNextWin){ - if( *pp==pE->pWin ){ + if( *pp==pE->y.pWin ){ *pp = (*pp)->pNextWin; } } @@ -95849,8 +96173,8 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){ return sqlite3AffinityType(pExpr->u.zToken, 0); } #endif - if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->pTab ){ - return sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn); + if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->y.pTab ){ + return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); } if( op==TK_SELECT_COLUMN ){ assert( pExpr->pLeft->flags&EP_xIsSelect ); @@ -95934,13 +96258,13 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ if( p->flags & EP_Generic ) break; if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER || op==TK_TRIGGER) - && p->pTab!=0 + && p->y.pTab!=0 ){ - /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally + /* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally ** a TK_COLUMN but was previously evaluated and cached in a register */ int j = p->iColumn; if( j>=0 ){ - const char *zColl = p->pTab->aCol[j].zColl; + const char *zColl = p->y.pTab->aCol[j].zColl; pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0); } break; @@ -96843,6 +97167,10 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ assert( p!=0 ); /* Sanity check: Assert that the IntValue is non-negative if it exists */ assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 ); + + assert( !ExprHasProperty(p, EP_WinFunc) || p->y.pWin!=0 || db->mallocFailed ); + assert( p->op!=TK_FUNCTION || ExprHasProperty(p, EP_TokenOnly|EP_Reduced) + || p->y.pWin==0 || ExprHasProperty(p, EP_WinFunc) ); #ifdef SQLITE_DEBUG if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){ assert( p->pLeft==0 ); @@ -96861,8 +97189,9 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ }else{ sqlite3ExprListDelete(db, p->x.pList); } - if( !ExprHasProperty(p, EP_Reduced) ){ - sqlite3WindowDelete(db, p->pWin); + if( ExprHasProperty(p, EP_WinFunc) ){ + assert( p->op==TK_FUNCTION ); + sqlite3WindowDelete(db, p->y.pWin); } } if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken); @@ -96926,7 +97255,7 @@ static int dupedExprStructSize(Expr *p, int flags){ assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 ); if( 0==flags || p->op==TK_SELECT_COLUMN #ifndef SQLITE_OMIT_WINDOWFUNC - || p->pWin + || ExprHasProperty(p, EP_WinFunc) #endif ){ nSize = EXPR_FULLSIZE; @@ -96953,7 +97282,7 @@ static int dupedExprStructSize(Expr *p, int flags){ static int dupedExprNodeSize(Expr *p, int flags){ int nByte = dupedExprStructSize(p, flags) & 0xfff; if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ - nByte += sqlite3Strlen30(p->u.zToken)+1; + nByte += sqlite3Strlen30NN(p->u.zToken)+1; } return ROUND8(nByte); } @@ -97056,22 +97385,24 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ } /* Fill in pNew->pLeft and pNew->pRight. */ - zAlloc += dupedExprNodeSize(p, dupFlags); - if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){ + if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly|EP_WinFunc) ){ + zAlloc += dupedExprNodeSize(p, dupFlags); if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){ pNew->pLeft = p->pLeft ? exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0; pNew->pRight = p->pRight ? exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0; } - }else{ #ifndef SQLITE_OMIT_WINDOWFUNC - if( ExprHasProperty(p, EP_Reduced|EP_TokenOnly) ){ - pNew->pWin = 0; - }else{ - pNew->pWin = sqlite3WindowDup(db, pNew, p->pWin); + if( ExprHasProperty(p, EP_WinFunc) ){ + pNew->y.pWin = sqlite3WindowDup(db, pNew, p->y.pWin); + assert( ExprHasProperty(pNew, EP_WinFunc) ); } #endif /* SQLITE_OMIT_WINDOWFUNC */ + if( pzBuffer ){ + *pzBuffer = zAlloc; + } + }else{ if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){ if( pNew->op==TK_SELECT_COLUMN ){ pNew->pLeft = p->pLeft; @@ -97083,9 +97414,6 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ pNew->pRight = sqlite3ExprDup(db, p->pRight, 0); } } - if( pzBuffer ){ - *pzBuffer = zAlloc; - } } return pNew; } @@ -97880,8 +98208,8 @@ SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){ return 0; case TK_COLUMN: return ExprHasProperty(p, EP_CanBeNull) || - p->pTab==0 || /* Reference to column of index on expression */ - (p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0); + p->y.pTab==0 || /* Reference to column of index on expression */ + (p->iColumn>=0 && p->y.pTab->aCol[p->iColumn].notNull==0); default: return 1; } @@ -97936,6 +98264,14 @@ SQLITE_PRIVATE int sqlite3IsRowid(const char *z){ if( sqlite3StrICmp(z, "OID")==0 ) return 1; return 0; } +#ifdef SQLITE_ENABLE_NORMALIZE +SQLITE_PRIVATE int sqlite3IsRowidN(const char *z, int n){ + if( sqlite3StrNICmp(z, "_ROWID_", n)==0 ) return 1; + if( sqlite3StrNICmp(z, "ROWID", n)==0 ) return 1; + if( sqlite3StrNICmp(z, "OID", n)==0 ) return 1; + return 0; +} +#endif /* ** pX is the RHS of an IN operator. If pX is a SELECT statement @@ -99169,7 +99505,7 @@ expr_code_doover: ** constant. */ int iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target); - int aff = sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn); + int aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); if( aff!=SQLITE_AFF_BLOB ){ static const char zAff[] = "B\000C\000D\000E"; assert( SQLITE_AFF_BLOB=='A' ); @@ -99193,7 +99529,7 @@ expr_code_doover: iTab = pParse->iSelfTab - 1; } } - return sqlite3ExprCodeGetColumn(pParse, pExpr->pTab, + return sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab, pExpr->iColumn, iTab, target, pExpr->op2); } @@ -99407,8 +99743,8 @@ expr_code_doover: CollSeq *pColl = 0; /* A collating sequence */ #ifndef SQLITE_OMIT_WINDOWFUNC - if( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) && pExpr->pWin ){ - return pExpr->pWin->regResult; + if( ExprHasProperty(pExpr, EP_WinFunc) ){ + return pExpr->y.pWin->regResult; } #endif @@ -99651,7 +99987,7 @@ expr_code_doover: ** p1==1 -> old.a p1==4 -> new.a ** p1==2 -> old.b p1==5 -> new.b */ - Table *pTab = pExpr->pTab; + Table *pTab = pExpr->y.pTab; int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn; assert( pExpr->iTable==0 || pExpr->iTable==1 ); @@ -99662,7 +99998,7 @@ expr_code_doover: sqlite3VdbeAddOp2(v, OP_Param, p1, target); VdbeComment((v, "r[%d]=%s.%s", target, (pExpr->iTable ? "new" : "old"), - (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName) + (pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[pExpr->iColumn].zName) )); #ifndef SQLITE_OMIT_FLOATING_POINT @@ -100513,6 +100849,20 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTa if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){ if( pA->op==TK_FUNCTION ){ if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2; +#ifndef SQLITE_OMIT_WINDOWFUNC + /* Justification for the assert(): + ** window functions have p->op==TK_FUNCTION but aggregate functions + ** have p->op==TK_AGG_FUNCTION. So any comparison between an aggregate + ** function and a window function should have failed before reaching + ** this point. And, it is not possible to have a window function and + ** a scalar function with the same name and number of arguments. So + ** if we reach this point, either A and B both window functions or + ** neither are a window functions. */ + assert( ExprHasProperty(pA,EP_WinFunc)==ExprHasProperty(pB,EP_WinFunc) ); + if( ExprHasProperty(pA,EP_WinFunc) ){ + if( sqlite3WindowCompare(pParse,pA->y.pWin,pB->y.pWin)!=0 ) return 2; + } +#endif }else if( pA->op==TK_COLLATE ){ if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2; }else if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){ @@ -100532,21 +100882,6 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTa if( pA->iTable!=pB->iTable && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2; } -#ifndef SQLITE_OMIT_WINDOWFUNC - /* Justification for the assert(): - ** window functions have p->op==TK_FUNCTION but aggregate functions - ** have p->op==TK_AGG_FUNCTION. So any comparison between an aggregate - ** function and a window function should have failed before reaching - ** this point. And, it is not possible to have a window function and - ** a scalar function with the same name and number of arguments. So - ** if we reach this point, either A and B both window functions or - ** neither are a window functions. */ - assert( (pA->pWin==0)==(pB->pWin==0) ); - - if( pA->pWin!=0 ){ - if( sqlite3WindowCompare(pParse,pA->pWin,pB->pWin)!=0 ) return 2; - } -#endif } return 0; } @@ -100687,8 +101022,8 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ testcase( pExpr->op==TK_LE ); testcase( pExpr->op==TK_GT ); testcase( pExpr->op==TK_GE ); - if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->pTab)) - || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->pTab)) + if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->y.pTab)) + || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->y.pTab)) ){ return WRC_Prune; } @@ -100919,7 +101254,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0 ){ pCol = &pAggInfo->aCol[k]; - pCol->pTab = pExpr->pTab; + pCol->pTab = pExpr->y.pTab; pCol->iTable = pExpr->iTable; pCol->iColumn = pExpr->iColumn; pCol->iMem = ++pParse->nMem; @@ -101802,10 +102137,16 @@ static void renameTokenCheckAll(Parse *pParse, void *pPtr){ #endif /* -** Add a new RenameToken object mapping parse tree element pPtr into -** token *pToken to the Parse object currently under construction. +** Remember that the parser tree element pPtr was created using +** the token pToken. ** -** Return a copy of pPtr. +** In other words, construct a new RenameToken object and add it +** to the list of RenameToken objects currently being built up +** in pParse->pRename. +** +** The pPtr argument is returned so that this routine can be used +** with tail recursion in tokenExpr() routine, for a small performance +** improvement. */ SQLITE_PRIVATE void *sqlite3RenameTokenMap(Parse *pParse, void *pPtr, Token *pToken){ RenameToken *pNew; @@ -101938,7 +102279,7 @@ static int renameColumnExprCb(Walker *pWalker, Expr *pExpr){ renameTokenFind(pWalker->pParse, p, (void*)pExpr); }else if( pExpr->op==TK_COLUMN && pExpr->iColumn==p->iCol - && p->pTab==pExpr->pTab + && p->pTab==pExpr->y.pTab ){ renameTokenFind(pWalker->pParse, p, (void*)pExpr); } @@ -102196,9 +102537,14 @@ static int renameResolveTrigger(Parse *pParse, const char *zDb){ db->aDb[sqlite3SchemaToIndex(db, pNew->pTabSchema)].zDbSName ); pParse->eTriggerOp = pNew->op; + /* ALWAYS() because if the table of the trigger does not exist, the + ** error would have been hit before this point */ + if( ALWAYS(pParse->pTriggerTab) ){ + rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab); + } /* Resolve symbols in WHEN clause */ - if( pNew->pWhen ){ + if( rc==SQLITE_OK && pNew->pWhen ){ rc = sqlite3ResolveExprNames(&sNC, pNew->pWhen); } @@ -102312,15 +102658,8 @@ static void renameParseCleanup(Parse *pParse){ ** into zNew. The name should be quoted if bQuote is true. ** ** This function is used internally by the ALTER TABLE RENAME COLUMN command. -** Though accessible to application code, it is not intended for use by -** applications. The existance of this function, and the way it works, -** is subject to change without notice. -** -** If any of the parameters are out-of-bounds, then simply return NULL. -** An out-of-bounds parameter can only occur when the application calls -** this function directly. The parameters will always be well-formed when -** this routine is invoked by the bytecode for a legitimate ALTER TABLE -** statement. +** It is only accessible to SQL created using sqlite3NestedParse(). It is +** not reachable from ordinary SQL passed into sqlite3_prepare(). */ static void renameColumnFunc( sqlite3_context *context, @@ -102476,8 +102815,8 @@ renameColumnFunc_done: */ static int renameTableExprCb(Walker *pWalker, Expr *pExpr){ RenameCtx *p = pWalker->u.pRename; - if( pExpr->op==TK_COLUMN && p->pTab==pExpr->pTab ){ - renameTokenFind(pWalker->pParse, p, (void*)&pExpr->pTab); + if( pExpr->op==TK_COLUMN && p->pTab==pExpr->y.pTab ){ + renameTokenFind(pWalker->pParse, p, (void*)&pExpr->y.pTab); } return WRC_Continue; } @@ -102574,7 +102913,7 @@ static void renameTableFunc( }else{ /* Modify any FK definitions to point to the new table. */ #ifndef SQLITE_OMIT_FOREIGN_KEY - if( db->flags & SQLITE_ForeignKeys ){ + if( isLegacy==0 || (db->flags & SQLITE_ForeignKeys) ){ FKey *pFKey; for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){ if( sqlite3_stricmp(pFKey->zTo, zOld)==0 ){ @@ -102728,9 +103067,9 @@ static void renameTableTest( */ SQLITE_PRIVATE void sqlite3AlterFunctions(void){ static FuncDef aAlterTableFuncs[] = { - FUNCTION(sqlite_rename_column, 9, 0, 0, renameColumnFunc), - FUNCTION(sqlite_rename_table, 7, 0, 0, renameTableFunc), - FUNCTION(sqlite_rename_test, 5, 0, 0, renameTableTest), + INTERNAL_FUNCTION(sqlite_rename_column, 9, renameColumnFunc), + INTERNAL_FUNCTION(sqlite_rename_table, 7, renameTableFunc), + INTERNAL_FUNCTION(sqlite_rename_test, 5, renameTableTest), }; sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs)); } @@ -104779,7 +105118,7 @@ static void attachFunc( if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt); pNew->pBt = 0; pNew->pSchema = 0; - rc = sqlite3BtreeOpen(pVfs, "x", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB); + rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB); }else{ /* This is a real ATTACH ** @@ -105459,6 +105798,7 @@ SQLITE_PRIVATE void sqlite3AuthRead( int iCol; /* Index of column in table */ assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER ); + assert( !IN_RENAME_OBJECT || db->xAuth==0 ); if( db->xAuth==0 ) return; iDb = sqlite3SchemaToIndex(pParse->db, pSchema); if( iDb<0 ){ @@ -105515,6 +105855,7 @@ SQLITE_PRIVATE int sqlite3AuthCheck( /* Don't do any authorization checks if the database is initialising ** or if the parser is being invoked from within sqlite3_declare_vtab. */ + assert( !IN_RENAME_OBJECT || db->xAuth==0 ); if( db->init.busy || IN_SPECIAL_PARSE ){ return SQLITE_OK; } @@ -105938,17 +106279,15 @@ SQLITE_PRIVATE Table *sqlite3LocateTable( if( p==0 ){ const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table"; #ifndef SQLITE_OMIT_VIRTUALTABLE - if( sqlite3FindDbName(db, zDbase)<1 ){ - /* If zName is the not the name of a table in the schema created using - ** CREATE, then check to see if it is the name of an virtual table that - ** can be an eponymous virtual table. */ - Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName); - if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){ - pMod = sqlite3PragmaVtabRegister(db, zName); - } - if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){ - return pMod->pEpoTab; - } + /* If zName is the not the name of a table in the schema created using + ** CREATE, then check to see if it is the name of an virtual table that + ** can be an eponymous virtual table. */ + Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName); + if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){ + pMod = sqlite3PragmaVtabRegister(db, zName); + } + if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){ + return pMod->pEpoTab; } #endif if( (flags & LOCATE_NOERR)==0 ){ @@ -106128,17 +106467,22 @@ SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3 *db, int iDb){ SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){ int i; sqlite3BtreeEnterAll(db); - assert( db->nSchemaLock==0 ); for(i=0; inDb; i++){ Db *pDb = &db->aDb[i]; if( pDb->pSchema ){ - sqlite3SchemaClear(pDb->pSchema); + if( db->nSchemaLock==0 ){ + sqlite3SchemaClear(pDb->pSchema); + }else{ + DbSetProperty(db, i, DB_ResetWanted); + } } } db->mDbFlags &= ~(DBFLAG_SchemaChange|DBFLAG_SchemaKnownOk); sqlite3VtabUnlockList(db); sqlite3BtreeLeaveAll(db); - sqlite3CollapseDatabaseArray(db); + if( db->nSchemaLock==0 ){ + sqlite3CollapseDatabaseArray(db); + } } /* @@ -106215,6 +106559,12 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){ /* Delete the Table structure itself. */ +#ifdef SQLITE_ENABLE_NORMALIZE + if( pTable->pColHash ){ + sqlite3HashClear(pTable->pColHash); + sqlite3_free(pTable->pColHash); + } +#endif sqlite3DeleteColumnNames(db, pTable); sqlite3DbFree(db, pTable->zName); sqlite3DbFree(db, pTable->zColAff); @@ -106373,6 +106723,20 @@ SQLITE_PRIVATE int sqlite3TwoPartName( return iDb; } +/* +** True if PRAGMA writable_schema is ON +*/ +SQLITE_PRIVATE int sqlite3WritableSchema(sqlite3 *db){ + testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==0 ); + testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))== + SQLITE_WriteSchema ); + testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))== + SQLITE_Defensive ); + testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))== + (SQLITE_WriteSchema|SQLITE_Defensive) ); + return (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==SQLITE_WriteSchema; +} + /* ** This routine is used to check if the UTF-8 string zName is a legal ** unqualified name for a new schema object (table, index, view or @@ -106382,7 +106746,7 @@ SQLITE_PRIVATE int sqlite3TwoPartName( */ SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *pParse, const char *zName){ if( !pParse->db->init.busy && pParse->nested==0 - && (pParse->db->flags & SQLITE_WriteSchema)==0 + && sqlite3WritableSchema(pParse->db)==0 && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){ sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName); return SQLITE_ERROR; @@ -107458,6 +107822,36 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ recomputeColumnsNotIndexed(pPk); } +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Return true if zName is a shadow table name in the current database +** connection. +** +** zName is temporarily modified while this routine is running, but is +** restored to its original value prior to this routine returning. +*/ +static int isShadowTableName(sqlite3 *db, char *zName){ + char *zTail; /* Pointer to the last "_" in zName */ + Table *pTab; /* Table that zName is a shadow of */ + Module *pMod; /* Module for the virtual table */ + + zTail = strrchr(zName, '_'); + if( zTail==0 ) return 0; + *zTail = 0; + pTab = sqlite3FindTable(db, zName, 0); + *zTail = '_'; + if( pTab==0 ) return 0; + if( !IsVirtual(pTab) ) return 0; + pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]); + if( pMod==0 ) return 0; + if( pMod->pModule->iVersion<3 ) return 0; + if( pMod->pModule->xShadowName==0 ) return 0; + return pMod->pModule->xShadowName(zTail+1); +} +#else +# define isShadowTableName(x,y) 0 +#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ + /* ** This routine is called to report the final ")" that terminates ** a CREATE TABLE statement. @@ -107497,6 +107891,10 @@ SQLITE_PRIVATE void sqlite3EndTable( p = pParse->pNewTable; if( p==0 ) return; + if( pSelect==0 && isShadowTableName(db, p->zName) ){ + p->tabFlags |= TF_Shadow; + } + /* If the db->init.busy is 1 it means we are reading the SQL off the ** "sqlite_master" or "sqlite_temp_master" table on the disk. ** So do not write to the disk again. Extract the root page number @@ -108004,7 +108402,7 @@ SQLITE_PRIVATE void sqlite3RootPageMoved(sqlite3 *db, int iDb, int iFrom, int iT static void destroyRootPage(Parse *pParse, int iTable, int iDb){ Vdbe *v = sqlite3GetVdbe(pParse); int r1 = sqlite3GetTempReg(pParse); - assert( iTable>1 ); + if( iTable<2 ) sqlite3ErrorMsg(pParse, "corrupt schema"); sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb); sqlite3MayAbort(pParse); #ifndef SQLITE_OMIT_AUTOVACUUM @@ -110459,6 +110857,21 @@ static FuncDef *functionSearch( } return 0; } +#ifdef SQLITE_ENABLE_NORMALIZE +SQLITE_PRIVATE FuncDef *sqlite3FunctionSearchN( + int h, /* Hash of the name */ + const char *zFunc, /* Name of function */ + int nFunc /* Length of the name */ +){ + FuncDef *p; + for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){ + if( sqlite3StrNICmp(p->zName, zFunc, nFunc)==0 ){ + return p; + } + } + return 0; +} +#endif /* SQLITE_ENABLE_NORMALIZE */ /* ** Insert a new FuncDef into a FuncDefHash hash table. @@ -110472,7 +110885,7 @@ SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs( FuncDef *pOther; const char *zName = aDef[i].zName; int nName = sqlite3Strlen30(zName); - int h = (zName[0] + nName) % SQLITE_FUNC_HASH_SZ; + int h = SQLITE_FUNC_HASH(zName[0], nName); assert( zName[0]>='a' && zName[0]<='z' ); pOther = functionSearch(h, zName); if( pOther ){ @@ -110551,7 +110964,7 @@ SQLITE_PRIVATE FuncDef *sqlite3FindFunction( */ if( !createFlag && (pBest==0 || (db->mDbFlags & DBFLAG_PreferBuiltin)!=0) ){ bestScore = 0; - h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % SQLITE_FUNC_HASH_SZ; + h = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zName[0]], nName); p = functionSearch(h, zName); while( p ){ int score = matchQuality(p, nArg, enc); @@ -110699,32 +111112,49 @@ SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ return pTab; } +/* Return true if table pTab is read-only. +** +** A table is read-only if any of the following are true: +** +** 1) It is a virtual table and no implementation of the xUpdate method +** has been provided +** +** 2) It is a system table (i.e. sqlite_master), this call is not +** part of a nested parse and writable_schema pragma has not +** been specified +** +** 3) The table is a shadow table, the database connection is in +** defensive mode, and the current sqlite3_prepare() +** is for a top-level SQL statement. +*/ +static int tabIsReadOnly(Parse *pParse, Table *pTab){ + sqlite3 *db; + if( IsVirtual(pTab) ){ + return sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0; + } + if( (pTab->tabFlags & (TF_Readonly|TF_Shadow))==0 ) return 0; + db = pParse->db; + if( (pTab->tabFlags & TF_Readonly)!=0 ){ + return sqlite3WritableSchema(db)==0 && pParse->nested==0; + } + assert( pTab->tabFlags & TF_Shadow ); + return (db->flags & SQLITE_Defensive)!=0 +#ifndef SQLITE_OMIT_VIRTUALTABLE + && db->pVtabCtx==0 +#endif + && db->nVdbeExec==0; +} + /* ** Check to make sure the given table is writable. If it is not ** writable, generate an error message and return 1. If it is ** writable return 0; */ SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){ - /* A table is not writable under the following circumstances: - ** - ** 1) It is a virtual table and no implementation of the xUpdate method - ** has been provided, or - ** 2) It is a system table (i.e. sqlite_master), this call is not - ** part of a nested parse and writable_schema pragma has not - ** been specified. - ** - ** In either case leave an error message in pParse and return non-zero. - */ - if( ( IsVirtual(pTab) - && sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 ) - || ( (pTab->tabFlags & TF_Readonly)!=0 - && (pParse->db->flags & SQLITE_WriteSchema)==0 - && pParse->nested==0 ) - ){ + if( tabIsReadOnly(pParse, pTab) ){ sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName); return 1; } - #ifndef SQLITE_OMIT_VIEW if( !viewOk && pTab->pSelect ){ sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName); @@ -114128,7 +114558,7 @@ static Expr *exprTableColumn( ){ Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0); if( pExpr ){ - pExpr->pTab = pTab; + pExpr->y.pTab = pTab; pExpr->iTable = iCursor; pExpr->iColumn = iCol; } @@ -115204,7 +115634,8 @@ SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ }while( i>=0 && zColAff[i]==SQLITE_AFF_BLOB ); pTab->zColAff = zColAff; } - i = sqlite3Strlen30(zColAff); + assert( zColAff!=0 ); + i = sqlite3Strlen30NN(zColAff); if( i ){ if( iReg ){ sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i); @@ -116184,14 +116615,15 @@ insert_cleanup: #endif /* -** Meanings of bits in of pWalker->eCode for checkConstraintUnchanged() +** Meanings of bits in of pWalker->eCode for +** sqlite3ExprReferencesUpdatedColumn() */ #define CKCNSTRNT_COLUMN 0x01 /* CHECK constraint uses a changing column */ #define CKCNSTRNT_ROWID 0x02 /* CHECK constraint references the ROWID */ -/* This is the Walker callback from checkConstraintUnchanged(). Set -** bit 0x01 of pWalker->eCode if -** pWalker->eCode to 0 if this expression node references any of the +/* This is the Walker callback from sqlite3ExprReferencesUpdatedColumn(). +* Set bit 0x01 of pWalker->eCode if pWalker->eCode to 0 and if this +** expression node references any of the ** columns that are being modifed by an UPDATE statement. */ static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){ @@ -116213,12 +116645,21 @@ static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){ ** only columns that are modified by the UPDATE are those for which ** aiChng[i]>=0, and also the ROWID is modified if chngRowid is true. ** -** Return true if CHECK constraint pExpr does not use any of the +** Return true if CHECK constraint pExpr uses any of the ** changing columns (or the rowid if it is changing). In other words, -** return true if this CHECK constraint can be skipped when validating +** return true if this CHECK constraint must be validated for ** the new row in the UPDATE statement. +** +** 2018-09-15: pExpr might also be an expression for an index-on-expressions. +** The operation of this routine is the same - return true if an only if +** the expression uses one or more of columns identified by the second and +** third arguments. */ -static int checkConstraintUnchanged(Expr *pExpr, int *aiChng, int chngRowid){ +SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn( + Expr *pExpr, /* The expression to be checked */ + int *aiChng, /* aiChng[x]>=0 if column x changed by the UPDATE */ + int chngRowid /* True if UPDATE changes the rowid */ +){ Walker w; memset(&w, 0, sizeof(w)); w.eCode = 0; @@ -116233,7 +116674,7 @@ static int checkConstraintUnchanged(Expr *pExpr, int *aiChng, int chngRowid){ testcase( w.eCode==CKCNSTRNT_COLUMN ); testcase( w.eCode==CKCNSTRNT_ROWID ); testcase( w.eCode==(CKCNSTRNT_ROWID|CKCNSTRNT_COLUMN) ); - return !w.eCode; + return w.eCode!=0; } /* @@ -116439,7 +116880,13 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( for(i=0; inExpr; i++){ int allOk; Expr *pExpr = pCheck->a[i].pExpr; - if( aiChng && checkConstraintUnchanged(pExpr, aiChng, pkChng) ) continue; + if( aiChng + && !sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, pkChng) + ){ + /* The check constraints do not reference any of the columns being + ** updated so there is no point it verifying the check constraint */ + continue; + } allOk = sqlite3VdbeMakeLabel(v); sqlite3VdbeVerifyAbortable(v, onError); sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL); @@ -117940,12 +118387,15 @@ struct sqlite3_api_routines { int (*str_errcode)(sqlite3_str*); int (*str_length)(sqlite3_str*); char *(*str_value)(sqlite3_str*); + /* Version 3.25.0 and later */ int (*create_window_function)(sqlite3*,const char*,int,int,void*, void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*), void (*xValue)(sqlite3_context*), void (*xInv)(sqlite3_context*,int,sqlite3_value**), void(*xDestroy)(void*)); + /* Version 3.26.0 and later */ + const char *(*normalized_sql)(sqlite3_stmt*); }; /* @@ -118233,6 +118683,8 @@ typedef int (*sqlite3_loadext_entry)( #define sqlite3_str_value sqlite3_api->str_value /* Version 3.25.0 and later */ #define sqlite3_create_window_function sqlite3_api->create_window_function +/* Version 3.26.0 and later */ +#define sqlite3_normalized_sql sqlite3_api->normalized_sql #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) @@ -118321,6 +118773,7 @@ typedef int (*sqlite3_loadext_entry)( # define sqlite3_declare_vtab 0 # define sqlite3_vtab_config 0 # define sqlite3_vtab_on_conflict 0 +# define sqlite3_vtab_collation 0 #endif #ifdef SQLITE_OMIT_SHARED_CACHE @@ -118688,7 +119141,13 @@ static const sqlite3_api_routines sqlite3Apis = { sqlite3_str_length, sqlite3_str_value, /* Version 3.25.0 and later */ - sqlite3_create_window_function + sqlite3_create_window_function, + /* Version 3.26.0 and later */ +#ifdef SQLITE_ENABLE_NORMALIZE + sqlite3_normalized_sql +#else + 0 +#endif }; /* @@ -119138,10 +119597,9 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){ #define PragTyp_ACTIVATE_EXTENSIONS 40 #define PragTyp_HEXKEY 41 #define PragTyp_KEY 42 -#define PragTyp_REKEY 43 -#define PragTyp_LOCK_STATUS 44 -#define PragTyp_PARSER_TRACE 45 -#define PragTyp_STATS 46 +#define PragTyp_LOCK_STATUS 43 +#define PragTyp_PARSER_TRACE 44 +#define PragTyp_STATS 45 /* Property flags associated with various pragma. */ #define PragFlg_NeedSchema 0x01 /* Force schema load before running */ @@ -119158,58 +119616,57 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){ ** result column is different from the name of the pragma */ static const char *const pragCName[] = { - /* 0 */ "cache_size", /* Used by: default_cache_size */ - /* 1 */ "cid", /* Used by: table_info */ - /* 2 */ "name", - /* 3 */ "type", - /* 4 */ "notnull", - /* 5 */ "dflt_value", - /* 6 */ "pk", - /* 7 */ "tbl", /* Used by: stats */ - /* 8 */ "idx", - /* 9 */ "wdth", - /* 10 */ "hght", - /* 11 */ "flgs", - /* 12 */ "seqno", /* Used by: index_info */ - /* 13 */ "cid", - /* 14 */ "name", + /* 0 */ "id", /* Used by: foreign_key_list */ + /* 1 */ "seq", + /* 2 */ "table", + /* 3 */ "from", + /* 4 */ "to", + /* 5 */ "on_update", + /* 6 */ "on_delete", + /* 7 */ "match", + /* 8 */ "cid", /* Used by: table_xinfo */ + /* 9 */ "name", + /* 10 */ "type", + /* 11 */ "notnull", + /* 12 */ "dflt_value", + /* 13 */ "pk", + /* 14 */ "hidden", + /* table_info reuses 8 */ /* 15 */ "seqno", /* Used by: index_xinfo */ /* 16 */ "cid", /* 17 */ "name", /* 18 */ "desc", /* 19 */ "coll", /* 20 */ "key", - /* 21 */ "seq", /* Used by: index_list */ - /* 22 */ "name", - /* 23 */ "unique", - /* 24 */ "origin", - /* 25 */ "partial", - /* 26 */ "seq", /* Used by: database_list */ + /* 21 */ "tbl", /* Used by: stats */ + /* 22 */ "idx", + /* 23 */ "wdth", + /* 24 */ "hght", + /* 25 */ "flgs", + /* 26 */ "seq", /* Used by: index_list */ /* 27 */ "name", - /* 28 */ "file", - /* 29 */ "name", /* Used by: function_list */ - /* 30 */ "builtin", - /* 31 */ "name", /* Used by: module_list pragma_list */ - /* 32 */ "seq", /* Used by: collation_list */ - /* 33 */ "name", - /* 34 */ "id", /* Used by: foreign_key_list */ - /* 35 */ "seq", - /* 36 */ "table", - /* 37 */ "from", - /* 38 */ "to", - /* 39 */ "on_update", - /* 40 */ "on_delete", - /* 41 */ "match", - /* 42 */ "table", /* Used by: foreign_key_check */ - /* 43 */ "rowid", - /* 44 */ "parent", - /* 45 */ "fkid", - /* 46 */ "busy", /* Used by: wal_checkpoint */ - /* 47 */ "log", - /* 48 */ "checkpointed", - /* 49 */ "timeout", /* Used by: busy_timeout */ - /* 50 */ "database", /* Used by: lock_status */ - /* 51 */ "status", + /* 28 */ "unique", + /* 29 */ "origin", + /* 30 */ "partial", + /* 31 */ "table", /* Used by: foreign_key_check */ + /* 32 */ "rowid", + /* 33 */ "parent", + /* 34 */ "fkid", + /* index_info reuses 15 */ + /* 35 */ "seq", /* Used by: database_list */ + /* 36 */ "name", + /* 37 */ "file", + /* 38 */ "busy", /* Used by: wal_checkpoint */ + /* 39 */ "log", + /* 40 */ "checkpointed", + /* 41 */ "name", /* Used by: function_list */ + /* 42 */ "builtin", + /* collation_list reuses 26 */ + /* 43 */ "database", /* Used by: lock_status */ + /* 44 */ "status", + /* 45 */ "cache_size", /* Used by: default_cache_size */ + /* module_list pragma_list reuses 9 */ + /* 46 */ "timeout", /* Used by: busy_timeout */ }; /* Definitions of all built-in pragmas */ @@ -119219,7 +119676,7 @@ typedef struct PragmaName { u8 mPragFlg; /* Zero or more PragFlg_XXX values */ u8 iPragCName; /* Start of column names in pragCName[] */ u8 nPragCName; /* Num of col names. 0 means use pragma name */ - u32 iArg; /* Extra argument */ + u64 iArg; /* Extra argument */ } PragmaName; static const PragmaName aPragmaName[] = { #if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD) @@ -119255,7 +119712,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "busy_timeout", /* ePragTyp: */ PragTyp_BUSY_TIMEOUT, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 49, 1, + /* ColNames: */ 46, 1, /* iArg: */ 0 }, #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) {/* zName: */ "cache_size", @@ -119292,7 +119749,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "collation_list", /* ePragTyp: */ PragTyp_COLLATION_LIST, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 32, 2, + /* ColNames: */ 26, 2, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) @@ -119327,14 +119784,14 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "database_list", /* ePragTyp: */ PragTyp_DATABASE_LIST, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0, - /* ColNames: */ 26, 3, + /* ColNames: */ 35, 3, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) {/* zName: */ "default_cache_size", /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, - /* ColNames: */ 0, 1, + /* ColNames: */ 45, 1, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) @@ -119364,14 +119821,14 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "foreign_key_check", /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0, - /* ColNames: */ 42, 4, + /* ColNames: */ 31, 4, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FOREIGN_KEY) {/* zName: */ "foreign_key_list", /* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, - /* ColNames: */ 34, 8, + /* ColNames: */ 0, 8, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) @@ -119407,7 +119864,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "function_list", /* ePragTyp: */ PragTyp_FUNCTION_LIST, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 29, 2, + /* ColNames: */ 41, 2, /* iArg: */ 0 }, #endif #endif @@ -119416,12 +119873,12 @@ static const PragmaName aPragmaName[] = { /* ePragTyp: */ PragTyp_HEXKEY, /* ePragFlg: */ 0, /* ColNames: */ 0, 0, - /* iArg: */ 0 }, + /* iArg: */ 2 }, {/* zName: */ "hexrekey", /* ePragTyp: */ PragTyp_HEXKEY, /* ePragFlg: */ 0, /* ColNames: */ 0, 0, - /* iArg: */ 0 }, + /* iArg: */ 3 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) #if !defined(SQLITE_OMIT_CHECK) @@ -119443,12 +119900,12 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "index_info", /* ePragTyp: */ PragTyp_INDEX_INFO, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, - /* ColNames: */ 12, 3, + /* ColNames: */ 15, 3, /* iArg: */ 0 }, {/* zName: */ "index_list", /* ePragTyp: */ PragTyp_INDEX_LIST, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, - /* ColNames: */ 21, 5, + /* ColNames: */ 26, 5, /* iArg: */ 0 }, {/* zName: */ "index_xinfo", /* ePragTyp: */ PragTyp_INDEX_INFO, @@ -119505,7 +119962,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "lock_status", /* ePragTyp: */ PragTyp_LOCK_STATUS, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 50, 2, + /* ColNames: */ 43, 2, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) @@ -119531,7 +119988,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "module_list", /* ePragTyp: */ PragTyp_MODULE_LIST, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 31, 1, + /* ColNames: */ 9, 1, /* iArg: */ 0 }, #endif #endif @@ -119564,7 +120021,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "pragma_list", /* ePragTyp: */ PragTyp_PRAGMA_LIST, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 31, 1, + /* ColNames: */ 9, 1, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) @@ -119595,10 +120052,10 @@ static const PragmaName aPragmaName[] = { #endif #if defined(SQLITE_HAS_CODEC) {/* zName: */ "rekey", - /* ePragTyp: */ PragTyp_REKEY, + /* ePragTyp: */ PragTyp_KEY, /* ePragFlg: */ 0, /* ColNames: */ 0, 0, - /* iArg: */ 0 }, + /* iArg: */ 1 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "reverse_unordered_selects", @@ -119651,7 +120108,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "stats", /* ePragTyp: */ PragTyp_STATS, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, - /* ColNames: */ 7, 5, + /* ColNames: */ 21, 5, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) @@ -119665,8 +120122,13 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "table_info", /* ePragTyp: */ PragTyp_TABLE_INFO, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, - /* ColNames: */ 1, 6, + /* ColNames: */ 8, 6, /* iArg: */ 0 }, + {/* zName: */ "table_xinfo", + /* ePragTyp: */ PragTyp_TABLE_INFO, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, + /* ColNames: */ 8, 7, + /* iArg: */ 1 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) {/* zName: */ "temp_store", @@ -119679,6 +120141,18 @@ static const PragmaName aPragmaName[] = { /* ePragFlg: */ PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ 0 }, +#endif +#if defined(SQLITE_HAS_CODEC) + {/* zName: */ "textkey", + /* ePragTyp: */ PragTyp_KEY, + /* ePragFlg: */ 0, + /* ColNames: */ 0, 0, + /* iArg: */ 4 }, + {/* zName: */ "textrekey", + /* ePragTyp: */ PragTyp_KEY, + /* ePragFlg: */ 0, + /* ColNames: */ 0, 0, + /* iArg: */ 5 }, #endif {/* zName: */ "threads", /* ePragTyp: */ PragTyp_THREADS, @@ -119730,7 +120204,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "wal_checkpoint", /* ePragTyp: */ PragTyp_WAL_CHECKPOINT, /* ePragFlg: */ PragFlg_NeedSchema, - /* ColNames: */ 46, 3, + /* ColNames: */ 38, 3, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) @@ -119738,10 +120212,10 @@ static const PragmaName aPragmaName[] = { /* ePragTyp: */ PragTyp_FLAG, /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, - /* iArg: */ SQLITE_WriteSchema }, + /* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError }, #endif }; -/* Number of pragmas: 61 on by default, 78 total. */ +/* Number of pragmas: 62 on by default, 81 total. */ /************** End of pragma.h **********************************************/ /************** Continuing where we left off in pragma.c *********************/ @@ -120753,7 +121227,7 @@ SQLITE_PRIVATE void sqlite3Pragma( setPragmaResultColumnNames(v, pPragma); returnSingleInt(v, (db->flags & pPragma->iArg)!=0 ); }else{ - int mask = pPragma->iArg; /* Mask of bits to set or clear. */ + u64 mask = pPragma->iArg; /* Mask of bits to set or clear. */ if( db->autoCommit==0 ){ /* Foreign key support may not be enabled or disabled while not ** in auto-commit mode. */ @@ -120802,15 +121276,17 @@ SQLITE_PRIVATE void sqlite3Pragma( Table *pTab; pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb); if( pTab ){ + int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); int i, k; int nHidden = 0; Column *pCol; Index *pPk = sqlite3PrimaryKeyIndex(pTab); - pParse->nMem = 6; - sqlite3CodeVerifySchema(pParse, iDb); + pParse->nMem = 7; + sqlite3CodeVerifySchema(pParse, iTabDb); sqlite3ViewGetColumnNames(pParse, pTab); for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){ - if( IsHiddenColumn(pCol) ){ + int isHidden = IsHiddenColumn(pCol); + if( isHidden && pPragma->iArg==0 ){ nHidden++; continue; } @@ -120822,13 +121298,14 @@ SQLITE_PRIVATE void sqlite3Pragma( for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){} } assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN ); - sqlite3VdbeMultiLoad(v, 1, "issisi", + sqlite3VdbeMultiLoad(v, 1, pPragma->iArg ? "issisii" : "issisi", i-nHidden, pCol->zName, sqlite3ColumnType(pCol,""), pCol->notNull ? 1 : 0, pCol->pDflt ? pCol->pDflt->u.zToken : 0, - k); + k, + isHidden); } } } @@ -120866,6 +121343,7 @@ SQLITE_PRIVATE void sqlite3Pragma( Table *pTab; pIdx = sqlite3FindIndex(db, zRight, zDb); if( pIdx ){ + int iIdxDb = sqlite3SchemaToIndex(db, pIdx->pSchema); int i; int mx; if( pPragma->iArg ){ @@ -120878,7 +121356,7 @@ SQLITE_PRIVATE void sqlite3Pragma( pParse->nMem = 3; } pTab = pIdx->pTable; - sqlite3CodeVerifySchema(pParse, iDb); + sqlite3CodeVerifySchema(pParse, iIdxDb); assert( pParse->nMem<=pPragma->nPragCName ); for(i=0; iaiColumn[i]; @@ -120902,8 +121380,9 @@ SQLITE_PRIVATE void sqlite3Pragma( int i; pTab = sqlite3FindTable(db, zRight, zDb); if( pTab ){ + int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); pParse->nMem = 5; - sqlite3CodeVerifySchema(pParse, iDb); + sqlite3CodeVerifySchema(pParse, iTabDb); for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){ const char *azOrigin[] = { "c", "u", "pk" }; sqlite3VdbeMultiLoad(v, 1, "isisi", @@ -120950,6 +121429,7 @@ SQLITE_PRIVATE void sqlite3Pragma( pParse->nMem = 2; for(i=0; iu.pHash ){ + if( p->funcFlags & SQLITE_FUNC_INTERNAL ) continue; sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 1); } } @@ -120991,9 +121471,10 @@ SQLITE_PRIVATE void sqlite3Pragma( if( pTab ){ pFK = pTab->pFKey; if( pFK ){ + int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); int i = 0; pParse->nMem = 8; - sqlite3CodeVerifySchema(pParse, iDb); + sqlite3CodeVerifySchema(pParse, iTabDb); while(pFK){ int j; for(j=0; jnCol; j++){ @@ -121038,9 +121519,9 @@ SQLITE_PRIVATE void sqlite3Pragma( pParse->nMem += 4; regKey = ++pParse->nMem; regRow = ++pParse->nMem; - sqlite3CodeVerifySchema(pParse, iDb); k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash); while( k ){ + int iTabDb; if( zRight ){ pTab = sqlite3LocateTable(pParse, 0, zRight, zDb); k = 0; @@ -121049,21 +121530,23 @@ SQLITE_PRIVATE void sqlite3Pragma( k = sqliteHashNext(k); } if( pTab==0 || pTab->pFKey==0 ) continue; - sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); + iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); + sqlite3CodeVerifySchema(pParse, iTabDb); + sqlite3TableLock(pParse, iTabDb, pTab->tnum, 0, pTab->zName); if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow; - sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead); + sqlite3OpenTable(pParse, 0, iTabDb, pTab, OP_OpenRead); sqlite3VdbeLoadString(v, regResult, pTab->zName); for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){ pParent = sqlite3FindTable(db, pFK->zTo, zDb); if( pParent==0 ) continue; pIdx = 0; - sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName); + sqlite3TableLock(pParse, iTabDb, pParent->tnum, 0, pParent->zName); x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0); if( x==0 ){ if( pIdx==0 ){ - sqlite3OpenTable(pParse, i, iDb, pParent, OP_OpenRead); + sqlite3OpenTable(pParse, i, iTabDb, pParent, OP_OpenRead); }else{ - sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iDb); + sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iTabDb); sqlite3VdbeSetP4KeyInfo(pParse, pIdx); } }else{ @@ -121832,12 +122315,24 @@ SQLITE_PRIVATE void sqlite3Pragma( #endif #ifdef SQLITE_HAS_CODEC + /* Pragma iArg + ** ---------- ------ + ** key 0 + ** rekey 1 + ** hexkey 2 + ** hexrekey 3 + ** textkey 4 + ** textrekey 5 + */ case PragTyp_KEY: { - if( zRight ) sqlite3_key_v2(db, zDb, zRight, sqlite3Strlen30(zRight)); - break; - } - case PragTyp_REKEY: { - if( zRight ) sqlite3_rekey_v2(db, zDb, zRight, sqlite3Strlen30(zRight)); + if( zRight ){ + int n = pPragma->iArg<4 ? sqlite3Strlen30(zRight) : -1; + if( (pPragma->iArg & 1)==0 ){ + sqlite3_key_v2(db, zDb, zRight, n); + }else{ + sqlite3_rekey_v2(db, zDb, zRight, n); + } + } break; } case PragTyp_HEXKEY: { @@ -121849,7 +122344,7 @@ SQLITE_PRIVATE void sqlite3Pragma( iByte = (iByte<<4) + sqlite3HexToInt(zRight[i]); if( (i&1)!=0 ) zKey[i/2] = iByte; } - if( (zLeft[3] & 0xf)==0xb ){ + if( (pPragma->iArg & 1)==0 ){ sqlite3_key_v2(db, zDb, zKey, i/2); }else{ sqlite3_rekey_v2(db, zDb, zKey, i/2); @@ -122179,7 +122674,8 @@ static const sqlite3_module pragmaVtabModule = { 0, /* xRename - rename the table */ 0, /* xSavepoint */ 0, /* xRelease */ - 0 /* xRollbackTo */ + 0, /* xRollbackTo */ + 0 /* xShadowName */ }; /* @@ -122532,8 +123028,8 @@ SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFl rc = SQLITE_NOMEM_BKPT; sqlite3ResetAllSchemasOfConnection(db); } - if( rc==SQLITE_OK || (db->flags&SQLITE_WriteSchema)){ - /* Black magic: If the SQLITE_WriteSchema flag is set, then consider + if( rc==SQLITE_OK || (db->flags&SQLITE_NoSchemaError)){ + /* Black magic: If the SQLITE_NoSchemaError flag is set, then consider ** the schema loaded, even if errors occurred. In this situation the ** current sqlite3_prepare() operation will fail, but the following one ** will attempt to compile the supplied statement against whatever subset @@ -122914,6 +123410,294 @@ static int sqlite3LockAndPrepare( return rc; } +#ifdef SQLITE_ENABLE_NORMALIZE +/* +** Checks if the specified token is a table, column, or function name, +** based on the databases associated with the statement being prepared. +** If the function fails, zero is returned and pRc is filled with the +** error code. +*/ +static int shouldTreatAsIdentifier( + sqlite3 *db, /* Database handle. */ + const char *zToken, /* Pointer to start of token to be checked */ + int nToken, /* Length of token to be checked */ + int *pRc /* Pointer to error code upon failure */ +){ + int bFound = 0; /* Non-zero if token is an identifier name. */ + int i, j; /* Database and column loop indexes. */ + Schema *pSchema; /* Schema for current database. */ + Hash *pHash; /* Hash table of tables for current database. */ + HashElem *e; /* Hash element for hash table iteration. */ + Table *pTab; /* Database table for columns being checked. */ + + if( sqlite3IsRowidN(zToken, nToken) ){ + return 1; + } + if( nToken>0 ){ + int hash = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zToken[0]], nToken); + if( sqlite3FunctionSearchN(hash, zToken, nToken) ) return 1; + } + assert( db!=0 ); + sqlite3_mutex_enter(db->mutex); + sqlite3BtreeEnterAll(db); + for(i=0; inDb; i++){ + pHash = &db->aFunc; + if( sqlite3HashFindN(pHash, zToken, nToken) ){ + bFound = 1; + break; + } + pSchema = db->aDb[i].pSchema; + if( pSchema==0 ) continue; + pHash = &pSchema->tblHash; + if( sqlite3HashFindN(pHash, zToken, nToken) ){ + bFound = 1; + break; + } + for(e=sqliteHashFirst(pHash); e; e=sqliteHashNext(e)){ + pTab = sqliteHashData(e); + if( pTab==0 ) continue; + pHash = pTab->pColHash; + if( pHash==0 ){ + pTab->pColHash = pHash = sqlite3_malloc(sizeof(Hash)); + if( pHash ){ + sqlite3HashInit(pHash); + for(j=0; jnCol; j++){ + Column *pCol = &pTab->aCol[j]; + sqlite3HashInsert(pHash, pCol->zName, pCol); + } + }else{ + *pRc = SQLITE_NOMEM_BKPT; + bFound = 0; + goto done; + } + } + if( pHash && sqlite3HashFindN(pHash, zToken, nToken) ){ + bFound = 1; + goto done; + } + } + } +done: + sqlite3BtreeLeaveAll(db); + sqlite3_mutex_leave(db->mutex); + return bFound; +} + +/* +** Attempt to estimate the final output buffer size needed for the fully +** normalized version of the specified SQL string. This should take into +** account any potential expansion that could occur (e.g. via IN clauses +** being expanded, etc). This size returned is the total number of bytes +** including the NUL terminator. +*/ +static int estimateNormalizedSize( + const char *zSql, /* The original SQL string */ + int nSql, /* Length of original SQL string */ + u8 prepFlags /* The flags passed to sqlite3_prepare_v3() */ +){ + int nOut = nSql + 4; + const char *z = zSql; + while( nOut0 ){ + zOut[j++] = '"'; + continue; + }else if( k==nToken-1 ){ + zOut[j++] = '"'; + continue; + } + } + if( bKeyword ){ + zOut[j++] = sqlite3Toupper(zSql[iIn+k]); + }else{ + zOut[j++] = sqlite3Tolower(zSql[iIn+k]); + } + } + *piOut = j; +} + +/* +** Perform normalization of the SQL contained in the prepared statement and +** store the result in the zNormSql field. The schema for the associated +** databases are consulted while performing the normalization in order to +** determine if a token appears to be an identifier. All identifiers are +** left intact in the normalized SQL and all literals are replaced with a +** single '?'. +*/ +SQLITE_PRIVATE void sqlite3Normalize( + Vdbe *pVdbe, /* VM being reprepared */ + const char *zSql, /* The original SQL string */ + int nSql, /* Size of the input string in bytes */ + u8 prepFlags /* The flags passed to sqlite3_prepare_v3() */ +){ + sqlite3 *db; /* Database handle. */ + char *z; /* The output string */ + int nZ; /* Size of the output string in bytes */ + int i; /* Next character to read from zSql[] */ + int j; /* Next character to fill in on z[] */ + int tokenType = 0; /* Type of the next token */ + int prevTokenType = 0; /* Type of the previous token, except spaces */ + int n; /* Size of the next token */ + int nParen = 0; /* Nesting level of parenthesis */ + Hash inHash; /* Table of parenthesis levels to output index. */ + + db = sqlite3VdbeDb(pVdbe); + assert( db!=0 ); + assert( pVdbe->zNormSql==0 ); + if( zSql==0 ) return; + nZ = estimateNormalizedSize(zSql, nSql, prepFlags); + z = sqlite3DbMallocRawNN(db, nZ); + if( z==0 ) return; + sqlite3HashInit(&inHash); + for(i=j=0; i0 ){ + sqlite3HashInsert(&inHash, zSql+nParen, 0); + assert( jj+6=0 ); + assert( nZ-1-j=0 ); + /* Fall through */ + } + case TK_MINUS: + case TK_SEMI: + case TK_PLUS: + case TK_STAR: + case TK_SLASH: + case TK_REM: + case TK_EQ: + case TK_LE: + case TK_NE: + case TK_LSHIFT: + case TK_LT: + case TK_RSHIFT: + case TK_GT: + case TK_GE: + case TK_BITOR: + case TK_CONCAT: + case TK_COMMA: + case TK_BITAND: + case TK_BITNOT: + case TK_DOT: + case TK_IN: + case TK_IS: + case TK_NOT: + case TK_NULL: + case TK_ID: { + if( tokenType==TK_NULL ){ + if( prevTokenType==TK_IS || prevTokenType==TK_NOT ){ + /* NULL is a keyword in this case, not a literal value */ + }else{ + /* Here the NULL is a literal value */ + z[j++] = '?'; + break; + } + } + if( j>0 && sqlite3IsIdChar(z[j-1]) && sqlite3IsIdChar(zSql[i]) ){ + z[j++] = ' '; + } + if( tokenType==TK_ID ){ + int i2 = i, n2 = n, rc = SQLITE_OK; + if( nParen>0 ){ + assert( nParen0 && z[j-1]==' ' ){ j--; } + if( j>0 && z[j-1]!=';' ){ z[j++] = ';'; } + z[j] = 0; + assert( jzNormSql = z; + sqlite3HashClear(&inHash); +} +#endif /* SQLITE_ENABLE_NORMALIZE */ + /* ** Rerun the compilation of a statement after a schema change. ** @@ -123926,7 +124710,7 @@ static void selectExprDefer( struct ExprList_item *pItem = &pEList->a[i]; if( pItem->u.x.iOrderByCol==0 ){ Expr *pExpr = pItem->pExpr; - Table *pTab = pExpr->pTab; + Table *pTab = pExpr->y.pTab; if( pExpr->op==TK_COLUMN && pExpr->iColumn>=0 && pTab && !IsVirtual(pTab) && (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF) ){ @@ -123949,12 +124733,12 @@ static void selectExprDefer( Expr *pNew = sqlite3PExpr(pParse, TK_COLUMN, 0, 0); if( pNew ){ pNew->iTable = pExpr->iTable; - pNew->pTab = pExpr->pTab; + pNew->y.pTab = pExpr->y.pTab; pNew->iColumn = pPk ? pPk->aiColumn[k] : -1; pExtra = sqlite3ExprListAppend(pParse, pExtra, pNew); } } - pSort->aDefer[nDefer].pTab = pExpr->pTab; + pSort->aDefer[nDefer].pTab = pExpr->y.pTab; pSort->aDefer[nDefer].iCsr = pExpr->iTable; pSort->aDefer[nDefer].nKey = nKey; nDefer++; @@ -124803,7 +125587,7 @@ static const char *columnTypeImpl( break; } - assert( pTab && pExpr->pTab==pTab ); + assert( pTab && pExpr->y.pTab==pTab ); if( pS ){ /* The "table" is actually a sub-select or a view in the FROM clause ** of the SELECT statement. Return the declaration type and origin @@ -124988,7 +125772,7 @@ static void generateColumnNames( assert( p!=0 ); assert( p->op!=TK_AGG_COLUMN ); /* Agg processing has not run yet */ - assert( p->op!=TK_COLUMN || p->pTab!=0 ); /* Covering idx not yet coded */ + assert( p->op!=TK_COLUMN || p->y.pTab!=0 ); /* Covering idx not yet coded */ if( pEList->a[i].zName ){ /* An AS clause always takes first priority */ char *zName = pEList->a[i].zName; @@ -124996,7 +125780,7 @@ static void generateColumnNames( }else if( srcName && p->op==TK_COLUMN ){ char *zCol; int iCol = p->iColumn; - pTab = p->pTab; + pTab = p->y.pTab; assert( pTab!=0 ); if( iCol<0 ) iCol = pTab->iPKey; assert( iCol==-1 || (iCol>=0 && iColnCol) ); @@ -125087,7 +125871,7 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList( if( pColExpr->op==TK_COLUMN ){ /* For columns use the column name name */ int iCol = pColExpr->iColumn; - Table *pTab = pColExpr->pTab; + Table *pTab = pColExpr->y.pTab; assert( pTab!=0 ); if( iCol<0 ) iCol = pTab->iPKey; zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid"; @@ -125441,6 +126225,13 @@ static void generateWithRecursiveQuery( Expr *pLimit; /* Saved LIMIT and OFFSET */ int regLimit, regOffset; /* Registers used by LIMIT and OFFSET */ +#ifndef SQLITE_OMIT_WINDOWFUNC + if( p->pWin ){ + sqlite3ErrorMsg(pParse, "cannot use window functions in recursive queries"); + return; + } +#endif + /* Obtain authorization to do a recursive query */ if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return; @@ -127190,7 +127981,7 @@ static int flattenSubquery( #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ /* -** A structure to keep track of all of the column values that fixed to +** A structure to keep track of all of the column values that are fixed to ** a known value due to WHERE clause constraints of the form COLUMN=VALUE. */ typedef struct WhereConst WhereConst; @@ -127202,13 +127993,28 @@ struct WhereConst { }; /* -** Add a new entry to the pConst object +** Add a new entry to the pConst object. Except, do not add duplicate +** pColumn entires. */ static void constInsert( - WhereConst *pConst, - Expr *pColumn, - Expr *pValue + WhereConst *pConst, /* The WhereConst into which we are inserting */ + Expr *pColumn, /* The COLUMN part of the constraint */ + Expr *pValue /* The VALUE part of the constraint */ ){ + int i; + assert( pColumn->op==TK_COLUMN ); + + /* 2018-10-25 ticket [cf5ed20f] + ** Make sure the same pColumn is not inserted more than once */ + for(i=0; inConst; i++){ + const Expr *pExpr = pConst->apExpr[i*2]; + assert( pExpr->op==TK_COLUMN ); + if( pExpr->iTable==pColumn->iTable + && pExpr->iColumn==pColumn->iColumn + ){ + return; /* Already present. Return without doing anything. */ + } + } pConst->nConst++; pConst->apExpr = sqlite3DbReallocOrFree(pConst->pParse->db, pConst->apExpr, @@ -131190,6 +131996,57 @@ SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ #endif } +/* +** Check to see if column iCol of index pIdx references any of the +** columns defined by aXRef and chngRowid. Return true if it does +** and false if not. This is an optimization. False-positives are a +** performance degradation, but false-negatives can result in a corrupt +** index and incorrect answers. +** +** aXRef[j] will be non-negative if column j of the original table is +** being updated. chngRowid will be true if the rowid of the table is +** being updated. +*/ +static int indexColumnIsBeingUpdated( + Index *pIdx, /* The index to check */ + int iCol, /* Which column of the index to check */ + int *aXRef, /* aXRef[j]>=0 if column j is being updated */ + int chngRowid /* true if the rowid is being updated */ +){ + i16 iIdxCol = pIdx->aiColumn[iCol]; + assert( iIdxCol!=XN_ROWID ); /* Cannot index rowid */ + if( iIdxCol>=0 ){ + return aXRef[iIdxCol]>=0; + } + assert( iIdxCol==XN_EXPR ); + assert( pIdx->aColExpr!=0 ); + assert( pIdx->aColExpr->a[iCol].pExpr!=0 ); + return sqlite3ExprReferencesUpdatedColumn(pIdx->aColExpr->a[iCol].pExpr, + aXRef,chngRowid); +} + +/* +** Check to see if index pIdx is a partial index whose conditional +** expression might change values due to an UPDATE. Return true if +** the index is subject to change and false if the index is guaranteed +** to be unchanged. This is an optimization. False-positives are a +** performance degradation, but false-negatives can result in a corrupt +** index and incorrect answers. +** +** aXRef[j] will be non-negative if column j of the original table is +** being updated. chngRowid will be true if the rowid of the table is +** being updated. +*/ +static int indexWhereClauseMightChange( + Index *pIdx, /* The index to check */ + int *aXRef, /* aXRef[j]>=0 if column j is being updated */ + int chngRowid /* true if the rowid is being updated */ +){ + if( pIdx->pPartIdxWhere==0 ) return 0; + return sqlite3ExprReferencesUpdatedColumn(pIdx->pPartIdxWhere, + aXRef, chngRowid); +} + /* ** Process an UPDATE statement. ** @@ -131413,19 +132270,18 @@ SQLITE_PRIVATE void sqlite3Update( /* There is one entry in the aRegIdx[] array for each index on the table ** being updated. Fill in aRegIdx[] with a register number that will hold ** the key for accessing each index. - ** - ** FIXME: Be smarter about omitting indexes that use expressions. */ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ int reg; - if( chngKey || hasFK>1 || pIdx->pPartIdxWhere || pIdx==pPk ){ + if( chngKey || hasFK>1 || pIdx==pPk + || indexWhereClauseMightChange(pIdx,aXRef,chngRowid) + ){ reg = ++pParse->nMem; pParse->nMem += pIdx->nColumn; }else{ reg = 0; for(i=0; inKeyCol; i++){ - i16 iIdxCol = pIdx->aiColumn[i]; - if( iIdxCol<0 || aXRef[iIdxCol]>=0 ){ + if( indexColumnIsBeingUpdated(pIdx, i, aXRef, chngRowid) ){ reg = ++pParse->nMem; pParse->nMem += pIdx->nColumn; if( (onError==OE_Replace) @@ -131974,7 +132830,7 @@ static void updateVirtualTable( sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i); }else{ sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i); - sqlite3VdbeChangeP5(v, 1); /* Enable sqlite3_vtab_nochange() */ + sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG);/* Enable sqlite3_vtab_nochange() */ } } if( HasRowid(pTab) ){ @@ -132475,7 +133331,8 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){ saved_mTrace = db->mTrace; db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks; db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum; - db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder | SQLITE_CountRows); + db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder + | SQLITE_Defensive | SQLITE_CountRows); db->mTrace = 0; zDbMain = db->aDb[iDb].zDbSName; @@ -133017,7 +133874,6 @@ SQLITE_PRIVATE void sqlite3VtabBeginParse( Token *pModuleName, /* Name of the module for the virtual table */ int ifNotExists /* No error if the table already exists */ ){ - int iDb; /* The database the table is being created in */ Table *pTable; /* The new virtual table */ sqlite3 *db; /* Database connection */ @@ -133027,8 +133883,6 @@ SQLITE_PRIVATE void sqlite3VtabBeginParse( assert( 0==pTable->pIndex ); db = pParse->db; - iDb = sqlite3SchemaToIndex(db, pTable->pSchema); - assert( iDb>=0 ); assert( pTable->nModuleArg==0 ); addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName)); @@ -133048,6 +133902,8 @@ SQLITE_PRIVATE void sqlite3VtabBeginParse( ** The second call, to obtain permission to create the table, is made now. */ if( pTable->azModuleArg ){ + int iDb = sqlite3SchemaToIndex(db, pTable->pSchema); + assert( iDb>=0 ); /* The database the table is being created in */ sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName, pTable->azModuleArg[0], pParse->db->aDb[iDb].zDbSName); } @@ -133742,7 +134598,7 @@ SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction( /* Check to see the left operand is a column in a virtual table */ if( NEVER(pExpr==0) ) return pDef; if( pExpr->op!=TK_COLUMN ) return pDef; - pTab = pExpr->pTab; + pTab = pExpr->y.pTab; if( pTab==0 ) return pDef; if( !IsVirtual(pTab) ) return pDef; pVtab = sqlite3GetVTable(db, pTab)->pVtab; @@ -134362,12 +135218,33 @@ struct WhereLoopBuilder { int nRecValid; /* Number of valid fields currently in pRec */ #endif unsigned int bldFlags; /* SQLITE_BLDF_* flags */ + unsigned int iPlanLimit; /* Search limiter */ }; /* Allowed values for WhereLoopBuider.bldFlags */ #define SQLITE_BLDF_INDEXED 0x0001 /* An index is used */ #define SQLITE_BLDF_UNIQUE 0x0002 /* All keys of a UNIQUE index used */ +/* The WhereLoopBuilder.iPlanLimit is used to limit the number of +** index+constraint combinations the query planner will consider for a +** particular query. If this parameter is unlimited, then certain +** pathological queries can spend excess time in the sqlite3WhereBegin() +** routine. The limit is high enough that is should not impact real-world +** queries. +** +** SQLITE_QUERY_PLANNER_LIMIT is the baseline limit. The limit is +** increased by SQLITE_QUERY_PLANNER_LIMIT_INCR before each term of the FROM +** clause is processed, so that every table in a join is guaranteed to be +** able to propose a some index+constraint combinations even if the initial +** baseline limit was exhausted by prior tables of the join. +*/ +#ifndef SQLITE_QUERY_PLANNER_LIMIT +# define SQLITE_QUERY_PLANNER_LIMIT 20000 +#endif +#ifndef SQLITE_QUERY_PLANNER_LIMIT_INCR +# define SQLITE_QUERY_PLANNER_LIMIT_INCR 1000 +#endif + /* ** The WHERE clause processing routine has two halves. The ** first part does the start of the WHERE loop and the second @@ -134929,7 +135806,7 @@ static Expr *removeUnindexableInClauseTerms( for(i=iEq; inLTerm; i++){ if( pLoop->aLTerm[i]->pExpr==pX ){ int iField = pLoop->aLTerm[i]->iField - 1; - assert( pOrigRhs->a[iField].pExpr!=0 ); + if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */ pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr); pOrigRhs->a[iField].pExpr = 0; assert( pOrigLhs->a[iField].pExpr!=0 ); @@ -135621,7 +136498,7 @@ static int whereIndexExprTransNode(Walker *p, Expr *pExpr){ pExpr->op = TK_COLUMN; pExpr->iTable = pX->iIdxCur; pExpr->iColumn = pX->iIdxCol; - pExpr->pTab = 0; + pExpr->y.pTab = 0; return WRC_Prune; }else{ return WRC_Continue; @@ -137021,7 +137898,7 @@ static int isLikeOrGlob( ){ if( pLeft->op!=TK_COLUMN || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT - || IsVirtual(pLeft->pTab) /* Value might be numeric */ + || IsVirtual(pLeft->y.pTab) /* Value might be numeric */ ){ sqlite3ExprDelete(db, pPrefix); sqlite3ValueFree(pVal); @@ -137122,7 +137999,7 @@ static int isAuxiliaryVtabOperator( ** MATCH(expression,vtab_column) */ pCol = pList->a[1].pExpr; - if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){ + if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){ for(i=0; iu.zToken, aOp[i].zOp)==0 ){ *peOp2 = aOp[i].eOp2; @@ -137144,12 +138021,12 @@ static int isAuxiliaryVtabOperator( ** with function names in an arbitrary case. */ pCol = pList->a[0].pExpr; - if( pCol->op==TK_COLUMN && IsVirtual(pCol->pTab) ){ + if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){ sqlite3_vtab *pVtab; sqlite3_module *pMod; void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**); void *pNotUsed; - pVtab = sqlite3GetVTable(db, pCol->pTab)->pVtab; + pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab; assert( pVtab!=0 ); assert( pVtab->pModule!=0 ); pMod = (sqlite3_module *)pVtab->pModule; @@ -137167,10 +138044,10 @@ static int isAuxiliaryVtabOperator( int res = 0; Expr *pLeft = pExpr->pLeft; Expr *pRight = pExpr->pRight; - if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->pTab) ){ + if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->y.pTab) ){ res++; } - if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->pTab) ){ + if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->y.pTab) ){ res++; SWAP(Expr*, pLeft, pRight); } @@ -138122,6 +138999,7 @@ static void exprAnalyze( if( pExpr->op==TK_NOTNULL && pExpr->pLeft->op==TK_COLUMN && pExpr->pLeft->iColumn>=0 + && !ExprHasProperty(pExpr, EP_FromJoin) && OptimizationEnabled(db, SQLITE_Stat34) ){ Expr *pNewExpr; @@ -138313,6 +139191,7 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs( pArgs = pItem->u1.pFuncArg; if( pArgs==0 ) return; for(j=k=0; jnExpr; j++){ + Expr *pRhs; while( knCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;} if( k>=pTab->nCol ){ sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d", @@ -138323,9 +139202,10 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs( if( pColRef==0 ) return; pColRef->iTable = pItem->iCursor; pColRef->iColumn = k++; - pColRef->pTab = pTab; - pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, - sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0)); + pColRef->y.pTab = pTab; + pRhs = sqlite3PExpr(pParse, TK_UPLUS, + sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0); + pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs); whereClauseInsert(pWC, pTerm, TERM_DYNAMIC); } } @@ -139188,7 +140068,6 @@ static void constructAutomaticIndex( translateColumnToCopy(pParse, addrTop, pLevel->iTabCur, pTabItem->regResult, 1); sqlite3VdbeGoto(v, addrTop); - pTabItem->fg.viaCoroutine = 0; }else{ sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v); } @@ -139366,9 +140245,11 @@ static sqlite3_index_info *allocateIndexInfo( ** method of the virtual table with the sqlite3_index_info object that ** comes in as the 3rd argument to this function. ** -** If an error occurs, pParse is populated with an error message and a -** non-zero value is returned. Otherwise, 0 is returned and the output -** part of the sqlite3_index_info structure is left populated. +** If an error occurs, pParse is populated with an error message and an +** appropriate error code is returned. A return of SQLITE_CONSTRAINT from +** xBestIndex is not considered an error. SQLITE_CONSTRAINT indicates that +** the current configuration of "unusable" flags in sqlite3_index_info can +** not result in a valid plan. ** ** Whether or not an error is returned, it is the responsibility of the ** caller to eventually free p->idxStr if p->needToFreeIdxStr indicates @@ -139382,7 +140263,7 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ rc = pVtab->pModule->xBestIndex(pVtab, p); TRACE_IDX_OUTPUTS(p); - if( rc!=SQLITE_OK ){ + if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){ if( rc==SQLITE_NOMEM ){ sqlite3OomFault(pParse->db); }else if( !pVtab->zErrMsg ){ @@ -139393,19 +140274,7 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ } sqlite3_free(pVtab->zErrMsg); pVtab->zErrMsg = 0; - -#if 0 - /* This error is now caught by the caller. - ** Search for "xBestIndex malfunction" below */ - for(i=0; inConstraint; i++){ - if( !p->aConstraint[i].usable && p->aConstraintUsage[i].argvIndex>0 ){ - sqlite3ErrorMsg(pParse, - "table %s: xBestIndex returned an invalid plan", pTab->zName); - } - } -#endif - - return pParse->nErr; + return rc; } #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */ @@ -140460,6 +141329,14 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ sqlite3 *db = pWInfo->pParse->db; int rc; + /* Stop the search once we hit the query planner search limit */ + if( pBuilder->iPlanLimit==0 ){ + WHERETRACE(0xffffffff,("=== query planner search limit reached ===\n")); + if( pBuilder->pOrSet ) pBuilder->pOrSet->n = 0; + return SQLITE_DONE; + } + pBuilder->iPlanLimit--; + /* If pBuilder->pOrSet is defined, then only keep track of the costs ** and prereqs. */ @@ -141470,7 +142347,17 @@ static int whereLoopAddVirtualOne( /* Invoke the virtual table xBestIndex() method */ rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo); - if( rc ) return rc; + if( rc ){ + if( rc==SQLITE_CONSTRAINT ){ + /* If the xBestIndex method returns SQLITE_CONSTRAINT, that means + ** that the particular combination of parameters provided is unusable. + ** Make no entries in the loop table. + */ + WHERETRACE(0xffff, (" ^^^^--- non-viable plan rejected!\n")); + return SQLITE_OK; + } + return rc; + } mxTerm = -1; assert( pNew->nLSlot>=nConstraint ); @@ -141866,9 +142753,11 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ /* Loop over the tables in the join, from left to right */ pNew = pBuilder->pNew; whereLoopInit(pNew); + pBuilder->iPlanLimit = SQLITE_QUERY_PLANNER_LIMIT; for(iTab=0, pItem=pTabList->a; pItemiTab = iTab; + pBuilder->iPlanLimit += SQLITE_QUERY_PLANNER_LIMIT_INCR; pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor); if( ((pItem->fg.jointype|priorJointype) & (JT_LEFT|JT_CROSS))!=0 ){ /* This condition is true when pItem is the FROM clause term on the @@ -141894,7 +142783,15 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ rc = whereLoopAddOr(pBuilder, mPrereq, mUnusable); } mPrior |= pNew->maskSelf; - if( rc || db->mallocFailed ) break; + if( rc || db->mallocFailed ){ + if( rc==SQLITE_DONE ){ + /* We hit the query planner search limit set by iPlanLimit */ + sqlite3_log(SQLITE_WARNING, "abbreviated query algorithm search"); + rc = SQLITE_OK; + }else{ + break; + } + } } whereLoopClear(db, pNew); @@ -144276,12 +145173,12 @@ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){ switch( pExpr->op ){ case TK_FUNCTION: - if( pExpr->pWin==0 ){ + if( !ExprHasProperty(pExpr, EP_WinFunc) ){ break; }else{ Window *pWin; for(pWin=p->pWin; pWin; pWin=pWin->pNextWin){ - if( pExpr->pWin==pWin ){ + if( pExpr->y.pWin==pWin ){ assert( pWin->pOwner==pExpr ); return WRC_Prune; } @@ -144398,7 +145295,7 @@ static ExprList *exprListAppendList( */ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ int rc = SQLITE_OK; - if( p->pWin ){ + if( p->pWin && p->pPrior==0 ){ Vdbe *v = sqlite3GetVdbe(pParse); sqlite3 *db = pParse->db; Select *pSub = 0; /* The subquery */ @@ -144611,11 +145508,13 @@ windowAllocErr: */ SQLITE_PRIVATE void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){ if( p ){ + assert( p->op==TK_FUNCTION ); /* This routine is only called for the parser. If pWin was not ** allocated due to an OOM, then the parser would fail before ever ** invoking this routine */ if( ALWAYS(pWin) ){ - p->pWin = pWin; + p->y.pWin = pWin; + ExprSetProperty(p, EP_WinFunc); pWin->pOwner = p; if( p->flags & EP_Distinct ){ sqlite3ErrorMsg(pParse, @@ -145778,7 +146677,7 @@ static void windowCodeDefaultStep( */ SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){ Window *pNew = 0; - if( p ){ + if( ALWAYS(p) ){ pNew = sqlite3DbMallocZero(db, sizeof(Window)); if( pNew ){ pNew->zName = sqlite3DbStrDup(db, p->zName); @@ -145930,6 +146829,7 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep( ** input grammar file: */ /* #include */ +/* #include */ /************ Begin %include sections from the grammar ************************/ /* #include "sqliteInt.h" */ @@ -146031,13 +146931,10 @@ static void disableLookaside(Parse *pParse){ p->pLeft = p->pRight = 0; p->x.pList = 0; p->pAggInfo = 0; - p->pTab = 0; + p->y.pTab = 0; p->op2 = 0; p->iTable = 0; p->iColumn = 0; -#ifndef SQLITE_OMIT_WINDOWFUNC - p->pWin = 0; -#endif p->u.zToken = (char*)&p[1]; memcpy(p->u.zToken, t.z, t.n); p->u.zToken[t.n] = 0; @@ -150229,10 +151126,9 @@ SQLITE_PRIVATE void sqlite3Parser( yymajor = YYNOCODE; }else{ while( yypParser->yytos >= yypParser->yystack - && yymx != YYERRORSYMBOL && (yyact = yy_find_reduce_action( yypParser->yytos->stateno, - YYERRORSYMBOL)) >= YY_MIN_REDUCE + YYERRORSYMBOL)) > YY_MAX_SHIFTREDUCE ){ yy_pop_parser_stack(yypParser); } @@ -151199,6 +152095,73 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ return i; } +#ifdef SQLITE_ENABLE_NORMALIZE +/* +** Return the length (in bytes) of the token that begins at z[0]. +** Store the token type in *tokenType before returning. If flags has +** SQLITE_TOKEN_NORMALIZE flag enabled, use the identifier token type +** for keywords. Add SQLITE_TOKEN_QUOTED to flags if the token was +** actually a quoted identifier. Add SQLITE_TOKEN_KEYWORD to flags +** if the token was recognized as a keyword; this is useful when the +** SQLITE_TOKEN_NORMALIZE flag is used, because it enables the caller +** to differentiate between a keyword being treated as an identifier +** (for normalization purposes) and an actual identifier. +*/ +SQLITE_PRIVATE int sqlite3GetTokenNormalized( + const unsigned char *z, + int *tokenType, + int *flags +){ + int n; + unsigned char iClass = aiClass[*z]; + if( iClass==CC_KYWD ){ + int i; + for(i=1; aiClass[z[i]]<=CC_KYWD; i++){} + if( IdChar(z[i]) ){ + /* This token started out using characters that can appear in keywords, + ** but z[i] is a character not allowed within keywords, so this must + ** be an identifier instead */ + i++; + while( IdChar(z[i]) ){ i++; } + *tokenType = TK_ID; + return i; + } + *tokenType = TK_ID; + n = keywordCode((char*)z, i, tokenType); + /* If the token is no longer considered to be an identifier, then it is a + ** keyword of some kind. Make the token back into an identifier and then + ** set the SQLITE_TOKEN_KEYWORD flag. Several non-identifier tokens are + ** used verbatim, including IN, IS, NOT, and NULL. */ + switch( *tokenType ){ + case TK_ID: { + /* do nothing, handled by caller */ + break; + } + case TK_IN: + case TK_IS: + case TK_NOT: + case TK_NULL: { + *flags |= SQLITE_TOKEN_KEYWORD; + break; + } + default: { + *tokenType = TK_ID; + *flags |= SQLITE_TOKEN_KEYWORD; + break; + } + } + }else{ + n = sqlite3GetToken(z, tokenType); + /* If the token is considered to be an identifier and the character class + ** of the first character is a quote, set the SQLITE_TOKEN_QUOTED flag. */ + if( *tokenType==TK_ID && (iClass==CC_QUOTE || iClass==CC_QUOTE2) ){ + *flags |= SQLITE_TOKEN_QUOTED; + } + } + return n; +} +#endif /* SQLITE_ENABLE_NORMALIZE */ + /* ** Run the parser on the given SQL string. The parser structure is ** passed in. An SQLITE_ status code is returned. If an error occurs @@ -152596,6 +153559,7 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){ { SQLITE_DBCONFIG_ENABLE_QPSG, SQLITE_EnableQPSG }, { SQLITE_DBCONFIG_TRIGGER_EQP, SQLITE_TriggerEQP }, { SQLITE_DBCONFIG_RESET_DATABASE, SQLITE_ResetDatabase }, + { SQLITE_DBCONFIG_DEFENSIVE, SQLITE_Defensive }, }; unsigned int i; rc = SQLITE_ERROR; /* IMP: R-42790-23372 */ @@ -154822,6 +155786,9 @@ static int openDatabase( #endif #if defined(SQLITE_ENABLE_QPSG) | SQLITE_EnableQPSG +#endif +#if defined(SQLITE_DEFAULT_DEFENSIVE) + | SQLITE_Defensive #endif ; sqlite3HashInit(&db->aCollSeq); @@ -155710,15 +156677,26 @@ SQLITE_API int sqlite3_test_control(int op, ...){ /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff); ** - ** If parameter onoff is non-zero, configure the wrappers so that all - ** subsequent calls to localtime() and variants fail. If onoff is zero, - ** undo this setting. + ** If parameter onoff is non-zero, subsequent calls to localtime() + ** and its variants fail. If onoff is zero, undo this setting. */ case SQLITE_TESTCTRL_LOCALTIME_FAULT: { sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int); break; } + /* sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCS, int onoff); + ** + ** If parameter onoff is non-zero, internal-use-only SQL functions + ** are visible to ordinary SQL. This is useful for testing but is + ** unsafe because invalid parameters to those internal-use-only functions + ** can result in crashes or segfaults. + */ + case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: { + sqlite3GlobalConfig.bInternalFunctions = va_arg(ap, int); + break; + } + /* sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int); ** ** Set or clear a flag that indicates that the database file is always well- @@ -159161,7 +160139,7 @@ static int fts3ScanInteriorNode( const char *zCsr = zNode; /* Cursor to iterate through node */ const char *zEnd = &zCsr[nNode];/* End of interior node buffer */ char *zBuffer = 0; /* Buffer to load terms into */ - int nAlloc = 0; /* Size of allocated buffer */ + i64 nAlloc = 0; /* Size of allocated buffer */ int isFirstTerm = 1; /* True when processing first term on page */ sqlite3_int64 iChild; /* Block id of child node to descend to */ @@ -159199,14 +160177,14 @@ static int fts3ScanInteriorNode( zCsr += fts3GetVarint32(zCsr, &nSuffix); assert( nPrefix>=0 && nSuffix>=0 ); - if( &zCsr[nSuffix]>zEnd ){ + if( nPrefix>zCsr-zNode || nSuffix>zEnd-zCsr ){ rc = FTS_CORRUPT_VTAB; goto finish_scan; } - if( nPrefix+nSuffix>nAlloc ){ + if( (i64)nPrefix+nSuffix>nAlloc ){ char *zNew; - nAlloc = (nPrefix+nSuffix) * 2; - zNew = (char *)sqlite3_realloc(zBuffer, nAlloc); + nAlloc = ((i64)nPrefix+nSuffix) * 2; + zNew = (char *)sqlite3_realloc64(zBuffer, nAlloc); if( !zNew ){ rc = SQLITE_NOMEM; goto finish_scan; @@ -161186,8 +162164,23 @@ static int fts3RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ return SQLITE_OK; } +/* +** Return true if zName is the extension on one of the shadow tables used +** by this module. +*/ +static int fts3ShadowName(const char *zName){ + static const char *azName[] = { + "content", "docsize", "segdir", "segments", "stat", + }; + unsigned int i; + for(i=0; i&pReader->aNode[pReader->nNode] + if( nSuffix<=0 + || (&pReader->aNode[pReader->nNode] - pNext)pReader->nTermAlloc ){ return FTS_CORRUPT_VTAB; } - if( nPrefix+nSuffix>pReader->nTermAlloc ){ - int nNew = (nPrefix+nSuffix)*2; - char *zNew = sqlite3_realloc(pReader->zTerm, nNew); + /* Both nPrefix and nSuffix were read by fts3GetVarint32() and so are + ** between 0 and 0x7FFFFFFF. But the sum of the two may cause integer + ** overflow - hence the (i64) casts. */ + if( (i64)nPrefix+nSuffix>(i64)pReader->nTermAlloc ){ + i64 nNew = ((i64)nPrefix+nSuffix)*2; + char *zNew = sqlite3_realloc64(pReader->zTerm, nNew); if( !zNew ){ return SQLITE_NOMEM; } @@ -168818,7 +169820,7 @@ static int fts3SegReaderNext( ** b-tree node. And that the final byte of the doclist is 0x00. If either ** of these statements is untrue, then the data structure is corrupt. */ - if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode] + if( (&pReader->aNode[pReader->nNode] - pReader->aDoclist)nDoclist || (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1]) ){ return FTS_CORRUPT_VTAB; @@ -171144,6 +172146,9 @@ static int nodeReaderNext(NodeReader *p){ } p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix); + if( nPrefix>p->iOff || nSuffix>p->nNode-p->iOff ){ + return SQLITE_CORRUPT_VTAB; + } blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc); if( rc==SQLITE_OK ){ memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix); @@ -171151,6 +172156,9 @@ static int nodeReaderNext(NodeReader *p){ p->iOff += nSuffix; if( p->iChild==0 ){ p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist); + if( (p->nNode-p->iOff)nDoclist ){ + return SQLITE_CORRUPT_VTAB; + } p->aDoclist = &p->aNode[p->iOff]; p->iOff += p->nDoclist; } @@ -171158,7 +172166,6 @@ static int nodeReaderNext(NodeReader *p){ } assert( p->iOff<=p->nNode ); - return rc; } @@ -177568,6 +178575,9 @@ static int jsonEachConnect( #define JEACH_PARENT 5 #define JEACH_FULLKEY 6 #define JEACH_PATH 7 +/* The xBestIndex method assumes that the JSON and ROOT columns are +** the last two columns in the table. Should this ever changes, be +** sure to update the xBestIndex method. */ #define JEACH_JSON 8 #define JEACH_ROOT 9 @@ -177825,35 +178835,54 @@ static int jsonEachBestIndex( sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo ){ - int i; - int jsonIdx = -1; - int rootIdx = -1; + int i; /* Loop counter or computed array index */ + int aIdx[2]; /* Index of constraints for JSON and ROOT */ + int unusableMask = 0; /* Mask of unusable JSON and ROOT constraints */ + int idxMask = 0; /* Mask of usable == constraints JSON and ROOT */ const struct sqlite3_index_constraint *pConstraint; + /* This implementation assumes that JSON and ROOT are the last two + ** columns in the table */ + assert( JEACH_ROOT == JEACH_JSON+1 ); UNUSED_PARAM(tab); + aIdx[0] = aIdx[1] = -1; pConstraint = pIdxInfo->aConstraint; for(i=0; inConstraint; i++, pConstraint++){ - if( pConstraint->usable==0 ) continue; - if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; - switch( pConstraint->iColumn ){ - case JEACH_JSON: jsonIdx = i; break; - case JEACH_ROOT: rootIdx = i; break; - default: /* no-op */ break; + int iCol; + int iMask; + if( pConstraint->iColumn < JEACH_JSON ) continue; + iCol = pConstraint->iColumn - JEACH_JSON; + assert( iCol==0 || iCol==1 ); + iMask = 1 << iCol; + if( pConstraint->usable==0 ){ + unusableMask |= iMask; + }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){ + aIdx[iCol] = i; + idxMask |= iMask; } } - if( jsonIdx<0 ){ + if( (unusableMask & ~idxMask)!=0 ){ + /* If there are any unusable constraints on JSON or ROOT, then reject + ** this entire plan */ + return SQLITE_CONSTRAINT; + } + if( aIdx[0]<0 ){ + /* No JSON input. Leave estimatedCost at the huge value that it was + ** initialized to to discourage the query planner from selecting this + ** plan. */ pIdxInfo->idxNum = 0; - pIdxInfo->estimatedCost = 1e99; }else{ pIdxInfo->estimatedCost = 1.0; - pIdxInfo->aConstraintUsage[jsonIdx].argvIndex = 1; - pIdxInfo->aConstraintUsage[jsonIdx].omit = 1; - if( rootIdx<0 ){ - pIdxInfo->idxNum = 1; + i = aIdx[0]; + pIdxInfo->aConstraintUsage[i].argvIndex = 1; + pIdxInfo->aConstraintUsage[i].omit = 1; + if( aIdx[1]<0 ){ + pIdxInfo->idxNum = 1; /* Only JSON supplied. Plan 1 */ }else{ - pIdxInfo->aConstraintUsage[rootIdx].argvIndex = 2; - pIdxInfo->aConstraintUsage[rootIdx].omit = 1; - pIdxInfo->idxNum = 3; + i = aIdx[1]; + pIdxInfo->aConstraintUsage[i].argvIndex = 2; + pIdxInfo->aConstraintUsage[i].omit = 1; + pIdxInfo->idxNum = 3; /* Both JSON and ROOT are supplied. Plan 3 */ } } return SQLITE_OK; @@ -177962,7 +178991,8 @@ static sqlite3_module jsonEachModule = { 0, /* xRename */ 0, /* xSavepoint */ 0, /* xRelease */ - 0 /* xRollbackTo */ + 0, /* xRollbackTo */ + 0 /* xShadowName */ }; /* The methods of the json_tree virtual table. */ @@ -177989,7 +179019,8 @@ static sqlite3_module jsonTreeModule = { 0, /* xRename */ 0, /* xSavepoint */ 0, /* xRelease */ - 0 /* xRollbackTo */ + 0, /* xRollbackTo */ + 0 /* xShadowName */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -181419,8 +182450,24 @@ static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){ return rc; } + +/* +** Return true if zName is the extension on one of the shadow tables used +** by this module. +*/ +static int rtreeShadowName(const char *zName){ + static const char *azName[] = { + "node", "parent", "rowid" + }; + unsigned int i; + for(i=0; iz[0] && safe_isspace(p->z[0]) ) p->z++; + while( safe_isspace(p->z[0]) ) p->z++; return p->z[0]; } @@ -182485,7 +183543,7 @@ static int geopolyParseNumber(GeoParse *p, GeoCoord *pVal){ if( c=='0' && z[j+1]>='0' && z[j+1]<='9' ) return 0; for(;; j++){ c = z[j]; - if( c>='0' && c<='9' ) continue; + if( safe_isdigit(c) ) continue; if( c=='.' ){ if( z[j-1]=='-' ) return 0; if( seenDP ) return 0; @@ -182507,7 +183565,17 @@ static int geopolyParseNumber(GeoParse *p, GeoCoord *pVal){ break; } if( z[j-1]<'0' ) return 0; - if( pVal ) *pVal = (GeoCoord)atof((const char*)p->z); + if( pVal ){ +#ifdef SQLITE_AMALGAMATION + /* The sqlite3AtoF() routine is much much faster than atof(), if it + ** is available */ + double r; + (void)sqlite3AtoF((const char*)p->z, &r, j, SQLITE_UTF8); + *pVal = r; +#else + *pVal = (GeoCoord)atof((const char*)p->z); +#endif + } p->z += j; return 1; } @@ -182565,12 +183633,10 @@ static GeoPoly *geopolyParseJson(const unsigned char *z, int *pRc){ && s.a[1]==s.a[s.nVertex*2-1] && (s.z++, geopolySkipSpace(&s)==0) ){ - int nByte; GeoPoly *pOut; int x = 1; s.nVertex--; /* Remove the redundant vertex at the end */ - nByte = sizeof(GeoPoly) * s.nVertex*2*sizeof(GeoCoord); - pOut = sqlite3_malloc64( nByte ); + pOut = sqlite3_malloc64( GEOPOLY_SZ(s.nVertex) ); x = 1; if( pOut==0 ) goto parse_json_err; pOut->nVertex = s.nVertex; @@ -182773,6 +183839,27 @@ static void geopolyXformFunc( } } +/* +** Compute the area enclosed by the polygon. +** +** This routine can also be used to detect polygons that rotate in +** the wrong direction. Polygons are suppose to be counter-clockwise (CCW). +** This routine returns a negative value for clockwise (CW) polygons. +*/ +static double geopolyArea(GeoPoly *p){ + double rArea = 0.0; + int ii; + for(ii=0; iinVertex-1; ii++){ + rArea += (p->a[ii*2] - p->a[ii*2+2]) /* (x0 - x1) */ + * (p->a[ii*2+1] + p->a[ii*2+3]) /* (y0 + y1) */ + * 0.5; + } + rArea += (p->a[ii*2] - p->a[0]) /* (xN - x0) */ + * (p->a[ii*2+1] + p->a[1]) /* (yN + y0) */ + * 0.5; + return rArea; +} + /* ** Implementation of the geopoly_area(X) function. ** @@ -182788,21 +183875,106 @@ static void geopolyAreaFunc( ){ GeoPoly *p = geopolyFuncParam(context, argv[0], 0); if( p ){ - double rArea = 0.0; - int ii; - for(ii=0; iinVertex-1; ii++){ - rArea += (p->a[ii*2] - p->a[ii*2+2]) /* (x0 - x1) */ - * (p->a[ii*2+1] + p->a[ii*2+3]) /* (y0 + y1) */ - * 0.5; - } - rArea += (p->a[ii*2] - p->a[0]) /* (xN - x0) */ - * (p->a[ii*2+1] + p->a[1]) /* (yN + y0) */ - * 0.5; - sqlite3_result_double(context, rArea); + sqlite3_result_double(context, geopolyArea(p)); sqlite3_free(p); } } +/* +** Implementation of the geopoly_ccw(X) function. +** +** If the rotation of polygon X is clockwise (incorrect) instead of +** counter-clockwise (the correct winding order according to RFC7946) +** then reverse the order of the vertexes in polygon X. +** +** In other words, this routine returns a CCW polygon regardless of the +** winding order of its input. +** +** Use this routine to sanitize historical inputs that that sometimes +** contain polygons that wind in the wrong direction. +*/ +static void geopolyCcwFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + GeoPoly *p = geopolyFuncParam(context, argv[0], 0); + if( p ){ + if( geopolyArea(p)<0.0 ){ + int ii, jj; + for(ii=2, jj=p->nVertex*2 - 2; iia[ii]; + p->a[ii] = p->a[jj]; + p->a[jj] = t; + t = p->a[ii+1]; + p->a[ii+1] = p->a[jj+1]; + p->a[jj+1] = t; + } + } + sqlite3_result_blob(context, p->hdr, + 4+8*p->nVertex, SQLITE_TRANSIENT); + sqlite3_free(p); + } +} + +#define GEOPOLY_PI 3.1415926535897932385 + +/* Fast approximation for sine(X) for X between -0.5*pi and 2*pi +*/ +static double geopolySine(double r){ + assert( r>=-0.5*GEOPOLY_PI && r<=2.0*GEOPOLY_PI ); + if( r>=1.5*GEOPOLY_PI ){ + r -= 2.0*GEOPOLY_PI; + } + if( r>=0.5*GEOPOLY_PI ){ + return -geopolySine(r-GEOPOLY_PI); + }else{ + double r2 = r*r; + double r3 = r2*r; + double r5 = r3*r2; + return 0.9996949*r - 0.1656700*r3 + 0.0075134*r5; + } +} + +/* +** Function: geopoly_regular(X,Y,R,N) +** +** Construct a simple, convex, regular polygon centered at X, Y +** with circumradius R and with N sides. +*/ +static void geopolyRegularFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + double x = sqlite3_value_double(argv[0]); + double y = sqlite3_value_double(argv[1]); + double r = sqlite3_value_double(argv[2]); + int n = sqlite3_value_int(argv[3]); + int i; + GeoPoly *p; + + if( n<3 || r<=0.0 ) return; + if( n>1000 ) n = 1000; + p = sqlite3_malloc64( sizeof(*p) + (n-1)*2*sizeof(GeoCoord) ); + if( p==0 ){ + sqlite3_result_error_nomem(context); + return; + } + i = 1; + p->hdr[0] = *(unsigned char*)&i; + p->hdr[1] = 0; + p->hdr[2] = (n>>8)&0xff; + p->hdr[3] = n&0xff; + for(i=0; ia[i*2] = x - r*geopolySine(rAngle-0.5*GEOPOLY_PI); + p->a[i*2+1] = y + r*geopolySine(rAngle); + } + sqlite3_result_blob(context, p->hdr, 4+8*n, SQLITE_TRANSIENT); + sqlite3_free(p); +} + /* ** If pPoly is a polygon, compute its bounding box. Then: ** @@ -182847,7 +184019,7 @@ static GeoPoly *geopolyBBox( if( pRc ) *pRc = SQLITE_OK; if( aCoord==0 ){ geopolyBboxFill: - pOut = sqlite3_realloc(p, sizeof(GeoPoly)+sizeof(GeoCoord)*6); + pOut = sqlite3_realloc(p, GEOPOLY_SZ(4)); if( pOut==0 ){ sqlite3_free(p); if( context ) sqlite3_result_error_nomem(context); @@ -183875,7 +185047,16 @@ static int geopolyUpdate( if( sqlite3_value_nochange(aData[2]) ){ sqlite3_bind_null(pUp, 2); }else{ - sqlite3_bind_value(pUp, 2, aData[2]); + GeoPoly *p = 0; + if( sqlite3_value_type(aData[2])==SQLITE_TEXT + && (p = geopolyFuncParam(0, aData[2], &rc))!=0 + && rc==SQLITE_OK + ){ + sqlite3_bind_blob(pUp, 2, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT); + }else{ + sqlite3_bind_value(pUp, 2, aData[2]); + } + sqlite3_free(p); nChange = 1; } for(jj=1; jjnAux; jj++){ @@ -183919,7 +185100,7 @@ static int geopolyFindFunction( static sqlite3_module geopolyModule = { - 2, /* iVersion */ + 3, /* iVersion */ geopolyCreate, /* xCreate - create a table */ geopolyConnect, /* xConnect - connect to an existing table */ geopolyBestIndex, /* xBestIndex - Determine search strategy */ @@ -183942,25 +185123,29 @@ static sqlite3_module geopolyModule = { rtreeSavepoint, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ + rtreeShadowName /* xShadowName */ }; static int sqlite3_geopoly_init(sqlite3 *db){ int rc = SQLITE_OK; static const struct { void (*xFunc)(sqlite3_context*,int,sqlite3_value**); - int nArg; + signed char nArg; + unsigned char bPure; const char *zName; } aFunc[] = { - { geopolyAreaFunc, 1, "geopoly_area" }, - { geopolyBlobFunc, 1, "geopoly_blob" }, - { geopolyJsonFunc, 1, "geopoly_json" }, - { geopolySvgFunc, -1, "geopoly_svg" }, - { geopolyWithinFunc, 2, "geopoly_within" }, - { geopolyContainsPointFunc, 3, "geopoly_contains_point" }, - { geopolyOverlapFunc, 2, "geopoly_overlap" }, - { geopolyDebugFunc, 1, "geopoly_debug" }, - { geopolyBBoxFunc, 1, "geopoly_bbox" }, - { geopolyXformFunc, 7, "geopoly_xform" }, + { geopolyAreaFunc, 1, 1, "geopoly_area" }, + { geopolyBlobFunc, 1, 1, "geopoly_blob" }, + { geopolyJsonFunc, 1, 1, "geopoly_json" }, + { geopolySvgFunc, -1, 1, "geopoly_svg" }, + { geopolyWithinFunc, 2, 1, "geopoly_within" }, + { geopolyContainsPointFunc, 3, 1, "geopoly_contains_point" }, + { geopolyOverlapFunc, 2, 1, "geopoly_overlap" }, + { geopolyDebugFunc, 1, 0, "geopoly_debug" }, + { geopolyBBoxFunc, 1, 1, "geopoly_bbox" }, + { geopolyXformFunc, 7, 1, "geopoly_xform" }, + { geopolyRegularFunc, 4, 1, "geopoly_regular" }, + { geopolyCcwFunc, 1, 1, "geopoly_ccw" }, }; static const struct { void (*xStep)(sqlite3_context*,int,sqlite3_value**); @@ -183971,8 +185156,9 @@ static int sqlite3_geopoly_init(sqlite3 *db){ }; int i; for(i=0; ipRbuVfs; + rbu_file *pIter; + assert( (p->openFlags & SQLITE_OPEN_MAIN_DB) ); + sqlite3_mutex_enter(pRbuVfs->mutex); + if( p->pRbu==0 ){ + for(pIter=pRbuVfs->pMain; pIter; pIter=pIter->pMainNext); + p->pMainNext = pRbuVfs->pMain; + pRbuVfs->pMain = p; + }else{ + for(pIter=pRbuVfs->pMainRbu; pIter && pIter!=p; pIter=pIter->pMainRbuNext){} + if( pIter==0 ){ + p->pMainRbuNext = pRbuVfs->pMainRbu; + pRbuVfs->pMainRbu = p; + } + } + sqlite3_mutex_leave(pRbuVfs->mutex); +} + +/* +** Remove an item from the main-db lists. +*/ +static void rbuMainlistRemove(rbu_file *p){ + rbu_file **pp; + sqlite3_mutex_enter(p->pRbuVfs->mutex); + for(pp=&p->pRbuVfs->pMain; *pp && *pp!=p; pp=&((*pp)->pMainNext)){} + if( *pp ) *pp = p->pMainNext; + p->pMainNext = 0; + for(pp=&p->pRbuVfs->pMainRbu; *pp && *pp!=p; pp=&((*pp)->pMainRbuNext)){} + if( *pp ) *pp = p->pMainRbuNext; + p->pMainRbuNext = 0; + sqlite3_mutex_leave(p->pRbuVfs->mutex); +} + +/* +** Given that zWal points to a buffer containing a wal file name passed to +** either the xOpen() or xAccess() VFS method, search the main-db list for +** a file-handle opened by the same database connection on the corresponding +** database file. +** +** If parameter bRbu is true, only search for file-descriptors with +** rbu_file.pDb!=0. +*/ +static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal, int bRbu){ + rbu_file *pDb; + sqlite3_mutex_enter(pRbuVfs->mutex); + if( bRbu ){ + for(pDb=pRbuVfs->pMainRbu; pDb && pDb->zWal!=zWal; pDb=pDb->pMainRbuNext){} + }else{ + for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){} + } + sqlite3_mutex_leave(pRbuVfs->mutex); + return pDb; +} + /* ** Close an rbu file. */ @@ -189641,17 +190892,14 @@ static int rbuVfsClose(sqlite3_file *pFile){ sqlite3_free(p->zDel); if( p->openFlags & SQLITE_OPEN_MAIN_DB ){ - rbu_file **pp; - sqlite3_mutex_enter(p->pRbuVfs->mutex); - for(pp=&p->pRbuVfs->pMain; *pp!=p; pp=&((*pp)->pMainNext)); - *pp = p->pMainNext; - sqlite3_mutex_leave(p->pRbuVfs->mutex); + rbuMainlistRemove(p); rbuUnlockShm(p); p->pReal->pMethods->xShmUnmap(p->pReal, 0); } else if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){ rbuUpdateTempSize(p, 0); } + assert( p->pMainNext==0 && p->pRbuVfs->pMain!=p ); /* Close the underlying file handle */ rc = p->pReal->pMethods->xClose(p->pReal); @@ -189910,6 +191158,9 @@ static int rbuVfsFileControl(sqlite3_file *pFile, int op, void *pArg){ }else if( rc==SQLITE_NOTFOUND ){ pRbu->pTargetFd = p; p->pRbu = pRbu; + if( p->openFlags & SQLITE_OPEN_MAIN_DB ){ + rbuMainlistAdd(p); + } if( p->pWalFd ) p->pWalFd->pRbu = pRbu; rc = SQLITE_OK; } @@ -190071,20 +191322,6 @@ static int rbuVfsShmUnmap(sqlite3_file *pFile, int delFlag){ return rc; } -/* -** Given that zWal points to a buffer containing a wal file name passed to -** either the xOpen() or xAccess() VFS method, return a pointer to the -** file-handle opened by the same database connection on the corresponding -** database file. -*/ -static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal){ - rbu_file *pDb; - sqlite3_mutex_enter(pRbuVfs->mutex); - for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){} - sqlite3_mutex_leave(pRbuVfs->mutex); - return pDb; -} - /* ** A main database named zName has just been opened. The following ** function returns a pointer to a buffer owned by SQLite that contains @@ -190163,7 +191400,7 @@ static int rbuVfsOpen( pFd->zWal = rbuMainToWal(zName, flags); } else if( flags & SQLITE_OPEN_WAL ){ - rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName); + rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName, 0); if( pDb ){ if( pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){ /* This call is to open a *-wal file. Intead, open the *-oal. This @@ -190215,10 +191452,7 @@ static int rbuVfsOpen( ** mutex protected linked list of all such files. */ pFile->pMethods = &rbuvfs_io_methods; if( flags & SQLITE_OPEN_MAIN_DB ){ - sqlite3_mutex_enter(pRbuVfs->mutex); - pFd->pMainNext = pRbuVfs->pMain; - pRbuVfs->pMain = pFd; - sqlite3_mutex_leave(pRbuVfs->mutex); + rbuMainlistAdd(pFd); } }else{ sqlite3_free(pFd->zDel); @@ -190266,7 +191500,7 @@ static int rbuVfsAccess( ** file opened instead. */ if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){ - rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath); + rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath, 1); if( pDb && pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){ if( *pResOut ){ rc = SQLITE_CANTOPEN; @@ -190679,17 +191913,15 @@ static int statDisconnect(sqlite3_vtab *pVtab){ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ int i; - pIdxInfo->estimatedCost = 1.0e6; /* Initial cost estimate */ - /* Look for a valid schema=? constraint. If found, change the idxNum to ** 1 and request the value of that constraint be sent to xFilter. And ** lower the cost estimate to encourage the constrained version to be ** used. */ for(i=0; inConstraint; i++){ - if( pIdxInfo->aConstraint[i].usable==0 ) continue; - if( pIdxInfo->aConstraint[i].op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; if( pIdxInfo->aConstraint[i].iColumn!=10 ) continue; + if( pIdxInfo->aConstraint[i].usable==0 ) return SQLITE_CONSTRAINT; + if( pIdxInfo->aConstraint[i].op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; pIdxInfo->idxNum = 1; pIdxInfo->estimatedCost = 1.0; pIdxInfo->aConstraintUsage[i].argvIndex = 1; @@ -190739,7 +191971,7 @@ static int statOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ return SQLITE_OK; } -static void statClearPage(StatPage *p){ +static void statClearCells(StatPage *p){ int i; if( p->aCell ){ for(i=0; inCell; i++){ @@ -190747,6 +191979,12 @@ static void statClearPage(StatPage *p){ } sqlite3_free(p->aCell); } + p->nCell = 0; + p->aCell = 0; +} + +static void statClearPage(StatPage *p){ + statClearCells(p); sqlite3PagerUnref(p->pPg); sqlite3_free(p->zPath); memset(p, 0, sizeof(StatPage)); @@ -190809,22 +192047,33 @@ static int statDecodePage(Btree *pBt, StatPage *p){ u8 *aHdr = &aData[p->iPgno==1 ? 100 : 0]; p->flags = aHdr[0]; + if( p->flags==0x0A || p->flags==0x0D ){ + isLeaf = 1; + nHdr = 8; + }else if( p->flags==0x05 || p->flags==0x02 ){ + isLeaf = 0; + nHdr = 12; + }else{ + goto statPageIsCorrupt; + } + if( p->iPgno==1 ) nHdr += 100; p->nCell = get2byte(&aHdr[3]); p->nMxPayload = 0; - - isLeaf = (p->flags==0x0A || p->flags==0x0D); - nHdr = 12 - isLeaf*4 + (p->iPgno==1)*100; + szPage = sqlite3BtreeGetPageSize(pBt); nUnused = get2byte(&aHdr[5]) - nHdr - 2*p->nCell; nUnused += (int)aHdr[7]; iOff = get2byte(&aHdr[1]); while( iOff ){ + int iNext; + if( iOff>=szPage ) goto statPageIsCorrupt; nUnused += get2byte(&aData[iOff+2]); - iOff = get2byte(&aData[iOff]); + iNext = get2byte(&aData[iOff]); + if( iNext0 ) goto statPageIsCorrupt; + iOff = iNext; } p->nUnused = nUnused; p->iRightChildPg = isLeaf ? 0 : sqlite3Get4byte(&aHdr[8]); - szPage = sqlite3BtreeGetPageSize(pBt); if( p->nCell ){ int i; /* Used to iterate through cells */ @@ -190841,6 +192090,7 @@ static int statDecodePage(Btree *pBt, StatPage *p){ StatCell *pCell = &p->aCell[i]; iOff = get2byte(&aData[nHdr+i*2]); + if( iOff=szPage ) goto statPageIsCorrupt; if( !isLeaf ){ pCell->iChildPg = sqlite3Get4byte(&aData[iOff]); iOff += 4; @@ -190857,13 +192107,14 @@ static int statDecodePage(Btree *pBt, StatPage *p){ } if( nPayload>(u32)p->nMxPayload ) p->nMxPayload = nPayload; getLocalPayload(nUsable, p->flags, nPayload, &nLocal); + if( nLocal<0 ) goto statPageIsCorrupt; pCell->nLocal = nLocal; - assert( nLocal>=0 ); assert( nPayload>=(u32)nLocal ); assert( nLocal<=(nUsable-35) ); if( nPayload>(u32)nLocal ){ int j; int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4); + if( iOff+nLocal>nUsable ) goto statPageIsCorrupt; pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4); pCell->nOvfl = nOvfl; pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl); @@ -190887,6 +192138,11 @@ static int statDecodePage(Btree *pBt, StatPage *p){ } return SQLITE_OK; + +statPageIsCorrupt: + p->flags = 0; + statClearCells(p); + return SQLITE_OK; } /* @@ -191182,6 +192438,7 @@ SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ + 0 /* xShadowName */ }; return sqlite3_create_module(db, "dbstat", &dbstat_module, 0); } @@ -191312,9 +192569,8 @@ static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ if( p->iColumn!=DBPAGE_COLUMN_SCHEMA ) continue; if( p->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; if( !p->usable ){ - /* No solution. Use the default SQLITE_BIG_DBL cost */ - pIdxInfo->estimatedRows = 0x7fffffff; - return SQLITE_OK; + /* No solution. */ + return SQLITE_CONSTRAINT; } iPlan = 2; pIdxInfo->aConstraintUsage[i].argvIndex = 1; @@ -191506,6 +192762,10 @@ static int dbpageUpdate( Pager *pPager; int szPage; + if( pTab->db->flags & SQLITE_Defensive ){ + zErr = "read-only"; + goto update_fail; + } if( argc==1 ){ zErr = "cannot delete"; goto update_fail; @@ -191596,6 +192856,7 @@ SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ + 0 /* xShadowName */ }; return sqlite3_create_module(db, "sqlite_dbpage", &dbpage_module, 0); } @@ -191632,6 +192893,8 @@ typedef struct SessionInput SessionInput; # endif #endif +static int sessions_strm_chunk_size = SESSIONS_STRM_CHUNK_SIZE; + typedef struct SessionHook SessionHook; struct SessionHook { void *pCtx; @@ -191694,6 +192957,7 @@ struct sqlite3_changeset_iter { SessionInput in; /* Input buffer or stream */ SessionBuffer tblhdr; /* Buffer to hold apValue/zTab/abPK/ */ int bPatchset; /* True if this is a patchset */ + int bInvert; /* True to invert changeset */ int rc; /* Iterator error code */ sqlite3_stmt *pConflict; /* Points to conflicting row, if any */ char *zTab; /* Current table */ @@ -191850,6 +193114,42 @@ struct SessionTable { ** The records associated with INSERT changes are in the same format as for ** changesets. It is not possible for a record associated with an INSERT ** change to contain a field set to "undefined". +** +** REBASE BLOB FORMAT: +** +** A rebase blob may be output by sqlite3changeset_apply_v2() and its +** streaming equivalent for use with the sqlite3_rebaser APIs to rebase +** existing changesets. A rebase blob contains one entry for each conflict +** resolved using either the OMIT or REPLACE strategies within the apply_v2() +** call. +** +** The format used for a rebase blob is very similar to that used for +** changesets. All entries related to a single table are grouped together. +** +** Each group of entries begins with a table header in changeset format: +** +** 1 byte: Constant 0x54 (capital 'T') +** Varint: Number of columns in the table. +** nCol bytes: 0x01 for PK columns, 0x00 otherwise. +** N bytes: Unqualified table name (encoded using UTF-8). Nul-terminated. +** +** Followed by one or more entries associated with the table. +** +** 1 byte: Either SQLITE_INSERT (0x12), DELETE (0x09). +** 1 byte: Flag. 0x01 for REPLACE, 0x00 for OMIT. +** record: (in the record format defined above). +** +** In a rebase blob, the first field is set to SQLITE_INSERT if the change +** that caused the conflict was an INSERT or UPDATE, or to SQLITE_DELETE if +** it was a DELETE. The second field is set to 0x01 if the conflict +** resolution strategy was REPLACE, or 0x00 if it was OMIT. +** +** If the change that caused the conflict was a DELETE, then the single +** record is a copy of the old.* record from the original changeset. If it +** was an INSERT, then the single record is a copy of the new.* record. If +** the conflicting change was an UPDATE, then the single record is a copy +** of the new.* record with the PK fields filled in based on the original +** old.* record. */ /* @@ -193400,12 +194700,12 @@ SQLITE_API int sqlite3session_attach( static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){ if( *pRc==SQLITE_OK && p->nAlloc-p->nBufnAlloc ? p->nAlloc : 128; + i64 nNew = p->nAlloc ? p->nAlloc : 128; do { nNew = nNew*2; - }while( nNew<(p->nBuf+nByte) ); + }while( (nNew-p->nBuf)aBuf, nNew); + aNew = (u8 *)sqlite3_realloc64(p->aBuf, nNew); if( 0==aNew ){ *pRc = SQLITE_NOMEM; }else{ @@ -194003,12 +195303,12 @@ static int sessionGenerateChangeset( rc = sqlite3_reset(pSel); } - /* If the buffer is now larger than SESSIONS_STRM_CHUNK_SIZE, pass + /* If the buffer is now larger than sessions_strm_chunk_size, pass ** its contents to the xOutput() callback. */ if( xOutput && rc==SQLITE_OK && buf.nBuf>nNoop - && buf.nBuf>SESSIONS_STRM_CHUNK_SIZE + && buf.nBuf>sessions_strm_chunk_size ){ rc = xOutput(pOut, (void*)buf.aBuf, buf.nBuf); nNoop = -1; @@ -194147,7 +195447,8 @@ static int sessionChangesetStart( int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn, int nChangeset, /* Size of buffer pChangeset in bytes */ - void *pChangeset /* Pointer to buffer containing changeset */ + void *pChangeset, /* Pointer to buffer containing changeset */ + int bInvert /* True to invert changeset */ ){ sqlite3_changeset_iter *pRet; /* Iterator to return */ int nByte; /* Number of bytes to allocate for iterator */ @@ -194167,6 +195468,7 @@ static int sessionChangesetStart( pRet->in.xInput = xInput; pRet->in.pIn = pIn; pRet->in.bEof = (xInput ? 0 : 1); + pRet->bInvert = bInvert; /* Populate the output variable and return success. */ *pp = pRet; @@ -194181,7 +195483,16 @@ SQLITE_API int sqlite3changeset_start( int nChangeset, /* Size of buffer pChangeset in bytes */ void *pChangeset /* Pointer to buffer containing changeset */ ){ - return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset); + return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, 0); +} +SQLITE_API int sqlite3changeset_start_v2( + sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ + int nChangeset, /* Size of buffer pChangeset in bytes */ + void *pChangeset, /* Pointer to buffer containing changeset */ + int flags +){ + int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT); + return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, bInvert); } /* @@ -194192,7 +195503,16 @@ SQLITE_API int sqlite3changeset_start_strm( int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn ){ - return sessionChangesetStart(pp, xInput, pIn, 0, 0); + return sessionChangesetStart(pp, xInput, pIn, 0, 0, 0); +} +SQLITE_API int sqlite3changeset_start_v2_strm( + sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ + int (*xInput)(void *pIn, void *pData, int *pnData), + void *pIn, + int flags +){ + int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT); + return sessionChangesetStart(pp, xInput, pIn, 0, 0, bInvert); } /* @@ -194200,7 +195520,7 @@ SQLITE_API int sqlite3changeset_start_strm( ** object and the buffer is full, discard some data to free up space. */ static void sessionDiscardData(SessionInput *pIn){ - if( pIn->xInput && pIn->iNext>=SESSIONS_STRM_CHUNK_SIZE ){ + if( pIn->xInput && pIn->iNext>=sessions_strm_chunk_size ){ int nMove = pIn->buf.nBuf - pIn->iNext; assert( nMove>=0 ); if( nMove>0 ){ @@ -194223,7 +195543,7 @@ static int sessionInputBuffer(SessionInput *pIn, int nByte){ int rc = SQLITE_OK; if( pIn->xInput ){ while( !pIn->bEof && (pIn->iNext+nByte)>=pIn->nData && rc==SQLITE_OK ){ - int nNew = SESSIONS_STRM_CHUNK_SIZE; + int nNew = sessions_strm_chunk_size; if( pIn->bNoDiscard==0 ) sessionDiscardData(pIn); if( SQLITE_OK==sessionBufferGrow(&pIn->buf, nNew, &rc) ){ @@ -194571,10 +195891,10 @@ static int sessionChangesetNext( op = p->in.aData[p->in.iNext++]; } - if( p->zTab==0 ){ + if( p->zTab==0 || (p->bPatchset && p->bInvert) ){ /* The first record in the changeset is not a table header. Must be a ** corrupt changeset. */ - assert( p->in.iNext==1 ); + assert( p->in.iNext==1 || p->zTab ); return (p->rc = SQLITE_CORRUPT_BKPT); } @@ -194599,33 +195919,39 @@ static int sessionChangesetNext( *paRec = &p->in.aData[p->in.iNext]; p->in.iNext += *pnRec; }else{ + sqlite3_value **apOld = (p->bInvert ? &p->apValue[p->nCol] : p->apValue); + sqlite3_value **apNew = (p->bInvert ? p->apValue : &p->apValue[p->nCol]); /* If this is an UPDATE or DELETE, read the old.* record. */ if( p->op!=SQLITE_INSERT && (p->bPatchset==0 || p->op==SQLITE_DELETE) ){ u8 *abPK = p->bPatchset ? p->abPK : 0; - p->rc = sessionReadRecord(&p->in, p->nCol, abPK, p->apValue); + p->rc = sessionReadRecord(&p->in, p->nCol, abPK, apOld); if( p->rc!=SQLITE_OK ) return p->rc; } /* If this is an INSERT or UPDATE, read the new.* record. */ if( p->op!=SQLITE_DELETE ){ - p->rc = sessionReadRecord(&p->in, p->nCol, 0, &p->apValue[p->nCol]); + p->rc = sessionReadRecord(&p->in, p->nCol, 0, apNew); if( p->rc!=SQLITE_OK ) return p->rc; } - if( p->bPatchset && p->op==SQLITE_UPDATE ){ + if( (p->bPatchset || p->bInvert) && p->op==SQLITE_UPDATE ){ /* If this is an UPDATE that is part of a patchset, then all PK and ** modified fields are present in the new.* record. The old.* record ** is currently completely empty. This block shifts the PK fields from ** new.* to old.*, to accommodate the code that reads these arrays. */ for(i=0; inCol; i++){ - assert( p->apValue[i]==0 ); + assert( p->bPatchset==0 || p->apValue[i]==0 ); if( p->abPK[i] ){ + assert( p->apValue[i]==0 ); p->apValue[i] = p->apValue[i+p->nCol]; if( p->apValue[i]==0 ) return (p->rc = SQLITE_CORRUPT_BKPT); p->apValue[i+p->nCol] = 0; } } + }else if( p->bInvert ){ + if( p->op==SQLITE_INSERT ) p->op = SQLITE_DELETE; + else if( p->op==SQLITE_DELETE ) p->op = SQLITE_INSERT; } } @@ -194942,7 +196268,7 @@ static int sessionChangesetInvert( } assert( rc==SQLITE_OK ); - if( xOutput && sOut.nBuf>=SESSIONS_STRM_CHUNK_SIZE ){ + if( xOutput && sOut.nBuf>=sessions_strm_chunk_size ){ rc = xOutput(pOut, sOut.aBuf, sOut.nBuf); sOut.nBuf = 0; if( rc!=SQLITE_OK ) goto finished_invert; @@ -195021,7 +196347,8 @@ struct SessionApplyCtx { int bDeferConstraints; /* True to defer constraints */ SessionBuffer constraints; /* Deferred constraints are stored here */ SessionBuffer rebase; /* Rebase information (if any) here */ - int bRebaseStarted; /* If table header is already in rebase */ + u8 bRebaseStarted; /* If table header is already in rebase */ + u8 bRebase; /* True to collect rebase information */ }; /* @@ -195418,35 +196745,36 @@ static int sessionRebaseAdd( sqlite3_changeset_iter *pIter /* Iterator pointing at current change */ ){ int rc = SQLITE_OK; - int i; - int eOp = pIter->op; - if( p->bRebaseStarted==0 ){ - /* Append a table-header to the rebase buffer */ - const char *zTab = pIter->zTab; - sessionAppendByte(&p->rebase, 'T', &rc); - sessionAppendVarint(&p->rebase, p->nCol, &rc); - sessionAppendBlob(&p->rebase, p->abPK, p->nCol, &rc); - sessionAppendBlob(&p->rebase, (u8*)zTab, (int)strlen(zTab)+1, &rc); - p->bRebaseStarted = 1; - } - - assert( eType==SQLITE_CHANGESET_REPLACE||eType==SQLITE_CHANGESET_OMIT ); - assert( eOp==SQLITE_DELETE || eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE ); - - sessionAppendByte(&p->rebase, - (eOp==SQLITE_DELETE ? SQLITE_DELETE : SQLITE_INSERT), &rc - ); - sessionAppendByte(&p->rebase, (eType==SQLITE_CHANGESET_REPLACE), &rc); - for(i=0; inCol; i++){ - sqlite3_value *pVal = 0; - if( eOp==SQLITE_DELETE || (eOp==SQLITE_UPDATE && p->abPK[i]) ){ - sqlite3changeset_old(pIter, i, &pVal); - }else{ - sqlite3changeset_new(pIter, i, &pVal); + if( p->bRebase ){ + int i; + int eOp = pIter->op; + if( p->bRebaseStarted==0 ){ + /* Append a table-header to the rebase buffer */ + const char *zTab = pIter->zTab; + sessionAppendByte(&p->rebase, 'T', &rc); + sessionAppendVarint(&p->rebase, p->nCol, &rc); + sessionAppendBlob(&p->rebase, p->abPK, p->nCol, &rc); + sessionAppendBlob(&p->rebase, (u8*)zTab, (int)strlen(zTab)+1, &rc); + p->bRebaseStarted = 1; } - sessionAppendValue(&p->rebase, pVal, &rc); - } + assert( eType==SQLITE_CHANGESET_REPLACE||eType==SQLITE_CHANGESET_OMIT ); + assert( eOp==SQLITE_DELETE || eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE ); + + sessionAppendByte(&p->rebase, + (eOp==SQLITE_DELETE ? SQLITE_DELETE : SQLITE_INSERT), &rc + ); + sessionAppendByte(&p->rebase, (eType==SQLITE_CHANGESET_REPLACE), &rc); + for(i=0; inCol; i++){ + sqlite3_value *pVal = 0; + if( eOp==SQLITE_DELETE || (eOp==SQLITE_UPDATE && p->abPK[i]) ){ + sqlite3changeset_old(pIter, i, &pVal); + }else{ + sqlite3changeset_new(pIter, i, &pVal); + } + sessionAppendValue(&p->rebase, pVal, &rc); + } + } return rc; } @@ -195789,7 +197117,7 @@ static int sessionRetryConstraints( SessionBuffer cons = pApply->constraints; memset(&pApply->constraints, 0, sizeof(SessionBuffer)); - rc = sessionChangesetStart(&pIter2, 0, 0, cons.nBuf, cons.aBuf); + rc = sessionChangesetStart(&pIter2, 0, 0, cons.nBuf, cons.aBuf, 0); if( rc==SQLITE_OK ){ int nByte = 2*pApply->nCol*sizeof(sqlite3_value*); int rc2; @@ -195855,6 +197183,7 @@ static int sessionChangesetApply( pIter->in.bNoDiscard = 1; memset(&sApply, 0, sizeof(sApply)); + sApply.bRebase = (ppRebase && pnRebase); sqlite3_mutex_enter(sqlite3_db_mutex(db)); if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); @@ -196005,7 +197334,8 @@ static int sessionChangesetApply( } } - if( rc==SQLITE_OK && bPatchset==0 && ppRebase && pnRebase ){ + assert( sApply.bRebase || sApply.rebase.nBuf==0 ); + if( rc==SQLITE_OK && bPatchset==0 && sApply.bRebase ){ *ppRebase = (void*)sApply.rebase.aBuf; *pnRebase = sApply.rebase.nBuf; sApply.rebase.aBuf = 0; @@ -196043,7 +197373,8 @@ SQLITE_API int sqlite3changeset_apply_v2( int flags ){ sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ - int rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset); + int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); + int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset,bInverse); if( rc==SQLITE_OK ){ rc = sessionChangesetApply( db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags @@ -196100,7 +197431,8 @@ SQLITE_API int sqlite3changeset_apply_v2_strm( int flags ){ sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ - int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn); + int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); + int rc = sessionChangesetStart(&pIter, xInput, pIn, 0, 0, bInverse); if( rc==SQLITE_OK ){ rc = sessionChangesetApply( db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags @@ -196473,13 +197805,12 @@ static int sessionChangegroupOutput( sessionAppendByte(&buf, p->op, &rc); sessionAppendByte(&buf, p->bIndirect, &rc); sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc); + if( rc==SQLITE_OK && xOutput && buf.nBuf>=sessions_strm_chunk_size ){ + rc = xOutput(pOut, buf.aBuf, buf.nBuf); + buf.nBuf = 0; + } } } - - if( rc==SQLITE_OK && xOutput && buf.nBuf>=SESSIONS_STRM_CHUNK_SIZE ){ - rc = xOutput(pOut, buf.aBuf, buf.nBuf); - buf.nBuf = 0; - } } if( rc==SQLITE_OK ){ @@ -196870,7 +198201,7 @@ static int sessionRebase( sessionAppendByte(&sOut, pIter->bIndirect, &rc); sessionAppendBlob(&sOut, aRec, nRec, &rc); } - if( rc==SQLITE_OK && xOutput && sOut.nBuf>SESSIONS_STRM_CHUNK_SIZE ){ + if( rc==SQLITE_OK && xOutput && sOut.nBuf>sessions_strm_chunk_size ){ rc = xOutput(pOut, sOut.aBuf, sOut.nBuf); sOut.nBuf = 0; } @@ -196981,6 +198312,27 @@ SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p){ } } +/* +** Global configuration +*/ +SQLITE_API int sqlite3session_config(int op, void *pArg){ + int rc = SQLITE_OK; + switch( op ){ + case SQLITE_SESSION_CONFIG_STRMSIZE: { + int *pInt = (int*)pArg; + if( *pInt>0 ){ + sessions_strm_chunk_size = *pInt; + } + *pInt = sessions_strm_chunk_size; + break; + } + default: + rc = SQLITE_MISUSE; + break; + } + return rc; +} + #endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */ /************** End of sqlite3session.c **************************************/ @@ -198415,6 +199767,7 @@ static void sqlite3Fts5UnicodeAscii(u8*, u8*); ** input grammar file: */ /* #include */ +/* #include */ /************ Begin %include sections from the grammar ************************/ /* #include "fts5Int.h" */ @@ -199742,10 +201095,9 @@ static void sqlite3Fts5Parser( fts5yymajor = fts5YYNOCODE; }else{ while( fts5yypParser->fts5yytos >= fts5yypParser->fts5yystack - && fts5yymx != fts5YYERRORSYMBOL && (fts5yyact = fts5yy_find_reduce_action( fts5yypParser->fts5yytos->stateno, - fts5YYERRORSYMBOL)) >= fts5YY_MIN_REDUCE + fts5YYERRORSYMBOL)) > fts5YY_MAX_SHIFTREDUCE ){ fts5yy_pop_parser_stack(fts5yypParser); } @@ -210695,7 +212047,7 @@ static int sqlite3Fts5IndexQuery( fts5CloseReader(p); } - *ppIter = &pRet->base; + *ppIter = (Fts5IndexIter*)pRet; sqlite3Fts5BufferFree(&buf); } return fts5IndexReturn(p); @@ -214444,12 +215796,27 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2018-09-25 19:08:10 fb90e7189ae6d62e77ba3a308ca5d683f90bbe633cf681865365b8e92792d1c7", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9", -1, SQLITE_TRANSIENT); +} + +/* +** Return true if zName is the extension on one of the shadow tables used +** by this module. +*/ +static int fts5ShadowName(const char *zName){ + static const char *azName[] = { + "config", "content", "data", "docsize", "idx" + }; + unsigned int i; + for(i=0; iiInstPos; int *po = &pCsr->iInstOff; + assert( sqlite3Fts5IterEof(pIter)==0 ); + assert( pCsr->bEof==0 ); while( eDetail==FTS5_DETAIL_NONE || sqlite3Fts5PoslistNext64(pIter->pData, pIter->nData, po, pp) ){ @@ -218525,7 +219895,7 @@ static int fts5VocabInstanceNext(Fts5VocabCursor *pCsr){ rc = sqlite3Fts5IterNextScan(pCsr->pIter); if( rc==SQLITE_OK ){ rc = fts5VocabInstanceNewTerm(pCsr); - if( eDetail==FTS5_DETAIL_NONE ) break; + if( pCsr->bEof || eDetail==FTS5_DETAIL_NONE ) break; } if( rc ){ pCsr->bEof = 1; @@ -218840,6 +220210,7 @@ static int sqlite3Fts5VocabInit(Fts5Global *pGlobal, sqlite3 *db){ /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ 0, + /* xShadowName */ 0 }; void *p = (void*)pGlobal; @@ -218847,8 +220218,6 @@ static int sqlite3Fts5VocabInit(Fts5Global *pGlobal, sqlite3 *db){ } - - #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) */ @@ -219122,6 +220491,7 @@ static sqlite3_module stmtModule = { 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ + 0, /* xShadowName */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -219154,9 +220524,9 @@ SQLITE_API int sqlite3_stmt_init( #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */ /************** End of stmt.c ************************************************/ -#if __LINE__!=219157 +#if __LINE__!=220527 #undef SQLITE_SOURCE_ID -#define SQLITE_SOURCE_ID "2018-09-25 19:08:10 fb90e7189ae6d62e77ba3a308ca5d683f90bbe633cf681865365b8e92792alt2" +#define SQLITE_SOURCE_ID "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238alt2" #endif /* Return the source-id for this library */ SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } diff --git a/src/3rdparty/sqlite/sqlite3.h b/src/3rdparty/sqlite/sqlite3.h index 4612ecda7f..f36ae57a64 100644 --- a/src/3rdparty/sqlite/sqlite3.h +++ b/src/3rdparty/sqlite/sqlite3.h @@ -123,9 +123,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.25.2" -#define SQLITE_VERSION_NUMBER 3025002 -#define SQLITE_SOURCE_ID "2018-09-25 19:08:10 fb90e7189ae6d62e77ba3a308ca5d683f90bbe633cf681865365b8e92792d1c7" +#define SQLITE_VERSION "3.26.0" +#define SQLITE_VERSION_NUMBER 3026000 +#define SQLITE_SOURCE_ID "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -2017,6 +2017,7 @@ struct sqlite3_mem_methods { ** is invoked. ** **
    +** [[SQLITE_DBCONFIG_LOOKASIDE]] **
    SQLITE_DBCONFIG_LOOKASIDE
    **
    ^This option takes three additional arguments that determine the ** [lookaside memory allocator] configuration for the [database connection]. @@ -2039,6 +2040,7 @@ struct sqlite3_mem_methods { ** memory is in use leaves the configuration unchanged and returns ** [SQLITE_BUSY].)^
    ** +** [[SQLITE_DBCONFIG_ENABLE_FKEY]] **
    SQLITE_DBCONFIG_ENABLE_FKEY
    **
    ^This option is used to enable or disable the enforcement of ** [foreign key constraints]. There should be two additional arguments. @@ -2049,6 +2051,7 @@ struct sqlite3_mem_methods { ** following this call. The second parameter may be a NULL pointer, in ** which case the FK enforcement setting is not reported back.
    ** +** [[SQLITE_DBCONFIG_ENABLE_TRIGGER]] **
    SQLITE_DBCONFIG_ENABLE_TRIGGER
    **
    ^This option is used to enable or disable [CREATE TRIGGER | triggers]. ** There should be two additional arguments. @@ -2059,6 +2062,7 @@ struct sqlite3_mem_methods { ** following this call. The second parameter may be a NULL pointer, in ** which case the trigger setting is not reported back.
    ** +** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]] **
    SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER
    **
    ^This option is used to enable or disable the two-argument ** version of the [fts3_tokenizer()] function which is part of the @@ -2072,6 +2076,7 @@ struct sqlite3_mem_methods { ** following this call. The second parameter may be a NULL pointer, in ** which case the new setting is not reported back.
    ** +** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]] **
    SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION
    **
    ^This option is used to enable or disable the [sqlite3_load_extension()] ** interface independently of the [load_extension()] SQL function. @@ -2089,7 +2094,7 @@ struct sqlite3_mem_methods { ** be a NULL pointer, in which case the new setting is not reported back. **
    ** -**
    SQLITE_DBCONFIG_MAINDBNAME
    +** [[SQLITE_DBCONFIG_MAINDBNAME]]
    SQLITE_DBCONFIG_MAINDBNAME
    **
    ^This option is used to change the name of the "main" database ** schema. ^The sole argument is a pointer to a constant UTF8 string ** which will become the new schema name in place of "main". ^SQLite @@ -2098,6 +2103,7 @@ struct sqlite3_mem_methods { ** until after the database connection closes. **
    ** +** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]] **
    SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE
    **
    Usually, when a database in wal mode is closed or detached from a ** database handle, SQLite checks if this will mean that there are now no @@ -2111,7 +2117,7 @@ struct sqlite3_mem_methods { ** have been disabled - 0 if they are not disabled, 1 if they are. **
    ** -**
    SQLITE_DBCONFIG_ENABLE_QPSG
    +** [[SQLITE_DBCONFIG_ENABLE_QPSG]]
    SQLITE_DBCONFIG_ENABLE_QPSG
    **
    ^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates ** the [query planner stability guarantee] (QPSG). When the QPSG is active, ** a single SQL query statement will always use the same algorithm regardless @@ -2127,7 +2133,7 @@ struct sqlite3_mem_methods { ** following this call. **
    ** -**
    SQLITE_DBCONFIG_TRIGGER_EQP
    +** [[SQLITE_DBCONFIG_TRIGGER_EQP]]
    SQLITE_DBCONFIG_TRIGGER_EQP
    **
    By default, the output of EXPLAIN QUERY PLAN commands does not ** include output for any operations performed by trigger programs. This ** option is used to set or clear (the default) a flag that governs this @@ -2139,7 +2145,7 @@ struct sqlite3_mem_methods { ** it is not disabled, 1 if it is. **
    ** -**
    SQLITE_DBCONFIG_RESET_DATABASE
    +** [[SQLITE_DBCONFIG_RESET_DATABASE]]
    SQLITE_DBCONFIG_RESET_DATABASE
    **
    Set the SQLITE_DBCONFIG_RESET_DATABASE flag and then run ** [VACUUM] in order to reset a database back to an empty database ** with no schema and no content. The following process works even for @@ -2158,6 +2164,18 @@ struct sqlite3_mem_methods { ** Because resetting a database is destructive and irreversible, the ** process requires the use of this obscure API and multiple steps to help ** ensure that it does not happen by accident. +** +** [[SQLITE_DBCONFIG_DEFENSIVE]]
    SQLITE_DBCONFIG_DEFENSIVE
    +**
    The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the +** "defensive" flag for a database connection. When the defensive +** flag is enabled, language features that allow ordinary SQL to +** deliberately corrupt the database file are disabled. The disabled +** features include but are not limited to the following: +**
      +**
    • The [PRAGMA writable_schema=ON] statement. +**
    • Writes to the [sqlite_dbpage] virtual table. +**
    • Direct writes to [shadow tables]. +**
    **
    **
    */ @@ -2171,7 +2189,8 @@ struct sqlite3_mem_methods { #define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */ #define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */ #define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */ -#define SQLITE_DBCONFIG_MAX 1009 /* Largest DBCONFIG */ +#define SQLITE_DBCONFIG_DEFENSIVE 1010 /* int int* */ +#define SQLITE_DBCONFIG_MAX 1010 /* Largest DBCONFIG */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes @@ -3609,9 +3628,19 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** on this hint by avoiding the use of [lookaside memory] so as not to ** deplete the limited store of lookaside memory. Future versions of ** SQLite may act on this hint differently. +** +** [[SQLITE_PREPARE_NORMALIZE]] ^(
    SQLITE_PREPARE_NORMALIZE
    +**
    The SQLITE_PREPARE_NORMALIZE flag indicates that a normalized +** representation of the SQL statement should be calculated and then +** associated with the prepared statement, which can be obtained via +** the [sqlite3_normalized_sql()] interface.)^ The semantics used to +** normalize a SQL statement are unspecified and subject to change. +** At a minimum, literal values will be replaced with suitable +** placeholders. **
    */ #define SQLITE_PREPARE_PERSISTENT 0x01 +#define SQLITE_PREPARE_NORMALIZE 0x02 /* ** CAPI3REF: Compiling An SQL Statement @@ -3769,6 +3798,11 @@ SQLITE_API int sqlite3_prepare16_v3( ** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8 ** string containing the SQL text of prepared statement P with ** [bound parameters] expanded. +** ^The sqlite3_normalized_sql(P) interface returns a pointer to a UTF-8 +** string containing the normalized SQL text of prepared statement P. The +** semantics used to normalize a SQL statement are unspecified and subject +** to change. At a minimum, literal values will be replaced with suitable +** placeholders. ** ** ^(For example, if a prepared statement is created using the SQL ** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345 @@ -3784,14 +3818,16 @@ SQLITE_API int sqlite3_prepare16_v3( ** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time ** option causes sqlite3_expanded_sql() to always return NULL. ** -** ^The string returned by sqlite3_sql(P) is managed by SQLite and is -** automatically freed when the prepared statement is finalized. +** ^The strings returned by sqlite3_sql(P) and sqlite3_normalized_sql(P) +** are managed by SQLite and are automatically freed when the prepared +** statement is finalized. ** ^The string returned by sqlite3_expanded_sql(P), on the other hand, ** is obtained from [sqlite3_malloc()] and must be free by the application ** by passing it to [sqlite3_free()]. */ SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt); SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt); +SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt); /* ** CAPI3REF: Determine If An SQL Statement Writes The Database @@ -6281,6 +6317,9 @@ struct sqlite3_module { int (*xSavepoint)(sqlite3_vtab *pVTab, int); int (*xRelease)(sqlite3_vtab *pVTab, int); int (*xRollbackTo)(sqlite3_vtab *pVTab, int); + /* The methods above are in versions 1 and 2 of the sqlite_module object. + ** Those below are for version 3 and greater. */ + int (*xShadowName)(const char*); }; /* @@ -7203,6 +7242,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ +#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */ #define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19 @@ -8615,6 +8655,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); ** can use to customize and optimize their behavior. ** **
    +** [[SQLITE_VTAB_CONSTRAINT_SUPPORT]] **
    SQLITE_VTAB_CONSTRAINT_SUPPORT **
    Calls of the form ** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported, @@ -9384,7 +9425,7 @@ struct sqlite3_rtree_query_info { sqlite3_int64 iRowid; /* Rowid for current entry */ sqlite3_rtree_dbl rParentScore; /* Score of parent node */ int eParentWithin; /* Visibility of parent node */ - int eWithin; /* OUT: Visiblity */ + int eWithin; /* OUT: Visibility */ sqlite3_rtree_dbl rScore; /* OUT: Write the score here */ /* The following fields are only available in 3.8.11 and later */ sqlite3_value **apSqlParam; /* Original SQL values of parameters */ @@ -9880,12 +9921,38 @@ SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession); ** consecutively. There is no chance that the iterator will visit a change ** the applies to table X, then one for table Y, and then later on visit ** another change for table X. +** +** The behavior of sqlite3changeset_start_v2() and its streaming equivalent +** may be modified by passing a combination of +** [SQLITE_CHANGESETSTART_INVERT | supported flags] as the 4th parameter. +** +** Note that the sqlite3changeset_start_v2() API is still experimental +** and therefore subject to change. */ SQLITE_API int sqlite3changeset_start( sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */ int nChangeset, /* Size of changeset blob in bytes */ void *pChangeset /* Pointer to blob containing changeset */ ); +SQLITE_API int sqlite3changeset_start_v2( + sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */ + int nChangeset, /* Size of changeset blob in bytes */ + void *pChangeset, /* Pointer to blob containing changeset */ + int flags /* SESSION_CHANGESETSTART_* flags */ +); + +/* +** CAPI3REF: Flags for sqlite3changeset_start_v2 +** +** The following flags may passed via the 4th parameter to +** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]: +** +**
    SQLITE_CHANGESETAPPLY_INVERT
    +** Invert the changeset while iterating through it. This is equivalent to +** inverting a changeset using sqlite3changeset_invert() before applying it. +** It is an error to specify this flag with a patchset. +*/ +#define SQLITE_CHANGESETSTART_INVERT 0x0002 /* @@ -10540,7 +10607,7 @@ SQLITE_API int sqlite3changeset_apply_v2( ), void *pCtx, /* First argument passed to xConflict */ void **ppRebase, int *pnRebase, /* OUT: Rebase data */ - int flags /* Combination of SESSION_APPLY_* flags */ + int flags /* SESSION_CHANGESETAPPLY_* flags */ ); /* @@ -10558,8 +10625,14 @@ SQLITE_API int sqlite3changeset_apply_v2( ** causes the sessions module to omit this savepoint. In this case, if the ** caller has an open transaction or savepoint when apply_v2() is called, ** it may revert the partially applied changeset by rolling it back. +** +**
    SQLITE_CHANGESETAPPLY_INVERT
    +** Invert the changeset before applying it. This is equivalent to inverting +** a changeset using sqlite3changeset_invert() before applying it. It is +** an error to specify this flag with a patchset. */ #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001 +#define SQLITE_CHANGESETAPPLY_INVERT 0x0002 /* ** CAPI3REF: Constants Passed To The Conflict Handler @@ -10953,6 +11026,12 @@ SQLITE_API int sqlite3changeset_start_strm( int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn ); +SQLITE_API int sqlite3changeset_start_v2_strm( + sqlite3_changeset_iter **pp, + int (*xInput)(void *pIn, void *pData, int *pnData), + void *pIn, + int flags +); SQLITE_API int sqlite3session_changeset_strm( sqlite3_session *pSession, int (*xOutput)(void *pOut, const void *pData, int nData), @@ -10979,6 +11058,45 @@ SQLITE_API int sqlite3rebaser_rebase_strm( void *pOut ); +/* +** CAPI3REF: Configure global parameters +** +** The sqlite3session_config() interface is used to make global configuration +** changes to the sessions module in order to tune it to the specific needs +** of the application. +** +** The sqlite3session_config() interface is not threadsafe. If it is invoked +** while any other thread is inside any other sessions method then the +** results are undefined. Furthermore, if it is invoked after any sessions +** related objects have been created, the results are also undefined. +** +** The first argument to the sqlite3session_config() function must be one +** of the SQLITE_SESSION_CONFIG_XXX constants defined below. The +** interpretation of the (void*) value passed as the second parameter and +** the effect of calling this function depends on the value of the first +** parameter. +** +**
    +**
    SQLITE_SESSION_CONFIG_STRMSIZE
    +** By default, the sessions module streaming interfaces attempt to input +** and output data in approximately 1 KiB chunks. This operand may be used +** to set and query the value of this configuration setting. The pointer +** passed as the second argument must point to a value of type (int). +** If this value is greater than 0, it is used as the new streaming data +** chunk size for both input and output. Before returning, the (int) value +** pointed to by pArg is set to the final value of the streaming interface +** chunk size. +**
    +** +** This function returns SQLITE_OK if successful, or an SQLite error code +** otherwise. +*/ +SQLITE_API int sqlite3session_config(int op, void *pArg); + +/* +** CAPI3REF: Values for sqlite3session_config(). +*/ +#define SQLITE_SESSION_CONFIG_STRMSIZE 1 /* ** Make sure we can call this stuff from C++. From 71b2de1f1d041ac3a7c932d02b6860c450d7c924 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 14 Dec 2018 09:14:19 +0100 Subject: [PATCH 0689/1650] Windows: Use the ptPaperSize information to set the paper size In some cases the DEVMODE structure is not updated with the selected paper size, whereas the ptPaperSize structure is always set to the right paper size. Therefore we set the page size on the printer to this after the page dialog is shown. Change-Id: Ieafd486232aca6e930f73a8131b7196ddecea305 Reviewed-by: Friedemann Kleint --- src/printsupport/dialogs/qpagesetupdialog_win.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/printsupport/dialogs/qpagesetupdialog_win.cpp b/src/printsupport/dialogs/qpagesetupdialog_win.cpp index 23fff82f25..464381bbe4 100644 --- a/src/printsupport/dialogs/qpagesetupdialog_win.cpp +++ b/src/printsupport/dialogs/qpagesetupdialog_win.cpp @@ -134,6 +134,8 @@ int QPageSetupDialog::exec() QDialog::setVisible(false); if (result) { engine->setGlobalDevMode(psd.hDevNames, psd.hDevMode); + d->printer->setPageSize(QPageSize(QSizeF(psd.ptPaperSize.x / multiplier, psd.ptPaperSize.y / multiplier), + layout.units() == QPageLayout::Inch ? QPageSize::Inch : QPageSize::Millimeter)); const QMarginsF margins(psd.rtMargin.left, psd.rtMargin.top, psd.rtMargin.right, psd.rtMargin.bottom); d->printer->setPageMargins(margins / multiplier, layout.units()); From 1fbd8caca6423622047512fa881817ae7cf55522 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 13 Sep 2018 14:38:11 -0700 Subject: [PATCH 0690/1650] Merge some code to simplify maintenance Change-Id: I8f261579aad648fdb4f0fffd15541369e3625461 Reviewed-by: Samuel Gaist Reviewed-by: Thiago Macieira --- src/corelib/tools/qstring.cpp | 89 +++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 40 deletions(-) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index d20c46774d..380ea408d3 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -265,29 +265,32 @@ const ushort *QtPrivate::qustrchr(QStringView str, ushort c) noexcept const ushort *e = reinterpret_cast(str.end()); #ifdef __SSE2__ + // Using the PMOVMSKB instruction, we get two bits for each character + // we compare. __m128i mch = _mm_set1_epi32(c | (c << 16)); + auto hasMatch = [mch, &n](__m128i data, ushort validityMask) { + __m128i result = _mm_cmpeq_epi16(data, mch); + uint mask = uint(_mm_movemask_epi8(result)); + if ((mask & validityMask) == 0) + return false; + uint idx = qCountTrailingZeroBits(mask); + n += idx / 2; + return true; + }; // we're going to read n[0..7] (16 bytes) for (const ushort *next = n + 8; next <= e; n = next, next += 8) { __m128i data = _mm_loadu_si128(reinterpret_cast(n)); - __m128i result = _mm_cmpeq_epi16(data, mch); - uint mask = _mm_movemask_epi8(result); - if (ushort(mask)) { - // found a match - return n + (qCountTrailingZeroBits(mask) >> 1); - } + if (hasMatch(data, 0xffff)) + return n; } # if !defined(__OPTIMIZE_SIZE__) // we're going to read n[0..3] (8 bytes) if (e - n > 3) { __m128i data = _mm_loadl_epi64(reinterpret_cast(n)); - __m128i result = _mm_cmpeq_epi16(data, mch); - uint mask = _mm_movemask_epi8(result); - if (uchar(mask)) { - // found a match - return n + (qCountTrailingZeroBits(mask) >> 1); - } + if (hasMatch(data, 0xff)) + return n; n += 4; } @@ -874,6 +877,19 @@ static int ucstrncmp(const QChar *a, const QChar *b, size_t l) const QChar *end = a + l; qptrdiff offset = 0; + // Using the PMOVMSKB instruction, we get two bits for each character + // we compare. + int retval; + auto isDifferent = [a, b, &offset, &retval](__m128i a_data, __m128i b_data) { + __m128i result = _mm_cmpeq_epi16(a_data, b_data); + uint mask = ~uint(_mm_movemask_epi8(result)); + if (ushort(mask) == 0) + return false; + uint idx = qCountTrailingZeroBits(mask); + retval = a[offset + idx / 2].unicode() - b[offset + idx / 2].unicode(); + return true; + }; + // we're going to read a[0..15] and b[0..15] (32 bytes) for ( ; a + offset + 16 <= end; offset += 16) { #ifdef __AVX2__ @@ -902,13 +918,8 @@ static int ucstrncmp(const QChar *a, const QChar *b, size_t l) if (a + offset + 8 <= end) { __m128i a_data = _mm_loadu_si128(reinterpret_cast(a + offset)); __m128i b_data = _mm_loadu_si128(reinterpret_cast(b + offset)); - __m128i result = _mm_cmpeq_epi16(a_data, b_data); - uint mask = ~_mm_movemask_epi8(result); - if (ushort(mask)) { - // found a different character - uint idx = qCountTrailingZeroBits(mask); - return a[offset + idx / 2].unicode() - b[offset + idx / 2].unicode(); - } + if (isDifferent(a_data, b_data)) + return retval; offset += 8; } @@ -917,13 +928,8 @@ static int ucstrncmp(const QChar *a, const QChar *b, size_t l) if (a + offset + 4 <= end) { __m128i a_data = _mm_loadl_epi64(reinterpret_cast(a + offset)); __m128i b_data = _mm_loadl_epi64(reinterpret_cast(b + offset)); - __m128i result = _mm_cmpeq_epi16(a_data, b_data); - uint mask = ~_mm_movemask_epi8(result); - if (uchar(mask)) { - // found a different character - uint idx = qCountTrailingZeroBits(mask); - return a[offset + idx / 2].unicode() - b[offset + idx / 2].unicode(); - } + if (isDifferent(a_data, b_data)) + return retval; offset += 4; } @@ -1018,6 +1024,19 @@ static int ucstrncmp(const QChar *a, const uchar *c, size_t l) __m128i nullmask = _mm_setzero_si128(); qptrdiff offset = 0; + // Using the PMOVMSKB instruction, we get two bits for each character + // we compare. + int retval; + auto isDifferent = [uc, c, &offset, &retval](__m128i a_data, __m128i b_data) { + __m128i result = _mm_cmpeq_epi16(a_data, b_data); + uint mask = ~uint(_mm_movemask_epi8(result)); + if (ushort(mask) == 0) + return false; + uint idx = qCountTrailingZeroBits(mask); + retval = uc[offset + idx / 2] - c[offset + idx / 2]; + return true; + }; + // we're going to read uc[offset..offset+15] (32 bytes) // and c[offset..offset+15] (16 bytes) for ( ; uc + offset + 15 < e; offset += 16) { @@ -1061,13 +1080,8 @@ static int ucstrncmp(const QChar *a, const uchar *c, size_t l) __m128i secondHalf = mm_load8_zero_extend(c + offset); __m128i ucdata = _mm_loadu_si128((const __m128i*)(uc + offset)); - __m128i result = _mm_cmpeq_epi16(secondHalf, ucdata); - uint mask = ~_mm_movemask_epi8(result); - if (ushort(mask)) { - // found a different character - uint idx = qCountTrailingZeroBits(mask); - return uc[offset + idx / 2] - c[offset + idx / 2]; - } + if (isDifferent(ucdata, secondHalf)) + return retval; // still matched offset += 8; @@ -1080,13 +1094,8 @@ static int ucstrncmp(const QChar *a, const uchar *c, size_t l) __m128i secondHalf = _mm_unpacklo_epi8(chunk, nullmask); __m128i ucdata = _mm_loadl_epi64(reinterpret_cast(uc + offset)); - __m128i result = _mm_cmpeq_epi8(secondHalf, ucdata); - uint mask = ~_mm_movemask_epi8(result); - if (uchar(mask)) { - // found a different character - uint idx = qCountTrailingZeroBits(mask); - return uc[offset + idx / 2] - c[offset + idx / 2]; - } + if (isDifferent(ucdata, secondHalf)) + return retval; // still matched offset += 4; From 482da2e4d2376767172a9a014321822e90fa6096 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 13 Sep 2018 14:24:24 -0700 Subject: [PATCH 0691/1650] Add an AVX2 code path to qustrchr The new loop does 32 bytes (16 code units) at a time Change-Id: I8f261579aad648fdb4f0fffd155412a4d77428e9 Reviewed-by: Allan Sandfeld Jensen --- src/corelib/tools/qstring.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 380ea408d3..d50a28abc5 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -265,9 +265,27 @@ const ushort *QtPrivate::qustrchr(QStringView str, ushort c) noexcept const ushort *e = reinterpret_cast(str.end()); #ifdef __SSE2__ + bool loops = true; // Using the PMOVMSKB instruction, we get two bits for each character // we compare. +# if defined(__AVX2__) && !defined(__OPTIMIZE_SIZE__) + // we're going to read n[0..15] (32 bytes) + __m256i mch256 = _mm256_set1_epi32(c | (c << 16)); + for (const ushort *next = n + 16; next <= e; n = next, next += 16) { + __m256i data = _mm256_loadu_si256(reinterpret_cast(n)); + __m256i result = _mm256_cmpeq_epi16(data, mch256); + uint mask = uint(_mm256_movemask_epi8(result)); + if (mask) { + uint idx = qCountTrailingZeroBits(mask); + return n + idx / 2; + } + } + loops = false; + __m128i mch = _mm256_castsi256_si128(mch256); +# else __m128i mch = _mm_set1_epi32(c | (c << 16)); +# endif + auto hasMatch = [mch, &n](__m128i data, ushort validityMask) { __m128i result = _mm_cmpeq_epi16(data, mch); uint mask = uint(_mm_movemask_epi8(result)); @@ -283,6 +301,11 @@ const ushort *QtPrivate::qustrchr(QStringView str, ushort c) noexcept __m128i data = _mm_loadu_si128(reinterpret_cast(n)); if (hasMatch(data, 0xffff)) return n; + + if (!loops) { + n += 8; + break; + } } # if !defined(__OPTIMIZE_SIZE__) From c41c5159d7d7688d61bdd1b013278302bb0116fb Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 16 Dec 2018 11:02:58 -0800 Subject: [PATCH 0692/1650] Doc: mark QMetaObject::invokeMethod overloads as threadsafe Fixes: QTBUG-72599 Change-Id: I61ce366d57bc46c89db5fffd1570e578a7979749 Reviewed-by: Giuseppe D'Angelo Reviewed-by: Paul Wicking --- src/corelib/kernel/qmetaobject.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index c642cd07f2..5de2717078 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -1381,6 +1381,8 @@ static inline QByteArray findMethodCandidates(const QMetaObject *metaObject, con } /*! + \threadsafe + Invokes the \a member (a signal or a slot name) on the object \a obj. Returns \c true if the member could be invoked. Returns \c false if there is no such member or the parameters did not match. @@ -1570,6 +1572,7 @@ bool QMetaObject::invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase * QGenericArgument val7 = QGenericArgument(), QGenericArgument val8 = QGenericArgument(), QGenericArgument val9 = QGenericArgument()); + \threadsafe \overload invokeMethod() This overload always invokes the member using the connection type Qt::AutoConnection. @@ -1588,6 +1591,7 @@ bool QMetaObject::invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase * QGenericArgument val8 = QGenericArgument(), QGenericArgument val9 = QGenericArgument()) + \threadsafe \overload invokeMethod() This overload can be used if the return value of the member is of no interest. @@ -1606,6 +1610,7 @@ bool QMetaObject::invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase * QGenericArgument val8 = QGenericArgument(), QGenericArgument val9 = QGenericArgument()) + \threadsafe \overload invokeMethod() This overload invokes the member using the connection type Qt::AutoConnection and @@ -1617,6 +1622,7 @@ bool QMetaObject::invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase * \since 5.10 + \threadsafe \overload Invokes the \a function in the event loop of \a context. \a function can be a functor @@ -1630,6 +1636,7 @@ bool QMetaObject::invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase * \since 5.10 + \threadsafe \overload Invokes the \a function in the event loop of \a context using the connection type Qt::AutoConnection. From 1387f1910bde3743dc181bac9d92e86fb64691ef Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Thu, 13 Dec 2018 20:48:49 +1000 Subject: [PATCH 0693/1650] wasm: emit finished after QNetworkReply abort MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I23445f5e0c936b82aa5d65b261d456a563deab9a Fixes: QTBUG-72516 Reviewed-by: Morten Johan Sørvig --- src/network/access/qnetworkreplywasmimpl.cpp | 31 +++++++++++++------- src/network/access/qnetworkreplywasmimpl_p.h | 4 +++ 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/network/access/qnetworkreplywasmimpl.cpp b/src/network/access/qnetworkreplywasmimpl.cpp index e8ca4d4084..3bfe927c9f 100644 --- a/src/network/access/qnetworkreplywasmimpl.cpp +++ b/src/network/access/qnetworkreplywasmimpl.cpp @@ -222,11 +222,17 @@ QByteArray QNetworkReplyWasmImpl::methodName() const void QNetworkReplyWasmImpl::close() { + setFinished(true); + emit finished(); + QNetworkReply::close(); } void QNetworkReplyWasmImpl::abort() { + Q_D(const QNetworkReplyWasmImpl); + d->doAbort(); + close(); } @@ -307,24 +313,29 @@ void QNetworkReplyWasmImplPrivate::setReplyAttributes(quintptr data, int statusC handler->q_func()->setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, statusReason); } +void QNetworkReplyWasmImplPrivate::doAbort() const +{ + m_xhr.call("abort"); +} + void QNetworkReplyWasmImplPrivate::doSendRequest() { Q_Q(QNetworkReplyWasmImpl); totalDownloadSize = 0; - val xhr = val::global("XMLHttpRequest").new_(); + m_xhr = val::global("XMLHttpRequest").new_(); std::string verb = q->methodName().toStdString(); QString extraDataString; - xhr.call("open", verb, request.url().toString().toStdString()); + m_xhr.call("open", verb, request.url().toString().toStdString()); - xhr.set("onerror", val::module_property("QNetworkReplyWasmImplPrivate_requestErrorCallback")); - xhr.set("onload", val::module_property("QNetworkReplyWasmImplPrivate_loadCallback")); - xhr.set("onprogress", val::module_property("QNetworkReplyWasmImplPrivate_progressCallback")); - xhr.set("onreadystatechange", val::module_property("QNetworkReplyWasmImplPrivate_responseHeadersCallback")); + m_xhr.set("onerror", val::module_property("QNetworkReplyWasmImplPrivate_requestErrorCallback")); + m_xhr.set("onload", val::module_property("QNetworkReplyWasmImplPrivate_loadCallback")); + m_xhr.set("onprogress", val::module_property("QNetworkReplyWasmImplPrivate_progressCallback")); + m_xhr.set("onreadystatechange", val::module_property("QNetworkReplyWasmImplPrivate_responseHeadersCallback")); - xhr.set("data-handler", val(quintptr(reinterpret_cast(this)))); + m_xhr.set("data-handler", val(quintptr(reinterpret_cast(this)))); QByteArray contentType = request.rawHeader("Content-Type"); @@ -343,7 +354,7 @@ void QNetworkReplyWasmImplPrivate::doSendRequest() } if (contentType.contains("json")) { if (!extraDataString.isEmpty()) { - xhr.set("responseType", val("json")); + m_xhr.set("responseType", val("json")); dataToSend = val(extraDataString.toStdString()); } } @@ -360,9 +371,9 @@ void QNetworkReplyWasmImplPrivate::doSendRequest() } // set request headers for (auto header : request.rawHeaderList()) { - xhr.call("setRequestHeader", header.toStdString(), request.rawHeader(header).toStdString()); + m_xhr.call("setRequestHeader", header.toStdString(), request.rawHeader(header).toStdString()); } - xhr.call("send", dataToSend); + m_xhr.call("send", dataToSend); } void QNetworkReplyWasmImplPrivate::emitReplyError(QNetworkReply::NetworkError errorCode, const QString &errorString) diff --git a/src/network/access/qnetworkreplywasmimpl_p.h b/src/network/access/qnetworkreplywasmimpl_p.h index 69c90de41a..e1e6bf4e24 100644 --- a/src/network/access/qnetworkreplywasmimpl_p.h +++ b/src/network/access/qnetworkreplywasmimpl_p.h @@ -62,6 +62,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -134,6 +135,9 @@ public: QIODevice *outgoingData; QSharedPointer outgoingDataBuffer; + emscripten::val m_xhr = emscripten::val::null(); + void doAbort() const; + static QNetworkReply::NetworkError statusCodeFromHttp(int httpStatusCode, const QUrl &url); Q_DECLARE_PUBLIC(QNetworkReplyWasmImpl) }; From 16aae58e2a5cc324b869568f6fb9cc4bedbc96d9 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 18 Dec 2018 08:38:43 -0800 Subject: [PATCH 0694/1650] Fix build with Clang 3.8 Commit 128a6eec065dfe683e6d776183d63908ca02e8fb replaced the static, unsorted list with a sorting implementation via templates. qmakearray_p.h:109:8: fatal error: recursive template instantiation exceeded maximum depth of 256 qmakearray_p.h:111:39: note: during template argument deduction for class template partial specialization 'QuickSortFilter >' [with Predicate = LessThan, Head = Xkb2Qt<269025163, 16777462>, Tail = ...] Fixes: QTBUG-72579 Change-Id: I548dbfddb69b4fd6a0a3fffd15717ac2bf2d7361 Reviewed-by: Gatis Paeglis Reviewed-by: Mikhail Svetkin --- src/plugins/platforms/xcb/xcb_qpa_lib.pro | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro index 9883617ab6..50b7f7f97d 100644 --- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro +++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro @@ -110,4 +110,8 @@ qtConfig(xkb) { qtConfig(dlopen): QMAKE_USE += libdl +# qxcbkeyboard.cpp's KeyTbl has more than 256 levels of expansion and older +# Clang uses that as a limit (it's 1024 in current versions). +clang:!intel_icc: QMAKE_CXXFLAGS += -ftemplate-depth=1024 + load(qt_module) From 91d98321d361b4304265e09dba227df9fdc78393 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 14 Dec 2018 20:20:56 +0100 Subject: [PATCH 0695/1650] qmake: move QT_BEGIN_NAMESPACE to correct place this makes no difference whatsoever, because qmake isn't actually built in a namespace, but it makes the new qtc code model happy. Change-Id: I70ad8e16cceff73276a821219fc80bab365954b5 Reviewed-by: Joerg Bornemann --- qmake/generators/win32/registry_p.h | 4 ++-- qmake/qmake_pch.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/qmake/generators/win32/registry_p.h b/qmake/generators/win32/registry_p.h index 3526dffd45..f9e8bba016 100644 --- a/qmake/generators/win32/registry_p.h +++ b/qmake/generators/win32/registry_p.h @@ -40,8 +40,6 @@ // We mean it. // -QT_BEGIN_NAMESPACE - #include #ifdef Q_OS_WIN32 @@ -52,6 +50,8 @@ QT_BEGIN_NAMESPACE #include +QT_BEGIN_NAMESPACE + /** * Read a value from the Windows registry. * diff --git a/qmake/qmake_pch.h b/qmake/qmake_pch.h index c0f62b263d..c97c872311 100644 --- a/qmake/qmake_pch.h +++ b/qmake/qmake_pch.h @@ -54,10 +54,10 @@ #include #include -QT_BEGIN_NAMESPACE //#include //#include "option.h" +QT_BEGIN_NAMESPACE QT_END_NAMESPACE #endif From 32aa6734d445e1eed38e55ee03af4267ab6cd2c7 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 14 Dec 2018 17:49:43 +0100 Subject: [PATCH 0696/1650] configure: add support for multiple libdirs in inline library sources while the command line doesn't actually permit it (that can be re-evaluated separately), derivatives of the inline source type may want to inject additional paths, as is the case with opcua. the incdir field supports multiple entries without additional action. Change-Id: I3860ca1fc8fab25c04eb63bdb2f855b77ff3b9a4 Reviewed-by: Rainer Keller Reviewed-by: Oswald Buddenhagen Reviewed-by: Joerg Bornemann --- mkspecs/features/qt_configure.prf | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index fe14ea1f40..5798a8a27b 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -707,8 +707,12 @@ defineTest(qtConfLibrary_inline) { } libdir = $$eval(config.input.$${input}.libdir) - !isEmpty(libdir): \ - $${1}.libs = -L$$libdir $$eval($${1}.libs) + !isEmpty(libdir) { + libs = + for (ld, libdir): \ + libs += -L$$ld + $${1}.libs = $$libs $$eval($${1}.libs) + } !qtConfResolveAllLibs($$1): \ return(false) From a8207699ce282cdcaa9423374fdad20a63897d25 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 24 Nov 2017 19:48:33 +0100 Subject: [PATCH 0697/1650] configure: normalize dashes to underscores in exported libraries it works without it, but technically speaking it's undefined behavior. Change-Id: Icdcdd5b923ce4cecd9dc9e75f9d5d66d0fa8a032 Reviewed-by: Joerg Bornemann --- mkspecs/features/qmake_use.prf | 6 +++--- mkspecs/features/qt_configure.prf | 16 ++++++++-------- mkspecs/features/qt_helper_lib.prf | 3 ++- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/mkspecs/features/qmake_use.prf b/mkspecs/features/qmake_use.prf index 8159e471a2..64faa4f215 100644 --- a/mkspecs/features/qmake_use.prf +++ b/mkspecs/features/qmake_use.prf @@ -5,14 +5,14 @@ for(ever) { for (use, QMAKE_USE$${suffix}) { use = $$split(use, /) name = $$take_first(use) - nu = $$upper($$name) + nu = $$upper($$replace(name, -, _)) !contains(use, linkonly): CC_USES += $$nu !contains(use, nolink): LD_USES += $$nu } CC_USES = $$resolve_depends(CC_USES, QMAKE_DEPENDS_, _CC) for (nu, CC_USES) { !defined(QMAKE_LIBS_$$nu, var): \ - error("Library '$$lower($$nu)' is not defined.") + error("Library '$$lower($$replace(nu, _, -))' is not defined.") DEFINES += $$eval(QMAKE_DEFINES_$${nu}) INCLUDEPATH += $$eval(QMAKE_INCDIR_$${nu}) @@ -20,7 +20,7 @@ for(ever) { LD_USES = $$resolve_depends(LD_USES, QMAKE_DEPENDS_, _LD) for (nu, LD_USES) { !defined(QMAKE_LIBS_$$nu, var): \ - error("Library '$$lower($$nu)' is not defined.") + error("Library '$$lower($$replace(nu, _, -))' is not defined.") debug: \ LIBS$${suffix} += $$eval(QMAKE_LIBS_$${nu}_DEBUG) $$eval(QMAKE_LIBS_$$nu) diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index 5798a8a27b..83802cffca 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -439,12 +439,12 @@ defineTest(qtConfSetupLibraries) { lpfx = $${currentConfig}.libraries.$${l} # 'export' may be omitted, in which case it falls back to the library's name !defined($${lpfx}.export, var) { - $${lpfx}.export = $$l + $${lpfx}.export = $$replace(l, -, _) export($${lpfx}.export) } # 'export' may also be empty, but we need a derived identifier alias = $$eval($${lpfx}.export) - isEmpty(alias): alias = $$l + isEmpty(alias): alias = $$replace(l, -, _) $${lpfx}.alias = $$alias export($${lpfx}.alias) # make it easy to refer to the library by its export name. @@ -804,7 +804,7 @@ defineTest(qtConfLibrary_pkgConfig) { largs = $$qtConfAllLibraryArgs($$eval($${2}.dependencies)) for (la, largs): \ eval("$$la") - USES = $$eval($$list($$upper($$QMAKE_USE))) + USES = $$eval($$list($$upper($$replace(QMAKE_USE, -, _)))) # _CC == _LD for configure's library sources, so pick first arbitrarily. DEPS = $$resolve_depends(USES, QMAKE_DEPENDS_, _CC) for (DEP, DEPS) { @@ -837,7 +837,7 @@ defineTest(qtConfTest_getPkgConfigVariable) { } defineReplace(qtConfLibraryArgs) { - NAME = $$upper($$eval($${1}.library)) + NAME = $$upper($$replace($${1}.library, -, _)) qmake_args = "QMAKE_LIBS_$${NAME} = $$val_escape($${1}.libs)" for (b, $${1}.builds._KEYS_): \ qmake_args += "QMAKE_LIBS_$${NAME}_$$upper($$b) = $$val_escape($${1}.builds.$${b})" @@ -853,8 +853,8 @@ defineReplace(qtConfLibraryArgs) { for (use, depends): \ dep_uses += $$section(use, :, 1, 1) qmake_args += \ - "QMAKE_DEPENDS_$${NAME}_CC = $$upper($$dep_uses)" \ - "QMAKE_DEPENDS_$${NAME}_LD = $$upper($$dep_uses)" + "QMAKE_DEPENDS_$${NAME}_CC = $$upper($$replace(dep_uses, -, _))" \ + "QMAKE_DEPENDS_$${NAME}_LD = $$upper($$replace(dep_uses, -, _))" } return($$qmake_args) } @@ -917,7 +917,7 @@ defineTest(qtConfExportLibrary) { !isEmpty(use_cfg): \ depends += $$upper($$eval($${use_cfg}.libraries.$${use_lib}.export)) else: \ - depends += $$upper($$use_lib) + depends += $$upper($$replace(use_lib, -, _)) } # we use suffixes instead of infixes, because $$resolve_depends() demands it. qtConfOutputVar(assign, $$output, QMAKE_DEPENDS_$${NAME}_CC, $$depends) @@ -1092,7 +1092,7 @@ defineTest(qtConfTestPrepare_compile) { } } isEmpty(libConfig) { - nu = $$upper($$u) + nu = $$upper($$replace(u, -, _)) !defined(QMAKE_LIBS_$$nu, var): \ error("Test $$1 tries to use undeclared library '$$u'") # using an external library by exported name. diff --git a/mkspecs/features/qt_helper_lib.prf b/mkspecs/features/qt_helper_lib.prf index 05d3b941bd..2cb54fc547 100644 --- a/mkspecs/features/qt_helper_lib.prf +++ b/mkspecs/features/qt_helper_lib.prf @@ -31,6 +31,7 @@ THE_TARGET = $$qt5LibraryTarget($$TARGET) !build_pass { MODULE = $$replace(TARGET, ^qt, ) + MODULE ~= s,-,_, MODULE_PRI = $$MODULE_QMAKE_OUTDIR/mkspecs/modules/qt_ext_$${MODULE}.pri ucmodule = $$upper($$MODULE) @@ -46,7 +47,7 @@ THE_TARGET = $$qt5LibraryTarget($$TARGET) for (use, QMAKE_USE) { use = $$split(use, /) name = $$take_first(use) - nu = $$upper($$name) + nu = $$upper($$replace(name, -, _)) !contains(use, linkonly): CC_USES += $$nu !contains(use, nolink): LD_USES += $$nu } From 6b39d51a2c39569f984ef90e905bdf43958f5431 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 13 Jul 2018 18:33:17 +0200 Subject: [PATCH 0698/1650] configure: enable sharing of inlined source code between tests this is implemented by means of (multiple) inheritance, which applies specifically only to the inlined source and header list, but not to library sources or dependencies. Change-Id: I8f1d5b34d1d2d12e39225dc50357ad6ec648c6b6 Reviewed-by: Joerg Bornemann --- mkspecs/features/qt_configure.prf | 59 +++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index 83802cffca..72bbd42fa5 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -592,6 +592,16 @@ defineTest(qtConfResolvePathLibs) { return($$ret) } +defineReplace(qtConfGetTestSourceList) { + result = + !isEmpty($${1}.test.inherit) { + base = $$section(1, ., 0, -2) + for (i, $${1}.test.inherit): \ + result += $$qtConfGetTestSourceList($${base}.$$i) + } + return($$result $$1) +} + defineReplace(qtConfGetTestIncludes) { defined($${1}._KEYS_, var) { 1st = $$first($${1}._KEYS_) @@ -637,7 +647,10 @@ defineTest(qtConfResolvePathIncs) { # thus make the code below work. return($$ret) } - hdrs = $$qtConfGetTestIncludes($${3}.headers) + tests = $$qtConfGetTestSourceList($$3) + hdrs = + for (test, tests): \ + hdrs += $$qtConfGetTestIncludes($${test}.headers) for (hdr, hdrs) { h = $$qtConfFindInPathList($$hdr, $$2 $$EXTRA_INCLUDEPATH $$QMAKE_DEFAULT_INCDIRS) isEmpty(h) { @@ -1109,10 +1122,14 @@ defineTest(qtConfTestPrepare_compile) { } defineTest(qtConfPrepareCompileTestSource) { - test_dir = $$3 + test_dir = $$2 - test_lang = $$eval($${1}.lang) - isEmpty(test_lang): test_lang = "c++" + tests = $$qtConfGetTestSourceList($$1) + + test_lang = "c++" + for (test, tests): \ + test_lang += $$eval($${test}.test.lang) + test_lang = $$last(test_lang) # Last non-empty, that is. equals(test_lang, "c++"): suffix = "cpp" else: equals(test_lang, "c"): suffix = "c" @@ -1123,25 +1140,30 @@ defineTest(qtConfPrepareCompileTestSource) { # Create source code contents = "/* Generated by configure */" # Custom code before includes - for (ent, $$qtConfScalarOrList($${1}.head)): \ - contents += $$ent + for (test, tests): \ + for (ent, $$qtConfScalarOrList($${test}.test.head)): \ + contents += $$ent # Includes - hdrs = $$qtConfGetTestIncludes($${1}.include) - isEmpty(hdrs): \ - hdrs = $$qtConfGetTestIncludes($$2) - for (ent, hdrs): \ - contents += "$${LITERAL_HASH}include <$$ent>" + for (test, tests) { + hdrs = $$qtConfGetTestIncludes($${test}.test.include) + isEmpty(hdrs): \ + hdrs = $$qtConfGetTestIncludes($${test}.headers) + for (ent, hdrs): \ + contents += "$${LITERAL_HASH}include <$$ent>" + } # Custom code after includes - for (ent, $$qtConfScalarOrList($${1}.tail)): \ - contents += $$ent + for (test, tests): \ + for (ent, $$qtConfScalarOrList($${test}.test.tail)): \ + contents += $$ent # And finally the custom code inside main() contents += \ "int main(int argc, char **argv)" \ "{" \ " (void)argc; (void)argv;" \ " /* BEGIN TEST: */" - for (ent, $$qtConfScalarOrList($${1}.main)): \ - contents += " $$ent" + for (test, tests): \ + for (ent, $$qtConfScalarOrList($${test}.test.main)): \ + contents += " $$ent" contents += \ " /* END TEST */" \ " return 0;" \ @@ -1151,8 +1173,9 @@ defineTest(qtConfPrepareCompileTestSource) { # Create stub .pro file contents = "SOURCES = main.$$suffix" # Custom project code - for (ent, $$qtConfScalarOrList($${1}.qmake)): \ - contents += $$ent + for (test, tests): \ + for (ent, $$qtConfScalarOrList($${test}.test.qmake)): \ + contents += $$ent write_file($$test_dir/$$basename(test_dir).pro, contents)|error() } @@ -1165,7 +1188,7 @@ defineTest(qtConfTest_compile) { isEmpty(test) { test_dir = $$test_base_out_dir/$$section(1, ".", -1) test_out_dir = $$test_dir - qtConfPrepareCompileTestSource($${1}.test, $${1}.headers, $$test_dir) + qtConfPrepareCompileTestSource($$1, $$test_dir) } else { test_dir = $$QMAKE_CONFIG_TESTS_DIR/$$test test_out_dir = $$test_base_out_dir/$$test From b6cd5fdc6b7c799a80126659f35801af9a26601a Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 3 May 2018 17:21:03 +0200 Subject: [PATCH 0699/1650] configure: inline openssl test sources Change-Id: I47c1c43b5db30cf1d59de9c6c20ca83abef2cf8c Reviewed-by: Joerg Bornemann --- config.tests/openssl/openssl.cpp | 54 ------------------------- config.tests/openssl/openssl.pro | 1 - config.tests/unix/openssl11/openssl.cpp | 48 ---------------------- config.tests/unix/openssl11/openssl.pro | 2 - src/network/configure.json | 26 ++++++++++-- 5 files changed, 23 insertions(+), 108 deletions(-) delete mode 100644 config.tests/openssl/openssl.cpp delete mode 100644 config.tests/openssl/openssl.pro delete mode 100644 config.tests/unix/openssl11/openssl.cpp delete mode 100644 config.tests/unix/openssl11/openssl.pro diff --git a/config.tests/openssl/openssl.cpp b/config.tests/openssl/openssl.cpp deleted file mode 100644 index 9188fb008f..0000000000 --- a/config.tests/openssl/openssl.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the config.tests of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER-0 < 0x10000000L -# error "OpenSSL >= 1.0.0 is required" -#endif - -#include - -#if OPENSSL_VERSION_NUMBER-0 >= 0x10002000L && !defined(OPENSSL_NO_EC) && !defined(SSL_CTRL_SET_CURVES) -# error "OpenSSL was reported as >= 1.0.2 but is missing required features, possibly it's libressl which is unsupported" -#endif - -int main() -{ -} diff --git a/config.tests/openssl/openssl.pro b/config.tests/openssl/openssl.pro deleted file mode 100644 index f0ee5e2b0c..0000000000 --- a/config.tests/openssl/openssl.pro +++ /dev/null @@ -1 +0,0 @@ -SOURCES = openssl.cpp diff --git a/config.tests/unix/openssl11/openssl.cpp b/config.tests/unix/openssl11/openssl.cpp deleted file mode 100644 index c20cc59deb..0000000000 --- a/config.tests/unix/openssl11/openssl.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the config.tests of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER-0 < 0x10100000L -# error "OpenSSL >= 1.1 is required" -#endif - -int main() -{ -} diff --git a/config.tests/unix/openssl11/openssl.pro b/config.tests/unix/openssl11/openssl.pro deleted file mode 100644 index a023aee4aa..0000000000 --- a/config.tests/unix/openssl11/openssl.pro +++ /dev/null @@ -1,2 +0,0 @@ -SOURCES = openssl.cpp -CONFIG -= x11 qt diff --git a/src/network/configure.json b/src/network/configure.json index e823ed9d2f..10c4f87a2e 100644 --- a/src/network/configure.json +++ b/src/network/configure.json @@ -57,7 +57,17 @@ "openssl_headers": { "label": "OpenSSL Headers", "export": "openssl", - "test": "openssl", + "test": { + "tail": [ + "#if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER-0 < 0x10000000L", + "# error OpenSSL >= 1.0.0 is required", + "#endif", + "#if OPENSSL_VERSION_NUMBER-0 >= 0x10002000L && !defined(OPENSSL_NO_EC) && !defined(SSL_CTRL_SET_CURVES)", + "# error OpenSSL was reported as >= 1.0.2 but is missing required features, possibly it's libressl which is unsupported", + "#endif" + ] + }, + "headers": [ "openssl/ssl.h", "openssl/opensslv.h" ], "sources": [ { "comment": "placeholder for OPENSSL_PATH", @@ -67,7 +77,10 @@ }, "openssl": { "label": "OpenSSL", - "test": "openssl", + "test": { + "inherit": "openssl_headers", + "main": "SSL_free(SSL_new(0));" + }, "sources": [ { "type": "openssl" }, { @@ -149,7 +162,14 @@ "openssl11": { "label": "OpenSSL 1.1 support", "type": "compile", - "test": "unix/openssl11", + "test": { + "include": "openssl/opensslv.h", + "tail": [ + "#if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER-0 < 0x10100000L", + "# error OpenSSL >= 1.1 is required", + "#endif" + ] + }, "use": "openssl" }, "dtls": { From 73b8769730701736cd0d05f904b69f2e7e35de1d Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 13 Jul 2018 21:25:12 +0200 Subject: [PATCH 0700/1650] configure: enable inline tests to contain auxiliary files ... and use that to migrate the pch test. Change-Id: I2ce884442cab6124c37142f571cf6f82191ee4f5 Reviewed-by: Joerg Bornemann --- config.tests/common/pch/header.h | 1 - config.tests/common/pch/pch.pro | 4 --- config.tests/common/pch/source.cpp | 44 ------------------------------ configure.json | 16 ++++++++++- mkspecs/features/qt_configure.prf | 5 ++++ 5 files changed, 20 insertions(+), 50 deletions(-) delete mode 100644 config.tests/common/pch/header.h delete mode 100644 config.tests/common/pch/pch.pro delete mode 100644 config.tests/common/pch/source.cpp diff --git a/config.tests/common/pch/header.h b/config.tests/common/pch/header.h deleted file mode 100644 index ebc22c4fb0..0000000000 --- a/config.tests/common/pch/header.h +++ /dev/null @@ -1 +0,0 @@ -#define HEADER_H diff --git a/config.tests/common/pch/pch.pro b/config.tests/common/pch/pch.pro deleted file mode 100644 index f6384b71e1..0000000000 --- a/config.tests/common/pch/pch.pro +++ /dev/null @@ -1,4 +0,0 @@ -CONFIG += precompile_header -PRECOMPILED_DIR = .pch -PRECOMPILED_HEADER = header.h -SOURCES = source.cpp diff --git a/config.tests/common/pch/source.cpp b/config.tests/common/pch/source.cpp deleted file mode 100644 index 855672ffa8..0000000000 --- a/config.tests/common/pch/source.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the configuration of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef HEADER_H -#error no go -#endif - -int main() { return 0; } diff --git a/configure.json b/configure.json index 2a717daf9a..9fce6d039e 100644 --- a/configure.json +++ b/configure.json @@ -324,7 +324,21 @@ "precompile_header": { "label": "precompiled header support", "type": "compile", - "test": "common/pch" + "test": { + "files": { + "header.h": "#define HEADER_H" + }, + "tail": [ + "#ifndef HEADER_H", + "#error no go", + "#endif" + ], + "qmake": [ + "CONFIG += precompile_header", + "PRECOMPILED_DIR = .pch", + "PRECOMPILED_HEADER = header.h" + ] + } }, "use_gold_linker": { "label": "gold linker", diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index 72bbd42fa5..f5aa444ade 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -1170,6 +1170,11 @@ defineTest(qtConfPrepareCompileTestSource) { "}" write_file($$test_dir/main.$$suffix, contents)|error() + for (test, tests) { + for (file, $$qtConfScalarOrList($${test}.test.files._KEYS_)): \ + write_file($$test_dir/$$file, $$qtConfScalarOrList($${test}.test.files.$${file}))|error() + } + # Create stub .pro file contents = "SOURCES = main.$$suffix" # Custom project code From 98689cd2f9d3e9e4dac33ccf6679b90d4b39284f Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 16 Jul 2018 12:10:19 +0200 Subject: [PATCH 0701/1650] configure: enable inline tests to refer to PWD ... and use that to inline the xlocalescanprint test. Change-Id: I0973133d7f9ecc9a38b70dc4b83df174a35b2b1f Reviewed-by: Joerg Bornemann --- config.tests/xlocalescanprint/qglobal.h | 43 ------------- .../xlocalescanprint/xlocalescanprint.cpp | 62 ------------------- .../xlocalescanprint/xlocalescanprint.pro | 1 - mkspecs/features/qt_configure.prf | 3 +- src/corelib/configure.json | 33 +++++++++- 5 files changed, 34 insertions(+), 108 deletions(-) delete mode 100644 config.tests/xlocalescanprint/qglobal.h delete mode 100644 config.tests/xlocalescanprint/xlocalescanprint.cpp delete mode 100644 config.tests/xlocalescanprint/xlocalescanprint.pro diff --git a/config.tests/xlocalescanprint/qglobal.h b/config.tests/xlocalescanprint/qglobal.h deleted file mode 100644 index 98de822847..0000000000 --- a/config.tests/xlocalescanprint/qglobal.h +++ /dev/null @@ -1,43 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the config.tests of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLOBAL_H -#define QGLOBAL_H - -#endif diff --git a/config.tests/xlocalescanprint/xlocalescanprint.cpp b/config.tests/xlocalescanprint/xlocalescanprint.cpp deleted file mode 100644 index 2f1f28f74e..0000000000 --- a/config.tests/xlocalescanprint/xlocalescanprint.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the config.tests of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#define QT_BEGIN_NAMESPACE -#define QT_END_NAMESPACE - -#ifdef _MSVC_VER -#define Q_CC_MSVC _MSVC_VER -#endif - -#define QT_NO_DOUBLECONVERSION - -#include "../../../src/corelib/tools/qdoublescanprint_p.h" - -int main(int argc, char **argv) -{ -#ifdef _MSVC_VER - _locale_t invalidLocale = NULL; -#else - locale_t invalidLocale = NULL; -#endif - double a = 3.4; - qDoubleSnprintf(argv[0], 1, invalidLocale, "invalid format", a); - qDoubleSscanf(argv[0], invalidLocale, "invalid format", &a, &argc); - return 0; -} diff --git a/config.tests/xlocalescanprint/xlocalescanprint.pro b/config.tests/xlocalescanprint/xlocalescanprint.pro deleted file mode 100644 index 3748d2a728..0000000000 --- a/config.tests/xlocalescanprint/xlocalescanprint.pro +++ /dev/null @@ -1 +0,0 @@ -SOURCES = xlocalescanprint.cpp diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index f5aa444ade..87190bc52a 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -1178,9 +1178,10 @@ defineTest(qtConfPrepareCompileTestSource) { # Create stub .pro file contents = "SOURCES = main.$$suffix" # Custom project code + pwd = $$val_escape($${currentConfig}.dir) for (test, tests): \ for (ent, $$qtConfScalarOrList($${test}.test.qmake)): \ - contents += $$ent + contents += $$replace(ent, "@PWD@", $$pwd) write_file($$test_dir/$$basename(test_dir).pro, contents)|error() } diff --git a/src/corelib/configure.json b/src/corelib/configure.json index eb213398ca..3b33e6158b 100644 --- a/src/corelib/configure.json +++ b/src/corelib/configure.json @@ -467,7 +467,38 @@ "xlocalescanprint": { "label": "xlocale.h (or equivalents)", "type": "compile", - "test": "xlocalescanprint" + "test": { + "files": { + "qglobal.h": [ + "#ifndef QGLOBAL_H", + "#define QGLOBAL_H", + "#endif" + ] + }, + "tail": [ + "#define QT_BEGIN_NAMESPACE", + "#define QT_END_NAMESPACE", + "", + "#ifdef _MSVC_VER", + "#define Q_CC_MSVC _MSVC_VER", + "#endif", + "", + "#define QT_NO_DOUBLECONVERSION", + "", + "#include QDSP_P_H" + ], + "main": [ + "#ifdef _MSVC_VER", + "_locale_t invalidLocale = NULL;", + "#else", + "locale_t invalidLocale = NULL;", + "#endif", + "double a = 3.4;", + "qDoubleSnprintf(argv[0], 1, invalidLocale, \"invalid format\", a);", + "qDoubleSscanf(argv[0], invalidLocale, \"invalid format\", &a, &argc);" + ], + "qmake": "DEFINES += QDSP_P_H=$$shell_quote(\\\"@PWD@/tools/qdoublescanprint_p.h\\\")" + } } }, From 52934d74be7d882f3f584a348ce29bedff7fa7a7 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 16 Jul 2018 14:10:42 +0200 Subject: [PATCH 0702/1650] configure: modernize iconv use use library objects for all variants, and inline the tests. Change-Id: I029f9a6655a783dab4a22abf601aadbb484c03af Reviewed-by: Joerg Bornemann --- config.tests/gnu-libiconv/gnu-libiconv.cpp | 54 ---------------------- config.tests/gnu-libiconv/gnu-libiconv.pro | 1 - config.tests/iconv/iconv.cpp | 54 ---------------------- config.tests/iconv/iconv.pro | 2 - config.tests/sun-libiconv/sun-libiconv.pro | 1 - src/corelib/codecs/codecs.pri | 3 +- src/corelib/configure.json | 54 ++++++++++++++++------ 7 files changed, 42 insertions(+), 127 deletions(-) delete mode 100644 config.tests/gnu-libiconv/gnu-libiconv.cpp delete mode 100644 config.tests/gnu-libiconv/gnu-libiconv.pro delete mode 100644 config.tests/iconv/iconv.cpp delete mode 100644 config.tests/iconv/iconv.pro delete mode 100644 config.tests/sun-libiconv/sun-libiconv.pro diff --git a/config.tests/gnu-libiconv/gnu-libiconv.cpp b/config.tests/gnu-libiconv/gnu-libiconv.cpp deleted file mode 100644 index fe4b87b923..0000000000 --- a/config.tests/gnu-libiconv/gnu-libiconv.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the config.tests of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -int main(int, char **) -{ - iconv_t x = iconv_open("", ""); - - const char *inp; - char *outp; - size_t inbytes, outbytes; - iconv(x, &inp, &inbytes, &outp, &outbytes); - - iconv_close(x); - - return 0; -} diff --git a/config.tests/gnu-libiconv/gnu-libiconv.pro b/config.tests/gnu-libiconv/gnu-libiconv.pro deleted file mode 100644 index e4e020cffb..0000000000 --- a/config.tests/gnu-libiconv/gnu-libiconv.pro +++ /dev/null @@ -1 +0,0 @@ -SOURCES = gnu-libiconv.cpp diff --git a/config.tests/iconv/iconv.cpp b/config.tests/iconv/iconv.cpp deleted file mode 100644 index be4236436f..0000000000 --- a/config.tests/iconv/iconv.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the config.tests of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -int main(int, char **) -{ - iconv_t x = iconv_open("", ""); - - char *inp; - char *outp; - size_t inbytes, outbytes; - iconv(x, &inp, &inbytes, &outp, &outbytes); - - iconv_close(x); - - return 0; -} diff --git a/config.tests/iconv/iconv.pro b/config.tests/iconv/iconv.pro deleted file mode 100644 index 70af0d2eb2..0000000000 --- a/config.tests/iconv/iconv.pro +++ /dev/null @@ -1,2 +0,0 @@ -SOURCES = iconv.cpp -mac|mingw|openbsd|qnx|haiku:LIBS += -liconv diff --git a/config.tests/sun-libiconv/sun-libiconv.pro b/config.tests/sun-libiconv/sun-libiconv.pro deleted file mode 100644 index d0881b732a..0000000000 --- a/config.tests/sun-libiconv/sun-libiconv.pro +++ /dev/null @@ -1 +0,0 @@ -SOURCES = ../gnu-libiconv/gnu-libiconv.cpp diff --git a/src/corelib/codecs/codecs.pri b/src/corelib/codecs/codecs.pri index f1bbde1d69..5d500ce521 100644 --- a/src/corelib/codecs/codecs.pri +++ b/src/corelib/codecs/codecs.pri @@ -56,8 +56,7 @@ qtConfig(textcodec) { qtConfig(iconv) { HEADERS += codecs/qiconvcodec_p.h SOURCES += codecs/qiconvcodec.cpp - qtConfig(gnu-libiconv): \ - QMAKE_USE_PRIVATE += iconv + QMAKE_USE_PRIVATE += iconv } win32 { diff --git a/src/corelib/configure.json b/src/corelib/configure.json index 3b33e6158b..a22a7459bd 100644 --- a/src/corelib/configure.json +++ b/src/corelib/configure.json @@ -47,14 +47,52 @@ { "type": "pkgConfig", "args": "glib-2.0 gthread-2.0" } ] }, + "posix_iconv": { + "label": "POSIX iconv", + "export": "iconv", + "test": { + "main": [ + "iconv_t x = iconv_open(\"\", \"\");", + "char *inp, *outp;", + "size_t inbytes, outbytes;", + "iconv(x, &inp, &inbytes, &outp, &outbytes);", + "iconv_close(x);" + ] + }, + "headers": "iconv.h", + "sources": [ + { "libs": "-liconv", "condition": "config.openbsd || config.haiku" }, + { "libs": "", "condition": "!(config.openbsd || config.haiku)" } + ] + }, "gnu_iconv": { "label": "GNU libiconv", "export": "iconv", - "test": "gnu-libiconv", + "test": { + "main": [ + "iconv_t x = iconv_open(\"\", \"\");", + "const char *inp;", + "char *outp;", + "size_t inbytes, outbytes;", + "iconv(x, &inp, &inbytes, &outp, &outbytes);", + "iconv_close(x);" + ] + }, + "headers": "iconv.h", "sources": [ "-liconv" ] }, + "sun_iconv": { + "label": "SUN libiconv", + "export": "iconv", + "test": { + "inherit": "gnu_iconv" + }, + "sources": [ + "" + ] + }, "icu": { "label": "ICU", "test": { @@ -336,16 +374,6 @@ ] } }, - "posix-iconv": { - "label": "POSIX iconv", - "type": "compile", - "test": "iconv" - }, - "sun-iconv": { - "label": "SUN libiconv", - "type": "compile", - "test": "sun-libiconv" - }, "inotify": { "label": "inotify", "type": "compile", @@ -576,14 +604,14 @@ "label": "POSIX iconv", "enable": "input.iconv == 'posix'", "disable": "input.iconv == 'sun' || input.iconv == 'gnu' || input.iconv == 'no'", - "condition": "!config.win32 && !config.qnx && !config.android && !config.darwin && tests.posix-iconv", + "condition": "!config.win32 && !config.qnx && !config.android && !config.darwin && libs.posix_iconv", "output": [ "privateFeature" ] }, "sun-libiconv": { "label": "SUN iconv", "enable": "input.iconv == 'sun'", "disable": "input.iconv == 'posix' || input.iconv == 'gnu' || input.iconv == 'no'", - "condition": "!config.win32 && !config.qnx && !config.android && !config.darwin && !features.posix-libiconv && tests.sun-iconv" + "condition": "!config.win32 && !config.qnx && !config.android && !config.darwin && !features.posix-libiconv && libs.sun_iconv" }, "gnu-libiconv": { "label": "GNU iconv", From 23207d1d2386d97b9d27f2af385d70f80c14ab95 Mon Sep 17 00:00:00 2001 From: Sune Vuorela Date: Sun, 16 Dec 2018 13:52:45 +0100 Subject: [PATCH 0703/1650] Empty filenames does not exist If empty paths is passed to the unix filesystem engine, we get a warning about empty filename passed to function, before returning false. Fix this by testing for empty string first, and don't send empty string to file engine. The current warning leads to code like if (!filename.isEmpty() && QFile::exists(filename)) { // } rather than the slightly cleaner if (QFile::exists(filename)) { // } Change-Id: I0207324889ec22e5a072c28d58337d117b0153b1 Reviewed-by: Thiago Macieira Reviewed-by: Mitch Curtis --- src/corelib/io/qfileinfo.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index 26078a6c71..185e061d8f 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -703,6 +703,8 @@ bool QFileInfo::exists() const */ bool QFileInfo::exists(const QString &file) { + if (file.isEmpty()) + return false; QFileSystemEntry entry(file); QFileSystemMetaData data; QAbstractFileEngine *engine = From 9ee6eed572df76b60248153cf16febd6156ad006 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Thu, 13 Dec 2018 11:31:21 +0100 Subject: [PATCH 0704/1650] Revert "configure: remove xkbcommon_evdev transition hack" This reverts commit 28fd625873f9bb191cb10a2a36a1b974c6e8c97e. We still need to have this intermedia stage to have all need things(qtwayland and qtwebengine) landed in dev. This revert will be reverted later. Change-Id: I0522d5b0efb2345e5b4879424d98531f7c1b44a2 Reviewed-by: Gatis Paeglis --- src/gui/configure.json | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/gui/configure.json b/src/gui/configure.json index 7585e9c8d4..e0d643b844 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -635,6 +635,16 @@ { "type": "pkgConfig", "args": "xkbcommon-x11" } ] }, + "xkbcommon_evdev": { + "label": "xkbcommon_evdev TRANSITION HACK", + "test": { + "include": [ "xkbcommon/xkbcommon.h" ], + "main": "xkb_context_new(XKB_CONTEXT_NO_FLAGS);" + }, + "sources": [ + { "type": "pkgConfig", "args": "xkbcommon >= 0.5.0" } + ] + }, "xrender": { "label": "XRender for native painting", "test": "x11/xrender", @@ -1379,6 +1389,11 @@ "condition": "libs.xkbcommon", "output": [ "privateFeature" ] }, + "xkbcommon-evdev": { + "label": "xkbcommon-evdev TRANSITION HACK", + "condition": "libs.xkbcommon_evdev", + "output": [ "privateFeature" ] + }, "xlib": { "label": "XLib", "autoDetect": "!config.darwin || features.xcb", From f3b980a25339c2d7db71eb9dd125d7d14df05fc6 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Mon, 10 Dec 2018 10:20:48 +0100 Subject: [PATCH 0705/1650] Use QStringLiteral instead of QString::fromLatin1 The value is returned, so it would be converted to QString anyway. This saves the allocation. Change-Id: I1a4ec4e16bccdd23e662be9b3dd7f8f09b4197ee Reviewed-by: Christian Ehrlicher --- src/gui/text/qfont.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 38462c6e24..d879836572 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -2180,7 +2180,7 @@ void QFont::cacheStatistics() */ QString QFont::lastResortFamily() const { - return QString::fromLatin1("helvetica"); + return QStringLiteral("helvetica"); } #endif From 50d53533e5ab1923865a9f80cb8b093ab477ae81 Mon Sep 17 00:00:00 2001 From: David Faure Date: Wed, 12 Dec 2018 09:41:49 +0100 Subject: [PATCH 0706/1650] QCommandLineParser: show application name in error messages Change-Id: I2c39759294ca0a11a59b9a38207bf1aef941b070 Fixes: QTBUG-58490 Reviewed-by: Thiago Macieira --- src/corelib/tools/qcommandlineparser.cpp | 2 +- .../tst_qcommandlineparser.cpp | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qcommandlineparser.cpp b/src/corelib/tools/qcommandlineparser.cpp index 279d6565da..6817d73143 100644 --- a/src/corelib/tools/qcommandlineparser.cpp +++ b/src/corelib/tools/qcommandlineparser.cpp @@ -589,7 +589,7 @@ static void showParserMessage(const QString &message, MessageType type) void QCommandLineParser::process(const QStringList &arguments) { if (!d->parse(arguments)) { - showParserMessage(errorText() + QLatin1Char('\n'), ErrorMessage); + showParserMessage(QCoreApplication::applicationName() + QLatin1String(": ") + errorText() + QLatin1Char('\n'), ErrorMessage); qt_call_post_routines(); ::exit(EXIT_FAILURE); } diff --git a/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp b/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp index 62c29229e1..7980f1f8f4 100644 --- a/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp +++ b/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp @@ -74,6 +74,7 @@ private slots: void testHelpOption_data(); void testHelpOption(); void testQuoteEscaping(); + void testUnknownOption(); }; static char *empty_argv[] = { 0 }; @@ -648,6 +649,27 @@ void tst_QCommandLineParser::testQuoteEscaping() #endif // QT_CONFIG(process) } +void tst_QCommandLineParser::testUnknownOption() +{ +#if !QT_CONFIG(process) + QSKIP("This test requires QProcess support"); +#elif defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED) + QSKIP("Deploying executable applications to file system on Android not supported."); +#else + QCoreApplication app(empty_argc, empty_argv); + QProcess process; + process.start("testhelper/qcommandlineparser_test_helper", QStringList() << + QString::number(QCommandLineParser::ParseAsLongOptions) << + "-unknown-option"); + QVERIFY(process.waitForFinished(5000)); + QCOMPARE(process.exitStatus(), QProcess::NormalExit); + process.setReadChannel(QProcess::StandardError); + QString output = process.readAll(); + QVERIFY2(output.contains("qcommandlineparser_test_helper"), qPrintable(output)); // separate in case of .exe extension + QVERIFY2(output.contains(": Unknown option 'unknown-option'"), qPrintable(output)); +#endif // QT_CONFIG(process) +} + QTEST_APPLESS_MAIN(tst_QCommandLineParser) #include "tst_qcommandlineparser.moc" From f377b1ddfb01f654975d8fee1dba3dbed78822e8 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Mon, 3 Dec 2018 08:35:28 +0100 Subject: [PATCH 0707/1650] qmake: Add support for installing executable files without calling strip Since some files are still executable (such as bash scripts) then they should not get strip called on them when installing in those cases. So by adding .CONFIG = nostrip, it indicates that strip should not be called on this. Fixes: QTBUG-60751 Change-Id: I19d502c07644daf9d487a8817c8e57d96eedab60 Reviewed-by: Oswald Buddenhagen --- qmake/generators/makefile.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 7247d1f8df..765aea4d83 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -1289,6 +1289,7 @@ MakefileGenerator::writeInstalls(QTextStream &t, bool noBuild) } } bool is_target = (wild == fileFixify(var("TARGET"), FileFixifyAbsolute)); + const bool noStrip = installConfigValues.contains("nostrip"); if(is_target || exists(wild)) { //real file or target QFileInfo fi(fileInfo(wild)); QString dst_file = filePrefixRoot(root, dst_dir); @@ -1302,7 +1303,7 @@ MakefileGenerator::writeInstalls(QTextStream &t, bool noBuild) cmd = QLatin1String("-$(QINSTALL)"); cmd += " " + escapeFilePath(wild) + " " + escapeFilePath(dst_file); inst << cmd; - if (!project->isActiveConfig("debug_info") && !project->isActiveConfig("nostrip") && + if (!noStrip && !project->isActiveConfig("debug_info") && !project->isActiveConfig("nostrip") && !fi.isDir() && fi.isExecutable() && !project->isEmpty("QMAKE_STRIP")) inst << QString("-") + var("QMAKE_STRIP") + " " + escapeFilePath(filePrefixRoot(root, fileFixify(dst_dir + filestr, FileFixifyAbsolute, false))); @@ -1337,7 +1338,7 @@ MakefileGenerator::writeInstalls(QTextStream &t, bool noBuild) QString cmd = QLatin1String("-$(QINSTALL) ") + escapeFilePath(dirstr + file) + " " + escapeFilePath(dst_file); inst << cmd; - if (!project->isActiveConfig("debug_info") && !project->isActiveConfig("nostrip") && + if (!noStrip && !project->isActiveConfig("debug_info") && !project->isActiveConfig("nostrip") && !fi.isDir() && fi.isExecutable() && !project->isEmpty("QMAKE_STRIP")) inst << QString("-") + var("QMAKE_STRIP") + " " + escapeFilePath(filePrefixRoot(root, fileFixify(dst_dir + file, FileFixifyAbsolute, false))); From 3f2786e3226ac8b25188fe1b1e6de802996f6720 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 12 Apr 2018 16:48:27 +0200 Subject: [PATCH 0708/1650] qmake: fixify target paths of extra compilers more consistently ... so we don't get into situations where a target has a relative path, while another target depends on it with an absolute path. Task-number: QTBUG-36768 Change-Id: Icc5b249914bb3f095f4a6542c30bacf5ea6f9ec9 Reviewed-by: Joerg Bornemann Reviewed-by: Oswald Buddenhagen --- qmake/generators/makefile.cpp | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 765aea4d83..8b36b64d1d 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -1876,12 +1876,14 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) if (config.indexOf("combine") != -1) { // compilers with a combined input only have one output QString input = project->first(ProKey(*it + ".output")).toQString(); - t << ' ' << escapeDependencyPath(Option::fixPathToTargetOS( - replaceExtraCompilerVariables(tmp_out, input, QString(), NoShell))); + t << ' ' << escapeDependencyPath(fileFixify( + replaceExtraCompilerVariables(tmp_out, input, QString(), NoShell), + FileFixifyFromOutdir)); } else { for (ProStringList::ConstIterator input = tmp_inputs.begin(); input != tmp_inputs.end(); ++input) { - t << ' ' << escapeDependencyPath(Option::fixPathToTargetOS( - replaceExtraCompilerVariables(tmp_out, (*input).toQString(), QString(), NoShell))); + t << ' ' << escapeDependencyPath(fileFixify( + replaceExtraCompilerVariables(tmp_out, (*input).toQString(), QString(), NoShell), + FileFixifyFromOutdir)); } } t << endl; @@ -1917,8 +1919,9 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) QString tinp = (*input).toQString(); QString out = replaceExtraCompilerVariables(tmp_out, tinp, QString(), NoShell); for (const QString &rc : qAsConst(raw_clean)) { - dels << ' ' + escapeFilePath(Option::fixPathToTargetOS( - replaceExtraCompilerVariables(rc, tinp, out, NoShell), false)); + dels << ' ' + escapeFilePath(fileFixify( + replaceExtraCompilerVariables(rc, tinp, out, NoShell), + FileFixifyFromOutdir)); } } if(project->isActiveConfig("no_delete_multiple_files")) { @@ -2034,7 +2037,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) QString out = replaceExtraCompilerVariables(tmp_out, QString(), QString(), NoShell); QString cmd = replaceExtraCompilerVariables(tmp_cmd, inputs, QStringList() << out, TargetShell); - t << escapeDependencyPath(Option::fixPathToTargetOS(out)) << ":"; + t << escapeDependencyPath(fileFixify(out, FileFixifyFromOutdir)) << ":"; // compiler.CONFIG+=explicit_dependencies means that ONLY compiler.depends gets to cause Makefile dependencies if (config.indexOf("explicit_dependencies") != -1) { t << " " << valList(escapeDependencyPaths(fileFixify(tmp_dep, FileFixifyFromOutdir))); @@ -2046,14 +2049,16 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) } for (ProStringList::ConstIterator input = tmp_inputs.begin(); input != tmp_inputs.end(); ++input) { QString inpf = (*input).toQString(); - QString in = Option::fixPathToTargetOS(inpf, false); - QStringList deps = findDependencies(inpf); - deps << in; - QString out = Option::fixPathToTargetOS(replaceExtraCompilerVariables(tmp_out, inpf, QString(), NoShell)); + QStringList deps; + deps << fileFixify(inpf, FileFixifyFromOutdir); + deps += findDependencies(inpf); + QString out = fileFixify(replaceExtraCompilerVariables(tmp_out, inpf, QString(), NoShell), + FileFixifyFromOutdir); if(!tmp_dep.isEmpty()) { QStringList pre_deps = fileFixify(tmp_dep, FileFixifyFromOutdir); for(int i = 0; i < pre_deps.size(); ++i) - deps << replaceExtraCompilerVariables(pre_deps.at(i), inpf, out, NoShell); + deps << fileFixify(replaceExtraCompilerVariables(pre_deps.at(i), inpf, out, NoShell), + FileFixifyFromOutdir); } QString cmd = replaceExtraCompilerVariables(tmp_cmd, inpf, out, TargetShell); // NOTE: The var -> QMAKE_COMP_var replace feature is unsupported, do not use! @@ -2113,7 +2118,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) //use the depend system to find includes of these included files QStringList inc_deps; for(int i = 0; i < deps.size(); ++i) { - const QString dep = deps.at(i); + const QString dep = fileFixify(deps.at(i), FileFixifyFromOutdir | FileFixifyAbsolute); if(QFile::exists(dep)) { SourceFileType type = TYPE_UNKNOWN; if(type == TYPE_UNKNOWN) { @@ -2150,11 +2155,10 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) } } } - deps += inc_deps; + deps += fileFixify(inc_deps, FileFixifyFromOutdir); } for(int i = 0; i < deps.size(); ) { QString &dep = deps[i]; - dep = Option::fixPathToTargetOS(dep, false); if(out == dep) deps.removeAt(i); else From 49c8595bf8f4563656498be9f99448526338acb3 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 17 Dec 2018 21:18:18 +0100 Subject: [PATCH 0709/1650] qmake: fix typo in function name Change-Id: Ie88ae0f13be83d6e63078eeb359d9ddf012c94fb Reviewed-by: Joerg Bornemann --- mkspecs/features/toolchain.prf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mkspecs/features/toolchain.prf b/mkspecs/features/toolchain.prf index c7ea20e180..1a76e50b49 100644 --- a/mkspecs/features/toolchain.prf +++ b/mkspecs/features/toolchain.prf @@ -9,7 +9,7 @@ defineReplace(qtMakeExpand) { } } -defineTest(qtCompilerErrror) { +defineTest(qtCompilerError) { !cross_compile: \ what = else: host_build: \ @@ -69,7 +69,7 @@ isEmpty($${target_prefix}.INCDIRS) { cxx_flags += -E -v output = $$system("$$cmd_prefix $$QMAKE_CXX $$qtMakeExpand($$cxx_flags) -xc++ - 2>&1 $$cmd_suffix", lines, ec) - !equals(ec, 0): qtCompilerErrror($$QMAKE_CXX, $$output) + !equals(ec, 0): qtCompilerError($$QMAKE_CXX, $$output) rim_qcc { for (line, output) { @@ -129,7 +129,7 @@ isEmpty($${target_prefix}.INCDIRS) { # What's more, -print-search-dirs can't be used on clang on Apple because it # won't print all the library paths (only the clang-internal ones). output = $$system("$$cmd_prefix $$QMAKE_LINK $$QMAKE_LFLAGS -print-search-dirs", lines, ec) - !equals(ec, 0): qtCompilerErrror($$QMAKE_LINK, $$output) + !equals(ec, 0): qtCompilerError($$QMAKE_LINK, $$output) for (line, output) { contains(line, "^libraries: .*") { @@ -149,7 +149,7 @@ isEmpty($${target_prefix}.INCDIRS) { } else: ghs { cmd = $$QMAKE_CXX $$QMAKE_CXXFLAGS -$${LITERAL_HASH} -o /tmp/fake_output /tmp/fake_input.cpp output = $$system("$$cmd", blob, ec) - !equals(ec, 0): qtCompilerErrror($$QMAKE_CXX, $$output) + !equals(ec, 0): qtCompilerError($$QMAKE_CXX, $$output) output ~= s/\\\\\\n {8}//g output = $$split(output, $$escape_expand(\\n)) for (line, output) { @@ -199,14 +199,14 @@ isEmpty($${target_prefix}.INCDIRS) { defineReplace(qtVariablesFromMSVC) { ret = $$system("$$1 -nologo -E $$2 $$system_quote($$PWD/data/macros.cpp) 2>NUL", lines, ec) - !equals(ec, 0): qtCompilerErrror($$1, $$ret) + !equals(ec, 0): qtCompilerError($$1, $$ret) return($$ret) } defineReplace(qtVariablesFromGCC) { ret = $$system("$$1 -E $$system_quote($$PWD/data/macros.cpp) \ 2>$$QMAKE_SYSTEM_NULL_DEVICE", lines, ec) - !equals(ec, 0): qtCompilerErrror($$1, $$ret) + !equals(ec, 0): qtCompilerError($$1, $$ret) return($$ret) } From e0926ca4260953a70cdb2a6f84da35517ead1349 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 19 Dec 2018 17:54:46 +0100 Subject: [PATCH 0710/1650] qmake: remove support for pre-5.6 qt module pris MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit it seems rather obsolete by now. Change-Id: I43a84367fbe9f82c3adc0e3825d14198e69eaa1f Reviewed-by: Tor Arne Vestbø --- mkspecs/features/qt.prf | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index d16b3cf1be..5da82fdb5b 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -198,28 +198,6 @@ for(ever) { MODULE_LIBS_ADD = $$MODULE_LIBS MODULE_LIBS_ADD -= $$QMAKE_DEFAULT_LIBDIRS - !contains(MODULE_CONFIG, v2) { - # Backwards compatibility with pre-5.6 module .pri files - - contains(MODULE_CONFIG, lib_bundle) { - MODULE_FRAMEWORKS = $$MODULE_LIBS - inc = $$MODULE_LIBS/$${MODULE_NAME}.framework/Headers - MODULE_INCLUDES = $$inc - contains(MODULE_CONFIG, internal_module): \ - MODULE_INCLUDES += \ - $$inc/$$eval(QT.$${QTLIB}.VERSION) \ - $$inc/$$eval(QT.$${QTLIB}.VERSION)/$$MODULE_NAME - } else { - # Re-insert the major version in the library name (cf qt5LibraryTarget above) - MODULE_NAME ~= s,^Qt,Qt$$QT_MAJOR_VERSION, - } - - # Only link to this module if a libs directory is set, else this is just a module - # to give access to sources or include files, and not for linking. - !isEmpty(MODULE_LIBS):!contains(MODULE_CONFIG, no_link): \ - MODULE_MODULE = $${MODULE_NAME}$${QT_LIBINFIX} - } - # Frameworks shouldn't need include paths, but much code does not use # module-qualified #includes, so by default we add paths which point # directly into the frameworks. Private modules have somewhat convoluted From 3a74a3b5a644ac196942c717d31cd5f8438f3c0b Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Thu, 20 Dec 2018 09:13:26 +0100 Subject: [PATCH 0711/1650] QSQL: add support for PostgreSQL 11 Add support for PostgreSQL 11 by adding QPSQLDriver::Version11 and use it in qMakePSQLVersion(). [ChangeLog][QSQL][PostgreSQL] Added support for PostgreSQL 11 Fixes: QTBUG-71642 Change-Id: Ie3cd3a81fd00084b587457b91b4e92c2e7001172 Reviewed-by: Andy Shaw Reviewed-by: Robert Szefner --- src/plugins/sqldrivers/psql/qsql_psql.cpp | 4 +++- src/plugins/sqldrivers/psql/qsql_psql_p.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plugins/sqldrivers/psql/qsql_psql.cpp b/src/plugins/sqldrivers/psql/qsql_psql.cpp index bf0493b0c3..7ad9db1ea8 100644 --- a/src/plugins/sqldrivers/psql/qsql_psql.cpp +++ b/src/plugins/sqldrivers/psql/qsql_psql.cpp @@ -1060,8 +1060,10 @@ static QPSQLDriver::Protocol qMakePSQLVersion(int vMaj, int vMin) } case 10: return QPSQLDriver::Version10; + case 11: + return QPSQLDriver::Version11; default: - if (vMaj > 10) + if (vMaj > 11) return QPSQLDriver::UnknownLaterVersion; break; } diff --git a/src/plugins/sqldrivers/psql/qsql_psql_p.h b/src/plugins/sqldrivers/psql/qsql_psql_p.h index 2873a9f851..7e1849d857 100644 --- a/src/plugins/sqldrivers/psql/qsql_psql_p.h +++ b/src/plugins/sqldrivers/psql/qsql_psql_p.h @@ -92,6 +92,7 @@ public: Version9_5 = 21, Version9_6 = 22, Version10 = 23, + Version11 = 24, UnknownLaterVersion = 100000 }; From b45c1e1c0e3dd838543c1e8d4725d9436367a16a Mon Sep 17 00:00:00 2001 From: Sami Nurmenniemi Date: Wed, 12 Dec 2018 13:45:16 +0200 Subject: [PATCH 0712/1650] Add possibility to configure QNX display order MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add environmental variable QT_QPA_QNX_DISPLAY_CONFIG for pointing to a file containing display order. Configuration file format is: { "displayOrder": [ 3, 1 ] } Task-number: QTBUG-66394 Change-Id: I8c20eb2b5cf35617d5a030213f5d4d68e62ace85 Reviewed-by: Kari Oikarinen Reviewed-by: Pasi Petäjäjärvi --- src/plugins/platforms/qnx/qqnxintegration.cpp | 114 +++++++++++++++++- src/plugins/platforms/qnx/qqnxintegration.h | 2 + 2 files changed, 112 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp index 8c8521325c..db79780407 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.cpp +++ b/src/plugins/platforms/qnx/qqnxintegration.cpp @@ -88,7 +88,10 @@ #include #include - +#include +#include +#include +#include #include #if defined(QQNXINTEGRATION_DEBUG) @@ -490,6 +493,108 @@ void QQnxIntegration::removeWindow(screen_window_t qnxWindow) m_windowMapper.remove(qnxWindow); } +/*! + Get display ID for given \a display + + Returns -1 for failure, otherwise returns display ID + */ +static int getIdOfDisplay(screen_display_t display) +{ + int displayId; + if (screen_get_display_property_iv(display, + SCREEN_PROPERTY_ID, + &displayId) == 0) { + return displayId; + } + return -1; +} + +/*! + Read JSON configuration file for the QNX display order + + Returns true if file was read successfully and fills \a requestedDisplays + */ +static bool getRequestedDisplays(QJsonArray &requestedDisplays) +{ + // Check if display configuration file is provided + QByteArray json = qgetenv("QT_QPA_QNX_DISPLAY_CONFIG"); + if (json.isEmpty()) + return false; + + // Check if configuration file exists + QFile file(QString::fromUtf8(json)); + if (!file.open(QFile::ReadOnly)) { + qWarning() << "Could not open config file" << json << "for reading"; + return false; + } + + // Read config file and check it's json + const QJsonDocument doc = QJsonDocument::fromJson(file.readAll()); + if (!doc.isObject()) { + qWarning() << "Invalid config file" << json + << "- no top-level JSON object"; + return false; + } + + // Read the requested display order + const QJsonObject object = doc.object(); + requestedDisplays = object.value(QLatin1String("displayOrder")).toArray(); + + return true; +} + +/*! + Match \a availableDisplays with display order defined in a json file + pointed to by QT_QPA_QNX_DISPLAY_CONFIG. Display order must use same + identifiers as defined for displays in graphics.conf. Number of + available displays must be specified in \a displayCount + + An example configuration is below: + \badcode + { + "displayOrder": [ 3, 1 ] + } + \endcode + + Returns ordered list of displays. If no order was specified, returns + displays in the same order as in the original list. +*/ +QList QQnxIntegration::sortDisplays(screen_display_t *availableDisplays, int displayCount) +{ + // Intermediate list for sorting + QList allDisplays; + for (int i = 0; i < displayCount; i++) + allDisplays.append(&availableDisplays[i]); + + // Read requested display order if available + QJsonArray requestedDisplays; + if (!getRequestedDisplays(requestedDisplays)) + return allDisplays; + + // Go through all the requested displays IDs + QList orderedDisplays; + for (const QJsonValue &value : qAsConst(requestedDisplays)) { + int requestedValue = value.toInt(); + + // Move all displays with matching ID from the intermediate list + // to the beginning of the ordered list + QMutableListIterator iter(allDisplays); + while (iter.hasNext()) { + screen_display_t *display = iter.next(); + if (getIdOfDisplay(*display) == requestedValue) { + orderedDisplays.append(display); + iter.remove(); + break; + } + } + } + + // Place all unordered displays to the end of list + orderedDisplays.append(allDisplays); + + return orderedDisplays; +} + void QQnxIntegration::createDisplays() { qIntegrationDebug(); @@ -508,15 +613,16 @@ void QQnxIntegration::createDisplays() screen_display_t *displays = (screen_display_t *)alloca(sizeof(screen_display_t) * displayCount); result = screen_get_context_property_pv(m_screenContext, SCREEN_PROPERTY_DISPLAYS, (void **)displays); + QList orderedDisplays = sortDisplays(displays, displayCount); Q_SCREEN_CRITICALERROR(result, "Failed to query displays"); // If it's primary, we create a QScreen for it even if it's not attached // since Qt will dereference QGuiApplication::primaryScreen() - createDisplay(displays[0], /*isPrimary=*/true); + createDisplay(*orderedDisplays[0], /*isPrimary=*/true); for (int i=1; i sortDisplays(screen_display_t *displays, + int displayCount); screen_context_t m_screenContext; QQnxScreenEventThread *m_screenEventThread; From 3e1758e35d14e6ee16e30ae2f6f6bd92d29d57f0 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Mon, 3 Dec 2018 15:40:53 +0100 Subject: [PATCH 0713/1650] QSsl: do not wait for 'connected'/'encrypted' if a protocol is disabled since we'll refuse to continue with a handshake, failing in initSslContext() on a disabled protocol versions. Then, functions like waitForEncrypted, connectToHostEncrypted, startServerEncryption and startClientEncryption should either bail out early (who needs a TCP connection which we'll abort anyway?) or bail out whenever we can, as soon as a disabled protocol was found in a configuration. This change also makes the behavior of different back-ends consistent, since it's a general code-path that reports the same SslInvalidUserData error. Update auto-test to ... actually test what it claims it tests. Task-number: QTBUG-72196 Task-number: QTBUG-72179 Change-Id: I548468993410f10c07ce5773b78f38132be8e3e0 Reviewed-by: Timur Pocheptsov --- src/network/ssl/qsslsocket.cpp | 26 +++++ src/network/ssl/qsslsocket_p.h | 1 + .../network/ssl/qsslsocket/tst_qsslsocket.cpp | 99 ++++++++++--------- 3 files changed, 82 insertions(+), 44 deletions(-) diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 068dfb9f2d..a6c86837ea 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -460,6 +460,9 @@ void QSslSocket::connectToHostEncrypted(const QString &hostName, quint16 port, O return; } + if (!d->verifyProtocolSupported("QSslSocket::connectToHostEncrypted:")) + return; + d->init(); d->autoStartHandshake = true; d->initialized = true; @@ -1607,6 +1610,8 @@ bool QSslSocket::waitForEncrypted(int msecs) return false; if (d->mode == UnencryptedMode && !d->autoStartHandshake) return false; + if (!d->verifyProtocolSupported("QSslSocket::waitForEncrypted:")) + return false; QElapsedTimer stopWatch; stopWatch.start(); @@ -1856,6 +1861,10 @@ void QSslSocket::startClientEncryption() d->setErrorAndEmit(QAbstractSocket::SslInternalError, tr("TLS initialization failed")); return; } + + if (!d->verifyProtocolSupported("QSslSocket::startClientEncryption:")) + return; + #ifdef QSSLSOCKET_DEBUG qCDebug(lcSsl) << "QSslSocket::startClientEncryption()"; #endif @@ -1899,6 +1908,9 @@ void QSslSocket::startServerEncryption() d->setErrorAndEmit(QAbstractSocket::SslInternalError, tr("TLS initialization failed")); return; } + if (!d->verifyProtocolSupported("QSslSocket::startServerEncryption")) + return; + d->mode = SslServerMode; emit modeChanged(d->mode); d->startServerEncryption(); @@ -2130,6 +2142,20 @@ void QSslSocketPrivate::init() configuration.peerCertificateChain.clear(); } +/*! + \internal +*/ +bool QSslSocketPrivate::verifyProtocolSupported(const char *where) +{ + if (configuration.protocol == QSsl::SslV2 || configuration.protocol == QSsl::SslV3) { + qCWarning(lcSsl) << where << "Attempted to use an unsupported protocol."; + setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError, + QSslSocket::tr("Attempted to use an unsupported protocol.")); + return false; + } + return true; +} + /*! \internal */ diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h index 2f394f013b..5115613695 100644 --- a/src/network/ssl/qsslsocket_p.h +++ b/src/network/ssl/qsslsocket_p.h @@ -97,6 +97,7 @@ public: virtual ~QSslSocketPrivate(); void init(); + bool verifyProtocolSupported(const char *where); bool initialized; QSslSocket::SslMode mode; diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index 0523f2591f..184f07a48e 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -245,8 +245,8 @@ private slots: void signatureAlgorithm(); #endif - void deprecatedProtocols_data(); - void deprecatedProtocols(); + void disabledProtocols_data(); + void disabledProtocols(); void setEmptyDefaultConfiguration(); // this test should be last @@ -4051,60 +4051,71 @@ void tst_QSslSocket::forwardReadChannelFinished() #endif // QT_NO_OPENSSL -void tst_QSslSocket::deprecatedProtocols_data() +void tst_QSslSocket::disabledProtocols_data() { - QTest::addColumn("protocol"); - QTest::addColumn("succeeds"); - QTest::newRow("SecureProtocols") << QSsl::SecureProtocols << true; - QTest::newRow("SslV2") << QSsl::SslV2 << false; - QTest::newRow("SslV3") << QSsl::SslV3 << false; + QTest::addColumn("disabledProtocol"); + QTest::newRow("SslV2") << QSsl::SslV2; + QTest::newRow("SslV3") << QSsl::SslV3; } -void tst_QSslSocket::deprecatedProtocols() +void tst_QSslSocket::disabledProtocols() { - QFETCH_GLOBAL(bool, setProxy); + QFETCH_GLOBAL(const bool, setProxy); if (setProxy) - QSKIP("This test does not work under a proxy"); + return; - QFETCH(QSsl::SslProtocol, protocol); - QFETCH(bool, succeeds); + QFETCH(const QSsl::SslProtocol, disabledProtocol); + const int timeoutMS = 500; + // Test a client socket. + { + // 0. connectToHostEncrypted: client-side, non-blocking API, error is discovered + // early, preventing any real connection from ever starting. + QSslSocket socket; + socket.setProtocol(disabledProtocol); + QCOMPARE(socket.error(), QAbstractSocket::UnknownSocketError); + socket.connectToHostEncrypted(QStringLiteral("doesnotmatter.org"), 1010); + QCOMPARE(socket.error(), QAbstractSocket::SslInvalidUserDataError); + QCOMPARE(socket.state(), QAbstractSocket::UnconnectedState); + } + { + // 1. startClientEncryption: client-side, non blocking API, but wants a socket in + // the 'connected' state (otherwise just returns false not setting any error code). + SslServer server; + QVERIFY(server.listen()); - QSslSocket socket; - socket.setProtocol(protocol); + QSslSocket socket; + QCOMPARE(socket.error(), QAbstractSocket::UnknownSocketError); - QSignalSpy connectedSpy(&socket, &QSslSocket::connected); - QVERIFY(connectedSpy.isValid()); + socket.connectToHost(server.serverAddress(), server.serverPort()); + QVERIFY(socket.waitForConnected(timeoutMS)); - QSignalSpy encryptedSpy(&socket, &QSslSocket::encrypted); - QVERIFY(encryptedSpy.isValid()); + socket.setProtocol(disabledProtocol); + socket.startClientEncryption(); + QCOMPARE(socket.error(), QAbstractSocket::SslInvalidUserDataError); + } + { + // 2. waitForEncrypted: client-side, blocking API plus requires from us + // to call ... connectToHostEncrypted(), which will notice an error and + // will prevent any connect at all. Nothing to test. + } - QSignalSpy errorSpy(&socket, QOverload::of(&QSslSocket::error)); - QVERIFY(errorSpy.isValid()); + // Test a server side, relatively simple: server does not connect, it listens/accepts + // and then calls startServerEncryption() (which must fall). + { + SslServer server; + server.protocol = disabledProtocol; + QVERIFY(server.listen()); - connect(&socket, QOverload &>::of(&QSslSocket::sslErrors), - &socket, QOverload<>::of(&QSslSocket::ignoreSslErrors)); + QTestEventLoop loop; + connect(&server, &SslServer::socketError, [&loop](QAbstractSocket::SocketError) + {loop.exitLoop();}); - SslServer server; - QVERIFY(server.listen()); - - socket.connectToHost(server.serverAddress(), server.serverPort()); - - // Can't use waitForConnected / waitForEncrypted as they wait forever, - // so do this asynchronously via QTRY_ macros (QTBUG-72179) - QTRY_COMPARE(connectedSpy.size(), 1); - QCOMPARE(encryptedSpy.size(), 0); - QCOMPARE(errorSpy.size(), 0); - - socket.startClientEncryption(); - - if (succeeds) { - QTRY_COMPARE(encryptedSpy.size(), 1); - QCOMPARE(errorSpy.size(), 0); - } else { - // The various backends differ in the errors fired here (QTBUG-72196), - // so just check that we did get an error (and we're not encrypted) - QTRY_VERIFY(errorSpy.size() > 0); - QCOMPARE(encryptedSpy.size(), 0); + QTcpSocket client; + client.connectToHost(server.serverAddress(), server.serverPort()); + loop.enterLoopMSecs(timeoutMS); + QVERIFY(!loop.timeout()); + QVERIFY(server.socket); + QCOMPARE(server.socket->error(), QAbstractSocket::SslInvalidUserDataError); } } From e6880e7cd145fe07651e8afdfd4a15d57b810024 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 20 Dec 2018 09:27:09 +0100 Subject: [PATCH 0714/1650] Fix text shifting vertically when elided When eliding text we would check for the existence of the ellipsis character and fall back to using the dot if it was not available. However, when font merging was in use, we would also use ellipsis from a fallback font if available. This could cause the metrics of the text to increase if the fallback font had larger metrics, and the result was that text could shift when elided. It is better to prefer the dot from the current font than to use the ellipsis from a fallback, so we only use the ellipsis if it is in the main font. [ChangeLog][QtGui][Text] Fixed a bug where eliding text could change the height of its bounding rectangle for certain fonts. Fixes: QTBUG-72553 Change-Id: Ib27fc65302465ddce661801bcc5ae32e55f1aeb9 Reviewed-by: Simon Hausmann --- src/gui/text/qtextengine.cpp | 10 +++++++ tests/auto/gui/text/qfontmetrics/testfont.qrc | 1 + .../text/qfontmetrics/tst_qfontmetrics.cpp | 27 +++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 8de16038ad..bdb5592e9e 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -3192,6 +3192,16 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int QChar ellipsisChar(0x2026); + // We only want to use the ellipsis character if it is from the main + // font (not one of the fallbacks), since using a fallback font + // will affect the metrics of the text, potentially causing it to shift + // when it is being elided. + if (engine->type() == QFontEngine::Multi) { + QFontEngineMulti *multiEngine = static_cast(engine); + multiEngine->ensureEngineAt(0); + engine = multiEngine->engine(0); + } + glyph_t glyph = engine->glyphIndex(ellipsisChar.unicode()); QGlyphLayout glyphs; diff --git a/tests/auto/gui/text/qfontmetrics/testfont.qrc b/tests/auto/gui/text/qfontmetrics/testfont.qrc index bc0c0b0959..30b4a3f82e 100644 --- a/tests/auto/gui/text/qfontmetrics/testfont.qrc +++ b/tests/auto/gui/text/qfontmetrics/testfont.qrc @@ -1,5 +1,6 @@ ucs4font.ttf + ../../../shared/resources/testfont.ttf diff --git a/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp b/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp index 9e705b4a00..a0e8525268 100644 --- a/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp +++ b/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp @@ -58,6 +58,7 @@ private slots: void lineWidth(); void mnemonicTextWidth(); void leadingBelowLine(); + void elidedMetrics(); }; void tst_QFontMetrics::same() @@ -331,5 +332,31 @@ void tst_QFontMetrics::leadingBelowLine() QCOMPARE(line.base(), line.ascent); } +void tst_QFontMetrics::elidedMetrics() +{ + QString testFont = QFINDTESTDATA("fonts/testfont.ttf"); + QVERIFY(!testFont.isEmpty()); + + int id = QFontDatabase::addApplicationFont(testFont); + QVERIFY(id >= 0); + + QFont font(QFontDatabase::applicationFontFamilies(id).at(0)); + font.setPixelSize(12.0); + + QFontMetricsF metrics(font); + QString s = QStringLiteral("VeryLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongText"); + + QRectF boundingRect = metrics.boundingRect(s); + + QString elided = metrics.elidedText(s, Qt::ElideRight, boundingRect.width() / 2.0); + + QRectF elidedBoundingRect = metrics.boundingRect(elided); + + QCOMPARE(boundingRect.height(), elidedBoundingRect.height()); + QCOMPARE(boundingRect.y(), elidedBoundingRect.y()); + + QFontDatabase::removeApplicationFont(id); +} + QTEST_MAIN(tst_QFontMetrics) #include "tst_qfontmetrics.moc" From 28b2232e7818f560bcd6c57f09ef42f2363e5338 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 20 Dec 2018 12:17:30 +0100 Subject: [PATCH 0715/1650] Don't dither antialiasing on glyphs when converting to mono When glyphs are converted to monochrome from an alpha map, it does not make sense to apply high quality dithering, because the result will be that some the subpixels along the edges that cover only part of a pixel are filled. This causes the glyphs to look jagged and ugly. Instead, we use ThresholdDither to fill all pixels that are >= 50% opacity. [ChangeLog][QtGui][Text] Improved appearance of monochrome text on some platforms. Fixes: QTBUG-69702 Change-Id: I0f44a8d73f6b9f1eb59f297d66438575f1e9db10 Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qtextureglyphcache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index 2a7e0eaa0c..99b04aaba6 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -335,7 +335,7 @@ void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g, QFixed subP // TODO optimize this mask = mask.alphaChannel(); mask.invertPixels(); - mask = mask.convertToFormat(QImage::Format_Mono); + mask = mask.convertToFormat(QImage::Format_Mono, Qt::ThresholdDither); } int mw = qMin(mask.width(), c.w); From 4aac07d0237cd4895f670ae2df6a8844ab91b699 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 2 Nov 2018 10:36:20 +0100 Subject: [PATCH 0716/1650] Android: Add support for setting/getting html and uris from clipboard This also updates the used API to use ClipData and not the deprecated ClipboardManager API. [ChangeLog][Platform Specific Changes][Android] QClipboard now supports HTML and URI data. Fixes: QTBUG-47835 Fixes: QTBUG-71503 Change-Id: I43f82bfc63b3d159087c0fb6c840c186a370e20c Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../org/qtproject/qt5/android/QtNative.java | 131 ++++++++++++++++-- .../platforms/android/androidjniclipboard.cpp | 68 ++++++--- .../platforms/android/androidjniclipboard.h | 5 +- .../android/qandroidplatformclipboard.cpp | 11 +- .../android/qandroidplatformclipboard.h | 5 +- 5 files changed, 180 insertions(+), 40 deletions(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java index adc67e93fb..5562c010aa 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java @@ -47,6 +47,7 @@ import java.util.concurrent.Semaphore; import android.app.Activity; import android.app.Service; import android.content.Context; +import android.content.ContentResolver; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ActivityInfo; @@ -57,6 +58,7 @@ import android.os.IBinder; import android.os.Looper; import android.content.ClipboardManager; import android.content.ClipboardManager.OnPrimaryClipChangedListener; +import android.content.ClipData; import android.util.Log; import android.view.ContextMenu; import android.view.KeyEvent; @@ -98,7 +100,9 @@ public class QtNative private static ClipboardManager m_clipboardManager = null; private static Method m_checkSelfPermissionMethod = null; private static Boolean m_tabletEventSupported = null; + private static boolean m_usePrimaryClip = false; public static QtThread m_qtThread = new QtThread(); + private static Method m_addItemMethod = null; private static final Runnable runPendingCppRunnablesRunnable = new Runnable() { @Override public void run() { @@ -697,26 +701,133 @@ public class QtNative } } + private static void clearClipData() + { + m_usePrimaryClip = false; + } private static void setClipboardText(String text) { - if (m_clipboardManager != null) - m_clipboardManager.setText(text); + if (m_clipboardManager != null) { + ClipData clipData = ClipData.newPlainText("text/plain", text); + updatePrimaryClip(clipData); + } } public static boolean hasClipboardText() { - if (m_clipboardManager != null) - return m_clipboardManager.hasText(); - else - return false; + if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) { + ClipData primaryClip = m_clipboardManager.getPrimaryClip(); + for (int i = 0; i < primaryClip.getItemCount(); ++i) + if (primaryClip.getItemAt(i).getText() != null) + return true; + } + return false; } private static String getClipboardText() { - if (m_clipboardManager != null) - return m_clipboardManager.getText().toString(); - else - return ""; + if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) { + ClipData primaryClip = m_clipboardManager.getPrimaryClip(); + for (int i = 0; i < primaryClip.getItemCount(); ++i) + if (primaryClip.getItemAt(i).getText() != null) + return primaryClip.getItemAt(i).getText().toString(); + } + return ""; + } + + private static void updatePrimaryClip(ClipData clipData) + { + if (m_usePrimaryClip) { + ClipData clip = m_clipboardManager.getPrimaryClip(); + if (Build.VERSION.SDK_INT >= 26) { + if (m_addItemMethod == null) { + Class[] cArg = new Class[2]; + cArg[0] = ContentResolver.class; + cArg[1] = ClipData.Item.class; + try { + m_addItemMethod = m_clipboardManager.getClass().getMethod("addItem", cArg); + } catch (Exception e) { + } + } + } + if (m_addItemMethod != null) { + try { + m_addItemMethod.invoke(m_activity.getContentResolver(), clipData.getItemAt(0)); + } catch (Exception e) { + e.printStackTrace(); + } + } else { + clip.addItem(clipData.getItemAt(0)); + } + m_clipboardManager.setPrimaryClip(clip); + } else { + m_clipboardManager.setPrimaryClip(clipData); + m_usePrimaryClip = true; + } + } + + private static void setClipboardHtml(String text, String html) + { + if (m_clipboardManager != null) { + ClipData clipData = ClipData.newHtmlText("text/html", text, html); + updatePrimaryClip(clipData); + } + } + + public static boolean hasClipboardHtml() + { + if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) { + ClipData primaryClip = m_clipboardManager.getPrimaryClip(); + for (int i = 0; i < primaryClip.getItemCount(); ++i) + if (primaryClip.getItemAt(i).getHtmlText() != null) + return true; + } + return false; + } + + private static String getClipboardHtml() + { + if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) { + ClipData primaryClip = m_clipboardManager.getPrimaryClip(); + for (int i = 0; i < primaryClip.getItemCount(); ++i) + if (primaryClip.getItemAt(i).getHtmlText() != null) + return primaryClip.getItemAt(i).getHtmlText().toString(); + } + return ""; + } + + private static void setClipboardUri(String uriString) + { + if (m_clipboardManager != null) { + ClipData clipData = ClipData.newUri(m_activity.getContentResolver(), "text/uri-list", + Uri.parse(uriString)); + updatePrimaryClip(clipData); + } + } + + public static boolean hasClipboardUri() + { + if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) { + ClipData primaryClip = m_clipboardManager.getPrimaryClip(); + for (int i = 0; i < primaryClip.getItemCount(); ++i) + if (primaryClip.getItemAt(i).getUri() != null) + return true; + } + return false; + } + + private static String[] getClipboardUris() + { + ArrayList uris = new ArrayList(); + if (m_clipboardManager != null && m_clipboardManager.hasPrimaryClip()) { + ClipData primaryClip = m_clipboardManager.getPrimaryClip(); + for (int i = 0; i < primaryClip.getItemCount(); ++i) + if (primaryClip.getItemAt(i).getUri() != null) + uris.add(primaryClip.getItemAt(i).getUri().toString()); + } + String[] strings = new String[uris.size()]; + strings = uris.toArray(strings); + return strings; } private static void openContextMenu(final int x, final int y, final int w, final int h) diff --git a/src/plugins/platforms/android/androidjniclipboard.cpp b/src/plugins/platforms/android/androidjniclipboard.cpp index d169035339..671d0b56d0 100644 --- a/src/plugins/platforms/android/androidjniclipboard.cpp +++ b/src/plugins/platforms/android/androidjniclipboard.cpp @@ -38,6 +38,7 @@ ****************************************************************************/ #include "androidjniclipboard.h" +#include #include QT_BEGIN_NAMESPACE @@ -62,27 +63,60 @@ namespace QtAndroidClipboard return; } } - - void setClipboardText(const QString &text) + void setClipboardMimeData(QMimeData *data) { - QJNIObjectPrivate::callStaticMethod(applicationClass(), - "setClipboardText", - "(Ljava/lang/String;)V", - QJNIObjectPrivate::fromString(text).object()); + QJNIObjectPrivate::callStaticMethod(applicationClass(), "clearClipData"); + if (data->hasText()) { + QJNIObjectPrivate::callStaticMethod(applicationClass(), + "setClipboardText", "(Ljava/lang/String;)V", + QJNIObjectPrivate::fromString(data->text()).object()); + } + if (data->hasHtml()) { + QJNIObjectPrivate::callStaticMethod(applicationClass(), + "setClipboardHtml", + "(Ljava/lang/String;Ljava/lang/String;)V", + QJNIObjectPrivate::fromString(data->text()).object(), + QJNIObjectPrivate::fromString(data->html()).object()); + } + if (data->hasUrls()) { + QList urls = data->urls(); + for (const auto &u : qAsConst(urls)) { + QJNIObjectPrivate::callStaticMethod(applicationClass(), "setClipboardUri", + "(Ljava/lang/String;)V", + QJNIObjectPrivate::fromString(u.toEncoded()).object()); + } + } } - bool hasClipboardText() + QMimeData *getClipboardMimeData() { - return QJNIObjectPrivate::callStaticMethod(applicationClass(), - "hasClipboardText"); - } - - QString clipboardText() - { - QJNIObjectPrivate text = QJNIObjectPrivate::callStaticObjectMethod(applicationClass(), - "getClipboardText", - "()Ljava/lang/String;"); - return text.toString(); + QMimeData *data = new QMimeData; + if (QJNIObjectPrivate::callStaticMethod(applicationClass(), "hasClipboardText")) { + data->setText(QJNIObjectPrivate::callStaticObjectMethod(applicationClass(), + "getClipboardText", + "()Ljava/lang/String;").toString()); + } + if (QJNIObjectPrivate::callStaticMethod(applicationClass(), "hasClipboardHtml")) { + data->setHtml(QJNIObjectPrivate::callStaticObjectMethod(applicationClass(), + "getClipboardHtml", + "()Ljava/lang/String;").toString()); + } + if (QJNIObjectPrivate::callStaticMethod(applicationClass(), "hasClipboardUri")) { + QJNIObjectPrivate uris = QJNIObjectPrivate::callStaticObjectMethod(applicationClass(), + "getClipboardUris", + "()[Ljava/lang/String;"); + if (uris.isValid()) { + QList urls; + QJNIEnvironmentPrivate env; + jobjectArray juris = static_cast(uris.object()); + const jint nUris = env->GetArrayLength(juris); + urls.reserve(static_cast(nUris)); + for (int i = 0; i < nUris; ++i) + urls << QUrl(QJNIObjectPrivate(env->GetObjectArrayElement(juris, i)).toString()); + data->setUrls(urls); + } + } + return data; } void onClipboardDataChanged(JNIEnv */*env*/, jobject /*thiz*/) diff --git a/src/plugins/platforms/android/androidjniclipboard.h b/src/plugins/platforms/android/androidjniclipboard.h index 2ec566e729..e83e6b555c 100644 --- a/src/plugins/platforms/android/androidjniclipboard.h +++ b/src/plugins/platforms/android/androidjniclipboard.h @@ -51,9 +51,8 @@ namespace QtAndroidClipboard { // Clipboard support void setClipboardManager(QAndroidPlatformClipboard *manager); - void setClipboardText(const QString &text); - bool hasClipboardText(); - QString clipboardText(); + void setClipboardMimeData(QMimeData *data); + QMimeData *getClipboardMimeData(); void onClipboardDataChanged(JNIEnv */*env*/, jobject /*thiz*/); // Clipboard support } diff --git a/src/plugins/platforms/android/qandroidplatformclipboard.cpp b/src/plugins/platforms/android/qandroidplatformclipboard.cpp index dc5147b259..17dfe27d12 100644 --- a/src/plugins/platforms/android/qandroidplatformclipboard.cpp +++ b/src/plugins/platforms/android/qandroidplatformclipboard.cpp @@ -52,16 +52,15 @@ QMimeData *QAndroidPlatformClipboard::mimeData(QClipboard::Mode mode) { Q_UNUSED(mode); Q_ASSERT(supportsMode(mode)); - m_mimeData.setText(QtAndroidClipboard::hasClipboardText() - ? QtAndroidClipboard::clipboardText() - : QString()); - return &m_mimeData; + QMimeData *data = QtAndroidClipboard::getClipboardMimeData(); + data->setParent(this); + return data; } void QAndroidPlatformClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode) { - if (supportsMode(mode)) - QtAndroidClipboard::setClipboardText(data != 0 && data->hasText() ? data->text() : QString()); + if (data && supportsMode(mode)) + QtAndroidClipboard::setClipboardMimeData(data); if (data != 0) data->deleteLater(); } diff --git a/src/plugins/platforms/android/qandroidplatformclipboard.h b/src/plugins/platforms/android/qandroidplatformclipboard.h index dfc3629c10..3ed9d323f8 100644 --- a/src/plugins/platforms/android/qandroidplatformclipboard.h +++ b/src/plugins/platforms/android/qandroidplatformclipboard.h @@ -46,7 +46,7 @@ #ifndef QT_NO_CLIPBOARD QT_BEGIN_NAMESPACE -class QAndroidPlatformClipboard: public QPlatformClipboard +class QAndroidPlatformClipboard : public QObject, public QPlatformClipboard { public: QAndroidPlatformClipboard(); @@ -54,9 +54,6 @@ public: QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard) override; void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard) override; bool supportsMode(QClipboard::Mode mode) const override; - -private: - QMimeData m_mimeData; }; QT_END_NAMESPACE From c879fc2ab7c5278f1a1f7727b011479a5baafc0c Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 14 Dec 2018 07:46:12 +0100 Subject: [PATCH 0717/1650] Pass the alignment to QFontMetrics::elidedText() When the text is elided, it needs to account for the mnenomic if there is one so it does not end up eliding the text unnecessarily. Change-Id: I77c15067f3e8d57d8deca83090bcb80554c3733f Reviewed-by: Christian Ehrlicher Reviewed-by: Richard Moe Gustavsen --- src/widgets/styles/qcommonstyle.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 10dfad2754..9fbbe1893a 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -1675,7 +1675,8 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, alignment |= Qt::AlignLeft | Qt::AlignVCenter; } tr.translate(shiftX, shiftY); - const QString text = toolbutton->fontMetrics.elidedText(toolbutton->text, Qt::ElideMiddle, tr.width()); + const QString text = toolbutton->fontMetrics.elidedText(toolbutton->text, Qt::ElideMiddle, + tr.width(), alignment); proxy()->drawItemText(p, QStyle::visualRect(opt->direction, rect, tr), alignment, toolbutton->palette, toolbutton->state & State_Enabled, text, QPalette::ButtonText); From 59386e090778da28daf70162807c774a034ff74c Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Mon, 17 Dec 2018 11:27:00 +0100 Subject: [PATCH 0718/1650] Fix compilation with QT_NO_COMPRESS Change-Id: Iabd57782458874abbc6b553b5e255a6b614de023 Reviewed-by: Thiago Macieira --- src/tools/rcc/rcc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp index a7919e31f9..862e574f2d 100644 --- a/src/tools/rcc/rcc.cpp +++ b/src/tools/rcc/rcc.cpp @@ -332,8 +332,8 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset, lib.m_errorDevice->write(msg.toUtf8()); } } - } #endif // QT_NO_COMPRESS + } // some info if (text || pass1) { From b337d2a88e5dba8b1e4c01ebe60a7cddc76d05d3 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 21 Dec 2018 13:02:57 -0200 Subject: [PATCH 0719/1650] Fix build with C++20 Fixes: QTBUG-72614 Change-Id: I548dbfddb69b4fd6a0a3fffd1572614a383366a5 Reviewed-by: Ville Voutilainen --- src/corelib/tools/qoffsetstringarray_p.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/corelib/tools/qoffsetstringarray_p.h b/src/corelib/tools/qoffsetstringarray_p.h index 5ca2200091..4dd9e9603b 100644 --- a/src/corelib/tools/qoffsetstringarray_p.h +++ b/src/corelib/tools/qoffsetstringarray_p.h @@ -83,8 +83,6 @@ template struct StaticString { const char data[N]; - - constexpr StaticString(const StaticString &other) noexcept = default; }; From 9ab04795e2eb8ae3fdb6ab6ef75f26db9d25e876 Mon Sep 17 00:00:00 2001 From: Antonio Larrosa Date: Fri, 21 Dec 2018 15:22:35 +0100 Subject: [PATCH 0720/1650] Fix qfloat16 methods definition without declaration when using Q_QDOC This fixes qtdoc failing to build on i586 because of an assertion in libclang since Q_QDOC is defined and thus the declaration of the qfloat16(float) constructor and operator float() are removed, thus their definitions should be removed too, which is what this patch does. Fixes: QTBUG-72725 Done-with: Michal Srb Change-Id: I6424873425d46345e09f411f9ce88f2520825da4 Reviewed-by: Thiago Macieira Reviewed-by: Jesus Fernandez --- src/corelib/global/qfloat16.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/corelib/global/qfloat16.h b/src/corelib/global/qfloat16.h index a8befd7adb..3e50ad8467 100644 --- a/src/corelib/global/qfloat16.h +++ b/src/corelib/global/qfloat16.h @@ -123,6 +123,7 @@ Q_REQUIRED_RESULT inline bool qIsNull(qfloat16 f) Q_DECL_NOTHROW inline int qIntCast(qfloat16 f) Q_DECL_NOTHROW { return int(static_cast(f)); } +#ifndef Q_QDOC QT_WARNING_PUSH QT_WARNING_DISABLE_CLANG("-Wc99-extensions") QT_WARNING_DISABLE_GCC("-Wold-style-cast") @@ -162,6 +163,7 @@ inline qfloat16::operator float() const Q_DECL_NOTHROW return f; #endif } +#endif inline qfloat16 operator-(qfloat16 a) Q_DECL_NOTHROW { From a7cea16005ea657d5de82d99a1f716a267eaf9bb Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 14 Dec 2018 12:34:55 -0800 Subject: [PATCH 0721/1650] MSVC x86: implement add_overflow for quint64 There's no 64-bit ADD instruction, so we make do with ADD+ADC. This is what Clang generates. ICC uses the two as well, but then performs some subtractions to find out if it overflowed. GCC for some inexplicable reason attempts to use SSE2 if that's enabled, otherwise it performs the subtractions like ICC. Alternative implementation which generates better code, but violates strict aliasing: uint *low = reinterpret_cast(r); uint *high = low + 1; return _addcarry_u32(_addcarry_u32(0, unsigned(v1), unsigned(v2), low), v1 >> 32, v2 >> 32, high); Manual testing shows this works. tst_qnumeric passes in debug mode. MSVC 2017 15.9 still miscompiles in release mode (reported to MS as [1]). [1] https://developercommunity.visualstudio.com/content/problem/409039/-addcarry-u32-wrong-results-with-constant-inputs.html Change-Id: I61ce366d57bc46c89db5fffd15704d53ebd4af3c Reviewed-by: Thomas Miller Reviewed-by: Allan Sandfeld Jensen --- src/corelib/global/qnumeric_p.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h index 0a6db9afcd..c762da80d3 100644 --- a/src/corelib/global/qnumeric_p.h +++ b/src/corelib/global/qnumeric_p.h @@ -373,10 +373,18 @@ template <> inline bool add_overflow(unsigned v1, unsigned v2, unsigned *r) // 32-bit mul_overflow is fine with the generic code above -# if defined(Q_PROCESSOR_X86_64) template <> inline bool add_overflow(quint64 v1, quint64 v2, quint64 *r) -{ return _addcarry_u64(0, v1, v2, reinterpret_cast(r)); } -# endif // x86-64 +{ +# if defined(Q_PROCESSOR_X86_64) + return _addcarry_u64(0, v1, v2, reinterpret_cast(r)); +# else + uint low, high; + uchar carry = _addcarry_u32(0, unsigned(v1), unsigned(v2), &low); + carry = _addcarry_u32(carry, v1 >> 32, v2 >> 32, &high); + *r = (quint64(high) << 32) | low; + return carry; +# endif // !x86-64 +} # endif // MSVC X86 #endif // !GCC } From 4a0ed282cf49c41cc8f77d71be11acc3911ccb13 Mon Sep 17 00:00:00 2001 From: Milla Pohjanheimo Date: Mon, 17 Dec 2018 10:17:47 +0200 Subject: [PATCH 0722/1650] Add binary compatibility files for 5.12 for QtBase Binary compatibility files added. Change-Id: I2543902fb7ac97270db7fb79ae09641898cc8ba4 Reviewed-by: Sergio Ahumada Reviewed-by: Simon Hausmann --- .../QtConcurrent.5.12.0.linux-gcc-amd64.txt | 4659 ++++ .../data/QtCore.5.12.0.linux-gcc-amd64.txt | 4607 ++++ .../data/QtDBus.5.12.0.linux-gcc-amd64.txt | 4946 ++++ .../bic/data/QtGui.5.12.0.linux-gcc-amd64.txt | 8422 +++++++ .../data/QtNetwork.5.12.0.linux-gcc-amd64.txt | 5509 +++++ .../data/QtOpenGL.5.12.0.linux-gcc-amd64.txt | 19441 +++++++++++++++ .../QtPrintSupport.5.12.0.linux-gcc-amd64.txt | 19692 ++++++++++++++++ .../bic/data/QtSql.5.12.0.linux-gcc-amd64.txt | 5034 ++++ .../data/QtTest.5.12.0.linux-gcc-amd64.txt | 4704 ++++ .../data/QtWidgets.5.12.0.linux-gcc-amd64.txt | 19191 +++++++++++++++ .../bic/data/QtXml.5.12.0.linux-gcc-amd64.txt | 5047 ++++ 11 files changed, 101252 insertions(+) create mode 100644 tests/auto/bic/data/QtConcurrent.5.12.0.linux-gcc-amd64.txt create mode 100644 tests/auto/bic/data/QtCore.5.12.0.linux-gcc-amd64.txt create mode 100644 tests/auto/bic/data/QtDBus.5.12.0.linux-gcc-amd64.txt create mode 100644 tests/auto/bic/data/QtGui.5.12.0.linux-gcc-amd64.txt create mode 100644 tests/auto/bic/data/QtNetwork.5.12.0.linux-gcc-amd64.txt create mode 100644 tests/auto/bic/data/QtOpenGL.5.12.0.linux-gcc-amd64.txt create mode 100644 tests/auto/bic/data/QtPrintSupport.5.12.0.linux-gcc-amd64.txt create mode 100644 tests/auto/bic/data/QtSql.5.12.0.linux-gcc-amd64.txt create mode 100644 tests/auto/bic/data/QtTest.5.12.0.linux-gcc-amd64.txt create mode 100644 tests/auto/bic/data/QtWidgets.5.12.0.linux-gcc-amd64.txt create mode 100644 tests/auto/bic/data/QtXml.5.12.0.linux-gcc-amd64.txt diff --git a/tests/auto/bic/data/QtConcurrent.5.12.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtConcurrent.5.12.0.linux-gcc-amd64.txt new file mode 100644 index 0000000000..5648f523fe --- /dev/null +++ b/tests/auto/bic/data/QtConcurrent.5.12.0.linux-gcc-amd64.txt @@ -0,0 +1,4659 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7f0f8cb872a0) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7f0f8cbcda20) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7f0f8cbcdc60) 0 empty + +Class std::__do_is_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_default_constructible_impl (0x0x7f0f8cbcdea0) 0 empty + +Class std::__do_is_static_castable_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_static_castable_impl (0x0x7f0f8a778120) 0 empty + +Class std::__do_is_direct_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_direct_constructible_impl (0x0x7f0f8a7782a0) 0 empty + +Class std::__do_is_nary_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nary_constructible_impl (0x0x7f0f8a778660) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7f0f8a801de0) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7f0f8a801ea0) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7f0f8a833240) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7f0f8a833300) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7f0f8a8333c0) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7f0f8a833480) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7f0f8a833720) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7f0f8a833900) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7f0f8a833d80) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7f0f8a833de0) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7f0f8a8eea80) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7f0f8a8eeae0) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7f0f8a7d5c30) 0 empty + std::input_iterator_tag (0x0x7f0f8a8eeb40) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7f0f8a7d5c98) 0 empty + std::forward_iterator_tag (0x0x7f0f8a7d5d00) 0 empty + std::input_iterator_tag (0x0x7f0f8a8eeba0) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7f0f8a7d5d68) 0 empty + std::bidirectional_iterator_tag (0x0x7f0f8a7d5dd0) 0 empty + std::forward_iterator_tag (0x0x7f0f8a7d5e38) 0 empty + std::input_iterator_tag (0x0x7f0f8a8eec00) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7f0f8a92d8a0) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7f0f8a92d900) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7f0f8a92d960) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7f0f8a92d9c0) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7f0f8a92da20) 0 empty + +Class wait + size=4 align=4 + base size=4 base align=4 +wait (0x0x7f0f8a60d540) 0 + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7f0f8a60d780) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7f0f8a60d840) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7f0f8a60d8a0) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7f0f8a60d960) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7f0f8a60d9c0) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7f0f8a60de40) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7f0f8a60dea0) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7f0f8a60df00) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16u) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7f0f8a92e3a8) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u) + std::exception (0x0x7f0f8a60df60) 0 nearly-empty + primary-for std::bad_exception (0x0x7f0f8a92e3a8) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7f0f8a754000) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7f0f8a754060) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16u) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7f0f8a92e5b0) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u) + std::exception (0x0x7f0f8a754480) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f0f8a92e5b0) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7f0f8a92e618) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16u) + std::bad_alloc (0x0x7f0f8a92e680) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7f0f8a92e618) + std::exception (0x0x7f0f8a7544e0) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f0f8a92e680) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7f0f8a754540) 0 empty + +Class __exception + size=40 align=8 + base size=40 base align=8 +__exception (0x0x7f0f8a421180) 0 + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7f0f8a421e40) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7f0f8a421ea0) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7f0f8a273d80) 0 + +Class __sched_param + size=4 align=4 + base size=4 base align=4 +__sched_param (0x0x7f0f8a273de0) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7f0f8a273ea0) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7f0f8a273f00) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7f0f8a273f60) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7f0f8a30c000) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7f0f8a30c120) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7f0f8a30c180) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7f0f8a30c5a0) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7f0f8a30c600) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7f0f8a13fde0) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7f0f8a13fe40) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7f0f89e0cde0) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7f0f89bb0c00) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7f0f89ba8270) 0 + std::iterator (0x0x7f0f89bb0cc0) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7f0f89ba82d8) 0 + std::_Bit_iterator_base (0x0x7f0f89ba8340) 0 + std::iterator (0x0x7f0f89bb0d20) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7f0f89ba83a8) 0 + std::_Bit_iterator_base (0x0x7f0f89ba8410) 0 + std::iterator (0x0x7f0f89bb0d80) 0 empty + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7f0f899a8ba0) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7f0f89adb960) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7f0f89adb900) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7f0f89871900) 0 + +Class qIsNull(double)::U + size=8 align=8 + base size=8 base align=8 +qIsNull(double)::U (0x0x7f0f884af420) 0 + +Class qIsNull(float)::U + size=4 align=4 + base size=4 base align=4 +qIsNull(float)::U (0x0x7f0f884af480) 0 + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7f0f88557f00) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7f0f88557f60) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7f0f8819f000) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7f0f8819f060) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7f0f8819f300) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7f0f8819f840) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7f0f881c82d8) 0 + std::__atomic_flag_base (0x0x7f0f8819f8a0) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7f0f881c8a28) 0 + QAtomicInteger (0x0x7f0f881c8a90) 0 + QBasicAtomicInteger (0x0x7f0f87dfa000) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7f0f87ccc5a0) 0 empty + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7f0f87a30780) 0 + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7f0f87a308a0) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7f0f87d51680) 0 + QGenericArgument (0x0x7f0f87a30900) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7f0f87a30a80) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7f0f87a30b40) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7f0f87b14ba0) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7f0f87b14c00) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7f0f87b14ea0) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7f0f87b14f00) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7f0f878032a0) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7f0f87803300) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7f0f87803360) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7f0f878033c0) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7f0f87803420) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7f0f878037e0) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7f0f877bdc98) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16u) + std::exception (0x0x7f0f878038a0) 0 nearly-empty + primary-for std::logic_error (0x0x7f0f877bdc98) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7f0f877bdd00) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16u) + std::logic_error (0x0x7f0f877bdd68) 0 + primary-for std::domain_error (0x0x7f0f877bdd00) + std::exception (0x0x7f0f87803900) 0 nearly-empty + primary-for std::logic_error (0x0x7f0f877bdd68) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7f0f877bddd0) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16u) + std::logic_error (0x0x7f0f877bde38) 0 + primary-for std::invalid_argument (0x0x7f0f877bddd0) + std::exception (0x0x7f0f87803960) 0 nearly-empty + primary-for std::logic_error (0x0x7f0f877bde38) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7f0f877bdea0) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16u) + std::logic_error (0x0x7f0f877bdf08) 0 + primary-for std::length_error (0x0x7f0f877bdea0) + std::exception (0x0x7f0f878039c0) 0 nearly-empty + primary-for std::logic_error (0x0x7f0f877bdf08) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7f0f877bdf70) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16u) + std::logic_error (0x0x7f0f877bd9c0) 0 + primary-for std::out_of_range (0x0x7f0f877bdf70) + std::exception (0x0x7f0f87803a20) 0 nearly-empty + primary-for std::logic_error (0x0x7f0f877bd9c0) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7f0f877bda90) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16u) + std::exception (0x0x7f0f87803a80) 0 nearly-empty + primary-for std::runtime_error (0x0x7f0f877bda90) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7f0f878f3000) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16u) + std::runtime_error (0x0x7f0f878f3068) 0 + primary-for std::range_error (0x0x7f0f878f3000) + std::exception (0x0x7f0f87803ae0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f0f878f3068) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7f0f878f30d0) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16u) + std::runtime_error (0x0x7f0f878f3138) 0 + primary-for std::overflow_error (0x0x7f0f878f30d0) + std::exception (0x0x7f0f87803b40) 0 nearly-empty + primary-for std::runtime_error (0x0x7f0f878f3138) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7f0f878f31a0) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16u) + std::runtime_error (0x0x7f0f878f3208) 0 + primary-for std::underflow_error (0x0x7f0f878f31a0) + std::exception (0x0x7f0f87803ba0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f0f878f3208) + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7f0f87803d20) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16u) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7f0f87803f60) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7f0f87924120) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7f0f878f36e8) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16u) + std::runtime_error (0x0x7f0f878f3750) 0 + primary-for std::system_error (0x0x7f0f878f36e8) + std::exception (0x0x7f0f87924360) 0 nearly-empty + primary-for std::runtime_error (0x0x7f0f878f3750) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7f0f87962340) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16u) + std::system_error (0x0x7f0f879623a8) 0 + primary-for std::ios_base::failure (0x0x7f0f87962340) + std::runtime_error (0x0x7f0f87962410) 0 + primary-for std::system_error (0x0x7f0f879623a8) + std::exception (0x0x7f0f87924660) 0 nearly-empty + primary-for std::runtime_error (0x0x7f0f87962410) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7f0f879246c0) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7f0f87924720) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7f0f87924780) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7f0f87924600) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7f0f87924f00) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7f0f87683600) 0 empty + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSo: 2u entries +0 ((& std::basic_ostream::_ZTVSo) + 24u) +8 ((& std::basic_ostream::_ZTVSo) + 64u) + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSi: 2u entries +0 ((& std::basic_istream::_ZTVSi) + 24u) +8 ((& std::basic_istream::_ZTVSi) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u) + +Construction vtable for std::basic_istream (0x0x7f0f871c8f70 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd0_Si: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7f0f871c8270 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd16_So: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSd: 7u entries +0 ((& std::basic_iostream::_ZTVSd) + 24u) +8 ((& std::basic_iostream::_ZTCSd0_Si) + 24u) +16 ((& std::basic_iostream::_ZTCSd0_Si) + 64u) +24 ((& std::basic_iostream::_ZTCSd16_So) + 24u) +32 ((& std::basic_iostream::_ZTCSd16_So) + 64u) +40 ((& std::basic_iostream::_ZTVSd) + 104u) +48 ((& std::basic_iostream::_ZTVSd) + 64u) + +Construction vtable for std::basic_istream (0x0x7f0f87278000 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7f0f872780d0 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries +0 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u) +16 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u) +24 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u) +32 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u) +40 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u) +48 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u) + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7f0f87420e40) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7f0f87420ea0) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7f0f86f9c240) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7f0f86f9c5a0) 0 + +Class QStringView + size=16 align=8 + base size=16 base align=8 +QStringView (0x0x7f0f86f9ca20) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7f0f870b98a0) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7f0f870b9f00) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7f0f870b9ea0) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7f0f86b98000) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7f0f86b98c00) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7f0f86cf78a0) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7f0f86cf7900) 0 empty + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7f0f86cf7960) 0 + +Class QListData::NotArrayCompatibleLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotArrayCompatibleLayout (0x0x7f0f86cf7d20) 0 empty + +Class QListData::NotIndirectLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotIndirectLayout (0x0x7f0f86cf7d80) 0 empty + +Class QListData::ArrayCompatibleLayout + size=1 align=1 + base size=1 base align=1 +QListData::ArrayCompatibleLayout (0x0x7f0f86cf5c98) 0 empty + QListData::NotIndirectLayout (0x0x7f0f86cf7de0) 0 empty + +Class QListData::InlineWithPaddingLayout + size=1 align=1 + base size=1 base align=1 +QListData::InlineWithPaddingLayout (0x0x7f0f86b4e3f0) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f0f86cf7e40) 0 empty + QListData::NotIndirectLayout (0x0x7f0f86cf7ea0) 0 empty + +Class QListData::IndirectLayout + size=1 align=1 + base size=1 base align=1 +QListData::IndirectLayout (0x0x7f0f86cf5d00) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f0f86cf7f00) 0 empty + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7f0f86cf7f60) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7f0f86cf7cc0) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7f0f86b60420) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7f0f86901660) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7f0f86901600) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7f0f86908750) 0 + QList (0x0x7f0f869087b8) 0 + QListSpecialMethods (0x0x7f0f86901840) 0 empty + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7f0f86901c60) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7f0f865f2840) 0 + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7f0f865f2ea0) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7f0f863c5060) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7f0f863c5120) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7f0f86908c98) 0 + std::__uses_alloc_base (0x0x7f0f863c50c0) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7f0f864b7180) 0 empty + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7f0f864b73c0) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7f0f864b7480) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7f0f864b75a0) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7f0f864b7720) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7f0f864b7b40) 0 + +Class QtMetaTypePrivate::VectorBoolElements + size=1 align=1 + base size=0 base align=1 +QtMetaTypePrivate::VectorBoolElements (0x0x7f0f864b7c60) 0 empty + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7f0f86241600) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7f0f86241a20) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7f0f86241d20) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7f0f8613c720) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7f0f85e8c5a0) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7f0f85e8c600) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16u) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7f0f85e8c7e0) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7f0f85e8c780) 0 + vptr=((& QObject::_ZTV7QObject) + 16u) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7f0f85f54a80) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7f0f85f54ae0) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7f0f85f54ba0) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7f0f85b7f2d8) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u) + QObject (0x0x7f0f85f54b40) 0 + primary-for QAbstractAnimation (0x0x7f0f85b7f2d8) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7f0f85f54c60) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7f0f85b7f340) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16u) + QObject (0x0x7f0f85f54c00) 0 + primary-for QAnimationDriver (0x0x7f0f85b7f340) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7f0f85f54d20) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7f0f85b7f3a8) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u) + QObject (0x0x7f0f85f54cc0) 0 + primary-for QEventLoop (0x0x7f0f85b7f3a8) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7f0f85f54f00) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7f0f85c0b000) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7f0f85c0b060) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7f0f85b7f4e0) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u) + QObject (0x0x7f0f85f54f60) 0 + primary-for QAbstractEventDispatcher (0x0x7f0f85b7f4e0) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7f0f85c0b300) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16u) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7f0f85b7f6e8) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16u) + std::exception (0x0x7f0f85c0b360) 0 nearly-empty + primary-for std::bad_cast (0x0x7f0f85b7f6e8) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7f0f85b7f750) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16u) + std::exception (0x0x7f0f85c0b3c0) 0 nearly-empty + primary-for std::bad_typeid (0x0x7f0f85b7f750) + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7f0f85cf29c0) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16u) + std::exception (0x0x7f0f859a3480) 0 nearly-empty + primary-for std::bad_function_call (0x0x7f0f85cf29c0) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7f0f859a3540) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7f0f859a35a0) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7f0f859a36c0) 0 + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7f0f859a3ba0) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7f0f85a5c120) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7f0f85a5c4e0) 0 + +Class QHashData + size=48 align=8 + base size=44 base align=8 +QHashData (0x0x7f0f85a5c480) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7f0f85a5c540) 0 empty + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7f0f85a5cde0) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7f0f85a5cea0) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7f0f85a5ce40) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7f0f85a5cf00) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7f0f85a5cd80) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7f0f85955a20) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7f0f855eb0c0) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7f0f855eb060) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7f0f855eb180) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7f0f855eb120) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7f0f8570f480) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7f0f8570fb40) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7f0f854f42a0) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7f0f854f2750) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u) + QObject (0x0x7f0f854f4240) 0 + primary-for QAbstractItemModel (0x0x7f0f854f2750) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7f0f854f4b40) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7f0f854f2e38) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u) + QAbstractItemModel (0x0x7f0f854f2ea0) 0 + primary-for QAbstractTableModel (0x0x7f0f854f2e38) + QObject (0x0x7f0f854f4ae0) 0 + primary-for QAbstractItemModel (0x0x7f0f854f2ea0) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7f0f854f4c00) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7f0f854f2f08) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u) + QAbstractItemModel (0x0x7f0f854f2f70) 0 + primary-for QAbstractListModel (0x0x7f0f854f2f08) + QObject (0x0x7f0f854f4ba0) 0 + primary-for QAbstractItemModel (0x0x7f0f854f2f70) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7f0f854f4ea0) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16u) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7f0f854f4f60) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7f0f852020d0) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16u) + QAbstractItemModel (0x0x7f0f85202138) 0 + primary-for QAbstractProxyModel (0x0x7f0f852020d0) + QObject (0x0x7f0f854f4f00) 0 + primary-for QAbstractItemModel (0x0x7f0f85202138) + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7f0f85250060) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7f0f852021a0) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u) + QObject (0x0x7f0f85250000) 0 + primary-for QAbstractState (0x0x7f0f852021a0) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7f0f85250120) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7f0f85202208) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u) + QObject (0x0x7f0f852500c0) 0 + primary-for QAbstractTransition (0x0x7f0f85202208) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7f0f852501e0) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7f0f85202270) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u) + QAbstractAnimation (0x0x7f0f852022d8) 0 + primary-for QAnimationGroup (0x0x7f0f85202270) + QObject (0x0x7f0f85250180) 0 + primary-for QAbstractAnimation (0x0x7f0f852022d8) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7f0f8529ef00) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7f0f852e01e0) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7f0f852e02a0) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7f0f852e05a0) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7f0f85202958) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16u) + QObject (0x0x7f0f852e0540) 0 + primary-for QIODevice (0x0x7f0f85202958) + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7f0f852e07e0) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7f0f85202a90) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16u) + QIODevice (0x0x7f0f85202af8) 0 + primary-for QBuffer (0x0x7f0f85202a90) + QObject (0x0x7f0f852e0780) 0 + primary-for QIODevice (0x0x7f0f85202af8) + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7f0f852e08a0) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7f0f852e0840) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7f0f852e09c0) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7f0f852e0960) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7f0f852e0ba0) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7f0f852e0d80) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7f0f85055060) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7f0f850557e0) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7f0f85055840) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7f0f85055780) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7f0f85114960) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7f0f85114f60) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16u) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7f0f84e32240) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7f0f84e32480) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7f0f84e32b40) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7f0f84e32cc0) 0 + +Class QDebug::Stream + size=80 align=8 + base size=76 base align=8 +QDebug::Stream (0x0x7f0f84bb4240) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7f0f84bb41e0) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7f0f84970540) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7f0f84970600) 0 empty + +Class QCborError + size=4 align=4 + base size=4 base align=4 +QCborError (0x0x7f0f849f4960) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7f0f849f4ae0) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7f0f84a81120) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7f0f84a81420) 0 + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7f0f84a817e0) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7f0f847c6ea0) 0 + +Class QCborParserError + size=16 align=8 + base size=12 base align=8 +QCborParserError (0x0x7f0f848494e0) 0 + +Class QCborValue + size=24 align=8 + base size=20 base align=8 +QCborValue (0x0x7f0f84849540) 0 + +Class QCborValueRef + size=16 align=8 + base size=16 base align=8 +QCborValueRef (0x0x7f0f846ab540) 0 + +Class QCborArray::Iterator + size=16 align=8 + base size=16 base align=8 +QCborArray::Iterator (0x0x7f0f846abae0) 0 + +Class QCborArray::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborArray::ConstIterator (0x0x7f0f846abb40) 0 + +Class QCborArray + size=8 align=8 + base size=8 base align=8 +QCborArray (0x0x7f0f846aba80) 0 + +Class QCborMap::Iterator + size=16 align=8 + base size=16 base align=8 +QCborMap::Iterator (0x0x7f0f843d8ba0) 0 + +Class QCborMap::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborMap::ConstIterator (0x0x7f0f843d8c00) 0 + +Class QCborMap + size=8 align=8 + base size=8 base align=8 +QCborMap (0x0x7f0f843d8b40) 0 + +Class qfloat16 + size=2 align=2 + base size=2 base align=2 +qfloat16 (0x0x7f0f8419f780) 0 + +Class QCborStreamWriter + size=8 align=8 + base size=8 base align=8 +QCborStreamWriter (0x0x7f0f8419fb40) 0 + +Class QCborStreamReader + size=24 align=8 + base size=20 base align=8 +QCborStreamReader (0x0x7f0f842f4540) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7f0f842f4ba0) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7f0f842f4c60) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7f0f83ff6c60) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7f0f84036120) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16u) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7f0f840350d0) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u) + QEvent (0x0x7f0f84036180) 0 + primary-for QTimerEvent (0x0x7f0f840350d0) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7f0f84035138) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u) + QEvent (0x0x7f0f840361e0) 0 + primary-for QChildEvent (0x0x7f0f84035138) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7f0f84035680) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u) + QEvent (0x0x7f0f840366c0) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7f0f84035680) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7f0f840356e8) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16u) + QEvent (0x0x7f0f84036720) 0 + primary-for QDeferredDeleteEvent (0x0x7f0f840356e8) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7f0f840367e0) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7f0f84035750) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u) + QObject (0x0x7f0f84036780) 0 + primary-for QCoreApplication (0x0x7f0f84035750) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7f0f84036840) 0 + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7f0f840368a0) 0 + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7f0f84036900) 0 + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7f0f840369c0) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7f0f84036ea0) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7f0f83d583c0) 0 + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7f0f83e81240) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7f0f83e6cbc8) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16u) + QIODevice (0x0x7f0f83e6cc30) 0 + primary-for QFileDevice (0x0x7f0f83e6cbc8) + QObject (0x0x7f0f83e811e0) 0 + primary-for QIODevice (0x0x7f0f83e6cc30) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7f0f83e81480) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7f0f83e6cd68) 0 + vptr=((& QFile::_ZTV5QFile) + 16u) + QFileDevice (0x0x7f0f83e6cdd0) 0 + primary-for QFile (0x0x7f0f83e6cd68) + QIODevice (0x0x7f0f83e6ce38) 0 + primary-for QFileDevice (0x0x7f0f83e6cdd0) + QObject (0x0x7f0f83e81420) 0 + primary-for QIODevice (0x0x7f0f83e6ce38) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7f0f83e81660) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7f0f83e81a80) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7f0f83b9f0c0) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7f0f83b9f300) 0 + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7f0f83c82720) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7f0f83c7ae38) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u) + QAbstractTransition (0x0x7f0f83c7aea0) 0 + primary-for QEventTransition (0x0x7f0f83c7ae38) + QObject (0x0x7f0f83c826c0) 0 + primary-for QAbstractTransition (0x0x7f0f83c7aea0) + +Vtable for QException +QException::_ZTV10QException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7f0f83c7af08) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16u) + std::exception (0x0x7f0f83c82780) 0 nearly-empty + primary-for QException (0x0x7f0f83c7af08) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7f0f83c7af70) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16u) + QException (0x0x7f0f83cf7000) 0 nearly-empty + primary-for QUnhandledException (0x0x7f0f83c7af70) + std::exception (0x0x7f0f83c827e0) 0 nearly-empty + primary-for QException (0x0x7f0f83cf7000) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7f0f83c82840) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7f0f83c82900) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7f0f83c82960) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7f0f83c82a80) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7f0f83cf7068) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16u) + QObject (0x0x7f0f83c82a20) 0 + primary-for QFileSelector (0x0x7f0f83cf7068) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7f0f83c82b40) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7f0f83cf70d0) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u) + QObject (0x0x7f0f83c82ae0) 0 + primary-for QFileSystemWatcher (0x0x7f0f83cf70d0) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7f0f83c82c00) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7f0f83cf7138) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16u) + QAbstractState (0x0x7f0f83cf71a0) 0 + primary-for QFinalState (0x0x7f0f83cf7138) + QObject (0x0x7f0f83c82ba0) 0 + primary-for QAbstractState (0x0x7f0f83cf71a0) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7f0f83c82c60) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16u) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7f0f83c82cc0) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7f0f83cf72d8) 0 + QBasicMutex (0x0x7f0f83c82ea0) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7f0f83c82f00) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7f0f83c82f60) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7f0f839e3000) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7f0f839e3120) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16u) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7f0f839e3960) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7f0f83ab6180) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0u +48 0u +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7f0f83ab0410) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u) + QObject (0x0x7f0f83ab6120) 0 + primary-for QFutureWatcherBase (0x0x7f0f83ab0410) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7f0f83ab6780) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7f0f83ab0d00) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u) + QAbstractState (0x0x7f0f83ab0d68) 0 + primary-for QHistoryState (0x0x7f0f83ab0d00) + QObject (0x0x7f0f83ab6720) 0 + primary-for QAbstractState (0x0x7f0f83ab0d68) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7f0f83ab6840) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7f0f83ab0dd0) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16u) + QAbstractProxyModel (0x0x7f0f83ab0e38) 0 + primary-for QIdentityProxyModel (0x0x7f0f83ab0dd0) + QAbstractItemModel (0x0x7f0f83ab0ea0) 0 + primary-for QAbstractProxyModel (0x0x7f0f83ab0e38) + QObject (0x0x7f0f83ab67e0) 0 + primary-for QAbstractItemModel (0x0x7f0f83ab0ea0) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7f0f83ab68a0) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7f0f83ab6f60) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7f0f8375b6e8) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u) + QObject (0x0x7f0f83ab6f00) 0 + primary-for QItemSelectionModel (0x0x7f0f8375b6e8) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7f0f8375b8f0) 0 + QList (0x0x7f0f8375b958) 0 + QListSpecialMethods (0x0x7f0f837b12a0) 0 empty + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7f0f837b1780) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7f0f8356cea0) 0 + +Class QJsonValuePtr + size=24 align=8 + base size=24 base align=8 +QJsonValuePtr (0x0x7f0f835e4420) 0 + +Class QJsonValueRefPtr + size=16 align=8 + base size=16 base align=8 +QJsonValueRefPtr (0x0x7f0f835e4480) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7f0f835e4660) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7f0f835e46c0) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7f0f835e4600) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7f0f836a9900) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7f0f836a9960) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7f0f83735000) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7f0f83735060) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7f0f836a9f60) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7f0f833d9300) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7f0f833cec98) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16u) + QObject (0x0x7f0f833d92a0) 0 + primary-for QLibrary (0x0x7f0f833cec98) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7f0f833d99c0) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7f0f833d94e0) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7f0f833d9ea0) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7f0f833d9f00) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7f0f834ec1e0) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7f0f834ec7e0) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7f0f8317b180) 0 + +Class QLinkedListData + size=32 align=8 + base size=25 base align=8 +QLinkedListData (0x0x7f0f8317b780) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7f0f8317bae0) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7f0f8317bc60) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7f0f8317bc00) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7f0f8317bde0) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7f0f832ff0c0) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7f0f832ff720) 0 + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7f0f832ff780) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7f0f832ffd80) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7f0f82ee80c0) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7f0f82ee8120) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7f0f82ee8420) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7f0f82e46f08) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16u) + QObject (0x0x7f0f82ee83c0) 0 + primary-for QMimeData (0x0x7f0f82e46f08) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7f0f82ee8480) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7f0f82ee8780) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7f0f82ee8840) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7f0f82f30138) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u) + QObject (0x0x7f0f82ee87e0) 0 + primary-for QObjectCleanupHandler (0x0x7f0f82f30138) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7f0f82ee88a0) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7f0f82f7d060) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7f0f82f30888) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u) + QAnimationGroup (0x0x7f0f82f308f0) 0 + primary-for QParallelAnimationGroup (0x0x7f0f82f30888) + QAbstractAnimation (0x0x7f0f82f30958) 0 + primary-for QAnimationGroup (0x0x7f0f82f308f0) + QObject (0x0x7f0f82f7d000) 0 + primary-for QAbstractAnimation (0x0x7f0f82f30958) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7f0f82f7d120) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7f0f82f309c0) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u) + QAbstractAnimation (0x0x7f0f82f30a28) 0 + primary-for QPauseAnimation (0x0x7f0f82f309c0) + QObject (0x0x7f0f82f7d0c0) 0 + primary-for QAbstractAnimation (0x0x7f0f82f30a28) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7f0f82f7d300) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7f0f82f7d600) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7f0f82f30c30) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u) + QObject (0x0x7f0f82f7d5a0) 0 + primary-for QPluginLoader (0x0x7f0f82f30c30) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7f0f82f7d660) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7f0f82f7dd20) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7f0f82fe5270) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16u) + QIODevice (0x0x7f0f82fe52d8) 0 + primary-for QProcess (0x0x7f0f82fe5270) + QObject (0x0x7f0f82f7dcc0) 0 + primary-for QIODevice (0x0x7f0f82fe52d8) + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7f0f82f7dde0) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7f0f82fe5340) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u) + QAbstractAnimation (0x0x7f0f82fe53a8) 0 + primary-for QVariantAnimation (0x0x7f0f82fe5340) + QObject (0x0x7f0f82f7dd80) 0 + primary-for QAbstractAnimation (0x0x7f0f82fe53a8) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7f0f82f7dea0) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7f0f82fe5478) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u) + QVariantAnimation (0x0x7f0f82fe54e0) 0 + primary-for QPropertyAnimation (0x0x7f0f82fe5478) + QAbstractAnimation (0x0x7f0f82fe5548) 0 + primary-for QVariantAnimation (0x0x7f0f82fe54e0) + QObject (0x0x7f0f82f7de40) 0 + primary-for QAbstractAnimation (0x0x7f0f82fe5548) + +Class QRandomGenerator::Storage + size=2504 align=8 + base size=2504 base align=8 +QRandomGenerator::Storage (0x0x7f0f82c67000) 0 + +Class QRandomGenerator + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator (0x0x7f0f82f7df60) 0 + +Class QRandomGenerator64 + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator64 (0x0x7f0f82cca820) 0 + QRandomGenerator (0x0x7f0f82caff60) 0 + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7f0f82d0d060) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7f0f82d0d300) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7f0f82d0d3c0) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7f0f82d0d480) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7f0f82d0d720) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7f0f82d0d9c0) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7f0f82d0dc60) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7f0f82d0df00) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7f0f82b530c0) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7f0f82e1a3a8) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16u) + QFileDevice (0x0x7f0f82e1a410) 0 + primary-for QSaveFile (0x0x7f0f82e1a3a8) + QIODevice (0x0x7f0f82e1a478) 0 + primary-for QFileDevice (0x0x7f0f82e1a410) + QObject (0x0x7f0f82b53060) 0 + primary-for QIODevice (0x0x7f0f82e1a478) + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7f0f82b531e0) 0 + +Class QSemaphoreReleaser + size=16 align=8 + base size=12 base align=8 +QSemaphoreReleaser (0x0x7f0f82b53360) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7f0f82896960) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7f0f82894d00) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u) + QAnimationGroup (0x0x7f0f82894d68) 0 + primary-for QSequentialAnimationGroup (0x0x7f0f82894d00) + QAbstractAnimation (0x0x7f0f82894dd0) 0 + primary-for QAnimationGroup (0x0x7f0f82894d68) + QObject (0x0x7f0f82896900) 0 + primary-for QAbstractAnimation (0x0x7f0f82894dd0) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7f0f82896a20) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7f0f82894e38) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16u) + QObject (0x0x7f0f828969c0) 0 + primary-for QSettings (0x0x7f0f82894e38) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7f0f82896ae0) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7f0f82894ea0) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u) + QObject (0x0x7f0f82896a80) 0 + primary-for QSharedMemory (0x0x7f0f82894ea0) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7f0f82896ba0) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7f0f82894f08) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u) + QObject (0x0x7f0f82896b40) 0 + primary-for QSignalMapper (0x0x7f0f82894f08) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7f0f82896c60) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7f0f82894f70) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u) + QAbstractTransition (0x0x7f0f82900000) 0 + primary-for QSignalTransition (0x0x7f0f82894f70) + QObject (0x0x7f0f82896c00) 0 + primary-for QAbstractTransition (0x0x7f0f82900000) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7f0f82896d20) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7f0f82900068) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u) + QObject (0x0x7f0f82896cc0) 0 + primary-for QSocketNotifier (0x0x7f0f82900068) + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7f0f82896de0) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7f0f829000d0) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16u) + QAbstractProxyModel (0x0x7f0f82900138) 0 + primary-for QSortFilterProxyModel (0x0x7f0f829000d0) + QAbstractItemModel (0x0x7f0f829001a0) 0 + primary-for QAbstractProxyModel (0x0x7f0f82900138) + QObject (0x0x7f0f82896d80) 0 + primary-for QAbstractItemModel (0x0x7f0f829001a0) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7f0f82896ea0) 0 empty + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7f0f82961120) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7f0f82900340) 0 + vptr=((& QState::_ZTV6QState) + 16u) + QAbstractState (0x0x7f0f829003a8) 0 + primary-for QState (0x0x7f0f82900340) + QObject (0x0x7f0f829610c0) 0 + primary-for QAbstractState (0x0x7f0f829003a8) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7f0f82961240) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7f0f82900548) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u) + QEvent (0x0x7f0f829612a0) 0 + primary-for QStateMachine::SignalEvent (0x0x7f0f82900548) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7f0f829005b0) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u) + QEvent (0x0x7f0f82961300) 0 + primary-for QStateMachine::WrappedEvent (0x0x7f0f829005b0) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7f0f82900410) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u) + QState (0x0x7f0f82900478) 0 + primary-for QStateMachine (0x0x7f0f82900410) + QAbstractState (0x0x7f0f829004e0) 0 + primary-for QState (0x0x7f0f82900478) + QObject (0x0x7f0f829611e0) 0 + primary-for QAbstractState (0x0x7f0f829004e0) + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7f0f82961360) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7f0f82a0d2a0) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7f0f8269b660) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7f0f826a15b0) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u) + QAbstractListModel (0x0x7f0f826a1618) 0 + primary-for QStringListModel (0x0x7f0f826a15b0) + QAbstractItemModel (0x0x7f0f826a1680) 0 + primary-for QAbstractListModel (0x0x7f0f826a1618) + QObject (0x0x7f0f8269b600) 0 + primary-for QAbstractItemModel (0x0x7f0f826a1680) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7f0f8269b6c0) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7f0f8269b780) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7f0f8269b8a0) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7f0f826a16e8) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u) + QFile (0x0x7f0f826a1750) 0 + primary-for QTemporaryFile (0x0x7f0f826a16e8) + QFileDevice (0x0x7f0f826a17b8) 0 + primary-for QFile (0x0x7f0f826a1750) + QIODevice (0x0x7f0f826a1820) 0 + primary-for QFileDevice (0x0x7f0f826a17b8) + QObject (0x0x7f0f8269b840) 0 + primary-for QIODevice (0x0x7f0f826a1820) + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7f0f8269b900) 0 + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7f0f8269bb40) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 0u +64 0u + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7f0f8269bae0) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7f0f8269bd20) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7f0f8269bd80) 0 + +Class std::__mutex_base + size=40 align=8 + base size=40 base align=8 +std::__mutex_base (0x0x7f0f8269bde0) 0 + +Class std::__recursive_mutex_base + size=40 align=8 + base size=40 base align=8 +std::__recursive_mutex_base (0x0x7f0f8269be40) 0 + +Class std::mutex + size=40 align=8 + base size=40 base align=8 +std::mutex (0x0x7f0f826a1a28) 0 + std::__mutex_base (0x0x7f0f8269bea0) 0 + +Class std::recursive_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_mutex (0x0x7f0f826a1a90) 0 + std::__recursive_mutex_base (0x0x7f0f8269bf00) 0 + +Class std::timed_mutex + size=40 align=8 + base size=40 base align=8 +std::timed_mutex (0x0x7f0f827a34d0) 0 + std::__mutex_base (0x0x7f0f827ab060) 0 + std::__timed_mutex_impl (0x0x7f0f827ab0c0) 0 empty + +Class std::recursive_timed_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_timed_mutex (0x0x7f0f827a3e70) 0 + std::__recursive_mutex_base (0x0x7f0f827ab180) 0 + std::__timed_mutex_impl (0x0x7f0f827ab1e0) 0 empty + +Class std::defer_lock_t + size=1 align=1 + base size=0 base align=1 +std::defer_lock_t (0x0x7f0f827ab240) 0 empty + +Class std::try_to_lock_t + size=1 align=1 + base size=0 base align=1 +std::try_to_lock_t (0x0x7f0f827ab2a0) 0 empty + +Class std::adopt_lock_t + size=1 align=1 + base size=0 base align=1 +std::adopt_lock_t (0x0x7f0f827ab300) 0 empty + +Class std::once_flag + size=4 align=4 + base size=4 base align=4 +std::once_flag (0x0x7f0f827ab540) 0 + +Vtable for __gnu_cxx::__concurrence_lock_error +__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what + +Class __gnu_cxx::__concurrence_lock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_lock_error (0x0x7f0f826a1bc8) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16u) + std::exception (0x0x7f0f827ab600) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_lock_error (0x0x7f0f826a1bc8) + +Vtable for __gnu_cxx::__concurrence_unlock_error +__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what + +Class __gnu_cxx::__concurrence_unlock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_unlock_error (0x0x7f0f826a1c30) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16u) + std::exception (0x0x7f0f827ab6c0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7f0f826a1c30) + +Vtable for __gnu_cxx::__concurrence_broadcast_error +__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what + +Class __gnu_cxx::__concurrence_broadcast_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_broadcast_error (0x0x7f0f826a1c98) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16u) + std::exception (0x0x7f0f827ab780) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7f0f826a1c98) + +Vtable for __gnu_cxx::__concurrence_wait_error +__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what + +Class __gnu_cxx::__concurrence_wait_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_wait_error (0x0x7f0f826a1d68) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16u) + std::exception (0x0x7f0f827ab840) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_wait_error (0x0x7f0f826a1d68) + +Class __gnu_cxx::__mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__mutex (0x0x7f0f827ab900) 0 + +Class __gnu_cxx::__recursive_mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__recursive_mutex (0x0x7f0f827ab960) 0 + +Class __gnu_cxx::__scoped_lock + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__scoped_lock (0x0x7f0f827ab9c0) 0 + +Class __gnu_cxx::__cond + size=48 align=8 + base size=48 base align=8 +__gnu_cxx::__cond (0x0x7f0f827aba20) 0 + +Vtable for std::bad_weak_ptr +std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12bad_weak_ptr) +16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +32 (int (*)(...))std::bad_weak_ptr::what + +Class std::bad_weak_ptr + size=8 align=8 + base size=8 base align=8 +std::bad_weak_ptr (0x0x7f0f826a1ea0) 0 nearly-empty + vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16u) + std::exception (0x0x7f0f827abd80) 0 nearly-empty + primary-for std::bad_weak_ptr (0x0x7f0f826a1ea0) + +Class std::_Sp_make_shared_tag + size=1 align=1 + base size=0 base align=1 +std::_Sp_make_shared_tag (0x0x7f0f824fd600) 0 empty + +Class std::_Sp_locker + size=2 align=1 + base size=2 base align=1 +std::_Sp_locker (0x0x7f0f824fdde0) 0 + +Class std::thread::id + size=8 align=8 + base size=8 base align=8 +std::thread::id (0x0x7f0f8228f000) 0 + +Vtable for std::thread::_Impl_base +std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6thread10_Impl_baseE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class std::thread::_Impl_base + size=24 align=8 + base size=24 base align=8 +std::thread::_Impl_base (0x0x7f0f8228f060) 0 + vptr=((& std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE) + 16u) + +Class std::thread + size=8 align=8 + base size=8 base align=8 +std::thread (0x0x7f0f824fdf60) 0 + +Class std::condition_variable + size=48 align=8 + base size=48 base align=8 +std::condition_variable (0x0x7f0f823c6c60) 0 + +Class std::__at_thread_exit_elt + size=16 align=8 + base size=16 base align=8 +std::__at_thread_exit_elt (0x0x7f0f823c6d20) 0 + +Class std::_V2::condition_variable_any + size=64 align=8 + base size=64 base align=8 +std::_V2::condition_variable_any (0x0x7f0f823c6d80) 0 + +Class std::__atomic_futex_unsigned_base + size=1 align=1 + base size=0 base align=1 +std::__atomic_futex_unsigned_base (0x0x7f0f82094420) 0 empty + +Vtable for std::future_error +std::future_error::_ZTVSt12future_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12future_error) +16 (int (*)(...))std::future_error::~future_error +24 (int (*)(...))std::future_error::~future_error +32 (int (*)(...))std::future_error::what + +Class std::future_error + size=32 align=8 + base size=32 base align=8 +std::future_error (0x0x7f0f820973a8) 0 + vptr=((& std::future_error::_ZTVSt12future_error) + 16u) + std::logic_error (0x0x7f0f82097410) 0 + primary-for std::future_error (0x0x7f0f820973a8) + std::exception (0x0x7f0f82094540) 0 nearly-empty + primary-for std::logic_error (0x0x7f0f82097410) + +Class std::__future_base::_Result_base::_Deleter + size=1 align=1 + base size=0 base align=1 +std::__future_base::_Result_base::_Deleter (0x0x7f0f82094660) 0 empty + +Vtable for std::__future_base::_Result_base +std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class std::__future_base::_Result_base + size=16 align=8 + base size=16 base align=8 +std::__future_base::_Result_base (0x0x7f0f82094600) 0 + vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16u) + +Class std::__future_base::_State_baseV2::__exception_ptr_tag + size=1 align=1 + base size=0 base align=1 +std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7f0f821f0ba0) 0 empty + +Class std::__future_base::_State_baseV2::_Make_ready + size=32 align=8 + base size=32 base align=8 +std::__future_base::_State_baseV2::_Make_ready (0x0x7f0f821f29c0) 0 + std::__at_thread_exit_elt (0x0x7f0f821f0c60) 0 + +Vtable for std::__future_base::_State_baseV2 +std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E) +16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_State_baseV2 + size=32 align=8 + base size=28 base align=8 +std::__future_base::_State_baseV2 (0x0x7f0f820947e0) 0 + vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16u) + +Class std::__future_base + size=1 align=1 + base size=0 base align=1 +std::__future_base (0x0x7f0f820945a0) 0 empty + +Vtable for std::__future_base::_Async_state_commonV2 +std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E) +16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_Async_state_commonV2 + size=48 align=8 + base size=44 base align=8 +std::__future_base::_Async_state_commonV2 (0x0x7f0f81b6c5b0) 0 + vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16u) + std::__future_base::_State_baseV2 (0x0x7f0f81b62b40) 0 + primary-for std::__future_base::_Async_state_commonV2 (0x0x7f0f81b6c5b0) + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7f0f81bca2a0) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7f0f81bf0068) 0 + vptr=((& QThread::_ZTV7QThread) + 16u) + QObject (0x0x7f0f81bca240) 0 + primary-for QThread (0x0x7f0f81bf0068) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7f0f81bca3c0) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7f0f81bf00d0) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u) + QObject (0x0x7f0f81bca360) 0 + primary-for QThreadPool (0x0x7f0f81bf00d0) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7f0f81bca420) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7f0f81bca540) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7f0f81bf0138) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u) + QObject (0x0x7f0f81bca4e0) 0 + primary-for QTimeLine (0x0x7f0f81bf0138) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7f0f81bca600) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7f0f81bf01a0) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16u) + QObject (0x0x7f0f81bca5a0) 0 + primary-for QTimer (0x0x7f0f81bf01a0) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7f0f81bcad20) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7f0f81bcacc0) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7f0f818b3300) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7f0f81bf0d68) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16u) + QObject (0x0x7f0f818b32a0) 0 + primary-for QTranslator (0x0x7f0f81bf0d68) + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7f0f818b3360) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7f0f818b39c0) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7f0f818b3a20) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7f0f818b3cc0) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7f0f818f2a28) 0 + QVector (0x0x7f0f819650c0) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7f0f81965120) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7f0f819653c0) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7f0f81965660) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7f0f81965900) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7f0f81965960) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7f0f816683c0) 0 + +Class QtConcurrent::MedianDouble + size=72 align=8 + base size=70 base align=8 +QtConcurrent::MedianDouble (0x0x7f0f816685a0) 0 + +Class QtConcurrent::ThreadEngineBarrier + size=16 align=8 + base size=16 base align=8 +QtConcurrent::ThreadEngineBarrier (0x0x7f0f81668ba0) 0 + +Vtable for QtConcurrent::ThreadEngineBase +QtConcurrent::ThreadEngineBase::_ZTVN12QtConcurrent16ThreadEngineBaseE: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN12QtConcurrent16ThreadEngineBaseE) +16 (int (*)(...))QtConcurrent::ThreadEngineBase::run +24 0u +32 0u +40 (int (*)(...))QtConcurrent::ThreadEngineBase::start +48 (int (*)(...))QtConcurrent::ThreadEngineBase::finish +56 (int (*)(...))QtConcurrent::ThreadEngineBase::threadFunction +64 (int (*)(...))QtConcurrent::ThreadEngineBase::shouldStartThread +72 (int (*)(...))QtConcurrent::ThreadEngineBase::shouldThrottleThread +80 (int (*)(...))__cxa_pure_virtual + +Class QtConcurrent::ThreadEngineBase + size=56 align=8 + base size=56 base align=8 +QtConcurrent::ThreadEngineBase (0x0x7f0f816a6340) 0 + vptr=((& QtConcurrent::ThreadEngineBase::_ZTVN12QtConcurrent16ThreadEngineBaseE) + 16u) + QRunnable (0x0x7f0f81668c00) 0 + primary-for QtConcurrent::ThreadEngineBase (0x0x7f0f816a6340) + +VTT for QtConcurrent::ThreadEngine +QtConcurrent::ThreadEngine::_ZTTN12QtConcurrent12ThreadEngineIvEE: 2u entries +0 ((& QtConcurrent::ThreadEngine::_ZTVN12QtConcurrent12ThreadEngineIvEE) + 24u) +8 ((& QtConcurrent::ThreadEngine::_ZTVN12QtConcurrent12ThreadEngineIvEE) + 136u) + +Class QtConcurrent::BlockSizeManager + size=96 align=8 + base size=92 base align=8 +QtConcurrent::BlockSizeManager (0x0x7f0f81668f60) 0 + +Class QtConcurrent::BlockSizeManagerV2 + size=176 align=8 + base size=172 base align=8 +QtConcurrent::BlockSizeManagerV2 (0x0x7f0f816ec120) 0 + +Class QtPrivate::PushBackWrapper + size=1 align=1 + base size=0 base align=1 +QtPrivate::PushBackWrapper (0x0x7f0f816ecb40) 0 empty + diff --git a/tests/auto/bic/data/QtCore.5.12.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtCore.5.12.0.linux-gcc-amd64.txt new file mode 100644 index 0000000000..93a9de90d2 --- /dev/null +++ b/tests/auto/bic/data/QtCore.5.12.0.linux-gcc-amd64.txt @@ -0,0 +1,4607 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7f10446532a0) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7f104469ba20) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7f104469bc60) 0 empty + +Class std::__do_is_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_default_constructible_impl (0x0x7f104469bea0) 0 empty + +Class std::__do_is_static_castable_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_static_castable_impl (0x0x7f1042245120) 0 empty + +Class std::__do_is_direct_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_direct_constructible_impl (0x0x7f10422452a0) 0 empty + +Class std::__do_is_nary_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nary_constructible_impl (0x0x7f1042245660) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7f10422cfde0) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7f10422cfea0) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7f1042301240) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7f1042301300) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7f10423013c0) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7f1042301480) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7f1042301720) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7f1042301900) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7f1042301d80) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7f1042301de0) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7f10423b9a80) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7f10423b9ae0) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7f10422a6bc8) 0 empty + std::input_iterator_tag (0x0x7f10423b9b40) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7f10422a6c30) 0 empty + std::forward_iterator_tag (0x0x7f10422a6c98) 0 empty + std::input_iterator_tag (0x0x7f10423b9ba0) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7f10422a6d00) 0 empty + std::bidirectional_iterator_tag (0x0x7f10422a6d68) 0 empty + std::forward_iterator_tag (0x0x7f10422a6dd0) 0 empty + std::input_iterator_tag (0x0x7f10423b9c00) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7f10423f68a0) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7f10423f6900) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7f10423f6960) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7f10423f69c0) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7f10423f6a20) 0 empty + +Class wait + size=4 align=4 + base size=4 base align=4 +wait (0x0x7f10420d7540) 0 + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7f10420d7780) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7f10420d7840) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7f10420d78a0) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7f10420d7960) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7f10420d79c0) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7f10420d7e40) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7f10420d7ea0) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7f10420d7f00) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16u) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7f10423f7340) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u) + std::exception (0x0x7f10420d7f60) 0 nearly-empty + primary-for std::bad_exception (0x0x7f10423f7340) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7f104221f000) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7f104221f060) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16u) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7f10423f7548) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u) + std::exception (0x0x7f104221f480) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f10423f7548) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7f10423f75b0) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16u) + std::bad_alloc (0x0x7f10423f7618) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7f10423f75b0) + std::exception (0x0x7f104221f4e0) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f10423f7618) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7f104221f540) 0 empty + +Class __exception + size=40 align=8 + base size=40 base align=8 +__exception (0x0x7f1041eee180) 0 + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7f1041eeee40) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7f1041eeeea0) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7f1041d40d80) 0 + +Class __sched_param + size=4 align=4 + base size=4 base align=4 +__sched_param (0x0x7f1041d40de0) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7f1041d40ea0) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7f1041d40f00) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7f1041d40f60) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7f1041dd6000) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7f1041dd6120) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7f1041dd6180) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7f1041dd65a0) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7f1041dd6600) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7f1041c09de0) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7f1041c09e40) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7f10418d8de0) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7f104167bc00) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7f104167a208) 0 + std::iterator (0x0x7f104167bcc0) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7f104167a270) 0 + std::_Bit_iterator_base (0x0x7f104167a2d8) 0 + std::iterator (0x0x7f104167bd20) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7f104167a340) 0 + std::_Bit_iterator_base (0x0x7f104167a3a8) 0 + std::iterator (0x0x7f104167bd80) 0 empty + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7f1041472ba0) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7f10415a5960) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7f10415a5900) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7f104133d900) 0 + +Class qIsNull(double)::U + size=8 align=8 + base size=8 base align=8 +qIsNull(double)::U (0x0x7f103ff7b420) 0 + +Class qIsNull(float)::U + size=4 align=4 + base size=4 base align=4 +qIsNull(float)::U (0x0x7f103ff7b480) 0 + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7f1040023f00) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7f1040023f60) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7f103fc6b000) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7f103fc6b060) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7f103fc6b300) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7f103fc6b840) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7f103fc97270) 0 + std::__atomic_flag_base (0x0x7f103fc6b8a0) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7f103fc979c0) 0 + QAtomicInteger (0x0x7f103fc97a28) 0 + QBasicAtomicInteger (0x0x7f103f8c5000) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7f103f7995a0) 0 empty + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7f103f4fb780) 0 + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7f103f4fb8a0) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7f103f4d4618) 0 + QGenericArgument (0x0x7f103f4fb900) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7f103f4fba80) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7f103f4fbb40) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7f103f5deba0) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7f103f5dec00) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7f103f5deea0) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7f103f5def00) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7f103f2ce2a0) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7f103f2ce300) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7f103f2ce360) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7f103f2ce3c0) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7f103f2ce420) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7f103f2ce7e0) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7f103f287c30) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16u) + std::exception (0x0x7f103f2ce8a0) 0 nearly-empty + primary-for std::logic_error (0x0x7f103f287c30) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7f103f287c98) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16u) + std::logic_error (0x0x7f103f287d00) 0 + primary-for std::domain_error (0x0x7f103f287c98) + std::exception (0x0x7f103f2ce900) 0 nearly-empty + primary-for std::logic_error (0x0x7f103f287d00) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7f103f287d68) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16u) + std::logic_error (0x0x7f103f287dd0) 0 + primary-for std::invalid_argument (0x0x7f103f287d68) + std::exception (0x0x7f103f2ce960) 0 nearly-empty + primary-for std::logic_error (0x0x7f103f287dd0) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7f103f287e38) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16u) + std::logic_error (0x0x7f103f287ea0) 0 + primary-for std::length_error (0x0x7f103f287e38) + std::exception (0x0x7f103f2ce9c0) 0 nearly-empty + primary-for std::logic_error (0x0x7f103f287ea0) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7f103f287f08) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16u) + std::logic_error (0x0x7f103f287f70) 0 + primary-for std::out_of_range (0x0x7f103f287f08) + std::exception (0x0x7f103f2cea20) 0 nearly-empty + primary-for std::logic_error (0x0x7f103f287f70) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7f103f287958) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16u) + std::exception (0x0x7f103f2cea80) 0 nearly-empty + primary-for std::runtime_error (0x0x7f103f287958) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7f103f287a28) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16u) + std::runtime_error (0x0x7f103f3be000) 0 + primary-for std::range_error (0x0x7f103f287a28) + std::exception (0x0x7f103f2ceae0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f103f3be000) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7f103f3be068) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16u) + std::runtime_error (0x0x7f103f3be0d0) 0 + primary-for std::overflow_error (0x0x7f103f3be068) + std::exception (0x0x7f103f2ceb40) 0 nearly-empty + primary-for std::runtime_error (0x0x7f103f3be0d0) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7f103f3be138) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16u) + std::runtime_error (0x0x7f103f3be1a0) 0 + primary-for std::underflow_error (0x0x7f103f3be138) + std::exception (0x0x7f103f2ceba0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f103f3be1a0) + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7f103f2ced20) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16u) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7f103f2cef60) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7f103f3ee120) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7f103f3be680) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16u) + std::runtime_error (0x0x7f103f3be6e8) 0 + primary-for std::system_error (0x0x7f103f3be680) + std::exception (0x0x7f103f3ee360) 0 nearly-empty + primary-for std::runtime_error (0x0x7f103f3be6e8) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7f103f42e2d8) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16u) + std::system_error (0x0x7f103f42e340) 0 + primary-for std::ios_base::failure (0x0x7f103f42e2d8) + std::runtime_error (0x0x7f103f42e3a8) 0 + primary-for std::system_error (0x0x7f103f42e340) + std::exception (0x0x7f103f3ee660) 0 nearly-empty + primary-for std::runtime_error (0x0x7f103f42e3a8) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7f103f3ee6c0) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7f103f3ee720) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7f103f3ee780) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7f103f3ee600) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7f103f3eef00) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7f103f14f600) 0 empty + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSo: 2u entries +0 ((& std::basic_ostream::_ZTVSo) + 24u) +8 ((& std::basic_ostream::_ZTVSo) + 64u) + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSi: 2u entries +0 ((& std::basic_istream::_ZTVSi) + 24u) +8 ((& std::basic_istream::_ZTVSi) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u) + +Construction vtable for std::basic_istream (0x0x7f103ec93ea0 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd0_Si: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7f103ec93f70 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd16_So: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSd: 7u entries +0 ((& std::basic_iostream::_ZTVSd) + 24u) +8 ((& std::basic_iostream::_ZTCSd0_Si) + 24u) +16 ((& std::basic_iostream::_ZTCSd0_Si) + 64u) +24 ((& std::basic_iostream::_ZTCSd16_So) + 24u) +32 ((& std::basic_iostream::_ZTCSd16_So) + 64u) +40 ((& std::basic_iostream::_ZTVSd) + 104u) +48 ((& std::basic_iostream::_ZTVSd) + 64u) + +Construction vtable for std::basic_istream (0x0x7f103ec93af8 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7f103ed40068 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries +0 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u) +16 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u) +24 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u) +32 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u) +40 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u) +48 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u) + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7f103eeece40) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7f103eeecea0) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7f103ea68240) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7f103ea685a0) 0 + +Class QStringView + size=16 align=8 + base size=16 base align=8 +QStringView (0x0x7f103ea68a20) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7f103eb848a0) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7f103eb84f00) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7f103eb84ea0) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7f103e663000) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7f103e663c00) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7f103e7c68a0) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7f103e7c6900) 0 empty + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7f103e7c6960) 0 + +Class QListData::NotArrayCompatibleLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotArrayCompatibleLayout (0x0x7f103e7c6d20) 0 empty + +Class QListData::NotIndirectLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotIndirectLayout (0x0x7f103e7c6d80) 0 empty + +Class QListData::ArrayCompatibleLayout + size=1 align=1 + base size=1 base align=1 +QListData::ArrayCompatibleLayout (0x0x7f103e7c3c30) 0 empty + QListData::NotIndirectLayout (0x0x7f103e7c6de0) 0 empty + +Class QListData::InlineWithPaddingLayout + size=1 align=1 + base size=1 base align=1 +QListData::InlineWithPaddingLayout (0x0x7f103e6193f0) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f103e7c6e40) 0 empty + QListData::NotIndirectLayout (0x0x7f103e7c6ea0) 0 empty + +Class QListData::IndirectLayout + size=1 align=1 + base size=1 base align=1 +QListData::IndirectLayout (0x0x7f103e7c3c98) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f103e7c6f00) 0 empty + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7f103e7c6f60) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7f103e7c6cc0) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7f103e62a420) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7f103e3cd660) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7f103e3cd600) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7f103e3d56e8) 0 + QList (0x0x7f103e3d5750) 0 + QListSpecialMethods (0x0x7f103e3cd840) 0 empty + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7f103e3cdc60) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7f103e0bc840) 0 + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7f103e0bcea0) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7f103de91060) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7f103de91120) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7f103e3d5bc8) 0 + std::__uses_alloc_base (0x0x7f103de910c0) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7f103df84180) 0 empty + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7f103df843c0) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7f103df84480) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7f103df845a0) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7f103df84720) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7f103df84b40) 0 + +Class QtMetaTypePrivate::VectorBoolElements + size=1 align=1 + base size=0 base align=1 +QtMetaTypePrivate::VectorBoolElements (0x0x7f103df84c60) 0 empty + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7f103dd0d600) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7f103dd0da20) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7f103dd0dd20) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7f103dc08720) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7f103d9585a0) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7f103d958600) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16u) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7f103d9587e0) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7f103d958780) 0 + vptr=((& QObject::_ZTV7QObject) + 16u) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7f103da21a80) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7f103da21ae0) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7f103da21ba0) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7f103d64c270) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u) + QObject (0x0x7f103da21b40) 0 + primary-for QAbstractAnimation (0x0x7f103d64c270) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7f103da21c60) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7f103d64c2d8) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16u) + QObject (0x0x7f103da21c00) 0 + primary-for QAnimationDriver (0x0x7f103d64c2d8) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7f103da21d20) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7f103d64c340) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u) + QObject (0x0x7f103da21cc0) 0 + primary-for QEventLoop (0x0x7f103d64c340) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7f103da21f00) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7f103d6d8000) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7f103d6d8060) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7f103d64c478) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u) + QObject (0x0x7f103da21f60) 0 + primary-for QAbstractEventDispatcher (0x0x7f103d64c478) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7f103d6d8300) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16u) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7f103d64c680) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16u) + std::exception (0x0x7f103d6d8360) 0 nearly-empty + primary-for std::bad_cast (0x0x7f103d64c680) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7f103d64c6e8) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16u) + std::exception (0x0x7f103d6d83c0) 0 nearly-empty + primary-for std::bad_typeid (0x0x7f103d64c6e8) + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7f103d7c3958) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16u) + std::exception (0x0x7f103d46f480) 0 nearly-empty + primary-for std::bad_function_call (0x0x7f103d7c3958) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7f103d46f540) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7f103d46f5a0) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7f103d46f6c0) 0 + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7f103d46fba0) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7f103d526120) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7f103d5264e0) 0 + +Class QHashData + size=48 align=8 + base size=44 base align=8 +QHashData (0x0x7f103d526480) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7f103d526540) 0 empty + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7f103d526de0) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7f103d526ea0) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7f103d526e40) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7f103d526f00) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7f103d526d80) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7f103d421a20) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7f103d0b70c0) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7f103d0b7060) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7f103d0b7180) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7f103d0b7120) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7f103d1da480) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7f103d1dab40) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7f103cfc22a0) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7f103cfc16e8) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u) + QObject (0x0x7f103cfc2240) 0 + primary-for QAbstractItemModel (0x0x7f103cfc16e8) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7f103cfc2b40) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7f103cfc1dd0) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u) + QAbstractItemModel (0x0x7f103cfc1e38) 0 + primary-for QAbstractTableModel (0x0x7f103cfc1dd0) + QObject (0x0x7f103cfc2ae0) 0 + primary-for QAbstractItemModel (0x0x7f103cfc1e38) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7f103cfc2c00) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7f103cfc1ea0) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u) + QAbstractItemModel (0x0x7f103cfc1f08) 0 + primary-for QAbstractListModel (0x0x7f103cfc1ea0) + QObject (0x0x7f103cfc2ba0) 0 + primary-for QAbstractItemModel (0x0x7f103cfc1f08) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7f103cfc2ea0) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16u) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7f103cfc2f60) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7f103ccce068) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16u) + QAbstractItemModel (0x0x7f103ccce0d0) 0 + primary-for QAbstractProxyModel (0x0x7f103ccce068) + QObject (0x0x7f103cfc2f00) 0 + primary-for QAbstractItemModel (0x0x7f103ccce0d0) + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7f103cd1a060) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7f103ccce138) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u) + QObject (0x0x7f103cd1a000) 0 + primary-for QAbstractState (0x0x7f103ccce138) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7f103cd1a120) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7f103ccce1a0) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u) + QObject (0x0x7f103cd1a0c0) 0 + primary-for QAbstractTransition (0x0x7f103ccce1a0) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7f103cd1a1e0) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7f103ccce208) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u) + QAbstractAnimation (0x0x7f103ccce270) 0 + primary-for QAnimationGroup (0x0x7f103ccce208) + QObject (0x0x7f103cd1a180) 0 + primary-for QAbstractAnimation (0x0x7f103ccce270) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7f103cd69f00) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7f103cdae1e0) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7f103cdae2a0) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7f103cdae5a0) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7f103ccce8f0) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16u) + QObject (0x0x7f103cdae540) 0 + primary-for QIODevice (0x0x7f103ccce8f0) + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7f103cdae7e0) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7f103cccea28) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16u) + QIODevice (0x0x7f103cccea90) 0 + primary-for QBuffer (0x0x7f103cccea28) + QObject (0x0x7f103cdae780) 0 + primary-for QIODevice (0x0x7f103cccea90) + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7f103cdae8a0) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7f103cdae840) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7f103cdae9c0) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7f103cdae960) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7f103cdaeba0) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7f103cdaed80) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7f103cb1e060) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7f103cb1e7e0) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7f103cb1e840) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7f103cb1e780) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7f103cbe1960) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7f103cbe1f60) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16u) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7f103c8fe240) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7f103c8fe480) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7f103c8feb40) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7f103c8fecc0) 0 + +Class QDebug::Stream + size=80 align=8 + base size=76 base align=8 +QDebug::Stream (0x0x7f103c67e240) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7f103c67e1e0) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7f103c43e540) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7f103c43e600) 0 empty + +Class QCborError + size=4 align=4 + base size=4 base align=4 +QCborError (0x0x7f103c4bf960) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7f103c4bfae0) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7f103c54b120) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7f103c54b420) 0 + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7f103c54b7e0) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7f103c293ea0) 0 + +Class QCborParserError + size=16 align=8 + base size=12 base align=8 +QCborParserError (0x0x7f103c3134e0) 0 + +Class QCborValue + size=24 align=8 + base size=20 base align=8 +QCborValue (0x0x7f103c313540) 0 + +Class QCborValueRef + size=16 align=8 + base size=16 base align=8 +QCborValueRef (0x0x7f103c175540) 0 + +Class QCborArray::Iterator + size=16 align=8 + base size=16 base align=8 +QCborArray::Iterator (0x0x7f103c175ae0) 0 + +Class QCborArray::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborArray::ConstIterator (0x0x7f103c175b40) 0 + +Class QCborArray + size=8 align=8 + base size=8 base align=8 +QCborArray (0x0x7f103c175a80) 0 + +Class QCborMap::Iterator + size=16 align=8 + base size=16 base align=8 +QCborMap::Iterator (0x0x7f103bea5ba0) 0 + +Class QCborMap::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborMap::ConstIterator (0x0x7f103bea5c00) 0 + +Class QCborMap + size=8 align=8 + base size=8 base align=8 +QCborMap (0x0x7f103bea5b40) 0 + +Class qfloat16 + size=2 align=2 + base size=2 base align=2 +qfloat16 (0x0x7f103bc69780) 0 + +Class QCborStreamWriter + size=8 align=8 + base size=8 base align=8 +QCborStreamWriter (0x0x7f103bc69b40) 0 + +Class QCborStreamReader + size=24 align=8 + base size=20 base align=8 +QCborStreamReader (0x0x7f103bdc0540) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7f103bdc0ba0) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7f103bdc0c60) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7f103bac2c60) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7f103bb00120) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16u) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7f103bb04068) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u) + QEvent (0x0x7f103bb00180) 0 + primary-for QTimerEvent (0x0x7f103bb04068) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7f103bb040d0) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u) + QEvent (0x0x7f103bb001e0) 0 + primary-for QChildEvent (0x0x7f103bb040d0) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7f103bb04618) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u) + QEvent (0x0x7f103bb006c0) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7f103bb04618) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7f103bb04680) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16u) + QEvent (0x0x7f103bb00720) 0 + primary-for QDeferredDeleteEvent (0x0x7f103bb04680) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7f103bb007e0) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7f103bb046e8) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u) + QObject (0x0x7f103bb00780) 0 + primary-for QCoreApplication (0x0x7f103bb046e8) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7f103bb00840) 0 + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7f103bb008a0) 0 + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7f103bb00900) 0 + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7f103bb009c0) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7f103bb00ea0) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7f103b8213c0) 0 + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7f103b94d240) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7f103b938b60) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16u) + QIODevice (0x0x7f103b938bc8) 0 + primary-for QFileDevice (0x0x7f103b938b60) + QObject (0x0x7f103b94d1e0) 0 + primary-for QIODevice (0x0x7f103b938bc8) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7f103b94d480) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7f103b938d00) 0 + vptr=((& QFile::_ZTV5QFile) + 16u) + QFileDevice (0x0x7f103b938d68) 0 + primary-for QFile (0x0x7f103b938d00) + QIODevice (0x0x7f103b938dd0) 0 + primary-for QFileDevice (0x0x7f103b938d68) + QObject (0x0x7f103b94d420) 0 + primary-for QIODevice (0x0x7f103b938dd0) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7f103b94d660) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7f103b94da80) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7f103b66b0c0) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7f103b66b300) 0 + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7f103b74d720) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7f103b747dd0) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u) + QAbstractTransition (0x0x7f103b747e38) 0 + primary-for QEventTransition (0x0x7f103b747dd0) + QObject (0x0x7f103b74d6c0) 0 + primary-for QAbstractTransition (0x0x7f103b747e38) + +Vtable for QException +QException::_ZTV10QException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7f103b747ea0) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16u) + std::exception (0x0x7f103b74d780) 0 nearly-empty + primary-for QException (0x0x7f103b747ea0) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7f103b747f08) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16u) + QException (0x0x7f103b747f70) 0 nearly-empty + primary-for QUnhandledException (0x0x7f103b747f08) + std::exception (0x0x7f103b74d7e0) 0 nearly-empty + primary-for QException (0x0x7f103b747f70) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7f103b74d840) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7f103b74d900) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7f103b74d960) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7f103b74da80) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7f103b7e1000) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16u) + QObject (0x0x7f103b74da20) 0 + primary-for QFileSelector (0x0x7f103b7e1000) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7f103b74db40) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7f103b7e1068) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u) + QObject (0x0x7f103b74dae0) 0 + primary-for QFileSystemWatcher (0x0x7f103b7e1068) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7f103b74dc00) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7f103b7e10d0) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16u) + QAbstractState (0x0x7f103b7e1138) 0 + primary-for QFinalState (0x0x7f103b7e10d0) + QObject (0x0x7f103b74dba0) 0 + primary-for QAbstractState (0x0x7f103b7e1138) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7f103b74dc60) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16u) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7f103b74dcc0) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7f103b7e1270) 0 + QBasicMutex (0x0x7f103b74dea0) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7f103b74df00) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7f103b74df60) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7f103b4af000) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7f103b4af120) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16u) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7f103b4af960) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7f103b582180) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0u +48 0u +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7f103b57c3a8) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u) + QObject (0x0x7f103b582120) 0 + primary-for QFutureWatcherBase (0x0x7f103b57c3a8) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7f103b582780) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7f103b57cc98) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u) + QAbstractState (0x0x7f103b57cd00) 0 + primary-for QHistoryState (0x0x7f103b57cc98) + QObject (0x0x7f103b582720) 0 + primary-for QAbstractState (0x0x7f103b57cd00) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7f103b582840) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7f103b57cd68) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16u) + QAbstractProxyModel (0x0x7f103b57cdd0) 0 + primary-for QIdentityProxyModel (0x0x7f103b57cd68) + QAbstractItemModel (0x0x7f103b57ce38) 0 + primary-for QAbstractProxyModel (0x0x7f103b57cdd0) + QObject (0x0x7f103b5827e0) 0 + primary-for QAbstractItemModel (0x0x7f103b57ce38) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7f103b5828a0) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7f103b582f60) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7f103b235680) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u) + QObject (0x0x7f103b582f00) 0 + primary-for QItemSelectionModel (0x0x7f103b235680) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7f103b235888) 0 + QList (0x0x7f103b2358f0) 0 + QListSpecialMethods (0x0x7f103b27c2a0) 0 empty + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7f103b27c780) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7f103b03aea0) 0 + +Class QJsonValuePtr + size=24 align=8 + base size=24 base align=8 +QJsonValuePtr (0x0x7f103b0b2420) 0 + +Class QJsonValueRefPtr + size=16 align=8 + base size=16 base align=8 +QJsonValueRefPtr (0x0x7f103b0b2480) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7f103b0b2660) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7f103b0b26c0) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7f103b0b2600) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7f103b172900) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7f103b172960) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7f103b200000) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7f103b200060) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7f103b172f60) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7f103aea8300) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7f103ae9ec30) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16u) + QObject (0x0x7f103aea82a0) 0 + primary-for QLibrary (0x0x7f103ae9ec30) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7f103aea89c0) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7f103aea84e0) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7f103aea8ea0) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7f103aea8f00) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7f103afb61e0) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7f103afb67e0) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7f103ac44180) 0 + +Class QLinkedListData + size=32 align=8 + base size=25 base align=8 +QLinkedListData (0x0x7f103ac44780) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7f103ac44ae0) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7f103ac44c60) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7f103ac44c00) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7f103ac44de0) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7f103adca0c0) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7f103adca720) 0 + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7f103adca780) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7f103adcad80) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7f103a9b40c0) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7f103a9b4120) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7f103a9b4420) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7f103ae15ea0) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16u) + QObject (0x0x7f103a9b43c0) 0 + primary-for QMimeData (0x0x7f103ae15ea0) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7f103a9b4480) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7f103a9b4780) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7f103a9b4840) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7f103a9ff0d0) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u) + QObject (0x0x7f103a9b47e0) 0 + primary-for QObjectCleanupHandler (0x0x7f103a9ff0d0) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7f103a9b48a0) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7f103aa4a060) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7f103a9ff820) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u) + QAnimationGroup (0x0x7f103a9ff888) 0 + primary-for QParallelAnimationGroup (0x0x7f103a9ff820) + QAbstractAnimation (0x0x7f103a9ff8f0) 0 + primary-for QAnimationGroup (0x0x7f103a9ff888) + QObject (0x0x7f103aa4a000) 0 + primary-for QAbstractAnimation (0x0x7f103a9ff8f0) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7f103aa4a120) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7f103a9ff958) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u) + QAbstractAnimation (0x0x7f103a9ff9c0) 0 + primary-for QPauseAnimation (0x0x7f103a9ff958) + QObject (0x0x7f103aa4a0c0) 0 + primary-for QAbstractAnimation (0x0x7f103a9ff9c0) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7f103aa4a300) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7f103aa4a600) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7f103a9ffbc8) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u) + QObject (0x0x7f103aa4a5a0) 0 + primary-for QPluginLoader (0x0x7f103a9ffbc8) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7f103aa4a660) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7f103aa4ad20) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7f103aab3208) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16u) + QIODevice (0x0x7f103aab3270) 0 + primary-for QProcess (0x0x7f103aab3208) + QObject (0x0x7f103aa4acc0) 0 + primary-for QIODevice (0x0x7f103aab3270) + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7f103aa4ade0) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7f103aab32d8) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u) + QAbstractAnimation (0x0x7f103aab3340) 0 + primary-for QVariantAnimation (0x0x7f103aab32d8) + QObject (0x0x7f103aa4ad80) 0 + primary-for QAbstractAnimation (0x0x7f103aab3340) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7f103aa4aea0) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7f103aab3410) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u) + QVariantAnimation (0x0x7f103aab3478) 0 + primary-for QPropertyAnimation (0x0x7f103aab3410) + QAbstractAnimation (0x0x7f103aab34e0) 0 + primary-for QVariantAnimation (0x0x7f103aab3478) + QObject (0x0x7f103aa4ae40) 0 + primary-for QAbstractAnimation (0x0x7f103aab34e0) + +Class QRandomGenerator::Storage + size=2504 align=8 + base size=2504 base align=8 +QRandomGenerator::Storage (0x0x7f103a732000) 0 + +Class QRandomGenerator + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator (0x0x7f103aa4af60) 0 + +Class QRandomGenerator64 + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator64 (0x0x7f103a7987b8) 0 + QRandomGenerator (0x0x7f103a77df60) 0 + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7f103a7d8060) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7f103a7d8300) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7f103a7d83c0) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7f103a7d8480) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7f103a7d8720) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7f103a7d89c0) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7f103a7d8c60) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7f103a7d8f00) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7f103a61d0c0) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7f103a908340) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16u) + QFileDevice (0x0x7f103a9083a8) 0 + primary-for QSaveFile (0x0x7f103a908340) + QIODevice (0x0x7f103a908410) 0 + primary-for QFileDevice (0x0x7f103a9083a8) + QObject (0x0x7f103a61d060) 0 + primary-for QIODevice (0x0x7f103a908410) + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7f103a61d1e0) 0 + +Class QSemaphoreReleaser + size=16 align=8 + base size=12 base align=8 +QSemaphoreReleaser (0x0x7f103a61d360) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7f103a364960) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7f103a360c98) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u) + QAnimationGroup (0x0x7f103a360d00) 0 + primary-for QSequentialAnimationGroup (0x0x7f103a360c98) + QAbstractAnimation (0x0x7f103a360d68) 0 + primary-for QAnimationGroup (0x0x7f103a360d00) + QObject (0x0x7f103a364900) 0 + primary-for QAbstractAnimation (0x0x7f103a360d68) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7f103a364a20) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7f103a360dd0) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16u) + QObject (0x0x7f103a3649c0) 0 + primary-for QSettings (0x0x7f103a360dd0) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7f103a364ae0) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7f103a360e38) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u) + QObject (0x0x7f103a364a80) 0 + primary-for QSharedMemory (0x0x7f103a360e38) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7f103a364ba0) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7f103a360ea0) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u) + QObject (0x0x7f103a364b40) 0 + primary-for QSignalMapper (0x0x7f103a360ea0) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7f103a364c60) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7f103a360f08) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u) + QAbstractTransition (0x0x7f103a360f70) 0 + primary-for QSignalTransition (0x0x7f103a360f08) + QObject (0x0x7f103a364c00) 0 + primary-for QAbstractTransition (0x0x7f103a360f70) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7f103a364d20) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7f103a3df000) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u) + QObject (0x0x7f103a364cc0) 0 + primary-for QSocketNotifier (0x0x7f103a3df000) + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7f103a364de0) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7f103a3df068) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16u) + QAbstractProxyModel (0x0x7f103a3df0d0) 0 + primary-for QSortFilterProxyModel (0x0x7f103a3df068) + QAbstractItemModel (0x0x7f103a3df138) 0 + primary-for QAbstractProxyModel (0x0x7f103a3df0d0) + QObject (0x0x7f103a364d80) 0 + primary-for QAbstractItemModel (0x0x7f103a3df138) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7f103a364ea0) 0 empty + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7f103a42c120) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7f103a3df2d8) 0 + vptr=((& QState::_ZTV6QState) + 16u) + QAbstractState (0x0x7f103a3df340) 0 + primary-for QState (0x0x7f103a3df2d8) + QObject (0x0x7f103a42c0c0) 0 + primary-for QAbstractState (0x0x7f103a3df340) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7f103a42c240) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7f103a3df4e0) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u) + QEvent (0x0x7f103a42c2a0) 0 + primary-for QStateMachine::SignalEvent (0x0x7f103a3df4e0) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7f103a3df548) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u) + QEvent (0x0x7f103a42c300) 0 + primary-for QStateMachine::WrappedEvent (0x0x7f103a3df548) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7f103a3df3a8) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u) + QState (0x0x7f103a3df410) 0 + primary-for QStateMachine (0x0x7f103a3df3a8) + QAbstractState (0x0x7f103a3df478) 0 + primary-for QState (0x0x7f103a3df410) + QObject (0x0x7f103a42c1e0) 0 + primary-for QAbstractState (0x0x7f103a3df478) + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7f103a42c360) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7f103a4db2a0) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7f103a168660) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7f103a16e548) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u) + QAbstractListModel (0x0x7f103a16e5b0) 0 + primary-for QStringListModel (0x0x7f103a16e548) + QAbstractItemModel (0x0x7f103a16e618) 0 + primary-for QAbstractListModel (0x0x7f103a16e5b0) + QObject (0x0x7f103a168600) 0 + primary-for QAbstractItemModel (0x0x7f103a16e618) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7f103a1686c0) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7f103a168780) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7f103a1688a0) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7f103a16e680) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u) + QFile (0x0x7f103a16e6e8) 0 + primary-for QTemporaryFile (0x0x7f103a16e680) + QFileDevice (0x0x7f103a16e750) 0 + primary-for QFile (0x0x7f103a16e6e8) + QIODevice (0x0x7f103a16e7b8) 0 + primary-for QFileDevice (0x0x7f103a16e750) + QObject (0x0x7f103a168840) 0 + primary-for QIODevice (0x0x7f103a16e7b8) + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7f103a168900) 0 + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7f103a168b40) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 0u +64 0u + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7f103a168ae0) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7f103a168d20) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7f103a168d80) 0 + +Class std::__mutex_base + size=40 align=8 + base size=40 base align=8 +std::__mutex_base (0x0x7f103a168de0) 0 + +Class std::__recursive_mutex_base + size=40 align=8 + base size=40 base align=8 +std::__recursive_mutex_base (0x0x7f103a168e40) 0 + +Class std::mutex + size=40 align=8 + base size=40 base align=8 +std::mutex (0x0x7f103a16e9c0) 0 + std::__mutex_base (0x0x7f103a168ea0) 0 + +Class std::recursive_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_mutex (0x0x7f103a16ea28) 0 + std::__recursive_mutex_base (0x0x7f103a168f00) 0 + +Class std::timed_mutex + size=40 align=8 + base size=40 base align=8 +std::timed_mutex (0x0x7f103a26f4d0) 0 + std::__mutex_base (0x0x7f103a275060) 0 + std::__timed_mutex_impl (0x0x7f103a2750c0) 0 empty + +Class std::recursive_timed_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_timed_mutex (0x0x7f103a26fe70) 0 + std::__recursive_mutex_base (0x0x7f103a275180) 0 + std::__timed_mutex_impl (0x0x7f103a2751e0) 0 empty + +Class std::defer_lock_t + size=1 align=1 + base size=0 base align=1 +std::defer_lock_t (0x0x7f103a275240) 0 empty + +Class std::try_to_lock_t + size=1 align=1 + base size=0 base align=1 +std::try_to_lock_t (0x0x7f103a2752a0) 0 empty + +Class std::adopt_lock_t + size=1 align=1 + base size=0 base align=1 +std::adopt_lock_t (0x0x7f103a275300) 0 empty + +Class std::once_flag + size=4 align=4 + base size=4 base align=4 +std::once_flag (0x0x7f103a275540) 0 + +Vtable for __gnu_cxx::__concurrence_lock_error +__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what + +Class __gnu_cxx::__concurrence_lock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_lock_error (0x0x7f103a16eb60) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16u) + std::exception (0x0x7f103a275600) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_lock_error (0x0x7f103a16eb60) + +Vtable for __gnu_cxx::__concurrence_unlock_error +__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what + +Class __gnu_cxx::__concurrence_unlock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_unlock_error (0x0x7f103a16ebc8) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16u) + std::exception (0x0x7f103a2756c0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7f103a16ebc8) + +Vtable for __gnu_cxx::__concurrence_broadcast_error +__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what + +Class __gnu_cxx::__concurrence_broadcast_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_broadcast_error (0x0x7f103a16ec30) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16u) + std::exception (0x0x7f103a275780) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7f103a16ec30) + +Vtable for __gnu_cxx::__concurrence_wait_error +__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what + +Class __gnu_cxx::__concurrence_wait_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_wait_error (0x0x7f103a16ed00) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16u) + std::exception (0x0x7f103a275840) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_wait_error (0x0x7f103a16ed00) + +Class __gnu_cxx::__mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__mutex (0x0x7f103a275900) 0 + +Class __gnu_cxx::__recursive_mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__recursive_mutex (0x0x7f103a275960) 0 + +Class __gnu_cxx::__scoped_lock + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__scoped_lock (0x0x7f103a2759c0) 0 + +Class __gnu_cxx::__cond + size=48 align=8 + base size=48 base align=8 +__gnu_cxx::__cond (0x0x7f103a275a20) 0 + +Vtable for std::bad_weak_ptr +std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12bad_weak_ptr) +16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +32 (int (*)(...))std::bad_weak_ptr::what + +Class std::bad_weak_ptr + size=8 align=8 + base size=8 base align=8 +std::bad_weak_ptr (0x0x7f103a16ee38) 0 nearly-empty + vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16u) + std::exception (0x0x7f103a275d80) 0 nearly-empty + primary-for std::bad_weak_ptr (0x0x7f103a16ee38) + +Class std::_Sp_make_shared_tag + size=1 align=1 + base size=0 base align=1 +std::_Sp_make_shared_tag (0x0x7f1039fcb600) 0 empty + +Class std::_Sp_locker + size=2 align=1 + base size=2 base align=1 +std::_Sp_locker (0x0x7f1039fcbde0) 0 + +Class std::thread::id + size=8 align=8 + base size=8 base align=8 +std::thread::id (0x0x7f1039d59000) 0 + +Vtable for std::thread::_Impl_base +std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6thread10_Impl_baseE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class std::thread::_Impl_base + size=24 align=8 + base size=24 base align=8 +std::thread::_Impl_base (0x0x7f1039d59060) 0 + vptr=((& std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE) + 16u) + +Class std::thread + size=8 align=8 + base size=8 base align=8 +std::thread (0x0x7f1039fcbf60) 0 + +Class std::condition_variable + size=48 align=8 + base size=48 base align=8 +std::condition_variable (0x0x7f1039e91c60) 0 + +Class std::__at_thread_exit_elt + size=16 align=8 + base size=16 base align=8 +std::__at_thread_exit_elt (0x0x7f1039e91d20) 0 + +Class std::_V2::condition_variable_any + size=64 align=8 + base size=64 base align=8 +std::_V2::condition_variable_any (0x0x7f1039e91d80) 0 + +Class std::__atomic_futex_unsigned_base + size=1 align=1 + base size=0 base align=1 +std::__atomic_futex_unsigned_base (0x0x7f1039b5d420) 0 empty + +Vtable for std::future_error +std::future_error::_ZTVSt12future_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12future_error) +16 (int (*)(...))std::future_error::~future_error +24 (int (*)(...))std::future_error::~future_error +32 (int (*)(...))std::future_error::what + +Class std::future_error + size=32 align=8 + base size=32 base align=8 +std::future_error (0x0x7f1039b62340) 0 + vptr=((& std::future_error::_ZTVSt12future_error) + 16u) + std::logic_error (0x0x7f1039b623a8) 0 + primary-for std::future_error (0x0x7f1039b62340) + std::exception (0x0x7f1039b5d540) 0 nearly-empty + primary-for std::logic_error (0x0x7f1039b623a8) + +Class std::__future_base::_Result_base::_Deleter + size=1 align=1 + base size=0 base align=1 +std::__future_base::_Result_base::_Deleter (0x0x7f1039b5d660) 0 empty + +Vtable for std::__future_base::_Result_base +std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class std::__future_base::_Result_base + size=16 align=8 + base size=16 base align=8 +std::__future_base::_Result_base (0x0x7f1039b5d600) 0 + vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16u) + +Class std::__future_base::_State_baseV2::__exception_ptr_tag + size=1 align=1 + base size=0 base align=1 +std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7f1039cbaba0) 0 empty + +Class std::__future_base::_State_baseV2::_Make_ready + size=32 align=8 + base size=32 base align=8 +std::__future_base::_State_baseV2::_Make_ready (0x0x7f1039cbb958) 0 + std::__at_thread_exit_elt (0x0x7f1039cbac60) 0 + +Vtable for std::__future_base::_State_baseV2 +std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E) +16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_State_baseV2 + size=32 align=8 + base size=28 base align=8 +std::__future_base::_State_baseV2 (0x0x7f1039b5d7e0) 0 + vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16u) + +Class std::__future_base + size=1 align=1 + base size=0 base align=1 +std::__future_base (0x0x7f1039b5d5a0) 0 empty + +Vtable for std::__future_base::_Async_state_commonV2 +std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E) +16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_Async_state_commonV2 + size=48 align=8 + base size=44 base align=8 +std::__future_base::_Async_state_commonV2 (0x0x7f103963a548) 0 + vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16u) + std::__future_base::_State_baseV2 (0x0x7f103962fb40) 0 + primary-for std::__future_base::_Async_state_commonV2 (0x0x7f103963a548) + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7f10396932a0) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7f10396c1000) 0 + vptr=((& QThread::_ZTV7QThread) + 16u) + QObject (0x0x7f1039693240) 0 + primary-for QThread (0x0x7f10396c1000) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7f10396933c0) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7f10396c1068) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u) + QObject (0x0x7f1039693360) 0 + primary-for QThreadPool (0x0x7f10396c1068) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7f1039693420) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7f1039693540) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7f10396c10d0) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u) + QObject (0x0x7f10396934e0) 0 + primary-for QTimeLine (0x0x7f10396c10d0) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7f1039693600) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7f10396c1138) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16u) + QObject (0x0x7f10396935a0) 0 + primary-for QTimer (0x0x7f10396c1138) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7f1039693d20) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7f1039693cc0) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7f103937e300) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7f10396c1d00) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16u) + QObject (0x0x7f103937e2a0) 0 + primary-for QTranslator (0x0x7f10396c1d00) + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7f103937e360) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7f103937e9c0) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7f103937ea20) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7f103937ecc0) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7f10393bd9c0) 0 + QVector (0x0x7f10394310c0) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7f1039431120) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7f10394313c0) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7f1039431660) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7f1039431900) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7f1039431960) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7f10391343c0) 0 + diff --git a/tests/auto/bic/data/QtDBus.5.12.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtDBus.5.12.0.linux-gcc-amd64.txt new file mode 100644 index 0000000000..6b0bf7c535 --- /dev/null +++ b/tests/auto/bic/data/QtDBus.5.12.0.linux-gcc-amd64.txt @@ -0,0 +1,4946 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7fc8a01b1540) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7fc8a01ffcc0) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7fc8a01fff00) 0 empty + +Class std::__do_is_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_default_constructible_impl (0x0x7fc89ddae180) 0 empty + +Class std::__do_is_static_castable_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_static_castable_impl (0x0x7fc89ddae3c0) 0 empty + +Class std::__do_is_direct_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_direct_constructible_impl (0x0x7fc89ddae540) 0 empty + +Class std::__do_is_nary_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nary_constructible_impl (0x0x7fc89ddae900) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7fc89de660c0) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7fc89de66180) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7fc89de664e0) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7fc89de665a0) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7fc89de66660) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7fc89de66720) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7fc89de669c0) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7fc89de66ba0) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7fc89deec060) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7fc89deec0c0) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7fc89df21d20) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7fc89df21d80) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7fc89de12d68) 0 empty + std::input_iterator_tag (0x0x7fc89df21de0) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7fc89de12dd0) 0 empty + std::forward_iterator_tag (0x0x7fc89de12e38) 0 empty + std::input_iterator_tag (0x0x7fc89df21e40) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7fc89de12ea0) 0 empty + std::bidirectional_iterator_tag (0x0x7fc89de12f08) 0 empty + std::forward_iterator_tag (0x0x7fc89de12f70) 0 empty + std::input_iterator_tag (0x0x7fc89df21ea0) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7fc89df4fb40) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7fc89df4fba0) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7fc89df4fc00) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7fc89df4fc60) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7fc89df4fcc0) 0 empty + +Class wait + size=4 align=4 + base size=4 base align=4 +wait (0x0x7fc89dc2d7e0) 0 + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7fc89dc2da20) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7fc89dc2dae0) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7fc89dc2db40) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7fc89dc2dc00) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7fc89dc2dc60) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7fc89dcc5120) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7fc89dcc5180) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7fc89dcc51e0) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16u) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7fc89df524e0) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u) + std::exception (0x0x7fc89dcc5240) 0 nearly-empty + primary-for std::bad_exception (0x0x7fc89df524e0) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7fc89dcc52a0) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7fc89dcc5300) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16u) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7fc89df526e8) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u) + std::exception (0x0x7fc89dcc5720) 0 nearly-empty + primary-for std::bad_alloc (0x0x7fc89df526e8) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7fc89df52750) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16u) + std::bad_alloc (0x0x7fc89df527b8) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7fc89df52750) + std::exception (0x0x7fc89dcc5780) 0 nearly-empty + primary-for std::bad_alloc (0x0x7fc89df527b8) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7fc89dcc57e0) 0 empty + +Class __exception + size=40 align=8 + base size=40 base align=8 +__exception (0x0x7fc89da41420) 0 + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7fc89d863120) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7fc89d863180) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7fc89d91e060) 0 + +Class __sched_param + size=4 align=4 + base size=4 base align=4 +__sched_param (0x0x7fc89d91e0c0) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7fc89d91e180) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7fc89d91e1e0) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7fc89d91e240) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7fc89d91e2a0) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7fc89d91e3c0) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7fc89d91e420) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7fc89d91e840) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7fc89d91e8a0) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7fc89d43a0c0) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7fc89d43a120) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7fc89d5190c0) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7fc89d519ea0) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7fc89d5173a8) 0 + std::iterator (0x0x7fc89d519f60) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7fc89d517410) 0 + std::_Bit_iterator_base (0x0x7fc89d517478) 0 + std::iterator (0x0x7fc89d350000) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7fc89d5174e0) 0 + std::_Bit_iterator_base (0x0x7fc89d517548) 0 + std::iterator (0x0x7fc89d350060) 0 empty + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7fc89d350e40) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7fc89d112c00) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7fc89d112ba0) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7fc89ce64ba0) 0 + +Class qIsNull(double)::U + size=8 align=8 + base size=8 base align=8 +qIsNull(double)::U (0x0x7fc89bad76c0) 0 + +Class qIsNull(float)::U + size=4 align=4 + base size=4 base align=4 +qIsNull(float)::U (0x0x7fc89bad7720) 0 + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7fc89b7b61e0) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7fc89b7b6240) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7fc89b7b62a0) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7fc89b7b6300) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7fc89b7b65a0) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7fc89b7b6ae0) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7fc89b7bd410) 0 + std::__atomic_flag_base (0x0x7fc89b7b6b40) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7fc89b7bdb60) 0 + QAtomicInteger (0x0x7fc89b7bdbc8) 0 + QBasicAtomicInteger (0x0x7fc89b39e2a0) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7fc89b2bd840) 0 empty + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7fc89b04fa20) 0 + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7fc89b04fb40) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7fc89b35b7b8) 0 + QGenericArgument (0x0x7fc89b04fba0) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7fc89b04fd20) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7fc89b04fde0) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7fc89b149e40) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7fc89b149ea0) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7fc89adf8180) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7fc89adf81e0) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7fc89adf8540) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7fc89adf85a0) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7fc89adf8600) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7fc89adf8660) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7fc89adf86c0) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7fc89adf8a80) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7fc89b16add0) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16u) + std::exception (0x0x7fc89adf8b40) 0 nearly-empty + primary-for std::logic_error (0x0x7fc89b16add0) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7fc89b16ae38) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16u) + std::logic_error (0x0x7fc89b16aea0) 0 + primary-for std::domain_error (0x0x7fc89b16ae38) + std::exception (0x0x7fc89adf8ba0) 0 nearly-empty + primary-for std::logic_error (0x0x7fc89b16aea0) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7fc89b16af08) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16u) + std::logic_error (0x0x7fc89b16af70) 0 + primary-for std::invalid_argument (0x0x7fc89b16af08) + std::exception (0x0x7fc89adf8c00) 0 nearly-empty + primary-for std::logic_error (0x0x7fc89b16af70) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7fc89b16aaf8) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16u) + std::logic_error (0x0x7fc89b16abc8) 0 + primary-for std::length_error (0x0x7fc89b16aaf8) + std::exception (0x0x7fc89adf8c60) 0 nearly-empty + primary-for std::logic_error (0x0x7fc89b16abc8) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7fc89af23000) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16u) + std::logic_error (0x0x7fc89af23068) 0 + primary-for std::out_of_range (0x0x7fc89af23000) + std::exception (0x0x7fc89adf8cc0) 0 nearly-empty + primary-for std::logic_error (0x0x7fc89af23068) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7fc89af230d0) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16u) + std::exception (0x0x7fc89adf8d20) 0 nearly-empty + primary-for std::runtime_error (0x0x7fc89af230d0) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7fc89af23138) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16u) + std::runtime_error (0x0x7fc89af231a0) 0 + primary-for std::range_error (0x0x7fc89af23138) + std::exception (0x0x7fc89adf8d80) 0 nearly-empty + primary-for std::runtime_error (0x0x7fc89af231a0) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7fc89af23208) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16u) + std::runtime_error (0x0x7fc89af23270) 0 + primary-for std::overflow_error (0x0x7fc89af23208) + std::exception (0x0x7fc89adf8de0) 0 nearly-empty + primary-for std::runtime_error (0x0x7fc89af23270) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7fc89af232d8) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16u) + std::runtime_error (0x0x7fc89af23340) 0 + primary-for std::underflow_error (0x0x7fc89af232d8) + std::exception (0x0x7fc89adf8e40) 0 nearly-empty + primary-for std::runtime_error (0x0x7fc89af23340) + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7fc89af3b000) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16u) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7fc89af3b240) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7fc89af3b3c0) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7fc89af23820) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16u) + std::runtime_error (0x0x7fc89af23888) 0 + primary-for std::system_error (0x0x7fc89af23820) + std::exception (0x0x7fc89af3b600) 0 nearly-empty + primary-for std::runtime_error (0x0x7fc89af23888) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7fc89ab9c478) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16u) + std::system_error (0x0x7fc89ab9c4e0) 0 + primary-for std::ios_base::failure (0x0x7fc89ab9c478) + std::runtime_error (0x0x7fc89ab9c548) 0 + primary-for std::system_error (0x0x7fc89ab9c4e0) + std::exception (0x0x7fc89af3b900) 0 nearly-empty + primary-for std::runtime_error (0x0x7fc89ab9c548) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7fc89af3b960) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7fc89af3b9c0) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7fc89af3ba20) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7fc89af3b8a0) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7fc89ac721e0) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7fc89ac728a0) 0 empty + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSo: 2u entries +0 ((& std::basic_ostream::_ZTVSo) + 24u) +8 ((& std::basic_ostream::_ZTVSo) + 64u) + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSi: 2u entries +0 ((& std::basic_istream::_ZTVSi) + 24u) +8 ((& std::basic_istream::_ZTVSi) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u) + +Construction vtable for std::basic_istream (0x0x7fc89a7e4478 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd0_Si: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7fc89a7e46e8 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd16_So: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSd: 7u entries +0 ((& std::basic_iostream::_ZTVSd) + 24u) +8 ((& std::basic_iostream::_ZTCSd0_Si) + 24u) +16 ((& std::basic_iostream::_ZTCSd0_Si) + 64u) +24 ((& std::basic_iostream::_ZTCSd16_So) + 24u) +32 ((& std::basic_iostream::_ZTCSd16_So) + 64u) +40 ((& std::basic_iostream::_ZTVSd) + 104u) +48 ((& std::basic_iostream::_ZTVSd) + 64u) + +Construction vtable for std::basic_istream (0x0x7fc89a89c270 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7fc89a89c340 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries +0 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u) +16 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u) +24 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u) +32 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u) +40 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u) +48 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u) + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7fc89a8c3120) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7fc89a8c3180) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7fc89a5c34e0) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7fc89a5c3840) 0 + +Class QStringView + size=16 align=8 + base size=16 base align=8 +QStringView (0x0x7fc89a5c3cc0) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7fc89a6ebb40) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7fc89a77d1e0) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7fc89a77d180) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7fc89a5282a0) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7fc89a528ea0) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7fc89a32cb40) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7fc89a32cba0) 0 empty + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7fc89a32cc00) 0 + +Class QListData::NotArrayCompatibleLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotArrayCompatibleLayout (0x0x7fc899d8d000) 0 empty + +Class QListData::NotIndirectLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotIndirectLayout (0x0x7fc899d8d060) 0 empty + +Class QListData::ArrayCompatibleLayout + size=1 align=1 + base size=1 base align=1 +QListData::ArrayCompatibleLayout (0x0x7fc89a330dd0) 0 empty + QListData::NotIndirectLayout (0x0x7fc899d8d0c0) 0 empty + +Class QListData::InlineWithPaddingLayout + size=1 align=1 + base size=1 base align=1 +QListData::InlineWithPaddingLayout (0x0x7fc89a184850) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7fc899d8d120) 0 empty + QListData::NotIndirectLayout (0x0x7fc899d8d180) 0 empty + +Class QListData::IndirectLayout + size=1 align=1 + base size=1 base align=1 +QListData::IndirectLayout (0x0x7fc89a330e38) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7fc899d8d1e0) 0 empty + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7fc899d8d240) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7fc89a32cf60) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7fc899d8d6c0) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7fc899f39900) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7fc899f398a0) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7fc899f3f888) 0 + QList (0x0x7fc899f3f8f0) 0 + QListSpecialMethods (0x0x7fc899f39ae0) 0 empty + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7fc899f39f00) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7fc899be4ae0) 0 + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7fc8999cf180) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7fc8999cf300) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7fc8999cf3c0) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7fc899a000d0) 0 + std::__uses_alloc_base (0x0x7fc8999cf360) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7fc899aeb420) 0 empty + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7fc899aeb660) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7fc899aeb720) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7fc899aeb840) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7fc899aeb9c0) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7fc899aebde0) 0 + +Class QtMetaTypePrivate::VectorBoolElements + size=1 align=1 + base size=0 base align=1 +QtMetaTypePrivate::VectorBoolElements (0x0x7fc899aebf00) 0 empty + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7fc8998448a0) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7fc899844cc0) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7fc899935000) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7fc8997569c0) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7fc8994c4840) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7fc8994c48a0) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16u) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7fc8994c4a80) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7fc8994c4a20) 0 + vptr=((& QObject::_ZTV7QObject) + 16u) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7fc89957cd20) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7fc89957cd80) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7fc89957ce40) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7fc8991bc410) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u) + QObject (0x0x7fc89957cde0) 0 + primary-for QAbstractAnimation (0x0x7fc8991bc410) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7fc89957cf00) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7fc8991bc478) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16u) + QObject (0x0x7fc89957cea0) 0 + primary-for QAnimationDriver (0x0x7fc8991bc478) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7fc89920f000) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7fc8991bc4e0) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u) + QObject (0x0x7fc89957cf60) 0 + primary-for QEventLoop (0x0x7fc8991bc4e0) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7fc89920f1e0) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7fc89920f2a0) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7fc89920f300) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7fc8991bc618) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u) + QObject (0x0x7fc89920f240) 0 + primary-for QAbstractEventDispatcher (0x0x7fc8991bc618) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7fc89920f5a0) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16u) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7fc8991bc820) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16u) + std::exception (0x0x7fc89920f600) 0 nearly-empty + primary-for std::bad_cast (0x0x7fc8991bc820) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7fc8991bc888) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16u) + std::exception (0x0x7fc89920f660) 0 nearly-empty + primary-for std::bad_typeid (0x0x7fc8991bc888) + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7fc899324af8) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16u) + std::exception (0x0x7fc898fb7720) 0 nearly-empty + primary-for std::bad_function_call (0x0x7fc899324af8) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7fc898fb77e0) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7fc898fb7840) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7fc898fb7960) 0 + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7fc898fb7e40) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7fc8990913c0) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7fc899091780) 0 + +Class QHashData + size=48 align=8 + base size=44 base align=8 +QHashData (0x0x7fc899091720) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7fc8990917e0) 0 empty + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7fc898ea60c0) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7fc898ea6180) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7fc898ea6120) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7fc898ea61e0) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7fc898ea6060) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7fc898f78cc0) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7fc898c1e360) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7fc898c1e300) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7fc898c1e420) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7fc898c1e3c0) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7fc898d41720) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7fc898d41de0) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7fc898b2e540) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7fc898b28888) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u) + QObject (0x0x7fc898b2e4e0) 0 + primary-for QAbstractItemModel (0x0x7fc898b28888) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7fc898b2ede0) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7fc898b28f70) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u) + QAbstractItemModel (0x0x7fc898808000) 0 + primary-for QAbstractTableModel (0x0x7fc898b28f70) + QObject (0x0x7fc898b2ed80) 0 + primary-for QAbstractItemModel (0x0x7fc898808000) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7fc898b2eea0) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7fc898808068) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u) + QAbstractItemModel (0x0x7fc8988080d0) 0 + primary-for QAbstractListModel (0x0x7fc898808068) + QObject (0x0x7fc898b2ee40) 0 + primary-for QAbstractItemModel (0x0x7fc8988080d0) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7fc89883d180) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16u) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7fc89883d240) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7fc898808208) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16u) + QAbstractItemModel (0x0x7fc898808270) 0 + primary-for QAbstractProxyModel (0x0x7fc898808208) + QObject (0x0x7fc89883d1e0) 0 + primary-for QAbstractItemModel (0x0x7fc898808270) + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7fc89883d300) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7fc8988082d8) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u) + QObject (0x0x7fc89883d2a0) 0 + primary-for QAbstractState (0x0x7fc8988082d8) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7fc89883d3c0) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7fc898808340) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u) + QObject (0x0x7fc89883d360) 0 + primary-for QAbstractTransition (0x0x7fc898808340) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7fc89883d480) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7fc8988083a8) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u) + QAbstractAnimation (0x0x7fc898808410) 0 + primary-for QAnimationGroup (0x0x7fc8988083a8) + QObject (0x0x7fc89883d420) 0 + primary-for QAbstractAnimation (0x0x7fc898808410) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7fc8988fa1e0) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7fc8988fa480) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7fc8988fa540) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7fc8988fa840) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7fc898808a90) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16u) + QObject (0x0x7fc8988fa7e0) 0 + primary-for QIODevice (0x0x7fc898808a90) + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7fc8988faa80) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7fc898808bc8) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16u) + QIODevice (0x0x7fc898808c30) 0 + primary-for QBuffer (0x0x7fc898808bc8) + QObject (0x0x7fc8988faa20) 0 + primary-for QIODevice (0x0x7fc898808c30) + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7fc8988fab40) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7fc8988faae0) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7fc8988fac60) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7fc8988fac00) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7fc8988fae40) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7fc898666060) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7fc898666300) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7fc898666a80) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7fc898666ae0) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7fc898666a20) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7fc89874bc00) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7fc898414240) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16u) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7fc8984144e0) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7fc898414720) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7fc898414de0) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7fc898414f60) 0 + +Class QDebug::Stream + size=80 align=8 + base size=76 base align=8 +QDebug::Stream (0x0x7fc8981a44e0) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7fc8981a4480) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7fc897fa57e0) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7fc897fa58a0) 0 empty + +Class QCborError + size=4 align=4 + base size=4 base align=4 +QCborError (0x0x7fc898029c00) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7fc898029d80) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7fc89809c3c0) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7fc89809c6c0) 0 + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7fc89809ca80) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7fc897e27180) 0 + +Class QCborParserError + size=16 align=8 + base size=12 base align=8 +QCborParserError (0x0x7fc897e27780) 0 + +Class QCborValue + size=24 align=8 + base size=20 base align=8 +QCborValue (0x0x7fc897e277e0) 0 + +Class QCborValueRef + size=16 align=8 + base size=16 base align=8 +QCborValueRef (0x0x7fc897cde7e0) 0 + +Class QCborArray::Iterator + size=16 align=8 + base size=16 base align=8 +QCborArray::Iterator (0x0x7fc897cded80) 0 + +Class QCborArray::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborArray::ConstIterator (0x0x7fc897cdede0) 0 + +Class QCborArray + size=8 align=8 + base size=8 base align=8 +QCborArray (0x0x7fc897cded20) 0 + +Class QCborMap::Iterator + size=16 align=8 + base size=16 base align=8 +QCborMap::Iterator (0x0x7fc897a11e40) 0 + +Class QCborMap::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborMap::ConstIterator (0x0x7fc897a11ea0) 0 + +Class QCborMap + size=8 align=8 + base size=8 base align=8 +QCborMap (0x0x7fc897a11de0) 0 + +Class qfloat16 + size=2 align=2 + base size=2 base align=2 +qfloat16 (0x0x7fc8977d8a20) 0 + +Class QCborStreamWriter + size=8 align=8 + base size=8 base align=8 +QCborStreamWriter (0x0x7fc8977d8de0) 0 + +Class QCborStreamReader + size=24 align=8 + base size=20 base align=8 +QCborStreamReader (0x0x7fc89792a7e0) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7fc89792ae40) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7fc89792af00) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7fc897621f00) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7fc8976663c0) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16u) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7fc89766c208) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u) + QEvent (0x0x7fc897666420) 0 + primary-for QTimerEvent (0x0x7fc89766c208) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7fc89766c270) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u) + QEvent (0x0x7fc897666480) 0 + primary-for QChildEvent (0x0x7fc89766c270) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7fc89766c7b8) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u) + QEvent (0x0x7fc897666960) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7fc89766c7b8) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7fc89766c820) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16u) + QEvent (0x0x7fc8976669c0) 0 + primary-for QDeferredDeleteEvent (0x0x7fc89766c820) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7fc897666a80) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7fc89766c888) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u) + QObject (0x0x7fc897666a20) 0 + primary-for QCoreApplication (0x0x7fc89766c888) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7fc897666ae0) 0 + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7fc897666b40) 0 + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7fc897666ba0) 0 + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7fc897666c60) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7fc897743180) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7fc897743660) 0 + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7fc8974ad4e0) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7fc8974a5d00) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16u) + QIODevice (0x0x7fc8974a5d68) 0 + primary-for QFileDevice (0x0x7fc8974a5d00) + QObject (0x0x7fc8974ad480) 0 + primary-for QIODevice (0x0x7fc8974a5d68) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7fc8974ad720) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7fc8974a5ea0) 0 + vptr=((& QFile::_ZTV5QFile) + 16u) + QFileDevice (0x0x7fc8974a5f08) 0 + primary-for QFile (0x0x7fc8974a5ea0) + QIODevice (0x0x7fc8974a5f70) 0 + primary-for QFileDevice (0x0x7fc8974a5f08) + QObject (0x0x7fc8974ad6c0) 0 + primary-for QIODevice (0x0x7fc8974a5f70) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7fc8974ad900) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7fc8974add20) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7fc8971b1360) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7fc8971b15a0) 0 + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7fc8972b79c0) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7fc8972b0f70) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u) + QAbstractTransition (0x0x7fc897319000) 0 + primary-for QEventTransition (0x0x7fc8972b0f70) + QObject (0x0x7fc8972b7960) 0 + primary-for QAbstractTransition (0x0x7fc897319000) + +Vtable for QException +QException::_ZTV10QException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7fc897319068) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16u) + std::exception (0x0x7fc8972b7a20) 0 nearly-empty + primary-for QException (0x0x7fc897319068) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7fc8973190d0) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16u) + QException (0x0x7fc897319138) 0 nearly-empty + primary-for QUnhandledException (0x0x7fc8973190d0) + std::exception (0x0x7fc8972b7a80) 0 nearly-empty + primary-for QException (0x0x7fc897319138) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7fc8972b7ae0) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7fc8972b7ba0) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7fc8972b7c00) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7fc8972b7d20) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7fc8973191a0) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16u) + QObject (0x0x7fc8972b7cc0) 0 + primary-for QFileSelector (0x0x7fc8973191a0) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7fc8972b7de0) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7fc897319208) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u) + QObject (0x0x7fc8972b7d80) 0 + primary-for QFileSystemWatcher (0x0x7fc897319208) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7fc8972b7ea0) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7fc897319270) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16u) + QAbstractState (0x0x7fc8973192d8) 0 + primary-for QFinalState (0x0x7fc897319270) + QObject (0x0x7fc8972b7e40) 0 + primary-for QAbstractState (0x0x7fc8973192d8) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7fc8972b7f00) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16u) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7fc8972b7f60) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7fc897319410) 0 + QBasicMutex (0x0x7fc896f82180) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7fc896f821e0) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7fc896f82240) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7fc896f822a0) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7fc896f823c0) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16u) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7fc896f82c00) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7fc8970ea420) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0u +48 0u +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7fc89709b548) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u) + QObject (0x0x7fc8970ea3c0) 0 + primary-for QFutureWatcherBase (0x0x7fc89709b548) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7fc8970eaa20) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7fc89709be38) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u) + QAbstractState (0x0x7fc89709bea0) 0 + primary-for QHistoryState (0x0x7fc89709be38) + QObject (0x0x7fc8970ea9c0) 0 + primary-for QAbstractState (0x0x7fc89709bea0) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7fc8970eaae0) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7fc89709bf08) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16u) + QAbstractProxyModel (0x0x7fc89709bf70) 0 + primary-for QIdentityProxyModel (0x0x7fc89709bf08) + QAbstractItemModel (0x0x7fc897162000) 0 + primary-for QAbstractProxyModel (0x0x7fc89709bf70) + QObject (0x0x7fc8970eaa80) 0 + primary-for QAbstractItemModel (0x0x7fc897162000) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7fc8970eab40) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7fc896dc8240) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7fc897162820) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u) + QObject (0x0x7fc896dc81e0) 0 + primary-for QItemSelectionModel (0x0x7fc897162820) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7fc897162a28) 0 + QList (0x0x7fc897162a90) 0 + QListSpecialMethods (0x0x7fc896dc8540) 0 empty + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7fc896dc8a20) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7fc896bcb180) 0 + +Class QJsonValuePtr + size=24 align=8 + base size=24 base align=8 +QJsonValuePtr (0x0x7fc896bcb6c0) 0 + +Class QJsonValueRefPtr + size=16 align=8 + base size=16 base align=8 +QJsonValueRefPtr (0x0x7fc896bcb720) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7fc896bcb900) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7fc896bcb960) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7fc896bcb8a0) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7fc896cdfba0) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7fc896cdfc00) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7fc896d5c2a0) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7fc896d5c300) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7fc896d5c240) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7fc896a105a0) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7fc896a08dd0) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16u) + QObject (0x0x7fc896a10540) 0 + primary-for QLibrary (0x0x7fc896a08dd0) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7fc896a10c60) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7fc896a10780) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7fc896afe180) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7fc896afe1e0) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7fc896afe480) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7fc896afea80) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7fc8967a6420) 0 + +Class QLinkedListData + size=32 align=8 + base size=25 base align=8 +QLinkedListData (0x0x7fc8967a6a20) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7fc8967a6d80) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7fc8967a6f00) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7fc8967a6ea0) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7fc8968e40c0) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7fc8968e4360) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7fc8968e49c0) 0 + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7fc8968e4a20) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7fc896513060) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7fc896513360) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7fc8965133c0) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7fc8965136c0) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7fc89653a068) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16u) + QObject (0x0x7fc896513660) 0 + primary-for QMimeData (0x0x7fc89653a068) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7fc896513720) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7fc896513a20) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7fc896513ae0) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7fc89653a270) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u) + QObject (0x0x7fc896513a80) 0 + primary-for QObjectCleanupHandler (0x0x7fc89653a270) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7fc896513b40) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7fc8965a1300) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7fc89653a9c0) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u) + QAnimationGroup (0x0x7fc89653aa28) 0 + primary-for QParallelAnimationGroup (0x0x7fc89653a9c0) + QAbstractAnimation (0x0x7fc89653aa90) 0 + primary-for QAnimationGroup (0x0x7fc89653aa28) + QObject (0x0x7fc8965a12a0) 0 + primary-for QAbstractAnimation (0x0x7fc89653aa90) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7fc8965a13c0) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7fc89653aaf8) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u) + QAbstractAnimation (0x0x7fc89653ab60) 0 + primary-for QPauseAnimation (0x0x7fc89653aaf8) + QObject (0x0x7fc8965a1360) 0 + primary-for QAbstractAnimation (0x0x7fc89653ab60) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7fc8965a15a0) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7fc8965a18a0) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7fc89653ad68) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u) + QObject (0x0x7fc8965a1840) 0 + primary-for QPluginLoader (0x0x7fc89653ad68) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7fc8965a1900) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7fc89662c000) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7fc89661f3a8) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16u) + QIODevice (0x0x7fc89661f410) 0 + primary-for QProcess (0x0x7fc89661f3a8) + QObject (0x0x7fc8965a1f60) 0 + primary-for QIODevice (0x0x7fc89661f410) + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7fc89662c0c0) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7fc89661f478) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u) + QAbstractAnimation (0x0x7fc89661f4e0) 0 + primary-for QVariantAnimation (0x0x7fc89661f478) + QObject (0x0x7fc89662c060) 0 + primary-for QAbstractAnimation (0x0x7fc89661f4e0) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7fc89662c180) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7fc89661f5b0) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u) + QVariantAnimation (0x0x7fc89661f618) 0 + primary-for QPropertyAnimation (0x0x7fc89661f5b0) + QAbstractAnimation (0x0x7fc89661f680) 0 + primary-for QVariantAnimation (0x0x7fc89661f618) + QObject (0x0x7fc89662c120) 0 + primary-for QAbstractAnimation (0x0x7fc89661f680) + +Class QRandomGenerator::Storage + size=2504 align=8 + base size=2504 base align=8 +QRandomGenerator::Storage (0x0x7fc89662c2a0) 0 + +Class QRandomGenerator + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator (0x0x7fc89662c240) 0 + +Class QRandomGenerator64 + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator64 (0x0x7fc896302958) 0 + QRandomGenerator (0x0x7fc89631e240) 0 + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7fc89631e300) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7fc89631e5a0) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7fc89631e660) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7fc89631e720) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7fc89631e9c0) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7fc89631ec60) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7fc89631ef00) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7fc8961131e0) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7fc896113360) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7fc8964504e0) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16u) + QFileDevice (0x0x7fc896450548) 0 + primary-for QSaveFile (0x0x7fc8964504e0) + QIODevice (0x0x7fc8964505b0) 0 + primary-for QFileDevice (0x0x7fc896450548) + QObject (0x0x7fc896113300) 0 + primary-for QIODevice (0x0x7fc8964505b0) + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7fc896113480) 0 + +Class QSemaphoreReleaser + size=16 align=8 + base size=12 base align=8 +QSemaphoreReleaser (0x0x7fc896113600) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7fc895ec3c00) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7fc895ec0e38) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u) + QAnimationGroup (0x0x7fc895ec0ea0) 0 + primary-for QSequentialAnimationGroup (0x0x7fc895ec0e38) + QAbstractAnimation (0x0x7fc895ec0f08) 0 + primary-for QAnimationGroup (0x0x7fc895ec0ea0) + QObject (0x0x7fc895ec3ba0) 0 + primary-for QAbstractAnimation (0x0x7fc895ec0f08) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7fc895ec3cc0) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7fc895ec0f70) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16u) + QObject (0x0x7fc895ec3c60) 0 + primary-for QSettings (0x0x7fc895ec0f70) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7fc895ec3d80) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7fc895f18000) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u) + QObject (0x0x7fc895ec3d20) 0 + primary-for QSharedMemory (0x0x7fc895f18000) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7fc895ec3e40) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7fc895f18068) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u) + QObject (0x0x7fc895ec3de0) 0 + primary-for QSignalMapper (0x0x7fc895f18068) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7fc895ec3f00) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7fc895f180d0) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u) + QAbstractTransition (0x0x7fc895f18138) 0 + primary-for QSignalTransition (0x0x7fc895f180d0) + QObject (0x0x7fc895ec3ea0) 0 + primary-for QAbstractTransition (0x0x7fc895f18138) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7fc895f50000) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7fc895f181a0) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u) + QObject (0x0x7fc895ec3f60) 0 + primary-for QSocketNotifier (0x0x7fc895f181a0) + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7fc895f500c0) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7fc895f18208) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16u) + QAbstractProxyModel (0x0x7fc895f18270) 0 + primary-for QSortFilterProxyModel (0x0x7fc895f18208) + QAbstractItemModel (0x0x7fc895f182d8) 0 + primary-for QAbstractProxyModel (0x0x7fc895f18270) + QObject (0x0x7fc895f50060) 0 + primary-for QAbstractItemModel (0x0x7fc895f182d8) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7fc895f50180) 0 empty + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7fc895f503c0) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7fc895f18478) 0 + vptr=((& QState::_ZTV6QState) + 16u) + QAbstractState (0x0x7fc895f184e0) 0 + primary-for QState (0x0x7fc895f18478) + QObject (0x0x7fc895f50360) 0 + primary-for QAbstractState (0x0x7fc895f184e0) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7fc895f504e0) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7fc895f18680) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u) + QEvent (0x0x7fc895f50540) 0 + primary-for QStateMachine::SignalEvent (0x0x7fc895f18680) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7fc895f186e8) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u) + QEvent (0x0x7fc895f505a0) 0 + primary-for QStateMachine::WrappedEvent (0x0x7fc895f186e8) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7fc895f18548) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u) + QState (0x0x7fc895f185b0) 0 + primary-for QStateMachine (0x0x7fc895f18548) + QAbstractState (0x0x7fc895f18618) 0 + primary-for QState (0x0x7fc895f185b0) + QObject (0x0x7fc895f50480) 0 + primary-for QAbstractState (0x0x7fc895f18618) + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7fc895f50600) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7fc896044540) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7fc895ccd900) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7fc895cda6e8) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u) + QAbstractListModel (0x0x7fc895cda750) 0 + primary-for QStringListModel (0x0x7fc895cda6e8) + QAbstractItemModel (0x0x7fc895cda7b8) 0 + primary-for QAbstractListModel (0x0x7fc895cda750) + QObject (0x0x7fc895ccd8a0) 0 + primary-for QAbstractItemModel (0x0x7fc895cda7b8) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7fc895ccd960) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7fc895ccda20) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7fc895ccdb40) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7fc895cda820) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u) + QFile (0x0x7fc895cda888) 0 + primary-for QTemporaryFile (0x0x7fc895cda820) + QFileDevice (0x0x7fc895cda8f0) 0 + primary-for QFile (0x0x7fc895cda888) + QIODevice (0x0x7fc895cda958) 0 + primary-for QFileDevice (0x0x7fc895cda8f0) + QObject (0x0x7fc895ccdae0) 0 + primary-for QIODevice (0x0x7fc895cda958) + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7fc895ccdba0) 0 + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7fc895ccdde0) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 0u +64 0u + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7fc895ccdd80) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7fc895db2000) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7fc895db2060) 0 + +Class std::__mutex_base + size=40 align=8 + base size=40 base align=8 +std::__mutex_base (0x0x7fc895db20c0) 0 + +Class std::__recursive_mutex_base + size=40 align=8 + base size=40 base align=8 +std::__recursive_mutex_base (0x0x7fc895db2120) 0 + +Class std::mutex + size=40 align=8 + base size=40 base align=8 +std::mutex (0x0x7fc895cdab60) 0 + std::__mutex_base (0x0x7fc895db2180) 0 + +Class std::recursive_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_mutex (0x0x7fc895cdabc8) 0 + std::__recursive_mutex_base (0x0x7fc895db21e0) 0 + +Class std::timed_mutex + size=40 align=8 + base size=40 base align=8 +std::timed_mutex (0x0x7fc895ddb930) 0 + std::__mutex_base (0x0x7fc895db2300) 0 + std::__timed_mutex_impl (0x0x7fc895db2360) 0 empty + +Class std::recursive_timed_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_timed_mutex (0x0x7fc895df5310) 0 + std::__recursive_mutex_base (0x0x7fc895db2420) 0 + std::__timed_mutex_impl (0x0x7fc895db2480) 0 empty + +Class std::defer_lock_t + size=1 align=1 + base size=0 base align=1 +std::defer_lock_t (0x0x7fc895db24e0) 0 empty + +Class std::try_to_lock_t + size=1 align=1 + base size=0 base align=1 +std::try_to_lock_t (0x0x7fc895db2540) 0 empty + +Class std::adopt_lock_t + size=1 align=1 + base size=0 base align=1 +std::adopt_lock_t (0x0x7fc895db25a0) 0 empty + +Class std::once_flag + size=4 align=4 + base size=4 base align=4 +std::once_flag (0x0x7fc895db27e0) 0 + +Vtable for __gnu_cxx::__concurrence_lock_error +__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what + +Class __gnu_cxx::__concurrence_lock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_lock_error (0x0x7fc895cdad00) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16u) + std::exception (0x0x7fc895db28a0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_lock_error (0x0x7fc895cdad00) + +Vtable for __gnu_cxx::__concurrence_unlock_error +__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what + +Class __gnu_cxx::__concurrence_unlock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_unlock_error (0x0x7fc895cdad68) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16u) + std::exception (0x0x7fc895db2960) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7fc895cdad68) + +Vtable for __gnu_cxx::__concurrence_broadcast_error +__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what + +Class __gnu_cxx::__concurrence_broadcast_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_broadcast_error (0x0x7fc895cdadd0) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16u) + std::exception (0x0x7fc895db2a20) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7fc895cdadd0) + +Vtable for __gnu_cxx::__concurrence_wait_error +__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what + +Class __gnu_cxx::__concurrence_wait_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_wait_error (0x0x7fc895cdaea0) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16u) + std::exception (0x0x7fc895db2ae0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_wait_error (0x0x7fc895cdaea0) + +Class __gnu_cxx::__mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__mutex (0x0x7fc895db2ba0) 0 + +Class __gnu_cxx::__recursive_mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__recursive_mutex (0x0x7fc895db2c00) 0 + +Class __gnu_cxx::__scoped_lock + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__scoped_lock (0x0x7fc895db2c60) 0 + +Class __gnu_cxx::__cond + size=48 align=8 + base size=48 base align=8 +__gnu_cxx::__cond (0x0x7fc895db2cc0) 0 + +Vtable for std::bad_weak_ptr +std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12bad_weak_ptr) +16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +32 (int (*)(...))std::bad_weak_ptr::what + +Class std::bad_weak_ptr + size=8 align=8 + base size=8 base align=8 +std::bad_weak_ptr (0x0x7fc895ace1a0) 0 nearly-empty + vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16u) + std::exception (0x0x7fc895b08060) 0 nearly-empty + primary-for std::bad_weak_ptr (0x0x7fc895ace1a0) + +Class std::_Sp_make_shared_tag + size=1 align=1 + base size=0 base align=1 +std::_Sp_make_shared_tag (0x0x7fc895b088a0) 0 empty + +Class std::_Sp_locker + size=2 align=1 + base size=2 base align=1 +std::_Sp_locker (0x0x7fc8958840c0) 0 + +Class std::thread::id + size=8 align=8 + base size=8 base align=8 +std::thread::id (0x0x7fc8958842a0) 0 + +Vtable for std::thread::_Impl_base +std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6thread10_Impl_baseE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class std::thread::_Impl_base + size=24 align=8 + base size=24 base align=8 +std::thread::_Impl_base (0x0x7fc895884300) 0 + vptr=((& std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE) + 16u) + +Class std::thread + size=8 align=8 + base size=8 base align=8 +std::thread (0x0x7fc895884240) 0 + +Class std::condition_variable + size=48 align=8 + base size=48 base align=8 +std::condition_variable (0x0x7fc8959fcf00) 0 + +Class std::__at_thread_exit_elt + size=16 align=8 + base size=16 base align=8 +std::__at_thread_exit_elt (0x0x7fc895a64000) 0 + +Class std::_V2::condition_variable_any + size=64 align=8 + base size=64 base align=8 +std::_V2::condition_variable_any (0x0x7fc895a64060) 0 + +Class std::__atomic_futex_unsigned_base + size=1 align=1 + base size=0 base align=1 +std::__atomic_futex_unsigned_base (0x0x7fc8956cb6c0) 0 empty + +Vtable for std::future_error +std::future_error::_ZTVSt12future_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12future_error) +16 (int (*)(...))std::future_error::~future_error +24 (int (*)(...))std::future_error::~future_error +32 (int (*)(...))std::future_error::what + +Class std::future_error + size=32 align=8 + base size=32 base align=8 +std::future_error (0x0x7fc8956cf4e0) 0 + vptr=((& std::future_error::_ZTVSt12future_error) + 16u) + std::logic_error (0x0x7fc8956cf548) 0 + primary-for std::future_error (0x0x7fc8956cf4e0) + std::exception (0x0x7fc8956cb7e0) 0 nearly-empty + primary-for std::logic_error (0x0x7fc8956cf548) + +Class std::__future_base::_Result_base::_Deleter + size=1 align=1 + base size=0 base align=1 +std::__future_base::_Result_base::_Deleter (0x0x7fc8956cb900) 0 empty + +Vtable for std::__future_base::_Result_base +std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class std::__future_base::_Result_base + size=16 align=8 + base size=16 base align=8 +std::__future_base::_Result_base (0x0x7fc8956cb8a0) 0 + vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16u) + +Class std::__future_base::_State_baseV2::__exception_ptr_tag + size=1 align=1 + base size=0 base align=1 +std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7fc8957a6e40) 0 empty + +Class std::__future_base::_State_baseV2::_Make_ready + size=32 align=8 + base size=32 base align=8 +std::__future_base::_State_baseV2::_Make_ready (0x0x7fc895826af8) 0 + std::__at_thread_exit_elt (0x0x7fc8957a6f00) 0 + +Vtable for std::__future_base::_State_baseV2 +std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E) +16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_State_baseV2 + size=32 align=8 + base size=28 base align=8 +std::__future_base::_State_baseV2 (0x0x7fc8956cba80) 0 + vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16u) + +Class std::__future_base + size=1 align=1 + base size=0 base align=1 +std::__future_base (0x0x7fc8956cb840) 0 empty + +Vtable for std::__future_base::_Async_state_commonV2 +std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E) +16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_Async_state_commonV2 + size=48 align=8 + base size=44 base align=8 +std::__future_base::_Async_state_commonV2 (0x0x7fc8951a76e8) 0 + vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16u) + std::__future_base::_State_baseV2 (0x0x7fc895191de0) 0 + primary-for std::__future_base::_Async_state_commonV2 (0x0x7fc8951a76e8) + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7fc8951ff540) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7fc8952201a0) 0 + vptr=((& QThread::_ZTV7QThread) + 16u) + QObject (0x0x7fc8951ff4e0) 0 + primary-for QThread (0x0x7fc8952201a0) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7fc8951ff660) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7fc895220208) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u) + QObject (0x0x7fc8951ff600) 0 + primary-for QThreadPool (0x0x7fc895220208) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7fc8951ff6c0) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7fc8951ff7e0) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7fc895220270) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u) + QObject (0x0x7fc8951ff780) 0 + primary-for QTimeLine (0x0x7fc895220270) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7fc8951ff8a0) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7fc8952202d8) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16u) + QObject (0x0x7fc8951ff840) 0 + primary-for QTimer (0x0x7fc8952202d8) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7fc894ecb000) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7fc8951fff60) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7fc894ecb5a0) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7fc895220ea0) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16u) + QObject (0x0x7fc894ecb540) 0 + primary-for QTranslator (0x0x7fc895220ea0) + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7fc894ecb600) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7fc894ecbc60) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7fc894ecbcc0) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7fc894ecbf60) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7fc894f2bb60) 0 + QVector (0x0x7fc894f77360) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7fc894f773c0) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7fc894f77660) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7fc894f77900) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7fc894f77ba0) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7fc894f77c00) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7fc894c78660) 0 + +Class QDBusAbstractAdaptor::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDBusAbstractAdaptor::QPrivateSignal (0x0x7fc894c787e0) 0 empty + +Vtable for QDBusAbstractAdaptor +QDBusAbstractAdaptor::_ZTV20QDBusAbstractAdaptor: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDBusAbstractAdaptor) +16 (int (*)(...))QDBusAbstractAdaptor::metaObject +24 (int (*)(...))QDBusAbstractAdaptor::qt_metacast +32 (int (*)(...))QDBusAbstractAdaptor::qt_metacall +40 (int (*)(...))QDBusAbstractAdaptor::~QDBusAbstractAdaptor +48 (int (*)(...))QDBusAbstractAdaptor::~QDBusAbstractAdaptor +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDBusAbstractAdaptor + size=16 align=8 + base size=16 base align=8 +QDBusAbstractAdaptor (0x0x7fc895023d00) 0 + vptr=((& QDBusAbstractAdaptor::_ZTV20QDBusAbstractAdaptor) + 16u) + QObject (0x0x7fc894c78780) 0 + primary-for QDBusAbstractAdaptor (0x0x7fc895023d00) + +Class QDBusError + size=32 align=8 + base size=32 base align=8 +QDBusError (0x0x7fc894c78840) 0 + +Class QDBusMessage + size=8 align=8 + base size=8 base align=8 +QDBusMessage (0x0x7fc894d4b900) 0 + +Class QDBusObjectPath + size=8 align=8 + base size=8 base align=8 +QDBusObjectPath (0x0x7fc894ddec00) 0 + +Class QDBusSignature + size=8 align=8 + base size=8 base align=8 +QDBusSignature (0x0x7fc894ddeea0) 0 + +Class QDBusVariant + size=16 align=8 + base size=16 base align=8 +QDBusVariant (0x0x7fc894e3a180) 0 + +Class QDBusConnection + size=8 align=8 + base size=8 base align=8 +QDBusConnection (0x0x7fc894e3a7e0) 0 + +Vtable for QDBusAbstractInterfaceBase +QDBusAbstractInterfaceBase::_ZTV26QDBusAbstractInterfaceBase: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QDBusAbstractInterfaceBase) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QDBusAbstractInterfaceBase::qt_metacall +40 (int (*)(...))QDBusAbstractInterfaceBase::~QDBusAbstractInterfaceBase +48 (int (*)(...))QDBusAbstractInterfaceBase::~QDBusAbstractInterfaceBase +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDBusAbstractInterfaceBase + size=16 align=8 + base size=16 base align=8 +QDBusAbstractInterfaceBase (0x0x7fc894b40958) 0 + vptr=((& QDBusAbstractInterfaceBase::_ZTV26QDBusAbstractInterfaceBase) + 16u) + QObject (0x0x7fc894b3da20) 0 + primary-for QDBusAbstractInterfaceBase (0x0x7fc894b40958) + +Class QDBusAbstractInterface::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDBusAbstractInterface::QPrivateSignal (0x0x7fc894b3dae0) 0 empty + +Vtable for QDBusAbstractInterface +QDBusAbstractInterface::_ZTV22QDBusAbstractInterface: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QDBusAbstractInterface) +16 (int (*)(...))QDBusAbstractInterface::metaObject +24 (int (*)(...))QDBusAbstractInterface::qt_metacast +32 (int (*)(...))QDBusAbstractInterface::qt_metacall +40 (int (*)(...))QDBusAbstractInterface::~QDBusAbstractInterface +48 (int (*)(...))QDBusAbstractInterface::~QDBusAbstractInterface +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QDBusAbstractInterface::connectNotify +104 (int (*)(...))QDBusAbstractInterface::disconnectNotify + +Class QDBusAbstractInterface + size=16 align=8 + base size=16 base align=8 +QDBusAbstractInterface (0x0x7fc894b409c0) 0 + vptr=((& QDBusAbstractInterface::_ZTV22QDBusAbstractInterface) + 16u) + QDBusAbstractInterfaceBase (0x0x7fc894b40a28) 0 + primary-for QDBusAbstractInterface (0x0x7fc894b409c0) + QObject (0x0x7fc894b3da80) 0 + primary-for QDBusAbstractInterfaceBase (0x0x7fc894b40a28) + +Class QDBusArgument + size=8 align=8 + base size=8 base align=8 +QDBusArgument (0x0x7fc894b3db40) 0 + +Class QDBusPendingCall + size=8 align=8 + base size=8 base align=8 +QDBusPendingCall (0x0x7fc8948b7d20) 0 + +Class QDBusPendingCallWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDBusPendingCallWatcher::QPrivateSignal (0x0x7fc89492b120) 0 empty + +Vtable for QDBusPendingCallWatcher +QDBusPendingCallWatcher::_ZTV23QDBusPendingCallWatcher: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QDBusPendingCallWatcher) +16 (int (*)(...))QDBusPendingCallWatcher::metaObject +24 (int (*)(...))QDBusPendingCallWatcher::qt_metacast +32 (int (*)(...))QDBusPendingCallWatcher::qt_metacall +40 (int (*)(...))QDBusPendingCallWatcher::~QDBusPendingCallWatcher +48 (int (*)(...))QDBusPendingCallWatcher::~QDBusPendingCallWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDBusPendingCallWatcher + size=24 align=8 + base size=24 base align=8 +QDBusPendingCallWatcher (0x0x7fc894904e00) 0 + vptr=((& QDBusPendingCallWatcher::_ZTV23QDBusPendingCallWatcher) + 16u) + QObject (0x0x7fc89492b060) 0 + primary-for QDBusPendingCallWatcher (0x0x7fc894904e00) + QDBusPendingCall (0x0x7fc89492b0c0) 16 + +Class QDBusPendingReplyData + size=8 align=8 + base size=8 base align=8 +QDBusPendingReplyData (0x0x7fc894902618) 0 + QDBusPendingCall (0x0x7fc89492b180) 0 + +Class QDBusPendingReplyTypes::TypeIsVoid + size=1 align=1 + base size=0 base align=1 +QDBusPendingReplyTypes::TypeIsVoid (0x0x7fc89492b6c0) 0 empty + +Class QDBusConnectionInterface::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDBusConnectionInterface::QPrivateSignal (0x0x7fc89492bae0) 0 empty + +Vtable for QDBusConnectionInterface +QDBusConnectionInterface::_ZTV24QDBusConnectionInterface: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QDBusConnectionInterface) +16 (int (*)(...))QDBusConnectionInterface::metaObject +24 (int (*)(...))QDBusConnectionInterface::qt_metacast +32 (int (*)(...))QDBusConnectionInterface::qt_metacall +40 (int (*)(...))QDBusConnectionInterface::~QDBusConnectionInterface +48 (int (*)(...))QDBusConnectionInterface::~QDBusConnectionInterface +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QDBusConnectionInterface::connectNotify +104 (int (*)(...))QDBusConnectionInterface::disconnectNotify + +Class QDBusConnectionInterface + size=16 align=8 + base size=16 base align=8 +QDBusConnectionInterface (0x0x7fc894902af8) 0 + vptr=((& QDBusConnectionInterface::_ZTV24QDBusConnectionInterface) + 16u) + QDBusAbstractInterface (0x0x7fc894902b60) 0 + primary-for QDBusConnectionInterface (0x0x7fc894902af8) + QDBusAbstractInterfaceBase (0x0x7fc894902bc8) 0 + primary-for QDBusAbstractInterface (0x0x7fc894902b60) + QObject (0x0x7fc89492ba80) 0 + primary-for QDBusAbstractInterfaceBase (0x0x7fc894902bc8) + +Class QDBusContext + size=8 align=8 + base size=8 base align=8 +QDBusContext (0x0x7fc89492bba0) 0 + +Vtable for QDBusInterface +QDBusInterface::_ZTV14QDBusInterface: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QDBusInterface) +16 (int (*)(...))QDBusInterface::metaObject +24 (int (*)(...))QDBusInterface::qt_metacast +32 (int (*)(...))QDBusInterface::qt_metacall +40 (int (*)(...))QDBusInterface::~QDBusInterface +48 (int (*)(...))QDBusInterface::~QDBusInterface +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QDBusAbstractInterface::connectNotify +104 (int (*)(...))QDBusAbstractInterface::disconnectNotify + +Class QDBusInterface + size=16 align=8 + base size=16 base align=8 +QDBusInterface (0x0x7fc894902c30) 0 + vptr=((& QDBusInterface::_ZTV14QDBusInterface) + 16u) + QDBusAbstractInterface (0x0x7fc894902c98) 0 + primary-for QDBusInterface (0x0x7fc894902c30) + QDBusAbstractInterfaceBase (0x0x7fc894902d00) 0 + primary-for QDBusAbstractInterface (0x0x7fc894902c98) + QObject (0x0x7fc89492bc00) 0 + primary-for QDBusAbstractInterfaceBase (0x0x7fc894902d00) + +Class QDBusMetaType + size=1 align=1 + base size=0 base align=1 +QDBusMetaType (0x0x7fc89492bc60) 0 empty + +Class QDBusServer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDBusServer::QPrivateSignal (0x0x7fc89492bd20) 0 empty + +Vtable for QDBusServer +QDBusServer::_ZTV11QDBusServer: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QDBusServer) +16 (int (*)(...))QDBusServer::metaObject +24 (int (*)(...))QDBusServer::qt_metacast +32 (int (*)(...))QDBusServer::qt_metacall +40 (int (*)(...))QDBusServer::~QDBusServer +48 (int (*)(...))QDBusServer::~QDBusServer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDBusServer + size=24 align=8 + base size=24 base align=8 +QDBusServer (0x0x7fc894902dd0) 0 + vptr=((& QDBusServer::_ZTV11QDBusServer) + 16u) + QObject (0x0x7fc89492bcc0) 0 + primary-for QDBusServer (0x0x7fc894902dd0) + +Class QDBusServiceWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDBusServiceWatcher::QPrivateSignal (0x0x7fc89492bde0) 0 empty + +Vtable for QDBusServiceWatcher +QDBusServiceWatcher::_ZTV19QDBusServiceWatcher: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QDBusServiceWatcher) +16 (int (*)(...))QDBusServiceWatcher::metaObject +24 (int (*)(...))QDBusServiceWatcher::qt_metacast +32 (int (*)(...))QDBusServiceWatcher::qt_metacall +40 (int (*)(...))QDBusServiceWatcher::~QDBusServiceWatcher +48 (int (*)(...))QDBusServiceWatcher::~QDBusServiceWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDBusServiceWatcher + size=16 align=8 + base size=16 base align=8 +QDBusServiceWatcher (0x0x7fc894902e38) 0 + vptr=((& QDBusServiceWatcher::_ZTV19QDBusServiceWatcher) + 16u) + QObject (0x0x7fc89492bd80) 0 + primary-for QDBusServiceWatcher (0x0x7fc894902e38) + +Class QDBusUnixFileDescriptor + size=8 align=8 + base size=8 base align=8 +QDBusUnixFileDescriptor (0x0x7fc894a02000) 0 + +Class QDBusVirtualObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDBusVirtualObject::QPrivateSignal (0x0x7fc894a02480) 0 empty + +Vtable for QDBusVirtualObject +QDBusVirtualObject::_ZTV18QDBusVirtualObject: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QDBusVirtualObject) +16 (int (*)(...))QDBusVirtualObject::metaObject +24 (int (*)(...))QDBusVirtualObject::qt_metacast +32 (int (*)(...))QDBusVirtualObject::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QDBusVirtualObject + size=16 align=8 + base size=16 base align=8 +QDBusVirtualObject (0x0x7fc894a24000) 0 + vptr=((& QDBusVirtualObject::_ZTV18QDBusVirtualObject) + 16u) + QObject (0x0x7fc894a02420) 0 + primary-for QDBusVirtualObject (0x0x7fc894a24000) + diff --git a/tests/auto/bic/data/QtGui.5.12.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtGui.5.12.0.linux-gcc-amd64.txt new file mode 100644 index 0000000000..5d8cea562b --- /dev/null +++ b/tests/auto/bic/data/QtGui.5.12.0.linux-gcc-amd64.txt @@ -0,0 +1,8422 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7f97c7db9660) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7f97c7e1fde0) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7f97c7e4a060) 0 empty + +Class std::__do_is_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_default_constructible_impl (0x0x7f97c7e4a2a0) 0 empty + +Class std::__do_is_static_castable_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_static_castable_impl (0x0x7f97c7e4a4e0) 0 empty + +Class std::__do_is_direct_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_direct_constructible_impl (0x0x7f97c7e4a660) 0 empty + +Class std::__do_is_nary_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nary_constructible_impl (0x0x7f97c7e4aa20) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7f97c7a9a1e0) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7f97c7a9a2a0) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7f97c7a9a600) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7f97c7a9a6c0) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7f97c7a9a780) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7f97c7a9a840) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7f97c7a9aae0) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7f97c7a9acc0) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7f97c7b18180) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7f97c7b181e0) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7f97c7b55e40) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7f97c7b55ea0) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7f97c7a88750) 0 empty + std::input_iterator_tag (0x0x7f97c7b55f00) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7f97c7a887b8) 0 empty + std::forward_iterator_tag (0x0x7f97c7a88820) 0 empty + std::input_iterator_tag (0x0x7f97c7b55f60) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7f97c7a88888) 0 empty + std::bidirectional_iterator_tag (0x0x7f97c7a888f0) 0 empty + std::forward_iterator_tag (0x0x7f97c7a88958) 0 empty + std::input_iterator_tag (0x0x7f97c7b7e000) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7f97c7b7ec60) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7f97c7b7ecc0) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7f97c7b7ed20) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7f97c7b7ed80) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7f97c7b7ede0) 0 empty + +Class wait + size=4 align=4 + base size=4 base align=4 +wait (0x0x7f97c784e900) 0 + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7f97c784eb40) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7f97c784ec00) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7f97c784ec60) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7f97c784ed20) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7f97c784ed80) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7f97c78f1240) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7f97c78f12a0) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7f97c78f1300) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16u) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7f97c7a88ea0) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u) + std::exception (0x0x7f97c78f1360) 0 nearly-empty + primary-for std::bad_exception (0x0x7f97c7a88ea0) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7f97c78f13c0) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7f97c78f1420) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16u) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7f97c79e00d0) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u) + std::exception (0x0x7f97c78f1840) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f97c79e00d0) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7f97c79e0138) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16u) + std::bad_alloc (0x0x7f97c79e01a0) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7f97c79e0138) + std::exception (0x0x7f97c78f18a0) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f97c79e01a0) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7f97c78f1900) 0 empty + +Class __exception + size=40 align=8 + base size=40 base align=8 +__exception (0x0x7f97c7665540) 0 + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7f97c7486240) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7f97c74862a0) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7f97c752a180) 0 + +Class __sched_param + size=4 align=4 + base size=4 base align=4 +__sched_param (0x0x7f97c752a1e0) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7f97c752a2a0) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7f97c752a300) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7f97c752a360) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7f97c752a3c0) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7f97c752a4e0) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7f97c752a540) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7f97c752a960) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7f97c752a9c0) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7f97c704c1e0) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7f97c704c240) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7f97c71271e0) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7f97c6f3c000) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7f97c7044f08) 0 + std::iterator (0x0x7f97c6f3c0c0) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7f97c7044f70) 0 + std::_Bit_iterator_base (0x0x7f97c70446e8) 0 + std::iterator (0x0x7f97c6f3c120) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7f97c7044750) 0 + std::_Bit_iterator_base (0x0x7f97c7044a28) 0 + std::iterator (0x0x7f97c6f3c180) 0 empty + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7f97c6f3cf60) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7f97c6d22d20) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7f97c6d22cc0) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7f97c6a56cc0) 0 + +Class qIsNull(double)::U + size=8 align=8 + base size=8 base align=8 +qIsNull(double)::U (0x0x7f97c56b07e0) 0 + +Class qIsNull(float)::U + size=4 align=4 + base size=4 base align=4 +qIsNull(float)::U (0x0x7f97c56b0840) 0 + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7f97c5797300) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7f97c5797360) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7f97c57973c0) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7f97c5797420) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7f97c57976c0) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7f97c5797c00) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7f97c5778dd0) 0 + std::__atomic_flag_base (0x0x7f97c5797c60) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7f97c55cd548) 0 + QAtomicInteger (0x0x7f97c55cd5b0) 0 + QBasicAtomicInteger (0x0x7f97c534d3c0) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7f97c4e79960) 0 empty + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7f97c4bdcb40) 0 + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7f97c4bdcc60) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7f97c4c321a0) 0 + QGenericArgument (0x0x7f97c4bdccc0) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7f97c4bdce40) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7f97c4bdcf00) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7f97c4cd7f60) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7f97c4d05000) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7f97c4d052a0) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7f97c4d05300) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7f97c4d05660) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7f97c4d056c0) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7f97c4d05720) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7f97c4d05780) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7f97c4d057e0) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7f97c4d05ba0) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7f97c4a0a7b8) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16u) + std::exception (0x0x7f97c4d05c60) 0 nearly-empty + primary-for std::logic_error (0x0x7f97c4a0a7b8) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7f97c4a0a820) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16u) + std::logic_error (0x0x7f97c4a0a888) 0 + primary-for std::domain_error (0x0x7f97c4a0a820) + std::exception (0x0x7f97c4d05cc0) 0 nearly-empty + primary-for std::logic_error (0x0x7f97c4a0a888) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7f97c4a0a8f0) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16u) + std::logic_error (0x0x7f97c4a0a958) 0 + primary-for std::invalid_argument (0x0x7f97c4a0a8f0) + std::exception (0x0x7f97c4d05d20) 0 nearly-empty + primary-for std::logic_error (0x0x7f97c4a0a958) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7f97c4a0a9c0) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16u) + std::logic_error (0x0x7f97c4a0aa28) 0 + primary-for std::length_error (0x0x7f97c4a0a9c0) + std::exception (0x0x7f97c4d05d80) 0 nearly-empty + primary-for std::logic_error (0x0x7f97c4a0aa28) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7f97c4a0aa90) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16u) + std::logic_error (0x0x7f97c4a0aaf8) 0 + primary-for std::out_of_range (0x0x7f97c4a0aa90) + std::exception (0x0x7f97c4d05de0) 0 nearly-empty + primary-for std::logic_error (0x0x7f97c4a0aaf8) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7f97c4a0ab60) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16u) + std::exception (0x0x7f97c4d05e40) 0 nearly-empty + primary-for std::runtime_error (0x0x7f97c4a0ab60) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7f97c4a0abc8) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16u) + std::runtime_error (0x0x7f97c4a0ac30) 0 + primary-for std::range_error (0x0x7f97c4a0abc8) + std::exception (0x0x7f97c4d05ea0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f97c4a0ac30) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7f97c4a0ac98) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16u) + std::runtime_error (0x0x7f97c4a0ad00) 0 + primary-for std::overflow_error (0x0x7f97c4a0ac98) + std::exception (0x0x7f97c4d05f00) 0 nearly-empty + primary-for std::runtime_error (0x0x7f97c4a0ad00) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7f97c4a0ad68) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16u) + std::runtime_error (0x0x7f97c4a0add0) 0 + primary-for std::underflow_error (0x0x7f97c4a0ad68) + std::exception (0x0x7f97c4d05f60) 0 nearly-empty + primary-for std::runtime_error (0x0x7f97c4a0add0) + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7f97c4ac5120) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16u) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7f97c4ac5360) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7f97c4ac54e0) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7f97c4b04208) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16u) + std::runtime_error (0x0x7f97c4b04270) 0 + primary-for std::system_error (0x0x7f97c4b04208) + std::exception (0x0x7f97c4ac5720) 0 nearly-empty + primary-for std::runtime_error (0x0x7f97c4b04270) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7f97c4b04e38) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16u) + std::system_error (0x0x7f97c4b04ea0) 0 + primary-for std::ios_base::failure (0x0x7f97c4b04e38) + std::runtime_error (0x0x7f97c4b04f08) 0 + primary-for std::system_error (0x0x7f97c4b04ea0) + std::exception (0x0x7f97c4ac5a20) 0 nearly-empty + primary-for std::runtime_error (0x0x7f97c4b04f08) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7f97c4ac5a80) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7f97c4ac5ae0) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7f97c4ac5b40) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7f97c4ac59c0) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7f97c4801300) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7f97c48019c0) 0 empty + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSo: 2u entries +0 ((& std::basic_ostream::_ZTVSo) + 24u) +8 ((& std::basic_ostream::_ZTVSo) + 64u) + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSi: 2u entries +0 ((& std::basic_istream::_ZTVSi) + 24u) +8 ((& std::basic_istream::_ZTVSi) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u) + +Construction vtable for std::basic_istream (0x0x7f97c43be820 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd0_Si: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7f97c43be8f0 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd16_So: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSd: 7u entries +0 ((& std::basic_iostream::_ZTVSd) + 24u) +8 ((& std::basic_iostream::_ZTCSd0_Si) + 24u) +16 ((& std::basic_iostream::_ZTCSd0_Si) + 64u) +24 ((& std::basic_iostream::_ZTCSd16_So) + 24u) +32 ((& std::basic_iostream::_ZTCSd16_So) + 64u) +40 ((& std::basic_iostream::_ZTVSd) + 104u) +48 ((& std::basic_iostream::_ZTVSd) + 64u) + +Construction vtable for std::basic_istream (0x0x7f97c43bec98 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7f97c43bed68 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries +0 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u) +16 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u) +24 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u) +32 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u) +40 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u) +48 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u) + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7f97c4422240) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7f97c44222a0) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7f97c4542600) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7f97c4542960) 0 + +Class QStringView + size=16 align=8 + base size=16 base align=8 +QStringView (0x0x7f97c4542de0) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7f97c4275c60) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7f97c4308300) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7f97c43082a0) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7f97c40b33c0) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7f97c3e7a000) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7f97c3e7ac60) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7f97c3e7acc0) 0 empty + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7f97c3e7ad20) 0 + +Class QListData::NotArrayCompatibleLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotArrayCompatibleLayout (0x0x7f97c3c91120) 0 empty + +Class QListData::NotIndirectLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotIndirectLayout (0x0x7f97c3c91180) 0 empty + +Class QListData::ArrayCompatibleLayout + size=1 align=1 + base size=1 base align=1 +QListData::ArrayCompatibleLayout (0x0x7f97c3bbf7b8) 0 empty + QListData::NotIndirectLayout (0x0x7f97c3c911e0) 0 empty + +Class QListData::InlineWithPaddingLayout + size=1 align=1 + base size=1 base align=1 +QListData::InlineWithPaddingLayout (0x0x7f97c3d19230) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f97c3c91240) 0 empty + QListData::NotIndirectLayout (0x0x7f97c3c912a0) 0 empty + +Class QListData::IndirectLayout + size=1 align=1 + base size=1 base align=1 +QListData::IndirectLayout (0x0x7f97c3bbf820) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f97c3c91300) 0 empty + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7f97c3c91360) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7f97c3c910c0) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7f97c3c917e0) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7f97c3ac8a20) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7f97c3ac89c0) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7f97c3ad5270) 0 + QList (0x0x7f97c3ad52d8) 0 + QListSpecialMethods (0x0x7f97c3ac8c00) 0 empty + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7f97c3b6b060) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7f97c3b6bc00) 0 + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7f97c38f42a0) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7f97c38f4420) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7f97c38f44e0) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7f97c3ad5bc8) 0 + std::__uses_alloc_base (0x0x7f97c38f4480) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7f97c3675540) 0 empty + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7f97c3675780) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7f97c3675840) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7f97c3675960) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7f97c3675ae0) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7f97c3675f00) 0 + +Class QtMetaTypePrivate::VectorBoolElements + size=1 align=1 + base size=0 base align=1 +QtMetaTypePrivate::VectorBoolElements (0x0x7f97c33d0060) 0 empty + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7f97c33d09c0) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7f97c33d0de0) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7f97c34bf120) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7f97c32cdae0) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7f97c302b960) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7f97c302b9c0) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16u) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7f97c302bba0) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7f97c302bb40) 0 + vptr=((& QObject::_ZTV7QObject) + 16u) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7f97c30dce40) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7f97c30dcea0) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7f97c30dcf60) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7f97c30fef70) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u) + QObject (0x0x7f97c30dcf00) 0 + primary-for QAbstractAnimation (0x0x7f97c30fef70) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7f97c3166060) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7f97c30fe138) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16u) + QObject (0x0x7f97c3166000) 0 + primary-for QAnimationDriver (0x0x7f97c30fe138) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7f97c3166120) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7f97c30fe2d8) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u) + QObject (0x0x7f97c31660c0) 0 + primary-for QEventLoop (0x0x7f97c30fe2d8) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7f97c3166300) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7f97c31663c0) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7f97c3166420) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7f97c2daf000) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u) + QObject (0x0x7f97c3166360) 0 + primary-for QAbstractEventDispatcher (0x0x7f97c2daf000) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7f97c31666c0) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16u) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7f97c2daf208) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16u) + std::exception (0x0x7f97c3166720) 0 nearly-empty + primary-for std::bad_cast (0x0x7f97c2daf208) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7f97c2daf270) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16u) + std::exception (0x0x7f97c3166780) 0 nearly-empty + primary-for std::bad_typeid (0x0x7f97c2daf270) + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7f97c2f264e0) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16u) + std::exception (0x0x7f97c2efe840) 0 nearly-empty + primary-for std::bad_function_call (0x0x7f97c2f264e0) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7f97c2efe900) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7f97c2efe960) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7f97c2efea80) 0 + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7f97c2efef60) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7f97c2bea4e0) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7f97c2bea8a0) 0 + +Class QHashData + size=48 align=8 + base size=44 base align=8 +QHashData (0x0x7f97c2bea840) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7f97c2bea900) 0 empty + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7f97c2a001e0) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7f97c2a002a0) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7f97c2a00240) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7f97c2a00300) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7f97c2a00180) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7f97c2acdde0) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7f97c277a480) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7f97c277a420) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7f97c277a540) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7f97c277a4e0) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7f97c289c840) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7f97c289cf00) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7f97c2688660) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7f97c268f270) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u) + QObject (0x0x7f97c2688600) 0 + primary-for QAbstractItemModel (0x0x7f97c268f270) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7f97c2688f00) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7f97c268f958) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u) + QAbstractItemModel (0x0x7f97c268f9c0) 0 + primary-for QAbstractTableModel (0x0x7f97c268f958) + QObject (0x0x7f97c2688ea0) 0 + primary-for QAbstractItemModel (0x0x7f97c268f9c0) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7f97c2378000) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7f97c268fa28) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u) + QAbstractItemModel (0x0x7f97c268fa90) 0 + primary-for QAbstractListModel (0x0x7f97c268fa28) + QObject (0x0x7f97c2688f60) 0 + primary-for QAbstractItemModel (0x0x7f97c268fa90) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7f97c23782a0) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16u) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7f97c2378360) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7f97c268fbc8) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16u) + QAbstractItemModel (0x0x7f97c268fc30) 0 + primary-for QAbstractProxyModel (0x0x7f97c268fbc8) + QObject (0x0x7f97c2378300) 0 + primary-for QAbstractItemModel (0x0x7f97c268fc30) + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7f97c2378420) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7f97c268fc98) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u) + QObject (0x0x7f97c23783c0) 0 + primary-for QAbstractState (0x0x7f97c268fc98) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7f97c23784e0) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7f97c268fd00) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u) + QObject (0x0x7f97c2378480) 0 + primary-for QAbstractTransition (0x0x7f97c268fd00) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7f97c23785a0) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7f97c268fd68) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u) + QAbstractAnimation (0x0x7f97c268fdd0) 0 + primary-for QAnimationGroup (0x0x7f97c268fd68) + QObject (0x0x7f97c2378540) 0 + primary-for QAbstractAnimation (0x0x7f97c268fdd0) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7f97c2453300) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7f97c24535a0) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7f97c2453660) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7f97c2453960) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7f97c2462478) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16u) + QObject (0x0x7f97c2453900) 0 + primary-for QIODevice (0x0x7f97c2462478) + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7f97c2453ba0) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7f97c24625b0) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16u) + QIODevice (0x0x7f97c2462618) 0 + primary-for QBuffer (0x0x7f97c24625b0) + QObject (0x0x7f97c2453b40) 0 + primary-for QIODevice (0x0x7f97c2462618) + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7f97c2453c60) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7f97c2453c00) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7f97c2453d80) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7f97c2453d20) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7f97c2453f60) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7f97c217e180) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7f97c217e420) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7f97c217eba0) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7f97c217ec00) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7f97c217eb40) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7f97c22a2d20) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7f97c236e360) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16u) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7f97c236e600) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7f97c236e840) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7f97c236ef00) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7f97c20a00c0) 0 + +Class QDebug::Stream + size=80 align=8 + base size=76 base align=8 +QDebug::Stream (0x0x7f97c20a0600) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7f97c20a05a0) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7f97c1eb2900) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7f97c1eb29c0) 0 empty + +Class QCborError + size=4 align=4 + base size=4 base align=4 +QCborError (0x0x7f97c1b30d20) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7f97c1b30ea0) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7f97c1b974e0) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7f97c1b977e0) 0 + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7f97c1b97ba0) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7f97c19312a0) 0 + +Class QCborParserError + size=16 align=8 + base size=12 base align=8 +QCborParserError (0x0x7f97c19318a0) 0 + +Class QCborValue + size=24 align=8 + base size=20 base align=8 +QCborValue (0x0x7f97c1931900) 0 + +Class QCborValueRef + size=16 align=8 + base size=16 base align=8 +QCborValueRef (0x0x7f97c17ea900) 0 + +Class QCborArray::Iterator + size=16 align=8 + base size=16 base align=8 +QCborArray::Iterator (0x0x7f97c17eaea0) 0 + +Class QCborArray::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborArray::ConstIterator (0x0x7f97c17eaf00) 0 + +Class QCborArray + size=8 align=8 + base size=8 base align=8 +QCborArray (0x0x7f97c17eae40) 0 + +Class QCborMap::Iterator + size=16 align=8 + base size=16 base align=8 +QCborMap::Iterator (0x0x7f97c191cf60) 0 + +Class QCborMap::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborMap::ConstIterator (0x0x7f97c15bd000) 0 + +Class QCborMap + size=8 align=8 + base size=8 base align=8 +QCborMap (0x0x7f97c191cf00) 0 + +Class qfloat16 + size=2 align=2 + base size=2 base align=2 +qfloat16 (0x0x7f97c16cfb40) 0 + +Class QCborStreamWriter + size=8 align=8 + base size=8 base align=8 +QCborStreamWriter (0x0x7f97c16cff00) 0 + +Class QCborStreamReader + size=24 align=8 + base size=20 base align=8 +QCborStreamReader (0x0x7f97c143a900) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7f97c143af60) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7f97c14de060) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7f97c115d060) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7f97c115d4e0) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16u) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7f97c1147bc8) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u) + QEvent (0x0x7f97c115d540) 0 + primary-for QTimerEvent (0x0x7f97c1147bc8) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7f97c1147c30) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u) + QEvent (0x0x7f97c115d5a0) 0 + primary-for QChildEvent (0x0x7f97c1147c30) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7f97c11cf1a0) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u) + QEvent (0x0x7f97c115da80) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7f97c11cf1a0) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7f97c11cf208) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16u) + QEvent (0x0x7f97c115dae0) 0 + primary-for QDeferredDeleteEvent (0x0x7f97c11cf208) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7f97c115dba0) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7f97c11cf270) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u) + QObject (0x0x7f97c115db40) 0 + primary-for QCoreApplication (0x0x7f97c11cf270) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7f97c115dc00) 0 + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7f97c115dc60) 0 + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7f97c115dcc0) 0 + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7f97c115dd80) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7f97c12502a0) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7f97c1250780) 0 + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7f97c0fb5600) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7f97c0fb46e8) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16u) + QIODevice (0x0x7f97c0fb4750) 0 + primary-for QFileDevice (0x0x7f97c0fb46e8) + QObject (0x0x7f97c0fb55a0) 0 + primary-for QIODevice (0x0x7f97c0fb4750) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7f97c0fb5840) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7f97c0fb4888) 0 + vptr=((& QFile::_ZTV5QFile) + 16u) + QFileDevice (0x0x7f97c0fb48f0) 0 + primary-for QFile (0x0x7f97c0fb4888) + QIODevice (0x0x7f97c0fb4958) 0 + primary-for QFileDevice (0x0x7f97c0fb48f0) + QObject (0x0x7f97c0fb57e0) 0 + primary-for QIODevice (0x0x7f97c0fb4958) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7f97c0fb5a20) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7f97c0fb5e40) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7f97c10a2480) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7f97c10a26c0) 0 + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7f97c0dbeae0) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7f97c0dc1958) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u) + QAbstractTransition (0x0x7f97c0dc19c0) 0 + primary-for QEventTransition (0x0x7f97c0dc1958) + QObject (0x0x7f97c0dbea80) 0 + primary-for QAbstractTransition (0x0x7f97c0dc19c0) + +Vtable for QException +QException::_ZTV10QException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7f97c0dc1a28) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16u) + std::exception (0x0x7f97c0dbeb40) 0 nearly-empty + primary-for QException (0x0x7f97c0dc1a28) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7f97c0dc1a90) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16u) + QException (0x0x7f97c0dc1af8) 0 nearly-empty + primary-for QUnhandledException (0x0x7f97c0dc1a90) + std::exception (0x0x7f97c0dbeba0) 0 nearly-empty + primary-for QException (0x0x7f97c0dc1af8) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7f97c0dbec00) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7f97c0dbecc0) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7f97c0dbed20) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7f97c0dbee40) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7f97c0dc1b60) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16u) + QObject (0x0x7f97c0dbede0) 0 + primary-for QFileSelector (0x0x7f97c0dc1b60) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7f97c0dbef00) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7f97c0dc1bc8) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u) + QObject (0x0x7f97c0dbeea0) 0 + primary-for QFileSystemWatcher (0x0x7f97c0dc1bc8) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7f97c0e73000) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7f97c0dc1c30) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16u) + QAbstractState (0x0x7f97c0dc1c98) 0 + primary-for QFinalState (0x0x7f97c0dc1c30) + QObject (0x0x7f97c0dbef60) 0 + primary-for QAbstractState (0x0x7f97c0dc1c98) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7f97c0e73060) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16u) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7f97c0e730c0) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7f97c0dc1dd0) 0 + QBasicMutex (0x0x7f97c0e732a0) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7f97c0e73300) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7f97c0e73360) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7f97c0e733c0) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7f97c0e734e0) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16u) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7f97c0e73d20) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7f97c0bef540) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0u +48 0u +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7f97c0b6af08) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u) + QObject (0x0x7f97c0bef4e0) 0 + primary-for QFutureWatcherBase (0x0x7f97c0b6af08) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7f97c0befb40) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7f97c0c2e820) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u) + QAbstractState (0x0x7f97c0c2e888) 0 + primary-for QHistoryState (0x0x7f97c0c2e820) + QObject (0x0x7f97c0befae0) 0 + primary-for QAbstractState (0x0x7f97c0c2e888) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7f97c0befc00) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7f97c0c2e8f0) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16u) + QAbstractProxyModel (0x0x7f97c0c2e958) 0 + primary-for QIdentityProxyModel (0x0x7f97c0c2e8f0) + QAbstractItemModel (0x0x7f97c0c2e9c0) 0 + primary-for QAbstractProxyModel (0x0x7f97c0c2e958) + QObject (0x0x7f97c0befba0) 0 + primary-for QAbstractItemModel (0x0x7f97c0c2e9c0) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7f97c0befc60) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7f97c0cc2360) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7f97c0cc3208) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u) + QObject (0x0x7f97c0cc2300) 0 + primary-for QItemSelectionModel (0x0x7f97c0cc3208) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7f97c0cc3410) 0 + QList (0x0x7f97c0cc3478) 0 + QListSpecialMethods (0x0x7f97c0cc2660) 0 empty + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7f97c0cc2b40) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7f97c0ad52a0) 0 + +Class QJsonValuePtr + size=24 align=8 + base size=24 base align=8 +QJsonValuePtr (0x0x7f97c0ad57e0) 0 + +Class QJsonValueRefPtr + size=16 align=8 + base size=16 base align=8 +QJsonValueRefPtr (0x0x7f97c0ad5840) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7f97c0ad5a20) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7f97c0ad5a80) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7f97c0ad59c0) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7f97c07e4cc0) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7f97c07e4d20) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7f97c085f3c0) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7f97c085f420) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7f97c085f360) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7f97c05156c0) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7f97c05197b8) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16u) + QObject (0x0x7f97c0515660) 0 + primary-for QLibrary (0x0x7f97c05197b8) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7f97c0515d80) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7f97c05158a0) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7f97c06062a0) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7f97c0606300) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7f97c06065a0) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7f97c0606ba0) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7f97c06a6540) 0 + +Class QLinkedListData + size=32 align=8 + base size=25 base align=8 +QLinkedListData (0x0x7f97c06a6b40) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7f97c06a6ea0) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7f97c03e5060) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7f97c03e5000) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7f97c03e51e0) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7f97c03e5480) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7f97c03e5ae0) 0 + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7f97c03e5b40) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7f97c011d180) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7f97c011d480) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7f97c011d4e0) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7f97c011d7e0) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7f97c04a9a28) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16u) + QObject (0x0x7f97c011d780) 0 + primary-for QMimeData (0x0x7f97c04a9a28) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7f97c011d840) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7f97c011db40) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7f97c011dc00) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7f97c04a9c30) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u) + QObject (0x0x7f97c011dba0) 0 + primary-for QObjectCleanupHandler (0x0x7f97c04a9c30) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7f97c011dc60) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7f97c01a7420) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7f97c01a8340) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u) + QAnimationGroup (0x0x7f97c01a83a8) 0 + primary-for QParallelAnimationGroup (0x0x7f97c01a8340) + QAbstractAnimation (0x0x7f97c01a8410) 0 + primary-for QAnimationGroup (0x0x7f97c01a83a8) + QObject (0x0x7f97c01a73c0) 0 + primary-for QAbstractAnimation (0x0x7f97c01a8410) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7f97c01a74e0) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7f97c01a8478) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u) + QAbstractAnimation (0x0x7f97c01a84e0) 0 + primary-for QPauseAnimation (0x0x7f97c01a8478) + QObject (0x0x7f97c01a7480) 0 + primary-for QAbstractAnimation (0x0x7f97c01a84e0) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7f97c01a76c0) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7f97c01a79c0) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7f97c01a86e8) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u) + QObject (0x0x7f97c01a7960) 0 + primary-for QPluginLoader (0x0x7f97c01a86e8) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7f97c01a7a20) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7f97c0230120) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7f97c01a8d68) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16u) + QIODevice (0x0x7f97c01a8dd0) 0 + primary-for QProcess (0x0x7f97c01a8d68) + QObject (0x0x7f97c02300c0) 0 + primary-for QIODevice (0x0x7f97c01a8dd0) + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7f97c02301e0) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7f97c01a8e38) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u) + QAbstractAnimation (0x0x7f97c01a8ea0) 0 + primary-for QVariantAnimation (0x0x7f97c01a8e38) + QObject (0x0x7f97c0230180) 0 + primary-for QAbstractAnimation (0x0x7f97c01a8ea0) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7f97c02302a0) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7f97c01a8f70) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u) + QVariantAnimation (0x0x7f97c0285000) 0 + primary-for QPropertyAnimation (0x0x7f97c01a8f70) + QAbstractAnimation (0x0x7f97c0285068) 0 + primary-for QVariantAnimation (0x0x7f97c0285000) + QObject (0x0x7f97c0230240) 0 + primary-for QAbstractAnimation (0x0x7f97c0285068) + +Class QRandomGenerator::Storage + size=2504 align=8 + base size=2504 base align=8 +QRandomGenerator::Storage (0x0x7f97c02303c0) 0 + +Class QRandomGenerator + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator (0x0x7f97c0230360) 0 + +Class QRandomGenerator64 + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator64 (0x0x7f97bff26340) 0 + QRandomGenerator (0x0x7f97bff24360) 0 + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7f97bff24420) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7f97bff246c0) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7f97bff24780) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7f97bff24840) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7f97bff24ae0) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7f97bff24d80) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7f97c0083060) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7f97c0083300) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7f97c0083480) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7f97bff26ea0) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16u) + QFileDevice (0x0x7f97bff26f08) 0 + primary-for QSaveFile (0x0x7f97bff26ea0) + QIODevice (0x0x7f97bff26f70) 0 + primary-for QFileDevice (0x0x7f97bff26f08) + QObject (0x0x7f97c0083420) 0 + primary-for QIODevice (0x0x7f97bff26f70) + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7f97c00835a0) 0 + +Class QSemaphoreReleaser + size=16 align=8 + base size=12 base align=8 +QSemaphoreReleaser (0x0x7f97c0083720) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7f97bfec8d20) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7f97bfedf820) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u) + QAnimationGroup (0x0x7f97bfedf888) 0 + primary-for QSequentialAnimationGroup (0x0x7f97bfedf820) + QAbstractAnimation (0x0x7f97bfedf8f0) 0 + primary-for QAnimationGroup (0x0x7f97bfedf888) + QObject (0x0x7f97bfec8cc0) 0 + primary-for QAbstractAnimation (0x0x7f97bfedf8f0) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7f97bfec8de0) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7f97bfedf958) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16u) + QObject (0x0x7f97bfec8d80) 0 + primary-for QSettings (0x0x7f97bfedf958) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7f97bfec8ea0) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7f97bfedf9c0) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u) + QObject (0x0x7f97bfec8e40) 0 + primary-for QSharedMemory (0x0x7f97bfedf9c0) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7f97bfec8f60) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7f97bfedfa28) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u) + QObject (0x0x7f97bfec8f00) 0 + primary-for QSignalMapper (0x0x7f97bfedfa28) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7f97bfb45060) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7f97bfedfa90) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u) + QAbstractTransition (0x0x7f97bfedfaf8) 0 + primary-for QSignalTransition (0x0x7f97bfedfa90) + QObject (0x0x7f97bfb45000) 0 + primary-for QAbstractTransition (0x0x7f97bfedfaf8) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7f97bfb45120) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7f97bfedfb60) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u) + QObject (0x0x7f97bfb450c0) 0 + primary-for QSocketNotifier (0x0x7f97bfedfb60) + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7f97bfb451e0) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7f97bfedfbc8) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16u) + QAbstractProxyModel (0x0x7f97bfedfc30) 0 + primary-for QSortFilterProxyModel (0x0x7f97bfedfbc8) + QAbstractItemModel (0x0x7f97bfedfc98) 0 + primary-for QAbstractProxyModel (0x0x7f97bfedfc30) + QObject (0x0x7f97bfb45180) 0 + primary-for QAbstractItemModel (0x0x7f97bfedfc98) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7f97bfb452a0) 0 empty + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7f97bfb454e0) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7f97bfedfe38) 0 + vptr=((& QState::_ZTV6QState) + 16u) + QAbstractState (0x0x7f97bfedfea0) 0 + primary-for QState (0x0x7f97bfedfe38) + QObject (0x0x7f97bfb45480) 0 + primary-for QAbstractState (0x0x7f97bfedfea0) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7f97bfb45600) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7f97bfbeb068) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u) + QEvent (0x0x7f97bfb45660) 0 + primary-for QStateMachine::SignalEvent (0x0x7f97bfbeb068) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7f97bfbeb0d0) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u) + QEvent (0x0x7f97bfb456c0) 0 + primary-for QStateMachine::WrappedEvent (0x0x7f97bfbeb0d0) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7f97bfedff08) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u) + QState (0x0x7f97bfedff70) 0 + primary-for QStateMachine (0x0x7f97bfedff08) + QAbstractState (0x0x7f97bfbeb000) 0 + primary-for QState (0x0x7f97bfedff70) + QObject (0x0x7f97bfb455a0) 0 + primary-for QAbstractState (0x0x7f97bfbeb000) + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7f97bfb45720) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7f97bfc4c660) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7f97bfcd2a20) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7f97bfcef0d0) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u) + QAbstractListModel (0x0x7f97bfcef138) 0 + primary-for QStringListModel (0x0x7f97bfcef0d0) + QAbstractItemModel (0x0x7f97bfcef1a0) 0 + primary-for QAbstractListModel (0x0x7f97bfcef138) + QObject (0x0x7f97bfcd29c0) 0 + primary-for QAbstractItemModel (0x0x7f97bfcef1a0) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7f97bfcd2a80) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7f97bfcd2b40) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7f97bfcd2c60) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7f97bfcef208) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u) + QFile (0x0x7f97bfcef270) 0 + primary-for QTemporaryFile (0x0x7f97bfcef208) + QFileDevice (0x0x7f97bfcef2d8) 0 + primary-for QFile (0x0x7f97bfcef270) + QIODevice (0x0x7f97bfcef340) 0 + primary-for QFileDevice (0x0x7f97bfcef2d8) + QObject (0x0x7f97bfcd2c00) 0 + primary-for QIODevice (0x0x7f97bfcef340) + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7f97bfcd2cc0) 0 + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7f97bfcd2f00) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 0u +64 0u + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7f97bfcd2ea0) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7f97bf984120) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7f97bf984180) 0 + +Class std::__mutex_base + size=40 align=8 + base size=40 base align=8 +std::__mutex_base (0x0x7f97bf9841e0) 0 + +Class std::__recursive_mutex_base + size=40 align=8 + base size=40 base align=8 +std::__recursive_mutex_base (0x0x7f97bf984240) 0 + +Class std::mutex + size=40 align=8 + base size=40 base align=8 +std::mutex (0x0x7f97bfcef548) 0 + std::__mutex_base (0x0x7f97bf9842a0) 0 + +Class std::recursive_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_mutex (0x0x7f97bfcef5b0) 0 + std::__recursive_mutex_base (0x0x7f97bf984300) 0 + +Class std::timed_mutex + size=40 align=8 + base size=40 base align=8 +std::timed_mutex (0x0x7f97bf9eb310) 0 + std::__mutex_base (0x0x7f97bf984420) 0 + std::__timed_mutex_impl (0x0x7f97bf984480) 0 empty + +Class std::recursive_timed_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_timed_mutex (0x0x7f97bf9ebcb0) 0 + std::__recursive_mutex_base (0x0x7f97bf984540) 0 + std::__timed_mutex_impl (0x0x7f97bf9845a0) 0 empty + +Class std::defer_lock_t + size=1 align=1 + base size=0 base align=1 +std::defer_lock_t (0x0x7f97bf984600) 0 empty + +Class std::try_to_lock_t + size=1 align=1 + base size=0 base align=1 +std::try_to_lock_t (0x0x7f97bf984660) 0 empty + +Class std::adopt_lock_t + size=1 align=1 + base size=0 base align=1 +std::adopt_lock_t (0x0x7f97bf9846c0) 0 empty + +Class std::once_flag + size=4 align=4 + base size=4 base align=4 +std::once_flag (0x0x7f97bf984900) 0 + +Vtable for __gnu_cxx::__concurrence_lock_error +__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what + +Class __gnu_cxx::__concurrence_lock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_lock_error (0x0x7f97bfcef6e8) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16u) + std::exception (0x0x7f97bf9849c0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_lock_error (0x0x7f97bfcef6e8) + +Vtable for __gnu_cxx::__concurrence_unlock_error +__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what + +Class __gnu_cxx::__concurrence_unlock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_unlock_error (0x0x7f97bfcef750) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16u) + std::exception (0x0x7f97bf984a80) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7f97bfcef750) + +Vtable for __gnu_cxx::__concurrence_broadcast_error +__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what + +Class __gnu_cxx::__concurrence_broadcast_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_broadcast_error (0x0x7f97bfcef7b8) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16u) + std::exception (0x0x7f97bf984b40) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7f97bfcef7b8) + +Vtable for __gnu_cxx::__concurrence_wait_error +__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what + +Class __gnu_cxx::__concurrence_wait_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_wait_error (0x0x7f97bfcef888) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16u) + std::exception (0x0x7f97bf984c00) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_wait_error (0x0x7f97bfcef888) + +Class __gnu_cxx::__mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__mutex (0x0x7f97bf984cc0) 0 + +Class __gnu_cxx::__recursive_mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__recursive_mutex (0x0x7f97bf984d20) 0 + +Class __gnu_cxx::__scoped_lock + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__scoped_lock (0x0x7f97bf984d80) 0 + +Class __gnu_cxx::__cond + size=48 align=8 + base size=48 base align=8 +__gnu_cxx::__cond (0x0x7f97bf984de0) 0 + +Vtable for std::bad_weak_ptr +std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12bad_weak_ptr) +16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +32 (int (*)(...))std::bad_weak_ptr::what + +Class std::bad_weak_ptr + size=8 align=8 + base size=8 base align=8 +std::bad_weak_ptr (0x0x7f97bfcefb60) 0 nearly-empty + vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16u) + std::exception (0x0x7f97bfacf180) 0 nearly-empty + primary-for std::bad_weak_ptr (0x0x7f97bfcefb60) + +Class std::_Sp_make_shared_tag + size=1 align=1 + base size=0 base align=1 +std::_Sp_make_shared_tag (0x0x7f97bfacf9c0) 0 empty + +Class std::_Sp_locker + size=2 align=1 + base size=2 base align=1 +std::_Sp_locker (0x0x7f97bf87d1e0) 0 + +Class std::thread::id + size=8 align=8 + base size=8 base align=8 +std::thread::id (0x0x7f97bf87d3c0) 0 + +Vtable for std::thread::_Impl_base +std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6thread10_Impl_baseE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class std::thread::_Impl_base + size=24 align=8 + base size=24 base align=8 +std::thread::_Impl_base (0x0x7f97bf87d420) 0 + vptr=((& std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE) + 16u) + +Class std::thread + size=8 align=8 + base size=8 base align=8 +std::thread (0x0x7f97bf87d360) 0 + +Class std::condition_variable + size=48 align=8 + base size=48 base align=8 +std::condition_variable (0x0x7f97bf61d060) 0 + +Class std::__at_thread_exit_elt + size=16 align=8 + base size=16 base align=8 +std::__at_thread_exit_elt (0x0x7f97bf61d120) 0 + +Class std::_V2::condition_variable_any + size=64 align=8 + base size=64 base align=8 +std::_V2::condition_variable_any (0x0x7f97bf61d180) 0 + +Class std::__atomic_futex_unsigned_base + size=1 align=1 + base size=0 base align=1 +std::__atomic_futex_unsigned_base (0x0x7f97bf6d37e0) 0 empty + +Vtable for std::future_error +std::future_error::_ZTVSt12future_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12future_error) +16 (int (*)(...))std::future_error::~future_error +24 (int (*)(...))std::future_error::~future_error +32 (int (*)(...))std::future_error::what + +Class std::future_error + size=32 align=8 + base size=32 base align=8 +std::future_error (0x0x7f97bf6c4ea0) 0 + vptr=((& std::future_error::_ZTVSt12future_error) + 16u) + std::logic_error (0x0x7f97bf6c4f08) 0 + primary-for std::future_error (0x0x7f97bf6c4ea0) + std::exception (0x0x7f97bf6d3900) 0 nearly-empty + primary-for std::logic_error (0x0x7f97bf6c4f08) + +Class std::__future_base::_Result_base::_Deleter + size=1 align=1 + base size=0 base align=1 +std::__future_base::_Result_base::_Deleter (0x0x7f97bf6d3a20) 0 empty + +Vtable for std::__future_base::_Result_base +std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class std::__future_base::_Result_base + size=16 align=8 + base size=16 base align=8 +std::__future_base::_Result_base (0x0x7f97bf6d39c0) 0 + vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16u) + +Class std::__future_base::_State_baseV2::__exception_ptr_tag + size=1 align=1 + base size=0 base align=1 +std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7f97bf369f60) 0 empty + +Class std::__future_base::_State_baseV2::_Make_ready + size=32 align=8 + base size=32 base align=8 +std::__future_base::_State_baseV2::_Make_ready (0x0x7f97bf4514e0) 0 + std::__at_thread_exit_elt (0x0x7f97bf475060) 0 + +Vtable for std::__future_base::_State_baseV2 +std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E) +16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_State_baseV2 + size=32 align=8 + base size=28 base align=8 +std::__future_base::_State_baseV2 (0x0x7f97bf6d3ba0) 0 + vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16u) + +Class std::__future_base + size=1 align=1 + base size=0 base align=1 +std::__future_base (0x0x7f97bf6d3960) 0 empty + +Vtable for std::__future_base::_Async_state_commonV2 +std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E) +16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_Async_state_commonV2 + size=48 align=8 + base size=44 base align=8 +std::__future_base::_Async_state_commonV2 (0x0x7f97bedf30d0) 0 + vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16u) + std::__future_base::_State_baseV2 (0x0x7f97bed9af00) 0 + primary-for std::__future_base::_Async_state_commonV2 (0x0x7f97bedf30d0) + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7f97bee01660) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7f97bedf3b60) 0 + vptr=((& QThread::_ZTV7QThread) + 16u) + QObject (0x0x7f97bee01600) 0 + primary-for QThread (0x0x7f97bedf3b60) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7f97bee01780) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7f97bedf3bc8) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u) + QObject (0x0x7f97bee01720) 0 + primary-for QThreadPool (0x0x7f97bedf3bc8) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7f97bee017e0) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7f97bee01900) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7f97bedf3c30) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u) + QObject (0x0x7f97bee018a0) 0 + primary-for QTimeLine (0x0x7f97bedf3c30) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7f97bee019c0) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7f97bedf3c98) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16u) + QObject (0x0x7f97bee01960) 0 + primary-for QTimer (0x0x7f97bedf3c98) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7f97beec7120) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7f97beec70c0) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7f97beec76c0) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7f97beebb820) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16u) + QObject (0x0x7f97beec7660) 0 + primary-for QTranslator (0x0x7f97beebb820) + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7f97beec7720) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7f97beec7d80) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7f97beec7de0) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7f97beb720c0) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7f97beb73548) 0 + QVector (0x0x7f97beb72480) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7f97beb724e0) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7f97beb72780) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7f97beb72a20) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7f97beb72cc0) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7f97beb72d20) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7f97bec7d780) 0 + +Class QRgba64 + size=8 align=8 + base size=8 base align=8 +QRgba64 (0x0x7f97bec7d8a0) 0 + +Class QColor + size=16 align=4 + base size=14 base align=4 +QColor (0x0x7f97bec7db40) 0 + +Class QRegion::QRegionData + size=16 align=8 + base size=16 base align=8 +QRegion::QRegionData (0x0x7f97be9a3540) 0 + +Class QRegion + size=8 align=8 + base size=8 base align=8 +QRegion (0x0x7f97be9a34e0) 0 + +Class QKeySequence + size=8 align=8 + base size=8 base align=8 +QKeySequence (0x0x7f97bea548a0) 0 + +Class QVector2D + size=8 align=4 + base size=8 base align=4 +QVector2D (0x0x7f97be705de0) 0 + +Class QTouchDevice + size=8 align=8 + base size=8 base align=8 +QTouchDevice (0x0x7f97be7500c0) 0 + +Vtable for QInputEvent +QInputEvent::_ZTV11QInputEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QInputEvent) +16 (int (*)(...))QInputEvent::~QInputEvent +24 (int (*)(...))QInputEvent::~QInputEvent + +Class QInputEvent + size=32 align=8 + base size=32 base align=8 +QInputEvent (0x0x7f97be72d340) 0 + vptr=((& QInputEvent::_ZTV11QInputEvent) + 16u) + QEvent (0x0x7f97be7502a0) 0 + primary-for QInputEvent (0x0x7f97be72d340) + +Vtable for QEnterEvent +QEnterEvent::_ZTV11QEnterEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QEnterEvent) +16 (int (*)(...))QEnterEvent::~QEnterEvent +24 (int (*)(...))QEnterEvent::~QEnterEvent + +Class QEnterEvent + size=72 align=8 + base size=72 base align=8 +QEnterEvent (0x0x7f97be72d3a8) 0 + vptr=((& QEnterEvent::_ZTV11QEnterEvent) + 16u) + QEvent (0x0x7f97be750300) 0 + primary-for QEnterEvent (0x0x7f97be72d3a8) + +Vtable for QMouseEvent +QMouseEvent::_ZTV11QMouseEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QMouseEvent) +16 (int (*)(...))QMouseEvent::~QMouseEvent +24 (int (*)(...))QMouseEvent::~QMouseEvent + +Class QMouseEvent + size=104 align=8 + base size=100 base align=8 +QMouseEvent (0x0x7f97be72d410) 0 + vptr=((& QMouseEvent::_ZTV11QMouseEvent) + 16u) + QInputEvent (0x0x7f97be72d478) 0 + primary-for QMouseEvent (0x0x7f97be72d410) + QEvent (0x0x7f97be750360) 0 + primary-for QInputEvent (0x0x7f97be72d478) + +Vtable for QHoverEvent +QHoverEvent::_ZTV11QHoverEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QHoverEvent) +16 (int (*)(...))QHoverEvent::~QHoverEvent +24 (int (*)(...))QHoverEvent::~QHoverEvent + +Class QHoverEvent + size=64 align=8 + base size=64 base align=8 +QHoverEvent (0x0x7f97be72d4e0) 0 + vptr=((& QHoverEvent::_ZTV11QHoverEvent) + 16u) + QInputEvent (0x0x7f97be72d548) 0 + primary-for QHoverEvent (0x0x7f97be72d4e0) + QEvent (0x0x7f97be7503c0) 0 + primary-for QInputEvent (0x0x7f97be72d548) + +Vtable for QWheelEvent +QWheelEvent::_ZTV11QWheelEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QWheelEvent) +16 (int (*)(...))QWheelEvent::~QWheelEvent +24 (int (*)(...))QWheelEvent::~QWheelEvent + +Class QWheelEvent + size=96 align=8 + base size=96 base align=8 +QWheelEvent (0x0x7f97be72d5b0) 0 + vptr=((& QWheelEvent::_ZTV11QWheelEvent) + 16u) + QInputEvent (0x0x7f97be72d618) 0 + primary-for QWheelEvent (0x0x7f97be72d5b0) + QEvent (0x0x7f97be750420) 0 + primary-for QInputEvent (0x0x7f97be72d618) + +Vtable for QTabletEvent +QTabletEvent::_ZTV12QTabletEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QTabletEvent) +16 (int (*)(...))QTabletEvent::~QTabletEvent +24 (int (*)(...))QTabletEvent::~QTabletEvent + +Class QTabletEvent + size=128 align=8 + base size=128 base align=8 +QTabletEvent (0x0x7f97be72d680) 0 + vptr=((& QTabletEvent::_ZTV12QTabletEvent) + 16u) + QInputEvent (0x0x7f97be72d6e8) 0 + primary-for QTabletEvent (0x0x7f97be72d680) + QEvent (0x0x7f97be750480) 0 + primary-for QInputEvent (0x0x7f97be72d6e8) + +Vtable for QNativeGestureEvent +QNativeGestureEvent::_ZTV19QNativeGestureEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QNativeGestureEvent) +16 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent +24 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent + +Class QNativeGestureEvent + size=112 align=8 + base size=112 base align=8 +QNativeGestureEvent (0x0x7f97be72d750) 0 + vptr=((& QNativeGestureEvent::_ZTV19QNativeGestureEvent) + 16u) + QInputEvent (0x0x7f97be72d7b8) 0 + primary-for QNativeGestureEvent (0x0x7f97be72d750) + QEvent (0x0x7f97be7504e0) 0 + primary-for QInputEvent (0x0x7f97be72d7b8) + +Vtable for QKeyEvent +QKeyEvent::_ZTV9QKeyEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QKeyEvent) +16 (int (*)(...))QKeyEvent::~QKeyEvent +24 (int (*)(...))QKeyEvent::~QKeyEvent + +Class QKeyEvent + size=64 align=8 + base size=59 base align=8 +QKeyEvent (0x0x7f97be72d820) 0 + vptr=((& QKeyEvent::_ZTV9QKeyEvent) + 16u) + QInputEvent (0x0x7f97be72d888) 0 + primary-for QKeyEvent (0x0x7f97be72d820) + QEvent (0x0x7f97be750540) 0 + primary-for QInputEvent (0x0x7f97be72d888) + +Vtable for QFocusEvent +QFocusEvent::_ZTV11QFocusEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFocusEvent) +16 (int (*)(...))QFocusEvent::~QFocusEvent +24 (int (*)(...))QFocusEvent::~QFocusEvent + +Class QFocusEvent + size=24 align=8 + base size=24 base align=8 +QFocusEvent (0x0x7f97be72d8f0) 0 + vptr=((& QFocusEvent::_ZTV11QFocusEvent) + 16u) + QEvent (0x0x7f97be7505a0) 0 + primary-for QFocusEvent (0x0x7f97be72d8f0) + +Vtable for QPaintEvent +QPaintEvent::_ZTV11QPaintEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QPaintEvent) +16 (int (*)(...))QPaintEvent::~QPaintEvent +24 (int (*)(...))QPaintEvent::~QPaintEvent + +Class QPaintEvent + size=56 align=8 + base size=49 base align=8 +QPaintEvent (0x0x7f97be72d958) 0 + vptr=((& QPaintEvent::_ZTV11QPaintEvent) + 16u) + QEvent (0x0x7f97be750600) 0 + primary-for QPaintEvent (0x0x7f97be72d958) + +Vtable for QMoveEvent +QMoveEvent::_ZTV10QMoveEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QMoveEvent) +16 (int (*)(...))QMoveEvent::~QMoveEvent +24 (int (*)(...))QMoveEvent::~QMoveEvent + +Class QMoveEvent + size=40 align=8 + base size=36 base align=8 +QMoveEvent (0x0x7f97be72d9c0) 0 + vptr=((& QMoveEvent::_ZTV10QMoveEvent) + 16u) + QEvent (0x0x7f97be750660) 0 + primary-for QMoveEvent (0x0x7f97be72d9c0) + +Vtable for QExposeEvent +QExposeEvent::_ZTV12QExposeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QExposeEvent) +16 (int (*)(...))QExposeEvent::~QExposeEvent +24 (int (*)(...))QExposeEvent::~QExposeEvent + +Class QExposeEvent + size=32 align=8 + base size=32 base align=8 +QExposeEvent (0x0x7f97be72da28) 0 + vptr=((& QExposeEvent::_ZTV12QExposeEvent) + 16u) + QEvent (0x0x7f97be7506c0) 0 + primary-for QExposeEvent (0x0x7f97be72da28) + +Vtable for QPlatformSurfaceEvent +QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QPlatformSurfaceEvent) +16 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent +24 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent + +Class QPlatformSurfaceEvent + size=24 align=8 + base size=24 base align=8 +QPlatformSurfaceEvent (0x0x7f97be72da90) 0 + vptr=((& QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent) + 16u) + QEvent (0x0x7f97be750720) 0 + primary-for QPlatformSurfaceEvent (0x0x7f97be72da90) + +Vtable for QResizeEvent +QResizeEvent::_ZTV12QResizeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QResizeEvent) +16 (int (*)(...))QResizeEvent::~QResizeEvent +24 (int (*)(...))QResizeEvent::~QResizeEvent + +Class QResizeEvent + size=40 align=8 + base size=36 base align=8 +QResizeEvent (0x0x7f97be72daf8) 0 + vptr=((& QResizeEvent::_ZTV12QResizeEvent) + 16u) + QEvent (0x0x7f97be750780) 0 + primary-for QResizeEvent (0x0x7f97be72daf8) + +Vtable for QCloseEvent +QCloseEvent::_ZTV11QCloseEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QCloseEvent) +16 (int (*)(...))QCloseEvent::~QCloseEvent +24 (int (*)(...))QCloseEvent::~QCloseEvent + +Class QCloseEvent + size=24 align=8 + base size=20 base align=8 +QCloseEvent (0x0x7f97be72db60) 0 + vptr=((& QCloseEvent::_ZTV11QCloseEvent) + 16u) + QEvent (0x0x7f97be7507e0) 0 + primary-for QCloseEvent (0x0x7f97be72db60) + +Vtable for QIconDragEvent +QIconDragEvent::_ZTV14QIconDragEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QIconDragEvent) +16 (int (*)(...))QIconDragEvent::~QIconDragEvent +24 (int (*)(...))QIconDragEvent::~QIconDragEvent + +Class QIconDragEvent + size=24 align=8 + base size=20 base align=8 +QIconDragEvent (0x0x7f97be72dbc8) 0 + vptr=((& QIconDragEvent::_ZTV14QIconDragEvent) + 16u) + QEvent (0x0x7f97be750840) 0 + primary-for QIconDragEvent (0x0x7f97be72dbc8) + +Vtable for QShowEvent +QShowEvent::_ZTV10QShowEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QShowEvent) +16 (int (*)(...))QShowEvent::~QShowEvent +24 (int (*)(...))QShowEvent::~QShowEvent + +Class QShowEvent + size=24 align=8 + base size=20 base align=8 +QShowEvent (0x0x7f97be72dc30) 0 + vptr=((& QShowEvent::_ZTV10QShowEvent) + 16u) + QEvent (0x0x7f97be7508a0) 0 + primary-for QShowEvent (0x0x7f97be72dc30) + +Vtable for QHideEvent +QHideEvent::_ZTV10QHideEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QHideEvent) +16 (int (*)(...))QHideEvent::~QHideEvent +24 (int (*)(...))QHideEvent::~QHideEvent + +Class QHideEvent + size=24 align=8 + base size=20 base align=8 +QHideEvent (0x0x7f97be72dc98) 0 + vptr=((& QHideEvent::_ZTV10QHideEvent) + 16u) + QEvent (0x0x7f97be750900) 0 + primary-for QHideEvent (0x0x7f97be72dc98) + +Vtable for QContextMenuEvent +QContextMenuEvent::_ZTV17QContextMenuEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QContextMenuEvent) +16 (int (*)(...))QContextMenuEvent::~QContextMenuEvent +24 (int (*)(...))QContextMenuEvent::~QContextMenuEvent + +Class QContextMenuEvent + size=56 align=8 + base size=49 base align=8 +QContextMenuEvent (0x0x7f97be72dd00) 0 + vptr=((& QContextMenuEvent::_ZTV17QContextMenuEvent) + 16u) + QInputEvent (0x0x7f97be72dd68) 0 + primary-for QContextMenuEvent (0x0x7f97be72dd00) + QEvent (0x0x7f97be750960) 0 + primary-for QInputEvent (0x0x7f97be72dd68) + +Class QInputMethodEvent::Attribute + size=32 align=8 + base size=32 base align=8 +QInputMethodEvent::Attribute (0x0x7f97be750a20) 0 + +Vtable for QInputMethodEvent +QInputMethodEvent::_ZTV17QInputMethodEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QInputMethodEvent) +16 (int (*)(...))QInputMethodEvent::~QInputMethodEvent +24 (int (*)(...))QInputMethodEvent::~QInputMethodEvent + +Class QInputMethodEvent + size=56 align=8 + base size=56 base align=8 +QInputMethodEvent (0x0x7f97be72ddd0) 0 + vptr=((& QInputMethodEvent::_ZTV17QInputMethodEvent) + 16u) + QEvent (0x0x7f97be7509c0) 0 + primary-for QInputMethodEvent (0x0x7f97be72ddd0) + +Class QInputMethodQueryEvent::QueryPair + size=24 align=8 + base size=24 base align=8 +QInputMethodQueryEvent::QueryPair (0x0x7f97be750ea0) 0 + +Vtable for QInputMethodQueryEvent +QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QInputMethodQueryEvent) +16 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent +24 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent + +Class QInputMethodQueryEvent + size=32 align=8 + base size=32 base align=8 +QInputMethodQueryEvent (0x0x7f97be8c2138) 0 + vptr=((& QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent) + 16u) + QEvent (0x0x7f97be750e40) 0 + primary-for QInputMethodQueryEvent (0x0x7f97be8c2138) + +Vtable for QDropEvent +QDropEvent::_ZTV10QDropEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QDropEvent) +16 (int (*)(...))QDropEvent::~QDropEvent +24 (int (*)(...))QDropEvent::~QDropEvent + +Class QDropEvent + size=72 align=8 + base size=72 base align=8 +QDropEvent (0x0x7f97be8c2410) 0 + vptr=((& QDropEvent::_ZTV10QDropEvent) + 16u) + QEvent (0x0x7f97be4fc240) 0 + primary-for QDropEvent (0x0x7f97be8c2410) + +Vtable for QDragMoveEvent +QDragMoveEvent::_ZTV14QDragMoveEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QDragMoveEvent) +16 (int (*)(...))QDragMoveEvent::~QDragMoveEvent +24 (int (*)(...))QDragMoveEvent::~QDragMoveEvent + +Class QDragMoveEvent + size=88 align=8 + base size=88 base align=8 +QDragMoveEvent (0x0x7f97be8c2478) 0 + vptr=((& QDragMoveEvent::_ZTV14QDragMoveEvent) + 16u) + QDropEvent (0x0x7f97be8c24e0) 0 + primary-for QDragMoveEvent (0x0x7f97be8c2478) + QEvent (0x0x7f97be4fc2a0) 0 + primary-for QDropEvent (0x0x7f97be8c24e0) + +Vtable for QDragEnterEvent +QDragEnterEvent::_ZTV15QDragEnterEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QDragEnterEvent) +16 (int (*)(...))QDragEnterEvent::~QDragEnterEvent +24 (int (*)(...))QDragEnterEvent::~QDragEnterEvent + +Class QDragEnterEvent + size=88 align=8 + base size=88 base align=8 +QDragEnterEvent (0x0x7f97be8c2548) 0 + vptr=((& QDragEnterEvent::_ZTV15QDragEnterEvent) + 16u) + QDragMoveEvent (0x0x7f97be8c25b0) 0 + primary-for QDragEnterEvent (0x0x7f97be8c2548) + QDropEvent (0x0x7f97be8c2618) 0 + primary-for QDragMoveEvent (0x0x7f97be8c25b0) + QEvent (0x0x7f97be4fc300) 0 + primary-for QDropEvent (0x0x7f97be8c2618) + +Vtable for QDragLeaveEvent +QDragLeaveEvent::_ZTV15QDragLeaveEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QDragLeaveEvent) +16 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent +24 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent + +Class QDragLeaveEvent + size=24 align=8 + base size=20 base align=8 +QDragLeaveEvent (0x0x7f97be8c2680) 0 + vptr=((& QDragLeaveEvent::_ZTV15QDragLeaveEvent) + 16u) + QEvent (0x0x7f97be4fc360) 0 + primary-for QDragLeaveEvent (0x0x7f97be8c2680) + +Vtable for QHelpEvent +QHelpEvent::_ZTV10QHelpEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QHelpEvent) +16 (int (*)(...))QHelpEvent::~QHelpEvent +24 (int (*)(...))QHelpEvent::~QHelpEvent + +Class QHelpEvent + size=40 align=8 + base size=36 base align=8 +QHelpEvent (0x0x7f97be8c26e8) 0 + vptr=((& QHelpEvent::_ZTV10QHelpEvent) + 16u) + QEvent (0x0x7f97be4fc3c0) 0 + primary-for QHelpEvent (0x0x7f97be8c26e8) + +Vtable for QStatusTipEvent +QStatusTipEvent::_ZTV15QStatusTipEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QStatusTipEvent) +16 (int (*)(...))QStatusTipEvent::~QStatusTipEvent +24 (int (*)(...))QStatusTipEvent::~QStatusTipEvent + +Class QStatusTipEvent + size=32 align=8 + base size=32 base align=8 +QStatusTipEvent (0x0x7f97be8c2750) 0 + vptr=((& QStatusTipEvent::_ZTV15QStatusTipEvent) + 16u) + QEvent (0x0x7f97be4fc420) 0 + primary-for QStatusTipEvent (0x0x7f97be8c2750) + +Vtable for QWhatsThisClickedEvent +QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QWhatsThisClickedEvent) +16 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent +24 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent + +Class QWhatsThisClickedEvent + size=32 align=8 + base size=32 base align=8 +QWhatsThisClickedEvent (0x0x7f97be8c27b8) 0 + vptr=((& QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent) + 16u) + QEvent (0x0x7f97be4fc480) 0 + primary-for QWhatsThisClickedEvent (0x0x7f97be8c27b8) + +Vtable for QActionEvent +QActionEvent::_ZTV12QActionEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QActionEvent) +16 (int (*)(...))QActionEvent::~QActionEvent +24 (int (*)(...))QActionEvent::~QActionEvent + +Class QActionEvent + size=40 align=8 + base size=40 base align=8 +QActionEvent (0x0x7f97be8c2820) 0 + vptr=((& QActionEvent::_ZTV12QActionEvent) + 16u) + QEvent (0x0x7f97be4fc4e0) 0 + primary-for QActionEvent (0x0x7f97be8c2820) + +Vtable for QFileOpenEvent +QFileOpenEvent::_ZTV14QFileOpenEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QFileOpenEvent) +16 (int (*)(...))QFileOpenEvent::~QFileOpenEvent +24 (int (*)(...))QFileOpenEvent::~QFileOpenEvent + +Class QFileOpenEvent + size=40 align=8 + base size=40 base align=8 +QFileOpenEvent (0x0x7f97be8c2888) 0 + vptr=((& QFileOpenEvent::_ZTV14QFileOpenEvent) + 16u) + QEvent (0x0x7f97be4fc540) 0 + primary-for QFileOpenEvent (0x0x7f97be8c2888) + +Vtable for QToolBarChangeEvent +QToolBarChangeEvent::_ZTV19QToolBarChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QToolBarChangeEvent) +16 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent +24 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent + +Class QToolBarChangeEvent + size=24 align=8 + base size=21 base align=8 +QToolBarChangeEvent (0x0x7f97be8c28f0) 0 + vptr=((& QToolBarChangeEvent::_ZTV19QToolBarChangeEvent) + 16u) + QEvent (0x0x7f97be4fc5a0) 0 + primary-for QToolBarChangeEvent (0x0x7f97be8c28f0) + +Vtable for QShortcutEvent +QShortcutEvent::_ZTV14QShortcutEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QShortcutEvent) +16 (int (*)(...))QShortcutEvent::~QShortcutEvent +24 (int (*)(...))QShortcutEvent::~QShortcutEvent + +Class QShortcutEvent + size=40 align=8 + base size=40 base align=8 +QShortcutEvent (0x0x7f97be8c2958) 0 + vptr=((& QShortcutEvent::_ZTV14QShortcutEvent) + 16u) + QEvent (0x0x7f97be4fc600) 0 + primary-for QShortcutEvent (0x0x7f97be8c2958) + +Vtable for QWindowStateChangeEvent +QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QWindowStateChangeEvent) +16 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent +24 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent + +Class QWindowStateChangeEvent + size=32 align=8 + base size=25 base align=8 +QWindowStateChangeEvent (0x0x7f97be8c29c0) 0 + vptr=((& QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent) + 16u) + QEvent (0x0x7f97be4fc660) 0 + primary-for QWindowStateChangeEvent (0x0x7f97be8c29c0) + +Class QPointingDeviceUniqueId + size=8 align=8 + base size=8 base align=8 +QPointingDeviceUniqueId (0x0x7f97be4fc6c0) 0 + +Class QTouchEvent::TouchPoint + size=8 align=8 + base size=8 base align=8 +QTouchEvent::TouchPoint (0x0x7f97be4fcd80) 0 + +Vtable for QTouchEvent +QTouchEvent::_ZTV11QTouchEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTouchEvent) +16 (int (*)(...))QTouchEvent::~QTouchEvent +24 (int (*)(...))QTouchEvent::~QTouchEvent + +Class QTouchEvent + size=72 align=8 + base size=72 base align=8 +QTouchEvent (0x0x7f97be563068) 0 + vptr=((& QTouchEvent::_ZTV11QTouchEvent) + 16u) + QInputEvent (0x0x7f97be5630d0) 0 + primary-for QTouchEvent (0x0x7f97be563068) + QEvent (0x0x7f97be4fcd20) 0 + primary-for QInputEvent (0x0x7f97be5630d0) + +Vtable for QScrollPrepareEvent +QScrollPrepareEvent::_ZTV19QScrollPrepareEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QScrollPrepareEvent) +16 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent +24 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent + +Class QScrollPrepareEvent + size=112 align=8 + base size=112 base align=8 +QScrollPrepareEvent (0x0x7f97be6238f0) 0 + vptr=((& QScrollPrepareEvent::_ZTV19QScrollPrepareEvent) + 16u) + QEvent (0x0x7f97be62a420) 0 + primary-for QScrollPrepareEvent (0x0x7f97be6238f0) + +Vtable for QScrollEvent +QScrollEvent::_ZTV12QScrollEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QScrollEvent) +16 (int (*)(...))QScrollEvent::~QScrollEvent +24 (int (*)(...))QScrollEvent::~QScrollEvent + +Class QScrollEvent + size=64 align=8 + base size=60 base align=8 +QScrollEvent (0x0x7f97be623958) 0 + vptr=((& QScrollEvent::_ZTV12QScrollEvent) + 16u) + QEvent (0x0x7f97be62a480) 0 + primary-for QScrollEvent (0x0x7f97be623958) + +Vtable for QScreenOrientationChangeEvent +QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QScreenOrientationChangeEvent) +16 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent +24 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent + +Class QScreenOrientationChangeEvent + size=40 align=8 + base size=36 base align=8 +QScreenOrientationChangeEvent (0x0x7f97be6239c0) 0 + vptr=((& QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent) + 16u) + QEvent (0x0x7f97be62a4e0) 0 + primary-for QScreenOrientationChangeEvent (0x0x7f97be6239c0) + +Vtable for QApplicationStateChangeEvent +QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QApplicationStateChangeEvent) +16 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent +24 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent + +Class QApplicationStateChangeEvent + size=24 align=8 + base size=24 base align=8 +QApplicationStateChangeEvent (0x0x7f97be623a28) 0 + vptr=((& QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent) + 16u) + QEvent (0x0x7f97be62a540) 0 + primary-for QApplicationStateChangeEvent (0x0x7f97be623a28) + +Class QFont + size=16 align=8 + base size=12 base align=8 +QFont (0x0x7f97be62a5a0) 0 + +Class QPolygon + size=8 align=8 + base size=8 base align=8 +QPolygon (0x0x7f97be2df7b8) 0 + QVector (0x0x7f97be2eb2a0) 0 + +Class QPolygonF + size=8 align=8 + base size=8 base align=8 +QPolygonF (0x0x7f97be2dfb60) 0 + QVector (0x0x7f97be2eb720) 0 + +Class QMatrix + size=48 align=8 + base size=48 base align=8 +QMatrix (0x0x7f97be2ebae0) 0 + +Class QPainterPath::Element + size=24 align=8 + base size=24 base align=8 +QPainterPath::Element (0x0x7f97be2ebde0) 0 + +Class QPainterPath + size=8 align=8 + base size=8 base align=8 +QPainterPath (0x0x7f97be2ebd80) 0 + +Class QPainterPathStroker + size=8 align=8 + base size=8 base align=8 +QPainterPathStroker (0x0x7f97be4337e0) 0 + +Class QTransform + size=88 align=8 + base size=88 base align=8 +QTransform (0x0x7f97be433900) 0 + +Vtable for QPaintDevice +QPaintDevice::_ZTV12QPaintDevice: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QPaintDevice) +16 0u +24 0u +32 (int (*)(...))QPaintDevice::devType +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QPaintDevice + size=24 align=8 + base size=24 base align=8 +QPaintDevice (0x0x7f97be4cf060) 0 + vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 16u) + +Class QPixelFormat + size=8 align=8 + base size=8 base align=8 +QPixelFormat (0x0x7f97be4cf0c0) 0 + +Vtable for QImage +QImage::_ZTV6QImage: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QImage) +16 (int (*)(...))QImage::~QImage +24 (int (*)(...))QImage::~QImage +32 (int (*)(...))QImage::devType +40 (int (*)(...))QImage::paintEngine +48 (int (*)(...))QImage::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QImage + size=32 align=8 + base size=32 base align=8 +QImage (0x0x7f97be181a28) 0 + vptr=((& QImage::_ZTV6QImage) + 16u) + QPaintDevice (0x0x7f97be4cfb40) 0 + primary-for QImage (0x0x7f97be181a28) + +Vtable for QPixmap +QPixmap::_ZTV7QPixmap: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QPixmap) +16 (int (*)(...))QPixmap::~QPixmap +24 (int (*)(...))QPixmap::~QPixmap +32 (int (*)(...))QPixmap::devType +40 (int (*)(...))QPixmap::paintEngine +48 (int (*)(...))QPixmap::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QPixmap + size=32 align=8 + base size=32 base align=8 +QPixmap (0x0x7f97be2675b0) 0 + vptr=((& QPixmap::_ZTV7QPixmap) + 16u) + QPaintDevice (0x0x7f97be25aae0) 0 + primary-for QPixmap (0x0x7f97be2675b0) + +Class QBrush + size=8 align=8 + base size=8 base align=8 +QBrush (0x0x7f97be25ade0) 0 + +Class QBrushData + size=112 align=8 + base size=112 base align=8 +QBrushData (0x0x7f97bdef35a0) 0 + +Class QGradient + size=64 align=8 + base size=64 base align=8 +QGradient (0x0x7f97bdef3600) 0 + +Class QLinearGradient + size=64 align=8 + base size=64 base align=8 +QLinearGradient (0x0x7f97be267f08) 0 + QGradient (0x0x7f97bdef38a0) 0 + +Class QRadialGradient + size=64 align=8 + base size=64 base align=8 +QRadialGradient (0x0x7f97be267f70) 0 + QGradient (0x0x7f97bdef3900) 0 + +Class QConicalGradient + size=64 align=8 + base size=64 base align=8 +QConicalGradient (0x0x7f97bdf6f000) 0 + QGradient (0x0x7f97bdef3960) 0 + +Class QPen + size=8 align=8 + base size=8 base align=8 +QPen (0x0x7f97bdef39c0) 0 + +Class QTextOption::Tab + size=16 align=8 + base size=14 base align=8 +QTextOption::Tab (0x0x7f97bdfedc00) 0 + +Class QTextOption + size=32 align=8 + base size=32 base align=8 +QTextOption (0x0x7f97bdfedba0) 0 + +Class QTextLength + size=16 align=8 + base size=16 base align=8 +QTextLength (0x0x7f97be0253c0) 0 + +Class QTextFormat + size=16 align=8 + base size=12 base align=8 +QTextFormat (0x0x7f97be025ae0) 0 + +Class QTextCharFormat + size=16 align=8 + base size=12 base align=8 +QTextCharFormat (0x0x7f97be08faf8) 0 + QTextFormat (0x0x7f97be0d6960) 0 + +Class QTextBlockFormat + size=16 align=8 + base size=12 base align=8 +QTextBlockFormat (0x0x7f97bddc1138) 0 + QTextFormat (0x0x7f97be0d6c00) 0 + +Class QTextListFormat + size=16 align=8 + base size=12 base align=8 +QTextListFormat (0x0x7f97bddc13a8) 0 + QTextFormat (0x0x7f97be0d6ea0) 0 + +Class QTextImageFormat + size=16 align=8 + base size=12 base align=8 +QTextImageFormat (0x0x7f97bddc15b0) 0 + QTextCharFormat (0x0x7f97bddc1618) 0 + QTextFormat (0x0x7f97bddfe180) 0 + +Class QTextFrameFormat + size=16 align=8 + base size=12 base align=8 +QTextFrameFormat (0x0x7f97bddc1820) 0 + QTextFormat (0x0x7f97bddfe420) 0 + +Class QTextTableFormat + size=16 align=8 + base size=12 base align=8 +QTextTableFormat (0x0x7f97bddc1a28) 0 + QTextFrameFormat (0x0x7f97bddc1a90) 0 + QTextFormat (0x0x7f97bddfe6c0) 0 + +Class QTextTableCellFormat + size=16 align=8 + base size=12 base align=8 +QTextTableCellFormat (0x0x7f97bddc1c98) 0 + QTextCharFormat (0x0x7f97bddc1d00) 0 + QTextFormat (0x0x7f97bddfe9c0) 0 + +Class QFontDatabase + size=8 align=8 + base size=8 base align=8 +QFontDatabase (0x0x7f97bddfec60) 0 + +Class QRawFont + size=8 align=8 + base size=8 base align=8 +QRawFont (0x0x7f97bddfecc0) 0 + +Class QGlyphRun + size=8 align=8 + base size=8 base align=8 +QGlyphRun (0x0x7f97bdebe1e0) 0 + +Class QTextCursor + size=8 align=8 + base size=8 base align=8 +QTextCursor (0x0x7f97bdebe4e0) 0 + +Class QTextInlineObject + size=16 align=8 + base size=16 base align=8 +QTextInlineObject (0x0x7f97bdebe7e0) 0 + +Class QTextLayout::FormatRange + size=24 align=8 + base size=24 base align=8 +QTextLayout::FormatRange (0x0x7f97bdebe8a0) 0 + +Class QTextLayout + size=8 align=8 + base size=8 base align=8 +QTextLayout (0x0x7f97bdebe840) 0 + +Class QTextLine + size=16 align=8 + base size=16 base align=8 +QTextLine (0x0x7f97bdbab300) 0 + +Vtable for QAbstractUndoItem +QAbstractUndoItem::_ZTV17QAbstractUndoItem: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAbstractUndoItem) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QAbstractUndoItem + size=8 align=8 + base size=8 base align=8 +QAbstractUndoItem (0x0x7f97bdbab360) 0 nearly-empty + vptr=((& QAbstractUndoItem::_ZTV17QAbstractUndoItem) + 16u) + +Class QTextDocument::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextDocument::QPrivateSignal (0x0x7f97bdbab420) 0 empty + +Vtable for QTextDocument +QTextDocument::_ZTV13QTextDocument: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QTextDocument) +16 (int (*)(...))QTextDocument::metaObject +24 (int (*)(...))QTextDocument::qt_metacast +32 (int (*)(...))QTextDocument::qt_metacall +40 (int (*)(...))QTextDocument::~QTextDocument +48 (int (*)(...))QTextDocument::~QTextDocument +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextDocument::clear +120 (int (*)(...))QTextDocument::createObject +128 (int (*)(...))QTextDocument::loadResource + +Class QTextDocument + size=16 align=8 + base size=16 base align=8 +QTextDocument (0x0x7f97bdbb8068) 0 + vptr=((& QTextDocument::_ZTV13QTextDocument) + 16u) + QObject (0x0x7f97bdbab3c0) 0 + primary-for QTextDocument (0x0x7f97bdbb8068) + +Class QPalette::Data + size=4 align=4 + base size=4 base align=4 +QPalette::Data (0x0x7f97bdbab660) 0 + +Class QPalette + size=16 align=8 + base size=12 base align=8 +QPalette (0x0x7f97bdbab600) 0 + +Class QAbstractTextDocumentLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTextDocumentLayout::QPrivateSignal (0x0x7f97bdccc720) 0 empty + +Class QAbstractTextDocumentLayout::Selection + size=24 align=8 + base size=24 base align=8 +QAbstractTextDocumentLayout::Selection (0x0x7f97bdccc780) 0 + +Class QAbstractTextDocumentLayout::PaintContext + size=64 align=8 + base size=64 base align=8 +QAbstractTextDocumentLayout::PaintContext (0x0x7f97bdccc7e0) 0 + +Vtable for QAbstractTextDocumentLayout +QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAbstractTextDocumentLayout) +16 (int (*)(...))QAbstractTextDocumentLayout::metaObject +24 (int (*)(...))QAbstractTextDocumentLayout::qt_metacast +32 (int (*)(...))QAbstractTextDocumentLayout::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractTextDocumentLayout::resizeInlineObject +176 (int (*)(...))QAbstractTextDocumentLayout::positionInlineObject +184 (int (*)(...))QAbstractTextDocumentLayout::drawInlineObject + +Class QAbstractTextDocumentLayout + size=16 align=8 + base size=16 base align=8 +QAbstractTextDocumentLayout (0x0x7f97bdcc8d68) 0 + vptr=((& QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout) + 16u) + QObject (0x0x7f97bdccc6c0) 0 + primary-for QAbstractTextDocumentLayout (0x0x7f97bdcc8d68) + +Vtable for QTextObjectInterface +QTextObjectInterface::_ZTV20QTextObjectInterface: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTextObjectInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QTextObjectInterface + size=8 align=8 + base size=8 base align=8 +QTextObjectInterface (0x0x7f97bdcccd80) 0 nearly-empty + vptr=((& QTextObjectInterface::_ZTV20QTextObjectInterface) + 16u) + +Class QAccessible::State + size=8 align=8 + base size=5 base align=8 +QAccessible::State (0x0x7f97bdcccea0) 0 + +Vtable for QAccessible::ActivationObserver +QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN11QAccessible18ActivationObserverE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAccessible::ActivationObserver + size=8 align=8 + base size=8 base align=8 +QAccessible::ActivationObserver (0x0x7f97bdcccf00) 0 nearly-empty + vptr=((& QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE) + 16u) + +Class QAccessible + size=1 align=1 + base size=0 base align=1 +QAccessible (0x0x7f97bdccce40) 0 empty + +Vtable for QAccessibleInterface +QAccessibleInterface::_ZTV20QAccessibleInterface: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QAccessibleInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QAccessibleInterface::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleInterface::focusChild +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleInterface (0x0x7f97bd97f120) 0 nearly-empty + vptr=((& QAccessibleInterface::_ZTV20QAccessibleInterface) + 16u) + +Vtable for QAccessibleTextInterface +QAccessibleTextInterface::_ZTV24QAccessibleTextInterface: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAccessibleTextInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))QAccessibleTextInterface::textBeforeOffset +104 (int (*)(...))QAccessibleTextInterface::textAfterOffset +112 (int (*)(...))QAccessibleTextInterface::textAtOffset +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTextInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTextInterface (0x0x7f97bd97f180) 0 nearly-empty + vptr=((& QAccessibleTextInterface::_ZTV24QAccessibleTextInterface) + 16u) + +Vtable for QAccessibleEditableTextInterface +QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI32QAccessibleEditableTextInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleEditableTextInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleEditableTextInterface (0x0x7f97bd97f1e0) 0 nearly-empty + vptr=((& QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface) + 16u) + +Vtable for QAccessibleValueInterface +QAccessibleValueInterface::_ZTV25QAccessibleValueInterface: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleValueInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleValueInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleValueInterface (0x0x7f97bd97f240) 0 nearly-empty + vptr=((& QAccessibleValueInterface::_ZTV25QAccessibleValueInterface) + 16u) + +Vtable for QAccessibleTableCellInterface +QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface: 12u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QAccessibleTableCellInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTableCellInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTableCellInterface (0x0x7f97bd97f2a0) 0 nearly-empty + vptr=((& QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface) + 16u) + +Vtable for QAccessibleTableInterface +QAccessibleTableInterface::_ZTV25QAccessibleTableInterface: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleTableInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTableInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTableInterface (0x0x7f97bd97f300) 0 nearly-empty + vptr=((& QAccessibleTableInterface::_ZTV25QAccessibleTableInterface) + 16u) + +Vtable for QAccessibleActionInterface +QAccessibleActionInterface::_ZTV26QAccessibleActionInterface: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleActionInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QAccessibleActionInterface::localizedActionName +48 (int (*)(...))QAccessibleActionInterface::localizedActionDescription +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleActionInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleActionInterface (0x0x7f97bd97f360) 0 nearly-empty + vptr=((& QAccessibleActionInterface::_ZTV26QAccessibleActionInterface) + 16u) + +Vtable for QAccessibleImageInterface +QAccessibleImageInterface::_ZTV25QAccessibleImageInterface: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleImageInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleImageInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleImageInterface (0x0x7f97bd97f3c0) 0 nearly-empty + vptr=((& QAccessibleImageInterface::_ZTV25QAccessibleImageInterface) + 16u) + +Vtable for QAccessibleEvent +QAccessibleEvent::_ZTV16QAccessibleEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAccessibleEvent) +16 (int (*)(...))QAccessibleEvent::~QAccessibleEvent +24 (int (*)(...))QAccessibleEvent::~QAccessibleEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleEvent + size=32 align=8 + base size=28 base align=8 +QAccessibleEvent (0x0x7f97bd97f420) 0 + vptr=((& QAccessibleEvent::_ZTV16QAccessibleEvent) + 16u) + +Vtable for QAccessibleStateChangeEvent +QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAccessibleStateChangeEvent) +16 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent +24 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleStateChangeEvent + size=40 align=8 + base size=40 base align=8 +QAccessibleStateChangeEvent (0x0x7f97bd9467b8) 0 + vptr=((& QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent) + 16u) + QAccessibleEvent (0x0x7f97bd97f960) 0 + primary-for QAccessibleStateChangeEvent (0x0x7f97bd9467b8) + +Vtable for QAccessibleTextCursorEvent +QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextCursorEvent) +16 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent +24 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextCursorEvent + size=32 align=8 + base size=32 base align=8 +QAccessibleTextCursorEvent (0x0x7f97bd946820) 0 + vptr=((& QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent) + 16u) + QAccessibleEvent (0x0x7f97bd97f9c0) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f97bd946820) + +Vtable for QAccessibleTextSelectionEvent +QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QAccessibleTextSelectionEvent) +16 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent +24 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextSelectionEvent + size=40 align=8 + base size=40 base align=8 +QAccessibleTextSelectionEvent (0x0x7f97bd946888) 0 + vptr=((& QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7f97bd9468f0) 0 + primary-for QAccessibleTextSelectionEvent (0x0x7f97bd946888) + QAccessibleEvent (0x0x7f97bd97fa20) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f97bd9468f0) + +Vtable for QAccessibleTextInsertEvent +QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextInsertEvent) +16 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent +24 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextInsertEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTextInsertEvent (0x0x7f97bd946958) 0 + vptr=((& QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7f97bd9469c0) 0 + primary-for QAccessibleTextInsertEvent (0x0x7f97bd946958) + QAccessibleEvent (0x0x7f97bd97fa80) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f97bd9469c0) + +Vtable for QAccessibleTextRemoveEvent +QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextRemoveEvent) +16 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent +24 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextRemoveEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTextRemoveEvent (0x0x7f97bd946a28) 0 + vptr=((& QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7f97bd946a90) 0 + primary-for QAccessibleTextRemoveEvent (0x0x7f97bd946a28) + QAccessibleEvent (0x0x7f97bd97fae0) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f97bd946a90) + +Vtable for QAccessibleTextUpdateEvent +QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextUpdateEvent) +16 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent +24 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextUpdateEvent + size=56 align=8 + base size=56 base align=8 +QAccessibleTextUpdateEvent (0x0x7f97bd946af8) 0 + vptr=((& QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7f97bd946b60) 0 + primary-for QAccessibleTextUpdateEvent (0x0x7f97bd946af8) + QAccessibleEvent (0x0x7f97bd97fb40) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f97bd946b60) + +Vtable for QAccessibleValueChangeEvent +QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAccessibleValueChangeEvent) +16 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent +24 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleValueChangeEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleValueChangeEvent (0x0x7f97bd946bc8) 0 + vptr=((& QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent) + 16u) + QAccessibleEvent (0x0x7f97bd97fba0) 0 + primary-for QAccessibleValueChangeEvent (0x0x7f97bd946bc8) + +Vtable for QAccessibleTableModelChangeEvent +QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI32QAccessibleTableModelChangeEvent) +16 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent +24 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTableModelChangeEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTableModelChangeEvent (0x0x7f97bd946c30) 0 + vptr=((& QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent) + 16u) + QAccessibleEvent (0x0x7f97bd97fc00) 0 + primary-for QAccessibleTableModelChangeEvent (0x0x7f97bd946c30) + +Vtable for QAccessibleBridge +QAccessibleBridge::_ZTV17QAccessibleBridge: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleBridge) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleBridge + size=8 align=8 + base size=8 base align=8 +QAccessibleBridge (0x0x7f97bd97fcc0) 0 nearly-empty + vptr=((& QAccessibleBridge::_ZTV17QAccessibleBridge) + 16u) + +Class QAccessibleBridgePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAccessibleBridgePlugin::QPrivateSignal (0x0x7f97bd97fd80) 0 empty + +Vtable for QAccessibleBridgePlugin +QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QAccessibleBridgePlugin) +16 (int (*)(...))QAccessibleBridgePlugin::metaObject +24 (int (*)(...))QAccessibleBridgePlugin::qt_metacast +32 (int (*)(...))QAccessibleBridgePlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleBridgePlugin + size=16 align=8 + base size=16 base align=8 +QAccessibleBridgePlugin (0x0x7f97bd946c98) 0 + vptr=((& QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin) + 16u) + QObject (0x0x7f97bd97fd20) 0 + primary-for QAccessibleBridgePlugin (0x0x7f97bd946c98) + +Vtable for QAccessibleObject +QAccessibleObject::_ZTV17QAccessibleObject: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleObject) +16 0u +24 0u +32 (int (*)(...))QAccessibleObject::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleInterface::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleInterface::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleObject::rect +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleObject + size=16 align=8 + base size=16 base align=8 +QAccessibleObject (0x0x7f97bd946d00) 0 + vptr=((& QAccessibleObject::_ZTV17QAccessibleObject) + 16u) + QAccessibleInterface (0x0x7f97bd97fde0) 0 nearly-empty + primary-for QAccessibleObject (0x0x7f97bd946d00) + +Vtable for QAccessibleApplication +QAccessibleApplication::_ZTV22QAccessibleApplication: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QAccessibleApplication) +16 (int (*)(...))QAccessibleApplication::~QAccessibleApplication +24 (int (*)(...))QAccessibleApplication::~QAccessibleApplication +32 (int (*)(...))QAccessibleObject::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleApplication::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleApplication::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))QAccessibleApplication::parent +88 (int (*)(...))QAccessibleApplication::child +96 (int (*)(...))QAccessibleApplication::childCount +104 (int (*)(...))QAccessibleApplication::indexOfChild +112 (int (*)(...))QAccessibleApplication::text +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleObject::rect +136 (int (*)(...))QAccessibleApplication::role +144 (int (*)(...))QAccessibleApplication::state +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleApplication + size=16 align=8 + base size=16 base align=8 +QAccessibleApplication (0x0x7f97bd946d68) 0 + vptr=((& QAccessibleApplication::_ZTV22QAccessibleApplication) + 16u) + QAccessibleObject (0x0x7f97bd946dd0) 0 + primary-for QAccessibleApplication (0x0x7f97bd946d68) + QAccessibleInterface (0x0x7f97bd97fe40) 0 nearly-empty + primary-for QAccessibleObject (0x0x7f97bd946dd0) + +Class QAccessiblePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAccessiblePlugin::QPrivateSignal (0x0x7f97bd97ff00) 0 empty + +Vtable for QAccessiblePlugin +QAccessiblePlugin::_ZTV17QAccessiblePlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessiblePlugin) +16 (int (*)(...))QAccessiblePlugin::metaObject +24 (int (*)(...))QAccessiblePlugin::qt_metacast +32 (int (*)(...))QAccessiblePlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QAccessiblePlugin + size=16 align=8 + base size=16 base align=8 +QAccessiblePlugin (0x0x7f97bd946e38) 0 + vptr=((& QAccessiblePlugin::_ZTV17QAccessiblePlugin) + 16u) + QObject (0x0x7f97bd97fea0) 0 + primary-for QAccessiblePlugin (0x0x7f97bd946e38) + +Class QSurfaceFormat + size=8 align=8 + base size=8 base align=8 +QSurfaceFormat (0x0x7f97bd97ff60) 0 + +Vtable for QSurface +QSurface::_ZTV8QSurface: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QSurface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual + +Class QSurface + size=24 align=8 + base size=24 base align=8 +QSurface (0x0x7f97bd707180) 0 + vptr=((& QSurface::_ZTV8QSurface) + 16u) + +Class QIcon + size=8 align=8 + base size=8 base align=8 +QIcon (0x0x7f97bd707300) 0 + +Class QCursor + size=8 align=8 + base size=8 base align=8 +QCursor (0x0x7f97bd7cf6c0) 0 + +Class QWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWindow::QPrivateSignal (0x0x7f97bd85bcc0) 0 empty + +Vtable for QWindow +QWindow::_ZTV7QWindow: 45u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QWindow) +16 (int (*)(...))QWindow::metaObject +24 (int (*)(...))QWindow::qt_metacast +32 (int (*)(...))QWindow::qt_metacall +40 (int (*)(...))QWindow::~QWindow +48 (int (*)(...))QWindow::~QWindow +56 (int (*)(...))QWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))-16 +304 (int (*)(...))(& _ZTI7QWindow) +312 (int (*)(...))QWindow::_ZThn16_N7QWindowD1Ev +320 (int (*)(...))QWindow::_ZThn16_N7QWindowD0Ev +328 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +336 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QWindow + size=40 align=8 + base size=40 base align=8 +QWindow (0x0x7f97bd86d620) 0 + vptr=((& QWindow::_ZTV7QWindow) + 16u) + QObject (0x0x7f97bd85bc00) 0 + primary-for QWindow (0x0x7f97bd86d620) + QSurface (0x0x7f97bd85bc60) 16 + vptr=((& QWindow::_ZTV7QWindow) + 312u) + +Class QBackingStore + size=8 align=8 + base size=8 base align=8 +QBackingStore (0x0x7f97bd85bde0) 0 + +Vtable for QBitmap +QBitmap::_ZTV7QBitmap: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBitmap) +16 (int (*)(...))QBitmap::~QBitmap +24 (int (*)(...))QBitmap::~QBitmap +32 (int (*)(...))QPixmap::devType +40 (int (*)(...))QPixmap::paintEngine +48 (int (*)(...))QPixmap::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QBitmap + size=32 align=8 + base size=32 base align=8 +QBitmap (0x0x7f97bd85dea0) 0 + vptr=((& QBitmap::_ZTV7QBitmap) + 16u) + QPixmap (0x0x7f97bd85df08) 0 + primary-for QBitmap (0x0x7f97bd85dea0) + QPaintDevice (0x0x7f97bd85bea0) 0 + primary-for QPixmap (0x0x7f97bd85df08) + +Class QClipboard::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QClipboard::QPrivateSignal (0x0x7f97bd4ee240) 0 empty + +Vtable for QClipboard +QClipboard::_ZTV10QClipboard: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QClipboard) +16 (int (*)(...))QClipboard::metaObject +24 (int (*)(...))QClipboard::qt_metacast +32 (int (*)(...))QClipboard::qt_metacall +40 (int (*)(...))QClipboard::~QClipboard +48 (int (*)(...))QClipboard::~QClipboard +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QClipboard + size=16 align=8 + base size=16 base align=8 +QClipboard (0x0x7f97bd4ef1a0) 0 + vptr=((& QClipboard::_ZTV10QClipboard) + 16u) + QObject (0x0x7f97bd4ee1e0) 0 + primary-for QClipboard (0x0x7f97bd4ef1a0) + +Class QDesktopServices + size=1 align=1 + base size=0 base align=1 +QDesktopServices (0x0x7f97bd4ee2a0) 0 empty + +Class QDrag::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDrag::QPrivateSignal (0x0x7f97bd4ee360) 0 empty + +Vtable for QDrag +QDrag::_ZTV5QDrag: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QDrag) +16 (int (*)(...))QDrag::metaObject +24 (int (*)(...))QDrag::qt_metacast +32 (int (*)(...))QDrag::qt_metacall +40 (int (*)(...))QDrag::~QDrag +48 (int (*)(...))QDrag::~QDrag +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDrag + size=16 align=8 + base size=16 base align=8 +QDrag (0x0x7f97bd4ef208) 0 + vptr=((& QDrag::_ZTV5QDrag) + 16u) + QObject (0x0x7f97bd4ee300) 0 + primary-for QDrag (0x0x7f97bd4ef208) + +Class QFontInfo + size=8 align=8 + base size=8 base align=8 +QFontInfo (0x0x7f97bd4ee3c0) 0 + +Class QFontMetrics + size=8 align=8 + base size=8 base align=8 +QFontMetrics (0x0x7f97bd4ee660) 0 + +Class QFontMetricsF + size=8 align=8 + base size=8 base align=8 +QFontMetricsF (0x0x7f97bd4ee960) 0 + +Class QGenericPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGenericPlugin::QPrivateSignal (0x0x7f97bd5c1e40) 0 empty + +Vtable for QGenericPlugin +QGenericPlugin::_ZTV14QGenericPlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QGenericPlugin) +16 (int (*)(...))QGenericPlugin::metaObject +24 (int (*)(...))QGenericPlugin::qt_metacast +32 (int (*)(...))QGenericPlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QGenericPlugin + size=16 align=8 + base size=16 base align=8 +QGenericPlugin (0x0x7f97bd4efa90) 0 + vptr=((& QGenericPlugin::_ZTV14QGenericPlugin) + 16u) + QObject (0x0x7f97bd5c1de0) 0 + primary-for QGenericPlugin (0x0x7f97bd4efa90) + +Class QGenericPluginFactory + size=1 align=1 + base size=0 base align=1 +QGenericPluginFactory (0x0x7f97bd5c1ea0) 0 empty + +Class QInputMethod::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QInputMethod::QPrivateSignal (0x0x7f97bd5c1f60) 0 empty + +Vtable for QInputMethod +QInputMethod::_ZTV12QInputMethod: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QInputMethod) +16 (int (*)(...))QInputMethod::metaObject +24 (int (*)(...))QInputMethod::qt_metacast +32 (int (*)(...))QInputMethod::qt_metacall +40 (int (*)(...))QInputMethod::~QInputMethod +48 (int (*)(...))QInputMethod::~QInputMethod +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QInputMethod + size=16 align=8 + base size=16 base align=8 +QInputMethod (0x0x7f97bd4efaf8) 0 + vptr=((& QInputMethod::_ZTV12QInputMethod) + 16u) + QObject (0x0x7f97bd5c1f00) 0 + primary-for QInputMethod (0x0x7f97bd4efaf8) + +Class QGuiApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGuiApplication::QPrivateSignal (0x0x7f97bd6d3060) 0 empty + +Vtable for QGuiApplication +QGuiApplication::_ZTV15QGuiApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGuiApplication) +16 (int (*)(...))QGuiApplication::metaObject +24 (int (*)(...))QGuiApplication::qt_metacast +32 (int (*)(...))QGuiApplication::qt_metacall +40 (int (*)(...))QGuiApplication::~QGuiApplication +48 (int (*)(...))QGuiApplication::~QGuiApplication +56 (int (*)(...))QGuiApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGuiApplication::notify +120 (int (*)(...))QGuiApplication::compressEvent + +Class QGuiApplication + size=16 align=8 + base size=16 base align=8 +QGuiApplication (0x0x7f97bd4efb60) 0 + vptr=((& QGuiApplication::_ZTV15QGuiApplication) + 16u) + QCoreApplication (0x0x7f97bd4efbc8) 0 + primary-for QGuiApplication (0x0x7f97bd4efb60) + QObject (0x0x7f97bd6d3000) 0 + primary-for QCoreApplication (0x0x7f97bd4efbc8) + +Class QIconEngine::AvailableSizesArgument + size=16 align=8 + base size=16 base align=8 +QIconEngine::AvailableSizesArgument (0x0x7f97bd6d35a0) 0 + +Class QIconEngine::ScaledPixmapArgument + size=56 align=8 + base size=56 base align=8 +QIconEngine::ScaledPixmapArgument (0x0x7f97bd6d3720) 0 + +Vtable for QIconEngine +QIconEngine::_ZTV11QIconEngine: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QIconEngine) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QIconEngine::actualSize +48 (int (*)(...))QIconEngine::pixmap +56 (int (*)(...))QIconEngine::addPixmap +64 (int (*)(...))QIconEngine::addFile +72 (int (*)(...))QIconEngine::key +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QIconEngine::read +96 (int (*)(...))QIconEngine::write +104 (int (*)(...))QIconEngine::availableSizes +112 (int (*)(...))QIconEngine::iconName +120 (int (*)(...))QIconEngine::virtual_hook + +Class QIconEngine + size=8 align=8 + base size=8 base align=8 +QIconEngine (0x0x7f97bd6d3540) 0 nearly-empty + vptr=((& QIconEngine::_ZTV11QIconEngine) + 16u) + +Class QIconEnginePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIconEnginePlugin::QPrivateSignal (0x0x7f97bd6d37e0) 0 empty + +Vtable for QIconEnginePlugin +QIconEnginePlugin::_ZTV17QIconEnginePlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QIconEnginePlugin) +16 (int (*)(...))QIconEnginePlugin::metaObject +24 (int (*)(...))QIconEnginePlugin::qt_metacast +32 (int (*)(...))QIconEnginePlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QIconEnginePlugin + size=16 align=8 + base size=16 base align=8 +QIconEnginePlugin (0x0x7f97bd2f4138) 0 + vptr=((& QIconEnginePlugin::_ZTV17QIconEnginePlugin) + 16u) + QObject (0x0x7f97bd6d3780) 0 + primary-for QIconEnginePlugin (0x0x7f97bd2f4138) + +Vtable for QImageIOHandler +QImageIOHandler::_ZTV15QImageIOHandler: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QImageIOHandler) +16 0u +24 0u +32 (int (*)(...))QImageIOHandler::name +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))QImageIOHandler::write +64 (int (*)(...))QImageIOHandler::option +72 (int (*)(...))QImageIOHandler::setOption +80 (int (*)(...))QImageIOHandler::supportsOption +88 (int (*)(...))QImageIOHandler::jumpToNextImage +96 (int (*)(...))QImageIOHandler::jumpToImage +104 (int (*)(...))QImageIOHandler::loopCount +112 (int (*)(...))QImageIOHandler::imageCount +120 (int (*)(...))QImageIOHandler::nextImageDelay +128 (int (*)(...))QImageIOHandler::currentImageNumber +136 (int (*)(...))QImageIOHandler::currentImageRect + +Class QImageIOHandler + size=16 align=8 + base size=16 base align=8 +QImageIOHandler (0x0x7f97bd6d3840) 0 + vptr=((& QImageIOHandler::_ZTV15QImageIOHandler) + 16u) + +Class QImageIOPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QImageIOPlugin::QPrivateSignal (0x0x7f97bd6d39c0) 0 empty + +Vtable for QImageIOPlugin +QImageIOPlugin::_ZTV14QImageIOPlugin: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QImageIOPlugin) +16 (int (*)(...))QImageIOPlugin::metaObject +24 (int (*)(...))QImageIOPlugin::qt_metacast +32 (int (*)(...))QImageIOPlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QImageIOPlugin + size=16 align=8 + base size=16 base align=8 +QImageIOPlugin (0x0x7f97bd2f41a0) 0 + vptr=((& QImageIOPlugin::_ZTV14QImageIOPlugin) + 16u) + QObject (0x0x7f97bd6d3960) 0 + primary-for QImageIOPlugin (0x0x7f97bd2f41a0) + +Class QImageReader + size=8 align=8 + base size=8 base align=8 +QImageReader (0x0x7f97bd6d3ba0) 0 + +Class QImageWriter + size=8 align=8 + base size=8 base align=8 +QImageWriter (0x0x7f97bd6d3c00) 0 + +Class QVector3D + size=12 align=4 + base size=12 base align=4 +QVector3D (0x0x7f97bd6d3c60) 0 + +Class QVector4D + size=16 align=4 + base size=16 base align=4 +QVector4D (0x0x7f97bd6d3f00) 0 + +Class QQuaternion + size=16 align=4 + base size=16 base align=4 +QQuaternion (0x0x7f97bd4231e0) 0 + +Class QMatrix4x4 + size=68 align=4 + base size=68 base align=4 +QMatrix4x4 (0x0x7f97bd4237e0) 0 + +Class QMovie::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMovie::QPrivateSignal (0x0x7f97bd423f60) 0 empty + +Vtable for QMovie +QMovie::_ZTV6QMovie: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QMovie) +16 (int (*)(...))QMovie::metaObject +24 (int (*)(...))QMovie::qt_metacast +32 (int (*)(...))QMovie::qt_metacall +40 (int (*)(...))QMovie::~QMovie +48 (int (*)(...))QMovie::~QMovie +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QMovie + size=16 align=8 + base size=16 base align=8 +QMovie (0x0x7f97bd1283a8) 0 + vptr=((& QMovie::_ZTV6QMovie) + 16u) + QObject (0x0x7f97bd423f00) 0 + primary-for QMovie (0x0x7f97bd1283a8) + +Class QOffscreenSurface::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOffscreenSurface::QPrivateSignal (0x0x7f97bd22a0c0) 0 empty + +Vtable for QOffscreenSurface +QOffscreenSurface::_ZTV17QOffscreenSurface: 26u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QOffscreenSurface) +16 (int (*)(...))QOffscreenSurface::metaObject +24 (int (*)(...))QOffscreenSurface::qt_metacast +32 (int (*)(...))QOffscreenSurface::qt_metacall +40 (int (*)(...))QOffscreenSurface::~QOffscreenSurface +48 (int (*)(...))QOffscreenSurface::~QOffscreenSurface +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QOffscreenSurface::surfaceType +120 (int (*)(...))QOffscreenSurface::format +128 (int (*)(...))QOffscreenSurface::size +136 (int (*)(...))QOffscreenSurface::surfaceHandle +144 (int (*)(...))-16 +152 (int (*)(...))(& _ZTI17QOffscreenSurface) +160 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD1Ev +168 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD0Ev +176 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface6formatEv +184 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface13surfaceHandleEv +192 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface11surfaceTypeEv +200 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface4sizeEv + +Class QOffscreenSurface + size=40 align=8 + base size=40 base align=8 +QOffscreenSurface (0x0x7f97bd1d2e00) 0 + vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 16u) + QObject (0x0x7f97bd22a000) 0 + primary-for QOffscreenSurface (0x0x7f97bd1d2e00) + QSurface (0x0x7f97bd22a060) 16 + vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 160u) + +Class QOpenGLBuffer + size=8 align=8 + base size=8 base align=8 +QOpenGLBuffer (0x0x7f97bd22a180) 0 + +Class QOpenGLVersionStatus + size=12 align=4 + base size=12 base align=4 +QOpenGLVersionStatus (0x0x7f97bd22a360) 0 + +Class QOpenGLVersionFunctionsBackend + size=16 align=8 + base size=12 base align=8 +QOpenGLVersionFunctionsBackend (0x0x7f97bcb8fe40) 0 + +Class QOpenGLVersionFunctionsStorage + size=8 align=8 + base size=8 base align=8 +QOpenGLVersionFunctionsStorage (0x0x7f97bcb8fea0) 0 + +Class QAbstractOpenGLFunctionsPrivate + size=16 align=8 + base size=9 base align=8 +QAbstractOpenGLFunctionsPrivate (0x0x7f97bcb8ff00) 0 + +Vtable for QAbstractOpenGLFunctions +QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractOpenGLFunctions) +16 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions +24 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions +32 (int (*)(...))QAbstractOpenGLFunctions::initializeOpenGLFunctions + +Class QAbstractOpenGLFunctions + size=16 align=8 + base size=16 base align=8 +QAbstractOpenGLFunctions (0x0x7f97bcb8ff60) 0 + vptr=((& QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions) + 16u) + +Class QOpenGLFunctions_1_0_CoreBackend::Functions + size=384 align=8 + base size=384 base align=8 +QOpenGLFunctions_1_0_CoreBackend::Functions (0x0x7f97bcbdb060) 0 + +Class QOpenGLFunctions_1_0_CoreBackend + size=400 align=8 + base size=400 base align=8 +QOpenGLFunctions_1_0_CoreBackend (0x0x7f97bcbb3618) 0 + QOpenGLVersionFunctionsBackend (0x0x7f97bcbdb000) 0 + +Class QOpenGLFunctions_1_1_CoreBackend::Functions + size=128 align=8 + base size=128 base align=8 +QOpenGLFunctions_1_1_CoreBackend::Functions (0x0x7f97bcbdb180) 0 + +Class QOpenGLFunctions_1_1_CoreBackend + size=144 align=8 + base size=144 base align=8 +QOpenGLFunctions_1_1_CoreBackend (0x0x7f97bcbb3680) 0 + QOpenGLVersionFunctionsBackend (0x0x7f97bcbdb120) 0 + +Class QOpenGLFunctions_1_2_CoreBackend::Functions + size=48 align=8 + base size=48 base align=8 +QOpenGLFunctions_1_2_CoreBackend::Functions (0x0x7f97bcbdb2a0) 0 + +Class QOpenGLFunctions_1_2_CoreBackend + size=64 align=8 + base size=64 base align=8 +QOpenGLFunctions_1_2_CoreBackend (0x0x7f97bcbb36e8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f97bcbdb240) 0 + +Class QOpenGLFunctions_1_3_CoreBackend::Functions + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_1_3_CoreBackend::Functions (0x0x7f97bcbdb3c0) 0 + +Class QOpenGLFunctions_1_3_CoreBackend + size=88 align=8 + base size=88 base align=8 +QOpenGLFunctions_1_3_CoreBackend (0x0x7f97bcbb3750) 0 + QOpenGLVersionFunctionsBackend (0x0x7f97bcbdb360) 0 + +Class QOpenGLFunctions_1_4_CoreBackend::Functions + size=56 align=8 + base size=56 base align=8 +QOpenGLFunctions_1_4_CoreBackend::Functions (0x0x7f97bcbdb540) 0 + +Class QOpenGLFunctions_1_4_CoreBackend + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_1_4_CoreBackend (0x0x7f97bcbb37b8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f97bcbdb4e0) 0 + +Class QOpenGLFunctions_1_5_CoreBackend::Functions + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_1_5_CoreBackend::Functions (0x0x7f97bcbdb660) 0 + +Class QOpenGLFunctions_1_5_CoreBackend + size=168 align=8 + base size=168 base align=8 +QOpenGLFunctions_1_5_CoreBackend (0x0x7f97bcbb3820) 0 + QOpenGLVersionFunctionsBackend (0x0x7f97bcbdb600) 0 + +Class QOpenGLFunctions_2_0_CoreBackend::Functions + size=744 align=8 + base size=744 base align=8 +QOpenGLFunctions_2_0_CoreBackend::Functions (0x0x7f97bcbdb780) 0 + +Class QOpenGLFunctions_2_0_CoreBackend + size=760 align=8 + base size=760 base align=8 +QOpenGLFunctions_2_0_CoreBackend (0x0x7f97bcbb3888) 0 + QOpenGLVersionFunctionsBackend (0x0x7f97bcbdb720) 0 + +Class QOpenGLFunctions_2_1_CoreBackend::Functions + size=48 align=8 + base size=48 base align=8 +QOpenGLFunctions_2_1_CoreBackend::Functions (0x0x7f97bcbdb8a0) 0 + +Class QOpenGLFunctions_2_1_CoreBackend + size=64 align=8 + base size=64 base align=8 +QOpenGLFunctions_2_1_CoreBackend (0x0x7f97bcbb38f0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f97bcbdb840) 0 + +Class QOpenGLFunctions_3_0_CoreBackend::Functions + size=672 align=8 + base size=672 base align=8 +QOpenGLFunctions_3_0_CoreBackend::Functions (0x0x7f97bcbdb9c0) 0 + +Class QOpenGLFunctions_3_0_CoreBackend + size=688 align=8 + base size=688 base align=8 +QOpenGLFunctions_3_0_CoreBackend (0x0x7f97bcbb3958) 0 + QOpenGLVersionFunctionsBackend (0x0x7f97bcbdb960) 0 + +Class QOpenGLFunctions_3_1_CoreBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_3_1_CoreBackend::Functions (0x0x7f97bcbdbae0) 0 + +Class QOpenGLFunctions_3_1_CoreBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_3_1_CoreBackend (0x0x7f97bcbb39c0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f97bcbdba80) 0 + +Class QOpenGLFunctions_3_2_CoreBackend::Functions + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_3_2_CoreBackend::Functions (0x0x7f97bcbdbc00) 0 + +Class QOpenGLFunctions_3_2_CoreBackend + size=168 align=8 + base size=168 base align=8 +QOpenGLFunctions_3_2_CoreBackend (0x0x7f97bcbb3a28) 0 + QOpenGLVersionFunctionsBackend (0x0x7f97bcbdbba0) 0 + +Class QOpenGLFunctions_3_3_CoreBackend::Functions + size=464 align=8 + base size=464 base align=8 +QOpenGLFunctions_3_3_CoreBackend::Functions (0x0x7f97bcbdbd20) 0 + +Class QOpenGLFunctions_3_3_CoreBackend + size=480 align=8 + base size=480 base align=8 +QOpenGLFunctions_3_3_CoreBackend (0x0x7f97bcbb3a90) 0 + QOpenGLVersionFunctionsBackend (0x0x7f97bcbdbcc0) 0 + +Class QOpenGLFunctions_4_0_CoreBackend::Functions + size=368 align=8 + base size=368 base align=8 +QOpenGLFunctions_4_0_CoreBackend::Functions (0x0x7f97bcbdbe40) 0 + +Class QOpenGLFunctions_4_0_CoreBackend + size=384 align=8 + base size=384 base align=8 +QOpenGLFunctions_4_0_CoreBackend (0x0x7f97bcbb3af8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f97bcbdbde0) 0 + +Class QOpenGLFunctions_4_1_CoreBackend::Functions + size=704 align=8 + base size=704 base align=8 +QOpenGLFunctions_4_1_CoreBackend::Functions (0x0x7f97bcbdbf60) 0 + +Class QOpenGLFunctions_4_1_CoreBackend + size=720 align=8 + base size=720 base align=8 +QOpenGLFunctions_4_1_CoreBackend (0x0x7f97bcbb3b60) 0 + QOpenGLVersionFunctionsBackend (0x0x7f97bcbdbf00) 0 + +Class QOpenGLFunctions_4_2_CoreBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_4_2_CoreBackend::Functions (0x0x7f97bccd20c0) 0 + +Class QOpenGLFunctions_4_2_CoreBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_4_2_CoreBackend (0x0x7f97bcbb3bc8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f97bccd2060) 0 + +Class QOpenGLFunctions_4_3_CoreBackend::Functions + size=344 align=8 + base size=344 base align=8 +QOpenGLFunctions_4_3_CoreBackend::Functions (0x0x7f97bccd21e0) 0 + +Class QOpenGLFunctions_4_3_CoreBackend + size=360 align=8 + base size=360 base align=8 +QOpenGLFunctions_4_3_CoreBackend (0x0x7f97bcbb3c30) 0 + QOpenGLVersionFunctionsBackend (0x0x7f97bccd2180) 0 + +Class QOpenGLFunctions_4_4_CoreBackend::Functions + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_4_4_CoreBackend::Functions (0x0x7f97bccd2300) 0 + +Class QOpenGLFunctions_4_4_CoreBackend + size=88 align=8 + base size=88 base align=8 +QOpenGLFunctions_4_4_CoreBackend (0x0x7f97bcbb3c98) 0 + QOpenGLVersionFunctionsBackend (0x0x7f97bccd22a0) 0 + +Class QOpenGLFunctions_4_5_CoreBackend::Functions + size=848 align=8 + base size=848 base align=8 +QOpenGLFunctions_4_5_CoreBackend::Functions (0x0x7f97bccd2480) 0 + +Class QOpenGLFunctions_4_5_CoreBackend + size=864 align=8 + base size=864 base align=8 +QOpenGLFunctions_4_5_CoreBackend (0x0x7f97bcbb3d00) 0 + QOpenGLVersionFunctionsBackend (0x0x7f97bccd2420) 0 + +Class QOpenGLFunctions_1_0_DeprecatedBackend::Functions + size=2064 align=8 + base size=2064 base align=8 +QOpenGLFunctions_1_0_DeprecatedBackend::Functions (0x0x7f97bccd25a0) 0 + +Class QOpenGLFunctions_1_0_DeprecatedBackend + size=2080 align=8 + base size=2080 base align=8 +QOpenGLFunctions_1_0_DeprecatedBackend (0x0x7f97bcbb3d68) 0 + QOpenGLVersionFunctionsBackend (0x0x7f97bccd2540) 0 + +Class QOpenGLFunctions_1_1_DeprecatedBackend::Functions + size=136 align=8 + base size=136 base align=8 +QOpenGLFunctions_1_1_DeprecatedBackend::Functions (0x0x7f97bccd26c0) 0 + +Class QOpenGLFunctions_1_1_DeprecatedBackend + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_1_1_DeprecatedBackend (0x0x7f97bcbb3dd0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f97bccd2660) 0 + +Class QOpenGLFunctions_1_2_DeprecatedBackend::Functions + size=256 align=8 + base size=256 base align=8 +QOpenGLFunctions_1_2_DeprecatedBackend::Functions (0x0x7f97bccd27e0) 0 + +Class QOpenGLFunctions_1_2_DeprecatedBackend + size=272 align=8 + base size=272 base align=8 +QOpenGLFunctions_1_2_DeprecatedBackend (0x0x7f97bcbb3e38) 0 + QOpenGLVersionFunctionsBackend (0x0x7f97bccd2780) 0 + +Class QOpenGLFunctions_1_3_DeprecatedBackend::Functions + size=296 align=8 + base size=296 base align=8 +QOpenGLFunctions_1_3_DeprecatedBackend::Functions (0x0x7f97bccd2900) 0 + +Class QOpenGLFunctions_1_3_DeprecatedBackend + size=312 align=8 + base size=312 base align=8 +QOpenGLFunctions_1_3_DeprecatedBackend (0x0x7f97bcbb3ea0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f97bccd28a0) 0 + +Class QOpenGLFunctions_1_4_DeprecatedBackend::Functions + size=304 align=8 + base size=304 base align=8 +QOpenGLFunctions_1_4_DeprecatedBackend::Functions (0x0x7f97bccd2a20) 0 + +Class QOpenGLFunctions_1_4_DeprecatedBackend + size=320 align=8 + base size=320 base align=8 +QOpenGLFunctions_1_4_DeprecatedBackend (0x0x7f97bcbb3f08) 0 + QOpenGLVersionFunctionsBackend (0x0x7f97bccd29c0) 0 + +Class QOpenGLFunctions_2_0_DeprecatedBackend::Functions + size=288 align=8 + base size=288 base align=8 +QOpenGLFunctions_2_0_DeprecatedBackend::Functions (0x0x7f97bccd2b40) 0 + +Class QOpenGLFunctions_2_0_DeprecatedBackend + size=304 align=8 + base size=304 base align=8 +QOpenGLFunctions_2_0_DeprecatedBackend (0x0x7f97bcbb3f70) 0 + QOpenGLVersionFunctionsBackend (0x0x7f97bccd2ae0) 0 + +Class QOpenGLFunctions_3_0_DeprecatedBackend::Functions + size=160 align=8 + base size=160 base align=8 +QOpenGLFunctions_3_0_DeprecatedBackend::Functions (0x0x7f97bccd2c60) 0 + +Class QOpenGLFunctions_3_0_DeprecatedBackend + size=176 align=8 + base size=176 base align=8 +QOpenGLFunctions_3_0_DeprecatedBackend (0x0x7f97bc9cf000) 0 + QOpenGLVersionFunctionsBackend (0x0x7f97bccd2c00) 0 + +Class QOpenGLFunctions_3_3_DeprecatedBackend::Functions + size=240 align=8 + base size=240 base align=8 +QOpenGLFunctions_3_3_DeprecatedBackend::Functions (0x0x7f97bccd2d80) 0 + +Class QOpenGLFunctions_3_3_DeprecatedBackend + size=256 align=8 + base size=256 base align=8 +QOpenGLFunctions_3_3_DeprecatedBackend (0x0x7f97bc9cf068) 0 + QOpenGLVersionFunctionsBackend (0x0x7f97bccd2d20) 0 + +Class QOpenGLFunctions_4_5_DeprecatedBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_4_5_DeprecatedBackend::Functions (0x0x7f97bccd2ea0) 0 + +Class QOpenGLFunctions_4_5_DeprecatedBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_4_5_DeprecatedBackend (0x0x7f97bc9cf0d0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f97bccd2e40) 0 + +Class QOpenGLVersionProfile + size=8 align=8 + base size=8 base align=8 +QOpenGLVersionProfile (0x0x7f97bccd2f60) 0 + +Class QOpenGLContextGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLContextGroup::QPrivateSignal (0x0x7f97bca00960) 0 empty + +Vtable for QOpenGLContextGroup +QOpenGLContextGroup::_ZTV19QOpenGLContextGroup: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QOpenGLContextGroup) +16 (int (*)(...))QOpenGLContextGroup::metaObject +24 (int (*)(...))QOpenGLContextGroup::qt_metacast +32 (int (*)(...))QOpenGLContextGroup::qt_metacall +40 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup +48 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLContextGroup + size=16 align=8 + base size=16 base align=8 +QOpenGLContextGroup (0x0x7f97bc9cfaf8) 0 + vptr=((& QOpenGLContextGroup::_ZTV19QOpenGLContextGroup) + 16u) + QObject (0x0x7f97bca00900) 0 + primary-for QOpenGLContextGroup (0x0x7f97bc9cfaf8) + +Class QOpenGLContext::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLContext::QPrivateSignal (0x0x7f97bca00a20) 0 empty + +Vtable for QOpenGLContext +QOpenGLContext::_ZTV14QOpenGLContext: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QOpenGLContext) +16 (int (*)(...))QOpenGLContext::metaObject +24 (int (*)(...))QOpenGLContext::qt_metacast +32 (int (*)(...))QOpenGLContext::qt_metacall +40 (int (*)(...))QOpenGLContext::~QOpenGLContext +48 (int (*)(...))QOpenGLContext::~QOpenGLContext +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLContext + size=16 align=8 + base size=16 base align=8 +QOpenGLContext (0x0x7f97bc9cfb60) 0 + vptr=((& QOpenGLContext::_ZTV14QOpenGLContext) + 16u) + QObject (0x0x7f97bca009c0) 0 + primary-for QOpenGLContext (0x0x7f97bc9cfb60) + +Class QOpenGLDebugMessage + size=8 align=8 + base size=8 base align=8 +QOpenGLDebugMessage (0x0x7f97bca00a80) 0 + +Class QOpenGLDebugLogger::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLDebugLogger::QPrivateSignal (0x0x7f97bca902a0) 0 empty + +Vtable for QOpenGLDebugLogger +QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLDebugLogger) +16 (int (*)(...))QOpenGLDebugLogger::metaObject +24 (int (*)(...))QOpenGLDebugLogger::qt_metacast +32 (int (*)(...))QOpenGLDebugLogger::qt_metacall +40 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger +48 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLDebugLogger + size=16 align=8 + base size=16 base align=8 +QOpenGLDebugLogger (0x0x7f97bc6e3000) 0 + vptr=((& QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger) + 16u) + QObject (0x0x7f97bca90240) 0 + primary-for QOpenGLDebugLogger (0x0x7f97bc6e3000) + +Class QOpenGLFunctions + size=8 align=8 + base size=8 base align=8 +QOpenGLFunctions (0x0x7f97bca90420) 0 + +Class QOpenGLFunctionsPrivate::Functions + size=1152 align=8 + base size=1152 base align=8 +QOpenGLFunctionsPrivate::Functions (0x0x7f97bca90660) 0 + +Class QOpenGLFunctionsPrivate + size=1152 align=8 + base size=1152 base align=8 +QOpenGLFunctionsPrivate (0x0x7f97bca90600) 0 + +Class QOpenGLExtraFunctions + size=8 align=8 + base size=8 base align=8 +QOpenGLExtraFunctions (0x0x7f97bc6e3270) 0 + QOpenGLFunctions (0x0x7f97bc864d80) 0 + +Class QOpenGLExtraFunctionsPrivate::Functions + size=1728 align=8 + base size=1728 base align=8 +QOpenGLExtraFunctionsPrivate::Functions (0x0x7f97bc864e40) 0 + +Class QOpenGLExtraFunctionsPrivate + size=2880 align=8 + base size=2880 base align=8 +QOpenGLExtraFunctionsPrivate (0x0x7f97bc6e32d8) 0 + QOpenGLFunctionsPrivate (0x0x7f97bc864de0) 0 + +Vtable for QOpenGLFramebufferObject +QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QOpenGLFramebufferObject) +16 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject +24 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject + +Class QOpenGLFramebufferObject + size=16 align=8 + base size=16 base align=8 +QOpenGLFramebufferObject (0x0x7f97bc6cb540) 0 + vptr=((& QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject) + 16u) + +Class QOpenGLFramebufferObjectFormat + size=8 align=8 + base size=8 base align=8 +QOpenGLFramebufferObjectFormat (0x0x7f97bc6cb660) 0 + +Vtable for QOpenGLPaintDevice +QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLPaintDevice) +16 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice +24 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice +32 (int (*)(...))QOpenGLPaintDevice::devType +40 (int (*)(...))QOpenGLPaintDevice::paintEngine +48 (int (*)(...))QOpenGLPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))QOpenGLPaintDevice::ensureActiveTarget + +Class QOpenGLPaintDevice + size=32 align=8 + base size=32 base align=8 +QOpenGLPaintDevice (0x0x7f97bc6e35b0) 0 + vptr=((& QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice) + 16u) + QPaintDevice (0x0x7f97bc6cb6c0) 0 + primary-for QOpenGLPaintDevice (0x0x7f97bc6e35b0) + +Class QOpenGLPixelTransferOptions + size=8 align=8 + base size=8 base align=8 +QOpenGLPixelTransferOptions (0x0x7f97bc6cb7e0) 0 + +Class QOpenGLShader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLShader::QPrivateSignal (0x0x7f97bc6cbb40) 0 empty + +Vtable for QOpenGLShader +QOpenGLShader::_ZTV13QOpenGLShader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QOpenGLShader) +16 (int (*)(...))QOpenGLShader::metaObject +24 (int (*)(...))QOpenGLShader::qt_metacast +32 (int (*)(...))QOpenGLShader::qt_metacall +40 (int (*)(...))QOpenGLShader::~QOpenGLShader +48 (int (*)(...))QOpenGLShader::~QOpenGLShader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLShader + size=16 align=8 + base size=16 base align=8 +QOpenGLShader (0x0x7f97bc6e37b8) 0 + vptr=((& QOpenGLShader::_ZTV13QOpenGLShader) + 16u) + QObject (0x0x7f97bc6cbae0) 0 + primary-for QOpenGLShader (0x0x7f97bc6e37b8) + +Class QOpenGLShaderProgram::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLShaderProgram::QPrivateSignal (0x0x7f97bc6cbd80) 0 empty + +Vtable for QOpenGLShaderProgram +QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QOpenGLShaderProgram) +16 (int (*)(...))QOpenGLShaderProgram::metaObject +24 (int (*)(...))QOpenGLShaderProgram::qt_metacast +32 (int (*)(...))QOpenGLShaderProgram::qt_metacall +40 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram +48 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QOpenGLShaderProgram::link + +Class QOpenGLShaderProgram + size=16 align=8 + base size=16 base align=8 +QOpenGLShaderProgram (0x0x7f97bc6e38f0) 0 + vptr=((& QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram) + 16u) + QObject (0x0x7f97bc6cbd20) 0 + primary-for QOpenGLShaderProgram (0x0x7f97bc6e38f0) + +Class QOpenGLTexture + size=8 align=8 + base size=8 base align=8 +QOpenGLTexture (0x0x7f97bc6cbde0) 0 + +Class QOpenGLTextureBlitter + size=8 align=8 + base size=8 base align=8 +QOpenGLTextureBlitter (0x0x7f97bc4430c0) 0 + +Class QOpenGLTimerQuery::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLTimerQuery::QPrivateSignal (0x0x7f97bc443240) 0 empty + +Vtable for QOpenGLTimerQuery +QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QOpenGLTimerQuery) +16 (int (*)(...))QOpenGLTimerQuery::metaObject +24 (int (*)(...))QOpenGLTimerQuery::qt_metacast +32 (int (*)(...))QOpenGLTimerQuery::qt_metacall +40 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery +48 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLTimerQuery + size=16 align=8 + base size=16 base align=8 +QOpenGLTimerQuery (0x0x7f97bc6e3a28) 0 + vptr=((& QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery) + 16u) + QObject (0x0x7f97bc4431e0) 0 + primary-for QOpenGLTimerQuery (0x0x7f97bc6e3a28) + +Class QOpenGLTimeMonitor::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLTimeMonitor::QPrivateSignal (0x0x7f97bc443300) 0 empty + +Vtable for QOpenGLTimeMonitor +QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLTimeMonitor) +16 (int (*)(...))QOpenGLTimeMonitor::metaObject +24 (int (*)(...))QOpenGLTimeMonitor::qt_metacast +32 (int (*)(...))QOpenGLTimeMonitor::qt_metacall +40 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor +48 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLTimeMonitor + size=16 align=8 + base size=16 base align=8 +QOpenGLTimeMonitor (0x0x7f97bc6e3a90) 0 + vptr=((& QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor) + 16u) + QObject (0x0x7f97bc4432a0) 0 + primary-for QOpenGLTimeMonitor (0x0x7f97bc6e3a90) + +Class QOpenGLVertexArrayObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLVertexArrayObject::QPrivateSignal (0x0x7f97bc4433c0) 0 empty + +Class QOpenGLVertexArrayObject::Binder + size=8 align=8 + base size=8 base align=8 +QOpenGLVertexArrayObject::Binder (0x0x7f97bc443420) 0 + +Vtable for QOpenGLVertexArrayObject +QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QOpenGLVertexArrayObject) +16 (int (*)(...))QOpenGLVertexArrayObject::metaObject +24 (int (*)(...))QOpenGLVertexArrayObject::qt_metacast +32 (int (*)(...))QOpenGLVertexArrayObject::qt_metacall +40 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject +48 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLVertexArrayObject + size=16 align=8 + base size=16 base align=8 +QOpenGLVertexArrayObject (0x0x7f97bc6e3af8) 0 + vptr=((& QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject) + 16u) + QObject (0x0x7f97bc443360) 0 + primary-for QOpenGLVertexArrayObject (0x0x7f97bc6e3af8) + +Class QPaintDeviceWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPaintDeviceWindow::QPrivateSignal (0x0x7f97bc4435a0) 0 empty + +Vtable for QPaintDeviceWindow +QPaintDeviceWindow::_ZTV18QPaintDeviceWindow: 58u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +16 (int (*)(...))QPaintDeviceWindow::metaObject +24 (int (*)(...))QPaintDeviceWindow::qt_metacast +32 (int (*)(...))QPaintDeviceWindow::qt_metacall +40 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow +48 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))QPaintDeviceWindow::paintEvent +304 (int (*)(...))QPaintDeviceWindow::metric +312 (int (*)(...))QPaintDeviceWindow::paintEngine +320 (int (*)(...))-16 +328 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +336 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD1Ev +344 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD0Ev +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +376 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +384 (int (*)(...))-40 +392 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +400 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD1Ev +408 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD0Ev +416 (int (*)(...))QPaintDevice::devType +424 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +432 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow6metricEN12QPaintDevice17PaintDeviceMetricE +440 (int (*)(...))QPaintDevice::initPainter +448 (int (*)(...))QPaintDevice::redirected +456 (int (*)(...))QPaintDevice::sharedPainter + +Class QPaintDeviceWindow + size=64 align=8 + base size=64 base align=8 +QPaintDeviceWindow (0x0x7f97bc498d20) 0 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 16u) + QWindow (0x0x7f97bc498d90) 0 + primary-for QPaintDeviceWindow (0x0x7f97bc498d20) + QObject (0x0x7f97bc443480) 0 + primary-for QWindow (0x0x7f97bc498d90) + QSurface (0x0x7f97bc4434e0) 16 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 336u) + QPaintDevice (0x0x7f97bc443540) 40 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 400u) + +Class QOpenGLWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLWindow::QPrivateSignal (0x0x7f97bc443720) 0 empty + +Vtable for QOpenGLWindow +QOpenGLWindow::_ZTV13QOpenGLWindow: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QOpenGLWindow) +16 (int (*)(...))QOpenGLWindow::metaObject +24 (int (*)(...))QOpenGLWindow::qt_metacast +32 (int (*)(...))QOpenGLWindow::qt_metacall +40 (int (*)(...))QOpenGLWindow::~QOpenGLWindow +48 (int (*)(...))QOpenGLWindow::~QOpenGLWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QOpenGLWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))QOpenGLWindow::paintEvent +304 (int (*)(...))QOpenGLWindow::metric +312 (int (*)(...))QPaintDeviceWindow::paintEngine +320 (int (*)(...))QOpenGLWindow::initializeGL +328 (int (*)(...))QOpenGLWindow::resizeGL +336 (int (*)(...))QOpenGLWindow::paintGL +344 (int (*)(...))QOpenGLWindow::paintUnderGL +352 (int (*)(...))QOpenGLWindow::paintOverGL +360 (int (*)(...))QOpenGLWindow::redirected +368 (int (*)(...))-16 +376 (int (*)(...))(& _ZTI13QOpenGLWindow) +384 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD1Ev +392 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD0Ev +400 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +408 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +416 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +424 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +432 (int (*)(...))-40 +440 (int (*)(...))(& _ZTI13QOpenGLWindow) +448 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD1Ev +456 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD0Ev +464 (int (*)(...))QPaintDevice::devType +472 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +480 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QPaintDevice::initPainter +496 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow10redirectedEP6QPoint +504 (int (*)(...))QPaintDevice::sharedPainter + +Class QOpenGLWindow + size=64 align=8 + base size=64 base align=8 +QOpenGLWindow (0x0x7f97bc6e3bc8) 0 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 16u) + QPaintDeviceWindow (0x0x7f97bc4c5150) 0 + primary-for QOpenGLWindow (0x0x7f97bc6e3bc8) + QWindow (0x0x7f97bc4c51c0) 0 + primary-for QPaintDeviceWindow (0x0x7f97bc4c5150) + QObject (0x0x7f97bc443600) 0 + primary-for QWindow (0x0x7f97bc4c51c0) + QSurface (0x0x7f97bc443660) 16 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 384u) + QPaintDevice (0x0x7f97bc4436c0) 40 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 448u) + +Class QPageSize + size=8 align=8 + base size=8 base align=8 +QPageSize (0x0x7f97bc443780) 0 + +Class QPageLayout + size=8 align=8 + base size=8 base align=8 +QPageLayout (0x0x7f97bc0f5180) 0 + +Class QPagedPaintDevice::Margins + size=32 align=8 + base size=32 base align=8 +QPagedPaintDevice::Margins (0x0x7f97bc0f5ba0) 0 + +Vtable for QPagedPaintDevice +QPagedPaintDevice::_ZTV17QPagedPaintDevice: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QPagedPaintDevice) +16 0u +24 0u +32 (int (*)(...))QPaintDevice::devType +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QPagedPaintDevice::setPageSize +96 (int (*)(...))QPagedPaintDevice::setPageSizeMM +104 (int (*)(...))QPagedPaintDevice::setMargins + +Class QPagedPaintDevice + size=32 align=8 + base size=32 base align=8 +QPagedPaintDevice (0x0x7f97bc0e28f0) 0 + vptr=((& QPagedPaintDevice::_ZTV17QPagedPaintDevice) + 16u) + QPaintDevice (0x0x7f97bc0f5b40) 0 + primary-for QPagedPaintDevice (0x0x7f97bc0e28f0) + +Class QPainter::PixmapFragment + size=80 align=8 + base size=80 base align=8 +QPainter::PixmapFragment (0x0x7f97bc0f5c60) 0 + +Class QPainter + size=8 align=8 + base size=8 base align=8 +QPainter (0x0x7f97bc0f5c00) 0 + +Class QTextItem + size=1 align=1 + base size=0 base align=1 +QTextItem (0x0x7f97bc1eaa80) 0 empty + +Vtable for QPaintEngine +QPaintEngine::_ZTV12QPaintEngine: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QPaintEngine) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))QPaintEngine::drawRects +64 (int (*)(...))QPaintEngine::drawRects +72 (int (*)(...))QPaintEngine::drawLines +80 (int (*)(...))QPaintEngine::drawLines +88 (int (*)(...))QPaintEngine::drawEllipse +96 (int (*)(...))QPaintEngine::drawEllipse +104 (int (*)(...))QPaintEngine::drawPath +112 (int (*)(...))QPaintEngine::drawPoints +120 (int (*)(...))QPaintEngine::drawPoints +128 (int (*)(...))QPaintEngine::drawPolygon +136 (int (*)(...))QPaintEngine::drawPolygon +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QPaintEngine::drawTextItem +160 (int (*)(...))QPaintEngine::drawTiledPixmap +168 (int (*)(...))QPaintEngine::drawImage +176 (int (*)(...))QPaintEngine::coordinateOffset +184 (int (*)(...))__cxa_pure_virtual + +Class QPaintEngine + size=32 align=8 + base size=32 base align=8 +QPaintEngine (0x0x7f97bc1ead20) 0 + vptr=((& QPaintEngine::_ZTV12QPaintEngine) + 16u) + +Class QPaintEngineState + size=4 align=4 + base size=4 base align=4 +QPaintEngineState (0x0x7f97bbfb5000) 0 + +Class QPdfWriter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPdfWriter::QPrivateSignal (0x0x7f97bbfb5420) 0 empty + +Vtable for QPdfWriter +QPdfWriter::_ZTV10QPdfWriter: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QPdfWriter) +16 (int (*)(...))QPdfWriter::metaObject +24 (int (*)(...))QPdfWriter::qt_metacast +32 (int (*)(...))QPdfWriter::qt_metacall +40 (int (*)(...))QPdfWriter::~QPdfWriter +48 (int (*)(...))QPdfWriter::~QPdfWriter +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPdfWriter::newPage +120 (int (*)(...))QPdfWriter::setPageSize +128 (int (*)(...))QPdfWriter::setPageSizeMM +136 (int (*)(...))QPdfWriter::setMargins +144 (int (*)(...))QPdfWriter::paintEngine +152 (int (*)(...))QPdfWriter::metric +160 (int (*)(...))-16 +168 (int (*)(...))(& _ZTI10QPdfWriter) +176 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD1Ev +184 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD0Ev +192 (int (*)(...))QPaintDevice::devType +200 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter11paintEngineEv +208 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter6metricEN12QPaintDevice17PaintDeviceMetricE +216 (int (*)(...))QPaintDevice::initPainter +224 (int (*)(...))QPaintDevice::redirected +232 (int (*)(...))QPaintDevice::sharedPainter +240 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter7newPageEv +248 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter11setPageSizeEN17QPagedPaintDevice8PageSizeE +256 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter13setPageSizeMMERK6QSizeF +264 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter10setMarginsERKN17QPagedPaintDevice7MarginsE + +Class QPdfWriter + size=48 align=8 + base size=48 base align=8 +QPdfWriter (0x0x7f97bc02b0e0) 0 + vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 16u) + QObject (0x0x7f97bbfb5360) 0 + primary-for QPdfWriter (0x0x7f97bc02b0e0) + QPagedPaintDevice (0x0x7f97bbed5958) 16 + vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 176u) + QPaintDevice (0x0x7f97bbfb53c0) 16 + primary-for QPagedPaintDevice (0x0x7f97bbed5958) + +Vtable for QPicture +QPicture::_ZTV8QPicture: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QPicture) +16 (int (*)(...))QPicture::~QPicture +24 (int (*)(...))QPicture::~QPicture +32 (int (*)(...))QPicture::devType +40 (int (*)(...))QPicture::paintEngine +48 (int (*)(...))QPicture::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))QPicture::setData + +Class QPicture + size=32 align=8 + base size=32 base align=8 +QPicture (0x0x7f97bbed59c0) 0 + vptr=((& QPicture::_ZTV8QPicture) + 16u) + QPaintDevice (0x0x7f97bbfb55a0) 0 + primary-for QPicture (0x0x7f97bbed59c0) + +Class QPictureIO + size=8 align=8 + base size=8 base align=8 +QPictureIO (0x0x7f97bbfb58a0) 0 + +Class QPictureFormatPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPictureFormatPlugin::QPrivateSignal (0x0x7f97bbfb5960) 0 empty + +Vtable for QPictureFormatPlugin +QPictureFormatPlugin::_ZTV20QPictureFormatPlugin: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QPictureFormatPlugin) +16 (int (*)(...))QPictureFormatPlugin::metaObject +24 (int (*)(...))QPictureFormatPlugin::qt_metacast +32 (int (*)(...))QPictureFormatPlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPictureFormatPlugin::loadPicture +120 (int (*)(...))QPictureFormatPlugin::savePicture +128 (int (*)(...))__cxa_pure_virtual + +Class QPictureFormatPlugin + size=16 align=8 + base size=16 base align=8 +QPictureFormatPlugin (0x0x7f97bbed5bc8) 0 + vptr=((& QPictureFormatPlugin::_ZTV20QPictureFormatPlugin) + 16u) + QObject (0x0x7f97bbfb5900) 0 + primary-for QPictureFormatPlugin (0x0x7f97bbed5bc8) + +Class QPixmapCache::Key + size=8 align=8 + base size=8 base align=8 +QPixmapCache::Key (0x0x7f97bbfb5a20) 0 + +Class QPixmapCache + size=1 align=1 + base size=0 base align=1 +QPixmapCache (0x0x7f97bbfb59c0) 0 empty + +Class QRasterWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRasterWindow::QPrivateSignal (0x0x7f97bbcf6ba0) 0 empty + +Vtable for QRasterWindow +QRasterWindow::_ZTV13QRasterWindow: 59u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QRasterWindow) +16 (int (*)(...))QRasterWindow::metaObject +24 (int (*)(...))QRasterWindow::qt_metacast +32 (int (*)(...))QRasterWindow::qt_metacall +40 (int (*)(...))QRasterWindow::~QRasterWindow +48 (int (*)(...))QRasterWindow::~QRasterWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))QPaintDeviceWindow::paintEvent +304 (int (*)(...))QRasterWindow::metric +312 (int (*)(...))QPaintDeviceWindow::paintEngine +320 (int (*)(...))QRasterWindow::redirected +328 (int (*)(...))-16 +336 (int (*)(...))(& _ZTI13QRasterWindow) +344 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD1Ev +352 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD0Ev +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +376 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +384 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +392 (int (*)(...))-40 +400 (int (*)(...))(& _ZTI13QRasterWindow) +408 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD1Ev +416 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD0Ev +424 (int (*)(...))QPaintDevice::devType +432 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +440 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow6metricEN12QPaintDevice17PaintDeviceMetricE +448 (int (*)(...))QPaintDevice::initPainter +456 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow10redirectedEP6QPoint +464 (int (*)(...))QPaintDevice::sharedPainter + +Class QRasterWindow + size=64 align=8 + base size=64 base align=8 +QRasterWindow (0x0x7f97bbd032d8) 0 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 16u) + QPaintDeviceWindow (0x0x7f97bbcfce70) 0 + primary-for QRasterWindow (0x0x7f97bbd032d8) + QWindow (0x0x7f97bbcfcee0) 0 + primary-for QPaintDeviceWindow (0x0x7f97bbcfce70) + QObject (0x0x7f97bbcf6a80) 0 + primary-for QWindow (0x0x7f97bbcfcee0) + QSurface (0x0x7f97bbcf6ae0) 16 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 344u) + QPaintDevice (0x0x7f97bbcf6b40) 40 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 408u) + +Class QScreen::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QScreen::QPrivateSignal (0x0x7f97bbcf6c60) 0 empty + +Vtable for QScreen +QScreen::_ZTV7QScreen: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QScreen) +16 (int (*)(...))QScreen::metaObject +24 (int (*)(...))QScreen::qt_metacast +32 (int (*)(...))QScreen::qt_metacall +40 (int (*)(...))QScreen::~QScreen +48 (int (*)(...))QScreen::~QScreen +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QScreen + size=16 align=8 + base size=16 base align=8 +QScreen (0x0x7f97bbd033a8) 0 + vptr=((& QScreen::_ZTV7QScreen) + 16u) + QObject (0x0x7f97bbcf6c00) 0 + primary-for QScreen (0x0x7f97bbd033a8) + +Class QSessionManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSessionManager::QPrivateSignal (0x0x7f97bbcf6d20) 0 empty + +Vtable for QSessionManager +QSessionManager::_ZTV15QSessionManager: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSessionManager) +16 (int (*)(...))QSessionManager::metaObject +24 (int (*)(...))QSessionManager::qt_metacast +32 (int (*)(...))QSessionManager::qt_metacall +40 (int (*)(...))QSessionManager::~QSessionManager +48 (int (*)(...))QSessionManager::~QSessionManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSessionManager + size=16 align=8 + base size=16 base align=8 +QSessionManager (0x0x7f97bbd03410) 0 + vptr=((& QSessionManager::_ZTV15QSessionManager) + 16u) + QObject (0x0x7f97bbcf6cc0) 0 + primary-for QSessionManager (0x0x7f97bbd03410) + +Vtable for QStandardItem +QStandardItem::_ZTV13QStandardItem: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStandardItem) +16 (int (*)(...))QStandardItem::~QStandardItem +24 (int (*)(...))QStandardItem::~QStandardItem +32 (int (*)(...))QStandardItem::data +40 (int (*)(...))QStandardItem::setData +48 (int (*)(...))QStandardItem::clone +56 (int (*)(...))QStandardItem::type +64 (int (*)(...))QStandardItem::read +72 (int (*)(...))QStandardItem::write +80 (int (*)(...))QStandardItem::operator< + +Class QStandardItem + size=16 align=8 + base size=16 base align=8 +QStandardItem (0x0x7f97bbcf6d80) 0 + vptr=((& QStandardItem::_ZTV13QStandardItem) + 16u) + +Class QStandardItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStandardItemModel::QPrivateSignal (0x0x7f97bbd944e0) 0 empty + +Vtable for QStandardItemModel +QStandardItemModel::_ZTV18QStandardItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QStandardItemModel) +16 (int (*)(...))QStandardItemModel::metaObject +24 (int (*)(...))QStandardItemModel::qt_metacast +32 (int (*)(...))QStandardItemModel::qt_metacall +40 (int (*)(...))QStandardItemModel::~QStandardItemModel +48 (int (*)(...))QStandardItemModel::~QStandardItemModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStandardItemModel::index +120 (int (*)(...))QStandardItemModel::parent +128 (int (*)(...))QStandardItemModel::sibling +136 (int (*)(...))QStandardItemModel::rowCount +144 (int (*)(...))QStandardItemModel::columnCount +152 (int (*)(...))QStandardItemModel::hasChildren +160 (int (*)(...))QStandardItemModel::data +168 (int (*)(...))QStandardItemModel::setData +176 (int (*)(...))QStandardItemModel::headerData +184 (int (*)(...))QStandardItemModel::setHeaderData +192 (int (*)(...))QStandardItemModel::itemData +200 (int (*)(...))QStandardItemModel::setItemData +208 (int (*)(...))QStandardItemModel::mimeTypes +216 (int (*)(...))QStandardItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QStandardItemModel::dropMimeData +240 (int (*)(...))QStandardItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStandardItemModel::insertRows +264 (int (*)(...))QStandardItemModel::insertColumns +272 (int (*)(...))QStandardItemModel::removeRows +280 (int (*)(...))QStandardItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStandardItemModel::flags +328 (int (*)(...))QStandardItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStandardItemModel + size=16 align=8 + base size=16 base align=8 +QStandardItemModel (0x0x7f97bbd03a90) 0 + vptr=((& QStandardItemModel::_ZTV18QStandardItemModel) + 16u) + QAbstractItemModel (0x0x7f97bbd03af8) 0 + primary-for QStandardItemModel (0x0x7f97bbd03a90) + QObject (0x0x7f97bbd94480) 0 + primary-for QAbstractItemModel (0x0x7f97bbd03af8) + +Class QStaticText + size=8 align=8 + base size=8 base align=8 +QStaticText (0x0x7f97bbd94540) 0 + +Class QStyleHints::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStyleHints::QPrivateSignal (0x0x7f97bbd949c0) 0 empty + +Vtable for QStyleHints +QStyleHints::_ZTV11QStyleHints: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QStyleHints) +16 (int (*)(...))QStyleHints::metaObject +24 (int (*)(...))QStyleHints::qt_metacast +32 (int (*)(...))QStyleHints::qt_metacall +40 (int (*)(...))QStyleHints::~QStyleHints +48 (int (*)(...))QStyleHints::~QStyleHints +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QStyleHints + size=16 align=8 + base size=16 base align=8 +QStyleHints (0x0x7f97bbd03d00) 0 + vptr=((& QStyleHints::_ZTV11QStyleHints) + 16u) + QObject (0x0x7f97bbd94960) 0 + primary-for QStyleHints (0x0x7f97bbd03d00) + +Class QTextObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextObject::QPrivateSignal (0x0x7f97bbd94a80) 0 empty + +Vtable for QTextObject +QTextObject::_ZTV11QTextObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextObject) +16 (int (*)(...))QTextObject::metaObject +24 (int (*)(...))QTextObject::qt_metacast +32 (int (*)(...))QTextObject::qt_metacall +40 (int (*)(...))QTextObject::~QTextObject +48 (int (*)(...))QTextObject::~QTextObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextObject + size=16 align=8 + base size=16 base align=8 +QTextObject (0x0x7f97bbd03d68) 0 + vptr=((& QTextObject::_ZTV11QTextObject) + 16u) + QObject (0x0x7f97bbd94a20) 0 + primary-for QTextObject (0x0x7f97bbd03d68) + +Class QTextBlockGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextBlockGroup::QPrivateSignal (0x0x7f97bbd94b40) 0 empty + +Vtable for QTextBlockGroup +QTextBlockGroup::_ZTV15QTextBlockGroup: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QTextBlockGroup) +16 (int (*)(...))QTextBlockGroup::metaObject +24 (int (*)(...))QTextBlockGroup::qt_metacast +32 (int (*)(...))QTextBlockGroup::qt_metacall +40 (int (*)(...))QTextBlockGroup::~QTextBlockGroup +48 (int (*)(...))QTextBlockGroup::~QTextBlockGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextBlockGroup::blockInserted +120 (int (*)(...))QTextBlockGroup::blockRemoved +128 (int (*)(...))QTextBlockGroup::blockFormatChanged + +Class QTextBlockGroup + size=16 align=8 + base size=16 base align=8 +QTextBlockGroup (0x0x7f97bbd03dd0) 0 + vptr=((& QTextBlockGroup::_ZTV15QTextBlockGroup) + 16u) + QTextObject (0x0x7f97bbd03e38) 0 + primary-for QTextBlockGroup (0x0x7f97bbd03dd0) + QObject (0x0x7f97bbd94ae0) 0 + primary-for QTextObject (0x0x7f97bbd03e38) + +Vtable for QTextFrameLayoutData +QTextFrameLayoutData::_ZTV20QTextFrameLayoutData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTextFrameLayoutData) +16 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData +24 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData + +Class QTextFrameLayoutData + size=8 align=8 + base size=8 base align=8 +QTextFrameLayoutData (0x0x7f97bbd94ba0) 0 nearly-empty + vptr=((& QTextFrameLayoutData::_ZTV20QTextFrameLayoutData) + 16u) + +Class QTextFrame::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextFrame::QPrivateSignal (0x0x7f97bbd94c60) 0 empty + +Class QTextFrame::iterator + size=32 align=8 + base size=28 base align=8 +QTextFrame::iterator (0x0x7f97bbd94cc0) 0 + +Vtable for QTextFrame +QTextFrame::_ZTV10QTextFrame: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextFrame) +16 (int (*)(...))QTextFrame::metaObject +24 (int (*)(...))QTextFrame::qt_metacast +32 (int (*)(...))QTextFrame::qt_metacall +40 (int (*)(...))QTextFrame::~QTextFrame +48 (int (*)(...))QTextFrame::~QTextFrame +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextFrame + size=16 align=8 + base size=16 base align=8 +QTextFrame (0x0x7f97bbd03ea0) 0 + vptr=((& QTextFrame::_ZTV10QTextFrame) + 16u) + QTextObject (0x0x7f97bbd03f08) 0 + primary-for QTextFrame (0x0x7f97bbd03ea0) + QObject (0x0x7f97bbd94c00) 0 + primary-for QTextObject (0x0x7f97bbd03f08) + +Vtable for QTextBlockUserData +QTextBlockUserData::_ZTV18QTextBlockUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QTextBlockUserData) +16 (int (*)(...))QTextBlockUserData::~QTextBlockUserData +24 (int (*)(...))QTextBlockUserData::~QTextBlockUserData + +Class QTextBlockUserData + size=8 align=8 + base size=8 base align=8 +QTextBlockUserData (0x0x7f97bbd94f60) 0 nearly-empty + vptr=((& QTextBlockUserData::_ZTV18QTextBlockUserData) + 16u) + +Class QTextBlock::iterator + size=24 align=8 + base size=20 base align=8 +QTextBlock::iterator (0x0x7f97bbadf060) 0 + +Class QTextBlock + size=16 align=8 + base size=12 base align=8 +QTextBlock (0x0x7f97bbadf000) 0 + +Class QTextFragment + size=16 align=8 + base size=16 base align=8 +QTextFragment (0x0x7f97bbadf540) 0 + +Class QSyntaxHighlighter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSyntaxHighlighter::QPrivateSignal (0x0x7f97bbadf840) 0 empty + +Vtable for QSyntaxHighlighter +QSyntaxHighlighter::_ZTV18QSyntaxHighlighter: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSyntaxHighlighter) +16 (int (*)(...))QSyntaxHighlighter::metaObject +24 (int (*)(...))QSyntaxHighlighter::qt_metacast +32 (int (*)(...))QSyntaxHighlighter::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QSyntaxHighlighter + size=16 align=8 + base size=16 base align=8 +QSyntaxHighlighter (0x0x7f97bbad9618) 0 + vptr=((& QSyntaxHighlighter::_ZTV18QSyntaxHighlighter) + 16u) + QObject (0x0x7f97bbadf7e0) 0 + primary-for QSyntaxHighlighter (0x0x7f97bbad9618) + +Class QTextDocumentFragment + size=8 align=8 + base size=8 base align=8 +QTextDocumentFragment (0x0x7f97bbadf8a0) 0 + +Class QTextDocumentWriter + size=8 align=8 + base size=8 base align=8 +QTextDocumentWriter (0x0x7f97bbadf900) 0 + +Class QTextList::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextList::QPrivateSignal (0x0x7f97bbadf9c0) 0 empty + +Vtable for QTextList +QTextList::_ZTV9QTextList: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTextList) +16 (int (*)(...))QTextList::metaObject +24 (int (*)(...))QTextList::qt_metacast +32 (int (*)(...))QTextList::qt_metacall +40 (int (*)(...))QTextList::~QTextList +48 (int (*)(...))QTextList::~QTextList +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextBlockGroup::blockInserted +120 (int (*)(...))QTextBlockGroup::blockRemoved +128 (int (*)(...))QTextBlockGroup::blockFormatChanged + +Class QTextList + size=16 align=8 + base size=16 base align=8 +QTextList (0x0x7f97bbad9680) 0 + vptr=((& QTextList::_ZTV9QTextList) + 16u) + QTextBlockGroup (0x0x7f97bbad96e8) 0 + primary-for QTextList (0x0x7f97bbad9680) + QTextObject (0x0x7f97bbad9750) 0 + primary-for QTextBlockGroup (0x0x7f97bbad96e8) + QObject (0x0x7f97bbadf960) 0 + primary-for QTextObject (0x0x7f97bbad9750) + +Class QTextTableCell + size=16 align=8 + base size=12 base align=8 +QTextTableCell (0x0x7f97bbadfa20) 0 + +Class QTextTable::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextTable::QPrivateSignal (0x0x7f97bbadfae0) 0 empty + +Vtable for QTextTable +QTextTable::_ZTV10QTextTable: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextTable) +16 (int (*)(...))QTextTable::metaObject +24 (int (*)(...))QTextTable::qt_metacast +32 (int (*)(...))QTextTable::qt_metacall +40 (int (*)(...))QTextTable::~QTextTable +48 (int (*)(...))QTextTable::~QTextTable +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextTable + size=16 align=8 + base size=16 base align=8 +QTextTable (0x0x7f97bbad97b8) 0 + vptr=((& QTextTable::_ZTV10QTextTable) + 16u) + QTextFrame (0x0x7f97bbad9820) 0 + primary-for QTextTable (0x0x7f97bbad97b8) + QTextObject (0x0x7f97bbad9888) 0 + primary-for QTextFrame (0x0x7f97bbad9820) + QObject (0x0x7f97bbadfa80) 0 + primary-for QTextObject (0x0x7f97bbad9888) + +Class QValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QValidator::QPrivateSignal (0x0x7f97bbadfba0) 0 empty + +Vtable for QValidator +QValidator::_ZTV10QValidator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QValidator) +16 (int (*)(...))QValidator::metaObject +24 (int (*)(...))QValidator::qt_metacast +32 (int (*)(...))QValidator::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QValidator::fixup + +Class QValidator + size=16 align=8 + base size=16 base align=8 +QValidator (0x0x7f97bbad98f0) 0 + vptr=((& QValidator::_ZTV10QValidator) + 16u) + QObject (0x0x7f97bbadfb40) 0 + primary-for QValidator (0x0x7f97bbad98f0) + +Class QIntValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIntValidator::QPrivateSignal (0x0x7f97bbadfc60) 0 empty + +Vtable for QIntValidator +QIntValidator::_ZTV13QIntValidator: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QIntValidator) +16 (int (*)(...))QIntValidator::metaObject +24 (int (*)(...))QIntValidator::qt_metacast +32 (int (*)(...))QIntValidator::qt_metacall +40 (int (*)(...))QIntValidator::~QIntValidator +48 (int (*)(...))QIntValidator::~QIntValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIntValidator::validate +120 (int (*)(...))QIntValidator::fixup +128 (int (*)(...))QIntValidator::setRange + +Class QIntValidator + size=24 align=8 + base size=24 base align=8 +QIntValidator (0x0x7f97bbad9958) 0 + vptr=((& QIntValidator::_ZTV13QIntValidator) + 16u) + QValidator (0x0x7f97bbad99c0) 0 + primary-for QIntValidator (0x0x7f97bbad9958) + QObject (0x0x7f97bbadfc00) 0 + primary-for QValidator (0x0x7f97bbad99c0) + +Class QDoubleValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDoubleValidator::QPrivateSignal (0x0x7f97bbadfd20) 0 empty + +Vtable for QDoubleValidator +QDoubleValidator::_ZTV16QDoubleValidator: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QDoubleValidator) +16 (int (*)(...))QDoubleValidator::metaObject +24 (int (*)(...))QDoubleValidator::qt_metacast +32 (int (*)(...))QDoubleValidator::qt_metacall +40 (int (*)(...))QDoubleValidator::~QDoubleValidator +48 (int (*)(...))QDoubleValidator::~QDoubleValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QDoubleValidator::validate +120 (int (*)(...))QValidator::fixup +128 (int (*)(...))QDoubleValidator::setRange + +Class QDoubleValidator + size=40 align=8 + base size=36 base align=8 +QDoubleValidator (0x0x7f97bbad9a28) 0 + vptr=((& QDoubleValidator::_ZTV16QDoubleValidator) + 16u) + QValidator (0x0x7f97bbad9a90) 0 + primary-for QDoubleValidator (0x0x7f97bbad9a28) + QObject (0x0x7f97bbadfcc0) 0 + primary-for QValidator (0x0x7f97bbad9a90) + +Class QRegExpValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRegExpValidator::QPrivateSignal (0x0x7f97bbadfe40) 0 empty + +Vtable for QRegExpValidator +QRegExpValidator::_ZTV16QRegExpValidator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QRegExpValidator) +16 (int (*)(...))QRegExpValidator::metaObject +24 (int (*)(...))QRegExpValidator::qt_metacast +32 (int (*)(...))QRegExpValidator::qt_metacall +40 (int (*)(...))QRegExpValidator::~QRegExpValidator +48 (int (*)(...))QRegExpValidator::~QRegExpValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QRegExpValidator::validate +120 (int (*)(...))QValidator::fixup + +Class QRegExpValidator + size=24 align=8 + base size=24 base align=8 +QRegExpValidator (0x0x7f97bbad9af8) 0 + vptr=((& QRegExpValidator::_ZTV16QRegExpValidator) + 16u) + QValidator (0x0x7f97bbad9b60) 0 + primary-for QRegExpValidator (0x0x7f97bbad9af8) + QObject (0x0x7f97bbadfde0) 0 + primary-for QValidator (0x0x7f97bbad9b60) + +Class QRegularExpressionValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRegularExpressionValidator::QPrivateSignal (0x0x7f97bbadff00) 0 empty + +Vtable for QRegularExpressionValidator +QRegularExpressionValidator::_ZTV27QRegularExpressionValidator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QRegularExpressionValidator) +16 (int (*)(...))QRegularExpressionValidator::metaObject +24 (int (*)(...))QRegularExpressionValidator::qt_metacast +32 (int (*)(...))QRegularExpressionValidator::qt_metacall +40 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator +48 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QRegularExpressionValidator::validate +120 (int (*)(...))QValidator::fixup + +Class QRegularExpressionValidator + size=16 align=8 + base size=16 base align=8 +QRegularExpressionValidator (0x0x7f97bbad9bc8) 0 + vptr=((& QRegularExpressionValidator::_ZTV27QRegularExpressionValidator) + 16u) + QValidator (0x0x7f97bbad9c30) 0 + primary-for QRegularExpressionValidator (0x0x7f97bbad9bc8) + QObject (0x0x7f97bbadfea0) 0 + primary-for QValidator (0x0x7f97bbad9c30) + diff --git a/tests/auto/bic/data/QtNetwork.5.12.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtNetwork.5.12.0.linux-gcc-amd64.txt new file mode 100644 index 0000000000..d8afba6062 --- /dev/null +++ b/tests/auto/bic/data/QtNetwork.5.12.0.linux-gcc-amd64.txt @@ -0,0 +1,5509 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7f30cfb60960) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7f30cd790120) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7f30cd790360) 0 empty + +Class std::__do_is_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_default_constructible_impl (0x0x7f30cd7905a0) 0 empty + +Class std::__do_is_static_castable_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_static_castable_impl (0x0x7f30cd7907e0) 0 empty + +Class std::__do_is_direct_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_direct_constructible_impl (0x0x7f30cd790960) 0 empty + +Class std::__do_is_nary_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nary_constructible_impl (0x0x7f30cd790d20) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7f30cd84d4e0) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7f30cd84d5a0) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7f30cd84d900) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7f30cd84d9c0) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7f30cd84da80) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7f30cd84db40) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7f30cd84dde0) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7f30cd89c000) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7f30cd89c480) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7f30cd89c4e0) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7f30cd936180) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7f30cd9361e0) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7f30cd8437b8) 0 empty + std::input_iterator_tag (0x0x7f30cd936240) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7f30cd843820) 0 empty + std::forward_iterator_tag (0x0x7f30cd843888) 0 empty + std::input_iterator_tag (0x0x7f30cd9362a0) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7f30cd8438f0) 0 empty + std::bidirectional_iterator_tag (0x0x7f30cd843958) 0 empty + std::forward_iterator_tag (0x0x7f30cd8439c0) 0 empty + std::input_iterator_tag (0x0x7f30cd936300) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7f30cd936f60) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7f30cd5ec000) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7f30cd5ec060) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7f30cd5ec0c0) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7f30cd5ec120) 0 empty + +Class wait + size=4 align=4 + base size=4 base align=4 +wait (0x0x7f30cd5ecc00) 0 + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7f30cd5ece40) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7f30cd5ecf00) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7f30cd5ecf60) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7f30cd6b0060) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7f30cd6b00c0) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7f30cd6b0540) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7f30cd6b05a0) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7f30cd6b0600) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16u) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7f30cd843f08) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u) + std::exception (0x0x7f30cd6b0660) 0 nearly-empty + primary-for std::bad_exception (0x0x7f30cd843f08) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7f30cd6b06c0) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7f30cd6b0720) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16u) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7f30cd3a6138) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u) + std::exception (0x0x7f30cd6b0b40) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f30cd3a6138) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7f30cd3a61a0) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16u) + std::bad_alloc (0x0x7f30cd3a6208) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7f30cd3a61a0) + std::exception (0x0x7f30cd6b0ba0) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f30cd3a6208) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7f30cd6b0c00) 0 empty + +Class __exception + size=40 align=8 + base size=40 base align=8 +__exception (0x0x7f30cd419840) 0 + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7f30cd22e540) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7f30cd22e5a0) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7f30cd2da480) 0 + +Class __sched_param + size=4 align=4 + base size=4 base align=4 +__sched_param (0x0x7f30cd2da4e0) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7f30cd2da5a0) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7f30cd2da600) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7f30cd2da660) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7f30cd2da6c0) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7f30cd2da7e0) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7f30cd2da840) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7f30cd2dac60) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7f30cd2dacc0) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7f30cce234e0) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7f30cce23540) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7f30ccede4e0) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7f30ccc92300) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7f30cce22f70) 0 + std::iterator (0x0x7f30ccc923c0) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7f30cce22750) 0 + std::_Bit_iterator_base (0x0x7f30cce227b8) 0 + std::iterator (0x0x7f30ccc92420) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7f30cce22a90) 0 + std::_Bit_iterator_base (0x0x7f30cce22af8) 0 + std::iterator (0x0x7f30ccc92480) 0 empty + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7f30cca9f2a0) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7f30cc7ff060) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7f30cc7ff000) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7f30cc5d6000) 0 + +Class qIsNull(double)::U + size=8 align=8 + base size=8 base align=8 +qIsNull(double)::U (0x0x7f30cb455ae0) 0 + +Class qIsNull(float)::U + size=4 align=4 + base size=4 base align=4 +qIsNull(float)::U (0x0x7f30cb455b40) 0 + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7f30cb19f600) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7f30cb19f660) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7f30cb19f6c0) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7f30cb19f720) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7f30cb19f9c0) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7f30cb19ff00) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7f30cb188e38) 0 + std::__atomic_flag_base (0x0x7f30cb19ff60) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7f30cafbc5b0) 0 + QAtomicInteger (0x0x7f30cafbc618) 0 + QBasicAtomicInteger (0x0x7f30cb0f96c0) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7f30cac3fc60) 0 empty + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7f30caa2fe40) 0 + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7f30caa2ff60) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7f30caa93208) 0 + QGenericArgument (0x0x7f30caaa4000) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7f30caaa4180) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7f30caaa4240) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7f30ca75d2a0) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7f30ca75d300) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7f30ca75d5a0) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7f30ca75d600) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7f30ca75d960) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7f30ca75d9c0) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7f30ca75da20) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7f30ca75da80) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7f30ca75dae0) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7f30ca75dea0) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7f30ca871820) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16u) + std::exception (0x0x7f30ca75df60) 0 nearly-empty + primary-for std::logic_error (0x0x7f30ca871820) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7f30ca871888) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16u) + std::logic_error (0x0x7f30ca8718f0) 0 + primary-for std::domain_error (0x0x7f30ca871888) + std::exception (0x0x7f30ca90d000) 0 nearly-empty + primary-for std::logic_error (0x0x7f30ca8718f0) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7f30ca871958) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16u) + std::logic_error (0x0x7f30ca8719c0) 0 + primary-for std::invalid_argument (0x0x7f30ca871958) + std::exception (0x0x7f30ca90d060) 0 nearly-empty + primary-for std::logic_error (0x0x7f30ca8719c0) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7f30ca871a28) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16u) + std::logic_error (0x0x7f30ca871a90) 0 + primary-for std::length_error (0x0x7f30ca871a28) + std::exception (0x0x7f30ca90d0c0) 0 nearly-empty + primary-for std::logic_error (0x0x7f30ca871a90) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7f30ca871af8) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16u) + std::logic_error (0x0x7f30ca871b60) 0 + primary-for std::out_of_range (0x0x7f30ca871af8) + std::exception (0x0x7f30ca90d120) 0 nearly-empty + primary-for std::logic_error (0x0x7f30ca871b60) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7f30ca871bc8) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16u) + std::exception (0x0x7f30ca90d180) 0 nearly-empty + primary-for std::runtime_error (0x0x7f30ca871bc8) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7f30ca871c30) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16u) + std::runtime_error (0x0x7f30ca871c98) 0 + primary-for std::range_error (0x0x7f30ca871c30) + std::exception (0x0x7f30ca90d1e0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f30ca871c98) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7f30ca871d00) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16u) + std::runtime_error (0x0x7f30ca871d68) 0 + primary-for std::overflow_error (0x0x7f30ca871d00) + std::exception (0x0x7f30ca90d240) 0 nearly-empty + primary-for std::runtime_error (0x0x7f30ca871d68) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7f30ca871dd0) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16u) + std::runtime_error (0x0x7f30ca871e38) 0 + primary-for std::underflow_error (0x0x7f30ca871dd0) + std::exception (0x0x7f30ca90d2a0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f30ca871e38) + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7f30ca90d420) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16u) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7f30ca90d660) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7f30ca90d7e0) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7f30ca555270) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16u) + std::runtime_error (0x0x7f30ca5552d8) 0 + primary-for std::system_error (0x0x7f30ca555270) + std::exception (0x0x7f30ca90da20) 0 nearly-empty + primary-for std::runtime_error (0x0x7f30ca5552d8) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7f30ca555ea0) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16u) + std::system_error (0x0x7f30ca555f08) 0 + primary-for std::ios_base::failure (0x0x7f30ca555ea0) + std::runtime_error (0x0x7f30ca555f70) 0 + primary-for std::system_error (0x0x7f30ca555f08) + std::exception (0x0x7f30ca90dd20) 0 nearly-empty + primary-for std::runtime_error (0x0x7f30ca555f70) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7f30ca90dd80) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7f30ca90dde0) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7f30ca90de40) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7f30ca90dcc0) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7f30ca666600) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7f30ca666cc0) 0 empty + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSo: 2u entries +0 ((& std::basic_ostream::_ZTVSo) + 24u) +8 ((& std::basic_ostream::_ZTVSo) + 64u) + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSi: 2u entries +0 ((& std::basic_istream::_ZTVSi) + 24u) +8 ((& std::basic_istream::_ZTVSi) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u) + +Construction vtable for std::basic_istream (0x0x7f30ca226888 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd0_Si: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7f30ca226958 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd16_So: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSd: 7u entries +0 ((& std::basic_iostream::_ZTVSd) + 24u) +8 ((& std::basic_iostream::_ZTCSd0_Si) + 24u) +16 ((& std::basic_iostream::_ZTCSd0_Si) + 64u) +24 ((& std::basic_iostream::_ZTCSd16_So) + 24u) +32 ((& std::basic_iostream::_ZTCSd16_So) + 64u) +40 ((& std::basic_iostream::_ZTVSd) + 104u) +48 ((& std::basic_iostream::_ZTVSd) + 64u) + +Construction vtable for std::basic_istream (0x0x7f30ca226d00 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7f30ca226dd0 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries +0 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u) +16 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u) +24 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u) +32 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u) +40 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u) +48 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u) + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7f30ca207540) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7f30ca2075a0) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7f30c9fa2900) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7f30c9fa2c60) 0 + +Class QStringView + size=16 align=8 + base size=16 base align=8 +QStringView (0x0x7f30ca09a120) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7f30ca09af60) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7f30c9d69600) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7f30c9d695a0) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7f30c9f086c0) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7f30c9ca8300) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7f30c9ca8f60) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7f30c9ab9000) 0 empty + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7f30c9ab9060) 0 + +Class QListData::NotArrayCompatibleLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotArrayCompatibleLayout (0x0x7f30c9ab9420) 0 empty + +Class QListData::NotIndirectLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotIndirectLayout (0x0x7f30c9ab9480) 0 empty + +Class QListData::ArrayCompatibleLayout + size=1 align=1 + base size=1 base align=1 +QListData::ArrayCompatibleLayout (0x0x7f30c9d46820) 0 empty + QListData::NotIndirectLayout (0x0x7f30c9ab94e0) 0 empty + +Class QListData::InlineWithPaddingLayout + size=1 align=1 + base size=1 base align=1 +QListData::InlineWithPaddingLayout (0x0x7f30c977f000) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f30c9ab9540) 0 empty + QListData::NotIndirectLayout (0x0x7f30c9ab95a0) 0 empty + +Class QListData::IndirectLayout + size=1 align=1 + base size=1 base align=1 +QListData::IndirectLayout (0x0x7f30c9d46888) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f30c9ab9600) 0 empty + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7f30c9ab9660) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7f30c9ab93c0) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7f30c9ab9ae0) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7f30c9928d20) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7f30c9928cc0) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7f30c993a2d8) 0 + QList (0x0x7f30c993a340) 0 + QListSpecialMethods (0x0x7f30c9928f00) 0 empty + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7f30c9594360) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7f30c9594f00) 0 + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7f30c96895a0) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7f30c9689720) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7f30c96897e0) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7f30c993ac30) 0 + std::__uses_alloc_base (0x0x7f30c9689780) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7f30c94bc840) 0 empty + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7f30c94bca80) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7f30c94bcb40) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7f30c94bcc60) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7f30c94bcde0) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7f30c91fe240) 0 + +Class QtMetaTypePrivate::VectorBoolElements + size=1 align=1 + base size=0 base align=1 +QtMetaTypePrivate::VectorBoolElements (0x0x7f30c91fe360) 0 empty + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7f30c91fecc0) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7f30c92f9120) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7f30c92f9420) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7f30c9136de0) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7f30c8ea5c60) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7f30c8ea5cc0) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16u) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7f30c8ea5ea0) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7f30c8ea5e40) 0 + vptr=((& QObject::_ZTV7QObject) + 16u) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7f30c8bb1180) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7f30c8bb11e0) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7f30c8bb12a0) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7f30c8b7f208) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u) + QObject (0x0x7f30c8bb1240) 0 + primary-for QAbstractAnimation (0x0x7f30c8b7f208) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7f30c8bb1360) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7f30c8b7f3a8) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16u) + QObject (0x0x7f30c8bb1300) 0 + primary-for QAnimationDriver (0x0x7f30c8b7f3a8) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7f30c8bb1420) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7f30c8b7f478) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u) + QObject (0x0x7f30c8bb13c0) 0 + primary-for QEventLoop (0x0x7f30c8b7f478) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7f30c8bb1600) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7f30c8bb16c0) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7f30c8bb1720) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7f30c8c10068) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u) + QObject (0x0x7f30c8bb1660) 0 + primary-for QAbstractEventDispatcher (0x0x7f30c8c10068) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7f30c8bb19c0) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16u) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7f30c8c10270) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16u) + std::exception (0x0x7f30c8bb1a20) 0 nearly-empty + primary-for std::bad_cast (0x0x7f30c8c10270) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7f30c8c102d8) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16u) + std::exception (0x0x7f30c8bb1a80) 0 nearly-empty + primary-for std::bad_typeid (0x0x7f30c8c102d8) + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7f30c89ab548) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16u) + std::exception (0x0x7f30c896db40) 0 nearly-empty + primary-for std::bad_function_call (0x0x7f30c89ab548) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7f30c896dc00) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7f30c896dc60) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7f30c896dd80) 0 + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7f30c8a372a0) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7f30c8a377e0) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7f30c8a37ba0) 0 + +Class QHashData + size=48 align=8 + base size=44 base align=8 +QHashData (0x0x7f30c8a37b40) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7f30c8a37c00) 0 empty + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7f30c87b34e0) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7f30c87b35a0) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7f30c87b3540) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7f30c87b3600) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7f30c87b3480) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7f30c8601120) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7f30c8601780) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7f30c8601720) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7f30c8601840) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7f30c86017e0) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7f30c8730b40) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7f30c8475240) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7f30c8512960) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7f30c85262d8) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u) + QObject (0x0x7f30c8512900) 0 + primary-for QAbstractItemModel (0x0x7f30c85262d8) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7f30c81b7240) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7f30c85269c0) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u) + QAbstractItemModel (0x0x7f30c8526a28) 0 + primary-for QAbstractTableModel (0x0x7f30c85269c0) + QObject (0x0x7f30c81b71e0) 0 + primary-for QAbstractItemModel (0x0x7f30c8526a28) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7f30c81b7300) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7f30c8526a90) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u) + QAbstractItemModel (0x0x7f30c8526af8) 0 + primary-for QAbstractListModel (0x0x7f30c8526a90) + QObject (0x0x7f30c81b72a0) 0 + primary-for QAbstractItemModel (0x0x7f30c8526af8) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7f30c81b75a0) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16u) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7f30c81b7660) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7f30c8526c30) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16u) + QAbstractItemModel (0x0x7f30c8526c98) 0 + primary-for QAbstractProxyModel (0x0x7f30c8526c30) + QObject (0x0x7f30c81b7600) 0 + primary-for QAbstractItemModel (0x0x7f30c8526c98) + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7f30c81b7720) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7f30c8526d00) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u) + QObject (0x0x7f30c81b76c0) 0 + primary-for QAbstractState (0x0x7f30c8526d00) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7f30c81b77e0) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7f30c8526d68) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u) + QObject (0x0x7f30c81b7780) 0 + primary-for QAbstractTransition (0x0x7f30c8526d68) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7f30c81b78a0) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7f30c8526dd0) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u) + QAbstractAnimation (0x0x7f30c8526e38) 0 + primary-for QAnimationGroup (0x0x7f30c8526dd0) + QObject (0x0x7f30c81b7840) 0 + primary-for QAbstractAnimation (0x0x7f30c8526e38) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7f30c82e1600) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7f30c82e18a0) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7f30c82e1960) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7f30c82e1c60) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7f30c82f04e0) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16u) + QObject (0x0x7f30c82e1c00) 0 + primary-for QIODevice (0x0x7f30c82f04e0) + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7f30c82e1ea0) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7f30c82f0618) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16u) + QIODevice (0x0x7f30c82f0680) 0 + primary-for QBuffer (0x0x7f30c82f0618) + QObject (0x0x7f30c82e1e40) 0 + primary-for QIODevice (0x0x7f30c82f0680) + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7f30c82e1f60) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7f30c82e1f00) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7f30c7fd30c0) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7f30c7fd3060) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7f30c7fd32a0) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7f30c7fd3480) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7f30c7fd3720) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7f30c7fd3ea0) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7f30c7fd3f00) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7f30c7fd3e40) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7f30c7d64060) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7f30c7d64660) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16u) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7f30c7d64900) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7f30c7d64b40) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7f30c7b44240) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7f30c7b443c0) 0 + +Class QDebug::Stream + size=80 align=8 + base size=76 base align=8 +QDebug::Stream (0x0x7f30c7b44900) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7f30c7b448a0) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7f30c797ac00) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7f30c797acc0) 0 empty + +Class QCborError + size=4 align=4 + base size=4 base align=4 +QCborError (0x0x7f30c7a20060) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7f30c7a201e0) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7f30c7a207e0) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7f30c7a20ae0) 0 + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7f30c7a20ea0) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7f30c77f65a0) 0 + +Class QCborParserError + size=16 align=8 + base size=12 base align=8 +QCborParserError (0x0x7f30c77f6ba0) 0 + +Class QCborValue + size=24 align=8 + base size=20 base align=8 +QCborValue (0x0x7f30c77f6c00) 0 + +Class QCborValueRef + size=16 align=8 + base size=16 base align=8 +QCborValueRef (0x0x7f30c76b2c00) 0 + +Class QCborArray::Iterator + size=16 align=8 + base size=16 base align=8 +QCborArray::Iterator (0x0x7f30c73921e0) 0 + +Class QCborArray::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborArray::ConstIterator (0x0x7f30c7392240) 0 + +Class QCborArray + size=8 align=8 + base size=8 base align=8 +QCborArray (0x0x7f30c7392180) 0 + +Class QCborMap::Iterator + size=16 align=8 + base size=16 base align=8 +QCborMap::Iterator (0x0x7f30c74572a0) 0 + +Class QCborMap::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborMap::ConstIterator (0x0x7f30c7457300) 0 + +Class QCborMap + size=8 align=8 + base size=8 base align=8 +QCborMap (0x0x7f30c7457240) 0 + +Class qfloat16 + size=2 align=2 + base size=2 base align=2 +qfloat16 (0x0x7f30c717ce40) 0 + +Class QCborStreamWriter + size=8 align=8 + base size=8 base align=8 +QCborStreamWriter (0x0x7f30c727d240) 0 + +Class QCborStreamReader + size=24 align=8 + base size=20 base align=8 +QCborStreamReader (0x0x7f30c727dc00) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7f30c6f4e2a0) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7f30c6f4e360) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7f30c7041360) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7f30c70417e0) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16u) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7f30c7036c30) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u) + QEvent (0x0x7f30c7041840) 0 + primary-for QTimerEvent (0x0x7f30c7036c30) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7f30c7036c98) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u) + QEvent (0x0x7f30c70418a0) 0 + primary-for QChildEvent (0x0x7f30c7036c98) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7f30c70bc208) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u) + QEvent (0x0x7f30c7041d80) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7f30c70bc208) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7f30c70bc270) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16u) + QEvent (0x0x7f30c7041de0) 0 + primary-for QDeferredDeleteEvent (0x0x7f30c70bc270) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7f30c7041ea0) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7f30c70bc2d8) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u) + QObject (0x0x7f30c7041e40) 0 + primary-for QCoreApplication (0x0x7f30c70bc2d8) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7f30c7041f00) 0 + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7f30c7041f60) 0 + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7f30c7109000) 0 + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7f30c71090c0) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7f30c71095a0) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7f30c7109a80) 0 + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7f30c6e80900) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7f30c6e85750) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16u) + QIODevice (0x0x7f30c6e857b8) 0 + primary-for QFileDevice (0x0x7f30c6e85750) + QObject (0x0x7f30c6e808a0) 0 + primary-for QIODevice (0x0x7f30c6e857b8) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7f30c6e80b40) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7f30c6e858f0) 0 + vptr=((& QFile::_ZTV5QFile) + 16u) + QFileDevice (0x0x7f30c6e85958) 0 + primary-for QFile (0x0x7f30c6e858f0) + QIODevice (0x0x7f30c6e859c0) 0 + primary-for QFileDevice (0x0x7f30c6e85958) + QObject (0x0x7f30c6e80ae0) 0 + primary-for QIODevice (0x0x7f30c6e859c0) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7f30c6e80d20) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7f30c6b3c180) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7f30c6b3c780) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7f30c6b3c9c0) 0 + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7f30c6c8ade0) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7f30c6c909c0) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u) + QAbstractTransition (0x0x7f30c6c90a28) 0 + primary-for QEventTransition (0x0x7f30c6c909c0) + QObject (0x0x7f30c6c8ad80) 0 + primary-for QAbstractTransition (0x0x7f30c6c90a28) + +Vtable for QException +QException::_ZTV10QException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7f30c6c90a90) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16u) + std::exception (0x0x7f30c6c8ae40) 0 nearly-empty + primary-for QException (0x0x7f30c6c90a90) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7f30c6c90af8) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16u) + QException (0x0x7f30c6c90b60) 0 nearly-empty + primary-for QUnhandledException (0x0x7f30c6c90af8) + std::exception (0x0x7f30c6c8aea0) 0 nearly-empty + primary-for QException (0x0x7f30c6c90b60) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7f30c6c8af00) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7f30c691a000) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7f30c691a060) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7f30c691a180) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7f30c6c90bc8) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16u) + QObject (0x0x7f30c691a120) 0 + primary-for QFileSelector (0x0x7f30c6c90bc8) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7f30c691a240) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7f30c6c90c30) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u) + QObject (0x0x7f30c691a1e0) 0 + primary-for QFileSystemWatcher (0x0x7f30c6c90c30) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7f30c691a300) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7f30c6c90c98) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16u) + QAbstractState (0x0x7f30c6c90d00) 0 + primary-for QFinalState (0x0x7f30c6c90c98) + QObject (0x0x7f30c691a2a0) 0 + primary-for QAbstractState (0x0x7f30c6c90d00) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7f30c691a360) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16u) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7f30c691a3c0) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7f30c6c90e38) 0 + QBasicMutex (0x0x7f30c691a5a0) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7f30c691a600) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7f30c691a660) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7f30c691a6c0) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7f30c691a7e0) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16u) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7f30c6a43060) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7f30c6a43840) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0u +48 0u +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7f30c6a38f70) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u) + QObject (0x0x7f30c6a437e0) 0 + primary-for QFutureWatcherBase (0x0x7f30c6a38f70) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7f30c6a43e40) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7f30c6afd888) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u) + QAbstractState (0x0x7f30c6afd8f0) 0 + primary-for QHistoryState (0x0x7f30c6afd888) + QObject (0x0x7f30c6a43de0) 0 + primary-for QAbstractState (0x0x7f30c6afd8f0) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7f30c6a43f00) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7f30c6afd958) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16u) + QAbstractProxyModel (0x0x7f30c6afd9c0) 0 + primary-for QIdentityProxyModel (0x0x7f30c6afd958) + QAbstractItemModel (0x0x7f30c6afda28) 0 + primary-for QAbstractProxyModel (0x0x7f30c6afd9c0) + QObject (0x0x7f30c6a43ea0) 0 + primary-for QAbstractItemModel (0x0x7f30c6afda28) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7f30c6a43f60) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7f30c6768660) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7f30c6793270) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u) + QObject (0x0x7f30c6768600) 0 + primary-for QItemSelectionModel (0x0x7f30c6793270) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7f30c6793478) 0 + QList (0x0x7f30c67934e0) 0 + QListSpecialMethods (0x0x7f30c6768960) 0 empty + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7f30c6768e40) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7f30c65985a0) 0 + +Class QJsonValuePtr + size=24 align=8 + base size=24 base align=8 +QJsonValuePtr (0x0x7f30c6598ae0) 0 + +Class QJsonValueRefPtr + size=16 align=8 + base size=16 base align=8 +QJsonValueRefPtr (0x0x7f30c6598b40) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7f30c6598d20) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7f30c6598d80) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7f30c6598cc0) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7f30c6313000) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7f30c6313060) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7f30c63136c0) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7f30c6313720) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7f30c6313660) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7f30c63e29c0) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7f30c63e7820) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16u) + QObject (0x0x7f30c63e2960) 0 + primary-for QLibrary (0x0x7f30c63e7820) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7f30c64710c0) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7f30c63e2ba0) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7f30c64715a0) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7f30c6471600) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7f30c64718a0) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7f30c6471ea0) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7f30c6171840) 0 + +Class QLinkedListData + size=32 align=8 + base size=25 base align=8 +QLinkedListData (0x0x7f30c6171e40) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7f30c62131e0) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7f30c6213360) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7f30c6213300) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7f30c62134e0) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7f30c6213780) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7f30c6213de0) 0 + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7f30c6213e40) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7f30c5ee0480) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7f30c5ee0780) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7f30c5ee07e0) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7f30c5ee0ae0) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7f30c5e78a90) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16u) + QObject (0x0x7f30c5ee0a80) 0 + primary-for QMimeData (0x0x7f30c5e78a90) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7f30c5ee0b40) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7f30c5ee0e40) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7f30c5ee0f00) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7f30c5e78c98) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u) + QObject (0x0x7f30c5ee0ea0) 0 + primary-for QObjectCleanupHandler (0x0x7f30c5e78c98) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7f30c5ee0f60) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7f30c5f6d720) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7f30c5f733a8) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u) + QAnimationGroup (0x0x7f30c5f73410) 0 + primary-for QParallelAnimationGroup (0x0x7f30c5f733a8) + QAbstractAnimation (0x0x7f30c5f73478) 0 + primary-for QAnimationGroup (0x0x7f30c5f73410) + QObject (0x0x7f30c5f6d6c0) 0 + primary-for QAbstractAnimation (0x0x7f30c5f73478) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7f30c5f6d7e0) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7f30c5f734e0) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u) + QAbstractAnimation (0x0x7f30c5f73548) 0 + primary-for QPauseAnimation (0x0x7f30c5f734e0) + QObject (0x0x7f30c5f6d780) 0 + primary-for QAbstractAnimation (0x0x7f30c5f73548) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7f30c5f6d9c0) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7f30c5f6dcc0) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7f30c5f73750) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u) + QObject (0x0x7f30c5f6dc60) 0 + primary-for QPluginLoader (0x0x7f30c5f73750) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7f30c5f6dd20) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7f30c5ff7420) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7f30c5f73dd0) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16u) + QIODevice (0x0x7f30c5f73e38) 0 + primary-for QProcess (0x0x7f30c5f73dd0) + QObject (0x0x7f30c5ff73c0) 0 + primary-for QIODevice (0x0x7f30c5f73e38) + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7f30c5ff74e0) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7f30c5f73ea0) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u) + QAbstractAnimation (0x0x7f30c5f73f08) 0 + primary-for QVariantAnimation (0x0x7f30c5f73ea0) + QObject (0x0x7f30c5ff7480) 0 + primary-for QAbstractAnimation (0x0x7f30c5f73f08) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7f30c5ff75a0) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7f30c5c4f000) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u) + QVariantAnimation (0x0x7f30c5c4f068) 0 + primary-for QPropertyAnimation (0x0x7f30c5c4f000) + QAbstractAnimation (0x0x7f30c5c4f0d0) 0 + primary-for QVariantAnimation (0x0x7f30c5c4f068) + QObject (0x0x7f30c5ff7540) 0 + primary-for QAbstractAnimation (0x0x7f30c5c4f0d0) + +Class QRandomGenerator::Storage + size=2504 align=8 + base size=2504 base align=8 +QRandomGenerator::Storage (0x0x7f30c5ff76c0) 0 + +Class QRandomGenerator + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator (0x0x7f30c5ff7660) 0 + +Class QRandomGenerator64 + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator64 (0x0x7f30c5cf23a8) 0 + QRandomGenerator (0x0x7f30c5ce1660) 0 + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7f30c5ce1720) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7f30c5ce19c0) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7f30c5ce1a80) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7f30c5ce1b40) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7f30c5ce1de0) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7f30c5dfe0c0) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7f30c5dfe360) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7f30c5dfe600) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7f30c5dfe780) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7f30c5cf2f08) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16u) + QFileDevice (0x0x7f30c5cf2f70) 0 + primary-for QSaveFile (0x0x7f30c5cf2f08) + QIODevice (0x0x7f30c5b67000) 0 + primary-for QFileDevice (0x0x7f30c5cf2f70) + QObject (0x0x7f30c5dfe720) 0 + primary-for QIODevice (0x0x7f30c5b67000) + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7f30c5dfe8a0) 0 + +Class QSemaphoreReleaser + size=16 align=8 + base size=12 base align=8 +QSemaphoreReleaser (0x0x7f30c5dfea20) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7f30c58b7060) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7f30c58ab888) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u) + QAnimationGroup (0x0x7f30c58ab8f0) 0 + primary-for QSequentialAnimationGroup (0x0x7f30c58ab888) + QAbstractAnimation (0x0x7f30c58ab958) 0 + primary-for QAnimationGroup (0x0x7f30c58ab8f0) + QObject (0x0x7f30c58b7000) 0 + primary-for QAbstractAnimation (0x0x7f30c58ab958) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7f30c58b7120) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7f30c58ab9c0) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16u) + QObject (0x0x7f30c58b70c0) 0 + primary-for QSettings (0x0x7f30c58ab9c0) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7f30c58b71e0) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7f30c58aba28) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u) + QObject (0x0x7f30c58b7180) 0 + primary-for QSharedMemory (0x0x7f30c58aba28) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7f30c58b72a0) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7f30c58aba90) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u) + QObject (0x0x7f30c58b7240) 0 + primary-for QSignalMapper (0x0x7f30c58aba90) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7f30c58b7360) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7f30c58abaf8) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u) + QAbstractTransition (0x0x7f30c58abb60) 0 + primary-for QSignalTransition (0x0x7f30c58abaf8) + QObject (0x0x7f30c58b7300) 0 + primary-for QAbstractTransition (0x0x7f30c58abb60) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7f30c58b7420) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7f30c58abbc8) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u) + QObject (0x0x7f30c58b73c0) 0 + primary-for QSocketNotifier (0x0x7f30c58abbc8) + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7f30c58b74e0) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7f30c58abc30) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16u) + QAbstractProxyModel (0x0x7f30c58abc98) 0 + primary-for QSortFilterProxyModel (0x0x7f30c58abc30) + QAbstractItemModel (0x0x7f30c58abd00) 0 + primary-for QAbstractProxyModel (0x0x7f30c58abc98) + QObject (0x0x7f30c58b7480) 0 + primary-for QAbstractItemModel (0x0x7f30c58abd00) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7f30c58b75a0) 0 empty + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7f30c58b77e0) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7f30c58abea0) 0 + vptr=((& QState::_ZTV6QState) + 16u) + QAbstractState (0x0x7f30c58abf08) 0 + primary-for QState (0x0x7f30c58abea0) + QObject (0x0x7f30c58b7780) 0 + primary-for QAbstractState (0x0x7f30c58abf08) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7f30c58b7900) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7f30c59b50d0) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u) + QEvent (0x0x7f30c58b7960) 0 + primary-for QStateMachine::SignalEvent (0x0x7f30c59b50d0) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7f30c59b5138) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u) + QEvent (0x0x7f30c58b79c0) 0 + primary-for QStateMachine::WrappedEvent (0x0x7f30c59b5138) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7f30c58abf70) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u) + QState (0x0x7f30c59b5000) 0 + primary-for QStateMachine (0x0x7f30c58abf70) + QAbstractState (0x0x7f30c59b5068) 0 + primary-for QState (0x0x7f30c59b5000) + QObject (0x0x7f30c58b78a0) 0 + primary-for QAbstractState (0x0x7f30c59b5068) + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7f30c58b7a20) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7f30c5a00960) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7f30c567fd20) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7f30c56bd138) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u) + QAbstractListModel (0x0x7f30c56bd1a0) 0 + primary-for QStringListModel (0x0x7f30c56bd138) + QAbstractItemModel (0x0x7f30c56bd208) 0 + primary-for QAbstractListModel (0x0x7f30c56bd1a0) + QObject (0x0x7f30c567fcc0) 0 + primary-for QAbstractItemModel (0x0x7f30c56bd208) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7f30c567fd80) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7f30c567fe40) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7f30c567ff60) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7f30c56bd270) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u) + QFile (0x0x7f30c56bd2d8) 0 + primary-for QTemporaryFile (0x0x7f30c56bd270) + QFileDevice (0x0x7f30c56bd340) 0 + primary-for QFile (0x0x7f30c56bd2d8) + QIODevice (0x0x7f30c56bd3a8) 0 + primary-for QFileDevice (0x0x7f30c56bd340) + QObject (0x0x7f30c567ff00) 0 + primary-for QIODevice (0x0x7f30c56bd3a8) + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7f30c5714000) 0 + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7f30c5714240) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 0u +64 0u + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7f30c57141e0) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7f30c5714420) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7f30c5714480) 0 + +Class std::__mutex_base + size=40 align=8 + base size=40 base align=8 +std::__mutex_base (0x0x7f30c57144e0) 0 + +Class std::__recursive_mutex_base + size=40 align=8 + base size=40 base align=8 +std::__recursive_mutex_base (0x0x7f30c5714540) 0 + +Class std::mutex + size=40 align=8 + base size=40 base align=8 +std::mutex (0x0x7f30c56bd5b0) 0 + std::__mutex_base (0x0x7f30c57145a0) 0 + +Class std::recursive_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_mutex (0x0x7f30c56bd618) 0 + std::__recursive_mutex_base (0x0x7f30c5714600) 0 + +Class std::timed_mutex + size=40 align=8 + base size=40 base align=8 +std::timed_mutex (0x0x7f30c57ba0e0) 0 + std::__mutex_base (0x0x7f30c5714720) 0 + std::__timed_mutex_impl (0x0x7f30c5714780) 0 empty + +Class std::recursive_timed_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_timed_mutex (0x0x7f30c57baa80) 0 + std::__recursive_mutex_base (0x0x7f30c5714840) 0 + std::__timed_mutex_impl (0x0x7f30c57148a0) 0 empty + +Class std::defer_lock_t + size=1 align=1 + base size=0 base align=1 +std::defer_lock_t (0x0x7f30c5714900) 0 empty + +Class std::try_to_lock_t + size=1 align=1 + base size=0 base align=1 +std::try_to_lock_t (0x0x7f30c5714960) 0 empty + +Class std::adopt_lock_t + size=1 align=1 + base size=0 base align=1 +std::adopt_lock_t (0x0x7f30c57149c0) 0 empty + +Class std::once_flag + size=4 align=4 + base size=4 base align=4 +std::once_flag (0x0x7f30c5714c00) 0 + +Vtable for __gnu_cxx::__concurrence_lock_error +__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what + +Class __gnu_cxx::__concurrence_lock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_lock_error (0x0x7f30c56bd750) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16u) + std::exception (0x0x7f30c5714cc0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_lock_error (0x0x7f30c56bd750) + +Vtable for __gnu_cxx::__concurrence_unlock_error +__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what + +Class __gnu_cxx::__concurrence_unlock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_unlock_error (0x0x7f30c56bd7b8) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16u) + std::exception (0x0x7f30c5714d80) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7f30c56bd7b8) + +Vtable for __gnu_cxx::__concurrence_broadcast_error +__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what + +Class __gnu_cxx::__concurrence_broadcast_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_broadcast_error (0x0x7f30c56bd820) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16u) + std::exception (0x0x7f30c5714e40) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7f30c56bd820) + +Vtable for __gnu_cxx::__concurrence_wait_error +__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what + +Class __gnu_cxx::__concurrence_wait_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_wait_error (0x0x7f30c56bd8f0) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16u) + std::exception (0x0x7f30c5714f00) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_wait_error (0x0x7f30c56bd8f0) + +Class __gnu_cxx::__mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__mutex (0x0x7f30c5450000) 0 + +Class __gnu_cxx::__recursive_mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__recursive_mutex (0x0x7f30c5450060) 0 + +Class __gnu_cxx::__scoped_lock + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__scoped_lock (0x0x7f30c54500c0) 0 + +Class __gnu_cxx::__cond + size=48 align=8 + base size=48 base align=8 +__gnu_cxx::__cond (0x0x7f30c5450120) 0 + +Vtable for std::bad_weak_ptr +std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12bad_weak_ptr) +16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +32 (int (*)(...))std::bad_weak_ptr::what + +Class std::bad_weak_ptr + size=8 align=8 + base size=8 base align=8 +std::bad_weak_ptr (0x0x7f30c56bdbc8) 0 nearly-empty + vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16u) + std::exception (0x0x7f30c5450480) 0 nearly-empty + primary-for std::bad_weak_ptr (0x0x7f30c56bdbc8) + +Class std::_Sp_make_shared_tag + size=1 align=1 + base size=0 base align=1 +std::_Sp_make_shared_tag (0x0x7f30c5450cc0) 0 empty + +Class std::_Sp_locker + size=2 align=1 + base size=2 base align=1 +std::_Sp_locker (0x0x7f30c55e64e0) 0 + +Class std::thread::id + size=8 align=8 + base size=8 base align=8 +std::thread::id (0x0x7f30c55e66c0) 0 + +Vtable for std::thread::_Impl_base +std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6thread10_Impl_baseE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class std::thread::_Impl_base + size=24 align=8 + base size=24 base align=8 +std::thread::_Impl_base (0x0x7f30c55e6720) 0 + vptr=((& std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE) + 16u) + +Class std::thread + size=8 align=8 + base size=8 base align=8 +std::thread (0x0x7f30c55e6660) 0 + +Class std::condition_variable + size=48 align=8 + base size=48 base align=8 +std::condition_variable (0x0x7f30c53ef360) 0 + +Class std::__at_thread_exit_elt + size=16 align=8 + base size=16 base align=8 +std::__at_thread_exit_elt (0x0x7f30c53ef420) 0 + +Class std::_V2::condition_variable_any + size=64 align=8 + base size=64 base align=8 +std::_V2::condition_variable_any (0x0x7f30c53ef480) 0 + +Class std::__atomic_futex_unsigned_base + size=1 align=1 + base size=0 base align=1 +std::__atomic_futex_unsigned_base (0x0x7f30c508fae0) 0 empty + +Vtable for std::future_error +std::future_error::_ZTVSt12future_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12future_error) +16 (int (*)(...))std::future_error::~future_error +24 (int (*)(...))std::future_error::~future_error +32 (int (*)(...))std::future_error::what + +Class std::future_error + size=32 align=8 + base size=32 base align=8 +std::future_error (0x0x7f30c5091f08) 0 + vptr=((& std::future_error::_ZTVSt12future_error) + 16u) + std::logic_error (0x0x7f30c5091f70) 0 + primary-for std::future_error (0x0x7f30c5091f08) + std::exception (0x0x7f30c508fc00) 0 nearly-empty + primary-for std::logic_error (0x0x7f30c5091f70) + +Class std::__future_base::_Result_base::_Deleter + size=1 align=1 + base size=0 base align=1 +std::__future_base::_Result_base::_Deleter (0x0x7f30c508fd20) 0 empty + +Vtable for std::__future_base::_Result_base +std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class std::__future_base::_Result_base + size=16 align=8 + base size=16 base align=8 +std::__future_base::_Result_base (0x0x7f30c508fcc0) 0 + vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16u) + +Class std::__future_base::_State_baseV2::__exception_ptr_tag + size=1 align=1 + base size=0 base align=1 +std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7f30c4e252a0) 0 empty + +Class std::__future_base::_State_baseV2::_Make_ready + size=32 align=8 + base size=32 base align=8 +std::__future_base::_State_baseV2::_Make_ready (0x0x7f30c4e21548) 0 + std::__at_thread_exit_elt (0x0x7f30c4e25360) 0 + +Vtable for std::__future_base::_State_baseV2 +std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E) +16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_State_baseV2 + size=32 align=8 + base size=28 base align=8 +std::__future_base::_State_baseV2 (0x0x7f30c508fea0) 0 + vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16u) + +Class std::__future_base + size=1 align=1 + base size=0 base align=1 +std::__future_base (0x0x7f30c508fc60) 0 empty + +Vtable for std::__future_base::_Async_state_commonV2 +std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E) +16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_Async_state_commonV2 + size=48 align=8 + base size=44 base align=8 +std::__future_base::_Async_state_commonV2 (0x0x7f30c4bc0138) 0 + vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16u) + std::__future_base::_State_baseV2 (0x0x7f30c4b9d240) 0 + primary-for std::__future_base::_Async_state_commonV2 (0x0x7f30c4bc0138) + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7f30c4b9d960) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7f30c4bc0bc8) 0 + vptr=((& QThread::_ZTV7QThread) + 16u) + QObject (0x0x7f30c4b9d900) 0 + primary-for QThread (0x0x7f30c4bc0bc8) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7f30c4b9da80) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7f30c4bc0c30) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u) + QObject (0x0x7f30c4b9da20) 0 + primary-for QThreadPool (0x0x7f30c4bc0c30) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7f30c4b9dae0) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7f30c4b9dc00) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7f30c4bc0c98) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u) + QObject (0x0x7f30c4b9dba0) 0 + primary-for QTimeLine (0x0x7f30c4bc0c98) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7f30c4b9dcc0) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7f30c4bc0d00) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16u) + QObject (0x0x7f30c4b9dc60) 0 + primary-for QTimer (0x0x7f30c4bc0d00) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7f30c488b420) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7f30c488b3c0) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7f30c488b9c0) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7f30c4887888) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16u) + QObject (0x0x7f30c488b960) 0 + primary-for QTranslator (0x0x7f30c4887888) + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7f30c488ba20) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7f30c490e0c0) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7f30c490e120) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7f30c490e3c0) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7f30c49435b0) 0 + QVector (0x0x7f30c490e780) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7f30c490e7e0) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7f30c490ea80) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7f30c490ed20) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7f30c4622000) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7f30c4622060) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7f30c4622a80) 0 + +Class QNetworkRequest + size=8 align=8 + base size=8 base align=8 +QNetworkRequest (0x0x7f30c4622ba0) 0 + +Class QNetworkCacheMetaData + size=8 align=8 + base size=8 base align=8 +QNetworkCacheMetaData (0x0x7f30c46cf120) 0 + +Class QAbstractNetworkCache::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractNetworkCache::QPrivateSignal (0x0x7f30c46cf7e0) 0 empty + +Vtable for QAbstractNetworkCache +QAbstractNetworkCache::_ZTV21QAbstractNetworkCache: 22u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QAbstractNetworkCache) +16 (int (*)(...))QAbstractNetworkCache::metaObject +24 (int (*)(...))QAbstractNetworkCache::qt_metacast +32 (int (*)(...))QAbstractNetworkCache::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNetworkCache + size=16 align=8 + base size=16 base align=8 +QAbstractNetworkCache (0x0x7f30c464ee38) 0 + vptr=((& QAbstractNetworkCache::_ZTV21QAbstractNetworkCache) + 16u) + QObject (0x0x7f30c46cf780) 0 + primary-for QAbstractNetworkCache (0x0x7f30c464ee38) + +Class QAbstractSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractSocket::QPrivateSignal (0x0x7f30c46cf8a0) 0 empty + +Vtable for QAbstractSocket +QAbstractSocket::_ZTV15QAbstractSocket: 41u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAbstractSocket) +16 (int (*)(...))QAbstractSocket::metaObject +24 (int (*)(...))QAbstractSocket::qt_metacast +32 (int (*)(...))QAbstractSocket::qt_metacall +40 (int (*)(...))QAbstractSocket::~QAbstractSocket +48 (int (*)(...))QAbstractSocket::~QAbstractSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QAbstractSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QAbstractSocket::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::writeData +240 (int (*)(...))QAbstractSocket::resume +248 (int (*)(...))QAbstractSocket::connectToHost +256 (int (*)(...))QAbstractSocket::connectToHost +264 (int (*)(...))QAbstractSocket::disconnectFromHost +272 (int (*)(...))QAbstractSocket::setReadBufferSize +280 (int (*)(...))QAbstractSocket::socketDescriptor +288 (int (*)(...))QAbstractSocket::setSocketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketOption +304 (int (*)(...))QAbstractSocket::socketOption +312 (int (*)(...))QAbstractSocket::waitForConnected +320 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QAbstractSocket + size=16 align=8 + base size=16 base align=8 +QAbstractSocket (0x0x7f30c464eea0) 0 + vptr=((& QAbstractSocket::_ZTV15QAbstractSocket) + 16u) + QIODevice (0x0x7f30c464ef08) 0 + primary-for QAbstractSocket (0x0x7f30c464eea0) + QObject (0x0x7f30c46cf840) 0 + primary-for QIODevice (0x0x7f30c464ef08) + +Class QAuthenticator + size=8 align=8 + base size=8 base align=8 +QAuthenticator (0x0x7f30c46cfe40) 0 + +Class QDnsDomainNameRecord + size=8 align=8 + base size=8 base align=8 +QDnsDomainNameRecord (0x0x7f30c46cfea0) 0 + +Class QDnsHostAddressRecord + size=8 align=8 + base size=8 base align=8 +QDnsHostAddressRecord (0x0x7f30c47c71e0) 0 + +Class QDnsMailExchangeRecord + size=8 align=8 + base size=8 base align=8 +QDnsMailExchangeRecord (0x0x7f30c47c74e0) 0 + +Class QDnsServiceRecord + size=8 align=8 + base size=8 base align=8 +QDnsServiceRecord (0x0x7f30c47c77e0) 0 + +Class QDnsTextRecord + size=8 align=8 + base size=8 base align=8 +QDnsTextRecord (0x0x7f30c47c7ae0) 0 + +Class QDnsLookup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDnsLookup::QPrivateSignal (0x0x7f30c47c7e40) 0 empty + +Vtable for QDnsLookup +QDnsLookup::_ZTV10QDnsLookup: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QDnsLookup) +16 (int (*)(...))QDnsLookup::metaObject +24 (int (*)(...))QDnsLookup::qt_metacast +32 (int (*)(...))QDnsLookup::qt_metacall +40 (int (*)(...))QDnsLookup::~QDnsLookup +48 (int (*)(...))QDnsLookup::~QDnsLookup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDnsLookup + size=16 align=8 + base size=16 base align=8 +QDnsLookup (0x0x7f30c4745958) 0 + vptr=((& QDnsLookup::_ZTV10QDnsLookup) + 16u) + QObject (0x0x7f30c47c7de0) 0 + primary-for QDnsLookup (0x0x7f30c4745958) + +Class QTcpSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTcpSocket::QPrivateSignal (0x0x7f30c47c7f00) 0 empty + +Vtable for QTcpSocket +QTcpSocket::_ZTV10QTcpSocket: 41u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTcpSocket) +16 (int (*)(...))QTcpSocket::metaObject +24 (int (*)(...))QTcpSocket::qt_metacast +32 (int (*)(...))QTcpSocket::qt_metacall +40 (int (*)(...))QTcpSocket::~QTcpSocket +48 (int (*)(...))QTcpSocket::~QTcpSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QAbstractSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QAbstractSocket::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::writeData +240 (int (*)(...))QAbstractSocket::resume +248 (int (*)(...))QAbstractSocket::connectToHost +256 (int (*)(...))QAbstractSocket::connectToHost +264 (int (*)(...))QAbstractSocket::disconnectFromHost +272 (int (*)(...))QAbstractSocket::setReadBufferSize +280 (int (*)(...))QAbstractSocket::socketDescriptor +288 (int (*)(...))QAbstractSocket::setSocketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketOption +304 (int (*)(...))QAbstractSocket::socketOption +312 (int (*)(...))QAbstractSocket::waitForConnected +320 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QTcpSocket + size=16 align=8 + base size=16 base align=8 +QTcpSocket (0x0x7f30c47459c0) 0 + vptr=((& QTcpSocket::_ZTV10QTcpSocket) + 16u) + QAbstractSocket (0x0x7f30c4745a28) 0 + primary-for QTcpSocket (0x0x7f30c47459c0) + QIODevice (0x0x7f30c4745a90) 0 + primary-for QAbstractSocket (0x0x7f30c4745a28) + QObject (0x0x7f30c47c7ea0) 0 + primary-for QIODevice (0x0x7f30c4745a90) + +Class QSslCertificate + size=8 align=8 + base size=8 base align=8 +QSslCertificate (0x0x7f30c4464120) 0 + +Class QSslError + size=8 align=8 + base size=8 base align=8 +QSslError (0x0x7f30c4464540) 0 + +Class QSslSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSslSocket::QPrivateSignal (0x0x7f30c4464ea0) 0 empty + +Vtable for QSslSocket +QSslSocket::_ZTV10QSslSocket: 41u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QSslSocket) +16 (int (*)(...))QSslSocket::metaObject +24 (int (*)(...))QSslSocket::qt_metacast +32 (int (*)(...))QSslSocket::qt_metacall +40 (int (*)(...))QSslSocket::~QSslSocket +48 (int (*)(...))QSslSocket::~QSslSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QSslSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QSslSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QSslSocket::bytesAvailable +184 (int (*)(...))QSslSocket::bytesToWrite +192 (int (*)(...))QSslSocket::canReadLine +200 (int (*)(...))QSslSocket::waitForReadyRead +208 (int (*)(...))QSslSocket::waitForBytesWritten +216 (int (*)(...))QSslSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QSslSocket::writeData +240 (int (*)(...))QSslSocket::resume +248 (int (*)(...))QSslSocket::connectToHost +256 (int (*)(...))QAbstractSocket::connectToHost +264 (int (*)(...))QSslSocket::disconnectFromHost +272 (int (*)(...))QSslSocket::setReadBufferSize +280 (int (*)(...))QAbstractSocket::socketDescriptor +288 (int (*)(...))QSslSocket::setSocketDescriptor +296 (int (*)(...))QSslSocket::setSocketOption +304 (int (*)(...))QSslSocket::socketOption +312 (int (*)(...))QSslSocket::waitForConnected +320 (int (*)(...))QSslSocket::waitForDisconnected + +Class QSslSocket + size=16 align=8 + base size=16 base align=8 +QSslSocket (0x0x7f30c44e0478) 0 + vptr=((& QSslSocket::_ZTV10QSslSocket) + 16u) + QTcpSocket (0x0x7f30c44e04e0) 0 + primary-for QSslSocket (0x0x7f30c44e0478) + QAbstractSocket (0x0x7f30c44e0548) 0 + primary-for QTcpSocket (0x0x7f30c44e04e0) + QIODevice (0x0x7f30c44e05b0) 0 + primary-for QAbstractSocket (0x0x7f30c44e0548) + QObject (0x0x7f30c4464e40) 0 + primary-for QIODevice (0x0x7f30c44e05b0) + +Class QDtlsClientVerifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDtlsClientVerifier::QPrivateSignal (0x0x7f30c4464f60) 0 empty + +Class QDtlsClientVerifier::GeneratorParameters + size=16 align=8 + base size=16 base align=8 +QDtlsClientVerifier::GeneratorParameters (0x0x7f30c454b000) 0 + +Vtable for QDtlsClientVerifier +QDtlsClientVerifier::_ZTV19QDtlsClientVerifier: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QDtlsClientVerifier) +16 (int (*)(...))QDtlsClientVerifier::metaObject +24 (int (*)(...))QDtlsClientVerifier::qt_metacast +32 (int (*)(...))QDtlsClientVerifier::qt_metacall +40 (int (*)(...))QDtlsClientVerifier::~QDtlsClientVerifier +48 (int (*)(...))QDtlsClientVerifier::~QDtlsClientVerifier +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDtlsClientVerifier + size=16 align=8 + base size=16 base align=8 +QDtlsClientVerifier (0x0x7f30c44e0618) 0 + vptr=((& QDtlsClientVerifier::_ZTV19QDtlsClientVerifier) + 16u) + QObject (0x0x7f30c4464f00) 0 + primary-for QDtlsClientVerifier (0x0x7f30c44e0618) + +Class QDtls::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDtls::QPrivateSignal (0x0x7f30c454b0c0) 0 empty + +Vtable for QDtls +QDtls::_ZTV5QDtls: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QDtls) +16 (int (*)(...))QDtls::metaObject +24 (int (*)(...))QDtls::qt_metacast +32 (int (*)(...))QDtls::qt_metacall +40 (int (*)(...))QDtls::~QDtls +48 (int (*)(...))QDtls::~QDtls +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDtls + size=16 align=8 + base size=16 base align=8 +QDtls (0x0x7f30c44e0680) 0 + vptr=((& QDtls::_ZTV5QDtls) + 16u) + QObject (0x0x7f30c454b060) 0 + primary-for QDtls (0x0x7f30c44e0680) + +Class QIPv6Address + size=16 align=1 + base size=16 base align=1 +QIPv6Address (0x0x7f30c454b180) 0 + +Class QHostAddress + size=8 align=8 + base size=8 base align=8 +QHostAddress (0x0x7f30c454b1e0) 0 + +Class QHostInfo + size=8 align=8 + base size=8 base align=8 +QHostInfo (0x0x7f30c454b9c0) 0 + +Class QHstsPolicy + size=8 align=8 + base size=8 base align=8 +QHstsPolicy (0x0x7f30c454bea0) 0 + +Class QHttpPart + size=8 align=8 + base size=8 base align=8 +QHttpPart (0x0x7f30c42266c0) 0 + +Class QHttpMultiPart::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHttpMultiPart::QPrivateSignal (0x0x7f30c4226a20) 0 empty + +Vtable for QHttpMultiPart +QHttpMultiPart::_ZTV14QHttpMultiPart: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QHttpMultiPart) +16 (int (*)(...))QHttpMultiPart::metaObject +24 (int (*)(...))QHttpMultiPart::qt_metacast +32 (int (*)(...))QHttpMultiPart::qt_metacall +40 (int (*)(...))QHttpMultiPart::~QHttpMultiPart +48 (int (*)(...))QHttpMultiPart::~QHttpMultiPart +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QHttpMultiPart + size=16 align=8 + base size=16 base align=8 +QHttpMultiPart (0x0x7f30c42028f0) 0 + vptr=((& QHttpMultiPart::_ZTV14QHttpMultiPart) + 16u) + QObject (0x0x7f30c42269c0) 0 + primary-for QHttpMultiPart (0x0x7f30c42028f0) + +Class QLocalServer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLocalServer::QPrivateSignal (0x0x7f30c4226ae0) 0 empty + +Vtable for QLocalServer +QLocalServer::_ZTV12QLocalServer: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QLocalServer) +16 (int (*)(...))QLocalServer::metaObject +24 (int (*)(...))QLocalServer::qt_metacast +32 (int (*)(...))QLocalServer::qt_metacall +40 (int (*)(...))QLocalServer::~QLocalServer +48 (int (*)(...))QLocalServer::~QLocalServer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLocalServer::hasPendingConnections +120 (int (*)(...))QLocalServer::nextPendingConnection +128 (int (*)(...))QLocalServer::incomingConnection + +Class QLocalServer + size=16 align=8 + base size=16 base align=8 +QLocalServer (0x0x7f30c4202958) 0 + vptr=((& QLocalServer::_ZTV12QLocalServer) + 16u) + QObject (0x0x7f30c4226a80) 0 + primary-for QLocalServer (0x0x7f30c4202958) + +Class QLocalSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLocalSocket::QPrivateSignal (0x0x7f30c4226d20) 0 empty + +Vtable for QLocalSocket +QLocalSocket::_ZTV12QLocalSocket: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QLocalSocket) +16 (int (*)(...))QLocalSocket::metaObject +24 (int (*)(...))QLocalSocket::qt_metacast +32 (int (*)(...))QLocalSocket::qt_metacall +40 (int (*)(...))QLocalSocket::~QLocalSocket +48 (int (*)(...))QLocalSocket::~QLocalSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLocalSocket::isSequential +120 (int (*)(...))QLocalSocket::open +128 (int (*)(...))QLocalSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QLocalSocket::bytesAvailable +184 (int (*)(...))QLocalSocket::bytesToWrite +192 (int (*)(...))QLocalSocket::canReadLine +200 (int (*)(...))QLocalSocket::waitForReadyRead +208 (int (*)(...))QLocalSocket::waitForBytesWritten +216 (int (*)(...))QLocalSocket::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QLocalSocket::writeData + +Class QLocalSocket + size=16 align=8 + base size=16 base align=8 +QLocalSocket (0x0x7f30c4202af8) 0 + vptr=((& QLocalSocket::_ZTV12QLocalSocket) + 16u) + QIODevice (0x0x7f30c4202b60) 0 + primary-for QLocalSocket (0x0x7f30c4202af8) + QObject (0x0x7f30c4226cc0) 0 + primary-for QIODevice (0x0x7f30c4202b60) + +Class QSslConfiguration + size=8 align=8 + base size=8 base align=8 +QSslConfiguration (0x0x7f30c4226d80) 0 + +Class QSslPreSharedKeyAuthenticator + size=8 align=8 + base size=8 base align=8 +QSslPreSharedKeyAuthenticator (0x0x7f30c432c5a0) 0 + +Class QNetworkAccessManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkAccessManager::QPrivateSignal (0x0x7f30c432cea0) 0 empty + +Vtable for QNetworkAccessManager +QNetworkAccessManager::_ZTV21QNetworkAccessManager: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QNetworkAccessManager) +16 (int (*)(...))QNetworkAccessManager::metaObject +24 (int (*)(...))QNetworkAccessManager::qt_metacast +32 (int (*)(...))QNetworkAccessManager::qt_metacall +40 (int (*)(...))QNetworkAccessManager::~QNetworkAccessManager +48 (int (*)(...))QNetworkAccessManager::~QNetworkAccessManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkAccessManager::createRequest + +Class QNetworkAccessManager + size=16 align=8 + base size=16 base align=8 +QNetworkAccessManager (0x0x7f30c4332820) 0 + vptr=((& QNetworkAccessManager::_ZTV21QNetworkAccessManager) + 16u) + QObject (0x0x7f30c432ce40) 0 + primary-for QNetworkAccessManager (0x0x7f30c4332820) + +Class QNetworkConfiguration + size=8 align=8 + base size=8 base align=8 +QNetworkConfiguration (0x0x7f30c432cf00) 0 + +Class QNetworkConfigurationManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkConfigurationManager::QPrivateSignal (0x0x7f30c43b33c0) 0 empty + +Vtable for QNetworkConfigurationManager +QNetworkConfigurationManager::_ZTV28QNetworkConfigurationManager: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QNetworkConfigurationManager) +16 (int (*)(...))QNetworkConfigurationManager::metaObject +24 (int (*)(...))QNetworkConfigurationManager::qt_metacast +32 (int (*)(...))QNetworkConfigurationManager::qt_metacall +40 (int (*)(...))QNetworkConfigurationManager::~QNetworkConfigurationManager +48 (int (*)(...))QNetworkConfigurationManager::~QNetworkConfigurationManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QNetworkConfigurationManager + size=16 align=8 + base size=16 base align=8 +QNetworkConfigurationManager (0x0x7f30c4332a28) 0 + vptr=((& QNetworkConfigurationManager::_ZTV28QNetworkConfigurationManager) + 16u) + QObject (0x0x7f30c43b3360) 0 + primary-for QNetworkConfigurationManager (0x0x7f30c4332a28) + +Class QNetworkCookie + size=8 align=8 + base size=8 base align=8 +QNetworkCookie (0x0x7f30c43b3720) 0 + +Class QNetworkCookieJar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkCookieJar::QPrivateSignal (0x0x7f30c43b3f00) 0 empty + +Vtable for QNetworkCookieJar +QNetworkCookieJar::_ZTV17QNetworkCookieJar: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QNetworkCookieJar) +16 (int (*)(...))QNetworkCookieJar::metaObject +24 (int (*)(...))QNetworkCookieJar::qt_metacast +32 (int (*)(...))QNetworkCookieJar::qt_metacall +40 (int (*)(...))QNetworkCookieJar::~QNetworkCookieJar +48 (int (*)(...))QNetworkCookieJar::~QNetworkCookieJar +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkCookieJar::cookiesForUrl +120 (int (*)(...))QNetworkCookieJar::setCookiesFromUrl +128 (int (*)(...))QNetworkCookieJar::insertCookie +136 (int (*)(...))QNetworkCookieJar::updateCookie +144 (int (*)(...))QNetworkCookieJar::deleteCookie +152 (int (*)(...))QNetworkCookieJar::validateCookie + +Class QNetworkCookieJar + size=16 align=8 + base size=16 base align=8 +QNetworkCookieJar (0x0x7f30c4037270) 0 + vptr=((& QNetworkCookieJar::_ZTV17QNetworkCookieJar) + 16u) + QObject (0x0x7f30c43b3ea0) 0 + primary-for QNetworkCookieJar (0x0x7f30c4037270) + +Class QNetworkDatagram + size=8 align=8 + base size=8 base align=8 +QNetworkDatagram (0x0x7f30c43b3f60) 0 + +Class QNetworkDiskCache::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkDiskCache::QPrivateSignal (0x0x7f30c40bff60) 0 empty + +Vtable for QNetworkDiskCache +QNetworkDiskCache::_ZTV17QNetworkDiskCache: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QNetworkDiskCache) +16 (int (*)(...))QNetworkDiskCache::metaObject +24 (int (*)(...))QNetworkDiskCache::qt_metacast +32 (int (*)(...))QNetworkDiskCache::qt_metacall +40 (int (*)(...))QNetworkDiskCache::~QNetworkDiskCache +48 (int (*)(...))QNetworkDiskCache::~QNetworkDiskCache +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkDiskCache::metaData +120 (int (*)(...))QNetworkDiskCache::updateMetaData +128 (int (*)(...))QNetworkDiskCache::data +136 (int (*)(...))QNetworkDiskCache::remove +144 (int (*)(...))QNetworkDiskCache::cacheSize +152 (int (*)(...))QNetworkDiskCache::prepare +160 (int (*)(...))QNetworkDiskCache::insert +168 (int (*)(...))QNetworkDiskCache::clear +176 (int (*)(...))QNetworkDiskCache::expire + +Class QNetworkDiskCache + size=16 align=8 + base size=16 base align=8 +QNetworkDiskCache (0x0x7f30c40d5c98) 0 + vptr=((& QNetworkDiskCache::_ZTV17QNetworkDiskCache) + 16u) + QAbstractNetworkCache (0x0x7f30c40d5d00) 0 + primary-for QNetworkDiskCache (0x0x7f30c40d5c98) + QObject (0x0x7f30c40bff00) 0 + primary-for QAbstractNetworkCache (0x0x7f30c40d5d00) + +Class QNetworkAddressEntry + size=8 align=8 + base size=8 base align=8 +QNetworkAddressEntry (0x0x7f30c4103000) 0 + +Class QNetworkInterface + size=8 align=8 + base size=8 base align=8 +QNetworkInterface (0x0x7f30c41036c0) 0 + +Class QNetworkProxyQuery + size=8 align=8 + base size=8 base align=8 +QNetworkProxyQuery (0x0x7f30c4103d80) 0 + +Class QNetworkProxy + size=8 align=8 + base size=8 base align=8 +QNetworkProxy (0x0x7f30c41b6420) 0 + +Vtable for QNetworkProxyFactory +QNetworkProxyFactory::_ZTV20QNetworkProxyFactory: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QNetworkProxyFactory) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QNetworkProxyFactory + size=8 align=8 + base size=8 base align=8 +QNetworkProxyFactory (0x0x7f30c41b6c00) 0 nearly-empty + vptr=((& QNetworkProxyFactory::_ZTV20QNetworkProxyFactory) + 16u) + +Class QNetworkReply::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkReply::QPrivateSignal (0x0x7f30c41b6de0) 0 empty + +Vtable for QNetworkReply +QNetworkReply::_ZTV13QNetworkReply: 36u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QNetworkReply) +16 (int (*)(...))QNetworkReply::metaObject +24 (int (*)(...))QNetworkReply::qt_metacast +32 (int (*)(...))QNetworkReply::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QNetworkReply::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QNetworkReply::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QNetworkReply::writeData +240 (int (*)(...))QNetworkReply::setReadBufferSize +248 (int (*)(...))__cxa_pure_virtual +256 (int (*)(...))QNetworkReply::ignoreSslErrors +264 (int (*)(...))QNetworkReply::sslConfigurationImplementation +272 (int (*)(...))QNetworkReply::setSslConfigurationImplementation +280 (int (*)(...))QNetworkReply::ignoreSslErrorsImplementation + +Class QNetworkReply + size=16 align=8 + base size=16 base align=8 +QNetworkReply (0x0x7f30c3de83a8) 0 + vptr=((& QNetworkReply::_ZTV13QNetworkReply) + 16u) + QIODevice (0x0x7f30c3de8410) 0 + primary-for QNetworkReply (0x0x7f30c3de83a8) + QObject (0x0x7f30c41b6d80) 0 + primary-for QIODevice (0x0x7f30c3de8410) + +Class QNetworkSession::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QNetworkSession::QPrivateSignal (0x0x7f30c3e52000) 0 empty + +Vtable for QNetworkSession +QNetworkSession::_ZTV15QNetworkSession: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QNetworkSession) +16 (int (*)(...))QNetworkSession::metaObject +24 (int (*)(...))QNetworkSession::qt_metacast +32 (int (*)(...))QNetworkSession::qt_metacall +40 (int (*)(...))QNetworkSession::~QNetworkSession +48 (int (*)(...))QNetworkSession::~QNetworkSession +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QNetworkSession::connectNotify +104 (int (*)(...))QNetworkSession::disconnectNotify + +Class QNetworkSession + size=24 align=8 + base size=24 base align=8 +QNetworkSession (0x0x7f30c3de8478) 0 + vptr=((& QNetworkSession::_ZTV15QNetworkSession) + 16u) + QObject (0x0x7f30c41b6f60) 0 + primary-for QNetworkSession (0x0x7f30c3de8478) + +Class QTcpServer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTcpServer::QPrivateSignal (0x0x7f30c3e525a0) 0 empty + +Vtable for QTcpServer +QTcpServer::_ZTV10QTcpServer: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTcpServer) +16 (int (*)(...))QTcpServer::metaObject +24 (int (*)(...))QTcpServer::qt_metacast +32 (int (*)(...))QTcpServer::qt_metacall +40 (int (*)(...))QTcpServer::~QTcpServer +48 (int (*)(...))QTcpServer::~QTcpServer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTcpServer::hasPendingConnections +120 (int (*)(...))QTcpServer::nextPendingConnection +128 (int (*)(...))QTcpServer::incomingConnection + +Class QTcpServer + size=16 align=8 + base size=16 base align=8 +QTcpServer (0x0x7f30c3de85b0) 0 + vptr=((& QTcpServer::_ZTV10QTcpServer) + 16u) + QObject (0x0x7f30c3e52540) 0 + primary-for QTcpServer (0x0x7f30c3de85b0) + +Class QSslCertificateExtension + size=8 align=8 + base size=8 base align=8 +QSslCertificateExtension (0x0x7f30c3e52600) 0 + +Class QSslCipher + size=8 align=8 + base size=8 base align=8 +QSslCipher (0x0x7f30c3e52900) 0 + +Class QSslDiffieHellmanParameters + size=8 align=8 + base size=8 base align=8 +QSslDiffieHellmanParameters (0x0x7f30c3eef120) 0 + +Class QSslEllipticCurve + size=4 align=4 + base size=4 base align=4 +QSslEllipticCurve (0x0x7f30c3f5cc00) 0 + +Class QSslKey + size=8 align=8 + base size=8 base align=8 +QSslKey (0x0x7f30c3f95360) 0 + +Class QUdpSocket::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QUdpSocket::QPrivateSignal (0x0x7f30c3f956c0) 0 empty + +Vtable for QUdpSocket +QUdpSocket::_ZTV10QUdpSocket: 41u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QUdpSocket) +16 (int (*)(...))QUdpSocket::metaObject +24 (int (*)(...))QUdpSocket::qt_metacast +32 (int (*)(...))QUdpSocket::qt_metacall +40 (int (*)(...))QUdpSocket::~QUdpSocket +48 (int (*)(...))QUdpSocket::~QUdpSocket +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractSocket::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QAbstractSocket::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QAbstractSocket::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QAbstractSocket::bytesAvailable +184 (int (*)(...))QAbstractSocket::bytesToWrite +192 (int (*)(...))QAbstractSocket::canReadLine +200 (int (*)(...))QAbstractSocket::waitForReadyRead +208 (int (*)(...))QAbstractSocket::waitForBytesWritten +216 (int (*)(...))QAbstractSocket::readData +224 (int (*)(...))QAbstractSocket::readLineData +232 (int (*)(...))QAbstractSocket::writeData +240 (int (*)(...))QAbstractSocket::resume +248 (int (*)(...))QAbstractSocket::connectToHost +256 (int (*)(...))QAbstractSocket::connectToHost +264 (int (*)(...))QAbstractSocket::disconnectFromHost +272 (int (*)(...))QAbstractSocket::setReadBufferSize +280 (int (*)(...))QAbstractSocket::socketDescriptor +288 (int (*)(...))QAbstractSocket::setSocketDescriptor +296 (int (*)(...))QAbstractSocket::setSocketOption +304 (int (*)(...))QAbstractSocket::socketOption +312 (int (*)(...))QAbstractSocket::waitForConnected +320 (int (*)(...))QAbstractSocket::waitForDisconnected + +Class QUdpSocket + size=16 align=8 + base size=16 base align=8 +QUdpSocket (0x0x7f30c3f78b60) 0 + vptr=((& QUdpSocket::_ZTV10QUdpSocket) + 16u) + QAbstractSocket (0x0x7f30c3f78bc8) 0 + primary-for QUdpSocket (0x0x7f30c3f78b60) + QIODevice (0x0x7f30c3f78c30) 0 + primary-for QAbstractSocket (0x0x7f30c3f78bc8) + QObject (0x0x7f30c3f95660) 0 + primary-for QIODevice (0x0x7f30c3f78c30) + diff --git a/tests/auto/bic/data/QtOpenGL.5.12.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtOpenGL.5.12.0.linux-gcc-amd64.txt new file mode 100644 index 0000000000..8f5c846b41 --- /dev/null +++ b/tests/auto/bic/data/QtOpenGL.5.12.0.linux-gcc-amd64.txt @@ -0,0 +1,19441 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7ff86ee43600) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7ff86ee92d80) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7ff86eebc000) 0 empty + +Class std::__do_is_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_default_constructible_impl (0x0x7ff86eebc240) 0 empty + +Class std::__do_is_static_castable_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_static_castable_impl (0x0x7ff86eebc480) 0 empty + +Class std::__do_is_direct_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_direct_constructible_impl (0x0x7ff86eebc600) 0 empty + +Class std::__do_is_nary_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nary_constructible_impl (0x0x7ff86eebc9c0) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7ff86ef77180) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7ff86ef77240) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7ff86ef775a0) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7ff86ef77660) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7ff86ef77720) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7ff86ef777e0) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7ff86ef77a80) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7ff86ef77c60) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7ff86eafa120) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7ff86eafa180) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7ff86eb2ede0) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7ff86eb2ee40) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7ff86ef2ba90) 0 empty + std::input_iterator_tag (0x0x7ff86eb2eea0) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7ff86ef2baf8) 0 empty + std::forward_iterator_tag (0x0x7ff86ef2bb60) 0 empty + std::input_iterator_tag (0x0x7ff86eb2ef00) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7ff86ef2bbc8) 0 empty + std::bidirectional_iterator_tag (0x0x7ff86ef2bc30) 0 empty + std::forward_iterator_tag (0x0x7ff86ef2bc98) 0 empty + std::input_iterator_tag (0x0x7ff86eb2ef60) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7ff86eb5ac00) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7ff86eb5ac60) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7ff86eb5acc0) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7ff86eb5ad20) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7ff86eb5ad80) 0 empty + +Class wait + size=4 align=4 + base size=4 base align=4 +wait (0x0x7ff86ec358a0) 0 + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7ff86ec35ae0) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7ff86ec35ba0) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7ff86ec35c00) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7ff86ec35cc0) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7ff86ec35d20) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7ff86e8d41e0) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7ff86e8d4240) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7ff86e8d42a0) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16u) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7ff86ebad208) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u) + std::exception (0x0x7ff86e8d4300) 0 nearly-empty + primary-for std::bad_exception (0x0x7ff86ebad208) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7ff86e8d4360) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7ff86e8d43c0) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16u) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7ff86ebad410) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u) + std::exception (0x0x7ff86e8d47e0) 0 nearly-empty + primary-for std::bad_alloc (0x0x7ff86ebad410) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7ff86ebad478) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16u) + std::bad_alloc (0x0x7ff86ebad4e0) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7ff86ebad478) + std::exception (0x0x7ff86e8d4840) 0 nearly-empty + primary-for std::bad_alloc (0x0x7ff86ebad4e0) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7ff86e8d48a0) 0 empty + +Class __exception + size=40 align=8 + base size=40 base align=8 +__exception (0x0x7ff86ea504e0) 0 + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7ff86e86d1e0) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7ff86e86d240) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7ff86e517120) 0 + +Class __sched_param + size=4 align=4 + base size=4 base align=4 +__sched_param (0x0x7ff86e517180) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7ff86e517240) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7ff86e5172a0) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7ff86e517300) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7ff86e517360) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7ff86e517480) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7ff86e5174e0) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7ff86e517900) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7ff86e517960) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7ff86e448180) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7ff86e4481e0) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7ff86e127180) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7ff86e127f60) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7ff86dec70d0) 0 + std::iterator (0x0x7ff86df4c060) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7ff86dec7138) 0 + std::_Bit_iterator_base (0x0x7ff86dec71a0) 0 + std::iterator (0x0x7ff86df4c0c0) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7ff86dec7208) 0 + std::_Bit_iterator_base (0x0x7ff86dec7270) 0 + std::iterator (0x0x7ff86df4c120) 0 empty + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7ff86df4cf00) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7ff86dd1dcc0) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7ff86dd1dc60) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7ff86de62c60) 0 + +Class qIsNull(double)::U + size=8 align=8 + base size=8 base align=8 +qIsNull(double)::U (0x0x7ff86c6e5780) 0 + +Class qIsNull(float)::U + size=4 align=4 + base size=4 base align=4 +qIsNull(float)::U (0x0x7ff86c6e57e0) 0 + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7ff86c7c72a0) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7ff86c7c7300) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7ff86c7c7360) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7ff86c7c73c0) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7ff86c7c7660) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7ff86c7c7ba0) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7ff86c81d138) 0 + std::__atomic_flag_base (0x0x7ff86c7c7c00) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7ff86c81d888) 0 + QAtomicInteger (0x0x7ff86c81d8f0) 0 + QBasicAtomicInteger (0x0x7ff86c37d360) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7ff86becb900) 0 empty + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7ff86c05dae0) 0 + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7ff86c05dc00) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7ff86c05f4e0) 0 + QGenericArgument (0x0x7ff86c05dc60) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7ff86c05dde0) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7ff86c05dea0) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7ff86bd18f00) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7ff86bd18f60) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7ff86bdc4240) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7ff86bdc42a0) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7ff86bdc4600) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7ff86bdc4660) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7ff86bdc46c0) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7ff86bdc4720) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7ff86bdc4780) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7ff86bdc4b40) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7ff86be0daf8) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16u) + std::exception (0x0x7ff86bdc4c00) 0 nearly-empty + primary-for std::logic_error (0x0x7ff86be0daf8) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7ff86be0db60) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16u) + std::logic_error (0x0x7ff86be0dbc8) 0 + primary-for std::domain_error (0x0x7ff86be0db60) + std::exception (0x0x7ff86bdc4c60) 0 nearly-empty + primary-for std::logic_error (0x0x7ff86be0dbc8) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7ff86be0dc30) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16u) + std::logic_error (0x0x7ff86be0dc98) 0 + primary-for std::invalid_argument (0x0x7ff86be0dc30) + std::exception (0x0x7ff86bdc4cc0) 0 nearly-empty + primary-for std::logic_error (0x0x7ff86be0dc98) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7ff86be0dd00) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16u) + std::logic_error (0x0x7ff86be0dd68) 0 + primary-for std::length_error (0x0x7ff86be0dd00) + std::exception (0x0x7ff86bdc4d20) 0 nearly-empty + primary-for std::logic_error (0x0x7ff86be0dd68) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7ff86be0ddd0) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16u) + std::logic_error (0x0x7ff86be0de38) 0 + primary-for std::out_of_range (0x0x7ff86be0ddd0) + std::exception (0x0x7ff86bdc4d80) 0 nearly-empty + primary-for std::logic_error (0x0x7ff86be0de38) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7ff86be0dea0) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16u) + std::exception (0x0x7ff86bdc4de0) 0 nearly-empty + primary-for std::runtime_error (0x0x7ff86be0dea0) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7ff86be0df08) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16u) + std::runtime_error (0x0x7ff86be0df70) 0 + primary-for std::range_error (0x0x7ff86be0df08) + std::exception (0x0x7ff86bdc4e40) 0 nearly-empty + primary-for std::runtime_error (0x0x7ff86be0df70) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7ff86be0d820) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16u) + std::runtime_error (0x0x7ff86be0d8f0) 0 + primary-for std::overflow_error (0x0x7ff86be0d820) + std::exception (0x0x7ff86bdc4ea0) 0 nearly-empty + primary-for std::runtime_error (0x0x7ff86be0d8f0) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7ff86bb04000) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16u) + std::runtime_error (0x0x7ff86bb04068) 0 + primary-for std::underflow_error (0x0x7ff86bb04000) + std::exception (0x0x7ff86bdc4f00) 0 nearly-empty + primary-for std::runtime_error (0x0x7ff86bb04068) + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7ff86bb0b0c0) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16u) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7ff86bb0b300) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7ff86bb0b480) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7ff86bb04548) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16u) + std::runtime_error (0x0x7ff86bb045b0) 0 + primary-for std::system_error (0x0x7ff86bb04548) + std::exception (0x0x7ff86bb0b6c0) 0 nearly-empty + primary-for std::runtime_error (0x0x7ff86bb045b0) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7ff86bb7f1a0) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16u) + std::system_error (0x0x7ff86bb7f208) 0 + primary-for std::ios_base::failure (0x0x7ff86bb7f1a0) + std::runtime_error (0x0x7ff86bb7f270) 0 + primary-for std::system_error (0x0x7ff86bb7f208) + std::exception (0x0x7ff86bb0b9c0) 0 nearly-empty + primary-for std::runtime_error (0x0x7ff86bb7f270) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7ff86bb0ba20) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7ff86bb0ba80) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7ff86bb0bae0) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7ff86bb0b960) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7ff86bc402a0) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7ff86bc40960) 0 empty + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSo: 2u entries +0 ((& std::basic_ostream::_ZTVSo) + 24u) +8 ((& std::basic_ostream::_ZTVSo) + 64u) + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSi: 2u entries +0 ((& std::basic_istream::_ZTVSi) + 24u) +8 ((& std::basic_istream::_ZTVSi) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u) + +Construction vtable for std::basic_istream (0x0x7ff86b7ebd68 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd0_Si: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7ff86b7ebe38 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd16_So: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSd: 7u entries +0 ((& std::basic_iostream::_ZTVSd) + 24u) +8 ((& std::basic_iostream::_ZTCSd0_Si) + 24u) +16 ((& std::basic_iostream::_ZTCSd0_Si) + 64u) +24 ((& std::basic_iostream::_ZTCSd16_So) + 24u) +32 ((& std::basic_iostream::_ZTCSd16_So) + 64u) +40 ((& std::basic_iostream::_ZTVSd) + 104u) +48 ((& std::basic_iostream::_ZTVSd) + 64u) + +Construction vtable for std::basic_istream (0x0x7ff86b7eb3a8 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7ff86b7eb9c0 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries +0 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u) +16 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u) +24 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u) +32 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u) +40 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u) +48 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u) + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7ff86b86f1e0) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7ff86b86f240) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7ff86b5875a0) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7ff86b587900) 0 + +Class QStringView + size=16 align=8 + base size=16 base align=8 +QStringView (0x0x7ff86b587d80) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7ff86b2bac00) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7ff86b34b2a0) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7ff86b34b240) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7ff86b0f5360) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7ff86b0f5f60) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7ff86aee8c00) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7ff86aee8c60) 0 empty + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7ff86aee8cc0) 0 + +Class QListData::NotArrayCompatibleLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotArrayCompatibleLayout (0x0x7ff86ad560c0) 0 empty + +Class QListData::NotIndirectLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotIndirectLayout (0x0x7ff86ad56120) 0 empty + +Class QListData::ArrayCompatibleLayout + size=1 align=1 + base size=1 base align=1 +QListData::ArrayCompatibleLayout (0x0x7ff86af03af8) 0 empty + QListData::NotIndirectLayout (0x0x7ff86ad56180) 0 empty + +Class QListData::InlineWithPaddingLayout + size=1 align=1 + base size=1 base align=1 +QListData::InlineWithPaddingLayout (0x0x7ff86ad58310) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7ff86ad561e0) 0 empty + QListData::NotIndirectLayout (0x0x7ff86ad56240) 0 empty + +Class QListData::IndirectLayout + size=1 align=1 + base size=1 base align=1 +QListData::IndirectLayout (0x0x7ff86af03b60) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7ff86ad562a0) 0 empty + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7ff86ad56300) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7ff86ad56060) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7ff86ad56780) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7ff86ab089c0) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7ff86ab08960) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7ff86ab135b0) 0 + QList (0x0x7ff86ab13618) 0 + QListSpecialMethods (0x0x7ff86ab08ba0) 0 empty + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7ff86abae000) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7ff86abaeba0) 0 + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7ff86a99e240) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7ff86a99e3c0) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7ff86a99e480) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7ff86ab13f08) 0 + std::__uses_alloc_base (0x0x7ff86a99e420) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7ff86a6ba4e0) 0 empty + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7ff86a6ba720) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7ff86a6ba7e0) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7ff86a6ba900) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7ff86a6baa80) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7ff86a6baea0) 0 + +Class QtMetaTypePrivate::VectorBoolElements + size=1 align=1 + base size=0 base align=1 +QtMetaTypePrivate::VectorBoolElements (0x0x7ff86a812000) 0 empty + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7ff86a812960) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7ff86a812d80) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7ff86a5000c0) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7ff86a326a80) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7ff86a081900) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7ff86a081960) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16u) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7ff86a081b40) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7ff86a081ae0) 0 + vptr=((& QObject::_ZTV7QObject) + 16u) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7ff86a132de0) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7ff86a132e40) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7ff86a132f00) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7ff86a17c138) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u) + QObject (0x0x7ff86a132ea0) 0 + primary-for QAbstractAnimation (0x0x7ff86a17c138) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7ff86a1bc000) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7ff86a17c1a0) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16u) + QObject (0x0x7ff86a132f60) 0 + primary-for QAnimationDriver (0x0x7ff86a17c1a0) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7ff86a1bc0c0) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7ff86a17c208) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u) + QObject (0x0x7ff86a1bc060) 0 + primary-for QEventLoop (0x0x7ff86a17c208) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7ff86a1bc2a0) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7ff86a1bc360) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7ff86a1bc3c0) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7ff86a17c340) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u) + QObject (0x0x7ff86a1bc300) 0 + primary-for QAbstractEventDispatcher (0x0x7ff86a17c340) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7ff86a1bc660) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16u) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7ff86a17c548) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16u) + std::exception (0x0x7ff86a1bc6c0) 0 nearly-empty + primary-for std::bad_cast (0x0x7ff86a17c548) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7ff86a17c5b0) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16u) + std::exception (0x0x7ff86a1bc720) 0 nearly-empty + primary-for std::bad_typeid (0x0x7ff86a17c5b0) + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7ff869f1a820) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16u) + std::exception (0x0x7ff869f487e0) 0 nearly-empty + primary-for std::bad_function_call (0x0x7ff869f1a820) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7ff869f488a0) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7ff869f48900) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7ff869f48a20) 0 + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7ff869f48f00) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7ff86a041480) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7ff86a041840) 0 + +Class QHashData + size=48 align=8 + base size=44 base align=8 +QHashData (0x0x7ff86a0417e0) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7ff86a0418a0) 0 empty + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7ff869e52180) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7ff869e52240) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7ff869e521e0) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7ff869e522a0) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7ff869e52120) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7ff869b1fd80) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7ff869bca420) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7ff869bca3c0) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7ff869bca4e0) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7ff869bca480) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7ff8698ef7e0) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7ff8698efea0) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7ff8696d8600) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7ff8696e05b0) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u) + QObject (0x0x7ff8696d85a0) 0 + primary-for QAbstractItemModel (0x0x7ff8696e05b0) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7ff8696d8ea0) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7ff8696e0c98) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u) + QAbstractItemModel (0x0x7ff8696e0d00) 0 + primary-for QAbstractTableModel (0x0x7ff8696e0c98) + QObject (0x0x7ff8696d8e40) 0 + primary-for QAbstractItemModel (0x0x7ff8696e0d00) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7ff8696d8f60) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7ff8696e0d68) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u) + QAbstractItemModel (0x0x7ff8696e0dd0) 0 + primary-for QAbstractListModel (0x0x7ff8696e0d68) + QObject (0x0x7ff8696d8f00) 0 + primary-for QAbstractItemModel (0x0x7ff8696e0dd0) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7ff8697e8240) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16u) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7ff8697e8300) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7ff8696e0f08) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16u) + QAbstractItemModel (0x0x7ff8696e0f70) 0 + primary-for QAbstractProxyModel (0x0x7ff8696e0f08) + QObject (0x0x7ff8697e82a0) 0 + primary-for QAbstractItemModel (0x0x7ff8696e0f70) + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7ff8697e83c0) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7ff86983a000) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u) + QObject (0x0x7ff8697e8360) 0 + primary-for QAbstractState (0x0x7ff86983a000) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7ff8697e8480) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7ff86983a068) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u) + QObject (0x0x7ff8697e8420) 0 + primary-for QAbstractTransition (0x0x7ff86983a068) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7ff8697e8540) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7ff86983a0d0) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u) + QAbstractAnimation (0x0x7ff86983a138) 0 + primary-for QAnimationGroup (0x0x7ff86983a0d0) + QObject (0x0x7ff8697e84e0) 0 + primary-for QAbstractAnimation (0x0x7ff86983a138) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7ff8694aa2a0) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7ff8694aa540) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7ff8694aa600) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7ff8694aa900) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7ff86983a7b8) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16u) + QObject (0x0x7ff8694aa8a0) 0 + primary-for QIODevice (0x0x7ff86983a7b8) + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7ff8694aab40) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7ff86983a8f0) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16u) + QIODevice (0x0x7ff86983a958) 0 + primary-for QBuffer (0x0x7ff86983a8f0) + QObject (0x0x7ff8694aaae0) 0 + primary-for QIODevice (0x0x7ff86983a958) + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7ff8694aac00) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7ff8694aaba0) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7ff8694aad20) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7ff8694aacc0) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7ff8694aaf00) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7ff8695ec120) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7ff8695ec3c0) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7ff8695ecb40) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7ff8695ecba0) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7ff8695ecae0) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7ff8692fdcc0) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7ff8693c4300) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16u) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7ff8693c45a0) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7ff8693c47e0) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7ff8693c4ea0) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7ff8690fc060) 0 + +Class QDebug::Stream + size=80 align=8 + base size=76 base align=8 +QDebug::Stream (0x0x7ff8690fc5a0) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7ff8690fc540) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7ff868f0c8a0) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7ff868f0c960) 0 empty + +Class QCborError + size=4 align=4 + base size=4 base align=4 +QCborError (0x0x7ff868f88cc0) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7ff868f88e40) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7ff868ff1480) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7ff868ff1780) 0 + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7ff868ff1b40) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7ff868d8d240) 0 + +Class QCborParserError + size=16 align=8 + base size=12 base align=8 +QCborParserError (0x0x7ff868d8d840) 0 + +Class QCborValue + size=24 align=8 + base size=20 base align=8 +QCborValue (0x0x7ff868d8d8a0) 0 + +Class QCborValueRef + size=16 align=8 + base size=16 base align=8 +QCborValueRef (0x0x7ff8688488a0) 0 + +Class QCborArray::Iterator + size=16 align=8 + base size=16 base align=8 +QCborArray::Iterator (0x0x7ff868848e40) 0 + +Class QCborArray::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborArray::ConstIterator (0x0x7ff868848ea0) 0 + +Class QCborArray + size=8 align=8 + base size=8 base align=8 +QCborArray (0x0x7ff868848de0) 0 + +Class QCborMap::Iterator + size=16 align=8 + base size=16 base align=8 +QCborMap::Iterator (0x0x7ff868978f00) 0 + +Class QCborMap::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborMap::ConstIterator (0x0x7ff868978f60) 0 + +Class QCborMap + size=8 align=8 + base size=8 base align=8 +QCborMap (0x0x7ff868978ea0) 0 + +Class qfloat16 + size=2 align=2 + base size=2 base align=2 +qfloat16 (0x0x7ff86873dae0) 0 + +Class QCborStreamWriter + size=8 align=8 + base size=8 base align=8 +QCborStreamWriter (0x0x7ff86873dea0) 0 + +Class QCborStreamReader + size=24 align=8 + base size=20 base align=8 +QCborStreamReader (0x0x7ff8684918a0) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7ff868491f00) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7ff86854a000) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7ff8685d9000) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7ff8685d9480) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16u) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7ff8685c0f08) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u) + QEvent (0x0x7ff8685d94e0) 0 + primary-for QTimerEvent (0x0x7ff8685c0f08) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7ff8685c0f70) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u) + QEvent (0x0x7ff8685d9540) 0 + primary-for QChildEvent (0x0x7ff8685c0f70) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7ff8682244e0) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u) + QEvent (0x0x7ff8685d9a20) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7ff8682244e0) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7ff868224548) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16u) + QEvent (0x0x7ff8685d9a80) 0 + primary-for QDeferredDeleteEvent (0x0x7ff868224548) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7ff8685d9b40) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7ff8682245b0) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u) + QObject (0x0x7ff8685d9ae0) 0 + primary-for QCoreApplication (0x0x7ff8682245b0) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7ff8685d9ba0) 0 + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7ff8685d9c00) 0 + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7ff8685d9c60) 0 + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7ff8685d9d20) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7ff8682aa240) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7ff8682aa720) 0 + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7ff8680115a0) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7ff86800ca28) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16u) + QIODevice (0x0x7ff86800ca90) 0 + primary-for QFileDevice (0x0x7ff86800ca28) + QObject (0x0x7ff868011540) 0 + primary-for QIODevice (0x0x7ff86800ca90) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7ff8680117e0) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7ff86800cbc8) 0 + vptr=((& QFile::_ZTV5QFile) + 16u) + QFileDevice (0x0x7ff86800cc30) 0 + primary-for QFile (0x0x7ff86800cbc8) + QIODevice (0x0x7ff86800cc98) 0 + primary-for QFileDevice (0x0x7ff86800cc30) + QObject (0x0x7ff868011780) 0 + primary-for QIODevice (0x0x7ff86800cc98) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7ff8680119c0) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7ff868011de0) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7ff868109420) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7ff868109660) 0 + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7ff867e1ba80) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7ff867e17c98) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u) + QAbstractTransition (0x0x7ff867e17d00) 0 + primary-for QEventTransition (0x0x7ff867e17c98) + QObject (0x0x7ff867e1ba20) 0 + primary-for QAbstractTransition (0x0x7ff867e17d00) + +Vtable for QException +QException::_ZTV10QException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7ff867e17d68) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16u) + std::exception (0x0x7ff867e1bae0) 0 nearly-empty + primary-for QException (0x0x7ff867e17d68) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7ff867e17dd0) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16u) + QException (0x0x7ff867e17e38) 0 nearly-empty + primary-for QUnhandledException (0x0x7ff867e17dd0) + std::exception (0x0x7ff867e1bb40) 0 nearly-empty + primary-for QException (0x0x7ff867e17e38) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7ff867e1bba0) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7ff867e1bc60) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7ff867e1bcc0) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7ff867e1bde0) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7ff867e17ea0) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16u) + QObject (0x0x7ff867e1bd80) 0 + primary-for QFileSelector (0x0x7ff867e17ea0) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7ff867e1bea0) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7ff867e17f08) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u) + QObject (0x0x7ff867e1be40) 0 + primary-for QFileSystemWatcher (0x0x7ff867e17f08) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7ff867e1bf60) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7ff867e17f70) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16u) + QAbstractState (0x0x7ff867ecc000) 0 + primary-for QFinalState (0x0x7ff867e17f70) + QObject (0x0x7ff867e1bf00) 0 + primary-for QAbstractState (0x0x7ff867ecc000) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7ff867eda000) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16u) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7ff867eda060) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7ff867ecc138) 0 + QBasicMutex (0x0x7ff867eda240) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7ff867eda2a0) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7ff867eda300) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7ff867eda360) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7ff867eda480) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16u) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7ff867edacc0) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7ff867c4b4e0) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0u +48 0u +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7ff867c4e270) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u) + QObject (0x0x7ff867c4b480) 0 + primary-for QFutureWatcherBase (0x0x7ff867c4e270) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7ff867c4bae0) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7ff867c4eb60) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u) + QAbstractState (0x0x7ff867c4ebc8) 0 + primary-for QHistoryState (0x0x7ff867c4eb60) + QObject (0x0x7ff867c4ba80) 0 + primary-for QAbstractState (0x0x7ff867c4ebc8) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7ff867c4bba0) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7ff867c4ec30) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16u) + QAbstractProxyModel (0x0x7ff867c4ec98) 0 + primary-for QIdentityProxyModel (0x0x7ff867c4ec30) + QAbstractItemModel (0x0x7ff867c4ed00) 0 + primary-for QAbstractProxyModel (0x0x7ff867c4ec98) + QObject (0x0x7ff867c4bb40) 0 + primary-for QAbstractItemModel (0x0x7ff867c4ed00) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7ff867c4bc00) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7ff867d1f300) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7ff867d19548) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u) + QObject (0x0x7ff867d1f2a0) 0 + primary-for QItemSelectionModel (0x0x7ff867d19548) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7ff867d19750) 0 + QList (0x0x7ff867d197b8) 0 + QListSpecialMethods (0x0x7ff867d1f600) 0 empty + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7ff867d1fae0) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7ff867b2d240) 0 + +Class QJsonValuePtr + size=24 align=8 + base size=24 base align=8 +QJsonValuePtr (0x0x7ff867b2d780) 0 + +Class QJsonValueRefPtr + size=16 align=8 + base size=16 base align=8 +QJsonValueRefPtr (0x0x7ff867b2d7e0) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7ff867b2d9c0) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7ff867b2da20) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7ff867b2d960) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7ff867841c60) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7ff867841cc0) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7ff8678bb360) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7ff8678bb3c0) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7ff8678bb300) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7ff867971660) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7ff86796caf8) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16u) + QObject (0x0x7ff867971600) 0 + primary-for QLibrary (0x0x7ff86796caf8) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7ff867971d20) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7ff867971840) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7ff867661240) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7ff8676612a0) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7ff867661540) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7ff867661b40) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7ff8677034e0) 0 + +Class QLinkedListData + size=32 align=8 + base size=25 base align=8 +QLinkedListData (0x0x7ff867703ae0) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7ff867703e40) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7ff867447000) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7ff867703f60) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7ff867447180) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7ff867447420) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7ff867447a80) 0 + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7ff867447ae0) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7ff867578120) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7ff867578420) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7ff867578480) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7ff867578780) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7ff867500d68) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16u) + QObject (0x0x7ff867578720) 0 + primary-for QMimeData (0x0x7ff867500d68) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7ff8675787e0) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7ff867578ae0) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7ff867578ba0) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7ff867500f70) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u) + QObject (0x0x7ff867578b40) 0 + primary-for QObjectCleanupHandler (0x0x7ff867500f70) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7ff867578c00) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7ff8672023c0) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7ff8671f16e8) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u) + QAnimationGroup (0x0x7ff8671f1750) 0 + primary-for QParallelAnimationGroup (0x0x7ff8671f16e8) + QAbstractAnimation (0x0x7ff8671f17b8) 0 + primary-for QAnimationGroup (0x0x7ff8671f1750) + QObject (0x0x7ff867202360) 0 + primary-for QAbstractAnimation (0x0x7ff8671f17b8) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7ff867202480) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7ff8671f1820) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u) + QAbstractAnimation (0x0x7ff8671f1888) 0 + primary-for QPauseAnimation (0x0x7ff8671f1820) + QObject (0x0x7ff867202420) 0 + primary-for QAbstractAnimation (0x0x7ff8671f1888) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7ff867202660) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7ff867202960) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7ff8671f1a90) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u) + QObject (0x0x7ff867202900) 0 + primary-for QPluginLoader (0x0x7ff8671f1a90) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7ff8672029c0) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7ff86728c0c0) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7ff86728b0d0) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16u) + QIODevice (0x0x7ff86728b138) 0 + primary-for QProcess (0x0x7ff86728b0d0) + QObject (0x0x7ff86728c060) 0 + primary-for QIODevice (0x0x7ff86728b138) + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7ff86728c180) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7ff86728b1a0) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u) + QAbstractAnimation (0x0x7ff86728b208) 0 + primary-for QVariantAnimation (0x0x7ff86728b1a0) + QObject (0x0x7ff86728c120) 0 + primary-for QAbstractAnimation (0x0x7ff86728b208) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7ff86728c240) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7ff86728b2d8) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u) + QVariantAnimation (0x0x7ff86728b340) 0 + primary-for QPropertyAnimation (0x0x7ff86728b2d8) + QAbstractAnimation (0x0x7ff86728b3a8) 0 + primary-for QVariantAnimation (0x0x7ff86728b340) + QObject (0x0x7ff86728c1e0) 0 + primary-for QAbstractAnimation (0x0x7ff86728b3a8) + +Class QRandomGenerator::Storage + size=2504 align=8 + base size=2504 base align=8 +QRandomGenerator::Storage (0x0x7ff86728c360) 0 + +Class QRandomGenerator + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator (0x0x7ff86728c300) 0 + +Class QRandomGenerator64 + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator64 (0x0x7ff86736d680) 0 + QRandomGenerator (0x0x7ff86737f300) 0 + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7ff86737f3c0) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7ff86737f660) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7ff86737f720) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7ff86737f7e0) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7ff86737fa80) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7ff86737fd20) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7ff867149000) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7ff8671492a0) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7ff867149420) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7ff8670de208) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16u) + QFileDevice (0x0x7ff8670de270) 0 + primary-for QSaveFile (0x0x7ff8670de208) + QIODevice (0x0x7ff8670de2d8) 0 + primary-for QFileDevice (0x0x7ff8670de270) + QObject (0x0x7ff8671493c0) 0 + primary-for QIODevice (0x0x7ff8670de2d8) + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7ff867149540) 0 + +Class QSemaphoreReleaser + size=16 align=8 + base size=12 base align=8 +QSemaphoreReleaser (0x0x7ff8671496c0) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7ff866f23cc0) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7ff866f36b60) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u) + QAnimationGroup (0x0x7ff866f36bc8) 0 + primary-for QSequentialAnimationGroup (0x0x7ff866f36b60) + QAbstractAnimation (0x0x7ff866f36c30) 0 + primary-for QAnimationGroup (0x0x7ff866f36bc8) + QObject (0x0x7ff866f23c60) 0 + primary-for QAbstractAnimation (0x0x7ff866f36c30) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7ff866f23d80) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7ff866f36c98) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16u) + QObject (0x0x7ff866f23d20) 0 + primary-for QSettings (0x0x7ff866f36c98) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7ff866f23e40) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7ff866f36d00) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u) + QObject (0x0x7ff866f23de0) 0 + primary-for QSharedMemory (0x0x7ff866f36d00) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7ff866f23f00) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7ff866f36d68) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u) + QObject (0x0x7ff866f23ea0) 0 + primary-for QSignalMapper (0x0x7ff866f36d68) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7ff866fa5000) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7ff866f36dd0) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u) + QAbstractTransition (0x0x7ff866f36e38) 0 + primary-for QSignalTransition (0x0x7ff866f36dd0) + QObject (0x0x7ff866f23f60) 0 + primary-for QAbstractTransition (0x0x7ff866f36e38) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7ff866fa50c0) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7ff866f36ea0) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u) + QObject (0x0x7ff866fa5060) 0 + primary-for QSocketNotifier (0x0x7ff866f36ea0) + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7ff866fa5180) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7ff866f36f08) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16u) + QAbstractProxyModel (0x0x7ff866f36f70) 0 + primary-for QSortFilterProxyModel (0x0x7ff866f36f08) + QAbstractItemModel (0x0x7ff866fc1000) 0 + primary-for QAbstractProxyModel (0x0x7ff866f36f70) + QObject (0x0x7ff866fa5120) 0 + primary-for QAbstractItemModel (0x0x7ff866fc1000) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7ff866fa5240) 0 empty + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7ff866fa5480) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7ff866fc11a0) 0 + vptr=((& QState::_ZTV6QState) + 16u) + QAbstractState (0x0x7ff866fc1208) 0 + primary-for QState (0x0x7ff866fc11a0) + QObject (0x0x7ff866fa5420) 0 + primary-for QAbstractState (0x0x7ff866fc1208) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7ff866fa55a0) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7ff866fc13a8) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u) + QEvent (0x0x7ff866fa5600) 0 + primary-for QStateMachine::SignalEvent (0x0x7ff866fc13a8) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7ff866fc1410) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u) + QEvent (0x0x7ff866fa5660) 0 + primary-for QStateMachine::WrappedEvent (0x0x7ff866fc1410) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7ff866fc1270) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u) + QState (0x0x7ff866fc12d8) 0 + primary-for QStateMachine (0x0x7ff866fc1270) + QAbstractState (0x0x7ff866fc1340) 0 + primary-for QState (0x0x7ff866fc12d8) + QObject (0x0x7ff866fa5540) 0 + primary-for QAbstractState (0x0x7ff866fc1340) + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7ff866fa56c0) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7ff866ca7600) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7ff866d2a9c0) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7ff866d40410) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u) + QAbstractListModel (0x0x7ff866d40478) 0 + primary-for QStringListModel (0x0x7ff866d40410) + QAbstractItemModel (0x0x7ff866d404e0) 0 + primary-for QAbstractListModel (0x0x7ff866d40478) + QObject (0x0x7ff866d2a960) 0 + primary-for QAbstractItemModel (0x0x7ff866d404e0) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7ff866d2aa20) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7ff866d2aae0) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7ff866d2ac00) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7ff866d40548) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u) + QFile (0x0x7ff866d405b0) 0 + primary-for QTemporaryFile (0x0x7ff866d40548) + QFileDevice (0x0x7ff866d40618) 0 + primary-for QFile (0x0x7ff866d405b0) + QIODevice (0x0x7ff866d40680) 0 + primary-for QFileDevice (0x0x7ff866d40618) + QObject (0x0x7ff866d2aba0) 0 + primary-for QIODevice (0x0x7ff866d40680) + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7ff866d2ac60) 0 + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7ff866d2aea0) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 0u +64 0u + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7ff866d2ae40) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7ff866de00c0) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7ff866de0120) 0 + +Class std::__mutex_base + size=40 align=8 + base size=40 base align=8 +std::__mutex_base (0x0x7ff866de0180) 0 + +Class std::__recursive_mutex_base + size=40 align=8 + base size=40 base align=8 +std::__recursive_mutex_base (0x0x7ff866de01e0) 0 + +Class std::mutex + size=40 align=8 + base size=40 base align=8 +std::mutex (0x0x7ff866d40888) 0 + std::__mutex_base (0x0x7ff866de0240) 0 + +Class std::recursive_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_mutex (0x0x7ff866d408f0) 0 + std::__recursive_mutex_base (0x0x7ff866de02a0) 0 + +Class std::timed_mutex + size=40 align=8 + base size=40 base align=8 +std::timed_mutex (0x0x7ff866a453f0) 0 + std::__mutex_base (0x0x7ff866de03c0) 0 + std::__timed_mutex_impl (0x0x7ff866de0420) 0 empty + +Class std::recursive_timed_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_timed_mutex (0x0x7ff866a45d90) 0 + std::__recursive_mutex_base (0x0x7ff866de04e0) 0 + std::__timed_mutex_impl (0x0x7ff866de0540) 0 empty + +Class std::defer_lock_t + size=1 align=1 + base size=0 base align=1 +std::defer_lock_t (0x0x7ff866de05a0) 0 empty + +Class std::try_to_lock_t + size=1 align=1 + base size=0 base align=1 +std::try_to_lock_t (0x0x7ff866de0600) 0 empty + +Class std::adopt_lock_t + size=1 align=1 + base size=0 base align=1 +std::adopt_lock_t (0x0x7ff866de0660) 0 empty + +Class std::once_flag + size=4 align=4 + base size=4 base align=4 +std::once_flag (0x0x7ff866de08a0) 0 + +Vtable for __gnu_cxx::__concurrence_lock_error +__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what + +Class __gnu_cxx::__concurrence_lock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_lock_error (0x0x7ff866d40a28) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16u) + std::exception (0x0x7ff866de0960) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_lock_error (0x0x7ff866d40a28) + +Vtable for __gnu_cxx::__concurrence_unlock_error +__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what + +Class __gnu_cxx::__concurrence_unlock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_unlock_error (0x0x7ff866d40a90) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16u) + std::exception (0x0x7ff866de0a20) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7ff866d40a90) + +Vtable for __gnu_cxx::__concurrence_broadcast_error +__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what + +Class __gnu_cxx::__concurrence_broadcast_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_broadcast_error (0x0x7ff866d40af8) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16u) + std::exception (0x0x7ff866de0ae0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7ff866d40af8) + +Vtable for __gnu_cxx::__concurrence_wait_error +__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what + +Class __gnu_cxx::__concurrence_wait_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_wait_error (0x0x7ff866d40bc8) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16u) + std::exception (0x0x7ff866de0ba0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_wait_error (0x0x7ff866d40bc8) + +Class __gnu_cxx::__mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__mutex (0x0x7ff866de0c60) 0 + +Class __gnu_cxx::__recursive_mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__recursive_mutex (0x0x7ff866de0cc0) 0 + +Class __gnu_cxx::__scoped_lock + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__scoped_lock (0x0x7ff866de0d20) 0 + +Class __gnu_cxx::__cond + size=48 align=8 + base size=48 base align=8 +__gnu_cxx::__cond (0x0x7ff866de0d80) 0 + +Vtable for std::bad_weak_ptr +std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12bad_weak_ptr) +16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +32 (int (*)(...))std::bad_weak_ptr::what + +Class std::bad_weak_ptr + size=8 align=8 + base size=8 base align=8 +std::bad_weak_ptr (0x0x7ff866d40ea0) 0 nearly-empty + vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16u) + std::exception (0x0x7ff866b2a120) 0 nearly-empty + primary-for std::bad_weak_ptr (0x0x7ff866d40ea0) + +Class std::_Sp_make_shared_tag + size=1 align=1 + base size=0 base align=1 +std::_Sp_make_shared_tag (0x0x7ff866b2a960) 0 empty + +Class std::_Sp_locker + size=2 align=1 + base size=2 base align=1 +std::_Sp_locker (0x0x7ff8668e6180) 0 + +Class std::thread::id + size=8 align=8 + base size=8 base align=8 +std::thread::id (0x0x7ff8668e6360) 0 + +Vtable for std::thread::_Impl_base +std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6thread10_Impl_baseE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class std::thread::_Impl_base + size=24 align=8 + base size=24 base align=8 +std::thread::_Impl_base (0x0x7ff8668e63c0) 0 + vptr=((& std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE) + 16u) + +Class std::thread + size=8 align=8 + base size=8 base align=8 +std::thread (0x0x7ff8668e6300) 0 + +Class std::condition_variable + size=48 align=8 + base size=48 base align=8 +std::condition_variable (0x0x7ff866684000) 0 + +Class std::__at_thread_exit_elt + size=16 align=8 + base size=16 base align=8 +std::__at_thread_exit_elt (0x0x7ff8666840c0) 0 + +Class std::_V2::condition_variable_any + size=64 align=8 + base size=64 base align=8 +std::_V2::condition_variable_any (0x0x7ff866684120) 0 + +Class std::__atomic_futex_unsigned_base + size=1 align=1 + base size=0 base align=1 +std::__atomic_futex_unsigned_base (0x0x7ff86672c780) 0 empty + +Vtable for std::future_error +std::future_error::_ZTVSt12future_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12future_error) +16 (int (*)(...))std::future_error::~future_error +24 (int (*)(...))std::future_error::~future_error +32 (int (*)(...))std::future_error::what + +Class std::future_error + size=32 align=8 + base size=32 base align=8 +std::future_error (0x0x7ff86676c208) 0 + vptr=((& std::future_error::_ZTVSt12future_error) + 16u) + std::logic_error (0x0x7ff86676c270) 0 + primary-for std::future_error (0x0x7ff86676c208) + std::exception (0x0x7ff86672c8a0) 0 nearly-empty + primary-for std::logic_error (0x0x7ff86676c270) + +Class std::__future_base::_Result_base::_Deleter + size=1 align=1 + base size=0 base align=1 +std::__future_base::_Result_base::_Deleter (0x0x7ff86672c9c0) 0 empty + +Vtable for std::__future_base::_Result_base +std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class std::__future_base::_Result_base + size=16 align=8 + base size=16 base align=8 +std::__future_base::_Result_base (0x0x7ff86672c960) 0 + vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16u) + +Class std::__future_base::_State_baseV2::__exception_ptr_tag + size=1 align=1 + base size=0 base align=1 +std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7ff8663f5f00) 0 empty + +Class std::__future_base::_State_baseV2::_Make_ready + size=32 align=8 + base size=32 base align=8 +std::__future_base::_State_baseV2::_Make_ready (0x0x7ff8664a7820) 0 + std::__at_thread_exit_elt (0x0x7ff8664d3000) 0 + +Vtable for std::__future_base::_State_baseV2 +std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E) +16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_State_baseV2 + size=32 align=8 + base size=28 base align=8 +std::__future_base::_State_baseV2 (0x0x7ff86672cb40) 0 + vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16u) + +Class std::__future_base + size=1 align=1 + base size=0 base align=1 +std::__future_base (0x0x7ff86672c900) 0 empty + +Vtable for std::__future_base::_Async_state_commonV2 +std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E) +16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_Async_state_commonV2 + size=48 align=8 + base size=44 base align=8 +std::__future_base::_Async_state_commonV2 (0x0x7ff865e11410) 0 + vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16u) + std::__future_base::_State_baseV2 (0x0x7ff865df6ea0) 0 + primary-for std::__future_base::_Async_state_commonV2 (0x0x7ff865e11410) + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7ff865e5e600) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7ff865e11ea0) 0 + vptr=((& QThread::_ZTV7QThread) + 16u) + QObject (0x0x7ff865e5e5a0) 0 + primary-for QThread (0x0x7ff865e11ea0) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7ff865e5e720) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7ff865e11f08) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u) + QObject (0x0x7ff865e5e6c0) 0 + primary-for QThreadPool (0x0x7ff865e11f08) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7ff865e5e780) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7ff865e5e8a0) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7ff865e11f70) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u) + QObject (0x0x7ff865e5e840) 0 + primary-for QTimeLine (0x0x7ff865e11f70) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7ff865e5e960) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7ff865ee5000) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16u) + QObject (0x0x7ff865e5e900) 0 + primary-for QTimer (0x0x7ff865ee5000) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7ff865f280c0) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7ff865f28060) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7ff865f28660) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7ff865ee5bc8) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16u) + QObject (0x0x7ff865f28600) 0 + primary-for QTranslator (0x0x7ff865ee5bc8) + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7ff865f286c0) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7ff865f28d20) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7ff865f28d80) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7ff865bce060) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7ff865f91888) 0 + QVector (0x0x7ff865bce420) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7ff865bce480) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7ff865bce720) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7ff865bce9c0) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7ff865bcec60) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7ff865bcecc0) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7ff865cda720) 0 + +Class QRgba64 + size=8 align=8 + base size=8 base align=8 +QRgba64 (0x0x7ff865cda840) 0 + +Class QColor + size=16 align=4 + base size=14 base align=4 +QColor (0x0x7ff865cdaae0) 0 + +Class QRegion::QRegionData + size=16 align=8 + base size=16 base align=8 +QRegion::QRegionData (0x0x7ff865a114e0) 0 + +Class QRegion + size=8 align=8 + base size=8 base align=8 +QRegion (0x0x7ff865a11480) 0 + +Class QKeySequence + size=8 align=8 + base size=8 base align=8 +QKeySequence (0x0x7ff865aac840) 0 + +Class QVector2D + size=8 align=4 + base size=8 base align=4 +QVector2D (0x0x7ff865b60d80) 0 + +Class QTouchDevice + size=8 align=8 + base size=8 base align=8 +QTouchDevice (0x0x7ff865ba7060) 0 + +Vtable for QInputEvent +QInputEvent::_ZTV11QInputEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QInputEvent) +16 (int (*)(...))QInputEvent::~QInputEvent +24 (int (*)(...))QInputEvent::~QInputEvent + +Class QInputEvent + size=32 align=8 + base size=32 base align=8 +QInputEvent (0x0x7ff865b73680) 0 + vptr=((& QInputEvent::_ZTV11QInputEvent) + 16u) + QEvent (0x0x7ff865ba7240) 0 + primary-for QInputEvent (0x0x7ff865b73680) + +Vtable for QEnterEvent +QEnterEvent::_ZTV11QEnterEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QEnterEvent) +16 (int (*)(...))QEnterEvent::~QEnterEvent +24 (int (*)(...))QEnterEvent::~QEnterEvent + +Class QEnterEvent + size=72 align=8 + base size=72 base align=8 +QEnterEvent (0x0x7ff865b736e8) 0 + vptr=((& QEnterEvent::_ZTV11QEnterEvent) + 16u) + QEvent (0x0x7ff865ba72a0) 0 + primary-for QEnterEvent (0x0x7ff865b736e8) + +Vtable for QMouseEvent +QMouseEvent::_ZTV11QMouseEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QMouseEvent) +16 (int (*)(...))QMouseEvent::~QMouseEvent +24 (int (*)(...))QMouseEvent::~QMouseEvent + +Class QMouseEvent + size=104 align=8 + base size=100 base align=8 +QMouseEvent (0x0x7ff865b73750) 0 + vptr=((& QMouseEvent::_ZTV11QMouseEvent) + 16u) + QInputEvent (0x0x7ff865b737b8) 0 + primary-for QMouseEvent (0x0x7ff865b73750) + QEvent (0x0x7ff865ba7300) 0 + primary-for QInputEvent (0x0x7ff865b737b8) + +Vtable for QHoverEvent +QHoverEvent::_ZTV11QHoverEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QHoverEvent) +16 (int (*)(...))QHoverEvent::~QHoverEvent +24 (int (*)(...))QHoverEvent::~QHoverEvent + +Class QHoverEvent + size=64 align=8 + base size=64 base align=8 +QHoverEvent (0x0x7ff865b73820) 0 + vptr=((& QHoverEvent::_ZTV11QHoverEvent) + 16u) + QInputEvent (0x0x7ff865b73888) 0 + primary-for QHoverEvent (0x0x7ff865b73820) + QEvent (0x0x7ff865ba7360) 0 + primary-for QInputEvent (0x0x7ff865b73888) + +Vtable for QWheelEvent +QWheelEvent::_ZTV11QWheelEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QWheelEvent) +16 (int (*)(...))QWheelEvent::~QWheelEvent +24 (int (*)(...))QWheelEvent::~QWheelEvent + +Class QWheelEvent + size=96 align=8 + base size=96 base align=8 +QWheelEvent (0x0x7ff865b738f0) 0 + vptr=((& QWheelEvent::_ZTV11QWheelEvent) + 16u) + QInputEvent (0x0x7ff865b73958) 0 + primary-for QWheelEvent (0x0x7ff865b738f0) + QEvent (0x0x7ff865ba73c0) 0 + primary-for QInputEvent (0x0x7ff865b73958) + +Vtable for QTabletEvent +QTabletEvent::_ZTV12QTabletEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QTabletEvent) +16 (int (*)(...))QTabletEvent::~QTabletEvent +24 (int (*)(...))QTabletEvent::~QTabletEvent + +Class QTabletEvent + size=128 align=8 + base size=128 base align=8 +QTabletEvent (0x0x7ff865b739c0) 0 + vptr=((& QTabletEvent::_ZTV12QTabletEvent) + 16u) + QInputEvent (0x0x7ff865b73a28) 0 + primary-for QTabletEvent (0x0x7ff865b739c0) + QEvent (0x0x7ff865ba7420) 0 + primary-for QInputEvent (0x0x7ff865b73a28) + +Vtable for QNativeGestureEvent +QNativeGestureEvent::_ZTV19QNativeGestureEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QNativeGestureEvent) +16 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent +24 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent + +Class QNativeGestureEvent + size=112 align=8 + base size=112 base align=8 +QNativeGestureEvent (0x0x7ff865b73a90) 0 + vptr=((& QNativeGestureEvent::_ZTV19QNativeGestureEvent) + 16u) + QInputEvent (0x0x7ff865b73af8) 0 + primary-for QNativeGestureEvent (0x0x7ff865b73a90) + QEvent (0x0x7ff865ba7480) 0 + primary-for QInputEvent (0x0x7ff865b73af8) + +Vtable for QKeyEvent +QKeyEvent::_ZTV9QKeyEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QKeyEvent) +16 (int (*)(...))QKeyEvent::~QKeyEvent +24 (int (*)(...))QKeyEvent::~QKeyEvent + +Class QKeyEvent + size=64 align=8 + base size=59 base align=8 +QKeyEvent (0x0x7ff865b73b60) 0 + vptr=((& QKeyEvent::_ZTV9QKeyEvent) + 16u) + QInputEvent (0x0x7ff865b73bc8) 0 + primary-for QKeyEvent (0x0x7ff865b73b60) + QEvent (0x0x7ff865ba74e0) 0 + primary-for QInputEvent (0x0x7ff865b73bc8) + +Vtable for QFocusEvent +QFocusEvent::_ZTV11QFocusEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFocusEvent) +16 (int (*)(...))QFocusEvent::~QFocusEvent +24 (int (*)(...))QFocusEvent::~QFocusEvent + +Class QFocusEvent + size=24 align=8 + base size=24 base align=8 +QFocusEvent (0x0x7ff865b73c30) 0 + vptr=((& QFocusEvent::_ZTV11QFocusEvent) + 16u) + QEvent (0x0x7ff865ba7540) 0 + primary-for QFocusEvent (0x0x7ff865b73c30) + +Vtable for QPaintEvent +QPaintEvent::_ZTV11QPaintEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QPaintEvent) +16 (int (*)(...))QPaintEvent::~QPaintEvent +24 (int (*)(...))QPaintEvent::~QPaintEvent + +Class QPaintEvent + size=56 align=8 + base size=49 base align=8 +QPaintEvent (0x0x7ff865b73c98) 0 + vptr=((& QPaintEvent::_ZTV11QPaintEvent) + 16u) + QEvent (0x0x7ff865ba75a0) 0 + primary-for QPaintEvent (0x0x7ff865b73c98) + +Vtable for QMoveEvent +QMoveEvent::_ZTV10QMoveEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QMoveEvent) +16 (int (*)(...))QMoveEvent::~QMoveEvent +24 (int (*)(...))QMoveEvent::~QMoveEvent + +Class QMoveEvent + size=40 align=8 + base size=36 base align=8 +QMoveEvent (0x0x7ff865b73d00) 0 + vptr=((& QMoveEvent::_ZTV10QMoveEvent) + 16u) + QEvent (0x0x7ff865ba7600) 0 + primary-for QMoveEvent (0x0x7ff865b73d00) + +Vtable for QExposeEvent +QExposeEvent::_ZTV12QExposeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QExposeEvent) +16 (int (*)(...))QExposeEvent::~QExposeEvent +24 (int (*)(...))QExposeEvent::~QExposeEvent + +Class QExposeEvent + size=32 align=8 + base size=32 base align=8 +QExposeEvent (0x0x7ff865b73d68) 0 + vptr=((& QExposeEvent::_ZTV12QExposeEvent) + 16u) + QEvent (0x0x7ff865ba7660) 0 + primary-for QExposeEvent (0x0x7ff865b73d68) + +Vtable for QPlatformSurfaceEvent +QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QPlatformSurfaceEvent) +16 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent +24 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent + +Class QPlatformSurfaceEvent + size=24 align=8 + base size=24 base align=8 +QPlatformSurfaceEvent (0x0x7ff865b73dd0) 0 + vptr=((& QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent) + 16u) + QEvent (0x0x7ff865ba76c0) 0 + primary-for QPlatformSurfaceEvent (0x0x7ff865b73dd0) + +Vtable for QResizeEvent +QResizeEvent::_ZTV12QResizeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QResizeEvent) +16 (int (*)(...))QResizeEvent::~QResizeEvent +24 (int (*)(...))QResizeEvent::~QResizeEvent + +Class QResizeEvent + size=40 align=8 + base size=36 base align=8 +QResizeEvent (0x0x7ff865b73e38) 0 + vptr=((& QResizeEvent::_ZTV12QResizeEvent) + 16u) + QEvent (0x0x7ff865ba7720) 0 + primary-for QResizeEvent (0x0x7ff865b73e38) + +Vtable for QCloseEvent +QCloseEvent::_ZTV11QCloseEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QCloseEvent) +16 (int (*)(...))QCloseEvent::~QCloseEvent +24 (int (*)(...))QCloseEvent::~QCloseEvent + +Class QCloseEvent + size=24 align=8 + base size=20 base align=8 +QCloseEvent (0x0x7ff865b73ea0) 0 + vptr=((& QCloseEvent::_ZTV11QCloseEvent) + 16u) + QEvent (0x0x7ff865ba7780) 0 + primary-for QCloseEvent (0x0x7ff865b73ea0) + +Vtable for QIconDragEvent +QIconDragEvent::_ZTV14QIconDragEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QIconDragEvent) +16 (int (*)(...))QIconDragEvent::~QIconDragEvent +24 (int (*)(...))QIconDragEvent::~QIconDragEvent + +Class QIconDragEvent + size=24 align=8 + base size=20 base align=8 +QIconDragEvent (0x0x7ff865b73f08) 0 + vptr=((& QIconDragEvent::_ZTV14QIconDragEvent) + 16u) + QEvent (0x0x7ff865ba77e0) 0 + primary-for QIconDragEvent (0x0x7ff865b73f08) + +Vtable for QShowEvent +QShowEvent::_ZTV10QShowEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QShowEvent) +16 (int (*)(...))QShowEvent::~QShowEvent +24 (int (*)(...))QShowEvent::~QShowEvent + +Class QShowEvent + size=24 align=8 + base size=20 base align=8 +QShowEvent (0x0x7ff865b73f70) 0 + vptr=((& QShowEvent::_ZTV10QShowEvent) + 16u) + QEvent (0x0x7ff865ba7840) 0 + primary-for QShowEvent (0x0x7ff865b73f70) + +Vtable for QHideEvent +QHideEvent::_ZTV10QHideEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QHideEvent) +16 (int (*)(...))QHideEvent::~QHideEvent +24 (int (*)(...))QHideEvent::~QHideEvent + +Class QHideEvent + size=24 align=8 + base size=20 base align=8 +QHideEvent (0x0x7ff8658c9000) 0 + vptr=((& QHideEvent::_ZTV10QHideEvent) + 16u) + QEvent (0x0x7ff865ba78a0) 0 + primary-for QHideEvent (0x0x7ff8658c9000) + +Vtable for QContextMenuEvent +QContextMenuEvent::_ZTV17QContextMenuEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QContextMenuEvent) +16 (int (*)(...))QContextMenuEvent::~QContextMenuEvent +24 (int (*)(...))QContextMenuEvent::~QContextMenuEvent + +Class QContextMenuEvent + size=56 align=8 + base size=49 base align=8 +QContextMenuEvent (0x0x7ff8658c9068) 0 + vptr=((& QContextMenuEvent::_ZTV17QContextMenuEvent) + 16u) + QInputEvent (0x0x7ff8658c90d0) 0 + primary-for QContextMenuEvent (0x0x7ff8658c9068) + QEvent (0x0x7ff865ba7900) 0 + primary-for QInputEvent (0x0x7ff8658c90d0) + +Class QInputMethodEvent::Attribute + size=32 align=8 + base size=32 base align=8 +QInputMethodEvent::Attribute (0x0x7ff865ba79c0) 0 + +Vtable for QInputMethodEvent +QInputMethodEvent::_ZTV17QInputMethodEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QInputMethodEvent) +16 (int (*)(...))QInputMethodEvent::~QInputMethodEvent +24 (int (*)(...))QInputMethodEvent::~QInputMethodEvent + +Class QInputMethodEvent + size=56 align=8 + base size=56 base align=8 +QInputMethodEvent (0x0x7ff8658c9138) 0 + vptr=((& QInputMethodEvent::_ZTV17QInputMethodEvent) + 16u) + QEvent (0x0x7ff865ba7960) 0 + primary-for QInputMethodEvent (0x0x7ff8658c9138) + +Class QInputMethodQueryEvent::QueryPair + size=24 align=8 + base size=24 base align=8 +QInputMethodQueryEvent::QueryPair (0x0x7ff865ba7e40) 0 + +Vtable for QInputMethodQueryEvent +QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QInputMethodQueryEvent) +16 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent +24 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent + +Class QInputMethodQueryEvent + size=32 align=8 + base size=32 base align=8 +QInputMethodQueryEvent (0x0x7ff8658c9478) 0 + vptr=((& QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent) + 16u) + QEvent (0x0x7ff865ba7de0) 0 + primary-for QInputMethodQueryEvent (0x0x7ff8658c9478) + +Vtable for QDropEvent +QDropEvent::_ZTV10QDropEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QDropEvent) +16 (int (*)(...))QDropEvent::~QDropEvent +24 (int (*)(...))QDropEvent::~QDropEvent + +Class QDropEvent + size=72 align=8 + base size=72 base align=8 +QDropEvent (0x0x7ff8658c9750) 0 + vptr=((& QDropEvent::_ZTV10QDropEvent) + 16u) + QEvent (0x0x7ff86595a1e0) 0 + primary-for QDropEvent (0x0x7ff8658c9750) + +Vtable for QDragMoveEvent +QDragMoveEvent::_ZTV14QDragMoveEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QDragMoveEvent) +16 (int (*)(...))QDragMoveEvent::~QDragMoveEvent +24 (int (*)(...))QDragMoveEvent::~QDragMoveEvent + +Class QDragMoveEvent + size=88 align=8 + base size=88 base align=8 +QDragMoveEvent (0x0x7ff8658c97b8) 0 + vptr=((& QDragMoveEvent::_ZTV14QDragMoveEvent) + 16u) + QDropEvent (0x0x7ff8658c9820) 0 + primary-for QDragMoveEvent (0x0x7ff8658c97b8) + QEvent (0x0x7ff86595a240) 0 + primary-for QDropEvent (0x0x7ff8658c9820) + +Vtable for QDragEnterEvent +QDragEnterEvent::_ZTV15QDragEnterEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QDragEnterEvent) +16 (int (*)(...))QDragEnterEvent::~QDragEnterEvent +24 (int (*)(...))QDragEnterEvent::~QDragEnterEvent + +Class QDragEnterEvent + size=88 align=8 + base size=88 base align=8 +QDragEnterEvent (0x0x7ff8658c9888) 0 + vptr=((& QDragEnterEvent::_ZTV15QDragEnterEvent) + 16u) + QDragMoveEvent (0x0x7ff8658c98f0) 0 + primary-for QDragEnterEvent (0x0x7ff8658c9888) + QDropEvent (0x0x7ff8658c9958) 0 + primary-for QDragMoveEvent (0x0x7ff8658c98f0) + QEvent (0x0x7ff86595a2a0) 0 + primary-for QDropEvent (0x0x7ff8658c9958) + +Vtable for QDragLeaveEvent +QDragLeaveEvent::_ZTV15QDragLeaveEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QDragLeaveEvent) +16 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent +24 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent + +Class QDragLeaveEvent + size=24 align=8 + base size=20 base align=8 +QDragLeaveEvent (0x0x7ff8658c99c0) 0 + vptr=((& QDragLeaveEvent::_ZTV15QDragLeaveEvent) + 16u) + QEvent (0x0x7ff86595a300) 0 + primary-for QDragLeaveEvent (0x0x7ff8658c99c0) + +Vtable for QHelpEvent +QHelpEvent::_ZTV10QHelpEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QHelpEvent) +16 (int (*)(...))QHelpEvent::~QHelpEvent +24 (int (*)(...))QHelpEvent::~QHelpEvent + +Class QHelpEvent + size=40 align=8 + base size=36 base align=8 +QHelpEvent (0x0x7ff8658c9a28) 0 + vptr=((& QHelpEvent::_ZTV10QHelpEvent) + 16u) + QEvent (0x0x7ff86595a360) 0 + primary-for QHelpEvent (0x0x7ff8658c9a28) + +Vtable for QStatusTipEvent +QStatusTipEvent::_ZTV15QStatusTipEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QStatusTipEvent) +16 (int (*)(...))QStatusTipEvent::~QStatusTipEvent +24 (int (*)(...))QStatusTipEvent::~QStatusTipEvent + +Class QStatusTipEvent + size=32 align=8 + base size=32 base align=8 +QStatusTipEvent (0x0x7ff8658c9a90) 0 + vptr=((& QStatusTipEvent::_ZTV15QStatusTipEvent) + 16u) + QEvent (0x0x7ff86595a3c0) 0 + primary-for QStatusTipEvent (0x0x7ff8658c9a90) + +Vtable for QWhatsThisClickedEvent +QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QWhatsThisClickedEvent) +16 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent +24 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent + +Class QWhatsThisClickedEvent + size=32 align=8 + base size=32 base align=8 +QWhatsThisClickedEvent (0x0x7ff8658c9af8) 0 + vptr=((& QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent) + 16u) + QEvent (0x0x7ff86595a420) 0 + primary-for QWhatsThisClickedEvent (0x0x7ff8658c9af8) + +Vtable for QActionEvent +QActionEvent::_ZTV12QActionEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QActionEvent) +16 (int (*)(...))QActionEvent::~QActionEvent +24 (int (*)(...))QActionEvent::~QActionEvent + +Class QActionEvent + size=40 align=8 + base size=40 base align=8 +QActionEvent (0x0x7ff8658c9b60) 0 + vptr=((& QActionEvent::_ZTV12QActionEvent) + 16u) + QEvent (0x0x7ff86595a480) 0 + primary-for QActionEvent (0x0x7ff8658c9b60) + +Vtable for QFileOpenEvent +QFileOpenEvent::_ZTV14QFileOpenEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QFileOpenEvent) +16 (int (*)(...))QFileOpenEvent::~QFileOpenEvent +24 (int (*)(...))QFileOpenEvent::~QFileOpenEvent + +Class QFileOpenEvent + size=40 align=8 + base size=40 base align=8 +QFileOpenEvent (0x0x7ff8658c9bc8) 0 + vptr=((& QFileOpenEvent::_ZTV14QFileOpenEvent) + 16u) + QEvent (0x0x7ff86595a4e0) 0 + primary-for QFileOpenEvent (0x0x7ff8658c9bc8) + +Vtable for QToolBarChangeEvent +QToolBarChangeEvent::_ZTV19QToolBarChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QToolBarChangeEvent) +16 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent +24 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent + +Class QToolBarChangeEvent + size=24 align=8 + base size=21 base align=8 +QToolBarChangeEvent (0x0x7ff8658c9c30) 0 + vptr=((& QToolBarChangeEvent::_ZTV19QToolBarChangeEvent) + 16u) + QEvent (0x0x7ff86595a540) 0 + primary-for QToolBarChangeEvent (0x0x7ff8658c9c30) + +Vtable for QShortcutEvent +QShortcutEvent::_ZTV14QShortcutEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QShortcutEvent) +16 (int (*)(...))QShortcutEvent::~QShortcutEvent +24 (int (*)(...))QShortcutEvent::~QShortcutEvent + +Class QShortcutEvent + size=40 align=8 + base size=40 base align=8 +QShortcutEvent (0x0x7ff8658c9c98) 0 + vptr=((& QShortcutEvent::_ZTV14QShortcutEvent) + 16u) + QEvent (0x0x7ff86595a5a0) 0 + primary-for QShortcutEvent (0x0x7ff8658c9c98) + +Vtable for QWindowStateChangeEvent +QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QWindowStateChangeEvent) +16 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent +24 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent + +Class QWindowStateChangeEvent + size=32 align=8 + base size=25 base align=8 +QWindowStateChangeEvent (0x0x7ff8658c9d00) 0 + vptr=((& QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent) + 16u) + QEvent (0x0x7ff86595a600) 0 + primary-for QWindowStateChangeEvent (0x0x7ff8658c9d00) + +Class QPointingDeviceUniqueId + size=8 align=8 + base size=8 base align=8 +QPointingDeviceUniqueId (0x0x7ff86595a660) 0 + +Class QTouchEvent::TouchPoint + size=8 align=8 + base size=8 base align=8 +QTouchEvent::TouchPoint (0x0x7ff86595ad20) 0 + +Vtable for QTouchEvent +QTouchEvent::_ZTV11QTouchEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTouchEvent) +16 (int (*)(...))QTouchEvent::~QTouchEvent +24 (int (*)(...))QTouchEvent::~QTouchEvent + +Class QTouchEvent + size=72 align=8 + base size=72 base align=8 +QTouchEvent (0x0x7ff8659ba3a8) 0 + vptr=((& QTouchEvent::_ZTV11QTouchEvent) + 16u) + QInputEvent (0x0x7ff8659ba410) 0 + primary-for QTouchEvent (0x0x7ff8659ba3a8) + QEvent (0x0x7ff86595acc0) 0 + primary-for QInputEvent (0x0x7ff8659ba410) + +Vtable for QScrollPrepareEvent +QScrollPrepareEvent::_ZTV19QScrollPrepareEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QScrollPrepareEvent) +16 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent +24 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent + +Class QScrollPrepareEvent + size=112 align=8 + base size=112 base align=8 +QScrollPrepareEvent (0x0x7ff86567ac30) 0 + vptr=((& QScrollPrepareEvent::_ZTV19QScrollPrepareEvent) + 16u) + QEvent (0x0x7ff8656923c0) 0 + primary-for QScrollPrepareEvent (0x0x7ff86567ac30) + +Vtable for QScrollEvent +QScrollEvent::_ZTV12QScrollEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QScrollEvent) +16 (int (*)(...))QScrollEvent::~QScrollEvent +24 (int (*)(...))QScrollEvent::~QScrollEvent + +Class QScrollEvent + size=64 align=8 + base size=60 base align=8 +QScrollEvent (0x0x7ff86567ac98) 0 + vptr=((& QScrollEvent::_ZTV12QScrollEvent) + 16u) + QEvent (0x0x7ff865692420) 0 + primary-for QScrollEvent (0x0x7ff86567ac98) + +Vtable for QScreenOrientationChangeEvent +QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QScreenOrientationChangeEvent) +16 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent +24 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent + +Class QScreenOrientationChangeEvent + size=40 align=8 + base size=36 base align=8 +QScreenOrientationChangeEvent (0x0x7ff86567ad00) 0 + vptr=((& QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent) + 16u) + QEvent (0x0x7ff865692480) 0 + primary-for QScreenOrientationChangeEvent (0x0x7ff86567ad00) + +Vtable for QApplicationStateChangeEvent +QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QApplicationStateChangeEvent) +16 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent +24 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent + +Class QApplicationStateChangeEvent + size=24 align=8 + base size=24 base align=8 +QApplicationStateChangeEvent (0x0x7ff86567ad68) 0 + vptr=((& QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent) + 16u) + QEvent (0x0x7ff8656924e0) 0 + primary-for QApplicationStateChangeEvent (0x0x7ff86567ad68) + +Class QFont + size=16 align=8 + base size=12 base align=8 +QFont (0x0x7ff865692540) 0 + +Class QPolygon + size=8 align=8 + base size=8 base align=8 +QPolygon (0x0x7ff86572faf8) 0 + QVector (0x0x7ff865746240) 0 + +Class QPolygonF + size=8 align=8 + base size=8 base align=8 +QPolygonF (0x0x7ff86572fea0) 0 + QVector (0x0x7ff8657466c0) 0 + +Class QMatrix + size=48 align=8 + base size=48 base align=8 +QMatrix (0x0x7ff865746a80) 0 + +Class QPainterPath::Element + size=24 align=8 + base size=24 base align=8 +QPainterPath::Element (0x0x7ff865746d80) 0 + +Class QPainterPath + size=8 align=8 + base size=8 base align=8 +QPainterPath (0x0x7ff865746d20) 0 + +Class QPainterPathStroker + size=8 align=8 + base size=8 base align=8 +QPainterPathStroker (0x0x7ff86548d780) 0 + +Class QTransform + size=88 align=8 + base size=88 base align=8 +QTransform (0x0x7ff86548d8a0) 0 + +Vtable for QPaintDevice +QPaintDevice::_ZTV12QPaintDevice: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QPaintDevice) +16 0u +24 0u +32 (int (*)(...))QPaintDevice::devType +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QPaintDevice + size=24 align=8 + base size=24 base align=8 +QPaintDevice (0x0x7ff865576000) 0 + vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 16u) + +Class QPixelFormat + size=8 align=8 + base size=8 base align=8 +QPixelFormat (0x0x7ff865576060) 0 + +Vtable for QImage +QImage::_ZTV6QImage: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QImage) +16 (int (*)(...))QImage::~QImage +24 (int (*)(...))QImage::~QImage +32 (int (*)(...))QImage::devType +40 (int (*)(...))QImage::paintEngine +48 (int (*)(...))QImage::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QImage + size=32 align=8 + base size=32 base align=8 +QImage (0x0x7ff865527d68) 0 + vptr=((& QImage::_ZTV6QImage) + 16u) + QPaintDevice (0x0x7ff865576ae0) 0 + primary-for QImage (0x0x7ff865527d68) + +Vtable for QPixmap +QPixmap::_ZTV7QPixmap: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QPixmap) +16 (int (*)(...))QPixmap::~QPixmap +24 (int (*)(...))QPixmap::~QPixmap +32 (int (*)(...))QPixmap::devType +40 (int (*)(...))QPixmap::paintEngine +48 (int (*)(...))QPixmap::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QPixmap + size=32 align=8 + base size=32 base align=8 +QPixmap (0x0x7ff8652c48f0) 0 + vptr=((& QPixmap::_ZTV7QPixmap) + 16u) + QPaintDevice (0x0x7ff8652b7a80) 0 + primary-for QPixmap (0x0x7ff8652c48f0) + +Class QBrush + size=8 align=8 + base size=8 base align=8 +QBrush (0x0x7ff8652b7d80) 0 + +Class QBrushData + size=112 align=8 + base size=112 base align=8 +QBrushData (0x0x7ff86534f540) 0 + +Class QGradient + size=64 align=8 + base size=64 base align=8 +QGradient (0x0x7ff86534f5a0) 0 + +Class QLinearGradient + size=64 align=8 + base size=64 base align=8 +QLinearGradient (0x0x7ff865358270) 0 + QGradient (0x0x7ff86534f840) 0 + +Class QRadialGradient + size=64 align=8 + base size=64 base align=8 +QRadialGradient (0x0x7ff8653582d8) 0 + QGradient (0x0x7ff86534f8a0) 0 + +Class QConicalGradient + size=64 align=8 + base size=64 base align=8 +QConicalGradient (0x0x7ff865358340) 0 + QGradient (0x0x7ff86534f900) 0 + +Class QPen + size=8 align=8 + base size=8 base align=8 +QPen (0x0x7ff86534f960) 0 + +Class QTextOption::Tab + size=16 align=8 + base size=14 base align=8 +QTextOption::Tab (0x0x7ff865040ba0) 0 + +Class QTextOption + size=32 align=8 + base size=32 base align=8 +QTextOption (0x0x7ff865040b40) 0 + +Class QTextLength + size=16 align=8 + base size=16 base align=8 +QTextLength (0x0x7ff86507b360) 0 + +Class QTextFormat + size=16 align=8 + base size=12 base align=8 +QTextFormat (0x0x7ff86507ba80) 0 + +Class QTextCharFormat + size=16 align=8 + base size=12 base align=8 +QTextCharFormat (0x0x7ff8651ab270) 0 + QTextFormat (0x0x7ff865149900) 0 + +Class QTextBlockFormat + size=16 align=8 + base size=12 base align=8 +QTextBlockFormat (0x0x7ff8651ab478) 0 + QTextFormat (0x0x7ff865149ba0) 0 + +Class QTextListFormat + size=16 align=8 + base size=12 base align=8 +QTextListFormat (0x0x7ff8651ab6e8) 0 + QTextFormat (0x0x7ff865149e40) 0 + +Class QTextImageFormat + size=16 align=8 + base size=12 base align=8 +QTextImageFormat (0x0x7ff8651ab8f0) 0 + QTextCharFormat (0x0x7ff8651ab958) 0 + QTextFormat (0x0x7ff864e59120) 0 + +Class QTextFrameFormat + size=16 align=8 + base size=12 base align=8 +QTextFrameFormat (0x0x7ff8651abb60) 0 + QTextFormat (0x0x7ff864e593c0) 0 + +Class QTextTableFormat + size=16 align=8 + base size=12 base align=8 +QTextTableFormat (0x0x7ff8651abd68) 0 + QTextFrameFormat (0x0x7ff8651abdd0) 0 + QTextFormat (0x0x7ff864e59660) 0 + +Class QTextTableCellFormat + size=16 align=8 + base size=12 base align=8 +QTextTableCellFormat (0x0x7ff864ec1000) 0 + QTextCharFormat (0x0x7ff864ec1068) 0 + QTextFormat (0x0x7ff864e59960) 0 + +Class QFontDatabase + size=8 align=8 + base size=8 base align=8 +QFontDatabase (0x0x7ff864e59c00) 0 + +Class QRawFont + size=8 align=8 + base size=8 base align=8 +QRawFont (0x0x7ff864e59c60) 0 + +Class QGlyphRun + size=8 align=8 + base size=8 base align=8 +QGlyphRun (0x0x7ff864f1c180) 0 + +Class QTextCursor + size=8 align=8 + base size=8 base align=8 +QTextCursor (0x0x7ff864f1c480) 0 + +Class QTextInlineObject + size=16 align=8 + base size=16 base align=8 +QTextInlineObject (0x0x7ff864f1c780) 0 + +Class QTextLayout::FormatRange + size=24 align=8 + base size=24 base align=8 +QTextLayout::FormatRange (0x0x7ff864f1c840) 0 + +Class QTextLayout + size=8 align=8 + base size=8 base align=8 +QTextLayout (0x0x7ff864f1c7e0) 0 + +Class QTextLine + size=16 align=8 + base size=16 base align=8 +QTextLine (0x0x7ff864c082a0) 0 + +Vtable for QAbstractUndoItem +QAbstractUndoItem::_ZTV17QAbstractUndoItem: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAbstractUndoItem) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QAbstractUndoItem + size=8 align=8 + base size=8 base align=8 +QAbstractUndoItem (0x0x7ff864c08300) 0 nearly-empty + vptr=((& QAbstractUndoItem::_ZTV17QAbstractUndoItem) + 16u) + +Class QTextDocument::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextDocument::QPrivateSignal (0x0x7ff864c083c0) 0 empty + +Vtable for QTextDocument +QTextDocument::_ZTV13QTextDocument: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QTextDocument) +16 (int (*)(...))QTextDocument::metaObject +24 (int (*)(...))QTextDocument::qt_metacast +32 (int (*)(...))QTextDocument::qt_metacall +40 (int (*)(...))QTextDocument::~QTextDocument +48 (int (*)(...))QTextDocument::~QTextDocument +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextDocument::clear +120 (int (*)(...))QTextDocument::createObject +128 (int (*)(...))QTextDocument::loadResource + +Class QTextDocument + size=16 align=8 + base size=16 base align=8 +QTextDocument (0x0x7ff864c073a8) 0 + vptr=((& QTextDocument::_ZTV13QTextDocument) + 16u) + QObject (0x0x7ff864c08360) 0 + primary-for QTextDocument (0x0x7ff864c073a8) + +Class QPalette::Data + size=4 align=4 + base size=4 base align=4 +QPalette::Data (0x0x7ff864c08600) 0 + +Class QPalette + size=16 align=8 + base size=12 base align=8 +QPalette (0x0x7ff864c085a0) 0 + +Class QAbstractTextDocumentLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTextDocumentLayout::QPrivateSignal (0x0x7ff864d286c0) 0 empty + +Class QAbstractTextDocumentLayout::Selection + size=24 align=8 + base size=24 base align=8 +QAbstractTextDocumentLayout::Selection (0x0x7ff864d28720) 0 + +Class QAbstractTextDocumentLayout::PaintContext + size=64 align=8 + base size=64 base align=8 +QAbstractTextDocumentLayout::PaintContext (0x0x7ff864d28780) 0 + +Vtable for QAbstractTextDocumentLayout +QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAbstractTextDocumentLayout) +16 (int (*)(...))QAbstractTextDocumentLayout::metaObject +24 (int (*)(...))QAbstractTextDocumentLayout::qt_metacast +32 (int (*)(...))QAbstractTextDocumentLayout::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractTextDocumentLayout::resizeInlineObject +176 (int (*)(...))QAbstractTextDocumentLayout::positionInlineObject +184 (int (*)(...))QAbstractTextDocumentLayout::drawInlineObject + +Class QAbstractTextDocumentLayout + size=16 align=8 + base size=16 base align=8 +QAbstractTextDocumentLayout (0x0x7ff864d4a0d0) 0 + vptr=((& QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout) + 16u) + QObject (0x0x7ff864d28660) 0 + primary-for QAbstractTextDocumentLayout (0x0x7ff864d4a0d0) + +Vtable for QTextObjectInterface +QTextObjectInterface::_ZTV20QTextObjectInterface: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTextObjectInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QTextObjectInterface + size=8 align=8 + base size=8 base align=8 +QTextObjectInterface (0x0x7ff864d28d20) 0 nearly-empty + vptr=((& QTextObjectInterface::_ZTV20QTextObjectInterface) + 16u) + +Class QAccessible::State + size=8 align=8 + base size=5 base align=8 +QAccessible::State (0x0x7ff864d28e40) 0 + +Vtable for QAccessible::ActivationObserver +QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN11QAccessible18ActivationObserverE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAccessible::ActivationObserver + size=8 align=8 + base size=8 base align=8 +QAccessible::ActivationObserver (0x0x7ff864d28ea0) 0 nearly-empty + vptr=((& QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE) + 16u) + +Class QAccessible + size=1 align=1 + base size=0 base align=1 +QAccessible (0x0x7ff864d28de0) 0 empty + +Vtable for QAccessibleInterface +QAccessibleInterface::_ZTV20QAccessibleInterface: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QAccessibleInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QAccessibleInterface::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleInterface::focusChild +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleInterface (0x0x7ff8649df0c0) 0 nearly-empty + vptr=((& QAccessibleInterface::_ZTV20QAccessibleInterface) + 16u) + +Vtable for QAccessibleTextInterface +QAccessibleTextInterface::_ZTV24QAccessibleTextInterface: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAccessibleTextInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))QAccessibleTextInterface::textBeforeOffset +104 (int (*)(...))QAccessibleTextInterface::textAfterOffset +112 (int (*)(...))QAccessibleTextInterface::textAtOffset +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTextInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTextInterface (0x0x7ff8649df120) 0 nearly-empty + vptr=((& QAccessibleTextInterface::_ZTV24QAccessibleTextInterface) + 16u) + +Vtable for QAccessibleEditableTextInterface +QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI32QAccessibleEditableTextInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleEditableTextInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleEditableTextInterface (0x0x7ff8649df180) 0 nearly-empty + vptr=((& QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface) + 16u) + +Vtable for QAccessibleValueInterface +QAccessibleValueInterface::_ZTV25QAccessibleValueInterface: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleValueInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleValueInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleValueInterface (0x0x7ff8649df1e0) 0 nearly-empty + vptr=((& QAccessibleValueInterface::_ZTV25QAccessibleValueInterface) + 16u) + +Vtable for QAccessibleTableCellInterface +QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface: 12u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QAccessibleTableCellInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTableCellInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTableCellInterface (0x0x7ff8649df240) 0 nearly-empty + vptr=((& QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface) + 16u) + +Vtable for QAccessibleTableInterface +QAccessibleTableInterface::_ZTV25QAccessibleTableInterface: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleTableInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTableInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTableInterface (0x0x7ff8649df2a0) 0 nearly-empty + vptr=((& QAccessibleTableInterface::_ZTV25QAccessibleTableInterface) + 16u) + +Vtable for QAccessibleActionInterface +QAccessibleActionInterface::_ZTV26QAccessibleActionInterface: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleActionInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QAccessibleActionInterface::localizedActionName +48 (int (*)(...))QAccessibleActionInterface::localizedActionDescription +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleActionInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleActionInterface (0x0x7ff8649df300) 0 nearly-empty + vptr=((& QAccessibleActionInterface::_ZTV26QAccessibleActionInterface) + 16u) + +Vtable for QAccessibleImageInterface +QAccessibleImageInterface::_ZTV25QAccessibleImageInterface: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleImageInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleImageInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleImageInterface (0x0x7ff8649df360) 0 nearly-empty + vptr=((& QAccessibleImageInterface::_ZTV25QAccessibleImageInterface) + 16u) + +Vtable for QAccessibleEvent +QAccessibleEvent::_ZTV16QAccessibleEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAccessibleEvent) +16 (int (*)(...))QAccessibleEvent::~QAccessibleEvent +24 (int (*)(...))QAccessibleEvent::~QAccessibleEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleEvent + size=32 align=8 + base size=28 base align=8 +QAccessibleEvent (0x0x7ff8649df3c0) 0 + vptr=((& QAccessibleEvent::_ZTV16QAccessibleEvent) + 16u) + +Vtable for QAccessibleStateChangeEvent +QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAccessibleStateChangeEvent) +16 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent +24 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleStateChangeEvent + size=40 align=8 + base size=40 base align=8 +QAccessibleStateChangeEvent (0x0x7ff864d4aaf8) 0 + vptr=((& QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent) + 16u) + QAccessibleEvent (0x0x7ff8649df900) 0 + primary-for QAccessibleStateChangeEvent (0x0x7ff864d4aaf8) + +Vtable for QAccessibleTextCursorEvent +QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextCursorEvent) +16 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent +24 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextCursorEvent + size=32 align=8 + base size=32 base align=8 +QAccessibleTextCursorEvent (0x0x7ff864d4ab60) 0 + vptr=((& QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent) + 16u) + QAccessibleEvent (0x0x7ff8649df960) 0 + primary-for QAccessibleTextCursorEvent (0x0x7ff864d4ab60) + +Vtable for QAccessibleTextSelectionEvent +QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QAccessibleTextSelectionEvent) +16 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent +24 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextSelectionEvent + size=40 align=8 + base size=40 base align=8 +QAccessibleTextSelectionEvent (0x0x7ff864d4abc8) 0 + vptr=((& QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7ff864d4ac30) 0 + primary-for QAccessibleTextSelectionEvent (0x0x7ff864d4abc8) + QAccessibleEvent (0x0x7ff8649df9c0) 0 + primary-for QAccessibleTextCursorEvent (0x0x7ff864d4ac30) + +Vtable for QAccessibleTextInsertEvent +QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextInsertEvent) +16 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent +24 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextInsertEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTextInsertEvent (0x0x7ff864d4ac98) 0 + vptr=((& QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7ff864d4ad00) 0 + primary-for QAccessibleTextInsertEvent (0x0x7ff864d4ac98) + QAccessibleEvent (0x0x7ff8649dfa20) 0 + primary-for QAccessibleTextCursorEvent (0x0x7ff864d4ad00) + +Vtable for QAccessibleTextRemoveEvent +QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextRemoveEvent) +16 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent +24 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextRemoveEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTextRemoveEvent (0x0x7ff864d4ad68) 0 + vptr=((& QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7ff864d4add0) 0 + primary-for QAccessibleTextRemoveEvent (0x0x7ff864d4ad68) + QAccessibleEvent (0x0x7ff8649dfa80) 0 + primary-for QAccessibleTextCursorEvent (0x0x7ff864d4add0) + +Vtable for QAccessibleTextUpdateEvent +QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextUpdateEvent) +16 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent +24 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextUpdateEvent + size=56 align=8 + base size=56 base align=8 +QAccessibleTextUpdateEvent (0x0x7ff864d4ae38) 0 + vptr=((& QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7ff864d4aea0) 0 + primary-for QAccessibleTextUpdateEvent (0x0x7ff864d4ae38) + QAccessibleEvent (0x0x7ff8649dfae0) 0 + primary-for QAccessibleTextCursorEvent (0x0x7ff864d4aea0) + +Vtable for QAccessibleValueChangeEvent +QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAccessibleValueChangeEvent) +16 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent +24 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleValueChangeEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleValueChangeEvent (0x0x7ff864d4af08) 0 + vptr=((& QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent) + 16u) + QAccessibleEvent (0x0x7ff8649dfb40) 0 + primary-for QAccessibleValueChangeEvent (0x0x7ff864d4af08) + +Vtable for QAccessibleTableModelChangeEvent +QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI32QAccessibleTableModelChangeEvent) +16 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent +24 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTableModelChangeEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTableModelChangeEvent (0x0x7ff864d4af70) 0 + vptr=((& QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent) + 16u) + QAccessibleEvent (0x0x7ff8649dfba0) 0 + primary-for QAccessibleTableModelChangeEvent (0x0x7ff864d4af70) + +Vtable for QAccessibleBridge +QAccessibleBridge::_ZTV17QAccessibleBridge: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleBridge) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleBridge + size=8 align=8 + base size=8 base align=8 +QAccessibleBridge (0x0x7ff8649dfc60) 0 nearly-empty + vptr=((& QAccessibleBridge::_ZTV17QAccessibleBridge) + 16u) + +Class QAccessibleBridgePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAccessibleBridgePlugin::QPrivateSignal (0x0x7ff8649dfd20) 0 empty + +Vtable for QAccessibleBridgePlugin +QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QAccessibleBridgePlugin) +16 (int (*)(...))QAccessibleBridgePlugin::metaObject +24 (int (*)(...))QAccessibleBridgePlugin::qt_metacast +32 (int (*)(...))QAccessibleBridgePlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleBridgePlugin + size=16 align=8 + base size=16 base align=8 +QAccessibleBridgePlugin (0x0x7ff864b1c000) 0 + vptr=((& QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin) + 16u) + QObject (0x0x7ff8649dfcc0) 0 + primary-for QAccessibleBridgePlugin (0x0x7ff864b1c000) + +Vtable for QAccessibleObject +QAccessibleObject::_ZTV17QAccessibleObject: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleObject) +16 0u +24 0u +32 (int (*)(...))QAccessibleObject::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleInterface::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleInterface::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleObject::rect +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleObject + size=16 align=8 + base size=16 base align=8 +QAccessibleObject (0x0x7ff864b1c068) 0 + vptr=((& QAccessibleObject::_ZTV17QAccessibleObject) + 16u) + QAccessibleInterface (0x0x7ff8649dfd80) 0 nearly-empty + primary-for QAccessibleObject (0x0x7ff864b1c068) + +Vtable for QAccessibleApplication +QAccessibleApplication::_ZTV22QAccessibleApplication: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QAccessibleApplication) +16 (int (*)(...))QAccessibleApplication::~QAccessibleApplication +24 (int (*)(...))QAccessibleApplication::~QAccessibleApplication +32 (int (*)(...))QAccessibleObject::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleApplication::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleApplication::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))QAccessibleApplication::parent +88 (int (*)(...))QAccessibleApplication::child +96 (int (*)(...))QAccessibleApplication::childCount +104 (int (*)(...))QAccessibleApplication::indexOfChild +112 (int (*)(...))QAccessibleApplication::text +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleObject::rect +136 (int (*)(...))QAccessibleApplication::role +144 (int (*)(...))QAccessibleApplication::state +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleApplication + size=16 align=8 + base size=16 base align=8 +QAccessibleApplication (0x0x7ff864b1c0d0) 0 + vptr=((& QAccessibleApplication::_ZTV22QAccessibleApplication) + 16u) + QAccessibleObject (0x0x7ff864b1c138) 0 + primary-for QAccessibleApplication (0x0x7ff864b1c0d0) + QAccessibleInterface (0x0x7ff8649dfde0) 0 nearly-empty + primary-for QAccessibleObject (0x0x7ff864b1c138) + +Class QAccessiblePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAccessiblePlugin::QPrivateSignal (0x0x7ff8649dfea0) 0 empty + +Vtable for QAccessiblePlugin +QAccessiblePlugin::_ZTV17QAccessiblePlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessiblePlugin) +16 (int (*)(...))QAccessiblePlugin::metaObject +24 (int (*)(...))QAccessiblePlugin::qt_metacast +32 (int (*)(...))QAccessiblePlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QAccessiblePlugin + size=16 align=8 + base size=16 base align=8 +QAccessiblePlugin (0x0x7ff864b1c1a0) 0 + vptr=((& QAccessiblePlugin::_ZTV17QAccessiblePlugin) + 16u) + QObject (0x0x7ff8649dfe40) 0 + primary-for QAccessiblePlugin (0x0x7ff864b1c1a0) + +Class QSurfaceFormat + size=8 align=8 + base size=8 base align=8 +QSurfaceFormat (0x0x7ff8649dff00) 0 + +Vtable for QSurface +QSurface::_ZTV8QSurface: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QSurface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual + +Class QSurface + size=24 align=8 + base size=24 base align=8 +QSurface (0x0x7ff864b68120) 0 + vptr=((& QSurface::_ZTV8QSurface) + 16u) + +Class QIcon + size=8 align=8 + base size=8 base align=8 +QIcon (0x0x7ff864b682a0) 0 + +Class QCursor + size=8 align=8 + base size=8 base align=8 +QCursor (0x0x7ff86482b660) 0 + +Class QWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWindow::QPrivateSignal (0x0x7ff8648bac60) 0 empty + +Vtable for QWindow +QWindow::_ZTV7QWindow: 45u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QWindow) +16 (int (*)(...))QWindow::metaObject +24 (int (*)(...))QWindow::qt_metacast +32 (int (*)(...))QWindow::qt_metacall +40 (int (*)(...))QWindow::~QWindow +48 (int (*)(...))QWindow::~QWindow +56 (int (*)(...))QWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))-16 +304 (int (*)(...))(& _ZTI7QWindow) +312 (int (*)(...))QWindow::_ZThn16_N7QWindowD1Ev +320 (int (*)(...))QWindow::_ZThn16_N7QWindowD0Ev +328 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +336 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QWindow + size=40 align=8 + base size=40 base align=8 +QWindow (0x0x7ff8648c7700) 0 + vptr=((& QWindow::_ZTV7QWindow) + 16u) + QObject (0x0x7ff8648baba0) 0 + primary-for QWindow (0x0x7ff8648c7700) + QSurface (0x0x7ff8648bac00) 16 + vptr=((& QWindow::_ZTV7QWindow) + 312u) + +Class QBackingStore + size=8 align=8 + base size=8 base align=8 +QBackingStore (0x0x7ff8648bad80) 0 + +Vtable for QBitmap +QBitmap::_ZTV7QBitmap: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBitmap) +16 (int (*)(...))QBitmap::~QBitmap +24 (int (*)(...))QBitmap::~QBitmap +32 (int (*)(...))QPixmap::devType +40 (int (*)(...))QPixmap::paintEngine +48 (int (*)(...))QPixmap::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QBitmap + size=32 align=8 + base size=32 base align=8 +QBitmap (0x0x7ff8648d1208) 0 + vptr=((& QBitmap::_ZTV7QBitmap) + 16u) + QPixmap (0x0x7ff8648d1270) 0 + primary-for QBitmap (0x0x7ff8648d1208) + QPaintDevice (0x0x7ff8648bae40) 0 + primary-for QPixmap (0x0x7ff8648d1270) + +Class QClipboard::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QClipboard::QPrivateSignal (0x0x7ff86494e1e0) 0 empty + +Vtable for QClipboard +QClipboard::_ZTV10QClipboard: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QClipboard) +16 (int (*)(...))QClipboard::metaObject +24 (int (*)(...))QClipboard::qt_metacast +32 (int (*)(...))QClipboard::qt_metacall +40 (int (*)(...))QClipboard::~QClipboard +48 (int (*)(...))QClipboard::~QClipboard +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QClipboard + size=16 align=8 + base size=16 base align=8 +QClipboard (0x0x7ff8648d14e0) 0 + vptr=((& QClipboard::_ZTV10QClipboard) + 16u) + QObject (0x0x7ff86494e180) 0 + primary-for QClipboard (0x0x7ff8648d14e0) + +Class QDesktopServices + size=1 align=1 + base size=0 base align=1 +QDesktopServices (0x0x7ff86494e240) 0 empty + +Class QDrag::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDrag::QPrivateSignal (0x0x7ff86494e300) 0 empty + +Vtable for QDrag +QDrag::_ZTV5QDrag: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QDrag) +16 (int (*)(...))QDrag::metaObject +24 (int (*)(...))QDrag::qt_metacast +32 (int (*)(...))QDrag::qt_metacall +40 (int (*)(...))QDrag::~QDrag +48 (int (*)(...))QDrag::~QDrag +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDrag + size=16 align=8 + base size=16 base align=8 +QDrag (0x0x7ff8648d1548) 0 + vptr=((& QDrag::_ZTV5QDrag) + 16u) + QObject (0x0x7ff86494e2a0) 0 + primary-for QDrag (0x0x7ff8648d1548) + +Class QFontInfo + size=8 align=8 + base size=8 base align=8 +QFontInfo (0x0x7ff86494e360) 0 + +Class QFontMetrics + size=8 align=8 + base size=8 base align=8 +QFontMetrics (0x0x7ff86494e600) 0 + +Class QFontMetricsF + size=8 align=8 + base size=8 base align=8 +QFontMetricsF (0x0x7ff86494e900) 0 + +Class QGenericPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGenericPlugin::QPrivateSignal (0x0x7ff864623de0) 0 empty + +Vtable for QGenericPlugin +QGenericPlugin::_ZTV14QGenericPlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QGenericPlugin) +16 (int (*)(...))QGenericPlugin::metaObject +24 (int (*)(...))QGenericPlugin::qt_metacast +32 (int (*)(...))QGenericPlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QGenericPlugin + size=16 align=8 + base size=16 base align=8 +QGenericPlugin (0x0x7ff8648d1dd0) 0 + vptr=((& QGenericPlugin::_ZTV14QGenericPlugin) + 16u) + QObject (0x0x7ff864623d80) 0 + primary-for QGenericPlugin (0x0x7ff8648d1dd0) + +Class QGenericPluginFactory + size=1 align=1 + base size=0 base align=1 +QGenericPluginFactory (0x0x7ff864623e40) 0 empty + +Class QInputMethod::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QInputMethod::QPrivateSignal (0x0x7ff864623f00) 0 empty + +Vtable for QInputMethod +QInputMethod::_ZTV12QInputMethod: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QInputMethod) +16 (int (*)(...))QInputMethod::metaObject +24 (int (*)(...))QInputMethod::qt_metacast +32 (int (*)(...))QInputMethod::qt_metacall +40 (int (*)(...))QInputMethod::~QInputMethod +48 (int (*)(...))QInputMethod::~QInputMethod +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QInputMethod + size=16 align=8 + base size=16 base align=8 +QInputMethod (0x0x7ff8648d1e38) 0 + vptr=((& QInputMethod::_ZTV12QInputMethod) + 16u) + QObject (0x0x7ff864623ea0) 0 + primary-for QInputMethod (0x0x7ff8648d1e38) + +Class QGuiApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGuiApplication::QPrivateSignal (0x0x7ff864730000) 0 empty + +Vtable for QGuiApplication +QGuiApplication::_ZTV15QGuiApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGuiApplication) +16 (int (*)(...))QGuiApplication::metaObject +24 (int (*)(...))QGuiApplication::qt_metacast +32 (int (*)(...))QGuiApplication::qt_metacall +40 (int (*)(...))QGuiApplication::~QGuiApplication +48 (int (*)(...))QGuiApplication::~QGuiApplication +56 (int (*)(...))QGuiApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGuiApplication::notify +120 (int (*)(...))QGuiApplication::compressEvent + +Class QGuiApplication + size=16 align=8 + base size=16 base align=8 +QGuiApplication (0x0x7ff8648d1ea0) 0 + vptr=((& QGuiApplication::_ZTV15QGuiApplication) + 16u) + QCoreApplication (0x0x7ff8648d1f08) 0 + primary-for QGuiApplication (0x0x7ff8648d1ea0) + QObject (0x0x7ff864623f60) 0 + primary-for QCoreApplication (0x0x7ff8648d1f08) + +Class QIconEngine::AvailableSizesArgument + size=16 align=8 + base size=16 base align=8 +QIconEngine::AvailableSizesArgument (0x0x7ff864730540) 0 + +Class QIconEngine::ScaledPixmapArgument + size=56 align=8 + base size=56 base align=8 +QIconEngine::ScaledPixmapArgument (0x0x7ff8647306c0) 0 + +Vtable for QIconEngine +QIconEngine::_ZTV11QIconEngine: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QIconEngine) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QIconEngine::actualSize +48 (int (*)(...))QIconEngine::pixmap +56 (int (*)(...))QIconEngine::addPixmap +64 (int (*)(...))QIconEngine::addFile +72 (int (*)(...))QIconEngine::key +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QIconEngine::read +96 (int (*)(...))QIconEngine::write +104 (int (*)(...))QIconEngine::availableSizes +112 (int (*)(...))QIconEngine::iconName +120 (int (*)(...))QIconEngine::virtual_hook + +Class QIconEngine + size=8 align=8 + base size=8 base align=8 +QIconEngine (0x0x7ff8647304e0) 0 nearly-empty + vptr=((& QIconEngine::_ZTV11QIconEngine) + 16u) + +Class QIconEnginePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIconEnginePlugin::QPrivateSignal (0x0x7ff864730780) 0 empty + +Vtable for QIconEnginePlugin +QIconEnginePlugin::_ZTV17QIconEnginePlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QIconEnginePlugin) +16 (int (*)(...))QIconEnginePlugin::metaObject +24 (int (*)(...))QIconEnginePlugin::qt_metacast +32 (int (*)(...))QIconEnginePlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QIconEnginePlugin + size=16 align=8 + base size=16 base align=8 +QIconEnginePlugin (0x0x7ff864750478) 0 + vptr=((& QIconEnginePlugin::_ZTV17QIconEnginePlugin) + 16u) + QObject (0x0x7ff864730720) 0 + primary-for QIconEnginePlugin (0x0x7ff864750478) + +Vtable for QImageIOHandler +QImageIOHandler::_ZTV15QImageIOHandler: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QImageIOHandler) +16 0u +24 0u +32 (int (*)(...))QImageIOHandler::name +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))QImageIOHandler::write +64 (int (*)(...))QImageIOHandler::option +72 (int (*)(...))QImageIOHandler::setOption +80 (int (*)(...))QImageIOHandler::supportsOption +88 (int (*)(...))QImageIOHandler::jumpToNextImage +96 (int (*)(...))QImageIOHandler::jumpToImage +104 (int (*)(...))QImageIOHandler::loopCount +112 (int (*)(...))QImageIOHandler::imageCount +120 (int (*)(...))QImageIOHandler::nextImageDelay +128 (int (*)(...))QImageIOHandler::currentImageNumber +136 (int (*)(...))QImageIOHandler::currentImageRect + +Class QImageIOHandler + size=16 align=8 + base size=16 base align=8 +QImageIOHandler (0x0x7ff8647307e0) 0 + vptr=((& QImageIOHandler::_ZTV15QImageIOHandler) + 16u) + +Class QImageIOPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QImageIOPlugin::QPrivateSignal (0x0x7ff864730960) 0 empty + +Vtable for QImageIOPlugin +QImageIOPlugin::_ZTV14QImageIOPlugin: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QImageIOPlugin) +16 (int (*)(...))QImageIOPlugin::metaObject +24 (int (*)(...))QImageIOPlugin::qt_metacast +32 (int (*)(...))QImageIOPlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QImageIOPlugin + size=16 align=8 + base size=16 base align=8 +QImageIOPlugin (0x0x7ff8647504e0) 0 + vptr=((& QImageIOPlugin::_ZTV14QImageIOPlugin) + 16u) + QObject (0x0x7ff864730900) 0 + primary-for QImageIOPlugin (0x0x7ff8647504e0) + +Class QImageReader + size=8 align=8 + base size=8 base align=8 +QImageReader (0x0x7ff864730b40) 0 + +Class QImageWriter + size=8 align=8 + base size=8 base align=8 +QImageWriter (0x0x7ff864730ba0) 0 + +Class QVector3D + size=12 align=4 + base size=12 base align=4 +QVector3D (0x0x7ff864730c00) 0 + +Class QVector4D + size=16 align=4 + base size=16 base align=4 +QVector4D (0x0x7ff864730ea0) 0 + +Class QQuaternion + size=16 align=4 + base size=16 base align=4 +QQuaternion (0x0x7ff86447e180) 0 + +Class QMatrix4x4 + size=68 align=4 + base size=68 base align=4 +QMatrix4x4 (0x0x7ff86447e780) 0 + +Class QMovie::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMovie::QPrivateSignal (0x0x7ff86447ef00) 0 empty + +Vtable for QMovie +QMovie::_ZTV6QMovie: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QMovie) +16 (int (*)(...))QMovie::metaObject +24 (int (*)(...))QMovie::qt_metacast +32 (int (*)(...))QMovie::qt_metacall +40 (int (*)(...))QMovie::~QMovie +48 (int (*)(...))QMovie::~QMovie +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QMovie + size=16 align=8 + base size=16 base align=8 +QMovie (0x0x7ff86455e6e8) 0 + vptr=((& QMovie::_ZTV6QMovie) + 16u) + QObject (0x0x7ff86447eea0) 0 + primary-for QMovie (0x0x7ff86455e6e8) + +Class QOffscreenSurface::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOffscreenSurface::QPrivateSignal (0x0x7ff864285060) 0 empty + +Vtable for QOffscreenSurface +QOffscreenSurface::_ZTV17QOffscreenSurface: 26u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QOffscreenSurface) +16 (int (*)(...))QOffscreenSurface::metaObject +24 (int (*)(...))QOffscreenSurface::qt_metacast +32 (int (*)(...))QOffscreenSurface::qt_metacall +40 (int (*)(...))QOffscreenSurface::~QOffscreenSurface +48 (int (*)(...))QOffscreenSurface::~QOffscreenSurface +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QOffscreenSurface::surfaceType +120 (int (*)(...))QOffscreenSurface::format +128 (int (*)(...))QOffscreenSurface::size +136 (int (*)(...))QOffscreenSurface::surfaceHandle +144 (int (*)(...))-16 +152 (int (*)(...))(& _ZTI17QOffscreenSurface) +160 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD1Ev +168 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD0Ev +176 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface6formatEv +184 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface13surfaceHandleEv +192 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface11surfaceTypeEv +200 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface4sizeEv + +Class QOffscreenSurface + size=40 align=8 + base size=40 base align=8 +QOffscreenSurface (0x0x7ff86422fee0) 0 + vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 16u) + QObject (0x0x7ff86447ef60) 0 + primary-for QOffscreenSurface (0x0x7ff86422fee0) + QSurface (0x0x7ff864285000) 16 + vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 160u) + +Class QOpenGLBuffer + size=8 align=8 + base size=8 base align=8 +QOpenGLBuffer (0x0x7ff864285120) 0 + +Class QOpenGLVersionStatus + size=12 align=4 + base size=12 base align=4 +QOpenGLVersionStatus (0x0x7ff864285300) 0 + +Class QOpenGLVersionFunctionsBackend + size=16 align=8 + base size=12 base align=8 +QOpenGLVersionFunctionsBackend (0x0x7ff863bebde0) 0 + +Class QOpenGLVersionFunctionsStorage + size=8 align=8 + base size=8 base align=8 +QOpenGLVersionFunctionsStorage (0x0x7ff863bebe40) 0 + +Class QAbstractOpenGLFunctionsPrivate + size=16 align=8 + base size=9 base align=8 +QAbstractOpenGLFunctionsPrivate (0x0x7ff863bebea0) 0 + +Vtable for QAbstractOpenGLFunctions +QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractOpenGLFunctions) +16 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions +24 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions +32 (int (*)(...))QAbstractOpenGLFunctions::initializeOpenGLFunctions + +Class QAbstractOpenGLFunctions + size=16 align=8 + base size=16 base align=8 +QAbstractOpenGLFunctions (0x0x7ff863bebf00) 0 + vptr=((& QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions) + 16u) + +Class QOpenGLFunctions_1_0_CoreBackend::Functions + size=384 align=8 + base size=384 base align=8 +QOpenGLFunctions_1_0_CoreBackend::Functions (0x0x7ff863c37000) 0 + +Class QOpenGLFunctions_1_0_CoreBackend + size=400 align=8 + base size=400 base align=8 +QOpenGLFunctions_1_0_CoreBackend (0x0x7ff863c0c958) 0 + QOpenGLVersionFunctionsBackend (0x0x7ff863bebf60) 0 + +Class QOpenGLFunctions_1_1_CoreBackend::Functions + size=128 align=8 + base size=128 base align=8 +QOpenGLFunctions_1_1_CoreBackend::Functions (0x0x7ff863c37120) 0 + +Class QOpenGLFunctions_1_1_CoreBackend + size=144 align=8 + base size=144 base align=8 +QOpenGLFunctions_1_1_CoreBackend (0x0x7ff863c0c9c0) 0 + QOpenGLVersionFunctionsBackend (0x0x7ff863c370c0) 0 + +Class QOpenGLFunctions_1_2_CoreBackend::Functions + size=48 align=8 + base size=48 base align=8 +QOpenGLFunctions_1_2_CoreBackend::Functions (0x0x7ff863c37240) 0 + +Class QOpenGLFunctions_1_2_CoreBackend + size=64 align=8 + base size=64 base align=8 +QOpenGLFunctions_1_2_CoreBackend (0x0x7ff863c0ca28) 0 + QOpenGLVersionFunctionsBackend (0x0x7ff863c371e0) 0 + +Class QOpenGLFunctions_1_3_CoreBackend::Functions + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_1_3_CoreBackend::Functions (0x0x7ff863c37360) 0 + +Class QOpenGLFunctions_1_3_CoreBackend + size=88 align=8 + base size=88 base align=8 +QOpenGLFunctions_1_3_CoreBackend (0x0x7ff863c0ca90) 0 + QOpenGLVersionFunctionsBackend (0x0x7ff863c37300) 0 + +Class QOpenGLFunctions_1_4_CoreBackend::Functions + size=56 align=8 + base size=56 base align=8 +QOpenGLFunctions_1_4_CoreBackend::Functions (0x0x7ff863c374e0) 0 + +Class QOpenGLFunctions_1_4_CoreBackend + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_1_4_CoreBackend (0x0x7ff863c0caf8) 0 + QOpenGLVersionFunctionsBackend (0x0x7ff863c37480) 0 + +Class QOpenGLFunctions_1_5_CoreBackend::Functions + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_1_5_CoreBackend::Functions (0x0x7ff863c37600) 0 + +Class QOpenGLFunctions_1_5_CoreBackend + size=168 align=8 + base size=168 base align=8 +QOpenGLFunctions_1_5_CoreBackend (0x0x7ff863c0cb60) 0 + QOpenGLVersionFunctionsBackend (0x0x7ff863c375a0) 0 + +Class QOpenGLFunctions_2_0_CoreBackend::Functions + size=744 align=8 + base size=744 base align=8 +QOpenGLFunctions_2_0_CoreBackend::Functions (0x0x7ff863c37720) 0 + +Class QOpenGLFunctions_2_0_CoreBackend + size=760 align=8 + base size=760 base align=8 +QOpenGLFunctions_2_0_CoreBackend (0x0x7ff863c0cbc8) 0 + QOpenGLVersionFunctionsBackend (0x0x7ff863c376c0) 0 + +Class QOpenGLFunctions_2_1_CoreBackend::Functions + size=48 align=8 + base size=48 base align=8 +QOpenGLFunctions_2_1_CoreBackend::Functions (0x0x7ff863c37840) 0 + +Class QOpenGLFunctions_2_1_CoreBackend + size=64 align=8 + base size=64 base align=8 +QOpenGLFunctions_2_1_CoreBackend (0x0x7ff863c0cc30) 0 + QOpenGLVersionFunctionsBackend (0x0x7ff863c377e0) 0 + +Class QOpenGLFunctions_3_0_CoreBackend::Functions + size=672 align=8 + base size=672 base align=8 +QOpenGLFunctions_3_0_CoreBackend::Functions (0x0x7ff863c37960) 0 + +Class QOpenGLFunctions_3_0_CoreBackend + size=688 align=8 + base size=688 base align=8 +QOpenGLFunctions_3_0_CoreBackend (0x0x7ff863c0cc98) 0 + QOpenGLVersionFunctionsBackend (0x0x7ff863c37900) 0 + +Class QOpenGLFunctions_3_1_CoreBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_3_1_CoreBackend::Functions (0x0x7ff863c37a80) 0 + +Class QOpenGLFunctions_3_1_CoreBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_3_1_CoreBackend (0x0x7ff863c0cd00) 0 + QOpenGLVersionFunctionsBackend (0x0x7ff863c37a20) 0 + +Class QOpenGLFunctions_3_2_CoreBackend::Functions + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_3_2_CoreBackend::Functions (0x0x7ff863c37ba0) 0 + +Class QOpenGLFunctions_3_2_CoreBackend + size=168 align=8 + base size=168 base align=8 +QOpenGLFunctions_3_2_CoreBackend (0x0x7ff863c0cd68) 0 + QOpenGLVersionFunctionsBackend (0x0x7ff863c37b40) 0 + +Class QOpenGLFunctions_3_3_CoreBackend::Functions + size=464 align=8 + base size=464 base align=8 +QOpenGLFunctions_3_3_CoreBackend::Functions (0x0x7ff863c37cc0) 0 + +Class QOpenGLFunctions_3_3_CoreBackend + size=480 align=8 + base size=480 base align=8 +QOpenGLFunctions_3_3_CoreBackend (0x0x7ff863c0cdd0) 0 + QOpenGLVersionFunctionsBackend (0x0x7ff863c37c60) 0 + +Class QOpenGLFunctions_4_0_CoreBackend::Functions + size=368 align=8 + base size=368 base align=8 +QOpenGLFunctions_4_0_CoreBackend::Functions (0x0x7ff863c37de0) 0 + +Class QOpenGLFunctions_4_0_CoreBackend + size=384 align=8 + base size=384 base align=8 +QOpenGLFunctions_4_0_CoreBackend (0x0x7ff863c0ce38) 0 + QOpenGLVersionFunctionsBackend (0x0x7ff863c37d80) 0 + +Class QOpenGLFunctions_4_1_CoreBackend::Functions + size=704 align=8 + base size=704 base align=8 +QOpenGLFunctions_4_1_CoreBackend::Functions (0x0x7ff863c37f00) 0 + +Class QOpenGLFunctions_4_1_CoreBackend + size=720 align=8 + base size=720 base align=8 +QOpenGLFunctions_4_1_CoreBackend (0x0x7ff863c0cea0) 0 + QOpenGLVersionFunctionsBackend (0x0x7ff863c37ea0) 0 + +Class QOpenGLFunctions_4_2_CoreBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_4_2_CoreBackend::Functions (0x0x7ff863d30060) 0 + +Class QOpenGLFunctions_4_2_CoreBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_4_2_CoreBackend (0x0x7ff863c0cf08) 0 + QOpenGLVersionFunctionsBackend (0x0x7ff863d30000) 0 + +Class QOpenGLFunctions_4_3_CoreBackend::Functions + size=344 align=8 + base size=344 base align=8 +QOpenGLFunctions_4_3_CoreBackend::Functions (0x0x7ff863d30180) 0 + +Class QOpenGLFunctions_4_3_CoreBackend + size=360 align=8 + base size=360 base align=8 +QOpenGLFunctions_4_3_CoreBackend (0x0x7ff863c0cf70) 0 + QOpenGLVersionFunctionsBackend (0x0x7ff863d30120) 0 + +Class QOpenGLFunctions_4_4_CoreBackend::Functions + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_4_4_CoreBackend::Functions (0x0x7ff863d302a0) 0 + +Class QOpenGLFunctions_4_4_CoreBackend + size=88 align=8 + base size=88 base align=8 +QOpenGLFunctions_4_4_CoreBackend (0x0x7ff863d54000) 0 + QOpenGLVersionFunctionsBackend (0x0x7ff863d30240) 0 + +Class QOpenGLFunctions_4_5_CoreBackend::Functions + size=848 align=8 + base size=848 base align=8 +QOpenGLFunctions_4_5_CoreBackend::Functions (0x0x7ff863d30420) 0 + +Class QOpenGLFunctions_4_5_CoreBackend + size=864 align=8 + base size=864 base align=8 +QOpenGLFunctions_4_5_CoreBackend (0x0x7ff863d54068) 0 + QOpenGLVersionFunctionsBackend (0x0x7ff863d303c0) 0 + +Class QOpenGLFunctions_1_0_DeprecatedBackend::Functions + size=2064 align=8 + base size=2064 base align=8 +QOpenGLFunctions_1_0_DeprecatedBackend::Functions (0x0x7ff863d30540) 0 + +Class QOpenGLFunctions_1_0_DeprecatedBackend + size=2080 align=8 + base size=2080 base align=8 +QOpenGLFunctions_1_0_DeprecatedBackend (0x0x7ff863d540d0) 0 + QOpenGLVersionFunctionsBackend (0x0x7ff863d304e0) 0 + +Class QOpenGLFunctions_1_1_DeprecatedBackend::Functions + size=136 align=8 + base size=136 base align=8 +QOpenGLFunctions_1_1_DeprecatedBackend::Functions (0x0x7ff863d30660) 0 + +Class QOpenGLFunctions_1_1_DeprecatedBackend + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_1_1_DeprecatedBackend (0x0x7ff863d54138) 0 + QOpenGLVersionFunctionsBackend (0x0x7ff863d30600) 0 + +Class QOpenGLFunctions_1_2_DeprecatedBackend::Functions + size=256 align=8 + base size=256 base align=8 +QOpenGLFunctions_1_2_DeprecatedBackend::Functions (0x0x7ff863d30780) 0 + +Class QOpenGLFunctions_1_2_DeprecatedBackend + size=272 align=8 + base size=272 base align=8 +QOpenGLFunctions_1_2_DeprecatedBackend (0x0x7ff863d541a0) 0 + QOpenGLVersionFunctionsBackend (0x0x7ff863d30720) 0 + +Class QOpenGLFunctions_1_3_DeprecatedBackend::Functions + size=296 align=8 + base size=296 base align=8 +QOpenGLFunctions_1_3_DeprecatedBackend::Functions (0x0x7ff863d308a0) 0 + +Class QOpenGLFunctions_1_3_DeprecatedBackend + size=312 align=8 + base size=312 base align=8 +QOpenGLFunctions_1_3_DeprecatedBackend (0x0x7ff863d54208) 0 + QOpenGLVersionFunctionsBackend (0x0x7ff863d30840) 0 + +Class QOpenGLFunctions_1_4_DeprecatedBackend::Functions + size=304 align=8 + base size=304 base align=8 +QOpenGLFunctions_1_4_DeprecatedBackend::Functions (0x0x7ff863d309c0) 0 + +Class QOpenGLFunctions_1_4_DeprecatedBackend + size=320 align=8 + base size=320 base align=8 +QOpenGLFunctions_1_4_DeprecatedBackend (0x0x7ff863d54270) 0 + QOpenGLVersionFunctionsBackend (0x0x7ff863d30960) 0 + +Class QOpenGLFunctions_2_0_DeprecatedBackend::Functions + size=288 align=8 + base size=288 base align=8 +QOpenGLFunctions_2_0_DeprecatedBackend::Functions (0x0x7ff863d30ae0) 0 + +Class QOpenGLFunctions_2_0_DeprecatedBackend + size=304 align=8 + base size=304 base align=8 +QOpenGLFunctions_2_0_DeprecatedBackend (0x0x7ff863d542d8) 0 + QOpenGLVersionFunctionsBackend (0x0x7ff863d30a80) 0 + +Class QOpenGLFunctions_3_0_DeprecatedBackend::Functions + size=160 align=8 + base size=160 base align=8 +QOpenGLFunctions_3_0_DeprecatedBackend::Functions (0x0x7ff863d30c00) 0 + +Class QOpenGLFunctions_3_0_DeprecatedBackend + size=176 align=8 + base size=176 base align=8 +QOpenGLFunctions_3_0_DeprecatedBackend (0x0x7ff863d54340) 0 + QOpenGLVersionFunctionsBackend (0x0x7ff863d30ba0) 0 + +Class QOpenGLFunctions_3_3_DeprecatedBackend::Functions + size=240 align=8 + base size=240 base align=8 +QOpenGLFunctions_3_3_DeprecatedBackend::Functions (0x0x7ff863d30d20) 0 + +Class QOpenGLFunctions_3_3_DeprecatedBackend + size=256 align=8 + base size=256 base align=8 +QOpenGLFunctions_3_3_DeprecatedBackend (0x0x7ff863d543a8) 0 + QOpenGLVersionFunctionsBackend (0x0x7ff863d30cc0) 0 + +Class QOpenGLFunctions_4_5_DeprecatedBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_4_5_DeprecatedBackend::Functions (0x0x7ff863d30e40) 0 + +Class QOpenGLFunctions_4_5_DeprecatedBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_4_5_DeprecatedBackend (0x0x7ff863d54410) 0 + QOpenGLVersionFunctionsBackend (0x0x7ff863d30de0) 0 + +Class QOpenGLVersionProfile + size=8 align=8 + base size=8 base align=8 +QOpenGLVersionProfile (0x0x7ff863d30f00) 0 + +Class QOpenGLContextGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLContextGroup::QPrivateSignal (0x0x7ff863a5e900) 0 empty + +Vtable for QOpenGLContextGroup +QOpenGLContextGroup::_ZTV19QOpenGLContextGroup: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QOpenGLContextGroup) +16 (int (*)(...))QOpenGLContextGroup::metaObject +24 (int (*)(...))QOpenGLContextGroup::qt_metacast +32 (int (*)(...))QOpenGLContextGroup::qt_metacall +40 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup +48 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLContextGroup + size=16 align=8 + base size=16 base align=8 +QOpenGLContextGroup (0x0x7ff863d54e38) 0 + vptr=((& QOpenGLContextGroup::_ZTV19QOpenGLContextGroup) + 16u) + QObject (0x0x7ff863a5e8a0) 0 + primary-for QOpenGLContextGroup (0x0x7ff863d54e38) + +Class QOpenGLContext::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLContext::QPrivateSignal (0x0x7ff863a5e9c0) 0 empty + +Vtable for QOpenGLContext +QOpenGLContext::_ZTV14QOpenGLContext: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QOpenGLContext) +16 (int (*)(...))QOpenGLContext::metaObject +24 (int (*)(...))QOpenGLContext::qt_metacast +32 (int (*)(...))QOpenGLContext::qt_metacall +40 (int (*)(...))QOpenGLContext::~QOpenGLContext +48 (int (*)(...))QOpenGLContext::~QOpenGLContext +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLContext + size=16 align=8 + base size=16 base align=8 +QOpenGLContext (0x0x7ff863d54ea0) 0 + vptr=((& QOpenGLContext::_ZTV14QOpenGLContext) + 16u) + QObject (0x0x7ff863a5e960) 0 + primary-for QOpenGLContext (0x0x7ff863d54ea0) + +Class QOpenGLDebugMessage + size=8 align=8 + base size=8 base align=8 +QOpenGLDebugMessage (0x0x7ff863a5ea20) 0 + +Class QOpenGLDebugLogger::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLDebugLogger::QPrivateSignal (0x0x7ff863af8240) 0 empty + +Vtable for QOpenGLDebugLogger +QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLDebugLogger) +16 (int (*)(...))QOpenGLDebugLogger::metaObject +24 (int (*)(...))QOpenGLDebugLogger::qt_metacast +32 (int (*)(...))QOpenGLDebugLogger::qt_metacall +40 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger +48 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLDebugLogger + size=16 align=8 + base size=16 base align=8 +QOpenGLDebugLogger (0x0x7ff863abb340) 0 + vptr=((& QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger) + 16u) + QObject (0x0x7ff863af81e0) 0 + primary-for QOpenGLDebugLogger (0x0x7ff863abb340) + +Class QOpenGLFunctions + size=8 align=8 + base size=8 base align=8 +QOpenGLFunctions (0x0x7ff863af83c0) 0 + +Class QOpenGLFunctionsPrivate::Functions + size=1152 align=8 + base size=1152 base align=8 +QOpenGLFunctionsPrivate::Functions (0x0x7ff863af8600) 0 + +Class QOpenGLFunctionsPrivate + size=1152 align=8 + base size=1152 base align=8 +QOpenGLFunctionsPrivate (0x0x7ff863af85a0) 0 + +Class QOpenGLExtraFunctions + size=8 align=8 + base size=8 base align=8 +QOpenGLExtraFunctions (0x0x7ff863abb5b0) 0 + QOpenGLFunctions (0x0x7ff8638bfd20) 0 + +Class QOpenGLExtraFunctionsPrivate::Functions + size=1728 align=8 + base size=1728 base align=8 +QOpenGLExtraFunctionsPrivate::Functions (0x0x7ff8638bfde0) 0 + +Class QOpenGLExtraFunctionsPrivate + size=2880 align=8 + base size=2880 base align=8 +QOpenGLExtraFunctionsPrivate (0x0x7ff863abb618) 0 + QOpenGLFunctionsPrivate (0x0x7ff8638bfd80) 0 + +Vtable for QOpenGLFramebufferObject +QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QOpenGLFramebufferObject) +16 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject +24 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject + +Class QOpenGLFramebufferObject + size=16 align=8 + base size=16 base align=8 +QOpenGLFramebufferObject (0x0x7ff8637284e0) 0 + vptr=((& QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject) + 16u) + +Class QOpenGLFramebufferObjectFormat + size=8 align=8 + base size=8 base align=8 +QOpenGLFramebufferObjectFormat (0x0x7ff863728600) 0 + +Vtable for QOpenGLPaintDevice +QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLPaintDevice) +16 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice +24 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice +32 (int (*)(...))QOpenGLPaintDevice::devType +40 (int (*)(...))QOpenGLPaintDevice::paintEngine +48 (int (*)(...))QOpenGLPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))QOpenGLPaintDevice::ensureActiveTarget + +Class QOpenGLPaintDevice + size=32 align=8 + base size=32 base align=8 +QOpenGLPaintDevice (0x0x7ff863abb8f0) 0 + vptr=((& QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice) + 16u) + QPaintDevice (0x0x7ff863728660) 0 + primary-for QOpenGLPaintDevice (0x0x7ff863abb8f0) + +Class QOpenGLPixelTransferOptions + size=8 align=8 + base size=8 base align=8 +QOpenGLPixelTransferOptions (0x0x7ff863728780) 0 + +Class QOpenGLShader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLShader::QPrivateSignal (0x0x7ff863728ae0) 0 empty + +Vtable for QOpenGLShader +QOpenGLShader::_ZTV13QOpenGLShader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QOpenGLShader) +16 (int (*)(...))QOpenGLShader::metaObject +24 (int (*)(...))QOpenGLShader::qt_metacast +32 (int (*)(...))QOpenGLShader::qt_metacall +40 (int (*)(...))QOpenGLShader::~QOpenGLShader +48 (int (*)(...))QOpenGLShader::~QOpenGLShader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLShader + size=16 align=8 + base size=16 base align=8 +QOpenGLShader (0x0x7ff863abbaf8) 0 + vptr=((& QOpenGLShader::_ZTV13QOpenGLShader) + 16u) + QObject (0x0x7ff863728a80) 0 + primary-for QOpenGLShader (0x0x7ff863abbaf8) + +Class QOpenGLShaderProgram::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLShaderProgram::QPrivateSignal (0x0x7ff863728d20) 0 empty + +Vtable for QOpenGLShaderProgram +QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QOpenGLShaderProgram) +16 (int (*)(...))QOpenGLShaderProgram::metaObject +24 (int (*)(...))QOpenGLShaderProgram::qt_metacast +32 (int (*)(...))QOpenGLShaderProgram::qt_metacall +40 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram +48 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QOpenGLShaderProgram::link + +Class QOpenGLShaderProgram + size=16 align=8 + base size=16 base align=8 +QOpenGLShaderProgram (0x0x7ff863abbc30) 0 + vptr=((& QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram) + 16u) + QObject (0x0x7ff863728cc0) 0 + primary-for QOpenGLShaderProgram (0x0x7ff863abbc30) + +Class QOpenGLTexture + size=8 align=8 + base size=8 base align=8 +QOpenGLTexture (0x0x7ff863728d80) 0 + +Class QOpenGLTextureBlitter + size=8 align=8 + base size=8 base align=8 +QOpenGLTextureBlitter (0x0x7ff8634a7060) 0 + +Class QOpenGLTimerQuery::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLTimerQuery::QPrivateSignal (0x0x7ff8634a71e0) 0 empty + +Vtable for QOpenGLTimerQuery +QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QOpenGLTimerQuery) +16 (int (*)(...))QOpenGLTimerQuery::metaObject +24 (int (*)(...))QOpenGLTimerQuery::qt_metacast +32 (int (*)(...))QOpenGLTimerQuery::qt_metacall +40 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery +48 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLTimerQuery + size=16 align=8 + base size=16 base align=8 +QOpenGLTimerQuery (0x0x7ff863abbd68) 0 + vptr=((& QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery) + 16u) + QObject (0x0x7ff8634a7180) 0 + primary-for QOpenGLTimerQuery (0x0x7ff863abbd68) + +Class QOpenGLTimeMonitor::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLTimeMonitor::QPrivateSignal (0x0x7ff8634a72a0) 0 empty + +Vtable for QOpenGLTimeMonitor +QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLTimeMonitor) +16 (int (*)(...))QOpenGLTimeMonitor::metaObject +24 (int (*)(...))QOpenGLTimeMonitor::qt_metacast +32 (int (*)(...))QOpenGLTimeMonitor::qt_metacall +40 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor +48 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLTimeMonitor + size=16 align=8 + base size=16 base align=8 +QOpenGLTimeMonitor (0x0x7ff863abbdd0) 0 + vptr=((& QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor) + 16u) + QObject (0x0x7ff8634a7240) 0 + primary-for QOpenGLTimeMonitor (0x0x7ff863abbdd0) + +Class QOpenGLVertexArrayObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLVertexArrayObject::QPrivateSignal (0x0x7ff8634a7360) 0 empty + +Class QOpenGLVertexArrayObject::Binder + size=8 align=8 + base size=8 base align=8 +QOpenGLVertexArrayObject::Binder (0x0x7ff8634a73c0) 0 + +Vtable for QOpenGLVertexArrayObject +QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QOpenGLVertexArrayObject) +16 (int (*)(...))QOpenGLVertexArrayObject::metaObject +24 (int (*)(...))QOpenGLVertexArrayObject::qt_metacast +32 (int (*)(...))QOpenGLVertexArrayObject::qt_metacall +40 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject +48 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLVertexArrayObject + size=16 align=8 + base size=16 base align=8 +QOpenGLVertexArrayObject (0x0x7ff863abbe38) 0 + vptr=((& QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject) + 16u) + QObject (0x0x7ff8634a7300) 0 + primary-for QOpenGLVertexArrayObject (0x0x7ff863abbe38) + +Class QPaintDeviceWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPaintDeviceWindow::QPrivateSignal (0x0x7ff8634a7540) 0 empty + +Vtable for QPaintDeviceWindow +QPaintDeviceWindow::_ZTV18QPaintDeviceWindow: 58u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +16 (int (*)(...))QPaintDeviceWindow::metaObject +24 (int (*)(...))QPaintDeviceWindow::qt_metacast +32 (int (*)(...))QPaintDeviceWindow::qt_metacall +40 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow +48 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))QPaintDeviceWindow::paintEvent +304 (int (*)(...))QPaintDeviceWindow::metric +312 (int (*)(...))QPaintDeviceWindow::paintEngine +320 (int (*)(...))-16 +328 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +336 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD1Ev +344 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD0Ev +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +376 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +384 (int (*)(...))-40 +392 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +400 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD1Ev +408 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD0Ev +416 (int (*)(...))QPaintDevice::devType +424 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +432 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow6metricEN12QPaintDevice17PaintDeviceMetricE +440 (int (*)(...))QPaintDevice::initPainter +448 (int (*)(...))QPaintDevice::redirected +456 (int (*)(...))QPaintDevice::sharedPainter + +Class QPaintDeviceWindow + size=64 align=8 + base size=64 base align=8 +QPaintDeviceWindow (0x0x7ff8634e8e00) 0 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 16u) + QWindow (0x0x7ff8634e8e70) 0 + primary-for QPaintDeviceWindow (0x0x7ff8634e8e00) + QObject (0x0x7ff8634a7420) 0 + primary-for QWindow (0x0x7ff8634e8e70) + QSurface (0x0x7ff8634a7480) 16 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 336u) + QPaintDevice (0x0x7ff8634a74e0) 40 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 400u) + +Class QOpenGLWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLWindow::QPrivateSignal (0x0x7ff8634a76c0) 0 empty + +Vtable for QOpenGLWindow +QOpenGLWindow::_ZTV13QOpenGLWindow: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QOpenGLWindow) +16 (int (*)(...))QOpenGLWindow::metaObject +24 (int (*)(...))QOpenGLWindow::qt_metacast +32 (int (*)(...))QOpenGLWindow::qt_metacall +40 (int (*)(...))QOpenGLWindow::~QOpenGLWindow +48 (int (*)(...))QOpenGLWindow::~QOpenGLWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QOpenGLWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))QOpenGLWindow::paintEvent +304 (int (*)(...))QOpenGLWindow::metric +312 (int (*)(...))QPaintDeviceWindow::paintEngine +320 (int (*)(...))QOpenGLWindow::initializeGL +328 (int (*)(...))QOpenGLWindow::resizeGL +336 (int (*)(...))QOpenGLWindow::paintGL +344 (int (*)(...))QOpenGLWindow::paintUnderGL +352 (int (*)(...))QOpenGLWindow::paintOverGL +360 (int (*)(...))QOpenGLWindow::redirected +368 (int (*)(...))-16 +376 (int (*)(...))(& _ZTI13QOpenGLWindow) +384 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD1Ev +392 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD0Ev +400 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +408 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +416 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +424 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +432 (int (*)(...))-40 +440 (int (*)(...))(& _ZTI13QOpenGLWindow) +448 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD1Ev +456 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD0Ev +464 (int (*)(...))QPaintDevice::devType +472 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +480 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QPaintDevice::initPainter +496 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow10redirectedEP6QPoint +504 (int (*)(...))QPaintDevice::sharedPainter + +Class QOpenGLWindow + size=64 align=8 + base size=64 base align=8 +QOpenGLWindow (0x0x7ff863abbf08) 0 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 16u) + QPaintDeviceWindow (0x0x7ff86351e230) 0 + primary-for QOpenGLWindow (0x0x7ff863abbf08) + QWindow (0x0x7ff86351e2a0) 0 + primary-for QPaintDeviceWindow (0x0x7ff86351e230) + QObject (0x0x7ff8634a75a0) 0 + primary-for QWindow (0x0x7ff86351e2a0) + QSurface (0x0x7ff8634a7600) 16 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 384u) + QPaintDevice (0x0x7ff8634a7660) 40 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 448u) + +Class QPageSize + size=8 align=8 + base size=8 base align=8 +QPageSize (0x0x7ff8634a7720) 0 + +Class QPageLayout + size=8 align=8 + base size=8 base align=8 +QPageLayout (0x0x7ff863586120) 0 + +Class QPagedPaintDevice::Margins + size=32 align=8 + base size=32 base align=8 +QPagedPaintDevice::Margins (0x0x7ff863586b40) 0 + +Vtable for QPagedPaintDevice +QPagedPaintDevice::_ZTV17QPagedPaintDevice: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QPagedPaintDevice) +16 0u +24 0u +32 (int (*)(...))QPaintDevice::devType +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QPagedPaintDevice::setPageSize +96 (int (*)(...))QPagedPaintDevice::setPageSizeMM +104 (int (*)(...))QPagedPaintDevice::setMargins + +Class QPagedPaintDevice + size=32 align=8 + base size=32 base align=8 +QPagedPaintDevice (0x0x7ff863563c30) 0 + vptr=((& QPagedPaintDevice::_ZTV17QPagedPaintDevice) + 16u) + QPaintDevice (0x0x7ff863586ae0) 0 + primary-for QPagedPaintDevice (0x0x7ff863563c30) + +Class QPainter::PixmapFragment + size=80 align=8 + base size=80 base align=8 +QPainter::PixmapFragment (0x0x7ff863586c00) 0 + +Class QPainter + size=8 align=8 + base size=8 base align=8 +QPainter (0x0x7ff863586ba0) 0 + +Class QTextItem + size=1 align=1 + base size=0 base align=1 +QTextItem (0x0x7ff86324ea20) 0 empty + +Vtable for QPaintEngine +QPaintEngine::_ZTV12QPaintEngine: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QPaintEngine) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))QPaintEngine::drawRects +64 (int (*)(...))QPaintEngine::drawRects +72 (int (*)(...))QPaintEngine::drawLines +80 (int (*)(...))QPaintEngine::drawLines +88 (int (*)(...))QPaintEngine::drawEllipse +96 (int (*)(...))QPaintEngine::drawEllipse +104 (int (*)(...))QPaintEngine::drawPath +112 (int (*)(...))QPaintEngine::drawPoints +120 (int (*)(...))QPaintEngine::drawPoints +128 (int (*)(...))QPaintEngine::drawPolygon +136 (int (*)(...))QPaintEngine::drawPolygon +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QPaintEngine::drawTextItem +160 (int (*)(...))QPaintEngine::drawTiledPixmap +168 (int (*)(...))QPaintEngine::drawImage +176 (int (*)(...))QPaintEngine::coordinateOffset +184 (int (*)(...))__cxa_pure_virtual + +Class QPaintEngine + size=32 align=8 + base size=32 base align=8 +QPaintEngine (0x0x7ff86324ecc0) 0 + vptr=((& QPaintEngine::_ZTV12QPaintEngine) + 16u) + +Class QPaintEngineState + size=4 align=4 + base size=4 base align=4 +QPaintEngineState (0x0x7ff86324ef60) 0 + +Class QPdfWriter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPdfWriter::QPrivateSignal (0x0x7ff8630173c0) 0 empty + +Vtable for QPdfWriter +QPdfWriter::_ZTV10QPdfWriter: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QPdfWriter) +16 (int (*)(...))QPdfWriter::metaObject +24 (int (*)(...))QPdfWriter::qt_metacast +32 (int (*)(...))QPdfWriter::qt_metacall +40 (int (*)(...))QPdfWriter::~QPdfWriter +48 (int (*)(...))QPdfWriter::~QPdfWriter +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPdfWriter::newPage +120 (int (*)(...))QPdfWriter::setPageSize +128 (int (*)(...))QPdfWriter::setPageSizeMM +136 (int (*)(...))QPdfWriter::setMargins +144 (int (*)(...))QPdfWriter::paintEngine +152 (int (*)(...))QPdfWriter::metric +160 (int (*)(...))-16 +168 (int (*)(...))(& _ZTI10QPdfWriter) +176 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD1Ev +184 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD0Ev +192 (int (*)(...))QPaintDevice::devType +200 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter11paintEngineEv +208 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter6metricEN12QPaintDevice17PaintDeviceMetricE +216 (int (*)(...))QPaintDevice::initPainter +224 (int (*)(...))QPaintDevice::redirected +232 (int (*)(...))QPaintDevice::sharedPainter +240 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter7newPageEv +248 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter11setPageSizeEN17QPagedPaintDevice8PageSizeE +256 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter13setPageSizeMMERK6QSizeF +264 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter10setMarginsERKN17QPagedPaintDevice7MarginsE + +Class QPdfWriter + size=48 align=8 + base size=48 base align=8 +QPdfWriter (0x0x7ff8630821c0) 0 + vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 16u) + QObject (0x0x7ff863017300) 0 + primary-for QPdfWriter (0x0x7ff8630821c0) + QPagedPaintDevice (0x0x7ff863265c98) 16 + vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 176u) + QPaintDevice (0x0x7ff863017360) 16 + primary-for QPagedPaintDevice (0x0x7ff863265c98) + +Vtable for QPicture +QPicture::_ZTV8QPicture: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QPicture) +16 (int (*)(...))QPicture::~QPicture +24 (int (*)(...))QPicture::~QPicture +32 (int (*)(...))QPicture::devType +40 (int (*)(...))QPicture::paintEngine +48 (int (*)(...))QPicture::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))QPicture::setData + +Class QPicture + size=32 align=8 + base size=32 base align=8 +QPicture (0x0x7ff863265d00) 0 + vptr=((& QPicture::_ZTV8QPicture) + 16u) + QPaintDevice (0x0x7ff863017540) 0 + primary-for QPicture (0x0x7ff863265d00) + +Class QPictureIO + size=8 align=8 + base size=8 base align=8 +QPictureIO (0x0x7ff863017840) 0 + +Class QPictureFormatPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPictureFormatPlugin::QPrivateSignal (0x0x7ff863017900) 0 empty + +Vtable for QPictureFormatPlugin +QPictureFormatPlugin::_ZTV20QPictureFormatPlugin: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QPictureFormatPlugin) +16 (int (*)(...))QPictureFormatPlugin::metaObject +24 (int (*)(...))QPictureFormatPlugin::qt_metacast +32 (int (*)(...))QPictureFormatPlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPictureFormatPlugin::loadPicture +120 (int (*)(...))QPictureFormatPlugin::savePicture +128 (int (*)(...))__cxa_pure_virtual + +Class QPictureFormatPlugin + size=16 align=8 + base size=16 base align=8 +QPictureFormatPlugin (0x0x7ff863265f08) 0 + vptr=((& QPictureFormatPlugin::_ZTV20QPictureFormatPlugin) + 16u) + QObject (0x0x7ff8630178a0) 0 + primary-for QPictureFormatPlugin (0x0x7ff863265f08) + +Class QPixmapCache::Key + size=8 align=8 + base size=8 base align=8 +QPixmapCache::Key (0x0x7ff8630179c0) 0 + +Class QPixmapCache + size=1 align=1 + base size=0 base align=1 +QPixmapCache (0x0x7ff863017960) 0 empty + +Class QRasterWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRasterWindow::QPrivateSignal (0x0x7ff863152b40) 0 empty + +Vtable for QRasterWindow +QRasterWindow::_ZTV13QRasterWindow: 59u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QRasterWindow) +16 (int (*)(...))QRasterWindow::metaObject +24 (int (*)(...))QRasterWindow::qt_metacast +32 (int (*)(...))QRasterWindow::qt_metacall +40 (int (*)(...))QRasterWindow::~QRasterWindow +48 (int (*)(...))QRasterWindow::~QRasterWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))QPaintDeviceWindow::paintEvent +304 (int (*)(...))QRasterWindow::metric +312 (int (*)(...))QPaintDeviceWindow::paintEngine +320 (int (*)(...))QRasterWindow::redirected +328 (int (*)(...))-16 +336 (int (*)(...))(& _ZTI13QRasterWindow) +344 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD1Ev +352 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD0Ev +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +376 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +384 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +392 (int (*)(...))-40 +400 (int (*)(...))(& _ZTI13QRasterWindow) +408 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD1Ev +416 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD0Ev +424 (int (*)(...))QPaintDevice::devType +432 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +440 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow6metricEN12QPaintDevice17PaintDeviceMetricE +448 (int (*)(...))QPaintDevice::initPainter +456 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow10redirectedEP6QPoint +464 (int (*)(...))QPaintDevice::sharedPainter + +Class QRasterWindow + size=64 align=8 + base size=64 base align=8 +QRasterWindow (0x0x7ff86315d618) 0 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 16u) + QPaintDeviceWindow (0x0x7ff863155f50) 0 + primary-for QRasterWindow (0x0x7ff86315d618) + QWindow (0x0x7ff863167000) 0 + primary-for QPaintDeviceWindow (0x0x7ff863155f50) + QObject (0x0x7ff863152a20) 0 + primary-for QWindow (0x0x7ff863167000) + QSurface (0x0x7ff863152a80) 16 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 344u) + QPaintDevice (0x0x7ff863152ae0) 40 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 408u) + +Class QScreen::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QScreen::QPrivateSignal (0x0x7ff863152c00) 0 empty + +Vtable for QScreen +QScreen::_ZTV7QScreen: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QScreen) +16 (int (*)(...))QScreen::metaObject +24 (int (*)(...))QScreen::qt_metacast +32 (int (*)(...))QScreen::qt_metacall +40 (int (*)(...))QScreen::~QScreen +48 (int (*)(...))QScreen::~QScreen +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QScreen + size=16 align=8 + base size=16 base align=8 +QScreen (0x0x7ff86315d6e8) 0 + vptr=((& QScreen::_ZTV7QScreen) + 16u) + QObject (0x0x7ff863152ba0) 0 + primary-for QScreen (0x0x7ff86315d6e8) + +Class QSessionManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSessionManager::QPrivateSignal (0x0x7ff863152cc0) 0 empty + +Vtable for QSessionManager +QSessionManager::_ZTV15QSessionManager: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSessionManager) +16 (int (*)(...))QSessionManager::metaObject +24 (int (*)(...))QSessionManager::qt_metacast +32 (int (*)(...))QSessionManager::qt_metacall +40 (int (*)(...))QSessionManager::~QSessionManager +48 (int (*)(...))QSessionManager::~QSessionManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSessionManager + size=16 align=8 + base size=16 base align=8 +QSessionManager (0x0x7ff86315d750) 0 + vptr=((& QSessionManager::_ZTV15QSessionManager) + 16u) + QObject (0x0x7ff863152c60) 0 + primary-for QSessionManager (0x0x7ff86315d750) + +Vtable for QStandardItem +QStandardItem::_ZTV13QStandardItem: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStandardItem) +16 (int (*)(...))QStandardItem::~QStandardItem +24 (int (*)(...))QStandardItem::~QStandardItem +32 (int (*)(...))QStandardItem::data +40 (int (*)(...))QStandardItem::setData +48 (int (*)(...))QStandardItem::clone +56 (int (*)(...))QStandardItem::type +64 (int (*)(...))QStandardItem::read +72 (int (*)(...))QStandardItem::write +80 (int (*)(...))QStandardItem::operator< + +Class QStandardItem + size=16 align=8 + base size=16 base align=8 +QStandardItem (0x0x7ff863152d20) 0 + vptr=((& QStandardItem::_ZTV13QStandardItem) + 16u) + +Class QStandardItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStandardItemModel::QPrivateSignal (0x0x7ff862df0480) 0 empty + +Vtable for QStandardItemModel +QStandardItemModel::_ZTV18QStandardItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QStandardItemModel) +16 (int (*)(...))QStandardItemModel::metaObject +24 (int (*)(...))QStandardItemModel::qt_metacast +32 (int (*)(...))QStandardItemModel::qt_metacall +40 (int (*)(...))QStandardItemModel::~QStandardItemModel +48 (int (*)(...))QStandardItemModel::~QStandardItemModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStandardItemModel::index +120 (int (*)(...))QStandardItemModel::parent +128 (int (*)(...))QStandardItemModel::sibling +136 (int (*)(...))QStandardItemModel::rowCount +144 (int (*)(...))QStandardItemModel::columnCount +152 (int (*)(...))QStandardItemModel::hasChildren +160 (int (*)(...))QStandardItemModel::data +168 (int (*)(...))QStandardItemModel::setData +176 (int (*)(...))QStandardItemModel::headerData +184 (int (*)(...))QStandardItemModel::setHeaderData +192 (int (*)(...))QStandardItemModel::itemData +200 (int (*)(...))QStandardItemModel::setItemData +208 (int (*)(...))QStandardItemModel::mimeTypes +216 (int (*)(...))QStandardItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QStandardItemModel::dropMimeData +240 (int (*)(...))QStandardItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStandardItemModel::insertRows +264 (int (*)(...))QStandardItemModel::insertColumns +272 (int (*)(...))QStandardItemModel::removeRows +280 (int (*)(...))QStandardItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStandardItemModel::flags +328 (int (*)(...))QStandardItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStandardItemModel + size=16 align=8 + base size=16 base align=8 +QStandardItemModel (0x0x7ff86315ddd0) 0 + vptr=((& QStandardItemModel::_ZTV18QStandardItemModel) + 16u) + QAbstractItemModel (0x0x7ff86315de38) 0 + primary-for QStandardItemModel (0x0x7ff86315ddd0) + QObject (0x0x7ff862df0420) 0 + primary-for QAbstractItemModel (0x0x7ff86315de38) + +Class QStaticText + size=8 align=8 + base size=8 base align=8 +QStaticText (0x0x7ff862df04e0) 0 + +Class QStyleHints::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStyleHints::QPrivateSignal (0x0x7ff862df0960) 0 empty + +Vtable for QStyleHints +QStyleHints::_ZTV11QStyleHints: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QStyleHints) +16 (int (*)(...))QStyleHints::metaObject +24 (int (*)(...))QStyleHints::qt_metacast +32 (int (*)(...))QStyleHints::qt_metacall +40 (int (*)(...))QStyleHints::~QStyleHints +48 (int (*)(...))QStyleHints::~QStyleHints +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QStyleHints + size=16 align=8 + base size=16 base align=8 +QStyleHints (0x0x7ff862eca068) 0 + vptr=((& QStyleHints::_ZTV11QStyleHints) + 16u) + QObject (0x0x7ff862df0900) 0 + primary-for QStyleHints (0x0x7ff862eca068) + +Class QTextObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextObject::QPrivateSignal (0x0x7ff862df0a20) 0 empty + +Vtable for QTextObject +QTextObject::_ZTV11QTextObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextObject) +16 (int (*)(...))QTextObject::metaObject +24 (int (*)(...))QTextObject::qt_metacast +32 (int (*)(...))QTextObject::qt_metacall +40 (int (*)(...))QTextObject::~QTextObject +48 (int (*)(...))QTextObject::~QTextObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextObject + size=16 align=8 + base size=16 base align=8 +QTextObject (0x0x7ff862eca0d0) 0 + vptr=((& QTextObject::_ZTV11QTextObject) + 16u) + QObject (0x0x7ff862df09c0) 0 + primary-for QTextObject (0x0x7ff862eca0d0) + +Class QTextBlockGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextBlockGroup::QPrivateSignal (0x0x7ff862df0ae0) 0 empty + +Vtable for QTextBlockGroup +QTextBlockGroup::_ZTV15QTextBlockGroup: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QTextBlockGroup) +16 (int (*)(...))QTextBlockGroup::metaObject +24 (int (*)(...))QTextBlockGroup::qt_metacast +32 (int (*)(...))QTextBlockGroup::qt_metacall +40 (int (*)(...))QTextBlockGroup::~QTextBlockGroup +48 (int (*)(...))QTextBlockGroup::~QTextBlockGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextBlockGroup::blockInserted +120 (int (*)(...))QTextBlockGroup::blockRemoved +128 (int (*)(...))QTextBlockGroup::blockFormatChanged + +Class QTextBlockGroup + size=16 align=8 + base size=16 base align=8 +QTextBlockGroup (0x0x7ff862eca138) 0 + vptr=((& QTextBlockGroup::_ZTV15QTextBlockGroup) + 16u) + QTextObject (0x0x7ff862eca1a0) 0 + primary-for QTextBlockGroup (0x0x7ff862eca138) + QObject (0x0x7ff862df0a80) 0 + primary-for QTextObject (0x0x7ff862eca1a0) + +Vtable for QTextFrameLayoutData +QTextFrameLayoutData::_ZTV20QTextFrameLayoutData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTextFrameLayoutData) +16 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData +24 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData + +Class QTextFrameLayoutData + size=8 align=8 + base size=8 base align=8 +QTextFrameLayoutData (0x0x7ff862df0b40) 0 nearly-empty + vptr=((& QTextFrameLayoutData::_ZTV20QTextFrameLayoutData) + 16u) + +Class QTextFrame::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextFrame::QPrivateSignal (0x0x7ff862df0c00) 0 empty + +Class QTextFrame::iterator + size=32 align=8 + base size=28 base align=8 +QTextFrame::iterator (0x0x7ff862df0c60) 0 + +Vtable for QTextFrame +QTextFrame::_ZTV10QTextFrame: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextFrame) +16 (int (*)(...))QTextFrame::metaObject +24 (int (*)(...))QTextFrame::qt_metacast +32 (int (*)(...))QTextFrame::qt_metacall +40 (int (*)(...))QTextFrame::~QTextFrame +48 (int (*)(...))QTextFrame::~QTextFrame +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextFrame + size=16 align=8 + base size=16 base align=8 +QTextFrame (0x0x7ff862eca208) 0 + vptr=((& QTextFrame::_ZTV10QTextFrame) + 16u) + QTextObject (0x0x7ff862eca270) 0 + primary-for QTextFrame (0x0x7ff862eca208) + QObject (0x0x7ff862df0ba0) 0 + primary-for QTextObject (0x0x7ff862eca270) + +Vtable for QTextBlockUserData +QTextBlockUserData::_ZTV18QTextBlockUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QTextBlockUserData) +16 (int (*)(...))QTextBlockUserData::~QTextBlockUserData +24 (int (*)(...))QTextBlockUserData::~QTextBlockUserData + +Class QTextBlockUserData + size=8 align=8 + base size=8 base align=8 +QTextBlockUserData (0x0x7ff862df0f00) 0 nearly-empty + vptr=((& QTextBlockUserData::_ZTV18QTextBlockUserData) + 16u) + +Class QTextBlock::iterator + size=24 align=8 + base size=20 base align=8 +QTextBlock::iterator (0x0x7ff862f43000) 0 + +Class QTextBlock + size=16 align=8 + base size=12 base align=8 +QTextBlock (0x0x7ff862df0f60) 0 + +Class QTextFragment + size=16 align=8 + base size=16 base align=8 +QTextFragment (0x0x7ff862f434e0) 0 + +Class QSyntaxHighlighter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSyntaxHighlighter::QPrivateSignal (0x0x7ff862f437e0) 0 empty + +Vtable for QSyntaxHighlighter +QSyntaxHighlighter::_ZTV18QSyntaxHighlighter: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSyntaxHighlighter) +16 (int (*)(...))QSyntaxHighlighter::metaObject +24 (int (*)(...))QSyntaxHighlighter::qt_metacast +32 (int (*)(...))QSyntaxHighlighter::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QSyntaxHighlighter + size=16 align=8 + base size=16 base align=8 +QSyntaxHighlighter (0x0x7ff862eca958) 0 + vptr=((& QSyntaxHighlighter::_ZTV18QSyntaxHighlighter) + 16u) + QObject (0x0x7ff862f43780) 0 + primary-for QSyntaxHighlighter (0x0x7ff862eca958) + +Class QTextDocumentFragment + size=8 align=8 + base size=8 base align=8 +QTextDocumentFragment (0x0x7ff862f43840) 0 + +Class QTextDocumentWriter + size=8 align=8 + base size=8 base align=8 +QTextDocumentWriter (0x0x7ff862f438a0) 0 + +Class QTextList::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextList::QPrivateSignal (0x0x7ff862f43960) 0 empty + +Vtable for QTextList +QTextList::_ZTV9QTextList: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTextList) +16 (int (*)(...))QTextList::metaObject +24 (int (*)(...))QTextList::qt_metacast +32 (int (*)(...))QTextList::qt_metacall +40 (int (*)(...))QTextList::~QTextList +48 (int (*)(...))QTextList::~QTextList +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextBlockGroup::blockInserted +120 (int (*)(...))QTextBlockGroup::blockRemoved +128 (int (*)(...))QTextBlockGroup::blockFormatChanged + +Class QTextList + size=16 align=8 + base size=16 base align=8 +QTextList (0x0x7ff862eca9c0) 0 + vptr=((& QTextList::_ZTV9QTextList) + 16u) + QTextBlockGroup (0x0x7ff862ecaa28) 0 + primary-for QTextList (0x0x7ff862eca9c0) + QTextObject (0x0x7ff862ecaa90) 0 + primary-for QTextBlockGroup (0x0x7ff862ecaa28) + QObject (0x0x7ff862f43900) 0 + primary-for QTextObject (0x0x7ff862ecaa90) + +Class QTextTableCell + size=16 align=8 + base size=12 base align=8 +QTextTableCell (0x0x7ff862f439c0) 0 + +Class QTextTable::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextTable::QPrivateSignal (0x0x7ff862f43a80) 0 empty + +Vtable for QTextTable +QTextTable::_ZTV10QTextTable: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextTable) +16 (int (*)(...))QTextTable::metaObject +24 (int (*)(...))QTextTable::qt_metacast +32 (int (*)(...))QTextTable::qt_metacall +40 (int (*)(...))QTextTable::~QTextTable +48 (int (*)(...))QTextTable::~QTextTable +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextTable + size=16 align=8 + base size=16 base align=8 +QTextTable (0x0x7ff862ecaaf8) 0 + vptr=((& QTextTable::_ZTV10QTextTable) + 16u) + QTextFrame (0x0x7ff862ecab60) 0 + primary-for QTextTable (0x0x7ff862ecaaf8) + QTextObject (0x0x7ff862ecabc8) 0 + primary-for QTextFrame (0x0x7ff862ecab60) + QObject (0x0x7ff862f43a20) 0 + primary-for QTextObject (0x0x7ff862ecabc8) + +Class QValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QValidator::QPrivateSignal (0x0x7ff862f43b40) 0 empty + +Vtable for QValidator +QValidator::_ZTV10QValidator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QValidator) +16 (int (*)(...))QValidator::metaObject +24 (int (*)(...))QValidator::qt_metacast +32 (int (*)(...))QValidator::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QValidator::fixup + +Class QValidator + size=16 align=8 + base size=16 base align=8 +QValidator (0x0x7ff862ecac30) 0 + vptr=((& QValidator::_ZTV10QValidator) + 16u) + QObject (0x0x7ff862f43ae0) 0 + primary-for QValidator (0x0x7ff862ecac30) + +Class QIntValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIntValidator::QPrivateSignal (0x0x7ff862f43c00) 0 empty + +Vtable for QIntValidator +QIntValidator::_ZTV13QIntValidator: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QIntValidator) +16 (int (*)(...))QIntValidator::metaObject +24 (int (*)(...))QIntValidator::qt_metacast +32 (int (*)(...))QIntValidator::qt_metacall +40 (int (*)(...))QIntValidator::~QIntValidator +48 (int (*)(...))QIntValidator::~QIntValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIntValidator::validate +120 (int (*)(...))QIntValidator::fixup +128 (int (*)(...))QIntValidator::setRange + +Class QIntValidator + size=24 align=8 + base size=24 base align=8 +QIntValidator (0x0x7ff862ecac98) 0 + vptr=((& QIntValidator::_ZTV13QIntValidator) + 16u) + QValidator (0x0x7ff862ecad00) 0 + primary-for QIntValidator (0x0x7ff862ecac98) + QObject (0x0x7ff862f43ba0) 0 + primary-for QValidator (0x0x7ff862ecad00) + +Class QDoubleValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDoubleValidator::QPrivateSignal (0x0x7ff862f43cc0) 0 empty + +Vtable for QDoubleValidator +QDoubleValidator::_ZTV16QDoubleValidator: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QDoubleValidator) +16 (int (*)(...))QDoubleValidator::metaObject +24 (int (*)(...))QDoubleValidator::qt_metacast +32 (int (*)(...))QDoubleValidator::qt_metacall +40 (int (*)(...))QDoubleValidator::~QDoubleValidator +48 (int (*)(...))QDoubleValidator::~QDoubleValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QDoubleValidator::validate +120 (int (*)(...))QValidator::fixup +128 (int (*)(...))QDoubleValidator::setRange + +Class QDoubleValidator + size=40 align=8 + base size=36 base align=8 +QDoubleValidator (0x0x7ff862ecad68) 0 + vptr=((& QDoubleValidator::_ZTV16QDoubleValidator) + 16u) + QValidator (0x0x7ff862ecadd0) 0 + primary-for QDoubleValidator (0x0x7ff862ecad68) + QObject (0x0x7ff862f43c60) 0 + primary-for QValidator (0x0x7ff862ecadd0) + +Class QRegExpValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRegExpValidator::QPrivateSignal (0x0x7ff862f43de0) 0 empty + +Vtable for QRegExpValidator +QRegExpValidator::_ZTV16QRegExpValidator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QRegExpValidator) +16 (int (*)(...))QRegExpValidator::metaObject +24 (int (*)(...))QRegExpValidator::qt_metacast +32 (int (*)(...))QRegExpValidator::qt_metacall +40 (int (*)(...))QRegExpValidator::~QRegExpValidator +48 (int (*)(...))QRegExpValidator::~QRegExpValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QRegExpValidator::validate +120 (int (*)(...))QValidator::fixup + +Class QRegExpValidator + size=24 align=8 + base size=24 base align=8 +QRegExpValidator (0x0x7ff862ecae38) 0 + vptr=((& QRegExpValidator::_ZTV16QRegExpValidator) + 16u) + QValidator (0x0x7ff862ecaea0) 0 + primary-for QRegExpValidator (0x0x7ff862ecae38) + QObject (0x0x7ff862f43d80) 0 + primary-for QValidator (0x0x7ff862ecaea0) + +Class QRegularExpressionValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRegularExpressionValidator::QPrivateSignal (0x0x7ff862f43ea0) 0 empty + +Vtable for QRegularExpressionValidator +QRegularExpressionValidator::_ZTV27QRegularExpressionValidator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QRegularExpressionValidator) +16 (int (*)(...))QRegularExpressionValidator::metaObject +24 (int (*)(...))QRegularExpressionValidator::qt_metacast +32 (int (*)(...))QRegularExpressionValidator::qt_metacall +40 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator +48 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QRegularExpressionValidator::validate +120 (int (*)(...))QValidator::fixup + +Class QRegularExpressionValidator + size=16 align=8 + base size=16 base align=8 +QRegularExpressionValidator (0x0x7ff862ecaf08) 0 + vptr=((& QRegularExpressionValidator::_ZTV27QRegularExpressionValidator) + 16u) + QValidator (0x0x7ff862ecaf70) 0 + primary-for QRegularExpressionValidator (0x0x7ff862ecaf08) + QObject (0x0x7ff862f43e40) 0 + primary-for QValidator (0x0x7ff862ecaf70) + +Class QSizePolicy::Bits + size=4 align=4 + base size=4 base align=4 +QSizePolicy::Bits (0x0x7ff862f43f60) 0 + +Class QSizePolicy + size=4 align=4 + base size=4 base align=4 +QSizePolicy (0x0x7ff862f43f00) 0 + +Class QWidgetData + size=88 align=8 + base size=88 base align=8 +QWidgetData (0x0x7ff862c4f8a0) 0 + +Class QWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWidget::QPrivateSignal (0x0x7ff862c4f9c0) 0 empty + +Vtable for QWidget +QWidget::_ZTV7QWidget: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QWidget) +16 (int (*)(...))QWidget::metaObject +24 (int (*)(...))QWidget::qt_metacast +32 (int (*)(...))QWidget::qt_metacall +40 (int (*)(...))QWidget::~QWidget +48 (int (*)(...))QWidget::~QWidget +56 (int (*)(...))QWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI7QWidget) +448 (int (*)(...))QWidget::_ZThn16_N7QWidgetD1Ev +456 (int (*)(...))QWidget::_ZThn16_N7QWidgetD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QWidget + size=48 align=8 + base size=48 base align=8 +QWidget (0x0x7ff862caea80) 0 + vptr=((& QWidget::_ZTV7QWidget) + 16u) + QObject (0x0x7ff862c4f900) 0 + primary-for QWidget (0x0x7ff862caea80) + QPaintDevice (0x0x7ff862c4f960) 16 + vptr=((& QWidget::_ZTV7QWidget) + 448u) + +Class QAbstractButton::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractButton::QPrivateSignal (0x0x7ff862d8e660) 0 empty + +Vtable for QAbstractButton +QAbstractButton::_ZTV15QAbstractButton: 67u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAbstractButton) +16 (int (*)(...))QAbstractButton::metaObject +24 (int (*)(...))QAbstractButton::qt_metacast +32 (int (*)(...))QAbstractButton::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractButton::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractButton::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractButton::mousePressEvent +176 (int (*)(...))QAbstractButton::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractButton::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QAbstractButton::keyPressEvent +216 (int (*)(...))QAbstractButton::keyReleaseEvent +224 (int (*)(...))QAbstractButton::focusInEvent +232 (int (*)(...))QAbstractButton::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))__cxa_pure_virtual +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractButton::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QAbstractButton::hitButton +440 (int (*)(...))QAbstractButton::checkStateSet +448 (int (*)(...))QAbstractButton::nextCheckState +456 (int (*)(...))-16 +464 (int (*)(...))(& _ZTI15QAbstractButton) +472 0u +480 0u +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QAbstractButton + size=48 align=8 + base size=48 base align=8 +QAbstractButton (0x0x7ff8629ad2d8) 0 + vptr=((& QAbstractButton::_ZTV15QAbstractButton) + 16u) + QWidget (0x0x7ff8629a5770) 0 + primary-for QAbstractButton (0x0x7ff8629ad2d8) + QObject (0x0x7ff862d8e5a0) 0 + primary-for QWidget (0x0x7ff8629a5770) + QPaintDevice (0x0x7ff862d8e600) 16 + vptr=((& QAbstractButton::_ZTV15QAbstractButton) + 472u) + +Class QAbstractSpinBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractSpinBox::QPrivateSignal (0x0x7ff862d8e780) 0 empty + +Vtable for QAbstractSpinBox +QAbstractSpinBox::_ZTV16QAbstractSpinBox: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAbstractSpinBox) +16 (int (*)(...))QAbstractSpinBox::metaObject +24 (int (*)(...))QAbstractSpinBox::qt_metacast +32 (int (*)(...))QAbstractSpinBox::qt_metacall +40 (int (*)(...))QAbstractSpinBox::~QAbstractSpinBox +48 (int (*)(...))QAbstractSpinBox::~QAbstractSpinBox +56 (int (*)(...))QAbstractSpinBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSpinBox::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractSpinBox::sizeHint +136 (int (*)(...))QAbstractSpinBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractSpinBox::mousePressEvent +176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent +200 (int (*)(...))QAbstractSpinBox::wheelEvent +208 (int (*)(...))QAbstractSpinBox::keyPressEvent +216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent +224 (int (*)(...))QAbstractSpinBox::focusInEvent +232 (int (*)(...))QAbstractSpinBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractSpinBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractSpinBox::resizeEvent +280 (int (*)(...))QAbstractSpinBox::closeEvent +288 (int (*)(...))QAbstractSpinBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QAbstractSpinBox::showEvent +352 (int (*)(...))QAbstractSpinBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSpinBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QAbstractSpinBox::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QAbstractSpinBox::validate +440 (int (*)(...))QAbstractSpinBox::fixup +448 (int (*)(...))QAbstractSpinBox::stepBy +456 (int (*)(...))QAbstractSpinBox::clear +464 (int (*)(...))QAbstractSpinBox::stepEnabled +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI16QAbstractSpinBox) +488 (int (*)(...))QAbstractSpinBox::_ZThn16_N16QAbstractSpinBoxD1Ev +496 (int (*)(...))QAbstractSpinBox::_ZThn16_N16QAbstractSpinBoxD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QAbstractSpinBox + size=48 align=8 + base size=48 base align=8 +QAbstractSpinBox (0x0x7ff8629ad340) 0 + vptr=((& QAbstractSpinBox::_ZTV16QAbstractSpinBox) + 16u) + QWidget (0x0x7ff8629a5a80) 0 + primary-for QAbstractSpinBox (0x0x7ff8629ad340) + QObject (0x0x7ff862d8e6c0) 0 + primary-for QWidget (0x0x7ff8629a5a80) + QPaintDevice (0x0x7ff862d8e720) 16 + vptr=((& QAbstractSpinBox::_ZTV16QAbstractSpinBox) + 488u) + +Class QAbstractSlider::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractSlider::QPrivateSignal (0x0x7ff862d8ea20) 0 empty + +Vtable for QAbstractSlider +QAbstractSlider::_ZTV15QAbstractSlider: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAbstractSlider) +16 (int (*)(...))QAbstractSlider::metaObject +24 (int (*)(...))QAbstractSlider::qt_metacast +32 (int (*)(...))QAbstractSlider::qt_metacall +40 (int (*)(...))QAbstractSlider::~QAbstractSlider +48 (int (*)(...))QAbstractSlider::~QAbstractSlider +56 (int (*)(...))QAbstractSlider::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSlider::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QAbstractSlider::wheelEvent +208 (int (*)(...))QAbstractSlider::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSlider::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QAbstractSlider::sliderChange +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI15QAbstractSlider) +456 (int (*)(...))QAbstractSlider::_ZThn16_N15QAbstractSliderD1Ev +464 (int (*)(...))QAbstractSlider::_ZThn16_N15QAbstractSliderD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QAbstractSlider + size=48 align=8 + base size=48 base align=8 +QAbstractSlider (0x0x7ff8629ad478) 0 + vptr=((& QAbstractSlider::_ZTV15QAbstractSlider) + 16u) + QWidget (0x0x7ff8629e9e70) 0 + primary-for QAbstractSlider (0x0x7ff8629ad478) + QObject (0x0x7ff862d8e960) 0 + primary-for QWidget (0x0x7ff8629e9e70) + QPaintDevice (0x0x7ff862d8e9c0) 16 + vptr=((& QAbstractSlider::_ZTV15QAbstractSlider) + 456u) + +Class QSlider::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSlider::QPrivateSignal (0x0x7ff862d8eb40) 0 empty + +Vtable for QSlider +QSlider::_ZTV7QSlider: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QSlider) +16 (int (*)(...))QSlider::metaObject +24 (int (*)(...))QSlider::qt_metacast +32 (int (*)(...))QSlider::qt_metacall +40 (int (*)(...))QSlider::~QSlider +48 (int (*)(...))QSlider::~QSlider +56 (int (*)(...))QSlider::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSlider::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QSlider::sizeHint +136 (int (*)(...))QSlider::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QSlider::mousePressEvent +176 (int (*)(...))QSlider::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QSlider::mouseMoveEvent +200 (int (*)(...))QAbstractSlider::wheelEvent +208 (int (*)(...))QAbstractSlider::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QSlider::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSlider::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QAbstractSlider::sliderChange +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI7QSlider) +456 (int (*)(...))QSlider::_ZThn16_N7QSliderD1Ev +464 (int (*)(...))QSlider::_ZThn16_N7QSliderD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QSlider + size=48 align=8 + base size=48 base align=8 +QSlider (0x0x7ff8629ad4e0) 0 + vptr=((& QSlider::_ZTV7QSlider) + 16u) + QAbstractSlider (0x0x7ff8629ad548) 0 + primary-for QSlider (0x0x7ff8629ad4e0) + QWidget (0x0x7ff862a3a700) 0 + primary-for QAbstractSlider (0x0x7ff8629ad548) + QObject (0x0x7ff862d8ea80) 0 + primary-for QWidget (0x0x7ff862a3a700) + QPaintDevice (0x0x7ff862d8eae0) 16 + vptr=((& QSlider::_ZTV7QSlider) + 456u) + +Class QStyle::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStyle::QPrivateSignal (0x0x7ff862d8ec00) 0 empty + +Vtable for QStyle +QStyle::_ZTV6QStyle: 37u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QStyle) +16 (int (*)(...))QStyle::metaObject +24 (int (*)(...))QStyle::qt_metacast +32 (int (*)(...))QStyle::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStyle::polish +120 (int (*)(...))QStyle::unpolish +128 (int (*)(...))QStyle::polish +136 (int (*)(...))QStyle::unpolish +144 (int (*)(...))QStyle::polish +152 (int (*)(...))QStyle::itemTextRect +160 (int (*)(...))QStyle::itemPixmapRect +168 (int (*)(...))QStyle::drawItemText +176 (int (*)(...))QStyle::drawItemPixmap +184 (int (*)(...))QStyle::standardPalette +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))__cxa_pure_virtual +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))__cxa_pure_virtual +232 (int (*)(...))__cxa_pure_virtual +240 (int (*)(...))__cxa_pure_virtual +248 (int (*)(...))__cxa_pure_virtual +256 (int (*)(...))__cxa_pure_virtual +264 (int (*)(...))__cxa_pure_virtual +272 (int (*)(...))__cxa_pure_virtual +280 (int (*)(...))__cxa_pure_virtual +288 (int (*)(...))__cxa_pure_virtual + +Class QStyle + size=16 align=8 + base size=16 base align=8 +QStyle (0x0x7ff8629ad618) 0 + vptr=((& QStyle::_ZTV6QStyle) + 16u) + QObject (0x0x7ff862d8eba0) 0 + primary-for QStyle (0x0x7ff8629ad618) + +Class QTabBar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTabBar::QPrivateSignal (0x0x7ff862b1c060) 0 empty + +Vtable for QTabBar +QTabBar::_ZTV7QTabBar: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QTabBar) +16 (int (*)(...))QTabBar::metaObject +24 (int (*)(...))QTabBar::qt_metacast +32 (int (*)(...))QTabBar::qt_metacall +40 (int (*)(...))QTabBar::~QTabBar +48 (int (*)(...))QTabBar::~QTabBar +56 (int (*)(...))QTabBar::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTabBar::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QTabBar::sizeHint +136 (int (*)(...))QTabBar::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QTabBar::mousePressEvent +176 (int (*)(...))QTabBar::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QTabBar::mouseMoveEvent +200 (int (*)(...))QTabBar::wheelEvent +208 (int (*)(...))QTabBar::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTabBar::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QTabBar::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QTabBar::showEvent +352 (int (*)(...))QTabBar::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QTabBar::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QTabBar::tabSizeHint +440 (int (*)(...))QTabBar::minimumTabSizeHint +448 (int (*)(...))QTabBar::tabInserted +456 (int (*)(...))QTabBar::tabRemoved +464 (int (*)(...))QTabBar::tabLayoutChange +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI7QTabBar) +488 (int (*)(...))QTabBar::_ZThn16_N7QTabBarD1Ev +496 (int (*)(...))QTabBar::_ZThn16_N7QTabBarD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTabBar + size=48 align=8 + base size=48 base align=8 +QTabBar (0x0x7ff8629ad820) 0 + vptr=((& QTabBar::_ZTV7QTabBar) + 16u) + QWidget (0x0x7ff862b06690) 0 + primary-for QTabBar (0x0x7ff8629ad820) + QObject (0x0x7ff862d8ef60) 0 + primary-for QWidget (0x0x7ff862b06690) + QPaintDevice (0x0x7ff862b1c000) 16 + vptr=((& QTabBar::_ZTV7QTabBar) + 488u) + +Class QTabWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTabWidget::QPrivateSignal (0x0x7ff862b1c180) 0 empty + +Vtable for QTabWidget +QTabWidget::_ZTV10QTabWidget: 66u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTabWidget) +16 (int (*)(...))QTabWidget::metaObject +24 (int (*)(...))QTabWidget::qt_metacast +32 (int (*)(...))QTabWidget::qt_metacall +40 (int (*)(...))QTabWidget::~QTabWidget +48 (int (*)(...))QTabWidget::~QTabWidget +56 (int (*)(...))QTabWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QTabWidget::sizeHint +136 (int (*)(...))QTabWidget::minimumSizeHint +144 (int (*)(...))QTabWidget::heightForWidth +152 (int (*)(...))QTabWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QTabWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTabWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QTabWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QTabWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QTabWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QTabWidget::tabInserted +440 (int (*)(...))QTabWidget::tabRemoved +448 (int (*)(...))-16 +456 (int (*)(...))(& _ZTI10QTabWidget) +464 (int (*)(...))QTabWidget::_ZThn16_N10QTabWidgetD1Ev +472 (int (*)(...))QTabWidget::_ZThn16_N10QTabWidgetD0Ev +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTabWidget + size=48 align=8 + base size=48 base align=8 +QTabWidget (0x0x7ff8629ad888) 0 + vptr=((& QTabWidget::_ZTV10QTabWidget) + 16u) + QWidget (0x0x7ff862b46070) 0 + primary-for QTabWidget (0x0x7ff8629ad888) + QObject (0x0x7ff862b1c0c0) 0 + primary-for QWidget (0x0x7ff862b46070) + QPaintDevice (0x0x7ff862b1c120) 16 + vptr=((& QTabWidget::_ZTV10QTabWidget) + 464u) + +Class QRubberBand::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRubberBand::QPrivateSignal (0x0x7ff862b1c2a0) 0 empty + +Vtable for QRubberBand +QRubberBand::_ZTV11QRubberBand: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QRubberBand) +16 (int (*)(...))QRubberBand::metaObject +24 (int (*)(...))QRubberBand::qt_metacast +32 (int (*)(...))QRubberBand::qt_metacall +40 (int (*)(...))QRubberBand::~QRubberBand +48 (int (*)(...))QRubberBand::~QRubberBand +56 (int (*)(...))QRubberBand::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QRubberBand::paintEvent +264 (int (*)(...))QRubberBand::moveEvent +272 (int (*)(...))QRubberBand::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QRubberBand::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QRubberBand::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI11QRubberBand) +448 (int (*)(...))QRubberBand::_ZThn16_N11QRubberBandD1Ev +456 (int (*)(...))QRubberBand::_ZThn16_N11QRubberBandD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QRubberBand + size=48 align=8 + base size=48 base align=8 +QRubberBand (0x0x7ff8629ad8f0) 0 + vptr=((& QRubberBand::_ZTV11QRubberBand) + 16u) + QWidget (0x0x7ff862b46850) 0 + primary-for QRubberBand (0x0x7ff8629ad8f0) + QObject (0x0x7ff862b1c1e0) 0 + primary-for QWidget (0x0x7ff862b46850) + QPaintDevice (0x0x7ff862b1c240) 16 + vptr=((& QRubberBand::_ZTV11QRubberBand) + 448u) + +Class QFrame::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFrame::QPrivateSignal (0x0x7ff862b1c3c0) 0 empty + +Vtable for QFrame +QFrame::_ZTV6QFrame: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QFrame) +16 (int (*)(...))QFrame::metaObject +24 (int (*)(...))QFrame::qt_metacast +32 (int (*)(...))QFrame::qt_metacall +40 (int (*)(...))QFrame::~QFrame +48 (int (*)(...))QFrame::~QFrame +56 (int (*)(...))QFrame::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QFrame::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QFrame::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI6QFrame) +448 (int (*)(...))QFrame::_ZThn16_N6QFrameD1Ev +456 (int (*)(...))QFrame::_ZThn16_N6QFrameD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QFrame + size=48 align=8 + base size=48 base align=8 +QFrame (0x0x7ff8629ad958) 0 + vptr=((& QFrame::_ZTV6QFrame) + 16u) + QWidget (0x0x7ff862b46e70) 0 + primary-for QFrame (0x0x7ff8629ad958) + QObject (0x0x7ff862b1c300) 0 + primary-for QWidget (0x0x7ff862b46e70) + QPaintDevice (0x0x7ff862b1c360) 16 + vptr=((& QFrame::_ZTV6QFrame) + 448u) + +Class QStyleOption + size=64 align=8 + base size=64 base align=8 +QStyleOption (0x0x7ff862b1c420) 0 + +Class QStyleOptionFocusRect + size=80 align=8 + base size=80 base align=8 +QStyleOptionFocusRect (0x0x7ff8629ad9c0) 0 + QStyleOption (0x0x7ff862b1c480) 0 + +Class QStyleOptionFrame + size=80 align=8 + base size=80 base align=8 +QStyleOptionFrame (0x0x7ff8629ada28) 0 + QStyleOption (0x0x7ff862b1c4e0) 0 + +Class QStyleOptionTabWidgetFrame + size=136 align=8 + base size=132 base align=8 +QStyleOptionTabWidgetFrame (0x0x7ff8629adb60) 0 + QStyleOption (0x0x7ff862b1c6c0) 0 + +Class QStyleOptionTabBarBase + size=104 align=8 + base size=101 base align=8 +QStyleOptionTabBarBase (0x0x7ff8629adbc8) 0 + QStyleOption (0x0x7ff862b1c720) 0 + +Class QStyleOptionHeader + size=120 align=8 + base size=116 base align=8 +QStyleOptionHeader (0x0x7ff8629adc30) 0 + QStyleOption (0x0x7ff862b1c7e0) 0 + +Class QStyleOptionButton + size=96 align=8 + base size=96 base align=8 +QStyleOptionButton (0x0x7ff8629adc98) 0 + QStyleOption (0x0x7ff862b1c840) 0 + +Class QStyleOptionTab + size=136 align=8 + base size=136 base align=8 +QStyleOptionTab (0x0x7ff8629addd0) 0 + QStyleOption (0x0x7ff862b1ca20) 0 + +Class QStyleOptionToolBar + size=88 align=8 + base size=88 base align=8 +QStyleOptionToolBar (0x0x7ff862873000) 0 + QStyleOption (0x0x7ff862b1cd80) 0 + +Class QStyleOptionProgressBar + size=104 align=8 + base size=102 base align=8 +QStyleOptionProgressBar (0x0x7ff862873138) 0 + QStyleOption (0x0x7ff862b1cf60) 0 + +Class QStyleOptionMenuItem + size=136 align=8 + base size=136 base align=8 +QStyleOptionMenuItem (0x0x7ff8628731a0) 0 + QStyleOption (0x0x7ff8628bf000) 0 + +Class QStyleOptionDockWidget + size=80 align=8 + base size=76 base align=8 +QStyleOptionDockWidget (0x0x7ff862873208) 0 + QStyleOption (0x0x7ff8628bf060) 0 + +Class QStyleOptionViewItem + size=192 align=8 + base size=192 base align=8 +QStyleOptionViewItem (0x0x7ff8628732d8) 0 + QStyleOption (0x0x7ff8628bf0c0) 0 + +Class QStyleOptionToolBox + size=88 align=8 + base size=88 base align=8 +QStyleOptionToolBox (0x0x7ff862873410) 0 + QStyleOption (0x0x7ff8628bf2a0) 0 + +Class QStyleOptionRubberBand + size=72 align=8 + base size=69 base align=8 +QStyleOptionRubberBand (0x0x7ff862873478) 0 + QStyleOption (0x0x7ff8628bf300) 0 + +Class QStyleOptionComplex + size=72 align=8 + base size=72 base align=8 +QStyleOptionComplex (0x0x7ff8628734e0) 0 + QStyleOption (0x0x7ff8628bf360) 0 + +Class QStyleOptionSlider + size=128 align=8 + base size=121 base align=8 +QStyleOptionSlider (0x0x7ff862873548) 0 + QStyleOptionComplex (0x0x7ff8628735b0) 0 + QStyleOption (0x0x7ff8628bf3c0) 0 + +Class QStyleOptionSpinBox + size=88 align=8 + base size=81 base align=8 +QStyleOptionSpinBox (0x0x7ff862873618) 0 + QStyleOptionComplex (0x0x7ff862873680) 0 + QStyleOption (0x0x7ff8628bf420) 0 + +Class QStyleOptionToolButton + size=136 align=8 + base size=136 base align=8 +QStyleOptionToolButton (0x0x7ff8628736e8) 0 + QStyleOptionComplex (0x0x7ff862873750) 0 + QStyleOption (0x0x7ff8628bf480) 0 + +Class QStyleOptionComboBox + size=120 align=8 + base size=120 base align=8 +QStyleOptionComboBox (0x0x7ff862873888) 0 + QStyleOptionComplex (0x0x7ff8628738f0) 0 + QStyleOption (0x0x7ff8628bf660) 0 + +Class QStyleOptionTitleBar + size=96 align=8 + base size=96 base align=8 +QStyleOptionTitleBar (0x0x7ff862873958) 0 + QStyleOptionComplex (0x0x7ff8628739c0) 0 + QStyleOption (0x0x7ff8628bf6c0) 0 + +Class QStyleOptionGroupBox + size=120 align=8 + base size=116 base align=8 +QStyleOptionGroupBox (0x0x7ff862873a28) 0 + QStyleOptionComplex (0x0x7ff862873a90) 0 + QStyleOption (0x0x7ff8628bf780) 0 + +Class QStyleOptionSizeGrip + size=80 align=8 + base size=76 base align=8 +QStyleOptionSizeGrip (0x0x7ff862873af8) 0 + QStyleOptionComplex (0x0x7ff862873b60) 0 + QStyleOption (0x0x7ff8628bf7e0) 0 + +Class QStyleOptionGraphicsItem + size=152 align=8 + base size=152 base align=8 +QStyleOptionGraphicsItem (0x0x7ff862873bc8) 0 + QStyleOption (0x0x7ff8628bf840) 0 + +Class QStyleHintReturn + size=8 align=4 + base size=8 base align=4 +QStyleHintReturn (0x0x7ff8628bfd20) 0 + +Class QStyleHintReturnMask + size=16 align=8 + base size=16 base align=8 +QStyleHintReturnMask (0x0x7ff8625d31a0) 0 + QStyleHintReturn (0x0x7ff8628bfd80) 0 + +Class QStyleHintReturnVariant + size=24 align=8 + base size=24 base align=8 +QStyleHintReturnVariant (0x0x7ff8625d3208) 0 + QStyleHintReturn (0x0x7ff8628bfde0) 0 + +Class QAbstractItemDelegate::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemDelegate::QPrivateSignal (0x0x7ff8625fc360) 0 empty + +Vtable for QAbstractItemDelegate +QAbstractItemDelegate::_ZTV21QAbstractItemDelegate: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QAbstractItemDelegate) +16 (int (*)(...))QAbstractItemDelegate::metaObject +24 (int (*)(...))QAbstractItemDelegate::qt_metacast +32 (int (*)(...))QAbstractItemDelegate::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemDelegate::createEditor +136 (int (*)(...))QAbstractItemDelegate::destroyEditor +144 (int (*)(...))QAbstractItemDelegate::setEditorData +152 (int (*)(...))QAbstractItemDelegate::setModelData +160 (int (*)(...))QAbstractItemDelegate::updateEditorGeometry +168 (int (*)(...))QAbstractItemDelegate::editorEvent +176 (int (*)(...))QAbstractItemDelegate::helpEvent +184 (int (*)(...))QAbstractItemDelegate::paintingRoles + +Class QAbstractItemDelegate + size=16 align=8 + base size=16 base align=8 +QAbstractItemDelegate (0x0x7ff8625d3750) 0 + vptr=((& QAbstractItemDelegate::_ZTV21QAbstractItemDelegate) + 16u) + QObject (0x0x7ff8625fc300) 0 + primary-for QAbstractItemDelegate (0x0x7ff8625d3750) + +Class QAbstractScrollArea::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractScrollArea::QPrivateSignal (0x0x7ff8625fc4e0) 0 empty + +Vtable for QAbstractScrollArea +QAbstractScrollArea::_ZTV19QAbstractScrollArea: 68u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractScrollArea) +16 (int (*)(...))QAbstractScrollArea::metaObject +24 (int (*)(...))QAbstractScrollArea::qt_metacast +32 (int (*)(...))QAbstractScrollArea::qt_metacall +40 (int (*)(...))QAbstractScrollArea::~QAbstractScrollArea +48 (int (*)(...))QAbstractScrollArea::~QAbstractScrollArea +56 (int (*)(...))QAbstractScrollArea::event +64 (int (*)(...))QAbstractScrollArea::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractScrollArea::mousePressEvent +176 (int (*)(...))QAbstractScrollArea::mouseReleaseEvent +184 (int (*)(...))QAbstractScrollArea::mouseDoubleClickEvent +192 (int (*)(...))QAbstractScrollArea::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractScrollArea::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractScrollArea::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractScrollArea::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractScrollArea::dragEnterEvent +320 (int (*)(...))QAbstractScrollArea::dragMoveEvent +328 (int (*)(...))QAbstractScrollArea::dragLeaveEvent +336 (int (*)(...))QAbstractScrollArea::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractScrollArea::viewportEvent +448 (int (*)(...))QAbstractScrollArea::scrollContentsBy +456 (int (*)(...))QAbstractScrollArea::viewportSizeHint +464 (int (*)(...))-16 +472 (int (*)(...))(& _ZTI19QAbstractScrollArea) +480 (int (*)(...))QAbstractScrollArea::_ZThn16_N19QAbstractScrollAreaD1Ev +488 (int (*)(...))QAbstractScrollArea::_ZThn16_N19QAbstractScrollAreaD0Ev +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QAbstractScrollArea + size=48 align=8 + base size=48 base align=8 +QAbstractScrollArea (0x0x7ff8625d37b8) 0 + vptr=((& QAbstractScrollArea::_ZTV19QAbstractScrollArea) + 16u) + QFrame (0x0x7ff8625d3820) 0 + primary-for QAbstractScrollArea (0x0x7ff8625d37b8) + QWidget (0x0x7ff8625f7b60) 0 + primary-for QFrame (0x0x7ff8625d3820) + QObject (0x0x7ff8625fc420) 0 + primary-for QWidget (0x0x7ff8625f7b60) + QPaintDevice (0x0x7ff8625fc480) 16 + vptr=((& QAbstractScrollArea::_ZTV19QAbstractScrollArea) + 480u) + +Class QAbstractItemView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemView::QPrivateSignal (0x0x7ff8625fc600) 0 empty + +Vtable for QAbstractItemView +QAbstractItemView::_ZTV17QAbstractItemView: 106u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAbstractItemView) +16 (int (*)(...))QAbstractItemView::metaObject +24 (int (*)(...))QAbstractItemView::qt_metacast +32 (int (*)(...))QAbstractItemView::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractItemView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QAbstractItemView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QAbstractItemView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QAbstractItemView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractScrollArea::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractItemView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QAbstractItemView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QAbstractItemView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractItemView::viewportEvent +448 (int (*)(...))QAbstractScrollArea::scrollContentsBy +456 (int (*)(...))QAbstractItemView::viewportSizeHint +464 (int (*)(...))QAbstractItemView::setModel +472 (int (*)(...))QAbstractItemView::setSelectionModel +480 (int (*)(...))QAbstractItemView::keyboardSearch +488 (int (*)(...))__cxa_pure_virtual +496 (int (*)(...))__cxa_pure_virtual +504 (int (*)(...))__cxa_pure_virtual +512 (int (*)(...))QAbstractItemView::sizeHintForRow +520 (int (*)(...))QAbstractItemView::sizeHintForColumn +528 (int (*)(...))QAbstractItemView::reset +536 (int (*)(...))QAbstractItemView::setRootIndex +544 (int (*)(...))QAbstractItemView::doItemsLayout +552 (int (*)(...))QAbstractItemView::selectAll +560 (int (*)(...))QAbstractItemView::dataChanged +568 (int (*)(...))QAbstractItemView::rowsInserted +576 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved +584 (int (*)(...))QAbstractItemView::selectionChanged +592 (int (*)(...))QAbstractItemView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QAbstractItemView::updateGeometries +624 (int (*)(...))QAbstractItemView::verticalScrollbarAction +632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction +640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))__cxa_pure_virtual +688 (int (*)(...))__cxa_pure_virtual +696 (int (*)(...))__cxa_pure_virtual +704 (int (*)(...))__cxa_pure_virtual +712 (int (*)(...))__cxa_pure_virtual +720 (int (*)(...))__cxa_pure_virtual +728 (int (*)(...))QAbstractItemView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QAbstractItemView::startDrag +760 (int (*)(...))QAbstractItemView::viewOptions +768 (int (*)(...))-16 +776 (int (*)(...))(& _ZTI17QAbstractItemView) +784 0u +792 0u +800 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +808 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +816 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QAbstractItemView + size=48 align=8 + base size=48 base align=8 +QAbstractItemView (0x0x7ff8625d3888) 0 + vptr=((& QAbstractItemView::_ZTV17QAbstractItemView) + 16u) + QAbstractScrollArea (0x0x7ff8625d38f0) 0 + primary-for QAbstractItemView (0x0x7ff8625d3888) + QFrame (0x0x7ff8625d3958) 0 + primary-for QAbstractScrollArea (0x0x7ff8625d38f0) + QWidget (0x0x7ff8626390e0) 0 + primary-for QFrame (0x0x7ff8625d3958) + QObject (0x0x7ff8625fc540) 0 + primary-for QWidget (0x0x7ff8626390e0) + QPaintDevice (0x0x7ff8625fc5a0) 16 + vptr=((& QAbstractItemView::_ZTV17QAbstractItemView) + 784u) + +Vtable for QAccessibleWidget +QAccessibleWidget::_ZTV17QAccessibleWidget: 35u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleWidget) +16 (int (*)(...))QAccessibleWidget::~QAccessibleWidget +24 (int (*)(...))QAccessibleWidget::~QAccessibleWidget +32 (int (*)(...))QAccessibleWidget::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleWidget::window +56 (int (*)(...))QAccessibleWidget::relations +64 (int (*)(...))QAccessibleWidget::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))QAccessibleWidget::parent +88 (int (*)(...))QAccessibleWidget::child +96 (int (*)(...))QAccessibleWidget::childCount +104 (int (*)(...))QAccessibleWidget::indexOfChild +112 (int (*)(...))QAccessibleWidget::text +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleWidget::rect +136 (int (*)(...))QAccessibleWidget::role +144 (int (*)(...))QAccessibleWidget::state +152 (int (*)(...))QAccessibleWidget::foregroundColor +160 (int (*)(...))QAccessibleWidget::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleWidget::interface_cast +184 (int (*)(...))QAccessibleWidget::actionNames +192 (int (*)(...))QAccessibleWidget::doAction +200 (int (*)(...))QAccessibleWidget::keyBindingsForAction +208 (int (*)(...))-16 +216 (int (*)(...))(& _ZTI17QAccessibleWidget) +224 (int (*)(...))QAccessibleWidget::_ZThn16_N17QAccessibleWidgetD1Ev +232 (int (*)(...))QAccessibleWidget::_ZThn16_N17QAccessibleWidgetD0Ev +240 (int (*)(...))QAccessibleWidget::_ZThn16_NK17QAccessibleWidget11actionNamesEv +248 (int (*)(...))QAccessibleActionInterface::localizedActionName +256 (int (*)(...))QAccessibleActionInterface::localizedActionDescription +264 (int (*)(...))QAccessibleWidget::_ZThn16_N17QAccessibleWidget8doActionERK7QString +272 (int (*)(...))QAccessibleWidget::_ZThn16_NK17QAccessibleWidget20keyBindingsForActionERK7QString + +Class QAccessibleWidget + size=32 align=8 + base size=32 base align=8 +QAccessibleWidget (0x0x7ff8626a47e0) 0 + vptr=((& QAccessibleWidget::_ZTV17QAccessibleWidget) + 16u) + QAccessibleObject (0x0x7ff8625d3a90) 0 + primary-for QAccessibleWidget (0x0x7ff8626a47e0) + QAccessibleInterface (0x0x7ff8625fc7e0) 0 nearly-empty + primary-for QAccessibleObject (0x0x7ff8625d3a90) + QAccessibleActionInterface (0x0x7ff8625fc840) 16 nearly-empty + vptr=((& QAccessibleWidget::_ZTV17QAccessibleWidget) + 224u) + +Class QAction::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAction::QPrivateSignal (0x0x7ff8625fc960) 0 empty + +Vtable for QAction +QAction::_ZTV7QAction: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QAction) +16 (int (*)(...))QAction::metaObject +24 (int (*)(...))QAction::qt_metacast +32 (int (*)(...))QAction::qt_metacall +40 (int (*)(...))QAction::~QAction +48 (int (*)(...))QAction::~QAction +56 (int (*)(...))QAction::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QAction + size=16 align=8 + base size=16 base align=8 +QAction (0x0x7ff8625d3af8) 0 + vptr=((& QAction::_ZTV7QAction) + 16u) + QObject (0x0x7ff8625fc900) 0 + primary-for QAction (0x0x7ff8625d3af8) + +Class QActionGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QActionGroup::QPrivateSignal (0x0x7ff8625fca20) 0 empty + +Vtable for QActionGroup +QActionGroup::_ZTV12QActionGroup: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QActionGroup) +16 (int (*)(...))QActionGroup::metaObject +24 (int (*)(...))QActionGroup::qt_metacast +32 (int (*)(...))QActionGroup::qt_metacall +40 (int (*)(...))QActionGroup::~QActionGroup +48 (int (*)(...))QActionGroup::~QActionGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QActionGroup + size=16 align=8 + base size=16 base align=8 +QActionGroup (0x0x7ff8625d3b60) 0 + vptr=((& QActionGroup::_ZTV12QActionGroup) + 16u) + QObject (0x0x7ff8625fc9c0) 0 + primary-for QActionGroup (0x0x7ff8625d3b60) + +Class QApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QApplication::QPrivateSignal (0x0x7ff8625fcae0) 0 empty + +Vtable for QApplication +QApplication::_ZTV12QApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QApplication) +16 (int (*)(...))QApplication::metaObject +24 (int (*)(...))QApplication::qt_metacast +32 (int (*)(...))QApplication::qt_metacall +40 (int (*)(...))QApplication::~QApplication +48 (int (*)(...))QApplication::~QApplication +56 (int (*)(...))QApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QApplication::notify +120 (int (*)(...))QApplication::compressEvent + +Class QApplication + size=16 align=8 + base size=16 base align=8 +QApplication (0x0x7ff8625d3bc8) 0 + vptr=((& QApplication::_ZTV12QApplication) + 16u) + QGuiApplication (0x0x7ff8625d3c30) 0 + primary-for QApplication (0x0x7ff8625d3bc8) + QCoreApplication (0x0x7ff8625d3c98) 0 + primary-for QGuiApplication (0x0x7ff8625d3c30) + QObject (0x0x7ff8625fca80) 0 + primary-for QCoreApplication (0x0x7ff8625d3c98) + +Vtable for QLayoutItem +QLayoutItem::_ZTV11QLayoutItem: 19u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QLayoutItem) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QLayoutItem::hasHeightForWidth +96 (int (*)(...))QLayoutItem::heightForWidth +104 (int (*)(...))QLayoutItem::minimumHeightForWidth +112 (int (*)(...))QLayoutItem::invalidate +120 (int (*)(...))QLayoutItem::widget +128 (int (*)(...))QLayoutItem::layout +136 (int (*)(...))QLayoutItem::spacerItem +144 (int (*)(...))QLayoutItem::controlTypes + +Class QLayoutItem + size=16 align=8 + base size=12 base align=8 +QLayoutItem (0x0x7ff8625fcb40) 0 + vptr=((& QLayoutItem::_ZTV11QLayoutItem) + 16u) + +Vtable for QSpacerItem +QSpacerItem::_ZTV11QSpacerItem: 19u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSpacerItem) +16 (int (*)(...))QSpacerItem::~QSpacerItem +24 (int (*)(...))QSpacerItem::~QSpacerItem +32 (int (*)(...))QSpacerItem::sizeHint +40 (int (*)(...))QSpacerItem::minimumSize +48 (int (*)(...))QSpacerItem::maximumSize +56 (int (*)(...))QSpacerItem::expandingDirections +64 (int (*)(...))QSpacerItem::setGeometry +72 (int (*)(...))QSpacerItem::geometry +80 (int (*)(...))QSpacerItem::isEmpty +88 (int (*)(...))QLayoutItem::hasHeightForWidth +96 (int (*)(...))QLayoutItem::heightForWidth +104 (int (*)(...))QLayoutItem::minimumHeightForWidth +112 (int (*)(...))QLayoutItem::invalidate +120 (int (*)(...))QLayoutItem::widget +128 (int (*)(...))QLayoutItem::layout +136 (int (*)(...))QSpacerItem::spacerItem +144 (int (*)(...))QLayoutItem::controlTypes + +Class QSpacerItem + size=40 align=8 + base size=40 base align=8 +QSpacerItem (0x0x7ff8625d3d00) 0 + vptr=((& QSpacerItem::_ZTV11QSpacerItem) + 16u) + QLayoutItem (0x0x7ff8625fcba0) 0 + primary-for QSpacerItem (0x0x7ff8625d3d00) + +Vtable for QWidgetItem +QWidgetItem::_ZTV11QWidgetItem: 19u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QWidgetItem) +16 (int (*)(...))QWidgetItem::~QWidgetItem +24 (int (*)(...))QWidgetItem::~QWidgetItem +32 (int (*)(...))QWidgetItem::sizeHint +40 (int (*)(...))QWidgetItem::minimumSize +48 (int (*)(...))QWidgetItem::maximumSize +56 (int (*)(...))QWidgetItem::expandingDirections +64 (int (*)(...))QWidgetItem::setGeometry +72 (int (*)(...))QWidgetItem::geometry +80 (int (*)(...))QWidgetItem::isEmpty +88 (int (*)(...))QWidgetItem::hasHeightForWidth +96 (int (*)(...))QWidgetItem::heightForWidth +104 (int (*)(...))QLayoutItem::minimumHeightForWidth +112 (int (*)(...))QLayoutItem::invalidate +120 (int (*)(...))QWidgetItem::widget +128 (int (*)(...))QLayoutItem::layout +136 (int (*)(...))QLayoutItem::spacerItem +144 (int (*)(...))QWidgetItem::controlTypes + +Class QWidgetItem + size=24 align=8 + base size=24 base align=8 +QWidgetItem (0x0x7ff8625d3d68) 0 + vptr=((& QWidgetItem::_ZTV11QWidgetItem) + 16u) + QLayoutItem (0x0x7ff8625fcc00) 0 + primary-for QWidgetItem (0x0x7ff8625d3d68) + +Vtable for QWidgetItemV2 +QWidgetItemV2::_ZTV13QWidgetItemV2: 19u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QWidgetItemV2) +16 (int (*)(...))QWidgetItemV2::~QWidgetItemV2 +24 (int (*)(...))QWidgetItemV2::~QWidgetItemV2 +32 (int (*)(...))QWidgetItemV2::sizeHint +40 (int (*)(...))QWidgetItemV2::minimumSize +48 (int (*)(...))QWidgetItemV2::maximumSize +56 (int (*)(...))QWidgetItem::expandingDirections +64 (int (*)(...))QWidgetItem::setGeometry +72 (int (*)(...))QWidgetItem::geometry +80 (int (*)(...))QWidgetItem::isEmpty +88 (int (*)(...))QWidgetItem::hasHeightForWidth +96 (int (*)(...))QWidgetItemV2::heightForWidth +104 (int (*)(...))QLayoutItem::minimumHeightForWidth +112 (int (*)(...))QLayoutItem::invalidate +120 (int (*)(...))QWidgetItem::widget +128 (int (*)(...))QLayoutItem::layout +136 (int (*)(...))QLayoutItem::spacerItem +144 (int (*)(...))QWidgetItem::controlTypes + +Class QWidgetItemV2 + size=88 align=8 + base size=88 base align=8 +QWidgetItemV2 (0x0x7ff8625d3dd0) 0 + vptr=((& QWidgetItemV2::_ZTV13QWidgetItemV2) + 16u) + QWidgetItem (0x0x7ff8625d3e38) 0 + primary-for QWidgetItemV2 (0x0x7ff8625d3dd0) + QLayoutItem (0x0x7ff8625fcc60) 0 + primary-for QWidgetItem (0x0x7ff8625d3e38) + +Class QLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLayout::QPrivateSignal (0x0x7ff8625fcd80) 0 empty + +Vtable for QLayout +QLayout::_ZTV7QLayout: 47u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QLayout) +16 (int (*)(...))QLayout::metaObject +24 (int (*)(...))QLayout::qt_metacast +32 (int (*)(...))QLayout::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLayout::invalidate +120 (int (*)(...))QLayout::geometry +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))QLayout::expandingDirections +144 (int (*)(...))QLayout::minimumSize +152 (int (*)(...))QLayout::maximumSize +160 (int (*)(...))QLayout::setGeometry +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))QLayout::indexOf +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))QLayout::isEmpty +208 (int (*)(...))QLayout::controlTypes +216 (int (*)(...))QLayout::layout +224 (int (*)(...))-16 +232 (int (*)(...))(& _ZTI7QLayout) +240 0u +248 0u +256 (int (*)(...))__cxa_pure_virtual +264 (int (*)(...))QLayout::_ZThn16_NK7QLayout11minimumSizeEv +272 (int (*)(...))QLayout::_ZThn16_NK7QLayout11maximumSizeEv +280 (int (*)(...))QLayout::_ZThn16_NK7QLayout19expandingDirectionsEv +288 (int (*)(...))QLayout::_ZThn16_N7QLayout11setGeometryERK5QRect +296 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +304 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +312 (int (*)(...))QLayoutItem::hasHeightForWidth +320 (int (*)(...))QLayoutItem::heightForWidth +328 (int (*)(...))QLayoutItem::minimumHeightForWidth +336 (int (*)(...))QLayout::_ZThn16_N7QLayout10invalidateEv +344 (int (*)(...))QLayoutItem::widget +352 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +360 (int (*)(...))QLayoutItem::spacerItem +368 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QLayout + size=32 align=8 + base size=28 base align=8 +QLayout (0x0x7ff862732850) 0 + vptr=((& QLayout::_ZTV7QLayout) + 16u) + QObject (0x0x7ff8625fccc0) 0 + primary-for QLayout (0x0x7ff862732850) + QLayoutItem (0x0x7ff8625fcd20) 16 + vptr=((& QLayout::_ZTV7QLayout) + 240u) + +Class QGridLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGridLayout::QPrivateSignal (0x0x7ff8625fcea0) 0 empty + +Vtable for QGridLayout +QGridLayout::_ZTV11QGridLayout: 51u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QGridLayout) +16 (int (*)(...))QGridLayout::metaObject +24 (int (*)(...))QGridLayout::qt_metacast +32 (int (*)(...))QGridLayout::qt_metacall +40 (int (*)(...))QGridLayout::~QGridLayout +48 (int (*)(...))QGridLayout::~QGridLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGridLayout::invalidate +120 (int (*)(...))QLayout::geometry +128 (int (*)(...))QGridLayout::addItem +136 (int (*)(...))QGridLayout::expandingDirections +144 (int (*)(...))QGridLayout::minimumSize +152 (int (*)(...))QGridLayout::maximumSize +160 (int (*)(...))QGridLayout::setGeometry +168 (int (*)(...))QGridLayout::itemAt +176 (int (*)(...))QGridLayout::takeAt +184 (int (*)(...))QLayout::indexOf +192 (int (*)(...))QGridLayout::count +200 (int (*)(...))QLayout::isEmpty +208 (int (*)(...))QLayout::controlTypes +216 (int (*)(...))QLayout::layout +224 (int (*)(...))QGridLayout::sizeHint +232 (int (*)(...))QGridLayout::hasHeightForWidth +240 (int (*)(...))QGridLayout::heightForWidth +248 (int (*)(...))QGridLayout::minimumHeightForWidth +256 (int (*)(...))-16 +264 (int (*)(...))(& _ZTI11QGridLayout) +272 (int (*)(...))QGridLayout::_ZThn16_N11QGridLayoutD1Ev +280 (int (*)(...))QGridLayout::_ZThn16_N11QGridLayoutD0Ev +288 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout8sizeHintEv +296 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout11minimumSizeEv +304 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout11maximumSizeEv +312 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout19expandingDirectionsEv +320 (int (*)(...))QGridLayout::_ZThn16_N11QGridLayout11setGeometryERK5QRect +328 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +336 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +344 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout17hasHeightForWidthEv +352 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout14heightForWidthEi +360 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout21minimumHeightForWidthEi +368 (int (*)(...))QGridLayout::_ZThn16_N11QGridLayout10invalidateEv +376 (int (*)(...))QLayoutItem::widget +384 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +392 (int (*)(...))QLayoutItem::spacerItem +400 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QGridLayout + size=32 align=8 + base size=28 base align=8 +QGridLayout (0x0x7ff8625d3ea0) 0 + vptr=((& QGridLayout::_ZTV11QGridLayout) + 16u) + QLayout (0x0x7ff862374070) 0 + primary-for QGridLayout (0x0x7ff8625d3ea0) + QObject (0x0x7ff8625fcde0) 0 + primary-for QLayout (0x0x7ff862374070) + QLayoutItem (0x0x7ff8625fce40) 16 + vptr=((& QGridLayout::_ZTV11QGridLayout) + 272u) + +Class QBoxLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBoxLayout::QPrivateSignal (0x0x7ff862399000) 0 empty + +Vtable for QBoxLayout +QBoxLayout::_ZTV10QBoxLayout: 51u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QBoxLayout) +16 (int (*)(...))QBoxLayout::metaObject +24 (int (*)(...))QBoxLayout::qt_metacast +32 (int (*)(...))QBoxLayout::qt_metacall +40 (int (*)(...))QBoxLayout::~QBoxLayout +48 (int (*)(...))QBoxLayout::~QBoxLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QBoxLayout::invalidate +120 (int (*)(...))QLayout::geometry +128 (int (*)(...))QBoxLayout::addItem +136 (int (*)(...))QBoxLayout::expandingDirections +144 (int (*)(...))QBoxLayout::minimumSize +152 (int (*)(...))QBoxLayout::maximumSize +160 (int (*)(...))QBoxLayout::setGeometry +168 (int (*)(...))QBoxLayout::itemAt +176 (int (*)(...))QBoxLayout::takeAt +184 (int (*)(...))QLayout::indexOf +192 (int (*)(...))QBoxLayout::count +200 (int (*)(...))QLayout::isEmpty +208 (int (*)(...))QLayout::controlTypes +216 (int (*)(...))QLayout::layout +224 (int (*)(...))QBoxLayout::sizeHint +232 (int (*)(...))QBoxLayout::hasHeightForWidth +240 (int (*)(...))QBoxLayout::heightForWidth +248 (int (*)(...))QBoxLayout::minimumHeightForWidth +256 (int (*)(...))-16 +264 (int (*)(...))(& _ZTI10QBoxLayout) +272 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayoutD1Ev +280 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayoutD0Ev +288 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout8sizeHintEv +296 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11minimumSizeEv +304 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11maximumSizeEv +312 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout19expandingDirectionsEv +320 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout11setGeometryERK5QRect +328 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +336 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +344 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout17hasHeightForWidthEv +352 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout14heightForWidthEi +360 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout21minimumHeightForWidthEi +368 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout10invalidateEv +376 (int (*)(...))QLayoutItem::widget +384 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +392 (int (*)(...))QLayoutItem::spacerItem +400 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QBoxLayout + size=32 align=8 + base size=28 base align=8 +QBoxLayout (0x0x7ff8625d3f08) 0 + vptr=((& QBoxLayout::_ZTV10QBoxLayout) + 16u) + QLayout (0x0x7ff862374620) 0 + primary-for QBoxLayout (0x0x7ff8625d3f08) + QObject (0x0x7ff8625fcf00) 0 + primary-for QLayout (0x0x7ff862374620) + QLayoutItem (0x0x7ff8625fcf60) 16 + vptr=((& QBoxLayout::_ZTV10QBoxLayout) + 272u) + +Class QHBoxLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHBoxLayout::QPrivateSignal (0x0x7ff862399120) 0 empty + +Vtable for QHBoxLayout +QHBoxLayout::_ZTV11QHBoxLayout: 51u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QHBoxLayout) +16 (int (*)(...))QHBoxLayout::metaObject +24 (int (*)(...))QHBoxLayout::qt_metacast +32 (int (*)(...))QHBoxLayout::qt_metacall +40 (int (*)(...))QHBoxLayout::~QHBoxLayout +48 (int (*)(...))QHBoxLayout::~QHBoxLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QBoxLayout::invalidate +120 (int (*)(...))QLayout::geometry +128 (int (*)(...))QBoxLayout::addItem +136 (int (*)(...))QBoxLayout::expandingDirections +144 (int (*)(...))QBoxLayout::minimumSize +152 (int (*)(...))QBoxLayout::maximumSize +160 (int (*)(...))QBoxLayout::setGeometry +168 (int (*)(...))QBoxLayout::itemAt +176 (int (*)(...))QBoxLayout::takeAt +184 (int (*)(...))QLayout::indexOf +192 (int (*)(...))QBoxLayout::count +200 (int (*)(...))QLayout::isEmpty +208 (int (*)(...))QLayout::controlTypes +216 (int (*)(...))QLayout::layout +224 (int (*)(...))QBoxLayout::sizeHint +232 (int (*)(...))QBoxLayout::hasHeightForWidth +240 (int (*)(...))QBoxLayout::heightForWidth +248 (int (*)(...))QBoxLayout::minimumHeightForWidth +256 (int (*)(...))-16 +264 (int (*)(...))(& _ZTI11QHBoxLayout) +272 (int (*)(...))QHBoxLayout::_ZThn16_N11QHBoxLayoutD1Ev +280 (int (*)(...))QHBoxLayout::_ZThn16_N11QHBoxLayoutD0Ev +288 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout8sizeHintEv +296 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11minimumSizeEv +304 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11maximumSizeEv +312 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout19expandingDirectionsEv +320 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout11setGeometryERK5QRect +328 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +336 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +344 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout17hasHeightForWidthEv +352 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout14heightForWidthEi +360 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout21minimumHeightForWidthEi +368 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout10invalidateEv +376 (int (*)(...))QLayoutItem::widget +384 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +392 (int (*)(...))QLayoutItem::spacerItem +400 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QHBoxLayout + size=32 align=8 + base size=28 base align=8 +QHBoxLayout (0x0x7ff8623b2000) 0 + vptr=((& QHBoxLayout::_ZTV11QHBoxLayout) + 16u) + QBoxLayout (0x0x7ff8623b2068) 0 + primary-for QHBoxLayout (0x0x7ff8623b2000) + QLayout (0x0x7ff862374cb0) 0 + primary-for QBoxLayout (0x0x7ff8623b2068) + QObject (0x0x7ff862399060) 0 + primary-for QLayout (0x0x7ff862374cb0) + QLayoutItem (0x0x7ff8623990c0) 16 + vptr=((& QHBoxLayout::_ZTV11QHBoxLayout) + 272u) + +Class QVBoxLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVBoxLayout::QPrivateSignal (0x0x7ff862399240) 0 empty + +Vtable for QVBoxLayout +QVBoxLayout::_ZTV11QVBoxLayout: 51u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QVBoxLayout) +16 (int (*)(...))QVBoxLayout::metaObject +24 (int (*)(...))QVBoxLayout::qt_metacast +32 (int (*)(...))QVBoxLayout::qt_metacall +40 (int (*)(...))QVBoxLayout::~QVBoxLayout +48 (int (*)(...))QVBoxLayout::~QVBoxLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QBoxLayout::invalidate +120 (int (*)(...))QLayout::geometry +128 (int (*)(...))QBoxLayout::addItem +136 (int (*)(...))QBoxLayout::expandingDirections +144 (int (*)(...))QBoxLayout::minimumSize +152 (int (*)(...))QBoxLayout::maximumSize +160 (int (*)(...))QBoxLayout::setGeometry +168 (int (*)(...))QBoxLayout::itemAt +176 (int (*)(...))QBoxLayout::takeAt +184 (int (*)(...))QLayout::indexOf +192 (int (*)(...))QBoxLayout::count +200 (int (*)(...))QLayout::isEmpty +208 (int (*)(...))QLayout::controlTypes +216 (int (*)(...))QLayout::layout +224 (int (*)(...))QBoxLayout::sizeHint +232 (int (*)(...))QBoxLayout::hasHeightForWidth +240 (int (*)(...))QBoxLayout::heightForWidth +248 (int (*)(...))QBoxLayout::minimumHeightForWidth +256 (int (*)(...))-16 +264 (int (*)(...))(& _ZTI11QVBoxLayout) +272 (int (*)(...))QVBoxLayout::_ZThn16_N11QVBoxLayoutD1Ev +280 (int (*)(...))QVBoxLayout::_ZThn16_N11QVBoxLayoutD0Ev +288 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout8sizeHintEv +296 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11minimumSizeEv +304 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11maximumSizeEv +312 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout19expandingDirectionsEv +320 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout11setGeometryERK5QRect +328 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +336 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +344 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout17hasHeightForWidthEv +352 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout14heightForWidthEi +360 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout21minimumHeightForWidthEi +368 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout10invalidateEv +376 (int (*)(...))QLayoutItem::widget +384 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +392 (int (*)(...))QLayoutItem::spacerItem +400 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QVBoxLayout + size=32 align=8 + base size=28 base align=8 +QVBoxLayout (0x0x7ff8623b20d0) 0 + vptr=((& QVBoxLayout::_ZTV11QVBoxLayout) + 16u) + QBoxLayout (0x0x7ff8623b2138) 0 + primary-for QVBoxLayout (0x0x7ff8623b20d0) + QLayout (0x0x7ff862374ee0) 0 + primary-for QBoxLayout (0x0x7ff8623b2138) + QObject (0x0x7ff862399180) 0 + primary-for QLayout (0x0x7ff862374ee0) + QLayoutItem (0x0x7ff8623991e0) 16 + vptr=((& QVBoxLayout::_ZTV11QVBoxLayout) + 272u) + +Class QButtonGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QButtonGroup::QPrivateSignal (0x0x7ff862399300) 0 empty + +Vtable for QButtonGroup +QButtonGroup::_ZTV12QButtonGroup: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QButtonGroup) +16 (int (*)(...))QButtonGroup::metaObject +24 (int (*)(...))QButtonGroup::qt_metacast +32 (int (*)(...))QButtonGroup::qt_metacall +40 (int (*)(...))QButtonGroup::~QButtonGroup +48 (int (*)(...))QButtonGroup::~QButtonGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QButtonGroup + size=16 align=8 + base size=16 base align=8 +QButtonGroup (0x0x7ff8623b21a0) 0 + vptr=((& QButtonGroup::_ZTV12QButtonGroup) + 16u) + QObject (0x0x7ff8623992a0) 0 + primary-for QButtonGroup (0x0x7ff8623b21a0) + +Class QCalendarWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCalendarWidget::QPrivateSignal (0x0x7ff862399420) 0 empty + +Vtable for QCalendarWidget +QCalendarWidget::_ZTV15QCalendarWidget: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QCalendarWidget) +16 (int (*)(...))QCalendarWidget::metaObject +24 (int (*)(...))QCalendarWidget::qt_metacast +32 (int (*)(...))QCalendarWidget::qt_metacall +40 (int (*)(...))QCalendarWidget::~QCalendarWidget +48 (int (*)(...))QCalendarWidget::~QCalendarWidget +56 (int (*)(...))QCalendarWidget::event +64 (int (*)(...))QCalendarWidget::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QCalendarWidget::sizeHint +136 (int (*)(...))QCalendarWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QCalendarWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QCalendarWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QCalendarWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QCalendarWidget::paintCell +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI15QCalendarWidget) +456 (int (*)(...))QCalendarWidget::_ZThn16_N15QCalendarWidgetD1Ev +464 (int (*)(...))QCalendarWidget::_ZThn16_N15QCalendarWidgetD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QCalendarWidget + size=48 align=8 + base size=48 base align=8 +QCalendarWidget (0x0x7ff8623b2208) 0 + vptr=((& QCalendarWidget::_ZTV15QCalendarWidget) + 16u) + QWidget (0x0x7ff8623c23f0) 0 + primary-for QCalendarWidget (0x0x7ff8623b2208) + QObject (0x0x7ff862399360) 0 + primary-for QWidget (0x0x7ff8623c23f0) + QPaintDevice (0x0x7ff8623993c0) 16 + vptr=((& QCalendarWidget::_ZTV15QCalendarWidget) + 456u) + +Class QCheckBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCheckBox::QPrivateSignal (0x0x7ff862399540) 0 empty + +Vtable for QCheckBox +QCheckBox::_ZTV9QCheckBox: 67u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QCheckBox) +16 (int (*)(...))QCheckBox::metaObject +24 (int (*)(...))QCheckBox::qt_metacast +32 (int (*)(...))QCheckBox::qt_metacall +40 (int (*)(...))QCheckBox::~QCheckBox +48 (int (*)(...))QCheckBox::~QCheckBox +56 (int (*)(...))QCheckBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractButton::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QCheckBox::sizeHint +136 (int (*)(...))QCheckBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractButton::mousePressEvent +176 (int (*)(...))QAbstractButton::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QCheckBox::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QAbstractButton::keyPressEvent +216 (int (*)(...))QAbstractButton::keyReleaseEvent +224 (int (*)(...))QAbstractButton::focusInEvent +232 (int (*)(...))QAbstractButton::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QCheckBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractButton::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QCheckBox::hitButton +440 (int (*)(...))QCheckBox::checkStateSet +448 (int (*)(...))QCheckBox::nextCheckState +456 (int (*)(...))-16 +464 (int (*)(...))(& _ZTI9QCheckBox) +472 (int (*)(...))QCheckBox::_ZThn16_N9QCheckBoxD1Ev +480 (int (*)(...))QCheckBox::_ZThn16_N9QCheckBoxD0Ev +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QCheckBox + size=48 align=8 + base size=48 base align=8 +QCheckBox (0x0x7ff8623b2270) 0 + vptr=((& QCheckBox::_ZTV9QCheckBox) + 16u) + QAbstractButton (0x0x7ff8623b22d8) 0 + primary-for QCheckBox (0x0x7ff8623b2270) + QWidget (0x0x7ff8623c2d20) 0 + primary-for QAbstractButton (0x0x7ff8623b22d8) + QObject (0x0x7ff862399480) 0 + primary-for QWidget (0x0x7ff8623c2d20) + QPaintDevice (0x0x7ff8623994e0) 16 + vptr=((& QCheckBox::_ZTV9QCheckBox) + 472u) + +Class QDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDialog::QPrivateSignal (0x0x7ff862399660) 0 empty + +Vtable for QDialog +QDialog::_ZTV7QDialog: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QDialog) +16 (int (*)(...))QDialog::metaObject +24 (int (*)(...))QDialog::qt_metacast +32 (int (*)(...))QDialog::qt_metacall +40 (int (*)(...))QDialog::~QDialog +48 (int (*)(...))QDialog::~QDialog +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QDialog::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI7QDialog) +488 (int (*)(...))QDialog::_ZThn16_N7QDialogD1Ev +496 (int (*)(...))QDialog::_ZThn16_N7QDialogD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDialog + size=48 align=8 + base size=48 base align=8 +QDialog (0x0x7ff8623b2340) 0 + vptr=((& QDialog::_ZTV7QDialog) + 16u) + QWidget (0x0x7ff862418070) 0 + primary-for QDialog (0x0x7ff8623b2340) + QObject (0x0x7ff8623995a0) 0 + primary-for QWidget (0x0x7ff862418070) + QPaintDevice (0x0x7ff862399600) 16 + vptr=((& QDialog::_ZTV7QDialog) + 488u) + +Class QColorDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QColorDialog::QPrivateSignal (0x0x7ff862399780) 0 empty + +Vtable for QColorDialog +QColorDialog::_ZTV12QColorDialog: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QColorDialog) +16 (int (*)(...))QColorDialog::metaObject +24 (int (*)(...))QColorDialog::qt_metacast +32 (int (*)(...))QColorDialog::qt_metacall +40 (int (*)(...))QColorDialog::~QColorDialog +48 (int (*)(...))QColorDialog::~QColorDialog +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QColorDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QColorDialog::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QColorDialog::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI12QColorDialog) +488 (int (*)(...))QColorDialog::_ZThn16_N12QColorDialogD1Ev +496 (int (*)(...))QColorDialog::_ZThn16_N12QColorDialogD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QColorDialog + size=48 align=8 + base size=48 base align=8 +QColorDialog (0x0x7ff8623b23a8) 0 + vptr=((& QColorDialog::_ZTV12QColorDialog) + 16u) + QDialog (0x0x7ff8623b2410) 0 + primary-for QColorDialog (0x0x7ff8623b23a8) + QWidget (0x0x7ff862418540) 0 + primary-for QDialog (0x0x7ff8623b2410) + QObject (0x0x7ff8623996c0) 0 + primary-for QWidget (0x0x7ff862418540) + QPaintDevice (0x0x7ff862399720) 16 + vptr=((& QColorDialog::_ZTV12QColorDialog) + 488u) + +Class QColormap + size=8 align=8 + base size=8 base align=8 +QColormap (0x0x7ff8623999c0) 0 + +Class QColumnView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QColumnView::QPrivateSignal (0x0x7ff862399ae0) 0 empty + +Vtable for QColumnView +QColumnView::_ZTV11QColumnView: 107u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QColumnView) +16 (int (*)(...))QColumnView::metaObject +24 (int (*)(...))QColumnView::qt_metacast +32 (int (*)(...))QColumnView::qt_metacall +40 (int (*)(...))QColumnView::~QColumnView +48 (int (*)(...))QColumnView::~QColumnView +56 (int (*)(...))QAbstractItemView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QAbstractItemView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QColumnView::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QAbstractItemView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QAbstractItemView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractScrollArea::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QColumnView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QAbstractItemView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QAbstractItemView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractItemView::viewportEvent +448 (int (*)(...))QColumnView::scrollContentsBy +456 (int (*)(...))QAbstractItemView::viewportSizeHint +464 (int (*)(...))QColumnView::setModel +472 (int (*)(...))QColumnView::setSelectionModel +480 (int (*)(...))QAbstractItemView::keyboardSearch +488 (int (*)(...))QColumnView::visualRect +496 (int (*)(...))QColumnView::scrollTo +504 (int (*)(...))QColumnView::indexAt +512 (int (*)(...))QAbstractItemView::sizeHintForRow +520 (int (*)(...))QAbstractItemView::sizeHintForColumn +528 (int (*)(...))QAbstractItemView::reset +536 (int (*)(...))QColumnView::setRootIndex +544 (int (*)(...))QAbstractItemView::doItemsLayout +552 (int (*)(...))QColumnView::selectAll +560 (int (*)(...))QAbstractItemView::dataChanged +568 (int (*)(...))QColumnView::rowsInserted +576 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved +584 (int (*)(...))QAbstractItemView::selectionChanged +592 (int (*)(...))QColumnView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QAbstractItemView::updateGeometries +624 (int (*)(...))QAbstractItemView::verticalScrollbarAction +632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction +640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))QColumnView::moveCursor +688 (int (*)(...))QColumnView::horizontalOffset +696 (int (*)(...))QColumnView::verticalOffset +704 (int (*)(...))QColumnView::isIndexHidden +712 (int (*)(...))QColumnView::setSelection +720 (int (*)(...))QColumnView::visualRegionForSelection +728 (int (*)(...))QAbstractItemView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QAbstractItemView::startDrag +760 (int (*)(...))QAbstractItemView::viewOptions +768 (int (*)(...))QColumnView::createColumn +776 (int (*)(...))-16 +784 (int (*)(...))(& _ZTI11QColumnView) +792 (int (*)(...))QColumnView::_ZThn16_N11QColumnViewD1Ev +800 (int (*)(...))QColumnView::_ZThn16_N11QColumnViewD0Ev +808 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +816 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +824 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +848 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QColumnView + size=48 align=8 + base size=48 base align=8 +QColumnView (0x0x7ff8623b2548) 0 + vptr=((& QColumnView::_ZTV11QColumnView) + 16u) + QAbstractItemView (0x0x7ff8623b25b0) 0 + primary-for QColumnView (0x0x7ff8623b2548) + QAbstractScrollArea (0x0x7ff8623b2618) 0 + primary-for QAbstractItemView (0x0x7ff8623b25b0) + QFrame (0x0x7ff8623b2680) 0 + primary-for QAbstractScrollArea (0x0x7ff8623b2618) + QWidget (0x0x7ff8624669a0) 0 + primary-for QFrame (0x0x7ff8623b2680) + QObject (0x0x7ff862399a20) 0 + primary-for QWidget (0x0x7ff8624669a0) + QPaintDevice (0x0x7ff862399a80) 16 + vptr=((& QColumnView::_ZTV11QColumnView) + 792u) + +Class QComboBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QComboBox::QPrivateSignal (0x0x7ff862399c00) 0 empty + +Vtable for QComboBox +QComboBox::_ZTV9QComboBox: 66u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QComboBox) +16 (int (*)(...))QComboBox::metaObject +24 (int (*)(...))QComboBox::qt_metacast +32 (int (*)(...))QComboBox::qt_metacall +40 (int (*)(...))QComboBox::~QComboBox +48 (int (*)(...))QComboBox::~QComboBox +56 (int (*)(...))QComboBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QComboBox::sizeHint +136 (int (*)(...))QComboBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QComboBox::mousePressEvent +176 (int (*)(...))QComboBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QComboBox::wheelEvent +208 (int (*)(...))QComboBox::keyPressEvent +216 (int (*)(...))QComboBox::keyReleaseEvent +224 (int (*)(...))QComboBox::focusInEvent +232 (int (*)(...))QComboBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QComboBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QComboBox::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QComboBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QComboBox::showEvent +352 (int (*)(...))QComboBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QComboBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QComboBox::inputMethodEvent +416 (int (*)(...))QComboBox::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QComboBox::showPopup +440 (int (*)(...))QComboBox::hidePopup +448 (int (*)(...))-16 +456 (int (*)(...))(& _ZTI9QComboBox) +464 (int (*)(...))QComboBox::_ZThn16_N9QComboBoxD1Ev +472 (int (*)(...))QComboBox::_ZThn16_N9QComboBoxD0Ev +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QComboBox + size=48 align=8 + base size=48 base align=8 +QComboBox (0x0x7ff8623b26e8) 0 + vptr=((& QComboBox::_ZTV9QComboBox) + 16u) + QWidget (0x0x7ff862466cb0) 0 + primary-for QComboBox (0x0x7ff8623b26e8) + QObject (0x0x7ff862399b40) 0 + primary-for QWidget (0x0x7ff862466cb0) + QPaintDevice (0x0x7ff862399ba0) 16 + vptr=((& QComboBox::_ZTV9QComboBox) + 464u) + +Class QPushButton::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPushButton::QPrivateSignal (0x0x7ff862399d20) 0 empty + +Vtable for QPushButton +QPushButton::_ZTV11QPushButton: 67u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QPushButton) +16 (int (*)(...))QPushButton::metaObject +24 (int (*)(...))QPushButton::qt_metacast +32 (int (*)(...))QPushButton::qt_metacall +40 (int (*)(...))QPushButton::~QPushButton +48 (int (*)(...))QPushButton::~QPushButton +56 (int (*)(...))QPushButton::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractButton::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QPushButton::sizeHint +136 (int (*)(...))QPushButton::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractButton::mousePressEvent +176 (int (*)(...))QAbstractButton::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractButton::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QPushButton::keyPressEvent +216 (int (*)(...))QAbstractButton::keyReleaseEvent +224 (int (*)(...))QPushButton::focusInEvent +232 (int (*)(...))QPushButton::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QPushButton::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractButton::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QAbstractButton::hitButton +440 (int (*)(...))QAbstractButton::checkStateSet +448 (int (*)(...))QAbstractButton::nextCheckState +456 (int (*)(...))-16 +464 (int (*)(...))(& _ZTI11QPushButton) +472 (int (*)(...))QPushButton::_ZThn16_N11QPushButtonD1Ev +480 (int (*)(...))QPushButton::_ZThn16_N11QPushButtonD0Ev +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QPushButton + size=48 align=8 + base size=48 base align=8 +QPushButton (0x0x7ff8623b2750) 0 + vptr=((& QPushButton::_ZTV11QPushButton) + 16u) + QAbstractButton (0x0x7ff8623b27b8) 0 + primary-for QPushButton (0x0x7ff8623b2750) + QWidget (0x0x7ff8624ad8c0) 0 + primary-for QAbstractButton (0x0x7ff8623b27b8) + QObject (0x0x7ff862399c60) 0 + primary-for QWidget (0x0x7ff8624ad8c0) + QPaintDevice (0x0x7ff862399cc0) 16 + vptr=((& QPushButton::_ZTV11QPushButton) + 472u) + +Class QCommandLinkButton::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCommandLinkButton::QPrivateSignal (0x0x7ff862399e40) 0 empty + +Vtable for QCommandLinkButton +QCommandLinkButton::_ZTV18QCommandLinkButton: 67u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QCommandLinkButton) +16 (int (*)(...))QCommandLinkButton::metaObject +24 (int (*)(...))QCommandLinkButton::qt_metacast +32 (int (*)(...))QCommandLinkButton::qt_metacall +40 (int (*)(...))QCommandLinkButton::~QCommandLinkButton +48 (int (*)(...))QCommandLinkButton::~QCommandLinkButton +56 (int (*)(...))QCommandLinkButton::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractButton::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QCommandLinkButton::sizeHint +136 (int (*)(...))QCommandLinkButton::minimumSizeHint +144 (int (*)(...))QCommandLinkButton::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractButton::mousePressEvent +176 (int (*)(...))QAbstractButton::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractButton::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QPushButton::keyPressEvent +216 (int (*)(...))QAbstractButton::keyReleaseEvent +224 (int (*)(...))QPushButton::focusInEvent +232 (int (*)(...))QPushButton::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QCommandLinkButton::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractButton::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QAbstractButton::hitButton +440 (int (*)(...))QAbstractButton::checkStateSet +448 (int (*)(...))QAbstractButton::nextCheckState +456 (int (*)(...))-16 +464 (int (*)(...))(& _ZTI18QCommandLinkButton) +472 (int (*)(...))QCommandLinkButton::_ZThn16_N18QCommandLinkButtonD1Ev +480 (int (*)(...))QCommandLinkButton::_ZThn16_N18QCommandLinkButtonD0Ev +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QCommandLinkButton + size=48 align=8 + base size=48 base align=8 +QCommandLinkButton (0x0x7ff8623b2820) 0 + vptr=((& QCommandLinkButton::_ZTV18QCommandLinkButton) + 16u) + QPushButton (0x0x7ff8623b2888) 0 + primary-for QCommandLinkButton (0x0x7ff8623b2820) + QAbstractButton (0x0x7ff8623b28f0) 0 + primary-for QPushButton (0x0x7ff8623b2888) + QWidget (0x0x7ff8624adbd0) 0 + primary-for QAbstractButton (0x0x7ff8623b28f0) + QObject (0x0x7ff862399d80) 0 + primary-for QWidget (0x0x7ff8624adbd0) + QPaintDevice (0x0x7ff862399de0) 16 + vptr=((& QCommandLinkButton::_ZTV18QCommandLinkButton) + 472u) + +Class QCommonStyle::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCommonStyle::QPrivateSignal (0x0x7ff862399f00) 0 empty + +Vtable for QCommonStyle +QCommonStyle::_ZTV12QCommonStyle: 37u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QCommonStyle) +16 (int (*)(...))QCommonStyle::metaObject +24 (int (*)(...))QCommonStyle::qt_metacast +32 (int (*)(...))QCommonStyle::qt_metacall +40 (int (*)(...))QCommonStyle::~QCommonStyle +48 (int (*)(...))QCommonStyle::~QCommonStyle +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCommonStyle::polish +120 (int (*)(...))QCommonStyle::unpolish +128 (int (*)(...))QCommonStyle::polish +136 (int (*)(...))QCommonStyle::unpolish +144 (int (*)(...))QCommonStyle::polish +152 (int (*)(...))QStyle::itemTextRect +160 (int (*)(...))QStyle::itemPixmapRect +168 (int (*)(...))QStyle::drawItemText +176 (int (*)(...))QStyle::drawItemPixmap +184 (int (*)(...))QStyle::standardPalette +192 (int (*)(...))QCommonStyle::drawPrimitive +200 (int (*)(...))QCommonStyle::drawControl +208 (int (*)(...))QCommonStyle::subElementRect +216 (int (*)(...))QCommonStyle::drawComplexControl +224 (int (*)(...))QCommonStyle::hitTestComplexControl +232 (int (*)(...))QCommonStyle::subControlRect +240 (int (*)(...))QCommonStyle::pixelMetric +248 (int (*)(...))QCommonStyle::sizeFromContents +256 (int (*)(...))QCommonStyle::styleHint +264 (int (*)(...))QCommonStyle::standardPixmap +272 (int (*)(...))QCommonStyle::standardIcon +280 (int (*)(...))QCommonStyle::generatedIconPixmap +288 (int (*)(...))QCommonStyle::layoutSpacing + +Class QCommonStyle + size=16 align=8 + base size=16 base align=8 +QCommonStyle (0x0x7ff8623b2958) 0 + vptr=((& QCommonStyle::_ZTV12QCommonStyle) + 16u) + QStyle (0x0x7ff8623b29c0) 0 + primary-for QCommonStyle (0x0x7ff8623b2958) + QObject (0x0x7ff862399ea0) 0 + primary-for QStyle (0x0x7ff8623b29c0) + +Class QCompleter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCompleter::QPrivateSignal (0x0x7ff862528000) 0 empty + +Vtable for QCompleter +QCompleter::_ZTV10QCompleter: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QCompleter) +16 (int (*)(...))QCompleter::metaObject +24 (int (*)(...))QCompleter::qt_metacast +32 (int (*)(...))QCompleter::qt_metacall +40 (int (*)(...))QCompleter::~QCompleter +48 (int (*)(...))QCompleter::~QCompleter +56 (int (*)(...))QCompleter::event +64 (int (*)(...))QCompleter::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCompleter::pathFromIndex +120 (int (*)(...))QCompleter::splitPath + +Class QCompleter + size=16 align=8 + base size=16 base align=8 +QCompleter (0x0x7ff8623b2a28) 0 + vptr=((& QCompleter::_ZTV10QCompleter) + 16u) + QObject (0x0x7ff862399f60) 0 + primary-for QCompleter (0x0x7ff8623b2a28) + +Class QDataWidgetMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDataWidgetMapper::QPrivateSignal (0x0x7ff8625280c0) 0 empty + +Vtable for QDataWidgetMapper +QDataWidgetMapper::_ZTV17QDataWidgetMapper: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QDataWidgetMapper) +16 (int (*)(...))QDataWidgetMapper::metaObject +24 (int (*)(...))QDataWidgetMapper::qt_metacast +32 (int (*)(...))QDataWidgetMapper::qt_metacall +40 (int (*)(...))QDataWidgetMapper::~QDataWidgetMapper +48 (int (*)(...))QDataWidgetMapper::~QDataWidgetMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QDataWidgetMapper::setCurrentIndex + +Class QDataWidgetMapper + size=16 align=8 + base size=16 base align=8 +QDataWidgetMapper (0x0x7ff8623b2a90) 0 + vptr=((& QDataWidgetMapper::_ZTV17QDataWidgetMapper) + 16u) + QObject (0x0x7ff862528060) 0 + primary-for QDataWidgetMapper (0x0x7ff8623b2a90) + +Class QDateTimeEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDateTimeEdit::QPrivateSignal (0x0x7ff8625281e0) 0 empty + +Vtable for QDateTimeEdit +QDateTimeEdit::_ZTV13QDateTimeEdit: 71u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QDateTimeEdit) +16 (int (*)(...))QDateTimeEdit::metaObject +24 (int (*)(...))QDateTimeEdit::qt_metacast +32 (int (*)(...))QDateTimeEdit::qt_metacall +40 (int (*)(...))QDateTimeEdit::~QDateTimeEdit +48 (int (*)(...))QDateTimeEdit::~QDateTimeEdit +56 (int (*)(...))QDateTimeEdit::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSpinBox::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QDateTimeEdit::sizeHint +136 (int (*)(...))QAbstractSpinBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QDateTimeEdit::mousePressEvent +176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent +200 (int (*)(...))QDateTimeEdit::wheelEvent +208 (int (*)(...))QDateTimeEdit::keyPressEvent +216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent +224 (int (*)(...))QDateTimeEdit::focusInEvent +232 (int (*)(...))QAbstractSpinBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QDateTimeEdit::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractSpinBox::resizeEvent +280 (int (*)(...))QAbstractSpinBox::closeEvent +288 (int (*)(...))QAbstractSpinBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QAbstractSpinBox::showEvent +352 (int (*)(...))QAbstractSpinBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSpinBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QAbstractSpinBox::inputMethodQuery +424 (int (*)(...))QDateTimeEdit::focusNextPrevChild +432 (int (*)(...))QDateTimeEdit::validate +440 (int (*)(...))QDateTimeEdit::fixup +448 (int (*)(...))QDateTimeEdit::stepBy +456 (int (*)(...))QDateTimeEdit::clear +464 (int (*)(...))QDateTimeEdit::stepEnabled +472 (int (*)(...))QDateTimeEdit::dateTimeFromText +480 (int (*)(...))QDateTimeEdit::textFromDateTime +488 (int (*)(...))-16 +496 (int (*)(...))(& _ZTI13QDateTimeEdit) +504 (int (*)(...))QDateTimeEdit::_ZThn16_N13QDateTimeEditD1Ev +512 (int (*)(...))QDateTimeEdit::_ZThn16_N13QDateTimeEditD0Ev +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDateTimeEdit + size=48 align=8 + base size=48 base align=8 +QDateTimeEdit (0x0x7ff8623b2af8) 0 + vptr=((& QDateTimeEdit::_ZTV13QDateTimeEdit) + 16u) + QAbstractSpinBox (0x0x7ff8623b2b60) 0 + primary-for QDateTimeEdit (0x0x7ff8623b2af8) + QWidget (0x0x7ff862520bd0) 0 + primary-for QAbstractSpinBox (0x0x7ff8623b2b60) + QObject (0x0x7ff862528120) 0 + primary-for QWidget (0x0x7ff862520bd0) + QPaintDevice (0x0x7ff862528180) 16 + vptr=((& QDateTimeEdit::_ZTV13QDateTimeEdit) + 504u) + +Class QTimeEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeEdit::QPrivateSignal (0x0x7ff862528480) 0 empty + +Vtable for QTimeEdit +QTimeEdit::_ZTV9QTimeEdit: 71u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeEdit) +16 (int (*)(...))QTimeEdit::metaObject +24 (int (*)(...))QTimeEdit::qt_metacast +32 (int (*)(...))QTimeEdit::qt_metacall +40 (int (*)(...))QTimeEdit::~QTimeEdit +48 (int (*)(...))QTimeEdit::~QTimeEdit +56 (int (*)(...))QDateTimeEdit::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSpinBox::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QDateTimeEdit::sizeHint +136 (int (*)(...))QAbstractSpinBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QDateTimeEdit::mousePressEvent +176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent +200 (int (*)(...))QDateTimeEdit::wheelEvent +208 (int (*)(...))QDateTimeEdit::keyPressEvent +216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent +224 (int (*)(...))QDateTimeEdit::focusInEvent +232 (int (*)(...))QAbstractSpinBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QDateTimeEdit::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractSpinBox::resizeEvent +280 (int (*)(...))QAbstractSpinBox::closeEvent +288 (int (*)(...))QAbstractSpinBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QAbstractSpinBox::showEvent +352 (int (*)(...))QAbstractSpinBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSpinBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QAbstractSpinBox::inputMethodQuery +424 (int (*)(...))QDateTimeEdit::focusNextPrevChild +432 (int (*)(...))QDateTimeEdit::validate +440 (int (*)(...))QDateTimeEdit::fixup +448 (int (*)(...))QDateTimeEdit::stepBy +456 (int (*)(...))QDateTimeEdit::clear +464 (int (*)(...))QDateTimeEdit::stepEnabled +472 (int (*)(...))QDateTimeEdit::dateTimeFromText +480 (int (*)(...))QDateTimeEdit::textFromDateTime +488 (int (*)(...))-16 +496 (int (*)(...))(& _ZTI9QTimeEdit) +504 (int (*)(...))QTimeEdit::_ZThn16_N9QTimeEditD1Ev +512 (int (*)(...))QTimeEdit::_ZThn16_N9QTimeEditD0Ev +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTimeEdit + size=48 align=8 + base size=48 base align=8 +QTimeEdit (0x0x7ff8623b2c98) 0 + vptr=((& QTimeEdit::_ZTV9QTimeEdit) + 16u) + QDateTimeEdit (0x0x7ff8623b2d00) 0 + primary-for QTimeEdit (0x0x7ff8623b2c98) + QAbstractSpinBox (0x0x7ff8623b2d68) 0 + primary-for QDateTimeEdit (0x0x7ff8623b2d00) + QWidget (0x0x7ff862159770) 0 + primary-for QAbstractSpinBox (0x0x7ff8623b2d68) + QObject (0x0x7ff8625283c0) 0 + primary-for QWidget (0x0x7ff862159770) + QPaintDevice (0x0x7ff862528420) 16 + vptr=((& QTimeEdit::_ZTV9QTimeEdit) + 504u) + +Class QDateEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDateEdit::QPrivateSignal (0x0x7ff8625285a0) 0 empty + +Vtable for QDateEdit +QDateEdit::_ZTV9QDateEdit: 71u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QDateEdit) +16 (int (*)(...))QDateEdit::metaObject +24 (int (*)(...))QDateEdit::qt_metacast +32 (int (*)(...))QDateEdit::qt_metacall +40 (int (*)(...))QDateEdit::~QDateEdit +48 (int (*)(...))QDateEdit::~QDateEdit +56 (int (*)(...))QDateTimeEdit::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSpinBox::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QDateTimeEdit::sizeHint +136 (int (*)(...))QAbstractSpinBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QDateTimeEdit::mousePressEvent +176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent +200 (int (*)(...))QDateTimeEdit::wheelEvent +208 (int (*)(...))QDateTimeEdit::keyPressEvent +216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent +224 (int (*)(...))QDateTimeEdit::focusInEvent +232 (int (*)(...))QAbstractSpinBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QDateTimeEdit::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractSpinBox::resizeEvent +280 (int (*)(...))QAbstractSpinBox::closeEvent +288 (int (*)(...))QAbstractSpinBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QAbstractSpinBox::showEvent +352 (int (*)(...))QAbstractSpinBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSpinBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QAbstractSpinBox::inputMethodQuery +424 (int (*)(...))QDateTimeEdit::focusNextPrevChild +432 (int (*)(...))QDateTimeEdit::validate +440 (int (*)(...))QDateTimeEdit::fixup +448 (int (*)(...))QDateTimeEdit::stepBy +456 (int (*)(...))QDateTimeEdit::clear +464 (int (*)(...))QDateTimeEdit::stepEnabled +472 (int (*)(...))QDateTimeEdit::dateTimeFromText +480 (int (*)(...))QDateTimeEdit::textFromDateTime +488 (int (*)(...))-16 +496 (int (*)(...))(& _ZTI9QDateEdit) +504 (int (*)(...))QDateEdit::_ZThn16_N9QDateEditD1Ev +512 (int (*)(...))QDateEdit::_ZThn16_N9QDateEditD0Ev +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDateEdit + size=48 align=8 + base size=48 base align=8 +QDateEdit (0x0x7ff8623b2dd0) 0 + vptr=((& QDateEdit::_ZTV9QDateEdit) + 16u) + QDateTimeEdit (0x0x7ff8623b2e38) 0 + primary-for QDateEdit (0x0x7ff8623b2dd0) + QAbstractSpinBox (0x0x7ff8623b2ea0) 0 + primary-for QDateTimeEdit (0x0x7ff8623b2e38) + QWidget (0x0x7ff8621599a0) 0 + primary-for QAbstractSpinBox (0x0x7ff8623b2ea0) + QObject (0x0x7ff8625284e0) 0 + primary-for QWidget (0x0x7ff8621599a0) + QPaintDevice (0x0x7ff862528540) 16 + vptr=((& QDateEdit::_ZTV9QDateEdit) + 504u) + +Class QDesktopWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDesktopWidget::QPrivateSignal (0x0x7ff8625286c0) 0 empty + +Vtable for QDesktopWidget +QDesktopWidget::_ZTV14QDesktopWidget: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QDesktopWidget) +16 (int (*)(...))QDesktopWidget::metaObject +24 (int (*)(...))QDesktopWidget::qt_metacast +32 (int (*)(...))QDesktopWidget::qt_metacall +40 (int (*)(...))QDesktopWidget::~QDesktopWidget +48 (int (*)(...))QDesktopWidget::~QDesktopWidget +56 (int (*)(...))QWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDesktopWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI14QDesktopWidget) +448 (int (*)(...))QDesktopWidget::_ZThn16_N14QDesktopWidgetD1Ev +456 (int (*)(...))QDesktopWidget::_ZThn16_N14QDesktopWidgetD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDesktopWidget + size=48 align=8 + base size=48 base align=8 +QDesktopWidget (0x0x7ff8623b2f08) 0 + vptr=((& QDesktopWidget::_ZTV14QDesktopWidget) + 16u) + QWidget (0x0x7ff8621bc3f0) 0 + primary-for QDesktopWidget (0x0x7ff8623b2f08) + QObject (0x0x7ff862528600) 0 + primary-for QWidget (0x0x7ff8621bc3f0) + QPaintDevice (0x0x7ff862528660) 16 + vptr=((& QDesktopWidget::_ZTV14QDesktopWidget) + 448u) + +Class QDial::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDial::QPrivateSignal (0x0x7ff8625287e0) 0 empty + +Vtable for QDial +QDial::_ZTV5QDial: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QDial) +16 (int (*)(...))QDial::metaObject +24 (int (*)(...))QDial::qt_metacast +32 (int (*)(...))QDial::qt_metacall +40 (int (*)(...))QDial::~QDial +48 (int (*)(...))QDial::~QDial +56 (int (*)(...))QDial::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSlider::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QDial::sizeHint +136 (int (*)(...))QDial::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QDial::mousePressEvent +176 (int (*)(...))QDial::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QDial::mouseMoveEvent +200 (int (*)(...))QAbstractSlider::wheelEvent +208 (int (*)(...))QAbstractSlider::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QDial::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDial::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSlider::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDial::sliderChange +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI5QDial) +456 (int (*)(...))QDial::_ZThn16_N5QDialD1Ev +464 (int (*)(...))QDial::_ZThn16_N5QDialD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDial + size=48 align=8 + base size=48 base align=8 +QDial (0x0x7ff8623b2f70) 0 + vptr=((& QDial::_ZTV5QDial) + 16u) + QAbstractSlider (0x0x7ff8621e4000) 0 + primary-for QDial (0x0x7ff8623b2f70) + QWidget (0x0x7ff8621bc850) 0 + primary-for QAbstractSlider (0x0x7ff8621e4000) + QObject (0x0x7ff862528720) 0 + primary-for QWidget (0x0x7ff8621bc850) + QPaintDevice (0x0x7ff862528780) 16 + vptr=((& QDial::_ZTV5QDial) + 456u) + +Class QDialogButtonBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDialogButtonBox::QPrivateSignal (0x0x7ff862528900) 0 empty + +Vtable for QDialogButtonBox +QDialogButtonBox::_ZTV16QDialogButtonBox: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QDialogButtonBox) +16 (int (*)(...))QDialogButtonBox::metaObject +24 (int (*)(...))QDialogButtonBox::qt_metacast +32 (int (*)(...))QDialogButtonBox::qt_metacall +40 (int (*)(...))QDialogButtonBox::~QDialogButtonBox +48 (int (*)(...))QDialogButtonBox::~QDialogButtonBox +56 (int (*)(...))QDialogButtonBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QDialogButtonBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI16QDialogButtonBox) +448 (int (*)(...))QDialogButtonBox::_ZThn16_N16QDialogButtonBoxD1Ev +456 (int (*)(...))QDialogButtonBox::_ZThn16_N16QDialogButtonBoxD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDialogButtonBox + size=48 align=8 + base size=48 base align=8 +QDialogButtonBox (0x0x7ff8621e4068) 0 + vptr=((& QDialogButtonBox::_ZTV16QDialogButtonBox) + 16u) + QWidget (0x0x7ff8621bcb60) 0 + primary-for QDialogButtonBox (0x0x7ff8621e4068) + QObject (0x0x7ff862528840) 0 + primary-for QWidget (0x0x7ff8621bcb60) + QPaintDevice (0x0x7ff8625288a0) 16 + vptr=((& QDialogButtonBox::_ZTV16QDialogButtonBox) + 448u) + +Vtable for QFileIconProvider +QFileIconProvider::_ZTV17QFileIconProvider: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFileIconProvider) +16 (int (*)(...))QFileIconProvider::~QFileIconProvider +24 (int (*)(...))QFileIconProvider::~QFileIconProvider +32 (int (*)(...))QFileIconProvider::icon +40 (int (*)(...))QFileIconProvider::icon +48 (int (*)(...))QFileIconProvider::type + +Class QFileIconProvider + size=16 align=8 + base size=16 base align=8 +QFileIconProvider (0x0x7ff862528ae0) 0 + vptr=((& QFileIconProvider::_ZTV17QFileIconProvider) + 16u) + +Class QDirModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDirModel::QPrivateSignal (0x0x7ff862528de0) 0 empty + +Vtable for QDirModel +QDirModel::_ZTV9QDirModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QDirModel) +16 (int (*)(...))QDirModel::metaObject +24 (int (*)(...))QDirModel::qt_metacast +32 (int (*)(...))QDirModel::qt_metacall +40 (int (*)(...))QDirModel::~QDirModel +48 (int (*)(...))QDirModel::~QDirModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QDirModel::index +120 (int (*)(...))QDirModel::parent +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))QDirModel::rowCount +144 (int (*)(...))QDirModel::columnCount +152 (int (*)(...))QDirModel::hasChildren +160 (int (*)(...))QDirModel::data +168 (int (*)(...))QDirModel::setData +176 (int (*)(...))QDirModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QDirModel::mimeTypes +216 (int (*)(...))QDirModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QDirModel::dropMimeData +240 (int (*)(...))QDirModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QDirModel::flags +328 (int (*)(...))QDirModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QDirModel + size=16 align=8 + base size=16 base align=8 +QDirModel (0x0x7ff8621e4270) 0 + vptr=((& QDirModel::_ZTV9QDirModel) + 16u) + QAbstractItemModel (0x0x7ff8621e42d8) 0 + primary-for QDirModel (0x0x7ff8621e4270) + QObject (0x0x7ff862528d80) 0 + primary-for QAbstractItemModel (0x0x7ff8621e42d8) + +Class QDockWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDockWidget::QPrivateSignal (0x0x7ff862528f00) 0 empty + +Vtable for QDockWidget +QDockWidget::_ZTV11QDockWidget: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QDockWidget) +16 (int (*)(...))QDockWidget::metaObject +24 (int (*)(...))QDockWidget::qt_metacast +32 (int (*)(...))QDockWidget::qt_metacall +40 (int (*)(...))QDockWidget::~QDockWidget +48 (int (*)(...))QDockWidget::~QDockWidget +56 (int (*)(...))QDockWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QDockWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QDockWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QDockWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI11QDockWidget) +448 (int (*)(...))QDockWidget::_ZThn16_N11QDockWidgetD1Ev +456 (int (*)(...))QDockWidget::_ZThn16_N11QDockWidgetD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDockWidget + size=48 align=8 + base size=48 base align=8 +QDockWidget (0x0x7ff8621e4340) 0 + vptr=((& QDockWidget::_ZTV11QDockWidget) + 16u) + QWidget (0x0x7ff862260d20) 0 + primary-for QDockWidget (0x0x7ff8621e4340) + QObject (0x0x7ff862528e40) 0 + primary-for QWidget (0x0x7ff862260d20) + QPaintDevice (0x0x7ff862528ea0) 16 + vptr=((& QDockWidget::_ZTV11QDockWidget) + 448u) + +Class QTileRules + size=8 align=4 + base size=8 base align=4 +QTileRules (0x0x7ff8622c95a0) 0 + +Class QErrorMessage::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QErrorMessage::QPrivateSignal (0x0x7ff8622c9840) 0 empty + +Vtable for QErrorMessage +QErrorMessage::_ZTV13QErrorMessage: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QErrorMessage) +16 (int (*)(...))QErrorMessage::metaObject +24 (int (*)(...))QErrorMessage::qt_metacast +32 (int (*)(...))QErrorMessage::qt_metacall +40 (int (*)(...))QErrorMessage::~QErrorMessage +48 (int (*)(...))QErrorMessage::~QErrorMessage +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QErrorMessage::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QErrorMessage::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI13QErrorMessage) +488 (int (*)(...))QErrorMessage::_ZThn16_N13QErrorMessageD1Ev +496 (int (*)(...))QErrorMessage::_ZThn16_N13QErrorMessageD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QErrorMessage + size=48 align=8 + base size=48 base align=8 +QErrorMessage (0x0x7ff8621e4a28) 0 + vptr=((& QErrorMessage::_ZTV13QErrorMessage) + 16u) + QDialog (0x0x7ff8621e4a90) 0 + primary-for QErrorMessage (0x0x7ff8621e4a28) + QWidget (0x0x7ff86231b770) 0 + primary-for QDialog (0x0x7ff8621e4a90) + QObject (0x0x7ff8622c9780) 0 + primary-for QWidget (0x0x7ff86231b770) + QPaintDevice (0x0x7ff8622c97e0) 16 + vptr=((& QErrorMessage::_ZTV13QErrorMessage) + 488u) + +Class QFileDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDialog::QPrivateSignal (0x0x7ff8622c9960) 0 empty + +Vtable for QFileDialog +QFileDialog::_ZTV11QFileDialog: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDialog) +16 (int (*)(...))QFileDialog::metaObject +24 (int (*)(...))QFileDialog::qt_metacast +32 (int (*)(...))QFileDialog::qt_metacall +40 (int (*)(...))QFileDialog::~QFileDialog +48 (int (*)(...))QFileDialog::~QFileDialog +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QFileDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFileDialog::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QFileDialog::done +456 (int (*)(...))QFileDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI11QFileDialog) +488 (int (*)(...))QFileDialog::_ZThn16_N11QFileDialogD1Ev +496 (int (*)(...))QFileDialog::_ZThn16_N11QFileDialogD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QFileDialog + size=48 align=8 + base size=48 base align=8 +QFileDialog (0x0x7ff8621e4af8) 0 + vptr=((& QFileDialog::_ZTV11QFileDialog) + 16u) + QDialog (0x0x7ff8621e4b60) 0 + primary-for QFileDialog (0x0x7ff8621e4af8) + QWidget (0x0x7ff86231ba80) 0 + primary-for QDialog (0x0x7ff8621e4b60) + QObject (0x0x7ff8622c98a0) 0 + primary-for QWidget (0x0x7ff86231ba80) + QPaintDevice (0x0x7ff8622c9900) 16 + vptr=((& QFileDialog::_ZTV11QFileDialog) + 488u) + +Class QFileSystemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemModel::QPrivateSignal (0x0x7ff8622c9ba0) 0 empty + +Vtable for QFileSystemModel +QFileSystemModel::_ZTV16QFileSystemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QFileSystemModel) +16 (int (*)(...))QFileSystemModel::metaObject +24 (int (*)(...))QFileSystemModel::qt_metacast +32 (int (*)(...))QFileSystemModel::qt_metacall +40 (int (*)(...))QFileSystemModel::~QFileSystemModel +48 (int (*)(...))QFileSystemModel::~QFileSystemModel +56 (int (*)(...))QFileSystemModel::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QFileSystemModel::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileSystemModel::index +120 (int (*)(...))QFileSystemModel::parent +128 (int (*)(...))QFileSystemModel::sibling +136 (int (*)(...))QFileSystemModel::rowCount +144 (int (*)(...))QFileSystemModel::columnCount +152 (int (*)(...))QFileSystemModel::hasChildren +160 (int (*)(...))QFileSystemModel::data +168 (int (*)(...))QFileSystemModel::setData +176 (int (*)(...))QFileSystemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QFileSystemModel::mimeTypes +216 (int (*)(...))QFileSystemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QFileSystemModel::dropMimeData +240 (int (*)(...))QFileSystemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QFileSystemModel::fetchMore +312 (int (*)(...))QFileSystemModel::canFetchMore +320 (int (*)(...))QFileSystemModel::flags +328 (int (*)(...))QFileSystemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QFileSystemModel + size=16 align=8 + base size=16 base align=8 +QFileSystemModel (0x0x7ff8621e4c98) 0 + vptr=((& QFileSystemModel::_ZTV16QFileSystemModel) + 16u) + QAbstractItemModel (0x0x7ff8621e4d00) 0 + primary-for QFileSystemModel (0x0x7ff8621e4c98) + QObject (0x0x7ff8622c9b40) 0 + primary-for QAbstractItemModel (0x0x7ff8621e4d00) + +Class QFocusFrame::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFocusFrame::QPrivateSignal (0x0x7ff8622c9d20) 0 empty + +Vtable for QFocusFrame +QFocusFrame::_ZTV11QFocusFrame: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFocusFrame) +16 (int (*)(...))QFocusFrame::metaObject +24 (int (*)(...))QFocusFrame::qt_metacast +32 (int (*)(...))QFocusFrame::qt_metacall +40 (int (*)(...))QFocusFrame::~QFocusFrame +48 (int (*)(...))QFocusFrame::~QFocusFrame +56 (int (*)(...))QFocusFrame::event +64 (int (*)(...))QFocusFrame::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QFocusFrame::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI11QFocusFrame) +448 (int (*)(...))QFocusFrame::_ZThn16_N11QFocusFrameD1Ev +456 (int (*)(...))QFocusFrame::_ZThn16_N11QFocusFrameD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QFocusFrame + size=48 align=8 + base size=48 base align=8 +QFocusFrame (0x0x7ff8621e4d68) 0 + vptr=((& QFocusFrame::_ZTV11QFocusFrame) + 16u) + QWidget (0x0x7ff861fef150) 0 + primary-for QFocusFrame (0x0x7ff8621e4d68) + QObject (0x0x7ff8622c9c60) 0 + primary-for QWidget (0x0x7ff861fef150) + QPaintDevice (0x0x7ff8622c9cc0) 16 + vptr=((& QFocusFrame::_ZTV11QFocusFrame) + 448u) + +Class QFontComboBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFontComboBox::QPrivateSignal (0x0x7ff8622c9e40) 0 empty + +Vtable for QFontComboBox +QFontComboBox::_ZTV13QFontComboBox: 66u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFontComboBox) +16 (int (*)(...))QFontComboBox::metaObject +24 (int (*)(...))QFontComboBox::qt_metacast +32 (int (*)(...))QFontComboBox::qt_metacall +40 (int (*)(...))QFontComboBox::~QFontComboBox +48 (int (*)(...))QFontComboBox::~QFontComboBox +56 (int (*)(...))QFontComboBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QFontComboBox::sizeHint +136 (int (*)(...))QComboBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QComboBox::mousePressEvent +176 (int (*)(...))QComboBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QComboBox::wheelEvent +208 (int (*)(...))QComboBox::keyPressEvent +216 (int (*)(...))QComboBox::keyReleaseEvent +224 (int (*)(...))QComboBox::focusInEvent +232 (int (*)(...))QComboBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QComboBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QComboBox::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QComboBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QComboBox::showEvent +352 (int (*)(...))QComboBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QComboBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QComboBox::inputMethodEvent +416 (int (*)(...))QComboBox::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QComboBox::showPopup +440 (int (*)(...))QComboBox::hidePopup +448 (int (*)(...))-16 +456 (int (*)(...))(& _ZTI13QFontComboBox) +464 (int (*)(...))QFontComboBox::_ZThn16_N13QFontComboBoxD1Ev +472 (int (*)(...))QFontComboBox::_ZThn16_N13QFontComboBoxD0Ev +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QFontComboBox + size=48 align=8 + base size=48 base align=8 +QFontComboBox (0x0x7ff8621e4dd0) 0 + vptr=((& QFontComboBox::_ZTV13QFontComboBox) + 16u) + QComboBox (0x0x7ff8621e4e38) 0 + primary-for QFontComboBox (0x0x7ff8621e4dd0) + QWidget (0x0x7ff861fef460) 0 + primary-for QComboBox (0x0x7ff8621e4e38) + QObject (0x0x7ff8622c9d80) 0 + primary-for QWidget (0x0x7ff861fef460) + QPaintDevice (0x0x7ff8622c9de0) 16 + vptr=((& QFontComboBox::_ZTV13QFontComboBox) + 464u) + +Class QFontDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFontDialog::QPrivateSignal (0x0x7ff862026120) 0 empty + +Vtable for QFontDialog +QFontDialog::_ZTV11QFontDialog: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFontDialog) +16 (int (*)(...))QFontDialog::metaObject +24 (int (*)(...))QFontDialog::qt_metacast +32 (int (*)(...))QFontDialog::qt_metacall +40 (int (*)(...))QFontDialog::~QFontDialog +48 (int (*)(...))QFontDialog::~QFontDialog +56 (int (*)(...))QWidget::event +64 (int (*)(...))QFontDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QFontDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFontDialog::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QFontDialog::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI11QFontDialog) +488 (int (*)(...))QFontDialog::_ZThn16_N11QFontDialogD1Ev +496 (int (*)(...))QFontDialog::_ZThn16_N11QFontDialogD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QFontDialog + size=48 align=8 + base size=48 base align=8 +QFontDialog (0x0x7ff86204c000) 0 + vptr=((& QFontDialog::_ZTV11QFontDialog) + 16u) + QDialog (0x0x7ff86204c068) 0 + primary-for QFontDialog (0x0x7ff86204c000) + QWidget (0x0x7ff86203b460) 0 + primary-for QDialog (0x0x7ff86204c068) + QObject (0x0x7ff862026060) 0 + primary-for QWidget (0x0x7ff86203b460) + QPaintDevice (0x0x7ff8620260c0) 16 + vptr=((& QFontDialog::_ZTV11QFontDialog) + 488u) + +Class QFormLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFormLayout::QPrivateSignal (0x0x7ff8620263c0) 0 empty + +Class QFormLayout::TakeRowResult + size=16 align=8 + base size=16 base align=8 +QFormLayout::TakeRowResult (0x0x7ff862026420) 0 + +Vtable for QFormLayout +QFormLayout::_ZTV11QFormLayout: 50u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFormLayout) +16 (int (*)(...))QFormLayout::metaObject +24 (int (*)(...))QFormLayout::qt_metacast +32 (int (*)(...))QFormLayout::qt_metacall +40 (int (*)(...))QFormLayout::~QFormLayout +48 (int (*)(...))QFormLayout::~QFormLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFormLayout::invalidate +120 (int (*)(...))QLayout::geometry +128 (int (*)(...))QFormLayout::addItem +136 (int (*)(...))QFormLayout::expandingDirections +144 (int (*)(...))QFormLayout::minimumSize +152 (int (*)(...))QLayout::maximumSize +160 (int (*)(...))QFormLayout::setGeometry +168 (int (*)(...))QFormLayout::itemAt +176 (int (*)(...))QFormLayout::takeAt +184 (int (*)(...))QLayout::indexOf +192 (int (*)(...))QFormLayout::count +200 (int (*)(...))QLayout::isEmpty +208 (int (*)(...))QLayout::controlTypes +216 (int (*)(...))QLayout::layout +224 (int (*)(...))QFormLayout::sizeHint +232 (int (*)(...))QFormLayout::hasHeightForWidth +240 (int (*)(...))QFormLayout::heightForWidth +248 (int (*)(...))-16 +256 (int (*)(...))(& _ZTI11QFormLayout) +264 (int (*)(...))QFormLayout::_ZThn16_N11QFormLayoutD1Ev +272 (int (*)(...))QFormLayout::_ZThn16_N11QFormLayoutD0Ev +280 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout8sizeHintEv +288 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout11minimumSizeEv +296 (int (*)(...))QLayout::_ZThn16_NK7QLayout11maximumSizeEv +304 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout19expandingDirectionsEv +312 (int (*)(...))QFormLayout::_ZThn16_N11QFormLayout11setGeometryERK5QRect +320 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +328 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +336 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout17hasHeightForWidthEv +344 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout14heightForWidthEi +352 (int (*)(...))QLayoutItem::minimumHeightForWidth +360 (int (*)(...))QFormLayout::_ZThn16_N11QFormLayout10invalidateEv +368 (int (*)(...))QLayoutItem::widget +376 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +384 (int (*)(...))QLayoutItem::spacerItem +392 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QFormLayout + size=32 align=8 + base size=28 base align=8 +QFormLayout (0x0x7ff86204c1a0) 0 + vptr=((& QFormLayout::_ZTV11QFormLayout) + 16u) + QLayout (0x0x7ff86207b850) 0 + primary-for QFormLayout (0x0x7ff86204c1a0) + QObject (0x0x7ff862026300) 0 + primary-for QLayout (0x0x7ff86207b850) + QLayoutItem (0x0x7ff862026360) 16 + vptr=((& QFormLayout::_ZTV11QFormLayout) + 264u) + +Class QGesture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGesture::QPrivateSignal (0x0x7ff862026960) 0 empty + +Vtable for QGesture +QGesture::_ZTV8QGesture: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QGesture) +16 (int (*)(...))QGesture::metaObject +24 (int (*)(...))QGesture::qt_metacast +32 (int (*)(...))QGesture::qt_metacall +40 (int (*)(...))QGesture::~QGesture +48 (int (*)(...))QGesture::~QGesture +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QGesture + size=16 align=8 + base size=16 base align=8 +QGesture (0x0x7ff86204c3a8) 0 + vptr=((& QGesture::_ZTV8QGesture) + 16u) + QObject (0x0x7ff862026900) 0 + primary-for QGesture (0x0x7ff86204c3a8) + +Class QPanGesture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPanGesture::QPrivateSignal (0x0x7ff862026a20) 0 empty + +Vtable for QPanGesture +QPanGesture::_ZTV11QPanGesture: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QPanGesture) +16 (int (*)(...))QPanGesture::metaObject +24 (int (*)(...))QPanGesture::qt_metacast +32 (int (*)(...))QPanGesture::qt_metacall +40 (int (*)(...))QPanGesture::~QPanGesture +48 (int (*)(...))QPanGesture::~QPanGesture +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPanGesture + size=16 align=8 + base size=16 base align=8 +QPanGesture (0x0x7ff86204c410) 0 + vptr=((& QPanGesture::_ZTV11QPanGesture) + 16u) + QGesture (0x0x7ff86204c478) 0 + primary-for QPanGesture (0x0x7ff86204c410) + QObject (0x0x7ff8620269c0) 0 + primary-for QGesture (0x0x7ff86204c478) + +Class QPinchGesture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPinchGesture::QPrivateSignal (0x0x7ff862026ae0) 0 empty + +Vtable for QPinchGesture +QPinchGesture::_ZTV13QPinchGesture: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPinchGesture) +16 (int (*)(...))QPinchGesture::metaObject +24 (int (*)(...))QPinchGesture::qt_metacast +32 (int (*)(...))QPinchGesture::qt_metacall +40 (int (*)(...))QPinchGesture::~QPinchGesture +48 (int (*)(...))QPinchGesture::~QPinchGesture +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPinchGesture + size=16 align=8 + base size=16 base align=8 +QPinchGesture (0x0x7ff86204c4e0) 0 + vptr=((& QPinchGesture::_ZTV13QPinchGesture) + 16u) + QGesture (0x0x7ff86204c548) 0 + primary-for QPinchGesture (0x0x7ff86204c4e0) + QObject (0x0x7ff862026a80) 0 + primary-for QGesture (0x0x7ff86204c548) + +Class QSwipeGesture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSwipeGesture::QPrivateSignal (0x0x7ff862026e40) 0 empty + +Vtable for QSwipeGesture +QSwipeGesture::_ZTV13QSwipeGesture: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSwipeGesture) +16 (int (*)(...))QSwipeGesture::metaObject +24 (int (*)(...))QSwipeGesture::qt_metacast +32 (int (*)(...))QSwipeGesture::qt_metacall +40 (int (*)(...))QSwipeGesture::~QSwipeGesture +48 (int (*)(...))QSwipeGesture::~QSwipeGesture +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSwipeGesture + size=16 align=8 + base size=16 base align=8 +QSwipeGesture (0x0x7ff86204c680) 0 + vptr=((& QSwipeGesture::_ZTV13QSwipeGesture) + 16u) + QGesture (0x0x7ff86204c6e8) 0 + primary-for QSwipeGesture (0x0x7ff86204c680) + QObject (0x0x7ff862026de0) 0 + primary-for QGesture (0x0x7ff86204c6e8) + +Class QTapGesture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTapGesture::QPrivateSignal (0x0x7ff862026f60) 0 empty + +Vtable for QTapGesture +QTapGesture::_ZTV11QTapGesture: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTapGesture) +16 (int (*)(...))QTapGesture::metaObject +24 (int (*)(...))QTapGesture::qt_metacast +32 (int (*)(...))QTapGesture::qt_metacall +40 (int (*)(...))QTapGesture::~QTapGesture +48 (int (*)(...))QTapGesture::~QTapGesture +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTapGesture + size=16 align=8 + base size=16 base align=8 +QTapGesture (0x0x7ff86204c750) 0 + vptr=((& QTapGesture::_ZTV11QTapGesture) + 16u) + QGesture (0x0x7ff86204c7b8) 0 + primary-for QTapGesture (0x0x7ff86204c750) + QObject (0x0x7ff862026f00) 0 + primary-for QGesture (0x0x7ff86204c7b8) + +Class QTapAndHoldGesture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTapAndHoldGesture::QPrivateSignal (0x0x7ff861d63060) 0 empty + +Vtable for QTapAndHoldGesture +QTapAndHoldGesture::_ZTV18QTapAndHoldGesture: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QTapAndHoldGesture) +16 (int (*)(...))QTapAndHoldGesture::metaObject +24 (int (*)(...))QTapAndHoldGesture::qt_metacast +32 (int (*)(...))QTapAndHoldGesture::qt_metacall +40 (int (*)(...))QTapAndHoldGesture::~QTapAndHoldGesture +48 (int (*)(...))QTapAndHoldGesture::~QTapAndHoldGesture +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTapAndHoldGesture + size=16 align=8 + base size=16 base align=8 +QTapAndHoldGesture (0x0x7ff86204c820) 0 + vptr=((& QTapAndHoldGesture::_ZTV18QTapAndHoldGesture) + 16u) + QGesture (0x0x7ff86204c888) 0 + primary-for QTapAndHoldGesture (0x0x7ff86204c820) + QObject (0x0x7ff861d63000) 0 + primary-for QGesture (0x0x7ff86204c888) + +Vtable for QGestureEvent +QGestureEvent::_ZTV13QGestureEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QGestureEvent) +16 (int (*)(...))QGestureEvent::~QGestureEvent +24 (int (*)(...))QGestureEvent::~QGestureEvent + +Class QGestureEvent + size=56 align=8 + base size=56 base align=8 +QGestureEvent (0x0x7ff86204c8f0) 0 + vptr=((& QGestureEvent::_ZTV13QGestureEvent) + 16u) + QEvent (0x0x7ff861d630c0) 0 + primary-for QGestureEvent (0x0x7ff86204c8f0) + +Vtable for QGestureRecognizer +QGestureRecognizer::_ZTV18QGestureRecognizer: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QGestureRecognizer) +16 0u +24 0u +32 (int (*)(...))QGestureRecognizer::create +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QGestureRecognizer::reset + +Class QGestureRecognizer + size=8 align=8 + base size=8 base align=8 +QGestureRecognizer (0x0x7ff873b15660) 0 nearly-empty + vptr=((& QGestureRecognizer::_ZTV18QGestureRecognizer) + 16u) + +Vtable for QGraphicsItem +QGraphicsItem::_ZTV13QGraphicsItem: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QGraphicsItem) +16 0u +24 0u +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QGraphicsItem::shape +56 (int (*)(...))QGraphicsItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsItem::isObscuredBy +88 (int (*)(...))QGraphicsItem::opaqueArea +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))QGraphicsItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsItem::supportsExtension +296 (int (*)(...))QGraphicsItem::setExtension +304 (int (*)(...))QGraphicsItem::extension + +Class QGraphicsItem + size=16 align=8 + base size=16 base align=8 +QGraphicsItem (0x0x7ff873b8b660) 0 + vptr=((& QGraphicsItem::_ZTV13QGraphicsItem) + 16u) + +Class QGraphicsObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsObject::QPrivateSignal (0x0x7ff86c37d720) 0 empty + +Vtable for QGraphicsObject +QGraphicsObject::_ZTV15QGraphicsObject: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGraphicsObject) +16 (int (*)(...))QGraphicsObject::metaObject +24 (int (*)(...))QGraphicsObject::qt_metacast +32 (int (*)(...))QGraphicsObject::qt_metacall +40 0u +48 0u +56 (int (*)(...))QGraphicsObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))-16 +120 (int (*)(...))(& _ZTI15QGraphicsObject) +128 0u +136 0u +144 (int (*)(...))QGraphicsItem::advance +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))QGraphicsItem::shape +168 (int (*)(...))QGraphicsItem::contains +176 (int (*)(...))QGraphicsItem::collidesWithItem +184 (int (*)(...))QGraphicsItem::collidesWithPath +192 (int (*)(...))QGraphicsItem::isObscuredBy +200 (int (*)(...))QGraphicsItem::opaqueArea +208 (int (*)(...))__cxa_pure_virtual +216 (int (*)(...))QGraphicsItem::type +224 (int (*)(...))QGraphicsItem::sceneEventFilter +232 (int (*)(...))QGraphicsItem::sceneEvent +240 (int (*)(...))QGraphicsItem::contextMenuEvent +248 (int (*)(...))QGraphicsItem::dragEnterEvent +256 (int (*)(...))QGraphicsItem::dragLeaveEvent +264 (int (*)(...))QGraphicsItem::dragMoveEvent +272 (int (*)(...))QGraphicsItem::dropEvent +280 (int (*)(...))QGraphicsItem::focusInEvent +288 (int (*)(...))QGraphicsItem::focusOutEvent +296 (int (*)(...))QGraphicsItem::hoverEnterEvent +304 (int (*)(...))QGraphicsItem::hoverMoveEvent +312 (int (*)(...))QGraphicsItem::hoverLeaveEvent +320 (int (*)(...))QGraphicsItem::keyPressEvent +328 (int (*)(...))QGraphicsItem::keyReleaseEvent +336 (int (*)(...))QGraphicsItem::mousePressEvent +344 (int (*)(...))QGraphicsItem::mouseMoveEvent +352 (int (*)(...))QGraphicsItem::mouseReleaseEvent +360 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +368 (int (*)(...))QGraphicsItem::wheelEvent +376 (int (*)(...))QGraphicsItem::inputMethodEvent +384 (int (*)(...))QGraphicsItem::inputMethodQuery +392 (int (*)(...))QGraphicsItem::itemChange +400 (int (*)(...))QGraphicsItem::supportsExtension +408 (int (*)(...))QGraphicsItem::setExtension +416 (int (*)(...))QGraphicsItem::extension + +Class QGraphicsObject + size=32 align=8 + base size=32 base align=8 +QGraphicsObject (0x0x7ff86ef10d20) 0 + vptr=((& QGraphicsObject::_ZTV15QGraphicsObject) + 16u) + QObject (0x0x7ff86dd1d300) 0 + primary-for QGraphicsObject (0x0x7ff86ef10d20) + QGraphicsItem (0x0x7ff86c37d6c0) 16 + vptr=((& QGraphicsObject::_ZTV15QGraphicsObject) + 128u) + +Vtable for QAbstractGraphicsShapeItem +QAbstractGraphicsShapeItem::_ZTV26QAbstractGraphicsShapeItem: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractGraphicsShapeItem) +16 0u +24 0u +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QGraphicsItem::shape +56 (int (*)(...))QGraphicsItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QAbstractGraphicsShapeItem::isObscuredBy +88 (int (*)(...))QAbstractGraphicsShapeItem::opaqueArea +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))QGraphicsItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsItem::supportsExtension +296 (int (*)(...))QGraphicsItem::setExtension +304 (int (*)(...))QGraphicsItem::extension + +Class QAbstractGraphicsShapeItem + size=16 align=8 + base size=16 base align=8 +QAbstractGraphicsShapeItem (0x0x7ff86dec7a28) 0 + vptr=((& QAbstractGraphicsShapeItem::_ZTV26QAbstractGraphicsShapeItem) + 16u) + QGraphicsItem (0x0x7ff86c37da20) 0 + primary-for QAbstractGraphicsShapeItem (0x0x7ff86dec7a28) + +Vtable for QGraphicsPathItem +QGraphicsPathItem::_ZTV17QGraphicsPathItem: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QGraphicsPathItem) +16 (int (*)(...))QGraphicsPathItem::~QGraphicsPathItem +24 (int (*)(...))QGraphicsPathItem::~QGraphicsPathItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsPathItem::boundingRect +48 (int (*)(...))QGraphicsPathItem::shape +56 (int (*)(...))QGraphicsPathItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsPathItem::isObscuredBy +88 (int (*)(...))QGraphicsPathItem::opaqueArea +96 (int (*)(...))QGraphicsPathItem::paint +104 (int (*)(...))QGraphicsPathItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsPathItem::supportsExtension +296 (int (*)(...))QGraphicsPathItem::setExtension +304 (int (*)(...))QGraphicsPathItem::extension + +Class QGraphicsPathItem + size=16 align=8 + base size=16 base align=8 +QGraphicsPathItem (0x0x7ff86dec7dd0) 0 + vptr=((& QGraphicsPathItem::_ZTV17QGraphicsPathItem) + 16u) + QAbstractGraphicsShapeItem (0x0x7ff86dec7e38) 0 + primary-for QGraphicsPathItem (0x0x7ff86dec7dd0) + QGraphicsItem (0x0x7ff86c37da80) 0 + primary-for QAbstractGraphicsShapeItem (0x0x7ff86dec7e38) + +Vtable for QGraphicsRectItem +QGraphicsRectItem::_ZTV17QGraphicsRectItem: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QGraphicsRectItem) +16 (int (*)(...))QGraphicsRectItem::~QGraphicsRectItem +24 (int (*)(...))QGraphicsRectItem::~QGraphicsRectItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsRectItem::boundingRect +48 (int (*)(...))QGraphicsRectItem::shape +56 (int (*)(...))QGraphicsRectItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsRectItem::isObscuredBy +88 (int (*)(...))QGraphicsRectItem::opaqueArea +96 (int (*)(...))QGraphicsRectItem::paint +104 (int (*)(...))QGraphicsRectItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsRectItem::supportsExtension +296 (int (*)(...))QGraphicsRectItem::setExtension +304 (int (*)(...))QGraphicsRectItem::extension + +Class QGraphicsRectItem + size=16 align=8 + base size=16 base align=8 +QGraphicsRectItem (0x0x7ff86db43f70) 0 + vptr=((& QGraphicsRectItem::_ZTV17QGraphicsRectItem) + 16u) + QAbstractGraphicsShapeItem (0x0x7ff86d2f3f08) 0 + primary-for QGraphicsRectItem (0x0x7ff86db43f70) + QGraphicsItem (0x0x7ff86bcd60c0) 0 + primary-for QAbstractGraphicsShapeItem (0x0x7ff86d2f3f08) + +Vtable for QGraphicsEllipseItem +QGraphicsEllipseItem::_ZTV20QGraphicsEllipseItem: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QGraphicsEllipseItem) +16 (int (*)(...))QGraphicsEllipseItem::~QGraphicsEllipseItem +24 (int (*)(...))QGraphicsEllipseItem::~QGraphicsEllipseItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsEllipseItem::boundingRect +48 (int (*)(...))QGraphicsEllipseItem::shape +56 (int (*)(...))QGraphicsEllipseItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsEllipseItem::isObscuredBy +88 (int (*)(...))QGraphicsEllipseItem::opaqueArea +96 (int (*)(...))QGraphicsEllipseItem::paint +104 (int (*)(...))QGraphicsEllipseItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsEllipseItem::supportsExtension +296 (int (*)(...))QGraphicsEllipseItem::setExtension +304 (int (*)(...))QGraphicsEllipseItem::extension + +Class QGraphicsEllipseItem + size=16 align=8 + base size=16 base align=8 +QGraphicsEllipseItem (0x0x7ff86d2f3f70) 0 + vptr=((& QGraphicsEllipseItem::_ZTV20QGraphicsEllipseItem) + 16u) + QAbstractGraphicsShapeItem (0x0x7ff86d2f3000) 0 + primary-for QGraphicsEllipseItem (0x0x7ff86d2f3f70) + QGraphicsItem (0x0x7ff86bcd6120) 0 + primary-for QAbstractGraphicsShapeItem (0x0x7ff86d2f3000) + +Vtable for QGraphicsPolygonItem +QGraphicsPolygonItem::_ZTV20QGraphicsPolygonItem: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QGraphicsPolygonItem) +16 (int (*)(...))QGraphicsPolygonItem::~QGraphicsPolygonItem +24 (int (*)(...))QGraphicsPolygonItem::~QGraphicsPolygonItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsPolygonItem::boundingRect +48 (int (*)(...))QGraphicsPolygonItem::shape +56 (int (*)(...))QGraphicsPolygonItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsPolygonItem::isObscuredBy +88 (int (*)(...))QGraphicsPolygonItem::opaqueArea +96 (int (*)(...))QGraphicsPolygonItem::paint +104 (int (*)(...))QGraphicsPolygonItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsPolygonItem::supportsExtension +296 (int (*)(...))QGraphicsPolygonItem::setExtension +304 (int (*)(...))QGraphicsPolygonItem::extension + +Class QGraphicsPolygonItem + size=16 align=8 + base size=16 base align=8 +QGraphicsPolygonItem (0x0x7ff86d2f3068) 0 + vptr=((& QGraphicsPolygonItem::_ZTV20QGraphicsPolygonItem) + 16u) + QAbstractGraphicsShapeItem (0x0x7ff86d2f3ea0) 0 + primary-for QGraphicsPolygonItem (0x0x7ff86d2f3068) + QGraphicsItem (0x0x7ff86bcd6a20) 0 + primary-for QAbstractGraphicsShapeItem (0x0x7ff86d2f3ea0) + +Vtable for QGraphicsLineItem +QGraphicsLineItem::_ZTV17QGraphicsLineItem: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QGraphicsLineItem) +16 (int (*)(...))QGraphicsLineItem::~QGraphicsLineItem +24 (int (*)(...))QGraphicsLineItem::~QGraphicsLineItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsLineItem::boundingRect +48 (int (*)(...))QGraphicsLineItem::shape +56 (int (*)(...))QGraphicsLineItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsLineItem::isObscuredBy +88 (int (*)(...))QGraphicsLineItem::opaqueArea +96 (int (*)(...))QGraphicsLineItem::paint +104 (int (*)(...))QGraphicsLineItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsLineItem::supportsExtension +296 (int (*)(...))QGraphicsLineItem::setExtension +304 (int (*)(...))QGraphicsLineItem::extension + +Class QGraphicsLineItem + size=16 align=8 + base size=16 base align=8 +QGraphicsLineItem (0x0x7ff86c965000) 0 + vptr=((& QGraphicsLineItem::_ZTV17QGraphicsLineItem) + 16u) + QGraphicsItem (0x0x7ff86bcd6a80) 0 + primary-for QGraphicsLineItem (0x0x7ff86c965000) + +Vtable for QGraphicsPixmapItem +QGraphicsPixmapItem::_ZTV19QGraphicsPixmapItem: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QGraphicsPixmapItem) +16 (int (*)(...))QGraphicsPixmapItem::~QGraphicsPixmapItem +24 (int (*)(...))QGraphicsPixmapItem::~QGraphicsPixmapItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsPixmapItem::boundingRect +48 (int (*)(...))QGraphicsPixmapItem::shape +56 (int (*)(...))QGraphicsPixmapItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsPixmapItem::isObscuredBy +88 (int (*)(...))QGraphicsPixmapItem::opaqueArea +96 (int (*)(...))QGraphicsPixmapItem::paint +104 (int (*)(...))QGraphicsPixmapItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsPixmapItem::supportsExtension +296 (int (*)(...))QGraphicsPixmapItem::setExtension +304 (int (*)(...))QGraphicsPixmapItem::extension + +Class QGraphicsPixmapItem + size=16 align=8 + base size=16 base align=8 +QGraphicsPixmapItem (0x0x7ff86c965068) 0 + vptr=((& QGraphicsPixmapItem::_ZTV19QGraphicsPixmapItem) + 16u) + QGraphicsItem (0x0x7ff86bcfc180) 0 + primary-for QGraphicsPixmapItem (0x0x7ff86c965068) + +Class QGraphicsTextItem::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsTextItem::QPrivateSignal (0x0x7ff86bcfc360) 0 empty + +Vtable for QGraphicsTextItem +QGraphicsTextItem::_ZTV17QGraphicsTextItem: 82u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QGraphicsTextItem) +16 (int (*)(...))QGraphicsTextItem::metaObject +24 (int (*)(...))QGraphicsTextItem::qt_metacast +32 (int (*)(...))QGraphicsTextItem::qt_metacall +40 (int (*)(...))QGraphicsTextItem::~QGraphicsTextItem +48 (int (*)(...))QGraphicsTextItem::~QGraphicsTextItem +56 (int (*)(...))QGraphicsObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsTextItem::boundingRect +120 (int (*)(...))QGraphicsTextItem::shape +128 (int (*)(...))QGraphicsTextItem::contains +136 (int (*)(...))QGraphicsTextItem::paint +144 (int (*)(...))QGraphicsTextItem::isObscuredBy +152 (int (*)(...))QGraphicsTextItem::opaqueArea +160 (int (*)(...))QGraphicsTextItem::type +168 (int (*)(...))QGraphicsTextItem::sceneEvent +176 (int (*)(...))QGraphicsTextItem::mousePressEvent +184 (int (*)(...))QGraphicsTextItem::mouseMoveEvent +192 (int (*)(...))QGraphicsTextItem::mouseReleaseEvent +200 (int (*)(...))QGraphicsTextItem::mouseDoubleClickEvent +208 (int (*)(...))QGraphicsTextItem::contextMenuEvent +216 (int (*)(...))QGraphicsTextItem::keyPressEvent +224 (int (*)(...))QGraphicsTextItem::keyReleaseEvent +232 (int (*)(...))QGraphicsTextItem::focusInEvent +240 (int (*)(...))QGraphicsTextItem::focusOutEvent +248 (int (*)(...))QGraphicsTextItem::dragEnterEvent +256 (int (*)(...))QGraphicsTextItem::dragLeaveEvent +264 (int (*)(...))QGraphicsTextItem::dragMoveEvent +272 (int (*)(...))QGraphicsTextItem::dropEvent +280 (int (*)(...))QGraphicsTextItem::inputMethodEvent +288 (int (*)(...))QGraphicsTextItem::hoverEnterEvent +296 (int (*)(...))QGraphicsTextItem::hoverMoveEvent +304 (int (*)(...))QGraphicsTextItem::hoverLeaveEvent +312 (int (*)(...))QGraphicsTextItem::inputMethodQuery +320 (int (*)(...))QGraphicsTextItem::supportsExtension +328 (int (*)(...))QGraphicsTextItem::setExtension +336 (int (*)(...))QGraphicsTextItem::extension +344 (int (*)(...))-16 +352 (int (*)(...))(& _ZTI17QGraphicsTextItem) +360 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItemD1Ev +368 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItemD0Ev +376 (int (*)(...))QGraphicsItem::advance +384 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem12boundingRectEv +392 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem5shapeEv +400 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem8containsERK7QPointF +408 (int (*)(...))QGraphicsItem::collidesWithItem +416 (int (*)(...))QGraphicsItem::collidesWithPath +424 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem12isObscuredByEPK13QGraphicsItem +432 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem10opaqueAreaEv +440 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem5paintEP8QPainterPK24QStyleOptionGraphicsItemP7QWidget +448 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem4typeEv +456 (int (*)(...))QGraphicsItem::sceneEventFilter +464 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem10sceneEventEP6QEvent +472 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem16contextMenuEventEP30QGraphicsSceneContextMenuEvent +480 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem14dragEnterEventEP27QGraphicsSceneDragDropEvent +488 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem14dragLeaveEventEP27QGraphicsSceneDragDropEvent +496 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem13dragMoveEventEP27QGraphicsSceneDragDropEvent +504 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem9dropEventEP27QGraphicsSceneDragDropEvent +512 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem12focusInEventEP11QFocusEvent +520 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem13focusOutEventEP11QFocusEvent +528 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem15hoverEnterEventEP24QGraphicsSceneHoverEvent +536 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem14hoverMoveEventEP24QGraphicsSceneHoverEvent +544 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem15hoverLeaveEventEP24QGraphicsSceneHoverEvent +552 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem13keyPressEventEP9QKeyEvent +560 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem15keyReleaseEventEP9QKeyEvent +568 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem15mousePressEventEP24QGraphicsSceneMouseEvent +576 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem14mouseMoveEventEP24QGraphicsSceneMouseEvent +584 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem17mouseReleaseEventEP24QGraphicsSceneMouseEvent +592 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem21mouseDoubleClickEventEP24QGraphicsSceneMouseEvent +600 (int (*)(...))QGraphicsItem::wheelEvent +608 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem16inputMethodEventEP17QInputMethodEvent +616 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem16inputMethodQueryEN2Qt16InputMethodQueryE +624 (int (*)(...))QGraphicsItem::itemChange +632 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem17supportsExtensionEN13QGraphicsItem9ExtensionE +640 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem12setExtensionEN13QGraphicsItem9ExtensionERK8QVariant +648 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem9extensionERK8QVariant + +Class QGraphicsTextItem + size=40 align=8 + base size=40 base align=8 +QGraphicsTextItem (0x0x7ff86c9650d0) 0 + vptr=((& QGraphicsTextItem::_ZTV17QGraphicsTextItem) + 16u) + QGraphicsObject (0x0x7ff86ef43460) 0 + primary-for QGraphicsTextItem (0x0x7ff86c9650d0) + QObject (0x0x7ff86bcfc1e0) 0 + primary-for QGraphicsObject (0x0x7ff86ef43460) + QGraphicsItem (0x0x7ff86bcfc2a0) 16 + vptr=((& QGraphicsTextItem::_ZTV17QGraphicsTextItem) + 360u) + +Vtable for QGraphicsSimpleTextItem +QGraphicsSimpleTextItem::_ZTV23QGraphicsSimpleTextItem: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGraphicsSimpleTextItem) +16 (int (*)(...))QGraphicsSimpleTextItem::~QGraphicsSimpleTextItem +24 (int (*)(...))QGraphicsSimpleTextItem::~QGraphicsSimpleTextItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsSimpleTextItem::boundingRect +48 (int (*)(...))QGraphicsSimpleTextItem::shape +56 (int (*)(...))QGraphicsSimpleTextItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsSimpleTextItem::isObscuredBy +88 (int (*)(...))QGraphicsSimpleTextItem::opaqueArea +96 (int (*)(...))QGraphicsSimpleTextItem::paint +104 (int (*)(...))QGraphicsSimpleTextItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsSimpleTextItem::supportsExtension +296 (int (*)(...))QGraphicsSimpleTextItem::setExtension +304 (int (*)(...))QGraphicsSimpleTextItem::extension + +Class QGraphicsSimpleTextItem + size=16 align=8 + base size=16 base align=8 +QGraphicsSimpleTextItem (0x0x7ff86c81dbc8) 0 + vptr=((& QGraphicsSimpleTextItem::_ZTV23QGraphicsSimpleTextItem) + 16u) + QAbstractGraphicsShapeItem (0x0x7ff86c81dc30) 0 + primary-for QGraphicsSimpleTextItem (0x0x7ff86c81dbc8) + QGraphicsItem (0x0x7ff86bcfcea0) 0 + primary-for QAbstractGraphicsShapeItem (0x0x7ff86c81dc30) + +Vtable for QGraphicsItemGroup +QGraphicsItemGroup::_ZTV18QGraphicsItemGroup: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QGraphicsItemGroup) +16 (int (*)(...))QGraphicsItemGroup::~QGraphicsItemGroup +24 (int (*)(...))QGraphicsItemGroup::~QGraphicsItemGroup +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsItemGroup::boundingRect +48 (int (*)(...))QGraphicsItem::shape +56 (int (*)(...))QGraphicsItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsItemGroup::isObscuredBy +88 (int (*)(...))QGraphicsItemGroup::opaqueArea +96 (int (*)(...))QGraphicsItemGroup::paint +104 (int (*)(...))QGraphicsItemGroup::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsItem::supportsExtension +296 (int (*)(...))QGraphicsItem::setExtension +304 (int (*)(...))QGraphicsItem::extension + +Class QGraphicsItemGroup + size=16 align=8 + base size=16 base align=8 +QGraphicsItemGroup (0x0x7ff86c05ff08) 0 + vptr=((& QGraphicsItemGroup::_ZTV18QGraphicsItemGroup) + 16u) + QGraphicsItem (0x0x7ff86bd185a0) 0 + primary-for QGraphicsItemGroup (0x0x7ff86c05ff08) + +Vtable for QGraphicsLayoutItem +QGraphicsLayoutItem::_ZTV19QGraphicsLayoutItem: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QGraphicsLayoutItem) +16 0u +24 0u +32 (int (*)(...))QGraphicsLayoutItem::setGeometry +40 (int (*)(...))QGraphicsLayoutItem::getContentsMargins +48 (int (*)(...))QGraphicsLayoutItem::updateGeometry +56 (int (*)(...))__cxa_pure_virtual + +Class QGraphicsLayoutItem + size=16 align=8 + base size=16 base align=8 +QGraphicsLayoutItem (0x0x7ff86bb0b180) 0 + vptr=((& QGraphicsLayoutItem::_ZTV19QGraphicsLayoutItem) + 16u) + +Vtable for QGraphicsLayout +QGraphicsLayout::_ZTV15QGraphicsLayout: 13u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGraphicsLayout) +16 0u +24 0u +32 (int (*)(...))QGraphicsLayoutItem::setGeometry +40 (int (*)(...))QGraphicsLayout::getContentsMargins +48 (int (*)(...))QGraphicsLayout::updateGeometry +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))QGraphicsLayout::invalidate +72 (int (*)(...))QGraphicsLayout::widgetEvent +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual + +Class QGraphicsLayout + size=16 align=8 + base size=16 base align=8 +QGraphicsLayout (0x0x7ff86c05ff70) 0 + vptr=((& QGraphicsLayout::_ZTV15QGraphicsLayout) + 16u) + QGraphicsLayoutItem (0x0x7ff86bb0bcc0) 0 + primary-for QGraphicsLayout (0x0x7ff86c05ff70) + +Class QGraphicsAnchor::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsAnchor::QPrivateSignal (0x0x7ff86bb0bde0) 0 empty + +Vtable for QGraphicsAnchor +QGraphicsAnchor::_ZTV15QGraphicsAnchor: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGraphicsAnchor) +16 (int (*)(...))QGraphicsAnchor::metaObject +24 (int (*)(...))QGraphicsAnchor::qt_metacast +32 (int (*)(...))QGraphicsAnchor::qt_metacall +40 (int (*)(...))QGraphicsAnchor::~QGraphicsAnchor +48 (int (*)(...))QGraphicsAnchor::~QGraphicsAnchor +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QGraphicsAnchor + size=16 align=8 + base size=16 base align=8 +QGraphicsAnchor (0x0x7ff86bce1478) 0 + vptr=((& QGraphicsAnchor::_ZTV15QGraphicsAnchor) + 16u) + QObject (0x0x7ff86bb0bd80) 0 + primary-for QGraphicsAnchor (0x0x7ff86bce1478) + +Vtable for QGraphicsAnchorLayout +QGraphicsAnchorLayout::_ZTV21QGraphicsAnchorLayout: 13u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QGraphicsAnchorLayout) +16 (int (*)(...))QGraphicsAnchorLayout::~QGraphicsAnchorLayout +24 (int (*)(...))QGraphicsAnchorLayout::~QGraphicsAnchorLayout +32 (int (*)(...))QGraphicsAnchorLayout::setGeometry +40 (int (*)(...))QGraphicsLayout::getContentsMargins +48 (int (*)(...))QGraphicsLayout::updateGeometry +56 (int (*)(...))QGraphicsAnchorLayout::sizeHint +64 (int (*)(...))QGraphicsAnchorLayout::invalidate +72 (int (*)(...))QGraphicsLayout::widgetEvent +80 (int (*)(...))QGraphicsAnchorLayout::count +88 (int (*)(...))QGraphicsAnchorLayout::itemAt +96 (int (*)(...))QGraphicsAnchorLayout::removeAt + +Class QGraphicsAnchorLayout + size=16 align=8 + base size=16 base align=8 +QGraphicsAnchorLayout (0x0x7ff86bce14e0) 0 + vptr=((& QGraphicsAnchorLayout::_ZTV21QGraphicsAnchorLayout) + 16u) + QGraphicsLayout (0x0x7ff86bd0c478) 0 + primary-for QGraphicsAnchorLayout (0x0x7ff86bce14e0) + QGraphicsLayoutItem (0x0x7ff86bb0be40) 0 + primary-for QGraphicsLayout (0x0x7ff86bd0c478) + +Class QGraphicsEffect::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsEffect::QPrivateSignal (0x0x7ff86bb0bf00) 0 empty + +Vtable for QGraphicsEffect +QGraphicsEffect::_ZTV15QGraphicsEffect: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGraphicsEffect) +16 (int (*)(...))QGraphicsEffect::metaObject +24 (int (*)(...))QGraphicsEffect::qt_metacast +32 (int (*)(...))QGraphicsEffect::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsEffect::boundingRectFor +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QGraphicsEffect::sourceChanged + +Class QGraphicsEffect + size=16 align=8 + base size=16 base align=8 +QGraphicsEffect (0x0x7ff86bd0c4e0) 0 + vptr=((& QGraphicsEffect::_ZTV15QGraphicsEffect) + 16u) + QObject (0x0x7ff86bb0bea0) 0 + primary-for QGraphicsEffect (0x0x7ff86bd0c4e0) + +Class QGraphicsColorizeEffect::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsColorizeEffect::QPrivateSignal (0x0x7ff86bc401e0) 0 empty + +Vtable for QGraphicsColorizeEffect +QGraphicsColorizeEffect::_ZTV23QGraphicsColorizeEffect: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGraphicsColorizeEffect) +16 (int (*)(...))QGraphicsColorizeEffect::metaObject +24 (int (*)(...))QGraphicsColorizeEffect::qt_metacast +32 (int (*)(...))QGraphicsColorizeEffect::qt_metacall +40 (int (*)(...))QGraphicsColorizeEffect::~QGraphicsColorizeEffect +48 (int (*)(...))QGraphicsColorizeEffect::~QGraphicsColorizeEffect +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsEffect::boundingRectFor +120 (int (*)(...))QGraphicsColorizeEffect::draw +128 (int (*)(...))QGraphicsEffect::sourceChanged + +Class QGraphicsColorizeEffect + size=16 align=8 + base size=16 base align=8 +QGraphicsColorizeEffect (0x0x7ff86bd2b478) 0 + vptr=((& QGraphicsColorizeEffect::_ZTV23QGraphicsColorizeEffect) + 16u) + QGraphicsEffect (0x0x7ff86bd2b4e0) 0 + primary-for QGraphicsColorizeEffect (0x0x7ff86bd2b478) + QObject (0x0x7ff86bc40180) 0 + primary-for QGraphicsEffect (0x0x7ff86bd2b4e0) + +Class QGraphicsBlurEffect::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsBlurEffect::QPrivateSignal (0x0x7ff86b9da300) 0 empty + +Vtable for QGraphicsBlurEffect +QGraphicsBlurEffect::_ZTV19QGraphicsBlurEffect: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QGraphicsBlurEffect) +16 (int (*)(...))QGraphicsBlurEffect::metaObject +24 (int (*)(...))QGraphicsBlurEffect::qt_metacast +32 (int (*)(...))QGraphicsBlurEffect::qt_metacall +40 (int (*)(...))QGraphicsBlurEffect::~QGraphicsBlurEffect +48 (int (*)(...))QGraphicsBlurEffect::~QGraphicsBlurEffect +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsBlurEffect::boundingRectFor +120 (int (*)(...))QGraphicsBlurEffect::draw +128 (int (*)(...))QGraphicsEffect::sourceChanged + +Class QGraphicsBlurEffect + size=16 align=8 + base size=16 base align=8 +QGraphicsBlurEffect (0x0x7ff86bd2b958) 0 + vptr=((& QGraphicsBlurEffect::_ZTV19QGraphicsBlurEffect) + 16u) + QGraphicsEffect (0x0x7ff86bd2b9c0) 0 + primary-for QGraphicsBlurEffect (0x0x7ff86bd2b958) + QObject (0x0x7ff86bc40240) 0 + primary-for QGraphicsEffect (0x0x7ff86bd2b9c0) + +Class QGraphicsDropShadowEffect::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsDropShadowEffect::QPrivateSignal (0x0x7ff86b9da7e0) 0 empty + +Vtable for QGraphicsDropShadowEffect +QGraphicsDropShadowEffect::_ZTV25QGraphicsDropShadowEffect: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QGraphicsDropShadowEffect) +16 (int (*)(...))QGraphicsDropShadowEffect::metaObject +24 (int (*)(...))QGraphicsDropShadowEffect::qt_metacast +32 (int (*)(...))QGraphicsDropShadowEffect::qt_metacall +40 (int (*)(...))QGraphicsDropShadowEffect::~QGraphicsDropShadowEffect +48 (int (*)(...))QGraphicsDropShadowEffect::~QGraphicsDropShadowEffect +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsDropShadowEffect::boundingRectFor +120 (int (*)(...))QGraphicsDropShadowEffect::draw +128 (int (*)(...))QGraphicsEffect::sourceChanged + +Class QGraphicsDropShadowEffect + size=16 align=8 + base size=16 base align=8 +QGraphicsDropShadowEffect (0x0x7ff86bb046e8) 0 + vptr=((& QGraphicsDropShadowEffect::_ZTV25QGraphicsDropShadowEffect) + 16u) + QGraphicsEffect (0x0x7ff86bb04750) 0 + primary-for QGraphicsDropShadowEffect (0x0x7ff86bb046e8) + QObject (0x0x7ff86b9da780) 0 + primary-for QGraphicsEffect (0x0x7ff86bb04750) + +Class QGraphicsOpacityEffect::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsOpacityEffect::QPrivateSignal (0x0x7ff86b86f8a0) 0 empty + +Vtable for QGraphicsOpacityEffect +QGraphicsOpacityEffect::_ZTV22QGraphicsOpacityEffect: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QGraphicsOpacityEffect) +16 (int (*)(...))QGraphicsOpacityEffect::metaObject +24 (int (*)(...))QGraphicsOpacityEffect::qt_metacast +32 (int (*)(...))QGraphicsOpacityEffect::qt_metacall +40 (int (*)(...))QGraphicsOpacityEffect::~QGraphicsOpacityEffect +48 (int (*)(...))QGraphicsOpacityEffect::~QGraphicsOpacityEffect +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsEffect::boundingRectFor +120 (int (*)(...))QGraphicsOpacityEffect::draw +128 (int (*)(...))QGraphicsEffect::sourceChanged + +Class QGraphicsOpacityEffect + size=16 align=8 + base size=16 base align=8 +QGraphicsOpacityEffect (0x0x7ff86bb047b8) 0 + vptr=((& QGraphicsOpacityEffect::_ZTV22QGraphicsOpacityEffect) + 16u) + QGraphicsEffect (0x0x7ff86bb04820) 0 + primary-for QGraphicsOpacityEffect (0x0x7ff86bb047b8) + QObject (0x0x7ff86b86f840) 0 + primary-for QGraphicsEffect (0x0x7ff86bb04820) + +Vtable for QGraphicsGridLayout +QGraphicsGridLayout::_ZTV19QGraphicsGridLayout: 13u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QGraphicsGridLayout) +16 (int (*)(...))QGraphicsGridLayout::~QGraphicsGridLayout +24 (int (*)(...))QGraphicsGridLayout::~QGraphicsGridLayout +32 (int (*)(...))QGraphicsGridLayout::setGeometry +40 (int (*)(...))QGraphicsLayout::getContentsMargins +48 (int (*)(...))QGraphicsLayout::updateGeometry +56 (int (*)(...))QGraphicsGridLayout::sizeHint +64 (int (*)(...))QGraphicsGridLayout::invalidate +72 (int (*)(...))QGraphicsLayout::widgetEvent +80 (int (*)(...))QGraphicsGridLayout::count +88 (int (*)(...))QGraphicsGridLayout::itemAt +96 (int (*)(...))QGraphicsGridLayout::removeAt + +Class QGraphicsGridLayout + size=16 align=8 + base size=16 base align=8 +QGraphicsGridLayout (0x0x7ff86bb04888) 0 + vptr=((& QGraphicsGridLayout::_ZTV19QGraphicsGridLayout) + 16u) + QGraphicsLayout (0x0x7ff86bb048f0) 0 + primary-for QGraphicsGridLayout (0x0x7ff86bb04888) + QGraphicsLayoutItem (0x0x7ff86b86f960) 0 + primary-for QGraphicsLayout (0x0x7ff86bb048f0) + +Class QGraphicsItemAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsItemAnimation::QPrivateSignal (0x0x7ff86b86fba0) 0 empty + +Vtable for QGraphicsItemAnimation +QGraphicsItemAnimation::_ZTV22QGraphicsItemAnimation: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QGraphicsItemAnimation) +16 (int (*)(...))QGraphicsItemAnimation::metaObject +24 (int (*)(...))QGraphicsItemAnimation::qt_metacast +32 (int (*)(...))QGraphicsItemAnimation::qt_metacall +40 (int (*)(...))QGraphicsItemAnimation::~QGraphicsItemAnimation +48 (int (*)(...))QGraphicsItemAnimation::~QGraphicsItemAnimation +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsItemAnimation::beforeAnimationStep +120 (int (*)(...))QGraphicsItemAnimation::afterAnimationStep + +Class QGraphicsItemAnimation + size=24 align=8 + base size=24 base align=8 +QGraphicsItemAnimation (0x0x7ff86bb049c0) 0 + vptr=((& QGraphicsItemAnimation::_ZTV22QGraphicsItemAnimation) + 16u) + QObject (0x0x7ff86b86fb40) 0 + primary-for QGraphicsItemAnimation (0x0x7ff86bb049c0) + +Vtable for QGraphicsLinearLayout +QGraphicsLinearLayout::_ZTV21QGraphicsLinearLayout: 13u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QGraphicsLinearLayout) +16 (int (*)(...))QGraphicsLinearLayout::~QGraphicsLinearLayout +24 (int (*)(...))QGraphicsLinearLayout::~QGraphicsLinearLayout +32 (int (*)(...))QGraphicsLinearLayout::setGeometry +40 (int (*)(...))QGraphicsLayout::getContentsMargins +48 (int (*)(...))QGraphicsLayout::updateGeometry +56 (int (*)(...))QGraphicsLinearLayout::sizeHint +64 (int (*)(...))QGraphicsLinearLayout::invalidate +72 (int (*)(...))QGraphicsLayout::widgetEvent +80 (int (*)(...))QGraphicsLinearLayout::count +88 (int (*)(...))QGraphicsLinearLayout::itemAt +96 (int (*)(...))QGraphicsLinearLayout::removeAt + +Class QGraphicsLinearLayout + size=16 align=8 + base size=16 base align=8 +QGraphicsLinearLayout (0x0x7ff86bb04a28) 0 + vptr=((& QGraphicsLinearLayout::_ZTV21QGraphicsLinearLayout) + 16u) + QGraphicsLayout (0x0x7ff86bb04a90) 0 + primary-for QGraphicsLinearLayout (0x0x7ff86bb04a28) + QGraphicsLayoutItem (0x0x7ff86b536720) 0 + primary-for QGraphicsLayout (0x0x7ff86bb04a90) + +Class QGraphicsWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsWidget::QPrivateSignal (0x0x7ff86b5601e0) 0 empty + +Vtable for QGraphicsWidget +QGraphicsWidget::_ZTV15QGraphicsWidget: 92u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGraphicsWidget) +16 (int (*)(...))QGraphicsWidget::metaObject +24 (int (*)(...))QGraphicsWidget::qt_metacast +32 (int (*)(...))QGraphicsWidget::qt_metacall +40 (int (*)(...))QGraphicsWidget::~QGraphicsWidget +48 (int (*)(...))QGraphicsWidget::~QGraphicsWidget +56 (int (*)(...))QGraphicsWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsWidget::setGeometry +120 (int (*)(...))QGraphicsWidget::getContentsMargins +128 (int (*)(...))QGraphicsWidget::type +136 (int (*)(...))QGraphicsWidget::paint +144 (int (*)(...))QGraphicsWidget::paintWindowFrame +152 (int (*)(...))QGraphicsWidget::boundingRect +160 (int (*)(...))QGraphicsWidget::shape +168 (int (*)(...))QGraphicsWidget::initStyleOption +176 (int (*)(...))QGraphicsWidget::sizeHint +184 (int (*)(...))QGraphicsWidget::updateGeometry +192 (int (*)(...))QGraphicsWidget::itemChange +200 (int (*)(...))QGraphicsWidget::propertyChange +208 (int (*)(...))QGraphicsWidget::sceneEvent +216 (int (*)(...))QGraphicsWidget::windowFrameEvent +224 (int (*)(...))QGraphicsWidget::windowFrameSectionAt +232 (int (*)(...))QGraphicsWidget::changeEvent +240 (int (*)(...))QGraphicsWidget::closeEvent +248 (int (*)(...))QGraphicsWidget::focusInEvent +256 (int (*)(...))QGraphicsWidget::focusNextPrevChild +264 (int (*)(...))QGraphicsWidget::focusOutEvent +272 (int (*)(...))QGraphicsWidget::hideEvent +280 (int (*)(...))QGraphicsWidget::moveEvent +288 (int (*)(...))QGraphicsWidget::polishEvent +296 (int (*)(...))QGraphicsWidget::resizeEvent +304 (int (*)(...))QGraphicsWidget::showEvent +312 (int (*)(...))QGraphicsWidget::hoverMoveEvent +320 (int (*)(...))QGraphicsWidget::hoverLeaveEvent +328 (int (*)(...))QGraphicsWidget::grabMouseEvent +336 (int (*)(...))QGraphicsWidget::ungrabMouseEvent +344 (int (*)(...))QGraphicsWidget::grabKeyboardEvent +352 (int (*)(...))QGraphicsWidget::ungrabKeyboardEvent +360 (int (*)(...))-16 +368 (int (*)(...))(& _ZTI15QGraphicsWidget) +376 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidgetD1Ev +384 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidgetD0Ev +392 (int (*)(...))QGraphicsItem::advance +400 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget12boundingRectEv +408 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget5shapeEv +416 (int (*)(...))QGraphicsItem::contains +424 (int (*)(...))QGraphicsItem::collidesWithItem +432 (int (*)(...))QGraphicsItem::collidesWithPath +440 (int (*)(...))QGraphicsItem::isObscuredBy +448 (int (*)(...))QGraphicsItem::opaqueArea +456 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget5paintEP8QPainterPK24QStyleOptionGraphicsItemP7QWidget +464 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget4typeEv +472 (int (*)(...))QGraphicsItem::sceneEventFilter +480 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget10sceneEventEP6QEvent +488 (int (*)(...))QGraphicsItem::contextMenuEvent +496 (int (*)(...))QGraphicsItem::dragEnterEvent +504 (int (*)(...))QGraphicsItem::dragLeaveEvent +512 (int (*)(...))QGraphicsItem::dragMoveEvent +520 (int (*)(...))QGraphicsItem::dropEvent +528 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget12focusInEventEP11QFocusEvent +536 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget13focusOutEventEP11QFocusEvent +544 (int (*)(...))QGraphicsItem::hoverEnterEvent +552 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget14hoverMoveEventEP24QGraphicsSceneHoverEvent +560 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget15hoverLeaveEventEP24QGraphicsSceneHoverEvent +568 (int (*)(...))QGraphicsItem::keyPressEvent +576 (int (*)(...))QGraphicsItem::keyReleaseEvent +584 (int (*)(...))QGraphicsItem::mousePressEvent +592 (int (*)(...))QGraphicsItem::mouseMoveEvent +600 (int (*)(...))QGraphicsItem::mouseReleaseEvent +608 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +616 (int (*)(...))QGraphicsItem::wheelEvent +624 (int (*)(...))QGraphicsItem::inputMethodEvent +632 (int (*)(...))QGraphicsItem::inputMethodQuery +640 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget10itemChangeEN13QGraphicsItem18GraphicsItemChangeERK8QVariant +648 (int (*)(...))QGraphicsItem::supportsExtension +656 (int (*)(...))QGraphicsItem::setExtension +664 (int (*)(...))QGraphicsItem::extension +672 (int (*)(...))-32 +680 (int (*)(...))(& _ZTI15QGraphicsWidget) +688 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidgetD1Ev +696 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidgetD0Ev +704 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidget11setGeometryERK6QRectF +712 (int (*)(...))QGraphicsWidget::_ZThn32_NK15QGraphicsWidget18getContentsMarginsEPdS0_S0_S0_ +720 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidget14updateGeometryEv +728 (int (*)(...))QGraphicsWidget::_ZThn32_NK15QGraphicsWidget8sizeHintEN2Qt8SizeHintERK6QSizeF + +Class QGraphicsWidget + size=48 align=8 + base size=48 base align=8 +QGraphicsWidget (0x0x7ff86eae6540) 0 + vptr=((& QGraphicsWidget::_ZTV15QGraphicsWidget) + 16u) + QGraphicsObject (0x0x7ff86eae65b0) 0 + primary-for QGraphicsWidget (0x0x7ff86eae6540) + QObject (0x0x7ff86b536780) 0 + primary-for QGraphicsObject (0x0x7ff86eae65b0) + QGraphicsItem (0x0x7ff86b5600c0) 16 + vptr=((& QGraphicsWidget::_ZTV15QGraphicsWidget) + 376u) + QGraphicsLayoutItem (0x0x7ff86b560120) 32 + vptr=((& QGraphicsWidget::_ZTV15QGraphicsWidget) + 688u) + +Class QGraphicsProxyWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsProxyWidget::QPrivateSignal (0x0x7ff86b5873c0) 0 empty + +Vtable for QGraphicsProxyWidget +QGraphicsProxyWidget::_ZTV20QGraphicsProxyWidget: 107u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QGraphicsProxyWidget) +16 (int (*)(...))QGraphicsProxyWidget::metaObject +24 (int (*)(...))QGraphicsProxyWidget::qt_metacast +32 (int (*)(...))QGraphicsProxyWidget::qt_metacall +40 (int (*)(...))QGraphicsProxyWidget::~QGraphicsProxyWidget +48 (int (*)(...))QGraphicsProxyWidget::~QGraphicsProxyWidget +56 (int (*)(...))QGraphicsProxyWidget::event +64 (int (*)(...))QGraphicsProxyWidget::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsProxyWidget::setGeometry +120 (int (*)(...))QGraphicsWidget::getContentsMargins +128 (int (*)(...))QGraphicsProxyWidget::type +136 (int (*)(...))QGraphicsProxyWidget::paint +144 (int (*)(...))QGraphicsWidget::paintWindowFrame +152 (int (*)(...))QGraphicsWidget::boundingRect +160 (int (*)(...))QGraphicsWidget::shape +168 (int (*)(...))QGraphicsWidget::initStyleOption +176 (int (*)(...))QGraphicsProxyWidget::sizeHint +184 (int (*)(...))QGraphicsWidget::updateGeometry +192 (int (*)(...))QGraphicsProxyWidget::itemChange +200 (int (*)(...))QGraphicsWidget::propertyChange +208 (int (*)(...))QGraphicsWidget::sceneEvent +216 (int (*)(...))QGraphicsWidget::windowFrameEvent +224 (int (*)(...))QGraphicsWidget::windowFrameSectionAt +232 (int (*)(...))QGraphicsWidget::changeEvent +240 (int (*)(...))QGraphicsWidget::closeEvent +248 (int (*)(...))QGraphicsProxyWidget::focusInEvent +256 (int (*)(...))QGraphicsProxyWidget::focusNextPrevChild +264 (int (*)(...))QGraphicsProxyWidget::focusOutEvent +272 (int (*)(...))QGraphicsProxyWidget::hideEvent +280 (int (*)(...))QGraphicsWidget::moveEvent +288 (int (*)(...))QGraphicsWidget::polishEvent +296 (int (*)(...))QGraphicsProxyWidget::resizeEvent +304 (int (*)(...))QGraphicsProxyWidget::showEvent +312 (int (*)(...))QGraphicsProxyWidget::hoverMoveEvent +320 (int (*)(...))QGraphicsProxyWidget::hoverLeaveEvent +328 (int (*)(...))QGraphicsProxyWidget::grabMouseEvent +336 (int (*)(...))QGraphicsProxyWidget::ungrabMouseEvent +344 (int (*)(...))QGraphicsWidget::grabKeyboardEvent +352 (int (*)(...))QGraphicsWidget::ungrabKeyboardEvent +360 (int (*)(...))QGraphicsProxyWidget::contextMenuEvent +368 (int (*)(...))QGraphicsProxyWidget::dragEnterEvent +376 (int (*)(...))QGraphicsProxyWidget::dragLeaveEvent +384 (int (*)(...))QGraphicsProxyWidget::dragMoveEvent +392 (int (*)(...))QGraphicsProxyWidget::dropEvent +400 (int (*)(...))QGraphicsProxyWidget::hoverEnterEvent +408 (int (*)(...))QGraphicsProxyWidget::mouseMoveEvent +416 (int (*)(...))QGraphicsProxyWidget::mousePressEvent +424 (int (*)(...))QGraphicsProxyWidget::mouseReleaseEvent +432 (int (*)(...))QGraphicsProxyWidget::mouseDoubleClickEvent +440 (int (*)(...))QGraphicsProxyWidget::wheelEvent +448 (int (*)(...))QGraphicsProxyWidget::keyPressEvent +456 (int (*)(...))QGraphicsProxyWidget::keyReleaseEvent +464 (int (*)(...))QGraphicsProxyWidget::inputMethodQuery +472 (int (*)(...))QGraphicsProxyWidget::inputMethodEvent +480 (int (*)(...))-16 +488 (int (*)(...))(& _ZTI20QGraphicsProxyWidget) +496 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidgetD1Ev +504 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidgetD0Ev +512 (int (*)(...))QGraphicsItem::advance +520 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget12boundingRectEv +528 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget5shapeEv +536 (int (*)(...))QGraphicsItem::contains +544 (int (*)(...))QGraphicsItem::collidesWithItem +552 (int (*)(...))QGraphicsItem::collidesWithPath +560 (int (*)(...))QGraphicsItem::isObscuredBy +568 (int (*)(...))QGraphicsItem::opaqueArea +576 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget5paintEP8QPainterPK24QStyleOptionGraphicsItemP7QWidget +584 (int (*)(...))QGraphicsProxyWidget::_ZThn16_NK20QGraphicsProxyWidget4typeEv +592 (int (*)(...))QGraphicsItem::sceneEventFilter +600 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget10sceneEventEP6QEvent +608 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget16contextMenuEventEP30QGraphicsSceneContextMenuEvent +616 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget14dragEnterEventEP27QGraphicsSceneDragDropEvent +624 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget14dragLeaveEventEP27QGraphicsSceneDragDropEvent +632 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget13dragMoveEventEP27QGraphicsSceneDragDropEvent +640 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget9dropEventEP27QGraphicsSceneDragDropEvent +648 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget12focusInEventEP11QFocusEvent +656 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget13focusOutEventEP11QFocusEvent +664 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget15hoverEnterEventEP24QGraphicsSceneHoverEvent +672 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget14hoverMoveEventEP24QGraphicsSceneHoverEvent +680 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget15hoverLeaveEventEP24QGraphicsSceneHoverEvent +688 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget13keyPressEventEP9QKeyEvent +696 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget15keyReleaseEventEP9QKeyEvent +704 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget15mousePressEventEP24QGraphicsSceneMouseEvent +712 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget14mouseMoveEventEP24QGraphicsSceneMouseEvent +720 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget17mouseReleaseEventEP24QGraphicsSceneMouseEvent +728 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget21mouseDoubleClickEventEP24QGraphicsSceneMouseEvent +736 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget10wheelEventEP24QGraphicsSceneWheelEvent +744 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget16inputMethodEventEP17QInputMethodEvent +752 (int (*)(...))QGraphicsProxyWidget::_ZThn16_NK20QGraphicsProxyWidget16inputMethodQueryEN2Qt16InputMethodQueryE +760 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget10itemChangeEN13QGraphicsItem18GraphicsItemChangeERK8QVariant +768 (int (*)(...))QGraphicsItem::supportsExtension +776 (int (*)(...))QGraphicsItem::setExtension +784 (int (*)(...))QGraphicsItem::extension +792 (int (*)(...))-32 +800 (int (*)(...))(& _ZTI20QGraphicsProxyWidget) +808 (int (*)(...))QGraphicsProxyWidget::_ZThn32_N20QGraphicsProxyWidgetD1Ev +816 (int (*)(...))QGraphicsProxyWidget::_ZThn32_N20QGraphicsProxyWidgetD0Ev +824 (int (*)(...))QGraphicsProxyWidget::_ZThn32_N20QGraphicsProxyWidget11setGeometryERK6QRectF +832 (int (*)(...))QGraphicsWidget::_ZThn32_NK15QGraphicsWidget18getContentsMarginsEPdS0_S0_S0_ +840 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidget14updateGeometryEv +848 (int (*)(...))QGraphicsProxyWidget::_ZThn32_NK20QGraphicsProxyWidget8sizeHintEN2Qt8SizeHintERK6QSizeF + +Class QGraphicsProxyWidget + size=48 align=8 + base size=48 base align=8 +QGraphicsProxyWidget (0x0x7ff86bb04bc8) 0 + vptr=((& QGraphicsProxyWidget::_ZTV20QGraphicsProxyWidget) + 16u) + QGraphicsWidget (0x0x7ff86eae6bd0) 0 + primary-for QGraphicsProxyWidget (0x0x7ff86bb04bc8) + QGraphicsObject (0x0x7ff86eae6c40) 0 + primary-for QGraphicsWidget (0x0x7ff86eae6bd0) + QObject (0x0x7ff86b560a80) 0 + primary-for QGraphicsObject (0x0x7ff86eae6c40) + QGraphicsItem (0x0x7ff86b5872a0) 16 + vptr=((& QGraphicsProxyWidget::_ZTV20QGraphicsProxyWidget) + 496u) + QGraphicsLayoutItem (0x0x7ff86b587300) 32 + vptr=((& QGraphicsProxyWidget::_ZTV20QGraphicsProxyWidget) + 808u) + +Class QGraphicsScene::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsScene::QPrivateSignal (0x0x7ff86ad56f60) 0 empty + +Vtable for QGraphicsScene +QGraphicsScene::_ZTV14QGraphicsScene: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QGraphicsScene) +16 (int (*)(...))QGraphicsScene::metaObject +24 (int (*)(...))QGraphicsScene::qt_metacast +32 (int (*)(...))QGraphicsScene::qt_metacall +40 (int (*)(...))QGraphicsScene::~QGraphicsScene +48 (int (*)(...))QGraphicsScene::~QGraphicsScene +56 (int (*)(...))QGraphicsScene::event +64 (int (*)(...))QGraphicsScene::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsScene::inputMethodQuery +120 (int (*)(...))QGraphicsScene::contextMenuEvent +128 (int (*)(...))QGraphicsScene::dragEnterEvent +136 (int (*)(...))QGraphicsScene::dragMoveEvent +144 (int (*)(...))QGraphicsScene::dragLeaveEvent +152 (int (*)(...))QGraphicsScene::dropEvent +160 (int (*)(...))QGraphicsScene::focusInEvent +168 (int (*)(...))QGraphicsScene::focusOutEvent +176 (int (*)(...))QGraphicsScene::helpEvent +184 (int (*)(...))QGraphicsScene::keyPressEvent +192 (int (*)(...))QGraphicsScene::keyReleaseEvent +200 (int (*)(...))QGraphicsScene::mousePressEvent +208 (int (*)(...))QGraphicsScene::mouseMoveEvent +216 (int (*)(...))QGraphicsScene::mouseReleaseEvent +224 (int (*)(...))QGraphicsScene::mouseDoubleClickEvent +232 (int (*)(...))QGraphicsScene::wheelEvent +240 (int (*)(...))QGraphicsScene::inputMethodEvent +248 (int (*)(...))QGraphicsScene::drawBackground +256 (int (*)(...))QGraphicsScene::drawForeground +264 (int (*)(...))QGraphicsScene::drawItems + +Class QGraphicsScene + size=16 align=8 + base size=16 base align=8 +QGraphicsScene (0x0x7ff86bb04dd0) 0 + vptr=((& QGraphicsScene::_ZTV14QGraphicsScene) + 16u) + QObject (0x0x7ff86ad56b40) 0 + primary-for QGraphicsScene (0x0x7ff86bb04dd0) + +Vtable for QGraphicsSceneEvent +QGraphicsSceneEvent::_ZTV19QGraphicsSceneEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QGraphicsSceneEvent) +16 (int (*)(...))QGraphicsSceneEvent::~QGraphicsSceneEvent +24 (int (*)(...))QGraphicsSceneEvent::~QGraphicsSceneEvent + +Class QGraphicsSceneEvent + size=32 align=8 + base size=32 base align=8 +QGraphicsSceneEvent (0x0x7ff86bb7f5b0) 0 + vptr=((& QGraphicsSceneEvent::_ZTV19QGraphicsSceneEvent) + 16u) + QEvent (0x0x7ff86aae3300) 0 + primary-for QGraphicsSceneEvent (0x0x7ff86bb7f5b0) + +Vtable for QGraphicsSceneMouseEvent +QGraphicsSceneMouseEvent::_ZTV24QGraphicsSceneMouseEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QGraphicsSceneMouseEvent) +16 (int (*)(...))QGraphicsSceneMouseEvent::~QGraphicsSceneMouseEvent +24 (int (*)(...))QGraphicsSceneMouseEvent::~QGraphicsSceneMouseEvent + +Class QGraphicsSceneMouseEvent + size=32 align=8 + base size=32 base align=8 +QGraphicsSceneMouseEvent (0x0x7ff86bb7f680) 0 + vptr=((& QGraphicsSceneMouseEvent::_ZTV24QGraphicsSceneMouseEvent) + 16u) + QGraphicsSceneEvent (0x0x7ff86bb7f6e8) 0 + primary-for QGraphicsSceneMouseEvent (0x0x7ff86bb7f680) + QEvent (0x0x7ff86aae3f60) 0 + primary-for QGraphicsSceneEvent (0x0x7ff86bb7f6e8) + +Vtable for QGraphicsSceneWheelEvent +QGraphicsSceneWheelEvent::_ZTV24QGraphicsSceneWheelEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QGraphicsSceneWheelEvent) +16 (int (*)(...))QGraphicsSceneWheelEvent::~QGraphicsSceneWheelEvent +24 (int (*)(...))QGraphicsSceneWheelEvent::~QGraphicsSceneWheelEvent + +Class QGraphicsSceneWheelEvent + size=32 align=8 + base size=32 base align=8 +QGraphicsSceneWheelEvent (0x0x7ff86bb7f750) 0 + vptr=((& QGraphicsSceneWheelEvent::_ZTV24QGraphicsSceneWheelEvent) + 16u) + QGraphicsSceneEvent (0x0x7ff86bb7f7b8) 0 + primary-for QGraphicsSceneWheelEvent (0x0x7ff86bb7f750) + QEvent (0x0x7ff86ab081e0) 0 + primary-for QGraphicsSceneEvent (0x0x7ff86bb7f7b8) + +Vtable for QGraphicsSceneContextMenuEvent +QGraphicsSceneContextMenuEvent::_ZTV30QGraphicsSceneContextMenuEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI30QGraphicsSceneContextMenuEvent) +16 (int (*)(...))QGraphicsSceneContextMenuEvent::~QGraphicsSceneContextMenuEvent +24 (int (*)(...))QGraphicsSceneContextMenuEvent::~QGraphicsSceneContextMenuEvent + +Class QGraphicsSceneContextMenuEvent + size=32 align=8 + base size=32 base align=8 +QGraphicsSceneContextMenuEvent (0x0x7ff86bb7f820) 0 + vptr=((& QGraphicsSceneContextMenuEvent::_ZTV30QGraphicsSceneContextMenuEvent) + 16u) + QGraphicsSceneEvent (0x0x7ff86bb7f888) 0 + primary-for QGraphicsSceneContextMenuEvent (0x0x7ff86bb7f820) + QEvent (0x0x7ff86ab08240) 0 + primary-for QGraphicsSceneEvent (0x0x7ff86bb7f888) + +Vtable for QGraphicsSceneHoverEvent +QGraphicsSceneHoverEvent::_ZTV24QGraphicsSceneHoverEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QGraphicsSceneHoverEvent) +16 (int (*)(...))QGraphicsSceneHoverEvent::~QGraphicsSceneHoverEvent +24 (int (*)(...))QGraphicsSceneHoverEvent::~QGraphicsSceneHoverEvent + +Class QGraphicsSceneHoverEvent + size=32 align=8 + base size=32 base align=8 +QGraphicsSceneHoverEvent (0x0x7ff86bb7f8f0) 0 + vptr=((& QGraphicsSceneHoverEvent::_ZTV24QGraphicsSceneHoverEvent) + 16u) + QGraphicsSceneEvent (0x0x7ff86bb7f958) 0 + primary-for QGraphicsSceneHoverEvent (0x0x7ff86bb7f8f0) + QEvent (0x0x7ff86a3c0480) 0 + primary-for QGraphicsSceneEvent (0x0x7ff86bb7f958) + +Vtable for QGraphicsSceneHelpEvent +QGraphicsSceneHelpEvent::_ZTV23QGraphicsSceneHelpEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGraphicsSceneHelpEvent) +16 (int (*)(...))QGraphicsSceneHelpEvent::~QGraphicsSceneHelpEvent +24 (int (*)(...))QGraphicsSceneHelpEvent::~QGraphicsSceneHelpEvent + +Class QGraphicsSceneHelpEvent + size=32 align=8 + base size=32 base align=8 +QGraphicsSceneHelpEvent (0x0x7ff86bb7f9c0) 0 + vptr=((& QGraphicsSceneHelpEvent::_ZTV23QGraphicsSceneHelpEvent) + 16u) + QGraphicsSceneEvent (0x0x7ff86b92eaf8) 0 + primary-for QGraphicsSceneHelpEvent (0x0x7ff86bb7f9c0) + QEvent (0x0x7ff86a3c04e0) 0 + primary-for QGraphicsSceneEvent (0x0x7ff86b92eaf8) + +Vtable for QGraphicsSceneDragDropEvent +QGraphicsSceneDragDropEvent::_ZTV27QGraphicsSceneDragDropEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QGraphicsSceneDragDropEvent) +16 (int (*)(...))QGraphicsSceneDragDropEvent::~QGraphicsSceneDragDropEvent +24 (int (*)(...))QGraphicsSceneDragDropEvent::~QGraphicsSceneDragDropEvent + +Class QGraphicsSceneDragDropEvent + size=32 align=8 + base size=32 base align=8 +QGraphicsSceneDragDropEvent (0x0x7ff86b92ebc8) 0 + vptr=((& QGraphicsSceneDragDropEvent::_ZTV27QGraphicsSceneDragDropEvent) + 16u) + QGraphicsSceneEvent (0x0x7ff86b6a2680) 0 + primary-for QGraphicsSceneDragDropEvent (0x0x7ff86b92ebc8) + QEvent (0x0x7ff86a3c0900) 0 + primary-for QGraphicsSceneEvent (0x0x7ff86b6a2680) + +Vtable for QGraphicsSceneResizeEvent +QGraphicsSceneResizeEvent::_ZTV25QGraphicsSceneResizeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QGraphicsSceneResizeEvent) +16 (int (*)(...))QGraphicsSceneResizeEvent::~QGraphicsSceneResizeEvent +24 (int (*)(...))QGraphicsSceneResizeEvent::~QGraphicsSceneResizeEvent + +Class QGraphicsSceneResizeEvent + size=32 align=8 + base size=32 base align=8 +QGraphicsSceneResizeEvent (0x0x7ff86b6a26e8) 0 + vptr=((& QGraphicsSceneResizeEvent::_ZTV25QGraphicsSceneResizeEvent) + 16u) + QGraphicsSceneEvent (0x0x7ff86b6a2750) 0 + primary-for QGraphicsSceneResizeEvent (0x0x7ff86b6a26e8) + QEvent (0x0x7ff86a3c0960) 0 + primary-for QGraphicsSceneEvent (0x0x7ff86b6a2750) + +Vtable for QGraphicsSceneMoveEvent +QGraphicsSceneMoveEvent::_ZTV23QGraphicsSceneMoveEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGraphicsSceneMoveEvent) +16 (int (*)(...))QGraphicsSceneMoveEvent::~QGraphicsSceneMoveEvent +24 (int (*)(...))QGraphicsSceneMoveEvent::~QGraphicsSceneMoveEvent + +Class QGraphicsSceneMoveEvent + size=32 align=8 + base size=32 base align=8 +QGraphicsSceneMoveEvent (0x0x7ff86b6a28f0) 0 + vptr=((& QGraphicsSceneMoveEvent::_ZTV23QGraphicsSceneMoveEvent) + 16u) + QGraphicsSceneEvent (0x0x7ff86b6a2958) 0 + primary-for QGraphicsSceneMoveEvent (0x0x7ff86b6a28f0) + QEvent (0x0x7ff86a4060c0) 0 + primary-for QGraphicsSceneEvent (0x0x7ff86b6a2958) + +Class QGraphicsTransform::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsTransform::QPrivateSignal (0x0x7ff86a406960) 0 empty + +Vtable for QGraphicsTransform +QGraphicsTransform::_ZTV18QGraphicsTransform: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QGraphicsTransform) +16 (int (*)(...))QGraphicsTransform::metaObject +24 (int (*)(...))QGraphicsTransform::qt_metacast +32 (int (*)(...))QGraphicsTransform::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QGraphicsTransform + size=16 align=8 + base size=16 base align=8 +QGraphicsTransform (0x0x7ff86b6a29c0) 0 + vptr=((& QGraphicsTransform::_ZTV18QGraphicsTransform) + 16u) + QObject (0x0x7ff86a406120) 0 + primary-for QGraphicsTransform (0x0x7ff86b6a29c0) + +Class QGraphicsScale::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsScale::QPrivateSignal (0x0x7ff86a406ae0) 0 empty + +Vtable for QGraphicsScale +QGraphicsScale::_ZTV14QGraphicsScale: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QGraphicsScale) +16 (int (*)(...))QGraphicsScale::metaObject +24 (int (*)(...))QGraphicsScale::qt_metacast +32 (int (*)(...))QGraphicsScale::qt_metacall +40 (int (*)(...))QGraphicsScale::~QGraphicsScale +48 (int (*)(...))QGraphicsScale::~QGraphicsScale +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsScale::applyTo + +Class QGraphicsScale + size=16 align=8 + base size=16 base align=8 +QGraphicsScale (0x0x7ff86b6a2a28) 0 + vptr=((& QGraphicsScale::_ZTV14QGraphicsScale) + 16u) + QGraphicsTransform (0x0x7ff86b6a2a90) 0 + primary-for QGraphicsScale (0x0x7ff86b6a2a28) + QObject (0x0x7ff86a4069c0) 0 + primary-for QGraphicsTransform (0x0x7ff86b6a2a90) + +Class QGraphicsRotation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsRotation::QPrivateSignal (0x0x7ff86a406c00) 0 empty + +Vtable for QGraphicsRotation +QGraphicsRotation::_ZTV17QGraphicsRotation: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QGraphicsRotation) +16 (int (*)(...))QGraphicsRotation::metaObject +24 (int (*)(...))QGraphicsRotation::qt_metacast +32 (int (*)(...))QGraphicsRotation::qt_metacall +40 (int (*)(...))QGraphicsRotation::~QGraphicsRotation +48 (int (*)(...))QGraphicsRotation::~QGraphicsRotation +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsRotation::applyTo + +Class QGraphicsRotation + size=16 align=8 + base size=16 base align=8 +QGraphicsRotation (0x0x7ff86b6a2d00) 0 + vptr=((& QGraphicsRotation::_ZTV17QGraphicsRotation) + 16u) + QGraphicsTransform (0x0x7ff86b6a2d68) 0 + primary-for QGraphicsRotation (0x0x7ff86b6a2d00) + QObject (0x0x7ff86a406b40) 0 + primary-for QGraphicsTransform (0x0x7ff86b6a2d68) + +Class QScrollArea::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QScrollArea::QPrivateSignal (0x0x7ff86a4331e0) 0 empty + +Vtable for QScrollArea +QScrollArea::_ZTV11QScrollArea: 68u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QScrollArea) +16 (int (*)(...))QScrollArea::metaObject +24 (int (*)(...))QScrollArea::qt_metacast +32 (int (*)(...))QScrollArea::qt_metacall +40 (int (*)(...))QScrollArea::~QScrollArea +48 (int (*)(...))QScrollArea::~QScrollArea +56 (int (*)(...))QScrollArea::event +64 (int (*)(...))QScrollArea::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractScrollArea::mousePressEvent +176 (int (*)(...))QAbstractScrollArea::mouseReleaseEvent +184 (int (*)(...))QAbstractScrollArea::mouseDoubleClickEvent +192 (int (*)(...))QAbstractScrollArea::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractScrollArea::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractScrollArea::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QScrollArea::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractScrollArea::dragEnterEvent +320 (int (*)(...))QAbstractScrollArea::dragMoveEvent +328 (int (*)(...))QAbstractScrollArea::dragLeaveEvent +336 (int (*)(...))QAbstractScrollArea::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QScrollArea::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractScrollArea::viewportEvent +448 (int (*)(...))QScrollArea::scrollContentsBy +456 (int (*)(...))QScrollArea::viewportSizeHint +464 (int (*)(...))-16 +472 (int (*)(...))(& _ZTI11QScrollArea) +480 (int (*)(...))QScrollArea::_ZThn16_N11QScrollAreaD1Ev +488 (int (*)(...))QScrollArea::_ZThn16_N11QScrollAreaD0Ev +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QScrollArea + size=48 align=8 + base size=48 base align=8 +QScrollArea (0x0x7ff86b6a2dd0) 0 + vptr=((& QScrollArea::_ZTV11QScrollArea) + 16u) + QAbstractScrollArea (0x0x7ff86b6a2f70) 0 + primary-for QScrollArea (0x0x7ff86b6a2dd0) + QFrame (0x0x7ff86b7eb068) 0 + primary-for QAbstractScrollArea (0x0x7ff86b6a2f70) + QWidget (0x0x7ff86eb58af0) 0 + primary-for QFrame (0x0x7ff86b7eb068) + QObject (0x0x7ff86a4330c0) 0 + primary-for QWidget (0x0x7ff86eb58af0) + QPaintDevice (0x0x7ff86a433120) 16 + vptr=((& QScrollArea::_ZTV11QScrollArea) + 480u) + +Class QGraphicsView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsView::QPrivateSignal (0x0x7ff86a433360) 0 empty + +Vtable for QGraphicsView +QGraphicsView::_ZTV13QGraphicsView: 71u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QGraphicsView) +16 (int (*)(...))QGraphicsView::metaObject +24 (int (*)(...))QGraphicsView::qt_metacast +32 (int (*)(...))QGraphicsView::qt_metacall +40 (int (*)(...))QGraphicsView::~QGraphicsView +48 (int (*)(...))QGraphicsView::~QGraphicsView +56 (int (*)(...))QGraphicsView::event +64 (int (*)(...))QAbstractScrollArea::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QGraphicsView::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QGraphicsView::mousePressEvent +176 (int (*)(...))QGraphicsView::mouseReleaseEvent +184 (int (*)(...))QGraphicsView::mouseDoubleClickEvent +192 (int (*)(...))QGraphicsView::mouseMoveEvent +200 (int (*)(...))QGraphicsView::wheelEvent +208 (int (*)(...))QGraphicsView::keyPressEvent +216 (int (*)(...))QGraphicsView::keyReleaseEvent +224 (int (*)(...))QGraphicsView::focusInEvent +232 (int (*)(...))QGraphicsView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QGraphicsView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QGraphicsView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QGraphicsView::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QGraphicsView::dragEnterEvent +320 (int (*)(...))QGraphicsView::dragMoveEvent +328 (int (*)(...))QGraphicsView::dragLeaveEvent +336 (int (*)(...))QGraphicsView::dropEvent +344 (int (*)(...))QGraphicsView::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QGraphicsView::inputMethodEvent +416 (int (*)(...))QGraphicsView::inputMethodQuery +424 (int (*)(...))QGraphicsView::focusNextPrevChild +432 (int (*)(...))QGraphicsView::setupViewport +440 (int (*)(...))QGraphicsView::viewportEvent +448 (int (*)(...))QGraphicsView::scrollContentsBy +456 (int (*)(...))QAbstractScrollArea::viewportSizeHint +464 (int (*)(...))QGraphicsView::drawBackground +472 (int (*)(...))QGraphicsView::drawForeground +480 (int (*)(...))QGraphicsView::drawItems +488 (int (*)(...))-16 +496 (int (*)(...))(& _ZTI13QGraphicsView) +504 (int (*)(...))QGraphicsView::_ZThn16_N13QGraphicsViewD1Ev +512 (int (*)(...))QGraphicsView::_ZThn16_N13QGraphicsViewD0Ev +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QGraphicsView + size=48 align=8 + base size=48 base align=8 +QGraphicsView (0x0x7ff86b7eb138) 0 + vptr=((& QGraphicsView::_ZTV13QGraphicsView) + 16u) + QAbstractScrollArea (0x0x7ff86b48b3a8) 0 + primary-for QGraphicsView (0x0x7ff86b7eb138) + QFrame (0x0x7ff86b48b0d0) 0 + primary-for QAbstractScrollArea (0x0x7ff86b48b3a8) + QWidget (0x0x7ff86eb58e00) 0 + primary-for QFrame (0x0x7ff86b48b0d0) + QObject (0x0x7ff86a433240) 0 + primary-for QWidget (0x0x7ff86eb58e00) + QPaintDevice (0x0x7ff86a433300) 16 + vptr=((& QGraphicsView::_ZTV13QGraphicsView) + 504u) + +Class QGroupBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGroupBox::QPrivateSignal (0x0x7ff86a132b40) 0 empty + +Vtable for QGroupBox +QGroupBox::_ZTV9QGroupBox: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QGroupBox) +16 (int (*)(...))QGroupBox::metaObject +24 (int (*)(...))QGroupBox::qt_metacast +32 (int (*)(...))QGroupBox::qt_metacall +40 (int (*)(...))QGroupBox::~QGroupBox +48 (int (*)(...))QGroupBox::~QGroupBox +56 (int (*)(...))QGroupBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QGroupBox::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QGroupBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QGroupBox::mousePressEvent +176 (int (*)(...))QGroupBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QGroupBox::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QGroupBox::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QGroupBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QGroupBox::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QGroupBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI9QGroupBox) +448 (int (*)(...))QGroupBox::_ZThn16_N9QGroupBoxD1Ev +456 (int (*)(...))QGroupBox::_ZThn16_N9QGroupBoxD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QGroupBox + size=48 align=8 + base size=48 base align=8 +QGroupBox (0x0x7ff86b53c208) 0 + vptr=((& QGroupBox::_ZTV9QGroupBox) + 16u) + QWidget (0x0x7ff86ec56700) 0 + primary-for QGroupBox (0x0x7ff86b53c208) + QObject (0x0x7ff86a1329c0) 0 + primary-for QWidget (0x0x7ff86ec56700) + QPaintDevice (0x0x7ff86a132ae0) 16 + vptr=((& QGroupBox::_ZTV9QGroupBox) + 448u) + +Class QHeaderView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHeaderView::QPrivateSignal (0x0x7ff869ada1e0) 0 empty + +Vtable for QHeaderView +QHeaderView::_ZTV11QHeaderView: 108u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QHeaderView) +16 (int (*)(...))QHeaderView::metaObject +24 (int (*)(...))QHeaderView::qt_metacast +32 (int (*)(...))QHeaderView::qt_metacall +40 (int (*)(...))QHeaderView::~QHeaderView +48 (int (*)(...))QHeaderView::~QHeaderView +56 (int (*)(...))QHeaderView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QAbstractItemView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QHeaderView::setVisible +128 (int (*)(...))QHeaderView::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QHeaderView::mousePressEvent +176 (int (*)(...))QHeaderView::mouseReleaseEvent +184 (int (*)(...))QHeaderView::mouseDoubleClickEvent +192 (int (*)(...))QHeaderView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QHeaderView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractItemView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QAbstractItemView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QAbstractItemView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QHeaderView::viewportEvent +448 (int (*)(...))QHeaderView::scrollContentsBy +456 (int (*)(...))QAbstractItemView::viewportSizeHint +464 (int (*)(...))QHeaderView::setModel +472 (int (*)(...))QAbstractItemView::setSelectionModel +480 (int (*)(...))QAbstractItemView::keyboardSearch +488 (int (*)(...))QHeaderView::visualRect +496 (int (*)(...))QHeaderView::scrollTo +504 (int (*)(...))QHeaderView::indexAt +512 (int (*)(...))QAbstractItemView::sizeHintForRow +520 (int (*)(...))QAbstractItemView::sizeHintForColumn +528 (int (*)(...))QHeaderView::reset +536 (int (*)(...))QAbstractItemView::setRootIndex +544 (int (*)(...))QHeaderView::doItemsLayout +552 (int (*)(...))QAbstractItemView::selectAll +560 (int (*)(...))QHeaderView::dataChanged +568 (int (*)(...))QHeaderView::rowsInserted +576 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved +584 (int (*)(...))QAbstractItemView::selectionChanged +592 (int (*)(...))QHeaderView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QHeaderView::updateGeometries +624 (int (*)(...))QAbstractItemView::verticalScrollbarAction +632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction +640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))QHeaderView::moveCursor +688 (int (*)(...))QHeaderView::horizontalOffset +696 (int (*)(...))QHeaderView::verticalOffset +704 (int (*)(...))QHeaderView::isIndexHidden +712 (int (*)(...))QHeaderView::setSelection +720 (int (*)(...))QHeaderView::visualRegionForSelection +728 (int (*)(...))QAbstractItemView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QAbstractItemView::startDrag +760 (int (*)(...))QAbstractItemView::viewOptions +768 (int (*)(...))QHeaderView::paintSection +776 (int (*)(...))QHeaderView::sectionSizeFromContents +784 (int (*)(...))-16 +792 (int (*)(...))(& _ZTI11QHeaderView) +800 (int (*)(...))QHeaderView::_ZThn16_N11QHeaderViewD1Ev +808 (int (*)(...))QHeaderView::_ZThn16_N11QHeaderViewD0Ev +816 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +848 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +856 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QHeaderView + size=48 align=8 + base size=48 base align=8 +QHeaderView (0x0x7ff86b53c270) 0 + vptr=((& QHeaderView::_ZTV11QHeaderView) + 16u) + QAbstractItemView (0x0x7ff86b53cdd0) 0 + primary-for QHeaderView (0x0x7ff86b53c270) + QAbstractScrollArea (0x0x7ff86b53ce38) 0 + primary-for QAbstractItemView (0x0x7ff86b53cdd0) + QFrame (0x0x7ff86b559000) 0 + primary-for QAbstractScrollArea (0x0x7ff86b53ce38) + QWidget (0x0x7ff86ec56c40) 0 + primary-for QFrame (0x0x7ff86b559000) + QObject (0x0x7ff869e52660) 0 + primary-for QWidget (0x0x7ff86ec56c40) + QPaintDevice (0x0x7ff869e526c0) 16 + vptr=((& QHeaderView::_ZTV11QHeaderView) + 800u) + +Class QLineEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLineEdit::QPrivateSignal (0x0x7ff8698a1c60) 0 empty + +Vtable for QLineEdit +QLineEdit::_ZTV9QLineEdit: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QLineEdit) +16 (int (*)(...))QLineEdit::metaObject +24 (int (*)(...))QLineEdit::qt_metacast +32 (int (*)(...))QLineEdit::qt_metacall +40 (int (*)(...))QLineEdit::~QLineEdit +48 (int (*)(...))QLineEdit::~QLineEdit +56 (int (*)(...))QLineEdit::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QLineEdit::sizeHint +136 (int (*)(...))QLineEdit::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QLineEdit::mousePressEvent +176 (int (*)(...))QLineEdit::mouseReleaseEvent +184 (int (*)(...))QLineEdit::mouseDoubleClickEvent +192 (int (*)(...))QLineEdit::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QLineEdit::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QLineEdit::focusInEvent +232 (int (*)(...))QLineEdit::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QLineEdit::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QLineEdit::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QLineEdit::dragEnterEvent +320 (int (*)(...))QLineEdit::dragMoveEvent +328 (int (*)(...))QLineEdit::dragLeaveEvent +336 (int (*)(...))QLineEdit::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QLineEdit::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QLineEdit::inputMethodEvent +416 (int (*)(...))QLineEdit::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI9QLineEdit) +448 (int (*)(...))QLineEdit::_ZThn16_N9QLineEditD1Ev +456 (int (*)(...))QLineEdit::_ZThn16_N9QLineEditD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QLineEdit + size=48 align=8 + base size=48 base align=8 +QLineEdit (0x0x7ff86b140af8) 0 + vptr=((& QLineEdit::_ZTV9QLineEdit) + 16u) + QWidget (0x0x7ff86ec68a80) 0 + primary-for QLineEdit (0x0x7ff86b140af8) + QObject (0x0x7ff8698a1540) 0 + primary-for QWidget (0x0x7ff86ec68a80) + QPaintDevice (0x0x7ff8698a1c00) 16 + vptr=((& QLineEdit::_ZTV9QLineEdit) + 448u) + +Class QInputDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QInputDialog::QPrivateSignal (0x0x7ff8698caba0) 0 empty + +Vtable for QInputDialog +QInputDialog::_ZTV12QInputDialog: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QInputDialog) +16 (int (*)(...))QInputDialog::metaObject +24 (int (*)(...))QInputDialog::qt_metacast +32 (int (*)(...))QInputDialog::qt_metacall +40 (int (*)(...))QInputDialog::~QInputDialog +48 (int (*)(...))QInputDialog::~QInputDialog +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QInputDialog::setVisible +128 (int (*)(...))QInputDialog::sizeHint +136 (int (*)(...))QInputDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QInputDialog::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI12QInputDialog) +488 (int (*)(...))QInputDialog::_ZThn16_N12QInputDialogD1Ev +496 (int (*)(...))QInputDialog::_ZThn16_N12QInputDialogD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QInputDialog + size=48 align=8 + base size=48 base align=8 +QInputDialog (0x0x7ff86b140b60) 0 + vptr=((& QInputDialog::_ZTV12QInputDialog) + 16u) + QDialog (0x0x7ff86af033a8) 0 + primary-for QInputDialog (0x0x7ff86b140b60) + QWidget (0x0x7ff86ec74380) 0 + primary-for QDialog (0x0x7ff86af033a8) + QObject (0x0x7ff8698ca420) 0 + primary-for QWidget (0x0x7ff86ec74380) + QPaintDevice (0x0x7ff8698ca480) 16 + vptr=((& QInputDialog::_ZTV12QInputDialog) + 488u) + +Class QItemDelegate::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemDelegate::QPrivateSignal (0x0x7ff86968ba80) 0 empty + +Vtable for QItemDelegate +QItemDelegate::_ZTV13QItemDelegate: 28u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QItemDelegate) +16 (int (*)(...))QItemDelegate::metaObject +24 (int (*)(...))QItemDelegate::qt_metacast +32 (int (*)(...))QItemDelegate::qt_metacall +40 (int (*)(...))QItemDelegate::~QItemDelegate +48 (int (*)(...))QItemDelegate::~QItemDelegate +56 (int (*)(...))QObject::event +64 (int (*)(...))QItemDelegate::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemDelegate::paint +120 (int (*)(...))QItemDelegate::sizeHint +128 (int (*)(...))QItemDelegate::createEditor +136 (int (*)(...))QAbstractItemDelegate::destroyEditor +144 (int (*)(...))QItemDelegate::setEditorData +152 (int (*)(...))QItemDelegate::setModelData +160 (int (*)(...))QItemDelegate::updateEditorGeometry +168 (int (*)(...))QItemDelegate::editorEvent +176 (int (*)(...))QAbstractItemDelegate::helpEvent +184 (int (*)(...))QAbstractItemDelegate::paintingRoles +192 (int (*)(...))QItemDelegate::drawDisplay +200 (int (*)(...))QItemDelegate::drawDecoration +208 (int (*)(...))QItemDelegate::drawFocus +216 (int (*)(...))QItemDelegate::drawCheck + +Class QItemDelegate + size=16 align=8 + base size=16 base align=8 +QItemDelegate (0x0x7ff86aab2068) 0 + vptr=((& QItemDelegate::_ZTV13QItemDelegate) + 16u) + QAbstractItemDelegate (0x0x7ff86aab2af8) 0 + primary-for QItemDelegate (0x0x7ff86aab2068) + QObject (0x0x7ff86968b9c0) 0 + primary-for QAbstractItemDelegate (0x0x7ff86aab2af8) + +Vtable for QItemEditorCreatorBase +QItemEditorCreatorBase::_ZTV22QItemEditorCreatorBase: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QItemEditorCreatorBase) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QItemEditorCreatorBase + size=8 align=8 + base size=8 base align=8 +QItemEditorCreatorBase (0x0x7ff86968bba0) 0 nearly-empty + vptr=((& QItemEditorCreatorBase::_ZTV22QItemEditorCreatorBase) + 16u) + +Vtable for QItemEditorFactory +QItemEditorFactory::_ZTV18QItemEditorFactory: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QItemEditorFactory) +16 (int (*)(...))QItemEditorFactory::~QItemEditorFactory +24 (int (*)(...))QItemEditorFactory::~QItemEditorFactory +32 (int (*)(...))QItemEditorFactory::createEditor +40 (int (*)(...))QItemEditorFactory::valuePropertyName + +Class QItemEditorFactory + size=16 align=8 + base size=16 base align=8 +QItemEditorFactory (0x0x7ff86968bd20) 0 + vptr=((& QItemEditorFactory::_ZTV18QItemEditorFactory) + 16u) + +Class QKeyEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QKeyEventTransition::QPrivateSignal (0x0x7ff8696ab0c0) 0 empty + +Vtable for QKeyEventTransition +QKeyEventTransition::_ZTV19QKeyEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QKeyEventTransition) +16 (int (*)(...))QKeyEventTransition::metaObject +24 (int (*)(...))QKeyEventTransition::qt_metacast +32 (int (*)(...))QKeyEventTransition::qt_metacall +40 (int (*)(...))QKeyEventTransition::~QKeyEventTransition +48 (int (*)(...))QKeyEventTransition::~QKeyEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QKeyEventTransition::eventTest +120 (int (*)(...))QKeyEventTransition::onTransition + +Class QKeyEventTransition + size=16 align=8 + base size=16 base align=8 +QKeyEventTransition (0x0x7ff86aad67b8) 0 + vptr=((& QKeyEventTransition::_ZTV19QKeyEventTransition) + 16u) + QEventTransition (0x0x7ff86aad6b60) 0 + primary-for QKeyEventTransition (0x0x7ff86aad67b8) + QAbstractTransition (0x0x7ff86aad6bc8) 0 + primary-for QEventTransition (0x0x7ff86aad6b60) + QObject (0x0x7ff8696ab000) 0 + primary-for QAbstractTransition (0x0x7ff86aad6bc8) + +Class QKeySequenceEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QKeySequenceEdit::QPrivateSignal (0x0x7ff8692a6a80) 0 empty + +Vtable for QKeySequenceEdit +QKeySequenceEdit::_ZTV16QKeySequenceEdit: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QKeySequenceEdit) +16 (int (*)(...))QKeySequenceEdit::metaObject +24 (int (*)(...))QKeySequenceEdit::qt_metacast +32 (int (*)(...))QKeySequenceEdit::qt_metacall +40 (int (*)(...))QKeySequenceEdit::~QKeySequenceEdit +48 (int (*)(...))QKeySequenceEdit::~QKeySequenceEdit +56 (int (*)(...))QKeySequenceEdit::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QKeySequenceEdit::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QKeySequenceEdit::keyPressEvent +216 (int (*)(...))QKeySequenceEdit::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI16QKeySequenceEdit) +448 (int (*)(...))QKeySequenceEdit::_ZThn16_N16QKeySequenceEditD1Ev +456 (int (*)(...))QKeySequenceEdit::_ZThn16_N16QKeySequenceEditD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QKeySequenceEdit + size=48 align=8 + base size=48 base align=8 +QKeySequenceEdit (0x0x7ff86aaf1750) 0 + vptr=((& QKeySequenceEdit::_ZTV16QKeySequenceEdit) + 16u) + QWidget (0x0x7ff86eca7690) 0 + primary-for QKeySequenceEdit (0x0x7ff86aaf1750) + QObject (0x0x7ff8695ecf00) 0 + primary-for QWidget (0x0x7ff86eca7690) + QPaintDevice (0x0x7ff8695ecf60) 16 + vptr=((& QKeySequenceEdit::_ZTV16QKeySequenceEdit) + 448u) + +Class QLabel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLabel::QPrivateSignal (0x0x7ff8692cd720) 0 empty + +Vtable for QLabel +QLabel::_ZTV6QLabel: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QLabel) +16 (int (*)(...))QLabel::metaObject +24 (int (*)(...))QLabel::qt_metacast +32 (int (*)(...))QLabel::qt_metacall +40 (int (*)(...))QLabel::~QLabel +48 (int (*)(...))QLabel::~QLabel +56 (int (*)(...))QLabel::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QLabel::sizeHint +136 (int (*)(...))QLabel::minimumSizeHint +144 (int (*)(...))QLabel::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QLabel::mousePressEvent +176 (int (*)(...))QLabel::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QLabel::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QLabel::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QLabel::focusInEvent +232 (int (*)(...))QLabel::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QLabel::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QLabel::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QLabel::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QLabel::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI6QLabel) +448 (int (*)(...))QLabel::_ZThn16_N6QLabelD1Ev +456 (int (*)(...))QLabel::_ZThn16_N6QLabelD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QLabel + size=48 align=8 + base size=48 base align=8 +QLabel (0x0x7ff86aaf17b8) 0 + vptr=((& QLabel::_ZTV6QLabel) + 16u) + QFrame (0x0x7ff86ab13548) 0 + primary-for QLabel (0x0x7ff86aaf17b8) + QWidget (0x0x7ff86eca7af0) 0 + primary-for QFrame (0x0x7ff86ab13548) + QObject (0x0x7ff8692a6ae0) 0 + primary-for QWidget (0x0x7ff86eca7af0) + QPaintDevice (0x0x7ff8692cd6c0) 16 + vptr=((& QLabel::_ZTV6QLabel) + 448u) + +Class QLCDNumber::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLCDNumber::QPrivateSignal (0x0x7ff8690fcd80) 0 empty + +Vtable for QLCDNumber +QLCDNumber::_ZTV10QLCDNumber: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QLCDNumber) +16 (int (*)(...))QLCDNumber::metaObject +24 (int (*)(...))QLCDNumber::qt_metacast +32 (int (*)(...))QLCDNumber::qt_metacall +40 (int (*)(...))QLCDNumber::~QLCDNumber +48 (int (*)(...))QLCDNumber::~QLCDNumber +56 (int (*)(...))QLCDNumber::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QLCDNumber::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QLCDNumber::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI10QLCDNumber) +448 (int (*)(...))QLCDNumber::_ZThn16_N10QLCDNumberD1Ev +456 (int (*)(...))QLCDNumber::_ZThn16_N10QLCDNumberD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QLCDNumber + size=48 align=8 + base size=48 base align=8 +QLCDNumber (0x0x7ff86ab136e8) 0 + vptr=((& QLCDNumber::_ZTV10QLCDNumber) + 16u) + QFrame (0x0x7ff86ab13750) 0 + primary-for QLCDNumber (0x0x7ff86ab136e8) + QWidget (0x0x7ff86eca7ee0) 0 + primary-for QFrame (0x0x7ff86ab13750) + QObject (0x0x7ff8690fc900) 0 + primary-for QWidget (0x0x7ff86eca7ee0) + QPaintDevice (0x0x7ff8690fc960) 16 + vptr=((& QLCDNumber::_ZTV10QLCDNumber) + 448u) + +Class QListView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QListView::QPrivateSignal (0x0x7ff868e1b180) 0 empty + +Vtable for QListView +QListView::_ZTV9QListView: 106u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QListView) +16 (int (*)(...))QListView::metaObject +24 (int (*)(...))QListView::qt_metacast +32 (int (*)(...))QListView::qt_metacall +40 (int (*)(...))QListView::~QListView +48 (int (*)(...))QListView::~QListView +56 (int (*)(...))QListView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QListView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QListView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QListView::mouseMoveEvent +200 (int (*)(...))QListView::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QListView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QListView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QListView::dragMoveEvent +328 (int (*)(...))QListView::dragLeaveEvent +336 (int (*)(...))QListView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractItemView::viewportEvent +448 (int (*)(...))QListView::scrollContentsBy +456 (int (*)(...))QListView::viewportSizeHint +464 (int (*)(...))QAbstractItemView::setModel +472 (int (*)(...))QAbstractItemView::setSelectionModel +480 (int (*)(...))QAbstractItemView::keyboardSearch +488 (int (*)(...))QListView::visualRect +496 (int (*)(...))QListView::scrollTo +504 (int (*)(...))QListView::indexAt +512 (int (*)(...))QAbstractItemView::sizeHintForRow +520 (int (*)(...))QAbstractItemView::sizeHintForColumn +528 (int (*)(...))QListView::reset +536 (int (*)(...))QListView::setRootIndex +544 (int (*)(...))QListView::doItemsLayout +552 (int (*)(...))QAbstractItemView::selectAll +560 (int (*)(...))QListView::dataChanged +568 (int (*)(...))QListView::rowsInserted +576 (int (*)(...))QListView::rowsAboutToBeRemoved +584 (int (*)(...))QListView::selectionChanged +592 (int (*)(...))QListView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QListView::updateGeometries +624 (int (*)(...))QAbstractItemView::verticalScrollbarAction +632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction +640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))QListView::moveCursor +688 (int (*)(...))QListView::horizontalOffset +696 (int (*)(...))QListView::verticalOffset +704 (int (*)(...))QListView::isIndexHidden +712 (int (*)(...))QListView::setSelection +720 (int (*)(...))QListView::visualRegionForSelection +728 (int (*)(...))QListView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QListView::startDrag +760 (int (*)(...))QListView::viewOptions +768 (int (*)(...))-16 +776 (int (*)(...))(& _ZTI9QListView) +784 (int (*)(...))QListView::_ZThn16_N9QListViewD1Ev +792 (int (*)(...))QListView::_ZThn16_N9QListViewD0Ev +800 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +808 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +816 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QListView + size=48 align=8 + base size=48 base align=8 +QListView (0x0x7ff86ab137b8) 0 + vptr=((& QListView::_ZTV9QListView) + 16u) + QAbstractItemView (0x0x7ff86a79b7b8) 0 + primary-for QListView (0x0x7ff86ab137b8) + QAbstractScrollArea (0x0x7ff86a53a3a8) 0 + primary-for QAbstractItemView (0x0x7ff86a79b7b8) + QFrame (0x0x7ff86a53a548) 0 + primary-for QAbstractScrollArea (0x0x7ff86a53a3a8) + QWidget (0x0x7ff86e8d0770) 0 + primary-for QFrame (0x0x7ff86a53a548) + QObject (0x0x7ff8690fcde0) 0 + primary-for QWidget (0x0x7ff86e8d0770) + QPaintDevice (0x0x7ff868e1b120) 16 + vptr=((& QListView::_ZTV9QListView) + 784u) + +Vtable for QListWidgetItem +QListWidgetItem::_ZTV15QListWidgetItem: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QListWidgetItem) +16 (int (*)(...))QListWidgetItem::~QListWidgetItem +24 (int (*)(...))QListWidgetItem::~QListWidgetItem +32 (int (*)(...))QListWidgetItem::clone +40 (int (*)(...))QListWidgetItem::setBackgroundColor +48 (int (*)(...))QListWidgetItem::data +56 (int (*)(...))QListWidgetItem::setData +64 (int (*)(...))QListWidgetItem::operator< +72 (int (*)(...))QListWidgetItem::read +80 (int (*)(...))QListWidgetItem::write + +Class QListWidgetItem + size=48 align=8 + base size=44 base align=8 +QListWidgetItem (0x0x7ff868e1b300) 0 + vptr=((& QListWidgetItem::_ZTV15QListWidgetItem) + 16u) + +Class QListWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QListWidget::QPrivateSignal (0x0x7ff868e3f180) 0 empty + +Vtable for QListWidget +QListWidget::_ZTV11QListWidget: 110u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QListWidget) +16 (int (*)(...))QListWidget::metaObject +24 (int (*)(...))QListWidget::qt_metacast +32 (int (*)(...))QListWidget::qt_metacall +40 (int (*)(...))QListWidget::~QListWidget +48 (int (*)(...))QListWidget::~QListWidget +56 (int (*)(...))QListWidget::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QListView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QListView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QListView::mouseMoveEvent +200 (int (*)(...))QListView::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QListView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QListView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QListView::dragMoveEvent +328 (int (*)(...))QListView::dragLeaveEvent +336 (int (*)(...))QListWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractItemView::viewportEvent +448 (int (*)(...))QListView::scrollContentsBy +456 (int (*)(...))QListView::viewportSizeHint +464 (int (*)(...))QListWidget::setModel +472 (int (*)(...))QListWidget::setSelectionModel +480 (int (*)(...))QAbstractItemView::keyboardSearch +488 (int (*)(...))QListView::visualRect +496 (int (*)(...))QListView::scrollTo +504 (int (*)(...))QListView::indexAt +512 (int (*)(...))QAbstractItemView::sizeHintForRow +520 (int (*)(...))QAbstractItemView::sizeHintForColumn +528 (int (*)(...))QListView::reset +536 (int (*)(...))QListView::setRootIndex +544 (int (*)(...))QListView::doItemsLayout +552 (int (*)(...))QAbstractItemView::selectAll +560 (int (*)(...))QListView::dataChanged +568 (int (*)(...))QListView::rowsInserted +576 (int (*)(...))QListView::rowsAboutToBeRemoved +584 (int (*)(...))QListView::selectionChanged +592 (int (*)(...))QListView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QListView::updateGeometries +624 (int (*)(...))QAbstractItemView::verticalScrollbarAction +632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction +640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))QListView::moveCursor +688 (int (*)(...))QListView::horizontalOffset +696 (int (*)(...))QListView::verticalOffset +704 (int (*)(...))QListView::isIndexHidden +712 (int (*)(...))QListView::setSelection +720 (int (*)(...))QListView::visualRegionForSelection +728 (int (*)(...))QListView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QListView::startDrag +760 (int (*)(...))QListView::viewOptions +768 (int (*)(...))QListWidget::mimeTypes +776 (int (*)(...))QListWidget::mimeData +784 (int (*)(...))QListWidget::dropMimeData +792 (int (*)(...))QListWidget::supportedDropActions +800 (int (*)(...))-16 +808 (int (*)(...))(& _ZTI11QListWidget) +816 (int (*)(...))QListWidget::_ZThn16_N11QListWidgetD1Ev +824 (int (*)(...))QListWidget::_ZThn16_N11QListWidgetD0Ev +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +848 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +856 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +864 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +872 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QListWidget + size=48 align=8 + base size=48 base align=8 +QListWidget (0x0x7ff86a53a888) 0 + vptr=((& QListWidget::_ZTV11QListWidget) + 16u) + QListView (0x0x7ff86a366af8) 0 + primary-for QListWidget (0x0x7ff86a53a888) + QAbstractItemView (0x0x7ff86a366b60) 0 + primary-for QListView (0x0x7ff86a366af8) + QAbstractScrollArea (0x0x7ff86a3eb6e8) 0 + primary-for QAbstractItemView (0x0x7ff86a366b60) + QFrame (0x0x7ff86a42e478) 0 + primary-for QAbstractScrollArea (0x0x7ff86a3eb6e8) + QWidget (0x0x7ff86e98d380) 0 + primary-for QFrame (0x0x7ff86a42e478) + QObject (0x0x7ff868e1b540) 0 + primary-for QWidget (0x0x7ff86e98d380) + QPaintDevice (0x0x7ff868e3f120) 16 + vptr=((& QListWidget::_ZTV11QListWidget) + 816u) + +Class QMainWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMainWindow::QPrivateSignal (0x0x7ff868e64000) 0 empty + +Vtable for QMainWindow +QMainWindow::_ZTV11QMainWindow: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QMainWindow) +16 (int (*)(...))QMainWindow::metaObject +24 (int (*)(...))QMainWindow::qt_metacast +32 (int (*)(...))QMainWindow::qt_metacall +40 (int (*)(...))QMainWindow::~QMainWindow +48 (int (*)(...))QMainWindow::~QMainWindow +56 (int (*)(...))QMainWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QMainWindow::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QMainWindow::createPopupMenu +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI11QMainWindow) +456 (int (*)(...))QMainWindow::_ZThn16_N11QMainWindowD1Ev +464 (int (*)(...))QMainWindow::_ZThn16_N11QMainWindowD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QMainWindow + size=48 align=8 + base size=48 base align=8 +QMainWindow (0x0x7ff86a42e4e0) 0 + vptr=((& QMainWindow::_ZTV11QMainWindow) + 16u) + QWidget (0x0x7ff86e98dd20) 0 + primary-for QMainWindow (0x0x7ff86a42e4e0) + QObject (0x0x7ff868e3fd20) 0 + primary-for QWidget (0x0x7ff86e98dd20) + QPaintDevice (0x0x7ff868e3fd80) 16 + vptr=((& QMainWindow::_ZTV11QMainWindow) + 456u) + +Class QMdiArea::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMdiArea::QPrivateSignal (0x0x7ff868d01f00) 0 empty + +Vtable for QMdiArea +QMdiArea::_ZTV8QMdiArea: 68u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QMdiArea) +16 (int (*)(...))QMdiArea::metaObject +24 (int (*)(...))QMdiArea::qt_metacast +32 (int (*)(...))QMdiArea::qt_metacall +40 (int (*)(...))QMdiArea::~QMdiArea +48 (int (*)(...))QMdiArea::~QMdiArea +56 (int (*)(...))QMdiArea::event +64 (int (*)(...))QMdiArea::eventFilter +72 (int (*)(...))QMdiArea::timerEvent +80 (int (*)(...))QMdiArea::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QMdiArea::sizeHint +136 (int (*)(...))QMdiArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractScrollArea::mousePressEvent +176 (int (*)(...))QAbstractScrollArea::mouseReleaseEvent +184 (int (*)(...))QAbstractScrollArea::mouseDoubleClickEvent +192 (int (*)(...))QAbstractScrollArea::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractScrollArea::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QMdiArea::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QMdiArea::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractScrollArea::dragEnterEvent +320 (int (*)(...))QAbstractScrollArea::dragMoveEvent +328 (int (*)(...))QAbstractScrollArea::dragLeaveEvent +336 (int (*)(...))QAbstractScrollArea::dropEvent +344 (int (*)(...))QMdiArea::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QMdiArea::setupViewport +440 (int (*)(...))QMdiArea::viewportEvent +448 (int (*)(...))QMdiArea::scrollContentsBy +456 (int (*)(...))QAbstractScrollArea::viewportSizeHint +464 (int (*)(...))-16 +472 (int (*)(...))(& _ZTI8QMdiArea) +480 (int (*)(...))QMdiArea::_ZThn16_N8QMdiAreaD1Ev +488 (int (*)(...))QMdiArea::_ZThn16_N8QMdiAreaD0Ev +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QMdiArea + size=48 align=8 + base size=48 base align=8 +QMdiArea (0x0x7ff86a42e8f0) 0 + vptr=((& QMdiArea::_ZTV8QMdiArea) + 16u) + QAbstractScrollArea (0x0x7ff86a42ebc8) 0 + primary-for QMdiArea (0x0x7ff86a42e8f0) + QFrame (0x0x7ff86a070dd0) 0 + primary-for QAbstractScrollArea (0x0x7ff86a42ebc8) + QWidget (0x0x7ff86e9c7150) 0 + primary-for QFrame (0x0x7ff86a070dd0) + QObject (0x0x7ff868d01c60) 0 + primary-for QWidget (0x0x7ff86e9c7150) + QPaintDevice (0x0x7ff868d01d20) 16 + vptr=((& QMdiArea::_ZTV8QMdiArea) + 480u) + +Class QMdiSubWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMdiSubWindow::QPrivateSignal (0x0x7ff868d43de0) 0 empty + +Vtable for QMdiSubWindow +QMdiSubWindow::_ZTV13QMdiSubWindow: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QMdiSubWindow) +16 (int (*)(...))QMdiSubWindow::metaObject +24 (int (*)(...))QMdiSubWindow::qt_metacast +32 (int (*)(...))QMdiSubWindow::qt_metacall +40 (int (*)(...))QMdiSubWindow::~QMdiSubWindow +48 (int (*)(...))QMdiSubWindow::~QMdiSubWindow +56 (int (*)(...))QMdiSubWindow::event +64 (int (*)(...))QMdiSubWindow::eventFilter +72 (int (*)(...))QMdiSubWindow::timerEvent +80 (int (*)(...))QMdiSubWindow::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QMdiSubWindow::sizeHint +136 (int (*)(...))QMdiSubWindow::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QMdiSubWindow::mousePressEvent +176 (int (*)(...))QMdiSubWindow::mouseReleaseEvent +184 (int (*)(...))QMdiSubWindow::mouseDoubleClickEvent +192 (int (*)(...))QMdiSubWindow::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QMdiSubWindow::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QMdiSubWindow::focusInEvent +232 (int (*)(...))QMdiSubWindow::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QMdiSubWindow::leaveEvent +256 (int (*)(...))QMdiSubWindow::paintEvent +264 (int (*)(...))QMdiSubWindow::moveEvent +272 (int (*)(...))QMdiSubWindow::resizeEvent +280 (int (*)(...))QMdiSubWindow::closeEvent +288 (int (*)(...))QMdiSubWindow::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QMdiSubWindow::showEvent +352 (int (*)(...))QMdiSubWindow::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QMdiSubWindow::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI13QMdiSubWindow) +448 (int (*)(...))QMdiSubWindow::_ZThn16_N13QMdiSubWindowD1Ev +456 (int (*)(...))QMdiSubWindow::_ZThn16_N13QMdiSubWindowD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QMdiSubWindow + size=48 align=8 + base size=48 base align=8 +QMdiSubWindow (0x0x7ff86a11b680) 0 + vptr=((& QMdiSubWindow::_ZTV13QMdiSubWindow) + 16u) + QWidget (0x0x7ff86ea5f3f0) 0 + primary-for QMdiSubWindow (0x0x7ff86a11b680) + QObject (0x0x7ff868d43b40) 0 + primary-for QWidget (0x0x7ff86ea5f3f0) + QPaintDevice (0x0x7ff868d43d80) 16 + vptr=((& QMdiSubWindow::_ZTV13QMdiSubWindow) + 448u) + +Class QMenu::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMenu::QPrivateSignal (0x0x7ff868a919c0) 0 empty + +Vtable for QMenu +QMenu::_ZTV5QMenu: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QMenu) +16 (int (*)(...))QMenu::metaObject +24 (int (*)(...))QMenu::qt_metacast +32 (int (*)(...))QMenu::qt_metacall +40 (int (*)(...))QMenu::~QMenu +48 (int (*)(...))QMenu::~QMenu +56 (int (*)(...))QMenu::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QMenu::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QMenu::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QMenu::mousePressEvent +176 (int (*)(...))QMenu::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QMenu::mouseMoveEvent +200 (int (*)(...))QMenu::wheelEvent +208 (int (*)(...))QMenu::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QMenu::enterEvent +248 (int (*)(...))QMenu::leaveEvent +256 (int (*)(...))QMenu::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QMenu::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QMenu::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QMenu::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QMenu::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI5QMenu) +448 (int (*)(...))QMenu::_ZThn16_N5QMenuD1Ev +456 (int (*)(...))QMenu::_ZThn16_N5QMenuD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QMenu + size=48 align=8 + base size=48 base align=8 +QMenu (0x0x7ff86a11bd68) 0 + vptr=((& QMenu::_ZTV5QMenu) + 16u) + QWidget (0x0x7ff86ea6d380) 0 + primary-for QMenu (0x0x7ff86a11bd68) + QObject (0x0x7ff868a915a0) 0 + primary-for QWidget (0x0x7ff86ea6d380) + QPaintDevice (0x0x7ff868a91960) 16 + vptr=((& QMenu::_ZTV5QMenu) + 448u) + +Class QMenuBar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMenuBar::QPrivateSignal (0x0x7ff868ab75a0) 0 empty + +Vtable for QMenuBar +QMenuBar::_ZTV8QMenuBar: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QMenuBar) +16 (int (*)(...))QMenuBar::metaObject +24 (int (*)(...))QMenuBar::qt_metacast +32 (int (*)(...))QMenuBar::qt_metacall +40 (int (*)(...))QMenuBar::~QMenuBar +48 (int (*)(...))QMenuBar::~QMenuBar +56 (int (*)(...))QMenuBar::event +64 (int (*)(...))QMenuBar::eventFilter +72 (int (*)(...))QMenuBar::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QMenuBar::setVisible +128 (int (*)(...))QMenuBar::sizeHint +136 (int (*)(...))QMenuBar::minimumSizeHint +144 (int (*)(...))QMenuBar::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QMenuBar::mousePressEvent +176 (int (*)(...))QMenuBar::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QMenuBar::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QMenuBar::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QMenuBar::focusInEvent +232 (int (*)(...))QMenuBar::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QMenuBar::leaveEvent +256 (int (*)(...))QMenuBar::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QMenuBar::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QMenuBar::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QMenuBar::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI8QMenuBar) +448 (int (*)(...))QMenuBar::_ZThn16_N8QMenuBarD1Ev +456 (int (*)(...))QMenuBar::_ZThn16_N8QMenuBarD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QMenuBar + size=48 align=8 + base size=48 base align=8 +QMenuBar (0x0x7ff86a11bea0) 0 + vptr=((& QMenuBar::_ZTV8QMenuBar) + 16u) + QWidget (0x0x7ff86ea6dc40) 0 + primary-for QMenuBar (0x0x7ff86a11bea0) + QObject (0x0x7ff868a91f00) 0 + primary-for QWidget (0x0x7ff86ea6dc40) + QPaintDevice (0x0x7ff868a91f60) 16 + vptr=((& QMenuBar::_ZTV8QMenuBar) + 448u) + +Class QMessageBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMessageBox::QPrivateSignal (0x0x7ff868ab7ea0) 0 empty + +Vtable for QMessageBox +QMessageBox::_ZTV11QMessageBox: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QMessageBox) +16 (int (*)(...))QMessageBox::metaObject +24 (int (*)(...))QMessageBox::qt_metacast +32 (int (*)(...))QMessageBox::qt_metacall +40 (int (*)(...))QMessageBox::~QMessageBox +48 (int (*)(...))QMessageBox::~QMessageBox +56 (int (*)(...))QMessageBox::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QMessageBox::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QMessageBox::resizeEvent +280 (int (*)(...))QMessageBox::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QMessageBox::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QMessageBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QDialog::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI11QMessageBox) +488 (int (*)(...))QMessageBox::_ZThn16_N11QMessageBoxD1Ev +496 (int (*)(...))QMessageBox::_ZThn16_N11QMessageBoxD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QMessageBox + size=48 align=8 + base size=48 base align=8 +QMessageBox (0x0x7ff86a17c000) 0 + vptr=((& QMessageBox::_ZTV11QMessageBox) + 16u) + QDialog (0x0x7ff86a17c068) 0 + primary-for QMessageBox (0x0x7ff86a17c000) + QWidget (0x0x7ff86ea80690) 0 + primary-for QDialog (0x0x7ff86a17c068) + QObject (0x0x7ff868ab7600) 0 + primary-for QWidget (0x0x7ff86ea80690) + QPaintDevice (0x0x7ff868ab7e40) 16 + vptr=((& QMessageBox::_ZTV11QMessageBox) + 488u) + +Class QMouseEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMouseEventTransition::QPrivateSignal (0x0x7ff868b0a600) 0 empty + +Vtable for QMouseEventTransition +QMouseEventTransition::_ZTV21QMouseEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QMouseEventTransition) +16 (int (*)(...))QMouseEventTransition::metaObject +24 (int (*)(...))QMouseEventTransition::qt_metacast +32 (int (*)(...))QMouseEventTransition::qt_metacall +40 (int (*)(...))QMouseEventTransition::~QMouseEventTransition +48 (int (*)(...))QMouseEventTransition::~QMouseEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMouseEventTransition::eventTest +120 (int (*)(...))QMouseEventTransition::onTransition + +Class QMouseEventTransition + size=16 align=8 + base size=16 base align=8 +QMouseEventTransition (0x0x7ff869f1aa28) 0 + vptr=((& QMouseEventTransition::_ZTV21QMouseEventTransition) + 16u) + QEventTransition (0x0x7ff86a0427b8) 0 + primary-for QMouseEventTransition (0x0x7ff869f1aa28) + QAbstractTransition (0x0x7ff86a042a28) 0 + primary-for QEventTransition (0x0x7ff86a0427b8) + QObject (0x0x7ff868b0a5a0) 0 + primary-for QAbstractTransition (0x0x7ff86a042a28) + +Class QOpenGLWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLWidget::QPrivateSignal (0x0x7ff868b0a8a0) 0 empty + +Vtable for QOpenGLWidget +QOpenGLWidget::_ZTV13QOpenGLWidget: 67u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QOpenGLWidget) +16 (int (*)(...))QOpenGLWidget::metaObject +24 (int (*)(...))QOpenGLWidget::qt_metacast +32 (int (*)(...))QOpenGLWidget::qt_metacall +40 (int (*)(...))QOpenGLWidget::~QOpenGLWidget +48 (int (*)(...))QOpenGLWidget::~QOpenGLWidget +56 (int (*)(...))QOpenGLWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QOpenGLWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QOpenGLWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QOpenGLWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QOpenGLWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QOpenGLWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QOpenGLWidget::initializeGL +440 (int (*)(...))QOpenGLWidget::resizeGL +448 (int (*)(...))QOpenGLWidget::paintGL +456 (int (*)(...))-16 +464 (int (*)(...))(& _ZTI13QOpenGLWidget) +472 (int (*)(...))QOpenGLWidget::_ZThn16_N13QOpenGLWidgetD1Ev +480 (int (*)(...))QOpenGLWidget::_ZThn16_N13QOpenGLWidgetD0Ev +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +496 (int (*)(...))QOpenGLWidget::_ZThn16_NK13QOpenGLWidget11paintEngineEv +504 (int (*)(...))QOpenGLWidget::_ZThn16_NK13QOpenGLWidget6metricEN12QPaintDevice17PaintDeviceMetricE +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +520 (int (*)(...))QOpenGLWidget::_ZThn16_NK13QOpenGLWidget10redirectedEP6QPoint +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QOpenGLWidget + size=48 align=8 + base size=48 base align=8 +QOpenGLWidget (0x0x7ff86a042e38) 0 + vptr=((& QOpenGLWidget::_ZTV13QOpenGLWidget) + 16u) + QWidget (0x0x7ff86e89a540) 0 + primary-for QOpenGLWidget (0x0x7ff86a042e38) + QObject (0x0x7ff868b0a780) 0 + primary-for QWidget (0x0x7ff86e89a540) + QPaintDevice (0x0x7ff868b0a7e0) 16 + vptr=((& QOpenGLWidget::_ZTV13QOpenGLWidget) + 472u) + +Class QTextEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextEdit::QPrivateSignal (0x0x7ff868b0aa80) 0 empty + +Class QTextEdit::ExtraSelection + size=24 align=8 + base size=24 base align=8 +QTextEdit::ExtraSelection (0x0x7ff868b0aae0) 0 + +Vtable for QTextEdit +QTextEdit::_ZTV9QTextEdit: 73u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTextEdit) +16 (int (*)(...))QTextEdit::metaObject +24 (int (*)(...))QTextEdit::qt_metacast +32 (int (*)(...))QTextEdit::qt_metacall +40 (int (*)(...))QTextEdit::~QTextEdit +48 (int (*)(...))QTextEdit::~QTextEdit +56 (int (*)(...))QTextEdit::event +64 (int (*)(...))QAbstractScrollArea::eventFilter +72 (int (*)(...))QTextEdit::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QTextEdit::mousePressEvent +176 (int (*)(...))QTextEdit::mouseReleaseEvent +184 (int (*)(...))QTextEdit::mouseDoubleClickEvent +192 (int (*)(...))QTextEdit::mouseMoveEvent +200 (int (*)(...))QTextEdit::wheelEvent +208 (int (*)(...))QTextEdit::keyPressEvent +216 (int (*)(...))QTextEdit::keyReleaseEvent +224 (int (*)(...))QTextEdit::focusInEvent +232 (int (*)(...))QTextEdit::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTextEdit::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QTextEdit::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QTextEdit::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QTextEdit::dragEnterEvent +320 (int (*)(...))QTextEdit::dragMoveEvent +328 (int (*)(...))QTextEdit::dragLeaveEvent +336 (int (*)(...))QTextEdit::dropEvent +344 (int (*)(...))QTextEdit::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QTextEdit::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QTextEdit::inputMethodEvent +416 (int (*)(...))QTextEdit::inputMethodQuery +424 (int (*)(...))QTextEdit::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractScrollArea::viewportEvent +448 (int (*)(...))QTextEdit::scrollContentsBy +456 (int (*)(...))QAbstractScrollArea::viewportSizeHint +464 (int (*)(...))QTextEdit::loadResource +472 (int (*)(...))QTextEdit::createMimeDataFromSelection +480 (int (*)(...))QTextEdit::canInsertFromMimeData +488 (int (*)(...))QTextEdit::insertFromMimeData +496 (int (*)(...))QTextEdit::doSetTextCursor +504 (int (*)(...))-16 +512 (int (*)(...))(& _ZTI9QTextEdit) +520 (int (*)(...))QTextEdit::_ZThn16_N9QTextEditD1Ev +528 (int (*)(...))QTextEdit::_ZThn16_N9QTextEditD0Ev +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +568 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +576 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTextEdit + size=48 align=8 + base size=48 base align=8 +QTextEdit (0x0x7ff869ac2340) 0 + vptr=((& QTextEdit::_ZTV9QTextEdit) + 16u) + QAbstractScrollArea (0x0x7ff869ac23a8) 0 + primary-for QTextEdit (0x0x7ff869ac2340) + QFrame (0x0x7ff869ac2680) 0 + primary-for QAbstractScrollArea (0x0x7ff869ac23a8) + QWidget (0x0x7ff86e89aa80) 0 + primary-for QFrame (0x0x7ff869ac2680) + QObject (0x0x7ff868b0a960) 0 + primary-for QWidget (0x0x7ff86e89aa80) + QPaintDevice (0x0x7ff868b0a9c0) 16 + vptr=((& QTextEdit::_ZTV9QTextEdit) + 520u) + +Class QPlainTextEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPlainTextEdit::QPrivateSignal (0x0x7ff868b57000) 0 empty + +Vtable for QPlainTextEdit +QPlainTextEdit::_ZTV14QPlainTextEdit: 73u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QPlainTextEdit) +16 (int (*)(...))QPlainTextEdit::metaObject +24 (int (*)(...))QPlainTextEdit::qt_metacast +32 (int (*)(...))QPlainTextEdit::qt_metacall +40 (int (*)(...))QPlainTextEdit::~QPlainTextEdit +48 (int (*)(...))QPlainTextEdit::~QPlainTextEdit +56 (int (*)(...))QPlainTextEdit::event +64 (int (*)(...))QAbstractScrollArea::eventFilter +72 (int (*)(...))QPlainTextEdit::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QPlainTextEdit::mousePressEvent +176 (int (*)(...))QPlainTextEdit::mouseReleaseEvent +184 (int (*)(...))QPlainTextEdit::mouseDoubleClickEvent +192 (int (*)(...))QPlainTextEdit::mouseMoveEvent +200 (int (*)(...))QPlainTextEdit::wheelEvent +208 (int (*)(...))QPlainTextEdit::keyPressEvent +216 (int (*)(...))QPlainTextEdit::keyReleaseEvent +224 (int (*)(...))QPlainTextEdit::focusInEvent +232 (int (*)(...))QPlainTextEdit::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QPlainTextEdit::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QPlainTextEdit::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QPlainTextEdit::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QPlainTextEdit::dragEnterEvent +320 (int (*)(...))QPlainTextEdit::dragMoveEvent +328 (int (*)(...))QPlainTextEdit::dragLeaveEvent +336 (int (*)(...))QPlainTextEdit::dropEvent +344 (int (*)(...))QPlainTextEdit::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QPlainTextEdit::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QPlainTextEdit::inputMethodEvent +416 (int (*)(...))QPlainTextEdit::inputMethodQuery +424 (int (*)(...))QPlainTextEdit::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractScrollArea::viewportEvent +448 (int (*)(...))QPlainTextEdit::scrollContentsBy +456 (int (*)(...))QAbstractScrollArea::viewportSizeHint +464 (int (*)(...))QPlainTextEdit::loadResource +472 (int (*)(...))QPlainTextEdit::createMimeDataFromSelection +480 (int (*)(...))QPlainTextEdit::canInsertFromMimeData +488 (int (*)(...))QPlainTextEdit::insertFromMimeData +496 (int (*)(...))QPlainTextEdit::doSetTextCursor +504 (int (*)(...))-16 +512 (int (*)(...))(& _ZTI14QPlainTextEdit) +520 (int (*)(...))QPlainTextEdit::_ZThn16_N14QPlainTextEditD1Ev +528 (int (*)(...))QPlainTextEdit::_ZThn16_N14QPlainTextEditD0Ev +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +568 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +576 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QPlainTextEdit + size=48 align=8 + base size=48 base align=8 +QPlainTextEdit (0x0x7ff869ac28f0) 0 + vptr=((& QPlainTextEdit::_ZTV14QPlainTextEdit) + 16u) + QAbstractScrollArea (0x0x7ff869ac2a90) 0 + primary-for QPlainTextEdit (0x0x7ff869ac28f0) + QFrame (0x0x7ff869ac2af8) 0 + primary-for QAbstractScrollArea (0x0x7ff869ac2a90) + QWidget (0x0x7ff86e539000) 0 + primary-for QFrame (0x0x7ff869ac2af8) + QObject (0x0x7ff868b32e40) 0 + primary-for QWidget (0x0x7ff86e539000) + QPaintDevice (0x0x7ff868b32ea0) 16 + vptr=((& QPlainTextEdit::_ZTV14QPlainTextEdit) + 520u) + +Class QPlainTextDocumentLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPlainTextDocumentLayout::QPrivateSignal (0x0x7ff868b572a0) 0 empty + +Vtable for QPlainTextDocumentLayout +QPlainTextDocumentLayout::_ZTV24QPlainTextDocumentLayout: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QPlainTextDocumentLayout) +16 (int (*)(...))QPlainTextDocumentLayout::metaObject +24 (int (*)(...))QPlainTextDocumentLayout::qt_metacast +32 (int (*)(...))QPlainTextDocumentLayout::qt_metacall +40 (int (*)(...))QPlainTextDocumentLayout::~QPlainTextDocumentLayout +48 (int (*)(...))QPlainTextDocumentLayout::~QPlainTextDocumentLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPlainTextDocumentLayout::draw +120 (int (*)(...))QPlainTextDocumentLayout::hitTest +128 (int (*)(...))QPlainTextDocumentLayout::pageCount +136 (int (*)(...))QPlainTextDocumentLayout::documentSize +144 (int (*)(...))QPlainTextDocumentLayout::frameBoundingRect +152 (int (*)(...))QPlainTextDocumentLayout::blockBoundingRect +160 (int (*)(...))QPlainTextDocumentLayout::documentChanged +168 (int (*)(...))QAbstractTextDocumentLayout::resizeInlineObject +176 (int (*)(...))QAbstractTextDocumentLayout::positionInlineObject +184 (int (*)(...))QAbstractTextDocumentLayout::drawInlineObject + +Class QPlainTextDocumentLayout + size=16 align=8 + base size=16 base align=8 +QPlainTextDocumentLayout (0x0x7ff869ac2b60) 0 + vptr=((& QPlainTextDocumentLayout::_ZTV24QPlainTextDocumentLayout) + 16u) + QAbstractTextDocumentLayout (0x0x7ff869ae4a90) 0 + primary-for QPlainTextDocumentLayout (0x0x7ff869ac2b60) + QObject (0x0x7ff868b57060) 0 + primary-for QAbstractTextDocumentLayout (0x0x7ff869ae4a90) + +Class QProgressBar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProgressBar::QPrivateSignal (0x0x7ff868b57d80) 0 empty + +Vtable for QProgressBar +QProgressBar::_ZTV12QProgressBar: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QProgressBar) +16 (int (*)(...))QProgressBar::metaObject +24 (int (*)(...))QProgressBar::qt_metacast +32 (int (*)(...))QProgressBar::qt_metacall +40 (int (*)(...))QProgressBar::~QProgressBar +48 (int (*)(...))QProgressBar::~QProgressBar +56 (int (*)(...))QProgressBar::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QProgressBar::sizeHint +136 (int (*)(...))QProgressBar::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QProgressBar::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QProgressBar::text +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI12QProgressBar) +456 (int (*)(...))QProgressBar::_ZThn16_N12QProgressBarD1Ev +464 (int (*)(...))QProgressBar::_ZThn16_N12QProgressBarD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QProgressBar + size=48 align=8 + base size=48 base align=8 +QProgressBar (0x0x7ff869ae4af8) 0 + vptr=((& QProgressBar::_ZTV12QProgressBar) + 16u) + QWidget (0x0x7ff86e555a80) 0 + primary-for QProgressBar (0x0x7ff869ae4af8) + QObject (0x0x7ff868b57300) 0 + primary-for QWidget (0x0x7ff86e555a80) + QPaintDevice (0x0x7ff868b57d20) 16 + vptr=((& QProgressBar::_ZTV12QProgressBar) + 456u) + +Class QProgressDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProgressDialog::QPrivateSignal (0x0x7ff868b790c0) 0 empty + +Vtable for QProgressDialog +QProgressDialog::_ZTV15QProgressDialog: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QProgressDialog) +16 (int (*)(...))QProgressDialog::metaObject +24 (int (*)(...))QProgressDialog::qt_metacast +32 (int (*)(...))QProgressDialog::qt_metacall +40 (int (*)(...))QProgressDialog::~QProgressDialog +48 (int (*)(...))QProgressDialog::~QProgressDialog +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QDialog::setVisible +128 (int (*)(...))QProgressDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QProgressDialog::resizeEvent +280 (int (*)(...))QProgressDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QProgressDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QProgressDialog::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QDialog::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI15QProgressDialog) +488 (int (*)(...))QProgressDialog::_ZThn16_N15QProgressDialogD1Ev +496 (int (*)(...))QProgressDialog::_ZThn16_N15QProgressDialogD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QProgressDialog + size=48 align=8 + base size=48 base align=8 +QProgressDialog (0x0x7ff869ae4bc8) 0 + vptr=((& QProgressDialog::_ZTV15QProgressDialog) + 16u) + QDialog (0x0x7ff869ae4c30) 0 + primary-for QProgressDialog (0x0x7ff869ae4bc8) + QWidget (0x0x7ff86e555f50) 0 + primary-for QDialog (0x0x7ff869ae4c30) + QObject (0x0x7ff868b57e40) 0 + primary-for QWidget (0x0x7ff86e555f50) + QPaintDevice (0x0x7ff868b79060) 16 + vptr=((& QProgressDialog::_ZTV15QProgressDialog) + 488u) + +Class QProxyStyle::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProxyStyle::QPrivateSignal (0x0x7ff868b79c60) 0 empty + +Vtable for QProxyStyle +QProxyStyle::_ZTV11QProxyStyle: 37u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QProxyStyle) +16 (int (*)(...))QProxyStyle::metaObject +24 (int (*)(...))QProxyStyle::qt_metacast +32 (int (*)(...))QProxyStyle::qt_metacall +40 (int (*)(...))QProxyStyle::~QProxyStyle +48 (int (*)(...))QProxyStyle::~QProxyStyle +56 (int (*)(...))QProxyStyle::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProxyStyle::polish +120 (int (*)(...))QProxyStyle::unpolish +128 (int (*)(...))QProxyStyle::polish +136 (int (*)(...))QProxyStyle::unpolish +144 (int (*)(...))QProxyStyle::polish +152 (int (*)(...))QProxyStyle::itemTextRect +160 (int (*)(...))QProxyStyle::itemPixmapRect +168 (int (*)(...))QProxyStyle::drawItemText +176 (int (*)(...))QProxyStyle::drawItemPixmap +184 (int (*)(...))QProxyStyle::standardPalette +192 (int (*)(...))QProxyStyle::drawPrimitive +200 (int (*)(...))QProxyStyle::drawControl +208 (int (*)(...))QProxyStyle::subElementRect +216 (int (*)(...))QProxyStyle::drawComplexControl +224 (int (*)(...))QProxyStyle::hitTestComplexControl +232 (int (*)(...))QProxyStyle::subControlRect +240 (int (*)(...))QProxyStyle::pixelMetric +248 (int (*)(...))QProxyStyle::sizeFromContents +256 (int (*)(...))QProxyStyle::styleHint +264 (int (*)(...))QProxyStyle::standardPixmap +272 (int (*)(...))QProxyStyle::standardIcon +280 (int (*)(...))QProxyStyle::generatedIconPixmap +288 (int (*)(...))QProxyStyle::layoutSpacing + +Class QProxyStyle + size=16 align=8 + base size=16 base align=8 +QProxyStyle (0x0x7ff869ae4f70) 0 + vptr=((& QProxyStyle::_ZTV11QProxyStyle) + 16u) + QCommonStyle (0x0x7ff869aff000) 0 + primary-for QProxyStyle (0x0x7ff869ae4f70) + QStyle (0x0x7ff869aff618) 0 + primary-for QCommonStyle (0x0x7ff869aff000) + QObject (0x0x7ff868b79c00) 0 + primary-for QStyle (0x0x7ff869aff618) + +Class QRadioButton::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRadioButton::QPrivateSignal (0x0x7ff868ba96c0) 0 empty + +Vtable for QRadioButton +QRadioButton::_ZTV12QRadioButton: 67u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QRadioButton) +16 (int (*)(...))QRadioButton::metaObject +24 (int (*)(...))QRadioButton::qt_metacast +32 (int (*)(...))QRadioButton::qt_metacall +40 (int (*)(...))QRadioButton::~QRadioButton +48 (int (*)(...))QRadioButton::~QRadioButton +56 (int (*)(...))QRadioButton::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractButton::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QRadioButton::sizeHint +136 (int (*)(...))QRadioButton::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractButton::mousePressEvent +176 (int (*)(...))QAbstractButton::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QRadioButton::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QAbstractButton::keyPressEvent +216 (int (*)(...))QAbstractButton::keyReleaseEvent +224 (int (*)(...))QAbstractButton::focusInEvent +232 (int (*)(...))QAbstractButton::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QRadioButton::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractButton::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QRadioButton::hitButton +440 (int (*)(...))QAbstractButton::checkStateSet +448 (int (*)(...))QAbstractButton::nextCheckState +456 (int (*)(...))-16 +464 (int (*)(...))(& _ZTI12QRadioButton) +472 (int (*)(...))QRadioButton::_ZThn16_N12QRadioButtonD1Ev +480 (int (*)(...))QRadioButton::_ZThn16_N12QRadioButtonD0Ev +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QRadioButton + size=48 align=8 + base size=48 base align=8 +QRadioButton (0x0x7ff869aff680) 0 + vptr=((& QRadioButton::_ZTV12QRadioButton) + 16u) + QAbstractButton (0x0x7ff869aff9c0) 0 + primary-for QRadioButton (0x0x7ff869aff680) + QWidget (0x0x7ff86e5b0620) 0 + primary-for QAbstractButton (0x0x7ff869aff9c0) + QObject (0x0x7ff868ba95a0) 0 + primary-for QWidget (0x0x7ff86e5b0620) + QPaintDevice (0x0x7ff868ba9600) 16 + vptr=((& QRadioButton::_ZTV12QRadioButton) + 472u) + +Class QScrollBar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QScrollBar::QPrivateSignal (0x0x7ff868ba9f60) 0 empty + +Vtable for QScrollBar +QScrollBar::_ZTV10QScrollBar: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QScrollBar) +16 (int (*)(...))QScrollBar::metaObject +24 (int (*)(...))QScrollBar::qt_metacast +32 (int (*)(...))QScrollBar::qt_metacall +40 (int (*)(...))QScrollBar::~QScrollBar +48 (int (*)(...))QScrollBar::~QScrollBar +56 (int (*)(...))QScrollBar::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSlider::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QScrollBar::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QScrollBar::mousePressEvent +176 (int (*)(...))QScrollBar::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QScrollBar::mouseMoveEvent +200 (int (*)(...))QScrollBar::wheelEvent +208 (int (*)(...))QAbstractSlider::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QScrollBar::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QScrollBar::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QScrollBar::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSlider::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QScrollBar::sliderChange +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI10QScrollBar) +456 (int (*)(...))QScrollBar::_ZThn16_N10QScrollBarD1Ev +464 (int (*)(...))QScrollBar::_ZThn16_N10QScrollBarD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QScrollBar + size=48 align=8 + base size=48 base align=8 +QScrollBar (0x0x7ff869affa28) 0 + vptr=((& QScrollBar::_ZTV10QScrollBar) + 16u) + QAbstractSlider (0x0x7ff869b18a90) 0 + primary-for QScrollBar (0x0x7ff869affa28) + QWidget (0x0x7ff86e5b09a0) 0 + primary-for QAbstractSlider (0x0x7ff869b18a90) + QObject (0x0x7ff868ba9e40) 0 + primary-for QWidget (0x0x7ff86e5b09a0) + QPaintDevice (0x0x7ff868ba9ea0) 16 + vptr=((& QScrollBar::_ZTV10QScrollBar) + 456u) + +Vtable for QScrollerProperties +QScrollerProperties::_ZTV19QScrollerProperties: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QScrollerProperties) +16 (int (*)(...))QScrollerProperties::~QScrollerProperties +24 (int (*)(...))QScrollerProperties::~QScrollerProperties + +Class QScrollerProperties + size=16 align=8 + base size=16 base align=8 +QScrollerProperties (0x0x7ff868bcc8a0) 0 + vptr=((& QScrollerProperties::_ZTV19QScrollerProperties) + 16u) + +Class QScroller::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QScroller::QPrivateSignal (0x0x7ff868bf96c0) 0 empty + +Vtable for QScroller +QScroller::_ZTV9QScroller: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QScroller) +16 (int (*)(...))QScroller::metaObject +24 (int (*)(...))QScroller::qt_metacast +32 (int (*)(...))QScroller::qt_metacall +40 (int (*)(...))QScroller::~QScroller +48 (int (*)(...))QScroller::~QScroller +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QScroller + size=24 align=8 + base size=24 base align=8 +QScroller (0x0x7ff869c23d68) 0 + vptr=((& QScroller::_ZTV9QScroller) + 16u) + QObject (0x0x7ff868bf9660) 0 + primary-for QScroller (0x0x7ff869c23d68) + +Class QShortcut::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QShortcut::QPrivateSignal (0x0x7ff86881ea80) 0 empty + +Vtable for QShortcut +QShortcut::_ZTV9QShortcut: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QShortcut) +16 (int (*)(...))QShortcut::metaObject +24 (int (*)(...))QShortcut::qt_metacast +32 (int (*)(...))QShortcut::qt_metacall +40 (int (*)(...))QShortcut::~QShortcut +48 (int (*)(...))QShortcut::~QShortcut +56 (int (*)(...))QShortcut::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QShortcut + size=16 align=8 + base size=16 base align=8 +QShortcut (0x0x7ff869c23dd0) 0 + vptr=((& QShortcut::_ZTV9QShortcut) + 16u) + QObject (0x0x7ff86881ea20) 0 + primary-for QShortcut (0x0x7ff869c23dd0) + +Class QSizeGrip::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSizeGrip::QPrivateSignal (0x0x7ff868643f00) 0 empty + +Vtable for QSizeGrip +QSizeGrip::_ZTV9QSizeGrip: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSizeGrip) +16 (int (*)(...))QSizeGrip::metaObject +24 (int (*)(...))QSizeGrip::qt_metacast +32 (int (*)(...))QSizeGrip::qt_metacall +40 (int (*)(...))QSizeGrip::~QSizeGrip +48 (int (*)(...))QSizeGrip::~QSizeGrip +56 (int (*)(...))QSizeGrip::event +64 (int (*)(...))QSizeGrip::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QSizeGrip::setVisible +128 (int (*)(...))QSizeGrip::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QSizeGrip::mousePressEvent +176 (int (*)(...))QSizeGrip::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QSizeGrip::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QSizeGrip::paintEvent +264 (int (*)(...))QSizeGrip::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QSizeGrip::showEvent +352 (int (*)(...))QSizeGrip::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI9QSizeGrip) +448 (int (*)(...))QSizeGrip::_ZThn16_N9QSizeGripD1Ev +456 (int (*)(...))QSizeGrip::_ZThn16_N9QSizeGripD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QSizeGrip + size=48 align=8 + base size=48 base align=8 +QSizeGrip (0x0x7ff8698c6340) 0 + vptr=((& QSizeGrip::_ZTV9QSizeGrip) + 16u) + QWidget (0x0x7ff86e3752a0) 0 + primary-for QSizeGrip (0x0x7ff8698c6340) + QObject (0x0x7ff8686437e0) 0 + primary-for QWidget (0x0x7ff86e3752a0) + QPaintDevice (0x0x7ff868643840) 16 + vptr=((& QSizeGrip::_ZTV9QSizeGrip) + 448u) + +Class QSpinBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSpinBox::QPrivateSignal (0x0x7ff86867c720) 0 empty + +Vtable for QSpinBox +QSpinBox::_ZTV8QSpinBox: 71u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QSpinBox) +16 (int (*)(...))QSpinBox::metaObject +24 (int (*)(...))QSpinBox::qt_metacast +32 (int (*)(...))QSpinBox::qt_metacall +40 (int (*)(...))QSpinBox::~QSpinBox +48 (int (*)(...))QSpinBox::~QSpinBox +56 (int (*)(...))QSpinBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSpinBox::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractSpinBox::sizeHint +136 (int (*)(...))QAbstractSpinBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractSpinBox::mousePressEvent +176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent +200 (int (*)(...))QAbstractSpinBox::wheelEvent +208 (int (*)(...))QAbstractSpinBox::keyPressEvent +216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent +224 (int (*)(...))QAbstractSpinBox::focusInEvent +232 (int (*)(...))QAbstractSpinBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractSpinBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractSpinBox::resizeEvent +280 (int (*)(...))QAbstractSpinBox::closeEvent +288 (int (*)(...))QAbstractSpinBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QAbstractSpinBox::showEvent +352 (int (*)(...))QAbstractSpinBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSpinBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QAbstractSpinBox::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QSpinBox::validate +440 (int (*)(...))QSpinBox::fixup +448 (int (*)(...))QAbstractSpinBox::stepBy +456 (int (*)(...))QAbstractSpinBox::clear +464 (int (*)(...))QAbstractSpinBox::stepEnabled +472 (int (*)(...))QSpinBox::valueFromText +480 (int (*)(...))QSpinBox::textFromValue +488 (int (*)(...))-16 +496 (int (*)(...))(& _ZTI8QSpinBox) +504 (int (*)(...))QSpinBox::_ZThn16_N8QSpinBoxD1Ev +512 (int (*)(...))QSpinBox::_ZThn16_N8QSpinBoxD0Ev +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QSpinBox + size=48 align=8 + base size=48 base align=8 +QSpinBox (0x0x7ff8698c63a8) 0 + vptr=((& QSpinBox::_ZTV8QSpinBox) + 16u) + QAbstractSpinBox (0x0x7ff8698c6d00) 0 + primary-for QSpinBox (0x0x7ff8698c63a8) + QWidget (0x0x7ff86e375690) 0 + primary-for QAbstractSpinBox (0x0x7ff8698c6d00) + QObject (0x0x7ff868643f60) 0 + primary-for QWidget (0x0x7ff86e375690) + QPaintDevice (0x0x7ff86867c6c0) 16 + vptr=((& QSpinBox::_ZTV8QSpinBox) + 504u) + +Class QDoubleSpinBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDoubleSpinBox::QPrivateSignal (0x0x7ff86867cc60) 0 empty + +Vtable for QDoubleSpinBox +QDoubleSpinBox::_ZTV14QDoubleSpinBox: 71u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QDoubleSpinBox) +16 (int (*)(...))QDoubleSpinBox::metaObject +24 (int (*)(...))QDoubleSpinBox::qt_metacast +32 (int (*)(...))QDoubleSpinBox::qt_metacall +40 (int (*)(...))QDoubleSpinBox::~QDoubleSpinBox +48 (int (*)(...))QDoubleSpinBox::~QDoubleSpinBox +56 (int (*)(...))QAbstractSpinBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSpinBox::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractSpinBox::sizeHint +136 (int (*)(...))QAbstractSpinBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractSpinBox::mousePressEvent +176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent +200 (int (*)(...))QAbstractSpinBox::wheelEvent +208 (int (*)(...))QAbstractSpinBox::keyPressEvent +216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent +224 (int (*)(...))QAbstractSpinBox::focusInEvent +232 (int (*)(...))QAbstractSpinBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractSpinBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractSpinBox::resizeEvent +280 (int (*)(...))QAbstractSpinBox::closeEvent +288 (int (*)(...))QAbstractSpinBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QAbstractSpinBox::showEvent +352 (int (*)(...))QAbstractSpinBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSpinBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QAbstractSpinBox::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDoubleSpinBox::validate +440 (int (*)(...))QDoubleSpinBox::fixup +448 (int (*)(...))QAbstractSpinBox::stepBy +456 (int (*)(...))QAbstractSpinBox::clear +464 (int (*)(...))QAbstractSpinBox::stepEnabled +472 (int (*)(...))QDoubleSpinBox::valueFromText +480 (int (*)(...))QDoubleSpinBox::textFromValue +488 (int (*)(...))-16 +496 (int (*)(...))(& _ZTI14QDoubleSpinBox) +504 (int (*)(...))QDoubleSpinBox::_ZThn16_N14QDoubleSpinBoxD1Ev +512 (int (*)(...))QDoubleSpinBox::_ZThn16_N14QDoubleSpinBoxD0Ev +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDoubleSpinBox + size=48 align=8 + base size=48 base align=8 +QDoubleSpinBox (0x0x7ff8698c6d68) 0 + vptr=((& QDoubleSpinBox::_ZTV14QDoubleSpinBox) + 16u) + QAbstractSpinBox (0x0x7ff869a2d888) 0 + primary-for QDoubleSpinBox (0x0x7ff8698c6d68) + QWidget (0x0x7ff86e3759a0) 0 + primary-for QAbstractSpinBox (0x0x7ff869a2d888) + QObject (0x0x7ff86867cb40) 0 + primary-for QWidget (0x0x7ff86e3759a0) + QPaintDevice (0x0x7ff86867cba0) 16 + vptr=((& QDoubleSpinBox::_ZTV14QDoubleSpinBox) + 504u) + +Class QSplashScreen::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSplashScreen::QPrivateSignal (0x0x7ff86869c8a0) 0 empty + +Vtable for QSplashScreen +QSplashScreen::_ZTV13QSplashScreen: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSplashScreen) +16 (int (*)(...))QSplashScreen::metaObject +24 (int (*)(...))QSplashScreen::qt_metacast +32 (int (*)(...))QSplashScreen::qt_metacall +40 (int (*)(...))QSplashScreen::~QSplashScreen +48 (int (*)(...))QSplashScreen::~QSplashScreen +56 (int (*)(...))QSplashScreen::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QSplashScreen::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QSplashScreen::drawContents +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI13QSplashScreen) +456 (int (*)(...))QSplashScreen::_ZThn16_N13QSplashScreenD1Ev +464 (int (*)(...))QSplashScreen::_ZThn16_N13QSplashScreenD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QSplashScreen + size=48 align=8 + base size=48 base align=8 +QSplashScreen (0x0x7ff869a2d8f0) 0 + vptr=((& QSplashScreen::_ZTV13QSplashScreen) + 16u) + QWidget (0x0x7ff86e375d20) 0 + primary-for QSplashScreen (0x0x7ff869a2d8f0) + QObject (0x0x7ff86867ce40) 0 + primary-for QWidget (0x0x7ff86e375d20) + QPaintDevice (0x0x7ff86867cea0) 16 + vptr=((& QSplashScreen::_ZTV13QSplashScreen) + 456u) + +Class QSplitter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSplitter::QPrivateSignal (0x0x7ff86869ccc0) 0 empty + +Vtable for QSplitter +QSplitter::_ZTV9QSplitter: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSplitter) +16 (int (*)(...))QSplitter::metaObject +24 (int (*)(...))QSplitter::qt_metacast +32 (int (*)(...))QSplitter::qt_metacall +40 (int (*)(...))QSplitter::~QSplitter +48 (int (*)(...))QSplitter::~QSplitter +56 (int (*)(...))QSplitter::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QSplitter::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QSplitter::sizeHint +136 (int (*)(...))QSplitter::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QFrame::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QSplitter::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QSplitter::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QSplitter::createHandle +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI9QSplitter) +456 (int (*)(...))QSplitter::_ZThn16_N9QSplitterD1Ev +464 (int (*)(...))QSplitter::_ZThn16_N9QSplitterD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QSplitter + size=48 align=8 + base size=48 base align=8 +QSplitter (0x0x7ff869a2da90) 0 + vptr=((& QSplitter::_ZTV9QSplitter) + 16u) + QFrame (0x0x7ff869a2dc98) 0 + primary-for QSplitter (0x0x7ff869a2da90) + QWidget (0x0x7ff86e45b150) 0 + primary-for QFrame (0x0x7ff869a2dc98) + QObject (0x0x7ff86869c900) 0 + primary-for QWidget (0x0x7ff86e45b150) + QPaintDevice (0x0x7ff86869cc60) 16 + vptr=((& QSplitter::_ZTV9QSplitter) + 456u) + +Class QSplitterHandle::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSplitterHandle::QPrivateSignal (0x0x7ff8686c81e0) 0 empty + +Vtable for QSplitterHandle +QSplitterHandle::_ZTV15QSplitterHandle: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSplitterHandle) +16 (int (*)(...))QSplitterHandle::metaObject +24 (int (*)(...))QSplitterHandle::qt_metacast +32 (int (*)(...))QSplitterHandle::qt_metacall +40 (int (*)(...))QSplitterHandle::~QSplitterHandle +48 (int (*)(...))QSplitterHandle::~QSplitterHandle +56 (int (*)(...))QSplitterHandle::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QSplitterHandle::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QSplitterHandle::mousePressEvent +176 (int (*)(...))QSplitterHandle::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QSplitterHandle::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QSplitterHandle::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QSplitterHandle::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI15QSplitterHandle) +448 (int (*)(...))QSplitterHandle::_ZThn16_N15QSplitterHandleD1Ev +456 (int (*)(...))QSplitterHandle::_ZThn16_N15QSplitterHandleD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QSplitterHandle + size=48 align=8 + base size=48 base align=8 +QSplitterHandle (0x0x7ff869a2dd00) 0 + vptr=((& QSplitterHandle::_ZTV15QSplitterHandle) + 16u) + QWidget (0x0x7ff86e45b460) 0 + primary-for QSplitterHandle (0x0x7ff869a2dd00) + QObject (0x0x7ff8686c8000) 0 + primary-for QWidget (0x0x7ff86e45b460) + QPaintDevice (0x0x7ff8686c8060) 16 + vptr=((& QSplitterHandle::_ZTV15QSplitterHandle) + 448u) + +Class QStackedLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStackedLayout::QPrivateSignal (0x0x7ff8686c83c0) 0 empty + +Vtable for QStackedLayout +QStackedLayout::_ZTV14QStackedLayout: 50u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QStackedLayout) +16 (int (*)(...))QStackedLayout::metaObject +24 (int (*)(...))QStackedLayout::qt_metacast +32 (int (*)(...))QStackedLayout::qt_metacall +40 (int (*)(...))QStackedLayout::~QStackedLayout +48 (int (*)(...))QStackedLayout::~QStackedLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLayout::invalidate +120 (int (*)(...))QLayout::geometry +128 (int (*)(...))QStackedLayout::addItem +136 (int (*)(...))QLayout::expandingDirections +144 (int (*)(...))QStackedLayout::minimumSize +152 (int (*)(...))QLayout::maximumSize +160 (int (*)(...))QStackedLayout::setGeometry +168 (int (*)(...))QStackedLayout::itemAt +176 (int (*)(...))QStackedLayout::takeAt +184 (int (*)(...))QLayout::indexOf +192 (int (*)(...))QStackedLayout::count +200 (int (*)(...))QLayout::isEmpty +208 (int (*)(...))QLayout::controlTypes +216 (int (*)(...))QLayout::layout +224 (int (*)(...))QStackedLayout::sizeHint +232 (int (*)(...))QStackedLayout::hasHeightForWidth +240 (int (*)(...))QStackedLayout::heightForWidth +248 (int (*)(...))-16 +256 (int (*)(...))(& _ZTI14QStackedLayout) +264 (int (*)(...))QStackedLayout::_ZThn16_N14QStackedLayoutD1Ev +272 (int (*)(...))QStackedLayout::_ZThn16_N14QStackedLayoutD0Ev +280 (int (*)(...))QStackedLayout::_ZThn16_NK14QStackedLayout8sizeHintEv +288 (int (*)(...))QStackedLayout::_ZThn16_NK14QStackedLayout11minimumSizeEv +296 (int (*)(...))QLayout::_ZThn16_NK7QLayout11maximumSizeEv +304 (int (*)(...))QLayout::_ZThn16_NK7QLayout19expandingDirectionsEv +312 (int (*)(...))QStackedLayout::_ZThn16_N14QStackedLayout11setGeometryERK5QRect +320 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +328 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +336 (int (*)(...))QStackedLayout::_ZThn16_NK14QStackedLayout17hasHeightForWidthEv +344 (int (*)(...))QStackedLayout::_ZThn16_NK14QStackedLayout14heightForWidthEi +352 (int (*)(...))QLayoutItem::minimumHeightForWidth +360 (int (*)(...))QLayout::_ZThn16_N7QLayout10invalidateEv +368 (int (*)(...))QLayoutItem::widget +376 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +384 (int (*)(...))QLayoutItem::spacerItem +392 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QStackedLayout + size=32 align=8 + base size=28 base align=8 +QStackedLayout (0x0x7ff869679a90) 0 + vptr=((& QStackedLayout::_ZTV14QStackedLayout) + 16u) + QLayout (0x0x7ff86e45b770) 0 + primary-for QStackedLayout (0x0x7ff869679a90) + QObject (0x0x7ff8686c8240) 0 + primary-for QLayout (0x0x7ff86e45b770) + QLayoutItem (0x0x7ff8686c8300) 16 + vptr=((& QStackedLayout::_ZTV14QStackedLayout) + 264u) + +Class QStackedWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStackedWidget::QPrivateSignal (0x0x7ff8686c8ea0) 0 empty + +Vtable for QStackedWidget +QStackedWidget::_ZTV14QStackedWidget: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QStackedWidget) +16 (int (*)(...))QStackedWidget::metaObject +24 (int (*)(...))QStackedWidget::qt_metacast +32 (int (*)(...))QStackedWidget::qt_metacall +40 (int (*)(...))QStackedWidget::~QStackedWidget +48 (int (*)(...))QStackedWidget::~QStackedWidget +56 (int (*)(...))QStackedWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QFrame::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QFrame::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI14QStackedWidget) +448 (int (*)(...))QStackedWidget::_ZThn16_N14QStackedWidgetD1Ev +456 (int (*)(...))QStackedWidget::_ZThn16_N14QStackedWidgetD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QStackedWidget + size=48 align=8 + base size=48 base align=8 +QStackedWidget (0x0x7ff869679af8) 0 + vptr=((& QStackedWidget::_ZTV14QStackedWidget) + 16u) + QFrame (0x0x7ff86969f548) 0 + primary-for QStackedWidget (0x0x7ff869679af8) + QWidget (0x0x7ff86e45bc40) 0 + primary-for QFrame (0x0x7ff86969f548) + QObject (0x0x7ff8686c8420) 0 + primary-for QWidget (0x0x7ff86e45bc40) + QPaintDevice (0x0x7ff8686c8e40) 16 + vptr=((& QStackedWidget::_ZTV14QStackedWidget) + 448u) + +Class QStatusBar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStatusBar::QPrivateSignal (0x0x7ff8686ea2a0) 0 empty + +Vtable for QStatusBar +QStatusBar::_ZTV10QStatusBar: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QStatusBar) +16 (int (*)(...))QStatusBar::metaObject +24 (int (*)(...))QStatusBar::qt_metacast +32 (int (*)(...))QStatusBar::qt_metacall +40 (int (*)(...))QStatusBar::~QStatusBar +48 (int (*)(...))QStatusBar::~QStatusBar +56 (int (*)(...))QStatusBar::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QStatusBar::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QStatusBar::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QStatusBar::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI10QStatusBar) +448 (int (*)(...))QStatusBar::_ZThn16_N10QStatusBarD1Ev +456 (int (*)(...))QStatusBar::_ZThn16_N10QStatusBarD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QStatusBar + size=48 align=8 + base size=48 base align=8 +QStatusBar (0x0x7ff86969f5b0) 0 + vptr=((& QStatusBar::_ZTV10QStatusBar) + 16u) + QWidget (0x0x7ff86e0fa000) 0 + primary-for QStatusBar (0x0x7ff86969f5b0) + QObject (0x0x7ff8686ea000) 0 + primary-for QWidget (0x0x7ff86e0fa000) + QPaintDevice (0x0x7ff8686ea060) 16 + vptr=((& QStatusBar::_ZTV10QStatusBar) + 448u) + +Class QStyledItemDelegate::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStyledItemDelegate::QPrivateSignal (0x0x7ff86854a360) 0 empty + +Vtable for QStyledItemDelegate +QStyledItemDelegate::_ZTV19QStyledItemDelegate: 26u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QStyledItemDelegate) +16 (int (*)(...))QStyledItemDelegate::metaObject +24 (int (*)(...))QStyledItemDelegate::qt_metacast +32 (int (*)(...))QStyledItemDelegate::qt_metacall +40 (int (*)(...))QStyledItemDelegate::~QStyledItemDelegate +48 (int (*)(...))QStyledItemDelegate::~QStyledItemDelegate +56 (int (*)(...))QObject::event +64 (int (*)(...))QStyledItemDelegate::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStyledItemDelegate::paint +120 (int (*)(...))QStyledItemDelegate::sizeHint +128 (int (*)(...))QStyledItemDelegate::createEditor +136 (int (*)(...))QAbstractItemDelegate::destroyEditor +144 (int (*)(...))QStyledItemDelegate::setEditorData +152 (int (*)(...))QStyledItemDelegate::setModelData +160 (int (*)(...))QStyledItemDelegate::updateEditorGeometry +168 (int (*)(...))QStyledItemDelegate::editorEvent +176 (int (*)(...))QAbstractItemDelegate::helpEvent +184 (int (*)(...))QAbstractItemDelegate::paintingRoles +192 (int (*)(...))QStyledItemDelegate::displayText +200 (int (*)(...))QStyledItemDelegate::initStyleOption + +Class QStyledItemDelegate + size=16 align=8 + base size=16 base align=8 +QStyledItemDelegate (0x0x7ff86969f6e8) 0 + vptr=((& QStyledItemDelegate::_ZTV19QStyledItemDelegate) + 16u) + QAbstractItemDelegate (0x0x7ff86969ff70) 0 + primary-for QStyledItemDelegate (0x0x7ff86969f6e8) + QObject (0x0x7ff8686ea300) 0 + primary-for QAbstractItemDelegate (0x0x7ff86969ff70) + +Class QStyleFactory + size=1 align=1 + base size=0 base align=1 +QStyleFactory (0x0x7ff86854a3c0) 0 empty + +Class QStylePainter + size=24 align=8 + base size=24 base align=8 +QStylePainter (0x0x7ff8696be000) 0 + QPainter (0x0x7ff86854aea0) 0 + +Class QStylePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStylePlugin::QPrivateSignal (0x0x7ff868584b40) 0 empty + +Vtable for QStylePlugin +QStylePlugin::_ZTV12QStylePlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QStylePlugin) +16 (int (*)(...))QStylePlugin::metaObject +24 (int (*)(...))QStylePlugin::qt_metacast +32 (int (*)(...))QStylePlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QStylePlugin + size=16 align=8 + base size=16 base align=8 +QStylePlugin (0x0x7ff8696be1a0) 0 + vptr=((& QStylePlugin::_ZTV12QStylePlugin) + 16u) + QObject (0x0x7ff868584ae0) 0 + primary-for QStylePlugin (0x0x7ff8696be1a0) + +Class QSystemTrayIcon::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSystemTrayIcon::QPrivateSignal (0x0x7ff8682aaa20) 0 empty + +Vtable for QSystemTrayIcon +QSystemTrayIcon::_ZTV15QSystemTrayIcon: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSystemTrayIcon) +16 (int (*)(...))QSystemTrayIcon::metaObject +24 (int (*)(...))QSystemTrayIcon::qt_metacast +32 (int (*)(...))QSystemTrayIcon::qt_metacall +40 (int (*)(...))QSystemTrayIcon::~QSystemTrayIcon +48 (int (*)(...))QSystemTrayIcon::~QSystemTrayIcon +56 (int (*)(...))QSystemTrayIcon::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSystemTrayIcon + size=16 align=8 + base size=16 base align=8 +QSystemTrayIcon (0x0x7ff8696e0c30) 0 + vptr=((& QSystemTrayIcon::_ZTV15QSystemTrayIcon) + 16u) + QObject (0x0x7ff8682aa9c0) 0 + primary-for QSystemTrayIcon (0x0x7ff8696e0c30) + +Class QTableView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTableView::QPrivateSignal (0x0x7ff868342300) 0 empty + +Vtable for QTableView +QTableView::_ZTV10QTableView: 106u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTableView) +16 (int (*)(...))QTableView::metaObject +24 (int (*)(...))QTableView::qt_metacast +32 (int (*)(...))QTableView::qt_metacall +40 (int (*)(...))QTableView::~QTableView +48 (int (*)(...))QTableView::~QTableView +56 (int (*)(...))QAbstractItemView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QTableView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QAbstractItemView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QAbstractItemView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTableView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractItemView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QAbstractItemView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QAbstractItemView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractItemView::viewportEvent +448 (int (*)(...))QTableView::scrollContentsBy +456 (int (*)(...))QTableView::viewportSizeHint +464 (int (*)(...))QTableView::setModel +472 (int (*)(...))QTableView::setSelectionModel +480 (int (*)(...))QAbstractItemView::keyboardSearch +488 (int (*)(...))QTableView::visualRect +496 (int (*)(...))QTableView::scrollTo +504 (int (*)(...))QTableView::indexAt +512 (int (*)(...))QTableView::sizeHintForRow +520 (int (*)(...))QTableView::sizeHintForColumn +528 (int (*)(...))QAbstractItemView::reset +536 (int (*)(...))QTableView::setRootIndex +544 (int (*)(...))QTableView::doItemsLayout +552 (int (*)(...))QAbstractItemView::selectAll +560 (int (*)(...))QAbstractItemView::dataChanged +568 (int (*)(...))QAbstractItemView::rowsInserted +576 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved +584 (int (*)(...))QTableView::selectionChanged +592 (int (*)(...))QTableView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QTableView::updateGeometries +624 (int (*)(...))QTableView::verticalScrollbarAction +632 (int (*)(...))QTableView::horizontalScrollbarAction +640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))QTableView::moveCursor +688 (int (*)(...))QTableView::horizontalOffset +696 (int (*)(...))QTableView::verticalOffset +704 (int (*)(...))QTableView::isIndexHidden +712 (int (*)(...))QTableView::setSelection +720 (int (*)(...))QTableView::visualRegionForSelection +728 (int (*)(...))QTableView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QAbstractItemView::startDrag +760 (int (*)(...))QTableView::viewOptions +768 (int (*)(...))-16 +776 (int (*)(...))(& _ZTI10QTableView) +784 (int (*)(...))QTableView::_ZThn16_N10QTableViewD1Ev +792 (int (*)(...))QTableView::_ZThn16_N10QTableViewD0Ev +800 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +808 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +816 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTableView + size=48 align=8 + base size=48 base align=8 +QTableView (0x0x7ff8696e0ea0) 0 + vptr=((& QTableView::_ZTV10QTableView) + 16u) + QAbstractItemView (0x0x7ff86983a5b0) 0 + primary-for QTableView (0x0x7ff8696e0ea0) + QAbstractScrollArea (0x0x7ff86925d4e0) 0 + primary-for QAbstractItemView (0x0x7ff86983a5b0) + QFrame (0x0x7ff86925d548) 0 + primary-for QAbstractScrollArea (0x0x7ff86925d4e0) + QWidget (0x0x7ff86e1e7cb0) 0 + primary-for QFrame (0x0x7ff86925d548) + QObject (0x0x7ff8683421e0) 0 + primary-for QWidget (0x0x7ff86e1e7cb0) + QPaintDevice (0x0x7ff868342240) 16 + vptr=((& QTableView::_ZTV10QTableView) + 784u) + +Class QTableWidgetSelectionRange + size=16 align=4 + base size=16 base align=4 +QTableWidgetSelectionRange (0x0x7ff868342900) 0 + +Vtable for QTableWidgetItem +QTableWidgetItem::_ZTV16QTableWidgetItem: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QTableWidgetItem) +16 (int (*)(...))QTableWidgetItem::~QTableWidgetItem +24 (int (*)(...))QTableWidgetItem::~QTableWidgetItem +32 (int (*)(...))QTableWidgetItem::clone +40 (int (*)(...))QTableWidgetItem::data +48 (int (*)(...))QTableWidgetItem::setData +56 (int (*)(...))QTableWidgetItem::operator< +64 (int (*)(...))QTableWidgetItem::read +72 (int (*)(...))QTableWidgetItem::write + +Class QTableWidgetItem + size=48 align=8 + base size=44 base align=8 +QTableWidgetItem (0x0x7ff868342960) 0 + vptr=((& QTableWidgetItem::_ZTV16QTableWidgetItem) + 16u) + +Class QTableWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTableWidget::QPrivateSignal (0x0x7ff868363720) 0 empty + +Vtable for QTableWidget +QTableWidget::_ZTV12QTableWidget: 110u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QTableWidget) +16 (int (*)(...))QTableWidget::metaObject +24 (int (*)(...))QTableWidget::qt_metacast +32 (int (*)(...))QTableWidget::qt_metacall +40 (int (*)(...))QTableWidget::~QTableWidget +48 (int (*)(...))QTableWidget::~QTableWidget +56 (int (*)(...))QTableWidget::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QTableView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QAbstractItemView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QAbstractItemView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTableView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractItemView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QAbstractItemView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QTableWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractItemView::viewportEvent +448 (int (*)(...))QTableView::scrollContentsBy +456 (int (*)(...))QTableView::viewportSizeHint +464 (int (*)(...))QTableWidget::setModel +472 (int (*)(...))QTableView::setSelectionModel +480 (int (*)(...))QAbstractItemView::keyboardSearch +488 (int (*)(...))QTableView::visualRect +496 (int (*)(...))QTableView::scrollTo +504 (int (*)(...))QTableView::indexAt +512 (int (*)(...))QTableView::sizeHintForRow +520 (int (*)(...))QTableView::sizeHintForColumn +528 (int (*)(...))QAbstractItemView::reset +536 (int (*)(...))QTableView::setRootIndex +544 (int (*)(...))QTableView::doItemsLayout +552 (int (*)(...))QAbstractItemView::selectAll +560 (int (*)(...))QAbstractItemView::dataChanged +568 (int (*)(...))QAbstractItemView::rowsInserted +576 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved +584 (int (*)(...))QTableView::selectionChanged +592 (int (*)(...))QTableView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QTableView::updateGeometries +624 (int (*)(...))QTableView::verticalScrollbarAction +632 (int (*)(...))QTableView::horizontalScrollbarAction +640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))QTableView::moveCursor +688 (int (*)(...))QTableView::horizontalOffset +696 (int (*)(...))QTableView::verticalOffset +704 (int (*)(...))QTableView::isIndexHidden +712 (int (*)(...))QTableView::setSelection +720 (int (*)(...))QTableView::visualRegionForSelection +728 (int (*)(...))QTableView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QAbstractItemView::startDrag +760 (int (*)(...))QTableView::viewOptions +768 (int (*)(...))QTableWidget::mimeTypes +776 (int (*)(...))QTableWidget::mimeData +784 (int (*)(...))QTableWidget::dropMimeData +792 (int (*)(...))QTableWidget::supportedDropActions +800 (int (*)(...))-16 +808 (int (*)(...))(& _ZTI12QTableWidget) +816 (int (*)(...))QTableWidget::_ZThn16_N12QTableWidgetD1Ev +824 (int (*)(...))QTableWidget::_ZThn16_N12QTableWidgetD0Ev +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +848 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +856 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +864 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +872 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTableWidget + size=48 align=8 + base size=48 base align=8 +QTableWidget (0x0x7ff86925dd68) 0 + vptr=((& QTableWidget::_ZTV12QTableWidget) + 16u) + QTableView (0x0x7ff86925ddd0) 0 + primary-for QTableWidget (0x0x7ff86925dd68) + QAbstractItemView (0x0x7ff86925df70) 0 + primary-for QTableView (0x0x7ff86925ddd0) + QAbstractScrollArea (0x0x7ff8692ba000) 0 + primary-for QAbstractItemView (0x0x7ff86925df70) + QFrame (0x0x7ff8692ba1a0) 0 + primary-for QAbstractScrollArea (0x0x7ff8692ba000) + QWidget (0x0x7ff86e28f380) 0 + primary-for QFrame (0x0x7ff8692ba1a0) + QObject (0x0x7ff868342d80) 0 + primary-for QWidget (0x0x7ff86e28f380) + QPaintDevice (0x0x7ff8683636c0) 16 + vptr=((& QTableWidget::_ZTV12QTableWidget) + 816u) + +Class QTextBrowser::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextBrowser::QPrivateSignal (0x0x7ff86838e4e0) 0 empty + +Vtable for QTextBrowser +QTextBrowser::_ZTV12QTextBrowser: 78u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QTextBrowser) +16 (int (*)(...))QTextBrowser::metaObject +24 (int (*)(...))QTextBrowser::qt_metacast +32 (int (*)(...))QTextBrowser::qt_metacall +40 (int (*)(...))QTextBrowser::~QTextBrowser +48 (int (*)(...))QTextBrowser::~QTextBrowser +56 (int (*)(...))QTextBrowser::event +64 (int (*)(...))QAbstractScrollArea::eventFilter +72 (int (*)(...))QTextEdit::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QTextBrowser::mousePressEvent +176 (int (*)(...))QTextBrowser::mouseReleaseEvent +184 (int (*)(...))QTextEdit::mouseDoubleClickEvent +192 (int (*)(...))QTextBrowser::mouseMoveEvent +200 (int (*)(...))QTextEdit::wheelEvent +208 (int (*)(...))QTextBrowser::keyPressEvent +216 (int (*)(...))QTextEdit::keyReleaseEvent +224 (int (*)(...))QTextEdit::focusInEvent +232 (int (*)(...))QTextBrowser::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTextBrowser::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QTextEdit::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QTextEdit::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QTextEdit::dragEnterEvent +320 (int (*)(...))QTextEdit::dragMoveEvent +328 (int (*)(...))QTextEdit::dragLeaveEvent +336 (int (*)(...))QTextEdit::dropEvent +344 (int (*)(...))QTextEdit::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QTextEdit::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QTextEdit::inputMethodEvent +416 (int (*)(...))QTextEdit::inputMethodQuery +424 (int (*)(...))QTextBrowser::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractScrollArea::viewportEvent +448 (int (*)(...))QTextEdit::scrollContentsBy +456 (int (*)(...))QAbstractScrollArea::viewportSizeHint +464 (int (*)(...))QTextBrowser::loadResource +472 (int (*)(...))QTextEdit::createMimeDataFromSelection +480 (int (*)(...))QTextEdit::canInsertFromMimeData +488 (int (*)(...))QTextEdit::insertFromMimeData +496 (int (*)(...))QTextEdit::doSetTextCursor +504 (int (*)(...))QTextBrowser::setSource +512 (int (*)(...))QTextBrowser::backward +520 (int (*)(...))QTextBrowser::forward +528 (int (*)(...))QTextBrowser::home +536 (int (*)(...))QTextBrowser::reload +544 (int (*)(...))-16 +552 (int (*)(...))(& _ZTI12QTextBrowser) +560 (int (*)(...))QTextBrowser::_ZThn16_N12QTextBrowserD1Ev +568 (int (*)(...))QTextBrowser::_ZThn16_N12QTextBrowserD0Ev +576 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +584 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +592 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +600 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +608 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +616 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTextBrowser + size=48 align=8 + base size=48 base align=8 +QTextBrowser (0x0x7ff8692ba208) 0 + vptr=((& QTextBrowser::_ZTV12QTextBrowser) + 16u) + QTextEdit (0x0x7ff8692ba270) 0 + primary-for QTextBrowser (0x0x7ff8692ba208) + QAbstractScrollArea (0x0x7ff8692baf70) 0 + primary-for QTextEdit (0x0x7ff8692ba270) + QFrame (0x0x7ff8692dc000) 0 + primary-for QAbstractScrollArea (0x0x7ff8692baf70) + QWidget (0x0x7ff86e28fa80) 0 + primary-for QFrame (0x0x7ff8692dc000) + QObject (0x0x7ff868363a20) 0 + primary-for QWidget (0x0x7ff86e28fa80) + QPaintDevice (0x0x7ff868363a80) 16 + vptr=((& QTextBrowser::_ZTV12QTextBrowser) + 560u) + +Class QToolBar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QToolBar::QPrivateSignal (0x0x7ff86838ed20) 0 empty + +Vtable for QToolBar +QToolBar::_ZTV8QToolBar: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QToolBar) +16 (int (*)(...))QToolBar::metaObject +24 (int (*)(...))QToolBar::qt_metacast +32 (int (*)(...))QToolBar::qt_metacall +40 (int (*)(...))QToolBar::~QToolBar +48 (int (*)(...))QToolBar::~QToolBar +56 (int (*)(...))QToolBar::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QToolBar::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QToolBar::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QToolBar::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI8QToolBar) +448 (int (*)(...))QToolBar::_ZThn16_N8QToolBarD1Ev +456 (int (*)(...))QToolBar::_ZThn16_N8QToolBarD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QToolBar + size=48 align=8 + base size=48 base align=8 +QToolBar (0x0x7ff8692dc340) 0 + vptr=((& QToolBar::_ZTV8QToolBar) + 16u) + QWidget (0x0x7ff86e28fd90) 0 + primary-for QToolBar (0x0x7ff8692dc340) + QObject (0x0x7ff86838e540) 0 + primary-for QWidget (0x0x7ff86e28fd90) + QPaintDevice (0x0x7ff86838ecc0) 16 + vptr=((& QToolBar::_ZTV8QToolBar) + 448u) + +Class QToolBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QToolBox::QPrivateSignal (0x0x7ff867df71e0) 0 empty + +Vtable for QToolBox +QToolBox::_ZTV8QToolBox: 66u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QToolBox) +16 (int (*)(...))QToolBox::metaObject +24 (int (*)(...))QToolBox::qt_metacast +32 (int (*)(...))QToolBox::qt_metacall +40 (int (*)(...))QToolBox::~QToolBox +48 (int (*)(...))QToolBox::~QToolBox +56 (int (*)(...))QToolBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QFrame::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QFrame::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QToolBox::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QToolBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QToolBox::itemInserted +440 (int (*)(...))QToolBox::itemRemoved +448 (int (*)(...))-16 +456 (int (*)(...))(& _ZTI8QToolBox) +464 (int (*)(...))QToolBox::_ZThn16_N8QToolBoxD1Ev +472 (int (*)(...))QToolBox::_ZThn16_N8QToolBoxD0Ev +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QToolBox + size=48 align=8 + base size=48 base align=8 +QToolBox (0x0x7ff868e33340) 0 + vptr=((& QToolBox::_ZTV8QToolBox) + 16u) + QFrame (0x0x7ff868e333a8) 0 + primary-for QToolBox (0x0x7ff868e33340) + QWidget (0x0x7ff86e2af000) 0 + primary-for QFrame (0x0x7ff868e333a8) + QObject (0x0x7ff867df70c0) 0 + primary-for QWidget (0x0x7ff86e2af000) + QPaintDevice (0x0x7ff867df7120) 16 + vptr=((& QToolBox::_ZTV8QToolBox) + 464u) + +Class QToolButton::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QToolButton::QPrivateSignal (0x0x7ff867df7de0) 0 empty + +Vtable for QToolButton +QToolButton::_ZTV11QToolButton: 67u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QToolButton) +16 (int (*)(...))QToolButton::metaObject +24 (int (*)(...))QToolButton::qt_metacast +32 (int (*)(...))QToolButton::qt_metacall +40 (int (*)(...))QToolButton::~QToolButton +48 (int (*)(...))QToolButton::~QToolButton +56 (int (*)(...))QToolButton::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QToolButton::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QToolButton::sizeHint +136 (int (*)(...))QToolButton::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QToolButton::mousePressEvent +176 (int (*)(...))QToolButton::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractButton::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QAbstractButton::keyPressEvent +216 (int (*)(...))QAbstractButton::keyReleaseEvent +224 (int (*)(...))QAbstractButton::focusInEvent +232 (int (*)(...))QAbstractButton::focusOutEvent +240 (int (*)(...))QToolButton::enterEvent +248 (int (*)(...))QToolButton::leaveEvent +256 (int (*)(...))QToolButton::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QToolButton::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QToolButton::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QToolButton::hitButton +440 (int (*)(...))QAbstractButton::checkStateSet +448 (int (*)(...))QToolButton::nextCheckState +456 (int (*)(...))-16 +464 (int (*)(...))(& _ZTI11QToolButton) +472 (int (*)(...))QToolButton::_ZThn16_N11QToolButtonD1Ev +480 (int (*)(...))QToolButton::_ZThn16_N11QToolButtonD0Ev +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QToolButton + size=48 align=8 + base size=48 base align=8 +QToolButton (0x0x7ff868e33750) 0 + vptr=((& QToolButton::_ZTV11QToolButton) + 16u) + QAbstractButton (0x0x7ff868e337b8) 0 + primary-for QToolButton (0x0x7ff868e33750) + QWidget (0x0x7ff86e2af540) 0 + primary-for QAbstractButton (0x0x7ff868e337b8) + QObject (0x0x7ff867df73c0) 0 + primary-for QWidget (0x0x7ff86e2af540) + QPaintDevice (0x0x7ff867df7420) 16 + vptr=((& QToolButton::_ZTV11QToolButton) + 472u) + +Class QToolTip + size=1 align=1 + base size=0 base align=1 +QToolTip (0x0x7ff867df7e40) 0 empty + +Class QTreeView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTreeView::QPrivateSignal (0x0x7ff867e1b180) 0 empty + +Vtable for QTreeView +QTreeView::_ZTV9QTreeView: 108u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTreeView) +16 (int (*)(...))QTreeView::metaObject +24 (int (*)(...))QTreeView::qt_metacast +32 (int (*)(...))QTreeView::qt_metacall +40 (int (*)(...))QTreeView::~QTreeView +48 (int (*)(...))QTreeView::~QTreeView +56 (int (*)(...))QAbstractItemView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QTreeView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QTreeView::mousePressEvent +176 (int (*)(...))QTreeView::mouseReleaseEvent +184 (int (*)(...))QTreeView::mouseDoubleClickEvent +192 (int (*)(...))QTreeView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QTreeView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTreeView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractItemView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QTreeView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QAbstractItemView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QTreeView::viewportEvent +448 (int (*)(...))QTreeView::scrollContentsBy +456 (int (*)(...))QTreeView::viewportSizeHint +464 (int (*)(...))QTreeView::setModel +472 (int (*)(...))QTreeView::setSelectionModel +480 (int (*)(...))QTreeView::keyboardSearch +488 (int (*)(...))QTreeView::visualRect +496 (int (*)(...))QTreeView::scrollTo +504 (int (*)(...))QTreeView::indexAt +512 (int (*)(...))QAbstractItemView::sizeHintForRow +520 (int (*)(...))QTreeView::sizeHintForColumn +528 (int (*)(...))QTreeView::reset +536 (int (*)(...))QTreeView::setRootIndex +544 (int (*)(...))QTreeView::doItemsLayout +552 (int (*)(...))QTreeView::selectAll +560 (int (*)(...))QTreeView::dataChanged +568 (int (*)(...))QTreeView::rowsInserted +576 (int (*)(...))QTreeView::rowsAboutToBeRemoved +584 (int (*)(...))QTreeView::selectionChanged +592 (int (*)(...))QTreeView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QTreeView::updateGeometries +624 (int (*)(...))QAbstractItemView::verticalScrollbarAction +632 (int (*)(...))QTreeView::horizontalScrollbarAction +640 (int (*)(...))QTreeView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))QTreeView::moveCursor +688 (int (*)(...))QTreeView::horizontalOffset +696 (int (*)(...))QTreeView::verticalOffset +704 (int (*)(...))QTreeView::isIndexHidden +712 (int (*)(...))QTreeView::setSelection +720 (int (*)(...))QTreeView::visualRegionForSelection +728 (int (*)(...))QTreeView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QAbstractItemView::startDrag +760 (int (*)(...))QAbstractItemView::viewOptions +768 (int (*)(...))QTreeView::drawRow +776 (int (*)(...))QTreeView::drawBranches +784 (int (*)(...))-16 +792 (int (*)(...))(& _ZTI9QTreeView) +800 (int (*)(...))QTreeView::_ZThn16_N9QTreeViewD1Ev +808 (int (*)(...))QTreeView::_ZThn16_N9QTreeViewD0Ev +816 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +848 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +856 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTreeView + size=48 align=8 + base size=48 base align=8 +QTreeView (0x0x7ff868e4d340) 0 + vptr=((& QTreeView::_ZTV9QTreeView) + 16u) + QAbstractItemView (0x0x7ff868e4d3a8) 0 + primary-for QTreeView (0x0x7ff868e4d340) + QAbstractScrollArea (0x0x7ff868f59d68) 0 + primary-for QAbstractItemView (0x0x7ff868e4d3a8) + QFrame (0x0x7ff868f83138) 0 + primary-for QAbstractScrollArea (0x0x7ff868f59d68) + QWidget (0x0x7ff86e2afb60) 0 + primary-for QFrame (0x0x7ff868f83138) + QObject (0x0x7ff867df7f00) 0 + primary-for QWidget (0x0x7ff86e2afb60) + QPaintDevice (0x0x7ff867e1b120) 16 + vptr=((& QTreeView::_ZTV9QTreeView) + 800u) + +Class QTreeWidgetItemIterator + size=24 align=8 + base size=20 base align=8 +QTreeWidgetItemIterator (0x0x7ff867eda900) 0 + +Vtable for QTreeWidgetItem +QTreeWidgetItem::_ZTV15QTreeWidgetItem: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QTreeWidgetItem) +16 (int (*)(...))QTreeWidgetItem::~QTreeWidgetItem +24 (int (*)(...))QTreeWidgetItem::~QTreeWidgetItem +32 (int (*)(...))QTreeWidgetItem::clone +40 (int (*)(...))QTreeWidgetItem::data +48 (int (*)(...))QTreeWidgetItem::setData +56 (int (*)(...))QTreeWidgetItem::operator< +64 (int (*)(...))QTreeWidgetItem::read +72 (int (*)(...))QTreeWidgetItem::write + +Class QTreeWidgetItem + size=64 align=8 + base size=60 base align=8 +QTreeWidgetItem (0x0x7ff8679ec360) 0 + vptr=((& QTreeWidgetItem::_ZTV15QTreeWidgetItem) + 16u) + +Class QTreeWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTreeWidget::QPrivateSignal (0x0x7ff867a16de0) 0 empty + +Vtable for QTreeWidget +QTreeWidget::_ZTV11QTreeWidget: 112u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTreeWidget) +16 (int (*)(...))QTreeWidget::metaObject +24 (int (*)(...))QTreeWidget::qt_metacast +32 (int (*)(...))QTreeWidget::qt_metacall +40 (int (*)(...))QTreeWidget::~QTreeWidget +48 (int (*)(...))QTreeWidget::~QTreeWidget +56 (int (*)(...))QTreeWidget::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QTreeView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QTreeView::mousePressEvent +176 (int (*)(...))QTreeView::mouseReleaseEvent +184 (int (*)(...))QTreeView::mouseDoubleClickEvent +192 (int (*)(...))QTreeView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QTreeView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTreeView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractItemView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QTreeView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QTreeWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QTreeView::viewportEvent +448 (int (*)(...))QTreeView::scrollContentsBy +456 (int (*)(...))QTreeView::viewportSizeHint +464 (int (*)(...))QTreeWidget::setModel +472 (int (*)(...))QTreeWidget::setSelectionModel +480 (int (*)(...))QTreeView::keyboardSearch +488 (int (*)(...))QTreeView::visualRect +496 (int (*)(...))QTreeView::scrollTo +504 (int (*)(...))QTreeView::indexAt +512 (int (*)(...))QAbstractItemView::sizeHintForRow +520 (int (*)(...))QTreeView::sizeHintForColumn +528 (int (*)(...))QTreeView::reset +536 (int (*)(...))QTreeView::setRootIndex +544 (int (*)(...))QTreeView::doItemsLayout +552 (int (*)(...))QTreeView::selectAll +560 (int (*)(...))QTreeView::dataChanged +568 (int (*)(...))QTreeView::rowsInserted +576 (int (*)(...))QTreeView::rowsAboutToBeRemoved +584 (int (*)(...))QTreeView::selectionChanged +592 (int (*)(...))QTreeView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QTreeView::updateGeometries +624 (int (*)(...))QAbstractItemView::verticalScrollbarAction +632 (int (*)(...))QTreeView::horizontalScrollbarAction +640 (int (*)(...))QTreeView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))QTreeView::moveCursor +688 (int (*)(...))QTreeView::horizontalOffset +696 (int (*)(...))QTreeView::verticalOffset +704 (int (*)(...))QTreeView::isIndexHidden +712 (int (*)(...))QTreeView::setSelection +720 (int (*)(...))QTreeView::visualRegionForSelection +728 (int (*)(...))QTreeView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QAbstractItemView::startDrag +760 (int (*)(...))QAbstractItemView::viewOptions +768 (int (*)(...))QTreeView::drawRow +776 (int (*)(...))QTreeView::drawBranches +784 (int (*)(...))QTreeWidget::mimeTypes +792 (int (*)(...))QTreeWidget::mimeData +800 (int (*)(...))QTreeWidget::dropMimeData +808 (int (*)(...))QTreeWidget::supportedDropActions +816 (int (*)(...))-16 +824 (int (*)(...))(& _ZTI11QTreeWidget) +832 (int (*)(...))QTreeWidget::_ZThn16_N11QTreeWidgetD1Ev +840 (int (*)(...))QTreeWidget::_ZThn16_N11QTreeWidgetD0Ev +848 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +856 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +864 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +872 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +880 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +888 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTreeWidget + size=48 align=8 + base size=48 base align=8 +QTreeWidget (0x0x7ff868f83c30) 0 + vptr=((& QTreeWidget::_ZTV11QTreeWidget) + 16u) + QTreeView (0x0x7ff868f83d00) 0 + primary-for QTreeWidget (0x0x7ff868f83c30) + QAbstractItemView (0x0x7ff868c7eb60) 0 + primary-for QTreeView (0x0x7ff868f83d00) + QAbstractScrollArea (0x0x7ff868c7ebc8) 0 + primary-for QAbstractItemView (0x0x7ff868c7eb60) + QFrame (0x0x7ff868c7ed68) 0 + primary-for QAbstractScrollArea (0x0x7ff868c7ebc8) + QWidget (0x0x7ff86e0a3cb0) 0 + primary-for QFrame (0x0x7ff868c7ed68) + QObject (0x0x7ff867a16cc0) 0 + primary-for QWidget (0x0x7ff86e0a3cb0) + QPaintDevice (0x0x7ff867a16d20) 16 + vptr=((& QTreeWidget::_ZTV11QTreeWidget) + 832u) + +Class QUndoGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QUndoGroup::QPrivateSignal (0x0x7ff867a3dba0) 0 empty + +Vtable for QUndoGroup +QUndoGroup::_ZTV10QUndoGroup: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QUndoGroup) +16 (int (*)(...))QUndoGroup::metaObject +24 (int (*)(...))QUndoGroup::qt_metacast +32 (int (*)(...))QUndoGroup::qt_metacall +40 (int (*)(...))QUndoGroup::~QUndoGroup +48 (int (*)(...))QUndoGroup::~QUndoGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QUndoGroup + size=16 align=8 + base size=16 base align=8 +QUndoGroup (0x0x7ff868d84f70) 0 + vptr=((& QUndoGroup::_ZTV10QUndoGroup) + 16u) + QObject (0x0x7ff867a3db40) 0 + primary-for QUndoGroup (0x0x7ff868d84f70) + +Vtable for QUndoCommand +QUndoCommand::_ZTV12QUndoCommand: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QUndoCommand) +16 (int (*)(...))QUndoCommand::~QUndoCommand +24 (int (*)(...))QUndoCommand::~QUndoCommand +32 (int (*)(...))QUndoCommand::undo +40 (int (*)(...))QUndoCommand::redo +48 (int (*)(...))QUndoCommand::id +56 (int (*)(...))QUndoCommand::mergeWith + +Class QUndoCommand + size=16 align=8 + base size=16 base align=8 +QUndoCommand (0x0x7ff867a6b2a0) 0 + vptr=((& QUndoCommand::_ZTV12QUndoCommand) + 16u) + +Class QUndoStack::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QUndoStack::QPrivateSignal (0x0x7ff867a6b7e0) 0 empty + +Vtable for QUndoStack +QUndoStack::_ZTV10QUndoStack: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QUndoStack) +16 (int (*)(...))QUndoStack::metaObject +24 (int (*)(...))QUndoStack::qt_metacast +32 (int (*)(...))QUndoStack::qt_metacall +40 (int (*)(...))QUndoStack::~QUndoStack +48 (int (*)(...))QUndoStack::~QUndoStack +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QUndoStack + size=16 align=8 + base size=16 base align=8 +QUndoStack (0x0x7ff868a80000) 0 + vptr=((& QUndoStack::_ZTV10QUndoStack) + 16u) + QObject (0x0x7ff867a6b300) 0 + primary-for QUndoStack (0x0x7ff868a80000) + +Class QUndoView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QUndoView::QPrivateSignal (0x0x7ff867a6bde0) 0 empty + +Vtable for QUndoView +QUndoView::_ZTV9QUndoView: 106u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QUndoView) +16 (int (*)(...))QUndoView::metaObject +24 (int (*)(...))QUndoView::qt_metacast +32 (int (*)(...))QUndoView::qt_metacall +40 (int (*)(...))QUndoView::~QUndoView +48 (int (*)(...))QUndoView::~QUndoView +56 (int (*)(...))QListView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QListView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QListView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QListView::mouseMoveEvent +200 (int (*)(...))QListView::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QListView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QListView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QListView::dragMoveEvent +328 (int (*)(...))QListView::dragLeaveEvent +336 (int (*)(...))QListView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractItemView::viewportEvent +448 (int (*)(...))QListView::scrollContentsBy +456 (int (*)(...))QListView::viewportSizeHint +464 (int (*)(...))QAbstractItemView::setModel +472 (int (*)(...))QAbstractItemView::setSelectionModel +480 (int (*)(...))QAbstractItemView::keyboardSearch +488 (int (*)(...))QListView::visualRect +496 (int (*)(...))QListView::scrollTo +504 (int (*)(...))QListView::indexAt +512 (int (*)(...))QAbstractItemView::sizeHintForRow +520 (int (*)(...))QAbstractItemView::sizeHintForColumn +528 (int (*)(...))QListView::reset +536 (int (*)(...))QListView::setRootIndex +544 (int (*)(...))QListView::doItemsLayout +552 (int (*)(...))QAbstractItemView::selectAll +560 (int (*)(...))QListView::dataChanged +568 (int (*)(...))QListView::rowsInserted +576 (int (*)(...))QListView::rowsAboutToBeRemoved +584 (int (*)(...))QListView::selectionChanged +592 (int (*)(...))QListView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QListView::updateGeometries +624 (int (*)(...))QAbstractItemView::verticalScrollbarAction +632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction +640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))QListView::moveCursor +688 (int (*)(...))QListView::horizontalOffset +696 (int (*)(...))QListView::verticalOffset +704 (int (*)(...))QListView::isIndexHidden +712 (int (*)(...))QListView::setSelection +720 (int (*)(...))QListView::visualRegionForSelection +728 (int (*)(...))QListView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QListView::startDrag +760 (int (*)(...))QListView::viewOptions +768 (int (*)(...))-16 +776 (int (*)(...))(& _ZTI9QUndoView) +784 (int (*)(...))QUndoView::_ZThn16_N9QUndoViewD1Ev +792 (int (*)(...))QUndoView::_ZThn16_N9QUndoViewD0Ev +800 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +808 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +816 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QUndoView + size=48 align=8 + base size=48 base align=8 +QUndoView (0x0x7ff868a80068) 0 + vptr=((& QUndoView::_ZTV9QUndoView) + 16u) + QListView (0x0x7ff868a800d0) 0 + primary-for QUndoView (0x0x7ff868a80068) + QAbstractItemView (0x0x7ff868a80208) 0 + primary-for QListView (0x0x7ff868a800d0) + QAbstractScrollArea (0x0x7ff868a80270) 0 + primary-for QAbstractItemView (0x0x7ff868a80208) + QFrame (0x0x7ff868a807b8) 0 + primary-for QAbstractScrollArea (0x0x7ff868a80270) + QWidget (0x0x7ff86dccee70) 0 + primary-for QFrame (0x0x7ff868a807b8) + QObject (0x0x7ff867a6b840) 0 + primary-for QWidget (0x0x7ff86dccee70) + QPaintDevice (0x0x7ff867a6bd80) 16 + vptr=((& QUndoView::_ZTV9QUndoView) + 784u) + +Class QWhatsThis + size=1 align=1 + base size=0 base align=1 +QWhatsThis (0x0x7ff867a6bea0) 0 empty + +Class QWidgetAction::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWidgetAction::QPrivateSignal (0x0x7ff867a8f120) 0 empty + +Vtable for QWidgetAction +QWidgetAction::_ZTV13QWidgetAction: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QWidgetAction) +16 (int (*)(...))QWidgetAction::metaObject +24 (int (*)(...))QWidgetAction::qt_metacast +32 (int (*)(...))QWidgetAction::qt_metacall +40 (int (*)(...))QWidgetAction::~QWidgetAction +48 (int (*)(...))QWidgetAction::~QWidgetAction +56 (int (*)(...))QWidgetAction::event +64 (int (*)(...))QWidgetAction::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidgetAction::createWidget +120 (int (*)(...))QWidgetAction::deleteWidget + +Class QWidgetAction + size=16 align=8 + base size=16 base align=8 +QWidgetAction (0x0x7ff868a80820) 0 + vptr=((& QWidgetAction::_ZTV13QWidgetAction) + 16u) + QAction (0x0x7ff868a80c30) 0 + primary-for QWidgetAction (0x0x7ff868a80820) + QObject (0x0x7ff867a8f0c0) 0 + primary-for QAction (0x0x7ff868a80c30) + +Class QWizard::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWizard::QPrivateSignal (0x0x7ff867a8fc00) 0 empty + +Vtable for QWizard +QWizard::_ZTV7QWizard: 73u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QWizard) +16 (int (*)(...))QWizard::metaObject +24 (int (*)(...))QWizard::qt_metacast +32 (int (*)(...))QWizard::qt_metacall +40 (int (*)(...))QWizard::~QWizard +48 (int (*)(...))QWizard::~QWizard +56 (int (*)(...))QWizard::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWizard::setVisible +128 (int (*)(...))QWizard::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWizard::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWizard::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QWizard::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))QWizard::validateCurrentPage +480 (int (*)(...))QWizard::nextId +488 (int (*)(...))QWizard::initializePage +496 (int (*)(...))QWizard::cleanupPage +504 (int (*)(...))-16 +512 (int (*)(...))(& _ZTI7QWizard) +520 (int (*)(...))QWizard::_ZThn16_N7QWizardD1Ev +528 (int (*)(...))QWizard::_ZThn16_N7QWizardD0Ev +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +568 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +576 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QWizard + size=48 align=8 + base size=48 base align=8 +QWizard (0x0x7ff868a80c98) 0 + vptr=((& QWizard::_ZTV7QWizard) + 16u) + QDialog (0x0x7ff868aacd00) 0 + primary-for QWizard (0x0x7ff868a80c98) + QWidget (0x0x7ff86dcddb60) 0 + primary-for QDialog (0x0x7ff868aacd00) + QObject (0x0x7ff867a8fae0) 0 + primary-for QWidget (0x0x7ff86dcddb60) + QPaintDevice (0x0x7ff867a8fb40) 16 + vptr=((& QWizard::_ZTV7QWizard) + 520u) + +Class QWizardPage::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWizardPage::QPrivateSignal (0x0x7ff867ab2de0) 0 empty + +Vtable for QWizardPage +QWizardPage::_ZTV11QWizardPage: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QWizardPage) +16 (int (*)(...))QWizardPage::metaObject +24 (int (*)(...))QWizardPage::qt_metacast +32 (int (*)(...))QWizardPage::qt_metacall +40 (int (*)(...))QWizardPage::~QWizardPage +48 (int (*)(...))QWizardPage::~QWizardPage +56 (int (*)(...))QWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QWizardPage::initializePage +440 (int (*)(...))QWizardPage::cleanupPage +448 (int (*)(...))QWizardPage::validatePage +456 (int (*)(...))QWizardPage::isComplete +464 (int (*)(...))QWizardPage::nextId +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI11QWizardPage) +488 (int (*)(...))QWizardPage::_ZThn16_N11QWizardPageD1Ev +496 (int (*)(...))QWizardPage::_ZThn16_N11QWizardPageD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QWizardPage + size=48 align=8 + base size=48 base align=8 +QWizardPage (0x0x7ff868acb1a0) 0 + vptr=((& QWizardPage::_ZTV11QWizardPage) + 16u) + QWidget (0x0x7ff86dd112a0) 0 + primary-for QWizardPage (0x0x7ff868acb1a0) + QObject (0x0x7ff867ab2a80) 0 + primary-for QWidget (0x0x7ff86dd112a0) + QPaintDevice (0x0x7ff867ab2ae0) 16 + vptr=((& QWizardPage::_ZTV11QWizardPage) + 488u) + +Class QGLColormap::QGLColormapData + size=24 align=8 + base size=24 base align=8 +QGLColormap::QGLColormapData (0x0x7ff867adf0c0) 0 + +Class QGLColormap + size=8 align=8 + base size=8 base align=8 +QGLColormap (0x0x7ff867ab2e40) 0 + +Class QGLFormat + size=8 align=8 + base size=8 base align=8 +QGLFormat (0x0x7ff867b067e0) 0 + +Vtable for QGLContext +QGLContext::_ZTV10QGLContext: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QGLContext) +16 (int (*)(...))QGLContext::~QGLContext +24 (int (*)(...))QGLContext::~QGLContext +32 (int (*)(...))QGLContext::create +40 (int (*)(...))QGLContext::makeCurrent +48 (int (*)(...))QGLContext::doneCurrent +56 (int (*)(...))QGLContext::swapBuffers +64 (int (*)(...))QGLContext::chooseContext + +Class QGLContext + size=16 align=8 + base size=16 base align=8 +QGLContext (0x0x7ff8677f03c0) 0 + vptr=((& QGLContext::_ZTV10QGLContext) + 16u) + +Class QGLWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGLWidget::QPrivateSignal (0x0x7ff8678412a0) 0 empty + +Vtable for QGLWidget +QGLWidget::_ZTV9QGLWidget: 74u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QGLWidget) +16 (int (*)(...))QGLWidget::metaObject +24 (int (*)(...))QGLWidget::qt_metacast +32 (int (*)(...))QGLWidget::qt_metacall +40 (int (*)(...))QGLWidget::~QGLWidget +48 (int (*)(...))QGLWidget::~QGLWidget +56 (int (*)(...))QGLWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QGLWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QGLWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QGLWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QGLWidget::updateGL +440 (int (*)(...))QGLWidget::updateOverlayGL +448 (int (*)(...))QGLWidget::initializeGL +456 (int (*)(...))QGLWidget::resizeGL +464 (int (*)(...))QGLWidget::paintGL +472 (int (*)(...))QGLWidget::initializeOverlayGL +480 (int (*)(...))QGLWidget::resizeOverlayGL +488 (int (*)(...))QGLWidget::paintOverlayGL +496 (int (*)(...))QGLWidget::glInit +504 (int (*)(...))QGLWidget::glDraw +512 (int (*)(...))-16 +520 (int (*)(...))(& _ZTI9QGLWidget) +528 (int (*)(...))QGLWidget::_ZThn16_N9QGLWidgetD1Ev +536 (int (*)(...))QGLWidget::_ZThn16_N9QGLWidgetD0Ev +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +552 (int (*)(...))QGLWidget::_ZThn16_NK9QGLWidget11paintEngineEv +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +568 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +576 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +584 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QGLWidget + size=48 align=8 + base size=48 base align=8 +QGLWidget (0x0x7ff868b59888) 0 + vptr=((& QGLWidget::_ZTV9QGLWidget) + 16u) + QWidget (0x0x7ff86d9dd460) 0 + primary-for QGLWidget (0x0x7ff868b59888) + QObject (0x0x7ff867815840) 0 + primary-for QWidget (0x0x7ff86d9dd460) + QPaintDevice (0x0x7ff867841240) 16 + vptr=((& QGLWidget::_ZTV9QGLWidget) + 528u) + +Class QGLBuffer + size=8 align=8 + base size=8 base align=8 +QGLBuffer (0x0x7ff867841360) 0 + +Vtable for QGLFramebufferObject +QGLFramebufferObject::_ZTV20QGLFramebufferObject: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QGLFramebufferObject) +16 (int (*)(...))QGLFramebufferObject::~QGLFramebufferObject +24 (int (*)(...))QGLFramebufferObject::~QGLFramebufferObject +32 (int (*)(...))QGLFramebufferObject::devType +40 (int (*)(...))QGLFramebufferObject::paintEngine +48 (int (*)(...))QGLFramebufferObject::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QGLFramebufferObject + size=32 align=8 + base size=32 base align=8 +QGLFramebufferObject (0x0x7ff868b598f0) 0 + vptr=((& QGLFramebufferObject::_ZTV20QGLFramebufferObject) + 16u) + QPaintDevice (0x0x7ff867841540) 0 + primary-for QGLFramebufferObject (0x0x7ff868b598f0) + +Class QGLFramebufferObjectFormat + size=8 align=8 + base size=8 base align=8 +QGLFramebufferObjectFormat (0x0x7ff8678bbae0) 0 + +Class QGLFunctions + size=8 align=8 + base size=8 base align=8 +QGLFunctions (0x0x7ff8678bbba0) 0 + +Class QGLFunctionsPrivate + size=8 align=8 + base size=8 base align=8 +QGLFunctionsPrivate (0x0x7ff867926f00) 0 + +Vtable for QGLPixelBuffer +QGLPixelBuffer::_ZTV14QGLPixelBuffer: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QGLPixelBuffer) +16 (int (*)(...))QGLPixelBuffer::~QGLPixelBuffer +24 (int (*)(...))QGLPixelBuffer::~QGLPixelBuffer +32 (int (*)(...))QGLPixelBuffer::devType +40 (int (*)(...))QGLPixelBuffer::paintEngine +48 (int (*)(...))QGLPixelBuffer::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QGLPixelBuffer + size=32 align=8 + base size=32 base align=8 +QGLPixelBuffer (0x0x7ff868b9d3a8) 0 + vptr=((& QGLPixelBuffer::_ZTV14QGLPixelBuffer) + 16u) + QPaintDevice (0x0x7ff866303240) 0 + primary-for QGLPixelBuffer (0x0x7ff868b9d3a8) + +Class QGLShader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGLShader::QPrivateSignal (0x0x7ff866059d20) 0 empty + +Vtable for QGLShader +QGLShader::_ZTV9QGLShader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QGLShader) +16 (int (*)(...))QGLShader::metaObject +24 (int (*)(...))QGLShader::qt_metacast +32 (int (*)(...))QGLShader::qt_metacall +40 (int (*)(...))QGLShader::~QGLShader +48 (int (*)(...))QGLShader::~QGLShader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QGLShader + size=16 align=8 + base size=16 base align=8 +QGLShader (0x0x7ff868b9d410) 0 + vptr=((& QGLShader::_ZTV9QGLShader) + 16u) + QObject (0x0x7ff866059480) 0 + primary-for QGLShader (0x0x7ff868b9d410) + +Class QGLShaderProgram::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGLShaderProgram::QPrivateSignal (0x0x7ff8661b2f00) 0 empty + +Vtable for QGLShaderProgram +QGLShaderProgram::_ZTV16QGLShaderProgram: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QGLShaderProgram) +16 (int (*)(...))QGLShaderProgram::metaObject +24 (int (*)(...))QGLShaderProgram::qt_metacast +32 (int (*)(...))QGLShaderProgram::qt_metacall +40 (int (*)(...))QGLShaderProgram::~QGLShaderProgram +48 (int (*)(...))QGLShaderProgram::~QGLShaderProgram +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGLShaderProgram::link + +Class QGLShaderProgram + size=16 align=8 + base size=16 base align=8 +QGLShaderProgram (0x0x7ff868b9d820) 0 + vptr=((& QGLShaderProgram::_ZTV16QGLShaderProgram) + 16u) + QObject (0x0x7ff86613aea0) 0 + primary-for QGLShaderProgram (0x0x7ff868b9d820) + diff --git a/tests/auto/bic/data/QtPrintSupport.5.12.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtPrintSupport.5.12.0.linux-gcc-amd64.txt new file mode 100644 index 0000000000..250c0b8ed9 --- /dev/null +++ b/tests/auto/bic/data/QtPrintSupport.5.12.0.linux-gcc-amd64.txt @@ -0,0 +1,19692 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7f9a56e2a1e0) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7f9a56e72960) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7f9a56e72ba0) 0 empty + +Class std::__do_is_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_default_constructible_impl (0x0x7f9a56e72de0) 0 empty + +Class std::__do_is_static_castable_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_static_castable_impl (0x0x7f9a56e9c060) 0 empty + +Class std::__do_is_direct_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_direct_constructible_impl (0x0x7f9a56e9c1e0) 0 empty + +Class std::__do_is_nary_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nary_constructible_impl (0x0x7f9a56e9c5a0) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7f9a56f28d20) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7f9a56f28de0) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7f9a56f57180) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7f9a56f57240) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7f9a56f57300) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7f9a56f573c0) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7f9a56f57660) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7f9a56f57840) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7f9a56f57cc0) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7f9a56f57d20) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7f9a56b0c9c0) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7f9a56b0ca20) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7f9a56ef8c98) 0 empty + std::input_iterator_tag (0x0x7f9a56b0ca80) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7f9a56ef8d00) 0 empty + std::forward_iterator_tag (0x0x7f9a56ef8d68) 0 empty + std::input_iterator_tag (0x0x7f9a56b0cae0) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7f9a56ef8dd0) 0 empty + std::bidirectional_iterator_tag (0x0x7f9a56ef8e38) 0 empty + std::forward_iterator_tag (0x0x7f9a56ef8ea0) 0 empty + std::input_iterator_tag (0x0x7f9a56b0cb40) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7f9a56b4c7e0) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7f9a56b4c840) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7f9a56b4c8a0) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7f9a56b4c900) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7f9a56b4c960) 0 empty + +Class wait + size=4 align=4 + base size=4 base align=4 +wait (0x0x7f9a56c3a480) 0 + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7f9a56c3a6c0) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7f9a56c3a780) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7f9a56c3a7e0) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7f9a56c3a8a0) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7f9a56c3a900) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7f9a56c3ad80) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7f9a56c3ade0) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7f9a56c3ae40) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16u) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7f9a56b49410) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u) + std::exception (0x0x7f9a56c3aea0) 0 nearly-empty + primary-for std::bad_exception (0x0x7f9a56b49410) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7f9a56c3af00) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7f9a56c3af60) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16u) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7f9a56b49618) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u) + std::exception (0x0x7f9a569903c0) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f9a56b49618) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7f9a56b49680) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16u) + std::bad_alloc (0x0x7f9a56b496e8) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7f9a56b49680) + std::exception (0x0x7f9a56990420) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f9a56b496e8) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7f9a56990480) 0 empty + +Class __exception + size=40 align=8 + base size=40 base align=8 +__exception (0x0x7f9a56a4b0c0) 0 + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7f9a56a4bd80) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7f9a56a4bde0) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7f9a56892cc0) 0 + +Class __sched_param + size=4 align=4 + base size=4 base align=4 +__sched_param (0x0x7f9a56892d20) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7f9a56892de0) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7f9a56892e40) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7f9a56892ea0) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7f9a56892f00) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7f9a5653f060) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7f9a5653f0c0) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7f9a5653f4e0) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7f9a5653f540) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7f9a5636ed20) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7f9a5636ed80) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7f9a5642ed20) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7f9a561ddb40) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7f9a5615e2d8) 0 + std::iterator (0x0x7f9a561ddc00) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7f9a5615e340) 0 + std::_Bit_iterator_base (0x0x7f9a5615e3a8) 0 + std::iterator (0x0x7f9a561ddc60) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7f9a5615e410) 0 + std::_Bit_iterator_base (0x0x7f9a5615e478) 0 + std::iterator (0x0x7f9a561ddcc0) 0 empty + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7f9a55fc6ae0) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7f9a55cfa8a0) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7f9a55cfa840) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7f9a55aa5840) 0 + +Class qIsNull(double)::U + size=8 align=8 + base size=8 base align=8 +qIsNull(double)::U (0x0x7f9a546cf360) 0 + +Class qIsNull(float)::U + size=4 align=4 + base size=4 base align=4 +qIsNull(float)::U (0x0x7f9a546cf3c0) 0 + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7f9a54777e40) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7f9a54777ea0) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7f9a54777f00) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7f9a54777f60) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7f9a547e3240) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7f9a547e3780) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7f9a547e6340) 0 + std::__atomic_flag_base (0x0x7f9a547e37e0) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7f9a547e6a90) 0 + QAtomicInteger (0x0x7f9a547e6af8) 0 + QBasicAtomicInteger (0x0x7f9a54571f00) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7f9a53ef84e0) 0 empty + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7f9a540556c0) 0 + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7f9a540557e0) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7f9a53f6a6e8) 0 + QGenericArgument (0x0x7f9a54055840) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7f9a540559c0) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7f9a54055a80) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7f9a53cfcae0) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7f9a53cfcb40) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7f9a53cfcde0) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7f9a53cfce40) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7f9a53dee1e0) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7f9a53dee240) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7f9a53dee2a0) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7f9a53dee300) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7f9a53dee360) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7f9a53dee720) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7f9a53d0cd00) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16u) + std::exception (0x0x7f9a53dee7e0) 0 nearly-empty + primary-for std::logic_error (0x0x7f9a53d0cd00) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7f9a53d0cd68) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16u) + std::logic_error (0x0x7f9a53d0cdd0) 0 + primary-for std::domain_error (0x0x7f9a53d0cd68) + std::exception (0x0x7f9a53dee840) 0 nearly-empty + primary-for std::logic_error (0x0x7f9a53d0cdd0) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7f9a53d0ce38) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16u) + std::logic_error (0x0x7f9a53d0cea0) 0 + primary-for std::invalid_argument (0x0x7f9a53d0ce38) + std::exception (0x0x7f9a53dee8a0) 0 nearly-empty + primary-for std::logic_error (0x0x7f9a53d0cea0) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7f9a53d0cf08) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16u) + std::logic_error (0x0x7f9a53d0cf70) 0 + primary-for std::length_error (0x0x7f9a53d0cf08) + std::exception (0x0x7f9a53dee900) 0 nearly-empty + primary-for std::logic_error (0x0x7f9a53d0cf70) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7f9a53d0ca28) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16u) + std::logic_error (0x0x7f9a53d0caf8) 0 + primary-for std::out_of_range (0x0x7f9a53d0ca28) + std::exception (0x0x7f9a53dee960) 0 nearly-empty + primary-for std::logic_error (0x0x7f9a53d0caf8) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7f9a53ac8000) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16u) + std::exception (0x0x7f9a53dee9c0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f9a53ac8000) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7f9a53ac8068) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16u) + std::runtime_error (0x0x7f9a53ac80d0) 0 + primary-for std::range_error (0x0x7f9a53ac8068) + std::exception (0x0x7f9a53deea20) 0 nearly-empty + primary-for std::runtime_error (0x0x7f9a53ac80d0) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7f9a53ac8138) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16u) + std::runtime_error (0x0x7f9a53ac81a0) 0 + primary-for std::overflow_error (0x0x7f9a53ac8138) + std::exception (0x0x7f9a53deea80) 0 nearly-empty + primary-for std::runtime_error (0x0x7f9a53ac81a0) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7f9a53ac8208) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16u) + std::runtime_error (0x0x7f9a53ac8270) 0 + primary-for std::underflow_error (0x0x7f9a53ac8208) + std::exception (0x0x7f9a53deeae0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f9a53ac8270) + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7f9a53deec60) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16u) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7f9a53deeea0) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7f9a53b04060) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7f9a53ac8750) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16u) + std::runtime_error (0x0x7f9a53ac87b8) 0 + primary-for std::system_error (0x0x7f9a53ac8750) + std::exception (0x0x7f9a53b042a0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f9a53ac87b8) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7f9a53b433a8) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16u) + std::system_error (0x0x7f9a53b43410) 0 + primary-for std::ios_base::failure (0x0x7f9a53b433a8) + std::runtime_error (0x0x7f9a53b43478) 0 + primary-for std::system_error (0x0x7f9a53b43410) + std::exception (0x0x7f9a53b045a0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f9a53b43478) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7f9a53b04600) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7f9a53b04660) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7f9a53b046c0) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7f9a53b04540) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7f9a53b04e40) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7f9a53882540) 0 empty + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSo: 2u entries +0 ((& std::basic_ostream::_ZTVSo) + 24u) +8 ((& std::basic_ostream::_ZTVSo) + 64u) + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSi: 2u entries +0 ((& std::basic_istream::_ZTVSi) + 24u) +8 ((& std::basic_istream::_ZTVSi) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u) + +Construction vtable for std::basic_istream (0x0x7f9a5378c068 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd0_Si: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7f9a5378c3a8 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd16_So: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSd: 7u entries +0 ((& std::basic_iostream::_ZTVSd) + 24u) +8 ((& std::basic_iostream::_ZTCSd0_Si) + 24u) +16 ((& std::basic_iostream::_ZTCSd0_Si) + 64u) +24 ((& std::basic_iostream::_ZTCSd16_So) + 24u) +32 ((& std::basic_iostream::_ZTCSd16_So) + 64u) +40 ((& std::basic_iostream::_ZTVSd) + 104u) +48 ((& std::basic_iostream::_ZTVSd) + 64u) + +Construction vtable for std::basic_istream (0x0x7f9a53840138 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7f9a53840208 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries +0 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u) +16 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u) +24 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u) +32 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u) +40 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u) +48 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u) + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7f9a53a1ad80) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7f9a53a1ade0) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7f9a5358d180) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7f9a5358d4e0) 0 + +Class QStringView + size=16 align=8 + base size=16 base align=8 +QStringView (0x0x7f9a5358d960) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7f9a5329a7e0) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7f9a5329ae40) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7f9a5329ade0) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7f9a5309ef00) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7f9a531b7b40) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7f9a52edb7e0) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7f9a52edb840) 0 empty + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7f9a52edb8a0) 0 + +Class QListData::NotArrayCompatibleLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotArrayCompatibleLayout (0x0x7f9a52edbc60) 0 empty + +Class QListData::NotIndirectLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotIndirectLayout (0x0x7f9a52edbcc0) 0 empty + +Class QListData::ArrayCompatibleLayout + size=1 align=1 + base size=1 base align=1 +QListData::ArrayCompatibleLayout (0x0x7f9a52ed6d00) 0 empty + QListData::NotIndirectLayout (0x0x7f9a52edbd20) 0 empty + +Class QListData::InlineWithPaddingLayout + size=1 align=1 + base size=1 base align=1 +QListData::InlineWithPaddingLayout (0x0x7f9a52d29380) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f9a52edbd80) 0 empty + QListData::NotIndirectLayout (0x0x7f9a52edbde0) 0 empty + +Class QListData::IndirectLayout + size=1 align=1 + base size=1 base align=1 +QListData::IndirectLayout (0x0x7f9a52ed6d68) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f9a52edbe40) 0 empty + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7f9a52edbea0) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7f9a52edbc00) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7f9a52d3d360) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7f9a52ae25a0) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7f9a52ae2540) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7f9a52ae47b8) 0 + QList (0x0x7f9a52ae4820) 0 + QListSpecialMethods (0x0x7f9a52ae2780) 0 empty + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7f9a52ae2ba0) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7f9a52bd2780) 0 + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7f9a52bd2de0) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7f9a52bd2f60) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7f9a529a9060) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7f9a529a8000) 0 + std::__uses_alloc_base (0x0x7f9a529a9000) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7f9a5269d0c0) 0 empty + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7f9a5269d300) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7f9a5269d3c0) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7f9a5269d4e0) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7f9a5269d660) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7f9a5269da80) 0 + +Class QtMetaTypePrivate::VectorBoolElements + size=1 align=1 + base size=0 base align=1 +QtMetaTypePrivate::VectorBoolElements (0x0x7f9a5269dba0) 0 empty + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7f9a52827540) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7f9a52827960) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7f9a52827c60) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7f9a5230d660) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7f9a5205a4e0) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7f9a5205a540) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16u) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7f9a5205a720) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7f9a5205a6c0) 0 + vptr=((& QObject::_ZTV7QObject) + 16u) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7f9a521239c0) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7f9a52123a20) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7f9a52123ae0) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7f9a5214e340) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u) + QObject (0x0x7f9a52123a80) 0 + primary-for QAbstractAnimation (0x0x7f9a5214e340) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7f9a52123ba0) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7f9a5214e3a8) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16u) + QObject (0x0x7f9a52123b40) 0 + primary-for QAnimationDriver (0x0x7f9a5214e3a8) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7f9a52123c60) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7f9a5214e410) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u) + QObject (0x0x7f9a52123c00) 0 + primary-for QEventLoop (0x0x7f9a5214e410) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7f9a52123e40) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7f9a52123f00) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7f9a52123f60) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7f9a5214e548) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u) + QObject (0x0x7f9a52123ea0) 0 + primary-for QAbstractEventDispatcher (0x0x7f9a5214e548) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7f9a521ec240) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16u) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7f9a5214e750) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16u) + std::exception (0x0x7f9a521ec2a0) 0 nearly-empty + primary-for std::bad_cast (0x0x7f9a5214e750) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7f9a5214e7b8) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16u) + std::exception (0x0x7f9a521ec300) 0 nearly-empty + primary-for std::bad_typeid (0x0x7f9a5214e7b8) + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7f9a51eaea28) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16u) + std::exception (0x0x7f9a51f633c0) 0 nearly-empty + primary-for std::bad_function_call (0x0x7f9a51eaea28) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7f9a51f63480) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7f9a51f634e0) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7f9a51f63600) 0 + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7f9a51f63ae0) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7f9a5201f060) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7f9a5201f420) 0 + +Class QHashData + size=48 align=8 + base size=44 base align=8 +QHashData (0x0x7f9a5201f3c0) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7f9a5201f480) 0 empty + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7f9a5201fd20) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7f9a5201fde0) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7f9a5201fd80) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7f9a5201fe40) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7f9a5201fcc0) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7f9a51b17960) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7f9a51bad000) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7f9a51b17f60) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7f9a51bad0c0) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7f9a51bad060) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7f9a518ce3c0) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7f9a518cea80) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7f9a516b51e0) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7f9a516b17b8) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u) + QObject (0x0x7f9a516b5180) 0 + primary-for QAbstractItemModel (0x0x7f9a516b17b8) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7f9a516b5a80) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7f9a516b1ea0) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u) + QAbstractItemModel (0x0x7f9a516b1f08) 0 + primary-for QAbstractTableModel (0x0x7f9a516b1ea0) + QObject (0x0x7f9a516b5a20) 0 + primary-for QAbstractItemModel (0x0x7f9a516b1f08) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7f9a516b5b40) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7f9a516b1f70) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u) + QAbstractItemModel (0x0x7f9a5179b000) 0 + primary-for QAbstractListModel (0x0x7f9a516b1f70) + QObject (0x0x7f9a516b5ae0) 0 + primary-for QAbstractItemModel (0x0x7f9a5179b000) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7f9a516b5de0) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16u) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7f9a516b5ea0) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7f9a5179b138) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16u) + QAbstractItemModel (0x0x7f9a5179b1a0) 0 + primary-for QAbstractProxyModel (0x0x7f9a5179b138) + QObject (0x0x7f9a516b5e40) 0 + primary-for QAbstractItemModel (0x0x7f9a5179b1a0) + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7f9a516b5f60) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7f9a5179b208) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u) + QObject (0x0x7f9a516b5f00) 0 + primary-for QAbstractState (0x0x7f9a5179b208) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7f9a5181b060) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7f9a5179b270) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u) + QObject (0x0x7f9a5181b000) 0 + primary-for QAbstractTransition (0x0x7f9a5179b270) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7f9a5181b120) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7f9a5179b2d8) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u) + QAbstractAnimation (0x0x7f9a5179b340) 0 + primary-for QAnimationGroup (0x0x7f9a5179b2d8) + QObject (0x0x7f9a5181b0c0) 0 + primary-for QAbstractAnimation (0x0x7f9a5179b340) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7f9a5145fe40) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7f9a514a3120) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7f9a514a31e0) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7f9a514a34e0) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7f9a5179b9c0) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16u) + QObject (0x0x7f9a514a3480) 0 + primary-for QIODevice (0x0x7f9a5179b9c0) + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7f9a514a3720) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7f9a5179baf8) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16u) + QIODevice (0x0x7f9a5179bb60) 0 + primary-for QBuffer (0x0x7f9a5179baf8) + QObject (0x0x7f9a514a36c0) 0 + primary-for QIODevice (0x0x7f9a5179bb60) + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7f9a514a37e0) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7f9a514a3780) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7f9a514a3900) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7f9a514a38a0) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7f9a514a3ae0) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7f9a514a3cc0) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7f9a514a3f60) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7f9a51626720) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7f9a51626780) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7f9a516266c0) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7f9a512d88a0) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7f9a512d8ea0) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16u) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7f9a51400180) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7f9a514003c0) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7f9a51400a80) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7f9a51400c00) 0 + +Class QDebug::Stream + size=80 align=8 + base size=76 base align=8 +QDebug::Stream (0x0x7f9a51177180) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7f9a51177120) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7f9a50ee9480) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7f9a50ee9540) 0 empty + +Class QCborError + size=4 align=4 + base size=4 base align=4 +QCborError (0x0x7f9a50f698a0) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7f9a50f69a20) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7f9a50bf6060) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7f9a50bf6360) 0 + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7f9a50bf6720) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7f9a50d3fde0) 0 + +Class QCborParserError + size=16 align=8 + base size=12 base align=8 +QCborParserError (0x0x7f9a50dbf420) 0 + +Class QCborValue + size=24 align=8 + base size=20 base align=8 +QCborValue (0x0x7f9a50dbf480) 0 + +Class QCborValueRef + size=16 align=8 + base size=16 base align=8 +QCborValueRef (0x0x7f9a50823480) 0 + +Class QCborArray::Iterator + size=16 align=8 + base size=16 base align=8 +QCborArray::Iterator (0x0x7f9a50823a20) 0 + +Class QCborArray::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborArray::ConstIterator (0x0x7f9a50823a80) 0 + +Class QCborArray + size=8 align=8 + base size=8 base align=8 +QCborArray (0x0x7f9a508239c0) 0 + +Class QCborMap::Iterator + size=16 align=8 + base size=16 base align=8 +QCborMap::Iterator (0x0x7f9a5096fae0) 0 + +Class QCborMap::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborMap::ConstIterator (0x0x7f9a5096fb40) 0 + +Class QCborMap + size=8 align=8 + base size=8 base align=8 +QCborMap (0x0x7f9a5096fa80) 0 + +Class qfloat16 + size=2 align=2 + base size=2 base align=2 +qfloat16 (0x0x7f9a507156c0) 0 + +Class QCborStreamWriter + size=8 align=8 + base size=8 base align=8 +QCborStreamWriter (0x0x7f9a50715a80) 0 + +Class QCborStreamReader + size=24 align=8 + base size=20 base align=8 +QCborStreamReader (0x0x7f9a5046e480) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7f9a5046eae0) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7f9a5046eba0) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7f9a5058cba0) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7f9a505d9060) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16u) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7f9a505c9138) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u) + QEvent (0x0x7f9a505d90c0) 0 + primary-for QTimerEvent (0x0x7f9a505c9138) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7f9a505c91a0) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u) + QEvent (0x0x7f9a505d9120) 0 + primary-for QChildEvent (0x0x7f9a505c91a0) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7f9a505c96e8) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u) + QEvent (0x0x7f9a505d9600) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7f9a505c96e8) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7f9a505c9750) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16u) + QEvent (0x0x7f9a505d9660) 0 + primary-for QDeferredDeleteEvent (0x0x7f9a505c9750) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7f9a505d9720) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7f9a505c97b8) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u) + QObject (0x0x7f9a505d96c0) 0 + primary-for QCoreApplication (0x0x7f9a505c97b8) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7f9a505d9780) 0 + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7f9a505d97e0) 0 + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7f9a505d9840) 0 + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7f9a505d9900) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7f9a505d9de0) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7f9a502cd300) 0 + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7f9a4fff6180) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7f9a4ffdac30) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16u) + QIODevice (0x0x7f9a4ffdac98) 0 + primary-for QFileDevice (0x0x7f9a4ffdac30) + QObject (0x0x7f9a4fff6120) 0 + primary-for QIODevice (0x0x7f9a4ffdac98) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7f9a4fff63c0) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7f9a4ffdadd0) 0 + vptr=((& QFile::_ZTV5QFile) + 16u) + QFileDevice (0x0x7f9a4ffdae38) 0 + primary-for QFile (0x0x7f9a4ffdadd0) + QIODevice (0x0x7f9a4ffdaea0) 0 + primary-for QFileDevice (0x0x7f9a4ffdae38) + QObject (0x0x7f9a4fff6360) 0 + primary-for QIODevice (0x0x7f9a4ffdaea0) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7f9a4fff65a0) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7f9a4fff69c0) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7f9a50132000) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7f9a50132240) 0 + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7f9a4fdf4660) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7f9a4fde9ea0) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u) + QAbstractTransition (0x0x7f9a4fde9f08) 0 + primary-for QEventTransition (0x0x7f9a4fde9ea0) + QObject (0x0x7f9a4fdf4600) 0 + primary-for QAbstractTransition (0x0x7f9a4fde9f08) + +Vtable for QException +QException::_ZTV10QException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7f9a4fde9f70) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16u) + std::exception (0x0x7f9a4fdf46c0) 0 nearly-empty + primary-for QException (0x0x7f9a4fde9f70) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7f9a4fe66000) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16u) + QException (0x0x7f9a4fe66068) 0 nearly-empty + primary-for QUnhandledException (0x0x7f9a4fe66000) + std::exception (0x0x7f9a4fdf4720) 0 nearly-empty + primary-for QException (0x0x7f9a4fe66068) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7f9a4fdf4780) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7f9a4fdf4840) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7f9a4fdf48a0) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7f9a4fdf49c0) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7f9a4fe660d0) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16u) + QObject (0x0x7f9a4fdf4960) 0 + primary-for QFileSelector (0x0x7f9a4fe660d0) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7f9a4fdf4a80) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7f9a4fe66138) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u) + QObject (0x0x7f9a4fdf4a20) 0 + primary-for QFileSystemWatcher (0x0x7f9a4fe66138) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7f9a4fdf4b40) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7f9a4fe661a0) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16u) + QAbstractState (0x0x7f9a4fe66208) 0 + primary-for QFinalState (0x0x7f9a4fe661a0) + QObject (0x0x7f9a4fdf4ae0) 0 + primary-for QAbstractState (0x0x7f9a4fe66208) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7f9a4fdf4ba0) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16u) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7f9a4fdf4c00) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7f9a4fe66340) 0 + QBasicMutex (0x0x7f9a4fdf4de0) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7f9a4fdf4e40) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7f9a4fdf4ea0) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7f9a4fdf4f00) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7f9a4ff75060) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16u) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7f9a4ff758a0) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7f9a4fc400c0) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0u +48 0u +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7f9a4fc1f478) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u) + QObject (0x0x7f9a4fc40060) 0 + primary-for QFutureWatcherBase (0x0x7f9a4fc1f478) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7f9a4fc406c0) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7f9a4fc1fd68) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u) + QAbstractState (0x0x7f9a4fc1fdd0) 0 + primary-for QHistoryState (0x0x7f9a4fc1fd68) + QObject (0x0x7f9a4fc40660) 0 + primary-for QAbstractState (0x0x7f9a4fc1fdd0) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7f9a4fc40780) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7f9a4fc1fe38) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16u) + QAbstractProxyModel (0x0x7f9a4fc1fea0) 0 + primary-for QIdentityProxyModel (0x0x7f9a4fc1fe38) + QAbstractItemModel (0x0x7f9a4fc1ff08) 0 + primary-for QAbstractProxyModel (0x0x7f9a4fc1fea0) + QObject (0x0x7f9a4fc40720) 0 + primary-for QAbstractItemModel (0x0x7f9a4fc1ff08) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7f9a4fc407e0) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7f9a4fc40ea0) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7f9a4fcc9750) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u) + QObject (0x0x7f9a4fc40e40) 0 + primary-for QItemSelectionModel (0x0x7f9a4fcc9750) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7f9a4fcc9958) 0 + QList (0x0x7f9a4fcc99c0) 0 + QListSpecialMethods (0x0x7f9a4fd231e0) 0 empty + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7f9a4fd236c0) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7f9a4fadcde0) 0 + +Class QJsonValuePtr + size=24 align=8 + base size=24 base align=8 +QJsonValuePtr (0x0x7f9a4fb53360) 0 + +Class QJsonValueRefPtr + size=16 align=8 + base size=16 base align=8 +QJsonValueRefPtr (0x0x7f9a4fb533c0) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7f9a4fb535a0) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7f9a4fb53600) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7f9a4fb53540) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7f9a4f81a840) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7f9a4f81a8a0) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7f9a4f81af00) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7f9a4f81af60) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7f9a4f81aea0) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7f9a4f97e240) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7f9a4f93bd00) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16u) + QObject (0x0x7f9a4f97e1e0) 0 + primary-for QLibrary (0x0x7f9a4f93bd00) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7f9a4f97e900) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7f9a4f97e420) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7f9a4f97ede0) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7f9a4f97ee40) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7f9a4f65a120) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7f9a4f65a720) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7f9a4f6eb0c0) 0 + +Class QLinkedListData + size=32 align=8 + base size=25 base align=8 +QLinkedListData (0x0x7f9a4f6eb6c0) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7f9a4f6eba20) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7f9a4f6ebba0) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7f9a4f6ebb40) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7f9a4f6ebd20) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7f9a4f4aa000) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7f9a4f4aa660) 0 + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7f9a4f4aa6c0) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7f9a4f4aacc0) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7f9a4f55d000) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7f9a4f55d060) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7f9a4f55d360) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7f9a4f4b6f70) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16u) + QObject (0x0x7f9a4f55d300) 0 + primary-for QMimeData (0x0x7f9a4f4b6f70) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7f9a4f55d3c0) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7f9a4f55d6c0) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7f9a4f55d780) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7f9a4f5a21a0) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u) + QObject (0x0x7f9a4f55d720) 0 + primary-for QObjectCleanupHandler (0x0x7f9a4f5a21a0) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7f9a4f55d7e0) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7f9a4f55df60) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7f9a4f5a28f0) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u) + QAnimationGroup (0x0x7f9a4f5a2958) 0 + primary-for QParallelAnimationGroup (0x0x7f9a4f5a28f0) + QAbstractAnimation (0x0x7f9a4f5a29c0) 0 + primary-for QAnimationGroup (0x0x7f9a4f5a2958) + QObject (0x0x7f9a4f55df00) 0 + primary-for QAbstractAnimation (0x0x7f9a4f5a29c0) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7f9a4f201060) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7f9a4f5a2a28) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u) + QAbstractAnimation (0x0x7f9a4f5a2a90) 0 + primary-for QPauseAnimation (0x0x7f9a4f5a2a28) + QObject (0x0x7f9a4f201000) 0 + primary-for QAbstractAnimation (0x0x7f9a4f5a2a90) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7f9a4f201240) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7f9a4f201540) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7f9a4f5a2c98) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u) + QObject (0x0x7f9a4f2014e0) 0 + primary-for QPluginLoader (0x0x7f9a4f5a2c98) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7f9a4f2015a0) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7f9a4f201c60) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7f9a4f2582d8) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16u) + QIODevice (0x0x7f9a4f258340) 0 + primary-for QProcess (0x0x7f9a4f2582d8) + QObject (0x0x7f9a4f201c00) 0 + primary-for QIODevice (0x0x7f9a4f258340) + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7f9a4f201d20) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7f9a4f2583a8) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u) + QAbstractAnimation (0x0x7f9a4f258410) 0 + primary-for QVariantAnimation (0x0x7f9a4f2583a8) + QObject (0x0x7f9a4f201cc0) 0 + primary-for QAbstractAnimation (0x0x7f9a4f258410) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7f9a4f201de0) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7f9a4f2584e0) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u) + QVariantAnimation (0x0x7f9a4f258548) 0 + primary-for QPropertyAnimation (0x0x7f9a4f2584e0) + QAbstractAnimation (0x0x7f9a4f2585b0) 0 + primary-for QVariantAnimation (0x0x7f9a4f258548) + QObject (0x0x7f9a4f201d80) 0 + primary-for QAbstractAnimation (0x0x7f9a4f2585b0) + +Class QRandomGenerator::Storage + size=2504 align=8 + base size=2504 base align=8 +QRandomGenerator::Storage (0x0x7f9a4f201f00) 0 + +Class QRandomGenerator + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator (0x0x7f9a4f201ea0) 0 + +Class QRandomGenerator64 + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator64 (0x0x7f9a4f33b888) 0 + QRandomGenerator (0x0x7f9a4f329ea0) 0 + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7f9a4f329f60) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7f9a4f388240) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7f9a4f388300) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7f9a4f3883c0) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7f9a4f388660) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7f9a4f388900) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7f9a4f388ba0) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7f9a4f388e40) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7f9a4edcc000) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7f9a4f087410) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16u) + QFileDevice (0x0x7f9a4f087478) 0 + primary-for QSaveFile (0x0x7f9a4f087410) + QIODevice (0x0x7f9a4f0874e0) 0 + primary-for QFileDevice (0x0x7f9a4f087478) + QObject (0x0x7f9a4f388f60) 0 + primary-for QIODevice (0x0x7f9a4f0874e0) + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7f9a4edcc120) 0 + +Class QSemaphoreReleaser + size=16 align=8 + base size=12 base align=8 +QSemaphoreReleaser (0x0x7f9a4edcc2a0) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7f9a4ef0a8a0) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7f9a4ef04d68) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u) + QAnimationGroup (0x0x7f9a4ef04dd0) 0 + primary-for QSequentialAnimationGroup (0x0x7f9a4ef04d68) + QAbstractAnimation (0x0x7f9a4ef04e38) 0 + primary-for QAnimationGroup (0x0x7f9a4ef04dd0) + QObject (0x0x7f9a4ef0a840) 0 + primary-for QAbstractAnimation (0x0x7f9a4ef04e38) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7f9a4ef0a960) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7f9a4ef04ea0) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16u) + QObject (0x0x7f9a4ef0a900) 0 + primary-for QSettings (0x0x7f9a4ef04ea0) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7f9a4ef0aa20) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7f9a4ef04f08) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u) + QObject (0x0x7f9a4ef0a9c0) 0 + primary-for QSharedMemory (0x0x7f9a4ef04f08) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7f9a4ef0aae0) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7f9a4ef04f70) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u) + QObject (0x0x7f9a4ef0aa80) 0 + primary-for QSignalMapper (0x0x7f9a4ef04f70) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7f9a4ef0aba0) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7f9a4ef72000) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u) + QAbstractTransition (0x0x7f9a4ef72068) 0 + primary-for QSignalTransition (0x0x7f9a4ef72000) + QObject (0x0x7f9a4ef0ab40) 0 + primary-for QAbstractTransition (0x0x7f9a4ef72068) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7f9a4ef0ac60) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7f9a4ef720d0) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u) + QObject (0x0x7f9a4ef0ac00) 0 + primary-for QSocketNotifier (0x0x7f9a4ef720d0) + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7f9a4ef0ad20) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7f9a4ef72138) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16u) + QAbstractProxyModel (0x0x7f9a4ef721a0) 0 + primary-for QSortFilterProxyModel (0x0x7f9a4ef72138) + QAbstractItemModel (0x0x7f9a4ef72208) 0 + primary-for QAbstractProxyModel (0x0x7f9a4ef721a0) + QObject (0x0x7f9a4ef0acc0) 0 + primary-for QAbstractItemModel (0x0x7f9a4ef72208) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7f9a4ef0ade0) 0 empty + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7f9a4ebfa060) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7f9a4ef723a8) 0 + vptr=((& QState::_ZTV6QState) + 16u) + QAbstractState (0x0x7f9a4ef72410) 0 + primary-for QState (0x0x7f9a4ef723a8) + QObject (0x0x7f9a4ebfa000) 0 + primary-for QAbstractState (0x0x7f9a4ef72410) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7f9a4ebfa180) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7f9a4ef725b0) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u) + QEvent (0x0x7f9a4ebfa1e0) 0 + primary-for QStateMachine::SignalEvent (0x0x7f9a4ef725b0) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7f9a4ef72618) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u) + QEvent (0x0x7f9a4ebfa240) 0 + primary-for QStateMachine::WrappedEvent (0x0x7f9a4ef72618) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7f9a4ef72478) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u) + QState (0x0x7f9a4ef724e0) 0 + primary-for QStateMachine (0x0x7f9a4ef72478) + QAbstractState (0x0x7f9a4ef72548) 0 + primary-for QState (0x0x7f9a4ef724e0) + QObject (0x0x7f9a4ebfa120) 0 + primary-for QAbstractState (0x0x7f9a4ef72548) + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7f9a4ebfa2a0) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7f9a4ec891e0) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7f9a4ed0e5a0) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7f9a4ed11618) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u) + QAbstractListModel (0x0x7f9a4ed11680) 0 + primary-for QStringListModel (0x0x7f9a4ed11618) + QAbstractItemModel (0x0x7f9a4ed116e8) 0 + primary-for QAbstractListModel (0x0x7f9a4ed11680) + QObject (0x0x7f9a4ed0e540) 0 + primary-for QAbstractItemModel (0x0x7f9a4ed116e8) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7f9a4ed0e600) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7f9a4ed0e6c0) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7f9a4ed0e7e0) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7f9a4ed11750) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u) + QFile (0x0x7f9a4ed117b8) 0 + primary-for QTemporaryFile (0x0x7f9a4ed11750) + QFileDevice (0x0x7f9a4ed11820) 0 + primary-for QFile (0x0x7f9a4ed117b8) + QIODevice (0x0x7f9a4ed11888) 0 + primary-for QFileDevice (0x0x7f9a4ed11820) + QObject (0x0x7f9a4ed0e780) 0 + primary-for QIODevice (0x0x7f9a4ed11888) + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7f9a4ed0e840) 0 + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7f9a4ed0ea80) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 0u +64 0u + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7f9a4ed0ea20) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7f9a4ed0ec60) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7f9a4ed0ecc0) 0 + +Class std::__mutex_base + size=40 align=8 + base size=40 base align=8 +std::__mutex_base (0x0x7f9a4ed0ed20) 0 + +Class std::__recursive_mutex_base + size=40 align=8 + base size=40 base align=8 +std::__recursive_mutex_base (0x0x7f9a4ed0ed80) 0 + +Class std::mutex + size=40 align=8 + base size=40 base align=8 +std::mutex (0x0x7f9a4ed11a90) 0 + std::__mutex_base (0x0x7f9a4ed0ede0) 0 + +Class std::recursive_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_mutex (0x0x7f9a4ed11af8) 0 + std::__recursive_mutex_base (0x0x7f9a4ed0ee40) 0 + +Class std::timed_mutex + size=40 align=8 + base size=40 base align=8 +std::timed_mutex (0x0x7f9a4ea17460) 0 + std::__mutex_base (0x0x7f9a4ed0ef60) 0 + std::__timed_mutex_impl (0x0x7f9a4ea23000) 0 empty + +Class std::recursive_timed_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_timed_mutex (0x0x7f9a4ea17e00) 0 + std::__recursive_mutex_base (0x0x7f9a4ea230c0) 0 + std::__timed_mutex_impl (0x0x7f9a4ea23120) 0 empty + +Class std::defer_lock_t + size=1 align=1 + base size=0 base align=1 +std::defer_lock_t (0x0x7f9a4ea23180) 0 empty + +Class std::try_to_lock_t + size=1 align=1 + base size=0 base align=1 +std::try_to_lock_t (0x0x7f9a4ea231e0) 0 empty + +Class std::adopt_lock_t + size=1 align=1 + base size=0 base align=1 +std::adopt_lock_t (0x0x7f9a4ea23240) 0 empty + +Class std::once_flag + size=4 align=4 + base size=4 base align=4 +std::once_flag (0x0x7f9a4ea23480) 0 + +Vtable for __gnu_cxx::__concurrence_lock_error +__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what + +Class __gnu_cxx::__concurrence_lock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_lock_error (0x0x7f9a4ed11c30) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16u) + std::exception (0x0x7f9a4ea23540) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_lock_error (0x0x7f9a4ed11c30) + +Vtable for __gnu_cxx::__concurrence_unlock_error +__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what + +Class __gnu_cxx::__concurrence_unlock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_unlock_error (0x0x7f9a4ed11c98) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16u) + std::exception (0x0x7f9a4ea23600) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7f9a4ed11c98) + +Vtable for __gnu_cxx::__concurrence_broadcast_error +__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what + +Class __gnu_cxx::__concurrence_broadcast_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_broadcast_error (0x0x7f9a4ed11d00) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16u) + std::exception (0x0x7f9a4ea236c0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7f9a4ed11d00) + +Vtable for __gnu_cxx::__concurrence_wait_error +__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what + +Class __gnu_cxx::__concurrence_wait_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_wait_error (0x0x7f9a4ed11dd0) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16u) + std::exception (0x0x7f9a4ea23780) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_wait_error (0x0x7f9a4ed11dd0) + +Class __gnu_cxx::__mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__mutex (0x0x7f9a4ea23840) 0 + +Class __gnu_cxx::__recursive_mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__recursive_mutex (0x0x7f9a4ea238a0) 0 + +Class __gnu_cxx::__scoped_lock + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__scoped_lock (0x0x7f9a4ea23900) 0 + +Class __gnu_cxx::__cond + size=48 align=8 + base size=48 base align=8 +__gnu_cxx::__cond (0x0x7f9a4ea23960) 0 + +Vtable for std::bad_weak_ptr +std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12bad_weak_ptr) +16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +32 (int (*)(...))std::bad_weak_ptr::what + +Class std::bad_weak_ptr + size=8 align=8 + base size=8 base align=8 +std::bad_weak_ptr (0x0x7f9a4ed11f08) 0 nearly-empty + vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16u) + std::exception (0x0x7f9a4ea23cc0) 0 nearly-empty + primary-for std::bad_weak_ptr (0x0x7f9a4ed11f08) + +Class std::_Sp_make_shared_tag + size=1 align=1 + base size=0 base align=1 +std::_Sp_make_shared_tag (0x0x7f9a4eb78540) 0 empty + +Class std::_Sp_locker + size=2 align=1 + base size=2 base align=1 +std::_Sp_locker (0x0x7f9a4eb78d20) 0 + +Class std::thread::id + size=8 align=8 + base size=8 base align=8 +std::thread::id (0x0x7f9a4eb78f00) 0 + +Vtable for std::thread::_Impl_base +std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6thread10_Impl_baseE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class std::thread::_Impl_base + size=24 align=8 + base size=24 base align=8 +std::thread::_Impl_base (0x0x7f9a4eb78f60) 0 + vptr=((& std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE) + 16u) + +Class std::thread + size=8 align=8 + base size=8 base align=8 +std::thread (0x0x7f9a4eb78ea0) 0 + +Class std::condition_variable + size=48 align=8 + base size=48 base align=8 +std::condition_variable (0x0x7f9a4e61aba0) 0 + +Class std::__at_thread_exit_elt + size=16 align=8 + base size=16 base align=8 +std::__at_thread_exit_elt (0x0x7f9a4e61ac60) 0 + +Class std::_V2::condition_variable_any + size=64 align=8 + base size=64 base align=8 +std::_V2::condition_variable_any (0x0x7f9a4e61acc0) 0 + +Class std::__atomic_futex_unsigned_base + size=1 align=1 + base size=0 base align=1 +std::__atomic_futex_unsigned_base (0x0x7f9a4e705360) 0 empty + +Vtable for std::future_error +std::future_error::_ZTVSt12future_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12future_error) +16 (int (*)(...))std::future_error::~future_error +24 (int (*)(...))std::future_error::~future_error +32 (int (*)(...))std::future_error::what + +Class std::future_error + size=32 align=8 + base size=32 base align=8 +std::future_error (0x0x7f9a4e706410) 0 + vptr=((& std::future_error::_ZTVSt12future_error) + 16u) + std::logic_error (0x0x7f9a4e706478) 0 + primary-for std::future_error (0x0x7f9a4e706410) + std::exception (0x0x7f9a4e705480) 0 nearly-empty + primary-for std::logic_error (0x0x7f9a4e706478) + +Class std::__future_base::_Result_base::_Deleter + size=1 align=1 + base size=0 base align=1 +std::__future_base::_Result_base::_Deleter (0x0x7f9a4e7055a0) 0 empty + +Vtable for std::__future_base::_Result_base +std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class std::__future_base::_Result_base + size=16 align=8 + base size=16 base align=8 +std::__future_base::_Result_base (0x0x7f9a4e705540) 0 + vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16u) + +Class std::__future_base::_State_baseV2::__exception_ptr_tag + size=1 align=1 + base size=0 base align=1 +std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7f9a4e462ae0) 0 empty + +Class std::__future_base::_State_baseV2::_Make_ready + size=32 align=8 + base size=32 base align=8 +std::__future_base::_State_baseV2::_Make_ready (0x0x7f9a4e461a28) 0 + std::__at_thread_exit_elt (0x0x7f9a4e462ba0) 0 + +Vtable for std::__future_base::_State_baseV2 +std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E) +16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_State_baseV2 + size=32 align=8 + base size=28 base align=8 +std::__future_base::_State_baseV2 (0x0x7f9a4e705720) 0 + vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16u) + +Class std::__future_base + size=1 align=1 + base size=0 base align=1 +std::__future_base (0x0x7f9a4e7054e0) 0 empty + +Vtable for std::__future_base::_Async_state_commonV2 +std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E) +16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_Async_state_commonV2 + size=48 align=8 + base size=44 base align=8 +std::__future_base::_Async_state_commonV2 (0x0x7f9a4ddde618) 0 + vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16u) + std::__future_base::_State_baseV2 (0x0x7f9a4ddd8a80) 0 + primary-for std::__future_base::_Async_state_commonV2 (0x0x7f9a4ddde618) + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7f9a4de541e0) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7f9a4de620d0) 0 + vptr=((& QThread::_ZTV7QThread) + 16u) + QObject (0x0x7f9a4de54180) 0 + primary-for QThread (0x0x7f9a4de620d0) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7f9a4de54300) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7f9a4de62138) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u) + QObject (0x0x7f9a4de542a0) 0 + primary-for QThreadPool (0x0x7f9a4de62138) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7f9a4de54360) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7f9a4de54480) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7f9a4de621a0) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u) + QObject (0x0x7f9a4de54420) 0 + primary-for QTimeLine (0x0x7f9a4de621a0) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7f9a4de54540) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7f9a4de62208) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16u) + QObject (0x0x7f9a4de544e0) 0 + primary-for QTimer (0x0x7f9a4de62208) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7f9a4de54c60) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7f9a4de54c00) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7f9a4df2a240) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7f9a4de62dd0) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16u) + QObject (0x0x7f9a4df2a1e0) 0 + primary-for QTranslator (0x0x7f9a4de62dd0) + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7f9a4df2a2a0) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7f9a4df2a900) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7f9a4df2a960) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7f9a4df2ac00) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7f9a4df64a90) 0 + QVector (0x0x7f9a4dc09000) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7f9a4dc09060) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7f9a4dc09300) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7f9a4dc095a0) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7f9a4dc09840) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7f9a4dc098a0) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7f9a4dcdb300) 0 + +Class QRgba64 + size=8 align=8 + base size=8 base align=8 +QRgba64 (0x0x7f9a4dcdb420) 0 + +Class QColor + size=16 align=4 + base size=14 base align=4 +QColor (0x0x7f9a4dcdb6c0) 0 + +Class QRegion::QRegionData + size=16 align=8 + base size=16 base align=8 +QRegion::QRegionData (0x0x7f9a4d9eb0c0) 0 + +Class QRegion + size=8 align=8 + base size=8 base align=8 +QRegion (0x0x7f9a4d9eb060) 0 + +Class QKeySequence + size=8 align=8 + base size=8 base align=8 +QKeySequence (0x0x7f9a4da8e420) 0 + +Class QVector2D + size=8 align=4 + base size=8 base align=4 +QVector2D (0x0x7f9a4db36960) 0 + +Class QTouchDevice + size=8 align=8 + base size=8 base align=8 +QTouchDevice (0x0x7f9a4db36c00) 0 + +Vtable for QInputEvent +QInputEvent::_ZTV11QInputEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QInputEvent) +16 (int (*)(...))QInputEvent::~QInputEvent +24 (int (*)(...))QInputEvent::~QInputEvent + +Class QInputEvent + size=32 align=8 + base size=32 base align=8 +QInputEvent (0x0x7f9a4db45888) 0 + vptr=((& QInputEvent::_ZTV11QInputEvent) + 16u) + QEvent (0x0x7f9a4db36de0) 0 + primary-for QInputEvent (0x0x7f9a4db45888) + +Vtable for QEnterEvent +QEnterEvent::_ZTV11QEnterEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QEnterEvent) +16 (int (*)(...))QEnterEvent::~QEnterEvent +24 (int (*)(...))QEnterEvent::~QEnterEvent + +Class QEnterEvent + size=72 align=8 + base size=72 base align=8 +QEnterEvent (0x0x7f9a4db458f0) 0 + vptr=((& QEnterEvent::_ZTV11QEnterEvent) + 16u) + QEvent (0x0x7f9a4db36e40) 0 + primary-for QEnterEvent (0x0x7f9a4db458f0) + +Vtable for QMouseEvent +QMouseEvent::_ZTV11QMouseEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QMouseEvent) +16 (int (*)(...))QMouseEvent::~QMouseEvent +24 (int (*)(...))QMouseEvent::~QMouseEvent + +Class QMouseEvent + size=104 align=8 + base size=100 base align=8 +QMouseEvent (0x0x7f9a4db45958) 0 + vptr=((& QMouseEvent::_ZTV11QMouseEvent) + 16u) + QInputEvent (0x0x7f9a4db459c0) 0 + primary-for QMouseEvent (0x0x7f9a4db45958) + QEvent (0x0x7f9a4db36ea0) 0 + primary-for QInputEvent (0x0x7f9a4db459c0) + +Vtable for QHoverEvent +QHoverEvent::_ZTV11QHoverEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QHoverEvent) +16 (int (*)(...))QHoverEvent::~QHoverEvent +24 (int (*)(...))QHoverEvent::~QHoverEvent + +Class QHoverEvent + size=64 align=8 + base size=64 base align=8 +QHoverEvent (0x0x7f9a4db45a28) 0 + vptr=((& QHoverEvent::_ZTV11QHoverEvent) + 16u) + QInputEvent (0x0x7f9a4db45a90) 0 + primary-for QHoverEvent (0x0x7f9a4db45a28) + QEvent (0x0x7f9a4db36f00) 0 + primary-for QInputEvent (0x0x7f9a4db45a90) + +Vtable for QWheelEvent +QWheelEvent::_ZTV11QWheelEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QWheelEvent) +16 (int (*)(...))QWheelEvent::~QWheelEvent +24 (int (*)(...))QWheelEvent::~QWheelEvent + +Class QWheelEvent + size=96 align=8 + base size=96 base align=8 +QWheelEvent (0x0x7f9a4db45af8) 0 + vptr=((& QWheelEvent::_ZTV11QWheelEvent) + 16u) + QInputEvent (0x0x7f9a4db45b60) 0 + primary-for QWheelEvent (0x0x7f9a4db45af8) + QEvent (0x0x7f9a4db36f60) 0 + primary-for QInputEvent (0x0x7f9a4db45b60) + +Vtable for QTabletEvent +QTabletEvent::_ZTV12QTabletEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QTabletEvent) +16 (int (*)(...))QTabletEvent::~QTabletEvent +24 (int (*)(...))QTabletEvent::~QTabletEvent + +Class QTabletEvent + size=128 align=8 + base size=128 base align=8 +QTabletEvent (0x0x7f9a4db45bc8) 0 + vptr=((& QTabletEvent::_ZTV12QTabletEvent) + 16u) + QInputEvent (0x0x7f9a4db45c30) 0 + primary-for QTabletEvent (0x0x7f9a4db45bc8) + QEvent (0x0x7f9a4d830000) 0 + primary-for QInputEvent (0x0x7f9a4db45c30) + +Vtable for QNativeGestureEvent +QNativeGestureEvent::_ZTV19QNativeGestureEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QNativeGestureEvent) +16 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent +24 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent + +Class QNativeGestureEvent + size=112 align=8 + base size=112 base align=8 +QNativeGestureEvent (0x0x7f9a4db45c98) 0 + vptr=((& QNativeGestureEvent::_ZTV19QNativeGestureEvent) + 16u) + QInputEvent (0x0x7f9a4db45d00) 0 + primary-for QNativeGestureEvent (0x0x7f9a4db45c98) + QEvent (0x0x7f9a4d830060) 0 + primary-for QInputEvent (0x0x7f9a4db45d00) + +Vtable for QKeyEvent +QKeyEvent::_ZTV9QKeyEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QKeyEvent) +16 (int (*)(...))QKeyEvent::~QKeyEvent +24 (int (*)(...))QKeyEvent::~QKeyEvent + +Class QKeyEvent + size=64 align=8 + base size=59 base align=8 +QKeyEvent (0x0x7f9a4db45d68) 0 + vptr=((& QKeyEvent::_ZTV9QKeyEvent) + 16u) + QInputEvent (0x0x7f9a4db45dd0) 0 + primary-for QKeyEvent (0x0x7f9a4db45d68) + QEvent (0x0x7f9a4d8300c0) 0 + primary-for QInputEvent (0x0x7f9a4db45dd0) + +Vtable for QFocusEvent +QFocusEvent::_ZTV11QFocusEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFocusEvent) +16 (int (*)(...))QFocusEvent::~QFocusEvent +24 (int (*)(...))QFocusEvent::~QFocusEvent + +Class QFocusEvent + size=24 align=8 + base size=24 base align=8 +QFocusEvent (0x0x7f9a4db45e38) 0 + vptr=((& QFocusEvent::_ZTV11QFocusEvent) + 16u) + QEvent (0x0x7f9a4d830120) 0 + primary-for QFocusEvent (0x0x7f9a4db45e38) + +Vtable for QPaintEvent +QPaintEvent::_ZTV11QPaintEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QPaintEvent) +16 (int (*)(...))QPaintEvent::~QPaintEvent +24 (int (*)(...))QPaintEvent::~QPaintEvent + +Class QPaintEvent + size=56 align=8 + base size=49 base align=8 +QPaintEvent (0x0x7f9a4db45ea0) 0 + vptr=((& QPaintEvent::_ZTV11QPaintEvent) + 16u) + QEvent (0x0x7f9a4d830180) 0 + primary-for QPaintEvent (0x0x7f9a4db45ea0) + +Vtable for QMoveEvent +QMoveEvent::_ZTV10QMoveEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QMoveEvent) +16 (int (*)(...))QMoveEvent::~QMoveEvent +24 (int (*)(...))QMoveEvent::~QMoveEvent + +Class QMoveEvent + size=40 align=8 + base size=36 base align=8 +QMoveEvent (0x0x7f9a4db45f08) 0 + vptr=((& QMoveEvent::_ZTV10QMoveEvent) + 16u) + QEvent (0x0x7f9a4d8301e0) 0 + primary-for QMoveEvent (0x0x7f9a4db45f08) + +Vtable for QExposeEvent +QExposeEvent::_ZTV12QExposeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QExposeEvent) +16 (int (*)(...))QExposeEvent::~QExposeEvent +24 (int (*)(...))QExposeEvent::~QExposeEvent + +Class QExposeEvent + size=32 align=8 + base size=32 base align=8 +QExposeEvent (0x0x7f9a4db45f70) 0 + vptr=((& QExposeEvent::_ZTV12QExposeEvent) + 16u) + QEvent (0x0x7f9a4d830240) 0 + primary-for QExposeEvent (0x0x7f9a4db45f70) + +Vtable for QPlatformSurfaceEvent +QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QPlatformSurfaceEvent) +16 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent +24 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent + +Class QPlatformSurfaceEvent + size=24 align=8 + base size=24 base align=8 +QPlatformSurfaceEvent (0x0x7f9a4d88a000) 0 + vptr=((& QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent) + 16u) + QEvent (0x0x7f9a4d8302a0) 0 + primary-for QPlatformSurfaceEvent (0x0x7f9a4d88a000) + +Vtable for QResizeEvent +QResizeEvent::_ZTV12QResizeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QResizeEvent) +16 (int (*)(...))QResizeEvent::~QResizeEvent +24 (int (*)(...))QResizeEvent::~QResizeEvent + +Class QResizeEvent + size=40 align=8 + base size=36 base align=8 +QResizeEvent (0x0x7f9a4d88a068) 0 + vptr=((& QResizeEvent::_ZTV12QResizeEvent) + 16u) + QEvent (0x0x7f9a4d830300) 0 + primary-for QResizeEvent (0x0x7f9a4d88a068) + +Vtable for QCloseEvent +QCloseEvent::_ZTV11QCloseEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QCloseEvent) +16 (int (*)(...))QCloseEvent::~QCloseEvent +24 (int (*)(...))QCloseEvent::~QCloseEvent + +Class QCloseEvent + size=24 align=8 + base size=20 base align=8 +QCloseEvent (0x0x7f9a4d88a0d0) 0 + vptr=((& QCloseEvent::_ZTV11QCloseEvent) + 16u) + QEvent (0x0x7f9a4d830360) 0 + primary-for QCloseEvent (0x0x7f9a4d88a0d0) + +Vtable for QIconDragEvent +QIconDragEvent::_ZTV14QIconDragEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QIconDragEvent) +16 (int (*)(...))QIconDragEvent::~QIconDragEvent +24 (int (*)(...))QIconDragEvent::~QIconDragEvent + +Class QIconDragEvent + size=24 align=8 + base size=20 base align=8 +QIconDragEvent (0x0x7f9a4d88a138) 0 + vptr=((& QIconDragEvent::_ZTV14QIconDragEvent) + 16u) + QEvent (0x0x7f9a4d8303c0) 0 + primary-for QIconDragEvent (0x0x7f9a4d88a138) + +Vtable for QShowEvent +QShowEvent::_ZTV10QShowEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QShowEvent) +16 (int (*)(...))QShowEvent::~QShowEvent +24 (int (*)(...))QShowEvent::~QShowEvent + +Class QShowEvent + size=24 align=8 + base size=20 base align=8 +QShowEvent (0x0x7f9a4d88a1a0) 0 + vptr=((& QShowEvent::_ZTV10QShowEvent) + 16u) + QEvent (0x0x7f9a4d830420) 0 + primary-for QShowEvent (0x0x7f9a4d88a1a0) + +Vtable for QHideEvent +QHideEvent::_ZTV10QHideEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QHideEvent) +16 (int (*)(...))QHideEvent::~QHideEvent +24 (int (*)(...))QHideEvent::~QHideEvent + +Class QHideEvent + size=24 align=8 + base size=20 base align=8 +QHideEvent (0x0x7f9a4d88a208) 0 + vptr=((& QHideEvent::_ZTV10QHideEvent) + 16u) + QEvent (0x0x7f9a4d830480) 0 + primary-for QHideEvent (0x0x7f9a4d88a208) + +Vtable for QContextMenuEvent +QContextMenuEvent::_ZTV17QContextMenuEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QContextMenuEvent) +16 (int (*)(...))QContextMenuEvent::~QContextMenuEvent +24 (int (*)(...))QContextMenuEvent::~QContextMenuEvent + +Class QContextMenuEvent + size=56 align=8 + base size=49 base align=8 +QContextMenuEvent (0x0x7f9a4d88a270) 0 + vptr=((& QContextMenuEvent::_ZTV17QContextMenuEvent) + 16u) + QInputEvent (0x0x7f9a4d88a2d8) 0 + primary-for QContextMenuEvent (0x0x7f9a4d88a270) + QEvent (0x0x7f9a4d8304e0) 0 + primary-for QInputEvent (0x0x7f9a4d88a2d8) + +Class QInputMethodEvent::Attribute + size=32 align=8 + base size=32 base align=8 +QInputMethodEvent::Attribute (0x0x7f9a4d8305a0) 0 + +Vtable for QInputMethodEvent +QInputMethodEvent::_ZTV17QInputMethodEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QInputMethodEvent) +16 (int (*)(...))QInputMethodEvent::~QInputMethodEvent +24 (int (*)(...))QInputMethodEvent::~QInputMethodEvent + +Class QInputMethodEvent + size=56 align=8 + base size=56 base align=8 +QInputMethodEvent (0x0x7f9a4d88a340) 0 + vptr=((& QInputMethodEvent::_ZTV17QInputMethodEvent) + 16u) + QEvent (0x0x7f9a4d830540) 0 + primary-for QInputMethodEvent (0x0x7f9a4d88a340) + +Class QInputMethodQueryEvent::QueryPair + size=24 align=8 + base size=24 base align=8 +QInputMethodQueryEvent::QueryPair (0x0x7f9a4d830a20) 0 + +Vtable for QInputMethodQueryEvent +QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QInputMethodQueryEvent) +16 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent +24 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent + +Class QInputMethodQueryEvent + size=32 align=8 + base size=32 base align=8 +QInputMethodQueryEvent (0x0x7f9a4d88a680) 0 + vptr=((& QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent) + 16u) + QEvent (0x0x7f9a4d8309c0) 0 + primary-for QInputMethodQueryEvent (0x0x7f9a4d88a680) + +Vtable for QDropEvent +QDropEvent::_ZTV10QDropEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QDropEvent) +16 (int (*)(...))QDropEvent::~QDropEvent +24 (int (*)(...))QDropEvent::~QDropEvent + +Class QDropEvent + size=72 align=8 + base size=72 base align=8 +QDropEvent (0x0x7f9a4d88a958) 0 + vptr=((& QDropEvent::_ZTV10QDropEvent) + 16u) + QEvent (0x0x7f9a4d830d80) 0 + primary-for QDropEvent (0x0x7f9a4d88a958) + +Vtable for QDragMoveEvent +QDragMoveEvent::_ZTV14QDragMoveEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QDragMoveEvent) +16 (int (*)(...))QDragMoveEvent::~QDragMoveEvent +24 (int (*)(...))QDragMoveEvent::~QDragMoveEvent + +Class QDragMoveEvent + size=88 align=8 + base size=88 base align=8 +QDragMoveEvent (0x0x7f9a4d88a9c0) 0 + vptr=((& QDragMoveEvent::_ZTV14QDragMoveEvent) + 16u) + QDropEvent (0x0x7f9a4d88aa28) 0 + primary-for QDragMoveEvent (0x0x7f9a4d88a9c0) + QEvent (0x0x7f9a4d830de0) 0 + primary-for QDropEvent (0x0x7f9a4d88aa28) + +Vtable for QDragEnterEvent +QDragEnterEvent::_ZTV15QDragEnterEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QDragEnterEvent) +16 (int (*)(...))QDragEnterEvent::~QDragEnterEvent +24 (int (*)(...))QDragEnterEvent::~QDragEnterEvent + +Class QDragEnterEvent + size=88 align=8 + base size=88 base align=8 +QDragEnterEvent (0x0x7f9a4d88aa90) 0 + vptr=((& QDragEnterEvent::_ZTV15QDragEnterEvent) + 16u) + QDragMoveEvent (0x0x7f9a4d88aaf8) 0 + primary-for QDragEnterEvent (0x0x7f9a4d88aa90) + QDropEvent (0x0x7f9a4d88ab60) 0 + primary-for QDragMoveEvent (0x0x7f9a4d88aaf8) + QEvent (0x0x7f9a4d830e40) 0 + primary-for QDropEvent (0x0x7f9a4d88ab60) + +Vtable for QDragLeaveEvent +QDragLeaveEvent::_ZTV15QDragLeaveEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QDragLeaveEvent) +16 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent +24 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent + +Class QDragLeaveEvent + size=24 align=8 + base size=20 base align=8 +QDragLeaveEvent (0x0x7f9a4d88abc8) 0 + vptr=((& QDragLeaveEvent::_ZTV15QDragLeaveEvent) + 16u) + QEvent (0x0x7f9a4d830ea0) 0 + primary-for QDragLeaveEvent (0x0x7f9a4d88abc8) + +Vtable for QHelpEvent +QHelpEvent::_ZTV10QHelpEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QHelpEvent) +16 (int (*)(...))QHelpEvent::~QHelpEvent +24 (int (*)(...))QHelpEvent::~QHelpEvent + +Class QHelpEvent + size=40 align=8 + base size=36 base align=8 +QHelpEvent (0x0x7f9a4d88ac30) 0 + vptr=((& QHelpEvent::_ZTV10QHelpEvent) + 16u) + QEvent (0x0x7f9a4d830f00) 0 + primary-for QHelpEvent (0x0x7f9a4d88ac30) + +Vtable for QStatusTipEvent +QStatusTipEvent::_ZTV15QStatusTipEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QStatusTipEvent) +16 (int (*)(...))QStatusTipEvent::~QStatusTipEvent +24 (int (*)(...))QStatusTipEvent::~QStatusTipEvent + +Class QStatusTipEvent + size=32 align=8 + base size=32 base align=8 +QStatusTipEvent (0x0x7f9a4d88ac98) 0 + vptr=((& QStatusTipEvent::_ZTV15QStatusTipEvent) + 16u) + QEvent (0x0x7f9a4d830f60) 0 + primary-for QStatusTipEvent (0x0x7f9a4d88ac98) + +Vtable for QWhatsThisClickedEvent +QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QWhatsThisClickedEvent) +16 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent +24 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent + +Class QWhatsThisClickedEvent + size=32 align=8 + base size=32 base align=8 +QWhatsThisClickedEvent (0x0x7f9a4d88ad00) 0 + vptr=((& QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent) + 16u) + QEvent (0x0x7f9a4d95d000) 0 + primary-for QWhatsThisClickedEvent (0x0x7f9a4d88ad00) + +Vtable for QActionEvent +QActionEvent::_ZTV12QActionEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QActionEvent) +16 (int (*)(...))QActionEvent::~QActionEvent +24 (int (*)(...))QActionEvent::~QActionEvent + +Class QActionEvent + size=40 align=8 + base size=40 base align=8 +QActionEvent (0x0x7f9a4d88ad68) 0 + vptr=((& QActionEvent::_ZTV12QActionEvent) + 16u) + QEvent (0x0x7f9a4d95d060) 0 + primary-for QActionEvent (0x0x7f9a4d88ad68) + +Vtable for QFileOpenEvent +QFileOpenEvent::_ZTV14QFileOpenEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QFileOpenEvent) +16 (int (*)(...))QFileOpenEvent::~QFileOpenEvent +24 (int (*)(...))QFileOpenEvent::~QFileOpenEvent + +Class QFileOpenEvent + size=40 align=8 + base size=40 base align=8 +QFileOpenEvent (0x0x7f9a4d88add0) 0 + vptr=((& QFileOpenEvent::_ZTV14QFileOpenEvent) + 16u) + QEvent (0x0x7f9a4d95d0c0) 0 + primary-for QFileOpenEvent (0x0x7f9a4d88add0) + +Vtable for QToolBarChangeEvent +QToolBarChangeEvent::_ZTV19QToolBarChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QToolBarChangeEvent) +16 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent +24 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent + +Class QToolBarChangeEvent + size=24 align=8 + base size=21 base align=8 +QToolBarChangeEvent (0x0x7f9a4d88ae38) 0 + vptr=((& QToolBarChangeEvent::_ZTV19QToolBarChangeEvent) + 16u) + QEvent (0x0x7f9a4d95d120) 0 + primary-for QToolBarChangeEvent (0x0x7f9a4d88ae38) + +Vtable for QShortcutEvent +QShortcutEvent::_ZTV14QShortcutEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QShortcutEvent) +16 (int (*)(...))QShortcutEvent::~QShortcutEvent +24 (int (*)(...))QShortcutEvent::~QShortcutEvent + +Class QShortcutEvent + size=40 align=8 + base size=40 base align=8 +QShortcutEvent (0x0x7f9a4d88aea0) 0 + vptr=((& QShortcutEvent::_ZTV14QShortcutEvent) + 16u) + QEvent (0x0x7f9a4d95d180) 0 + primary-for QShortcutEvent (0x0x7f9a4d88aea0) + +Vtable for QWindowStateChangeEvent +QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QWindowStateChangeEvent) +16 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent +24 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent + +Class QWindowStateChangeEvent + size=32 align=8 + base size=25 base align=8 +QWindowStateChangeEvent (0x0x7f9a4d88af08) 0 + vptr=((& QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent) + 16u) + QEvent (0x0x7f9a4d95d1e0) 0 + primary-for QWindowStateChangeEvent (0x0x7f9a4d88af08) + +Class QPointingDeviceUniqueId + size=8 align=8 + base size=8 base align=8 +QPointingDeviceUniqueId (0x0x7f9a4d95d240) 0 + +Class QTouchEvent::TouchPoint + size=8 align=8 + base size=8 base align=8 +QTouchEvent::TouchPoint (0x0x7f9a4d95d900) 0 + +Vtable for QTouchEvent +QTouchEvent::_ZTV11QTouchEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTouchEvent) +16 (int (*)(...))QTouchEvent::~QTouchEvent +24 (int (*)(...))QTouchEvent::~QTouchEvent + +Class QTouchEvent + size=72 align=8 + base size=72 base align=8 +QTouchEvent (0x0x7f9a4d9895b0) 0 + vptr=((& QTouchEvent::_ZTV11QTouchEvent) + 16u) + QInputEvent (0x0x7f9a4d989618) 0 + primary-for QTouchEvent (0x0x7f9a4d9895b0) + QEvent (0x0x7f9a4d95d8a0) 0 + primary-for QInputEvent (0x0x7f9a4d989618) + +Vtable for QScrollPrepareEvent +QScrollPrepareEvent::_ZTV19QScrollPrepareEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QScrollPrepareEvent) +16 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent +24 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent + +Class QScrollPrepareEvent + size=112 align=8 + base size=112 base align=8 +QScrollPrepareEvent (0x0x7f9a4d64be38) 0 + vptr=((& QScrollPrepareEvent::_ZTV19QScrollPrepareEvent) + 16u) + QEvent (0x0x7f9a4d649f60) 0 + primary-for QScrollPrepareEvent (0x0x7f9a4d64be38) + +Vtable for QScrollEvent +QScrollEvent::_ZTV12QScrollEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QScrollEvent) +16 (int (*)(...))QScrollEvent::~QScrollEvent +24 (int (*)(...))QScrollEvent::~QScrollEvent + +Class QScrollEvent + size=64 align=8 + base size=60 base align=8 +QScrollEvent (0x0x7f9a4d64bea0) 0 + vptr=((& QScrollEvent::_ZTV12QScrollEvent) + 16u) + QEvent (0x0x7f9a4d69a000) 0 + primary-for QScrollEvent (0x0x7f9a4d64bea0) + +Vtable for QScreenOrientationChangeEvent +QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QScreenOrientationChangeEvent) +16 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent +24 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent + +Class QScreenOrientationChangeEvent + size=40 align=8 + base size=36 base align=8 +QScreenOrientationChangeEvent (0x0x7f9a4d64bf08) 0 + vptr=((& QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent) + 16u) + QEvent (0x0x7f9a4d69a060) 0 + primary-for QScreenOrientationChangeEvent (0x0x7f9a4d64bf08) + +Vtable for QApplicationStateChangeEvent +QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QApplicationStateChangeEvent) +16 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent +24 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent + +Class QApplicationStateChangeEvent + size=24 align=8 + base size=24 base align=8 +QApplicationStateChangeEvent (0x0x7f9a4d64bf70) 0 + vptr=((& QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent) + 16u) + QEvent (0x0x7f9a4d69a0c0) 0 + primary-for QApplicationStateChangeEvent (0x0x7f9a4d64bf70) + +Class QFont + size=16 align=8 + base size=12 base align=8 +QFont (0x0x7f9a4d69a120) 0 + +Class QPolygon + size=8 align=8 + base size=8 base align=8 +QPolygon (0x0x7f9a4d6fad00) 0 + QVector (0x0x7f9a4d69ade0) 0 + +Class QPolygonF + size=8 align=8 + base size=8 base align=8 +QPolygonF (0x0x7f9a4d7970d0) 0 + QVector (0x0x7f9a4d7772a0) 0 + +Class QMatrix + size=48 align=8 + base size=48 base align=8 +QMatrix (0x0x7f9a4d777660) 0 + +Class QPainterPath::Element + size=24 align=8 + base size=24 base align=8 +QPainterPath::Element (0x0x7f9a4d777960) 0 + +Class QPainterPath + size=8 align=8 + base size=8 base align=8 +QPainterPath (0x0x7f9a4d777900) 0 + +Class QPainterPathStroker + size=8 align=8 + base size=8 base align=8 +QPainterPathStroker (0x0x7f9a4d483360) 0 + +Class QTransform + size=88 align=8 + base size=88 base align=8 +QTransform (0x0x7f9a4d483480) 0 + +Vtable for QPaintDevice +QPaintDevice::_ZTV12QPaintDevice: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QPaintDevice) +16 0u +24 0u +32 (int (*)(...))QPaintDevice::devType +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QPaintDevice + size=24 align=8 + base size=24 base align=8 +QPaintDevice (0x0x7f9a4d483ba0) 0 + vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 16u) + +Class QPixelFormat + size=8 align=8 + base size=8 base align=8 +QPixelFormat (0x0x7f9a4d483c00) 0 + +Vtable for QImage +QImage::_ZTV6QImage: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QImage) +16 (int (*)(...))QImage::~QImage +24 (int (*)(...))QImage::~QImage +32 (int (*)(...))QImage::devType +40 (int (*)(...))QImage::paintEngine +48 (int (*)(...))QImage::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QImage + size=32 align=8 + base size=32 base align=8 +QImage (0x0x7f9a4d4f6f70) 0 + vptr=((& QImage::_ZTV6QImage) + 16u) + QPaintDevice (0x0x7f9a4d1b36c0) 0 + primary-for QImage (0x0x7f9a4d4f6f70) + +Vtable for QPixmap +QPixmap::_ZTV7QPixmap: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QPixmap) +16 (int (*)(...))QPixmap::~QPixmap +24 (int (*)(...))QPixmap::~QPixmap +32 (int (*)(...))QPixmap::devType +40 (int (*)(...))QPixmap::paintEngine +48 (int (*)(...))QPixmap::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QPixmap + size=32 align=8 + base size=32 base align=8 +QPixmap (0x0x7f9a4d28eaf8) 0 + vptr=((& QPixmap::_ZTV7QPixmap) + 16u) + QPaintDevice (0x0x7f9a4d28f660) 0 + primary-for QPixmap (0x0x7f9a4d28eaf8) + +Class QBrush + size=8 align=8 + base size=8 base align=8 +QBrush (0x0x7f9a4d28f960) 0 + +Class QBrushData + size=112 align=8 + base size=112 base align=8 +QBrushData (0x0x7f9a4d32c120) 0 + +Class QGradient + size=64 align=8 + base size=64 base align=8 +QGradient (0x0x7f9a4d32c180) 0 + +Class QLinearGradient + size=64 align=8 + base size=64 base align=8 +QLinearGradient (0x0x7f9a4d324478) 0 + QGradient (0x0x7f9a4d32c420) 0 + +Class QRadialGradient + size=64 align=8 + base size=64 base align=8 +QRadialGradient (0x0x7f9a4d3244e0) 0 + QGradient (0x0x7f9a4d32c480) 0 + +Class QConicalGradient + size=64 align=8 + base size=64 base align=8 +QConicalGradient (0x0x7f9a4d324548) 0 + QGradient (0x0x7f9a4d32c4e0) 0 + +Class QPen + size=8 align=8 + base size=8 base align=8 +QPen (0x0x7f9a4d32c540) 0 + +Class QTextOption::Tab + size=16 align=8 + base size=14 base align=8 +QTextOption::Tab (0x0x7f9a4d01a780) 0 + +Class QTextOption + size=32 align=8 + base size=32 base align=8 +QTextOption (0x0x7f9a4d01a720) 0 + +Class QTextLength + size=16 align=8 + base size=16 base align=8 +QTextLength (0x0x7f9a4d01af00) 0 + +Class QTextFormat + size=16 align=8 + base size=12 base align=8 +QTextFormat (0x0x7f9a4d0a7660) 0 + +Class QTextCharFormat + size=16 align=8 + base size=12 base align=8 +QTextCharFormat (0x0x7f9a4d122478) 0 + QTextFormat (0x0x7f9a4d1234e0) 0 + +Class QTextBlockFormat + size=16 align=8 + base size=12 base align=8 +QTextBlockFormat (0x0x7f9a4d122680) 0 + QTextFormat (0x0x7f9a4d123780) 0 + +Class QTextListFormat + size=16 align=8 + base size=12 base align=8 +QTextListFormat (0x0x7f9a4d1228f0) 0 + QTextFormat (0x0x7f9a4d123a20) 0 + +Class QTextImageFormat + size=16 align=8 + base size=12 base align=8 +QTextImageFormat (0x0x7f9a4d122af8) 0 + QTextCharFormat (0x0x7f9a4d122b60) 0 + QTextFormat (0x0x7f9a4d123cc0) 0 + +Class QTextFrameFormat + size=16 align=8 + base size=12 base align=8 +QTextFrameFormat (0x0x7f9a4d122d68) 0 + QTextFormat (0x0x7f9a4d123f60) 0 + +Class QTextTableFormat + size=16 align=8 + base size=12 base align=8 +QTextTableFormat (0x0x7f9a4d122f70) 0 + QTextFrameFormat (0x0x7f9a4ce76000) 0 + QTextFormat (0x0x7f9a4ce63240) 0 + +Class QTextTableCellFormat + size=16 align=8 + base size=12 base align=8 +QTextTableCellFormat (0x0x7f9a4ce76208) 0 + QTextCharFormat (0x0x7f9a4ce76270) 0 + QTextFormat (0x0x7f9a4ce63540) 0 + +Class QFontDatabase + size=8 align=8 + base size=8 base align=8 +QFontDatabase (0x0x7f9a4ce637e0) 0 + +Class QRawFont + size=8 align=8 + base size=8 base align=8 +QRawFont (0x0x7f9a4ce63840) 0 + +Class QGlyphRun + size=8 align=8 + base size=8 base align=8 +QGlyphRun (0x0x7f9a4ce63d20) 0 + +Class QTextCursor + size=8 align=8 + base size=8 base align=8 +QTextCursor (0x0x7f9a4cf3d060) 0 + +Class QTextInlineObject + size=16 align=8 + base size=16 base align=8 +QTextInlineObject (0x0x7f9a4cf3d360) 0 + +Class QTextLayout::FormatRange + size=24 align=8 + base size=24 base align=8 +QTextLayout::FormatRange (0x0x7f9a4cf3d420) 0 + +Class QTextLayout + size=8 align=8 + base size=8 base align=8 +QTextLayout (0x0x7f9a4cf3d3c0) 0 + +Class QTextLine + size=16 align=8 + base size=16 base align=8 +QTextLine (0x0x7f9a4cf3de40) 0 + +Vtable for QAbstractUndoItem +QAbstractUndoItem::_ZTV17QAbstractUndoItem: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAbstractUndoItem) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QAbstractUndoItem + size=8 align=8 + base size=8 base align=8 +QAbstractUndoItem (0x0x7f9a4cf3dea0) 0 nearly-empty + vptr=((& QAbstractUndoItem::_ZTV17QAbstractUndoItem) + 16u) + +Class QTextDocument::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextDocument::QPrivateSignal (0x0x7f9a4cf3df60) 0 empty + +Vtable for QTextDocument +QTextDocument::_ZTV13QTextDocument: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QTextDocument) +16 (int (*)(...))QTextDocument::metaObject +24 (int (*)(...))QTextDocument::qt_metacast +32 (int (*)(...))QTextDocument::qt_metacall +40 (int (*)(...))QTextDocument::~QTextDocument +48 (int (*)(...))QTextDocument::~QTextDocument +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextDocument::clear +120 (int (*)(...))QTextDocument::createObject +128 (int (*)(...))QTextDocument::loadResource + +Class QTextDocument + size=16 align=8 + base size=16 base align=8 +QTextDocument (0x0x7f9a4cbdb5b0) 0 + vptr=((& QTextDocument::_ZTV13QTextDocument) + 16u) + QObject (0x0x7f9a4cf3df00) 0 + primary-for QTextDocument (0x0x7f9a4cbdb5b0) + +Class QPalette::Data + size=4 align=4 + base size=4 base align=4 +QPalette::Data (0x0x7f9a4cc2d1e0) 0 + +Class QPalette + size=16 align=8 + base size=12 base align=8 +QPalette (0x0x7f9a4cc2d180) 0 + +Class QAbstractTextDocumentLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTextDocumentLayout::QPrivateSignal (0x0x7f9a4cd182a0) 0 empty + +Class QAbstractTextDocumentLayout::Selection + size=24 align=8 + base size=24 base align=8 +QAbstractTextDocumentLayout::Selection (0x0x7f9a4cd18300) 0 + +Class QAbstractTextDocumentLayout::PaintContext + size=64 align=8 + base size=64 base align=8 +QAbstractTextDocumentLayout::PaintContext (0x0x7f9a4cd18360) 0 + +Vtable for QAbstractTextDocumentLayout +QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAbstractTextDocumentLayout) +16 (int (*)(...))QAbstractTextDocumentLayout::metaObject +24 (int (*)(...))QAbstractTextDocumentLayout::qt_metacast +32 (int (*)(...))QAbstractTextDocumentLayout::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractTextDocumentLayout::resizeInlineObject +176 (int (*)(...))QAbstractTextDocumentLayout::positionInlineObject +184 (int (*)(...))QAbstractTextDocumentLayout::drawInlineObject + +Class QAbstractTextDocumentLayout + size=16 align=8 + base size=16 base align=8 +QAbstractTextDocumentLayout (0x0x7f9a4cd012d8) 0 + vptr=((& QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout) + 16u) + QObject (0x0x7f9a4cd18240) 0 + primary-for QAbstractTextDocumentLayout (0x0x7f9a4cd012d8) + +Vtable for QTextObjectInterface +QTextObjectInterface::_ZTV20QTextObjectInterface: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTextObjectInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QTextObjectInterface + size=8 align=8 + base size=8 base align=8 +QTextObjectInterface (0x0x7f9a4cd18900) 0 nearly-empty + vptr=((& QTextObjectInterface::_ZTV20QTextObjectInterface) + 16u) + +Class QAccessible::State + size=8 align=8 + base size=5 base align=8 +QAccessible::State (0x0x7f9a4cd18a20) 0 + +Vtable for QAccessible::ActivationObserver +QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN11QAccessible18ActivationObserverE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAccessible::ActivationObserver + size=8 align=8 + base size=8 base align=8 +QAccessible::ActivationObserver (0x0x7f9a4cd18a80) 0 nearly-empty + vptr=((& QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE) + 16u) + +Class QAccessible + size=1 align=1 + base size=0 base align=1 +QAccessible (0x0x7f9a4cd189c0) 0 empty + +Vtable for QAccessibleInterface +QAccessibleInterface::_ZTV20QAccessibleInterface: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QAccessibleInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QAccessibleInterface::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleInterface::focusChild +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleInterface (0x0x7f9a4cd18c60) 0 nearly-empty + vptr=((& QAccessibleInterface::_ZTV20QAccessibleInterface) + 16u) + +Vtable for QAccessibleTextInterface +QAccessibleTextInterface::_ZTV24QAccessibleTextInterface: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAccessibleTextInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))QAccessibleTextInterface::textBeforeOffset +104 (int (*)(...))QAccessibleTextInterface::textAfterOffset +112 (int (*)(...))QAccessibleTextInterface::textAtOffset +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTextInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTextInterface (0x0x7f9a4cd18cc0) 0 nearly-empty + vptr=((& QAccessibleTextInterface::_ZTV24QAccessibleTextInterface) + 16u) + +Vtable for QAccessibleEditableTextInterface +QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI32QAccessibleEditableTextInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleEditableTextInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleEditableTextInterface (0x0x7f9a4cd18d20) 0 nearly-empty + vptr=((& QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface) + 16u) + +Vtable for QAccessibleValueInterface +QAccessibleValueInterface::_ZTV25QAccessibleValueInterface: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleValueInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleValueInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleValueInterface (0x0x7f9a4cd18d80) 0 nearly-empty + vptr=((& QAccessibleValueInterface::_ZTV25QAccessibleValueInterface) + 16u) + +Vtable for QAccessibleTableCellInterface +QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface: 12u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QAccessibleTableCellInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTableCellInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTableCellInterface (0x0x7f9a4cd18de0) 0 nearly-empty + vptr=((& QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface) + 16u) + +Vtable for QAccessibleTableInterface +QAccessibleTableInterface::_ZTV25QAccessibleTableInterface: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleTableInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTableInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTableInterface (0x0x7f9a4cd18e40) 0 nearly-empty + vptr=((& QAccessibleTableInterface::_ZTV25QAccessibleTableInterface) + 16u) + +Vtable for QAccessibleActionInterface +QAccessibleActionInterface::_ZTV26QAccessibleActionInterface: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleActionInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QAccessibleActionInterface::localizedActionName +48 (int (*)(...))QAccessibleActionInterface::localizedActionDescription +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleActionInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleActionInterface (0x0x7f9a4cd18ea0) 0 nearly-empty + vptr=((& QAccessibleActionInterface::_ZTV26QAccessibleActionInterface) + 16u) + +Vtable for QAccessibleImageInterface +QAccessibleImageInterface::_ZTV25QAccessibleImageInterface: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleImageInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleImageInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleImageInterface (0x0x7f9a4cd18f00) 0 nearly-empty + vptr=((& QAccessibleImageInterface::_ZTV25QAccessibleImageInterface) + 16u) + +Vtable for QAccessibleEvent +QAccessibleEvent::_ZTV16QAccessibleEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAccessibleEvent) +16 (int (*)(...))QAccessibleEvent::~QAccessibleEvent +24 (int (*)(...))QAccessibleEvent::~QAccessibleEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleEvent + size=32 align=8 + base size=28 base align=8 +QAccessibleEvent (0x0x7f9a4cd18f60) 0 + vptr=((& QAccessibleEvent::_ZTV16QAccessibleEvent) + 16u) + +Vtable for QAccessibleStateChangeEvent +QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAccessibleStateChangeEvent) +16 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent +24 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleStateChangeEvent + size=40 align=8 + base size=40 base align=8 +QAccessibleStateChangeEvent (0x0x7f9a4cd01d00) 0 + vptr=((& QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent) + 16u) + QAccessibleEvent (0x0x7f9a4ca194e0) 0 + primary-for QAccessibleStateChangeEvent (0x0x7f9a4cd01d00) + +Vtable for QAccessibleTextCursorEvent +QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextCursorEvent) +16 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent +24 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextCursorEvent + size=32 align=8 + base size=32 base align=8 +QAccessibleTextCursorEvent (0x0x7f9a4cd01d68) 0 + vptr=((& QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent) + 16u) + QAccessibleEvent (0x0x7f9a4ca19540) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f9a4cd01d68) + +Vtable for QAccessibleTextSelectionEvent +QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QAccessibleTextSelectionEvent) +16 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent +24 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextSelectionEvent + size=40 align=8 + base size=40 base align=8 +QAccessibleTextSelectionEvent (0x0x7f9a4cd01dd0) 0 + vptr=((& QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7f9a4cd01e38) 0 + primary-for QAccessibleTextSelectionEvent (0x0x7f9a4cd01dd0) + QAccessibleEvent (0x0x7f9a4ca195a0) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f9a4cd01e38) + +Vtable for QAccessibleTextInsertEvent +QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextInsertEvent) +16 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent +24 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextInsertEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTextInsertEvent (0x0x7f9a4cd01ea0) 0 + vptr=((& QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7f9a4cd01f08) 0 + primary-for QAccessibleTextInsertEvent (0x0x7f9a4cd01ea0) + QAccessibleEvent (0x0x7f9a4ca19600) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f9a4cd01f08) + +Vtable for QAccessibleTextRemoveEvent +QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextRemoveEvent) +16 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent +24 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextRemoveEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTextRemoveEvent (0x0x7f9a4cd01f70) 0 + vptr=((& QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7f9a4caa3000) 0 + primary-for QAccessibleTextRemoveEvent (0x0x7f9a4cd01f70) + QAccessibleEvent (0x0x7f9a4ca19660) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f9a4caa3000) + +Vtable for QAccessibleTextUpdateEvent +QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextUpdateEvent) +16 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent +24 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextUpdateEvent + size=56 align=8 + base size=56 base align=8 +QAccessibleTextUpdateEvent (0x0x7f9a4caa3068) 0 + vptr=((& QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7f9a4caa30d0) 0 + primary-for QAccessibleTextUpdateEvent (0x0x7f9a4caa3068) + QAccessibleEvent (0x0x7f9a4ca196c0) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f9a4caa30d0) + +Vtable for QAccessibleValueChangeEvent +QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAccessibleValueChangeEvent) +16 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent +24 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleValueChangeEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleValueChangeEvent (0x0x7f9a4caa3138) 0 + vptr=((& QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent) + 16u) + QAccessibleEvent (0x0x7f9a4ca19720) 0 + primary-for QAccessibleValueChangeEvent (0x0x7f9a4caa3138) + +Vtable for QAccessibleTableModelChangeEvent +QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI32QAccessibleTableModelChangeEvent) +16 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent +24 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTableModelChangeEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTableModelChangeEvent (0x0x7f9a4caa31a0) 0 + vptr=((& QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent) + 16u) + QAccessibleEvent (0x0x7f9a4ca19780) 0 + primary-for QAccessibleTableModelChangeEvent (0x0x7f9a4caa31a0) + +Vtable for QAccessibleBridge +QAccessibleBridge::_ZTV17QAccessibleBridge: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleBridge) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleBridge + size=8 align=8 + base size=8 base align=8 +QAccessibleBridge (0x0x7f9a4ca19840) 0 nearly-empty + vptr=((& QAccessibleBridge::_ZTV17QAccessibleBridge) + 16u) + +Class QAccessibleBridgePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAccessibleBridgePlugin::QPrivateSignal (0x0x7f9a4ca19900) 0 empty + +Vtable for QAccessibleBridgePlugin +QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QAccessibleBridgePlugin) +16 (int (*)(...))QAccessibleBridgePlugin::metaObject +24 (int (*)(...))QAccessibleBridgePlugin::qt_metacast +32 (int (*)(...))QAccessibleBridgePlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleBridgePlugin + size=16 align=8 + base size=16 base align=8 +QAccessibleBridgePlugin (0x0x7f9a4caa3208) 0 + vptr=((& QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin) + 16u) + QObject (0x0x7f9a4ca198a0) 0 + primary-for QAccessibleBridgePlugin (0x0x7f9a4caa3208) + +Vtable for QAccessibleObject +QAccessibleObject::_ZTV17QAccessibleObject: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleObject) +16 0u +24 0u +32 (int (*)(...))QAccessibleObject::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleInterface::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleInterface::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleObject::rect +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleObject + size=16 align=8 + base size=16 base align=8 +QAccessibleObject (0x0x7f9a4caa3270) 0 + vptr=((& QAccessibleObject::_ZTV17QAccessibleObject) + 16u) + QAccessibleInterface (0x0x7f9a4ca19960) 0 nearly-empty + primary-for QAccessibleObject (0x0x7f9a4caa3270) + +Vtable for QAccessibleApplication +QAccessibleApplication::_ZTV22QAccessibleApplication: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QAccessibleApplication) +16 (int (*)(...))QAccessibleApplication::~QAccessibleApplication +24 (int (*)(...))QAccessibleApplication::~QAccessibleApplication +32 (int (*)(...))QAccessibleObject::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleApplication::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleApplication::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))QAccessibleApplication::parent +88 (int (*)(...))QAccessibleApplication::child +96 (int (*)(...))QAccessibleApplication::childCount +104 (int (*)(...))QAccessibleApplication::indexOfChild +112 (int (*)(...))QAccessibleApplication::text +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleObject::rect +136 (int (*)(...))QAccessibleApplication::role +144 (int (*)(...))QAccessibleApplication::state +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleApplication + size=16 align=8 + base size=16 base align=8 +QAccessibleApplication (0x0x7f9a4caa32d8) 0 + vptr=((& QAccessibleApplication::_ZTV22QAccessibleApplication) + 16u) + QAccessibleObject (0x0x7f9a4caa3340) 0 + primary-for QAccessibleApplication (0x0x7f9a4caa32d8) + QAccessibleInterface (0x0x7f9a4ca199c0) 0 nearly-empty + primary-for QAccessibleObject (0x0x7f9a4caa3340) + +Class QAccessiblePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAccessiblePlugin::QPrivateSignal (0x0x7f9a4ca19a80) 0 empty + +Vtable for QAccessiblePlugin +QAccessiblePlugin::_ZTV17QAccessiblePlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessiblePlugin) +16 (int (*)(...))QAccessiblePlugin::metaObject +24 (int (*)(...))QAccessiblePlugin::qt_metacast +32 (int (*)(...))QAccessiblePlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QAccessiblePlugin + size=16 align=8 + base size=16 base align=8 +QAccessiblePlugin (0x0x7f9a4caa33a8) 0 + vptr=((& QAccessiblePlugin::_ZTV17QAccessiblePlugin) + 16u) + QObject (0x0x7f9a4ca19a20) 0 + primary-for QAccessiblePlugin (0x0x7f9a4caa33a8) + +Class QSurfaceFormat + size=8 align=8 + base size=8 base align=8 +QSurfaceFormat (0x0x7f9a4ca19ae0) 0 + +Vtable for QSurface +QSurface::_ZTV8QSurface: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QSurface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual + +Class QSurface + size=24 align=8 + base size=24 base align=8 +QSurface (0x0x7f9a4ca19cc0) 0 + vptr=((& QSurface::_ZTV8QSurface) + 16u) + +Class QIcon + size=8 align=8 + base size=8 base align=8 +QIcon (0x0x7f9a4ca19e40) 0 + +Class QCursor + size=8 align=8 + base size=8 base align=8 +QCursor (0x0x7f9a4c80b240) 0 + +Class QWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWindow::QPrivateSignal (0x0x7f9a4c892840) 0 empty + +Vtable for QWindow +QWindow::_ZTV7QWindow: 45u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QWindow) +16 (int (*)(...))QWindow::metaObject +24 (int (*)(...))QWindow::qt_metacast +32 (int (*)(...))QWindow::qt_metacall +40 (int (*)(...))QWindow::~QWindow +48 (int (*)(...))QWindow::~QWindow +56 (int (*)(...))QWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))-16 +304 (int (*)(...))(& _ZTI7QWindow) +312 (int (*)(...))QWindow::_ZThn16_N7QWindowD1Ev +320 (int (*)(...))QWindow::_ZThn16_N7QWindowD0Ev +328 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +336 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QWindow + size=40 align=8 + base size=40 base align=8 +QWindow (0x0x7f9a4c89b770) 0 + vptr=((& QWindow::_ZTV7QWindow) + 16u) + QObject (0x0x7f9a4c892780) 0 + primary-for QWindow (0x0x7f9a4c89b770) + QSurface (0x0x7f9a4c8927e0) 16 + vptr=((& QWindow::_ZTV7QWindow) + 312u) + +Class QBackingStore + size=8 align=8 + base size=8 base align=8 +QBackingStore (0x0x7f9a4c892960) 0 + +Vtable for QBitmap +QBitmap::_ZTV7QBitmap: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBitmap) +16 (int (*)(...))QBitmap::~QBitmap +24 (int (*)(...))QBitmap::~QBitmap +32 (int (*)(...))QPixmap::devType +40 (int (*)(...))QPixmap::paintEngine +48 (int (*)(...))QPixmap::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QBitmap + size=32 align=8 + base size=32 base align=8 +QBitmap (0x0x7f9a4c8a1410) 0 + vptr=((& QBitmap::_ZTV7QBitmap) + 16u) + QPixmap (0x0x7f9a4c8a1478) 0 + primary-for QBitmap (0x0x7f9a4c8a1410) + QPaintDevice (0x0x7f9a4c892a20) 0 + primary-for QPixmap (0x0x7f9a4c8a1478) + +Class QClipboard::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QClipboard::QPrivateSignal (0x0x7f9a4c892d80) 0 empty + +Vtable for QClipboard +QClipboard::_ZTV10QClipboard: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QClipboard) +16 (int (*)(...))QClipboard::metaObject +24 (int (*)(...))QClipboard::qt_metacast +32 (int (*)(...))QClipboard::qt_metacall +40 (int (*)(...))QClipboard::~QClipboard +48 (int (*)(...))QClipboard::~QClipboard +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QClipboard + size=16 align=8 + base size=16 base align=8 +QClipboard (0x0x7f9a4c8a16e8) 0 + vptr=((& QClipboard::_ZTV10QClipboard) + 16u) + QObject (0x0x7f9a4c892d20) 0 + primary-for QClipboard (0x0x7f9a4c8a16e8) + +Class QDesktopServices + size=1 align=1 + base size=0 base align=1 +QDesktopServices (0x0x7f9a4c892de0) 0 empty + +Class QDrag::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDrag::QPrivateSignal (0x0x7f9a4c892ea0) 0 empty + +Vtable for QDrag +QDrag::_ZTV5QDrag: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QDrag) +16 (int (*)(...))QDrag::metaObject +24 (int (*)(...))QDrag::qt_metacast +32 (int (*)(...))QDrag::qt_metacall +40 (int (*)(...))QDrag::~QDrag +48 (int (*)(...))QDrag::~QDrag +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDrag + size=16 align=8 + base size=16 base align=8 +QDrag (0x0x7f9a4c8a1750) 0 + vptr=((& QDrag::_ZTV5QDrag) + 16u) + QObject (0x0x7f9a4c892e40) 0 + primary-for QDrag (0x0x7f9a4c8a1750) + +Class QFontInfo + size=8 align=8 + base size=8 base align=8 +QFontInfo (0x0x7f9a4c892f00) 0 + +Class QFontMetrics + size=8 align=8 + base size=8 base align=8 +QFontMetrics (0x0x7f9a4c9551e0) 0 + +Class QFontMetricsF + size=8 align=8 + base size=8 base align=8 +QFontMetricsF (0x0x7f9a4c9554e0) 0 + +Class QGenericPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGenericPlugin::QPrivateSignal (0x0x7f9a4c63d9c0) 0 empty + +Vtable for QGenericPlugin +QGenericPlugin::_ZTV14QGenericPlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QGenericPlugin) +16 (int (*)(...))QGenericPlugin::metaObject +24 (int (*)(...))QGenericPlugin::qt_metacast +32 (int (*)(...))QGenericPlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QGenericPlugin + size=16 align=8 + base size=16 base align=8 +QGenericPlugin (0x0x7f9a4c8a1dd0) 0 + vptr=((& QGenericPlugin::_ZTV14QGenericPlugin) + 16u) + QObject (0x0x7f9a4c63d960) 0 + primary-for QGenericPlugin (0x0x7f9a4c8a1dd0) + +Class QGenericPluginFactory + size=1 align=1 + base size=0 base align=1 +QGenericPluginFactory (0x0x7f9a4c63da20) 0 empty + +Class QInputMethod::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QInputMethod::QPrivateSignal (0x0x7f9a4c63dae0) 0 empty + +Vtable for QInputMethod +QInputMethod::_ZTV12QInputMethod: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QInputMethod) +16 (int (*)(...))QInputMethod::metaObject +24 (int (*)(...))QInputMethod::qt_metacast +32 (int (*)(...))QInputMethod::qt_metacall +40 (int (*)(...))QInputMethod::~QInputMethod +48 (int (*)(...))QInputMethod::~QInputMethod +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QInputMethod + size=16 align=8 + base size=16 base align=8 +QInputMethod (0x0x7f9a4c8a1ea0) 0 + vptr=((& QInputMethod::_ZTV12QInputMethod) + 16u) + QObject (0x0x7f9a4c63da80) 0 + primary-for QInputMethod (0x0x7f9a4c8a1ea0) + +Class QGuiApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGuiApplication::QPrivateSignal (0x0x7f9a4c63dba0) 0 empty + +Vtable for QGuiApplication +QGuiApplication::_ZTV15QGuiApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGuiApplication) +16 (int (*)(...))QGuiApplication::metaObject +24 (int (*)(...))QGuiApplication::qt_metacast +32 (int (*)(...))QGuiApplication::qt_metacall +40 (int (*)(...))QGuiApplication::~QGuiApplication +48 (int (*)(...))QGuiApplication::~QGuiApplication +56 (int (*)(...))QGuiApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGuiApplication::notify +120 (int (*)(...))QGuiApplication::compressEvent + +Class QGuiApplication + size=16 align=8 + base size=16 base align=8 +QGuiApplication (0x0x7f9a4c700000) 0 + vptr=((& QGuiApplication::_ZTV15QGuiApplication) + 16u) + QCoreApplication (0x0x7f9a4c700068) 0 + primary-for QGuiApplication (0x0x7f9a4c700000) + QObject (0x0x7f9a4c63db40) 0 + primary-for QCoreApplication (0x0x7f9a4c700068) + +Class QIconEngine::AvailableSizesArgument + size=16 align=8 + base size=16 base align=8 +QIconEngine::AvailableSizesArgument (0x0x7f9a4c724120) 0 + +Class QIconEngine::ScaledPixmapArgument + size=56 align=8 + base size=56 base align=8 +QIconEngine::ScaledPixmapArgument (0x0x7f9a4c7242a0) 0 + +Vtable for QIconEngine +QIconEngine::_ZTV11QIconEngine: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QIconEngine) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QIconEngine::actualSize +48 (int (*)(...))QIconEngine::pixmap +56 (int (*)(...))QIconEngine::addPixmap +64 (int (*)(...))QIconEngine::addFile +72 (int (*)(...))QIconEngine::key +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QIconEngine::read +96 (int (*)(...))QIconEngine::write +104 (int (*)(...))QIconEngine::availableSizes +112 (int (*)(...))QIconEngine::iconName +120 (int (*)(...))QIconEngine::virtual_hook + +Class QIconEngine + size=8 align=8 + base size=8 base align=8 +QIconEngine (0x0x7f9a4c7240c0) 0 nearly-empty + vptr=((& QIconEngine::_ZTV11QIconEngine) + 16u) + +Class QIconEnginePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIconEnginePlugin::QPrivateSignal (0x0x7f9a4c724360) 0 empty + +Vtable for QIconEnginePlugin +QIconEnginePlugin::_ZTV17QIconEnginePlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QIconEnginePlugin) +16 (int (*)(...))QIconEnginePlugin::metaObject +24 (int (*)(...))QIconEnginePlugin::qt_metacast +32 (int (*)(...))QIconEnginePlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QIconEnginePlugin + size=16 align=8 + base size=16 base align=8 +QIconEnginePlugin (0x0x7f9a4c700680) 0 + vptr=((& QIconEnginePlugin::_ZTV17QIconEnginePlugin) + 16u) + QObject (0x0x7f9a4c724300) 0 + primary-for QIconEnginePlugin (0x0x7f9a4c700680) + +Vtable for QImageIOHandler +QImageIOHandler::_ZTV15QImageIOHandler: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QImageIOHandler) +16 0u +24 0u +32 (int (*)(...))QImageIOHandler::name +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))QImageIOHandler::write +64 (int (*)(...))QImageIOHandler::option +72 (int (*)(...))QImageIOHandler::setOption +80 (int (*)(...))QImageIOHandler::supportsOption +88 (int (*)(...))QImageIOHandler::jumpToNextImage +96 (int (*)(...))QImageIOHandler::jumpToImage +104 (int (*)(...))QImageIOHandler::loopCount +112 (int (*)(...))QImageIOHandler::imageCount +120 (int (*)(...))QImageIOHandler::nextImageDelay +128 (int (*)(...))QImageIOHandler::currentImageNumber +136 (int (*)(...))QImageIOHandler::currentImageRect + +Class QImageIOHandler + size=16 align=8 + base size=16 base align=8 +QImageIOHandler (0x0x7f9a4c7243c0) 0 + vptr=((& QImageIOHandler::_ZTV15QImageIOHandler) + 16u) + +Class QImageIOPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QImageIOPlugin::QPrivateSignal (0x0x7f9a4c724540) 0 empty + +Vtable for QImageIOPlugin +QImageIOPlugin::_ZTV14QImageIOPlugin: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QImageIOPlugin) +16 (int (*)(...))QImageIOPlugin::metaObject +24 (int (*)(...))QImageIOPlugin::qt_metacast +32 (int (*)(...))QImageIOPlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QImageIOPlugin + size=16 align=8 + base size=16 base align=8 +QImageIOPlugin (0x0x7f9a4c7006e8) 0 + vptr=((& QImageIOPlugin::_ZTV14QImageIOPlugin) + 16u) + QObject (0x0x7f9a4c7244e0) 0 + primary-for QImageIOPlugin (0x0x7f9a4c7006e8) + +Class QImageReader + size=8 align=8 + base size=8 base align=8 +QImageReader (0x0x7f9a4c724720) 0 + +Class QImageWriter + size=8 align=8 + base size=8 base align=8 +QImageWriter (0x0x7f9a4c724780) 0 + +Class QVector3D + size=12 align=4 + base size=12 base align=4 +QVector3D (0x0x7f9a4c7247e0) 0 + +Class QVector4D + size=16 align=4 + base size=16 base align=4 +QVector4D (0x0x7f9a4c724a80) 0 + +Class QQuaternion + size=16 align=4 + base size=16 base align=4 +QQuaternion (0x0x7f9a4c724d20) 0 + +Class QMatrix4x4 + size=68 align=4 + base size=68 base align=4 +QMatrix4x4 (0x0x7f9a4c4d8360) 0 + +Class QMovie::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMovie::QPrivateSignal (0x0x7f9a4c4d8ae0) 0 empty + +Vtable for QMovie +QMovie::_ZTV6QMovie: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QMovie) +16 (int (*)(...))QMovie::metaObject +24 (int (*)(...))QMovie::qt_metacast +32 (int (*)(...))QMovie::qt_metacall +40 (int (*)(...))QMovie::~QMovie +48 (int (*)(...))QMovie::~QMovie +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QMovie + size=16 align=8 + base size=16 base align=8 +QMovie (0x0x7f9a4c4db8f0) 0 + vptr=((& QMovie::_ZTV6QMovie) + 16u) + QObject (0x0x7f9a4c4d8a80) 0 + primary-for QMovie (0x0x7f9a4c4db8f0) + +Class QOffscreenSurface::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOffscreenSurface::QPrivateSignal (0x0x7f9a4c4d8c00) 0 empty + +Vtable for QOffscreenSurface +QOffscreenSurface::_ZTV17QOffscreenSurface: 26u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QOffscreenSurface) +16 (int (*)(...))QOffscreenSurface::metaObject +24 (int (*)(...))QOffscreenSurface::qt_metacast +32 (int (*)(...))QOffscreenSurface::qt_metacall +40 (int (*)(...))QOffscreenSurface::~QOffscreenSurface +48 (int (*)(...))QOffscreenSurface::~QOffscreenSurface +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QOffscreenSurface::surfaceType +120 (int (*)(...))QOffscreenSurface::format +128 (int (*)(...))QOffscreenSurface::size +136 (int (*)(...))QOffscreenSurface::surfaceHandle +144 (int (*)(...))-16 +152 (int (*)(...))(& _ZTI17QOffscreenSurface) +160 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD1Ev +168 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD0Ev +176 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface6formatEv +184 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface13surfaceHandleEv +192 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface11surfaceTypeEv +200 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface4sizeEv + +Class QOffscreenSurface + size=40 align=8 + base size=40 base align=8 +QOffscreenSurface (0x0x7f9a4c1fff50) 0 + vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 16u) + QObject (0x0x7f9a4c4d8b40) 0 + primary-for QOffscreenSurface (0x0x7f9a4c1fff50) + QSurface (0x0x7f9a4c4d8ba0) 16 + vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 160u) + +Class QOpenGLBuffer + size=8 align=8 + base size=8 base align=8 +QOpenGLBuffer (0x0x7f9a4c4d8cc0) 0 + +Class QOpenGLVersionStatus + size=12 align=4 + base size=12 base align=4 +QOpenGLVersionStatus (0x0x7f9a4c4d8ea0) 0 + +Class QOpenGLVersionFunctionsBackend + size=16 align=8 + base size=12 base align=8 +QOpenGLVersionFunctionsBackend (0x0x7f9a4bbd79c0) 0 + +Class QOpenGLVersionFunctionsStorage + size=8 align=8 + base size=8 base align=8 +QOpenGLVersionFunctionsStorage (0x0x7f9a4bbd7a20) 0 + +Class QAbstractOpenGLFunctionsPrivate + size=16 align=8 + base size=9 base align=8 +QAbstractOpenGLFunctionsPrivate (0x0x7f9a4bbd7a80) 0 + +Vtable for QAbstractOpenGLFunctions +QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractOpenGLFunctions) +16 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions +24 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions +32 (int (*)(...))QAbstractOpenGLFunctions::initializeOpenGLFunctions + +Class QAbstractOpenGLFunctions + size=16 align=8 + base size=16 base align=8 +QAbstractOpenGLFunctions (0x0x7f9a4bbd7ae0) 0 + vptr=((& QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions) + 16u) + +Class QOpenGLFunctions_1_0_CoreBackend::Functions + size=384 align=8 + base size=384 base align=8 +QOpenGLFunctions_1_0_CoreBackend::Functions (0x0x7f9a4bbd7ba0) 0 + +Class QOpenGLFunctions_1_0_CoreBackend + size=400 align=8 + base size=400 base align=8 +QOpenGLFunctions_1_0_CoreBackend (0x0x7f9a4bbd5b60) 0 + QOpenGLVersionFunctionsBackend (0x0x7f9a4bbd7b40) 0 + +Class QOpenGLFunctions_1_1_CoreBackend::Functions + size=128 align=8 + base size=128 base align=8 +QOpenGLFunctions_1_1_CoreBackend::Functions (0x0x7f9a4bbd7cc0) 0 + +Class QOpenGLFunctions_1_1_CoreBackend + size=144 align=8 + base size=144 base align=8 +QOpenGLFunctions_1_1_CoreBackend (0x0x7f9a4bbd5bc8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f9a4bbd7c60) 0 + +Class QOpenGLFunctions_1_2_CoreBackend::Functions + size=48 align=8 + base size=48 base align=8 +QOpenGLFunctions_1_2_CoreBackend::Functions (0x0x7f9a4bbd7de0) 0 + +Class QOpenGLFunctions_1_2_CoreBackend + size=64 align=8 + base size=64 base align=8 +QOpenGLFunctions_1_2_CoreBackend (0x0x7f9a4bbd5c30) 0 + QOpenGLVersionFunctionsBackend (0x0x7f9a4bbd7d80) 0 + +Class QOpenGLFunctions_1_3_CoreBackend::Functions + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_1_3_CoreBackend::Functions (0x0x7f9a4bbd7f00) 0 + +Class QOpenGLFunctions_1_3_CoreBackend + size=88 align=8 + base size=88 base align=8 +QOpenGLFunctions_1_3_CoreBackend (0x0x7f9a4bbd5c98) 0 + QOpenGLVersionFunctionsBackend (0x0x7f9a4bbd7ea0) 0 + +Class QOpenGLFunctions_1_4_CoreBackend::Functions + size=56 align=8 + base size=56 base align=8 +QOpenGLFunctions_1_4_CoreBackend::Functions (0x0x7f9a4bc380c0) 0 + +Class QOpenGLFunctions_1_4_CoreBackend + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_1_4_CoreBackend (0x0x7f9a4bbd5d00) 0 + QOpenGLVersionFunctionsBackend (0x0x7f9a4bc38060) 0 + +Class QOpenGLFunctions_1_5_CoreBackend::Functions + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_1_5_CoreBackend::Functions (0x0x7f9a4bc381e0) 0 + +Class QOpenGLFunctions_1_5_CoreBackend + size=168 align=8 + base size=168 base align=8 +QOpenGLFunctions_1_5_CoreBackend (0x0x7f9a4bbd5d68) 0 + QOpenGLVersionFunctionsBackend (0x0x7f9a4bc38180) 0 + +Class QOpenGLFunctions_2_0_CoreBackend::Functions + size=744 align=8 + base size=744 base align=8 +QOpenGLFunctions_2_0_CoreBackend::Functions (0x0x7f9a4bc38300) 0 + +Class QOpenGLFunctions_2_0_CoreBackend + size=760 align=8 + base size=760 base align=8 +QOpenGLFunctions_2_0_CoreBackend (0x0x7f9a4bbd5dd0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f9a4bc382a0) 0 + +Class QOpenGLFunctions_2_1_CoreBackend::Functions + size=48 align=8 + base size=48 base align=8 +QOpenGLFunctions_2_1_CoreBackend::Functions (0x0x7f9a4bc38420) 0 + +Class QOpenGLFunctions_2_1_CoreBackend + size=64 align=8 + base size=64 base align=8 +QOpenGLFunctions_2_1_CoreBackend (0x0x7f9a4bbd5e38) 0 + QOpenGLVersionFunctionsBackend (0x0x7f9a4bc383c0) 0 + +Class QOpenGLFunctions_3_0_CoreBackend::Functions + size=672 align=8 + base size=672 base align=8 +QOpenGLFunctions_3_0_CoreBackend::Functions (0x0x7f9a4bc38540) 0 + +Class QOpenGLFunctions_3_0_CoreBackend + size=688 align=8 + base size=688 base align=8 +QOpenGLFunctions_3_0_CoreBackend (0x0x7f9a4bbd5ea0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f9a4bc384e0) 0 + +Class QOpenGLFunctions_3_1_CoreBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_3_1_CoreBackend::Functions (0x0x7f9a4bc38660) 0 + +Class QOpenGLFunctions_3_1_CoreBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_3_1_CoreBackend (0x0x7f9a4bbd5f08) 0 + QOpenGLVersionFunctionsBackend (0x0x7f9a4bc38600) 0 + +Class QOpenGLFunctions_3_2_CoreBackend::Functions + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_3_2_CoreBackend::Functions (0x0x7f9a4bc38780) 0 + +Class QOpenGLFunctions_3_2_CoreBackend + size=168 align=8 + base size=168 base align=8 +QOpenGLFunctions_3_2_CoreBackend (0x0x7f9a4bbd5f70) 0 + QOpenGLVersionFunctionsBackend (0x0x7f9a4bc38720) 0 + +Class QOpenGLFunctions_3_3_CoreBackend::Functions + size=464 align=8 + base size=464 base align=8 +QOpenGLFunctions_3_3_CoreBackend::Functions (0x0x7f9a4bc388a0) 0 + +Class QOpenGLFunctions_3_3_CoreBackend + size=480 align=8 + base size=480 base align=8 +QOpenGLFunctions_3_3_CoreBackend (0x0x7f9a4bcaf000) 0 + QOpenGLVersionFunctionsBackend (0x0x7f9a4bc38840) 0 + +Class QOpenGLFunctions_4_0_CoreBackend::Functions + size=368 align=8 + base size=368 base align=8 +QOpenGLFunctions_4_0_CoreBackend::Functions (0x0x7f9a4bc389c0) 0 + +Class QOpenGLFunctions_4_0_CoreBackend + size=384 align=8 + base size=384 base align=8 +QOpenGLFunctions_4_0_CoreBackend (0x0x7f9a4bcaf068) 0 + QOpenGLVersionFunctionsBackend (0x0x7f9a4bc38960) 0 + +Class QOpenGLFunctions_4_1_CoreBackend::Functions + size=704 align=8 + base size=704 base align=8 +QOpenGLFunctions_4_1_CoreBackend::Functions (0x0x7f9a4bc38ae0) 0 + +Class QOpenGLFunctions_4_1_CoreBackend + size=720 align=8 + base size=720 base align=8 +QOpenGLFunctions_4_1_CoreBackend (0x0x7f9a4bcaf0d0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f9a4bc38a80) 0 + +Class QOpenGLFunctions_4_2_CoreBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_4_2_CoreBackend::Functions (0x0x7f9a4bc38c00) 0 + +Class QOpenGLFunctions_4_2_CoreBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_4_2_CoreBackend (0x0x7f9a4bcaf138) 0 + QOpenGLVersionFunctionsBackend (0x0x7f9a4bc38ba0) 0 + +Class QOpenGLFunctions_4_3_CoreBackend::Functions + size=344 align=8 + base size=344 base align=8 +QOpenGLFunctions_4_3_CoreBackend::Functions (0x0x7f9a4bc38d20) 0 + +Class QOpenGLFunctions_4_3_CoreBackend + size=360 align=8 + base size=360 base align=8 +QOpenGLFunctions_4_3_CoreBackend (0x0x7f9a4bcaf1a0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f9a4bc38cc0) 0 + +Class QOpenGLFunctions_4_4_CoreBackend::Functions + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_4_4_CoreBackend::Functions (0x0x7f9a4bc38e40) 0 + +Class QOpenGLFunctions_4_4_CoreBackend + size=88 align=8 + base size=88 base align=8 +QOpenGLFunctions_4_4_CoreBackend (0x0x7f9a4bcaf208) 0 + QOpenGLVersionFunctionsBackend (0x0x7f9a4bc38de0) 0 + +Class QOpenGLFunctions_4_5_CoreBackend::Functions + size=848 align=8 + base size=848 base align=8 +QOpenGLFunctions_4_5_CoreBackend::Functions (0x0x7f9a4bd31000) 0 + +Class QOpenGLFunctions_4_5_CoreBackend + size=864 align=8 + base size=864 base align=8 +QOpenGLFunctions_4_5_CoreBackend (0x0x7f9a4bcaf270) 0 + QOpenGLVersionFunctionsBackend (0x0x7f9a4bc38f60) 0 + +Class QOpenGLFunctions_1_0_DeprecatedBackend::Functions + size=2064 align=8 + base size=2064 base align=8 +QOpenGLFunctions_1_0_DeprecatedBackend::Functions (0x0x7f9a4bd31120) 0 + +Class QOpenGLFunctions_1_0_DeprecatedBackend + size=2080 align=8 + base size=2080 base align=8 +QOpenGLFunctions_1_0_DeprecatedBackend (0x0x7f9a4bcaf2d8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f9a4bd310c0) 0 + +Class QOpenGLFunctions_1_1_DeprecatedBackend::Functions + size=136 align=8 + base size=136 base align=8 +QOpenGLFunctions_1_1_DeprecatedBackend::Functions (0x0x7f9a4bd31240) 0 + +Class QOpenGLFunctions_1_1_DeprecatedBackend + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_1_1_DeprecatedBackend (0x0x7f9a4bcaf340) 0 + QOpenGLVersionFunctionsBackend (0x0x7f9a4bd311e0) 0 + +Class QOpenGLFunctions_1_2_DeprecatedBackend::Functions + size=256 align=8 + base size=256 base align=8 +QOpenGLFunctions_1_2_DeprecatedBackend::Functions (0x0x7f9a4bd31360) 0 + +Class QOpenGLFunctions_1_2_DeprecatedBackend + size=272 align=8 + base size=272 base align=8 +QOpenGLFunctions_1_2_DeprecatedBackend (0x0x7f9a4bcaf3a8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f9a4bd31300) 0 + +Class QOpenGLFunctions_1_3_DeprecatedBackend::Functions + size=296 align=8 + base size=296 base align=8 +QOpenGLFunctions_1_3_DeprecatedBackend::Functions (0x0x7f9a4bd31480) 0 + +Class QOpenGLFunctions_1_3_DeprecatedBackend + size=312 align=8 + base size=312 base align=8 +QOpenGLFunctions_1_3_DeprecatedBackend (0x0x7f9a4bcaf410) 0 + QOpenGLVersionFunctionsBackend (0x0x7f9a4bd31420) 0 + +Class QOpenGLFunctions_1_4_DeprecatedBackend::Functions + size=304 align=8 + base size=304 base align=8 +QOpenGLFunctions_1_4_DeprecatedBackend::Functions (0x0x7f9a4bd315a0) 0 + +Class QOpenGLFunctions_1_4_DeprecatedBackend + size=320 align=8 + base size=320 base align=8 +QOpenGLFunctions_1_4_DeprecatedBackend (0x0x7f9a4bcaf478) 0 + QOpenGLVersionFunctionsBackend (0x0x7f9a4bd31540) 0 + +Class QOpenGLFunctions_2_0_DeprecatedBackend::Functions + size=288 align=8 + base size=288 base align=8 +QOpenGLFunctions_2_0_DeprecatedBackend::Functions (0x0x7f9a4bd316c0) 0 + +Class QOpenGLFunctions_2_0_DeprecatedBackend + size=304 align=8 + base size=304 base align=8 +QOpenGLFunctions_2_0_DeprecatedBackend (0x0x7f9a4bcaf4e0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f9a4bd31660) 0 + +Class QOpenGLFunctions_3_0_DeprecatedBackend::Functions + size=160 align=8 + base size=160 base align=8 +QOpenGLFunctions_3_0_DeprecatedBackend::Functions (0x0x7f9a4bd317e0) 0 + +Class QOpenGLFunctions_3_0_DeprecatedBackend + size=176 align=8 + base size=176 base align=8 +QOpenGLFunctions_3_0_DeprecatedBackend (0x0x7f9a4bcaf548) 0 + QOpenGLVersionFunctionsBackend (0x0x7f9a4bd31780) 0 + +Class QOpenGLFunctions_3_3_DeprecatedBackend::Functions + size=240 align=8 + base size=240 base align=8 +QOpenGLFunctions_3_3_DeprecatedBackend::Functions (0x0x7f9a4bd31900) 0 + +Class QOpenGLFunctions_3_3_DeprecatedBackend + size=256 align=8 + base size=256 base align=8 +QOpenGLFunctions_3_3_DeprecatedBackend (0x0x7f9a4bcaf5b0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f9a4bd318a0) 0 + +Class QOpenGLFunctions_4_5_DeprecatedBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_4_5_DeprecatedBackend::Functions (0x0x7f9a4bd31a20) 0 + +Class QOpenGLFunctions_4_5_DeprecatedBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_4_5_DeprecatedBackend (0x0x7f9a4bcaf618) 0 + QOpenGLVersionFunctionsBackend (0x0x7f9a4bd319c0) 0 + +Class QOpenGLVersionProfile + size=8 align=8 + base size=8 base align=8 +QOpenGLVersionProfile (0x0x7f9a4bd31ae0) 0 + +Class QOpenGLContextGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLContextGroup::QPrivateSignal (0x0x7f9a4ba3f4e0) 0 empty + +Vtable for QOpenGLContextGroup +QOpenGLContextGroup::_ZTV19QOpenGLContextGroup: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QOpenGLContextGroup) +16 (int (*)(...))QOpenGLContextGroup::metaObject +24 (int (*)(...))QOpenGLContextGroup::qt_metacast +32 (int (*)(...))QOpenGLContextGroup::qt_metacall +40 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup +48 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLContextGroup + size=16 align=8 + base size=16 base align=8 +QOpenGLContextGroup (0x0x7f9a4ba47068) 0 + vptr=((& QOpenGLContextGroup::_ZTV19QOpenGLContextGroup) + 16u) + QObject (0x0x7f9a4ba3f480) 0 + primary-for QOpenGLContextGroup (0x0x7f9a4ba47068) + +Class QOpenGLContext::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLContext::QPrivateSignal (0x0x7f9a4ba3f5a0) 0 empty + +Vtable for QOpenGLContext +QOpenGLContext::_ZTV14QOpenGLContext: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QOpenGLContext) +16 (int (*)(...))QOpenGLContext::metaObject +24 (int (*)(...))QOpenGLContext::qt_metacast +32 (int (*)(...))QOpenGLContext::qt_metacall +40 (int (*)(...))QOpenGLContext::~QOpenGLContext +48 (int (*)(...))QOpenGLContext::~QOpenGLContext +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLContext + size=16 align=8 + base size=16 base align=8 +QOpenGLContext (0x0x7f9a4ba470d0) 0 + vptr=((& QOpenGLContext::_ZTV14QOpenGLContext) + 16u) + QObject (0x0x7f9a4ba3f540) 0 + primary-for QOpenGLContext (0x0x7f9a4ba470d0) + +Class QOpenGLDebugMessage + size=8 align=8 + base size=8 base align=8 +QOpenGLDebugMessage (0x0x7f9a4ba3f600) 0 + +Class QOpenGLDebugLogger::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLDebugLogger::QPrivateSignal (0x0x7f9a4ba3fde0) 0 empty + +Vtable for QOpenGLDebugLogger +QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLDebugLogger) +16 (int (*)(...))QOpenGLDebugLogger::metaObject +24 (int (*)(...))QOpenGLDebugLogger::qt_metacast +32 (int (*)(...))QOpenGLDebugLogger::qt_metacall +40 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger +48 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLDebugLogger + size=16 align=8 + base size=16 base align=8 +QOpenGLDebugLogger (0x0x7f9a4ba47548) 0 + vptr=((& QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger) + 16u) + QObject (0x0x7f9a4ba3fd80) 0 + primary-for QOpenGLDebugLogger (0x0x7f9a4ba47548) + +Class QOpenGLFunctions + size=8 align=8 + base size=8 base align=8 +QOpenGLFunctions (0x0x7f9a4ba3ff60) 0 + +Class QOpenGLFunctionsPrivate::Functions + size=1152 align=8 + base size=1152 base align=8 +QOpenGLFunctionsPrivate::Functions (0x0x7f9a4bb831e0) 0 + +Class QOpenGLFunctionsPrivate + size=1152 align=8 + base size=1152 base align=8 +QOpenGLFunctionsPrivate (0x0x7f9a4bb83180) 0 + +Class QOpenGLExtraFunctions + size=8 align=8 + base size=8 base align=8 +QOpenGLExtraFunctions (0x0x7f9a4ba477b8) 0 + QOpenGLFunctions (0x0x7f9a4b8a7900) 0 + +Class QOpenGLExtraFunctionsPrivate::Functions + size=1728 align=8 + base size=1728 base align=8 +QOpenGLExtraFunctionsPrivate::Functions (0x0x7f9a4b8a79c0) 0 + +Class QOpenGLExtraFunctionsPrivate + size=2880 align=8 + base size=2880 base align=8 +QOpenGLExtraFunctionsPrivate (0x0x7f9a4ba47820) 0 + QOpenGLFunctionsPrivate (0x0x7f9a4b8a7960) 0 + +Vtable for QOpenGLFramebufferObject +QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QOpenGLFramebufferObject) +16 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject +24 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject + +Class QOpenGLFramebufferObject + size=16 align=8 + base size=16 base align=8 +QOpenGLFramebufferObject (0x0x7f9a4b70d0c0) 0 + vptr=((& QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject) + 16u) + +Class QOpenGLFramebufferObjectFormat + size=8 align=8 + base size=8 base align=8 +QOpenGLFramebufferObjectFormat (0x0x7f9a4b70d1e0) 0 + +Vtable for QOpenGLPaintDevice +QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLPaintDevice) +16 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice +24 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice +32 (int (*)(...))QOpenGLPaintDevice::devType +40 (int (*)(...))QOpenGLPaintDevice::paintEngine +48 (int (*)(...))QOpenGLPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))QOpenGLPaintDevice::ensureActiveTarget + +Class QOpenGLPaintDevice + size=32 align=8 + base size=32 base align=8 +QOpenGLPaintDevice (0x0x7f9a4ba47af8) 0 + vptr=((& QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice) + 16u) + QPaintDevice (0x0x7f9a4b70d240) 0 + primary-for QOpenGLPaintDevice (0x0x7f9a4ba47af8) + +Class QOpenGLPixelTransferOptions + size=8 align=8 + base size=8 base align=8 +QOpenGLPixelTransferOptions (0x0x7f9a4b70d360) 0 + +Class QOpenGLShader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLShader::QPrivateSignal (0x0x7f9a4b70d6c0) 0 empty + +Vtable for QOpenGLShader +QOpenGLShader::_ZTV13QOpenGLShader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QOpenGLShader) +16 (int (*)(...))QOpenGLShader::metaObject +24 (int (*)(...))QOpenGLShader::qt_metacast +32 (int (*)(...))QOpenGLShader::qt_metacall +40 (int (*)(...))QOpenGLShader::~QOpenGLShader +48 (int (*)(...))QOpenGLShader::~QOpenGLShader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLShader + size=16 align=8 + base size=16 base align=8 +QOpenGLShader (0x0x7f9a4ba47d00) 0 + vptr=((& QOpenGLShader::_ZTV13QOpenGLShader) + 16u) + QObject (0x0x7f9a4b70d660) 0 + primary-for QOpenGLShader (0x0x7f9a4ba47d00) + +Class QOpenGLShaderProgram::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLShaderProgram::QPrivateSignal (0x0x7f9a4b70d900) 0 empty + +Vtable for QOpenGLShaderProgram +QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QOpenGLShaderProgram) +16 (int (*)(...))QOpenGLShaderProgram::metaObject +24 (int (*)(...))QOpenGLShaderProgram::qt_metacast +32 (int (*)(...))QOpenGLShaderProgram::qt_metacall +40 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram +48 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QOpenGLShaderProgram::link + +Class QOpenGLShaderProgram + size=16 align=8 + base size=16 base align=8 +QOpenGLShaderProgram (0x0x7f9a4ba47e38) 0 + vptr=((& QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram) + 16u) + QObject (0x0x7f9a4b70d8a0) 0 + primary-for QOpenGLShaderProgram (0x0x7f9a4ba47e38) + +Class QOpenGLTexture + size=8 align=8 + base size=8 base align=8 +QOpenGLTexture (0x0x7f9a4b70d960) 0 + +Class QOpenGLTextureBlitter + size=8 align=8 + base size=8 base align=8 +QOpenGLTextureBlitter (0x0x7f9a4b70dc00) 0 + +Class QOpenGLTimerQuery::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLTimerQuery::QPrivateSignal (0x0x7f9a4b70dd80) 0 empty + +Vtable for QOpenGLTimerQuery +QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QOpenGLTimerQuery) +16 (int (*)(...))QOpenGLTimerQuery::metaObject +24 (int (*)(...))QOpenGLTimerQuery::qt_metacast +32 (int (*)(...))QOpenGLTimerQuery::qt_metacall +40 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery +48 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLTimerQuery + size=16 align=8 + base size=16 base align=8 +QOpenGLTimerQuery (0x0x7f9a4ba47f70) 0 + vptr=((& QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery) + 16u) + QObject (0x0x7f9a4b70dd20) 0 + primary-for QOpenGLTimerQuery (0x0x7f9a4ba47f70) + +Class QOpenGLTimeMonitor::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLTimeMonitor::QPrivateSignal (0x0x7f9a4b70de40) 0 empty + +Vtable for QOpenGLTimeMonitor +QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLTimeMonitor) +16 (int (*)(...))QOpenGLTimeMonitor::metaObject +24 (int (*)(...))QOpenGLTimeMonitor::qt_metacast +32 (int (*)(...))QOpenGLTimeMonitor::qt_metacall +40 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor +48 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLTimeMonitor + size=16 align=8 + base size=16 base align=8 +QOpenGLTimeMonitor (0x0x7f9a4b4b8000) 0 + vptr=((& QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor) + 16u) + QObject (0x0x7f9a4b70dde0) 0 + primary-for QOpenGLTimeMonitor (0x0x7f9a4b4b8000) + +Class QOpenGLVertexArrayObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLVertexArrayObject::QPrivateSignal (0x0x7f9a4b70df00) 0 empty + +Class QOpenGLVertexArrayObject::Binder + size=8 align=8 + base size=8 base align=8 +QOpenGLVertexArrayObject::Binder (0x0x7f9a4b70df60) 0 + +Vtable for QOpenGLVertexArrayObject +QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QOpenGLVertexArrayObject) +16 (int (*)(...))QOpenGLVertexArrayObject::metaObject +24 (int (*)(...))QOpenGLVertexArrayObject::qt_metacast +32 (int (*)(...))QOpenGLVertexArrayObject::qt_metacall +40 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject +48 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLVertexArrayObject + size=16 align=8 + base size=16 base align=8 +QOpenGLVertexArrayObject (0x0x7f9a4b4b8068) 0 + vptr=((& QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject) + 16u) + QObject (0x0x7f9a4b70dea0) 0 + primary-for QOpenGLVertexArrayObject (0x0x7f9a4b4b8068) + +Class QPaintDeviceWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPaintDeviceWindow::QPrivateSignal (0x0x7f9a4b4e1120) 0 empty + +Vtable for QPaintDeviceWindow +QPaintDeviceWindow::_ZTV18QPaintDeviceWindow: 58u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +16 (int (*)(...))QPaintDeviceWindow::metaObject +24 (int (*)(...))QPaintDeviceWindow::qt_metacast +32 (int (*)(...))QPaintDeviceWindow::qt_metacall +40 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow +48 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))QPaintDeviceWindow::paintEvent +304 (int (*)(...))QPaintDeviceWindow::metric +312 (int (*)(...))QPaintDeviceWindow::paintEngine +320 (int (*)(...))-16 +328 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +336 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD1Ev +344 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD0Ev +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +376 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +384 (int (*)(...))-40 +392 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +400 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD1Ev +408 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD0Ev +416 (int (*)(...))QPaintDevice::devType +424 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +432 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow6metricEN12QPaintDevice17PaintDeviceMetricE +440 (int (*)(...))QPaintDevice::initPainter +448 (int (*)(...))QPaintDevice::redirected +456 (int (*)(...))QPaintDevice::sharedPainter + +Class QPaintDeviceWindow + size=64 align=8 + base size=64 base align=8 +QPaintDeviceWindow (0x0x7f9a4b4bae70) 0 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 16u) + QWindow (0x0x7f9a4b4baee0) 0 + primary-for QPaintDeviceWindow (0x0x7f9a4b4bae70) + QObject (0x0x7f9a4b4e1000) 0 + primary-for QWindow (0x0x7f9a4b4baee0) + QSurface (0x0x7f9a4b4e1060) 16 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 336u) + QPaintDevice (0x0x7f9a4b4e10c0) 40 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 400u) + +Class QOpenGLWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLWindow::QPrivateSignal (0x0x7f9a4b4e12a0) 0 empty + +Vtable for QOpenGLWindow +QOpenGLWindow::_ZTV13QOpenGLWindow: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QOpenGLWindow) +16 (int (*)(...))QOpenGLWindow::metaObject +24 (int (*)(...))QOpenGLWindow::qt_metacast +32 (int (*)(...))QOpenGLWindow::qt_metacall +40 (int (*)(...))QOpenGLWindow::~QOpenGLWindow +48 (int (*)(...))QOpenGLWindow::~QOpenGLWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QOpenGLWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))QOpenGLWindow::paintEvent +304 (int (*)(...))QOpenGLWindow::metric +312 (int (*)(...))QPaintDeviceWindow::paintEngine +320 (int (*)(...))QOpenGLWindow::initializeGL +328 (int (*)(...))QOpenGLWindow::resizeGL +336 (int (*)(...))QOpenGLWindow::paintGL +344 (int (*)(...))QOpenGLWindow::paintUnderGL +352 (int (*)(...))QOpenGLWindow::paintOverGL +360 (int (*)(...))QOpenGLWindow::redirected +368 (int (*)(...))-16 +376 (int (*)(...))(& _ZTI13QOpenGLWindow) +384 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD1Ev +392 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD0Ev +400 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +408 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +416 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +424 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +432 (int (*)(...))-40 +440 (int (*)(...))(& _ZTI13QOpenGLWindow) +448 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD1Ev +456 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD0Ev +464 (int (*)(...))QPaintDevice::devType +472 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +480 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QPaintDevice::initPainter +496 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow10redirectedEP6QPoint +504 (int (*)(...))QPaintDevice::sharedPainter + +Class QOpenGLWindow + size=64 align=8 + base size=64 base align=8 +QOpenGLWindow (0x0x7f9a4b4b8138) 0 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 16u) + QPaintDeviceWindow (0x0x7f9a4b4e32a0) 0 + primary-for QOpenGLWindow (0x0x7f9a4b4b8138) + QWindow (0x0x7f9a4b4e3310) 0 + primary-for QPaintDeviceWindow (0x0x7f9a4b4e32a0) + QObject (0x0x7f9a4b4e1180) 0 + primary-for QWindow (0x0x7f9a4b4e3310) + QSurface (0x0x7f9a4b4e11e0) 16 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 384u) + QPaintDevice (0x0x7f9a4b4e1240) 40 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 448u) + +Class QPageSize + size=8 align=8 + base size=8 base align=8 +QPageSize (0x0x7f9a4b4e1300) 0 + +Class QPageLayout + size=8 align=8 + base size=8 base align=8 +QPageLayout (0x0x7f9a4b4e1cc0) 0 + +Class QPagedPaintDevice::Margins + size=32 align=8 + base size=32 base align=8 +QPagedPaintDevice::Margins (0x0x7f9a4b58b720) 0 + +Vtable for QPagedPaintDevice +QPagedPaintDevice::_ZTV17QPagedPaintDevice: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QPagedPaintDevice) +16 0u +24 0u +32 (int (*)(...))QPaintDevice::devType +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QPagedPaintDevice::setPageSize +96 (int (*)(...))QPagedPaintDevice::setPageSizeMM +104 (int (*)(...))QPagedPaintDevice::setMargins + +Class QPagedPaintDevice + size=32 align=8 + base size=32 base align=8 +QPagedPaintDevice (0x0x7f9a4b4b8e38) 0 + vptr=((& QPagedPaintDevice::_ZTV17QPagedPaintDevice) + 16u) + QPaintDevice (0x0x7f9a4b58b6c0) 0 + primary-for QPagedPaintDevice (0x0x7f9a4b4b8e38) + +Class QPainter::PixmapFragment + size=80 align=8 + base size=80 base align=8 +QPainter::PixmapFragment (0x0x7f9a4b58b7e0) 0 + +Class QPainter + size=8 align=8 + base size=8 base align=8 +QPainter (0x0x7f9a4b58b780) 0 + +Class QTextItem + size=1 align=1 + base size=0 base align=1 +QTextItem (0x0x7f9a4b2ba600) 0 empty + +Vtable for QPaintEngine +QPaintEngine::_ZTV12QPaintEngine: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QPaintEngine) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))QPaintEngine::drawRects +64 (int (*)(...))QPaintEngine::drawRects +72 (int (*)(...))QPaintEngine::drawLines +80 (int (*)(...))QPaintEngine::drawLines +88 (int (*)(...))QPaintEngine::drawEllipse +96 (int (*)(...))QPaintEngine::drawEllipse +104 (int (*)(...))QPaintEngine::drawPath +112 (int (*)(...))QPaintEngine::drawPoints +120 (int (*)(...))QPaintEngine::drawPoints +128 (int (*)(...))QPaintEngine::drawPolygon +136 (int (*)(...))QPaintEngine::drawPolygon +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QPaintEngine::drawTextItem +160 (int (*)(...))QPaintEngine::drawTiledPixmap +168 (int (*)(...))QPaintEngine::drawImage +176 (int (*)(...))QPaintEngine::coordinateOffset +184 (int (*)(...))__cxa_pure_virtual + +Class QPaintEngine + size=32 align=8 + base size=32 base align=8 +QPaintEngine (0x0x7f9a4b2ba8a0) 0 + vptr=((& QPaintEngine::_ZTV12QPaintEngine) + 16u) + +Class QPaintEngineState + size=4 align=4 + base size=4 base align=4 +QPaintEngineState (0x0x7f9a4b2bab40) 0 + +Class QPdfWriter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPdfWriter::QPrivateSignal (0x0x7f9a4b2baf60) 0 empty + +Vtable for QPdfWriter +QPdfWriter::_ZTV10QPdfWriter: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QPdfWriter) +16 (int (*)(...))QPdfWriter::metaObject +24 (int (*)(...))QPdfWriter::qt_metacast +32 (int (*)(...))QPdfWriter::qt_metacall +40 (int (*)(...))QPdfWriter::~QPdfWriter +48 (int (*)(...))QPdfWriter::~QPdfWriter +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPdfWriter::newPage +120 (int (*)(...))QPdfWriter::setPageSize +128 (int (*)(...))QPdfWriter::setPageSizeMM +136 (int (*)(...))QPdfWriter::setMargins +144 (int (*)(...))QPdfWriter::paintEngine +152 (int (*)(...))QPdfWriter::metric +160 (int (*)(...))-16 +168 (int (*)(...))(& _ZTI10QPdfWriter) +176 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD1Ev +184 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD0Ev +192 (int (*)(...))QPaintDevice::devType +200 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter11paintEngineEv +208 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter6metricEN12QPaintDevice17PaintDeviceMetricE +216 (int (*)(...))QPaintDevice::initPainter +224 (int (*)(...))QPaintDevice::redirected +232 (int (*)(...))QPaintDevice::sharedPainter +240 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter7newPageEv +248 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter11setPageSizeEN17QPagedPaintDevice8PageSizeE +256 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter13setPageSizeMMERK6QSizeF +264 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter10setMarginsERKN17QPagedPaintDevice7MarginsE + +Class QPdfWriter + size=48 align=8 + base size=48 base align=8 +QPdfWriter (0x0x7f9a4b04e230) 0 + vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 16u) + QObject (0x0x7f9a4b2baea0) 0 + primary-for QPdfWriter (0x0x7f9a4b04e230) + QPagedPaintDevice (0x0x7f9a4b214ea0) 16 + vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 176u) + QPaintDevice (0x0x7f9a4b2baf00) 16 + primary-for QPagedPaintDevice (0x0x7f9a4b214ea0) + +Vtable for QPicture +QPicture::_ZTV8QPicture: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QPicture) +16 (int (*)(...))QPicture::~QPicture +24 (int (*)(...))QPicture::~QPicture +32 (int (*)(...))QPicture::devType +40 (int (*)(...))QPicture::paintEngine +48 (int (*)(...))QPicture::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))QPicture::setData + +Class QPicture + size=32 align=8 + base size=32 base align=8 +QPicture (0x0x7f9a4b214f08) 0 + vptr=((& QPicture::_ZTV8QPicture) + 16u) + QPaintDevice (0x0x7f9a4b071120) 0 + primary-for QPicture (0x0x7f9a4b214f08) + +Class QPictureIO + size=8 align=8 + base size=8 base align=8 +QPictureIO (0x0x7f9a4b071420) 0 + +Class QPictureFormatPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPictureFormatPlugin::QPrivateSignal (0x0x7f9a4b0714e0) 0 empty + +Vtable for QPictureFormatPlugin +QPictureFormatPlugin::_ZTV20QPictureFormatPlugin: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QPictureFormatPlugin) +16 (int (*)(...))QPictureFormatPlugin::metaObject +24 (int (*)(...))QPictureFormatPlugin::qt_metacast +32 (int (*)(...))QPictureFormatPlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPictureFormatPlugin::loadPicture +120 (int (*)(...))QPictureFormatPlugin::savePicture +128 (int (*)(...))__cxa_pure_virtual + +Class QPictureFormatPlugin + size=16 align=8 + base size=16 base align=8 +QPictureFormatPlugin (0x0x7f9a4b098138) 0 + vptr=((& QPictureFormatPlugin::_ZTV20QPictureFormatPlugin) + 16u) + QObject (0x0x7f9a4b071480) 0 + primary-for QPictureFormatPlugin (0x0x7f9a4b098138) + +Class QPixmapCache::Key + size=8 align=8 + base size=8 base align=8 +QPixmapCache::Key (0x0x7f9a4b0715a0) 0 + +Class QPixmapCache + size=1 align=1 + base size=0 base align=1 +QPixmapCache (0x0x7f9a4b071540) 0 empty + +Class QRasterWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRasterWindow::QPrivateSignal (0x0x7f9a4b12a720) 0 empty + +Vtable for QRasterWindow +QRasterWindow::_ZTV13QRasterWindow: 59u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QRasterWindow) +16 (int (*)(...))QRasterWindow::metaObject +24 (int (*)(...))QRasterWindow::qt_metacast +32 (int (*)(...))QRasterWindow::qt_metacall +40 (int (*)(...))QRasterWindow::~QRasterWindow +48 (int (*)(...))QRasterWindow::~QRasterWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))QPaintDeviceWindow::paintEvent +304 (int (*)(...))QRasterWindow::metric +312 (int (*)(...))QPaintDeviceWindow::paintEngine +320 (int (*)(...))QRasterWindow::redirected +328 (int (*)(...))-16 +336 (int (*)(...))(& _ZTI13QRasterWindow) +344 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD1Ev +352 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD0Ev +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +376 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +384 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +392 (int (*)(...))-40 +400 (int (*)(...))(& _ZTI13QRasterWindow) +408 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD1Ev +416 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD0Ev +424 (int (*)(...))QPaintDevice::devType +432 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +440 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow6metricEN12QPaintDevice17PaintDeviceMetricE +448 (int (*)(...))QPaintDevice::initPainter +456 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow10redirectedEP6QPoint +464 (int (*)(...))QPaintDevice::sharedPainter + +Class QRasterWindow + size=64 align=8 + base size=64 base align=8 +QRasterWindow (0x0x7f9a4b12b820) 0 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 16u) + QPaintDeviceWindow (0x0x7f9a4b13d000) 0 + primary-for QRasterWindow (0x0x7f9a4b12b820) + QWindow (0x0x7f9a4b13d070) 0 + primary-for QPaintDeviceWindow (0x0x7f9a4b13d000) + QObject (0x0x7f9a4b12a600) 0 + primary-for QWindow (0x0x7f9a4b13d070) + QSurface (0x0x7f9a4b12a660) 16 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 344u) + QPaintDevice (0x0x7f9a4b12a6c0) 40 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 408u) + +Class QScreen::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QScreen::QPrivateSignal (0x0x7f9a4b12a7e0) 0 empty + +Vtable for QScreen +QScreen::_ZTV7QScreen: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QScreen) +16 (int (*)(...))QScreen::metaObject +24 (int (*)(...))QScreen::qt_metacast +32 (int (*)(...))QScreen::qt_metacall +40 (int (*)(...))QScreen::~QScreen +48 (int (*)(...))QScreen::~QScreen +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QScreen + size=16 align=8 + base size=16 base align=8 +QScreen (0x0x7f9a4b12b8f0) 0 + vptr=((& QScreen::_ZTV7QScreen) + 16u) + QObject (0x0x7f9a4b12a780) 0 + primary-for QScreen (0x0x7f9a4b12b8f0) + +Class QSessionManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSessionManager::QPrivateSignal (0x0x7f9a4b12a8a0) 0 empty + +Vtable for QSessionManager +QSessionManager::_ZTV15QSessionManager: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSessionManager) +16 (int (*)(...))QSessionManager::metaObject +24 (int (*)(...))QSessionManager::qt_metacast +32 (int (*)(...))QSessionManager::qt_metacall +40 (int (*)(...))QSessionManager::~QSessionManager +48 (int (*)(...))QSessionManager::~QSessionManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSessionManager + size=16 align=8 + base size=16 base align=8 +QSessionManager (0x0x7f9a4b12b958) 0 + vptr=((& QSessionManager::_ZTV15QSessionManager) + 16u) + QObject (0x0x7f9a4b12a840) 0 + primary-for QSessionManager (0x0x7f9a4b12b958) + +Vtable for QStandardItem +QStandardItem::_ZTV13QStandardItem: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStandardItem) +16 (int (*)(...))QStandardItem::~QStandardItem +24 (int (*)(...))QStandardItem::~QStandardItem +32 (int (*)(...))QStandardItem::data +40 (int (*)(...))QStandardItem::setData +48 (int (*)(...))QStandardItem::clone +56 (int (*)(...))QStandardItem::type +64 (int (*)(...))QStandardItem::read +72 (int (*)(...))QStandardItem::write +80 (int (*)(...))QStandardItem::operator< + +Class QStandardItem + size=16 align=8 + base size=16 base align=8 +QStandardItem (0x0x7f9a4b12a900) 0 + vptr=((& QStandardItem::_ZTV13QStandardItem) + 16u) + +Class QStandardItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStandardItemModel::QPrivateSignal (0x0x7f9a4ae49060) 0 empty + +Vtable for QStandardItemModel +QStandardItemModel::_ZTV18QStandardItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QStandardItemModel) +16 (int (*)(...))QStandardItemModel::metaObject +24 (int (*)(...))QStandardItemModel::qt_metacast +32 (int (*)(...))QStandardItemModel::qt_metacall +40 (int (*)(...))QStandardItemModel::~QStandardItemModel +48 (int (*)(...))QStandardItemModel::~QStandardItemModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStandardItemModel::index +120 (int (*)(...))QStandardItemModel::parent +128 (int (*)(...))QStandardItemModel::sibling +136 (int (*)(...))QStandardItemModel::rowCount +144 (int (*)(...))QStandardItemModel::columnCount +152 (int (*)(...))QStandardItemModel::hasChildren +160 (int (*)(...))QStandardItemModel::data +168 (int (*)(...))QStandardItemModel::setData +176 (int (*)(...))QStandardItemModel::headerData +184 (int (*)(...))QStandardItemModel::setHeaderData +192 (int (*)(...))QStandardItemModel::itemData +200 (int (*)(...))QStandardItemModel::setItemData +208 (int (*)(...))QStandardItemModel::mimeTypes +216 (int (*)(...))QStandardItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QStandardItemModel::dropMimeData +240 (int (*)(...))QStandardItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStandardItemModel::insertRows +264 (int (*)(...))QStandardItemModel::insertColumns +272 (int (*)(...))QStandardItemModel::removeRows +280 (int (*)(...))QStandardItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStandardItemModel::flags +328 (int (*)(...))QStandardItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStandardItemModel + size=16 align=8 + base size=16 base align=8 +QStandardItemModel (0x0x7f9a4ae48000) 0 + vptr=((& QStandardItemModel::_ZTV18QStandardItemModel) + 16u) + QAbstractItemModel (0x0x7f9a4ae48068) 0 + primary-for QStandardItemModel (0x0x7f9a4ae48000) + QObject (0x0x7f9a4ae49000) 0 + primary-for QAbstractItemModel (0x0x7f9a4ae48068) + +Class QStaticText + size=8 align=8 + base size=8 base align=8 +QStaticText (0x0x7f9a4ae490c0) 0 + +Class QStyleHints::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStyleHints::QPrivateSignal (0x0x7f9a4ae49540) 0 empty + +Vtable for QStyleHints +QStyleHints::_ZTV11QStyleHints: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QStyleHints) +16 (int (*)(...))QStyleHints::metaObject +24 (int (*)(...))QStyleHints::qt_metacast +32 (int (*)(...))QStyleHints::qt_metacall +40 (int (*)(...))QStyleHints::~QStyleHints +48 (int (*)(...))QStyleHints::~QStyleHints +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QStyleHints + size=16 align=8 + base size=16 base align=8 +QStyleHints (0x0x7f9a4ae48270) 0 + vptr=((& QStyleHints::_ZTV11QStyleHints) + 16u) + QObject (0x0x7f9a4ae494e0) 0 + primary-for QStyleHints (0x0x7f9a4ae48270) + +Class QTextObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextObject::QPrivateSignal (0x0x7f9a4ae49600) 0 empty + +Vtable for QTextObject +QTextObject::_ZTV11QTextObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextObject) +16 (int (*)(...))QTextObject::metaObject +24 (int (*)(...))QTextObject::qt_metacast +32 (int (*)(...))QTextObject::qt_metacall +40 (int (*)(...))QTextObject::~QTextObject +48 (int (*)(...))QTextObject::~QTextObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextObject + size=16 align=8 + base size=16 base align=8 +QTextObject (0x0x7f9a4ae482d8) 0 + vptr=((& QTextObject::_ZTV11QTextObject) + 16u) + QObject (0x0x7f9a4ae495a0) 0 + primary-for QTextObject (0x0x7f9a4ae482d8) + +Class QTextBlockGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextBlockGroup::QPrivateSignal (0x0x7f9a4ae496c0) 0 empty + +Vtable for QTextBlockGroup +QTextBlockGroup::_ZTV15QTextBlockGroup: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QTextBlockGroup) +16 (int (*)(...))QTextBlockGroup::metaObject +24 (int (*)(...))QTextBlockGroup::qt_metacast +32 (int (*)(...))QTextBlockGroup::qt_metacall +40 (int (*)(...))QTextBlockGroup::~QTextBlockGroup +48 (int (*)(...))QTextBlockGroup::~QTextBlockGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextBlockGroup::blockInserted +120 (int (*)(...))QTextBlockGroup::blockRemoved +128 (int (*)(...))QTextBlockGroup::blockFormatChanged + +Class QTextBlockGroup + size=16 align=8 + base size=16 base align=8 +QTextBlockGroup (0x0x7f9a4ae48340) 0 + vptr=((& QTextBlockGroup::_ZTV15QTextBlockGroup) + 16u) + QTextObject (0x0x7f9a4ae483a8) 0 + primary-for QTextBlockGroup (0x0x7f9a4ae48340) + QObject (0x0x7f9a4ae49660) 0 + primary-for QTextObject (0x0x7f9a4ae483a8) + +Vtable for QTextFrameLayoutData +QTextFrameLayoutData::_ZTV20QTextFrameLayoutData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTextFrameLayoutData) +16 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData +24 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData + +Class QTextFrameLayoutData + size=8 align=8 + base size=8 base align=8 +QTextFrameLayoutData (0x0x7f9a4ae49720) 0 nearly-empty + vptr=((& QTextFrameLayoutData::_ZTV20QTextFrameLayoutData) + 16u) + +Class QTextFrame::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextFrame::QPrivateSignal (0x0x7f9a4ae497e0) 0 empty + +Class QTextFrame::iterator + size=32 align=8 + base size=28 base align=8 +QTextFrame::iterator (0x0x7f9a4ae49840) 0 + +Vtable for QTextFrame +QTextFrame::_ZTV10QTextFrame: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextFrame) +16 (int (*)(...))QTextFrame::metaObject +24 (int (*)(...))QTextFrame::qt_metacast +32 (int (*)(...))QTextFrame::qt_metacall +40 (int (*)(...))QTextFrame::~QTextFrame +48 (int (*)(...))QTextFrame::~QTextFrame +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextFrame + size=16 align=8 + base size=16 base align=8 +QTextFrame (0x0x7f9a4ae48410) 0 + vptr=((& QTextFrame::_ZTV10QTextFrame) + 16u) + QTextObject (0x0x7f9a4ae48478) 0 + primary-for QTextFrame (0x0x7f9a4ae48410) + QObject (0x0x7f9a4ae49780) 0 + primary-for QTextObject (0x0x7f9a4ae48478) + +Vtable for QTextBlockUserData +QTextBlockUserData::_ZTV18QTextBlockUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QTextBlockUserData) +16 (int (*)(...))QTextBlockUserData::~QTextBlockUserData +24 (int (*)(...))QTextBlockUserData::~QTextBlockUserData + +Class QTextBlockUserData + size=8 align=8 + base size=8 base align=8 +QTextBlockUserData (0x0x7f9a4ae49ae0) 0 nearly-empty + vptr=((& QTextBlockUserData::_ZTV18QTextBlockUserData) + 16u) + +Class QTextBlock::iterator + size=24 align=8 + base size=20 base align=8 +QTextBlock::iterator (0x0x7f9a4ae49ba0) 0 + +Class QTextBlock + size=16 align=8 + base size=12 base align=8 +QTextBlock (0x0x7f9a4ae49b40) 0 + +Class QTextFragment + size=16 align=8 + base size=16 base align=8 +QTextFragment (0x0x7f9a4af400c0) 0 + +Class QSyntaxHighlighter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSyntaxHighlighter::QPrivateSignal (0x0x7f9a4af403c0) 0 empty + +Vtable for QSyntaxHighlighter +QSyntaxHighlighter::_ZTV18QSyntaxHighlighter: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSyntaxHighlighter) +16 (int (*)(...))QSyntaxHighlighter::metaObject +24 (int (*)(...))QSyntaxHighlighter::qt_metacast +32 (int (*)(...))QSyntaxHighlighter::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QSyntaxHighlighter + size=16 align=8 + base size=16 base align=8 +QSyntaxHighlighter (0x0x7f9a4ae48b60) 0 + vptr=((& QSyntaxHighlighter::_ZTV18QSyntaxHighlighter) + 16u) + QObject (0x0x7f9a4af40360) 0 + primary-for QSyntaxHighlighter (0x0x7f9a4ae48b60) + +Class QTextDocumentFragment + size=8 align=8 + base size=8 base align=8 +QTextDocumentFragment (0x0x7f9a4af40420) 0 + +Class QTextDocumentWriter + size=8 align=8 + base size=8 base align=8 +QTextDocumentWriter (0x0x7f9a4af40480) 0 + +Class QTextList::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextList::QPrivateSignal (0x0x7f9a4af40540) 0 empty + +Vtable for QTextList +QTextList::_ZTV9QTextList: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTextList) +16 (int (*)(...))QTextList::metaObject +24 (int (*)(...))QTextList::qt_metacast +32 (int (*)(...))QTextList::qt_metacall +40 (int (*)(...))QTextList::~QTextList +48 (int (*)(...))QTextList::~QTextList +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextBlockGroup::blockInserted +120 (int (*)(...))QTextBlockGroup::blockRemoved +128 (int (*)(...))QTextBlockGroup::blockFormatChanged + +Class QTextList + size=16 align=8 + base size=16 base align=8 +QTextList (0x0x7f9a4ae48bc8) 0 + vptr=((& QTextList::_ZTV9QTextList) + 16u) + QTextBlockGroup (0x0x7f9a4ae48c30) 0 + primary-for QTextList (0x0x7f9a4ae48bc8) + QTextObject (0x0x7f9a4ae48c98) 0 + primary-for QTextBlockGroup (0x0x7f9a4ae48c30) + QObject (0x0x7f9a4af404e0) 0 + primary-for QTextObject (0x0x7f9a4ae48c98) + +Class QTextTableCell + size=16 align=8 + base size=12 base align=8 +QTextTableCell (0x0x7f9a4af405a0) 0 + +Class QTextTable::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextTable::QPrivateSignal (0x0x7f9a4af40660) 0 empty + +Vtable for QTextTable +QTextTable::_ZTV10QTextTable: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextTable) +16 (int (*)(...))QTextTable::metaObject +24 (int (*)(...))QTextTable::qt_metacast +32 (int (*)(...))QTextTable::qt_metacall +40 (int (*)(...))QTextTable::~QTextTable +48 (int (*)(...))QTextTable::~QTextTable +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextTable + size=16 align=8 + base size=16 base align=8 +QTextTable (0x0x7f9a4ae48d00) 0 + vptr=((& QTextTable::_ZTV10QTextTable) + 16u) + QTextFrame (0x0x7f9a4ae48d68) 0 + primary-for QTextTable (0x0x7f9a4ae48d00) + QTextObject (0x0x7f9a4ae48dd0) 0 + primary-for QTextFrame (0x0x7f9a4ae48d68) + QObject (0x0x7f9a4af40600) 0 + primary-for QTextObject (0x0x7f9a4ae48dd0) + +Class QValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QValidator::QPrivateSignal (0x0x7f9a4af40720) 0 empty + +Vtable for QValidator +QValidator::_ZTV10QValidator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QValidator) +16 (int (*)(...))QValidator::metaObject +24 (int (*)(...))QValidator::qt_metacast +32 (int (*)(...))QValidator::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QValidator::fixup + +Class QValidator + size=16 align=8 + base size=16 base align=8 +QValidator (0x0x7f9a4ae48e38) 0 + vptr=((& QValidator::_ZTV10QValidator) + 16u) + QObject (0x0x7f9a4af406c0) 0 + primary-for QValidator (0x0x7f9a4ae48e38) + +Class QIntValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIntValidator::QPrivateSignal (0x0x7f9a4af407e0) 0 empty + +Vtable for QIntValidator +QIntValidator::_ZTV13QIntValidator: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QIntValidator) +16 (int (*)(...))QIntValidator::metaObject +24 (int (*)(...))QIntValidator::qt_metacast +32 (int (*)(...))QIntValidator::qt_metacall +40 (int (*)(...))QIntValidator::~QIntValidator +48 (int (*)(...))QIntValidator::~QIntValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIntValidator::validate +120 (int (*)(...))QIntValidator::fixup +128 (int (*)(...))QIntValidator::setRange + +Class QIntValidator + size=24 align=8 + base size=24 base align=8 +QIntValidator (0x0x7f9a4ae48ea0) 0 + vptr=((& QIntValidator::_ZTV13QIntValidator) + 16u) + QValidator (0x0x7f9a4ae48f08) 0 + primary-for QIntValidator (0x0x7f9a4ae48ea0) + QObject (0x0x7f9a4af40780) 0 + primary-for QValidator (0x0x7f9a4ae48f08) + +Class QDoubleValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDoubleValidator::QPrivateSignal (0x0x7f9a4af408a0) 0 empty + +Vtable for QDoubleValidator +QDoubleValidator::_ZTV16QDoubleValidator: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QDoubleValidator) +16 (int (*)(...))QDoubleValidator::metaObject +24 (int (*)(...))QDoubleValidator::qt_metacast +32 (int (*)(...))QDoubleValidator::qt_metacall +40 (int (*)(...))QDoubleValidator::~QDoubleValidator +48 (int (*)(...))QDoubleValidator::~QDoubleValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QDoubleValidator::validate +120 (int (*)(...))QValidator::fixup +128 (int (*)(...))QDoubleValidator::setRange + +Class QDoubleValidator + size=40 align=8 + base size=36 base align=8 +QDoubleValidator (0x0x7f9a4ae48f70) 0 + vptr=((& QDoubleValidator::_ZTV16QDoubleValidator) + 16u) + QValidator (0x0x7f9a4abda000) 0 + primary-for QDoubleValidator (0x0x7f9a4ae48f70) + QObject (0x0x7f9a4af40840) 0 + primary-for QValidator (0x0x7f9a4abda000) + +Class QRegExpValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRegExpValidator::QPrivateSignal (0x0x7f9a4af409c0) 0 empty + +Vtable for QRegExpValidator +QRegExpValidator::_ZTV16QRegExpValidator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QRegExpValidator) +16 (int (*)(...))QRegExpValidator::metaObject +24 (int (*)(...))QRegExpValidator::qt_metacast +32 (int (*)(...))QRegExpValidator::qt_metacall +40 (int (*)(...))QRegExpValidator::~QRegExpValidator +48 (int (*)(...))QRegExpValidator::~QRegExpValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QRegExpValidator::validate +120 (int (*)(...))QValidator::fixup + +Class QRegExpValidator + size=24 align=8 + base size=24 base align=8 +QRegExpValidator (0x0x7f9a4abda068) 0 + vptr=((& QRegExpValidator::_ZTV16QRegExpValidator) + 16u) + QValidator (0x0x7f9a4abda0d0) 0 + primary-for QRegExpValidator (0x0x7f9a4abda068) + QObject (0x0x7f9a4af40960) 0 + primary-for QValidator (0x0x7f9a4abda0d0) + +Class QRegularExpressionValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRegularExpressionValidator::QPrivateSignal (0x0x7f9a4af40a80) 0 empty + +Vtable for QRegularExpressionValidator +QRegularExpressionValidator::_ZTV27QRegularExpressionValidator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QRegularExpressionValidator) +16 (int (*)(...))QRegularExpressionValidator::metaObject +24 (int (*)(...))QRegularExpressionValidator::qt_metacast +32 (int (*)(...))QRegularExpressionValidator::qt_metacall +40 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator +48 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QRegularExpressionValidator::validate +120 (int (*)(...))QValidator::fixup + +Class QRegularExpressionValidator + size=16 align=8 + base size=16 base align=8 +QRegularExpressionValidator (0x0x7f9a4abda138) 0 + vptr=((& QRegularExpressionValidator::_ZTV27QRegularExpressionValidator) + 16u) + QValidator (0x0x7f9a4abda1a0) 0 + primary-for QRegularExpressionValidator (0x0x7f9a4abda138) + QObject (0x0x7f9a4af40a20) 0 + primary-for QValidator (0x0x7f9a4abda1a0) + +Class QSizePolicy::Bits + size=4 align=4 + base size=4 base align=4 +QSizePolicy::Bits (0x0x7f9a4af40b40) 0 + +Class QSizePolicy + size=4 align=4 + base size=4 base align=4 +QSizePolicy (0x0x7f9a4af40ae0) 0 + +Class QWidgetData + size=88 align=8 + base size=88 base align=8 +QWidgetData (0x0x7f9a4ac42480) 0 + +Class QWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWidget::QPrivateSignal (0x0x7f9a4ac425a0) 0 empty + +Vtable for QWidget +QWidget::_ZTV7QWidget: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QWidget) +16 (int (*)(...))QWidget::metaObject +24 (int (*)(...))QWidget::qt_metacast +32 (int (*)(...))QWidget::qt_metacall +40 (int (*)(...))QWidget::~QWidget +48 (int (*)(...))QWidget::~QWidget +56 (int (*)(...))QWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI7QWidget) +448 (int (*)(...))QWidget::_ZThn16_N7QWidgetD1Ev +456 (int (*)(...))QWidget::_ZThn16_N7QWidgetD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QWidget + size=48 align=8 + base size=48 base align=8 +QWidget (0x0x7f9a4ac84af0) 0 + vptr=((& QWidget::_ZTV7QWidget) + 16u) + QObject (0x0x7f9a4ac424e0) 0 + primary-for QWidget (0x0x7f9a4ac84af0) + QPaintDevice (0x0x7f9a4ac42540) 16 + vptr=((& QWidget::_ZTV7QWidget) + 448u) + +Class QAbstractButton::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractButton::QPrivateSignal (0x0x7f9a4a981240) 0 empty + +Vtable for QAbstractButton +QAbstractButton::_ZTV15QAbstractButton: 67u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAbstractButton) +16 (int (*)(...))QAbstractButton::metaObject +24 (int (*)(...))QAbstractButton::qt_metacast +32 (int (*)(...))QAbstractButton::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractButton::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractButton::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractButton::mousePressEvent +176 (int (*)(...))QAbstractButton::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractButton::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QAbstractButton::keyPressEvent +216 (int (*)(...))QAbstractButton::keyReleaseEvent +224 (int (*)(...))QAbstractButton::focusInEvent +232 (int (*)(...))QAbstractButton::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))__cxa_pure_virtual +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractButton::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QAbstractButton::hitButton +440 (int (*)(...))QAbstractButton::checkStateSet +448 (int (*)(...))QAbstractButton::nextCheckState +456 (int (*)(...))-16 +464 (int (*)(...))(& _ZTI15QAbstractButton) +472 0u +480 0u +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QAbstractButton + size=48 align=8 + base size=48 base align=8 +QAbstractButton (0x0x7f9a4a97c4e0) 0 + vptr=((& QAbstractButton::_ZTV15QAbstractButton) + 16u) + QWidget (0x0x7f9a4a9787e0) 0 + primary-for QAbstractButton (0x0x7f9a4a97c4e0) + QObject (0x0x7f9a4a981180) 0 + primary-for QWidget (0x0x7f9a4a9787e0) + QPaintDevice (0x0x7f9a4a9811e0) 16 + vptr=((& QAbstractButton::_ZTV15QAbstractButton) + 472u) + +Class QAbstractSpinBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractSpinBox::QPrivateSignal (0x0x7f9a4a981360) 0 empty + +Vtable for QAbstractSpinBox +QAbstractSpinBox::_ZTV16QAbstractSpinBox: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAbstractSpinBox) +16 (int (*)(...))QAbstractSpinBox::metaObject +24 (int (*)(...))QAbstractSpinBox::qt_metacast +32 (int (*)(...))QAbstractSpinBox::qt_metacall +40 (int (*)(...))QAbstractSpinBox::~QAbstractSpinBox +48 (int (*)(...))QAbstractSpinBox::~QAbstractSpinBox +56 (int (*)(...))QAbstractSpinBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSpinBox::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractSpinBox::sizeHint +136 (int (*)(...))QAbstractSpinBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractSpinBox::mousePressEvent +176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent +200 (int (*)(...))QAbstractSpinBox::wheelEvent +208 (int (*)(...))QAbstractSpinBox::keyPressEvent +216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent +224 (int (*)(...))QAbstractSpinBox::focusInEvent +232 (int (*)(...))QAbstractSpinBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractSpinBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractSpinBox::resizeEvent +280 (int (*)(...))QAbstractSpinBox::closeEvent +288 (int (*)(...))QAbstractSpinBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QAbstractSpinBox::showEvent +352 (int (*)(...))QAbstractSpinBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSpinBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QAbstractSpinBox::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QAbstractSpinBox::validate +440 (int (*)(...))QAbstractSpinBox::fixup +448 (int (*)(...))QAbstractSpinBox::stepBy +456 (int (*)(...))QAbstractSpinBox::clear +464 (int (*)(...))QAbstractSpinBox::stepEnabled +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI16QAbstractSpinBox) +488 (int (*)(...))QAbstractSpinBox::_ZThn16_N16QAbstractSpinBoxD1Ev +496 (int (*)(...))QAbstractSpinBox::_ZThn16_N16QAbstractSpinBoxD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QAbstractSpinBox + size=48 align=8 + base size=48 base align=8 +QAbstractSpinBox (0x0x7f9a4a97c548) 0 + vptr=((& QAbstractSpinBox::_ZTV16QAbstractSpinBox) + 16u) + QWidget (0x0x7f9a4a978af0) 0 + primary-for QAbstractSpinBox (0x0x7f9a4a97c548) + QObject (0x0x7f9a4a9812a0) 0 + primary-for QWidget (0x0x7f9a4a978af0) + QPaintDevice (0x0x7f9a4a981300) 16 + vptr=((& QAbstractSpinBox::_ZTV16QAbstractSpinBox) + 488u) + +Class QAbstractSlider::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractSlider::QPrivateSignal (0x0x7f9a4a981600) 0 empty + +Vtable for QAbstractSlider +QAbstractSlider::_ZTV15QAbstractSlider: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAbstractSlider) +16 (int (*)(...))QAbstractSlider::metaObject +24 (int (*)(...))QAbstractSlider::qt_metacast +32 (int (*)(...))QAbstractSlider::qt_metacall +40 (int (*)(...))QAbstractSlider::~QAbstractSlider +48 (int (*)(...))QAbstractSlider::~QAbstractSlider +56 (int (*)(...))QAbstractSlider::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSlider::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QAbstractSlider::wheelEvent +208 (int (*)(...))QAbstractSlider::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSlider::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QAbstractSlider::sliderChange +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI15QAbstractSlider) +456 (int (*)(...))QAbstractSlider::_ZThn16_N15QAbstractSliderD1Ev +464 (int (*)(...))QAbstractSlider::_ZThn16_N15QAbstractSliderD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QAbstractSlider + size=48 align=8 + base size=48 base align=8 +QAbstractSlider (0x0x7f9a4a97c680) 0 + vptr=((& QAbstractSlider::_ZTV15QAbstractSlider) + 16u) + QWidget (0x0x7f9a4a9bdee0) 0 + primary-for QAbstractSlider (0x0x7f9a4a97c680) + QObject (0x0x7f9a4a981540) 0 + primary-for QWidget (0x0x7f9a4a9bdee0) + QPaintDevice (0x0x7f9a4a9815a0) 16 + vptr=((& QAbstractSlider::_ZTV15QAbstractSlider) + 456u) + +Class QSlider::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSlider::QPrivateSignal (0x0x7f9a4a981720) 0 empty + +Vtable for QSlider +QSlider::_ZTV7QSlider: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QSlider) +16 (int (*)(...))QSlider::metaObject +24 (int (*)(...))QSlider::qt_metacast +32 (int (*)(...))QSlider::qt_metacall +40 (int (*)(...))QSlider::~QSlider +48 (int (*)(...))QSlider::~QSlider +56 (int (*)(...))QSlider::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSlider::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QSlider::sizeHint +136 (int (*)(...))QSlider::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QSlider::mousePressEvent +176 (int (*)(...))QSlider::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QSlider::mouseMoveEvent +200 (int (*)(...))QAbstractSlider::wheelEvent +208 (int (*)(...))QAbstractSlider::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QSlider::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSlider::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QAbstractSlider::sliderChange +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI7QSlider) +456 (int (*)(...))QSlider::_ZThn16_N7QSliderD1Ev +464 (int (*)(...))QSlider::_ZThn16_N7QSliderD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QSlider + size=48 align=8 + base size=48 base align=8 +QSlider (0x0x7f9a4a97c6e8) 0 + vptr=((& QSlider::_ZTV7QSlider) + 16u) + QAbstractSlider (0x0x7f9a4a97c750) 0 + primary-for QSlider (0x0x7f9a4a97c6e8) + QWidget (0x0x7f9a4aa07770) 0 + primary-for QAbstractSlider (0x0x7f9a4a97c750) + QObject (0x0x7f9a4a981660) 0 + primary-for QWidget (0x0x7f9a4aa07770) + QPaintDevice (0x0x7f9a4a9816c0) 16 + vptr=((& QSlider::_ZTV7QSlider) + 456u) + +Class QStyle::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStyle::QPrivateSignal (0x0x7f9a4a9817e0) 0 empty + +Vtable for QStyle +QStyle::_ZTV6QStyle: 37u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QStyle) +16 (int (*)(...))QStyle::metaObject +24 (int (*)(...))QStyle::qt_metacast +32 (int (*)(...))QStyle::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStyle::polish +120 (int (*)(...))QStyle::unpolish +128 (int (*)(...))QStyle::polish +136 (int (*)(...))QStyle::unpolish +144 (int (*)(...))QStyle::polish +152 (int (*)(...))QStyle::itemTextRect +160 (int (*)(...))QStyle::itemPixmapRect +168 (int (*)(...))QStyle::drawItemText +176 (int (*)(...))QStyle::drawItemPixmap +184 (int (*)(...))QStyle::standardPalette +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))__cxa_pure_virtual +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))__cxa_pure_virtual +232 (int (*)(...))__cxa_pure_virtual +240 (int (*)(...))__cxa_pure_virtual +248 (int (*)(...))__cxa_pure_virtual +256 (int (*)(...))__cxa_pure_virtual +264 (int (*)(...))__cxa_pure_virtual +272 (int (*)(...))__cxa_pure_virtual +280 (int (*)(...))__cxa_pure_virtual +288 (int (*)(...))__cxa_pure_virtual + +Class QStyle + size=16 align=8 + base size=16 base align=8 +QStyle (0x0x7f9a4a97c820) 0 + vptr=((& QStyle::_ZTV6QStyle) + 16u) + QObject (0x0x7f9a4a981780) 0 + primary-for QStyle (0x0x7f9a4a97c820) + +Class QTabBar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTabBar::QPrivateSignal (0x0x7f9a4a981c00) 0 empty + +Vtable for QTabBar +QTabBar::_ZTV7QTabBar: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QTabBar) +16 (int (*)(...))QTabBar::metaObject +24 (int (*)(...))QTabBar::qt_metacast +32 (int (*)(...))QTabBar::qt_metacall +40 (int (*)(...))QTabBar::~QTabBar +48 (int (*)(...))QTabBar::~QTabBar +56 (int (*)(...))QTabBar::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTabBar::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QTabBar::sizeHint +136 (int (*)(...))QTabBar::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QTabBar::mousePressEvent +176 (int (*)(...))QTabBar::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QTabBar::mouseMoveEvent +200 (int (*)(...))QTabBar::wheelEvent +208 (int (*)(...))QTabBar::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTabBar::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QTabBar::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QTabBar::showEvent +352 (int (*)(...))QTabBar::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QTabBar::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QTabBar::tabSizeHint +440 (int (*)(...))QTabBar::minimumTabSizeHint +448 (int (*)(...))QTabBar::tabInserted +456 (int (*)(...))QTabBar::tabRemoved +464 (int (*)(...))QTabBar::tabLayoutChange +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI7QTabBar) +488 (int (*)(...))QTabBar::_ZThn16_N7QTabBarD1Ev +496 (int (*)(...))QTabBar::_ZThn16_N7QTabBarD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTabBar + size=48 align=8 + base size=48 base align=8 +QTabBar (0x0x7f9a4a97ca28) 0 + vptr=((& QTabBar::_ZTV7QTabBar) + 16u) + QWidget (0x0x7f9a4aad8700) 0 + primary-for QTabBar (0x0x7f9a4a97ca28) + QObject (0x0x7f9a4a981b40) 0 + primary-for QWidget (0x0x7f9a4aad8700) + QPaintDevice (0x0x7f9a4a981ba0) 16 + vptr=((& QTabBar::_ZTV7QTabBar) + 488u) + +Class QTabWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTabWidget::QPrivateSignal (0x0x7f9a4a981d20) 0 empty + +Vtable for QTabWidget +QTabWidget::_ZTV10QTabWidget: 66u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTabWidget) +16 (int (*)(...))QTabWidget::metaObject +24 (int (*)(...))QTabWidget::qt_metacast +32 (int (*)(...))QTabWidget::qt_metacall +40 (int (*)(...))QTabWidget::~QTabWidget +48 (int (*)(...))QTabWidget::~QTabWidget +56 (int (*)(...))QTabWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QTabWidget::sizeHint +136 (int (*)(...))QTabWidget::minimumSizeHint +144 (int (*)(...))QTabWidget::heightForWidth +152 (int (*)(...))QTabWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QTabWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTabWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QTabWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QTabWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QTabWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QTabWidget::tabInserted +440 (int (*)(...))QTabWidget::tabRemoved +448 (int (*)(...))-16 +456 (int (*)(...))(& _ZTI10QTabWidget) +464 (int (*)(...))QTabWidget::_ZThn16_N10QTabWidgetD1Ev +472 (int (*)(...))QTabWidget::_ZThn16_N10QTabWidgetD0Ev +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTabWidget + size=48 align=8 + base size=48 base align=8 +QTabWidget (0x0x7f9a4a97ca90) 0 + vptr=((& QTabWidget::_ZTV10QTabWidget) + 16u) + QWidget (0x0x7f9a4ab190e0) 0 + primary-for QTabWidget (0x0x7f9a4a97ca90) + QObject (0x0x7f9a4a981c60) 0 + primary-for QWidget (0x0x7f9a4ab190e0) + QPaintDevice (0x0x7f9a4a981cc0) 16 + vptr=((& QTabWidget::_ZTV10QTabWidget) + 464u) + +Class QRubberBand::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRubberBand::QPrivateSignal (0x0x7f9a4a981e40) 0 empty + +Vtable for QRubberBand +QRubberBand::_ZTV11QRubberBand: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QRubberBand) +16 (int (*)(...))QRubberBand::metaObject +24 (int (*)(...))QRubberBand::qt_metacast +32 (int (*)(...))QRubberBand::qt_metacall +40 (int (*)(...))QRubberBand::~QRubberBand +48 (int (*)(...))QRubberBand::~QRubberBand +56 (int (*)(...))QRubberBand::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QRubberBand::paintEvent +264 (int (*)(...))QRubberBand::moveEvent +272 (int (*)(...))QRubberBand::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QRubberBand::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QRubberBand::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI11QRubberBand) +448 (int (*)(...))QRubberBand::_ZThn16_N11QRubberBandD1Ev +456 (int (*)(...))QRubberBand::_ZThn16_N11QRubberBandD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QRubberBand + size=48 align=8 + base size=48 base align=8 +QRubberBand (0x0x7f9a4a97caf8) 0 + vptr=((& QRubberBand::_ZTV11QRubberBand) + 16u) + QWidget (0x0x7f9a4ab198c0) 0 + primary-for QRubberBand (0x0x7f9a4a97caf8) + QObject (0x0x7f9a4a981d80) 0 + primary-for QWidget (0x0x7f9a4ab198c0) + QPaintDevice (0x0x7f9a4a981de0) 16 + vptr=((& QRubberBand::_ZTV11QRubberBand) + 448u) + +Class QFrame::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFrame::QPrivateSignal (0x0x7f9a4a981f60) 0 empty + +Vtable for QFrame +QFrame::_ZTV6QFrame: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QFrame) +16 (int (*)(...))QFrame::metaObject +24 (int (*)(...))QFrame::qt_metacast +32 (int (*)(...))QFrame::qt_metacall +40 (int (*)(...))QFrame::~QFrame +48 (int (*)(...))QFrame::~QFrame +56 (int (*)(...))QFrame::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QFrame::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QFrame::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI6QFrame) +448 (int (*)(...))QFrame::_ZThn16_N6QFrameD1Ev +456 (int (*)(...))QFrame::_ZThn16_N6QFrameD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QFrame + size=48 align=8 + base size=48 base align=8 +QFrame (0x0x7f9a4a97cb60) 0 + vptr=((& QFrame::_ZTV6QFrame) + 16u) + QWidget (0x0x7f9a4ab19ee0) 0 + primary-for QFrame (0x0x7f9a4a97cb60) + QObject (0x0x7f9a4a981ea0) 0 + primary-for QWidget (0x0x7f9a4ab19ee0) + QPaintDevice (0x0x7f9a4a981f00) 16 + vptr=((& QFrame::_ZTV6QFrame) + 448u) + +Class QStyleOption + size=64 align=8 + base size=64 base align=8 +QStyleOption (0x0x7f9a4a73c000) 0 + +Class QStyleOptionFocusRect + size=80 align=8 + base size=80 base align=8 +QStyleOptionFocusRect (0x0x7f9a4a97cbc8) 0 + QStyleOption (0x0x7f9a4a73c060) 0 + +Class QStyleOptionFrame + size=80 align=8 + base size=80 base align=8 +QStyleOptionFrame (0x0x7f9a4a97cc30) 0 + QStyleOption (0x0x7f9a4a73c0c0) 0 + +Class QStyleOptionTabWidgetFrame + size=136 align=8 + base size=132 base align=8 +QStyleOptionTabWidgetFrame (0x0x7f9a4a97cd68) 0 + QStyleOption (0x0x7f9a4a73c2a0) 0 + +Class QStyleOptionTabBarBase + size=104 align=8 + base size=101 base align=8 +QStyleOptionTabBarBase (0x0x7f9a4a97cdd0) 0 + QStyleOption (0x0x7f9a4a73c300) 0 + +Class QStyleOptionHeader + size=120 align=8 + base size=116 base align=8 +QStyleOptionHeader (0x0x7f9a4a97ce38) 0 + QStyleOption (0x0x7f9a4a73c3c0) 0 + +Class QStyleOptionButton + size=96 align=8 + base size=96 base align=8 +QStyleOptionButton (0x0x7f9a4a97cea0) 0 + QStyleOption (0x0x7f9a4a73c420) 0 + +Class QStyleOptionTab + size=136 align=8 + base size=136 base align=8 +QStyleOptionTab (0x0x7f9a4a7ef000) 0 + QStyleOption (0x0x7f9a4a73c600) 0 + +Class QStyleOptionToolBar + size=88 align=8 + base size=88 base align=8 +QStyleOptionToolBar (0x0x7f9a4a7ef208) 0 + QStyleOption (0x0x7f9a4a73c960) 0 + +Class QStyleOptionProgressBar + size=104 align=8 + base size=102 base align=8 +QStyleOptionProgressBar (0x0x7f9a4a7ef340) 0 + QStyleOption (0x0x7f9a4a73cb40) 0 + +Class QStyleOptionMenuItem + size=136 align=8 + base size=136 base align=8 +QStyleOptionMenuItem (0x0x7f9a4a7ef3a8) 0 + QStyleOption (0x0x7f9a4a73cba0) 0 + +Class QStyleOptionDockWidget + size=80 align=8 + base size=76 base align=8 +QStyleOptionDockWidget (0x0x7f9a4a7ef410) 0 + QStyleOption (0x0x7f9a4a73cc00) 0 + +Class QStyleOptionViewItem + size=192 align=8 + base size=192 base align=8 +QStyleOptionViewItem (0x0x7f9a4a7ef4e0) 0 + QStyleOption (0x0x7f9a4a73cc60) 0 + +Class QStyleOptionToolBox + size=88 align=8 + base size=88 base align=8 +QStyleOptionToolBox (0x0x7f9a4a7ef618) 0 + QStyleOption (0x0x7f9a4a73ce40) 0 + +Class QStyleOptionRubberBand + size=72 align=8 + base size=69 base align=8 +QStyleOptionRubberBand (0x0x7f9a4a7ef680) 0 + QStyleOption (0x0x7f9a4a73cea0) 0 + +Class QStyleOptionComplex + size=72 align=8 + base size=72 base align=8 +QStyleOptionComplex (0x0x7f9a4a7ef6e8) 0 + QStyleOption (0x0x7f9a4a73cf00) 0 + +Class QStyleOptionSlider + size=128 align=8 + base size=121 base align=8 +QStyleOptionSlider (0x0x7f9a4a7ef750) 0 + QStyleOptionComplex (0x0x7f9a4a7ef7b8) 0 + QStyleOption (0x0x7f9a4a73cf60) 0 + +Class QStyleOptionSpinBox + size=88 align=8 + base size=81 base align=8 +QStyleOptionSpinBox (0x0x7f9a4a7ef820) 0 + QStyleOptionComplex (0x0x7f9a4a7ef888) 0 + QStyleOption (0x0x7f9a4a91d000) 0 + +Class QStyleOptionToolButton + size=136 align=8 + base size=136 base align=8 +QStyleOptionToolButton (0x0x7f9a4a7ef8f0) 0 + QStyleOptionComplex (0x0x7f9a4a7ef958) 0 + QStyleOption (0x0x7f9a4a91d060) 0 + +Class QStyleOptionComboBox + size=120 align=8 + base size=120 base align=8 +QStyleOptionComboBox (0x0x7f9a4a7efa90) 0 + QStyleOptionComplex (0x0x7f9a4a7efaf8) 0 + QStyleOption (0x0x7f9a4a91d240) 0 + +Class QStyleOptionTitleBar + size=96 align=8 + base size=96 base align=8 +QStyleOptionTitleBar (0x0x7f9a4a7efb60) 0 + QStyleOptionComplex (0x0x7f9a4a7efbc8) 0 + QStyleOption (0x0x7f9a4a91d2a0) 0 + +Class QStyleOptionGroupBox + size=120 align=8 + base size=116 base align=8 +QStyleOptionGroupBox (0x0x7f9a4a7efc30) 0 + QStyleOptionComplex (0x0x7f9a4a7efc98) 0 + QStyleOption (0x0x7f9a4a91d360) 0 + +Class QStyleOptionSizeGrip + size=80 align=8 + base size=76 base align=8 +QStyleOptionSizeGrip (0x0x7f9a4a7efd00) 0 + QStyleOptionComplex (0x0x7f9a4a7efd68) 0 + QStyleOption (0x0x7f9a4a91d3c0) 0 + +Class QStyleOptionGraphicsItem + size=152 align=8 + base size=152 base align=8 +QStyleOptionGraphicsItem (0x0x7f9a4a7efdd0) 0 + QStyleOption (0x0x7f9a4a91d420) 0 + +Class QStyleHintReturn + size=8 align=4 + base size=8 base align=4 +QStyleHintReturn (0x0x7f9a4a91d900) 0 + +Class QStyleHintReturnMask + size=16 align=8 + base size=16 base align=8 +QStyleHintReturnMask (0x0x7f9a4a5a33a8) 0 + QStyleHintReturn (0x0x7f9a4a91d960) 0 + +Class QStyleHintReturnVariant + size=24 align=8 + base size=24 base align=8 +QStyleHintReturnVariant (0x0x7f9a4a5a3410) 0 + QStyleHintReturn (0x0x7f9a4a91d9c0) 0 + +Class QAbstractItemDelegate::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemDelegate::QPrivateSignal (0x0x7f9a4a91df00) 0 empty + +Vtable for QAbstractItemDelegate +QAbstractItemDelegate::_ZTV21QAbstractItemDelegate: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QAbstractItemDelegate) +16 (int (*)(...))QAbstractItemDelegate::metaObject +24 (int (*)(...))QAbstractItemDelegate::qt_metacast +32 (int (*)(...))QAbstractItemDelegate::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemDelegate::createEditor +136 (int (*)(...))QAbstractItemDelegate::destroyEditor +144 (int (*)(...))QAbstractItemDelegate::setEditorData +152 (int (*)(...))QAbstractItemDelegate::setModelData +160 (int (*)(...))QAbstractItemDelegate::updateEditorGeometry +168 (int (*)(...))QAbstractItemDelegate::editorEvent +176 (int (*)(...))QAbstractItemDelegate::helpEvent +184 (int (*)(...))QAbstractItemDelegate::paintingRoles + +Class QAbstractItemDelegate + size=16 align=8 + base size=16 base align=8 +QAbstractItemDelegate (0x0x7f9a4a5a3958) 0 + vptr=((& QAbstractItemDelegate::_ZTV21QAbstractItemDelegate) + 16u) + QObject (0x0x7f9a4a91dea0) 0 + primary-for QAbstractItemDelegate (0x0x7f9a4a5a3958) + +Class QAbstractScrollArea::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractScrollArea::QPrivateSignal (0x0x7f9a4a5ed0c0) 0 empty + +Vtable for QAbstractScrollArea +QAbstractScrollArea::_ZTV19QAbstractScrollArea: 68u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractScrollArea) +16 (int (*)(...))QAbstractScrollArea::metaObject +24 (int (*)(...))QAbstractScrollArea::qt_metacast +32 (int (*)(...))QAbstractScrollArea::qt_metacall +40 (int (*)(...))QAbstractScrollArea::~QAbstractScrollArea +48 (int (*)(...))QAbstractScrollArea::~QAbstractScrollArea +56 (int (*)(...))QAbstractScrollArea::event +64 (int (*)(...))QAbstractScrollArea::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractScrollArea::mousePressEvent +176 (int (*)(...))QAbstractScrollArea::mouseReleaseEvent +184 (int (*)(...))QAbstractScrollArea::mouseDoubleClickEvent +192 (int (*)(...))QAbstractScrollArea::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractScrollArea::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractScrollArea::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractScrollArea::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractScrollArea::dragEnterEvent +320 (int (*)(...))QAbstractScrollArea::dragMoveEvent +328 (int (*)(...))QAbstractScrollArea::dragLeaveEvent +336 (int (*)(...))QAbstractScrollArea::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractScrollArea::viewportEvent +448 (int (*)(...))QAbstractScrollArea::scrollContentsBy +456 (int (*)(...))QAbstractScrollArea::viewportSizeHint +464 (int (*)(...))-16 +472 (int (*)(...))(& _ZTI19QAbstractScrollArea) +480 (int (*)(...))QAbstractScrollArea::_ZThn16_N19QAbstractScrollAreaD1Ev +488 (int (*)(...))QAbstractScrollArea::_ZThn16_N19QAbstractScrollAreaD0Ev +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QAbstractScrollArea + size=48 align=8 + base size=48 base align=8 +QAbstractScrollArea (0x0x7f9a4a5a39c0) 0 + vptr=((& QAbstractScrollArea::_ZTV19QAbstractScrollArea) + 16u) + QFrame (0x0x7f9a4a5a3a28) 0 + primary-for QAbstractScrollArea (0x0x7f9a4a5a39c0) + QWidget (0x0x7f9a4a5ccbd0) 0 + primary-for QFrame (0x0x7f9a4a5a3a28) + QObject (0x0x7f9a4a5ed000) 0 + primary-for QWidget (0x0x7f9a4a5ccbd0) + QPaintDevice (0x0x7f9a4a5ed060) 16 + vptr=((& QAbstractScrollArea::_ZTV19QAbstractScrollArea) + 480u) + +Class QAbstractItemView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemView::QPrivateSignal (0x0x7f9a4a5ed1e0) 0 empty + +Vtable for QAbstractItemView +QAbstractItemView::_ZTV17QAbstractItemView: 106u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAbstractItemView) +16 (int (*)(...))QAbstractItemView::metaObject +24 (int (*)(...))QAbstractItemView::qt_metacast +32 (int (*)(...))QAbstractItemView::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractItemView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QAbstractItemView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QAbstractItemView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QAbstractItemView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractScrollArea::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractItemView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QAbstractItemView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QAbstractItemView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractItemView::viewportEvent +448 (int (*)(...))QAbstractScrollArea::scrollContentsBy +456 (int (*)(...))QAbstractItemView::viewportSizeHint +464 (int (*)(...))QAbstractItemView::setModel +472 (int (*)(...))QAbstractItemView::setSelectionModel +480 (int (*)(...))QAbstractItemView::keyboardSearch +488 (int (*)(...))__cxa_pure_virtual +496 (int (*)(...))__cxa_pure_virtual +504 (int (*)(...))__cxa_pure_virtual +512 (int (*)(...))QAbstractItemView::sizeHintForRow +520 (int (*)(...))QAbstractItemView::sizeHintForColumn +528 (int (*)(...))QAbstractItemView::reset +536 (int (*)(...))QAbstractItemView::setRootIndex +544 (int (*)(...))QAbstractItemView::doItemsLayout +552 (int (*)(...))QAbstractItemView::selectAll +560 (int (*)(...))QAbstractItemView::dataChanged +568 (int (*)(...))QAbstractItemView::rowsInserted +576 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved +584 (int (*)(...))QAbstractItemView::selectionChanged +592 (int (*)(...))QAbstractItemView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QAbstractItemView::updateGeometries +624 (int (*)(...))QAbstractItemView::verticalScrollbarAction +632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction +640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))__cxa_pure_virtual +688 (int (*)(...))__cxa_pure_virtual +696 (int (*)(...))__cxa_pure_virtual +704 (int (*)(...))__cxa_pure_virtual +712 (int (*)(...))__cxa_pure_virtual +720 (int (*)(...))__cxa_pure_virtual +728 (int (*)(...))QAbstractItemView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QAbstractItemView::startDrag +760 (int (*)(...))QAbstractItemView::viewOptions +768 (int (*)(...))-16 +776 (int (*)(...))(& _ZTI17QAbstractItemView) +784 0u +792 0u +800 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +808 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +816 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QAbstractItemView + size=48 align=8 + base size=48 base align=8 +QAbstractItemView (0x0x7f9a4a5a3a90) 0 + vptr=((& QAbstractItemView::_ZTV17QAbstractItemView) + 16u) + QAbstractScrollArea (0x0x7f9a4a5a3af8) 0 + primary-for QAbstractItemView (0x0x7f9a4a5a3a90) + QFrame (0x0x7f9a4a5a3b60) 0 + primary-for QAbstractScrollArea (0x0x7f9a4a5a3af8) + QWidget (0x0x7f9a4a60e150) 0 + primary-for QFrame (0x0x7f9a4a5a3b60) + QObject (0x0x7f9a4a5ed120) 0 + primary-for QWidget (0x0x7f9a4a60e150) + QPaintDevice (0x0x7f9a4a5ed180) 16 + vptr=((& QAbstractItemView::_ZTV17QAbstractItemView) + 784u) + +Vtable for QAccessibleWidget +QAccessibleWidget::_ZTV17QAccessibleWidget: 35u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleWidget) +16 (int (*)(...))QAccessibleWidget::~QAccessibleWidget +24 (int (*)(...))QAccessibleWidget::~QAccessibleWidget +32 (int (*)(...))QAccessibleWidget::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleWidget::window +56 (int (*)(...))QAccessibleWidget::relations +64 (int (*)(...))QAccessibleWidget::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))QAccessibleWidget::parent +88 (int (*)(...))QAccessibleWidget::child +96 (int (*)(...))QAccessibleWidget::childCount +104 (int (*)(...))QAccessibleWidget::indexOfChild +112 (int (*)(...))QAccessibleWidget::text +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleWidget::rect +136 (int (*)(...))QAccessibleWidget::role +144 (int (*)(...))QAccessibleWidget::state +152 (int (*)(...))QAccessibleWidget::foregroundColor +160 (int (*)(...))QAccessibleWidget::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleWidget::interface_cast +184 (int (*)(...))QAccessibleWidget::actionNames +192 (int (*)(...))QAccessibleWidget::doAction +200 (int (*)(...))QAccessibleWidget::keyBindingsForAction +208 (int (*)(...))-16 +216 (int (*)(...))(& _ZTI17QAccessibleWidget) +224 (int (*)(...))QAccessibleWidget::_ZThn16_N17QAccessibleWidgetD1Ev +232 (int (*)(...))QAccessibleWidget::_ZThn16_N17QAccessibleWidgetD0Ev +240 (int (*)(...))QAccessibleWidget::_ZThn16_NK17QAccessibleWidget11actionNamesEv +248 (int (*)(...))QAccessibleActionInterface::localizedActionName +256 (int (*)(...))QAccessibleActionInterface::localizedActionDescription +264 (int (*)(...))QAccessibleWidget::_ZThn16_N17QAccessibleWidget8doActionERK7QString +272 (int (*)(...))QAccessibleWidget::_ZThn16_NK17QAccessibleWidget20keyBindingsForActionERK7QString + +Class QAccessibleWidget + size=32 align=8 + base size=32 base align=8 +QAccessibleWidget (0x0x7f9a4a675850) 0 + vptr=((& QAccessibleWidget::_ZTV17QAccessibleWidget) + 16u) + QAccessibleObject (0x0x7f9a4a5a3c98) 0 + primary-for QAccessibleWidget (0x0x7f9a4a675850) + QAccessibleInterface (0x0x7f9a4a5ed3c0) 0 nearly-empty + primary-for QAccessibleObject (0x0x7f9a4a5a3c98) + QAccessibleActionInterface (0x0x7f9a4a5ed420) 16 nearly-empty + vptr=((& QAccessibleWidget::_ZTV17QAccessibleWidget) + 224u) + +Class QAction::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAction::QPrivateSignal (0x0x7f9a4a5ed540) 0 empty + +Vtable for QAction +QAction::_ZTV7QAction: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QAction) +16 (int (*)(...))QAction::metaObject +24 (int (*)(...))QAction::qt_metacast +32 (int (*)(...))QAction::qt_metacall +40 (int (*)(...))QAction::~QAction +48 (int (*)(...))QAction::~QAction +56 (int (*)(...))QAction::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QAction + size=16 align=8 + base size=16 base align=8 +QAction (0x0x7f9a4a5a3d00) 0 + vptr=((& QAction::_ZTV7QAction) + 16u) + QObject (0x0x7f9a4a5ed4e0) 0 + primary-for QAction (0x0x7f9a4a5a3d00) + +Class QActionGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QActionGroup::QPrivateSignal (0x0x7f9a4a5ed600) 0 empty + +Vtable for QActionGroup +QActionGroup::_ZTV12QActionGroup: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QActionGroup) +16 (int (*)(...))QActionGroup::metaObject +24 (int (*)(...))QActionGroup::qt_metacast +32 (int (*)(...))QActionGroup::qt_metacall +40 (int (*)(...))QActionGroup::~QActionGroup +48 (int (*)(...))QActionGroup::~QActionGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QActionGroup + size=16 align=8 + base size=16 base align=8 +QActionGroup (0x0x7f9a4a5a3d68) 0 + vptr=((& QActionGroup::_ZTV12QActionGroup) + 16u) + QObject (0x0x7f9a4a5ed5a0) 0 + primary-for QActionGroup (0x0x7f9a4a5a3d68) + +Class QApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QApplication::QPrivateSignal (0x0x7f9a4a5ed6c0) 0 empty + +Vtable for QApplication +QApplication::_ZTV12QApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QApplication) +16 (int (*)(...))QApplication::metaObject +24 (int (*)(...))QApplication::qt_metacast +32 (int (*)(...))QApplication::qt_metacall +40 (int (*)(...))QApplication::~QApplication +48 (int (*)(...))QApplication::~QApplication +56 (int (*)(...))QApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QApplication::notify +120 (int (*)(...))QApplication::compressEvent + +Class QApplication + size=16 align=8 + base size=16 base align=8 +QApplication (0x0x7f9a4a5a3dd0) 0 + vptr=((& QApplication::_ZTV12QApplication) + 16u) + QGuiApplication (0x0x7f9a4a5a3e38) 0 + primary-for QApplication (0x0x7f9a4a5a3dd0) + QCoreApplication (0x0x7f9a4a5a3ea0) 0 + primary-for QGuiApplication (0x0x7f9a4a5a3e38) + QObject (0x0x7f9a4a5ed660) 0 + primary-for QCoreApplication (0x0x7f9a4a5a3ea0) + +Vtable for QLayoutItem +QLayoutItem::_ZTV11QLayoutItem: 19u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QLayoutItem) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QLayoutItem::hasHeightForWidth +96 (int (*)(...))QLayoutItem::heightForWidth +104 (int (*)(...))QLayoutItem::minimumHeightForWidth +112 (int (*)(...))QLayoutItem::invalidate +120 (int (*)(...))QLayoutItem::widget +128 (int (*)(...))QLayoutItem::layout +136 (int (*)(...))QLayoutItem::spacerItem +144 (int (*)(...))QLayoutItem::controlTypes + +Class QLayoutItem + size=16 align=8 + base size=12 base align=8 +QLayoutItem (0x0x7f9a4a5ed720) 0 + vptr=((& QLayoutItem::_ZTV11QLayoutItem) + 16u) + +Vtable for QSpacerItem +QSpacerItem::_ZTV11QSpacerItem: 19u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSpacerItem) +16 (int (*)(...))QSpacerItem::~QSpacerItem +24 (int (*)(...))QSpacerItem::~QSpacerItem +32 (int (*)(...))QSpacerItem::sizeHint +40 (int (*)(...))QSpacerItem::minimumSize +48 (int (*)(...))QSpacerItem::maximumSize +56 (int (*)(...))QSpacerItem::expandingDirections +64 (int (*)(...))QSpacerItem::setGeometry +72 (int (*)(...))QSpacerItem::geometry +80 (int (*)(...))QSpacerItem::isEmpty +88 (int (*)(...))QLayoutItem::hasHeightForWidth +96 (int (*)(...))QLayoutItem::heightForWidth +104 (int (*)(...))QLayoutItem::minimumHeightForWidth +112 (int (*)(...))QLayoutItem::invalidate +120 (int (*)(...))QLayoutItem::widget +128 (int (*)(...))QLayoutItem::layout +136 (int (*)(...))QSpacerItem::spacerItem +144 (int (*)(...))QLayoutItem::controlTypes + +Class QSpacerItem + size=40 align=8 + base size=40 base align=8 +QSpacerItem (0x0x7f9a4a5a3f08) 0 + vptr=((& QSpacerItem::_ZTV11QSpacerItem) + 16u) + QLayoutItem (0x0x7f9a4a5ed780) 0 + primary-for QSpacerItem (0x0x7f9a4a5a3f08) + +Vtable for QWidgetItem +QWidgetItem::_ZTV11QWidgetItem: 19u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QWidgetItem) +16 (int (*)(...))QWidgetItem::~QWidgetItem +24 (int (*)(...))QWidgetItem::~QWidgetItem +32 (int (*)(...))QWidgetItem::sizeHint +40 (int (*)(...))QWidgetItem::minimumSize +48 (int (*)(...))QWidgetItem::maximumSize +56 (int (*)(...))QWidgetItem::expandingDirections +64 (int (*)(...))QWidgetItem::setGeometry +72 (int (*)(...))QWidgetItem::geometry +80 (int (*)(...))QWidgetItem::isEmpty +88 (int (*)(...))QWidgetItem::hasHeightForWidth +96 (int (*)(...))QWidgetItem::heightForWidth +104 (int (*)(...))QLayoutItem::minimumHeightForWidth +112 (int (*)(...))QLayoutItem::invalidate +120 (int (*)(...))QWidgetItem::widget +128 (int (*)(...))QLayoutItem::layout +136 (int (*)(...))QLayoutItem::spacerItem +144 (int (*)(...))QWidgetItem::controlTypes + +Class QWidgetItem + size=24 align=8 + base size=24 base align=8 +QWidgetItem (0x0x7f9a4a5a3f70) 0 + vptr=((& QWidgetItem::_ZTV11QWidgetItem) + 16u) + QLayoutItem (0x0x7f9a4a5ed7e0) 0 + primary-for QWidgetItem (0x0x7f9a4a5a3f70) + +Vtable for QWidgetItemV2 +QWidgetItemV2::_ZTV13QWidgetItemV2: 19u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QWidgetItemV2) +16 (int (*)(...))QWidgetItemV2::~QWidgetItemV2 +24 (int (*)(...))QWidgetItemV2::~QWidgetItemV2 +32 (int (*)(...))QWidgetItemV2::sizeHint +40 (int (*)(...))QWidgetItemV2::minimumSize +48 (int (*)(...))QWidgetItemV2::maximumSize +56 (int (*)(...))QWidgetItem::expandingDirections +64 (int (*)(...))QWidgetItem::setGeometry +72 (int (*)(...))QWidgetItem::geometry +80 (int (*)(...))QWidgetItem::isEmpty +88 (int (*)(...))QWidgetItem::hasHeightForWidth +96 (int (*)(...))QWidgetItemV2::heightForWidth +104 (int (*)(...))QLayoutItem::minimumHeightForWidth +112 (int (*)(...))QLayoutItem::invalidate +120 (int (*)(...))QWidgetItem::widget +128 (int (*)(...))QLayoutItem::layout +136 (int (*)(...))QLayoutItem::spacerItem +144 (int (*)(...))QWidgetItem::controlTypes + +Class QWidgetItemV2 + size=88 align=8 + base size=88 base align=8 +QWidgetItemV2 (0x0x7f9a4a71d000) 0 + vptr=((& QWidgetItemV2::_ZTV13QWidgetItemV2) + 16u) + QWidgetItem (0x0x7f9a4a71d068) 0 + primary-for QWidgetItemV2 (0x0x7f9a4a71d000) + QLayoutItem (0x0x7f9a4a5ed840) 0 + primary-for QWidgetItem (0x0x7f9a4a71d068) + +Class QLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLayout::QPrivateSignal (0x0x7f9a4a5ed960) 0 empty + +Vtable for QLayout +QLayout::_ZTV7QLayout: 47u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QLayout) +16 (int (*)(...))QLayout::metaObject +24 (int (*)(...))QLayout::qt_metacast +32 (int (*)(...))QLayout::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLayout::invalidate +120 (int (*)(...))QLayout::geometry +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))QLayout::expandingDirections +144 (int (*)(...))QLayout::minimumSize +152 (int (*)(...))QLayout::maximumSize +160 (int (*)(...))QLayout::setGeometry +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))QLayout::indexOf +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))QLayout::isEmpty +208 (int (*)(...))QLayout::controlTypes +216 (int (*)(...))QLayout::layout +224 (int (*)(...))-16 +232 (int (*)(...))(& _ZTI7QLayout) +240 0u +248 0u +256 (int (*)(...))__cxa_pure_virtual +264 (int (*)(...))QLayout::_ZThn16_NK7QLayout11minimumSizeEv +272 (int (*)(...))QLayout::_ZThn16_NK7QLayout11maximumSizeEv +280 (int (*)(...))QLayout::_ZThn16_NK7QLayout19expandingDirectionsEv +288 (int (*)(...))QLayout::_ZThn16_N7QLayout11setGeometryERK5QRect +296 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +304 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +312 (int (*)(...))QLayoutItem::hasHeightForWidth +320 (int (*)(...))QLayoutItem::heightForWidth +328 (int (*)(...))QLayoutItem::minimumHeightForWidth +336 (int (*)(...))QLayout::_ZThn16_N7QLayout10invalidateEv +344 (int (*)(...))QLayoutItem::widget +352 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +360 (int (*)(...))QLayoutItem::spacerItem +368 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QLayout + size=32 align=8 + base size=28 base align=8 +QLayout (0x0x7f9a4a7028c0) 0 + vptr=((& QLayout::_ZTV7QLayout) + 16u) + QObject (0x0x7f9a4a5ed8a0) 0 + primary-for QLayout (0x0x7f9a4a7028c0) + QLayoutItem (0x0x7f9a4a5ed900) 16 + vptr=((& QLayout::_ZTV7QLayout) + 240u) + +Class QGridLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGridLayout::QPrivateSignal (0x0x7f9a4a5eda80) 0 empty + +Vtable for QGridLayout +QGridLayout::_ZTV11QGridLayout: 51u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QGridLayout) +16 (int (*)(...))QGridLayout::metaObject +24 (int (*)(...))QGridLayout::qt_metacast +32 (int (*)(...))QGridLayout::qt_metacall +40 (int (*)(...))QGridLayout::~QGridLayout +48 (int (*)(...))QGridLayout::~QGridLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGridLayout::invalidate +120 (int (*)(...))QLayout::geometry +128 (int (*)(...))QGridLayout::addItem +136 (int (*)(...))QGridLayout::expandingDirections +144 (int (*)(...))QGridLayout::minimumSize +152 (int (*)(...))QGridLayout::maximumSize +160 (int (*)(...))QGridLayout::setGeometry +168 (int (*)(...))QGridLayout::itemAt +176 (int (*)(...))QGridLayout::takeAt +184 (int (*)(...))QLayout::indexOf +192 (int (*)(...))QGridLayout::count +200 (int (*)(...))QLayout::isEmpty +208 (int (*)(...))QLayout::controlTypes +216 (int (*)(...))QLayout::layout +224 (int (*)(...))QGridLayout::sizeHint +232 (int (*)(...))QGridLayout::hasHeightForWidth +240 (int (*)(...))QGridLayout::heightForWidth +248 (int (*)(...))QGridLayout::minimumHeightForWidth +256 (int (*)(...))-16 +264 (int (*)(...))(& _ZTI11QGridLayout) +272 (int (*)(...))QGridLayout::_ZThn16_N11QGridLayoutD1Ev +280 (int (*)(...))QGridLayout::_ZThn16_N11QGridLayoutD0Ev +288 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout8sizeHintEv +296 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout11minimumSizeEv +304 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout11maximumSizeEv +312 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout19expandingDirectionsEv +320 (int (*)(...))QGridLayout::_ZThn16_N11QGridLayout11setGeometryERK5QRect +328 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +336 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +344 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout17hasHeightForWidthEv +352 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout14heightForWidthEi +360 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout21minimumHeightForWidthEi +368 (int (*)(...))QGridLayout::_ZThn16_N11QGridLayout10invalidateEv +376 (int (*)(...))QLayoutItem::widget +384 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +392 (int (*)(...))QLayoutItem::spacerItem +400 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QGridLayout + size=32 align=8 + base size=28 base align=8 +QGridLayout (0x0x7f9a4a71d0d0) 0 + vptr=((& QGridLayout::_ZTV11QGridLayout) + 16u) + QLayout (0x0x7f9a4a3470e0) 0 + primary-for QGridLayout (0x0x7f9a4a71d0d0) + QObject (0x0x7f9a4a5ed9c0) 0 + primary-for QLayout (0x0x7f9a4a3470e0) + QLayoutItem (0x0x7f9a4a5eda20) 16 + vptr=((& QGridLayout::_ZTV11QGridLayout) + 272u) + +Class QBoxLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBoxLayout::QPrivateSignal (0x0x7f9a4a5edba0) 0 empty + +Vtable for QBoxLayout +QBoxLayout::_ZTV10QBoxLayout: 51u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QBoxLayout) +16 (int (*)(...))QBoxLayout::metaObject +24 (int (*)(...))QBoxLayout::qt_metacast +32 (int (*)(...))QBoxLayout::qt_metacall +40 (int (*)(...))QBoxLayout::~QBoxLayout +48 (int (*)(...))QBoxLayout::~QBoxLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QBoxLayout::invalidate +120 (int (*)(...))QLayout::geometry +128 (int (*)(...))QBoxLayout::addItem +136 (int (*)(...))QBoxLayout::expandingDirections +144 (int (*)(...))QBoxLayout::minimumSize +152 (int (*)(...))QBoxLayout::maximumSize +160 (int (*)(...))QBoxLayout::setGeometry +168 (int (*)(...))QBoxLayout::itemAt +176 (int (*)(...))QBoxLayout::takeAt +184 (int (*)(...))QLayout::indexOf +192 (int (*)(...))QBoxLayout::count +200 (int (*)(...))QLayout::isEmpty +208 (int (*)(...))QLayout::controlTypes +216 (int (*)(...))QLayout::layout +224 (int (*)(...))QBoxLayout::sizeHint +232 (int (*)(...))QBoxLayout::hasHeightForWidth +240 (int (*)(...))QBoxLayout::heightForWidth +248 (int (*)(...))QBoxLayout::minimumHeightForWidth +256 (int (*)(...))-16 +264 (int (*)(...))(& _ZTI10QBoxLayout) +272 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayoutD1Ev +280 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayoutD0Ev +288 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout8sizeHintEv +296 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11minimumSizeEv +304 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11maximumSizeEv +312 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout19expandingDirectionsEv +320 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout11setGeometryERK5QRect +328 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +336 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +344 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout17hasHeightForWidthEv +352 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout14heightForWidthEi +360 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout21minimumHeightForWidthEi +368 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout10invalidateEv +376 (int (*)(...))QLayoutItem::widget +384 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +392 (int (*)(...))QLayoutItem::spacerItem +400 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QBoxLayout + size=32 align=8 + base size=28 base align=8 +QBoxLayout (0x0x7f9a4a71d138) 0 + vptr=((& QBoxLayout::_ZTV10QBoxLayout) + 16u) + QLayout (0x0x7f9a4a347690) 0 + primary-for QBoxLayout (0x0x7f9a4a71d138) + QObject (0x0x7f9a4a5edae0) 0 + primary-for QLayout (0x0x7f9a4a347690) + QLayoutItem (0x0x7f9a4a5edb40) 16 + vptr=((& QBoxLayout::_ZTV10QBoxLayout) + 272u) + +Class QHBoxLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHBoxLayout::QPrivateSignal (0x0x7f9a4a5edcc0) 0 empty + +Vtable for QHBoxLayout +QHBoxLayout::_ZTV11QHBoxLayout: 51u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QHBoxLayout) +16 (int (*)(...))QHBoxLayout::metaObject +24 (int (*)(...))QHBoxLayout::qt_metacast +32 (int (*)(...))QHBoxLayout::qt_metacall +40 (int (*)(...))QHBoxLayout::~QHBoxLayout +48 (int (*)(...))QHBoxLayout::~QHBoxLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QBoxLayout::invalidate +120 (int (*)(...))QLayout::geometry +128 (int (*)(...))QBoxLayout::addItem +136 (int (*)(...))QBoxLayout::expandingDirections +144 (int (*)(...))QBoxLayout::minimumSize +152 (int (*)(...))QBoxLayout::maximumSize +160 (int (*)(...))QBoxLayout::setGeometry +168 (int (*)(...))QBoxLayout::itemAt +176 (int (*)(...))QBoxLayout::takeAt +184 (int (*)(...))QLayout::indexOf +192 (int (*)(...))QBoxLayout::count +200 (int (*)(...))QLayout::isEmpty +208 (int (*)(...))QLayout::controlTypes +216 (int (*)(...))QLayout::layout +224 (int (*)(...))QBoxLayout::sizeHint +232 (int (*)(...))QBoxLayout::hasHeightForWidth +240 (int (*)(...))QBoxLayout::heightForWidth +248 (int (*)(...))QBoxLayout::minimumHeightForWidth +256 (int (*)(...))-16 +264 (int (*)(...))(& _ZTI11QHBoxLayout) +272 (int (*)(...))QHBoxLayout::_ZThn16_N11QHBoxLayoutD1Ev +280 (int (*)(...))QHBoxLayout::_ZThn16_N11QHBoxLayoutD0Ev +288 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout8sizeHintEv +296 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11minimumSizeEv +304 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11maximumSizeEv +312 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout19expandingDirectionsEv +320 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout11setGeometryERK5QRect +328 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +336 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +344 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout17hasHeightForWidthEv +352 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout14heightForWidthEi +360 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout21minimumHeightForWidthEi +368 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout10invalidateEv +376 (int (*)(...))QLayoutItem::widget +384 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +392 (int (*)(...))QLayoutItem::spacerItem +400 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QHBoxLayout + size=32 align=8 + base size=28 base align=8 +QHBoxLayout (0x0x7f9a4a71d208) 0 + vptr=((& QHBoxLayout::_ZTV11QHBoxLayout) + 16u) + QBoxLayout (0x0x7f9a4a71d270) 0 + primary-for QHBoxLayout (0x0x7f9a4a71d208) + QLayout (0x0x7f9a4a347d20) 0 + primary-for QBoxLayout (0x0x7f9a4a71d270) + QObject (0x0x7f9a4a5edc00) 0 + primary-for QLayout (0x0x7f9a4a347d20) + QLayoutItem (0x0x7f9a4a5edc60) 16 + vptr=((& QHBoxLayout::_ZTV11QHBoxLayout) + 272u) + +Class QVBoxLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVBoxLayout::QPrivateSignal (0x0x7f9a4a5edde0) 0 empty + +Vtable for QVBoxLayout +QVBoxLayout::_ZTV11QVBoxLayout: 51u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QVBoxLayout) +16 (int (*)(...))QVBoxLayout::metaObject +24 (int (*)(...))QVBoxLayout::qt_metacast +32 (int (*)(...))QVBoxLayout::qt_metacall +40 (int (*)(...))QVBoxLayout::~QVBoxLayout +48 (int (*)(...))QVBoxLayout::~QVBoxLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QBoxLayout::invalidate +120 (int (*)(...))QLayout::geometry +128 (int (*)(...))QBoxLayout::addItem +136 (int (*)(...))QBoxLayout::expandingDirections +144 (int (*)(...))QBoxLayout::minimumSize +152 (int (*)(...))QBoxLayout::maximumSize +160 (int (*)(...))QBoxLayout::setGeometry +168 (int (*)(...))QBoxLayout::itemAt +176 (int (*)(...))QBoxLayout::takeAt +184 (int (*)(...))QLayout::indexOf +192 (int (*)(...))QBoxLayout::count +200 (int (*)(...))QLayout::isEmpty +208 (int (*)(...))QLayout::controlTypes +216 (int (*)(...))QLayout::layout +224 (int (*)(...))QBoxLayout::sizeHint +232 (int (*)(...))QBoxLayout::hasHeightForWidth +240 (int (*)(...))QBoxLayout::heightForWidth +248 (int (*)(...))QBoxLayout::minimumHeightForWidth +256 (int (*)(...))-16 +264 (int (*)(...))(& _ZTI11QVBoxLayout) +272 (int (*)(...))QVBoxLayout::_ZThn16_N11QVBoxLayoutD1Ev +280 (int (*)(...))QVBoxLayout::_ZThn16_N11QVBoxLayoutD0Ev +288 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout8sizeHintEv +296 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11minimumSizeEv +304 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11maximumSizeEv +312 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout19expandingDirectionsEv +320 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout11setGeometryERK5QRect +328 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +336 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +344 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout17hasHeightForWidthEv +352 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout14heightForWidthEi +360 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout21minimumHeightForWidthEi +368 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout10invalidateEv +376 (int (*)(...))QLayoutItem::widget +384 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +392 (int (*)(...))QLayoutItem::spacerItem +400 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QVBoxLayout + size=32 align=8 + base size=28 base align=8 +QVBoxLayout (0x0x7f9a4a71d2d8) 0 + vptr=((& QVBoxLayout::_ZTV11QVBoxLayout) + 16u) + QBoxLayout (0x0x7f9a4a71d340) 0 + primary-for QVBoxLayout (0x0x7f9a4a71d2d8) + QLayout (0x0x7f9a4a347f50) 0 + primary-for QBoxLayout (0x0x7f9a4a71d340) + QObject (0x0x7f9a4a5edd20) 0 + primary-for QLayout (0x0x7f9a4a347f50) + QLayoutItem (0x0x7f9a4a5edd80) 16 + vptr=((& QVBoxLayout::_ZTV11QVBoxLayout) + 272u) + +Class QButtonGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QButtonGroup::QPrivateSignal (0x0x7f9a4a5edea0) 0 empty + +Vtable for QButtonGroup +QButtonGroup::_ZTV12QButtonGroup: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QButtonGroup) +16 (int (*)(...))QButtonGroup::metaObject +24 (int (*)(...))QButtonGroup::qt_metacast +32 (int (*)(...))QButtonGroup::qt_metacall +40 (int (*)(...))QButtonGroup::~QButtonGroup +48 (int (*)(...))QButtonGroup::~QButtonGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QButtonGroup + size=16 align=8 + base size=16 base align=8 +QButtonGroup (0x0x7f9a4a71d3a8) 0 + vptr=((& QButtonGroup::_ZTV12QButtonGroup) + 16u) + QObject (0x0x7f9a4a5ede40) 0 + primary-for QButtonGroup (0x0x7f9a4a71d3a8) + +Class QCalendarWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCalendarWidget::QPrivateSignal (0x0x7f9a4a3b4000) 0 empty + +Vtable for QCalendarWidget +QCalendarWidget::_ZTV15QCalendarWidget: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QCalendarWidget) +16 (int (*)(...))QCalendarWidget::metaObject +24 (int (*)(...))QCalendarWidget::qt_metacast +32 (int (*)(...))QCalendarWidget::qt_metacall +40 (int (*)(...))QCalendarWidget::~QCalendarWidget +48 (int (*)(...))QCalendarWidget::~QCalendarWidget +56 (int (*)(...))QCalendarWidget::event +64 (int (*)(...))QCalendarWidget::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QCalendarWidget::sizeHint +136 (int (*)(...))QCalendarWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QCalendarWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QCalendarWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QCalendarWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QCalendarWidget::paintCell +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI15QCalendarWidget) +456 (int (*)(...))QCalendarWidget::_ZThn16_N15QCalendarWidgetD1Ev +464 (int (*)(...))QCalendarWidget::_ZThn16_N15QCalendarWidgetD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QCalendarWidget + size=48 align=8 + base size=48 base align=8 +QCalendarWidget (0x0x7f9a4a71d410) 0 + vptr=((& QCalendarWidget::_ZTV15QCalendarWidget) + 16u) + QWidget (0x0x7f9a4a391460) 0 + primary-for QCalendarWidget (0x0x7f9a4a71d410) + QObject (0x0x7f9a4a5edf00) 0 + primary-for QWidget (0x0x7f9a4a391460) + QPaintDevice (0x0x7f9a4a5edf60) 16 + vptr=((& QCalendarWidget::_ZTV15QCalendarWidget) + 456u) + +Class QCheckBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCheckBox::QPrivateSignal (0x0x7f9a4a3b4120) 0 empty + +Vtable for QCheckBox +QCheckBox::_ZTV9QCheckBox: 67u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QCheckBox) +16 (int (*)(...))QCheckBox::metaObject +24 (int (*)(...))QCheckBox::qt_metacast +32 (int (*)(...))QCheckBox::qt_metacall +40 (int (*)(...))QCheckBox::~QCheckBox +48 (int (*)(...))QCheckBox::~QCheckBox +56 (int (*)(...))QCheckBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractButton::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QCheckBox::sizeHint +136 (int (*)(...))QCheckBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractButton::mousePressEvent +176 (int (*)(...))QAbstractButton::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QCheckBox::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QAbstractButton::keyPressEvent +216 (int (*)(...))QAbstractButton::keyReleaseEvent +224 (int (*)(...))QAbstractButton::focusInEvent +232 (int (*)(...))QAbstractButton::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QCheckBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractButton::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QCheckBox::hitButton +440 (int (*)(...))QCheckBox::checkStateSet +448 (int (*)(...))QCheckBox::nextCheckState +456 (int (*)(...))-16 +464 (int (*)(...))(& _ZTI9QCheckBox) +472 (int (*)(...))QCheckBox::_ZThn16_N9QCheckBoxD1Ev +480 (int (*)(...))QCheckBox::_ZThn16_N9QCheckBoxD0Ev +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QCheckBox + size=48 align=8 + base size=48 base align=8 +QCheckBox (0x0x7f9a4a71d478) 0 + vptr=((& QCheckBox::_ZTV9QCheckBox) + 16u) + QAbstractButton (0x0x7f9a4a71d4e0) 0 + primary-for QCheckBox (0x0x7f9a4a71d478) + QWidget (0x0x7f9a4a391d90) 0 + primary-for QAbstractButton (0x0x7f9a4a71d4e0) + QObject (0x0x7f9a4a3b4060) 0 + primary-for QWidget (0x0x7f9a4a391d90) + QPaintDevice (0x0x7f9a4a3b40c0) 16 + vptr=((& QCheckBox::_ZTV9QCheckBox) + 472u) + +Class QDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDialog::QPrivateSignal (0x0x7f9a4a3b4240) 0 empty + +Vtable for QDialog +QDialog::_ZTV7QDialog: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QDialog) +16 (int (*)(...))QDialog::metaObject +24 (int (*)(...))QDialog::qt_metacast +32 (int (*)(...))QDialog::qt_metacall +40 (int (*)(...))QDialog::~QDialog +48 (int (*)(...))QDialog::~QDialog +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QDialog::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI7QDialog) +488 (int (*)(...))QDialog::_ZThn16_N7QDialogD1Ev +496 (int (*)(...))QDialog::_ZThn16_N7QDialogD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDialog + size=48 align=8 + base size=48 base align=8 +QDialog (0x0x7f9a4a71d548) 0 + vptr=((& QDialog::_ZTV7QDialog) + 16u) + QWidget (0x0x7f9a4a3eb0e0) 0 + primary-for QDialog (0x0x7f9a4a71d548) + QObject (0x0x7f9a4a3b4180) 0 + primary-for QWidget (0x0x7f9a4a3eb0e0) + QPaintDevice (0x0x7f9a4a3b41e0) 16 + vptr=((& QDialog::_ZTV7QDialog) + 488u) + +Class QColorDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QColorDialog::QPrivateSignal (0x0x7f9a4a3b4360) 0 empty + +Vtable for QColorDialog +QColorDialog::_ZTV12QColorDialog: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QColorDialog) +16 (int (*)(...))QColorDialog::metaObject +24 (int (*)(...))QColorDialog::qt_metacast +32 (int (*)(...))QColorDialog::qt_metacall +40 (int (*)(...))QColorDialog::~QColorDialog +48 (int (*)(...))QColorDialog::~QColorDialog +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QColorDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QColorDialog::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QColorDialog::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI12QColorDialog) +488 (int (*)(...))QColorDialog::_ZThn16_N12QColorDialogD1Ev +496 (int (*)(...))QColorDialog::_ZThn16_N12QColorDialogD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QColorDialog + size=48 align=8 + base size=48 base align=8 +QColorDialog (0x0x7f9a4a71d5b0) 0 + vptr=((& QColorDialog::_ZTV12QColorDialog) + 16u) + QDialog (0x0x7f9a4a71d618) 0 + primary-for QColorDialog (0x0x7f9a4a71d5b0) + QWidget (0x0x7f9a4a3eb5b0) 0 + primary-for QDialog (0x0x7f9a4a71d618) + QObject (0x0x7f9a4a3b42a0) 0 + primary-for QWidget (0x0x7f9a4a3eb5b0) + QPaintDevice (0x0x7f9a4a3b4300) 16 + vptr=((& QColorDialog::_ZTV12QColorDialog) + 488u) + +Class QColormap + size=8 align=8 + base size=8 base align=8 +QColormap (0x0x7f9a4a3b45a0) 0 + +Class QColumnView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QColumnView::QPrivateSignal (0x0x7f9a4a3b46c0) 0 empty + +Vtable for QColumnView +QColumnView::_ZTV11QColumnView: 107u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QColumnView) +16 (int (*)(...))QColumnView::metaObject +24 (int (*)(...))QColumnView::qt_metacast +32 (int (*)(...))QColumnView::qt_metacall +40 (int (*)(...))QColumnView::~QColumnView +48 (int (*)(...))QColumnView::~QColumnView +56 (int (*)(...))QAbstractItemView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QAbstractItemView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QColumnView::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QAbstractItemView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QAbstractItemView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractScrollArea::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QColumnView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QAbstractItemView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QAbstractItemView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractItemView::viewportEvent +448 (int (*)(...))QColumnView::scrollContentsBy +456 (int (*)(...))QAbstractItemView::viewportSizeHint +464 (int (*)(...))QColumnView::setModel +472 (int (*)(...))QColumnView::setSelectionModel +480 (int (*)(...))QAbstractItemView::keyboardSearch +488 (int (*)(...))QColumnView::visualRect +496 (int (*)(...))QColumnView::scrollTo +504 (int (*)(...))QColumnView::indexAt +512 (int (*)(...))QAbstractItemView::sizeHintForRow +520 (int (*)(...))QAbstractItemView::sizeHintForColumn +528 (int (*)(...))QAbstractItemView::reset +536 (int (*)(...))QColumnView::setRootIndex +544 (int (*)(...))QAbstractItemView::doItemsLayout +552 (int (*)(...))QColumnView::selectAll +560 (int (*)(...))QAbstractItemView::dataChanged +568 (int (*)(...))QColumnView::rowsInserted +576 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved +584 (int (*)(...))QAbstractItemView::selectionChanged +592 (int (*)(...))QColumnView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QAbstractItemView::updateGeometries +624 (int (*)(...))QAbstractItemView::verticalScrollbarAction +632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction +640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))QColumnView::moveCursor +688 (int (*)(...))QColumnView::horizontalOffset +696 (int (*)(...))QColumnView::verticalOffset +704 (int (*)(...))QColumnView::isIndexHidden +712 (int (*)(...))QColumnView::setSelection +720 (int (*)(...))QColumnView::visualRegionForSelection +728 (int (*)(...))QAbstractItemView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QAbstractItemView::startDrag +760 (int (*)(...))QAbstractItemView::viewOptions +768 (int (*)(...))QColumnView::createColumn +776 (int (*)(...))-16 +784 (int (*)(...))(& _ZTI11QColumnView) +792 (int (*)(...))QColumnView::_ZThn16_N11QColumnViewD1Ev +800 (int (*)(...))QColumnView::_ZThn16_N11QColumnViewD0Ev +808 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +816 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +824 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +848 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QColumnView + size=48 align=8 + base size=48 base align=8 +QColumnView (0x0x7f9a4a71d750) 0 + vptr=((& QColumnView::_ZTV11QColumnView) + 16u) + QAbstractItemView (0x0x7f9a4a71d7b8) 0 + primary-for QColumnView (0x0x7f9a4a71d750) + QAbstractScrollArea (0x0x7f9a4a71d820) 0 + primary-for QAbstractItemView (0x0x7f9a4a71d7b8) + QFrame (0x0x7f9a4a71d888) 0 + primary-for QAbstractScrollArea (0x0x7f9a4a71d820) + QWidget (0x0x7f9a4a437a10) 0 + primary-for QFrame (0x0x7f9a4a71d888) + QObject (0x0x7f9a4a3b4600) 0 + primary-for QWidget (0x0x7f9a4a437a10) + QPaintDevice (0x0x7f9a4a3b4660) 16 + vptr=((& QColumnView::_ZTV11QColumnView) + 792u) + +Class QComboBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QComboBox::QPrivateSignal (0x0x7f9a4a3b47e0) 0 empty + +Vtable for QComboBox +QComboBox::_ZTV9QComboBox: 66u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QComboBox) +16 (int (*)(...))QComboBox::metaObject +24 (int (*)(...))QComboBox::qt_metacast +32 (int (*)(...))QComboBox::qt_metacall +40 (int (*)(...))QComboBox::~QComboBox +48 (int (*)(...))QComboBox::~QComboBox +56 (int (*)(...))QComboBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QComboBox::sizeHint +136 (int (*)(...))QComboBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QComboBox::mousePressEvent +176 (int (*)(...))QComboBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QComboBox::wheelEvent +208 (int (*)(...))QComboBox::keyPressEvent +216 (int (*)(...))QComboBox::keyReleaseEvent +224 (int (*)(...))QComboBox::focusInEvent +232 (int (*)(...))QComboBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QComboBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QComboBox::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QComboBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QComboBox::showEvent +352 (int (*)(...))QComboBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QComboBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QComboBox::inputMethodEvent +416 (int (*)(...))QComboBox::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QComboBox::showPopup +440 (int (*)(...))QComboBox::hidePopup +448 (int (*)(...))-16 +456 (int (*)(...))(& _ZTI9QComboBox) +464 (int (*)(...))QComboBox::_ZThn16_N9QComboBoxD1Ev +472 (int (*)(...))QComboBox::_ZThn16_N9QComboBoxD0Ev +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QComboBox + size=48 align=8 + base size=48 base align=8 +QComboBox (0x0x7f9a4a71d8f0) 0 + vptr=((& QComboBox::_ZTV9QComboBox) + 16u) + QWidget (0x0x7f9a4a437d20) 0 + primary-for QComboBox (0x0x7f9a4a71d8f0) + QObject (0x0x7f9a4a3b4720) 0 + primary-for QWidget (0x0x7f9a4a437d20) + QPaintDevice (0x0x7f9a4a3b4780) 16 + vptr=((& QComboBox::_ZTV9QComboBox) + 464u) + +Class QPushButton::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPushButton::QPrivateSignal (0x0x7f9a4a3b4900) 0 empty + +Vtable for QPushButton +QPushButton::_ZTV11QPushButton: 67u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QPushButton) +16 (int (*)(...))QPushButton::metaObject +24 (int (*)(...))QPushButton::qt_metacast +32 (int (*)(...))QPushButton::qt_metacall +40 (int (*)(...))QPushButton::~QPushButton +48 (int (*)(...))QPushButton::~QPushButton +56 (int (*)(...))QPushButton::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractButton::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QPushButton::sizeHint +136 (int (*)(...))QPushButton::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractButton::mousePressEvent +176 (int (*)(...))QAbstractButton::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractButton::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QPushButton::keyPressEvent +216 (int (*)(...))QAbstractButton::keyReleaseEvent +224 (int (*)(...))QPushButton::focusInEvent +232 (int (*)(...))QPushButton::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QPushButton::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractButton::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QAbstractButton::hitButton +440 (int (*)(...))QAbstractButton::checkStateSet +448 (int (*)(...))QAbstractButton::nextCheckState +456 (int (*)(...))-16 +464 (int (*)(...))(& _ZTI11QPushButton) +472 (int (*)(...))QPushButton::_ZThn16_N11QPushButtonD1Ev +480 (int (*)(...))QPushButton::_ZThn16_N11QPushButtonD0Ev +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QPushButton + size=48 align=8 + base size=48 base align=8 +QPushButton (0x0x7f9a4a71d958) 0 + vptr=((& QPushButton::_ZTV11QPushButton) + 16u) + QAbstractButton (0x0x7f9a4a71d9c0) 0 + primary-for QPushButton (0x0x7f9a4a71d958) + QWidget (0x0x7f9a4a47e930) 0 + primary-for QAbstractButton (0x0x7f9a4a71d9c0) + QObject (0x0x7f9a4a3b4840) 0 + primary-for QWidget (0x0x7f9a4a47e930) + QPaintDevice (0x0x7f9a4a3b48a0) 16 + vptr=((& QPushButton::_ZTV11QPushButton) + 472u) + +Class QCommandLinkButton::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCommandLinkButton::QPrivateSignal (0x0x7f9a4a3b4a20) 0 empty + +Vtable for QCommandLinkButton +QCommandLinkButton::_ZTV18QCommandLinkButton: 67u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QCommandLinkButton) +16 (int (*)(...))QCommandLinkButton::metaObject +24 (int (*)(...))QCommandLinkButton::qt_metacast +32 (int (*)(...))QCommandLinkButton::qt_metacall +40 (int (*)(...))QCommandLinkButton::~QCommandLinkButton +48 (int (*)(...))QCommandLinkButton::~QCommandLinkButton +56 (int (*)(...))QCommandLinkButton::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractButton::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QCommandLinkButton::sizeHint +136 (int (*)(...))QCommandLinkButton::minimumSizeHint +144 (int (*)(...))QCommandLinkButton::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractButton::mousePressEvent +176 (int (*)(...))QAbstractButton::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractButton::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QPushButton::keyPressEvent +216 (int (*)(...))QAbstractButton::keyReleaseEvent +224 (int (*)(...))QPushButton::focusInEvent +232 (int (*)(...))QPushButton::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QCommandLinkButton::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractButton::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QAbstractButton::hitButton +440 (int (*)(...))QAbstractButton::checkStateSet +448 (int (*)(...))QAbstractButton::nextCheckState +456 (int (*)(...))-16 +464 (int (*)(...))(& _ZTI18QCommandLinkButton) +472 (int (*)(...))QCommandLinkButton::_ZThn16_N18QCommandLinkButtonD1Ev +480 (int (*)(...))QCommandLinkButton::_ZThn16_N18QCommandLinkButtonD0Ev +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QCommandLinkButton + size=48 align=8 + base size=48 base align=8 +QCommandLinkButton (0x0x7f9a4a71da28) 0 + vptr=((& QCommandLinkButton::_ZTV18QCommandLinkButton) + 16u) + QPushButton (0x0x7f9a4a71da90) 0 + primary-for QCommandLinkButton (0x0x7f9a4a71da28) + QAbstractButton (0x0x7f9a4a71daf8) 0 + primary-for QPushButton (0x0x7f9a4a71da90) + QWidget (0x0x7f9a4a47ec40) 0 + primary-for QAbstractButton (0x0x7f9a4a71daf8) + QObject (0x0x7f9a4a3b4960) 0 + primary-for QWidget (0x0x7f9a4a47ec40) + QPaintDevice (0x0x7f9a4a3b49c0) 16 + vptr=((& QCommandLinkButton::_ZTV18QCommandLinkButton) + 472u) + +Class QCommonStyle::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCommonStyle::QPrivateSignal (0x0x7f9a4a3b4ae0) 0 empty + +Vtable for QCommonStyle +QCommonStyle::_ZTV12QCommonStyle: 37u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QCommonStyle) +16 (int (*)(...))QCommonStyle::metaObject +24 (int (*)(...))QCommonStyle::qt_metacast +32 (int (*)(...))QCommonStyle::qt_metacall +40 (int (*)(...))QCommonStyle::~QCommonStyle +48 (int (*)(...))QCommonStyle::~QCommonStyle +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCommonStyle::polish +120 (int (*)(...))QCommonStyle::unpolish +128 (int (*)(...))QCommonStyle::polish +136 (int (*)(...))QCommonStyle::unpolish +144 (int (*)(...))QCommonStyle::polish +152 (int (*)(...))QStyle::itemTextRect +160 (int (*)(...))QStyle::itemPixmapRect +168 (int (*)(...))QStyle::drawItemText +176 (int (*)(...))QStyle::drawItemPixmap +184 (int (*)(...))QStyle::standardPalette +192 (int (*)(...))QCommonStyle::drawPrimitive +200 (int (*)(...))QCommonStyle::drawControl +208 (int (*)(...))QCommonStyle::subElementRect +216 (int (*)(...))QCommonStyle::drawComplexControl +224 (int (*)(...))QCommonStyle::hitTestComplexControl +232 (int (*)(...))QCommonStyle::subControlRect +240 (int (*)(...))QCommonStyle::pixelMetric +248 (int (*)(...))QCommonStyle::sizeFromContents +256 (int (*)(...))QCommonStyle::styleHint +264 (int (*)(...))QCommonStyle::standardPixmap +272 (int (*)(...))QCommonStyle::standardIcon +280 (int (*)(...))QCommonStyle::generatedIconPixmap +288 (int (*)(...))QCommonStyle::layoutSpacing + +Class QCommonStyle + size=16 align=8 + base size=16 base align=8 +QCommonStyle (0x0x7f9a4a71db60) 0 + vptr=((& QCommonStyle::_ZTV12QCommonStyle) + 16u) + QStyle (0x0x7f9a4a71dbc8) 0 + primary-for QCommonStyle (0x0x7f9a4a71db60) + QObject (0x0x7f9a4a3b4a80) 0 + primary-for QStyle (0x0x7f9a4a71dbc8) + +Class QCompleter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCompleter::QPrivateSignal (0x0x7f9a4a3b4ba0) 0 empty + +Vtable for QCompleter +QCompleter::_ZTV10QCompleter: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QCompleter) +16 (int (*)(...))QCompleter::metaObject +24 (int (*)(...))QCompleter::qt_metacast +32 (int (*)(...))QCompleter::qt_metacall +40 (int (*)(...))QCompleter::~QCompleter +48 (int (*)(...))QCompleter::~QCompleter +56 (int (*)(...))QCompleter::event +64 (int (*)(...))QCompleter::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCompleter::pathFromIndex +120 (int (*)(...))QCompleter::splitPath + +Class QCompleter + size=16 align=8 + base size=16 base align=8 +QCompleter (0x0x7f9a4a71dc30) 0 + vptr=((& QCompleter::_ZTV10QCompleter) + 16u) + QObject (0x0x7f9a4a3b4b40) 0 + primary-for QCompleter (0x0x7f9a4a71dc30) + +Class QDataWidgetMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDataWidgetMapper::QPrivateSignal (0x0x7f9a4a3b4c60) 0 empty + +Vtable for QDataWidgetMapper +QDataWidgetMapper::_ZTV17QDataWidgetMapper: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QDataWidgetMapper) +16 (int (*)(...))QDataWidgetMapper::metaObject +24 (int (*)(...))QDataWidgetMapper::qt_metacast +32 (int (*)(...))QDataWidgetMapper::qt_metacall +40 (int (*)(...))QDataWidgetMapper::~QDataWidgetMapper +48 (int (*)(...))QDataWidgetMapper::~QDataWidgetMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QDataWidgetMapper::setCurrentIndex + +Class QDataWidgetMapper + size=16 align=8 + base size=16 base align=8 +QDataWidgetMapper (0x0x7f9a4a71dc98) 0 + vptr=((& QDataWidgetMapper::_ZTV17QDataWidgetMapper) + 16u) + QObject (0x0x7f9a4a3b4c00) 0 + primary-for QDataWidgetMapper (0x0x7f9a4a71dc98) + +Class QDateTimeEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDateTimeEdit::QPrivateSignal (0x0x7f9a4a3b4d80) 0 empty + +Vtable for QDateTimeEdit +QDateTimeEdit::_ZTV13QDateTimeEdit: 71u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QDateTimeEdit) +16 (int (*)(...))QDateTimeEdit::metaObject +24 (int (*)(...))QDateTimeEdit::qt_metacast +32 (int (*)(...))QDateTimeEdit::qt_metacall +40 (int (*)(...))QDateTimeEdit::~QDateTimeEdit +48 (int (*)(...))QDateTimeEdit::~QDateTimeEdit +56 (int (*)(...))QDateTimeEdit::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSpinBox::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QDateTimeEdit::sizeHint +136 (int (*)(...))QAbstractSpinBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QDateTimeEdit::mousePressEvent +176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent +200 (int (*)(...))QDateTimeEdit::wheelEvent +208 (int (*)(...))QDateTimeEdit::keyPressEvent +216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent +224 (int (*)(...))QDateTimeEdit::focusInEvent +232 (int (*)(...))QAbstractSpinBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QDateTimeEdit::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractSpinBox::resizeEvent +280 (int (*)(...))QAbstractSpinBox::closeEvent +288 (int (*)(...))QAbstractSpinBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QAbstractSpinBox::showEvent +352 (int (*)(...))QAbstractSpinBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSpinBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QAbstractSpinBox::inputMethodQuery +424 (int (*)(...))QDateTimeEdit::focusNextPrevChild +432 (int (*)(...))QDateTimeEdit::validate +440 (int (*)(...))QDateTimeEdit::fixup +448 (int (*)(...))QDateTimeEdit::stepBy +456 (int (*)(...))QDateTimeEdit::clear +464 (int (*)(...))QDateTimeEdit::stepEnabled +472 (int (*)(...))QDateTimeEdit::dateTimeFromText +480 (int (*)(...))QDateTimeEdit::textFromDateTime +488 (int (*)(...))-16 +496 (int (*)(...))(& _ZTI13QDateTimeEdit) +504 (int (*)(...))QDateTimeEdit::_ZThn16_N13QDateTimeEditD1Ev +512 (int (*)(...))QDateTimeEdit::_ZThn16_N13QDateTimeEditD0Ev +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDateTimeEdit + size=48 align=8 + base size=48 base align=8 +QDateTimeEdit (0x0x7f9a4a71dd00) 0 + vptr=((& QDateTimeEdit::_ZTV13QDateTimeEdit) + 16u) + QAbstractSpinBox (0x0x7f9a4a71dd68) 0 + primary-for QDateTimeEdit (0x0x7f9a4a71dd00) + QWidget (0x0x7f9a4a4e2c40) 0 + primary-for QAbstractSpinBox (0x0x7f9a4a71dd68) + QObject (0x0x7f9a4a3b4cc0) 0 + primary-for QWidget (0x0x7f9a4a4e2c40) + QPaintDevice (0x0x7f9a4a3b4d20) 16 + vptr=((& QDateTimeEdit::_ZTV13QDateTimeEdit) + 504u) + +Class QTimeEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeEdit::QPrivateSignal (0x0x7f9a4a169060) 0 empty + +Vtable for QTimeEdit +QTimeEdit::_ZTV9QTimeEdit: 71u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeEdit) +16 (int (*)(...))QTimeEdit::metaObject +24 (int (*)(...))QTimeEdit::qt_metacast +32 (int (*)(...))QTimeEdit::qt_metacall +40 (int (*)(...))QTimeEdit::~QTimeEdit +48 (int (*)(...))QTimeEdit::~QTimeEdit +56 (int (*)(...))QDateTimeEdit::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSpinBox::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QDateTimeEdit::sizeHint +136 (int (*)(...))QAbstractSpinBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QDateTimeEdit::mousePressEvent +176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent +200 (int (*)(...))QDateTimeEdit::wheelEvent +208 (int (*)(...))QDateTimeEdit::keyPressEvent +216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent +224 (int (*)(...))QDateTimeEdit::focusInEvent +232 (int (*)(...))QAbstractSpinBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QDateTimeEdit::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractSpinBox::resizeEvent +280 (int (*)(...))QAbstractSpinBox::closeEvent +288 (int (*)(...))QAbstractSpinBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QAbstractSpinBox::showEvent +352 (int (*)(...))QAbstractSpinBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSpinBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QAbstractSpinBox::inputMethodQuery +424 (int (*)(...))QDateTimeEdit::focusNextPrevChild +432 (int (*)(...))QDateTimeEdit::validate +440 (int (*)(...))QDateTimeEdit::fixup +448 (int (*)(...))QDateTimeEdit::stepBy +456 (int (*)(...))QDateTimeEdit::clear +464 (int (*)(...))QDateTimeEdit::stepEnabled +472 (int (*)(...))QDateTimeEdit::dateTimeFromText +480 (int (*)(...))QDateTimeEdit::textFromDateTime +488 (int (*)(...))-16 +496 (int (*)(...))(& _ZTI9QTimeEdit) +504 (int (*)(...))QTimeEdit::_ZThn16_N9QTimeEditD1Ev +512 (int (*)(...))QTimeEdit::_ZThn16_N9QTimeEditD0Ev +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTimeEdit + size=48 align=8 + base size=48 base align=8 +QTimeEdit (0x0x7f9a4a71dea0) 0 + vptr=((& QTimeEdit::_ZTV9QTimeEdit) + 16u) + QDateTimeEdit (0x0x7f9a4a71df08) 0 + primary-for QTimeEdit (0x0x7f9a4a71dea0) + QAbstractSpinBox (0x0x7f9a4a71df70) 0 + primary-for QDateTimeEdit (0x0x7f9a4a71df08) + QWidget (0x0x7f9a4a12a7e0) 0 + primary-for QAbstractSpinBox (0x0x7f9a4a71df70) + QObject (0x0x7f9a4a3b4f60) 0 + primary-for QWidget (0x0x7f9a4a12a7e0) + QPaintDevice (0x0x7f9a4a169000) 16 + vptr=((& QTimeEdit::_ZTV9QTimeEdit) + 504u) + +Class QDateEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDateEdit::QPrivateSignal (0x0x7f9a4a169180) 0 empty + +Vtable for QDateEdit +QDateEdit::_ZTV9QDateEdit: 71u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QDateEdit) +16 (int (*)(...))QDateEdit::metaObject +24 (int (*)(...))QDateEdit::qt_metacast +32 (int (*)(...))QDateEdit::qt_metacall +40 (int (*)(...))QDateEdit::~QDateEdit +48 (int (*)(...))QDateEdit::~QDateEdit +56 (int (*)(...))QDateTimeEdit::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSpinBox::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QDateTimeEdit::sizeHint +136 (int (*)(...))QAbstractSpinBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QDateTimeEdit::mousePressEvent +176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent +200 (int (*)(...))QDateTimeEdit::wheelEvent +208 (int (*)(...))QDateTimeEdit::keyPressEvent +216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent +224 (int (*)(...))QDateTimeEdit::focusInEvent +232 (int (*)(...))QAbstractSpinBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QDateTimeEdit::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractSpinBox::resizeEvent +280 (int (*)(...))QAbstractSpinBox::closeEvent +288 (int (*)(...))QAbstractSpinBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QAbstractSpinBox::showEvent +352 (int (*)(...))QAbstractSpinBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSpinBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QAbstractSpinBox::inputMethodQuery +424 (int (*)(...))QDateTimeEdit::focusNextPrevChild +432 (int (*)(...))QDateTimeEdit::validate +440 (int (*)(...))QDateTimeEdit::fixup +448 (int (*)(...))QDateTimeEdit::stepBy +456 (int (*)(...))QDateTimeEdit::clear +464 (int (*)(...))QDateTimeEdit::stepEnabled +472 (int (*)(...))QDateTimeEdit::dateTimeFromText +480 (int (*)(...))QDateTimeEdit::textFromDateTime +488 (int (*)(...))-16 +496 (int (*)(...))(& _ZTI9QDateEdit) +504 (int (*)(...))QDateEdit::_ZThn16_N9QDateEditD1Ev +512 (int (*)(...))QDateEdit::_ZThn16_N9QDateEditD0Ev +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDateEdit + size=48 align=8 + base size=48 base align=8 +QDateEdit (0x0x7f9a4a176000) 0 + vptr=((& QDateEdit::_ZTV9QDateEdit) + 16u) + QDateTimeEdit (0x0x7f9a4a176068) 0 + primary-for QDateEdit (0x0x7f9a4a176000) + QAbstractSpinBox (0x0x7f9a4a1760d0) 0 + primary-for QDateTimeEdit (0x0x7f9a4a176068) + QWidget (0x0x7f9a4a12aa10) 0 + primary-for QAbstractSpinBox (0x0x7f9a4a1760d0) + QObject (0x0x7f9a4a1690c0) 0 + primary-for QWidget (0x0x7f9a4a12aa10) + QPaintDevice (0x0x7f9a4a169120) 16 + vptr=((& QDateEdit::_ZTV9QDateEdit) + 504u) + +Class QDesktopWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDesktopWidget::QPrivateSignal (0x0x7f9a4a1692a0) 0 empty + +Vtable for QDesktopWidget +QDesktopWidget::_ZTV14QDesktopWidget: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QDesktopWidget) +16 (int (*)(...))QDesktopWidget::metaObject +24 (int (*)(...))QDesktopWidget::qt_metacast +32 (int (*)(...))QDesktopWidget::qt_metacall +40 (int (*)(...))QDesktopWidget::~QDesktopWidget +48 (int (*)(...))QDesktopWidget::~QDesktopWidget +56 (int (*)(...))QWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDesktopWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI14QDesktopWidget) +448 (int (*)(...))QDesktopWidget::_ZThn16_N14QDesktopWidgetD1Ev +456 (int (*)(...))QDesktopWidget::_ZThn16_N14QDesktopWidgetD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDesktopWidget + size=48 align=8 + base size=48 base align=8 +QDesktopWidget (0x0x7f9a4a176138) 0 + vptr=((& QDesktopWidget::_ZTV14QDesktopWidget) + 16u) + QWidget (0x0x7f9a4a191460) 0 + primary-for QDesktopWidget (0x0x7f9a4a176138) + QObject (0x0x7f9a4a1691e0) 0 + primary-for QWidget (0x0x7f9a4a191460) + QPaintDevice (0x0x7f9a4a169240) 16 + vptr=((& QDesktopWidget::_ZTV14QDesktopWidget) + 448u) + +Class QDial::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDial::QPrivateSignal (0x0x7f9a4a1693c0) 0 empty + +Vtable for QDial +QDial::_ZTV5QDial: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QDial) +16 (int (*)(...))QDial::metaObject +24 (int (*)(...))QDial::qt_metacast +32 (int (*)(...))QDial::qt_metacall +40 (int (*)(...))QDial::~QDial +48 (int (*)(...))QDial::~QDial +56 (int (*)(...))QDial::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSlider::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QDial::sizeHint +136 (int (*)(...))QDial::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QDial::mousePressEvent +176 (int (*)(...))QDial::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QDial::mouseMoveEvent +200 (int (*)(...))QAbstractSlider::wheelEvent +208 (int (*)(...))QAbstractSlider::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QDial::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDial::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSlider::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDial::sliderChange +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI5QDial) +456 (int (*)(...))QDial::_ZThn16_N5QDialD1Ev +464 (int (*)(...))QDial::_ZThn16_N5QDialD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDial + size=48 align=8 + base size=48 base align=8 +QDial (0x0x7f9a4a1761a0) 0 + vptr=((& QDial::_ZTV5QDial) + 16u) + QAbstractSlider (0x0x7f9a4a176208) 0 + primary-for QDial (0x0x7f9a4a1761a0) + QWidget (0x0x7f9a4a1918c0) 0 + primary-for QAbstractSlider (0x0x7f9a4a176208) + QObject (0x0x7f9a4a169300) 0 + primary-for QWidget (0x0x7f9a4a1918c0) + QPaintDevice (0x0x7f9a4a169360) 16 + vptr=((& QDial::_ZTV5QDial) + 456u) + +Class QDialogButtonBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDialogButtonBox::QPrivateSignal (0x0x7f9a4a1694e0) 0 empty + +Vtable for QDialogButtonBox +QDialogButtonBox::_ZTV16QDialogButtonBox: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QDialogButtonBox) +16 (int (*)(...))QDialogButtonBox::metaObject +24 (int (*)(...))QDialogButtonBox::qt_metacast +32 (int (*)(...))QDialogButtonBox::qt_metacall +40 (int (*)(...))QDialogButtonBox::~QDialogButtonBox +48 (int (*)(...))QDialogButtonBox::~QDialogButtonBox +56 (int (*)(...))QDialogButtonBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QDialogButtonBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI16QDialogButtonBox) +448 (int (*)(...))QDialogButtonBox::_ZThn16_N16QDialogButtonBoxD1Ev +456 (int (*)(...))QDialogButtonBox::_ZThn16_N16QDialogButtonBoxD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDialogButtonBox + size=48 align=8 + base size=48 base align=8 +QDialogButtonBox (0x0x7f9a4a176270) 0 + vptr=((& QDialogButtonBox::_ZTV16QDialogButtonBox) + 16u) + QWidget (0x0x7f9a4a191bd0) 0 + primary-for QDialogButtonBox (0x0x7f9a4a176270) + QObject (0x0x7f9a4a169420) 0 + primary-for QWidget (0x0x7f9a4a191bd0) + QPaintDevice (0x0x7f9a4a169480) 16 + vptr=((& QDialogButtonBox::_ZTV16QDialogButtonBox) + 448u) + +Vtable for QFileIconProvider +QFileIconProvider::_ZTV17QFileIconProvider: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFileIconProvider) +16 (int (*)(...))QFileIconProvider::~QFileIconProvider +24 (int (*)(...))QFileIconProvider::~QFileIconProvider +32 (int (*)(...))QFileIconProvider::icon +40 (int (*)(...))QFileIconProvider::icon +48 (int (*)(...))QFileIconProvider::type + +Class QFileIconProvider + size=16 align=8 + base size=16 base align=8 +QFileIconProvider (0x0x7f9a4a1696c0) 0 + vptr=((& QFileIconProvider::_ZTV17QFileIconProvider) + 16u) + +Class QDirModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDirModel::QPrivateSignal (0x0x7f9a4a1699c0) 0 empty + +Vtable for QDirModel +QDirModel::_ZTV9QDirModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QDirModel) +16 (int (*)(...))QDirModel::metaObject +24 (int (*)(...))QDirModel::qt_metacast +32 (int (*)(...))QDirModel::qt_metacall +40 (int (*)(...))QDirModel::~QDirModel +48 (int (*)(...))QDirModel::~QDirModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QDirModel::index +120 (int (*)(...))QDirModel::parent +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))QDirModel::rowCount +144 (int (*)(...))QDirModel::columnCount +152 (int (*)(...))QDirModel::hasChildren +160 (int (*)(...))QDirModel::data +168 (int (*)(...))QDirModel::setData +176 (int (*)(...))QDirModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QDirModel::mimeTypes +216 (int (*)(...))QDirModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QDirModel::dropMimeData +240 (int (*)(...))QDirModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QDirModel::flags +328 (int (*)(...))QDirModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QDirModel + size=16 align=8 + base size=16 base align=8 +QDirModel (0x0x7f9a4a176478) 0 + vptr=((& QDirModel::_ZTV9QDirModel) + 16u) + QAbstractItemModel (0x0x7f9a4a1764e0) 0 + primary-for QDirModel (0x0x7f9a4a176478) + QObject (0x0x7f9a4a169960) 0 + primary-for QAbstractItemModel (0x0x7f9a4a1764e0) + +Class QDockWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDockWidget::QPrivateSignal (0x0x7f9a4a169ae0) 0 empty + +Vtable for QDockWidget +QDockWidget::_ZTV11QDockWidget: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QDockWidget) +16 (int (*)(...))QDockWidget::metaObject +24 (int (*)(...))QDockWidget::qt_metacast +32 (int (*)(...))QDockWidget::qt_metacall +40 (int (*)(...))QDockWidget::~QDockWidget +48 (int (*)(...))QDockWidget::~QDockWidget +56 (int (*)(...))QDockWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QDockWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QDockWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QDockWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI11QDockWidget) +448 (int (*)(...))QDockWidget::_ZThn16_N11QDockWidgetD1Ev +456 (int (*)(...))QDockWidget::_ZThn16_N11QDockWidgetD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDockWidget + size=48 align=8 + base size=48 base align=8 +QDockWidget (0x0x7f9a4a176548) 0 + vptr=((& QDockWidget::_ZTV11QDockWidget) + 16u) + QWidget (0x0x7f9a4a22ed90) 0 + primary-for QDockWidget (0x0x7f9a4a176548) + QObject (0x0x7f9a4a169a20) 0 + primary-for QWidget (0x0x7f9a4a22ed90) + QPaintDevice (0x0x7f9a4a169a80) 16 + vptr=((& QDockWidget::_ZTV11QDockWidget) + 448u) + +Class QTileRules + size=8 align=4 + base size=8 base align=4 +QTileRules (0x0x7f9a4a2bb180) 0 + +Class QErrorMessage::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QErrorMessage::QPrivateSignal (0x0x7f9a4a2bb420) 0 empty + +Vtable for QErrorMessage +QErrorMessage::_ZTV13QErrorMessage: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QErrorMessage) +16 (int (*)(...))QErrorMessage::metaObject +24 (int (*)(...))QErrorMessage::qt_metacast +32 (int (*)(...))QErrorMessage::qt_metacall +40 (int (*)(...))QErrorMessage::~QErrorMessage +48 (int (*)(...))QErrorMessage::~QErrorMessage +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QErrorMessage::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QErrorMessage::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI13QErrorMessage) +488 (int (*)(...))QErrorMessage::_ZThn16_N13QErrorMessageD1Ev +496 (int (*)(...))QErrorMessage::_ZThn16_N13QErrorMessageD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QErrorMessage + size=48 align=8 + base size=48 base align=8 +QErrorMessage (0x0x7f9a4a176c30) 0 + vptr=((& QErrorMessage::_ZTV13QErrorMessage) + 16u) + QDialog (0x0x7f9a4a176c98) 0 + primary-for QErrorMessage (0x0x7f9a4a176c30) + QWidget (0x0x7f9a4a2ef7e0) 0 + primary-for QDialog (0x0x7f9a4a176c98) + QObject (0x0x7f9a4a2bb360) 0 + primary-for QWidget (0x0x7f9a4a2ef7e0) + QPaintDevice (0x0x7f9a4a2bb3c0) 16 + vptr=((& QErrorMessage::_ZTV13QErrorMessage) + 488u) + +Class QFileDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDialog::QPrivateSignal (0x0x7f9a4a2bb540) 0 empty + +Vtable for QFileDialog +QFileDialog::_ZTV11QFileDialog: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDialog) +16 (int (*)(...))QFileDialog::metaObject +24 (int (*)(...))QFileDialog::qt_metacast +32 (int (*)(...))QFileDialog::qt_metacall +40 (int (*)(...))QFileDialog::~QFileDialog +48 (int (*)(...))QFileDialog::~QFileDialog +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QFileDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFileDialog::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QFileDialog::done +456 (int (*)(...))QFileDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI11QFileDialog) +488 (int (*)(...))QFileDialog::_ZThn16_N11QFileDialogD1Ev +496 (int (*)(...))QFileDialog::_ZThn16_N11QFileDialogD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QFileDialog + size=48 align=8 + base size=48 base align=8 +QFileDialog (0x0x7f9a4a176d00) 0 + vptr=((& QFileDialog::_ZTV11QFileDialog) + 16u) + QDialog (0x0x7f9a4a176d68) 0 + primary-for QFileDialog (0x0x7f9a4a176d00) + QWidget (0x0x7f9a4a2efaf0) 0 + primary-for QDialog (0x0x7f9a4a176d68) + QObject (0x0x7f9a4a2bb480) 0 + primary-for QWidget (0x0x7f9a4a2efaf0) + QPaintDevice (0x0x7f9a4a2bb4e0) 16 + vptr=((& QFileDialog::_ZTV11QFileDialog) + 488u) + +Class QFileSystemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemModel::QPrivateSignal (0x0x7f9a4a2bb780) 0 empty + +Vtable for QFileSystemModel +QFileSystemModel::_ZTV16QFileSystemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QFileSystemModel) +16 (int (*)(...))QFileSystemModel::metaObject +24 (int (*)(...))QFileSystemModel::qt_metacast +32 (int (*)(...))QFileSystemModel::qt_metacall +40 (int (*)(...))QFileSystemModel::~QFileSystemModel +48 (int (*)(...))QFileSystemModel::~QFileSystemModel +56 (int (*)(...))QFileSystemModel::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QFileSystemModel::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileSystemModel::index +120 (int (*)(...))QFileSystemModel::parent +128 (int (*)(...))QFileSystemModel::sibling +136 (int (*)(...))QFileSystemModel::rowCount +144 (int (*)(...))QFileSystemModel::columnCount +152 (int (*)(...))QFileSystemModel::hasChildren +160 (int (*)(...))QFileSystemModel::data +168 (int (*)(...))QFileSystemModel::setData +176 (int (*)(...))QFileSystemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QFileSystemModel::mimeTypes +216 (int (*)(...))QFileSystemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QFileSystemModel::dropMimeData +240 (int (*)(...))QFileSystemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QFileSystemModel::fetchMore +312 (int (*)(...))QFileSystemModel::canFetchMore +320 (int (*)(...))QFileSystemModel::flags +328 (int (*)(...))QFileSystemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QFileSystemModel + size=16 align=8 + base size=16 base align=8 +QFileSystemModel (0x0x7f9a4a176ea0) 0 + vptr=((& QFileSystemModel::_ZTV16QFileSystemModel) + 16u) + QAbstractItemModel (0x0x7f9a4a176f08) 0 + primary-for QFileSystemModel (0x0x7f9a4a176ea0) + QObject (0x0x7f9a4a2bb720) 0 + primary-for QAbstractItemModel (0x0x7f9a4a176f08) + +Class QFocusFrame::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFocusFrame::QPrivateSignal (0x0x7f9a4a2bb900) 0 empty + +Vtable for QFocusFrame +QFocusFrame::_ZTV11QFocusFrame: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFocusFrame) +16 (int (*)(...))QFocusFrame::metaObject +24 (int (*)(...))QFocusFrame::qt_metacast +32 (int (*)(...))QFocusFrame::qt_metacall +40 (int (*)(...))QFocusFrame::~QFocusFrame +48 (int (*)(...))QFocusFrame::~QFocusFrame +56 (int (*)(...))QFocusFrame::event +64 (int (*)(...))QFocusFrame::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QFocusFrame::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI11QFocusFrame) +448 (int (*)(...))QFocusFrame::_ZThn16_N11QFocusFrameD1Ev +456 (int (*)(...))QFocusFrame::_ZThn16_N11QFocusFrameD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QFocusFrame + size=48 align=8 + base size=48 base align=8 +QFocusFrame (0x0x7f9a4a176f70) 0 + vptr=((& QFocusFrame::_ZTV11QFocusFrame) + 16u) + QWidget (0x0x7f9a49fc21c0) 0 + primary-for QFocusFrame (0x0x7f9a4a176f70) + QObject (0x0x7f9a4a2bb840) 0 + primary-for QWidget (0x0x7f9a49fc21c0) + QPaintDevice (0x0x7f9a4a2bb8a0) 16 + vptr=((& QFocusFrame::_ZTV11QFocusFrame) + 448u) + +Class QFontComboBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFontComboBox::QPrivateSignal (0x0x7f9a4a2bba20) 0 empty + +Vtable for QFontComboBox +QFontComboBox::_ZTV13QFontComboBox: 66u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFontComboBox) +16 (int (*)(...))QFontComboBox::metaObject +24 (int (*)(...))QFontComboBox::qt_metacast +32 (int (*)(...))QFontComboBox::qt_metacall +40 (int (*)(...))QFontComboBox::~QFontComboBox +48 (int (*)(...))QFontComboBox::~QFontComboBox +56 (int (*)(...))QFontComboBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QFontComboBox::sizeHint +136 (int (*)(...))QComboBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QComboBox::mousePressEvent +176 (int (*)(...))QComboBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QComboBox::wheelEvent +208 (int (*)(...))QComboBox::keyPressEvent +216 (int (*)(...))QComboBox::keyReleaseEvent +224 (int (*)(...))QComboBox::focusInEvent +232 (int (*)(...))QComboBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QComboBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QComboBox::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QComboBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QComboBox::showEvent +352 (int (*)(...))QComboBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QComboBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QComboBox::inputMethodEvent +416 (int (*)(...))QComboBox::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QComboBox::showPopup +440 (int (*)(...))QComboBox::hidePopup +448 (int (*)(...))-16 +456 (int (*)(...))(& _ZTI13QFontComboBox) +464 (int (*)(...))QFontComboBox::_ZThn16_N13QFontComboBoxD1Ev +472 (int (*)(...))QFontComboBox::_ZThn16_N13QFontComboBoxD0Ev +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QFontComboBox + size=48 align=8 + base size=48 base align=8 +QFontComboBox (0x0x7f9a49fd6000) 0 + vptr=((& QFontComboBox::_ZTV13QFontComboBox) + 16u) + QComboBox (0x0x7f9a49fd6068) 0 + primary-for QFontComboBox (0x0x7f9a49fd6000) + QWidget (0x0x7f9a49fc24d0) 0 + primary-for QComboBox (0x0x7f9a49fd6068) + QObject (0x0x7f9a4a2bb960) 0 + primary-for QWidget (0x0x7f9a49fc24d0) + QPaintDevice (0x0x7f9a4a2bb9c0) 16 + vptr=((& QFontComboBox::_ZTV13QFontComboBox) + 464u) + +Class QFontDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFontDialog::QPrivateSignal (0x0x7f9a4a2bbcc0) 0 empty + +Vtable for QFontDialog +QFontDialog::_ZTV11QFontDialog: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFontDialog) +16 (int (*)(...))QFontDialog::metaObject +24 (int (*)(...))QFontDialog::qt_metacast +32 (int (*)(...))QFontDialog::qt_metacall +40 (int (*)(...))QFontDialog::~QFontDialog +48 (int (*)(...))QFontDialog::~QFontDialog +56 (int (*)(...))QWidget::event +64 (int (*)(...))QFontDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QFontDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFontDialog::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QFontDialog::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI11QFontDialog) +488 (int (*)(...))QFontDialog::_ZThn16_N11QFontDialogD1Ev +496 (int (*)(...))QFontDialog::_ZThn16_N11QFontDialogD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QFontDialog + size=48 align=8 + base size=48 base align=8 +QFontDialog (0x0x7f9a49fd6208) 0 + vptr=((& QFontDialog::_ZTV11QFontDialog) + 16u) + QDialog (0x0x7f9a49fd6270) 0 + primary-for QFontDialog (0x0x7f9a49fd6208) + QWidget (0x0x7f9a4a00e4d0) 0 + primary-for QDialog (0x0x7f9a49fd6270) + QObject (0x0x7f9a4a2bbc00) 0 + primary-for QWidget (0x0x7f9a4a00e4d0) + QPaintDevice (0x0x7f9a4a2bbc60) 16 + vptr=((& QFontDialog::_ZTV11QFontDialog) + 488u) + +Class QFormLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFormLayout::QPrivateSignal (0x0x7f9a4a2bbf60) 0 empty + +Class QFormLayout::TakeRowResult + size=16 align=8 + base size=16 base align=8 +QFormLayout::TakeRowResult (0x0x7f9a4a073000) 0 + +Vtable for QFormLayout +QFormLayout::_ZTV11QFormLayout: 50u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFormLayout) +16 (int (*)(...))QFormLayout::metaObject +24 (int (*)(...))QFormLayout::qt_metacast +32 (int (*)(...))QFormLayout::qt_metacall +40 (int (*)(...))QFormLayout::~QFormLayout +48 (int (*)(...))QFormLayout::~QFormLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFormLayout::invalidate +120 (int (*)(...))QLayout::geometry +128 (int (*)(...))QFormLayout::addItem +136 (int (*)(...))QFormLayout::expandingDirections +144 (int (*)(...))QFormLayout::minimumSize +152 (int (*)(...))QLayout::maximumSize +160 (int (*)(...))QFormLayout::setGeometry +168 (int (*)(...))QFormLayout::itemAt +176 (int (*)(...))QFormLayout::takeAt +184 (int (*)(...))QLayout::indexOf +192 (int (*)(...))QFormLayout::count +200 (int (*)(...))QLayout::isEmpty +208 (int (*)(...))QLayout::controlTypes +216 (int (*)(...))QLayout::layout +224 (int (*)(...))QFormLayout::sizeHint +232 (int (*)(...))QFormLayout::hasHeightForWidth +240 (int (*)(...))QFormLayout::heightForWidth +248 (int (*)(...))-16 +256 (int (*)(...))(& _ZTI11QFormLayout) +264 (int (*)(...))QFormLayout::_ZThn16_N11QFormLayoutD1Ev +272 (int (*)(...))QFormLayout::_ZThn16_N11QFormLayoutD0Ev +280 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout8sizeHintEv +288 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout11minimumSizeEv +296 (int (*)(...))QLayout::_ZThn16_NK7QLayout11maximumSizeEv +304 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout19expandingDirectionsEv +312 (int (*)(...))QFormLayout::_ZThn16_N11QFormLayout11setGeometryERK5QRect +320 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +328 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +336 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout17hasHeightForWidthEv +344 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout14heightForWidthEi +352 (int (*)(...))QLayoutItem::minimumHeightForWidth +360 (int (*)(...))QFormLayout::_ZThn16_N11QFormLayout10invalidateEv +368 (int (*)(...))QLayoutItem::widget +376 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +384 (int (*)(...))QLayoutItem::spacerItem +392 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QFormLayout + size=32 align=8 + base size=28 base align=8 +QFormLayout (0x0x7f9a49fd63a8) 0 + vptr=((& QFormLayout::_ZTV11QFormLayout) + 16u) + QLayout (0x0x7f9a4a04d8c0) 0 + primary-for QFormLayout (0x0x7f9a49fd63a8) + QObject (0x0x7f9a4a2bbea0) 0 + primary-for QLayout (0x0x7f9a4a04d8c0) + QLayoutItem (0x0x7f9a4a2bbf00) 16 + vptr=((& QFormLayout::_ZTV11QFormLayout) + 264u) + +Class QGesture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGesture::QPrivateSignal (0x0x7f9a4a073540) 0 empty + +Vtable for QGesture +QGesture::_ZTV8QGesture: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QGesture) +16 (int (*)(...))QGesture::metaObject +24 (int (*)(...))QGesture::qt_metacast +32 (int (*)(...))QGesture::qt_metacall +40 (int (*)(...))QGesture::~QGesture +48 (int (*)(...))QGesture::~QGesture +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QGesture + size=16 align=8 + base size=16 base align=8 +QGesture (0x0x7f9a49fd65b0) 0 + vptr=((& QGesture::_ZTV8QGesture) + 16u) + QObject (0x0x7f9a4a0734e0) 0 + primary-for QGesture (0x0x7f9a49fd65b0) + +Class QPanGesture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPanGesture::QPrivateSignal (0x0x7f9a4a073600) 0 empty + +Vtable for QPanGesture +QPanGesture::_ZTV11QPanGesture: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QPanGesture) +16 (int (*)(...))QPanGesture::metaObject +24 (int (*)(...))QPanGesture::qt_metacast +32 (int (*)(...))QPanGesture::qt_metacall +40 (int (*)(...))QPanGesture::~QPanGesture +48 (int (*)(...))QPanGesture::~QPanGesture +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPanGesture + size=16 align=8 + base size=16 base align=8 +QPanGesture (0x0x7f9a49fd6618) 0 + vptr=((& QPanGesture::_ZTV11QPanGesture) + 16u) + QGesture (0x0x7f9a49fd6680) 0 + primary-for QPanGesture (0x0x7f9a49fd6618) + QObject (0x0x7f9a4a0735a0) 0 + primary-for QGesture (0x0x7f9a49fd6680) + +Class QPinchGesture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPinchGesture::QPrivateSignal (0x0x7f9a4a0736c0) 0 empty + +Vtable for QPinchGesture +QPinchGesture::_ZTV13QPinchGesture: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPinchGesture) +16 (int (*)(...))QPinchGesture::metaObject +24 (int (*)(...))QPinchGesture::qt_metacast +32 (int (*)(...))QPinchGesture::qt_metacall +40 (int (*)(...))QPinchGesture::~QPinchGesture +48 (int (*)(...))QPinchGesture::~QPinchGesture +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPinchGesture + size=16 align=8 + base size=16 base align=8 +QPinchGesture (0x0x7f9a49fd66e8) 0 + vptr=((& QPinchGesture::_ZTV13QPinchGesture) + 16u) + QGesture (0x0x7f9a49fd6750) 0 + primary-for QPinchGesture (0x0x7f9a49fd66e8) + QObject (0x0x7f9a4a073660) 0 + primary-for QGesture (0x0x7f9a49fd6750) + +Class QSwipeGesture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSwipeGesture::QPrivateSignal (0x0x7f9a4a073a20) 0 empty + +Vtable for QSwipeGesture +QSwipeGesture::_ZTV13QSwipeGesture: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSwipeGesture) +16 (int (*)(...))QSwipeGesture::metaObject +24 (int (*)(...))QSwipeGesture::qt_metacast +32 (int (*)(...))QSwipeGesture::qt_metacall +40 (int (*)(...))QSwipeGesture::~QSwipeGesture +48 (int (*)(...))QSwipeGesture::~QSwipeGesture +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSwipeGesture + size=16 align=8 + base size=16 base align=8 +QSwipeGesture (0x0x7f9a49fd6888) 0 + vptr=((& QSwipeGesture::_ZTV13QSwipeGesture) + 16u) + QGesture (0x0x7f9a49fd68f0) 0 + primary-for QSwipeGesture (0x0x7f9a49fd6888) + QObject (0x0x7f9a4a0739c0) 0 + primary-for QGesture (0x0x7f9a49fd68f0) + +Class QTapGesture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTapGesture::QPrivateSignal (0x0x7f9a4a073b40) 0 empty + +Vtable for QTapGesture +QTapGesture::_ZTV11QTapGesture: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTapGesture) +16 (int (*)(...))QTapGesture::metaObject +24 (int (*)(...))QTapGesture::qt_metacast +32 (int (*)(...))QTapGesture::qt_metacall +40 (int (*)(...))QTapGesture::~QTapGesture +48 (int (*)(...))QTapGesture::~QTapGesture +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTapGesture + size=16 align=8 + base size=16 base align=8 +QTapGesture (0x0x7f9a49fd6958) 0 + vptr=((& QTapGesture::_ZTV11QTapGesture) + 16u) + QGesture (0x0x7f9a49fd69c0) 0 + primary-for QTapGesture (0x0x7f9a49fd6958) + QObject (0x0x7f9a4a073ae0) 0 + primary-for QGesture (0x0x7f9a49fd69c0) + +Class QTapAndHoldGesture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTapAndHoldGesture::QPrivateSignal (0x0x7f9a4a073c00) 0 empty + +Vtable for QTapAndHoldGesture +QTapAndHoldGesture::_ZTV18QTapAndHoldGesture: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QTapAndHoldGesture) +16 (int (*)(...))QTapAndHoldGesture::metaObject +24 (int (*)(...))QTapAndHoldGesture::qt_metacast +32 (int (*)(...))QTapAndHoldGesture::qt_metacall +40 (int (*)(...))QTapAndHoldGesture::~QTapAndHoldGesture +48 (int (*)(...))QTapAndHoldGesture::~QTapAndHoldGesture +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTapAndHoldGesture + size=16 align=8 + base size=16 base align=8 +QTapAndHoldGesture (0x0x7f9a49fd6a28) 0 + vptr=((& QTapAndHoldGesture::_ZTV18QTapAndHoldGesture) + 16u) + QGesture (0x0x7f9a49fd6a90) 0 + primary-for QTapAndHoldGesture (0x0x7f9a49fd6a28) + QObject (0x0x7f9a4a073ba0) 0 + primary-for QGesture (0x0x7f9a49fd6a90) + +Vtable for QGestureEvent +QGestureEvent::_ZTV13QGestureEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QGestureEvent) +16 (int (*)(...))QGestureEvent::~QGestureEvent +24 (int (*)(...))QGestureEvent::~QGestureEvent + +Class QGestureEvent + size=56 align=8 + base size=56 base align=8 +QGestureEvent (0x0x7f9a49fd6af8) 0 + vptr=((& QGestureEvent::_ZTV13QGestureEvent) + 16u) + QEvent (0x0x7f9a4a073c60) 0 + primary-for QGestureEvent (0x0x7f9a49fd6af8) + +Vtable for QGestureRecognizer +QGestureRecognizer::_ZTV18QGestureRecognizer: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QGestureRecognizer) +16 0u +24 0u +32 (int (*)(...))QGestureRecognizer::create +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QGestureRecognizer::reset + +Class QGestureRecognizer + size=8 align=8 + base size=8 base align=8 +QGestureRecognizer (0x0x7f9a5baf0660) 0 nearly-empty + vptr=((& QGestureRecognizer::_ZTV18QGestureRecognizer) + 16u) + +Vtable for QGraphicsItem +QGraphicsItem::_ZTV13QGraphicsItem: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QGraphicsItem) +16 0u +24 0u +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QGraphicsItem::shape +56 (int (*)(...))QGraphicsItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsItem::isObscuredBy +88 (int (*)(...))QGraphicsItem::opaqueArea +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))QGraphicsItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsItem::supportsExtension +296 (int (*)(...))QGraphicsItem::setExtension +304 (int (*)(...))QGraphicsItem::extension + +Class QGraphicsItem + size=16 align=8 + base size=16 base align=8 +QGraphicsItem (0x0x7f9a5bb66660) 0 + vptr=((& QGraphicsItem::_ZTV13QGraphicsItem) + 16u) + +Class QGraphicsObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsObject::QPrivateSignal (0x0x7f9a5442b300) 0 empty + +Vtable for QGraphicsObject +QGraphicsObject::_ZTV15QGraphicsObject: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGraphicsObject) +16 (int (*)(...))QGraphicsObject::metaObject +24 (int (*)(...))QGraphicsObject::qt_metacast +32 (int (*)(...))QGraphicsObject::qt_metacall +40 0u +48 0u +56 (int (*)(...))QGraphicsObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))-16 +120 (int (*)(...))(& _ZTI15QGraphicsObject) +128 0u +136 0u +144 (int (*)(...))QGraphicsItem::advance +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))QGraphicsItem::shape +168 (int (*)(...))QGraphicsItem::contains +176 (int (*)(...))QGraphicsItem::collidesWithItem +184 (int (*)(...))QGraphicsItem::collidesWithPath +192 (int (*)(...))QGraphicsItem::isObscuredBy +200 (int (*)(...))QGraphicsItem::opaqueArea +208 (int (*)(...))__cxa_pure_virtual +216 (int (*)(...))QGraphicsItem::type +224 (int (*)(...))QGraphicsItem::sceneEventFilter +232 (int (*)(...))QGraphicsItem::sceneEvent +240 (int (*)(...))QGraphicsItem::contextMenuEvent +248 (int (*)(...))QGraphicsItem::dragEnterEvent +256 (int (*)(...))QGraphicsItem::dragLeaveEvent +264 (int (*)(...))QGraphicsItem::dragMoveEvent +272 (int (*)(...))QGraphicsItem::dropEvent +280 (int (*)(...))QGraphicsItem::focusInEvent +288 (int (*)(...))QGraphicsItem::focusOutEvent +296 (int (*)(...))QGraphicsItem::hoverEnterEvent +304 (int (*)(...))QGraphicsItem::hoverMoveEvent +312 (int (*)(...))QGraphicsItem::hoverLeaveEvent +320 (int (*)(...))QGraphicsItem::keyPressEvent +328 (int (*)(...))QGraphicsItem::keyReleaseEvent +336 (int (*)(...))QGraphicsItem::mousePressEvent +344 (int (*)(...))QGraphicsItem::mouseMoveEvent +352 (int (*)(...))QGraphicsItem::mouseReleaseEvent +360 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +368 (int (*)(...))QGraphicsItem::wheelEvent +376 (int (*)(...))QGraphicsItem::inputMethodEvent +384 (int (*)(...))QGraphicsItem::inputMethodQuery +392 (int (*)(...))QGraphicsItem::itemChange +400 (int (*)(...))QGraphicsItem::supportsExtension +408 (int (*)(...))QGraphicsItem::setExtension +416 (int (*)(...))QGraphicsItem::extension + +Class QGraphicsObject + size=32 align=8 + base size=32 base align=8 +QGraphicsObject (0x0x7f9a56ee2d90) 0 + vptr=((& QGraphicsObject::_ZTV15QGraphicsObject) + 16u) + QObject (0x0x7f9a55fc6ea0) 0 + primary-for QGraphicsObject (0x0x7f9a56ee2d90) + QGraphicsItem (0x0x7f9a5442b2a0) 16 + vptr=((& QGraphicsObject::_ZTV15QGraphicsObject) + 128u) + +Vtable for QAbstractGraphicsShapeItem +QAbstractGraphicsShapeItem::_ZTV26QAbstractGraphicsShapeItem: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractGraphicsShapeItem) +16 0u +24 0u +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QGraphicsItem::shape +56 (int (*)(...))QGraphicsItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QAbstractGraphicsShapeItem::isObscuredBy +88 (int (*)(...))QAbstractGraphicsShapeItem::opaqueArea +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))QGraphicsItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsItem::supportsExtension +296 (int (*)(...))QGraphicsItem::setExtension +304 (int (*)(...))QGraphicsItem::extension + +Class QAbstractGraphicsShapeItem + size=16 align=8 + base size=16 base align=8 +QAbstractGraphicsShapeItem (0x0x7f9a55e3a000) 0 + vptr=((& QAbstractGraphicsShapeItem::_ZTV26QAbstractGraphicsShapeItem) + 16u) + QGraphicsItem (0x0x7f9a5442b600) 0 + primary-for QAbstractGraphicsShapeItem (0x0x7f9a55e3a000) + +Vtable for QGraphicsPathItem +QGraphicsPathItem::_ZTV17QGraphicsPathItem: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QGraphicsPathItem) +16 (int (*)(...))QGraphicsPathItem::~QGraphicsPathItem +24 (int (*)(...))QGraphicsPathItem::~QGraphicsPathItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsPathItem::boundingRect +48 (int (*)(...))QGraphicsPathItem::shape +56 (int (*)(...))QGraphicsPathItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsPathItem::isObscuredBy +88 (int (*)(...))QGraphicsPathItem::opaqueArea +96 (int (*)(...))QGraphicsPathItem::paint +104 (int (*)(...))QGraphicsPathItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsPathItem::supportsExtension +296 (int (*)(...))QGraphicsPathItem::setExtension +304 (int (*)(...))QGraphicsPathItem::extension + +Class QGraphicsPathItem + size=16 align=8 + base size=16 base align=8 +QGraphicsPathItem (0x0x7f9a55e3a068) 0 + vptr=((& QGraphicsPathItem::_ZTV17QGraphicsPathItem) + 16u) + QAbstractGraphicsShapeItem (0x0x7f9a55e3a0d0) 0 + primary-for QGraphicsPathItem (0x0x7f9a55e3a068) + QGraphicsItem (0x0x7f9a5442b660) 0 + primary-for QAbstractGraphicsShapeItem (0x0x7f9a55e3a0d0) + +Vtable for QGraphicsRectItem +QGraphicsRectItem::_ZTV17QGraphicsRectItem: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QGraphicsRectItem) +16 (int (*)(...))QGraphicsRectItem::~QGraphicsRectItem +24 (int (*)(...))QGraphicsRectItem::~QGraphicsRectItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsRectItem::boundingRect +48 (int (*)(...))QGraphicsRectItem::shape +56 (int (*)(...))QGraphicsRectItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsRectItem::isObscuredBy +88 (int (*)(...))QGraphicsRectItem::opaqueArea +96 (int (*)(...))QGraphicsRectItem::paint +104 (int (*)(...))QGraphicsRectItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsRectItem::supportsExtension +296 (int (*)(...))QGraphicsRectItem::setExtension +304 (int (*)(...))QGraphicsRectItem::extension + +Class QGraphicsRectItem + size=16 align=8 + base size=16 base align=8 +QGraphicsRectItem (0x0x7f9a55a8b068) 0 + vptr=((& QGraphicsRectItem::_ZTV17QGraphicsRectItem) + 16u) + QAbstractGraphicsShapeItem (0x0x7f9a55a8b208) 0 + primary-for QGraphicsRectItem (0x0x7f9a55a8b068) + QGraphicsItem (0x0x7f9a54055c60) 0 + primary-for QAbstractGraphicsShapeItem (0x0x7f9a55a8b208) + +Vtable for QGraphicsEllipseItem +QGraphicsEllipseItem::_ZTV20QGraphicsEllipseItem: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QGraphicsEllipseItem) +16 (int (*)(...))QGraphicsEllipseItem::~QGraphicsEllipseItem +24 (int (*)(...))QGraphicsEllipseItem::~QGraphicsEllipseItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsEllipseItem::boundingRect +48 (int (*)(...))QGraphicsEllipseItem::shape +56 (int (*)(...))QGraphicsEllipseItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsEllipseItem::isObscuredBy +88 (int (*)(...))QGraphicsEllipseItem::opaqueArea +96 (int (*)(...))QGraphicsEllipseItem::paint +104 (int (*)(...))QGraphicsEllipseItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsEllipseItem::supportsExtension +296 (int (*)(...))QGraphicsEllipseItem::setExtension +304 (int (*)(...))QGraphicsEllipseItem::extension + +Class QGraphicsEllipseItem + size=16 align=8 + base size=16 base align=8 +QGraphicsEllipseItem (0x0x7f9a55a8b270) 0 + vptr=((& QGraphicsEllipseItem::_ZTV20QGraphicsEllipseItem) + 16u) + QAbstractGraphicsShapeItem (0x0x7f9a54bdc1a0) 0 + primary-for QGraphicsEllipseItem (0x0x7f9a55a8b270) + QGraphicsItem (0x0x7f9a54055cc0) 0 + primary-for QAbstractGraphicsShapeItem (0x0x7f9a54bdc1a0) + +Vtable for QGraphicsPolygonItem +QGraphicsPolygonItem::_ZTV20QGraphicsPolygonItem: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QGraphicsPolygonItem) +16 (int (*)(...))QGraphicsPolygonItem::~QGraphicsPolygonItem +24 (int (*)(...))QGraphicsPolygonItem::~QGraphicsPolygonItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsPolygonItem::boundingRect +48 (int (*)(...))QGraphicsPolygonItem::shape +56 (int (*)(...))QGraphicsPolygonItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsPolygonItem::isObscuredBy +88 (int (*)(...))QGraphicsPolygonItem::opaqueArea +96 (int (*)(...))QGraphicsPolygonItem::paint +104 (int (*)(...))QGraphicsPolygonItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsPolygonItem::supportsExtension +296 (int (*)(...))QGraphicsPolygonItem::setExtension +304 (int (*)(...))QGraphicsPolygonItem::extension + +Class QGraphicsPolygonItem + size=16 align=8 + base size=16 base align=8 +QGraphicsPolygonItem (0x0x7f9a54bdc8f0) 0 + vptr=((& QGraphicsPolygonItem::_ZTV20QGraphicsPolygonItem) + 16u) + QAbstractGraphicsShapeItem (0x0x7f9a54bdc958) 0 + primary-for QGraphicsPolygonItem (0x0x7f9a54bdc8f0) + QGraphicsItem (0x0x7f9a53cad600) 0 + primary-for QAbstractGraphicsShapeItem (0x0x7f9a54bdc958) + +Vtable for QGraphicsLineItem +QGraphicsLineItem::_ZTV17QGraphicsLineItem: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QGraphicsLineItem) +16 (int (*)(...))QGraphicsLineItem::~QGraphicsLineItem +24 (int (*)(...))QGraphicsLineItem::~QGraphicsLineItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsLineItem::boundingRect +48 (int (*)(...))QGraphicsLineItem::shape +56 (int (*)(...))QGraphicsLineItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsLineItem::isObscuredBy +88 (int (*)(...))QGraphicsLineItem::opaqueArea +96 (int (*)(...))QGraphicsLineItem::paint +104 (int (*)(...))QGraphicsLineItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsLineItem::supportsExtension +296 (int (*)(...))QGraphicsLineItem::setExtension +304 (int (*)(...))QGraphicsLineItem::extension + +Class QGraphicsLineItem + size=16 align=8 + base size=16 base align=8 +QGraphicsLineItem (0x0x7f9a54bdc9c0) 0 + vptr=((& QGraphicsLineItem::_ZTV17QGraphicsLineItem) + 16u) + QGraphicsItem (0x0x7f9a53cad660) 0 + primary-for QGraphicsLineItem (0x0x7f9a54bdc9c0) + +Vtable for QGraphicsPixmapItem +QGraphicsPixmapItem::_ZTV19QGraphicsPixmapItem: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QGraphicsPixmapItem) +16 (int (*)(...))QGraphicsPixmapItem::~QGraphicsPixmapItem +24 (int (*)(...))QGraphicsPixmapItem::~QGraphicsPixmapItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsPixmapItem::boundingRect +48 (int (*)(...))QGraphicsPixmapItem::shape +56 (int (*)(...))QGraphicsPixmapItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsPixmapItem::isObscuredBy +88 (int (*)(...))QGraphicsPixmapItem::opaqueArea +96 (int (*)(...))QGraphicsPixmapItem::paint +104 (int (*)(...))QGraphicsPixmapItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsPixmapItem::supportsExtension +296 (int (*)(...))QGraphicsPixmapItem::setExtension +304 (int (*)(...))QGraphicsPixmapItem::extension + +Class QGraphicsPixmapItem + size=16 align=8 + base size=16 base align=8 +QGraphicsPixmapItem (0x0x7f9a54bdca28) 0 + vptr=((& QGraphicsPixmapItem::_ZTV19QGraphicsPixmapItem) + 16u) + QGraphicsItem (0x0x7f9a53cadd20) 0 + primary-for QGraphicsPixmapItem (0x0x7f9a54bdca28) + +Class QGraphicsTextItem::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsTextItem::QPrivateSignal (0x0x7f9a53cadf00) 0 empty + +Vtable for QGraphicsTextItem +QGraphicsTextItem::_ZTV17QGraphicsTextItem: 82u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QGraphicsTextItem) +16 (int (*)(...))QGraphicsTextItem::metaObject +24 (int (*)(...))QGraphicsTextItem::qt_metacast +32 (int (*)(...))QGraphicsTextItem::qt_metacall +40 (int (*)(...))QGraphicsTextItem::~QGraphicsTextItem +48 (int (*)(...))QGraphicsTextItem::~QGraphicsTextItem +56 (int (*)(...))QGraphicsObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsTextItem::boundingRect +120 (int (*)(...))QGraphicsTextItem::shape +128 (int (*)(...))QGraphicsTextItem::contains +136 (int (*)(...))QGraphicsTextItem::paint +144 (int (*)(...))QGraphicsTextItem::isObscuredBy +152 (int (*)(...))QGraphicsTextItem::opaqueArea +160 (int (*)(...))QGraphicsTextItem::type +168 (int (*)(...))QGraphicsTextItem::sceneEvent +176 (int (*)(...))QGraphicsTextItem::mousePressEvent +184 (int (*)(...))QGraphicsTextItem::mouseMoveEvent +192 (int (*)(...))QGraphicsTextItem::mouseReleaseEvent +200 (int (*)(...))QGraphicsTextItem::mouseDoubleClickEvent +208 (int (*)(...))QGraphicsTextItem::contextMenuEvent +216 (int (*)(...))QGraphicsTextItem::keyPressEvent +224 (int (*)(...))QGraphicsTextItem::keyReleaseEvent +232 (int (*)(...))QGraphicsTextItem::focusInEvent +240 (int (*)(...))QGraphicsTextItem::focusOutEvent +248 (int (*)(...))QGraphicsTextItem::dragEnterEvent +256 (int (*)(...))QGraphicsTextItem::dragLeaveEvent +264 (int (*)(...))QGraphicsTextItem::dragMoveEvent +272 (int (*)(...))QGraphicsTextItem::dropEvent +280 (int (*)(...))QGraphicsTextItem::inputMethodEvent +288 (int (*)(...))QGraphicsTextItem::hoverEnterEvent +296 (int (*)(...))QGraphicsTextItem::hoverMoveEvent +304 (int (*)(...))QGraphicsTextItem::hoverLeaveEvent +312 (int (*)(...))QGraphicsTextItem::inputMethodQuery +320 (int (*)(...))QGraphicsTextItem::supportsExtension +328 (int (*)(...))QGraphicsTextItem::setExtension +336 (int (*)(...))QGraphicsTextItem::extension +344 (int (*)(...))-16 +352 (int (*)(...))(& _ZTI17QGraphicsTextItem) +360 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItemD1Ev +368 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItemD0Ev +376 (int (*)(...))QGraphicsItem::advance +384 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem12boundingRectEv +392 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem5shapeEv +400 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem8containsERK7QPointF +408 (int (*)(...))QGraphicsItem::collidesWithItem +416 (int (*)(...))QGraphicsItem::collidesWithPath +424 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem12isObscuredByEPK13QGraphicsItem +432 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem10opaqueAreaEv +440 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem5paintEP8QPainterPK24QStyleOptionGraphicsItemP7QWidget +448 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem4typeEv +456 (int (*)(...))QGraphicsItem::sceneEventFilter +464 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem10sceneEventEP6QEvent +472 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem16contextMenuEventEP30QGraphicsSceneContextMenuEvent +480 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem14dragEnterEventEP27QGraphicsSceneDragDropEvent +488 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem14dragLeaveEventEP27QGraphicsSceneDragDropEvent +496 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem13dragMoveEventEP27QGraphicsSceneDragDropEvent +504 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem9dropEventEP27QGraphicsSceneDragDropEvent +512 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem12focusInEventEP11QFocusEvent +520 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem13focusOutEventEP11QFocusEvent +528 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem15hoverEnterEventEP24QGraphicsSceneHoverEvent +536 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem14hoverMoveEventEP24QGraphicsSceneHoverEvent +544 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem15hoverLeaveEventEP24QGraphicsSceneHoverEvent +552 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem13keyPressEventEP9QKeyEvent +560 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem15keyReleaseEventEP9QKeyEvent +568 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem15mousePressEventEP24QGraphicsSceneMouseEvent +576 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem14mouseMoveEventEP24QGraphicsSceneMouseEvent +584 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem17mouseReleaseEventEP24QGraphicsSceneMouseEvent +592 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem21mouseDoubleClickEventEP24QGraphicsSceneMouseEvent +600 (int (*)(...))QGraphicsItem::wheelEvent +608 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem16inputMethodEventEP17QInputMethodEvent +616 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem16inputMethodQueryEN2Qt16InputMethodQueryE +624 (int (*)(...))QGraphicsItem::itemChange +632 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem17supportsExtensionEN13QGraphicsItem9ExtensionE +640 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem12setExtensionEN13QGraphicsItem9ExtensionERK8QVariant +648 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem9extensionERK8QVariant + +Class QGraphicsTextItem + size=40 align=8 + base size=40 base align=8 +QGraphicsTextItem (0x0x7f9a54bdca90) 0 + vptr=((& QGraphicsTextItem::_ZTV17QGraphicsTextItem) + 16u) + QGraphicsObject (0x0x7f9a56f164d0) 0 + primary-for QGraphicsTextItem (0x0x7f9a54bdca90) + QObject (0x0x7f9a53cadd80) 0 + primary-for QGraphicsObject (0x0x7f9a56f164d0) + QGraphicsItem (0x0x7f9a53cade40) 16 + vptr=((& QGraphicsTextItem::_ZTV17QGraphicsTextItem) + 360u) + +Vtable for QGraphicsSimpleTextItem +QGraphicsSimpleTextItem::_ZTV23QGraphicsSimpleTextItem: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGraphicsSimpleTextItem) +16 (int (*)(...))QGraphicsSimpleTextItem::~QGraphicsSimpleTextItem +24 (int (*)(...))QGraphicsSimpleTextItem::~QGraphicsSimpleTextItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsSimpleTextItem::boundingRect +48 (int (*)(...))QGraphicsSimpleTextItem::shape +56 (int (*)(...))QGraphicsSimpleTextItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsSimpleTextItem::isObscuredBy +88 (int (*)(...))QGraphicsSimpleTextItem::opaqueArea +96 (int (*)(...))QGraphicsSimpleTextItem::paint +104 (int (*)(...))QGraphicsSimpleTextItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsSimpleTextItem::supportsExtension +296 (int (*)(...))QGraphicsSimpleTextItem::setExtension +304 (int (*)(...))QGraphicsSimpleTextItem::extension + +Class QGraphicsSimpleTextItem + size=16 align=8 + base size=16 base align=8 +QGraphicsSimpleTextItem (0x0x7f9a547e6dd0) 0 + vptr=((& QGraphicsSimpleTextItem::_ZTV23QGraphicsSimpleTextItem) + 16u) + QAbstractGraphicsShapeItem (0x0x7f9a547e6e38) 0 + primary-for QGraphicsSimpleTextItem (0x0x7f9a547e6dd0) + QGraphicsItem (0x0x7f9a53cd1a80) 0 + primary-for QAbstractGraphicsShapeItem (0x0x7f9a547e6e38) + +Vtable for QGraphicsItemGroup +QGraphicsItemGroup::_ZTV18QGraphicsItemGroup: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QGraphicsItemGroup) +16 (int (*)(...))QGraphicsItemGroup::~QGraphicsItemGroup +24 (int (*)(...))QGraphicsItemGroup::~QGraphicsItemGroup +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsItemGroup::boundingRect +48 (int (*)(...))QGraphicsItem::shape +56 (int (*)(...))QGraphicsItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsItemGroup::isObscuredBy +88 (int (*)(...))QGraphicsItemGroup::opaqueArea +96 (int (*)(...))QGraphicsItemGroup::paint +104 (int (*)(...))QGraphicsItemGroup::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsItem::supportsExtension +296 (int (*)(...))QGraphicsItem::setExtension +304 (int (*)(...))QGraphicsItem::extension + +Class QGraphicsItemGroup + size=16 align=8 + base size=16 base align=8 +QGraphicsItemGroup (0x0x7f9a53cb2068) 0 + vptr=((& QGraphicsItemGroup::_ZTV18QGraphicsItemGroup) + 16u) + QGraphicsItem (0x0x7f9a53cfc180) 0 + primary-for QGraphicsItemGroup (0x0x7f9a53cb2068) + +Vtable for QGraphicsLayoutItem +QGraphicsLayoutItem::_ZTV19QGraphicsLayoutItem: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QGraphicsLayoutItem) +16 0u +24 0u +32 (int (*)(...))QGraphicsLayoutItem::setGeometry +40 (int (*)(...))QGraphicsLayoutItem::getContentsMargins +48 (int (*)(...))QGraphicsLayoutItem::updateGeometry +56 (int (*)(...))__cxa_pure_virtual + +Class QGraphicsLayoutItem + size=16 align=8 + base size=16 base align=8 +QGraphicsLayoutItem (0x0x7f9a53deed20) 0 + vptr=((& QGraphicsLayoutItem::_ZTV19QGraphicsLayoutItem) + 16u) + +Vtable for QGraphicsLayout +QGraphicsLayout::_ZTV15QGraphicsLayout: 13u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGraphicsLayout) +16 0u +24 0u +32 (int (*)(...))QGraphicsLayoutItem::setGeometry +40 (int (*)(...))QGraphicsLayout::getContentsMargins +48 (int (*)(...))QGraphicsLayout::updateGeometry +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))QGraphicsLayout::invalidate +72 (int (*)(...))QGraphicsLayout::widgetEvent +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual + +Class QGraphicsLayout + size=16 align=8 + base size=16 base align=8 +QGraphicsLayout (0x0x7f9a53cb20d0) 0 + vptr=((& QGraphicsLayout::_ZTV15QGraphicsLayout) + 16u) + QGraphicsLayoutItem (0x0x7f9a53b048a0) 0 + primary-for QGraphicsLayout (0x0x7f9a53cb20d0) + +Class QGraphicsAnchor::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsAnchor::QPrivateSignal (0x0x7f9a53b049c0) 0 empty + +Vtable for QGraphicsAnchor +QGraphicsAnchor::_ZTV15QGraphicsAnchor: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGraphicsAnchor) +16 (int (*)(...))QGraphicsAnchor::metaObject +24 (int (*)(...))QGraphicsAnchor::qt_metacast +32 (int (*)(...))QGraphicsAnchor::qt_metacall +40 (int (*)(...))QGraphicsAnchor::~QGraphicsAnchor +48 (int (*)(...))QGraphicsAnchor::~QGraphicsAnchor +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QGraphicsAnchor + size=16 align=8 + base size=16 base align=8 +QGraphicsAnchor (0x0x7f9a53cb2680) 0 + vptr=((& QGraphicsAnchor::_ZTV15QGraphicsAnchor) + 16u) + QObject (0x0x7f9a53b04960) 0 + primary-for QGraphicsAnchor (0x0x7f9a53cb2680) + +Vtable for QGraphicsAnchorLayout +QGraphicsAnchorLayout::_ZTV21QGraphicsAnchorLayout: 13u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QGraphicsAnchorLayout) +16 (int (*)(...))QGraphicsAnchorLayout::~QGraphicsAnchorLayout +24 (int (*)(...))QGraphicsAnchorLayout::~QGraphicsAnchorLayout +32 (int (*)(...))QGraphicsAnchorLayout::setGeometry +40 (int (*)(...))QGraphicsLayout::getContentsMargins +48 (int (*)(...))QGraphicsLayout::updateGeometry +56 (int (*)(...))QGraphicsAnchorLayout::sizeHint +64 (int (*)(...))QGraphicsAnchorLayout::invalidate +72 (int (*)(...))QGraphicsLayout::widgetEvent +80 (int (*)(...))QGraphicsAnchorLayout::count +88 (int (*)(...))QGraphicsAnchorLayout::itemAt +96 (int (*)(...))QGraphicsAnchorLayout::removeAt + +Class QGraphicsAnchorLayout + size=16 align=8 + base size=16 base align=8 +QGraphicsAnchorLayout (0x0x7f9a53cb26e8) 0 + vptr=((& QGraphicsAnchorLayout::_ZTV21QGraphicsAnchorLayout) + 16u) + QGraphicsLayout (0x0x7f9a53cd0680) 0 + primary-for QGraphicsAnchorLayout (0x0x7f9a53cb26e8) + QGraphicsLayoutItem (0x0x7f9a53b04a20) 0 + primary-for QGraphicsLayout (0x0x7f9a53cd0680) + +Class QGraphicsEffect::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsEffect::QPrivateSignal (0x0x7f9a53b04ae0) 0 empty + +Vtable for QGraphicsEffect +QGraphicsEffect::_ZTV15QGraphicsEffect: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGraphicsEffect) +16 (int (*)(...))QGraphicsEffect::metaObject +24 (int (*)(...))QGraphicsEffect::qt_metacast +32 (int (*)(...))QGraphicsEffect::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsEffect::boundingRectFor +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QGraphicsEffect::sourceChanged + +Class QGraphicsEffect + size=16 align=8 + base size=16 base align=8 +QGraphicsEffect (0x0x7f9a53cd06e8) 0 + vptr=((& QGraphicsEffect::_ZTV15QGraphicsEffect) + 16u) + QObject (0x0x7f9a53b04a80) 0 + primary-for QGraphicsEffect (0x0x7f9a53cd06e8) + +Class QGraphicsColorizeEffect::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsColorizeEffect::QPrivateSignal (0x0x7f9a53b04d80) 0 empty + +Vtable for QGraphicsColorizeEffect +QGraphicsColorizeEffect::_ZTV23QGraphicsColorizeEffect: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGraphicsColorizeEffect) +16 (int (*)(...))QGraphicsColorizeEffect::metaObject +24 (int (*)(...))QGraphicsColorizeEffect::qt_metacast +32 (int (*)(...))QGraphicsColorizeEffect::qt_metacall +40 (int (*)(...))QGraphicsColorizeEffect::~QGraphicsColorizeEffect +48 (int (*)(...))QGraphicsColorizeEffect::~QGraphicsColorizeEffect +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsEffect::boundingRectFor +120 (int (*)(...))QGraphicsColorizeEffect::draw +128 (int (*)(...))QGraphicsEffect::sourceChanged + +Class QGraphicsColorizeEffect + size=16 align=8 + base size=16 base align=8 +QGraphicsColorizeEffect (0x0x7f9a53cee680) 0 + vptr=((& QGraphicsColorizeEffect::_ZTV23QGraphicsColorizeEffect) + 16u) + QGraphicsEffect (0x0x7f9a53cee6e8) 0 + primary-for QGraphicsColorizeEffect (0x0x7f9a53cee680) + QObject (0x0x7f9a53b04d20) 0 + primary-for QGraphicsEffect (0x0x7f9a53cee6e8) + +Class QGraphicsBlurEffect::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsBlurEffect::QPrivateSignal (0x0x7f9a53882ea0) 0 empty + +Vtable for QGraphicsBlurEffect +QGraphicsBlurEffect::_ZTV19QGraphicsBlurEffect: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QGraphicsBlurEffect) +16 (int (*)(...))QGraphicsBlurEffect::metaObject +24 (int (*)(...))QGraphicsBlurEffect::qt_metacast +32 (int (*)(...))QGraphicsBlurEffect::qt_metacall +40 (int (*)(...))QGraphicsBlurEffect::~QGraphicsBlurEffect +48 (int (*)(...))QGraphicsBlurEffect::~QGraphicsBlurEffect +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsBlurEffect::boundingRectFor +120 (int (*)(...))QGraphicsBlurEffect::draw +128 (int (*)(...))QGraphicsEffect::sourceChanged + +Class QGraphicsBlurEffect + size=16 align=8 + base size=16 base align=8 +QGraphicsBlurEffect (0x0x7f9a53ceeb60) 0 + vptr=((& QGraphicsBlurEffect::_ZTV19QGraphicsBlurEffect) + 16u) + QGraphicsEffect (0x0x7f9a53ceebc8) 0 + primary-for QGraphicsBlurEffect (0x0x7f9a53ceeb60) + QObject (0x0x7f9a53b04de0) 0 + primary-for QGraphicsEffect (0x0x7f9a53ceebc8) + +Class QGraphicsDropShadowEffect::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsDropShadowEffect::QPrivateSignal (0x0x7f9a53a1a3c0) 0 empty + +Vtable for QGraphicsDropShadowEffect +QGraphicsDropShadowEffect::_ZTV25QGraphicsDropShadowEffect: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QGraphicsDropShadowEffect) +16 (int (*)(...))QGraphicsDropShadowEffect::metaObject +24 (int (*)(...))QGraphicsDropShadowEffect::qt_metacast +32 (int (*)(...))QGraphicsDropShadowEffect::qt_metacall +40 (int (*)(...))QGraphicsDropShadowEffect::~QGraphicsDropShadowEffect +48 (int (*)(...))QGraphicsDropShadowEffect::~QGraphicsDropShadowEffect +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsDropShadowEffect::boundingRectFor +120 (int (*)(...))QGraphicsDropShadowEffect::draw +128 (int (*)(...))QGraphicsEffect::sourceChanged + +Class QGraphicsDropShadowEffect + size=16 align=8 + base size=16 base align=8 +QGraphicsDropShadowEffect (0x0x7f9a53ac88f0) 0 + vptr=((& QGraphicsDropShadowEffect::_ZTV25QGraphicsDropShadowEffect) + 16u) + QGraphicsEffect (0x0x7f9a53ac8958) 0 + primary-for QGraphicsDropShadowEffect (0x0x7f9a53ac88f0) + QObject (0x0x7f9a53a1a360) 0 + primary-for QGraphicsEffect (0x0x7f9a53ac8958) + +Class QGraphicsOpacityEffect::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsOpacityEffect::QPrivateSignal (0x0x7f9a534f2480) 0 empty + +Vtable for QGraphicsOpacityEffect +QGraphicsOpacityEffect::_ZTV22QGraphicsOpacityEffect: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QGraphicsOpacityEffect) +16 (int (*)(...))QGraphicsOpacityEffect::metaObject +24 (int (*)(...))QGraphicsOpacityEffect::qt_metacast +32 (int (*)(...))QGraphicsOpacityEffect::qt_metacall +40 (int (*)(...))QGraphicsOpacityEffect::~QGraphicsOpacityEffect +48 (int (*)(...))QGraphicsOpacityEffect::~QGraphicsOpacityEffect +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsEffect::boundingRectFor +120 (int (*)(...))QGraphicsOpacityEffect::draw +128 (int (*)(...))QGraphicsEffect::sourceChanged + +Class QGraphicsOpacityEffect + size=16 align=8 + base size=16 base align=8 +QGraphicsOpacityEffect (0x0x7f9a53ac89c0) 0 + vptr=((& QGraphicsOpacityEffect::_ZTV22QGraphicsOpacityEffect) + 16u) + QGraphicsEffect (0x0x7f9a53ac8a28) 0 + primary-for QGraphicsOpacityEffect (0x0x7f9a53ac89c0) + QObject (0x0x7f9a534f2420) 0 + primary-for QGraphicsEffect (0x0x7f9a53ac8a28) + +Vtable for QGraphicsGridLayout +QGraphicsGridLayout::_ZTV19QGraphicsGridLayout: 13u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QGraphicsGridLayout) +16 (int (*)(...))QGraphicsGridLayout::~QGraphicsGridLayout +24 (int (*)(...))QGraphicsGridLayout::~QGraphicsGridLayout +32 (int (*)(...))QGraphicsGridLayout::setGeometry +40 (int (*)(...))QGraphicsLayout::getContentsMargins +48 (int (*)(...))QGraphicsLayout::updateGeometry +56 (int (*)(...))QGraphicsGridLayout::sizeHint +64 (int (*)(...))QGraphicsGridLayout::invalidate +72 (int (*)(...))QGraphicsLayout::widgetEvent +80 (int (*)(...))QGraphicsGridLayout::count +88 (int (*)(...))QGraphicsGridLayout::itemAt +96 (int (*)(...))QGraphicsGridLayout::removeAt + +Class QGraphicsGridLayout + size=16 align=8 + base size=16 base align=8 +QGraphicsGridLayout (0x0x7f9a53ac8a90) 0 + vptr=((& QGraphicsGridLayout::_ZTV19QGraphicsGridLayout) + 16u) + QGraphicsLayout (0x0x7f9a53ac8af8) 0 + primary-for QGraphicsGridLayout (0x0x7f9a53ac8a90) + QGraphicsLayoutItem (0x0x7f9a534f2540) 0 + primary-for QGraphicsLayout (0x0x7f9a53ac8af8) + +Class QGraphicsItemAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsItemAnimation::QPrivateSignal (0x0x7f9a534f2780) 0 empty + +Vtable for QGraphicsItemAnimation +QGraphicsItemAnimation::_ZTV22QGraphicsItemAnimation: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QGraphicsItemAnimation) +16 (int (*)(...))QGraphicsItemAnimation::metaObject +24 (int (*)(...))QGraphicsItemAnimation::qt_metacast +32 (int (*)(...))QGraphicsItemAnimation::qt_metacall +40 (int (*)(...))QGraphicsItemAnimation::~QGraphicsItemAnimation +48 (int (*)(...))QGraphicsItemAnimation::~QGraphicsItemAnimation +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsItemAnimation::beforeAnimationStep +120 (int (*)(...))QGraphicsItemAnimation::afterAnimationStep + +Class QGraphicsItemAnimation + size=24 align=8 + base size=24 base align=8 +QGraphicsItemAnimation (0x0x7f9a53ac8bc8) 0 + vptr=((& QGraphicsItemAnimation::_ZTV22QGraphicsItemAnimation) + 16u) + QObject (0x0x7f9a534f2720) 0 + primary-for QGraphicsItemAnimation (0x0x7f9a53ac8bc8) + +Vtable for QGraphicsLinearLayout +QGraphicsLinearLayout::_ZTV21QGraphicsLinearLayout: 13u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QGraphicsLinearLayout) +16 (int (*)(...))QGraphicsLinearLayout::~QGraphicsLinearLayout +24 (int (*)(...))QGraphicsLinearLayout::~QGraphicsLinearLayout +32 (int (*)(...))QGraphicsLinearLayout::setGeometry +40 (int (*)(...))QGraphicsLayout::getContentsMargins +48 (int (*)(...))QGraphicsLayout::updateGeometry +56 (int (*)(...))QGraphicsLinearLayout::sizeHint +64 (int (*)(...))QGraphicsLinearLayout::invalidate +72 (int (*)(...))QGraphicsLayout::widgetEvent +80 (int (*)(...))QGraphicsLinearLayout::count +88 (int (*)(...))QGraphicsLinearLayout::itemAt +96 (int (*)(...))QGraphicsLinearLayout::removeAt + +Class QGraphicsLinearLayout + size=16 align=8 + base size=16 base align=8 +QGraphicsLinearLayout (0x0x7f9a53ac8c30) 0 + vptr=((& QGraphicsLinearLayout::_ZTV21QGraphicsLinearLayout) + 16u) + QGraphicsLayout (0x0x7f9a53ac8c98) 0 + primary-for QGraphicsLinearLayout (0x0x7f9a53ac8c30) + QGraphicsLayoutItem (0x0x7f9a53518300) 0 + primary-for QGraphicsLayout (0x0x7f9a53ac8c98) + +Class QGraphicsWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsWidget::QPrivateSignal (0x0x7f9a53518d80) 0 empty + +Vtable for QGraphicsWidget +QGraphicsWidget::_ZTV15QGraphicsWidget: 92u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGraphicsWidget) +16 (int (*)(...))QGraphicsWidget::metaObject +24 (int (*)(...))QGraphicsWidget::qt_metacast +32 (int (*)(...))QGraphicsWidget::qt_metacall +40 (int (*)(...))QGraphicsWidget::~QGraphicsWidget +48 (int (*)(...))QGraphicsWidget::~QGraphicsWidget +56 (int (*)(...))QGraphicsWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsWidget::setGeometry +120 (int (*)(...))QGraphicsWidget::getContentsMargins +128 (int (*)(...))QGraphicsWidget::type +136 (int (*)(...))QGraphicsWidget::paint +144 (int (*)(...))QGraphicsWidget::paintWindowFrame +152 (int (*)(...))QGraphicsWidget::boundingRect +160 (int (*)(...))QGraphicsWidget::shape +168 (int (*)(...))QGraphicsWidget::initStyleOption +176 (int (*)(...))QGraphicsWidget::sizeHint +184 (int (*)(...))QGraphicsWidget::updateGeometry +192 (int (*)(...))QGraphicsWidget::itemChange +200 (int (*)(...))QGraphicsWidget::propertyChange +208 (int (*)(...))QGraphicsWidget::sceneEvent +216 (int (*)(...))QGraphicsWidget::windowFrameEvent +224 (int (*)(...))QGraphicsWidget::windowFrameSectionAt +232 (int (*)(...))QGraphicsWidget::changeEvent +240 (int (*)(...))QGraphicsWidget::closeEvent +248 (int (*)(...))QGraphicsWidget::focusInEvent +256 (int (*)(...))QGraphicsWidget::focusNextPrevChild +264 (int (*)(...))QGraphicsWidget::focusOutEvent +272 (int (*)(...))QGraphicsWidget::hideEvent +280 (int (*)(...))QGraphicsWidget::moveEvent +288 (int (*)(...))QGraphicsWidget::polishEvent +296 (int (*)(...))QGraphicsWidget::resizeEvent +304 (int (*)(...))QGraphicsWidget::showEvent +312 (int (*)(...))QGraphicsWidget::hoverMoveEvent +320 (int (*)(...))QGraphicsWidget::hoverLeaveEvent +328 (int (*)(...))QGraphicsWidget::grabMouseEvent +336 (int (*)(...))QGraphicsWidget::ungrabMouseEvent +344 (int (*)(...))QGraphicsWidget::grabKeyboardEvent +352 (int (*)(...))QGraphicsWidget::ungrabKeyboardEvent +360 (int (*)(...))-16 +368 (int (*)(...))(& _ZTI15QGraphicsWidget) +376 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidgetD1Ev +384 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidgetD0Ev +392 (int (*)(...))QGraphicsItem::advance +400 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget12boundingRectEv +408 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget5shapeEv +416 (int (*)(...))QGraphicsItem::contains +424 (int (*)(...))QGraphicsItem::collidesWithItem +432 (int (*)(...))QGraphicsItem::collidesWithPath +440 (int (*)(...))QGraphicsItem::isObscuredBy +448 (int (*)(...))QGraphicsItem::opaqueArea +456 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget5paintEP8QPainterPK24QStyleOptionGraphicsItemP7QWidget +464 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget4typeEv +472 (int (*)(...))QGraphicsItem::sceneEventFilter +480 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget10sceneEventEP6QEvent +488 (int (*)(...))QGraphicsItem::contextMenuEvent +496 (int (*)(...))QGraphicsItem::dragEnterEvent +504 (int (*)(...))QGraphicsItem::dragLeaveEvent +512 (int (*)(...))QGraphicsItem::dragMoveEvent +520 (int (*)(...))QGraphicsItem::dropEvent +528 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget12focusInEventEP11QFocusEvent +536 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget13focusOutEventEP11QFocusEvent +544 (int (*)(...))QGraphicsItem::hoverEnterEvent +552 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget14hoverMoveEventEP24QGraphicsSceneHoverEvent +560 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget15hoverLeaveEventEP24QGraphicsSceneHoverEvent +568 (int (*)(...))QGraphicsItem::keyPressEvent +576 (int (*)(...))QGraphicsItem::keyReleaseEvent +584 (int (*)(...))QGraphicsItem::mousePressEvent +592 (int (*)(...))QGraphicsItem::mouseMoveEvent +600 (int (*)(...))QGraphicsItem::mouseReleaseEvent +608 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +616 (int (*)(...))QGraphicsItem::wheelEvent +624 (int (*)(...))QGraphicsItem::inputMethodEvent +632 (int (*)(...))QGraphicsItem::inputMethodQuery +640 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget10itemChangeEN13QGraphicsItem18GraphicsItemChangeERK8QVariant +648 (int (*)(...))QGraphicsItem::supportsExtension +656 (int (*)(...))QGraphicsItem::setExtension +664 (int (*)(...))QGraphicsItem::extension +672 (int (*)(...))-32 +680 (int (*)(...))(& _ZTI15QGraphicsWidget) +688 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidgetD1Ev +696 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidgetD0Ev +704 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidget11setGeometryERK6QRectF +712 (int (*)(...))QGraphicsWidget::_ZThn32_NK15QGraphicsWidget18getContentsMarginsEPdS0_S0_S0_ +720 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidget14updateGeometryEv +728 (int (*)(...))QGraphicsWidget::_ZThn32_NK15QGraphicsWidget8sizeHintEN2Qt8SizeHintERK6QSizeF + +Class QGraphicsWidget + size=48 align=8 + base size=48 base align=8 +QGraphicsWidget (0x0x7f9a56aca8c0) 0 + vptr=((& QGraphicsWidget::_ZTV15QGraphicsWidget) + 16u) + QGraphicsObject (0x0x7f9a56aca9a0) 0 + primary-for QGraphicsWidget (0x0x7f9a56aca8c0) + QObject (0x0x7f9a53518360) 0 + primary-for QGraphicsObject (0x0x7f9a56aca9a0) + QGraphicsItem (0x0x7f9a53518c60) 16 + vptr=((& QGraphicsWidget::_ZTV15QGraphicsWidget) + 376u) + QGraphicsLayoutItem (0x0x7f9a53518cc0) 32 + vptr=((& QGraphicsWidget::_ZTV15QGraphicsWidget) + 688u) + +Class QGraphicsProxyWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsProxyWidget::QPrivateSignal (0x0x7f9a53537f60) 0 empty + +Vtable for QGraphicsProxyWidget +QGraphicsProxyWidget::_ZTV20QGraphicsProxyWidget: 107u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QGraphicsProxyWidget) +16 (int (*)(...))QGraphicsProxyWidget::metaObject +24 (int (*)(...))QGraphicsProxyWidget::qt_metacast +32 (int (*)(...))QGraphicsProxyWidget::qt_metacall +40 (int (*)(...))QGraphicsProxyWidget::~QGraphicsProxyWidget +48 (int (*)(...))QGraphicsProxyWidget::~QGraphicsProxyWidget +56 (int (*)(...))QGraphicsProxyWidget::event +64 (int (*)(...))QGraphicsProxyWidget::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsProxyWidget::setGeometry +120 (int (*)(...))QGraphicsWidget::getContentsMargins +128 (int (*)(...))QGraphicsProxyWidget::type +136 (int (*)(...))QGraphicsProxyWidget::paint +144 (int (*)(...))QGraphicsWidget::paintWindowFrame +152 (int (*)(...))QGraphicsWidget::boundingRect +160 (int (*)(...))QGraphicsWidget::shape +168 (int (*)(...))QGraphicsWidget::initStyleOption +176 (int (*)(...))QGraphicsProxyWidget::sizeHint +184 (int (*)(...))QGraphicsWidget::updateGeometry +192 (int (*)(...))QGraphicsProxyWidget::itemChange +200 (int (*)(...))QGraphicsWidget::propertyChange +208 (int (*)(...))QGraphicsWidget::sceneEvent +216 (int (*)(...))QGraphicsWidget::windowFrameEvent +224 (int (*)(...))QGraphicsWidget::windowFrameSectionAt +232 (int (*)(...))QGraphicsWidget::changeEvent +240 (int (*)(...))QGraphicsWidget::closeEvent +248 (int (*)(...))QGraphicsProxyWidget::focusInEvent +256 (int (*)(...))QGraphicsProxyWidget::focusNextPrevChild +264 (int (*)(...))QGraphicsProxyWidget::focusOutEvent +272 (int (*)(...))QGraphicsProxyWidget::hideEvent +280 (int (*)(...))QGraphicsWidget::moveEvent +288 (int (*)(...))QGraphicsWidget::polishEvent +296 (int (*)(...))QGraphicsProxyWidget::resizeEvent +304 (int (*)(...))QGraphicsProxyWidget::showEvent +312 (int (*)(...))QGraphicsProxyWidget::hoverMoveEvent +320 (int (*)(...))QGraphicsProxyWidget::hoverLeaveEvent +328 (int (*)(...))QGraphicsProxyWidget::grabMouseEvent +336 (int (*)(...))QGraphicsProxyWidget::ungrabMouseEvent +344 (int (*)(...))QGraphicsWidget::grabKeyboardEvent +352 (int (*)(...))QGraphicsWidget::ungrabKeyboardEvent +360 (int (*)(...))QGraphicsProxyWidget::contextMenuEvent +368 (int (*)(...))QGraphicsProxyWidget::dragEnterEvent +376 (int (*)(...))QGraphicsProxyWidget::dragLeaveEvent +384 (int (*)(...))QGraphicsProxyWidget::dragMoveEvent +392 (int (*)(...))QGraphicsProxyWidget::dropEvent +400 (int (*)(...))QGraphicsProxyWidget::hoverEnterEvent +408 (int (*)(...))QGraphicsProxyWidget::mouseMoveEvent +416 (int (*)(...))QGraphicsProxyWidget::mousePressEvent +424 (int (*)(...))QGraphicsProxyWidget::mouseReleaseEvent +432 (int (*)(...))QGraphicsProxyWidget::mouseDoubleClickEvent +440 (int (*)(...))QGraphicsProxyWidget::wheelEvent +448 (int (*)(...))QGraphicsProxyWidget::keyPressEvent +456 (int (*)(...))QGraphicsProxyWidget::keyReleaseEvent +464 (int (*)(...))QGraphicsProxyWidget::inputMethodQuery +472 (int (*)(...))QGraphicsProxyWidget::inputMethodEvent +480 (int (*)(...))-16 +488 (int (*)(...))(& _ZTI20QGraphicsProxyWidget) +496 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidgetD1Ev +504 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidgetD0Ev +512 (int (*)(...))QGraphicsItem::advance +520 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget12boundingRectEv +528 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget5shapeEv +536 (int (*)(...))QGraphicsItem::contains +544 (int (*)(...))QGraphicsItem::collidesWithItem +552 (int (*)(...))QGraphicsItem::collidesWithPath +560 (int (*)(...))QGraphicsItem::isObscuredBy +568 (int (*)(...))QGraphicsItem::opaqueArea +576 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget5paintEP8QPainterPK24QStyleOptionGraphicsItemP7QWidget +584 (int (*)(...))QGraphicsProxyWidget::_ZThn16_NK20QGraphicsProxyWidget4typeEv +592 (int (*)(...))QGraphicsItem::sceneEventFilter +600 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget10sceneEventEP6QEvent +608 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget16contextMenuEventEP30QGraphicsSceneContextMenuEvent +616 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget14dragEnterEventEP27QGraphicsSceneDragDropEvent +624 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget14dragLeaveEventEP27QGraphicsSceneDragDropEvent +632 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget13dragMoveEventEP27QGraphicsSceneDragDropEvent +640 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget9dropEventEP27QGraphicsSceneDragDropEvent +648 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget12focusInEventEP11QFocusEvent +656 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget13focusOutEventEP11QFocusEvent +664 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget15hoverEnterEventEP24QGraphicsSceneHoverEvent +672 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget14hoverMoveEventEP24QGraphicsSceneHoverEvent +680 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget15hoverLeaveEventEP24QGraphicsSceneHoverEvent +688 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget13keyPressEventEP9QKeyEvent +696 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget15keyReleaseEventEP9QKeyEvent +704 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget15mousePressEventEP24QGraphicsSceneMouseEvent +712 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget14mouseMoveEventEP24QGraphicsSceneMouseEvent +720 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget17mouseReleaseEventEP24QGraphicsSceneMouseEvent +728 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget21mouseDoubleClickEventEP24QGraphicsSceneMouseEvent +736 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget10wheelEventEP24QGraphicsSceneWheelEvent +744 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget16inputMethodEventEP17QInputMethodEvent +752 (int (*)(...))QGraphicsProxyWidget::_ZThn16_NK20QGraphicsProxyWidget16inputMethodQueryEN2Qt16InputMethodQueryE +760 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget10itemChangeEN13QGraphicsItem18GraphicsItemChangeERK8QVariant +768 (int (*)(...))QGraphicsItem::supportsExtension +776 (int (*)(...))QGraphicsItem::setExtension +784 (int (*)(...))QGraphicsItem::extension +792 (int (*)(...))-32 +800 (int (*)(...))(& _ZTI20QGraphicsProxyWidget) +808 (int (*)(...))QGraphicsProxyWidget::_ZThn32_N20QGraphicsProxyWidgetD1Ev +816 (int (*)(...))QGraphicsProxyWidget::_ZThn32_N20QGraphicsProxyWidgetD0Ev +824 (int (*)(...))QGraphicsProxyWidget::_ZThn32_N20QGraphicsProxyWidget11setGeometryERK6QRectF +832 (int (*)(...))QGraphicsWidget::_ZThn32_NK15QGraphicsWidget18getContentsMarginsEPdS0_S0_S0_ +840 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidget14updateGeometryEv +848 (int (*)(...))QGraphicsProxyWidget::_ZThn32_NK20QGraphicsProxyWidget8sizeHintEN2Qt8SizeHintERK6QSizeF + +Class QGraphicsProxyWidget + size=48 align=8 + base size=48 base align=8 +QGraphicsProxyWidget (0x0x7f9a53ac8dd0) 0 + vptr=((& QGraphicsProxyWidget::_ZTV20QGraphicsProxyWidget) + 16u) + QGraphicsWidget (0x0x7f9a56ae2620) 0 + primary-for QGraphicsProxyWidget (0x0x7f9a53ac8dd0) + QGraphicsObject (0x0x7f9a56ae2700) 0 + primary-for QGraphicsWidget (0x0x7f9a56ae2620) + QObject (0x0x7f9a53537660) 0 + primary-for QGraphicsObject (0x0x7f9a56ae2700) + QGraphicsItem (0x0x7f9a53537e40) 16 + vptr=((& QGraphicsProxyWidget::_ZTV20QGraphicsProxyWidget) + 496u) + QGraphicsLayoutItem (0x0x7f9a53537ea0) 32 + vptr=((& QGraphicsProxyWidget::_ZTV20QGraphicsProxyWidget) + 808u) + +Class QGraphicsScene::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsScene::QPrivateSignal (0x0x7f9a52d3db40) 0 empty + +Vtable for QGraphicsScene +QGraphicsScene::_ZTV14QGraphicsScene: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QGraphicsScene) +16 (int (*)(...))QGraphicsScene::metaObject +24 (int (*)(...))QGraphicsScene::qt_metacast +32 (int (*)(...))QGraphicsScene::qt_metacall +40 (int (*)(...))QGraphicsScene::~QGraphicsScene +48 (int (*)(...))QGraphicsScene::~QGraphicsScene +56 (int (*)(...))QGraphicsScene::event +64 (int (*)(...))QGraphicsScene::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsScene::inputMethodQuery +120 (int (*)(...))QGraphicsScene::contextMenuEvent +128 (int (*)(...))QGraphicsScene::dragEnterEvent +136 (int (*)(...))QGraphicsScene::dragMoveEvent +144 (int (*)(...))QGraphicsScene::dragLeaveEvent +152 (int (*)(...))QGraphicsScene::dropEvent +160 (int (*)(...))QGraphicsScene::focusInEvent +168 (int (*)(...))QGraphicsScene::focusOutEvent +176 (int (*)(...))QGraphicsScene::helpEvent +184 (int (*)(...))QGraphicsScene::keyPressEvent +192 (int (*)(...))QGraphicsScene::keyReleaseEvent +200 (int (*)(...))QGraphicsScene::mousePressEvent +208 (int (*)(...))QGraphicsScene::mouseMoveEvent +216 (int (*)(...))QGraphicsScene::mouseReleaseEvent +224 (int (*)(...))QGraphicsScene::mouseDoubleClickEvent +232 (int (*)(...))QGraphicsScene::wheelEvent +240 (int (*)(...))QGraphicsScene::inputMethodEvent +248 (int (*)(...))QGraphicsScene::drawBackground +256 (int (*)(...))QGraphicsScene::drawForeground +264 (int (*)(...))QGraphicsScene::drawItems + +Class QGraphicsScene + size=16 align=8 + base size=16 base align=8 +QGraphicsScene (0x0x7f9a53b43000) 0 + vptr=((& QGraphicsScene::_ZTV14QGraphicsScene) + 16u) + QObject (0x0x7f9a52d3d720) 0 + primary-for QGraphicsScene (0x0x7f9a53b43000) + +Vtable for QGraphicsSceneEvent +QGraphicsSceneEvent::_ZTV19QGraphicsSceneEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QGraphicsSceneEvent) +16 (int (*)(...))QGraphicsSceneEvent::~QGraphicsSceneEvent +24 (int (*)(...))QGraphicsSceneEvent::~QGraphicsSceneEvent + +Class QGraphicsSceneEvent + size=32 align=8 + base size=32 base align=8 +QGraphicsSceneEvent (0x0x7f9a53b437b8) 0 + vptr=((& QGraphicsSceneEvent::_ZTV19QGraphicsSceneEvent) + 16u) + QEvent (0x0x7f9a52a97ea0) 0 + primary-for QGraphicsSceneEvent (0x0x7f9a53b437b8) + +Vtable for QGraphicsSceneMouseEvent +QGraphicsSceneMouseEvent::_ZTV24QGraphicsSceneMouseEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QGraphicsSceneMouseEvent) +16 (int (*)(...))QGraphicsSceneMouseEvent::~QGraphicsSceneMouseEvent +24 (int (*)(...))QGraphicsSceneMouseEvent::~QGraphicsSceneMouseEvent + +Class QGraphicsSceneMouseEvent + size=32 align=8 + base size=32 base align=8 +QGraphicsSceneMouseEvent (0x0x7f9a53b43888) 0 + vptr=((& QGraphicsSceneMouseEvent::_ZTV24QGraphicsSceneMouseEvent) + 16u) + QGraphicsSceneEvent (0x0x7f9a53b438f0) 0 + primary-for QGraphicsSceneMouseEvent (0x0x7f9a53b43888) + QEvent (0x0x7f9a52abdb40) 0 + primary-for QGraphicsSceneEvent (0x0x7f9a53b438f0) + +Vtable for QGraphicsSceneWheelEvent +QGraphicsSceneWheelEvent::_ZTV24QGraphicsSceneWheelEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QGraphicsSceneWheelEvent) +16 (int (*)(...))QGraphicsSceneWheelEvent::~QGraphicsSceneWheelEvent +24 (int (*)(...))QGraphicsSceneWheelEvent::~QGraphicsSceneWheelEvent + +Class QGraphicsSceneWheelEvent + size=32 align=8 + base size=32 base align=8 +QGraphicsSceneWheelEvent (0x0x7f9a53b43958) 0 + vptr=((& QGraphicsSceneWheelEvent::_ZTV24QGraphicsSceneWheelEvent) + 16u) + QGraphicsSceneEvent (0x0x7f9a53b439c0) 0 + primary-for QGraphicsSceneWheelEvent (0x0x7f9a53b43958) + QEvent (0x0x7f9a52abdd80) 0 + primary-for QGraphicsSceneEvent (0x0x7f9a53b439c0) + +Vtable for QGraphicsSceneContextMenuEvent +QGraphicsSceneContextMenuEvent::_ZTV30QGraphicsSceneContextMenuEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI30QGraphicsSceneContextMenuEvent) +16 (int (*)(...))QGraphicsSceneContextMenuEvent::~QGraphicsSceneContextMenuEvent +24 (int (*)(...))QGraphicsSceneContextMenuEvent::~QGraphicsSceneContextMenuEvent + +Class QGraphicsSceneContextMenuEvent + size=32 align=8 + base size=32 base align=8 +QGraphicsSceneContextMenuEvent (0x0x7f9a53b43a28) 0 + vptr=((& QGraphicsSceneContextMenuEvent::_ZTV30QGraphicsSceneContextMenuEvent) + 16u) + QGraphicsSceneEvent (0x0x7f9a53b43a90) 0 + primary-for QGraphicsSceneContextMenuEvent (0x0x7f9a53b43a28) + QEvent (0x0x7f9a52abdde0) 0 + primary-for QGraphicsSceneEvent (0x0x7f9a53b43a90) + +Vtable for QGraphicsSceneHoverEvent +QGraphicsSceneHoverEvent::_ZTV24QGraphicsSceneHoverEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QGraphicsSceneHoverEvent) +16 (int (*)(...))QGraphicsSceneHoverEvent::~QGraphicsSceneHoverEvent +24 (int (*)(...))QGraphicsSceneHoverEvent::~QGraphicsSceneHoverEvent + +Class QGraphicsSceneHoverEvent + size=32 align=8 + base size=32 base align=8 +QGraphicsSceneHoverEvent (0x0x7f9a53b43af8) 0 + vptr=((& QGraphicsSceneHoverEvent::_ZTV24QGraphicsSceneHoverEvent) + 16u) + QGraphicsSceneEvent (0x0x7f9a53b43b60) 0 + primary-for QGraphicsSceneHoverEvent (0x0x7f9a53b43af8) + QEvent (0x0x7f9a5239d060) 0 + primary-for QGraphicsSceneEvent (0x0x7f9a53b43b60) + +Vtable for QGraphicsSceneHelpEvent +QGraphicsSceneHelpEvent::_ZTV23QGraphicsSceneHelpEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGraphicsSceneHelpEvent) +16 (int (*)(...))QGraphicsSceneHelpEvent::~QGraphicsSceneHelpEvent +24 (int (*)(...))QGraphicsSceneHelpEvent::~QGraphicsSceneHelpEvent + +Class QGraphicsSceneHelpEvent + size=32 align=8 + base size=32 base align=8 +QGraphicsSceneHelpEvent (0x0x7f9a53b43bc8) 0 + vptr=((& QGraphicsSceneHelpEvent::_ZTV23QGraphicsSceneHelpEvent) + 16u) + QGraphicsSceneEvent (0x0x7f9a538f7d00) 0 + primary-for QGraphicsSceneHelpEvent (0x0x7f9a53b43bc8) + QEvent (0x0x7f9a5239d0c0) 0 + primary-for QGraphicsSceneEvent (0x0x7f9a538f7d00) + +Vtable for QGraphicsSceneDragDropEvent +QGraphicsSceneDragDropEvent::_ZTV27QGraphicsSceneDragDropEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QGraphicsSceneDragDropEvent) +16 (int (*)(...))QGraphicsSceneDragDropEvent::~QGraphicsSceneDragDropEvent +24 (int (*)(...))QGraphicsSceneDragDropEvent::~QGraphicsSceneDragDropEvent + +Class QGraphicsSceneDragDropEvent + size=32 align=8 + base size=32 base align=8 +QGraphicsSceneDragDropEvent (0x0x7f9a538f7dd0) 0 + vptr=((& QGraphicsSceneDragDropEvent::_ZTV27QGraphicsSceneDragDropEvent) + 16u) + QGraphicsSceneEvent (0x0x7f9a5366bf70) 0 + primary-for QGraphicsSceneDragDropEvent (0x0x7f9a538f7dd0) + QEvent (0x0x7f9a5239d4e0) 0 + primary-for QGraphicsSceneEvent (0x0x7f9a5366bf70) + +Vtable for QGraphicsSceneResizeEvent +QGraphicsSceneResizeEvent::_ZTV25QGraphicsSceneResizeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QGraphicsSceneResizeEvent) +16 (int (*)(...))QGraphicsSceneResizeEvent::~QGraphicsSceneResizeEvent +24 (int (*)(...))QGraphicsSceneResizeEvent::~QGraphicsSceneResizeEvent + +Class QGraphicsSceneResizeEvent + size=32 align=8 + base size=32 base align=8 +QGraphicsSceneResizeEvent (0x0x7f9a5366b888) 0 + vptr=((& QGraphicsSceneResizeEvent::_ZTV25QGraphicsSceneResizeEvent) + 16u) + QGraphicsSceneEvent (0x0x7f9a5366b8f0) 0 + primary-for QGraphicsSceneResizeEvent (0x0x7f9a5366b888) + QEvent (0x0x7f9a5239d540) 0 + primary-for QGraphicsSceneEvent (0x0x7f9a5366b8f0) + +Vtable for QGraphicsSceneMoveEvent +QGraphicsSceneMoveEvent::_ZTV23QGraphicsSceneMoveEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGraphicsSceneMoveEvent) +16 (int (*)(...))QGraphicsSceneMoveEvent::~QGraphicsSceneMoveEvent +24 (int (*)(...))QGraphicsSceneMoveEvent::~QGraphicsSceneMoveEvent + +Class QGraphicsSceneMoveEvent + size=32 align=8 + base size=32 base align=8 +QGraphicsSceneMoveEvent (0x0x7f9a5366b958) 0 + vptr=((& QGraphicsSceneMoveEvent::_ZTV23QGraphicsSceneMoveEvent) + 16u) + QGraphicsSceneEvent (0x0x7f9a5366bb60) 0 + primary-for QGraphicsSceneMoveEvent (0x0x7f9a5366b958) + QEvent (0x0x7f9a5239dc60) 0 + primary-for QGraphicsSceneEvent (0x0x7f9a5366bb60) + +Class QGraphicsTransform::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsTransform::QPrivateSignal (0x0x7f9a523d9540) 0 empty + +Vtable for QGraphicsTransform +QGraphicsTransform::_ZTV18QGraphicsTransform: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QGraphicsTransform) +16 (int (*)(...))QGraphicsTransform::metaObject +24 (int (*)(...))QGraphicsTransform::qt_metacast +32 (int (*)(...))QGraphicsTransform::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QGraphicsTransform + size=16 align=8 + base size=16 base align=8 +QGraphicsTransform (0x0x7f9a5366bbc8) 0 + vptr=((& QGraphicsTransform::_ZTV18QGraphicsTransform) + 16u) + QObject (0x0x7f9a5239dcc0) 0 + primary-for QGraphicsTransform (0x0x7f9a5366bbc8) + +Class QGraphicsScale::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsScale::QPrivateSignal (0x0x7f9a523d96c0) 0 empty + +Vtable for QGraphicsScale +QGraphicsScale::_ZTV14QGraphicsScale: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QGraphicsScale) +16 (int (*)(...))QGraphicsScale::metaObject +24 (int (*)(...))QGraphicsScale::qt_metacast +32 (int (*)(...))QGraphicsScale::qt_metacall +40 (int (*)(...))QGraphicsScale::~QGraphicsScale +48 (int (*)(...))QGraphicsScale::~QGraphicsScale +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsScale::applyTo + +Class QGraphicsScale + size=16 align=8 + base size=16 base align=8 +QGraphicsScale (0x0x7f9a5366bc30) 0 + vptr=((& QGraphicsScale::_ZTV14QGraphicsScale) + 16u) + QGraphicsTransform (0x0x7f9a5366bc98) 0 + primary-for QGraphicsScale (0x0x7f9a5366bc30) + QObject (0x0x7f9a523d95a0) 0 + primary-for QGraphicsTransform (0x0x7f9a5366bc98) + +Class QGraphicsRotation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsRotation::QPrivateSignal (0x0x7f9a523d97e0) 0 empty + +Vtable for QGraphicsRotation +QGraphicsRotation::_ZTV17QGraphicsRotation: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QGraphicsRotation) +16 (int (*)(...))QGraphicsRotation::metaObject +24 (int (*)(...))QGraphicsRotation::qt_metacast +32 (int (*)(...))QGraphicsRotation::qt_metacall +40 (int (*)(...))QGraphicsRotation::~QGraphicsRotation +48 (int (*)(...))QGraphicsRotation::~QGraphicsRotation +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsRotation::applyTo + +Class QGraphicsRotation + size=16 align=8 + base size=16 base align=8 +QGraphicsRotation (0x0x7f9a5378c0d0) 0 + vptr=((& QGraphicsRotation::_ZTV17QGraphicsRotation) + 16u) + QGraphicsTransform (0x0x7f9a5378c138) 0 + primary-for QGraphicsRotation (0x0x7f9a5378c0d0) + QObject (0x0x7f9a523d9720) 0 + primary-for QGraphicsTransform (0x0x7f9a5378c138) + +Class QScrollArea::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QScrollArea::QPrivateSignal (0x0x7f9a523d9d80) 0 empty + +Vtable for QScrollArea +QScrollArea::_ZTV11QScrollArea: 68u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QScrollArea) +16 (int (*)(...))QScrollArea::metaObject +24 (int (*)(...))QScrollArea::qt_metacast +32 (int (*)(...))QScrollArea::qt_metacall +40 (int (*)(...))QScrollArea::~QScrollArea +48 (int (*)(...))QScrollArea::~QScrollArea +56 (int (*)(...))QScrollArea::event +64 (int (*)(...))QScrollArea::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractScrollArea::mousePressEvent +176 (int (*)(...))QAbstractScrollArea::mouseReleaseEvent +184 (int (*)(...))QAbstractScrollArea::mouseDoubleClickEvent +192 (int (*)(...))QAbstractScrollArea::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractScrollArea::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractScrollArea::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QScrollArea::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractScrollArea::dragEnterEvent +320 (int (*)(...))QAbstractScrollArea::dragMoveEvent +328 (int (*)(...))QAbstractScrollArea::dragLeaveEvent +336 (int (*)(...))QAbstractScrollArea::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QScrollArea::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractScrollArea::viewportEvent +448 (int (*)(...))QScrollArea::scrollContentsBy +456 (int (*)(...))QScrollArea::viewportSizeHint +464 (int (*)(...))-16 +472 (int (*)(...))(& _ZTI11QScrollArea) +480 (int (*)(...))QScrollArea::_ZThn16_N11QScrollAreaD1Ev +488 (int (*)(...))QScrollArea::_ZThn16_N11QScrollAreaD0Ev +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QScrollArea + size=48 align=8 + base size=48 base align=8 +QScrollArea (0x0x7f9a5378c1a0) 0 + vptr=((& QScrollArea::_ZTV11QScrollArea) + 16u) + QAbstractScrollArea (0x0x7f9a5378c208) 0 + primary-for QScrollArea (0x0x7f9a5378c1a0) + QFrame (0x0x7f9a5378c680) 0 + primary-for QAbstractScrollArea (0x0x7f9a5378c208) + QWidget (0x0x7f9a56b42cb0) 0 + primary-for QFrame (0x0x7f9a5378c680) + QObject (0x0x7f9a523d9c60) 0 + primary-for QWidget (0x0x7f9a56b42cb0) + QPaintDevice (0x0x7f9a523d9cc0) 16 + vptr=((& QScrollArea::_ZTV11QScrollArea) + 480u) + +Class QGraphicsView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsView::QPrivateSignal (0x0x7f9a523d9f00) 0 empty + +Vtable for QGraphicsView +QGraphicsView::_ZTV13QGraphicsView: 71u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QGraphicsView) +16 (int (*)(...))QGraphicsView::metaObject +24 (int (*)(...))QGraphicsView::qt_metacast +32 (int (*)(...))QGraphicsView::qt_metacall +40 (int (*)(...))QGraphicsView::~QGraphicsView +48 (int (*)(...))QGraphicsView::~QGraphicsView +56 (int (*)(...))QGraphicsView::event +64 (int (*)(...))QAbstractScrollArea::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QGraphicsView::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QGraphicsView::mousePressEvent +176 (int (*)(...))QGraphicsView::mouseReleaseEvent +184 (int (*)(...))QGraphicsView::mouseDoubleClickEvent +192 (int (*)(...))QGraphicsView::mouseMoveEvent +200 (int (*)(...))QGraphicsView::wheelEvent +208 (int (*)(...))QGraphicsView::keyPressEvent +216 (int (*)(...))QGraphicsView::keyReleaseEvent +224 (int (*)(...))QGraphicsView::focusInEvent +232 (int (*)(...))QGraphicsView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QGraphicsView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QGraphicsView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QGraphicsView::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QGraphicsView::dragEnterEvent +320 (int (*)(...))QGraphicsView::dragMoveEvent +328 (int (*)(...))QGraphicsView::dragLeaveEvent +336 (int (*)(...))QGraphicsView::dropEvent +344 (int (*)(...))QGraphicsView::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QGraphicsView::inputMethodEvent +416 (int (*)(...))QGraphicsView::inputMethodQuery +424 (int (*)(...))QGraphicsView::focusNextPrevChild +432 (int (*)(...))QGraphicsView::setupViewport +440 (int (*)(...))QGraphicsView::viewportEvent +448 (int (*)(...))QGraphicsView::scrollContentsBy +456 (int (*)(...))QAbstractScrollArea::viewportSizeHint +464 (int (*)(...))QGraphicsView::drawBackground +472 (int (*)(...))QGraphicsView::drawForeground +480 (int (*)(...))QGraphicsView::drawItems +488 (int (*)(...))-16 +496 (int (*)(...))(& _ZTI13QGraphicsView) +504 (int (*)(...))QGraphicsView::_ZThn16_N13QGraphicsViewD1Ev +512 (int (*)(...))QGraphicsView::_ZThn16_N13QGraphicsViewD0Ev +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QGraphicsView + size=48 align=8 + base size=48 base align=8 +QGraphicsView (0x0x7f9a5378cc30) 0 + vptr=((& QGraphicsView::_ZTV13QGraphicsView) + 16u) + QAbstractScrollArea (0x0x7f9a53840680) 0 + primary-for QGraphicsView (0x0x7f9a5378cc30) + QFrame (0x0x7f9a538403a8) 0 + primary-for QAbstractScrollArea (0x0x7f9a53840680) + QWidget (0x0x7f9a56c1c000) 0 + primary-for QFrame (0x0x7f9a538403a8) + QObject (0x0x7f9a523d9de0) 0 + primary-for QWidget (0x0x7f9a56c1c000) + QPaintDevice (0x0x7f9a523d9ea0) 16 + vptr=((& QGraphicsView::_ZTV13QGraphicsView) + 504u) + +Class QGroupBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGroupBox::QPrivateSignal (0x0x7f9a52123720) 0 empty + +Vtable for QGroupBox +QGroupBox::_ZTV9QGroupBox: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QGroupBox) +16 (int (*)(...))QGroupBox::metaObject +24 (int (*)(...))QGroupBox::qt_metacast +32 (int (*)(...))QGroupBox::qt_metacall +40 (int (*)(...))QGroupBox::~QGroupBox +48 (int (*)(...))QGroupBox::~QGroupBox +56 (int (*)(...))QGroupBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QGroupBox::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QGroupBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QGroupBox::mousePressEvent +176 (int (*)(...))QGroupBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QGroupBox::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QGroupBox::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QGroupBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QGroupBox::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QGroupBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI9QGroupBox) +448 (int (*)(...))QGroupBox::_ZThn16_N9QGroupBoxD1Ev +456 (int (*)(...))QGroupBox::_ZThn16_N9QGroupBoxD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QGroupBox + size=48 align=8 + base size=48 base align=8 +QGroupBox (0x0x7f9a53509410) 0 + vptr=((& QGroupBox::_ZTV9QGroupBox) + 16u) + QWidget (0x0x7f9a56c3ba80) 0 + primary-for QGroupBox (0x0x7f9a53509410) + QObject (0x0x7f9a521235a0) 0 + primary-for QWidget (0x0x7f9a56c3ba80) + QPaintDevice (0x0x7f9a521236c0) 16 + vptr=((& QGroupBox::_ZTV9QGroupBox) + 448u) + +Class QHeaderView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHeaderView::QPrivateSignal (0x0x7f9a51a8dd80) 0 empty + +Vtable for QHeaderView +QHeaderView::_ZTV11QHeaderView: 108u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QHeaderView) +16 (int (*)(...))QHeaderView::metaObject +24 (int (*)(...))QHeaderView::qt_metacast +32 (int (*)(...))QHeaderView::qt_metacall +40 (int (*)(...))QHeaderView::~QHeaderView +48 (int (*)(...))QHeaderView::~QHeaderView +56 (int (*)(...))QHeaderView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QAbstractItemView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QHeaderView::setVisible +128 (int (*)(...))QHeaderView::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QHeaderView::mousePressEvent +176 (int (*)(...))QHeaderView::mouseReleaseEvent +184 (int (*)(...))QHeaderView::mouseDoubleClickEvent +192 (int (*)(...))QHeaderView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QHeaderView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractItemView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QAbstractItemView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QAbstractItemView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QHeaderView::viewportEvent +448 (int (*)(...))QHeaderView::scrollContentsBy +456 (int (*)(...))QAbstractItemView::viewportSizeHint +464 (int (*)(...))QHeaderView::setModel +472 (int (*)(...))QAbstractItemView::setSelectionModel +480 (int (*)(...))QAbstractItemView::keyboardSearch +488 (int (*)(...))QHeaderView::visualRect +496 (int (*)(...))QHeaderView::scrollTo +504 (int (*)(...))QHeaderView::indexAt +512 (int (*)(...))QAbstractItemView::sizeHintForRow +520 (int (*)(...))QAbstractItemView::sizeHintForColumn +528 (int (*)(...))QHeaderView::reset +536 (int (*)(...))QAbstractItemView::setRootIndex +544 (int (*)(...))QHeaderView::doItemsLayout +552 (int (*)(...))QAbstractItemView::selectAll +560 (int (*)(...))QHeaderView::dataChanged +568 (int (*)(...))QHeaderView::rowsInserted +576 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved +584 (int (*)(...))QAbstractItemView::selectionChanged +592 (int (*)(...))QHeaderView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QHeaderView::updateGeometries +624 (int (*)(...))QAbstractItemView::verticalScrollbarAction +632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction +640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))QHeaderView::moveCursor +688 (int (*)(...))QHeaderView::horizontalOffset +696 (int (*)(...))QHeaderView::verticalOffset +704 (int (*)(...))QHeaderView::isIndexHidden +712 (int (*)(...))QHeaderView::setSelection +720 (int (*)(...))QHeaderView::visualRegionForSelection +728 (int (*)(...))QAbstractItemView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QAbstractItemView::startDrag +760 (int (*)(...))QAbstractItemView::viewOptions +768 (int (*)(...))QHeaderView::paintSection +776 (int (*)(...))QHeaderView::sectionSizeFromContents +784 (int (*)(...))-16 +792 (int (*)(...))(& _ZTI11QHeaderView) +800 (int (*)(...))QHeaderView::_ZThn16_N11QHeaderViewD1Ev +808 (int (*)(...))QHeaderView::_ZThn16_N11QHeaderViewD0Ev +816 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +848 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +856 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QHeaderView + size=48 align=8 + base size=48 base align=8 +QHeaderView (0x0x7f9a53509478) 0 + vptr=((& QHeaderView::_ZTV11QHeaderView) + 16u) + QAbstractItemView (0x0x7f9a5352d000) 0 + primary-for QHeaderView (0x0x7f9a53509478) + QAbstractScrollArea (0x0x7f9a5352d068) 0 + primary-for QAbstractItemView (0x0x7f9a5352d000) + QFrame (0x0x7f9a5352d208) 0 + primary-for QAbstractScrollArea (0x0x7f9a5352d068) + QWidget (0x0x7f9a56c3be00) 0 + primary-for QFrame (0x0x7f9a5352d208) + QObject (0x0x7f9a51a8d240) 0 + primary-for QWidget (0x0x7f9a56c3be00) + QPaintDevice (0x0x7f9a51a8d2a0) 16 + vptr=((& QHeaderView::_ZTV11QHeaderView) + 800u) + +Class QLineEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLineEdit::QPrivateSignal (0x0x7f9a51882840) 0 empty + +Vtable for QLineEdit +QLineEdit::_ZTV9QLineEdit: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QLineEdit) +16 (int (*)(...))QLineEdit::metaObject +24 (int (*)(...))QLineEdit::qt_metacast +32 (int (*)(...))QLineEdit::qt_metacall +40 (int (*)(...))QLineEdit::~QLineEdit +48 (int (*)(...))QLineEdit::~QLineEdit +56 (int (*)(...))QLineEdit::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QLineEdit::sizeHint +136 (int (*)(...))QLineEdit::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QLineEdit::mousePressEvent +176 (int (*)(...))QLineEdit::mouseReleaseEvent +184 (int (*)(...))QLineEdit::mouseDoubleClickEvent +192 (int (*)(...))QLineEdit::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QLineEdit::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QLineEdit::focusInEvent +232 (int (*)(...))QLineEdit::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QLineEdit::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QLineEdit::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QLineEdit::dragEnterEvent +320 (int (*)(...))QLineEdit::dragMoveEvent +328 (int (*)(...))QLineEdit::dragLeaveEvent +336 (int (*)(...))QLineEdit::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QLineEdit::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QLineEdit::inputMethodEvent +416 (int (*)(...))QLineEdit::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI9QLineEdit) +448 (int (*)(...))QLineEdit::_ZThn16_N9QLineEditD1Ev +456 (int (*)(...))QLineEdit::_ZThn16_N9QLineEditD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QLineEdit + size=48 align=8 + base size=48 base align=8 +QLineEdit (0x0x7f9a530ccd00) 0 + vptr=((& QLineEdit::_ZTV9QLineEdit) + 16u) + QWidget (0x0x7f9a56c45c40) 0 + primary-for QLineEdit (0x0x7f9a530ccd00) + QObject (0x0x7f9a51882120) 0 + primary-for QWidget (0x0x7f9a56c45c40) + QPaintDevice (0x0x7f9a518827e0) 16 + vptr=((& QLineEdit::_ZTV9QLineEdit) + 448u) + +Class QInputDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QInputDialog::QPrivateSignal (0x0x7f9a518a9780) 0 empty + +Vtable for QInputDialog +QInputDialog::_ZTV12QInputDialog: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QInputDialog) +16 (int (*)(...))QInputDialog::metaObject +24 (int (*)(...))QInputDialog::qt_metacast +32 (int (*)(...))QInputDialog::qt_metacall +40 (int (*)(...))QInputDialog::~QInputDialog +48 (int (*)(...))QInputDialog::~QInputDialog +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QInputDialog::setVisible +128 (int (*)(...))QInputDialog::sizeHint +136 (int (*)(...))QInputDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QInputDialog::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI12QInputDialog) +488 (int (*)(...))QInputDialog::_ZThn16_N12QInputDialogD1Ev +496 (int (*)(...))QInputDialog::_ZThn16_N12QInputDialogD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QInputDialog + size=48 align=8 + base size=48 base align=8 +QInputDialog (0x0x7f9a530ccd68) 0 + vptr=((& QInputDialog::_ZTV12QInputDialog) + 16u) + QDialog (0x0x7f9a52ed65b0) 0 + primary-for QInputDialog (0x0x7f9a530ccd68) + QWidget (0x0x7f9a56c66540) 0 + primary-for QDialog (0x0x7f9a52ed65b0) + QObject (0x0x7f9a518a9000) 0 + primary-for QWidget (0x0x7f9a56c66540) + QPaintDevice (0x0x7f9a518a9060) 16 + vptr=((& QInputDialog::_ZTV12QInputDialog) + 488u) + +Class QItemDelegate::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemDelegate::QPrivateSignal (0x0x7f9a5166c660) 0 empty + +Vtable for QItemDelegate +QItemDelegate::_ZTV13QItemDelegate: 28u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QItemDelegate) +16 (int (*)(...))QItemDelegate::metaObject +24 (int (*)(...))QItemDelegate::qt_metacast +32 (int (*)(...))QItemDelegate::qt_metacall +40 (int (*)(...))QItemDelegate::~QItemDelegate +48 (int (*)(...))QItemDelegate::~QItemDelegate +56 (int (*)(...))QObject::event +64 (int (*)(...))QItemDelegate::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemDelegate::paint +120 (int (*)(...))QItemDelegate::sizeHint +128 (int (*)(...))QItemDelegate::createEditor +136 (int (*)(...))QAbstractItemDelegate::destroyEditor +144 (int (*)(...))QItemDelegate::setEditorData +152 (int (*)(...))QItemDelegate::setModelData +160 (int (*)(...))QItemDelegate::updateEditorGeometry +168 (int (*)(...))QItemDelegate::editorEvent +176 (int (*)(...))QAbstractItemDelegate::helpEvent +184 (int (*)(...))QAbstractItemDelegate::paintingRoles +192 (int (*)(...))QItemDelegate::drawDisplay +200 (int (*)(...))QItemDelegate::drawDecoration +208 (int (*)(...))QItemDelegate::drawFocus +216 (int (*)(...))QItemDelegate::drawCheck + +Class QItemDelegate + size=16 align=8 + base size=16 base align=8 +QItemDelegate (0x0x7f9a52a7f270) 0 + vptr=((& QItemDelegate::_ZTV13QItemDelegate) + 16u) + QAbstractItemDelegate (0x0x7f9a52a7fd00) 0 + primary-for QItemDelegate (0x0x7f9a52a7f270) + QObject (0x0x7f9a5166c5a0) 0 + primary-for QAbstractItemDelegate (0x0x7f9a52a7fd00) + +Vtable for QItemEditorCreatorBase +QItemEditorCreatorBase::_ZTV22QItemEditorCreatorBase: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QItemEditorCreatorBase) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QItemEditorCreatorBase + size=8 align=8 + base size=8 base align=8 +QItemEditorCreatorBase (0x0x7f9a5166c780) 0 nearly-empty + vptr=((& QItemEditorCreatorBase::_ZTV22QItemEditorCreatorBase) + 16u) + +Vtable for QItemEditorFactory +QItemEditorFactory::_ZTV18QItemEditorFactory: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QItemEditorFactory) +16 (int (*)(...))QItemEditorFactory::~QItemEditorFactory +24 (int (*)(...))QItemEditorFactory::~QItemEditorFactory +32 (int (*)(...))QItemEditorFactory::createEditor +40 (int (*)(...))QItemEditorFactory::valuePropertyName + +Class QItemEditorFactory + size=16 align=8 + base size=16 base align=8 +QItemEditorFactory (0x0x7f9a5166c900) 0 + vptr=((& QItemEditorFactory::_ZTV18QItemEditorFactory) + 16u) + +Class QKeyEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QKeyEventTransition::QPrivateSignal (0x0x7f9a5166cc60) 0 empty + +Vtable for QKeyEventTransition +QKeyEventTransition::_ZTV19QKeyEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QKeyEventTransition) +16 (int (*)(...))QKeyEventTransition::metaObject +24 (int (*)(...))QKeyEventTransition::qt_metacast +32 (int (*)(...))QKeyEventTransition::qt_metacall +40 (int (*)(...))QKeyEventTransition::~QKeyEventTransition +48 (int (*)(...))QKeyEventTransition::~QKeyEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QKeyEventTransition::eventTest +120 (int (*)(...))QKeyEventTransition::onTransition + +Class QKeyEventTransition + size=16 align=8 + base size=16 base align=8 +QKeyEventTransition (0x0x7f9a52aa69c0) 0 + vptr=((& QKeyEventTransition::_ZTV19QKeyEventTransition) + 16u) + QEventTransition (0x0x7f9a52aa6d68) 0 + primary-for QKeyEventTransition (0x0x7f9a52aa69c0) + QAbstractTransition (0x0x7f9a52aa6dd0) 0 + primary-for QEventTransition (0x0x7f9a52aa6d68) + QObject (0x0x7f9a5166cba0) 0 + primary-for QAbstractTransition (0x0x7f9a52aa6dd0) + +Class QKeySequenceEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QKeySequenceEdit::QPrivateSignal (0x0x7f9a5127e660) 0 empty + +Vtable for QKeySequenceEdit +QKeySequenceEdit::_ZTV16QKeySequenceEdit: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QKeySequenceEdit) +16 (int (*)(...))QKeySequenceEdit::metaObject +24 (int (*)(...))QKeySequenceEdit::qt_metacast +32 (int (*)(...))QKeySequenceEdit::qt_metacall +40 (int (*)(...))QKeySequenceEdit::~QKeySequenceEdit +48 (int (*)(...))QKeySequenceEdit::~QKeySequenceEdit +56 (int (*)(...))QKeySequenceEdit::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QKeySequenceEdit::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QKeySequenceEdit::keyPressEvent +216 (int (*)(...))QKeySequenceEdit::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI16QKeySequenceEdit) +448 (int (*)(...))QKeySequenceEdit::_ZThn16_N16QKeySequenceEditD1Ev +456 (int (*)(...))QKeySequenceEdit::_ZThn16_N16QKeySequenceEditD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QKeySequenceEdit + size=48 align=8 + base size=48 base align=8 +QKeySequenceEdit (0x0x7f9a52ac2958) 0 + vptr=((& QKeySequenceEdit::_ZTV16QKeySequenceEdit) + 16u) + QWidget (0x0x7f9a568a38c0) 0 + primary-for QKeySequenceEdit (0x0x7f9a52ac2958) + QObject (0x0x7f9a51626ae0) 0 + primary-for QWidget (0x0x7f9a568a38c0) + QPaintDevice (0x0x7f9a51626b40) 16 + vptr=((& QKeySequenceEdit::_ZTV16QKeySequenceEdit) + 448u) + +Class QLabel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLabel::QPrivateSignal (0x0x7f9a512af300) 0 empty + +Vtable for QLabel +QLabel::_ZTV6QLabel: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QLabel) +16 (int (*)(...))QLabel::metaObject +24 (int (*)(...))QLabel::qt_metacast +32 (int (*)(...))QLabel::qt_metacall +40 (int (*)(...))QLabel::~QLabel +48 (int (*)(...))QLabel::~QLabel +56 (int (*)(...))QLabel::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QLabel::sizeHint +136 (int (*)(...))QLabel::minimumSizeHint +144 (int (*)(...))QLabel::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QLabel::mousePressEvent +176 (int (*)(...))QLabel::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QLabel::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QLabel::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QLabel::focusInEvent +232 (int (*)(...))QLabel::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QLabel::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QLabel::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QLabel::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QLabel::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI6QLabel) +448 (int (*)(...))QLabel::_ZThn16_N6QLabelD1Ev +456 (int (*)(...))QLabel::_ZThn16_N6QLabelD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QLabel + size=48 align=8 + base size=48 base align=8 +QLabel (0x0x7f9a52ac29c0) 0 + vptr=((& QLabel::_ZTV6QLabel) + 16u) + QFrame (0x0x7f9a52ae4750) 0 + primary-for QLabel (0x0x7f9a52ac29c0) + QWidget (0x0x7f9a568a3bd0) 0 + primary-for QFrame (0x0x7f9a52ae4750) + QObject (0x0x7f9a5127e6c0) 0 + primary-for QWidget (0x0x7f9a568a3bd0) + QPaintDevice (0x0x7f9a512af2a0) 16 + vptr=((& QLabel::_ZTV6QLabel) + 448u) + +Class QLCDNumber::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLCDNumber::QPrivateSignal (0x0x7f9a51177960) 0 empty + +Vtable for QLCDNumber +QLCDNumber::_ZTV10QLCDNumber: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QLCDNumber) +16 (int (*)(...))QLCDNumber::metaObject +24 (int (*)(...))QLCDNumber::qt_metacast +32 (int (*)(...))QLCDNumber::qt_metacall +40 (int (*)(...))QLCDNumber::~QLCDNumber +48 (int (*)(...))QLCDNumber::~QLCDNumber +56 (int (*)(...))QLCDNumber::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QLCDNumber::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QLCDNumber::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI10QLCDNumber) +448 (int (*)(...))QLCDNumber::_ZThn16_N10QLCDNumberD1Ev +456 (int (*)(...))QLCDNumber::_ZThn16_N10QLCDNumberD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QLCDNumber + size=48 align=8 + base size=48 base align=8 +QLCDNumber (0x0x7f9a52ae48f0) 0 + vptr=((& QLCDNumber::_ZTV10QLCDNumber) + 16u) + QFrame (0x0x7f9a52ae4958) 0 + primary-for QLCDNumber (0x0x7f9a52ae48f0) + QWidget (0x0x7f9a568fd000) 0 + primary-for QFrame (0x0x7f9a52ae4958) + QObject (0x0x7f9a511774e0) 0 + primary-for QWidget (0x0x7f9a568fd000) + QPaintDevice (0x0x7f9a51177540) 16 + vptr=((& QLCDNumber::_ZTV10QLCDNumber) + 448u) + +Class QListView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QListView::QPrivateSignal (0x0x7f9a51177d20) 0 empty + +Vtable for QListView +QListView::_ZTV9QListView: 106u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QListView) +16 (int (*)(...))QListView::metaObject +24 (int (*)(...))QListView::qt_metacast +32 (int (*)(...))QListView::qt_metacall +40 (int (*)(...))QListView::~QListView +48 (int (*)(...))QListView::~QListView +56 (int (*)(...))QListView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QListView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QListView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QListView::mouseMoveEvent +200 (int (*)(...))QListView::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QListView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QListView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QListView::dragMoveEvent +328 (int (*)(...))QListView::dragLeaveEvent +336 (int (*)(...))QListView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractItemView::viewportEvent +448 (int (*)(...))QListView::scrollContentsBy +456 (int (*)(...))QListView::viewportSizeHint +464 (int (*)(...))QAbstractItemView::setModel +472 (int (*)(...))QAbstractItemView::setSelectionModel +480 (int (*)(...))QAbstractItemView::keyboardSearch +488 (int (*)(...))QListView::visualRect +496 (int (*)(...))QListView::scrollTo +504 (int (*)(...))QListView::indexAt +512 (int (*)(...))QAbstractItemView::sizeHintForRow +520 (int (*)(...))QAbstractItemView::sizeHintForColumn +528 (int (*)(...))QListView::reset +536 (int (*)(...))QListView::setRootIndex +544 (int (*)(...))QListView::doItemsLayout +552 (int (*)(...))QAbstractItemView::selectAll +560 (int (*)(...))QListView::dataChanged +568 (int (*)(...))QListView::rowsInserted +576 (int (*)(...))QListView::rowsAboutToBeRemoved +584 (int (*)(...))QListView::selectionChanged +592 (int (*)(...))QListView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QListView::updateGeometries +624 (int (*)(...))QAbstractItemView::verticalScrollbarAction +632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction +640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))QListView::moveCursor +688 (int (*)(...))QListView::horizontalOffset +696 (int (*)(...))QListView::verticalOffset +704 (int (*)(...))QListView::isIndexHidden +712 (int (*)(...))QListView::setSelection +720 (int (*)(...))QListView::visualRegionForSelection +728 (int (*)(...))QListView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QListView::startDrag +760 (int (*)(...))QListView::viewOptions +768 (int (*)(...))-16 +776 (int (*)(...))(& _ZTI9QListView) +784 (int (*)(...))QListView::_ZThn16_N9QListViewD1Ev +792 (int (*)(...))QListView::_ZThn16_N9QListViewD0Ev +800 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +808 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +816 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QListView + size=48 align=8 + base size=48 base align=8 +QListView (0x0x7f9a52ae49c0) 0 + vptr=((& QListView::_ZTV9QListView) + 16u) + QAbstractItemView (0x0x7f9a527669c0) 0 + primary-for QListView (0x0x7f9a52ae49c0) + QAbstractScrollArea (0x0x7f9a524e85b0) 0 + primary-for QAbstractItemView (0x0x7f9a527669c0) + QFrame (0x0x7f9a524e8750) 0 + primary-for QAbstractScrollArea (0x0x7f9a524e85b0) + QWidget (0x0x7f9a568fd7e0) 0 + primary-for QFrame (0x0x7f9a524e8750) + QObject (0x0x7f9a511779c0) 0 + primary-for QWidget (0x0x7f9a568fd7e0) + QPaintDevice (0x0x7f9a51177cc0) 16 + vptr=((& QListView::_ZTV9QListView) + 784u) + +Vtable for QListWidgetItem +QListWidgetItem::_ZTV15QListWidgetItem: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QListWidgetItem) +16 (int (*)(...))QListWidgetItem::~QListWidgetItem +24 (int (*)(...))QListWidgetItem::~QListWidgetItem +32 (int (*)(...))QListWidgetItem::clone +40 (int (*)(...))QListWidgetItem::setBackgroundColor +48 (int (*)(...))QListWidgetItem::data +56 (int (*)(...))QListWidgetItem::setData +64 (int (*)(...))QListWidgetItem::operator< +72 (int (*)(...))QListWidgetItem::read +80 (int (*)(...))QListWidgetItem::write + +Class QListWidgetItem + size=48 align=8 + base size=44 base align=8 +QListWidgetItem (0x0x7f9a51177ea0) 0 + vptr=((& QListWidgetItem::_ZTV15QListWidgetItem) + 16u) + +Class QListWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QListWidget::QPrivateSignal (0x0x7f9a50df1d20) 0 empty + +Vtable for QListWidget +QListWidget::_ZTV11QListWidget: 110u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QListWidget) +16 (int (*)(...))QListWidget::metaObject +24 (int (*)(...))QListWidget::qt_metacast +32 (int (*)(...))QListWidget::qt_metacall +40 (int (*)(...))QListWidget::~QListWidget +48 (int (*)(...))QListWidget::~QListWidget +56 (int (*)(...))QListWidget::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QListView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QListView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QListView::mouseMoveEvent +200 (int (*)(...))QListView::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QListView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QListView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QListView::dragMoveEvent +328 (int (*)(...))QListView::dragLeaveEvent +336 (int (*)(...))QListWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractItemView::viewportEvent +448 (int (*)(...))QListView::scrollContentsBy +456 (int (*)(...))QListView::viewportSizeHint +464 (int (*)(...))QListWidget::setModel +472 (int (*)(...))QListWidget::setSelectionModel +480 (int (*)(...))QAbstractItemView::keyboardSearch +488 (int (*)(...))QListView::visualRect +496 (int (*)(...))QListView::scrollTo +504 (int (*)(...))QListView::indexAt +512 (int (*)(...))QAbstractItemView::sizeHintForRow +520 (int (*)(...))QAbstractItemView::sizeHintForColumn +528 (int (*)(...))QListView::reset +536 (int (*)(...))QListView::setRootIndex +544 (int (*)(...))QListView::doItemsLayout +552 (int (*)(...))QAbstractItemView::selectAll +560 (int (*)(...))QListView::dataChanged +568 (int (*)(...))QListView::rowsInserted +576 (int (*)(...))QListView::rowsAboutToBeRemoved +584 (int (*)(...))QListView::selectionChanged +592 (int (*)(...))QListView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QListView::updateGeometries +624 (int (*)(...))QAbstractItemView::verticalScrollbarAction +632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction +640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))QListView::moveCursor +688 (int (*)(...))QListView::horizontalOffset +696 (int (*)(...))QListView::verticalOffset +704 (int (*)(...))QListView::isIndexHidden +712 (int (*)(...))QListView::setSelection +720 (int (*)(...))QListView::visualRegionForSelection +728 (int (*)(...))QListView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QListView::startDrag +760 (int (*)(...))QListView::viewOptions +768 (int (*)(...))QListWidget::mimeTypes +776 (int (*)(...))QListWidget::mimeData +784 (int (*)(...))QListWidget::dropMimeData +792 (int (*)(...))QListWidget::supportedDropActions +800 (int (*)(...))-16 +808 (int (*)(...))(& _ZTI11QListWidget) +816 (int (*)(...))QListWidget::_ZThn16_N11QListWidgetD1Ev +824 (int (*)(...))QListWidget::_ZThn16_N11QListWidgetD0Ev +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +848 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +856 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +864 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +872 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QListWidget + size=48 align=8 + base size=48 base align=8 +QListWidget (0x0x7f9a524e8a90) 0 + vptr=((& QListWidget::_ZTV11QListWidget) + 16u) + QListView (0x0x7f9a52312d00) 0 + primary-for QListWidget (0x0x7f9a524e8a90) + QAbstractItemView (0x0x7f9a52312d68) 0 + primary-for QListView (0x0x7f9a52312d00) + QAbstractScrollArea (0x0x7f9a523ac8f0) 0 + primary-for QAbstractItemView (0x0x7f9a52312d68) + QFrame (0x0x7f9a523eb680) 0 + primary-for QAbstractScrollArea (0x0x7f9a523ac8f0) + QWidget (0x0x7f9a569824d0) 0 + primary-for QFrame (0x0x7f9a523eb680) + QObject (0x0x7f9a50df1120) 0 + primary-for QWidget (0x0x7f9a569824d0) + QPaintDevice (0x0x7f9a50df1cc0) 16 + vptr=((& QListWidget::_ZTV11QListWidget) + 816u) + +Class QMainWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMainWindow::QPrivateSignal (0x0x7f9a50e1aba0) 0 empty + +Vtable for QMainWindow +QMainWindow::_ZTV11QMainWindow: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QMainWindow) +16 (int (*)(...))QMainWindow::metaObject +24 (int (*)(...))QMainWindow::qt_metacast +32 (int (*)(...))QMainWindow::qt_metacall +40 (int (*)(...))QMainWindow::~QMainWindow +48 (int (*)(...))QMainWindow::~QMainWindow +56 (int (*)(...))QMainWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QMainWindow::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QMainWindow::createPopupMenu +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI11QMainWindow) +456 (int (*)(...))QMainWindow::_ZThn16_N11QMainWindowD1Ev +464 (int (*)(...))QMainWindow::_ZThn16_N11QMainWindowD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QMainWindow + size=48 align=8 + base size=48 base align=8 +QMainWindow (0x0x7f9a523eb6e8) 0 + vptr=((& QMainWindow::_ZTV11QMainWindow) + 16u) + QWidget (0x0x7f9a56982f50) 0 + primary-for QMainWindow (0x0x7f9a523eb6e8) + QObject (0x0x7f9a50e1a900) 0 + primary-for QWidget (0x0x7f9a56982f50) + QPaintDevice (0x0x7f9a50e1a960) 16 + vptr=((& QMainWindow::_ZTV11QMainWindow) + 456u) + +Class QMdiArea::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMdiArea::QPrivateSignal (0x0x7f9a50cf9ae0) 0 empty + +Vtable for QMdiArea +QMdiArea::_ZTV8QMdiArea: 68u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QMdiArea) +16 (int (*)(...))QMdiArea::metaObject +24 (int (*)(...))QMdiArea::qt_metacast +32 (int (*)(...))QMdiArea::qt_metacall +40 (int (*)(...))QMdiArea::~QMdiArea +48 (int (*)(...))QMdiArea::~QMdiArea +56 (int (*)(...))QMdiArea::event +64 (int (*)(...))QMdiArea::eventFilter +72 (int (*)(...))QMdiArea::timerEvent +80 (int (*)(...))QMdiArea::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QMdiArea::sizeHint +136 (int (*)(...))QMdiArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractScrollArea::mousePressEvent +176 (int (*)(...))QAbstractScrollArea::mouseReleaseEvent +184 (int (*)(...))QAbstractScrollArea::mouseDoubleClickEvent +192 (int (*)(...))QAbstractScrollArea::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractScrollArea::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QMdiArea::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QMdiArea::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractScrollArea::dragEnterEvent +320 (int (*)(...))QAbstractScrollArea::dragMoveEvent +328 (int (*)(...))QAbstractScrollArea::dragLeaveEvent +336 (int (*)(...))QAbstractScrollArea::dropEvent +344 (int (*)(...))QMdiArea::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QMdiArea::setupViewport +440 (int (*)(...))QMdiArea::viewportEvent +448 (int (*)(...))QMdiArea::scrollContentsBy +456 (int (*)(...))QAbstractScrollArea::viewportSizeHint +464 (int (*)(...))-16 +472 (int (*)(...))(& _ZTI8QMdiArea) +480 (int (*)(...))QMdiArea::_ZThn16_N8QMdiAreaD1Ev +488 (int (*)(...))QMdiArea::_ZThn16_N8QMdiAreaD0Ev +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QMdiArea + size=48 align=8 + base size=48 base align=8 +QMdiArea (0x0x7f9a523ebaf8) 0 + vptr=((& QMdiArea::_ZTV8QMdiArea) + 16u) + QAbstractScrollArea (0x0x7f9a523ebd00) 0 + primary-for QMdiArea (0x0x7f9a523ebaf8) + QFrame (0x0x7f9a523ebdd0) 0 + primary-for QAbstractScrollArea (0x0x7f9a523ebd00) + QWidget (0x0x7f9a56a31230) 0 + primary-for QFrame (0x0x7f9a523ebdd0) + QObject (0x0x7f9a50cf9840) 0 + primary-for QWidget (0x0x7f9a56a31230) + QPaintDevice (0x0x7f9a50cf9900) 16 + vptr=((& QMdiArea::_ZTV8QMdiArea) + 480u) + +Class QMdiSubWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMdiSubWindow::QPrivateSignal (0x0x7f9a50d1e9c0) 0 empty + +Vtable for QMdiSubWindow +QMdiSubWindow::_ZTV13QMdiSubWindow: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QMdiSubWindow) +16 (int (*)(...))QMdiSubWindow::metaObject +24 (int (*)(...))QMdiSubWindow::qt_metacast +32 (int (*)(...))QMdiSubWindow::qt_metacall +40 (int (*)(...))QMdiSubWindow::~QMdiSubWindow +48 (int (*)(...))QMdiSubWindow::~QMdiSubWindow +56 (int (*)(...))QMdiSubWindow::event +64 (int (*)(...))QMdiSubWindow::eventFilter +72 (int (*)(...))QMdiSubWindow::timerEvent +80 (int (*)(...))QMdiSubWindow::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QMdiSubWindow::sizeHint +136 (int (*)(...))QMdiSubWindow::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QMdiSubWindow::mousePressEvent +176 (int (*)(...))QMdiSubWindow::mouseReleaseEvent +184 (int (*)(...))QMdiSubWindow::mouseDoubleClickEvent +192 (int (*)(...))QMdiSubWindow::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QMdiSubWindow::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QMdiSubWindow::focusInEvent +232 (int (*)(...))QMdiSubWindow::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QMdiSubWindow::leaveEvent +256 (int (*)(...))QMdiSubWindow::paintEvent +264 (int (*)(...))QMdiSubWindow::moveEvent +272 (int (*)(...))QMdiSubWindow::resizeEvent +280 (int (*)(...))QMdiSubWindow::closeEvent +288 (int (*)(...))QMdiSubWindow::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QMdiSubWindow::showEvent +352 (int (*)(...))QMdiSubWindow::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QMdiSubWindow::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI13QMdiSubWindow) +448 (int (*)(...))QMdiSubWindow::_ZThn16_N13QMdiSubWindowD1Ev +456 (int (*)(...))QMdiSubWindow::_ZThn16_N13QMdiSubWindowD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QMdiSubWindow + size=48 align=8 + base size=48 base align=8 +QMdiSubWindow (0x0x7f9a520ebc98) 0 + vptr=((& QMdiSubWindow::_ZTV13QMdiSubWindow) + 16u) + QWidget (0x0x7f9a56a3e4d0) 0 + primary-for QMdiSubWindow (0x0x7f9a520ebc98) + QObject (0x0x7f9a50d1e720) 0 + primary-for QWidget (0x0x7f9a56a3e4d0) + QPaintDevice (0x0x7f9a50d1e960) 16 + vptr=((& QMdiSubWindow::_ZTV13QMdiSubWindow) + 448u) + +Class QMenu::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMenu::QPrivateSignal (0x0x7f9a50a705a0) 0 empty + +Vtable for QMenu +QMenu::_ZTV5QMenu: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QMenu) +16 (int (*)(...))QMenu::metaObject +24 (int (*)(...))QMenu::qt_metacast +32 (int (*)(...))QMenu::qt_metacall +40 (int (*)(...))QMenu::~QMenu +48 (int (*)(...))QMenu::~QMenu +56 (int (*)(...))QMenu::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QMenu::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QMenu::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QMenu::mousePressEvent +176 (int (*)(...))QMenu::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QMenu::mouseMoveEvent +200 (int (*)(...))QMenu::wheelEvent +208 (int (*)(...))QMenu::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QMenu::enterEvent +248 (int (*)(...))QMenu::leaveEvent +256 (int (*)(...))QMenu::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QMenu::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QMenu::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QMenu::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QMenu::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI5QMenu) +448 (int (*)(...))QMenu::_ZThn16_N5QMenuD1Ev +456 (int (*)(...))QMenu::_ZThn16_N5QMenuD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QMenu + size=48 align=8 + base size=48 base align=8 +QMenu (0x0x7f9a5214e068) 0 + vptr=((& QMenu::_ZTV5QMenu) + 16u) + QWidget (0x0x7f9a56a528c0) 0 + primary-for QMenu (0x0x7f9a5214e068) + QObject (0x0x7f9a50a70180) 0 + primary-for QWidget (0x0x7f9a56a528c0) + QPaintDevice (0x0x7f9a50a70540) 16 + vptr=((& QMenu::_ZTV5QMenu) + 448u) + +Class QMenuBar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMenuBar::QPrivateSignal (0x0x7f9a50a95180) 0 empty + +Vtable for QMenuBar +QMenuBar::_ZTV8QMenuBar: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QMenuBar) +16 (int (*)(...))QMenuBar::metaObject +24 (int (*)(...))QMenuBar::qt_metacast +32 (int (*)(...))QMenuBar::qt_metacall +40 (int (*)(...))QMenuBar::~QMenuBar +48 (int (*)(...))QMenuBar::~QMenuBar +56 (int (*)(...))QMenuBar::event +64 (int (*)(...))QMenuBar::eventFilter +72 (int (*)(...))QMenuBar::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QMenuBar::setVisible +128 (int (*)(...))QMenuBar::sizeHint +136 (int (*)(...))QMenuBar::minimumSizeHint +144 (int (*)(...))QMenuBar::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QMenuBar::mousePressEvent +176 (int (*)(...))QMenuBar::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QMenuBar::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QMenuBar::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QMenuBar::focusInEvent +232 (int (*)(...))QMenuBar::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QMenuBar::leaveEvent +256 (int (*)(...))QMenuBar::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QMenuBar::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QMenuBar::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QMenuBar::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI8QMenuBar) +448 (int (*)(...))QMenuBar::_ZThn16_N8QMenuBarD1Ev +456 (int (*)(...))QMenuBar::_ZThn16_N8QMenuBarD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QMenuBar + size=48 align=8 + base size=48 base align=8 +QMenuBar (0x0x7f9a5214e0d0) 0 + vptr=((& QMenuBar::_ZTV8QMenuBar) + 16u) + QWidget (0x0x7f9a56810150) 0 + primary-for QMenuBar (0x0x7f9a5214e0d0) + QObject (0x0x7f9a50a70ae0) 0 + primary-for QWidget (0x0x7f9a56810150) + QPaintDevice (0x0x7f9a50a70b40) 16 + vptr=((& QMenuBar::_ZTV8QMenuBar) + 448u) + +Class QMessageBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMessageBox::QPrivateSignal (0x0x7f9a50a95a80) 0 empty + +Vtable for QMessageBox +QMessageBox::_ZTV11QMessageBox: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QMessageBox) +16 (int (*)(...))QMessageBox::metaObject +24 (int (*)(...))QMessageBox::qt_metacast +32 (int (*)(...))QMessageBox::qt_metacall +40 (int (*)(...))QMessageBox::~QMessageBox +48 (int (*)(...))QMessageBox::~QMessageBox +56 (int (*)(...))QMessageBox::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QMessageBox::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QMessageBox::resizeEvent +280 (int (*)(...))QMessageBox::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QMessageBox::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QMessageBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QDialog::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI11QMessageBox) +488 (int (*)(...))QMessageBox::_ZThn16_N11QMessageBoxD1Ev +496 (int (*)(...))QMessageBox::_ZThn16_N11QMessageBoxD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QMessageBox + size=48 align=8 + base size=48 base align=8 +QMessageBox (0x0x7f9a5214e208) 0 + vptr=((& QMessageBox::_ZTV11QMessageBox) + 16u) + QDialog (0x0x7f9a5214e270) 0 + primary-for QMessageBox (0x0x7f9a5214e208) + QWidget (0x0x7f9a56810700) 0 + primary-for QDialog (0x0x7f9a5214e270) + QObject (0x0x7f9a50a951e0) 0 + primary-for QWidget (0x0x7f9a56810700) + QPaintDevice (0x0x7f9a50a95a20) 16 + vptr=((& QMessageBox::_ZTV11QMessageBox) + 488u) + +Class QMouseEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMouseEventTransition::QPrivateSignal (0x0x7f9a50aeb1e0) 0 empty + +Vtable for QMouseEventTransition +QMouseEventTransition::_ZTV21QMouseEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QMouseEventTransition) +16 (int (*)(...))QMouseEventTransition::metaObject +24 (int (*)(...))QMouseEventTransition::qt_metacast +32 (int (*)(...))QMouseEventTransition::qt_metacall +40 (int (*)(...))QMouseEventTransition::~QMouseEventTransition +48 (int (*)(...))QMouseEventTransition::~QMouseEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMouseEventTransition::eventTest +120 (int (*)(...))QMouseEventTransition::onTransition + +Class QMouseEventTransition + size=16 align=8 + base size=16 base align=8 +QMouseEventTransition (0x0x7f9a51eaec30) 0 + vptr=((& QMouseEventTransition::_ZTV21QMouseEventTransition) + 16u) + QEventTransition (0x0x7f9a51fea9c0) 0 + primary-for QMouseEventTransition (0x0x7f9a51eaec30) + QAbstractTransition (0x0x7f9a51feac30) 0 + primary-for QEventTransition (0x0x7f9a51fea9c0) + QObject (0x0x7f9a50aeb180) 0 + primary-for QAbstractTransition (0x0x7f9a51feac30) + +Class QOpenGLWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLWidget::QPrivateSignal (0x0x7f9a50aeb480) 0 empty + +Vtable for QOpenGLWidget +QOpenGLWidget::_ZTV13QOpenGLWidget: 67u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QOpenGLWidget) +16 (int (*)(...))QOpenGLWidget::metaObject +24 (int (*)(...))QOpenGLWidget::qt_metacast +32 (int (*)(...))QOpenGLWidget::qt_metacall +40 (int (*)(...))QOpenGLWidget::~QOpenGLWidget +48 (int (*)(...))QOpenGLWidget::~QOpenGLWidget +56 (int (*)(...))QOpenGLWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QOpenGLWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QOpenGLWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QOpenGLWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QOpenGLWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QOpenGLWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QOpenGLWidget::initializeGL +440 (int (*)(...))QOpenGLWidget::resizeGL +448 (int (*)(...))QOpenGLWidget::paintGL +456 (int (*)(...))-16 +464 (int (*)(...))(& _ZTI13QOpenGLWidget) +472 (int (*)(...))QOpenGLWidget::_ZThn16_N13QOpenGLWidgetD1Ev +480 (int (*)(...))QOpenGLWidget::_ZThn16_N13QOpenGLWidgetD0Ev +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +496 (int (*)(...))QOpenGLWidget::_ZThn16_NK13QOpenGLWidget11paintEngineEv +504 (int (*)(...))QOpenGLWidget::_ZThn16_NK13QOpenGLWidget6metricEN12QPaintDevice17PaintDeviceMetricE +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +520 (int (*)(...))QOpenGLWidget::_ZThn16_NK13QOpenGLWidget10redirectedEP6QPoint +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QOpenGLWidget + size=48 align=8 + base size=48 base align=8 +QOpenGLWidget (0x0x7f9a51a91000) 0 + vptr=((& QOpenGLWidget::_ZTV13QOpenGLWidget) + 16u) + QWidget (0x0x7f9a56526620) 0 + primary-for QOpenGLWidget (0x0x7f9a51a91000) + QObject (0x0x7f9a50aeb360) 0 + primary-for QWidget (0x0x7f9a56526620) + QPaintDevice (0x0x7f9a50aeb3c0) 16 + vptr=((& QOpenGLWidget::_ZTV13QOpenGLWidget) + 472u) + +Class QTextEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextEdit::QPrivateSignal (0x0x7f9a50aeb660) 0 empty + +Class QTextEdit::ExtraSelection + size=24 align=8 + base size=24 base align=8 +QTextEdit::ExtraSelection (0x0x7f9a50aeb6c0) 0 + +Vtable for QTextEdit +QTextEdit::_ZTV9QTextEdit: 73u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTextEdit) +16 (int (*)(...))QTextEdit::metaObject +24 (int (*)(...))QTextEdit::qt_metacast +32 (int (*)(...))QTextEdit::qt_metacall +40 (int (*)(...))QTextEdit::~QTextEdit +48 (int (*)(...))QTextEdit::~QTextEdit +56 (int (*)(...))QTextEdit::event +64 (int (*)(...))QAbstractScrollArea::eventFilter +72 (int (*)(...))QTextEdit::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QTextEdit::mousePressEvent +176 (int (*)(...))QTextEdit::mouseReleaseEvent +184 (int (*)(...))QTextEdit::mouseDoubleClickEvent +192 (int (*)(...))QTextEdit::mouseMoveEvent +200 (int (*)(...))QTextEdit::wheelEvent +208 (int (*)(...))QTextEdit::keyPressEvent +216 (int (*)(...))QTextEdit::keyReleaseEvent +224 (int (*)(...))QTextEdit::focusInEvent +232 (int (*)(...))QTextEdit::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTextEdit::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QTextEdit::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QTextEdit::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QTextEdit::dragEnterEvent +320 (int (*)(...))QTextEdit::dragMoveEvent +328 (int (*)(...))QTextEdit::dragLeaveEvent +336 (int (*)(...))QTextEdit::dropEvent +344 (int (*)(...))QTextEdit::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QTextEdit::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QTextEdit::inputMethodEvent +416 (int (*)(...))QTextEdit::inputMethodQuery +424 (int (*)(...))QTextEdit::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractScrollArea::viewportEvent +448 (int (*)(...))QTextEdit::scrollContentsBy +456 (int (*)(...))QAbstractScrollArea::viewportSizeHint +464 (int (*)(...))QTextEdit::loadResource +472 (int (*)(...))QTextEdit::createMimeDataFromSelection +480 (int (*)(...))QTextEdit::canInsertFromMimeData +488 (int (*)(...))QTextEdit::insertFromMimeData +496 (int (*)(...))QTextEdit::doSetTextCursor +504 (int (*)(...))-16 +512 (int (*)(...))(& _ZTI9QTextEdit) +520 (int (*)(...))QTextEdit::_ZThn16_N9QTextEditD1Ev +528 (int (*)(...))QTextEdit::_ZThn16_N9QTextEditD0Ev +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +568 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +576 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTextEdit + size=48 align=8 + base size=48 base align=8 +QTextEdit (0x0x7f9a51a91548) 0 + vptr=((& QTextEdit::_ZTV9QTextEdit) + 16u) + QAbstractScrollArea (0x0x7f9a51a915b0) 0 + primary-for QTextEdit (0x0x7f9a51a91548) + QFrame (0x0x7f9a51a91888) 0 + primary-for QAbstractScrollArea (0x0x7f9a51a915b0) + QWidget (0x0x7f9a56526a80) 0 + primary-for QFrame (0x0x7f9a51a91888) + QObject (0x0x7f9a50aeb540) 0 + primary-for QWidget (0x0x7f9a56526a80) + QPaintDevice (0x0x7f9a50aeb5a0) 16 + vptr=((& QTextEdit::_ZTV9QTextEdit) + 520u) + +Class QPlainTextEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPlainTextEdit::QPrivateSignal (0x0x7f9a50b0bba0) 0 empty + +Vtable for QPlainTextEdit +QPlainTextEdit::_ZTV14QPlainTextEdit: 73u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QPlainTextEdit) +16 (int (*)(...))QPlainTextEdit::metaObject +24 (int (*)(...))QPlainTextEdit::qt_metacast +32 (int (*)(...))QPlainTextEdit::qt_metacall +40 (int (*)(...))QPlainTextEdit::~QPlainTextEdit +48 (int (*)(...))QPlainTextEdit::~QPlainTextEdit +56 (int (*)(...))QPlainTextEdit::event +64 (int (*)(...))QAbstractScrollArea::eventFilter +72 (int (*)(...))QPlainTextEdit::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QPlainTextEdit::mousePressEvent +176 (int (*)(...))QPlainTextEdit::mouseReleaseEvent +184 (int (*)(...))QPlainTextEdit::mouseDoubleClickEvent +192 (int (*)(...))QPlainTextEdit::mouseMoveEvent +200 (int (*)(...))QPlainTextEdit::wheelEvent +208 (int (*)(...))QPlainTextEdit::keyPressEvent +216 (int (*)(...))QPlainTextEdit::keyReleaseEvent +224 (int (*)(...))QPlainTextEdit::focusInEvent +232 (int (*)(...))QPlainTextEdit::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QPlainTextEdit::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QPlainTextEdit::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QPlainTextEdit::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QPlainTextEdit::dragEnterEvent +320 (int (*)(...))QPlainTextEdit::dragMoveEvent +328 (int (*)(...))QPlainTextEdit::dragLeaveEvent +336 (int (*)(...))QPlainTextEdit::dropEvent +344 (int (*)(...))QPlainTextEdit::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QPlainTextEdit::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QPlainTextEdit::inputMethodEvent +416 (int (*)(...))QPlainTextEdit::inputMethodQuery +424 (int (*)(...))QPlainTextEdit::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractScrollArea::viewportEvent +448 (int (*)(...))QPlainTextEdit::scrollContentsBy +456 (int (*)(...))QAbstractScrollArea::viewportSizeHint +464 (int (*)(...))QPlainTextEdit::loadResource +472 (int (*)(...))QPlainTextEdit::createMimeDataFromSelection +480 (int (*)(...))QPlainTextEdit::canInsertFromMimeData +488 (int (*)(...))QPlainTextEdit::insertFromMimeData +496 (int (*)(...))QPlainTextEdit::doSetTextCursor +504 (int (*)(...))-16 +512 (int (*)(...))(& _ZTI14QPlainTextEdit) +520 (int (*)(...))QPlainTextEdit::_ZThn16_N14QPlainTextEditD1Ev +528 (int (*)(...))QPlainTextEdit::_ZThn16_N14QPlainTextEditD0Ev +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +568 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +576 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QPlainTextEdit + size=48 align=8 + base size=48 base align=8 +QPlainTextEdit (0x0x7f9a51a91af8) 0 + vptr=((& QPlainTextEdit::_ZTV14QPlainTextEdit) + 16u) + QAbstractScrollArea (0x0x7f9a51a91c98) 0 + primary-for QPlainTextEdit (0x0x7f9a51a91af8) + QFrame (0x0x7f9a51a91d00) 0 + primary-for QAbstractScrollArea (0x0x7f9a51a91c98) + QWidget (0x0x7f9a5665e000) 0 + primary-for QFrame (0x0x7f9a51a91d00) + QObject (0x0x7f9a50b0ba20) 0 + primary-for QWidget (0x0x7f9a5665e000) + QPaintDevice (0x0x7f9a50b0ba80) 16 + vptr=((& QPlainTextEdit::_ZTV14QPlainTextEdit) + 520u) + +Class QPlainTextDocumentLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPlainTextDocumentLayout::QPrivateSignal (0x0x7f9a50b0be40) 0 empty + +Vtable for QPlainTextDocumentLayout +QPlainTextDocumentLayout::_ZTV24QPlainTextDocumentLayout: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QPlainTextDocumentLayout) +16 (int (*)(...))QPlainTextDocumentLayout::metaObject +24 (int (*)(...))QPlainTextDocumentLayout::qt_metacast +32 (int (*)(...))QPlainTextDocumentLayout::qt_metacall +40 (int (*)(...))QPlainTextDocumentLayout::~QPlainTextDocumentLayout +48 (int (*)(...))QPlainTextDocumentLayout::~QPlainTextDocumentLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPlainTextDocumentLayout::draw +120 (int (*)(...))QPlainTextDocumentLayout::hitTest +128 (int (*)(...))QPlainTextDocumentLayout::pageCount +136 (int (*)(...))QPlainTextDocumentLayout::documentSize +144 (int (*)(...))QPlainTextDocumentLayout::frameBoundingRect +152 (int (*)(...))QPlainTextDocumentLayout::blockBoundingRect +160 (int (*)(...))QPlainTextDocumentLayout::documentChanged +168 (int (*)(...))QAbstractTextDocumentLayout::resizeInlineObject +176 (int (*)(...))QAbstractTextDocumentLayout::positionInlineObject +184 (int (*)(...))QAbstractTextDocumentLayout::drawInlineObject + +Class QPlainTextDocumentLayout + size=16 align=8 + base size=16 base align=8 +QPlainTextDocumentLayout (0x0x7f9a51a91d68) 0 + vptr=((& QPlainTextDocumentLayout::_ZTV24QPlainTextDocumentLayout) + 16u) + QAbstractTextDocumentLayout (0x0x7f9a51ab1c98) 0 + primary-for QPlainTextDocumentLayout (0x0x7f9a51a91d68) + QObject (0x0x7f9a50b0bc00) 0 + primary-for QAbstractTextDocumentLayout (0x0x7f9a51ab1c98) + +Class QProgressBar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProgressBar::QPrivateSignal (0x0x7f9a50b2d960) 0 empty + +Vtable for QProgressBar +QProgressBar::_ZTV12QProgressBar: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QProgressBar) +16 (int (*)(...))QProgressBar::metaObject +24 (int (*)(...))QProgressBar::qt_metacast +32 (int (*)(...))QProgressBar::qt_metacall +40 (int (*)(...))QProgressBar::~QProgressBar +48 (int (*)(...))QProgressBar::~QProgressBar +56 (int (*)(...))QProgressBar::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QProgressBar::sizeHint +136 (int (*)(...))QProgressBar::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QProgressBar::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QProgressBar::text +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI12QProgressBar) +456 (int (*)(...))QProgressBar::_ZThn16_N12QProgressBarD1Ev +464 (int (*)(...))QProgressBar::_ZThn16_N12QProgressBarD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QProgressBar + size=48 align=8 + base size=48 base align=8 +QProgressBar (0x0x7f9a51ab1d00) 0 + vptr=((& QProgressBar::_ZTV12QProgressBar) + 16u) + QWidget (0x0x7f9a5665ed20) 0 + primary-for QProgressBar (0x0x7f9a51ab1d00) + QObject (0x0x7f9a50b0bea0) 0 + primary-for QWidget (0x0x7f9a5665ed20) + QPaintDevice (0x0x7f9a50b2d900) 16 + vptr=((& QProgressBar::_ZTV12QProgressBar) + 456u) + +Class QProgressDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProgressDialog::QPrivateSignal (0x0x7f9a50b2dc60) 0 empty + +Vtable for QProgressDialog +QProgressDialog::_ZTV15QProgressDialog: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QProgressDialog) +16 (int (*)(...))QProgressDialog::metaObject +24 (int (*)(...))QProgressDialog::qt_metacast +32 (int (*)(...))QProgressDialog::qt_metacall +40 (int (*)(...))QProgressDialog::~QProgressDialog +48 (int (*)(...))QProgressDialog::~QProgressDialog +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QDialog::setVisible +128 (int (*)(...))QProgressDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QProgressDialog::resizeEvent +280 (int (*)(...))QProgressDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QProgressDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QProgressDialog::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QDialog::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI15QProgressDialog) +488 (int (*)(...))QProgressDialog::_ZThn16_N15QProgressDialogD1Ev +496 (int (*)(...))QProgressDialog::_ZThn16_N15QProgressDialogD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QProgressDialog + size=48 align=8 + base size=48 base align=8 +QProgressDialog (0x0x7f9a51ab1dd0) 0 + vptr=((& QProgressDialog::_ZTV15QProgressDialog) + 16u) + QDialog (0x0x7f9a51ab1e38) 0 + primary-for QProgressDialog (0x0x7f9a51ab1dd0) + QWidget (0x0x7f9a562b62a0) 0 + primary-for QDialog (0x0x7f9a51ab1e38) + QObject (0x0x7f9a50b2da20) 0 + primary-for QWidget (0x0x7f9a562b62a0) + QPaintDevice (0x0x7f9a50b2dc00) 16 + vptr=((& QProgressDialog::_ZTV15QProgressDialog) + 488u) + +Class QProxyStyle::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProxyStyle::QPrivateSignal (0x0x7f9a50b58840) 0 empty + +Vtable for QProxyStyle +QProxyStyle::_ZTV11QProxyStyle: 37u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QProxyStyle) +16 (int (*)(...))QProxyStyle::metaObject +24 (int (*)(...))QProxyStyle::qt_metacast +32 (int (*)(...))QProxyStyle::qt_metacall +40 (int (*)(...))QProxyStyle::~QProxyStyle +48 (int (*)(...))QProxyStyle::~QProxyStyle +56 (int (*)(...))QProxyStyle::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProxyStyle::polish +120 (int (*)(...))QProxyStyle::unpolish +128 (int (*)(...))QProxyStyle::polish +136 (int (*)(...))QProxyStyle::unpolish +144 (int (*)(...))QProxyStyle::polish +152 (int (*)(...))QProxyStyle::itemTextRect +160 (int (*)(...))QProxyStyle::itemPixmapRect +168 (int (*)(...))QProxyStyle::drawItemText +176 (int (*)(...))QProxyStyle::drawItemPixmap +184 (int (*)(...))QProxyStyle::standardPalette +192 (int (*)(...))QProxyStyle::drawPrimitive +200 (int (*)(...))QProxyStyle::drawControl +208 (int (*)(...))QProxyStyle::subElementRect +216 (int (*)(...))QProxyStyle::drawComplexControl +224 (int (*)(...))QProxyStyle::hitTestComplexControl +232 (int (*)(...))QProxyStyle::subControlRect +240 (int (*)(...))QProxyStyle::pixelMetric +248 (int (*)(...))QProxyStyle::sizeFromContents +256 (int (*)(...))QProxyStyle::styleHint +264 (int (*)(...))QProxyStyle::standardPixmap +272 (int (*)(...))QProxyStyle::standardIcon +280 (int (*)(...))QProxyStyle::generatedIconPixmap +288 (int (*)(...))QProxyStyle::layoutSpacing + +Class QProxyStyle + size=16 align=8 + base size=16 base align=8 +QProxyStyle (0x0x7f9a51acf1a0) 0 + vptr=((& QProxyStyle::_ZTV11QProxyStyle) + 16u) + QCommonStyle (0x0x7f9a51acf208) 0 + primary-for QProxyStyle (0x0x7f9a51acf1a0) + QStyle (0x0x7f9a51acf820) 0 + primary-for QCommonStyle (0x0x7f9a51acf208) + QObject (0x0x7f9a50b587e0) 0 + primary-for QStyle (0x0x7f9a51acf820) + +Class QRadioButton::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRadioButton::QPrivateSignal (0x0x7f9a50b812a0) 0 empty + +Vtable for QRadioButton +QRadioButton::_ZTV12QRadioButton: 67u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QRadioButton) +16 (int (*)(...))QRadioButton::metaObject +24 (int (*)(...))QRadioButton::qt_metacast +32 (int (*)(...))QRadioButton::qt_metacall +40 (int (*)(...))QRadioButton::~QRadioButton +48 (int (*)(...))QRadioButton::~QRadioButton +56 (int (*)(...))QRadioButton::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractButton::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QRadioButton::sizeHint +136 (int (*)(...))QRadioButton::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractButton::mousePressEvent +176 (int (*)(...))QAbstractButton::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QRadioButton::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QAbstractButton::keyPressEvent +216 (int (*)(...))QAbstractButton::keyReleaseEvent +224 (int (*)(...))QAbstractButton::focusInEvent +232 (int (*)(...))QAbstractButton::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QRadioButton::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractButton::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QRadioButton::hitButton +440 (int (*)(...))QAbstractButton::checkStateSet +448 (int (*)(...))QAbstractButton::nextCheckState +456 (int (*)(...))-16 +464 (int (*)(...))(& _ZTI12QRadioButton) +472 (int (*)(...))QRadioButton::_ZThn16_N12QRadioButtonD1Ev +480 (int (*)(...))QRadioButton::_ZThn16_N12QRadioButtonD0Ev +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QRadioButton + size=48 align=8 + base size=48 base align=8 +QRadioButton (0x0x7f9a51acf888) 0 + vptr=((& QRadioButton::_ZTV12QRadioButton) + 16u) + QAbstractButton (0x0x7f9a51acfbc8) 0 + primary-for QRadioButton (0x0x7f9a51acf888) + QWidget (0x0x7f9a562b6930) 0 + primary-for QAbstractButton (0x0x7f9a51acfbc8) + QObject (0x0x7f9a50b81180) 0 + primary-for QWidget (0x0x7f9a562b6930) + QPaintDevice (0x0x7f9a50b811e0) 16 + vptr=((& QRadioButton::_ZTV12QRadioButton) + 472u) + +Class QScrollBar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QScrollBar::QPrivateSignal (0x0x7f9a50b81b40) 0 empty + +Vtable for QScrollBar +QScrollBar::_ZTV10QScrollBar: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QScrollBar) +16 (int (*)(...))QScrollBar::metaObject +24 (int (*)(...))QScrollBar::qt_metacast +32 (int (*)(...))QScrollBar::qt_metacall +40 (int (*)(...))QScrollBar::~QScrollBar +48 (int (*)(...))QScrollBar::~QScrollBar +56 (int (*)(...))QScrollBar::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSlider::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QScrollBar::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QScrollBar::mousePressEvent +176 (int (*)(...))QScrollBar::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QScrollBar::mouseMoveEvent +200 (int (*)(...))QScrollBar::wheelEvent +208 (int (*)(...))QAbstractSlider::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QScrollBar::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QScrollBar::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QScrollBar::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSlider::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QScrollBar::sliderChange +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI10QScrollBar) +456 (int (*)(...))QScrollBar::_ZThn16_N10QScrollBarD1Ev +464 (int (*)(...))QScrollBar::_ZThn16_N10QScrollBarD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QScrollBar + size=48 align=8 + base size=48 base align=8 +QScrollBar (0x0x7f9a51acfc30) 0 + vptr=((& QScrollBar::_ZTV10QScrollBar) + 16u) + QAbstractSlider (0x0x7f9a51aedc98) 0 + primary-for QScrollBar (0x0x7f9a51acfc30) + QWidget (0x0x7f9a562b6cb0) 0 + primary-for QAbstractSlider (0x0x7f9a51aedc98) + QObject (0x0x7f9a50b81a20) 0 + primary-for QWidget (0x0x7f9a562b6cb0) + QPaintDevice (0x0x7f9a50b81a80) 16 + vptr=((& QScrollBar::_ZTV10QScrollBar) + 456u) + +Vtable for QScrollerProperties +QScrollerProperties::_ZTV19QScrollerProperties: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QScrollerProperties) +16 (int (*)(...))QScrollerProperties::~QScrollerProperties +24 (int (*)(...))QScrollerProperties::~QScrollerProperties + +Class QScrollerProperties + size=16 align=8 + base size=16 base align=8 +QScrollerProperties (0x0x7f9a50ba6480) 0 + vptr=((& QScrollerProperties::_ZTV19QScrollerProperties) + 16u) + +Class QScroller::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QScroller::QPrivateSignal (0x0x7f9a50bd52a0) 0 empty + +Vtable for QScroller +QScroller::_ZTV9QScroller: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QScroller) +16 (int (*)(...))QScroller::metaObject +24 (int (*)(...))QScroller::qt_metacast +32 (int (*)(...))QScroller::qt_metacall +40 (int (*)(...))QScroller::~QScroller +48 (int (*)(...))QScroller::~QScroller +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QScroller + size=24 align=8 + base size=24 base align=8 +QScroller (0x0x7f9a51bf3270) 0 + vptr=((& QScroller::_ZTV9QScroller) + 16u) + QObject (0x0x7f9a50bd5240) 0 + primary-for QScroller (0x0x7f9a51bf3270) + +Class QShortcut::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QShortcut::QPrivateSignal (0x0x7f9a507f7660) 0 empty + +Vtable for QShortcut +QShortcut::_ZTV9QShortcut: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QShortcut) +16 (int (*)(...))QShortcut::metaObject +24 (int (*)(...))QShortcut::qt_metacast +32 (int (*)(...))QShortcut::qt_metacall +40 (int (*)(...))QShortcut::~QShortcut +48 (int (*)(...))QShortcut::~QShortcut +56 (int (*)(...))QShortcut::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QShortcut + size=16 align=8 + base size=16 base align=8 +QShortcut (0x0x7f9a51bf3f70) 0 + vptr=((& QShortcut::_ZTV9QShortcut) + 16u) + QObject (0x0x7f9a507f7600) 0 + primary-for QShortcut (0x0x7f9a51bf3f70) + +Class QSizeGrip::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSizeGrip::QPrivateSignal (0x0x7f9a50631ae0) 0 empty + +Vtable for QSizeGrip +QSizeGrip::_ZTV9QSizeGrip: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSizeGrip) +16 (int (*)(...))QSizeGrip::metaObject +24 (int (*)(...))QSizeGrip::qt_metacast +32 (int (*)(...))QSizeGrip::qt_metacall +40 (int (*)(...))QSizeGrip::~QSizeGrip +48 (int (*)(...))QSizeGrip::~QSizeGrip +56 (int (*)(...))QSizeGrip::event +64 (int (*)(...))QSizeGrip::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QSizeGrip::setVisible +128 (int (*)(...))QSizeGrip::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QSizeGrip::mousePressEvent +176 (int (*)(...))QSizeGrip::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QSizeGrip::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QSizeGrip::paintEvent +264 (int (*)(...))QSizeGrip::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QSizeGrip::showEvent +352 (int (*)(...))QSizeGrip::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI9QSizeGrip) +448 (int (*)(...))QSizeGrip::_ZThn16_N9QSizeGripD1Ev +456 (int (*)(...))QSizeGrip::_ZThn16_N9QSizeGripD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QSizeGrip + size=48 align=8 + base size=48 base align=8 +QSizeGrip (0x0x7f9a51898548) 0 + vptr=((& QSizeGrip::_ZTV9QSizeGrip) + 16u) + QWidget (0x0x7f9a560cb4d0) 0 + primary-for QSizeGrip (0x0x7f9a51898548) + QObject (0x0x7f9a506313c0) 0 + primary-for QWidget (0x0x7f9a560cb4d0) + QPaintDevice (0x0x7f9a50631420) 16 + vptr=((& QSizeGrip::_ZTV9QSizeGrip) + 448u) + +Class QSpinBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSpinBox::QPrivateSignal (0x0x7f9a50657300) 0 empty + +Vtable for QSpinBox +QSpinBox::_ZTV8QSpinBox: 71u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QSpinBox) +16 (int (*)(...))QSpinBox::metaObject +24 (int (*)(...))QSpinBox::qt_metacast +32 (int (*)(...))QSpinBox::qt_metacall +40 (int (*)(...))QSpinBox::~QSpinBox +48 (int (*)(...))QSpinBox::~QSpinBox +56 (int (*)(...))QSpinBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSpinBox::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractSpinBox::sizeHint +136 (int (*)(...))QAbstractSpinBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractSpinBox::mousePressEvent +176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent +200 (int (*)(...))QAbstractSpinBox::wheelEvent +208 (int (*)(...))QAbstractSpinBox::keyPressEvent +216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent +224 (int (*)(...))QAbstractSpinBox::focusInEvent +232 (int (*)(...))QAbstractSpinBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractSpinBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractSpinBox::resizeEvent +280 (int (*)(...))QAbstractSpinBox::closeEvent +288 (int (*)(...))QAbstractSpinBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QAbstractSpinBox::showEvent +352 (int (*)(...))QAbstractSpinBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSpinBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QAbstractSpinBox::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QSpinBox::validate +440 (int (*)(...))QSpinBox::fixup +448 (int (*)(...))QAbstractSpinBox::stepBy +456 (int (*)(...))QAbstractSpinBox::clear +464 (int (*)(...))QAbstractSpinBox::stepEnabled +472 (int (*)(...))QSpinBox::valueFromText +480 (int (*)(...))QSpinBox::textFromValue +488 (int (*)(...))-16 +496 (int (*)(...))(& _ZTI8QSpinBox) +504 (int (*)(...))QSpinBox::_ZThn16_N8QSpinBoxD1Ev +512 (int (*)(...))QSpinBox::_ZThn16_N8QSpinBoxD0Ev +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QSpinBox + size=48 align=8 + base size=48 base align=8 +QSpinBox (0x0x7f9a518985b0) 0 + vptr=((& QSpinBox::_ZTV8QSpinBox) + 16u) + QAbstractSpinBox (0x0x7f9a51898f08) 0 + primary-for QSpinBox (0x0x7f9a518985b0) + QWidget (0x0x7f9a560cb850) 0 + primary-for QAbstractSpinBox (0x0x7f9a51898f08) + QObject (0x0x7f9a50631b40) 0 + primary-for QWidget (0x0x7f9a560cb850) + QPaintDevice (0x0x7f9a506572a0) 16 + vptr=((& QSpinBox::_ZTV8QSpinBox) + 504u) + +Class QDoubleSpinBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDoubleSpinBox::QPrivateSignal (0x0x7f9a50657840) 0 empty + +Vtable for QDoubleSpinBox +QDoubleSpinBox::_ZTV14QDoubleSpinBox: 71u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QDoubleSpinBox) +16 (int (*)(...))QDoubleSpinBox::metaObject +24 (int (*)(...))QDoubleSpinBox::qt_metacast +32 (int (*)(...))QDoubleSpinBox::qt_metacall +40 (int (*)(...))QDoubleSpinBox::~QDoubleSpinBox +48 (int (*)(...))QDoubleSpinBox::~QDoubleSpinBox +56 (int (*)(...))QAbstractSpinBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSpinBox::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractSpinBox::sizeHint +136 (int (*)(...))QAbstractSpinBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractSpinBox::mousePressEvent +176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent +200 (int (*)(...))QAbstractSpinBox::wheelEvent +208 (int (*)(...))QAbstractSpinBox::keyPressEvent +216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent +224 (int (*)(...))QAbstractSpinBox::focusInEvent +232 (int (*)(...))QAbstractSpinBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractSpinBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractSpinBox::resizeEvent +280 (int (*)(...))QAbstractSpinBox::closeEvent +288 (int (*)(...))QAbstractSpinBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QAbstractSpinBox::showEvent +352 (int (*)(...))QAbstractSpinBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSpinBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QAbstractSpinBox::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDoubleSpinBox::validate +440 (int (*)(...))QDoubleSpinBox::fixup +448 (int (*)(...))QAbstractSpinBox::stepBy +456 (int (*)(...))QAbstractSpinBox::clear +464 (int (*)(...))QAbstractSpinBox::stepEnabled +472 (int (*)(...))QDoubleSpinBox::valueFromText +480 (int (*)(...))QDoubleSpinBox::textFromValue +488 (int (*)(...))-16 +496 (int (*)(...))(& _ZTI14QDoubleSpinBox) +504 (int (*)(...))QDoubleSpinBox::_ZThn16_N14QDoubleSpinBoxD1Ev +512 (int (*)(...))QDoubleSpinBox::_ZThn16_N14QDoubleSpinBoxD0Ev +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDoubleSpinBox + size=48 align=8 + base size=48 base align=8 +QDoubleSpinBox (0x0x7f9a51898f70) 0 + vptr=((& QDoubleSpinBox::_ZTV14QDoubleSpinBox) + 16u) + QAbstractSpinBox (0x0x7f9a51a01a90) 0 + primary-for QDoubleSpinBox (0x0x7f9a51898f70) + QWidget (0x0x7f9a560cbb60) 0 + primary-for QAbstractSpinBox (0x0x7f9a51a01a90) + QObject (0x0x7f9a50657720) 0 + primary-for QWidget (0x0x7f9a560cbb60) + QPaintDevice (0x0x7f9a50657780) 16 + vptr=((& QDoubleSpinBox::_ZTV14QDoubleSpinBox) + 504u) + +Class QSplashScreen::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSplashScreen::QPrivateSignal (0x0x7f9a50678480) 0 empty + +Vtable for QSplashScreen +QSplashScreen::_ZTV13QSplashScreen: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSplashScreen) +16 (int (*)(...))QSplashScreen::metaObject +24 (int (*)(...))QSplashScreen::qt_metacast +32 (int (*)(...))QSplashScreen::qt_metacall +40 (int (*)(...))QSplashScreen::~QSplashScreen +48 (int (*)(...))QSplashScreen::~QSplashScreen +56 (int (*)(...))QSplashScreen::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QSplashScreen::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QSplashScreen::drawContents +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI13QSplashScreen) +456 (int (*)(...))QSplashScreen::_ZThn16_N13QSplashScreenD1Ev +464 (int (*)(...))QSplashScreen::_ZThn16_N13QSplashScreenD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QSplashScreen + size=48 align=8 + base size=48 base align=8 +QSplashScreen (0x0x7f9a51a01af8) 0 + vptr=((& QSplashScreen::_ZTV13QSplashScreen) + 16u) + QWidget (0x0x7f9a560cbe70) 0 + primary-for QSplashScreen (0x0x7f9a51a01af8) + QObject (0x0x7f9a50657a20) 0 + primary-for QWidget (0x0x7f9a560cbe70) + QPaintDevice (0x0x7f9a50657a80) 16 + vptr=((& QSplashScreen::_ZTV13QSplashScreen) + 456u) + +Class QSplitter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSplitter::QPrivateSignal (0x0x7f9a506788a0) 0 empty + +Vtable for QSplitter +QSplitter::_ZTV9QSplitter: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSplitter) +16 (int (*)(...))QSplitter::metaObject +24 (int (*)(...))QSplitter::qt_metacast +32 (int (*)(...))QSplitter::qt_metacall +40 (int (*)(...))QSplitter::~QSplitter +48 (int (*)(...))QSplitter::~QSplitter +56 (int (*)(...))QSplitter::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QSplitter::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QSplitter::sizeHint +136 (int (*)(...))QSplitter::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QFrame::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QSplitter::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QSplitter::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QSplitter::createHandle +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI9QSplitter) +456 (int (*)(...))QSplitter::_ZThn16_N9QSplitterD1Ev +464 (int (*)(...))QSplitter::_ZThn16_N9QSplitterD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QSplitter + size=48 align=8 + base size=48 base align=8 +QSplitter (0x0x7f9a51a01c98) 0 + vptr=((& QSplitter::_ZTV9QSplitter) + 16u) + QFrame (0x0x7f9a51a01ea0) 0 + primary-for QSplitter (0x0x7f9a51a01c98) + QWidget (0x0x7f9a561b9620) 0 + primary-for QFrame (0x0x7f9a51a01ea0) + QObject (0x0x7f9a506784e0) 0 + primary-for QWidget (0x0x7f9a561b9620) + QPaintDevice (0x0x7f9a50678840) 16 + vptr=((& QSplitter::_ZTV9QSplitter) + 456u) + +Class QSplitterHandle::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSplitterHandle::QPrivateSignal (0x0x7f9a50678d80) 0 empty + +Vtable for QSplitterHandle +QSplitterHandle::_ZTV15QSplitterHandle: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSplitterHandle) +16 (int (*)(...))QSplitterHandle::metaObject +24 (int (*)(...))QSplitterHandle::qt_metacast +32 (int (*)(...))QSplitterHandle::qt_metacall +40 (int (*)(...))QSplitterHandle::~QSplitterHandle +48 (int (*)(...))QSplitterHandle::~QSplitterHandle +56 (int (*)(...))QSplitterHandle::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QSplitterHandle::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QSplitterHandle::mousePressEvent +176 (int (*)(...))QSplitterHandle::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QSplitterHandle::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QSplitterHandle::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QSplitterHandle::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI15QSplitterHandle) +448 (int (*)(...))QSplitterHandle::_ZThn16_N15QSplitterHandleD1Ev +456 (int (*)(...))QSplitterHandle::_ZThn16_N15QSplitterHandleD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QSplitterHandle + size=48 align=8 + base size=48 base align=8 +QSplitterHandle (0x0x7f9a51a01f08) 0 + vptr=((& QSplitterHandle::_ZTV15QSplitterHandle) + 16u) + QWidget (0x0x7f9a561b9930) 0 + primary-for QSplitterHandle (0x0x7f9a51a01f08) + QObject (0x0x7f9a50678ba0) 0 + primary-for QWidget (0x0x7f9a561b9930) + QPaintDevice (0x0x7f9a50678c00) 16 + vptr=((& QSplitterHandle::_ZTV15QSplitterHandle) + 448u) + +Class QStackedLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStackedLayout::QPrivateSignal (0x0x7f9a50678f60) 0 empty + +Vtable for QStackedLayout +QStackedLayout::_ZTV14QStackedLayout: 50u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QStackedLayout) +16 (int (*)(...))QStackedLayout::metaObject +24 (int (*)(...))QStackedLayout::qt_metacast +32 (int (*)(...))QStackedLayout::qt_metacall +40 (int (*)(...))QStackedLayout::~QStackedLayout +48 (int (*)(...))QStackedLayout::~QStackedLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLayout::invalidate +120 (int (*)(...))QLayout::geometry +128 (int (*)(...))QStackedLayout::addItem +136 (int (*)(...))QLayout::expandingDirections +144 (int (*)(...))QStackedLayout::minimumSize +152 (int (*)(...))QLayout::maximumSize +160 (int (*)(...))QStackedLayout::setGeometry +168 (int (*)(...))QStackedLayout::itemAt +176 (int (*)(...))QStackedLayout::takeAt +184 (int (*)(...))QLayout::indexOf +192 (int (*)(...))QStackedLayout::count +200 (int (*)(...))QLayout::isEmpty +208 (int (*)(...))QLayout::controlTypes +216 (int (*)(...))QLayout::layout +224 (int (*)(...))QStackedLayout::sizeHint +232 (int (*)(...))QStackedLayout::hasHeightForWidth +240 (int (*)(...))QStackedLayout::heightForWidth +248 (int (*)(...))-16 +256 (int (*)(...))(& _ZTI14QStackedLayout) +264 (int (*)(...))QStackedLayout::_ZThn16_N14QStackedLayoutD1Ev +272 (int (*)(...))QStackedLayout::_ZThn16_N14QStackedLayoutD0Ev +280 (int (*)(...))QStackedLayout::_ZThn16_NK14QStackedLayout8sizeHintEv +288 (int (*)(...))QStackedLayout::_ZThn16_NK14QStackedLayout11minimumSizeEv +296 (int (*)(...))QLayout::_ZThn16_NK7QLayout11maximumSizeEv +304 (int (*)(...))QLayout::_ZThn16_NK7QLayout19expandingDirectionsEv +312 (int (*)(...))QStackedLayout::_ZThn16_N14QStackedLayout11setGeometryERK5QRect +320 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +328 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +336 (int (*)(...))QStackedLayout::_ZThn16_NK14QStackedLayout17hasHeightForWidthEv +344 (int (*)(...))QStackedLayout::_ZThn16_NK14QStackedLayout14heightForWidthEi +352 (int (*)(...))QLayoutItem::minimumHeightForWidth +360 (int (*)(...))QLayout::_ZThn16_N7QLayout10invalidateEv +368 (int (*)(...))QLayoutItem::widget +376 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +384 (int (*)(...))QLayoutItem::spacerItem +392 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QStackedLayout + size=32 align=8 + base size=28 base align=8 +QStackedLayout (0x0x7f9a5164ac98) 0 + vptr=((& QStackedLayout::_ZTV14QStackedLayout) + 16u) + QLayout (0x0x7f9a561b9c40) 0 + primary-for QStackedLayout (0x0x7f9a5164ac98) + QObject (0x0x7f9a50678de0) 0 + primary-for QLayout (0x0x7f9a561b9c40) + QLayoutItem (0x0x7f9a50678ea0) 16 + vptr=((& QStackedLayout::_ZTV14QStackedLayout) + 264u) + +Class QStackedWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStackedWidget::QPrivateSignal (0x0x7f9a5069ea80) 0 empty + +Vtable for QStackedWidget +QStackedWidget::_ZTV14QStackedWidget: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QStackedWidget) +16 (int (*)(...))QStackedWidget::metaObject +24 (int (*)(...))QStackedWidget::qt_metacast +32 (int (*)(...))QStackedWidget::qt_metacall +40 (int (*)(...))QStackedWidget::~QStackedWidget +48 (int (*)(...))QStackedWidget::~QStackedWidget +56 (int (*)(...))QStackedWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QFrame::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QFrame::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI14QStackedWidget) +448 (int (*)(...))QStackedWidget::_ZThn16_N14QStackedWidgetD1Ev +456 (int (*)(...))QStackedWidget::_ZThn16_N14QStackedWidgetD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QStackedWidget + size=48 align=8 + base size=48 base align=8 +QStackedWidget (0x0x7f9a5164ad00) 0 + vptr=((& QStackedWidget::_ZTV14QStackedWidget) + 16u) + QFrame (0x0x7f9a5166e750) 0 + primary-for QStackedWidget (0x0x7f9a5164ad00) + QWidget (0x0x7f9a56256150) 0 + primary-for QFrame (0x0x7f9a5166e750) + QObject (0x0x7f9a5069e000) 0 + primary-for QWidget (0x0x7f9a56256150) + QPaintDevice (0x0x7f9a5069ea20) 16 + vptr=((& QStackedWidget::_ZTV14QStackedWidget) + 448u) + +Class QStatusBar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStatusBar::QPrivateSignal (0x0x7f9a5069ee40) 0 empty + +Vtable for QStatusBar +QStatusBar::_ZTV10QStatusBar: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QStatusBar) +16 (int (*)(...))QStatusBar::metaObject +24 (int (*)(...))QStatusBar::qt_metacast +32 (int (*)(...))QStatusBar::qt_metacall +40 (int (*)(...))QStatusBar::~QStatusBar +48 (int (*)(...))QStatusBar::~QStatusBar +56 (int (*)(...))QStatusBar::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QStatusBar::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QStatusBar::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QStatusBar::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI10QStatusBar) +448 (int (*)(...))QStatusBar::_ZThn16_N10QStatusBarD1Ev +456 (int (*)(...))QStatusBar::_ZThn16_N10QStatusBarD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QStatusBar + size=48 align=8 + base size=48 base align=8 +QStatusBar (0x0x7f9a5166e7b8) 0 + vptr=((& QStatusBar::_ZTV10QStatusBar) + 16u) + QWidget (0x0x7f9a562564d0) 0 + primary-for QStatusBar (0x0x7f9a5166e7b8) + QObject (0x0x7f9a5069eba0) 0 + primary-for QWidget (0x0x7f9a562564d0) + QPaintDevice (0x0x7f9a5069ec00) 16 + vptr=((& QStatusBar::_ZTV10QStatusBar) + 448u) + +Class QStyledItemDelegate::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStyledItemDelegate::QPrivateSignal (0x0x7f9a5046ef00) 0 empty + +Vtable for QStyledItemDelegate +QStyledItemDelegate::_ZTV19QStyledItemDelegate: 26u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QStyledItemDelegate) +16 (int (*)(...))QStyledItemDelegate::metaObject +24 (int (*)(...))QStyledItemDelegate::qt_metacast +32 (int (*)(...))QStyledItemDelegate::qt_metacall +40 (int (*)(...))QStyledItemDelegate::~QStyledItemDelegate +48 (int (*)(...))QStyledItemDelegate::~QStyledItemDelegate +56 (int (*)(...))QObject::event +64 (int (*)(...))QStyledItemDelegate::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStyledItemDelegate::paint +120 (int (*)(...))QStyledItemDelegate::sizeHint +128 (int (*)(...))QStyledItemDelegate::createEditor +136 (int (*)(...))QAbstractItemDelegate::destroyEditor +144 (int (*)(...))QStyledItemDelegate::setEditorData +152 (int (*)(...))QStyledItemDelegate::setModelData +160 (int (*)(...))QStyledItemDelegate::updateEditorGeometry +168 (int (*)(...))QStyledItemDelegate::editorEvent +176 (int (*)(...))QAbstractItemDelegate::helpEvent +184 (int (*)(...))QAbstractItemDelegate::paintingRoles +192 (int (*)(...))QStyledItemDelegate::displayText +200 (int (*)(...))QStyledItemDelegate::initStyleOption + +Class QStyledItemDelegate + size=16 align=8 + base size=16 base align=8 +QStyledItemDelegate (0x0x7f9a5166e8f0) 0 + vptr=((& QStyledItemDelegate::_ZTV19QStyledItemDelegate) + 16u) + QAbstractItemDelegate (0x0x7f9a5168e1a0) 0 + primary-for QStyledItemDelegate (0x0x7f9a5166e8f0) + QObject (0x0x7f9a5069eea0) 0 + primary-for QAbstractItemDelegate (0x0x7f9a5168e1a0) + +Class QStyleFactory + size=1 align=1 + base size=0 base align=1 +QStyleFactory (0x0x7f9a5046ef60) 0 empty + +Class QStylePainter + size=24 align=8 + base size=24 base align=8 +QStylePainter (0x0x7f9a5168e208) 0 + QPainter (0x0x7f9a50537a80) 0 + +Class QStylePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStylePlugin::QPrivateSignal (0x0x7f9a5055f720) 0 empty + +Vtable for QStylePlugin +QStylePlugin::_ZTV12QStylePlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QStylePlugin) +16 (int (*)(...))QStylePlugin::metaObject +24 (int (*)(...))QStylePlugin::qt_metacast +32 (int (*)(...))QStylePlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QStylePlugin + size=16 align=8 + base size=16 base align=8 +QStylePlugin (0x0x7f9a5168e3a8) 0 + vptr=((& QStylePlugin::_ZTV12QStylePlugin) + 16u) + QObject (0x0x7f9a5055f6c0) 0 + primary-for QStylePlugin (0x0x7f9a5168e3a8) + +Class QSystemTrayIcon::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSystemTrayIcon::QPrivateSignal (0x0x7f9a502cd600) 0 empty + +Vtable for QSystemTrayIcon +QSystemTrayIcon::_ZTV15QSystemTrayIcon: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSystemTrayIcon) +16 (int (*)(...))QSystemTrayIcon::metaObject +24 (int (*)(...))QSystemTrayIcon::qt_metacast +32 (int (*)(...))QSystemTrayIcon::qt_metacall +40 (int (*)(...))QSystemTrayIcon::~QSystemTrayIcon +48 (int (*)(...))QSystemTrayIcon::~QSystemTrayIcon +56 (int (*)(...))QSystemTrayIcon::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSystemTrayIcon + size=16 align=8 + base size=16 base align=8 +QSystemTrayIcon (0x0x7f9a516b1e38) 0 + vptr=((& QSystemTrayIcon::_ZTV15QSystemTrayIcon) + 16u) + QObject (0x0x7f9a502cd5a0) 0 + primary-for QSystemTrayIcon (0x0x7f9a516b1e38) + +Class QTableView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTableView::QPrivateSignal (0x0x7f9a502cdea0) 0 empty + +Vtable for QTableView +QTableView::_ZTV10QTableView: 106u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTableView) +16 (int (*)(...))QTableView::metaObject +24 (int (*)(...))QTableView::qt_metacast +32 (int (*)(...))QTableView::qt_metacall +40 (int (*)(...))QTableView::~QTableView +48 (int (*)(...))QTableView::~QTableView +56 (int (*)(...))QAbstractItemView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QTableView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QAbstractItemView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QAbstractItemView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTableView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractItemView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QAbstractItemView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QAbstractItemView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractItemView::viewportEvent +448 (int (*)(...))QTableView::scrollContentsBy +456 (int (*)(...))QTableView::viewportSizeHint +464 (int (*)(...))QTableView::setModel +472 (int (*)(...))QTableView::setSelectionModel +480 (int (*)(...))QAbstractItemView::keyboardSearch +488 (int (*)(...))QTableView::visualRect +496 (int (*)(...))QTableView::scrollTo +504 (int (*)(...))QTableView::indexAt +512 (int (*)(...))QTableView::sizeHintForRow +520 (int (*)(...))QTableView::sizeHintForColumn +528 (int (*)(...))QAbstractItemView::reset +536 (int (*)(...))QTableView::setRootIndex +544 (int (*)(...))QTableView::doItemsLayout +552 (int (*)(...))QAbstractItemView::selectAll +560 (int (*)(...))QAbstractItemView::dataChanged +568 (int (*)(...))QAbstractItemView::rowsInserted +576 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved +584 (int (*)(...))QTableView::selectionChanged +592 (int (*)(...))QTableView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QTableView::updateGeometries +624 (int (*)(...))QTableView::verticalScrollbarAction +632 (int (*)(...))QTableView::horizontalScrollbarAction +640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))QTableView::moveCursor +688 (int (*)(...))QTableView::horizontalOffset +696 (int (*)(...))QTableView::verticalOffset +704 (int (*)(...))QTableView::isIndexHidden +712 (int (*)(...))QTableView::setSelection +720 (int (*)(...))QTableView::visualRegionForSelection +728 (int (*)(...))QTableView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QAbstractItemView::startDrag +760 (int (*)(...))QTableView::viewOptions +768 (int (*)(...))-16 +776 (int (*)(...))(& _ZTI10QTableView) +784 (int (*)(...))QTableView::_ZThn16_N10QTableViewD1Ev +792 (int (*)(...))QTableView::_ZThn16_N10QTableViewD0Ev +800 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +808 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +816 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTableView + size=48 align=8 + base size=48 base align=8 +QTableView (0x0x7f9a5179b0d0) 0 + vptr=((& QTableView::_ZTV10QTableView) + 16u) + QAbstractItemView (0x0x7f9a5179b7b8) 0 + primary-for QTableView (0x0x7f9a5179b0d0) + QAbstractScrollArea (0x0x7f9a5162b6e8) 0 + primary-for QAbstractItemView (0x0x7f9a5179b7b8) + QFrame (0x0x7f9a5162b750) 0 + primary-for QAbstractScrollArea (0x0x7f9a5162b6e8) + QWidget (0x0x7f9a56262e70) 0 + primary-for QFrame (0x0x7f9a5162b750) + QObject (0x0x7f9a502cdd80) 0 + primary-for QWidget (0x0x7f9a56262e70) + QPaintDevice (0x0x7f9a502cdde0) 16 + vptr=((& QTableView::_ZTV10QTableView) + 784u) + +Class QTableWidgetSelectionRange + size=16 align=4 + base size=16 base align=4 +QTableWidgetSelectionRange (0x0x7f9a5031f4e0) 0 + +Vtable for QTableWidgetItem +QTableWidgetItem::_ZTV16QTableWidgetItem: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QTableWidgetItem) +16 (int (*)(...))QTableWidgetItem::~QTableWidgetItem +24 (int (*)(...))QTableWidgetItem::~QTableWidgetItem +32 (int (*)(...))QTableWidgetItem::clone +40 (int (*)(...))QTableWidgetItem::data +48 (int (*)(...))QTableWidgetItem::setData +56 (int (*)(...))QTableWidgetItem::operator< +64 (int (*)(...))QTableWidgetItem::read +72 (int (*)(...))QTableWidgetItem::write + +Class QTableWidgetItem + size=48 align=8 + base size=44 base align=8 +QTableWidgetItem (0x0x7f9a5031f540) 0 + vptr=((& QTableWidgetItem::_ZTV16QTableWidgetItem) + 16u) + +Class QTableWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTableWidget::QPrivateSignal (0x0x7f9a5033f300) 0 empty + +Vtable for QTableWidget +QTableWidget::_ZTV12QTableWidget: 110u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QTableWidget) +16 (int (*)(...))QTableWidget::metaObject +24 (int (*)(...))QTableWidget::qt_metacast +32 (int (*)(...))QTableWidget::qt_metacall +40 (int (*)(...))QTableWidget::~QTableWidget +48 (int (*)(...))QTableWidget::~QTableWidget +56 (int (*)(...))QTableWidget::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QTableView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QAbstractItemView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QAbstractItemView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTableView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractItemView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QAbstractItemView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QTableWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractItemView::viewportEvent +448 (int (*)(...))QTableView::scrollContentsBy +456 (int (*)(...))QTableView::viewportSizeHint +464 (int (*)(...))QTableWidget::setModel +472 (int (*)(...))QTableView::setSelectionModel +480 (int (*)(...))QAbstractItemView::keyboardSearch +488 (int (*)(...))QTableView::visualRect +496 (int (*)(...))QTableView::scrollTo +504 (int (*)(...))QTableView::indexAt +512 (int (*)(...))QTableView::sizeHintForRow +520 (int (*)(...))QTableView::sizeHintForColumn +528 (int (*)(...))QAbstractItemView::reset +536 (int (*)(...))QTableView::setRootIndex +544 (int (*)(...))QTableView::doItemsLayout +552 (int (*)(...))QAbstractItemView::selectAll +560 (int (*)(...))QAbstractItemView::dataChanged +568 (int (*)(...))QAbstractItemView::rowsInserted +576 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved +584 (int (*)(...))QTableView::selectionChanged +592 (int (*)(...))QTableView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QTableView::updateGeometries +624 (int (*)(...))QTableView::verticalScrollbarAction +632 (int (*)(...))QTableView::horizontalScrollbarAction +640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))QTableView::moveCursor +688 (int (*)(...))QTableView::horizontalOffset +696 (int (*)(...))QTableView::verticalOffset +704 (int (*)(...))QTableView::isIndexHidden +712 (int (*)(...))QTableView::setSelection +720 (int (*)(...))QTableView::visualRegionForSelection +728 (int (*)(...))QTableView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QAbstractItemView::startDrag +760 (int (*)(...))QTableView::viewOptions +768 (int (*)(...))QTableWidget::mimeTypes +776 (int (*)(...))QTableWidget::mimeData +784 (int (*)(...))QTableWidget::dropMimeData +792 (int (*)(...))QTableWidget::supportedDropActions +800 (int (*)(...))-16 +808 (int (*)(...))(& _ZTI12QTableWidget) +816 (int (*)(...))QTableWidget::_ZThn16_N12QTableWidgetD1Ev +824 (int (*)(...))QTableWidget::_ZThn16_N12QTableWidgetD0Ev +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +848 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +856 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +864 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +872 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTableWidget + size=48 align=8 + base size=48 base align=8 +QTableWidget (0x0x7f9a5162bf70) 0 + vptr=((& QTableWidget::_ZTV12QTableWidget) + 16u) + QTableView (0x0x7f9a5128a000) 0 + primary-for QTableWidget (0x0x7f9a5162bf70) + QAbstractItemView (0x0x7f9a5128a1a0) 0 + primary-for QTableView (0x0x7f9a5128a000) + QAbstractScrollArea (0x0x7f9a5128a208) 0 + primary-for QAbstractItemView (0x0x7f9a5128a1a0) + QFrame (0x0x7f9a5128a3a8) 0 + primary-for QAbstractScrollArea (0x0x7f9a5128a208) + QWidget (0x0x7f9a562844d0) 0 + primary-for QFrame (0x0x7f9a5128a3a8) + QObject (0x0x7f9a5031f960) 0 + primary-for QWidget (0x0x7f9a562844d0) + QPaintDevice (0x0x7f9a5033f2a0) 16 + vptr=((& QTableWidget::_ZTV12QTableWidget) + 816u) + +Class QTextBrowser::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextBrowser::QPrivateSignal (0x0x7f9a5038d0c0) 0 empty + +Vtable for QTextBrowser +QTextBrowser::_ZTV12QTextBrowser: 78u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QTextBrowser) +16 (int (*)(...))QTextBrowser::metaObject +24 (int (*)(...))QTextBrowser::qt_metacast +32 (int (*)(...))QTextBrowser::qt_metacall +40 (int (*)(...))QTextBrowser::~QTextBrowser +48 (int (*)(...))QTextBrowser::~QTextBrowser +56 (int (*)(...))QTextBrowser::event +64 (int (*)(...))QAbstractScrollArea::eventFilter +72 (int (*)(...))QTextEdit::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QTextBrowser::mousePressEvent +176 (int (*)(...))QTextBrowser::mouseReleaseEvent +184 (int (*)(...))QTextEdit::mouseDoubleClickEvent +192 (int (*)(...))QTextBrowser::mouseMoveEvent +200 (int (*)(...))QTextEdit::wheelEvent +208 (int (*)(...))QTextBrowser::keyPressEvent +216 (int (*)(...))QTextEdit::keyReleaseEvent +224 (int (*)(...))QTextEdit::focusInEvent +232 (int (*)(...))QTextBrowser::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTextBrowser::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QTextEdit::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QTextEdit::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QTextEdit::dragEnterEvent +320 (int (*)(...))QTextEdit::dragMoveEvent +328 (int (*)(...))QTextEdit::dragLeaveEvent +336 (int (*)(...))QTextEdit::dropEvent +344 (int (*)(...))QTextEdit::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QTextEdit::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QTextEdit::inputMethodEvent +416 (int (*)(...))QTextEdit::inputMethodQuery +424 (int (*)(...))QTextBrowser::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractScrollArea::viewportEvent +448 (int (*)(...))QTextEdit::scrollContentsBy +456 (int (*)(...))QAbstractScrollArea::viewportSizeHint +464 (int (*)(...))QTextBrowser::loadResource +472 (int (*)(...))QTextEdit::createMimeDataFromSelection +480 (int (*)(...))QTextEdit::canInsertFromMimeData +488 (int (*)(...))QTextEdit::insertFromMimeData +496 (int (*)(...))QTextEdit::doSetTextCursor +504 (int (*)(...))QTextBrowser::setSource +512 (int (*)(...))QTextBrowser::backward +520 (int (*)(...))QTextBrowser::forward +528 (int (*)(...))QTextBrowser::home +536 (int (*)(...))QTextBrowser::reload +544 (int (*)(...))-16 +552 (int (*)(...))(& _ZTI12QTextBrowser) +560 (int (*)(...))QTextBrowser::_ZThn16_N12QTextBrowserD1Ev +568 (int (*)(...))QTextBrowser::_ZThn16_N12QTextBrowserD0Ev +576 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +584 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +592 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +600 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +608 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +616 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTextBrowser + size=48 align=8 + base size=48 base align=8 +QTextBrowser (0x0x7f9a5128a410) 0 + vptr=((& QTextBrowser::_ZTV12QTextBrowser) + 16u) + QTextEdit (0x0x7f9a5128a478) 0 + primary-for QTextBrowser (0x0x7f9a5128a410) + QAbstractScrollArea (0x0x7f9a512ac1a0) 0 + primary-for QTextEdit (0x0x7f9a5128a478) + QFrame (0x0x7f9a512ac208) 0 + primary-for QAbstractScrollArea (0x0x7f9a512ac1a0) + QWidget (0x0x7f9a56284bd0) 0 + primary-for QFrame (0x0x7f9a512ac208) + QObject (0x0x7f9a5033f600) 0 + primary-for QWidget (0x0x7f9a56284bd0) + QPaintDevice (0x0x7f9a5033f660) 16 + vptr=((& QTextBrowser::_ZTV12QTextBrowser) + 560u) + +Class QToolBar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QToolBar::QPrivateSignal (0x0x7f9a5038d900) 0 empty + +Vtable for QToolBar +QToolBar::_ZTV8QToolBar: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QToolBar) +16 (int (*)(...))QToolBar::metaObject +24 (int (*)(...))QToolBar::qt_metacast +32 (int (*)(...))QToolBar::qt_metacall +40 (int (*)(...))QToolBar::~QToolBar +48 (int (*)(...))QToolBar::~QToolBar +56 (int (*)(...))QToolBar::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QToolBar::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QToolBar::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QToolBar::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI8QToolBar) +448 (int (*)(...))QToolBar::_ZThn16_N8QToolBarD1Ev +456 (int (*)(...))QToolBar::_ZThn16_N8QToolBarD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QToolBar + size=48 align=8 + base size=48 base align=8 +QToolBar (0x0x7f9a512ac548) 0 + vptr=((& QToolBar::_ZTV8QToolBar) + 16u) + QWidget (0x0x7f9a56284ee0) 0 + primary-for QToolBar (0x0x7f9a512ac548) + QObject (0x0x7f9a5038d120) 0 + primary-for QWidget (0x0x7f9a56284ee0) + QPaintDevice (0x0x7f9a5038d8a0) 16 + vptr=((& QToolBar::_ZTV8QToolBar) + 448u) + +Class QToolBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QToolBox::QPrivateSignal (0x0x7f9a501aed80) 0 empty + +Vtable for QToolBox +QToolBox::_ZTV8QToolBox: 66u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QToolBox) +16 (int (*)(...))QToolBox::metaObject +24 (int (*)(...))QToolBox::qt_metacast +32 (int (*)(...))QToolBox::qt_metacall +40 (int (*)(...))QToolBox::~QToolBox +48 (int (*)(...))QToolBox::~QToolBox +56 (int (*)(...))QToolBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QFrame::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QFrame::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QToolBox::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QToolBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QToolBox::itemInserted +440 (int (*)(...))QToolBox::itemRemoved +448 (int (*)(...))-16 +456 (int (*)(...))(& _ZTI8QToolBox) +464 (int (*)(...))QToolBox::_ZThn16_N8QToolBoxD1Ev +472 (int (*)(...))QToolBox::_ZThn16_N8QToolBoxD0Ev +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QToolBox + size=48 align=8 + base size=48 base align=8 +QToolBox (0x0x7f9a50e03548) 0 + vptr=((& QToolBox::_ZTV8QToolBox) + 16u) + QFrame (0x0x7f9a50e035b0) 0 + primary-for QToolBox (0x0x7f9a50e03548) + QWidget (0x0x7f9a55f47150) 0 + primary-for QFrame (0x0x7f9a50e035b0) + QObject (0x0x7f9a501aec60) 0 + primary-for QWidget (0x0x7f9a55f47150) + QPaintDevice (0x0x7f9a501aecc0) 16 + vptr=((& QToolBox::_ZTV8QToolBox) + 464u) + +Class QToolButton::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QToolButton::QPrivateSignal (0x0x7f9a4fdcd9c0) 0 empty + +Vtable for QToolButton +QToolButton::_ZTV11QToolButton: 67u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QToolButton) +16 (int (*)(...))QToolButton::metaObject +24 (int (*)(...))QToolButton::qt_metacast +32 (int (*)(...))QToolButton::qt_metacall +40 (int (*)(...))QToolButton::~QToolButton +48 (int (*)(...))QToolButton::~QToolButton +56 (int (*)(...))QToolButton::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QToolButton::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QToolButton::sizeHint +136 (int (*)(...))QToolButton::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QToolButton::mousePressEvent +176 (int (*)(...))QToolButton::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractButton::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QAbstractButton::keyPressEvent +216 (int (*)(...))QAbstractButton::keyReleaseEvent +224 (int (*)(...))QAbstractButton::focusInEvent +232 (int (*)(...))QAbstractButton::focusOutEvent +240 (int (*)(...))QToolButton::enterEvent +248 (int (*)(...))QToolButton::leaveEvent +256 (int (*)(...))QToolButton::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QToolButton::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QToolButton::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QToolButton::hitButton +440 (int (*)(...))QAbstractButton::checkStateSet +448 (int (*)(...))QToolButton::nextCheckState +456 (int (*)(...))-16 +464 (int (*)(...))(& _ZTI11QToolButton) +472 (int (*)(...))QToolButton::_ZThn16_N11QToolButtonD1Ev +480 (int (*)(...))QToolButton::_ZThn16_N11QToolButtonD0Ev +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QToolButton + size=48 align=8 + base size=48 base align=8 +QToolButton (0x0x7f9a50e03958) 0 + vptr=((& QToolButton::_ZTV11QToolButton) + 16u) + QAbstractButton (0x0x7f9a50e039c0) 0 + primary-for QToolButton (0x0x7f9a50e03958) + QWidget (0x0x7f9a55f47620) 0 + primary-for QAbstractButton (0x0x7f9a50e039c0) + QObject (0x0x7f9a501aef60) 0 + primary-for QWidget (0x0x7f9a55f47620) + QPaintDevice (0x0x7f9a4fdcd000) 16 + vptr=((& QToolButton::_ZTV11QToolButton) + 472u) + +Class QToolTip + size=1 align=1 + base size=0 base align=1 +QToolTip (0x0x7f9a4fdcda20) 0 empty + +Class QTreeView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTreeView::QPrivateSignal (0x0x7f9a4fdcdd20) 0 empty + +Vtable for QTreeView +QTreeView::_ZTV9QTreeView: 108u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTreeView) +16 (int (*)(...))QTreeView::metaObject +24 (int (*)(...))QTreeView::qt_metacast +32 (int (*)(...))QTreeView::qt_metacall +40 (int (*)(...))QTreeView::~QTreeView +48 (int (*)(...))QTreeView::~QTreeView +56 (int (*)(...))QAbstractItemView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QTreeView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QTreeView::mousePressEvent +176 (int (*)(...))QTreeView::mouseReleaseEvent +184 (int (*)(...))QTreeView::mouseDoubleClickEvent +192 (int (*)(...))QTreeView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QTreeView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTreeView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractItemView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QTreeView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QAbstractItemView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QTreeView::viewportEvent +448 (int (*)(...))QTreeView::scrollContentsBy +456 (int (*)(...))QTreeView::viewportSizeHint +464 (int (*)(...))QTreeView::setModel +472 (int (*)(...))QTreeView::setSelectionModel +480 (int (*)(...))QTreeView::keyboardSearch +488 (int (*)(...))QTreeView::visualRect +496 (int (*)(...))QTreeView::scrollTo +504 (int (*)(...))QTreeView::indexAt +512 (int (*)(...))QAbstractItemView::sizeHintForRow +520 (int (*)(...))QTreeView::sizeHintForColumn +528 (int (*)(...))QTreeView::reset +536 (int (*)(...))QTreeView::setRootIndex +544 (int (*)(...))QTreeView::doItemsLayout +552 (int (*)(...))QTreeView::selectAll +560 (int (*)(...))QTreeView::dataChanged +568 (int (*)(...))QTreeView::rowsInserted +576 (int (*)(...))QTreeView::rowsAboutToBeRemoved +584 (int (*)(...))QTreeView::selectionChanged +592 (int (*)(...))QTreeView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QTreeView::updateGeometries +624 (int (*)(...))QAbstractItemView::verticalScrollbarAction +632 (int (*)(...))QTreeView::horizontalScrollbarAction +640 (int (*)(...))QTreeView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))QTreeView::moveCursor +688 (int (*)(...))QTreeView::horizontalOffset +696 (int (*)(...))QTreeView::verticalOffset +704 (int (*)(...))QTreeView::isIndexHidden +712 (int (*)(...))QTreeView::setSelection +720 (int (*)(...))QTreeView::visualRegionForSelection +728 (int (*)(...))QTreeView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QAbstractItemView::startDrag +760 (int (*)(...))QAbstractItemView::viewOptions +768 (int (*)(...))QTreeView::drawRow +776 (int (*)(...))QTreeView::drawBranches +784 (int (*)(...))-16 +792 (int (*)(...))(& _ZTI9QTreeView) +800 (int (*)(...))QTreeView::_ZThn16_N9QTreeViewD1Ev +808 (int (*)(...))QTreeView::_ZThn16_N9QTreeViewD0Ev +816 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +848 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +856 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTreeView + size=48 align=8 + base size=48 base align=8 +QTreeView (0x0x7f9a50e1f548) 0 + vptr=((& QTreeView::_ZTV9QTreeView) + 16u) + QAbstractItemView (0x0x7f9a50e1f5b0) 0 + primary-for QTreeView (0x0x7f9a50e1f548) + QAbstractScrollArea (0x0x7f9a50f2af70) 0 + primary-for QAbstractItemView (0x0x7f9a50e1f5b0) + QFrame (0x0x7f9a50f54340) 0 + primary-for QAbstractScrollArea (0x0x7f9a50f2af70) + QWidget (0x0x7f9a55f47cb0) 0 + primary-for QFrame (0x0x7f9a50f54340) + QObject (0x0x7f9a4fdcdae0) 0 + primary-for QWidget (0x0x7f9a55f47cb0) + QPaintDevice (0x0x7f9a4fdcdcc0) 16 + vptr=((& QTreeView::_ZTV9QTreeView) + 800u) + +Class QTreeWidgetItemIterator + size=24 align=8 + base size=20 base align=8 +QTreeWidgetItemIterator (0x0x7f9a4ff754e0) 0 + +Vtable for QTreeWidgetItem +QTreeWidgetItem::_ZTV15QTreeWidgetItem: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QTreeWidgetItem) +16 (int (*)(...))QTreeWidgetItem::~QTreeWidgetItem +24 (int (*)(...))QTreeWidgetItem::~QTreeWidgetItem +32 (int (*)(...))QTreeWidgetItem::clone +40 (int (*)(...))QTreeWidgetItem::data +48 (int (*)(...))QTreeWidgetItem::setData +56 (int (*)(...))QTreeWidgetItem::operator< +64 (int (*)(...))QTreeWidgetItem::read +72 (int (*)(...))QTreeWidgetItem::write + +Class QTreeWidgetItem + size=64 align=8 + base size=60 base align=8 +QTreeWidgetItem (0x0x7f9a4fd23f00) 0 + vptr=((& QTreeWidgetItem::_ZTV15QTreeWidgetItem) + 16u) + +Class QTreeWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTreeWidget::QPrivateSignal (0x0x7f9a4f9f19c0) 0 empty + +Vtable for QTreeWidget +QTreeWidget::_ZTV11QTreeWidget: 112u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTreeWidget) +16 (int (*)(...))QTreeWidget::metaObject +24 (int (*)(...))QTreeWidget::qt_metacast +32 (int (*)(...))QTreeWidget::qt_metacall +40 (int (*)(...))QTreeWidget::~QTreeWidget +48 (int (*)(...))QTreeWidget::~QTreeWidget +56 (int (*)(...))QTreeWidget::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QTreeView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QTreeView::mousePressEvent +176 (int (*)(...))QTreeView::mouseReleaseEvent +184 (int (*)(...))QTreeView::mouseDoubleClickEvent +192 (int (*)(...))QTreeView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QTreeView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTreeView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractItemView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QTreeView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QTreeWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QTreeView::viewportEvent +448 (int (*)(...))QTreeView::scrollContentsBy +456 (int (*)(...))QTreeView::viewportSizeHint +464 (int (*)(...))QTreeWidget::setModel +472 (int (*)(...))QTreeWidget::setSelectionModel +480 (int (*)(...))QTreeView::keyboardSearch +488 (int (*)(...))QTreeView::visualRect +496 (int (*)(...))QTreeView::scrollTo +504 (int (*)(...))QTreeView::indexAt +512 (int (*)(...))QAbstractItemView::sizeHintForRow +520 (int (*)(...))QTreeView::sizeHintForColumn +528 (int (*)(...))QTreeView::reset +536 (int (*)(...))QTreeView::setRootIndex +544 (int (*)(...))QTreeView::doItemsLayout +552 (int (*)(...))QTreeView::selectAll +560 (int (*)(...))QTreeView::dataChanged +568 (int (*)(...))QTreeView::rowsInserted +576 (int (*)(...))QTreeView::rowsAboutToBeRemoved +584 (int (*)(...))QTreeView::selectionChanged +592 (int (*)(...))QTreeView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QTreeView::updateGeometries +624 (int (*)(...))QAbstractItemView::verticalScrollbarAction +632 (int (*)(...))QTreeView::horizontalScrollbarAction +640 (int (*)(...))QTreeView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))QTreeView::moveCursor +688 (int (*)(...))QTreeView::horizontalOffset +696 (int (*)(...))QTreeView::verticalOffset +704 (int (*)(...))QTreeView::isIndexHidden +712 (int (*)(...))QTreeView::setSelection +720 (int (*)(...))QTreeView::visualRegionForSelection +728 (int (*)(...))QTreeView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QAbstractItemView::startDrag +760 (int (*)(...))QAbstractItemView::viewOptions +768 (int (*)(...))QTreeView::drawRow +776 (int (*)(...))QTreeView::drawBranches +784 (int (*)(...))QTreeWidget::mimeTypes +792 (int (*)(...))QTreeWidget::mimeData +800 (int (*)(...))QTreeWidget::dropMimeData +808 (int (*)(...))QTreeWidget::supportedDropActions +816 (int (*)(...))-16 +824 (int (*)(...))(& _ZTI11QTreeWidget) +832 (int (*)(...))QTreeWidget::_ZThn16_N11QTreeWidgetD1Ev +840 (int (*)(...))QTreeWidget::_ZThn16_N11QTreeWidgetD0Ev +848 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +856 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +864 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +872 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +880 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +888 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTreeWidget + size=48 align=8 + base size=48 base align=8 +QTreeWidget (0x0x7f9a50f54e38) 0 + vptr=((& QTreeWidget::_ZTV11QTreeWidget) + 16u) + QTreeView (0x0x7f9a50f54f08) 0 + primary-for QTreeWidget (0x0x7f9a50f54e38) + QAbstractItemView (0x0x7f9a50c35d68) 0 + primary-for QTreeView (0x0x7f9a50f54f08) + QAbstractScrollArea (0x0x7f9a50c35dd0) 0 + primary-for QAbstractItemView (0x0x7f9a50c35d68) + QFrame (0x0x7f9a50c35f70) 0 + primary-for QAbstractScrollArea (0x0x7f9a50c35dd0) + QWidget (0x0x7f9a55cbe150) 0 + primary-for QFrame (0x0x7f9a50c35f70) + QObject (0x0x7f9a4f9f18a0) 0 + primary-for QWidget (0x0x7f9a55cbe150) + QPaintDevice (0x0x7f9a4f9f1900) 16 + vptr=((& QTreeWidget::_ZTV11QTreeWidget) + 832u) + +Class QUndoGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QUndoGroup::QPrivateSignal (0x0x7f9a4fa1e780) 0 empty + +Vtable for QUndoGroup +QUndoGroup::_ZTV10QUndoGroup: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QUndoGroup) +16 (int (*)(...))QUndoGroup::metaObject +24 (int (*)(...))QUndoGroup::qt_metacast +32 (int (*)(...))QUndoGroup::qt_metacall +40 (int (*)(...))QUndoGroup::~QUndoGroup +48 (int (*)(...))QUndoGroup::~QUndoGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QUndoGroup + size=16 align=8 + base size=16 base align=8 +QUndoGroup (0x0x7f9a50a0b1a0) 0 + vptr=((& QUndoGroup::_ZTV10QUndoGroup) + 16u) + QObject (0x0x7f9a4fa1e720) 0 + primary-for QUndoGroup (0x0x7f9a50a0b1a0) + +Vtable for QUndoCommand +QUndoCommand::_ZTV12QUndoCommand: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QUndoCommand) +16 (int (*)(...))QUndoCommand::~QUndoCommand +24 (int (*)(...))QUndoCommand::~QUndoCommand +32 (int (*)(...))QUndoCommand::undo +40 (int (*)(...))QUndoCommand::redo +48 (int (*)(...))QUndoCommand::id +56 (int (*)(...))QUndoCommand::mergeWith + +Class QUndoCommand + size=16 align=8 + base size=16 base align=8 +QUndoCommand (0x0x7f9a4fa1ee40) 0 + vptr=((& QUndoCommand::_ZTV12QUndoCommand) + 16u) + +Class QUndoStack::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QUndoStack::QPrivateSignal (0x0x7f9a4fa453c0) 0 empty + +Vtable for QUndoStack +QUndoStack::_ZTV10QUndoStack: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QUndoStack) +16 (int (*)(...))QUndoStack::metaObject +24 (int (*)(...))QUndoStack::qt_metacast +32 (int (*)(...))QUndoStack::qt_metacall +40 (int (*)(...))QUndoStack::~QUndoStack +48 (int (*)(...))QUndoStack::~QUndoStack +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QUndoStack + size=16 align=8 + base size=16 base align=8 +QUndoStack (0x0x7f9a50a0b208) 0 + vptr=((& QUndoStack::_ZTV10QUndoStack) + 16u) + QObject (0x0x7f9a4fa1eea0) 0 + primary-for QUndoStack (0x0x7f9a50a0b208) + +Class QUndoView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QUndoView::QPrivateSignal (0x0x7f9a4fa459c0) 0 empty + +Vtable for QUndoView +QUndoView::_ZTV9QUndoView: 106u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QUndoView) +16 (int (*)(...))QUndoView::metaObject +24 (int (*)(...))QUndoView::qt_metacast +32 (int (*)(...))QUndoView::qt_metacall +40 (int (*)(...))QUndoView::~QUndoView +48 (int (*)(...))QUndoView::~QUndoView +56 (int (*)(...))QListView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QListView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QListView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QListView::mouseMoveEvent +200 (int (*)(...))QListView::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QListView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QListView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QListView::dragMoveEvent +328 (int (*)(...))QListView::dragLeaveEvent +336 (int (*)(...))QListView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractItemView::viewportEvent +448 (int (*)(...))QListView::scrollContentsBy +456 (int (*)(...))QListView::viewportSizeHint +464 (int (*)(...))QAbstractItemView::setModel +472 (int (*)(...))QAbstractItemView::setSelectionModel +480 (int (*)(...))QAbstractItemView::keyboardSearch +488 (int (*)(...))QListView::visualRect +496 (int (*)(...))QListView::scrollTo +504 (int (*)(...))QListView::indexAt +512 (int (*)(...))QAbstractItemView::sizeHintForRow +520 (int (*)(...))QAbstractItemView::sizeHintForColumn +528 (int (*)(...))QListView::reset +536 (int (*)(...))QListView::setRootIndex +544 (int (*)(...))QListView::doItemsLayout +552 (int (*)(...))QAbstractItemView::selectAll +560 (int (*)(...))QListView::dataChanged +568 (int (*)(...))QListView::rowsInserted +576 (int (*)(...))QListView::rowsAboutToBeRemoved +584 (int (*)(...))QListView::selectionChanged +592 (int (*)(...))QListView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QListView::updateGeometries +624 (int (*)(...))QAbstractItemView::verticalScrollbarAction +632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction +640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))QListView::moveCursor +688 (int (*)(...))QListView::horizontalOffset +696 (int (*)(...))QListView::verticalOffset +704 (int (*)(...))QListView::isIndexHidden +712 (int (*)(...))QListView::setSelection +720 (int (*)(...))QListView::visualRegionForSelection +728 (int (*)(...))QListView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QListView::startDrag +760 (int (*)(...))QListView::viewOptions +768 (int (*)(...))-16 +776 (int (*)(...))(& _ZTI9QUndoView) +784 (int (*)(...))QUndoView::_ZThn16_N9QUndoViewD1Ev +792 (int (*)(...))QUndoView::_ZThn16_N9QUndoViewD0Ev +800 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +808 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +816 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QUndoView + size=48 align=8 + base size=48 base align=8 +QUndoView (0x0x7f9a50a0b270) 0 + vptr=((& QUndoView::_ZTV9QUndoView) + 16u) + QListView (0x0x7f9a50a0b2d8) 0 + primary-for QUndoView (0x0x7f9a50a0b270) + QAbstractItemView (0x0x7f9a50a0b410) 0 + primary-for QListView (0x0x7f9a50a0b2d8) + QAbstractScrollArea (0x0x7f9a50a0b478) 0 + primary-for QAbstractItemView (0x0x7f9a50a0b410) + QFrame (0x0x7f9a50a0b9c0) 0 + primary-for QAbstractScrollArea (0x0x7f9a50a0b478) + QWidget (0x0x7f9a55ccfa10) 0 + primary-for QFrame (0x0x7f9a50a0b9c0) + QObject (0x0x7f9a4fa45420) 0 + primary-for QWidget (0x0x7f9a55ccfa10) + QPaintDevice (0x0x7f9a4fa45960) 16 + vptr=((& QUndoView::_ZTV9QUndoView) + 784u) + +Class QWhatsThis + size=1 align=1 + base size=0 base align=1 +QWhatsThis (0x0x7f9a4fa45a80) 0 empty + +Class QWidgetAction::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWidgetAction::QPrivateSignal (0x0x7f9a4fa45cc0) 0 empty + +Vtable for QWidgetAction +QWidgetAction::_ZTV13QWidgetAction: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QWidgetAction) +16 (int (*)(...))QWidgetAction::metaObject +24 (int (*)(...))QWidgetAction::qt_metacast +32 (int (*)(...))QWidgetAction::qt_metacall +40 (int (*)(...))QWidgetAction::~QWidgetAction +48 (int (*)(...))QWidgetAction::~QWidgetAction +56 (int (*)(...))QWidgetAction::event +64 (int (*)(...))QWidgetAction::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidgetAction::createWidget +120 (int (*)(...))QWidgetAction::deleteWidget + +Class QWidgetAction + size=16 align=8 + base size=16 base align=8 +QWidgetAction (0x0x7f9a50a0ba28) 0 + vptr=((& QWidgetAction::_ZTV13QWidgetAction) + 16u) + QAction (0x0x7f9a50a0be38) 0 + primary-for QWidgetAction (0x0x7f9a50a0ba28) + QObject (0x0x7f9a4fa45c60) 0 + primary-for QAction (0x0x7f9a50a0be38) + +Class QWizard::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWizard::QPrivateSignal (0x0x7f9a4fa677e0) 0 empty + +Vtable for QWizard +QWizard::_ZTV7QWizard: 73u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QWizard) +16 (int (*)(...))QWizard::metaObject +24 (int (*)(...))QWizard::qt_metacast +32 (int (*)(...))QWizard::qt_metacall +40 (int (*)(...))QWizard::~QWizard +48 (int (*)(...))QWizard::~QWizard +56 (int (*)(...))QWizard::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWizard::setVisible +128 (int (*)(...))QWizard::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWizard::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWizard::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QWizard::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))QWizard::validateCurrentPage +480 (int (*)(...))QWizard::nextId +488 (int (*)(...))QWizard::initializePage +496 (int (*)(...))QWizard::cleanupPage +504 (int (*)(...))-16 +512 (int (*)(...))(& _ZTI7QWizard) +520 (int (*)(...))QWizard::_ZThn16_N7QWizardD1Ev +528 (int (*)(...))QWizard::_ZThn16_N7QWizardD0Ev +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +568 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +576 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QWizard + size=48 align=8 + base size=48 base align=8 +QWizard (0x0x7f9a50a0bea0) 0 + vptr=((& QWizard::_ZTV7QWizard) + 16u) + QDialog (0x0x7f9a50a75f08) 0 + primary-for QWizard (0x0x7f9a50a0bea0) + QWidget (0x0x7f9a55ce2150) 0 + primary-for QDialog (0x0x7f9a50a75f08) + QObject (0x0x7f9a4fa676c0) 0 + primary-for QWidget (0x0x7f9a55ce2150) + QPaintDevice (0x0x7f9a4fa67720) 16 + vptr=((& QWizard::_ZTV7QWizard) + 520u) + +Class QWizardPage::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWizardPage::QPrivateSignal (0x0x7f9a4fa989c0) 0 empty + +Vtable for QWizardPage +QWizardPage::_ZTV11QWizardPage: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QWizardPage) +16 (int (*)(...))QWizardPage::metaObject +24 (int (*)(...))QWizardPage::qt_metacast +32 (int (*)(...))QWizardPage::qt_metacall +40 (int (*)(...))QWizardPage::~QWizardPage +48 (int (*)(...))QWizardPage::~QWizardPage +56 (int (*)(...))QWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QWizardPage::initializePage +440 (int (*)(...))QWizardPage::cleanupPage +448 (int (*)(...))QWizardPage::validatePage +456 (int (*)(...))QWizardPage::isComplete +464 (int (*)(...))QWizardPage::nextId +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI11QWizardPage) +488 (int (*)(...))QWizardPage::_ZThn16_N11QWizardPageD1Ev +496 (int (*)(...))QWizardPage::_ZThn16_N11QWizardPageD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QWizardPage + size=48 align=8 + base size=48 base align=8 +QWizardPage (0x0x7f9a50a9b3a8) 0 + vptr=((& QWizardPage::_ZTV11QWizardPage) + 16u) + QWidget (0x0x7f9a55c4f000) 0 + primary-for QWizardPage (0x0x7f9a50a9b3a8) + QObject (0x0x7f9a4fa98660) 0 + primary-for QWidget (0x0x7f9a55c4f000) + QPaintDevice (0x0x7f9a4fa986c0) 16 + vptr=((& QWizardPage::_ZTV11QWizardPage) + 488u) + +Class QAbstractPrintDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractPrintDialog::QPrivateSignal (0x0x7f9a4fa98cc0) 0 empty + +Vtable for QAbstractPrintDialog +QAbstractPrintDialog::_ZTV20QAbstractPrintDialog: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QAbstractPrintDialog) +16 (int (*)(...))QAbstractPrintDialog::metaObject +24 (int (*)(...))QAbstractPrintDialog::qt_metacast +32 (int (*)(...))QAbstractPrintDialog::qt_metacall +40 0u +48 0u +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))__cxa_pure_virtual +448 (int (*)(...))QDialog::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI20QAbstractPrintDialog) +488 0u +496 0u +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QAbstractPrintDialog + size=48 align=8 + base size=48 base align=8 +QAbstractPrintDialog (0x0x7f9a50ab7d00) 0 + vptr=((& QAbstractPrintDialog::_ZTV20QAbstractPrintDialog) + 16u) + QDialog (0x0x7f9a50ade548) 0 + primary-for QAbstractPrintDialog (0x0x7f9a50ab7d00) + QWidget (0x0x7f9a55c4f310) 0 + primary-for QDialog (0x0x7f9a50ade548) + QObject (0x0x7f9a4fa98a20) 0 + primary-for QWidget (0x0x7f9a55c4f310) + QPaintDevice (0x0x7f9a4fa98c60) 16 + vptr=((& QAbstractPrintDialog::_ZTV20QAbstractPrintDialog) + 488u) + +Class QPageSetupDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPageSetupDialog::QPrivateSignal (0x0x7f9a4fb53d20) 0 empty + +Vtable for QPageSetupDialog +QPageSetupDialog::_ZTV16QPageSetupDialog: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QPageSetupDialog) +16 (int (*)(...))QPageSetupDialog::metaObject +24 (int (*)(...))QPageSetupDialog::qt_metacast +32 (int (*)(...))QPageSetupDialog::qt_metacall +40 (int (*)(...))QPageSetupDialog::~QPageSetupDialog +48 (int (*)(...))QPageSetupDialog::~QPageSetupDialog +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QPageSetupDialog::exec +448 (int (*)(...))QPageSetupDialog::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI16QPageSetupDialog) +488 (int (*)(...))QPageSetupDialog::_ZThn16_N16QPageSetupDialogD1Ev +496 (int (*)(...))QPageSetupDialog::_ZThn16_N16QPageSetupDialogD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QPageSetupDialog + size=48 align=8 + base size=48 base align=8 +QPageSetupDialog (0x0x7f9a50b07068) 0 + vptr=((& QPageSetupDialog::_ZTV16QPageSetupDialog) + 16u) + QDialog (0x0x7f9a50b28a28) 0 + primary-for QPageSetupDialog (0x0x7f9a50b07068) + QWidget (0x0x7f9a558e27e0) 0 + primary-for QDialog (0x0x7f9a50b28a28) + QObject (0x0x7f9a4fb53c00) 0 + primary-for QWidget (0x0x7f9a558e27e0) + QPaintDevice (0x0x7f9a4fb53c60) 16 + vptr=((& QPageSetupDialog::_ZTV16QPageSetupDialog) + 488u) + +Class QPrintDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPrintDialog::QPrivateSignal (0x0x7f9a4fbc3ae0) 0 empty + +Vtable for QPrintDialog +QPrintDialog::_ZTV12QPrintDialog: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QPrintDialog) +16 (int (*)(...))QPrintDialog::metaObject +24 (int (*)(...))QPrintDialog::qt_metacast +32 (int (*)(...))QPrintDialog::qt_metacall +40 (int (*)(...))QPrintDialog::~QPrintDialog +48 (int (*)(...))QPrintDialog::~QPrintDialog +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QPrintDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QPrintDialog::exec +448 (int (*)(...))QPrintDialog::done +456 (int (*)(...))QPrintDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI12QPrintDialog) +488 (int (*)(...))QPrintDialog::_ZThn16_N12QPrintDialogD1Ev +496 (int (*)(...))QPrintDialog::_ZThn16_N12QPrintDialogD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QPrintDialog + size=48 align=8 + base size=48 base align=8 +QPrintDialog (0x0x7f9a50b28a90) 0 + vptr=((& QPrintDialog::_ZTV12QPrintDialog) + 16u) + QAbstractPrintDialog (0x0x7f9a50b28af8) 0 + primary-for QPrintDialog (0x0x7f9a50b28a90) + QDialog (0x0x7f9a50b28b60) 0 + primary-for QAbstractPrintDialog (0x0x7f9a50b28af8) + QWidget (0x0x7f9a558e2bd0) 0 + primary-for QDialog (0x0x7f9a50b28b60) + QObject (0x0x7f9a4fb53f00) 0 + primary-for QWidget (0x0x7f9a558e2bd0) + QPaintDevice (0x0x7f9a4fb53f60) 16 + vptr=((& QPrintDialog::_ZTV12QPrintDialog) + 488u) + +Vtable for QPrinter +QPrinter::_ZTV8QPrinter: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QPrinter) +16 (int (*)(...))QPrinter::~QPrinter +24 (int (*)(...))QPrinter::~QPrinter +32 (int (*)(...))QPrinter::devType +40 (int (*)(...))QPrinter::paintEngine +48 (int (*)(...))QPrinter::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))QPrinter::newPage +88 (int (*)(...))QPrinter::setPageSize +96 (int (*)(...))QPrinter::setPageSizeMM +104 (int (*)(...))QPrinter::setMargins + +Class QPrinter + size=40 align=8 + base size=40 base align=8 +QPrinter (0x0x7f9a50b489c0) 0 + vptr=((& QPrinter::_ZTV8QPrinter) + 16u) + QPagedPaintDevice (0x0x7f9a50b48a28) 0 + primary-for QPrinter (0x0x7f9a50b489c0) + QPaintDevice (0x0x7f9a4fbc3b40) 0 + primary-for QPagedPaintDevice (0x0x7f9a50b48a28) + +Vtable for QPrintEngine +QPrintEngine::_ZTV12QPrintEngine: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QPrintEngine) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual + +Class QPrintEngine + size=8 align=8 + base size=8 base align=8 +QPrintEngine (0x0x7f9a4f7f4de0) 0 nearly-empty + vptr=((& QPrintEngine::_ZTV12QPrintEngine) + 16u) + +Class QPrinterInfo + size=8 align=8 + base size=8 base align=8 +QPrinterInfo (0x0x7f9a4f7f4e40) 0 + +Class QPrintPreviewDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPrintPreviewDialog::QPrivateSignal (0x0x7f9a4f8bf660) 0 empty + +Vtable for QPrintPreviewDialog +QPrintPreviewDialog::_ZTV19QPrintPreviewDialog: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QPrintPreviewDialog) +16 (int (*)(...))QPrintPreviewDialog::metaObject +24 (int (*)(...))QPrintPreviewDialog::qt_metacast +32 (int (*)(...))QPrintPreviewDialog::qt_metacall +40 (int (*)(...))QPrintPreviewDialog::~QPrintPreviewDialog +48 (int (*)(...))QPrintPreviewDialog::~QPrintPreviewDialog +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QPrintPreviewDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QPrintPreviewDialog::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI19QPrintPreviewDialog) +488 (int (*)(...))QPrintPreviewDialog::_ZThn16_N19QPrintPreviewDialogD1Ev +496 (int (*)(...))QPrintPreviewDialog::_ZThn16_N19QPrintPreviewDialogD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QPrintPreviewDialog + size=48 align=8 + base size=48 base align=8 +QPrintPreviewDialog (0x0x7f9a50b6e5b0) 0 + vptr=((& QPrintPreviewDialog::_ZTV19QPrintPreviewDialog) + 16u) + QDialog (0x0x7f9a50b6e618) 0 + primary-for QPrintPreviewDialog (0x0x7f9a50b6e5b0) + QWidget (0x0x7f9a554d01c0) 0 + primary-for QDialog (0x0x7f9a50b6e618) + QObject (0x0x7f9a4f81a120) 0 + primary-for QWidget (0x0x7f9a554d01c0) + QPaintDevice (0x0x7f9a4f81a180) 16 + vptr=((& QPrintPreviewDialog::_ZTV19QPrintPreviewDialog) + 488u) + +Class QPrintPreviewWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPrintPreviewWidget::QPrivateSignal (0x0x7f9a4f8bf960) 0 empty + +Vtable for QPrintPreviewWidget +QPrintPreviewWidget::_ZTV19QPrintPreviewWidget: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QPrintPreviewWidget) +16 (int (*)(...))QPrintPreviewWidget::metaObject +24 (int (*)(...))QPrintPreviewWidget::qt_metacast +32 (int (*)(...))QPrintPreviewWidget::qt_metacall +40 (int (*)(...))QPrintPreviewWidget::~QPrintPreviewWidget +48 (int (*)(...))QPrintPreviewWidget::~QPrintPreviewWidget +56 (int (*)(...))QWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QPrintPreviewWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI19QPrintPreviewWidget) +448 (int (*)(...))QPrintPreviewWidget::_ZThn16_N19QPrintPreviewWidgetD1Ev +456 (int (*)(...))QPrintPreviewWidget::_ZThn16_N19QPrintPreviewWidgetD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QPrintPreviewWidget + size=48 align=8 + base size=48 base align=8 +QPrintPreviewWidget (0x0x7f9a50b6e7b8) 0 + vptr=((& QPrintPreviewWidget::_ZTV19QPrintPreviewWidget) + 16u) + QWidget (0x0x7f9a554d05b0) 0 + primary-for QPrintPreviewWidget (0x0x7f9a50b6e7b8) + QObject (0x0x7f9a4f8bf6c0) 0 + primary-for QWidget (0x0x7f9a554d05b0) + QPaintDevice (0x0x7f9a4f8bf780) 16 + vptr=((& QPrintPreviewWidget::_ZTV19QPrintPreviewWidget) + 448u) + diff --git a/tests/auto/bic/data/QtSql.5.12.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtSql.5.12.0.linux-gcc-amd64.txt new file mode 100644 index 0000000000..18dd2246fa --- /dev/null +++ b/tests/auto/bic/data/QtSql.5.12.0.linux-gcc-amd64.txt @@ -0,0 +1,5034 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7efcad586360) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7efcad5cfae0) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7efcad5cfd20) 0 empty + +Class std::__do_is_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_default_constructible_impl (0x0x7efcad5cff60) 0 empty + +Class std::__do_is_static_castable_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_static_castable_impl (0x0x7efcab17a1e0) 0 empty + +Class std::__do_is_direct_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_direct_constructible_impl (0x0x7efcab17a360) 0 empty + +Class std::__do_is_nary_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nary_constructible_impl (0x0x7efcab17a720) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7efcab208ea0) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7efcab208f60) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7efcab235300) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7efcab2353c0) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7efcab235480) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7efcab235540) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7efcab2357e0) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7efcab2359c0) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7efcab235e40) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7efcab235ea0) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7efcab2efb40) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7efcab2efba0) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7efcab1d9c98) 0 empty + std::input_iterator_tag (0x0x7efcab2efc00) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7efcab1d9d00) 0 empty + std::forward_iterator_tag (0x0x7efcab1d9d68) 0 empty + std::input_iterator_tag (0x0x7efcab2efc60) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7efcab1d9dd0) 0 empty + std::bidirectional_iterator_tag (0x0x7efcab1d9e38) 0 empty + std::forward_iterator_tag (0x0x7efcab1d9ea0) 0 empty + std::input_iterator_tag (0x0x7efcab2efcc0) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7efcab320960) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7efcab3209c0) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7efcab320a20) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7efcab320a80) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7efcab320ae0) 0 empty + +Class wait + size=4 align=4 + base size=4 base align=4 +wait (0x0x7efcab009600) 0 + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7efcab009840) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7efcab009900) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7efcab009960) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7efcab009a20) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7efcab009a80) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7efcab009f00) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7efcab009f60) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7efcab14a000) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16u) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7efcab32c410) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u) + std::exception (0x0x7efcab14a060) 0 nearly-empty + primary-for std::bad_exception (0x0x7efcab32c410) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7efcab14a0c0) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7efcab14a120) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16u) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7efcab32c618) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u) + std::exception (0x0x7efcab14a540) 0 nearly-empty + primary-for std::bad_alloc (0x0x7efcab32c618) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7efcab32c680) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16u) + std::bad_alloc (0x0x7efcab32c6e8) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7efcab32c680) + std::exception (0x0x7efcab14a5a0) 0 nearly-empty + primary-for std::bad_alloc (0x0x7efcab32c6e8) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7efcab14a600) 0 empty + +Class __exception + size=40 align=8 + base size=40 base align=8 +__exception (0x0x7efcaae26240) 0 + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7efcaae26f00) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7efcaae26f60) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7efcaac72e40) 0 + +Class __sched_param + size=4 align=4 + base size=4 base align=4 +__sched_param (0x0x7efcaac72ea0) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7efcaac72f60) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7efcaacfb000) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7efcaacfb060) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7efcaacfb0c0) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7efcaacfb1e0) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7efcaacfb240) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7efcaacfb660) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7efcaacfb6c0) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7efcaab35ea0) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7efcaab35f00) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7efcaa80dea0) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7efcaa5b1cc0) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7efcaa93f2d8) 0 + std::iterator (0x0x7efcaa5b1d80) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7efcaa93f340) 0 + std::_Bit_iterator_base (0x0x7efcaa93f3a8) 0 + std::iterator (0x0x7efcaa5b1de0) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7efcaa93f410) 0 + std::_Bit_iterator_base (0x0x7efcaa93f478) 0 + std::iterator (0x0x7efcaa5b1e40) 0 empty + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7efcaa39ac60) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7efcaa4dca20) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7efcaa4dc9c0) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7efcaa2639c0) 0 + +Class qIsNull(double)::U + size=8 align=8 + base size=8 base align=8 +qIsNull(double)::U (0x0x7efca8eaf4e0) 0 + +Class qIsNull(float)::U + size=4 align=4 + base size=4 base align=4 +qIsNull(float)::U (0x0x7efca8eaf540) 0 + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7efca8b85000) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7efca8b85060) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7efca8b850c0) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7efca8b85120) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7efca8b853c0) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7efca8b85900) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7efca8bc9340) 0 + std::__atomic_flag_base (0x0x7efca8b85960) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7efca8bc9a90) 0 + QAtomicInteger (0x0x7efca8bc9af8) 0 + QBasicAtomicInteger (0x0x7efca87ba0c0) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7efca86b2660) 0 empty + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7efca8426840) 0 + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7efca8426960) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7efca87516e8) 0 + QGenericArgument (0x0x7efca84269c0) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7efca8426b40) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7efca8426c00) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7efca8513c60) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7efca8513cc0) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7efca8513f60) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7efca81fe000) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7efca81fe360) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7efca81fe3c0) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7efca81fe420) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7efca81fe480) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7efca81fe4e0) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7efca81fe8a0) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7efca8532d00) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16u) + std::exception (0x0x7efca81fe960) 0 nearly-empty + primary-for std::logic_error (0x0x7efca8532d00) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7efca8532d68) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16u) + std::logic_error (0x0x7efca8532dd0) 0 + primary-for std::domain_error (0x0x7efca8532d68) + std::exception (0x0x7efca81fe9c0) 0 nearly-empty + primary-for std::logic_error (0x0x7efca8532dd0) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7efca8532e38) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16u) + std::logic_error (0x0x7efca8532ea0) 0 + primary-for std::invalid_argument (0x0x7efca8532e38) + std::exception (0x0x7efca81fea20) 0 nearly-empty + primary-for std::logic_error (0x0x7efca8532ea0) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7efca8532f08) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16u) + std::logic_error (0x0x7efca8532f70) 0 + primary-for std::length_error (0x0x7efca8532f08) + std::exception (0x0x7efca81fea80) 0 nearly-empty + primary-for std::logic_error (0x0x7efca8532f70) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7efca8532a28) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16u) + std::logic_error (0x0x7efca8532af8) 0 + primary-for std::out_of_range (0x0x7efca8532a28) + std::exception (0x0x7efca81feae0) 0 nearly-empty + primary-for std::logic_error (0x0x7efca8532af8) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7efca82ed000) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16u) + std::exception (0x0x7efca81feb40) 0 nearly-empty + primary-for std::runtime_error (0x0x7efca82ed000) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7efca82ed068) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16u) + std::runtime_error (0x0x7efca82ed0d0) 0 + primary-for std::range_error (0x0x7efca82ed068) + std::exception (0x0x7efca81feba0) 0 nearly-empty + primary-for std::runtime_error (0x0x7efca82ed0d0) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7efca82ed138) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16u) + std::runtime_error (0x0x7efca82ed1a0) 0 + primary-for std::overflow_error (0x0x7efca82ed138) + std::exception (0x0x7efca81fec00) 0 nearly-empty + primary-for std::runtime_error (0x0x7efca82ed1a0) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7efca82ed208) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16u) + std::runtime_error (0x0x7efca82ed270) 0 + primary-for std::underflow_error (0x0x7efca82ed208) + std::exception (0x0x7efca81fec60) 0 nearly-empty + primary-for std::runtime_error (0x0x7efca82ed270) + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7efca81fede0) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16u) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7efca830d060) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7efca830d1e0) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7efca82ed750) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16u) + std::runtime_error (0x0x7efca82ed7b8) 0 + primary-for std::system_error (0x0x7efca82ed750) + std::exception (0x0x7efca830d420) 0 nearly-empty + primary-for std::runtime_error (0x0x7efca82ed7b8) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7efca7f653a8) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16u) + std::system_error (0x0x7efca7f65410) 0 + primary-for std::ios_base::failure (0x0x7efca7f653a8) + std::runtime_error (0x0x7efca7f65478) 0 + primary-for std::system_error (0x0x7efca7f65410) + std::exception (0x0x7efca830d720) 0 nearly-empty + primary-for std::runtime_error (0x0x7efca7f65478) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7efca830d780) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7efca830d7e0) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7efca830d840) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7efca830d6c0) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7efca806f000) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7efca806f6c0) 0 empty + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSo: 2u entries +0 ((& std::basic_ostream::_ZTVSo) + 24u) +8 ((& std::basic_ostream::_ZTVSo) + 64u) + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSi: 2u entries +0 ((& std::basic_istream::_ZTVSi) + 24u) +8 ((& std::basic_istream::_ZTVSi) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u) + +Construction vtable for std::basic_istream (0x0x7efca7bb0068 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd0_Si: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7efca7bb03a8 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd16_So: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSd: 7u entries +0 ((& std::basic_iostream::_ZTVSd) + 24u) +8 ((& std::basic_iostream::_ZTCSd0_Si) + 24u) +16 ((& std::basic_iostream::_ZTCSd0_Si) + 64u) +24 ((& std::basic_iostream::_ZTCSd16_So) + 24u) +32 ((& std::basic_iostream::_ZTCSd16_So) + 64u) +40 ((& std::basic_iostream::_ZTVSd) + 104u) +48 ((& std::basic_iostream::_ZTVSd) + 64u) + +Construction vtable for std::basic_istream (0x0x7efca7c66138 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7efca7c66208 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries +0 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u) +16 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u) +24 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u) +32 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u) +40 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u) +48 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u) + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7efca7e09f00) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7efca7e09f60) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7efca799e300) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7efca799e660) 0 + +Class QStringView + size=16 align=8 + base size=16 base align=8 +QStringView (0x0x7efca799eae0) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7efca7ab5960) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7efca7820000) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7efca7ab5f60) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7efca79360c0) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7efca7936cc0) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7efca76fb960) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7efca76fb9c0) 0 empty + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7efca76fba20) 0 + +Class QListData::NotArrayCompatibleLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotArrayCompatibleLayout (0x0x7efca76fbde0) 0 empty + +Class QListData::NotIndirectLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotIndirectLayout (0x0x7efca76fbe40) 0 empty + +Class QListData::ArrayCompatibleLayout + size=1 align=1 + base size=1 base align=1 +QListData::ArrayCompatibleLayout (0x0x7efca76f9d00) 0 empty + QListData::NotIndirectLayout (0x0x7efca76fbea0) 0 empty + +Class QListData::InlineWithPaddingLayout + size=1 align=1 + base size=1 base align=1 +QListData::InlineWithPaddingLayout (0x0x7efca754d4d0) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7efca76fbf00) 0 empty + QListData::NotIndirectLayout (0x0x7efca76fbf60) 0 empty + +Class QListData::IndirectLayout + size=1 align=1 + base size=1 base align=1 +QListData::IndirectLayout (0x0x7efca76f9d68) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7efca7552000) 0 empty + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7efca7552060) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7efca76fbd80) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7efca75524e0) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7efca7305720) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7efca73056c0) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7efca730b7b8) 0 + QList (0x0x7efca730b820) 0 + QListSpecialMethods (0x0x7efca7305900) 0 empty + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7efca7305d20) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7efca6ff2900) 0 + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7efca6ff2f60) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7efca6dc6120) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7efca6dc61e0) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7efca6dc9000) 0 + std::__uses_alloc_base (0x0x7efca6dc6180) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7efca6eb6240) 0 empty + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7efca6eb6480) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7efca6eb6540) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7efca6eb6660) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7efca6eb67e0) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7efca6eb6c00) 0 + +Class QtMetaTypePrivate::VectorBoolElements + size=1 align=1 + base size=0 base align=1 +QtMetaTypePrivate::VectorBoolElements (0x0x7efca6eb6d20) 0 empty + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7efca6c3a6c0) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7efca6c3aae0) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7efca6c3ade0) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7efca6b307e0) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7efca688d660) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7efca688d6c0) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16u) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7efca688d8a0) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7efca688d840) 0 + vptr=((& QObject::_ZTV7QObject) + 16u) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7efca6957b40) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7efca6957ba0) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7efca6957c60) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7efca6583340) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u) + QObject (0x0x7efca6957c00) 0 + primary-for QAbstractAnimation (0x0x7efca6583340) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7efca6957d20) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7efca65833a8) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16u) + QObject (0x0x7efca6957cc0) 0 + primary-for QAnimationDriver (0x0x7efca65833a8) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7efca6957de0) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7efca6583410) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u) + QObject (0x0x7efca6957d80) 0 + primary-for QEventLoop (0x0x7efca6583410) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7efca6605000) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7efca66050c0) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7efca6605120) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7efca6583548) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u) + QObject (0x0x7efca6605060) 0 + primary-for QAbstractEventDispatcher (0x0x7efca6583548) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7efca66053c0) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16u) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7efca6583750) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16u) + std::exception (0x0x7efca6605420) 0 nearly-empty + primary-for std::bad_cast (0x0x7efca6583750) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7efca65837b8) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16u) + std::exception (0x0x7efca6605480) 0 nearly-empty + primary-for std::bad_typeid (0x0x7efca65837b8) + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7efca66f2a28) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16u) + std::exception (0x0x7efca63a3540) 0 nearly-empty + primary-for std::bad_function_call (0x0x7efca66f2a28) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7efca63a3600) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7efca63a3660) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7efca63a3780) 0 + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7efca63a3c60) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7efca645a1e0) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7efca645a5a0) 0 + +Class QHashData + size=48 align=8 + base size=44 base align=8 +QHashData (0x0x7efca645a540) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7efca645a600) 0 empty + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7efca645aea0) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7efca645af60) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7efca645af00) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7efca62a4000) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7efca645ae40) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7efca6340ae0) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7efca5fec180) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7efca5fec120) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7efca5fec240) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7efca5fec1e0) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7efca610d540) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7efca610dc00) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7efca5ef9360) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7efca5ef87b8) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u) + QObject (0x0x7efca5ef9300) 0 + primary-for QAbstractItemModel (0x0x7efca5ef87b8) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7efca5ef9c00) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7efca5ef8ea0) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u) + QAbstractItemModel (0x0x7efca5ef8f08) 0 + primary-for QAbstractTableModel (0x0x7efca5ef8ea0) + QObject (0x0x7efca5ef9ba0) 0 + primary-for QAbstractItemModel (0x0x7efca5ef8f08) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7efca5ef9cc0) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7efca5ef8f70) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u) + QAbstractItemModel (0x0x7efca5bde000) 0 + primary-for QAbstractListModel (0x0x7efca5ef8f70) + QObject (0x0x7efca5ef9c60) 0 + primary-for QAbstractItemModel (0x0x7efca5bde000) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7efca5ef9f60) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16u) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7efca5c38060) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7efca5bde138) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16u) + QAbstractItemModel (0x0x7efca5bde1a0) 0 + primary-for QAbstractProxyModel (0x0x7efca5bde138) + QObject (0x0x7efca5c38000) 0 + primary-for QAbstractItemModel (0x0x7efca5bde1a0) + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7efca5c38120) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7efca5bde208) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u) + QObject (0x0x7efca5c380c0) 0 + primary-for QAbstractState (0x0x7efca5bde208) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7efca5c381e0) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7efca5bde270) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u) + QObject (0x0x7efca5c38180) 0 + primary-for QAbstractTransition (0x0x7efca5bde270) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7efca5c382a0) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7efca5bde2d8) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u) + QAbstractAnimation (0x0x7efca5bde340) 0 + primary-for QAnimationGroup (0x0x7efca5bde2d8) + QObject (0x0x7efca5c38240) 0 + primary-for QAbstractAnimation (0x0x7efca5bde340) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7efca5cde000) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7efca5cde2a0) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7efca5cde360) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7efca5cde660) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7efca5bde9c0) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16u) + QObject (0x0x7efca5cde600) 0 + primary-for QIODevice (0x0x7efca5bde9c0) + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7efca5cde8a0) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7efca5bdeaf8) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16u) + QIODevice (0x0x7efca5bdeb60) 0 + primary-for QBuffer (0x0x7efca5bdeaf8) + QObject (0x0x7efca5cde840) 0 + primary-for QIODevice (0x0x7efca5bdeb60) + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7efca5cde960) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7efca5cde900) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7efca5cdea80) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7efca5cdea20) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7efca5cdec60) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7efca5cdee40) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7efca5a54120) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7efca5a548a0) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7efca5a54900) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7efca5a54840) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7efca5b18a20) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7efca57ed060) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16u) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7efca57ed300) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7efca57ed540) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7efca57edc00) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7efca57edd80) 0 + +Class QDebug::Stream + size=80 align=8 + base size=76 base align=8 +QDebug::Stream (0x0x7efca557d300) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7efca557d2a0) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7efca5372600) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7efca53726c0) 0 empty + +Class QCborError + size=4 align=4 + base size=4 base align=4 +QCborError (0x0x7efca53f6a20) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7efca53f6ba0) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7efca54801e0) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7efca54804e0) 0 + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7efca54808a0) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7efca51c9f60) 0 + +Class QCborParserError + size=16 align=8 + base size=12 base align=8 +QCborParserError (0x0x7efca52485a0) 0 + +Class QCborValue + size=24 align=8 + base size=20 base align=8 +QCborValue (0x0x7efca5248600) 0 + +Class QCborValueRef + size=16 align=8 + base size=16 base align=8 +QCborValueRef (0x0x7efca50ab600) 0 + +Class QCborArray::Iterator + size=16 align=8 + base size=16 base align=8 +QCborArray::Iterator (0x0x7efca50abba0) 0 + +Class QCborArray::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborArray::ConstIterator (0x0x7efca50abc00) 0 + +Class QCborArray + size=8 align=8 + base size=8 base align=8 +QCborArray (0x0x7efca50abb40) 0 + +Class QCborMap::Iterator + size=16 align=8 + base size=16 base align=8 +QCborMap::Iterator (0x0x7efca4ddcc60) 0 + +Class QCborMap::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborMap::ConstIterator (0x0x7efca4ddccc0) 0 + +Class QCborMap + size=8 align=8 + base size=8 base align=8 +QCborMap (0x0x7efca4ddcc00) 0 + +Class qfloat16 + size=2 align=2 + base size=2 base align=2 +qfloat16 (0x0x7efca4ba1840) 0 + +Class QCborStreamWriter + size=8 align=8 + base size=8 base align=8 +QCborStreamWriter (0x0x7efca4ba1c00) 0 + +Class QCborStreamReader + size=24 align=8 + base size=20 base align=8 +QCborStreamReader (0x0x7efca4cf7600) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7efca4cf7c60) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7efca4cf7d20) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7efca49f7d20) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7efca4a331e0) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16u) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7efca4a36138) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u) + QEvent (0x0x7efca4a33240) 0 + primary-for QTimerEvent (0x0x7efca4a36138) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7efca4a361a0) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u) + QEvent (0x0x7efca4a332a0) 0 + primary-for QChildEvent (0x0x7efca4a361a0) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7efca4a366e8) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u) + QEvent (0x0x7efca4a33780) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7efca4a366e8) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7efca4a36750) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16u) + QEvent (0x0x7efca4a337e0) 0 + primary-for QDeferredDeleteEvent (0x0x7efca4a36750) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7efca4a338a0) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7efca4a367b8) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u) + QObject (0x0x7efca4a33840) 0 + primary-for QCoreApplication (0x0x7efca4a367b8) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7efca4a33900) 0 + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7efca4a33960) 0 + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7efca4a339c0) 0 + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7efca4a33a80) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7efca4a33f60) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7efca4755480) 0 + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7efca4879300) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7efca486ec30) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16u) + QIODevice (0x0x7efca486ec98) 0 + primary-for QFileDevice (0x0x7efca486ec30) + QObject (0x0x7efca48792a0) 0 + primary-for QIODevice (0x0x7efca486ec98) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7efca4879540) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7efca486edd0) 0 + vptr=((& QFile::_ZTV5QFile) + 16u) + QFileDevice (0x0x7efca486ee38) 0 + primary-for QFile (0x0x7efca486edd0) + QIODevice (0x0x7efca486eea0) 0 + primary-for QFileDevice (0x0x7efca486ee38) + QObject (0x0x7efca48794e0) 0 + primary-for QIODevice (0x0x7efca486eea0) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7efca4879720) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7efca4879b40) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7efca45a1180) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7efca45a13c0) 0 + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7efca46827e0) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7efca467cea0) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u) + QAbstractTransition (0x0x7efca467cf08) 0 + primary-for QEventTransition (0x0x7efca467cea0) + QObject (0x0x7efca4682780) 0 + primary-for QAbstractTransition (0x0x7efca467cf08) + +Vtable for QException +QException::_ZTV10QException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7efca467cf70) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16u) + std::exception (0x0x7efca4682840) 0 nearly-empty + primary-for QException (0x0x7efca467cf70) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7efca46f8000) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16u) + QException (0x0x7efca46f8068) 0 nearly-empty + primary-for QUnhandledException (0x0x7efca46f8000) + std::exception (0x0x7efca46828a0) 0 nearly-empty + primary-for QException (0x0x7efca46f8068) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7efca4682900) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7efca46829c0) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7efca4682a20) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7efca4682b40) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7efca46f80d0) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16u) + QObject (0x0x7efca4682ae0) 0 + primary-for QFileSelector (0x0x7efca46f80d0) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7efca4682c00) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7efca46f8138) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u) + QObject (0x0x7efca4682ba0) 0 + primary-for QFileSystemWatcher (0x0x7efca46f8138) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7efca4682cc0) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7efca46f81a0) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16u) + QAbstractState (0x0x7efca46f8208) 0 + primary-for QFinalState (0x0x7efca46f81a0) + QObject (0x0x7efca4682c60) 0 + primary-for QAbstractState (0x0x7efca46f8208) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7efca4682d20) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16u) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7efca4682d80) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7efca46f8340) 0 + QBasicMutex (0x0x7efca4682f60) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7efca43cd000) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7efca43cd060) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7efca43cd0c0) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7efca43cd1e0) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16u) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7efca43cda20) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7efca44b8240) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0u +48 0u +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7efca44b4478) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u) + QObject (0x0x7efca44b81e0) 0 + primary-for QFutureWatcherBase (0x0x7efca44b4478) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7efca44b8840) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7efca44b4d68) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u) + QAbstractState (0x0x7efca44b4dd0) 0 + primary-for QHistoryState (0x0x7efca44b4d68) + QObject (0x0x7efca44b87e0) 0 + primary-for QAbstractState (0x0x7efca44b4dd0) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7efca44b8900) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7efca44b4e38) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16u) + QAbstractProxyModel (0x0x7efca44b4ea0) 0 + primary-for QIdentityProxyModel (0x0x7efca44b4e38) + QAbstractItemModel (0x0x7efca44b4f08) 0 + primary-for QAbstractProxyModel (0x0x7efca44b4ea0) + QObject (0x0x7efca44b88a0) 0 + primary-for QAbstractItemModel (0x0x7efca44b4f08) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7efca44b8960) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7efca4197060) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7efca415c750) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u) + QObject (0x0x7efca4197000) 0 + primary-for QItemSelectionModel (0x0x7efca415c750) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7efca415c958) 0 + QList (0x0x7efca415c9c0) 0 + QListSpecialMethods (0x0x7efca4197360) 0 empty + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7efca4197840) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7efca3f6ef60) 0 + +Class QJsonValuePtr + size=24 align=8 + base size=24 base align=8 +QJsonValuePtr (0x0x7efca3fb94e0) 0 + +Class QJsonValueRefPtr + size=16 align=8 + base size=16 base align=8 +QJsonValueRefPtr (0x0x7efca3fb9540) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7efca3fb9720) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7efca3fb9780) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7efca3fb96c0) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7efca40a99c0) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7efca40a9a20) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7efca41280c0) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7efca4128120) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7efca4128060) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7efca3ddd3c0) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7efca3dd1d00) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16u) + QObject (0x0x7efca3ddd360) 0 + primary-for QLibrary (0x0x7efca3dd1d00) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7efca3ddda80) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7efca3ddd5a0) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7efca3dddf60) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7efca3edc000) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7efca3edc2a0) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7efca3edc8a0) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7efca3b7b240) 0 + +Class QLinkedListData + size=32 align=8 + base size=25 base align=8 +QLinkedListData (0x0x7efca3b7b840) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7efca3b7bba0) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7efca3b7bd20) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7efca3b7bcc0) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7efca3b7bea0) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7efca3d00180) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7efca3d007e0) 0 + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7efca3d00840) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7efca3d00e40) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7efca38ea180) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7efca38ea1e0) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7efca38ea4e0) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7efca3847f70) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16u) + QObject (0x0x7efca38ea480) 0 + primary-for QMimeData (0x0x7efca3847f70) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7efca38ea540) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7efca38ea840) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7efca38ea900) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7efca39331a0) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u) + QObject (0x0x7efca38ea8a0) 0 + primary-for QObjectCleanupHandler (0x0x7efca39331a0) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7efca38ea960) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7efca397d120) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7efca39338f0) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u) + QAnimationGroup (0x0x7efca3933958) 0 + primary-for QParallelAnimationGroup (0x0x7efca39338f0) + QAbstractAnimation (0x0x7efca39339c0) 0 + primary-for QAnimationGroup (0x0x7efca3933958) + QObject (0x0x7efca397d0c0) 0 + primary-for QAbstractAnimation (0x0x7efca39339c0) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7efca397d1e0) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7efca3933a28) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u) + QAbstractAnimation (0x0x7efca3933a90) 0 + primary-for QPauseAnimation (0x0x7efca3933a28) + QObject (0x0x7efca397d180) 0 + primary-for QAbstractAnimation (0x0x7efca3933a90) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7efca397d3c0) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7efca397d6c0) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7efca3933c98) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u) + QObject (0x0x7efca397d660) 0 + primary-for QPluginLoader (0x0x7efca3933c98) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7efca397d720) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7efca397dde0) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7efca39e62d8) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16u) + QIODevice (0x0x7efca39e6340) 0 + primary-for QProcess (0x0x7efca39e62d8) + QObject (0x0x7efca397dd80) 0 + primary-for QIODevice (0x0x7efca39e6340) + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7efca397dea0) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7efca39e63a8) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u) + QAbstractAnimation (0x0x7efca39e6410) 0 + primary-for QVariantAnimation (0x0x7efca39e63a8) + QObject (0x0x7efca397de40) 0 + primary-for QAbstractAnimation (0x0x7efca39e6410) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7efca397df60) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7efca39e64e0) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u) + QVariantAnimation (0x0x7efca39e6548) 0 + primary-for QPropertyAnimation (0x0x7efca39e64e0) + QAbstractAnimation (0x0x7efca39e65b0) 0 + primary-for QVariantAnimation (0x0x7efca39e6548) + QObject (0x0x7efca397df00) 0 + primary-for QAbstractAnimation (0x0x7efca39e65b0) + +Class QRandomGenerator::Storage + size=2504 align=8 + base size=2504 base align=8 +QRandomGenerator::Storage (0x0x7efca36520c0) 0 + +Class QRandomGenerator + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator (0x0x7efca3652060) 0 + +Class QRandomGenerator64 + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator64 (0x0x7efca36ce888) 0 + QRandomGenerator (0x0x7efca36f4060) 0 + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7efca36f4120) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7efca36f43c0) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7efca36f4480) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7efca36f4540) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7efca36f47e0) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7efca36f4a80) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7efca36f4d20) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7efca3544000) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7efca3544180) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7efca3817410) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16u) + QFileDevice (0x0x7efca3817478) 0 + primary-for QSaveFile (0x0x7efca3817410) + QIODevice (0x0x7efca38174e0) 0 + primary-for QFileDevice (0x0x7efca3817478) + QObject (0x0x7efca3544120) 0 + primary-for QIODevice (0x0x7efca38174e0) + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7efca35442a0) 0 + +Class QSemaphoreReleaser + size=16 align=8 + base size=12 base align=8 +QSemaphoreReleaser (0x0x7efca3544420) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7efca3298a20) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7efca3292d68) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u) + QAnimationGroup (0x0x7efca3292dd0) 0 + primary-for QSequentialAnimationGroup (0x0x7efca3292d68) + QAbstractAnimation (0x0x7efca3292e38) 0 + primary-for QAnimationGroup (0x0x7efca3292dd0) + QObject (0x0x7efca32989c0) 0 + primary-for QAbstractAnimation (0x0x7efca3292e38) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7efca3298ae0) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7efca3292ea0) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16u) + QObject (0x0x7efca3298a80) 0 + primary-for QSettings (0x0x7efca3292ea0) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7efca3298ba0) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7efca3292f08) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u) + QObject (0x0x7efca3298b40) 0 + primary-for QSharedMemory (0x0x7efca3292f08) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7efca3298c60) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7efca3292f70) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u) + QObject (0x0x7efca3298c00) 0 + primary-for QSignalMapper (0x0x7efca3292f70) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7efca3298d20) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7efca3303000) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u) + QAbstractTransition (0x0x7efca3303068) 0 + primary-for QSignalTransition (0x0x7efca3303000) + QObject (0x0x7efca3298cc0) 0 + primary-for QAbstractTransition (0x0x7efca3303068) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7efca3298de0) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7efca33030d0) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u) + QObject (0x0x7efca3298d80) 0 + primary-for QSocketNotifier (0x0x7efca33030d0) + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7efca3298ea0) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7efca3303138) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16u) + QAbstractProxyModel (0x0x7efca33031a0) 0 + primary-for QSortFilterProxyModel (0x0x7efca3303138) + QAbstractItemModel (0x0x7efca3303208) 0 + primary-for QAbstractProxyModel (0x0x7efca33031a0) + QObject (0x0x7efca3298e40) 0 + primary-for QAbstractItemModel (0x0x7efca3303208) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7efca3298f60) 0 empty + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7efca33601e0) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7efca33033a8) 0 + vptr=((& QState::_ZTV6QState) + 16u) + QAbstractState (0x0x7efca3303410) 0 + primary-for QState (0x0x7efca33033a8) + QObject (0x0x7efca3360180) 0 + primary-for QAbstractState (0x0x7efca3303410) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7efca3360300) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7efca33035b0) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u) + QEvent (0x0x7efca3360360) 0 + primary-for QStateMachine::SignalEvent (0x0x7efca33035b0) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7efca3303618) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u) + QEvent (0x0x7efca33603c0) 0 + primary-for QStateMachine::WrappedEvent (0x0x7efca3303618) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7efca3303478) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u) + QState (0x0x7efca33034e0) 0 + primary-for QStateMachine (0x0x7efca3303478) + QAbstractState (0x0x7efca3303548) 0 + primary-for QState (0x0x7efca33034e0) + QObject (0x0x7efca33602a0) 0 + primary-for QAbstractState (0x0x7efca3303548) + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7efca3360420) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7efca340f360) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7efca309d720) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7efca30a4618) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u) + QAbstractListModel (0x0x7efca30a4680) 0 + primary-for QStringListModel (0x0x7efca30a4618) + QAbstractItemModel (0x0x7efca30a46e8) 0 + primary-for QAbstractListModel (0x0x7efca30a4680) + QObject (0x0x7efca309d6c0) 0 + primary-for QAbstractItemModel (0x0x7efca30a46e8) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7efca309d780) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7efca309d840) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7efca309d960) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7efca30a4750) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u) + QFile (0x0x7efca30a47b8) 0 + primary-for QTemporaryFile (0x0x7efca30a4750) + QFileDevice (0x0x7efca30a4820) 0 + primary-for QFile (0x0x7efca30a47b8) + QIODevice (0x0x7efca30a4888) 0 + primary-for QFileDevice (0x0x7efca30a4820) + QObject (0x0x7efca309d900) 0 + primary-for QIODevice (0x0x7efca30a4888) + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7efca309d9c0) 0 + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7efca309dc00) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 0u +64 0u + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7efca309dba0) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7efca309dde0) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7efca309de40) 0 + +Class std::__mutex_base + size=40 align=8 + base size=40 base align=8 +std::__mutex_base (0x0x7efca309dea0) 0 + +Class std::__recursive_mutex_base + size=40 align=8 + base size=40 base align=8 +std::__recursive_mutex_base (0x0x7efca309df00) 0 + +Class std::mutex + size=40 align=8 + base size=40 base align=8 +std::mutex (0x0x7efca30a4a90) 0 + std::__mutex_base (0x0x7efca309df60) 0 + +Class std::recursive_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_mutex (0x0x7efca30a4af8) 0 + std::__recursive_mutex_base (0x0x7efca319d000) 0 + +Class std::timed_mutex + size=40 align=8 + base size=40 base align=8 +std::timed_mutex (0x0x7efca31a55b0) 0 + std::__mutex_base (0x0x7efca319d120) 0 + std::__timed_mutex_impl (0x0x7efca319d180) 0 empty + +Class std::recursive_timed_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_timed_mutex (0x0x7efca31a5f50) 0 + std::__recursive_mutex_base (0x0x7efca319d240) 0 + std::__timed_mutex_impl (0x0x7efca319d2a0) 0 empty + +Class std::defer_lock_t + size=1 align=1 + base size=0 base align=1 +std::defer_lock_t (0x0x7efca319d300) 0 empty + +Class std::try_to_lock_t + size=1 align=1 + base size=0 base align=1 +std::try_to_lock_t (0x0x7efca319d360) 0 empty + +Class std::adopt_lock_t + size=1 align=1 + base size=0 base align=1 +std::adopt_lock_t (0x0x7efca319d3c0) 0 empty + +Class std::once_flag + size=4 align=4 + base size=4 base align=4 +std::once_flag (0x0x7efca319d600) 0 + +Vtable for __gnu_cxx::__concurrence_lock_error +__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what + +Class __gnu_cxx::__concurrence_lock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_lock_error (0x0x7efca30a4c30) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16u) + std::exception (0x0x7efca319d6c0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_lock_error (0x0x7efca30a4c30) + +Vtable for __gnu_cxx::__concurrence_unlock_error +__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what + +Class __gnu_cxx::__concurrence_unlock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_unlock_error (0x0x7efca30a4c98) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16u) + std::exception (0x0x7efca319d780) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7efca30a4c98) + +Vtable for __gnu_cxx::__concurrence_broadcast_error +__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what + +Class __gnu_cxx::__concurrence_broadcast_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_broadcast_error (0x0x7efca30a4d00) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16u) + std::exception (0x0x7efca319d840) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7efca30a4d00) + +Vtable for __gnu_cxx::__concurrence_wait_error +__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what + +Class __gnu_cxx::__concurrence_wait_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_wait_error (0x0x7efca30a4dd0) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16u) + std::exception (0x0x7efca319d900) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_wait_error (0x0x7efca30a4dd0) + +Class __gnu_cxx::__mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__mutex (0x0x7efca319d9c0) 0 + +Class __gnu_cxx::__recursive_mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__recursive_mutex (0x0x7efca319da20) 0 + +Class __gnu_cxx::__scoped_lock + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__scoped_lock (0x0x7efca319da80) 0 + +Class __gnu_cxx::__cond + size=48 align=8 + base size=48 base align=8 +__gnu_cxx::__cond (0x0x7efca319dae0) 0 + +Vtable for std::bad_weak_ptr +std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12bad_weak_ptr) +16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +32 (int (*)(...))std::bad_weak_ptr::what + +Class std::bad_weak_ptr + size=8 align=8 + base size=8 base align=8 +std::bad_weak_ptr (0x0x7efca30a4f08) 0 nearly-empty + vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16u) + std::exception (0x0x7efca319de40) 0 nearly-empty + primary-for std::bad_weak_ptr (0x0x7efca30a4f08) + +Class std::_Sp_make_shared_tag + size=1 align=1 + base size=0 base align=1 +std::_Sp_make_shared_tag (0x0x7efca2ef56c0) 0 empty + +Class std::_Sp_locker + size=2 align=1 + base size=2 base align=1 +std::_Sp_locker (0x0x7efca2ef5ea0) 0 + +Class std::thread::id + size=8 align=8 + base size=8 base align=8 +std::thread::id (0x0x7efca2c890c0) 0 + +Vtable for std::thread::_Impl_base +std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6thread10_Impl_baseE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class std::thread::_Impl_base + size=24 align=8 + base size=24 base align=8 +std::thread::_Impl_base (0x0x7efca2c89120) 0 + vptr=((& std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE) + 16u) + +Class std::thread + size=8 align=8 + base size=8 base align=8 +std::thread (0x0x7efca2c89060) 0 + +Class std::condition_variable + size=48 align=8 + base size=48 base align=8 +std::condition_variable (0x0x7efca2dc6d20) 0 + +Class std::__at_thread_exit_elt + size=16 align=8 + base size=16 base align=8 +std::__at_thread_exit_elt (0x0x7efca2dc6de0) 0 + +Class std::_V2::condition_variable_any + size=64 align=8 + base size=64 base align=8 +std::_V2::condition_variable_any (0x0x7efca2dc6e40) 0 + +Class std::__atomic_futex_unsigned_base + size=1 align=1 + base size=0 base align=1 +std::__atomic_futex_unsigned_base (0x0x7efca2a934e0) 0 empty + +Vtable for std::future_error +std::future_error::_ZTVSt12future_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12future_error) +16 (int (*)(...))std::future_error::~future_error +24 (int (*)(...))std::future_error::~future_error +32 (int (*)(...))std::future_error::what + +Class std::future_error + size=32 align=8 + base size=32 base align=8 +std::future_error (0x0x7efca2a98410) 0 + vptr=((& std::future_error::_ZTVSt12future_error) + 16u) + std::logic_error (0x0x7efca2a98478) 0 + primary-for std::future_error (0x0x7efca2a98410) + std::exception (0x0x7efca2a93600) 0 nearly-empty + primary-for std::logic_error (0x0x7efca2a98478) + +Class std::__future_base::_Result_base::_Deleter + size=1 align=1 + base size=0 base align=1 +std::__future_base::_Result_base::_Deleter (0x0x7efca2a93720) 0 empty + +Vtable for std::__future_base::_Result_base +std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class std::__future_base::_Result_base + size=16 align=8 + base size=16 base align=8 +std::__future_base::_Result_base (0x0x7efca2a936c0) 0 + vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16u) + +Class std::__future_base::_State_baseV2::__exception_ptr_tag + size=1 align=1 + base size=0 base align=1 +std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7efca2bf0c60) 0 empty + +Class std::__future_base::_State_baseV2::_Make_ready + size=32 align=8 + base size=32 base align=8 +std::__future_base::_State_baseV2::_Make_ready (0x0x7efca2bf1a28) 0 + std::__at_thread_exit_elt (0x0x7efca2bf0d20) 0 + +Vtable for std::__future_base::_State_baseV2 +std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E) +16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_State_baseV2 + size=32 align=8 + base size=28 base align=8 +std::__future_base::_State_baseV2 (0x0x7efca2a938a0) 0 + vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16u) + +Class std::__future_base + size=1 align=1 + base size=0 base align=1 +std::__future_base (0x0x7efca2a93660) 0 empty + +Vtable for std::__future_base::_Async_state_commonV2 +std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E) +16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_Async_state_commonV2 + size=48 align=8 + base size=44 base align=8 +std::__future_base::_Async_state_commonV2 (0x0x7efca2570618) 0 + vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16u) + std::__future_base::_State_baseV2 (0x0x7efca2563c00) 0 + primary-for std::__future_base::_Async_state_commonV2 (0x0x7efca2570618) + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7efca25ca360) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7efca25f10d0) 0 + vptr=((& QThread::_ZTV7QThread) + 16u) + QObject (0x0x7efca25ca300) 0 + primary-for QThread (0x0x7efca25f10d0) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7efca25ca480) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7efca25f1138) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u) + QObject (0x0x7efca25ca420) 0 + primary-for QThreadPool (0x0x7efca25f1138) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7efca25ca4e0) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7efca25ca600) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7efca25f11a0) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u) + QObject (0x0x7efca25ca5a0) 0 + primary-for QTimeLine (0x0x7efca25f11a0) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7efca25ca6c0) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7efca25f1208) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16u) + QObject (0x0x7efca25ca660) 0 + primary-for QTimer (0x0x7efca25f1208) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7efca25cade0) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7efca25cad80) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7efca22b33c0) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7efca25f1dd0) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16u) + QObject (0x0x7efca22b3360) 0 + primary-for QTranslator (0x0x7efca25f1dd0) + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7efca22b3420) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7efca22b3a80) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7efca22b3ae0) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7efca22b3d80) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7efca22f5a90) 0 + QVector (0x0x7efca2366180) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7efca23661e0) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7efca2366480) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7efca2366720) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7efca23669c0) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7efca2366a20) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7efca206a480) 0 + +Vtable for QSqlDriverCreatorBase +QSqlDriverCreatorBase::_ZTV21QSqlDriverCreatorBase: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSqlDriverCreatorBase) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QSqlDriverCreatorBase + size=8 align=8 + base size=8 base align=8 +QSqlDriverCreatorBase (0x0x7efca206a720) 0 nearly-empty + vptr=((& QSqlDriverCreatorBase::_ZTV21QSqlDriverCreatorBase) + 16u) + +Class QSqlDatabase + size=8 align=8 + base size=8 base align=8 +QSqlDatabase (0x0x7efca206a7e0) 0 + +Class QSqlDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSqlDriver::QPrivateSignal (0x0x7efca206a8a0) 0 empty + +Vtable for QSqlDriver +QSqlDriver::_ZTV10QSqlDriver: 38u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QSqlDriver) +16 (int (*)(...))QSqlDriver::metaObject +24 (int (*)(...))QSqlDriver::qt_metacast +32 (int (*)(...))QSqlDriver::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSqlDriver::isOpen +120 (int (*)(...))QSqlDriver::beginTransaction +128 (int (*)(...))QSqlDriver::commitTransaction +136 (int (*)(...))QSqlDriver::rollbackTransaction +144 (int (*)(...))QSqlDriver::tables +152 (int (*)(...))QSqlDriver::primaryIndex +160 (int (*)(...))QSqlDriver::record +168 (int (*)(...))QSqlDriver::formatValue +176 (int (*)(...))QSqlDriver::escapeIdentifier +184 (int (*)(...))QSqlDriver::sqlStatement +192 (int (*)(...))QSqlDriver::handle +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))__cxa_pure_virtual +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))__cxa_pure_virtual +232 (int (*)(...))QSqlDriver::subscribeToNotification +240 (int (*)(...))QSqlDriver::unsubscribeFromNotification +248 (int (*)(...))QSqlDriver::subscribedToNotifications +256 (int (*)(...))QSqlDriver::isIdentifierEscaped +264 (int (*)(...))QSqlDriver::stripDelimiters +272 (int (*)(...))QSqlDriver::cancelQuery +280 (int (*)(...))QSqlDriver::setOpen +288 (int (*)(...))QSqlDriver::setOpenError +296 (int (*)(...))QSqlDriver::setLastError + +Class QSqlDriver + size=16 align=8 + base size=16 base align=8 +QSqlDriver (0x0x7efca23f3d00) 0 + vptr=((& QSqlDriver::_ZTV10QSqlDriver) + 16u) + QObject (0x0x7efca206a840) 0 + primary-for QSqlDriver (0x0x7efca23f3d00) + +Class QSqlDriverPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSqlDriverPlugin::QPrivateSignal (0x0x7efca206a960) 0 empty + +Vtable for QSqlDriverPlugin +QSqlDriverPlugin::_ZTV16QSqlDriverPlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QSqlDriverPlugin) +16 (int (*)(...))QSqlDriverPlugin::metaObject +24 (int (*)(...))QSqlDriverPlugin::qt_metacast +32 (int (*)(...))QSqlDriverPlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QSqlDriverPlugin + size=16 align=8 + base size=16 base align=8 +QSqlDriverPlugin (0x0x7efca23f3d68) 0 + vptr=((& QSqlDriverPlugin::_ZTV16QSqlDriverPlugin) + 16u) + QObject (0x0x7efca206a900) 0 + primary-for QSqlDriverPlugin (0x0x7efca23f3d68) + +Class QSqlError::Unused + size=8 align=4 + base size=8 base align=4 +QSqlError::Unused (0x0x7efca206aa20) 0 + +Class QSqlError + size=24 align=8 + base size=24 base align=8 +QSqlError (0x0x7efca206a9c0) 0 + +Class QSqlField + size=24 align=8 + base size=24 base align=8 +QSqlField (0x0x7efca2175840) 0 + +Class QSqlRecord + size=8 align=8 + base size=8 base align=8 +QSqlRecord (0x0x7efca21758a0) 0 + +Class QSqlIndex + size=32 align=8 + base size=32 base align=8 +QSqlIndex (0x0x7efca21778f0) 0 + QSqlRecord (0x0x7efca2175900) 0 + +Class QSqlQuery + size=8 align=8 + base size=8 base align=8 +QSqlQuery (0x0x7efca2175a20) 0 + +Class QSqlQueryModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSqlQueryModel::QPrivateSignal (0x0x7efca2175ae0) 0 empty + +Vtable for QSqlQueryModel +QSqlQueryModel::_ZTV14QSqlQueryModel: 51u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QSqlQueryModel) +16 (int (*)(...))QSqlQueryModel::metaObject +24 (int (*)(...))QSqlQueryModel::qt_metacast +32 (int (*)(...))QSqlQueryModel::qt_metacall +40 (int (*)(...))QSqlQueryModel::~QSqlQueryModel +48 (int (*)(...))QSqlQueryModel::~QSqlQueryModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))QSqlQueryModel::rowCount +144 (int (*)(...))QSqlQueryModel::columnCount +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))QSqlQueryModel::data +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QSqlQueryModel::headerData +184 (int (*)(...))QSqlQueryModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QSqlQueryModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QSqlQueryModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSqlQueryModel::fetchMore +312 (int (*)(...))QSqlQueryModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QSqlQueryModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert +384 (int (*)(...))QSqlQueryModel::clear +392 (int (*)(...))QSqlQueryModel::queryChange +400 (int (*)(...))QSqlQueryModel::indexInQuery + +Class QSqlQueryModel + size=16 align=8 + base size=16 base align=8 +QSqlQueryModel (0x0x7efca2177a28) 0 + vptr=((& QSqlQueryModel::_ZTV14QSqlQueryModel) + 16u) + QAbstractTableModel (0x0x7efca2177a90) 0 + primary-for QSqlQueryModel (0x0x7efca2177a28) + QAbstractItemModel (0x0x7efca2177af8) 0 + primary-for QAbstractTableModel (0x0x7efca2177a90) + QObject (0x0x7efca2175a80) 0 + primary-for QAbstractItemModel (0x0x7efca2177af8) + +Class QSqlTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSqlTableModel::QPrivateSignal (0x0x7efca2175ba0) 0 empty + +Vtable for QSqlTableModel +QSqlTableModel::_ZTV14QSqlTableModel: 63u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QSqlTableModel) +16 (int (*)(...))QSqlTableModel::metaObject +24 (int (*)(...))QSqlTableModel::qt_metacast +32 (int (*)(...))QSqlTableModel::qt_metacall +40 (int (*)(...))QSqlTableModel::~QSqlTableModel +48 (int (*)(...))QSqlTableModel::~QSqlTableModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))QSqlTableModel::rowCount +144 (int (*)(...))QSqlQueryModel::columnCount +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))QSqlTableModel::data +168 (int (*)(...))QSqlTableModel::setData +176 (int (*)(...))QSqlTableModel::headerData +184 (int (*)(...))QSqlQueryModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QSqlTableModel::insertRows +264 (int (*)(...))QSqlQueryModel::insertColumns +272 (int (*)(...))QSqlTableModel::removeRows +280 (int (*)(...))QSqlTableModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSqlQueryModel::fetchMore +312 (int (*)(...))QSqlQueryModel::canFetchMore +320 (int (*)(...))QSqlTableModel::flags +328 (int (*)(...))QSqlTableModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QSqlQueryModel::roleNames +368 (int (*)(...))QSqlTableModel::submit +376 (int (*)(...))QSqlTableModel::revert +384 (int (*)(...))QSqlTableModel::clear +392 (int (*)(...))QSqlQueryModel::queryChange +400 (int (*)(...))QSqlTableModel::indexInQuery +408 (int (*)(...))QSqlTableModel::setTable +416 (int (*)(...))QSqlTableModel::setEditStrategy +424 (int (*)(...))QSqlTableModel::setSort +432 (int (*)(...))QSqlTableModel::setFilter +440 (int (*)(...))QSqlTableModel::revertRow +448 (int (*)(...))QSqlTableModel::select +456 (int (*)(...))QSqlTableModel::selectRow +464 (int (*)(...))QSqlTableModel::updateRowInTable +472 (int (*)(...))QSqlTableModel::insertRowIntoTable +480 (int (*)(...))QSqlTableModel::deleteRowFromTable +488 (int (*)(...))QSqlTableModel::orderByClause +496 (int (*)(...))QSqlTableModel::selectStatement + +Class QSqlTableModel + size=16 align=8 + base size=16 base align=8 +QSqlTableModel (0x0x7efca2177b60) 0 + vptr=((& QSqlTableModel::_ZTV14QSqlTableModel) + 16u) + QSqlQueryModel (0x0x7efca2177bc8) 0 + primary-for QSqlTableModel (0x0x7efca2177b60) + QAbstractTableModel (0x0x7efca2177c30) 0 + primary-for QSqlQueryModel (0x0x7efca2177bc8) + QAbstractItemModel (0x0x7efca2177c98) 0 + primary-for QAbstractTableModel (0x0x7efca2177c30) + QObject (0x0x7efca2175b40) 0 + primary-for QAbstractItemModel (0x0x7efca2177c98) + +Class QSqlRelation + size=24 align=8 + base size=24 base align=8 +QSqlRelation (0x0x7efca2175c00) 0 + +Class QSqlRelationalTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSqlRelationalTableModel::QPrivateSignal (0x0x7efca2175f00) 0 empty + +Vtable for QSqlRelationalTableModel +QSqlRelationalTableModel::_ZTV24QSqlRelationalTableModel: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QSqlRelationalTableModel) +16 (int (*)(...))QSqlRelationalTableModel::metaObject +24 (int (*)(...))QSqlRelationalTableModel::qt_metacast +32 (int (*)(...))QSqlRelationalTableModel::qt_metacall +40 (int (*)(...))QSqlRelationalTableModel::~QSqlRelationalTableModel +48 (int (*)(...))QSqlRelationalTableModel::~QSqlRelationalTableModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))QSqlTableModel::rowCount +144 (int (*)(...))QSqlQueryModel::columnCount +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))QSqlRelationalTableModel::data +168 (int (*)(...))QSqlRelationalTableModel::setData +176 (int (*)(...))QSqlTableModel::headerData +184 (int (*)(...))QSqlQueryModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QSqlTableModel::insertRows +264 (int (*)(...))QSqlQueryModel::insertColumns +272 (int (*)(...))QSqlTableModel::removeRows +280 (int (*)(...))QSqlRelationalTableModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSqlQueryModel::fetchMore +312 (int (*)(...))QSqlQueryModel::canFetchMore +320 (int (*)(...))QSqlTableModel::flags +328 (int (*)(...))QSqlTableModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QSqlQueryModel::roleNames +368 (int (*)(...))QSqlTableModel::submit +376 (int (*)(...))QSqlTableModel::revert +384 (int (*)(...))QSqlRelationalTableModel::clear +392 (int (*)(...))QSqlQueryModel::queryChange +400 (int (*)(...))QSqlTableModel::indexInQuery +408 (int (*)(...))QSqlRelationalTableModel::setTable +416 (int (*)(...))QSqlTableModel::setEditStrategy +424 (int (*)(...))QSqlTableModel::setSort +432 (int (*)(...))QSqlTableModel::setFilter +440 (int (*)(...))QSqlRelationalTableModel::revertRow +448 (int (*)(...))QSqlRelationalTableModel::select +456 (int (*)(...))QSqlTableModel::selectRow +464 (int (*)(...))QSqlRelationalTableModel::updateRowInTable +472 (int (*)(...))QSqlRelationalTableModel::insertRowIntoTable +480 (int (*)(...))QSqlTableModel::deleteRowFromTable +488 (int (*)(...))QSqlRelationalTableModel::orderByClause +496 (int (*)(...))QSqlRelationalTableModel::selectStatement +504 (int (*)(...))QSqlRelationalTableModel::setRelation +512 (int (*)(...))QSqlRelationalTableModel::relationModel + +Class QSqlRelationalTableModel + size=16 align=8 + base size=16 base align=8 +QSqlRelationalTableModel (0x0x7efca2177f08) 0 + vptr=((& QSqlRelationalTableModel::_ZTV24QSqlRelationalTableModel) + 16u) + QSqlTableModel (0x0x7efca2177f70) 0 + primary-for QSqlRelationalTableModel (0x0x7efca2177f08) + QSqlQueryModel (0x0x7efca1e3f000) 0 + primary-for QSqlTableModel (0x0x7efca2177f70) + QAbstractTableModel (0x0x7efca1e3f068) 0 + primary-for QSqlQueryModel (0x0x7efca1e3f000) + QAbstractItemModel (0x0x7efca1e3f0d0) 0 + primary-for QAbstractTableModel (0x0x7efca1e3f068) + QObject (0x0x7efca2175ea0) 0 + primary-for QAbstractItemModel (0x0x7efca1e3f0d0) + +Vtable for QSqlResult +QSqlResult::_ZTV10QSqlResult: 33u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QSqlResult) +16 0u +24 0u +32 (int (*)(...))QSqlResult::handle +40 (int (*)(...))QSqlResult::setAt +48 (int (*)(...))QSqlResult::setActive +56 (int (*)(...))QSqlResult::setLastError +64 (int (*)(...))QSqlResult::setQuery +72 (int (*)(...))QSqlResult::setSelect +80 (int (*)(...))QSqlResult::setForwardOnly +88 (int (*)(...))QSqlResult::exec +96 (int (*)(...))QSqlResult::prepare +104 (int (*)(...))QSqlResult::savePrepare +112 (int (*)(...))QSqlResult::bindValue +120 (int (*)(...))QSqlResult::bindValue +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))QSqlResult::fetchNext +168 (int (*)(...))QSqlResult::fetchPrevious +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QSqlResult::record +216 (int (*)(...))QSqlResult::lastInsertId +224 (int (*)(...))QSqlResult::virtual_hook +232 (int (*)(...))QSqlResult::execBatch +240 (int (*)(...))QSqlResult::detachFromResultSet +248 (int (*)(...))QSqlResult::setNumericalPrecisionPolicy +256 (int (*)(...))QSqlResult::nextResult + +Class QSqlResult + size=16 align=8 + base size=16 base align=8 +QSqlResult (0x0x7efca2175f60) 0 + vptr=((& QSqlResult::_ZTV10QSqlResult) + 16u) + diff --git a/tests/auto/bic/data/QtTest.5.12.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtTest.5.12.0.linux-gcc-amd64.txt new file mode 100644 index 0000000000..faaf2c505a --- /dev/null +++ b/tests/auto/bic/data/QtTest.5.12.0.linux-gcc-amd64.txt @@ -0,0 +1,4704 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7fde232fa4e0) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7fde23346c60) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7fde23346ea0) 0 empty + +Class std::__do_is_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_default_constructible_impl (0x0x7fde20ef1120) 0 empty + +Class std::__do_is_static_castable_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_static_castable_impl (0x0x7fde20ef1360) 0 empty + +Class std::__do_is_direct_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_direct_constructible_impl (0x0x7fde20ef14e0) 0 empty + +Class std::__do_is_nary_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nary_constructible_impl (0x0x7fde20ef18a0) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7fde20fac060) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7fde20fac120) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7fde20fac480) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7fde20fac540) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7fde20fac600) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7fde20fac6c0) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7fde20fac960) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7fde20facb40) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7fde21037000) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7fde21037060) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7fde21068cc0) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7fde21068d20) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7fde20f58c30) 0 empty + std::input_iterator_tag (0x0x7fde21068d80) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7fde20f58c98) 0 empty + std::forward_iterator_tag (0x0x7fde20f58d00) 0 empty + std::input_iterator_tag (0x0x7fde21068de0) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7fde20f58d68) 0 empty + std::bidirectional_iterator_tag (0x0x7fde20f58dd0) 0 empty + std::forward_iterator_tag (0x0x7fde20f58e38) 0 empty + std::input_iterator_tag (0x0x7fde21068e40) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7fde21098ae0) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7fde21098b40) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7fde21098ba0) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7fde21098c00) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7fde21098c60) 0 empty + +Class wait + size=4 align=4 + base size=4 base align=4 +wait (0x0x7fde20d77780) 0 + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7fde20d779c0) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7fde20d77a80) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7fde20d77ae0) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7fde20d77ba0) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7fde20d77c00) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7fde20e0c0c0) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7fde20e0c120) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7fde20e0c180) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16u) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7fde210ac3a8) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u) + std::exception (0x0x7fde20e0c1e0) 0 nearly-empty + primary-for std::bad_exception (0x0x7fde210ac3a8) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7fde20e0c240) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7fde20e0c2a0) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16u) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7fde210ac5b0) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u) + std::exception (0x0x7fde20e0c6c0) 0 nearly-empty + primary-for std::bad_alloc (0x0x7fde210ac5b0) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7fde210ac618) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16u) + std::bad_alloc (0x0x7fde210ac680) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7fde210ac618) + std::exception (0x0x7fde20e0c720) 0 nearly-empty + primary-for std::bad_alloc (0x0x7fde210ac680) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7fde20e0c780) 0 empty + +Class __exception + size=40 align=8 + base size=40 base align=8 +__exception (0x0x7fde20b883c0) 0 + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7fde209aa0c0) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7fde209aa120) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7fde20a6e000) 0 + +Class __sched_param + size=4 align=4 + base size=4 base align=4 +__sched_param (0x0x7fde20a6e060) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7fde20a6e120) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7fde20a6e180) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7fde20a6e1e0) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7fde20a6e240) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7fde20a6e360) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7fde20a6e3c0) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7fde20a6e7e0) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7fde20a6e840) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7fde20583060) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7fde205830c0) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7fde206be060) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7fde206bee40) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7fde20327270) 0 + std::iterator (0x0x7fde206bef00) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7fde203272d8) 0 + std::_Bit_iterator_base (0x0x7fde20327340) 0 + std::iterator (0x0x7fde206bef60) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7fde203273a8) 0 + std::_Bit_iterator_base (0x0x7fde20327410) 0 + std::iterator (0x0x7fde204b5000) 0 empty + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7fde204b5de0) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7fde20257ba0) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7fde20257b40) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7fde1ffb4b40) 0 + +Class qIsNull(double)::U + size=8 align=8 + base size=8 base align=8 +qIsNull(double)::U (0x0x7fde1ec1f660) 0 + +Class qIsNull(float)::U + size=4 align=4 + base size=4 base align=4 +qIsNull(float)::U (0x0x7fde1ec1f6c0) 0 + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7fde1e8fe180) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7fde1e8fe1e0) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7fde1e8fe240) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7fde1e8fe2a0) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7fde1e8fe540) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7fde1e8fea80) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7fde1e94a2d8) 0 + std::__atomic_flag_base (0x0x7fde1e8feae0) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7fde1e94aa28) 0 + QAtomicInteger (0x0x7fde1e94aa90) 0 + QBasicAtomicInteger (0x0x7fde1e4e2240) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7fde1e40f7e0) 0 empty + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7fde1e1949c0) 0 + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7fde1e194ae0) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7fde1e4d1680) 0 + QGenericArgument (0x0x7fde1e194b40) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7fde1e194cc0) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7fde1e194d80) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7fde1e290de0) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7fde1e290e40) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7fde1df3f120) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7fde1df3f180) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7fde1df3f4e0) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7fde1df3f540) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7fde1df3f5a0) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7fde1df3f600) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7fde1df3f660) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7fde1df3fa20) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7fde1df3ec98) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16u) + std::exception (0x0x7fde1df3fae0) 0 nearly-empty + primary-for std::logic_error (0x0x7fde1df3ec98) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7fde1df3ed00) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16u) + std::logic_error (0x0x7fde1df3ed68) 0 + primary-for std::domain_error (0x0x7fde1df3ed00) + std::exception (0x0x7fde1df3fb40) 0 nearly-empty + primary-for std::logic_error (0x0x7fde1df3ed68) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7fde1df3edd0) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16u) + std::logic_error (0x0x7fde1df3ee38) 0 + primary-for std::invalid_argument (0x0x7fde1df3edd0) + std::exception (0x0x7fde1df3fba0) 0 nearly-empty + primary-for std::logic_error (0x0x7fde1df3ee38) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7fde1df3eea0) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16u) + std::logic_error (0x0x7fde1df3ef08) 0 + primary-for std::length_error (0x0x7fde1df3eea0) + std::exception (0x0x7fde1df3fc00) 0 nearly-empty + primary-for std::logic_error (0x0x7fde1df3ef08) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7fde1df3ef70) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16u) + std::logic_error (0x0x7fde1df3e9c0) 0 + primary-for std::out_of_range (0x0x7fde1df3ef70) + std::exception (0x0x7fde1df3fc60) 0 nearly-empty + primary-for std::logic_error (0x0x7fde1df3e9c0) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7fde1df3ea90) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16u) + std::exception (0x0x7fde1df3fcc0) 0 nearly-empty + primary-for std::runtime_error (0x0x7fde1df3ea90) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7fde1e073000) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16u) + std::runtime_error (0x0x7fde1e073068) 0 + primary-for std::range_error (0x0x7fde1e073000) + std::exception (0x0x7fde1df3fd20) 0 nearly-empty + primary-for std::runtime_error (0x0x7fde1e073068) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7fde1e0730d0) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16u) + std::runtime_error (0x0x7fde1e073138) 0 + primary-for std::overflow_error (0x0x7fde1e0730d0) + std::exception (0x0x7fde1df3fd80) 0 nearly-empty + primary-for std::runtime_error (0x0x7fde1e073138) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7fde1e0731a0) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16u) + std::runtime_error (0x0x7fde1e073208) 0 + primary-for std::underflow_error (0x0x7fde1e0731a0) + std::exception (0x0x7fde1df3fde0) 0 nearly-empty + primary-for std::runtime_error (0x0x7fde1e073208) + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7fde1df3ff60) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16u) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7fde1e0881e0) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7fde1e088360) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7fde1e0736e8) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16u) + std::runtime_error (0x0x7fde1e073750) 0 + primary-for std::system_error (0x0x7fde1e0736e8) + std::exception (0x0x7fde1e0885a0) 0 nearly-empty + primary-for std::runtime_error (0x0x7fde1e073750) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7fde1dce3340) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16u) + std::system_error (0x0x7fde1dce33a8) 0 + primary-for std::ios_base::failure (0x0x7fde1dce3340) + std::runtime_error (0x0x7fde1dce3410) 0 + primary-for std::system_error (0x0x7fde1dce33a8) + std::exception (0x0x7fde1e0888a0) 0 nearly-empty + primary-for std::runtime_error (0x0x7fde1dce3410) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7fde1e088900) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7fde1e088960) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7fde1e0889c0) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7fde1e088840) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7fde1ddba180) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7fde1ddba840) 0 empty + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSo: 2u entries +0 ((& std::basic_ostream::_ZTVSo) + 24u) +8 ((& std::basic_ostream::_ZTVSo) + 64u) + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSi: 2u entries +0 ((& std::basic_istream::_ZTVSi) + 24u) +8 ((& std::basic_istream::_ZTVSi) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u) + +Construction vtable for std::basic_istream (0x0x7fde1d949f70 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd0_Si: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7fde1d949270 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd16_So: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSd: 7u entries +0 ((& std::basic_iostream::_ZTVSd) + 24u) +8 ((& std::basic_iostream::_ZTCSd0_Si) + 24u) +16 ((& std::basic_iostream::_ZTCSd0_Si) + 64u) +24 ((& std::basic_iostream::_ZTCSd16_So) + 24u) +32 ((& std::basic_iostream::_ZTCSd16_So) + 64u) +40 ((& std::basic_iostream::_ZTVSd) + 104u) +48 ((& std::basic_iostream::_ZTVSd) + 64u) + +Construction vtable for std::basic_istream (0x0x7fde1d9f8000 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7fde1d9f80d0 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries +0 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u) +16 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u) +24 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u) +32 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u) +40 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u) +48 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u) + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7fde1da120c0) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7fde1da12120) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7fde1d70a480) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7fde1d70a7e0) 0 + +Class QStringView + size=16 align=8 + base size=16 base align=8 +QStringView (0x0x7fde1d70ac60) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7fde1d832ae0) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7fde1d4eb180) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7fde1d4eb120) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7fde1d66c240) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7fde1d66ce40) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7fde1d473ae0) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7fde1d473b40) 0 empty + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7fde1d473ba0) 0 + +Class QListData::NotArrayCompatibleLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotArrayCompatibleLayout (0x0x7fde1d473f60) 0 empty + +Class QListData::NotIndirectLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotIndirectLayout (0x0x7fde1d2ce000) 0 empty + +Class QListData::ArrayCompatibleLayout + size=1 align=1 + base size=1 base align=1 +QListData::ArrayCompatibleLayout (0x0x7fde1d476c98) 0 empty + QListData::NotIndirectLayout (0x0x7fde1d2ce060) 0 empty + +Class QListData::InlineWithPaddingLayout + size=1 align=1 + base size=1 base align=1 +QListData::InlineWithPaddingLayout (0x0x7fde1d2cc3f0) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7fde1d2ce0c0) 0 empty + QListData::NotIndirectLayout (0x0x7fde1d2ce120) 0 empty + +Class QListData::IndirectLayout + size=1 align=1 + base size=1 base align=1 +QListData::IndirectLayout (0x0x7fde1d476d00) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7fde1d2ce180) 0 empty + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7fde1d2ce1e0) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7fde1d473f00) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7fde1d2ce660) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7fde1d07f8a0) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7fde1d07f840) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7fde1d087750) 0 + QList (0x0x7fde1d0877b8) 0 + QListSpecialMethods (0x0x7fde1d07fa80) 0 empty + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7fde1d07fea0) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7fde1cd2ea80) 0 + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7fde1cb19120) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7fde1cb192a0) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7fde1cb19360) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7fde1d087c98) 0 + std::__uses_alloc_base (0x0x7fde1cb19300) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7fde1cc313c0) 0 empty + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7fde1cc31600) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7fde1cc316c0) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7fde1cc317e0) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7fde1cc31960) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7fde1cc31d80) 0 + +Class QtMetaTypePrivate::VectorBoolElements + size=1 align=1 + base size=0 base align=1 +QtMetaTypePrivate::VectorBoolElements (0x0x7fde1cc31ea0) 0 empty + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7fde1c992840) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7fde1c992c60) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7fde1c992f60) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7fde1c89e960) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7fde1c6077e0) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7fde1c607840) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16u) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7fde1c607a20) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7fde1c6079c0) 0 + vptr=((& QObject::_ZTV7QObject) + 16u) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7fde1c6cfcc0) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7fde1c6cfd20) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7fde1c6cfde0) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7fde1c3012d8) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u) + QObject (0x0x7fde1c6cfd80) 0 + primary-for QAbstractAnimation (0x0x7fde1c3012d8) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7fde1c6cfea0) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7fde1c301340) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16u) + QObject (0x0x7fde1c6cfe40) 0 + primary-for QAnimationDriver (0x0x7fde1c301340) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7fde1c6cff60) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7fde1c3013a8) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u) + QObject (0x0x7fde1c6cff00) 0 + primary-for QEventLoop (0x0x7fde1c3013a8) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7fde1c35d180) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7fde1c35d240) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7fde1c35d2a0) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7fde1c3014e0) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u) + QObject (0x0x7fde1c35d1e0) 0 + primary-for QAbstractEventDispatcher (0x0x7fde1c3014e0) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7fde1c35d540) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16u) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7fde1c3016e8) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16u) + std::exception (0x0x7fde1c35d5a0) 0 nearly-empty + primary-for std::bad_cast (0x0x7fde1c3016e8) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7fde1c301750) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16u) + std::exception (0x0x7fde1c35d600) 0 nearly-empty + primary-for std::bad_typeid (0x0x7fde1c301750) + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7fde1c4729c0) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16u) + std::exception (0x0x7fde1c0fc6c0) 0 nearly-empty + primary-for std::bad_function_call (0x0x7fde1c4729c0) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7fde1c0fc780) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7fde1c0fc7e0) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7fde1c0fc900) 0 + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7fde1c0fcde0) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7fde1c1d7360) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7fde1c1d7720) 0 + +Class QHashData + size=48 align=8 + base size=44 base align=8 +QHashData (0x0x7fde1c1d76c0) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7fde1c1d7780) 0 empty + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7fde1bfec060) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7fde1bfec120) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7fde1bfec0c0) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7fde1bfec180) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7fde1bfec000) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7fde1c0bfc60) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7fde1bd63300) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7fde1bd632a0) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7fde1bd633c0) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7fde1bd63360) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7fde1be896c0) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7fde1be89d80) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7fde1bc724e0) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7fde1bc73750) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u) + QObject (0x0x7fde1bc72480) 0 + primary-for QAbstractItemModel (0x0x7fde1bc73750) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7fde1bc72d80) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7fde1bc73e38) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u) + QAbstractItemModel (0x0x7fde1bc73ea0) 0 + primary-for QAbstractTableModel (0x0x7fde1bc73e38) + QObject (0x0x7fde1bc72d20) 0 + primary-for QAbstractItemModel (0x0x7fde1bc73ea0) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7fde1bc72e40) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7fde1bc73f08) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u) + QAbstractItemModel (0x0x7fde1bc73f70) 0 + primary-for QAbstractListModel (0x0x7fde1bc73f08) + QObject (0x0x7fde1bc72de0) 0 + primary-for QAbstractItemModel (0x0x7fde1bc73f70) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7fde1b985120) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16u) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7fde1b9851e0) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7fde1b9810d0) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16u) + QAbstractItemModel (0x0x7fde1b981138) 0 + primary-for QAbstractProxyModel (0x0x7fde1b9810d0) + QObject (0x0x7fde1b985180) 0 + primary-for QAbstractItemModel (0x0x7fde1b981138) + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7fde1b9852a0) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7fde1b9811a0) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u) + QObject (0x0x7fde1b985240) 0 + primary-for QAbstractState (0x0x7fde1b9811a0) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7fde1b985360) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7fde1b981208) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u) + QObject (0x0x7fde1b985300) 0 + primary-for QAbstractTransition (0x0x7fde1b981208) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7fde1b985420) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7fde1b981270) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u) + QAbstractAnimation (0x0x7fde1b9812d8) 0 + primary-for QAnimationGroup (0x0x7fde1b981270) + QObject (0x0x7fde1b9853c0) 0 + primary-for QAbstractAnimation (0x0x7fde1b9812d8) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7fde1ba42180) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7fde1ba42420) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7fde1ba424e0) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7fde1ba427e0) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7fde1b981958) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16u) + QObject (0x0x7fde1ba42780) 0 + primary-for QIODevice (0x0x7fde1b981958) + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7fde1ba42a20) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7fde1b981a90) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16u) + QIODevice (0x0x7fde1b981af8) 0 + primary-for QBuffer (0x0x7fde1b981a90) + QObject (0x0x7fde1ba429c0) 0 + primary-for QIODevice (0x0x7fde1b981af8) + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7fde1ba42ae0) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7fde1ba42a80) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7fde1ba42c00) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7fde1ba42ba0) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7fde1ba42de0) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7fde1b7af000) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7fde1b7af2a0) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7fde1b7afa20) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7fde1b7afa80) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7fde1b7af9c0) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7fde1b893ba0) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7fde1b55d1e0) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16u) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7fde1b55d480) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7fde1b55d6c0) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7fde1b55dd80) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7fde1b55df00) 0 + +Class QDebug::Stream + size=80 align=8 + base size=76 base align=8 +QDebug::Stream (0x0x7fde1b2e8480) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7fde1b2e8420) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7fde1b0ea780) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7fde1b0ea840) 0 empty + +Class QCborError + size=4 align=4 + base size=4 base align=4 +QCborError (0x0x7fde1b16eba0) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7fde1b16ed20) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7fde1b1e3360) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7fde1b1e3660) 0 + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7fde1b1e3a20) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7fde1af6c120) 0 + +Class QCborParserError + size=16 align=8 + base size=12 base align=8 +QCborParserError (0x0x7fde1af6c720) 0 + +Class QCborValue + size=24 align=8 + base size=20 base align=8 +QCborValue (0x0x7fde1af6c780) 0 + +Class QCborValueRef + size=16 align=8 + base size=16 base align=8 +QCborValueRef (0x0x7fde1ae22780) 0 + +Class QCborArray::Iterator + size=16 align=8 + base size=16 base align=8 +QCborArray::Iterator (0x0x7fde1ae22d20) 0 + +Class QCborArray::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborArray::ConstIterator (0x0x7fde1ae22d80) 0 + +Class QCborArray + size=8 align=8 + base size=8 base align=8 +QCborArray (0x0x7fde1ae22cc0) 0 + +Class QCborMap::Iterator + size=16 align=8 + base size=16 base align=8 +QCborMap::Iterator (0x0x7fde1ab57de0) 0 + +Class QCborMap::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborMap::ConstIterator (0x0x7fde1ab57e40) 0 + +Class QCborMap + size=8 align=8 + base size=8 base align=8 +QCborMap (0x0x7fde1ab57d80) 0 + +Class qfloat16 + size=2 align=2 + base size=2 base align=2 +qfloat16 (0x0x7fde1a91c9c0) 0 + +Class QCborStreamWriter + size=8 align=8 + base size=8 base align=8 +QCborStreamWriter (0x0x7fde1a91cd80) 0 + +Class QCborStreamReader + size=24 align=8 + base size=20 base align=8 +QCborStreamReader (0x0x7fde1aa71780) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7fde1aa71de0) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7fde1aa71ea0) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7fde1a769ea0) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7fde1a7b0360) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16u) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7fde1a7b50d0) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u) + QEvent (0x0x7fde1a7b03c0) 0 + primary-for QTimerEvent (0x0x7fde1a7b50d0) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7fde1a7b5138) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u) + QEvent (0x0x7fde1a7b0420) 0 + primary-for QChildEvent (0x0x7fde1a7b5138) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7fde1a7b5680) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u) + QEvent (0x0x7fde1a7b0900) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7fde1a7b5680) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7fde1a7b56e8) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16u) + QEvent (0x0x7fde1a7b0960) 0 + primary-for QDeferredDeleteEvent (0x0x7fde1a7b56e8) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7fde1a7b0a20) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7fde1a7b5750) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u) + QObject (0x0x7fde1a7b09c0) 0 + primary-for QCoreApplication (0x0x7fde1a7b5750) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7fde1a7b0a80) 0 + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7fde1a7b0ae0) 0 + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7fde1a7b0b40) 0 + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7fde1a7b0c00) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7fde1a888120) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7fde1a888600) 0 + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7fde1a5f6480) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7fde1a5ecbc8) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16u) + QIODevice (0x0x7fde1a5ecc30) 0 + primary-for QFileDevice (0x0x7fde1a5ecbc8) + QObject (0x0x7fde1a5f6420) 0 + primary-for QIODevice (0x0x7fde1a5ecc30) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7fde1a5f66c0) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7fde1a5ecd68) 0 + vptr=((& QFile::_ZTV5QFile) + 16u) + QFileDevice (0x0x7fde1a5ecdd0) 0 + primary-for QFile (0x0x7fde1a5ecd68) + QIODevice (0x0x7fde1a5ece38) 0 + primary-for QFileDevice (0x0x7fde1a5ecdd0) + QObject (0x0x7fde1a5f6660) 0 + primary-for QIODevice (0x0x7fde1a5ece38) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7fde1a5f68a0) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7fde1a5f6cc0) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7fde1a2f8300) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7fde1a2f8540) 0 + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7fde1a3ff960) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7fde1a3fbe38) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u) + QAbstractTransition (0x0x7fde1a3fbea0) 0 + primary-for QEventTransition (0x0x7fde1a3fbe38) + QObject (0x0x7fde1a3ff900) 0 + primary-for QAbstractTransition (0x0x7fde1a3fbea0) + +Vtable for QException +QException::_ZTV10QException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7fde1a3fbf08) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16u) + std::exception (0x0x7fde1a3ff9c0) 0 nearly-empty + primary-for QException (0x0x7fde1a3fbf08) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7fde1a3fbf70) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16u) + QException (0x0x7fde1a476000) 0 nearly-empty + primary-for QUnhandledException (0x0x7fde1a3fbf70) + std::exception (0x0x7fde1a3ffa20) 0 nearly-empty + primary-for QException (0x0x7fde1a476000) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7fde1a3ffa80) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7fde1a3ffb40) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7fde1a3ffba0) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7fde1a3ffcc0) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7fde1a476068) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16u) + QObject (0x0x7fde1a3ffc60) 0 + primary-for QFileSelector (0x0x7fde1a476068) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7fde1a3ffd80) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7fde1a4760d0) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u) + QObject (0x0x7fde1a3ffd20) 0 + primary-for QFileSystemWatcher (0x0x7fde1a4760d0) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7fde1a3ffe40) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7fde1a476138) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16u) + QAbstractState (0x0x7fde1a4761a0) 0 + primary-for QFinalState (0x0x7fde1a476138) + QObject (0x0x7fde1a3ffde0) 0 + primary-for QAbstractState (0x0x7fde1a4761a0) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7fde1a3ffea0) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16u) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7fde1a3fff00) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7fde1a4762d8) 0 + QBasicMutex (0x0x7fde1a0c9120) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7fde1a0c9180) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7fde1a0c91e0) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7fde1a0c9240) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7fde1a0c9360) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16u) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7fde1a0c9ba0) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7fde1a2313c0) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0u +48 0u +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7fde1a232410) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u) + QObject (0x0x7fde1a231360) 0 + primary-for QFutureWatcherBase (0x0x7fde1a232410) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7fde1a2319c0) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7fde1a232d00) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u) + QAbstractState (0x0x7fde1a232d68) 0 + primary-for QHistoryState (0x0x7fde1a232d00) + QObject (0x0x7fde1a231960) 0 + primary-for QAbstractState (0x0x7fde1a232d68) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7fde1a231a80) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7fde1a232dd0) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16u) + QAbstractProxyModel (0x0x7fde1a232e38) 0 + primary-for QIdentityProxyModel (0x0x7fde1a232dd0) + QAbstractItemModel (0x0x7fde1a232ea0) 0 + primary-for QAbstractProxyModel (0x0x7fde1a232e38) + QObject (0x0x7fde1a231a20) 0 + primary-for QAbstractItemModel (0x0x7fde1a232ea0) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7fde1a231ae0) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7fde19f101e0) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7fde19edd6e8) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u) + QObject (0x0x7fde19f10180) 0 + primary-for QItemSelectionModel (0x0x7fde19edd6e8) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7fde19edd8f0) 0 + QList (0x0x7fde19edd958) 0 + QListSpecialMethods (0x0x7fde19f104e0) 0 empty + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7fde19f109c0) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7fde19d12120) 0 + +Class QJsonValuePtr + size=24 align=8 + base size=24 base align=8 +QJsonValuePtr (0x0x7fde19d12660) 0 + +Class QJsonValueRefPtr + size=16 align=8 + base size=16 base align=8 +QJsonValueRefPtr (0x0x7fde19d126c0) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7fde19d128a0) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7fde19d12900) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7fde19d12840) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7fde19e26b40) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7fde19e26ba0) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7fde19ea1240) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7fde19ea12a0) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7fde19ea11e0) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7fde19b56540) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7fde19b4dc98) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16u) + QObject (0x0x7fde19b564e0) 0 + primary-for QLibrary (0x0x7fde19b4dc98) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7fde19b56c00) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7fde19b56720) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7fde19c4d120) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7fde19c4d180) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7fde19c4d420) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7fde19c4da20) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7fde198ea3c0) 0 + +Class QLinkedListData + size=32 align=8 + base size=25 base align=8 +QLinkedListData (0x0x7fde198ea9c0) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7fde198ead20) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7fde198eaea0) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7fde198eae40) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7fde19a6c060) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7fde19a6c300) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7fde19a6c960) 0 + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7fde19a6c9c0) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7fde1965e000) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7fde1965e300) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7fde1965e360) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7fde1965e660) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7fde195c4f08) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16u) + QObject (0x0x7fde1965e600) 0 + primary-for QMimeData (0x0x7fde195c4f08) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7fde1965e6c0) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7fde1965e9c0) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7fde1965ea80) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7fde196b1138) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u) + QObject (0x0x7fde1965ea20) 0 + primary-for QObjectCleanupHandler (0x0x7fde196b1138) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7fde1965eae0) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7fde196f62a0) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7fde196b1888) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u) + QAnimationGroup (0x0x7fde196b18f0) 0 + primary-for QParallelAnimationGroup (0x0x7fde196b1888) + QAbstractAnimation (0x0x7fde196b1958) 0 + primary-for QAnimationGroup (0x0x7fde196b18f0) + QObject (0x0x7fde196f6240) 0 + primary-for QAbstractAnimation (0x0x7fde196b1958) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7fde196f6360) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7fde196b19c0) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u) + QAbstractAnimation (0x0x7fde196b1a28) 0 + primary-for QPauseAnimation (0x0x7fde196b19c0) + QObject (0x0x7fde196f6300) 0 + primary-for QAbstractAnimation (0x0x7fde196b1a28) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7fde196f6540) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7fde196f6840) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7fde196b1c30) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u) + QObject (0x0x7fde196f67e0) 0 + primary-for QPluginLoader (0x0x7fde196b1c30) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7fde196f68a0) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7fde196f6f60) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7fde19767270) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16u) + QIODevice (0x0x7fde197672d8) 0 + primary-for QProcess (0x0x7fde19767270) + QObject (0x0x7fde196f6f00) 0 + primary-for QIODevice (0x0x7fde197672d8) + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7fde197a9060) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7fde19767340) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u) + QAbstractAnimation (0x0x7fde197673a8) 0 + primary-for QVariantAnimation (0x0x7fde19767340) + QObject (0x0x7fde197a9000) 0 + primary-for QAbstractAnimation (0x0x7fde197673a8) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7fde197a9120) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7fde19767478) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u) + QVariantAnimation (0x0x7fde197674e0) 0 + primary-for QPropertyAnimation (0x0x7fde19767478) + QAbstractAnimation (0x0x7fde19767548) 0 + primary-for QVariantAnimation (0x0x7fde197674e0) + QObject (0x0x7fde197a90c0) 0 + primary-for QAbstractAnimation (0x0x7fde19767548) + +Class QRandomGenerator::Storage + size=2504 align=8 + base size=2504 base align=8 +QRandomGenerator::Storage (0x0x7fde197a9240) 0 + +Class QRandomGenerator + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator (0x0x7fde197a91e0) 0 + +Class QRandomGenerator64 + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator64 (0x0x7fde19449820) 0 + QRandomGenerator (0x0x7fde194621e0) 0 + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7fde194622a0) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7fde19462540) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7fde19462600) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7fde194626c0) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7fde19462960) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7fde19462c00) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7fde19462ea0) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7fde19257180) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7fde19257300) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7fde195963a8) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16u) + QFileDevice (0x0x7fde19596410) 0 + primary-for QSaveFile (0x0x7fde195963a8) + QIODevice (0x0x7fde19596478) 0 + primary-for QFileDevice (0x0x7fde19596410) + QObject (0x0x7fde192572a0) 0 + primary-for QIODevice (0x0x7fde19596478) + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7fde19257420) 0 + +Class QSemaphoreReleaser + size=16 align=8 + base size=12 base align=8 +QSemaphoreReleaser (0x0x7fde192575a0) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7fde1900fba0) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7fde19014d00) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u) + QAnimationGroup (0x0x7fde19014d68) 0 + primary-for QSequentialAnimationGroup (0x0x7fde19014d00) + QAbstractAnimation (0x0x7fde19014dd0) 0 + primary-for QAnimationGroup (0x0x7fde19014d68) + QObject (0x0x7fde1900fb40) 0 + primary-for QAbstractAnimation (0x0x7fde19014dd0) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7fde1900fc60) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7fde19014e38) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16u) + QObject (0x0x7fde1900fc00) 0 + primary-for QSettings (0x0x7fde19014e38) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7fde1900fd20) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7fde19014ea0) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u) + QObject (0x0x7fde1900fcc0) 0 + primary-for QSharedMemory (0x0x7fde19014ea0) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7fde1900fde0) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7fde19014f08) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u) + QObject (0x0x7fde1900fd80) 0 + primary-for QSignalMapper (0x0x7fde19014f08) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7fde1900fea0) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7fde19014f70) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u) + QAbstractTransition (0x0x7fde19081000) 0 + primary-for QSignalTransition (0x0x7fde19014f70) + QObject (0x0x7fde1900fe40) 0 + primary-for QAbstractTransition (0x0x7fde19081000) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7fde1900ff60) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7fde19081068) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u) + QObject (0x0x7fde1900ff00) 0 + primary-for QSocketNotifier (0x0x7fde19081068) + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7fde190a1060) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7fde190810d0) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16u) + QAbstractProxyModel (0x0x7fde19081138) 0 + primary-for QSortFilterProxyModel (0x0x7fde190810d0) + QAbstractItemModel (0x0x7fde190811a0) 0 + primary-for QAbstractProxyModel (0x0x7fde19081138) + QObject (0x0x7fde190a1000) 0 + primary-for QAbstractItemModel (0x0x7fde190811a0) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7fde190a1120) 0 empty + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7fde190a1360) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7fde19081340) 0 + vptr=((& QState::_ZTV6QState) + 16u) + QAbstractState (0x0x7fde190813a8) 0 + primary-for QState (0x0x7fde19081340) + QObject (0x0x7fde190a1300) 0 + primary-for QAbstractState (0x0x7fde190813a8) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7fde190a1480) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7fde19081548) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u) + QEvent (0x0x7fde190a14e0) 0 + primary-for QStateMachine::SignalEvent (0x0x7fde19081548) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7fde190815b0) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u) + QEvent (0x0x7fde190a1540) 0 + primary-for QStateMachine::WrappedEvent (0x0x7fde190815b0) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7fde19081410) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u) + QState (0x0x7fde19081478) 0 + primary-for QStateMachine (0x0x7fde19081410) + QAbstractState (0x0x7fde190814e0) 0 + primary-for QState (0x0x7fde19081478) + QObject (0x0x7fde190a1420) 0 + primary-for QAbstractState (0x0x7fde190814e0) + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7fde190a15a0) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7fde191894e0) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7fde18e138a0) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7fde18e1f5b0) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u) + QAbstractListModel (0x0x7fde18e1f618) 0 + primary-for QStringListModel (0x0x7fde18e1f5b0) + QAbstractItemModel (0x0x7fde18e1f680) 0 + primary-for QAbstractListModel (0x0x7fde18e1f618) + QObject (0x0x7fde18e13840) 0 + primary-for QAbstractItemModel (0x0x7fde18e1f680) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7fde18e13900) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7fde18e139c0) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7fde18e13ae0) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7fde18e1f6e8) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u) + QFile (0x0x7fde18e1f750) 0 + primary-for QTemporaryFile (0x0x7fde18e1f6e8) + QFileDevice (0x0x7fde18e1f7b8) 0 + primary-for QFile (0x0x7fde18e1f750) + QIODevice (0x0x7fde18e1f820) 0 + primary-for QFileDevice (0x0x7fde18e1f7b8) + QObject (0x0x7fde18e13a80) 0 + primary-for QIODevice (0x0x7fde18e1f820) + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7fde18e13b40) 0 + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7fde18e13d80) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 0u +64 0u + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7fde18e13d20) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7fde18e13f60) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7fde18eff000) 0 + +Class std::__mutex_base + size=40 align=8 + base size=40 base align=8 +std::__mutex_base (0x0x7fde18eff060) 0 + +Class std::__recursive_mutex_base + size=40 align=8 + base size=40 base align=8 +std::__recursive_mutex_base (0x0x7fde18eff0c0) 0 + +Class std::mutex + size=40 align=8 + base size=40 base align=8 +std::mutex (0x0x7fde18e1fa28) 0 + std::__mutex_base (0x0x7fde18eff120) 0 + +Class std::recursive_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_mutex (0x0x7fde18e1fa90) 0 + std::__recursive_mutex_base (0x0x7fde18eff180) 0 + +Class std::timed_mutex + size=40 align=8 + base size=40 base align=8 +std::timed_mutex (0x0x7fde18f254d0) 0 + std::__mutex_base (0x0x7fde18eff2a0) 0 + std::__timed_mutex_impl (0x0x7fde18eff300) 0 empty + +Class std::recursive_timed_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_timed_mutex (0x0x7fde18f25e70) 0 + std::__recursive_mutex_base (0x0x7fde18eff3c0) 0 + std::__timed_mutex_impl (0x0x7fde18eff420) 0 empty + +Class std::defer_lock_t + size=1 align=1 + base size=0 base align=1 +std::defer_lock_t (0x0x7fde18eff480) 0 empty + +Class std::try_to_lock_t + size=1 align=1 + base size=0 base align=1 +std::try_to_lock_t (0x0x7fde18eff4e0) 0 empty + +Class std::adopt_lock_t + size=1 align=1 + base size=0 base align=1 +std::adopt_lock_t (0x0x7fde18eff540) 0 empty + +Class std::once_flag + size=4 align=4 + base size=4 base align=4 +std::once_flag (0x0x7fde18eff780) 0 + +Vtable for __gnu_cxx::__concurrence_lock_error +__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what + +Class __gnu_cxx::__concurrence_lock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_lock_error (0x0x7fde18e1fbc8) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16u) + std::exception (0x0x7fde18eff840) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_lock_error (0x0x7fde18e1fbc8) + +Vtable for __gnu_cxx::__concurrence_unlock_error +__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what + +Class __gnu_cxx::__concurrence_unlock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_unlock_error (0x0x7fde18e1fc30) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16u) + std::exception (0x0x7fde18eff900) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7fde18e1fc30) + +Vtable for __gnu_cxx::__concurrence_broadcast_error +__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what + +Class __gnu_cxx::__concurrence_broadcast_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_broadcast_error (0x0x7fde18e1fc98) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16u) + std::exception (0x0x7fde18eff9c0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7fde18e1fc98) + +Vtable for __gnu_cxx::__concurrence_wait_error +__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what + +Class __gnu_cxx::__concurrence_wait_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_wait_error (0x0x7fde18e1fd68) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16u) + std::exception (0x0x7fde18effa80) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_wait_error (0x0x7fde18e1fd68) + +Class __gnu_cxx::__mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__mutex (0x0x7fde18effb40) 0 + +Class __gnu_cxx::__recursive_mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__recursive_mutex (0x0x7fde18effba0) 0 + +Class __gnu_cxx::__scoped_lock + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__scoped_lock (0x0x7fde18effc00) 0 + +Class __gnu_cxx::__cond + size=48 align=8 + base size=48 base align=8 +__gnu_cxx::__cond (0x0x7fde18effc60) 0 + +Vtable for std::bad_weak_ptr +std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12bad_weak_ptr) +16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +32 (int (*)(...))std::bad_weak_ptr::what + +Class std::bad_weak_ptr + size=8 align=8 + base size=8 base align=8 +std::bad_weak_ptr (0x0x7fde18e1fea0) 0 nearly-empty + vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16u) + std::exception (0x0x7fde18c59000) 0 nearly-empty + primary-for std::bad_weak_ptr (0x0x7fde18e1fea0) + +Class std::_Sp_make_shared_tag + size=1 align=1 + base size=0 base align=1 +std::_Sp_make_shared_tag (0x0x7fde18c59840) 0 empty + +Class std::_Sp_locker + size=2 align=1 + base size=2 base align=1 +std::_Sp_locker (0x0x7fde189d6060) 0 + +Class std::thread::id + size=8 align=8 + base size=8 base align=8 +std::thread::id (0x0x7fde189d6240) 0 + +Vtable for std::thread::_Impl_base +std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6thread10_Impl_baseE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class std::thread::_Impl_base + size=24 align=8 + base size=24 base align=8 +std::thread::_Impl_base (0x0x7fde189d62a0) 0 + vptr=((& std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE) + 16u) + +Class std::thread + size=8 align=8 + base size=8 base align=8 +std::thread (0x0x7fde189d61e0) 0 + +Class std::condition_variable + size=48 align=8 + base size=48 base align=8 +std::condition_variable (0x0x7fde18b40ea0) 0 + +Class std::__at_thread_exit_elt + size=16 align=8 + base size=16 base align=8 +std::__at_thread_exit_elt (0x0x7fde18b40f60) 0 + +Class std::_V2::condition_variable_any + size=64 align=8 + base size=64 base align=8 +std::_V2::condition_variable_any (0x0x7fde18ba7000) 0 + +Class std::__atomic_futex_unsigned_base + size=1 align=1 + base size=0 base align=1 +std::__atomic_futex_unsigned_base (0x0x7fde1880e660) 0 empty + +Vtable for std::future_error +std::future_error::_ZTVSt12future_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12future_error) +16 (int (*)(...))std::future_error::~future_error +24 (int (*)(...))std::future_error::~future_error +32 (int (*)(...))std::future_error::what + +Class std::future_error + size=32 align=8 + base size=32 base align=8 +std::future_error (0x0x7fde188163a8) 0 + vptr=((& std::future_error::_ZTVSt12future_error) + 16u) + std::logic_error (0x0x7fde18816410) 0 + primary-for std::future_error (0x0x7fde188163a8) + std::exception (0x0x7fde1880e780) 0 nearly-empty + primary-for std::logic_error (0x0x7fde18816410) + +Class std::__future_base::_Result_base::_Deleter + size=1 align=1 + base size=0 base align=1 +std::__future_base::_Result_base::_Deleter (0x0x7fde1880e8a0) 0 empty + +Vtable for std::__future_base::_Result_base +std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class std::__future_base::_Result_base + size=16 align=8 + base size=16 base align=8 +std::__future_base::_Result_base (0x0x7fde1880e840) 0 + vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16u) + +Class std::__future_base::_State_baseV2::__exception_ptr_tag + size=1 align=1 + base size=0 base align=1 +std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7fde18927de0) 0 empty + +Class std::__future_base::_State_baseV2::_Make_ready + size=32 align=8 + base size=32 base align=8 +std::__future_base::_State_baseV2::_Make_ready (0x0x7fde1896e9c0) 0 + std::__at_thread_exit_elt (0x0x7fde18927ea0) 0 + +Vtable for std::__future_base::_State_baseV2 +std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E) +16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_State_baseV2 + size=32 align=8 + base size=28 base align=8 +std::__future_base::_State_baseV2 (0x0x7fde1880ea20) 0 + vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16u) + +Class std::__future_base + size=1 align=1 + base size=0 base align=1 +std::__future_base (0x0x7fde1880e7e0) 0 empty + +Vtable for std::__future_base::_Async_state_commonV2 +std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E) +16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_Async_state_commonV2 + size=48 align=8 + base size=44 base align=8 +std::__future_base::_Async_state_commonV2 (0x0x7fde182ed5b0) 0 + vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16u) + std::__future_base::_State_baseV2 (0x0x7fde182d7d80) 0 + primary-for std::__future_base::_Async_state_commonV2 (0x0x7fde182ed5b0) + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7fde183424e0) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7fde1836f068) 0 + vptr=((& QThread::_ZTV7QThread) + 16u) + QObject (0x0x7fde18342480) 0 + primary-for QThread (0x0x7fde1836f068) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7fde18342600) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7fde1836f0d0) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u) + QObject (0x0x7fde183425a0) 0 + primary-for QThreadPool (0x0x7fde1836f0d0) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7fde18342660) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7fde18342780) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7fde1836f138) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u) + QObject (0x0x7fde18342720) 0 + primary-for QTimeLine (0x0x7fde1836f138) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7fde18342840) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7fde1836f1a0) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16u) + QObject (0x0x7fde183427e0) 0 + primary-for QTimer (0x0x7fde1836f1a0) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7fde18342f60) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7fde18342f00) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7fde18021540) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7fde1836fd68) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16u) + QObject (0x0x7fde180214e0) 0 + primary-for QTranslator (0x0x7fde1836fd68) + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7fde180215a0) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7fde18021c00) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7fde18021c60) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7fde18021f00) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7fde18071a28) 0 + QVector (0x0x7fde180de300) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7fde180de360) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7fde180de600) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7fde180de8a0) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7fde180deb40) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7fde180deba0) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7fde17dbd600) 0 + +Class QAbstractItemModelTester::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModelTester::QPrivateSignal (0x0x7fde17dbd780) 0 empty + +Vtable for QAbstractItemModelTester +QAbstractItemModelTester::_ZTV24QAbstractItemModelTester: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractItemModelTester) +16 (int (*)(...))QAbstractItemModelTester::metaObject +24 (int (*)(...))QAbstractItemModelTester::qt_metacast +32 (int (*)(...))QAbstractItemModelTester::qt_metacall +40 (int (*)(...))QAbstractItemModelTester::~QAbstractItemModelTester +48 (int (*)(...))QAbstractItemModelTester::~QAbstractItemModelTester +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QAbstractItemModelTester + size=16 align=8 + base size=16 base align=8 +QAbstractItemModelTester (0x0x7fde18191af8) 0 + vptr=((& QAbstractItemModelTester::_ZTV24QAbstractItemModelTester) + 16u) + QObject (0x0x7fde17dbd720) 0 + primary-for QAbstractItemModelTester (0x0x7fde18191af8) + +Class QTest::QBenchmarkIterationController + size=4 align=4 + base size=4 base align=4 +QTest::QBenchmarkIterationController (0x0x7fde17dbd7e0) 0 + +Class QTestEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTestEventLoop::QPrivateSignal (0x0x7fde17dbd8a0) 0 empty + +Vtable for QTestEventLoop +QTestEventLoop::_ZTV14QTestEventLoop: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTestEventLoop) +16 (int (*)(...))QTestEventLoop::metaObject +24 (int (*)(...))QTestEventLoop::qt_metacast +32 (int (*)(...))QTestEventLoop::qt_metacall +40 (int (*)(...))QTestEventLoop::~QTestEventLoop +48 (int (*)(...))QTestEventLoop::~QTestEventLoop +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTestEventLoop::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTestEventLoop + size=32 align=8 + base size=32 base align=8 +QTestEventLoop (0x0x7fde18191b60) 0 + vptr=((& QTestEventLoop::_ZTV14QTestEventLoop) + 16u) + QObject (0x0x7fde17dbd840) 0 + primary-for QTestEventLoop (0x0x7fde18191b60) + +Vtable for QSignalSpy +QSignalSpy::_ZTV10QSignalSpy: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QSignalSpy) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QSignalSpy::qt_metacall +40 (int (*)(...))QSignalSpy::~QSignalSpy +48 (int (*)(...))QSignalSpy::~QSignalSpy +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalSpy + size=80 align=8 + base size=73 base align=8 +QSignalSpy (0x0x7fde17e8c230) 0 + vptr=((& QSignalSpy::_ZTV10QSignalSpy) + 16u) + QObject (0x0x7fde17e667e0) 0 + primary-for QSignalSpy (0x0x7fde17e8c230) + QList > (0x0x7fde17e58bc8) 16 + QListSpecialMethods > (0x0x7fde17e66840) 16 empty + +Class QTestData + size=8 align=8 + base size=8 base align=8 +QTestData (0x0x7fde17ee3900) 0 + diff --git a/tests/auto/bic/data/QtWidgets.5.12.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtWidgets.5.12.0.linux-gcc-amd64.txt new file mode 100644 index 0000000000..4e51564cec --- /dev/null +++ b/tests/auto/bic/data/QtWidgets.5.12.0.linux-gcc-amd64.txt @@ -0,0 +1,19191 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7f58e1213120) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7f58e12598a0) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7f58e1259ae0) 0 empty + +Class std::__do_is_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_default_constructible_impl (0x0x7f58e1259d20) 0 empty + +Class std::__do_is_static_castable_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_static_castable_impl (0x0x7f58e1259f60) 0 empty + +Class std::__do_is_direct_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_direct_constructible_impl (0x0x7f58e1285120) 0 empty + +Class std::__do_is_nary_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nary_constructible_impl (0x0x7f58e12854e0) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7f58e1312c60) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7f58e1312d20) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7f58e13400c0) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7f58e1340180) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7f58e1340240) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7f58e1340300) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7f58e13405a0) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7f58e1340780) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7f58e1340c00) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7f58e1340c60) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7f58e0ef4900) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7f58e0ef4960) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7f58e12e3a90) 0 empty + std::input_iterator_tag (0x0x7f58e0ef49c0) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7f58e12e3af8) 0 empty + std::forward_iterator_tag (0x0x7f58e12e3b60) 0 empty + std::input_iterator_tag (0x0x7f58e0ef4a20) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7f58e12e3bc8) 0 empty + std::bidirectional_iterator_tag (0x0x7f58e12e3c30) 0 empty + std::forward_iterator_tag (0x0x7f58e12e3c98) 0 empty + std::input_iterator_tag (0x0x7f58e0ef4a80) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7f58e0f32720) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7f58e0f32780) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7f58e0f327e0) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7f58e0f32840) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7f58e0f328a0) 0 empty + +Class wait + size=4 align=4 + base size=4 base align=4 +wait (0x0x7f58e10253c0) 0 + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7f58e1025600) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7f58e10256c0) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7f58e1025720) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7f58e10257e0) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7f58e1025840) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7f58e1025cc0) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7f58e1025d20) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7f58e1025d80) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16u) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7f58e0f65208) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u) + std::exception (0x0x7f58e1025de0) 0 nearly-empty + primary-for std::bad_exception (0x0x7f58e0f65208) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7f58e1025e40) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7f58e1025ea0) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16u) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7f58e0f65410) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u) + std::exception (0x0x7f58e0d76300) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f58e0f65410) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7f58e0f65478) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16u) + std::bad_alloc (0x0x7f58e0f654e0) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7f58e0f65478) + std::exception (0x0x7f58e0d76360) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f58e0f654e0) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7f58e0d763c0) 0 empty + +Class __exception + size=40 align=8 + base size=40 base align=8 +__exception (0x0x7f58e0a88000) 0 + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7f58e0a88cc0) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7f58e0a88d20) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7f58e0c7bc00) 0 + +Class __sched_param + size=4 align=4 + base size=4 base align=4 +__sched_param (0x0x7f58e0c7bc60) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7f58e0c7bd20) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7f58e0c7bd80) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7f58e0c7bde0) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7f58e0c7be40) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7f58e0c7bf60) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7f58e0926000) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7f58e0926420) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7f58e0926480) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7f58e07cbc60) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7f58e07cbcc0) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7f58e0813c60) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7f58e05cfa80) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7f58e067e0d0) 0 + std::iterator (0x0x7f58e05cfb40) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7f58e067e138) 0 + std::_Bit_iterator_base (0x0x7f58e067e1a0) 0 + std::iterator (0x0x7f58e05cfba0) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7f58e067e208) 0 + std::_Bit_iterator_base (0x0x7f58e067e270) 0 + std::iterator (0x0x7f58e05cfc00) 0 empty + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7f58e03b9a20) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7f58e00de7e0) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7f58e00de780) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7f58dfe9d780) 0 + +Class qIsNull(double)::U + size=8 align=8 + base size=8 base align=8 +qIsNull(double)::U (0x0x7f58deab62a0) 0 + +Class qIsNull(float)::U + size=4 align=4 + base size=4 base align=4 +qIsNull(float)::U (0x0x7f58deab6300) 0 + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7f58deb5cd80) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7f58deb5cde0) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7f58deb5ce40) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7f58deb5cea0) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7f58debc9180) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7f58debc96c0) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7f58debd4138) 0 + std::__atomic_flag_base (0x0x7f58debc9720) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7f58debd4888) 0 + QAtomicInteger (0x0x7f58debd48f0) 0 + QBasicAtomicInteger (0x0x7f58de977e40) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7f58de2fa420) 0 empty + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7f58de43a600) 0 + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7f58de43a720) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7f58de4154e0) 0 + QGenericArgument (0x0x7f58de43a780) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7f58de43a900) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7f58de43a9c0) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7f58de0e2a20) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7f58de0e2a80) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7f58de0e2d20) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7f58de0e2d80) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7f58de1fc120) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7f58de1fc180) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7f58de1fc1e0) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7f58de1fc240) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7f58de1fc2a0) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7f58de1fc660) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7f58de1c4af8) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16u) + std::exception (0x0x7f58de1fc720) 0 nearly-empty + primary-for std::logic_error (0x0x7f58de1c4af8) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7f58de1c4b60) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16u) + std::logic_error (0x0x7f58de1c4bc8) 0 + primary-for std::domain_error (0x0x7f58de1c4b60) + std::exception (0x0x7f58de1fc780) 0 nearly-empty + primary-for std::logic_error (0x0x7f58de1c4bc8) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7f58de1c4c30) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16u) + std::logic_error (0x0x7f58de1c4c98) 0 + primary-for std::invalid_argument (0x0x7f58de1c4c30) + std::exception (0x0x7f58de1fc7e0) 0 nearly-empty + primary-for std::logic_error (0x0x7f58de1c4c98) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7f58de1c4d00) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16u) + std::logic_error (0x0x7f58de1c4d68) 0 + primary-for std::length_error (0x0x7f58de1c4d00) + std::exception (0x0x7f58de1fc840) 0 nearly-empty + primary-for std::logic_error (0x0x7f58de1c4d68) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7f58de1c4dd0) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16u) + std::logic_error (0x0x7f58de1c4e38) 0 + primary-for std::out_of_range (0x0x7f58de1c4dd0) + std::exception (0x0x7f58de1fc8a0) 0 nearly-empty + primary-for std::logic_error (0x0x7f58de1c4e38) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7f58de1c4ea0) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16u) + std::exception (0x0x7f58de1fc900) 0 nearly-empty + primary-for std::runtime_error (0x0x7f58de1c4ea0) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7f58de1c4f08) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16u) + std::runtime_error (0x0x7f58de1c4f70) 0 + primary-for std::range_error (0x0x7f58de1c4f08) + std::exception (0x0x7f58de1fc960) 0 nearly-empty + primary-for std::runtime_error (0x0x7f58de1c4f70) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7f58de1c4820) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16u) + std::runtime_error (0x0x7f58de1c48f0) 0 + primary-for std::overflow_error (0x0x7f58de1c4820) + std::exception (0x0x7f58de1fc9c0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f58de1c48f0) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7f58ddebc000) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16u) + std::runtime_error (0x0x7f58ddebc068) 0 + primary-for std::underflow_error (0x0x7f58ddebc000) + std::exception (0x0x7f58de1fca20) 0 nearly-empty + primary-for std::runtime_error (0x0x7f58ddebc068) + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7f58de1fcba0) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16u) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7f58de1fcde0) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7f58de1fcf60) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7f58ddebc548) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16u) + std::runtime_error (0x0x7f58ddebc5b0) 0 + primary-for std::system_error (0x0x7f58ddebc548) + std::exception (0x0x7f58ddefd1e0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f58ddebc5b0) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7f58ddf341a0) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16u) + std::system_error (0x0x7f58ddf34208) 0 + primary-for std::ios_base::failure (0x0x7f58ddf341a0) + std::runtime_error (0x0x7f58ddf34270) 0 + primary-for std::system_error (0x0x7f58ddf34208) + std::exception (0x0x7f58ddefd4e0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f58ddf34270) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7f58ddefd540) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7f58ddefd5a0) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7f58ddefd600) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7f58ddefd480) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7f58ddefdd80) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7f58ddc79480) 0 empty + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSo: 2u entries +0 ((& std::basic_ostream::_ZTVSo) + 24u) +8 ((& std::basic_ostream::_ZTVSo) + 64u) + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSi: 2u entries +0 ((& std::basic_istream::_ZTVSi) + 24u) +8 ((& std::basic_istream::_ZTVSi) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u) + +Construction vtable for std::basic_istream (0x0x7f58ddba0d68 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd0_Si: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7f58ddba0e38 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd16_So: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSd: 7u entries +0 ((& std::basic_iostream::_ZTVSd) + 24u) +8 ((& std::basic_iostream::_ZTCSd0_Si) + 24u) +16 ((& std::basic_iostream::_ZTCSd0_Si) + 64u) +24 ((& std::basic_iostream::_ZTCSd16_So) + 24u) +32 ((& std::basic_iostream::_ZTCSd16_So) + 64u) +40 ((& std::basic_iostream::_ZTVSd) + 104u) +48 ((& std::basic_iostream::_ZTVSd) + 64u) + +Construction vtable for std::basic_istream (0x0x7f58ddba03a8 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7f58ddba09c0 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries +0 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u) +16 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u) +24 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u) +32 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u) +40 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u) +48 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u) + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7f58dde01cc0) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7f58dde01d20) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7f58dd9740c0) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7f58dd974420) 0 + +Class QStringView + size=16 align=8 + base size=16 base align=8 +QStringView (0x0x7f58dd9748a0) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7f58dd67e720) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7f58dd67ed80) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7f58dd67ed20) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7f58dd48ae40) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7f58dd59aa80) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7f58dd2d5720) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7f58dd2d5780) 0 empty + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7f58dd2d57e0) 0 + +Class QListData::NotArrayCompatibleLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotArrayCompatibleLayout (0x0x7f58dd2d5ba0) 0 empty + +Class QListData::NotIndirectLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotIndirectLayout (0x0x7f58dd2d5c00) 0 empty + +Class QListData::ArrayCompatibleLayout + size=1 align=1 + base size=1 base align=1 +QListData::ArrayCompatibleLayout (0x0x7f58dd2baaf8) 0 empty + QListData::NotIndirectLayout (0x0x7f58dd2d5c60) 0 empty + +Class QListData::InlineWithPaddingLayout + size=1 align=1 + base size=1 base align=1 +QListData::InlineWithPaddingLayout (0x0x7f58dd10e310) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f58dd2d5cc0) 0 empty + QListData::NotIndirectLayout (0x0x7f58dd2d5d20) 0 empty + +Class QListData::IndirectLayout + size=1 align=1 + base size=1 base align=1 +QListData::IndirectLayout (0x0x7f58dd2bab60) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f58dd2d5d80) 0 empty + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7f58dd2d5de0) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7f58dd2d5b40) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7f58dd1322a0) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7f58dceca4e0) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7f58dceca480) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7f58dcecd5b0) 0 + QList (0x0x7f58dcecd618) 0 + QListSpecialMethods (0x0x7f58dceca6c0) 0 empty + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7f58dcecaae0) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7f58dcfb86c0) 0 + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7f58dcfb8d20) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7f58dcfb8ea0) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7f58dcfb8f60) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7f58dcecdf08) 0 + std::__uses_alloc_base (0x0x7f58dcfb8f00) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7f58dca8c000) 0 empty + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7f58dca8c240) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7f58dca8c300) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7f58dca8c420) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7f58dca8c5a0) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7f58dca8c9c0) 0 + +Class QtMetaTypePrivate::VectorBoolElements + size=1 align=1 + base size=0 base align=1 +QtMetaTypePrivate::VectorBoolElements (0x0x7f58dca8cae0) 0 empty + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7f58dc849480) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7f58dc8498a0) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7f58dc849ba0) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7f58dc6f45a0) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7f58dc442420) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7f58dc442480) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16u) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7f58dc442660) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7f58dc442600) 0 + vptr=((& QObject::_ZTV7QObject) + 16u) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7f58dc50a900) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7f58dc50a960) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7f58dc50aa20) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7f58dc536138) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u) + QObject (0x0x7f58dc50a9c0) 0 + primary-for QAbstractAnimation (0x0x7f58dc536138) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7f58dc50aae0) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7f58dc5361a0) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16u) + QObject (0x0x7f58dc50aa80) 0 + primary-for QAnimationDriver (0x0x7f58dc5361a0) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7f58dc50aba0) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7f58dc536208) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u) + QObject (0x0x7f58dc50ab40) 0 + primary-for QEventLoop (0x0x7f58dc536208) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7f58dc50ad80) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7f58dc50ae40) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7f58dc50aea0) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7f58dc536340) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u) + QObject (0x0x7f58dc50ade0) 0 + primary-for QAbstractEventDispatcher (0x0x7f58dc536340) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7f58dc5d5180) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16u) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7f58dc536548) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16u) + std::exception (0x0x7f58dc5d51e0) 0 nearly-empty + primary-for std::bad_cast (0x0x7f58dc536548) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7f58dc5365b0) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16u) + std::exception (0x0x7f58dc5d5240) 0 nearly-empty + primary-for std::bad_typeid (0x0x7f58dc5365b0) + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7f58dc2d1820) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16u) + std::exception (0x0x7f58dc34b300) 0 nearly-empty + primary-for std::bad_function_call (0x0x7f58dc2d1820) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7f58dc34b3c0) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7f58dc34b420) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7f58dc34b540) 0 + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7f58dc34ba20) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7f58dc34bf60) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7f58dc418360) 0 + +Class QHashData + size=48 align=8 + base size=44 base align=8 +QHashData (0x0x7f58dc418300) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7f58dc4183c0) 0 empty + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7f58dc418c60) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7f58dc418d20) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7f58dc418cc0) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7f58dc418d80) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7f58dc418c00) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7f58dbf418a0) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7f58dbf41f00) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7f58dbf41ea0) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7f58dbf9f000) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7f58dbf41f60) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7f58dbcb1300) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7f58dbcb19c0) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7f58dba9d120) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7f58dba995b0) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u) + QObject (0x0x7f58dba9d0c0) 0 + primary-for QAbstractItemModel (0x0x7f58dba995b0) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7f58dba9d9c0) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7f58dba99c98) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u) + QAbstractItemModel (0x0x7f58dba99d00) 0 + primary-for QAbstractTableModel (0x0x7f58dba99c98) + QObject (0x0x7f58dba9d960) 0 + primary-for QAbstractItemModel (0x0x7f58dba99d00) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7f58dba9da80) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7f58dba99d68) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u) + QAbstractItemModel (0x0x7f58dba99dd0) 0 + primary-for QAbstractListModel (0x0x7f58dba99d68) + QObject (0x0x7f58dba9da20) 0 + primary-for QAbstractItemModel (0x0x7f58dba99dd0) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7f58dba9dd20) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16u) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7f58dba9dde0) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7f58dba99f08) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16u) + QAbstractItemModel (0x0x7f58dba99f70) 0 + primary-for QAbstractProxyModel (0x0x7f58dba99f08) + QObject (0x0x7f58dba9dd80) 0 + primary-for QAbstractItemModel (0x0x7f58dba99f70) + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7f58dba9dea0) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7f58dbbf1000) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u) + QObject (0x0x7f58dba9de40) 0 + primary-for QAbstractState (0x0x7f58dbbf1000) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7f58dba9df60) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7f58dbbf1068) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u) + QObject (0x0x7f58dba9df00) 0 + primary-for QAbstractTransition (0x0x7f58dbbf1068) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7f58dbc19060) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7f58dbbf10d0) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u) + QAbstractAnimation (0x0x7f58dbbf1138) 0 + primary-for QAnimationGroup (0x0x7f58dbbf10d0) + QObject (0x0x7f58dbc19000) 0 + primary-for QAbstractAnimation (0x0x7f58dbbf1138) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7f58db844d80) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7f58db887060) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7f58db887120) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7f58db887420) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7f58dbbf17b8) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16u) + QObject (0x0x7f58db8873c0) 0 + primary-for QIODevice (0x0x7f58dbbf17b8) + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7f58db887660) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7f58dbbf18f0) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16u) + QIODevice (0x0x7f58dbbf1958) 0 + primary-for QBuffer (0x0x7f58dbbf18f0) + QObject (0x0x7f58db887600) 0 + primary-for QIODevice (0x0x7f58dbbf1958) + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7f58db887720) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7f58db8876c0) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7f58db887840) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7f58db8877e0) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7f58db887a20) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7f58db887c00) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7f58db887ea0) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7f58dba0d660) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7f58dba0d6c0) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7f58dba0d600) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7f58db6c07e0) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7f58db6c0de0) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16u) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7f58db7e80c0) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7f58db7e8300) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7f58db7e89c0) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7f58db7e8b40) 0 + +Class QDebug::Stream + size=80 align=8 + base size=76 base align=8 +QDebug::Stream (0x0x7f58db5740c0) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7f58db574060) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7f58db2cd3c0) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7f58db2cd480) 0 empty + +Class QCborError + size=4 align=4 + base size=4 base align=4 +QCborError (0x0x7f58db3517e0) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7f58db351960) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7f58db351f60) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7f58db00d2a0) 0 + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7f58db00d660) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7f58db127d20) 0 + +Class QCborParserError + size=16 align=8 + base size=12 base align=8 +QCborParserError (0x0x7f58db1a7360) 0 + +Class QCborValue + size=24 align=8 + base size=20 base align=8 +QCborValue (0x0x7f58db1a73c0) 0 + +Class QCborValueRef + size=16 align=8 + base size=16 base align=8 +QCborValueRef (0x0x7f58dac483c0) 0 + +Class QCborArray::Iterator + size=16 align=8 + base size=16 base align=8 +QCborArray::Iterator (0x0x7f58dac48960) 0 + +Class QCborArray::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborArray::ConstIterator (0x0x7f58dac489c0) 0 + +Class QCborArray + size=8 align=8 + base size=8 base align=8 +QCborArray (0x0x7f58dac48900) 0 + +Class QCborMap::Iterator + size=16 align=8 + base size=16 base align=8 +QCborMap::Iterator (0x0x7f58dad56a20) 0 + +Class QCborMap::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborMap::ConstIterator (0x0x7f58dad56a80) 0 + +Class QCborMap + size=8 align=8 + base size=8 base align=8 +QCborMap (0x0x7f58dad569c0) 0 + +Class qfloat16 + size=2 align=2 + base size=2 base align=2 +qfloat16 (0x0x7f58dab1b600) 0 + +Class QCborStreamWriter + size=8 align=8 + base size=8 base align=8 +QCborStreamWriter (0x0x7f58dab1b9c0) 0 + +Class QCborStreamReader + size=24 align=8 + base size=20 base align=8 +QCborStreamReader (0x0x7f58da8543c0) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7f58da854a20) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7f58da854ae0) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7f58da972ae0) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7f58da972f60) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16u) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7f58da976f08) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u) + QEvent (0x0x7f58da5ce000) 0 + primary-for QTimerEvent (0x0x7f58da976f08) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7f58da976f70) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u) + QEvent (0x0x7f58da5ce060) 0 + primary-for QChildEvent (0x0x7f58da976f70) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7f58da5dd4e0) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u) + QEvent (0x0x7f58da5ce540) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7f58da5dd4e0) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7f58da5dd548) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16u) + QEvent (0x0x7f58da5ce5a0) 0 + primary-for QDeferredDeleteEvent (0x0x7f58da5dd548) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7f58da5ce660) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7f58da5dd5b0) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u) + QObject (0x0x7f58da5ce600) 0 + primary-for QCoreApplication (0x0x7f58da5dd5b0) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7f58da5ce6c0) 0 + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7f58da5ce720) 0 + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7f58da5ce780) 0 + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7f58da5ce840) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7f58da5ced20) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7f58da6b2240) 0 + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7f58da3e30c0) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7f58da3c3a28) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16u) + QIODevice (0x0x7f58da3c3a90) 0 + primary-for QFileDevice (0x0x7f58da3c3a28) + QObject (0x0x7f58da3e3060) 0 + primary-for QIODevice (0x0x7f58da3c3a90) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7f58da3e3300) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7f58da3c3bc8) 0 + vptr=((& QFile::_ZTV5QFile) + 16u) + QFileDevice (0x0x7f58da3c3c30) 0 + primary-for QFile (0x0x7f58da3c3bc8) + QIODevice (0x0x7f58da3c3c98) 0 + primary-for QFileDevice (0x0x7f58da3c3c30) + QObject (0x0x7f58da3e32a0) 0 + primary-for QIODevice (0x0x7f58da3c3c98) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7f58da3e34e0) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7f58da3e3900) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7f58da3e3f00) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7f58da527180) 0 + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7f58da1d95a0) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7f58da1cec98) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u) + QAbstractTransition (0x0x7f58da1ced00) 0 + primary-for QEventTransition (0x0x7f58da1cec98) + QObject (0x0x7f58da1d9540) 0 + primary-for QAbstractTransition (0x0x7f58da1ced00) + +Vtable for QException +QException::_ZTV10QException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7f58da1ced68) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16u) + std::exception (0x0x7f58da1d9600) 0 nearly-empty + primary-for QException (0x0x7f58da1ced68) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7f58da1cedd0) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16u) + QException (0x0x7f58da1cee38) 0 nearly-empty + primary-for QUnhandledException (0x0x7f58da1cedd0) + std::exception (0x0x7f58da1d9660) 0 nearly-empty + primary-for QException (0x0x7f58da1cee38) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7f58da1d96c0) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7f58da1d9780) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7f58da1d97e0) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7f58da1d9900) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7f58da1ceea0) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16u) + QObject (0x0x7f58da1d98a0) 0 + primary-for QFileSelector (0x0x7f58da1ceea0) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7f58da1d99c0) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7f58da1cef08) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u) + QObject (0x0x7f58da1d9960) 0 + primary-for QFileSystemWatcher (0x0x7f58da1cef08) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7f58da1d9a80) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7f58da1cef70) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16u) + QAbstractState (0x0x7f58da283000) 0 + primary-for QFinalState (0x0x7f58da1cef70) + QObject (0x0x7f58da1d9a20) 0 + primary-for QAbstractState (0x0x7f58da283000) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7f58da1d9ae0) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16u) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7f58da1d9b40) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7f58da283138) 0 + QBasicMutex (0x0x7f58da1d9d20) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7f58da1d9d80) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7f58da1d9de0) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7f58da1d9e40) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7f58da1d9f60) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16u) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7f58da3787e0) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7f58da031000) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0u +48 0u +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7f58da007270) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u) + QObject (0x0x7f58da378f60) 0 + primary-for QFutureWatcherBase (0x0x7f58da007270) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7f58da031600) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7f58da007b60) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u) + QAbstractState (0x0x7f58da007bc8) 0 + primary-for QHistoryState (0x0x7f58da007b60) + QObject (0x0x7f58da0315a0) 0 + primary-for QAbstractState (0x0x7f58da007bc8) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7f58da0316c0) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7f58da007c30) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16u) + QAbstractProxyModel (0x0x7f58da007c98) 0 + primary-for QIdentityProxyModel (0x0x7f58da007c30) + QAbstractItemModel (0x0x7f58da007d00) 0 + primary-for QAbstractProxyModel (0x0x7f58da007c98) + QObject (0x0x7f58da031660) 0 + primary-for QAbstractItemModel (0x0x7f58da007d00) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7f58da031720) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7f58da031de0) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7f58da0d2548) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u) + QObject (0x0x7f58da031d80) 0 + primary-for QItemSelectionModel (0x0x7f58da0d2548) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7f58da0d2750) 0 + QList (0x0x7f58da0d27b8) 0 + QListSpecialMethods (0x0x7f58da12d120) 0 empty + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7f58da12d600) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7f58d9ecdd20) 0 + +Class QJsonValuePtr + size=24 align=8 + base size=24 base align=8 +QJsonValuePtr (0x0x7f58d9f3b2a0) 0 + +Class QJsonValueRefPtr + size=16 align=8 + base size=16 base align=8 +QJsonValueRefPtr (0x0x7f58d9f3b300) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7f58d9f3b4e0) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7f58d9f3b540) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7f58d9f3b480) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7f58d9bfd780) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7f58d9bfd7e0) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7f58d9bfde40) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7f58d9bfdea0) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7f58d9bfdde0) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7f58d9d65180) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7f58d9d24af8) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16u) + QObject (0x0x7f58d9d65120) 0 + primary-for QLibrary (0x0x7f58d9d24af8) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7f58d9d65840) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7f58d9d65360) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7f58d9d65d20) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7f58d9d65d80) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7f58d9a41060) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7f58d9a41660) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7f58d9af5000) 0 + +Class QLinkedListData + size=32 align=8 + base size=25 base align=8 +QLinkedListData (0x0x7f58d9af5600) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7f58d9af5960) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7f58d9af5ae0) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7f58d9af5a80) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7f58d9af5c60) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7f58d9af5f00) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7f58d98975a0) 0 + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7f58d9897600) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7f58d9897c00) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7f58d9897f00) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7f58d9897f60) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7f58d99512a0) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7f58d98b8d68) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16u) + QObject (0x0x7f58d9951240) 0 + primary-for QMimeData (0x0x7f58d98b8d68) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7f58d9951300) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7f58d9951600) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7f58d99516c0) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7f58d98b8f70) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u) + QObject (0x0x7f58d9951660) 0 + primary-for QObjectCleanupHandler (0x0x7f58d98b8f70) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7f58d9951720) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7f58d9951ea0) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7f58d99ab6e8) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u) + QAnimationGroup (0x0x7f58d99ab750) 0 + primary-for QParallelAnimationGroup (0x0x7f58d99ab6e8) + QAbstractAnimation (0x0x7f58d99ab7b8) 0 + primary-for QAnimationGroup (0x0x7f58d99ab750) + QObject (0x0x7f58d9951e40) 0 + primary-for QAbstractAnimation (0x0x7f58d99ab7b8) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7f58d9951f60) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7f58d99ab820) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u) + QAbstractAnimation (0x0x7f58d99ab888) 0 + primary-for QPauseAnimation (0x0x7f58d99ab820) + QObject (0x0x7f58d9951f00) 0 + primary-for QAbstractAnimation (0x0x7f58d99ab888) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7f58d95f2180) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7f58d95f2480) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7f58d99aba90) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u) + QObject (0x0x7f58d95f2420) 0 + primary-for QPluginLoader (0x0x7f58d99aba90) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7f58d95f24e0) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7f58d95f2ba0) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7f58d96430d0) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16u) + QIODevice (0x0x7f58d9643138) 0 + primary-for QProcess (0x0x7f58d96430d0) + QObject (0x0x7f58d95f2b40) 0 + primary-for QIODevice (0x0x7f58d9643138) + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7f58d95f2c60) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7f58d96431a0) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u) + QAbstractAnimation (0x0x7f58d9643208) 0 + primary-for QVariantAnimation (0x0x7f58d96431a0) + QObject (0x0x7f58d95f2c00) 0 + primary-for QAbstractAnimation (0x0x7f58d9643208) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7f58d95f2d20) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7f58d96432d8) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u) + QVariantAnimation (0x0x7f58d9643340) 0 + primary-for QPropertyAnimation (0x0x7f58d96432d8) + QAbstractAnimation (0x0x7f58d96433a8) 0 + primary-for QVariantAnimation (0x0x7f58d9643340) + QObject (0x0x7f58d95f2cc0) 0 + primary-for QAbstractAnimation (0x0x7f58d96433a8) + +Class QRandomGenerator::Storage + size=2504 align=8 + base size=2504 base align=8 +QRandomGenerator::Storage (0x0x7f58d95f2e40) 0 + +Class QRandomGenerator + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator (0x0x7f58d95f2de0) 0 + +Class QRandomGenerator64 + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator64 (0x0x7f58d9725680) 0 + QRandomGenerator (0x0x7f58d970dde0) 0 + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7f58d970dea0) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7f58d979e180) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7f58d979e240) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7f58d979e300) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7f58d979e5a0) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7f58d979e840) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7f58d979eae0) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7f58d979ed80) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7f58d979ef00) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7f58d9494208) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16u) + QFileDevice (0x0x7f58d9494270) 0 + primary-for QSaveFile (0x0x7f58d9494208) + QIODevice (0x0x7f58d94942d8) 0 + primary-for QFileDevice (0x0x7f58d9494270) + QObject (0x0x7f58d979eea0) 0 + primary-for QIODevice (0x0x7f58d94942d8) + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7f58d91c2060) 0 + +Class QSemaphoreReleaser + size=16 align=8 + base size=12 base align=8 +QSemaphoreReleaser (0x0x7f58d91c21e0) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7f58d92ee7e0) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7f58d92ecb60) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u) + QAnimationGroup (0x0x7f58d92ecbc8) 0 + primary-for QSequentialAnimationGroup (0x0x7f58d92ecb60) + QAbstractAnimation (0x0x7f58d92ecc30) 0 + primary-for QAnimationGroup (0x0x7f58d92ecbc8) + QObject (0x0x7f58d92ee780) 0 + primary-for QAbstractAnimation (0x0x7f58d92ecc30) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7f58d92ee8a0) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7f58d92ecc98) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16u) + QObject (0x0x7f58d92ee840) 0 + primary-for QSettings (0x0x7f58d92ecc98) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7f58d92ee960) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7f58d92ecd00) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u) + QObject (0x0x7f58d92ee900) 0 + primary-for QSharedMemory (0x0x7f58d92ecd00) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7f58d92eea20) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7f58d92ecd68) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u) + QObject (0x0x7f58d92ee9c0) 0 + primary-for QSignalMapper (0x0x7f58d92ecd68) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7f58d92eeae0) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7f58d92ecdd0) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u) + QAbstractTransition (0x0x7f58d92ece38) 0 + primary-for QSignalTransition (0x0x7f58d92ecdd0) + QObject (0x0x7f58d92eea80) 0 + primary-for QAbstractTransition (0x0x7f58d92ece38) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7f58d92eeba0) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7f58d92ecea0) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u) + QObject (0x0x7f58d92eeb40) 0 + primary-for QSocketNotifier (0x0x7f58d92ecea0) + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7f58d92eec60) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7f58d92ecf08) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16u) + QAbstractProxyModel (0x0x7f58d92ecf70) 0 + primary-for QSortFilterProxyModel (0x0x7f58d92ecf08) + QAbstractItemModel (0x0x7f58d9376000) 0 + primary-for QAbstractProxyModel (0x0x7f58d92ecf70) + QObject (0x0x7f58d92eec00) 0 + primary-for QAbstractItemModel (0x0x7f58d9376000) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7f58d92eed20) 0 empty + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7f58d92eef60) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7f58d93761a0) 0 + vptr=((& QState::_ZTV6QState) + 16u) + QAbstractState (0x0x7f58d9376208) 0 + primary-for QState (0x0x7f58d93761a0) + QObject (0x0x7f58d92eef00) 0 + primary-for QAbstractState (0x0x7f58d9376208) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7f58d8ff10c0) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7f58d93763a8) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u) + QEvent (0x0x7f58d8ff1120) 0 + primary-for QStateMachine::SignalEvent (0x0x7f58d93763a8) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7f58d9376410) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u) + QEvent (0x0x7f58d8ff1180) 0 + primary-for QStateMachine::WrappedEvent (0x0x7f58d9376410) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7f58d9376270) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u) + QState (0x0x7f58d93762d8) 0 + primary-for QStateMachine (0x0x7f58d9376270) + QAbstractState (0x0x7f58d9376340) 0 + primary-for QState (0x0x7f58d93762d8) + QObject (0x0x7f58d8ff1060) 0 + primary-for QAbstractState (0x0x7f58d9376340) + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7f58d8ff11e0) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7f58d9070120) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7f58d90f54e0) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7f58d90f8410) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u) + QAbstractListModel (0x0x7f58d90f8478) 0 + primary-for QStringListModel (0x0x7f58d90f8410) + QAbstractItemModel (0x0x7f58d90f84e0) 0 + primary-for QAbstractListModel (0x0x7f58d90f8478) + QObject (0x0x7f58d90f5480) 0 + primary-for QAbstractItemModel (0x0x7f58d90f84e0) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7f58d90f5540) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7f58d90f5600) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7f58d90f5720) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7f58d90f8548) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u) + QFile (0x0x7f58d90f85b0) 0 + primary-for QTemporaryFile (0x0x7f58d90f8548) + QFileDevice (0x0x7f58d90f8618) 0 + primary-for QFile (0x0x7f58d90f85b0) + QIODevice (0x0x7f58d90f8680) 0 + primary-for QFileDevice (0x0x7f58d90f8618) + QObject (0x0x7f58d90f56c0) 0 + primary-for QIODevice (0x0x7f58d90f8680) + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7f58d90f5780) 0 + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7f58d90f59c0) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 0u +64 0u + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7f58d90f5960) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7f58d90f5ba0) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7f58d90f5c00) 0 + +Class std::__mutex_base + size=40 align=8 + base size=40 base align=8 +std::__mutex_base (0x0x7f58d90f5c60) 0 + +Class std::__recursive_mutex_base + size=40 align=8 + base size=40 base align=8 +std::__recursive_mutex_base (0x0x7f58d90f5cc0) 0 + +Class std::mutex + size=40 align=8 + base size=40 base align=8 +std::mutex (0x0x7f58d90f8888) 0 + std::__mutex_base (0x0x7f58d90f5d20) 0 + +Class std::recursive_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_mutex (0x0x7f58d90f88f0) 0 + std::__recursive_mutex_base (0x0x7f58d90f5d80) 0 + +Class std::timed_mutex + size=40 align=8 + base size=40 base align=8 +std::timed_mutex (0x0x7f58d8dfb3f0) 0 + std::__mutex_base (0x0x7f58d90f5ea0) 0 + std::__timed_mutex_impl (0x0x7f58d90f5f00) 0 empty + +Class std::recursive_timed_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_timed_mutex (0x0x7f58d8dfbd90) 0 + std::__recursive_mutex_base (0x0x7f58d8e15000) 0 + std::__timed_mutex_impl (0x0x7f58d8e15060) 0 empty + +Class std::defer_lock_t + size=1 align=1 + base size=0 base align=1 +std::defer_lock_t (0x0x7f58d8e150c0) 0 empty + +Class std::try_to_lock_t + size=1 align=1 + base size=0 base align=1 +std::try_to_lock_t (0x0x7f58d8e15120) 0 empty + +Class std::adopt_lock_t + size=1 align=1 + base size=0 base align=1 +std::adopt_lock_t (0x0x7f58d8e15180) 0 empty + +Class std::once_flag + size=4 align=4 + base size=4 base align=4 +std::once_flag (0x0x7f58d8e153c0) 0 + +Vtable for __gnu_cxx::__concurrence_lock_error +__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what + +Class __gnu_cxx::__concurrence_lock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_lock_error (0x0x7f58d90f8a28) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16u) + std::exception (0x0x7f58d8e15480) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_lock_error (0x0x7f58d90f8a28) + +Vtable for __gnu_cxx::__concurrence_unlock_error +__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what + +Class __gnu_cxx::__concurrence_unlock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_unlock_error (0x0x7f58d90f8a90) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16u) + std::exception (0x0x7f58d8e15540) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7f58d90f8a90) + +Vtable for __gnu_cxx::__concurrence_broadcast_error +__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what + +Class __gnu_cxx::__concurrence_broadcast_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_broadcast_error (0x0x7f58d90f8af8) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16u) + std::exception (0x0x7f58d8e15600) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7f58d90f8af8) + +Vtable for __gnu_cxx::__concurrence_wait_error +__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what + +Class __gnu_cxx::__concurrence_wait_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_wait_error (0x0x7f58d90f8bc8) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16u) + std::exception (0x0x7f58d8e156c0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_wait_error (0x0x7f58d90f8bc8) + +Class __gnu_cxx::__mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__mutex (0x0x7f58d8e15780) 0 + +Class __gnu_cxx::__recursive_mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__recursive_mutex (0x0x7f58d8e157e0) 0 + +Class __gnu_cxx::__scoped_lock + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__scoped_lock (0x0x7f58d8e15840) 0 + +Class __gnu_cxx::__cond + size=48 align=8 + base size=48 base align=8 +__gnu_cxx::__cond (0x0x7f58d8e158a0) 0 + +Vtable for std::bad_weak_ptr +std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12bad_weak_ptr) +16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +32 (int (*)(...))std::bad_weak_ptr::what + +Class std::bad_weak_ptr + size=8 align=8 + base size=8 base align=8 +std::bad_weak_ptr (0x0x7f58d90f8ea0) 0 nearly-empty + vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16u) + std::exception (0x0x7f58d8e15c00) 0 nearly-empty + primary-for std::bad_weak_ptr (0x0x7f58d90f8ea0) + +Class std::_Sp_make_shared_tag + size=1 align=1 + base size=0 base align=1 +std::_Sp_make_shared_tag (0x0x7f58d8f68480) 0 empty + +Class std::_Sp_locker + size=2 align=1 + base size=2 base align=1 +std::_Sp_locker (0x0x7f58d8f68c60) 0 + +Class std::thread::id + size=8 align=8 + base size=8 base align=8 +std::thread::id (0x0x7f58d8f68e40) 0 + +Vtable for std::thread::_Impl_base +std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6thread10_Impl_baseE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class std::thread::_Impl_base + size=24 align=8 + base size=24 base align=8 +std::thread::_Impl_base (0x0x7f58d8f68ea0) 0 + vptr=((& std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE) + 16u) + +Class std::thread + size=8 align=8 + base size=8 base align=8 +std::thread (0x0x7f58d8f68de0) 0 + +Class std::condition_variable + size=48 align=8 + base size=48 base align=8 +std::condition_variable (0x0x7f58d89fdae0) 0 + +Class std::__at_thread_exit_elt + size=16 align=8 + base size=16 base align=8 +std::__at_thread_exit_elt (0x0x7f58d89fdba0) 0 + +Class std::_V2::condition_variable_any + size=64 align=8 + base size=64 base align=8 +std::_V2::condition_variable_any (0x0x7f58d89fdc00) 0 + +Class std::__atomic_futex_unsigned_base + size=1 align=1 + base size=0 base align=1 +std::__atomic_futex_unsigned_base (0x0x7f58d8aea2a0) 0 empty + +Vtable for std::future_error +std::future_error::_ZTVSt12future_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12future_error) +16 (int (*)(...))std::future_error::~future_error +24 (int (*)(...))std::future_error::~future_error +32 (int (*)(...))std::future_error::what + +Class std::future_error + size=32 align=8 + base size=32 base align=8 +std::future_error (0x0x7f58d8b23208) 0 + vptr=((& std::future_error::_ZTVSt12future_error) + 16u) + std::logic_error (0x0x7f58d8b23270) 0 + primary-for std::future_error (0x0x7f58d8b23208) + std::exception (0x0x7f58d8aea3c0) 0 nearly-empty + primary-for std::logic_error (0x0x7f58d8b23270) + +Class std::__future_base::_Result_base::_Deleter + size=1 align=1 + base size=0 base align=1 +std::__future_base::_Result_base::_Deleter (0x0x7f58d8aea4e0) 0 empty + +Vtable for std::__future_base::_Result_base +std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class std::__future_base::_Result_base + size=16 align=8 + base size=16 base align=8 +std::__future_base::_Result_base (0x0x7f58d8aea480) 0 + vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16u) + +Class std::__future_base::_State_baseV2::__exception_ptr_tag + size=1 align=1 + base size=0 base align=1 +std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7f58d8859a20) 0 empty + +Class std::__future_base::_State_baseV2::_Make_ready + size=32 align=8 + base size=32 base align=8 +std::__future_base::_State_baseV2::_Make_ready (0x0x7f58d885e820) 0 + std::__at_thread_exit_elt (0x0x7f58d8859ae0) 0 + +Vtable for std::__future_base::_State_baseV2 +std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E) +16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_State_baseV2 + size=32 align=8 + base size=28 base align=8 +std::__future_base::_State_baseV2 (0x0x7f58d8aea660) 0 + vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16u) + +Class std::__future_base + size=1 align=1 + base size=0 base align=1 +std::__future_base (0x0x7f58d8aea420) 0 empty + +Vtable for std::__future_base::_Async_state_commonV2 +std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E) +16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_Async_state_commonV2 + size=48 align=8 + base size=44 base align=8 +std::__future_base::_Async_state_commonV2 (0x0x7f58d81c7410) 0 + vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16u) + std::__future_base::_State_baseV2 (0x0x7f58d81bc9c0) 0 + primary-for std::__future_base::_Async_state_commonV2 (0x0x7f58d81c7410) + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7f58d8244120) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7f58d81c7ea0) 0 + vptr=((& QThread::_ZTV7QThread) + 16u) + QObject (0x0x7f58d82440c0) 0 + primary-for QThread (0x0x7f58d81c7ea0) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7f58d8244240) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7f58d81c7f08) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u) + QObject (0x0x7f58d82441e0) 0 + primary-for QThreadPool (0x0x7f58d81c7f08) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7f58d82442a0) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7f58d82443c0) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7f58d81c7f70) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u) + QObject (0x0x7f58d8244360) 0 + primary-for QTimeLine (0x0x7f58d81c7f70) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7f58d8244480) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7f58d829f000) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16u) + QObject (0x0x7f58d8244420) 0 + primary-for QTimer (0x0x7f58d829f000) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7f58d8244ba0) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7f58d8244b40) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7f58d8311180) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7f58d829fbc8) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16u) + QObject (0x0x7f58d8311120) 0 + primary-for QTranslator (0x0x7f58d829fbc8) + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7f58d83111e0) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7f58d8311840) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7f58d83118a0) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7f58d8311b40) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7f58d8349888) 0 + QVector (0x0x7f58d8311f00) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7f58d8311f60) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7f58d800c240) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7f58d800c4e0) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7f58d800c780) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7f58d800c7e0) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7f58d80c2240) 0 + +Class QRgba64 + size=8 align=8 + base size=8 base align=8 +QRgba64 (0x0x7f58d80c2360) 0 + +Class QColor + size=16 align=4 + base size=14 base align=4 +QColor (0x0x7f58d80c2600) 0 + +Class QRegion::QRegionData + size=16 align=8 + base size=16 base align=8 +QRegion::QRegionData (0x0x7f58d7df4000) 0 + +Class QRegion + size=8 align=8 + base size=8 base align=8 +QRegion (0x0x7f58d80c2f60) 0 + +Class QKeySequence + size=8 align=8 + base size=8 base align=8 +QKeySequence (0x0x7f58d7e77360) 0 + +Class QVector2D + size=8 align=4 + base size=8 base align=4 +QVector2D (0x0x7f58d7f208a0) 0 + +Class QTouchDevice + size=8 align=8 + base size=8 base align=8 +QTouchDevice (0x0x7f58d7f20b40) 0 + +Vtable for QInputEvent +QInputEvent::_ZTV11QInputEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QInputEvent) +16 (int (*)(...))QInputEvent::~QInputEvent +24 (int (*)(...))QInputEvent::~QInputEvent + +Class QInputEvent + size=32 align=8 + base size=32 base align=8 +QInputEvent (0x0x7f58d7f2c680) 0 + vptr=((& QInputEvent::_ZTV11QInputEvent) + 16u) + QEvent (0x0x7f58d7f20d20) 0 + primary-for QInputEvent (0x0x7f58d7f2c680) + +Vtable for QEnterEvent +QEnterEvent::_ZTV11QEnterEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QEnterEvent) +16 (int (*)(...))QEnterEvent::~QEnterEvent +24 (int (*)(...))QEnterEvent::~QEnterEvent + +Class QEnterEvent + size=72 align=8 + base size=72 base align=8 +QEnterEvent (0x0x7f58d7f2c6e8) 0 + vptr=((& QEnterEvent::_ZTV11QEnterEvent) + 16u) + QEvent (0x0x7f58d7f20d80) 0 + primary-for QEnterEvent (0x0x7f58d7f2c6e8) + +Vtable for QMouseEvent +QMouseEvent::_ZTV11QMouseEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QMouseEvent) +16 (int (*)(...))QMouseEvent::~QMouseEvent +24 (int (*)(...))QMouseEvent::~QMouseEvent + +Class QMouseEvent + size=104 align=8 + base size=100 base align=8 +QMouseEvent (0x0x7f58d7f2c750) 0 + vptr=((& QMouseEvent::_ZTV11QMouseEvent) + 16u) + QInputEvent (0x0x7f58d7f2c7b8) 0 + primary-for QMouseEvent (0x0x7f58d7f2c750) + QEvent (0x0x7f58d7f20de0) 0 + primary-for QInputEvent (0x0x7f58d7f2c7b8) + +Vtable for QHoverEvent +QHoverEvent::_ZTV11QHoverEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QHoverEvent) +16 (int (*)(...))QHoverEvent::~QHoverEvent +24 (int (*)(...))QHoverEvent::~QHoverEvent + +Class QHoverEvent + size=64 align=8 + base size=64 base align=8 +QHoverEvent (0x0x7f58d7f2c820) 0 + vptr=((& QHoverEvent::_ZTV11QHoverEvent) + 16u) + QInputEvent (0x0x7f58d7f2c888) 0 + primary-for QHoverEvent (0x0x7f58d7f2c820) + QEvent (0x0x7f58d7f20e40) 0 + primary-for QInputEvent (0x0x7f58d7f2c888) + +Vtable for QWheelEvent +QWheelEvent::_ZTV11QWheelEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QWheelEvent) +16 (int (*)(...))QWheelEvent::~QWheelEvent +24 (int (*)(...))QWheelEvent::~QWheelEvent + +Class QWheelEvent + size=96 align=8 + base size=96 base align=8 +QWheelEvent (0x0x7f58d7f2c8f0) 0 + vptr=((& QWheelEvent::_ZTV11QWheelEvent) + 16u) + QInputEvent (0x0x7f58d7f2c958) 0 + primary-for QWheelEvent (0x0x7f58d7f2c8f0) + QEvent (0x0x7f58d7f20ea0) 0 + primary-for QInputEvent (0x0x7f58d7f2c958) + +Vtable for QTabletEvent +QTabletEvent::_ZTV12QTabletEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QTabletEvent) +16 (int (*)(...))QTabletEvent::~QTabletEvent +24 (int (*)(...))QTabletEvent::~QTabletEvent + +Class QTabletEvent + size=128 align=8 + base size=128 base align=8 +QTabletEvent (0x0x7f58d7f2c9c0) 0 + vptr=((& QTabletEvent::_ZTV12QTabletEvent) + 16u) + QInputEvent (0x0x7f58d7f2ca28) 0 + primary-for QTabletEvent (0x0x7f58d7f2c9c0) + QEvent (0x0x7f58d7f20f00) 0 + primary-for QInputEvent (0x0x7f58d7f2ca28) + +Vtable for QNativeGestureEvent +QNativeGestureEvent::_ZTV19QNativeGestureEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QNativeGestureEvent) +16 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent +24 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent + +Class QNativeGestureEvent + size=112 align=8 + base size=112 base align=8 +QNativeGestureEvent (0x0x7f58d7f2ca90) 0 + vptr=((& QNativeGestureEvent::_ZTV19QNativeGestureEvent) + 16u) + QInputEvent (0x0x7f58d7f2caf8) 0 + primary-for QNativeGestureEvent (0x0x7f58d7f2ca90) + QEvent (0x0x7f58d7f20f60) 0 + primary-for QInputEvent (0x0x7f58d7f2caf8) + +Vtable for QKeyEvent +QKeyEvent::_ZTV9QKeyEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QKeyEvent) +16 (int (*)(...))QKeyEvent::~QKeyEvent +24 (int (*)(...))QKeyEvent::~QKeyEvent + +Class QKeyEvent + size=64 align=8 + base size=59 base align=8 +QKeyEvent (0x0x7f58d7f2cb60) 0 + vptr=((& QKeyEvent::_ZTV9QKeyEvent) + 16u) + QInputEvent (0x0x7f58d7f2cbc8) 0 + primary-for QKeyEvent (0x0x7f58d7f2cb60) + QEvent (0x0x7f58d7c40000) 0 + primary-for QInputEvent (0x0x7f58d7f2cbc8) + +Vtable for QFocusEvent +QFocusEvent::_ZTV11QFocusEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFocusEvent) +16 (int (*)(...))QFocusEvent::~QFocusEvent +24 (int (*)(...))QFocusEvent::~QFocusEvent + +Class QFocusEvent + size=24 align=8 + base size=24 base align=8 +QFocusEvent (0x0x7f58d7f2cc30) 0 + vptr=((& QFocusEvent::_ZTV11QFocusEvent) + 16u) + QEvent (0x0x7f58d7c40060) 0 + primary-for QFocusEvent (0x0x7f58d7f2cc30) + +Vtable for QPaintEvent +QPaintEvent::_ZTV11QPaintEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QPaintEvent) +16 (int (*)(...))QPaintEvent::~QPaintEvent +24 (int (*)(...))QPaintEvent::~QPaintEvent + +Class QPaintEvent + size=56 align=8 + base size=49 base align=8 +QPaintEvent (0x0x7f58d7f2cc98) 0 + vptr=((& QPaintEvent::_ZTV11QPaintEvent) + 16u) + QEvent (0x0x7f58d7c400c0) 0 + primary-for QPaintEvent (0x0x7f58d7f2cc98) + +Vtable for QMoveEvent +QMoveEvent::_ZTV10QMoveEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QMoveEvent) +16 (int (*)(...))QMoveEvent::~QMoveEvent +24 (int (*)(...))QMoveEvent::~QMoveEvent + +Class QMoveEvent + size=40 align=8 + base size=36 base align=8 +QMoveEvent (0x0x7f58d7f2cd00) 0 + vptr=((& QMoveEvent::_ZTV10QMoveEvent) + 16u) + QEvent (0x0x7f58d7c40120) 0 + primary-for QMoveEvent (0x0x7f58d7f2cd00) + +Vtable for QExposeEvent +QExposeEvent::_ZTV12QExposeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QExposeEvent) +16 (int (*)(...))QExposeEvent::~QExposeEvent +24 (int (*)(...))QExposeEvent::~QExposeEvent + +Class QExposeEvent + size=32 align=8 + base size=32 base align=8 +QExposeEvent (0x0x7f58d7f2cd68) 0 + vptr=((& QExposeEvent::_ZTV12QExposeEvent) + 16u) + QEvent (0x0x7f58d7c40180) 0 + primary-for QExposeEvent (0x0x7f58d7f2cd68) + +Vtable for QPlatformSurfaceEvent +QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QPlatformSurfaceEvent) +16 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent +24 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent + +Class QPlatformSurfaceEvent + size=24 align=8 + base size=24 base align=8 +QPlatformSurfaceEvent (0x0x7f58d7f2cdd0) 0 + vptr=((& QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent) + 16u) + QEvent (0x0x7f58d7c401e0) 0 + primary-for QPlatformSurfaceEvent (0x0x7f58d7f2cdd0) + +Vtable for QResizeEvent +QResizeEvent::_ZTV12QResizeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QResizeEvent) +16 (int (*)(...))QResizeEvent::~QResizeEvent +24 (int (*)(...))QResizeEvent::~QResizeEvent + +Class QResizeEvent + size=40 align=8 + base size=36 base align=8 +QResizeEvent (0x0x7f58d7f2ce38) 0 + vptr=((& QResizeEvent::_ZTV12QResizeEvent) + 16u) + QEvent (0x0x7f58d7c40240) 0 + primary-for QResizeEvent (0x0x7f58d7f2ce38) + +Vtable for QCloseEvent +QCloseEvent::_ZTV11QCloseEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QCloseEvent) +16 (int (*)(...))QCloseEvent::~QCloseEvent +24 (int (*)(...))QCloseEvent::~QCloseEvent + +Class QCloseEvent + size=24 align=8 + base size=20 base align=8 +QCloseEvent (0x0x7f58d7f2cea0) 0 + vptr=((& QCloseEvent::_ZTV11QCloseEvent) + 16u) + QEvent (0x0x7f58d7c402a0) 0 + primary-for QCloseEvent (0x0x7f58d7f2cea0) + +Vtable for QIconDragEvent +QIconDragEvent::_ZTV14QIconDragEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QIconDragEvent) +16 (int (*)(...))QIconDragEvent::~QIconDragEvent +24 (int (*)(...))QIconDragEvent::~QIconDragEvent + +Class QIconDragEvent + size=24 align=8 + base size=20 base align=8 +QIconDragEvent (0x0x7f58d7f2cf08) 0 + vptr=((& QIconDragEvent::_ZTV14QIconDragEvent) + 16u) + QEvent (0x0x7f58d7c40300) 0 + primary-for QIconDragEvent (0x0x7f58d7f2cf08) + +Vtable for QShowEvent +QShowEvent::_ZTV10QShowEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QShowEvent) +16 (int (*)(...))QShowEvent::~QShowEvent +24 (int (*)(...))QShowEvent::~QShowEvent + +Class QShowEvent + size=24 align=8 + base size=20 base align=8 +QShowEvent (0x0x7f58d7f2cf70) 0 + vptr=((& QShowEvent::_ZTV10QShowEvent) + 16u) + QEvent (0x0x7f58d7c40360) 0 + primary-for QShowEvent (0x0x7f58d7f2cf70) + +Vtable for QHideEvent +QHideEvent::_ZTV10QHideEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QHideEvent) +16 (int (*)(...))QHideEvent::~QHideEvent +24 (int (*)(...))QHideEvent::~QHideEvent + +Class QHideEvent + size=24 align=8 + base size=20 base align=8 +QHideEvent (0x0x7f58d7c82000) 0 + vptr=((& QHideEvent::_ZTV10QHideEvent) + 16u) + QEvent (0x0x7f58d7c403c0) 0 + primary-for QHideEvent (0x0x7f58d7c82000) + +Vtable for QContextMenuEvent +QContextMenuEvent::_ZTV17QContextMenuEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QContextMenuEvent) +16 (int (*)(...))QContextMenuEvent::~QContextMenuEvent +24 (int (*)(...))QContextMenuEvent::~QContextMenuEvent + +Class QContextMenuEvent + size=56 align=8 + base size=49 base align=8 +QContextMenuEvent (0x0x7f58d7c82068) 0 + vptr=((& QContextMenuEvent::_ZTV17QContextMenuEvent) + 16u) + QInputEvent (0x0x7f58d7c820d0) 0 + primary-for QContextMenuEvent (0x0x7f58d7c82068) + QEvent (0x0x7f58d7c40420) 0 + primary-for QInputEvent (0x0x7f58d7c820d0) + +Class QInputMethodEvent::Attribute + size=32 align=8 + base size=32 base align=8 +QInputMethodEvent::Attribute (0x0x7f58d7c404e0) 0 + +Vtable for QInputMethodEvent +QInputMethodEvent::_ZTV17QInputMethodEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QInputMethodEvent) +16 (int (*)(...))QInputMethodEvent::~QInputMethodEvent +24 (int (*)(...))QInputMethodEvent::~QInputMethodEvent + +Class QInputMethodEvent + size=56 align=8 + base size=56 base align=8 +QInputMethodEvent (0x0x7f58d7c82138) 0 + vptr=((& QInputMethodEvent::_ZTV17QInputMethodEvent) + 16u) + QEvent (0x0x7f58d7c40480) 0 + primary-for QInputMethodEvent (0x0x7f58d7c82138) + +Class QInputMethodQueryEvent::QueryPair + size=24 align=8 + base size=24 base align=8 +QInputMethodQueryEvent::QueryPair (0x0x7f58d7c40960) 0 + +Vtable for QInputMethodQueryEvent +QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QInputMethodQueryEvent) +16 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent +24 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent + +Class QInputMethodQueryEvent + size=32 align=8 + base size=32 base align=8 +QInputMethodQueryEvent (0x0x7f58d7c82478) 0 + vptr=((& QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent) + 16u) + QEvent (0x0x7f58d7c40900) 0 + primary-for QInputMethodQueryEvent (0x0x7f58d7c82478) + +Vtable for QDropEvent +QDropEvent::_ZTV10QDropEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QDropEvent) +16 (int (*)(...))QDropEvent::~QDropEvent +24 (int (*)(...))QDropEvent::~QDropEvent + +Class QDropEvent + size=72 align=8 + base size=72 base align=8 +QDropEvent (0x0x7f58d7c82750) 0 + vptr=((& QDropEvent::_ZTV10QDropEvent) + 16u) + QEvent (0x0x7f58d7c40cc0) 0 + primary-for QDropEvent (0x0x7f58d7c82750) + +Vtable for QDragMoveEvent +QDragMoveEvent::_ZTV14QDragMoveEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QDragMoveEvent) +16 (int (*)(...))QDragMoveEvent::~QDragMoveEvent +24 (int (*)(...))QDragMoveEvent::~QDragMoveEvent + +Class QDragMoveEvent + size=88 align=8 + base size=88 base align=8 +QDragMoveEvent (0x0x7f58d7c827b8) 0 + vptr=((& QDragMoveEvent::_ZTV14QDragMoveEvent) + 16u) + QDropEvent (0x0x7f58d7c82820) 0 + primary-for QDragMoveEvent (0x0x7f58d7c827b8) + QEvent (0x0x7f58d7c40d20) 0 + primary-for QDropEvent (0x0x7f58d7c82820) + +Vtable for QDragEnterEvent +QDragEnterEvent::_ZTV15QDragEnterEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QDragEnterEvent) +16 (int (*)(...))QDragEnterEvent::~QDragEnterEvent +24 (int (*)(...))QDragEnterEvent::~QDragEnterEvent + +Class QDragEnterEvent + size=88 align=8 + base size=88 base align=8 +QDragEnterEvent (0x0x7f58d7c82888) 0 + vptr=((& QDragEnterEvent::_ZTV15QDragEnterEvent) + 16u) + QDragMoveEvent (0x0x7f58d7c828f0) 0 + primary-for QDragEnterEvent (0x0x7f58d7c82888) + QDropEvent (0x0x7f58d7c82958) 0 + primary-for QDragMoveEvent (0x0x7f58d7c828f0) + QEvent (0x0x7f58d7c40d80) 0 + primary-for QDropEvent (0x0x7f58d7c82958) + +Vtable for QDragLeaveEvent +QDragLeaveEvent::_ZTV15QDragLeaveEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QDragLeaveEvent) +16 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent +24 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent + +Class QDragLeaveEvent + size=24 align=8 + base size=20 base align=8 +QDragLeaveEvent (0x0x7f58d7c829c0) 0 + vptr=((& QDragLeaveEvent::_ZTV15QDragLeaveEvent) + 16u) + QEvent (0x0x7f58d7c40de0) 0 + primary-for QDragLeaveEvent (0x0x7f58d7c829c0) + +Vtable for QHelpEvent +QHelpEvent::_ZTV10QHelpEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QHelpEvent) +16 (int (*)(...))QHelpEvent::~QHelpEvent +24 (int (*)(...))QHelpEvent::~QHelpEvent + +Class QHelpEvent + size=40 align=8 + base size=36 base align=8 +QHelpEvent (0x0x7f58d7c82a28) 0 + vptr=((& QHelpEvent::_ZTV10QHelpEvent) + 16u) + QEvent (0x0x7f58d7c40e40) 0 + primary-for QHelpEvent (0x0x7f58d7c82a28) + +Vtable for QStatusTipEvent +QStatusTipEvent::_ZTV15QStatusTipEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QStatusTipEvent) +16 (int (*)(...))QStatusTipEvent::~QStatusTipEvent +24 (int (*)(...))QStatusTipEvent::~QStatusTipEvent + +Class QStatusTipEvent + size=32 align=8 + base size=32 base align=8 +QStatusTipEvent (0x0x7f58d7c82a90) 0 + vptr=((& QStatusTipEvent::_ZTV15QStatusTipEvent) + 16u) + QEvent (0x0x7f58d7c40ea0) 0 + primary-for QStatusTipEvent (0x0x7f58d7c82a90) + +Vtable for QWhatsThisClickedEvent +QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QWhatsThisClickedEvent) +16 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent +24 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent + +Class QWhatsThisClickedEvent + size=32 align=8 + base size=32 base align=8 +QWhatsThisClickedEvent (0x0x7f58d7c82af8) 0 + vptr=((& QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent) + 16u) + QEvent (0x0x7f58d7c40f00) 0 + primary-for QWhatsThisClickedEvent (0x0x7f58d7c82af8) + +Vtable for QActionEvent +QActionEvent::_ZTV12QActionEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QActionEvent) +16 (int (*)(...))QActionEvent::~QActionEvent +24 (int (*)(...))QActionEvent::~QActionEvent + +Class QActionEvent + size=40 align=8 + base size=40 base align=8 +QActionEvent (0x0x7f58d7c82b60) 0 + vptr=((& QActionEvent::_ZTV12QActionEvent) + 16u) + QEvent (0x0x7f58d7c40f60) 0 + primary-for QActionEvent (0x0x7f58d7c82b60) + +Vtable for QFileOpenEvent +QFileOpenEvent::_ZTV14QFileOpenEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QFileOpenEvent) +16 (int (*)(...))QFileOpenEvent::~QFileOpenEvent +24 (int (*)(...))QFileOpenEvent::~QFileOpenEvent + +Class QFileOpenEvent + size=40 align=8 + base size=40 base align=8 +QFileOpenEvent (0x0x7f58d7c82bc8) 0 + vptr=((& QFileOpenEvent::_ZTV14QFileOpenEvent) + 16u) + QEvent (0x0x7f58d7d4c000) 0 + primary-for QFileOpenEvent (0x0x7f58d7c82bc8) + +Vtable for QToolBarChangeEvent +QToolBarChangeEvent::_ZTV19QToolBarChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QToolBarChangeEvent) +16 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent +24 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent + +Class QToolBarChangeEvent + size=24 align=8 + base size=21 base align=8 +QToolBarChangeEvent (0x0x7f58d7c82c30) 0 + vptr=((& QToolBarChangeEvent::_ZTV19QToolBarChangeEvent) + 16u) + QEvent (0x0x7f58d7d4c060) 0 + primary-for QToolBarChangeEvent (0x0x7f58d7c82c30) + +Vtable for QShortcutEvent +QShortcutEvent::_ZTV14QShortcutEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QShortcutEvent) +16 (int (*)(...))QShortcutEvent::~QShortcutEvent +24 (int (*)(...))QShortcutEvent::~QShortcutEvent + +Class QShortcutEvent + size=40 align=8 + base size=40 base align=8 +QShortcutEvent (0x0x7f58d7c82c98) 0 + vptr=((& QShortcutEvent::_ZTV14QShortcutEvent) + 16u) + QEvent (0x0x7f58d7d4c0c0) 0 + primary-for QShortcutEvent (0x0x7f58d7c82c98) + +Vtable for QWindowStateChangeEvent +QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QWindowStateChangeEvent) +16 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent +24 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent + +Class QWindowStateChangeEvent + size=32 align=8 + base size=25 base align=8 +QWindowStateChangeEvent (0x0x7f58d7c82d00) 0 + vptr=((& QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent) + 16u) + QEvent (0x0x7f58d7d4c120) 0 + primary-for QWindowStateChangeEvent (0x0x7f58d7c82d00) + +Class QPointingDeviceUniqueId + size=8 align=8 + base size=8 base align=8 +QPointingDeviceUniqueId (0x0x7f58d7d4c180) 0 + +Class QTouchEvent::TouchPoint + size=8 align=8 + base size=8 base align=8 +QTouchEvent::TouchPoint (0x0x7f58d7d4c840) 0 + +Vtable for QTouchEvent +QTouchEvent::_ZTV11QTouchEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTouchEvent) +16 (int (*)(...))QTouchEvent::~QTouchEvent +24 (int (*)(...))QTouchEvent::~QTouchEvent + +Class QTouchEvent + size=72 align=8 + base size=72 base align=8 +QTouchEvent (0x0x7f58d7d733a8) 0 + vptr=((& QTouchEvent::_ZTV11QTouchEvent) + 16u) + QInputEvent (0x0x7f58d7d73410) 0 + primary-for QTouchEvent (0x0x7f58d7d733a8) + QEvent (0x0x7f58d7d4c7e0) 0 + primary-for QInputEvent (0x0x7f58d7d73410) + +Vtable for QScrollPrepareEvent +QScrollPrepareEvent::_ZTV19QScrollPrepareEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QScrollPrepareEvent) +16 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent +24 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent + +Class QScrollPrepareEvent + size=112 align=8 + base size=112 base align=8 +QScrollPrepareEvent (0x0x7f58d7a34c30) 0 + vptr=((& QScrollPrepareEvent::_ZTV19QScrollPrepareEvent) + 16u) + QEvent (0x0x7f58d7a33ea0) 0 + primary-for QScrollPrepareEvent (0x0x7f58d7a34c30) + +Vtable for QScrollEvent +QScrollEvent::_ZTV12QScrollEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QScrollEvent) +16 (int (*)(...))QScrollEvent::~QScrollEvent +24 (int (*)(...))QScrollEvent::~QScrollEvent + +Class QScrollEvent + size=64 align=8 + base size=60 base align=8 +QScrollEvent (0x0x7f58d7a34c98) 0 + vptr=((& QScrollEvent::_ZTV12QScrollEvent) + 16u) + QEvent (0x0x7f58d7a33f00) 0 + primary-for QScrollEvent (0x0x7f58d7a34c98) + +Vtable for QScreenOrientationChangeEvent +QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QScreenOrientationChangeEvent) +16 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent +24 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent + +Class QScreenOrientationChangeEvent + size=40 align=8 + base size=36 base align=8 +QScreenOrientationChangeEvent (0x0x7f58d7a34d00) 0 + vptr=((& QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent) + 16u) + QEvent (0x0x7f58d7a33f60) 0 + primary-for QScreenOrientationChangeEvent (0x0x7f58d7a34d00) + +Vtable for QApplicationStateChangeEvent +QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI28QApplicationStateChangeEvent) +16 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent +24 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent + +Class QApplicationStateChangeEvent + size=24 align=8 + base size=24 base align=8 +QApplicationStateChangeEvent (0x0x7f58d7a34d68) 0 + vptr=((& QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent) + 16u) + QEvent (0x0x7f58d7a88000) 0 + primary-for QApplicationStateChangeEvent (0x0x7f58d7a34d68) + +Class QFont + size=16 align=8 + base size=12 base align=8 +QFont (0x0x7f58d7a88060) 0 + +Class QPolygon + size=8 align=8 + base size=8 base align=8 +QPolygon (0x0x7f58d7ae6af8) 0 + QVector (0x0x7f58d7a88d20) 0 + +Class QPolygonF + size=8 align=8 + base size=8 base align=8 +QPolygonF (0x0x7f58d7ae6ea0) 0 + QVector (0x0x7f58d7b5f1e0) 0 + +Class QMatrix + size=48 align=8 + base size=48 base align=8 +QMatrix (0x0x7f58d7b5f5a0) 0 + +Class QPainterPath::Element + size=24 align=8 + base size=24 base align=8 +QPainterPath::Element (0x0x7f58d7b5f8a0) 0 + +Class QPainterPath + size=8 align=8 + base size=8 base align=8 +QPainterPath (0x0x7f58d7b5f840) 0 + +Class QPainterPathStroker + size=8 align=8 + base size=8 base align=8 +QPainterPathStroker (0x0x7f58d786c2a0) 0 + +Class QTransform + size=88 align=8 + base size=88 base align=8 +QTransform (0x0x7f58d786c3c0) 0 + +Vtable for QPaintDevice +QPaintDevice::_ZTV12QPaintDevice: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QPaintDevice) +16 0u +24 0u +32 (int (*)(...))QPaintDevice::devType +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QPaintDevice + size=24 align=8 + base size=24 base align=8 +QPaintDevice (0x0x7f58d786cae0) 0 + vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 16u) + +Class QPixelFormat + size=8 align=8 + base size=8 base align=8 +QPixelFormat (0x0x7f58d786cb40) 0 + +Vtable for QImage +QImage::_ZTV6QImage: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QImage) +16 (int (*)(...))QImage::~QImage +24 (int (*)(...))QImage::~QImage +32 (int (*)(...))QImage::devType +40 (int (*)(...))QImage::paintEngine +48 (int (*)(...))QImage::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QImage + size=32 align=8 + base size=32 base align=8 +QImage (0x0x7f58d78ded68) 0 + vptr=((& QImage::_ZTV6QImage) + 16u) + QPaintDevice (0x0x7f58d7997600) 0 + primary-for QImage (0x0x7f58d78ded68) + +Vtable for QPixmap +QPixmap::_ZTV7QPixmap: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QPixmap) +16 (int (*)(...))QPixmap::~QPixmap +24 (int (*)(...))QPixmap::~QPixmap +32 (int (*)(...))QPixmap::devType +40 (int (*)(...))QPixmap::paintEngine +48 (int (*)(...))QPixmap::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QPixmap + size=32 align=8 + base size=32 base align=8 +QPixmap (0x0x7f58d767d8f0) 0 + vptr=((& QPixmap::_ZTV7QPixmap) + 16u) + QPaintDevice (0x0x7f58d76795a0) 0 + primary-for QPixmap (0x0x7f58d767d8f0) + +Class QBrush + size=8 align=8 + base size=8 base align=8 +QBrush (0x0x7f58d76798a0) 0 + +Class QBrushData + size=112 align=8 + base size=112 base align=8 +QBrushData (0x0x7f58d7711060) 0 + +Class QGradient + size=64 align=8 + base size=64 base align=8 +QGradient (0x0x7f58d77110c0) 0 + +Class QLinearGradient + size=64 align=8 + base size=64 base align=8 +QLinearGradient (0x0x7f58d770f270) 0 + QGradient (0x0x7f58d7711360) 0 + +Class QRadialGradient + size=64 align=8 + base size=64 base align=8 +QRadialGradient (0x0x7f58d770f2d8) 0 + QGradient (0x0x7f58d77113c0) 0 + +Class QConicalGradient + size=64 align=8 + base size=64 base align=8 +QConicalGradient (0x0x7f58d770f340) 0 + QGradient (0x0x7f58d7711420) 0 + +Class QPen + size=8 align=8 + base size=8 base align=8 +QPen (0x0x7f58d7711480) 0 + +Class QTextOption::Tab + size=16 align=8 + base size=14 base align=8 +QTextOption::Tab (0x0x7f58d73fe6c0) 0 + +Class QTextOption + size=32 align=8 + base size=32 base align=8 +QTextOption (0x0x7f58d73fe660) 0 + +Class QTextLength + size=16 align=8 + base size=16 base align=8 +QTextLength (0x0x7f58d73fee40) 0 + +Class QTextFormat + size=16 align=8 + base size=12 base align=8 +QTextFormat (0x0x7f58d748d5a0) 0 + +Class QTextCharFormat + size=16 align=8 + base size=12 base align=8 +QTextCharFormat (0x0x7f58d7563270) 0 + QTextFormat (0x0x7f58d752e420) 0 + +Class QTextBlockFormat + size=16 align=8 + base size=12 base align=8 +QTextBlockFormat (0x0x7f58d7563478) 0 + QTextFormat (0x0x7f58d752e6c0) 0 + +Class QTextListFormat + size=16 align=8 + base size=12 base align=8 +QTextListFormat (0x0x7f58d75636e8) 0 + QTextFormat (0x0x7f58d752e960) 0 + +Class QTextImageFormat + size=16 align=8 + base size=12 base align=8 +QTextImageFormat (0x0x7f58d75638f0) 0 + QTextCharFormat (0x0x7f58d7563958) 0 + QTextFormat (0x0x7f58d752ec00) 0 + +Class QTextFrameFormat + size=16 align=8 + base size=12 base align=8 +QTextFrameFormat (0x0x7f58d7563b60) 0 + QTextFormat (0x0x7f58d752eea0) 0 + +Class QTextTableFormat + size=16 align=8 + base size=12 base align=8 +QTextTableFormat (0x0x7f58d7563d68) 0 + QTextFrameFormat (0x0x7f58d7563dd0) 0 + QTextFormat (0x0x7f58d7249180) 0 + +Class QTextTableCellFormat + size=16 align=8 + base size=12 base align=8 +QTextTableCellFormat (0x0x7f58d727a000) 0 + QTextCharFormat (0x0x7f58d727a068) 0 + QTextFormat (0x0x7f58d7249480) 0 + +Class QFontDatabase + size=8 align=8 + base size=8 base align=8 +QFontDatabase (0x0x7f58d7249720) 0 + +Class QRawFont + size=8 align=8 + base size=8 base align=8 +QRawFont (0x0x7f58d7249780) 0 + +Class QGlyphRun + size=8 align=8 + base size=8 base align=8 +QGlyphRun (0x0x7f58d7249c60) 0 + +Class QTextCursor + size=8 align=8 + base size=8 base align=8 +QTextCursor (0x0x7f58d7249f60) 0 + +Class QTextInlineObject + size=16 align=8 + base size=16 base align=8 +QTextInlineObject (0x0x7f58d73412a0) 0 + +Class QTextLayout::FormatRange + size=24 align=8 + base size=24 base align=8 +QTextLayout::FormatRange (0x0x7f58d7341360) 0 + +Class QTextLayout + size=8 align=8 + base size=8 base align=8 +QTextLayout (0x0x7f58d7341300) 0 + +Class QTextLine + size=16 align=8 + base size=16 base align=8 +QTextLine (0x0x7f58d7341d80) 0 + +Vtable for QAbstractUndoItem +QAbstractUndoItem::_ZTV17QAbstractUndoItem: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAbstractUndoItem) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QAbstractUndoItem + size=8 align=8 + base size=8 base align=8 +QAbstractUndoItem (0x0x7f58d7341de0) 0 nearly-empty + vptr=((& QAbstractUndoItem::_ZTV17QAbstractUndoItem) + 16u) + +Class QTextDocument::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextDocument::QPrivateSignal (0x0x7f58d7341ea0) 0 empty + +Vtable for QTextDocument +QTextDocument::_ZTV13QTextDocument: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QTextDocument) +16 (int (*)(...))QTextDocument::metaObject +24 (int (*)(...))QTextDocument::qt_metacast +32 (int (*)(...))QTextDocument::qt_metacall +40 (int (*)(...))QTextDocument::~QTextDocument +48 (int (*)(...))QTextDocument::~QTextDocument +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextDocument::clear +120 (int (*)(...))QTextDocument::createObject +128 (int (*)(...))QTextDocument::loadResource + +Class QTextDocument + size=16 align=8 + base size=16 base align=8 +QTextDocument (0x0x7f58d6fc13a8) 0 + vptr=((& QTextDocument::_ZTV13QTextDocument) + 16u) + QObject (0x0x7f58d7341e40) 0 + primary-for QTextDocument (0x0x7f58d6fc13a8) + +Class QPalette::Data + size=4 align=4 + base size=4 base align=4 +QPalette::Data (0x0x7f58d7014120) 0 + +Class QPalette + size=16 align=8 + base size=12 base align=8 +QPalette (0x0x7f58d70140c0) 0 + +Class QAbstractTextDocumentLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTextDocumentLayout::QPrivateSignal (0x0x7f58d71011e0) 0 empty + +Class QAbstractTextDocumentLayout::Selection + size=24 align=8 + base size=24 base align=8 +QAbstractTextDocumentLayout::Selection (0x0x7f58d7101240) 0 + +Class QAbstractTextDocumentLayout::PaintContext + size=64 align=8 + base size=64 base align=8 +QAbstractTextDocumentLayout::PaintContext (0x0x7f58d71012a0) 0 + +Vtable for QAbstractTextDocumentLayout +QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAbstractTextDocumentLayout) +16 (int (*)(...))QAbstractTextDocumentLayout::metaObject +24 (int (*)(...))QAbstractTextDocumentLayout::qt_metacast +32 (int (*)(...))QAbstractTextDocumentLayout::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractTextDocumentLayout::resizeInlineObject +176 (int (*)(...))QAbstractTextDocumentLayout::positionInlineObject +184 (int (*)(...))QAbstractTextDocumentLayout::drawInlineObject + +Class QAbstractTextDocumentLayout + size=16 align=8 + base size=16 base align=8 +QAbstractTextDocumentLayout (0x0x7f58d71040d0) 0 + vptr=((& QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout) + 16u) + QObject (0x0x7f58d7101180) 0 + primary-for QAbstractTextDocumentLayout (0x0x7f58d71040d0) + +Vtable for QTextObjectInterface +QTextObjectInterface::_ZTV20QTextObjectInterface: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTextObjectInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QTextObjectInterface + size=8 align=8 + base size=8 base align=8 +QTextObjectInterface (0x0x7f58d7101840) 0 nearly-empty + vptr=((& QTextObjectInterface::_ZTV20QTextObjectInterface) + 16u) + +Class QAccessible::State + size=8 align=8 + base size=5 base align=8 +QAccessible::State (0x0x7f58d7101960) 0 + +Vtable for QAccessible::ActivationObserver +QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN11QAccessible18ActivationObserverE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAccessible::ActivationObserver + size=8 align=8 + base size=8 base align=8 +QAccessible::ActivationObserver (0x0x7f58d71019c0) 0 nearly-empty + vptr=((& QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE) + 16u) + +Class QAccessible + size=1 align=1 + base size=0 base align=1 +QAccessible (0x0x7f58d7101900) 0 empty + +Vtable for QAccessibleInterface +QAccessibleInterface::_ZTV20QAccessibleInterface: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QAccessibleInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QAccessibleInterface::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleInterface::focusChild +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleInterface (0x0x7f58d7101ba0) 0 nearly-empty + vptr=((& QAccessibleInterface::_ZTV20QAccessibleInterface) + 16u) + +Vtable for QAccessibleTextInterface +QAccessibleTextInterface::_ZTV24QAccessibleTextInterface: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAccessibleTextInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))QAccessibleTextInterface::textBeforeOffset +104 (int (*)(...))QAccessibleTextInterface::textAfterOffset +112 (int (*)(...))QAccessibleTextInterface::textAtOffset +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTextInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTextInterface (0x0x7f58d7101c00) 0 nearly-empty + vptr=((& QAccessibleTextInterface::_ZTV24QAccessibleTextInterface) + 16u) + +Vtable for QAccessibleEditableTextInterface +QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI32QAccessibleEditableTextInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleEditableTextInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleEditableTextInterface (0x0x7f58d7101c60) 0 nearly-empty + vptr=((& QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface) + 16u) + +Vtable for QAccessibleValueInterface +QAccessibleValueInterface::_ZTV25QAccessibleValueInterface: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleValueInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleValueInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleValueInterface (0x0x7f58d7101cc0) 0 nearly-empty + vptr=((& QAccessibleValueInterface::_ZTV25QAccessibleValueInterface) + 16u) + +Vtable for QAccessibleTableCellInterface +QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface: 12u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QAccessibleTableCellInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTableCellInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTableCellInterface (0x0x7f58d7101d20) 0 nearly-empty + vptr=((& QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface) + 16u) + +Vtable for QAccessibleTableInterface +QAccessibleTableInterface::_ZTV25QAccessibleTableInterface: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleTableInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleTableInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleTableInterface (0x0x7f58d7101d80) 0 nearly-empty + vptr=((& QAccessibleTableInterface::_ZTV25QAccessibleTableInterface) + 16u) + +Vtable for QAccessibleActionInterface +QAccessibleActionInterface::_ZTV26QAccessibleActionInterface: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleActionInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QAccessibleActionInterface::localizedActionName +48 (int (*)(...))QAccessibleActionInterface::localizedActionDescription +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleActionInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleActionInterface (0x0x7f58d7101de0) 0 nearly-empty + vptr=((& QAccessibleActionInterface::_ZTV26QAccessibleActionInterface) + 16u) + +Vtable for QAccessibleImageInterface +QAccessibleImageInterface::_ZTV25QAccessibleImageInterface: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QAccessibleImageInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleImageInterface + size=8 align=8 + base size=8 base align=8 +QAccessibleImageInterface (0x0x7f58d7101e40) 0 nearly-empty + vptr=((& QAccessibleImageInterface::_ZTV25QAccessibleImageInterface) + 16u) + +Vtable for QAccessibleEvent +QAccessibleEvent::_ZTV16QAccessibleEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAccessibleEvent) +16 (int (*)(...))QAccessibleEvent::~QAccessibleEvent +24 (int (*)(...))QAccessibleEvent::~QAccessibleEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleEvent + size=32 align=8 + base size=28 base align=8 +QAccessibleEvent (0x0x7f58d7101ea0) 0 + vptr=((& QAccessibleEvent::_ZTV16QAccessibleEvent) + 16u) + +Vtable for QAccessibleStateChangeEvent +QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAccessibleStateChangeEvent) +16 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent +24 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleStateChangeEvent + size=40 align=8 + base size=40 base align=8 +QAccessibleStateChangeEvent (0x0x7f58d7104af8) 0 + vptr=((& QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent) + 16u) + QAccessibleEvent (0x0x7f58d6e02420) 0 + primary-for QAccessibleStateChangeEvent (0x0x7f58d7104af8) + +Vtable for QAccessibleTextCursorEvent +QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextCursorEvent) +16 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent +24 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextCursorEvent + size=32 align=8 + base size=32 base align=8 +QAccessibleTextCursorEvent (0x0x7f58d7104b60) 0 + vptr=((& QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent) + 16u) + QAccessibleEvent (0x0x7f58d6e02480) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f58d7104b60) + +Vtable for QAccessibleTextSelectionEvent +QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI29QAccessibleTextSelectionEvent) +16 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent +24 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextSelectionEvent + size=40 align=8 + base size=40 base align=8 +QAccessibleTextSelectionEvent (0x0x7f58d7104bc8) 0 + vptr=((& QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7f58d7104c30) 0 + primary-for QAccessibleTextSelectionEvent (0x0x7f58d7104bc8) + QAccessibleEvent (0x0x7f58d6e024e0) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f58d7104c30) + +Vtable for QAccessibleTextInsertEvent +QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextInsertEvent) +16 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent +24 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextInsertEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTextInsertEvent (0x0x7f58d7104c98) 0 + vptr=((& QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7f58d7104d00) 0 + primary-for QAccessibleTextInsertEvent (0x0x7f58d7104c98) + QAccessibleEvent (0x0x7f58d6e02540) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f58d7104d00) + +Vtable for QAccessibleTextRemoveEvent +QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextRemoveEvent) +16 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent +24 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextRemoveEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTextRemoveEvent (0x0x7f58d7104d68) 0 + vptr=((& QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7f58d7104dd0) 0 + primary-for QAccessibleTextRemoveEvent (0x0x7f58d7104d68) + QAccessibleEvent (0x0x7f58d6e025a0) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f58d7104dd0) + +Vtable for QAccessibleTextUpdateEvent +QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAccessibleTextUpdateEvent) +16 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent +24 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTextUpdateEvent + size=56 align=8 + base size=56 base align=8 +QAccessibleTextUpdateEvent (0x0x7f58d7104e38) 0 + vptr=((& QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent) + 16u) + QAccessibleTextCursorEvent (0x0x7f58d7104ea0) 0 + primary-for QAccessibleTextUpdateEvent (0x0x7f58d7104e38) + QAccessibleEvent (0x0x7f58d6e02600) 0 + primary-for QAccessibleTextCursorEvent (0x0x7f58d7104ea0) + +Vtable for QAccessibleValueChangeEvent +QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QAccessibleValueChangeEvent) +16 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent +24 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleValueChangeEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleValueChangeEvent (0x0x7f58d7104f08) 0 + vptr=((& QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent) + 16u) + QAccessibleEvent (0x0x7f58d6e02660) 0 + primary-for QAccessibleValueChangeEvent (0x0x7f58d7104f08) + +Vtable for QAccessibleTableModelChangeEvent +QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI32QAccessibleTableModelChangeEvent) +16 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent +24 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent +32 (int (*)(...))QAccessibleEvent::accessibleInterface + +Class QAccessibleTableModelChangeEvent + size=48 align=8 + base size=48 base align=8 +QAccessibleTableModelChangeEvent (0x0x7f58d7104f70) 0 + vptr=((& QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent) + 16u) + QAccessibleEvent (0x0x7f58d6e026c0) 0 + primary-for QAccessibleTableModelChangeEvent (0x0x7f58d7104f70) + +Vtable for QAccessibleBridge +QAccessibleBridge::_ZTV17QAccessibleBridge: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleBridge) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleBridge + size=8 align=8 + base size=8 base align=8 +QAccessibleBridge (0x0x7f58d6e02780) 0 nearly-empty + vptr=((& QAccessibleBridge::_ZTV17QAccessibleBridge) + 16u) + +Class QAccessibleBridgePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAccessibleBridgePlugin::QPrivateSignal (0x0x7f58d6e02840) 0 empty + +Vtable for QAccessibleBridgePlugin +QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QAccessibleBridgePlugin) +16 (int (*)(...))QAccessibleBridgePlugin::metaObject +24 (int (*)(...))QAccessibleBridgePlugin::qt_metacast +32 (int (*)(...))QAccessibleBridgePlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QAccessibleBridgePlugin + size=16 align=8 + base size=16 base align=8 +QAccessibleBridgePlugin (0x0x7f58d6ed4000) 0 + vptr=((& QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin) + 16u) + QObject (0x0x7f58d6e027e0) 0 + primary-for QAccessibleBridgePlugin (0x0x7f58d6ed4000) + +Vtable for QAccessibleObject +QAccessibleObject::_ZTV17QAccessibleObject: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleObject) +16 0u +24 0u +32 (int (*)(...))QAccessibleObject::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleInterface::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleInterface::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleObject::rect +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleObject + size=16 align=8 + base size=16 base align=8 +QAccessibleObject (0x0x7f58d6ed4068) 0 + vptr=((& QAccessibleObject::_ZTV17QAccessibleObject) + 16u) + QAccessibleInterface (0x0x7f58d6e028a0) 0 nearly-empty + primary-for QAccessibleObject (0x0x7f58d6ed4068) + +Vtable for QAccessibleApplication +QAccessibleApplication::_ZTV22QAccessibleApplication: 23u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QAccessibleApplication) +16 (int (*)(...))QAccessibleApplication::~QAccessibleApplication +24 (int (*)(...))QAccessibleApplication::~QAccessibleApplication +32 (int (*)(...))QAccessibleObject::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleApplication::window +56 (int (*)(...))QAccessibleInterface::relations +64 (int (*)(...))QAccessibleApplication::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))QAccessibleApplication::parent +88 (int (*)(...))QAccessibleApplication::child +96 (int (*)(...))QAccessibleApplication::childCount +104 (int (*)(...))QAccessibleApplication::indexOfChild +112 (int (*)(...))QAccessibleApplication::text +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleObject::rect +136 (int (*)(...))QAccessibleApplication::role +144 (int (*)(...))QAccessibleApplication::state +152 (int (*)(...))QAccessibleInterface::foregroundColor +160 (int (*)(...))QAccessibleInterface::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleInterface::interface_cast + +Class QAccessibleApplication + size=16 align=8 + base size=16 base align=8 +QAccessibleApplication (0x0x7f58d6ed40d0) 0 + vptr=((& QAccessibleApplication::_ZTV22QAccessibleApplication) + 16u) + QAccessibleObject (0x0x7f58d6ed4138) 0 + primary-for QAccessibleApplication (0x0x7f58d6ed40d0) + QAccessibleInterface (0x0x7f58d6e02900) 0 nearly-empty + primary-for QAccessibleObject (0x0x7f58d6ed4138) + +Class QAccessiblePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAccessiblePlugin::QPrivateSignal (0x0x7f58d6e029c0) 0 empty + +Vtable for QAccessiblePlugin +QAccessiblePlugin::_ZTV17QAccessiblePlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessiblePlugin) +16 (int (*)(...))QAccessiblePlugin::metaObject +24 (int (*)(...))QAccessiblePlugin::qt_metacast +32 (int (*)(...))QAccessiblePlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QAccessiblePlugin + size=16 align=8 + base size=16 base align=8 +QAccessiblePlugin (0x0x7f58d6ed41a0) 0 + vptr=((& QAccessiblePlugin::_ZTV17QAccessiblePlugin) + 16u) + QObject (0x0x7f58d6e02960) 0 + primary-for QAccessiblePlugin (0x0x7f58d6ed41a0) + +Class QSurfaceFormat + size=8 align=8 + base size=8 base align=8 +QSurfaceFormat (0x0x7f58d6e02a20) 0 + +Vtable for QSurface +QSurface::_ZTV8QSurface: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QSurface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual + +Class QSurface + size=24 align=8 + base size=24 base align=8 +QSurface (0x0x7f58d6e02c00) 0 + vptr=((& QSurface::_ZTV8QSurface) + 16u) + +Class QIcon + size=8 align=8 + base size=8 base align=8 +QIcon (0x0x7f58d6e02d80) 0 + +Class QCursor + size=8 align=8 + base size=8 base align=8 +QCursor (0x0x7f58d6bf2180) 0 + +Class QWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWindow::QPrivateSignal (0x0x7f58d6c77780) 0 empty + +Vtable for QWindow +QWindow::_ZTV7QWindow: 45u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QWindow) +16 (int (*)(...))QWindow::metaObject +24 (int (*)(...))QWindow::qt_metacast +32 (int (*)(...))QWindow::qt_metacall +40 (int (*)(...))QWindow::~QWindow +48 (int (*)(...))QWindow::~QWindow +56 (int (*)(...))QWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))-16 +304 (int (*)(...))(& _ZTI7QWindow) +312 (int (*)(...))QWindow::_ZThn16_N7QWindowD1Ev +320 (int (*)(...))QWindow::_ZThn16_N7QWindowD0Ev +328 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +336 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +344 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv + +Class QWindow + size=40 align=8 + base size=40 base align=8 +QWindow (0x0x7f58d6c80700) 0 + vptr=((& QWindow::_ZTV7QWindow) + 16u) + QObject (0x0x7f58d6c776c0) 0 + primary-for QWindow (0x0x7f58d6c80700) + QSurface (0x0x7f58d6c77720) 16 + vptr=((& QWindow::_ZTV7QWindow) + 312u) + +Class QBackingStore + size=8 align=8 + base size=8 base align=8 +QBackingStore (0x0x7f58d6c778a0) 0 + +Vtable for QBitmap +QBitmap::_ZTV7QBitmap: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBitmap) +16 (int (*)(...))QBitmap::~QBitmap +24 (int (*)(...))QBitmap::~QBitmap +32 (int (*)(...))QPixmap::devType +40 (int (*)(...))QPixmap::paintEngine +48 (int (*)(...))QPixmap::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter + +Class QBitmap + size=32 align=8 + base size=32 base align=8 +QBitmap (0x0x7f58d6c88208) 0 + vptr=((& QBitmap::_ZTV7QBitmap) + 16u) + QPixmap (0x0x7f58d6c88270) 0 + primary-for QBitmap (0x0x7f58d6c88208) + QPaintDevice (0x0x7f58d6c77960) 0 + primary-for QPixmap (0x0x7f58d6c88270) + +Class QClipboard::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QClipboard::QPrivateSignal (0x0x7f58d6c77cc0) 0 empty + +Vtable for QClipboard +QClipboard::_ZTV10QClipboard: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QClipboard) +16 (int (*)(...))QClipboard::metaObject +24 (int (*)(...))QClipboard::qt_metacast +32 (int (*)(...))QClipboard::qt_metacall +40 (int (*)(...))QClipboard::~QClipboard +48 (int (*)(...))QClipboard::~QClipboard +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QClipboard + size=16 align=8 + base size=16 base align=8 +QClipboard (0x0x7f58d6c884e0) 0 + vptr=((& QClipboard::_ZTV10QClipboard) + 16u) + QObject (0x0x7f58d6c77c60) 0 + primary-for QClipboard (0x0x7f58d6c884e0) + +Class QDesktopServices + size=1 align=1 + base size=0 base align=1 +QDesktopServices (0x0x7f58d6c77d20) 0 empty + +Class QDrag::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDrag::QPrivateSignal (0x0x7f58d6c77de0) 0 empty + +Vtable for QDrag +QDrag::_ZTV5QDrag: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QDrag) +16 (int (*)(...))QDrag::metaObject +24 (int (*)(...))QDrag::qt_metacast +32 (int (*)(...))QDrag::qt_metacall +40 (int (*)(...))QDrag::~QDrag +48 (int (*)(...))QDrag::~QDrag +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QDrag + size=16 align=8 + base size=16 base align=8 +QDrag (0x0x7f58d6c88548) 0 + vptr=((& QDrag::_ZTV5QDrag) + 16u) + QObject (0x0x7f58d6c77d80) 0 + primary-for QDrag (0x0x7f58d6c88548) + +Class QFontInfo + size=8 align=8 + base size=8 base align=8 +QFontInfo (0x0x7f58d6c77e40) 0 + +Class QFontMetrics + size=8 align=8 + base size=8 base align=8 +QFontMetrics (0x0x7f58d6d3b120) 0 + +Class QFontMetricsF + size=8 align=8 + base size=8 base align=8 +QFontMetricsF (0x0x7f58d6d3b420) 0 + +Class QGenericPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGenericPlugin::QPrivateSignal (0x0x7f58d6a28900) 0 empty + +Vtable for QGenericPlugin +QGenericPlugin::_ZTV14QGenericPlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QGenericPlugin) +16 (int (*)(...))QGenericPlugin::metaObject +24 (int (*)(...))QGenericPlugin::qt_metacast +32 (int (*)(...))QGenericPlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QGenericPlugin + size=16 align=8 + base size=16 base align=8 +QGenericPlugin (0x0x7f58d6c88dd0) 0 + vptr=((& QGenericPlugin::_ZTV14QGenericPlugin) + 16u) + QObject (0x0x7f58d6a288a0) 0 + primary-for QGenericPlugin (0x0x7f58d6c88dd0) + +Class QGenericPluginFactory + size=1 align=1 + base size=0 base align=1 +QGenericPluginFactory (0x0x7f58d6a28960) 0 empty + +Class QInputMethod::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QInputMethod::QPrivateSignal (0x0x7f58d6a28a20) 0 empty + +Vtable for QInputMethod +QInputMethod::_ZTV12QInputMethod: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QInputMethod) +16 (int (*)(...))QInputMethod::metaObject +24 (int (*)(...))QInputMethod::qt_metacast +32 (int (*)(...))QInputMethod::qt_metacall +40 (int (*)(...))QInputMethod::~QInputMethod +48 (int (*)(...))QInputMethod::~QInputMethod +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QInputMethod + size=16 align=8 + base size=16 base align=8 +QInputMethod (0x0x7f58d6c88e38) 0 + vptr=((& QInputMethod::_ZTV12QInputMethod) + 16u) + QObject (0x0x7f58d6a289c0) 0 + primary-for QInputMethod (0x0x7f58d6c88e38) + +Class QGuiApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGuiApplication::QPrivateSignal (0x0x7f58d6a28ae0) 0 empty + +Vtable for QGuiApplication +QGuiApplication::_ZTV15QGuiApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGuiApplication) +16 (int (*)(...))QGuiApplication::metaObject +24 (int (*)(...))QGuiApplication::qt_metacast +32 (int (*)(...))QGuiApplication::qt_metacall +40 (int (*)(...))QGuiApplication::~QGuiApplication +48 (int (*)(...))QGuiApplication::~QGuiApplication +56 (int (*)(...))QGuiApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGuiApplication::notify +120 (int (*)(...))QGuiApplication::compressEvent + +Class QGuiApplication + size=16 align=8 + base size=16 base align=8 +QGuiApplication (0x0x7f58d6c88ea0) 0 + vptr=((& QGuiApplication::_ZTV15QGuiApplication) + 16u) + QCoreApplication (0x0x7f58d6c88f08) 0 + primary-for QGuiApplication (0x0x7f58d6c88ea0) + QObject (0x0x7f58d6a28a80) 0 + primary-for QCoreApplication (0x0x7f58d6c88f08) + +Class QIconEngine::AvailableSizesArgument + size=16 align=8 + base size=16 base align=8 +QIconEngine::AvailableSizesArgument (0x0x7f58d6b12060) 0 + +Class QIconEngine::ScaledPixmapArgument + size=56 align=8 + base size=56 base align=8 +QIconEngine::ScaledPixmapArgument (0x0x7f58d6b121e0) 0 + +Vtable for QIconEngine +QIconEngine::_ZTV11QIconEngine: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QIconEngine) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))QIconEngine::actualSize +48 (int (*)(...))QIconEngine::pixmap +56 (int (*)(...))QIconEngine::addPixmap +64 (int (*)(...))QIconEngine::addFile +72 (int (*)(...))QIconEngine::key +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QIconEngine::read +96 (int (*)(...))QIconEngine::write +104 (int (*)(...))QIconEngine::availableSizes +112 (int (*)(...))QIconEngine::iconName +120 (int (*)(...))QIconEngine::virtual_hook + +Class QIconEngine + size=8 align=8 + base size=8 base align=8 +QIconEngine (0x0x7f58d6b12000) 0 nearly-empty + vptr=((& QIconEngine::_ZTV11QIconEngine) + 16u) + +Class QIconEnginePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIconEnginePlugin::QPrivateSignal (0x0x7f58d6b122a0) 0 empty + +Vtable for QIconEnginePlugin +QIconEnginePlugin::_ZTV17QIconEnginePlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QIconEnginePlugin) +16 (int (*)(...))QIconEnginePlugin::metaObject +24 (int (*)(...))QIconEnginePlugin::qt_metacast +32 (int (*)(...))QIconEnginePlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QIconEnginePlugin + size=16 align=8 + base size=16 base align=8 +QIconEnginePlugin (0x0x7f58d6b04478) 0 + vptr=((& QIconEnginePlugin::_ZTV17QIconEnginePlugin) + 16u) + QObject (0x0x7f58d6b12240) 0 + primary-for QIconEnginePlugin (0x0x7f58d6b04478) + +Vtable for QImageIOHandler +QImageIOHandler::_ZTV15QImageIOHandler: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QImageIOHandler) +16 0u +24 0u +32 (int (*)(...))QImageIOHandler::name +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))QImageIOHandler::write +64 (int (*)(...))QImageIOHandler::option +72 (int (*)(...))QImageIOHandler::setOption +80 (int (*)(...))QImageIOHandler::supportsOption +88 (int (*)(...))QImageIOHandler::jumpToNextImage +96 (int (*)(...))QImageIOHandler::jumpToImage +104 (int (*)(...))QImageIOHandler::loopCount +112 (int (*)(...))QImageIOHandler::imageCount +120 (int (*)(...))QImageIOHandler::nextImageDelay +128 (int (*)(...))QImageIOHandler::currentImageNumber +136 (int (*)(...))QImageIOHandler::currentImageRect + +Class QImageIOHandler + size=16 align=8 + base size=16 base align=8 +QImageIOHandler (0x0x7f58d6b12300) 0 + vptr=((& QImageIOHandler::_ZTV15QImageIOHandler) + 16u) + +Class QImageIOPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QImageIOPlugin::QPrivateSignal (0x0x7f58d6b12480) 0 empty + +Vtable for QImageIOPlugin +QImageIOPlugin::_ZTV14QImageIOPlugin: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QImageIOPlugin) +16 (int (*)(...))QImageIOPlugin::metaObject +24 (int (*)(...))QImageIOPlugin::qt_metacast +32 (int (*)(...))QImageIOPlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QImageIOPlugin + size=16 align=8 + base size=16 base align=8 +QImageIOPlugin (0x0x7f58d6b044e0) 0 + vptr=((& QImageIOPlugin::_ZTV14QImageIOPlugin) + 16u) + QObject (0x0x7f58d6b12420) 0 + primary-for QImageIOPlugin (0x0x7f58d6b044e0) + +Class QImageReader + size=8 align=8 + base size=8 base align=8 +QImageReader (0x0x7f58d6b12660) 0 + +Class QImageWriter + size=8 align=8 + base size=8 base align=8 +QImageWriter (0x0x7f58d6b126c0) 0 + +Class QVector3D + size=12 align=4 + base size=12 base align=4 +QVector3D (0x0x7f58d6b12720) 0 + +Class QVector4D + size=16 align=4 + base size=16 base align=4 +QVector4D (0x0x7f58d6b129c0) 0 + +Class QQuaternion + size=16 align=4 + base size=16 base align=4 +QQuaternion (0x0x7f58d6b12c60) 0 + +Class QMatrix4x4 + size=68 align=4 + base size=68 base align=4 +QMatrix4x4 (0x0x7f58d68bf2a0) 0 + +Class QMovie::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMovie::QPrivateSignal (0x0x7f58d68bfa20) 0 empty + +Vtable for QMovie +QMovie::_ZTV6QMovie: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QMovie) +16 (int (*)(...))QMovie::metaObject +24 (int (*)(...))QMovie::qt_metacast +32 (int (*)(...))QMovie::qt_metacall +40 (int (*)(...))QMovie::~QMovie +48 (int (*)(...))QMovie::~QMovie +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QMovie + size=16 align=8 + base size=16 base align=8 +QMovie (0x0x7f58d69146e8) 0 + vptr=((& QMovie::_ZTV6QMovie) + 16u) + QObject (0x0x7f58d68bf9c0) 0 + primary-for QMovie (0x0x7f58d69146e8) + +Class QOffscreenSurface::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOffscreenSurface::QPrivateSignal (0x0x7f58d68bfb40) 0 empty + +Vtable for QOffscreenSurface +QOffscreenSurface::_ZTV17QOffscreenSurface: 26u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QOffscreenSurface) +16 (int (*)(...))QOffscreenSurface::metaObject +24 (int (*)(...))QOffscreenSurface::qt_metacast +32 (int (*)(...))QOffscreenSurface::qt_metacall +40 (int (*)(...))QOffscreenSurface::~QOffscreenSurface +48 (int (*)(...))QOffscreenSurface::~QOffscreenSurface +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QOffscreenSurface::surfaceType +120 (int (*)(...))QOffscreenSurface::format +128 (int (*)(...))QOffscreenSurface::size +136 (int (*)(...))QOffscreenSurface::surfaceHandle +144 (int (*)(...))-16 +152 (int (*)(...))(& _ZTI17QOffscreenSurface) +160 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD1Ev +168 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD0Ev +176 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface6formatEv +184 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface13surfaceHandleEv +192 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface11surfaceTypeEv +200 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface4sizeEv + +Class QOffscreenSurface + size=40 align=8 + base size=40 base align=8 +QOffscreenSurface (0x0x7f58d65e4ee0) 0 + vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 16u) + QObject (0x0x7f58d68bfa80) 0 + primary-for QOffscreenSurface (0x0x7f58d65e4ee0) + QSurface (0x0x7f58d68bfae0) 16 + vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 160u) + +Class QOpenGLBuffer + size=8 align=8 + base size=8 base align=8 +QOpenGLBuffer (0x0x7f58d68bfc00) 0 + +Class QOpenGLVersionStatus + size=12 align=4 + base size=12 base align=4 +QOpenGLVersionStatus (0x0x7f58d68bfde0) 0 + +Class QOpenGLVersionFunctionsBackend + size=16 align=8 + base size=12 base align=8 +QOpenGLVersionFunctionsBackend (0x0x7f58d5fbe900) 0 + +Class QOpenGLVersionFunctionsStorage + size=8 align=8 + base size=8 base align=8 +QOpenGLVersionFunctionsStorage (0x0x7f58d5fbe960) 0 + +Class QAbstractOpenGLFunctionsPrivate + size=16 align=8 + base size=9 base align=8 +QAbstractOpenGLFunctionsPrivate (0x0x7f58d5fbe9c0) 0 + +Vtable for QAbstractOpenGLFunctions +QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractOpenGLFunctions) +16 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions +24 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions +32 (int (*)(...))QAbstractOpenGLFunctions::initializeOpenGLFunctions + +Class QAbstractOpenGLFunctions + size=16 align=8 + base size=16 base align=8 +QAbstractOpenGLFunctions (0x0x7f58d5fbea20) 0 + vptr=((& QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions) + 16u) + +Class QOpenGLFunctions_1_0_CoreBackend::Functions + size=384 align=8 + base size=384 base align=8 +QOpenGLFunctions_1_0_CoreBackend::Functions (0x0x7f58d5fbeae0) 0 + +Class QOpenGLFunctions_1_0_CoreBackend + size=400 align=8 + base size=400 base align=8 +QOpenGLFunctions_1_0_CoreBackend (0x0x7f58d5fc5958) 0 + QOpenGLVersionFunctionsBackend (0x0x7f58d5fbea80) 0 + +Class QOpenGLFunctions_1_1_CoreBackend::Functions + size=128 align=8 + base size=128 base align=8 +QOpenGLFunctions_1_1_CoreBackend::Functions (0x0x7f58d5fbec00) 0 + +Class QOpenGLFunctions_1_1_CoreBackend + size=144 align=8 + base size=144 base align=8 +QOpenGLFunctions_1_1_CoreBackend (0x0x7f58d5fc59c0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f58d5fbeba0) 0 + +Class QOpenGLFunctions_1_2_CoreBackend::Functions + size=48 align=8 + base size=48 base align=8 +QOpenGLFunctions_1_2_CoreBackend::Functions (0x0x7f58d5fbed20) 0 + +Class QOpenGLFunctions_1_2_CoreBackend + size=64 align=8 + base size=64 base align=8 +QOpenGLFunctions_1_2_CoreBackend (0x0x7f58d5fc5a28) 0 + QOpenGLVersionFunctionsBackend (0x0x7f58d5fbecc0) 0 + +Class QOpenGLFunctions_1_3_CoreBackend::Functions + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_1_3_CoreBackend::Functions (0x0x7f58d5fbee40) 0 + +Class QOpenGLFunctions_1_3_CoreBackend + size=88 align=8 + base size=88 base align=8 +QOpenGLFunctions_1_3_CoreBackend (0x0x7f58d5fc5a90) 0 + QOpenGLVersionFunctionsBackend (0x0x7f58d5fbede0) 0 + +Class QOpenGLFunctions_1_4_CoreBackend::Functions + size=56 align=8 + base size=56 base align=8 +QOpenGLFunctions_1_4_CoreBackend::Functions (0x0x7f58d6023000) 0 + +Class QOpenGLFunctions_1_4_CoreBackend + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_1_4_CoreBackend (0x0x7f58d5fc5af8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f58d5fbef60) 0 + +Class QOpenGLFunctions_1_5_CoreBackend::Functions + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_1_5_CoreBackend::Functions (0x0x7f58d6023120) 0 + +Class QOpenGLFunctions_1_5_CoreBackend + size=168 align=8 + base size=168 base align=8 +QOpenGLFunctions_1_5_CoreBackend (0x0x7f58d5fc5b60) 0 + QOpenGLVersionFunctionsBackend (0x0x7f58d60230c0) 0 + +Class QOpenGLFunctions_2_0_CoreBackend::Functions + size=744 align=8 + base size=744 base align=8 +QOpenGLFunctions_2_0_CoreBackend::Functions (0x0x7f58d6023240) 0 + +Class QOpenGLFunctions_2_0_CoreBackend + size=760 align=8 + base size=760 base align=8 +QOpenGLFunctions_2_0_CoreBackend (0x0x7f58d5fc5bc8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f58d60231e0) 0 + +Class QOpenGLFunctions_2_1_CoreBackend::Functions + size=48 align=8 + base size=48 base align=8 +QOpenGLFunctions_2_1_CoreBackend::Functions (0x0x7f58d6023360) 0 + +Class QOpenGLFunctions_2_1_CoreBackend + size=64 align=8 + base size=64 base align=8 +QOpenGLFunctions_2_1_CoreBackend (0x0x7f58d5fc5c30) 0 + QOpenGLVersionFunctionsBackend (0x0x7f58d6023300) 0 + +Class QOpenGLFunctions_3_0_CoreBackend::Functions + size=672 align=8 + base size=672 base align=8 +QOpenGLFunctions_3_0_CoreBackend::Functions (0x0x7f58d6023480) 0 + +Class QOpenGLFunctions_3_0_CoreBackend + size=688 align=8 + base size=688 base align=8 +QOpenGLFunctions_3_0_CoreBackend (0x0x7f58d5fc5c98) 0 + QOpenGLVersionFunctionsBackend (0x0x7f58d6023420) 0 + +Class QOpenGLFunctions_3_1_CoreBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_3_1_CoreBackend::Functions (0x0x7f58d60235a0) 0 + +Class QOpenGLFunctions_3_1_CoreBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_3_1_CoreBackend (0x0x7f58d5fc5d00) 0 + QOpenGLVersionFunctionsBackend (0x0x7f58d6023540) 0 + +Class QOpenGLFunctions_3_2_CoreBackend::Functions + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_3_2_CoreBackend::Functions (0x0x7f58d60236c0) 0 + +Class QOpenGLFunctions_3_2_CoreBackend + size=168 align=8 + base size=168 base align=8 +QOpenGLFunctions_3_2_CoreBackend (0x0x7f58d5fc5d68) 0 + QOpenGLVersionFunctionsBackend (0x0x7f58d6023660) 0 + +Class QOpenGLFunctions_3_3_CoreBackend::Functions + size=464 align=8 + base size=464 base align=8 +QOpenGLFunctions_3_3_CoreBackend::Functions (0x0x7f58d60237e0) 0 + +Class QOpenGLFunctions_3_3_CoreBackend + size=480 align=8 + base size=480 base align=8 +QOpenGLFunctions_3_3_CoreBackend (0x0x7f58d5fc5dd0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f58d6023780) 0 + +Class QOpenGLFunctions_4_0_CoreBackend::Functions + size=368 align=8 + base size=368 base align=8 +QOpenGLFunctions_4_0_CoreBackend::Functions (0x0x7f58d6023900) 0 + +Class QOpenGLFunctions_4_0_CoreBackend + size=384 align=8 + base size=384 base align=8 +QOpenGLFunctions_4_0_CoreBackend (0x0x7f58d5fc5e38) 0 + QOpenGLVersionFunctionsBackend (0x0x7f58d60238a0) 0 + +Class QOpenGLFunctions_4_1_CoreBackend::Functions + size=704 align=8 + base size=704 base align=8 +QOpenGLFunctions_4_1_CoreBackend::Functions (0x0x7f58d6023a20) 0 + +Class QOpenGLFunctions_4_1_CoreBackend + size=720 align=8 + base size=720 base align=8 +QOpenGLFunctions_4_1_CoreBackend (0x0x7f58d5fc5ea0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f58d60239c0) 0 + +Class QOpenGLFunctions_4_2_CoreBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_4_2_CoreBackend::Functions (0x0x7f58d6023b40) 0 + +Class QOpenGLFunctions_4_2_CoreBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_4_2_CoreBackend (0x0x7f58d5fc5f08) 0 + QOpenGLVersionFunctionsBackend (0x0x7f58d6023ae0) 0 + +Class QOpenGLFunctions_4_3_CoreBackend::Functions + size=344 align=8 + base size=344 base align=8 +QOpenGLFunctions_4_3_CoreBackend::Functions (0x0x7f58d6023c60) 0 + +Class QOpenGLFunctions_4_3_CoreBackend + size=360 align=8 + base size=360 base align=8 +QOpenGLFunctions_4_3_CoreBackend (0x0x7f58d5fc5f70) 0 + QOpenGLVersionFunctionsBackend (0x0x7f58d6023c00) 0 + +Class QOpenGLFunctions_4_4_CoreBackend::Functions + size=72 align=8 + base size=72 base align=8 +QOpenGLFunctions_4_4_CoreBackend::Functions (0x0x7f58d6023d80) 0 + +Class QOpenGLFunctions_4_4_CoreBackend + size=88 align=8 + base size=88 base align=8 +QOpenGLFunctions_4_4_CoreBackend (0x0x7f58d610a000) 0 + QOpenGLVersionFunctionsBackend (0x0x7f58d6023d20) 0 + +Class QOpenGLFunctions_4_5_CoreBackend::Functions + size=848 align=8 + base size=848 base align=8 +QOpenGLFunctions_4_5_CoreBackend::Functions (0x0x7f58d6023f00) 0 + +Class QOpenGLFunctions_4_5_CoreBackend + size=864 align=8 + base size=864 base align=8 +QOpenGLFunctions_4_5_CoreBackend (0x0x7f58d610a068) 0 + QOpenGLVersionFunctionsBackend (0x0x7f58d6023ea0) 0 + +Class QOpenGLFunctions_1_0_DeprecatedBackend::Functions + size=2064 align=8 + base size=2064 base align=8 +QOpenGLFunctions_1_0_DeprecatedBackend::Functions (0x0x7f58d6146060) 0 + +Class QOpenGLFunctions_1_0_DeprecatedBackend + size=2080 align=8 + base size=2080 base align=8 +QOpenGLFunctions_1_0_DeprecatedBackend (0x0x7f58d610a0d0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f58d6146000) 0 + +Class QOpenGLFunctions_1_1_DeprecatedBackend::Functions + size=136 align=8 + base size=136 base align=8 +QOpenGLFunctions_1_1_DeprecatedBackend::Functions (0x0x7f58d6146180) 0 + +Class QOpenGLFunctions_1_1_DeprecatedBackend + size=152 align=8 + base size=152 base align=8 +QOpenGLFunctions_1_1_DeprecatedBackend (0x0x7f58d610a138) 0 + QOpenGLVersionFunctionsBackend (0x0x7f58d6146120) 0 + +Class QOpenGLFunctions_1_2_DeprecatedBackend::Functions + size=256 align=8 + base size=256 base align=8 +QOpenGLFunctions_1_2_DeprecatedBackend::Functions (0x0x7f58d61462a0) 0 + +Class QOpenGLFunctions_1_2_DeprecatedBackend + size=272 align=8 + base size=272 base align=8 +QOpenGLFunctions_1_2_DeprecatedBackend (0x0x7f58d610a1a0) 0 + QOpenGLVersionFunctionsBackend (0x0x7f58d6146240) 0 + +Class QOpenGLFunctions_1_3_DeprecatedBackend::Functions + size=296 align=8 + base size=296 base align=8 +QOpenGLFunctions_1_3_DeprecatedBackend::Functions (0x0x7f58d61463c0) 0 + +Class QOpenGLFunctions_1_3_DeprecatedBackend + size=312 align=8 + base size=312 base align=8 +QOpenGLFunctions_1_3_DeprecatedBackend (0x0x7f58d610a208) 0 + QOpenGLVersionFunctionsBackend (0x0x7f58d6146360) 0 + +Class QOpenGLFunctions_1_4_DeprecatedBackend::Functions + size=304 align=8 + base size=304 base align=8 +QOpenGLFunctions_1_4_DeprecatedBackend::Functions (0x0x7f58d61464e0) 0 + +Class QOpenGLFunctions_1_4_DeprecatedBackend + size=320 align=8 + base size=320 base align=8 +QOpenGLFunctions_1_4_DeprecatedBackend (0x0x7f58d610a270) 0 + QOpenGLVersionFunctionsBackend (0x0x7f58d6146480) 0 + +Class QOpenGLFunctions_2_0_DeprecatedBackend::Functions + size=288 align=8 + base size=288 base align=8 +QOpenGLFunctions_2_0_DeprecatedBackend::Functions (0x0x7f58d6146600) 0 + +Class QOpenGLFunctions_2_0_DeprecatedBackend + size=304 align=8 + base size=304 base align=8 +QOpenGLFunctions_2_0_DeprecatedBackend (0x0x7f58d610a2d8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f58d61465a0) 0 + +Class QOpenGLFunctions_3_0_DeprecatedBackend::Functions + size=160 align=8 + base size=160 base align=8 +QOpenGLFunctions_3_0_DeprecatedBackend::Functions (0x0x7f58d6146720) 0 + +Class QOpenGLFunctions_3_0_DeprecatedBackend + size=176 align=8 + base size=176 base align=8 +QOpenGLFunctions_3_0_DeprecatedBackend (0x0x7f58d610a340) 0 + QOpenGLVersionFunctionsBackend (0x0x7f58d61466c0) 0 + +Class QOpenGLFunctions_3_3_DeprecatedBackend::Functions + size=240 align=8 + base size=240 base align=8 +QOpenGLFunctions_3_3_DeprecatedBackend::Functions (0x0x7f58d6146840) 0 + +Class QOpenGLFunctions_3_3_DeprecatedBackend + size=256 align=8 + base size=256 base align=8 +QOpenGLFunctions_3_3_DeprecatedBackend (0x0x7f58d610a3a8) 0 + QOpenGLVersionFunctionsBackend (0x0x7f58d61467e0) 0 + +Class QOpenGLFunctions_4_5_DeprecatedBackend::Functions + size=96 align=8 + base size=96 base align=8 +QOpenGLFunctions_4_5_DeprecatedBackend::Functions (0x0x7f58d6146960) 0 + +Class QOpenGLFunctions_4_5_DeprecatedBackend + size=112 align=8 + base size=112 base align=8 +QOpenGLFunctions_4_5_DeprecatedBackend (0x0x7f58d610a410) 0 + QOpenGLVersionFunctionsBackend (0x0x7f58d6146900) 0 + +Class QOpenGLVersionProfile + size=8 align=8 + base size=8 base align=8 +QOpenGLVersionProfile (0x0x7f58d6146a20) 0 + +Class QOpenGLContextGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLContextGroup::QPrivateSignal (0x0x7f58d5e21420) 0 empty + +Vtable for QOpenGLContextGroup +QOpenGLContextGroup::_ZTV19QOpenGLContextGroup: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QOpenGLContextGroup) +16 (int (*)(...))QOpenGLContextGroup::metaObject +24 (int (*)(...))QOpenGLContextGroup::qt_metacast +32 (int (*)(...))QOpenGLContextGroup::qt_metacall +40 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup +48 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLContextGroup + size=16 align=8 + base size=16 base align=8 +QOpenGLContextGroup (0x0x7f58d610ae38) 0 + vptr=((& QOpenGLContextGroup::_ZTV19QOpenGLContextGroup) + 16u) + QObject (0x0x7f58d5e213c0) 0 + primary-for QOpenGLContextGroup (0x0x7f58d610ae38) + +Class QOpenGLContext::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLContext::QPrivateSignal (0x0x7f58d5e214e0) 0 empty + +Vtable for QOpenGLContext +QOpenGLContext::_ZTV14QOpenGLContext: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QOpenGLContext) +16 (int (*)(...))QOpenGLContext::metaObject +24 (int (*)(...))QOpenGLContext::qt_metacast +32 (int (*)(...))QOpenGLContext::qt_metacall +40 (int (*)(...))QOpenGLContext::~QOpenGLContext +48 (int (*)(...))QOpenGLContext::~QOpenGLContext +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLContext + size=16 align=8 + base size=16 base align=8 +QOpenGLContext (0x0x7f58d610aea0) 0 + vptr=((& QOpenGLContext::_ZTV14QOpenGLContext) + 16u) + QObject (0x0x7f58d5e21480) 0 + primary-for QOpenGLContext (0x0x7f58d610aea0) + +Class QOpenGLDebugMessage + size=8 align=8 + base size=8 base align=8 +QOpenGLDebugMessage (0x0x7f58d5e21540) 0 + +Class QOpenGLDebugLogger::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLDebugLogger::QPrivateSignal (0x0x7f58d5e21d20) 0 empty + +Vtable for QOpenGLDebugLogger +QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLDebugLogger) +16 (int (*)(...))QOpenGLDebugLogger::metaObject +24 (int (*)(...))QOpenGLDebugLogger::qt_metacast +32 (int (*)(...))QOpenGLDebugLogger::qt_metacall +40 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger +48 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLDebugLogger + size=16 align=8 + base size=16 base align=8 +QOpenGLDebugLogger (0x0x7f58d5e6e340) 0 + vptr=((& QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger) + 16u) + QObject (0x0x7f58d5e21cc0) 0 + primary-for QOpenGLDebugLogger (0x0x7f58d5e6e340) + +Class QOpenGLFunctions + size=8 align=8 + base size=8 base align=8 +QOpenGLFunctions (0x0x7f58d5e21ea0) 0 + +Class QOpenGLFunctionsPrivate::Functions + size=1152 align=8 + base size=1152 base align=8 +QOpenGLFunctionsPrivate::Functions (0x0x7f58d5f6c120) 0 + +Class QOpenGLFunctionsPrivate + size=1152 align=8 + base size=1152 base align=8 +QOpenGLFunctionsPrivate (0x0x7f58d5f6c0c0) 0 + +Class QOpenGLExtraFunctions + size=8 align=8 + base size=8 base align=8 +QOpenGLExtraFunctions (0x0x7f58d5e6e5b0) 0 + QOpenGLFunctions (0x0x7f58d5c8f840) 0 + +Class QOpenGLExtraFunctionsPrivate::Functions + size=1728 align=8 + base size=1728 base align=8 +QOpenGLExtraFunctionsPrivate::Functions (0x0x7f58d5c8f900) 0 + +Class QOpenGLExtraFunctionsPrivate + size=2880 align=8 + base size=2880 base align=8 +QOpenGLExtraFunctionsPrivate (0x0x7f58d5e6e618) 0 + QOpenGLFunctionsPrivate (0x0x7f58d5c8f8a0) 0 + +Vtable for QOpenGLFramebufferObject +QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QOpenGLFramebufferObject) +16 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject +24 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject + +Class QOpenGLFramebufferObject + size=16 align=8 + base size=16 base align=8 +QOpenGLFramebufferObject (0x0x7f58d5af8000) 0 + vptr=((& QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject) + 16u) + +Class QOpenGLFramebufferObjectFormat + size=8 align=8 + base size=8 base align=8 +QOpenGLFramebufferObjectFormat (0x0x7f58d5af8120) 0 + +Vtable for QOpenGLPaintDevice +QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLPaintDevice) +16 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice +24 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice +32 (int (*)(...))QOpenGLPaintDevice::devType +40 (int (*)(...))QOpenGLPaintDevice::paintEngine +48 (int (*)(...))QOpenGLPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))QOpenGLPaintDevice::ensureActiveTarget + +Class QOpenGLPaintDevice + size=32 align=8 + base size=32 base align=8 +QOpenGLPaintDevice (0x0x7f58d5e6e8f0) 0 + vptr=((& QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice) + 16u) + QPaintDevice (0x0x7f58d5af8180) 0 + primary-for QOpenGLPaintDevice (0x0x7f58d5e6e8f0) + +Class QOpenGLPixelTransferOptions + size=8 align=8 + base size=8 base align=8 +QOpenGLPixelTransferOptions (0x0x7f58d5af82a0) 0 + +Class QOpenGLShader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLShader::QPrivateSignal (0x0x7f58d5af8600) 0 empty + +Vtable for QOpenGLShader +QOpenGLShader::_ZTV13QOpenGLShader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QOpenGLShader) +16 (int (*)(...))QOpenGLShader::metaObject +24 (int (*)(...))QOpenGLShader::qt_metacast +32 (int (*)(...))QOpenGLShader::qt_metacall +40 (int (*)(...))QOpenGLShader::~QOpenGLShader +48 (int (*)(...))QOpenGLShader::~QOpenGLShader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLShader + size=16 align=8 + base size=16 base align=8 +QOpenGLShader (0x0x7f58d5e6eaf8) 0 + vptr=((& QOpenGLShader::_ZTV13QOpenGLShader) + 16u) + QObject (0x0x7f58d5af85a0) 0 + primary-for QOpenGLShader (0x0x7f58d5e6eaf8) + +Class QOpenGLShaderProgram::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLShaderProgram::QPrivateSignal (0x0x7f58d5af8840) 0 empty + +Vtable for QOpenGLShaderProgram +QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QOpenGLShaderProgram) +16 (int (*)(...))QOpenGLShaderProgram::metaObject +24 (int (*)(...))QOpenGLShaderProgram::qt_metacast +32 (int (*)(...))QOpenGLShaderProgram::qt_metacall +40 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram +48 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QOpenGLShaderProgram::link + +Class QOpenGLShaderProgram + size=16 align=8 + base size=16 base align=8 +QOpenGLShaderProgram (0x0x7f58d5e6ec30) 0 + vptr=((& QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram) + 16u) + QObject (0x0x7f58d5af87e0) 0 + primary-for QOpenGLShaderProgram (0x0x7f58d5e6ec30) + +Class QOpenGLTexture + size=8 align=8 + base size=8 base align=8 +QOpenGLTexture (0x0x7f58d5af88a0) 0 + +Class QOpenGLTextureBlitter + size=8 align=8 + base size=8 base align=8 +QOpenGLTextureBlitter (0x0x7f58d5af8b40) 0 + +Class QOpenGLTimerQuery::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLTimerQuery::QPrivateSignal (0x0x7f58d5af8cc0) 0 empty + +Vtable for QOpenGLTimerQuery +QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QOpenGLTimerQuery) +16 (int (*)(...))QOpenGLTimerQuery::metaObject +24 (int (*)(...))QOpenGLTimerQuery::qt_metacast +32 (int (*)(...))QOpenGLTimerQuery::qt_metacall +40 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery +48 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLTimerQuery + size=16 align=8 + base size=16 base align=8 +QOpenGLTimerQuery (0x0x7f58d5e6ed68) 0 + vptr=((& QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery) + 16u) + QObject (0x0x7f58d5af8c60) 0 + primary-for QOpenGLTimerQuery (0x0x7f58d5e6ed68) + +Class QOpenGLTimeMonitor::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLTimeMonitor::QPrivateSignal (0x0x7f58d5af8d80) 0 empty + +Vtable for QOpenGLTimeMonitor +QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QOpenGLTimeMonitor) +16 (int (*)(...))QOpenGLTimeMonitor::metaObject +24 (int (*)(...))QOpenGLTimeMonitor::qt_metacast +32 (int (*)(...))QOpenGLTimeMonitor::qt_metacall +40 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor +48 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLTimeMonitor + size=16 align=8 + base size=16 base align=8 +QOpenGLTimeMonitor (0x0x7f58d5e6edd0) 0 + vptr=((& QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor) + 16u) + QObject (0x0x7f58d5af8d20) 0 + primary-for QOpenGLTimeMonitor (0x0x7f58d5e6edd0) + +Class QOpenGLVertexArrayObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLVertexArrayObject::QPrivateSignal (0x0x7f58d5af8e40) 0 empty + +Class QOpenGLVertexArrayObject::Binder + size=8 align=8 + base size=8 base align=8 +QOpenGLVertexArrayObject::Binder (0x0x7f58d5af8ea0) 0 + +Vtable for QOpenGLVertexArrayObject +QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QOpenGLVertexArrayObject) +16 (int (*)(...))QOpenGLVertexArrayObject::metaObject +24 (int (*)(...))QOpenGLVertexArrayObject::qt_metacast +32 (int (*)(...))QOpenGLVertexArrayObject::qt_metacall +40 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject +48 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QOpenGLVertexArrayObject + size=16 align=8 + base size=16 base align=8 +QOpenGLVertexArrayObject (0x0x7f58d5e6ee38) 0 + vptr=((& QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject) + 16u) + QObject (0x0x7f58d5af8de0) 0 + primary-for QOpenGLVertexArrayObject (0x0x7f58d5e6ee38) + +Class QPaintDeviceWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPaintDeviceWindow::QPrivateSignal (0x0x7f58d58c4060) 0 empty + +Vtable for QPaintDeviceWindow +QPaintDeviceWindow::_ZTV18QPaintDeviceWindow: 58u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +16 (int (*)(...))QPaintDeviceWindow::metaObject +24 (int (*)(...))QPaintDeviceWindow::qt_metacast +32 (int (*)(...))QPaintDeviceWindow::qt_metacall +40 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow +48 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))QPaintDeviceWindow::paintEvent +304 (int (*)(...))QPaintDeviceWindow::metric +312 (int (*)(...))QPaintDeviceWindow::paintEngine +320 (int (*)(...))-16 +328 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +336 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD1Ev +344 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD0Ev +352 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +376 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +384 (int (*)(...))-40 +392 (int (*)(...))(& _ZTI18QPaintDeviceWindow) +400 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD1Ev +408 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD0Ev +416 (int (*)(...))QPaintDevice::devType +424 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +432 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow6metricEN12QPaintDevice17PaintDeviceMetricE +440 (int (*)(...))QPaintDevice::initPainter +448 (int (*)(...))QPaintDevice::redirected +456 (int (*)(...))QPaintDevice::sharedPainter + +Class QPaintDeviceWindow + size=64 align=8 + base size=64 base align=8 +QPaintDeviceWindow (0x0x7f58d589ee00) 0 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 16u) + QWindow (0x0x7f58d589ee70) 0 + primary-for QPaintDeviceWindow (0x0x7f58d589ee00) + QObject (0x0x7f58d5af8f00) 0 + primary-for QWindow (0x0x7f58d589ee70) + QSurface (0x0x7f58d5af8f60) 16 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 336u) + QPaintDevice (0x0x7f58d58c4000) 40 + vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 400u) + +Class QOpenGLWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLWindow::QPrivateSignal (0x0x7f58d58c41e0) 0 empty + +Vtable for QOpenGLWindow +QOpenGLWindow::_ZTV13QOpenGLWindow: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QOpenGLWindow) +16 (int (*)(...))QOpenGLWindow::metaObject +24 (int (*)(...))QOpenGLWindow::qt_metacast +32 (int (*)(...))QOpenGLWindow::qt_metacall +40 (int (*)(...))QOpenGLWindow::~QOpenGLWindow +48 (int (*)(...))QOpenGLWindow::~QOpenGLWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QOpenGLWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))QOpenGLWindow::paintEvent +304 (int (*)(...))QOpenGLWindow::metric +312 (int (*)(...))QPaintDeviceWindow::paintEngine +320 (int (*)(...))QOpenGLWindow::initializeGL +328 (int (*)(...))QOpenGLWindow::resizeGL +336 (int (*)(...))QOpenGLWindow::paintGL +344 (int (*)(...))QOpenGLWindow::paintUnderGL +352 (int (*)(...))QOpenGLWindow::paintOverGL +360 (int (*)(...))QOpenGLWindow::redirected +368 (int (*)(...))-16 +376 (int (*)(...))(& _ZTI13QOpenGLWindow) +384 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD1Ev +392 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD0Ev +400 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +408 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +416 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +424 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +432 (int (*)(...))-40 +440 (int (*)(...))(& _ZTI13QOpenGLWindow) +448 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD1Ev +456 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD0Ev +464 (int (*)(...))QPaintDevice::devType +472 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +480 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QPaintDevice::initPainter +496 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow10redirectedEP6QPoint +504 (int (*)(...))QPaintDevice::sharedPainter + +Class QOpenGLWindow + size=64 align=8 + base size=64 base align=8 +QOpenGLWindow (0x0x7f58d5e6ef08) 0 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 16u) + QPaintDeviceWindow (0x0x7f58d58d4230) 0 + primary-for QOpenGLWindow (0x0x7f58d5e6ef08) + QWindow (0x0x7f58d58d42a0) 0 + primary-for QPaintDeviceWindow (0x0x7f58d58d4230) + QObject (0x0x7f58d58c40c0) 0 + primary-for QWindow (0x0x7f58d58d42a0) + QSurface (0x0x7f58d58c4120) 16 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 384u) + QPaintDevice (0x0x7f58d58c4180) 40 + vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 448u) + +Class QPageSize + size=8 align=8 + base size=8 base align=8 +QPageSize (0x0x7f58d58c4240) 0 + +Class QPageLayout + size=8 align=8 + base size=8 base align=8 +QPageLayout (0x0x7f58d58c4c00) 0 + +Class QPagedPaintDevice::Margins + size=32 align=8 + base size=32 base align=8 +QPagedPaintDevice::Margins (0x0x7f58d5971660) 0 + +Vtable for QPagedPaintDevice +QPagedPaintDevice::_ZTV17QPagedPaintDevice: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QPagedPaintDevice) +16 0u +24 0u +32 (int (*)(...))QPaintDevice::devType +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QPaintDevice::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QPagedPaintDevice::setPageSize +96 (int (*)(...))QPagedPaintDevice::setPageSizeMM +104 (int (*)(...))QPagedPaintDevice::setMargins + +Class QPagedPaintDevice + size=32 align=8 + base size=32 base align=8 +QPagedPaintDevice (0x0x7f58d591bc30) 0 + vptr=((& QPagedPaintDevice::_ZTV17QPagedPaintDevice) + 16u) + QPaintDevice (0x0x7f58d5971600) 0 + primary-for QPagedPaintDevice (0x0x7f58d591bc30) + +Class QPainter::PixmapFragment + size=80 align=8 + base size=80 base align=8 +QPainter::PixmapFragment (0x0x7f58d5971720) 0 + +Class QPainter + size=8 align=8 + base size=8 base align=8 +QPainter (0x0x7f58d59716c0) 0 + +Class QTextItem + size=1 align=1 + base size=0 base align=1 +QTextItem (0x0x7f58d56cf540) 0 empty + +Vtable for QPaintEngine +QPaintEngine::_ZTV12QPaintEngine: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QPaintEngine) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))QPaintEngine::drawRects +64 (int (*)(...))QPaintEngine::drawRects +72 (int (*)(...))QPaintEngine::drawLines +80 (int (*)(...))QPaintEngine::drawLines +88 (int (*)(...))QPaintEngine::drawEllipse +96 (int (*)(...))QPaintEngine::drawEllipse +104 (int (*)(...))QPaintEngine::drawPath +112 (int (*)(...))QPaintEngine::drawPoints +120 (int (*)(...))QPaintEngine::drawPoints +128 (int (*)(...))QPaintEngine::drawPolygon +136 (int (*)(...))QPaintEngine::drawPolygon +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QPaintEngine::drawTextItem +160 (int (*)(...))QPaintEngine::drawTiledPixmap +168 (int (*)(...))QPaintEngine::drawImage +176 (int (*)(...))QPaintEngine::coordinateOffset +184 (int (*)(...))__cxa_pure_virtual + +Class QPaintEngine + size=32 align=8 + base size=32 base align=8 +QPaintEngine (0x0x7f58d56cf7e0) 0 + vptr=((& QPaintEngine::_ZTV12QPaintEngine) + 16u) + +Class QPaintEngineState + size=4 align=4 + base size=4 base align=4 +QPaintEngineState (0x0x7f58d56cfa80) 0 + +Class QPdfWriter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPdfWriter::QPrivateSignal (0x0x7f58d56cfea0) 0 empty + +Vtable for QPdfWriter +QPdfWriter::_ZTV10QPdfWriter: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QPdfWriter) +16 (int (*)(...))QPdfWriter::metaObject +24 (int (*)(...))QPdfWriter::qt_metacast +32 (int (*)(...))QPdfWriter::qt_metacall +40 (int (*)(...))QPdfWriter::~QPdfWriter +48 (int (*)(...))QPdfWriter::~QPdfWriter +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPdfWriter::newPage +120 (int (*)(...))QPdfWriter::setPageSize +128 (int (*)(...))QPdfWriter::setPageSizeMM +136 (int (*)(...))QPdfWriter::setMargins +144 (int (*)(...))QPdfWriter::paintEngine +152 (int (*)(...))QPdfWriter::metric +160 (int (*)(...))-16 +168 (int (*)(...))(& _ZTI10QPdfWriter) +176 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD1Ev +184 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD0Ev +192 (int (*)(...))QPaintDevice::devType +200 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter11paintEngineEv +208 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter6metricEN12QPaintDevice17PaintDeviceMetricE +216 (int (*)(...))QPaintDevice::initPainter +224 (int (*)(...))QPaintDevice::redirected +232 (int (*)(...))QPaintDevice::sharedPainter +240 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter7newPageEv +248 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter11setPageSizeEN17QPagedPaintDevice8PageSizeE +256 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter13setPageSizeMMERK6QSizeF +264 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter10setMarginsERKN17QPagedPaintDevice7MarginsE + +Class QPdfWriter + size=48 align=8 + base size=48 base align=8 +QPdfWriter (0x0x7f58d543a1c0) 0 + vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 16u) + QObject (0x0x7f58d56cfde0) 0 + primary-for QPdfWriter (0x0x7f58d543a1c0) + QPagedPaintDevice (0x0x7f58d5619c98) 16 + vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 176u) + QPaintDevice (0x0x7f58d56cfe40) 16 + primary-for QPagedPaintDevice (0x0x7f58d5619c98) + +Vtable for QPicture +QPicture::_ZTV8QPicture: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QPicture) +16 (int (*)(...))QPicture::~QPicture +24 (int (*)(...))QPicture::~QPicture +32 (int (*)(...))QPicture::devType +40 (int (*)(...))QPicture::paintEngine +48 (int (*)(...))QPicture::metric +56 (int (*)(...))QPaintDevice::initPainter +64 (int (*)(...))QPaintDevice::redirected +72 (int (*)(...))QPaintDevice::sharedPainter +80 (int (*)(...))QPicture::setData + +Class QPicture + size=32 align=8 + base size=32 base align=8 +QPicture (0x0x7f58d5619d00) 0 + vptr=((& QPicture::_ZTV8QPicture) + 16u) + QPaintDevice (0x0x7f58d5455060) 0 + primary-for QPicture (0x0x7f58d5619d00) + +Class QPictureIO + size=8 align=8 + base size=8 base align=8 +QPictureIO (0x0x7f58d5455360) 0 + +Class QPictureFormatPlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPictureFormatPlugin::QPrivateSignal (0x0x7f58d5455420) 0 empty + +Vtable for QPictureFormatPlugin +QPictureFormatPlugin::_ZTV20QPictureFormatPlugin: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QPictureFormatPlugin) +16 (int (*)(...))QPictureFormatPlugin::metaObject +24 (int (*)(...))QPictureFormatPlugin::qt_metacast +32 (int (*)(...))QPictureFormatPlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPictureFormatPlugin::loadPicture +120 (int (*)(...))QPictureFormatPlugin::savePicture +128 (int (*)(...))__cxa_pure_virtual + +Class QPictureFormatPlugin + size=16 align=8 + base size=16 base align=8 +QPictureFormatPlugin (0x0x7f58d5619f08) 0 + vptr=((& QPictureFormatPlugin::_ZTV20QPictureFormatPlugin) + 16u) + QObject (0x0x7f58d54553c0) 0 + primary-for QPictureFormatPlugin (0x0x7f58d5619f08) + +Class QPixmapCache::Key + size=8 align=8 + base size=8 base align=8 +QPixmapCache::Key (0x0x7f58d54554e0) 0 + +Class QPixmapCache + size=1 align=1 + base size=0 base align=1 +QPixmapCache (0x0x7f58d5455480) 0 empty + +Class QRasterWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRasterWindow::QPrivateSignal (0x0x7f58d5511660) 0 empty + +Vtable for QRasterWindow +QRasterWindow::_ZTV13QRasterWindow: 59u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QRasterWindow) +16 (int (*)(...))QRasterWindow::metaObject +24 (int (*)(...))QRasterWindow::qt_metacast +32 (int (*)(...))QRasterWindow::qt_metacall +40 (int (*)(...))QRasterWindow::~QRasterWindow +48 (int (*)(...))QRasterWindow::~QRasterWindow +56 (int (*)(...))QPaintDeviceWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWindow::surfaceType +120 (int (*)(...))QWindow::format +128 (int (*)(...))QWindow::size +136 (int (*)(...))QWindow::accessibleRoot +144 (int (*)(...))QWindow::focusObject +152 (int (*)(...))QPaintDeviceWindow::exposeEvent +160 (int (*)(...))QWindow::resizeEvent +168 (int (*)(...))QWindow::moveEvent +176 (int (*)(...))QWindow::focusInEvent +184 (int (*)(...))QWindow::focusOutEvent +192 (int (*)(...))QWindow::showEvent +200 (int (*)(...))QWindow::hideEvent +208 (int (*)(...))QWindow::keyPressEvent +216 (int (*)(...))QWindow::keyReleaseEvent +224 (int (*)(...))QWindow::mousePressEvent +232 (int (*)(...))QWindow::mouseReleaseEvent +240 (int (*)(...))QWindow::mouseDoubleClickEvent +248 (int (*)(...))QWindow::mouseMoveEvent +256 (int (*)(...))QWindow::wheelEvent +264 (int (*)(...))QWindow::touchEvent +272 (int (*)(...))QWindow::tabletEvent +280 (int (*)(...))QWindow::nativeEvent +288 (int (*)(...))QWindow::surfaceHandle +296 (int (*)(...))QPaintDeviceWindow::paintEvent +304 (int (*)(...))QRasterWindow::metric +312 (int (*)(...))QPaintDeviceWindow::paintEngine +320 (int (*)(...))QRasterWindow::redirected +328 (int (*)(...))-16 +336 (int (*)(...))(& _ZTI13QRasterWindow) +344 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD1Ev +352 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD0Ev +360 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv +368 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv +376 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv +384 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv +392 (int (*)(...))-40 +400 (int (*)(...))(& _ZTI13QRasterWindow) +408 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD1Ev +416 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD0Ev +424 (int (*)(...))QPaintDevice::devType +432 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv +440 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow6metricEN12QPaintDevice17PaintDeviceMetricE +448 (int (*)(...))QPaintDevice::initPainter +456 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow10redirectedEP6QPoint +464 (int (*)(...))QPaintDevice::sharedPainter + +Class QRasterWindow + size=64 align=8 + base size=64 base align=8 +QRasterWindow (0x0x7f58d5513618) 0 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 16u) + QPaintDeviceWindow (0x0x7f58d550ef50) 0 + primary-for QRasterWindow (0x0x7f58d5513618) + QWindow (0x0x7f58d551f000) 0 + primary-for QPaintDeviceWindow (0x0x7f58d550ef50) + QObject (0x0x7f58d5511540) 0 + primary-for QWindow (0x0x7f58d551f000) + QSurface (0x0x7f58d55115a0) 16 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 344u) + QPaintDevice (0x0x7f58d5511600) 40 + vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 408u) + +Class QScreen::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QScreen::QPrivateSignal (0x0x7f58d5511720) 0 empty + +Vtable for QScreen +QScreen::_ZTV7QScreen: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QScreen) +16 (int (*)(...))QScreen::metaObject +24 (int (*)(...))QScreen::qt_metacast +32 (int (*)(...))QScreen::qt_metacall +40 (int (*)(...))QScreen::~QScreen +48 (int (*)(...))QScreen::~QScreen +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QScreen + size=16 align=8 + base size=16 base align=8 +QScreen (0x0x7f58d55136e8) 0 + vptr=((& QScreen::_ZTV7QScreen) + 16u) + QObject (0x0x7f58d55116c0) 0 + primary-for QScreen (0x0x7f58d55136e8) + +Class QSessionManager::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSessionManager::QPrivateSignal (0x0x7f58d55117e0) 0 empty + +Vtable for QSessionManager +QSessionManager::_ZTV15QSessionManager: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSessionManager) +16 (int (*)(...))QSessionManager::metaObject +24 (int (*)(...))QSessionManager::qt_metacast +32 (int (*)(...))QSessionManager::qt_metacall +40 (int (*)(...))QSessionManager::~QSessionManager +48 (int (*)(...))QSessionManager::~QSessionManager +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSessionManager + size=16 align=8 + base size=16 base align=8 +QSessionManager (0x0x7f58d5513750) 0 + vptr=((& QSessionManager::_ZTV15QSessionManager) + 16u) + QObject (0x0x7f58d5511780) 0 + primary-for QSessionManager (0x0x7f58d5513750) + +Vtable for QStandardItem +QStandardItem::_ZTV13QStandardItem: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStandardItem) +16 (int (*)(...))QStandardItem::~QStandardItem +24 (int (*)(...))QStandardItem::~QStandardItem +32 (int (*)(...))QStandardItem::data +40 (int (*)(...))QStandardItem::setData +48 (int (*)(...))QStandardItem::clone +56 (int (*)(...))QStandardItem::type +64 (int (*)(...))QStandardItem::read +72 (int (*)(...))QStandardItem::write +80 (int (*)(...))QStandardItem::operator< + +Class QStandardItem + size=16 align=8 + base size=16 base align=8 +QStandardItem (0x0x7f58d5511840) 0 + vptr=((& QStandardItem::_ZTV13QStandardItem) + 16u) + +Class QStandardItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStandardItemModel::QPrivateSignal (0x0x7f58d5511f60) 0 empty + +Vtable for QStandardItemModel +QStandardItemModel::_ZTV18QStandardItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QStandardItemModel) +16 (int (*)(...))QStandardItemModel::metaObject +24 (int (*)(...))QStandardItemModel::qt_metacast +32 (int (*)(...))QStandardItemModel::qt_metacall +40 (int (*)(...))QStandardItemModel::~QStandardItemModel +48 (int (*)(...))QStandardItemModel::~QStandardItemModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStandardItemModel::index +120 (int (*)(...))QStandardItemModel::parent +128 (int (*)(...))QStandardItemModel::sibling +136 (int (*)(...))QStandardItemModel::rowCount +144 (int (*)(...))QStandardItemModel::columnCount +152 (int (*)(...))QStandardItemModel::hasChildren +160 (int (*)(...))QStandardItemModel::data +168 (int (*)(...))QStandardItemModel::setData +176 (int (*)(...))QStandardItemModel::headerData +184 (int (*)(...))QStandardItemModel::setHeaderData +192 (int (*)(...))QStandardItemModel::itemData +200 (int (*)(...))QStandardItemModel::setItemData +208 (int (*)(...))QStandardItemModel::mimeTypes +216 (int (*)(...))QStandardItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QStandardItemModel::dropMimeData +240 (int (*)(...))QStandardItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStandardItemModel::insertRows +264 (int (*)(...))QStandardItemModel::insertColumns +272 (int (*)(...))QStandardItemModel::removeRows +280 (int (*)(...))QStandardItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStandardItemModel::flags +328 (int (*)(...))QStandardItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStandardItemModel + size=16 align=8 + base size=16 base align=8 +QStandardItemModel (0x0x7f58d5513dd0) 0 + vptr=((& QStandardItemModel::_ZTV18QStandardItemModel) + 16u) + QAbstractItemModel (0x0x7f58d5513e38) 0 + primary-for QStandardItemModel (0x0x7f58d5513dd0) + QObject (0x0x7f58d5511f00) 0 + primary-for QAbstractItemModel (0x0x7f58d5513e38) + +Class QStaticText + size=8 align=8 + base size=8 base align=8 +QStaticText (0x0x7f58d5263000) 0 + +Class QStyleHints::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStyleHints::QPrivateSignal (0x0x7f58d5263480) 0 empty + +Vtable for QStyleHints +QStyleHints::_ZTV11QStyleHints: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QStyleHints) +16 (int (*)(...))QStyleHints::metaObject +24 (int (*)(...))QStyleHints::qt_metacast +32 (int (*)(...))QStyleHints::qt_metacall +40 (int (*)(...))QStyleHints::~QStyleHints +48 (int (*)(...))QStyleHints::~QStyleHints +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QStyleHints + size=16 align=8 + base size=16 base align=8 +QStyleHints (0x0x7f58d5281068) 0 + vptr=((& QStyleHints::_ZTV11QStyleHints) + 16u) + QObject (0x0x7f58d5263420) 0 + primary-for QStyleHints (0x0x7f58d5281068) + +Class QTextObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextObject::QPrivateSignal (0x0x7f58d5263540) 0 empty + +Vtable for QTextObject +QTextObject::_ZTV11QTextObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextObject) +16 (int (*)(...))QTextObject::metaObject +24 (int (*)(...))QTextObject::qt_metacast +32 (int (*)(...))QTextObject::qt_metacall +40 (int (*)(...))QTextObject::~QTextObject +48 (int (*)(...))QTextObject::~QTextObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextObject + size=16 align=8 + base size=16 base align=8 +QTextObject (0x0x7f58d52810d0) 0 + vptr=((& QTextObject::_ZTV11QTextObject) + 16u) + QObject (0x0x7f58d52634e0) 0 + primary-for QTextObject (0x0x7f58d52810d0) + +Class QTextBlockGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextBlockGroup::QPrivateSignal (0x0x7f58d5263600) 0 empty + +Vtable for QTextBlockGroup +QTextBlockGroup::_ZTV15QTextBlockGroup: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QTextBlockGroup) +16 (int (*)(...))QTextBlockGroup::metaObject +24 (int (*)(...))QTextBlockGroup::qt_metacast +32 (int (*)(...))QTextBlockGroup::qt_metacall +40 (int (*)(...))QTextBlockGroup::~QTextBlockGroup +48 (int (*)(...))QTextBlockGroup::~QTextBlockGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextBlockGroup::blockInserted +120 (int (*)(...))QTextBlockGroup::blockRemoved +128 (int (*)(...))QTextBlockGroup::blockFormatChanged + +Class QTextBlockGroup + size=16 align=8 + base size=16 base align=8 +QTextBlockGroup (0x0x7f58d5281138) 0 + vptr=((& QTextBlockGroup::_ZTV15QTextBlockGroup) + 16u) + QTextObject (0x0x7f58d52811a0) 0 + primary-for QTextBlockGroup (0x0x7f58d5281138) + QObject (0x0x7f58d52635a0) 0 + primary-for QTextObject (0x0x7f58d52811a0) + +Vtable for QTextFrameLayoutData +QTextFrameLayoutData::_ZTV20QTextFrameLayoutData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QTextFrameLayoutData) +16 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData +24 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData + +Class QTextFrameLayoutData + size=8 align=8 + base size=8 base align=8 +QTextFrameLayoutData (0x0x7f58d5263660) 0 nearly-empty + vptr=((& QTextFrameLayoutData::_ZTV20QTextFrameLayoutData) + 16u) + +Class QTextFrame::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextFrame::QPrivateSignal (0x0x7f58d5263720) 0 empty + +Class QTextFrame::iterator + size=32 align=8 + base size=28 base align=8 +QTextFrame::iterator (0x0x7f58d5263780) 0 + +Vtable for QTextFrame +QTextFrame::_ZTV10QTextFrame: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextFrame) +16 (int (*)(...))QTextFrame::metaObject +24 (int (*)(...))QTextFrame::qt_metacast +32 (int (*)(...))QTextFrame::qt_metacall +40 (int (*)(...))QTextFrame::~QTextFrame +48 (int (*)(...))QTextFrame::~QTextFrame +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextFrame + size=16 align=8 + base size=16 base align=8 +QTextFrame (0x0x7f58d5281208) 0 + vptr=((& QTextFrame::_ZTV10QTextFrame) + 16u) + QTextObject (0x0x7f58d5281270) 0 + primary-for QTextFrame (0x0x7f58d5281208) + QObject (0x0x7f58d52636c0) 0 + primary-for QTextObject (0x0x7f58d5281270) + +Vtable for QTextBlockUserData +QTextBlockUserData::_ZTV18QTextBlockUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QTextBlockUserData) +16 (int (*)(...))QTextBlockUserData::~QTextBlockUserData +24 (int (*)(...))QTextBlockUserData::~QTextBlockUserData + +Class QTextBlockUserData + size=8 align=8 + base size=8 base align=8 +QTextBlockUserData (0x0x7f58d5263a20) 0 nearly-empty + vptr=((& QTextBlockUserData::_ZTV18QTextBlockUserData) + 16u) + +Class QTextBlock::iterator + size=24 align=8 + base size=20 base align=8 +QTextBlock::iterator (0x0x7f58d5263ae0) 0 + +Class QTextBlock + size=16 align=8 + base size=12 base align=8 +QTextBlock (0x0x7f58d5263a80) 0 + +Class QTextFragment + size=16 align=8 + base size=16 base align=8 +QTextFragment (0x0x7f58d5325000) 0 + +Class QSyntaxHighlighter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSyntaxHighlighter::QPrivateSignal (0x0x7f58d5325300) 0 empty + +Vtable for QSyntaxHighlighter +QSyntaxHighlighter::_ZTV18QSyntaxHighlighter: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QSyntaxHighlighter) +16 (int (*)(...))QSyntaxHighlighter::metaObject +24 (int (*)(...))QSyntaxHighlighter::qt_metacast +32 (int (*)(...))QSyntaxHighlighter::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QSyntaxHighlighter + size=16 align=8 + base size=16 base align=8 +QSyntaxHighlighter (0x0x7f58d5281958) 0 + vptr=((& QSyntaxHighlighter::_ZTV18QSyntaxHighlighter) + 16u) + QObject (0x0x7f58d53252a0) 0 + primary-for QSyntaxHighlighter (0x0x7f58d5281958) + +Class QTextDocumentFragment + size=8 align=8 + base size=8 base align=8 +QTextDocumentFragment (0x0x7f58d5325360) 0 + +Class QTextDocumentWriter + size=8 align=8 + base size=8 base align=8 +QTextDocumentWriter (0x0x7f58d53253c0) 0 + +Class QTextList::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextList::QPrivateSignal (0x0x7f58d5325480) 0 empty + +Vtable for QTextList +QTextList::_ZTV9QTextList: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTextList) +16 (int (*)(...))QTextList::metaObject +24 (int (*)(...))QTextList::qt_metacast +32 (int (*)(...))QTextList::qt_metacall +40 (int (*)(...))QTextList::~QTextList +48 (int (*)(...))QTextList::~QTextList +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTextBlockGroup::blockInserted +120 (int (*)(...))QTextBlockGroup::blockRemoved +128 (int (*)(...))QTextBlockGroup::blockFormatChanged + +Class QTextList + size=16 align=8 + base size=16 base align=8 +QTextList (0x0x7f58d52819c0) 0 + vptr=((& QTextList::_ZTV9QTextList) + 16u) + QTextBlockGroup (0x0x7f58d5281a28) 0 + primary-for QTextList (0x0x7f58d52819c0) + QTextObject (0x0x7f58d5281a90) 0 + primary-for QTextBlockGroup (0x0x7f58d5281a28) + QObject (0x0x7f58d5325420) 0 + primary-for QTextObject (0x0x7f58d5281a90) + +Class QTextTableCell + size=16 align=8 + base size=12 base align=8 +QTextTableCell (0x0x7f58d53254e0) 0 + +Class QTextTable::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextTable::QPrivateSignal (0x0x7f58d53255a0) 0 empty + +Vtable for QTextTable +QTextTable::_ZTV10QTextTable: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextTable) +16 (int (*)(...))QTextTable::metaObject +24 (int (*)(...))QTextTable::qt_metacast +32 (int (*)(...))QTextTable::qt_metacall +40 (int (*)(...))QTextTable::~QTextTable +48 (int (*)(...))QTextTable::~QTextTable +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTextTable + size=16 align=8 + base size=16 base align=8 +QTextTable (0x0x7f58d5281af8) 0 + vptr=((& QTextTable::_ZTV10QTextTable) + 16u) + QTextFrame (0x0x7f58d5281b60) 0 + primary-for QTextTable (0x0x7f58d5281af8) + QTextObject (0x0x7f58d5281bc8) 0 + primary-for QTextFrame (0x0x7f58d5281b60) + QObject (0x0x7f58d5325540) 0 + primary-for QTextObject (0x0x7f58d5281bc8) + +Class QValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QValidator::QPrivateSignal (0x0x7f58d5325660) 0 empty + +Vtable for QValidator +QValidator::_ZTV10QValidator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QValidator) +16 (int (*)(...))QValidator::metaObject +24 (int (*)(...))QValidator::qt_metacast +32 (int (*)(...))QValidator::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))QValidator::fixup + +Class QValidator + size=16 align=8 + base size=16 base align=8 +QValidator (0x0x7f58d5281c30) 0 + vptr=((& QValidator::_ZTV10QValidator) + 16u) + QObject (0x0x7f58d5325600) 0 + primary-for QValidator (0x0x7f58d5281c30) + +Class QIntValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIntValidator::QPrivateSignal (0x0x7f58d5325720) 0 empty + +Vtable for QIntValidator +QIntValidator::_ZTV13QIntValidator: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QIntValidator) +16 (int (*)(...))QIntValidator::metaObject +24 (int (*)(...))QIntValidator::qt_metacast +32 (int (*)(...))QIntValidator::qt_metacall +40 (int (*)(...))QIntValidator::~QIntValidator +48 (int (*)(...))QIntValidator::~QIntValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIntValidator::validate +120 (int (*)(...))QIntValidator::fixup +128 (int (*)(...))QIntValidator::setRange + +Class QIntValidator + size=24 align=8 + base size=24 base align=8 +QIntValidator (0x0x7f58d5281c98) 0 + vptr=((& QIntValidator::_ZTV13QIntValidator) + 16u) + QValidator (0x0x7f58d5281d00) 0 + primary-for QIntValidator (0x0x7f58d5281c98) + QObject (0x0x7f58d53256c0) 0 + primary-for QValidator (0x0x7f58d5281d00) + +Class QDoubleValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDoubleValidator::QPrivateSignal (0x0x7f58d53257e0) 0 empty + +Vtable for QDoubleValidator +QDoubleValidator::_ZTV16QDoubleValidator: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QDoubleValidator) +16 (int (*)(...))QDoubleValidator::metaObject +24 (int (*)(...))QDoubleValidator::qt_metacast +32 (int (*)(...))QDoubleValidator::qt_metacall +40 (int (*)(...))QDoubleValidator::~QDoubleValidator +48 (int (*)(...))QDoubleValidator::~QDoubleValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QDoubleValidator::validate +120 (int (*)(...))QValidator::fixup +128 (int (*)(...))QDoubleValidator::setRange + +Class QDoubleValidator + size=40 align=8 + base size=36 base align=8 +QDoubleValidator (0x0x7f58d5281d68) 0 + vptr=((& QDoubleValidator::_ZTV16QDoubleValidator) + 16u) + QValidator (0x0x7f58d5281dd0) 0 + primary-for QDoubleValidator (0x0x7f58d5281d68) + QObject (0x0x7f58d5325780) 0 + primary-for QValidator (0x0x7f58d5281dd0) + +Class QRegExpValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRegExpValidator::QPrivateSignal (0x0x7f58d5325900) 0 empty + +Vtable for QRegExpValidator +QRegExpValidator::_ZTV16QRegExpValidator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QRegExpValidator) +16 (int (*)(...))QRegExpValidator::metaObject +24 (int (*)(...))QRegExpValidator::qt_metacast +32 (int (*)(...))QRegExpValidator::qt_metacall +40 (int (*)(...))QRegExpValidator::~QRegExpValidator +48 (int (*)(...))QRegExpValidator::~QRegExpValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QRegExpValidator::validate +120 (int (*)(...))QValidator::fixup + +Class QRegExpValidator + size=24 align=8 + base size=24 base align=8 +QRegExpValidator (0x0x7f58d5281e38) 0 + vptr=((& QRegExpValidator::_ZTV16QRegExpValidator) + 16u) + QValidator (0x0x7f58d5281ea0) 0 + primary-for QRegExpValidator (0x0x7f58d5281e38) + QObject (0x0x7f58d53258a0) 0 + primary-for QValidator (0x0x7f58d5281ea0) + +Class QRegularExpressionValidator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRegularExpressionValidator::QPrivateSignal (0x0x7f58d53259c0) 0 empty + +Vtable for QRegularExpressionValidator +QRegularExpressionValidator::_ZTV27QRegularExpressionValidator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QRegularExpressionValidator) +16 (int (*)(...))QRegularExpressionValidator::metaObject +24 (int (*)(...))QRegularExpressionValidator::qt_metacast +32 (int (*)(...))QRegularExpressionValidator::qt_metacall +40 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator +48 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QRegularExpressionValidator::validate +120 (int (*)(...))QValidator::fixup + +Class QRegularExpressionValidator + size=16 align=8 + base size=16 base align=8 +QRegularExpressionValidator (0x0x7f58d5281f08) 0 + vptr=((& QRegularExpressionValidator::_ZTV27QRegularExpressionValidator) + 16u) + QValidator (0x0x7f58d5281f70) 0 + primary-for QRegularExpressionValidator (0x0x7f58d5281f08) + QObject (0x0x7f58d5325960) 0 + primary-for QValidator (0x0x7f58d5281f70) + +Class QSizePolicy::Bits + size=4 align=4 + base size=4 base align=4 +QSizePolicy::Bits (0x0x7f58d5325a80) 0 + +Class QSizePolicy + size=4 align=4 + base size=4 base align=4 +QSizePolicy (0x0x7f58d5325a20) 0 + +Class QWidgetData + size=88 align=8 + base size=88 base align=8 +QWidgetData (0x0x7f58d50273c0) 0 + +Class QWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWidget::QPrivateSignal (0x0x7f58d50274e0) 0 empty + +Vtable for QWidget +QWidget::_ZTV7QWidget: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QWidget) +16 (int (*)(...))QWidget::metaObject +24 (int (*)(...))QWidget::qt_metacast +32 (int (*)(...))QWidget::qt_metacall +40 (int (*)(...))QWidget::~QWidget +48 (int (*)(...))QWidget::~QWidget +56 (int (*)(...))QWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI7QWidget) +448 (int (*)(...))QWidget::_ZThn16_N7QWidgetD1Ev +456 (int (*)(...))QWidget::_ZThn16_N7QWidgetD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QWidget + size=48 align=8 + base size=48 base align=8 +QWidget (0x0x7f58d5066a80) 0 + vptr=((& QWidget::_ZTV7QWidget) + 16u) + QObject (0x0x7f58d5027420) 0 + primary-for QWidget (0x0x7f58d5066a80) + QPaintDevice (0x0x7f58d5027480) 16 + vptr=((& QWidget::_ZTV7QWidget) + 448u) + +Class QAbstractButton::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractButton::QPrivateSignal (0x0x7f58d4d67180) 0 empty + +Vtable for QAbstractButton +QAbstractButton::_ZTV15QAbstractButton: 67u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAbstractButton) +16 (int (*)(...))QAbstractButton::metaObject +24 (int (*)(...))QAbstractButton::qt_metacast +32 (int (*)(...))QAbstractButton::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractButton::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractButton::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractButton::mousePressEvent +176 (int (*)(...))QAbstractButton::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractButton::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QAbstractButton::keyPressEvent +216 (int (*)(...))QAbstractButton::keyReleaseEvent +224 (int (*)(...))QAbstractButton::focusInEvent +232 (int (*)(...))QAbstractButton::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))__cxa_pure_virtual +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractButton::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QAbstractButton::hitButton +440 (int (*)(...))QAbstractButton::checkStateSet +448 (int (*)(...))QAbstractButton::nextCheckState +456 (int (*)(...))-16 +464 (int (*)(...))(& _ZTI15QAbstractButton) +472 0u +480 0u +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QAbstractButton + size=48 align=8 + base size=48 base align=8 +QAbstractButton (0x0x7f58d4d662d8) 0 + vptr=((& QAbstractButton::_ZTV15QAbstractButton) + 16u) + QWidget (0x0x7f58d4d5b770) 0 + primary-for QAbstractButton (0x0x7f58d4d662d8) + QObject (0x0x7f58d4d670c0) 0 + primary-for QWidget (0x0x7f58d4d5b770) + QPaintDevice (0x0x7f58d4d67120) 16 + vptr=((& QAbstractButton::_ZTV15QAbstractButton) + 472u) + +Class QAbstractSpinBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractSpinBox::QPrivateSignal (0x0x7f58d4d672a0) 0 empty + +Vtable for QAbstractSpinBox +QAbstractSpinBox::_ZTV16QAbstractSpinBox: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAbstractSpinBox) +16 (int (*)(...))QAbstractSpinBox::metaObject +24 (int (*)(...))QAbstractSpinBox::qt_metacast +32 (int (*)(...))QAbstractSpinBox::qt_metacall +40 (int (*)(...))QAbstractSpinBox::~QAbstractSpinBox +48 (int (*)(...))QAbstractSpinBox::~QAbstractSpinBox +56 (int (*)(...))QAbstractSpinBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSpinBox::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractSpinBox::sizeHint +136 (int (*)(...))QAbstractSpinBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractSpinBox::mousePressEvent +176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent +200 (int (*)(...))QAbstractSpinBox::wheelEvent +208 (int (*)(...))QAbstractSpinBox::keyPressEvent +216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent +224 (int (*)(...))QAbstractSpinBox::focusInEvent +232 (int (*)(...))QAbstractSpinBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractSpinBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractSpinBox::resizeEvent +280 (int (*)(...))QAbstractSpinBox::closeEvent +288 (int (*)(...))QAbstractSpinBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QAbstractSpinBox::showEvent +352 (int (*)(...))QAbstractSpinBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSpinBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QAbstractSpinBox::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QAbstractSpinBox::validate +440 (int (*)(...))QAbstractSpinBox::fixup +448 (int (*)(...))QAbstractSpinBox::stepBy +456 (int (*)(...))QAbstractSpinBox::clear +464 (int (*)(...))QAbstractSpinBox::stepEnabled +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI16QAbstractSpinBox) +488 (int (*)(...))QAbstractSpinBox::_ZThn16_N16QAbstractSpinBoxD1Ev +496 (int (*)(...))QAbstractSpinBox::_ZThn16_N16QAbstractSpinBoxD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QAbstractSpinBox + size=48 align=8 + base size=48 base align=8 +QAbstractSpinBox (0x0x7f58d4d66340) 0 + vptr=((& QAbstractSpinBox::_ZTV16QAbstractSpinBox) + 16u) + QWidget (0x0x7f58d4d5ba80) 0 + primary-for QAbstractSpinBox (0x0x7f58d4d66340) + QObject (0x0x7f58d4d671e0) 0 + primary-for QWidget (0x0x7f58d4d5ba80) + QPaintDevice (0x0x7f58d4d67240) 16 + vptr=((& QAbstractSpinBox::_ZTV16QAbstractSpinBox) + 488u) + +Class QAbstractSlider::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractSlider::QPrivateSignal (0x0x7f58d4d67540) 0 empty + +Vtable for QAbstractSlider +QAbstractSlider::_ZTV15QAbstractSlider: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAbstractSlider) +16 (int (*)(...))QAbstractSlider::metaObject +24 (int (*)(...))QAbstractSlider::qt_metacast +32 (int (*)(...))QAbstractSlider::qt_metacall +40 (int (*)(...))QAbstractSlider::~QAbstractSlider +48 (int (*)(...))QAbstractSlider::~QAbstractSlider +56 (int (*)(...))QAbstractSlider::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSlider::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QAbstractSlider::wheelEvent +208 (int (*)(...))QAbstractSlider::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSlider::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QAbstractSlider::sliderChange +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI15QAbstractSlider) +456 (int (*)(...))QAbstractSlider::_ZThn16_N15QAbstractSliderD1Ev +464 (int (*)(...))QAbstractSlider::_ZThn16_N15QAbstractSliderD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QAbstractSlider + size=48 align=8 + base size=48 base align=8 +QAbstractSlider (0x0x7f58d4d66478) 0 + vptr=((& QAbstractSlider::_ZTV15QAbstractSlider) + 16u) + QWidget (0x0x7f58d4d9ee70) 0 + primary-for QAbstractSlider (0x0x7f58d4d66478) + QObject (0x0x7f58d4d67480) 0 + primary-for QWidget (0x0x7f58d4d9ee70) + QPaintDevice (0x0x7f58d4d674e0) 16 + vptr=((& QAbstractSlider::_ZTV15QAbstractSlider) + 456u) + +Class QSlider::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSlider::QPrivateSignal (0x0x7f58d4d67660) 0 empty + +Vtable for QSlider +QSlider::_ZTV7QSlider: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QSlider) +16 (int (*)(...))QSlider::metaObject +24 (int (*)(...))QSlider::qt_metacast +32 (int (*)(...))QSlider::qt_metacall +40 (int (*)(...))QSlider::~QSlider +48 (int (*)(...))QSlider::~QSlider +56 (int (*)(...))QSlider::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSlider::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QSlider::sizeHint +136 (int (*)(...))QSlider::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QSlider::mousePressEvent +176 (int (*)(...))QSlider::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QSlider::mouseMoveEvent +200 (int (*)(...))QAbstractSlider::wheelEvent +208 (int (*)(...))QAbstractSlider::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QSlider::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSlider::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QAbstractSlider::sliderChange +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI7QSlider) +456 (int (*)(...))QSlider::_ZThn16_N7QSliderD1Ev +464 (int (*)(...))QSlider::_ZThn16_N7QSliderD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QSlider + size=48 align=8 + base size=48 base align=8 +QSlider (0x0x7f58d4d664e0) 0 + vptr=((& QSlider::_ZTV7QSlider) + 16u) + QAbstractSlider (0x0x7f58d4d66548) 0 + primary-for QSlider (0x0x7f58d4d664e0) + QWidget (0x0x7f58d4df1700) 0 + primary-for QAbstractSlider (0x0x7f58d4d66548) + QObject (0x0x7f58d4d675a0) 0 + primary-for QWidget (0x0x7f58d4df1700) + QPaintDevice (0x0x7f58d4d67600) 16 + vptr=((& QSlider::_ZTV7QSlider) + 456u) + +Class QStyle::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStyle::QPrivateSignal (0x0x7f58d4d67720) 0 empty + +Vtable for QStyle +QStyle::_ZTV6QStyle: 37u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QStyle) +16 (int (*)(...))QStyle::metaObject +24 (int (*)(...))QStyle::qt_metacast +32 (int (*)(...))QStyle::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStyle::polish +120 (int (*)(...))QStyle::unpolish +128 (int (*)(...))QStyle::polish +136 (int (*)(...))QStyle::unpolish +144 (int (*)(...))QStyle::polish +152 (int (*)(...))QStyle::itemTextRect +160 (int (*)(...))QStyle::itemPixmapRect +168 (int (*)(...))QStyle::drawItemText +176 (int (*)(...))QStyle::drawItemPixmap +184 (int (*)(...))QStyle::standardPalette +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))__cxa_pure_virtual +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))__cxa_pure_virtual +232 (int (*)(...))__cxa_pure_virtual +240 (int (*)(...))__cxa_pure_virtual +248 (int (*)(...))__cxa_pure_virtual +256 (int (*)(...))__cxa_pure_virtual +264 (int (*)(...))__cxa_pure_virtual +272 (int (*)(...))__cxa_pure_virtual +280 (int (*)(...))__cxa_pure_virtual +288 (int (*)(...))__cxa_pure_virtual + +Class QStyle + size=16 align=8 + base size=16 base align=8 +QStyle (0x0x7f58d4d66618) 0 + vptr=((& QStyle::_ZTV6QStyle) + 16u) + QObject (0x0x7f58d4d676c0) 0 + primary-for QStyle (0x0x7f58d4d66618) + +Class QTabBar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTabBar::QPrivateSignal (0x0x7f58d4d67b40) 0 empty + +Vtable for QTabBar +QTabBar::_ZTV7QTabBar: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QTabBar) +16 (int (*)(...))QTabBar::metaObject +24 (int (*)(...))QTabBar::qt_metacast +32 (int (*)(...))QTabBar::qt_metacall +40 (int (*)(...))QTabBar::~QTabBar +48 (int (*)(...))QTabBar::~QTabBar +56 (int (*)(...))QTabBar::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTabBar::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QTabBar::sizeHint +136 (int (*)(...))QTabBar::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QTabBar::mousePressEvent +176 (int (*)(...))QTabBar::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QTabBar::mouseMoveEvent +200 (int (*)(...))QTabBar::wheelEvent +208 (int (*)(...))QTabBar::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTabBar::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QTabBar::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QTabBar::showEvent +352 (int (*)(...))QTabBar::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QTabBar::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QTabBar::tabSizeHint +440 (int (*)(...))QTabBar::minimumTabSizeHint +448 (int (*)(...))QTabBar::tabInserted +456 (int (*)(...))QTabBar::tabRemoved +464 (int (*)(...))QTabBar::tabLayoutChange +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI7QTabBar) +488 (int (*)(...))QTabBar::_ZThn16_N7QTabBarD1Ev +496 (int (*)(...))QTabBar::_ZThn16_N7QTabBarD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTabBar + size=48 align=8 + base size=48 base align=8 +QTabBar (0x0x7f58d4d66820) 0 + vptr=((& QTabBar::_ZTV7QTabBar) + 16u) + QWidget (0x0x7f58d4ebe690) 0 + primary-for QTabBar (0x0x7f58d4d66820) + QObject (0x0x7f58d4d67a80) 0 + primary-for QWidget (0x0x7f58d4ebe690) + QPaintDevice (0x0x7f58d4d67ae0) 16 + vptr=((& QTabBar::_ZTV7QTabBar) + 488u) + +Class QTabWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTabWidget::QPrivateSignal (0x0x7f58d4d67c60) 0 empty + +Vtable for QTabWidget +QTabWidget::_ZTV10QTabWidget: 66u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTabWidget) +16 (int (*)(...))QTabWidget::metaObject +24 (int (*)(...))QTabWidget::qt_metacast +32 (int (*)(...))QTabWidget::qt_metacall +40 (int (*)(...))QTabWidget::~QTabWidget +48 (int (*)(...))QTabWidget::~QTabWidget +56 (int (*)(...))QTabWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QTabWidget::sizeHint +136 (int (*)(...))QTabWidget::minimumSizeHint +144 (int (*)(...))QTabWidget::heightForWidth +152 (int (*)(...))QTabWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QTabWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTabWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QTabWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QTabWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QTabWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QTabWidget::tabInserted +440 (int (*)(...))QTabWidget::tabRemoved +448 (int (*)(...))-16 +456 (int (*)(...))(& _ZTI10QTabWidget) +464 (int (*)(...))QTabWidget::_ZThn16_N10QTabWidgetD1Ev +472 (int (*)(...))QTabWidget::_ZThn16_N10QTabWidgetD0Ev +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTabWidget + size=48 align=8 + base size=48 base align=8 +QTabWidget (0x0x7f58d4d66888) 0 + vptr=((& QTabWidget::_ZTV10QTabWidget) + 16u) + QWidget (0x0x7f58d4eff070) 0 + primary-for QTabWidget (0x0x7f58d4d66888) + QObject (0x0x7f58d4d67ba0) 0 + primary-for QWidget (0x0x7f58d4eff070) + QPaintDevice (0x0x7f58d4d67c00) 16 + vptr=((& QTabWidget::_ZTV10QTabWidget) + 464u) + +Class QRubberBand::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRubberBand::QPrivateSignal (0x0x7f58d4d67d80) 0 empty + +Vtable for QRubberBand +QRubberBand::_ZTV11QRubberBand: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QRubberBand) +16 (int (*)(...))QRubberBand::metaObject +24 (int (*)(...))QRubberBand::qt_metacast +32 (int (*)(...))QRubberBand::qt_metacall +40 (int (*)(...))QRubberBand::~QRubberBand +48 (int (*)(...))QRubberBand::~QRubberBand +56 (int (*)(...))QRubberBand::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QRubberBand::paintEvent +264 (int (*)(...))QRubberBand::moveEvent +272 (int (*)(...))QRubberBand::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QRubberBand::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QRubberBand::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI11QRubberBand) +448 (int (*)(...))QRubberBand::_ZThn16_N11QRubberBandD1Ev +456 (int (*)(...))QRubberBand::_ZThn16_N11QRubberBandD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QRubberBand + size=48 align=8 + base size=48 base align=8 +QRubberBand (0x0x7f58d4d668f0) 0 + vptr=((& QRubberBand::_ZTV11QRubberBand) + 16u) + QWidget (0x0x7f58d4eff850) 0 + primary-for QRubberBand (0x0x7f58d4d668f0) + QObject (0x0x7f58d4d67cc0) 0 + primary-for QWidget (0x0x7f58d4eff850) + QPaintDevice (0x0x7f58d4d67d20) 16 + vptr=((& QRubberBand::_ZTV11QRubberBand) + 448u) + +Class QFrame::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFrame::QPrivateSignal (0x0x7f58d4d67ea0) 0 empty + +Vtable for QFrame +QFrame::_ZTV6QFrame: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QFrame) +16 (int (*)(...))QFrame::metaObject +24 (int (*)(...))QFrame::qt_metacast +32 (int (*)(...))QFrame::qt_metacall +40 (int (*)(...))QFrame::~QFrame +48 (int (*)(...))QFrame::~QFrame +56 (int (*)(...))QFrame::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QFrame::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QFrame::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI6QFrame) +448 (int (*)(...))QFrame::_ZThn16_N6QFrameD1Ev +456 (int (*)(...))QFrame::_ZThn16_N6QFrameD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QFrame + size=48 align=8 + base size=48 base align=8 +QFrame (0x0x7f58d4d66958) 0 + vptr=((& QFrame::_ZTV6QFrame) + 16u) + QWidget (0x0x7f58d4effe70) 0 + primary-for QFrame (0x0x7f58d4d66958) + QObject (0x0x7f58d4d67de0) 0 + primary-for QWidget (0x0x7f58d4effe70) + QPaintDevice (0x0x7f58d4d67e40) 16 + vptr=((& QFrame::_ZTV6QFrame) + 448u) + +Class QStyleOption + size=64 align=8 + base size=64 base align=8 +QStyleOption (0x0x7f58d4d67f00) 0 + +Class QStyleOptionFocusRect + size=80 align=8 + base size=80 base align=8 +QStyleOptionFocusRect (0x0x7f58d4d669c0) 0 + QStyleOption (0x0x7f58d4d67f60) 0 + +Class QStyleOptionFrame + size=80 align=8 + base size=80 base align=8 +QStyleOptionFrame (0x0x7f58d4d66a28) 0 + QStyleOption (0x0x7f58d4b35000) 0 + +Class QStyleOptionTabWidgetFrame + size=136 align=8 + base size=132 base align=8 +QStyleOptionTabWidgetFrame (0x0x7f58d4d66b60) 0 + QStyleOption (0x0x7f58d4b351e0) 0 + +Class QStyleOptionTabBarBase + size=104 align=8 + base size=101 base align=8 +QStyleOptionTabBarBase (0x0x7f58d4d66bc8) 0 + QStyleOption (0x0x7f58d4b35240) 0 + +Class QStyleOptionHeader + size=120 align=8 + base size=116 base align=8 +QStyleOptionHeader (0x0x7f58d4d66c30) 0 + QStyleOption (0x0x7f58d4b35300) 0 + +Class QStyleOptionButton + size=96 align=8 + base size=96 base align=8 +QStyleOptionButton (0x0x7f58d4d66c98) 0 + QStyleOption (0x0x7f58d4b35360) 0 + +Class QStyleOptionTab + size=136 align=8 + base size=136 base align=8 +QStyleOptionTab (0x0x7f58d4d66dd0) 0 + QStyleOption (0x0x7f58d4b35540) 0 + +Class QStyleOptionToolBar + size=88 align=8 + base size=88 base align=8 +QStyleOptionToolBar (0x0x7f58d4c2d000) 0 + QStyleOption (0x0x7f58d4b358a0) 0 + +Class QStyleOptionProgressBar + size=104 align=8 + base size=102 base align=8 +QStyleOptionProgressBar (0x0x7f58d4c2d138) 0 + QStyleOption (0x0x7f58d4b35a80) 0 + +Class QStyleOptionMenuItem + size=136 align=8 + base size=136 base align=8 +QStyleOptionMenuItem (0x0x7f58d4c2d1a0) 0 + QStyleOption (0x0x7f58d4b35ae0) 0 + +Class QStyleOptionDockWidget + size=80 align=8 + base size=76 base align=8 +QStyleOptionDockWidget (0x0x7f58d4c2d208) 0 + QStyleOption (0x0x7f58d4b35b40) 0 + +Class QStyleOptionViewItem + size=192 align=8 + base size=192 base align=8 +QStyleOptionViewItem (0x0x7f58d4c2d2d8) 0 + QStyleOption (0x0x7f58d4b35ba0) 0 + +Class QStyleOptionToolBox + size=88 align=8 + base size=88 base align=8 +QStyleOptionToolBox (0x0x7f58d4c2d410) 0 + QStyleOption (0x0x7f58d4b35d80) 0 + +Class QStyleOptionRubberBand + size=72 align=8 + base size=69 base align=8 +QStyleOptionRubberBand (0x0x7f58d4c2d478) 0 + QStyleOption (0x0x7f58d4b35de0) 0 + +Class QStyleOptionComplex + size=72 align=8 + base size=72 base align=8 +QStyleOptionComplex (0x0x7f58d4c2d4e0) 0 + QStyleOption (0x0x7f58d4b35e40) 0 + +Class QStyleOptionSlider + size=128 align=8 + base size=121 base align=8 +QStyleOptionSlider (0x0x7f58d4c2d548) 0 + QStyleOptionComplex (0x0x7f58d4c2d5b0) 0 + QStyleOption (0x0x7f58d4b35ea0) 0 + +Class QStyleOptionSpinBox + size=88 align=8 + base size=81 base align=8 +QStyleOptionSpinBox (0x0x7f58d4c2d618) 0 + QStyleOptionComplex (0x0x7f58d4c2d680) 0 + QStyleOption (0x0x7f58d4b35f00) 0 + +Class QStyleOptionToolButton + size=136 align=8 + base size=136 base align=8 +QStyleOptionToolButton (0x0x7f58d4c2d6e8) 0 + QStyleOptionComplex (0x0x7f58d4c2d750) 0 + QStyleOption (0x0x7f58d4b35f60) 0 + +Class QStyleOptionComboBox + size=120 align=8 + base size=120 base align=8 +QStyleOptionComboBox (0x0x7f58d4c2d888) 0 + QStyleOptionComplex (0x0x7f58d4c2d8f0) 0 + QStyleOption (0x0x7f58d4d12180) 0 + +Class QStyleOptionTitleBar + size=96 align=8 + base size=96 base align=8 +QStyleOptionTitleBar (0x0x7f58d4c2d958) 0 + QStyleOptionComplex (0x0x7f58d4c2d9c0) 0 + QStyleOption (0x0x7f58d4d121e0) 0 + +Class QStyleOptionGroupBox + size=120 align=8 + base size=116 base align=8 +QStyleOptionGroupBox (0x0x7f58d4c2da28) 0 + QStyleOptionComplex (0x0x7f58d4c2da90) 0 + QStyleOption (0x0x7f58d4d122a0) 0 + +Class QStyleOptionSizeGrip + size=80 align=8 + base size=76 base align=8 +QStyleOptionSizeGrip (0x0x7f58d4c2daf8) 0 + QStyleOptionComplex (0x0x7f58d4c2db60) 0 + QStyleOption (0x0x7f58d4d12300) 0 + +Class QStyleOptionGraphicsItem + size=152 align=8 + base size=152 base align=8 +QStyleOptionGraphicsItem (0x0x7f58d4c2dbc8) 0 + QStyleOption (0x0x7f58d4d12360) 0 + +Class QStyleHintReturn + size=8 align=4 + base size=8 base align=4 +QStyleHintReturn (0x0x7f58d4d12840) 0 + +Class QStyleHintReturnMask + size=16 align=8 + base size=16 base align=8 +QStyleHintReturnMask (0x0x7f58d49891a0) 0 + QStyleHintReturn (0x0x7f58d4d128a0) 0 + +Class QStyleHintReturnVariant + size=24 align=8 + base size=24 base align=8 +QStyleHintReturnVariant (0x0x7f58d4989208) 0 + QStyleHintReturn (0x0x7f58d4d12900) 0 + +Class QAbstractItemDelegate::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemDelegate::QPrivateSignal (0x0x7f58d4d12e40) 0 empty + +Vtable for QAbstractItemDelegate +QAbstractItemDelegate::_ZTV21QAbstractItemDelegate: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QAbstractItemDelegate) +16 (int (*)(...))QAbstractItemDelegate::metaObject +24 (int (*)(...))QAbstractItemDelegate::qt_metacast +32 (int (*)(...))QAbstractItemDelegate::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemDelegate::createEditor +136 (int (*)(...))QAbstractItemDelegate::destroyEditor +144 (int (*)(...))QAbstractItemDelegate::setEditorData +152 (int (*)(...))QAbstractItemDelegate::setModelData +160 (int (*)(...))QAbstractItemDelegate::updateEditorGeometry +168 (int (*)(...))QAbstractItemDelegate::editorEvent +176 (int (*)(...))QAbstractItemDelegate::helpEvent +184 (int (*)(...))QAbstractItemDelegate::paintingRoles + +Class QAbstractItemDelegate + size=16 align=8 + base size=16 base align=8 +QAbstractItemDelegate (0x0x7f58d4989750) 0 + vptr=((& QAbstractItemDelegate::_ZTV21QAbstractItemDelegate) + 16u) + QObject (0x0x7f58d4d12de0) 0 + primary-for QAbstractItemDelegate (0x0x7f58d4989750) + +Class QAbstractScrollArea::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractScrollArea::QPrivateSignal (0x0x7f58d49d6000) 0 empty + +Vtable for QAbstractScrollArea +QAbstractScrollArea::_ZTV19QAbstractScrollArea: 68u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractScrollArea) +16 (int (*)(...))QAbstractScrollArea::metaObject +24 (int (*)(...))QAbstractScrollArea::qt_metacast +32 (int (*)(...))QAbstractScrollArea::qt_metacall +40 (int (*)(...))QAbstractScrollArea::~QAbstractScrollArea +48 (int (*)(...))QAbstractScrollArea::~QAbstractScrollArea +56 (int (*)(...))QAbstractScrollArea::event +64 (int (*)(...))QAbstractScrollArea::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractScrollArea::mousePressEvent +176 (int (*)(...))QAbstractScrollArea::mouseReleaseEvent +184 (int (*)(...))QAbstractScrollArea::mouseDoubleClickEvent +192 (int (*)(...))QAbstractScrollArea::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractScrollArea::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractScrollArea::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractScrollArea::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractScrollArea::dragEnterEvent +320 (int (*)(...))QAbstractScrollArea::dragMoveEvent +328 (int (*)(...))QAbstractScrollArea::dragLeaveEvent +336 (int (*)(...))QAbstractScrollArea::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractScrollArea::viewportEvent +448 (int (*)(...))QAbstractScrollArea::scrollContentsBy +456 (int (*)(...))QAbstractScrollArea::viewportSizeHint +464 (int (*)(...))-16 +472 (int (*)(...))(& _ZTI19QAbstractScrollArea) +480 (int (*)(...))QAbstractScrollArea::_ZThn16_N19QAbstractScrollAreaD1Ev +488 (int (*)(...))QAbstractScrollArea::_ZThn16_N19QAbstractScrollAreaD0Ev +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QAbstractScrollArea + size=48 align=8 + base size=48 base align=8 +QAbstractScrollArea (0x0x7f58d49897b8) 0 + vptr=((& QAbstractScrollArea::_ZTV19QAbstractScrollArea) + 16u) + QFrame (0x0x7f58d4989820) 0 + primary-for QAbstractScrollArea (0x0x7f58d49897b8) + QWidget (0x0x7f58d49aeb60) 0 + primary-for QFrame (0x0x7f58d4989820) + QObject (0x0x7f58d4d12f00) 0 + primary-for QWidget (0x0x7f58d49aeb60) + QPaintDevice (0x0x7f58d4d12f60) 16 + vptr=((& QAbstractScrollArea::_ZTV19QAbstractScrollArea) + 480u) + +Class QAbstractItemView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemView::QPrivateSignal (0x0x7f58d49d6120) 0 empty + +Vtable for QAbstractItemView +QAbstractItemView::_ZTV17QAbstractItemView: 106u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAbstractItemView) +16 (int (*)(...))QAbstractItemView::metaObject +24 (int (*)(...))QAbstractItemView::qt_metacast +32 (int (*)(...))QAbstractItemView::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractItemView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QAbstractItemView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QAbstractItemView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QAbstractItemView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractScrollArea::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractItemView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QAbstractItemView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QAbstractItemView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractItemView::viewportEvent +448 (int (*)(...))QAbstractScrollArea::scrollContentsBy +456 (int (*)(...))QAbstractItemView::viewportSizeHint +464 (int (*)(...))QAbstractItemView::setModel +472 (int (*)(...))QAbstractItemView::setSelectionModel +480 (int (*)(...))QAbstractItemView::keyboardSearch +488 (int (*)(...))__cxa_pure_virtual +496 (int (*)(...))__cxa_pure_virtual +504 (int (*)(...))__cxa_pure_virtual +512 (int (*)(...))QAbstractItemView::sizeHintForRow +520 (int (*)(...))QAbstractItemView::sizeHintForColumn +528 (int (*)(...))QAbstractItemView::reset +536 (int (*)(...))QAbstractItemView::setRootIndex +544 (int (*)(...))QAbstractItemView::doItemsLayout +552 (int (*)(...))QAbstractItemView::selectAll +560 (int (*)(...))QAbstractItemView::dataChanged +568 (int (*)(...))QAbstractItemView::rowsInserted +576 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved +584 (int (*)(...))QAbstractItemView::selectionChanged +592 (int (*)(...))QAbstractItemView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QAbstractItemView::updateGeometries +624 (int (*)(...))QAbstractItemView::verticalScrollbarAction +632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction +640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))__cxa_pure_virtual +688 (int (*)(...))__cxa_pure_virtual +696 (int (*)(...))__cxa_pure_virtual +704 (int (*)(...))__cxa_pure_virtual +712 (int (*)(...))__cxa_pure_virtual +720 (int (*)(...))__cxa_pure_virtual +728 (int (*)(...))QAbstractItemView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QAbstractItemView::startDrag +760 (int (*)(...))QAbstractItemView::viewOptions +768 (int (*)(...))-16 +776 (int (*)(...))(& _ZTI17QAbstractItemView) +784 0u +792 0u +800 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +808 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +816 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QAbstractItemView + size=48 align=8 + base size=48 base align=8 +QAbstractItemView (0x0x7f58d4989888) 0 + vptr=((& QAbstractItemView::_ZTV17QAbstractItemView) + 16u) + QAbstractScrollArea (0x0x7f58d49898f0) 0 + primary-for QAbstractItemView (0x0x7f58d4989888) + QFrame (0x0x7f58d4989958) 0 + primary-for QAbstractScrollArea (0x0x7f58d49898f0) + QWidget (0x0x7f58d49f20e0) 0 + primary-for QFrame (0x0x7f58d4989958) + QObject (0x0x7f58d49d6060) 0 + primary-for QWidget (0x0x7f58d49f20e0) + QPaintDevice (0x0x7f58d49d60c0) 16 + vptr=((& QAbstractItemView::_ZTV17QAbstractItemView) + 784u) + +Vtable for QAccessibleWidget +QAccessibleWidget::_ZTV17QAccessibleWidget: 35u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QAccessibleWidget) +16 (int (*)(...))QAccessibleWidget::~QAccessibleWidget +24 (int (*)(...))QAccessibleWidget::~QAccessibleWidget +32 (int (*)(...))QAccessibleWidget::isValid +40 (int (*)(...))QAccessibleObject::object +48 (int (*)(...))QAccessibleWidget::window +56 (int (*)(...))QAccessibleWidget::relations +64 (int (*)(...))QAccessibleWidget::focusChild +72 (int (*)(...))QAccessibleObject::childAt +80 (int (*)(...))QAccessibleWidget::parent +88 (int (*)(...))QAccessibleWidget::child +96 (int (*)(...))QAccessibleWidget::childCount +104 (int (*)(...))QAccessibleWidget::indexOfChild +112 (int (*)(...))QAccessibleWidget::text +120 (int (*)(...))QAccessibleObject::setText +128 (int (*)(...))QAccessibleWidget::rect +136 (int (*)(...))QAccessibleWidget::role +144 (int (*)(...))QAccessibleWidget::state +152 (int (*)(...))QAccessibleWidget::foregroundColor +160 (int (*)(...))QAccessibleWidget::backgroundColor +168 (int (*)(...))QAccessibleInterface::virtual_hook +176 (int (*)(...))QAccessibleWidget::interface_cast +184 (int (*)(...))QAccessibleWidget::actionNames +192 (int (*)(...))QAccessibleWidget::doAction +200 (int (*)(...))QAccessibleWidget::keyBindingsForAction +208 (int (*)(...))-16 +216 (int (*)(...))(& _ZTI17QAccessibleWidget) +224 (int (*)(...))QAccessibleWidget::_ZThn16_N17QAccessibleWidgetD1Ev +232 (int (*)(...))QAccessibleWidget::_ZThn16_N17QAccessibleWidgetD0Ev +240 (int (*)(...))QAccessibleWidget::_ZThn16_NK17QAccessibleWidget11actionNamesEv +248 (int (*)(...))QAccessibleActionInterface::localizedActionName +256 (int (*)(...))QAccessibleActionInterface::localizedActionDescription +264 (int (*)(...))QAccessibleWidget::_ZThn16_N17QAccessibleWidget8doActionERK7QString +272 (int (*)(...))QAccessibleWidget::_ZThn16_NK17QAccessibleWidget20keyBindingsForActionERK7QString + +Class QAccessibleWidget + size=32 align=8 + base size=32 base align=8 +QAccessibleWidget (0x0x7f58d4a5c7e0) 0 + vptr=((& QAccessibleWidget::_ZTV17QAccessibleWidget) + 16u) + QAccessibleObject (0x0x7f58d4989a90) 0 + primary-for QAccessibleWidget (0x0x7f58d4a5c7e0) + QAccessibleInterface (0x0x7f58d49d6300) 0 nearly-empty + primary-for QAccessibleObject (0x0x7f58d4989a90) + QAccessibleActionInterface (0x0x7f58d49d6360) 16 nearly-empty + vptr=((& QAccessibleWidget::_ZTV17QAccessibleWidget) + 224u) + +Class QAction::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAction::QPrivateSignal (0x0x7f58d49d6480) 0 empty + +Vtable for QAction +QAction::_ZTV7QAction: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QAction) +16 (int (*)(...))QAction::metaObject +24 (int (*)(...))QAction::qt_metacast +32 (int (*)(...))QAction::qt_metacall +40 (int (*)(...))QAction::~QAction +48 (int (*)(...))QAction::~QAction +56 (int (*)(...))QAction::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QAction + size=16 align=8 + base size=16 base align=8 +QAction (0x0x7f58d4989af8) 0 + vptr=((& QAction::_ZTV7QAction) + 16u) + QObject (0x0x7f58d49d6420) 0 + primary-for QAction (0x0x7f58d4989af8) + +Class QActionGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QActionGroup::QPrivateSignal (0x0x7f58d49d6540) 0 empty + +Vtable for QActionGroup +QActionGroup::_ZTV12QActionGroup: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QActionGroup) +16 (int (*)(...))QActionGroup::metaObject +24 (int (*)(...))QActionGroup::qt_metacast +32 (int (*)(...))QActionGroup::qt_metacall +40 (int (*)(...))QActionGroup::~QActionGroup +48 (int (*)(...))QActionGroup::~QActionGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QActionGroup + size=16 align=8 + base size=16 base align=8 +QActionGroup (0x0x7f58d4989b60) 0 + vptr=((& QActionGroup::_ZTV12QActionGroup) + 16u) + QObject (0x0x7f58d49d64e0) 0 + primary-for QActionGroup (0x0x7f58d4989b60) + +Class QApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QApplication::QPrivateSignal (0x0x7f58d49d6600) 0 empty + +Vtable for QApplication +QApplication::_ZTV12QApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QApplication) +16 (int (*)(...))QApplication::metaObject +24 (int (*)(...))QApplication::qt_metacast +32 (int (*)(...))QApplication::qt_metacall +40 (int (*)(...))QApplication::~QApplication +48 (int (*)(...))QApplication::~QApplication +56 (int (*)(...))QApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QApplication::notify +120 (int (*)(...))QApplication::compressEvent + +Class QApplication + size=16 align=8 + base size=16 base align=8 +QApplication (0x0x7f58d4989bc8) 0 + vptr=((& QApplication::_ZTV12QApplication) + 16u) + QGuiApplication (0x0x7f58d4989c30) 0 + primary-for QApplication (0x0x7f58d4989bc8) + QCoreApplication (0x0x7f58d4989c98) 0 + primary-for QGuiApplication (0x0x7f58d4989c30) + QObject (0x0x7f58d49d65a0) 0 + primary-for QCoreApplication (0x0x7f58d4989c98) + +Vtable for QLayoutItem +QLayoutItem::_ZTV11QLayoutItem: 19u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QLayoutItem) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))QLayoutItem::hasHeightForWidth +96 (int (*)(...))QLayoutItem::heightForWidth +104 (int (*)(...))QLayoutItem::minimumHeightForWidth +112 (int (*)(...))QLayoutItem::invalidate +120 (int (*)(...))QLayoutItem::widget +128 (int (*)(...))QLayoutItem::layout +136 (int (*)(...))QLayoutItem::spacerItem +144 (int (*)(...))QLayoutItem::controlTypes + +Class QLayoutItem + size=16 align=8 + base size=12 base align=8 +QLayoutItem (0x0x7f58d49d6660) 0 + vptr=((& QLayoutItem::_ZTV11QLayoutItem) + 16u) + +Vtable for QSpacerItem +QSpacerItem::_ZTV11QSpacerItem: 19u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QSpacerItem) +16 (int (*)(...))QSpacerItem::~QSpacerItem +24 (int (*)(...))QSpacerItem::~QSpacerItem +32 (int (*)(...))QSpacerItem::sizeHint +40 (int (*)(...))QSpacerItem::minimumSize +48 (int (*)(...))QSpacerItem::maximumSize +56 (int (*)(...))QSpacerItem::expandingDirections +64 (int (*)(...))QSpacerItem::setGeometry +72 (int (*)(...))QSpacerItem::geometry +80 (int (*)(...))QSpacerItem::isEmpty +88 (int (*)(...))QLayoutItem::hasHeightForWidth +96 (int (*)(...))QLayoutItem::heightForWidth +104 (int (*)(...))QLayoutItem::minimumHeightForWidth +112 (int (*)(...))QLayoutItem::invalidate +120 (int (*)(...))QLayoutItem::widget +128 (int (*)(...))QLayoutItem::layout +136 (int (*)(...))QSpacerItem::spacerItem +144 (int (*)(...))QLayoutItem::controlTypes + +Class QSpacerItem + size=40 align=8 + base size=40 base align=8 +QSpacerItem (0x0x7f58d4989d00) 0 + vptr=((& QSpacerItem::_ZTV11QSpacerItem) + 16u) + QLayoutItem (0x0x7f58d49d66c0) 0 + primary-for QSpacerItem (0x0x7f58d4989d00) + +Vtable for QWidgetItem +QWidgetItem::_ZTV11QWidgetItem: 19u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QWidgetItem) +16 (int (*)(...))QWidgetItem::~QWidgetItem +24 (int (*)(...))QWidgetItem::~QWidgetItem +32 (int (*)(...))QWidgetItem::sizeHint +40 (int (*)(...))QWidgetItem::minimumSize +48 (int (*)(...))QWidgetItem::maximumSize +56 (int (*)(...))QWidgetItem::expandingDirections +64 (int (*)(...))QWidgetItem::setGeometry +72 (int (*)(...))QWidgetItem::geometry +80 (int (*)(...))QWidgetItem::isEmpty +88 (int (*)(...))QWidgetItem::hasHeightForWidth +96 (int (*)(...))QWidgetItem::heightForWidth +104 (int (*)(...))QLayoutItem::minimumHeightForWidth +112 (int (*)(...))QLayoutItem::invalidate +120 (int (*)(...))QWidgetItem::widget +128 (int (*)(...))QLayoutItem::layout +136 (int (*)(...))QLayoutItem::spacerItem +144 (int (*)(...))QWidgetItem::controlTypes + +Class QWidgetItem + size=24 align=8 + base size=24 base align=8 +QWidgetItem (0x0x7f58d4989d68) 0 + vptr=((& QWidgetItem::_ZTV11QWidgetItem) + 16u) + QLayoutItem (0x0x7f58d49d6720) 0 + primary-for QWidgetItem (0x0x7f58d4989d68) + +Vtable for QWidgetItemV2 +QWidgetItemV2::_ZTV13QWidgetItemV2: 19u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QWidgetItemV2) +16 (int (*)(...))QWidgetItemV2::~QWidgetItemV2 +24 (int (*)(...))QWidgetItemV2::~QWidgetItemV2 +32 (int (*)(...))QWidgetItemV2::sizeHint +40 (int (*)(...))QWidgetItemV2::minimumSize +48 (int (*)(...))QWidgetItemV2::maximumSize +56 (int (*)(...))QWidgetItem::expandingDirections +64 (int (*)(...))QWidgetItem::setGeometry +72 (int (*)(...))QWidgetItem::geometry +80 (int (*)(...))QWidgetItem::isEmpty +88 (int (*)(...))QWidgetItem::hasHeightForWidth +96 (int (*)(...))QWidgetItemV2::heightForWidth +104 (int (*)(...))QLayoutItem::minimumHeightForWidth +112 (int (*)(...))QLayoutItem::invalidate +120 (int (*)(...))QWidgetItem::widget +128 (int (*)(...))QLayoutItem::layout +136 (int (*)(...))QLayoutItem::spacerItem +144 (int (*)(...))QWidgetItem::controlTypes + +Class QWidgetItemV2 + size=88 align=8 + base size=88 base align=8 +QWidgetItemV2 (0x0x7f58d4989dd0) 0 + vptr=((& QWidgetItemV2::_ZTV13QWidgetItemV2) + 16u) + QWidgetItem (0x0x7f58d4989e38) 0 + primary-for QWidgetItemV2 (0x0x7f58d4989dd0) + QLayoutItem (0x0x7f58d49d6780) 0 + primary-for QWidgetItem (0x0x7f58d4989e38) + +Class QLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLayout::QPrivateSignal (0x0x7f58d49d68a0) 0 empty + +Vtable for QLayout +QLayout::_ZTV7QLayout: 47u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QLayout) +16 (int (*)(...))QLayout::metaObject +24 (int (*)(...))QLayout::qt_metacast +32 (int (*)(...))QLayout::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLayout::invalidate +120 (int (*)(...))QLayout::geometry +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))QLayout::expandingDirections +144 (int (*)(...))QLayout::minimumSize +152 (int (*)(...))QLayout::maximumSize +160 (int (*)(...))QLayout::setGeometry +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))QLayout::indexOf +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))QLayout::isEmpty +208 (int (*)(...))QLayout::controlTypes +216 (int (*)(...))QLayout::layout +224 (int (*)(...))-16 +232 (int (*)(...))(& _ZTI7QLayout) +240 0u +248 0u +256 (int (*)(...))__cxa_pure_virtual +264 (int (*)(...))QLayout::_ZThn16_NK7QLayout11minimumSizeEv +272 (int (*)(...))QLayout::_ZThn16_NK7QLayout11maximumSizeEv +280 (int (*)(...))QLayout::_ZThn16_NK7QLayout19expandingDirectionsEv +288 (int (*)(...))QLayout::_ZThn16_N7QLayout11setGeometryERK5QRect +296 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +304 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +312 (int (*)(...))QLayoutItem::hasHeightForWidth +320 (int (*)(...))QLayoutItem::heightForWidth +328 (int (*)(...))QLayoutItem::minimumHeightForWidth +336 (int (*)(...))QLayout::_ZThn16_N7QLayout10invalidateEv +344 (int (*)(...))QLayoutItem::widget +352 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +360 (int (*)(...))QLayoutItem::spacerItem +368 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QLayout + size=32 align=8 + base size=28 base align=8 +QLayout (0x0x7f58d4ae9850) 0 + vptr=((& QLayout::_ZTV7QLayout) + 16u) + QObject (0x0x7f58d49d67e0) 0 + primary-for QLayout (0x0x7f58d4ae9850) + QLayoutItem (0x0x7f58d49d6840) 16 + vptr=((& QLayout::_ZTV7QLayout) + 240u) + +Class QGridLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGridLayout::QPrivateSignal (0x0x7f58d49d69c0) 0 empty + +Vtable for QGridLayout +QGridLayout::_ZTV11QGridLayout: 51u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QGridLayout) +16 (int (*)(...))QGridLayout::metaObject +24 (int (*)(...))QGridLayout::qt_metacast +32 (int (*)(...))QGridLayout::qt_metacall +40 (int (*)(...))QGridLayout::~QGridLayout +48 (int (*)(...))QGridLayout::~QGridLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGridLayout::invalidate +120 (int (*)(...))QLayout::geometry +128 (int (*)(...))QGridLayout::addItem +136 (int (*)(...))QGridLayout::expandingDirections +144 (int (*)(...))QGridLayout::minimumSize +152 (int (*)(...))QGridLayout::maximumSize +160 (int (*)(...))QGridLayout::setGeometry +168 (int (*)(...))QGridLayout::itemAt +176 (int (*)(...))QGridLayout::takeAt +184 (int (*)(...))QLayout::indexOf +192 (int (*)(...))QGridLayout::count +200 (int (*)(...))QLayout::isEmpty +208 (int (*)(...))QLayout::controlTypes +216 (int (*)(...))QLayout::layout +224 (int (*)(...))QGridLayout::sizeHint +232 (int (*)(...))QGridLayout::hasHeightForWidth +240 (int (*)(...))QGridLayout::heightForWidth +248 (int (*)(...))QGridLayout::minimumHeightForWidth +256 (int (*)(...))-16 +264 (int (*)(...))(& _ZTI11QGridLayout) +272 (int (*)(...))QGridLayout::_ZThn16_N11QGridLayoutD1Ev +280 (int (*)(...))QGridLayout::_ZThn16_N11QGridLayoutD0Ev +288 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout8sizeHintEv +296 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout11minimumSizeEv +304 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout11maximumSizeEv +312 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout19expandingDirectionsEv +320 (int (*)(...))QGridLayout::_ZThn16_N11QGridLayout11setGeometryERK5QRect +328 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +336 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +344 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout17hasHeightForWidthEv +352 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout14heightForWidthEi +360 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout21minimumHeightForWidthEi +368 (int (*)(...))QGridLayout::_ZThn16_N11QGridLayout10invalidateEv +376 (int (*)(...))QLayoutItem::widget +384 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +392 (int (*)(...))QLayoutItem::spacerItem +400 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QGridLayout + size=32 align=8 + base size=28 base align=8 +QGridLayout (0x0x7f58d4989ea0) 0 + vptr=((& QGridLayout::_ZTV11QGridLayout) + 16u) + QLayout (0x0x7f58d472a070) 0 + primary-for QGridLayout (0x0x7f58d4989ea0) + QObject (0x0x7f58d49d6900) 0 + primary-for QLayout (0x0x7f58d472a070) + QLayoutItem (0x0x7f58d49d6960) 16 + vptr=((& QGridLayout::_ZTV11QGridLayout) + 272u) + +Class QBoxLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBoxLayout::QPrivateSignal (0x0x7f58d49d6ae0) 0 empty + +Vtable for QBoxLayout +QBoxLayout::_ZTV10QBoxLayout: 51u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QBoxLayout) +16 (int (*)(...))QBoxLayout::metaObject +24 (int (*)(...))QBoxLayout::qt_metacast +32 (int (*)(...))QBoxLayout::qt_metacall +40 (int (*)(...))QBoxLayout::~QBoxLayout +48 (int (*)(...))QBoxLayout::~QBoxLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QBoxLayout::invalidate +120 (int (*)(...))QLayout::geometry +128 (int (*)(...))QBoxLayout::addItem +136 (int (*)(...))QBoxLayout::expandingDirections +144 (int (*)(...))QBoxLayout::minimumSize +152 (int (*)(...))QBoxLayout::maximumSize +160 (int (*)(...))QBoxLayout::setGeometry +168 (int (*)(...))QBoxLayout::itemAt +176 (int (*)(...))QBoxLayout::takeAt +184 (int (*)(...))QLayout::indexOf +192 (int (*)(...))QBoxLayout::count +200 (int (*)(...))QLayout::isEmpty +208 (int (*)(...))QLayout::controlTypes +216 (int (*)(...))QLayout::layout +224 (int (*)(...))QBoxLayout::sizeHint +232 (int (*)(...))QBoxLayout::hasHeightForWidth +240 (int (*)(...))QBoxLayout::heightForWidth +248 (int (*)(...))QBoxLayout::minimumHeightForWidth +256 (int (*)(...))-16 +264 (int (*)(...))(& _ZTI10QBoxLayout) +272 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayoutD1Ev +280 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayoutD0Ev +288 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout8sizeHintEv +296 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11minimumSizeEv +304 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11maximumSizeEv +312 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout19expandingDirectionsEv +320 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout11setGeometryERK5QRect +328 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +336 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +344 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout17hasHeightForWidthEv +352 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout14heightForWidthEi +360 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout21minimumHeightForWidthEi +368 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout10invalidateEv +376 (int (*)(...))QLayoutItem::widget +384 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +392 (int (*)(...))QLayoutItem::spacerItem +400 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QBoxLayout + size=32 align=8 + base size=28 base align=8 +QBoxLayout (0x0x7f58d4989f08) 0 + vptr=((& QBoxLayout::_ZTV10QBoxLayout) + 16u) + QLayout (0x0x7f58d472a620) 0 + primary-for QBoxLayout (0x0x7f58d4989f08) + QObject (0x0x7f58d49d6a20) 0 + primary-for QLayout (0x0x7f58d472a620) + QLayoutItem (0x0x7f58d49d6a80) 16 + vptr=((& QBoxLayout::_ZTV10QBoxLayout) + 272u) + +Class QHBoxLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHBoxLayout::QPrivateSignal (0x0x7f58d49d6c00) 0 empty + +Vtable for QHBoxLayout +QHBoxLayout::_ZTV11QHBoxLayout: 51u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QHBoxLayout) +16 (int (*)(...))QHBoxLayout::metaObject +24 (int (*)(...))QHBoxLayout::qt_metacast +32 (int (*)(...))QHBoxLayout::qt_metacall +40 (int (*)(...))QHBoxLayout::~QHBoxLayout +48 (int (*)(...))QHBoxLayout::~QHBoxLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QBoxLayout::invalidate +120 (int (*)(...))QLayout::geometry +128 (int (*)(...))QBoxLayout::addItem +136 (int (*)(...))QBoxLayout::expandingDirections +144 (int (*)(...))QBoxLayout::minimumSize +152 (int (*)(...))QBoxLayout::maximumSize +160 (int (*)(...))QBoxLayout::setGeometry +168 (int (*)(...))QBoxLayout::itemAt +176 (int (*)(...))QBoxLayout::takeAt +184 (int (*)(...))QLayout::indexOf +192 (int (*)(...))QBoxLayout::count +200 (int (*)(...))QLayout::isEmpty +208 (int (*)(...))QLayout::controlTypes +216 (int (*)(...))QLayout::layout +224 (int (*)(...))QBoxLayout::sizeHint +232 (int (*)(...))QBoxLayout::hasHeightForWidth +240 (int (*)(...))QBoxLayout::heightForWidth +248 (int (*)(...))QBoxLayout::minimumHeightForWidth +256 (int (*)(...))-16 +264 (int (*)(...))(& _ZTI11QHBoxLayout) +272 (int (*)(...))QHBoxLayout::_ZThn16_N11QHBoxLayoutD1Ev +280 (int (*)(...))QHBoxLayout::_ZThn16_N11QHBoxLayoutD0Ev +288 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout8sizeHintEv +296 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11minimumSizeEv +304 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11maximumSizeEv +312 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout19expandingDirectionsEv +320 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout11setGeometryERK5QRect +328 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +336 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +344 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout17hasHeightForWidthEv +352 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout14heightForWidthEi +360 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout21minimumHeightForWidthEi +368 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout10invalidateEv +376 (int (*)(...))QLayoutItem::widget +384 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +392 (int (*)(...))QLayoutItem::spacerItem +400 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QHBoxLayout + size=32 align=8 + base size=28 base align=8 +QHBoxLayout (0x0x7f58d476a000) 0 + vptr=((& QHBoxLayout::_ZTV11QHBoxLayout) + 16u) + QBoxLayout (0x0x7f58d476a068) 0 + primary-for QHBoxLayout (0x0x7f58d476a000) + QLayout (0x0x7f58d472acb0) 0 + primary-for QBoxLayout (0x0x7f58d476a068) + QObject (0x0x7f58d49d6b40) 0 + primary-for QLayout (0x0x7f58d472acb0) + QLayoutItem (0x0x7f58d49d6ba0) 16 + vptr=((& QHBoxLayout::_ZTV11QHBoxLayout) + 272u) + +Class QVBoxLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVBoxLayout::QPrivateSignal (0x0x7f58d49d6d20) 0 empty + +Vtable for QVBoxLayout +QVBoxLayout::_ZTV11QVBoxLayout: 51u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QVBoxLayout) +16 (int (*)(...))QVBoxLayout::metaObject +24 (int (*)(...))QVBoxLayout::qt_metacast +32 (int (*)(...))QVBoxLayout::qt_metacall +40 (int (*)(...))QVBoxLayout::~QVBoxLayout +48 (int (*)(...))QVBoxLayout::~QVBoxLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QBoxLayout::invalidate +120 (int (*)(...))QLayout::geometry +128 (int (*)(...))QBoxLayout::addItem +136 (int (*)(...))QBoxLayout::expandingDirections +144 (int (*)(...))QBoxLayout::minimumSize +152 (int (*)(...))QBoxLayout::maximumSize +160 (int (*)(...))QBoxLayout::setGeometry +168 (int (*)(...))QBoxLayout::itemAt +176 (int (*)(...))QBoxLayout::takeAt +184 (int (*)(...))QLayout::indexOf +192 (int (*)(...))QBoxLayout::count +200 (int (*)(...))QLayout::isEmpty +208 (int (*)(...))QLayout::controlTypes +216 (int (*)(...))QLayout::layout +224 (int (*)(...))QBoxLayout::sizeHint +232 (int (*)(...))QBoxLayout::hasHeightForWidth +240 (int (*)(...))QBoxLayout::heightForWidth +248 (int (*)(...))QBoxLayout::minimumHeightForWidth +256 (int (*)(...))-16 +264 (int (*)(...))(& _ZTI11QVBoxLayout) +272 (int (*)(...))QVBoxLayout::_ZThn16_N11QVBoxLayoutD1Ev +280 (int (*)(...))QVBoxLayout::_ZThn16_N11QVBoxLayoutD0Ev +288 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout8sizeHintEv +296 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11minimumSizeEv +304 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11maximumSizeEv +312 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout19expandingDirectionsEv +320 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout11setGeometryERK5QRect +328 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +336 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +344 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout17hasHeightForWidthEv +352 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout14heightForWidthEi +360 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout21minimumHeightForWidthEi +368 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout10invalidateEv +376 (int (*)(...))QLayoutItem::widget +384 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +392 (int (*)(...))QLayoutItem::spacerItem +400 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QVBoxLayout + size=32 align=8 + base size=28 base align=8 +QVBoxLayout (0x0x7f58d476a0d0) 0 + vptr=((& QVBoxLayout::_ZTV11QVBoxLayout) + 16u) + QBoxLayout (0x0x7f58d476a138) 0 + primary-for QVBoxLayout (0x0x7f58d476a0d0) + QLayout (0x0x7f58d472aee0) 0 + primary-for QBoxLayout (0x0x7f58d476a138) + QObject (0x0x7f58d49d6c60) 0 + primary-for QLayout (0x0x7f58d472aee0) + QLayoutItem (0x0x7f58d49d6cc0) 16 + vptr=((& QVBoxLayout::_ZTV11QVBoxLayout) + 272u) + +Class QButtonGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QButtonGroup::QPrivateSignal (0x0x7f58d49d6de0) 0 empty + +Vtable for QButtonGroup +QButtonGroup::_ZTV12QButtonGroup: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QButtonGroup) +16 (int (*)(...))QButtonGroup::metaObject +24 (int (*)(...))QButtonGroup::qt_metacast +32 (int (*)(...))QButtonGroup::qt_metacall +40 (int (*)(...))QButtonGroup::~QButtonGroup +48 (int (*)(...))QButtonGroup::~QButtonGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QButtonGroup + size=16 align=8 + base size=16 base align=8 +QButtonGroup (0x0x7f58d476a1a0) 0 + vptr=((& QButtonGroup::_ZTV12QButtonGroup) + 16u) + QObject (0x0x7f58d49d6d80) 0 + primary-for QButtonGroup (0x0x7f58d476a1a0) + +Class QCalendarWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCalendarWidget::QPrivateSignal (0x0x7f58d49d6f00) 0 empty + +Vtable for QCalendarWidget +QCalendarWidget::_ZTV15QCalendarWidget: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QCalendarWidget) +16 (int (*)(...))QCalendarWidget::metaObject +24 (int (*)(...))QCalendarWidget::qt_metacast +32 (int (*)(...))QCalendarWidget::qt_metacall +40 (int (*)(...))QCalendarWidget::~QCalendarWidget +48 (int (*)(...))QCalendarWidget::~QCalendarWidget +56 (int (*)(...))QCalendarWidget::event +64 (int (*)(...))QCalendarWidget::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QCalendarWidget::sizeHint +136 (int (*)(...))QCalendarWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QCalendarWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QCalendarWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QCalendarWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QCalendarWidget::paintCell +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI15QCalendarWidget) +456 (int (*)(...))QCalendarWidget::_ZThn16_N15QCalendarWidgetD1Ev +464 (int (*)(...))QCalendarWidget::_ZThn16_N15QCalendarWidgetD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QCalendarWidget + size=48 align=8 + base size=48 base align=8 +QCalendarWidget (0x0x7f58d476a208) 0 + vptr=((& QCalendarWidget::_ZTV15QCalendarWidget) + 16u) + QWidget (0x0x7f58d47783f0) 0 + primary-for QCalendarWidget (0x0x7f58d476a208) + QObject (0x0x7f58d49d6e40) 0 + primary-for QWidget (0x0x7f58d47783f0) + QPaintDevice (0x0x7f58d49d6ea0) 16 + vptr=((& QCalendarWidget::_ZTV15QCalendarWidget) + 456u) + +Class QCheckBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCheckBox::QPrivateSignal (0x0x7f58d47bc060) 0 empty + +Vtable for QCheckBox +QCheckBox::_ZTV9QCheckBox: 67u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QCheckBox) +16 (int (*)(...))QCheckBox::metaObject +24 (int (*)(...))QCheckBox::qt_metacast +32 (int (*)(...))QCheckBox::qt_metacall +40 (int (*)(...))QCheckBox::~QCheckBox +48 (int (*)(...))QCheckBox::~QCheckBox +56 (int (*)(...))QCheckBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractButton::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QCheckBox::sizeHint +136 (int (*)(...))QCheckBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractButton::mousePressEvent +176 (int (*)(...))QAbstractButton::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QCheckBox::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QAbstractButton::keyPressEvent +216 (int (*)(...))QAbstractButton::keyReleaseEvent +224 (int (*)(...))QAbstractButton::focusInEvent +232 (int (*)(...))QAbstractButton::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QCheckBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractButton::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QCheckBox::hitButton +440 (int (*)(...))QCheckBox::checkStateSet +448 (int (*)(...))QCheckBox::nextCheckState +456 (int (*)(...))-16 +464 (int (*)(...))(& _ZTI9QCheckBox) +472 (int (*)(...))QCheckBox::_ZThn16_N9QCheckBoxD1Ev +480 (int (*)(...))QCheckBox::_ZThn16_N9QCheckBoxD0Ev +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QCheckBox + size=48 align=8 + base size=48 base align=8 +QCheckBox (0x0x7f58d476a270) 0 + vptr=((& QCheckBox::_ZTV9QCheckBox) + 16u) + QAbstractButton (0x0x7f58d476a2d8) 0 + primary-for QCheckBox (0x0x7f58d476a270) + QWidget (0x0x7f58d4778d20) 0 + primary-for QAbstractButton (0x0x7f58d476a2d8) + QObject (0x0x7f58d49d6f60) 0 + primary-for QWidget (0x0x7f58d4778d20) + QPaintDevice (0x0x7f58d47bc000) 16 + vptr=((& QCheckBox::_ZTV9QCheckBox) + 472u) + +Class QDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDialog::QPrivateSignal (0x0x7f58d47bc180) 0 empty + +Vtable for QDialog +QDialog::_ZTV7QDialog: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QDialog) +16 (int (*)(...))QDialog::metaObject +24 (int (*)(...))QDialog::qt_metacast +32 (int (*)(...))QDialog::qt_metacall +40 (int (*)(...))QDialog::~QDialog +48 (int (*)(...))QDialog::~QDialog +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QDialog::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI7QDialog) +488 (int (*)(...))QDialog::_ZThn16_N7QDialogD1Ev +496 (int (*)(...))QDialog::_ZThn16_N7QDialogD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDialog + size=48 align=8 + base size=48 base align=8 +QDialog (0x0x7f58d476a340) 0 + vptr=((& QDialog::_ZTV7QDialog) + 16u) + QWidget (0x0x7f58d47d1070) 0 + primary-for QDialog (0x0x7f58d476a340) + QObject (0x0x7f58d47bc0c0) 0 + primary-for QWidget (0x0x7f58d47d1070) + QPaintDevice (0x0x7f58d47bc120) 16 + vptr=((& QDialog::_ZTV7QDialog) + 488u) + +Class QColorDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QColorDialog::QPrivateSignal (0x0x7f58d47bc2a0) 0 empty + +Vtable for QColorDialog +QColorDialog::_ZTV12QColorDialog: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QColorDialog) +16 (int (*)(...))QColorDialog::metaObject +24 (int (*)(...))QColorDialog::qt_metacast +32 (int (*)(...))QColorDialog::qt_metacall +40 (int (*)(...))QColorDialog::~QColorDialog +48 (int (*)(...))QColorDialog::~QColorDialog +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QColorDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QColorDialog::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QColorDialog::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI12QColorDialog) +488 (int (*)(...))QColorDialog::_ZThn16_N12QColorDialogD1Ev +496 (int (*)(...))QColorDialog::_ZThn16_N12QColorDialogD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QColorDialog + size=48 align=8 + base size=48 base align=8 +QColorDialog (0x0x7f58d476a3a8) 0 + vptr=((& QColorDialog::_ZTV12QColorDialog) + 16u) + QDialog (0x0x7f58d476a410) 0 + primary-for QColorDialog (0x0x7f58d476a3a8) + QWidget (0x0x7f58d47d1540) 0 + primary-for QDialog (0x0x7f58d476a410) + QObject (0x0x7f58d47bc1e0) 0 + primary-for QWidget (0x0x7f58d47d1540) + QPaintDevice (0x0x7f58d47bc240) 16 + vptr=((& QColorDialog::_ZTV12QColorDialog) + 488u) + +Class QColormap + size=8 align=8 + base size=8 base align=8 +QColormap (0x0x7f58d47bc4e0) 0 + +Class QColumnView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QColumnView::QPrivateSignal (0x0x7f58d47bc600) 0 empty + +Vtable for QColumnView +QColumnView::_ZTV11QColumnView: 107u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QColumnView) +16 (int (*)(...))QColumnView::metaObject +24 (int (*)(...))QColumnView::qt_metacast +32 (int (*)(...))QColumnView::qt_metacall +40 (int (*)(...))QColumnView::~QColumnView +48 (int (*)(...))QColumnView::~QColumnView +56 (int (*)(...))QAbstractItemView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QAbstractItemView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QColumnView::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QAbstractItemView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QAbstractItemView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractScrollArea::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QColumnView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QAbstractItemView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QAbstractItemView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractItemView::viewportEvent +448 (int (*)(...))QColumnView::scrollContentsBy +456 (int (*)(...))QAbstractItemView::viewportSizeHint +464 (int (*)(...))QColumnView::setModel +472 (int (*)(...))QColumnView::setSelectionModel +480 (int (*)(...))QAbstractItemView::keyboardSearch +488 (int (*)(...))QColumnView::visualRect +496 (int (*)(...))QColumnView::scrollTo +504 (int (*)(...))QColumnView::indexAt +512 (int (*)(...))QAbstractItemView::sizeHintForRow +520 (int (*)(...))QAbstractItemView::sizeHintForColumn +528 (int (*)(...))QAbstractItemView::reset +536 (int (*)(...))QColumnView::setRootIndex +544 (int (*)(...))QAbstractItemView::doItemsLayout +552 (int (*)(...))QColumnView::selectAll +560 (int (*)(...))QAbstractItemView::dataChanged +568 (int (*)(...))QColumnView::rowsInserted +576 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved +584 (int (*)(...))QAbstractItemView::selectionChanged +592 (int (*)(...))QColumnView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QAbstractItemView::updateGeometries +624 (int (*)(...))QAbstractItemView::verticalScrollbarAction +632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction +640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))QColumnView::moveCursor +688 (int (*)(...))QColumnView::horizontalOffset +696 (int (*)(...))QColumnView::verticalOffset +704 (int (*)(...))QColumnView::isIndexHidden +712 (int (*)(...))QColumnView::setSelection +720 (int (*)(...))QColumnView::visualRegionForSelection +728 (int (*)(...))QAbstractItemView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QAbstractItemView::startDrag +760 (int (*)(...))QAbstractItemView::viewOptions +768 (int (*)(...))QColumnView::createColumn +776 (int (*)(...))-16 +784 (int (*)(...))(& _ZTI11QColumnView) +792 (int (*)(...))QColumnView::_ZThn16_N11QColumnViewD1Ev +800 (int (*)(...))QColumnView::_ZThn16_N11QColumnViewD0Ev +808 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +816 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +824 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +848 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QColumnView + size=48 align=8 + base size=48 base align=8 +QColumnView (0x0x7f58d476a548) 0 + vptr=((& QColumnView::_ZTV11QColumnView) + 16u) + QAbstractItemView (0x0x7f58d476a5b0) 0 + primary-for QColumnView (0x0x7f58d476a548) + QAbstractScrollArea (0x0x7f58d476a618) 0 + primary-for QAbstractItemView (0x0x7f58d476a5b0) + QFrame (0x0x7f58d476a680) 0 + primary-for QAbstractScrollArea (0x0x7f58d476a618) + QWidget (0x0x7f58d481d9a0) 0 + primary-for QFrame (0x0x7f58d476a680) + QObject (0x0x7f58d47bc540) 0 + primary-for QWidget (0x0x7f58d481d9a0) + QPaintDevice (0x0x7f58d47bc5a0) 16 + vptr=((& QColumnView::_ZTV11QColumnView) + 792u) + +Class QComboBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QComboBox::QPrivateSignal (0x0x7f58d47bc720) 0 empty + +Vtable for QComboBox +QComboBox::_ZTV9QComboBox: 66u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QComboBox) +16 (int (*)(...))QComboBox::metaObject +24 (int (*)(...))QComboBox::qt_metacast +32 (int (*)(...))QComboBox::qt_metacall +40 (int (*)(...))QComboBox::~QComboBox +48 (int (*)(...))QComboBox::~QComboBox +56 (int (*)(...))QComboBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QComboBox::sizeHint +136 (int (*)(...))QComboBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QComboBox::mousePressEvent +176 (int (*)(...))QComboBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QComboBox::wheelEvent +208 (int (*)(...))QComboBox::keyPressEvent +216 (int (*)(...))QComboBox::keyReleaseEvent +224 (int (*)(...))QComboBox::focusInEvent +232 (int (*)(...))QComboBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QComboBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QComboBox::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QComboBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QComboBox::showEvent +352 (int (*)(...))QComboBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QComboBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QComboBox::inputMethodEvent +416 (int (*)(...))QComboBox::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QComboBox::showPopup +440 (int (*)(...))QComboBox::hidePopup +448 (int (*)(...))-16 +456 (int (*)(...))(& _ZTI9QComboBox) +464 (int (*)(...))QComboBox::_ZThn16_N9QComboBoxD1Ev +472 (int (*)(...))QComboBox::_ZThn16_N9QComboBoxD0Ev +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QComboBox + size=48 align=8 + base size=48 base align=8 +QComboBox (0x0x7f58d476a6e8) 0 + vptr=((& QComboBox::_ZTV9QComboBox) + 16u) + QWidget (0x0x7f58d481dcb0) 0 + primary-for QComboBox (0x0x7f58d476a6e8) + QObject (0x0x7f58d47bc660) 0 + primary-for QWidget (0x0x7f58d481dcb0) + QPaintDevice (0x0x7f58d47bc6c0) 16 + vptr=((& QComboBox::_ZTV9QComboBox) + 464u) + +Class QPushButton::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPushButton::QPrivateSignal (0x0x7f58d47bc840) 0 empty + +Vtable for QPushButton +QPushButton::_ZTV11QPushButton: 67u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QPushButton) +16 (int (*)(...))QPushButton::metaObject +24 (int (*)(...))QPushButton::qt_metacast +32 (int (*)(...))QPushButton::qt_metacall +40 (int (*)(...))QPushButton::~QPushButton +48 (int (*)(...))QPushButton::~QPushButton +56 (int (*)(...))QPushButton::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractButton::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QPushButton::sizeHint +136 (int (*)(...))QPushButton::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractButton::mousePressEvent +176 (int (*)(...))QAbstractButton::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractButton::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QPushButton::keyPressEvent +216 (int (*)(...))QAbstractButton::keyReleaseEvent +224 (int (*)(...))QPushButton::focusInEvent +232 (int (*)(...))QPushButton::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QPushButton::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractButton::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QAbstractButton::hitButton +440 (int (*)(...))QAbstractButton::checkStateSet +448 (int (*)(...))QAbstractButton::nextCheckState +456 (int (*)(...))-16 +464 (int (*)(...))(& _ZTI11QPushButton) +472 (int (*)(...))QPushButton::_ZThn16_N11QPushButtonD1Ev +480 (int (*)(...))QPushButton::_ZThn16_N11QPushButtonD0Ev +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QPushButton + size=48 align=8 + base size=48 base align=8 +QPushButton (0x0x7f58d476a750) 0 + vptr=((& QPushButton::_ZTV11QPushButton) + 16u) + QAbstractButton (0x0x7f58d476a7b8) 0 + primary-for QPushButton (0x0x7f58d476a750) + QWidget (0x0x7f58d48678c0) 0 + primary-for QAbstractButton (0x0x7f58d476a7b8) + QObject (0x0x7f58d47bc780) 0 + primary-for QWidget (0x0x7f58d48678c0) + QPaintDevice (0x0x7f58d47bc7e0) 16 + vptr=((& QPushButton::_ZTV11QPushButton) + 472u) + +Class QCommandLinkButton::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCommandLinkButton::QPrivateSignal (0x0x7f58d47bc960) 0 empty + +Vtable for QCommandLinkButton +QCommandLinkButton::_ZTV18QCommandLinkButton: 67u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QCommandLinkButton) +16 (int (*)(...))QCommandLinkButton::metaObject +24 (int (*)(...))QCommandLinkButton::qt_metacast +32 (int (*)(...))QCommandLinkButton::qt_metacall +40 (int (*)(...))QCommandLinkButton::~QCommandLinkButton +48 (int (*)(...))QCommandLinkButton::~QCommandLinkButton +56 (int (*)(...))QCommandLinkButton::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractButton::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QCommandLinkButton::sizeHint +136 (int (*)(...))QCommandLinkButton::minimumSizeHint +144 (int (*)(...))QCommandLinkButton::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractButton::mousePressEvent +176 (int (*)(...))QAbstractButton::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractButton::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QPushButton::keyPressEvent +216 (int (*)(...))QAbstractButton::keyReleaseEvent +224 (int (*)(...))QPushButton::focusInEvent +232 (int (*)(...))QPushButton::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QCommandLinkButton::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractButton::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QAbstractButton::hitButton +440 (int (*)(...))QAbstractButton::checkStateSet +448 (int (*)(...))QAbstractButton::nextCheckState +456 (int (*)(...))-16 +464 (int (*)(...))(& _ZTI18QCommandLinkButton) +472 (int (*)(...))QCommandLinkButton::_ZThn16_N18QCommandLinkButtonD1Ev +480 (int (*)(...))QCommandLinkButton::_ZThn16_N18QCommandLinkButtonD0Ev +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QCommandLinkButton + size=48 align=8 + base size=48 base align=8 +QCommandLinkButton (0x0x7f58d476a820) 0 + vptr=((& QCommandLinkButton::_ZTV18QCommandLinkButton) + 16u) + QPushButton (0x0x7f58d476a888) 0 + primary-for QCommandLinkButton (0x0x7f58d476a820) + QAbstractButton (0x0x7f58d476a8f0) 0 + primary-for QPushButton (0x0x7f58d476a888) + QWidget (0x0x7f58d4867bd0) 0 + primary-for QAbstractButton (0x0x7f58d476a8f0) + QObject (0x0x7f58d47bc8a0) 0 + primary-for QWidget (0x0x7f58d4867bd0) + QPaintDevice (0x0x7f58d47bc900) 16 + vptr=((& QCommandLinkButton::_ZTV18QCommandLinkButton) + 472u) + +Class QCommonStyle::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCommonStyle::QPrivateSignal (0x0x7f58d47bca20) 0 empty + +Vtable for QCommonStyle +QCommonStyle::_ZTV12QCommonStyle: 37u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QCommonStyle) +16 (int (*)(...))QCommonStyle::metaObject +24 (int (*)(...))QCommonStyle::qt_metacast +32 (int (*)(...))QCommonStyle::qt_metacall +40 (int (*)(...))QCommonStyle::~QCommonStyle +48 (int (*)(...))QCommonStyle::~QCommonStyle +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCommonStyle::polish +120 (int (*)(...))QCommonStyle::unpolish +128 (int (*)(...))QCommonStyle::polish +136 (int (*)(...))QCommonStyle::unpolish +144 (int (*)(...))QCommonStyle::polish +152 (int (*)(...))QStyle::itemTextRect +160 (int (*)(...))QStyle::itemPixmapRect +168 (int (*)(...))QStyle::drawItemText +176 (int (*)(...))QStyle::drawItemPixmap +184 (int (*)(...))QStyle::standardPalette +192 (int (*)(...))QCommonStyle::drawPrimitive +200 (int (*)(...))QCommonStyle::drawControl +208 (int (*)(...))QCommonStyle::subElementRect +216 (int (*)(...))QCommonStyle::drawComplexControl +224 (int (*)(...))QCommonStyle::hitTestComplexControl +232 (int (*)(...))QCommonStyle::subControlRect +240 (int (*)(...))QCommonStyle::pixelMetric +248 (int (*)(...))QCommonStyle::sizeFromContents +256 (int (*)(...))QCommonStyle::styleHint +264 (int (*)(...))QCommonStyle::standardPixmap +272 (int (*)(...))QCommonStyle::standardIcon +280 (int (*)(...))QCommonStyle::generatedIconPixmap +288 (int (*)(...))QCommonStyle::layoutSpacing + +Class QCommonStyle + size=16 align=8 + base size=16 base align=8 +QCommonStyle (0x0x7f58d476a958) 0 + vptr=((& QCommonStyle::_ZTV12QCommonStyle) + 16u) + QStyle (0x0x7f58d476a9c0) 0 + primary-for QCommonStyle (0x0x7f58d476a958) + QObject (0x0x7f58d47bc9c0) 0 + primary-for QStyle (0x0x7f58d476a9c0) + +Class QCompleter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCompleter::QPrivateSignal (0x0x7f58d47bcae0) 0 empty + +Vtable for QCompleter +QCompleter::_ZTV10QCompleter: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QCompleter) +16 (int (*)(...))QCompleter::metaObject +24 (int (*)(...))QCompleter::qt_metacast +32 (int (*)(...))QCompleter::qt_metacall +40 (int (*)(...))QCompleter::~QCompleter +48 (int (*)(...))QCompleter::~QCompleter +56 (int (*)(...))QCompleter::event +64 (int (*)(...))QCompleter::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCompleter::pathFromIndex +120 (int (*)(...))QCompleter::splitPath + +Class QCompleter + size=16 align=8 + base size=16 base align=8 +QCompleter (0x0x7f58d476aa28) 0 + vptr=((& QCompleter::_ZTV10QCompleter) + 16u) + QObject (0x0x7f58d47bca80) 0 + primary-for QCompleter (0x0x7f58d476aa28) + +Class QDataWidgetMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDataWidgetMapper::QPrivateSignal (0x0x7f58d47bcba0) 0 empty + +Vtable for QDataWidgetMapper +QDataWidgetMapper::_ZTV17QDataWidgetMapper: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QDataWidgetMapper) +16 (int (*)(...))QDataWidgetMapper::metaObject +24 (int (*)(...))QDataWidgetMapper::qt_metacast +32 (int (*)(...))QDataWidgetMapper::qt_metacall +40 (int (*)(...))QDataWidgetMapper::~QDataWidgetMapper +48 (int (*)(...))QDataWidgetMapper::~QDataWidgetMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QDataWidgetMapper::setCurrentIndex + +Class QDataWidgetMapper + size=16 align=8 + base size=16 base align=8 +QDataWidgetMapper (0x0x7f58d476aa90) 0 + vptr=((& QDataWidgetMapper::_ZTV17QDataWidgetMapper) + 16u) + QObject (0x0x7f58d47bcb40) 0 + primary-for QDataWidgetMapper (0x0x7f58d476aa90) + +Class QDateTimeEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDateTimeEdit::QPrivateSignal (0x0x7f58d47bccc0) 0 empty + +Vtable for QDateTimeEdit +QDateTimeEdit::_ZTV13QDateTimeEdit: 71u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QDateTimeEdit) +16 (int (*)(...))QDateTimeEdit::metaObject +24 (int (*)(...))QDateTimeEdit::qt_metacast +32 (int (*)(...))QDateTimeEdit::qt_metacall +40 (int (*)(...))QDateTimeEdit::~QDateTimeEdit +48 (int (*)(...))QDateTimeEdit::~QDateTimeEdit +56 (int (*)(...))QDateTimeEdit::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSpinBox::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QDateTimeEdit::sizeHint +136 (int (*)(...))QAbstractSpinBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QDateTimeEdit::mousePressEvent +176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent +200 (int (*)(...))QDateTimeEdit::wheelEvent +208 (int (*)(...))QDateTimeEdit::keyPressEvent +216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent +224 (int (*)(...))QDateTimeEdit::focusInEvent +232 (int (*)(...))QAbstractSpinBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QDateTimeEdit::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractSpinBox::resizeEvent +280 (int (*)(...))QAbstractSpinBox::closeEvent +288 (int (*)(...))QAbstractSpinBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QAbstractSpinBox::showEvent +352 (int (*)(...))QAbstractSpinBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSpinBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QAbstractSpinBox::inputMethodQuery +424 (int (*)(...))QDateTimeEdit::focusNextPrevChild +432 (int (*)(...))QDateTimeEdit::validate +440 (int (*)(...))QDateTimeEdit::fixup +448 (int (*)(...))QDateTimeEdit::stepBy +456 (int (*)(...))QDateTimeEdit::clear +464 (int (*)(...))QDateTimeEdit::stepEnabled +472 (int (*)(...))QDateTimeEdit::dateTimeFromText +480 (int (*)(...))QDateTimeEdit::textFromDateTime +488 (int (*)(...))-16 +496 (int (*)(...))(& _ZTI13QDateTimeEdit) +504 (int (*)(...))QDateTimeEdit::_ZThn16_N13QDateTimeEditD1Ev +512 (int (*)(...))QDateTimeEdit::_ZThn16_N13QDateTimeEditD0Ev +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDateTimeEdit + size=48 align=8 + base size=48 base align=8 +QDateTimeEdit (0x0x7f58d476aaf8) 0 + vptr=((& QDateTimeEdit::_ZTV13QDateTimeEdit) + 16u) + QAbstractSpinBox (0x0x7f58d476ab60) 0 + primary-for QDateTimeEdit (0x0x7f58d476aaf8) + QWidget (0x0x7f58d48d8bd0) 0 + primary-for QAbstractSpinBox (0x0x7f58d476ab60) + QObject (0x0x7f58d47bcc00) 0 + primary-for QWidget (0x0x7f58d48d8bd0) + QPaintDevice (0x0x7f58d47bcc60) 16 + vptr=((& QDateTimeEdit::_ZTV13QDateTimeEdit) + 504u) + +Class QTimeEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeEdit::QPrivateSignal (0x0x7f58d47bcf60) 0 empty + +Vtable for QTimeEdit +QTimeEdit::_ZTV9QTimeEdit: 71u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeEdit) +16 (int (*)(...))QTimeEdit::metaObject +24 (int (*)(...))QTimeEdit::qt_metacast +32 (int (*)(...))QTimeEdit::qt_metacall +40 (int (*)(...))QTimeEdit::~QTimeEdit +48 (int (*)(...))QTimeEdit::~QTimeEdit +56 (int (*)(...))QDateTimeEdit::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSpinBox::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QDateTimeEdit::sizeHint +136 (int (*)(...))QAbstractSpinBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QDateTimeEdit::mousePressEvent +176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent +200 (int (*)(...))QDateTimeEdit::wheelEvent +208 (int (*)(...))QDateTimeEdit::keyPressEvent +216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent +224 (int (*)(...))QDateTimeEdit::focusInEvent +232 (int (*)(...))QAbstractSpinBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QDateTimeEdit::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractSpinBox::resizeEvent +280 (int (*)(...))QAbstractSpinBox::closeEvent +288 (int (*)(...))QAbstractSpinBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QAbstractSpinBox::showEvent +352 (int (*)(...))QAbstractSpinBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSpinBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QAbstractSpinBox::inputMethodQuery +424 (int (*)(...))QDateTimeEdit::focusNextPrevChild +432 (int (*)(...))QDateTimeEdit::validate +440 (int (*)(...))QDateTimeEdit::fixup +448 (int (*)(...))QDateTimeEdit::stepBy +456 (int (*)(...))QDateTimeEdit::clear +464 (int (*)(...))QDateTimeEdit::stepEnabled +472 (int (*)(...))QDateTimeEdit::dateTimeFromText +480 (int (*)(...))QDateTimeEdit::textFromDateTime +488 (int (*)(...))-16 +496 (int (*)(...))(& _ZTI9QTimeEdit) +504 (int (*)(...))QTimeEdit::_ZThn16_N9QTimeEditD1Ev +512 (int (*)(...))QTimeEdit::_ZThn16_N9QTimeEditD0Ev +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTimeEdit + size=48 align=8 + base size=48 base align=8 +QTimeEdit (0x0x7f58d476ac98) 0 + vptr=((& QTimeEdit::_ZTV9QTimeEdit) + 16u) + QDateTimeEdit (0x0x7f58d476ad00) 0 + primary-for QTimeEdit (0x0x7f58d476ac98) + QAbstractSpinBox (0x0x7f58d476ad68) 0 + primary-for QDateTimeEdit (0x0x7f58d476ad00) + QWidget (0x0x7f58d4910770) 0 + primary-for QAbstractSpinBox (0x0x7f58d476ad68) + QObject (0x0x7f58d47bcea0) 0 + primary-for QWidget (0x0x7f58d4910770) + QPaintDevice (0x0x7f58d47bcf00) 16 + vptr=((& QTimeEdit::_ZTV9QTimeEdit) + 504u) + +Class QDateEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDateEdit::QPrivateSignal (0x0x7f58d455b0c0) 0 empty + +Vtable for QDateEdit +QDateEdit::_ZTV9QDateEdit: 71u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QDateEdit) +16 (int (*)(...))QDateEdit::metaObject +24 (int (*)(...))QDateEdit::qt_metacast +32 (int (*)(...))QDateEdit::qt_metacall +40 (int (*)(...))QDateEdit::~QDateEdit +48 (int (*)(...))QDateEdit::~QDateEdit +56 (int (*)(...))QDateTimeEdit::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSpinBox::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QDateTimeEdit::sizeHint +136 (int (*)(...))QAbstractSpinBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QDateTimeEdit::mousePressEvent +176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent +200 (int (*)(...))QDateTimeEdit::wheelEvent +208 (int (*)(...))QDateTimeEdit::keyPressEvent +216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent +224 (int (*)(...))QDateTimeEdit::focusInEvent +232 (int (*)(...))QAbstractSpinBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QDateTimeEdit::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractSpinBox::resizeEvent +280 (int (*)(...))QAbstractSpinBox::closeEvent +288 (int (*)(...))QAbstractSpinBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QAbstractSpinBox::showEvent +352 (int (*)(...))QAbstractSpinBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSpinBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QAbstractSpinBox::inputMethodQuery +424 (int (*)(...))QDateTimeEdit::focusNextPrevChild +432 (int (*)(...))QDateTimeEdit::validate +440 (int (*)(...))QDateTimeEdit::fixup +448 (int (*)(...))QDateTimeEdit::stepBy +456 (int (*)(...))QDateTimeEdit::clear +464 (int (*)(...))QDateTimeEdit::stepEnabled +472 (int (*)(...))QDateTimeEdit::dateTimeFromText +480 (int (*)(...))QDateTimeEdit::textFromDateTime +488 (int (*)(...))-16 +496 (int (*)(...))(& _ZTI9QDateEdit) +504 (int (*)(...))QDateEdit::_ZThn16_N9QDateEditD1Ev +512 (int (*)(...))QDateEdit::_ZThn16_N9QDateEditD0Ev +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDateEdit + size=48 align=8 + base size=48 base align=8 +QDateEdit (0x0x7f58d476add0) 0 + vptr=((& QDateEdit::_ZTV9QDateEdit) + 16u) + QDateTimeEdit (0x0x7f58d476ae38) 0 + primary-for QDateEdit (0x0x7f58d476add0) + QAbstractSpinBox (0x0x7f58d476aea0) 0 + primary-for QDateTimeEdit (0x0x7f58d476ae38) + QWidget (0x0x7f58d49109a0) 0 + primary-for QAbstractSpinBox (0x0x7f58d476aea0) + QObject (0x0x7f58d455b000) 0 + primary-for QWidget (0x0x7f58d49109a0) + QPaintDevice (0x0x7f58d455b060) 16 + vptr=((& QDateEdit::_ZTV9QDateEdit) + 504u) + +Class QDesktopWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDesktopWidget::QPrivateSignal (0x0x7f58d455b1e0) 0 empty + +Vtable for QDesktopWidget +QDesktopWidget::_ZTV14QDesktopWidget: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QDesktopWidget) +16 (int (*)(...))QDesktopWidget::metaObject +24 (int (*)(...))QDesktopWidget::qt_metacast +32 (int (*)(...))QDesktopWidget::qt_metacall +40 (int (*)(...))QDesktopWidget::~QDesktopWidget +48 (int (*)(...))QDesktopWidget::~QDesktopWidget +56 (int (*)(...))QWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDesktopWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI14QDesktopWidget) +448 (int (*)(...))QDesktopWidget::_ZThn16_N14QDesktopWidgetD1Ev +456 (int (*)(...))QDesktopWidget::_ZThn16_N14QDesktopWidgetD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDesktopWidget + size=48 align=8 + base size=48 base align=8 +QDesktopWidget (0x0x7f58d476af08) 0 + vptr=((& QDesktopWidget::_ZTV14QDesktopWidget) + 16u) + QWidget (0x0x7f58d45733f0) 0 + primary-for QDesktopWidget (0x0x7f58d476af08) + QObject (0x0x7f58d455b120) 0 + primary-for QWidget (0x0x7f58d45733f0) + QPaintDevice (0x0x7f58d455b180) 16 + vptr=((& QDesktopWidget::_ZTV14QDesktopWidget) + 448u) + +Class QDial::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDial::QPrivateSignal (0x0x7f58d455b300) 0 empty + +Vtable for QDial +QDial::_ZTV5QDial: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QDial) +16 (int (*)(...))QDial::metaObject +24 (int (*)(...))QDial::qt_metacast +32 (int (*)(...))QDial::qt_metacall +40 (int (*)(...))QDial::~QDial +48 (int (*)(...))QDial::~QDial +56 (int (*)(...))QDial::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSlider::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QDial::sizeHint +136 (int (*)(...))QDial::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QDial::mousePressEvent +176 (int (*)(...))QDial::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QDial::mouseMoveEvent +200 (int (*)(...))QAbstractSlider::wheelEvent +208 (int (*)(...))QAbstractSlider::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QDial::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDial::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSlider::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDial::sliderChange +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI5QDial) +456 (int (*)(...))QDial::_ZThn16_N5QDialD1Ev +464 (int (*)(...))QDial::_ZThn16_N5QDialD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDial + size=48 align=8 + base size=48 base align=8 +QDial (0x0x7f58d476af70) 0 + vptr=((& QDial::_ZTV5QDial) + 16u) + QAbstractSlider (0x0x7f58d459d000) 0 + primary-for QDial (0x0x7f58d476af70) + QWidget (0x0x7f58d4573850) 0 + primary-for QAbstractSlider (0x0x7f58d459d000) + QObject (0x0x7f58d455b240) 0 + primary-for QWidget (0x0x7f58d4573850) + QPaintDevice (0x0x7f58d455b2a0) 16 + vptr=((& QDial::_ZTV5QDial) + 456u) + +Class QDialogButtonBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDialogButtonBox::QPrivateSignal (0x0x7f58d455b420) 0 empty + +Vtable for QDialogButtonBox +QDialogButtonBox::_ZTV16QDialogButtonBox: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QDialogButtonBox) +16 (int (*)(...))QDialogButtonBox::metaObject +24 (int (*)(...))QDialogButtonBox::qt_metacast +32 (int (*)(...))QDialogButtonBox::qt_metacall +40 (int (*)(...))QDialogButtonBox::~QDialogButtonBox +48 (int (*)(...))QDialogButtonBox::~QDialogButtonBox +56 (int (*)(...))QDialogButtonBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QDialogButtonBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI16QDialogButtonBox) +448 (int (*)(...))QDialogButtonBox::_ZThn16_N16QDialogButtonBoxD1Ev +456 (int (*)(...))QDialogButtonBox::_ZThn16_N16QDialogButtonBoxD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDialogButtonBox + size=48 align=8 + base size=48 base align=8 +QDialogButtonBox (0x0x7f58d459d068) 0 + vptr=((& QDialogButtonBox::_ZTV16QDialogButtonBox) + 16u) + QWidget (0x0x7f58d4573b60) 0 + primary-for QDialogButtonBox (0x0x7f58d459d068) + QObject (0x0x7f58d455b360) 0 + primary-for QWidget (0x0x7f58d4573b60) + QPaintDevice (0x0x7f58d455b3c0) 16 + vptr=((& QDialogButtonBox::_ZTV16QDialogButtonBox) + 448u) + +Vtable for QFileIconProvider +QFileIconProvider::_ZTV17QFileIconProvider: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFileIconProvider) +16 (int (*)(...))QFileIconProvider::~QFileIconProvider +24 (int (*)(...))QFileIconProvider::~QFileIconProvider +32 (int (*)(...))QFileIconProvider::icon +40 (int (*)(...))QFileIconProvider::icon +48 (int (*)(...))QFileIconProvider::type + +Class QFileIconProvider + size=16 align=8 + base size=16 base align=8 +QFileIconProvider (0x0x7f58d455b600) 0 + vptr=((& QFileIconProvider::_ZTV17QFileIconProvider) + 16u) + +Class QDirModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDirModel::QPrivateSignal (0x0x7f58d455b900) 0 empty + +Vtable for QDirModel +QDirModel::_ZTV9QDirModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QDirModel) +16 (int (*)(...))QDirModel::metaObject +24 (int (*)(...))QDirModel::qt_metacast +32 (int (*)(...))QDirModel::qt_metacall +40 (int (*)(...))QDirModel::~QDirModel +48 (int (*)(...))QDirModel::~QDirModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QDirModel::index +120 (int (*)(...))QDirModel::parent +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))QDirModel::rowCount +144 (int (*)(...))QDirModel::columnCount +152 (int (*)(...))QDirModel::hasChildren +160 (int (*)(...))QDirModel::data +168 (int (*)(...))QDirModel::setData +176 (int (*)(...))QDirModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QDirModel::mimeTypes +216 (int (*)(...))QDirModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QDirModel::dropMimeData +240 (int (*)(...))QDirModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QDirModel::flags +328 (int (*)(...))QDirModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QDirModel + size=16 align=8 + base size=16 base align=8 +QDirModel (0x0x7f58d459d270) 0 + vptr=((& QDirModel::_ZTV9QDirModel) + 16u) + QAbstractItemModel (0x0x7f58d459d2d8) 0 + primary-for QDirModel (0x0x7f58d459d270) + QObject (0x0x7f58d455b8a0) 0 + primary-for QAbstractItemModel (0x0x7f58d459d2d8) + +Class QDockWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDockWidget::QPrivateSignal (0x0x7f58d455ba20) 0 empty + +Vtable for QDockWidget +QDockWidget::_ZTV11QDockWidget: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QDockWidget) +16 (int (*)(...))QDockWidget::metaObject +24 (int (*)(...))QDockWidget::qt_metacast +32 (int (*)(...))QDockWidget::qt_metacall +40 (int (*)(...))QDockWidget::~QDockWidget +48 (int (*)(...))QDockWidget::~QDockWidget +56 (int (*)(...))QDockWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QDockWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QDockWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QDockWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI11QDockWidget) +448 (int (*)(...))QDockWidget::_ZThn16_N11QDockWidgetD1Ev +456 (int (*)(...))QDockWidget::_ZThn16_N11QDockWidgetD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDockWidget + size=48 align=8 + base size=48 base align=8 +QDockWidget (0x0x7f58d459d340) 0 + vptr=((& QDockWidget::_ZTV11QDockWidget) + 16u) + QWidget (0x0x7f58d4618d20) 0 + primary-for QDockWidget (0x0x7f58d459d340) + QObject (0x0x7f58d455b960) 0 + primary-for QWidget (0x0x7f58d4618d20) + QPaintDevice (0x0x7f58d455b9c0) 16 + vptr=((& QDockWidget::_ZTV11QDockWidget) + 448u) + +Class QTileRules + size=8 align=4 + base size=8 base align=4 +QTileRules (0x0x7f58d46a00c0) 0 + +Class QErrorMessage::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QErrorMessage::QPrivateSignal (0x0x7f58d46a0360) 0 empty + +Vtable for QErrorMessage +QErrorMessage::_ZTV13QErrorMessage: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QErrorMessage) +16 (int (*)(...))QErrorMessage::metaObject +24 (int (*)(...))QErrorMessage::qt_metacast +32 (int (*)(...))QErrorMessage::qt_metacall +40 (int (*)(...))QErrorMessage::~QErrorMessage +48 (int (*)(...))QErrorMessage::~QErrorMessage +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QErrorMessage::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QErrorMessage::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI13QErrorMessage) +488 (int (*)(...))QErrorMessage::_ZThn16_N13QErrorMessageD1Ev +496 (int (*)(...))QErrorMessage::_ZThn16_N13QErrorMessageD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QErrorMessage + size=48 align=8 + base size=48 base align=8 +QErrorMessage (0x0x7f58d459da28) 0 + vptr=((& QErrorMessage::_ZTV13QErrorMessage) + 16u) + QDialog (0x0x7f58d459da90) 0 + primary-for QErrorMessage (0x0x7f58d459da28) + QWidget (0x0x7f58d46d6770) 0 + primary-for QDialog (0x0x7f58d459da90) + QObject (0x0x7f58d46a02a0) 0 + primary-for QWidget (0x0x7f58d46d6770) + QPaintDevice (0x0x7f58d46a0300) 16 + vptr=((& QErrorMessage::_ZTV13QErrorMessage) + 488u) + +Class QFileDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDialog::QPrivateSignal (0x0x7f58d46a0480) 0 empty + +Vtable for QFileDialog +QFileDialog::_ZTV11QFileDialog: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDialog) +16 (int (*)(...))QFileDialog::metaObject +24 (int (*)(...))QFileDialog::qt_metacast +32 (int (*)(...))QFileDialog::qt_metacall +40 (int (*)(...))QFileDialog::~QFileDialog +48 (int (*)(...))QFileDialog::~QFileDialog +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QFileDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFileDialog::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QFileDialog::done +456 (int (*)(...))QFileDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI11QFileDialog) +488 (int (*)(...))QFileDialog::_ZThn16_N11QFileDialogD1Ev +496 (int (*)(...))QFileDialog::_ZThn16_N11QFileDialogD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QFileDialog + size=48 align=8 + base size=48 base align=8 +QFileDialog (0x0x7f58d459daf8) 0 + vptr=((& QFileDialog::_ZTV11QFileDialog) + 16u) + QDialog (0x0x7f58d459db60) 0 + primary-for QFileDialog (0x0x7f58d459daf8) + QWidget (0x0x7f58d46d6a80) 0 + primary-for QDialog (0x0x7f58d459db60) + QObject (0x0x7f58d46a03c0) 0 + primary-for QWidget (0x0x7f58d46d6a80) + QPaintDevice (0x0x7f58d46a0420) 16 + vptr=((& QFileDialog::_ZTV11QFileDialog) + 488u) + +Class QFileSystemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemModel::QPrivateSignal (0x0x7f58d46a06c0) 0 empty + +Vtable for QFileSystemModel +QFileSystemModel::_ZTV16QFileSystemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QFileSystemModel) +16 (int (*)(...))QFileSystemModel::metaObject +24 (int (*)(...))QFileSystemModel::qt_metacast +32 (int (*)(...))QFileSystemModel::qt_metacall +40 (int (*)(...))QFileSystemModel::~QFileSystemModel +48 (int (*)(...))QFileSystemModel::~QFileSystemModel +56 (int (*)(...))QFileSystemModel::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QFileSystemModel::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileSystemModel::index +120 (int (*)(...))QFileSystemModel::parent +128 (int (*)(...))QFileSystemModel::sibling +136 (int (*)(...))QFileSystemModel::rowCount +144 (int (*)(...))QFileSystemModel::columnCount +152 (int (*)(...))QFileSystemModel::hasChildren +160 (int (*)(...))QFileSystemModel::data +168 (int (*)(...))QFileSystemModel::setData +176 (int (*)(...))QFileSystemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QFileSystemModel::mimeTypes +216 (int (*)(...))QFileSystemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QFileSystemModel::dropMimeData +240 (int (*)(...))QFileSystemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QFileSystemModel::fetchMore +312 (int (*)(...))QFileSystemModel::canFetchMore +320 (int (*)(...))QFileSystemModel::flags +328 (int (*)(...))QFileSystemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QFileSystemModel + size=16 align=8 + base size=16 base align=8 +QFileSystemModel (0x0x7f58d459dc98) 0 + vptr=((& QFileSystemModel::_ZTV16QFileSystemModel) + 16u) + QAbstractItemModel (0x0x7f58d459dd00) 0 + primary-for QFileSystemModel (0x0x7f58d459dc98) + QObject (0x0x7f58d46a0660) 0 + primary-for QAbstractItemModel (0x0x7f58d459dd00) + +Class QFocusFrame::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFocusFrame::QPrivateSignal (0x0x7f58d46a0840) 0 empty + +Vtable for QFocusFrame +QFocusFrame::_ZTV11QFocusFrame: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFocusFrame) +16 (int (*)(...))QFocusFrame::metaObject +24 (int (*)(...))QFocusFrame::qt_metacast +32 (int (*)(...))QFocusFrame::qt_metacall +40 (int (*)(...))QFocusFrame::~QFocusFrame +48 (int (*)(...))QFocusFrame::~QFocusFrame +56 (int (*)(...))QFocusFrame::event +64 (int (*)(...))QFocusFrame::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QFocusFrame::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI11QFocusFrame) +448 (int (*)(...))QFocusFrame::_ZThn16_N11QFocusFrameD1Ev +456 (int (*)(...))QFocusFrame::_ZThn16_N11QFocusFrameD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QFocusFrame + size=48 align=8 + base size=48 base align=8 +QFocusFrame (0x0x7f58d459dd68) 0 + vptr=((& QFocusFrame::_ZTV11QFocusFrame) + 16u) + QWidget (0x0x7f58d43a7150) 0 + primary-for QFocusFrame (0x0x7f58d459dd68) + QObject (0x0x7f58d46a0780) 0 + primary-for QWidget (0x0x7f58d43a7150) + QPaintDevice (0x0x7f58d46a07e0) 16 + vptr=((& QFocusFrame::_ZTV11QFocusFrame) + 448u) + +Class QFontComboBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFontComboBox::QPrivateSignal (0x0x7f58d46a0960) 0 empty + +Vtable for QFontComboBox +QFontComboBox::_ZTV13QFontComboBox: 66u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFontComboBox) +16 (int (*)(...))QFontComboBox::metaObject +24 (int (*)(...))QFontComboBox::qt_metacast +32 (int (*)(...))QFontComboBox::qt_metacall +40 (int (*)(...))QFontComboBox::~QFontComboBox +48 (int (*)(...))QFontComboBox::~QFontComboBox +56 (int (*)(...))QFontComboBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QFontComboBox::sizeHint +136 (int (*)(...))QComboBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QComboBox::mousePressEvent +176 (int (*)(...))QComboBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QComboBox::wheelEvent +208 (int (*)(...))QComboBox::keyPressEvent +216 (int (*)(...))QComboBox::keyReleaseEvent +224 (int (*)(...))QComboBox::focusInEvent +232 (int (*)(...))QComboBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QComboBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QComboBox::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QComboBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QComboBox::showEvent +352 (int (*)(...))QComboBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QComboBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QComboBox::inputMethodEvent +416 (int (*)(...))QComboBox::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QComboBox::showPopup +440 (int (*)(...))QComboBox::hidePopup +448 (int (*)(...))-16 +456 (int (*)(...))(& _ZTI13QFontComboBox) +464 (int (*)(...))QFontComboBox::_ZThn16_N13QFontComboBoxD1Ev +472 (int (*)(...))QFontComboBox::_ZThn16_N13QFontComboBoxD0Ev +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QFontComboBox + size=48 align=8 + base size=48 base align=8 +QFontComboBox (0x0x7f58d459ddd0) 0 + vptr=((& QFontComboBox::_ZTV13QFontComboBox) + 16u) + QComboBox (0x0x7f58d459de38) 0 + primary-for QFontComboBox (0x0x7f58d459ddd0) + QWidget (0x0x7f58d43a7460) 0 + primary-for QComboBox (0x0x7f58d459de38) + QObject (0x0x7f58d46a08a0) 0 + primary-for QWidget (0x0x7f58d43a7460) + QPaintDevice (0x0x7f58d46a0900) 16 + vptr=((& QFontComboBox::_ZTV13QFontComboBox) + 464u) + +Class QFontDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFontDialog::QPrivateSignal (0x0x7f58d46a0c00) 0 empty + +Vtable for QFontDialog +QFontDialog::_ZTV11QFontDialog: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFontDialog) +16 (int (*)(...))QFontDialog::metaObject +24 (int (*)(...))QFontDialog::qt_metacast +32 (int (*)(...))QFontDialog::qt_metacall +40 (int (*)(...))QFontDialog::~QFontDialog +48 (int (*)(...))QFontDialog::~QFontDialog +56 (int (*)(...))QWidget::event +64 (int (*)(...))QFontDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QFontDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFontDialog::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QFontDialog::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI11QFontDialog) +488 (int (*)(...))QFontDialog::_ZThn16_N11QFontDialogD1Ev +496 (int (*)(...))QFontDialog::_ZThn16_N11QFontDialogD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QFontDialog + size=48 align=8 + base size=48 base align=8 +QFontDialog (0x0x7f58d4404000) 0 + vptr=((& QFontDialog::_ZTV11QFontDialog) + 16u) + QDialog (0x0x7f58d4404068) 0 + primary-for QFontDialog (0x0x7f58d4404000) + QWidget (0x0x7f58d43f3460) 0 + primary-for QDialog (0x0x7f58d4404068) + QObject (0x0x7f58d46a0b40) 0 + primary-for QWidget (0x0x7f58d43f3460) + QPaintDevice (0x0x7f58d46a0ba0) 16 + vptr=((& QFontDialog::_ZTV11QFontDialog) + 488u) + +Class QFormLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFormLayout::QPrivateSignal (0x0x7f58d46a0ea0) 0 empty + +Class QFormLayout::TakeRowResult + size=16 align=8 + base size=16 base align=8 +QFormLayout::TakeRowResult (0x0x7f58d46a0f00) 0 + +Vtable for QFormLayout +QFormLayout::_ZTV11QFormLayout: 50u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFormLayout) +16 (int (*)(...))QFormLayout::metaObject +24 (int (*)(...))QFormLayout::qt_metacast +32 (int (*)(...))QFormLayout::qt_metacall +40 (int (*)(...))QFormLayout::~QFormLayout +48 (int (*)(...))QFormLayout::~QFormLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFormLayout::invalidate +120 (int (*)(...))QLayout::geometry +128 (int (*)(...))QFormLayout::addItem +136 (int (*)(...))QFormLayout::expandingDirections +144 (int (*)(...))QFormLayout::minimumSize +152 (int (*)(...))QLayout::maximumSize +160 (int (*)(...))QFormLayout::setGeometry +168 (int (*)(...))QFormLayout::itemAt +176 (int (*)(...))QFormLayout::takeAt +184 (int (*)(...))QLayout::indexOf +192 (int (*)(...))QFormLayout::count +200 (int (*)(...))QLayout::isEmpty +208 (int (*)(...))QLayout::controlTypes +216 (int (*)(...))QLayout::layout +224 (int (*)(...))QFormLayout::sizeHint +232 (int (*)(...))QFormLayout::hasHeightForWidth +240 (int (*)(...))QFormLayout::heightForWidth +248 (int (*)(...))-16 +256 (int (*)(...))(& _ZTI11QFormLayout) +264 (int (*)(...))QFormLayout::_ZThn16_N11QFormLayoutD1Ev +272 (int (*)(...))QFormLayout::_ZThn16_N11QFormLayoutD0Ev +280 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout8sizeHintEv +288 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout11minimumSizeEv +296 (int (*)(...))QLayout::_ZThn16_NK7QLayout11maximumSizeEv +304 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout19expandingDirectionsEv +312 (int (*)(...))QFormLayout::_ZThn16_N11QFormLayout11setGeometryERK5QRect +320 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +328 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +336 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout17hasHeightForWidthEv +344 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout14heightForWidthEi +352 (int (*)(...))QLayoutItem::minimumHeightForWidth +360 (int (*)(...))QFormLayout::_ZThn16_N11QFormLayout10invalidateEv +368 (int (*)(...))QLayoutItem::widget +376 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +384 (int (*)(...))QLayoutItem::spacerItem +392 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QFormLayout + size=32 align=8 + base size=28 base align=8 +QFormLayout (0x0x7f58d44041a0) 0 + vptr=((& QFormLayout::_ZTV11QFormLayout) + 16u) + QLayout (0x0x7f58d4433850) 0 + primary-for QFormLayout (0x0x7f58d44041a0) + QObject (0x0x7f58d46a0de0) 0 + primary-for QLayout (0x0x7f58d4433850) + QLayoutItem (0x0x7f58d46a0e40) 16 + vptr=((& QFormLayout::_ZTV11QFormLayout) + 264u) + +Class QGesture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGesture::QPrivateSignal (0x0x7f58d447d480) 0 empty + +Vtable for QGesture +QGesture::_ZTV8QGesture: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QGesture) +16 (int (*)(...))QGesture::metaObject +24 (int (*)(...))QGesture::qt_metacast +32 (int (*)(...))QGesture::qt_metacall +40 (int (*)(...))QGesture::~QGesture +48 (int (*)(...))QGesture::~QGesture +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QGesture + size=16 align=8 + base size=16 base align=8 +QGesture (0x0x7f58d44043a8) 0 + vptr=((& QGesture::_ZTV8QGesture) + 16u) + QObject (0x0x7f58d447d420) 0 + primary-for QGesture (0x0x7f58d44043a8) + +Class QPanGesture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPanGesture::QPrivateSignal (0x0x7f58d447d540) 0 empty + +Vtable for QPanGesture +QPanGesture::_ZTV11QPanGesture: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QPanGesture) +16 (int (*)(...))QPanGesture::metaObject +24 (int (*)(...))QPanGesture::qt_metacast +32 (int (*)(...))QPanGesture::qt_metacall +40 (int (*)(...))QPanGesture::~QPanGesture +48 (int (*)(...))QPanGesture::~QPanGesture +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPanGesture + size=16 align=8 + base size=16 base align=8 +QPanGesture (0x0x7f58d4404410) 0 + vptr=((& QPanGesture::_ZTV11QPanGesture) + 16u) + QGesture (0x0x7f58d4404478) 0 + primary-for QPanGesture (0x0x7f58d4404410) + QObject (0x0x7f58d447d4e0) 0 + primary-for QGesture (0x0x7f58d4404478) + +Class QPinchGesture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPinchGesture::QPrivateSignal (0x0x7f58d447d600) 0 empty + +Vtable for QPinchGesture +QPinchGesture::_ZTV13QPinchGesture: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPinchGesture) +16 (int (*)(...))QPinchGesture::metaObject +24 (int (*)(...))QPinchGesture::qt_metacast +32 (int (*)(...))QPinchGesture::qt_metacall +40 (int (*)(...))QPinchGesture::~QPinchGesture +48 (int (*)(...))QPinchGesture::~QPinchGesture +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPinchGesture + size=16 align=8 + base size=16 base align=8 +QPinchGesture (0x0x7f58d44044e0) 0 + vptr=((& QPinchGesture::_ZTV13QPinchGesture) + 16u) + QGesture (0x0x7f58d4404548) 0 + primary-for QPinchGesture (0x0x7f58d44044e0) + QObject (0x0x7f58d447d5a0) 0 + primary-for QGesture (0x0x7f58d4404548) + +Class QSwipeGesture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSwipeGesture::QPrivateSignal (0x0x7f58d447d960) 0 empty + +Vtable for QSwipeGesture +QSwipeGesture::_ZTV13QSwipeGesture: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSwipeGesture) +16 (int (*)(...))QSwipeGesture::metaObject +24 (int (*)(...))QSwipeGesture::qt_metacast +32 (int (*)(...))QSwipeGesture::qt_metacall +40 (int (*)(...))QSwipeGesture::~QSwipeGesture +48 (int (*)(...))QSwipeGesture::~QSwipeGesture +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSwipeGesture + size=16 align=8 + base size=16 base align=8 +QSwipeGesture (0x0x7f58d4404680) 0 + vptr=((& QSwipeGesture::_ZTV13QSwipeGesture) + 16u) + QGesture (0x0x7f58d44046e8) 0 + primary-for QSwipeGesture (0x0x7f58d4404680) + QObject (0x0x7f58d447d900) 0 + primary-for QGesture (0x0x7f58d44046e8) + +Class QTapGesture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTapGesture::QPrivateSignal (0x0x7f58d447da80) 0 empty + +Vtable for QTapGesture +QTapGesture::_ZTV11QTapGesture: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTapGesture) +16 (int (*)(...))QTapGesture::metaObject +24 (int (*)(...))QTapGesture::qt_metacast +32 (int (*)(...))QTapGesture::qt_metacall +40 (int (*)(...))QTapGesture::~QTapGesture +48 (int (*)(...))QTapGesture::~QTapGesture +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTapGesture + size=16 align=8 + base size=16 base align=8 +QTapGesture (0x0x7f58d4404750) 0 + vptr=((& QTapGesture::_ZTV11QTapGesture) + 16u) + QGesture (0x0x7f58d44047b8) 0 + primary-for QTapGesture (0x0x7f58d4404750) + QObject (0x0x7f58d447da20) 0 + primary-for QGesture (0x0x7f58d44047b8) + +Class QTapAndHoldGesture::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTapAndHoldGesture::QPrivateSignal (0x0x7f58d447db40) 0 empty + +Vtable for QTapAndHoldGesture +QTapAndHoldGesture::_ZTV18QTapAndHoldGesture: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QTapAndHoldGesture) +16 (int (*)(...))QTapAndHoldGesture::metaObject +24 (int (*)(...))QTapAndHoldGesture::qt_metacast +32 (int (*)(...))QTapAndHoldGesture::qt_metacall +40 (int (*)(...))QTapAndHoldGesture::~QTapAndHoldGesture +48 (int (*)(...))QTapAndHoldGesture::~QTapAndHoldGesture +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTapAndHoldGesture + size=16 align=8 + base size=16 base align=8 +QTapAndHoldGesture (0x0x7f58d4404820) 0 + vptr=((& QTapAndHoldGesture::_ZTV18QTapAndHoldGesture) + 16u) + QGesture (0x0x7f58d4404888) 0 + primary-for QTapAndHoldGesture (0x0x7f58d4404820) + QObject (0x0x7f58d447dae0) 0 + primary-for QGesture (0x0x7f58d4404888) + +Vtable for QGestureEvent +QGestureEvent::_ZTV13QGestureEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QGestureEvent) +16 (int (*)(...))QGestureEvent::~QGestureEvent +24 (int (*)(...))QGestureEvent::~QGestureEvent + +Class QGestureEvent + size=56 align=8 + base size=56 base align=8 +QGestureEvent (0x0x7f58d44048f0) 0 + vptr=((& QGestureEvent::_ZTV13QGestureEvent) + 16u) + QEvent (0x0x7f58d447dba0) 0 + primary-for QGestureEvent (0x0x7f58d44048f0) + +Vtable for QGestureRecognizer +QGestureRecognizer::_ZTV18QGestureRecognizer: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QGestureRecognizer) +16 0u +24 0u +32 (int (*)(...))QGestureRecognizer::create +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QGestureRecognizer::reset + +Class QGestureRecognizer + size=8 align=8 + base size=8 base align=8 +QGestureRecognizer (0x0x7f58e5ee3660) 0 nearly-empty + vptr=((& QGestureRecognizer::_ZTV18QGestureRecognizer) + 16u) + +Vtable for QGraphicsItem +QGraphicsItem::_ZTV13QGraphicsItem: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QGraphicsItem) +16 0u +24 0u +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QGraphicsItem::shape +56 (int (*)(...))QGraphicsItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsItem::isObscuredBy +88 (int (*)(...))QGraphicsItem::opaqueArea +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))QGraphicsItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsItem::supportsExtension +296 (int (*)(...))QGraphicsItem::setExtension +304 (int (*)(...))QGraphicsItem::extension + +Class QGraphicsItem + size=16 align=8 + base size=16 base align=8 +QGraphicsItem (0x0x7f58e5f59660) 0 + vptr=((& QGraphicsItem::_ZTV13QGraphicsItem) + 16u) + +Class QGraphicsObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsObject::QPrivateSignal (0x0x7f58de813240) 0 empty + +Vtable for QGraphicsObject +QGraphicsObject::_ZTV15QGraphicsObject: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGraphicsObject) +16 (int (*)(...))QGraphicsObject::metaObject +24 (int (*)(...))QGraphicsObject::qt_metacast +32 (int (*)(...))QGraphicsObject::qt_metacall +40 0u +48 0u +56 (int (*)(...))QGraphicsObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))-16 +120 (int (*)(...))(& _ZTI15QGraphicsObject) +128 0u +136 0u +144 (int (*)(...))QGraphicsItem::advance +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))QGraphicsItem::shape +168 (int (*)(...))QGraphicsItem::contains +176 (int (*)(...))QGraphicsItem::collidesWithItem +184 (int (*)(...))QGraphicsItem::collidesWithPath +192 (int (*)(...))QGraphicsItem::isObscuredBy +200 (int (*)(...))QGraphicsItem::opaqueArea +208 (int (*)(...))__cxa_pure_virtual +216 (int (*)(...))QGraphicsItem::type +224 (int (*)(...))QGraphicsItem::sceneEventFilter +232 (int (*)(...))QGraphicsItem::sceneEvent +240 (int (*)(...))QGraphicsItem::contextMenuEvent +248 (int (*)(...))QGraphicsItem::dragEnterEvent +256 (int (*)(...))QGraphicsItem::dragLeaveEvent +264 (int (*)(...))QGraphicsItem::dragMoveEvent +272 (int (*)(...))QGraphicsItem::dropEvent +280 (int (*)(...))QGraphicsItem::focusInEvent +288 (int (*)(...))QGraphicsItem::focusOutEvent +296 (int (*)(...))QGraphicsItem::hoverEnterEvent +304 (int (*)(...))QGraphicsItem::hoverMoveEvent +312 (int (*)(...))QGraphicsItem::hoverLeaveEvent +320 (int (*)(...))QGraphicsItem::keyPressEvent +328 (int (*)(...))QGraphicsItem::keyReleaseEvent +336 (int (*)(...))QGraphicsItem::mousePressEvent +344 (int (*)(...))QGraphicsItem::mouseMoveEvent +352 (int (*)(...))QGraphicsItem::mouseReleaseEvent +360 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +368 (int (*)(...))QGraphicsItem::wheelEvent +376 (int (*)(...))QGraphicsItem::inputMethodEvent +384 (int (*)(...))QGraphicsItem::inputMethodQuery +392 (int (*)(...))QGraphicsItem::itemChange +400 (int (*)(...))QGraphicsItem::supportsExtension +408 (int (*)(...))QGraphicsItem::setExtension +416 (int (*)(...))QGraphicsItem::extension + +Class QGraphicsObject + size=32 align=8 + base size=32 base align=8 +QGraphicsObject (0x0x7f58e12c8d20) 0 + vptr=((& QGraphicsObject::_ZTV15QGraphicsObject) + 16u) + QObject (0x0x7f58e03b9de0) 0 + primary-for QGraphicsObject (0x0x7f58e12c8d20) + QGraphicsItem (0x0x7f58de8131e0) 16 + vptr=((& QGraphicsObject::_ZTV15QGraphicsObject) + 128u) + +Vtable for QAbstractGraphicsShapeItem +QAbstractGraphicsShapeItem::_ZTV26QAbstractGraphicsShapeItem: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractGraphicsShapeItem) +16 0u +24 0u +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))QGraphicsItem::shape +56 (int (*)(...))QGraphicsItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QAbstractGraphicsShapeItem::isObscuredBy +88 (int (*)(...))QAbstractGraphicsShapeItem::opaqueArea +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))QGraphicsItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsItem::supportsExtension +296 (int (*)(...))QGraphicsItem::setExtension +304 (int (*)(...))QGraphicsItem::extension + +Class QAbstractGraphicsShapeItem + size=16 align=8 + base size=16 base align=8 +QAbstractGraphicsShapeItem (0x0x7f58e067ea28) 0 + vptr=((& QAbstractGraphicsShapeItem::_ZTV26QAbstractGraphicsShapeItem) + 16u) + QGraphicsItem (0x0x7f58de813540) 0 + primary-for QAbstractGraphicsShapeItem (0x0x7f58e067ea28) + +Vtable for QGraphicsPathItem +QGraphicsPathItem::_ZTV17QGraphicsPathItem: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QGraphicsPathItem) +16 (int (*)(...))QGraphicsPathItem::~QGraphicsPathItem +24 (int (*)(...))QGraphicsPathItem::~QGraphicsPathItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsPathItem::boundingRect +48 (int (*)(...))QGraphicsPathItem::shape +56 (int (*)(...))QGraphicsPathItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsPathItem::isObscuredBy +88 (int (*)(...))QGraphicsPathItem::opaqueArea +96 (int (*)(...))QGraphicsPathItem::paint +104 (int (*)(...))QGraphicsPathItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsPathItem::supportsExtension +296 (int (*)(...))QGraphicsPathItem::setExtension +304 (int (*)(...))QGraphicsPathItem::extension + +Class QGraphicsPathItem + size=16 align=8 + base size=16 base align=8 +QGraphicsPathItem (0x0x7f58e067edd0) 0 + vptr=((& QGraphicsPathItem::_ZTV17QGraphicsPathItem) + 16u) + QAbstractGraphicsShapeItem (0x0x7f58e067ee38) 0 + primary-for QGraphicsPathItem (0x0x7f58e067edd0) + QGraphicsItem (0x0x7f58de8135a0) 0 + primary-for QAbstractGraphicsShapeItem (0x0x7f58e067ee38) + +Vtable for QGraphicsRectItem +QGraphicsRectItem::_ZTV17QGraphicsRectItem: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QGraphicsRectItem) +16 (int (*)(...))QGraphicsRectItem::~QGraphicsRectItem +24 (int (*)(...))QGraphicsRectItem::~QGraphicsRectItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsRectItem::boundingRect +48 (int (*)(...))QGraphicsRectItem::shape +56 (int (*)(...))QGraphicsRectItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsRectItem::isObscuredBy +88 (int (*)(...))QGraphicsRectItem::opaqueArea +96 (int (*)(...))QGraphicsRectItem::paint +104 (int (*)(...))QGraphicsRectItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsRectItem::supportsExtension +296 (int (*)(...))QGraphicsRectItem::setExtension +304 (int (*)(...))QGraphicsRectItem::extension + +Class QGraphicsRectItem + size=16 align=8 + base size=16 base align=8 +QGraphicsRectItem (0x0x7f58dfefaf70) 0 + vptr=((& QGraphicsRectItem::_ZTV17QGraphicsRectItem) + 16u) + QAbstractGraphicsShapeItem (0x0x7f58df6aaf08) 0 + primary-for QGraphicsRectItem (0x0x7f58dfefaf70) + QGraphicsItem (0x0x7f58de43aba0) 0 + primary-for QAbstractGraphicsShapeItem (0x0x7f58df6aaf08) + +Vtable for QGraphicsEllipseItem +QGraphicsEllipseItem::_ZTV20QGraphicsEllipseItem: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QGraphicsEllipseItem) +16 (int (*)(...))QGraphicsEllipseItem::~QGraphicsEllipseItem +24 (int (*)(...))QGraphicsEllipseItem::~QGraphicsEllipseItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsEllipseItem::boundingRect +48 (int (*)(...))QGraphicsEllipseItem::shape +56 (int (*)(...))QGraphicsEllipseItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsEllipseItem::isObscuredBy +88 (int (*)(...))QGraphicsEllipseItem::opaqueArea +96 (int (*)(...))QGraphicsEllipseItem::paint +104 (int (*)(...))QGraphicsEllipseItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsEllipseItem::supportsExtension +296 (int (*)(...))QGraphicsEllipseItem::setExtension +304 (int (*)(...))QGraphicsEllipseItem::extension + +Class QGraphicsEllipseItem + size=16 align=8 + base size=16 base align=8 +QGraphicsEllipseItem (0x0x7f58df6aaf70) 0 + vptr=((& QGraphicsEllipseItem::_ZTV20QGraphicsEllipseItem) + 16u) + QAbstractGraphicsShapeItem (0x0x7f58df6aa000) 0 + primary-for QGraphicsEllipseItem (0x0x7f58df6aaf70) + QGraphicsItem (0x0x7f58de43ac00) 0 + primary-for QAbstractGraphicsShapeItem (0x0x7f58df6aa000) + +Vtable for QGraphicsPolygonItem +QGraphicsPolygonItem::_ZTV20QGraphicsPolygonItem: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QGraphicsPolygonItem) +16 (int (*)(...))QGraphicsPolygonItem::~QGraphicsPolygonItem +24 (int (*)(...))QGraphicsPolygonItem::~QGraphicsPolygonItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsPolygonItem::boundingRect +48 (int (*)(...))QGraphicsPolygonItem::shape +56 (int (*)(...))QGraphicsPolygonItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsPolygonItem::isObscuredBy +88 (int (*)(...))QGraphicsPolygonItem::opaqueArea +96 (int (*)(...))QGraphicsPolygonItem::paint +104 (int (*)(...))QGraphicsPolygonItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsPolygonItem::supportsExtension +296 (int (*)(...))QGraphicsPolygonItem::setExtension +304 (int (*)(...))QGraphicsPolygonItem::extension + +Class QGraphicsPolygonItem + size=16 align=8 + base size=16 base align=8 +QGraphicsPolygonItem (0x0x7f58df6aa068) 0 + vptr=((& QGraphicsPolygonItem::_ZTV20QGraphicsPolygonItem) + 16u) + QAbstractGraphicsShapeItem (0x0x7f58df6aaea0) 0 + primary-for QGraphicsPolygonItem (0x0x7f58df6aa068) + QGraphicsItem (0x0x7f58de094540) 0 + primary-for QAbstractGraphicsShapeItem (0x0x7f58df6aaea0) + +Vtable for QGraphicsLineItem +QGraphicsLineItem::_ZTV17QGraphicsLineItem: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QGraphicsLineItem) +16 (int (*)(...))QGraphicsLineItem::~QGraphicsLineItem +24 (int (*)(...))QGraphicsLineItem::~QGraphicsLineItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsLineItem::boundingRect +48 (int (*)(...))QGraphicsLineItem::shape +56 (int (*)(...))QGraphicsLineItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsLineItem::isObscuredBy +88 (int (*)(...))QGraphicsLineItem::opaqueArea +96 (int (*)(...))QGraphicsLineItem::paint +104 (int (*)(...))QGraphicsLineItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsLineItem::supportsExtension +296 (int (*)(...))QGraphicsLineItem::setExtension +304 (int (*)(...))QGraphicsLineItem::extension + +Class QGraphicsLineItem + size=16 align=8 + base size=16 base align=8 +QGraphicsLineItem (0x0x7f58ded1c000) 0 + vptr=((& QGraphicsLineItem::_ZTV17QGraphicsLineItem) + 16u) + QGraphicsItem (0x0x7f58de0945a0) 0 + primary-for QGraphicsLineItem (0x0x7f58ded1c000) + +Vtable for QGraphicsPixmapItem +QGraphicsPixmapItem::_ZTV19QGraphicsPixmapItem: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QGraphicsPixmapItem) +16 (int (*)(...))QGraphicsPixmapItem::~QGraphicsPixmapItem +24 (int (*)(...))QGraphicsPixmapItem::~QGraphicsPixmapItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsPixmapItem::boundingRect +48 (int (*)(...))QGraphicsPixmapItem::shape +56 (int (*)(...))QGraphicsPixmapItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsPixmapItem::isObscuredBy +88 (int (*)(...))QGraphicsPixmapItem::opaqueArea +96 (int (*)(...))QGraphicsPixmapItem::paint +104 (int (*)(...))QGraphicsPixmapItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsPixmapItem::supportsExtension +296 (int (*)(...))QGraphicsPixmapItem::setExtension +304 (int (*)(...))QGraphicsPixmapItem::extension + +Class QGraphicsPixmapItem + size=16 align=8 + base size=16 base align=8 +QGraphicsPixmapItem (0x0x7f58ded1c068) 0 + vptr=((& QGraphicsPixmapItem::_ZTV19QGraphicsPixmapItem) + 16u) + QGraphicsItem (0x0x7f58de094c60) 0 + primary-for QGraphicsPixmapItem (0x0x7f58ded1c068) + +Class QGraphicsTextItem::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsTextItem::QPrivateSignal (0x0x7f58de094e40) 0 empty + +Vtable for QGraphicsTextItem +QGraphicsTextItem::_ZTV17QGraphicsTextItem: 82u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QGraphicsTextItem) +16 (int (*)(...))QGraphicsTextItem::metaObject +24 (int (*)(...))QGraphicsTextItem::qt_metacast +32 (int (*)(...))QGraphicsTextItem::qt_metacall +40 (int (*)(...))QGraphicsTextItem::~QGraphicsTextItem +48 (int (*)(...))QGraphicsTextItem::~QGraphicsTextItem +56 (int (*)(...))QGraphicsObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsTextItem::boundingRect +120 (int (*)(...))QGraphicsTextItem::shape +128 (int (*)(...))QGraphicsTextItem::contains +136 (int (*)(...))QGraphicsTextItem::paint +144 (int (*)(...))QGraphicsTextItem::isObscuredBy +152 (int (*)(...))QGraphicsTextItem::opaqueArea +160 (int (*)(...))QGraphicsTextItem::type +168 (int (*)(...))QGraphicsTextItem::sceneEvent +176 (int (*)(...))QGraphicsTextItem::mousePressEvent +184 (int (*)(...))QGraphicsTextItem::mouseMoveEvent +192 (int (*)(...))QGraphicsTextItem::mouseReleaseEvent +200 (int (*)(...))QGraphicsTextItem::mouseDoubleClickEvent +208 (int (*)(...))QGraphicsTextItem::contextMenuEvent +216 (int (*)(...))QGraphicsTextItem::keyPressEvent +224 (int (*)(...))QGraphicsTextItem::keyReleaseEvent +232 (int (*)(...))QGraphicsTextItem::focusInEvent +240 (int (*)(...))QGraphicsTextItem::focusOutEvent +248 (int (*)(...))QGraphicsTextItem::dragEnterEvent +256 (int (*)(...))QGraphicsTextItem::dragLeaveEvent +264 (int (*)(...))QGraphicsTextItem::dragMoveEvent +272 (int (*)(...))QGraphicsTextItem::dropEvent +280 (int (*)(...))QGraphicsTextItem::inputMethodEvent +288 (int (*)(...))QGraphicsTextItem::hoverEnterEvent +296 (int (*)(...))QGraphicsTextItem::hoverMoveEvent +304 (int (*)(...))QGraphicsTextItem::hoverLeaveEvent +312 (int (*)(...))QGraphicsTextItem::inputMethodQuery +320 (int (*)(...))QGraphicsTextItem::supportsExtension +328 (int (*)(...))QGraphicsTextItem::setExtension +336 (int (*)(...))QGraphicsTextItem::extension +344 (int (*)(...))-16 +352 (int (*)(...))(& _ZTI17QGraphicsTextItem) +360 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItemD1Ev +368 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItemD0Ev +376 (int (*)(...))QGraphicsItem::advance +384 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem12boundingRectEv +392 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem5shapeEv +400 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem8containsERK7QPointF +408 (int (*)(...))QGraphicsItem::collidesWithItem +416 (int (*)(...))QGraphicsItem::collidesWithPath +424 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem12isObscuredByEPK13QGraphicsItem +432 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem10opaqueAreaEv +440 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem5paintEP8QPainterPK24QStyleOptionGraphicsItemP7QWidget +448 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem4typeEv +456 (int (*)(...))QGraphicsItem::sceneEventFilter +464 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem10sceneEventEP6QEvent +472 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem16contextMenuEventEP30QGraphicsSceneContextMenuEvent +480 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem14dragEnterEventEP27QGraphicsSceneDragDropEvent +488 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem14dragLeaveEventEP27QGraphicsSceneDragDropEvent +496 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem13dragMoveEventEP27QGraphicsSceneDragDropEvent +504 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem9dropEventEP27QGraphicsSceneDragDropEvent +512 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem12focusInEventEP11QFocusEvent +520 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem13focusOutEventEP11QFocusEvent +528 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem15hoverEnterEventEP24QGraphicsSceneHoverEvent +536 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem14hoverMoveEventEP24QGraphicsSceneHoverEvent +544 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem15hoverLeaveEventEP24QGraphicsSceneHoverEvent +552 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem13keyPressEventEP9QKeyEvent +560 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem15keyReleaseEventEP9QKeyEvent +568 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem15mousePressEventEP24QGraphicsSceneMouseEvent +576 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem14mouseMoveEventEP24QGraphicsSceneMouseEvent +584 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem17mouseReleaseEventEP24QGraphicsSceneMouseEvent +592 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem21mouseDoubleClickEventEP24QGraphicsSceneMouseEvent +600 (int (*)(...))QGraphicsItem::wheelEvent +608 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem16inputMethodEventEP17QInputMethodEvent +616 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem16inputMethodQueryEN2Qt16InputMethodQueryE +624 (int (*)(...))QGraphicsItem::itemChange +632 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem17supportsExtensionEN13QGraphicsItem9ExtensionE +640 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem12setExtensionEN13QGraphicsItem9ExtensionERK8QVariant +648 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem9extensionERK8QVariant + +Class QGraphicsTextItem + size=40 align=8 + base size=40 base align=8 +QGraphicsTextItem (0x0x7f58ded1c0d0) 0 + vptr=((& QGraphicsTextItem::_ZTV17QGraphicsTextItem) + 16u) + QGraphicsObject (0x0x7f58e12fd460) 0 + primary-for QGraphicsTextItem (0x0x7f58ded1c0d0) + QObject (0x0x7f58de094cc0) 0 + primary-for QGraphicsObject (0x0x7f58e12fd460) + QGraphicsItem (0x0x7f58de094d80) 16 + vptr=((& QGraphicsTextItem::_ZTV17QGraphicsTextItem) + 360u) + +Vtable for QGraphicsSimpleTextItem +QGraphicsSimpleTextItem::_ZTV23QGraphicsSimpleTextItem: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGraphicsSimpleTextItem) +16 (int (*)(...))QGraphicsSimpleTextItem::~QGraphicsSimpleTextItem +24 (int (*)(...))QGraphicsSimpleTextItem::~QGraphicsSimpleTextItem +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsSimpleTextItem::boundingRect +48 (int (*)(...))QGraphicsSimpleTextItem::shape +56 (int (*)(...))QGraphicsSimpleTextItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsSimpleTextItem::isObscuredBy +88 (int (*)(...))QGraphicsSimpleTextItem::opaqueArea +96 (int (*)(...))QGraphicsSimpleTextItem::paint +104 (int (*)(...))QGraphicsSimpleTextItem::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsSimpleTextItem::supportsExtension +296 (int (*)(...))QGraphicsSimpleTextItem::setExtension +304 (int (*)(...))QGraphicsSimpleTextItem::extension + +Class QGraphicsSimpleTextItem + size=16 align=8 + base size=16 base align=8 +QGraphicsSimpleTextItem (0x0x7f58debd4bc8) 0 + vptr=((& QGraphicsSimpleTextItem::_ZTV23QGraphicsSimpleTextItem) + 16u) + QAbstractGraphicsShapeItem (0x0x7f58debd4c30) 0 + primary-for QGraphicsSimpleTextItem (0x0x7f58debd4bc8) + QGraphicsItem (0x0x7f58de0b89c0) 0 + primary-for QAbstractGraphicsShapeItem (0x0x7f58debd4c30) + +Vtable for QGraphicsItemGroup +QGraphicsItemGroup::_ZTV18QGraphicsItemGroup: 39u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QGraphicsItemGroup) +16 (int (*)(...))QGraphicsItemGroup::~QGraphicsItemGroup +24 (int (*)(...))QGraphicsItemGroup::~QGraphicsItemGroup +32 (int (*)(...))QGraphicsItem::advance +40 (int (*)(...))QGraphicsItemGroup::boundingRect +48 (int (*)(...))QGraphicsItem::shape +56 (int (*)(...))QGraphicsItem::contains +64 (int (*)(...))QGraphicsItem::collidesWithItem +72 (int (*)(...))QGraphicsItem::collidesWithPath +80 (int (*)(...))QGraphicsItemGroup::isObscuredBy +88 (int (*)(...))QGraphicsItemGroup::opaqueArea +96 (int (*)(...))QGraphicsItemGroup::paint +104 (int (*)(...))QGraphicsItemGroup::type +112 (int (*)(...))QGraphicsItem::sceneEventFilter +120 (int (*)(...))QGraphicsItem::sceneEvent +128 (int (*)(...))QGraphicsItem::contextMenuEvent +136 (int (*)(...))QGraphicsItem::dragEnterEvent +144 (int (*)(...))QGraphicsItem::dragLeaveEvent +152 (int (*)(...))QGraphicsItem::dragMoveEvent +160 (int (*)(...))QGraphicsItem::dropEvent +168 (int (*)(...))QGraphicsItem::focusInEvent +176 (int (*)(...))QGraphicsItem::focusOutEvent +184 (int (*)(...))QGraphicsItem::hoverEnterEvent +192 (int (*)(...))QGraphicsItem::hoverMoveEvent +200 (int (*)(...))QGraphicsItem::hoverLeaveEvent +208 (int (*)(...))QGraphicsItem::keyPressEvent +216 (int (*)(...))QGraphicsItem::keyReleaseEvent +224 (int (*)(...))QGraphicsItem::mousePressEvent +232 (int (*)(...))QGraphicsItem::mouseMoveEvent +240 (int (*)(...))QGraphicsItem::mouseReleaseEvent +248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +256 (int (*)(...))QGraphicsItem::wheelEvent +264 (int (*)(...))QGraphicsItem::inputMethodEvent +272 (int (*)(...))QGraphicsItem::inputMethodQuery +280 (int (*)(...))QGraphicsItem::itemChange +288 (int (*)(...))QGraphicsItem::supportsExtension +296 (int (*)(...))QGraphicsItem::setExtension +304 (int (*)(...))QGraphicsItem::extension + +Class QGraphicsItemGroup + size=16 align=8 + base size=16 base align=8 +QGraphicsItemGroup (0x0x7f58de415f08) 0 + vptr=((& QGraphicsItemGroup::_ZTV18QGraphicsItemGroup) + 16u) + QGraphicsItem (0x0x7f58de0e20c0) 0 + primary-for QGraphicsItemGroup (0x0x7f58de415f08) + +Vtable for QGraphicsLayoutItem +QGraphicsLayoutItem::_ZTV19QGraphicsLayoutItem: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QGraphicsLayoutItem) +16 0u +24 0u +32 (int (*)(...))QGraphicsLayoutItem::setGeometry +40 (int (*)(...))QGraphicsLayoutItem::getContentsMargins +48 (int (*)(...))QGraphicsLayoutItem::updateGeometry +56 (int (*)(...))__cxa_pure_virtual + +Class QGraphicsLayoutItem + size=16 align=8 + base size=16 base align=8 +QGraphicsLayoutItem (0x0x7f58de1fcc60) 0 + vptr=((& QGraphicsLayoutItem::_ZTV19QGraphicsLayoutItem) + 16u) + +Vtable for QGraphicsLayout +QGraphicsLayout::_ZTV15QGraphicsLayout: 13u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGraphicsLayout) +16 0u +24 0u +32 (int (*)(...))QGraphicsLayoutItem::setGeometry +40 (int (*)(...))QGraphicsLayout::getContentsMargins +48 (int (*)(...))QGraphicsLayout::updateGeometry +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))QGraphicsLayout::invalidate +72 (int (*)(...))QGraphicsLayout::widgetEvent +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual + +Class QGraphicsLayout + size=16 align=8 + base size=16 base align=8 +QGraphicsLayout (0x0x7f58de415f70) 0 + vptr=((& QGraphicsLayout::_ZTV15QGraphicsLayout) + 16u) + QGraphicsLayoutItem (0x0x7f58ddefd7e0) 0 + primary-for QGraphicsLayout (0x0x7f58de415f70) + +Class QGraphicsAnchor::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsAnchor::QPrivateSignal (0x0x7f58ddefd900) 0 empty + +Vtable for QGraphicsAnchor +QGraphicsAnchor::_ZTV15QGraphicsAnchor: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGraphicsAnchor) +16 (int (*)(...))QGraphicsAnchor::metaObject +24 (int (*)(...))QGraphicsAnchor::qt_metacast +32 (int (*)(...))QGraphicsAnchor::qt_metacall +40 (int (*)(...))QGraphicsAnchor::~QGraphicsAnchor +48 (int (*)(...))QGraphicsAnchor::~QGraphicsAnchor +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QGraphicsAnchor + size=16 align=8 + base size=16 base align=8 +QGraphicsAnchor (0x0x7f58de097478) 0 + vptr=((& QGraphicsAnchor::_ZTV15QGraphicsAnchor) + 16u) + QObject (0x0x7f58ddefd8a0) 0 + primary-for QGraphicsAnchor (0x0x7f58de097478) + +Vtable for QGraphicsAnchorLayout +QGraphicsAnchorLayout::_ZTV21QGraphicsAnchorLayout: 13u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QGraphicsAnchorLayout) +16 (int (*)(...))QGraphicsAnchorLayout::~QGraphicsAnchorLayout +24 (int (*)(...))QGraphicsAnchorLayout::~QGraphicsAnchorLayout +32 (int (*)(...))QGraphicsAnchorLayout::setGeometry +40 (int (*)(...))QGraphicsLayout::getContentsMargins +48 (int (*)(...))QGraphicsLayout::updateGeometry +56 (int (*)(...))QGraphicsAnchorLayout::sizeHint +64 (int (*)(...))QGraphicsAnchorLayout::invalidate +72 (int (*)(...))QGraphicsLayout::widgetEvent +80 (int (*)(...))QGraphicsAnchorLayout::count +88 (int (*)(...))QGraphicsAnchorLayout::itemAt +96 (int (*)(...))QGraphicsAnchorLayout::removeAt + +Class QGraphicsAnchorLayout + size=16 align=8 + base size=16 base align=8 +QGraphicsAnchorLayout (0x0x7f58de0974e0) 0 + vptr=((& QGraphicsAnchorLayout::_ZTV21QGraphicsAnchorLayout) + 16u) + QGraphicsLayout (0x0x7f58de0c4478) 0 + primary-for QGraphicsAnchorLayout (0x0x7f58de0974e0) + QGraphicsLayoutItem (0x0x7f58ddefd960) 0 + primary-for QGraphicsLayout (0x0x7f58de0c4478) + +Class QGraphicsEffect::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsEffect::QPrivateSignal (0x0x7f58ddefda20) 0 empty + +Vtable for QGraphicsEffect +QGraphicsEffect::_ZTV15QGraphicsEffect: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGraphicsEffect) +16 (int (*)(...))QGraphicsEffect::metaObject +24 (int (*)(...))QGraphicsEffect::qt_metacast +32 (int (*)(...))QGraphicsEffect::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsEffect::boundingRectFor +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QGraphicsEffect::sourceChanged + +Class QGraphicsEffect + size=16 align=8 + base size=16 base align=8 +QGraphicsEffect (0x0x7f58de0c44e0) 0 + vptr=((& QGraphicsEffect::_ZTV15QGraphicsEffect) + 16u) + QObject (0x0x7f58ddefd9c0) 0 + primary-for QGraphicsEffect (0x0x7f58de0c44e0) + +Class QGraphicsColorizeEffect::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsColorizeEffect::QPrivateSignal (0x0x7f58ddefdcc0) 0 empty + +Vtable for QGraphicsColorizeEffect +QGraphicsColorizeEffect::_ZTV23QGraphicsColorizeEffect: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGraphicsColorizeEffect) +16 (int (*)(...))QGraphicsColorizeEffect::metaObject +24 (int (*)(...))QGraphicsColorizeEffect::qt_metacast +32 (int (*)(...))QGraphicsColorizeEffect::qt_metacall +40 (int (*)(...))QGraphicsColorizeEffect::~QGraphicsColorizeEffect +48 (int (*)(...))QGraphicsColorizeEffect::~QGraphicsColorizeEffect +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsEffect::boundingRectFor +120 (int (*)(...))QGraphicsColorizeEffect::draw +128 (int (*)(...))QGraphicsEffect::sourceChanged + +Class QGraphicsColorizeEffect + size=16 align=8 + base size=16 base align=8 +QGraphicsColorizeEffect (0x0x7f58de0de478) 0 + vptr=((& QGraphicsColorizeEffect::_ZTV23QGraphicsColorizeEffect) + 16u) + QGraphicsEffect (0x0x7f58de0de4e0) 0 + primary-for QGraphicsColorizeEffect (0x0x7f58de0de478) + QObject (0x0x7f58ddefdc60) 0 + primary-for QGraphicsEffect (0x0x7f58de0de4e0) + +Class QGraphicsBlurEffect::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsBlurEffect::QPrivateSignal (0x0x7f58ddc79de0) 0 empty + +Vtable for QGraphicsBlurEffect +QGraphicsBlurEffect::_ZTV19QGraphicsBlurEffect: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QGraphicsBlurEffect) +16 (int (*)(...))QGraphicsBlurEffect::metaObject +24 (int (*)(...))QGraphicsBlurEffect::qt_metacast +32 (int (*)(...))QGraphicsBlurEffect::qt_metacall +40 (int (*)(...))QGraphicsBlurEffect::~QGraphicsBlurEffect +48 (int (*)(...))QGraphicsBlurEffect::~QGraphicsBlurEffect +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsBlurEffect::boundingRectFor +120 (int (*)(...))QGraphicsBlurEffect::draw +128 (int (*)(...))QGraphicsEffect::sourceChanged + +Class QGraphicsBlurEffect + size=16 align=8 + base size=16 base align=8 +QGraphicsBlurEffect (0x0x7f58de0de958) 0 + vptr=((& QGraphicsBlurEffect::_ZTV19QGraphicsBlurEffect) + 16u) + QGraphicsEffect (0x0x7f58de0de9c0) 0 + primary-for QGraphicsBlurEffect (0x0x7f58de0de958) + QObject (0x0x7f58ddefdd20) 0 + primary-for QGraphicsEffect (0x0x7f58de0de9c0) + +Class QGraphicsDropShadowEffect::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsDropShadowEffect::QPrivateSignal (0x0x7f58dde01300) 0 empty + +Vtable for QGraphicsDropShadowEffect +QGraphicsDropShadowEffect::_ZTV25QGraphicsDropShadowEffect: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QGraphicsDropShadowEffect) +16 (int (*)(...))QGraphicsDropShadowEffect::metaObject +24 (int (*)(...))QGraphicsDropShadowEffect::qt_metacast +32 (int (*)(...))QGraphicsDropShadowEffect::qt_metacall +40 (int (*)(...))QGraphicsDropShadowEffect::~QGraphicsDropShadowEffect +48 (int (*)(...))QGraphicsDropShadowEffect::~QGraphicsDropShadowEffect +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsDropShadowEffect::boundingRectFor +120 (int (*)(...))QGraphicsDropShadowEffect::draw +128 (int (*)(...))QGraphicsEffect::sourceChanged + +Class QGraphicsDropShadowEffect + size=16 align=8 + base size=16 base align=8 +QGraphicsDropShadowEffect (0x0x7f58ddebc6e8) 0 + vptr=((& QGraphicsDropShadowEffect::_ZTV25QGraphicsDropShadowEffect) + 16u) + QGraphicsEffect (0x0x7f58ddebc750) 0 + primary-for QGraphicsDropShadowEffect (0x0x7f58ddebc6e8) + QObject (0x0x7f58dde012a0) 0 + primary-for QGraphicsEffect (0x0x7f58ddebc750) + +Class QGraphicsOpacityEffect::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsOpacityEffect::QPrivateSignal (0x0x7f58dd8d53c0) 0 empty + +Vtable for QGraphicsOpacityEffect +QGraphicsOpacityEffect::_ZTV22QGraphicsOpacityEffect: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QGraphicsOpacityEffect) +16 (int (*)(...))QGraphicsOpacityEffect::metaObject +24 (int (*)(...))QGraphicsOpacityEffect::qt_metacast +32 (int (*)(...))QGraphicsOpacityEffect::qt_metacall +40 (int (*)(...))QGraphicsOpacityEffect::~QGraphicsOpacityEffect +48 (int (*)(...))QGraphicsOpacityEffect::~QGraphicsOpacityEffect +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsEffect::boundingRectFor +120 (int (*)(...))QGraphicsOpacityEffect::draw +128 (int (*)(...))QGraphicsEffect::sourceChanged + +Class QGraphicsOpacityEffect + size=16 align=8 + base size=16 base align=8 +QGraphicsOpacityEffect (0x0x7f58ddebc7b8) 0 + vptr=((& QGraphicsOpacityEffect::_ZTV22QGraphicsOpacityEffect) + 16u) + QGraphicsEffect (0x0x7f58ddebc820) 0 + primary-for QGraphicsOpacityEffect (0x0x7f58ddebc7b8) + QObject (0x0x7f58dd8d5360) 0 + primary-for QGraphicsEffect (0x0x7f58ddebc820) + +Vtable for QGraphicsGridLayout +QGraphicsGridLayout::_ZTV19QGraphicsGridLayout: 13u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QGraphicsGridLayout) +16 (int (*)(...))QGraphicsGridLayout::~QGraphicsGridLayout +24 (int (*)(...))QGraphicsGridLayout::~QGraphicsGridLayout +32 (int (*)(...))QGraphicsGridLayout::setGeometry +40 (int (*)(...))QGraphicsLayout::getContentsMargins +48 (int (*)(...))QGraphicsLayout::updateGeometry +56 (int (*)(...))QGraphicsGridLayout::sizeHint +64 (int (*)(...))QGraphicsGridLayout::invalidate +72 (int (*)(...))QGraphicsLayout::widgetEvent +80 (int (*)(...))QGraphicsGridLayout::count +88 (int (*)(...))QGraphicsGridLayout::itemAt +96 (int (*)(...))QGraphicsGridLayout::removeAt + +Class QGraphicsGridLayout + size=16 align=8 + base size=16 base align=8 +QGraphicsGridLayout (0x0x7f58ddebc888) 0 + vptr=((& QGraphicsGridLayout::_ZTV19QGraphicsGridLayout) + 16u) + QGraphicsLayout (0x0x7f58ddebc8f0) 0 + primary-for QGraphicsGridLayout (0x0x7f58ddebc888) + QGraphicsLayoutItem (0x0x7f58dd8d5480) 0 + primary-for QGraphicsLayout (0x0x7f58ddebc8f0) + +Class QGraphicsItemAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsItemAnimation::QPrivateSignal (0x0x7f58dd8d56c0) 0 empty + +Vtable for QGraphicsItemAnimation +QGraphicsItemAnimation::_ZTV22QGraphicsItemAnimation: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QGraphicsItemAnimation) +16 (int (*)(...))QGraphicsItemAnimation::metaObject +24 (int (*)(...))QGraphicsItemAnimation::qt_metacast +32 (int (*)(...))QGraphicsItemAnimation::qt_metacall +40 (int (*)(...))QGraphicsItemAnimation::~QGraphicsItemAnimation +48 (int (*)(...))QGraphicsItemAnimation::~QGraphicsItemAnimation +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsItemAnimation::beforeAnimationStep +120 (int (*)(...))QGraphicsItemAnimation::afterAnimationStep + +Class QGraphicsItemAnimation + size=24 align=8 + base size=24 base align=8 +QGraphicsItemAnimation (0x0x7f58ddebc9c0) 0 + vptr=((& QGraphicsItemAnimation::_ZTV22QGraphicsItemAnimation) + 16u) + QObject (0x0x7f58dd8d5660) 0 + primary-for QGraphicsItemAnimation (0x0x7f58ddebc9c0) + +Vtable for QGraphicsLinearLayout +QGraphicsLinearLayout::_ZTV21QGraphicsLinearLayout: 13u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QGraphicsLinearLayout) +16 (int (*)(...))QGraphicsLinearLayout::~QGraphicsLinearLayout +24 (int (*)(...))QGraphicsLinearLayout::~QGraphicsLinearLayout +32 (int (*)(...))QGraphicsLinearLayout::setGeometry +40 (int (*)(...))QGraphicsLayout::getContentsMargins +48 (int (*)(...))QGraphicsLayout::updateGeometry +56 (int (*)(...))QGraphicsLinearLayout::sizeHint +64 (int (*)(...))QGraphicsLinearLayout::invalidate +72 (int (*)(...))QGraphicsLayout::widgetEvent +80 (int (*)(...))QGraphicsLinearLayout::count +88 (int (*)(...))QGraphicsLinearLayout::itemAt +96 (int (*)(...))QGraphicsLinearLayout::removeAt + +Class QGraphicsLinearLayout + size=16 align=8 + base size=16 base align=8 +QGraphicsLinearLayout (0x0x7f58ddebca28) 0 + vptr=((& QGraphicsLinearLayout::_ZTV21QGraphicsLinearLayout) + 16u) + QGraphicsLayout (0x0x7f58ddebca90) 0 + primary-for QGraphicsLinearLayout (0x0x7f58ddebca28) + QGraphicsLayoutItem (0x0x7f58dd8fc240) 0 + primary-for QGraphicsLayout (0x0x7f58ddebca90) + +Class QGraphicsWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsWidget::QPrivateSignal (0x0x7f58dd8fccc0) 0 empty + +Vtable for QGraphicsWidget +QGraphicsWidget::_ZTV15QGraphicsWidget: 92u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QGraphicsWidget) +16 (int (*)(...))QGraphicsWidget::metaObject +24 (int (*)(...))QGraphicsWidget::qt_metacast +32 (int (*)(...))QGraphicsWidget::qt_metacall +40 (int (*)(...))QGraphicsWidget::~QGraphicsWidget +48 (int (*)(...))QGraphicsWidget::~QGraphicsWidget +56 (int (*)(...))QGraphicsWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsWidget::setGeometry +120 (int (*)(...))QGraphicsWidget::getContentsMargins +128 (int (*)(...))QGraphicsWidget::type +136 (int (*)(...))QGraphicsWidget::paint +144 (int (*)(...))QGraphicsWidget::paintWindowFrame +152 (int (*)(...))QGraphicsWidget::boundingRect +160 (int (*)(...))QGraphicsWidget::shape +168 (int (*)(...))QGraphicsWidget::initStyleOption +176 (int (*)(...))QGraphicsWidget::sizeHint +184 (int (*)(...))QGraphicsWidget::updateGeometry +192 (int (*)(...))QGraphicsWidget::itemChange +200 (int (*)(...))QGraphicsWidget::propertyChange +208 (int (*)(...))QGraphicsWidget::sceneEvent +216 (int (*)(...))QGraphicsWidget::windowFrameEvent +224 (int (*)(...))QGraphicsWidget::windowFrameSectionAt +232 (int (*)(...))QGraphicsWidget::changeEvent +240 (int (*)(...))QGraphicsWidget::closeEvent +248 (int (*)(...))QGraphicsWidget::focusInEvent +256 (int (*)(...))QGraphicsWidget::focusNextPrevChild +264 (int (*)(...))QGraphicsWidget::focusOutEvent +272 (int (*)(...))QGraphicsWidget::hideEvent +280 (int (*)(...))QGraphicsWidget::moveEvent +288 (int (*)(...))QGraphicsWidget::polishEvent +296 (int (*)(...))QGraphicsWidget::resizeEvent +304 (int (*)(...))QGraphicsWidget::showEvent +312 (int (*)(...))QGraphicsWidget::hoverMoveEvent +320 (int (*)(...))QGraphicsWidget::hoverLeaveEvent +328 (int (*)(...))QGraphicsWidget::grabMouseEvent +336 (int (*)(...))QGraphicsWidget::ungrabMouseEvent +344 (int (*)(...))QGraphicsWidget::grabKeyboardEvent +352 (int (*)(...))QGraphicsWidget::ungrabKeyboardEvent +360 (int (*)(...))-16 +368 (int (*)(...))(& _ZTI15QGraphicsWidget) +376 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidgetD1Ev +384 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidgetD0Ev +392 (int (*)(...))QGraphicsItem::advance +400 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget12boundingRectEv +408 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget5shapeEv +416 (int (*)(...))QGraphicsItem::contains +424 (int (*)(...))QGraphicsItem::collidesWithItem +432 (int (*)(...))QGraphicsItem::collidesWithPath +440 (int (*)(...))QGraphicsItem::isObscuredBy +448 (int (*)(...))QGraphicsItem::opaqueArea +456 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget5paintEP8QPainterPK24QStyleOptionGraphicsItemP7QWidget +464 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget4typeEv +472 (int (*)(...))QGraphicsItem::sceneEventFilter +480 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget10sceneEventEP6QEvent +488 (int (*)(...))QGraphicsItem::contextMenuEvent +496 (int (*)(...))QGraphicsItem::dragEnterEvent +504 (int (*)(...))QGraphicsItem::dragLeaveEvent +512 (int (*)(...))QGraphicsItem::dragMoveEvent +520 (int (*)(...))QGraphicsItem::dropEvent +528 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget12focusInEventEP11QFocusEvent +536 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget13focusOutEventEP11QFocusEvent +544 (int (*)(...))QGraphicsItem::hoverEnterEvent +552 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget14hoverMoveEventEP24QGraphicsSceneHoverEvent +560 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget15hoverLeaveEventEP24QGraphicsSceneHoverEvent +568 (int (*)(...))QGraphicsItem::keyPressEvent +576 (int (*)(...))QGraphicsItem::keyReleaseEvent +584 (int (*)(...))QGraphicsItem::mousePressEvent +592 (int (*)(...))QGraphicsItem::mouseMoveEvent +600 (int (*)(...))QGraphicsItem::mouseReleaseEvent +608 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent +616 (int (*)(...))QGraphicsItem::wheelEvent +624 (int (*)(...))QGraphicsItem::inputMethodEvent +632 (int (*)(...))QGraphicsItem::inputMethodQuery +640 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget10itemChangeEN13QGraphicsItem18GraphicsItemChangeERK8QVariant +648 (int (*)(...))QGraphicsItem::supportsExtension +656 (int (*)(...))QGraphicsItem::setExtension +664 (int (*)(...))QGraphicsItem::extension +672 (int (*)(...))-32 +680 (int (*)(...))(& _ZTI15QGraphicsWidget) +688 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidgetD1Ev +696 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidgetD0Ev +704 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidget11setGeometryERK6QRectF +712 (int (*)(...))QGraphicsWidget::_ZThn32_NK15QGraphicsWidget18getContentsMarginsEPdS0_S0_S0_ +720 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidget14updateGeometryEv +728 (int (*)(...))QGraphicsWidget::_ZThn32_NK15QGraphicsWidget8sizeHintEN2Qt8SizeHintERK6QSizeF + +Class QGraphicsWidget + size=48 align=8 + base size=48 base align=8 +QGraphicsWidget (0x0x7f58e0e9f540) 0 + vptr=((& QGraphicsWidget::_ZTV15QGraphicsWidget) + 16u) + QGraphicsObject (0x0x7f58e0e9f5b0) 0 + primary-for QGraphicsWidget (0x0x7f58e0e9f540) + QObject (0x0x7f58dd8fc2a0) 0 + primary-for QGraphicsObject (0x0x7f58e0e9f5b0) + QGraphicsItem (0x0x7f58dd8fcba0) 16 + vptr=((& QGraphicsWidget::_ZTV15QGraphicsWidget) + 376u) + QGraphicsLayoutItem (0x0x7f58dd8fcc00) 32 + vptr=((& QGraphicsWidget::_ZTV15QGraphicsWidget) + 688u) + +Class QGraphicsProxyWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsProxyWidget::QPrivateSignal (0x0x7f58dd91eea0) 0 empty + +Vtable for QGraphicsProxyWidget +QGraphicsProxyWidget::_ZTV20QGraphicsProxyWidget: 107u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QGraphicsProxyWidget) +16 (int (*)(...))QGraphicsProxyWidget::metaObject +24 (int (*)(...))QGraphicsProxyWidget::qt_metacast +32 (int (*)(...))QGraphicsProxyWidget::qt_metacall +40 (int (*)(...))QGraphicsProxyWidget::~QGraphicsProxyWidget +48 (int (*)(...))QGraphicsProxyWidget::~QGraphicsProxyWidget +56 (int (*)(...))QGraphicsProxyWidget::event +64 (int (*)(...))QGraphicsProxyWidget::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsProxyWidget::setGeometry +120 (int (*)(...))QGraphicsWidget::getContentsMargins +128 (int (*)(...))QGraphicsProxyWidget::type +136 (int (*)(...))QGraphicsProxyWidget::paint +144 (int (*)(...))QGraphicsWidget::paintWindowFrame +152 (int (*)(...))QGraphicsWidget::boundingRect +160 (int (*)(...))QGraphicsWidget::shape +168 (int (*)(...))QGraphicsWidget::initStyleOption +176 (int (*)(...))QGraphicsProxyWidget::sizeHint +184 (int (*)(...))QGraphicsWidget::updateGeometry +192 (int (*)(...))QGraphicsProxyWidget::itemChange +200 (int (*)(...))QGraphicsWidget::propertyChange +208 (int (*)(...))QGraphicsWidget::sceneEvent +216 (int (*)(...))QGraphicsWidget::windowFrameEvent +224 (int (*)(...))QGraphicsWidget::windowFrameSectionAt +232 (int (*)(...))QGraphicsWidget::changeEvent +240 (int (*)(...))QGraphicsWidget::closeEvent +248 (int (*)(...))QGraphicsProxyWidget::focusInEvent +256 (int (*)(...))QGraphicsProxyWidget::focusNextPrevChild +264 (int (*)(...))QGraphicsProxyWidget::focusOutEvent +272 (int (*)(...))QGraphicsProxyWidget::hideEvent +280 (int (*)(...))QGraphicsWidget::moveEvent +288 (int (*)(...))QGraphicsWidget::polishEvent +296 (int (*)(...))QGraphicsProxyWidget::resizeEvent +304 (int (*)(...))QGraphicsProxyWidget::showEvent +312 (int (*)(...))QGraphicsProxyWidget::hoverMoveEvent +320 (int (*)(...))QGraphicsProxyWidget::hoverLeaveEvent +328 (int (*)(...))QGraphicsProxyWidget::grabMouseEvent +336 (int (*)(...))QGraphicsProxyWidget::ungrabMouseEvent +344 (int (*)(...))QGraphicsWidget::grabKeyboardEvent +352 (int (*)(...))QGraphicsWidget::ungrabKeyboardEvent +360 (int (*)(...))QGraphicsProxyWidget::contextMenuEvent +368 (int (*)(...))QGraphicsProxyWidget::dragEnterEvent +376 (int (*)(...))QGraphicsProxyWidget::dragLeaveEvent +384 (int (*)(...))QGraphicsProxyWidget::dragMoveEvent +392 (int (*)(...))QGraphicsProxyWidget::dropEvent +400 (int (*)(...))QGraphicsProxyWidget::hoverEnterEvent +408 (int (*)(...))QGraphicsProxyWidget::mouseMoveEvent +416 (int (*)(...))QGraphicsProxyWidget::mousePressEvent +424 (int (*)(...))QGraphicsProxyWidget::mouseReleaseEvent +432 (int (*)(...))QGraphicsProxyWidget::mouseDoubleClickEvent +440 (int (*)(...))QGraphicsProxyWidget::wheelEvent +448 (int (*)(...))QGraphicsProxyWidget::keyPressEvent +456 (int (*)(...))QGraphicsProxyWidget::keyReleaseEvent +464 (int (*)(...))QGraphicsProxyWidget::inputMethodQuery +472 (int (*)(...))QGraphicsProxyWidget::inputMethodEvent +480 (int (*)(...))-16 +488 (int (*)(...))(& _ZTI20QGraphicsProxyWidget) +496 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidgetD1Ev +504 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidgetD0Ev +512 (int (*)(...))QGraphicsItem::advance +520 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget12boundingRectEv +528 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget5shapeEv +536 (int (*)(...))QGraphicsItem::contains +544 (int (*)(...))QGraphicsItem::collidesWithItem +552 (int (*)(...))QGraphicsItem::collidesWithPath +560 (int (*)(...))QGraphicsItem::isObscuredBy +568 (int (*)(...))QGraphicsItem::opaqueArea +576 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget5paintEP8QPainterPK24QStyleOptionGraphicsItemP7QWidget +584 (int (*)(...))QGraphicsProxyWidget::_ZThn16_NK20QGraphicsProxyWidget4typeEv +592 (int (*)(...))QGraphicsItem::sceneEventFilter +600 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget10sceneEventEP6QEvent +608 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget16contextMenuEventEP30QGraphicsSceneContextMenuEvent +616 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget14dragEnterEventEP27QGraphicsSceneDragDropEvent +624 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget14dragLeaveEventEP27QGraphicsSceneDragDropEvent +632 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget13dragMoveEventEP27QGraphicsSceneDragDropEvent +640 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget9dropEventEP27QGraphicsSceneDragDropEvent +648 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget12focusInEventEP11QFocusEvent +656 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget13focusOutEventEP11QFocusEvent +664 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget15hoverEnterEventEP24QGraphicsSceneHoverEvent +672 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget14hoverMoveEventEP24QGraphicsSceneHoverEvent +680 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget15hoverLeaveEventEP24QGraphicsSceneHoverEvent +688 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget13keyPressEventEP9QKeyEvent +696 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget15keyReleaseEventEP9QKeyEvent +704 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget15mousePressEventEP24QGraphicsSceneMouseEvent +712 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget14mouseMoveEventEP24QGraphicsSceneMouseEvent +720 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget17mouseReleaseEventEP24QGraphicsSceneMouseEvent +728 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget21mouseDoubleClickEventEP24QGraphicsSceneMouseEvent +736 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget10wheelEventEP24QGraphicsSceneWheelEvent +744 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget16inputMethodEventEP17QInputMethodEvent +752 (int (*)(...))QGraphicsProxyWidget::_ZThn16_NK20QGraphicsProxyWidget16inputMethodQueryEN2Qt16InputMethodQueryE +760 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget10itemChangeEN13QGraphicsItem18GraphicsItemChangeERK8QVariant +768 (int (*)(...))QGraphicsItem::supportsExtension +776 (int (*)(...))QGraphicsItem::setExtension +784 (int (*)(...))QGraphicsItem::extension +792 (int (*)(...))-32 +800 (int (*)(...))(& _ZTI20QGraphicsProxyWidget) +808 (int (*)(...))QGraphicsProxyWidget::_ZThn32_N20QGraphicsProxyWidgetD1Ev +816 (int (*)(...))QGraphicsProxyWidget::_ZThn32_N20QGraphicsProxyWidgetD0Ev +824 (int (*)(...))QGraphicsProxyWidget::_ZThn32_N20QGraphicsProxyWidget11setGeometryERK6QRectF +832 (int (*)(...))QGraphicsWidget::_ZThn32_NK15QGraphicsWidget18getContentsMarginsEPdS0_S0_S0_ +840 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidget14updateGeometryEv +848 (int (*)(...))QGraphicsProxyWidget::_ZThn32_NK20QGraphicsProxyWidget8sizeHintEN2Qt8SizeHintERK6QSizeF + +Class QGraphicsProxyWidget + size=48 align=8 + base size=48 base align=8 +QGraphicsProxyWidget (0x0x7f58ddebcbc8) 0 + vptr=((& QGraphicsProxyWidget::_ZTV20QGraphicsProxyWidget) + 16u) + QGraphicsWidget (0x0x7f58e0e9fbd0) 0 + primary-for QGraphicsProxyWidget (0x0x7f58ddebcbc8) + QGraphicsObject (0x0x7f58e0e9fc40) 0 + primary-for QGraphicsWidget (0x0x7f58e0e9fbd0) + QObject (0x0x7f58dd91e5a0) 0 + primary-for QGraphicsObject (0x0x7f58e0e9fc40) + QGraphicsItem (0x0x7f58dd91ed80) 16 + vptr=((& QGraphicsProxyWidget::_ZTV20QGraphicsProxyWidget) + 496u) + QGraphicsLayoutItem (0x0x7f58dd91ede0) 32 + vptr=((& QGraphicsProxyWidget::_ZTV20QGraphicsProxyWidget) + 808u) + +Class QGraphicsScene::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsScene::QPrivateSignal (0x0x7f58dd132a80) 0 empty + +Vtable for QGraphicsScene +QGraphicsScene::_ZTV14QGraphicsScene: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QGraphicsScene) +16 (int (*)(...))QGraphicsScene::metaObject +24 (int (*)(...))QGraphicsScene::qt_metacast +32 (int (*)(...))QGraphicsScene::qt_metacall +40 (int (*)(...))QGraphicsScene::~QGraphicsScene +48 (int (*)(...))QGraphicsScene::~QGraphicsScene +56 (int (*)(...))QGraphicsScene::event +64 (int (*)(...))QGraphicsScene::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsScene::inputMethodQuery +120 (int (*)(...))QGraphicsScene::contextMenuEvent +128 (int (*)(...))QGraphicsScene::dragEnterEvent +136 (int (*)(...))QGraphicsScene::dragMoveEvent +144 (int (*)(...))QGraphicsScene::dragLeaveEvent +152 (int (*)(...))QGraphicsScene::dropEvent +160 (int (*)(...))QGraphicsScene::focusInEvent +168 (int (*)(...))QGraphicsScene::focusOutEvent +176 (int (*)(...))QGraphicsScene::helpEvent +184 (int (*)(...))QGraphicsScene::keyPressEvent +192 (int (*)(...))QGraphicsScene::keyReleaseEvent +200 (int (*)(...))QGraphicsScene::mousePressEvent +208 (int (*)(...))QGraphicsScene::mouseMoveEvent +216 (int (*)(...))QGraphicsScene::mouseReleaseEvent +224 (int (*)(...))QGraphicsScene::mouseDoubleClickEvent +232 (int (*)(...))QGraphicsScene::wheelEvent +240 (int (*)(...))QGraphicsScene::inputMethodEvent +248 (int (*)(...))QGraphicsScene::drawBackground +256 (int (*)(...))QGraphicsScene::drawForeground +264 (int (*)(...))QGraphicsScene::drawItems + +Class QGraphicsScene + size=16 align=8 + base size=16 base align=8 +QGraphicsScene (0x0x7f58ddebcdd0) 0 + vptr=((& QGraphicsScene::_ZTV14QGraphicsScene) + 16u) + QObject (0x0x7f58dd132660) 0 + primary-for QGraphicsScene (0x0x7f58ddebcdd0) + +Vtable for QGraphicsSceneEvent +QGraphicsSceneEvent::_ZTV19QGraphicsSceneEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QGraphicsSceneEvent) +16 (int (*)(...))QGraphicsSceneEvent::~QGraphicsSceneEvent +24 (int (*)(...))QGraphicsSceneEvent::~QGraphicsSceneEvent + +Class QGraphicsSceneEvent + size=32 align=8 + base size=32 base align=8 +QGraphicsSceneEvent (0x0x7f58ddf345b0) 0 + vptr=((& QGraphicsSceneEvent::_ZTV19QGraphicsSceneEvent) + 16u) + QEvent (0x0x7f58dce7fde0) 0 + primary-for QGraphicsSceneEvent (0x0x7f58ddf345b0) + +Vtable for QGraphicsSceneMouseEvent +QGraphicsSceneMouseEvent::_ZTV24QGraphicsSceneMouseEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QGraphicsSceneMouseEvent) +16 (int (*)(...))QGraphicsSceneMouseEvent::~QGraphicsSceneMouseEvent +24 (int (*)(...))QGraphicsSceneMouseEvent::~QGraphicsSceneMouseEvent + +Class QGraphicsSceneMouseEvent + size=32 align=8 + base size=32 base align=8 +QGraphicsSceneMouseEvent (0x0x7f58ddf34680) 0 + vptr=((& QGraphicsSceneMouseEvent::_ZTV24QGraphicsSceneMouseEvent) + 16u) + QGraphicsSceneEvent (0x0x7f58ddf346e8) 0 + primary-for QGraphicsSceneMouseEvent (0x0x7f58ddf34680) + QEvent (0x0x7f58dcea4a80) 0 + primary-for QGraphicsSceneEvent (0x0x7f58ddf346e8) + +Vtable for QGraphicsSceneWheelEvent +QGraphicsSceneWheelEvent::_ZTV24QGraphicsSceneWheelEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QGraphicsSceneWheelEvent) +16 (int (*)(...))QGraphicsSceneWheelEvent::~QGraphicsSceneWheelEvent +24 (int (*)(...))QGraphicsSceneWheelEvent::~QGraphicsSceneWheelEvent + +Class QGraphicsSceneWheelEvent + size=32 align=8 + base size=32 base align=8 +QGraphicsSceneWheelEvent (0x0x7f58ddf34750) 0 + vptr=((& QGraphicsSceneWheelEvent::_ZTV24QGraphicsSceneWheelEvent) + 16u) + QGraphicsSceneEvent (0x0x7f58ddf347b8) 0 + primary-for QGraphicsSceneWheelEvent (0x0x7f58ddf34750) + QEvent (0x0x7f58dcea4cc0) 0 + primary-for QGraphicsSceneEvent (0x0x7f58ddf347b8) + +Vtable for QGraphicsSceneContextMenuEvent +QGraphicsSceneContextMenuEvent::_ZTV30QGraphicsSceneContextMenuEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI30QGraphicsSceneContextMenuEvent) +16 (int (*)(...))QGraphicsSceneContextMenuEvent::~QGraphicsSceneContextMenuEvent +24 (int (*)(...))QGraphicsSceneContextMenuEvent::~QGraphicsSceneContextMenuEvent + +Class QGraphicsSceneContextMenuEvent + size=32 align=8 + base size=32 base align=8 +QGraphicsSceneContextMenuEvent (0x0x7f58ddf34820) 0 + vptr=((& QGraphicsSceneContextMenuEvent::_ZTV30QGraphicsSceneContextMenuEvent) + 16u) + QGraphicsSceneEvent (0x0x7f58ddf34888) 0 + primary-for QGraphicsSceneContextMenuEvent (0x0x7f58ddf34820) + QEvent (0x0x7f58dcea4d20) 0 + primary-for QGraphicsSceneEvent (0x0x7f58ddf34888) + +Vtable for QGraphicsSceneHoverEvent +QGraphicsSceneHoverEvent::_ZTV24QGraphicsSceneHoverEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QGraphicsSceneHoverEvent) +16 (int (*)(...))QGraphicsSceneHoverEvent::~QGraphicsSceneHoverEvent +24 (int (*)(...))QGraphicsSceneHoverEvent::~QGraphicsSceneHoverEvent + +Class QGraphicsSceneHoverEvent + size=32 align=8 + base size=32 base align=8 +QGraphicsSceneHoverEvent (0x0x7f58ddf348f0) 0 + vptr=((& QGraphicsSceneHoverEvent::_ZTV24QGraphicsSceneHoverEvent) + 16u) + QGraphicsSceneEvent (0x0x7f58ddf34958) 0 + primary-for QGraphicsSceneHoverEvent (0x0x7f58ddf348f0) + QEvent (0x0x7f58dc6f4f60) 0 + primary-for QGraphicsSceneEvent (0x0x7f58ddf34958) + +Vtable for QGraphicsSceneHelpEvent +QGraphicsSceneHelpEvent::_ZTV23QGraphicsSceneHelpEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGraphicsSceneHelpEvent) +16 (int (*)(...))QGraphicsSceneHelpEvent::~QGraphicsSceneHelpEvent +24 (int (*)(...))QGraphicsSceneHelpEvent::~QGraphicsSceneHelpEvent + +Class QGraphicsSceneHelpEvent + size=32 align=8 + base size=32 base align=8 +QGraphicsSceneHelpEvent (0x0x7f58ddf349c0) 0 + vptr=((& QGraphicsSceneHelpEvent::_ZTV23QGraphicsSceneHelpEvent) + 16u) + QGraphicsSceneEvent (0x0x7f58ddce6af8) 0 + primary-for QGraphicsSceneHelpEvent (0x0x7f58ddf349c0) + QEvent (0x0x7f58dc782000) 0 + primary-for QGraphicsSceneEvent (0x0x7f58ddce6af8) + +Vtable for QGraphicsSceneDragDropEvent +QGraphicsSceneDragDropEvent::_ZTV27QGraphicsSceneDragDropEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QGraphicsSceneDragDropEvent) +16 (int (*)(...))QGraphicsSceneDragDropEvent::~QGraphicsSceneDragDropEvent +24 (int (*)(...))QGraphicsSceneDragDropEvent::~QGraphicsSceneDragDropEvent + +Class QGraphicsSceneDragDropEvent + size=32 align=8 + base size=32 base align=8 +QGraphicsSceneDragDropEvent (0x0x7f58ddce6bc8) 0 + vptr=((& QGraphicsSceneDragDropEvent::_ZTV27QGraphicsSceneDragDropEvent) + 16u) + QGraphicsSceneEvent (0x0x7f58dda5c680) 0 + primary-for QGraphicsSceneDragDropEvent (0x0x7f58ddce6bc8) + QEvent (0x0x7f58dc782420) 0 + primary-for QGraphicsSceneEvent (0x0x7f58dda5c680) + +Vtable for QGraphicsSceneResizeEvent +QGraphicsSceneResizeEvent::_ZTV25QGraphicsSceneResizeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QGraphicsSceneResizeEvent) +16 (int (*)(...))QGraphicsSceneResizeEvent::~QGraphicsSceneResizeEvent +24 (int (*)(...))QGraphicsSceneResizeEvent::~QGraphicsSceneResizeEvent + +Class QGraphicsSceneResizeEvent + size=32 align=8 + base size=32 base align=8 +QGraphicsSceneResizeEvent (0x0x7f58dda5c6e8) 0 + vptr=((& QGraphicsSceneResizeEvent::_ZTV25QGraphicsSceneResizeEvent) + 16u) + QGraphicsSceneEvent (0x0x7f58dda5c750) 0 + primary-for QGraphicsSceneResizeEvent (0x0x7f58dda5c6e8) + QEvent (0x0x7f58dc782480) 0 + primary-for QGraphicsSceneEvent (0x0x7f58dda5c750) + +Vtable for QGraphicsSceneMoveEvent +QGraphicsSceneMoveEvent::_ZTV23QGraphicsSceneMoveEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QGraphicsSceneMoveEvent) +16 (int (*)(...))QGraphicsSceneMoveEvent::~QGraphicsSceneMoveEvent +24 (int (*)(...))QGraphicsSceneMoveEvent::~QGraphicsSceneMoveEvent + +Class QGraphicsSceneMoveEvent + size=32 align=8 + base size=32 base align=8 +QGraphicsSceneMoveEvent (0x0x7f58dda5c8f0) 0 + vptr=((& QGraphicsSceneMoveEvent::_ZTV23QGraphicsSceneMoveEvent) + 16u) + QGraphicsSceneEvent (0x0x7f58dda5c958) 0 + primary-for QGraphicsSceneMoveEvent (0x0x7f58dda5c8f0) + QEvent (0x0x7f58dc782ba0) 0 + primary-for QGraphicsSceneEvent (0x0x7f58dda5c958) + +Class QGraphicsTransform::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsTransform::QPrivateSignal (0x0x7f58dc7bc480) 0 empty + +Vtable for QGraphicsTransform +QGraphicsTransform::_ZTV18QGraphicsTransform: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QGraphicsTransform) +16 (int (*)(...))QGraphicsTransform::metaObject +24 (int (*)(...))QGraphicsTransform::qt_metacast +32 (int (*)(...))QGraphicsTransform::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QGraphicsTransform + size=16 align=8 + base size=16 base align=8 +QGraphicsTransform (0x0x7f58dda5c9c0) 0 + vptr=((& QGraphicsTransform::_ZTV18QGraphicsTransform) + 16u) + QObject (0x0x7f58dc782c00) 0 + primary-for QGraphicsTransform (0x0x7f58dda5c9c0) + +Class QGraphicsScale::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsScale::QPrivateSignal (0x0x7f58dc7bc600) 0 empty + +Vtable for QGraphicsScale +QGraphicsScale::_ZTV14QGraphicsScale: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QGraphicsScale) +16 (int (*)(...))QGraphicsScale::metaObject +24 (int (*)(...))QGraphicsScale::qt_metacast +32 (int (*)(...))QGraphicsScale::qt_metacall +40 (int (*)(...))QGraphicsScale::~QGraphicsScale +48 (int (*)(...))QGraphicsScale::~QGraphicsScale +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsScale::applyTo + +Class QGraphicsScale + size=16 align=8 + base size=16 base align=8 +QGraphicsScale (0x0x7f58dda5ca28) 0 + vptr=((& QGraphicsScale::_ZTV14QGraphicsScale) + 16u) + QGraphicsTransform (0x0x7f58dda5ca90) 0 + primary-for QGraphicsScale (0x0x7f58dda5ca28) + QObject (0x0x7f58dc7bc4e0) 0 + primary-for QGraphicsTransform (0x0x7f58dda5ca90) + +Class QGraphicsRotation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsRotation::QPrivateSignal (0x0x7f58dc7bc720) 0 empty + +Vtable for QGraphicsRotation +QGraphicsRotation::_ZTV17QGraphicsRotation: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QGraphicsRotation) +16 (int (*)(...))QGraphicsRotation::metaObject +24 (int (*)(...))QGraphicsRotation::qt_metacast +32 (int (*)(...))QGraphicsRotation::qt_metacall +40 (int (*)(...))QGraphicsRotation::~QGraphicsRotation +48 (int (*)(...))QGraphicsRotation::~QGraphicsRotation +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QGraphicsRotation::applyTo + +Class QGraphicsRotation + size=16 align=8 + base size=16 base align=8 +QGraphicsRotation (0x0x7f58dda5cd00) 0 + vptr=((& QGraphicsRotation::_ZTV17QGraphicsRotation) + 16u) + QGraphicsTransform (0x0x7f58dda5cd68) 0 + primary-for QGraphicsRotation (0x0x7f58dda5cd00) + QObject (0x0x7f58dc7bc660) 0 + primary-for QGraphicsTransform (0x0x7f58dda5cd68) + +Class QScrollArea::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QScrollArea::QPrivateSignal (0x0x7f58dc7bccc0) 0 empty + +Vtable for QScrollArea +QScrollArea::_ZTV11QScrollArea: 68u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QScrollArea) +16 (int (*)(...))QScrollArea::metaObject +24 (int (*)(...))QScrollArea::qt_metacast +32 (int (*)(...))QScrollArea::qt_metacall +40 (int (*)(...))QScrollArea::~QScrollArea +48 (int (*)(...))QScrollArea::~QScrollArea +56 (int (*)(...))QScrollArea::event +64 (int (*)(...))QScrollArea::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractScrollArea::mousePressEvent +176 (int (*)(...))QAbstractScrollArea::mouseReleaseEvent +184 (int (*)(...))QAbstractScrollArea::mouseDoubleClickEvent +192 (int (*)(...))QAbstractScrollArea::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractScrollArea::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractScrollArea::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QScrollArea::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractScrollArea::dragEnterEvent +320 (int (*)(...))QAbstractScrollArea::dragMoveEvent +328 (int (*)(...))QAbstractScrollArea::dragLeaveEvent +336 (int (*)(...))QAbstractScrollArea::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QScrollArea::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractScrollArea::viewportEvent +448 (int (*)(...))QScrollArea::scrollContentsBy +456 (int (*)(...))QScrollArea::viewportSizeHint +464 (int (*)(...))-16 +472 (int (*)(...))(& _ZTI11QScrollArea) +480 (int (*)(...))QScrollArea::_ZThn16_N11QScrollAreaD1Ev +488 (int (*)(...))QScrollArea::_ZThn16_N11QScrollAreaD0Ev +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QScrollArea + size=48 align=8 + base size=48 base align=8 +QScrollArea (0x0x7f58dda5cdd0) 0 + vptr=((& QScrollArea::_ZTV11QScrollArea) + 16u) + QAbstractScrollArea (0x0x7f58dda5cf70) 0 + primary-for QScrollArea (0x0x7f58dda5cdd0) + QFrame (0x0x7f58ddba0068) 0 + primary-for QAbstractScrollArea (0x0x7f58dda5cf70) + QWidget (0x0x7f58e0f12af0) 0 + primary-for QFrame (0x0x7f58ddba0068) + QObject (0x0x7f58dc7bcba0) 0 + primary-for QWidget (0x0x7f58e0f12af0) + QPaintDevice (0x0x7f58dc7bcc00) 16 + vptr=((& QScrollArea::_ZTV11QScrollArea) + 480u) + +Class QGraphicsView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGraphicsView::QPrivateSignal (0x0x7f58dc7bce40) 0 empty + +Vtable for QGraphicsView +QGraphicsView::_ZTV13QGraphicsView: 71u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QGraphicsView) +16 (int (*)(...))QGraphicsView::metaObject +24 (int (*)(...))QGraphicsView::qt_metacast +32 (int (*)(...))QGraphicsView::qt_metacall +40 (int (*)(...))QGraphicsView::~QGraphicsView +48 (int (*)(...))QGraphicsView::~QGraphicsView +56 (int (*)(...))QGraphicsView::event +64 (int (*)(...))QAbstractScrollArea::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QGraphicsView::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QGraphicsView::mousePressEvent +176 (int (*)(...))QGraphicsView::mouseReleaseEvent +184 (int (*)(...))QGraphicsView::mouseDoubleClickEvent +192 (int (*)(...))QGraphicsView::mouseMoveEvent +200 (int (*)(...))QGraphicsView::wheelEvent +208 (int (*)(...))QGraphicsView::keyPressEvent +216 (int (*)(...))QGraphicsView::keyReleaseEvent +224 (int (*)(...))QGraphicsView::focusInEvent +232 (int (*)(...))QGraphicsView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QGraphicsView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QGraphicsView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QGraphicsView::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QGraphicsView::dragEnterEvent +320 (int (*)(...))QGraphicsView::dragMoveEvent +328 (int (*)(...))QGraphicsView::dragLeaveEvent +336 (int (*)(...))QGraphicsView::dropEvent +344 (int (*)(...))QGraphicsView::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QGraphicsView::inputMethodEvent +416 (int (*)(...))QGraphicsView::inputMethodQuery +424 (int (*)(...))QGraphicsView::focusNextPrevChild +432 (int (*)(...))QGraphicsView::setupViewport +440 (int (*)(...))QGraphicsView::viewportEvent +448 (int (*)(...))QGraphicsView::scrollContentsBy +456 (int (*)(...))QAbstractScrollArea::viewportSizeHint +464 (int (*)(...))QGraphicsView::drawBackground +472 (int (*)(...))QGraphicsView::drawForeground +480 (int (*)(...))QGraphicsView::drawItems +488 (int (*)(...))-16 +496 (int (*)(...))(& _ZTI13QGraphicsView) +504 (int (*)(...))QGraphicsView::_ZThn16_N13QGraphicsViewD1Ev +512 (int (*)(...))QGraphicsView::_ZThn16_N13QGraphicsViewD0Ev +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QGraphicsView + size=48 align=8 + base size=48 base align=8 +QGraphicsView (0x0x7f58ddba0138) 0 + vptr=((& QGraphicsView::_ZTV13QGraphicsView) + 16u) + QAbstractScrollArea (0x0x7f58ddc413a8) 0 + primary-for QGraphicsView (0x0x7f58ddba0138) + QFrame (0x0x7f58ddc410d0) 0 + primary-for QAbstractScrollArea (0x0x7f58ddc413a8) + QWidget (0x0x7f58e0f12e00) 0 + primary-for QFrame (0x0x7f58ddc410d0) + QObject (0x0x7f58dc7bcd20) 0 + primary-for QWidget (0x0x7f58e0f12e00) + QPaintDevice (0x0x7f58dc7bcde0) 16 + vptr=((& QGraphicsView::_ZTV13QGraphicsView) + 504u) + +Class QGroupBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QGroupBox::QPrivateSignal (0x0x7f58dc50a660) 0 empty + +Vtable for QGroupBox +QGroupBox::_ZTV9QGroupBox: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QGroupBox) +16 (int (*)(...))QGroupBox::metaObject +24 (int (*)(...))QGroupBox::qt_metacast +32 (int (*)(...))QGroupBox::qt_metacall +40 (int (*)(...))QGroupBox::~QGroupBox +48 (int (*)(...))QGroupBox::~QGroupBox +56 (int (*)(...))QGroupBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QGroupBox::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QGroupBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QGroupBox::mousePressEvent +176 (int (*)(...))QGroupBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QGroupBox::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QGroupBox::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QGroupBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QGroupBox::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QGroupBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI9QGroupBox) +448 (int (*)(...))QGroupBox::_ZThn16_N9QGroupBoxD1Ev +456 (int (*)(...))QGroupBox::_ZThn16_N9QGroupBoxD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QGroupBox + size=48 align=8 + base size=48 base align=8 +QGroupBox (0x0x7f58dd8f3208) 0 + vptr=((& QGroupBox::_ZTV9QGroupBox) + 16u) + QWidget (0x0x7f58e100f700) 0 + primary-for QGroupBox (0x0x7f58dd8f3208) + QObject (0x0x7f58dc50a4e0) 0 + primary-for QWidget (0x0x7f58e100f700) + QPaintDevice (0x0x7f58dc50a600) 16 + vptr=((& QGroupBox::_ZTV9QGroupBox) + 448u) + +Class QHeaderView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHeaderView::QPrivateSignal (0x0x7f58dbe75cc0) 0 empty + +Vtable for QHeaderView +QHeaderView::_ZTV11QHeaderView: 108u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QHeaderView) +16 (int (*)(...))QHeaderView::metaObject +24 (int (*)(...))QHeaderView::qt_metacast +32 (int (*)(...))QHeaderView::qt_metacall +40 (int (*)(...))QHeaderView::~QHeaderView +48 (int (*)(...))QHeaderView::~QHeaderView +56 (int (*)(...))QHeaderView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QAbstractItemView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QHeaderView::setVisible +128 (int (*)(...))QHeaderView::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QHeaderView::mousePressEvent +176 (int (*)(...))QHeaderView::mouseReleaseEvent +184 (int (*)(...))QHeaderView::mouseDoubleClickEvent +192 (int (*)(...))QHeaderView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QHeaderView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractItemView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QAbstractItemView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QAbstractItemView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QHeaderView::viewportEvent +448 (int (*)(...))QHeaderView::scrollContentsBy +456 (int (*)(...))QAbstractItemView::viewportSizeHint +464 (int (*)(...))QHeaderView::setModel +472 (int (*)(...))QAbstractItemView::setSelectionModel +480 (int (*)(...))QAbstractItemView::keyboardSearch +488 (int (*)(...))QHeaderView::visualRect +496 (int (*)(...))QHeaderView::scrollTo +504 (int (*)(...))QHeaderView::indexAt +512 (int (*)(...))QAbstractItemView::sizeHintForRow +520 (int (*)(...))QAbstractItemView::sizeHintForColumn +528 (int (*)(...))QHeaderView::reset +536 (int (*)(...))QAbstractItemView::setRootIndex +544 (int (*)(...))QHeaderView::doItemsLayout +552 (int (*)(...))QAbstractItemView::selectAll +560 (int (*)(...))QHeaderView::dataChanged +568 (int (*)(...))QHeaderView::rowsInserted +576 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved +584 (int (*)(...))QAbstractItemView::selectionChanged +592 (int (*)(...))QHeaderView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QHeaderView::updateGeometries +624 (int (*)(...))QAbstractItemView::verticalScrollbarAction +632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction +640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))QHeaderView::moveCursor +688 (int (*)(...))QHeaderView::horizontalOffset +696 (int (*)(...))QHeaderView::verticalOffset +704 (int (*)(...))QHeaderView::isIndexHidden +712 (int (*)(...))QHeaderView::setSelection +720 (int (*)(...))QHeaderView::visualRegionForSelection +728 (int (*)(...))QAbstractItemView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QAbstractItemView::startDrag +760 (int (*)(...))QAbstractItemView::viewOptions +768 (int (*)(...))QHeaderView::paintSection +776 (int (*)(...))QHeaderView::sectionSizeFromContents +784 (int (*)(...))-16 +792 (int (*)(...))(& _ZTI11QHeaderView) +800 (int (*)(...))QHeaderView::_ZThn16_N11QHeaderViewD1Ev +808 (int (*)(...))QHeaderView::_ZThn16_N11QHeaderViewD0Ev +816 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +848 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +856 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QHeaderView + size=48 align=8 + base size=48 base align=8 +QHeaderView (0x0x7f58dd8f3270) 0 + vptr=((& QHeaderView::_ZTV11QHeaderView) + 16u) + QAbstractItemView (0x0x7f58dd8f3dd0) 0 + primary-for QHeaderView (0x0x7f58dd8f3270) + QAbstractScrollArea (0x0x7f58dd8f3e38) 0 + primary-for QAbstractItemView (0x0x7f58dd8f3dd0) + QFrame (0x0x7f58dd911000) 0 + primary-for QAbstractScrollArea (0x0x7f58dd8f3e38) + QWidget (0x0x7f58e100fc40) 0 + primary-for QFrame (0x0x7f58dd911000) + QObject (0x0x7f58dbe75180) 0 + primary-for QWidget (0x0x7f58e100fc40) + QPaintDevice (0x0x7f58dbe751e0) 16 + vptr=((& QHeaderView::_ZTV11QHeaderView) + 800u) + +Class QLineEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLineEdit::QPrivateSignal (0x0x7f58dbc69780) 0 empty + +Vtable for QLineEdit +QLineEdit::_ZTV9QLineEdit: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QLineEdit) +16 (int (*)(...))QLineEdit::metaObject +24 (int (*)(...))QLineEdit::qt_metacast +32 (int (*)(...))QLineEdit::qt_metacall +40 (int (*)(...))QLineEdit::~QLineEdit +48 (int (*)(...))QLineEdit::~QLineEdit +56 (int (*)(...))QLineEdit::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QLineEdit::sizeHint +136 (int (*)(...))QLineEdit::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QLineEdit::mousePressEvent +176 (int (*)(...))QLineEdit::mouseReleaseEvent +184 (int (*)(...))QLineEdit::mouseDoubleClickEvent +192 (int (*)(...))QLineEdit::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QLineEdit::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QLineEdit::focusInEvent +232 (int (*)(...))QLineEdit::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QLineEdit::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QLineEdit::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QLineEdit::dragEnterEvent +320 (int (*)(...))QLineEdit::dragMoveEvent +328 (int (*)(...))QLineEdit::dragLeaveEvent +336 (int (*)(...))QLineEdit::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QLineEdit::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QLineEdit::inputMethodEvent +416 (int (*)(...))QLineEdit::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI9QLineEdit) +448 (int (*)(...))QLineEdit::_ZThn16_N9QLineEditD1Ev +456 (int (*)(...))QLineEdit::_ZThn16_N9QLineEditD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QLineEdit + size=48 align=8 + base size=48 base align=8 +QLineEdit (0x0x7f58dd4f8af8) 0 + vptr=((& QLineEdit::_ZTV9QLineEdit) + 16u) + QWidget (0x0x7f58e1021a80) 0 + primary-for QLineEdit (0x0x7f58dd4f8af8) + QObject (0x0x7f58dbc69060) 0 + primary-for QWidget (0x0x7f58e1021a80) + QPaintDevice (0x0x7f58dbc69720) 16 + vptr=((& QLineEdit::_ZTV9QLineEdit) + 448u) + +Class QInputDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QInputDialog::QPrivateSignal (0x0x7f58dbc8d6c0) 0 empty + +Vtable for QInputDialog +QInputDialog::_ZTV12QInputDialog: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QInputDialog) +16 (int (*)(...))QInputDialog::metaObject +24 (int (*)(...))QInputDialog::qt_metacast +32 (int (*)(...))QInputDialog::qt_metacall +40 (int (*)(...))QInputDialog::~QInputDialog +48 (int (*)(...))QInputDialog::~QInputDialog +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QInputDialog::setVisible +128 (int (*)(...))QInputDialog::sizeHint +136 (int (*)(...))QInputDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QDialog::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QInputDialog::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI12QInputDialog) +488 (int (*)(...))QInputDialog::_ZThn16_N12QInputDialogD1Ev +496 (int (*)(...))QInputDialog::_ZThn16_N12QInputDialogD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QInputDialog + size=48 align=8 + base size=48 base align=8 +QInputDialog (0x0x7f58dd4f8b60) 0 + vptr=((& QInputDialog::_ZTV12QInputDialog) + 16u) + QDialog (0x0x7f58dd2ba3a8) 0 + primary-for QInputDialog (0x0x7f58dd4f8b60) + QWidget (0x0x7f58e102d380) 0 + primary-for QDialog (0x0x7f58dd2ba3a8) + QObject (0x0x7f58dbc69f00) 0 + primary-for QWidget (0x0x7f58e102d380) + QPaintDevice (0x0x7f58dbc69f60) 16 + vptr=((& QInputDialog::_ZTV12QInputDialog) + 488u) + +Class QItemDelegate::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemDelegate::QPrivateSignal (0x0x7f58dba525a0) 0 empty + +Vtable for QItemDelegate +QItemDelegate::_ZTV13QItemDelegate: 28u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QItemDelegate) +16 (int (*)(...))QItemDelegate::metaObject +24 (int (*)(...))QItemDelegate::qt_metacast +32 (int (*)(...))QItemDelegate::qt_metacall +40 (int (*)(...))QItemDelegate::~QItemDelegate +48 (int (*)(...))QItemDelegate::~QItemDelegate +56 (int (*)(...))QObject::event +64 (int (*)(...))QItemDelegate::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemDelegate::paint +120 (int (*)(...))QItemDelegate::sizeHint +128 (int (*)(...))QItemDelegate::createEditor +136 (int (*)(...))QAbstractItemDelegate::destroyEditor +144 (int (*)(...))QItemDelegate::setEditorData +152 (int (*)(...))QItemDelegate::setModelData +160 (int (*)(...))QItemDelegate::updateEditorGeometry +168 (int (*)(...))QItemDelegate::editorEvent +176 (int (*)(...))QAbstractItemDelegate::helpEvent +184 (int (*)(...))QAbstractItemDelegate::paintingRoles +192 (int (*)(...))QItemDelegate::drawDisplay +200 (int (*)(...))QItemDelegate::drawDecoration +208 (int (*)(...))QItemDelegate::drawFocus +216 (int (*)(...))QItemDelegate::drawCheck + +Class QItemDelegate + size=16 align=8 + base size=16 base align=8 +QItemDelegate (0x0x7f58dce6b068) 0 + vptr=((& QItemDelegate::_ZTV13QItemDelegate) + 16u) + QAbstractItemDelegate (0x0x7f58dce6baf8) 0 + primary-for QItemDelegate (0x0x7f58dce6b068) + QObject (0x0x7f58dba524e0) 0 + primary-for QAbstractItemDelegate (0x0x7f58dce6baf8) + +Vtable for QItemEditorCreatorBase +QItemEditorCreatorBase::_ZTV22QItemEditorCreatorBase: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI22QItemEditorCreatorBase) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QItemEditorCreatorBase + size=8 align=8 + base size=8 base align=8 +QItemEditorCreatorBase (0x0x7f58dba526c0) 0 nearly-empty + vptr=((& QItemEditorCreatorBase::_ZTV22QItemEditorCreatorBase) + 16u) + +Vtable for QItemEditorFactory +QItemEditorFactory::_ZTV18QItemEditorFactory: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QItemEditorFactory) +16 (int (*)(...))QItemEditorFactory::~QItemEditorFactory +24 (int (*)(...))QItemEditorFactory::~QItemEditorFactory +32 (int (*)(...))QItemEditorFactory::createEditor +40 (int (*)(...))QItemEditorFactory::valuePropertyName + +Class QItemEditorFactory + size=16 align=8 + base size=16 base align=8 +QItemEditorFactory (0x0x7f58dba52840) 0 + vptr=((& QItemEditorFactory::_ZTV18QItemEditorFactory) + 16u) + +Class QKeyEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QKeyEventTransition::QPrivateSignal (0x0x7f58dba52ba0) 0 empty + +Vtable for QKeyEventTransition +QKeyEventTransition::_ZTV19QKeyEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QKeyEventTransition) +16 (int (*)(...))QKeyEventTransition::metaObject +24 (int (*)(...))QKeyEventTransition::qt_metacast +32 (int (*)(...))QKeyEventTransition::qt_metacall +40 (int (*)(...))QKeyEventTransition::~QKeyEventTransition +48 (int (*)(...))QKeyEventTransition::~QKeyEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QKeyEventTransition::eventTest +120 (int (*)(...))QKeyEventTransition::onTransition + +Class QKeyEventTransition + size=16 align=8 + base size=16 base align=8 +QKeyEventTransition (0x0x7f58dce917b8) 0 + vptr=((& QKeyEventTransition::_ZTV19QKeyEventTransition) + 16u) + QEventTransition (0x0x7f58dce91b60) 0 + primary-for QKeyEventTransition (0x0x7f58dce917b8) + QAbstractTransition (0x0x7f58dce91bc8) 0 + primary-for QEventTransition (0x0x7f58dce91b60) + QObject (0x0x7f58dba52ae0) 0 + primary-for QAbstractTransition (0x0x7f58dce91bc8) + +Class QKeySequenceEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QKeySequenceEdit::QPrivateSignal (0x0x7f58db66b5a0) 0 empty + +Vtable for QKeySequenceEdit +QKeySequenceEdit::_ZTV16QKeySequenceEdit: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QKeySequenceEdit) +16 (int (*)(...))QKeySequenceEdit::metaObject +24 (int (*)(...))QKeySequenceEdit::qt_metacast +32 (int (*)(...))QKeySequenceEdit::qt_metacall +40 (int (*)(...))QKeySequenceEdit::~QKeySequenceEdit +48 (int (*)(...))QKeySequenceEdit::~QKeySequenceEdit +56 (int (*)(...))QKeySequenceEdit::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QKeySequenceEdit::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QKeySequenceEdit::keyPressEvent +216 (int (*)(...))QKeySequenceEdit::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI16QKeySequenceEdit) +448 (int (*)(...))QKeySequenceEdit::_ZThn16_N16QKeySequenceEditD1Ev +456 (int (*)(...))QKeySequenceEdit::_ZThn16_N16QKeySequenceEditD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QKeySequenceEdit + size=48 align=8 + base size=48 base align=8 +QKeySequenceEdit (0x0x7f58dceaa750) 0 + vptr=((& QKeySequenceEdit::_ZTV16QKeySequenceEdit) + 16u) + QWidget (0x0x7f58e1060690) 0 + primary-for QKeySequenceEdit (0x0x7f58dceaa750) + QObject (0x0x7f58dba0da20) 0 + primary-for QWidget (0x0x7f58e1060690) + QPaintDevice (0x0x7f58dba0da80) 16 + vptr=((& QKeySequenceEdit::_ZTV16QKeySequenceEdit) + 448u) + +Class QLabel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLabel::QPrivateSignal (0x0x7f58db696240) 0 empty + +Vtable for QLabel +QLabel::_ZTV6QLabel: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QLabel) +16 (int (*)(...))QLabel::metaObject +24 (int (*)(...))QLabel::qt_metacast +32 (int (*)(...))QLabel::qt_metacall +40 (int (*)(...))QLabel::~QLabel +48 (int (*)(...))QLabel::~QLabel +56 (int (*)(...))QLabel::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QLabel::sizeHint +136 (int (*)(...))QLabel::minimumSizeHint +144 (int (*)(...))QLabel::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QLabel::mousePressEvent +176 (int (*)(...))QLabel::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QLabel::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QLabel::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QLabel::focusInEvent +232 (int (*)(...))QLabel::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QLabel::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QLabel::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QLabel::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QLabel::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI6QLabel) +448 (int (*)(...))QLabel::_ZThn16_N6QLabelD1Ev +456 (int (*)(...))QLabel::_ZThn16_N6QLabelD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QLabel + size=48 align=8 + base size=48 base align=8 +QLabel (0x0x7f58dceaa7b8) 0 + vptr=((& QLabel::_ZTV6QLabel) + 16u) + QFrame (0x0x7f58dcecd548) 0 + primary-for QLabel (0x0x7f58dceaa7b8) + QWidget (0x0x7f58e1060af0) 0 + primary-for QFrame (0x0x7f58dcecd548) + QObject (0x0x7f58db66b600) 0 + primary-for QWidget (0x0x7f58e1060af0) + QPaintDevice (0x0x7f58db6961e0) 16 + vptr=((& QLabel::_ZTV6QLabel) + 448u) + +Class QLCDNumber::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLCDNumber::QPrivateSignal (0x0x7f58db5748a0) 0 empty + +Vtable for QLCDNumber +QLCDNumber::_ZTV10QLCDNumber: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QLCDNumber) +16 (int (*)(...))QLCDNumber::metaObject +24 (int (*)(...))QLCDNumber::qt_metacast +32 (int (*)(...))QLCDNumber::qt_metacall +40 (int (*)(...))QLCDNumber::~QLCDNumber +48 (int (*)(...))QLCDNumber::~QLCDNumber +56 (int (*)(...))QLCDNumber::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QLCDNumber::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QLCDNumber::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI10QLCDNumber) +448 (int (*)(...))QLCDNumber::_ZThn16_N10QLCDNumberD1Ev +456 (int (*)(...))QLCDNumber::_ZThn16_N10QLCDNumberD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QLCDNumber + size=48 align=8 + base size=48 base align=8 +QLCDNumber (0x0x7f58dcecd6e8) 0 + vptr=((& QLCDNumber::_ZTV10QLCDNumber) + 16u) + QFrame (0x0x7f58dcecd750) 0 + primary-for QLCDNumber (0x0x7f58dcecd6e8) + QWidget (0x0x7f58e1060ee0) 0 + primary-for QFrame (0x0x7f58dcecd750) + QObject (0x0x7f58db574420) 0 + primary-for QWidget (0x0x7f58e1060ee0) + QPaintDevice (0x0x7f58db574480) 16 + vptr=((& QLCDNumber::_ZTV10QLCDNumber) + 448u) + +Class QListView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QListView::QPrivateSignal (0x0x7f58db574c60) 0 empty + +Vtable for QListView +QListView::_ZTV9QListView: 106u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QListView) +16 (int (*)(...))QListView::metaObject +24 (int (*)(...))QListView::qt_metacast +32 (int (*)(...))QListView::qt_metacall +40 (int (*)(...))QListView::~QListView +48 (int (*)(...))QListView::~QListView +56 (int (*)(...))QListView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QListView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QListView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QListView::mouseMoveEvent +200 (int (*)(...))QListView::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QListView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QListView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QListView::dragMoveEvent +328 (int (*)(...))QListView::dragLeaveEvent +336 (int (*)(...))QListView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractItemView::viewportEvent +448 (int (*)(...))QListView::scrollContentsBy +456 (int (*)(...))QListView::viewportSizeHint +464 (int (*)(...))QAbstractItemView::setModel +472 (int (*)(...))QAbstractItemView::setSelectionModel +480 (int (*)(...))QAbstractItemView::keyboardSearch +488 (int (*)(...))QListView::visualRect +496 (int (*)(...))QListView::scrollTo +504 (int (*)(...))QListView::indexAt +512 (int (*)(...))QAbstractItemView::sizeHintForRow +520 (int (*)(...))QAbstractItemView::sizeHintForColumn +528 (int (*)(...))QListView::reset +536 (int (*)(...))QListView::setRootIndex +544 (int (*)(...))QListView::doItemsLayout +552 (int (*)(...))QAbstractItemView::selectAll +560 (int (*)(...))QListView::dataChanged +568 (int (*)(...))QListView::rowsInserted +576 (int (*)(...))QListView::rowsAboutToBeRemoved +584 (int (*)(...))QListView::selectionChanged +592 (int (*)(...))QListView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QListView::updateGeometries +624 (int (*)(...))QAbstractItemView::verticalScrollbarAction +632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction +640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))QListView::moveCursor +688 (int (*)(...))QListView::horizontalOffset +696 (int (*)(...))QListView::verticalOffset +704 (int (*)(...))QListView::isIndexHidden +712 (int (*)(...))QListView::setSelection +720 (int (*)(...))QListView::visualRegionForSelection +728 (int (*)(...))QListView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QListView::startDrag +760 (int (*)(...))QListView::viewOptions +768 (int (*)(...))-16 +776 (int (*)(...))(& _ZTI9QListView) +784 (int (*)(...))QListView::_ZThn16_N9QListViewD1Ev +792 (int (*)(...))QListView::_ZThn16_N9QListViewD0Ev +800 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +808 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +816 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QListView + size=48 align=8 + base size=48 base align=8 +QListView (0x0x7f58dcecd7b8) 0 + vptr=((& QListView::_ZTV9QListView) + 16u) + QAbstractItemView (0x0x7f58dcb517b8) 0 + primary-for QListView (0x0x7f58dcecd7b8) + QAbstractScrollArea (0x0x7f58dc8f43a8) 0 + primary-for QAbstractItemView (0x0x7f58dcb517b8) + QFrame (0x0x7f58dc8f4548) 0 + primary-for QAbstractScrollArea (0x0x7f58dc8f43a8) + QWidget (0x0x7f58e0c87770) 0 + primary-for QFrame (0x0x7f58dc8f4548) + QObject (0x0x7f58db574900) 0 + primary-for QWidget (0x0x7f58e0c87770) + QPaintDevice (0x0x7f58db574c00) 16 + vptr=((& QListView::_ZTV9QListView) + 784u) + +Vtable for QListWidgetItem +QListWidgetItem::_ZTV15QListWidgetItem: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QListWidgetItem) +16 (int (*)(...))QListWidgetItem::~QListWidgetItem +24 (int (*)(...))QListWidgetItem::~QListWidgetItem +32 (int (*)(...))QListWidgetItem::clone +40 (int (*)(...))QListWidgetItem::setBackgroundColor +48 (int (*)(...))QListWidgetItem::data +56 (int (*)(...))QListWidgetItem::setData +64 (int (*)(...))QListWidgetItem::operator< +72 (int (*)(...))QListWidgetItem::read +80 (int (*)(...))QListWidgetItem::write + +Class QListWidgetItem + size=48 align=8 + base size=44 base align=8 +QListWidgetItem (0x0x7f58db574de0) 0 + vptr=((& QListWidgetItem::_ZTV15QListWidgetItem) + 16u) + +Class QListWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QListWidget::QPrivateSignal (0x0x7f58db5d7c60) 0 empty + +Vtable for QListWidget +QListWidget::_ZTV11QListWidget: 110u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QListWidget) +16 (int (*)(...))QListWidget::metaObject +24 (int (*)(...))QListWidget::qt_metacast +32 (int (*)(...))QListWidget::qt_metacall +40 (int (*)(...))QListWidget::~QListWidget +48 (int (*)(...))QListWidget::~QListWidget +56 (int (*)(...))QListWidget::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QListView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QListView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QListView::mouseMoveEvent +200 (int (*)(...))QListView::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QListView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QListView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QListView::dragMoveEvent +328 (int (*)(...))QListView::dragLeaveEvent +336 (int (*)(...))QListWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractItemView::viewportEvent +448 (int (*)(...))QListView::scrollContentsBy +456 (int (*)(...))QListView::viewportSizeHint +464 (int (*)(...))QListWidget::setModel +472 (int (*)(...))QListWidget::setSelectionModel +480 (int (*)(...))QAbstractItemView::keyboardSearch +488 (int (*)(...))QListView::visualRect +496 (int (*)(...))QListView::scrollTo +504 (int (*)(...))QListView::indexAt +512 (int (*)(...))QAbstractItemView::sizeHintForRow +520 (int (*)(...))QAbstractItemView::sizeHintForColumn +528 (int (*)(...))QListView::reset +536 (int (*)(...))QListView::setRootIndex +544 (int (*)(...))QListView::doItemsLayout +552 (int (*)(...))QAbstractItemView::selectAll +560 (int (*)(...))QListView::dataChanged +568 (int (*)(...))QListView::rowsInserted +576 (int (*)(...))QListView::rowsAboutToBeRemoved +584 (int (*)(...))QListView::selectionChanged +592 (int (*)(...))QListView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QListView::updateGeometries +624 (int (*)(...))QAbstractItemView::verticalScrollbarAction +632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction +640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))QListView::moveCursor +688 (int (*)(...))QListView::horizontalOffset +696 (int (*)(...))QListView::verticalOffset +704 (int (*)(...))QListView::isIndexHidden +712 (int (*)(...))QListView::setSelection +720 (int (*)(...))QListView::visualRegionForSelection +728 (int (*)(...))QListView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QListView::startDrag +760 (int (*)(...))QListView::viewOptions +768 (int (*)(...))QListWidget::mimeTypes +776 (int (*)(...))QListWidget::mimeData +784 (int (*)(...))QListWidget::dropMimeData +792 (int (*)(...))QListWidget::supportedDropActions +800 (int (*)(...))-16 +808 (int (*)(...))(& _ZTI11QListWidget) +816 (int (*)(...))QListWidget::_ZThn16_N11QListWidgetD1Ev +824 (int (*)(...))QListWidget::_ZThn16_N11QListWidgetD0Ev +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +848 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +856 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +864 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +872 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QListWidget + size=48 align=8 + base size=48 base align=8 +QListWidget (0x0x7f58dc8f4888) 0 + vptr=((& QListWidget::_ZTV11QListWidget) + 16u) + QListView (0x0x7f58dc70baf8) 0 + primary-for QListWidget (0x0x7f58dc8f4888) + QAbstractItemView (0x0x7f58dc70bb60) 0 + primary-for QListView (0x0x7f58dc70baf8) + QAbstractScrollArea (0x0x7f58dc7926e8) 0 + primary-for QAbstractItemView (0x0x7f58dc70bb60) + QFrame (0x0x7f58dc7d6478) 0 + primary-for QAbstractScrollArea (0x0x7f58dc7926e8) + QWidget (0x0x7f58e0d45380) 0 + primary-for QFrame (0x0x7f58dc7d6478) + QObject (0x0x7f58db5d7060) 0 + primary-for QWidget (0x0x7f58e0d45380) + QPaintDevice (0x0x7f58db5d7c00) 16 + vptr=((& QListWidget::_ZTV11QListWidget) + 816u) + +Class QMainWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMainWindow::QPrivateSignal (0x0x7f58db1fdae0) 0 empty + +Vtable for QMainWindow +QMainWindow::_ZTV11QMainWindow: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QMainWindow) +16 (int (*)(...))QMainWindow::metaObject +24 (int (*)(...))QMainWindow::qt_metacast +32 (int (*)(...))QMainWindow::qt_metacall +40 (int (*)(...))QMainWindow::~QMainWindow +48 (int (*)(...))QMainWindow::~QMainWindow +56 (int (*)(...))QMainWindow::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QMainWindow::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QMainWindow::createPopupMenu +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI11QMainWindow) +456 (int (*)(...))QMainWindow::_ZThn16_N11QMainWindowD1Ev +464 (int (*)(...))QMainWindow::_ZThn16_N11QMainWindowD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QMainWindow + size=48 align=8 + base size=48 base align=8 +QMainWindow (0x0x7f58dc7d64e0) 0 + vptr=((& QMainWindow::_ZTV11QMainWindow) + 16u) + QWidget (0x0x7f58e0d45d20) 0 + primary-for QMainWindow (0x0x7f58dc7d64e0) + QObject (0x0x7f58db1fd840) 0 + primary-for QWidget (0x0x7f58e0d45d20) + QPaintDevice (0x0x7f58db1fd8a0) 16 + vptr=((& QMainWindow::_ZTV11QMainWindow) + 456u) + +Class QMdiArea::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMdiArea::QPrivateSignal (0x0x7f58db0e0a20) 0 empty + +Vtable for QMdiArea +QMdiArea::_ZTV8QMdiArea: 68u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QMdiArea) +16 (int (*)(...))QMdiArea::metaObject +24 (int (*)(...))QMdiArea::qt_metacast +32 (int (*)(...))QMdiArea::qt_metacall +40 (int (*)(...))QMdiArea::~QMdiArea +48 (int (*)(...))QMdiArea::~QMdiArea +56 (int (*)(...))QMdiArea::event +64 (int (*)(...))QMdiArea::eventFilter +72 (int (*)(...))QMdiArea::timerEvent +80 (int (*)(...))QMdiArea::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QMdiArea::sizeHint +136 (int (*)(...))QMdiArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractScrollArea::mousePressEvent +176 (int (*)(...))QAbstractScrollArea::mouseReleaseEvent +184 (int (*)(...))QAbstractScrollArea::mouseDoubleClickEvent +192 (int (*)(...))QAbstractScrollArea::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractScrollArea::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QMdiArea::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QMdiArea::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractScrollArea::dragEnterEvent +320 (int (*)(...))QAbstractScrollArea::dragMoveEvent +328 (int (*)(...))QAbstractScrollArea::dragLeaveEvent +336 (int (*)(...))QAbstractScrollArea::dropEvent +344 (int (*)(...))QMdiArea::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QMdiArea::setupViewport +440 (int (*)(...))QMdiArea::viewportEvent +448 (int (*)(...))QMdiArea::scrollContentsBy +456 (int (*)(...))QAbstractScrollArea::viewportSizeHint +464 (int (*)(...))-16 +472 (int (*)(...))(& _ZTI8QMdiArea) +480 (int (*)(...))QMdiArea::_ZThn16_N8QMdiAreaD1Ev +488 (int (*)(...))QMdiArea::_ZThn16_N8QMdiAreaD0Ev +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QMdiArea + size=48 align=8 + base size=48 base align=8 +QMdiArea (0x0x7f58dc7d68f0) 0 + vptr=((& QMdiArea::_ZTV8QMdiArea) + 16u) + QAbstractScrollArea (0x0x7f58dc7d6bc8) 0 + primary-for QMdiArea (0x0x7f58dc7d68f0) + QFrame (0x0x7f58dc829dd0) 0 + primary-for QAbstractScrollArea (0x0x7f58dc7d6bc8) + QWidget (0x0x7f58e0d7f150) 0 + primary-for QFrame (0x0x7f58dc829dd0) + QObject (0x0x7f58db0e0780) 0 + primary-for QWidget (0x0x7f58e0d7f150) + QPaintDevice (0x0x7f58db0e0840) 16 + vptr=((& QMdiArea::_ZTV8QMdiArea) + 480u) + +Class QMdiSubWindow::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMdiSubWindow::QPrivateSignal (0x0x7f58db105900) 0 empty + +Vtable for QMdiSubWindow +QMdiSubWindow::_ZTV13QMdiSubWindow: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QMdiSubWindow) +16 (int (*)(...))QMdiSubWindow::metaObject +24 (int (*)(...))QMdiSubWindow::qt_metacast +32 (int (*)(...))QMdiSubWindow::qt_metacall +40 (int (*)(...))QMdiSubWindow::~QMdiSubWindow +48 (int (*)(...))QMdiSubWindow::~QMdiSubWindow +56 (int (*)(...))QMdiSubWindow::event +64 (int (*)(...))QMdiSubWindow::eventFilter +72 (int (*)(...))QMdiSubWindow::timerEvent +80 (int (*)(...))QMdiSubWindow::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QMdiSubWindow::sizeHint +136 (int (*)(...))QMdiSubWindow::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QMdiSubWindow::mousePressEvent +176 (int (*)(...))QMdiSubWindow::mouseReleaseEvent +184 (int (*)(...))QMdiSubWindow::mouseDoubleClickEvent +192 (int (*)(...))QMdiSubWindow::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QMdiSubWindow::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QMdiSubWindow::focusInEvent +232 (int (*)(...))QMdiSubWindow::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QMdiSubWindow::leaveEvent +256 (int (*)(...))QMdiSubWindow::paintEvent +264 (int (*)(...))QMdiSubWindow::moveEvent +272 (int (*)(...))QMdiSubWindow::resizeEvent +280 (int (*)(...))QMdiSubWindow::closeEvent +288 (int (*)(...))QMdiSubWindow::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QMdiSubWindow::showEvent +352 (int (*)(...))QMdiSubWindow::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QMdiSubWindow::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI13QMdiSubWindow) +448 (int (*)(...))QMdiSubWindow::_ZThn16_N13QMdiSubWindowD1Ev +456 (int (*)(...))QMdiSubWindow::_ZThn16_N13QMdiSubWindowD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QMdiSubWindow + size=48 align=8 + base size=48 base align=8 +QMdiSubWindow (0x0x7f58dc4d2680) 0 + vptr=((& QMdiSubWindow::_ZTV13QMdiSubWindow) + 16u) + QWidget (0x0x7f58e0e163f0) 0 + primary-for QMdiSubWindow (0x0x7f58dc4d2680) + QObject (0x0x7f58db105660) 0 + primary-for QWidget (0x0x7f58e0e163f0) + QPaintDevice (0x0x7f58db1058a0) 16 + vptr=((& QMdiSubWindow::_ZTV13QMdiSubWindow) + 448u) + +Class QMenu::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMenu::QPrivateSignal (0x0x7f58dae594e0) 0 empty + +Vtable for QMenu +QMenu::_ZTV5QMenu: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QMenu) +16 (int (*)(...))QMenu::metaObject +24 (int (*)(...))QMenu::qt_metacast +32 (int (*)(...))QMenu::qt_metacall +40 (int (*)(...))QMenu::~QMenu +48 (int (*)(...))QMenu::~QMenu +56 (int (*)(...))QMenu::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QMenu::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QMenu::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QMenu::mousePressEvent +176 (int (*)(...))QMenu::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QMenu::mouseMoveEvent +200 (int (*)(...))QMenu::wheelEvent +208 (int (*)(...))QMenu::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QMenu::enterEvent +248 (int (*)(...))QMenu::leaveEvent +256 (int (*)(...))QMenu::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QMenu::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QMenu::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QMenu::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QMenu::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI5QMenu) +448 (int (*)(...))QMenu::_ZThn16_N5QMenuD1Ev +456 (int (*)(...))QMenu::_ZThn16_N5QMenuD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QMenu + size=48 align=8 + base size=48 base align=8 +QMenu (0x0x7f58dc4d2d68) 0 + vptr=((& QMenu::_ZTV5QMenu) + 16u) + QWidget (0x0x7f58e0e25380) 0 + primary-for QMenu (0x0x7f58dc4d2d68) + QObject (0x0x7f58dae590c0) 0 + primary-for QWidget (0x0x7f58e0e25380) + QPaintDevice (0x0x7f58dae59480) 16 + vptr=((& QMenu::_ZTV5QMenu) + 448u) + +Class QMenuBar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMenuBar::QPrivateSignal (0x0x7f58dae7c0c0) 0 empty + +Vtable for QMenuBar +QMenuBar::_ZTV8QMenuBar: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QMenuBar) +16 (int (*)(...))QMenuBar::metaObject +24 (int (*)(...))QMenuBar::qt_metacast +32 (int (*)(...))QMenuBar::qt_metacall +40 (int (*)(...))QMenuBar::~QMenuBar +48 (int (*)(...))QMenuBar::~QMenuBar +56 (int (*)(...))QMenuBar::event +64 (int (*)(...))QMenuBar::eventFilter +72 (int (*)(...))QMenuBar::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QMenuBar::setVisible +128 (int (*)(...))QMenuBar::sizeHint +136 (int (*)(...))QMenuBar::minimumSizeHint +144 (int (*)(...))QMenuBar::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QMenuBar::mousePressEvent +176 (int (*)(...))QMenuBar::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QMenuBar::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QMenuBar::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QMenuBar::focusInEvent +232 (int (*)(...))QMenuBar::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QMenuBar::leaveEvent +256 (int (*)(...))QMenuBar::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QMenuBar::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QMenuBar::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QMenuBar::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI8QMenuBar) +448 (int (*)(...))QMenuBar::_ZThn16_N8QMenuBarD1Ev +456 (int (*)(...))QMenuBar::_ZThn16_N8QMenuBarD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QMenuBar + size=48 align=8 + base size=48 base align=8 +QMenuBar (0x0x7f58dc4d2ea0) 0 + vptr=((& QMenuBar::_ZTV8QMenuBar) + 16u) + QWidget (0x0x7f58e0e25c40) 0 + primary-for QMenuBar (0x0x7f58dc4d2ea0) + QObject (0x0x7f58dae59a20) 0 + primary-for QWidget (0x0x7f58e0e25c40) + QPaintDevice (0x0x7f58dae59a80) 16 + vptr=((& QMenuBar::_ZTV8QMenuBar) + 448u) + +Class QMessageBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMessageBox::QPrivateSignal (0x0x7f58dae7c9c0) 0 empty + +Vtable for QMessageBox +QMessageBox::_ZTV11QMessageBox: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QMessageBox) +16 (int (*)(...))QMessageBox::metaObject +24 (int (*)(...))QMessageBox::qt_metacast +32 (int (*)(...))QMessageBox::qt_metacall +40 (int (*)(...))QMessageBox::~QMessageBox +48 (int (*)(...))QMessageBox::~QMessageBox +56 (int (*)(...))QMessageBox::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QDialog::setVisible +128 (int (*)(...))QDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QMessageBox::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QMessageBox::resizeEvent +280 (int (*)(...))QMessageBox::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QMessageBox::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QMessageBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QDialog::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI11QMessageBox) +488 (int (*)(...))QMessageBox::_ZThn16_N11QMessageBoxD1Ev +496 (int (*)(...))QMessageBox::_ZThn16_N11QMessageBoxD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QMessageBox + size=48 align=8 + base size=48 base align=8 +QMessageBox (0x0x7f58dc536000) 0 + vptr=((& QMessageBox::_ZTV11QMessageBox) + 16u) + QDialog (0x0x7f58dc536068) 0 + primary-for QMessageBox (0x0x7f58dc536000) + QWidget (0x0x7f58e0e37690) 0 + primary-for QDialog (0x0x7f58dc536068) + QObject (0x0x7f58dae7c120) 0 + primary-for QWidget (0x0x7f58e0e37690) + QPaintDevice (0x0x7f58dae7c960) 16 + vptr=((& QMessageBox::_ZTV11QMessageBox) + 488u) + +Class QMouseEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMouseEventTransition::QPrivateSignal (0x0x7f58daed0120) 0 empty + +Vtable for QMouseEventTransition +QMouseEventTransition::_ZTV21QMouseEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QMouseEventTransition) +16 (int (*)(...))QMouseEventTransition::metaObject +24 (int (*)(...))QMouseEventTransition::qt_metacast +32 (int (*)(...))QMouseEventTransition::qt_metacall +40 (int (*)(...))QMouseEventTransition::~QMouseEventTransition +48 (int (*)(...))QMouseEventTransition::~QMouseEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMouseEventTransition::eventTest +120 (int (*)(...))QMouseEventTransition::onTransition + +Class QMouseEventTransition + size=16 align=8 + base size=16 base align=8 +QMouseEventTransition (0x0x7f58dc2d1a28) 0 + vptr=((& QMouseEventTransition::_ZTV21QMouseEventTransition) + 16u) + QEventTransition (0x0x7f58dc3f77b8) 0 + primary-for QMouseEventTransition (0x0x7f58dc2d1a28) + QAbstractTransition (0x0x7f58dc3f7a28) 0 + primary-for QEventTransition (0x0x7f58dc3f77b8) + QObject (0x0x7f58daed00c0) 0 + primary-for QAbstractTransition (0x0x7f58dc3f7a28) + +Class QOpenGLWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QOpenGLWidget::QPrivateSignal (0x0x7f58daed03c0) 0 empty + +Vtable for QOpenGLWidget +QOpenGLWidget::_ZTV13QOpenGLWidget: 67u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QOpenGLWidget) +16 (int (*)(...))QOpenGLWidget::metaObject +24 (int (*)(...))QOpenGLWidget::qt_metacast +32 (int (*)(...))QOpenGLWidget::qt_metacall +40 (int (*)(...))QOpenGLWidget::~QOpenGLWidget +48 (int (*)(...))QOpenGLWidget::~QOpenGLWidget +56 (int (*)(...))QOpenGLWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QOpenGLWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QOpenGLWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QOpenGLWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QOpenGLWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QOpenGLWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QOpenGLWidget::initializeGL +440 (int (*)(...))QOpenGLWidget::resizeGL +448 (int (*)(...))QOpenGLWidget::paintGL +456 (int (*)(...))-16 +464 (int (*)(...))(& _ZTI13QOpenGLWidget) +472 (int (*)(...))QOpenGLWidget::_ZThn16_N13QOpenGLWidgetD1Ev +480 (int (*)(...))QOpenGLWidget::_ZThn16_N13QOpenGLWidgetD0Ev +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +496 (int (*)(...))QOpenGLWidget::_ZThn16_NK13QOpenGLWidget11paintEngineEv +504 (int (*)(...))QOpenGLWidget::_ZThn16_NK13QOpenGLWidget6metricEN12QPaintDevice17PaintDeviceMetricE +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +520 (int (*)(...))QOpenGLWidget::_ZThn16_NK13QOpenGLWidget10redirectedEP6QPoint +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QOpenGLWidget + size=48 align=8 + base size=48 base align=8 +QOpenGLWidget (0x0x7f58dc3f7e38) 0 + vptr=((& QOpenGLWidget::_ZTV13QOpenGLWidget) + 16u) + QWidget (0x0x7f58e0c50540) 0 + primary-for QOpenGLWidget (0x0x7f58dc3f7e38) + QObject (0x0x7f58daed02a0) 0 + primary-for QWidget (0x0x7f58e0c50540) + QPaintDevice (0x0x7f58daed0300) 16 + vptr=((& QOpenGLWidget::_ZTV13QOpenGLWidget) + 472u) + +Class QTextEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextEdit::QPrivateSignal (0x0x7f58daed05a0) 0 empty + +Class QTextEdit::ExtraSelection + size=24 align=8 + base size=24 base align=8 +QTextEdit::ExtraSelection (0x0x7f58daed0600) 0 + +Vtable for QTextEdit +QTextEdit::_ZTV9QTextEdit: 73u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTextEdit) +16 (int (*)(...))QTextEdit::metaObject +24 (int (*)(...))QTextEdit::qt_metacast +32 (int (*)(...))QTextEdit::qt_metacall +40 (int (*)(...))QTextEdit::~QTextEdit +48 (int (*)(...))QTextEdit::~QTextEdit +56 (int (*)(...))QTextEdit::event +64 (int (*)(...))QAbstractScrollArea::eventFilter +72 (int (*)(...))QTextEdit::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QTextEdit::mousePressEvent +176 (int (*)(...))QTextEdit::mouseReleaseEvent +184 (int (*)(...))QTextEdit::mouseDoubleClickEvent +192 (int (*)(...))QTextEdit::mouseMoveEvent +200 (int (*)(...))QTextEdit::wheelEvent +208 (int (*)(...))QTextEdit::keyPressEvent +216 (int (*)(...))QTextEdit::keyReleaseEvent +224 (int (*)(...))QTextEdit::focusInEvent +232 (int (*)(...))QTextEdit::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTextEdit::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QTextEdit::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QTextEdit::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QTextEdit::dragEnterEvent +320 (int (*)(...))QTextEdit::dragMoveEvent +328 (int (*)(...))QTextEdit::dragLeaveEvent +336 (int (*)(...))QTextEdit::dropEvent +344 (int (*)(...))QTextEdit::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QTextEdit::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QTextEdit::inputMethodEvent +416 (int (*)(...))QTextEdit::inputMethodQuery +424 (int (*)(...))QTextEdit::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractScrollArea::viewportEvent +448 (int (*)(...))QTextEdit::scrollContentsBy +456 (int (*)(...))QAbstractScrollArea::viewportSizeHint +464 (int (*)(...))QTextEdit::loadResource +472 (int (*)(...))QTextEdit::createMimeDataFromSelection +480 (int (*)(...))QTextEdit::canInsertFromMimeData +488 (int (*)(...))QTextEdit::insertFromMimeData +496 (int (*)(...))QTextEdit::doSetTextCursor +504 (int (*)(...))-16 +512 (int (*)(...))(& _ZTI9QTextEdit) +520 (int (*)(...))QTextEdit::_ZThn16_N9QTextEditD1Ev +528 (int (*)(...))QTextEdit::_ZThn16_N9QTextEditD0Ev +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +568 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +576 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTextEdit + size=48 align=8 + base size=48 base align=8 +QTextEdit (0x0x7f58dbe7b340) 0 + vptr=((& QTextEdit::_ZTV9QTextEdit) + 16u) + QAbstractScrollArea (0x0x7f58dbe7b3a8) 0 + primary-for QTextEdit (0x0x7f58dbe7b340) + QFrame (0x0x7f58dbe7b680) 0 + primary-for QAbstractScrollArea (0x0x7f58dbe7b3a8) + QWidget (0x0x7f58e0c50a80) 0 + primary-for QFrame (0x0x7f58dbe7b680) + QObject (0x0x7f58daed0480) 0 + primary-for QWidget (0x0x7f58e0c50a80) + QPaintDevice (0x0x7f58daed04e0) 16 + vptr=((& QTextEdit::_ZTV9QTextEdit) + 520u) + +Class QPlainTextEdit::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPlainTextEdit::QPrivateSignal (0x0x7f58daef0ae0) 0 empty + +Vtable for QPlainTextEdit +QPlainTextEdit::_ZTV14QPlainTextEdit: 73u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QPlainTextEdit) +16 (int (*)(...))QPlainTextEdit::metaObject +24 (int (*)(...))QPlainTextEdit::qt_metacast +32 (int (*)(...))QPlainTextEdit::qt_metacall +40 (int (*)(...))QPlainTextEdit::~QPlainTextEdit +48 (int (*)(...))QPlainTextEdit::~QPlainTextEdit +56 (int (*)(...))QPlainTextEdit::event +64 (int (*)(...))QAbstractScrollArea::eventFilter +72 (int (*)(...))QPlainTextEdit::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QPlainTextEdit::mousePressEvent +176 (int (*)(...))QPlainTextEdit::mouseReleaseEvent +184 (int (*)(...))QPlainTextEdit::mouseDoubleClickEvent +192 (int (*)(...))QPlainTextEdit::mouseMoveEvent +200 (int (*)(...))QPlainTextEdit::wheelEvent +208 (int (*)(...))QPlainTextEdit::keyPressEvent +216 (int (*)(...))QPlainTextEdit::keyReleaseEvent +224 (int (*)(...))QPlainTextEdit::focusInEvent +232 (int (*)(...))QPlainTextEdit::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QPlainTextEdit::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QPlainTextEdit::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QPlainTextEdit::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QPlainTextEdit::dragEnterEvent +320 (int (*)(...))QPlainTextEdit::dragMoveEvent +328 (int (*)(...))QPlainTextEdit::dragLeaveEvent +336 (int (*)(...))QPlainTextEdit::dropEvent +344 (int (*)(...))QPlainTextEdit::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QPlainTextEdit::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QPlainTextEdit::inputMethodEvent +416 (int (*)(...))QPlainTextEdit::inputMethodQuery +424 (int (*)(...))QPlainTextEdit::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractScrollArea::viewportEvent +448 (int (*)(...))QPlainTextEdit::scrollContentsBy +456 (int (*)(...))QAbstractScrollArea::viewportSizeHint +464 (int (*)(...))QPlainTextEdit::loadResource +472 (int (*)(...))QPlainTextEdit::createMimeDataFromSelection +480 (int (*)(...))QPlainTextEdit::canInsertFromMimeData +488 (int (*)(...))QPlainTextEdit::insertFromMimeData +496 (int (*)(...))QPlainTextEdit::doSetTextCursor +504 (int (*)(...))-16 +512 (int (*)(...))(& _ZTI14QPlainTextEdit) +520 (int (*)(...))QPlainTextEdit::_ZThn16_N14QPlainTextEditD1Ev +528 (int (*)(...))QPlainTextEdit::_ZThn16_N14QPlainTextEditD0Ev +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +568 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +576 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QPlainTextEdit + size=48 align=8 + base size=48 base align=8 +QPlainTextEdit (0x0x7f58dbe7b8f0) 0 + vptr=((& QPlainTextEdit::_ZTV14QPlainTextEdit) + 16u) + QAbstractScrollArea (0x0x7f58dbe7ba90) 0 + primary-for QPlainTextEdit (0x0x7f58dbe7b8f0) + QFrame (0x0x7f58dbe7baf8) 0 + primary-for QAbstractScrollArea (0x0x7f58dbe7ba90) + QWidget (0x0x7f58e08ef000) 0 + primary-for QFrame (0x0x7f58dbe7baf8) + QObject (0x0x7f58daef0960) 0 + primary-for QWidget (0x0x7f58e08ef000) + QPaintDevice (0x0x7f58daef09c0) 16 + vptr=((& QPlainTextEdit::_ZTV14QPlainTextEdit) + 520u) + +Class QPlainTextDocumentLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPlainTextDocumentLayout::QPrivateSignal (0x0x7f58daef0d80) 0 empty + +Vtable for QPlainTextDocumentLayout +QPlainTextDocumentLayout::_ZTV24QPlainTextDocumentLayout: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QPlainTextDocumentLayout) +16 (int (*)(...))QPlainTextDocumentLayout::metaObject +24 (int (*)(...))QPlainTextDocumentLayout::qt_metacast +32 (int (*)(...))QPlainTextDocumentLayout::qt_metacall +40 (int (*)(...))QPlainTextDocumentLayout::~QPlainTextDocumentLayout +48 (int (*)(...))QPlainTextDocumentLayout::~QPlainTextDocumentLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPlainTextDocumentLayout::draw +120 (int (*)(...))QPlainTextDocumentLayout::hitTest +128 (int (*)(...))QPlainTextDocumentLayout::pageCount +136 (int (*)(...))QPlainTextDocumentLayout::documentSize +144 (int (*)(...))QPlainTextDocumentLayout::frameBoundingRect +152 (int (*)(...))QPlainTextDocumentLayout::blockBoundingRect +160 (int (*)(...))QPlainTextDocumentLayout::documentChanged +168 (int (*)(...))QAbstractTextDocumentLayout::resizeInlineObject +176 (int (*)(...))QAbstractTextDocumentLayout::positionInlineObject +184 (int (*)(...))QAbstractTextDocumentLayout::drawInlineObject + +Class QPlainTextDocumentLayout + size=16 align=8 + base size=16 base align=8 +QPlainTextDocumentLayout (0x0x7f58dbe7bb60) 0 + vptr=((& QPlainTextDocumentLayout::_ZTV24QPlainTextDocumentLayout) + 16u) + QAbstractTextDocumentLayout (0x0x7f58dbe9da90) 0 + primary-for QPlainTextDocumentLayout (0x0x7f58dbe7bb60) + QObject (0x0x7f58daef0b40) 0 + primary-for QAbstractTextDocumentLayout (0x0x7f58dbe9da90) + +Class QProgressBar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProgressBar::QPrivateSignal (0x0x7f58daf168a0) 0 empty + +Vtable for QProgressBar +QProgressBar::_ZTV12QProgressBar: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QProgressBar) +16 (int (*)(...))QProgressBar::metaObject +24 (int (*)(...))QProgressBar::qt_metacast +32 (int (*)(...))QProgressBar::qt_metacall +40 (int (*)(...))QProgressBar::~QProgressBar +48 (int (*)(...))QProgressBar::~QProgressBar +56 (int (*)(...))QProgressBar::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QProgressBar::sizeHint +136 (int (*)(...))QProgressBar::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QProgressBar::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QProgressBar::text +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI12QProgressBar) +456 (int (*)(...))QProgressBar::_ZThn16_N12QProgressBarD1Ev +464 (int (*)(...))QProgressBar::_ZThn16_N12QProgressBarD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QProgressBar + size=48 align=8 + base size=48 base align=8 +QProgressBar (0x0x7f58dbe9daf8) 0 + vptr=((& QProgressBar::_ZTV12QProgressBar) + 16u) + QWidget (0x0x7f58e090aa80) 0 + primary-for QProgressBar (0x0x7f58dbe9daf8) + QObject (0x0x7f58daef0de0) 0 + primary-for QWidget (0x0x7f58e090aa80) + QPaintDevice (0x0x7f58daf16840) 16 + vptr=((& QProgressBar::_ZTV12QProgressBar) + 456u) + +Class QProgressDialog::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProgressDialog::QPrivateSignal (0x0x7f58daf16ba0) 0 empty + +Vtable for QProgressDialog +QProgressDialog::_ZTV15QProgressDialog: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QProgressDialog) +16 (int (*)(...))QProgressDialog::metaObject +24 (int (*)(...))QProgressDialog::qt_metacast +32 (int (*)(...))QProgressDialog::qt_metacall +40 (int (*)(...))QProgressDialog::~QProgressDialog +48 (int (*)(...))QProgressDialog::~QProgressDialog +56 (int (*)(...))QWidget::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QDialog::setVisible +128 (int (*)(...))QProgressDialog::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QProgressDialog::resizeEvent +280 (int (*)(...))QProgressDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QProgressDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QProgressDialog::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QDialog::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI15QProgressDialog) +488 (int (*)(...))QProgressDialog::_ZThn16_N15QProgressDialogD1Ev +496 (int (*)(...))QProgressDialog::_ZThn16_N15QProgressDialogD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QProgressDialog + size=48 align=8 + base size=48 base align=8 +QProgressDialog (0x0x7f58dbe9dbc8) 0 + vptr=((& QProgressDialog::_ZTV15QProgressDialog) + 16u) + QDialog (0x0x7f58dbe9dc30) 0 + primary-for QProgressDialog (0x0x7f58dbe9dbc8) + QWidget (0x0x7f58e090af50) 0 + primary-for QDialog (0x0x7f58dbe9dc30) + QObject (0x0x7f58daf16960) 0 + primary-for QWidget (0x0x7f58e090af50) + QPaintDevice (0x0x7f58daf16b40) 16 + vptr=((& QProgressDialog::_ZTV15QProgressDialog) + 488u) + +Class QProxyStyle::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProxyStyle::QPrivateSignal (0x0x7f58daf40780) 0 empty + +Vtable for QProxyStyle +QProxyStyle::_ZTV11QProxyStyle: 37u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QProxyStyle) +16 (int (*)(...))QProxyStyle::metaObject +24 (int (*)(...))QProxyStyle::qt_metacast +32 (int (*)(...))QProxyStyle::qt_metacall +40 (int (*)(...))QProxyStyle::~QProxyStyle +48 (int (*)(...))QProxyStyle::~QProxyStyle +56 (int (*)(...))QProxyStyle::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProxyStyle::polish +120 (int (*)(...))QProxyStyle::unpolish +128 (int (*)(...))QProxyStyle::polish +136 (int (*)(...))QProxyStyle::unpolish +144 (int (*)(...))QProxyStyle::polish +152 (int (*)(...))QProxyStyle::itemTextRect +160 (int (*)(...))QProxyStyle::itemPixmapRect +168 (int (*)(...))QProxyStyle::drawItemText +176 (int (*)(...))QProxyStyle::drawItemPixmap +184 (int (*)(...))QProxyStyle::standardPalette +192 (int (*)(...))QProxyStyle::drawPrimitive +200 (int (*)(...))QProxyStyle::drawControl +208 (int (*)(...))QProxyStyle::subElementRect +216 (int (*)(...))QProxyStyle::drawComplexControl +224 (int (*)(...))QProxyStyle::hitTestComplexControl +232 (int (*)(...))QProxyStyle::subControlRect +240 (int (*)(...))QProxyStyle::pixelMetric +248 (int (*)(...))QProxyStyle::sizeFromContents +256 (int (*)(...))QProxyStyle::styleHint +264 (int (*)(...))QProxyStyle::standardPixmap +272 (int (*)(...))QProxyStyle::standardIcon +280 (int (*)(...))QProxyStyle::generatedIconPixmap +288 (int (*)(...))QProxyStyle::layoutSpacing + +Class QProxyStyle + size=16 align=8 + base size=16 base align=8 +QProxyStyle (0x0x7f58dbe9df70) 0 + vptr=((& QProxyStyle::_ZTV11QProxyStyle) + 16u) + QCommonStyle (0x0x7f58dbeb6000) 0 + primary-for QProxyStyle (0x0x7f58dbe9df70) + QStyle (0x0x7f58dbeb6618) 0 + primary-for QCommonStyle (0x0x7f58dbeb6000) + QObject (0x0x7f58daf40720) 0 + primary-for QStyle (0x0x7f58dbeb6618) + +Class QRadioButton::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QRadioButton::QPrivateSignal (0x0x7f58daf681e0) 0 empty + +Vtable for QRadioButton +QRadioButton::_ZTV12QRadioButton: 67u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QRadioButton) +16 (int (*)(...))QRadioButton::metaObject +24 (int (*)(...))QRadioButton::qt_metacast +32 (int (*)(...))QRadioButton::qt_metacall +40 (int (*)(...))QRadioButton::~QRadioButton +48 (int (*)(...))QRadioButton::~QRadioButton +56 (int (*)(...))QRadioButton::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractButton::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QRadioButton::sizeHint +136 (int (*)(...))QRadioButton::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractButton::mousePressEvent +176 (int (*)(...))QAbstractButton::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QRadioButton::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QAbstractButton::keyPressEvent +216 (int (*)(...))QAbstractButton::keyReleaseEvent +224 (int (*)(...))QAbstractButton::focusInEvent +232 (int (*)(...))QAbstractButton::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QRadioButton::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractButton::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QRadioButton::hitButton +440 (int (*)(...))QAbstractButton::checkStateSet +448 (int (*)(...))QAbstractButton::nextCheckState +456 (int (*)(...))-16 +464 (int (*)(...))(& _ZTI12QRadioButton) +472 (int (*)(...))QRadioButton::_ZThn16_N12QRadioButtonD1Ev +480 (int (*)(...))QRadioButton::_ZThn16_N12QRadioButtonD0Ev +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QRadioButton + size=48 align=8 + base size=48 base align=8 +QRadioButton (0x0x7f58dbeb6680) 0 + vptr=((& QRadioButton::_ZTV12QRadioButton) + 16u) + QAbstractButton (0x0x7f58dbeb69c0) 0 + primary-for QRadioButton (0x0x7f58dbeb6680) + QWidget (0x0x7f58e0968620) 0 + primary-for QAbstractButton (0x0x7f58dbeb69c0) + QObject (0x0x7f58daf680c0) 0 + primary-for QWidget (0x0x7f58e0968620) + QPaintDevice (0x0x7f58daf68120) 16 + vptr=((& QRadioButton::_ZTV12QRadioButton) + 472u) + +Class QScrollBar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QScrollBar::QPrivateSignal (0x0x7f58daf68a80) 0 empty + +Vtable for QScrollBar +QScrollBar::_ZTV10QScrollBar: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QScrollBar) +16 (int (*)(...))QScrollBar::metaObject +24 (int (*)(...))QScrollBar::qt_metacast +32 (int (*)(...))QScrollBar::qt_metacall +40 (int (*)(...))QScrollBar::~QScrollBar +48 (int (*)(...))QScrollBar::~QScrollBar +56 (int (*)(...))QScrollBar::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSlider::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QScrollBar::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QScrollBar::mousePressEvent +176 (int (*)(...))QScrollBar::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QScrollBar::mouseMoveEvent +200 (int (*)(...))QScrollBar::wheelEvent +208 (int (*)(...))QAbstractSlider::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QScrollBar::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QScrollBar::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QScrollBar::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSlider::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QScrollBar::sliderChange +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI10QScrollBar) +456 (int (*)(...))QScrollBar::_ZThn16_N10QScrollBarD1Ev +464 (int (*)(...))QScrollBar::_ZThn16_N10QScrollBarD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QScrollBar + size=48 align=8 + base size=48 base align=8 +QScrollBar (0x0x7f58dbeb6a28) 0 + vptr=((& QScrollBar::_ZTV10QScrollBar) + 16u) + QAbstractSlider (0x0x7f58dbed2a90) 0 + primary-for QScrollBar (0x0x7f58dbeb6a28) + QWidget (0x0x7f58e09689a0) 0 + primary-for QAbstractSlider (0x0x7f58dbed2a90) + QObject (0x0x7f58daf68960) 0 + primary-for QWidget (0x0x7f58e09689a0) + QPaintDevice (0x0x7f58daf689c0) 16 + vptr=((& QScrollBar::_ZTV10QScrollBar) + 456u) + +Vtable for QScrollerProperties +QScrollerProperties::_ZTV19QScrollerProperties: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QScrollerProperties) +16 (int (*)(...))QScrollerProperties::~QScrollerProperties +24 (int (*)(...))QScrollerProperties::~QScrollerProperties + +Class QScrollerProperties + size=16 align=8 + base size=16 base align=8 +QScrollerProperties (0x0x7f58daf8c3c0) 0 + vptr=((& QScrollerProperties::_ZTV19QScrollerProperties) + 16u) + +Class QScroller::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QScroller::QPrivateSignal (0x0x7f58dafba1e0) 0 empty + +Vtable for QScroller +QScroller::_ZTV9QScroller: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QScroller) +16 (int (*)(...))QScroller::metaObject +24 (int (*)(...))QScroller::qt_metacast +32 (int (*)(...))QScroller::qt_metacall +40 (int (*)(...))QScroller::~QScroller +48 (int (*)(...))QScroller::~QScroller +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QScroller + size=24 align=8 + base size=24 base align=8 +QScroller (0x0x7f58dbfdad68) 0 + vptr=((& QScroller::_ZTV9QScroller) + 16u) + QObject (0x0x7f58dafba180) 0 + primary-for QScroller (0x0x7f58dbfdad68) + +Class QShortcut::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QShortcut::QPrivateSignal (0x0x7f58dafdd5a0) 0 empty + +Vtable for QShortcut +QShortcut::_ZTV9QShortcut: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QShortcut) +16 (int (*)(...))QShortcut::metaObject +24 (int (*)(...))QShortcut::qt_metacast +32 (int (*)(...))QShortcut::qt_metacall +40 (int (*)(...))QShortcut::~QShortcut +48 (int (*)(...))QShortcut::~QShortcut +56 (int (*)(...))QShortcut::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QShortcut + size=16 align=8 + base size=16 base align=8 +QShortcut (0x0x7f58dbfdadd0) 0 + vptr=((& QShortcut::_ZTV9QShortcut) + 16u) + QObject (0x0x7f58dafdd540) 0 + primary-for QShortcut (0x0x7f58dbfdadd0) + +Class QSizeGrip::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSizeGrip::QPrivateSignal (0x0x7f58daa19a20) 0 empty + +Vtable for QSizeGrip +QSizeGrip::_ZTV9QSizeGrip: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSizeGrip) +16 (int (*)(...))QSizeGrip::metaObject +24 (int (*)(...))QSizeGrip::qt_metacast +32 (int (*)(...))QSizeGrip::qt_metacall +40 (int (*)(...))QSizeGrip::~QSizeGrip +48 (int (*)(...))QSizeGrip::~QSizeGrip +56 (int (*)(...))QSizeGrip::event +64 (int (*)(...))QSizeGrip::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QSizeGrip::setVisible +128 (int (*)(...))QSizeGrip::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QSizeGrip::mousePressEvent +176 (int (*)(...))QSizeGrip::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QSizeGrip::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QSizeGrip::paintEvent +264 (int (*)(...))QSizeGrip::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QSizeGrip::showEvent +352 (int (*)(...))QSizeGrip::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI9QSizeGrip) +448 (int (*)(...))QSizeGrip::_ZThn16_N9QSizeGripD1Ev +456 (int (*)(...))QSizeGrip::_ZThn16_N9QSizeGripD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QSizeGrip + size=48 align=8 + base size=48 base align=8 +QSizeGrip (0x0x7f58dbc7f340) 0 + vptr=((& QSizeGrip::_ZTV9QSizeGrip) + 16u) + QWidget (0x0x7f58e072c2a0) 0 + primary-for QSizeGrip (0x0x7f58dbc7f340) + QObject (0x0x7f58daa19300) 0 + primary-for QWidget (0x0x7f58e072c2a0) + QPaintDevice (0x0x7f58daa19360) 16 + vptr=((& QSizeGrip::_ZTV9QSizeGrip) + 448u) + +Class QSpinBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSpinBox::QPrivateSignal (0x0x7f58daa3f240) 0 empty + +Vtable for QSpinBox +QSpinBox::_ZTV8QSpinBox: 71u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QSpinBox) +16 (int (*)(...))QSpinBox::metaObject +24 (int (*)(...))QSpinBox::qt_metacast +32 (int (*)(...))QSpinBox::qt_metacall +40 (int (*)(...))QSpinBox::~QSpinBox +48 (int (*)(...))QSpinBox::~QSpinBox +56 (int (*)(...))QSpinBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSpinBox::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractSpinBox::sizeHint +136 (int (*)(...))QAbstractSpinBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractSpinBox::mousePressEvent +176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent +200 (int (*)(...))QAbstractSpinBox::wheelEvent +208 (int (*)(...))QAbstractSpinBox::keyPressEvent +216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent +224 (int (*)(...))QAbstractSpinBox::focusInEvent +232 (int (*)(...))QAbstractSpinBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractSpinBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractSpinBox::resizeEvent +280 (int (*)(...))QAbstractSpinBox::closeEvent +288 (int (*)(...))QAbstractSpinBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QAbstractSpinBox::showEvent +352 (int (*)(...))QAbstractSpinBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSpinBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QAbstractSpinBox::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QSpinBox::validate +440 (int (*)(...))QSpinBox::fixup +448 (int (*)(...))QAbstractSpinBox::stepBy +456 (int (*)(...))QAbstractSpinBox::clear +464 (int (*)(...))QAbstractSpinBox::stepEnabled +472 (int (*)(...))QSpinBox::valueFromText +480 (int (*)(...))QSpinBox::textFromValue +488 (int (*)(...))-16 +496 (int (*)(...))(& _ZTI8QSpinBox) +504 (int (*)(...))QSpinBox::_ZThn16_N8QSpinBoxD1Ev +512 (int (*)(...))QSpinBox::_ZThn16_N8QSpinBoxD0Ev +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QSpinBox + size=48 align=8 + base size=48 base align=8 +QSpinBox (0x0x7f58dbc7f3a8) 0 + vptr=((& QSpinBox::_ZTV8QSpinBox) + 16u) + QAbstractSpinBox (0x0x7f58dbc7fd00) 0 + primary-for QSpinBox (0x0x7f58dbc7f3a8) + QWidget (0x0x7f58e072c690) 0 + primary-for QAbstractSpinBox (0x0x7f58dbc7fd00) + QObject (0x0x7f58daa19a80) 0 + primary-for QWidget (0x0x7f58e072c690) + QPaintDevice (0x0x7f58daa3f1e0) 16 + vptr=((& QSpinBox::_ZTV8QSpinBox) + 504u) + +Class QDoubleSpinBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QDoubleSpinBox::QPrivateSignal (0x0x7f58daa3f780) 0 empty + +Vtable for QDoubleSpinBox +QDoubleSpinBox::_ZTV14QDoubleSpinBox: 71u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QDoubleSpinBox) +16 (int (*)(...))QDoubleSpinBox::metaObject +24 (int (*)(...))QDoubleSpinBox::qt_metacast +32 (int (*)(...))QDoubleSpinBox::qt_metacall +40 (int (*)(...))QDoubleSpinBox::~QDoubleSpinBox +48 (int (*)(...))QDoubleSpinBox::~QDoubleSpinBox +56 (int (*)(...))QAbstractSpinBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QAbstractSpinBox::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractSpinBox::sizeHint +136 (int (*)(...))QAbstractSpinBox::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractSpinBox::mousePressEvent +176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent +200 (int (*)(...))QAbstractSpinBox::wheelEvent +208 (int (*)(...))QAbstractSpinBox::keyPressEvent +216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent +224 (int (*)(...))QAbstractSpinBox::focusInEvent +232 (int (*)(...))QAbstractSpinBox::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QAbstractSpinBox::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractSpinBox::resizeEvent +280 (int (*)(...))QAbstractSpinBox::closeEvent +288 (int (*)(...))QAbstractSpinBox::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QAbstractSpinBox::showEvent +352 (int (*)(...))QAbstractSpinBox::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QAbstractSpinBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QAbstractSpinBox::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDoubleSpinBox::validate +440 (int (*)(...))QDoubleSpinBox::fixup +448 (int (*)(...))QAbstractSpinBox::stepBy +456 (int (*)(...))QAbstractSpinBox::clear +464 (int (*)(...))QAbstractSpinBox::stepEnabled +472 (int (*)(...))QDoubleSpinBox::valueFromText +480 (int (*)(...))QDoubleSpinBox::textFromValue +488 (int (*)(...))-16 +496 (int (*)(...))(& _ZTI14QDoubleSpinBox) +504 (int (*)(...))QDoubleSpinBox::_ZThn16_N14QDoubleSpinBoxD1Ev +512 (int (*)(...))QDoubleSpinBox::_ZThn16_N14QDoubleSpinBoxD0Ev +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QDoubleSpinBox + size=48 align=8 + base size=48 base align=8 +QDoubleSpinBox (0x0x7f58dbc7fd68) 0 + vptr=((& QDoubleSpinBox::_ZTV14QDoubleSpinBox) + 16u) + QAbstractSpinBox (0x0x7f58dbde6888) 0 + primary-for QDoubleSpinBox (0x0x7f58dbc7fd68) + QWidget (0x0x7f58e072c9a0) 0 + primary-for QAbstractSpinBox (0x0x7f58dbde6888) + QObject (0x0x7f58daa3f660) 0 + primary-for QWidget (0x0x7f58e072c9a0) + QPaintDevice (0x0x7f58daa3f6c0) 16 + vptr=((& QDoubleSpinBox::_ZTV14QDoubleSpinBox) + 504u) + +Class QSplashScreen::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSplashScreen::QPrivateSignal (0x0x7f58daa5e3c0) 0 empty + +Vtable for QSplashScreen +QSplashScreen::_ZTV13QSplashScreen: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSplashScreen) +16 (int (*)(...))QSplashScreen::metaObject +24 (int (*)(...))QSplashScreen::qt_metacast +32 (int (*)(...))QSplashScreen::qt_metacall +40 (int (*)(...))QSplashScreen::~QSplashScreen +48 (int (*)(...))QSplashScreen::~QSplashScreen +56 (int (*)(...))QSplashScreen::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QSplashScreen::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QSplashScreen::drawContents +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI13QSplashScreen) +456 (int (*)(...))QSplashScreen::_ZThn16_N13QSplashScreenD1Ev +464 (int (*)(...))QSplashScreen::_ZThn16_N13QSplashScreenD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QSplashScreen + size=48 align=8 + base size=48 base align=8 +QSplashScreen (0x0x7f58dbde68f0) 0 + vptr=((& QSplashScreen::_ZTV13QSplashScreen) + 16u) + QWidget (0x0x7f58e072cd20) 0 + primary-for QSplashScreen (0x0x7f58dbde68f0) + QObject (0x0x7f58daa3f960) 0 + primary-for QWidget (0x0x7f58e072cd20) + QPaintDevice (0x0x7f58daa3f9c0) 16 + vptr=((& QSplashScreen::_ZTV13QSplashScreen) + 456u) + +Class QSplitter::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSplitter::QPrivateSignal (0x0x7f58daa5e7e0) 0 empty + +Vtable for QSplitter +QSplitter::_ZTV9QSplitter: 65u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSplitter) +16 (int (*)(...))QSplitter::metaObject +24 (int (*)(...))QSplitter::qt_metacast +32 (int (*)(...))QSplitter::qt_metacall +40 (int (*)(...))QSplitter::~QSplitter +48 (int (*)(...))QSplitter::~QSplitter +56 (int (*)(...))QSplitter::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QSplitter::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QSplitter::sizeHint +136 (int (*)(...))QSplitter::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QFrame::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QSplitter::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QSplitter::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QSplitter::createHandle +440 (int (*)(...))-16 +448 (int (*)(...))(& _ZTI9QSplitter) +456 (int (*)(...))QSplitter::_ZThn16_N9QSplitterD1Ev +464 (int (*)(...))QSplitter::_ZThn16_N9QSplitterD0Ev +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QSplitter + size=48 align=8 + base size=48 base align=8 +QSplitter (0x0x7f58dbde6a90) 0 + vptr=((& QSplitter::_ZTV9QSplitter) + 16u) + QFrame (0x0x7f58dbde6c98) 0 + primary-for QSplitter (0x0x7f58dbde6a90) + QWidget (0x0x7f58e0811150) 0 + primary-for QFrame (0x0x7f58dbde6c98) + QObject (0x0x7f58daa5e420) 0 + primary-for QWidget (0x0x7f58e0811150) + QPaintDevice (0x0x7f58daa5e780) 16 + vptr=((& QSplitter::_ZTV9QSplitter) + 456u) + +Class QSplitterHandle::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSplitterHandle::QPrivateSignal (0x0x7f58daa5ecc0) 0 empty + +Vtable for QSplitterHandle +QSplitterHandle::_ZTV15QSplitterHandle: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSplitterHandle) +16 (int (*)(...))QSplitterHandle::metaObject +24 (int (*)(...))QSplitterHandle::qt_metacast +32 (int (*)(...))QSplitterHandle::qt_metacall +40 (int (*)(...))QSplitterHandle::~QSplitterHandle +48 (int (*)(...))QSplitterHandle::~QSplitterHandle +56 (int (*)(...))QSplitterHandle::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QSplitterHandle::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QSplitterHandle::mousePressEvent +176 (int (*)(...))QSplitterHandle::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QSplitterHandle::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QSplitterHandle::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QSplitterHandle::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI15QSplitterHandle) +448 (int (*)(...))QSplitterHandle::_ZThn16_N15QSplitterHandleD1Ev +456 (int (*)(...))QSplitterHandle::_ZThn16_N15QSplitterHandleD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QSplitterHandle + size=48 align=8 + base size=48 base align=8 +QSplitterHandle (0x0x7f58dbde6d00) 0 + vptr=((& QSplitterHandle::_ZTV15QSplitterHandle) + 16u) + QWidget (0x0x7f58e0811460) 0 + primary-for QSplitterHandle (0x0x7f58dbde6d00) + QObject (0x0x7f58daa5eae0) 0 + primary-for QWidget (0x0x7f58e0811460) + QPaintDevice (0x0x7f58daa5eb40) 16 + vptr=((& QSplitterHandle::_ZTV15QSplitterHandle) + 448u) + +Class QStackedLayout::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStackedLayout::QPrivateSignal (0x0x7f58daa5eea0) 0 empty + +Vtable for QStackedLayout +QStackedLayout::_ZTV14QStackedLayout: 50u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QStackedLayout) +16 (int (*)(...))QStackedLayout::metaObject +24 (int (*)(...))QStackedLayout::qt_metacast +32 (int (*)(...))QStackedLayout::qt_metacall +40 (int (*)(...))QStackedLayout::~QStackedLayout +48 (int (*)(...))QStackedLayout::~QStackedLayout +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QLayout::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QLayout::invalidate +120 (int (*)(...))QLayout::geometry +128 (int (*)(...))QStackedLayout::addItem +136 (int (*)(...))QLayout::expandingDirections +144 (int (*)(...))QStackedLayout::minimumSize +152 (int (*)(...))QLayout::maximumSize +160 (int (*)(...))QStackedLayout::setGeometry +168 (int (*)(...))QStackedLayout::itemAt +176 (int (*)(...))QStackedLayout::takeAt +184 (int (*)(...))QLayout::indexOf +192 (int (*)(...))QStackedLayout::count +200 (int (*)(...))QLayout::isEmpty +208 (int (*)(...))QLayout::controlTypes +216 (int (*)(...))QLayout::layout +224 (int (*)(...))QStackedLayout::sizeHint +232 (int (*)(...))QStackedLayout::hasHeightForWidth +240 (int (*)(...))QStackedLayout::heightForWidth +248 (int (*)(...))-16 +256 (int (*)(...))(& _ZTI14QStackedLayout) +264 (int (*)(...))QStackedLayout::_ZThn16_N14QStackedLayoutD1Ev +272 (int (*)(...))QStackedLayout::_ZThn16_N14QStackedLayoutD0Ev +280 (int (*)(...))QStackedLayout::_ZThn16_NK14QStackedLayout8sizeHintEv +288 (int (*)(...))QStackedLayout::_ZThn16_NK14QStackedLayout11minimumSizeEv +296 (int (*)(...))QLayout::_ZThn16_NK7QLayout11maximumSizeEv +304 (int (*)(...))QLayout::_ZThn16_NK7QLayout19expandingDirectionsEv +312 (int (*)(...))QStackedLayout::_ZThn16_N14QStackedLayout11setGeometryERK5QRect +320 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv +328 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv +336 (int (*)(...))QStackedLayout::_ZThn16_NK14QStackedLayout17hasHeightForWidthEv +344 (int (*)(...))QStackedLayout::_ZThn16_NK14QStackedLayout14heightForWidthEi +352 (int (*)(...))QLayoutItem::minimumHeightForWidth +360 (int (*)(...))QLayout::_ZThn16_N7QLayout10invalidateEv +368 (int (*)(...))QLayoutItem::widget +376 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv +384 (int (*)(...))QLayoutItem::spacerItem +392 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv + +Class QStackedLayout + size=32 align=8 + base size=28 base align=8 +QStackedLayout (0x0x7f58dba33a90) 0 + vptr=((& QStackedLayout::_ZTV14QStackedLayout) + 16u) + QLayout (0x0x7f58e0811770) 0 + primary-for QStackedLayout (0x0x7f58dba33a90) + QObject (0x0x7f58daa5ed20) 0 + primary-for QLayout (0x0x7f58e0811770) + QLayoutItem (0x0x7f58daa5ede0) 16 + vptr=((& QStackedLayout::_ZTV14QStackedLayout) + 264u) + +Class QStackedWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStackedWidget::QPrivateSignal (0x0x7f58daa869c0) 0 empty + +Vtable for QStackedWidget +QStackedWidget::_ZTV14QStackedWidget: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QStackedWidget) +16 (int (*)(...))QStackedWidget::metaObject +24 (int (*)(...))QStackedWidget::qt_metacast +32 (int (*)(...))QStackedWidget::qt_metacall +40 (int (*)(...))QStackedWidget::~QStackedWidget +48 (int (*)(...))QStackedWidget::~QStackedWidget +56 (int (*)(...))QStackedWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QFrame::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QFrame::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI14QStackedWidget) +448 (int (*)(...))QStackedWidget::_ZThn16_N14QStackedWidgetD1Ev +456 (int (*)(...))QStackedWidget::_ZThn16_N14QStackedWidgetD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QStackedWidget + size=48 align=8 + base size=48 base align=8 +QStackedWidget (0x0x7f58dba33af8) 0 + vptr=((& QStackedWidget::_ZTV14QStackedWidget) + 16u) + QFrame (0x0x7f58dba56548) 0 + primary-for QStackedWidget (0x0x7f58dba33af8) + QWidget (0x0x7f58e0811c40) 0 + primary-for QFrame (0x0x7f58dba56548) + QObject (0x0x7f58daa5ef00) 0 + primary-for QWidget (0x0x7f58e0811c40) + QPaintDevice (0x0x7f58daa86960) 16 + vptr=((& QStackedWidget::_ZTV14QStackedWidget) + 448u) + +Class QStatusBar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStatusBar::QPrivateSignal (0x0x7f58daa86d80) 0 empty + +Vtable for QStatusBar +QStatusBar::_ZTV10QStatusBar: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QStatusBar) +16 (int (*)(...))QStatusBar::metaObject +24 (int (*)(...))QStatusBar::qt_metacast +32 (int (*)(...))QStatusBar::qt_metacall +40 (int (*)(...))QStatusBar::~QStatusBar +48 (int (*)(...))QStatusBar::~QStatusBar +56 (int (*)(...))QStatusBar::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QStatusBar::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QStatusBar::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QStatusBar::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI10QStatusBar) +448 (int (*)(...))QStatusBar::_ZThn16_N10QStatusBarD1Ev +456 (int (*)(...))QStatusBar::_ZThn16_N10QStatusBarD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QStatusBar + size=48 align=8 + base size=48 base align=8 +QStatusBar (0x0x7f58dba565b0) 0 + vptr=((& QStatusBar::_ZTV10QStatusBar) + 16u) + QWidget (0x0x7f58e04b2000) 0 + primary-for QStatusBar (0x0x7f58dba565b0) + QObject (0x0x7f58daa86ae0) 0 + primary-for QWidget (0x0x7f58e04b2000) + QPaintDevice (0x0x7f58daa86b40) 16 + vptr=((& QStatusBar::_ZTV10QStatusBar) + 448u) + +Class QStyledItemDelegate::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStyledItemDelegate::QPrivateSignal (0x0x7f58da854e40) 0 empty + +Vtable for QStyledItemDelegate +QStyledItemDelegate::_ZTV19QStyledItemDelegate: 26u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QStyledItemDelegate) +16 (int (*)(...))QStyledItemDelegate::metaObject +24 (int (*)(...))QStyledItemDelegate::qt_metacast +32 (int (*)(...))QStyledItemDelegate::qt_metacall +40 (int (*)(...))QStyledItemDelegate::~QStyledItemDelegate +48 (int (*)(...))QStyledItemDelegate::~QStyledItemDelegate +56 (int (*)(...))QObject::event +64 (int (*)(...))QStyledItemDelegate::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStyledItemDelegate::paint +120 (int (*)(...))QStyledItemDelegate::sizeHint +128 (int (*)(...))QStyledItemDelegate::createEditor +136 (int (*)(...))QAbstractItemDelegate::destroyEditor +144 (int (*)(...))QStyledItemDelegate::setEditorData +152 (int (*)(...))QStyledItemDelegate::setModelData +160 (int (*)(...))QStyledItemDelegate::updateEditorGeometry +168 (int (*)(...))QStyledItemDelegate::editorEvent +176 (int (*)(...))QAbstractItemDelegate::helpEvent +184 (int (*)(...))QAbstractItemDelegate::paintingRoles +192 (int (*)(...))QStyledItemDelegate::displayText +200 (int (*)(...))QStyledItemDelegate::initStyleOption + +Class QStyledItemDelegate + size=16 align=8 + base size=16 base align=8 +QStyledItemDelegate (0x0x7f58dba566e8) 0 + vptr=((& QStyledItemDelegate::_ZTV19QStyledItemDelegate) + 16u) + QAbstractItemDelegate (0x0x7f58dba56f70) 0 + primary-for QStyledItemDelegate (0x0x7f58dba566e8) + QObject (0x0x7f58daa86de0) 0 + primary-for QAbstractItemDelegate (0x0x7f58dba56f70) + +Class QStyleFactory + size=1 align=1 + base size=0 base align=1 +QStyleFactory (0x0x7f58da854ea0) 0 empty + +Class QStylePainter + size=24 align=8 + base size=24 base align=8 +QStylePainter (0x0x7f58dba77000) 0 + QPainter (0x0x7f58da91e9c0) 0 + +Class QStylePlugin::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStylePlugin::QPrivateSignal (0x0x7f58da946660) 0 empty + +Vtable for QStylePlugin +QStylePlugin::_ZTV12QStylePlugin: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QStylePlugin) +16 (int (*)(...))QStylePlugin::metaObject +24 (int (*)(...))QStylePlugin::qt_metacast +32 (int (*)(...))QStylePlugin::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual + +Class QStylePlugin + size=16 align=8 + base size=16 base align=8 +QStylePlugin (0x0x7f58dba771a0) 0 + vptr=((& QStylePlugin::_ZTV12QStylePlugin) + 16u) + QObject (0x0x7f58da946600) 0 + primary-for QStylePlugin (0x0x7f58dba771a0) + +Class QSystemTrayIcon::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSystemTrayIcon::QPrivateSignal (0x0x7f58da6b2540) 0 empty + +Vtable for QSystemTrayIcon +QSystemTrayIcon::_ZTV15QSystemTrayIcon: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSystemTrayIcon) +16 (int (*)(...))QSystemTrayIcon::metaObject +24 (int (*)(...))QSystemTrayIcon::qt_metacast +32 (int (*)(...))QSystemTrayIcon::qt_metacall +40 (int (*)(...))QSystemTrayIcon::~QSystemTrayIcon +48 (int (*)(...))QSystemTrayIcon::~QSystemTrayIcon +56 (int (*)(...))QSystemTrayIcon::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSystemTrayIcon + size=16 align=8 + base size=16 base align=8 +QSystemTrayIcon (0x0x7f58dba99c30) 0 + vptr=((& QSystemTrayIcon::_ZTV15QSystemTrayIcon) + 16u) + QObject (0x0x7f58da6b24e0) 0 + primary-for QSystemTrayIcon (0x0x7f58dba99c30) + +Class QTableView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTableView::QPrivateSignal (0x0x7f58da6b2de0) 0 empty + +Vtable for QTableView +QTableView::_ZTV10QTableView: 106u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTableView) +16 (int (*)(...))QTableView::metaObject +24 (int (*)(...))QTableView::qt_metacast +32 (int (*)(...))QTableView::qt_metacall +40 (int (*)(...))QTableView::~QTableView +48 (int (*)(...))QTableView::~QTableView +56 (int (*)(...))QAbstractItemView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QTableView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QAbstractItemView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QAbstractItemView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTableView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractItemView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QAbstractItemView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QAbstractItemView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractItemView::viewportEvent +448 (int (*)(...))QTableView::scrollContentsBy +456 (int (*)(...))QTableView::viewportSizeHint +464 (int (*)(...))QTableView::setModel +472 (int (*)(...))QTableView::setSelectionModel +480 (int (*)(...))QAbstractItemView::keyboardSearch +488 (int (*)(...))QTableView::visualRect +496 (int (*)(...))QTableView::scrollTo +504 (int (*)(...))QTableView::indexAt +512 (int (*)(...))QTableView::sizeHintForRow +520 (int (*)(...))QTableView::sizeHintForColumn +528 (int (*)(...))QAbstractItemView::reset +536 (int (*)(...))QTableView::setRootIndex +544 (int (*)(...))QTableView::doItemsLayout +552 (int (*)(...))QAbstractItemView::selectAll +560 (int (*)(...))QAbstractItemView::dataChanged +568 (int (*)(...))QAbstractItemView::rowsInserted +576 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved +584 (int (*)(...))QTableView::selectionChanged +592 (int (*)(...))QTableView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QTableView::updateGeometries +624 (int (*)(...))QTableView::verticalScrollbarAction +632 (int (*)(...))QTableView::horizontalScrollbarAction +640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))QTableView::moveCursor +688 (int (*)(...))QTableView::horizontalOffset +696 (int (*)(...))QTableView::verticalOffset +704 (int (*)(...))QTableView::isIndexHidden +712 (int (*)(...))QTableView::setSelection +720 (int (*)(...))QTableView::visualRegionForSelection +728 (int (*)(...))QTableView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QAbstractItemView::startDrag +760 (int (*)(...))QTableView::viewOptions +768 (int (*)(...))-16 +776 (int (*)(...))(& _ZTI10QTableView) +784 (int (*)(...))QTableView::_ZThn16_N10QTableViewD1Ev +792 (int (*)(...))QTableView::_ZThn16_N10QTableViewD0Ev +800 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +808 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +816 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTableView + size=48 align=8 + base size=48 base align=8 +QTableView (0x0x7f58dba99ea0) 0 + vptr=((& QTableView::_ZTV10QTableView) + 16u) + QAbstractItemView (0x0x7f58dbbf15b0) 0 + primary-for QTableView (0x0x7f58dba99ea0) + QAbstractScrollArea (0x0x7f58dba144e0) 0 + primary-for QAbstractItemView (0x0x7f58dbbf15b0) + QFrame (0x0x7f58dba14548) 0 + primary-for QAbstractScrollArea (0x0x7f58dba144e0) + QWidget (0x0x7f58e059ccb0) 0 + primary-for QFrame (0x0x7f58dba14548) + QObject (0x0x7f58da6b2cc0) 0 + primary-for QWidget (0x0x7f58e059ccb0) + QPaintDevice (0x0x7f58da6b2d20) 16 + vptr=((& QTableView::_ZTV10QTableView) + 784u) + +Class QTableWidgetSelectionRange + size=16 align=4 + base size=16 base align=4 +QTableWidgetSelectionRange (0x0x7f58da700420) 0 + +Vtable for QTableWidgetItem +QTableWidgetItem::_ZTV16QTableWidgetItem: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QTableWidgetItem) +16 (int (*)(...))QTableWidgetItem::~QTableWidgetItem +24 (int (*)(...))QTableWidgetItem::~QTableWidgetItem +32 (int (*)(...))QTableWidgetItem::clone +40 (int (*)(...))QTableWidgetItem::data +48 (int (*)(...))QTableWidgetItem::setData +56 (int (*)(...))QTableWidgetItem::operator< +64 (int (*)(...))QTableWidgetItem::read +72 (int (*)(...))QTableWidgetItem::write + +Class QTableWidgetItem + size=48 align=8 + base size=44 base align=8 +QTableWidgetItem (0x0x7f58da700480) 0 + vptr=((& QTableWidgetItem::_ZTV16QTableWidgetItem) + 16u) + +Class QTableWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTableWidget::QPrivateSignal (0x0x7f58da72c240) 0 empty + +Vtable for QTableWidget +QTableWidget::_ZTV12QTableWidget: 110u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QTableWidget) +16 (int (*)(...))QTableWidget::metaObject +24 (int (*)(...))QTableWidget::qt_metacast +32 (int (*)(...))QTableWidget::qt_metacall +40 (int (*)(...))QTableWidget::~QTableWidget +48 (int (*)(...))QTableWidget::~QTableWidget +56 (int (*)(...))QTableWidget::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QTableView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QAbstractItemView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QAbstractItemView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTableView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractItemView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QAbstractItemView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QTableWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractItemView::viewportEvent +448 (int (*)(...))QTableView::scrollContentsBy +456 (int (*)(...))QTableView::viewportSizeHint +464 (int (*)(...))QTableWidget::setModel +472 (int (*)(...))QTableView::setSelectionModel +480 (int (*)(...))QAbstractItemView::keyboardSearch +488 (int (*)(...))QTableView::visualRect +496 (int (*)(...))QTableView::scrollTo +504 (int (*)(...))QTableView::indexAt +512 (int (*)(...))QTableView::sizeHintForRow +520 (int (*)(...))QTableView::sizeHintForColumn +528 (int (*)(...))QAbstractItemView::reset +536 (int (*)(...))QTableView::setRootIndex +544 (int (*)(...))QTableView::doItemsLayout +552 (int (*)(...))QAbstractItemView::selectAll +560 (int (*)(...))QAbstractItemView::dataChanged +568 (int (*)(...))QAbstractItemView::rowsInserted +576 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved +584 (int (*)(...))QTableView::selectionChanged +592 (int (*)(...))QTableView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QTableView::updateGeometries +624 (int (*)(...))QTableView::verticalScrollbarAction +632 (int (*)(...))QTableView::horizontalScrollbarAction +640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))QTableView::moveCursor +688 (int (*)(...))QTableView::horizontalOffset +696 (int (*)(...))QTableView::verticalOffset +704 (int (*)(...))QTableView::isIndexHidden +712 (int (*)(...))QTableView::setSelection +720 (int (*)(...))QTableView::visualRegionForSelection +728 (int (*)(...))QTableView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QAbstractItemView::startDrag +760 (int (*)(...))QTableView::viewOptions +768 (int (*)(...))QTableWidget::mimeTypes +776 (int (*)(...))QTableWidget::mimeData +784 (int (*)(...))QTableWidget::dropMimeData +792 (int (*)(...))QTableWidget::supportedDropActions +800 (int (*)(...))-16 +808 (int (*)(...))(& _ZTI12QTableWidget) +816 (int (*)(...))QTableWidget::_ZThn16_N12QTableWidgetD1Ev +824 (int (*)(...))QTableWidget::_ZThn16_N12QTableWidgetD0Ev +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +848 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +856 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +864 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +872 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTableWidget + size=48 align=8 + base size=48 base align=8 +QTableWidget (0x0x7f58dba14d68) 0 + vptr=((& QTableWidget::_ZTV12QTableWidget) + 16u) + QTableView (0x0x7f58dba14dd0) 0 + primary-for QTableWidget (0x0x7f58dba14d68) + QAbstractItemView (0x0x7f58dba14f70) 0 + primary-for QTableView (0x0x7f58dba14dd0) + QAbstractScrollArea (0x0x7f58db673000) 0 + primary-for QAbstractItemView (0x0x7f58dba14f70) + QFrame (0x0x7f58db6731a0) 0 + primary-for QAbstractScrollArea (0x0x7f58db673000) + QWidget (0x0x7f58e0646380) 0 + primary-for QFrame (0x0x7f58db6731a0) + QObject (0x0x7f58da7008a0) 0 + primary-for QWidget (0x0x7f58e0646380) + QPaintDevice (0x0x7f58da72c1e0) 16 + vptr=((& QTableWidget::_ZTV12QTableWidget) + 816u) + +Class QTextBrowser::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTextBrowser::QPrivateSignal (0x0x7f58da772000) 0 empty + +Vtable for QTextBrowser +QTextBrowser::_ZTV12QTextBrowser: 78u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QTextBrowser) +16 (int (*)(...))QTextBrowser::metaObject +24 (int (*)(...))QTextBrowser::qt_metacast +32 (int (*)(...))QTextBrowser::qt_metacall +40 (int (*)(...))QTextBrowser::~QTextBrowser +48 (int (*)(...))QTextBrowser::~QTextBrowser +56 (int (*)(...))QTextBrowser::event +64 (int (*)(...))QAbstractScrollArea::eventFilter +72 (int (*)(...))QTextEdit::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QTextBrowser::mousePressEvent +176 (int (*)(...))QTextBrowser::mouseReleaseEvent +184 (int (*)(...))QTextEdit::mouseDoubleClickEvent +192 (int (*)(...))QTextBrowser::mouseMoveEvent +200 (int (*)(...))QTextEdit::wheelEvent +208 (int (*)(...))QTextBrowser::keyPressEvent +216 (int (*)(...))QTextEdit::keyReleaseEvent +224 (int (*)(...))QTextEdit::focusInEvent +232 (int (*)(...))QTextBrowser::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTextBrowser::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QTextEdit::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QTextEdit::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QTextEdit::dragEnterEvent +320 (int (*)(...))QTextEdit::dragMoveEvent +328 (int (*)(...))QTextEdit::dragLeaveEvent +336 (int (*)(...))QTextEdit::dropEvent +344 (int (*)(...))QTextEdit::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QTextEdit::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QTextEdit::inputMethodEvent +416 (int (*)(...))QTextEdit::inputMethodQuery +424 (int (*)(...))QTextBrowser::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractScrollArea::viewportEvent +448 (int (*)(...))QTextEdit::scrollContentsBy +456 (int (*)(...))QAbstractScrollArea::viewportSizeHint +464 (int (*)(...))QTextBrowser::loadResource +472 (int (*)(...))QTextEdit::createMimeDataFromSelection +480 (int (*)(...))QTextEdit::canInsertFromMimeData +488 (int (*)(...))QTextEdit::insertFromMimeData +496 (int (*)(...))QTextEdit::doSetTextCursor +504 (int (*)(...))QTextBrowser::setSource +512 (int (*)(...))QTextBrowser::backward +520 (int (*)(...))QTextBrowser::forward +528 (int (*)(...))QTextBrowser::home +536 (int (*)(...))QTextBrowser::reload +544 (int (*)(...))-16 +552 (int (*)(...))(& _ZTI12QTextBrowser) +560 (int (*)(...))QTextBrowser::_ZThn16_N12QTextBrowserD1Ev +568 (int (*)(...))QTextBrowser::_ZThn16_N12QTextBrowserD0Ev +576 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +584 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +592 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +600 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +608 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +616 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTextBrowser + size=48 align=8 + base size=48 base align=8 +QTextBrowser (0x0x7f58db673208) 0 + vptr=((& QTextBrowser::_ZTV12QTextBrowser) + 16u) + QTextEdit (0x0x7f58db673270) 0 + primary-for QTextBrowser (0x0x7f58db673208) + QAbstractScrollArea (0x0x7f58db673f70) 0 + primary-for QTextEdit (0x0x7f58db673270) + QFrame (0x0x7f58db695000) 0 + primary-for QAbstractScrollArea (0x0x7f58db673f70) + QWidget (0x0x7f58e0646a80) 0 + primary-for QFrame (0x0x7f58db695000) + QObject (0x0x7f58da72c540) 0 + primary-for QWidget (0x0x7f58e0646a80) + QPaintDevice (0x0x7f58da72c5a0) 16 + vptr=((& QTextBrowser::_ZTV12QTextBrowser) + 560u) + +Class QToolBar::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QToolBar::QPrivateSignal (0x0x7f58da772840) 0 empty + +Vtable for QToolBar +QToolBar::_ZTV8QToolBar: 64u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QToolBar) +16 (int (*)(...))QToolBar::metaObject +24 (int (*)(...))QToolBar::qt_metacast +32 (int (*)(...))QToolBar::qt_metacall +40 (int (*)(...))QToolBar::~QToolBar +48 (int (*)(...))QToolBar::~QToolBar +56 (int (*)(...))QToolBar::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QToolBar::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QToolBar::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QToolBar::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))-16 +440 (int (*)(...))(& _ZTI8QToolBar) +448 (int (*)(...))QToolBar::_ZThn16_N8QToolBarD1Ev +456 (int (*)(...))QToolBar::_ZThn16_N8QToolBarD0Ev +464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QToolBar + size=48 align=8 + base size=48 base align=8 +QToolBar (0x0x7f58db695340) 0 + vptr=((& QToolBar::_ZTV8QToolBar) + 16u) + QWidget (0x0x7f58e0646d90) 0 + primary-for QToolBar (0x0x7f58db695340) + QObject (0x0x7f58da772060) 0 + primary-for QWidget (0x0x7f58e0646d90) + QPaintDevice (0x0x7f58da7727e0) 16 + vptr=((& QToolBar::_ZTV8QToolBar) + 448u) + +Class QToolBox::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QToolBox::QPrivateSignal (0x0x7f58da594cc0) 0 empty + +Vtable for QToolBox +QToolBox::_ZTV8QToolBox: 66u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QToolBox) +16 (int (*)(...))QToolBox::metaObject +24 (int (*)(...))QToolBox::qt_metacast +32 (int (*)(...))QToolBox::qt_metacall +40 (int (*)(...))QToolBox::~QToolBox +48 (int (*)(...))QToolBox::~QToolBox +56 (int (*)(...))QToolBox::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QFrame::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QFrame::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QToolBox::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QToolBox::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QToolBox::itemInserted +440 (int (*)(...))QToolBox::itemRemoved +448 (int (*)(...))-16 +456 (int (*)(...))(& _ZTI8QToolBox) +464 (int (*)(...))QToolBox::_ZThn16_N8QToolBoxD1Ev +472 (int (*)(...))QToolBox::_ZThn16_N8QToolBoxD0Ev +480 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QToolBox + size=48 align=8 + base size=48 base align=8 +QToolBox (0x0x7f58db1ea340) 0 + vptr=((& QToolBox::_ZTV8QToolBox) + 16u) + QFrame (0x0x7f58db1ea3a8) 0 + primary-for QToolBox (0x0x7f58db1ea340) + QWidget (0x0x7f58e0667000) 0 + primary-for QFrame (0x0x7f58db1ea3a8) + QObject (0x0x7f58da594ba0) 0 + primary-for QWidget (0x0x7f58e0667000) + QPaintDevice (0x0x7f58da594c00) 16 + vptr=((& QToolBox::_ZTV8QToolBox) + 464u) + +Class QToolButton::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QToolButton::QPrivateSignal (0x0x7f58da5b5900) 0 empty + +Vtable for QToolButton +QToolButton::_ZTV11QToolButton: 67u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QToolButton) +16 (int (*)(...))QToolButton::metaObject +24 (int (*)(...))QToolButton::qt_metacast +32 (int (*)(...))QToolButton::qt_metacall +40 (int (*)(...))QToolButton::~QToolButton +48 (int (*)(...))QToolButton::~QToolButton +56 (int (*)(...))QToolButton::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QToolButton::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QToolButton::sizeHint +136 (int (*)(...))QToolButton::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QToolButton::mousePressEvent +176 (int (*)(...))QToolButton::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QAbstractButton::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QAbstractButton::keyPressEvent +216 (int (*)(...))QAbstractButton::keyReleaseEvent +224 (int (*)(...))QAbstractButton::focusInEvent +232 (int (*)(...))QAbstractButton::focusOutEvent +240 (int (*)(...))QToolButton::enterEvent +248 (int (*)(...))QToolButton::leaveEvent +256 (int (*)(...))QToolButton::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QToolButton::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QToolButton::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QToolButton::hitButton +440 (int (*)(...))QAbstractButton::checkStateSet +448 (int (*)(...))QToolButton::nextCheckState +456 (int (*)(...))-16 +464 (int (*)(...))(& _ZTI11QToolButton) +472 (int (*)(...))QToolButton::_ZThn16_N11QToolButtonD1Ev +480 (int (*)(...))QToolButton::_ZThn16_N11QToolButtonD0Ev +488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QToolButton + size=48 align=8 + base size=48 base align=8 +QToolButton (0x0x7f58db1ea750) 0 + vptr=((& QToolButton::_ZTV11QToolButton) + 16u) + QAbstractButton (0x0x7f58db1ea7b8) 0 + primary-for QToolButton (0x0x7f58db1ea750) + QWidget (0x0x7f58e0667540) 0 + primary-for QAbstractButton (0x0x7f58db1ea7b8) + QObject (0x0x7f58da594ea0) 0 + primary-for QWidget (0x0x7f58e0667540) + QPaintDevice (0x0x7f58da594f00) 16 + vptr=((& QToolButton::_ZTV11QToolButton) + 472u) + +Class QToolTip + size=1 align=1 + base size=0 base align=1 +QToolTip (0x0x7f58da5b5960) 0 empty + +Class QTreeView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTreeView::QPrivateSignal (0x0x7f58da5b5c60) 0 empty + +Vtable for QTreeView +QTreeView::_ZTV9QTreeView: 108u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTreeView) +16 (int (*)(...))QTreeView::metaObject +24 (int (*)(...))QTreeView::qt_metacast +32 (int (*)(...))QTreeView::qt_metacall +40 (int (*)(...))QTreeView::~QTreeView +48 (int (*)(...))QTreeView::~QTreeView +56 (int (*)(...))QAbstractItemView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QTreeView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QTreeView::mousePressEvent +176 (int (*)(...))QTreeView::mouseReleaseEvent +184 (int (*)(...))QTreeView::mouseDoubleClickEvent +192 (int (*)(...))QTreeView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QTreeView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTreeView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractItemView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QTreeView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QAbstractItemView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QTreeView::viewportEvent +448 (int (*)(...))QTreeView::scrollContentsBy +456 (int (*)(...))QTreeView::viewportSizeHint +464 (int (*)(...))QTreeView::setModel +472 (int (*)(...))QTreeView::setSelectionModel +480 (int (*)(...))QTreeView::keyboardSearch +488 (int (*)(...))QTreeView::visualRect +496 (int (*)(...))QTreeView::scrollTo +504 (int (*)(...))QTreeView::indexAt +512 (int (*)(...))QAbstractItemView::sizeHintForRow +520 (int (*)(...))QTreeView::sizeHintForColumn +528 (int (*)(...))QTreeView::reset +536 (int (*)(...))QTreeView::setRootIndex +544 (int (*)(...))QTreeView::doItemsLayout +552 (int (*)(...))QTreeView::selectAll +560 (int (*)(...))QTreeView::dataChanged +568 (int (*)(...))QTreeView::rowsInserted +576 (int (*)(...))QTreeView::rowsAboutToBeRemoved +584 (int (*)(...))QTreeView::selectionChanged +592 (int (*)(...))QTreeView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QTreeView::updateGeometries +624 (int (*)(...))QAbstractItemView::verticalScrollbarAction +632 (int (*)(...))QTreeView::horizontalScrollbarAction +640 (int (*)(...))QTreeView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))QTreeView::moveCursor +688 (int (*)(...))QTreeView::horizontalOffset +696 (int (*)(...))QTreeView::verticalOffset +704 (int (*)(...))QTreeView::isIndexHidden +712 (int (*)(...))QTreeView::setSelection +720 (int (*)(...))QTreeView::visualRegionForSelection +728 (int (*)(...))QTreeView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QAbstractItemView::startDrag +760 (int (*)(...))QAbstractItemView::viewOptions +768 (int (*)(...))QTreeView::drawRow +776 (int (*)(...))QTreeView::drawBranches +784 (int (*)(...))-16 +792 (int (*)(...))(& _ZTI9QTreeView) +800 (int (*)(...))QTreeView::_ZThn16_N9QTreeViewD1Ev +808 (int (*)(...))QTreeView::_ZThn16_N9QTreeViewD0Ev +816 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +848 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +856 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTreeView + size=48 align=8 + base size=48 base align=8 +QTreeView (0x0x7f58db205340) 0 + vptr=((& QTreeView::_ZTV9QTreeView) + 16u) + QAbstractItemView (0x0x7f58db2053a8) 0 + primary-for QTreeView (0x0x7f58db205340) + QAbstractScrollArea (0x0x7f58db312d68) 0 + primary-for QAbstractItemView (0x0x7f58db2053a8) + QFrame (0x0x7f58db33b138) 0 + primary-for QAbstractScrollArea (0x0x7f58db312d68) + QWidget (0x0x7f58e0667b60) 0 + primary-for QFrame (0x0x7f58db33b138) + QObject (0x0x7f58da5b5a20) 0 + primary-for QWidget (0x0x7f58e0667b60) + QPaintDevice (0x0x7f58da5b5c00) 16 + vptr=((& QTreeView::_ZTV9QTreeView) + 800u) + +Class QTreeWidgetItemIterator + size=24 align=8 + base size=20 base align=8 +QTreeWidgetItemIterator (0x0x7f58da378420) 0 + +Vtable for QTreeWidgetItem +QTreeWidgetItem::_ZTV15QTreeWidgetItem: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QTreeWidgetItem) +16 (int (*)(...))QTreeWidgetItem::~QTreeWidgetItem +24 (int (*)(...))QTreeWidgetItem::~QTreeWidgetItem +32 (int (*)(...))QTreeWidgetItem::clone +40 (int (*)(...))QTreeWidgetItem::data +48 (int (*)(...))QTreeWidgetItem::setData +56 (int (*)(...))QTreeWidgetItem::operator< +64 (int (*)(...))QTreeWidgetItem::read +72 (int (*)(...))QTreeWidgetItem::write + +Class QTreeWidgetItem + size=64 align=8 + base size=60 base align=8 +QTreeWidgetItem (0x0x7f58da12de40) 0 + vptr=((& QTreeWidgetItem::_ZTV15QTreeWidgetItem) + 16u) + +Class QTreeWidget::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTreeWidget::QPrivateSignal (0x0x7f58d9dd7900) 0 empty + +Vtable for QTreeWidget +QTreeWidget::_ZTV11QTreeWidget: 112u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTreeWidget) +16 (int (*)(...))QTreeWidget::metaObject +24 (int (*)(...))QTreeWidget::qt_metacast +32 (int (*)(...))QTreeWidget::qt_metacall +40 (int (*)(...))QTreeWidget::~QTreeWidget +48 (int (*)(...))QTreeWidget::~QTreeWidget +56 (int (*)(...))QTreeWidget::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QTreeView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QTreeView::mousePressEvent +176 (int (*)(...))QTreeView::mouseReleaseEvent +184 (int (*)(...))QTreeView::mouseDoubleClickEvent +192 (int (*)(...))QTreeView::mouseMoveEvent +200 (int (*)(...))QAbstractScrollArea::wheelEvent +208 (int (*)(...))QTreeView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QTreeView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QAbstractItemView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QTreeView::dragMoveEvent +328 (int (*)(...))QAbstractItemView::dragLeaveEvent +336 (int (*)(...))QTreeWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QTreeView::viewportEvent +448 (int (*)(...))QTreeView::scrollContentsBy +456 (int (*)(...))QTreeView::viewportSizeHint +464 (int (*)(...))QTreeWidget::setModel +472 (int (*)(...))QTreeWidget::setSelectionModel +480 (int (*)(...))QTreeView::keyboardSearch +488 (int (*)(...))QTreeView::visualRect +496 (int (*)(...))QTreeView::scrollTo +504 (int (*)(...))QTreeView::indexAt +512 (int (*)(...))QAbstractItemView::sizeHintForRow +520 (int (*)(...))QTreeView::sizeHintForColumn +528 (int (*)(...))QTreeView::reset +536 (int (*)(...))QTreeView::setRootIndex +544 (int (*)(...))QTreeView::doItemsLayout +552 (int (*)(...))QTreeView::selectAll +560 (int (*)(...))QTreeView::dataChanged +568 (int (*)(...))QTreeView::rowsInserted +576 (int (*)(...))QTreeView::rowsAboutToBeRemoved +584 (int (*)(...))QTreeView::selectionChanged +592 (int (*)(...))QTreeView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QTreeView::updateGeometries +624 (int (*)(...))QAbstractItemView::verticalScrollbarAction +632 (int (*)(...))QTreeView::horizontalScrollbarAction +640 (int (*)(...))QTreeView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))QTreeView::moveCursor +688 (int (*)(...))QTreeView::horizontalOffset +696 (int (*)(...))QTreeView::verticalOffset +704 (int (*)(...))QTreeView::isIndexHidden +712 (int (*)(...))QTreeView::setSelection +720 (int (*)(...))QTreeView::visualRegionForSelection +728 (int (*)(...))QTreeView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QAbstractItemView::startDrag +760 (int (*)(...))QAbstractItemView::viewOptions +768 (int (*)(...))QTreeView::drawRow +776 (int (*)(...))QTreeView::drawBranches +784 (int (*)(...))QTreeWidget::mimeTypes +792 (int (*)(...))QTreeWidget::mimeData +800 (int (*)(...))QTreeWidget::dropMimeData +808 (int (*)(...))QTreeWidget::supportedDropActions +816 (int (*)(...))-16 +824 (int (*)(...))(& _ZTI11QTreeWidget) +832 (int (*)(...))QTreeWidget::_ZThn16_N11QTreeWidgetD1Ev +840 (int (*)(...))QTreeWidget::_ZThn16_N11QTreeWidgetD0Ev +848 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +856 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +864 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +872 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +880 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +888 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QTreeWidget + size=48 align=8 + base size=48 base align=8 +QTreeWidget (0x0x7f58db33bc30) 0 + vptr=((& QTreeWidget::_ZTV11QTreeWidget) + 16u) + QTreeView (0x0x7f58db33bd00) 0 + primary-for QTreeWidget (0x0x7f58db33bc30) + QAbstractItemView (0x0x7f58db036b60) 0 + primary-for QTreeView (0x0x7f58db33bd00) + QAbstractScrollArea (0x0x7f58db036bc8) 0 + primary-for QAbstractItemView (0x0x7f58db036b60) + QFrame (0x0x7f58db036d68) 0 + primary-for QAbstractScrollArea (0x0x7f58db036bc8) + QWidget (0x0x7f58e045bcb0) 0 + primary-for QFrame (0x0x7f58db036d68) + QObject (0x0x7f58d9dd77e0) 0 + primary-for QWidget (0x0x7f58e045bcb0) + QPaintDevice (0x0x7f58d9dd7840) 16 + vptr=((& QTreeWidget::_ZTV11QTreeWidget) + 832u) + +Class QUndoGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QUndoGroup::QPrivateSignal (0x0x7f58d9e076c0) 0 empty + +Vtable for QUndoGroup +QUndoGroup::_ZTV10QUndoGroup: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QUndoGroup) +16 (int (*)(...))QUndoGroup::metaObject +24 (int (*)(...))QUndoGroup::qt_metacast +32 (int (*)(...))QUndoGroup::qt_metacall +40 (int (*)(...))QUndoGroup::~QUndoGroup +48 (int (*)(...))QUndoGroup::~QUndoGroup +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QUndoGroup + size=16 align=8 + base size=16 base align=8 +QUndoGroup (0x0x7f58db13cf70) 0 + vptr=((& QUndoGroup::_ZTV10QUndoGroup) + 16u) + QObject (0x0x7f58d9e07660) 0 + primary-for QUndoGroup (0x0x7f58db13cf70) + +Vtable for QUndoCommand +QUndoCommand::_ZTV12QUndoCommand: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI12QUndoCommand) +16 (int (*)(...))QUndoCommand::~QUndoCommand +24 (int (*)(...))QUndoCommand::~QUndoCommand +32 (int (*)(...))QUndoCommand::undo +40 (int (*)(...))QUndoCommand::redo +48 (int (*)(...))QUndoCommand::id +56 (int (*)(...))QUndoCommand::mergeWith + +Class QUndoCommand + size=16 align=8 + base size=16 base align=8 +QUndoCommand (0x0x7f58d9e07d80) 0 + vptr=((& QUndoCommand::_ZTV12QUndoCommand) + 16u) + +Class QUndoStack::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QUndoStack::QPrivateSignal (0x0x7f58d9e2b300) 0 empty + +Vtable for QUndoStack +QUndoStack::_ZTV10QUndoStack: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QUndoStack) +16 (int (*)(...))QUndoStack::metaObject +24 (int (*)(...))QUndoStack::qt_metacast +32 (int (*)(...))QUndoStack::qt_metacall +40 (int (*)(...))QUndoStack::~QUndoStack +48 (int (*)(...))QUndoStack::~QUndoStack +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QUndoStack + size=16 align=8 + base size=16 base align=8 +QUndoStack (0x0x7f58dae38000) 0 + vptr=((& QUndoStack::_ZTV10QUndoStack) + 16u) + QObject (0x0x7f58d9e07de0) 0 + primary-for QUndoStack (0x0x7f58dae38000) + +Class QUndoView::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QUndoView::QPrivateSignal (0x0x7f58d9e2b900) 0 empty + +Vtable for QUndoView +QUndoView::_ZTV9QUndoView: 106u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QUndoView) +16 (int (*)(...))QUndoView::metaObject +24 (int (*)(...))QUndoView::qt_metacast +32 (int (*)(...))QUndoView::qt_metacall +40 (int (*)(...))QUndoView::~QUndoView +48 (int (*)(...))QUndoView::~QUndoView +56 (int (*)(...))QListView::event +64 (int (*)(...))QAbstractItemView::eventFilter +72 (int (*)(...))QListView::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QAbstractScrollArea::sizeHint +136 (int (*)(...))QAbstractScrollArea::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QAbstractItemView::mousePressEvent +176 (int (*)(...))QListView::mouseReleaseEvent +184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent +192 (int (*)(...))QListView::mouseMoveEvent +200 (int (*)(...))QListView::wheelEvent +208 (int (*)(...))QAbstractItemView::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QAbstractItemView::focusInEvent +232 (int (*)(...))QAbstractItemView::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QListView::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QListView::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QAbstractScrollArea::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QAbstractItemView::dragEnterEvent +320 (int (*)(...))QListView::dragMoveEvent +328 (int (*)(...))QListView::dragLeaveEvent +336 (int (*)(...))QListView::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QFrame::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QAbstractItemView::inputMethodEvent +416 (int (*)(...))QAbstractItemView::inputMethodQuery +424 (int (*)(...))QAbstractItemView::focusNextPrevChild +432 (int (*)(...))QAbstractScrollArea::setupViewport +440 (int (*)(...))QAbstractItemView::viewportEvent +448 (int (*)(...))QListView::scrollContentsBy +456 (int (*)(...))QListView::viewportSizeHint +464 (int (*)(...))QAbstractItemView::setModel +472 (int (*)(...))QAbstractItemView::setSelectionModel +480 (int (*)(...))QAbstractItemView::keyboardSearch +488 (int (*)(...))QListView::visualRect +496 (int (*)(...))QListView::scrollTo +504 (int (*)(...))QListView::indexAt +512 (int (*)(...))QAbstractItemView::sizeHintForRow +520 (int (*)(...))QAbstractItemView::sizeHintForColumn +528 (int (*)(...))QListView::reset +536 (int (*)(...))QListView::setRootIndex +544 (int (*)(...))QListView::doItemsLayout +552 (int (*)(...))QAbstractItemView::selectAll +560 (int (*)(...))QListView::dataChanged +568 (int (*)(...))QListView::rowsInserted +576 (int (*)(...))QListView::rowsAboutToBeRemoved +584 (int (*)(...))QListView::selectionChanged +592 (int (*)(...))QListView::currentChanged +600 (int (*)(...))QAbstractItemView::updateEditorData +608 (int (*)(...))QAbstractItemView::updateEditorGeometries +616 (int (*)(...))QListView::updateGeometries +624 (int (*)(...))QAbstractItemView::verticalScrollbarAction +632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction +640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged +648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged +656 (int (*)(...))QAbstractItemView::closeEditor +664 (int (*)(...))QAbstractItemView::commitData +672 (int (*)(...))QAbstractItemView::editorDestroyed +680 (int (*)(...))QListView::moveCursor +688 (int (*)(...))QListView::horizontalOffset +696 (int (*)(...))QListView::verticalOffset +704 (int (*)(...))QListView::isIndexHidden +712 (int (*)(...))QListView::setSelection +720 (int (*)(...))QListView::visualRegionForSelection +728 (int (*)(...))QListView::selectedIndexes +736 (int (*)(...))QAbstractItemView::edit +744 (int (*)(...))QAbstractItemView::selectionCommand +752 (int (*)(...))QListView::startDrag +760 (int (*)(...))QListView::viewOptions +768 (int (*)(...))-16 +776 (int (*)(...))(& _ZTI9QUndoView) +784 (int (*)(...))QUndoView::_ZThn16_N9QUndoViewD1Ev +792 (int (*)(...))QUndoView::_ZThn16_N9QUndoViewD0Ev +800 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +808 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +816 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +832 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +840 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QUndoView + size=48 align=8 + base size=48 base align=8 +QUndoView (0x0x7f58dae38068) 0 + vptr=((& QUndoView::_ZTV9QUndoView) + 16u) + QListView (0x0x7f58dae380d0) 0 + primary-for QUndoView (0x0x7f58dae38068) + QAbstractItemView (0x0x7f58dae38208) 0 + primary-for QListView (0x0x7f58dae380d0) + QAbstractScrollArea (0x0x7f58dae38270) 0 + primary-for QAbstractItemView (0x0x7f58dae38208) + QFrame (0x0x7f58dae387b8) 0 + primary-for QAbstractScrollArea (0x0x7f58dae38270) + QWidget (0x0x7f58e0485e70) 0 + primary-for QFrame (0x0x7f58dae387b8) + QObject (0x0x7f58d9e2b360) 0 + primary-for QWidget (0x0x7f58e0485e70) + QPaintDevice (0x0x7f58d9e2b8a0) 16 + vptr=((& QUndoView::_ZTV9QUndoView) + 784u) + +Class QWhatsThis + size=1 align=1 + base size=0 base align=1 +QWhatsThis (0x0x7f58d9e2b9c0) 0 empty + +Class QWidgetAction::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWidgetAction::QPrivateSignal (0x0x7f58d9e2bc00) 0 empty + +Vtable for QWidgetAction +QWidgetAction::_ZTV13QWidgetAction: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QWidgetAction) +16 (int (*)(...))QWidgetAction::metaObject +24 (int (*)(...))QWidgetAction::qt_metacast +32 (int (*)(...))QWidgetAction::qt_metacall +40 (int (*)(...))QWidgetAction::~QWidgetAction +48 (int (*)(...))QWidgetAction::~QWidgetAction +56 (int (*)(...))QWidgetAction::event +64 (int (*)(...))QWidgetAction::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidgetAction::createWidget +120 (int (*)(...))QWidgetAction::deleteWidget + +Class QWidgetAction + size=16 align=8 + base size=16 base align=8 +QWidgetAction (0x0x7f58dae38820) 0 + vptr=((& QWidgetAction::_ZTV13QWidgetAction) + 16u) + QAction (0x0x7f58dae38c30) 0 + primary-for QWidgetAction (0x0x7f58dae38820) + QObject (0x0x7f58d9e2bba0) 0 + primary-for QAction (0x0x7f58dae38c30) + +Class QWizard::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWizard::QPrivateSignal (0x0x7f58d9e4e720) 0 empty + +Vtable for QWizard +QWizard::_ZTV7QWizard: 73u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QWizard) +16 (int (*)(...))QWizard::metaObject +24 (int (*)(...))QWizard::qt_metacast +32 (int (*)(...))QWizard::qt_metacall +40 (int (*)(...))QWizard::~QWizard +48 (int (*)(...))QWizard::~QWizard +56 (int (*)(...))QWizard::event +64 (int (*)(...))QDialog::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWizard::setVisible +128 (int (*)(...))QWizard::sizeHint +136 (int (*)(...))QDialog::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QDialog::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWizard::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWizard::resizeEvent +280 (int (*)(...))QDialog::closeEvent +288 (int (*)(...))QDialog::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QDialog::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QDialog::open +440 (int (*)(...))QDialog::exec +448 (int (*)(...))QWizard::done +456 (int (*)(...))QDialog::accept +464 (int (*)(...))QDialog::reject +472 (int (*)(...))QWizard::validateCurrentPage +480 (int (*)(...))QWizard::nextId +488 (int (*)(...))QWizard::initializePage +496 (int (*)(...))QWizard::cleanupPage +504 (int (*)(...))-16 +512 (int (*)(...))(& _ZTI7QWizard) +520 (int (*)(...))QWizard::_ZThn16_N7QWizardD1Ev +528 (int (*)(...))QWizard::_ZThn16_N7QWizardD0Ev +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +552 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +560 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +568 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +576 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QWizard + size=48 align=8 + base size=48 base align=8 +QWizard (0x0x7f58dae38c98) 0 + vptr=((& QWizard::_ZTV7QWizard) + 16u) + QDialog (0x0x7f58dae62d00) 0 + primary-for QWizard (0x0x7f58dae38c98) + QWidget (0x0x7f58e0093b60) 0 + primary-for QDialog (0x0x7f58dae62d00) + QObject (0x0x7f58d9e4e600) 0 + primary-for QWidget (0x0x7f58e0093b60) + QPaintDevice (0x0x7f58d9e4e660) 16 + vptr=((& QWizard::_ZTV7QWizard) + 520u) + +Class QWizardPage::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QWizardPage::QPrivateSignal (0x0x7f58d9e7f900) 0 empty + +Vtable for QWizardPage +QWizardPage::_ZTV11QWizardPage: 69u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QWizardPage) +16 (int (*)(...))QWizardPage::metaObject +24 (int (*)(...))QWizardPage::qt_metacast +32 (int (*)(...))QWizardPage::qt_metacall +40 (int (*)(...))QWizardPage::~QWizardPage +48 (int (*)(...))QWizardPage::~QWizardPage +56 (int (*)(...))QWidget::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QWidget::devType +120 (int (*)(...))QWidget::setVisible +128 (int (*)(...))QWidget::sizeHint +136 (int (*)(...))QWidget::minimumSizeHint +144 (int (*)(...))QWidget::heightForWidth +152 (int (*)(...))QWidget::hasHeightForWidth +160 (int (*)(...))QWidget::paintEngine +168 (int (*)(...))QWidget::mousePressEvent +176 (int (*)(...))QWidget::mouseReleaseEvent +184 (int (*)(...))QWidget::mouseDoubleClickEvent +192 (int (*)(...))QWidget::mouseMoveEvent +200 (int (*)(...))QWidget::wheelEvent +208 (int (*)(...))QWidget::keyPressEvent +216 (int (*)(...))QWidget::keyReleaseEvent +224 (int (*)(...))QWidget::focusInEvent +232 (int (*)(...))QWidget::focusOutEvent +240 (int (*)(...))QWidget::enterEvent +248 (int (*)(...))QWidget::leaveEvent +256 (int (*)(...))QWidget::paintEvent +264 (int (*)(...))QWidget::moveEvent +272 (int (*)(...))QWidget::resizeEvent +280 (int (*)(...))QWidget::closeEvent +288 (int (*)(...))QWidget::contextMenuEvent +296 (int (*)(...))QWidget::tabletEvent +304 (int (*)(...))QWidget::actionEvent +312 (int (*)(...))QWidget::dragEnterEvent +320 (int (*)(...))QWidget::dragMoveEvent +328 (int (*)(...))QWidget::dragLeaveEvent +336 (int (*)(...))QWidget::dropEvent +344 (int (*)(...))QWidget::showEvent +352 (int (*)(...))QWidget::hideEvent +360 (int (*)(...))QWidget::nativeEvent +368 (int (*)(...))QWidget::changeEvent +376 (int (*)(...))QWidget::metric +384 (int (*)(...))QWidget::initPainter +392 (int (*)(...))QWidget::redirected +400 (int (*)(...))QWidget::sharedPainter +408 (int (*)(...))QWidget::inputMethodEvent +416 (int (*)(...))QWidget::inputMethodQuery +424 (int (*)(...))QWidget::focusNextPrevChild +432 (int (*)(...))QWizardPage::initializePage +440 (int (*)(...))QWizardPage::cleanupPage +448 (int (*)(...))QWizardPage::validatePage +456 (int (*)(...))QWizardPage::isComplete +464 (int (*)(...))QWizardPage::nextId +472 (int (*)(...))-16 +480 (int (*)(...))(& _ZTI11QWizardPage) +488 (int (*)(...))QWizardPage::_ZThn16_N11QWizardPageD1Ev +496 (int (*)(...))QWizardPage::_ZThn16_N11QWizardPageD0Ev +504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv +512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv +520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE +528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter +536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint +544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv + +Class QWizardPage + size=48 align=8 + base size=48 base align=8 +QWizardPage (0x0x7f58dae821a0) 0 + vptr=((& QWizardPage::_ZTV11QWizardPage) + 16u) + QWidget (0x0x7f58e00c72a0) 0 + primary-for QWizardPage (0x0x7f58dae821a0) + QObject (0x0x7f58d9e7f5a0) 0 + primary-for QWidget (0x0x7f58e00c72a0) + QPaintDevice (0x0x7f58d9e7f600) 16 + vptr=((& QWizardPage::_ZTV11QWizardPage) + 488u) + diff --git a/tests/auto/bic/data/QtXml.5.12.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtXml.5.12.0.linux-gcc-amd64.txt new file mode 100644 index 0000000000..ad593fafe6 --- /dev/null +++ b/tests/auto/bic/data/QtXml.5.12.0.linux-gcc-amd64.txt @@ -0,0 +1,5047 @@ +Class std::__failure_type + size=1 align=1 + base size=0 base align=1 +std::__failure_type (0x0x7f51c326b2a0) 0 empty + +Class std::__do_is_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_destructible_impl (0x0x7f51c32b3a20) 0 empty + +Class std::__do_is_nt_destructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nt_destructible_impl (0x0x7f51c32b3c60) 0 empty + +Class std::__do_is_default_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_default_constructible_impl (0x0x7f51c32b3ea0) 0 empty + +Class std::__do_is_static_castable_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_static_castable_impl (0x0x7f51c0e5f120) 0 empty + +Class std::__do_is_direct_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_direct_constructible_impl (0x0x7f51c0e5f2a0) 0 empty + +Class std::__do_is_nary_constructible_impl + size=1 align=1 + base size=0 base align=1 +std::__do_is_nary_constructible_impl (0x0x7f51c0e5f660) 0 empty + +Class std::__do_common_type_impl + size=1 align=1 + base size=0 base align=1 +std::__do_common_type_impl (0x0x7f51c0eeade0) 0 empty + +Class std::__do_member_type_wrapper + size=1 align=1 + base size=0 base align=1 +std::__do_member_type_wrapper (0x0x7f51c0eeaea0) 0 empty + +Class std::__result_of_memfun_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_ref_impl (0x0x7f51c0f1c240) 0 empty + +Class std::__result_of_memfun_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memfun_deref_impl (0x0x7f51c0f1c300) 0 empty + +Class std::__result_of_memobj_ref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_ref_impl (0x0x7f51c0f1c3c0) 0 empty + +Class std::__result_of_memobj_deref_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_memobj_deref_impl (0x0x7f51c0f1c480) 0 empty + +Class std::__result_of_other_impl + size=1 align=1 + base size=0 base align=1 +std::__result_of_other_impl (0x0x7f51c0f1c720) 0 empty + +Class std::piecewise_construct_t + size=1 align=1 + base size=0 base align=1 +std::piecewise_construct_t (0x0x7f51c0f1c900) 0 empty + +Class std::__true_type + size=1 align=1 + base size=0 base align=1 +std::__true_type (0x0x7f51c0f1cd80) 0 empty + +Class std::__false_type + size=1 align=1 + base size=0 base align=1 +std::__false_type (0x0x7f51c0f1cde0) 0 empty + +Class std::input_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::input_iterator_tag (0x0x7f51c0fd5a80) 0 empty + +Class std::output_iterator_tag + size=1 align=1 + base size=0 base align=1 +std::output_iterator_tag (0x0x7f51c0fd5ae0) 0 empty + +Class std::forward_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::forward_iterator_tag (0x0x7f51c0ec0bc8) 0 empty + std::input_iterator_tag (0x0x7f51c0fd5b40) 0 empty + +Class std::bidirectional_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::bidirectional_iterator_tag (0x0x7f51c0ec0c30) 0 empty + std::forward_iterator_tag (0x0x7f51c0ec0c98) 0 empty + std::input_iterator_tag (0x0x7f51c0fd5ba0) 0 empty + +Class std::random_access_iterator_tag + size=1 align=1 + base size=1 base align=1 +std::random_access_iterator_tag (0x0x7f51c0ec0d00) 0 empty + std::bidirectional_iterator_tag (0x0x7f51c0ec0d68) 0 empty + std::forward_iterator_tag (0x0x7f51c0ec0dd0) 0 empty + std::input_iterator_tag (0x0x7f51c0fd5c00) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_iter (0x0x7f51c10108a0) 0 empty + +Class __gnu_cxx::__ops::_Iter_less_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_less_val (0x0x7f51c1010900) 0 empty + +Class __gnu_cxx::__ops::_Val_less_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Val_less_iter (0x0x7f51c1010960) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_iter + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7f51c10109c0) 0 empty + +Class __gnu_cxx::__ops::_Iter_equal_to_val + size=1 align=1 + base size=0 base align=1 +__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7f51c1010a20) 0 empty + +Class wait + size=4 align=4 + base size=4 base align=4 +wait (0x0x7f51c0cf1540) 0 + +Class __locale_struct + size=232 align=8 + base size=232 base align=8 +__locale_struct (0x0x7f51c0cf1780) 0 + +Class timespec + size=16 align=8 + base size=16 base align=8 +timespec (0x0x7f51c0cf1840) 0 + +Class timeval + size=16 align=8 + base size=16 base align=8 +timeval (0x0x7f51c0cf18a0) 0 + +Class pthread_attr_t + size=56 align=8 + base size=56 base align=8 +pthread_attr_t (0x0x7f51c0cf1960) 0 + +Class __pthread_internal_list + size=16 align=8 + base size=16 base align=8 +__pthread_internal_list (0x0x7f51c0cf19c0) 0 + +Class random_data + size=48 align=8 + base size=48 base align=8 +random_data (0x0x7f51c0cf1e40) 0 + +Class drand48_data + size=24 align=8 + base size=24 base align=8 +drand48_data (0x0x7f51c0cf1ea0) 0 + +Vtable for std::exception +std::exception::_ZTVSt9exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9exception) +16 (int (*)(...))std::exception::~exception +24 (int (*)(...))std::exception::~exception +32 (int (*)(...))std::exception::what + +Class std::exception + size=8 align=8 + base size=8 base align=8 +std::exception (0x0x7f51c0cf1f00) 0 nearly-empty + vptr=((& std::exception::_ZTVSt9exception) + 16u) + +Vtable for std::bad_exception +std::bad_exception::_ZTVSt13bad_exception: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13bad_exception) +16 (int (*)(...))std::bad_exception::~bad_exception +24 (int (*)(...))std::bad_exception::~bad_exception +32 (int (*)(...))std::bad_exception::what + +Class std::bad_exception + size=8 align=8 + base size=8 base align=8 +std::bad_exception (0x0x7f51c1011340) 0 nearly-empty + vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u) + std::exception (0x0x7f51c0cf1f60) 0 nearly-empty + primary-for std::bad_exception (0x0x7f51c1011340) + +Class std::__exception_ptr::exception_ptr + size=8 align=8 + base size=8 base align=8 +std::__exception_ptr::exception_ptr (0x0x7f51c0e39000) 0 + +Vtable for std::nested_exception +std::nested_exception::_ZTVSt16nested_exception: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16nested_exception) +16 (int (*)(...))std::nested_exception::~nested_exception +24 (int (*)(...))std::nested_exception::~nested_exception + +Class std::nested_exception + size=16 align=8 + base size=16 base align=8 +std::nested_exception (0x0x7f51c0e39060) 0 + vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16u) + +Vtable for std::bad_alloc +std::bad_alloc::_ZTVSt9bad_alloc: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9bad_alloc) +16 (int (*)(...))std::bad_alloc::~bad_alloc +24 (int (*)(...))std::bad_alloc::~bad_alloc +32 (int (*)(...))std::bad_alloc::what + +Class std::bad_alloc + size=8 align=8 + base size=8 base align=8 +std::bad_alloc (0x0x7f51c1011548) 0 nearly-empty + vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u) + std::exception (0x0x7f51c0e39480) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f51c1011548) + +Vtable for std::bad_array_new_length +std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt20bad_array_new_length) +16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length +32 (int (*)(...))std::bad_array_new_length::what + +Class std::bad_array_new_length + size=8 align=8 + base size=8 base align=8 +std::bad_array_new_length (0x0x7f51c10115b0) 0 nearly-empty + vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16u) + std::bad_alloc (0x0x7f51c1011618) 0 nearly-empty + primary-for std::bad_array_new_length (0x0x7f51c10115b0) + std::exception (0x0x7f51c0e394e0) 0 nearly-empty + primary-for std::bad_alloc (0x0x7f51c1011618) + +Class std::nothrow_t + size=1 align=1 + base size=0 base align=1 +std::nothrow_t (0x0x7f51c0e39540) 0 empty + +Class __exception + size=40 align=8 + base size=40 base align=8 +__exception (0x0x7f51c0b09180) 0 + +Class lconv + size=96 align=8 + base size=96 base align=8 +lconv (0x0x7f51c0b09e40) 0 + +Vtable for __cxxabiv1::__forced_unwind +__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class __cxxabiv1::__forced_unwind + size=8 align=8 + base size=8 base align=8 +__cxxabiv1::__forced_unwind (0x0x7f51c0b09ea0) 0 nearly-empty + vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u) + +Class sched_param + size=4 align=4 + base size=4 base align=4 +sched_param (0x0x7f51c0959d80) 0 + +Class __sched_param + size=4 align=4 + base size=4 base align=4 +__sched_param (0x0x7f51c0959de0) 0 + +Class timex + size=208 align=8 + base size=208 base align=8 +timex (0x0x7f51c0959ea0) 0 + +Class tm + size=56 align=8 + base size=56 base align=8 +tm (0x0x7f51c0959f00) 0 + +Class itimerspec + size=32 align=8 + base size=32 base align=8 +itimerspec (0x0x7f51c0959f60) 0 + +Class _pthread_cleanup_buffer + size=32 align=8 + base size=32 base align=8 +_pthread_cleanup_buffer (0x0x7f51c09f2000) 0 + +Class __pthread_cleanup_frame + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_frame (0x0x7f51c09f2120) 0 + +Class __pthread_cleanup_class + size=24 align=8 + base size=24 base align=8 +__pthread_cleanup_class (0x0x7f51c09f2180) 0 + +Class _IO_marker + size=24 align=8 + base size=24 base align=8 +_IO_marker (0x0x7f51c09f25a0) 0 + +Class _IO_FILE + size=216 align=8 + base size=216 base align=8 +_IO_FILE (0x0x7f51c09f2600) 0 + +Class std::_Hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Hash_impl (0x0x7f51c0825de0) 0 empty + +Class std::_Fnv_hash_impl + size=1 align=1 + base size=0 base align=1 +std::_Fnv_hash_impl (0x0x7f51c0825e40) 0 empty + +Class std::__numeric_limits_base + size=1 align=1 + base size=0 base align=1 +std::__numeric_limits_base (0x0x7f51c04f3de0) 0 empty + +Class std::_Bit_reference + size=16 align=8 + base size=16 base align=8 +std::_Bit_reference (0x0x7f51c0293c00) 0 + +Class std::_Bit_iterator_base + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator_base (0x0x7f51c0292208) 0 + std::iterator (0x0x7f51c0293cc0) 0 empty + +Class std::_Bit_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_iterator (0x0x7f51c0292270) 0 + std::_Bit_iterator_base (0x0x7f51c02922d8) 0 + std::iterator (0x0x7f51c0293d20) 0 empty + +Class std::_Bit_const_iterator + size=16 align=8 + base size=12 base align=8 +std::_Bit_const_iterator (0x0x7f51c0292340) 0 + std::_Bit_iterator_base (0x0x7f51c02923a8) 0 + std::iterator (0x0x7f51c0293d80) 0 empty + +Class std::random_device + size=5000 align=8 + base size=5000 base align=8 +std::random_device (0x0x7f51c008dba0) 0 + +Class std::bernoulli_distribution::param_type + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution::param_type (0x0x7f51c01c0960) 0 + +Class std::bernoulli_distribution + size=8 align=8 + base size=8 base align=8 +std::bernoulli_distribution (0x0x7f51c01c0900) 0 + +Class std::seed_seq + size=24 align=8 + base size=24 base align=8 +std::seed_seq (0x0x7f51bff56900) 0 + +Class qIsNull(double)::U + size=8 align=8 + base size=8 base align=8 +qIsNull(double)::U (0x0x7f51beb94420) 0 + +Class qIsNull(float)::U + size=4 align=4 + base size=4 base align=4 +qIsNull(float)::U (0x0x7f51beb94480) 0 + +Class QSysInfo + size=1 align=1 + base size=0 base align=1 +QSysInfo (0x0x7f51bec3af00) 0 empty + +Class QMessageLogContext + size=32 align=8 + base size=32 base align=8 +QMessageLogContext (0x0x7f51bec3af60) 0 + +Class QMessageLogger + size=32 align=8 + base size=32 base align=8 +QMessageLogger (0x0x7f51be885000) 0 + +Class QFlag + size=4 align=4 + base size=4 base align=4 +QFlag (0x0x7f51be885060) 0 + +Class QIncompatibleFlag + size=4 align=4 + base size=4 base align=4 +QIncompatibleFlag (0x0x7f51be885300) 0 + +Class std::__atomic_flag_base + size=1 align=1 + base size=1 base align=1 +std::__atomic_flag_base (0x0x7f51be885840) 0 + +Class std::atomic_flag + size=1 align=1 + base size=1 base align=1 +std::atomic_flag (0x0x7f51be8b0270) 0 + std::__atomic_flag_base (0x0x7f51be8858a0) 0 + +Class QAtomicInt + size=4 align=4 + base size=4 base align=4 +QAtomicInt (0x0x7f51be8b09c0) 0 + QAtomicInteger (0x0x7f51be8b0a28) 0 + QBasicAtomicInteger (0x0x7f51be4e1000) 0 + +Class QInternal + size=1 align=1 + base size=0 base align=1 +QInternal (0x0x7f51be3b35a0) 0 empty + +Class QtPrivate::QSlotObjectBase + size=16 align=8 + base size=16 base align=8 +QtPrivate::QSlotObjectBase (0x0x7f51be113780) 0 + +Class QGenericArgument + size=16 align=8 + base size=16 base align=8 +QGenericArgument (0x0x7f51be1138a0) 0 + +Class QGenericReturnArgument + size=16 align=8 + base size=16 base align=8 +QGenericReturnArgument (0x0x7f51be0ee618) 0 + QGenericArgument (0x0x7f51be113900) 0 + +Class QMetaObject + size=48 align=8 + base size=48 base align=8 +QMetaObject (0x0x7f51be113a80) 0 + +Class QMetaObject::Connection + size=8 align=8 + base size=8 base align=8 +QMetaObject::Connection (0x0x7f51be113b40) 0 + +Class QLatin1Char + size=1 align=1 + base size=1 base align=1 +QLatin1Char (0x0x7f51be1f9ba0) 0 + +Class QChar + size=2 align=2 + base size=2 base align=2 +QChar (0x0x7f51be1f9c00) 0 + +Class QtPrivate::RefCount + size=4 align=4 + base size=4 base align=4 +QtPrivate::RefCount (0x0x7f51be1f9ea0) 0 + +Class QArrayData + size=24 align=8 + base size=24 base align=8 +QArrayData (0x0x7f51be1f9f00) 0 + +Class QtPrivate::QContainerImplHelper + size=1 align=1 + base size=0 base align=1 +QtPrivate::QContainerImplHelper (0x0x7f51bdee82a0) 0 empty + +Class std::locale + size=8 align=8 + base size=8 base align=8 +std::locale (0x0x7f51bdee8300) 0 + +Vtable for std::locale::facet +std::locale::facet::_ZTVNSt6locale5facetE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6locale5facetE) +16 (int (*)(...))std::locale::facet::~facet +24 (int (*)(...))std::locale::facet::~facet + +Class std::locale::facet + size=16 align=8 + base size=12 base align=8 +std::locale::facet (0x0x7f51bdee8360) 0 + vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u) + +Class std::locale::id + size=8 align=8 + base size=8 base align=8 +std::locale::id (0x0x7f51bdee83c0) 0 + +Class std::locale::_Impl + size=40 align=8 + base size=40 base align=8 +std::locale::_Impl (0x0x7f51bdee8420) 0 + +Class std::__cow_string + size=8 align=8 + base size=8 base align=8 +std::__cow_string (0x0x7f51bdee87e0) 0 + +Vtable for std::logic_error +std::logic_error::_ZTVSt11logic_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11logic_error) +16 (int (*)(...))std::logic_error::~logic_error +24 (int (*)(...))std::logic_error::~logic_error +32 (int (*)(...))std::logic_error::what + +Class std::logic_error + size=16 align=8 + base size=16 base align=8 +std::logic_error (0x0x7f51bdea1c30) 0 + vptr=((& std::logic_error::_ZTVSt11logic_error) + 16u) + std::exception (0x0x7f51bdee88a0) 0 nearly-empty + primary-for std::logic_error (0x0x7f51bdea1c30) + +Vtable for std::domain_error +std::domain_error::_ZTVSt12domain_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12domain_error) +16 (int (*)(...))std::domain_error::~domain_error +24 (int (*)(...))std::domain_error::~domain_error +32 (int (*)(...))std::logic_error::what + +Class std::domain_error + size=16 align=8 + base size=16 base align=8 +std::domain_error (0x0x7f51bdea1c98) 0 + vptr=((& std::domain_error::_ZTVSt12domain_error) + 16u) + std::logic_error (0x0x7f51bdea1d00) 0 + primary-for std::domain_error (0x0x7f51bdea1c98) + std::exception (0x0x7f51bdee8900) 0 nearly-empty + primary-for std::logic_error (0x0x7f51bdea1d00) + +Vtable for std::invalid_argument +std::invalid_argument::_ZTVSt16invalid_argument: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt16invalid_argument) +16 (int (*)(...))std::invalid_argument::~invalid_argument +24 (int (*)(...))std::invalid_argument::~invalid_argument +32 (int (*)(...))std::logic_error::what + +Class std::invalid_argument + size=16 align=8 + base size=16 base align=8 +std::invalid_argument (0x0x7f51bdea1d68) 0 + vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16u) + std::logic_error (0x0x7f51bdea1dd0) 0 + primary-for std::invalid_argument (0x0x7f51bdea1d68) + std::exception (0x0x7f51bdee8960) 0 nearly-empty + primary-for std::logic_error (0x0x7f51bdea1dd0) + +Vtable for std::length_error +std::length_error::_ZTVSt12length_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12length_error) +16 (int (*)(...))std::length_error::~length_error +24 (int (*)(...))std::length_error::~length_error +32 (int (*)(...))std::logic_error::what + +Class std::length_error + size=16 align=8 + base size=16 base align=8 +std::length_error (0x0x7f51bdea1e38) 0 + vptr=((& std::length_error::_ZTVSt12length_error) + 16u) + std::logic_error (0x0x7f51bdea1ea0) 0 + primary-for std::length_error (0x0x7f51bdea1e38) + std::exception (0x0x7f51bdee89c0) 0 nearly-empty + primary-for std::logic_error (0x0x7f51bdea1ea0) + +Vtable for std::out_of_range +std::out_of_range::_ZTVSt12out_of_range: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12out_of_range) +16 (int (*)(...))std::out_of_range::~out_of_range +24 (int (*)(...))std::out_of_range::~out_of_range +32 (int (*)(...))std::logic_error::what + +Class std::out_of_range + size=16 align=8 + base size=16 base align=8 +std::out_of_range (0x0x7f51bdea1f08) 0 + vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16u) + std::logic_error (0x0x7f51bdea1f70) 0 + primary-for std::out_of_range (0x0x7f51bdea1f08) + std::exception (0x0x7f51bdee8a20) 0 nearly-empty + primary-for std::logic_error (0x0x7f51bdea1f70) + +Vtable for std::runtime_error +std::runtime_error::_ZTVSt13runtime_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt13runtime_error) +16 (int (*)(...))std::runtime_error::~runtime_error +24 (int (*)(...))std::runtime_error::~runtime_error +32 (int (*)(...))std::runtime_error::what + +Class std::runtime_error + size=16 align=8 + base size=16 base align=8 +std::runtime_error (0x0x7f51bdea1958) 0 + vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16u) + std::exception (0x0x7f51bdee8a80) 0 nearly-empty + primary-for std::runtime_error (0x0x7f51bdea1958) + +Vtable for std::range_error +std::range_error::_ZTVSt11range_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt11range_error) +16 (int (*)(...))std::range_error::~range_error +24 (int (*)(...))std::range_error::~range_error +32 (int (*)(...))std::runtime_error::what + +Class std::range_error + size=16 align=8 + base size=16 base align=8 +std::range_error (0x0x7f51bdea1a28) 0 + vptr=((& std::range_error::_ZTVSt11range_error) + 16u) + std::runtime_error (0x0x7f51bdfd7000) 0 + primary-for std::range_error (0x0x7f51bdea1a28) + std::exception (0x0x7f51bdee8ae0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f51bdfd7000) + +Vtable for std::overflow_error +std::overflow_error::_ZTVSt14overflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt14overflow_error) +16 (int (*)(...))std::overflow_error::~overflow_error +24 (int (*)(...))std::overflow_error::~overflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::overflow_error + size=16 align=8 + base size=16 base align=8 +std::overflow_error (0x0x7f51bdfd7068) 0 + vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16u) + std::runtime_error (0x0x7f51bdfd70d0) 0 + primary-for std::overflow_error (0x0x7f51bdfd7068) + std::exception (0x0x7f51bdee8b40) 0 nearly-empty + primary-for std::runtime_error (0x0x7f51bdfd70d0) + +Vtable for std::underflow_error +std::underflow_error::_ZTVSt15underflow_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt15underflow_error) +16 (int (*)(...))std::underflow_error::~underflow_error +24 (int (*)(...))std::underflow_error::~underflow_error +32 (int (*)(...))std::runtime_error::what + +Class std::underflow_error + size=16 align=8 + base size=16 base align=8 +std::underflow_error (0x0x7f51bdfd7138) 0 + vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16u) + std::runtime_error (0x0x7f51bdfd71a0) 0 + primary-for std::underflow_error (0x0x7f51bdfd7138) + std::exception (0x0x7f51bdee8ba0) 0 nearly-empty + primary-for std::runtime_error (0x0x7f51bdfd71a0) + +Vtable for std::_V2::error_category +std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt3_V214error_categoryE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))std::_V2::error_category::_M_message +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))std::_V2::error_category::default_error_condition +64 (int (*)(...))std::_V2::error_category::equivalent +72 (int (*)(...))std::_V2::error_category::equivalent + +Class std::_V2::error_category + size=8 align=8 + base size=8 base align=8 +std::_V2::error_category (0x0x7f51bdee8d20) 0 nearly-empty + vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16u) + +Class std::error_code + size=16 align=8 + base size=16 base align=8 +std::error_code (0x0x7f51bdee8f60) 0 + +Class std::error_condition + size=16 align=8 + base size=16 base align=8 +std::error_condition (0x0x7f51be00a120) 0 + +Vtable for std::system_error +std::system_error::_ZTVSt12system_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12system_error) +16 (int (*)(...))std::system_error::~system_error +24 (int (*)(...))std::system_error::~system_error +32 (int (*)(...))std::runtime_error::what + +Class std::system_error + size=32 align=8 + base size=32 base align=8 +std::system_error (0x0x7f51bdfd7680) 0 + vptr=((& std::system_error::_ZTVSt12system_error) + 16u) + std::runtime_error (0x0x7f51bdfd76e8) 0 + primary-for std::system_error (0x0x7f51bdfd7680) + std::exception (0x0x7f51be00a360) 0 nearly-empty + primary-for std::runtime_error (0x0x7f51bdfd76e8) + +Vtable for std::ios_base::failure +std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E) +16 (int (*)(...))std::ios_base::failure::~failure +24 (int (*)(...))std::ios_base::failure::~failure +32 (int (*)(...))std::ios_base::failure::what + +Class std::ios_base::failure + size=32 align=8 + base size=32 base align=8 +std::ios_base::failure (0x0x7f51be0482d8) 0 + vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16u) + std::system_error (0x0x7f51be048340) 0 + primary-for std::ios_base::failure (0x0x7f51be0482d8) + std::runtime_error (0x0x7f51be0483a8) 0 + primary-for std::system_error (0x0x7f51be048340) + std::exception (0x0x7f51be00a660) 0 nearly-empty + primary-for std::runtime_error (0x0x7f51be0483a8) + +Class std::ios_base::_Callback_list + size=24 align=8 + base size=24 base align=8 +std::ios_base::_Callback_list (0x0x7f51be00a6c0) 0 + +Class std::ios_base::_Words + size=16 align=8 + base size=16 base align=8 +std::ios_base::_Words (0x0x7f51be00a720) 0 + +Class std::ios_base::Init + size=1 align=1 + base size=0 base align=1 +std::ios_base::Init (0x0x7f51be00a780) 0 empty + +Vtable for std::ios_base +std::ios_base::_ZTVSt8ios_base: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8ios_base) +16 (int (*)(...))std::ios_base::~ios_base +24 (int (*)(...))std::ios_base::~ios_base + +Class std::ios_base + size=216 align=8 + base size=216 base align=8 +std::ios_base (0x0x7f51be00a600) 0 + vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u) + +Class std::ctype_base + size=1 align=1 + base size=0 base align=1 +std::ctype_base (0x0x7f51be00af00) 0 empty + +Class std::__num_base + size=1 align=1 + base size=0 base align=1 +std::__num_base (0x0x7f51bdd68600) 0 empty + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSo: 2u entries +0 ((& std::basic_ostream::_ZTVSo) + 24u) +8 ((& std::basic_ostream::_ZTVSo) + 64u) + +VTT for std::basic_ostream +std::basic_ostream::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_ostream::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSi: 2u entries +0 ((& std::basic_istream::_ZTVSi) + 24u) +8 ((& std::basic_istream::_ZTVSi) + 64u) + +VTT for std::basic_istream +std::basic_istream::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries +0 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_istream::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u) + +Construction vtable for std::basic_istream (0x0x7f51bd8adea0 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd0_Si: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISi) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISi) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7f51bd8adf70 instance) in std::basic_iostream +std::basic_iostream::_ZTCSd16_So: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISo) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISo) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSd: 7u entries +0 ((& std::basic_iostream::_ZTVSd) + 24u) +8 ((& std::basic_iostream::_ZTCSd0_Si) + 24u) +16 ((& std::basic_iostream::_ZTCSd0_Si) + 64u) +24 ((& std::basic_iostream::_ZTCSd16_So) + 24u) +32 ((& std::basic_iostream::_ZTCSd16_So) + 64u) +40 ((& std::basic_iostream::_ZTVSd) + 104u) +48 ((& std::basic_iostream::_ZTVSd) + 64u) + +Construction vtable for std::basic_istream (0x0x7f51bd8adaf8 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries +0 24u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551592u +48 (int (*)(...))-24 +56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE) +64 0u +72 0u + +Construction vtable for std::basic_ostream (0x0x7f51bd95b068 instance) in std::basic_iostream +std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries +0 8u +8 (int (*)(...))0 +16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +24 0u +32 0u +40 18446744073709551608u +48 (int (*)(...))-8 +56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE) +64 0u +72 0u + +VTT for std::basic_iostream +std::basic_iostream::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries +0 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u) +8 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u) +16 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u) +24 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u) +32 ((& std::basic_iostream::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u) +40 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u) +48 ((& std::basic_iostream::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u) + +Class QByteArrayDataPtr + size=8 align=8 + base size=8 base align=8 +QByteArrayDataPtr (0x0x7f51bdb08e40) 0 + +Class QByteArray + size=8 align=8 + base size=8 base align=8 +QByteArray (0x0x7f51bdb08ea0) 0 + +Class QByteRef + size=16 align=8 + base size=12 base align=8 +QByteRef (0x0x7f51bd682240) 0 + +Class QStringDataPtr + size=8 align=8 + base size=8 base align=8 +QStringDataPtr (0x0x7f51bd6825a0) 0 + +Class QStringView + size=16 align=8 + base size=16 base align=8 +QStringView (0x0x7f51bd682a20) 0 + +Class QLatin1String + size=16 align=8 + base size=16 base align=8 +QLatin1String (0x0x7f51bd7a08a0) 0 + +Class QString::Null + size=1 align=1 + base size=0 base align=1 +QString::Null (0x0x7f51bd7a0f00) 0 empty + +Class QString + size=8 align=8 + base size=8 base align=8 +QString (0x0x7f51bd7a0ea0) 0 + +Class QCharRef + size=16 align=8 + base size=12 base align=8 +QCharRef (0x0x7f51bd27d000) 0 + +Class QStringRef + size=16 align=8 + base size=16 base align=8 +QStringRef (0x0x7f51bd27dc00) 0 + +Class QtPrivate::QHashCombine + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombine (0x0x7f51bd3e08a0) 0 empty + +Class QtPrivate::QHashCombineCommutative + size=1 align=1 + base size=0 base align=1 +QtPrivate::QHashCombineCommutative (0x0x7f51bd3e0900) 0 empty + +Class std::__detail::_List_node_base + size=16 align=8 + base size=16 base align=8 +std::__detail::_List_node_base (0x0x7f51bd3e0960) 0 + +Class QListData::NotArrayCompatibleLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotArrayCompatibleLayout (0x0x7f51bd3e0d20) 0 empty + +Class QListData::NotIndirectLayout + size=1 align=1 + base size=0 base align=1 +QListData::NotIndirectLayout (0x0x7f51bd3e0d80) 0 empty + +Class QListData::ArrayCompatibleLayout + size=1 align=1 + base size=1 base align=1 +QListData::ArrayCompatibleLayout (0x0x7f51bd3dcc30) 0 empty + QListData::NotIndirectLayout (0x0x7f51bd3e0de0) 0 empty + +Class QListData::InlineWithPaddingLayout + size=1 align=1 + base size=1 base align=1 +QListData::InlineWithPaddingLayout (0x0x7f51bd233460) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f51bd3e0e40) 0 empty + QListData::NotIndirectLayout (0x0x7f51bd3e0ea0) 0 empty + +Class QListData::IndirectLayout + size=1 align=1 + base size=1 base align=1 +QListData::IndirectLayout (0x0x7f51bd3dcc98) 0 empty + QListData::NotArrayCompatibleLayout (0x0x7f51bd3e0f00) 0 empty + +Class QListData::Data + size=24 align=8 + base size=24 base align=8 +QListData::Data (0x0x7f51bd3e0f60) 0 + +Class QListData + size=8 align=8 + base size=8 base align=8 +QListData (0x0x7f51bd3e0cc0) 0 + +Class QRegExp + size=8 align=8 + base size=8 base align=8 +QRegExp (0x0x7f51bd244420) 0 + +Class QStringMatcher::Data + size=272 align=8 + base size=272 base align=8 +QStringMatcher::Data (0x0x7f51bcfe7660) 0 + +Class QStringMatcher + size=1048 align=8 + base size=1048 base align=8 +QStringMatcher (0x0x7f51bcfe7600) 0 + +Class QStringList + size=8 align=8 + base size=8 base align=8 +QStringList (0x0x7f51bcfed6e8) 0 + QList (0x0x7f51bcfed750) 0 + QListSpecialMethods (0x0x7f51bcfe7840) 0 empty + +Class QScopedPointerPodDeleter + size=1 align=1 + base size=0 base align=1 +QScopedPointerPodDeleter (0x0x7f51bcfe7c60) 0 empty + +Class std::_Rb_tree_node_base + size=32 align=8 + base size=32 base align=8 +std::_Rb_tree_node_base (0x0x7f51bccd6840) 0 + +Class std::allocator_arg_t + size=1 align=1 + base size=0 base align=1 +std::allocator_arg_t (0x0x7f51bccd6ea0) 0 empty + +Class std::__uses_alloc_base + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc_base (0x0x7f51bcaac060) 0 empty + +Class std::__uses_alloc0::_Sink + size=1 align=1 + base size=0 base align=1 +std::__uses_alloc0::_Sink (0x0x7f51bcaac120) 0 empty + +Class std::__uses_alloc0 + size=1 align=1 + base size=1 base align=1 +std::__uses_alloc0 (0x0x7f51bcfedbc8) 0 + std::__uses_alloc_base (0x0x7f51bcaac0c0) 0 empty + +Class std::_Swallow_assign + size=1 align=1 + base size=0 base align=1 +std::_Swallow_assign (0x0x7f51bcb9e180) 0 empty + +Class QtPrivate::AbstractDebugStreamFunction + size=16 align=8 + base size=16 base align=8 +QtPrivate::AbstractDebugStreamFunction (0x0x7f51bcb9e3c0) 0 + +Class QtPrivate::AbstractComparatorFunction + size=24 align=8 + base size=24 base align=8 +QtPrivate::AbstractComparatorFunction (0x0x7f51bcb9e480) 0 + +Class QtPrivate::AbstractConverterFunction + size=8 align=8 + base size=8 base align=8 +QtPrivate::AbstractConverterFunction (0x0x7f51bcb9e5a0) 0 + +Class QMetaType + size=80 align=8 + base size=80 base align=8 +QMetaType (0x0x7f51bcb9e720) 0 + +Class QtMetaTypePrivate::VariantData + size=24 align=8 + base size=20 base align=8 +QtMetaTypePrivate::VariantData (0x0x7f51bcb9eb40) 0 + +Class QtMetaTypePrivate::VectorBoolElements + size=1 align=1 + base size=0 base align=1 +QtMetaTypePrivate::VectorBoolElements (0x0x7f51bcb9ec60) 0 empty + +Class QtMetaTypePrivate::QSequentialIterableImpl + size=104 align=8 + base size=104 base align=8 +QtMetaTypePrivate::QSequentialIterableImpl (0x0x7f51bc926600) 0 + +Class QtMetaTypePrivate::QAssociativeIterableImpl + size=112 align=8 + base size=112 base align=8 +QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7f51bc926a20) 0 + +Class QtMetaTypePrivate::QPairVariantInterfaceImpl + size=40 align=8 + base size=40 base align=8 +QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7f51bc926d20) 0 + +Class std::chrono::_V2::system_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::system_clock (0x0x7f51bc822720) 0 empty + +Class std::chrono::_V2::steady_clock + size=1 align=1 + base size=0 base align=1 +std::chrono::_V2::steady_clock (0x0x7f51bc5705a0) 0 empty + +Vtable for QObjectData +QObjectData::_ZTV11QObjectData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QObjectData) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))__cxa_pure_virtual + +Class QObjectData + size=48 align=8 + base size=48 base align=8 +QObjectData (0x0x7f51bc570600) 0 + vptr=((& QObjectData::_ZTV11QObjectData) + 16u) + +Class QObject::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObject::QPrivateSignal (0x0x7f51bc5707e0) 0 empty + +Vtable for QObject +QObject::_ZTV7QObject: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QObject) +16 (int (*)(...))QObject::metaObject +24 (int (*)(...))QObject::qt_metacast +32 (int (*)(...))QObject::qt_metacall +40 (int (*)(...))QObject::~QObject +48 (int (*)(...))QObject::~QObject +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObject + size=16 align=8 + base size=16 base align=8 +QObject (0x0x7f51bc570780) 0 + vptr=((& QObject::_ZTV7QObject) + 16u) + +Vtable for QObjectUserData +QObjectUserData::_ZTV15QObjectUserData: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QObjectUserData) +16 (int (*)(...))QObjectUserData::~QObjectUserData +24 (int (*)(...))QObjectUserData::~QObjectUserData + +Class QObjectUserData + size=8 align=8 + base size=8 base align=8 +QObjectUserData (0x0x7f51bc639a80) 0 nearly-empty + vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u) + +Class QSignalBlocker + size=16 align=8 + base size=10 base align=8 +QSignalBlocker (0x0x7f51bc639ae0) 0 + +Class QAbstractAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractAnimation::QPrivateSignal (0x0x7f51bc639ba0) 0 empty + +Vtable for QAbstractAnimation +QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractAnimation) +16 (int (*)(...))QAbstractAnimation::metaObject +24 (int (*)(...))QAbstractAnimation::qt_metacast +32 (int (*)(...))QAbstractAnimation::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAbstractAnimation + size=16 align=8 + base size=16 base align=8 +QAbstractAnimation (0x0x7f51bc266270) 0 + vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u) + QObject (0x0x7f51bc639b40) 0 + primary-for QAbstractAnimation (0x0x7f51bc266270) + +Class QAnimationDriver::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationDriver::QPrivateSignal (0x0x7f51bc639c60) 0 empty + +Vtable for QAnimationDriver +QAnimationDriver::_ZTV16QAnimationDriver: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QAnimationDriver) +16 (int (*)(...))QAnimationDriver::metaObject +24 (int (*)(...))QAnimationDriver::qt_metacast +32 (int (*)(...))QAnimationDriver::qt_metacall +40 (int (*)(...))QAnimationDriver::~QAnimationDriver +48 (int (*)(...))QAnimationDriver::~QAnimationDriver +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAnimationDriver::advance +120 (int (*)(...))QAnimationDriver::elapsed +128 (int (*)(...))QAnimationDriver::start +136 (int (*)(...))QAnimationDriver::stop + +Class QAnimationDriver + size=16 align=8 + base size=16 base align=8 +QAnimationDriver (0x0x7f51bc2662d8) 0 + vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16u) + QObject (0x0x7f51bc639c00) 0 + primary-for QAnimationDriver (0x0x7f51bc2662d8) + +Class QEventLoop::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventLoop::QPrivateSignal (0x0x7f51bc639d20) 0 empty + +Vtable for QEventLoop +QEventLoop::_ZTV10QEventLoop: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QEventLoop) +16 (int (*)(...))QEventLoop::metaObject +24 (int (*)(...))QEventLoop::qt_metacast +32 (int (*)(...))QEventLoop::qt_metacall +40 (int (*)(...))QEventLoop::~QEventLoop +48 (int (*)(...))QEventLoop::~QEventLoop +56 (int (*)(...))QEventLoop::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QEventLoop + size=16 align=8 + base size=16 base align=8 +QEventLoop (0x0x7f51bc266340) 0 + vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u) + QObject (0x0x7f51bc639cc0) 0 + primary-for QEventLoop (0x0x7f51bc266340) + +Class QEventLoopLocker + size=8 align=8 + base size=8 base align=8 +QEventLoopLocker (0x0x7f51bc639f00) 0 + +Class QAbstractEventDispatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractEventDispatcher::QPrivateSignal (0x0x7f51bc2f2000) 0 empty + +Class QAbstractEventDispatcher::TimerInfo + size=12 align=4 + base size=12 base align=4 +QAbstractEventDispatcher::TimerInfo (0x0x7f51bc2f2060) 0 + +Vtable for QAbstractEventDispatcher +QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher) +16 (int (*)(...))QAbstractEventDispatcher::metaObject +24 (int (*)(...))QAbstractEventDispatcher::qt_metacast +32 (int (*)(...))QAbstractEventDispatcher::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual +192 (int (*)(...))__cxa_pure_virtual +200 (int (*)(...))__cxa_pure_virtual +208 (int (*)(...))QAbstractEventDispatcher::startingUp +216 (int (*)(...))QAbstractEventDispatcher::closingDown + +Class QAbstractEventDispatcher + size=16 align=8 + base size=16 base align=8 +QAbstractEventDispatcher (0x0x7f51bc266478) 0 + vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u) + QObject (0x0x7f51bc639f60) 0 + primary-for QAbstractEventDispatcher (0x0x7f51bc266478) + +Vtable for std::type_info +std::type_info::_ZTVSt9type_info: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt9type_info) +16 (int (*)(...))std::type_info::~type_info +24 (int (*)(...))std::type_info::~type_info +32 (int (*)(...))std::type_info::__is_pointer_p +40 (int (*)(...))std::type_info::__is_function_p +48 (int (*)(...))std::type_info::__do_catch +56 (int (*)(...))std::type_info::__do_upcast + +Class std::type_info + size=16 align=8 + base size=16 base align=8 +std::type_info (0x0x7f51bc2f2300) 0 + vptr=((& std::type_info::_ZTVSt9type_info) + 16u) + +Vtable for std::bad_cast +std::bad_cast::_ZTVSt8bad_cast: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt8bad_cast) +16 (int (*)(...))std::bad_cast::~bad_cast +24 (int (*)(...))std::bad_cast::~bad_cast +32 (int (*)(...))std::bad_cast::what + +Class std::bad_cast + size=8 align=8 + base size=8 base align=8 +std::bad_cast (0x0x7f51bc266680) 0 nearly-empty + vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16u) + std::exception (0x0x7f51bc2f2360) 0 nearly-empty + primary-for std::bad_cast (0x0x7f51bc266680) + +Vtable for std::bad_typeid +std::bad_typeid::_ZTVSt10bad_typeid: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt10bad_typeid) +16 (int (*)(...))std::bad_typeid::~bad_typeid +24 (int (*)(...))std::bad_typeid::~bad_typeid +32 (int (*)(...))std::bad_typeid::what + +Class std::bad_typeid + size=8 align=8 + base size=8 base align=8 +std::bad_typeid (0x0x7f51bc2666e8) 0 nearly-empty + vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16u) + std::exception (0x0x7f51bc2f23c0) 0 nearly-empty + primary-for std::bad_typeid (0x0x7f51bc2666e8) + +Vtable for std::bad_function_call +std::bad_function_call::_ZTVSt17bad_function_call: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt17bad_function_call) +16 (int (*)(...))std::bad_function_call::~bad_function_call +24 (int (*)(...))std::bad_function_call::~bad_function_call +32 (int (*)(...))std::bad_function_call::what + +Class std::bad_function_call + size=8 align=8 + base size=8 base align=8 +std::bad_function_call (0x0x7f51bc3da958) 0 nearly-empty + vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16u) + std::exception (0x0x7f51bc087480) 0 nearly-empty + primary-for std::bad_function_call (0x0x7f51bc3da958) + +Class std::_Nocopy_types + size=16 align=8 + base size=16 base align=8 +std::_Nocopy_types (0x0x7f51bc087540) 0 + +Class std::_Any_data + size=16 align=8 + base size=16 base align=8 +std::_Any_data (0x0x7f51bc0875a0) 0 + +Class std::_Function_base + size=24 align=8 + base size=24 base align=8 +std::_Function_base (0x0x7f51bc0876c0) 0 + +Class QMapNodeBase + size=24 align=8 + base size=24 base align=8 +QMapNodeBase (0x0x7f51bc087ba0) 0 + +Class QMapDataBase + size=40 align=8 + base size=40 base align=8 +QMapDataBase (0x0x7f51bc13f120) 0 + +Class QHashData::Node + size=16 align=8 + base size=16 base align=8 +QHashData::Node (0x0x7f51bc13f4e0) 0 + +Class QHashData + size=48 align=8 + base size=44 base align=8 +QHashData (0x0x7f51bc13f480) 0 + +Class QHashDummyValue + size=1 align=1 + base size=0 base align=1 +QHashDummyValue (0x0x7f51bc13f540) 0 empty + +Class QVariant::PrivateShared + size=16 align=8 + base size=12 base align=8 +QVariant::PrivateShared (0x0x7f51bc13fde0) 0 + +Class QVariant::Private::Data + size=8 align=8 + base size=8 base align=8 +QVariant::Private::Data (0x0x7f51bc13fea0) 0 + +Class QVariant::Private + size=16 align=8 + base size=12 base align=8 +QVariant::Private (0x0x7f51bc13fe40) 0 + +Class QVariant::Handler + size=72 align=8 + base size=72 base align=8 +QVariant::Handler (0x0x7f51bc13ff00) 0 + +Class QVariant + size=16 align=8 + base size=16 base align=8 +QVariant (0x0x7f51bc13fd80) 0 + +Class QVariantComparisonHelper + size=8 align=8 + base size=8 base align=8 +QVariantComparisonHelper (0x0x7f51bc03ba20) 0 + +Class QSequentialIterable::const_iterator + size=112 align=8 + base size=112 base align=8 +QSequentialIterable::const_iterator (0x0x7f51bbcd10c0) 0 + +Class QSequentialIterable + size=104 align=8 + base size=104 base align=8 +QSequentialIterable (0x0x7f51bbcd1060) 0 + +Class QAssociativeIterable::const_iterator + size=120 align=8 + base size=120 base align=8 +QAssociativeIterable::const_iterator (0x0x7f51bbcd1180) 0 + +Class QAssociativeIterable + size=112 align=8 + base size=112 base align=8 +QAssociativeIterable (0x0x7f51bbcd1120) 0 + +Class QModelIndex + size=24 align=8 + base size=24 base align=8 +QModelIndex (0x0x7f51bbdf2480) 0 + +Class QPersistentModelIndex + size=8 align=8 + base size=8 base align=8 +QPersistentModelIndex (0x0x7f51bbdf2b40) 0 + +Class QAbstractItemModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractItemModel::QPrivateSignal (0x0x7f51bbbda2a0) 0 empty + +Vtable for QAbstractItemModel +QAbstractItemModel::_ZTV18QAbstractItemModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractItemModel) +16 (int (*)(...))QAbstractItemModel::metaObject +24 (int (*)(...))QAbstractItemModel::qt_metacast +32 (int (*)(...))QAbstractItemModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractItemModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractItemModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractItemModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractItemModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractItemModel + size=16 align=8 + base size=16 base align=8 +QAbstractItemModel (0x0x7f51bbbd96e8) 0 + vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u) + QObject (0x0x7f51bbbda240) 0 + primary-for QAbstractItemModel (0x0x7f51bbbd96e8) + +Class QAbstractTableModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTableModel::QPrivateSignal (0x0x7f51bbbdab40) 0 empty + +Vtable for QAbstractTableModel +QAbstractTableModel::_ZTV19QAbstractTableModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTableModel) +16 (int (*)(...))QAbstractTableModel::metaObject +24 (int (*)(...))QAbstractTableModel::qt_metacast +32 (int (*)(...))QAbstractTableModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractTableModel::index +120 (int (*)(...))QAbstractTableModel::parent +128 (int (*)(...))QAbstractTableModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractTableModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractTableModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractTableModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractTableModel + size=16 align=8 + base size=16 base align=8 +QAbstractTableModel (0x0x7f51bbbd9dd0) 0 + vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u) + QAbstractItemModel (0x0x7f51bbbd9e38) 0 + primary-for QAbstractTableModel (0x0x7f51bbbd9dd0) + QObject (0x0x7f51bbbdaae0) 0 + primary-for QAbstractItemModel (0x0x7f51bbbd9e38) + +Class QAbstractListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractListModel::QPrivateSignal (0x0x7f51bbbdac00) 0 empty + +Vtable for QAbstractListModel +QAbstractListModel::_ZTV18QAbstractListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QAbstractListModel) +16 (int (*)(...))QAbstractListModel::metaObject +24 (int (*)(...))QAbstractListModel::qt_metacast +32 (int (*)(...))QAbstractListModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QAbstractListModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))QAbstractItemModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QAbstractItemModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QAbstractListModel::flags +328 (int (*)(...))QAbstractItemModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QAbstractListModel + size=16 align=8 + base size=16 base align=8 +QAbstractListModel (0x0x7f51bbbd9ea0) 0 + vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u) + QAbstractItemModel (0x0x7f51bbbd9f08) 0 + primary-for QAbstractListModel (0x0x7f51bbbd9ea0) + QObject (0x0x7f51bbbdaba0) 0 + primary-for QAbstractItemModel (0x0x7f51bbbd9f08) + +Vtable for QAbstractNativeEventFilter +QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QAbstractNativeEventFilter + size=16 align=8 + base size=16 base align=8 +QAbstractNativeEventFilter (0x0x7f51bbbdaea0) 0 + vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16u) + +Class QAbstractProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractProxyModel::QPrivateSignal (0x0x7f51bbbdaf60) 0 empty + +Vtable for QAbstractProxyModel +QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractProxyModel) +16 (int (*)(...))QAbstractProxyModel::metaObject +24 (int (*)(...))QAbstractProxyModel::qt_metacast +32 (int (*)(...))QAbstractProxyModel::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractProxyModel::sibling +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QAbstractProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QAbstractProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QAbstractItemModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QAbstractItemModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QAbstractProxyModel::setSourceModel +392 (int (*)(...))__cxa_pure_virtual +400 (int (*)(...))__cxa_pure_virtual +408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource +416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource + +Class QAbstractProxyModel + size=16 align=8 + base size=16 base align=8 +QAbstractProxyModel (0x0x7f51bb8e7068) 0 + vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16u) + QAbstractItemModel (0x0x7f51bb8e70d0) 0 + primary-for QAbstractProxyModel (0x0x7f51bb8e7068) + QObject (0x0x7f51bbbdaf00) 0 + primary-for QAbstractItemModel (0x0x7f51bb8e70d0) + +Class QAbstractState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractState::QPrivateSignal (0x0x7f51bb936060) 0 empty + +Vtable for QAbstractState +QAbstractState::_ZTV14QAbstractState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QAbstractState) +16 (int (*)(...))QAbstractState::metaObject +24 (int (*)(...))QAbstractState::qt_metacast +32 (int (*)(...))QAbstractState::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractState + size=16 align=8 + base size=16 base align=8 +QAbstractState (0x0x7f51bb8e7138) 0 + vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u) + QObject (0x0x7f51bb936000) 0 + primary-for QAbstractState (0x0x7f51bb8e7138) + +Class QAbstractTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAbstractTransition::QPrivateSignal (0x0x7f51bb936120) 0 empty + +Vtable for QAbstractTransition +QAbstractTransition::_ZTV19QAbstractTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QAbstractTransition) +16 (int (*)(...))QAbstractTransition::metaObject +24 (int (*)(...))QAbstractTransition::qt_metacast +32 (int (*)(...))QAbstractTransition::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAbstractTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QAbstractTransition + size=16 align=8 + base size=16 base align=8 +QAbstractTransition (0x0x7f51bb8e71a0) 0 + vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u) + QObject (0x0x7f51bb9360c0) 0 + primary-for QAbstractTransition (0x0x7f51bb8e71a0) + +Class QAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QAnimationGroup::QPrivateSignal (0x0x7f51bb9361e0) 0 empty + +Vtable for QAnimationGroup +QAnimationGroup::_ZTV15QAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QAnimationGroup) +16 (int (*)(...))QAnimationGroup::metaObject +24 (int (*)(...))QAnimationGroup::qt_metacast +32 (int (*)(...))QAnimationGroup::qt_metacall +40 0u +48 0u +56 (int (*)(...))QAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QAnimationGroup + size=16 align=8 + base size=16 base align=8 +QAnimationGroup (0x0x7f51bb8e7208) 0 + vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u) + QAbstractAnimation (0x0x7f51bb8e7270) 0 + primary-for QAnimationGroup (0x0x7f51bb8e7208) + QObject (0x0x7f51bb936180) 0 + primary-for QAbstractAnimation (0x0x7f51bb8e7270) + +Class QBasicTimer + size=4 align=4 + base size=4 base align=4 +QBasicTimer (0x0x7f51bb982f00) 0 + +Class QBitArray + size=8 align=8 + base size=8 base align=8 +QBitArray (0x0x7f51bb9c81e0) 0 + +Class QBitRef + size=16 align=8 + base size=12 base align=8 +QBitRef (0x0x7f51bb9c82a0) 0 + +Class QIODevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIODevice::QPrivateSignal (0x0x7f51bb9c85a0) 0 empty + +Vtable for QIODevice +QIODevice::_ZTV9QIODevice: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QIODevice) +16 (int (*)(...))QIODevice::metaObject +24 (int (*)(...))QIODevice::qt_metacast +32 (int (*)(...))QIODevice::qt_metacall +40 0u +48 0u +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QIODevice::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QIODevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))__cxa_pure_virtual +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))__cxa_pure_virtual + +Class QIODevice + size=16 align=8 + base size=16 base align=8 +QIODevice (0x0x7f51bb8e78f0) 0 + vptr=((& QIODevice::_ZTV9QIODevice) + 16u) + QObject (0x0x7f51bb9c8540) 0 + primary-for QIODevice (0x0x7f51bb8e78f0) + +Class QBuffer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QBuffer::QPrivateSignal (0x0x7f51bb9c87e0) 0 empty + +Vtable for QBuffer +QBuffer::_ZTV7QBuffer: 30u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QBuffer) +16 (int (*)(...))QBuffer::metaObject +24 (int (*)(...))QBuffer::qt_metacast +32 (int (*)(...))QBuffer::qt_metacall +40 (int (*)(...))QBuffer::~QBuffer +48 (int (*)(...))QBuffer::~QBuffer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QBuffer::connectNotify +104 (int (*)(...))QBuffer::disconnectNotify +112 (int (*)(...))QIODevice::isSequential +120 (int (*)(...))QBuffer::open +128 (int (*)(...))QBuffer::close +136 (int (*)(...))QBuffer::pos +144 (int (*)(...))QBuffer::size +152 (int (*)(...))QBuffer::seek +160 (int (*)(...))QBuffer::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QBuffer::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QBuffer::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QBuffer::writeData + +Class QBuffer + size=16 align=8 + base size=16 base align=8 +QBuffer (0x0x7f51bb8e7a28) 0 + vptr=((& QBuffer::_ZTV7QBuffer) + 16u) + QIODevice (0x0x7f51bb8e7a90) 0 + primary-for QBuffer (0x0x7f51bb8e7a28) + QObject (0x0x7f51bb9c8780) 0 + primary-for QIODevice (0x0x7f51bb8e7a90) + +Class QByteArrayMatcher::Data + size=272 align=8 + base size=272 base align=8 +QByteArrayMatcher::Data (0x0x7f51bb9c88a0) 0 + +Class QByteArrayMatcher + size=1040 align=8 + base size=1040 base align=8 +QByteArrayMatcher (0x0x7f51bb9c8840) 0 + +Class QStaticByteArrayMatcherBase::Skiptable + size=256 align=1 + base size=256 base align=1 +QStaticByteArrayMatcherBase::Skiptable (0x0x7f51bb9c89c0) 0 + +Class QStaticByteArrayMatcherBase + size=256 align=16 + base size=256 base align=16 +QStaticByteArrayMatcherBase (0x0x7f51bb9c8960) 0 + +Class QSharedData + size=4 align=4 + base size=4 base align=4 +QSharedData (0x0x7f51bb9c8ba0) 0 + +Class QDate + size=8 align=8 + base size=8 base align=8 +QDate (0x0x7f51bb9c8d80) 0 + +Class QTime + size=4 align=4 + base size=4 base align=4 +QTime (0x0x7f51bb737060) 0 + +Class QDateTime::ShortData + size=8 align=8 + base size=8 base align=8 +QDateTime::ShortData (0x0x7f51bb7377e0) 0 + +Class QDateTime::Data + size=8 align=8 + base size=8 base align=8 +QDateTime::Data (0x0x7f51bb737840) 0 + +Class QDateTime + size=8 align=8 + base size=8 base align=8 +QDateTime (0x0x7f51bb737780) 0 + +Class QLocale + size=8 align=8 + base size=8 base align=8 +QLocale (0x0x7f51bb7fa960) 0 + +Vtable for QTextStream +QTextStream::_ZTV11QTextStream: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTextStream) +16 (int (*)(...))QTextStream::~QTextStream +24 (int (*)(...))QTextStream::~QTextStream + +Class QTextStream + size=16 align=8 + base size=16 base align=8 +QTextStream (0x0x7f51bb7faf60) 0 + vptr=((& QTextStream::_ZTV11QTextStream) + 16u) + +Class QTextStreamManipulator + size=40 align=8 + base size=38 base align=8 +QTextStreamManipulator (0x0x7f51bb517240) 0 + +Class QContiguousCacheData + size=24 align=4 + base size=24 base align=4 +QContiguousCacheData (0x0x7f51bb517480) 0 + +Class QtSharedPointer::NormalDeleter + size=1 align=1 + base size=0 base align=1 +QtSharedPointer::NormalDeleter (0x0x7f51bb517b40) 0 empty + +Class QtSharedPointer::ExternalRefCountData + size=16 align=8 + base size=16 base align=8 +QtSharedPointer::ExternalRefCountData (0x0x7f51bb517cc0) 0 + +Class QDebug::Stream + size=80 align=8 + base size=76 base align=8 +QDebug::Stream (0x0x7f51bb297240) 0 + +Class QDebug + size=8 align=8 + base size=8 base align=8 +QDebug (0x0x7f51bb2971e0) 0 + +Class QDebugStateSaver + size=8 align=8 + base size=8 base align=8 +QDebugStateSaver (0x0x7f51bb056540) 0 + +Class QNoDebug + size=1 align=1 + base size=0 base align=1 +QNoDebug (0x0x7f51bb056600) 0 empty + +Class QCborError + size=4 align=4 + base size=4 base align=4 +QCborError (0x0x7f51bb0d9960) 0 + +Class QRegularExpression + size=8 align=8 + base size=8 base align=8 +QRegularExpression (0x0x7f51bb0d9ae0) 0 + +Class QRegularExpressionMatch + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatch (0x0x7f51bb166120) 0 + +Class QRegularExpressionMatchIterator + size=8 align=8 + base size=8 base align=8 +QRegularExpressionMatchIterator (0x0x7f51bb166420) 0 + +Class QUrl + size=8 align=8 + base size=8 base align=8 +QUrl (0x0x7f51bb1667e0) 0 + +Class QUuid + size=16 align=4 + base size=16 base align=4 +QUuid (0x0x7f51baeacea0) 0 + +Class QCborParserError + size=16 align=8 + base size=12 base align=8 +QCborParserError (0x0x7f51baf2d4e0) 0 + +Class QCborValue + size=24 align=8 + base size=20 base align=8 +QCborValue (0x0x7f51baf2d540) 0 + +Class QCborValueRef + size=16 align=8 + base size=16 base align=8 +QCborValueRef (0x0x7f51bad8f540) 0 + +Class QCborArray::Iterator + size=16 align=8 + base size=16 base align=8 +QCborArray::Iterator (0x0x7f51bad8fae0) 0 + +Class QCborArray::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborArray::ConstIterator (0x0x7f51bad8fb40) 0 + +Class QCborArray + size=8 align=8 + base size=8 base align=8 +QCborArray (0x0x7f51bad8fa80) 0 + +Class QCborMap::Iterator + size=16 align=8 + base size=16 base align=8 +QCborMap::Iterator (0x0x7f51baabfba0) 0 + +Class QCborMap::ConstIterator + size=16 align=8 + base size=16 base align=8 +QCborMap::ConstIterator (0x0x7f51baabfc00) 0 + +Class QCborMap + size=8 align=8 + base size=8 base align=8 +QCborMap (0x0x7f51baabfb40) 0 + +Class qfloat16 + size=2 align=2 + base size=2 base align=2 +qfloat16 (0x0x7f51ba886780) 0 + +Class QCborStreamWriter + size=8 align=8 + base size=8 base align=8 +QCborStreamWriter (0x0x7f51ba886b40) 0 + +Class QCborStreamReader + size=24 align=8 + base size=20 base align=8 +QCborStreamReader (0x0x7f51ba9db540) 0 + +Class QCollatorSortKey + size=8 align=8 + base size=8 base align=8 +QCollatorSortKey (0x0x7f51ba9dbba0) 0 + +Class QCollator + size=8 align=8 + base size=8 base align=8 +QCollator (0x0x7f51ba9dbc60) 0 + +Class QCommandLineOption + size=8 align=8 + base size=8 base align=8 +QCommandLineOption (0x0x7f51ba6dec60) 0 + +Vtable for QEvent +QEvent::_ZTV6QEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QEvent) +16 (int (*)(...))QEvent::~QEvent +24 (int (*)(...))QEvent::~QEvent + +Class QEvent + size=24 align=8 + base size=20 base align=8 +QEvent (0x0x7f51ba71b120) 0 + vptr=((& QEvent::_ZTV6QEvent) + 16u) + +Vtable for QTimerEvent +QTimerEvent::_ZTV11QTimerEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTimerEvent) +16 (int (*)(...))QTimerEvent::~QTimerEvent +24 (int (*)(...))QTimerEvent::~QTimerEvent + +Class QTimerEvent + size=24 align=8 + base size=24 base align=8 +QTimerEvent (0x0x7f51ba71e068) 0 + vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u) + QEvent (0x0x7f51ba71b180) 0 + primary-for QTimerEvent (0x0x7f51ba71e068) + +Vtable for QChildEvent +QChildEvent::_ZTV11QChildEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QChildEvent) +16 (int (*)(...))QChildEvent::~QChildEvent +24 (int (*)(...))QChildEvent::~QChildEvent + +Class QChildEvent + size=32 align=8 + base size=32 base align=8 +QChildEvent (0x0x7f51ba71e0d0) 0 + vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u) + QEvent (0x0x7f51ba71b1e0) 0 + primary-for QChildEvent (0x0x7f51ba71e0d0) + +Vtable for QDynamicPropertyChangeEvent +QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent) +16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent +24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent + +Class QDynamicPropertyChangeEvent + size=32 align=8 + base size=32 base align=8 +QDynamicPropertyChangeEvent (0x0x7f51ba71e618) 0 + vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u) + QEvent (0x0x7f51ba71b6c0) 0 + primary-for QDynamicPropertyChangeEvent (0x0x7f51ba71e618) + +Vtable for QDeferredDeleteEvent +QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent) +16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent +24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent + +Class QDeferredDeleteEvent + size=24 align=8 + base size=24 base align=8 +QDeferredDeleteEvent (0x0x7f51ba71e680) 0 + vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16u) + QEvent (0x0x7f51ba71b720) 0 + primary-for QDeferredDeleteEvent (0x0x7f51ba71e680) + +Class QCoreApplication::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QCoreApplication::QPrivateSignal (0x0x7f51ba71b7e0) 0 empty + +Vtable for QCoreApplication +QCoreApplication::_ZTV16QCoreApplication: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QCoreApplication) +16 (int (*)(...))QCoreApplication::metaObject +24 (int (*)(...))QCoreApplication::qt_metacast +32 (int (*)(...))QCoreApplication::qt_metacall +40 (int (*)(...))QCoreApplication::~QCoreApplication +48 (int (*)(...))QCoreApplication::~QCoreApplication +56 (int (*)(...))QCoreApplication::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QCoreApplication::notify +120 (int (*)(...))QCoreApplication::compressEvent + +Class QCoreApplication + size=16 align=8 + base size=16 base align=8 +QCoreApplication (0x0x7f51ba71e6e8) 0 + vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u) + QObject (0x0x7f51ba71b780) 0 + primary-for QCoreApplication (0x0x7f51ba71e6e8) + +Class QCommandLineParser + size=8 align=8 + base size=8 base align=8 +QCommandLineParser (0x0x7f51ba71b840) 0 + +Class QCryptographicHash + size=8 align=8 + base size=8 base align=8 +QCryptographicHash (0x0x7f51ba71b8a0) 0 + +Class QDataStream + size=32 align=8 + base size=32 base align=8 +QDataStream (0x0x7f51ba71b900) 0 + +Class QtPrivate::StreamStateSaver + size=16 align=8 + base size=12 base align=8 +QtPrivate::StreamStateSaver (0x0x7f51ba71b9c0) 0 + +Class QElapsedTimer + size=16 align=8 + base size=16 base align=8 +QElapsedTimer (0x0x7f51ba71bea0) 0 + +Class QDeadlineTimer + size=16 align=8 + base size=16 base align=8 +QDeadlineTimer (0x0x7f51ba43c3c0) 0 + +Class QFileDevice::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileDevice::QPrivateSignal (0x0x7f51ba566240) 0 empty + +Vtable for QFileDevice +QFileDevice::_ZTV11QFileDevice: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFileDevice) +16 (int (*)(...))QFileDevice::metaObject +24 (int (*)(...))QFileDevice::qt_metacast +32 (int (*)(...))QFileDevice::qt_metacall +40 (int (*)(...))QFileDevice::~QFileDevice +48 (int (*)(...))QFileDevice::~QFileDevice +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QIODevice::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFileDevice::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QFileDevice + size=16 align=8 + base size=16 base align=8 +QFileDevice (0x0x7f51ba552b60) 0 + vptr=((& QFileDevice::_ZTV11QFileDevice) + 16u) + QIODevice (0x0x7f51ba552bc8) 0 + primary-for QFileDevice (0x0x7f51ba552b60) + QObject (0x0x7f51ba5661e0) 0 + primary-for QIODevice (0x0x7f51ba552bc8) + +Class QFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFile::QPrivateSignal (0x0x7f51ba566480) 0 empty + +Vtable for QFile +QFile::_ZTV5QFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI5QFile) +16 (int (*)(...))QFile::metaObject +24 (int (*)(...))QFile::qt_metacast +32 (int (*)(...))QFile::qt_metacall +40 (int (*)(...))QFile::~QFile +48 (int (*)(...))QFile::~QFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QFile + size=16 align=8 + base size=16 base align=8 +QFile (0x0x7f51ba552d00) 0 + vptr=((& QFile::_ZTV5QFile) + 16u) + QFileDevice (0x0x7f51ba552d68) 0 + primary-for QFile (0x0x7f51ba552d00) + QIODevice (0x0x7f51ba552dd0) 0 + primary-for QFileDevice (0x0x7f51ba552d68) + QObject (0x0x7f51ba566420) 0 + primary-for QIODevice (0x0x7f51ba552dd0) + +Class QFileInfo + size=8 align=8 + base size=8 base align=8 +QFileInfo (0x0x7f51ba566660) 0 + +Class QDir + size=8 align=8 + base size=8 base align=8 +QDir (0x0x7f51ba566a80) 0 + +Class QDirIterator + size=8 align=8 + base size=8 base align=8 +QDirIterator (0x0x7f51ba2840c0) 0 + +Class QEasingCurve + size=8 align=8 + base size=8 base align=8 +QEasingCurve (0x0x7f51ba284300) 0 + +Class QEventTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QEventTransition::QPrivateSignal (0x0x7f51ba369720) 0 empty + +Vtable for QEventTransition +QEventTransition::_ZTV16QEventTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QEventTransition) +16 (int (*)(...))QEventTransition::metaObject +24 (int (*)(...))QEventTransition::qt_metacast +32 (int (*)(...))QEventTransition::qt_metacall +40 (int (*)(...))QEventTransition::~QEventTransition +48 (int (*)(...))QEventTransition::~QEventTransition +56 (int (*)(...))QEventTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QEventTransition::eventTest +120 (int (*)(...))QEventTransition::onTransition + +Class QEventTransition + size=16 align=8 + base size=16 base align=8 +QEventTransition (0x0x7f51ba362dd0) 0 + vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u) + QAbstractTransition (0x0x7f51ba362e38) 0 + primary-for QEventTransition (0x0x7f51ba362dd0) + QObject (0x0x7f51ba3696c0) 0 + primary-for QAbstractTransition (0x0x7f51ba362e38) + +Vtable for QException +QException::_ZTV10QException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QException) +16 (int (*)(...))QException::~QException +24 (int (*)(...))QException::~QException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QException::raise +48 (int (*)(...))QException::clone + +Class QException + size=8 align=8 + base size=8 base align=8 +QException (0x0x7f51ba362ea0) 0 nearly-empty + vptr=((& QException::_ZTV10QException) + 16u) + std::exception (0x0x7f51ba369780) 0 nearly-empty + primary-for QException (0x0x7f51ba362ea0) + +Vtable for QUnhandledException +QUnhandledException::_ZTV19QUnhandledException: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QUnhandledException) +16 (int (*)(...))QUnhandledException::~QUnhandledException +24 (int (*)(...))QUnhandledException::~QUnhandledException +32 (int (*)(...))std::exception::what +40 (int (*)(...))QUnhandledException::raise +48 (int (*)(...))QUnhandledException::clone + +Class QUnhandledException + size=8 align=8 + base size=8 base align=8 +QUnhandledException (0x0x7f51ba362f08) 0 nearly-empty + vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16u) + QException (0x0x7f51ba362f70) 0 nearly-empty + primary-for QUnhandledException (0x0x7f51ba362f08) + std::exception (0x0x7f51ba3697e0) 0 nearly-empty + primary-for QException (0x0x7f51ba362f70) + +Class QtPrivate::ExceptionHolder + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionHolder (0x0x7f51ba369840) 0 + +Class QtPrivate::ExceptionStore + size=8 align=8 + base size=8 base align=8 +QtPrivate::ExceptionStore (0x0x7f51ba369900) 0 + +Vtable for QFactoryInterface +QFactoryInterface::_ZTV17QFactoryInterface: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QFactoryInterface) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class QFactoryInterface + size=8 align=8 + base size=8 base align=8 +QFactoryInterface (0x0x7f51ba369960) 0 nearly-empty + vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u) + +Class QFileSelector::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSelector::QPrivateSignal (0x0x7f51ba369a80) 0 empty + +Vtable for QFileSelector +QFileSelector::_ZTV13QFileSelector: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QFileSelector) +16 (int (*)(...))QFileSelector::metaObject +24 (int (*)(...))QFileSelector::qt_metacast +32 (int (*)(...))QFileSelector::qt_metacall +40 (int (*)(...))QFileSelector::~QFileSelector +48 (int (*)(...))QFileSelector::~QFileSelector +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSelector + size=16 align=8 + base size=16 base align=8 +QFileSelector (0x0x7f51ba3fb000) 0 + vptr=((& QFileSelector::_ZTV13QFileSelector) + 16u) + QObject (0x0x7f51ba369a20) 0 + primary-for QFileSelector (0x0x7f51ba3fb000) + +Class QFileSystemWatcher::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFileSystemWatcher::QPrivateSignal (0x0x7f51ba369b40) 0 empty + +Vtable for QFileSystemWatcher +QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFileSystemWatcher) +16 (int (*)(...))QFileSystemWatcher::metaObject +24 (int (*)(...))QFileSystemWatcher::qt_metacast +32 (int (*)(...))QFileSystemWatcher::qt_metacall +40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QFileSystemWatcher + size=16 align=8 + base size=16 base align=8 +QFileSystemWatcher (0x0x7f51ba3fb068) 0 + vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u) + QObject (0x0x7f51ba369ae0) 0 + primary-for QFileSystemWatcher (0x0x7f51ba3fb068) + +Class QFinalState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFinalState::QPrivateSignal (0x0x7f51ba369c00) 0 empty + +Vtable for QFinalState +QFinalState::_ZTV11QFinalState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QFinalState) +16 (int (*)(...))QFinalState::metaObject +24 (int (*)(...))QFinalState::qt_metacast +32 (int (*)(...))QFinalState::qt_metacall +40 (int (*)(...))QFinalState::~QFinalState +48 (int (*)(...))QFinalState::~QFinalState +56 (int (*)(...))QFinalState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFinalState::onEntry +120 (int (*)(...))QFinalState::onExit + +Class QFinalState + size=16 align=8 + base size=16 base align=8 +QFinalState (0x0x7f51ba3fb0d0) 0 + vptr=((& QFinalState::_ZTV11QFinalState) + 16u) + QAbstractState (0x0x7f51ba3fb138) 0 + primary-for QFinalState (0x0x7f51ba3fb0d0) + QObject (0x0x7f51ba369ba0) 0 + primary-for QAbstractState (0x0x7f51ba3fb138) + +Vtable for QRunnable +QRunnable::_ZTV9QRunnable: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QRunnable) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class QRunnable + size=16 align=8 + base size=12 base align=8 +QRunnable (0x0x7f51ba369c60) 0 + vptr=((& QRunnable::_ZTV9QRunnable) + 16u) + +Class QBasicMutex + size=8 align=8 + base size=8 base align=8 +QBasicMutex (0x0x7f51ba369cc0) 0 + +Class QMutex + size=8 align=8 + base size=8 base align=8 +QMutex (0x0x7f51ba3fb270) 0 + QBasicMutex (0x0x7f51ba369ea0) 0 + +Class QMutexLocker + size=8 align=8 + base size=8 base align=8 +QMutexLocker (0x0x7f51ba369f00) 0 + +Class QtPrivate::ResultItem + size=16 align=8 + base size=16 base align=8 +QtPrivate::ResultItem (0x0x7f51ba369f60) 0 + +Class QtPrivate::ResultIteratorBase + size=16 align=8 + base size=12 base align=8 +QtPrivate::ResultIteratorBase (0x0x7f51ba0ca000) 0 + +Vtable for QtPrivate::ResultStoreBase +QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE) +16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase +24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase + +Class QtPrivate::ResultStoreBase + size=48 align=8 + base size=44 base align=8 +QtPrivate::ResultStoreBase (0x0x7f51ba0ca120) 0 + vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16u) + +Vtable for QFutureInterfaceBase +QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI20QFutureInterfaceBase) +16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase +24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase + +Class QFutureInterfaceBase + size=16 align=8 + base size=16 base align=8 +QFutureInterfaceBase (0x0x7f51ba0ca960) 0 + vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u) + +Class QFutureWatcherBase::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QFutureWatcherBase::QPrivateSignal (0x0x7f51ba19c180) 0 empty + +Vtable for QFutureWatcherBase +QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QFutureWatcherBase) +16 (int (*)(...))QFutureWatcherBase::metaObject +24 (int (*)(...))QFutureWatcherBase::qt_metacast +32 (int (*)(...))QFutureWatcherBase::qt_metacall +40 0u +48 0u +56 (int (*)(...))QFutureWatcherBase::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QFutureWatcherBase::connectNotify +104 (int (*)(...))QFutureWatcherBase::disconnectNotify +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QFutureWatcherBase + size=16 align=8 + base size=16 base align=8 +QFutureWatcherBase (0x0x7f51ba1953a8) 0 + vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u) + QObject (0x0x7f51ba19c120) 0 + primary-for QFutureWatcherBase (0x0x7f51ba1953a8) + +Class QHistoryState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QHistoryState::QPrivateSignal (0x0x7f51ba19c780) 0 empty + +Vtable for QHistoryState +QHistoryState::_ZTV13QHistoryState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QHistoryState) +16 (int (*)(...))QHistoryState::metaObject +24 (int (*)(...))QHistoryState::qt_metacast +32 (int (*)(...))QHistoryState::qt_metacall +40 (int (*)(...))QHistoryState::~QHistoryState +48 (int (*)(...))QHistoryState::~QHistoryState +56 (int (*)(...))QHistoryState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QHistoryState::onEntry +120 (int (*)(...))QHistoryState::onExit + +Class QHistoryState + size=16 align=8 + base size=16 base align=8 +QHistoryState (0x0x7f51ba195c98) 0 + vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u) + QAbstractState (0x0x7f51ba195d00) 0 + primary-for QHistoryState (0x0x7f51ba195c98) + QObject (0x0x7f51ba19c720) 0 + primary-for QAbstractState (0x0x7f51ba195d00) + +Class QIdentityProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QIdentityProxyModel::QPrivateSignal (0x0x7f51ba19c840) 0 empty + +Vtable for QIdentityProxyModel +QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QIdentityProxyModel) +16 (int (*)(...))QIdentityProxyModel::metaObject +24 (int (*)(...))QIdentityProxyModel::qt_metacast +32 (int (*)(...))QIdentityProxyModel::qt_metacall +40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QIdentityProxyModel::index +120 (int (*)(...))QIdentityProxyModel::parent +128 (int (*)(...))QIdentityProxyModel::sibling +136 (int (*)(...))QIdentityProxyModel::rowCount +144 (int (*)(...))QIdentityProxyModel::columnCount +152 (int (*)(...))QAbstractProxyModel::hasChildren +160 (int (*)(...))QAbstractProxyModel::data +168 (int (*)(...))QAbstractProxyModel::setData +176 (int (*)(...))QIdentityProxyModel::headerData +184 (int (*)(...))QAbstractProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QAbstractProxyModel::mimeTypes +216 (int (*)(...))QAbstractProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QIdentityProxyModel::dropMimeData +240 (int (*)(...))QAbstractProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QIdentityProxyModel::insertRows +264 (int (*)(...))QIdentityProxyModel::insertColumns +272 (int (*)(...))QIdentityProxyModel::removeRows +280 (int (*)(...))QIdentityProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractProxyModel::fetchMore +312 (int (*)(...))QAbstractProxyModel::canFetchMore +320 (int (*)(...))QAbstractProxyModel::flags +328 (int (*)(...))QAbstractProxyModel::sort +336 (int (*)(...))QAbstractProxyModel::buddy +344 (int (*)(...))QIdentityProxyModel::match +352 (int (*)(...))QAbstractProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QIdentityProxyModel::setSourceModel +392 (int (*)(...))QIdentityProxyModel::mapToSource +400 (int (*)(...))QIdentityProxyModel::mapFromSource +408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource +416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource + +Class QIdentityProxyModel + size=16 align=8 + base size=16 base align=8 +QIdentityProxyModel (0x0x7f51ba195d68) 0 + vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16u) + QAbstractProxyModel (0x0x7f51ba195dd0) 0 + primary-for QIdentityProxyModel (0x0x7f51ba195d68) + QAbstractItemModel (0x0x7f51ba195e38) 0 + primary-for QAbstractProxyModel (0x0x7f51ba195dd0) + QObject (0x0x7f51ba19c7e0) 0 + primary-for QAbstractItemModel (0x0x7f51ba195e38) + +Class QItemSelectionRange + size=16 align=8 + base size=16 base align=8 +QItemSelectionRange (0x0x7f51ba19c8a0) 0 + +Class QItemSelectionModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QItemSelectionModel::QPrivateSignal (0x0x7f51ba19cf60) 0 empty + +Vtable for QItemSelectionModel +QItemSelectionModel::_ZTV19QItemSelectionModel: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI19QItemSelectionModel) +16 (int (*)(...))QItemSelectionModel::metaObject +24 (int (*)(...))QItemSelectionModel::qt_metacast +32 (int (*)(...))QItemSelectionModel::qt_metacall +40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QItemSelectionModel::setCurrentIndex +120 (int (*)(...))QItemSelectionModel::select +128 (int (*)(...))QItemSelectionModel::select +136 (int (*)(...))QItemSelectionModel::clear +144 (int (*)(...))QItemSelectionModel::reset +152 (int (*)(...))QItemSelectionModel::clearCurrentIndex + +Class QItemSelectionModel + size=16 align=8 + base size=16 base align=8 +QItemSelectionModel (0x0x7f51b9e4f680) 0 + vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u) + QObject (0x0x7f51ba19cf00) 0 + primary-for QItemSelectionModel (0x0x7f51b9e4f680) + +Class QItemSelection + size=8 align=8 + base size=8 base align=8 +QItemSelection (0x0x7f51b9e4f888) 0 + QList (0x0x7f51b9e4f8f0) 0 + QListSpecialMethods (0x0x7f51b9e942a0) 0 empty + +Class QJsonValue + size=24 align=8 + base size=20 base align=8 +QJsonValue (0x0x7f51b9e94780) 0 + +Class QJsonValueRef + size=16 align=8 + base size=12 base align=8 +QJsonValueRef (0x0x7f51b9c52ea0) 0 + +Class QJsonValuePtr + size=24 align=8 + base size=24 base align=8 +QJsonValuePtr (0x0x7f51b9ccc420) 0 + +Class QJsonValueRefPtr + size=16 align=8 + base size=16 base align=8 +QJsonValueRefPtr (0x0x7f51b9ccc480) 0 + +Class QJsonArray::iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::iterator (0x0x7f51b9ccc660) 0 + +Class QJsonArray::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonArray::const_iterator (0x0x7f51b9ccc6c0) 0 + +Class QJsonArray + size=16 align=8 + base size=16 base align=8 +QJsonArray (0x0x7f51b9ccc600) 0 + +Class QJsonParseError + size=8 align=4 + base size=8 base align=4 +QJsonParseError (0x0x7f51b9d8d900) 0 + +Class QJsonDocument + size=8 align=8 + base size=8 base align=8 +QJsonDocument (0x0x7f51b9d8d960) 0 + +Class QJsonObject::iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::iterator (0x0x7f51b9e18000) 0 + +Class QJsonObject::const_iterator + size=16 align=8 + base size=12 base align=8 +QJsonObject::const_iterator (0x0x7f51b9e18060) 0 + +Class QJsonObject + size=16 align=8 + base size=16 base align=8 +QJsonObject (0x0x7f51b9d8df60) 0 + +Class QLibrary::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QLibrary::QPrivateSignal (0x0x7f51b9ac1300) 0 empty + +Vtable for QLibrary +QLibrary::_ZTV8QLibrary: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QLibrary) +16 (int (*)(...))QLibrary::metaObject +24 (int (*)(...))QLibrary::qt_metacast +32 (int (*)(...))QLibrary::qt_metacall +40 (int (*)(...))QLibrary::~QLibrary +48 (int (*)(...))QLibrary::~QLibrary +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QLibrary + size=32 align=8 + base size=25 base align=8 +QLibrary (0x0x7f51b9ab6c30) 0 + vptr=((& QLibrary::_ZTV8QLibrary) + 16u) + QObject (0x0x7f51b9ac12a0) 0 + primary-for QLibrary (0x0x7f51b9ab6c30) + +Class QVersionNumber::SegmentStorage + size=8 align=8 + base size=8 base align=8 +QVersionNumber::SegmentStorage (0x0x7f51b9ac19c0) 0 + +Class QVersionNumber + size=8 align=8 + base size=8 base align=8 +QVersionNumber (0x0x7f51b9ac14e0) 0 + +Class QLibraryInfo + size=1 align=1 + base size=0 base align=1 +QLibraryInfo (0x0x7f51b9ac1ea0) 0 empty + +Class QPoint + size=8 align=4 + base size=8 base align=4 +QPoint (0x0x7f51b9ac1f00) 0 + +Class QPointF + size=16 align=8 + base size=16 base align=8 +QPointF (0x0x7f51b9bcf1e0) 0 + +Class QLine + size=16 align=4 + base size=16 base align=4 +QLine (0x0x7f51b9bcf7e0) 0 + +Class QLineF + size=32 align=8 + base size=32 base align=8 +QLineF (0x0x7f51b9861180) 0 + +Class QLinkedListData + size=32 align=8 + base size=25 base align=8 +QLinkedListData (0x0x7f51b9861780) 0 + +Class QLockFile + size=8 align=8 + base size=8 base align=8 +QLockFile (0x0x7f51b9861ae0) 0 + +Class QLoggingCategory::AtomicBools + size=4 align=1 + base size=4 base align=1 +QLoggingCategory::AtomicBools (0x0x7f51b9861c60) 0 + +Class QLoggingCategory + size=24 align=8 + base size=24 base align=8 +QLoggingCategory (0x0x7f51b9861c00) 0 + +Class QMargins + size=16 align=4 + base size=16 base align=4 +QMargins (0x0x7f51b9861de0) 0 + +Class QMarginsF + size=32 align=8 + base size=32 base align=8 +QMarginsF (0x0x7f51b99e30c0) 0 + +Class QMessageAuthenticationCode + size=8 align=8 + base size=8 base align=8 +QMessageAuthenticationCode (0x0x7f51b99e3720) 0 + +Class QMetaMethod + size=16 align=8 + base size=12 base align=8 +QMetaMethod (0x0x7f51b99e3780) 0 + +Class QMetaEnum + size=16 align=8 + base size=12 base align=8 +QMetaEnum (0x0x7f51b99e3d80) 0 + +Class QMetaProperty + size=32 align=8 + base size=32 base align=8 +QMetaProperty (0x0x7f51b95cd0c0) 0 + +Class QMetaClassInfo + size=16 align=8 + base size=12 base align=8 +QMetaClassInfo (0x0x7f51b95cd120) 0 + +Class QMimeData::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QMimeData::QPrivateSignal (0x0x7f51b95cd420) 0 empty + +Vtable for QMimeData +QMimeData::_ZTV9QMimeData: 17u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QMimeData) +16 (int (*)(...))QMimeData::metaObject +24 (int (*)(...))QMimeData::qt_metacast +32 (int (*)(...))QMimeData::qt_metacall +40 (int (*)(...))QMimeData::~QMimeData +48 (int (*)(...))QMimeData::~QMimeData +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QMimeData::hasFormat +120 (int (*)(...))QMimeData::formats +128 (int (*)(...))QMimeData::retrieveData + +Class QMimeData + size=16 align=8 + base size=16 base align=8 +QMimeData (0x0x7f51b952cea0) 0 + vptr=((& QMimeData::_ZTV9QMimeData) + 16u) + QObject (0x0x7f51b95cd3c0) 0 + primary-for QMimeData (0x0x7f51b952cea0) + +Class QMimeType + size=8 align=8 + base size=8 base align=8 +QMimeType (0x0x7f51b95cd480) 0 + +Class QMimeDatabase + size=8 align=8 + base size=8 base align=8 +QMimeDatabase (0x0x7f51b95cd780) 0 + +Class QObjectCleanupHandler::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QObjectCleanupHandler::QPrivateSignal (0x0x7f51b95cd840) 0 empty + +Vtable for QObjectCleanupHandler +QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QObjectCleanupHandler) +16 (int (*)(...))QObjectCleanupHandler::metaObject +24 (int (*)(...))QObjectCleanupHandler::qt_metacast +32 (int (*)(...))QObjectCleanupHandler::qt_metacall +40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QObjectCleanupHandler + size=24 align=8 + base size=24 base align=8 +QObjectCleanupHandler (0x0x7f51b96180d0) 0 + vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u) + QObject (0x0x7f51b95cd7e0) 0 + primary-for QObjectCleanupHandler (0x0x7f51b96180d0) + +Class QOperatingSystemVersion + size=16 align=4 + base size=16 base align=4 +QOperatingSystemVersion (0x0x7f51b95cd8a0) 0 + +Class QParallelAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QParallelAnimationGroup::QPrivateSignal (0x0x7f51b9663060) 0 empty + +Vtable for QParallelAnimationGroup +QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI23QParallelAnimationGroup) +16 (int (*)(...))QParallelAnimationGroup::metaObject +24 (int (*)(...))QParallelAnimationGroup::qt_metacast +32 (int (*)(...))QParallelAnimationGroup::qt_metacall +40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup +56 (int (*)(...))QParallelAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QParallelAnimationGroup::duration +120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime +128 (int (*)(...))QParallelAnimationGroup::updateState +136 (int (*)(...))QParallelAnimationGroup::updateDirection + +Class QParallelAnimationGroup + size=16 align=8 + base size=16 base align=8 +QParallelAnimationGroup (0x0x7f51b9618820) 0 + vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u) + QAnimationGroup (0x0x7f51b9618888) 0 + primary-for QParallelAnimationGroup (0x0x7f51b9618820) + QAbstractAnimation (0x0x7f51b96188f0) 0 + primary-for QAnimationGroup (0x0x7f51b9618888) + QObject (0x0x7f51b9663000) 0 + primary-for QAbstractAnimation (0x0x7f51b96188f0) + +Class QPauseAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPauseAnimation::QPrivateSignal (0x0x7f51b9663120) 0 empty + +Vtable for QPauseAnimation +QPauseAnimation::_ZTV15QPauseAnimation: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QPauseAnimation) +16 (int (*)(...))QPauseAnimation::metaObject +24 (int (*)(...))QPauseAnimation::qt_metacast +32 (int (*)(...))QPauseAnimation::qt_metacall +40 (int (*)(...))QPauseAnimation::~QPauseAnimation +48 (int (*)(...))QPauseAnimation::~QPauseAnimation +56 (int (*)(...))QPauseAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QPauseAnimation::duration +120 (int (*)(...))QPauseAnimation::updateCurrentTime +128 (int (*)(...))QAbstractAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection + +Class QPauseAnimation + size=16 align=8 + base size=16 base align=8 +QPauseAnimation (0x0x7f51b9618958) 0 + vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u) + QAbstractAnimation (0x0x7f51b96189c0) 0 + primary-for QPauseAnimation (0x0x7f51b9618958) + QObject (0x0x7f51b96630c0) 0 + primary-for QAbstractAnimation (0x0x7f51b96189c0) + +Class QStaticPlugin + size=16 align=8 + base size=16 base align=8 +QStaticPlugin (0x0x7f51b9663300) 0 + +Class QPluginLoader::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPluginLoader::QPrivateSignal (0x0x7f51b9663600) 0 empty + +Vtable for QPluginLoader +QPluginLoader::_ZTV13QPluginLoader: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QPluginLoader) +16 (int (*)(...))QPluginLoader::metaObject +24 (int (*)(...))QPluginLoader::qt_metacast +32 (int (*)(...))QPluginLoader::qt_metacall +40 (int (*)(...))QPluginLoader::~QPluginLoader +48 (int (*)(...))QPluginLoader::~QPluginLoader +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QPluginLoader + size=32 align=8 + base size=25 base align=8 +QPluginLoader (0x0x7f51b9618bc8) 0 + vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u) + QObject (0x0x7f51b96635a0) 0 + primary-for QPluginLoader (0x0x7f51b9618bc8) + +Class QProcessEnvironment + size=8 align=8 + base size=8 base align=8 +QProcessEnvironment (0x0x7f51b9663660) 0 + +Class QProcess::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QProcess::QPrivateSignal (0x0x7f51b9663d20) 0 empty + +Vtable for QProcess +QProcess::_ZTV8QProcess: 31u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI8QProcess) +16 (int (*)(...))QProcess::metaObject +24 (int (*)(...))QProcess::qt_metacast +32 (int (*)(...))QProcess::qt_metacall +40 (int (*)(...))QProcess::~QProcess +48 (int (*)(...))QProcess::~QProcess +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QProcess::isSequential +120 (int (*)(...))QProcess::open +128 (int (*)(...))QProcess::close +136 (int (*)(...))QIODevice::pos +144 (int (*)(...))QIODevice::size +152 (int (*)(...))QIODevice::seek +160 (int (*)(...))QProcess::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QProcess::bytesAvailable +184 (int (*)(...))QProcess::bytesToWrite +192 (int (*)(...))QProcess::canReadLine +200 (int (*)(...))QProcess::waitForReadyRead +208 (int (*)(...))QProcess::waitForBytesWritten +216 (int (*)(...))QProcess::readData +224 (int (*)(...))QIODevice::readLineData +232 (int (*)(...))QProcess::writeData +240 (int (*)(...))QProcess::setupChildProcess + +Class QProcess + size=16 align=8 + base size=16 base align=8 +QProcess (0x0x7f51b96cc208) 0 + vptr=((& QProcess::_ZTV8QProcess) + 16u) + QIODevice (0x0x7f51b96cc270) 0 + primary-for QProcess (0x0x7f51b96cc208) + QObject (0x0x7f51b9663cc0) 0 + primary-for QIODevice (0x0x7f51b96cc270) + +Class QVariantAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QVariantAnimation::QPrivateSignal (0x0x7f51b9663de0) 0 empty + +Vtable for QVariantAnimation +QVariantAnimation::_ZTV17QVariantAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QVariantAnimation) +16 (int (*)(...))QVariantAnimation::metaObject +24 (int (*)(...))QVariantAnimation::qt_metacast +32 (int (*)(...))QVariantAnimation::qt_metacall +40 (int (*)(...))QVariantAnimation::~QVariantAnimation +48 (int (*)(...))QVariantAnimation::~QVariantAnimation +56 (int (*)(...))QVariantAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QVariantAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QVariantAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QVariantAnimation + size=16 align=8 + base size=16 base align=8 +QVariantAnimation (0x0x7f51b96cc2d8) 0 + vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u) + QAbstractAnimation (0x0x7f51b96cc340) 0 + primary-for QVariantAnimation (0x0x7f51b96cc2d8) + QObject (0x0x7f51b9663d80) 0 + primary-for QAbstractAnimation (0x0x7f51b96cc340) + +Class QPropertyAnimation::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QPropertyAnimation::QPrivateSignal (0x0x7f51b9663ea0) 0 empty + +Vtable for QPropertyAnimation +QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QPropertyAnimation) +16 (int (*)(...))QPropertyAnimation::metaObject +24 (int (*)(...))QPropertyAnimation::qt_metacast +32 (int (*)(...))QPropertyAnimation::qt_metacall +40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation +56 (int (*)(...))QPropertyAnimation::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QVariantAnimation::duration +120 (int (*)(...))QVariantAnimation::updateCurrentTime +128 (int (*)(...))QPropertyAnimation::updateState +136 (int (*)(...))QAbstractAnimation::updateDirection +144 (int (*)(...))QPropertyAnimation::updateCurrentValue +152 (int (*)(...))QVariantAnimation::interpolated + +Class QPropertyAnimation + size=16 align=8 + base size=16 base align=8 +QPropertyAnimation (0x0x7f51b96cc410) 0 + vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u) + QVariantAnimation (0x0x7f51b96cc478) 0 + primary-for QPropertyAnimation (0x0x7f51b96cc410) + QAbstractAnimation (0x0x7f51b96cc4e0) 0 + primary-for QVariantAnimation (0x0x7f51b96cc478) + QObject (0x0x7f51b9663e40) 0 + primary-for QAbstractAnimation (0x0x7f51b96cc4e0) + +Class QRandomGenerator::Storage + size=2504 align=8 + base size=2504 base align=8 +QRandomGenerator::Storage (0x0x7f51b934c000) 0 + +Class QRandomGenerator + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator (0x0x7f51b9663f60) 0 + +Class QRandomGenerator64 + size=2512 align=8 + base size=2512 base align=8 +QRandomGenerator64 (0x0x7f51b93b27b8) 0 + QRandomGenerator (0x0x7f51b9396f60) 0 + +Class QReadWriteLock + size=8 align=8 + base size=8 base align=8 +QReadWriteLock (0x0x7f51b93f3060) 0 + +Class QReadLocker + size=8 align=8 + base size=8 base align=8 +QReadLocker (0x0x7f51b93f3300) 0 + +Class QWriteLocker + size=8 align=8 + base size=8 base align=8 +QWriteLocker (0x0x7f51b93f33c0) 0 + +Class QSize + size=8 align=4 + base size=8 base align=4 +QSize (0x0x7f51b93f3480) 0 + +Class QSizeF + size=16 align=8 + base size=16 base align=8 +QSizeF (0x0x7f51b93f3720) 0 + +Class QRect + size=16 align=4 + base size=16 base align=4 +QRect (0x0x7f51b93f39c0) 0 + +Class QRectF + size=32 align=8 + base size=32 base align=8 +QRectF (0x0x7f51b93f3c60) 0 + +Class QResource + size=8 align=8 + base size=8 base align=8 +QResource (0x0x7f51b93f3f00) 0 + +Class QSaveFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSaveFile::QPrivateSignal (0x0x7f51b92380c0) 0 empty + +Vtable for QSaveFile +QSaveFile::_ZTV9QSaveFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSaveFile) +16 (int (*)(...))QSaveFile::metaObject +24 (int (*)(...))QSaveFile::qt_metacast +32 (int (*)(...))QSaveFile::qt_metacall +40 (int (*)(...))QSaveFile::~QSaveFile +48 (int (*)(...))QSaveFile::~QSaveFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QSaveFile::open +128 (int (*)(...))QSaveFile::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFileDevice::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QSaveFile::writeData +240 (int (*)(...))QSaveFile::fileName +248 (int (*)(...))QFileDevice::resize +256 (int (*)(...))QFileDevice::permissions +264 (int (*)(...))QFileDevice::setPermissions + +Class QSaveFile + size=16 align=8 + base size=16 base align=8 +QSaveFile (0x0x7f51b9523340) 0 + vptr=((& QSaveFile::_ZTV9QSaveFile) + 16u) + QFileDevice (0x0x7f51b95233a8) 0 + primary-for QSaveFile (0x0x7f51b9523340) + QIODevice (0x0x7f51b9523410) 0 + primary-for QFileDevice (0x0x7f51b95233a8) + QObject (0x0x7f51b9238060) 0 + primary-for QIODevice (0x0x7f51b9523410) + +Class QSemaphore + size=8 align=8 + base size=8 base align=8 +QSemaphore (0x0x7f51b92381e0) 0 + +Class QSemaphoreReleaser + size=16 align=8 + base size=12 base align=8 +QSemaphoreReleaser (0x0x7f51b9238360) 0 + +Class QSequentialAnimationGroup::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSequentialAnimationGroup::QPrivateSignal (0x0x7f51b8f7b960) 0 empty + +Vtable for QSequentialAnimationGroup +QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup) +16 (int (*)(...))QSequentialAnimationGroup::metaObject +24 (int (*)(...))QSequentialAnimationGroup::qt_metacast +32 (int (*)(...))QSequentialAnimationGroup::qt_metacall +40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup +56 (int (*)(...))QSequentialAnimationGroup::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSequentialAnimationGroup::duration +120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime +128 (int (*)(...))QSequentialAnimationGroup::updateState +136 (int (*)(...))QSequentialAnimationGroup::updateDirection + +Class QSequentialAnimationGroup + size=16 align=8 + base size=16 base align=8 +QSequentialAnimationGroup (0x0x7f51b8f78c98) 0 + vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u) + QAnimationGroup (0x0x7f51b8f78d00) 0 + primary-for QSequentialAnimationGroup (0x0x7f51b8f78c98) + QAbstractAnimation (0x0x7f51b8f78d68) 0 + primary-for QAnimationGroup (0x0x7f51b8f78d00) + QObject (0x0x7f51b8f7b900) 0 + primary-for QAbstractAnimation (0x0x7f51b8f78d68) + +Class QSettings::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSettings::QPrivateSignal (0x0x7f51b8f7ba20) 0 empty + +Vtable for QSettings +QSettings::_ZTV9QSettings: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QSettings) +16 (int (*)(...))QSettings::metaObject +24 (int (*)(...))QSettings::qt_metacast +32 (int (*)(...))QSettings::qt_metacall +40 (int (*)(...))QSettings::~QSettings +48 (int (*)(...))QSettings::~QSettings +56 (int (*)(...))QSettings::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSettings + size=16 align=8 + base size=16 base align=8 +QSettings (0x0x7f51b8f78dd0) 0 + vptr=((& QSettings::_ZTV9QSettings) + 16u) + QObject (0x0x7f51b8f7b9c0) 0 + primary-for QSettings (0x0x7f51b8f78dd0) + +Class QSharedMemory::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSharedMemory::QPrivateSignal (0x0x7f51b8f7bae0) 0 empty + +Vtable for QSharedMemory +QSharedMemory::_ZTV13QSharedMemory: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSharedMemory) +16 (int (*)(...))QSharedMemory::metaObject +24 (int (*)(...))QSharedMemory::qt_metacast +32 (int (*)(...))QSharedMemory::qt_metacall +40 (int (*)(...))QSharedMemory::~QSharedMemory +48 (int (*)(...))QSharedMemory::~QSharedMemory +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSharedMemory + size=16 align=8 + base size=16 base align=8 +QSharedMemory (0x0x7f51b8f78e38) 0 + vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u) + QObject (0x0x7f51b8f7ba80) 0 + primary-for QSharedMemory (0x0x7f51b8f78e38) + +Class QSignalMapper::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalMapper::QPrivateSignal (0x0x7f51b8f7bba0) 0 empty + +Vtable for QSignalMapper +QSignalMapper::_ZTV13QSignalMapper: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QSignalMapper) +16 (int (*)(...))QSignalMapper::metaObject +24 (int (*)(...))QSignalMapper::qt_metacast +32 (int (*)(...))QSignalMapper::qt_metacall +40 (int (*)(...))QSignalMapper::~QSignalMapper +48 (int (*)(...))QSignalMapper::~QSignalMapper +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSignalMapper + size=16 align=8 + base size=16 base align=8 +QSignalMapper (0x0x7f51b8f78ea0) 0 + vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u) + QObject (0x0x7f51b8f7bb40) 0 + primary-for QSignalMapper (0x0x7f51b8f78ea0) + +Class QSignalTransition::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSignalTransition::QPrivateSignal (0x0x7f51b8f7bc60) 0 empty + +Vtable for QSignalTransition +QSignalTransition::_ZTV17QSignalTransition: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI17QSignalTransition) +16 (int (*)(...))QSignalTransition::metaObject +24 (int (*)(...))QSignalTransition::qt_metacast +32 (int (*)(...))QSignalTransition::qt_metacall +40 (int (*)(...))QSignalTransition::~QSignalTransition +48 (int (*)(...))QSignalTransition::~QSignalTransition +56 (int (*)(...))QSignalTransition::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSignalTransition::eventTest +120 (int (*)(...))QSignalTransition::onTransition + +Class QSignalTransition + size=16 align=8 + base size=16 base align=8 +QSignalTransition (0x0x7f51b8f78f08) 0 + vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u) + QAbstractTransition (0x0x7f51b8f78f70) 0 + primary-for QSignalTransition (0x0x7f51b8f78f08) + QObject (0x0x7f51b8f7bc00) 0 + primary-for QAbstractTransition (0x0x7f51b8f78f70) + +Class QSocketNotifier::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSocketNotifier::QPrivateSignal (0x0x7f51b8f7bd20) 0 empty + +Vtable for QSocketNotifier +QSocketNotifier::_ZTV15QSocketNotifier: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QSocketNotifier) +16 (int (*)(...))QSocketNotifier::metaObject +24 (int (*)(...))QSocketNotifier::qt_metacast +32 (int (*)(...))QSocketNotifier::qt_metacall +40 (int (*)(...))QSocketNotifier::~QSocketNotifier +48 (int (*)(...))QSocketNotifier::~QSocketNotifier +56 (int (*)(...))QSocketNotifier::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QSocketNotifier + size=16 align=8 + base size=16 base align=8 +QSocketNotifier (0x0x7f51b8ff8000) 0 + vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u) + QObject (0x0x7f51b8f7bcc0) 0 + primary-for QSocketNotifier (0x0x7f51b8ff8000) + +Class QSortFilterProxyModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QSortFilterProxyModel::QPrivateSignal (0x0x7f51b8f7bde0) 0 empty + +Vtable for QSortFilterProxyModel +QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI21QSortFilterProxyModel) +16 (int (*)(...))QSortFilterProxyModel::metaObject +24 (int (*)(...))QSortFilterProxyModel::qt_metacast +32 (int (*)(...))QSortFilterProxyModel::qt_metacall +40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QSortFilterProxyModel::index +120 (int (*)(...))QSortFilterProxyModel::parent +128 (int (*)(...))QSortFilterProxyModel::sibling +136 (int (*)(...))QSortFilterProxyModel::rowCount +144 (int (*)(...))QSortFilterProxyModel::columnCount +152 (int (*)(...))QSortFilterProxyModel::hasChildren +160 (int (*)(...))QSortFilterProxyModel::data +168 (int (*)(...))QSortFilterProxyModel::setData +176 (int (*)(...))QSortFilterProxyModel::headerData +184 (int (*)(...))QSortFilterProxyModel::setHeaderData +192 (int (*)(...))QAbstractProxyModel::itemData +200 (int (*)(...))QAbstractProxyModel::setItemData +208 (int (*)(...))QSortFilterProxyModel::mimeTypes +216 (int (*)(...))QSortFilterProxyModel::mimeData +224 (int (*)(...))QAbstractProxyModel::canDropMimeData +232 (int (*)(...))QSortFilterProxyModel::dropMimeData +240 (int (*)(...))QSortFilterProxyModel::supportedDropActions +248 (int (*)(...))QAbstractProxyModel::supportedDragActions +256 (int (*)(...))QSortFilterProxyModel::insertRows +264 (int (*)(...))QSortFilterProxyModel::insertColumns +272 (int (*)(...))QSortFilterProxyModel::removeRows +280 (int (*)(...))QSortFilterProxyModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QSortFilterProxyModel::fetchMore +312 (int (*)(...))QSortFilterProxyModel::canFetchMore +320 (int (*)(...))QSortFilterProxyModel::flags +328 (int (*)(...))QSortFilterProxyModel::sort +336 (int (*)(...))QSortFilterProxyModel::buddy +344 (int (*)(...))QSortFilterProxyModel::match +352 (int (*)(...))QSortFilterProxyModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractProxyModel::submit +376 (int (*)(...))QAbstractProxyModel::revert +384 (int (*)(...))QSortFilterProxyModel::setSourceModel +392 (int (*)(...))QSortFilterProxyModel::mapToSource +400 (int (*)(...))QSortFilterProxyModel::mapFromSource +408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource +416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource +424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow +432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn +440 (int (*)(...))QSortFilterProxyModel::lessThan + +Class QSortFilterProxyModel + size=16 align=8 + base size=16 base align=8 +QSortFilterProxyModel (0x0x7f51b8ff8068) 0 + vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16u) + QAbstractProxyModel (0x0x7f51b8ff80d0) 0 + primary-for QSortFilterProxyModel (0x0x7f51b8ff8068) + QAbstractItemModel (0x0x7f51b8ff8138) 0 + primary-for QAbstractProxyModel (0x0x7f51b8ff80d0) + QObject (0x0x7f51b8f7bd80) 0 + primary-for QAbstractItemModel (0x0x7f51b8ff8138) + +Class QStandardPaths + size=1 align=1 + base size=0 base align=1 +QStandardPaths (0x0x7f51b8f7bea0) 0 empty + +Class QState::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QState::QPrivateSignal (0x0x7f51b9047120) 0 empty + +Vtable for QState +QState::_ZTV6QState: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QState) +16 (int (*)(...))QState::metaObject +24 (int (*)(...))QState::qt_metacast +32 (int (*)(...))QState::qt_metacall +40 (int (*)(...))QState::~QState +48 (int (*)(...))QState::~QState +56 (int (*)(...))QState::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QState::onEntry +120 (int (*)(...))QState::onExit + +Class QState + size=16 align=8 + base size=16 base align=8 +QState (0x0x7f51b8ff82d8) 0 + vptr=((& QState::_ZTV6QState) + 16u) + QAbstractState (0x0x7f51b8ff8340) 0 + primary-for QState (0x0x7f51b8ff82d8) + QObject (0x0x7f51b90470c0) 0 + primary-for QAbstractState (0x0x7f51b8ff8340) + +Class QStateMachine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStateMachine::QPrivateSignal (0x0x7f51b9047240) 0 empty + +Vtable for QStateMachine::SignalEvent +QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE) +16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent +24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent + +Class QStateMachine::SignalEvent + size=48 align=8 + base size=48 base align=8 +QStateMachine::SignalEvent (0x0x7f51b8ff84e0) 0 + vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u) + QEvent (0x0x7f51b90472a0) 0 + primary-for QStateMachine::SignalEvent (0x0x7f51b8ff84e0) + +Vtable for QStateMachine::WrappedEvent +QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE) +16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent +24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent + +Class QStateMachine::WrappedEvent + size=40 align=8 + base size=40 base align=8 +QStateMachine::WrappedEvent (0x0x7f51b8ff8548) 0 + vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u) + QEvent (0x0x7f51b9047300) 0 + primary-for QStateMachine::WrappedEvent (0x0x7f51b8ff8548) + +Vtable for QStateMachine +QStateMachine::_ZTV13QStateMachine: 20u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI13QStateMachine) +16 (int (*)(...))QStateMachine::metaObject +24 (int (*)(...))QStateMachine::qt_metacast +32 (int (*)(...))QStateMachine::qt_metacall +40 (int (*)(...))QStateMachine::~QStateMachine +48 (int (*)(...))QStateMachine::~QStateMachine +56 (int (*)(...))QStateMachine::event +64 (int (*)(...))QStateMachine::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QStateMachine::onEntry +120 (int (*)(...))QStateMachine::onExit +128 (int (*)(...))QStateMachine::beginSelectTransitions +136 (int (*)(...))QStateMachine::endSelectTransitions +144 (int (*)(...))QStateMachine::beginMicrostep +152 (int (*)(...))QStateMachine::endMicrostep + +Class QStateMachine + size=16 align=8 + base size=16 base align=8 +QStateMachine (0x0x7f51b8ff83a8) 0 + vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u) + QState (0x0x7f51b8ff8410) 0 + primary-for QStateMachine (0x0x7f51b8ff83a8) + QAbstractState (0x0x7f51b8ff8478) 0 + primary-for QState (0x0x7f51b8ff8410) + QObject (0x0x7f51b90471e0) 0 + primary-for QAbstractState (0x0x7f51b8ff8478) + +Class QStorageInfo + size=8 align=8 + base size=8 base align=8 +QStorageInfo (0x0x7f51b9047360) 0 + +Class QAbstractConcatenable + size=1 align=1 + base size=0 base align=1 +QAbstractConcatenable (0x0x7f51b90f42a0) 0 empty + +Class QStringListModel::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QStringListModel::QPrivateSignal (0x0x7f51b8d82660) 0 empty + +Vtable for QStringListModel +QStringListModel::_ZTV16QStringListModel: 48u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QStringListModel) +16 (int (*)(...))QStringListModel::metaObject +24 (int (*)(...))QStringListModel::qt_metacast +32 (int (*)(...))QStringListModel::qt_metacall +40 (int (*)(...))QStringListModel::~QStringListModel +48 (int (*)(...))QStringListModel::~QStringListModel +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QAbstractListModel::index +120 (int (*)(...))QAbstractListModel::parent +128 (int (*)(...))QStringListModel::sibling +136 (int (*)(...))QStringListModel::rowCount +144 (int (*)(...))QAbstractListModel::columnCount +152 (int (*)(...))QAbstractListModel::hasChildren +160 (int (*)(...))QStringListModel::data +168 (int (*)(...))QStringListModel::setData +176 (int (*)(...))QAbstractItemModel::headerData +184 (int (*)(...))QAbstractItemModel::setHeaderData +192 (int (*)(...))QAbstractItemModel::itemData +200 (int (*)(...))QAbstractItemModel::setItemData +208 (int (*)(...))QAbstractItemModel::mimeTypes +216 (int (*)(...))QAbstractItemModel::mimeData +224 (int (*)(...))QAbstractItemModel::canDropMimeData +232 (int (*)(...))QAbstractListModel::dropMimeData +240 (int (*)(...))QStringListModel::supportedDropActions +248 (int (*)(...))QAbstractItemModel::supportedDragActions +256 (int (*)(...))QStringListModel::insertRows +264 (int (*)(...))QAbstractItemModel::insertColumns +272 (int (*)(...))QStringListModel::removeRows +280 (int (*)(...))QAbstractItemModel::removeColumns +288 (int (*)(...))QAbstractItemModel::moveRows +296 (int (*)(...))QAbstractItemModel::moveColumns +304 (int (*)(...))QAbstractItemModel::fetchMore +312 (int (*)(...))QAbstractItemModel::canFetchMore +320 (int (*)(...))QStringListModel::flags +328 (int (*)(...))QStringListModel::sort +336 (int (*)(...))QAbstractItemModel::buddy +344 (int (*)(...))QAbstractItemModel::match +352 (int (*)(...))QAbstractItemModel::span +360 (int (*)(...))QAbstractItemModel::roleNames +368 (int (*)(...))QAbstractItemModel::submit +376 (int (*)(...))QAbstractItemModel::revert + +Class QStringListModel + size=24 align=8 + base size=24 base align=8 +QStringListModel (0x0x7f51b8d87548) 0 + vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u) + QAbstractListModel (0x0x7f51b8d875b0) 0 + primary-for QStringListModel (0x0x7f51b8d87548) + QAbstractItemModel (0x0x7f51b8d87618) 0 + primary-for QAbstractListModel (0x0x7f51b8d875b0) + QObject (0x0x7f51b8d82600) 0 + primary-for QAbstractItemModel (0x0x7f51b8d87618) + +Class QSystemSemaphore + size=8 align=8 + base size=8 base align=8 +QSystemSemaphore (0x0x7f51b8d826c0) 0 + +Class QTemporaryDir + size=8 align=8 + base size=8 base align=8 +QTemporaryDir (0x0x7f51b8d82780) 0 + +Class QTemporaryFile::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTemporaryFile::QPrivateSignal (0x0x7f51b8d828a0) 0 empty + +Vtable for QTemporaryFile +QTemporaryFile::_ZTV14QTemporaryFile: 34u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QTemporaryFile) +16 (int (*)(...))QTemporaryFile::metaObject +24 (int (*)(...))QTemporaryFile::qt_metacast +32 (int (*)(...))QTemporaryFile::qt_metacall +40 (int (*)(...))QTemporaryFile::~QTemporaryFile +48 (int (*)(...))QTemporaryFile::~QTemporaryFile +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QFileDevice::isSequential +120 (int (*)(...))QTemporaryFile::open +128 (int (*)(...))QFileDevice::close +136 (int (*)(...))QFileDevice::pos +144 (int (*)(...))QFile::size +152 (int (*)(...))QFileDevice::seek +160 (int (*)(...))QFileDevice::atEnd +168 (int (*)(...))QIODevice::reset +176 (int (*)(...))QIODevice::bytesAvailable +184 (int (*)(...))QIODevice::bytesToWrite +192 (int (*)(...))QIODevice::canReadLine +200 (int (*)(...))QIODevice::waitForReadyRead +208 (int (*)(...))QIODevice::waitForBytesWritten +216 (int (*)(...))QFileDevice::readData +224 (int (*)(...))QFileDevice::readLineData +232 (int (*)(...))QFileDevice::writeData +240 (int (*)(...))QTemporaryFile::fileName +248 (int (*)(...))QFile::resize +256 (int (*)(...))QFile::permissions +264 (int (*)(...))QFile::setPermissions + +Class QTemporaryFile + size=16 align=8 + base size=16 base align=8 +QTemporaryFile (0x0x7f51b8d87680) 0 + vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u) + QFile (0x0x7f51b8d876e8) 0 + primary-for QTemporaryFile (0x0x7f51b8d87680) + QFileDevice (0x0x7f51b8d87750) 0 + primary-for QFile (0x0x7f51b8d876e8) + QIODevice (0x0x7f51b8d877b8) 0 + primary-for QFileDevice (0x0x7f51b8d87750) + QObject (0x0x7f51b8d82840) 0 + primary-for QIODevice (0x0x7f51b8d877b8) + +Class QTextBoundaryFinder + size=48 align=8 + base size=48 base align=8 +QTextBoundaryFinder (0x0x7f51b8d82900) 0 + +Class QTextCodec::ConverterState + size=32 align=8 + base size=32 base align=8 +QTextCodec::ConverterState (0x0x7f51b8d82b40) 0 + +Vtable for QTextCodec +QTextCodec::_ZTV10QTextCodec: 9u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QTextCodec) +16 (int (*)(...))__cxa_pure_virtual +24 (int (*)(...))QTextCodec::aliases +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 0u +64 0u + +Class QTextCodec + size=8 align=8 + base size=8 base align=8 +QTextCodec (0x0x7f51b8d82ae0) 0 nearly-empty + vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u) + +Class QTextEncoder + size=40 align=8 + base size=40 base align=8 +QTextEncoder (0x0x7f51b8d82d20) 0 + +Class QTextDecoder + size=40 align=8 + base size=40 base align=8 +QTextDecoder (0x0x7f51b8d82d80) 0 + +Class std::__mutex_base + size=40 align=8 + base size=40 base align=8 +std::__mutex_base (0x0x7f51b8d82de0) 0 + +Class std::__recursive_mutex_base + size=40 align=8 + base size=40 base align=8 +std::__recursive_mutex_base (0x0x7f51b8d82e40) 0 + +Class std::mutex + size=40 align=8 + base size=40 base align=8 +std::mutex (0x0x7f51b8d879c0) 0 + std::__mutex_base (0x0x7f51b8d82ea0) 0 + +Class std::recursive_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_mutex (0x0x7f51b8d87a28) 0 + std::__recursive_mutex_base (0x0x7f51b8d82f00) 0 + +Class std::timed_mutex + size=40 align=8 + base size=40 base align=8 +std::timed_mutex (0x0x7f51b8e89540) 0 + std::__mutex_base (0x0x7f51b8e90060) 0 + std::__timed_mutex_impl (0x0x7f51b8e900c0) 0 empty + +Class std::recursive_timed_mutex + size=40 align=8 + base size=40 base align=8 +std::recursive_timed_mutex (0x0x7f51b8e89ee0) 0 + std::__recursive_mutex_base (0x0x7f51b8e90180) 0 + std::__timed_mutex_impl (0x0x7f51b8e901e0) 0 empty + +Class std::defer_lock_t + size=1 align=1 + base size=0 base align=1 +std::defer_lock_t (0x0x7f51b8e90240) 0 empty + +Class std::try_to_lock_t + size=1 align=1 + base size=0 base align=1 +std::try_to_lock_t (0x0x7f51b8e902a0) 0 empty + +Class std::adopt_lock_t + size=1 align=1 + base size=0 base align=1 +std::adopt_lock_t (0x0x7f51b8e90300) 0 empty + +Class std::once_flag + size=4 align=4 + base size=4 base align=4 +std::once_flag (0x0x7f51b8e90540) 0 + +Vtable for __gnu_cxx::__concurrence_lock_error +__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error +32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what + +Class __gnu_cxx::__concurrence_lock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_lock_error (0x0x7f51b8d87b60) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16u) + std::exception (0x0x7f51b8e90600) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_lock_error (0x0x7f51b8d87b60) + +Vtable for __gnu_cxx::__concurrence_unlock_error +__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error +32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what + +Class __gnu_cxx::__concurrence_unlock_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_unlock_error (0x0x7f51b8d87bc8) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16u) + std::exception (0x0x7f51b8e906c0) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7f51b8d87bc8) + +Vtable for __gnu_cxx::__concurrence_broadcast_error +__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error +32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what + +Class __gnu_cxx::__concurrence_broadcast_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_broadcast_error (0x0x7f51b8d87c30) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16u) + std::exception (0x0x7f51b8e90780) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7f51b8d87c30) + +Vtable for __gnu_cxx::__concurrence_wait_error +__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE) +16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error +32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what + +Class __gnu_cxx::__concurrence_wait_error + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__concurrence_wait_error (0x0x7f51b8d87d00) 0 nearly-empty + vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16u) + std::exception (0x0x7f51b8e90840) 0 nearly-empty + primary-for __gnu_cxx::__concurrence_wait_error (0x0x7f51b8d87d00) + +Class __gnu_cxx::__mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__mutex (0x0x7f51b8e90900) 0 + +Class __gnu_cxx::__recursive_mutex + size=40 align=8 + base size=40 base align=8 +__gnu_cxx::__recursive_mutex (0x0x7f51b8e90960) 0 + +Class __gnu_cxx::__scoped_lock + size=8 align=8 + base size=8 base align=8 +__gnu_cxx::__scoped_lock (0x0x7f51b8e909c0) 0 + +Class __gnu_cxx::__cond + size=48 align=8 + base size=48 base align=8 +__gnu_cxx::__cond (0x0x7f51b8e90a20) 0 + +Vtable for std::bad_weak_ptr +std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12bad_weak_ptr) +16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr +32 (int (*)(...))std::bad_weak_ptr::what + +Class std::bad_weak_ptr + size=8 align=8 + base size=8 base align=8 +std::bad_weak_ptr (0x0x7f51b8d87e38) 0 nearly-empty + vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16u) + std::exception (0x0x7f51b8e90d80) 0 nearly-empty + primary-for std::bad_weak_ptr (0x0x7f51b8d87e38) + +Class std::_Sp_make_shared_tag + size=1 align=1 + base size=0 base align=1 +std::_Sp_make_shared_tag (0x0x7f51b8be5600) 0 empty + +Class std::_Sp_locker + size=2 align=1 + base size=2 base align=1 +std::_Sp_locker (0x0x7f51b8be5de0) 0 + +Class std::thread::id + size=8 align=8 + base size=8 base align=8 +std::thread::id (0x0x7f51b8973000) 0 + +Vtable for std::thread::_Impl_base +std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt6thread10_Impl_baseE) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual + +Class std::thread::_Impl_base + size=24 align=8 + base size=24 base align=8 +std::thread::_Impl_base (0x0x7f51b8973060) 0 + vptr=((& std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE) + 16u) + +Class std::thread + size=8 align=8 + base size=8 base align=8 +std::thread (0x0x7f51b8be5f60) 0 + +Class std::condition_variable + size=48 align=8 + base size=48 base align=8 +std::condition_variable (0x0x7f51b8aaac60) 0 + +Class std::__at_thread_exit_elt + size=16 align=8 + base size=16 base align=8 +std::__at_thread_exit_elt (0x0x7f51b8aaad20) 0 + +Class std::_V2::condition_variable_any + size=64 align=8 + base size=64 base align=8 +std::_V2::condition_variable_any (0x0x7f51b8aaad80) 0 + +Class std::__atomic_futex_unsigned_base + size=1 align=1 + base size=0 base align=1 +std::__atomic_futex_unsigned_base (0x0x7f51b8776420) 0 empty + +Vtable for std::future_error +std::future_error::_ZTVSt12future_error: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTISt12future_error) +16 (int (*)(...))std::future_error::~future_error +24 (int (*)(...))std::future_error::~future_error +32 (int (*)(...))std::future_error::what + +Class std::future_error + size=32 align=8 + base size=32 base align=8 +std::future_error (0x0x7f51b877c340) 0 + vptr=((& std::future_error::_ZTVSt12future_error) + 16u) + std::logic_error (0x0x7f51b877c3a8) 0 + primary-for std::future_error (0x0x7f51b877c340) + std::exception (0x0x7f51b8776540) 0 nearly-empty + primary-for std::logic_error (0x0x7f51b877c3a8) + +Class std::__future_base::_Result_base::_Deleter + size=1 align=1 + base size=0 base align=1 +std::__future_base::_Result_base::_Deleter (0x0x7f51b8776660) 0 empty + +Vtable for std::__future_base::_Result_base +std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE) +16 (int (*)(...))__cxa_pure_virtual +24 0u +32 0u + +Class std::__future_base::_Result_base + size=16 align=8 + base size=16 base align=8 +std::__future_base::_Result_base (0x0x7f51b8776600) 0 + vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16u) + +Class std::__future_base::_State_baseV2::__exception_ptr_tag + size=1 align=1 + base size=0 base align=1 +std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7f51b88d3ba0) 0 empty + +Class std::__future_base::_State_baseV2::_Make_ready + size=32 align=8 + base size=32 base align=8 +std::__future_base::_State_baseV2::_Make_ready (0x0x7f51b88d4958) 0 + std::__at_thread_exit_elt (0x0x7f51b88d3c60) 0 + +Vtable for std::__future_base::_State_baseV2 +std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E) +16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2 +32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_State_baseV2 + size=32 align=8 + base size=28 base align=8 +std::__future_base::_State_baseV2 (0x0x7f51b87767e0) 0 + vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16u) + +Class std::__future_base + size=1 align=1 + base size=0 base align=1 +std::__future_base (0x0x7f51b87765a0) 0 empty + +Vtable for std::__future_base::_Async_state_commonV2 +std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E) +16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2 +32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async +40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future + +Class std::__future_base::_Async_state_commonV2 + size=48 align=8 + base size=44 base align=8 +std::__future_base::_Async_state_commonV2 (0x0x7f51b8253548) 0 + vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16u) + std::__future_base::_State_baseV2 (0x0x7f51b8248b40) 0 + primary-for std::__future_base::_Async_state_commonV2 (0x0x7f51b8253548) + +Class QThread::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThread::QPrivateSignal (0x0x7f51b82ad2a0) 0 empty + +Vtable for QThread +QThread::_ZTV7QThread: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI7QThread) +16 (int (*)(...))QThread::metaObject +24 (int (*)(...))QThread::qt_metacast +32 (int (*)(...))QThread::qt_metacall +40 (int (*)(...))QThread::~QThread +48 (int (*)(...))QThread::~QThread +56 (int (*)(...))QThread::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QThread::run + +Class QThread + size=16 align=8 + base size=16 base align=8 +QThread (0x0x7f51b82da000) 0 + vptr=((& QThread::_ZTV7QThread) + 16u) + QObject (0x0x7f51b82ad240) 0 + primary-for QThread (0x0x7f51b82da000) + +Class QThreadPool::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QThreadPool::QPrivateSignal (0x0x7f51b82ad3c0) 0 empty + +Vtable for QThreadPool +QThreadPool::_ZTV11QThreadPool: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QThreadPool) +16 (int (*)(...))QThreadPool::metaObject +24 (int (*)(...))QThreadPool::qt_metacast +32 (int (*)(...))QThreadPool::qt_metacall +40 (int (*)(...))QThreadPool::~QThreadPool +48 (int (*)(...))QThreadPool::~QThreadPool +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QThreadPool + size=16 align=8 + base size=16 base align=8 +QThreadPool (0x0x7f51b82da068) 0 + vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u) + QObject (0x0x7f51b82ad360) 0 + primary-for QThreadPool (0x0x7f51b82da068) + +Class QThreadStorageData + size=4 align=4 + base size=4 base align=4 +QThreadStorageData (0x0x7f51b82ad420) 0 + +Class QTimeLine::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimeLine::QPrivateSignal (0x0x7f51b82ad540) 0 empty + +Vtable for QTimeLine +QTimeLine::_ZTV9QTimeLine: 15u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI9QTimeLine) +16 (int (*)(...))QTimeLine::metaObject +24 (int (*)(...))QTimeLine::qt_metacast +32 (int (*)(...))QTimeLine::qt_metacall +40 (int (*)(...))QTimeLine::~QTimeLine +48 (int (*)(...))QTimeLine::~QTimeLine +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimeLine::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTimeLine::valueForTime + +Class QTimeLine + size=16 align=8 + base size=16 base align=8 +QTimeLine (0x0x7f51b82da0d0) 0 + vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u) + QObject (0x0x7f51b82ad4e0) 0 + primary-for QTimeLine (0x0x7f51b82da0d0) + +Class QTimer::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTimer::QPrivateSignal (0x0x7f51b82ad600) 0 empty + +Vtable for QTimer +QTimer::_ZTV6QTimer: 14u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI6QTimer) +16 (int (*)(...))QTimer::metaObject +24 (int (*)(...))QTimer::qt_metacast +32 (int (*)(...))QTimer::qt_metacall +40 (int (*)(...))QTimer::~QTimer +48 (int (*)(...))QTimer::~QTimer +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QTimer::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify + +Class QTimer + size=32 align=8 + base size=29 base align=8 +QTimer (0x0x7f51b82da138) 0 + vptr=((& QTimer::_ZTV6QTimer) + 16u) + QObject (0x0x7f51b82ad5a0) 0 + primary-for QTimer (0x0x7f51b82da138) + +Class QTimeZone::OffsetData + size=32 align=8 + base size=28 base align=8 +QTimeZone::OffsetData (0x0x7f51b82add20) 0 + +Class QTimeZone + size=8 align=8 + base size=8 base align=8 +QTimeZone (0x0x7f51b82adcc0) 0 + +Class QTranslator::QPrivateSignal + size=1 align=1 + base size=0 base align=1 +QTranslator::QPrivateSignal (0x0x7f51b7f99300) 0 empty + +Vtable for QTranslator +QTranslator::_ZTV11QTranslator: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QTranslator) +16 (int (*)(...))QTranslator::metaObject +24 (int (*)(...))QTranslator::qt_metacast +32 (int (*)(...))QTranslator::qt_metacall +40 (int (*)(...))QTranslator::~QTranslator +48 (int (*)(...))QTranslator::~QTranslator +56 (int (*)(...))QObject::event +64 (int (*)(...))QObject::eventFilter +72 (int (*)(...))QObject::timerEvent +80 (int (*)(...))QObject::childEvent +88 (int (*)(...))QObject::customEvent +96 (int (*)(...))QObject::connectNotify +104 (int (*)(...))QObject::disconnectNotify +112 (int (*)(...))QTranslator::translate +120 (int (*)(...))QTranslator::isEmpty + +Class QTranslator + size=16 align=8 + base size=16 base align=8 +QTranslator (0x0x7f51b82dad00) 0 + vptr=((& QTranslator::_ZTV11QTranslator) + 16u) + QObject (0x0x7f51b7f992a0) 0 + primary-for QTranslator (0x0x7f51b82dad00) + +Class QUrlQuery + size=8 align=8 + base size=8 base align=8 +QUrlQuery (0x0x7f51b7f99360) 0 + +Class QWaitCondition + size=8 align=8 + base size=8 base align=8 +QWaitCondition (0x0x7f51b7f999c0) 0 + +Class QXmlStreamStringRef + size=16 align=8 + base size=16 base align=8 +QXmlStreamStringRef (0x0x7f51b7f99a20) 0 + +Class QXmlStreamAttribute + size=80 align=8 + base size=73 base align=8 +QXmlStreamAttribute (0x0x7f51b7f99cc0) 0 + +Class QXmlStreamAttributes + size=8 align=8 + base size=8 base align=8 +QXmlStreamAttributes (0x0x7f51b7fd79c0) 0 + QVector (0x0x7f51b804b0c0) 0 + +Class QXmlStreamNamespaceDeclaration + size=40 align=8 + base size=40 base align=8 +QXmlStreamNamespaceDeclaration (0x0x7f51b804b120) 0 + +Class QXmlStreamNotationDeclaration + size=56 align=8 + base size=56 base align=8 +QXmlStreamNotationDeclaration (0x0x7f51b804b3c0) 0 + +Class QXmlStreamEntityDeclaration + size=88 align=8 + base size=88 base align=8 +QXmlStreamEntityDeclaration (0x0x7f51b804b660) 0 + +Vtable for QXmlStreamEntityResolver +QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver) +16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver +32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity +40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity + +Class QXmlStreamEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlStreamEntityResolver (0x0x7f51b804b900) 0 nearly-empty + vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u) + +Class QXmlStreamReader + size=8 align=8 + base size=8 base align=8 +QXmlStreamReader (0x0x7f51b804b960) 0 + +Class QXmlStreamWriter + size=8 align=8 + base size=8 base align=8 +QXmlStreamWriter (0x0x7f51b7d4d3c0) 0 + +Class QDomImplementation + size=8 align=8 + base size=8 base align=8 +QDomImplementation (0x0x7f51b7d4d4e0) 0 + +Class QDomNode + size=8 align=8 + base size=8 base align=8 +QDomNode (0x0x7f51b7d4d540) 0 + +Class QDomNodeList + size=8 align=8 + base size=8 base align=8 +QDomNodeList (0x0x7f51b7d4d5a0) 0 + +Class QDomDocumentType + size=8 align=8 + base size=8 base align=8 +QDomDocumentType (0x0x7f51b80f6a90) 0 + QDomNode (0x0x7f51b7d4d600) 0 + +Class QDomDocument + size=8 align=8 + base size=8 base align=8 +QDomDocument (0x0x7f51b80f6af8) 0 + QDomNode (0x0x7f51b7d4d660) 0 + +Class QDomNamedNodeMap + size=8 align=8 + base size=8 base align=8 +QDomNamedNodeMap (0x0x7f51b7d4d6c0) 0 + +Class QDomDocumentFragment + size=8 align=8 + base size=8 base align=8 +QDomDocumentFragment (0x0x7f51b80f6b60) 0 + QDomNode (0x0x7f51b7d4d720) 0 + +Class QDomCharacterData + size=8 align=8 + base size=8 base align=8 +QDomCharacterData (0x0x7f51b80f6bc8) 0 + QDomNode (0x0x7f51b7d4d780) 0 + +Class QDomAttr + size=8 align=8 + base size=8 base align=8 +QDomAttr (0x0x7f51b80f6c30) 0 + QDomNode (0x0x7f51b7d4d7e0) 0 + +Class QDomElement + size=8 align=8 + base size=8 base align=8 +QDomElement (0x0x7f51b80f6c98) 0 + QDomNode (0x0x7f51b7d4d840) 0 + +Class QDomText + size=8 align=8 + base size=8 base align=8 +QDomText (0x0x7f51b80f6d00) 0 + QDomCharacterData (0x0x7f51b80f6d68) 0 + QDomNode (0x0x7f51b7d4d8a0) 0 + +Class QDomComment + size=8 align=8 + base size=8 base align=8 +QDomComment (0x0x7f51b80f6dd0) 0 + QDomCharacterData (0x0x7f51b80f6e38) 0 + QDomNode (0x0x7f51b7d4d900) 0 + +Class QDomCDATASection + size=8 align=8 + base size=8 base align=8 +QDomCDATASection (0x0x7f51b80f6ea0) 0 + QDomText (0x0x7f51b80f6f08) 0 + QDomCharacterData (0x0x7f51b80f6f70) 0 + QDomNode (0x0x7f51b7d4d960) 0 + +Class QDomNotation + size=8 align=8 + base size=8 base align=8 +QDomNotation (0x0x7f51b7deb000) 0 + QDomNode (0x0x7f51b7d4d9c0) 0 + +Class QDomEntity + size=8 align=8 + base size=8 base align=8 +QDomEntity (0x0x7f51b7deb068) 0 + QDomNode (0x0x7f51b7d4da20) 0 + +Class QDomEntityReference + size=8 align=8 + base size=8 base align=8 +QDomEntityReference (0x0x7f51b7deb0d0) 0 + QDomNode (0x0x7f51b7d4da80) 0 + +Class QDomProcessingInstruction + size=8 align=8 + base size=8 base align=8 +QDomProcessingInstruction (0x0x7f51b7deb138) 0 + QDomNode (0x0x7f51b7d4dae0) 0 + +Class QXmlNamespaceSupport + size=8 align=8 + base size=8 base align=8 +QXmlNamespaceSupport (0x0x7f51b7d4db40) 0 + +Class QXmlAttributes::Attribute + size=32 align=8 + base size=32 base align=8 +QXmlAttributes::Attribute (0x0x7f51b7d4dc00) 0 + +Vtable for QXmlAttributes +QXmlAttributes::_ZTV14QXmlAttributes: 4u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QXmlAttributes) +16 (int (*)(...))QXmlAttributes::~QXmlAttributes +24 (int (*)(...))QXmlAttributes::~QXmlAttributes + +Class QXmlAttributes + size=24 align=8 + base size=24 base align=8 +QXmlAttributes (0x0x7f51b7d4dba0) 0 + vptr=((& QXmlAttributes::_ZTV14QXmlAttributes) + 16u) + +Vtable for QXmlInputSource +QXmlInputSource::_ZTV15QXmlInputSource: 11u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QXmlInputSource) +16 (int (*)(...))QXmlInputSource::~QXmlInputSource +24 (int (*)(...))QXmlInputSource::~QXmlInputSource +32 (int (*)(...))QXmlInputSource::setData +40 (int (*)(...))QXmlInputSource::setData +48 (int (*)(...))QXmlInputSource::fetchData +56 (int (*)(...))QXmlInputSource::data +64 (int (*)(...))QXmlInputSource::next +72 (int (*)(...))QXmlInputSource::reset +80 (int (*)(...))QXmlInputSource::fromRawData + +Class QXmlInputSource + size=16 align=8 + base size=16 base align=8 +QXmlInputSource (0x0x7f51b7b28d80) 0 + vptr=((& QXmlInputSource::_ZTV15QXmlInputSource) + 16u) + +Class QXmlParseException + size=8 align=8 + base size=8 base align=8 +QXmlParseException (0x0x7f51b7b28de0) 0 + +Vtable for QXmlReader +QXmlReader::_ZTV10QXmlReader: 24u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI10QXmlReader) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual +128 (int (*)(...))__cxa_pure_virtual +136 (int (*)(...))__cxa_pure_virtual +144 (int (*)(...))__cxa_pure_virtual +152 (int (*)(...))__cxa_pure_virtual +160 (int (*)(...))__cxa_pure_virtual +168 (int (*)(...))__cxa_pure_virtual +176 (int (*)(...))__cxa_pure_virtual +184 (int (*)(...))__cxa_pure_virtual + +Class QXmlReader + size=8 align=8 + base size=8 base align=8 +QXmlReader (0x0x7f51b7b28ea0) 0 nearly-empty + vptr=((& QXmlReader::_ZTV10QXmlReader) + 16u) + +Vtable for QXmlSimpleReader +QXmlSimpleReader::_ZTV16QXmlSimpleReader: 26u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QXmlSimpleReader) +16 (int (*)(...))QXmlSimpleReader::~QXmlSimpleReader +24 (int (*)(...))QXmlSimpleReader::~QXmlSimpleReader +32 (int (*)(...))QXmlSimpleReader::feature +40 (int (*)(...))QXmlSimpleReader::setFeature +48 (int (*)(...))QXmlSimpleReader::hasFeature +56 (int (*)(...))QXmlSimpleReader::property +64 (int (*)(...))QXmlSimpleReader::setProperty +72 (int (*)(...))QXmlSimpleReader::hasProperty +80 (int (*)(...))QXmlSimpleReader::setEntityResolver +88 (int (*)(...))QXmlSimpleReader::entityResolver +96 (int (*)(...))QXmlSimpleReader::setDTDHandler +104 (int (*)(...))QXmlSimpleReader::DTDHandler +112 (int (*)(...))QXmlSimpleReader::setContentHandler +120 (int (*)(...))QXmlSimpleReader::contentHandler +128 (int (*)(...))QXmlSimpleReader::setErrorHandler +136 (int (*)(...))QXmlSimpleReader::errorHandler +144 (int (*)(...))QXmlSimpleReader::setLexicalHandler +152 (int (*)(...))QXmlSimpleReader::lexicalHandler +160 (int (*)(...))QXmlSimpleReader::setDeclHandler +168 (int (*)(...))QXmlSimpleReader::declHandler +176 (int (*)(...))QXmlSimpleReader::parse +184 (int (*)(...))QXmlSimpleReader::parse +192 (int (*)(...))QXmlSimpleReader::parse +200 (int (*)(...))QXmlSimpleReader::parseContinue + +Class QXmlSimpleReader + size=16 align=8 + base size=16 base align=8 +QXmlSimpleReader (0x0x7f51b7b30af8) 0 + vptr=((& QXmlSimpleReader::_ZTV16QXmlSimpleReader) + 16u) + QXmlReader (0x0x7f51b7b28f00) 0 nearly-empty + primary-for QXmlSimpleReader (0x0x7f51b7b30af8) + +Vtable for QXmlLocator +QXmlLocator::_ZTV11QXmlLocator: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI11QXmlLocator) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QXmlLocator + size=8 align=8 + base size=8 base align=8 +QXmlLocator (0x0x7f51b7b7c060) 0 nearly-empty + vptr=((& QXmlLocator::_ZTV11QXmlLocator) + 16u) + +Vtable for QXmlContentHandler +QXmlContentHandler::_ZTV18QXmlContentHandler: 16u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QXmlContentHandler) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual +96 (int (*)(...))__cxa_pure_virtual +104 (int (*)(...))__cxa_pure_virtual +112 (int (*)(...))__cxa_pure_virtual +120 (int (*)(...))__cxa_pure_virtual + +Class QXmlContentHandler + size=8 align=8 + base size=8 base align=8 +QXmlContentHandler (0x0x7f51b7b7c0c0) 0 nearly-empty + vptr=((& QXmlContentHandler::_ZTV18QXmlContentHandler) + 16u) + +Vtable for QXmlErrorHandler +QXmlErrorHandler::_ZTV16QXmlErrorHandler: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI16QXmlErrorHandler) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual + +Class QXmlErrorHandler + size=8 align=8 + base size=8 base align=8 +QXmlErrorHandler (0x0x7f51b7b7c120) 0 nearly-empty + vptr=((& QXmlErrorHandler::_ZTV16QXmlErrorHandler) + 16u) + +Vtable for QXmlDTDHandler +QXmlDTDHandler::_ZTV14QXmlDTDHandler: 7u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI14QXmlDTDHandler) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual + +Class QXmlDTDHandler + size=8 align=8 + base size=8 base align=8 +QXmlDTDHandler (0x0x7f51b7b7c180) 0 nearly-empty + vptr=((& QXmlDTDHandler::_ZTV14QXmlDTDHandler) + 16u) + +Vtable for QXmlEntityResolver +QXmlEntityResolver::_ZTV18QXmlEntityResolver: 6u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QXmlEntityResolver) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual + +Class QXmlEntityResolver + size=8 align=8 + base size=8 base align=8 +QXmlEntityResolver (0x0x7f51b7b7c1e0) 0 nearly-empty + vptr=((& QXmlEntityResolver::_ZTV18QXmlEntityResolver) + 16u) + +Vtable for QXmlLexicalHandler +QXmlLexicalHandler::_ZTV18QXmlLexicalHandler: 12u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QXmlLexicalHandler) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual +64 (int (*)(...))__cxa_pure_virtual +72 (int (*)(...))__cxa_pure_virtual +80 (int (*)(...))__cxa_pure_virtual +88 (int (*)(...))__cxa_pure_virtual + +Class QXmlLexicalHandler + size=8 align=8 + base size=8 base align=8 +QXmlLexicalHandler (0x0x7f51b7b7c240) 0 nearly-empty + vptr=((& QXmlLexicalHandler::_ZTV18QXmlLexicalHandler) + 16u) + +Vtable for QXmlDeclHandler +QXmlDeclHandler::_ZTV15QXmlDeclHandler: 8u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI15QXmlDeclHandler) +16 0u +24 0u +32 (int (*)(...))__cxa_pure_virtual +40 (int (*)(...))__cxa_pure_virtual +48 (int (*)(...))__cxa_pure_virtual +56 (int (*)(...))__cxa_pure_virtual + +Class QXmlDeclHandler + size=8 align=8 + base size=8 base align=8 +QXmlDeclHandler (0x0x7f51b7b7c2a0) 0 nearly-empty + vptr=((& QXmlDeclHandler::_ZTV15QXmlDeclHandler) + 16u) + +Vtable for QXmlDefaultHandler +QXmlDefaultHandler::_ZTV18QXmlDefaultHandler: 73u entries +0 (int (*)(...))0 +8 (int (*)(...))(& _ZTI18QXmlDefaultHandler) +16 (int (*)(...))QXmlDefaultHandler::~QXmlDefaultHandler +24 (int (*)(...))QXmlDefaultHandler::~QXmlDefaultHandler +32 (int (*)(...))QXmlDefaultHandler::setDocumentLocator +40 (int (*)(...))QXmlDefaultHandler::startDocument +48 (int (*)(...))QXmlDefaultHandler::endDocument +56 (int (*)(...))QXmlDefaultHandler::startPrefixMapping +64 (int (*)(...))QXmlDefaultHandler::endPrefixMapping +72 (int (*)(...))QXmlDefaultHandler::startElement +80 (int (*)(...))QXmlDefaultHandler::endElement +88 (int (*)(...))QXmlDefaultHandler::characters +96 (int (*)(...))QXmlDefaultHandler::ignorableWhitespace +104 (int (*)(...))QXmlDefaultHandler::processingInstruction +112 (int (*)(...))QXmlDefaultHandler::skippedEntity +120 (int (*)(...))QXmlDefaultHandler::errorString +128 (int (*)(...))QXmlDefaultHandler::warning +136 (int (*)(...))QXmlDefaultHandler::error +144 (int (*)(...))QXmlDefaultHandler::fatalError +152 (int (*)(...))QXmlDefaultHandler::notationDecl +160 (int (*)(...))QXmlDefaultHandler::unparsedEntityDecl +168 (int (*)(...))QXmlDefaultHandler::resolveEntity +176 (int (*)(...))QXmlDefaultHandler::startDTD +184 (int (*)(...))QXmlDefaultHandler::endDTD +192 (int (*)(...))QXmlDefaultHandler::startEntity +200 (int (*)(...))QXmlDefaultHandler::endEntity +208 (int (*)(...))QXmlDefaultHandler::startCDATA +216 (int (*)(...))QXmlDefaultHandler::endCDATA +224 (int (*)(...))QXmlDefaultHandler::comment +232 (int (*)(...))QXmlDefaultHandler::attributeDecl +240 (int (*)(...))QXmlDefaultHandler::internalEntityDecl +248 (int (*)(...))QXmlDefaultHandler::externalEntityDecl +256 (int (*)(...))-8 +264 (int (*)(...))(& _ZTI18QXmlDefaultHandler) +272 (int (*)(...))QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandlerD1Ev +280 (int (*)(...))QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandlerD0Ev +288 (int (*)(...))QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandler7warningERK18QXmlParseException +296 (int (*)(...))QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandler5errorERK18QXmlParseException +304 (int (*)(...))QXmlDefaultHandler::_ZThn8_N18QXmlDefaultHandler10fatalErrorERK18QXmlParseException +312 (int (*)(...))QXmlDefaultHandler::_ZThn8_NK18QXmlDefaultHandler11errorStringEv +320 (int (*)(...))-16 +328 (int (*)(...))(& _ZTI18QXmlDefaultHandler) +336 (int (*)(...))QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandlerD1Ev +344 (int (*)(...))QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandlerD0Ev +352 (int (*)(...))QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler12notationDeclERK7QStringS2_S2_ +360 (int (*)(...))QXmlDefaultHandler::_ZThn16_N18QXmlDefaultHandler18unparsedEntityDeclERK7QStringS2_S2_S2_ +368 (int (*)(...))QXmlDefaultHandler::_ZThn16_NK18QXmlDefaultHandler11errorStringEv +376 (int (*)(...))-24 +384 (int (*)(...))(& _ZTI18QXmlDefaultHandler) +392 (int (*)(...))QXmlDefaultHandler::_ZThn24_N18QXmlDefaultHandlerD1Ev +400 (int (*)(...))QXmlDefaultHandler::_ZThn24_N18QXmlDefaultHandlerD0Ev +408 (int (*)(...))QXmlDefaultHandler::_ZThn24_N18QXmlDefaultHandler13resolveEntityERK7QStringS2_RP15QXmlInputSource +416 (int (*)(...))QXmlDefaultHandler::_ZThn24_NK18QXmlDefaultHandler11errorStringEv +424 (int (*)(...))-32 +432 (int (*)(...))(& _ZTI18QXmlDefaultHandler) +440 (int (*)(...))QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandlerD1Ev +448 (int (*)(...))QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandlerD0Ev +456 (int (*)(...))QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler8startDTDERK7QStringS2_S2_ +464 (int (*)(...))QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler6endDTDEv +472 (int (*)(...))QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler11startEntityERK7QString +480 (int (*)(...))QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler9endEntityERK7QString +488 (int (*)(...))QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler10startCDATAEv +496 (int (*)(...))QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler8endCDATAEv +504 (int (*)(...))QXmlDefaultHandler::_ZThn32_N18QXmlDefaultHandler7commentERK7QString +512 (int (*)(...))QXmlDefaultHandler::_ZThn32_NK18QXmlDefaultHandler11errorStringEv +520 (int (*)(...))-40 +528 (int (*)(...))(& _ZTI18QXmlDefaultHandler) +536 (int (*)(...))QXmlDefaultHandler::_ZThn40_N18QXmlDefaultHandlerD1Ev +544 (int (*)(...))QXmlDefaultHandler::_ZThn40_N18QXmlDefaultHandlerD0Ev +552 (int (*)(...))QXmlDefaultHandler::_ZThn40_N18QXmlDefaultHandler13attributeDeclERK7QStringS2_S2_S2_S2_ +560 (int (*)(...))QXmlDefaultHandler::_ZThn40_N18QXmlDefaultHandler18internalEntityDeclERK7QStringS2_ +568 (int (*)(...))QXmlDefaultHandler::_ZThn40_N18QXmlDefaultHandler18externalEntityDeclERK7QStringS2_S2_ +576 (int (*)(...))QXmlDefaultHandler::_ZThn40_NK18QXmlDefaultHandler11errorStringEv + +Class QXmlDefaultHandler + size=56 align=8 + base size=56 base align=8 +QXmlDefaultHandler (0x0x7f51b7bab3f0) 0 + vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 16u) + QXmlContentHandler (0x0x7f51b7b7c300) 0 nearly-empty + primary-for QXmlDefaultHandler (0x0x7f51b7bab3f0) + QXmlErrorHandler (0x0x7f51b7b7c360) 8 nearly-empty + vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 272u) + QXmlDTDHandler (0x0x7f51b7b7c3c0) 16 nearly-empty + vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 336u) + QXmlEntityResolver (0x0x7f51b7b7c420) 24 nearly-empty + vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 392u) + QXmlLexicalHandler (0x0x7f51b7b7c480) 32 nearly-empty + vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 440u) + QXmlDeclHandler (0x0x7f51b7b7c4e0) 40 nearly-empty + vptr=((& QXmlDefaultHandler::_ZTV18QXmlDefaultHandler) + 536u) + From f372714e96c91619179574b05d97cea07ffc3b5d Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 17 Dec 2018 10:51:33 +0100 Subject: [PATCH 0723/1650] Doc: Fix typo in QStyle Change-Id: Ic979cb66acb3f8824aefb6ad858c0f746ce3e02b Reviewed-by: Leena Miettinen --- src/widgets/styles/qstyle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp index 8006be8c27..ac4fb7fbd1 100644 --- a/src/widgets/styles/qstyle.cpp +++ b/src/widgets/styles/qstyle.cpp @@ -1998,7 +1998,7 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment, This enum value has been introduced in Qt 5.10. \value SH_SpinBox_ButtonsInsideFrame - Determnines if the spin box buttons are inside the line edit frame. + Determines if the spin box buttons are inside the line edit frame. This enum value has been introduced in Qt 5.11. \value SH_SpinBox_StepModifier From 28a28af182c7fb9b0cf6d0b9ccc948843c6992a1 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 20 Dec 2018 15:48:06 +0100 Subject: [PATCH 0724/1650] QtCore: Unify license headers Change-Id: Iff4f6da9f0bbf7a0627101f455dd8467681b2783 Reviewed-by: Thiago Macieira --- ...elib_animation_qparallelanimationgroup.cpp | 49 +++++++----- ...c_corelib_animation_qpropertyanimation.cpp | 49 +++++++----- ...ib_animation_qsequentialanimationgroup.cpp | 49 +++++++----- ...rc_corelib_animation_qvariantanimation.cpp | 49 +++++++----- .../code/src_corelib_global_qlogging.cpp | 49 +++++++----- .../code/src_corelib_global_qnumeric.cpp | 49 +++++++----- ...corelib_global_qoperatingsystemversion.cpp | 49 +++++++----- .../code/src_corelib_global_qrandom.cpp | 49 +++++++----- .../snippets/code/src_corelib_io_qdebug.cpp | 49 +++++++----- .../code/src_corelib_io_qfileselector.cpp | 49 +++++++----- .../code/src_corelib_io_qloggingcategory.cpp | 49 +++++++----- .../code/src_corelib_io_qstorageinfo.cpp | 49 +++++++----- .../code/src_corelib_io_qurlquery.cpp | 49 +++++++----- .../src_corelib_kernel_qdeadlinetimer.cpp | 49 +++++++----- .../src_corelib_kernel_qtestsupport_core.cpp | 49 +++++++----- .../src_corelib_serialization_qcborstream.cpp | 49 +++++++----- .../src_corelib_serialization_qcborvalue.cpp | 49 +++++++----- .../src_corelib_serialization_qdatastream.cpp | 49 +++++++----- ...rc_corelib_serialization_qjsondocument.cpp | 49 +++++++----- .../src_corelib_tools_qbytearraymatcher.cpp | 49 +++++++----- .../src_corelib_tools_qcontiguouscache.cpp | 49 +++++++----- .../code/src_corelib_tools_qshareddata.cpp | 49 +++++++----- .../code/src_corelib_tools_qsharedpointer.cpp | 49 +++++++----- .../code/src_corelib_tools_qstringview.cpp | 49 +++++++----- .../src_gui_itemviews_qidentityproxymodel.cpp | 2 +- src/corelib/doc/snippets/hellotrmain.cpp | 2 +- .../doc/snippets/qbytearraylist/main.cpp | 49 +++++++----- .../doc/snippets/qelapsedtimer/main.cpp | 2 +- .../doc/snippets/qloggingcategory/main.cpp | 2 +- .../snippets/resource-system/mainwindow.cpp | 2 +- .../doc/snippets/timers/analogclock.cpp | 2 +- src/corelib/global/archdetect.cpp | 2 +- .../itemmodels/qabstractproxymodel.cpp | 2 +- src/corelib/itemmodels/qabstractproxymodel.h | 2 +- .../itemmodels/qabstractproxymodel_p.h | 2 +- .../itemmodels/qidentityproxymodel.cpp | 2 +- src/corelib/itemmodels/qidentityproxymodel.h | 2 +- .../itemmodels/qitemselectionmodel.cpp | 2 +- src/corelib/itemmodels/qitemselectionmodel.h | 2 +- .../itemmodels/qitemselectionmodel_p.h | 2 +- .../itemmodels/qsortfilterproxymodel.cpp | 2 +- .../itemmodels/qsortfilterproxymodel.h | 2 +- src/corelib/itemmodels/qstringlistmodel.cpp | 2 +- src/corelib/itemmodels/qstringlistmodel.h | 2 +- src/corelib/kernel/qcore_mac_objc.mm | 76 +++++++++---------- src/corelib/kernel/qppsattribute.cpp | 74 +++++++++--------- src/corelib/kernel/qppsattribute_p.h | 75 +++++++++--------- src/corelib/kernel/qppsattributeprivate_p.h | 74 +++++++++--------- src/corelib/kernel/qppsobject.cpp | 74 +++++++++--------- src/corelib/kernel/qppsobject_p.h | 74 +++++++++--------- src/corelib/kernel/qppsobjectprivate_p.h | 74 +++++++++--------- src/corelib/kernel/qtestsupport_core.cpp | 2 +- src/corelib/kernel/qtestsupport_core.h | 2 +- src/corelib/tools/qstring_mips_dsp_asm.S | 2 +- 54 files changed, 1033 insertions(+), 757 deletions(-) diff --git a/src/corelib/doc/snippets/code/src_corelib_animation_qparallelanimationgroup.cpp b/src/corelib/doc/snippets/code/src_corelib_animation_qparallelanimationgroup.cpp index 3fc53bc58b..472c5d41c4 100644 --- a/src/corelib/doc/snippets/code/src_corelib_animation_qparallelanimationgroup.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_animation_qparallelanimationgroup.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/corelib/doc/snippets/code/src_corelib_animation_qpropertyanimation.cpp b/src/corelib/doc/snippets/code/src_corelib_animation_qpropertyanimation.cpp index a6dbd909d7..7bd8121b90 100644 --- a/src/corelib/doc/snippets/code/src_corelib_animation_qpropertyanimation.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_animation_qpropertyanimation.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/corelib/doc/snippets/code/src_corelib_animation_qsequentialanimationgroup.cpp b/src/corelib/doc/snippets/code/src_corelib_animation_qsequentialanimationgroup.cpp index 1f1363f127..0eff184926 100644 --- a/src/corelib/doc/snippets/code/src_corelib_animation_qsequentialanimationgroup.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_animation_qsequentialanimationgroup.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/corelib/doc/snippets/code/src_corelib_animation_qvariantanimation.cpp b/src/corelib/doc/snippets/code/src_corelib_animation_qvariantanimation.cpp index b462ff2d6a..0808dcc145 100644 --- a/src/corelib/doc/snippets/code/src_corelib_animation_qvariantanimation.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_animation_qvariantanimation.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qlogging.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qlogging.cpp index 7b0b357cff..7589050bc2 100644 --- a/src/corelib/doc/snippets/code/src_corelib_global_qlogging.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_global_qlogging.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qnumeric.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qnumeric.cpp index 5d64070b1b..d281089041 100644 --- a/src/corelib/doc/snippets/code/src_corelib_global_qnumeric.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_global_qnumeric.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qoperatingsystemversion.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qoperatingsystemversion.cpp index d9e927c55a..c712dfa432 100644 --- a/src/corelib/doc/snippets/code/src_corelib_global_qoperatingsystemversion.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_global_qoperatingsystemversion.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qrandom.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qrandom.cpp index b03e656b64..6e47a7a3d9 100644 --- a/src/corelib/doc/snippets/code/src_corelib_global_qrandom.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_global_qrandom.cpp @@ -4,9 +4,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -15,24 +15,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/corelib/doc/snippets/code/src_corelib_io_qdebug.cpp b/src/corelib/doc/snippets/code/src_corelib_io_qdebug.cpp index 4bbdc509ca..14e72e99dd 100644 --- a/src/corelib/doc/snippets/code/src_corelib_io_qdebug.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_io_qdebug.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/corelib/doc/snippets/code/src_corelib_io_qfileselector.cpp b/src/corelib/doc/snippets/code/src_corelib_io_qfileselector.cpp index 91c94eb762..0d1aa691cf 100644 --- a/src/corelib/doc/snippets/code/src_corelib_io_qfileselector.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_io_qfileselector.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtWidgets module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/corelib/doc/snippets/code/src_corelib_io_qloggingcategory.cpp b/src/corelib/doc/snippets/code/src_corelib_io_qloggingcategory.cpp index 20ae52a251..cab48f1e27 100644 --- a/src/corelib/doc/snippets/code/src_corelib_io_qloggingcategory.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_io_qloggingcategory.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/corelib/doc/snippets/code/src_corelib_io_qstorageinfo.cpp b/src/corelib/doc/snippets/code/src_corelib_io_qstorageinfo.cpp index e0594433ff..c7a1b34f7a 100644 --- a/src/corelib/doc/snippets/code/src_corelib_io_qstorageinfo.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_io_qstorageinfo.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2014 Ivan Komissarov ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/corelib/doc/snippets/code/src_corelib_io_qurlquery.cpp b/src/corelib/doc/snippets/code/src_corelib_io_qurlquery.cpp index da87bfd143..22f1d3260f 100644 --- a/src/corelib/doc/snippets/code/src_corelib_io_qurlquery.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_io_qurlquery.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtWidgets module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qdeadlinetimer.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qdeadlinetimer.cpp index eb291d7b18..35c06f842e 100644 --- a/src/corelib/doc/snippets/code/src_corelib_kernel_qdeadlinetimer.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qdeadlinetimer.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtWidgets module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp index ed3e9bd0c0..e793cb1f55 100644 --- a/src/corelib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtTest module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/corelib/doc/snippets/code/src_corelib_serialization_qcborstream.cpp b/src/corelib/doc/snippets/code/src_corelib_serialization_qcborstream.cpp index dbe38aa4b5..6ddb5a9365 100644 --- a/src/corelib/doc/snippets/code/src_corelib_serialization_qcborstream.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_serialization_qcborstream.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtWidgets module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/corelib/doc/snippets/code/src_corelib_serialization_qcborvalue.cpp b/src/corelib/doc/snippets/code/src_corelib_serialization_qcborvalue.cpp index 63f813cf69..5406536cfe 100644 --- a/src/corelib/doc/snippets/code/src_corelib_serialization_qcborvalue.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_serialization_qcborvalue.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtWidgets module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/corelib/doc/snippets/code/src_corelib_serialization_qdatastream.cpp b/src/corelib/doc/snippets/code/src_corelib_serialization_qdatastream.cpp index 5caaa16727..cfcc2f8f94 100644 --- a/src/corelib/doc/snippets/code/src_corelib_serialization_qdatastream.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_serialization_qdatastream.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/corelib/doc/snippets/code/src_corelib_serialization_qjsondocument.cpp b/src/corelib/doc/snippets/code/src_corelib_serialization_qjsondocument.cpp index c4913b1740..1fe328c0a0 100644 --- a/src/corelib/doc/snippets/code/src_corelib_serialization_qjsondocument.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_serialization_qjsondocument.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qbytearraymatcher.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qbytearraymatcher.cpp index 63fc1f91e7..9cf94f0494 100644 --- a/src/corelib/doc/snippets/code/src_corelib_tools_qbytearraymatcher.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_tools_qbytearraymatcher.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qcontiguouscache.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qcontiguouscache.cpp index 6bc9604243..84780374e9 100644 --- a/src/corelib/doc/snippets/code/src_corelib_tools_qcontiguouscache.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_tools_qcontiguouscache.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qshareddata.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qshareddata.cpp index 45e8b0a965..88c8ae4151 100644 --- a/src/corelib/doc/snippets/code/src_corelib_tools_qshareddata.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_tools_qshareddata.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qsharedpointer.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qsharedpointer.cpp index 69061ce298..e2979fa7b4 100644 --- a/src/corelib/doc/snippets/code/src_corelib_tools_qsharedpointer.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_tools_qsharedpointer.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qstringview.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qstringview.cpp index 5dc153372c..fc426e1977 100644 --- a/src/corelib/doc/snippets/code/src_corelib_tools_qstringview.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_tools_qstringview.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtWidgets module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/corelib/doc/snippets/code/src_gui_itemviews_qidentityproxymodel.cpp b/src/corelib/doc/snippets/code/src_gui_itemviews_qidentityproxymodel.cpp index d89e28836f..c1af521c03 100644 --- a/src/corelib/doc/snippets/code/src_gui_itemviews_qidentityproxymodel.cpp +++ b/src/corelib/doc/snippets/code/src_gui_itemviews_qidentityproxymodel.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage diff --git a/src/corelib/doc/snippets/hellotrmain.cpp b/src/corelib/doc/snippets/hellotrmain.cpp index 7e09c58f4f..2fab919a47 100644 --- a/src/corelib/doc/snippets/hellotrmain.cpp +++ b/src/corelib/doc/snippets/hellotrmain.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the examples of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage diff --git a/src/corelib/doc/snippets/qbytearraylist/main.cpp b/src/corelib/doc/snippets/qbytearraylist/main.cpp index 8a861eca4a..fd52ef945b 100644 --- a/src/corelib/doc/snippets/qbytearraylist/main.cpp +++ b/src/corelib/doc/snippets/qbytearraylist/main.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2014 by Southwest Research Institute (R) ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/corelib/doc/snippets/qelapsedtimer/main.cpp b/src/corelib/doc/snippets/qelapsedtimer/main.cpp index add6ad0169..408c4eab07 100644 --- a/src/corelib/doc/snippets/qelapsedtimer/main.cpp +++ b/src/corelib/doc/snippets/qelapsedtimer/main.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtNetwork module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage diff --git a/src/corelib/doc/snippets/qloggingcategory/main.cpp b/src/corelib/doc/snippets/qloggingcategory/main.cpp index 73df3c2d2f..f5c47b2ae8 100644 --- a/src/corelib/doc/snippets/qloggingcategory/main.cpp +++ b/src/corelib/doc/snippets/qloggingcategory/main.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the examples of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage diff --git a/src/corelib/doc/snippets/resource-system/mainwindow.cpp b/src/corelib/doc/snippets/resource-system/mainwindow.cpp index 6fcf52e588..bbeeec64ac 100644 --- a/src/corelib/doc/snippets/resource-system/mainwindow.cpp +++ b/src/corelib/doc/snippets/resource-system/mainwindow.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the examples of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage diff --git a/src/corelib/doc/snippets/timers/analogclock.cpp b/src/corelib/doc/snippets/timers/analogclock.cpp index 0dc2fbc708..4e1957a450 100644 --- a/src/corelib/doc/snippets/timers/analogclock.cpp +++ b/src/corelib/doc/snippets/timers/analogclock.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the examples of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage diff --git a/src/corelib/global/archdetect.cpp b/src/corelib/global/archdetect.cpp index 422df3ff90..66a5e074f6 100644 --- a/src/corelib/global/archdetect.cpp +++ b/src/corelib/global/archdetect.cpp @@ -4,7 +4,7 @@ ** Copyright (C) 2016 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the FOO module of the Qt Toolkit. +** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/corelib/itemmodels/qabstractproxymodel.cpp b/src/corelib/itemmodels/qabstractproxymodel.cpp index b7c49a53e4..62b3ee85b9 100644 --- a/src/corelib/itemmodels/qabstractproxymodel.cpp +++ b/src/corelib/itemmodels/qabstractproxymodel.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/corelib/itemmodels/qabstractproxymodel.h b/src/corelib/itemmodels/qabstractproxymodel.h index c4e5d67908..08ecf9d15f 100644 --- a/src/corelib/itemmodels/qabstractproxymodel.h +++ b/src/corelib/itemmodels/qabstractproxymodel.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/corelib/itemmodels/qabstractproxymodel_p.h b/src/corelib/itemmodels/qabstractproxymodel_p.h index 3a9f33baba..f7bd5cc691 100644 --- a/src/corelib/itemmodels/qabstractproxymodel_p.h +++ b/src/corelib/itemmodels/qabstractproxymodel_p.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/corelib/itemmodels/qidentityproxymodel.cpp b/src/corelib/itemmodels/qidentityproxymodel.cpp index c1e23dbd0c..f869601d3f 100644 --- a/src/corelib/itemmodels/qidentityproxymodel.cpp +++ b/src/corelib/itemmodels/qidentityproxymodel.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/corelib/itemmodels/qidentityproxymodel.h b/src/corelib/itemmodels/qidentityproxymodel.h index 3e6f5e4c48..89ac89cdba 100644 --- a/src/corelib/itemmodels/qidentityproxymodel.h +++ b/src/corelib/itemmodels/qidentityproxymodel.h @@ -3,7 +3,7 @@ ** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/corelib/itemmodels/qitemselectionmodel.cpp b/src/corelib/itemmodels/qitemselectionmodel.cpp index edb9bb9098..1bacb63b17 100644 --- a/src/corelib/itemmodels/qitemselectionmodel.cpp +++ b/src/corelib/itemmodels/qitemselectionmodel.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/corelib/itemmodels/qitemselectionmodel.h b/src/corelib/itemmodels/qitemselectionmodel.h index 63e5f0ca9c..1c924053a5 100644 --- a/src/corelib/itemmodels/qitemselectionmodel.h +++ b/src/corelib/itemmodels/qitemselectionmodel.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/corelib/itemmodels/qitemselectionmodel_p.h b/src/corelib/itemmodels/qitemselectionmodel_p.h index 187d4a2c1d..e12a0c2928 100644 --- a/src/corelib/itemmodels/qitemselectionmodel_p.h +++ b/src/corelib/itemmodels/qitemselectionmodel_p.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp index 21fbf83382..87960b0863 100644 --- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp +++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.h b/src/corelib/itemmodels/qsortfilterproxymodel.h index 0be8b88672..303226668f 100644 --- a/src/corelib/itemmodels/qsortfilterproxymodel.h +++ b/src/corelib/itemmodels/qsortfilterproxymodel.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/corelib/itemmodels/qstringlistmodel.cpp b/src/corelib/itemmodels/qstringlistmodel.cpp index 567e6fa35e..0adaba9b9a 100644 --- a/src/corelib/itemmodels/qstringlistmodel.cpp +++ b/src/corelib/itemmodels/qstringlistmodel.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/corelib/itemmodels/qstringlistmodel.h b/src/corelib/itemmodels/qstringlistmodel.h index a40c13ae40..53376285c6 100644 --- a/src/corelib/itemmodels/qstringlistmodel.h +++ b/src/corelib/itemmodels/qstringlistmodel.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm index 4ca9c2e996..cb3539f3ec 100644 --- a/src/corelib/kernel/qcore_mac_objc.mm +++ b/src/corelib/kernel/qcore_mac_objc.mm @@ -1,42 +1,42 @@ /**************************************************************************** - ** - ** Copyright (C) 2016 The Qt Company Ltd. - ** Copyright (C) 2014 Petroules Corporation. - ** Contact: https://www.qt.io/licensing/ - ** - ** This file is part of the QtCore module of the Qt Toolkit. - ** - ** $QT_BEGIN_LICENSE:LGPL$ - ** Commercial License Usage - ** Licensees holding valid commercial Qt licenses may use this file in - ** accordance with the commercial license agreement provided with the - ** Software or, alternatively, in accordance with the terms contained in - ** a written agreement between you and The Qt Company. For licensing terms - ** and conditions see https://www.qt.io/terms-conditions. For further - ** information use the contact form at https://www.qt.io/contact-us. - ** - ** GNU Lesser General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU Lesser - ** General Public License version 3 as published by the Free Software - ** Foundation and appearing in the file LICENSE.LGPL3 included in the - ** packaging of this file. Please review the following information to - ** ensure the GNU Lesser General Public License version 3 requirements - ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. - ** - ** GNU General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU - ** General Public License version 2.0 or (at your option) the GNU General - ** Public license version 3 or any later version approved by the KDE Free - ** Qt Foundation. The licenses are as published by the Free Software - ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 - ** included in the packaging of this file. Please review the following - ** information to ensure the GNU General Public License requirements will - ** be met: https://www.gnu.org/licenses/gpl-2.0.html and - ** https://www.gnu.org/licenses/gpl-3.0.html. - ** - ** $QT_END_LICENSE$ - ** - ****************************************************************************/ +** +** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2014 Petroules Corporation. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ #include diff --git a/src/corelib/kernel/qppsattribute.cpp b/src/corelib/kernel/qppsattribute.cpp index ffd5c53a6d..6be462edb5 100644 --- a/src/corelib/kernel/qppsattribute.cpp +++ b/src/corelib/kernel/qppsattribute.cpp @@ -1,41 +1,41 @@ /**************************************************************************** - ** - ** Copyright (C) 2013 BlackBerry Limited. All rights reserved. - ** Contact: https://www.qt.io/licensing/ - ** - ** This file is part of the QtCore module of the Qt Toolkit. - ** - ** $QT_BEGIN_LICENSE:LGPL$ - ** Commercial License Usage - ** Licensees holding valid commercial Qt licenses may use this file in - ** accordance with the commercial license agreement provided with the - ** Software or, alternatively, in accordance with the terms contained in - ** a written agreement between you and The Qt Company. For licensing terms - ** and conditions see https://www.qt.io/terms-conditions. For further - ** information use the contact form at https://www.qt.io/contact-us. - ** - ** GNU Lesser General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU Lesser - ** General Public License version 3 as published by the Free Software - ** Foundation and appearing in the file LICENSE.LGPL3 included in the - ** packaging of this file. Please review the following information to - ** ensure the GNU Lesser General Public License version 3 requirements - ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. - ** - ** GNU General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU - ** General Public License version 2.0 or (at your option) the GNU General - ** Public license version 3 or any later version approved by the KDE Free - ** Qt Foundation. The licenses are as published by the Free Software - ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 - ** included in the packaging of this file. Please review the following - ** information to ensure the GNU General Public License requirements will - ** be met: https://www.gnu.org/licenses/gpl-2.0.html and - ** https://www.gnu.org/licenses/gpl-3.0.html. - ** - ** $QT_END_LICENSE$ - ** - ****************************************************************************/ +** +** Copyright (C) 2013 BlackBerry Limited. All rights reserved. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ #include "qppsattribute_p.h" #include "qppsattributeprivate_p.h" diff --git a/src/corelib/kernel/qppsattribute_p.h b/src/corelib/kernel/qppsattribute_p.h index 035756e002..b59dcd5851 100644 --- a/src/corelib/kernel/qppsattribute_p.h +++ b/src/corelib/kernel/qppsattribute_p.h @@ -1,41 +1,42 @@ /**************************************************************************** - ** - ** Copyright (C) 2013 BlackBerry Limited. All rights reserved. - ** Contact: https://www.qt.io/licensing/ - ** - ** This file is part of the QtCore module of the Qt Toolkit. - ** - ** $QT_BEGIN_LICENSE:LGPL$ - ** Commercial License Usage - ** Licensees holding valid commercial Qt licenses may use this file in - ** accordance with the commercial license agreement provided with the - ** Software or, alternatively, in accordance with the terms contained in - ** a written agreement between you and The Qt Company. For licensing terms - ** and conditions see https://www.qt.io/terms-conditions. For further - ** information use the contact form at https://www.qt.io/contact-us. - ** - ** GNU Lesser General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU Lesser - ** General Public License version 3 as published by the Free Software - ** Foundation and appearing in the file LICENSE.LGPL3 included in the - ** packaging of this file. Please review the following information to - ** ensure the GNU Lesser General Public License version 3 requirements - ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. - ** - ** GNU General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU - ** General Public License version 2.0 or (at your option) the GNU General - ** Public license version 3 or any later version approved by the KDE Free - ** Qt Foundation. The licenses are as published by the Free Software - ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 - ** included in the packaging of this file. Please review the following - ** information to ensure the GNU General Public License requirements will - ** be met: https://www.gnu.org/licenses/gpl-2.0.html and - ** https://www.gnu.org/licenses/gpl-3.0.html. - ** - ** $QT_END_LICENSE$ - ** - ****************************************************************************/ +** +** Copyright (C) 2013 BlackBerry Limited. All rights reserved. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + #ifndef QPPSATTRIBUTE_P_H #define QPPSATTRIBUTE_P_H diff --git a/src/corelib/kernel/qppsattributeprivate_p.h b/src/corelib/kernel/qppsattributeprivate_p.h index 6166447ef2..78b7b3c4c2 100644 --- a/src/corelib/kernel/qppsattributeprivate_p.h +++ b/src/corelib/kernel/qppsattributeprivate_p.h @@ -1,41 +1,41 @@ /**************************************************************************** - ** - ** Copyright (C) 2013 BlackBerry Limited. All rights reserved. - ** Contact: https://www.qt.io/licensing/ - ** - ** This file is part of the QtCore module of the Qt Toolkit. - ** - ** $QT_BEGIN_LICENSE:LGPL$ - ** Commercial License Usage - ** Licensees holding valid commercial Qt licenses may use this file in - ** accordance with the commercial license agreement provided with the - ** Software or, alternatively, in accordance with the terms contained in - ** a written agreement between you and The Qt Company. For licensing terms - ** and conditions see https://www.qt.io/terms-conditions. For further - ** information use the contact form at https://www.qt.io/contact-us. - ** - ** GNU Lesser General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU Lesser - ** General Public License version 3 as published by the Free Software - ** Foundation and appearing in the file LICENSE.LGPL3 included in the - ** packaging of this file. Please review the following information to - ** ensure the GNU Lesser General Public License version 3 requirements - ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. - ** - ** GNU General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU - ** General Public License version 2.0 or (at your option) the GNU General - ** Public license version 3 or any later version approved by the KDE Free - ** Qt Foundation. The licenses are as published by the Free Software - ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 - ** included in the packaging of this file. Please review the following - ** information to ensure the GNU General Public License requirements will - ** be met: https://www.gnu.org/licenses/gpl-2.0.html and - ** https://www.gnu.org/licenses/gpl-3.0.html. - ** - ** $QT_END_LICENSE$ - ** - ****************************************************************************/ +** +** Copyright (C) 2013 BlackBerry Limited. All rights reserved. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ #ifndef QPPSATTRIBUTEPRIVATE_P_H #define QPPSATTRIBUTEPRIVATE_P_H diff --git a/src/corelib/kernel/qppsobject.cpp b/src/corelib/kernel/qppsobject.cpp index d58715d12b..f4001d3833 100644 --- a/src/corelib/kernel/qppsobject.cpp +++ b/src/corelib/kernel/qppsobject.cpp @@ -1,41 +1,41 @@ /**************************************************************************** - ** - ** Copyright (C) 2013 BlackBerry Limited. All rights reserved. - ** Contact: https://www.qt.io/licensing/ - ** - ** This file is part of the QtCore module of the Qt Toolkit. - ** - ** $QT_BEGIN_LICENSE:LGPL$ - ** Commercial License Usage - ** Licensees holding valid commercial Qt licenses may use this file in - ** accordance with the commercial license agreement provided with the - ** Software or, alternatively, in accordance with the terms contained in - ** a written agreement between you and The Qt Company. For licensing terms - ** and conditions see https://www.qt.io/terms-conditions. For further - ** information use the contact form at https://www.qt.io/contact-us. - ** - ** GNU Lesser General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU Lesser - ** General Public License version 3 as published by the Free Software - ** Foundation and appearing in the file LICENSE.LGPL3 included in the - ** packaging of this file. Please review the following information to - ** ensure the GNU Lesser General Public License version 3 requirements - ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. - ** - ** GNU General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU - ** General Public License version 2.0 or (at your option) the GNU General - ** Public license version 3 or any later version approved by the KDE Free - ** Qt Foundation. The licenses are as published by the Free Software - ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 - ** included in the packaging of this file. Please review the following - ** information to ensure the GNU General Public License requirements will - ** be met: https://www.gnu.org/licenses/gpl-2.0.html and - ** https://www.gnu.org/licenses/gpl-3.0.html. - ** - ** $QT_END_LICENSE$ - ** - ****************************************************************************/ +** +** Copyright (C) 2013 BlackBerry Limited. All rights reserved. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ #include "qppsobject_p.h" diff --git a/src/corelib/kernel/qppsobject_p.h b/src/corelib/kernel/qppsobject_p.h index c7b99c8e42..abcf00fa05 100644 --- a/src/corelib/kernel/qppsobject_p.h +++ b/src/corelib/kernel/qppsobject_p.h @@ -1,41 +1,41 @@ /**************************************************************************** - ** - ** Copyright (C) 2013 BlackBerry Limited. All rights reserved. - ** Contact: https://www.qt.io/licensing/ - ** - ** This file is part of the QtCore module of the Qt Toolkit. - ** - ** $QT_BEGIN_LICENSE:LGPL$ - ** Commercial License Usage - ** Licensees holding valid commercial Qt licenses may use this file in - ** accordance with the commercial license agreement provided with the - ** Software or, alternatively, in accordance with the terms contained in - ** a written agreement between you and The Qt Company. For licensing terms - ** and conditions see https://www.qt.io/terms-conditions. For further - ** information use the contact form at https://www.qt.io/contact-us. - ** - ** GNU Lesser General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU Lesser - ** General Public License version 3 as published by the Free Software - ** Foundation and appearing in the file LICENSE.LGPL3 included in the - ** packaging of this file. Please review the following information to - ** ensure the GNU Lesser General Public License version 3 requirements - ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. - ** - ** GNU General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU - ** General Public License version 2.0 or (at your option) the GNU General - ** Public license version 3 or any later version approved by the KDE Free - ** Qt Foundation. The licenses are as published by the Free Software - ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 - ** included in the packaging of this file. Please review the following - ** information to ensure the GNU General Public License requirements will - ** be met: https://www.gnu.org/licenses/gpl-2.0.html and - ** https://www.gnu.org/licenses/gpl-3.0.html. - ** - ** $QT_END_LICENSE$ - ** - ****************************************************************************/ +** +** Copyright (C) 2013 BlackBerry Limited. All rights reserved. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ #ifndef QPPSOBJECT_P_H #define QPPSOBJECT_P_H diff --git a/src/corelib/kernel/qppsobjectprivate_p.h b/src/corelib/kernel/qppsobjectprivate_p.h index dae44e3609..d6b4640832 100644 --- a/src/corelib/kernel/qppsobjectprivate_p.h +++ b/src/corelib/kernel/qppsobjectprivate_p.h @@ -1,41 +1,41 @@ /**************************************************************************** - ** - ** Copyright (C) 2013 BlackBerry Limited. All rights reserved. - ** Contact: https://www.qt.io/licensing/ - ** - ** This file is part of the QtCore module of the Qt Toolkit. - ** - ** $QT_BEGIN_LICENSE:LGPL$ - ** Commercial License Usage - ** Licensees holding valid commercial Qt licenses may use this file in - ** accordance with the commercial license agreement provided with the - ** Software or, alternatively, in accordance with the terms contained in - ** a written agreement between you and The Qt Company. For licensing terms - ** and conditions see https://www.qt.io/terms-conditions. For further - ** information use the contact form at https://www.qt.io/contact-us. - ** - ** GNU Lesser General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU Lesser - ** General Public License version 3 as published by the Free Software - ** Foundation and appearing in the file LICENSE.LGPL3 included in the - ** packaging of this file. Please review the following information to - ** ensure the GNU Lesser General Public License version 3 requirements - ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. - ** - ** GNU General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU - ** General Public License version 2.0 or (at your option) the GNU General - ** Public license version 3 or any later version approved by the KDE Free - ** Qt Foundation. The licenses are as published by the Free Software - ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 - ** included in the packaging of this file. Please review the following - ** information to ensure the GNU General Public License requirements will - ** be met: https://www.gnu.org/licenses/gpl-2.0.html and - ** https://www.gnu.org/licenses/gpl-3.0.html. - ** - ** $QT_END_LICENSE$ - ** - ****************************************************************************/ +** +** Copyright (C) 2013 BlackBerry Limited. All rights reserved. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ #ifndef QPPSOBJECTPRIVATE_P_H_ #define QPPSOBJECTPRIVATE_P_H_ diff --git a/src/corelib/kernel/qtestsupport_core.cpp b/src/corelib/kernel/qtestsupport_core.cpp index d69551a227..e00ad75fef 100644 --- a/src/corelib/kernel/qtestsupport_core.cpp +++ b/src/corelib/kernel/qtestsupport_core.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtTest module of the Qt Toolkit. +** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/corelib/kernel/qtestsupport_core.h b/src/corelib/kernel/qtestsupport_core.h index 7fc0054580..c8b664b6d3 100644 --- a/src/corelib/kernel/qtestsupport_core.h +++ b/src/corelib/kernel/qtestsupport_core.h @@ -3,7 +3,7 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtTest module of the Qt Toolkit. +** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/corelib/tools/qstring_mips_dsp_asm.S b/src/corelib/tools/qstring_mips_dsp_asm.S index faf90e14be..202f322310 100644 --- a/src/corelib/tools/qstring_mips_dsp_asm.S +++ b/src/corelib/tools/qstring_mips_dsp_asm.S @@ -3,7 +3,7 @@ ** Copyright (C) 2013 Imagination Technologies Limited, www.imgtec.com ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the QtCore module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage From 07e5edf99123de2d0a8620eb89b14bc2eb99b675 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Wed, 5 Dec 2018 10:48:55 +0100 Subject: [PATCH 0725/1650] Doc: Consistently mark QT_XYZ_CAST_FROM_ASCII with \c Otherwise it gets linkified, which looks inconsistent. Instead, use \sa for functions where QT_NO_CAST_FROM_ASCII or QT_RESTRICTED_CAST_FROM_ASCII is referenced. Change-Id: Ic3933d8c4c81c963215de7f3aac4d0a11e61cbc2 Reviewed-by: Paul Wicking Reviewed-by: Oswald Buddenhagen Reviewed-by: Martin Smith --- src/corelib/tools/qchar.cpp | 2 +- src/corelib/tools/qstring.cpp | 96 ++++++++++++++++++++++++++-- src/corelib/tools/qstringbuilder.cpp | 2 +- 3 files changed, 91 insertions(+), 9 deletions(-) diff --git a/src/corelib/tools/qchar.cpp b/src/corelib/tools/qchar.cpp index 94de69f075..47c853084b 100644 --- a/src/corelib/tools/qchar.cpp +++ b/src/corelib/tools/qchar.cpp @@ -652,7 +652,7 @@ QT_BEGIN_NAMESPACE Constructs a QChar corresponding to ASCII/Latin-1 character \a ch. \note This constructor is not available when \c QT_NO_CAST_FROM_ASCII - or QT_RESTRICTED_CAST_FROM_ASCII is defined. + or \c QT_RESTRICTED_CAST_FROM_ASCII is defined. \sa QT_NO_CAST_FROM_ASCII, QT_RESTRICTED_CAST_FROM_ASCII */ diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index d50a28abc5..63d44eb39c 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -1350,7 +1350,7 @@ const QString::Null QString::null = { }; literals and 8-bit data to unicode QStrings, but allows the use of the \c{QChar(char)} and \c{QString(const char (&ch)[N]} constructors, and the \c{QString::operator=(const char (&ch)[N])} assignment operator - giving most of the type-safety benefits of QT_NO_CAST_FROM_ASCII + giving most of the type-safety benefits of \c QT_NO_CAST_FROM_ASCII but does not require user code to wrap character and string literals with QLatin1Char, QLatin1String or similar. @@ -2005,13 +2005,13 @@ const QString::Null QString::null = { }; can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. - \note Defining QT_RESTRICTED_CAST_FROM_ASCII also disables + \note Defining \c QT_RESTRICTED_CAST_FROM_ASCII also disables this constructor, but enables a \c{QString(const char (&ch)[N])} constructor instead. Using non-literal input, or input with embedded NUL characters, or non-7-bit characters is undefined in this case. - \sa fromLatin1(), fromLocal8Bit(), fromUtf8() + \sa fromLatin1(), fromLocal8Bit(), fromUtf8(), QT_NO_CAST_FROM_ASCII, QT_RESTRICTED_CAST_FROM_ASCII */ /*! \fn QString QString::fromStdString(const std::string &str) @@ -2204,7 +2204,7 @@ QString::QString(QChar ch) can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. - \sa fromLatin1(), fromLocal8Bit(), fromUtf8() + \sa fromLatin1(), fromLocal8Bit(), fromUtf8(), QT_NO_CAST_FROM_ASCII */ /*! \fn QString::QString(const Null &) @@ -2452,6 +2452,8 @@ QString &QString::operator=(QLatin1String other) QT_NO_CAST_FROM_ASCII when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! \fn QString &QString::operator=(const char *str) @@ -2466,6 +2468,7 @@ QString &QString::operator=(QLatin1String other) This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + \sa QT_NO_CAST_FROM_ASCII, QT_RESTRICTED_CAST_FROM_ASCII */ /*! \fn QString &QString::operator=(char ch) @@ -2480,6 +2483,8 @@ QString &QString::operator=(QLatin1String other) QT_NO_CAST_FROM_ASCII when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! @@ -2542,8 +2547,10 @@ QString &QString::operator=(QChar ch) If the given \a position is greater than size(), the array is first extended using resize(). - This function is not available when QT_NO_CAST_FROM_ASCII is + This function is not available when \c QT_NO_CAST_FROM_ASCII is defined. + + \sa QT_NO_CAST_FROM_ASCII */ @@ -2558,8 +2565,10 @@ QString &QString::operator=(QChar ch) If the given \a position is greater than size(), the array is first extended using resize(). - This function is not available when QT_NO_CAST_FROM_ASCII is + This function is not available when \c QT_NO_CAST_FROM_ASCII is defined. + + \sa QT_NO_CAST_FROM_ASCII */ @@ -2724,6 +2733,8 @@ QString &QString::append(QLatin1String str) when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! \fn QString &QString::append(const char *str) @@ -2737,6 +2748,8 @@ QString &QString::append(QLatin1String str) when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! @@ -2799,6 +2812,8 @@ QString &QString::append(QChar ch) QT_NO_CAST_FROM_ASCII when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! \fn QString &QString::prepend(const char *str) @@ -2812,6 +2827,8 @@ QString &QString::append(QChar ch) QT_NO_CAST_FROM_ASCII when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! \fn QString &QString::prepend(QChar ch) @@ -3410,6 +3427,8 @@ bool QString::operator==(QLatin1String other) const Q_DECL_NOTHROW Returns \c true if this string is lexically equal to the parameter string \a other. Otherwise returns \c false. + + \sa QT_NO_CAST_FROM_ASCII */ /*! \fn bool QString::operator==(const char *other) const @@ -3423,6 +3442,8 @@ bool QString::operator==(QLatin1String other) const Q_DECL_NOTHROW QT_NO_CAST_FROM_ASCII when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! @@ -3463,6 +3484,8 @@ bool QString::operator<(QLatin1String other) const Q_DECL_NOTHROW QT_NO_CAST_FROM_ASCII when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! \fn bool QString::operator<(const char *other) const @@ -3479,6 +3502,8 @@ bool QString::operator<(QLatin1String other) const Q_DECL_NOTHROW QT_NO_CAST_FROM_ASCII when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! \fn bool operator<=(const QString &s1, const QString &s2) @@ -3514,6 +3539,8 @@ bool QString::operator<(QLatin1String other) const Q_DECL_NOTHROW QT_NO_CAST_FROM_ASCII when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! \fn bool QString::operator<=(const char *other) const @@ -3527,6 +3554,8 @@ bool QString::operator<(QLatin1String other) const Q_DECL_NOTHROW QT_NO_CAST_FROM_ASCII when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! \fn bool operator>(const QString &s1, const QString &s2) @@ -3564,6 +3593,8 @@ bool QString::operator>(QLatin1String other) const Q_DECL_NOTHROW QT_NO_CAST_FROM_ASCII when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! \fn bool QString::operator>(const char *other) const @@ -3577,6 +3608,8 @@ bool QString::operator>(QLatin1String other) const Q_DECL_NOTHROW when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! \fn bool operator>=(const QString &s1, const QString &s2) @@ -3611,6 +3644,8 @@ bool QString::operator>(QLatin1String other) const Q_DECL_NOTHROW when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! \fn bool QString::operator>=(const char *other) const @@ -3624,6 +3659,8 @@ bool QString::operator>(QLatin1String other) const Q_DECL_NOTHROW when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! \fn bool operator!=(const QString &s1, const QString &s2) @@ -3658,6 +3695,8 @@ bool QString::operator>(QLatin1String other) const Q_DECL_NOTHROW when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! \fn bool QString::operator!=(const char *other) const @@ -3671,6 +3710,8 @@ bool QString::operator>(QLatin1String other) const Q_DECL_NOTHROW QT_NO_CAST_FROM_ASCII when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! @@ -6064,6 +6105,8 @@ QString& QString::fill(QChar ch, int size) QT_NO_CAST_FROM_ASCII when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! \fn QString &QString::operator+=(const char *str) @@ -6077,6 +6120,8 @@ QString& QString::fill(QChar ch, int size) when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! \fn QString &QString::operator+=(const QStringRef &str) @@ -6098,6 +6143,8 @@ QString& QString::fill(QChar ch, int size) when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! \fn QString &QString::operator+=(QChar ch) @@ -9275,7 +9322,7 @@ QString &QString::setRawData(const QChar *unicode, int size) in the first place. In those cases, using QStringLiteral may be the better option. - \sa QString, QLatin1Char, {QStringLiteral()}{QStringLiteral} + \sa QString, QLatin1Char, {QStringLiteral()}{QStringLiteral}, QT_NO_CAST_FROM_ASCII */ /*! @@ -9752,6 +9799,8 @@ QString &QString::setRawData(const QChar *unicode, int size) QT_NO_CAST_FROM_ASCII when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! @@ -9766,6 +9815,8 @@ QString &QString::setRawData(const QChar *unicode, int size) QT_NO_CAST_FROM_ASCII when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! \fn bool QLatin1String::operator!=(const QString &other) const @@ -9791,6 +9842,8 @@ QString &QString::setRawData(const QChar *unicode, int size) QT_NO_CAST_FROM_ASCII when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! @@ -9805,6 +9858,8 @@ QString &QString::setRawData(const QChar *unicode, int size) QT_NO_CAST_FROM_ASCII when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! @@ -9831,6 +9886,8 @@ QString &QString::setRawData(const QChar *unicode, int size) when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! @@ -9845,6 +9902,8 @@ QString &QString::setRawData(const QChar *unicode, int size) when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! @@ -9871,6 +9930,8 @@ QString &QString::setRawData(const QChar *unicode, int size) QT_NO_CAST_FROM_ASCII when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! @@ -9885,6 +9946,8 @@ QString &QString::setRawData(const QChar *unicode, int size) QT_NO_CAST_FROM_ASCII when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! @@ -9911,6 +9974,8 @@ QString &QString::setRawData(const QChar *unicode, int size) QT_NO_CAST_FROM_ASCII when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! @@ -9925,6 +9990,8 @@ QString &QString::setRawData(const QChar *unicode, int size) QT_NO_CAST_FROM_ASCII when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! \fn bool QLatin1String::operator<=(const QString &other) const @@ -9950,6 +10017,8 @@ QString &QString::setRawData(const QChar *unicode, int size) QT_NO_CAST_FROM_ASCII when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ /*! @@ -9964,6 +10033,8 @@ QString &QString::setRawData(const QChar *unicode, int size) QT_NO_CAST_FROM_ASCII when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + + \sa QT_NO_CAST_FROM_ASCII */ @@ -10592,6 +10663,7 @@ bool operator<(const QStringRef &s1,const QStringRef &s2) Q_DECL_NOTHROW Returns \c true if this string is lexically equal to the parameter string \a s. Otherwise returns \c false. + \sa QT_NO_CAST_FROM_ASCII */ /*! @@ -10609,6 +10681,8 @@ bool operator<(const QStringRef &s1,const QStringRef &s2) Q_DECL_NOTHROW Returns \c true if this string is not lexically equal to the parameter string \a s. Otherwise returns \c false. + + \sa QT_NO_CAST_FROM_ASCII */ /*! @@ -10626,6 +10700,8 @@ bool operator<(const QStringRef &s1,const QStringRef &s2) Q_DECL_NOTHROW Returns \c true if this string is lexically smaller than the parameter string \a s. Otherwise returns \c false. + + \sa QT_NO_CAST_FROM_ASCII */ /*! @@ -10643,6 +10719,8 @@ bool operator<(const QStringRef &s1,const QStringRef &s2) Q_DECL_NOTHROW Returns \c true if this string is lexically smaller than or equal to the parameter string \a s. Otherwise returns \c false. + + \sa QT_NO_CAST_FROM_ASCII */ /*! @@ -10661,6 +10739,8 @@ bool operator<(const QStringRef &s1,const QStringRef &s2) Q_DECL_NOTHROW Returns \c true if this string is lexically greater than the parameter string \a s. Otherwise returns \c false. + + \sa QT_NO_CAST_FROM_ASCII */ /*! @@ -10678,6 +10758,8 @@ bool operator<(const QStringRef &s1,const QStringRef &s2) Q_DECL_NOTHROW Returns \c true if this string is lexically greater than or equal to the parameter string \a s. Otherwise returns \c false. + + \sa QT_NO_CAST_FROM_ASCII */ /*! \typedef QString::Data diff --git a/src/corelib/tools/qstringbuilder.cpp b/src/corelib/tools/qstringbuilder.cpp index 081d7136a7..8afc83819b 100644 --- a/src/corelib/tools/qstringbuilder.cpp +++ b/src/corelib/tools/qstringbuilder.cpp @@ -80,7 +80,7 @@ QT_BEGIN_NAMESPACE \endlist The types in the last list point are only available when - QT_NO_CAST_FROM_ASCII is not defined. + \c QT_NO_CAST_FROM_ASCII is not defined. For building QByteArrays: From b978cdcb268cbeb233c5e06fa4bb193cd34348aa Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Tue, 11 Dec 2018 14:17:05 +0100 Subject: [PATCH 0726/1650] Make sure -prefix documentation is also valid for top-level build Fixes: QTBUG-71540 Change-Id: I1c8c66706beaa130f9eb7a6f2ee02a21f98d8afc Reviewed-by: Oswald Buddenhagen --- config_help.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config_help.txt b/config_help.txt index 5369163055..7b5da3fbeb 100644 --- a/config_help.txt +++ b/config_help.txt @@ -17,7 +17,8 @@ quoting and double quotes for the outer quoting. Top-level installation directories: -prefix ...... The deployment directory, as seen on the target device. - [/usr/local/Qt-$QT_VERSION, $PWD if -developer-build] + [/usr/local/Qt-$QT_VERSION; qtbase build directory if + -developer-build] -extprefix ... The installation directory, as seen on the host machine. [SYSROOT/PREFIX] -hostprefix [dir] .. The installation directory for build tools running on From 8915c9715a183e30f725d7cf4a5571f12c74650e Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 3 Dec 2018 11:08:28 +0100 Subject: [PATCH 0727/1650] Doc: Remove pre-Windows 7 from QCollator documentation The code path that this refers to was removed already for Qt 5.11 in commit 53fb2c48ef472ee74a2. Change-Id: I4a7ae1b89b24c0ab7ceaa43f763c7ef422ca4900 Reviewed-by: Friedemann Kleint --- src/corelib/tools/qcollator.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/corelib/tools/qcollator.cpp b/src/corelib/tools/qcollator.cpp index 4315d35a52..76dcf35833 100644 --- a/src/corelib/tools/qcollator.cpp +++ b/src/corelib/tools/qcollator.cpp @@ -222,11 +222,6 @@ Qt::CaseSensitivity QCollator::caseSensitivity() const By default this mode is off. - \note On Windows, this functionality makes use of the \l{ICU} library. If Qt was - compiled without ICU support, it falls back to code using native Windows API, - which only works from Windows 7 onwards. On older versions of Windows, it will not work - and a warning will be emitted at runtime. - \sa numericMode() */ void QCollator::setNumericMode(bool on) From 69f7115c43ef17c2d8ff3f7842e64b539da94dcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 18 Dec 2018 13:17:45 +0100 Subject: [PATCH 0728/1650] macOS: Merge qt_mac_createRoleFonts into only caller MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Id6e61a70e4ebe47896dcbc8680d1d6b06c747871 Reviewed-by: Timur Pocheptsov Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoatheme.mm | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm index 240deeddbd..c46df25b66 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.mm +++ b/src/plugins/platforms/cocoa/qcocoatheme.mm @@ -228,16 +228,12 @@ const QPalette *QCocoaTheme::palette(Palette type) const return nullptr; } -QHash qt_mac_createRoleFonts() -{ - QCoreTextFontDatabase *ctfd = static_cast(QGuiApplicationPrivate::platformIntegration()->fontDatabase()); - return ctfd->themeFonts(); -} - const QFont *QCocoaTheme::font(Font type) const { if (m_fonts.isEmpty()) { - m_fonts = qt_mac_createRoleFonts(); + const auto *platformIntegration = QGuiApplicationPrivate::platformIntegration(); + const auto *coreTextFontDb = static_cast(platformIntegration->fontDatabase()); + m_fonts = coreTextFontDb->themeFonts(); } return m_fonts.value(type, nullptr); } From 6881699d7605c29f61d6809c9fa9eb04807bef9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Mon, 10 Dec 2018 15:00:58 +0100 Subject: [PATCH 0729/1650] Fix layering violation in isForeignWindow() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QPlatformWindow::isForeignWindow() should return whether the native window is of the foreign window type, or false if the platform (plugin) does not support this concept. It should not call QWindow::type(), since that function may itself be implemented in terms of isForeignWindow(). Change-Id: Ib67a5a44c5c1db0acb4d3bc155e187f8164146d1 Reviewed-by: Tor Arne Vestbø Reviewed-by: Timur Pocheptsov --- src/gui/kernel/qplatformwindow.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h index 1590a10554..075ac0f82b 100644 --- a/src/gui/kernel/qplatformwindow.h +++ b/src/gui/kernel/qplatformwindow.h @@ -108,7 +108,7 @@ public: virtual bool isActive() const; virtual bool isAncestorOf(const QPlatformWindow *child) const; virtual bool isEmbedded() const; - virtual bool isForeignWindow() const { return window()->type() == Qt::ForeignWindow; }; + virtual bool isForeignWindow() const { return false; }; virtual QPoint mapToGlobal(const QPoint &pos) const; virtual QPoint mapFromGlobal(const QPoint &pos) const; From f4b77570e21c2d29ccdb923af73867b5055a6e89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 24 Oct 2018 14:46:32 +0200 Subject: [PATCH 0730/1650] Make QWindow::type() reflect ForeignWindow status MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Qt::ForeignWindow flag is or’ed to d->windowFlags by QWindow::flags(). Use this getter function instead of accessing d->windowFlags() directly. Change-Id: I6a82aa7e379ba51272954ffe7b87f108034da8c6 Reviewed-by: Tor Arne Vestbø --- src/gui/kernel/qwindow.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index bc2d6e6a17..0f5873543b 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -919,8 +919,7 @@ void QWindow::setFlag(Qt::WindowType flag, bool on) */ Qt::WindowType QWindow::type() const { - Q_D(const QWindow); - return static_cast(int(d->windowFlags & Qt::WindowType_Mask)); + return static_cast(int(flags() & Qt::WindowType_Mask)); } /*! From fb67ac6368aeb9547cc78551708e4ed0d9e4bbfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 12 Dec 2018 13:52:52 +0100 Subject: [PATCH 0731/1650] Modernize QNSImageView implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use Objc properties instead of instance variables. Change-Id: I4bddf2c9c824467d7c42dd5bb0c3b4aacd6b27be Reviewed-by: Tor Arne Vestbø --- .../platforms/cocoa/qcocoasystemtrayicon.mm | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm index 0158895441..3a7ac60424 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm +++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm @@ -105,6 +105,8 @@ QT_USE_NAMESPACE @end @interface QT_MANGLE_NAMESPACE(QNSImageView) : NSImageView +@property (nonatomic, assign) BOOL down; +@property (nonatomic, assign) QT_MANGLE_NAMESPACE(QNSStatusItem) *parent; @end QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSStatusItem); @@ -277,36 +279,32 @@ QT_END_NAMESPACE @implementation NSStatusItem (Qt) @end -@implementation QNSImageView { - BOOL down; - QT_MANGLE_NAMESPACE(QNSStatusItem) *parent; -} - +@implementation QNSImageView - (instancetype)initWithParent:(QNSStatusItem *)myParent { self = [super init]; - parent = myParent; - down = NO; + self.parent = myParent; + self.down = NO; return self; } - (void)menuTrackingDone:(NSNotification *)__unused notification { - down = NO; + self.down = NO; [self setNeedsDisplay:YES]; } - (void)mousePressed:(NSEvent *)mouseEvent { - down = YES; + self.down = YES; int clickCount = [mouseEvent clickCount]; [self setNeedsDisplay:YES]; if (clickCount == 2) { [self menuTrackingDone:nil]; - [parent doubleClickSelector:self]; + [self.parent doubleClickSelector:self]; } else { - [parent triggerSelector:self button:cocoaButton2QtButton(mouseEvent)]; + [self.parent triggerSelector:self button:cocoaButton2QtButton(mouseEvent)]; } } @@ -344,7 +342,7 @@ QT_END_NAMESPACE } - (void)drawRect:(NSRect)rect { - [[parent item] drawStatusBarBackgroundInRect:rect withHighlight:down]; + [[self.parent item] drawStatusBarBackgroundInRect:rect withHighlight:self.down]; [super drawRect:rect]; } @end From f0dd6655e1df27dbb10bc43e0787d9328800c93a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 12 Dec 2018 14:59:48 +0100 Subject: [PATCH 0732/1650] Fix QSystemTrayIcon stale pointer access MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The child imageCell is a NSView and may be retained by Cocoa, which means it may outlive the parent QNSStatusItem. Clear its parent pointer to avoid referencing a stale pointer. Task-number: QTBUG-47929 Change-Id: I6078070b8c9f512ecd034fee4e54b1d8282dabdf Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm index 3a7ac60424..4982f5ee05 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm +++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm @@ -372,6 +372,7 @@ QT_END_NAMESPACE - (void)dealloc { [[NSStatusBar systemStatusBar] removeStatusItem:item]; [[NSNotificationCenter defaultCenter] removeObserver:imageCell]; + imageCell.parent = nil; [imageCell release]; [item release]; [super dealloc]; From 37b30983023a2e1fd5d7250ee2d15d8574a5cc2d Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Sat, 22 Dec 2018 18:55:37 +0100 Subject: [PATCH 0733/1650] Revert "Revert "configure: remove xkbcommon_evdev transition hack"" This reverts commit 9ee6eed572df76b60248153cf16febd6156ad006. Now the qt5 dev baseline have both old and new one. We can remove the old one. Change-Id: I9f9495f2ae82f1e23d800b66384301ca0fa8a646 Reviewed-by: Gatis Paeglis Reviewed-by: Allan Sandfeld Jensen --- src/gui/configure.json | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/gui/configure.json b/src/gui/configure.json index e0d643b844..7585e9c8d4 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -635,16 +635,6 @@ { "type": "pkgConfig", "args": "xkbcommon-x11" } ] }, - "xkbcommon_evdev": { - "label": "xkbcommon_evdev TRANSITION HACK", - "test": { - "include": [ "xkbcommon/xkbcommon.h" ], - "main": "xkb_context_new(XKB_CONTEXT_NO_FLAGS);" - }, - "sources": [ - { "type": "pkgConfig", "args": "xkbcommon >= 0.5.0" } - ] - }, "xrender": { "label": "XRender for native painting", "test": "x11/xrender", @@ -1389,11 +1379,6 @@ "condition": "libs.xkbcommon", "output": [ "privateFeature" ] }, - "xkbcommon-evdev": { - "label": "xkbcommon-evdev TRANSITION HACK", - "condition": "libs.xkbcommon_evdev", - "output": [ "privateFeature" ] - }, "xlib": { "label": "XLib", "autoDetect": "!config.darwin || features.xcb", From f03941e4113e2c8c0a594592be44efc92614ec9d Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 21 Dec 2018 14:34:28 +0100 Subject: [PATCH 0734/1650] Add overload of QSqlDatabase::cloneDatabase to allow cloning cross threads Since QSqlDatabase::database() cannot be used to access another database from another thread, then the overload is provided to make it possible to clone with just the connection name. This will handle the cloning internally safely then. Fixes: QTBUG-72545 Change-Id: I861cc5aa2c38c1e3797f6f086594a1228f05bada Reviewed-by: Simon Hausmann --- src/sql/kernel/qsqldatabase.cpp | 34 +++++++++++++++++++ src/sql/kernel/qsqldatabase.h | 1 + .../kernel/qsqldatabase/tst_qsqldatabase.cpp | 10 ++++++ 3 files changed, 45 insertions(+) diff --git a/src/sql/kernel/qsqldatabase.cpp b/src/sql/kernel/qsqldatabase.cpp index 2c7b4b83db..12ab9671b5 100644 --- a/src/sql/kernel/qsqldatabase.cpp +++ b/src/sql/kernel/qsqldatabase.cpp @@ -1379,6 +1379,40 @@ QSqlDatabase QSqlDatabase::cloneDatabase(const QSqlDatabase &other, const QStrin return db; } +/*! + \since 5.13 + \overload + + Clones the database connection \a other and stores it as \a + connectionName. All the settings from the original database, e.g. + databaseName(), hostName(), etc., are copied across. Does nothing + if \a other is an invalid database. Returns the newly created + database connection. + + \note The new connection has not been opened. Before using the new + connection, you must call open(). + + This overload is useful when cloning the database in another thread to the + one that is used by the database represented by \a other. +*/ + +QSqlDatabase QSqlDatabase::cloneDatabase(const QString &other, const QString &connectionName) +{ + const QConnectionDict *dict = dbDict(); + Q_ASSERT(dict); + + dict->lock.lockForRead(); + QSqlDatabase otherDb = dict->value(other); + dict->lock.unlock(); + if (!otherDb.isValid()) + return QSqlDatabase(); + + QSqlDatabase db(otherDb.driverName()); + db.d->copy(otherDb.d); + QSqlDatabasePrivate::addDatabase(db, connectionName); + return db; +} + /*! \since 4.4 diff --git a/src/sql/kernel/qsqldatabase.h b/src/sql/kernel/qsqldatabase.h index 3aadab9b2f..f233c72c19 100644 --- a/src/sql/kernel/qsqldatabase.h +++ b/src/sql/kernel/qsqldatabase.h @@ -118,6 +118,7 @@ public: static QSqlDatabase addDatabase(QSqlDriver* driver, const QString& connectionName = QLatin1String(defaultConnection)); static QSqlDatabase cloneDatabase(const QSqlDatabase &other, const QString& connectionName); + static QSqlDatabase cloneDatabase(const QString &other, const QString& connectionName); static QSqlDatabase database(const QString& connectionName = QLatin1String(defaultConnection), bool open = true); static void removeDatabase(const QString& connectionName); diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp index bdfa957083..afc3fb1ec9 100644 --- a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp @@ -2422,6 +2422,16 @@ public slots: QSqlDatabase invalidDb = QSqlDatabase::database("invalid"); QVERIFY(!invalidDb.isValid()); + + { + QSqlDatabase clonedDatabase = QSqlDatabase::cloneDatabase(dbName, "CloneDB"); + QVERIFY(!clonedDatabase.isOpen()); + QVERIFY(clonedDatabase.isValid()); + QVERIFY(clonedDatabase.open()); + QVERIFY(clonedDatabase.isOpen()); + clonedDatabase.close(); + } + QThread::currentThread()->exit(); } private: From 5af60d3b371360285af442d1ee194b44d681f297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 10 Dec 2018 23:37:54 +0100 Subject: [PATCH 0735/1650] macOS: Prevent checking for stale SDK without the required SDK name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There's no need to check the SDK at the root exclusive-build Makefile, we can leave it to the individual build passes where the SDK variable is available. Fixes: QTBUG-72449 Change-Id: Ic829babf4c76e6d20812de0b94120199ebfb300c Reviewed-by: Morten Johan Sørvig Reviewed-by: Tor Arne Vestbø --- mkspecs/features/mac/default_post.prf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/mac/default_post.prf b/mkspecs/features/mac/default_post.prf index 3881b432ef..8e2c5e603a 100644 --- a/mkspecs/features/mac/default_post.prf +++ b/mkspecs/features/mac/default_post.prf @@ -1,7 +1,7 @@ load(default_post) contains(TEMPLATE, .*app) { - !macx-xcode { + !macx-xcode:if(isEmpty(BUILDS)|build_pass) { # Detect changes to the platform SDK QMAKE_EXTRA_VARIABLES += QMAKE_MAC_SDK QMAKE_MAC_SDK_VERSION QMAKE_XCODE_DEVELOPER_PATH QMAKE_EXTRA_INCLUDES += $$shell_quote($$PWD/sdk.mk) From 3306b162392cb4afe268e8dfecd3a0e7ba7eaca6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 18 Dec 2018 22:20:57 +0100 Subject: [PATCH 0736/1650] macOS: Only do gamma-corrected blending for subpixel-antialiased text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The grayscale font-smoothing doesn't expect to be linearly blended, as first assumed. Amended nativetext manual test to better diagnose the native Core Text behavior. Non-linear blending will result in the magenta text having a dark outline against the green background. Change-Id: I24a5f04eb1bd66fb98d621078d80ee9b80800827 Reviewed-by: Simon Hausmann Reviewed-by: Tor Arne Vestbø --- src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm | 2 +- tests/manual/textrendering/nativetext/main.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index 19b450b643..7957cd130a 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -736,7 +736,7 @@ bool QCoreTextFontEngine::shouldSmoothFont() const bool QCoreTextFontEngine::expectsGammaCorrectedBlending() const { - return shouldSmoothFont(); + return shouldSmoothFont() && fontSmoothing() == Subpixel; } qreal QCoreTextFontEngine::fontSmoothingGamma() diff --git a/tests/manual/textrendering/nativetext/main.cpp b/tests/manual/textrendering/nativetext/main.cpp index 7e98dd44d0..b481e44bae 100644 --- a/tests/manual/textrendering/nativetext/main.cpp +++ b/tests/manual/textrendering/nativetext/main.cpp @@ -101,7 +101,7 @@ public: const int ascent = fontMetrics().ascent(); - QPen metricsPen(Qt::magenta, 1.0); + QPen metricsPen(QColor(112, 216, 255), 1.0); metricsPen.setCosmetic(true); p.setPen(metricsPen); p.drawLine(QPoint(0, ascent), QPoint(width(), ascent)); @@ -201,7 +201,7 @@ public: case 0: return qMakePair(QColor(), QColor()); case 1: return qMakePair(QColor(Qt::black), QColor(Qt::white)); case 2: return qMakePair(QColor(Qt::white), QColor(Qt::black)); - case 3: return qMakePair(QColor(Qt::green), QColor(Qt::red)); + case 3: return qMakePair(QColor(Qt::magenta), QColor(Qt::green)); case 4: return qMakePair(QColor(0, 0, 0, 128), QColor(Qt::white)); case 5: return qMakePair(QColor(255, 255, 255, 128), QColor(Qt::black)); default: return qMakePair(QColor(), QColor()); From 0c95c11e6553f9ec7e295db80bb603b1ce8ff534 Mon Sep 17 00:00:00 2001 From: Paul Wicking Date: Wed, 12 Dec 2018 08:16:46 +0100 Subject: [PATCH 0737/1650] Doc: Add missing \since to QLineEdit's inputRejected signal The signal was introduced in 5.12.0, according to qtbase/dist/changes-5.12.0 (which refers to QTBUG-57448). Also confirmed in qtdoc/doc/src/whatsnew/whatsnew512.qdoc. Added in commit c901cdadc0a. Fixes: QTBUG-72386 Change-Id: I291dfefe40eea0e9208bda6eed6dd96e41ba6d2b Reviewed-by: Martin Smith Reviewed-by: Andy Shaw --- src/widgets/widgets/qlineedit.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp index 2ae2e16c89..4301a3a2e7 100644 --- a/src/widgets/widgets/qlineedit.cpp +++ b/src/widgets/widgets/qlineedit.cpp @@ -1681,6 +1681,7 @@ void QLineEdit::mouseDoubleClickEvent(QMouseEvent* e) /*! \fn void QLineEdit::inputRejected() + \since 5.12 This signal is emitted when the user presses a key that is not considered to be acceptable input. For example, if a key press From ff835a5030f3ec0aaa91ad0332739ca3259804e8 Mon Sep 17 00:00:00 2001 From: Luca Beldi Date: Thu, 6 Dec 2018 08:48:35 +0000 Subject: [PATCH 0738/1650] Fix QStringListModel::setData to check for actual changes QStringListModel::setData documentation states that "The dataChanged() signal is emitted if the item is changed." This patch actually respects the doc. setData will check that the data actually changed before sending the dataChanged signal. [ChangeLog][QtCore][QStringListModel] setData will now emit the dataChanged() signal only if the string set is different from the one already contained in the model Change-Id: I4308a6f3b4851203fb899c5e29a36076e0c32f2f Reviewed-by: David Faure --- src/corelib/itemmodels/qstringlistmodel.cpp | 5 ++++- .../qstringlistmodel/tst_qstringlistmodel.cpp | 20 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/corelib/itemmodels/qstringlistmodel.cpp b/src/corelib/itemmodels/qstringlistmodel.cpp index 0adaba9b9a..f92a0d6676 100644 --- a/src/corelib/itemmodels/qstringlistmodel.cpp +++ b/src/corelib/itemmodels/qstringlistmodel.cpp @@ -184,7 +184,10 @@ bool QStringListModel::setData(const QModelIndex &index, const QVariant &value, { if (index.row() >= 0 && index.row() < lst.size() && (role == Qt::EditRole || role == Qt::DisplayRole)) { - lst.replace(index.row(), value.toString()); + const QString valueString = value.toString(); + if (lst.at(index.row()) == valueString) + return true; + lst.replace(index.row(), valueString); QVector roles; roles.reserve(2); roles.append(Qt::DisplayRole); diff --git a/tests/auto/corelib/itemmodels/qstringlistmodel/tst_qstringlistmodel.cpp b/tests/auto/corelib/itemmodels/qstringlistmodel/tst_qstringlistmodel.cpp index 9a54c0a70d..1b40e77648 100644 --- a/tests/auto/corelib/itemmodels/qstringlistmodel/tst_qstringlistmodel.cpp +++ b/tests/auto/corelib/itemmodels/qstringlistmodel/tst_qstringlistmodel.cpp @@ -81,6 +81,8 @@ private slots: void setData_emits_both_roles_data(); void setData_emits_both_roles(); + void setData_emits_on_change_only(); + void supportedDragDropActions(); }; @@ -246,6 +248,24 @@ void tst_QStringListModel::setData_emits_both_roles() expected); } +void tst_QStringListModel::setData_emits_on_change_only() +{ + QStringListModel model(QStringList{QStringLiteral("one"), QStringLiteral("two")}); + QSignalSpy dataChangedSpy(&model, &QAbstractItemModel::dataChanged); + QVERIFY(dataChangedSpy.isValid()); + const QModelIndex modelIdx = model.index(0, 0); + const QString newStringData = QStringLiteral("test"); + QVERIFY(model.setData(modelIdx, newStringData)); + QCOMPARE(dataChangedSpy.count(), 1); + const QList spyList = dataChangedSpy.takeFirst(); + QCOMPARE(spyList.at(0).value(), modelIdx); + QCOMPARE(spyList.at(1).value(), modelIdx); + const QVector expectedRoles{Qt::DisplayRole, Qt::EditRole}; + QCOMPARE(spyList.at(2).value >(), expectedRoles); + QVERIFY(model.setData(modelIdx, newStringData)); + QVERIFY(dataChangedSpy.isEmpty()); +} + void tst_QStringListModel::supportedDragDropActions() { QStringListModel model; From aece0a13569737bbcced0e73c0e0b12863e2cf1f Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sun, 16 Dec 2018 14:46:49 +0100 Subject: [PATCH 0739/1650] QColor: mark light()/dark() as deprecated MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QColor::light()/dark() are deprecated since Qt4 times. Therefore annotate them with Q_DEPRECATED so they can be removed in Qt6. Change-Id: Ifbfc59d6a070670a43c9b60a23f83cc4ba59bf07 Reviewed-by: André Hartmann Reviewed-by: Eirik Aavitsland --- src/gui/painting/qcolor.cpp | 48 +++++++++++++++++++++++-------------- src/gui/painting/qcolor.h | 12 ++++------ 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index a504e35c37..b3fa1eedde 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -2695,18 +2695,13 @@ QColor QColor::fromCmykF(qreal c, qreal m, qreal y, qreal k, qreal a) recommend using the darker() function for this purpose. If the \a factor is 0 or negative, the return value is unspecified. - The function converts the current RGB color to HSV, multiplies the value - (V) component by \a factor and converts the color back to RGB. + The function converts the current color to HSV, multiplies the value + (V) component by \a factor and converts the color back to it's original + color spec. \sa darker(), isValid() */ - -/*! - \obsolete - - Use lighter(\a factor) instead. -*/ -QColor QColor::light(int factor) const Q_DECL_NOTHROW +QColor QColor::lighter(int factor) const Q_DECL_NOTHROW { if (factor <= 0) // invalid lightness factor return *this; @@ -2745,18 +2740,13 @@ QColor QColor::light(int factor) const Q_DECL_NOTHROW but we recommend using the lighter() function for this purpose. If the \a factor is 0 or negative, the return value is unspecified. - The function converts the current RGB color to HSV, divides the value (V) - component by \a factor and converts the color back to RGB. + The function converts the current color to HSV, divides the value (V) + component by \a factor and converts the color back to it's original + color spec. \sa lighter(), isValid() */ - -/*! - \obsolete - - Use darker(\a factor) instead. -*/ -QColor QColor::dark(int factor) const Q_DECL_NOTHROW +QColor QColor::darker(int factor) const Q_DECL_NOTHROW { if (factor <= 0) // invalid darkness factor return *this; @@ -2770,6 +2760,28 @@ QColor QColor::dark(int factor) const Q_DECL_NOTHROW return hsv.convertTo(cspec); } +#if QT_DEPRECATED_SINCE(5, 13) +/*! + \obsolete + + Use lighter(\a factor) instead. +*/ +QColor QColor::light(int factor) const Q_DECL_NOTHROW +{ + return lighter(factor); +} + +/*! + \obsolete + + Use darker(\a factor) instead. +*/ +QColor QColor::dark(int factor) const Q_DECL_NOTHROW +{ + return darker(factor); +} +#endif + #if QT_VERSION < QT_VERSION_CHECK(6,0,0) /*! Assigns a copy of \a color to this color, and returns a reference to it. diff --git a/src/gui/painting/qcolor.h b/src/gui/painting/qcolor.h index a9b05ae7e3..4822612cf8 100644 --- a/src/gui/painting/qcolor.h +++ b/src/gui/painting/qcolor.h @@ -219,9 +219,13 @@ public: static QColor fromHsl(int h, int s, int l, int a = 255); static QColor fromHslF(qreal h, qreal s, qreal l, qreal a = 1.0); +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X("Use QColor::lighter() instead") Q_REQUIRED_RESULT QColor light(int f = 150) const Q_DECL_NOTHROW; - Q_REQUIRED_RESULT QColor lighter(int f = 150) const Q_DECL_NOTHROW; + QT_DEPRECATED_X("Use QColor::darker() instead") Q_REQUIRED_RESULT QColor dark(int f = 200) const Q_DECL_NOTHROW; +#endif + Q_REQUIRED_RESULT QColor lighter(int f = 150) const Q_DECL_NOTHROW; Q_REQUIRED_RESULT QColor darker(int f = 200) const Q_DECL_NOTHROW; bool operator==(const QColor &c) const Q_DECL_NOTHROW; @@ -308,12 +312,6 @@ inline QColor::QColor(const QColor &acolor) Q_DECL_NOTHROW inline bool QColor::isValid() const Q_DECL_NOTHROW { return cspec != Invalid; } -inline QColor QColor::lighter(int f) const Q_DECL_NOTHROW -{ return light(f); } - -inline QColor QColor::darker(int f) const Q_DECL_NOTHROW -{ return dark(f); } - QT_END_NAMESPACE #endif // QCOLOR_H From 844044f37b84b1700d356e2fe27b5c6a445f88ea Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Wed, 19 Dec 2018 21:25:31 +0100 Subject: [PATCH 0740/1650] QTabWidget: properly horizontally align tab icon When an icon used for a QTabWidget is smaller than the default size, it was not properly aligned horizontally although it was done for the vertical alignment. Therefore also align it horizontally to be consistent. Fixes: QTBUG-38108 Change-Id: I0e2e3af7ead699f2834aed1d8b67cbe775c897af Reviewed-by: Friedemann Kleint Reviewed-by: Richard Moe Gustavsen --- src/widgets/styles/qcommonstyle.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 01c69f1152..b146cb1183 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -1186,8 +1186,9 @@ void QCommonStylePrivate::tabLayout(const QStyleOptionTab *opt, const QWidget *w // High-dpi icons do not need adjustment; make sure tabIconSize is not larger than iconSize tabIconSize = QSize(qMin(tabIconSize.width(), iconSize.width()), qMin(tabIconSize.height(), iconSize.height())); - *iconRect = QRect(tr.left(), tr.center().y() - tabIconSize.height() / 2, - tabIconSize.width(), tabIconSize.height()); + const int offsetX = (iconSize.width() - tabIconSize.width()) / 2; + *iconRect = QRect(tr.left() + offsetX, tr.center().y() - tabIconSize.height() / 2, + tabIconSize.width(), tabIconSize.height()); if (!verticalTabs) *iconRect = proxyStyle->visualRect(opt->direction, opt->rect, *iconRect); tr.setLeft(tr.left() + tabIconSize.width() + 4); From c8720d62102f4e53f12117835735259d20e99433 Mon Sep 17 00:00:00 2001 From: Jeremy Whiting Date: Tue, 18 Dec 2018 21:15:15 -0700 Subject: [PATCH 0741/1650] Fix typo in fetchmore example documentation In fetchmore example documentation there's a typo on the first line. The text should read 'shows how to' but instead reads 'shows how two' Change-Id: Ifc169581e8fc43315dc01c7d1f267dd45600af82 Reviewed-by: Frederik Gladhorn --- examples/widgets/doc/src/fetchmore.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/widgets/doc/src/fetchmore.qdoc b/examples/widgets/doc/src/fetchmore.qdoc index df0cf3b8ec..a27efaf071 100644 --- a/examples/widgets/doc/src/fetchmore.qdoc +++ b/examples/widgets/doc/src/fetchmore.qdoc @@ -29,7 +29,7 @@ \example itemviews/fetchmore \title Fetch More Example \ingroup examples-itemviews - \brief The Fetch More example shows how two add items to an item view + \brief The Fetch More example shows how to add items to an item view model on demand. \image fetchmore-example.png From f05cc4144e06fd06eed12a3e427eb49e7ad1cf85 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Tue, 18 Dec 2018 16:49:20 +0300 Subject: [PATCH 0742/1650] QDialog: Pass transient parent as a parent to native dialogs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sometimes it's needed to show a native dialog for another process, for example in xdg-desktop-portal-kde. In this case we have WId of a parent window which can be used for calling QWindow::setTransientParent(QWindow::fromWinId(...)). Pass this transient parent to a native dialog so it could use it as a transient parent for itself. Rename QDialogPrivate::parentWindow() for clarity. Change-Id: I68974ddea35f9366a0ddffe602d9d028f45e26fa Reviewed-by: Tor Arne Vestbø --- src/widgets/dialogs/qdialog.cpp | 9 ++++++--- src/widgets/dialogs/qdialog_p.h | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp index 06f0393b4c..6f96018f3e 100644 --- a/src/widgets/dialogs/qdialog.cpp +++ b/src/widgets/dialogs/qdialog.cpp @@ -145,10 +145,13 @@ bool QDialogPrivate::canBeNativeDialog() const return false; } -QWindow *QDialogPrivate::parentWindow() const +QWindow *QDialogPrivate::transientParentWindow() const { - if (const QWidget *parent = q_func()->nativeParentWidget()) + Q_Q(const QDialog); + if (const QWidget *parent = q->nativeParentWidget()) return parent->windowHandle(); + else if (q->windowHandle()) + return q->windowHandle()->transientParent(); return 0; } @@ -158,7 +161,7 @@ bool QDialogPrivate::setNativeDialogVisible(bool visible) if (visible) { Q_Q(QDialog); helperPrepareShow(helper); - nativeDialogInUse = helper->show(q->windowFlags(), q->windowModality(), parentWindow()); + nativeDialogInUse = helper->show(q->windowFlags(), q->windowModality(), transientParentWindow()); } else if (nativeDialogInUse) { helper->hide(); } diff --git a/src/widgets/dialogs/qdialog_p.h b/src/widgets/dialogs/qdialog_p.h index 99fff08e65..b1de56188c 100644 --- a/src/widgets/dialogs/qdialog_p.h +++ b/src/widgets/dialogs/qdialog_p.h @@ -87,7 +87,7 @@ public: {} ~QDialogPrivate(); - QWindow *parentWindow() const; + QWindow *transientParentWindow() const; bool setNativeDialogVisible(bool visible); QVariant styleHint(QPlatformDialogHelper::StyleHint hint) const; void deletePlatformHelper(); From f568bfce641f52b4641b5d8281c99742f1ae6f40 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sun, 23 Dec 2018 17:59:18 +0100 Subject: [PATCH 0743/1650] QTreeView: fix keyboard navigation when first or last item is disabled The keyboard navigation did not consider the disabled state when trying to find the new index under all circumstances. This lead to a non-working PageUp/Down/Home/End navigation when the first or last item was disabled or hidden. Fix it by explicitly checking if the calculated item is hidden/enabled and skip it in this case. Fixes: QTBUG-44746 Fixes: QTBUG-34832 Change-Id: Ifa3b64a405e67b792db5db9d186d426fcfe183fb Reviewed-by: David Faure --- src/widgets/itemviews/qtreeview.cpp | 30 +++++++++++++++++-- src/widgets/itemviews/qtreeview_p.h | 2 ++ .../itemviews/qtreeview/tst_qtreeview.cpp | 24 +++++++++++++++ .../itemviews/qtreewidget/tst_qtreewidget.cpp | 28 +++++++++++++++++ 4 files changed, 81 insertions(+), 3 deletions(-) diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index f37da86539..3fad6ca3df 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -2301,9 +2301,9 @@ QModelIndex QTreeView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie case MovePageDown: return d->modelIndex(d->pageDown(vi), current.column()); case MoveHome: - return d->model->index(0, current.column(), d->root); + return d->modelIndex(d->itemForKeyHome(), current.column()); case MoveEnd: - return d->modelIndex(d->viewItems.count() - 1, current.column()); + return d->modelIndex(d->itemForKeyEnd(), current.column()); } return current; } @@ -3422,7 +3422,11 @@ int QTreeViewPrivate::pageUp(int i) const int index = itemAtCoordinate(coordinateForItem(i) - viewport->height()); while (isItemHiddenOrDisabled(index)) index--; - return index == -1 ? 0 : index; + if (index == -1) + index = 0; + while (isItemHiddenOrDisabled(index)) + index++; + return index >= viewItems.count() ? 0 : index; } int QTreeViewPrivate::pageDown(int i) const @@ -3430,6 +3434,26 @@ int QTreeViewPrivate::pageDown(int i) const int index = itemAtCoordinate(coordinateForItem(i) + viewport->height()); while (isItemHiddenOrDisabled(index)) index++; + if (index == -1 || index >= viewItems.count()) + index = viewItems.count() - 1; + while (isItemHiddenOrDisabled(index)) + index--; + return index == -1 ? viewItems.count() - 1 : index; +} + +int QTreeViewPrivate::itemForKeyHome() const +{ + int index = 0; + while (isItemHiddenOrDisabled(index)) + index++; + return index >= viewItems.count() ? 0 : index; +} + +int QTreeViewPrivate::itemForKeyEnd() const +{ + int index = viewItems.count() - 1; + while (isItemHiddenOrDisabled(index)) + index--; return index == -1 ? viewItems.count() - 1 : index; } diff --git a/src/widgets/itemviews/qtreeview_p.h b/src/widgets/itemviews/qtreeview_p.h index 0a0e7aae87..9666a9f8c2 100644 --- a/src/widgets/itemviews/qtreeview_p.h +++ b/src/widgets/itemviews/qtreeview_p.h @@ -140,6 +140,8 @@ public: int pageUp(int item) const; int pageDown(int item) const; + int itemForKeyHome() const; + int itemForKeyEnd() const; int itemHeight(int item) const; int indentationForItem(int item) const; diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index e452efff07..ece2e9a220 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -4135,6 +4135,30 @@ void tst_QTreeView::keyboardNavigationWithDisabled() QCOMPARE(view.currentIndex(), model.index(12, 0)); QTest::keyClick(view.viewport(), Qt::Key_Up); QCOMPARE(view.currentIndex(), model.index(6, 0)); + // QTBUG-44746 - when first/last item is disabled, + // Key_PageUp/Down/Home/End will not work as expected. + model.item(0)->setEnabled(false); + model.item(1)->setEnabled(true); + model.item(2)->setEnabled(true); + model.item(model.rowCount() - 1)->setEnabled(false); + model.item(model.rowCount() - 2)->setEnabled(true); + model.item(model.rowCount() - 3)->setEnabled(true); + // PageUp + view.setCurrentIndex(model.index(2, 0)); + QCOMPARE(view.currentIndex(), model.index(2, 0)); + QTest::keyClick(view.viewport(), Qt::Key_PageUp); + QCOMPARE(view.currentIndex(), model.index(1, 0)); + // PageDown + view.setCurrentIndex(model.index(model.rowCount() - 3, 0)); + QCOMPARE(view.currentIndex(), model.index(model.rowCount() - 3, 0)); + QTest::keyClick(view.viewport(), Qt::Key_PageDown); + QCOMPARE(view.currentIndex(), model.index(model.rowCount() - 2, 0)); + // Key_Home + QTest::keyClick(view.viewport(), Qt::Key_Home); + QCOMPARE(view.currentIndex(), model.index(1, 0)); + // Key_End + QTest::keyClick(view.viewport(), Qt::Key_End); + QCOMPARE(view.currentIndex(), model.index(model.rowCount() - 2, 0)); } class RemoveColumnOne : public QSortFilterProxyModel diff --git a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp index ccae4ad626..74a2cc71ac 100644 --- a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp +++ b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp @@ -99,6 +99,7 @@ private slots: void insertTopLevelItems_data(); void insertTopLevelItems(); void keyboardNavigation(); + void keyboardNavigationWithHidden(); void scrollToItem(); void setSortingEnabled(); void match(); @@ -1575,6 +1576,33 @@ void tst_QTreeWidget::keyboardNavigation() } } +void tst_QTreeWidget::keyboardNavigationWithHidden() +{ + QTreeWidget tw; + for (int i = 0; i < 1000; ++i) + tw.addTopLevelItem(new QTreeWidgetItem({QString::number(i), QStringLiteral("second col")})); + // QTBUG-34832 - when first/last item is hidden, + // Key_PageUp/Down/Home/End will not work as expected. + tw.topLevelItem(0)->setHidden(true); + tw.topLevelItem(tw.model()->rowCount() - 1)->setHidden(true); + // PageUp + tw.setCurrentIndex(tw.model()->index(2, 0)); + QCOMPARE(tw.currentIndex(), tw.model()->index(2, 0)); + QTest::keyClick(tw.viewport(), Qt::Key_PageUp); + QCOMPARE(tw.currentIndex(), tw.model()->index(1, 0)); + // PageDown + tw.setCurrentIndex(tw.model()->index(tw.model()->rowCount() - 3, 0)); + QCOMPARE(tw.currentIndex(), tw.model()->index(tw.model()->rowCount() - 3, 0)); + QTest::keyClick(tw.viewport(), Qt::Key_PageDown); + QCOMPARE(tw.currentIndex(), tw.model()->index(tw.model()->rowCount() - 2, 0)); + // Key_Home + QTest::keyClick(tw.viewport(), Qt::Key_Home); + QCOMPARE(tw.currentIndex(), tw.model()->index(1, 0)); + // Key_End + QTest::keyClick(tw.viewport(), Qt::Key_End); + QCOMPARE(tw.currentIndex(), tw.model()->index(tw.model()->rowCount() - 2, 0)); +} + void tst_QTreeWidget::scrollToItem() { // Check if all parent nodes of the item found are expanded. From 4c1313197bc175d5dd38cb0e2904509f52254e2d Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sat, 15 Dec 2018 20:42:18 +0100 Subject: [PATCH 0744/1650] QbstractItemView: Allow Key_Space for keyboardSearch() The keyboard search in QAbstractItemView did not handled Key_Space because this is also an edit trigger. It was also consumed if no edit was started. This patch changes this behavior and triggers the keybaord search when the editing was not started. Fixes: QTBUG-48505 Change-Id: I58e0d283f863c9b12ac5d2f6171f15522bd7c30a Reviewed-by: David Faure --- src/widgets/itemviews/qabstractitemview.cpp | 10 ++++- .../qtablewidget/tst_qtablewidget.cpp | 42 +++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 02eae33a12..638cee8289 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -2438,8 +2438,14 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event) break; case Qt::Key_Space: case Qt::Key_Select: - if (!edit(currentIndex(), AnyKeyPressed, event) && d->selectionModel) - d->selectionModel->select(currentIndex(), selectionCommand(currentIndex(), event)); + if (!edit(currentIndex(), AnyKeyPressed, event)) { + if (d->selectionModel) + d->selectionModel->select(currentIndex(), selectionCommand(currentIndex(), event)); + if (event->key() == Qt::Key_Space) { + keyboardSearch(event->text()); + event->accept(); + } + } #ifdef QT_KEYPAD_NAVIGATION if ( event->key()==Qt::Key_Select ) { // Also do Key_Enter action. diff --git a/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp b/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp index 2e8f262c85..f97c43e347 100644 --- a/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp +++ b/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp @@ -91,6 +91,7 @@ private slots: void itemWithHeaderItems(); void mimeData(); void selectedRowAfterSorting(); + void search(); #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) void clearItemData(); #endif @@ -164,6 +165,7 @@ void tst_QTableWidget::initTestCase() { testWidget = new QTableWidget(); testWidget->show(); + QApplication::setKeyboardInputInterval(100); } void tst_QTableWidget::cleanupTestCase() @@ -1598,6 +1600,7 @@ public: using QTableWidget::mimeData; using QTableWidget::indexFromItem; + using QTableWidget::keyPressEvent; }; void tst_QTableWidget::mimeData() @@ -1672,6 +1675,45 @@ void tst_QTableWidget::selectedRowAfterSorting() } } +void tst_QTableWidget::search() +{ + auto createItem = [](const QString &txt) + { + auto item = new QTableWidgetItem(txt); + item->setFlags(item->flags().setFlag(Qt::ItemIsEditable, false)); + return item; + }; + + auto checkSeries = [](TestTableWidget &tw, const QVector> &series) + { + for (const auto &p : series) { + QKeyEvent e = p.first; + tw.keyPressEvent(&e); + QVERIFY(tw.selectionModel()->isSelected(tw.model()->index(p.second, 0))); + } + }; + TestTableWidget tw(5, 1); + tw.setItem(0, 0, createItem("12")); + tw.setItem(1, 0, createItem("123")); + tw.setItem(2, 0, createItem("123 4")); + tw.setItem(3, 0, createItem("123 5")); + tw.setItem(4, 0, createItem(" ")); + tw.show(); + + QKeyEvent evSpace(QEvent::KeyPress, Qt::Key_Space, Qt::NoModifier, " "); + QKeyEvent ev1(QEvent::KeyPress, Qt::Key_1, Qt::NoModifier, "1"); + QKeyEvent ev2(QEvent::KeyPress, Qt::Key_2, Qt::NoModifier, "2"); + QKeyEvent ev3(QEvent::KeyPress, Qt::Key_3, Qt::NoModifier, "3"); + QKeyEvent ev4(QEvent::KeyPress, Qt::Key_4, Qt::NoModifier, "4"); + QKeyEvent ev5(QEvent::KeyPress, Qt::Key_5, Qt::NoModifier, "5"); + + checkSeries(tw, {{evSpace, 4}, {ev1, 4}}); + QTest::qWait(QApplication::keyboardInputInterval() * 2); + checkSeries(tw, {{ev1, 0}, {ev2, 0}, {ev3, 1}, {evSpace, 2}, {ev5, 3}}); + QTest::qWait(QApplication::keyboardInputInterval() * 2); + checkSeries(tw, {{ev1, 0}, {ev2, 0}, {ev3, 1}, {evSpace, 2}, {ev4, 2}}); +} + #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) void tst_QTableWidget::clearItemData() { From 94daa69699272819e9d47b27c1270939d6672ebd Mon Sep 17 00:00:00 2001 From: Alejandro Exojo Date: Tue, 10 Jul 2018 17:14:52 +0200 Subject: [PATCH 0745/1650] Remove unused pointers for PressDelayHandler Change-Id: I7e2fcf828c6027737b176aa566ebd7e48c7953e7 Reviewed-by: Friedemann Kleint --- src/widgets/util/qflickgesture.cpp | 2 -- src/widgets/util/qflickgesture_p.h | 3 --- 2 files changed, 5 deletions(-) diff --git a/src/widgets/util/qflickgesture.cpp b/src/widgets/util/qflickgesture.cpp index b59fe0d504..a8b2a00a80 100644 --- a/src/widgets/util/qflickgesture.cpp +++ b/src/widgets/util/qflickgesture.cpp @@ -130,8 +130,6 @@ private: , mouseEventSource(Qt::MouseEventNotSynthesized) { } - static PressDelayHandler *inst; - public: enum { UngrabMouseBefore = 1, diff --git a/src/widgets/util/qflickgesture_p.h b/src/widgets/util/qflickgesture_p.h index 74a0f2a0f3..d5ace887ae 100644 --- a/src/widgets/util/qflickgesture_p.h +++ b/src/widgets/util/qflickgesture_p.h @@ -77,8 +77,6 @@ public: friend class QFlickGestureRecognizer; }; -class PressDelayHandler; - class QFlickGesturePrivate : public QGesturePrivate { Q_DECLARE_PUBLIC(QFlickGesture) @@ -89,7 +87,6 @@ public: QScroller *receiverScroller; Qt::MouseButton button; // NoButton == Touch bool macIgnoreWheel; - static PressDelayHandler *pressDelayHandler; }; class QFlickGestureRecognizer : public QGestureRecognizer From 7ef0b575b38d267bd3dc14ff46935d556562ff00 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Wed, 26 Dec 2018 14:05:06 +0100 Subject: [PATCH 0746/1650] QtTest: add toString(QModelIndex) Add toString(QModelIndex) to make debugging itemmodels/views autotests easier. [ChangeLog][QtTest] Added QTest::toString(const QModelIndex &idx) Change-Id: I20ad6b1fb145c00a3239131a3274fdbefc3b3ffd Reviewed-by: David Faure Reviewed-by: Thiago Macieira --- src/testlib/qtest.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/testlib/qtest.h b/src/testlib/qtest.h index 900050f012..3906eddb79 100644 --- a/src/testlib/qtest.h +++ b/src/testlib/qtest.h @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -128,6 +129,13 @@ template<> inline char *toString(const QChar &c) return qstrdup(qPrintable(QString::fromLatin1("QChar: '%1' (0x%2)").arg(c).arg(QString::number(static_cast(c.unicode()), 16)))); } +template<> inline char *toString(const QModelIndex &idx) +{ + char msg[128]; + qsnprintf(msg, sizeof(msg), "QModelIndex(%d,%d,%p,%p)", idx.row(), idx.column(), idx.internalPointer(), idx.model()); + return qstrdup(msg); +} + template<> inline char *toString(const QPoint &p) { char msg[128] = {'\0'}; From 7f34e8b58ca51b8ce0b0d7757ae903ac9e940c80 Mon Sep 17 00:00:00 2001 From: Alejandro Exojo Date: Wed, 11 Jul 2018 17:33:29 +0200 Subject: [PATCH 0747/1650] Fix and unit test QPalette::resolve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function is setting the brushes correctly in the return value, but without updating the resolve_mask, making it return wrong results in functions like isBrushSet or the debug operator. Added a unit test for the member function, since the class is still mostly untested, and clarified the reference documentation of what the function is supposed to do. Change-Id: Iaa820dc44f095e125f9375cb00da5569986803c6 Reviewed-by: Tor Arne Vestbø --- src/gui/kernel/qpalette.cpp | 4 +- .../auto/gui/kernel/qpalette/tst_qpalette.cpp | 38 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qpalette.cpp b/src/gui/kernel/qpalette.cpp index 16b1f847bd..b4383c5bfc 100644 --- a/src/gui/kernel/qpalette.cpp +++ b/src/gui/kernel/qpalette.cpp @@ -941,7 +941,8 @@ qint64 QPalette::cacheKey() const } /*! - Returns a new QPalette that has attributes copied from \a other. + Returns a new QPalette that is a union of this instance and \a other. + Color roles set in this instance take precedence. */ QPalette QPalette::resolve(const QPalette &other) const { @@ -959,6 +960,7 @@ QPalette QPalette::resolve(const QPalette &other) const if (!(data.resolve_mask & (1<br[grp][role] = other.d->br[grp][role]; + palette.data.resolve_mask |= other.data.resolve_mask; return palette; } diff --git a/tests/auto/gui/kernel/qpalette/tst_qpalette.cpp b/tests/auto/gui/kernel/qpalette/tst_qpalette.cpp index a0ac1b3631..7f29b1c24e 100644 --- a/tests/auto/gui/kernel/qpalette/tst_qpalette.cpp +++ b/tests/auto/gui/kernel/qpalette/tst_qpalette.cpp @@ -37,6 +37,7 @@ class tst_QPalette : public QObject private Q_SLOTS: void roleValues_data(); void roleValues(); + void resolve(); void copySemantics(); void moveSemantics(); void setBrush(); @@ -80,6 +81,43 @@ void tst_QPalette::roleValues() QCOMPARE(role, value); } +void tst_QPalette::resolve() +{ + QPalette p1; + p1.setBrush(QPalette::WindowText, Qt::green); + p1.setBrush(QPalette::Button, Qt::green); + + QVERIFY(p1.isBrushSet(QPalette::Active, QPalette::WindowText)); + QVERIFY(p1.isBrushSet(QPalette::Active, QPalette::Button)); + + QPalette p2; + p2.setBrush(QPalette::WindowText, Qt::red); + + QVERIFY(p2.isBrushSet(QPalette::Active, QPalette::WindowText)); + QVERIFY(!p2.isBrushSet(QPalette::Active, QPalette::Button)); + + QPalette p1ResolvedTo2 = p1.resolve(p2); + // p1ResolvedTo2 gets everything from p1 and nothing copied from p2 because + // it already has a WindowText. That is two brushes, and to the same value + // as p1. + QCOMPARE(p1ResolvedTo2, p1); + QVERIFY(p1ResolvedTo2.isBrushSet(QPalette::Active, QPalette::WindowText)); + QCOMPARE(p1.windowText(), p1ResolvedTo2.windowText()); + QVERIFY(p1ResolvedTo2.isBrushSet(QPalette::Active, QPalette::Button)); + QCOMPARE(p1.button(), p1ResolvedTo2.button()); + + QPalette p2ResolvedTo1 = p2.resolve(p1); + // p2ResolvedTo1 gets the WindowText set, and to the same value as the + // original p2, however, Button gets set from p1. + QVERIFY(p2ResolvedTo1.isBrushSet(QPalette::Active, QPalette::WindowText)); + QCOMPARE(p2.windowText(), p2ResolvedTo1.windowText()); + QVERIFY(p2ResolvedTo1.isBrushSet(QPalette::Active, QPalette::Button)); + QCOMPARE(p1.button(), p2ResolvedTo1.button()); + + QVERIFY(p2ResolvedTo1 != p1); + QVERIFY(p2ResolvedTo1 != p2); +} + void tst_QPalette::copySemantics() { QPalette src(Qt::red), dst; From 804eea08b43d426112a5c1152f52dd3660e25b71 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 29 Dec 2018 16:38:26 -0200 Subject: [PATCH 0748/1650] Work around FreeBSD 12.0 breaking source compatibility with IFM_FDDI The macro disappeared. qnetworkinterface_unix.cpp:467:14: error: use of undeclared identifier 'IFM_FDDI'; did you mean 'IFT_FDDI'? Fixes: QTBUG-72775 Change-Id: I548dbfddb69b4fd6a0a3fffd1574e1ad4e670e5b Reviewed-by: Giuseppe D'Angelo --- src/network/kernel/qnetworkinterface_unix.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/network/kernel/qnetworkinterface_unix.cpp b/src/network/kernel/qnetworkinterface_unix.cpp index 8f290e5107..c28c5ea9e6 100644 --- a/src/network/kernel/qnetworkinterface_unix.cpp +++ b/src/network/kernel/qnetworkinterface_unix.cpp @@ -464,8 +464,10 @@ static QNetworkInterface::InterfaceType probeIfType(int socket, int iftype, stru case IFM_ETHER: return QNetworkInterface::Ethernet; +#ifdef IFM_FDDI case IFM_FDDI: return QNetworkInterface::Fddi; +#endif case IFM_IEEE80211: return QNetworkInterface::Ieee80211; From 9636a43abcf98dede8b267f557b728e99f0d56cd Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Thu, 1 Nov 2018 11:52:28 +0100 Subject: [PATCH 0749/1650] Doc: Update page Tamil Script Code for Information Interchange Task-number: QTBUG-56668 Change-Id: I173d73ef5e9b08e865cb75fa03849665fcda652e Reviewed-by: Venugopal Shivashankar --- src/corelib/codecs/codecs.qdoc | 6 ++---- src/corelib/doc/src/external-resources.qdoc | 8 ++++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/corelib/codecs/codecs.qdoc b/src/corelib/codecs/codecs.qdoc index 9364b7a989..ec9b8185e2 100644 --- a/src/corelib/codecs/codecs.qdoc +++ b/src/corelib/codecs/codecs.qdoc @@ -276,13 +276,11 @@ TSCII, formally the Tamil Standard Code Information Interchange specification, is a commonly used charset for Tamils. The - official page for the standard is at - \l{http://www.tamil.net/tscii/} + official page for the standard is \l{Information Technology in Tamil} - This codec uses the mapping table found at - \l{http://www.geocities.com/Athens/5180/tsciiset.html}. Tamil uses composed Unicode which might cause some problems if you are using Unicode fonts instead of TSCII fonts. + A Tamil codepage layout can be found on \l {Tamil Script Code}. Most of the code was written by Hans Petter Bieker and is included in Qt with the author's permission and the grateful diff --git a/src/corelib/doc/src/external-resources.qdoc b/src/corelib/doc/src/external-resources.qdoc index f7c9dbb365..f16a21d521 100644 --- a/src/corelib/doc/src/external-resources.qdoc +++ b/src/corelib/doc/src/external-resources.qdoc @@ -32,13 +32,13 @@ */ /*! - \externalpage http://www.geocities.com/Athens/5180/tsciiset.html - \title http://www.geocities.com/Athens/5180/tsciiset.html + \externalpage https://en.wikipedia.org/wiki/Tamil_Script_Code_for_Information_Interchange + \title Tamil Script Code */ /*! - \externalpage http://www.tamil.net/tscii/ - \title http://www.tamil.net/tscii/ + \externalpage http://home.infitt.org + \title Information Technology in Tamil */ /*! From 29ea287716175b57aa7b050b70eb3eb5c9049464 Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Thu, 13 Dec 2018 15:54:35 +0100 Subject: [PATCH 0750/1650] Windows QPA: Avoid duplication of mouse events The code being removed was added as a workaround to support the use of QCursor::setPos() with unit tests. This function was used to move the Windows mouse cursor, internally calling SetCursorPos(), which generates only WM_MOUSE* messages, bypassing the pointer messages. However, the workaround had the unintended effect of generating duplicated mouse events for normal mouse movement, which caused issues like the one described by QTBUG-70974. However, it seems the tests are no longer depending on it, allowing it to be removed. Fixes: QTBUG-70974 Change-Id: Iaf0d64c73951ab1b660e9bb90e7ee009e53fbd3a Reviewed-by: Friedemann Kleint --- .../windows/qwindowspointerhandler.cpp | 29 ------------------- 1 file changed, 29 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp index 3534f06971..78a8083d5b 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp @@ -370,22 +370,6 @@ static Qt::MouseButtons mouseButtonsFromPointerFlags(POINTER_FLAGS pointerFlags) return result; } -static Qt::MouseButtons mouseButtonsFromKeyState(WPARAM keyState) -{ - Qt::MouseButtons result = Qt::NoButton; - if (keyState & MK_LBUTTON) - result |= Qt::LeftButton; - if (keyState & MK_RBUTTON) - result |= Qt::RightButton; - if (keyState & MK_MBUTTON) - result |= Qt::MiddleButton; - if (keyState & MK_XBUTTON1) - result |= Qt::XButton1; - if (keyState & MK_XBUTTON2) - result |= Qt::XButton2; - return result; -} - static QWindow *getWindowUnderPointer(QWindow *window, QPoint globalPos) { QWindow *currentWindowUnderPointer = QWindowsScreen::windowAt(globalPos, CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT); @@ -816,14 +800,6 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtW return false; } - // Windows sends a mouse move with no buttons pressed to signal "Enter" - // when a window is shown over the cursor. Discard the event and only use - // it for generating QEvent::Enter to be consistent with other platforms - - // X11 and macOS. - static QPoint lastMouseMovePos; - const bool discardEvent = msg.wParam == 0 && (m_windowUnderPointer.isNull() || globalPos == lastMouseMovePos); - lastMouseMovePos = globalPos; - QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos); if (currentWindowUnderPointer != m_windowUnderPointer) { @@ -846,11 +822,6 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtW m_windowUnderPointer = currentWindowUnderPointer; } - const Qt::MouseButtons mouseButtons = mouseButtonsFromKeyState(msg.wParam); - - if (!discardEvent) - QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos, mouseButtons, Qt::NoButton, QEvent::MouseMove, - keyModifiers, Qt::MouseEventNotSynthesized); return false; } From 7ba16f4c1ea172026da834887de1b8da797de79a Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Mon, 31 Dec 2018 16:20:48 +0100 Subject: [PATCH 0751/1650] QComboBox/WindowVistaStyle: restore focus rect The focus rect for the QComboBox was removed during the refactoring done in 5c60e4b8f9cc88e48f5e7652eefe90e1366ae23d. Readd the functionality in a similar to QWindowsStyle::drawComplexControl(). Fixes: QTBUG-69239 Change-Id: I74e4060fbe52432318e3c986fc838cf353d99843 Reviewed-by: Andre de la Rocha Reviewed-by: Friedemann Kleint --- src/plugins/styles/windowsvista/qwindowsvistastyle.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp b/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp index 7b35d1b58c..771552a121 100644 --- a/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp +++ b/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp @@ -1664,9 +1664,15 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle theme.stateId = CBXS_NORMAL; d->drawBackground(theme); } + if ((sub & SC_ComboBoxEditField) && (flags & State_HasFocus)) { + QStyleOptionFocusRect fropt; + fropt.QStyleOption::operator=(*cmb); + fropt.rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxEditField, widget); + proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget); + } } - } - break; + } + break; case CC_ScrollBar: if (const QStyleOptionSlider *scrollbar = qstyleoption_cast(option)) { From f9d8762d37d83e3f3f21adfece0dbbb15886d722 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Fri, 21 Dec 2018 09:38:30 +0100 Subject: [PATCH 0752/1650] winrt: Remove yet another Windows Phone leftover Hardware and camera button handling are phone specific APIs we no longer support in Qt. Change-Id: Ib11f894a426b8e4b71acf24876437ddab2cea548 Reviewed-by: Oliver Wolff Reviewed-by: Andre de la Rocha Reviewed-by: Oswald Buddenhagen --- qmake/generators/win32/msvc_nmake.cpp | 8 -- .../platforms/winrt/qwinrtintegration.cpp | 132 ------------------ .../platforms/winrt/qwinrtintegration.h | 16 --- 3 files changed, 156 deletions(-) diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index 780f6bd4d8..548d2e8575 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -195,11 +195,6 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) incDirs << crtInclude + QStringLiteral("/winrt"); if (winrtBuild) { - // Only use mobile-specific headers and link against store-specific libs for - // winrt builds. - incDirs << kitDir + QStringLiteral("Extension SDKs/WindowsMobile/") - + crtVersion + QStringLiteral("/Include/WinRT"); - libDirs << toolsInstallDir + QStringLiteral("lib/") + arch + QStringLiteral("/store"); } else { // Desktop projects may require the atl headers and libs. @@ -236,9 +231,6 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) incDirs << crtInclude + QStringLiteral("/shared"); incDirs << crtInclude + QStringLiteral("/winrt"); - incDirs << kitDir + QStringLiteral("Extension SDKs/WindowsMobile/") - + crtVersion + QStringLiteral("/Include/WinRT"); - libDirs << vcInstallDir + QStringLiteral("lib/store/") + compilerArch; libDirs << vcInstallDir + QStringLiteral("atlmfc/lib") + compilerArch; diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp index 4f37583bed..78cbc3aec3 100644 --- a/src/plugins/platforms/winrt/qwinrtintegration.cpp +++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp @@ -75,13 +75,6 @@ #include #include -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) -# include -# include - using namespace ABI::Windows::Foundation::Metadata; -#endif - - using namespace Microsoft::WRL; using namespace Microsoft::WRL::Wrappers; using namespace ABI::Windows::Foundation; @@ -92,27 +85,14 @@ using namespace ABI::Windows::UI::Core; using namespace ABI::Windows::UI::ViewManagement; using namespace ABI::Windows::Graphics::Display; using namespace ABI::Windows::ApplicationModel::Core; -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) -using namespace ABI::Windows::Phone::UI::Input; -#endif typedef IEventHandler ResumeHandler; typedef IEventHandler SuspendHandler; -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) -typedef IEventHandler BackPressedHandler; -typedef IEventHandler CameraButtonHandler; -#endif QT_BEGIN_NAMESPACE typedef HRESULT (__stdcall ICoreApplication::*CoreApplicationCallbackRemover)(EventRegistrationToken); uint qHash(CoreApplicationCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); } -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) -typedef HRESULT (__stdcall IHardwareButtonsStatics::*HardwareButtonsCallbackRemover)(EventRegistrationToken); -uint qHash(HardwareButtonsCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); } -typedef HRESULT (__stdcall IHardwareButtonsStatics2::*HardwareButtons2CallbackRemover)(EventRegistrationToken); -uint qHash(HardwareButtons2CallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); } -#endif class QWinRTIntegrationPrivate { @@ -128,15 +108,6 @@ public: ComPtr application; QHash applicationTokens; -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) - ComPtr hardwareButtons; - QHash buttonsTokens; - ComPtr cameraButtons; - QHash cameraTokens; - boolean hasHardwareButtons; - bool cameraHalfPressed : 1; - bool cameraPressed : 1; -#endif }; QWinRTIntegration::QWinRTIntegration() : d_ptr(new QWinRTIntegrationPrivate) @@ -156,45 +127,6 @@ QWinRTIntegration::QWinRTIntegration() : d_ptr(new QWinRTIntegrationPrivate) &d->applicationTokens[&ICoreApplication::remove_Resuming]); Q_ASSERT_SUCCEEDED(hr); -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) - d->hasHardwareButtons = false; - ComPtr apiInformationStatics; - hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Foundation_Metadata_ApiInformation).Get(), - IID_PPV_ARGS(&apiInformationStatics)); - - if (SUCCEEDED(hr)) { - const HStringReference valueRef(L"Windows.Phone.UI.Input.HardwareButtons"); - hr = apiInformationStatics->IsTypePresent(valueRef.Get(), &d->hasHardwareButtons); - } - - if (d->hasHardwareButtons) { - hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Phone_UI_Input_HardwareButtons).Get(), - IID_PPV_ARGS(&d->hardwareButtons)); - Q_ASSERT_SUCCEEDED(hr); - hr = d->hardwareButtons->add_BackPressed(Callback(this, &QWinRTIntegration::onBackButtonPressed).Get(), - &d->buttonsTokens[&IHardwareButtonsStatics::remove_BackPressed]); - Q_ASSERT_SUCCEEDED(hr); - - hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Phone_UI_Input_HardwareButtons).Get(), - IID_PPV_ARGS(&d->cameraButtons)); - Q_ASSERT_SUCCEEDED(hr); - if (qEnvironmentVariableIntValue("QT_QPA_ENABLE_CAMERA_KEYS")) { - hr = d->cameraButtons->add_CameraPressed(Callback(this, &QWinRTIntegration::onCameraPressed).Get(), - &d->cameraTokens[&IHardwareButtonsStatics2::remove_CameraPressed]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->cameraButtons->add_CameraHalfPressed(Callback(this, &QWinRTIntegration::onCameraHalfPressed).Get(), - &d->cameraTokens[&IHardwareButtonsStatics2::remove_CameraHalfPressed]); - Q_ASSERT_SUCCEEDED(hr); - hr = d->cameraButtons->add_CameraReleased(Callback(this, &QWinRTIntegration::onCameraReleased).Get(), - &d->cameraTokens[&IHardwareButtonsStatics2::remove_CameraReleased]); - Q_ASSERT_SUCCEEDED(hr); - } - d->cameraPressed = false; - d->cameraHalfPressed = false; - } -#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) - - QEventDispatcherWinRT::runOnXamlThread([d]() { d->mainScreen = new QWinRTScreen; return S_OK; @@ -214,18 +146,6 @@ QWinRTIntegration::~QWinRTIntegration() Q_D(QWinRTIntegration); HRESULT hr; -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) - if (d->hasHardwareButtons) { - for (QHash::const_iterator i = d->buttonsTokens.begin(); i != d->buttonsTokens.end(); ++i) { - hr = (d->hardwareButtons.Get()->*i.key())(i.value()); - Q_ASSERT_SUCCEEDED(hr); - } - for (QHash::const_iterator i = d->cameraTokens.begin(); i != d->cameraTokens.end(); ++i) { - hr = (d->cameraButtons.Get()->*i.key())(i.value()); - Q_ASSERT_SUCCEEDED(hr); - } - } -#endif // Do not execute this on Windows Phone as the application is already // shutting down and trying to unregister suspending/resume handler will // cause exceptions and assert in debug mode @@ -353,58 +273,6 @@ QPlatformTheme *QWinRTIntegration::createPlatformTheme(const QString &name) cons // System-level integration points -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) -HRESULT QWinRTIntegration::onBackButtonPressed(IInspectable *, IBackPressedEventArgs *args) -{ - Q_D(QWinRTIntegration); - QWindow *window = d->mainScreen->topWindow(); - QWindowSystemInterface::setSynchronousWindowSystemEvents(true); - const bool pressed = QWindowSystemInterface::handleExtendedKeyEvent(window, QEvent::KeyPress, Qt::Key_Back, Qt::NoModifier, - 0, 0, 0, QString(), false, 1, false); - const bool released = QWindowSystemInterface::handleExtendedKeyEvent(window, QEvent::KeyRelease, Qt::Key_Back, Qt::NoModifier, - 0, 0, 0, QString(), false, 1, false); - QWindowSystemInterface::setSynchronousWindowSystemEvents(false); - args->put_Handled(pressed || released); - return S_OK; -} - -HRESULT QWinRTIntegration::onCameraPressed(IInspectable *, ICameraEventArgs *) -{ - Q_D(QWinRTIntegration); - QWindow *window = d->mainScreen->topWindow(); - QWindowSystemInterface::handleExtendedKeyEvent(window, QEvent::KeyPress, Qt::Key_Camera, Qt::NoModifier, - 0, 0, 0, QString(), false, 1, false); - d->cameraPressed = true; - return S_OK; -} - -HRESULT QWinRTIntegration::onCameraHalfPressed(IInspectable *, ICameraEventArgs *) -{ - Q_D(QWinRTIntegration); - QWindow *window = d->mainScreen->topWindow(); - QWindowSystemInterface::handleExtendedKeyEvent(window, QEvent::KeyPress, Qt::Key_CameraFocus, Qt::NoModifier, - 0, 0, 0, QString(), false, 1, false); - d->cameraHalfPressed = true; - return S_OK; -} - -HRESULT QWinRTIntegration::onCameraReleased(IInspectable *, ICameraEventArgs *) -{ - Q_D(QWinRTIntegration); - QWindow *window = d->mainScreen->topWindow(); - if (d->cameraHalfPressed) - QWindowSystemInterface::handleExtendedKeyEvent(window, QEvent::KeyRelease, Qt::Key_CameraFocus, Qt::NoModifier, - 0, 0, 0, QString(), false, 1, false); - - if (d->cameraPressed) - QWindowSystemInterface::handleExtendedKeyEvent(window, QEvent::KeyRelease, Qt::Key_Camera, Qt::NoModifier, - 0, 0, 0, QString(), false, 1, false); - d->cameraHalfPressed = false; - d->cameraPressed = false; - return S_OK; -} -#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) - HRESULT QWinRTIntegration::onSuspended(IInspectable *, ISuspendingEventArgs *) { QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationSuspended); diff --git a/src/plugins/platforms/winrt/qwinrtintegration.h b/src/plugins/platforms/winrt/qwinrtintegration.h index 636e594b4b..e944ed5d79 100644 --- a/src/plugins/platforms/winrt/qwinrtintegration.h +++ b/src/plugins/platforms/winrt/qwinrtintegration.h @@ -50,16 +50,6 @@ namespace ABI { namespace Foundation { struct IAsyncAction; } -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) - namespace Phone { - namespace UI { - namespace Input { - struct IBackPressedEventArgs; - struct ICameraEventArgs; - } - } - } -#endif } } struct IAsyncInfo; @@ -111,12 +101,6 @@ public: QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const override; private: -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) - HRESULT onBackButtonPressed(IInspectable *, ABI::Windows::Phone::UI::Input::IBackPressedEventArgs *args); - HRESULT onCameraPressed(IInspectable *, ABI::Windows::Phone::UI::Input::ICameraEventArgs *); - HRESULT onCameraHalfPressed(IInspectable *, ABI::Windows::Phone::UI::Input::ICameraEventArgs *); - HRESULT onCameraReleased(IInspectable *, ABI::Windows::Phone::UI::Input::ICameraEventArgs *); -#endif HRESULT onSuspended(IInspectable *, ABI::Windows::ApplicationModel::ISuspendingEventArgs *); HRESULT onResume(IInspectable *, IInspectable *); From 451ebdff824cad329b40aad9a10cec5e5cb464cc Mon Sep 17 00:00:00 2001 From: Ryan Chu Date: Wed, 2 Jan 2019 09:04:34 +0000 Subject: [PATCH 0753/1650] Revert "Disable Docker-based test servers on macOS temporarily" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit c1fc47b06aa27e253271d59b6c1f11a6c4ab674a. CI is now running on 18.04 hosts and vmx is enabled on that level. As the update in QTQAINFRA-2288, the macOS 10.13, openSUSE 42.3 and Ubuntu 18.04 had vmx enabled inside the VM. Change-Id: I6ec4094ca826418f46f417b3cab89678bb089417 Reviewed-by: Jędrzej Nowacki Reviewed-by: Qt CI Bot --- tests/auto/testserver.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/testserver.pri b/tests/auto/testserver.pri index eefb29ab19..7dd32db0af 100644 --- a/tests/auto/testserver.pri +++ b/tests/auto/testserver.pri @@ -53,7 +53,7 @@ TESTSERVER_VERSION = $$system(docker-compose --version) -equals(QMAKE_HOST.os, Darwin)|equals(QMAKE_HOST.os, Windows)|isEmpty(TESTSERVER_VERSION) { +equals(QMAKE_HOST.os, Windows)|isEmpty(TESTSERVER_VERSION) { # Make check with server "qt-test-server.qt-test-net" as a fallback message("testserver: qt-test-server.qt-test-net") } else { From 8c04aab8966611e96c64f469b7a1c6afe67e3fca Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 7 Dec 2018 14:17:38 +0100 Subject: [PATCH 0754/1650] Cleanup Widgets examples - new signal/slot syntax Cleanup the Widget examples - use the new signal/slot syntax where possible - layout, statemachine, tools and touch subdirectory Change-Id: I466b309b643ef7ffc27be7591fa10f4c75cfd3f8 Reviewed-by: Luca Beldi Reviewed-by: Sze Howe Koh Reviewed-by: Paul Wicking --- .../widgets/layouts/basiclayouts/dialog.cpp | 6 +-- .../widgets/statemachine/factorial/main.cpp | 4 +- .../widgets/statemachine/rogue/window.cpp | 3 +- .../statemachine/trafficlight/main.cpp | 16 +++---- .../statemachine/twowaybutton/main.cpp | 4 +- .../widgets/tools/completer/mainwindow.cpp | 20 ++++---- .../tools/customcompleter/mainwindow.cpp | 6 +-- .../tools/customcompleter/textedit.cpp | 4 +- .../widgets/tools/regexp/regexpdialog.cpp | 18 +++---- .../tools/treemodelcompleter/mainwindow.cpp | 26 +++++----- examples/widgets/tools/undo/mainwindow.cpp | 48 +++++++++---------- .../tools/undoframework/mainwindow.cpp | 22 ++++----- .../widgets/touch/fingerpaint/mainwindow.cpp | 16 +++---- 13 files changed, 100 insertions(+), 93 deletions(-) diff --git a/examples/widgets/layouts/basiclayouts/dialog.cpp b/examples/widgets/layouts/basiclayouts/dialog.cpp index 7acbc50eb7..8376820545 100644 --- a/examples/widgets/layouts/basiclayouts/dialog.cpp +++ b/examples/widgets/layouts/basiclayouts/dialog.cpp @@ -69,8 +69,8 @@ Dialog::Dialog() buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); //! [1] //! [2] @@ -99,7 +99,7 @@ void Dialog::createMenu() exitAction = fileMenu->addAction(tr("E&xit")); menuBar->addMenu(fileMenu); - connect(exitAction, SIGNAL(triggered()), this, SLOT(accept())); + connect(exitAction, &QAction::triggered, this, &QDialog::accept); } //! [6] diff --git a/examples/widgets/statemachine/factorial/main.cpp b/examples/widgets/statemachine/factorial/main.cpp index f100aa0110..2d25822828 100644 --- a/examples/widgets/statemachine/factorial/main.cpp +++ b/examples/widgets/statemachine/factorial/main.cpp @@ -100,7 +100,7 @@ class FactorialLoopTransition : public QSignalTransition { public: FactorialLoopTransition(Factorial *fact) - : QSignalTransition(fact, SIGNAL(xChanged(int))), m_fact(fact) + : QSignalTransition(fact, &Factorial::xChanged), m_fact(fact) {} bool eventTest(QEvent *e) override @@ -130,7 +130,7 @@ class FactorialDoneTransition : public QSignalTransition { public: FactorialDoneTransition(Factorial *fact) - : QSignalTransition(fact, SIGNAL(xChanged(int))), m_fact(fact) + : QSignalTransition(fact, &Factorial::xChanged), m_fact(fact) {} bool eventTest(QEvent *e) override diff --git a/examples/widgets/statemachine/rogue/window.cpp b/examples/widgets/statemachine/rogue/window.cpp index 059fbf1003..f91a6e522e 100644 --- a/examples/widgets/statemachine/rogue/window.cpp +++ b/examples/widgets/statemachine/rogue/window.cpp @@ -217,7 +217,8 @@ void Window::buildMachine() //![5] machine->setInitialState(inputState); - connect(machine, SIGNAL(finished()), qApp, SLOT(quit())); + connect(machine, &QStateMachine::finished, + qApp, &QApplication::quit); machine->start(); } diff --git a/examples/widgets/statemachine/trafficlight/main.cpp b/examples/widgets/statemachine/trafficlight/main.cpp index 21df91d8b0..b348d4f65d 100644 --- a/examples/widgets/statemachine/trafficlight/main.cpp +++ b/examples/widgets/statemachine/trafficlight/main.cpp @@ -132,11 +132,11 @@ QState *createLightState(LightWidget *light, int duration, QState *parent = 0) timer->setInterval(duration); timer->setSingleShot(true); QState *timing = new QState(lightState); - QObject::connect(timing, SIGNAL(entered()), light, SLOT(turnOn())); - QObject::connect(timing, SIGNAL(entered()), timer, SLOT(start())); - QObject::connect(timing, SIGNAL(exited()), light, SLOT(turnOff())); + QObject::connect(timing, &QAbstractState::entered, light, &LightWidget::turnOn); + QObject::connect(timing, &QAbstractState::entered, timer, QOverload<>::of(&QTimer::start)); + QObject::connect(timing, &QAbstractState::exited, light, &LightWidget::turnOff); QFinalState *done = new QFinalState(lightState); - timing->addTransition(timer, SIGNAL(timeout()), done); + timing->addTransition(timer, &QTimer::timeout, done); lightState->setInitialState(timing); return lightState; } @@ -159,14 +159,14 @@ public: redGoingYellow->setObjectName("redGoingYellow"); QState *yellowGoingGreen = createLightState(widget->yellowLight(), 1000); yellowGoingGreen->setObjectName("yellowGoingGreen"); - redGoingYellow->addTransition(redGoingYellow, SIGNAL(finished()), yellowGoingGreen); + redGoingYellow->addTransition(redGoingYellow, &QState::finished, yellowGoingGreen); QState *greenGoingYellow = createLightState(widget->greenLight(), 3000); greenGoingYellow->setObjectName("greenGoingYellow"); - yellowGoingGreen->addTransition(yellowGoingGreen, SIGNAL(finished()), greenGoingYellow); + yellowGoingGreen->addTransition(yellowGoingGreen, &QState::finished, greenGoingYellow); QState *yellowGoingRed = createLightState(widget->yellowLight(), 1000); yellowGoingRed->setObjectName("yellowGoingRed"); - greenGoingYellow->addTransition(greenGoingYellow, SIGNAL(finished()), yellowGoingRed); - yellowGoingRed->addTransition(yellowGoingRed, SIGNAL(finished()), redGoingYellow); + greenGoingYellow->addTransition(greenGoingYellow, &QState::finished, yellowGoingRed); + yellowGoingRed->addTransition(yellowGoingRed, &QState::finished, redGoingYellow); machine->addState(redGoingYellow); machine->addState(yellowGoingGreen); diff --git a/examples/widgets/statemachine/twowaybutton/main.cpp b/examples/widgets/statemachine/twowaybutton/main.cpp index 5c778aba70..3d4fef3bbe 100644 --- a/examples/widgets/statemachine/twowaybutton/main.cpp +++ b/examples/widgets/statemachine/twowaybutton/main.cpp @@ -69,8 +69,8 @@ int main(int argc, char **argv) //! [1] //! [2] - off->addTransition(&button, SIGNAL(clicked()), on); - on->addTransition(&button, SIGNAL(clicked()), off); + off->addTransition(&button, &QAbstractButton::clicked, on); + on->addTransition(&button, &QAbstractButton::clicked, off); //! [2] //! [3] diff --git a/examples/widgets/tools/completer/mainwindow.cpp b/examples/widgets/tools/completer/mainwindow.cpp index 8eb2e60030..114ff0fd7c 100644 --- a/examples/widgets/tools/completer/mainwindow.cpp +++ b/examples/widgets/tools/completer/mainwindow.cpp @@ -102,10 +102,14 @@ MainWindow::MainWindow(QWidget *parent) contentsLabel = new QLabel; contentsLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - connect(modelCombo, SIGNAL(activated(int)), this, SLOT(changeModel())); - connect(modeCombo, SIGNAL(activated(int)), this, SLOT(changeMode(int))); - connect(caseCombo, SIGNAL(activated(int)), this, SLOT(changeCase(int))); - connect(maxVisibleSpinBox, SIGNAL(valueChanged(int)), this, SLOT(changeMaxVisible(int))); + connect(modelCombo, QOverload::of(&QComboBox::activated), + this, &MainWindow::changeModel); + connect(modeCombo, QOverload::of(&QComboBox::activated), + this, &MainWindow::changeMode); + connect(caseCombo, QOverload::of(&QComboBox::activated), + this, &MainWindow::changeCase); + connect(maxVisibleSpinBox, QOverload::of(&QSpinBox::valueChanged), + this, &MainWindow::changeMaxVisible); //! [2] //! [3] @@ -136,9 +140,9 @@ void MainWindow::createMenu() QAction *aboutAct = new QAction(tr("About"), this); QAction *aboutQtAct = new QAction(tr("About Qt"), this); - connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit())); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); - connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); + connect(exitAction, &QAction::triggered, qApp, &QApplication::quit); + connect(aboutAct, &QAction::triggered, this, &MainWindow::about); + connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt); QMenu* fileMenu = menuBar()->addMenu(tr("File")); fileMenu->addAction(exitAction); @@ -271,7 +275,7 @@ void MainWindow::changeModel() changeCase(caseCombo->currentIndex()); completer->setWrapAround(wrapCheckBox->isChecked()); lineEdit->setCompleter(completer); - connect(wrapCheckBox, SIGNAL(clicked(bool)), completer, SLOT(setWrapAround(bool))); + connect(wrapCheckBox, &QAbstractButton::clicked, completer, &QCompleter::setWrapAround); } //! [14] diff --git a/examples/widgets/tools/customcompleter/mainwindow.cpp b/examples/widgets/tools/customcompleter/mainwindow.cpp index 7b9db708b9..39f5f39617 100644 --- a/examples/widgets/tools/customcompleter/mainwindow.cpp +++ b/examples/widgets/tools/customcompleter/mainwindow.cpp @@ -79,9 +79,9 @@ void MainWindow::createMenu() QAction *aboutAct = new QAction(tr("About"), this); QAction *aboutQtAct = new QAction(tr("About Qt"), this); - connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit())); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); - connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); + connect(exitAction, &QAction::triggered, qApp, &QApplication::quit); + connect(aboutAct, &QAction::triggered, this, &MainWindow::about); + connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt); QMenu* fileMenu = menuBar()->addMenu(tr("File")); fileMenu->addAction(exitAction); diff --git a/examples/widgets/tools/customcompleter/textedit.cpp b/examples/widgets/tools/customcompleter/textedit.cpp index 5512e72843..d42f7b38bb 100644 --- a/examples/widgets/tools/customcompleter/textedit.cpp +++ b/examples/widgets/tools/customcompleter/textedit.cpp @@ -88,8 +88,8 @@ void TextEdit::setCompleter(QCompleter *completer) c->setWidget(this); c->setCompletionMode(QCompleter::PopupCompletion); c->setCaseSensitivity(Qt::CaseInsensitive); - QObject::connect(c, SIGNAL(activated(QString)), - this, SLOT(insertCompletion(QString))); + QObject::connect(c, QOverload::of(&QCompleter::activated), + this, &TextEdit::insertCompletion); } //! [2] diff --git a/examples/widgets/tools/regexp/regexpdialog.cpp b/examples/widgets/tools/regexp/regexpdialog.cpp index 7b3fee5794..bf61d09974 100644 --- a/examples/widgets/tools/regexp/regexpdialog.cpp +++ b/examples/widgets/tools/regexp/regexpdialog.cpp @@ -135,15 +135,15 @@ RegExpDialog::RegExpDialog(QWidget *parent) } setLayout(mainLayout); - connect(patternComboBox, SIGNAL(editTextChanged(QString)), - this, SLOT(refresh())); - connect(textComboBox, SIGNAL(editTextChanged(QString)), - this, SLOT(refresh())); - connect(caseSensitiveCheckBox, SIGNAL(toggled(bool)), - this, SLOT(refresh())); - connect(minimalCheckBox, SIGNAL(toggled(bool)), this, SLOT(refresh())); - connect(syntaxComboBox, SIGNAL(currentIndexChanged(int)), - this, SLOT(refresh())); + connect(patternComboBox, &QComboBox::editTextChanged, + this, &RegExpDialog::refresh); + connect(textComboBox, &QComboBox::editTextChanged, + this, &RegExpDialog::refresh); + connect(caseSensitiveCheckBox, &QAbstractButton::toggled, + this, &RegExpDialog::refresh); + connect(minimalCheckBox, &QAbstractButton::toggled, this, &RegExpDialog::refresh); + connect(syntaxComboBox, QOverload::of(&QComboBox::currentIndexChanged), + this, &RegExpDialog::refresh); patternComboBox->addItem(tr("[A-Za-z_]+([A-Za-z_0-9]*)")); textComboBox->addItem(tr("(10 + delta4) * 32")); diff --git a/examples/widgets/tools/treemodelcompleter/mainwindow.cpp b/examples/widgets/tools/treemodelcompleter/mainwindow.cpp index 72b2fad833..dec3cb0496 100644 --- a/examples/widgets/tools/treemodelcompleter/mainwindow.cpp +++ b/examples/widgets/tools/treemodelcompleter/mainwindow.cpp @@ -61,8 +61,8 @@ MainWindow::MainWindow(QWidget *parent) completer = new TreeModelCompleter(this); completer->setModel(modelFromFile(":/resources/treemodel.txt")); completer->setSeparator(QLatin1String(".")); - QObject::connect(completer, SIGNAL(highlighted(QModelIndex)), - this, SLOT(highlight(QModelIndex))); + QObject::connect(completer, QOverload::of(&TreeModelCompleter::highlighted), + this, &MainWindow::highlight); QWidget *centralWidget = new QWidget; @@ -91,18 +91,18 @@ MainWindow::MainWindow(QWidget *parent) QLineEdit *separatorLineEdit = new QLineEdit; separatorLineEdit->setText(completer->separator()); - connect(separatorLineEdit, SIGNAL(textChanged(QString)), - completer, SLOT(setSeparator(QString))); + connect(separatorLineEdit, &QLineEdit::textChanged, + completer, &TreeModelCompleter::setSeparator); QCheckBox *wrapCheckBox = new QCheckBox; wrapCheckBox->setText(tr("Wrap around completions")); wrapCheckBox->setChecked(completer->wrapAround()); - connect(wrapCheckBox, SIGNAL(clicked(bool)), completer, SLOT(setWrapAround(bool))); + connect(wrapCheckBox, &QAbstractButton::clicked, completer, &QCompleter::setWrapAround); contentsLabel = new QLabel; contentsLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - connect(separatorLineEdit, SIGNAL(textChanged(QString)), - this, SLOT(updateContentsLabel(QString))); + connect(separatorLineEdit, &QLineEdit::textChanged, + this, &MainWindow::updateContentsLabel); treeView = new QTreeView; treeView->setModel(completer->model()); @@ -111,8 +111,10 @@ MainWindow::MainWindow(QWidget *parent) //! [1] //! [2] - connect(modeCombo, SIGNAL(activated(int)), this, SLOT(changeMode(int))); - connect(caseCombo, SIGNAL(activated(int)), this, SLOT(changeCase(int))); + connect(modeCombo, QOverload::of(&QComboBox::activated), + this, &MainWindow::changeMode); + connect(caseCombo, QOverload::of(&QComboBox::activated), + this, &MainWindow::changeMode); lineEdit = new QLineEdit; lineEdit->setCompleter(completer); @@ -145,9 +147,9 @@ void MainWindow::createMenu() QAction *aboutAct = new QAction(tr("About"), this); QAction *aboutQtAct = new QAction(tr("About Qt"), this); - connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit())); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); - connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); + connect(exitAction, &QAction::triggered, qApp, &QApplication::quit); + connect(aboutAct, &QAction::triggered, this, &MainWindow::about); + connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt); QMenu* fileMenu = menuBar()->addMenu(tr("File")); fileMenu->addAction(exitAction); diff --git a/examples/widgets/tools/undo/mainwindow.cpp b/examples/widgets/tools/undo/mainwindow.cpp index 5976163f3f..118d604742 100644 --- a/examples/widgets/tools/undo/mainwindow.cpp +++ b/examples/widgets/tools/undo/mainwindow.cpp @@ -68,25 +68,25 @@ MainWindow::MainWindow(QWidget *parent) documentTabs->removeTab(0); delete w; - connect(actionOpen, SIGNAL(triggered()), this, SLOT(openDocument())); - connect(actionClose, SIGNAL(triggered()), this, SLOT(closeDocument())); - connect(actionNew, SIGNAL(triggered()), this, SLOT(newDocument())); - connect(actionSave, SIGNAL(triggered()), this, SLOT(saveDocument())); - connect(actionExit, SIGNAL(triggered()), this, SLOT(close())); - connect(actionRed, SIGNAL(triggered()), this, SLOT(setShapeColor())); - connect(actionGreen, SIGNAL(triggered()), this, SLOT(setShapeColor())); - connect(actionBlue, SIGNAL(triggered()), this, SLOT(setShapeColor())); - connect(actionAddCircle, SIGNAL(triggered()), this, SLOT(addShape())); - connect(actionAddRectangle, SIGNAL(triggered()), this, SLOT(addShape())); - connect(actionAddTriangle, SIGNAL(triggered()), this, SLOT(addShape())); - connect(actionRemoveShape, SIGNAL(triggered()), this, SLOT(removeShape())); - connect(actionAddRobot, SIGNAL(triggered()), this, SLOT(addRobot())); - connect(actionAddSnowman, SIGNAL(triggered()), this, SLOT(addSnowman())); - connect(actionAbout, SIGNAL(triggered()), this, SLOT(about())); - connect(actionAboutQt, SIGNAL(triggered()), this, SLOT(aboutQt())); + connect(actionOpen, &QAction::triggered, this, &MainWindow::openDocument); + connect(actionClose, &QAction::triggered, this, &MainWindow::closeDocument); + connect(actionNew, &QAction::triggered, this, &MainWindow::newDocument); + connect(actionSave, &QAction::triggered, this, &MainWindow::saveDocument); + connect(actionExit, &QAction::triggered, this, &QWidget::close); + connect(actionRed, &QAction::triggered, this, &MainWindow::setShapeColor); + connect(actionGreen, &QAction::triggered, this, &MainWindow::setShapeColor); + connect(actionBlue, &QAction::triggered, this, &MainWindow::setShapeColor); + connect(actionAddCircle, &QAction::triggered, this, &MainWindow::addShape); + connect(actionAddRectangle, &QAction::triggered, this, &MainWindow::addShape); + connect(actionAddTriangle, &QAction::triggered, this, &MainWindow::addShape); + connect(actionRemoveShape, &QAction::triggered, this, &MainWindow::removeShape); + connect(actionAddRobot, &QAction::triggered, this, &MainWindow::addRobot); + connect(actionAddSnowman, &QAction::triggered, this, &MainWindow::addSnowman); + connect(actionAbout, &QAction::triggered, this, &MainWindow::about); + connect(actionAboutQt, &QAction::triggered, this, &MainWindow::aboutQt); - connect(undoLimit, SIGNAL(valueChanged(int)), this, SLOT(updateActions())); - connect(documentTabs, SIGNAL(currentChanged(int)), this, SLOT(updateActions())); + connect(undoLimit, QOverload::of(&QSpinBox::valueChanged), this, &MainWindow::updateActions); + connect(documentTabs, &QTabWidget::currentChanged, this, &MainWindow::updateActions); actionOpen->setShortcut(QString("Ctrl+O")); actionClose->setShortcut(QString("Ctrl+W")); @@ -226,9 +226,9 @@ void MainWindow::addDocument(Document *doc) return; m_undoGroup->addStack(doc->undoStack()); documentTabs->addTab(doc, fixedWindowTitle(doc)); - connect(doc, SIGNAL(currentShapeChanged(QString)), this, SLOT(updateActions())); - connect(doc->undoStack(), SIGNAL(indexChanged(int)), this, SLOT(updateActions())); - connect(doc->undoStack(), SIGNAL(cleanChanged(bool)), this, SLOT(updateActions())); + connect(doc, &Document::currentShapeChanged, this, &MainWindow::updateActions); + connect(doc->undoStack(), &QUndoStack::indexChanged, this, &MainWindow::updateActions); + connect(doc->undoStack(), &QUndoStack::cleanChanged, this, &MainWindow::updateActions); setCurrentDocument(doc); } @@ -251,9 +251,9 @@ void MainWindow::removeDocument(Document *doc) documentTabs->removeTab(index); m_undoGroup->removeStack(doc->undoStack()); - disconnect(doc, SIGNAL(currentShapeChanged(QString)), this, SLOT(updateActions())); - disconnect(doc->undoStack(), SIGNAL(indexChanged(int)), this, SLOT(updateActions())); - disconnect(doc->undoStack(), SIGNAL(cleanChanged(bool)), this, SLOT(updateActions())); + disconnect(doc, &Document::currentShapeChanged, this, &MainWindow::updateActions); + disconnect(doc->undoStack(), &QUndoStack::indexChanged, this, &MainWindow::updateActions); + disconnect(doc->undoStack(), &QUndoStack::cleanChanged, this, &MainWindow::updateActions); if (documentTabs->count() == 0) { newDocument(); diff --git a/examples/widgets/tools/undoframework/mainwindow.cpp b/examples/widgets/tools/undoframework/mainwindow.cpp index b2f5405b73..e95d50d164 100644 --- a/examples/widgets/tools/undoframework/mainwindow.cpp +++ b/examples/widgets/tools/undoframework/mainwindow.cpp @@ -70,8 +70,8 @@ MainWindow::MainWindow() diagramScene->setBackgroundBrush(pixmapBrush); diagramScene->setSceneRect(QRect(0, 0, 500, 500)); - connect(diagramScene, SIGNAL(itemMoved(DiagramItem*,QPointF)), - this, SLOT(itemMoved(DiagramItem*,QPointF))); + connect(diagramScene, &DiagramScene::itemMoved, + this, &MainWindow::itemMoved); setWindowTitle("Undo Framework"); QGraphicsView *view = new QGraphicsView(diagramScene); @@ -95,18 +95,18 @@ void MainWindow::createActions() { deleteAction = new QAction(tr("&Delete Item"), this); deleteAction->setShortcut(tr("Del")); - connect(deleteAction, SIGNAL(triggered()), this, SLOT(deleteItem())); + connect(deleteAction, &QAction::triggered, this, &MainWindow::deleteItem); //! [2] //! [3] //! [3] //! [4] addBoxAction = new QAction(tr("Add &Box"), this); //! [4] addBoxAction->setShortcut(tr("Ctrl+O")); - connect(addBoxAction, SIGNAL(triggered()), this, SLOT(addBox())); + connect(addBoxAction, &QAction::triggered, this, &MainWindow::addBox); addTriangleAction = new QAction(tr("Add &Triangle"), this); addTriangleAction->setShortcut(tr("Ctrl+T")); - connect(addTriangleAction, SIGNAL(triggered()), this, SLOT(addTriangle())); + connect(addTriangleAction, &QAction::triggered, this, &MainWindow::addTriangle); //! [5] undoAction = undoStack->createUndoAction(this, tr("&Undo")); @@ -118,13 +118,13 @@ void MainWindow::createActions() exitAction = new QAction(tr("E&xit"), this); exitAction->setShortcuts(QKeySequence::Quit); - connect(exitAction, SIGNAL(triggered()), this, SLOT(close())); + connect(exitAction, &QAction::triggered, this, &QWidget::close); aboutAction = new QAction(tr("&About"), this); QList aboutShortcuts; aboutShortcuts << tr("Ctrl+A") << tr("Ctrl+B"); aboutAction->setShortcuts(aboutShortcuts); - connect(aboutAction, SIGNAL(triggered()), this, SLOT(about())); + connect(aboutAction, &QAction::triggered, this, &MainWindow::about); } //! [6] @@ -140,10 +140,10 @@ void MainWindow::createMenus() editMenu->addAction(redoAction); editMenu->addSeparator(); editMenu->addAction(deleteAction); - connect(editMenu, SIGNAL(aboutToShow()), - this, SLOT(itemMenuAboutToShow())); - connect(editMenu, SIGNAL(aboutToHide()), - this, SLOT(itemMenuAboutToHide())); + connect(editMenu, &QMenu::aboutToShow, + this, &MainWindow::itemMenuAboutToShow); + connect(editMenu, &QMenu::aboutToHide, + this, &MainWindow::itemMenuAboutToHide); //! [7] itemMenu = menuBar()->addMenu(tr("&Item")); diff --git a/examples/widgets/touch/fingerpaint/mainwindow.cpp b/examples/widgets/touch/fingerpaint/mainwindow.cpp index 0e45eea240..b0d91d25bf 100644 --- a/examples/widgets/touch/fingerpaint/mainwindow.cpp +++ b/examples/widgets/touch/fingerpaint/mainwindow.cpp @@ -127,34 +127,34 @@ void MainWindow::createActions() { openAct = new QAction(tr("&Open..."), this); openAct->setShortcut(tr("Ctrl+O")); - connect(openAct, SIGNAL(triggered()), this, SLOT(open())); + connect(openAct, &QAction::triggered, this, &MainWindow::open); foreach (QByteArray format, QImageWriter::supportedImageFormats()) { QString text = tr("%1...").arg(QString(format).toUpper()); QAction *action = new QAction(text, this); action->setData(format); - connect(action, SIGNAL(triggered()), this, SLOT(save())); + connect(action, &QAction::triggered, this, &MainWindow::save); saveAsActs.append(action); } printAct = new QAction(tr("&Print..."), this); - connect(printAct, SIGNAL(triggered()), scribbleArea, SLOT(print())); + connect(printAct, &QAction::triggered, scribbleArea, &ScribbleArea::print); exitAct = new QAction(tr("E&xit"), this); exitAct->setShortcut(tr("Ctrl+Q")); - connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); + connect(exitAct, &QAction::triggered, this, &QWidget::close); clearScreenAct = new QAction(tr("&Clear Screen"), this); clearScreenAct->setShortcut(tr("Ctrl+L")); - connect(clearScreenAct, SIGNAL(triggered()), - scribbleArea, SLOT(clearImage())); + connect(clearScreenAct, &QAction::triggered, + scribbleArea, &ScribbleArea::clearImage); aboutAct = new QAction(tr("&About"), this); - connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); + connect(aboutAct, &QAction::triggered, this, &MainWindow::about); aboutQtAct = new QAction(tr("About &Qt"), this); - connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); + connect(aboutQtAct, &QAction::triggered, qApp, &QApplication::aboutQt); } //! [14] From a21f3431b861b09a4768801f856d431c6ac44313 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 7 Dec 2018 14:14:13 +0100 Subject: [PATCH 0755/1650] Cleanup Widgets examples - new signal/slot syntax Cleanup the Widget examples - use the new signal/slot syntax where possible - tutorials subdirectory Change-Id: I741589f6616578412ad74f8371e0e3c87df783a2 Reviewed-by: Sze Howe Koh Reviewed-by: Luca Beldi --- .../addressbook/part2/addressbook.cpp | 9 +++-- .../addressbook/part3/addressbook.cpp | 16 +++++---- .../addressbook/part4/addressbook.cpp | 21 ++++++++---- .../addressbook/part5/addressbook.cpp | 24 +++++++++----- .../addressbook/part5/finddialog.cpp | 6 ++-- .../addressbook/part6/addressbook.cpp | 30 +++++++++++------ .../addressbook/part6/finddialog.cpp | 6 ++-- .../addressbook/part7/addressbook.cpp | 33 ++++++++++++------- .../addressbook/part7/finddialog.cpp | 6 ++-- .../gettingStarted/gsQt/part2/main.cpp | 3 +- .../gettingStarted/gsQt/part3/main.cpp | 3 +- .../gettingStarted/gsQt/part4/main.cpp | 10 +++--- .../gettingStarted/gsQt/part5/main.cpp | 10 +++--- 13 files changed, 116 insertions(+), 61 deletions(-) diff --git a/examples/widgets/tutorials/addressbook/part2/addressbook.cpp b/examples/widgets/tutorials/addressbook/part2/addressbook.cpp index 34fa5d2060..d5ee394abd 100644 --- a/examples/widgets/tutorials/addressbook/part2/addressbook.cpp +++ b/examples/widgets/tutorials/addressbook/part2/addressbook.cpp @@ -74,9 +74,12 @@ AddressBook::AddressBook(QWidget *parent) cancelButton->hide(); //! [pushbutton declaration] //! [connecting signals and slots] - connect(addButton, SIGNAL(clicked()), this, SLOT(addContact())); - connect(submitButton, SIGNAL(clicked()), this, SLOT(submitContact())); - connect(cancelButton, SIGNAL(clicked()), this, SLOT(cancel())); + connect(addButton, &QPushButton::clicked, + this, &AddressBook::addContact); + connect(submitButton, &QPushButton::clicked, + this, &AddressBook::submitContact); + connect(cancelButton, &QPushButton::clicked, + this, &AddressBook::cancel); //! [connecting signals and slots] //! [vertical layout] QVBoxLayout *buttonLayout1 = new QVBoxLayout; diff --git a/examples/widgets/tutorials/addressbook/part3/addressbook.cpp b/examples/widgets/tutorials/addressbook/part3/addressbook.cpp index caef83970a..b6d48f7a0d 100644 --- a/examples/widgets/tutorials/addressbook/part3/addressbook.cpp +++ b/examples/widgets/tutorials/addressbook/part3/addressbook.cpp @@ -74,13 +74,17 @@ AddressBook::AddressBook(QWidget *parent) previousButton = new QPushButton(tr("&Previous")); previousButton->setEnabled(false); //! [navigation pushbuttons] - - connect(addButton, SIGNAL(clicked()), this, SLOT(addContact())); - connect(submitButton, SIGNAL(clicked()), this, SLOT(submitContact())); - connect(cancelButton, SIGNAL(clicked()), this, SLOT(cancel())); + connect(addButton, &QPushButton::clicked, + this, &AddressBook::addContact); + connect(submitButton, &QPushButton::clicked, + this, &AddressBook::submitContact); + connect(cancelButton, &QPushButton::clicked, + this, &AddressBook::cancel); //! [connecting navigation signals] - connect(nextButton, SIGNAL(clicked()), this, SLOT(next())); - connect(previousButton, SIGNAL(clicked()), this, SLOT(previous())); + connect(nextButton, &QPushButton::clicked, + this, &AddressBook::next); + connect(previousButton, &QPushButton::clicked, + this, &AddressBook::previous); //! [connecting navigation signals] QVBoxLayout *buttonLayout1 = new QVBoxLayout; diff --git a/examples/widgets/tutorials/addressbook/part4/addressbook.cpp b/examples/widgets/tutorials/addressbook/part4/addressbook.cpp index 92f0776727..77ce216c07 100644 --- a/examples/widgets/tutorials/addressbook/part4/addressbook.cpp +++ b/examples/widgets/tutorials/addressbook/part4/addressbook.cpp @@ -79,15 +79,22 @@ AddressBook::AddressBook(QWidget *parent) previousButton = new QPushButton(tr("&Previous")); previousButton->setEnabled(false); - connect(addButton, SIGNAL(clicked()), this, SLOT(addContact())); - connect(submitButton, SIGNAL(clicked()), this, SLOT(submitContact())); + connect(addButton, &QPushButton::clicked, + this, &AddressBook::addContact); + connect(submitButton, &QPushButton::clicked, + this, &AddressBook::submitContact); //! [connecting edit and remove] - connect(editButton, SIGNAL(clicked()), this, SLOT(editContact())); - connect(removeButton, SIGNAL(clicked()), this, SLOT(removeContact())); + connect(editButton, &QPushButton::clicked, + this, &AddressBook::editContact); + connect(removeButton, &QPushButton::clicked, + this, &AddressBook::removeContact); //! [connecting edit and remove] - connect(cancelButton, SIGNAL(clicked()), this, SLOT(cancel())); - connect(nextButton, SIGNAL(clicked()), this, SLOT(next())); - connect(previousButton, SIGNAL(clicked()), this, SLOT(previous())); + connect(cancelButton, &QPushButton::clicked, + this, &AddressBook::cancel); + connect(nextButton, &QPushButton::clicked, + this, &AddressBook::next); + connect(previousButton, &QPushButton::clicked, + this, &AddressBook::previous); QVBoxLayout *buttonLayout1 = new QVBoxLayout; buttonLayout1->addWidget(addButton); diff --git a/examples/widgets/tutorials/addressbook/part5/addressbook.cpp b/examples/widgets/tutorials/addressbook/part5/addressbook.cpp index 6e09ec287d..5505a0e35c 100644 --- a/examples/widgets/tutorials/addressbook/part5/addressbook.cpp +++ b/examples/widgets/tutorials/addressbook/part5/addressbook.cpp @@ -86,16 +86,24 @@ AddressBook::AddressBook(QWidget *parent) dialog = new FindDialog(this); //! [instantiating FindDialog] - connect(addButton, SIGNAL(clicked()), this, SLOT(addContact())); - connect(submitButton, SIGNAL(clicked()), this, SLOT(submitContact())); - connect(editButton, SIGNAL(clicked()), this, SLOT(editContact())); - connect(cancelButton, SIGNAL(clicked()), this, SLOT(cancel())); - connect(removeButton, SIGNAL(clicked()), this, SLOT(removeContact())); + connect(addButton, &QPushButton::clicked, + this, &AddressBook::addContact); + connect(submitButton, &QPushButton::clicked, + this, &AddressBook::submitContact); + connect(editButton, &QPushButton::clicked, + this, &AddressBook::editContact); + connect(removeButton, &QPushButton::clicked, + this, &AddressBook::removeContact); + connect(cancelButton, &QPushButton::clicked, + this, &AddressBook::cancel); //! [signals and slots for find] - connect(findButton, SIGNAL(clicked()), this, SLOT(findContact())); + connect(findButton, &QPushButton::clicked, + this, &AddressBook::findContact); //! [signals and slots for find] - connect(nextButton, SIGNAL(clicked()), this, SLOT(next())); - connect(previousButton, SIGNAL(clicked()), this, SLOT(previous())); + connect(nextButton, &QPushButton::clicked, + this, &AddressBook::next); + connect(previousButton, &QPushButton::clicked, + this, &AddressBook::previous); QVBoxLayout *buttonLayout1 = new QVBoxLayout; buttonLayout1->addWidget(addButton); diff --git a/examples/widgets/tutorials/addressbook/part5/finddialog.cpp b/examples/widgets/tutorials/addressbook/part5/finddialog.cpp index b0d9a5e6e3..615b39d42f 100644 --- a/examples/widgets/tutorials/addressbook/part5/finddialog.cpp +++ b/examples/widgets/tutorials/addressbook/part5/finddialog.cpp @@ -68,8 +68,10 @@ FindDialog::FindDialog(QWidget *parent) setLayout(layout); setWindowTitle(tr("Find a Contact")); - connect(findButton, SIGNAL(clicked()), this, SLOT(findClicked())); - connect(findButton, SIGNAL(clicked()), this, SLOT(accept())); + connect(findButton, &QPushButton::clicked, + this, &FindDialog::findClicked); + connect(findButton, &QPushButton::clicked, + this, &FindDialog::accept); } //! [constructor] //! [findClicked() function] diff --git a/examples/widgets/tutorials/addressbook/part6/addressbook.cpp b/examples/widgets/tutorials/addressbook/part6/addressbook.cpp index b2e361a45e..8e740cfffc 100644 --- a/examples/widgets/tutorials/addressbook/part6/addressbook.cpp +++ b/examples/widgets/tutorials/addressbook/part6/addressbook.cpp @@ -92,16 +92,26 @@ AddressBook::AddressBook(QWidget *parent) dialog = new FindDialog(this); - connect(addButton, SIGNAL(clicked()), this, SLOT(addContact())); - connect(submitButton, SIGNAL(clicked()), this, SLOT(submitContact())); - connect(editButton, SIGNAL(clicked()), this, SLOT(editContact())); - connect(cancelButton, SIGNAL(clicked()), this, SLOT(cancel())); - connect(removeButton, SIGNAL(clicked()), this, SLOT(removeContact())); - connect(findButton, SIGNAL(clicked()), this, SLOT(findContact())); - connect(nextButton, SIGNAL(clicked()), this, SLOT(next())); - connect(previousButton, SIGNAL(clicked()), this, SLOT(previous())); - connect(loadButton, SIGNAL(clicked()), this, SLOT(loadFromFile())); - connect(saveButton, SIGNAL(clicked()), this, SLOT(saveToFile())); + connect(addButton, &QPushButton::clicked, + this, &AddressBook::addContact); + connect(submitButton, &QPushButton::clicked, + this, &AddressBook::submitContact); + connect(editButton, &QPushButton::clicked, + this, &AddressBook::editContact); + connect(removeButton, &QPushButton::clicked, + this, &AddressBook::removeContact); + connect(cancelButton, &QPushButton::clicked, + this, &AddressBook::cancel); + connect(findButton, &QPushButton::clicked, + this, &AddressBook::findContact); + connect(nextButton, &QPushButton::clicked, + this, &AddressBook::next); + connect(previousButton, &QPushButton::clicked, + this, &AddressBook::previous); + connect(loadButton, &QPushButton::clicked, + this, &AddressBook::loadFromFile); + connect(saveButton, &QPushButton::clicked, + this, &AddressBook::saveToFile); QVBoxLayout *buttonLayout1 = new QVBoxLayout; buttonLayout1->addWidget(addButton); diff --git a/examples/widgets/tutorials/addressbook/part6/finddialog.cpp b/examples/widgets/tutorials/addressbook/part6/finddialog.cpp index 6a1e6b116f..c25cccd552 100644 --- a/examples/widgets/tutorials/addressbook/part6/finddialog.cpp +++ b/examples/widgets/tutorials/addressbook/part6/finddialog.cpp @@ -67,8 +67,10 @@ FindDialog::FindDialog(QWidget *parent) setLayout(layout); setWindowTitle(tr("Find a Contact")); - connect(findButton, SIGNAL(clicked()), this, SLOT(findClicked())); - connect(findButton, SIGNAL(clicked()), this, SLOT(accept())); + connect(findButton, &QPushButton::clicked, + this, &FindDialog::findClicked); + connect(findButton, &QPushButton::clicked, + this, &FindDialog::accept); } void FindDialog::findClicked() diff --git a/examples/widgets/tutorials/addressbook/part7/addressbook.cpp b/examples/widgets/tutorials/addressbook/part7/addressbook.cpp index e946c873e3..717d0882af 100644 --- a/examples/widgets/tutorials/addressbook/part7/addressbook.cpp +++ b/examples/widgets/tutorials/addressbook/part7/addressbook.cpp @@ -92,17 +92,28 @@ AddressBook::AddressBook(QWidget *parent) dialog = new FindDialog(this); - connect(addButton, SIGNAL(clicked()), this, SLOT(addContact())); - connect(submitButton, SIGNAL(clicked()), this, SLOT(submitContact())); - connect(editButton, SIGNAL(clicked()), this, SLOT(editContact())); - connect(cancelButton, SIGNAL(clicked()), this, SLOT(cancel())); - connect(removeButton, SIGNAL(clicked()), this, SLOT(removeContact())); - connect(findButton, SIGNAL(clicked()), this, SLOT(findContact())); - connect(nextButton, SIGNAL(clicked()), this, SLOT(next())); - connect(previousButton, SIGNAL(clicked()), this, SLOT(previous())); - connect(loadButton, SIGNAL(clicked()), this, SLOT(loadFromFile())); - connect(saveButton, SIGNAL(clicked()), this, SLOT(saveToFile())); - connect(exportButton, SIGNAL(clicked()), this, SLOT(exportAsVCard())); + connect(addButton, &QPushButton::clicked, + this, &AddressBook::addContact); + connect(submitButton, &QPushButton::clicked, + this, &AddressBook::submitContact); + connect(editButton, &QPushButton::clicked, + this, &AddressBook::editContact); + connect(removeButton, &QPushButton::clicked, + this, &AddressBook::removeContact); + connect(cancelButton, &QPushButton::clicked, + this, &AddressBook::cancel); + connect(findButton, &QPushButton::clicked, + this, &AddressBook::findContact); + connect(nextButton, &QPushButton::clicked, + this, &AddressBook::next); + connect(previousButton, &QPushButton::clicked, + this, &AddressBook::previous); + connect(loadButton, &QPushButton::clicked, + this, &AddressBook::loadFromFile); + connect(saveButton, &QPushButton::clicked, + this, &AddressBook::saveToFile); + connect(exportButton, &QPushButton::clicked, + this, &AddressBook::exportAsVCard); QVBoxLayout *buttonLayout1 = new QVBoxLayout; buttonLayout1->addWidget(addButton); diff --git a/examples/widgets/tutorials/addressbook/part7/finddialog.cpp b/examples/widgets/tutorials/addressbook/part7/finddialog.cpp index 6a1e6b116f..c25cccd552 100644 --- a/examples/widgets/tutorials/addressbook/part7/finddialog.cpp +++ b/examples/widgets/tutorials/addressbook/part7/finddialog.cpp @@ -67,8 +67,10 @@ FindDialog::FindDialog(QWidget *parent) setLayout(layout); setWindowTitle(tr("Find a Contact")); - connect(findButton, SIGNAL(clicked()), this, SLOT(findClicked())); - connect(findButton, SIGNAL(clicked()), this, SLOT(accept())); + connect(findButton, &QPushButton::clicked, + this, &FindDialog::findClicked); + connect(findButton, &QPushButton::clicked, + this, &FindDialog::accept); } void FindDialog::findClicked() diff --git a/examples/widgets/tutorials/gettingStarted/gsQt/part2/main.cpp b/examples/widgets/tutorials/gettingStarted/gsQt/part2/main.cpp index 90f5f1a6b3..8bf83859a0 100644 --- a/examples/widgets/tutorials/gettingStarted/gsQt/part2/main.cpp +++ b/examples/widgets/tutorials/gettingStarted/gsQt/part2/main.cpp @@ -57,7 +57,8 @@ int main(int argc, char *argv[]) QTextEdit *textEdit = new QTextEdit; QPushButton *quitButton = new QPushButton("&Quit"); - QObject::connect(quitButton, SIGNAL(clicked()), qApp, SLOT(quit())); + QObject::connect(quitButton, &QPushButton::clicked, + qApp, &QApplication::quit); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(textEdit); diff --git a/examples/widgets/tutorials/gettingStarted/gsQt/part3/main.cpp b/examples/widgets/tutorials/gettingStarted/gsQt/part3/main.cpp index 0a60c1cf16..d4b43eb034 100644 --- a/examples/widgets/tutorials/gettingStarted/gsQt/part3/main.cpp +++ b/examples/widgets/tutorials/gettingStarted/gsQt/part3/main.cpp @@ -71,7 +71,8 @@ Notepad::Notepad() textEdit = new QTextEdit; quitButton = new QPushButton(tr("Quit")); - connect(quitButton, SIGNAL(clicked()), this, SLOT(quit())); + connect(quitButton, &QPushButton::clicked, + this, &Notepad::quit); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(textEdit); diff --git a/examples/widgets/tutorials/gettingStarted/gsQt/part4/main.cpp b/examples/widgets/tutorials/gettingStarted/gsQt/part4/main.cpp index 6d9e96a3d4..8c5fbc70ca 100644 --- a/examples/widgets/tutorials/gettingStarted/gsQt/part4/main.cpp +++ b/examples/widgets/tutorials/gettingStarted/gsQt/part4/main.cpp @@ -73,14 +73,16 @@ private: Notepad::Notepad() { - loadAction = new QAction(tr("&Load"), this); saveAction = new QAction(tr("&Save"), this); exitAction = new QAction(tr("E&xit"), this); - connect(loadAction, SIGNAL(triggered()), this, SLOT(load())); - connect(saveAction, SIGNAL(triggered()), this, SLOT(save())); - connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit())); + connect(loadAction, &QAction::triggered, + this, &Notepad::load); + connect(saveAction, &QAction::triggered, + this, &Notepad::save); + connect(exitAction, &QAction::triggered, + qApp, &QApplication::quit); fileMenu = menuBar()->addMenu(tr("&File")); fileMenu->addAction(loadAction); diff --git a/examples/widgets/tutorials/gettingStarted/gsQt/part5/main.cpp b/examples/widgets/tutorials/gettingStarted/gsQt/part5/main.cpp index b2b4a73874..cc3e1a261c 100644 --- a/examples/widgets/tutorials/gettingStarted/gsQt/part5/main.cpp +++ b/examples/widgets/tutorials/gettingStarted/gsQt/part5/main.cpp @@ -73,14 +73,16 @@ private: Notepad::Notepad() { - openAction = new QAction(tr("&Load"), this); saveAction = new QAction(tr("&Save"), this); exitAction = new QAction(tr("E&xit"), this); - connect(openAction, SIGNAL(triggered()), this, SLOT(open())); - connect(saveAction, SIGNAL(triggered()), this, SLOT(save())); - connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit())); + connect(openAction, &QAction::triggered, + this, &Notepad::open); + connect(saveAction, &QAction::triggered, + this, &Notepad::save); + connect(exitAction, &QAction::triggered, + qApp, &QApplication::quit); fileMenu = menuBar()->addMenu(tr("&File")); fileMenu->addAction(openAction); From ceddc14af17df166d05d98cfa76256bfc0b34183 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 21 Dec 2018 11:31:24 +0100 Subject: [PATCH 0756/1650] Draw ShowTabsAndSpaces symbols with the correct font We would draw the tab and space symbols without setting the correct font on the painter first. [ChangeLog][QtGui][Text] Fixed so ShowTabsAndSpaces will use the correct font. Fixes: QTBUG-62540 Change-Id: I3b7d6d317473e7aab722dafe1a128c57a830f634 Reviewed-by: Andy Shaw Reviewed-by: Konstantin Ritt --- src/gui/text/qtextlayout.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index be306ed224..f3f0caa379 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -2598,6 +2598,7 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR Qt::IntersectClip); else x /= 2; // Centered + p->setFont(f); p->drawText(QPointF(iterator.x.toReal() + x, y.toReal()), visualTab); } @@ -2671,8 +2672,11 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR if (c.style() != Qt::NoBrush) p->setPen(c.color()); QChar visualSpace(si.analysis.flags == QScriptAnalysis::Space ? (ushort)0xb7 : (ushort)0xb0); + QFont oldFont = p->font(); + p->setFont(eng->font(si)); p->drawText(QPointF(iterator.x.toReal(), itemBaseLine.toReal()), visualSpace); p->setPen(pen); + p->setFont(oldFont); } } eng->drawDecorations(p); From 651b4845de69e04e54285dac42430d0ae4b5fe02 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Wed, 5 Dec 2018 15:20:57 +0100 Subject: [PATCH 0757/1650] Doc: Fix linking errors qtbase MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I225e59bea0a8eac14fd11ef2b091907ae955c447 Reviewed-by: Topi Reiniö --- src/network/ssl/qpassworddigestor.cpp | 2 +- src/testlib/qtestcase.cpp | 4 ++-- src/testlib/qtestevent.qdoc | 2 +- src/widgets/kernel/qwidget.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/network/ssl/qpassworddigestor.cpp b/src/network/ssl/qpassworddigestor.cpp index 127d94e849..706fa1de05 100644 --- a/src/network/ssl/qpassworddigestor.cpp +++ b/src/network/ssl/qpassworddigestor.cpp @@ -75,7 +75,7 @@ namespace QPasswordDigestor { \a salt must always be 8 bytes long! \note This function is provided for use with legacy applications and all - new applications are recommended to use \l {pbkdf2} {PBKDF2}. + new applications are recommended to use \l {deriveKeyPbkdf2} {PBKDF2}. \sa deriveKeyPbkdf2, QCryptographicHash, QCryptographicHash::hashLength */ diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index dbe7353bbe..2b0ad52b2d 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -2419,7 +2419,7 @@ bool QTest::currentTestFailed() Sleeps for \a ms milliseconds, blocking execution of the test. qSleep() will not do any event processing and leave your test unresponsive. Network communication might time out while - sleeping. Use \l qWait() to do non-blocking sleeping. + sleeping. Use \l {QTest::qWait()} to do non-blocking sleeping. \a ms must be greater than 0. @@ -2430,7 +2430,7 @@ bool QTest::currentTestFailed() Example: \snippet code/src_qtestlib_qtestcase.cpp 23 - \sa qWait() + \sa {QTest::qWait()} */ void QTest::qSleep(int ms) { diff --git a/src/testlib/qtestevent.qdoc b/src/testlib/qtestevent.qdoc index f0d3bff162..af84f2ac2b 100644 --- a/src/testlib/qtestevent.qdoc +++ b/src/testlib/qtestevent.qdoc @@ -133,7 +133,7 @@ Adds a \a msecs milliseconds delay. - \sa QTest::qWait() + \sa {QTest::qWait()} */ /*! \fn void QTestEventList::simulate(QWidget *w) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index bcfae46155..9a07c55e10 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -4495,7 +4495,7 @@ void QWidget::setForegroundRole(QPalette::ColorRole role) the "color", "background-color", "selection-color", "selection-background-color" and "alternate-background-color". - \sa QApplication::palette(), QWidget::font(), \l {Qt Style Sheets} + \sa QApplication::palette(), QWidget::font(), {Qt Style Sheets} */ const QPalette &QWidget::palette() const { From 6899117a59256082f37492d81ecaf56a0844690e Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Thu, 27 Dec 2018 01:10:29 +0100 Subject: [PATCH 0758/1650] configure: properly atomize render vs. renderutil xcb-render is a C interface for X11 extension. xcb-render-util is a utility library that complements xcb-render by providing convenience functions and interfaces which make the raw X protocol more usable. Bumped xcb-render-util version to avoid having include hacks. We were bundling 8 years old release 0.3.8 (Apr, 2011). 0.3.9 is the latest release and it was relesed 4,5 years ago (Jun, 2014). All CI machines have 0.3.9. The only thing that have changed in xcb-render-util sources since 2011 is that we don't need to have various hacks to include xcb_renderutil.h in C++ files. Upgrading bundled XCB libs was also requested in QTBUG-71109. Task-number: QTBUG-71109 Change-Id: Ib261f7584ad81be95660123b007e2200a3042f4c Reviewed-by: Oswald Buddenhagen --- src/3rdparty/xcb/README | 2 +- src/3rdparty/xcb/include/xcb/xcb_renderutil.h | 10 +++++- src/3rdparty/xcb/xcb-util-renderutil/util.c | 30 +++++++++------- src/gui/configure.json | 35 ++++++++++--------- .../platforms/xcb/qxcbbackingstore.cpp | 6 ---- src/plugins/platforms/xcb/qxcbimage.cpp | 6 ---- src/plugins/platforms/xcb/xcb_qpa_lib.pro | 2 +- 7 files changed, 46 insertions(+), 45 deletions(-) diff --git a/src/3rdparty/xcb/README b/src/3rdparty/xcb/README index 9e8ea30b51..2f1ee24079 100644 --- a/src/3rdparty/xcb/README +++ b/src/3rdparty/xcb/README @@ -8,7 +8,7 @@ Contains the header and sources files from selected xcb libraries: Pointer Barriers API and SendExtensionEvent API) libxcb-util-image-0.3.9 libxcb-util-keysyms-0.3.9 - libxcb-util-renderutil-0.3.8 + libxcb-util-renderutil-0.3.9 libxcb-util-wm-0.3.9 The 'include' directory was obtained by compiling and installing all of the modules. diff --git a/src/3rdparty/xcb/include/xcb/xcb_renderutil.h b/src/3rdparty/xcb/include/xcb/xcb_renderutil.h index 6eb5923236..77c5b7f054 100644 --- a/src/3rdparty/xcb/include/xcb/xcb_renderutil.h +++ b/src/3rdparty/xcb/include/xcb/xcb_renderutil.h @@ -27,6 +27,10 @@ #define XCB_RENDERUTIL #include +#ifdef __cplusplus +extern "C" { +#endif + typedef enum xcb_pict_format_t { XCB_PICT_FORMAT_ID = (1 << 0), XCB_PICT_FORMAT_TYPE = (1 << 1), @@ -58,7 +62,7 @@ xcb_render_util_find_visual_format (const xcb_render_query_pict_formats_reply_t xcb_render_pictforminfo_t * xcb_render_util_find_format (const xcb_render_query_pict_formats_reply_t *formats, unsigned long mask, - const xcb_render_pictforminfo_t *template, + const xcb_render_pictforminfo_t *ptemplate, int count); xcb_render_pictforminfo_t * @@ -139,4 +143,8 @@ void xcb_render_util_composite_text_free ( xcb_render_util_composite_text_stream_t *stream ); +#ifdef __cplusplus +} +#endif + #endif /* XCB_RENDERUTIL */ diff --git a/src/3rdparty/xcb/xcb-util-renderutil/util.c b/src/3rdparty/xcb/xcb-util-renderutil/util.c index 2d8840d204..7666c433dd 100644 --- a/src/3rdparty/xcb/xcb-util-renderutil/util.c +++ b/src/3rdparty/xcb/xcb-util-renderutil/util.c @@ -19,6 +19,10 @@ * PERFORMANCE OF THIS SOFTWARE. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include "xcb_renderutil.h" xcb_render_pictvisual_t * @@ -41,7 +45,7 @@ xcb_render_util_find_visual_format (const xcb_render_query_pict_formats_reply_t xcb_render_pictforminfo_t * xcb_render_util_find_format (const xcb_render_query_pict_formats_reply_t *formats, unsigned long mask, - const xcb_render_pictforminfo_t *template, + const xcb_render_pictforminfo_t *ptemplate, int count) { xcb_render_pictforminfo_iterator_t i; @@ -50,40 +54,40 @@ xcb_render_util_find_format (const xcb_render_query_pict_formats_reply_t *format for (i = xcb_render_query_pict_formats_formats_iterator(formats); i.rem; xcb_render_pictforminfo_next(&i)) { if (mask & XCB_PICT_FORMAT_ID) - if (template->id != i.data->id) + if (ptemplate->id != i.data->id) continue; if (mask & XCB_PICT_FORMAT_TYPE) - if (template->type != i.data->type) + if (ptemplate->type != i.data->type) continue; if (mask & XCB_PICT_FORMAT_DEPTH) - if (template->depth != i.data->depth) + if (ptemplate->depth != i.data->depth) continue; if (mask & XCB_PICT_FORMAT_RED) - if (template->direct.red_shift != i.data->direct.red_shift) + if (ptemplate->direct.red_shift != i.data->direct.red_shift) continue; if (mask & XCB_PICT_FORMAT_RED_MASK) - if (template->direct.red_mask != i.data->direct.red_mask) + if (ptemplate->direct.red_mask != i.data->direct.red_mask) continue; if (mask & XCB_PICT_FORMAT_GREEN) - if (template->direct.green_shift != i.data->direct.green_shift) + if (ptemplate->direct.green_shift != i.data->direct.green_shift) continue; if (mask & XCB_PICT_FORMAT_GREEN_MASK) - if (template->direct.green_mask != i.data->direct.green_mask) + if (ptemplate->direct.green_mask != i.data->direct.green_mask) continue; if (mask & XCB_PICT_FORMAT_BLUE) - if (template->direct.blue_shift != i.data->direct.blue_shift) + if (ptemplate->direct.blue_shift != i.data->direct.blue_shift) continue; if (mask & XCB_PICT_FORMAT_BLUE_MASK) - if (template->direct.blue_mask != i.data->direct.blue_mask) + if (ptemplate->direct.blue_mask != i.data->direct.blue_mask) continue; if (mask & XCB_PICT_FORMAT_ALPHA) - if (template->direct.alpha_shift != i.data->direct.alpha_shift) + if (ptemplate->direct.alpha_shift != i.data->direct.alpha_shift) continue; if (mask & XCB_PICT_FORMAT_ALPHA_MASK) - if (template->direct.alpha_mask != i.data->direct.alpha_mask) + if (ptemplate->direct.alpha_mask != i.data->direct.alpha_mask) continue; if (mask & XCB_PICT_FORMAT_COLORMAP) - if (template->colormap != i.data->colormap) + if (ptemplate->colormap != i.data->colormap) continue; if (count-- == 0) return i.data; diff --git a/src/gui/configure.json b/src/gui/configure.json index caa6f065f0..7b861c80fe 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -615,6 +615,20 @@ ], "use": "xcb" }, + "xcb_renderutil": { + "label": "XCB Renderutil >= 0.3.9", + "test": { + "main": [ + "xcb_render_util_find_standard_format(nullptr, XCB_PICT_STANDARD_ARGB_32);" + ] + }, + "headers": "xcb/xcb_renderutil.h", + "sources": [ + { "type": "pkgConfig", "args": "xcb-renderutil >= 0.3.9" }, + "-lxcb-render-util" + ], + "use": "xcb xcb_render" + }, "xcb_randr": { "label": "XCB RandR", "headers": "xcb/randr.h", @@ -704,32 +718,20 @@ "xcb_render": { "label": "XCB XRender", "test": { - "tail": [ - "// 'template' is used as a function argument name in xcb_renderutil.h", - "#define template template_param", - "// extern \"C\" is missing, too", - "extern \"C\" {", - "#include ", - "}", - "#undef template" - ], "main": [ - "int primaryScreen = 0;", "xcb_generic_error_t *error = 0;", "xcb_connection_t *connection = 0;", "xcb_render_query_pict_formats_cookie_t formatsCookie =", " xcb_render_query_pict_formats(connection);", "xcb_render_query_pict_formats_reply_t *formatsReply =", " xcb_render_query_pict_formats_reply(", - " connection, formatsCookie, &error);", - "xcb_render_util_find_standard_format(", - " formatsReply, XCB_PICT_STANDARD_ARGB_32);" + " connection, formatsCookie, &error);" ] }, "headers": "xcb/render.h", "sources": [ - { "type": "pkgConfig", "args": "xcb-renderutil xcb-render" }, - "-lxcb-render-util -lxcb-render" + { "type": "pkgConfig", "args": "xcb-render" }, + "-lxcb-render" ], "use": "xcb" }, @@ -737,7 +739,6 @@ "label": "XCB GLX", "test": { "main": [ - "int primaryScreen = 0;", "xcb_connection_t *connection = 0;", "xcb_generic_error_t *error = 0;", "xcb_glx_query_version_cookie_t xglx_query_cookie = xcb_glx_query_version(", @@ -1555,7 +1556,7 @@ "xcb-render": { "label": "XCB render", "emitIf": "features.xcb", - "condition": "!features.system-xcb || libs.xcb_render", + "condition": "!features.system-xcb || (libs.xcb_render && libs.xcb_renderutil)", "output": [ "privateFeature" ] }, "xkb": { diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index ba9a3e68ee..e446933dac 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -47,13 +47,7 @@ #include #if QT_CONFIG(xcb_render) #include -// 'template' is used as a function argument name in xcb_renderutil.h -#define template template_param -// extern "C" is missing too -extern "C" { #include -} -#undef template #endif #include diff --git a/src/plugins/platforms/xcb/qxcbimage.cpp b/src/plugins/platforms/xcb/qxcbimage.cpp index 44c7d22344..31c24f40b4 100644 --- a/src/plugins/platforms/xcb/qxcbimage.cpp +++ b/src/plugins/platforms/xcb/qxcbimage.cpp @@ -44,13 +44,7 @@ #include #if QT_CONFIG(xcb_render) #include -// 'template' is used as a function argument name in xcb_renderutil.h -#define template template_param -// extern "C" is missing too -extern "C" { #include -} -#undef template #endif #include "qxcbconnection.h" diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro index f4ca9cc81d..1369d3496e 100644 --- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro +++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro @@ -97,7 +97,7 @@ qtConfig(vulkan) { !qtConfig(system-xcb) { QMAKE_USE += xcb-static } else { - qtConfig(xcb-render): QMAKE_USE += xcb_render + qtConfig(xcb-render): QMAKE_USE += xcb_render xcb_renderutil qtConfig(xcb-xinput): QMAKE_USE += xcb_xinput QMAKE_USE += xcb_icccm xcb_image xcb_keysyms xcb_randr xcb_shape xcb_shm xcb_sync xcb_xfixes xcb_xinerama } From 7d8fe4d98fc5e05f60a91649f208b92d622a4eac Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Thu, 27 Dec 2018 01:10:29 +0100 Subject: [PATCH 0759/1650] configure: make xcb-render a hard dependency for xcb plugin Its been available by default since at least libxcb 1.5, and in Qt 5.12 we have even increased the minimal required libxcb version to 1.9. Having configure switches for extensions is a legacy from Qt 4. There are still few exceptions in Qt5, where the reason is that we have to support Linux distributions that don't ship recent enough libxcb. Task-number: QTBUG-30939 Change-Id: I0a02d93b6411119ec018b0cb8fe5c63beeab62ee Reviewed-by: Oswald Buddenhagen Reviewed-by: Allan Sandfeld Jensen --- src/gui/configure.json | 42 +++++++------------ .../platforms/xcb/qxcbbackingstore.cpp | 12 ------ src/plugins/platforms/xcb/qxcbbackingstore.h | 3 +- .../platforms/xcb/qxcbconnection_basic.cpp | 10 +---- src/plugins/platforms/xcb/qxcbcursor.cpp | 4 -- src/plugins/platforms/xcb/qxcbimage.cpp | 11 +---- src/plugins/platforms/xcb/xcb_qpa_lib.pro | 5 ++- 7 files changed, 23 insertions(+), 64 deletions(-) diff --git a/src/gui/configure.json b/src/gui/configure.json index 7b861c80fe..3af7d2d49d 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -617,11 +617,6 @@ }, "xcb_renderutil": { "label": "XCB Renderutil >= 0.3.9", - "test": { - "main": [ - "xcb_render_util_find_standard_format(nullptr, XCB_PICT_STANDARD_ARGB_32);" - ] - }, "headers": "xcb/xcb_renderutil.h", "sources": [ { "type": "pkgConfig", "args": "xcb-renderutil >= 0.3.9" }, @@ -717,17 +712,6 @@ }, "xcb_render": { "label": "XCB XRender", - "test": { - "main": [ - "xcb_generic_error_t *error = 0;", - "xcb_connection_t *connection = 0;", - "xcb_render_query_pict_formats_cookie_t formatsCookie =", - " xcb_render_query_pict_formats(connection);", - "xcb_render_query_pict_formats_reply_t *formatsReply =", - " xcb_render_query_pict_formats_reply(", - " connection, formatsCookie, &error);" - ] - }, "headers": "xcb/render.h", "sources": [ { "type": "pkgConfig", "args": "xcb-render" }, @@ -1075,19 +1059,31 @@ "xcb/xcb_image.h", "xcb/xcb_keysyms.h", "xcb/randr.h", + "xcb/render.h", "xcb/shape.h", "xcb/shm.h", "xcb/sync.h", "xcb/xfixes.h", "xcb/xinerama.h", - "xcb/xcb_icccm.h" + "xcb/xcb_icccm.h", + "xcb/xcb_renderutil.h" ], "main": [ "int primaryScreen = 0;", - "(void) xcb_connect(\"\", &primaryScreen);" + "xcb_connection_t *c = xcb_connect(\"\", &primaryScreen);", + + "/* RENDER */", + "xcb_generic_error_t *error = nullptr;", + "xcb_render_query_pict_formats_cookie_t formatsCookie =", + " xcb_render_query_pict_formats(c);", + "xcb_render_query_pict_formats_reply_t *formatsReply =", + " xcb_render_query_pict_formats_reply(c, formatsCookie, &error);", + + "/* RENDERUTIL: xcb_renderutil.h include won't compile unless version >= 0.3.9 */", + "xcb_render_util_find_standard_format(nullptr, XCB_PICT_STANDARD_ARGB_32);" ] }, - "use": "xcb_icccm xcb_image xcb_keysyms xcb_randr xcb_shape xcb_shm xcb_sync xcb_xfixes xcb_xinerama xcb" + "use": "xcb_icccm xcb_image xcb_keysyms xcb_randr xcb_render xcb_renderutil xcb_shape xcb_shm xcb_sync xcb_xfixes xcb_xinerama xcb" }, "x11prefix": { "label": "X11 prefix", @@ -1553,12 +1549,6 @@ "condition": "features.xcb-native-painting", "output": [ "privateFeature" ] }, - "xcb-render": { - "label": "XCB render", - "emitIf": "features.xcb", - "condition": "!features.system-xcb || (libs.xcb_render && libs.xcb_renderutil)", - "output": [ "privateFeature" ] - }, "xkb": { "label": "XCB XKB", "emitIf": "features.xcb", @@ -1943,7 +1933,7 @@ QMAKE_LIBDIR_OPENGL[_ES2] and QMAKE_LIBS_OPENGL[_ES2] in the mkspec for your pla "section": "X11", "condition": "features.xcb", "entries": [ - "system-xcb", "egl_x11", "xkb", "xlib", "xcb-render", "xcb-glx", "xcb-xinput", "xcb-xlib", "xcb-native-painting" + "system-xcb", "egl_x11", "xkb", "xlib", "xcb-glx", "xcb-xinput", "xcb-xlib", "xcb-native-painting" ] }, { diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index e446933dac..f9240a45cc 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -45,10 +45,8 @@ #include #include -#if QT_CONFIG(xcb_render) #include #include -#endif #include #include @@ -956,16 +954,13 @@ QXcbSystemTrayBackingStore::QXcbSystemTrayBackingStore(QWindow *window) if (depth != 32) { platformWindow->setParentRelativeBackPixmap(); -#if QT_CONFIG(xcb_render) initXRenderMode(); -#endif m_useGrabbedBackgound = !m_usingXRenderMode; } } QXcbSystemTrayBackingStore::~QXcbSystemTrayBackingStore() { -#if QT_CONFIG(xcb_render) if (m_xrenderPicture) { xcb_render_free_picture(xcb_connection(), m_xrenderPicture); m_xrenderPicture = XCB_NONE; @@ -978,7 +973,6 @@ QXcbSystemTrayBackingStore::~QXcbSystemTrayBackingStore() xcb_render_free_picture(xcb_connection(), m_windowPicture); m_windowPicture = XCB_NONE; } -#endif // QT_CONFIG(xcb_render) } void QXcbSystemTrayBackingStore::beginPaint(const QRegion ®ion) @@ -1000,7 +994,6 @@ void QXcbSystemTrayBackingStore::render(xcb_window_t window, const QRegion ®i return; } -#if QT_CONFIG(xcb_render) m_image->put(m_xrenderPixmap, region, offset); const QRect bounds = region.boundingRect(); const QPoint target = bounds.topLeft(); @@ -1011,7 +1004,6 @@ void QXcbSystemTrayBackingStore::render(xcb_window_t window, const QRegion ®i m_xrenderPicture, 0, m_windowPicture, target.x(), target.y(), 0, 0, target.x(), target.y(), source.width(), source.height()); -#endif // QT_CONFIG(xcb_render) } void QXcbSystemTrayBackingStore::recreateImage(QXcbWindow *win, const QSize &size) @@ -1028,7 +1020,6 @@ void QXcbSystemTrayBackingStore::recreateImage(QXcbWindow *win, const QSize &siz return; } -#if QT_CONFIG(xcb_render) if (m_xrenderPicture) { xcb_render_free_picture(xcb_connection(), m_xrenderPicture); m_xrenderPicture = XCB_NONE; @@ -1051,10 +1042,8 @@ void QXcbSystemTrayBackingStore::recreateImage(QXcbWindow *win, const QSize &siz m_image->resize(size); else m_image = new QXcbBackingStoreImage(this, size, 32, QImage::Format_ARGB32_Premultiplied); -#endif // QT_CONFIG(xcb_render) } -#if QT_CONFIG(xcb_render) void QXcbSystemTrayBackingStore::initXRenderMode() { if (!connection()->hasXRender()) @@ -1098,6 +1087,5 @@ void QXcbSystemTrayBackingStore::initXRenderMode() m_usingXRenderMode = true; } -#endif // QT_CONFIG(xcb_render) QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.h b/src/plugins/platforms/xcb/qxcbbackingstore.h index b91e5c7dc2..0c30929d4e 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.h +++ b/src/plugins/platforms/xcb/qxcbbackingstore.h @@ -99,14 +99,13 @@ protected: void recreateImage(QXcbWindow *win, const QSize &size) override; private: -#if QT_CONFIG(xcb_render) void initXRenderMode(); xcb_pixmap_t m_xrenderPixmap = XCB_NONE; xcb_render_picture_t m_xrenderPicture = XCB_NONE; xcb_render_pictformat_t m_xrenderPictFormat = XCB_NONE; xcb_render_picture_t m_windowPicture = XCB_NONE; -#endif + bool m_usingXRenderMode = false; bool m_useGrabbedBackgound = false; QPixmap m_grabbedBackground; diff --git a/src/plugins/platforms/xcb/qxcbconnection_basic.cpp b/src/plugins/platforms/xcb/qxcbconnection_basic.cpp index b8335d1240..c69912c361 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_basic.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_basic.cpp @@ -44,12 +44,10 @@ #include #include #include +#include #if QT_CONFIG(xcb_xinput) #include #endif -#if QT_CONFIG(xcb_render) -#include -#endif #if QT_CONFIG(xkb) #define explicit dont_use_cxx_explicit #include @@ -139,12 +137,10 @@ QXcbBasicConnection::QXcbBasicConnection(const char *displayName) xcb_extension_t *extensions[] = { &xcb_shm_id, &xcb_xfixes_id, &xcb_randr_id, &xcb_shape_id, &xcb_sync_id, + &xcb_render_id, #if QT_CONFIG(xkb) &xcb_xkb_id, #endif -#if QT_CONFIG(xcb_render) - &xcb_render_id, -#endif #if QT_CONFIG(xcb_xinput) &xcb_input_id, #endif @@ -293,7 +289,6 @@ void QXcbBasicConnection::initializeShm() void QXcbBasicConnection::initializeXRandr() { -#if QT_CONFIG(xcb_render) const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_xcbConnection, &xcb_render_id); if (!reply || !reply->present) { qCDebug(lcQpaXcb, "XRender extension not present on the X server"); @@ -311,7 +306,6 @@ void QXcbBasicConnection::initializeXRandr() m_hasXRandr = true; m_xrenderVersion.first = xrenderQuery->major_version; m_xrenderVersion.second = xrenderQuery->minor_version; -#endif } void QXcbBasicConnection::initializeXinerama() diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp index 7831671d42..fbadab4d50 100644 --- a/src/plugins/platforms/xcb/qxcbcursor.cpp +++ b/src/plugins/platforms/xcb/qxcbcursor.cpp @@ -607,14 +607,10 @@ xcb_cursor_t QXcbCursor::createBitmapCursor(QCursor *cursor) QPoint spot = cursor->hotSpot(); xcb_cursor_t c = XCB_NONE; if (cursor->pixmap().depth() > 1) { -#if QT_CONFIG(xcb_render) if (connection()->hasXRender(0, 5)) c = qt_xcb_createCursorXRender(m_screen, cursor->pixmap().toImage(), spot); else qCWarning(lcQpaXcb, "xrender >= 0.5 required to create pixmap cursors"); -#else - qCWarning(lcQpaXcb, "This build of Qt does not support pixmap cursors"); -#endif } else { xcb_connection_t *conn = xcb_connection(); xcb_pixmap_t cp = qt_xcb_XPixmapFromBitmap(m_screen, cursor->bitmap()->toImage()); diff --git a/src/plugins/platforms/xcb/qxcbimage.cpp b/src/plugins/platforms/xcb/qxcbimage.cpp index 31c24f40b4..8f33e6ed31 100644 --- a/src/plugins/platforms/xcb/qxcbimage.cpp +++ b/src/plugins/platforms/xcb/qxcbimage.cpp @@ -42,10 +42,9 @@ #include #include #include -#if QT_CONFIG(xcb_render) + #include #include -#endif #include "qxcbconnection.h" #include "qxcbintegration.h" @@ -230,7 +229,6 @@ xcb_pixmap_t qt_xcb_XPixmapFromBitmap(QXcbScreen *screen, const QImage &image) xcb_cursor_t qt_xcb_createCursorXRender(QXcbScreen *screen, const QImage &image, const QPoint &spot) { -#if QT_CONFIG(xcb_render) xcb_connection_t *conn = screen->xcb_connection(); const int w = image.width(); const int h = image.height(); @@ -283,13 +281,6 @@ xcb_cursor_t qt_xcb_createCursorXRender(QXcbScreen *screen, const QImage &image, xcb_render_free_picture(conn, pic); xcb_free_pixmap(conn, pix); return cursor; - -#else - Q_UNUSED(screen); - Q_UNUSED(image); - Q_UNUSED(spot); - return XCB_NONE; -#endif } QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro index 1369d3496e..647058167b 100644 --- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro +++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro @@ -97,9 +97,10 @@ qtConfig(vulkan) { !qtConfig(system-xcb) { QMAKE_USE += xcb-static } else { - qtConfig(xcb-render): QMAKE_USE += xcb_render xcb_renderutil qtConfig(xcb-xinput): QMAKE_USE += xcb_xinput - QMAKE_USE += xcb_icccm xcb_image xcb_keysyms xcb_randr xcb_shape xcb_shm xcb_sync xcb_xfixes xcb_xinerama + QMAKE_USE += \ + xcb_icccm xcb_image xcb_keysyms xcb_randr xcb_render xcb_renderutil \ + xcb_shape xcb_shm xcb_sync xcb_xfixes xcb_xinerama } QMAKE_USE += xcb From 0decdcb754dbbd42769ede69eb32c17ea05f4d8c Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Fri, 28 Dec 2018 23:43:18 +0100 Subject: [PATCH 0760/1650] configure: add X11 subsection in "Features used by QPA backends" xcb-xlib is used by XCB and EGLFS_X11. xlib is used by XCB, EGLFS_X11 and offscreen plugin (not listed currently under "QPA backends"). egl_x11 is used by XCB GL integration plugin and EGLFS_X11. Renamed X11 -> XCB under "QPA backends", because that is the correct QPA name. Change-Id: I455ac3a41da3ab84453d8de0edc657c3a5e064c9 Reviewed-by: Oswald Buddenhagen --- src/gui/configure.json | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/gui/configure.json b/src/gui/configure.json index 3af7d2d49d..f33f34ec60 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -1902,7 +1902,15 @@ QMAKE_LIBDIR_OPENGL[_ES2] and QMAKE_LIBS_OPENGL[_ES2] in the mkspec for your pla "integrityhid", "mtdev", "tslib", - "xkbcommon" + "xkbcommon", + { + "section": "X11 specific", + "entries": [ + "xlib", + "xcb-xlib", + "egl_x11" + ] + } ] }, { @@ -1930,10 +1938,10 @@ QMAKE_LIBDIR_OPENGL[_ES2] and QMAKE_LIBS_OPENGL[_ES2] in the mkspec for your pla ] }, { - "section": "X11", + "section": "XCB", "condition": "features.xcb", "entries": [ - "system-xcb", "egl_x11", "xkb", "xlib", "xcb-glx", "xcb-xinput", "xcb-xlib", "xcb-native-painting" + "system-xcb", "xkb", "xcb-xinput", "xcb-glx", "xcb-native-painting" ] }, { From dd988e2074fa8d7d230b14ab997bcfc86dc6e1a4 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Thu, 27 Dec 2018 01:10:29 +0100 Subject: [PATCH 0761/1650] configure: add XCB GL integration features This way Qt builders can see if everything has been configured properly for XCB GL integrations at configure time, instead of at the end of the build process. Change-Id: I00740cc2edd7f6ecfcda0ddfb22649d1b4db4aa2 Reviewed-by: Oswald Buddenhagen --- src/gui/configure.json | 26 ++++++++++++++++--- .../xcb/gl_integrations/gl_integrations.pro | 4 +-- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/gui/configure.json b/src/gui/configure.json index f33f34ec60..582705f402 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -1531,12 +1531,24 @@ "emitIf": "features.xcb", "output": [ { "type": "varAssign", "name": "QMAKE_X11_PREFIX", "value": "tests.x11prefix.value" } ] }, - "xcb-glx": { - "label": "XCB GLX", + "xcb-glx-plugin": { + "label": "GLX Plugin", "emitIf": "features.xcb", + "condition": "features.xcb-xlib && features.opengl && !features.opengles2", + "output": [ "privateFeature" ] + }, + "xcb-glx": { + "label": " XCB GLX", + "emitIf": "features.xcb && features.xcb-glx-plugin", "condition": "libs.xcb_glx", "output": [ "privateFeature" ] }, + "xcb-egl-plugin": { + "label": "EGL-X11 Plugin", + "emitIf": "features.xcb", + "condition": "features.egl_x11 && features.opengl", + "output": [ "privateFeature" ] + }, "xcb-native-painting": { "label": "Native painting (experimental)", "emitIf": "features.xcb", @@ -1941,7 +1953,15 @@ QMAKE_LIBDIR_OPENGL[_ES2] and QMAKE_LIBS_OPENGL[_ES2] in the mkspec for your pla "section": "XCB", "condition": "features.xcb", "entries": [ - "system-xcb", "xkb", "xcb-xinput", "xcb-glx", "xcb-native-painting" + "system-xcb", "xkb", "xcb-xinput", "xcb-native-painting", + { + "section": "GL integrations", + "entries": [ + "xcb-glx-plugin", + "xcb-glx", + "xcb-egl-plugin" + ] + } ] }, { diff --git a/src/plugins/platforms/xcb/gl_integrations/gl_integrations.pro b/src/plugins/platforms/xcb/gl_integrations/gl_integrations.pro index b8f878ffe8..dde176433c 100644 --- a/src/plugins/platforms/xcb/gl_integrations/gl_integrations.pro +++ b/src/plugins/platforms/xcb/gl_integrations/gl_integrations.pro @@ -1,10 +1,10 @@ TEMPLATE = subdirs QT_FOR_CONFIG += gui-private -qtConfig(egl):qtConfig(egl_x11):qtConfig(opengl) { +qtConfig(xcb-egl-plugin) { SUBDIRS += xcb_egl } -qtConfig(xcb-xlib):qtConfig(opengl):!qtConfig(opengles2) { +qtConfig(xcb-glx-plugin) { SUBDIRS += xcb_glx } From 7ca39bf7bcfaca46463d41b25441127909bbdd82 Mon Sep 17 00:00:00 2001 From: Samuel Gaist Date: Wed, 12 Dec 2018 12:18:10 +0100 Subject: [PATCH 0762/1650] Doc: cleanup semaphore example This patch removes unused signal and variable. Change-Id: Ia4eaf083493d3d37e3ff22e0380d5a5ee69f91cf Reviewed-by: Paul Wicking Reviewed-by: Sze Howe Koh --- examples/corelib/threads/semaphores/semaphores.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/examples/corelib/threads/semaphores/semaphores.cpp b/examples/corelib/threads/semaphores/semaphores.cpp index 145624bb0b..a245b9906b 100644 --- a/examples/corelib/threads/semaphores/semaphores.cpp +++ b/examples/corelib/threads/semaphores/semaphores.cpp @@ -94,12 +94,6 @@ public: } fprintf(stderr, "\n"); } - -signals: - void stringConsumed(const QString &text); - -protected: - bool finish; }; //! [4] From 1606a8aa1c8ab2bce4009ba34a854cd83ddf39e0 Mon Sep 17 00:00:00 2001 From: Samuel Gaist Date: Wed, 2 Jan 2019 13:44:13 +0100 Subject: [PATCH 0763/1650] Doc: fix typo in QAbstractSocket::bind documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: QTBUG-72780 Change-Id: I16d89d29f573dba37ed8e1986ed9677117ca6aad Reviewed-by: André Hartmann Reviewed-by: Paul Wicking Reviewed-by: Topi Reiniö --- src/network/socket/qabstractsocket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 2f93c5fa2b..e86793cb21 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -1549,7 +1549,7 @@ void QAbstractSocket::setPauseMode(PauseModes pauseMode) By default, the socket is bound using the DefaultForPlatform BindMode. If a port is not specified, a random port is chosen. - On success, the functions returns \c true and the socket enters + On success, the function returns \c true and the socket enters BoundState; otherwise it returns \c false. */ From 9682d217e21a2e88b6de799d79b843bbe0039df1 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Fri, 21 Dec 2018 14:59:43 +0100 Subject: [PATCH 0764/1650] QImage::create fail if given an empty size Previously valid but empty sizes i.e. QSize(0, 131073) where accepted, but such sizes make no sense for an image since they actually contain no pixels Change-Id: Ie61e33401ad8aaea633646c66fc03f36793e839c Reviewed-by: Eirik Aavitsland --- src/gui/image/qimage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index b6d93331e6..4c00c7705a 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -117,7 +117,7 @@ QImageData::QImageData() */ QImageData * QImageData::create(const QSize &size, QImage::Format format) { - if (!size.isValid() || format == QImage::Format_Invalid) + if (size.isEmpty() || format == QImage::Format_Invalid) return nullptr; // invalid parameter(s) int width = size.width(); From df27484fc0349bb060e023ac2dce246c1176d838 Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Wed, 19 Dec 2018 20:57:25 +0100 Subject: [PATCH 0765/1650] Windows QPA: Fix mouse pointer capture and Enter/Leave events Qt expects the platform plugin to capture the mouse on any button press and keep it captured until buttons are released. The missing capture logic was causing extra Enter/Leave events to be generated. Change-Id: I5a78ea600374701c740f395b38ba5abd51f561d8 Fixes: QTBUG-72600 Reviewed-by: Friedemann Kleint --- .../windows/qwindowspointerhandler.cpp | 183 +++++++++++++----- .../windows/qwindowspointerhandler.h | 4 + 2 files changed, 136 insertions(+), 51 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp index 78a8083d5b..be67eb0248 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp @@ -54,7 +54,6 @@ # include "qwindowsdrag.h" #endif -#include #include #include #include @@ -370,6 +369,22 @@ static Qt::MouseButtons mouseButtonsFromPointerFlags(POINTER_FLAGS pointerFlags) return result; } +static Qt::MouseButtons mouseButtonsFromKeyState(WPARAM keyState) +{ + Qt::MouseButtons result = Qt::NoButton; + if (keyState & MK_LBUTTON) + result |= Qt::LeftButton; + if (keyState & MK_RBUTTON) + result |= Qt::RightButton; + if (keyState & MK_MBUTTON) + result |= Qt::MiddleButton; + if (keyState & MK_XBUTTON1) + result |= Qt::XButton1; + if (keyState & MK_XBUTTON2) + result |= Qt::XButton2; + return result; +} + static QWindow *getWindowUnderPointer(QWindow *window, QPoint globalPos) { QWindow *currentWindowUnderPointer = QWindowsScreen::windowAt(globalPos, CWP_SKIPINVISIBLE | CWP_SKIPTRANSPARENT); @@ -411,6 +426,15 @@ static bool isValidWheelReceiver(QWindow *candidate) return false; } +static bool isMenuWindow(QWindow *window) +{ + if (window) + if (QObject *fo = window->focusObject()) + if (fo->inherits("QMenu")) + return true; + return false; +} + static QTouchDevice *createTouchDevice() { const int digitizers = GetSystemMetrics(SM_DIGITIZER); @@ -439,6 +463,103 @@ QTouchDevice *QWindowsPointerHandler::ensureTouchDevice() return m_touchDevice; } +void QWindowsPointerHandler::handleCaptureRelease(QWindow *window, + QWindow *currentWindowUnderPointer, + HWND hwnd, + QEvent::Type eventType, + Qt::MouseButtons mouseButtons) +{ + QWindowsWindow *platformWindow = static_cast(window->handle()); + + // Qt expects the platform plugin to capture the mouse on any button press until release. + if (!platformWindow->hasMouseCapture() && eventType == QEvent::MouseButtonPress) { + + platformWindow->setMouseGrabEnabled(true); + platformWindow->setFlag(QWindowsWindow::AutoMouseCapture); + qCDebug(lcQpaEvents) << "Automatic mouse capture " << window; + + // Implement "Click to focus" for native child windows (unless it is a native widget window). + if (!window->isTopLevel() && !window->inherits("QWidgetWindow") && QGuiApplication::focusWindow() != window) + window->requestActivate(); + + } else if (platformWindow->hasMouseCapture() + && platformWindow->testFlag(QWindowsWindow::AutoMouseCapture) + && eventType == QEvent::MouseButtonRelease + && !mouseButtons) { + + platformWindow->setMouseGrabEnabled(false); + qCDebug(lcQpaEvents) << "Releasing automatic mouse capture " << window; + } + + // Enter new window: track to generate leave event. + // If there is an active capture, only track if the current window is capturing, + // so we don't get extra leave when cursor leaves the application. + if (window != m_currentWindow && + (!platformWindow->hasMouseCapture() || currentWindowUnderPointer == window)) { + trackLeave(hwnd); + m_currentWindow = window; + } +} + +void QWindowsPointerHandler::handleEnterLeave(QWindow *window, + QWindow *currentWindowUnderPointer, + QPoint globalPos) +{ + QWindowsWindow *platformWindow = static_cast(window->handle()); + const bool hasCapture = platformWindow->hasMouseCapture(); + + // No enter or leave events are sent as long as there is an autocapturing window. + if (!hasCapture || !platformWindow->testFlag(QWindowsWindow::AutoMouseCapture)) { + + // Leave is needed if: + // 1) There is no capture and we move from a window to another window. + // Note: Leaving the application entirely is handled in translateMouseEvent(WM_MOUSELEAVE). + // 2) There is capture and we move out of the capturing window. + // 3) There is a new capture and we were over another window. + if ((m_windowUnderPointer && m_windowUnderPointer != currentWindowUnderPointer + && (!hasCapture || window == m_windowUnderPointer)) + || (hasCapture && m_previousCaptureWindow != window && m_windowUnderPointer + && m_windowUnderPointer != window)) { + + qCDebug(lcQpaEvents) << "Leaving window " << m_windowUnderPointer; + QWindowSystemInterface::handleLeaveEvent(m_windowUnderPointer); + + if (hasCapture && currentWindowUnderPointer != window) { + // Clear tracking if capturing and current window is not the capturing window + // to avoid leave when mouse actually leaves the application. + m_currentWindow = nullptr; + // We are not officially in any window, but we need to set some cursor to clear + // whatever cursor the left window had, so apply the cursor of the capture window. + platformWindow->applyCursor(); + } + } + + // Enter is needed if: + // 1) There is no capture and we move to a new window. + // 2) There is capture and we move into the capturing window. + // 3) The capture just ended and we are over non-capturing window. + if ((currentWindowUnderPointer && m_windowUnderPointer != currentWindowUnderPointer + && (!hasCapture || currentWindowUnderPointer == window)) + || (m_previousCaptureWindow && !hasCapture && currentWindowUnderPointer + && currentWindowUnderPointer != m_previousCaptureWindow)) { + + QPoint wumLocalPos; + if (QWindowsWindow *wumPlatformWindow = QWindowsWindow::windowsWindowOf(currentWindowUnderPointer)) { + wumLocalPos = wumPlatformWindow->mapFromGlobal(globalPos); + wumPlatformWindow->applyCursor(); + } + qCDebug(lcQpaEvents) << "Entering window " << currentWindowUnderPointer; + QWindowSystemInterface::handleEnterEvent(currentWindowUnderPointer, wumLocalPos, globalPos); + } + + // We need to track m_windowUnderPointer separately from m_currentWindow, as Windows + // mouse tracking will not trigger WM_MOUSELEAVE for leaving window when mouse capture is set. + m_windowUnderPointer = currentWindowUnderPointer; + } + + m_previousCaptureWindow = hasCapture ? window : nullptr; +} + bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, PVOID vPointerInfo) @@ -448,9 +569,7 @@ bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND h const QPoint localPos = QWindowsGeometryHint::mapFromGlobal(hwnd, globalPos); const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers(); const Qt::MouseButtons mouseButtons = mouseButtonsFromPointerFlags(pointerInfo->pointerFlags); - QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos); - QWindowsWindow *platformWindow = static_cast(window->handle()); switch (msg.message) { case WM_NCPOINTERDOWN: @@ -469,38 +588,17 @@ bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND h keyModifiers, Qt::MouseEventNotSynthesized); return false; // To allow window dragging, etc. } else { - if (eventType == QEvent::MouseButtonPress) { - // Implement "Click to focus" for native child windows (unless it is a native widget window). - if (!window->isTopLevel() && !window->inherits("QWidgetWindow") && QGuiApplication::focusWindow() != window) - window->requestActivate(); - } - if (currentWindowUnderPointer != m_windowUnderPointer) { - if (m_windowUnderPointer && m_windowUnderPointer == m_currentWindow) { - QWindowSystemInterface::handleLeaveEvent(m_windowUnderPointer); - m_currentWindow = nullptr; - } - if (currentWindowUnderPointer) { - if (currentWindowUnderPointer != m_currentWindow) { - QWindowSystemInterface::handleEnterEvent(currentWindowUnderPointer, localPos, globalPos); - m_currentWindow = currentWindowUnderPointer; - if (QWindowsWindow *wumPlatformWindow = QWindowsWindow::windowsWindowOf(currentWindowUnderPointer)) - wumPlatformWindow->applyCursor(); - trackLeave(hwnd); - } - } else { - platformWindow->applyCursor(); - } - m_windowUnderPointer = currentWindowUnderPointer; - } + handleCaptureRelease(window, currentWindowUnderPointer, hwnd, eventType, mouseButtons); + handleEnterLeave(window, currentWindowUnderPointer, globalPos); QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos, mouseButtons, button, eventType, keyModifiers, Qt::MouseEventNotSynthesized); // The initial down click over the QSizeGrip area, which posts a resize WM_SYSCOMMAND // has go to through DefWindowProc() for resizing to work, so we return false here, - // unless the mouse is captured, as it would mess with menu processing. - return msg.message != WM_POINTERDOWN || GetCapture(); + // unless the click was on a menu, as it would mess with menu processing. + return msg.message != WM_POINTERDOWN || isMenuWindow(window); } } case WM_POINTERHWHEEL: @@ -770,7 +868,6 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtW } const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers(); - QWindowsWindow *platformWindow = static_cast(window->handle()); if (et == QtWindows::MouseWheelEvent) { @@ -792,36 +889,20 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtW if (msg.message == WM_MOUSELEAVE) { if (window == m_currentWindow) { - QWindowSystemInterface::handleLeaveEvent(window); + QWindow *leaveTarget = m_windowUnderPointer ? m_windowUnderPointer : m_currentWindow; + qCDebug(lcQpaEvents) << "Leaving window " << leaveTarget; + QWindowSystemInterface::handleLeaveEvent(leaveTarget); m_windowUnderPointer = nullptr; m_currentWindow = nullptr; - platformWindow->applyCursor(); } return false; } QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos); + const Qt::MouseButtons mouseButtons = mouseButtonsFromKeyState(msg.wParam); - if (currentWindowUnderPointer != m_windowUnderPointer) { - if (m_windowUnderPointer && m_windowUnderPointer == m_currentWindow) { - QWindowSystemInterface::handleLeaveEvent(m_windowUnderPointer); - m_currentWindow = nullptr; - } - - if (currentWindowUnderPointer) { - if (currentWindowUnderPointer != m_currentWindow) { - QWindowSystemInterface::handleEnterEvent(currentWindowUnderPointer, localPos, globalPos); - m_currentWindow = currentWindowUnderPointer; - if (QWindowsWindow *wumPlatformWindow = QWindowsWindow::windowsWindowOf(currentWindowUnderPointer)) - wumPlatformWindow->applyCursor(); - trackLeave(hwnd); - } - } else { - platformWindow->applyCursor(); - } - m_windowUnderPointer = currentWindowUnderPointer; - } - + handleCaptureRelease(window, currentWindowUnderPointer, hwnd, QEvent::MouseMove, mouseButtons); + handleEnterLeave(window, currentWindowUnderPointer, globalPos); return false; } diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.h b/src/plugins/platforms/windows/qwindowspointerhandler.h index 3861ebf919..a586c7863c 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.h +++ b/src/plugins/platforms/windows/qwindowspointerhandler.h @@ -46,6 +46,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -68,11 +69,14 @@ private: bool translateMouseTouchPadEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, PVOID vPointerInfo); bool translateTouchEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, PVOID vTouchInfo, unsigned int count); bool translatePenEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, PVOID vPenInfo); + void handleCaptureRelease(QWindow *window, QWindow *currentWindowUnderPointer, HWND hwnd, QEvent::Type eventType, Qt::MouseButtons mouseButtons); + void handleEnterLeave(QWindow *window, QWindow *currentWindowUnderPointer, QPoint globalPos); QTouchDevice *m_touchDevice = nullptr; QHash m_lastTouchPositions; QPointer m_windowUnderPointer; QPointer m_currentWindow; + QWindow *m_previousCaptureWindow = nullptr; bool m_needsEnterOnPointerUpdate = false; }; From d8bbb5ee0e60d44a70d29306e607a59caf7fe5bc Mon Sep 17 00:00:00 2001 From: Vitaly Fanaskov Date: Fri, 7 Dec 2018 16:04:33 +0100 Subject: [PATCH 0766/1650] Respect roles of buttons added to QMessageBox MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a button added to QMessageBox has AcceptRole or YesRole, the signal accepted() will be emitted upon click on the button. If the button has RejectRole or NoRole, the signal rejected() will be emitted upon click on the button. If a button has a different role, neither accepted() nor rejected() will be emitted. This works for both standard and custom buttons. The signal finished() with result code will be sent regardless of a clicked button role. Also added documentation strings for some methods of private classes in order to have better tooltips in IDE(s). Task-number: QTBUG-44131 Change-Id: I521a4e5112eb4cf168f6fbb4c002dbe119aeeb09 Reviewed-by: Tor Arne Vestbø --- src/widgets/dialogs/qdialog.cpp | 48 +++++++--- src/widgets/dialogs/qdialog_p.h | 3 + src/widgets/dialogs/qmessagebox.cpp | 42 +++++++- .../dialogs/qmessagebox/tst_qmessagebox.cpp | 95 +++++++++++++++++++ 4 files changed, 173 insertions(+), 15 deletions(-) diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp index 6f96018f3e..1fb5e61301 100644 --- a/src/widgets/dialogs/qdialog.cpp +++ b/src/widgets/dialogs/qdialog.cpp @@ -145,6 +145,41 @@ bool QDialogPrivate::canBeNativeDialog() const return false; } +/*! + \internal + + Properly hides dialog and sets the \p resultCode + */ +void QDialogPrivate::hide(int resultCode) +{ + Q_Q(QDialog); + + q->setResult(resultCode); + q->hide(); + + close_helper(QWidgetPrivate::CloseNoEvent); + resetModalitySetByOpen(); +} + +/*! + \internal + + Emits finished() signal with \p resultCode. If the \p dialogCode + is equal to 0 emits rejected(), if the \p dialogCode is equal to + 1 emits accepted(). + */ +void QDialogPrivate::finalize(int resultCode, int dialogCode) +{ + Q_Q(QDialog); + + if (dialogCode == QDialog::Accepted) + emit q->accepted(); + else if (dialogCode == QDialog::Rejected) + emit q->rejected(); + + emit q->finished(resultCode); +} + QWindow *QDialogPrivate::transientParentWindow() const { Q_Q(const QDialog); @@ -593,17 +628,8 @@ int QDialog::exec() void QDialog::done(int r) { Q_D(QDialog); - setResult(r); - hide(); - - d->close_helper(QWidgetPrivate::CloseNoEvent); - d->resetModalitySetByOpen(); - - emit finished(r); - if (r == Accepted) - emit accepted(); - else if (r == Rejected) - emit rejected(); + d->hide(r); + d->finalize(r, r); } /*! diff --git a/src/widgets/dialogs/qdialog_p.h b/src/widgets/dialogs/qdialog_p.h index b1de56188c..92634f6793 100644 --- a/src/widgets/dialogs/qdialog_p.h +++ b/src/widgets/dialogs/qdialog_p.h @@ -122,6 +122,9 @@ public: QPlatformDialogHelper *platformHelper() const; virtual bool canBeNativeDialog() const; + void hide(int resultCode); + void finalize(int resultCode, int dialogCode); + private: virtual void initHelper(QPlatformDialogHelper *) {} virtual void helperPrepareShow(QPlatformDialogHelper *) {} diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index ffbbe82856..ce918b8a74 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -209,6 +209,7 @@ public: void setupLayout(); void _q_buttonClicked(QAbstractButton *); void _q_clicked(QPlatformDialogHelper::StandardButton button, QPlatformDialogHelper::ButtonRole role); + void setClickedButton(QAbstractButton *button); QAbstractButton *findButton(int button0, int button1, int button2, int flags); void addOldButtons(int button0, int button1, int button2); @@ -216,6 +217,8 @@ public: QAbstractButton *abstractButtonForId(int id) const; int execReturnCode(QAbstractButton *button); + int dialogCodeForButton(QAbstractButton *button) const; + void detectEscapeButton(); void updateSize(); int layoutMinimumWidth(); @@ -466,6 +469,27 @@ int QMessageBoxPrivate::execReturnCode(QAbstractButton *button) return ret; } +/*! + \internal + + Returns 0 for RejectedRole and NoRole, 1 for AcceptedRole and YesRole, -1 otherwise + */ +int QMessageBoxPrivate::dialogCodeForButton(QAbstractButton *button) const +{ + Q_Q(const QMessageBox); + + switch (q->buttonRole(button)) { + case QMessageBox::AcceptRole: + case QMessageBox::YesRole: + return QDialog::Accepted; + case QMessageBox::RejectRole: + case QMessageBox::NoRole: + return QDialog::Rejected; + default: + return -1; + } +} + void QMessageBoxPrivate::_q_buttonClicked(QAbstractButton *button) { Q_Q(QMessageBox); @@ -477,20 +501,30 @@ void QMessageBoxPrivate::_q_buttonClicked(QAbstractButton *button) } else #endif { - clickedButton = button; - q->done(execReturnCode(button)); // does not trigger closeEvent - emit q->buttonClicked(button); + setClickedButton(button); if (receiverToDisconnectOnClose) { QObject::disconnect(q, signalToDisconnectOnClose, receiverToDisconnectOnClose, memberToDisconnectOnClose); - receiverToDisconnectOnClose = 0; + receiverToDisconnectOnClose = nullptr; } signalToDisconnectOnClose.clear(); memberToDisconnectOnClose.clear(); } } +void QMessageBoxPrivate::setClickedButton(QAbstractButton *button) +{ + Q_Q(QMessageBox); + + clickedButton = button; + emit q->buttonClicked(clickedButton); + + auto resultCode = execReturnCode(button); + hide(resultCode); + finalize(resultCode, dialogCodeForButton(button)); +} + void QMessageBoxPrivate::_q_clicked(QPlatformDialogHelper::StandardButton button, QPlatformDialogHelper::ButtonRole role) { Q_Q(QMessageBox); diff --git a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp index 3b31a74adf..eeda17074b 100644 --- a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp +++ b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp @@ -110,6 +110,10 @@ private slots: void setInformativeText(); void iconPixmap(); + // QTBUG-44131 + void acceptedRejectedSignals(); + void acceptedRejectedSignals_data(); + void cleanup(); }; @@ -717,5 +721,96 @@ void tst_QMessageBox::iconPixmap() QCOMPARE(messageBox.iconPixmap(), QPixmap()); } +using SignalSignature = void(QDialog::*)(); +Q_DECLARE_METATYPE(SignalSignature); +Q_DECLARE_METATYPE(QMessageBox::ButtonRole) + +using ButtonsCreator = std::function(QMessageBox &)>; +Q_DECLARE_METATYPE(ButtonsCreator); + +using RoleSet = QSet; +Q_DECLARE_METATYPE(RoleSet); + +void tst_QMessageBox::acceptedRejectedSignals() +{ + QMessageBox messageBox(QMessageBox::Information, "Test window", "Test text"); + + QFETCH(ButtonsCreator, buttonsCreator); + QVERIFY(buttonsCreator); + + const auto buttons = buttonsCreator(messageBox); + QVERIFY(!buttons.isEmpty()); + + QFETCH(RoleSet, roles); + QFETCH(SignalSignature, signalSignature); + for (auto button: buttons) { + QVERIFY(button); + + messageBox.show(); + QVERIFY(QTest::qWaitForWindowExposed(&messageBox)); + + QSignalSpy spy(&messageBox, signalSignature); + QVERIFY(spy.isValid()); + button->click(); + + if (roles.contains(messageBox.buttonRole(button))) + QCOMPARE(spy.count(), 1); + else + QVERIFY(spy.isEmpty()); + } +} + +static void addAcceptedRow(const char *title, ButtonsCreator bc) +{ + QTest::newRow(title) << (RoleSet() << QMessageBox::AcceptRole << QMessageBox::YesRole) + << &QDialog::accepted << bc; +} + +static void addRejectedRow(const char *title, ButtonsCreator bc) +{ + QTest::newRow(title) << (RoleSet() << QMessageBox::RejectRole << QMessageBox::NoRole) + << &QDialog::rejected << bc; +} + +static void addCustomButtonsData() +{ + ButtonsCreator buttonsCreator = [](QMessageBox &messageBox) { + QVector buttons(QMessageBox::NRoles); + for (int i = QMessageBox::AcceptRole; i < QMessageBox::NRoles; ++i) { + buttons[i] = messageBox.addButton( + QString("Button role: %1").arg(i), QMessageBox::ButtonRole(i)); + } + + return buttons; + }; + + addAcceptedRow("Accepted_CustomButtons", buttonsCreator); + addRejectedRow("Rejected_CustomButtons", buttonsCreator); +} + +static void addStandardButtonsData() +{ + ButtonsCreator buttonsCreator = [](QMessageBox &messageBox) { + QVector buttons; + for (int i = QMessageBox::FirstButton; i <= QMessageBox::LastButton; i <<= 1) + buttons << messageBox.addButton(QMessageBox::StandardButton(i)); + + return buttons; + }; + + addAcceptedRow("Accepted_StandardButtons", buttonsCreator); + addRejectedRow("Rejected_StandardButtons", buttonsCreator); +} + +void tst_QMessageBox::acceptedRejectedSignals_data() +{ + QTest::addColumn("roles"); + QTest::addColumn("signalSignature"); + QTest::addColumn("buttonsCreator"); + + addStandardButtonsData(); + addCustomButtonsData(); +} + QTEST_MAIN(tst_QMessageBox) #include "tst_qmessagebox.moc" From 88e34b0a4636de234cc37410c25f0c1032d99a89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 19 Dec 2018 22:52:23 +0100 Subject: [PATCH 0767/1650] CoreText: Fix inaccurate use of pixelSize when dealing with pointSize Change-Id: If46fa157bc921efd8145823c806b6b04f49233cf Reviewed-by: Timur Pocheptsov --- .../fontdatabases/mac/qcoretextfontdatabase.mm | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index ba23271e55..047773d8e3 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -194,7 +194,7 @@ struct FontDescription { QFont::Weight weight; QFont::Style style; QFont::Stretch stretch; - int pixelSize; + qreal pointSize; bool fixedPitch; QSupportedWritingSystems writingSystems; }; @@ -210,7 +210,7 @@ Q_DECL_UNUSED static inline QDebug operator<<(QDebug debug, const FontDescriptio << ", weight=" << fd.weight << ", style=" << fd.style << ", stretch=" << fd.stretch - << ", pixelSize=" << fd.pixelSize + << ", pointSize=" << fd.pointSize << ", fixedPitch=" << fd.fixedPitch << ", writingSystems=" << fd.writingSystems << ")"; @@ -286,9 +286,11 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd) if (CFNumberIsFloatType(size)) { double d; CFNumberGetValue(size, kCFNumberDoubleType, &d); - fd->pixelSize = d; + fd->pointSize = d; } else { - CFNumberGetValue(size, kCFNumberIntType, &fd->pixelSize); + int i; + CFNumberGetValue(size, kCFNumberIntType, &i); + fd->pointSize = i; } } @@ -316,8 +318,8 @@ void QCoreTextFontDatabase::populateFromDescriptor(CTFontDescriptorRef font, con CFRetain(font); QPlatformFontDatabase::registerFont(family, fd.styleName, fd.foundryName, fd.weight, fd.style, fd.stretch, - true /* antialiased */, true /* scalable */, - fd.pixelSize, fd.fixedPitch, fd.writingSystems, (void *) font); + true /* antialiased */, true /* scalable */, 0 /* pixelSize, ignored as font is scalable */, + fd.fixedPitch, fd.writingSystems, (void *)font); } static NSString * const kQtFontDataAttribute = @"QtFontDataAttribute"; @@ -727,7 +729,7 @@ QFont *QCoreTextFontDatabase::themeFont(QPlatformTheme::Font f) const else CFRelease(fontDesc); - QFont *font = new QFont(fd.familyName, fd.pixelSize, fd.weight, fd.style == QFont::StyleItalic); + QFont *font = new QFont(fd.familyName, fd.pointSize, fd.weight, fd.style == QFont::StyleItalic); return font; } From 4dc2bc323c985bdceb27f096dd6c8e7af657bb6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 2 Jan 2019 19:35:07 +0100 Subject: [PATCH 0768/1650] macOS: Remove Mojave forward-declarations now that we build with Xcode 10 Change-Id: I8528932f3744fbf3473219b6eeda7c26ac039b67 Reviewed-by: Timur Pocheptsov --- src/corelib/kernel/qcore_mac_objc.mm | 12 ++++-------- src/plugins/platforms/cocoa/qcocoatheme.mm | 10 ++++------ 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm index cb3539f3ec..7b78ef11be 100644 --- a/src/corelib/kernel/qcore_mac_objc.mm +++ b/src/corelib/kernel/qcore_mac_objc.mm @@ -41,12 +41,7 @@ #include #ifdef Q_OS_MACOS -# include -# if !QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14) -@interface NSApplication (MojaveForwardDeclarations) -@property (strong) NSAppearance *effectiveAppearance NS_AVAILABLE_MAC(10_14); -@end -# endif +#include #endif #if defined(QT_PLATFORM_UIKIT) @@ -174,10 +169,11 @@ QDebug operator<<(QDebug debug, const QMacAutoReleasePool *pool) #ifdef Q_OS_MACOS bool qt_mac_applicationIsInDarkMode() { +#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14) if (__builtin_available(macOS 10.14, *)) return [NSApp.effectiveAppearance.name hasSuffix:@"DarkAqua"]; - else - return false; +#endif + return false; } #endif diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm index c46df25b66..efe670abed 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.mm +++ b/src/plugins/platforms/cocoa/qcocoatheme.mm @@ -80,12 +80,7 @@ #include -#if !QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14) -@interface NSApplication (MojaveForwardDeclarations) -@property (readonly, strong) NSAppearance *effectiveAppearance NS_AVAILABLE_MAC(10_14); -@end -#endif - +#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14) @interface QT_MANGLE_NAMESPACE(QCocoaThemeAppAppearanceObserver) : NSObject @property (readonly, nonatomic) QCocoaTheme *theme; - (instancetype)initWithTheme:(QCocoaTheme *)theme; @@ -124,6 +119,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaThemeAppAppearanceObserver); self.theme->handleSystemThemeChange(); } @end +#endif // QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14) QT_BEGIN_NAMESPACE @@ -132,8 +128,10 @@ const char *QCocoaTheme::name = "cocoa"; QCocoaTheme::QCocoaTheme() : m_systemPalette(nullptr), m_appearanceObserver(nil) { +#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14) if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave) m_appearanceObserver = [[QCocoaThemeAppAppearanceObserver alloc] initWithTheme:this]; +#endif [[NSNotificationCenter defaultCenter] addObserverForName:NSSystemColorsDidChangeNotification object:nil queue:nil usingBlock:^(NSNotification *) { From 66c9161d055ad221d1a0c53d35e00484027cf775 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Thu, 20 Dec 2018 00:29:08 +0100 Subject: [PATCH 0769/1650] Doc: Fix link in QImage::load() documentation Change-Id: I9a3a059a860f5b21253ab0e7cdc616cbfc9a3885 Reviewed-by: Eirik Aavitsland --- src/gui/image/qimage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 0105f1decd..830a110d68 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -3543,7 +3543,7 @@ void QImage::rgbSwapped_inplace() The loader attempts to read the image using the specified \a format, e.g., PNG or JPG. If \a format is not specified (which is the default), it is auto-detected based on the file's suffix and header. For details, see - {QImageReader::setAutoDetectImageFormat()}{QImageReader}. + QImageReader::setAutoDetectImageFormat(). The file name can either refer to an actual file on disk or to one of the application's embedded resources. See the From f7dc6042cbff1b9638bc916872c1aaff86de0c0d Mon Sep 17 00:00:00 2001 From: Vitaly Fanaskov Date: Fri, 7 Dec 2018 16:59:30 +0100 Subject: [PATCH 0770/1650] Remove dead code Task-number: QTBUG-44131 Change-Id: Ic092f2be5855840d6467560159c12f3c5aa36344 Reviewed-by: Christian Ehrlicher Reviewed-by: Lars Knoll --- .../dialogs/qmessagebox/tst_qmessagebox.cpp | 134 ------------------ 1 file changed, 134 deletions(-) diff --git a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp index eeda17074b..76314564f1 100644 --- a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp +++ b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp @@ -38,49 +38,6 @@ #include #include -#define CONVENIENCE_FUNC_SYMS(func) \ - { \ - int x1 = QMessageBox::func(0, "Foo", "Bar"); \ - int x3 = QMessageBox::func(0, "Foo", "Bar", "Save"); \ - int x6 = QMessageBox::func(0, "Foo", "Bar", "Save", "Save As"); \ - int x7 = QMessageBox::func(0, "Foo", "Bar", "Save", "Save As", "Dont Save"); \ - int x8 = QMessageBox::func(0, "Foo", "Bar", "Save", "Save As", "Dont Save", 1); \ - int x9 = QMessageBox::func(0, "Foo", "Bar", "Save", "Save As", "Dont Save", 1, 2); \ - int x10 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::YesAll, QMessageBox::Yes); \ - int x11 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::YesAll, QMessageBox::Yes, \ - QMessageBox::No); \ - qDebug("%d %d %d %d %d %d %d %d", x1, x3, x6, x7, x8, x9, x10, x11); \ - { \ - int x4 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes, (int)QMessageBox::No); \ - int x5 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes, (int)QMessageBox::No); \ - int x6 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default, (int)QMessageBox::No); \ - int x7 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes, QMessageBox::No); \ - int x8 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes, QMessageBox::No); \ - int x9 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No); \ - int x10 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes, (int)QMessageBox::No, (int)QMessageBox::Ok); \ - int x11 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes, (int)QMessageBox::No, (int)QMessageBox::Ok); \ - int x12 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default, (int)QMessageBox::No, (int)QMessageBox::Ok); \ - int x13 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes, QMessageBox::No, (int)QMessageBox::Ok); \ - int x14 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes, QMessageBox::No, (int)QMessageBox::Ok); \ - int x15 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, (int)QMessageBox::Ok); \ - int x16 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes, (int)QMessageBox::No, QMessageBox::Ok); \ - int x17 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes, (int)QMessageBox::No, QMessageBox::Ok); \ - int x18 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default, (int)QMessageBox::No, QMessageBox::Ok); \ - int x19 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes, QMessageBox::No, QMessageBox::Ok); \ - int x20 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes, QMessageBox::No, QMessageBox::Ok); \ - int x21 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Ok); \ - qDebug("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d", x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21); \ - } \ - } - -#define CONVENIENCE_FUNC_SYMS_EXTRA(func) \ - { \ - int x1 = QMessageBox::func(0, "Foo", "Bar", (int)QMessageBox::Yes); \ - int x2 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes); \ - int x3 = QMessageBox::func(0, "Foo", "Bar", QMessageBox::Yes | QMessageBox::Default); \ - qDebug("%d %d %d", x1, x2, x3); \ - } - class tst_QMessageBox : public QObject { Q_OBJECT @@ -103,7 +60,6 @@ private slots: void staticSourceCompat(); void instanceSourceCompat(); - void testSymbols(); void incorrectDefaultButton(); void updateSize(); @@ -509,96 +465,6 @@ void tst_QMessageBox::instanceSourceCompat() #endif } -void tst_QMessageBox::testSymbols() -{ - return; - - QMessageBox::Icon icon; - icon = QMessageBox::NoIcon; - icon = QMessageBox::Information; - icon = QMessageBox::Warning; - icon = QMessageBox::Critical; - icon = QMessageBox::Question; - - QMessageBox mb1; - QMessageBox mb2(0); - QMessageBox mb3(&mb1); - QMessageBox mb3b("title", "text", QMessageBox::Critical, int(QMessageBox::Yes), - int(QMessageBox::No), int(QMessageBox::Cancel), &mb1, Qt::Dialog); - - QMessageBox::Button button = QMessageBox::NoButton; - button = QMessageBox::Ok; - button = QMessageBox::Cancel; - button = QMessageBox::Yes; - button = QMessageBox::No; - button = QMessageBox::Abort; - button = QMessageBox::Retry; - button = QMessageBox::Ignore; - button = QMessageBox::YesAll; - button = QMessageBox::NoAll; - button = QMessageBox::ButtonMask; - button = QMessageBox::Default; - button = QMessageBox::Escape; - button = QMessageBox::FlagMask; - QVERIFY(button); - - const QString text = QStringLiteral("Foo"); - mb1.setText(text); - QCOMPARE(mb1.text(), text); - - icon = mb1.icon(); - QCOMPARE(icon, QMessageBox::NoIcon); - mb1.setIcon(QMessageBox::Question); - QCOMPARE(mb1.icon(), QMessageBox::Question); - - QPixmap iconPixmap = mb1.iconPixmap(); - mb1.setIconPixmap(iconPixmap); - QCOMPARE(mb1.icon(), QMessageBox::NoIcon); - - QCOMPARE(mb1.buttonText(QMessageBox::Ok), QLatin1String("OK")); - QCOMPARE(mb1.buttonText(QMessageBox::Cancel), QString()); - QCOMPARE(mb1.buttonText(QMessageBox::Ok | QMessageBox::Default), QString()); - - const QString button1 = QStringLiteral("Bar"); - mb2.setButtonText(QMessageBox::Cancel, QStringLiteral("Foo")); - mb2.setButtonText(QMessageBox::Ok, button1); - mb2.setButtonText(QMessageBox::Ok | QMessageBox::Default, QStringLiteral("Baz")); - - QCOMPARE(mb2.buttonText(QMessageBox::Cancel), QString()); - QCOMPARE(mb2.buttonText(QMessageBox::Ok), button1); - - QVERIFY(mb3b.buttonText(QMessageBox::Yes).endsWith("Yes")); - QCOMPARE(mb3b.buttonText(QMessageBox::YesAll), QString()); - QCOMPARE(mb3b.buttonText(QMessageBox::Ok), QString()); - - const QString button2 = QStringLiteral("Blah"); - mb3b.setButtonText(QMessageBox::Yes, button2); - mb3b.setButtonText(QMessageBox::YesAll, QStringLiteral("Zoo")); - mb3b.setButtonText(QMessageBox::Ok, QStringLiteral("Zoo")); - - QCOMPARE(mb3b.buttonText(QMessageBox::Yes), button2); - QCOMPARE(mb3b.buttonText(QMessageBox::YesAll), QString()); - QCOMPARE(mb3b.buttonText(QMessageBox::Ok), QString()); - - QCOMPARE(mb1.textFormat(), Qt::AutoText); - mb1.setTextFormat(Qt::PlainText); - QCOMPARE(mb1.textFormat(), Qt::PlainText); - - CONVENIENCE_FUNC_SYMS(information); - CONVENIENCE_FUNC_SYMS_EXTRA(information); - CONVENIENCE_FUNC_SYMS(question); - CONVENIENCE_FUNC_SYMS_EXTRA(question); - CONVENIENCE_FUNC_SYMS(warning); - CONVENIENCE_FUNC_SYMS(critical); - - QSize sizeHint = mb1.sizeHint(); - QVERIFY(sizeHint.width() > 20 && sizeHint.height() > 20); - - QMessageBox::about(&mb1, "title", "text"); - QMessageBox::aboutQt(&mb1); - QMessageBox::aboutQt(&mb1, "title"); -} - void tst_QMessageBox::detailsText() { QMessageBox box; From 8c2ca29045498be5fd74b8a4df633e7edae211c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tony=20Saraj=C3=A4rvi?= Date: Thu, 15 Nov 2018 09:51:25 +0200 Subject: [PATCH 0771/1650] Revert "Blacklist tst_QTimer::basic_chrono on macOS" Incorrectly blacklisted. This reverts commit 40a7c57ba990dfd58814a4a9dc69948991458cd4. Task-number: QTBUG-61013 Change-Id: I7d9dc4a4b1c8d7ff77ab75c61027b908ffb74552 Reviewed-by: Liang Qi --- tests/auto/corelib/kernel/qtimer/BLACKLIST | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/auto/corelib/kernel/qtimer/BLACKLIST b/tests/auto/corelib/kernel/qtimer/BLACKLIST index b355bc22c2..e5136624d8 100644 --- a/tests/auto/corelib/kernel/qtimer/BLACKLIST +++ b/tests/auto/corelib/kernel/qtimer/BLACKLIST @@ -1,5 +1,3 @@ [remainingTime] windows osx -[basic_chrono] -osx ci From 17fe5fc128541553b1eda719d47221763959f8b6 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 14 Dec 2018 16:17:22 +0100 Subject: [PATCH 0772/1650] Restore behavior for QToolTip not wrapping by default This partially reverts 7a1d77b6e4ec38ae8fc17, which caused regressions e.g. in Qt Creator. The behavior of QToolTip for wrapping has been always special in that wordWrap was enabled as soon as some HTML tags were detected, while plain text was not wrapped. This is arguably bad API, but by now a lot of applications depend on this exact behavior, so I don't think it's worth to change this anymore. What can be kept though is the check for overlong tooltips that do not fit on the screen. In this case wrapping makes sense. [ChangeLog][QtWidgets] Reverted a Qt 5.12.0 behavior change in QToolTip that made plain tooltip text be wrapped automatically. Fixes: QTBUG-72568 Change-Id: I6fa3e455f09cffaeb8ad1cdc6e81d71ae344dd34 Reviewed-by: Richard Moe Gustavsen --- src/widgets/kernel/qtooltip.cpp | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp index 2e6575c163..b9d8758fe0 100644 --- a/src/widgets/kernel/qtooltip.cpp +++ b/src/widgets/kernel/qtooltip.cpp @@ -214,7 +214,6 @@ void QTipLabel::reuseTip(const QString &text, int msecDisplayTime, const QPoint } #endif - setWordWrap(true); setText(text); updateSize(pos); restartExpireTimer(msecDisplayTime); @@ -227,19 +226,16 @@ void QTipLabel::updateSize(const QPoint &pos) // Make it look good with the default ToolTip font on Mac, which has a small descent. if (fm.descent() == 2 && fm.ascent() >= 11) ++extra.rheight(); + setWordWrap(Qt::mightBeRichText(text())); QSize sh = sizeHint(); - if (wordWrap()) { - QScreen *screen = QGuiApplication::screenAt(pos); - if (!screen) - screen = QGuiApplication::primaryScreen(); - if (screen) { - const qreal screenWidth = screen->geometry().width(); - if (sh.width() > screenWidth) { - // Try to use widely accepted 75chars max length or 80% of the screen width else. - // See https://en.wikipedia.org/wiki/Line_length - sh.setWidth(qMin(fm.averageCharWidth() * 75, static_cast(screenWidth * .8))); - sh.setHeight(heightForWidth(sh.width())); - } + QScreen *screen = QGuiApplication::screenAt(pos); + if (!screen) + screen = QGuiApplication::primaryScreen(); + if (screen) { + const qreal screenWidth = screen->geometry().width(); + if (!wordWrap() && sh.width() > screenWidth) { + setWordWrap(true); + sh = sizeHint(); } } resize(sh + extra); From 3b03150aa2af76b13424c988c6c7892d19cce6c5 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Wed, 12 Dec 2018 12:36:39 +0100 Subject: [PATCH 0773/1650] Doc: Restore documentation for QTest functions in other modules Qt Test library sources specific to Core, GUI and Widgets modules were moved around in commit 88867e39b. The new source locations must be referenced in Qt Test documentation configuration. The same sources are excluded in their original doc projects, and the related snippet file is moved over to qttestlib. The commit also fixes the remaining documentation issues for Qt Test. Change-Id: Ibe011aa83639e574d647f12bc9e53e618781bce6 Reviewed-by: Martin Smith --- src/corelib/doc/qtcore.qdocconf | 3 +++ src/corelib/kernel/qtestsupport_core.cpp | 6 ++--- src/gui/doc/qtgui.qdocconf | 5 ++++- src/gui/kernel/qtestsupport_gui.cpp | 10 ++++----- src/testlib/doc/qttestlib.qdocconf | 8 +++++++ .../src_corelib_kernel_qtestsupport_core.cpp | 0 src/testlib/qtestcase.qdoc | 22 +++++++++++++++++++ src/widgets/doc/qtwidgets.qdocconf | 3 +++ src/widgets/kernel/qtestsupport_widgets.cpp | 17 +++++++------- 9 files changed, 54 insertions(+), 20 deletions(-) rename src/{corelib => testlib}/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp (100%) diff --git a/src/corelib/doc/qtcore.qdocconf b/src/corelib/doc/qtcore.qdocconf index 5a42e21845..85dcde4607 100644 --- a/src/corelib/doc/qtcore.qdocconf +++ b/src/corelib/doc/qtcore.qdocconf @@ -45,6 +45,9 @@ excludedirs += snippets excludefiles += ../../../examples/widgets/tools/customcompleter/doc/src/customcompleter.qdoc \ ../../../examples/widgets/tools/codecs/doc/src/codecs.qdoc +# Included in qttestlib.qdocconf instead +excludefiles += ../kernel/qtestsupport_core.cpp + manifestmeta.highlighted.names = "QtCore/JSON Save Game Example" \ "QtCore/Local Fortune*" diff --git a/src/corelib/kernel/qtestsupport_core.cpp b/src/corelib/kernel/qtestsupport_core.cpp index d69551a227..aba2a136a1 100644 --- a/src/corelib/kernel/qtestsupport_core.cpp +++ b/src/corelib/kernel/qtestsupport_core.cpp @@ -59,8 +59,7 @@ Q_CORE_EXPORT void QTestPrivate::qSleep(int ms) #endif } -/*! \fn template bool qWaitFor(Functor predicate, int timeout) - \relates QTest +/*! \fn template bool QTest::qWaitFor(Functor predicate, int timeout) Waits for \a timeout milliseconds or until the \a predicate returns true. @@ -77,8 +76,7 @@ Q_CORE_EXPORT void QTestPrivate::qSleep(int ms) */ -/*! \fn void qWait(int ms) - \relates QTest +/*! \fn void QTest::qWait(int ms) Waits for \a ms milliseconds. While waiting, events will be processed and your test will stay responsive to user interface events or network communication. diff --git a/src/gui/doc/qtgui.qdocconf b/src/gui/doc/qtgui.qdocconf index e546c817a7..b8b8a00cd6 100644 --- a/src/gui/doc/qtgui.qdocconf +++ b/src/gui/doc/qtgui.qdocconf @@ -54,7 +54,10 @@ exampledirs += ../../../examples/gui \ imagedirs += images \ ../../../examples/gui/doc/images \ - ../../../doc/src/images \ + ../../../doc/src/images + +# Included in qttestlib.qdocconf instead +excludefiles += ../kernel/qtestsupport_gui.cpp manifestmeta.highlighted.names = "QtGui/Analog Clock Window Example" diff --git a/src/gui/kernel/qtestsupport_gui.cpp b/src/gui/kernel/qtestsupport_gui.cpp index 56e0eb52b3..8a6f662274 100644 --- a/src/gui/kernel/qtestsupport_gui.cpp +++ b/src/gui/kernel/qtestsupport_gui.cpp @@ -44,23 +44,21 @@ QT_BEGIN_NAMESPACE -/*! \fn bool qWaitForWindowActive(QWindow *window, int timeout) - \relates QTest +/*! \since 5.0 Waits for \a timeout milliseconds or until the \a window is active. Returns \c true if \c window is active within \a timeout milliseconds, otherwise returns \c false. - \sa QTest::qWaitForWindowExposed(), QWindow::isActive() + \sa qWaitForWindowExposed(), QWindow::isActive() */ Q_GUI_EXPORT bool QTest::qWaitForWindowActive(QWindow *window, int timeout) { return QTest::qWaitFor([&]() { return window->isActive(); }, timeout); } -/*! \fn bool qWaitForWindowExposed(QWindow *window, int timeout) - \relates QTest +/*! \since 5.0 Waits for \a timeout milliseconds or until the \a window is exposed. @@ -73,7 +71,7 @@ Q_GUI_EXPORT bool QTest::qWaitForWindowActive(QWindow *window, int timeout) area is completely covered by other windows, or if the window is otherwise not visible. This function will then time out when waiting for such a window. - \sa QTest::qWaitForWindowActive(), QWindow::isExposed() + \sa qWaitForWindowActive(), QWindow::isExposed() */ Q_GUI_EXPORT bool QTest::qWaitForWindowExposed(QWindow *window, int timeout) { diff --git a/src/testlib/doc/qttestlib.qdocconf b/src/testlib/doc/qttestlib.qdocconf index 1fdb136e78..93a5ab393c 100644 --- a/src/testlib/doc/qttestlib.qdocconf +++ b/src/testlib/doc/qttestlib.qdocconf @@ -31,8 +31,16 @@ depends += qtcore qtdoc qtwidgets qtgui qmake qtquick headerdirs += .. +headers += ../../corelib/kernel/qtestsupport_core.h \ + ../../gui/kernel/qtestsupport_gui.h \ + ../../widgets/kernel/qtestsupport_widgets.h + sourcedirs += .. +sources += ../../corelib/kernel/qtestsupport_core.cpp \ + ../../gui/kernel/qtestsupport_gui.cpp \ + ../../widgets/kernel/qtestsupport_widgets.cpp + exampledirs += ../../../examples/qtestlib \ ../ \ snippets diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp b/src/testlib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp similarity index 100% rename from src/corelib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp rename to src/testlib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp diff --git a/src/testlib/qtestcase.qdoc b/src/testlib/qtestcase.qdoc index ad9776f7ec..b00c9e51cd 100644 --- a/src/testlib/qtestcase.qdoc +++ b/src/testlib/qtestcase.qdoc @@ -994,6 +994,22 @@ \sa QTest::toHexRepresentation() */ +/*! + \fn char *QTest::toString(const QCborError &c) + \overload + \since 5.12 + + Returns a textual representation of the given CBOR error \a c. +*/ + +/*! + \fn template char *QTest::toString(const std::tuple &tuple) + \overload + \since 5.12 + + Returns a textual representation of the given \a tuple. +*/ + /*! \fn char *QTest::toString(const QTime &time) \overload @@ -1112,6 +1128,12 @@ Returns a textual representation of size policy \a sp. */ +/*! + \fn template char *QTest::toString(const Tuple &tuple, QtPrivate::IndexesList ) + \internal + \since 5.12 +*/ + /*! \fn QTouchDevice *QTest::createTouchDevice(QTouchDevice::DeviceType devType = QTouchDevice::TouchScreen) \since 5.8 diff --git a/src/widgets/doc/qtwidgets.qdocconf b/src/widgets/doc/qtwidgets.qdocconf index 4700ee29bf..5d7262fca1 100644 --- a/src/widgets/doc/qtwidgets.qdocconf +++ b/src/widgets/doc/qtwidgets.qdocconf @@ -40,6 +40,9 @@ exampledirs += ../../../examples/widgets \ excludedirs += snippets +# Included in qttestlib.qdocconf instead +excludefiles += ../kernel/qtestsupport_widgets.cpp + imagedirs += images \ ../../../doc/src/images \ ../../../examples/widgets/doc/images \ diff --git a/src/widgets/kernel/qtestsupport_widgets.cpp b/src/widgets/kernel/qtestsupport_widgets.cpp index b227e6ff5d..0056bebdc6 100644 --- a/src/widgets/kernel/qtestsupport_widgets.cpp +++ b/src/widgets/kernel/qtestsupport_widgets.cpp @@ -46,15 +46,14 @@ QT_BEGIN_NAMESPACE -/*! \fn bool qWaitForWindowActive(QWidget *widget, int timeout) - \relates QTest +/*! \since 5.0 Waits for \a timeout milliseconds or until the \a widget's window is active. Returns \c true if \c widget's window is active within \a timeout milliseconds, otherwise returns \c false. - \sa QTest::qWaitForWindowExposed(), QWidget::isActiveWindow() + \sa qWaitForWindowExposed(), QWidget::isActiveWindow() */ Q_WIDGETS_EXPORT Q_REQUIRED_RESULT bool QTest::qWaitForWindowActive(QWidget *widget, int timeout) { @@ -63,8 +62,7 @@ Q_WIDGETS_EXPORT Q_REQUIRED_RESULT bool QTest::qWaitForWindowActive(QWidget *wid return false; } -/*! \fn bool qWaitForWindowExposed(QWidget *widget, int timeout) - \relates QTest +/*! \since 5.0 Waits for \a timeout milliseconds or until the \a widget's window is exposed. @@ -80,7 +78,7 @@ Q_WIDGETS_EXPORT Q_REQUIRED_RESULT bool QTest::qWaitForWindowActive(QWidget *wid A specific configuration where this happens is when using QGLWidget as a viewport widget on macOS: The viewport widget gets the expose event, not the parent widget. - \sa QTest::qWaitForWindowActive() + \sa qWaitForWindowActive() */ Q_WIDGETS_EXPORT Q_REQUIRED_RESULT bool QTest::qWaitForWindowExposed(QWidget *widget, int timeout) { @@ -89,11 +87,12 @@ Q_WIDGETS_EXPORT Q_REQUIRED_RESULT bool QTest::qWaitForWindowExposed(QWidget *wi return false; } -/*! \fn bool qWaitForWindowShown(QWidget *widget, int timeout) - \relates QTest +/*! \fn bool QTest::qWaitForWindowShown(QWidget *widget, int timeout) \since 5.0 \deprecated + Use qWaitForWindowExposed() instead. + Waits for \a timeout milliseconds or until the \a widget's window is exposed. Returns \c true if \c widget's window is exposed within \a timeout milliseconds, otherwise returns \c false. @@ -107,7 +106,7 @@ Q_WIDGETS_EXPORT Q_REQUIRED_RESULT bool QTest::qWaitForWindowExposed(QWidget *wi QTest::qWaitForWindowShown(&widget); \endcode - \sa QTest::qWaitForWindowActive(), QTest::qWaitForWindowExposed() + \sa qWaitForWindowActive(), qWaitForWindowExposed() */ QT_END_NAMESPACE From 6191249259719dee6f8f6eb42289e0582f1c02bc Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 3 Jan 2019 13:33:28 +0100 Subject: [PATCH 0774/1650] Use the AndroidDeadlockProtector when using a blockingqueued connection This amends 2afe4a1a074096a3a6476aae21e732c418717da7 to account for cases where it was crashing when it was using the QueuedConnection. The problem came from the fact it was blocking while waiting for a surface update which was pending to come later on, but the Android thread was already blocked which prevented it from being processed. Fixes: QTBUG-72101 Change-Id: I43e355cf1a7792599f23827903d065b1b1298902 Reviewed-by: BogDan Vatra --- src/plugins/platforms/android/qandroidinputcontext.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp index 7b3546f9bb..394e284bb6 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.cpp +++ b/src/plugins/platforms/android/qandroidinputcontext.cpp @@ -99,13 +99,12 @@ static jfieldID m_selectionStartFieldID = 0; static jfieldID m_startOffsetFieldID = 0; static jfieldID m_textFieldID = 0; -Q_DECLARE_METATYPE(std::function) - static void runOnQtThread(const std::function &func) { - const bool block = QGuiApplication::applicationState() >= Qt::ApplicationInactive; - QMetaObject::invokeMethod(m_androidInputContext, "safeCall", - block ? Qt::BlockingQueuedConnection : Qt::QueuedConnection, Q_ARG(std::function, func)); + AndroidDeadlockProtector protector; + if (!protector.acquire()) + return; + QMetaObject::invokeMethod(m_androidInputContext, "safeCall", Qt::BlockingQueuedConnection, Q_ARG(std::function, func)); } static jboolean beginBatchEdit(JNIEnv */*env*/, jobject /*thiz*/) @@ -516,7 +515,6 @@ QAndroidInputContext::QAndroidInputContext() m_handleMode = Hidden; updateSelectionHandles(); }); - qRegisterMetaType>(); } QAndroidInputContext::~QAndroidInputContext() From 406d1dcfd744c2fca87e1d151a467bbcd914380b Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Thu, 27 Dec 2018 10:11:26 +0000 Subject: [PATCH 0775/1650] Revert "QListView: Honor css :first/:middle/:last Pseudo-States" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 1aa3edf3f888f394040d32d4a211257f9e9e2791 since it created a regression within the windows styling. Task-number: QTBUG-27110 Fixes: QTBUG-72748 Change-Id: I7e5004be6cf398ef0b533a25066d924310ed1e48 Reviewed-by: Friedemann Kleint Reviewed-by: Thorbjørn Lund Martsum Reviewed-by: Shawn Rutledge --- src/widgets/itemviews/qlistview.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index e5769940d4..1248e91c8c 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -982,18 +982,9 @@ void QListView::paintEvent(QPaintEvent *e) ? qMax(viewport()->size().width(), d->contentsSize().width()) - 2 * d->spacing() : qMax(viewport()->size().height(), d->contentsSize().height()) - 2 * d->spacing(); - const int rowCount = d->commonListView->rowCount(); QVector::const_iterator end = toBeRendered.constEnd(); for (QVector::const_iterator it = toBeRendered.constBegin(); it != end; ++it) { Q_ASSERT((*it).isValid()); - if (rowCount == 1) - option.viewItemPosition = QStyleOptionViewItem::OnlyOne; - else if ((*it).row() == 0) - option.viewItemPosition = QStyleOptionViewItem::Beginning; - else if ((*it).row() == rowCount - 1) - option.viewItemPosition = QStyleOptionViewItem::End; - else - option.viewItemPosition = QStyleOptionViewItem::Middle; option.rect = visualRect(*it); if (flow() == TopToBottom) From fe63900dc9891dd355ca1f10d6c7e5fd1516f5d5 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Mon, 5 Nov 2018 14:26:24 +0100 Subject: [PATCH 0776/1650] xcb: rework focus-in peeker so we can drop PeekFunc API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The API for registering temporary peek function was added ~7 years ago by 78264f333eb7c262380714ed6517562266f11a03. It was never been used for anything else. The solution from 78264f333 also did not work very well on KDE desktop, quoting Martin Flöser: "In case the keyboard gets grabbed by another process and immediately ungrabbed the active Qt application window receives a FocusOut and a FocusIn event. FocusOut on the grab of keyboard, FocusIn on the ungrab. Qt registers a peek function for checking the FocusIn event, but the timespan is too short: the new event is not yet queued. This causes a QEvent::WindowDeactivate being emitted, followed directly by a QEvent::WindowActivate. This has quite some side effects, for example rendering flickering in the GUI (switching to inactive/active in short time frame), hooks on WindowDeactivate being run, etc. Real world examples for such short keyboard grabs are global shortcut listener applications like kglobalaccel5. It has e.g. a passive key grab on the mute key, which is then turned into an active grab when the key is grabbed. Kglobalaccel5 immediately ungrabs the keyboard and flushes the connection if it gets a key event, but it of course causes the sequence of FocusOut and FocusIn events in the active Qt window." Reworked the code to use QTimer instead, which is more elegant solution, because it does not rely on race-conditions, but uses a concreate time to wait instead. Also the need to write focusInPeeker() caused us to duplicate event handlers that were present already elsewhere. Change-Id: I647e52fb2634fdf55a640e19b13265c356f96c95 Reviewed-by: Mikhail Svetkin Reviewed-by: Gatis Paeglis --- src/plugins/platforms/xcb/qxcbconnection.cpp | 26 ++++----------- src/plugins/platforms/xcb/qxcbconnection.h | 10 +++--- src/plugins/platforms/xcb/qxcbwindow.cpp | 33 +++----------------- 3 files changed, 15 insertions(+), 54 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 37ee980924..15ffaaf2e2 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -131,6 +131,12 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra if (!m_startupId.isNull()) qunsetenv("DESKTOP_STARTUP_ID"); + m_focusInTimer.setSingleShot(true); + m_focusInTimer.callOnTimeout([]() { + // No FocusIn events for us, proceed with FocusOut normally. + QWindowSystemInterface::handleWindowActivated(nullptr, Qt::ActiveWindowFocusReason); + }); + sync(); } @@ -731,11 +737,6 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) m_glIntegration->handleXcbEvent(event, response_type); } -void QXcbConnection::addPeekFunc(PeekFunc f) -{ - m_peekFuncs.append(f); -} - void QXcbConnection::setFocusWindow(QWindow *w) { m_focusWindow = w ? static_cast(w->handle()) : nullptr; @@ -1015,15 +1016,6 @@ void QXcbConnection::processXcbEvents(QEventLoop::ProcessEventsFlags flags) if (compressEvent(event)) continue; - auto isWaitingFor = [=](PeekFunc peekFunc) { - // These callbacks return true if the event is what they were - // waiting for, remove them from the list in that case. - return peekFunc(this, event); - }; - m_peekFuncs.erase(std::remove_if(m_peekFuncs.begin(), m_peekFuncs.end(), - isWaitingFor), - m_peekFuncs.end()); - handleXcbEvent(event); // The lock-based solution used to free the lock inside this loop, @@ -1032,12 +1024,6 @@ void QXcbConnection::processXcbEvents(QEventLoop::ProcessEventsFlags flags) m_eventQueue->flushBufferedEvents(); } - // Indicate with a null event that the event the callbacks are waiting for - // is not in the queue currently. - for (PeekFunc f : qAsConst(m_peekFuncs)) - f(this, nullptr); - m_peekFuncs.clear(); - xcb_flush(xcb_connection()); } diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 47036ca257..d63888b48f 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -43,6 +43,7 @@ #include #include +#include #include #include "qxcbexport.h" #include @@ -183,9 +184,6 @@ public: QXcbWindowEventListener *windowEventListenerFromId(xcb_window_t id); QXcbWindow *platformWindowFromId(xcb_window_t id); - typedef bool (*PeekFunc)(QXcbConnection *, xcb_generic_event_t *); - void addPeekFunc(PeekFunc f); - inline xcb_timestamp_t time() const { return m_time; } inline void setTime(xcb_timestamp_t t) { if (t > m_time) m_time = t; } @@ -247,6 +245,8 @@ public: void flush() { xcb_flush(xcb_connection()); } void processXcbEvents(QEventLoop::ProcessEventsFlags flags); + QTimer &focusInTimer() { return m_focusInTimer; }; + protected: bool event(QEvent *e) override; @@ -364,8 +364,6 @@ private: WindowMapper m_mapper; - QVector m_peekFuncs; - Qt::MouseButtons m_buttonState = 0; Qt::MouseButton m_button = Qt::NoButton; @@ -386,6 +384,8 @@ private: friend class QXcbEventQueue; QByteArray m_xdgCurrentDesktop; + QTimer m_focusInTimer; + }; #if QT_CONFIG(xcb_xinput) #if QT_CONFIG(tabletevent) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 3bfcbf2adb..9382488b74 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -843,40 +843,12 @@ void QXcbWindow::doFocusIn() QWindowSystemInterface::handleWindowActivated(w, Qt::ActiveWindowFocusReason); } -static bool focusInPeeker(QXcbConnection *connection, xcb_generic_event_t *event) -{ - if (!event) { - // FocusIn event is not in the queue, proceed with FocusOut normally. - QWindowSystemInterface::handleWindowActivated(nullptr, Qt::ActiveWindowFocusReason); - return true; - } - uint response_type = event->response_type & ~0x80; - if (response_type == XCB_FOCUS_IN) { - // Ignore focus events that are being sent only because the pointer is over - // our window, even if the input focus is in a different window. - xcb_focus_in_event_t *e = (xcb_focus_in_event_t *) event; - if (e->detail != XCB_NOTIFY_DETAIL_POINTER) - return true; - } - - /* We are also interested in XEMBED_FOCUS_IN events */ - if (response_type == XCB_CLIENT_MESSAGE) { - xcb_client_message_event_t *cme = (xcb_client_message_event_t *)event; - if (cme->type == connection->atom(QXcbAtom::_XEMBED) - && cme->data.data32[1] == XEMBED_FOCUS_IN) - return true; - } - - return false; -} - void QXcbWindow::doFocusOut() { connection()->setFocusWindow(nullptr); relayFocusToModalWindow(); // Do not set the active window to nullptr if there is a FocusIn coming. - // The FocusIn handler will update QXcbConnection::setFocusWindow() accordingly. - connection()->addPeekFunc(focusInPeeker); + connection()->focusInTimer().start(400); } struct QtMotifWmHints { @@ -2264,6 +2236,8 @@ void QXcbWindow::handleFocusInEvent(const xcb_focus_in_event_t *event) // our window, even if the input focus is in a different window. if (event->detail == XCB_NOTIFY_DETAIL_POINTER) return; + + connection()->focusInTimer().stop(); doFocusIn(); } @@ -2491,6 +2465,7 @@ void QXcbWindow::handleXEmbedMessage(const xcb_client_message_event_t *event) xcbScreen()->windowShown(this); break; case XEMBED_FOCUS_IN: + connection()->focusInTimer().stop(); Qt::FocusReason reason; switch (event->data.data32[2]) { case XEMBED_FOCUS_FIRST: From 0c54e0251f27fab85baa03fff7213600419f491c Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Wed, 2 Jan 2019 21:54:31 +0100 Subject: [PATCH 0777/1650] ibus: send batched QInputMethodQueryEvent event Change-Id: Idc537a497569d86bb63776934d5e0bbbc39291be Reviewed-by: Mikhail Svetkin Reviewed-by: Lars Knoll --- .../ibus/qibusplatforminputcontext.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp index 3a54f33832..c0979e7864 100644 --- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp +++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp @@ -217,17 +217,14 @@ void QIBusPlatformInputContext::update(Qt::InputMethodQueries q) && (q.testFlag(Qt::ImSurroundingText) || q.testFlag(Qt::ImCursorPosition) || q.testFlag(Qt::ImAnchorPosition))) { - QInputMethodQueryEvent srrndTextQuery(Qt::ImSurroundingText); - QInputMethodQueryEvent cursorPosQuery(Qt::ImCursorPosition); - QInputMethodQueryEvent anchorPosQuery(Qt::ImAnchorPosition); - QCoreApplication::sendEvent(input, &srrndTextQuery); - QCoreApplication::sendEvent(input, &cursorPosQuery); - QCoreApplication::sendEvent(input, &anchorPosQuery); + QInputMethodQueryEvent query(Qt::ImSurroundingText | Qt::ImCursorPosition | Qt::ImAnchorPosition); - QString surroundingText = srrndTextQuery.value(Qt::ImSurroundingText).toString(); - uint cursorPosition = cursorPosQuery.value(Qt::ImCursorPosition).toUInt(); - uint anchorPosition = anchorPosQuery.value(Qt::ImAnchorPosition).toUInt(); + QCoreApplication::sendEvent(input, &query); + + QString surroundingText = query.value(Qt::ImSurroundingText).toString(); + uint cursorPosition = query.value(Qt::ImCursorPosition).toUInt(); + uint anchorPosition = query.value(Qt::ImAnchorPosition).toUInt(); QIBusText text; text.text = surroundingText; From 1075f10184e52ecb08e9b91ae8da25d12f17a9ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sat, 22 Dec 2018 20:08:27 +0100 Subject: [PATCH 0778/1650] macOS: Optimize detection of dark mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I579527c54f8453c1e4f57bab7eebfc576b6ad365 Reviewed-by: Morten Johan Sørvig --- src/corelib/kernel/qcore_mac_objc.mm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm index 7b78ef11be..bc23e821fd 100644 --- a/src/corelib/kernel/qcore_mac_objc.mm +++ b/src/corelib/kernel/qcore_mac_objc.mm @@ -170,8 +170,11 @@ QDebug operator<<(QDebug debug, const QMacAutoReleasePool *pool) bool qt_mac_applicationIsInDarkMode() { #if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14) - if (__builtin_available(macOS 10.14, *)) - return [NSApp.effectiveAppearance.name hasSuffix:@"DarkAqua"]; + if (__builtin_available(macOS 10.14, *)) { + auto appearance = [NSApp.effectiveAppearance bestMatchFromAppearancesWithNames: + @[ NSAppearanceNameAqua, NSAppearanceNameDarkAqua ]]; + return [appearance isEqualToString:NSAppearanceNameDarkAqua]; + } #endif return false; } From 1fb41a38692a4f675a9a336d92d806e12eeb0de9 Mon Sep 17 00:00:00 2001 From: Ville Voutilainen Date: Fri, 4 Jan 2019 09:35:40 +0200 Subject: [PATCH 0779/1650] Fix qbswap calls for Big Endian targets Task-number: QTBUG-71945 Change-Id: I5356f8e32d00ea591b1f65cdd4111276fcf876ac Reviewed-by: Simon Hausmann Reviewed-by: Khem Raj --- src/corelib/global/qendian.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qendian.h b/src/corelib/global/qendian.h index f2e5833468..615f523888 100644 --- a/src/corelib/global/qendian.h +++ b/src/corelib/global/qendian.h @@ -204,9 +204,9 @@ template inline Q_DECL_CONSTEXPR T qToBigEndian(T source) template inline Q_DECL_CONSTEXPR T qFromBigEndian(T source) { return source; } template inline Q_DECL_CONSTEXPR T qToLittleEndian(T source) -{ return qbswap(source); } +{ return qbswap(source); } template inline Q_DECL_CONSTEXPR T qFromLittleEndian(T source) -{ return qbswap(source); } +{ return qbswap(source); } template inline void qToBigEndian(T src, void *dest) { qToUnaligned(src, dest); } template inline void qToLittleEndian(T src, void *dest) From 012f7bb622add41ffc79c0d1eb62043c840be7db Mon Sep 17 00:00:00 2001 From: Sona Kurazyan Date: Fri, 4 Jan 2019 10:45:59 +0100 Subject: [PATCH 0780/1650] Copy backend configuration while setting dtls config When setting dtls configuration, we should also copy backendConfig, otherwise this setting will be ignored. Change-Id: I4df53e8e6d8c2bd0eb7dddb9928b7883c401d60a Reviewed-by: Timur Pocheptsov --- src/network/ssl/qdtls.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/network/ssl/qdtls.cpp b/src/network/ssl/qdtls.cpp index bbb22aa527..3185bfa124 100644 --- a/src/network/ssl/qdtls.cpp +++ b/src/network/ssl/qdtls.cpp @@ -370,6 +370,7 @@ void QDtlsBasePrivate::setConfiguration(const QSslConfiguration &configuration) dtlsConfiguration.nextProtocolNegotiationStatus = configuration.nextProtocolNegotiationStatus(); dtlsConfiguration.dtlsCookieEnabled = configuration.dtlsCookieVerificationEnabled(); dtlsConfiguration.allowRootCertOnDemandLoading = configuration.d->allowRootCertOnDemandLoading; + dtlsConfiguration.backendConfig = configuration.backendConfiguration(); clearDtlsError(); } From 2f4eea5b9cce7b438eeb9016c52a67937d536793 Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Sat, 5 Jan 2019 12:50:18 +0100 Subject: [PATCH 0781/1650] Also integrate Android AAR libraries This works in the same way as JARs are currently provided by dependencies, and becomes necessary when needing e.g. the Android support/compat libs for implementing the Java side of a library. While this is not relevant (yet?) for Qt itself, we hit this with KDE's notification framework. Change-Id: Ia87d1a048a493f7bc311abf5761f33d1943cfbe9 Reviewed-by: BogDan Vatra --- src/android/templates/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/android/templates/build.gradle b/src/android/templates/build.gradle index fcd8ae345d..989d0792cf 100644 --- a/src/android/templates/build.gradle +++ b/src/android/templates/build.gradle @@ -17,7 +17,7 @@ repositories { apply plugin: 'com.android.application' dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar']) } android { From fff59911a353b3fcf74369d8459ac79ce350a54d Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 14 Dec 2018 20:13:44 +0100 Subject: [PATCH 0782/1650] qmake: add QMAKE_EXPORTED_VARIABLES because QMAKE_EXTRA_VARIABLES sometimes just ain't enough. Change-Id: I739e5b6510e4701ca0a86834e4f9a978d7ef1cf4 Reviewed-by: Joerg Bornemann --- qmake/generators/makefile.cpp | 19 +++++++++++++++++++ qmake/generators/makefile.h | 1 + qmake/generators/unix/unixmake2.cpp | 2 ++ qmake/generators/win32/winmakefile.cpp | 2 ++ 4 files changed, 24 insertions(+) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 8b36b64d1d..99455e7cb5 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -2212,6 +2212,25 @@ MakefileGenerator::writeExtraVariables(QTextStream &t) } } +// This is a more powerful alternative to the above function. +// It's meant to be internal, as one can make quite a mess with it. +void +MakefileGenerator::writeExportedVariables(QTextStream &t) +{ + const auto &vars = project->values("QMAKE_EXPORTED_VARIABLES"); + if (vars.isEmpty()) + return; + for (const auto &exp : vars) { + const ProString &name = project->first(ProKey(exp + ".name")); + const ProString &value = project->first(ProKey(exp + ".value")); + if (!value.isEmpty()) + t << name << " = " << value << endl; + else + t << name << " =\n"; + } + t << endl; +} + bool MakefileGenerator::writeDummyMakefile(QTextStream &t) { diff --git a/qmake/generators/makefile.h b/qmake/generators/makefile.h index b5c150e1cb..0c30e74a1d 100644 --- a/qmake/generators/makefile.h +++ b/qmake/generators/makefile.h @@ -79,6 +79,7 @@ protected: void writeHeader(QTextStream &t); void writeSubDirs(QTextStream &t); void writeMakeQmake(QTextStream &t, bool noDummyQmakeAll = false); + void writeExportedVariables(QTextStream &t); void writeExtraVariables(QTextStream &t); void writeExtraTargets(QTextStream &t); void writeExtraCompilerTargets(QTextStream &t); diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index d3abedb50b..4b33713a75 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -180,6 +180,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) ProStringList &bundledFiles = project->values("QMAKE_BUNDLED_FILES"); + writeExportedVariables(t); + t << "####### Compiler, tools and options\n\n"; t << "CC = " << var("QMAKE_CC") << endl; t << "CXX = " << var("QMAKE_CXX") << endl; diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp index e0d03ccc1c..91215c94b1 100644 --- a/qmake/generators/win32/winmakefile.cpp +++ b/qmake/generators/win32/winmakefile.cpp @@ -520,6 +520,8 @@ void Win32MakefileGenerator::writeIncPart(QTextStream &t) void Win32MakefileGenerator::writeStandardParts(QTextStream &t) { + writeExportedVariables(t); + t << "####### Compiler, tools and options\n\n"; t << "CC = " << var("QMAKE_CC") << endl; t << "CXX = " << var("QMAKE_CXX") << endl; From f89ac0101ad4a6cb5339a3bfe132aad897eafc9d Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 14 Dec 2018 21:12:11 +0100 Subject: [PATCH 0783/1650] qmake: add $$read_registry() function Change-Id: I7f9f17e0f44c273e4754d1decc92a8594cad8658 Reviewed-by: Simon Hausmann --- qmake/Makefile.unix | 6 +-- qmake/Makefile.unix.win32 | 2 +- qmake/doc/src/qmake-manual.qdoc | 11 +++++ qmake/library/qmakebuiltins.cpp | 40 ++++++++++++++++++- .../win32 => library}/registry.cpp | 0 .../win32 => library}/registry_p.h | 0 tests/auto/tools/qmakelib/qmakelib.pro | 2 + 7 files changed, 56 insertions(+), 5 deletions(-) rename qmake/{generators/win32 => library}/registry.cpp (100%) rename qmake/{generators/win32 => library}/registry_p.h (100%) diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index 9e0b51ba55..0f69b6b487 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -192,6 +192,9 @@ qmakeevaluator.o: $(QMKLIBSRC)/qmakeevaluator.cpp qmakebuiltins.o: $(QMKLIBSRC)/qmakebuiltins.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< +registry.o: $(QMKLIBSRC)/registry.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $< + project.o: $(QMKSRC)/project.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< @@ -225,9 +228,6 @@ unixmake.o: $(QMKSRC)/generators/unix/unixmake.cpp unixmake2.o: $(QMKSRC)/generators/unix/unixmake2.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< -registry.o: $(QMKSRC)/generators/win32/registry.cpp - $(CXX) -c -o $@ $(CXXFLAGS) $< - winmakefile.o: $(QMKSRC)/generators/win32/winmakefile.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< diff --git a/qmake/Makefile.unix.win32 b/qmake/Makefile.unix.win32 index 48efd6f030..faf09ac11e 100644 --- a/qmake/Makefile.unix.win32 +++ b/qmake/Makefile.unix.win32 @@ -18,4 +18,4 @@ QTSRCS = \ $(SOURCE_PATH)/src/corelib/io/qsettings_win.cpp \ $(SOURCE_PATH)/src/corelib/tools/qlocale_win.cpp \ $(SOURCE_PATH)/src/corelib/plugin/qsystemlibrary.cpp \ - $(SOURCE_PATH)/qmake/generators/win32/registry.cpp + $(SOURCE_PATH)/qmake/library/registry.cpp diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index 97744e7460..fb8bad32a2 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -3258,6 +3258,17 @@ Returns the \c string with every special regular expression character escaped with a backslash. This function is a wrapper around QRegExp::escape. + \section2 read_registry(tree, key[, flag]) + + Returns the value of registry key \c key inside the tree \c tree. + + Only the trees \c HKEY_CURRENT_USER (\c HKCU) and \c HKEY_LOCAL_MACHINE + (\c HKLM) are supported. + + The \c flag may be \c WOW64_32KEY (\c 32) or \c WOW64_64KEY (\c 64). + + \note This function is available only on Windows hosts. + \section2 relative_path(filePath[, base]) Returns the path to \c filePath relative to \c base. diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index f81bec158b..dd7766c8e0 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -52,6 +52,9 @@ # include #endif #include +#ifdef Q_OS_WIN +# include +#endif #include @@ -93,7 +96,7 @@ enum ExpandFunc { E_UPPER, E_LOWER, E_TITLE, E_FILES, E_PROMPT, E_RE_ESCAPE, E_VAL_ESCAPE, E_REPLACE, E_SORT_DEPENDS, E_RESOLVE_DEPENDS, E_ENUMERATE_VARS, E_SHADOWED, E_ABSOLUTE_PATH, E_RELATIVE_PATH, E_CLEAN_PATH, - E_SYSTEM_PATH, E_SHELL_PATH, E_SYSTEM_QUOTE, E_SHELL_QUOTE, E_GETENV + E_SYSTEM_PATH, E_SHELL_PATH, E_SYSTEM_QUOTE, E_SHELL_QUOTE, E_GETENV, E_READ_REGISTRY }; enum TestFunc { @@ -190,6 +193,7 @@ void QMakeEvaluator::initFunctionStatics() { "system_quote", E_SYSTEM_QUOTE, -1, 1, "arg" }, { "shell_quote", E_SHELL_QUOTE, -1, 1, "arg" }, { "getenv", E_GETENV, 1, 1, "arg" }, + { "read_registry", E_READ_REGISTRY, 2, 3, "tree, key, [wow64]" }, }; statics.expands.reserve((int)(sizeof(expandInits)/sizeof(expandInits[0]))); for (unsigned i = 0; i < sizeof(expandInits)/sizeof(expandInits[0]); ++i) @@ -1214,6 +1218,40 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand( ret << ProString(m_option->getEnv(u1.str())); break; } +#ifdef Q_OS_WIN + case E_READ_REGISTRY: { + HKEY tree; + const auto par = args.at(0); + if (!par.compare(QLatin1String("HKCU"), Qt::CaseInsensitive) + || !par.compare(QLatin1String("HKEY_CURRENT_USER"), Qt::CaseInsensitive)) { + tree = HKEY_CURRENT_USER; + } else if (!par.compare(QLatin1String("HKLM"), Qt::CaseInsensitive) + || !par.compare(QLatin1String("HKEY_LOCAL_MACHINE"), Qt::CaseInsensitive)) { + tree = HKEY_LOCAL_MACHINE; + } else { + evalError(fL1S("read_registry(): invalid or unsupported registry tree %1.") + .arg(par.toQStringView())); + goto allfail; + } + int flags = 0; + if (args.count() > 2) { + const auto opt = args.at(2); + if (opt == "32" + || !opt.compare(QLatin1String("wow64_32key"), Qt::CaseInsensitive)) { + flags = KEY_WOW64_32KEY; + } else if (opt == "64" + || !opt.compare(QLatin1String("wow64_64key"), Qt::CaseInsensitive)) { + flags = KEY_WOW64_64KEY; + } else { + evalError(fL1S("read_registry(): invalid option %1.") + .arg(opt.toQStringView())); + goto allfail; + } + } + ret << ProString(qt_readRegistryKey(tree, args.at(1).toQString(m_tmp1), flags)); + break; + } +#endif default: evalError(fL1S("Function '%1' is not implemented.").arg(func.toQStringView())); break; diff --git a/qmake/generators/win32/registry.cpp b/qmake/library/registry.cpp similarity index 100% rename from qmake/generators/win32/registry.cpp rename to qmake/library/registry.cpp diff --git a/qmake/generators/win32/registry_p.h b/qmake/library/registry_p.h similarity index 100% rename from qmake/generators/win32/registry_p.h rename to qmake/library/registry_p.h diff --git a/tests/auto/tools/qmakelib/qmakelib.pro b/tests/auto/tools/qmakelib/qmakelib.pro index 140bece708..29f17f6a14 100644 --- a/tests/auto/tools/qmakelib/qmakelib.pro +++ b/tests/auto/tools/qmakelib/qmakelib.pro @@ -1,6 +1,7 @@ CONFIG += testcase TARGET = tst_qmakelib QT = core testlib +win32: LIBS += -ladvapi32 INCLUDEPATH += ../../../../qmake/library VPATH += ../../../../qmake/library @@ -13,6 +14,7 @@ SOURCES += \ parsertest.cpp \ evaltest.cpp \ ioutils.cpp \ + registry.cpp \ proitems.cpp \ qmakevfs.cpp \ qmakeparser.cpp \ From ef14c3dc1a6106673969bc55967c434761d33629 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 17 Dec 2018 21:16:27 +0100 Subject: [PATCH 0784/1650] qmake: reshuffle toolchain.prf swap the order of compiler version detection and default path detection. this keeps a subsequent commit smaller, which introduces a dependency between the two. Change-Id: I2d4cbee1fd3555411c18833bbee0201c994a9942 Reviewed-by: Joerg Bornemann --- mkspecs/features/toolchain.prf | 209 +++++++++++++++++---------------- 1 file changed, 106 insertions(+), 103 deletions(-) diff --git a/mkspecs/features/toolchain.prf b/mkspecs/features/toolchain.prf index 1a76e50b49..734a7fbf86 100644 --- a/mkspecs/features/toolchain.prf +++ b/mkspecs/features/toolchain.prf @@ -1,14 +1,3 @@ - -defineReplace(qtMakeExpand) { - out = "$$1" - for(ever) { - m = $$replace(out, ".*\\$\\(EXPORT_([^)]+)\\).*", \\1) - equals(m, $$out): \ - return($$out) - out = $$replace(out, "\\$\\(EXPORT_$$m\\)", $$eval($$m)) - } -} - defineTest(qtCompilerError) { !cross_compile: \ what = @@ -30,6 +19,112 @@ cross_compile:host_build: \ else: \ target_prefix = QMAKE_CXX +# +# Determine and cache the compiler version +# + +defineReplace(qtVariablesFromMSVC) { + ret = $$system("$$1 -nologo -E $$2 $$system_quote($$PWD/data/macros.cpp) 2>NUL", lines, ec) + !equals(ec, 0): qtCompilerError($$1, $$ret) + return($$ret) +} + +defineReplace(qtVariablesFromGCC) { + ret = $$system("$$1 -E $$system_quote($$PWD/data/macros.cpp) \ + 2>$$QMAKE_SYSTEM_NULL_DEVICE", lines, ec) + !equals(ec, 0): qtCompilerError($$1, $$ret) + return($$ret) +} + +isEmpty($${target_prefix}.COMPILER_MACROS) { + msvc { + clang_cl { + # We need to obtain the cl.exe version first + vars = $$qtVariablesFromMSVC(cl) + for (v, vars) { + isEmpty(v)|contains(v, $${LITERAL_HASH}.*): next() + eval($$v) + } + isEmpty(QMAKE_MSC_FULL_VER): error("Could not determine the Visual Studio version") + + QMAKE_CFLAGS_MSVC_COMPAT = $$replace(QMAKE_MSC_FULL_VER, "(..)(..)(.*)", \ + "-fms-compatibility-version=\\1.\\2.\\3") + cache($${target_prefix}.QMAKE_CFLAGS_MSVC_COMPAT, set stash, QMAKE_CFLAGS_MSVC_COMPAT) + $${target_prefix}.COMPILER_MACROS += QMAKE_CFLAGS_MSVC_COMPAT + vars = $$qtVariablesFromMSVC($$QMAKE_CXX, $$QMAKE_CFLAGS_MSVC_COMPAT) + } else { + vars = $$qtVariablesFromMSVC($$QMAKE_CXX) + } + } else: gcc|ghs { + vars = $$qtVariablesFromGCC($$QMAKE_CXX) + } + for (v, vars) { + !contains(v, "[A-Z_]+ = .*"): next() + # Set both for the outer scope ... + eval($$v) + v ~= s/ .*// + isEmpty($$v): error("Compiler produced empty value for $${v}.") + # ... and save QMAKE_(HOST_)?CXX. in the cache. + cache($${target_prefix}.$$v, set stash, $$v) + $${target_prefix}.COMPILER_MACROS += $$v + } + cache($${target_prefix}.COMPILER_MACROS, set stash) +} else { + # load from the cache + for (i, $${target_prefix}.COMPILER_MACROS): \ + $$i = $$eval($${target_prefix}.$$i) +} + +# Populate QMAKE_COMPILER_DEFINES and some compatibility variables. +# The $$format_number() calls strip leading zeros to avoid misinterpretation as octal. +QMAKE_COMPILER_DEFINES += __cplusplus=$$QT_COMPILER_STDCXX +!isEmpty(QMAKE_MSC_VER): \ + QMAKE_COMPILER_DEFINES += _MSC_VER=$$QMAKE_MSC_VER _MSC_FULL_VER=$$QMAKE_MSC_FULL_VER +!isEmpty(QMAKE_ICC_VER): \ + QMAKE_COMPILER_DEFINES += __INTEL_COMPILER=$$QMAKE_ICC_VER __INTEL_COMPILER_UPDATE=$$QMAKE_ICC_UPDATE_VER +!isEmpty(QMAKE_APPLE_CC): \ + QMAKE_COMPILER_DEFINES += __APPLE_CC__=$$QMAKE_APPLE_CC +!isEmpty(QMAKE_APPLE_CLANG_MAJOR_VERSION): \ + QMAKE_COMPILER_DEFINES += __clang__ \ + __clang_major__=$$QMAKE_APPLE_CLANG_MAJOR_VERSION \ + __clang_minor__=$$QMAKE_APPLE_CLANG_MINOR_VERSION \ + __clang_patchlevel__=$$QMAKE_APPLE_CLANG_PATCH_VERSION +!isEmpty(QMAKE_CLANG_MAJOR_VERSION): \ + QMAKE_COMPILER_DEFINES += __clang__ \ + __clang_major__=$$QMAKE_CLANG_MAJOR_VERSION \ + __clang_minor__=$$QMAKE_CLANG_MINOR_VERSION \ + __clang_patchlevel__=$$QMAKE_CLANG_PATCH_VERSION +!isEmpty(QMAKE_GCC_MAJOR_VERSION): \ + QMAKE_COMPILER_DEFINES += \ + __GNUC__=$$QMAKE_GCC_MAJOR_VERSION \ + __GNUC_MINOR__=$$QMAKE_GCC_MINOR_VERSION \ + __GNUC_PATCHLEVEL__=$$QMAKE_GCC_PATCH_VERSION +!isEmpty(QMAKE_GHS_VERSION): \ + QMAKE_COMPILER_DEFINES += __ghs__ __GHS_VERSION_NUMBER=$$QMAKE_GHS_VERSION + +QMAKE_CFLAGS += $$QMAKE_CFLAGS_MSVC_COMPAT +QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_MSVC_COMPAT + +clang_cl|intel_icl { + include(../common/msvc-based-version.conf) +} else: msvc { + include(../common/msvc-version.conf) +} + +# +# Determine and cache the default search paths +# + +defineReplace(qtMakeExpand) { + out = "$$1" + for(ever) { + m = $$replace(out, ".*\\$\\(EXPORT_([^)]+)\\).*", \\1) + equals(m, $$out): \ + return($$out) + out = $$replace(out, "\\$\\(EXPORT_$$m\\)", $$eval($$m)) + } +} + isEmpty($${target_prefix}.INCDIRS) { # # Get default include and library paths from compiler @@ -193,96 +288,4 @@ isEmpty($${target_prefix}.INCDIRS) { QMAKE_DEFAULT_LIBDIRS = $$eval($${target_prefix}.LIBDIRS) } -# -# Determine and cache the compiler version -# - -defineReplace(qtVariablesFromMSVC) { - ret = $$system("$$1 -nologo -E $$2 $$system_quote($$PWD/data/macros.cpp) 2>NUL", lines, ec) - !equals(ec, 0): qtCompilerError($$1, $$ret) - return($$ret) -} - -defineReplace(qtVariablesFromGCC) { - ret = $$system("$$1 -E $$system_quote($$PWD/data/macros.cpp) \ - 2>$$QMAKE_SYSTEM_NULL_DEVICE", lines, ec) - !equals(ec, 0): qtCompilerError($$1, $$ret) - return($$ret) -} - -isEmpty($${target_prefix}.COMPILER_MACROS) { - msvc { - clang_cl { - # We need to obtain the cl.exe version first - vars = $$qtVariablesFromMSVC(cl) - for (v, vars) { - isEmpty(v)|contains(v, $${LITERAL_HASH}.*): next() - eval($$v) - } - isEmpty(QMAKE_MSC_FULL_VER): error("Could not determine the Visual Studio version") - - QMAKE_CFLAGS_MSVC_COMPAT = $$replace(QMAKE_MSC_FULL_VER, "(..)(..)(.*)", \ - "-fms-compatibility-version=\\1.\\2.\\3") - cache($${target_prefix}.QMAKE_CFLAGS_MSVC_COMPAT, set stash, QMAKE_CFLAGS_MSVC_COMPAT) - $${target_prefix}.COMPILER_MACROS += QMAKE_CFLAGS_MSVC_COMPAT - vars = $$qtVariablesFromMSVC($$QMAKE_CXX, $$QMAKE_CFLAGS_MSVC_COMPAT) - } else { - vars = $$qtVariablesFromMSVC($$QMAKE_CXX) - } - } else: gcc|ghs { - vars = $$qtVariablesFromGCC($$QMAKE_CXX) - } - for (v, vars) { - !contains(v, "[A-Z_]+ = .*"): next() - # Set both for the outer scope ... - eval($$v) - v ~= s/ .*// - isEmpty($$v): error("Compiler produced empty value for $${v}.") - # ... and save QMAKE_(HOST_)?CXX. in the cache. - cache($${target_prefix}.$$v, set stash, $$v) - $${target_prefix}.COMPILER_MACROS += $$v - } - cache($${target_prefix}.COMPILER_MACROS, set stash) -} else { - # load from the cache - for (i, $${target_prefix}.COMPILER_MACROS): \ - $$i = $$eval($${target_prefix}.$$i) -} - unset(target_prefix) - -# Populate QMAKE_COMPILER_DEFINES and some compatibility variables. -# The $$format_number() calls strip leading zeros to avoid misinterpretation as octal. -QMAKE_COMPILER_DEFINES += __cplusplus=$$QT_COMPILER_STDCXX -!isEmpty(QMAKE_MSC_VER): \ - QMAKE_COMPILER_DEFINES += _MSC_VER=$$QMAKE_MSC_VER _MSC_FULL_VER=$$QMAKE_MSC_FULL_VER -!isEmpty(QMAKE_ICC_VER): \ - QMAKE_COMPILER_DEFINES += __INTEL_COMPILER=$$QMAKE_ICC_VER __INTEL_COMPILER_UPDATE=$$QMAKE_ICC_UPDATE_VER -!isEmpty(QMAKE_APPLE_CC): \ - QMAKE_COMPILER_DEFINES += __APPLE_CC__=$$QMAKE_APPLE_CC -!isEmpty(QMAKE_APPLE_CLANG_MAJOR_VERSION): \ - QMAKE_COMPILER_DEFINES += __clang__ \ - __clang_major__=$$QMAKE_APPLE_CLANG_MAJOR_VERSION \ - __clang_minor__=$$QMAKE_APPLE_CLANG_MINOR_VERSION \ - __clang_patchlevel__=$$QMAKE_APPLE_CLANG_PATCH_VERSION -!isEmpty(QMAKE_CLANG_MAJOR_VERSION): \ - QMAKE_COMPILER_DEFINES += __clang__ \ - __clang_major__=$$QMAKE_CLANG_MAJOR_VERSION \ - __clang_minor__=$$QMAKE_CLANG_MINOR_VERSION \ - __clang_patchlevel__=$$QMAKE_CLANG_PATCH_VERSION -!isEmpty(QMAKE_GCC_MAJOR_VERSION): \ - QMAKE_COMPILER_DEFINES += \ - __GNUC__=$$QMAKE_GCC_MAJOR_VERSION \ - __GNUC_MINOR__=$$QMAKE_GCC_MINOR_VERSION \ - __GNUC_PATCHLEVEL__=$$QMAKE_GCC_PATCH_VERSION -!isEmpty(QMAKE_GHS_VERSION): \ - QMAKE_COMPILER_DEFINES += __ghs__ __GHS_VERSION_NUMBER=$$QMAKE_GHS_VERSION - -QMAKE_CFLAGS += $$QMAKE_CFLAGS_MSVC_COMPAT -QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_MSVC_COMPAT - -clang_cl|intel_icl { - include(../common/msvc-based-version.conf) -} else: msvc { - include(../common/msvc-version.conf) -} From 45e4dfb449fb15632e5144cf671e38943fa1455f Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 17 Dec 2018 20:57:18 +0100 Subject: [PATCH 0785/1650] qmake: rewrite msvc/nmake cross-build environment setup rather than reproducing vcvarsall.bat's functionality as hard-wired code in the nmake generator, just invoke the actual script from toolchain.prf. this is much easier, more future proof, and - critically - makes the detected variables available to configure's new library & header search facilities. [ChangeLog][Important Behavior Changes][qmake][WinRT] Cross-builds will now ignore pre-set values of %INCLUDE% and %LIB% when building target executables. If necessary, use configure's -I and -L switches when building Qt, and pass QMAKE_INCDIR and QMAKE_LIBDIR on qmake's command line when building own projects. Change-Id: I36f53e8880d6523f3f6f7a44d40d87d04bd06854 Reviewed-by: Thomas Miller Reviewed-by: Oliver Wolff --- mkspecs/features/data/dumpvcvars.bat | 44 ++++++ mkspecs/features/toolchain.prf | 146 +++++++++++++++++-- mkspecs/winrt-arm-msvc2015/qmake.conf | 1 - mkspecs/winrt-arm-msvc2017/qmake.conf | 1 - mkspecs/winrt-x64-msvc2015/qmake.conf | 1 - mkspecs/winrt-x64-msvc2017/qmake.conf | 1 - mkspecs/winrt-x86-msvc2015/qmake.conf | 1 - mkspecs/winrt-x86-msvc2017/qmake.conf | 1 - qmake/generators/win32/msvc_nmake.cpp | 201 -------------------------- 9 files changed, 181 insertions(+), 216 deletions(-) create mode 100644 mkspecs/features/data/dumpvcvars.bat diff --git a/mkspecs/features/data/dumpvcvars.bat b/mkspecs/features/data/dumpvcvars.bat new file mode 100644 index 0000000000..4721da2e39 --- /dev/null +++ b/mkspecs/features/data/dumpvcvars.bat @@ -0,0 +1,44 @@ +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:: +:: Copyright (C) 2018 The Qt Company Ltd. +:: Contact: https://www.qt.io/licensing/ +:: +:: This file is part of the tools applications of the Qt Toolkit. +:: +:: $QT_BEGIN_LICENSE:GPL-EXCEPT$ +:: Commercial License Usage +:: Licensees holding valid commercial Qt licenses may use this file in +:: accordance with the commercial license agreement provided with the +:: Software or, alternatively, in accordance with the terms contained in +:: a written agreement between you and The Qt Company. For licensing terms +:: and conditions see https://www.qt.io/terms-conditions. For further +:: information use the contact form at https://www.qt.io/contact-us. +:: +:: GNU General Public License Usage +:: Alternatively, this file may be used under the terms of the GNU +:: General Public License version 3 as published by the Free Software +:: Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +:: included in the packaging of this file. Please review the following +:: information to ensure the GNU General Public License requirements will +:: be met: https://www.gnu.org/licenses/gpl-3.0.html. +:: +:: $QT_END_LICENSE$ +:: +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +@echo off + +REM We clear INCLUDE and LIB, because we want to obtain pristine values. +REM PATH cannot be cleared, because then the script does not even run, +REM and it would be counterproductive anyway (see toolchain.prf). +set INCLUDE= +set LIB= + +call %* || exit 1 +REM VS2015 does not set errorlevel in case of failure. +if "%INCLUDE%" == "" exit 1 + +echo =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= +echo %INCLUDE% +echo %LIB% +echo %PATH% diff --git a/mkspecs/features/toolchain.prf b/mkspecs/features/toolchain.prf index 734a7fbf86..2a7cbabc54 100644 --- a/mkspecs/features/toolchain.prf +++ b/mkspecs/features/toolchain.prf @@ -1,3 +1,13 @@ +defineTest(qtToolchainError) { + msg = \ + $$1 \ + "===================" \ + $$2 \ + "===================" \ + $$3 + error($$join(msg, $$escape_expand(\\n))) +} + defineTest(qtCompilerError) { !cross_compile: \ what = @@ -5,13 +15,8 @@ defineTest(qtCompilerError) { what = " host" else: \ what = " target" - msg = \ - "Cannot run$$what compiler '$$1'. Output:" \ - "===================" \ - $$2 \ - "===================" \ - "Maybe you forgot to setup the environment?" - error($$join(msg, $$escape_expand(\\n))) + qtToolchainError("Cannot run$$what compiler '$$1'. Output:", $$2, \ + "Maybe you forgot to setup the environment?") } cross_compile:host_build: \ @@ -125,6 +130,36 @@ defineReplace(qtMakeExpand) { } } +defineReplace(qtSplitPathList) { + paths = $$split(1, $$QMAKE_DIRLIST_SEP) + ret = + for (p, paths): \ + ret += $$clean_path($$p) + return($$ret) +} + +defineReplace(qtNmakePathList) { + paths = + for (p, 1): \ + paths += $$shell_path($$p) + paths ~= s,$${LITERAL_HASH},^$${LITERAL_HASH},g + paths ~= s,\\$,\$\$,g + return($$join(paths, $$QMAKE_DIRLIST_SEP)) +} + +msvc { + arch = $$lower($$VCPROJ_ARCH) + equals(arch, x64): \ # may be "win32" or undefined + arch = amd64 + else: !equals(arch, arm):!equals(arch, arm64): \ # may be "win32" or undefined + arch = x86 + # Consider only WinRT and ARM64 desktop builds to be cross-builds - + # the host is assumed to be Intel and capable of running the target + # executables (so building for x64 on x86 will break). + winrt|equals(arch, arm64): \ + CONFIG += msvc_cross +} + isEmpty($${target_prefix}.INCDIRS) { # # Get default include and library paths from compiler @@ -264,9 +299,89 @@ isEmpty($${target_prefix}.INCDIRS) { } } } + } else: msvc_cross { + # Use a batch file, because %VAR% in the system() call expands to + # the pre-script-call value, and !VAR! cannot be enabled outside + # a batch file without invoking another shell instance. + cmd = $$system_quote($$system_path($$PWD/data/dumpvcvars.bat)) + + hostArch = $$QMAKE_HOST.arch + equals(hostArch, x86_64): \ + hostArch = amd64 + !equals(arch, $$hostArch): \ + arch = $${hostArch}_$$arch + + isEmpty(MSVC_VER): \ + error("Mkspec does not specify MSVC_VER. Cannot continue.") + versionAtLeast(MSVC_VER, 15.0) { + dir = $$(VSINSTALLDIR) + isEmpty(dir): \ + dir = $$read_registry(HKLM, \ + "Software\\Microsoft\\VisualStudio\\SxS\\VS7\\$$MSVC_VER", 32) + isEmpty(dir): \ + error("Failed to find the Visual Studio installation directory.") + cmd += $$system_quote($$dir\\VC\\Auxiliary\\Build\\vcvarsall.bat) $$arch + } else { + dir = $$(VCINSTALLDIR) + isEmpty(dir): \ + dir = $$read_registry(HKLM, \ + "Software\\Microsoft\\VisualStudio\\$$MSVC_VER\\Setup\\VC\\ProductDir", 32) + isEmpty(dir): \ + error("Failed to find the Visual C installation directory.") + cmd += $$system_quote($$dir\\vcvarsall.bat) $$arch + } + winrt: cmd += store + + isEmpty(WINSDK_VER): \ + error("Mkspec does not specify WINSDK_VER. Cannot continue.") + # We prefer the environment variable, because that may work around + # a broken registry entry after uninstalling a newer SDK. + # However, we do that only if the major+minor SDK version matches + # the one requested by the mkspec, as we might be building for a + # newer target than the host. + winsdk_ver = $$(WindowsSDKVersion) + !isEmpty(winsdk_ver) { + winsdk_ver ~= s,\\\\$,, # Work around SDK breakage. + !equals(WINSDK_VER, $$replace(winsdk_ver, ^(\\d+\\.\\d+).*$, \\1)): \ + winsdk_ver = + } + !isEmpty(winsdk_ver) { + cmd += $$winsdk_ver + } else { + winsdk_ver = $$read_registry(HKLM, \ + "Software\\Microsoft\\Microsoft SDKs\\Windows\\v$$WINSDK_VER\\ProductVersion", 32) + isEmpty(winsdk_ver): \ + error("Windows SDK $$WINSDK_VER requested by mkspec is not installed. Cannot continue.") + cmd += $${winsdk_ver}.0 + } + + output = $$system("$$cmd 2>&1", lines, ec) + !equals(ec, 0): \ + qtToolchainError("SDK setup script failed. Output:", $$output, \ + "Command was: $$cmd") + lines = $$output + for(ever) { + isEmpty(lines): \ + break() + line = $$take_first(lines) + equals(line, "=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+="): \ + break() + } + !count(lines, 3): \ + qtToolchainError("SDK setup script returned unexpected output:", $$output, \ + "Command was: $$cmd") + + # These contain only paths for the target. + QMAKE_DEFAULT_INCDIRS = $$qtSplitPathList($$member(lines, 0)) + QMAKE_DEFAULT_LIBDIRS = $$qtSplitPathList($$member(lines, 1)) + # PATH is inherently for the host, and paths that are not shadowed + # by vcvarsall.bat are assumed to contain only tools that work for + # both host and target builds. + QMAKE_DEFAULT_PATH = $$qtSplitPathList($$member(lines, 2)) + # We de-duplicate, because the script just prepends to the paths for + # the host, some of which are identical to the ones for the target. + QMAKE_DEFAULT_PATH = $$unique(QMAKE_DEFAULT_PATH) } else: msvc { - # This doesn't differentiate between host and target, - # but neither do the compilers. LIB = $$getenv("LIB") QMAKE_DEFAULT_LIBDIRS = $$split(LIB, $$QMAKE_DIRLIST_SEP) INCLUDE = $$getenv("INCLUDE") @@ -283,9 +398,22 @@ isEmpty($${target_prefix}.INCDIRS) { cache($${target_prefix}.INCDIRS, set stash, QMAKE_DEFAULT_INCDIRS) !isEmpty(QMAKE_DEFAULT_LIBDIRS): \ cache($${target_prefix}.LIBDIRS, set stash, QMAKE_DEFAULT_LIBDIRS) + !isEmpty(QMAKE_DEFAULT_PATH): \ + cache($${target_prefix}.PATH, set stash, QMAKE_DEFAULT_PATH) } else { QMAKE_DEFAULT_INCDIRS = $$eval($${target_prefix}.INCDIRS) QMAKE_DEFAULT_LIBDIRS = $$eval($${target_prefix}.LIBDIRS) + QMAKE_DEFAULT_PATH = $$eval($${target_prefix}.PATH) +} + +msvc_cross { + qmake_inc_exp.name = INCLUDE + qmake_inc_exp.value = $$qtNmakePathList($$QMAKE_DEFAULT_INCDIRS) + qmake_lib_exp.name = LIB + qmake_lib_exp.value = $$qtNmakePathList($$QMAKE_DEFAULT_LIBDIRS) + qmake_path_exp.name = PATH + qmake_path_exp.value = $$qtNmakePathList($$QMAKE_DEFAULT_PATH) + QMAKE_EXPORTED_VARIABLES += qmake_inc_exp qmake_lib_exp qmake_path_exp } unset(target_prefix) diff --git a/mkspecs/winrt-arm-msvc2015/qmake.conf b/mkspecs/winrt-arm-msvc2015/qmake.conf index 8bca6f4af8..bc113d4954 100644 --- a/mkspecs/winrt-arm-msvc2015/qmake.conf +++ b/mkspecs/winrt-arm-msvc2015/qmake.conf @@ -15,6 +15,5 @@ QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib One VCPROJ_ARCH = ARM WINSDK_VER = 10.0 -WINTARGET_VER = winv10.0 WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in WINRT_MANIFEST.architecture = arm diff --git a/mkspecs/winrt-arm-msvc2017/qmake.conf b/mkspecs/winrt-arm-msvc2017/qmake.conf index bf571d620c..1160d5766d 100644 --- a/mkspecs/winrt-arm-msvc2017/qmake.conf +++ b/mkspecs/winrt-arm-msvc2017/qmake.conf @@ -15,6 +15,5 @@ QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib One VCPROJ_ARCH = ARM WINSDK_VER = 10.0 -WINTARGET_VER = winv10.0 WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in WINRT_MANIFEST.architecture = arm diff --git a/mkspecs/winrt-x64-msvc2015/qmake.conf b/mkspecs/winrt-x64-msvc2015/qmake.conf index d503399e3c..d1d1eb6513 100644 --- a/mkspecs/winrt-x64-msvc2015/qmake.conf +++ b/mkspecs/winrt-x64-msvc2015/qmake.conf @@ -15,6 +15,5 @@ QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib One VCPROJ_ARCH = x64 WINSDK_VER = 10.0 -WINTARGET_VER = winv10.0 WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in WINRT_MANIFEST.architecture = x64 diff --git a/mkspecs/winrt-x64-msvc2017/qmake.conf b/mkspecs/winrt-x64-msvc2017/qmake.conf index cb2209fa23..dce896bd47 100644 --- a/mkspecs/winrt-x64-msvc2017/qmake.conf +++ b/mkspecs/winrt-x64-msvc2017/qmake.conf @@ -15,6 +15,5 @@ QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib One VCPROJ_ARCH = x64 WINSDK_VER = 10.0 -WINTARGET_VER = winv10.0 WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in WINRT_MANIFEST.architecture = x64 diff --git a/mkspecs/winrt-x86-msvc2015/qmake.conf b/mkspecs/winrt-x86-msvc2015/qmake.conf index 37ce0e5525..06f059b600 100644 --- a/mkspecs/winrt-x86-msvc2015/qmake.conf +++ b/mkspecs/winrt-x86-msvc2015/qmake.conf @@ -14,6 +14,5 @@ QMAKE_LFLAGS += /SAFESEH /MACHINE:X86 /NODEFAULTLIB:kernel32.lib QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib OneCore.lib VCPROJ_ARCH = Win32 WINSDK_VER = 10.0 -WINTARGET_VER = winv10.0 WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in WINRT_MANIFEST.architecture = x86 diff --git a/mkspecs/winrt-x86-msvc2017/qmake.conf b/mkspecs/winrt-x86-msvc2017/qmake.conf index 3c9506bbad..94fb68f6c0 100644 --- a/mkspecs/winrt-x86-msvc2017/qmake.conf +++ b/mkspecs/winrt-x86-msvc2017/qmake.conf @@ -14,6 +14,5 @@ QMAKE_LFLAGS += /SAFESEH /MACHINE:X86 /NODEFAULTLIB:kernel32.lib QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib OneCore.lib VCPROJ_ARCH = Win32 WINSDK_VER = 10.0 -WINTARGET_VER = winv10.0 WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in WINRT_MANIFEST.architecture = x86 diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index 548d2e8575..aa3d389b67 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -34,23 +34,10 @@ #include #include -#include - #include QT_BEGIN_NAMESPACE -static QString nmakePathList(const QStringList &list) -{ - QStringList pathList; - pathList.reserve(list.size()); - for (const QString &path : list) - pathList.append(QDir::cleanPath(path)); - - return QDir::toNativeSeparators(pathList.join(QLatin1Char(';'))) - .replace('#', QLatin1String("^#")).replace('$', QLatin1String("$$")); -} - NmakeMakefileGenerator::NmakeMakefileGenerator() : usePCH(false), usePCHC(false) { @@ -70,194 +57,6 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) if(Option::mkfile::do_stub_makefile) return MakefileGenerator::writeStubMakefile(t); #endif - if (!project->isHostBuild()) { - const QString msvcVer = project->first("MSVC_VER").toQString(); - if (msvcVer.isEmpty()) { - fprintf(stderr, "Mkspec does not specify MSVC_VER. Cannot continue.\n"); - return false; - } - - bool winrtBuild = false; - bool crossPlatformDesktopBuild = false; - QString arch = project->first("VCPROJ_ARCH").toQString().toLower(); - if (project->isActiveConfig(QStringLiteral("winrt"))) { - winrtBuild = true; - - // Only add explicit support for arm64 cross-platform desktop builds. - } else if ((arch == QLatin1String("arm64")) && (msvcVer == QStringLiteral("15.0"))) { - crossPlatformDesktopBuild = true; - } - - if (winrtBuild || crossPlatformDesktopBuild) { - QString compiler; - QString compilerArch; - const ProStringList hostArch = project->values("QMAKE_TARGET.arch"); - if (msvcVer == QStringLiteral("15.0")) { - if (hostArch.contains("x86_64")) - compiler = QStringLiteral("HostX64/"); - else - compiler = QStringLiteral("HostX86/"); - if (arch == QLatin1String("arm")) { - compiler += QStringLiteral("arm"); - compilerArch = QStringLiteral("arm"); - } else if (arch == QLatin1String("x64")) { - compiler += QStringLiteral("x64"); - compilerArch = QStringLiteral("amd64"); - } else if (arch == QLatin1String("arm64")) { - compiler += QStringLiteral("arm64"); - compilerArch = QStringLiteral("arm64"); - } else { - arch = QStringLiteral("x86"); - compiler += QStringLiteral("x86"); - } - } else { - if (arch == QLatin1String("arm")) { - compiler = QStringLiteral("x86_arm"); - compilerArch = QStringLiteral("arm"); - } else if (arch == QLatin1String("x64")) { - const ProStringList hostArch = project->values("QMAKE_TARGET.arch"); - if (hostArch.contains("x86_64")) - compiler = QStringLiteral("amd64"); - else - compiler = QStringLiteral("x86_amd64"); - compilerArch = QStringLiteral("amd64"); - } else { - arch = QStringLiteral("x86"); - } - } - - const QString winsdkVer = project->first("WINSDK_VER").toQString(); - if (winsdkVer.isEmpty()) { - fprintf(stderr, "Mkspec does not specify WINSDK_VER. Cannot continue.\n"); - return false; - } - const QString targetVer = project->first("WINTARGET_VER").toQString(); - if (targetVer.isEmpty() && winrtBuild) { - fprintf(stderr, "Mkspec does not specify WINTARGET_VER. Cannot continue.\n"); - return false; - } - -#ifdef Q_OS_WIN - QString regKey; - if (msvcVer == QStringLiteral("15.0")) - regKey = QStringLiteral("Software\\Microsoft\\VisualStudio\\SxS\\VS7\\") + msvcVer; - else - regKey = QStringLiteral("Software\\Microsoft\\VisualStudio\\") + msvcVer + ("\\Setup\\VC\\ProductDir"); - const QString vcInstallDir = qt_readRegistryKey(HKEY_LOCAL_MACHINE, regKey, KEY_WOW64_32KEY); - if (vcInstallDir.isEmpty()) { - fprintf(stderr, "Failed to find the Visual Studio installation directory.\n"); - return false; - } - - const QString windowsPath = "Software\\Microsoft\\Microsoft SDKs\\Windows\\v"; - - regKey = windowsPath + winsdkVer + QStringLiteral("\\InstallationFolder"); - const QString kitDir = qt_readRegistryKey(HKEY_LOCAL_MACHINE, regKey, KEY_WOW64_32KEY); - if (kitDir.isEmpty()) { - fprintf(stderr, "Failed to find the Windows Kit installation directory.\n"); - return false; - } -#else - const QString vcInstallDir = "/fake/vc_install_dir"; - const QString kitDir = "/fake/sdk_install_dir"; -#endif // Q_OS_WIN - QStringList incDirs; - QStringList libDirs; - QStringList binDirs; - if (msvcVer == QStringLiteral("15.0")) { - const QString toolsInstallDir = qgetenv("VCToolsInstallDir"); - if (toolsInstallDir.isEmpty()) { - fprintf(stderr, "Failed to access tools installation dir.\n"); - return false; - } - - binDirs << toolsInstallDir + QStringLiteral("bin/") + compiler; - if (arch == QStringLiteral("x64")) - binDirs << toolsInstallDir + QStringLiteral("bin/HostX86/X86"); - binDirs << kitDir + QStringLiteral("bin/x86"); - binDirs << vcInstallDir + QStringLiteral("Common7/Tools"); - binDirs << vcInstallDir + QStringLiteral("Common7/ide"); - binDirs << vcInstallDir + QStringLiteral("MSBuild/15.0/bin"); - - incDirs << toolsInstallDir + QStringLiteral("include"); - incDirs << vcInstallDir + QStringLiteral("VC/Auxiliary/VS/include"); - - const QString crtVersion = qgetenv("UCRTVersion"); - if (crtVersion.isEmpty()) { - fprintf(stderr, "Failed to access CRT version.\n"); - return false; - } - const QString crtInclude = kitDir + QStringLiteral("Include/") + crtVersion; - const QString crtLib = kitDir + QStringLiteral("Lib/") + crtVersion; - incDirs << crtInclude + QStringLiteral("/ucrt"); - incDirs << crtInclude + QStringLiteral("/um"); - incDirs << crtInclude + QStringLiteral("/shared"); - incDirs << crtInclude + QStringLiteral("/winrt"); - - if (winrtBuild) { - libDirs << toolsInstallDir + QStringLiteral("lib/") + arch + QStringLiteral("/store"); - } else { - // Desktop projects may require the atl headers and libs. - incDirs << toolsInstallDir + QStringLiteral("atlmfc/include"); - libDirs << toolsInstallDir + QStringLiteral("atlmfc/lib/") + compilerArch; - libDirs << toolsInstallDir + QStringLiteral("lib/") + arch; - } - - libDirs << vcInstallDir + QStringLiteral("VC/Auxiliary/VS/lib/") + arch; - - libDirs << crtLib + QStringLiteral("/ucrt/") + arch; - libDirs << crtLib + QStringLiteral("/um/") + arch; - } else if (msvcVer == QStringLiteral("14.0")) { - binDirs << vcInstallDir + QStringLiteral("bin/") + compiler; - binDirs << vcInstallDir + QStringLiteral("bin/"); // Maybe remove for x86 again? - binDirs << kitDir + QStringLiteral("bin/") + (arch == QStringLiteral("arm") ? QStringLiteral("x86") : arch); - binDirs << vcInstallDir + QStringLiteral("../Common7/Tools/bin"); - binDirs << vcInstallDir + QStringLiteral("../Common7/Tools"); - binDirs << vcInstallDir + QStringLiteral("../Common7/ide"); - binDirs << kitDir + QStringLiteral("Windows Performance Toolkit/"); - - incDirs << vcInstallDir + QStringLiteral("include"); - incDirs << vcInstallDir + QStringLiteral("atlmfc/include"); - - const QString crtVersion = qgetenv("UCRTVersion"); - if (crtVersion.isEmpty()) { - fprintf(stderr, "Failed to access CRT version.\n"); - return false; - } - const QString crtInclude = kitDir + QStringLiteral("Include/") + crtVersion; - const QString crtLib = kitDir + QStringLiteral("Lib/") + crtVersion; - incDirs << crtInclude + QStringLiteral("/ucrt"); - incDirs << crtInclude + QStringLiteral("/um"); - incDirs << crtInclude + QStringLiteral("/shared"); - incDirs << crtInclude + QStringLiteral("/winrt"); - - libDirs << vcInstallDir + QStringLiteral("lib/store/") + compilerArch; - libDirs << vcInstallDir + QStringLiteral("atlmfc/lib") + compilerArch; - - libDirs << crtLib + QStringLiteral("/ucrt/") + arch; - libDirs << crtLib + QStringLiteral("/um/") + arch; - } else { - incDirs << vcInstallDir + QStringLiteral("/include"); - libDirs << vcInstallDir + QStringLiteral("/lib/store/") + compilerArch - << vcInstallDir + QStringLiteral("/lib/") + compilerArch; - binDirs << vcInstallDir + QStringLiteral("/bin/") + compiler - << vcInstallDir + QStringLiteral("/../Common7/IDE"); - libDirs << kitDir + QStringLiteral("/Lib/") + targetVer + ("/um/") + arch; - incDirs << kitDir + QStringLiteral("/include/um") - << kitDir + QStringLiteral("/include/shared") - << kitDir + QStringLiteral("/include/winrt"); - } - - binDirs << vcInstallDir + QStringLiteral("/bin"); - - // Inherit PATH - binDirs << QString::fromLocal8Bit(qgetenv("PATH")).split(QLatin1Char(';')); - - t << "\nINCLUDE = " << nmakePathList(incDirs); - t << "\nLIB = " << nmakePathList(libDirs); - t << "\nPATH = " << nmakePathList(binDirs) << '\n'; - } - } writeNmakeParts(t); return MakefileGenerator::writeMakefile(t); } From ecdccce8e468784e050b65052da193bb40e2d9b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Fri, 4 Jan 2019 13:48:56 +0100 Subject: [PATCH 0786/1650] Fix warnings about uninitialized variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qtbase/src/corelib/kernel/qmetatype.cpp: In static member function ‘static void QMetaType::destroy(int, void*)’: qtbase/src/corelib/kernel/qmetatype.cpp:2599:27: error: ‘info.QMetaType::m_destructor’ may be used uninitialized in this function [-Werror=maybe-uninitialized] if (m_typedDestructor && !m_destructor) ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~ qtbase/src/corelib/kernel/qmetatype.cpp:1868:15: note: ‘info.QMetaType::m_destructor’ was declared here QMetaType info(type); ^~~~ qtbase/src/corelib/kernel/qmetatype.cpp:2600:26: error: ‘info.QMetaType::m_typedDestructor’ may be used uninitialized in this function [-Werror=maybe-uninitialized] m_typedDestructor(m_typeId, data); ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~ qtbase/src/corelib/kernel/qmetatype.cpp:1868:15: note: ‘info.QMetaType::m_typedDestructor’ was declared here QMetaType info(type); ^~~~ The extended (not inlined) function may be called on a half initialized invalid instance. Change-Id: I26d677a8ad2bd0c5846233f06393e774d377936d Reviewed-by: Liang Qi Reviewed-by: Thiago Macieira --- src/corelib/kernel/qmetatype.cpp | 6 ++++++ tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp | 11 +++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index eb67544f21..632b86959d 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -2566,6 +2566,8 @@ void *QMetaType::createExtended(const void *copy) const */ void QMetaType::destroyExtended(void *data) const { + if (m_typeId == QMetaType::UnknownType) + return; if (Q_UNLIKELY(m_typedDestructor && !m_destructor)) m_typedDestructor(m_typeId, data); else @@ -2582,6 +2584,8 @@ void QMetaType::destroyExtended(void *data) const */ void *QMetaType::constructExtended(void *where, const void *copy) const { + if (m_typeId == QMetaType::UnknownType) + return nullptr; if (m_typedConstructor && !m_constructor) return m_typedConstructor(m_typeId, where, copy); return nullptr; @@ -2596,6 +2600,8 @@ void *QMetaType::constructExtended(void *where, const void *copy) const */ void QMetaType::destructExtended(void *data) const { + if (m_typeId == QMetaType::UnknownType) + return; if (m_typedDestructor && !m_destructor) m_typedDestructor(m_typeId, data); } diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index 5d9b5ca95c..e6fac74ccc 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -123,6 +123,7 @@ private slots: void compareCustomType(); void compareCustomEqualOnlyType(); void customDebugStream(); + void unknownType(); }; struct BaseGenericType @@ -2529,6 +2530,16 @@ void tst_QMetaType::customDebugStream() qDebug() << v1; } +void tst_QMetaType::unknownType() +{ + QMetaType invalid(QMetaType::UnknownType); + QVERIFY(!invalid.create()); + QVERIFY(!invalid.sizeOf()); + QVERIFY(!invalid.metaObject()); + int buffer = 0xBAD; + invalid.construct(&buffer); + QCOMPARE(buffer, 0xBAD); +} // Compile-time test, it should be possible to register function pointer types class Undefined; From 7984327c40a09cdd79f03a52649484e5f0c5704c Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Mon, 31 Dec 2018 17:41:11 +0100 Subject: [PATCH 0787/1650] Network examples: cleanup foreach usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace deprecated foreach macro with range-based for loop Change-Id: I0d1f2cfd557d02ccc48b41b3fea137baa2962fc1 Reviewed-by: André Hartmann Reviewed-by: Timur Pocheptsov --- .../network/bearermonitor/bearermonitor.cpp | 6 ++- examples/network/dnslookup/dnslookup.cpp | 24 +++++++---- examples/network/http/httpwindow.cpp | 2 +- examples/network/network-chat/client.cpp | 7 ++-- examples/network/network-chat/peermanager.cpp | 12 +++--- examples/network/network-chat/peermanager.h | 2 +- examples/network/torrent/addtorrentdialog.cpp | 3 +- examples/network/torrent/filemanager.cpp | 7 ++-- examples/network/torrent/mainwindow.cpp | 6 +-- examples/network/torrent/metainfo.cpp | 8 ++-- examples/network/torrent/ratecontroller.cpp | 4 +- examples/network/torrent/torrentclient.cpp | 42 +++++++++---------- examples/network/torrent/torrentserver.cpp | 2 +- 13 files changed, 69 insertions(+), 56 deletions(-) diff --git a/examples/network/bearermonitor/bearermonitor.cpp b/examples/network/bearermonitor/bearermonitor.cpp index f9b899b06b..1a54f5ec8a 100644 --- a/examples/network/bearermonitor/bearermonitor.cpp +++ b/examples/network/bearermonitor/bearermonitor.cpp @@ -142,7 +142,8 @@ void BearerMonitor::configurationAdded(const QNetworkConfiguration &config, QTre treeWidget->addTopLevelItem(item); if (config.type() == QNetworkConfiguration::ServiceNetwork) { - foreach (const QNetworkConfiguration &child, config.children()) + const QList children = config.children(); + for (const QNetworkConfiguration &child : children) configurationAdded(child, item); } } @@ -181,7 +182,8 @@ void BearerMonitor::configurationChanged(const QNetworkConfiguration &config) void BearerMonitor::updateSnapConfiguration(QTreeWidgetItem *parent, const QNetworkConfiguration &snap) { QMap itemMap; - foreach (QTreeWidgetItem *item, parent->takeChildren()) + const QList children = parent->takeChildren(); + for (QTreeWidgetItem *item : children) itemMap.insert(item->data(0, Qt::UserRole).toString(), item); QList allConfigurations = snap.children(); diff --git a/examples/network/dnslookup/dnslookup.cpp b/examples/network/dnslookup/dnslookup.cpp index 63819b170c..a2d927d43d 100644 --- a/examples/network/dnslookup/dnslookup.cpp +++ b/examples/network/dnslookup/dnslookup.cpp @@ -172,35 +172,43 @@ void DnsManager::showResults() printf("Error: %i (%s)\n", dns->error(), qPrintable(dns->errorString())); // CNAME records - foreach (const QDnsDomainNameRecord &record, dns->canonicalNameRecords()) + const QList cnameRecords = dns->canonicalNameRecords(); + for (const QDnsDomainNameRecord &record : cnameRecords) printf("%s\t%i\tIN\tCNAME\t%s\n", qPrintable(record.name()), record.timeToLive(), qPrintable(record.value())); // A and AAAA records - foreach (const QDnsHostAddressRecord &record, dns->hostAddressRecords()) { + const QList aRecords = dns->hostAddressRecords(); + for (const QDnsHostAddressRecord &record : aRecords) { const char *type = (record.value().protocol() == QAbstractSocket::IPv6Protocol) ? "AAAA" : "A"; printf("%s\t%i\tIN\t%s\t%s\n", qPrintable(record.name()), record.timeToLive(), type, qPrintable(record.value().toString())); } // MX records - foreach (const QDnsMailExchangeRecord &record, dns->mailExchangeRecords()) + const QList mxRecords = dns->mailExchangeRecords(); + for (const QDnsMailExchangeRecord &record : mxRecords) printf("%s\t%i\tIN\tMX\t%u %s\n", qPrintable(record.name()), record.timeToLive(), record.preference(), qPrintable(record.exchange())); // NS records - foreach (const QDnsDomainNameRecord &record, dns->nameServerRecords()) + const QList nsRecords = dns->nameServerRecords(); + for (const QDnsDomainNameRecord &record : nsRecords) printf("%s\t%i\tIN\tNS\t%s\n", qPrintable(record.name()), record.timeToLive(), qPrintable(record.value())); // PTR records - foreach (const QDnsDomainNameRecord &record, dns->pointerRecords()) + const QList ptrRecords = dns->pointerRecords(); + for (const QDnsDomainNameRecord &record : ptrRecords) printf("%s\t%i\tIN\tPTR\t%s\n", qPrintable(record.name()), record.timeToLive(), qPrintable(record.value())); // SRV records - foreach (const QDnsServiceRecord &record, dns->serviceRecords()) + const QList srvRecords = dns->serviceRecords(); + for (const QDnsServiceRecord &record : srvRecords) printf("%s\t%i\tIN\tSRV\t%u %u %u %s\n", qPrintable(record.name()), record.timeToLive(), record.priority(), record.weight(), record.port(), qPrintable(record.target())); // TXT records - foreach (const QDnsTextRecord &record, dns->textRecords()) { + const QList txtRecords = dns->textRecords(); + for (const QDnsTextRecord &record : txtRecords) { QStringList values; - foreach (const QByteArray &ba, record.values()) + const QList dnsRecords = record.values(); + for (const QByteArray &ba : dnsRecords) values << "\"" + QString::fromLatin1(ba) + "\""; printf("%s\t%i\tIN\tTXT\t%s\n", qPrintable(record.name()), record.timeToLive(), qPrintable(values.join(' '))); } diff --git a/examples/network/http/httpwindow.cpp b/examples/network/http/httpwindow.cpp index ec90b8f7fe..39ffb3cc87 100644 --- a/examples/network/http/httpwindow.cpp +++ b/examples/network/http/httpwindow.cpp @@ -319,7 +319,7 @@ void HttpWindow::slotAuthenticationRequired(QNetworkReply *, QAuthenticator *aut void HttpWindow::sslErrors(QNetworkReply *, const QList &errors) { QString errorString; - foreach (const QSslError &error, errors) { + for (const QSslError &error : errors) { if (!errorString.isEmpty()) errorString += '\n'; errorString += error.errorString(); diff --git a/examples/network/network-chat/client.cpp b/examples/network/network-chat/client.cpp index 97c2c44b6b..b76ef18238 100644 --- a/examples/network/network-chat/client.cpp +++ b/examples/network/network-chat/client.cpp @@ -71,8 +71,7 @@ void Client::sendMessage(const QString &message) if (message.isEmpty()) return; - QList connections = peers.values(); - foreach (Connection *connection, connections) + for (Connection *connection : qAsConst(peers)) connection->sendMessage(message); } @@ -90,8 +89,8 @@ bool Client::hasConnection(const QHostAddress &senderIp, int senderPort) const if (!peers.contains(senderIp)) return false; - QList connections = peers.values(senderIp); - foreach (Connection *connection, connections) { + const QList connections = peers.values(senderIp); + for (const Connection *connection : connections) { if (connection->peerPort() == senderPort) return true; } diff --git a/examples/network/network-chat/peermanager.cpp b/examples/network/network-chat/peermanager.cpp index 38fa2e8e50..5c48edb1b9 100644 --- a/examples/network/network-chat/peermanager.cpp +++ b/examples/network/network-chat/peermanager.cpp @@ -104,9 +104,9 @@ void PeerManager::startBroadcasting() broadcastTimer.start(); } -bool PeerManager::isLocalHostAddress(const QHostAddress &address) +bool PeerManager::isLocalHostAddress(const QHostAddress &address) const { - foreach (QHostAddress localAddress, ipAddresses) { + for (const QHostAddress &localAddress : ipAddresses) { if (address.isEqual(localAddress)) return true; } @@ -125,7 +125,7 @@ void PeerManager::sendBroadcastDatagram() } bool validBroadcastAddresses = true; - foreach (QHostAddress address, broadcastAddresses) { + for (const QHostAddress &address : qAsConst(broadcastAddresses)) { if (broadcastSocket.writeDatagram(datagram, address, broadcastPort) == -1) validBroadcastAddresses = false; @@ -182,8 +182,10 @@ void PeerManager::updateAddresses() { broadcastAddresses.clear(); ipAddresses.clear(); - foreach (QNetworkInterface interface, QNetworkInterface::allInterfaces()) { - foreach (QNetworkAddressEntry entry, interface.addressEntries()) { + const QList interfaces = QNetworkInterface::allInterfaces(); + for (const QNetworkInterface &interface : interfaces) { + const QList entries = interface.addressEntries(); + for (const QNetworkAddressEntry &entry : entries) { QHostAddress broadcastAddress = entry.broadcast(); if (broadcastAddress != QHostAddress::Null && entry.ip() != QHostAddress::LocalHost) { broadcastAddresses << broadcastAddress; diff --git a/examples/network/network-chat/peermanager.h b/examples/network/network-chat/peermanager.h index b79028235b..6105c83115 100644 --- a/examples/network/network-chat/peermanager.h +++ b/examples/network/network-chat/peermanager.h @@ -70,7 +70,7 @@ public: void setServerPort(int port); QString userName() const; void startBroadcasting(); - bool isLocalHostAddress(const QHostAddress &address); + bool isLocalHostAddress(const QHostAddress &address) const; signals: void newConnection(Connection *connection); diff --git a/examples/network/torrent/addtorrentdialog.cpp b/examples/network/torrent/addtorrentdialog.cpp index 0d197ec5fa..c87110ac4a 100644 --- a/examples/network/torrent/addtorrentdialog.cpp +++ b/examples/network/torrent/addtorrentdialog.cpp @@ -148,7 +148,8 @@ void AddTorrentDialog::setTorrent(const QString &torrentFile) ui.torrentContents->setHtml(metaInfo.singleFile().name); } else { QString html; - foreach (MetaInfoMultiFile file, metaInfo.multiFiles()) { + const QList multiFiles = metaInfo.multiFiles(); + for (const MetaInfoMultiFile &file : multiFiles) { QString name = metaInfo.name(); if (!name.isEmpty()) { html += name; diff --git a/examples/network/torrent/filemanager.cpp b/examples/network/torrent/filemanager.cpp index d05408cebc..69345442c7 100644 --- a/examples/network/torrent/filemanager.cpp +++ b/examples/network/torrent/filemanager.cpp @@ -77,7 +77,7 @@ FileManager::~FileManager() cond.wakeOne(); wait(); - foreach (QFile *file, files) { + for (QFile *file : qAsConst(files)) { file->close(); delete file; } @@ -285,7 +285,8 @@ bool FileManager::generateFiles() return false; } - foreach (const MetaInfoMultiFile &entry, metaInfo.multiFiles()) { + const QList multiFiles = metaInfo.multiFiles(); + for (const MetaInfoMultiFile &entry : multiFiles) { QString filePath = QFileInfo(prefix + entry.path).path(); if (!QFile::exists(filePath)) { if (!dir.mkpath(filePath)) { @@ -437,7 +438,7 @@ void FileManager::verifyFileContents() } // Verify all pending pieces - foreach (int index, newPendingVerificationRequests) + for (int index : qAsConst(newPendingVerificationRequests)) emit pieceVerified(index, verifySinglePiece(index)); } diff --git a/examples/network/torrent/mainwindow.cpp b/examples/network/torrent/mainwindow.cpp index 660472c05c..39b166101d 100644 --- a/examples/network/torrent/mainwindow.cpp +++ b/examples/network/torrent/mainwindow.cpp @@ -239,7 +239,7 @@ int MainWindow::rowOfClient(TorrentClient *client) const // Return the row that displays this client's status, or -1 if the // client is not known. int row = 0; - foreach (Job job, jobs) { + for (const Job &job : jobs) { if (job.client == client) return row; ++row; @@ -358,7 +358,7 @@ bool MainWindow::addTorrent(const QString &fileName, const QString &destinationF const QByteArray &resumeState) { // Check if the torrent is already being downloaded. - foreach (Job job, jobs) { + for (const Job &job : qAsConst(jobs)) { if (job.torrentFileName == fileName && job.destinationDirectory == destinationFolder) { QMessageBox::warning(this, tr("Already downloading"), tr("The torrent file %1 is " @@ -684,7 +684,7 @@ void MainWindow::closeEvent(QCloseEvent *) // them to signal that they have stopped. jobsToStop = 0; jobsStopped = 0; - foreach (Job job, jobs) { + for (const Job &job : qAsConst(jobs)) { ++jobsToStop; TorrentClient *client = job.client; client->disconnect(); diff --git a/examples/network/torrent/metainfo.cpp b/examples/network/torrent/metainfo.cpp index 565533e2f9..29b34b12a0 100644 --- a/examples/network/torrent/metainfo.cpp +++ b/examples/network/torrent/metainfo.cpp @@ -101,10 +101,10 @@ bool MetaInfo::parse(const QByteArray &data) QList files = info.value("files").toList(); for (int i = 0; i < files.size(); ++i) { - QMap file = qvariant_cast(files.at(i)); - QList pathElements = file.value("path").toList(); + const QMap file = qvariant_cast(files.at(i)); + const QList pathElements = file.value("path").toList(); QByteArray path; - foreach (QVariant p, pathElements) { + for (const QVariant &p : pathElements) { if (!path.isEmpty()) path += '/'; path += p.toByteArray(); @@ -221,7 +221,7 @@ qint64 MetaInfo::totalSize() const return singleFile().length; qint64 size = 0; - foreach (MetaInfoMultiFile file, multiFiles()) + for (const MetaInfoMultiFile &file : metaInfoMultiFiles) size += file.length; return size; } diff --git a/examples/network/torrent/ratecontroller.cpp b/examples/network/torrent/ratecontroller.cpp index cec05c7455..47b49dba30 100644 --- a/examples/network/torrent/ratecontroller.cpp +++ b/examples/network/torrent/ratecontroller.cpp @@ -78,7 +78,7 @@ void RateController::removeSocket(PeerWireClient *socket) void RateController::setDownloadLimit(int bytesPerSecond) { downLimit = bytesPerSecond; - foreach (PeerWireClient *socket, sockets) + for (PeerWireClient *socket : qAsConst(sockets)) socket->setReadBufferSize(downLimit * 4); } @@ -108,7 +108,7 @@ void RateController::transfer() } QSet pendingSockets; - foreach (PeerWireClient *client, sockets) { + for (PeerWireClient *client : qAsConst(sockets)) { if (client->canTransferMore()) pendingSockets << client; } diff --git a/examples/network/torrent/torrentclient.cpp b/examples/network/torrent/torrentclient.cpp index 95232646ab..d01a5f3d9e 100644 --- a/examples/network/torrent/torrentclient.cpp +++ b/examples/network/torrent/torrentclient.cpp @@ -383,7 +383,7 @@ qint64 TorrentClient::uploadedBytes() const int TorrentClient::connectedPeerCount() const { int tmp = 0; - foreach (PeerWireClient *client, d->connections) { + for (PeerWireClient *client : d->connections) { if (client->state() == QAbstractSocket::ConnectedState) ++tmp; } @@ -393,7 +393,7 @@ int TorrentClient::connectedPeerCount() const int TorrentClient::seedCount() const { int tmp = 0; - foreach (PeerWireClient *client, d->connections) { + for (PeerWireClient *client : d->connections) { if (client->availablePieces().count(true) == d->pieceCount) ++tmp; } @@ -464,7 +464,7 @@ void TorrentClient::stop() } // Abort all existing connections - foreach (PeerWireClient *client, d->connections) { + for (PeerWireClient *client : qAsConst(d->connections)) { RateController::instance()->removeSocket(client); ConnectionManager::instance()->removeConnection(client); client->abort(); @@ -487,7 +487,7 @@ void TorrentClient::setPaused(bool paused) // connections to 0. Keep the list of peers, so we can quickly // resume later. d->setState(Paused); - foreach (PeerWireClient *client, d->connections) + for (PeerWireClient *client : qAsConst(d->connections)) client->abort(); d->connections.clear(); TorrentServer::instance()->removeClient(this); @@ -622,7 +622,7 @@ void TorrentClient::pieceVerified(int pieceIndex, bool ok) } // Update the peer list so we know who's still interesting. - foreach (TorrentPeer *peer, d->peers) { + for (TorrentPeer *peer : qAsConst(d->peers)) { if (!peer->interesting) continue; bool interesting = false; @@ -642,7 +642,7 @@ void TorrentClient::pieceVerified(int pieceIndex, bool ok) d->incompletePieces.clearBit(pieceIndex); // Notify connected peers. - foreach (PeerWireClient *client, d->connections) { + for (PeerWireClient *client : qAsConst(d->connections)) { if (client->state() == QAbstractSocket::ConnectedState && !client->availablePieces().testBit(pieceIndex)) { client->sendPieceNotification(pieceIndex); @@ -720,9 +720,9 @@ QList TorrentClient::weighedFreePeers() const qint64 now = QDateTime::currentSecsSinceEpoch(); QList freePeers; QMap connectionsPerPeer; - foreach (TorrentPeer *peer, d->peers) { + for (TorrentPeer *peer : d->peers) { bool busy = false; - foreach (PeerWireClient *client, d->connections) { + for (PeerWireClient *client : d->connections) { if (client->state() == PeerWireClient::ConnectedState && client->peerAddress() == peer->address && client->peerPort() == peer->port) { @@ -742,7 +742,7 @@ QList TorrentClient::weighedFreePeers() const // Assign points based on connection speed and pieces available. QList > points; - foreach (TorrentPeer *peer, freePeers) { + for (TorrentPeer *peer : qAsConst(freePeers)) { int tmp = 0; if (peer->interesting) { tmp += peer->numCompletedPieces; @@ -765,7 +765,7 @@ QList TorrentClient::weighedFreePeers() const QMultiMap pointMap; int lowestScore = 0; int lastIndex = 0; - foreach (PointPair point, points) { + for (const PointPair &point : qAsConst(points)) { if (point.first > lowestScore) { lowestScore = point.first; ++lastIndex; @@ -816,7 +816,7 @@ void TorrentClient::setupOutgoingConnection() PeerWireClient *client = qobject_cast(sender()); // Update connection statistics. - foreach (TorrentPeer *peer, d->peers) { + for (TorrentPeer *peer : qAsConst(d->peers)) { if (peer->port == client->peerPort() && peer->address == client->peerAddress()) { peer->connectTime = peer->lastVisited - peer->connectStart; break; @@ -1085,7 +1085,7 @@ void TorrentClient::scheduleUploads() // no use in unchoking them. QList allClients = d->connections; QMultiMap transferSpeeds; - foreach (PeerWireClient *client, allClients) { + for (PeerWireClient *client : qAsConst(allClients)) { if (client->state() == QAbstractSocket::ConnectedState && client->availablePieces().count(true) != d->pieceCount) { if (d->state == Seeding) { @@ -1143,7 +1143,7 @@ void TorrentClient::scheduleDownloads() // Check what each client is doing, and assign payloads to those // who are either idle or done. - foreach (PeerWireClient *client, d->connections) + for (PeerWireClient *client : qAsConst(d->connections)) schedulePieceForClient(client); } @@ -1222,7 +1222,7 @@ void TorrentClient::schedulePieceForClient(PeerWireClient *client) incompletePiecesAvailableToClient &= client->availablePieces(); // Remove all pieces that this client has already requested. - foreach (int i, currentPieces) + for (int i : qAsConst(currentPieces)) incompletePiecesAvailableToClient.clearBit(i); // Only continue if more pieces can be scheduled. If no pieces @@ -1258,7 +1258,7 @@ void TorrentClient::schedulePieceForClient(PeerWireClient *client) memset(occurrences, 0, d->pieceCount * sizeof(int)); // Count how many of each piece are available. - foreach (PeerWireClient *peer, d->connections) { + for (PeerWireClient *peer : qAsConst(d->connections)) { QBitArray peerPieces = peer->availablePieces(); int peerPiecesSize = peerPieces.size(); for (int i = 0; i < peerPiecesSize; ++i) { @@ -1356,7 +1356,7 @@ void TorrentClient::requestMore(PeerWireClient *client) // Starting with the first piece that we're waiting for, request // blocks until the quota is filled up. - foreach (TorrentPiece *piece, piecesInProgress) { + for (TorrentPiece *piece : qAsConst(piecesInProgress)) { numBlocksInProgress += requestBlocks(client, piece, maxInProgress - numBlocksInProgress); if (numBlocksInProgress == maxInProgress) break; @@ -1450,8 +1450,8 @@ void TorrentClient::peerUnchoked() void TorrentClient::addToPeerList(const QList &peerList) { // Add peers we don't already know of to our list of peers. - QList addresses = QNetworkInterface::allAddresses(); - foreach (TorrentPeer peer, peerList) { + const QList addresses = QNetworkInterface::allAddresses(); + for (const TorrentPeer &peer : peerList) { if (addresses.contains(peer.address) && peer.port == TorrentServer::instance()->serverPort()) { // Skip our own server. @@ -1459,7 +1459,7 @@ void TorrentClient::addToPeerList(const QList &peerList) } bool known = false; - foreach (TorrentPeer *knownPeer, d->peers) { + for (const TorrentPeer *knownPeer : qAsConst(d->peers)) { if (knownPeer->port == peer.port && knownPeer->address == peer.address) { known = true; @@ -1486,8 +1486,8 @@ void TorrentClient::addToPeerList(const QList &peerList) if (d->peers.size() > maxPeers) { // Find what peers are currently connected & active QSet activePeers; - foreach (TorrentPeer *peer, d->peers) { - foreach (PeerWireClient *client, d->connections) { + for (TorrentPeer *peer : qAsConst(d->peers)) { + for (const PeerWireClient *client : qAsConst(d->connections)) { if (client->peer() == peer && (client->downloadSpeed() + client->uploadSpeed()) > 1024) activePeers << peer; } diff --git a/examples/network/torrent/torrentserver.cpp b/examples/network/torrent/torrentserver.cpp index da98529fe0..c68f33249c 100644 --- a/examples/network/torrent/torrentserver.cpp +++ b/examples/network/torrent/torrentserver.cpp @@ -102,7 +102,7 @@ void TorrentServer::removeClient() void TorrentServer::processInfoHash(const QByteArray &infoHash) { PeerWireClient *peer = qobject_cast(sender()); - foreach (TorrentClient *client, clients) { + for (TorrentClient *client : qAsConst(clients)) { if (client->state() >= TorrentClient::Searching && client->infoHash() == infoHash) { peer->disconnect(peer, 0, this, 0); client->setupIncomingConnection(peer); From 0b736d91b779c9f475ccb6a21339d0aa1cada2e4 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sat, 29 Dec 2018 12:45:45 +0100 Subject: [PATCH 0788/1650] QFormLayout: honor Qt::AlignHCenter for labelAlignment The QFormLayout did not handle Qt::AlignCenter, only Qt::AlignLeft/Right for the labelAlignment property. Therefore also add the code for Qt::AlignHCenter to be consistent Fixes: QTBUG-2780 Change-Id: I0d6dd61ba583e3ee37a003fae000d992505c08d1 Reviewed-by: Richard Moe Gustavsen --- src/widgets/kernel/qformlayout.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/widgets/kernel/qformlayout.cpp b/src/widgets/kernel/qformlayout.cpp index 101ce8b64c..7cdddf3133 100644 --- a/src/widgets/kernel/qformlayout.cpp +++ b/src/widgets/kernel/qformlayout.cpp @@ -2209,8 +2209,11 @@ void QFormLayoutPrivate::arrangeWidgets(const QVector& layouts, Q QSize sz(qMin(label->layoutWidth, label->sizeHint.width()), height); int x = leftOffset + rect.x() + label->layoutPos; - if (fixedAlignment(q->labelAlignment(), layoutDirection) & Qt::AlignRight) + const auto fAlign = fixedAlignment(q->labelAlignment(), layoutDirection); + if (fAlign & Qt::AlignRight) x += label->layoutWidth - sz.width(); + else if (fAlign & Qt::AlignHCenter) + x += label->layoutWidth / 2 - sz.width() / 2; QPoint p(x, layouts.at(label->vLayoutIndex).pos); // ### expansion & sizepolicy stuff From 3456d516504c70226934826393284b1eb6d9c35d Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sun, 23 Dec 2018 14:24:20 +0100 Subject: [PATCH 0789/1650] QProgressDialog: remove unused QCursor member The private member parentCursor was not populated since Qt4 times. This lead to an unexpected behavior: When QProgressDialog::reset() was called and value() was greater than 0, the cursor of the parent was set to a default-constructed QCursor. Therefore remove QProgressDialogPrivate::parentCursor. Fixes: QTBUG-72660 Change-Id: I195688300e07ddbbb7c17a9f471513c542269c2a Reviewed-by: Giuseppe D'Angelo Reviewed-by: Friedemann Kleint --- src/widgets/dialogs/qprogressdialog.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/widgets/dialogs/qprogressdialog.cpp b/src/widgets/dialogs/qprogressdialog.cpp index 4bf78e2115..854043e48f 100644 --- a/src/widgets/dialogs/qprogressdialog.cpp +++ b/src/widgets/dialogs/qprogressdialog.cpp @@ -47,7 +47,6 @@ #include "qapplication.h" #include "qstyle.h" #include "qpushbutton.h" -#include "qcursor.h" #include "qtimer.h" #include "qelapsedtimer.h" #include @@ -94,9 +93,6 @@ public: bool cancellation_flag; bool setValue_called; QElapsedTimer starttime; -#ifndef QT_NO_CURSOR - QCursor parentCursor; -#endif int showTime; bool autoClose; bool autoReset; @@ -597,12 +593,6 @@ void QProgressDialog::setRange(int minimum, int maximum) void QProgressDialog::reset() { Q_D(QProgressDialog); -#ifndef QT_NO_CURSOR - if (value() >= 0) { - if (parentWidget()) - parentWidget()->setCursor(d->parentCursor); - } -#endif if (d->autoClose || d->forceHide) hide(); d->bar->reset(); From 283008e123e5eacb83869682528b2024186634f8 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Thu, 6 Dec 2018 18:13:47 +0100 Subject: [PATCH 0790/1650] Doc: replace QItemDelegate with QStyledItemDelegate Since QStyledItemDelegate should be preferred over QItemDelegate the documentation should point to QStyledItemDelegate instead. Also mark some internal classes which derive from QItemDelegate so they will not be forgotten during Qt6 porting. Change-Id: I2dd17feedf8593afac5ca16d2546e1f0bc0250ae Reviewed-by: Paul Wicking Reviewed-by: Konstantin Shegunov Reviewed-by: Richard Moe Gustavsen --- src/sql/models/qsqlrelationaldelegate.h | 2 +- src/widgets/doc/src/model-view-programming.qdoc | 16 ++++++++-------- src/widgets/itemviews/qabstractitemdelegate.cpp | 4 ++-- src/widgets/itemviews/qabstractitemview.cpp | 2 +- src/widgets/itemviews/qcolumnview_p.h | 1 + src/widgets/itemviews/qdatawidgetmapper.cpp | 1 + src/widgets/itemviews/qitemeditorfactory.cpp | 16 ++++++++-------- src/widgets/itemviews/qlistwidget.cpp | 2 +- src/widgets/itemviews/qtableview.cpp | 2 +- src/widgets/itemviews/qtreewidget.cpp | 2 +- src/widgets/util/qcompleter_p.h | 1 + src/widgets/widgets/qcalendarwidget.cpp | 1 + src/widgets/widgets/qcombobox_p.h | 1 + 13 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/sql/models/qsqlrelationaldelegate.h b/src/sql/models/qsqlrelationaldelegate.h index e8ae5a229d..e52ded5a18 100644 --- a/src/sql/models/qsqlrelationaldelegate.h +++ b/src/sql/models/qsqlrelationaldelegate.h @@ -58,7 +58,7 @@ QT_REQUIRE_CONFIG(sqlmodel); #include QT_BEGIN_NAMESPACE - +// ### Qt6: QStyledItemDelegate class QSqlRelationalDelegate: public QItemDelegate { static int fieldIndex(const QSqlTableModel *const model, diff --git a/src/widgets/doc/src/model-view-programming.qdoc b/src/widgets/doc/src/model-view-programming.qdoc index f6b7c80656..83397c90b6 100644 --- a/src/widgets/doc/src/model-view-programming.qdoc +++ b/src/widgets/doc/src/model-view-programming.qdoc @@ -693,9 +693,9 @@ \l QAbstractItemDelegate class. Delegates are expected to be able to render their contents themselves - by implementing the \l{QItemDelegate::paint()}{paint()} - and \l{QItemDelegate::sizeHint()}{sizeHint()} functions. - However, simple widget-based delegates can subclass \l QItemDelegate + by implementing the \l{QStyledItemDelegate::paint()}{paint()} + and \l{QStyledItemDelegate::sizeHint()}{sizeHint()} functions. + However, simple widget-based delegates can subclass \l QStyledItemDelegate instead of \l QAbstractItemDelegate, and take advantage of the default implementations of these functions. @@ -709,14 +709,14 @@ \section2 Using an existing delegate - The standard views provided with Qt use instances of \l QItemDelegate + The standard views provided with Qt use instances of \l QStyledItemDelegate to provide editing facilities. This default implementation of the delegate interface renders items in the usual style for each of the standard views: \l QListView, \l QTableView, and \l QTreeView. All the standard roles are handled by the default delegate used by the standard views. The way these are interpreted is described in the - QItemDelegate documentation. + QStyledItemDelegate documentation. The delegate used by a view is returned by the \l{QAbstractItemView::itemDelegate()}{itemDelegate()} function. @@ -799,7 +799,7 @@ In this case, we ensure that the spin box is up-to-date, and update the model with the value it contains using the index specified. - The standard \l QItemDelegate class informs the view when it has + The standard \l QStyledItemDelegate class informs the view when it has finished editing by emitting the \l{QAbstractItemDelegate::closeEditor()}{closeEditor()} signal. The view ensures that the editor widget is closed and destroyed. In @@ -838,11 +838,11 @@ assist any subsequent editing operations. This is achieved by emitting the \l{QAbstractItemDelegate::closeEditor()}{closeEditor()} signal with a suitable hint. This is taken care of by the default - QItemDelegate event filter which we installed on the spin box when + QStyledItemDelegate event filter which we installed on the spin box when it was constructed. The behavior of the spin box could be adjusted to make it more user - friendly. In the default event filter supplied by QItemDelegate, if + friendly. In the default event filter supplied by QStyledItemDelegate, if the user hits \uicontrol Return to confirm their choice in the spin box, the delegate commits the value to the model and closes the spin box. We can change this behavior by installing our own event filter on the diff --git a/src/widgets/itemviews/qabstractitemdelegate.cpp b/src/widgets/itemviews/qabstractitemdelegate.cpp index 7bc0ece4b3..6e46eefa38 100644 --- a/src/widgets/itemviews/qabstractitemdelegate.cpp +++ b/src/widgets/itemviews/qabstractitemdelegate.cpp @@ -88,7 +88,7 @@ QT_BEGIN_NAMESPACE and is part of Qt's \l{Model/View Programming}{model/view framework}. To render an item in a custom way, you must implement paint() and - sizeHint(). The QItemDelegate class provides default implementations for + sizeHint(). The QStyledItemDelegate class provides default implementations for these functions; if you do not need custom rendering, subclass that class instead. @@ -115,7 +115,7 @@ QT_BEGIN_NAMESPACE The second approach is to handle user events directly by reimplementing editorEvent(). - \sa {model-view-programming}{Model/View Programming}, QItemDelegate, + \sa {model-view-programming}{Model/View Programming}, QStyledItemDelegate, {Pixelator Example}, QStyledItemDelegate, QStyle */ diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 638cee8289..1151379e17 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -3211,7 +3211,7 @@ bool QAbstractItemView::isPersistentEditorOpen(const QModelIndex &index) const This function should only be used to display static content within the visible area corresponding to an item of data. If you want to display custom dynamic content or implement a custom editor widget, subclass - QItemDelegate instead. + QStyledItemDelegate instead. \sa {Delegate Classes} */ diff --git a/src/widgets/itemviews/qcolumnview_p.h b/src/widgets/itemviews/qcolumnview_p.h index 9f0d2a40dc..7b36b1f3da 100644 --- a/src/widgets/itemviews/qcolumnview_p.h +++ b/src/widgets/itemviews/qcolumnview_p.h @@ -181,6 +181,7 @@ public: /*! * This is a delegate that will paint the triangle */ +// ### Qt6: QStyledItemDelegate class QColumnViewDelegate : public QItemDelegate { diff --git a/src/widgets/itemviews/qdatawidgetmapper.cpp b/src/widgets/itemviews/qdatawidgetmapper.cpp index 1f0dbff7a9..125ee73194 100644 --- a/src/widgets/itemviews/qdatawidgetmapper.cpp +++ b/src/widgets/itemviews/qdatawidgetmapper.cpp @@ -324,6 +324,7 @@ void QDataWidgetMapperPrivate::_q_modelDestroyed() QDataWidgetMapper::QDataWidgetMapper(QObject *parent) : QObject(*new QDataWidgetMapperPrivate, parent) { + // ### Qt6: QStyledItemDelegate setItemDelegate(new QItemDelegate(this)); } diff --git a/src/widgets/itemviews/qitemeditorfactory.cpp b/src/widgets/itemviews/qitemeditorfactory.cpp index 0986da9707..43dd004530 100644 --- a/src/widgets/itemviews/qitemeditorfactory.cpp +++ b/src/widgets/itemviews/qitemeditorfactory.cpp @@ -122,7 +122,7 @@ Q_SIGNALS: \inmodule QtWidgets When editing data in an item view, editors are created and - displayed by a delegate. QItemDelegate, which is the delegate by + displayed by a delegate. QStyledItemDelegate, which is the delegate by default installed on Qt's item views, uses a QItemEditorFactory to create editors for it. A default unique instance provided by QItemEditorFactory is used by all item delegates. If you set a @@ -156,7 +156,7 @@ Q_SIGNALS: Additional editors can be registered with the registerEditor() function. - \sa QItemDelegate, {Model/View Programming}, {Color Editor Factory Example} + \sa QStyledItemDelegate, {Model/View Programming}, {Color Editor Factory Example} */ /*! @@ -375,7 +375,7 @@ void QItemEditorFactory::setDefaultFactory(QItemEditorFactory *factory) QItemEditorCreatorBase objects are specialized widget factories that provide editor widgets for one particular QVariant data type. They are used by QItemEditorFactory to create editors for - \l{QItemDelegate}s. Creator bases must be registered with + \l{QStyledItemDelegate}s. Creator bases must be registered with QItemEditorFactory::registerEditor(). An editor should provide a user property for the data it edits. @@ -457,7 +457,7 @@ QItemEditorCreatorBase::~QItemEditorCreatorBase() \snippet code/src_gui_itemviews_qitemeditorfactory.cpp 1 The constructor takes the name of the property that contains the - editing data. QItemDelegate can then access the property by name + editing data. QStyledItemDelegate can then access the property by name when it sets and retrieves editing data. Only use this class if your editor does not define a user property (using the USER keyword in the Q_PROPERTY macro). If the widget has a user @@ -472,7 +472,7 @@ QItemEditorCreatorBase::~QItemEditorCreatorBase() Constructs an editor creator object using \a valuePropertyName as the name of the property to be used for editing. The - property name is used by QItemDelegate when setting and + property name is used by QStyledItemDelegate when setting and getting editor data. Note that the \a valuePropertyName is only used if the editor @@ -508,11 +508,11 @@ QItemEditorCreatorBase::~QItemEditorCreatorBase() \snippet code/src_gui_itemviews_qitemeditorfactory.cpp 2 Setting the \c editorFactory created above in an item delegate via - QItemDelegate::setItemEditorFactory() makes sure that all values of type + QStyledItemDelegate::setItemEditorFactory() makes sure that all values of type QVariant::DateTime will be edited in \c{MyFancyDateTimeEdit}. The editor must provide a user property that will contain the - editing data. The property is used by \l{QItemDelegate}s to set + editing data. The property is used by \l{QStyledItemDelegate}s to set and retrieve the data (using Qt's \l{Meta-Object System}{meta-object system}). You set the user property with the USER keyword: @@ -520,7 +520,7 @@ QItemEditorCreatorBase::~QItemEditorCreatorBase() \snippet code/src_gui_itemviews_qitemeditorfactory.cpp 3 \sa QItemEditorCreatorBase, QItemEditorCreator, - QItemEditorFactory, QItemDelegate, {Color Editor Factory Example} + QItemEditorFactory, QStyledItemDelegate, {Color Editor Factory Example} */ /*! diff --git a/src/widgets/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp index ea92c5605b..3b3a72cd4f 100644 --- a/src/widgets/itemviews/qlistwidget.cpp +++ b/src/widgets/itemviews/qlistwidget.cpp @@ -1757,7 +1757,7 @@ QWidget *QListWidget::itemWidget(QListWidgetItem *item) const This function should only be used to display static content in the place of a list widget item. If you want to display custom dynamic content or - implement a custom editor widget, use QListView and subclass QItemDelegate + implement a custom editor widget, use QListView and subclass QStyledItemDelegate instead. \sa itemWidget(), removeItemWidget(), {Delegate Classes} diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp index fce6b75079..a7d144672c 100644 --- a/src/widgets/itemviews/qtableview.cpp +++ b/src/widgets/itemviews/qtableview.cpp @@ -1108,7 +1108,7 @@ int QTableViewPrivate::heightHintForIndex(const QModelIndex &index, int hint, QS \l showGrid property. The items shown in a table view, like those in the other item views, are - rendered and edited using standard \l{QItemDelegate}{delegates}. However, + rendered and edited using standard \l{QStyledItemDelegate}{delegates}. However, for some tasks it is sometimes useful to be able to insert widgets in a table instead. Widgets are set for particular indexes with the \l{QAbstractItemView::}{setIndexWidget()} function, and diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp index ac117b1c07..1923f5edc1 100644 --- a/src/widgets/itemviews/qtreewidget.cpp +++ b/src/widgets/itemviews/qtreewidget.cpp @@ -3101,7 +3101,7 @@ QWidget *QTreeWidget::itemWidget(QTreeWidgetItem *item, int column) const This function should only be used to display static content in the place of a tree widget item. If you want to display custom dynamic content or - implement a custom editor widget, use QTreeView and subclass QItemDelegate + implement a custom editor widget, use QTreeView and subclass QStyledItemDelegate instead. This function cannot be called before the item hierarchy has been set up, diff --git a/src/widgets/util/qcompleter_p.h b/src/widgets/util/qcompleter_p.h index 765363744b..21dddf446e 100644 --- a/src/widgets/util/qcompleter_p.h +++ b/src/widgets/util/qcompleter_p.h @@ -194,6 +194,7 @@ private: const QIndexMapper& iv, QMatchData* m); }; +// ### Qt6: QStyledItemDelegate class QCompleterItemDelegate : public QItemDelegate { public: diff --git a/src/widgets/widgets/qcalendarwidget.cpp b/src/widgets/widgets/qcalendarwidget.cpp index 0553972591..5649243d1d 100644 --- a/src/widgets/widgets/qcalendarwidget.cpp +++ b/src/widgets/widgets/qcalendarwidget.cpp @@ -1555,6 +1555,7 @@ void QCalendarView::mouseReleaseEvent(QMouseEvent *event) } } +// ### Qt6: QStyledItemDelegate class QCalendarDelegate : public QItemDelegate { Q_OBJECT diff --git a/src/widgets/widgets/qcombobox_p.h b/src/widgets/widgets/qcombobox_p.h index f76a95d2ae..71404964da 100644 --- a/src/widgets/widgets/qcombobox_p.h +++ b/src/widgets/widgets/qcombobox_p.h @@ -293,6 +293,7 @@ private: QComboBox *mCombo; }; +// ### Qt6: QStyledItemDelegate ? // Note that this class is intentionally not using QStyledItemDelegate // Vista does not use the new theme for combo boxes and there might // be other side effects from using the new class From cf27d9e8a5e14ebe083f4b0fa2204d0646e7ed5e Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 7 Dec 2018 14:17:02 +0100 Subject: [PATCH 0791/1650] Cleanup Widgets examples - new signal/slot syntax MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cleanup the Widget examples - use the new signal/slot syntax where possible - painting and richtext subdirectory Change-Id: If0e365ab1cabf9184076595494cfca151406fddf Reviewed-by: Luca Beldi Reviewed-by: Topi Reiniö --- .../widgets/painting/basicdrawing/window.cpp | 32 +++++----- .../painting/composition/composition.cpp | 62 +++++++++---------- .../painting/concentriccircles/window.cpp | 4 +- .../widgets/painting/deform/pathdeform.cpp | 43 +++++++------ .../painting/fontsampler/mainwindow.cpp | 15 ++--- .../widgets/painting/gradients/gradients.cpp | 2 +- .../imagecomposition/imagecomposer.cpp | 9 ++- .../widgets/painting/painterpaths/window.cpp | 40 +++++++----- .../painting/pathstroke/pathstroke.cpp | 56 ++++++++--------- .../widgets/painting/shared/hoverpoints.cpp | 4 +- .../painting/transformations/window.cpp | 7 ++- .../widgets/richtext/calendar/mainwindow.cpp | 10 +-- .../widgets/richtext/orderform/mainwindow.cpp | 2 +- .../richtext/syntaxhighlighter/mainwindow.cpp | 13 ++-- 14 files changed, 160 insertions(+), 139 deletions(-) diff --git a/examples/widgets/painting/basicdrawing/window.cpp b/examples/widgets/painting/basicdrawing/window.cpp index c80237e914..65f6971d13 100644 --- a/examples/widgets/painting/basicdrawing/window.cpp +++ b/examples/widgets/painting/basicdrawing/window.cpp @@ -157,22 +157,22 @@ Window::Window() //! [7] //! [8] - connect(shapeComboBox, SIGNAL(activated(int)), - this, SLOT(shapeChanged())); - connect(penWidthSpinBox, SIGNAL(valueChanged(int)), - this, SLOT(penChanged())); - connect(penStyleComboBox, SIGNAL(activated(int)), - this, SLOT(penChanged())); - connect(penCapComboBox, SIGNAL(activated(int)), - this, SLOT(penChanged())); - connect(penJoinComboBox, SIGNAL(activated(int)), - this, SLOT(penChanged())); - connect(brushStyleComboBox, SIGNAL(activated(int)), - this, SLOT(brushChanged())); - connect(antialiasingCheckBox, SIGNAL(toggled(bool)), - renderArea, SLOT(setAntialiased(bool))); - connect(transformationsCheckBox, SIGNAL(toggled(bool)), - renderArea, SLOT(setTransformed(bool))); + connect(shapeComboBox, QOverload::of(&QComboBox::activated), + this, &Window::shapeChanged); + connect(penWidthSpinBox, QOverload::of(&QSpinBox::valueChanged), + this, &Window::penChanged); + connect(penStyleComboBox, QOverload::of(&QComboBox::activated), + this, &Window::penChanged); + connect(penCapComboBox, QOverload::of(&QComboBox::activated), + this, &Window::penChanged); + connect(penJoinComboBox, QOverload::of(&QComboBox::activated), + this, &Window::penChanged); + connect(brushStyleComboBox, QOverload::of(&QComboBox::activated), + this, &Window::brushChanged); + connect(antialiasingCheckBox, &QAbstractButton::toggled, + renderArea, &RenderArea::setAntialiased); + connect(transformationsCheckBox, &QAbstractButton::toggled, + renderArea, &RenderArea::setTransformed); //! [8] //! [9] diff --git a/examples/widgets/painting/composition/composition.cpp b/examples/widgets/painting/composition/composition.cpp index e0abc5875c..96088cca4a 100644 --- a/examples/widgets/painting/composition/composition.cpp +++ b/examples/widgets/painting/composition/composition.cpp @@ -76,68 +76,68 @@ CompositionWidget::CompositionWidget(QWidget *parent) modesGroup->setTitle(tr("Mode")); rbClear = new QRadioButton(tr("Clear"), modesGroup); - connect(rbClear, SIGNAL(clicked()), view, SLOT(setClearMode())); + connect(rbClear, &QAbstractButton::clicked, view, &CompositionRenderer::setClearMode); rbSource = new QRadioButton(tr("Source"), modesGroup); - connect(rbSource, SIGNAL(clicked()), view, SLOT(setSourceMode())); + connect(rbSource, &QAbstractButton::clicked, view, &CompositionRenderer::setSourceMode); rbDest = new QRadioButton(tr("Destination"), modesGroup); - connect(rbDest, SIGNAL(clicked()), view, SLOT(setDestMode())); + connect(rbDest, &QAbstractButton::clicked, view, &CompositionRenderer::setDestMode); rbSourceOver = new QRadioButton(tr("Source Over"), modesGroup); - connect(rbSourceOver, SIGNAL(clicked()), view, SLOT(setSourceOverMode())); + connect(rbSourceOver, &QAbstractButton::clicked, view, &CompositionRenderer::setSourceOverMode); rbDestOver = new QRadioButton(tr("Destination Over"), modesGroup); - connect(rbDestOver, SIGNAL(clicked()), view, SLOT(setDestOverMode())); + connect(rbDestOver, &QAbstractButton::clicked, view, &CompositionRenderer::setDestOverMode); rbSourceIn = new QRadioButton(tr("Source In"), modesGroup); - connect(rbSourceIn, SIGNAL(clicked()), view, SLOT(setSourceInMode())); + connect(rbSourceIn, &QAbstractButton::clicked, view, &CompositionRenderer::setSourceInMode); rbDestIn = new QRadioButton(tr("Dest In"), modesGroup); - connect(rbDestIn, SIGNAL(clicked()), view, SLOT(setDestInMode())); + connect(rbDestIn, &QAbstractButton::clicked, view, &CompositionRenderer::setDestInMode); rbSourceOut = new QRadioButton(tr("Source Out"), modesGroup); - connect(rbSourceOut, SIGNAL(clicked()), view, SLOT(setSourceOutMode())); + connect(rbSourceOut, &QAbstractButton::clicked, view, &CompositionRenderer::setSourceOutMode); rbDestOut = new QRadioButton(tr("Dest Out"), modesGroup); - connect(rbDestOut, SIGNAL(clicked()), view, SLOT(setDestOutMode())); + connect(rbDestOut, &QAbstractButton::clicked, view, &CompositionRenderer::setDestOutMode); rbSourceAtop = new QRadioButton(tr("Source Atop"), modesGroup); - connect(rbSourceAtop, SIGNAL(clicked()), view, SLOT(setSourceAtopMode())); + connect(rbSourceAtop, &QAbstractButton::clicked, view, &CompositionRenderer::setSourceAtopMode); rbDestAtop = new QRadioButton(tr("Dest Atop"), modesGroup); - connect(rbDestAtop, SIGNAL(clicked()), view, SLOT(setDestAtopMode())); + connect(rbDestAtop, &QAbstractButton::clicked, view, &CompositionRenderer::setDestAtopMode); rbXor = new QRadioButton(tr("Xor"), modesGroup); - connect(rbXor, SIGNAL(clicked()), view, SLOT(setXorMode())); + connect(rbXor, &QAbstractButton::clicked, view, &CompositionRenderer::setXorMode); rbPlus = new QRadioButton(tr("Plus"), modesGroup); - connect(rbPlus, SIGNAL(clicked()), view, SLOT(setPlusMode())); + connect(rbPlus, &QAbstractButton::clicked, view, &CompositionRenderer::setPlusMode); rbMultiply = new QRadioButton(tr("Multiply"), modesGroup); - connect(rbMultiply, SIGNAL(clicked()), view, SLOT(setMultiplyMode())); + connect(rbMultiply, &QAbstractButton::clicked, view, &CompositionRenderer::setMultiplyMode); rbScreen = new QRadioButton(tr("Screen"), modesGroup); - connect(rbScreen, SIGNAL(clicked()), view, SLOT(setScreenMode())); + connect(rbScreen, &QAbstractButton::clicked, view, &CompositionRenderer::setScreenMode); rbOverlay = new QRadioButton(tr("Overlay"), modesGroup); - connect(rbOverlay, SIGNAL(clicked()), view, SLOT(setOverlayMode())); + connect(rbOverlay, &QAbstractButton::clicked, view, &CompositionRenderer::setOverlayMode); rbDarken = new QRadioButton(tr("Darken"), modesGroup); - connect(rbDarken, SIGNAL(clicked()), view, SLOT(setDarkenMode())); + connect(rbDarken, &QAbstractButton::clicked, view, &CompositionRenderer::setDarkenMode); rbLighten = new QRadioButton(tr("Lighten"), modesGroup); - connect(rbLighten, SIGNAL(clicked()), view, SLOT(setLightenMode())); + connect(rbLighten, &QAbstractButton::clicked, view, &CompositionRenderer::setLightenMode); rbColorDodge = new QRadioButton(tr("Color Dodge"), modesGroup); - connect(rbColorDodge, SIGNAL(clicked()), view, SLOT(setColorDodgeMode())); + connect(rbColorDodge, &QAbstractButton::clicked, view, &CompositionRenderer::setColorDodgeMode); rbColorBurn = new QRadioButton(tr("Color Burn"), modesGroup); - connect(rbColorBurn, SIGNAL(clicked()), view, SLOT(setColorBurnMode())); + connect(rbColorBurn, &QAbstractButton::clicked, view, &CompositionRenderer::setColorBurnMode); rbHardLight = new QRadioButton(tr("Hard Light"), modesGroup); - connect(rbHardLight, SIGNAL(clicked()), view, SLOT(setHardLightMode())); + connect(rbHardLight, &QAbstractButton::clicked, view, &CompositionRenderer::setHardLightMode); rbSoftLight = new QRadioButton(tr("Soft Light"), modesGroup); - connect(rbSoftLight, SIGNAL(clicked()), view, SLOT(setSoftLightMode())); + connect(rbSoftLight, &QAbstractButton::clicked, view, &CompositionRenderer::setSoftLightMode); rbDifference = new QRadioButton(tr("Difference"), modesGroup); - connect(rbDifference, SIGNAL(clicked()), view, SLOT(setDifferenceMode())); + connect(rbDifference, &QAbstractButton::clicked, view, &CompositionRenderer::setDifferenceMode); rbExclusion = new QRadioButton(tr("Exclusion"), modesGroup); - connect(rbExclusion, SIGNAL(clicked()), view, SLOT(setExclusionMode())); + connect(rbExclusion, &QAbstractButton::clicked, view, &CompositionRenderer::setExclusionMode); QGroupBox *circleColorGroup = new QGroupBox(mainGroup); circleColorGroup->setTitle(tr("Circle color")); QSlider *circleColorSlider = new QSlider(Qt::Horizontal, circleColorGroup); circleColorSlider->setRange(0, 359); circleColorSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); - connect(circleColorSlider, SIGNAL(valueChanged(int)), view, SLOT(setCircleColor(int))); + connect(circleColorSlider, &QAbstractSlider::valueChanged, view, &CompositionRenderer::setCircleColor); QGroupBox *circleAlphaGroup = new QGroupBox(mainGroup); circleAlphaGroup->setTitle(tr("Circle alpha")); QSlider *circleAlphaSlider = new QSlider(Qt::Horizontal, circleAlphaGroup); circleAlphaSlider->setRange(0, 255); circleAlphaSlider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); - connect(circleAlphaSlider, SIGNAL(valueChanged(int)), view, SLOT(setCircleAlpha(int))); + connect(circleAlphaSlider, &QAbstractSlider::valueChanged, view, &CompositionRenderer::setCircleAlpha); QPushButton *showSourceButton = new QPushButton(mainGroup); showSourceButton->setText(tr("Show Source")); @@ -209,13 +209,13 @@ CompositionWidget::CompositionWidget(QWidget *parent) view->loadDescription(":res/composition/composition.html"); view->loadSourceFile(":res/composition/composition.cpp"); - connect(whatsThisButton, SIGNAL(clicked(bool)), view, SLOT(setDescriptionEnabled(bool))); - connect(view, SIGNAL(descriptionEnabledChanged(bool)), whatsThisButton, SLOT(setChecked(bool))); - connect(showSourceButton, SIGNAL(clicked()), view, SLOT(showSource())); + connect(whatsThisButton, &QAbstractButton::clicked, view, &ArthurFrame::setDescriptionEnabled); + connect(view, &ArthurFrame::descriptionEnabledChanged, whatsThisButton, &QAbstractButton::setChecked); + connect(showSourceButton, &QAbstractButton::clicked, view, &ArthurFrame::showSource); #if QT_CONFIG(opengl) - connect(enableOpenGLButton, SIGNAL(clicked(bool)), view, SLOT(enableOpenGL(bool))); + connect(enableOpenGLButton, &QAbstractButton::clicked, view, &ArthurFrame::enableOpenGL); #endif - connect(animateButton, SIGNAL(toggled(bool)), view, SLOT(setAnimationEnabled(bool))); + connect(animateButton, &QAbstractButton::toggled, view, &CompositionRenderer::setAnimationEnabled); circleColorSlider->setValue(270); circleAlphaSlider->setValue(200); diff --git a/examples/widgets/painting/concentriccircles/window.cpp b/examples/widgets/painting/concentriccircles/window.cpp index 0f65dc2285..45258e0bc4 100644 --- a/examples/widgets/painting/concentriccircles/window.cpp +++ b/examples/widgets/painting/concentriccircles/window.cpp @@ -77,8 +77,8 @@ Window::Window() circleWidgets[i][j]->setAntialiased(j != 0); circleWidgets[i][j]->setFloatBased(i != 0); - connect(timer, SIGNAL(timeout()), - circleWidgets[i][j], SLOT(nextAnimationFrame())); + connect(timer, &QTimer::timeout, + circleWidgets[i][j], &CircleWidget::nextAnimationFrame); layout->addWidget(circleWidgets[i][j], i + 1, j + 1); } diff --git a/examples/widgets/painting/deform/pathdeform.cpp b/examples/widgets/painting/deform/pathdeform.cpp index 7c3fe45277..3b80c40e9b 100644 --- a/examples/widgets/painting/deform/pathdeform.cpp +++ b/examples/widgets/painting/deform/pathdeform.cpp @@ -152,19 +152,19 @@ void PathDeformControls::layoutForDesktop() mainLayout->addWidget(mainGroup); mainLayout->setMargin(0); - connect(radiusSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setRadius(int))); - connect(deformSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setIntensity(int))); - connect(fontSizeSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setFontSize(int))); - connect(animateButton, SIGNAL(clicked(bool)), m_renderer, SLOT(setAnimated(bool))); + connect(radiusSlider, &QAbstractSlider::valueChanged, m_renderer, &PathDeformRenderer::setRadius); + connect(deformSlider, &QAbstractSlider::valueChanged, m_renderer, &PathDeformRenderer::setIntensity); + connect(fontSizeSlider, &QAbstractSlider::valueChanged, m_renderer, &PathDeformRenderer::setFontSize); + connect(animateButton, &QAbstractButton::clicked, m_renderer, &PathDeformRenderer::setAnimated); #if QT_CONFIG(opengl) - connect(enableOpenGLButton, SIGNAL(clicked(bool)), m_renderer, SLOT(enableOpenGL(bool))); + connect(enableOpenGLButton, &QAbstractButton::clicked, m_renderer, &ArthurFrame::enableOpenGL); #endif - connect(textInput, SIGNAL(textChanged(QString)), m_renderer, SLOT(setText(QString))); - connect(m_renderer, SIGNAL(descriptionEnabledChanged(bool)), - whatsThisButton, SLOT(setChecked(bool))); - connect(whatsThisButton, SIGNAL(clicked(bool)), m_renderer, SLOT(setDescriptionEnabled(bool))); - connect(showSourceButton, SIGNAL(clicked()), m_renderer, SLOT(showSource())); + connect(textInput, &QLineEdit::textChanged, m_renderer, &PathDeformRenderer::setText); + connect(m_renderer, &ArthurFrame::descriptionEnabledChanged, + whatsThisButton, &QAbstractButton::setChecked); + connect(whatsThisButton, &QAbstractButton::clicked, m_renderer, &ArthurFrame::setDescriptionEnabled); + connect(showSourceButton, &QAbstractButton::clicked, m_renderer, &ArthurFrame::showSource); animateButton->animateClick(); deformSlider->setValue(80); @@ -229,14 +229,14 @@ void PathDeformControls::layoutForSmallScreen() mainLayout->addWidget(okButton); mainLayout->addWidget(quitButton); - connect(quitButton, SIGNAL(clicked()), this, SIGNAL(quitPressed())); - connect(okButton, SIGNAL(clicked()), this, SIGNAL(okPressed())); - connect(radiusSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setRadius(int))); - connect(deformSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setIntensity(int))); - connect(fontSizeSlider, SIGNAL(valueChanged(int)), m_renderer, SLOT(setFontSize(int))); - connect(animateButton, SIGNAL(clicked(bool)), m_renderer, SLOT(setAnimated(bool))); + connect(quitButton, &QAbstractButton::clicked, this, &PathDeformControls::quitPressed); + connect(okButton, &QAbstractButton::clicked, this, &PathDeformControls::okPressed); + connect(radiusSlider, &QAbstractSlider::valueChanged, m_renderer, &PathDeformRenderer::setRadius); + connect(deformSlider, &QAbstractSlider::valueChanged, m_renderer, &PathDeformRenderer::setIntensity); + connect(fontSizeSlider, &QAbstractSlider::valueChanged, m_renderer, &PathDeformRenderer::setFontSize); + connect(animateButton, &QAbstractButton::clicked, m_renderer, &PathDeformRenderer::setAnimated); #if QT_CONFIG(opengl) - connect(enableOpenGLButton, SIGNAL(clicked(bool)), m_renderer, SLOT(enableOpenGL(bool))); + connect(enableOpenGLButton, &QAbstractButton::clicked, m_renderer, &ArthurFrame::enableOpenGL); #endif @@ -272,9 +272,12 @@ PathDeformWidget::PathDeformWidget(QWidget *parent, bool smallScreen) m_renderer->loadDescription(":res/deform/pathdeform.html"); m_renderer->setDescriptionEnabled(false); - connect(m_renderer, SIGNAL(clicked()), this, SLOT(showControls())); - connect(m_controls, SIGNAL(okPressed()), this, SLOT(hideControls())); - connect(m_controls, SIGNAL(quitPressed()), QCoreApplication::instance(), SLOT(quit())); + connect(m_renderer, &PathDeformRenderer::clicked, + this, &PathDeformWidget::showControls); + connect(m_controls, &PathDeformControls::okPressed, + this, &PathDeformWidget::hideControls); + connect(m_controls, &PathDeformControls::quitPressed, + qApp, &QCoreApplication::quit); } diff --git a/examples/widgets/painting/fontsampler/mainwindow.cpp b/examples/widgets/painting/fontsampler/mainwindow.cpp index bd15438df9..6344806f29 100644 --- a/examples/widgets/painting/fontsampler/mainwindow.cpp +++ b/examples/widgets/painting/fontsampler/mainwindow.cpp @@ -71,11 +71,12 @@ MainWindow::MainWindow(QWidget *parent) markedCount = 0; setupFontTree(); - connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); - connect(fontTree, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), - this, SLOT(showFont(QTreeWidgetItem*))); - connect(fontTree, SIGNAL(itemChanged(QTreeWidgetItem*,int)), - this, SLOT(updateStyles(QTreeWidgetItem*,int))); + connect(quitAction, &QAction::triggered, + qApp, &QApplication::quit); + connect(fontTree, &QTreeWidget::currentItemChanged, + this, &MainWindow::showFont); + connect(fontTree, &QTreeWidget::itemChanged, + this, &MainWindow::updateStyles); fontTree->setItemSelected(fontTree->topLevelItem(0), true); showFont(fontTree->topLevelItem(0)); @@ -285,8 +286,8 @@ void MainWindow::on_printPreviewAction_triggered() QPrinter printer(QPrinter::HighResolution); QPrintPreviewDialog preview(&printer, this); - connect(&preview, SIGNAL(paintRequested(QPrinter*)), - this, SLOT(printDocument(QPrinter*))); + connect(&preview, &QPrintPreviewDialog::paintRequested, + this, &MainWindow::printDocument); preview.exec(); #endif } diff --git a/examples/widgets/painting/gradients/gradients.cpp b/examples/widgets/painting/gradients/gradients.cpp index 004f6710cd..fd6eaeb0d9 100644 --- a/examples/widgets/painting/gradients/gradients.cpp +++ b/examples/widgets/painting/gradients/gradients.cpp @@ -421,7 +421,7 @@ GradientWidget::GradientWidget(QWidget *parent) m_renderer->loadSourceFile(":res/gradients/gradients.cpp"); m_renderer->loadDescription(":res/gradients/gradients.html"); - QTimer::singleShot(50, this, SLOT(setDefault1())); + QTimer::singleShot(50, this, &GradientWidget::setDefault1); } void GradientWidget::setDefault(int config) diff --git a/examples/widgets/painting/imagecomposition/imagecomposer.cpp b/examples/widgets/painting/imagecomposition/imagecomposer.cpp index d53017b955..ffdc8f433c 100644 --- a/examples/widgets/painting/imagecomposition/imagecomposer.cpp +++ b/examples/widgets/painting/imagecomposition/imagecomposer.cpp @@ -100,9 +100,12 @@ ImageComposer::ImageComposer() //! [2] //! [3] - connect(sourceButton, SIGNAL(clicked()), this, SLOT(chooseSource())); - connect(operatorComboBox, SIGNAL(activated(int)), this, SLOT(recalculateResult())); - connect(destinationButton, SIGNAL(clicked()), this, SLOT(chooseDestination())); + connect(sourceButton, &QAbstractButton::clicked, + this, &ImageComposer::chooseSource); + connect(operatorComboBox, QOverload::of(&QComboBox::activated), + this, &ImageComposer::recalculateResult); + connect(destinationButton, &QAbstractButton::clicked, + this, &ImageComposer::chooseDestination); //! [3] //! [4] diff --git a/examples/widgets/painting/painterpaths/window.cpp b/examples/widgets/painting/painterpaths/window.cpp index a987937b39..95e312623e 100644 --- a/examples/widgets/painting/painterpaths/window.cpp +++ b/examples/widgets/painting/painterpaths/window.cpp @@ -194,22 +194,30 @@ Window::Window() //! [12] //! [16] - connect(fillRuleComboBox, SIGNAL(activated(int)), this, SLOT(fillRuleChanged())); - connect(fillColor1ComboBox, SIGNAL(activated(int)), this, SLOT(fillGradientChanged())); - connect(fillColor2ComboBox, SIGNAL(activated(int)), this, SLOT(fillGradientChanged())); - connect(penColorComboBox, SIGNAL(activated(int)), this, SLOT(penColorChanged())); + connect(fillRuleComboBox, QOverload::of(&QComboBox::activated), + this, &Window::fillRuleChanged); + connect(fillColor1ComboBox, QOverload::of(&QComboBox::activated), + this, &Window::fillGradientChanged); + connect(fillColor2ComboBox, QOverload::of(&QComboBox::activated), + this, &Window::fillGradientChanged); + connect(penColorComboBox, QOverload::of(&QComboBox::activated), + this, &Window::penColorChanged); - for(QList::iterator it = renderAreas.begin(); it != renderAreas.end(); it++) { - connect(penWidthSpinBox, SIGNAL(valueChanged(int)), *it, SLOT(setPenWidth(int))); - connect(rotationAngleSpinBox, SIGNAL(valueChanged(int)), *it, SLOT(setRotationAngle(int))); + for (RenderArea *area : qAsConst(renderAreas)) { + connect(penWidthSpinBox, QOverload::of(&QSpinBox::valueChanged), + area, &RenderArea::setPenWidth); + connect(rotationAngleSpinBox, QOverload::of(&QSpinBox::valueChanged), + area, &RenderArea::setRotationAngle); } //! [16] //! [17] QGridLayout *topLayout = new QGridLayout; - int i=0; - for(QList::iterator it = renderAreas.begin(); it != renderAreas.end(); it++, i++) - topLayout->addWidget(*it, i / 3, i % 3); + int i = 0; + for (RenderArea *area : qAsConst(renderAreas)) { + topLayout->addWidget(area, i / 3, i % 3); + ++i; + } QGridLayout *mainLayout = new QGridLayout; mainLayout->addLayout(topLayout, 0, 0, 1, 4); @@ -243,8 +251,8 @@ void Window::fillRuleChanged() { Qt::FillRule rule = (Qt::FillRule)currentItemData(fillRuleComboBox).toInt(); - for (QList::iterator it = renderAreas.begin(); it != renderAreas.end(); ++it) - (*it)->setFillRule(rule); + for (RenderArea *area : qAsConst(renderAreas)) + area->setFillRule(rule); } //! [19] @@ -254,8 +262,8 @@ void Window::fillGradientChanged() QColor color1 = qvariant_cast(currentItemData(fillColor1ComboBox)); QColor color2 = qvariant_cast(currentItemData(fillColor2ComboBox)); - for (QList::iterator it = renderAreas.begin(); it != renderAreas.end(); ++it) - (*it)->setFillGradient(color1, color2); + for (RenderArea *area : qAsConst(renderAreas)) + area->setFillGradient(color1, color2); } //! [20] @@ -264,8 +272,8 @@ void Window::penColorChanged() { QColor color = qvariant_cast(currentItemData(penColorComboBox)); - for (QList::iterator it = renderAreas.begin(); it != renderAreas.end(); ++it) - (*it)->setPenColor(color); + for (RenderArea *area : qAsConst(renderAreas)) + area->setPenColor(color); } //! [21] diff --git a/examples/widgets/painting/pathstroke/pathstroke.cpp b/examples/widgets/painting/pathstroke/pathstroke.cpp index b04998afac..acb946496f 100644 --- a/examples/widgets/painting/pathstroke/pathstroke.cpp +++ b/examples/widgets/painting/pathstroke/pathstroke.cpp @@ -164,24 +164,24 @@ void PathStrokeControls::createCommonControls(QWidget* parent) // Connections - connect(flatCap, SIGNAL(clicked()), m_renderer, SLOT(setFlatCap())); - connect(squareCap, SIGNAL(clicked()), m_renderer, SLOT(setSquareCap())); - connect(roundCap, SIGNAL(clicked()), m_renderer, SLOT(setRoundCap())); + connect(flatCap, &QAbstractButton::clicked, m_renderer, &PathStrokeRenderer::setFlatCap); + connect(squareCap, &QAbstractButton::clicked, m_renderer, &PathStrokeRenderer::setSquareCap); + connect(roundCap, &QAbstractButton::clicked, m_renderer, &PathStrokeRenderer::setRoundCap); - connect(bevelJoin, SIGNAL(clicked()), m_renderer, SLOT(setBevelJoin())); - connect(miterJoin, SIGNAL(clicked()), m_renderer, SLOT(setMiterJoin())); - connect(svgMiterJoin, SIGNAL(clicked()), m_renderer, SLOT(setSvgMiterJoin())); - connect(roundJoin, SIGNAL(clicked()), m_renderer, SLOT(setRoundJoin())); + connect(bevelJoin, &QAbstractButton::clicked, m_renderer, &PathStrokeRenderer::setBevelJoin); + connect(miterJoin, &QAbstractButton::clicked, m_renderer, &PathStrokeRenderer::setMiterJoin); + connect(svgMiterJoin, &QAbstractButton::clicked, m_renderer, &PathStrokeRenderer::setSvgMiterJoin); + connect(roundJoin, &QAbstractButton::clicked, m_renderer, &PathStrokeRenderer::setRoundJoin); - connect(curveMode, SIGNAL(clicked()), m_renderer, SLOT(setCurveMode())); - connect(lineMode, SIGNAL(clicked()), m_renderer, SLOT(setLineMode())); + connect(curveMode, &QAbstractButton::clicked, m_renderer, &PathStrokeRenderer::setCurveMode); + connect(lineMode, &QAbstractButton::clicked, m_renderer, &PathStrokeRenderer::setLineMode); - connect(solidLine, SIGNAL(clicked()), m_renderer, SLOT(setSolidLine())); - connect(dashLine, SIGNAL(clicked()), m_renderer, SLOT(setDashLine())); - connect(dotLine, SIGNAL(clicked()), m_renderer, SLOT(setDotLine())); - connect(dashDotLine, SIGNAL(clicked()), m_renderer, SLOT(setDashDotLine())); - connect(dashDotDotLine, SIGNAL(clicked()), m_renderer, SLOT(setDashDotDotLine())); - connect(customDashLine, SIGNAL(clicked()), m_renderer, SLOT(setCustomDashLine())); + connect(solidLine, &QAbstractButton::clicked, m_renderer, &PathStrokeRenderer::setSolidLine); + connect(dashLine, &QAbstractButton::clicked, m_renderer, &PathStrokeRenderer::setDashLine); + connect(dotLine, &QAbstractButton::clicked, m_renderer, &PathStrokeRenderer::setDotLine); + connect(dashDotLine, &QAbstractButton::clicked, m_renderer, &PathStrokeRenderer::setDashDotLine); + connect(dashDotDotLine, &QAbstractButton::clicked, m_renderer, &PathStrokeRenderer::setDashDotDotLine); + connect(customDashLine, &QAbstractButton::clicked, m_renderer, &PathStrokeRenderer::setCustomDashLine); // Set the defaults: flatCap->setChecked(true); @@ -247,17 +247,17 @@ void PathStrokeControls::layoutForDesktop() // Set up connections - connect(animated, SIGNAL(toggled(bool)), m_renderer, SLOT(setAnimation(bool))); + connect(animated, &QAbstractButton::toggled, m_renderer, &PathStrokeRenderer::setAnimation); - connect(penWidth, SIGNAL(valueChanged(int)), m_renderer, SLOT(setPenWidth(int))); + connect(penWidth, &QAbstractSlider::valueChanged, m_renderer, &PathStrokeRenderer::setPenWidth); - connect(showSourceButton, SIGNAL(clicked()), m_renderer, SLOT(showSource())); + connect(showSourceButton, &QAbstractButton::clicked, m_renderer, &ArthurFrame::showSource); #if QT_CONFIG(opengl) - connect(enableOpenGLButton, SIGNAL(clicked(bool)), m_renderer, SLOT(enableOpenGL(bool))); + connect(enableOpenGLButton, &QAbstractButton::clicked, m_renderer, &ArthurFrame::enableOpenGL); #endif - connect(whatsThisButton, SIGNAL(clicked(bool)), m_renderer, SLOT(setDescriptionEnabled(bool))); - connect(m_renderer, SIGNAL(descriptionEnabledChanged(bool)), - whatsThisButton, SLOT(setChecked(bool))); + connect(whatsThisButton, &QAbstractButton::clicked, m_renderer, &ArthurFrame::setDescriptionEnabled); + connect(m_renderer, &ArthurFrame::descriptionEnabledChanged, + whatsThisButton, &QAbstractButton::setChecked); // Set the defaults @@ -327,12 +327,12 @@ void PathStrokeControls::layoutForSmallScreens() mainLayout->addWidget(okBtn, 2, 2, Qt::AlignHCenter | Qt::AlignTop); #if QT_CONFIG(opengl) - connect(enableOpenGLButton, SIGNAL(clicked(bool)), m_renderer, SLOT(enableOpenGL(bool))); + connect(enableOpenGLButton, &QAbstractButton::clicked, m_renderer, &ArthurFrame::enableOpenGL); #endif - connect(penWidth, SIGNAL(valueChanged(int)), m_renderer, SLOT(setPenWidth(int))); - connect(quitBtn, SIGNAL(clicked()), this, SLOT(emitQuitSignal())); - connect(okBtn, SIGNAL(clicked()), this, SLOT(emitOkSignal())); + connect(penWidth, &QAbstractSlider::valueChanged, m_renderer, &PathStrokeRenderer::setPenWidth); + connect(quitBtn, &QAbstractButton::clicked, this, &PathStrokeControls::emitQuitSignal); + connect(okBtn, &QAbstractButton::clicked, this, &PathStrokeControls::emitOkSignal); m_renderer->setAnimation(true); penWidth->setValue(50); @@ -368,8 +368,8 @@ PathStrokeWidget::PathStrokeWidget(bool smallScreen) m_renderer->loadSourceFile(":res/pathstroke/pathstroke.cpp"); m_renderer->loadDescription(":res/pathstroke/pathstroke.html"); - connect(m_renderer, SIGNAL(clicked()), this, SLOT(showControls())); - connect(m_controls, SIGNAL(okPressed()), this, SLOT(hideControls())); + connect(m_renderer, &PathStrokeRenderer::clicked, this, &PathStrokeWidget::showControls); + connect(m_controls, &PathStrokeControls::okPressed, this, &PathStrokeWidget::hideControls); connect(m_controls, SIGNAL(quitPressed()), QApplication::instance(), SLOT(quit())); } diff --git a/examples/widgets/painting/shared/hoverpoints.cpp b/examples/widgets/painting/shared/hoverpoints.cpp index 7cd8cc0b29..a16bda4835 100644 --- a/examples/widgets/painting/shared/hoverpoints.cpp +++ b/examples/widgets/painting/shared/hoverpoints.cpp @@ -73,8 +73,8 @@ HoverPoints::HoverPoints(QWidget *widget, PointShape shape) m_editable = true; m_enabled = true; - connect(this, SIGNAL(pointsChanged(QPolygonF)), - m_widget, SLOT(update())); + connect(this, &HoverPoints::pointsChanged, + m_widget, QOverload<>::of(&QWidget::update)); } diff --git a/examples/widgets/painting/transformations/window.cpp b/examples/widgets/painting/transformations/window.cpp index d8babb2e00..8261c4e12e 100644 --- a/examples/widgets/painting/transformations/window.cpp +++ b/examples/widgets/painting/transformations/window.cpp @@ -79,8 +79,8 @@ Window::Window() operationComboBoxes[i]->addItem(tr("Scale to 75%")); operationComboBoxes[i]->addItem(tr("Translate by (50, 50)")); - connect(operationComboBoxes[i], SIGNAL(activated(int)), - this, SLOT(operationChanged())); + connect(operationComboBoxes[i], QOverload::of(&QComboBox::activated), + this, &Window::operationChanged); layout->addWidget(transformedRenderAreas[i], 0, i + 1); layout->addWidget(operationComboBoxes[i], 1, i + 1); @@ -159,7 +159,8 @@ void Window::setupShapes() shapes.append(text); shapes.append(truck); - connect(shapeComboBox, SIGNAL(activated(int)), this, SLOT(shapeSelected(int))); + connect(shapeComboBox, QOverload::of(&QComboBox::activated), + this, &Window::shapeSelected); } //! [7] diff --git a/examples/widgets/richtext/calendar/mainwindow.cpp b/examples/widgets/richtext/calendar/mainwindow.cpp index 38dc0e2849..3ddb1cf7ad 100644 --- a/examples/widgets/richtext/calendar/mainwindow.cpp +++ b/examples/widgets/richtext/calendar/mainwindow.cpp @@ -86,10 +86,12 @@ MainWindow::MainWindow() //! [2] //! [3] - connect(monthCombo, SIGNAL(activated(int)), this, SLOT(setMonth(int))); - connect(yearEdit, SIGNAL(dateChanged(QDate)), this, SLOT(setYear(QDate))); - connect(fontSizeSpinBox, SIGNAL(valueChanged(int)), - this, SLOT(setFontSize(int))); + connect(monthCombo, QOverload::of(&QComboBox::activated), + this, &MainWindow::setMonth); + connect(yearEdit, &QDateTimeEdit::dateChanged, + this, &MainWindow::setYear); + connect(fontSizeSpinBox, QOverload::of(&QSpinBox::valueChanged), + this, &MainWindow::setFontSize); //! [3] fontSizeSpinBox->setValue(10); diff --git a/examples/widgets/richtext/orderform/mainwindow.cpp b/examples/widgets/richtext/orderform/mainwindow.cpp index b207ee4dbc..291c37edf6 100644 --- a/examples/widgets/richtext/orderform/mainwindow.cpp +++ b/examples/widgets/richtext/orderform/mainwindow.cpp @@ -66,7 +66,7 @@ MainWindow::MainWindow() QMenu *fileMenu = new QMenu(tr("&File"), this); QAction *newAction = fileMenu->addAction(tr("&New...")); newAction->setShortcuts(QKeySequence::New); - printAction = fileMenu->addAction(tr("&Print..."), this, SLOT(printFile())); + printAction = fileMenu->addAction(tr("&Print..."), this, &MainWindow::printFile); printAction->setShortcuts(QKeySequence::Print); printAction->setEnabled(false); QAction *quitAction = fileMenu->addAction(tr("E&xit")); diff --git a/examples/widgets/richtext/syntaxhighlighter/mainwindow.cpp b/examples/widgets/richtext/syntaxhighlighter/mainwindow.cpp index dd58f1f45b..2dba0ba73e 100644 --- a/examples/widgets/richtext/syntaxhighlighter/mainwindow.cpp +++ b/examples/widgets/richtext/syntaxhighlighter/mainwindow.cpp @@ -117,9 +117,12 @@ void MainWindow::setupFileMenu() QMenu *fileMenu = new QMenu(tr("&File"), this); menuBar()->addMenu(fileMenu); - fileMenu->addAction(tr("&New"), this, SLOT(newFile()), QKeySequence::New); - fileMenu->addAction(tr("&Open..."), this, SLOT(openFile()), QKeySequence::Open); - fileMenu->addAction(tr("E&xit"), qApp, SLOT(quit()), QKeySequence::Quit); + fileMenu->addAction(tr("&New"), this, + &MainWindow::newFile, QKeySequence::New); + fileMenu->addAction(tr("&Open..."), + this, [this](){ openFile(); }, QKeySequence::Open); + fileMenu->addAction(tr("E&xit"), qApp, + &QApplication::quit, QKeySequence::Quit); } void MainWindow::setupHelpMenu() @@ -127,6 +130,6 @@ void MainWindow::setupHelpMenu() QMenu *helpMenu = new QMenu(tr("&Help"), this); menuBar()->addMenu(helpMenu); - helpMenu->addAction(tr("&About"), this, SLOT(about())); - helpMenu->addAction(tr("About &Qt"), qApp, SLOT(aboutQt())); + helpMenu->addAction(tr("&About"), this, &MainWindow::about); + helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt); } From 8cf812231405e011b422a1505d9a219618fe5cee Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 7 Dec 2018 14:15:36 +0100 Subject: [PATCH 0792/1650] Cleanup Widgets examples - new signal/slot syntax MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cleanup the Widget examples - use the new signal/slot syntax where possible - animation, effects and graphicsview subdirectory Change-Id: I6cbaea6e628eb06f8e0ca6a0b795030a66b83878 Reviewed-by: Luca Beldi Reviewed-by: Topi Reiniö --- examples/widgets/animation/easing/window.cpp | 15 +++-- .../widgets/animation/moveblocks/main.cpp | 4 +- examples/widgets/animation/states/main.cpp | 6 +- .../widgets/animation/stickman/lifecycle.cpp | 16 +++-- .../widgets/animation/stickman/stickman.cpp | 2 +- .../animation/sub-attaq/animationmanager.cpp | 4 +- examples/widgets/animation/sub-attaq/boat.cpp | 10 +-- examples/widgets/animation/sub-attaq/bomb.cpp | 10 +-- .../animation/sub-attaq/graphicsscene.cpp | 18 +++--- .../animation/sub-attaq/qanimationstate.cpp | 6 +- .../widgets/animation/sub-attaq/states.cpp | 12 ++-- .../widgets/animation/sub-attaq/submarine.cpp | 12 ++-- .../widgets/animation/sub-attaq/submarine_p.h | 3 +- .../widgets/animation/sub-attaq/torpedo.cpp | 10 +-- .../effects/fademessage/fademessage.cpp | 2 +- examples/widgets/graphicsview/boxes/scene.cpp | 42 ++++++------ examples/widgets/graphicsview/chip/view.cpp | 32 +++++----- .../graphicsview/collidingmice/main.cpp | 2 +- .../diagramscene/diagramscene.cpp | 8 +-- .../graphicsview/diagramscene/mainwindow.cpp | 64 +++++++++---------- .../embeddeddialogs/customproxy.cpp | 8 +-- 21 files changed, 148 insertions(+), 138 deletions(-) diff --git a/examples/widgets/animation/easing/window.cpp b/examples/widgets/animation/easing/window.cpp index 8c03e0534d..aa12147388 100644 --- a/examples/widgets/animation/easing/window.cpp +++ b/examples/widgets/animation/easing/window.cpp @@ -66,11 +66,16 @@ Window::Window(QWidget *parent) m_ui.amplitudeSpinBox->setValue(dummy.amplitude()); m_ui.overshootSpinBox->setValue(dummy.overshoot()); - connect(m_ui.easingCurvePicker, SIGNAL(currentRowChanged(int)), this, SLOT(curveChanged(int))); - connect(buttonGroup, SIGNAL(buttonClicked(int)), this, SLOT(pathChanged(int))); - connect(m_ui.periodSpinBox, SIGNAL(valueChanged(double)), this, SLOT(periodChanged(double))); - connect(m_ui.amplitudeSpinBox, SIGNAL(valueChanged(double)), this, SLOT(amplitudeChanged(double))); - connect(m_ui.overshootSpinBox, SIGNAL(valueChanged(double)), this, SLOT(overshootChanged(double))); + connect(m_ui.easingCurvePicker, &QListWidget::currentRowChanged, + this, &Window::curveChanged); + connect(buttonGroup, QOverload::of(&QButtonGroup::buttonClicked), + this, &Window::pathChanged); + connect(m_ui.periodSpinBox, QOverload::of(&QDoubleSpinBox::valueChanged), + this, &Window::periodChanged); + connect(m_ui.amplitudeSpinBox, QOverload::of(&QDoubleSpinBox::valueChanged), + this, &Window::amplitudeChanged); + connect(m_ui.overshootSpinBox, QOverload::of(&QDoubleSpinBox::valueChanged), + this, &Window::overshootChanged); createCurveIcons(); QPixmap pix(QLatin1String(":/images/qt-logo.png")); diff --git a/examples/widgets/animation/moveblocks/main.cpp b/examples/widgets/animation/moveblocks/main.cpp index 6d17696108..e59b17cbf9 100644 --- a/examples/widgets/animation/moveblocks/main.cpp +++ b/examples/widgets/animation/moveblocks/main.cpp @@ -214,7 +214,7 @@ int main(int argc, char **argv) QTimer timer; timer.setInterval(1250); timer.setSingleShot(true); - QObject::connect(group, SIGNAL(entered()), &timer, SLOT(start())); + QObject::connect(group, &QState::entered, &timer, QOverload<>::of(&QTimer::start)); //![2] //![3] @@ -302,7 +302,7 @@ int main(int argc, char **argv) //![7] StateSwitcher *stateSwitcher = new StateSwitcher(&machine); stateSwitcher->setObjectName("stateSwitcher"); - group->addTransition(&timer, SIGNAL(timeout()), stateSwitcher); + group->addTransition(&timer, &QTimer::timeout, stateSwitcher); stateSwitcher->addState(state1, &animationGroup); stateSwitcher->addState(state2, &animationGroup); //![7] diff --git a/examples/widgets/animation/states/main.cpp b/examples/widgets/animation/states/main.cpp index 14d193c301..0f61b7457a 100644 --- a/examples/widgets/animation/states/main.cpp +++ b/examples/widgets/animation/states/main.cpp @@ -214,7 +214,7 @@ int main(int argc, char *argv[]) state3->assignProperty(p5, "opacity", qreal(1)); state3->assignProperty(p6, "opacity", qreal(1)); - QAbstractTransition *t1 = state1->addTransition(button, SIGNAL(clicked()), state2); + QAbstractTransition *t1 = state1->addTransition(button, &QAbstractButton::clicked, state2); QSequentialAnimationGroup *animation1SubGroup = new QSequentialAnimationGroup; animation1SubGroup->addPause(250); animation1SubGroup->addAnimation(new QPropertyAnimation(box, "geometry")); @@ -239,7 +239,7 @@ int main(int argc, char *argv[]) t1->addAnimation(new QPropertyAnimation(p5, "opacity")); t1->addAnimation(new QPropertyAnimation(p6, "opacity")); - QAbstractTransition *t2 = state2->addTransition(button, SIGNAL(clicked()), state3); + QAbstractTransition *t2 = state2->addTransition(button, &QAbstractButton::clicked, state3); t2->addAnimation(new QPropertyAnimation(box, "geometry")); t2->addAnimation(new QPropertyAnimation(widget, "geometry")); t2->addAnimation(new QPropertyAnimation(p1, "pos")); @@ -261,7 +261,7 @@ int main(int argc, char *argv[]) t2->addAnimation(new QPropertyAnimation(p5, "opacity")); t2->addAnimation(new QPropertyAnimation(p6, "opacity")); - QAbstractTransition *t3 = state3->addTransition(button, SIGNAL(clicked()), state1); + QAbstractTransition *t3 = state3->addTransition(button, &QAbstractButton::clicked, state1); t3->addAnimation(new QPropertyAnimation(box, "geometry")); t3->addAnimation(new QPropertyAnimation(widget, "geometry")); t3->addAnimation(new QPropertyAnimation(p1, "pos")); diff --git a/examples/widgets/animation/stickman/lifecycle.cpp b/examples/widgets/animation/stickman/lifecycle.cpp index dbe9a299b4..5d4c406b2e 100644 --- a/examples/widgets/animation/stickman/lifecycle.cpp +++ b/examples/widgets/animation/stickman/lifecycle.cpp @@ -61,11 +61,11 @@ class KeyPressTransition: public QSignalTransition { public: KeyPressTransition(GraphicsView *receiver, Qt::Key key) - : QSignalTransition(receiver, SIGNAL(keyPressed(int))), m_key(key) + : QSignalTransition(receiver, &GraphicsView::keyPressed), m_key(key) { } KeyPressTransition(GraphicsView *receiver, Qt::Key key, QAbstractState *target) - : QSignalTransition(receiver, SIGNAL(keyPressed(int))), m_key(key) + : QSignalTransition(receiver, &GraphicsView::keyPressed), m_key(key) { setTargetState(target); } @@ -132,8 +132,10 @@ LifeCycle::LifeCycle(StickMan *stickMan, GraphicsView *keyReceiver) QTimer *timer = new QTimer(lightningBlink); timer->setSingleShot(true); timer->setInterval(100); - QObject::connect(lightningBlink, SIGNAL(entered()), timer, SLOT(start())); - QObject::connect(lightningBlink, SIGNAL(exited()), timer, SLOT(stop())); + QObject::connect(lightningBlink, &QAbstractState::entered, + timer, QOverload<>::of(&QTimer::start)); + QObject::connect(lightningBlink, &QAbstractState::exited, + timer, &QTimer::stop); //! [5] m_dead = new QState(m_machine); @@ -151,7 +153,7 @@ LifeCycle::LifeCycle(StickMan *stickMan, GraphicsView *keyReceiver) // Lightning strikes at random m_alive->addTransition(new LightningStrikesTransition(lightningBlink)); //! [0] - lightningBlink->addTransition(timer, SIGNAL(timeout()), m_dead); + lightningBlink->addTransition(timer, &QTimer::timeout, m_dead); //! [0] m_machine->setInitialState(m_alive); @@ -206,14 +208,14 @@ QState *LifeCycle::makeState(QState *parentState, const QString &animationFileNa topLevel->setInitialState(frameState); else //! [2] - previousState->addTransition(previousState, SIGNAL(propertiesAssigned()), frameState); + previousState->addTransition(previousState, &QState::propertiesAssigned, frameState); //! [2] previousState = frameState; } // Loop - previousState->addTransition(previousState, SIGNAL(propertiesAssigned()), topLevel->initialState()); + previousState->addTransition(previousState, &QState::propertiesAssigned, topLevel->initialState()); return topLevel; diff --git a/examples/widgets/animation/stickman/stickman.cpp b/examples/widgets/animation/stickman/stickman.cpp index b7a2d87ada..8b183d87d5 100644 --- a/examples/widgets/animation/stickman/stickman.cpp +++ b/examples/widgets/animation/stickman/stickman.cpp @@ -126,7 +126,7 @@ StickMan::StickMan() // Set up start position of limbs for (int i=0; iaddTransition(leftMoveStop); //The animation is finished, it means we reached the border of the screen, the boat is stopped so we move to the stop state - moveStateLeft->addTransition(movementAnimation, SIGNAL(finished()), stopState); - moveStateRight->addTransition(movementAnimation, SIGNAL(finished()), stopState); + moveStateLeft->addTransition(movementAnimation, &QAbstractAnimation::finished, stopState); + moveStateRight->addTransition(movementAnimation, &QAbstractAnimation::finished, stopState); //We set up the keys for dropping bombs KeyLaunchTransition *upFireLeft = new KeyLaunchTransition(this, QEvent::KeyPress, Qt::Key_Up); @@ -187,13 +187,13 @@ Boat::Boat() : PixmapItem(QString("boat"), GraphicsScene::Big), destroyedState->setAnimation(destroyAnimation); //Play a nice animation when the boat is destroyed - moving->addTransition(this, SIGNAL(boatDestroyed()), destroyedState); + moving->addTransition(this, &Boat::boatDestroyed, destroyedState); //Transition to final state when the destroyed animation is finished - destroyedState->addTransition(destroyedState, SIGNAL(animationFinished()), final); + destroyedState->addTransition(destroyedState, &QAnimationState::animationFinished, final); //The machine has finished to be executed, then the boat is dead - connect(machine,SIGNAL(finished()), this, SIGNAL(boatExecutionFinished())); + connect(machine,&QState::finished, this, &Boat::boatExecutionFinished); } diff --git a/examples/widgets/animation/sub-attaq/bomb.cpp b/examples/widgets/animation/sub-attaq/bomb.cpp index a80d2d46c5..76e4575293 100644 --- a/examples/widgets/animation/sub-attaq/bomb.cpp +++ b/examples/widgets/animation/sub-attaq/bomb.cpp @@ -83,8 +83,8 @@ void Bomb::launch(Bomb::Direction direction) anim->setEndValue(QPointF(x() + delta*2,scene()->height())); anim->setDuration(y()/2*60); launchAnimation->addAnimation(anim); - connect(anim,SIGNAL(valueChanged(QVariant)),this,SLOT(onAnimationLaunchValueChanged(QVariant))); - connect(this, SIGNAL(bombExploded()), launchAnimation, SLOT(stop())); + connect(anim,&QVariantAnimation::valueChanged,this,&Bomb::onAnimationLaunchValueChanged); + connect(this, &Bomb::bombExploded, launchAnimation, &QAbstractAnimation::stop); //We setup the state machine of the bomb QStateMachine *machine = new QStateMachine(this); @@ -98,13 +98,13 @@ void Bomb::launch(Bomb::Direction direction) machine->setInitialState(launched); //### Add a nice animation when the bomb is destroyed - launched->addTransition(this, SIGNAL(bombExploded()),final); + launched->addTransition(this, &Bomb::bombExploded,final); //If the animation is finished, then we move to the final state - launched->addTransition(launched, SIGNAL(animationFinished()), final); + launched->addTransition(launched, &QAnimationState::animationFinished, final); //The machine has finished to be executed, then the boat is dead - connect(machine,SIGNAL(finished()),this, SIGNAL(bombExecutionFinished())); + connect(machine,&QState::finished,this, &Bomb::bombExecutionFinished); machine->start(); diff --git a/examples/widgets/animation/sub-attaq/graphicsscene.cpp b/examples/widgets/animation/sub-attaq/graphicsscene.cpp index e0913f99f6..3205cdc54d 100644 --- a/examples/widgets/animation/sub-attaq/graphicsscene.cpp +++ b/examples/widgets/animation/sub-attaq/graphicsscene.cpp @@ -191,15 +191,15 @@ void GraphicsScene::setupScene(QAction *newAction, QAction *quitAction) lettersFadingState->setAnimation(lettersGroupFading); //if new game then we fade out the welcome screen and start playing - lettersMovingState->addTransition(newAction, SIGNAL(triggered()), lettersFadingState); - lettersFadingState->addTransition(lettersFadingState, SIGNAL(animationFinished()), gameState); + lettersMovingState->addTransition(newAction, &QAction::triggered, lettersFadingState); + lettersFadingState->addTransition(lettersFadingState, &QAnimationState::animationFinished, gameState); //New Game is triggered then player start playing - gameState->addTransition(newAction, SIGNAL(triggered()), gameState); + gameState->addTransition(newAction, &QAction::triggered, gameState); //Wanna quit, then connect to CTRL+Q - gameState->addTransition(quitAction, SIGNAL(triggered()), final); - lettersMovingState->addTransition(quitAction, SIGNAL(triggered()), final); + gameState->addTransition(quitAction, &QAction::triggered, final); + lettersMovingState->addTransition(quitAction, &QAction::triggered, final); //Welcome screen is the initial state machine->setInitialState(lettersMovingState); @@ -207,27 +207,27 @@ void GraphicsScene::setupScene(QAction *newAction, QAction *quitAction) machine->start(); //We reach the final state, then we quit - connect(machine, SIGNAL(finished()), qApp, SLOT(quit())); + connect(machine, &QStateMachine::finished, qApp, &QApplication::quit); } void GraphicsScene::addItem(Bomb *bomb) { bombs.insert(bomb); - connect(bomb,SIGNAL(bombExecutionFinished()),this, SLOT(onBombExecutionFinished())); + connect(bomb,&Bomb::bombExecutionFinished,this, &GraphicsScene::onBombExecutionFinished); QGraphicsScene::addItem(bomb); } void GraphicsScene::addItem(Torpedo *torpedo) { torpedos.insert(torpedo); - connect(torpedo,SIGNAL(torpedoExecutionFinished()),this, SLOT(onTorpedoExecutionFinished())); + connect(torpedo,&Torpedo::torpedoExecutionFinished,this, &GraphicsScene::onTorpedoExecutionFinished); QGraphicsScene::addItem(torpedo); } void GraphicsScene::addItem(SubMarine *submarine) { submarines.insert(submarine); - connect(submarine,SIGNAL(subMarineExecutionFinished()),this, SLOT(onSubMarineExecutionFinished())); + connect(submarine,&SubMarine::subMarineExecutionFinished,this, &GraphicsScene::onSubMarineExecutionFinished); QGraphicsScene::addItem(submarine); } diff --git a/examples/widgets/animation/sub-attaq/qanimationstate.cpp b/examples/widgets/animation/sub-attaq/qanimationstate.cpp index ae24af6da3..fc0da7cea2 100644 --- a/examples/widgets/animation/sub-attaq/qanimationstate.cpp +++ b/examples/widgets/animation/sub-attaq/qanimationstate.cpp @@ -73,7 +73,7 @@ QAnimationState *s = new QAnimationState(machine->rootState()); QPropertyAnimation *animation = new QPropertyAnimation(obj, "pos"); s->setAnimation(animation); QState *s2 = new QState(machine->rootState()); -s->addTransition(s, SIGNAL(animationFinished()), s2); +s->addTransition(s, &QAnimationState::animationFinished, s2); machine.start(); \endcode @@ -107,13 +107,13 @@ void QAnimationState::setAnimation(QAbstractAnimation *animation) //Disconnect from the previous animation if exist if(m_animation) - disconnect(m_animation, SIGNAL(finished()), this, SIGNAL(animationFinished())); + disconnect(m_animation, &QAbstractAnimation::finished, this, &QAnimationState::animationFinished); m_animation = animation; if (m_animation) { //connect the new animation - connect(m_animation, SIGNAL(finished()), this, SIGNAL(animationFinished())); + connect(m_animation, &QAbstractAnimation::finished, this, &QAnimationState::animationFinished); } } diff --git a/examples/widgets/animation/sub-attaq/states.cpp b/examples/widgets/animation/sub-attaq/states.cpp index e19704db7b..8a3a97a20f 100644 --- a/examples/widgets/animation/sub-attaq/states.cpp +++ b/examples/widgets/animation/sub-attaq/states.cpp @@ -124,7 +124,7 @@ void PlayState::onEntry(QEvent *) WinState *winState = new WinState(scene, this, machine); //The boat has been destroyed then the game is finished - levelState->addTransition(scene->boat, SIGNAL(boatExecutionFinished()),lostState); + levelState->addTransition(scene->boat, &Boat::boatExecutionFinished,lostState); //This transition check if we won or not WinTransition *winTransition = new WinTransition(scene, this, winState); @@ -157,7 +157,7 @@ void PlayState::onEntry(QEvent *) winState->addTransition(spaceTransition); //We lost we should reach the final state - lostState->addTransition(lostState, SIGNAL(finished()), final); + lostState->addTransition(lostState, &QState::finished, final); machine->start(); } @@ -291,8 +291,8 @@ UpdateScoreState::UpdateScoreState(QState *parent) : QState(parent) /** Win transition */ UpdateScoreTransition::UpdateScoreTransition(GraphicsScene *scene, PlayState *game, QAbstractState *target) - : QSignalTransition(scene,SIGNAL(subMarineDestroyed(int))), - game(game), scene(scene) + : QSignalTransition(scene, &GraphicsScene::subMarineDestroyed), + game(game), scene(scene) { setTargetState(target); } @@ -309,8 +309,8 @@ bool UpdateScoreTransition::eventTest(QEvent *event) /** Win transition */ WinTransition::WinTransition(GraphicsScene *scene, PlayState *game, QAbstractState *target) - : QSignalTransition(scene,SIGNAL(allSubMarineDestroyed(int))), - game(game), scene(scene) + : QSignalTransition(scene, &GraphicsScene::allSubMarineDestroyed), + game(game), scene(scene) { setTargetState(target); } diff --git a/examples/widgets/animation/sub-attaq/submarine.cpp b/examples/widgets/animation/sub-attaq/submarine.cpp index a451185ce0..775e75ceed 100644 --- a/examples/widgets/animation/sub-attaq/submarine.cpp +++ b/examples/widgets/animation/sub-attaq/submarine.cpp @@ -106,7 +106,7 @@ SubMarine::SubMarine(int type, const QString &name, int points) : PixmapItem(QSt //This is the initial state of the moving root state moving->setInitialState(movement); - movement->addTransition(this, SIGNAL(subMarineStateChanged()), moving); + movement->addTransition(this, &SubMarine::subMarineStateChanged, moving); //This is the initial state of the machine machine->setInitialState(moving); @@ -115,23 +115,23 @@ SubMarine::SubMarine(int type, const QString &name, int points) : PixmapItem(QSt QFinalState *final = new QFinalState(machine); //If the moving animation is finished we move to the return state - movement->addTransition(movement, SIGNAL(animationFinished()), rotation); + movement->addTransition(movement, &QAnimationState::animationFinished, rotation); //If the return animation is finished we move to the moving state - rotation->addTransition(rotation, SIGNAL(animationFinished()), movement); + rotation->addTransition(rotation, &QAnimationState::animationFinished, movement); //This state play the destroyed animation QAnimationState *destroyedState = new QAnimationState(machine); destroyedState->setAnimation(setupDestroyAnimation(this)); //Play a nice animation when the submarine is destroyed - moving->addTransition(this, SIGNAL(subMarineDestroyed()), destroyedState); + moving->addTransition(this, &SubMarine::subMarineDestroyed, destroyedState); //Transition to final state when the destroyed animation is finished - destroyedState->addTransition(destroyedState, SIGNAL(animationFinished()), final); + destroyedState->addTransition(destroyedState, &QAnimationState::animationFinished, final); //The machine has finished to be executed, then the submarine is dead - connect(machine,SIGNAL(finished()),this, SIGNAL(subMarineExecutionFinished())); + connect(machine,&QState::finished,this, &SubMarine::subMarineExecutionFinished); machine->start(); } diff --git a/examples/widgets/animation/sub-attaq/submarine_p.h b/examples/widgets/animation/sub-attaq/submarine_p.h index 698b4b494f..1c2cb7ceac 100644 --- a/examples/widgets/animation/sub-attaq/submarine_p.h +++ b/examples/widgets/animation/sub-attaq/submarine_p.h @@ -80,7 +80,8 @@ public: explicit MovementState(SubMarine *submarine, QState *parent = 0) : QAnimationState(parent) { movementAnimation = new QPropertyAnimation(submarine, "pos"); - connect(movementAnimation,SIGNAL(valueChanged(const QVariant &)),this,SLOT(onAnimationMovementValueChanged(const QVariant &))); + connect(movementAnimation, &QPropertyAnimation::valueChanged, + this, &MovementState::onAnimationMovementValueChanged); setAnimation(movementAnimation); AnimationManager::self()->registerAnimation(movementAnimation); this->submarine = submarine; diff --git a/examples/widgets/animation/sub-attaq/torpedo.cpp b/examples/widgets/animation/sub-attaq/torpedo.cpp index 2e9d970326..5f8ef2f2b8 100644 --- a/examples/widgets/animation/sub-attaq/torpedo.cpp +++ b/examples/widgets/animation/sub-attaq/torpedo.cpp @@ -73,8 +73,8 @@ void Torpedo::launch() launchAnimation->setEndValue(QPointF(x(),qobject_cast(scene())->sealLevel() - 15)); launchAnimation->setEasingCurve(QEasingCurve::InQuad); launchAnimation->setDuration(y()/currentSpeed*10); - connect(launchAnimation,SIGNAL(valueChanged(QVariant)),this,SLOT(onAnimationLaunchValueChanged(QVariant))); - connect(this,SIGNAL(torpedoExploded()), launchAnimation, SLOT(stop())); + connect(launchAnimation,&QVariantAnimation::valueChanged,this,&Torpedo::onAnimationLaunchValueChanged); + connect(this,&Torpedo::torpedoExploded, launchAnimation, &QAbstractAnimation::stop); //We setup the state machine of the torpedo QStateMachine *machine = new QStateMachine(this); @@ -89,13 +89,13 @@ void Torpedo::launch() machine->setInitialState(launched); //### Add a nice animation when the torpedo is destroyed - launched->addTransition(this, SIGNAL(torpedoExploded()),final); + launched->addTransition(this, &Torpedo::torpedoExploded,final); //If the animation is finished, then we move to the final state - launched->addTransition(launched, SIGNAL(animationFinished()), final); + launched->addTransition(launched, &QAnimationState::animationFinished, final); //The machine has finished to be executed, then the boat is dead - connect(machine,SIGNAL(finished()),this, SIGNAL(torpedoExecutionFinished())); + connect(machine,&QState::finished,this, &Torpedo::torpedoExecutionFinished); machine->start(); } diff --git a/examples/widgets/effects/fademessage/fademessage.cpp b/examples/widgets/effects/fademessage/fademessage.cpp index 9943147bb7..4c3a70bb4f 100644 --- a/examples/widgets/effects/fademessage/fademessage.cpp +++ b/examples/widgets/effects/fademessage/fademessage.cpp @@ -131,7 +131,7 @@ void FadeMessage::setupScene() QPushButton *press = new QPushButton; press->setText(tr("Press me")); - connect(press, SIGNAL(clicked()), SLOT(togglePopup())); + connect(press, &QAbstractButton::clicked, this, &FadeMessage::togglePopup); m_scene.addWidget(press); press->move(300, 500); diff --git a/examples/widgets/graphicsview/boxes/scene.cpp b/examples/widgets/graphicsview/boxes/scene.cpp index 1637c1f781..3c65206c02 100644 --- a/examples/widgets/graphicsview/boxes/scene.cpp +++ b/examples/widgets/graphicsview/boxes/scene.cpp @@ -111,7 +111,7 @@ ColorEdit::ColorEdit(QRgb initialColor, int id) m_button->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); layout->addWidget(m_button); - connect(m_lineEdit, SIGNAL(editingFinished()), this, SLOT(editDone())); + connect(m_lineEdit, &QLineEdit::editingFinished, this, &ColorEdit::editDone); } void ColorEdit::editDone() @@ -166,7 +166,7 @@ FloatEdit::FloatEdit(float initialValue, int id) m_lineEdit = new QLineEdit(QString::number(m_value)); layout->addWidget(m_lineEdit); - connect(m_lineEdit, SIGNAL(editingFinished()), this, SLOT(editDone())); + connect(m_lineEdit, &QLineEdit::editingFinished, this, &FloatEdit::editDone); } void FloatEdit::editDone() @@ -252,7 +252,7 @@ void TwoSidedGraphicsWidget::animateFlip() .translate(-r.width() / 2, -r.height() / 2)); if ((m_current == 0 && m_angle > 0) || (m_current == 1 && m_angle < 180)) - QTimer::singleShot(25, this, SLOT(animateFlip())); + QTimer::singleShot(25, this, &TwoSidedGraphicsWidget::animateFlip); } QVariant GraphicsWidget::itemChange(GraphicsItemChange change, const QVariant &value) @@ -307,7 +307,7 @@ RenderOptionsDialog::RenderOptionsDialog() check->setCheckState(Qt::Unchecked); // Dynamic cube maps are only enabled when multi-texturing and render to texture are available. check->setEnabled(glActiveTexture && glGenFramebuffersEXT); - connect(check, SIGNAL(stateChanged(int)), this, SIGNAL(dynamicCubemapToggled(int))); + connect(check, &QCheckBox::stateChanged, this, &RenderOptionsDialog::dynamicCubemapToggled); layout->addWidget(check, 0, 0, 1, 2); ++row; @@ -356,7 +356,7 @@ RenderOptionsDialog::RenderOptionsDialog() ColorEdit *colorEdit = new ColorEdit(it->toUInt(&ok, 16), m_parameterNames.size() - 1); m_parameterEdits << colorEdit; layout->addWidget(colorEdit); - connect(colorEdit, SIGNAL(colorChanged(QRgb,int)), this, SLOT(setColorParameter(QRgb,int))); + connect(colorEdit, &ColorEdit::colorChanged, this, &RenderOptionsDialog::setColorParameter); ++row; } else if (type == "float") { layout->addWidget(new QLabel(m_parameterNames.back())); @@ -364,7 +364,7 @@ RenderOptionsDialog::RenderOptionsDialog() FloatEdit *floatEdit = new FloatEdit(it->toFloat(&ok), m_parameterNames.size() - 1); m_parameterEdits << floatEdit; layout->addWidget(floatEdit); - connect(floatEdit, SIGNAL(valueChanged(float,int)), this, SLOT(setFloatParameter(float,int))); + connect(floatEdit, &FloatEdit::valueChanged, this, &RenderOptionsDialog::setFloatParameter); ++row; } } @@ -375,13 +375,15 @@ RenderOptionsDialog::RenderOptionsDialog() layout->addWidget(new QLabel(tr("Texture:"))); m_textureCombo = new QComboBox; - connect(m_textureCombo, SIGNAL(currentIndexChanged(int)), this, SIGNAL(textureChanged(int))); + connect(m_textureCombo, QOverload::of(&QComboBox::currentIndexChanged), + this, &RenderOptionsDialog::textureChanged); layout->addWidget(m_textureCombo); ++row; layout->addWidget(new QLabel(tr("Shader:"))); m_shaderCombo = new QComboBox; - connect(m_shaderCombo, SIGNAL(currentIndexChanged(int)), this, SIGNAL(shaderChanged(int))); + connect(m_shaderCombo, QOverload::of(&QComboBox::currentIndexChanged), + this, &RenderOptionsDialog::shaderChanged); layout->addWidget(m_shaderCombo); ++row; @@ -439,15 +441,15 @@ ItemDialog::ItemDialog() button = new QPushButton(tr("Add Qt box")); layout->addWidget(button); - connect(button, SIGNAL(clicked()), this, SLOT(triggerNewQtBox())); + connect(button, &QAbstractButton::clicked, this, &ItemDialog::triggerNewQtBox); button = new QPushButton(tr("Add circle")); layout->addWidget(button); - connect(button, SIGNAL(clicked()), this, SLOT(triggerNewCircleItem())); + connect(button, &QAbstractButton::clicked, this, &ItemDialog::triggerNewCircleItem); button = new QPushButton(tr("Add square")); layout->addWidget(button); - connect(button, SIGNAL(clicked()), this, SLOT(triggerNewSquareItem())); + connect(button, &QAbstractButton::clicked, this, &ItemDialog::triggerNewSquareItem); layout->addStretch(1); } @@ -506,21 +508,21 @@ Scene::Scene(int width, int height, int maxTextureSize) m_renderOptions->move(20, 120); m_renderOptions->resize(m_renderOptions->sizeHint()); - connect(m_renderOptions, SIGNAL(dynamicCubemapToggled(int)), this, SLOT(toggleDynamicCubemap(int))); - connect(m_renderOptions, SIGNAL(colorParameterChanged(QString,QRgb)), this, SLOT(setColorParameter(QString,QRgb))); - connect(m_renderOptions, SIGNAL(floatParameterChanged(QString,float)), this, SLOT(setFloatParameter(QString,float))); - connect(m_renderOptions, SIGNAL(textureChanged(int)), this, SLOT(setTexture(int))); - connect(m_renderOptions, SIGNAL(shaderChanged(int)), this, SLOT(setShader(int))); + connect(m_renderOptions, &RenderOptionsDialog::dynamicCubemapToggled, this, &Scene::toggleDynamicCubemap); + connect(m_renderOptions, &RenderOptionsDialog::colorParameterChanged, this, &Scene::setColorParameter); + connect(m_renderOptions, &RenderOptionsDialog::floatParameterChanged, this, &Scene::setFloatParameter); + connect(m_renderOptions, &RenderOptionsDialog::textureChanged, this, &Scene::setTexture); + connect(m_renderOptions, &RenderOptionsDialog::shaderChanged, this, &Scene::setShader); m_itemDialog = new ItemDialog; - connect(m_itemDialog, SIGNAL(newItemTriggered(ItemDialog::ItemType)), this, SLOT(newItem(ItemDialog::ItemType))); + connect(m_itemDialog, &ItemDialog::newItemTriggered, this, &Scene::newItem); TwoSidedGraphicsWidget *twoSided = new TwoSidedGraphicsWidget(this); twoSided->setWidget(0, m_renderOptions); twoSided->setWidget(1, m_itemDialog); - connect(m_renderOptions, SIGNAL(doubleClicked()), twoSided, SLOT(flip())); - connect(m_itemDialog, SIGNAL(doubleClicked()), twoSided, SLOT(flip())); + connect(m_renderOptions, &RenderOptionsDialog::doubleClicked, twoSided, &TwoSidedGraphicsWidget::flip); + connect(m_itemDialog, &ItemDialog::doubleClicked, twoSided, &TwoSidedGraphicsWidget::flip); addItem(new QtBox(64, width - 64, height - 64)); addItem(new QtBox(64, width - 64, 64)); @@ -531,7 +533,7 @@ Scene::Scene(int width, int height, int maxTextureSize) m_timer = new QTimer(this); m_timer->setInterval(20); - connect(m_timer, SIGNAL(timeout()), this, SLOT(update())); + connect(m_timer, &QTimer::timeout, this, [this](){ update(); }); m_timer->start(); m_time.start(); diff --git a/examples/widgets/graphicsview/chip/view.cpp b/examples/widgets/graphicsview/chip/view.cpp index 491f1a54cf..9676c13ff7 100644 --- a/examples/widgets/graphicsview/chip/view.cpp +++ b/examples/widgets/graphicsview/chip/view.cpp @@ -190,22 +190,22 @@ View::View(const QString &name, QWidget *parent) topLayout->addWidget(resetButton, 2, 1); setLayout(topLayout); - connect(resetButton, SIGNAL(clicked()), this, SLOT(resetView())); - connect(zoomSlider, SIGNAL(valueChanged(int)), this, SLOT(setupMatrix())); - connect(rotateSlider, SIGNAL(valueChanged(int)), this, SLOT(setupMatrix())); - connect(graphicsView->verticalScrollBar(), SIGNAL(valueChanged(int)), - this, SLOT(setResetButtonEnabled())); - connect(graphicsView->horizontalScrollBar(), SIGNAL(valueChanged(int)), - this, SLOT(setResetButtonEnabled())); - connect(selectModeButton, SIGNAL(toggled(bool)), this, SLOT(togglePointerMode())); - connect(dragModeButton, SIGNAL(toggled(bool)), this, SLOT(togglePointerMode())); - connect(antialiasButton, SIGNAL(toggled(bool)), this, SLOT(toggleAntialiasing())); - connect(openGlButton, SIGNAL(toggled(bool)), this, SLOT(toggleOpenGL())); - connect(rotateLeftIcon, SIGNAL(clicked()), this, SLOT(rotateLeft())); - connect(rotateRightIcon, SIGNAL(clicked()), this, SLOT(rotateRight())); - connect(zoomInIcon, SIGNAL(clicked()), this, SLOT(zoomIn())); - connect(zoomOutIcon, SIGNAL(clicked()), this, SLOT(zoomOut())); - connect(printButton, SIGNAL(clicked()), this, SLOT(print())); + connect(resetButton, &QAbstractButton::clicked, this, &View::resetView); + connect(zoomSlider, &QAbstractSlider::valueChanged, this, &View::setupMatrix); + connect(rotateSlider, &QAbstractSlider::valueChanged, this, &View::setupMatrix); + connect(graphicsView->verticalScrollBar(), &QAbstractSlider::valueChanged, + this, &View::setResetButtonEnabled); + connect(graphicsView->horizontalScrollBar(), &QAbstractSlider::valueChanged, + this, &View::setResetButtonEnabled); + connect(selectModeButton, &QAbstractButton::toggled, this, &View::togglePointerMode); + connect(dragModeButton, &QAbstractButton::toggled, this, &View::togglePointerMode); + connect(antialiasButton, &QAbstractButton::toggled, this, &View::toggleAntialiasing); + connect(openGlButton, &QAbstractButton::toggled, this, &View::toggleOpenGL); + connect(rotateLeftIcon, &QAbstractButton::clicked, this, &View::rotateLeft); + connect(rotateRightIcon, &QAbstractButton::clicked, this, &View::rotateRight); + connect(zoomInIcon, &QAbstractButton::clicked, this, &View::zoomIn); + connect(zoomOutIcon, &QAbstractButton::clicked, this, &View::zoomOut); + connect(printButton, &QAbstractButton::clicked, this, &View::print); setupMatrix(); } diff --git a/examples/widgets/graphicsview/collidingmice/main.cpp b/examples/widgets/graphicsview/collidingmice/main.cpp index 91aee70b86..dfb20815b9 100644 --- a/examples/widgets/graphicsview/collidingmice/main.cpp +++ b/examples/widgets/graphicsview/collidingmice/main.cpp @@ -92,7 +92,7 @@ int main(int argc, char **argv) view.show(); QTimer timer; - QObject::connect(&timer, SIGNAL(timeout()), &scene, SLOT(advance())); + QObject::connect(&timer, &QTimer::timeout, &scene, &QGraphicsScene::advance); timer.start(1000 / 33); return app.exec(); diff --git a/examples/widgets/graphicsview/diagramscene/diagramscene.cpp b/examples/widgets/graphicsview/diagramscene/diagramscene.cpp index bbbc512b55..51d855cc75 100644 --- a/examples/widgets/graphicsview/diagramscene/diagramscene.cpp +++ b/examples/widgets/graphicsview/diagramscene/diagramscene.cpp @@ -169,10 +169,10 @@ void DiagramScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) textItem->setFont(myFont); textItem->setTextInteractionFlags(Qt::TextEditorInteraction); textItem->setZValue(1000.0); - connect(textItem, SIGNAL(lostFocus(DiagramTextItem*)), - this, SLOT(editorLostFocus(DiagramTextItem*))); - connect(textItem, SIGNAL(selectedChange(QGraphicsItem*)), - this, SIGNAL(itemSelected(QGraphicsItem*))); + connect(textItem, &DiagramTextItem::lostFocus, + this, &DiagramScene::editorLostFocus); + connect(textItem, &DiagramTextItem::selectedChange, + this, &DiagramScene::itemSelected); addItem(textItem); textItem->setDefaultTextColor(myTextColor); textItem->setPos(mouseEvent->scenePos()); diff --git a/examples/widgets/graphicsview/diagramscene/mainwindow.cpp b/examples/widgets/graphicsview/diagramscene/mainwindow.cpp index 36353674ea..875c41b284 100644 --- a/examples/widgets/graphicsview/diagramscene/mainwindow.cpp +++ b/examples/widgets/graphicsview/diagramscene/mainwindow.cpp @@ -67,12 +67,12 @@ MainWindow::MainWindow() scene = new DiagramScene(itemMenu, this); scene->setSceneRect(QRectF(0, 0, 5000, 5000)); - connect(scene, SIGNAL(itemInserted(DiagramItem*)), - this, SLOT(itemInserted(DiagramItem*))); - connect(scene, SIGNAL(textInserted(QGraphicsTextItem*)), - this, SLOT(textInserted(QGraphicsTextItem*))); - connect(scene, SIGNAL(itemSelected(QGraphicsItem*)), - this, SLOT(itemSelected(QGraphicsItem*))); + connect(scene, &DiagramScene::itemInserted, + this, &MainWindow::itemInserted); + connect(scene, &DiagramScene::textInserted, + this, &MainWindow::textInserted); + connect(scene, &DiagramScene::itemSelected, + this, &MainWindow::itemSelected); createToolbars(); QHBoxLayout *layout = new QHBoxLayout; @@ -332,8 +332,8 @@ void MainWindow::createToolBox() { buttonGroup = new QButtonGroup(this); buttonGroup->setExclusive(false); - connect(buttonGroup, SIGNAL(buttonClicked(int)), - this, SLOT(buttonGroupClicked(int))); + connect(buttonGroup, QOverload::of(&QButtonGroup::buttonClicked), + this, &MainWindow::buttonGroupClicked); QGridLayout *layout = new QGridLayout; layout->addWidget(createCellWidget(tr("Conditional"), DiagramItem::Conditional), 0, 0); layout->addWidget(createCellWidget(tr("Process"), DiagramItem::Step),0, 1); @@ -359,8 +359,8 @@ void MainWindow::createToolBox() itemWidget->setLayout(layout); backgroundButtonGroup = new QButtonGroup(this); - connect(backgroundButtonGroup, SIGNAL(buttonClicked(QAbstractButton*)), - this, SLOT(backgroundButtonGroupClicked(QAbstractButton*))); + connect(backgroundButtonGroup, QOverload::of(&QButtonGroup::buttonClicked), + this, &MainWindow::backgroundButtonGroupClicked); QGridLayout *backgroundLayout = new QGridLayout; backgroundLayout->addWidget(createBackgroundCellWidget(tr("Blue Grid"), @@ -395,44 +395,44 @@ void MainWindow::createActions() tr("Bring to &Front"), this); toFrontAction->setShortcut(tr("Ctrl+F")); toFrontAction->setStatusTip(tr("Bring item to front")); - connect(toFrontAction, SIGNAL(triggered()), this, SLOT(bringToFront())); + connect(toFrontAction, &QAction::triggered, this, &MainWindow::bringToFront); //! [23] sendBackAction = new QAction(QIcon(":/images/sendtoback.png"), tr("Send to &Back"), this); sendBackAction->setShortcut(tr("Ctrl+T")); sendBackAction->setStatusTip(tr("Send item to back")); - connect(sendBackAction, SIGNAL(triggered()), this, SLOT(sendToBack())); + connect(sendBackAction, &QAction::triggered, this, &MainWindow::sendToBack); deleteAction = new QAction(QIcon(":/images/delete.png"), tr("&Delete"), this); deleteAction->setShortcut(tr("Delete")); deleteAction->setStatusTip(tr("Delete item from diagram")); - connect(deleteAction, SIGNAL(triggered()), this, SLOT(deleteItem())); + connect(deleteAction, &QAction::triggered, this, &MainWindow::deleteItem); exitAction = new QAction(tr("E&xit"), this); exitAction->setShortcuts(QKeySequence::Quit); exitAction->setStatusTip(tr("Quit Scenediagram example")); - connect(exitAction, SIGNAL(triggered()), this, SLOT(close())); + connect(exitAction, &QAction::triggered, this, &QWidget::close); boldAction = new QAction(tr("Bold"), this); boldAction->setCheckable(true); QPixmap pixmap(":/images/bold.png"); boldAction->setIcon(QIcon(pixmap)); boldAction->setShortcut(tr("Ctrl+B")); - connect(boldAction, SIGNAL(triggered()), this, SLOT(handleFontChange())); + connect(boldAction, &QAction::triggered, this, &MainWindow::handleFontChange); italicAction = new QAction(QIcon(":/images/italic.png"), tr("Italic"), this); italicAction->setCheckable(true); italicAction->setShortcut(tr("Ctrl+I")); - connect(italicAction, SIGNAL(triggered()), this, SLOT(handleFontChange())); + connect(italicAction, &QAction::triggered, this, &MainWindow::handleFontChange); underlineAction = new QAction(QIcon(":/images/underline.png"), tr("Underline"), this); underlineAction->setCheckable(true); underlineAction->setShortcut(tr("Ctrl+U")); - connect(underlineAction, SIGNAL(triggered()), this, SLOT(handleFontChange())); + connect(underlineAction, &QAction::triggered, this, &MainWindow::handleFontChange); aboutAction = new QAction(tr("A&bout"), this); aboutAction->setShortcut(tr("F1")); - connect(aboutAction, SIGNAL(triggered()), this, SLOT(about())); + connect(aboutAction, &QAction::triggered, this, &MainWindow::about); } //! [24] @@ -462,8 +462,8 @@ void MainWindow::createToolbars() editToolBar->addAction(sendBackAction); fontCombo = new QFontComboBox(); - connect(fontCombo, SIGNAL(currentFontChanged(QFont)), - this, SLOT(currentFontChanged(QFont))); + connect(fontCombo, &QFontComboBox::currentFontChanged, + this, &MainWindow::currentFontChanged); fontSizeCombo = new QComboBox; fontSizeCombo->setEditable(true); @@ -471,8 +471,8 @@ void MainWindow::createToolbars() fontSizeCombo->addItem(QString().setNum(i)); QIntValidator *validator = new QIntValidator(2, 64, this); fontSizeCombo->setValidator(validator); - connect(fontSizeCombo, SIGNAL(currentIndexChanged(QString)), - this, SLOT(fontSizeChanged(QString))); + connect(fontSizeCombo, QOverload::of(&QComboBox::currentIndexChanged), + this, &MainWindow::fontSizeChanged); fontColorToolButton = new QToolButton; fontColorToolButton->setPopupMode(QToolButton::MenuButtonPopup); @@ -480,8 +480,8 @@ void MainWindow::createToolbars() textAction = fontColorToolButton->menu()->defaultAction(); fontColorToolButton->setIcon(createColorToolButtonIcon(":/images/textpointer.png", Qt::black)); fontColorToolButton->setAutoFillBackground(true); - connect(fontColorToolButton, SIGNAL(clicked()), - this, SLOT(textButtonTriggered())); + connect(fontColorToolButton, &QAbstractButton::clicked, + this, &MainWindow::textButtonTriggered); //! [26] fillColorToolButton = new QToolButton; @@ -490,8 +490,8 @@ void MainWindow::createToolbars() fillAction = fillColorToolButton->menu()->defaultAction(); fillColorToolButton->setIcon(createColorToolButtonIcon( ":/images/floodfill.png", Qt::white)); - connect(fillColorToolButton, SIGNAL(clicked()), - this, SLOT(fillButtonTriggered())); + connect(fillColorToolButton, &QAbstractButton::clicked, + this, &MainWindow::fillButtonTriggered); //! [26] lineColorToolButton = new QToolButton; @@ -500,8 +500,8 @@ void MainWindow::createToolbars() lineAction = lineColorToolButton->menu()->defaultAction(); lineColorToolButton->setIcon(createColorToolButtonIcon( ":/images/linecolor.png", Qt::black)); - connect(lineColorToolButton, SIGNAL(clicked()), - this, SLOT(lineButtonTriggered())); + connect(lineColorToolButton, &QAbstractButton::clicked, + this, &MainWindow::lineButtonTriggered); textToolBar = addToolBar(tr("Font")); textToolBar->addWidget(fontCombo); @@ -526,16 +526,16 @@ void MainWindow::createToolbars() pointerTypeGroup = new QButtonGroup(this); pointerTypeGroup->addButton(pointerButton, int(DiagramScene::MoveItem)); pointerTypeGroup->addButton(linePointerButton, int(DiagramScene::InsertLine)); - connect(pointerTypeGroup, SIGNAL(buttonClicked(int)), - this, SLOT(pointerGroupClicked(int))); + connect(pointerTypeGroup, QOverload::of(&QButtonGroup::buttonClicked), + this, &MainWindow::pointerGroupClicked); sceneScaleCombo = new QComboBox; QStringList scales; scales << tr("50%") << tr("75%") << tr("100%") << tr("125%") << tr("150%"); sceneScaleCombo->addItems(scales); sceneScaleCombo->setCurrentIndex(2); - connect(sceneScaleCombo, SIGNAL(currentIndexChanged(QString)), - this, SLOT(sceneScaleChanged(QString))); + connect(sceneScaleCombo, QOverload::of(&QComboBox::currentIndexChanged), + this, &MainWindow::sceneScaleChanged); pointerToolbar = addToolBar(tr("Pointer type")); pointerToolbar->addWidget(pointerButton); diff --git a/examples/widgets/graphicsview/embeddeddialogs/customproxy.cpp b/examples/widgets/graphicsview/embeddeddialogs/customproxy.cpp index 158c31d9c1..c181a03e85 100644 --- a/examples/widgets/graphicsview/embeddeddialogs/customproxy.cpp +++ b/examples/widgets/graphicsview/embeddeddialogs/customproxy.cpp @@ -58,10 +58,10 @@ CustomProxy::CustomProxy(QGraphicsItem *parent, Qt::WindowFlags wFlags) : QGraphicsProxyWidget(parent, wFlags), popupShown(false), currentPopup(0) { timeLine = new QTimeLine(250, this); - connect(timeLine, SIGNAL(valueChanged(qreal)), - this, SLOT(updateStep(qreal))); - connect(timeLine, SIGNAL(stateChanged(QTimeLine::State)), - this, SLOT(stateChanged(QTimeLine::State))); + connect(timeLine, &QTimeLine::valueChanged, + this, &CustomProxy::updateStep); + connect(timeLine, &QTimeLine::stateChanged, + this, &CustomProxy::stateChanged); } QRectF CustomProxy::boundingRect() const From abcf7a103eb1e00f2487b2346129112778f8c112 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Wed, 2 Jan 2019 12:18:15 +0100 Subject: [PATCH 0793/1650] configure: improve warning when all qpa plugins disabled with features.gui The mentioned README file has never been very trustworthy and after 863c6887495c0bd9ee3a85aa7cd2d997cdc5c93c it has become very minimal - it doesn't contain anything that is not already present in "configure --help" and enforced by the configure process. Furthermore, the warning was XCB specific, but Qt supports also other QPA plugins on linux. Change-Id: I3211dda3f294cbcd5f3d15fe8c21a1af7627f048 Reviewed-by: Joerg Bornemann --- config_help.txt | 2 +- src/gui/configure.json | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/config_help.txt b/config_help.txt index 7b5da3fbeb..fb37cbaed9 100644 --- a/config_help.txt +++ b/config_help.txt @@ -293,7 +293,7 @@ Gui, printing, widget options: -kms ............... Enable backends for KMS [auto] (Linux only) -linuxfb ........... Enable Linux Framebuffer support [auto] (Linux only) -mirclient ......... Enable Mir client support [no] (Linux only) - -xcb ............... Select used xcb-* libraries [system/qt/no] + -xcb ............... Enable X11 support. Select used xcb-* libraries [system/qt/no] (-qt-xcb still uses system version of libxcb itself) Input backends: diff --git a/src/gui/configure.json b/src/gui/configure.json index 582705f402..89934c8f1d 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -1830,8 +1830,7 @@ or may depend on your system and XQuartz setup." "condition": "features.gui && config.linux && !config.android && !features.xcb && !features.eglfs && !features.directfb && !features.linuxfb && !features.mirclient", "message": "No QPA platform plugin enabled! This will produce a Qt that cannot run GUI applications. -The dependencies needed for xcb to build are listed in -src/plugins/platforms/xcb/README" +See \"Platform backends\" in the output of --help." }, { "type": "warning", From 07685355b5a129dd65b08e39c96df4972924a809 Mon Sep 17 00:00:00 2001 From: Kari Oikarinen Date: Mon, 7 Jan 2019 09:33:46 +0200 Subject: [PATCH 0794/1650] Bump version Change-Id: I2bf8da98a140bdd9848139a96bea736708357a1a Reviewed-by: Jani Heikkinen --- .qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.qmake.conf b/.qmake.conf index 5df08093cd..518aa07f06 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -4,4 +4,4 @@ CONFIG += warning_clean QT_SOURCE_TREE = $$PWD QT_BUILD_TREE = $$shadowed($$PWD) -MODULE_VERSION = 5.12.0 +MODULE_VERSION = 5.12.1 From f7d7d7c81cf233a305ec1b1972bb459623a68e2b Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 17 Dec 2018 13:49:51 +0100 Subject: [PATCH 0795/1650] Minor optimization Avoid calling QThread::current() in many cases. Change-Id: Iac2e8ff1a72e3d39b6efa7e94239abbce29924ac Reviewed-by: Thiago Macieira Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/kernel/qmetaobject.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 5de2717078..27153e0c4d 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -2257,9 +2257,9 @@ bool QMetaMethod::invoke(QObject *object, return false; // check connection type - QThread *currentThread = QThread::currentThread(); - QThread *objectThread = object->thread(); if (connectionType == Qt::AutoConnection) { + QThread *currentThread = QThread::currentThread(); + QThread *objectThread = object->thread(); connectionType = currentThread == objectThread ? Qt::DirectConnection : Qt::QueuedConnection; @@ -2342,6 +2342,8 @@ bool QMetaMethod::invoke(QObject *object, 0, -1, nargs, types, args)); } else { // blocking queued connection #if QT_CONFIG(thread) + QThread *currentThread = QThread::currentThread(); + QThread *objectThread = object->thread(); if (currentThread == objectThread) { qWarning("QMetaMethod::invoke: Dead lock detected in " "BlockingQueuedConnection: Receiver is %s(%p)", From 87c47c6a82c7b6b40e248844feb23088d109f744 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 3 Jan 2019 15:25:59 +0100 Subject: [PATCH 0796/1650] Minor optimization Avoid a couple of branches in QMetaObject::activate(). Change-Id: I15394d1ede48be771797fc5f64a5de6387e6f814 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/kernel/qobject.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 36c108b697..5989fbd1ef 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -3673,10 +3673,12 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i return; } - void *empty_argv[] = { 0 }; + void *empty_argv[] = { nullptr }; + if (!argv) + argv = empty_argv; + if (qt_signal_spy_callback_set.signal_begin_callback != 0) { - qt_signal_spy_callback_set.signal_begin_callback(sender, signal_index, - argv ? argv : empty_argv); + qt_signal_spy_callback_set.signal_begin_callback(sender, signal_index, argv); } Q_TRACE(QMetaObject_activate_begin_signal, sender, signal_index); @@ -3739,7 +3741,7 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i // put into the event queue if ((c->connectionType == Qt::AutoConnection && !receiverInSameThread) || (c->connectionType == Qt::QueuedConnection)) { - queued_activate(sender, signal_index, c, argv ? argv : empty_argv, locker); + queued_activate(sender, signal_index, c, argv, locker); continue; #if QT_CONFIG(thread) } else if (c->connectionType == Qt::BlockingQueuedConnection) { @@ -3751,8 +3753,8 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i } QSemaphore semaphore; QMetaCallEvent *ev = c->isSlotObject ? - new QMetaCallEvent(c->slotObj, sender, signal_index, 0, 0, argv ? argv : empty_argv, &semaphore) : - new QMetaCallEvent(c->method_offset, c->method_relative, c->callFunction, sender, signal_index, 0, 0, argv ? argv : empty_argv, &semaphore); + new QMetaCallEvent(c->slotObj, sender, signal_index, 0, 0, argv, &semaphore) : + new QMetaCallEvent(c->method_offset, c->method_relative, c->callFunction, sender, signal_index, 0, 0, argv, &semaphore); QCoreApplication::postEvent(receiver, ev); locker.unlock(); semaphore.acquire(); @@ -3771,7 +3773,7 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i QScopedPointer obj(c->slotObj); locker.unlock(); Q_TRACE(QMetaObject_activate_begin_slot_functor, obj.data()); - obj->call(receiver, argv ? argv : empty_argv); + obj->call(receiver, argv); Q_TRACE(QMetaObject_activate_end_slot_functor, obj.data()); // Make sure the slot object gets destroyed before the mutex is locked again, as the @@ -3787,10 +3789,10 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i const auto callFunction = c->callFunction; locker.unlock(); if (qt_signal_spy_callback_set.slot_begin_callback != 0) - qt_signal_spy_callback_set.slot_begin_callback(receiver, methodIndex, argv ? argv : empty_argv); + qt_signal_spy_callback_set.slot_begin_callback(receiver, methodIndex, argv); Q_TRACE(QMetaObject_activate_begin_slot, receiver, methodIndex); - callFunction(receiver, QMetaObject::InvokeMetaMethod, method_relative, argv ? argv : empty_argv); + callFunction(receiver, QMetaObject::InvokeMetaMethod, method_relative, argv); Q_TRACE(QMetaObject_activate_end_slot, receiver, methodIndex); if (qt_signal_spy_callback_set.slot_end_callback != 0) @@ -3801,13 +3803,11 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i locker.unlock(); if (qt_signal_spy_callback_set.slot_begin_callback != 0) { - qt_signal_spy_callback_set.slot_begin_callback(receiver, - method, - argv ? argv : empty_argv); + qt_signal_spy_callback_set.slot_begin_callback(receiver, method, argv); } Q_TRACE(QMetaObject_activate_begin_slot, receiver, method); - metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv); + metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv); Q_TRACE(QMetaObject_activate_end_slot, receiver, method); if (qt_signal_spy_callback_set.slot_end_callback != 0) From 52e0d9e23c3f7a1b0faf6649cf3dd825bcfd4f08 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Thu, 3 Jan 2019 20:33:57 +0100 Subject: [PATCH 0797/1650] Drag'n'Drop: fix dnd when dragMoveEvent() is not implemented The refactoring of dnd with f8944a7f07112c85dc4f66848cabb490514cd28e added a regression which results in a need to reimplement dragMoveEvent() on the drop side. Before this change it was possible to accept the dnd in dragEnterEvent() without again accepting it in dragMoveEvent(). Fix it in a similar way it's done in QGuiApplicationPrivate::processDrag() by prefilling the first simulated QDragMoveEvent with the values from the previous QDragEnterEvent before it is sent to the drop receiver. Fixes: QTBUG-72844 Change-Id: I1300dd02b7f1d9dcd44ecefa8335f92ad6c6cafa Reviewed-by: Gatis Paeglis --- src/widgets/kernel/qwidgetwindow.cpp | 7 ++-- .../qwidget_window/tst_qwidget_window.cpp | 36 ++++++++++++++++--- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 279c6c0282..991a05fa02 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -899,10 +899,10 @@ void QWidgetWindow::handleDragMoveEvent(QDragMoveEvent *event) const QPoint mapped = widget->mapFromGlobal(m_widget->mapToGlobal(event->pos())); QDragMoveEvent translated(mapped, event->possibleActions(), event->mimeData(), event->mouseButtons(), event->keyboardModifiers()); - translated.setDropAction(event->dropAction()); - translated.setAccepted(event->isAccepted()); if (widget == m_dragTarget) { // Target widget unchanged: Send DragMove + translated.setDropAction(event->dropAction()); + translated.setAccepted(event->isAccepted()); QGuiApplication::forwardEvent(m_dragTarget, &translated, event); } else { if (m_dragTarget) { // Send DragLeave to previous @@ -912,6 +912,9 @@ void QWidgetWindow::handleDragMoveEvent(QDragMoveEvent *event) } // Send DragEnter to new widget. handleDragEnterEvent(static_cast(event), widget); + // Handling 'DragEnter' should suffice for the application. + translated.setDropAction(event->dropAction()); + translated.setAccepted(event->isAccepted()); // The drag enter event is always immediately followed by a drag move event, // see QDragEnterEvent documentation. QGuiApplication::forwardEvent(m_dragTarget, &translated, event); diff --git a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp index f4da4c3e5f..431d6ba960 100644 --- a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp +++ b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp @@ -470,6 +470,10 @@ static const char *expectedLogC[] = { "Event at 11,241 accepted", "acceptingDropsWidget2::dropEvent at 1,51 action=1 MIME_DATA_ADDRESS 'testmimetext'", "Event at 11,261 accepted", + "acceptingDropsWidget3::dragEnterEvent at 1,21 action=1 MIME_DATA_ADDRESS 'testmimetext'", + "Event at 11,281 accepted", + "acceptingDropsWidget3::dragLeaveEvent QDragLeaveEvent", + "Event at 11,301 ignored", "acceptingDropsWidget1::dragEnterEvent at 10,10 action=1 MIME_DATA_ADDRESS 'testmimetext'", "Event at 0,0 accepted", "acceptingDropsWidget1::dragMoveEvent at 11,11 action=1 MIME_DATA_ADDRESS 'testmimetext'", @@ -482,8 +486,9 @@ static const char *expectedLogC[] = { class DnDEventLoggerWidget : public QWidget { public: - DnDEventLoggerWidget(QStringList *log, QWidget *w = 0) : QWidget(w), m_log(log) {} - + DnDEventLoggerWidget(QStringList *log, QWidget *w = nullptr, bool ignoreDragMove = false) + : QWidget(w), m_log(log), m_ignoreDragMove(ignoreDragMove) + {} protected: void dragEnterEvent(QDragEnterEvent *); void dragMoveEvent(QDragMoveEvent *); @@ -493,6 +498,7 @@ protected: private: void formatDropEvent(const char *function, const QDropEvent *e, QTextStream &str) const; QStringList *m_log; + bool m_ignoreDragMove; }; void DnDEventLoggerWidget::formatDropEvent(const char *function, const QDropEvent *e, QTextStream &str) const @@ -513,6 +519,8 @@ void DnDEventLoggerWidget::dragEnterEvent(QDragEnterEvent *e) void DnDEventLoggerWidget::dragMoveEvent(QDragMoveEvent *e) { + if (m_ignoreDragMove) + return; e->accept(); QString message; QTextStream str(&message); @@ -580,7 +588,17 @@ void tst_QWidget_window::tst_dnd() dropsRefusingWidget2->resize(160, 60); dropsRefusingWidget2->move(10, 10); + QWidget *dropsAcceptingWidget3 = new DnDEventLoggerWidget(&log, &dndTestWidget, true); + dropsAcceptingWidget3->setAcceptDrops(true); + dropsAcceptingWidget3->setObjectName(QLatin1String("acceptingDropsWidget3")); + // 260 + 40 = 300 = widget size, must not be more than that. + // otherwise it will break WinRT because there the tlw is maximized every time + // and this window will receive one more event + dropsAcceptingWidget3->resize(180, 40); + dropsAcceptingWidget3->move(10, 260); + dndTestWidget.show(); + QVERIFY(QTest::qWaitForWindowExposed(&dndTestWidget)); qApp->setActiveWindow(&dndTestWidget); QVERIFY(QTest::qWaitForWindowActive(&dndTestWidget)); @@ -595,16 +613,17 @@ void tst_QWidget_window::tst_dnd() log.push_back(msgEventAccepted(e)); while (true) { position.ry() += 20; - if (position.y() >= 250) { + if (position.y() >= 250 && position.y() < 270) { QDropEvent e(position, Qt::CopyAction, &mimeData, Qt::LeftButton, Qt::NoModifier); qApp->sendEvent(window, &e); log.push_back(msgEventAccepted(e)); - break; } else { QDragMoveEvent e(position, Qt::CopyAction, &mimeData, Qt::LeftButton, Qt::NoModifier); qApp->sendEvent(window, &e); log.push_back(msgEventAccepted(e)); } + if (position.y() > 290) + break; } window = nativeWidget->windowHandle(); @@ -628,6 +647,15 @@ void tst_QWidget_window::tst_dnd() for (int i= 0; i < expectedLogSize; ++i) expectedLog.push_back(QString::fromLatin1(expectedLogC[i]).replace(mimeDataAddressPlaceHolder, mimeDataAddress)); + if (log.size() != expectedLog.size()) { + for (int i = 0; i < log.size() && i < expectedLog.size(); ++i) + QCOMPARE(log.at(i), expectedLog.at(i)); + const int iMin = std::min(log.size(), expectedLog.size()); + for (int i = iMin; i < log.size(); ++i) + qDebug() << "log[" << i << "]:" << log.at(i); + for (int i = iMin; i < expectedLog.size(); ++i) + qDebug() << "exp[" << i << "]:" << log.at(i); + } QCOMPARE(log, expectedLog); } From da43362921a62ea3163a042be20ec0f550d05cfa Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Sat, 5 Jan 2019 21:31:54 +0200 Subject: [PATCH 0798/1650] Fix libs dir location on arm64 On Android arm64 the native libs are not in /data/app/../libs/... anymore but they are moved to some random location, so, trying to load the libs from old location will fail. Fixes: QTBUG-72616 Fixes: QTBUG-71027 Change-Id: I70263c8ae2d014999fbc78f40bd9b7d04d31d1dd Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../java/src/org/qtproject/qt5/android/bindings/QtLoader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java index 7826527918..ae9ccc09db 100644 --- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java +++ b/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java @@ -612,7 +612,7 @@ public abstract class QtLoader { } if (m_qtLibs != null) { - String libPrefix = apkDeployFromSystem ? libsDir + "lib" : localPrefix + "lib/lib"; + String libPrefix = libsDir + "lib"; for (int i = 0; i < m_qtLibs.length; i++) libraryList.add(libPrefix + m_qtLibs[i] + ".so"); } From 4f598ff06276433c24600b7afbdfc35564216e09 Mon Sep 17 00:00:00 2001 From: Mikhail Svetkin Date: Thu, 3 Jan 2019 09:56:18 +0100 Subject: [PATCH 0799/1650] Optimize allocation of QClipData::m_spans Calculate the size of m_spans before allocate them. Change-Id: Ie572f243d6c167f42e807701bf9bf76a3c6c0c69 Reviewed-by: Eirik Aavitsland Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qpaintengine_raster.cpp | 80 ++++++++++++------------ 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 650fffbd76..0f5c7756ad 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -3882,51 +3882,15 @@ void QClipData::initialize() Q_CHECK_PTR(m_clipLines); QT_TRY { - m_spans = (QSpan *)malloc(clipSpanHeight*sizeof(QSpan)); allocated = clipSpanHeight; - Q_CHECK_PTR(m_spans); - QT_TRY { - if (hasRectClip) { - int y = 0; - while (y < ymin) { - m_clipLines[y].spans = 0; - m_clipLines[y].count = 0; - ++y; - } - - const int len = clipRect.width(); - count = 0; - while (y < ymax) { - QSpan *span = m_spans + count; - span->x = xmin; - span->len = len; - span->y = y; - span->coverage = 255; - ++count; - - m_clipLines[y].spans = span; - m_clipLines[y].count = 1; - ++y; - } - - while (y < clipSpanHeight) { - m_clipLines[y].spans = 0; - m_clipLines[y].count = 0; - ++y; - } - } else if (hasRegionClip) { - + if (hasRegionClip) { const auto rects = clipRegion.begin(); const int numRects = clipRegion.rectCount(); - - { // resize - const int maxSpans = (ymax - ymin) * numRects; - if (maxSpans > allocated) { - m_spans = q_check_ptr((QSpan *)realloc(m_spans, maxSpans * sizeof(QSpan))); - allocated = maxSpans; - } - } + const int maxSpans = (ymax - ymin) * numRects; + allocated = qMax(allocated, maxSpans); + m_spans = (QSpan *)malloc(allocated * sizeof(QSpan)); + Q_CHECK_PTR(m_spans); int y = 0; int firstInBand = 0; @@ -3973,6 +3937,40 @@ void QClipData::initialize() ++y; } + return; + } + + m_spans = (QSpan *)malloc(allocated * sizeof(QSpan)); + Q_CHECK_PTR(m_spans); + + if (hasRectClip) { + int y = 0; + while (y < ymin) { + m_clipLines[y].spans = 0; + m_clipLines[y].count = 0; + ++y; + } + + const int len = clipRect.width(); + count = 0; + while (y < ymax) { + QSpan *span = m_spans + count; + span->x = xmin; + span->len = len; + span->y = y; + span->coverage = 255; + ++count; + + m_clipLines[y].spans = span; + m_clipLines[y].count = 1; + ++y; + } + + while (y < clipSpanHeight) { + m_clipLines[y].spans = 0; + m_clipLines[y].count = 0; + ++y; + } } } QT_CATCH(...) { free(m_spans); // have to free m_spans again or someone might think that we were successfully initialized. From bec817334705d86bc4e99af2e7220bb877f036d3 Mon Sep 17 00:00:00 2001 From: Mikhail Svetkin Date: Thu, 3 Jan 2019 15:57:37 +0100 Subject: [PATCH 0800/1650] QPainter: replace an QVector with QVarLengthArray We usually do not keep a lot of QPainter states, but we need to call 1 allocation and 1 reallocation for keep 4 states. It will be better to use QVarLengthArray with preallocation for 8 states. Change-Id: Iacb6aa7a73807491534b1a915453f218d6e4305b Reviewed-by: Eirik Aavitsland --- src/gui/painting/qpainter_p.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/painting/qpainter_p.h b/src/gui/painting/qpainter_p.h index 2d44577310..930180e9fa 100644 --- a/src/gui/painting/qpainter_p.h +++ b/src/gui/painting/qpainter_p.h @@ -51,6 +51,7 @@ // We mean it. // +#include #include #include "QtGui/qbrush.h" #include "QtGui/qfont.h" @@ -202,7 +203,7 @@ public: QPainterPrivate **d_ptrs; QPainterState *state; - QVector states; + QVarLengthArray states; mutable QPainterDummyState *dummyState; From 1f2c23a7ca1699b345578aeb52fbd97b612e079a Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 7 Dec 2018 12:00:48 +0100 Subject: [PATCH 0801/1650] Cleanup Widgets examples - foreach Cleanup the Widget examples - replace foreach with range-based for loop in subdirectory tools, touch and tutorials Change-Id: I008d23b5993a18a3332fe9f5e5bca68cb0561066 Reviewed-by: Luca Beldi Reviewed-by: Sze Howe Koh Reviewed-by: Paul Wicking --- examples/widgets/tools/codecs/mainwindow.cpp | 14 ++++---- examples/widgets/tools/codecs/previewform.cpp | 2 +- .../echoplugin/echowindow/echowindow.cpp | 3 +- .../widgets/tools/i18n/languagechooser.cpp | 8 ++--- .../tools/settingseditor/settingstree.cpp | 6 ++-- examples/widgets/touch/dials/main.cpp | 4 +-- .../widgets/touch/fingerpaint/mainwindow.cpp | 6 ++-- .../touch/fingerpaint/scribblearea.cpp | 6 ++-- examples/widgets/touch/pinchzoom/mouse.cpp | 2 +- .../tutorials/widgets/nestedlayouts/main.cpp | 35 ++++++++++--------- 10 files changed, 45 insertions(+), 41 deletions(-) diff --git a/examples/widgets/tools/codecs/mainwindow.cpp b/examples/widgets/tools/codecs/mainwindow.cpp index 229c2ccfd4..53db9fe61f 100644 --- a/examples/widgets/tools/codecs/mainwindow.cpp +++ b/examples/widgets/tools/codecs/mainwindow.cpp @@ -127,11 +127,10 @@ void MainWindow::about() void MainWindow::aboutToShowSaveAsMenu() { - QString currentText = textEdit->toPlainText(); - - foreach (QAction *action, saveAsActs) { - QByteArray codecName = action->data().toByteArray(); - QTextCodec *codec = QTextCodec::codecForName(codecName); + const QString currentText = textEdit->toPlainText(); + for (QAction *action : qAsConst(saveAsActs)) { + const QByteArray codecName = action->data().toByteArray(); + const QTextCodec *codec = QTextCodec::codecForName(codecName); action->setVisible(codec && codec->canEncode(currentText)); } } @@ -142,7 +141,8 @@ void MainWindow::findCodecs() QRegularExpression iso8859RegExp("^ISO[- ]8859-([0-9]+).*$"); QRegularExpressionMatch match; - foreach (int mib, QTextCodec::availableMibs()) { + const QList mibs = QTextCodec::availableMibs(); + for (int mib : mibs) { QTextCodec *codec = QTextCodec::codecForMib(mib); QString sortKey = codec->name().toUpper(); @@ -177,7 +177,7 @@ void MainWindow::createMenus() QMenu *saveAsMenu = fileMenu->addMenu(tr("&Save As")); connect(saveAsMenu, &QMenu::aboutToShow, this, &MainWindow::aboutToShowSaveAsMenu); - foreach (const QTextCodec *codec, codecs) { + for (const QTextCodec *codec : qAsConst(codecs)) { const QByteArray name = codec->name(); QAction *action = saveAsMenu->addAction(tr("%1...").arg(QLatin1String(name))); action->setData(QVariant(name)); diff --git a/examples/widgets/tools/codecs/previewform.cpp b/examples/widgets/tools/codecs/previewform.cpp index d19b9c0833..206b5757cd 100644 --- a/examples/widgets/tools/codecs/previewform.cpp +++ b/examples/widgets/tools/codecs/previewform.cpp @@ -182,7 +182,7 @@ PreviewForm::PreviewForm(QWidget *parent) void PreviewForm::setCodecList(const QList &list) { encodingComboBox->clear(); - foreach (const QTextCodec *codec, list) { + for (const QTextCodec *codec : list) { encodingComboBox->addItem(QLatin1String(codec->name()), QVariant(codec->mibEnum())); } diff --git a/examples/widgets/tools/echoplugin/echowindow/echowindow.cpp b/examples/widgets/tools/echoplugin/echowindow/echowindow.cpp index 64b59d506e..6886a4cd88 100644 --- a/examples/widgets/tools/echoplugin/echowindow/echowindow.cpp +++ b/examples/widgets/tools/echoplugin/echowindow/echowindow.cpp @@ -113,7 +113,8 @@ bool EchoWindow::loadPlugin() } #endif pluginsDir.cd("plugins"); - foreach (QString fileName, pluginsDir.entryList(QDir::Files)) { + const QStringList entries = pluginsDir.entryList(QDir::Files); + for (const QString &fileName : entries) { QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName)); QObject *plugin = pluginLoader.instance(); if (plugin) { diff --git a/examples/widgets/tools/i18n/languagechooser.cpp b/examples/widgets/tools/i18n/languagechooser.cpp index 58cf9d4047..f07d0ddee3 100644 --- a/examples/widgets/tools/i18n/languagechooser.cpp +++ b/examples/widgets/tools/i18n/languagechooser.cpp @@ -148,14 +148,14 @@ void LanguageChooser::checkBoxToggled() void LanguageChooser::showAll() { - foreach (QCheckBox *checkBox, qmFileForCheckBoxMap.keys()) - checkBox->setChecked(true); + for (auto it = qmFileForCheckBoxMap.keyBegin(); it != qmFileForCheckBoxMap.keyEnd(); ++it) + (*it)->setChecked(true); } void LanguageChooser::hideAll() { - foreach (QCheckBox *checkBox, qmFileForCheckBoxMap.keys()) - checkBox->setChecked(false); + for (auto it = qmFileForCheckBoxMap.keyBegin(); it != qmFileForCheckBoxMap.keyEnd(); ++it) + (*it)->setChecked(false); } QStringList LanguageChooser::findQmFiles() diff --git a/examples/widgets/tools/settingseditor/settingstree.cpp b/examples/widgets/tools/settingseditor/settingstree.cpp index 4ca843784e..8585792787 100644 --- a/examples/widgets/tools/settingseditor/settingstree.cpp +++ b/examples/widgets/tools/settingseditor/settingstree.cpp @@ -170,7 +170,8 @@ void SettingsTree::updateChildItems(QTreeWidgetItem *parent) { int dividerIndex = 0; - foreach (QString group, settings->childGroups()) { + const QStringList childGroups = settings->childGroups(); + for (const QString &group : childGroups) { QTreeWidgetItem *child; int childIndex = findChild(parent, group, dividerIndex); if (childIndex != -1) { @@ -190,7 +191,8 @@ void SettingsTree::updateChildItems(QTreeWidgetItem *parent) settings->endGroup(); } - foreach (const QString &key, settings->childKeys()) { + const QStringList childKeys = settings->childKeys(); + for (const QString &key : childKeys) { QTreeWidgetItem *child; int childIndex = findChild(parent, key, 0); diff --git a/examples/widgets/touch/dials/main.cpp b/examples/widgets/touch/dials/main.cpp index 071f485de3..059dfdc716 100644 --- a/examples/widgets/touch/dials/main.cpp +++ b/examples/widgets/touch/dials/main.cpp @@ -60,8 +60,8 @@ int main(int argc, char **argv) QWidget window; Ui::Dials dialsUi; dialsUi.setupUi(&window); - QList sliders = window.findChildren(); - foreach (QAbstractSlider *slider, sliders) + const QList sliders = window.findChildren(); + for (QAbstractSlider *slider : sliders) slider->setAttribute(Qt::WA_AcceptTouchEvents); window.showMaximized(); return app.exec(); diff --git a/examples/widgets/touch/fingerpaint/mainwindow.cpp b/examples/widgets/touch/fingerpaint/mainwindow.cpp index b0d91d25bf..2f7ec38d1a 100644 --- a/examples/widgets/touch/fingerpaint/mainwindow.cpp +++ b/examples/widgets/touch/fingerpaint/mainwindow.cpp @@ -129,7 +129,8 @@ void MainWindow::createActions() openAct->setShortcut(tr("Ctrl+O")); connect(openAct, &QAction::triggered, this, &MainWindow::open); - foreach (QByteArray format, QImageWriter::supportedImageFormats()) { + const QList imageFormats = QImageWriter::supportedImageFormats(); + for (const QByteArray &format : imageFormats) { QString text = tr("%1...").arg(QString(format).toUpper()); QAction *action = new QAction(text, this); @@ -163,8 +164,7 @@ void MainWindow::createMenus() //! [15] //! [16] { saveAsMenu = new QMenu(tr("&Save As"), this); - foreach (QAction *action, saveAsActs) - saveAsMenu->addAction(action); + saveAsMenu->addActions(saveAsActs); fileMenu = new QMenu(tr("&File"), this); fileMenu->addAction(openAct); diff --git a/examples/widgets/touch/fingerpaint/scribblearea.cpp b/examples/widgets/touch/fingerpaint/scribblearea.cpp index aa4e60c934..0b0c4476d9 100644 --- a/examples/widgets/touch/fingerpaint/scribblearea.cpp +++ b/examples/widgets/touch/fingerpaint/scribblearea.cpp @@ -195,9 +195,9 @@ bool ScribbleArea::event(QEvent *event) case QEvent::TouchUpdate: case QEvent::TouchEnd: { - QTouchEvent *touch = static_cast(event); - QList touchPoints = static_cast(event)->touchPoints(); - foreach (const QTouchEvent::TouchPoint &touchPoint, touchPoints) { + const QTouchEvent *touch = static_cast(event); + const QList touchPoints = static_cast(event)->touchPoints(); + for (const QTouchEvent::TouchPoint &touchPoint : touchPoints) { switch (touchPoint.state()) { case Qt::TouchPointStationary: case Qt::TouchPointReleased: diff --git a/examples/widgets/touch/pinchzoom/mouse.cpp b/examples/widgets/touch/pinchzoom/mouse.cpp index 1e6814be13..1dfd7d749c 100644 --- a/examples/widgets/touch/pinchzoom/mouse.cpp +++ b/examples/widgets/touch/pinchzoom/mouse.cpp @@ -163,7 +163,7 @@ void Mouse::timerEvent(QTimerEvent *) << mapToScene(0, 0) << mapToScene(-30, -50) << mapToScene(30, -50)); - foreach (QGraphicsItem *item, dangerMice) { + for (QGraphicsItem *item : dangerMice) { if (item == this) continue; diff --git a/examples/widgets/tutorials/widgets/nestedlayouts/main.cpp b/examples/widgets/tutorials/widgets/nestedlayouts/main.cpp index 9acc74b469..8880dbe3d0 100644 --- a/examples/widgets/tutorials/widgets/nestedlayouts/main.cpp +++ b/examples/widgets/tutorials/widgets/nestedlayouts/main.cpp @@ -76,25 +76,26 @@ int main(int argc, char *argv[]) //! [set up the model] QStandardItemModel model; - model.setHorizontalHeaderLabels( - QStringList() << QApplication::translate("nestedlayouts", "Name") - << QApplication::translate("nestedlayouts", "Office")); + model.setHorizontalHeaderLabels({ QApplication::translate("nestedlayouts", "Name"), + QApplication::translate("nestedlayouts", "Office") }); - QList rows = QList() - << (QStringList() << "Verne Nilsen" << "123") - << (QStringList() << "Carlos Tang" << "77") - << (QStringList() << "Bronwyn Hawcroft" << "119") - << (QStringList() << "Alessandro Hanssen" << "32") - << (QStringList() << "Andrew John Bakken" << "54") - << (QStringList() << "Vanessa Weatherley" << "85") - << (QStringList() << "Rebecca Dickens" << "17") - << (QStringList() << "David Bradley" << "42") - << (QStringList() << "Knut Walters" << "25") - << (QStringList() << "Andrea Jones" << "34"); + const QStringList rows[] = { + QStringList{ QStringLiteral("Verne Nilsen"), QStringLiteral("123") }, + QStringList{ QStringLiteral("Carlos Tang"), QStringLiteral("77") }, + QStringList{ QStringLiteral("Bronwyn Hawcroft"), QStringLiteral("119") }, + QStringList{ QStringLiteral("Alessandro Hanssen"), QStringLiteral("32") }, + QStringList{ QStringLiteral("Andrew John Bakken"), QStringLiteral("54") }, + QStringList{ QStringLiteral("Vanessa Weatherley"), QStringLiteral("85") }, + QStringList{ QStringLiteral("Rebecca Dickens"), QStringLiteral("17") }, + QStringList{ QStringLiteral("David Bradley"), QStringLiteral("42") }, + QStringList{ QStringLiteral("Knut Walters"), QStringLiteral("25") }, + QStringList{ QStringLiteral("Andrea Jones"), QStringLiteral("34") } + }; - foreach (QStringList row, rows) { - QList items; - foreach (QString text, row) + QList items; + for (const QStringList &row : rows) { + items.clear(); + for (const QString &text : row) items.append(new QStandardItem(text)); model.appendRow(items); } From 772f56c3cf54dc34dbaa3ae50570a006f9e7721a Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Mon, 7 Jan 2019 13:58:30 +0100 Subject: [PATCH 0802/1650] Fix warnings about uninitialized variables - qrgba64_p.h In function 'QRgba64 rgbBlend(QRgba64, QRgba64, uint)': error: 'blend.QRgba64::rgba' is used uninitialized in this function [-Werror=uninitialized] qrgba64_p.h:246:13: note: 'blend' was declared here QRgba64 blend; Change-Id: I7b263f863281c51c7d8099704f2cffcc7e1a07df Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qrgba64_p.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/painting/qrgba64_p.h b/src/gui/painting/qrgba64_p.h index b7e4d4d905..ca879de27c 100644 --- a/src/gui/painting/qrgba64_p.h +++ b/src/gui/painting/qrgba64_p.h @@ -266,10 +266,10 @@ inline QRgba64 rgbBlend(QRgba64 d, QRgba64 s, uint rgbAlpha) const int mr = qRed(rgbAlpha); const int mg = qGreen(rgbAlpha); const int mb = qBlue(rgbAlpha); - blend.setRed (qt_div_255(s.red() * mr + d.red() * (255 - mr))); - blend.setGreen(qt_div_255(s.green() * mg + d.green() * (255 - mg))); - blend.setBlue (qt_div_255(s.blue() * mb + d.blue() * (255 - mb))); - blend.setAlpha(s.alpha()); + blend = qRgba64(qt_div_255(s.red() * mr + d.red() * (255 - mr)), + qt_div_255(s.green() * mg + d.green() * (255 - mg)), + qt_div_255(s.blue() * mb + d.blue() * (255 - mb)), + s.alpha()); #endif return blend; } From 2cd633e7eef6f67ee7ed5f23afea7e0f23c7eb03 Mon Sep 17 00:00:00 2001 From: Max Mazurov Date: Wed, 2 Jan 2019 16:55:24 +0000 Subject: [PATCH 0803/1650] XCB: Use application name for X11 selection owner name This makes it possible for clipboard managers (or other scripts) to distinguish different Qt applications and act differently. Change-Id: I5bc5a1914b51127b24a81142ca9dbdb196ffd0d8 Fixes: QTBUG-72806 Reviewed-by: Gatis Paeglis --- src/plugins/platforms/xcb/qxcbconnection.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 37ee980924..29acf0e86d 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -39,6 +39,7 @@ #include #include +#include #include "qxcbconnection.h" #include "qxcbkeyboard.h" @@ -817,7 +818,7 @@ xcb_window_t QXcbConnection::getQtSelectionOwner() 0); // value list QXcbWindow::setWindowTitle(connection(), m_qtSelectionOwner, - QStringLiteral("Qt Selection Window")); + QLatin1String("Qt Selection Owner for ") + QCoreApplication::applicationName()); } return m_qtSelectionOwner; } From 5733dfbd90fd059e7310786faefb022b00289592 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 20 Dec 2018 16:30:51 +0100 Subject: [PATCH 0804/1650] qmake: make CONFIG+=egl work again while it's legacy and should not be used (use QMAKE_USE+=egl instead), it shouldn't be broken nonetheless. amends 310bf3f57c. Fixes: QTBUG-72564 Change-Id: Id6a070a4653dc1182a6b4d75af027a6ee6cbacae Reviewed-by: Joerg Bornemann Reviewed-by: Laszlo Agocs Reviewed-by: Rolf Eike Beer --- mkspecs/features/egl.prf | 1 + src/platformsupport/eglconvenience/qt_egl_p.h | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/mkspecs/features/egl.prf b/mkspecs/features/egl.prf index 9fa0c9e219..4577785576 100644 --- a/mkspecs/features/egl.prf +++ b/mkspecs/features/egl.prf @@ -2,6 +2,7 @@ INCLUDEPATH += $$QMAKE_INCDIR_EGL LIBS_PRIVATE += $$QMAKE_LIBS_EGL QMAKE_CFLAGS += $$QMAKE_CFLAGS_EGL QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_EGL +DEFINES += $$QMAKE_DEFINES_EGL LIBS += $$QMAKE_LFLAGS_EGL for(p, QMAKE_LIBDIR_EGL) { LIBS_PRIVATE += -L$$p diff --git a/src/platformsupport/eglconvenience/qt_egl_p.h b/src/platformsupport/eglconvenience/qt_egl_p.h index e2c6b0ceb6..ea554927de 100644 --- a/src/platformsupport/eglconvenience/qt_egl_p.h +++ b/src/platformsupport/eglconvenience/qt_egl_p.h @@ -52,7 +52,9 @@ // #ifdef QT_EGL_NO_X11 -# define MESA_EGL_NO_X11_HEADERS // MESA +# ifndef MESA_EGL_NO_X11_HEADERS +# define MESA_EGL_NO_X11_HEADERS // MESA +# endif # if !defined(Q_OS_INTEGRITY) # define WIN_INTERFACE_CUSTOM // NV # endif // Q_OS_INTEGRITY From 4e6a42cdd050c8714686fa53b3246c4fc66d18fd Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 12 Oct 2018 16:52:54 +0200 Subject: [PATCH 0805/1650] Optimize ARGB32->RGBA64PM better This conversion is critical for ARGB32 painting, and no compiler optimized the premultiplication efficiently. Change-Id: Iee137c2f7020246478d09e880a7a1bf2ed3c6fd4 Reviewed-by: Thiago Macieira --- src/gui/painting/qdrawhelper.cpp | 48 ++++++++------ src/gui/painting/qdrawhelper_neon.cpp | 94 +++++++++++++++++++++++++++ src/gui/painting/qdrawhelper_sse4.cpp | 77 ++++++++++++++++++++++ 3 files changed, 199 insertions(+), 20 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index af9375fcec..cdf5826672 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -1086,18 +1086,8 @@ static const QRgba64 *QT_FASTCALL fetchRGB32ToRGB64(QRgba64 *buffer, const uchar static const QRgba64 *QT_FASTCALL convertARGB32ToRGBA64PM(QRgba64 *buffer, const uint *src, int count, const QVector *, QDitherInfo *) { -#ifdef __SSE2__ - qConvertARGB32PMToRGBA64PM_sse2(buffer, src, count); - for (int i = 0; i < count; ++i) - buffer[i] = buffer[i].premultiplied(); -#elif defined(__ARM_NEON__) - qConvertARGB32PMToRGBA64PM_neon(buffer, src, count); - for (int i = 0; i < count; ++i) - buffer[i] = buffer[i].premultiplied(); -#else for (int i = 0; i < count; ++i) buffer[i] = QRgba64::fromArgb32(src[i]).premultiplied(); -#endif return buffer; } @@ -1149,18 +1139,8 @@ static const QRgba64 *QT_FASTCALL fetchRGBA64ToRGBA64PM(QRgba64 *buffer, const u static const QRgba64 *QT_FASTCALL convertRGBA8888ToRGBA64PM(QRgba64 *buffer, const uint *src, int count, const QVector *, QDitherInfo *) { -#ifdef __SSE2__ - qConvertARGB32PMToRGBA64PM_sse2(buffer, src, count); - for (int i = 0; i < count; ++i) - buffer[i] = buffer[i].premultiplied(); -#elif defined(__ARM_NEON__) - qConvertARGB32PMToRGBA64PM_neon(buffer, src, count); - for (int i = 0; i < count; ++i) - buffer[i] = buffer[i].premultiplied(); -#else for (int i = 0; i < count; ++i) buffer[i] = QRgba64::fromArgb32(RGBA2ARGB(src[i])).premultiplied(); -#endif return buffer; } @@ -6514,6 +6494,14 @@ static void qInitDrawhelperFunctions() const QVector *, QDitherInfo *); extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_sse4(uint *buffer, const uchar *src, int index, int count, const QVector *, QDitherInfo *); + extern const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_sse4(QRgba64 *buffer, const uint *src, int count, + const QVector *, QDitherInfo *); + extern const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_sse4(QRgba64 *buffer, const uint *src, int count, + const QVector *, QDitherInfo *); + extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_sse4(QRgba64 *buffer, const uchar *src, int index, int count, + const QVector *, QDitherInfo *); + extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_sse4(QRgba64 *buffer, const uchar *src, int index, int count, + const QVector *, QDitherInfo *); extern void QT_FASTCALL storeARGB32FromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count, const QVector *, QDitherInfo *); extern void QT_FASTCALL storeRGBA8888FromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count, @@ -6530,8 +6518,14 @@ static void qInitDrawhelperFunctions() qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_sse4; qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_sse4; qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_sse4; + qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_sse4; + qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_sse4; qPixelLayouts[QImage::Format_ARGB32].storeFromARGB32PM = storeARGB32FromARGB32PM_sse4; + qPixelLayouts[QImage::Format_RGBA8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_sse4; + qPixelLayouts[QImage::Format_RGBA8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_sse4; qPixelLayouts[QImage::Format_RGBA8888].storeFromARGB32PM = storeRGBA8888FromARGB32PM_sse4; + qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_sse4; + qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_sse4; qPixelLayouts[QImage::Format_RGBX8888].storeFromARGB32PM = storeRGBXFromARGB32PM_sse4; qPixelLayouts[QImage::Format_A2BGR30_Premultiplied].storeFromARGB32PM = storeA2RGB30PMFromARGB32PM_sse4; qPixelLayouts[QImage::Format_A2RGB30_Premultiplied].storeFromARGB32PM = storeA2RGB30PMFromARGB32PM_sse4; @@ -6620,6 +6614,14 @@ static void qInitDrawhelperFunctions() const QVector *, QDitherInfo *); extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_neon(uint *buffer, const uchar *src, int index, int count, const QVector *, QDitherInfo *); + extern const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_neon(QRgba64 *buffer, const uint *src, int count, + const QVector *, QDitherInfo *); + extern const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_neon(QRgba64 *buffer, const uint *src, int count, + const QVector *, QDitherInfo *); + extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_neon(QRgba64 *buffer, const uchar *src, int index, int count, + const QVector *, QDitherInfo *); + extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_neon(QRgba64 *buffer, const uchar *src, int index, int count, + const QVector *, QDitherInfo *); extern void QT_FASTCALL storeARGB32FromARGB32PM_neon(uchar *dest, const uint *src, int index, int count, const QVector *, QDitherInfo *); extern void QT_FASTCALL storeRGBA8888FromARGB32PM_neon(uchar *dest, const uint *src, int index, int count, @@ -6629,10 +6631,16 @@ static void qInitDrawhelperFunctions() qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_neon; qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_neon; qPixelLayouts[QImage::Format_ARGB32].storeFromARGB32PM = storeARGB32FromARGB32PM_neon; + qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_neon; + qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_neon; qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_neon; qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_neon; qPixelLayouts[QImage::Format_RGBA8888].storeFromARGB32PM = storeRGBA8888FromARGB32PM_neon; + qPixelLayouts[QImage::Format_RGBA8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_neon; + qPixelLayouts[QImage::Format_RGBA8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_neon; qPixelLayouts[QImage::Format_RGBX8888].storeFromARGB32PM = storeRGBXFromARGB32PM_neon; + qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_neon; + qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_neon; #endif #if defined(ENABLE_PIXMAN_DRAWHELPERS) diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp index e33af3b784..3fcbcfd053 100644 --- a/src/gui/painting/qdrawhelper_neon.cpp +++ b/src/gui/painting/qdrawhelper_neon.cpp @@ -1149,6 +1149,72 @@ static inline void convertARGBToARGB32PM_neon(uint *buffer, const uint *src, int } } +template +static inline void convertARGB32ToRGBA64PM_neon(QRgba64 *buffer, const uint *src, int count) +{ + if (count <= 0) + return; + + const uint8x8_t shuffleMask = { 3, 3, 3, 3, 7, 7, 7, 7}; + const uint64x2_t blendMask = vdupq_n_u64(Q_UINT64_C(0xffff000000000000)); + + int i = 0; + for (; i < count-3; i += 4) { + uint32x4_t vs32 = vld1q_u32(src + i); + uint32x4_t alphaVector = vshrq_n_u32(vs32, 24); +#if defined(Q_PROCESSOR_ARM_64) + uint32_t alphaSum = vaddvq_u32(alphaVector); +#else + // no vaddvq_u32 + uint32x2_t tmp = vpadd_u32(vget_low_u32(alphaVector), vget_high_u32(alphaVector)); + uint32_t alphaSum = vget_lane_u32(vpadd_u32(tmp, tmp), 0); +#endif + if (alphaSum) { + if (!RGBA) + vs32 = vrgba2argb(vs32); + const uint8x16_t vs8 = vreinterpretq_u8_u32(vs32); + const uint8x16x2_t v = vzipq_u8(vs8, vs8); + if (alphaSum != 255 * 4) { + const uint8x8_t s1 = vreinterpret_u8_u32(vget_low_u32(vs32)); + const uint8x8_t s2 = vreinterpret_u8_u32(vget_high_u32(vs32)); + const uint8x8_t alpha1 = vtbl1_u8(s1, shuffleMask); + const uint8x8_t alpha2 = vtbl1_u8(s2, shuffleMask); + uint16x8_t src1 = vmull_u8(s1, alpha1); + uint16x8_t src2 = vmull_u8(s2, alpha2); + // convert from 0->(255x255) to 0->(255x257) + src1 = vsraq_n_u16(src1, src1, 7); + src2 = vsraq_n_u16(src2, src2, 7); + + // now restore alpha from the trivial conversion + const uint64x2_t d1 = vbslq_u64(blendMask, vreinterpretq_u64_u8(v.val[0]), vreinterpretq_u64_u16(src1)); + const uint64x2_t d2 = vbslq_u64(blendMask, vreinterpretq_u64_u8(v.val[1]), vreinterpretq_u64_u16(src2)); + + vst1q_u16((uint16_t *)buffer, vreinterpretq_u16_u64(d1)); + buffer += 2; + vst1q_u16((uint16_t *)buffer, vreinterpretq_u16_u64(d2)); + buffer += 2; + } else { + vst1q_u16((uint16_t *)buffer, vreinterpretq_u16_u8(v.val[0])); + buffer += 2; + vst1q_u16((uint16_t *)buffer, vreinterpretq_u16_u8(v.val[1])); + buffer += 2; + } + } else { + vst1q_u16((uint16_t *)buffer, vdupq_n_u16(0)); + buffer += 2; + vst1q_u16((uint16_t *)buffer, vdupq_n_u16(0)); + buffer += 2; + } + } + + SIMD_EPILOGUE(i, count, 3) { + uint s = src[i]; + if (RGBA) + s = RGBA2ARGB(s); + *buffer++ = QRgba64::fromArgb32(s).premultiplied(); + } +} + static inline float32x4_t reciprocal_mul_ps(float32x4_t a, float mul) { float32x4_t ia = vrecpeq_f32(a); // estimate 1/a @@ -1258,6 +1324,34 @@ const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_neon(uint *buffer, const uchar * return buffer; } +const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_neon(QRgba64 *buffer, const uint *src, int count, + const QVector *, QDitherInfo *) +{ + convertARGB32ToRGBA64PM_neon(buffer, src, count); + return buffer; +} + +const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_neon(QRgba64 *buffer, const uint *src, int count, + const QVector *, QDitherInfo *) +{ + convertARGB32ToRGBA64PM_neon(buffer, src, count); + return buffer; +} + +const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_neon(QRgba64 *buffer, const uchar *src, int index, int count, + const QVector *, QDitherInfo *) +{ + convertARGB32ToRGBA64PM_neon(buffer, reinterpret_cast(src) + index, count); + return buffer; +} + +const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_neon(QRgba64 *buffer, const uchar *src, int index, int count, + const QVector *, QDitherInfo *) +{ + convertARGB32ToRGBA64PM_neon(buffer, reinterpret_cast(src) + index, count); + return buffer; +} + void QT_FASTCALL storeRGB32FromARGB32PM_neon(uchar *dest, const uint *src, int index, int count, const QVector *, QDitherInfo *) { diff --git a/src/gui/painting/qdrawhelper_sse4.cpp b/src/gui/painting/qdrawhelper_sse4.cpp index 06bfd3465e..9e3e6682bb 100644 --- a/src/gui/painting/qdrawhelper_sse4.cpp +++ b/src/gui/painting/qdrawhelper_sse4.cpp @@ -94,6 +94,55 @@ static void convertARGBToARGB32PM_sse4(uint *buffer, const uint *src, int count) } } +template +static void convertARGBToRGBA64PM_sse4(QRgba64 *buffer, const uint *src, int count) +{ + int i = 0; + const __m128i alphaMask = _mm_set1_epi32(0xff000000); + const __m128i rgbaMask = _mm_setr_epi8(2, 1, 0, 3, 6, 5, 4, 7, 10, 9, 8, 11, 14, 13, 12, 15); + const __m128i shuffleMask = _mm_setr_epi8(6, 7, 6, 7, 6, 7, 6, 7, 14, 15, 14, 15, 14, 15, 14, 15); + const __m128i zero = _mm_setzero_si128(); + + for (; i < count - 3; i += 4) { + __m128i srcVector = _mm_loadu_si128((const __m128i *)&src[i]); + if (!_mm_testz_si128(srcVector, alphaMask)) { + if (!_mm_testc_si128(srcVector, alphaMask)) { + if (!RGBA) + srcVector = _mm_shuffle_epi8(srcVector, rgbaMask); + __m128i src1 = _mm_unpacklo_epi8(srcVector, zero); + __m128i src2 = _mm_unpackhi_epi8(srcVector, zero); + __m128i alpha1 = _mm_shuffle_epi8(src1, shuffleMask); + __m128i alpha2 = _mm_shuffle_epi8(src2, shuffleMask); + src1 = _mm_mullo_epi16(src1, alpha1); + src2 = _mm_mullo_epi16(src2, alpha2); + alpha1 = _mm_unpacklo_epi8(srcVector, srcVector); + alpha2 = _mm_unpackhi_epi8(srcVector, srcVector); + src1 = _mm_add_epi16(src1, _mm_srli_epi16(src1, 7)); + src2 = _mm_add_epi16(src2, _mm_srli_epi16(src2, 7)); + src1 = _mm_blend_epi16(src1, alpha1, 0x88); + src2 = _mm_blend_epi16(src2, alpha2, 0x88); + _mm_storeu_si128((__m128i *)&buffer[i], src1); + _mm_storeu_si128((__m128i *)&buffer[i + 2], src2); + } else { + if (!RGBA) + srcVector = _mm_shuffle_epi8(srcVector, rgbaMask); + const __m128i src1 = _mm_unpacklo_epi8(srcVector, srcVector); + const __m128i src2 = _mm_unpackhi_epi8(srcVector, srcVector); + _mm_storeu_si128((__m128i *)&buffer[i], src1); + _mm_storeu_si128((__m128i *)&buffer[i + 2], src2); + } + } else { + _mm_storeu_si128((__m128i *)&buffer[i], zero); + _mm_storeu_si128((__m128i *)&buffer[i + 2], zero); + } + } + + SIMD_EPILOGUE(i, count, 3) { + const uint s = RGBA ? RGBA2ARGB(src[i]) : src[i]; + buffer[i] = QRgba64::fromArgb32(s).premultiplied(); + } +} + static inline __m128 Q_DECL_VECTORCALL reciprocal_mul_ps(__m128 a, float mul) { __m128 ia = _mm_rcp_ps(a); // Approximate 1/a @@ -269,6 +318,20 @@ void QT_FASTCALL convertRGBA8888ToARGB32PM_sse4(uint *buffer, int count, const Q convertARGBToARGB32PM_sse4(buffer, buffer, count); } +const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_sse4(QRgba64 *buffer, const uint *src, int count, + const QVector *, QDitherInfo *) +{ + convertARGBToRGBA64PM_sse4(buffer, src, count); + return buffer; +} + +const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_sse4(QRgba64 *buffer, const uint *src, int count, + const QVector *, QDitherInfo *) +{ + convertARGBToRGBA64PM_sse4(buffer, src, count); + return buffer; +} + const uint *QT_FASTCALL fetchARGB32ToARGB32PM_sse4(uint *buffer, const uchar *src, int index, int count, const QVector *, QDitherInfo *) { @@ -283,6 +346,20 @@ const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_sse4(uint *buffer, const uchar * return buffer; } +const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_sse4(QRgba64 *buffer, const uchar *src, int index, int count, + const QVector *, QDitherInfo *) +{ + convertARGBToRGBA64PM_sse4(buffer, reinterpret_cast(src) + index, count); + return buffer; +} + +const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_sse4(QRgba64 *buffer, const uchar *src, int index, int count, + const QVector *, QDitherInfo *) +{ + convertARGBToRGBA64PM_sse4(buffer, reinterpret_cast(src) + index, count); + return buffer; +} + void QT_FASTCALL storeRGB32FromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count, const QVector *, QDitherInfo *) { From e6a7b61d273c2985dee63df34e5941ee90754e2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Micha=C3=ABl=20Celerier?= Date: Sun, 9 Jul 2017 19:27:35 +0200 Subject: [PATCH 0806/1650] Add clear, reserve and capacity methods to QPainterPath This allows anticipating and reusing internal allocations of QPainterPathElements instead of using the common `m_myPath = QPainterPath{}` pattern. [ChangeLog][QtGui][QPainterPath] Added clear(), reserve(), capacity(). clear() removes allocated QPainterPath elements but preserves allocated memory, which can be useful for application with complex paths that are often recreated. reserve() and capacity() follow QVector semantics. Change-Id: I763461e2a421feda9053d3eb512af2fcf07ade2b Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qpainterpath.cpp | 67 +++++++++++++++++-- src/gui/painting/qpainterpath.h | 5 ++ src/gui/painting/qpainterpath_p.h | 20 ++++++ .../qpainterpath/tst_qpainterpath.cpp | 43 ++++++++++++ 4 files changed, 129 insertions(+), 6 deletions(-) diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp index c5ccf0003d..3687bcf7d0 100644 --- a/src/gui/painting/qpainterpath.cpp +++ b/src/gui/painting/qpainterpath.cpp @@ -628,6 +628,55 @@ QPainterPath::~QPainterPath() { } +/*! + Clears the path elements stored. + + This allows the path to reuse previous memory allocations. + + \sa reserve(), capacity() + \since 5.13 +*/ +void QPainterPath::clear() +{ + if (!d_ptr) + return; + + detach(); + d_func()->clear(); +} + +/*! + Reserves a given amount of elements in QPainterPath's internal memory. + + Attempts to allocate memory for at least \a size elements. + + \sa clear(), capacity(), QVector::reserve() + \since 5.13 +*/ +void QPainterPath::reserve(int size) +{ + Q_D(QPainterPath); + if ((!d && size > 0) || (d && d->elements.capacity() < size)) { + detach(); + d->elements.reserve(size); + } +} + +/*! + Returns the number of elements allocated by the QPainterPath. + + \sa clear(), reserve() + \since 5.13 +*/ +int QPainterPath::capacity() const +{ + Q_D(QPainterPath); + if (d) + return d->elements.capacity(); + + return 0; +} + /*! Closes the current subpath by drawing a line to the beginning of the subpath, automatically starting a new path. The current point @@ -2271,13 +2320,19 @@ static inline bool epsilonCompare(const QPointF &a, const QPointF &b, const QSiz bool QPainterPath::operator==(const QPainterPath &path) const { QPainterPathData *d = reinterpret_cast(d_func()); - if (path.d_func() == d) + QPainterPathData *other_d = path.d_func(); + if (other_d == d) return true; - else if (!d || !path.d_func()) + else if (!d || !other_d) { + if (!d && other_d->elements.empty() && other_d->fillRule == Qt::OddEvenFill) + return true; + if (!other_d && d && d->elements.empty() && d->fillRule == Qt::OddEvenFill) + return true; return false; - else if (d->fillRule != path.d_func()->fillRule) + } + else if (d->fillRule != other_d->fillRule) return false; - else if (d->elements.size() != path.d_func()->elements.size()) + else if (d->elements.size() != other_d->elements.size()) return false; const qreal qt_epsilon = sizeof(qreal) == sizeof(double) ? 1e-12 : qreal(1e-5); @@ -2287,8 +2342,8 @@ bool QPainterPath::operator==(const QPainterPath &path) const epsilon.rheight() *= qt_epsilon; for (int i = 0; i < d->elements.size(); ++i) - if (d->elements.at(i).type != path.d_func()->elements.at(i).type - || !epsilonCompare(d->elements.at(i), path.d_func()->elements.at(i), epsilon)) + if (d->elements.at(i).type != other_d->elements.at(i).type + || !epsilonCompare(d->elements.at(i), other_d->elements.at(i), epsilon)) return false; return true; diff --git a/src/gui/painting/qpainterpath.h b/src/gui/painting/qpainterpath.h index db39c1c5a0..770b8f48d0 100644 --- a/src/gui/painting/qpainterpath.h +++ b/src/gui/painting/qpainterpath.h @@ -97,8 +97,13 @@ public: { qSwap(d_ptr, other.d_ptr); return *this; } #endif ~QPainterPath(); + inline void swap(QPainterPath &other) Q_DECL_NOEXCEPT { d_ptr.swap(other.d_ptr); } + void clear(); + void reserve(int size); + int capacity() const; + void closeSubpath(); void moveTo(const QPointF &p); diff --git a/src/gui/painting/qpainterpath_p.h b/src/gui/painting/qpainterpath_p.h index aab318bcab..a36c8005bc 100644 --- a/src/gui/painting/qpainterpath_p.h +++ b/src/gui/painting/qpainterpath_p.h @@ -194,6 +194,7 @@ public: inline bool isClosed() const; inline void close(); inline void maybeMoveTo(); + inline void clear(); const QVectorPath &vectorPath() { if (!pathConverter) @@ -290,6 +291,25 @@ inline void QPainterPathData::maybeMoveTo() } } +inline void QPainterPathData::clear() +{ + Q_ASSERT(ref.load() == 1); + + elements.clear(); + + cStart = 0; + + bounds = {}; + controlBounds = {}; + + require_moveTo = false; + dirtyBounds = false; + dirtyControlBounds = false; + convex = false; + + delete pathConverter; + pathConverter = nullptr; +} #define KAPPA qreal(0.5522847498) diff --git a/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp b/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp index 16215714f3..69c961c1a1 100644 --- a/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp +++ b/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp @@ -43,6 +43,8 @@ public slots: void cleanupTestCase(); private slots: void getSetCheck(); + void clear(); + void reserveAndCapacity(); void swap(); void contains_QPointF_data(); @@ -148,6 +150,47 @@ void tst_QPainterPath::swap() QCOMPARE(p2.boundingRect().toRect(), QRect( 0, 0,10,10)); } +void tst_QPainterPath::clear() +{ + QPainterPath p1; + QPainterPath p2; + p1.clear(); + QCOMPARE(p1, p2); + + p1.addRect(0, 0, 10, 10); + p1.clear(); + QCOMPARE(p1, p2); + + QCOMPARE(p1.fillRule(), Qt::OddEvenFill); + p1.setFillRule(Qt::WindingFill); + p1.clear(); + QCOMPARE(p1.fillRule(), Qt::WindingFill); +} + +void tst_QPainterPath::reserveAndCapacity() +{ + QPainterPath p; + QVERIFY(p.capacity() == 0); + + p.addRect(0, 0, 10, 10); + QVERIFY(p.capacity() > 0); + + p.clear(); + QVERIFY(p.capacity() > 0); + + p = QPainterPath{}; + QVERIFY(p.capacity() == 0); + + p.moveTo(100, 100); + QVERIFY(p.capacity() > 1); + + p.reserve(1000); + QVERIFY(p.capacity() >= 1000); + + p.reserve(0); + QVERIFY(p.capacity() >= 1000); +} + Q_DECLARE_METATYPE(QPainterPath) void tst_QPainterPath::currentPosition() From 2327944d241f48495a7b867b8e206a4c8c5d52e3 Mon Sep 17 00:00:00 2001 From: Samuli Piippo Date: Mon, 7 Jan 2019 10:29:53 +0200 Subject: [PATCH 0807/1650] qmake: use default libdirs to search for prl libs Default libdirs are never added to the modules' LIBS and if Qt was configured to use one of the default libdirs, module might end up without any path to search for its prl files. Add default libdirs to the search path similar as it's done in unix/makefile generator. Fixes: QTBUG-72855 Change-Id: I43c5bae0d54ba9427ab0ad3eab61ba0c4e2cbde8 Reviewed-by: Joerg Bornemann --- qmake/generators/win32/winmakefile.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp index 91215c94b1..6046e5791e 100644 --- a/qmake/generators/win32/winmakefile.cpp +++ b/qmake/generators/win32/winmakefile.cpp @@ -84,6 +84,8 @@ Win32MakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags) if (impexts.isEmpty()) impexts = project->values("QMAKE_EXTENSION_STATICLIB"); QList dirs; + for (const ProString &dlib : project->values("QMAKE_DEFAULT_LIBDIRS")) + dirs.append(QMakeLocalFileName(dlib.toQString())); static const char * const lflags[] = { "LIBS", "LIBS_PRIVATE", "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", nullptr }; for (int i = 0; lflags[i]; i++) { From 56e92dfdf255231aff0034d2e197fd096da7f0c0 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 7 Jan 2019 13:41:10 +0100 Subject: [PATCH 0808/1650] QSplashScreen: Fix positioning in multimonitor setups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, QSplashScreen::setPixmap() used QDesktopWidgetPrivate::screenGeometry().center() to determine the screen position, which would always result in the primary screen being used. That is counter to the documentation of QSplashScreen(QWidget *, QPixmap), which states that a desktop screen widget can be passed as parent to set the screen. To fix that and make it easier to work with QScreen (which is the likely outcome of QTBUG-62094), extract the setPixmap() to QSplashScreenPrivate with an additional QScreen * parameter and add a helper to determine it. Do not set a position in case no parent was passed so that QPlatformWindow::initialGeometry() triggers, centering it over the cursor. Fixes: QTBUG-72819 Task-number: QTBUG-62094 Change-Id: Ic38cfecd24c3ff6b82dff37702b627c5a50a3e1d Reviewed-by: Tor Arne Vestbø --- src/widgets/widgets/qsplashscreen.cpp | 57 ++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 10 deletions(-) diff --git a/src/widgets/widgets/qsplashscreen.cpp b/src/widgets/widgets/qsplashscreen.cpp index 277d2fd99f..4af4f90119 100644 --- a/src/widgets/widgets/qsplashscreen.cpp +++ b/src/widgets/widgets/qsplashscreen.cpp @@ -46,6 +46,7 @@ #include "qpixmap.h" #include "qtextdocument.h" #include "qtextcursor.h" +#include #include #include #include @@ -69,6 +70,10 @@ public: int currAlign; inline QSplashScreenPrivate(); + + void setPixmap(const QPixmap &p, const QScreen *screen = nullptr); + + static const QScreen *screenFor(const QWidget *w); }; /*! @@ -143,8 +148,9 @@ QSplashScreen::QSplashScreen(const QPixmap &pixmap, Qt::WindowFlags f) QSplashScreen::QSplashScreen(QWidget *parent, const QPixmap &pixmap, Qt::WindowFlags f) : QWidget(*new QSplashScreenPrivate, parent, Qt::SplashScreen | Qt::FramelessWindowHint | f) { - d_func()->pixmap = pixmap; - setPixmap(d_func()->pixmap); // Does an implicit repaint + // Does an implicit repaint. Explicitly pass parent as QObject::parent() + // is still 0 here due to QWidget's special handling. + d_func()->setPixmap(pixmap, QSplashScreenPrivate::screenFor(parent)); } /*! @@ -276,16 +282,47 @@ void QSplashScreen::finish(QWidget *mainWin) */ void QSplashScreen::setPixmap(const QPixmap &pixmap) { - Q_D(QSplashScreen); + d_func()->setPixmap(pixmap, QSplashScreenPrivate::screenFor(this)); +} - d->pixmap = pixmap; - setAttribute(Qt::WA_TranslucentBackground, pixmap.hasAlpha()); +// In setPixmap(), resize and try to position on a screen according to: +// 1) If a QDesktopScreenWidget is found in the parent hierarchy, use that (see docs on +// QSplashScreen(QWidget *, QPixmap). +// 2) If a widget with associated QWindow is found, use that +// 3) When nothing can be found, do not position the widget, allowing for +// QPlatformWindow::initialGeometry() to center it over the cursor - QRect r(QPoint(), d->pixmap.size() / d->pixmap.devicePixelRatio()); - resize(r.size()); - move(QDesktopWidgetPrivate::screenGeometry().center() - r.center()); - if (isVisible()) - repaint(); +static inline int screenNumberOf(const QDesktopScreenWidget *dsw) +{ + auto desktopWidgetPrivate = + static_cast(qt_widget_private(QApplication::desktop())); + return desktopWidgetPrivate->screens.indexOf(const_cast(dsw)); +} + +const QScreen *QSplashScreenPrivate::screenFor(const QWidget *w) +{ + for (const QWidget *p = w; p !=nullptr ; p = p->parentWidget()) { + if (auto dsw = qobject_cast(p)) + return QGuiApplication::screens().value(screenNumberOf(dsw)); + if (QWindow *window = p->windowHandle()) + return window->screen(); + } + return nullptr; +} + +void QSplashScreenPrivate::setPixmap(const QPixmap &p, const QScreen *screen) +{ + Q_Q(QSplashScreen); + + pixmap = p; + q->setAttribute(Qt::WA_TranslucentBackground, pixmap.hasAlpha()); + + QRect r(QPoint(), pixmap.size() / pixmap.devicePixelRatio()); + q->resize(r.size()); + if (screen) + q->move(screen->geometry().center() - r.center()); + if (q->isVisible()) + q->repaint(); } /*! From 78b422c3415d99713cac98137a9ebad6571eb937 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Wed, 2 Jan 2019 13:11:47 +0100 Subject: [PATCH 0809/1650] QNetworkReplyHttpImpl::_q_startOperation - remove a useless warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since it explains nothing and now, after some other bug was fixed (see, for example, c89d0f9d532), we trigger this message on the first request, which happens because: - 'createSession()' indeed, creates a session, compares a previous kwnon state (which happens to be 'Invalid') with a current state, which is 'Connected' and then invokes '_q_networkSessionStateChanged'. - '_q_networkSessionStateChanged()' on 'Connected' emits 'networkSessionConnected()' to which a newly-created QNetworkReplyHttpImpl will respond with it's _q_startOperation(). - QHttpNetworkReplyImpl will also try to 'open' a session, its 'opened()' signal will trigger, again, 'networkSessionConnected()' and ... the next _q_startOperation(). Now, not to add even more twisted spaghetti if/conditions with some unpredictable regressions, let's suppress a useless warning and silently return. We, indeed, in 'Working' state, let's keep working. Task-number: QTBUG-72463 Change-Id: I5282979920915ffded889c20b8ae740a46efef04 Reviewed-by: Mårten Nordheim --- src/network/access/qnetworkreplyhttpimpl.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index ed2235ad28..ef54c198ba 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -1879,11 +1879,9 @@ void QNetworkReplyHttpImplPrivate::_q_startOperation() { Q_Q(QNetworkReplyHttpImpl); - // ensure this function is only being called once - if (state == Working) { - qDebug() << "QNetworkReplyHttpImplPrivate::_q_startOperation was called more than once" << url; + if (state == Working) // ensure this function is only being called once return; - } + state = Working; #ifndef QT_NO_BEARERMANAGEMENT From 98552a84cec7459db1ff41d1cebadcec9ee93849 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Tue, 18 Dec 2018 15:13:42 +0100 Subject: [PATCH 0810/1650] Emit paletteChanged and send ApplicationPaletteChange on theme change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: QTBUG-72575 Change-Id: I407e081295a456a7bdd36de91ca5bbf74bba6078 Reviewed-by: Tor Arne Vestbø --- src/gui/kernel/qguiapplication.cpp | 12 ++++++++++ src/gui/kernel/qguiapplication_p.h | 1 + src/widgets/kernel/qapplication.cpp | 36 ++++++++++++++--------------- src/widgets/kernel/qapplication_p.h | 3 +++ 4 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index f4e2dda05a..a63e172461 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -3983,6 +3983,9 @@ void QGuiApplicationPrivate::notifyThemeChanged() !QCoreApplication::testAttribute(Qt::AA_SetPalette)) { clearPalette(); initPalette(); + emit qGuiApp->paletteChanged(*app_pal); + if (is_app_running && !is_app_closing) + sendApplicationPaletteChange(); } if (!(applicationResourceFlags & ApplicationFontExplicitlySet)) { QMutexLocker locker(&applicationFontMutex); @@ -3991,6 +3994,15 @@ void QGuiApplicationPrivate::notifyThemeChanged() } } +void QGuiApplicationPrivate::sendApplicationPaletteChange(bool toAllWidgets, const char *className) +{ + Q_UNUSED(toAllWidgets) + Q_UNUSED(className) + + QEvent event(QEvent::ApplicationPaletteChange); + QGuiApplication::sendEvent(QGuiApplication::instance(), &event); +} + #if QT_CONFIG(draganddrop) void QGuiApplicationPrivate::notifyDragStarted(const QDrag *drag) { diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index 79c1a1c820..042a36c31f 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -313,6 +313,7 @@ public: protected: virtual void notifyThemeChanged(); + virtual void sendApplicationPaletteChange(bool toAllWidgets = false, const char *className = nullptr); bool tryCloseRemainingWindows(QWindowList processedWindows); #if QT_CONFIG(draganddrop) virtual void notifyDragStarted(const QDrag *); diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index f9db6155af..6800a51d4b 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -1420,24 +1420,7 @@ void QApplicationPrivate::setPalette_helper(const QPalette &palette, const char* if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) { // Send ApplicationPaletteChange to qApp itself, and to the widgets. - QEvent e(QEvent::ApplicationPaletteChange); - QApplication::sendEvent(QApplication::instance(), &e); - - QWidgetList wids = QApplication::allWidgets(); - for (QWidgetList::ConstIterator it = wids.constBegin(), cend = wids.constEnd(); it != cend; ++it) { - QWidget *w = *it; - if (all || (!className && w->isWindow()) || w->inherits(className)) // matching class - QApplication::sendEvent(w, &e); - } - - // Send to all scenes as well. -#if QT_CONFIG(graphicsview) - QList &scenes = qApp->d_func()->scene_list; - for (QList::ConstIterator it = scenes.constBegin(); - it != scenes.constEnd(); ++it) { - QApplication::sendEvent(*it, &e); - } -#endif // QT_CONFIG(graphicsview) + qApp->d_func()->sendApplicationPaletteChange(all, className); } if (!className && (!QApplicationPrivate::sys_pal || !palette.isCopyOf(*QApplicationPrivate::sys_pal))) { if (!QApplicationPrivate::set_pal) @@ -4508,6 +4491,23 @@ void QApplicationPrivate::notifyThemeChanged() qt_init_tooltip_palette(); } +void QApplicationPrivate::sendApplicationPaletteChange(bool toAllWidgets, const char *className) +{ + QGuiApplicationPrivate::sendApplicationPaletteChange(); + + QEvent event(QEvent::ApplicationPaletteChange); + const QWidgetList widgets = QApplication::allWidgets(); + for (auto widget : widgets) { + if (toAllWidgets || (!className && widget->isWindow()) || (className && widget->inherits(className))) + QApplication::sendEvent(widget, &event); + } + +#if QT_CONFIG(graphicsview) + for (auto scene : qAsConst(scene_list)) + QApplication::sendEvent(scene, &event); +#endif // QT_CONFIG(graphicsview) +} + #if QT_CONFIG(draganddrop) void QApplicationPrivate::notifyDragStarted(const QDrag *drag) { diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h index 05bc2468c1..133279f977 100644 --- a/src/widgets/kernel/qapplication_p.h +++ b/src/widgets/kernel/qapplication_p.h @@ -177,6 +177,9 @@ public: protected: void notifyThemeChanged() override; + void sendApplicationPaletteChange(bool toAllWidgets = false, + const char *className = nullptr) override; + #if QT_CONFIG(draganddrop) void notifyDragStarted(const QDrag *) override; #endif // QT_CONFIG(draganddrop) From a3f3c1d599d412a6ffbcffdca8916acd3506381d Mon Sep 17 00:00:00 2001 From: Heikki Halmet Date: Mon, 7 Jan 2019 14:46:02 +0200 Subject: [PATCH 0811/1650] Make Android arch x86_64 to use platform-21 Change-Id: I0dc1f87af2270aa5a8ac9fcc256b5b923e1c8c21 Reviewed-by: Eskil Abrahamsen Blomfeldt --- configure.pri | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configure.pri b/configure.pri index b3b3e27c44..629ca78ff1 100644 --- a/configure.pri +++ b/configure.pri @@ -606,6 +606,9 @@ defineTest(qtConfOutput_prepareOptions) { isEmpty(platform): equals(target_arch, arm64-v8a): \ platform = android-21 + isEmpty(platform): equals(target_arch, x86_64): \ + platform = android-21 + isEmpty(platform): \ platform = android-16 ### the windows configure disagrees ... From 8b1a23ed32cbba28ad642a1884a50e6f2b13d17e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tony=20Saraj=C3=A4rvi?= Date: Tue, 8 Jan 2019 12:23:35 +0200 Subject: [PATCH 0812/1650] Blacklist a flaky qtableview function in WinRT Task-number: QTBUG-72853 Change-Id: Iaf2b25712b571a3ce73387cb3d2e70d427808364 Reviewed-by: Oliver Wolff --- tests/auto/widgets/itemviews/qtableview/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/widgets/itemviews/qtableview/BLACKLIST b/tests/auto/widgets/itemviews/qtableview/BLACKLIST index fc231a4e30..be90475a6f 100644 --- a/tests/auto/widgets/itemviews/qtableview/BLACKLIST +++ b/tests/auto/widgets/itemviews/qtableview/BLACKLIST @@ -1,2 +1,4 @@ [moveCursorBiggerJump] osx +[columnViewportPosition] +winrt # QTBUG-72853 From 2e2832a4994a8172ce1ba5b3e1478ef5a7f8c24f Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 3 Jan 2019 16:52:08 +0100 Subject: [PATCH 0813/1650] Fix typo in fontconfig autotest Change-Id: Ie6ef3aa654083cd23320eda99660ff85050d999c Reviewed-by: Leena Miettinen --- src/gui/configure.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/configure.json b/src/gui/configure.json index 89934c8f1d..39c0232c0b 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -250,7 +250,7 @@ "test": { "tail": [ "#ifndef FC_RGBA_UNKNOWN", - "# error This version of fontconfig is tool old, it is missing the FC_RGBA_UNKNOWN define", + "# error This version of fontconfig is too old, it is missing the FC_RGBA_UNKNOWN define", "#endif" ], "main": [ From c961d1a6d29af8ea385c042ec0d2d419e3bbfa84 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 12 Oct 2018 11:10:07 +0200 Subject: [PATCH 0814/1650] Make convert_generic_to_rgb64 more generic This makes it possible to get rid of specialized functions for converting to RGBA64PM, while at the same time making the conversion faster as the painter routines are better optimized. Change-Id: I3e73856b2c1411977450e72af1741aab0ecf537e Reviewed-by: Eirik Aavitsland --- src/gui/image/qimage.cpp | 8 +- src/gui/image/qimage_conversions.cpp | 127 ++++-------------- .../qimageconversion/tst_qimageconversion.cpp | 10 ++ 3 files changed, 35 insertions(+), 110 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 4c00c7705a..efef5eee58 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -2062,13 +2062,7 @@ QImage QImage::convertToFormat_helper(Format format, Qt::ImageConversionFlags fl Image_Converter converter = qimage_converter_map[d->format][format]; if (!converter && format > QImage::Format_Indexed8 && d->format > QImage::Format_Indexed8) { if (highColorPrecision(format) && highColorPrecision(d->format)) { - // Convert over RGBA64_Premultiplied - if (format == QImage::Format_RGBA64_Premultiplied) - converter = convert_generic_to_rgb64; - else { - Q_ASSERT(d->format != QImage::Format_RGBA64_Premultiplied); - return convertToFormat(Format_RGBA64_Premultiplied, flags).convertToFormat(format, flags); - } + converter = convert_generic_to_rgb64; } else converter = convert_generic; } diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index ea9347183e..82ffb8af8b 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -223,18 +223,29 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio void convert_generic_to_rgb64(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) { - Q_ASSERT(dest->format == QImage::Format_RGBA64_Premultiplied); + Q_ASSERT(dest->format > QImage::Format_Indexed8); Q_ASSERT(src->format > QImage::Format_Indexed8); + QRgba64 buf[BufferSize]; + QRgba64 *buffer = buf; const QPixelLayout *srcLayout = &qPixelLayouts[src->format]; + const QPixelLayout *destLayout = &qPixelLayouts[dest->format]; const uchar *srcData = src->data; uchar *destData = dest->data; const FetchAndConvertPixelsFunc64 fetch = srcLayout->fetchToRGBA64PM; + const ConvertAndStorePixelsFunc64 store = qStoreFromRGBA64PM[dest->format]; for (int y = 0; y < src->height; ++y) { - const QRgba64 *ptr = fetch((QRgba64*)destData, srcData, 0, src->width, nullptr, nullptr); - if (ptr != (const QRgba64*)destData) { - memcpy(destData, ptr, dest->bytes_per_line); + int x = 0; + while (x < src->width) { + int l = src->width - x; + if (destLayout->bpp == QPixelLayout::BPP64) + buffer = reinterpret_cast(destData) + x; + else + l = qMin(l, BufferSize); + const QRgba64 *ptr = fetch(buffer, srcData, x, l, nullptr, nullptr); + store(destData, ptr, x, l, nullptr, nullptr); + x += l; } srcData += src->bytes_per_line; destData += dest->bytes_per_line; @@ -1204,33 +1215,6 @@ static void convert_RGBA64_to_ARGB32(QImageData *dest, const QImageData *src, Qt } } -template -static void convert_RGBA64PM_to_ARGB32(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) -{ - Q_ASSERT(src->format == QImage::Format_RGBA64_Premultiplied); - Q_ASSERT(RGBA || dest->format == QImage::Format_ARGB32); - Q_ASSERT(!RGBA || dest->format == QImage::Format_RGBA8888); - Q_ASSERT(src->width == dest->width); - Q_ASSERT(src->height == dest->height); - - const int src_pad = (src->bytes_per_line >> 3) - src->width; - const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; - const QRgba64 *src_data = reinterpret_cast(src->data); - uint *dest_data = reinterpret_cast(dest->data); - - for (int i = 0; i < src->height; ++i) { - const QRgba64 *end = src_data + src->width; - while (src_data < end) { - QRgba64 s = src_data->unpremultiplied(); - *dest_data = RGBA ? ARGB2RGBA(s.toArgb32()) : s.toArgb32(); - ++src_data; - ++dest_data; - } - src_data += src_pad; - dest_data += dest_pad; - } -} - template static void convert_ARGB32_to_RGBA64(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) { @@ -1240,74 +1224,14 @@ static void convert_ARGB32_to_RGBA64(QImageData *dest, const QImageData *src, Qt Q_ASSERT(src->width == dest->width); Q_ASSERT(src->height == dest->height); - const int src_pad = (src->bytes_per_line >> 2) - src->width; - const int dest_pad = (dest->bytes_per_line >> 3) - dest->width; - const uint *src_data = reinterpret_cast(src->data); - QRgba64 *dest_data = reinterpret_cast(dest->data); + const uchar *src_data = src->data; + uchar *dest_data = dest->data; + const FetchAndConvertPixelsFunc64 fetch = qPixelLayouts[src->format + 1].fetchToRGBA64PM; for (int i = 0; i < src->height; ++i) { - const uint *end = src_data + src->width; - while (src_data < end) { - if (RGBA) - *dest_data = QRgba64::fromArgb32(RGBA2ARGB(*src_data)); - else - *dest_data = QRgba64::fromArgb32(*src_data); - ++src_data; - ++dest_data; - } - src_data += src_pad; - dest_data += dest_pad; - } -} - -template -static void convert_RGBA64PM_to_RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) -{ - Q_ASSERT(src->format == QImage::Format_RGBA64_Premultiplied); - Q_ASSERT(dest->format == QImage::Format_RGB30 || dest->format == QImage::Format_BGR30); - Q_ASSERT(src->width == dest->width); - Q_ASSERT(src->height == dest->height); - - const int src_pad = (src->bytes_per_line >> 3) - src->width; - const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; - const QRgba64 *src_data = reinterpret_cast(src->data); - uint *dest_data = reinterpret_cast(dest->data); - - for (int i = 0; i < src->height; ++i) { - const QRgba64 *end = src_data + src->width; - while (src_data < end) { - *dest_data = 0xc0000000 | qConvertRgb64ToRgb30(src_data->unpremultiplied()); - ++src_data; - ++dest_data; - } - src_data += src_pad; - dest_data += dest_pad; - } -} - -template -static void convert_RGBA64PM_to_A2RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) -{ - Q_ASSERT(src->format == QImage::Format_RGBA64_Premultiplied); - Q_ASSERT(dest->format == QImage::Format_A2RGB30_Premultiplied - || dest->format == QImage::Format_A2BGR30_Premultiplied); - Q_ASSERT(src->width == dest->width); - Q_ASSERT(src->height == dest->height); - - const int src_pad = (src->bytes_per_line >> 3) - src->width; - const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; - const QRgba64 *src_data = reinterpret_cast(src->data); - uint *dest_data = reinterpret_cast(dest->data); - - for (int i = 0; i < src->height; ++i) { - const QRgba64 *end = src_data + src->width; - while (src_data < end) { - *dest_data = qConvertRgb64ToRgb30(*src_data); - ++src_data; - ++dest_data; - } - src_data += src_pad; - dest_data += dest_pad; + fetch(reinterpret_cast(dest_data), src_data, 0, src->width, nullptr, nullptr); + src_data += src->bytes_per_line;; + dest_data += dest->bytes_per_line; } } @@ -2958,7 +2882,6 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - convert_RGBA64PM_to_ARGB32, 0, 0, 0, @@ -2970,12 +2893,10 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - convert_RGBA64PM_to_ARGB32, 0, - convert_RGBA64PM_to_RGB30, - convert_RGBA64PM_to_A2RGB30, - convert_RGBA64PM_to_RGB30, - convert_RGBA64PM_to_A2RGB30, + 0, + 0, + 0, 0, 0, 0, 0, 0, convert_RGBA64PM_to_RGBA64, convert_RGBA64PM_to_RGBA64, diff --git a/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp b/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp index e0f69bee11..605df100ee 100644 --- a/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp +++ b/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp @@ -200,6 +200,8 @@ void tst_QImageConversion::convertRgb32_data() QTest::newRow("argb32 -> argb8565pm") << argb32 << QImage::Format_ARGB8565_Premultiplied; QTest::newRow("argb32 -> argb4444pm") << argb32 << QImage::Format_ARGB4444_Premultiplied; QTest::newRow("argb32 -> argb6666pm") << argb32 << QImage::Format_ARGB6666_Premultiplied; + QTest::newRow("argb32 -> rgba64") << argb32 << QImage::Format_RGBA64; + QTest::newRow("argb32 -> rgba64pm") << argb32 << QImage::Format_RGBA64_Premultiplied; QTest::newRow("argb32pm -> rgb16") << argb32pm << QImage::Format_RGB16; QTest::newRow("argb32pm -> rgb32") << argb32pm << QImage::Format_RGB32; @@ -239,6 +241,7 @@ void tst_QImageConversion::convertGeneric_data() QImage a2rgb30 = argb32.convertToFormat(QImage::Format_A2RGB30_Premultiplied); QImage rgb666 = rgb32.convertToFormat(QImage::Format_RGB666); QImage argb4444 = argb32.convertToFormat(QImage::Format_ARGB4444_Premultiplied); + QImage rgba64pm = argb32.convertToFormat(QImage::Format_RGBA64_Premultiplied); QTest::newRow("indexed8 -> rgb32") << i8 << QImage::Format_RGB32; QTest::newRow("indexed8 -> argb32") << i8 << QImage::Format_ARGB32; @@ -289,6 +292,13 @@ void tst_QImageConversion::convertGeneric_data() QTest::newRow("argb4444pm -> rgba8888pm") << argb4444 << QImage::Format_RGBA8888_Premultiplied; QTest::newRow("argb4444pm -> rgb30") << argb4444 << QImage::Format_RGB30; QTest::newRow("argb4444pm -> a2bgr30") << argb4444 << QImage::Format_A2BGR30_Premultiplied; + + QTest::newRow("rgba64pm -> argb32") << rgba64pm << QImage::Format_ARGB32; + QTest::newRow("rgba64pm -> rgbx8888") << rgba64pm << QImage::Format_RGBX8888; + QTest::newRow("rgba64pm -> rgba8888pm") << rgba64pm << QImage::Format_RGBA8888_Premultiplied; + QTest::newRow("rgba64pm -> rgb30") << rgba64pm << QImage::Format_RGB30; + QTest::newRow("rgba64pm -> a2bgr30") << rgba64pm << QImage::Format_A2BGR30_Premultiplied; + QTest::newRow("rgba64pm -> rgba64") << rgba64pm << QImage::Format_RGBA64; } void tst_QImageConversion::convertGeneric() From 4d9ac14bf8d1c1a33a2720c7f7dcaf8d912a592f Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Wed, 31 Oct 2018 14:51:26 +0100 Subject: [PATCH 0815/1650] Doc: Complete doc on QHostAddress::clear() Task-number: QTBUG-31280 Change-Id: Ia9904433b0b67bead8831f2ef678b9598977df6b Reviewed-by: Timur Pocheptsov Reviewed-by: Paul Wicking --- src/network/kernel/qhostaddress.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp index 27b5f570dc..fba91c62c8 100644 --- a/src/network/kernel/qhostaddress.cpp +++ b/src/network/kernel/qhostaddress.cpp @@ -574,7 +574,8 @@ QHostAddress &QHostAddress::operator=(SpecialAddress address) */ /*! - Sets the host address to null. + Sets the host address to null and sets the protocol to + QAbstractSocket::UnknownNetworkLayerProtocol. \sa QHostAddress::Null */ From afb08ac5dae930912768f3f0ae4352189b8c3641 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Mon, 7 Jan 2019 13:54:40 +0100 Subject: [PATCH 0816/1650] Use jint instead of jboolean where applicable and initialize variables This amends change c6af7cf666d43c68c90ad829c3a55d84ee8e4a3e which had incorrectly used jboolean to store the result of getCursorCapsMode() and thus lost the information it was passing. The variables are also initialized in case there is a lock problem when calling runOnQtThread. Fixes: QTBUG-72783 Change-Id: Ibdc21e348c25ee4fdff242d14b3722c6551b042c Reviewed-by: BogDan Vatra --- .../android/qandroidinputcontext.cpp | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp index 394e284bb6..cdc52e1cb4 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.cpp +++ b/src/plugins/platforms/android/qandroidinputcontext.cpp @@ -115,7 +115,7 @@ static jboolean beginBatchEdit(JNIEnv */*env*/, jobject /*thiz*/) #ifdef QT_DEBUG_ANDROID_IM_PROTOCOL qDebug("@@@ BEGINBATCH"); #endif - jboolean res; + jboolean res = JNI_FALSE; runOnQtThread([&res]{res = m_androidInputContext->beginBatchEdit();}); return res; } @@ -129,7 +129,7 @@ static jboolean endBatchEdit(JNIEnv */*env*/, jobject /*thiz*/) qDebug("@@@ ENDBATCH"); #endif - jboolean res; + jboolean res = JNI_FALSE; runOnQtThread([&res]{res = m_androidInputContext->endBatchEdit();}); return res; } @@ -148,7 +148,7 @@ static jboolean commitText(JNIEnv *env, jobject /*thiz*/, jstring text, jint new #ifdef QT_DEBUG_ANDROID_IM_PROTOCOL qDebug() << "@@@ COMMIT" << str << newCursorPosition; #endif - jboolean res; + jboolean res = JNI_FALSE; runOnQtThread([&]{res = m_androidInputContext->commitText(str, newCursorPosition);}); return res; } @@ -161,7 +161,7 @@ static jboolean deleteSurroundingText(JNIEnv */*env*/, jobject /*thiz*/, jint le #ifdef QT_DEBUG_ANDROID_IM_PROTOCOL qDebug() << "@@@ DELETE" << leftLength << rightLength; #endif - jboolean res; + jboolean res = JNI_FALSE; runOnQtThread([&]{res = m_androidInputContext->deleteSurroundingText(leftLength, rightLength);}); return res; } @@ -174,7 +174,7 @@ static jboolean finishComposingText(JNIEnv */*env*/, jobject /*thiz*/) #ifdef QT_DEBUG_ANDROID_IM_PROTOCOL qDebug("@@@ FINISH"); #endif - jboolean res; + jboolean res = JNI_FALSE; runOnQtThread([&]{res = m_androidInputContext->finishComposingText();}); return res; } @@ -184,7 +184,7 @@ static jint getCursorCapsMode(JNIEnv */*env*/, jobject /*thiz*/, jint reqModes) if (!m_androidInputContext) return 0; - jboolean res; + jint res = 0; runOnQtThread([&]{res = m_androidInputContext->getCursorCapsMode(reqModes);}); return res; } @@ -269,7 +269,7 @@ static jboolean setComposingText(JNIEnv *env, jobject /*thiz*/, jstring text, ji #ifdef QT_DEBUG_ANDROID_IM_PROTOCOL qDebug() << "@@@ SET" << str << newCursorPosition; #endif - jboolean res; + jboolean res = JNI_FALSE; runOnQtThread([&]{res = m_androidInputContext->setComposingText(str, newCursorPosition);}); return res; } @@ -282,7 +282,7 @@ static jboolean setComposingRegion(JNIEnv */*env*/, jobject /*thiz*/, jint start #ifdef QT_DEBUG_ANDROID_IM_PROTOCOL qDebug() << "@@@ SETR" << start << end; #endif - jboolean res; + jboolean res = JNI_FALSE; runOnQtThread([&]{res = m_androidInputContext->setComposingRegion(start, end);}); return res; } @@ -296,7 +296,7 @@ static jboolean setSelection(JNIEnv */*env*/, jobject /*thiz*/, jint start, jint #ifdef QT_DEBUG_ANDROID_IM_PROTOCOL qDebug() << "@@@ SETSEL" << start << end; #endif - jboolean res; + jboolean res = JNI_FALSE; runOnQtThread([&]{res = m_androidInputContext->setSelection(start, end);}); return res; @@ -310,7 +310,7 @@ static jboolean selectAll(JNIEnv */*env*/, jobject /*thiz*/) #ifdef QT_DEBUG_ANDROID_IM_PROTOCOL qDebug("@@@ SELALL"); #endif - jboolean res; + jboolean res = JNI_FALSE; runOnQtThread([&]{res = m_androidInputContext->selectAll();}); return res; } @@ -323,7 +323,7 @@ static jboolean cut(JNIEnv */*env*/, jobject /*thiz*/) #ifdef QT_DEBUG_ANDROID_IM_PROTOCOL qDebug("@@@"); #endif - jboolean res; + jboolean res = JNI_FALSE; runOnQtThread([&]{res = m_androidInputContext->cut();}); return res; } @@ -336,7 +336,7 @@ static jboolean copy(JNIEnv */*env*/, jobject /*thiz*/) #ifdef QT_DEBUG_ANDROID_IM_PROTOCOL qDebug("@@@"); #endif - jboolean res; + jboolean res = JNI_FALSE; runOnQtThread([&]{res = m_androidInputContext->copy();}); return res; } @@ -349,7 +349,7 @@ static jboolean copyURL(JNIEnv */*env*/, jobject /*thiz*/) #ifdef QT_DEBUG_ANDROID_IM_PROTOCOL qDebug("@@@"); #endif - jboolean res; + jboolean res = JNI_FALSE; runOnQtThread([&]{res = m_androidInputContext->copyURL();}); return res; } @@ -362,7 +362,7 @@ static jboolean paste(JNIEnv */*env*/, jobject /*thiz*/) #ifdef QT_DEBUG_ANDROID_IM_PROTOCOL qDebug("@@@ PASTE"); #endif - jboolean res; + jboolean res = JNI_FALSE; runOnQtThread([&]{res = m_androidInputContext->paste();}); return res; } From a8db9b8663f0bf3d66b36b5f743bd2fd47105cb6 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 8 Jan 2019 13:48:47 +0100 Subject: [PATCH 0817/1650] Fix a crash in QTextEngine when a paragraph only contains a tab This fixes a regression introduced by change c3d2d83fcb0f88de7d08cb7d088db8942e2e0f64. Change-Id: Idf840804c68cd6b1751e122b45e9dd2775af56f5 Fixes: QTBUG-72900 Fixes: QTBUG-72754 Reviewed-by: David Faure --- src/gui/text/qtextengine.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index bdb5592e9e..506df0664d 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1972,14 +1972,18 @@ void QTextEngine::shape(int item) const } // fix log clusters to point to the previous glyph, as the object doesn't have a glyph of it's own. // This is required so that all entries in the array get initialized and are ordered correctly. - ushort *lc = logClusters(&li); - *lc = item ? lc[-1] : 0; + if (layoutData->logClustersPtr) { + ushort *lc = logClusters(&li); + *lc = (lc != layoutData->logClustersPtr) ? lc[-1] : 0; + } } else if (li.analysis.flags == QScriptAnalysis::Tab) { // set up at least the ascent/descent/leading of the script item for the tab fontEngine(li, &li.ascent, &li.descent, &li.leading); // see the comment above - ushort *lc = logClusters(&li); - *lc = item ? lc[-1] : 0; + if (layoutData->logClustersPtr) { + ushort *lc = logClusters(&li); + *lc = (lc != layoutData->logClustersPtr) ? lc[-1] : 0; + } } else { shapeText(item); } From 5feac1e10cfb95e2d17658b7a1611052a4ff8d17 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 3 Jan 2019 15:09:38 +0100 Subject: [PATCH 0818/1650] Fix attribution file for "FreeBSD strtoll and strtoull" The JSON file format does not support an "Upstream" entry, see also https://quips-qt-io.herokuapp.com/quip-0007.html Finally, the link didn't work for me. This amends ceeecbae510af6e Change-Id: I707f1113c399d85c2fbf982726033ac74f691915 Reviewed-by: Allan Sandfeld Jensen --- src/3rdparty/freebsd/qt_attribution.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/3rdparty/freebsd/qt_attribution.json b/src/3rdparty/freebsd/qt_attribution.json index 6a4a9ca1af..644880a90d 100644 --- a/src/3rdparty/freebsd/qt_attribution.json +++ b/src/3rdparty/freebsd/qt_attribution.json @@ -7,7 +7,7 @@ "Description": "strtoll() and strtoull() are functions for converting a string to (unsigned) long long integer.", "Homepage": "https://github.com/freebsd/freebsd/", - "Upstream": "https://raw.githubusercontent.com/freebsd/freebsd/raw/tree/master/lib/libc/stdlib/$file", + "DownloadLocation": "https://github.com/freebsd/freebsd/tree/master/lib/libc/stdlib", "Version": "upstream has complicated with std locales; do not update", "Version": "18b29f3fb8abee5d57ed8f4a44f806bec7e0eeff", "License": "BSD 3-clause \"New\" or \"Revised\" License", From 81c3c66bb44c98b29a0181450ffa38a1c1fa06d9 Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Tue, 8 Jan 2019 13:00:46 +0100 Subject: [PATCH 0819/1650] Fix PDF generation for locales using comma as decimal separator A previous change that extended the maximum PDF size has caused the generation of invalid PDF output when the current locale was set to something using commas instead of points when outputting floating point numbers through printf(). This change uses QByteArray::number() instead, which uses points, irrespective of the current locale. Fixes: QTBUG-72868 Fixes: QTBUG-72848 Change-Id: I292eba2d6c89b3e01957bb8c04c04bdca8ada316 Reviewed-by: Friedemann Kleint Reviewed-by: Tobias Koenig --- src/gui/painting/qpdf.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index e69726b617..ae3df6f9ec 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -1953,13 +1953,14 @@ void QPdfEnginePrivate::writePage() "/Contents %d 0 R\n" "/Resources %d 0 R\n" "/Annots %d 0 R\n" - "/MediaBox [0 0 %f %f]\n", + "/MediaBox [0 0 %s %s]\n", pageRoot, pageStream, resources, annots, // make sure we use the pagesize from when we started the page, since the user may have changed it - currentPage->pageSize.width() / userUnit, currentPage->pageSize.height() / userUnit); + QByteArray::number(currentPage->pageSize.width() / userUnit, 'f').constData(), + QByteArray::number(currentPage->pageSize.height() / userUnit, 'f').constData()); if (pdfVersion >= QPdfEngine::Version_1_6) - xprintf("/UserUnit %f\n", userUnit); + xprintf("/UserUnit %s\n", QByteArray::number(userUnit, 'f').constData()); xprintf(">>\n" "endobj\n"); From 74c8aa76089ce0b16ddd4d560530cf6df85d397e Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Fri, 4 Jan 2019 10:32:28 +0100 Subject: [PATCH 0820/1650] bmp image handler: Reject invalid 0-dimension files early Avoid spending time on decoding attempt of invalid bmp files specifying height or width as 0. Change-Id: Ia6666088515eee54777f7154868fb7d07c6b4438 Done-with: Albert Astals Cid Reviewed-by: Lars Knoll Reviewed-by: Albert Astals Cid --- src/gui/image/qbmphandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp index 5dff4ab0ac..7257853c3e 100644 --- a/src/gui/image/qbmphandler.cpp +++ b/src/gui/image/qbmphandler.cpp @@ -188,7 +188,7 @@ static bool read_dib_infoheader(QDataStream &s, BMP_INFOHDR &bi) if (!(comp == BMP_RGB || (nbits == 4 && comp == BMP_RLE4) || (nbits == 8 && comp == BMP_RLE8) || ((nbits == 16 || nbits == 32) && comp == BMP_BITFIELDS))) return false; // weird compression type - if (bi.biWidth < 0 || quint64(bi.biWidth) * qAbs(bi.biHeight) > 16384 * 16384) + if (bi.biWidth <= 0 || !bi.biHeight || quint64(bi.biWidth) * qAbs(bi.biHeight) > 16384 * 16384) return false; return true; From e70230405dce5ac03817fc564a3a8ba5f208422a Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 31 Oct 2017 14:29:37 +0100 Subject: [PATCH 0821/1650] Don't treat the ampersand in a titlebar as a mnemonic As the mnemonic has no meaning when it is in a dockwidget title, we should just treat it as a literal ampersand instead and display it as such. Fixes: QTBUG-54485 Change-Id: I96c856ce2771a68d226f48f8f47affc24f1c53cd Reviewed-by: Frederik Gladhorn --- src/plugins/styles/mac/qmacstyle_mac.mm | 2 +- src/widgets/styles/qcommonstyle.cpp | 2 +- src/widgets/styles/qfusionstyle.cpp | 2 +- src/widgets/styles/qstylesheetstyle.cpp | 2 +- src/widgets/styles/qwindowsstyle.cpp | 2 +- src/widgets/widgets/qdockwidget.cpp | 1 + src/widgets/widgets/qdockwidget_p.h | 1 + .../widgets/qdockwidget/tst_qdockwidget.cpp | 48 +++++++++++++++++++ 8 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index b84448d5e2..f647b95458 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -3922,7 +3922,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter titleRect.width()); const auto text = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, titleRect.width()); - proxy()->drawItemText(p, titleRect, Qt::AlignCenter | Qt::TextShowMnemonic, dwOpt->palette, + proxy()->drawItemText(p, titleRect, Qt::AlignCenter, dwOpt->palette, dwOpt->state & State_Enabled, text, QPalette::WindowText); } p->restore(); diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index d1767679f7..49543061cc 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -2096,7 +2096,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, const int indent = p->fontMetrics().descent(); proxy()->drawItemText(p, r.adjusted(indent + 1, 1, -indent - 1, -1), - Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, dwOpt->palette, + Qt::AlignLeft | Qt::AlignVCenter, dwOpt->palette, dwOpt->state & State_Enabled, dwOpt->title, QPalette::WindowText); diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp index cada64a646..7c58adeb85 100644 --- a/src/widgets/styles/qfusionstyle.cpp +++ b/src/widgets/styles/qfusionstyle.cpp @@ -1256,7 +1256,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio Qt::ElideRight, titleRect.width()); proxy()->drawItemText(painter, titleRect, - Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, dwOpt->palette, + Qt::AlignLeft | Qt::AlignVCenter, dwOpt->palette, dwOpt->state & State_Enabled, titleText, QPalette::WindowText); } diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 5ed7195b60..e261055c3c 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -4224,7 +4224,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q QString titleText = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, r.width()); drawItemText(p, r, - alignment | Qt::TextShowMnemonic, dwOpt->palette, + alignment, dwOpt->palette, dwOpt->state & State_Enabled, titleText, QPalette::WindowText); diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp index 5ad0666932..c0a8228e42 100644 --- a/src/widgets/styles/qwindowsstyle.cpp +++ b/src/widgets/styles/qwindowsstyle.cpp @@ -1825,7 +1825,7 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai titleRect.height(), titleRect.width()); } proxy()->drawItemText(p, titleRect, - Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, palette, + Qt::AlignLeft | Qt::AlignVCenter, palette, dwOpt->state & State_Enabled, dwOpt->title, floating ? (active ? QPalette::BrightText : QPalette::Window) : QPalette::WindowText); p->setFont(oldFont); diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp index 663225ebf3..cd3accefff 100644 --- a/src/widgets/widgets/qdockwidget.cpp +++ b/src/widgets/widgets/qdockwidget.cpp @@ -55,6 +55,7 @@ #include #include +#include #include "qdockwidget_p.h" #include "qmainwindowlayout_p.h" diff --git a/src/widgets/widgets/qdockwidget_p.h b/src/widgets/widgets/qdockwidget_p.h index 766e4ed161..14d73e815f 100644 --- a/src/widgets/widgets/qdockwidget_p.h +++ b/src/widgets/widgets/qdockwidget_p.h @@ -108,6 +108,7 @@ public: // QMainWindow *findMainWindow(QWidget *widget) const; QRect undockedGeometry; QString fixedWindowTitle; + QString dockedWindowTitle; bool mousePressEvent(QMouseEvent *event); bool mouseDoubleClickEvent(QMouseEvent *event); diff --git a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp index 078a3215fd..f8ce6a2c0a 100644 --- a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp +++ b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp @@ -71,6 +71,7 @@ private slots: void restoreStateOfFloating(); void restoreDockWidget(); void restoreStateWhileStillFloating(); + void setWindowTitle(); // task specific tests: void task165177_deleteFocusWidget(); void task169808_setFloating(); @@ -993,7 +994,54 @@ void tst_QDockWidget::taskQTBUG_9758_undockedGeometry() QVERIFY(dock1.y() >= 0); } +void tst_QDockWidget::setWindowTitle() +{ + QMainWindow window; + QDockWidget dock1(&window); + QDockWidget dock2(&window); + const QString dock1Title = QStringLiteral("&Window"); + const QString dock2Title = QStringLiteral("&Modifiable Window [*]"); + dock1.setWindowTitle(dock1Title); + dock2.setWindowTitle(dock2Title); + window.addDockWidget(Qt::RightDockWidgetArea, &dock1); + window.addDockWidget(Qt::RightDockWidgetArea, &dock2); + window.show(); + QVERIFY(QTest::qWaitForWindowExposed(&window)); + + QCOMPARE(dock1.windowTitle(), dock1Title); + QCOMPARE(dock2.windowTitle(), dock2Title); + + dock1.setFloating(true); + dock1.show(); + QVERIFY(QTest::qWaitForWindowExposed(&dock1)); + QCOMPARE(dock1.windowTitle(), dock1Title); + dock1.setFloating(false); + QCOMPARE(dock1.windowTitle(), dock1Title); + dock1.setFloating(true); + dock1.show(); + QVERIFY(QTest::qWaitForWindowExposed(&dock1)); + const QString changed = QStringLiteral("Changed "); + dock1.setWindowTitle(QString(changed + dock1Title)); + QCOMPARE(dock1.windowTitle(), QString(changed + dock1Title)); + dock1.setFloating(false); + QCOMPARE(dock1.windowTitle(), QString(changed + dock1Title)); + + dock2.setWindowModified(true); + QCOMPARE(dock2.windowTitle(), dock2Title); + dock2.setFloating(true); + dock2.show(); + QVERIFY(QTest::qWaitForWindowExposed(&dock2)); + QCOMPARE(dock2.windowTitle(), dock2Title); + dock2.setWindowModified(false); + QCOMPARE(dock2.windowTitle(), dock2Title); + dock2.setFloating(false); + QCOMPARE(dock2.windowTitle(), dock2Title); + dock2.setFloating(true); + dock2.show(); + QVERIFY(QTest::qWaitForWindowExposed(&dock2)); + QCOMPARE(dock2.windowTitle(), dock2Title); +} QTEST_MAIN(tst_QDockWidget) #include "tst_qdockwidget.moc" From 574ac8734d99133387ceab6025d93d1cf202711e Mon Sep 17 00:00:00 2001 From: Ryan Chu Date: Fri, 4 Jan 2019 16:29:30 +0100 Subject: [PATCH 0822/1650] Skip smb-path test of tst_QNetworkReply when using Docker test servers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tests of smb protocol only work in the CI network. Therefore, the docker-based test server for Windows can't pass all the tests of QNetworkReply. These two tests should be reworked when adding Samba server to the docker-based test servers later on. Task-number: QTBUG-72861 Change-Id: I54e639b5414760ee929d0d28fe10f9e021aff7dc Reviewed-by: Jędrzej Nowacki --- .../network/access/qnetworkreply/tst_qnetworkreply.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 30b41da515..61f0f70ea7 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -1809,6 +1809,11 @@ void tst_QNetworkReply::getFromFileSpecial_data() void tst_QNetworkReply::getFromFileSpecial() { +#if defined(QT_TEST_SERVER) && defined(Q_OS_WIN) + if (qstrcmp(QTest::currentDataTag(), "smb-path") == 0) + QSKIP("Docker-based test server doesn't support smb protocol yet"); +#endif + QFETCH(QString, fileName); QFETCH(QString, url); @@ -3202,6 +3207,11 @@ void tst_QNetworkReply::ioGetFromFileSpecial_data() void tst_QNetworkReply::ioGetFromFileSpecial() { +#if defined(QT_TEST_SERVER) && defined(Q_OS_WIN) + if (qstrcmp(QTest::currentDataTag(), "smb-path") == 0) + QSKIP("Docker-based test server doesn't support smb protocol yet"); +#endif + QFETCH(QString, fileName); QFETCH(QString, url); From 2780f80fae58ecd986c0695f9bc61cfb5b099dc0 Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Mon, 17 Dec 2018 13:16:40 +1000 Subject: [PATCH 0823/1650] wasm: fix blob download handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I34a8ec05c18b15ed71787986b5b0316693235b4d Fixes: QTBUG-72105 Reviewed-by: Morten Johan Sørvig --- src/network/access/qnetworkreplywasmimpl.cpp | 27 ++++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/network/access/qnetworkreplywasmimpl.cpp b/src/network/access/qnetworkreplywasmimpl.cpp index 3bfe927c9f..df4e034d97 100644 --- a/src/network/access/qnetworkreplywasmimpl.cpp +++ b/src/network/access/qnetworkreplywasmimpl.cpp @@ -102,6 +102,8 @@ static void q_loadCallback(val event) return; } QString statusText = QString::fromStdString(xhr["statusText"].as()); + int readyState = xhr["readyState"].as(); + if (status == 200 || status == 203) { QString responseString; const std::string responseType = xhr["responseType"].as(); @@ -112,13 +114,15 @@ static void q_loadCallback(val event) QString::fromStdWString(val::global("JSON").call("stringify", xhr["response"])); } else if (responseType == "arraybuffer" || responseType == "blob") { // handle this data in the FileReader, triggered by the call to readAsArrayBuffer + val blob = xhr["response"]; + val reader = val::global("FileReader").new_(); reader.set("onload", val::module_property("QNetworkReplyWasmImplPrivate_readBinary")); reader.set("data-handler", xhr["data-handler"]); - reader.call("readAsArrayBuffer", xhr["response"]); + + reader.call("readAsArrayBuffer", blob); } - int readyState = xhr["readyState"].as(); if (readyState == 4) { // done reply->setReplyAttributes(xhr["data-handler"].as(), status, statusText); @@ -167,9 +171,9 @@ static void q_readBinary(val event) reinterpret_cast(buffer.data()), size); destinationTypedArray.call("set", sourceTypedArray); reply->dataReceived(buffer, buffer.size()); + QCoreApplication::processEvents(); } - EMSCRIPTEN_BINDINGS(network_module) { function("QNetworkReplyWasmImplPrivate_requestErrorCallback", q_requestErrorCallback); function("QNetworkReplyWasmImplPrivate_progressCallback", q_progressCallback); @@ -240,9 +244,6 @@ qint64 QNetworkReplyWasmImpl::bytesAvailable() const { Q_D(const QNetworkReplyWasmImpl); - if (!d->isFinished) - return QNetworkReply::bytesAvailable(); - return QNetworkReply::bytesAvailable() + d->downloadBufferCurrentSize - d->downloadBufferReadPosition; } @@ -357,8 +358,7 @@ void QNetworkReplyWasmImplPrivate::doSendRequest() m_xhr.set("responseType", val("json")); dataToSend = val(extraDataString.toStdString()); } - } - if (contentType.contains("form")) { //construct form data + } else if (contentType.contains("form")) { //construct form data if (!extraDataString.isEmpty()) { val formData = val::global("FormData").new_(); QStringList formList = extraDataString.split('&'); @@ -368,6 +368,8 @@ void QNetworkReplyWasmImplPrivate::doSendRequest() } dataToSend = formData; } + } else { + m_xhr.set("responseType", val("blob")); } // set request headers for (auto header : request.rawHeaderList()) { @@ -417,10 +419,13 @@ void QNetworkReplyWasmImplPrivate::dataReceived(const QByteArray &buffer, int bu downloadBuffer.append(buffer, bufferSize); + emit q->readyRead(); + if (downloadBufferCurrentSize == totalDownloadSize) { - q->setFinished(true); - emit q->finished(); - } + q->setFinished(true); + emit q->readChannelFinished(); + emit q->finished(); + } } //taken from qnetworkrequest.cpp From 0cc9c304798a436d844d3c2a51025729d888bfb2 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Tue, 8 Jan 2019 15:03:24 +0100 Subject: [PATCH 0824/1650] disabledProtocol() - use the right address when connecting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ... as we normally do in other tests, using localhost. Change-Id: I7969d7bfd50b545adae7e23476d17b6224e9a8fc Reviewed-by: Mårten Nordheim --- tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index 184f07a48e..afba37c1f0 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -4086,7 +4086,7 @@ void tst_QSslSocket::disabledProtocols() QSslSocket socket; QCOMPARE(socket.error(), QAbstractSocket::UnknownSocketError); - socket.connectToHost(server.serverAddress(), server.serverPort()); + socket.connectToHost(QHostAddress::LocalHost, server.serverPort()); QVERIFY(socket.waitForConnected(timeoutMS)); socket.setProtocol(disabledProtocol); @@ -4111,7 +4111,7 @@ void tst_QSslSocket::disabledProtocols() {loop.exitLoop();}); QTcpSocket client; - client.connectToHost(server.serverAddress(), server.serverPort()); + client.connectToHost(QHostAddress::LocalHost, server.serverPort()); loop.enterLoopMSecs(timeoutMS); QVERIFY(!loop.timeout()); QVERIFY(server.socket); From 166162d8305404e8fc820de91ef9f6d733b4657a Mon Sep 17 00:00:00 2001 From: Roland Rossgotterer Date: Mon, 7 Jan 2019 14:49:28 +0100 Subject: [PATCH 0825/1650] Always access the 64-bit registry key to read MachineGuid When running a 32bit application on a 64bit Windows, the call to open the key "HKLM/Software/Microsoft/Cryptography/MachineGuid" will by default be redirect to "HKLM/Software/WOW6432Node/Microsoft/Cryptography/MachineGuid" which does not exist. Instead access the 64bit key from either a 32bit or 64bit application. KEY_WOW64_64KEY has no effect on 32bit Windows. Change-Id: Ic5e13f99d08aef2658d58a52cffe66dbab0510b8 Reviewed-by: Thiago Macieira --- src/corelib/global/qglobal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 88d4877be5..0109bb3568 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -2933,7 +2933,7 @@ QByteArray QSysInfo::machineUniqueId() #elif defined(Q_OS_WIN) && !defined(Q_OS_WINRT) // Let's poke at the registry HKEY key = NULL; - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Cryptography", 0, KEY_READ, &key) + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Cryptography", 0, KEY_READ | KEY_WOW64_64KEY, &key) == ERROR_SUCCESS) { wchar_t buffer[UuidStringLen + 1]; DWORD size = sizeof(buffer); From 0330db86fdd42ef1be1354cdbbd6e0ffc21d9a80 Mon Sep 17 00:00:00 2001 From: Roland Rossgotterer Date: Tue, 8 Jan 2019 16:03:02 +0100 Subject: [PATCH 0826/1650] Increase sysctl argument buffer size to include null character An UUID is 36 characters long, but sysctl and sysctlbyname return a null terminated string with 37 characters. That was too long for the provided buffer. Surprisingly the return code was still 0 instead of -1. The returned buffer was empty though. Change-Id: Ic4d20ecc1b2b3a3e98468d31ac304957d56deee9 Reviewed-by: Thiago Macieira --- src/corelib/global/qglobal.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 0109bb3568..d15a8ba6ae 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -2899,18 +2899,18 @@ enum { QByteArray QSysInfo::machineUniqueId() { #ifdef Q_OS_BSD4 - char uuid[UuidStringLen]; + char uuid[UuidStringLen + 1]; size_t uuidlen = sizeof(uuid); # ifdef KERN_HOSTUUID int name[] = { CTL_KERN, KERN_HOSTUUID }; if (sysctl(name, sizeof name / sizeof name[0], &uuid, &uuidlen, nullptr, 0) == 0 && uuidlen == sizeof(uuid)) - return QByteArray(uuid, uuidlen); + return QByteArray(uuid, uuidlen - 1); # else // Darwin: no fixed value, we need to search by name if (sysctlbyname("kern.uuid", uuid, &uuidlen, nullptr, 0) == 0 && uuidlen == sizeof(uuid)) - return QByteArray(uuid, uuidlen); + return QByteArray(uuid, uuidlen - 1); # endif #elif defined(Q_OS_UNIX) // The modern name on Linux is /etc/machine-id, but that path is @@ -2974,11 +2974,11 @@ QByteArray QSysInfo::bootUniqueId() } #elif defined(Q_OS_DARWIN) // "kern.bootsessionuuid" is only available by name - char uuid[UuidStringLen]; + char uuid[UuidStringLen + 1]; size_t uuidlen = sizeof(uuid); if (sysctlbyname("kern.bootsessionuuid", uuid, &uuidlen, nullptr, 0) == 0 && uuidlen == sizeof(uuid)) - return QByteArray(uuid, uuidlen); + return QByteArray(uuid, uuidlen - 1); #endif return QByteArray(); }; From 68511d41d50b1a136fb0e74fdabfd362e0b21a1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 5 Sep 2018 13:47:05 +0200 Subject: [PATCH 0827/1650] qWaitFor: Prevent being stuck in QCoreApplication::processEvents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When using the overload of QCoreApplication::processEvents that takes a maxtime argument, the function will keep processing events until there are no more events, or until it times out. The problem is that the function doesn't distinguish between events that were on the event queue when the function was called, and events generated by processing events as part of its own execution. If for example a widget calls update() in its paintEvent, the function will spin for the entire duration of maxtime. That doesn't work for qWaitFor, where we need to check the predicate between each pass, so we use the overload of processEvents that doesn't take a maxtime. That's fine, as we have our own timeout logic. Change-Id: I9738d7d0187c36d4a5ddfcd3fd075b0bd84583c4 Reviewed-by: Qt CI Bot Reviewed-by: Tor Arne Vestbø --- src/corelib/kernel/qtestsupport_core.h | 8 ++++- tests/auto/opengl/qgl/tst_qgl.cpp | 1 + .../dialogs/qfiledialog2/tst_qfiledialog2.cpp | 5 ++++ .../qgraphicseffect/tst_qgraphicseffect.cpp | 1 + .../tst_qgraphicseffectsource.cpp | 1 + .../qgraphicsitem/tst_qgraphicsitem.cpp | 29 +++++++++++++------ .../qgraphicsscene/tst_qgraphicsscene.cpp | 1 + .../qgraphicsview/tst_qgraphicsview.cpp | 1 + .../itemviews/qtreewidget/tst_qtreewidget.cpp | 1 + 9 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/corelib/kernel/qtestsupport_core.h b/src/corelib/kernel/qtestsupport_core.h index c8b664b6d3..c8209b5ae4 100644 --- a/src/corelib/kernel/qtestsupport_core.h +++ b/src/corelib/kernel/qtestsupport_core.h @@ -67,7 +67,13 @@ Q_REQUIRED_RESULT static bool qWaitFor(Functor predicate, int timeout = 5000) QDeadlineTimer deadline(remaining, Qt::PreciseTimer); do { - QCoreApplication::processEvents(QEventLoop::AllEvents, remaining); + // We explicitly do not pass the remaining time to processEvents, as + // that would keep spinning processEvents for the whole duration if + // new events were posted as part of processing events, and we need + // to return back to this function to check the predicate between + // each pass of processEvents. Our own timer will take care of the + // timeout. + QCoreApplication::processEvents(QEventLoop::AllEvents); QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete); remaining = deadline.remainingTime(); diff --git a/tests/auto/opengl/qgl/tst_qgl.cpp b/tests/auto/opengl/qgl/tst_qgl.cpp index 7666bf81e4..053c4b026b 100644 --- a/tests/auto/opengl/qgl/tst_qgl.cpp +++ b/tests/auto/opengl/qgl/tst_qgl.cpp @@ -924,6 +924,7 @@ void tst_QGL::partialGLWidgetUpdates() widget.setAutoFillBackground(autoFillBackground); widget.show(); QVERIFY(QTest::qWaitForWindowExposed(&widget)); + QCoreApplication::processEvents(); // Process all queued paint events if (widget.format().doubleBuffer() != doubleBufferedContext) QSKIP("Platform does not support requested format"); diff --git a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp index 8f9a8c11a7..24ce598279 100644 --- a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp +++ b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp @@ -601,6 +601,11 @@ void tst_QFileDialog2::task227930_correctNavigationKeyboardBehavior() fd.setDirectory(current.absolutePath()); fd.show(); QVERIFY(QTest::qWaitForWindowActive(&fd)); + + // Ensure LayoutRequest event is processed so that the list view + // is sorted correctly to have the directory entires at the top. + QCoreApplication::processEvents(); + QListView *list = fd.findChild("listView"); QVERIFY(list); QTest::keyClick(list, Qt::Key_Down); diff --git a/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp b/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp index 95662a49a0..c4b6e22c37 100644 --- a/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp +++ b/tests/auto/widgets/effects/qgraphicseffect/tst_qgraphicseffect.cpp @@ -313,6 +313,7 @@ void tst_QGraphicsEffect::draw() view.show(); QVERIFY(QTest::qWaitForWindowActive(&view)); QTRY_VERIFY(item->numRepaints > 0); + QCoreApplication::processEvents(); // Process all queued paint events item->reset(); // Make sure installing the effect triggers a repaint. diff --git a/tests/auto/widgets/graphicsview/qgraphicseffectsource/tst_qgraphicseffectsource.cpp b/tests/auto/widgets/graphicsview/qgraphicseffectsource/tst_qgraphicseffectsource.cpp index e7d26622c9..973a73a4a9 100644 --- a/tests/auto/widgets/graphicsview/qgraphicseffectsource/tst_qgraphicseffectsource.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicseffectsource/tst_qgraphicseffectsource.cpp @@ -183,6 +183,7 @@ void tst_QGraphicsEffectSource::init() effect->storeDeviceDependentStuff = false; effect->doNothingInDraw = false; item->reset(); + QCoreApplication::processEvents(); // Process all queued paint events } void tst_QGraphicsEffectSource::graphicsItem() diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp index bd08461544..5f269bd520 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp @@ -3231,6 +3231,7 @@ void tst_QGraphicsItem::hoverEventsGenerateRepaints() view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); QVERIFY(QTest::qWaitForWindowActive(&view)); + QCoreApplication::processEvents(); // Process all queued paint events EventTester *tester = new EventTester; scene.addItem(tester); @@ -5074,13 +5075,11 @@ void tst_QGraphicsItem::paint() QGraphicsView view2(&scene2); view2.show(); QVERIFY(QTest::qWaitForWindowExposed(&view2)); + QCoreApplication::processEvents(); // Process all queued paint events PaintTester tester2; scene2.addItem(&tester2); -#ifdef Q_OS_WINRT - QEXPECT_FAIL("", "Fails on WinRT. Figure out why - QTBUG-68297", Abort); -#endif //First show one paint QTRY_COMPARE(tester2.painted, 1); @@ -6534,11 +6533,9 @@ void tst_QGraphicsItem::ensureUpdateOnTextItem() QGraphicsView view(&scene); view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); + QCoreApplication::processEvents(); // Process all queued paint events TextItem *text1 = new TextItem(QLatin1String("123")); scene.addItem(text1); -#ifdef Q_OS_WINRT - QEXPECT_FAIL("", "Fails on WinRT. Figure out why - QTBUG-68297", Abort); -#endif QTRY_COMPARE(text1->updates,1); //same bouding rect but we have to update @@ -6810,6 +6807,7 @@ void tst_QGraphicsItem::opacity2() view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); QVERIFY(QTest::qWaitForWindowActive(&view)); + QCoreApplication::processEvents(); // Process all queued paint events QTRY_VERIFY(view.repaints >= 1); #define RESET_REPAINT_COUNTERS \ @@ -6883,6 +6881,7 @@ void tst_QGraphicsItem::opacityZeroUpdates() view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); QVERIFY(QTest::qWaitForWindowActive(&view)); + QCoreApplication::processEvents(); // Process all queued paint events QTRY_VERIFY(view.repaints > 0); view.reset(); @@ -7275,6 +7274,7 @@ void tst_QGraphicsItem::cacheMode() QApplication::setActiveWindow(&view); QVERIFY(QTest::qWaitForWindowExposed(&view)); QVERIFY(QTest::qWaitForWindowActive(&view)); + QCoreApplication::processEvents(); // Process all queued paint events EventTester *tester = new EventTester; EventTester *testerChild = new EventTester; @@ -7454,6 +7454,7 @@ void tst_QGraphicsItem::cacheMode2() QApplication::setActiveWindow(&view); QVERIFY(QTest::qWaitForWindowExposed(&view)); QVERIFY(QTest::qWaitForWindowActive(&view)); + QCoreApplication::processEvents(); // Process all queued paint events EventTester *tester = new EventTester; scene.addItem(tester); @@ -7944,6 +7945,7 @@ void tst_QGraphicsItem::itemUsesExtendedStyleOption() rect->startTrack = false; topLevel.show(); QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); + QCoreApplication::processEvents(); // Process all queued paint events QTRY_VERIFY(rect->repaints > 0); rect->repaints = 0; rect->startTrack = true; @@ -8030,6 +8032,7 @@ void tst_QGraphicsItem::moveItem() MyGraphicsView view(&scene); view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); + QCoreApplication::processEvents(); // Process all queued paint events EventTester *parent = new EventTester; EventTester *child = new EventTester(parent); @@ -8108,6 +8111,7 @@ void tst_QGraphicsItem::moveLineItem() view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); QVERIFY(QTest::qWaitForWindowActive(&view)); + QCoreApplication::processEvents(); // Process all queued paint events view.reset(); QRectF brect = item->boundingRect(); @@ -8288,6 +8292,7 @@ void tst_QGraphicsItem::hitTestGraphicsEffectItem() toplevel.resize(300, 300); toplevel.show(); QVERIFY(QTest::qWaitForWindowExposed(&toplevel)); + QCoreApplication::processEvents(); // Process all queued paint events // Confuse the BSP with dummy items. QGraphicsRectItem *dummy = new QGraphicsRectItem(0, 0, 20, 20); @@ -11266,6 +11271,7 @@ void tst_QGraphicsItem::QTBUG_6738_missingUpdateWithSetParent() qApp->setActiveWindow(&view); QVERIFY(QTest::qWaitForWindowExposed(&view)); QVERIFY(QTest::qWaitForWindowActive(&view)); + QCoreApplication::processEvents(); // Process all queued paint events QTRY_VERIFY(view.repaints > 0); // test case #1 @@ -11315,6 +11321,7 @@ void tst_QGraphicsItem::QT_2653_fullUpdateDiscardingOpacityUpdate() view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); QVERIFY(QTest::qWaitForWindowActive(&view)); + QCoreApplication::processEvents(); // Process all queued paint events view.reset(); parentGreen->setOpacity(1.0); @@ -11348,6 +11355,8 @@ void tst_QGraphicsItem::QTBUG_7714_fullUpdateDiscardingOpacityUpdate2() origView.show(); QVERIFY(QTest::qWaitForWindowActive(&origView)); + QCoreApplication::processEvents(); // Process all queued paint events + origView.setGeometry(origView.x() + origView.width() + 20, origView.y() + 20, origView.width(), origView.height()); @@ -11356,9 +11365,6 @@ void tst_QGraphicsItem::QTBUG_7714_fullUpdateDiscardingOpacityUpdate2() origView.reset(); childYellow->setOpacity(0.0); -#ifdef Q_OS_WINRT - QEXPECT_FAIL("", "Fails on WinRT. Figure out why - QTBUG-68297", Abort); -#endif QTRY_COMPARE(origView.repaints, 1); view.show(); @@ -11370,6 +11376,10 @@ void tst_QGraphicsItem::QTBUG_7714_fullUpdateDiscardingOpacityUpdate2() childYellow->setOpacity(1.0); +#ifdef Q_OS_WINRT + QEXPECT_FAIL("", "Fails on WinRT. Figure out why - QTBUG-68297", Abort); +#endif + QTRY_COMPARE(origView.repaints, 1); QTRY_COMPARE(view.repaints, 1); } @@ -11505,6 +11515,7 @@ void tst_QGraphicsItem::doNotMarkFullUpdateIfNotInScene() view.show(); QVERIFY(QTest::qWaitForWindowExposed(view.windowHandle())); QVERIFY(QTest::qWaitForWindowActive(view.windowHandle())); + QCoreApplication::processEvents(); // Process all queued paint events view.activateWindow(); QTRY_VERIFY(view.isActiveWindow()); QTRY_VERIFY(view.repaints >= 1); diff --git a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp index 838b1f4be6..48488abfb8 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp @@ -4318,6 +4318,7 @@ void tst_QGraphicsScene::removeFullyTransparentItem() view.show(); qApp->setActiveWindow(&view); QVERIFY(QTest::qWaitForWindowActive(&view)); + QCoreApplication::processEvents(); // Process all queued paint events // NB! The parent has the ItemHasNoContents flag set, which means // the parent itself doesn't generate any update requests, only the diff --git a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp index 3dc110298a..55139ff99a 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp @@ -1650,6 +1650,7 @@ void tst_QGraphicsView::itemsInRect_cosmeticAdjust() QVERIFY(QTest::qWaitForWindowActive(&view)); QTRY_VERIFY(rect->numPaints > 0); + QCoreApplication::processEvents(); // Process all queued paint events rect->numPaints = 0; if (updateRect.isNull()) view.viewport()->update(); diff --git a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp index 8c93df9073..adb2c54751 100644 --- a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp +++ b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp @@ -3368,6 +3368,7 @@ void tst_QTreeWidget::setChildIndicatorPolicy() treeWidget.setItemDelegate(&delegate); treeWidget.show(); QVERIFY(QTest::qWaitForWindowExposed(&treeWidget)); + QCoreApplication::processEvents(); // Process all queued paint events QTreeWidgetItem *item = new QTreeWidgetItem(QStringList("Hello")); treeWidget.insertTopLevelItem(0, item); From 8551b7d93ce3767b2cebb0d442e72d8ad450539e Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Thu, 20 Dec 2018 09:51:30 +0100 Subject: [PATCH 0828/1650] QSQL: cleanup/modernize PostgreSQL plugin Cleanup/modernize the PostgreSQL plugin - use nullptr - use range-based for loop - use QStringLiteral or QByteArray::fromRawData instead QLatin1String/QString::fromLatin1 where possible - use QRegularExpression instead QRegExp - use QQueue instead QList - uppercase SQL keywords Change-Id: Ie22be1538328ff1e2b663066ede96741d271e050 Reviewed-by: Andy Shaw --- src/plugins/sqldrivers/psql/main.cpp | 8 +- src/plugins/sqldrivers/psql/qsql_psql.cpp | 167 ++++++++++++---------- src/plugins/sqldrivers/psql/qsql_psql_p.h | 4 +- 3 files changed, 94 insertions(+), 85 deletions(-) diff --git a/src/plugins/sqldrivers/psql/main.cpp b/src/plugins/sqldrivers/psql/main.cpp index c5d546f6ff..a0862a238a 100644 --- a/src/plugins/sqldrivers/psql/main.cpp +++ b/src/plugins/sqldrivers/psql/main.cpp @@ -61,11 +61,9 @@ QPSQLDriverPlugin::QPSQLDriverPlugin() QSqlDriver* QPSQLDriverPlugin::create(const QString &name) { - if (name == QLatin1String("QPSQL") || name == QLatin1String("QPSQL7")) { - QPSQLDriver* driver = new QPSQLDriver(); - return driver; - } - return 0; + if (name == QLatin1String("QPSQL") || name == QLatin1String("QPSQL7")) + return new QPSQLDriver; + return nullptr; } QT_END_NAMESPACE diff --git a/src/plugins/sqldrivers/psql/qsql_psql.cpp b/src/plugins/sqldrivers/psql/qsql_psql.cpp index 7ad9db1ea8..9fc9317da6 100644 --- a/src/plugins/sqldrivers/psql/qsql_psql.cpp +++ b/src/plugins/sqldrivers/psql/qsql_psql.cpp @@ -42,7 +42,7 @@ #include #include #include -#include +#include #include #include #include @@ -54,6 +54,8 @@ #include #include +#include + #include #include @@ -147,10 +149,10 @@ class QPSQLDriverPrivate final : public QSqlDriverPrivate Q_DECLARE_PUBLIC(QPSQLDriver) public: QPSQLDriverPrivate() : QSqlDriverPrivate(), - connection(0), + connection(nullptr), isUtf8(false), pro(QPSQLDriver::Version6), - sn(0), + sn(nullptr), pendingNotifyCheck(false), hasBackslashEscape(false), stmtCount(0), @@ -187,11 +189,13 @@ public: void QPSQLDriverPrivate::appendTables(QStringList &tl, QSqlQuery &t, QChar type) { - QString query = QString::fromLatin1("select pg_class.relname, pg_namespace.nspname from pg_class " - "left join pg_namespace on (pg_class.relnamespace = pg_namespace.oid) " - "where (pg_class.relkind = '%1') and (pg_class.relname !~ '^Inv') " - "and (pg_class.relname !~ '^pg_') " - "and (pg_namespace.nspname != 'information_schema')").arg(type); + const QString query = + QStringLiteral("SELECT pg_class.relname, pg_namespace.nspname FROM pg_class " + "LEFT JOIN pg_namespace ON (pg_class.relnamespace = pg_namespace.oid) " + "WHERE (pg_class.relkind = '") + type + + QStringLiteral("') AND (pg_class.relname !~ '^Inv') " + "AND (pg_class.relname !~ '^pg_') " + "AND (pg_namespace.nspname != 'information_schema')"); t.exec(query); while (t.next()) { QString schema = t.value(1).toString(); @@ -294,10 +298,10 @@ public: Q_DECLARE_SQLDRIVER_PRIVATE(QPSQLDriver) QPSQLResultPrivate(QPSQLResult *q, const QPSQLDriver *drv) : QSqlResultPrivate(q, drv), - result(0), + result(nullptr), + stmtId(InvalidStatementId), currentSize(-1), canFetchMoreRows(false), - stmtId(InvalidStatementId), preparedQueriesEnabled(false) { } @@ -305,12 +309,12 @@ public: void deallocatePreparedStmt(); PGresult *result; - QList nextResultSets; + std::queue nextResultSets; + QString preparedStmtId; + StatementId stmtId; int currentSize; bool canFetchMoreRows; - StatementId stmtId; bool preparedQueriesEnabled; - QString preparedStmtId; bool processResults(); }; @@ -423,7 +427,7 @@ static QVariant::Type qDecodePSQLType(int t) void QPSQLResultPrivate::deallocatePreparedStmt() { - const QString stmt = QLatin1String("DEALLOCATE ") + preparedStmtId; + const QString stmt = QStringLiteral("DEALLOCATE ") + preparedStmtId; PGresult *result = drv_d_func()->exec(stmt); if (PQresultStatus(result) != PGRES_COMMAND_OK) @@ -460,8 +464,10 @@ void QPSQLResult::cleanup() if (d->result) PQclear(d->result); d->result = nullptr; - while (!d->nextResultSets.isEmpty()) - PQclear(d->nextResultSets.takeFirst()); + while (!d->nextResultSets.empty()) { + PQclear(d->nextResultSets.front()); + d->nextResultSets.pop(); + } if (d->stmtId != InvalidStatementId) { if (d->drv_d_func()) d->drv_d_func()->finishQuery(d->stmtId); @@ -622,7 +628,11 @@ bool QPSQLResult::nextResult() if (d->result) PQclear(d->result); - d->result = d->nextResultSets.isEmpty() ? nullptr : d->nextResultSets.takeFirst(); + d->result = nullptr; + if (!d->nextResultSets.empty()) { + d->result = d->nextResultSets.front(); + d->nextResultSets.pop(); + } return d->processResults(); } @@ -646,9 +656,9 @@ QVariant QPSQLResult::data(int i) return d->drv_d_func()->isUtf8 ? QString::fromUtf8(val) : QString::fromLatin1(val); case QVariant::LongLong: if (val[0] == '-') - return QString::fromLatin1(val).toLongLong(); + return QByteArray::fromRawData(val, qstrlen(val)).toLongLong(); else - return QString::fromLatin1(val).toULongLong(); + return QByteArray::fromRawData(val, qstrlen(val)).toULongLong(); case QVariant::Int: return atoi(val); case QVariant::Double: { @@ -754,7 +764,7 @@ bool QPSQLResult::reset (const QString& query) if (!isForwardOnly()) { // Fetch all result sets right away while (PGresult *nextResultSet = d->drv_d_func()->getResult(d->stmtId)) - d->nextResultSets.append(nextResultSet); + d->nextResultSets.push(nextResultSet); } return d->processResults(); } @@ -768,7 +778,8 @@ int QPSQLResult::size() int QPSQLResult::numRowsAffected() { Q_D(const QPSQLResult); - return QString::fromLatin1(PQcmdTuples(d->result)).toInt(); + const char *tuples = PQcmdTuples(d->result); + return QByteArray::fromRawData(tuples, qstrlen(tuples)).toInt(); } QVariant QPSQLResult::lastInsertId() const @@ -777,7 +788,7 @@ QVariant QPSQLResult::lastInsertId() const if (d->drv_d_func()->pro >= QPSQLDriver::Version8_1) { QSqlQuery qry(driver()->createResult()); // Most recent sequence value obtained from nextval - if (qry.exec(QLatin1String("SELECT lastval();")) && qry.next()) + if (qry.exec(QStringLiteral("SELECT lastval();")) && qry.next()) return qry.value(0); } else if (isActive()) { Oid id = PQoidValue(d->result); @@ -868,15 +879,13 @@ static QString qCreateParamString(const QVector &boundValues, const QS QString params; QSqlField f; - for (int i = 0; i < boundValues.count(); ++i) { - const QVariant &val = boundValues.at(i); - + for (const QVariant &val : boundValues) { f.setType(val.type()); if (val.isNull()) f.clear(); else f.setValue(val); - if(!params.isNull()) + if (!params.isNull()) params.append(QLatin1String(", ")); params.append(driver->formatValue(f)); } @@ -886,7 +895,7 @@ static QString qCreateParamString(const QVector &boundValues, const QS QString qMakePreparedStmtId() { static QBasicAtomicInt qPreparedStmtCount = Q_BASIC_ATOMIC_INITIALIZER(0); - QString id = QLatin1String("qpsqlpstmt_") + QString::number(qPreparedStmtCount.fetchAndAddRelaxed(1) + 1, 16); + QString id = QStringLiteral("qpsqlpstmt_") + QString::number(qPreparedStmtCount.fetchAndAddRelaxed(1) + 1, 16); return id; } @@ -902,7 +911,7 @@ bool QPSQLResult::prepare(const QString &query) d->deallocatePreparedStmt(); const QString stmtId = qMakePreparedStmtId(); - const QString stmt = QString::fromLatin1("PREPARE %1 AS ").arg(stmtId).append(d->positionalToNamedBinding(query)); + const QString stmt = QStringLiteral("PREPARE %1 AS ").arg(stmtId).append(d->positionalToNamedBinding(query)); PGresult *result = d->drv_d_func()->exec(stmt); @@ -930,9 +939,9 @@ bool QPSQLResult::exec() QString stmt; const QString params = qCreateParamString(boundValues(), driver()); if (params.isEmpty()) - stmt = QString::fromLatin1("EXECUTE %1").arg(d->preparedStmtId); + stmt = QStringLiteral("EXECUTE %1").arg(d->preparedStmtId); else - stmt = QString::fromLatin1("EXECUTE %1 (%2)").arg(d->preparedStmtId, params); + stmt = QStringLiteral("EXECUTE %1 (%2)").arg(d->preparedStmtId, params); d->stmtId = d->drv_d_func()->sendQuery(stmt); if (d->stmtId == InvalidStatementId) { @@ -948,7 +957,7 @@ bool QPSQLResult::exec() if (!isForwardOnly()) { // Fetch all result sets right away while (PGresult *nextResultSet = d->drv_d_func()->getResult(d->stmtId)) - d->nextResultSets.append(nextResultSet); + d->nextResultSets.push(nextResultSet); } return d->processResults(); } @@ -994,7 +1003,7 @@ void QPSQLDriverPrivate::detectBackslashEscape() hasBackslashEscape = true; } else { hasBackslashEscape = false; - PGresult* result = exec(QLatin1String("SELECT '\\\\' x")); + PGresult* result = exec(QStringLiteral("SELECT '\\\\' x")); int status = PQresultStatus(result); if (status == PGRES_COMMAND_OK || status == PGRES_TUPLES_OK) if (QString::fromLatin1(PQgetvalue(result, 0, 0)) == QLatin1String("\\")) @@ -1072,20 +1081,21 @@ static QPSQLDriver::Protocol qMakePSQLVersion(int vMaj, int vMin) static QPSQLDriver::Protocol qFindPSQLVersion(const QString &versionString) { - const QRegExp rx(QStringLiteral("(\\d+)(?:\\.(\\d+))?")); - if (rx.indexIn(versionString) != -1) { + const QRegularExpression rx(QStringLiteral("(\\d+)(?:\\.(\\d+))?")); + const QRegularExpressionMatch match = rx.match(versionString); + if (match.hasMatch()) { // Beginning with PostgreSQL version 10, a major release is indicated by // increasing the first part of the version, e.g. 10 to 11. // Before version 10, a major release was indicated by increasing either // the first or second part of the version number, e.g. 9.5 to 9.6. - int vMaj = rx.cap(1).toInt(); + int vMaj = match.capturedRef(1).toInt(); int vMin; if (vMaj >= 10) { vMin = 0; } else { - if (rx.cap(2).isEmpty()) + if (match.capturedRef(2).isEmpty()) return QPSQLDriver::VersionUnknown; - vMin = rx.cap(2).toInt(); + vMin = match.capturedRef(2).toInt(); } return qMakePSQLVersion(vMaj, vMin); } @@ -1096,7 +1106,7 @@ static QPSQLDriver::Protocol qFindPSQLVersion(const QString &versionString) QPSQLDriver::Protocol QPSQLDriverPrivate::getPSQLVersion() { QPSQLDriver::Protocol serverVersion = QPSQLDriver::Version6; - PGresult* result = exec("select version()"); + PGresult* result = exec("SELECT version()"); int status = PQresultStatus(result); if (status == PGRES_COMMAND_OK || status == PGRES_TUPLES_OK) { serverVersion = qFindPSQLVersion( @@ -1355,8 +1365,8 @@ QStringList QPSQLDriver::tables(QSql::TableType type) const if (type & QSql::Views) const_cast(d)->appendTables(tl, t, QLatin1Char('v')); if (type & QSql::SystemTables) { - t.exec(QLatin1String("select relname from pg_class where (relkind = 'r') " - "and (relname like 'pg_%') ")); + t.exec(QStringLiteral("SELECT relname FROM pg_class WHERE (relkind = 'r') " + "AND (relname LIKE 'pg_%') ")); while (t.next()) tl.append(t.value(0).toString()); } @@ -1394,20 +1404,20 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const else schema = std::move(schema).toLower(); - QString stmt = QLatin1String("SELECT pg_attribute.attname, pg_attribute.atttypid::int, " - "pg_class.relname " - "FROM pg_attribute, pg_class " - "WHERE %1 pg_class.oid IN " - "(SELECT indexrelid FROM pg_index WHERE indisprimary = true AND indrelid IN " - "(SELECT oid FROM pg_class WHERE relname = '%2')) " - "AND pg_attribute.attrelid = pg_class.oid " - "AND pg_attribute.attisdropped = false " - "ORDER BY pg_attribute.attnum"); + QString stmt = QStringLiteral("SELECT pg_attribute.attname, pg_attribute.atttypid::int, " + "pg_class.relname " + "FROM pg_attribute, pg_class " + "WHERE %1 pg_class.oid IN " + "(SELECT indexrelid FROM pg_index WHERE indisprimary = true AND indrelid IN " + "(SELECT oid FROM pg_class WHERE relname = '%2')) " + "AND pg_attribute.attrelid = pg_class.oid " + "AND pg_attribute.attisdropped = false " + "ORDER BY pg_attribute.attnum"); if (schema.isEmpty()) - stmt = stmt.arg(QLatin1String("pg_table_is_visible(pg_class.oid) AND")); + stmt = stmt.arg(QStringLiteral("pg_table_is_visible(pg_class.oid) AND")); else - stmt = stmt.arg(QString::fromLatin1("pg_class.relnamespace = (select oid from " - "pg_namespace where pg_namespace.nspname = '%1') AND").arg(schema)); + stmt = stmt.arg(QStringLiteral("pg_class.relnamespace = (SELECT oid FROM " + "pg_namespace WHERE pg_namespace.nspname = '%1') AND").arg(schema)); i.exec(stmt.arg(tbl)); while (i.isActive() && i.next()) { @@ -1438,23 +1448,23 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const else schema = std::move(schema).toLower(); - QString stmt = QLatin1String("select pg_attribute.attname, pg_attribute.atttypid::int, " - "pg_attribute.attnotnull, pg_attribute.attlen, pg_attribute.atttypmod, " - "pg_attrdef.adsrc " - "from pg_class, pg_attribute " - "left join pg_attrdef on (pg_attrdef.adrelid = " - "pg_attribute.attrelid and pg_attrdef.adnum = pg_attribute.attnum) " - "where %1 " - "and pg_class.relname = '%2' " - "and pg_attribute.attnum > 0 " - "and pg_attribute.attrelid = pg_class.oid " - "and pg_attribute.attisdropped = false " - "order by pg_attribute.attnum"); + QString stmt = QStringLiteral("SELECT pg_attribute.attname, pg_attribute.atttypid::int, " + "pg_attribute.attnotnull, pg_attribute.attlen, pg_attribute.atttypmod, " + "pg_attrdef.adsrc " + "FROM pg_class, pg_attribute " + "LEFT JOIN pg_attrdef ON (pg_attrdef.adrelid = " + "pg_attribute.attrelid AND pg_attrdef.adnum = pg_attribute.attnum) " + "WHERE %1 " + "AND pg_class.relname = '%2' " + "AND pg_attribute.attnum > 0 " + "AND pg_attribute.attrelid = pg_class.oid " + "AND pg_attribute.attisdropped = false " + "ORDER BY pg_attribute.attnum"); if (schema.isEmpty()) - stmt = stmt.arg(QLatin1String("pg_table_is_visible(pg_class.oid)")); + stmt = stmt.arg(QStringLiteral("pg_table_is_visible(pg_class.oid)")); else - stmt = stmt.arg(QString::fromLatin1("pg_class.relnamespace = (select oid from " - "pg_namespace where pg_namespace.nspname = '%1')").arg(schema)); + stmt = stmt.arg(QStringLiteral("pg_class.relnamespace = (SELECT oid FROM " + "pg_namespace WHERE pg_namespace.nspname = '%1')").arg(schema)); QSqlQuery query(createResult()); query.exec(stmt.arg(tbl)); @@ -1496,9 +1506,10 @@ inline void assignSpecialPsqlFloatValue(FloatType val, QString *target) QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const { Q_D(const QPSQLDriver); + const auto nullStr = [](){ return QStringLiteral("NULL"); }; QString r; if (field.isNull()) { - r = QLatin1String("NULL"); + r = nullStr(); } else { switch (int(field.type())) { case QVariant::DateTime: @@ -1507,14 +1518,14 @@ QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const // we force the value to be considered with a timezone information, and we force it to be UTC // this is safe since postgresql stores only the UTC value and not the timezone offset (only used // while parsing), so we have correct behavior in both case of with timezone and without tz - r = QLatin1String("TIMESTAMP WITH TIME ZONE ") + QLatin1Char('\'') + - QLocale::c().toString(field.value().toDateTime().toUTC(), QLatin1String("yyyy-MM-ddThh:mm:ss.zzz")) + + r = QStringLiteral("TIMESTAMP WITH TIME ZONE ") + QLatin1Char('\'') + + QLocale::c().toString(field.value().toDateTime().toUTC(), QStringLiteral("yyyy-MM-ddThh:mm:ss.zzz")) + QLatin1Char('Z') + QLatin1Char('\''); } else { - r = QLatin1String("NULL"); + r = nullStr(); } #else - r = QLatin1String("NULL"); + r = nullStr(); #endif // datestring break; case QVariant::Time: @@ -1524,19 +1535,19 @@ QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const } else #endif { - r = QLatin1String("NULL"); + r = nullStr(); } break; case QVariant::String: r = QSqlDriver::formatValue(field, trimStrings); if (d->hasBackslashEscape) - r.replace(QLatin1String("\\"), QLatin1String("\\\\")); + r.replace(QLatin1Char('\\'), QLatin1String("\\\\")); break; case QVariant::Bool: if (field.value().toBool()) - r = QLatin1String("TRUE"); + r = QStringLiteral("TRUE"); else - r = QLatin1String("FALSE"); + r = QStringLiteral("FALSE"); break; case QVariant::ByteArray: { QByteArray ba(field.value().toByteArray()); @@ -1615,7 +1626,7 @@ bool QPSQLDriver::subscribeToNotification(const QString &name) // Add the name to the list of subscriptions here so that QSQLDriverPrivate::exec knows // to check for notifications immediately after executing the LISTEN d->seid << name; - QString query = QLatin1String("LISTEN ") + escapeIdentifier(name, QSqlDriver::TableName); + QString query = QStringLiteral("LISTEN ") + escapeIdentifier(name, QSqlDriver::TableName); PGresult *result = d->exec(query); if (PQresultStatus(result) != PGRES_COMMAND_OK) { d->seid.removeLast(); @@ -1651,7 +1662,7 @@ bool QPSQLDriver::unsubscribeFromNotification(const QString &name) return false; } - QString query = QLatin1String("UNLISTEN ") + escapeIdentifier(name, QSqlDriver::TableName); + QString query = QStringLiteral("UNLISTEN ") + escapeIdentifier(name, QSqlDriver::TableName); PGresult *result = d->exec(query); if (PQresultStatus(result) != PGRES_COMMAND_OK) { setLastError(qMakeError(tr("Unable to unsubscribe"), QSqlError::StatementError, d, result)); diff --git a/src/plugins/sqldrivers/psql/qsql_psql_p.h b/src/plugins/sqldrivers/psql/qsql_psql_p.h index 7e1849d857..4f372346c6 100644 --- a/src/plugins/sqldrivers/psql/qsql_psql_p.h +++ b/src/plugins/sqldrivers/psql/qsql_psql_p.h @@ -96,8 +96,8 @@ public: UnknownLaterVersion = 100000 }; - explicit QPSQLDriver(QObject *parent=0); - explicit QPSQLDriver(PGconn *conn, QObject *parent=0); + explicit QPSQLDriver(QObject *parent = nullptr); + explicit QPSQLDriver(PGconn *conn, QObject *parent = nullptr); ~QPSQLDriver(); bool hasFeature(DriverFeature f) const override; bool open(const QString & db, From c8c5ff19de1c34a99b8315e59015d115957b3584 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 8 Jan 2019 12:06:26 -0800 Subject: [PATCH 0829/1650] Add AVX2 version of the ARGB32->RGBA64PM code Change-Id: I251f00d706d646ed87b4fffd1577f84854e358a4 Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qdrawhelper.cpp | 9 ++ src/gui/painting/qdrawhelper_avx2.cpp | 134 ++++++++++++++++++++++++++ 2 files changed, 143 insertions(+) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index cdf5826672..f1c0852d82 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -6579,6 +6579,15 @@ static void qInitDrawhelperFunctions() bilinearFastTransformHelperARGB32PM[0][SimpleScaleTransform] = fetchTransformedBilinearARGB32PM_simple_scale_helper_avx2; bilinearFastTransformHelperARGB32PM[0][DownscaleTransform] = fetchTransformedBilinearARGB32PM_downscale_helper_avx2; bilinearFastTransformHelperARGB32PM[0][FastRotateTransform] = fetchTransformedBilinearARGB32PM_fast_rotate_helper_avx2; + + extern const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_avx2(QRgba64 *, const uint *, int, const QVector *, QDitherInfo *); + extern const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_avx2(QRgba64 *, const uint *, int count, const QVector *, QDitherInfo *); + extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_avx2(QRgba64 *, const uchar *, int, int, const QVector *, QDitherInfo *); + extern const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_avx2(QRgba64 *, const uchar *, int, int, const QVector *, QDitherInfo *); + qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_avx2; + qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_avx2; + qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_avx2; + qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_avx2; } #endif diff --git a/src/gui/painting/qdrawhelper_avx2.cpp b/src/gui/painting/qdrawhelper_avx2.cpp index 2e36f538bd..7829e476e5 100644 --- a/src/gui/painting/qdrawhelper_avx2.cpp +++ b/src/gui/painting/qdrawhelper_avx2.cpp @@ -995,6 +995,140 @@ void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper_avx2(uint * } } +template +static void convertARGBToRGBA64PM_avx2(QRgba64 *buffer, const uint *src, qsizetype count) +{ + qsizetype i = 0; + const __m256i alphaMask = _mm256_broadcastsi128_si256(_mm_set1_epi32(0xff000000)); + const __m256i rgbaMask = _mm256_broadcastsi128_si256(_mm_setr_epi8(2, 1, 0, 3, 6, 5, 4, 7, 10, 9, 8, 11, 14, 13, 12, 15)); + const __m256i shuffleMask = _mm256_broadcastsi128_si256(_mm_setr_epi8(6, 7, 6, 7, 6, 7, 6, 7, 14, 15, 14, 15, 14, 15, 14, 15)); + const __m256i zero = _mm256_setzero_si256(); + + for (; i < count - 7; i += 8) { + __m256i src1, src2; + __m256i srcVector = _mm256_loadu_si256(reinterpret_cast(src + i)); + if (!_mm256_testz_si256(srcVector, alphaMask)) { + if (!_mm256_testc_si256(srcVector, alphaMask)) { + if (!RGBA) + srcVector = _mm256_shuffle_epi8(srcVector, rgbaMask); + src1 = _mm256_unpacklo_epi8(srcVector, zero); + src2 = _mm256_unpackhi_epi8(srcVector, zero); + __m256i alpha1 = _mm256_shuffle_epi8(src1, shuffleMask); + __m256i alpha2 = _mm256_shuffle_epi8(src2, shuffleMask); + src1 = _mm256_mullo_epi16(src1, alpha1); + src2 = _mm256_mullo_epi16(src2, alpha2); + alpha1 = _mm256_unpacklo_epi8(srcVector, srcVector); + alpha2 = _mm256_unpackhi_epi8(srcVector, srcVector); + src1 = _mm256_add_epi16(src1, _mm256_srli_epi16(src1, 7)); + src2 = _mm256_add_epi16(src2, _mm256_srli_epi16(src2, 7)); + src1 = _mm256_blend_epi16(src1, alpha1, 0x88); + src2 = _mm256_blend_epi16(src2, alpha2, 0x88); + } else { + if (!RGBA) + srcVector = _mm256_shuffle_epi8(srcVector, rgbaMask); + src1 = _mm256_unpacklo_epi8(srcVector, srcVector); + src2 = _mm256_unpackhi_epi8(srcVector, srcVector); + } + } else { + src1 = src2 = zero; + } + _mm256_storeu_si256(reinterpret_cast<__m256i *>(buffer + i), src1); + _mm256_storeu_si256(reinterpret_cast<__m256i *>(buffer + i) + 1, src2); + } + + if (i < count - 3) { + __m128i srcVector = _mm_loadu_si128(reinterpret_cast(src + i)); + __m256i src; + if (!_mm_testz_si128(srcVector, _mm256_castsi256_si128(alphaMask))) { + if (!_mm_testc_si128(srcVector, _mm256_castsi256_si128(alphaMask))) { + if (!RGBA) + srcVector = _mm_shuffle_epi8(srcVector, _mm256_castsi256_si128(rgbaMask)); + src = _mm256_cvtepu8_epi16(srcVector); + __m256i alpha = _mm256_shuffle_epi8(src, shuffleMask); + src = _mm256_mullo_epi16(src, alpha); + + __m128i alpha1 = _mm_unpacklo_epi8(srcVector, srcVector); + __m128i alpha2 = _mm_unpackhi_epi8(srcVector, srcVector); + alpha = _mm256_inserti128_si256(_mm256_castsi128_si256(alpha1), alpha2, 1); + src = _mm256_add_epi16(src, _mm256_srli_epi16(src, 7)); + src = _mm256_blend_epi16(src, alpha, 0x88); + } else { + if (!RGBA) + srcVector = _mm_shuffle_epi8(srcVector, _mm256_castsi256_si128(rgbaMask)); + const __m128i src1 = _mm_unpacklo_epi8(srcVector, srcVector); + const __m128i src2 = _mm_unpackhi_epi8(srcVector, srcVector); + src = _mm256_castsi128_si256(src1); + src = _mm256_inserti128_si256(src, src2, 1); + } + } else { + src = zero; + } + _mm256_storeu_si256(reinterpret_cast<__m256i *>(buffer + i), src); + i += 4; + } + + auto convert_half = [=](__m128i &srcVector) { + if (!_mm_testz_si128(srcVector, _mm256_castsi256_si128(alphaMask))) { + if (!_mm_testc_si128(srcVector, _mm256_castsi256_si128(alphaMask))) { + if (!RGBA) + srcVector = _mm_shuffle_epi8(srcVector, _mm256_castsi256_si128(rgbaMask)); + __m128i src1 = _mm_unpacklo_epi8(srcVector, _mm256_castsi256_si128(zero)); + __m128i alpha1 = _mm_shuffle_epi8(src1, _mm256_castsi256_si128(shuffleMask)); + src1 = _mm_mullo_epi16(src1, alpha1); + alpha1 = _mm_unpacklo_epi8(srcVector, srcVector); + src1 = _mm_add_epi16(src1, _mm_srli_epi16(src1, 7)); + src1 = _mm_blend_epi16(src1, alpha1, 0x88); + return src1; + } else { + if (!RGBA) + srcVector = _mm_shuffle_epi8(srcVector, _mm256_castsi256_si128(rgbaMask)); + const __m128i src1 = _mm_unpacklo_epi8(srcVector, srcVector); + return src1; + } + } else { + return _mm256_castsi256_si128(zero); + } + }; + if (i < count - 1) { + __m128i srcVector = _mm_loadl_epi64(reinterpret_cast(src + i)); + _mm_storeu_si128(reinterpret_cast<__m128i *>(buffer + i), convert_half(srcVector)); + i += 2; + } + + if (i != count) { + __m128i srcVector = _mm_cvtsi32_si128(src[i]); + _mm_storel_epi64(reinterpret_cast<__m128i *>(buffer + i), convert_half(srcVector)); + } +} + +const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_avx2(QRgba64 *buffer, const uint *src, int count, + const QVector *, QDitherInfo *) +{ + convertARGBToRGBA64PM_avx2(buffer, src, count); + return buffer; +} + +const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_avx2(QRgba64 *buffer, const uint *src, int count, + const QVector *, QDitherInfo *) +{ + convertARGBToRGBA64PM_avx2(buffer, src, count); + return buffer; +} + +const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_avx2(QRgba64 *buffer, const uchar *src, int index, int count, + const QVector *, QDitherInfo *) +{ + convertARGBToRGBA64PM_avx2(buffer, reinterpret_cast(src) + index, count); + return buffer; +} + +const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_avx2(QRgba64 *buffer, const uchar *src, int index, int count, + const QVector *, QDitherInfo *) +{ + convertARGBToRGBA64PM_avx2(buffer, reinterpret_cast(src) + index, count); + return buffer; +} + QT_END_NAMESPACE #endif From f370410097f8cb8d8fdf6174b799497fe7fe0adf Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 8 Jan 2019 12:27:31 -0800 Subject: [PATCH 0830/1650] Add AVX2 version of ARGB->ARGB32PM Similar to the previous commit. This also removes the SSE4 implementations from Qt builds that use AVX2 throughout. Change-Id: I251f00d706d646ed87b4fffd1577f96ed52a4cf4 Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qdrawhelper.cpp | 17 +++- src/gui/painting/qdrawhelper_avx2.cpp | 138 ++++++++++++++++++++++++++ src/gui/painting/qdrawhelper_sse4.cpp | 4 + 3 files changed, 157 insertions(+), 2 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index f1c0852d82..2dd18f6dfc 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -6514,18 +6514,20 @@ static void qInitDrawhelperFunctions() const QVector *, QDitherInfo *); extern void QT_FASTCALL destStore64ARGB32_sse4(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length); extern void QT_FASTCALL destStore64RGBA8888_sse4(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 *buffer, int length); +# ifndef __AVX2__ qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_sse4; qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_sse4; qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_sse4; qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_sse4; qPixelLayouts[QImage::Format_ARGB32].fetchToRGBA64PM = fetchARGB32ToRGBA64PM_sse4; qPixelLayouts[QImage::Format_ARGB32].convertToRGBA64PM = convertARGB32ToRGBA64PM_sse4; - qPixelLayouts[QImage::Format_ARGB32].storeFromARGB32PM = storeARGB32FromARGB32PM_sse4; qPixelLayouts[QImage::Format_RGBA8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_sse4; qPixelLayouts[QImage::Format_RGBA8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_sse4; - qPixelLayouts[QImage::Format_RGBA8888].storeFromARGB32PM = storeRGBA8888FromARGB32PM_sse4; qPixelLayouts[QImage::Format_RGBX8888].fetchToRGBA64PM = fetchRGBA8888ToRGBA64PM_sse4; qPixelLayouts[QImage::Format_RGBX8888].convertToRGBA64PM = convertRGBA8888ToRGBA64PM_sse4; +# endif + qPixelLayouts[QImage::Format_ARGB32].storeFromARGB32PM = storeARGB32FromARGB32PM_sse4; + qPixelLayouts[QImage::Format_RGBA8888].storeFromARGB32PM = storeRGBA8888FromARGB32PM_sse4; qPixelLayouts[QImage::Format_RGBX8888].storeFromARGB32PM = storeRGBXFromARGB32PM_sse4; qPixelLayouts[QImage::Format_A2BGR30_Premultiplied].storeFromARGB32PM = storeA2RGB30PMFromARGB32PM_sse4; qPixelLayouts[QImage::Format_A2RGB30_Premultiplied].storeFromARGB32PM = storeA2RGB30PMFromARGB32PM_sse4; @@ -6580,6 +6582,17 @@ static void qInitDrawhelperFunctions() bilinearFastTransformHelperARGB32PM[0][DownscaleTransform] = fetchTransformedBilinearARGB32PM_downscale_helper_avx2; bilinearFastTransformHelperARGB32PM[0][FastRotateTransform] = fetchTransformedBilinearARGB32PM_fast_rotate_helper_avx2; + extern void QT_FASTCALL convertARGB32ToARGB32PM_avx2(uint *buffer, int count, const QVector *); + extern void QT_FASTCALL convertRGBA8888ToARGB32PM_avx2(uint *buffer, int count, const QVector *); + extern const uint *QT_FASTCALL fetchARGB32ToARGB32PM_avx2(uint *buffer, const uchar *src, int index, int count, + const QVector *, QDitherInfo *); + extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_avx2(uint *buffer, const uchar *src, int index, int count, + const QVector *, QDitherInfo *); + qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_avx2; + qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_avx2; + qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_avx2; + qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_avx2; + extern const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_avx2(QRgba64 *, const uint *, int, const QVector *, QDitherInfo *); extern const QRgba64 * QT_FASTCALL convertRGBA8888ToRGBA64PM_avx2(QRgba64 *, const uint *, int count, const QVector *, QDitherInfo *); extern const QRgba64 *QT_FASTCALL fetchARGB32ToRGBA64PM_avx2(QRgba64 *, const uchar *, int, int, const QVector *, QDitherInfo *); diff --git a/src/gui/painting/qdrawhelper_avx2.cpp b/src/gui/painting/qdrawhelper_avx2.cpp index 7829e476e5..d8732dc29f 100644 --- a/src/gui/painting/qdrawhelper_avx2.cpp +++ b/src/gui/painting/qdrawhelper_avx2.cpp @@ -995,6 +995,144 @@ void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper_avx2(uint * } } +template +static void convertARGBToARGB32PM_avx2(uint *buffer, const uint *src, qsizetype count) +{ + qsizetype i = 0; + const __m256i alphaMask = _mm256_set1_epi32(0xff000000); + const __m256i rgbaMask = _mm256_broadcastsi128_si256(_mm_setr_epi8(2, 1, 0, 3, 6, 5, 4, 7, 10, 9, 8, 11, 14, 13, 12, 15)); + const __m256i shuffleMask = _mm256_broadcastsi128_si256(_mm_setr_epi8(6, 7, 6, 7, 6, 7, 6, 7, 14, 15, 14, 15, 14, 15, 14, 15)); + const __m256i half = _mm256_set1_epi16(0x0080); + const __m256i zero = _mm256_setzero_si256(); + + for (; i < count - 7; i += 8) { + __m256i srcVector = _mm256_loadu_si256(reinterpret_cast(src + i)); + if (!_mm256_testz_si256(srcVector, alphaMask)) { + if (!_mm256_testc_si256(srcVector, alphaMask)) { + if (RGBA) + srcVector = _mm256_shuffle_epi8(srcVector, rgbaMask); + __m256i src1 = _mm256_unpacklo_epi8(srcVector, zero); + __m256i src2 = _mm256_unpackhi_epi8(srcVector, zero); + __m256i alpha1 = _mm256_shuffle_epi8(src1, shuffleMask); + __m256i alpha2 = _mm256_shuffle_epi8(src2, shuffleMask); + src1 = _mm256_mullo_epi16(src1, alpha1); + src2 = _mm256_mullo_epi16(src2, alpha2); + src1 = _mm256_add_epi16(src1, _mm256_srli_epi16(src1, 8)); + src2 = _mm256_add_epi16(src2, _mm256_srli_epi16(src2, 8)); + src1 = _mm256_add_epi16(src1, half); + src2 = _mm256_add_epi16(src2, half); + src1 = _mm256_srli_epi16(src1, 8); + src2 = _mm256_srli_epi16(src2, 8); + src1 = _mm256_blend_epi16(src1, alpha1, 0x88); + src2 = _mm256_blend_epi16(src2, alpha2, 0x88); + srcVector = _mm256_packus_epi16(src1, src2); + _mm256_storeu_si256(reinterpret_cast<__m256i *>(buffer + i), srcVector); + } else { + if (RGBA) + srcVector = _mm256_shuffle_epi8(srcVector, rgbaMask); + if (buffer != src || RGBA) + _mm256_storeu_si256(reinterpret_cast<__m256i *>(buffer + i), srcVector); + } + } else { + _mm256_storeu_si256(reinterpret_cast<__m256i *>(buffer + i), zero); + } + } + + if (i < count - 3) { + __m128i srcVector = _mm_loadu_si128(reinterpret_cast(src + i)); + if (!_mm_testz_si128(srcVector, _mm256_castsi256_si128(alphaMask))) { + if (!_mm_testc_si128(srcVector, _mm256_castsi256_si128(alphaMask))) { + if (RGBA) + srcVector = _mm_shuffle_epi8(srcVector, _mm256_castsi256_si128(rgbaMask)); + __m128i src1 = _mm_unpacklo_epi8(srcVector, _mm256_castsi256_si128(zero)); + __m128i src2 = _mm_unpackhi_epi8(srcVector, _mm256_castsi256_si128(zero)); + __m128i alpha1 = _mm_shuffle_epi8(src1, _mm256_castsi256_si128(shuffleMask)); + __m128i alpha2 = _mm_shuffle_epi8(src2, _mm256_castsi256_si128(shuffleMask)); + src1 = _mm_mullo_epi16(src1, alpha1); + src2 = _mm_mullo_epi16(src2, alpha2); + src1 = _mm_add_epi16(src1, _mm_srli_epi16(src1, 8)); + src2 = _mm_add_epi16(src2, _mm_srli_epi16(src2, 8)); + src1 = _mm_add_epi16(src1, _mm256_castsi256_si128(half)); + src2 = _mm_add_epi16(src2, _mm256_castsi256_si128(half)); + src1 = _mm_srli_epi16(src1, 8); + src2 = _mm_srli_epi16(src2, 8); + src1 = _mm_blend_epi16(src1, alpha1, 0x88); + src2 = _mm_blend_epi16(src2, alpha2, 0x88); + _mm_storeu_si128(reinterpret_cast<__m128i *>(buffer + i), srcVector); + } else { + if (RGBA) + srcVector = _mm_shuffle_epi8(srcVector, _mm256_castsi256_si128(rgbaMask)); + if (buffer != src || RGBA) + _mm_storeu_si128(reinterpret_cast<__m128i *>(buffer + i), srcVector); + } + } else { + _mm_storeu_si128(reinterpret_cast<__m128i *>(buffer + i), _mm256_castsi256_si128(zero)); + } + i += 4; + } + + auto convert_half = [=](__m128i &srcVector) { + if (!_mm_testz_si128(srcVector, _mm256_castsi256_si128(alphaMask))) { + if (!_mm_testc_si128(srcVector, _mm256_castsi256_si128(alphaMask))) { + if (RGBA) + srcVector = _mm_shuffle_epi8(srcVector, _mm256_castsi256_si128(rgbaMask)); + __m128i src1 = _mm_unpacklo_epi8(srcVector, _mm256_castsi256_si128(zero)); + __m128i alpha1 = _mm_shuffle_epi8(src1, _mm256_castsi256_si128(shuffleMask)); + src1 = _mm_mullo_epi16(src1, alpha1); + src1 = _mm_add_epi16(src1, _mm_srli_epi16(src1, 8)); + src1 = _mm_add_epi16(src1, _mm256_castsi256_si128(half)); + src1 = _mm_srli_epi16(src1, 8); + src1 = _mm_blend_epi16(src1, alpha1, 0x88); + srcVector = _mm_packus_epi16(src1, src1); + return true; + } else { + if (RGBA) + srcVector = _mm_shuffle_epi8(srcVector, _mm256_castsi256_si128(rgbaMask)); + return buffer != src || RGBA; + } + } else { + srcVector = _mm256_castsi256_si128(zero); + return true; + } + }; + if (i < count - 1) { + __m128i srcVector = _mm_loadl_epi64(reinterpret_cast(src + i)); + if (convert_half(srcVector)) + _mm_storel_epi64(reinterpret_cast<__m128i *>(buffer + i), srcVector); + i += 2; + } + + if (i != count) { + __m128i srcVector = _mm_cvtsi32_si128(src[i]); + if (convert_half(srcVector)) + buffer[i] = _mm_cvtsi128_si32(srcVector); + } +} + +void QT_FASTCALL convertARGB32ToARGB32PM_avx2(uint *buffer, int count, const QVector *) +{ + convertARGBToARGB32PM_avx2(buffer, buffer, count); +} + +void QT_FASTCALL convertRGBA8888ToARGB32PM_avx2(uint *buffer, int count, const QVector *) +{ + convertARGBToARGB32PM_avx2(buffer, buffer, count); +} + +const uint *QT_FASTCALL fetchARGB32ToARGB32PM_avx2(uint *buffer, const uchar *src, int index, int count, + const QVector *, QDitherInfo *) +{ + convertARGBToARGB32PM_avx2(buffer, reinterpret_cast(src) + index, count); + return buffer; +} + +const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_avx2(uint *buffer, const uchar *src, int index, int count, + const QVector *, QDitherInfo *) +{ + convertARGBToARGB32PM_avx2(buffer, reinterpret_cast(src) + index, count); + return buffer; +} + template static void convertARGBToRGBA64PM_avx2(QRgba64 *buffer, const uint *src, qsizetype count) { diff --git a/src/gui/painting/qdrawhelper_sse4.cpp b/src/gui/painting/qdrawhelper_sse4.cpp index 9e3e6682bb..e4b93e8511 100644 --- a/src/gui/painting/qdrawhelper_sse4.cpp +++ b/src/gui/painting/qdrawhelper_sse4.cpp @@ -45,6 +45,7 @@ QT_BEGIN_NAMESPACE +#ifndef __AVX2__ template static void convertARGBToARGB32PM_sse4(uint *buffer, const uint *src, int count) { @@ -142,6 +143,7 @@ static void convertARGBToRGBA64PM_sse4(QRgba64 *buffer, const uint *src, int cou buffer[i] = QRgba64::fromArgb32(s).premultiplied(); } } +#endif // __AVX2__ static inline __m128 Q_DECL_VECTORCALL reciprocal_mul_ps(__m128 a, float mul) { @@ -308,6 +310,7 @@ static inline void convertARGBFromRGBA64PM_sse4(uint *buffer, const QRgba64 *src } } +#ifndef __AVX2__ void QT_FASTCALL convertARGB32ToARGB32PM_sse4(uint *buffer, int count, const QVector *) { convertARGBToARGB32PM_sse4(buffer, buffer, count); @@ -359,6 +362,7 @@ const QRgba64 *QT_FASTCALL fetchRGBA8888ToRGBA64PM_sse4(QRgba64 *buffer, const u convertARGBToRGBA64PM_sse4(buffer, reinterpret_cast(src) + index, count); return buffer; } +#endif // __AVX2__ void QT_FASTCALL storeRGB32FromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count, const QVector *, QDitherInfo *) From 8c47c2a08ec69fe45a14f6c2334befcb2e074790 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 2 Nov 2018 15:20:43 +0100 Subject: [PATCH 0831/1650] uic: Refactor CustomWidgetsInfo::extends() Add a extendsOneOf() helper that takes a QStringList to be searched and simplify the code accordingly. In WriteInitialization::acceptWidget(), move the variable CustomWidgetsInfo *cwi up and reuse everywhere to shorten code. Task-number: PYSIDE-797 Change-Id: I331e135b6aa58dbbd413ca151eb67b3eb92f09c6 Reviewed-by: Jarek Kobus --- src/tools/uic/cpp/cppwriteincludes.cpp | 12 ++--- src/tools/uic/cpp/cppwriteinitialization.cpp | 54 ++++++++++++-------- src/tools/uic/customwidgetsinfo.cpp | 18 +++++++ src/tools/uic/customwidgetsinfo.h | 1 + src/tools/uic/uic.cpp | 32 +++++++----- 5 files changed, 75 insertions(+), 42 deletions(-) diff --git a/src/tools/uic/cpp/cppwriteincludes.cpp b/src/tools/uic/cpp/cppwriteincludes.cpp index 74546bb01d..0ba49627c0 100644 --- a/src/tools/uic/cpp/cppwriteincludes.cpp +++ b/src/tools/uic/cpp/cppwriteincludes.cpp @@ -214,14 +214,14 @@ void WriteIncludes::add(const QString &className, bool determineHeader, const QS m_knownClasses.insert(className); const CustomWidgetsInfo *cwi = m_uic->customWidgetsInfo(); - if (cwi->extends(className, QLatin1String("QTreeView")) - || cwi->extends(className, QLatin1String("QTreeWidget")) - || cwi->extends(className, QLatin1String("QTableView")) - || cwi->extends(className, QLatin1String("QTableWidget"))) { + static const QStringList treeViewsWithHeaders = { + QLatin1String("QTreeView"), QLatin1String("QTreeWidget"), + QLatin1String("QTableView"), QLatin1String("QTableWidget") + }; + if (cwi->extendsOneOf(className, treeViewsWithHeaders)) add(QLatin1String("QHeaderView")); - } - if (!m_laidOut && m_uic->customWidgetsInfo()->extends(className, QLatin1String("QToolBox"))) + if (!m_laidOut && cwi->extends(className, QLatin1String("QToolBox"))) add(QLatin1String("QLayout")); // spacing property of QToolBox) if (className == QLatin1String("Line")) { // ### hmm, deprecate me! diff --git a/src/tools/uic/cpp/cppwriteinitialization.cpp b/src/tools/uic/cpp/cppwriteinitialization.cpp index 9db20a5395..dbe4860d7e 100644 --- a/src/tools/uic/cpp/cppwriteinitialization.cpp +++ b/src/tools/uic/cpp/cppwriteinitialization.cpp @@ -608,18 +608,23 @@ void WriteInitialization::acceptWidget(DomWidget *node) if (m_uic->isContainer(parentClass)) parentWidget.clear(); - if (m_widgetChain.size() != 1) - m_output << m_indent << varName << " = new " << m_uic->customWidgetsInfo()->realClassName(className) << '(' << parentWidget << ");\n"; + const auto *cwi = m_uic->customWidgetsInfo(); + + if (m_widgetChain.size() != 1) { + m_output << m_indent << varName << " = new " << cwi->realClassName(className) + << '(' << parentWidget << ");\n"; + } parentWidget = savedParentWidget; - if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QComboBox"))) { + + if (cwi->extends(className, QLatin1String("QComboBox"))) { initializeComboBox(node); - } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QListWidget"))) { + } else if (cwi->extends(className, QLatin1String("QListWidget"))) { initializeListWidget(node); - } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTreeWidget"))) { + } else if (cwi->extends(className, QLatin1String("QTreeWidget"))) { initializeTreeWidget(node); - } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTableWidget"))) { + } else if (cwi->extends(className, QLatin1String("QTableWidget"))) { initializeTableWidget(node); } @@ -629,7 +634,7 @@ void WriteInitialization::acceptWidget(DomWidget *node) writeProperties(varName, className, node->elementProperty()); if (!parentWidget.isEmpty() - && m_uic->customWidgetsInfo()->extends(className, QLatin1String("QMenu"))) { + && cwi->extends(className, QLatin1String("QMenu"))) { initializeMenu(node, parentWidget); } @@ -657,10 +662,10 @@ void WriteInitialization::acceptWidget(DomWidget *node) const QString pageDefaultString = QLatin1String("Page"); - if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QMainWindow"))) { - if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QMenuBar"))) { + if (cwi->extends(parentClass, QLatin1String("QMainWindow"))) { + if (cwi->extends(className, QLatin1String("QMenuBar"))) { m_output << m_indent << parentWidget << "->setMenuBar(" << varName <<");\n"; - } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QToolBar"))) { + } else if (cwi->extends(className, QLatin1String("QToolBar"))) { m_output << m_indent << parentWidget << "->addToolBar(" << toolBarAreaStringFromDOMAttributes(attributes) << varName << ");\n"; @@ -670,7 +675,7 @@ void WriteInitialization::acceptWidget(DomWidget *node) } } - } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QDockWidget"))) { + } else if (cwi->extends(className, QLatin1String("QDockWidget"))) { m_output << m_indent << parentWidget << "->addDockWidget("; if (DomProperty *pstyle = attributes.value(QLatin1String("dockWidgetArea"))) m_output << "Qt::" << language::dockWidgetArea(pstyle->elementNumber()) << ", "; @@ -683,9 +688,9 @@ void WriteInitialization::acceptWidget(DomWidget *node) } // Check for addPageMethod of a custom plugin first - QString addPageMethod = m_uic->customWidgetsInfo()->customWidgetAddPageMethod(parentClass); + QString addPageMethod = cwi->customWidgetAddPageMethod(parentClass); if (addPageMethod.isEmpty()) - addPageMethod = m_uic->customWidgetsInfo()->simpleContainerAddPageMethod(parentClass); + addPageMethod = cwi->simpleContainerAddPageMethod(parentClass); if (!addPageMethod.isEmpty()) { m_output << m_indent << parentWidget << "->" << addPageMethod << '(' << varName << ");\n"; } else if (m_uic->customWidgetsInfo()->extends(parentClass, QLatin1String("QWizard"))) { @@ -753,8 +758,14 @@ void WriteInitialization::acceptWidget(DomWidget *node) QLatin1String("stretchLastSection"), }; - if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTreeView")) - || m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTreeWidget"))) { + static const QStringList trees = { + QLatin1String("QTreeView"), QLatin1String("QTreeWidget") + }; + static const QStringList tables = { + QLatin1String("QTableView"), QLatin1String("QTableWidget") + }; + + if (cwi->extendsOneOf(className, trees)) { DomPropertyList headerProperties; for (auto realPropertyName : realPropertyNames) { const QString fakePropertyName = QLatin1String("header") @@ -767,9 +778,7 @@ void WriteInitialization::acceptWidget(DomWidget *node) writeProperties(varName + QLatin1String("->header()"), QLatin1String("QHeaderView"), headerProperties, WritePropertyIgnoreObjectName); - } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTableView")) - || m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTableWidget"))) { - + } else if (cwi->extendsOneOf(className, tables)) { static const QLatin1String headerPrefixes[] = { QLatin1String("horizontalHeader"), QLatin1String("verticalHeader"), @@ -1166,11 +1175,12 @@ void WriteInitialization::writeProperties(const QString &varName, << p->elementNumber() << ");\n"; continue; } + static const QStringList currentIndexWidgets = { + QLatin1String("QComboBox"), QLatin1String("QStackedWidget"), + QLatin1String("QTabWidget"), QLatin1String("QToolBox") + }; if (propertyName == QLatin1String("currentIndex") // set currentIndex later - && (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QComboBox")) - || m_uic->customWidgetsInfo()->extends(className, QLatin1String("QStackedWidget")) - || m_uic->customWidgetsInfo()->extends(className, QLatin1String("QTabWidget")) - || m_uic->customWidgetsInfo()->extends(className, QLatin1String("QToolBox")))) { + && (m_uic->customWidgetsInfo()->extendsOneOf(className, currentIndexWidgets))) { m_delayedOut << m_indent << varName << "->setCurrentIndex(" << p->elementNumber() << ");\n"; continue; diff --git a/src/tools/uic/customwidgetsinfo.cpp b/src/tools/uic/customwidgetsinfo.cpp index 4afdf74d08..d6a409152b 100644 --- a/src/tools/uic/customwidgetsinfo.cpp +++ b/src/tools/uic/customwidgetsinfo.cpp @@ -75,6 +75,24 @@ bool CustomWidgetsInfo::extends(const QString &classNameIn, QLatin1String baseCl return false; } +bool CustomWidgetsInfo::extendsOneOf(const QString &classNameIn, + const QStringList &baseClassNames) const +{ + if (baseClassNames.contains(classNameIn)) + return true; + + QString className = classNameIn; + while (const DomCustomWidget *c = customWidget(className)) { + const QString extends = c->elementExtends(); + if (className == extends) // Faulty legacy custom widget entries exist. + return false; + if (baseClassNames.contains(extends)) + return true; + className = extends; + } + return false; +} + bool CustomWidgetsInfo::isCustomWidgetContainer(const QString &className) const { if (const DomCustomWidget *dcw = m_customWidgets.value(className, 0)) diff --git a/src/tools/uic/customwidgetsinfo.h b/src/tools/uic/customwidgetsinfo.h index a4278b1aca..8a10999027 100644 --- a/src/tools/uic/customwidgetsinfo.h +++ b/src/tools/uic/customwidgetsinfo.h @@ -57,6 +57,7 @@ public: QString realClassName(const QString &className) const; bool extends(const QString &className, QLatin1String baseClassName) const; + bool extendsOneOf(const QString &className, const QStringList &baseClassNames) const; bool isCustomWidgetContainer(const QString &className) const; diff --git a/src/tools/uic/uic.cpp b/src/tools/uic/uic.cpp index b426d33e5c..225dc6aeb2 100644 --- a/src/tools/uic/uic.cpp +++ b/src/tools/uic/uic.cpp @@ -245,28 +245,32 @@ void Uic::writeHeaderProtectionEnd() bool Uic::isButton(const QString &className) const { - return customWidgetsInfo()->extends(className, QLatin1String("QRadioButton")) - || customWidgetsInfo()->extends(className, QLatin1String("QToolButton")) - || customWidgetsInfo()->extends(className, QLatin1String("QCheckBox")) - || customWidgetsInfo()->extends(className, QLatin1String("QPushButton")) - || customWidgetsInfo()->extends(className, QLatin1String("QCommandLinkButton")); + static const QStringList buttons = { + QLatin1String("QRadioButton"), QLatin1String("QToolButton"), + QLatin1String("QCheckBox"), QLatin1String("QPushButton"), + QLatin1String("QCommandLinkButton") + }; + return customWidgetsInfo()->extendsOneOf(className, buttons); } bool Uic::isContainer(const QString &className) const { - return customWidgetsInfo()->extends(className, QLatin1String("QStackedWidget")) - || customWidgetsInfo()->extends(className, QLatin1String("QToolBox")) - || customWidgetsInfo()->extends(className, QLatin1String("QTabWidget")) - || customWidgetsInfo()->extends(className, QLatin1String("QScrollArea")) - || customWidgetsInfo()->extends(className, QLatin1String("QMdiArea")) - || customWidgetsInfo()->extends(className, QLatin1String("QWizard")) - || customWidgetsInfo()->extends(className, QLatin1String("QDockWidget")); + static const QStringList containers = { + QLatin1String("QStackedWidget"), QLatin1String("QToolBox"), + QLatin1String("QTabWidget"), QLatin1String("QScrollArea"), + QLatin1String("QMdiArea"), QLatin1String("QWizard"), + QLatin1String("QDockWidget") + }; + + return customWidgetsInfo()->extendsOneOf(className, containers); } bool Uic::isMenu(const QString &className) const { - return customWidgetsInfo()->extends(className, QLatin1String("QMenu")) - || customWidgetsInfo()->extends(className, QLatin1String("QPopupMenu")); + static const QStringList menus = { + QLatin1String("QMenu"), QLatin1String("QPopupMenu") + }; + return customWidgetsInfo()->extendsOneOf(className, menus); } QT_END_NAMESPACE From 574b56913f3d1ca6ad05617c32bd275807613c6b Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Mon, 7 Jan 2019 14:55:58 +0100 Subject: [PATCH 0832/1650] Doc: mention that some filtered events need to be explicitly accepted QKeyEvent's detailed description already documents this: "A key event contains a special accept flag that indicates whether the receiver will handle the key event. This flag is set by default for QEvent::KeyPress and QEvent::KeyRelease, so there is no need to call accept() when acting on a key event. For QEvent::ShortcutOverride the receiver needs to explicitly accept the event to trigger the override. Calling ignore() on a key event will propagate it to the parent widget. The event is propagated up the parent widget chain until a widget accepts it or an event filter consumes it." However, someone looking at eventFilter() won't see this, resulting in the shortcut not being consumed and propagating elsewhere, so mention it in the docs for eventFilter() too. Change-Id: I14fece52133be641ccdabd81f75706cd10b64669 Reviewed-by: Friedemann Kleint Reviewed-by: Venugopal Shivashankar Reviewed-by: Paul Wicking --- src/corelib/kernel/qobject.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 14af9ac8ef..b5d97c5538 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -1374,6 +1374,10 @@ void QObject::customEvent(QEvent * /* event */) might have reimplemented eventFilter() for its own internal purposes. + Some events, such as \l QEvent::ShortcutOverride must be explicitly + accepted (by calling \l {QEvent::}{accept()} on them) in order to prevent + propagation. + \warning If you delete the receiver object in this function, be sure to return true. Otherwise, Qt will forward the event to the deleted object and the program might crash. From 3eac688ec005833509bffc7097c378af9c5b515f Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 10 Jan 2019 08:46:52 +0100 Subject: [PATCH 0833/1650] Documentation: Add \nullptr macro and use where applicable Qt for Python users reading the documentation assume that int(0) can be passed for pointer parameters. Use the newly introduced \nullptr to disambiguate this. In a follow-up step, the \nullptr macro can be defined as None when generating the Qt for Python documentation. Task-number: PYSIDE-903 Change-Id: I3a45f87175a0668ab5f3f95f0aff409f7e3ef027 Reviewed-by: Cristian Maureira-Fredes Reviewed-by: Christian Tismer Reviewed-by: Venugopal Shivashankar Reviewed-by: Paul Wicking --- doc/global/macros.qdocconf | 1 + src/gui/accessible/qaccessible.cpp | 14 +++++++------- src/gui/image/qimage.cpp | 2 +- src/gui/itemmodels/qstandarditemmodel.cpp | 18 +++++++++--------- src/gui/kernel/qevent.cpp | 4 ++-- src/gui/kernel/qguiapplication.cpp | 2 +- src/gui/kernel/qopenglcontext.cpp | 2 +- src/gui/kernel/qplatformcursor.cpp | 2 +- src/gui/kernel/qplatformintegration.cpp | 2 +- src/gui/kernel/qplatformscreen.cpp | 2 +- src/gui/kernel/qwindow.cpp | 2 +- src/gui/painting/qpaintengine.cpp | 2 +- src/gui/text/qtextcursor.cpp | 6 +++--- src/gui/text/qtextobject.cpp | 2 +- src/network/access/qftp.cpp | 2 +- src/network/access/qnetworkrequest.cpp | 2 +- src/testlib/qtestcase.qdoc | 2 +- src/widgets/dialogs/qdialog.cpp | 2 +- src/widgets/dialogs/qprogressdialog.cpp | 2 +- src/widgets/effects/qgraphicseffect.cpp | 6 +++--- src/widgets/graphicsview/qgraphicsitem.cpp | 4 ++-- .../graphicsview/qgraphicslayoutitem.cpp | 2 +- .../itemviews/qabstractitemdelegate.cpp | 2 +- src/widgets/itemviews/qlistwidget.cpp | 4 ++-- src/widgets/itemviews/qtablewidget.cpp | 6 +++--- src/widgets/itemviews/qtreewidget.cpp | 2 +- src/widgets/kernel/qapplication.cpp | 6 +++--- src/widgets/kernel/qformlayout.cpp | 2 +- src/widgets/kernel/qwidget.cpp | 4 ++-- src/widgets/styles/qstylefactory.cpp | 2 +- src/widgets/util/qundogroup.cpp | 2 +- src/widgets/util/qundoview.cpp | 2 +- src/widgets/widgets/qabstractbutton.cpp | 2 +- src/widgets/widgets/qabstractspinbox.cpp | 2 +- src/widgets/widgets/qmenu.cpp | 2 +- src/widgets/widgets/qmenubar.cpp | 2 +- 36 files changed, 62 insertions(+), 61 deletions(-) diff --git a/doc/global/macros.qdocconf b/doc/global/macros.qdocconf index 704b1da277..ef3ca1dc1d 100644 --- a/doc/global/macros.qdocconf +++ b/doc/global/macros.qdocconf @@ -14,6 +14,7 @@ macro.macos = "macOS" macro.menu = "\\b" macro.oslash.HTML = "ø" macro.ouml.HTML = "ö" +macro.nullptr = "\\c{nullptr}" macro.QA = "\\e{Qt Assistant}" macro.QD = "\\e{Qt Designer}" macro.QL = "\\e{Qt Linguist}" diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index a3f53e149b..46dec7f28d 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -654,7 +654,7 @@ void QAccessible::removeActivationObserver(ActivationObserver *observer) /*! If a QAccessibleInterface implementation exists for the given \a object, this function returns a pointer to the implementation; otherwise it - returns 0. + returns \nullptr. The function calls all installed factory functions (from most recently installed to least recently installed) until one is found @@ -770,7 +770,7 @@ QAccessible::Id QAccessible::uniqueId(QAccessibleInterface *iface) /*! Returns the QAccessibleInterface belonging to the \a id. - Returns 0 if the id is invalid. + Returns \nullptr if the id is invalid. */ QAccessibleInterface *QAccessible::accessibleInterface(Id id) { @@ -1119,7 +1119,7 @@ QAccessibleInterface *QAccessibleInterface::focusChild() const \fn QAccessibleInterface *QAccessibleInterface::childAt(int x, int y) const Returns the QAccessibleInterface of a child that contains the screen coordinates (\a x, \a y). - If there are no children at this position this function returns 0. + If there are no children at this position this function returns \nullptr. The returned accessible must be a child, but not necessarily a direct child. This function is only relyable for visible objects (invisible @@ -1139,7 +1139,7 @@ QAccessibleInterface *QAccessibleInterface::focusChild() const Returns the QAccessibleInterface of the parent in the accessible object hierarchy. - Returns 0 if no parent exists (e.g. for the top level application object). + Returns \nullptr if no parent exists (e.g. for the top level application object). \sa child() */ @@ -1150,7 +1150,7 @@ QAccessibleInterface *QAccessibleInterface::focusChild() const Returns the accessible child with index \a index. 0-based index. The number of children of an object can be checked with childCount. - Returns 0 when asking for an invalid child (e.g. when the child became invalid in the meantime). + Returns \nullptr when asking for an invalid child (e.g. when the child became invalid in the meantime). \sa childCount(), parent() */ @@ -1356,7 +1356,7 @@ QAccessibleEvent::~QAccessibleEvent() \internal Returns the uniqueId of the QAccessibleInterface represented by this event. - In case the object() function returns 0 this is the only way to access the + In case the object() function returns \nullptr, this is the only way to access the interface. */ QAccessible::Id QAccessibleEvent::uniqueId() const @@ -1786,7 +1786,7 @@ QAccessibleInterface *QAccessibleEvent::accessibleInterface() const (This means that at least one interface among the ancestors should return a valid QWindow pointer). - The default implementation returns 0. + The default implementation returns \nullptr. */ QWindow *QAccessibleInterface::window() const { diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 0105f1decd..6801e2e1ea 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -113,7 +113,7 @@ QImageData::QImageData() \internal Creates a new image data. - Returns 0 if invalid parameters are give or anything else failed. + Returns \nullptr if invalid parameters are give or anything else failed. */ QImageData * QImageData::create(const QSize &size, QImage::Format format) { diff --git a/src/gui/itemmodels/qstandarditemmodel.cpp b/src/gui/itemmodels/qstandarditemmodel.cpp index 430ba152a9..7afad95bd9 100644 --- a/src/gui/itemmodels/qstandarditemmodel.cpp +++ b/src/gui/itemmodels/qstandarditemmodel.cpp @@ -879,8 +879,8 @@ QStandardItem::~QStandardItem() } /*! - Returns the item's parent item, or 0 if the item has no parent. - \note For toplevel items parent() returns 0. To receive toplevel + Returns the item's parent item, or \nullptr if the item has no parent. + \note For toplevel items parent() returns \nullptr. To receive toplevel item's parent use QStandardItemModel::invisibleRootItem() instead. \sa child(), QStandardItemModel::invisibleRootItem() @@ -1548,7 +1548,7 @@ QModelIndex QStandardItem::index() const Returns the QStandardItemModel that this item belongs to. If the item is not a child of another item that belongs to the model, this - function returns 0. + function returns \nullptr. \sa index() */ @@ -1865,7 +1865,7 @@ void QStandardItem::setChild(int row, int column, QStandardItem *item) /*! Returns the child item at (\a row, \a column) if one has been set; otherwise - returns 0. + returns \nullptr. \sa setChild(), takeChild(), parent() */ @@ -1881,7 +1881,7 @@ QStandardItem *QStandardItem::child(int row, int column) const /*! Removes the child item at (\a row, \a column) without deleting it, and returns a pointer to the item. If there was no child at the given location, then - this function returns 0. + this function returns \nullptr. Note that this function, unlike takeRow() and takeColumn(), does not affect the dimensions of the child table. @@ -2283,7 +2283,7 @@ void QStandardItemModel::clear() itemPrototype()), and set it in the parent item's child table, if no item already exists at that index. - If \a index is an invalid index, this function returns 0. + If \a index is an invalid index, this function returns \nullptr. \sa indexFromItem() */ @@ -2380,7 +2380,7 @@ void QStandardItemModel::setItem(int row, int column, QStandardItem *item) \since 4.2 Returns the item for the given \a row and \a column if one has been set; - otherwise returns 0. + otherwise returns \nullptr. \sa setItem(), takeItem(), itemFromIndex() */ @@ -2453,7 +2453,7 @@ void QStandardItemModel::setHorizontalHeaderItem(int column, QStandardItem *item \since 4.2 Returns the horizontal header item for \a column if one has been set; - otherwise returns 0. + otherwise returns \nullptr. \sa setHorizontalHeaderItem(), verticalHeaderItem() */ @@ -2509,7 +2509,7 @@ void QStandardItemModel::setVerticalHeaderItem(int row, QStandardItem *item) \since 4.2 Returns the vertical header item for row \a row if one has been set; - otherwise returns 0. + otherwise returns \nullptr. \sa setVerticalHeaderItem(), horizontalHeaderItem() */ diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 53d1ac1fc0..7123c4d8ba 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -3072,7 +3072,7 @@ QDropEvent::~QDropEvent() /*! If the source of the drag operation is a widget in this application, this function returns that source; otherwise it - returns 0. The source of the operation is the first parameter to + returns \nullptr. The source of the operation is the first parameter to the QDrag object used instantiate the drag. This is useful if your widget needs special behavior when dragging @@ -3514,7 +3514,7 @@ QActionEvent::~QActionEvent() \fn QAction *QActionEvent::before() const If type() is \l ActionAdded, returns the action that should - appear before action(). If this function returns 0, the action + appear before action(). If this function returns \nullptr, the action should be appended to already existing actions on the same widget. diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index a63e172461..fd01f8bb7b 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -3747,7 +3747,7 @@ Qt::LayoutDirection QGuiApplication::layoutDirection() Returns the active application override cursor. - This function returns 0 if no application cursor has been defined (i.e. the + This function returns \nullptr if no application cursor has been defined (i.e. the internal cursor stack is empty). \sa setOverrideCursor(), restoreOverrideCursor() diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index c5d5490ea0..be04513de6 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -1118,7 +1118,7 @@ void QOpenGLContext::swapBuffers(QSurface *surface) /*! Resolves the function pointer to an OpenGL extension function, identified by \a procName - Returns 0 if no such function can be found. + Returns \nullptr if no such function can be found. */ QFunctionPointer QOpenGLContext::getProcAddress(const QByteArray &procName) const { diff --git a/src/gui/kernel/qplatformcursor.cpp b/src/gui/kernel/qplatformcursor.cpp index bab26f6028..76e38ab12d 100644 --- a/src/gui/kernel/qplatformcursor.cpp +++ b/src/gui/kernel/qplatformcursor.cpp @@ -84,7 +84,7 @@ QT_BEGIN_NAMESPACE \a windowCursor is a pointer to the QCursor that should be displayed. - To unset the cursor of \a window, 0 is passed. This means \a window does not have + To unset the cursor of \a window, \nullptr is passed. This means \a window does not have a cursor set and the cursor of a the first parent window which has a cursor explicitly set or the system default cursor should take effect. diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp index 6e285a8fa5..7d1fcd4eeb 100644 --- a/src/gui/kernel/qplatformintegration.cpp +++ b/src/gui/kernel/qplatformintegration.cpp @@ -350,7 +350,7 @@ void QPlatformIntegration::destroy() /*! Returns the platforms input context. - The default implementation returns 0, implying no input method support. + The default implementation returns \nullptr, implying no input method support. */ QPlatformInputContext *QPlatformIntegration::inputContext() const { diff --git a/src/gui/kernel/qplatformscreen.cpp b/src/gui/kernel/qplatformscreen.cpp index 9614be7f3e..b7b312e89e 100644 --- a/src/gui/kernel/qplatformscreen.cpp +++ b/src/gui/kernel/qplatformscreen.cpp @@ -370,7 +370,7 @@ QString QPlatformScreen::serialNumber() const /*! Reimplement this function in subclass to return the cursor of the screen. - The default implementation returns 0. + The default implementation returns \nullptr. */ QPlatformCursor *QPlatformScreen::cursor() const { diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index bc2d6e6a17..61ef029cbd 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -2644,7 +2644,7 @@ QOpenGLContext *QWindowPrivate::shareContext() const native window, or to embed a native window inside a QWindow. If foreign windows are not supported or embedding the native window - failed in the platform plugin, this function returns 0. + failed in the platform plugin, this function returns \nullptr. \note The resulting QWindow should not be used to manipulate the underlying native window (besides re-parenting), or to observe state changes of the diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp index 1aee7d5f74..bfe1c9cadf 100644 --- a/src/gui/painting/qpaintengine.cpp +++ b/src/gui/painting/qpaintengine.cpp @@ -913,7 +913,7 @@ void QPaintEngine::setPaintDevice(QPaintDevice *device) /*! Returns the device that this engine is painting on, if painting is - active; otherwise returns 0. + active; otherwise returns \nullptr. */ QPaintDevice *QPaintEngine::paintDevice() const { diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index af8fcf369c..7719a2e6da 100644 --- a/src/gui/text/qtextcursor.cpp +++ b/src/gui/text/qtextcursor.cpp @@ -2116,7 +2116,7 @@ QTextList *QTextCursor::createList(QTextListFormat::Style style) /*! Returns the current list if the cursor position() is inside a - block that is part of a list; otherwise returns 0. + block that is part of a list; otherwise returns \nullptr. \sa insertList(), createList() */ @@ -2176,7 +2176,7 @@ QTextTable *QTextCursor::insertTable(int rows, int cols, const QTextTableFormat /*! Returns a pointer to the current table if the cursor position() - is inside a block that is part of a table; otherwise returns 0. + is inside a block that is part of a table; otherwise returns \nullptr. \sa insertTable() */ @@ -2213,7 +2213,7 @@ QTextFrame *QTextCursor::insertFrame(const QTextFrameFormat &format) } /*! - Returns a pointer to the current frame. Returns 0 if the cursor is invalid. + Returns a pointer to the current frame. Returns \nullptr if the cursor is invalid. \sa insertFrame() */ diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp index e2130a09d9..0ed8be8530 100644 --- a/src/gui/text/qtextobject.cpp +++ b/src/gui/text/qtextobject.cpp @@ -1301,7 +1301,7 @@ const QTextDocument *QTextBlock::document() const /*! If the block represents a list item, returns the list that the item belongs - to; otherwise returns 0. + to; otherwise returns \nullptr. */ QTextList *QTextBlock::textList() const { diff --git a/src/network/access/qftp.cpp b/src/network/access/qftp.cpp index feece4ebaf..d33355c470 100644 --- a/src/network/access/qftp.cpp +++ b/src/network/access/qftp.cpp @@ -2154,7 +2154,7 @@ QFtp::Command QFtp::currentCommand() const \internal Returns the QIODevice pointer that is used by the FTP command to read data from or store data to. If there is no current FTP command being executed or - if the command does not use an IO device, this function returns 0. + if the command does not use an IO device, this function returns \nullptr. This function can be used to delete the QIODevice in the slot connected to the commandFinished() signal. diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index 689eecfbb9..e4c46c3183 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -714,7 +714,7 @@ void QNetworkRequest::setOriginatingObject(QObject *object) \since 4.6 Returns a reference to the object that initiated this - network request; returns 0 if not set or the object has + network request; returns \nullptr if not set or the object has been destroyed. \sa setOriginatingObject() diff --git a/src/testlib/qtestcase.qdoc b/src/testlib/qtestcase.qdoc index ad9776f7ec..31903ea29c 100644 --- a/src/testlib/qtestcase.qdoc +++ b/src/testlib/qtestcase.qdoc @@ -959,7 +959,7 @@ \overload \since 5.8 - Returns a string containing \c{nullptr}. + Returns a string containing \nullptr. */ /*! diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp index 1fb5e61301..c9093095a7 100644 --- a/src/widgets/dialogs/qdialog.cpp +++ b/src/widgets/dialogs/qdialog.cpp @@ -969,7 +969,7 @@ Qt::Orientation QDialog::orientation() const Sets the widget, \a extension, to be the dialog's extension, deleting any previous extension. The dialog takes ownership of the - extension. Note that if 0 is passed any existing extension will be + extension. Note that if \nullptr is passed, any existing extension will be deleted. This function must only be called while the dialog is hidden. Instead of using this functionality, we recommend that you simply call diff --git a/src/widgets/dialogs/qprogressdialog.cpp b/src/widgets/dialogs/qprogressdialog.cpp index 4bf78e2115..e1fb1055ae 100644 --- a/src/widgets/dialogs/qprogressdialog.cpp +++ b/src/widgets/dialogs/qprogressdialog.cpp @@ -397,7 +397,7 @@ void QProgressDialog::setLabelText(const QString &text) Sets the cancel button to the push button, \a cancelButton. The progress dialog takes ownership of this button which will be deleted when necessary, so do not pass the address of an object that is on - the stack, i.e. use new() to create the button. If 0 is passed then + the stack, i.e. use new() to create the button. If \nullptr is passed, no cancel button will be shown. \sa setCancelButtonText() diff --git a/src/widgets/effects/qgraphicseffect.cpp b/src/widgets/effects/qgraphicseffect.cpp index 028010d3dd..94188f3485 100644 --- a/src/widgets/effects/qgraphicseffect.cpp +++ b/src/widgets/effects/qgraphicseffect.cpp @@ -178,7 +178,7 @@ QRectF QGraphicsEffect::sourceBoundingRect(Qt::CoordinateSystem system) const /*! Returns a pointer to the item if this source is a QGraphicsItem; otherwise - returns 0. + returns \nullptr. \sa widget() */ @@ -189,7 +189,7 @@ const QGraphicsItem *QGraphicsEffectSource::graphicsItem() const /*! Returns a pointer to the widget if this source is a QWidget; otherwise - returns 0. + returns \nullptr. \sa graphicsItem() */ @@ -200,7 +200,7 @@ const QWidget *QGraphicsEffectSource::widget() const /*! Returns a pointer to the style options (used when drawing the source) if - available; otherwise returns 0. + available; otherwise returns \nullptr. \sa graphicsItem(), widget() */ diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp index 3a9bfab298..86f3d6a2f0 100644 --- a/src/widgets/graphicsview/qgraphicsitem.cpp +++ b/src/widgets/graphicsview/qgraphicsitem.cpp @@ -1726,8 +1726,8 @@ QGraphicsItem *QGraphicsItem::topLevelItem() const /*! \since 4.6 - Returns a pointer to the item's parent, cast to a QGraphicsObject. returns 0 if the parent item - is not a QGraphicsObject. + Returns a pointer to the item's parent, cast to a QGraphicsObject. Returns + \nullptr if the parent item is not a QGraphicsObject. \sa parentItem(), childItems() */ diff --git a/src/widgets/graphicsview/qgraphicslayoutitem.cpp b/src/widgets/graphicsview/qgraphicslayoutitem.cpp index 9951fc0383..aed154a95f 100644 --- a/src/widgets/graphicsview/qgraphicslayoutitem.cpp +++ b/src/widgets/graphicsview/qgraphicslayoutitem.cpp @@ -369,7 +369,7 @@ bool QGraphicsLayoutItemPrivate::hasWidthForHeight() const protected constructor, or by calling setParentLayoutItem(). The parentLayoutItem() function returns a pointer to the item's layoutItem parent. If the item's parent is 0 or if the parent does not inherit - from QGraphicsItem, the parentLayoutItem() function then returns 0. + from QGraphicsItem, the parentLayoutItem() function then returns \nullptr. isLayout() returns \c true if the QGraphicsLayoutItem subclass is itself a layout, or false otherwise. diff --git a/src/widgets/itemviews/qabstractitemdelegate.cpp b/src/widgets/itemviews/qabstractitemdelegate.cpp index 7bc0ece4b3..9508aed3d3 100644 --- a/src/widgets/itemviews/qabstractitemdelegate.cpp +++ b/src/widgets/itemviews/qabstractitemdelegate.cpp @@ -240,7 +240,7 @@ QAbstractItemDelegate::~QAbstractItemDelegate() model being used. The editor's parent widget is specified by \a parent, and the item options by \a option. - The base implementation returns 0. If you want custom editing you + The base implementation returns \nullptr. If you want custom editing you will need to reimplement this function. The returned editor widget should have Qt::StrongFocus; diff --git a/src/widgets/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp index 72e0a67a64..b9c0e0a4b7 100644 --- a/src/widgets/itemviews/qlistwidget.cpp +++ b/src/widgets/itemviews/qlistwidget.cpp @@ -1375,7 +1375,7 @@ void QListWidget::setSelectionModel(QItemSelectionModel *selectionModel) /*! Returns the item that occupies the given \a row in the list if one has been - set; otherwise returns 0. + set; otherwise returns \nullptr. \sa row() */ @@ -1442,7 +1442,7 @@ void QListWidget::insertItems(int row, const QStringList &labels) /*! Removes and returns the item from the given \a row in the list widget; - otherwise returns 0. + otherwise returns \nullptr. Items removed from a list widget will not be managed by Qt, and will need to be deleted manually. diff --git a/src/widgets/itemviews/qtablewidget.cpp b/src/widgets/itemviews/qtablewidget.cpp index 2d539e10ba..eee3e91ac3 100644 --- a/src/widgets/itemviews/qtablewidget.cpp +++ b/src/widgets/itemviews/qtablewidget.cpp @@ -1936,7 +1936,7 @@ int QTableWidget::column(const QTableWidgetItem *item) const /*! Returns the item for the given \a row and \a column if one has been set; otherwise - returns 0. + returns \nullptr. \sa setItem() */ @@ -2029,7 +2029,7 @@ QTableWidgetItem *QTableWidget::takeVerticalHeaderItem(int row) /*! Returns the horizontal header item for column, \a column, if one has been - set; otherwise returns 0. + set; otherwise returns \nullptr. */ QTableWidgetItem *QTableWidget::horizontalHeaderItem(int column) const { @@ -2435,7 +2435,7 @@ int QTableWidget::visualColumn(int logicalColumn) const /*! \fn QTableWidgetItem *QTableWidget::itemAt(const QPoint &point) const - Returns a pointer to the item at the given \a point, or returns 0 if + Returns a pointer to the item at the given \a point, or returns \nullptr if \a point is not covered by an item in the table widget. \sa item() diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp index a0af27115d..9fbfb50029 100644 --- a/src/widgets/itemviews/qtreewidget.cpp +++ b/src/widgets/itemviews/qtreewidget.cpp @@ -2688,7 +2688,7 @@ void QTreeWidget::addTopLevelItem(QTreeWidgetItem *item) /*! Removes the top-level item at the given \a index in the tree and - returns it, otherwise returns 0; + returns it, otherwise returns \nullptr; \sa insertTopLevelItem(), topLevelItem(), topLevelItemCount() */ diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 6800a51d4b..ebab87b193 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -360,7 +360,7 @@ void QApplicationPrivate::createEventDispatcher() /*! \fn QWidget *QApplication::topLevelAt(const QPoint &point) - Returns the top-level widget at the given \a point; returns 0 if + Returns the top-level widget at the given \a point; returns \nullptr if there is no such widget. */ QWidget *QApplication::topLevelAt(const QPoint &pos) @@ -1226,7 +1226,7 @@ void QApplication::setStyle(QStyle *style) "windows", "windowsvista", "fusion", or "macintosh". Style names are case insensitive. - Returns 0 if an unknown \a style is passed, otherwise the QStyle object + Returns \nullptr if an unknown \a style is passed, otherwise the QStyle object returned is set as the application's GUI style. \warning To ensure that the application's style is set correctly, it is @@ -2177,7 +2177,7 @@ void QApplicationPrivate::notifyActiveWindowChange(QWindow *previous) /*!internal * Helper function that returns the new focus widget, but does not set the focus reason. - * Returns 0 if a new focus widget could not be found. + * Returns \nullptr if a new focus widget could not be found. * Shared with QGraphicsProxyWidgetPrivate::findFocusChild() */ QWidget *QApplicationPrivate::focusNextPrevChild_helper(QWidget *toplevel, bool next, diff --git a/src/widgets/kernel/qformlayout.cpp b/src/widgets/kernel/qformlayout.cpp index 66e8858e21..600934b8a1 100644 --- a/src/widgets/kernel/qformlayout.cpp +++ b/src/widgets/kernel/qformlayout.cpp @@ -1825,7 +1825,7 @@ int QFormLayout::rowCount() const /*! Returns the layout item in the given \a row with the specified \a - role (column). Returns 0 if there is no such item. + role (column). Returns \nullptr if there is no such item. \sa QLayout::itemAt(), setItem() */ diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 2a94b25ec9..9f7c486148 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -10409,7 +10409,7 @@ bool QWidget::hasHeightForWidth() const Returns the visible child widget at the position (\a{x}, \a{y}) in the widget's coordinate system. If there is no visible child - widget at the specified position, the function returns 0. + widget at the specified position, the function returns \nullptr. */ /*! @@ -12373,7 +12373,7 @@ Q_WIDGETS_EXPORT QWidgetPrivate *qt_widget_private(QWidget *widget) \since 4.5 Returns the proxy widget for the corresponding embedded widget in a graphics - view; otherwise returns 0. + view; otherwise returns \nullptr. \sa QGraphicsProxyWidget::createProxyForChildWidget(), QGraphicsScene::addWidget() diff --git a/src/widgets/styles/qstylefactory.cpp b/src/widgets/styles/qstylefactory.cpp index c959994d2c..b0ce5e52cf 100644 --- a/src/widgets/styles/qstylefactory.cpp +++ b/src/widgets/styles/qstylefactory.cpp @@ -77,7 +77,7 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, /*! Creates and returns a QStyle object that matches the given \a key, or - returns 0 if no matching style is found. + returns \nullptr if no matching style is found. Both built-in styles and styles from style plugins are queried for a matching style. diff --git a/src/widgets/util/qundogroup.cpp b/src/widgets/util/qundogroup.cpp index f9605c7a2f..9bd63d4232 100644 --- a/src/widgets/util/qundogroup.cpp +++ b/src/widgets/util/qundogroup.cpp @@ -242,7 +242,7 @@ void QUndoGroup::setActiveStack(QUndoStack *stack) Returns the active stack of this group. If none of the stacks are active, or if the group is empty, this function - returns 0. + returns \nullptr. \sa setActiveStack(), QUndoStack::setActive() */ diff --git a/src/widgets/util/qundoview.cpp b/src/widgets/util/qundoview.cpp index 31f6c0dff2..c862cbcea5 100644 --- a/src/widgets/util/qundoview.cpp +++ b/src/widgets/util/qundoview.cpp @@ -412,7 +412,7 @@ void QUndoView::setGroup(QUndoGroup *group) /*! Returns the group displayed by this view. - If the view is not looking at group, this function returns 0. + If the view is not looking at group, this function returns \nullptr. \sa setGroup(), setStack() */ diff --git a/src/widgets/widgets/qabstractbutton.cpp b/src/widgets/widgets/qabstractbutton.cpp index 5854472ff0..f30a3bc7b8 100644 --- a/src/widgets/widgets/qabstractbutton.cpp +++ b/src/widgets/widgets/qabstractbutton.cpp @@ -805,7 +805,7 @@ bool QAbstractButton::autoExclusive() const Returns the group that this button belongs to. If the button is not a member of any QButtonGroup, this function - returns 0. + returns \nullptr. \sa QButtonGroup */ diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp index 4e1aa51b4b..00ac5034e9 100644 --- a/src/widgets/widgets/qabstractspinbox.cpp +++ b/src/widgets/widgets/qabstractspinbox.cpp @@ -692,7 +692,7 @@ QLineEdit *QAbstractSpinBox::lineEdit() const QAbstractSpinBox takes ownership of the new lineEdit - If QLineEdit::validator() for the \a lineEdit returns 0, the internal + If QLineEdit::validator() for the \a lineEdit returns \nullptr, the internal validator of the spinbox will be set on the line edit. */ diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index e3c29ff6ee..48253b52b0 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -2283,7 +2283,7 @@ int QMenu::columnCount() const } /*! - Returns the item at \a pt; returns 0 if there is no item there. + Returns the item at \a pt; returns \nullptr if there is no item there. */ QAction *QMenu::actionAt(const QPoint &pt) const { diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index ce74a4c2ff..e7984078de 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -1581,7 +1581,7 @@ bool QMenuBar::eventFilter(QObject *object, QEvent *event) } /*! - Returns the QAction at \a pt. Returns 0 if there is no action at \a pt or if + Returns the QAction at \a pt. Returns \nullptr if there is no action at \a pt or if the location has a separator. \sa addAction(), addSeparator() From f1aa4c076fd10ededea3e87b7f53da2c0be84906 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 10 Jan 2019 07:57:21 +0100 Subject: [PATCH 0834/1650] Fix build with -no-libpng on Windows Check for availability of libpng in our bundled libfreetype. Fixes: QTBUG-71395 Change-Id: I99664b8583011f517b18e1038e327c6cb6799af7 Reviewed-by: Oliver Wolff --- src/3rdparty/freetype/freetype.pro | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/3rdparty/freetype/freetype.pro b/src/3rdparty/freetype/freetype.pro index 47ac9122ae..4034815158 100644 --- a/src/3rdparty/freetype/freetype.pro +++ b/src/3rdparty/freetype/freetype.pro @@ -69,8 +69,11 @@ DEFINES += FT2_BUILD_LIBRARY DEFINES += FT_CONFIG_OPTION_SYSTEM_ZLIB include(../zlib_dependency.pri) -DEFINES += FT_CONFIG_OPTION_USE_PNG include($$OUT_PWD/../../gui/qtgui-config.pri) -QMAKE_USE_PRIVATE += libpng +QT_FOR_CONFIG += gui-private +qtConfig(png) { + DEFINES += FT_CONFIG_OPTION_USE_PNG + QMAKE_USE_PRIVATE += libpng +} DEFINES += TT_CONFIG_OPTION_SUBPIXEL_HINTING From eef4d16639d739a7ddf59bc44a9c4d54f67fafa7 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 21 Dec 2018 16:45:01 +0100 Subject: [PATCH 0835/1650] QtOpenGLExtensions: Unify license headers Change-Id: If410c0dc739657a65732d29d45a86a35bee359de Reviewed-by: Jani Heikkinen --- src/openglextensions/qopenglextensions.cpp | 2 +- src/openglextensions/qopenglextensions.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openglextensions/qopenglextensions.cpp b/src/openglextensions/qopenglextensions.cpp index e923e7cead..6413ae4a78 100644 --- a/src/openglextensions/qopenglextensions.cpp +++ b/src/openglextensions/qopenglextensions.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB) ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the QtOpenGLExtensions module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage diff --git a/src/openglextensions/qopenglextensions.h b/src/openglextensions/qopenglextensions.h index afbc18f474..59dbdd4f12 100644 --- a/src/openglextensions/qopenglextensions.h +++ b/src/openglextensions/qopenglextensions.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB) ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the QtOpenGLExtensions module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage From 911da982df662dfddbb087ca33af239574dd8132 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Fri, 11 Jan 2019 10:25:55 +0100 Subject: [PATCH 0836/1650] qmltestcase: Fix generation of Visual Studio project files Mimicking the approach from testlib_defines.prf, DEFINES containing a path surrounded by quotation marks have to be handled differently for Visual Studio projects. Change-Id: I26f6a45d4df154f599e8be15b3aa3905cf703a1f Reviewed-by: Joerg Bornemann --- mkspecs/features/qmltestcase.prf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mkspecs/features/qmltestcase.prf b/mkspecs/features/qmltestcase.prf index 216f37d61a..b4b1224781 100644 --- a/mkspecs/features/qmltestcase.prf +++ b/mkspecs/features/qmltestcase.prf @@ -1,7 +1,8 @@ !isEmpty(SOURCES) { QT += qml qmltest load(testcase) - DEFINES += QUICK_TEST_SOURCE_DIR=\"\\\"$$_PRO_FILE_PWD_\\\"\" + contains(TEMPLATE, vc.*): DEFINES += QUICK_TEST_SOURCE_DIR=\"$$_PRO_FILE_PWD_\" + else: DEFINES += QUICK_TEST_SOURCE_DIR=$$shell_quote(\"$$_PRO_FILE_PWD_\") } else { # Allow a project to run tests without a CPP stub TEMPLATE = aux From 7044409c878f100c005b76fc90717b4f71667f04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 11 Jan 2019 12:12:11 +0100 Subject: [PATCH 0837/1650] macOS: Use tool environment to ensure tests load matching Qt libraries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Linking with a framework suffix to pick up the debug version of libraries doesn't work as long as the dependencies picked up from prl files are not rewritten to also include the suffix. The result is that we end up loading both release and debug versions of the Qt libraries. Use the target environment (target_wrapper.sh) to set the image suffix instead, which means 'make check' will automatically work. Change-Id: I60b0840760f68e579c270245d394e1dd609a0ebb Reviewed-by: Timur Pocheptsov Reviewed-by: Tor Arne Vestbø --- mkspecs/features/qt.prf | 8 -------- mkspecs/features/testcase.prf | 10 +++++++--- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index 5da82fdb5b..d8d5acaafd 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -209,14 +209,6 @@ for(ever) { !isEmpty(MODULE_MODULE) { contains(MODULE_CONFIG, lib_bundle) { framework = $$MODULE_MODULE - qtConfig(debug_and_release):qt_link_suffixed_framework:!macx-xcode { - platform_target_suffix = $$qtPlatformTargetSuffix() - !isEmpty(platform_target_suffix): \ - # The -framework linker argument supports a name[,suffix] version, - # where if the suffix is specified the framework is first searched - # for the library with the suffix and then without. - framework = $$framework,$$platform_target_suffix - } LIBS$$var_sfx += -framework $$framework } else { !isEmpty(MODULE_LIBS_ADD): \ diff --git a/mkspecs/features/testcase.prf b/mkspecs/features/testcase.prf index bfc28c6861..b8102c26b5 100644 --- a/mkspecs/features/testcase.prf +++ b/mkspecs/features/testcase.prf @@ -21,15 +21,19 @@ testcase_lowdpi { } } -# Make sure we explicitly link to the debug version of the Qt libraries if needed -macos: CONFIG += qt_link_suffixed_framework - benchmark: type = benchmark else: type = check $${type}.files = $${type}.path = . +# Make sure we explicitly load the debug version of the Qt libraries if needed +macos { + dyld_image_suffix.name = DYLD_IMAGE_SUFFIX + dyld_image_suffix.value = $$qtPlatformTargetSuffix() + QT_TOOL_ENV += dyld_image_suffix +} + # Add environment for non-installed builds. Do this first, so the # 'make' variable expansions don't end up in a batch file/script. QT_TOOL_NAME = target From 69bd238ad86abfe725d90707f3b578f5d766ba3c Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Fri, 11 Jan 2019 16:10:54 +0100 Subject: [PATCH 0838/1650] Fix resolving of libraries on Apple platforms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Qt couldn't be configured with -system-zlib on macOS, because qmake failed to find "/usr/lib/libz.dylib". The library path is something along the lines of "/Applications/Xcode.app/.../MacOSX10.14.sdk/usr/lib" which doesn't contain "libz.dylib". But it contains "libz.tbd", which is a YAML-file pointing to "/usr/lib/libz.dylib". One can pass the absolute path to this tbd file to the linker, which will then pick up "/usr/lib/libz.dylib". Introduce a new variable QMAKE_EXTENSIONS_AUX_SHLIB, which is a list of auxiliary extensions for shared libs, and add the "tbd" extension to it on macOS. Change-Id: I083b79a69d00232e35f9d6164ffa86cb473f1742 Fixes: QTBUG-72745 Fixes: QTBUG-72964 Reviewed-by: Christian Kandeler Reviewed-by: Tor Arne Vestbø Reviewed-by: Edward Welbourne --- mkspecs/common/mac.conf | 1 + mkspecs/features/qt_configure.prf | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/mkspecs/common/mac.conf b/mkspecs/common/mac.conf index 61bea952b2..b77494ec9b 100644 --- a/mkspecs/common/mac.conf +++ b/mkspecs/common/mac.conf @@ -14,6 +14,7 @@ include(unix.conf) QMAKE_RESOURCE = /Developer/Tools/Rez QMAKE_EXTENSION_SHLIB = dylib +QMAKE_EXTENSIONS_AUX_SHLIB = tbd QMAKE_LIBDIR = # sdk.prf will prefix the proper SDK sysroot diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index 87190bc52a..c45439c3ef 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -531,8 +531,11 @@ defineTest(qtConfResolveLibs) { unix { # Under UNIX, we look for actual shared libraries, in addition # to static ones. + shexts = $$QMAKE_EXTENSION_SHLIB $$QMAKE_EXTENSIONS_AUX_SHLIB + for (ext, shexts) { + lcan += $${QMAKE_PREFIX_SHLIB}$${lib}.$${ext} + } lcan += \ - $${QMAKE_PREFIX_SHLIB}$${lib}.$${QMAKE_EXTENSION_SHLIB} \ $${QMAKE_PREFIX_STATICLIB}$${lib}.$${QMAKE_EXTENSION_STATICLIB} } else { # Under Windows, we look only for static libraries, as even for DLLs From dd5e7f1a52c51061ad54e870df7f8e04c0f06fbe Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 5 Nov 2018 16:55:08 +0100 Subject: [PATCH 0839/1650] Use a more robust test for absolute paths in QDir Its filePath() and absoluteFilePath() don't trust its own isAbsolute(), due to some infelicities on MS-Win; and kludged round a consequent problem with resource paths; but other virtual file systems weren't catered for. Replace the convoluted test there with a static bool function (so that future kludges in this area shall only need to edit one place; and can document why they're needed) and use a more robust test that handles all virtual file systems (by asking QFileInfo) but falls back to QFileSystemEntry to work round the known infelicities on MS-Win. Add regression test for asset library paths issue on iOS. Ammends 27f1f84c1c2. Moved a couple of local variables to after the early return, since it doesn't need them, in the process. Task-number: QTBUG-70237 Change-Id: Ib3954826df40ccf816beebe5c3751497e3bf6433 Reviewed-by: Edward Welbourne Reviewed-by: Andy Shaw --- src/corelib/io/qdir.cpp | 29 +++++++++++------ tests/auto/corelib/io/qdir/Info.plist | 41 +++++++++++++++++++++++++ tests/auto/corelib/io/qdir/qdir.pro | 1 + tests/auto/corelib/io/qdir/tst_qdir.cpp | 5 +++ 4 files changed, 66 insertions(+), 10 deletions(-) create mode 100644 tests/auto/corelib/io/qdir/Info.plist diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 4b63a38963..f7778943c9 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -748,6 +748,21 @@ static int drivePrefixLength(const QString &path) } #endif // Q_OS_WIN +static bool treatAsAbsolute(const QString &path) +{ + // ### Qt 6: be consistent about absolute paths + + // QFileInfo will use the right FS-engine for virtual file-systems + // (e.g. resource paths). Unfortunately, for real file-systems, it relies + // on QFileSystemEntry's isRelative(), which is flawed on MS-Win, ignoring + // its (correct) isAbsolute(). So only use that isAbsolute() unless there's + // a colon in the path. + // FIXME: relies on virtual file-systems having colons in their prefixes. + // The case of an MS-absolute C:/... path happens to work either way. + return (path.contains(QLatin1Char(':')) && QFileInfo(path).isAbsolute()) + || QFileSystemEntry(path).isAbsolute(); +} + /*! Returns the path name of a file in the directory. Does \e not check if the file actually exists in the directory; but see @@ -759,13 +774,10 @@ static int drivePrefixLength(const QString &path) */ QString QDir::filePath(const QString &fileName) const { - const QDirPrivate* d = d_ptr.constData(); - // Mistrust our own isAbsolutePath() for real files; Q_OS_WIN needs a drive. - if (fileName.startsWith(QLatin1Char(':')) // i.e. resource path - ? isAbsolutePath(fileName) : QFileSystemEntry(fileName).isAbsolute()) { + if (treatAsAbsolute(fileName)) return fileName; - } + const QDirPrivate* d = d_ptr.constData(); QString ret = d->dirEntry.filePath(); if (fileName.isEmpty()) return ret; @@ -793,13 +805,10 @@ QString QDir::filePath(const QString &fileName) const */ QString QDir::absoluteFilePath(const QString &fileName) const { - const QDirPrivate* d = d_ptr.constData(); - // Mistrust our own isAbsolutePath() for real files; Q_OS_WIN needs a drive. - if (fileName.startsWith(QLatin1Char(':')) // i.e. resource path - ? isAbsolutePath(fileName) : QFileSystemEntry(fileName).isAbsolute()) { + if (treatAsAbsolute(fileName)) return fileName; - } + const QDirPrivate* d = d_ptr.constData(); d->resolveAbsoluteEntry(); const QString absoluteDirPath = d->absoluteDirEntry.filePath(); if (fileName.isEmpty()) diff --git a/tests/auto/corelib/io/qdir/Info.plist b/tests/auto/corelib/io/qdir/Info.plist new file mode 100644 index 0000000000..7dc5622bde --- /dev/null +++ b/tests/auto/corelib/io/qdir/Info.plist @@ -0,0 +1,41 @@ + + + + + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleGetInfoString + Created by Qt/QMake + CFBundleIconFile + ${ASSETCATALOG_COMPILER_APPICON_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + ${QMAKE_SHORT_VERSION} + CFBundleSignature + ${QMAKE_PKGINFO_TYPEINFO} + CFBundleVersion + ${QMAKE_FULL_VERSION} + LSRequiresIPhoneOS + + MinimumOSVersion + ${IPHONEOS_DEPLOYMENT_TARGET} + UILaunchStoryboardName + LaunchScreen + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + NSPhotoLibraryUsageDescription + Enables use of assets file engine + + diff --git a/tests/auto/corelib/io/qdir/qdir.pro b/tests/auto/corelib/io/qdir/qdir.pro index 2252e71cd8..a8b106e250 100644 --- a/tests/auto/corelib/io/qdir/qdir.pro +++ b/tests/auto/corelib/io/qdir/qdir.pro @@ -3,6 +3,7 @@ TARGET = tst_qdir QT = core core-private testlib SOURCES = tst_qdir.cpp RESOURCES += qdir.qrc +ios: QMAKE_INFO_PLIST = Info.plist TESTDATA += testdir testData searchdir resources entrylist types tst_qdir.cpp diff --git a/tests/auto/corelib/io/qdir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/tst_qdir.cpp index af9c6be432..34588b19bc 100644 --- a/tests/auto/corelib/io/qdir/tst_qdir.cpp +++ b/tests/auto/corelib/io/qdir/tst_qdir.cpp @@ -1523,6 +1523,11 @@ void tst_QDir::filePath_data() QTest::newRow("rel-rel") << "relative" << "path" << "relative/path"; QTest::newRow("empty-empty") << "" << "" << "."; QTest::newRow("resource") << ":/prefix" << "foo.bar" << ":/prefix/foo.bar"; +#ifdef Q_OS_IOS + QTest::newRow("assets-rel") << "assets-library:/" << "foo/bar.baz" << "assets-library:/foo/bar.baz"; + QTest::newRow("assets-abs") << "assets-library:/" << "/foo/bar.baz" << "/foo/bar.baz"; + QTest::newRow("abs-assets") << "/some/path" << "assets-library:/foo/bar.baz" << "assets-library:/foo/bar.baz"; +#endif #ifdef Q_OS_WIN QTest::newRow("abs-LTUNC") << "Q:/path" << "\\/leaning\\tooth/pick" << "\\/leaning\\tooth/pick"; QTest::newRow("LTUNC-slash") << "\\/leaning\\tooth/pick" << "/path" << "//leaning/tooth/path"; From 5dadc3d807af89c37b002749d3b39bfc94b10acd Mon Sep 17 00:00:00 2001 From: Andreas Date: Fri, 11 Jan 2019 11:01:04 +0100 Subject: [PATCH 0840/1650] xcb: fix initialization of XRandr and XRender Fixes: QTBUG-72957 Change-Id: Ia698eef5dae4e2d35ca2e565fbdc23da40c83d8a Reviewed-by: Gatis Paeglis --- src/plugins/platforms/xcb/qxcbconnection_basic.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection_basic.cpp b/src/plugins/platforms/xcb/qxcbconnection_basic.cpp index c69912c361..af72285135 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_basic.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_basic.cpp @@ -287,7 +287,7 @@ void QXcbBasicConnection::initializeShm() logging->setEnabled(QtMsgType::QtWarningMsg, true); } -void QXcbBasicConnection::initializeXRandr() +void QXcbBasicConnection::initializeXRender() { const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_xcbConnection, &xcb_render_id); if (!reply || !reply->present) { @@ -303,7 +303,7 @@ void QXcbBasicConnection::initializeXRandr() return; } - m_hasXRandr = true; + m_hasXRender = true; m_xrenderVersion.first = xrenderQuery->major_version; m_xrenderVersion.second = xrenderQuery->minor_version; } @@ -337,7 +337,7 @@ void QXcbBasicConnection::initializeXFixes() m_xfixesFirstEvent = reply->first_event; } -void QXcbBasicConnection::initializeXRender() +void QXcbBasicConnection::initializeXRandr() { const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_xcbConnection, &xcb_randr_id); if (!reply || !reply->present) @@ -352,7 +352,7 @@ void QXcbBasicConnection::initializeXRender() return; } - m_hasXRender = true; + m_hasXRandr = true; m_xrandrFirstEvent = reply->first_event; } From 6e21c9ac4a70c448b42666b622d6001fefc1c231 Mon Sep 17 00:00:00 2001 From: David Faure Date: Sun, 13 Jan 2019 15:38:30 +0100 Subject: [PATCH 0841/1650] QLocale: fix crash when using qDebug() in a global destructor `kdevelop -s doesnotexist` led to ASSERT failure in Q_GLOBAL_STATIC: "The global static was used after being destroyed because of a qDebug() statement in some "unregister" method called by a global object's destructor. This is normally fine, but with %{time} in QT_MESSAGE_PATTERN, qDebug() ends up using QLocale after its global objects (systemLocalePrivate and defaultLocalePrivate) were destroyed. Change-Id: I8d8b34e0197ad1eda8283fcf36d2c250385bb1a3 Reviewed-by: Thiago Macieira --- src/corelib/tools/qlocale.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 1f5d5f0dc6..63499ab93f 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -2367,6 +2367,8 @@ QLocale QLocale::system() { // this function is NOT thread-safe! QT_PREPEND_NAMESPACE(systemData)(); // trigger updating of the system data if necessary + if (systemLocalePrivate.isDestroyed()) + return QLocale(QLocale::C); return QLocale(*systemLocalePrivate->data()); } From af99497bdbcfb5202bd226b76910de9fd82e0625 Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Mon, 7 Jan 2019 16:56:11 +0100 Subject: [PATCH 0842/1650] Windows QPA: Support "press and hold for right-clicking" Windows sends a fake WM_RBUTTONUP/WM_RBUTTONDOWN when the user presses and holds the pen/finger on a tablet/touchscreen, e.g., in order to show a context menu. Windows only sends already synthesized legacy mouse messages for this condition, instead of anything detectable in the pointer messages. So we need to handle these legacy messages in the Windows QPA. Task-number: QTBUG-36162 Change-Id: Ia93c423601e2e8a8baac3f9b7791bf8a3113885a Reviewed-by: Friedemann Kleint --- .../windows/qwindowspointerhandler.cpp | 55 +++++++++++++------ .../windows/qwindowspointerhandler.h | 1 + 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp index be67eb0248..e428a8cf63 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp @@ -200,6 +200,8 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q return false; } + m_lastPointerType = pointerType; + // Handle non-client pen/touch as generic mouse events for compatibility with QDockWindow. if ((pointerType == QT_PT_TOUCH || pointerType == QT_PT_PEN) && (et & QtWindows::NonClientEventFlag)) { POINTER_INFO pointerInfo; @@ -838,6 +840,16 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin #endif } +static inline bool isMouseEventSynthesizedFromPenOrTouch() +{ + // For details, see + // https://docs.microsoft.com/en-us/windows/desktop/tablet/system-events-and-mouse-messages + const LONG_PTR SIGNATURE_MASK = 0xFFFFFF00; + const LONG_PTR MI_WP_SIGNATURE = 0xFF515700; + + return ((::GetMessageExtraInfo() & SIGNATURE_MASK) == MI_WP_SIGNATURE); +} + // Process old-style mouse messages here. bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result) { @@ -846,15 +858,6 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtW flushTabletEvents(); *result = 0; - if (et != QtWindows::MouseWheelEvent && msg.message != WM_MOUSELEAVE && msg.message != WM_MOUSEMOVE) - return false; - - // Ignore messages synthesized from touch/pen (only use them for flushing queues). - const quint64 signatureMask = 0xffffff00; - const quint64 miWpSignature = 0xff515700; - const quint64 extraInfo = quint64(GetMessageExtraInfo()); - if ((extraInfo & signatureMask) == miWpSignature) - return false; const QPoint eventPos(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam)); QPoint localPos; @@ -868,6 +871,26 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtW } const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers(); + const Qt::MouseButtons mouseButtons = mouseButtonsFromKeyState(msg.wParam); + + // Handle "press and hold for right-clicking". + // We have to synthesize it here as it only comes from Windows as a fake RMB. + // MS docs say we could use bit 7 from extraInfo to distinguish pen from touch, + // but on the Surface it is set for both. So we use the last pointer type. + if (isMouseEventSynthesizedFromPenOrTouch()) { + if ((msg.message == WM_RBUTTONDOWN || msg.message == WM_RBUTTONUP) + && (((m_lastPointerType == QT_PT_PEN) + && QCoreApplication::testAttribute(Qt::AA_SynthesizeMouseForUnhandledTabletEvents)) + || ((m_lastPointerType == QT_PT_TOUCH) + && QCoreApplication::testAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents)))) { + QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos, mouseButtons, Qt::RightButton, + (msg.message == WM_RBUTTONDOWN) ? QEvent::MouseButtonPress + : QEvent::MouseButtonRelease, + keyModifiers, Qt::MouseEventSynthesizedBySystem); + } + // Messages synthesized from touch/pen are only used for flushing queues and press&hold. + return false; + } if (et == QtWindows::MouseWheelEvent) { @@ -888,6 +911,7 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtW } if (msg.message == WM_MOUSELEAVE) { + if (window == m_currentWindow) { QWindow *leaveTarget = m_windowUnderPointer ? m_windowUnderPointer : m_currentWindow; qCDebug(lcQpaEvents) << "Leaving window " << leaveTarget; @@ -895,14 +919,13 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtW m_windowUnderPointer = nullptr; m_currentWindow = nullptr; } - return false; + + } else if (msg.message == WM_MOUSEMOVE) { + + QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos); + handleCaptureRelease(window, currentWindowUnderPointer, hwnd, QEvent::MouseMove, mouseButtons); + handleEnterLeave(window, currentWindowUnderPointer, globalPos); } - - QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos); - const Qt::MouseButtons mouseButtons = mouseButtonsFromKeyState(msg.wParam); - - handleCaptureRelease(window, currentWindowUnderPointer, hwnd, QEvent::MouseMove, mouseButtons); - handleEnterLeave(window, currentWindowUnderPointer, globalPos); return false; } diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.h b/src/plugins/platforms/windows/qwindowspointerhandler.h index a586c7863c..ec3179e821 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.h +++ b/src/plugins/platforms/windows/qwindowspointerhandler.h @@ -78,6 +78,7 @@ private: QPointer m_currentWindow; QWindow *m_previousCaptureWindow = nullptr; bool m_needsEnterOnPointerUpdate = false; + DWORD m_lastPointerType = 0; }; QT_END_NAMESPACE From 6178913a234dfbb5a24c9128f6460f070fb7ce14 Mon Sep 17 00:00:00 2001 From: Kari Oikarinen Date: Mon, 14 Jan 2019 09:12:55 +0200 Subject: [PATCH 0843/1650] Bump version Change-Id: I80954f7a3f33dbc8f04b61ebe5b5ed8b6ecb7b6a --- .qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.qmake.conf b/.qmake.conf index 518aa07f06..6c2b67442a 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -4,4 +4,4 @@ CONFIG += warning_clean QT_SOURCE_TREE = $$PWD QT_BUILD_TREE = $$shadowed($$PWD) -MODULE_VERSION = 5.12.1 +MODULE_VERSION = 5.12.2 From c365fa49d85810c6ad09bb5f43b5081cd7543bf1 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 19 Dec 2016 13:50:17 +0100 Subject: [PATCH 0844/1650] fix out-of-bounds access on trailing percent sign in tr() argument tr() recognizes %n and %Ln. it offers no way to escape lone percent signs, which implies that they must be interpreted verbatim, which is what the code actually does. except that it would run off the end if the % appeared at the end of the string. Fixes: QTBUG-57171 Done-with: Mateusz Starzycki Change-Id: Icf81925c482be1ea66ec8daafb3e92ad17ea7fab Reviewed-by: Oswald Buddenhagen --- src/corelib/kernel/qcoreapplication.cpp | 4 ++++ .../kernel/qcoreapplication/tst_qcoreapplication.cpp | 6 ++++++ .../corelib/kernel/qcoreapplication/tst_qcoreapplication.h | 1 + 3 files changed, 11 insertions(+) diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 3c8b0f947c..b6b4da3885 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -2097,9 +2097,13 @@ static void replacePercentN(QString *result, int n) int len = 0; while ((percentPos = result->indexOf(QLatin1Char('%'), percentPos + len)) != -1) { len = 1; + if (percentPos + len == result->length()) + break; QString fmt; if (result->at(percentPos + len) == QLatin1Char('L')) { ++len; + if (percentPos + len == result->length()) + break; fmt = QLatin1String("%L1"); } else { fmt = QLatin1String("%1"); diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp index a53501b9dd..6adb393ddd 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp +++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp @@ -928,6 +928,12 @@ void tst_QCoreApplication::threadedEventDelivery() thread.start(); QVERIFY(thread.wait(1000)); QCOMPARE(receiver.recordedEvents.contains(QEvent::User + 1), eventsReceived); + +} + +void tst_QCoreApplication::testTrWithPercantegeAtTheEnd() +{ + QCoreApplication::translate("testcontext", "this will crash%", "testdisamb", 3); } #if QT_CONFIG(library) diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h index 105cca5174..2a23cf0751 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h +++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h @@ -59,6 +59,7 @@ private slots: void applicationEventFilters_auxThread(); void threadedEventDelivery_data(); void threadedEventDelivery(); + void testTrWithPercantegeAtTheEnd(); #if QT_CONFIG(library) void addRemoveLibPaths(); #endif From 2ab139596d058cf9cc93e723c340467c70d93b10 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 10 Jan 2019 13:07:30 +0100 Subject: [PATCH 0845/1650] Fix alignment-warnings about Q_DECLARE_PRIVATE's casts Q_DECLARE_PRIVATE gets used in the declaration of the public class, where the private class is typically visible only as a forward-decl, with no knowledge of what it's based on; consequently, the macro is obliged to use reinterpret_cast<>, which is subject to warnings when the compiler *can* see both types and their alignments differ. The same applies to Q_DECLARE_PRIVATE_D. So suppress gcc's -Wcast-align around the d_func() return statements. (If we get similar problems with other compilers we can add their suppressions likewise; but, for now, we've only seen this on MIPS64, where we use gcc.) This tripped over one use of Q_DECLARE_PRIVATE in a private Q_SLOTS: section; for some reason, gcc didn't like the semicolon on the friend declaration. Changing the context to plain private fixed that. Fixes: QTBUG-72885 Change-Id: I5edc11d46bd4eb820713adede79d53191a7e2736 Reviewed-by: Liang Qi Reviewed-by: Ville Voutilainen Reviewed-by: Boxiang Sun --- src/corelib/global/qglobal.h | 14 ++++++++++---- src/network/access/qnetworkreplyfileimpl_p.h | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index b608489576..ccab228804 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1037,14 +1037,20 @@ for (auto _container_ = QtPrivate::qMakeForeachContainer(container); \ template inline T *qGetPtrHelper(T *ptr) { return ptr; } template inline auto qGetPtrHelper(const Ptr &ptr) -> decltype(ptr.operator->()) { return ptr.operator->(); } +// The body must be a statement: +#define Q_CAST_IGNORE_ALIGN(body) QT_WARNING_PUSH QT_WARNING_DISABLE_GCC("-Wcast-align") body QT_WARNING_POP #define Q_DECLARE_PRIVATE(Class) \ - inline Class##Private* d_func() { return reinterpret_cast(qGetPtrHelper(d_ptr)); } \ - inline const Class##Private* d_func() const { return reinterpret_cast(qGetPtrHelper(d_ptr)); } \ + inline Class##Private* d_func() \ + { Q_CAST_IGNORE_ALIGN(return reinterpret_cast(qGetPtrHelper(d_ptr));) } \ + inline const Class##Private* d_func() const \ + { Q_CAST_IGNORE_ALIGN(return reinterpret_cast(qGetPtrHelper(d_ptr));) } \ friend class Class##Private; #define Q_DECLARE_PRIVATE_D(Dptr, Class) \ - inline Class##Private* d_func() { return reinterpret_cast(qGetPtrHelper(Dptr)); } \ - inline const Class##Private* d_func() const { return reinterpret_cast(qGetPtrHelper(Dptr)); } \ + inline Class##Private* d_func() \ + { Q_CAST_IGNORE_ALIGN(return reinterpret_cast(qGetPtrHelper(Dptr));) } \ + inline const Class##Private* d_func() const \ + { Q_CAST_IGNORE_ALIGN(return reinterpret_cast(qGetPtrHelper(Dptr));) } \ friend class Class##Private; #define Q_DECLARE_PUBLIC(Class) \ diff --git a/src/network/access/qnetworkreplyfileimpl_p.h b/src/network/access/qnetworkreplyfileimpl_p.h index 55aece0bed..48d82abd3f 100644 --- a/src/network/access/qnetworkreplyfileimpl_p.h +++ b/src/network/access/qnetworkreplyfileimpl_p.h @@ -80,6 +80,7 @@ public: private Q_SLOTS: void fileOpenFinished(bool isOpen); +private: Q_DECLARE_PRIVATE(QNetworkReplyFileImpl) }; From cacf2ad9229a6842dbc0e002ed8ba4d04db026ae Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Thu, 10 Jan 2019 11:11:52 +0100 Subject: [PATCH 0846/1650] Fix deprecation warnings about QFontMetrics::width Recommend QFontMetrics::horizontalAdvance not QFont::horizontalAdvance Amends c2bf0cac957b1e7866538201433f3cd38313ab7f Change-Id: I7699acb7855fcff2297507343851b42b14d0f7f6 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfontmetrics.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/text/qfontmetrics.h b/src/gui/text/qfontmetrics.h index cbccc886fd..61931fa9bc 100644 --- a/src/gui/text/qfontmetrics.h +++ b/src/gui/text/qfontmetrics.h @@ -104,11 +104,11 @@ public: int rightBearing(QChar) const; #if QT_DEPRECATED_SINCE(5, 11) - QT_DEPRECATED_X("Use QFont::horizontalAdvance") + QT_DEPRECATED_X("Use QFontMetrics::horizontalAdvance") int width(const QString &, int len = -1) const; - QT_DEPRECATED_X("Use QFont::horizontalAdvance") + QT_DEPRECATED_X("Use QFontMetrics::horizontalAdvance") int width(const QString &, int len, int flags) const; - QT_DEPRECATED_X("Use QFont::horizontalAdvance") + QT_DEPRECATED_X("Use QFontMetrics::horizontalAdvance") int width(QChar) const; #endif From b95a4bbe84e5216d8dba9a0c077062fbb0efb30b Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Fri, 11 Jan 2019 11:27:19 +0100 Subject: [PATCH 0847/1650] MakefileGenerator: deduplicate code Factor out a resolveDependency method. We will enhance it in a subsequent commit. Change-Id: I4eead8bd03066c2ccbc9d9276acbc9f6c3bc6b97 Reviewed-by: Edward Welbourne --- qmake/generators/makefile.cpp | 34 ++++++++++++++-------------------- qmake/generators/makefile.h | 1 + 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 99455e7cb5..45684b5225 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -1839,6 +1839,18 @@ static QStringList splitDeps(const QString &indeps, bool lineMode) return deps; } +QString MakefileGenerator::resolveDependency(const QDir &outDir, const QString &file) +{ + const QList &depdirs = QMakeSourceFileInfo::dependencyPaths(); + for (const auto &depdir : depdirs) { + const QString &local = depdir.local(); + QString lf = outDir.absoluteFilePath(local + '/' + file); + if (exists(lf)) + return lf; + } + return {}; +} + void MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) { @@ -1991,16 +2003,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) } else if (exists(absFile)) { file = absFile; } else { - QString localFile; - QList depdirs = QMakeSourceFileInfo::dependencyPaths(); - for (QList::Iterator dit = depdirs.begin(); - dit != depdirs.end(); ++dit) { - QString lf = outDir.absoluteFilePath((*dit).local() + '/' + file); - if (exists(lf)) { - localFile = lf; - break; - } - } + QString localFile = resolveDependency(outDir, file); if (localFile.isEmpty()) { if (exists(file)) warn_msg(WarnDeprecated, ".depend_command for extra compiler %s" @@ -2088,16 +2091,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) } else if (exists(absFile)) { file = absFile; } else { - QString localFile; - QList depdirs = QMakeSourceFileInfo::dependencyPaths(); - for (QList::Iterator dit = depdirs.begin(); - dit != depdirs.end(); ++dit) { - QString lf = outDir.absoluteFilePath((*dit).local() + '/' + file); - if (exists(lf)) { - localFile = lf; - break; - } - } + QString localFile = resolveDependency(outDir, file); if (localFile.isEmpty()) { if (exists(file)) warn_msg(WarnDeprecated, ".depend_command for extra compiler %s" diff --git a/qmake/generators/makefile.h b/qmake/generators/makefile.h index 0c30e74a1d..3a75f6f473 100644 --- a/qmake/generators/makefile.h +++ b/qmake/generators/makefile.h @@ -82,6 +82,7 @@ protected: void writeExportedVariables(QTextStream &t); void writeExtraVariables(QTextStream &t); void writeExtraTargets(QTextStream &t); + QString resolveDependency(const QDir &outDir, const QString &file); void writeExtraCompilerTargets(QTextStream &t); void writeExtraCompilerVariables(QTextStream &t); bool writeDummyMakefile(QTextStream &t); From c6bd9082f4c6b53b30ef6badb7169df31a052305 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Fri, 11 Jan 2019 11:31:24 +0100 Subject: [PATCH 0848/1650] Resolve macOS framework headers for extra compiler depend_command On macOS, if an extra compiler returns a framework include via its depend_command, we must resolve it properly. For example, the uic extra compiler might return an include "QtQuickWidget/QQuickWidget", but the actual header file is located in "QtQuickWidget.framework/Headers/QQuickWidget". Fixes: QTBUG-72641 Change-Id: I42f11c74d01c88db8a32025b7f04d9ad50b2d08b Reviewed-by: Edward Welbourne Reviewed-by: Kai Koehne --- qmake/generators/makefile.cpp | 18 ++++++++++++++++++ qmake/generators/makefile.h | 1 + 2 files changed, 19 insertions(+) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 45684b5225..f824f12bce 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -424,6 +424,9 @@ MakefileGenerator::init() } incs.append(project->specDir()); + const auto platform = v["QMAKE_PLATFORM"]; + resolveDependenciesInFrameworks = platform.contains("darwin"); + const char * const cacheKeys[] = { "_QMAKE_STASH_", "_QMAKE_SUPER_CACHE_", nullptr }; for (int i = 0; cacheKeys[i]; ++i) { if (v[cacheKeys[i]].isEmpty()) @@ -1847,6 +1850,21 @@ QString MakefileGenerator::resolveDependency(const QDir &outDir, const QString & QString lf = outDir.absoluteFilePath(local + '/' + file); if (exists(lf)) return lf; + + if (resolveDependenciesInFrameworks) { + // Given a file like "QtWidgets/QWidget", try to resolve it + // as framework header "QtWidgets.framework/Headers/QWidget". + int cut = file.indexOf('/'); + if (cut < 0 || cut + 1 >= file.size()) + continue; + QStringRef framework = file.leftRef(cut); + QStringRef include = file.midRef(cut + 1); + if (local.endsWith('/' + framework + ".framework/Headers")) { + lf = outDir.absoluteFilePath(local + '/' + include); + if (exists(lf)) + return lf; + } + } } return {}; } diff --git a/qmake/generators/makefile.h b/qmake/generators/makefile.h index 3a75f6f473..0535017ff6 100644 --- a/qmake/generators/makefile.h +++ b/qmake/generators/makefile.h @@ -55,6 +55,7 @@ class MakefileGenerator : protected QMakeSourceFileInfo { QString spec; bool no_io; + bool resolveDependenciesInFrameworks = false; QHash init_compiler_already; QString makedir, chkexists; QString build_args(); From 1b47e7154a31a4747942043df933a3af978dc1cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 9 Jan 2019 02:32:36 +0100 Subject: [PATCH 0849/1650] Fix default rpath dirs on Apple platforms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The @executable_path relative framework directory is one step below the executable, as in: Foo.app/Contents/Frameworks not: Foo.app/Contents/MacOS/Frameworks The former is what Xcode defaults to for new projects. Change-Id: Id08f3f1d80f1c84d76fb71676c5df4a3a6b3da36 Reviewed-by: Kai Koehne Reviewed-by: Joerg Bornemann Reviewed-by: Tor Arne Vestbø --- mkspecs/features/mac/default_post.prf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/mac/default_post.prf b/mkspecs/features/mac/default_post.prf index 8e2c5e603a..c46222debd 100644 --- a/mkspecs/features/mac/default_post.prf +++ b/mkspecs/features/mac/default_post.prf @@ -67,7 +67,7 @@ qt { # Add the same default rpaths as Xcode does for new projects. # This is especially important for iOS/tvOS/watchOS where no other option is possible. !no_default_rpath { - QMAKE_RPATHDIR += @executable_path/Frameworks + QMAKE_RPATHDIR += @executable_path/../Frameworks equals(TEMPLATE, lib):!plugin:lib_bundle: QMAKE_RPATHDIR += @loader_path/Frameworks } From eabef55b8bd61b8693c4ed61c667bb0bbade0904 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Tue, 15 Jan 2019 09:56:18 +0100 Subject: [PATCH 0850/1650] testlib: Add missing header files to .pro file With all the headers missing, Creator's clang code model just gives up and it's impossible to work on testlib in Creator. Change-Id: I8814264db10992eeec6f45625580f6788d23b56b Reviewed-by: Edward Welbourne --- src/testlib/testlib.pro | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/testlib/testlib.pro b/src/testlib/testlib.pro index 46b61dac07..34bb581e02 100644 --- a/src/testlib/testlib.pro +++ b/src/testlib/testlib.pro @@ -12,6 +12,7 @@ unix:!embedded:QMAKE_PKGCONFIG_DESCRIPTION = Qt \ QMAKE_DOCS = $$PWD/doc/qttestlib.qdocconf HEADERS = \ + qabstracttestlogger_p.h \ qbenchmark.h \ qbenchmark_p.h \ qbenchmarkmeasurement_p.h \ @@ -21,10 +22,16 @@ HEADERS = \ qbenchmarkperfevents_p.h \ qbenchmarkmetric.h \ qbenchmarkmetric_p.h \ + qcsvbenchmarklogger_p.h \ + qplaintestlogger_p.h \ + qsignaldumper_p.h \ qsignalspy.h \ + qteamcitylogger_p.h \ qtestaccessible.h \ qtestassert.h \ qtestcase.h \ + qtestcoreelement_p.h \ + qtestcorelist_p.h \ qtestdata.h \ qtestevent.h \ qtesteventloop.h \ @@ -32,15 +39,23 @@ HEADERS = \ qtest_network.h \ qtest_widgets.h \ qtest.h \ + qtestelement_p.h \ + qtestelementattribute_p.h \ qtestkeyboard.h \ + qtestlog_p.h \ qtestmouse.h \ + qtestresult_p.h \ qtestspontaneevent.h \ qtestsystem.h \ + qtesttable_p.h \ qtesttouch.h \ qtestblacklist_p.h \ qtesthelpers_p.h \ qttestglobal.h \ - qtaptestlogger_p.h + qtestxunitstreamer_p.h \ + qtaptestlogger_p.h \ + qxmltestlogger_p.h \ + qxunittestlogger_p.h SOURCES = \ qtestcase.cpp \ From a7fa2618e4c8f10927a01d415d96ee783cf4348d Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Mon, 14 Jan 2019 13:00:06 -0600 Subject: [PATCH 0851/1650] Update QOpenGLTexture::generateMipMaps for ES 3 Per the Khronos documentation, this operation is not permitted on ES 3. Change-Id: Iff70ef83d48228277b883df588011432ba80f4bd Reviewed-by: Giuseppe D'Angelo --- src/gui/opengl/qopengltexture.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp index cea4b51a5c..5b7956d31e 100644 --- a/src/gui/opengl/qopengltexture.cpp +++ b/src/gui/opengl/qopengltexture.cpp @@ -3914,8 +3914,7 @@ bool QOpenGLTexture::isAutoMipMapGenerationEnabled() const have disabled automatic mipmap generation then you need to call this function or the overload to create the mipmap chain. - \note Mipmap generation is not supported for compressed textures with OpenGL - ES 2.0. + \note Mipmap generation is not supported for compressed textures with OpenGL ES. \sa setAutoMipMapGenerationEnabled(), setMipLevels(), mipLevels() */ @@ -3926,7 +3925,7 @@ void QOpenGLTexture::generateMipMaps() Q_ASSERT(d->textureId); if (isCompressedFormat(d->format)) { if (QOpenGLContext *ctx = QOpenGLContext::currentContext()) - if (ctx->isOpenGLES() && ctx->format().majorVersion() < 3) + if (ctx->isOpenGLES()) return; } d->texFuncs->glGenerateTextureMipmap(d->textureId, d->target, d->bindingTarget); @@ -3951,7 +3950,7 @@ void QOpenGLTexture::generateMipMaps(int baseLevel, bool resetBaseLevel) Q_ASSERT(d->textureId); if (isCompressedFormat(d->format)) { if (QOpenGLContext *ctx = QOpenGLContext::currentContext()) - if (ctx->isOpenGLES() && ctx->format().majorVersion() < 3) + if (ctx->isOpenGLES()) return; } int oldBaseLevel; From f7a7a49f9235c9375fc515a3062341f285f3c2c3 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 9 Jan 2019 20:24:32 -0800 Subject: [PATCH 0852/1650] Fix the AVX2 ARGB->ARGB64 conversion code Commit c8c5ff19de1c34a99b8315e59015d115957b3584 introduced the solution as a simple scaling up of the code in qdrawhelper_sse4.cpp, but it's bad due to the way that the 256-bit unpack instructions work: the unpack-low instruction unpacks the lower half of each half of the 256-bit register. So we fix it up by inserting a permute4x64 that swaps the middle two quarters of the 256-bit register (permute8x32 requires a __m256i parameter, instead of an immediate). This introduces an instruction that costs 3 cycles in each loop, but since the AVX2 code has double the throughput compared to SSE4 code, it should still be faster. This problem does not affect the ARGB->ARGB32 code because that repacks at the end. Change-Id: I4d4dadb709f1482fa8ccfffd1578620b45166a4f Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qdrawhelper_avx2.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/gui/painting/qdrawhelper_avx2.cpp b/src/gui/painting/qdrawhelper_avx2.cpp index d8732dc29f..21e07bb2dc 100644 --- a/src/gui/painting/qdrawhelper_avx2.cpp +++ b/src/gui/painting/qdrawhelper_avx2.cpp @@ -1146,9 +1146,20 @@ static void convertARGBToRGBA64PM_avx2(QRgba64 *buffer, const uint *src, qsizety __m256i src1, src2; __m256i srcVector = _mm256_loadu_si256(reinterpret_cast(src + i)); if (!_mm256_testz_si256(srcVector, alphaMask)) { - if (!_mm256_testc_si256(srcVector, alphaMask)) { - if (!RGBA) - srcVector = _mm256_shuffle_epi8(srcVector, rgbaMask); + // keep the two _mm_test[zc]_siXXX next to each other + bool cf = _mm256_testc_si256(srcVector, alphaMask); + if (!RGBA) + srcVector = _mm256_shuffle_epi8(srcVector, rgbaMask); + + // The two unpack instructions unpack the low and upper halves of + // each 128-bit half of the 256-bit register. Here's the tracking + // of what's where: (p is 32-bit, P is 64-bit) + // as loaded: [ p1, p2, p3, p4; p5, p6, p7, p8 ] + // after permute4x64 [ p1, p2, p5, p6; p3, p4, p7, p8 ] + // after unpacklo/hi [ P1, P2; P3, P4 ] [ P5, P6; P7, P8 ] + srcVector = _mm256_permute4x64_epi64(srcVector, _MM_SHUFFLE(3, 1, 2, 0)); + + if (!cf) { src1 = _mm256_unpacklo_epi8(srcVector, zero); src2 = _mm256_unpackhi_epi8(srcVector, zero); __m256i alpha1 = _mm256_shuffle_epi8(src1, shuffleMask); @@ -1162,8 +1173,6 @@ static void convertARGBToRGBA64PM_avx2(QRgba64 *buffer, const uint *src, qsizety src1 = _mm256_blend_epi16(src1, alpha1, 0x88); src2 = _mm256_blend_epi16(src2, alpha2, 0x88); } else { - if (!RGBA) - srcVector = _mm256_shuffle_epi8(srcVector, rgbaMask); src1 = _mm256_unpacklo_epi8(srcVector, srcVector); src2 = _mm256_unpackhi_epi8(srcVector, srcVector); } From 2c875efa999527b5d1419ea06d786b0a462c7133 Mon Sep 17 00:00:00 2001 From: Ryan Chu Date: Tue, 8 Jan 2019 14:34:30 +0100 Subject: [PATCH 0853/1650] Support debug_and_release option (which is the default under Windows) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When debug_and_release option is in use, qmake will generate one mata-Makefile and two additional leaf Makefile (Makefile.Debug and Makefile.Release). In such case, testserver.pri will be included in all three passes. The problem is that the mata-Mafile is used to invoke leaf Mafile recursively. The docker test server should only be integrated in the leaf Makefile. To resolve this problem, this change uses "!build_pass" condition to determine whether this is a pass of meta-Makefile, and then skip it. Change-Id: Ibc48d657680e089ebaa1bc356b87eb4cfd9f4580 Reviewed-by: Jędrzej Nowacki Reviewed-by: Edward Welbourne --- tests/auto/testserver.pri | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/auto/testserver.pri b/tests/auto/testserver.pri index 7dd32db0af..1a8b5a8187 100644 --- a/tests/auto/testserver.pri +++ b/tests/auto/testserver.pri @@ -51,6 +51,11 @@ # 2. testserver_clean - Clean up server containers/images and tidy away related # files. +# The docker test server should only be integrated in the leaf Makefile. +# If debug_and_release option is in use, skip the meta-Makefile except for +# Makefile.Debug and Makefile.Release. +debug_and_release:!build_pass: return() + TESTSERVER_VERSION = $$system(docker-compose --version) equals(QMAKE_HOST.os, Windows)|isEmpty(TESTSERVER_VERSION) { @@ -124,7 +129,7 @@ equals(QMAKE_HOST.os, Windows)|isEmpty(TESTSERVER_VERSION) { --detach --force-recreate --timeout 1 $${QT_TEST_SERVER_LIST} && # Check test cases with docker-based test servers. - testserver_test.commands += $(MAKE) check_network; + testserver_test.commands += $(MAKE) -f $(MAKEFILE) check_network; # Stop and remove test servers after testing. testserver_test.commands += docker-compose $$MACHINE_CONFIG -f $$TESTSERVER_COMPOSE_FILE down \ From 8961493b4036af018842820238c4eda0c0717e64 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Fri, 11 Jan 2019 10:37:46 +0100 Subject: [PATCH 0854/1650] QMacStyle - take into account that native controls are transparent now MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We use NSButton to emulate tabs in QTabWidget. Starting from 10.14 in dark theme those button objects tend to be somewhat transparent, thus widget's frame is visible through tab buttons. This is true for native controls also - NSButton, NSSegmentedControl, NSTabView - they all show the similar behavior. The only difference is NSTabView, which is the closest control to our QTabWidget - tab buttons are transparent, but they (AppKit) it would appear just do not draw the frame under this area. Let's do the same, but using clipping. Task-number: QTBUG-71741 Change-Id: I9f19014d0db5f36bacf76ee0068fae6eee793c0f Reviewed-by: Tor Arne Vestbø --- src/plugins/styles/mac/qmacstyle_mac.mm | 29 +++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index b84448d5e2..c2b6fbfead 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -130,6 +130,7 @@ #include #endif #include +#include #include #include #include @@ -314,6 +315,26 @@ static QLinearGradient titlebarGradientInactive() return qt_mac_applicationIsInDarkMode() ? darkGradient : lightGradient; } +static void clipTabBarFrame(const QStyleOption *option, const QMacStyle *style, CGContextRef ctx) +{ + Q_ASSERT(option); + Q_ASSERT(style); + Q_ASSERT(ctx); + + if (qt_mac_applicationIsInDarkMode()) { + QTabWidget *tabWidget = qobject_cast(option->styleObject); + Q_ASSERT(tabWidget); + + const QRect tabBarRect = style->subElementRect(QStyle::SE_TabWidgetTabBar, option, tabWidget).adjusted(2, 2, -3, -2); + const QRegion clipPath = QRegion(option->rect) - tabBarRect; + QVarLengthArray cgRects; + for (const QRect &qtRect : clipPath) + cgRects.push_back(qtRect.toCGRect()); + if (cgRects.size()) + CGContextClipToRects(ctx, &cgRects[0], size_t(cgRects.size())); + } +} + static const QColor titlebarSeparatorLineActive(111, 111, 111); static const QColor titlebarSeparatorLineInactive(131, 131, 131); static const QColor darkModeSeparatorLine(88, 88, 88); @@ -2976,6 +2997,8 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai // QDarkNSBox, of type NSBoxCustom. Its appearance is close enough to the real thing so // we can use this for now. d->drawNSViewInRect(box, opt->rect, p, ^(CGContextRef ctx, const CGRect &rect) { + if (QTabWidget *tabWidget = qobject_cast(opt->styleObject)) + clipTabBarFrame(opt, this, ctx); CGContextTranslateCTM(ctx, 0, rect.origin.y + rect.size.height); CGContextScaleCTM(ctx, 1, -1); if (QOperatingSystemVersion::current() < QOperatingSystemVersion::MacOSMojave @@ -3699,6 +3722,12 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter // inFrame:withView:], -[drawRect:] or anything in between. Besides, // there's no public API do draw the pressed state, AFAICS. We'll use // a push NSButton instead and clip the CGContext. + // NOTE/TODO: this is not true. On 10.13 NSSegmentedControl works with + // some (black?) magic/magic dances, on 10.14 it simply works (was + // it fixed in AppKit?). But, indeed, we cannot make a tab 'pressed' + // with NSSegmentedControl (only selected), so we stay with buttons + // (mixing buttons and NSSegmentedControl for such a simple thing + // is too much work). const auto cs = d->effectiveAquaSizeConstrain(opt, w); // Extra hacks to get the proper pressed appreance when not selected or selected and inactive From b782004149610d5c6af27e12d788acfb213b84d0 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 15 Jan 2019 16:38:01 +0100 Subject: [PATCH 0855/1650] Fix multiple emission of QGuiApplication::lastWindowClosed() when native child widgets are used MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Run the handling in QWindowPrivate::maybeQuitOnLastWindowClosed() for top level windows only. Fixes: QTBUG-73061 Change-Id: I74deb50b06a64e8ef0e438d2abf14888f778a46e Reviewed-by: Tor Arne Vestbø Reviewed-by: Qt CI Bot --- src/gui/kernel/qwindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 61ef029cbd..e0da4d0ea7 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -2588,6 +2588,8 @@ void QWindowPrivate::maybeQuitOnLastWindowClosed() return; Q_Q(QWindow); + if (!q->isTopLevel()) + return; // Attempt to close the application only if this has WA_QuitOnClose set and a non-visible parent bool quitOnClose = QGuiApplication::quitOnLastWindowClosed() && !q->parent(); QWindowList list = QGuiApplication::topLevelWindows(); From fa2821b484dfe21de1af508bec314ff865917014 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 9 Jan 2019 10:33:30 +0100 Subject: [PATCH 0856/1650] Add the command line option --no-strip to androiddeployqt There are certain use cases for keeping debug information on the device, for example collecting stack traces when the app crashes. [ChangeLog][Android] Added the --no-strip command line option to androiddeployqt. Change-Id: I96574c2c57d85fb23d5fc65380e471fa892b6543 Fixes: QTBUG-57771 Reviewed-by: Volker Krause Reviewed-by: Andy Shaw --- src/tools/androiddeployqt/main.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp index 587ae21e4f..af3a3ae39a 100644 --- a/src/tools/androiddeployqt/main.cpp +++ b/src/tools/androiddeployqt/main.cpp @@ -128,6 +128,7 @@ struct Options bool build; bool gradle; bool auxMode; + bool stripLibraries = true; QTime timer; // External tools @@ -437,6 +438,8 @@ Options parseOptions() options.generateAssetsFileList = false; } else if (argument.compare(QLatin1String("--aux-mode"), Qt::CaseInsensitive) == 0) { options.auxMode = true; + } else if (argument.compare(QLatin1String("--no-strip"), Qt::CaseInsensitive) == 0) { + options.stripLibraries = false; } } @@ -525,6 +528,7 @@ void printHelp() " --aux-mode: Operate in auxiliary mode. This will only copy the\n" " dependencies into the build directory and update the XML templates.\n" " The project will not be built or installed.\n" + " --no-strip: Do not strip debug symbols from libraries.\n" " --help: Displays this information.\n\n", qPrintable(QCoreApplication::arguments().at(0)) ); @@ -1897,6 +1901,8 @@ bool stripFile(const Options &options, const QString &fileName) bool stripLibraries(const Options &options) { + if (!options.stripLibraries) + return true; if (options.verbose) fprintf(stdout, "Stripping libraries to minimize size.\n"); From af821f79cacbac0be9995a7eb4a0448a9a2958bf Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 16 Jan 2019 11:16:46 +0100 Subject: [PATCH 0857/1650] Remove duplicate windeployqt_clean target That target is added unconditionally at the end of windeployqt.prf. Fixes: QTBUG-73018 Change-Id: I8d29691c30df64bf5383daa10e169985d47592f2 Reviewed-by: Oliver Wolff --- mkspecs/features/win32/windeployqt.prf | 1 - 1 file changed, 1 deletion(-) diff --git a/mkspecs/features/win32/windeployqt.prf b/mkspecs/features/win32/windeployqt.prf index fb5b2c4234..1929b7000e 100644 --- a/mkspecs/features/win32/windeployqt.prf +++ b/mkspecs/features/win32/windeployqt.prf @@ -10,7 +10,6 @@ build_pass { windeployqt.commands = $$QMAKE_WINDEPLOYQT $$WINDEPLOYQT_OPTIONS -list target $$WINDEPLOYQT_TARGET > $$WINDEPLOYQT_OUTPUT windeployqt_clean.commands = if exist $$WINDEPLOYQT_OUTPUT for /f %i in ($$WINDEPLOYQT_OUTPUT) do $$QMAKE_DEL_FILE %~fi && $$QMAKE_DEL_DIR %~pi - QMAKE_EXTRA_TARGETS += windeployqt_clean DISTCLEAN_DEPS += windeployqt_clean QMAKE_DISTCLEAN += $$WINDEPLOYQT_OUTPUT } else { From f8f0f3eef1151c9377a5c76ccfa6432e930e1307 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Mon, 14 Jan 2019 10:37:42 +0100 Subject: [PATCH 0858/1650] QSyntaxHighlighter: cancel delayed highlight if done manually MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was an implicit effect before which stopped working after dec7961709c90f6977d2447f7fa6c6625af41cb2. Reintroduce it as some projects used this side-effect as a way to abort the initial highlighting. Change-Id: I5340ee9882a242bc8b5f7f843f1cfe793a65d357 Reviewed-by: Jędrzej Nowacki --- src/gui/text/qsyntaxhighlighter.cpp | 1 + .../tst_qsyntaxhighlighter.cpp | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/gui/text/qsyntaxhighlighter.cpp b/src/gui/text/qsyntaxhighlighter.cpp index b09f8b565a..0e07b69868 100644 --- a/src/gui/text/qsyntaxhighlighter.cpp +++ b/src/gui/text/qsyntaxhighlighter.cpp @@ -376,6 +376,7 @@ void QSyntaxHighlighter::rehighlight() QTextCursor cursor(d->doc); d->rehighlight(cursor, QTextCursor::End); + d->rehighlightPending = false; // user manually did a full rehighlight } /*! diff --git a/tests/auto/gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp b/tests/auto/gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp index 9d6ce78b24..c683ecd424 100644 --- a/tests/auto/gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp +++ b/tests/auto/gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp @@ -82,6 +82,7 @@ private slots: void preservePreeditArea(); void task108530(); void avoidUnnecessaryRehighlight(); + void avoidUnnecessaryDelayedRehighlight(); void noContentsChangedDuringHighlight(); void rehighlight(); void rehighlightBlock(); @@ -478,6 +479,24 @@ void tst_QSyntaxHighlighter::avoidUnnecessaryRehighlight() QTRY_VERIFY(!hl->highlighted); } +void tst_QSyntaxHighlighter::avoidUnnecessaryDelayedRehighlight() +{ + // Having text in the document before creating the highlighter starts the delayed rehighlight + cursor.insertText("Hello World"); + + TestHighlighter *hl = new TestHighlighter(doc); + QVERIFY(!hl->highlighted); + + hl->rehighlight(); + QVERIFY(hl->highlighted); + + hl->highlighted = false; + // Process events, including delayed rehighlight emission + QCoreApplication::processEvents(); + // Should be cancelled and no extra rehighlight should be done + QVERIFY(!hl->highlighted); +} + void tst_QSyntaxHighlighter::noContentsChangedDuringHighlight() { QVector formats; From 8e500e15fa544f5eb9667f1c916d3764848bf4e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Mon, 14 Jan 2019 16:30:45 +0100 Subject: [PATCH 0859/1650] tst_qsyntaxhighlighter: fix no-op QTRY_VERIFY check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bool is assigned on the previous line: QTRY_VERIFY will not do anything because the statement is already true. Change-Id: I067290e19ffd100819b2b631af431c6013623a00 Reviewed-by: Jędrzej Nowacki --- .../gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/auto/gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp b/tests/auto/gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp index c683ecd424..55fff34a8e 100644 --- a/tests/auto/gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp +++ b/tests/auto/gui/text/qsyntaxhighlighter/tst_qsyntaxhighlighter.cpp @@ -476,7 +476,8 @@ void tst_QSyntaxHighlighter::avoidUnnecessaryRehighlight() QVERIFY(hl->highlighted); hl->highlighted = false; - QTRY_VERIFY(!hl->highlighted); + QCoreApplication::processEvents(); + QVERIFY(!hl->highlighted); } void tst_QSyntaxHighlighter::avoidUnnecessaryDelayedRehighlight() From 61af5abb33f98039733492633f5bf4b56efc9972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Tue, 15 Jan 2019 14:16:19 +0100 Subject: [PATCH 0860/1650] clang-cl: use GCC -m CPU feature flag option To enable non-default options Change-Id: I2d2f5dc8368a8235fd91e7f9986df4402612a823 Reviewed-by: Thiago Macieira Reviewed-by: Friedemann Kleint --- mkspecs/win32-clang-msvc/qmake.conf | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/mkspecs/win32-clang-msvc/qmake.conf b/mkspecs/win32-clang-msvc/qmake.conf index 027f93ca6e..c639ad6f3d 100644 --- a/mkspecs/win32-clang-msvc/qmake.conf +++ b/mkspecs/win32-clang-msvc/qmake.conf @@ -6,6 +6,27 @@ include(../common/msvc-desktop.conf) +# clang-cl does not use anything above SSE2 without extra arguments +QMAKE_CFLAGS_SSE3 = -msse3 +QMAKE_CFLAGS_SSSE3 = -mssse3 +QMAKE_CFLAGS_SSE4_1 = -msse4.1 +QMAKE_CFLAGS_SSE4_2 = -msse4.2 +QMAKE_CFLAGS_AVX = -mavx +QMAKE_CFLAGS_AVX2 = -mavx2 +QMAKE_CFLAGS_F16C = -mf16c +QMAKE_CFLAGS_RDRND = -mrdrnd +QMAKE_CFLAGS_AVX512F = -mavx512f +QMAKE_CFLAGS_AVX512ER = -mavx512er +QMAKE_CFLAGS_AVX512CD = -mavx512cd +QMAKE_CFLAGS_AVX512PF = -mavx512pf +QMAKE_CFLAGS_AVX512DQ = -mavx512dq +QMAKE_CFLAGS_AVX512BW = -mavx512bw +QMAKE_CFLAGS_AVX512VL = -mavx512vl +QMAKE_CFLAGS_AVX512IFMA = -mavx512ifma +QMAKE_CFLAGS_AVX512VBMI = -mavx512vbmi +QMAKE_CFLAGS_AESNI = -maes +QMAKE_CFLAGS_SHANI = -msha + QMAKE_COMPILER += clang_cl llvm QMAKE_CC = clang-cl From 5d8b01468e8bd752dad090aaef4ccf3a83a58a0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Klitzing?= Date: Thu, 27 Dec 2018 09:51:50 +0100 Subject: [PATCH 0861/1650] Update bundled libpng to version 1.6.36 The remaining diff to clean 1.6.36 is archived in the qtpatches.diff file. [ChangeLog][Third-Party Code] libpng was updated to version 1.6.36 Change-Id: Ia9d20c5abca115d509ed0aaf9eebfc85a88bef1d Reviewed-by: Kai Koehne Reviewed-by: Eirik Aavitsland --- src/3rdparty/libpng/ANNOUNCE | 93 +++++--- src/3rdparty/libpng/CHANGES | 29 ++- src/3rdparty/libpng/LICENSE | 173 +++++++------- src/3rdparty/libpng/README | 109 +++------ src/3rdparty/libpng/libpng-manual.txt | 91 ++------ src/3rdparty/libpng/png.c | 50 ++-- src/3rdparty/libpng/png.h | 299 +++++++++++------------- src/3rdparty/libpng/pngconf.h | 16 +- src/3rdparty/libpng/pngdebug.h | 6 +- src/3rdparty/libpng/pngerror.c | 12 +- src/3rdparty/libpng/pngget.c | 6 +- src/3rdparty/libpng/pnginfo.h | 6 +- src/3rdparty/libpng/pnglibconf.h | 11 +- src/3rdparty/libpng/pngmem.c | 6 +- src/3rdparty/libpng/pngpread.c | 16 +- src/3rdparty/libpng/pngpriv.h | 38 ++- src/3rdparty/libpng/pngread.c | 32 +-- src/3rdparty/libpng/pngrio.c | 6 +- src/3rdparty/libpng/pngrtran.c | 88 +++++-- src/3rdparty/libpng/pngrutil.c | 39 ++-- src/3rdparty/libpng/pngset.c | 12 +- src/3rdparty/libpng/pngstruct.h | 10 +- src/3rdparty/libpng/pngtrans.c | 12 +- src/3rdparty/libpng/pngwio.c | 6 +- src/3rdparty/libpng/pngwrite.c | 38 +-- src/3rdparty/libpng/pngwtran.c | 11 +- src/3rdparty/libpng/pngwutil.c | 38 +-- src/3rdparty/libpng/qt_attribution.json | 6 +- 28 files changed, 627 insertions(+), 632 deletions(-) diff --git a/src/3rdparty/libpng/ANNOUNCE b/src/3rdparty/libpng/ANNOUNCE index 9fc9021b5a..f1724c0d0d 100644 --- a/src/3rdparty/libpng/ANNOUNCE +++ b/src/3rdparty/libpng/ANNOUNCE @@ -1,48 +1,77 @@ -Libpng 1.6.35 - July 15, 2018 +libpng 1.6.36 - December 1, 2018 +================================ This is a public release of libpng, intended for use in production code. -Files available for download: + +Files available for download +---------------------------- Source files with LF line endings (for Unix/Linux): - libpng-1.6.35.tar.xz (LZMA-compressed, recommended) - libpng-1.6.35.tar.gz + * libpng-1.6.36.tar.xz (LZMA-compressed, recommended) + * libpng-1.6.36.tar.gz Source files with CRLF line endings (for Windows): - lp1635.7z (LZMA-compressed, recommended) - lp1635.zip + * lp1636.7z (LZMA-compressed, recommended) + * lp1636.zip Other information: - libpng-1.6.35-README.txt - libpng-1.6.35-LICENSE.txt + * README.md + * LICENSE.md + * AUTHORS.md + * TRADEMARK.md -Changes since the last public release (1.6.34): - Restored 21 of the contrib/pngsuite/i*.png, which do not cause test - failures. Placed the remainder in contrib/pngsuite/interlaced/i*.png. - Added calls to png_set_*() transforms commonly used by browsers to - the fuzzer. - Removed some unnecessary brackets in pngrtran.c - Fixed miscellaneous typos (Patch by github user "luzpaz"). - Change "ASM C" to "C ASM" in CMakeLists.txt - Fixed incorrect handling of bKGD chunk in sub-8-bit files (Cosmin) - Added hardware optimization directories to zip and 7z distributions. - Fixed incorrect bitmask for options. - Fixed many spelling typos. - Make png_get_iCCP consistent with man page (allow compression-type argument - to be NULL, bug report by Lenard Szolnoki). - Replaced the remaining uses of png_size_t with size_t (Cosmin) - Fixed the calculation of row_factor in png_check_chunk_length - (reported by Thuan Pham in SourceForge issue #278) - Added missing parentheses to a macro definition - (suggested by "irwir" in GitHub issue #216) +IMPORTANT licensing update: libpng license v2 +--------------------------------------------- -Send comments/corrections/commendations to png-mng-implement at lists.sf.net -(subscription required; visit +The new libpng license comprises the terms and conditions from the zlib +license, and the disclaimer from the Boost license. + +The legacy libpng license, used until libpng-1.6.35, is appended to the +new license, following the precedent established in the Python Software +Foundation License version 2. + +From now on, the list of contributing authors shall be maintained in a +separate AUTHORS file. The lists of previous contributing authors, +mentioned in the legacy libpng license and considered to be an integral +part of that license, are kept intact, with no further updates. + + +Changes since the previous public release (version 1.6.35) +---------------------------------------------------------- + + * Optimized png_do_expand_palette for ARM processors. + Improved performance by around 10-22% on a recent ARM Chromebook. + (Contributed by Richard Townsend, ARM Holdings) + * Fixed manipulation of machine-specific optimization options. + (Contributed by Vicki Pfau) + * Used memcpy instead of manual pointer arithmetic on Intel SSE2. + (Contributed by Samuel Williams) + * Fixed build errors with MSVC on ARM64. + (Contributed by Zhijie Liang) + * Fixed detection of libm in CMakeLists. + (Contributed by Cameron Cawley) + * Fixed incorrect creation of pkg-config file in CMakeLists. + (Contributed by Kyle Bentley) + * Fixed the CMake build on Windows MSYS by avoiding symlinks. + * Fixed a build warning on OpenBSD. + (Contributed by Theo Buehler) + * Fixed various typos in comments. + (Contributed by "luz.paz") + * Raised the minimum required CMake version from 3.0.2 to 3.1. + * Removed yet more of the vestigial support for pre-ANSI C compilers. + * Removed ancient makefiles for ancient systems that have been broken + across all previous libpng-1.6.x versions. + * Removed the Y2K compliance statement and the export control + information. + * Applied various code style and documentation fixes. + + +Send comments/corrections/commendations to png-mng-implement at lists.sf.net. +Subscription is required; visit https://lists.sourceforge.net/lists/listinfo/png-mng-implement -to subscribe). - -Glenn R-P +to subscribe. diff --git a/src/3rdparty/libpng/CHANGES b/src/3rdparty/libpng/CHANGES index 0ed6a11872..bdd4480654 100644 --- a/src/3rdparty/libpng/CHANGES +++ b/src/3rdparty/libpng/CHANGES @@ -6063,9 +6063,34 @@ Version 1.6.35 [July 15, 2018] Added missing parentheses to a macro definition (suggested by "irwir" in GitHub issue #216) +Version 1.6.36 [December 1, 2018] + Optimized png_do_expand_palette for ARM processors. + Improved performance by around 10-22% on a recent ARM Chromebook. + (Contributed by Richard Townsend, ARM Holdings) + Fixed manipulation of machine-specific optimization options. + (Contributed by Vicki Pfau) + Used memcpy instead of manual pointer arithmetic on Intel SSE2. + (Contributed by Samuel Williams) + Fixed build errors with MSVC on ARM64. + (Contributed by Zhijie Liang) + Fixed detection of libm in CMakeLists. + (Contributed by Cameron Cawley) + Fixed incorrect creation of pkg-config file in CMakeLists. + (Contributed by Kyle Bentley) + Fixed the CMake build on Windows MSYS by avoiding symlinks. + Fixed a build warning on OpenBSD. + (Contributed by Theo Buehler) + Fixed various typos in comments. + (Contributed by "luz.paz") + Raised the minimum required CMake version from 3.0.2 to 3.1. + Removed yet more of the vestigial support for pre-ANSI C compilers. + Removed ancient makefiles for ancient systems that have been broken + across all previous libpng-1.6.x versions. + Removed the Y2K compliance statement and the export control + information. + Applied various code style and documentation fixes. + Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit https://lists.sourceforge.net/lists/listinfo/png-mng-implement to subscribe). - -Glenn R-P diff --git a/src/3rdparty/libpng/LICENSE b/src/3rdparty/libpng/LICENSE index 6ee9c8f554..62ab8e48dc 100644 --- a/src/3rdparty/libpng/LICENSE +++ b/src/3rdparty/libpng/LICENSE @@ -1,14 +1,43 @@ +COPYRIGHT NOTICE, DISCLAIMER, and LICENSE +========================================= -This copy of the libpng notices is provided for your convenience. In case of -any discrepancy between this copy and the notices in the file png.h that is -included in the libpng distribution, the latter shall prevail. +PNG Reference Library License version 2 +--------------------------------------- -COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: + * Copyright (c) 1995-2018 The PNG Reference Library Authors. + * Copyright (c) 2018 Cosmin Truta. + * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson. + * Copyright (c) 1996-1997 Andreas Dilger. + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. -If you modify libpng you may insert additional notices immediately following -this sentence. +The software is supplied "as is", without warranty of any kind, +express or implied, including, without limitation, the warranties +of merchantability, fitness for a particular purpose, title, and +non-infringement. In no even shall the Copyright owners, or +anyone distributing the software, be liable for any damages or +other liability, whether in contract, tort or otherwise, arising +from, out of, or in connection with the software, or the use or +other dealings in the software, even if advised of the possibility +of such damage. -This code is released under the libpng license. +Permission is hereby granted to use, copy, modify, and distribute +this software, or portions hereof, for any purpose, without fee, +subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you + must not claim that you wrote the original software. If you + use this software in a product, an acknowledgment in the product + documentation would be appreciated, but is not required. + + 2. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + + 3. This Copyright notice may not be removed or altered from any + source or altered source distribution. + + +PNG Reference Library License version 1 (for libpng 0.5 through 1.6.35) +----------------------------------------------------------------------- libpng versions 1.0.7, July 1, 2000 through 1.6.35, July 15, 2018 are Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson, are @@ -16,38 +45,38 @@ derived from libpng-1.0.6, and are distributed according to the same disclaimer and license as libpng-1.0.6 with the following individuals added to the list of Contributing Authors: - Simon-Pierre Cadieux - Eric S. Raymond - Mans Rullgard - Cosmin Truta - Gilles Vollant - James Yu - Mandar Sahastrabuddhe - Google Inc. - Vadim Barkov + Simon-Pierre Cadieux + Eric S. Raymond + Mans Rullgard + Cosmin Truta + Gilles Vollant + James Yu + Mandar Sahastrabuddhe + Google Inc. + Vadim Barkov and with the following additions to the disclaimer: - There is no warranty against interference with your enjoyment of the - library or against infringement. There is no warranty that our - efforts or the library will fulfill any of your particular purposes - or needs. This library is provided with all faults, and the entire - risk of satisfactory quality, performance, accuracy, and effort is with - the user. + There is no warranty against interference with your enjoyment of + the library or against infringement. There is no warranty that our + efforts or the library will fulfill any of your particular purposes + or needs. This library is provided with all faults, and the entire + risk of satisfactory quality, performance, accuracy, and effort is + with the user. Some files in the "contrib" directory and some configure-generated -files that are distributed with libpng have other copyright owners and +files that are distributed with libpng have other copyright owners, and are released under other open source licenses. libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from libpng-0.96, and are distributed according to the same disclaimer and -license as libpng-0.96, with the following individuals added to the list -of Contributing Authors: +license as libpng-0.96, with the following individuals added to the +list of Contributing Authors: - Tom Lane - Glenn Randers-Pehrson - Willem van Schaik + Tom Lane + Glenn Randers-Pehrson + Willem van Schaik libpng versions 0.89, June 1996, through 0.96, May 1997, are Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88, @@ -55,14 +84,14 @@ and are distributed according to the same disclaimer and license as libpng-0.88, with the following individuals added to the list of Contributing Authors: - John Bowler - Kevin Bracey - Sam Bushell - Magnus Holmgren - Greg Roelofs - Tom Tanner + John Bowler + Kevin Bracey + Sam Bushell + Magnus Holmgren + Greg Roelofs + Tom Tanner -Some files in the "scripts" directory have other copyright owners +Some files in the "scripts" directory have other copyright owners, but are released under this license. libpng versions 0.5, May 1995, through 0.88, January 1996, are @@ -71,63 +100,35 @@ Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. For the purposes of this copyright and license, "Contributing Authors" is defined as the following set of individuals: - Andreas Dilger - Dave Martindale - Guy Eric Schalnat - Paul Schmidt - Tim Wegner + Andreas Dilger + Dave Martindale + Guy Eric Schalnat + Paul Schmidt + Tim Wegner -The PNG Reference Library is supplied "AS IS". The Contributing Authors -and Group 42, Inc. disclaim all warranties, expressed or implied, -including, without limitation, the warranties of merchantability and of -fitness for any purpose. The Contributing Authors and Group 42, Inc. -assume no liability for direct, indirect, incidental, special, exemplary, -or consequential damages, which may result from the use of the PNG -Reference Library, even if advised of the possibility of such damage. +The PNG Reference Library is supplied "AS IS". The Contributing +Authors and Group 42, Inc. disclaim all warranties, expressed or +implied, including, without limitation, the warranties of +merchantability and of fitness for any purpose. The Contributing +Authors and Group 42, Inc. assume no liability for direct, indirect, +incidental, special, exemplary, or consequential damages, which may +result from the use of the PNG Reference Library, even if advised of +the possibility of such damage. Permission is hereby granted to use, copy, modify, and distribute this source code, or portions hereof, for any purpose, without fee, subject to the following restrictions: - 1. The origin of this source code must not be misrepresented. + 1. The origin of this source code must not be misrepresented. - 2. Altered versions must be plainly marked as such and must not - be misrepresented as being the original source. + 2. Altered versions must be plainly marked as such and must not + be misrepresented as being the original source. - 3. This Copyright notice may not be removed or altered from any - source or altered source distribution. + 3. This Copyright notice may not be removed or altered from any + source or altered source distribution. -The Contributing Authors and Group 42, Inc. specifically permit, without -fee, and encourage the use of this source code as a component to -supporting the PNG file format in commercial products. If you use this -source code in a product, acknowledgment is not required but would be -appreciated. - -END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE. - -TRADEMARK: - -The name "libpng" has not been registered by the Copyright owner -as a trademark in any jurisdiction. However, because libpng has -been distributed and maintained world-wide, continually since 1995, -the Copyright owner claims "common-law trademark protection" in any -jurisdiction where common-law trademark is recognized. - -OSI CERTIFICATION: - -Libpng is OSI Certified Open Source Software. OSI Certified Open Source is -a certification mark of the Open Source Initiative. OSI has not addressed -the additional disclaimers inserted at version 1.0.7. - -EXPORT CONTROL: - -The Copyright owner believes that the Export Control Classification -Number (ECCN) for libpng is EAR99, which means not subject to export -controls or International Traffic in Arms Regulations (ITAR) because -it is open source, publicly available software, that does not contain -any encryption software. See the EAR, paragraphs 734.3(b)(3) and -734.7(b). - -Glenn Randers-Pehrson -glennrp at users.sourceforge.net -July 15, 2018 +The Contributing Authors and Group 42, Inc. specifically permit, +without fee, and encourage the use of this source code as a component +to supporting the PNG file format in commercial products. If you use +this source code in a product, acknowledgment is not required but would +be appreciated. diff --git a/src/3rdparty/libpng/README b/src/3rdparty/libpng/README index f098b27f39..e41e0f549b 100644 --- a/src/3rdparty/libpng/README +++ b/src/3rdparty/libpng/README @@ -1,15 +1,16 @@ -README for libpng version 1.6.35 - July 15, 2018 (shared library 16.0) -See the note about version numbers near the top of png.h +README for libpng version 1.6.36 - December 1, 2018 +=================================================== +See the note about version numbers near the top of png.h. See INSTALL for instructions on how to install libpng. Libpng comes in several distribution formats. Get libpng-*.tar.gz or -libpng-*.tar.xz or if you want UNIX-style line endings in the text files, -or lpng*.7z or lpng*.zip if you want DOS-style line endings. +libpng-*.tar.xz or if you want UNIX-style line endings in the text +files, or lpng*.7z or lpng*.zip if you want DOS-style line endings. Version 0.89 was the first official release of libpng. Don't let the -fact that it's the first release fool you. The libpng library has been in -extensive use and testing since mid-1995. By late 1997 it had +fact that it's the first release fool you. The libpng library has been +in extensive use and testing since mid-1995. By late 1997 it had finally gotten to the stage where there hadn't been significant changes to the API in some time, and people have a bad feeling about libraries with versions < 1.0. Version 1.0.0 was released in @@ -60,59 +61,37 @@ the library action on the detection of chunk CRC errors. It is possible to set different actions based on whether the CRC error occurred in a critical or an ancillary chunk. -The changes made to the library, and bugs fixed are based on discussions -on the PNG-implement mailing list and not on material submitted -privately to Guy, Andreas, or Glenn. They will forward any good -suggestions to the list. - -For a detailed description on using libpng, read libpng-manual.txt. For -examples of libpng in a program, see example.c and pngtest.c. For usage -information and restrictions (what little they are) on libpng, see -png.h. For a description on using zlib (the compression library used by -libpng) and zlib's restrictions, see zlib.h +For a detailed description on using libpng, read libpng-manual.txt. +For examples of libpng in a program, see example.c and pngtest.c. For +usage information and restrictions (what little they are) on libpng, +see png.h. For a description on using zlib (the compression library +used by libpng) and zlib's restrictions, see zlib.h I have included a general makefile, as well as several machine and -compiler specific ones, but you may have to modify one for your own needs. +compiler specific ones, but you may have to modify one for your own +needs. You should use zlib 1.0.4 or later to run this, but it MAY work with versions as old as zlib 0.95. Even so, there are bugs in older zlib versions which can cause the output of invalid compression streams for -some images. You will definitely need zlib 1.0.4 or later if you are -taking advantage of the MS-DOS "far" structure allocation for the small -and medium memory models. You should also note that zlib is a -compression library that is useful for more things than just PNG files. -You can use zlib as a drop-in replacement for fread() and fwrite() if -you are so inclined. +some images. -zlib should be available at the same place that libpng is, or at zlib.net. +You should also note that zlib is a compression library that is useful +for more things than just PNG files. You can use zlib as a drop-in +replacement for fread() and fwrite(), if you are so inclined. + +zlib should be available at the same place that libpng is, or at +https://zlib.net. You may also want a copy of the PNG specification. It is available as an RFC, a W3C Recommendation, and an ISO/IEC Standard. You can find these at http://www.libpng.org/pub/png/pngdocs.html . This code is currently being archived at libpng.sourceforge.io in the -[DOWNLOAD] area, and at http://libpng.download/src . If you -can't find it in any of those places, e-mail me, and I'll help you find it. +[DOWNLOAD] area, and at http://libpng.download/src . -I am not a lawyer, but I believe that the Export Control Classification -Number (ECCN) for libpng is EAR99, which means not subject to export -controls or International Traffic in Arms Regulations (ITAR) because it -is open source, publicly available software, that does not contain any -encryption software. See the EAR, paragraphs 734.3(b)(3) and 734.7(b). - -If you have any code changes, requests, problems, etc., please e-mail -them to me. Also, I'd appreciate any make files or project files, -and any modifications you needed to make to get libpng to compile, -along with a #define variable to tell what compiler/system you are on. -If you needed to add transformations to libpng, or wish libpng would -provide the image in a different way, drop me a note (and code, if -possible), so I can consider supporting the transformation. -Finally, if you get any warning messages when compiling libpng -(note: not zlib), and they are easy to fix, I'd appreciate the -fix. Please mention "libpng" somewhere in the subject line. Thanks. - -This release was created and will be supported by myself (of course -based in a large way on Guy's and Andreas' earlier work), and the PNG +This release, based in a large way on Glenn's, Guy's and Andreas' +earlier work, was created and will be supported by myself and the PNG development group. Send comments/corrections/commendations to png-mng-implement at @@ -120,34 +99,21 @@ lists.sourceforge.net (subscription required; visit https://lists.sourceforge.net/lists/listinfo/png-mng-implement to subscribe). -You can't reach Guy, the original libpng author, at the addresses -given in previous versions of this document. He and Andreas will -read mail addressed to the png-implement list, however. - -Please do not send general questions about PNG. Send them to -png-mng-misc at lists.sf.net (subscription required; visit +Send general questions about the PNG specification to png-mng-misc +at lists.sourceforge.net (subscription required; visit https://lists.sourceforge.net/lists/listinfo/png-mng-misc to -subscribe). If you have a question about something -in the PNG specification that is related to using libpng, send it -to me. Send me any questions that start with "I was using libpng, -and ...". If in doubt, send questions to me. I'll bounce them -to others, if necessary. - -Please do not send suggestions on how to change PNG. We have -been discussing PNG for twenty years now, and it is official and -finished. If you have suggestions for libpng, however, I'll -gladly listen. Even if your suggestion is not used immediately, -it may be used later. +subscribe). Files in this distribution: ANNOUNCE => Announcement of this version, with recent changes + AUTHORS => List of contributing authors CHANGES => Description of changes between libpng versions KNOWNBUG => List of known bugs and deficiencies LICENSE => License to use and redistribute libpng README => This file TODO => Things not implemented in the current library - Y2KINFO => Statement of Y2K compliance + TRADEMARK => Trademark information example.c => Example code for using libpng functions libpng.3 => manual page for libpng (includes libpng-manual.txt) libpng-manual.txt => Description of libpng and its functions @@ -208,15 +174,10 @@ Files in this distribution: scripts => Directory containing scripts for building libpng: (see scripts/README.txt for the list of scripts) -Good luck, and happy coding. +Good luck, and happy coding! --Glenn Randers-Pehrson (current maintainer, since 1998) - Internet: glennrp at users.sourceforge.net - --Andreas Eric Dilger (former maintainer, 1996-1997) - Internet: adilger at enel.ucalgary.ca - Web: http://www-mddsp.enel.ucalgary.ca/People/adilger/ - --Guy Eric Schalnat (original author and former maintainer, 1995-1996) - (formerly of Group 42, Inc) - Internet: gschal at infinet.com + * Cosmin Truta (current maintainer, since 2018) + * Glenn Randers-Pehrson (former maintainer, 1998-2018) + * Andreas Eric Dilger (former maintainer, 1996-1997) + * Guy Eric Schalnat (original author and former maintainer, 1995-1996) + (formerly of Group 42, Inc.) diff --git a/src/3rdparty/libpng/libpng-manual.txt b/src/3rdparty/libpng/libpng-manual.txt index b14a534163..19cfed28ad 100644 --- a/src/3rdparty/libpng/libpng-manual.txt +++ b/src/3rdparty/libpng/libpng-manual.txt @@ -1,7 +1,6 @@ libpng-manual.txt - A description on how to use and modify libpng - libpng version 1.6.35 - July 15, 2018 - Updated and distributed by Glenn Randers-Pehrson + Copyright (c) 2018 Cosmin Truta Copyright (c) 1998-2018 Glenn Randers-Pehrson This document is released under the libpng license. @@ -10,9 +9,13 @@ libpng-manual.txt - A description on how to use and modify libpng Based on: + libpng version 1.6.36 - December 1, 2018 + Updated and distributed by Cosmin Truta + Copyright (c) 2018 Cosmin Truta + libpng versions 0.97, January 1998, through 1.6.35 - July 15, 2018 Updated and distributed by Glenn Randers-Pehrson - Copyright (c) 1998-2017 Glenn Randers-Pehrson + Copyright (c) 1998-2018 Glenn Randers-Pehrson libpng 1.0 beta 6 - version 0.96 - May 28, 1997 Updated and distributed by Andreas Dilger @@ -44,7 +47,6 @@ libpng-manual.txt - A description on how to use and modify libpng XIII. Detecting libpng XIV. Source code repository XV. Coding style - XVI. Y2K Compliance in libpng I. Introduction @@ -65,7 +67,7 @@ file format in application programs. The PNG specification (second edition), November 2003, is available as a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2004 (E)) at -. The W3C and ISO documents have identical technical content. The PNG-1.2 specification is available at @@ -73,9 +75,9 @@ The PNG-1.2 specification is available at It is technically equivalent to the PNG specification (second edition) but has some additional material. -The PNG-1.0 specification is available as RFC 2083 +The PNG-1.0 specification is available as RFC 2083 at and as a -W3C Recommendation . +W3C Recommendation at . Some additional chunks are described in the special-purpose public chunks documents at @@ -4054,7 +4056,7 @@ Flags containing additional information about the image are held in the 'flags' field of png_image. PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB == 0x01 - This indicates the the RGB values of the in-memory bitmap do not + This indicates that the RGB values of the in-memory bitmap do not correspond to the red, green and blue end-points defined by sRGB. PNG_IMAGE_FLAG_FAST == 0x02 @@ -4520,7 +4522,7 @@ When PNG_DEBUG = 1, the macros are defined, but only png_debug statements having level = 0 will be printed. There aren't any such statements in this version of libpng, but if you insert some they will be printed. -VII. MNG support +VII. MNG support The MNG specification (available at http://www.libpng.org/pub/mng) allows certain extensions to PNG for PNG images that are embedded in MNG datastreams. @@ -4547,7 +4549,7 @@ or any other MNG chunks; your application must provide its own support for them. You may wish to consider using libmng (available at https://www.libmng.com/) instead. -VIII. Changes to Libpng from version 0.88 +VIII. Changes to Libpng from version 0.88 It should be noted that versions of libpng later than 0.96 are not distributed by the original libpng author, Guy Schalnat, nor by @@ -4602,7 +4604,7 @@ application: png_uint_32 application_vn = PNG_LIBPNG_VER; -IX. Changes to Libpng from version 1.0.x to 1.2.x +IX. Changes to Libpng from version 1.0.x to 1.2.x Support for user memory management was enabled by default. To accomplish this, the functions png_create_read_struct_2(), @@ -4699,7 +4701,7 @@ which also expands tRNS to alpha was replaced with png_set_expand_gray_1_2_4_to_8() which does not. It has been deprecated since libpng-1.0.18 and 1.2.9. -X. Changes to Libpng from version 1.0.x/1.2.x to 1.4.x +X. Changes to Libpng from version 1.0.x/1.2.x to 1.4.x Private libpng prototypes and macro definitions were moved from png.h and pngconf.h into a new pngpriv.h header file. @@ -4809,7 +4811,7 @@ was renamed to PNG_READ_QUANTIZE_SUPPORTED. We removed the trailing '.' from the warning and error messages. -XI. Changes to Libpng from version 1.4.x to 1.5.x +XI. Changes to Libpng from version 1.4.x to 1.5.x From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the function) incorrectly returned a value of type png_uint_32. @@ -4872,7 +4874,7 @@ to png_bytepp, and in png_set_iCCP, from png_charp to png_const_bytep. There are changes of form in png.h, including new and changed macros to declare parts of the API. Some API functions with arguments that are pointers to data not modified within the function have been corrected to -declare these arguments with PNG_CONST. +declare these arguments with const. Much of the internal use of C macros to control the library build has also changed and some of this is visible in the exported header files, in @@ -5067,7 +5069,7 @@ even though the default is to use the macros - this allows applications to choose at app buildtime whether or not to use macros (previously impossible because the functions weren't in the default build.) -XII. Changes to Libpng from version 1.5.x to 1.6.x +XII. Changes to Libpng from version 1.5.x to 1.6.x A "simplified API" has been added (see documentation in png.h and a simple example in contrib/examples/pngtopng.c). The new publicly visible API @@ -5230,7 +5232,7 @@ attempt to decode the Exif profile; it simply returns a byte array containing the profile to the calling application which must do its own decoding. -XIII. Detecting libpng +XIII. Detecting libpng The png_get_io_ptr() function has been present since libpng-0.88, has never changed, and is unaffected by conditional compilation macros. It is the @@ -5255,7 +5257,7 @@ or you can browse it with a web browser at https://sourceforge.net/p/libpng/code/ci/libpng16/tree/ Patches can be sent to png-mng-implement at lists.sourceforge.net or -you can upload them to the libpng bug tracker at +uploaded to the libpng bug tracker at https://libpng.sourceforge.io/ @@ -5405,58 +5407,3 @@ We do not use the TAB character for indentation in the C sources. Lines do not exceed 80 characters. Other rules can be inferred by inspecting the libpng source. - -XVI. Y2K Compliance in libpng - -Since the PNG Development group is an ad-hoc body, we can't make -an official declaration. - -This is your unofficial assurance that libpng from version 0.71 and -upward through 1.6.35 are Y2K compliant. It is my belief that earlier -versions were also Y2K compliant. - -Libpng only has two year fields. One is a 2-byte unsigned integer -that will hold years up to 65535. The other, which is deprecated, -holds the date in text format, and will hold years up to 9999. - -The integer is - "png_uint_16 year" in png_time_struct. - -The string is - "char time_buffer[29]" in png_struct. This is no longer used -in libpng-1.6.x and will be removed from libpng-1.7.0. - -There are seven time-related functions: - - png_convert_to_rfc_1123_buffer() in png.c - (formerly png_convert_to_rfc_1152() in error, and - also formerly png_convert_to_rfc_1123()) - png_convert_from_struct_tm() in pngwrite.c, called - in pngwrite.c - png_convert_from_time_t() in pngwrite.c - png_get_tIME() in pngget.c - png_handle_tIME() in pngrutil.c, called in pngread.c - png_set_tIME() in pngset.c - png_write_tIME() in pngwutil.c, called in pngwrite.c - -All appear to handle dates properly in a Y2K environment. The -png_convert_from_time_t() function calls gmtime() to convert from system -clock time, which returns (year - 1900), which we properly convert to -the full 4-digit year. There is a possibility that applications using -libpng are not passing 4-digit years into the png_convert_to_rfc_1123() -function, or that they are incorrectly passing only a 2-digit year -instead of "year - 1900" into the png_convert_from_struct_tm() function, -but this is not under our control. The libpng documentation has always -stated that it works with 4-digit years, and the APIs have been -documented as such. - -The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned -integer to hold the year, and can hold years as large as 65535. - -zlib, upon which libpng depends, is also Y2K compliant. It contains -no date-related code. - - - Glenn Randers-Pehrson - libpng maintainer - PNG Development Group diff --git a/src/3rdparty/libpng/png.c b/src/3rdparty/libpng/png.c index a25afebcc8..3dce191d17 100644 --- a/src/3rdparty/libpng/png.c +++ b/src/3rdparty/libpng/png.c @@ -1,10 +1,10 @@ /* png.c - location for general purpose libpng functions * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -14,7 +14,7 @@ #include "pngpriv.h" /* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_6_35 Your_png_h_is_not_version_1_6_35; +typedef png_libpng_version_1_6_36 Your_png_h_is_not_version_1_6_36; #ifdef __GNUC__ /* The version tests may need to be added to, but the problem warning has @@ -736,7 +736,7 @@ png_save_int_32(png_bytep buf, png_int_32 i) int PNGAPI png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime) { - static PNG_CONST char short_months[12][4] = + static const char short_months[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; @@ -814,20 +814,14 @@ png_get_copyright(png_const_structrp png_ptr) #ifdef PNG_STRING_COPYRIGHT return PNG_STRING_COPYRIGHT #else -# ifdef __STDC__ return PNG_STRING_NEWLINE \ - "libpng version 1.6.35 - July 15, 2018" PNG_STRING_NEWLINE \ + "libpng version 1.6.36" PNG_STRING_NEWLINE \ + "Copyright (c) 2018 Cosmin Truta" PNG_STRING_NEWLINE \ "Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \ PNG_STRING_NEWLINE \ "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ PNG_STRING_NEWLINE; -# else - return "libpng version 1.6.35 - July 15, 2018\ - Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson\ - Copyright (c) 1996-1997 Andreas Dilger\ - Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."; -# endif #endif } @@ -1121,7 +1115,7 @@ png_colorspace_set_gamma(png_const_structrp png_ptr, png_colorspacerp colorspace, png_fixed_point gAMA) { /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't - * occur. Since the fixed point representation is asymetrical it is + * occur. Since the fixed point representation is asymmetrical it is * possible for 1/gamma to overflow the limit of 21474 and this means the * gamma value must be at least 5/100000 and hence at most 20000.0. For * safety the limits here are a little narrower. The values are 0.00016 to @@ -3134,11 +3128,11 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size, /* The total output count (max) is now 4+precision */ /* Check for an exponent, if we don't need one we are - * done and just need to terminate the string. At - * this point exp_b10==(-1) is effectively a flag - it got - * to '-1' because of the decrement after outputting - * the decimal point above (the exponent required is - * *not* -1!) + * done and just need to terminate the string. At this + * point, exp_b10==(-1) is effectively a flag: it got + * to '-1' because of the decrement, after outputting + * the decimal point above. (The exponent required is + * *not* -1.) */ if (exp_b10 >= (-1) && exp_b10 <= 2) { @@ -3976,18 +3970,18 @@ png_gamma_correct(png_structrp png_ptr, unsigned int value, */ static void png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable, - PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val) + unsigned int shift, png_fixed_point gamma_val) { /* Various values derived from 'shift': */ - PNG_CONST unsigned int num = 1U << (8U - shift); + unsigned int num = 1U << (8U - shift); #ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED /* CSE the division and work round wacky GCC warnings (see the comments * in png_gamma_8bit_correct for where these come from.) */ - PNG_CONST double fmax = 1./(((png_int_32)1 << (16U - shift))-1); + double fmax = 1.0 / (((png_int_32)1 << (16U - shift)) - 1); #endif - PNG_CONST unsigned int max = (1U << (16U - shift))-1U; - PNG_CONST unsigned int max_by_2 = 1U << (15U-shift); + unsigned int max = (1U << (16U - shift)) - 1U; + unsigned int max_by_2 = 1U << (15U - shift); unsigned int i; png_uint_16pp table = *ptable = @@ -4053,10 +4047,10 @@ png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable, */ static void png_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable, - PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val) + unsigned int shift, png_fixed_point gamma_val) { - PNG_CONST unsigned int num = 1U << (8U - shift); - PNG_CONST unsigned int max = (1U << (16U - shift))-1U; + unsigned int num = 1U << (8U - shift); + unsigned int max = (1U << (16U - shift))-1U; unsigned int i; png_uint_32 last; @@ -4121,7 +4115,7 @@ png_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable, */ static void png_build_8bit_table(png_structrp png_ptr, png_bytepp ptable, - PNG_CONST png_fixed_point gamma_val) + png_fixed_point gamma_val) { unsigned int i; png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256); diff --git a/src/3rdparty/libpng/png.h b/src/3rdparty/libpng/png.h index 19e464cc17..8e272a0553 100644 --- a/src/3rdparty/libpng/png.h +++ b/src/3rdparty/libpng/png.h @@ -1,29 +1,65 @@ /* png.h - header file for PNG reference library * - * libpng version 1.6.35, July 15, 2018 + * libpng version 1.6.36 - December 1, 2018 * + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * - * This code is released under the libpng license (See LICENSE, below) + * This code is released under the libpng license. (See LICENSE, below.) * * Authors and maintainers: * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat * libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger - * libpng versions 0.97, January 1998, through 1.6.35, July 15, 2018: + * libpng versions 0.97, January 1998, through 1.6.35, July 2018: * Glenn Randers-Pehrson. + * libpng version 1.6.36, December 1, 2018: Cosmin Truta * See also "Contributing Authors", below. */ /* - * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: + * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE + * ========================================= * - * If you modify libpng you may insert additional notices immediately following - * this sentence. + * PNG Reference Library License version 2 + * --------------------------------------- * - * This code is released under the libpng license. + * * Copyright (c) 1995-2018 The PNG Reference Library Authors. + * * Copyright (c) 2018 Cosmin Truta. + * * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson. + * * Copyright (c) 1996-1997 Andreas Dilger. + * * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. + * + * The software is supplied "as is", without warranty of any kind, + * express or implied, including, without limitation, the warranties + * of merchantability, fitness for a particular purpose, title, and + * non-infringement. In no even shall the Copyright owners, or + * anyone distributing the software, be liable for any damages or + * other liability, whether in contract, tort or otherwise, arising + * from, out of, or in connection with the software, or the use or + * other dealings in the software, even if advised of the possibility + * of such damage. + * + * Permission is hereby granted to use, copy, modify, and distribute + * this software, or portions hereof, for any purpose, without fee, + * subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you + * must not claim that you wrote the original software. If you + * use this software in a product, an acknowledgment in the product + * documentation would be appreciated, but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must + * not be misrepresented as being the original software. + * + * 3. This Copyright notice may not be removed or altered from any + * source or altered source distribution. + * + * + * PNG Reference Library License version 1 (for libpng 0.5 through 1.6.35) + * ----------------------------------------------------------------------- * * libpng versions 1.0.7, July 1, 2000 through 1.6.35, July 15, 2018 are * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson, are @@ -31,38 +67,38 @@ * disclaimer and license as libpng-1.0.6 with the following individuals * added to the list of Contributing Authors: * - * Simon-Pierre Cadieux - * Eric S. Raymond - * Mans Rullgard - * Cosmin Truta - * Gilles Vollant - * James Yu - * Mandar Sahastrabuddhe - * Google Inc. - * Vadim Barkov + * Simon-Pierre Cadieux + * Eric S. Raymond + * Mans Rullgard + * Cosmin Truta + * Gilles Vollant + * James Yu + * Mandar Sahastrabuddhe + * Google Inc. + * Vadim Barkov * * and with the following additions to the disclaimer: * - * There is no warranty against interference with your enjoyment of the - * library or against infringement. There is no warranty that our - * efforts or the library will fulfill any of your particular purposes - * or needs. This library is provided with all faults, and the entire - * risk of satisfactory quality, performance, accuracy, and effort is with - * the user. + * There is no warranty against interference with your enjoyment of + * the library or against infringement. There is no warranty that our + * efforts or the library will fulfill any of your particular purposes + * or needs. This library is provided with all faults, and the entire + * risk of satisfactory quality, performance, accuracy, and effort is + * with the user. * * Some files in the "contrib" directory and some configure-generated - * files that are distributed with libpng have other copyright owners and + * files that are distributed with libpng have other copyright owners, and * are released under other open source licenses. * * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are * Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from * libpng-0.96, and are distributed according to the same disclaimer and - * license as libpng-0.96, with the following individuals added to the list - * of Contributing Authors: + * license as libpng-0.96, with the following individuals added to the + * list of Contributing Authors: * - * Tom Lane - * Glenn Randers-Pehrson - * Willem van Schaik + * Tom Lane + * Glenn Randers-Pehrson + * Willem van Schaik * * libpng versions 0.89, June 1996, through 0.96, May 1997, are * Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88, @@ -70,14 +106,14 @@ * libpng-0.88, with the following individuals added to the list of * Contributing Authors: * - * John Bowler - * Kevin Bracey - * Sam Bushell - * Magnus Holmgren - * Greg Roelofs - * Tom Tanner + * John Bowler + * Kevin Bracey + * Sam Bushell + * Magnus Holmgren + * Greg Roelofs + * Tom Tanner * - * Some files in the "scripts" directory have other copyright owners + * Some files in the "scripts" directory have other copyright owners, * but are released under this license. * * libpng versions 0.5, May 1995, through 0.88, January 1996, are @@ -86,62 +122,49 @@ * For the purposes of this copyright and license, "Contributing Authors" * is defined as the following set of individuals: * - * Andreas Dilger - * Dave Martindale - * Guy Eric Schalnat - * Paul Schmidt - * Tim Wegner + * Andreas Dilger + * Dave Martindale + * Guy Eric Schalnat + * Paul Schmidt + * Tim Wegner * - * The PNG Reference Library is supplied "AS IS". The Contributing Authors - * and Group 42, Inc. disclaim all warranties, expressed or implied, - * including, without limitation, the warranties of merchantability and of - * fitness for any purpose. The Contributing Authors and Group 42, Inc. - * assume no liability for direct, indirect, incidental, special, exemplary, - * or consequential damages, which may result from the use of the PNG - * Reference Library, even if advised of the possibility of such damage. + * The PNG Reference Library is supplied "AS IS". The Contributing + * Authors and Group 42, Inc. disclaim all warranties, expressed or + * implied, including, without limitation, the warranties of + * merchantability and of fitness for any purpose. The Contributing + * Authors and Group 42, Inc. assume no liability for direct, indirect, + * incidental, special, exemplary, or consequential damages, which may + * result from the use of the PNG Reference Library, even if advised of + * the possibility of such damage. * * Permission is hereby granted to use, copy, modify, and distribute this * source code, or portions hereof, for any purpose, without fee, subject * to the following restrictions: * - * 1. The origin of this source code must not be misrepresented. + * 1. The origin of this source code must not be misrepresented. * - * 2. Altered versions must be plainly marked as such and must not - * be misrepresented as being the original source. + * 2. Altered versions must be plainly marked as such and must not + * be misrepresented as being the original source. * - * 3. This Copyright notice may not be removed or altered from any - * source or altered source distribution. + * 3. This Copyright notice may not be removed or altered from any + * source or altered source distribution. * - * The Contributing Authors and Group 42, Inc. specifically permit, without - * fee, and encourage the use of this source code as a component to - * supporting the PNG file format in commercial products. If you use this - * source code in a product, acknowledgment is not required but would be - * appreciated. + * The Contributing Authors and Group 42, Inc. specifically permit, + * without fee, and encourage the use of this source code as a component + * to supporting the PNG file format in commercial products. If you use + * this source code in a product, acknowledgment is not required but would + * be appreciated. * * END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE. * - * TRADEMARK: + * TRADEMARK + * ========= * - * The name "libpng" has not been registered by the Copyright owner + * The name "libpng" has not been registered by the Copyright owners * as a trademark in any jurisdiction. However, because libpng has * been distributed and maintained world-wide, continually since 1995, - * the Copyright owner claims "common-law trademark protection" in any + * the Copyright owners claim "common-law trademark protection" in any * jurisdiction where common-law trademark is recognized. - * - * OSI CERTIFICATION: - * - * Libpng is OSI Certified Open Source Software. OSI Certified Open Source is - * a certification mark of the Open Source Initiative. OSI has not addressed - * the additional disclaimers inserted at version 1.0.7. - * - * EXPORT CONTROL: - * - * The Copyright owner believes that the Export Control Classification - * Number (ECCN) for libpng is EAR99, which means not subject to export - * controls or International Traffic in Arms Regulations (ITAR) because - * it is open source, publicly available software, that does not contain - * any encryption software. See the EAR, paragraphs 734.3(b)(3) and - * 734.7(b). */ /* @@ -207,23 +230,25 @@ * 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible) * 1.0.7 1 10007 (still compatible) * ... - * 1.0.19 10 10019 10.so.0.19[.0] + * 1.0.69 10 10069 10.so.0.69[.0] * ... - * 1.2.59 13 10257 12.so.0.59[.0] + * 1.2.59 13 10259 12.so.0.59[.0] * ... - * 1.5.30 15 10527 15.so.15.30[.0] + * 1.4.20 14 10420 14.so.0.20[.0] * ... - * 1.6.35 16 10635 16.so.16.35[.0] + * 1.5.30 15 10530 15.so.15.30[.0] + * ... + * 1.6.36 16 10636 16.so.16.36[.0] * - * Henceforth the source version will match the shared-library major - * and minor numbers; the shared-library major version number will be - * used for changes in backward compatibility, as it is intended. The - * PNG_LIBPNG_VER macro, which is not used within libpng but is available - * for applications, is an unsigned integer of the form xyyzz corresponding - * to the source version x.y.z (leading zeros in y and z). Beta versions - * were given the previous public release number plus a letter, until - * version 1.0.6j; from then on they were given the upcoming public - * release number plus "betaNN" or "rcNN". + * Henceforth the source version will match the shared-library major and + * minor numbers; the shared-library major version number will be used for + * changes in backward compatibility, as it is intended. + * The PNG_LIBPNG_VER macro, which is not used within libpng but is + * available for applications, is an unsigned integer of the form XYYZZ + * corresponding to the source version X.Y.Z (leading zeros in Y and Z). + * Beta versions were given the previous public release number plus a + * letter, until version 1.0.6j; from then on they were given the upcoming + * public release number plus "betaNN" or "rcNN". * * Binary incompatibility exists only when applications make direct access * to the info_ptr or png_ptr members through png.h, and the compiled @@ -233,65 +258,8 @@ * in binary compatibility (e.g., when a new feature is added). * * See libpng.txt or libpng.3 for more information. The PNG specification - * is available as a W3C Recommendation and as an ISO Specification, - * */ #ifndef PNG_H @@ -309,8 +277,8 @@ */ /* Version information for png.h - this should match the version in png.c */ -#define PNG_LIBPNG_VER_STRING "1.6.35" -#define PNG_HEADER_VERSION_STRING " libpng version 1.6.35 - July 15, 2018\n" +#define PNG_LIBPNG_VER_STRING "1.6.36" +#define PNG_HEADER_VERSION_STRING " libpng version 1.6.36 - December 1, 2018\n" #define PNG_LIBPNG_VER_SONUM 16 #define PNG_LIBPNG_VER_DLLNUM 16 @@ -318,13 +286,13 @@ /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ #define PNG_LIBPNG_VER_MAJOR 1 #define PNG_LIBPNG_VER_MINOR 6 -#define PNG_LIBPNG_VER_RELEASE 35 +#define PNG_LIBPNG_VER_RELEASE 36 /* This should match the numeric part of the final component of * PNG_LIBPNG_VER_STRING, omitting any leading zero: */ -#define PNG_LIBPNG_VER_BUILD 02 +#define PNG_LIBPNG_VER_BUILD 0 /* Release Status */ #define PNG_LIBPNG_BUILD_ALPHA 1 @@ -341,15 +309,16 @@ #define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with PNG_LIBPNG_BUILD_PRIVATE */ -#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_BETA +#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE -/* Careful here. At one time, Guy wanted to use 082, but that would be octal. - * We must not include leading zeros. - * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only - * version 1.0.0 was mis-numbered 100 instead of 10000). From - * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release +/* Careful here. At one time, Guy wanted to use 082, but that + * would be octal. We must not include leading zeros. + * Versions 0.7 through 1.0.0 were in the range 0 to 100 here + * (only version 1.0.0 was mis-numbered 100 instead of 10000). + * From version 1.0.1 it is: + * XXYYZZ, where XX=major, YY=minor, ZZ=release */ -#define PNG_LIBPNG_VER 10635 /* 1.6.35 */ +#define PNG_LIBPNG_VER 10636 /* 1.6.36 */ /* Library configuration: these options cannot be changed after * the library has been built. @@ -459,7 +428,7 @@ extern "C" { /* This triggers a compiler error in png.c, if png.c and png.h * do not agree upon the version number. */ -typedef char* png_libpng_version_1_6_35; +typedef char* png_libpng_version_1_6_36; /* Basic control structions. Read libpng-manual.txt or libpng.3 for more info. * @@ -2013,12 +1982,12 @@ PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed, (png_const_structrp png_ptr, PNG_EXPORT(246, png_uint_32, png_get_eXIf, (png_const_structrp png_ptr, png_inforp info_ptr, png_bytep *exif)); PNG_EXPORT(247, void, png_set_eXIf, (png_const_structrp png_ptr, - png_inforp info_ptr, const png_bytep exif)); + png_inforp info_ptr, png_bytep exif)); PNG_EXPORT(248, png_uint_32, png_get_eXIf_1, (png_const_structrp png_ptr, png_const_inforp info_ptr, png_uint_32 *num_exif, png_bytep *exif)); PNG_EXPORT(249, void, png_set_eXIf_1, (png_const_structrp png_ptr, - png_inforp info_ptr, const png_uint_32 num_exif, const png_bytep exif)); + png_inforp info_ptr, png_uint_32 num_exif, png_bytep exif)); #endif #ifdef PNG_gAMA_SUPPORTED @@ -2764,7 +2733,7 @@ typedef struct * * When the simplified API needs to convert between sRGB and linear colorspaces, * the actual sRGB transfer curve defined in the sRGB specification (see the - * article at https://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2 + * article at ) is used, not the gamma=1/2.2 * approximation used elsewhere in libpng. * * When an alpha channel is present it is expected to denote pixel coverage @@ -2967,7 +2936,7 @@ typedef struct * 'flags' field of png_image. */ #define PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB 0x01 - /* This indicates the the RGB values of the in-memory bitmap do not + /* This indicates that the RGB values of the in-memory bitmap do not * correspond to the red, green and blue end-points defined by sRGB. */ diff --git a/src/3rdparty/libpng/pngconf.h b/src/3rdparty/libpng/pngconf.h index a4646bab85..5e641b2509 100644 --- a/src/3rdparty/libpng/pngconf.h +++ b/src/3rdparty/libpng/pngconf.h @@ -1,11 +1,12 @@ /* pngconf.h - machine configurable file for libpng * - * libpng version 1.6.35, July 15, 2018 + * libpng version 1.6.36 * + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -57,14 +58,13 @@ #endif /* PNG_BUILDING_SYMBOL_TABLE */ -/* Prior to 1.6.0 it was possible to turn off 'const' in declarations using - * PNG_NO_CONST; this is no longer supported except for data declarations which - * apparently still cause problems in 2011 on some compilers. +/* Prior to 1.6.0, it was possible to turn off 'const' in declarations, + * using PNG_NO_CONST. This is no longer supported. */ #define PNG_CONST const /* backward compatibility only */ -/* This controls optimization of the reading of 16-bit and 32-bit values - * from PNG files. It can be set on a per-app-file basis - it +/* This controls optimization of the reading of 16-bit and 32-bit + * values from PNG files. It can be set on a per-app-file basis: it * just changes whether a macro is used when the function is called. * The library builder sets the default; if read functions are not * built into the library the macro implementation is forced on. diff --git a/src/3rdparty/libpng/pngdebug.h b/src/3rdparty/libpng/pngdebug.h index 15a7ed0c95..00d5a4569e 100644 --- a/src/3rdparty/libpng/pngdebug.h +++ b/src/3rdparty/libpng/pngdebug.h @@ -1,10 +1,10 @@ /* pngdebug.h - Debugging macros for libpng, also used in pngtest.c * - * Last changed in libpng 1.6.8 [December 19, 2013] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer diff --git a/src/3rdparty/libpng/pngerror.c b/src/3rdparty/libpng/pngerror.c index ad48bfb986..ec3a709b9d 100644 --- a/src/3rdparty/libpng/pngerror.c +++ b/src/3rdparty/libpng/pngerror.c @@ -1,10 +1,10 @@ /* pngerror.c - stub functions for i/o and memory allocation * - * Last changed in libpng 1.6.31 [July 27, 2017] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -425,7 +425,7 @@ png_app_error(png_const_structrp png_ptr, png_const_charp error_message) * if the character is invalid. */ #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) -static PNG_CONST char png_digit[16] = { +static const char png_digit[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; @@ -885,7 +885,7 @@ PNG_FUNCTION(void /* PRIVATE */, (PNGCBAPI png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message), PNG_NORETURN) { - const png_const_structrp png_ptr = png_nonconst_ptr; + png_const_structrp png_ptr = png_nonconst_ptr; png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr); /* An error is always logged here, overwriting anything (typically a warning) @@ -920,7 +920,7 @@ png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message), void /* PRIVATE */ PNGCBAPI png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message) { - const png_const_structrp png_ptr = png_nonconst_ptr; + png_const_structrp png_ptr = png_nonconst_ptr; png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr); /* A warning is only logged if there is no prior warning or error. */ diff --git a/src/3rdparty/libpng/pngget.c b/src/3rdparty/libpng/pngget.c index 2325508f1d..5abf1efd9f 100644 --- a/src/3rdparty/libpng/pngget.c +++ b/src/3rdparty/libpng/pngget.c @@ -1,10 +1,10 @@ /* pngget.c - retrieval of values from info struct * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer diff --git a/src/3rdparty/libpng/pnginfo.h b/src/3rdparty/libpng/pnginfo.h index 2fcf868dac..1f98dedc42 100644 --- a/src/3rdparty/libpng/pnginfo.h +++ b/src/3rdparty/libpng/pnginfo.h @@ -1,10 +1,10 @@ /* pnginfo.h - header file for PNG reference library * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2013,2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer diff --git a/src/3rdparty/libpng/pnglibconf.h b/src/3rdparty/libpng/pnglibconf.h index 00acecc69b..00340c678b 100644 --- a/src/3rdparty/libpng/pnglibconf.h +++ b/src/3rdparty/libpng/pnglibconf.h @@ -1,10 +1,9 @@ -/* libpng 1.6.35 STANDARD API DEFINITION */ - /* pnglibconf.h - library build configuration */ -/* Libpng version 1.6.35 - July 15, 2018 */ +/* libpng version 1.6.36 */ -/* Copyright (c) 1998-2018 Glenn Randers-Pehrson */ +/* Copyright (c) 2018 Cosmin Truta */ +/* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson */ /* This code is released under the libpng license. */ /* For conditions of distribution and use, see the disclaimer */ @@ -20,8 +19,6 @@ #define PNG_ALIGNED_MEMORY_SUPPORTED /*#undef PNG_ARM_NEON_API_SUPPORTED*/ /*#undef PNG_ARM_NEON_CHECK_SUPPORTED*/ -/*#undef PNG_POWERPC_VSX_API_SUPPORTED*/ -/*#undef PNG_POWERPC_VSX_CHECK_SUPPORTED*/ #define PNG_BENIGN_ERRORS_SUPPORTED #define PNG_BENIGN_READ_ERRORS_SUPPORTED /*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/ @@ -46,6 +43,8 @@ #define PNG_IO_STATE_SUPPORTED #define PNG_MNG_FEATURES_SUPPORTED #define PNG_POINTER_INDEXING_SUPPORTED +/*#undef PNG_POWERPC_VSX_API_SUPPORTED*/ +/*#undef PNG_POWERPC_VSX_CHECK_SUPPORTED*/ #define PNG_PROGRESSIVE_READ_SUPPORTED #define PNG_READ_16BIT_SUPPORTED #define PNG_READ_ALPHA_MODE_SUPPORTED diff --git a/src/3rdparty/libpng/pngmem.c b/src/3rdparty/libpng/pngmem.c index ff3ef7e88c..09ed9c1c99 100644 --- a/src/3rdparty/libpng/pngmem.c +++ b/src/3rdparty/libpng/pngmem.c @@ -1,10 +1,10 @@ /* pngmem.c - stub functions for memory allocation * - * Last changed in libpng 1.6.26 [October 20, 2016] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2014,2016 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer diff --git a/src/3rdparty/libpng/pngpread.c b/src/3rdparty/libpng/pngpread.c index c4ba51c4d4..e283627b77 100644 --- a/src/3rdparty/libpng/pngpread.c +++ b/src/3rdparty/libpng/pngpread.c @@ -1,10 +1,10 @@ /* pngpread.c - read a png file in push mode * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -972,20 +972,20 @@ png_read_push_finish_row(png_structrp png_ptr) /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Start of interlace block */ - static PNG_CONST png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; + static const png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; /* Offset to next interlace block */ - static PNG_CONST png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; + static const png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; /* Start of interlace block in the y direction */ - static PNG_CONST png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; + static const png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; /* Offset to next interlace block in the y direction */ - static PNG_CONST png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; + static const png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; /* Height of interlace block. This is not currently used - if you need * it, uncomment it here and in png.h - static PNG_CONST png_byte png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; + static const png_byte png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; */ #endif diff --git a/src/3rdparty/libpng/pngpriv.h b/src/3rdparty/libpng/pngpriv.h index e43862a886..f53c81d039 100644 --- a/src/3rdparty/libpng/pngpriv.h +++ b/src/3rdparty/libpng/pngpriv.h @@ -1,10 +1,10 @@ /* pngpriv.h - private declarations for use inside libpng * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -180,7 +180,10 @@ # else /* !defined __ARM_NEON__ */ /* The 'intrinsics' code simply won't compile without this -mfpu=neon: */ -# define PNG_ARM_NEON_IMPLEMENTATION 2 +# if !defined(__aarch64__) + /* The assembler code currently does not work on ARM64 */ +# define PNG_ARM_NEON_IMPLEMENTATION 2 +# endif /* __aarch64__ */ # endif /* __ARM_NEON__ */ # endif /* !PNG_ARM_NEON_IMPLEMENTATION */ @@ -1548,10 +1551,10 @@ PNG_INTERNAL_FUNCTION(void,png_handle_zTXt,(png_structrp png_ptr, #endif PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_const_structrp png_ptr, - const png_uint_32 chunk_name),PNG_EMPTY); + png_uint_32 chunk_name),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_check_chunk_length,(png_const_structrp png_ptr, - const png_uint_32 chunk_length),PNG_EMPTY); + png_uint_32 chunk_length),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_handle_unknown,(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length, int keep),PNG_EMPTY); @@ -2128,6 +2131,29 @@ PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_sse2, PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr, png_const_charp key, png_bytep new_key), PNG_EMPTY); +#if PNG_ARM_NEON_IMPLEMENTATION == 1 +PNG_INTERNAL_FUNCTION(void, + png_riffle_palette_rgba, + (png_structrp, png_row_infop), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(int, + png_do_expand_palette_neon_rgba, + (png_structrp, + png_row_infop, + png_const_bytep, + const png_bytepp, + const png_bytepp), + PNG_EMPTY); +PNG_INTERNAL_FUNCTION(int, + png_do_expand_palette_neon_rgb, + (png_structrp, + png_row_infop, + png_const_bytep, + const png_bytepp, + const png_bytepp), + PNG_EMPTY); +#endif + /* Maintainer: Put new private prototypes here ^ */ #include "pngdebug.h" diff --git a/src/3rdparty/libpng/pngread.c b/src/3rdparty/libpng/pngread.c index bff7503ee3..f8e762196e 100644 --- a/src/3rdparty/libpng/pngread.c +++ b/src/3rdparty/libpng/pngread.c @@ -1,10 +1,10 @@ /* pngread.c - read a PNG file * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -1621,7 +1621,7 @@ png_image_skip_unused_chunks(png_structrp png_ptr) * errors (which are unfortunately quite common.) */ { - static PNG_CONST png_byte chunks_to_process[] = { + static const png_byte chunks_to_process[] = { 98, 75, 71, 68, '\0', /* bKGD */ 99, 72, 82, 77, '\0', /* cHRM */ 103, 65, 77, 65, '\0', /* gAMA */ @@ -1758,9 +1758,9 @@ png_create_colormap_entry(png_image_read_control *display, png_uint_32 alpha, int encoding) { png_imagep image = display->image; - const int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) != 0 ? + int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) != 0 ? P_LINEAR : P_sRGB; - const int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 && + int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 && (red != green || green != blue); if (ip > 255) @@ -1869,13 +1869,13 @@ png_create_colormap_entry(png_image_read_control *display, /* Store the value. */ { # ifdef PNG_FORMAT_AFIRST_SUPPORTED - const int afirst = (image->format & PNG_FORMAT_FLAG_AFIRST) != 0 && + int afirst = (image->format & PNG_FORMAT_FLAG_AFIRST) != 0 && (image->format & PNG_FORMAT_FLAG_ALPHA) != 0; # else # define afirst 0 # endif # ifdef PNG_FORMAT_BGR_SUPPORTED - const int bgr = (image->format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0; + int bgr = (image->format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0; # else # define bgr 0 # endif @@ -2085,11 +2085,11 @@ png_image_read_colormap(png_voidp argument) { png_image_read_control *display = png_voidcast(png_image_read_control*, argument); - const png_imagep image = display->image; + png_imagep image = display->image; - const png_structrp png_ptr = image->opaque->png_ptr; - const png_uint_32 output_format = image->format; - const int output_encoding = (output_format & PNG_FORMAT_FLAG_LINEAR) != 0 ? + png_structrp png_ptr = image->opaque->png_ptr; + png_uint_32 output_format = image->format; + int output_encoding = (output_format & PNG_FORMAT_FLAG_LINEAR) != 0 ? P_LINEAR : P_sRGB; unsigned int cmap_entries; @@ -2802,7 +2802,7 @@ png_image_read_colormap(png_voidp argument) unsigned int num_trans = png_ptr->num_trans; png_const_bytep trans = num_trans > 0 ? png_ptr->trans_alpha : NULL; png_const_colorp colormap = png_ptr->palette; - const int do_background = trans != NULL && + int do_background = trans != NULL && (output_format & PNG_FORMAT_FLAG_ALPHA) == 0; unsigned int i; @@ -3946,7 +3946,7 @@ png_image_read_direct(png_voidp argument) */ if (linear != 0) { - PNG_CONST png_uint_16 le = 0x0001; + png_uint_16 le = 0x0001; if ((*(png_const_bytep) & le) != 0) png_set_swap(png_ptr); @@ -4108,7 +4108,7 @@ png_image_finish_read(png_imagep image, png_const_colorp background, * original PNG format because it may not occur in the output PNG format * and libpng deals with the issues of reading the original. */ - const unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format); + unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format); /* The following checks just the 'row_stride' calculation to ensure it * fits in a signed 32-bit value. Because channels/components can be @@ -4119,7 +4119,7 @@ png_image_finish_read(png_imagep image, png_const_colorp background, if (image->width <= 0x7fffffffU/channels) /* no overflow */ { png_uint_32 check; - const png_uint_32 png_row_stride = image->width * channels; + png_uint_32 png_row_stride = image->width * channels; if (row_stride == 0) row_stride = (png_int_32)/*SAFE*/png_row_stride; diff --git a/src/3rdparty/libpng/pngrio.c b/src/3rdparty/libpng/pngrio.c index 372221483f..7946358101 100644 --- a/src/3rdparty/libpng/pngrio.c +++ b/src/3rdparty/libpng/pngrio.c @@ -1,10 +1,10 @@ /* pngrio.c - functions for data input * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer diff --git a/src/3rdparty/libpng/pngrtran.c b/src/3rdparty/libpng/pngrtran.c index 67d1f249a6..ccc58ce6f1 100644 --- a/src/3rdparty/libpng/pngrtran.c +++ b/src/3rdparty/libpng/pngrtran.c @@ -1,10 +1,10 @@ /* pngrtran.c - transforms the data in a row for PNG readers * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -18,6 +18,17 @@ #include "pngpriv.h" +#ifdef PNG_ARM_NEON_IMPLEMENTATION +# if PNG_ARM_NEON_IMPLEMENTATION == 1 +# define PNG_ARM_NEON_INTRINSICS_AVAILABLE +# if defined(_MSC_VER) && defined(_M_ARM64) +# include +# else +# include +# endif +# endif +#endif + #ifdef PNG_READ_SUPPORTED /* Set the action on getting a CRC error for an ancillary or critical chunk. */ @@ -2986,7 +2997,6 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) */ static int png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row) - { int rgb_error = 0; @@ -2995,12 +3005,11 @@ png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row) if ((row_info->color_type & PNG_COLOR_MASK_PALETTE) == 0 && (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) { - PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; - PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; - PNG_CONST png_uint_32 bc = 32768 - rc - gc; - PNG_CONST png_uint_32 row_width = row_info->width; - PNG_CONST int have_alpha = - (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0; + png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; + png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; + png_uint_32 bc = 32768 - rc - gc; + png_uint_32 row_width = row_info->width; + int have_alpha = (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0; if (row_info->bit_depth == 8) { @@ -4143,12 +4152,11 @@ png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr) { if (row_info->bit_depth == 8) { - PNG_CONST png_bytep table = png_ptr->gamma_from_1; + png_bytep table = png_ptr->gamma_from_1; if (table != NULL) { - PNG_CONST int step = - (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2; + int step = (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2; /* The alpha channel is the last component: */ row += step - 1; @@ -4162,13 +4170,12 @@ png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr) else if (row_info->bit_depth == 16) { - PNG_CONST png_uint_16pp table = png_ptr->gamma_16_from_1; - PNG_CONST int gamma_shift = png_ptr->gamma_shift; + png_uint_16pp table = png_ptr->gamma_16_from_1; + int gamma_shift = png_ptr->gamma_shift; if (table != NULL) { - PNG_CONST int step = - (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4; + int step = (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4; /* The alpha channel is the last component: */ row += step - 2; @@ -4199,8 +4206,9 @@ png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr) * upon whether you supply trans and num_trans. */ static void -png_do_expand_palette(png_row_infop row_info, png_bytep row, - png_const_colorp palette, png_const_bytep trans_alpha, int num_trans) +png_do_expand_palette(png_structrp png_ptr, png_row_infop row_info, + png_bytep row, png_const_colorp palette, png_const_bytep trans_alpha, + int num_trans) { int shift, value; png_bytep sp, dp; @@ -4304,14 +4312,25 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, sp = row + (size_t)row_width - 1; dp = row + ((size_t)row_width << 2) - 1; - for (i = 0; i < row_width; i++) + i = 0; +#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE + if (png_ptr->riffled_palette != NULL) + { + /* The RGBA optimization works with png_ptr->bit_depth == 8 + * but sometimes row_info->bit_depth has been changed to 8. + * In these cases, the palette hasn't been riffled. + */ + i = png_do_expand_palette_neon_rgba(png_ptr, row_info, row, + &sp, &dp); + } +#endif + + for (; i < row_width; i++) { if ((int)(*sp) >= num_trans) *dp-- = 0xff; - else *dp-- = trans_alpha[*sp]; - *dp-- = palette[*sp].blue; *dp-- = palette[*sp].green; *dp-- = palette[*sp].red; @@ -4328,8 +4347,13 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, { sp = row + (size_t)row_width - 1; dp = row + (size_t)(row_width * 3) - 1; + i = 0; +#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE + i = png_do_expand_palette_neon_rgb(png_ptr, row_info, row, + &sp, &dp); +#endif - for (i = 0; i < row_width; i++) + for (; i < row_width; i++) { *dp-- = palette[*sp].blue; *dp-- = palette[*sp].green; @@ -4743,8 +4767,22 @@ png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info) { if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) { - png_do_expand_palette(row_info, png_ptr->row_buf + 1, - png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); +#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE + if ((png_ptr->num_trans > 0) && (png_ptr->bit_depth == 8)) + { + /* Allocate space for the decompressed full palette. */ + if (png_ptr->riffled_palette == NULL) + { + png_ptr->riffled_palette = png_malloc(png_ptr, 256*4); + if (png_ptr->riffled_palette == NULL) + png_error(png_ptr, "NULL row buffer"); + /* Build the RGBA palette. */ + png_riffle_palette_rgba(png_ptr, row_info); + } + } +#endif + png_do_expand_palette(png_ptr, row_info, png_ptr->row_buf + 1, + png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); } else diff --git a/src/3rdparty/libpng/pngrutil.c b/src/3rdparty/libpng/pngrutil.c index 7001f1976e..d5fa08c397 100644 --- a/src/3rdparty/libpng/pngrutil.c +++ b/src/3rdparty/libpng/pngrutil.c @@ -1,10 +1,10 @@ /* pngrutil.c - utilities to read a PNG file * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -1461,8 +1461,7 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) { /* We have the ICC profile header; do the basic header checks. */ - const png_uint_32 profile_length = - png_get_uint_32(profile_header); + png_uint_32 profile_length = png_get_uint_32(profile_header); if (png_icc_check_length(png_ptr, &png_ptr->colorspace, keyword, profile_length) != 0) @@ -1479,8 +1478,8 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) * profile. The header check has already validated * that none of this stuff will overflow. */ - const png_uint_32 tag_count = png_get_uint_32( - profile_header+128); + png_uint_32 tag_count = + png_get_uint_32(profile_header + 128); png_bytep profile = png_read_buffer(png_ptr, profile_length, 2/*silent*/); @@ -3132,7 +3131,7 @@ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr, */ void /* PRIVATE */ -png_check_chunk_name(png_const_structrp png_ptr, const png_uint_32 chunk_name) +png_check_chunk_name(png_const_structrp png_ptr, png_uint_32 chunk_name) { int i; png_uint_32 cn=chunk_name; @@ -3151,7 +3150,7 @@ png_check_chunk_name(png_const_structrp png_ptr, const png_uint_32 chunk_name) } void /* PRIVATE */ -png_check_chunk_length(png_const_structrp png_ptr, const png_uint_32 length) +png_check_chunk_length(png_const_structrp png_ptr, png_uint_32 length) { png_alloc_size_t limit = PNG_UINT_31_MAX; @@ -3363,7 +3362,7 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display) /* Hence the pre-compiled masks indexed by PACKSWAP (or not), depth and * then pass: */ - static PNG_CONST png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] = + static const png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] = { /* Little-endian byte masks for PACKSWAP */ { S_MASKS(1,0), S_MASKS(2,0), S_MASKS(4,0) }, @@ -3374,7 +3373,7 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display) /* display_mask has only three entries for the odd passes, so index by * pass>>1. */ - static PNG_CONST png_uint_32 display_mask[2][3][3] = + static const png_uint_32 display_mask[2][3][3] = { /* Little-endian byte masks for PACKSWAP */ { B_MASKS(1,0), B_MASKS(2,0), B_MASKS(4,0) }, @@ -3687,7 +3686,7 @@ png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, { /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Offset to next interlace block */ - static PNG_CONST unsigned int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + static const unsigned int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; png_debug(1, "in png_do_read_interlace"); if (row != NULL && row_info != NULL) @@ -4329,16 +4328,16 @@ png_read_finish_row(png_structrp png_ptr) /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Start of interlace block */ - static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; /* Offset to next interlace block */ - static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; /* Start of interlace block in the y direction */ - static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; /* Offset to next interlace block in the y direction */ - static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; + static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; png_debug(1, "in png_read_finish_row"); png_ptr->row_number++; @@ -4394,16 +4393,16 @@ png_read_start_row(png_structrp png_ptr) /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Start of interlace block */ - static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; /* Offset to next interlace block */ - static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; /* Start of interlace block in the y direction */ - static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; /* Offset to next interlace block in the y direction */ - static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; + static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; unsigned int max_pixel_depth; size_t row_bytes; diff --git a/src/3rdparty/libpng/pngset.c b/src/3rdparty/libpng/pngset.c index 7cf54d9248..ec75dbe369 100644 --- a/src/3rdparty/libpng/pngset.c +++ b/src/3rdparty/libpng/pngset.c @@ -1,10 +1,10 @@ /* pngset.c - storage of image information into info struct * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -137,7 +137,7 @@ png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X, #ifdef PNG_eXIf_SUPPORTED void PNGAPI png_set_eXIf(png_const_structrp png_ptr, png_inforp info_ptr, - const png_bytep eXIf_buf) + png_bytep eXIf_buf) { png_warning(png_ptr, "png_set_eXIf does not work; use png_set_eXIf_1"); PNG_UNUSED(info_ptr) @@ -146,7 +146,7 @@ png_set_eXIf(png_const_structrp png_ptr, png_inforp info_ptr, void PNGAPI png_set_eXIf_1(png_const_structrp png_ptr, png_inforp info_ptr, - const png_uint_32 num_exif, const png_bytep eXIf_buf) + png_uint_32 num_exif, png_bytep eXIf_buf) { int i; @@ -1399,7 +1399,7 @@ png_set_keep_unknown_chunks(png_structrp png_ptr, int keep, /* Ignore all unknown chunks and all chunks recognized by * libpng except for IHDR, PLTE, tRNS, IDAT, and IEND */ - static PNG_CONST png_byte chunks_to_ignore[] = { + static const png_byte chunks_to_ignore[] = { 98, 75, 71, 68, '\0', /* bKGD */ 99, 72, 82, 77, '\0', /* cHRM */ 101, 88, 73, 102, '\0', /* eXIf */ diff --git a/src/3rdparty/libpng/pngstruct.h b/src/3rdparty/libpng/pngstruct.h index 699e8ac68a..94a6d041ff 100644 --- a/src/3rdparty/libpng/pngstruct.h +++ b/src/3rdparty/libpng/pngstruct.h @@ -1,10 +1,10 @@ /* pngstruct.h - header file for PNG reference library * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -228,6 +228,10 @@ struct png_struct_def * big_row_buf; while writing it is separately * allocated. */ +#ifdef PNG_READ_EXPAND_SUPPORTED + /* Buffer to accelerate palette transformations. */ + png_bytep riffled_palette; +#endif #ifdef PNG_WRITE_FILTER_SUPPORTED png_bytep try_row; /* buffer to save trial row when filtering */ png_bytep tst_row; /* buffer to save best trial row when filtering */ diff --git a/src/3rdparty/libpng/pngtrans.c b/src/3rdparty/libpng/pngtrans.c index de84aa6d6b..1100f46ebe 100644 --- a/src/3rdparty/libpng/pngtrans.c +++ b/src/3rdparty/libpng/pngtrans.c @@ -1,10 +1,10 @@ /* pngtrans.c - transforms the data in a row (used by both readers and writers) * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -345,7 +345,7 @@ png_do_swap(png_row_infop row_info, png_bytep row) #endif #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) -static PNG_CONST png_byte onebppswaptable[256] = { +static const png_byte onebppswaptable[256] = { 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, @@ -380,7 +380,7 @@ static PNG_CONST png_byte onebppswaptable[256] = { 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF }; -static PNG_CONST png_byte twobppswaptable[256] = { +static const png_byte twobppswaptable[256] = { 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0, 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0, 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4, @@ -415,7 +415,7 @@ static PNG_CONST png_byte twobppswaptable[256] = { 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF }; -static PNG_CONST png_byte fourbppswaptable[256] = { +static const png_byte fourbppswaptable[256] = { 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, diff --git a/src/3rdparty/libpng/pngwio.c b/src/3rdparty/libpng/pngwio.c index e5391687a2..10e919dd03 100644 --- a/src/3rdparty/libpng/pngwio.c +++ b/src/3rdparty/libpng/pngwio.c @@ -1,10 +1,10 @@ /* pngwio.c - functions for data output * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2014,2016,2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer diff --git a/src/3rdparty/libpng/pngwrite.c b/src/3rdparty/libpng/pngwrite.c index 5bd87f373e..160c877d38 100644 --- a/src/3rdparty/libpng/pngwrite.c +++ b/src/3rdparty/libpng/pngwrite.c @@ -1,10 +1,10 @@ /* pngwrite.c - general routines to write a PNG file * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -469,7 +469,7 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr) #ifdef PNG_CONVERT_tIME_SUPPORTED void PNGAPI -png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm * ttime) +png_convert_from_struct_tm(png_timep ptime, const struct tm * ttime) { png_debug(1, "in png_convert_from_struct_tm"); @@ -948,6 +948,10 @@ png_write_destroy(png_structrp png_ptr) png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list); png_free(png_ptr, png_ptr->row_buf); png_ptr->row_buf = NULL; +#ifdef PNG_READ_EXPANDED_SUPPORTED + png_free(png_ptr, png_ptr->riffled_palette); + png_ptr->riffled_palette = NULL; +#endif #ifdef PNG_WRITE_FILTER_SUPPORTED png_free(png_ptr, png_ptr->prev_row); png_free(png_ptr, png_ptr->try_row); @@ -1536,7 +1540,7 @@ png_write_image_16bit(png_voidp argument) display->first_row); png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row); png_uint_16p row_end; - const unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? + unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1; int aindex = 0; png_uint_32 y = image->height; @@ -1573,7 +1577,7 @@ png_write_image_16bit(png_voidp argument) while (out_ptr < row_end) { - const png_uint_16 alpha = in_ptr[aindex]; + png_uint_16 alpha = in_ptr[aindex]; png_uint_32 reciprocal = 0; int c; @@ -1695,7 +1699,7 @@ png_write_image_8bit(png_voidp argument) display->first_row); png_bytep output_row = png_voidcast(png_bytep, display->local_row); png_uint_32 y = image->height; - const unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? + unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1; if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0) @@ -1783,25 +1787,25 @@ png_write_image_8bit(png_voidp argument) static void png_image_set_PLTE(png_image_write_control *display) { - const png_imagep image = display->image; + png_imagep image = display->image; const void *cmap = display->colormap; - const int entries = image->colormap_entries > 256 ? 256 : + int entries = image->colormap_entries > 256 ? 256 : (int)image->colormap_entries; /* NOTE: the caller must check for cmap != NULL and entries != 0 */ - const png_uint_32 format = image->format; - const unsigned int channels = PNG_IMAGE_SAMPLE_CHANNELS(format); + png_uint_32 format = image->format; + unsigned int channels = PNG_IMAGE_SAMPLE_CHANNELS(format); # if defined(PNG_FORMAT_BGR_SUPPORTED) &&\ defined(PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED) - const int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 && + int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 && (format & PNG_FORMAT_FLAG_ALPHA) != 0; # else # define afirst 0 # endif # ifdef PNG_FORMAT_BGR_SUPPORTED - const int bgr = (format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0; + int bgr = (format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0; # else # define bgr 0 # endif @@ -1951,12 +1955,12 @@ png_image_write_main(png_voidp argument) * and total image size to ensure that they are within the system limits. */ { - const unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format); + unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format); if (image->width <= 0x7fffffffU/channels) /* no overflow */ { png_uint_32 check; - const png_uint_32 png_row_stride = image->width * channels; + png_uint_32 png_row_stride = image->width * channels; if (display->row_stride == 0) display->row_stride = (png_int_32)/*SAFE*/png_row_stride; @@ -2052,7 +2056,7 @@ png_image_write_main(png_voidp argument) */ if (write_16bit != 0) { - PNG_CONST png_uint_16 le = 0x0001; + png_uint_16 le = 0x0001; if ((*(png_const_bytep) & le) != 0) png_set_swap(png_ptr); @@ -2166,7 +2170,7 @@ image_memory_write)(png_structp png_ptr, png_bytep/*const*/ data, size_t size) { png_image_write_control *display = png_voidcast(png_image_write_control*, png_ptr->io_ptr/*backdoor: png_get_io_ptr(png_ptr)*/); - const png_alloc_size_t ob = display->output_bytes; + png_alloc_size_t ob = display->output_bytes; /* Check for overflow; this should never happen: */ if (size <= ((png_alloc_size_t)-1) - ob) diff --git a/src/3rdparty/libpng/pngwtran.c b/src/3rdparty/libpng/pngwtran.c index 3a1e0a21d2..49a13c1e98 100644 --- a/src/3rdparty/libpng/pngwtran.c +++ b/src/3rdparty/libpng/pngwtran.c @@ -1,10 +1,10 @@ /* pngwtran.c - transforms the data in a row for PNG writers * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -254,8 +254,7 @@ png_do_shift(png_row_infop row_info, png_bytep row, for (i = 0; i < istop; i++, bp++) { - - const unsigned int c = i%channels; + unsigned int c = i%channels; int j; unsigned int v, out; @@ -283,7 +282,7 @@ png_do_shift(png_row_infop row_info, png_bytep row, for (bp = row, i = 0; i < istop; i++) { - const unsigned int c = i%channels; + unsigned int c = i%channels; int j; unsigned int value, v; diff --git a/src/3rdparty/libpng/pngwutil.c b/src/3rdparty/libpng/pngwutil.c index ab431e712c..16345e4c0b 100644 --- a/src/3rdparty/libpng/pngwutil.c +++ b/src/3rdparty/libpng/pngwutil.c @@ -1,10 +1,10 @@ /* pngwutil.c - utilities to write a PNG file * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -1893,16 +1893,16 @@ png_write_start_row(png_structrp png_ptr) /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Start of interlace block */ - static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; /* Offset to next interlace block */ - static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; /* Start of interlace block in the y direction */ - static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; /* Offset to next interlace block in the y direction */ - static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; + static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; #endif png_alloc_size_t buf_size; @@ -2008,16 +2008,16 @@ png_write_finish_row(png_structrp png_ptr) /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Start of interlace block */ - static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; /* Offset to next interlace block */ - static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; /* Start of interlace block in the y direction */ - static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; /* Offset to next interlace block in the y direction */ - static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; + static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; #endif png_debug(1, "in png_write_finish_row"); @@ -2098,10 +2098,10 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Start of interlace block */ - static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; /* Offset to next interlace block */ - static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; png_debug(1, "in png_do_write_interlace"); @@ -2276,7 +2276,7 @@ png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row, #ifdef PNG_WRITE_FILTER_SUPPORTED static size_t /* PRIVATE */ -png_setup_sub_row(png_structrp png_ptr, const png_uint_32 bpp, +png_setup_sub_row(png_structrp png_ptr, png_uint_32 bpp, size_t row_bytes, size_t lmins) { png_bytep rp, dp, lp; @@ -2315,7 +2315,7 @@ png_setup_sub_row(png_structrp png_ptr, const png_uint_32 bpp, } static void /* PRIVATE */ -png_setup_sub_row_only(png_structrp png_ptr, const png_uint_32 bpp, +png_setup_sub_row_only(png_structrp png_ptr, png_uint_32 bpp, size_t row_bytes) { png_bytep rp, dp, lp; @@ -2380,7 +2380,7 @@ png_setup_up_row_only(png_structrp png_ptr, size_t row_bytes) } static size_t /* PRIVATE */ -png_setup_avg_row(png_structrp png_ptr, const png_uint_32 bpp, +png_setup_avg_row(png_structrp png_ptr, png_uint_32 bpp, size_t row_bytes, size_t lmins) { png_bytep rp, dp, pp, lp; @@ -2420,7 +2420,7 @@ png_setup_avg_row(png_structrp png_ptr, const png_uint_32 bpp, return (sum); } static void /* PRIVATE */ -png_setup_avg_row_only(png_structrp png_ptr, const png_uint_32 bpp, +png_setup_avg_row_only(png_structrp png_ptr, png_uint_32 bpp, size_t row_bytes) { png_bytep rp, dp, pp, lp; @@ -2442,7 +2442,7 @@ png_setup_avg_row_only(png_structrp png_ptr, const png_uint_32 bpp, } static size_t /* PRIVATE */ -png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp, +png_setup_paeth_row(png_structrp png_ptr, png_uint_32 bpp, size_t row_bytes, size_t lmins) { png_bytep rp, dp, pp, cp, lp; @@ -2503,7 +2503,7 @@ png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp, return (sum); } static void /* PRIVATE */ -png_setup_paeth_row_only(png_structrp png_ptr, const png_uint_32 bpp, +png_setup_paeth_row_only(png_structrp png_ptr, png_uint_32 bpp, size_t row_bytes) { png_bytep rp, dp, pp, cp, lp; diff --git a/src/3rdparty/libpng/qt_attribution.json b/src/3rdparty/libpng/qt_attribution.json index 2f82b4c1c6..a0fd149bf4 100644 --- a/src/3rdparty/libpng/qt_attribution.json +++ b/src/3rdparty/libpng/qt_attribution.json @@ -6,9 +6,9 @@ "Description": "libpng is the official PNG reference library.", "Homepage": "http://www.libpng.org/pub/png/libpng.html", - "Version": "1.6.35", - "License": "libpng License", - "LicenseId": "Libpng", + "Version": "1.6.36", + "License": "libpng License and libpng License 2", + "LicenseId": "Libpng AND Libpng2", "LicenseFile": "LICENSE", "Copyright": "Copyright (c) 1998-2018 Glenn Randers-Pehrson Copyright (c) 2000-2017 Simon-Pierre Cadieux From fe29a6a6ebbf28505df7cdf1de24fa540fd3745e Mon Sep 17 00:00:00 2001 From: Ryan Chu Date: Wed, 9 Jan 2019 00:19:10 +0100 Subject: [PATCH 0862/1650] Fix the timing issue of vsftpd during boot (probably invalid config) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This appears to be a timing issue of vsftpd's initial script (/etc/init.d/vsftpd). When starting the vsftpd service, the script uses a while loop to make sure that the vsftpd process has been created with the expected PID. The problem is that it should sleep if it can't grep the same PID via ps command. while [ ${n} -le 5 ] do _PID="$(if [ -e ...vsftpd.pid ]; then cat ...vsftpd.pid; fi)" if ! ps -C vsftpd | grep -qs "${_PID}" then break fi sleep 1 n=$(( $n + 1 )) done if ! ps -C vsftpd | grep -qs "${_PID}" then log_warning_msg "vsftpd failed - probably invalid config." exit 1 fi However, synchronization based on time is not working in general. This change will rewrite the while loop to an infinite loop and remove the exclamation symbol (!) from the if condition. Upgrading the version of vsftpd is not helpful here because vsftpd_3.0.3-11 (Ubuntu 18.10) didn't resolve it yet. Change-Id: I07382709c33bd9bab61fcea76ab7deca5f630084 Reviewed-by: Jędrzej Nowacki Reviewed-by: Edward Welbourne --- tests/testserver/vsftpd/vsftpd.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/testserver/vsftpd/vsftpd.sh b/tests/testserver/vsftpd/vsftpd.sh index 845c576534..14364f94c2 100755 --- a/tests/testserver/vsftpd/vsftpd.sh +++ b/tests/testserver/vsftpd/vsftpd.sh @@ -41,9 +41,10 @@ useradd -d "/home/$USER/ftp" -s /bin/bash ftptest; echo "ftptest:$PASS" | chpass cp $TESTDATA/vsftpd.{conf,user_list} /etc/ # Resolve error message "vsftpd failed - probably invalid config" during boot -command='start-stop-daemon --start --background -m --oknodo --pidfile /var/run/vsftpd/vsftpd.pid' -command+=' --exec ${DAEMON}' -sed -i "s,$command.*$,$command; sleep 10," /etc/init.d/vsftpd +# This bug has been reported to Debian bug tracking system (ID #911396) +command='ps -C vsftpd | grep -qs "${_PID}"' +sed -i -e 's,while [ ${n} -le 5 ].*$,while true,' \ + -e "s,\t\t\tif ! $command.*$,\t\t\tif $command," /etc/init.d/vsftpd # Populate the FTP sites: su $USER -c "cp -r $TESTDATA/ftp ~/ftp" From a53500f5bf75a89e2a616781c806553568531e5a Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 16 Jan 2019 13:47:12 +0100 Subject: [PATCH 0863/1650] Eliminate some stray misleading paths from expected output files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The output files for the tuplediagnostics selftest of testlib had a stray non-canoical path fragment in them; so replaced with its canonical form. Change-Id: Ib421380036c3fb1b91447eb8c87be4ad0dfe5c96 Reviewed-by: Jędrzej Nowacki --- .../testlib/selftests/expected_tuplediagnostics.lightxml | 4 ++-- .../auto/testlib/selftests/expected_tuplediagnostics.tap | 8 ++++---- .../testlib/selftests/expected_tuplediagnostics.teamcity | 4 ++-- .../auto/testlib/selftests/expected_tuplediagnostics.txt | 4 ++-- .../auto/testlib/selftests/expected_tuplediagnostics.xml | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/auto/testlib/selftests/expected_tuplediagnostics.lightxml b/tests/auto/testlib/selftests/expected_tuplediagnostics.lightxml index 810941d894..85f8fac42a 100644 --- a/tests/auto/testlib/selftests/expected_tuplediagnostics.lightxml +++ b/tests/auto/testlib/selftests/expected_tuplediagnostics.lightxml @@ -12,7 +12,7 @@ - + {1}): std::tuple(1) Expected (std::tuple{2}): std::tuple(2)]]> @@ -20,7 +20,7 @@ - + diff --git a/tests/auto/testlib/selftests/expected_tuplediagnostics.tap b/tests/auto/testlib/selftests/expected_tuplediagnostics.tap index 9e007c14e1..a079a9bf40 100644 --- a/tests/auto/testlib/selftests/expected_tuplediagnostics.tap +++ b/tests/auto/testlib/selftests/expected_tuplediagnostics.tap @@ -10,8 +10,8 @@ not ok 3 - testSimpleTuple() found: std::tuple(1) (std::tuple{1}) expected: std::tuple(2) (std::tuple{2}) actual: std::tuple(1) (std::tuple{1}) - at: tst_TupleDiagnostics::testSimpleTuple() (/localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp:53) - file: /localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp + at: tst_TupleDiagnostics::testSimpleTuple() (qtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp:53) + file: qtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp line: 53 ... not ok 4 - testTuple() @@ -22,8 +22,8 @@ not ok 4 - testTuple() found: std::tuple(42, 'Y', "tuple1") (tuple1) expected: std::tuple(42, 'Y', "tuple2") (tuple2) actual: std::tuple(42, 'Y', "tuple1") (tuple1) - at: tst_TupleDiagnostics::testTuple() (/localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp:60) - file: /localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp + at: tst_TupleDiagnostics::testTuple() (qtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp:60) + file: qtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp line: 60 ... ok 5 - cleanupTestCase() diff --git a/tests/auto/testlib/selftests/expected_tuplediagnostics.teamcity b/tests/auto/testlib/selftests/expected_tuplediagnostics.teamcity index a395857c60..7256992518 100644 --- a/tests/auto/testlib/selftests/expected_tuplediagnostics.teamcity +++ b/tests/auto/testlib/selftests/expected_tuplediagnostics.teamcity @@ -4,10 +4,10 @@ ##teamcity[testStarted name='testEmptyTuple()' flowId='tst_TupleDiagnostics'] ##teamcity[testFinished name='testEmptyTuple()' flowId='tst_TupleDiagnostics'] ##teamcity[testStarted name='testSimpleTuple()' flowId='tst_TupleDiagnostics'] -##teamcity[testFailed name='testSimpleTuple()' message='Failure! |[Loc: /localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp(0)|]' details='Compared values are not the same|n Actual (std::tuple{1}): std::tuple(1)|n Expected (std::tuple{2}): std::tuple(2)' flowId='tst_TupleDiagnostics'] +##teamcity[testFailed name='testSimpleTuple()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp(0)|]' details='Compared values are not the same|n Actual (std::tuple{1}): std::tuple(1)|n Expected (std::tuple{2}): std::tuple(2)' flowId='tst_TupleDiagnostics'] ##teamcity[testFinished name='testSimpleTuple()' flowId='tst_TupleDiagnostics'] ##teamcity[testStarted name='testTuple()' flowId='tst_TupleDiagnostics'] -##teamcity[testFailed name='testTuple()' message='Failure! |[Loc: /localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp(0)|]' details='Compared values are not the same|n Actual (tuple1): std::tuple(42, |'Y|', "tuple1")|n Expected (tuple2): std::tuple(42, |'Y|', "tuple2")' flowId='tst_TupleDiagnostics'] +##teamcity[testFailed name='testTuple()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp(0)|]' details='Compared values are not the same|n Actual (tuple1): std::tuple(42, |'Y|', "tuple1")|n Expected (tuple2): std::tuple(42, |'Y|', "tuple2")' flowId='tst_TupleDiagnostics'] ##teamcity[testFinished name='testTuple()' flowId='tst_TupleDiagnostics'] ##teamcity[testStarted name='cleanupTestCase()' flowId='tst_TupleDiagnostics'] ##teamcity[testFinished name='cleanupTestCase()' flowId='tst_TupleDiagnostics'] diff --git a/tests/auto/testlib/selftests/expected_tuplediagnostics.txt b/tests/auto/testlib/selftests/expected_tuplediagnostics.txt index ce568bf6c0..8d121acc83 100644 --- a/tests/auto/testlib/selftests/expected_tuplediagnostics.txt +++ b/tests/auto/testlib/selftests/expected_tuplediagnostics.txt @@ -5,11 +5,11 @@ PASS : tst_TupleDiagnostics::testEmptyTuple() FAIL! : tst_TupleDiagnostics::testSimpleTuple() Compared values are not the same Actual (std::tuple{1}): std::tuple(1) Expected (std::tuple{2}): std::tuple(2) - Loc: [/localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp(0)] + Loc: [qtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp(0)] FAIL! : tst_TupleDiagnostics::testTuple() Compared values are not the same Actual (tuple1): std::tuple(42, 'Y', "tuple1") Expected (tuple2): std::tuple(42, 'Y', "tuple2") - Loc: [/localqtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp(0)] + Loc: [qtbase/tests/auto/testlib/selftests/tuplediagnostics/tst_tuplediagnostics.cpp(0)] PASS : tst_TupleDiagnostics::cleanupTestCase() Totals: 3 passed, 2 failed, 0 skipped, 0 blacklisted, 0ms ********* Finished testing of tst_TupleDiagnostics ********* diff --git a/tests/auto/testlib/selftests/expected_tuplediagnostics.xml b/tests/auto/testlib/selftests/expected_tuplediagnostics.xml index 4c55a6d393..f32974adb4 100644 --- a/tests/auto/testlib/selftests/expected_tuplediagnostics.xml +++ b/tests/auto/testlib/selftests/expected_tuplediagnostics.xml @@ -14,7 +14,7 @@ - + {1}): std::tuple(1) Expected (std::tuple{2}): std::tuple(2)]]> @@ -22,7 +22,7 @@ - + From ccfd6872badaed768df14076dc46afcb2b3c861a Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 11 Jan 2019 20:18:23 +0100 Subject: [PATCH 0864/1650] QSqlRelationalDelegate: compile with QT_NO_CAST_FROM_BYTEARRAY QSqlRelationalDelegate::setEditorData() does not compile when QT_NO_CAST_FROM_BYTEARRAY is defined. Since it's a public header this will break user code. Fix it by calling QByteArray::data() instead of relying on the implicit cast. Fixes: QTBUG-72764 Change-Id: I9c111dd25f48c9c9780d9f9a5b6b75eed0c8d6ed Reviewed-by: Edward Welbourne Reviewed-by: Andy Shaw --- src/sql/models/qsqlrelationaldelegate.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sql/models/qsqlrelationaldelegate.h b/src/sql/models/qsqlrelationaldelegate.h index e8ae5a229d..ca5c46778f 100644 --- a/src/sql/models/qsqlrelationaldelegate.h +++ b/src/sql/models/qsqlrelationaldelegate.h @@ -109,11 +109,11 @@ QWidget *createEditor(QWidget *aParent, // to present the DisplayRole and not the EditRole which // is the id reference to the related model QVariant v = index.data(Qt::DisplayRole); - QByteArray n = editor->metaObject()->userProperty().name(); + const QByteArray n = editor->metaObject()->userProperty().name(); if (!n.isEmpty()) { if (!v.isValid()) - v = QVariant(editor->property(n).userType(), nullptr); - editor->setProperty(n, v); + v = QVariant(editor->property(n.data()).userType(), nullptr); + editor->setProperty(n.data(), v); return; } } From 83aa70f0ca5e5c7427a3493c4d3dbc398735a5df Mon Sep 17 00:00:00 2001 From: Vyacheslav Koscheev Date: Wed, 16 Jan 2019 13:11:37 +0700 Subject: [PATCH 0865/1650] Android: fix NPE on m_editPopupMenu Change-Id: Id6d4aea91d621194cf85f604b1b9acdc916bede1 Reviewed-by: Olivier Goffart (Woboq GmbH) --- .../src/org/qtproject/qt5/android/QtActivityDelegate.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index 74b515ef5b..02033859e9 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -506,7 +506,8 @@ public class QtActivityDelegate m_rightSelectionHandle = null; m_leftSelectionHandle = null; } - m_editPopupMenu.hide(); + if (m_editPopupMenu != null) + m_editPopupMenu.hide(); break; case CursorHandleShowNormal: @@ -561,7 +562,8 @@ public class QtActivityDelegate } m_editPopupMenu.setPosition(editX, editY, editButtons); } else { - m_editPopupMenu.hide(); + if (m_editPopupMenu != null) + m_editPopupMenu.hide(); } } From 9d2923c1b048b519c352c40bf26328dacef9304e Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 18 Jan 2019 20:52:36 +0100 Subject: [PATCH 0866/1650] tst_QString: fix localeAwareCompare() when using ICU tst_QString::localeAwareCompare() is failing since ab448f731ecd8437c7c5c8b96a0e7f419ec3a7ca because the 'C' locale no longer initializes ICU and falls back to simple QString comparison. Fix it by explicitly setting the locale for the testdata to en_US so the QCollator is properly initialized. Task-number: QTBUG-73116 Change-Id: I9d4d55e666c5c52f93298dedb7e22da01a25318d Reviewed-by: Thiago Macieira --- .../corelib/tools/qstring/tst_qstring.cpp | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index f429bda804..c78cd2276f 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -5521,35 +5521,35 @@ void tst_QString::localeAwareCompare_data() // console.log("\u1111\u1171\u11B6".localeCompare("\ud4db") // example from Unicode 5.0, section 3.7, definition D70 - QTest::newRow("normalize1") << QString() << QString::fromUtf8("o\xCC\x88") << QString::fromUtf8("\xC3\xB6") << 0; + QTest::newRow("normalize1") << QString("en_US") << QString::fromUtf8("o\xCC\x88") << QString::fromUtf8("\xC3\xB6") << 0; // examples from Unicode 5.0, chapter 3.11 - QTest::newRow("normalize2") << QString() << QString::fromUtf8("\xC3\xA4\xCC\xA3") << QString::fromUtf8("a\xCC\xA3\xCC\x88") << 0; - QTest::newRow("normalize3") << QString() << QString::fromUtf8("a\xCC\x88\xCC\xA3") << QString::fromUtf8("a\xCC\xA3\xCC\x88") << 0; - QTest::newRow("normalize4") << QString() << QString::fromUtf8("\xE1\xBA\xA1\xCC\x88") << QString::fromUtf8("a\xCC\xA3\xCC\x88") << 0; - QTest::newRow("normalize5") << QString() << QString::fromUtf8("\xC3\xA4\xCC\x86") << QString::fromUtf8("a\xCC\x88\xCC\x86") << 0; - QTest::newRow("normalize6") << QString() << QString::fromUtf8("\xC4\x83\xCC\x88") << QString::fromUtf8("a\xCC\x86\xCC\x88") << 0; + QTest::newRow("normalize2") << QString("en_US") << QString::fromUtf8("\xC3\xA4\xCC\xA3") << QString::fromUtf8("a\xCC\xA3\xCC\x88") << 0; + QTest::newRow("normalize3") << QString("en_US") << QString::fromUtf8("a\xCC\x88\xCC\xA3") << QString::fromUtf8("a\xCC\xA3\xCC\x88") << 0; + QTest::newRow("normalize4") << QString("en_US") << QString::fromUtf8("\xE1\xBA\xA1\xCC\x88") << QString::fromUtf8("a\xCC\xA3\xCC\x88") << 0; + QTest::newRow("normalize5") << QString("en_US") << QString::fromUtf8("\xC3\xA4\xCC\x86") << QString::fromUtf8("a\xCC\x88\xCC\x86") << 0; + QTest::newRow("normalize6") << QString("en_US") << QString::fromUtf8("\xC4\x83\xCC\x88") << QString::fromUtf8("a\xCC\x86\xCC\x88") << 0; // example from Unicode 5.0, chapter 3.12 - QTest::newRow("normalize7") << QString() << QString::fromUtf8("\xE1\x84\x91\xE1\x85\xB1\xE1\x86\xB6") << QString::fromUtf8("\xED\x93\x9B") << 0; + QTest::newRow("normalize7") << QString("en_US") << QString::fromUtf8("\xE1\x84\x91\xE1\x85\xB1\xE1\x86\xB6") << QString::fromUtf8("\xED\x93\x9B") << 0; // examples from UTS 10, Unicode Collation Algorithm - QTest::newRow("normalize8") << QString() << QString::fromUtf8("\xE2\x84\xAB") << QString::fromUtf8("\xC3\x85") << 0; - QTest::newRow("normalize9") << QString() << QString::fromUtf8("\xE2\x84\xAB") << QString::fromUtf8("A\xCC\x8A") << 0; - QTest::newRow("normalize10") << QString() << QString::fromUtf8("x\xCC\x9B\xCC\xA3") << QString::fromUtf8("x\xCC\xA3\xCC\x9B") << 0; - QTest::newRow("normalize11") << QString() << QString::fromUtf8("\xE1\xBB\xB1") << QString::fromUtf8("\xE1\xBB\xA5\xCC\x9B") << 0; - QTest::newRow("normalize12") << QString() << QString::fromUtf8("\xE1\xBB\xB1") << QString::fromUtf8("u\xCC\x9B\xCC\xA3") << 0; - QTest::newRow("normalize13") << QString() << QString::fromUtf8("\xE1\xBB\xB1") << QString::fromUtf8("\xC6\xB0\xCC\xA3") << 0; - QTest::newRow("normalize14") << QString() << QString::fromUtf8("\xE1\xBB\xB1") << QString::fromUtf8("u\xCC\xA3\xCC\x9B") << 0; + QTest::newRow("normalize8") << QString("en_US") << QString::fromUtf8("\xE2\x84\xAB") << QString::fromUtf8("\xC3\x85") << 0; + QTest::newRow("normalize9") << QString("en_US") << QString::fromUtf8("\xE2\x84\xAB") << QString::fromUtf8("A\xCC\x8A") << 0; + QTest::newRow("normalize10") << QString("en_US") << QString::fromUtf8("x\xCC\x9B\xCC\xA3") << QString::fromUtf8("x\xCC\xA3\xCC\x9B") << 0; + QTest::newRow("normalize11") << QString("en_US") << QString::fromUtf8("\xE1\xBB\xB1") << QString::fromUtf8("\xE1\xBB\xA5\xCC\x9B") << 0; + QTest::newRow("normalize12") << QString("en_US") << QString::fromUtf8("\xE1\xBB\xB1") << QString::fromUtf8("u\xCC\x9B\xCC\xA3") << 0; + QTest::newRow("normalize13") << QString("en_US") << QString::fromUtf8("\xE1\xBB\xB1") << QString::fromUtf8("\xC6\xB0\xCC\xA3") << 0; + QTest::newRow("normalize14") << QString("en_US") << QString::fromUtf8("\xE1\xBB\xB1") << QString::fromUtf8("u\xCC\xA3\xCC\x9B") << 0; // examples from UAX 15, Unicode Normalization Forms - QTest::newRow("normalize15") << QString() << QString::fromUtf8("\xC3\x87") << QString::fromUtf8("C\xCC\xA7") << 0; - QTest::newRow("normalize16") << QString() << QString::fromUtf8("q\xCC\x87\xCC\xA3") << QString::fromUtf8("q\xCC\xA3\xCC\x87") << 0; - QTest::newRow("normalize17") << QString() << QString::fromUtf8("\xEA\xB0\x80") << QString::fromUtf8("\xE1\x84\x80\xE1\x85\xA1") << 0; - QTest::newRow("normalize18") << QString() << QString::fromUtf8("\xE2\x84\xAB") << QString::fromUtf8("A\xCC\x8A") << 0; - QTest::newRow("normalize19") << QString() << QString::fromUtf8("\xE2\x84\xA6") << QString::fromUtf8("\xCE\xA9") << 0; - QTest::newRow("normalize20") << QString() << QString::fromUtf8("\xC3\x85") << QString::fromUtf8("A\xCC\x8A") << 0; - QTest::newRow("normalize21") << QString() << QString::fromUtf8("\xC3\xB4") << QString::fromUtf8("o\xCC\x82") << 0; - QTest::newRow("normalize22") << QString() << QString::fromUtf8("\xE1\xB9\xA9") << QString::fromUtf8("s\xCC\xA3\xCC\x87") << 0; - QTest::newRow("normalize23") << QString() << QString::fromUtf8("\xE1\xB8\x8B\xCC\xA3") << QString::fromUtf8("d\xCC\xA3\xCC\x87") << 0; - QTest::newRow("normalize24") << QString() << QString::fromUtf8("\xE1\xB8\x8B\xCC\xA3") << QString::fromUtf8("\xE1\xB8\x8D\xCC\x87") << 0; - QTest::newRow("normalize25") << QString() << QString::fromUtf8("q\xCC\x87\xCC\xA3") << QString::fromUtf8("q\xCC\xA3\xCC\x87") << 0; + QTest::newRow("normalize15") << QString("en_US") << QString::fromUtf8("\xC3\x87") << QString::fromUtf8("C\xCC\xA7") << 0; + QTest::newRow("normalize16") << QString("en_US") << QString::fromUtf8("q\xCC\x87\xCC\xA3") << QString::fromUtf8("q\xCC\xA3\xCC\x87") << 0; + QTest::newRow("normalize17") << QString("en_US") << QString::fromUtf8("\xEA\xB0\x80") << QString::fromUtf8("\xE1\x84\x80\xE1\x85\xA1") << 0; + QTest::newRow("normalize18") << QString("en_US") << QString::fromUtf8("\xE2\x84\xAB") << QString::fromUtf8("A\xCC\x8A") << 0; + QTest::newRow("normalize19") << QString("en_US") << QString::fromUtf8("\xE2\x84\xA6") << QString::fromUtf8("\xCE\xA9") << 0; + QTest::newRow("normalize20") << QString("en_US") << QString::fromUtf8("\xC3\x85") << QString::fromUtf8("A\xCC\x8A") << 0; + QTest::newRow("normalize21") << QString("en_US") << QString::fromUtf8("\xC3\xB4") << QString::fromUtf8("o\xCC\x82") << 0; + QTest::newRow("normalize22") << QString("en_US") << QString::fromUtf8("\xE1\xB9\xA9") << QString::fromUtf8("s\xCC\xA3\xCC\x87") << 0; + QTest::newRow("normalize23") << QString("en_US") << QString::fromUtf8("\xE1\xB8\x8B\xCC\xA3") << QString::fromUtf8("d\xCC\xA3\xCC\x87") << 0; + QTest::newRow("normalize24") << QString("en_US") << QString::fromUtf8("\xE1\xB8\x8B\xCC\xA3") << QString::fromUtf8("\xE1\xB8\x8D\xCC\x87") << 0; + QTest::newRow("normalize25") << QString("en_US") << QString::fromUtf8("q\xCC\x87\xCC\xA3") << QString::fromUtf8("q\xCC\xA3\xCC\x87") << 0; } From b1092a7d4240d419cc2b5f3f5c326a1cb680bbdd Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sat, 19 Jan 2019 18:59:55 +0100 Subject: [PATCH 0867/1650] tst_QPrinter: stabilize qprinter test The CreationDate entry in the two PDF files can potentially be different depending on when the test is run. 97b4c5a5746a33a27076d72ceb3533fbd54b9642 already accounts for it but the current tag for creation date is '/CreationDate'. Therefore check if the line contains 'CreationDate' instead. Change-Id: I1fc069cf935bba07084ac4a0743ff05312374d10 Reviewed-by: Thiago Macieira --- tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp b/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp index a65dd0bf8f..abe4325278 100644 --- a/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp +++ b/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp @@ -644,7 +644,7 @@ void tst_QPrinter::taskQTBUG4497_reusePrinterOnDifferentFiles() QByteArray file1Line = file1.readLine(); QByteArray file2Line = file2.readLine(); - if (!file1Line.startsWith("%%CreationDate")) + if (!file1Line.contains("CreationDate")) QCOMPARE(file1Line, file2Line); } From f43f636f50d3bd6890a2feb513ece3f82c604d49 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Fri, 28 Dec 2018 23:44:02 +0100 Subject: [PATCH 0868/1650] configure: fix a bug where -no-xcb implied eglfs_x11=no Change-Id: I89bbef23a0abd7692b9bda7b356502f5450af6cc Reviewed-by: Kai Koehne Reviewed-by: Laszlo Agocs --- src/gui/configure.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gui/configure.json b/src/gui/configure.json index 39c0232c0b..97883d97ad 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -1436,7 +1436,7 @@ }, "eglfs_x11": { "label": "EGLFS X11", - "condition": "features.eglfs && features.xcb && features.xcb-xlib && features.egl_x11", + "condition": "features.eglfs && features.xcb-xlib && features.egl_x11", "output": [ "privateFeature" ] }, "gif": { @@ -1569,7 +1569,6 @@ }, "xcb-xlib": { "label": "XCB Xlib", - "emitIf": "features.xcb", "condition": "features.xlib && libs.xcb_xlib", "output": [ "privateFeature" ] }, From 30e665f7471859cd88f5d5be4008e7b0632bb5c3 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Thu, 27 Dec 2018 01:10:29 +0100 Subject: [PATCH 0869/1650] eglfs_kms: Fix build with -no-opengl This patch amends 259adc5e77a40bc8f0b7e4c17f7a38bfc4ad511b Change-Id: Ie8d8a8e0817cea455eb1fe14501e8429d29428b8 Reviewed-by: Laszlo Agocs --- .../deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp | 2 ++ .../eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp index 402338197d..1e4f4e72c8 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp @@ -118,6 +118,8 @@ QPlatformCursor *QEglFSKmsGbmIntegration::createCursor(QPlatformScreen *screen) qCDebug(qLcEglfsKmsDebug, "Using plain OpenGL mouse cursor"); return new QEglFSCursor(screen); } +#else + Q_UNUSED(screen); #endif return nullptr; } diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp index a67457a6a5..ab39af6b80 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp @@ -289,7 +289,9 @@ QPlatformCursor *QEglFSKmsEglDeviceIntegration::createCursor(QPlatformScreen *sc { #if QT_CONFIG(opengl) if (screenConfig()->separateScreens()) - return new QEglFSCursor(screen); + return new QEglFSCursor(screen); +#else + Q_UNUSED(screen); #endif return nullptr; } From 119487650e28073f5766cc43cb679eb629a2a0c5 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Tue, 15 Jan 2019 15:32:44 +0100 Subject: [PATCH 0870/1650] Doc: End sentence about Q_GADGET with dot Change-Id: I55380d133017670f212df331fba655e80538e412 Reviewed-by: Leena Miettinen --- src/corelib/kernel/qobject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index b5d97c5538..4680742a3e 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -4446,7 +4446,7 @@ QDebug operator<<(QDebug dbg, const QObject *o) macro, it must appear in the private section of a class definition. Q_GADGETs can have Q_ENUM, Q_PROPERTY and Q_INVOKABLE, but they cannot have - signals or slots + signals or slots. Q_GADGET makes a class member, \c{staticMetaObject}, available. \c{staticMetaObject} is of type QMetaObject and provides access to the From 4f6a4c7992b2794f1ac026800e9a1ce72d6ab2f3 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 20 Dec 2018 14:16:53 +0100 Subject: [PATCH 0871/1650] Fix license header for qprinterinfo.cpp Fixes: QTBUG-72598 Change-Id: I1fb9f384509726276ff32ceb5709e7b0fb98d729 Reviewed-by: Kai Pastor Reviewed-by: Jani Heikkinen --- src/printsupport/kernel/qprinterinfo.cpp | 30 +++++++++++++++++------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/printsupport/kernel/qprinterinfo.cpp b/src/printsupport/kernel/qprinterinfo.cpp index 49a0c9ece4..4b092dee64 100644 --- a/src/printsupport/kernel/qprinterinfo.cpp +++ b/src/printsupport/kernel/qprinterinfo.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the documentation of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:FDL$ +** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,13 +14,25 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** ** $QT_END_LICENSE$ ** ****************************************************************************/ From 524a37f99d3d3115a1b371fd289044d90349a824 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Thu, 20 Dec 2018 17:38:03 +0100 Subject: [PATCH 0872/1650] qfilesystemengine_win: Update LinkType whenever asked Checking the known flags prevented us from correctly setting the LinkType flag if we had previously set LinkType as a known flag since the flag is not reset between updates. Manifested itself in situations where the file info is loaded and then the LegacyLinkType flag is checked through QFileInfoPrivate::checkAttribute. Since the LegacyLinkType is not set for Windows it will update the metadata and exclude the LinkType flag. Change-Id: Iea27f42fe11f36ba2247e52fa9c82b4639666a64 Fixes: QTBUG-72644 Reviewed-by: Thiago Macieira --- src/corelib/io/qfilesystemengine_win.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index a796fd005a..3f4b46573b 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -1038,8 +1038,7 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM if (what & QFileSystemMetaData::Permissions) fillPermissions(fname, data, what); - if ((what & QFileSystemMetaData::LinkType) - && data.missingFlags(QFileSystemMetaData::LinkType)) { + if (what & QFileSystemMetaData::LinkType) { data.knownFlagsMask |= QFileSystemMetaData::LinkType; if (data.fileAttribute_ & FILE_ATTRIBUTE_REPARSE_POINT) { WIN32_FIND_DATA findData; From 9818af7d436f7aa1bf5c635041cc5d08fec599b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 18 Jan 2019 09:31:10 +0200 Subject: [PATCH 0873/1650] qsimd: Fix compilation with trunk clang for mingw Current tip-of-tree clang (after Clang 8 was branched) added an intrinsic function __builtin_ia32_xgetbv, and added the following define that provides _xgetbv: #define _xgetbv(A) __builtin_ia32_xgetbv((long long)(A)) This fallback declaration of the _xgetbv function only is used in case the Q_OS_WIN branch of the #if/#elif below is used, if the #if (defined(Q_CC_GNU) && !defined(Q_CC_EMSCRIPTEN)) || defined(Q_CC_GHS) wasn't taken. I left out the !defined(Q_CC_EMSCRIPTEN) part as I believe Q_OS_WIN and Q_CC_EMSCRIPTEN are mutually exclusive. Change-Id: I257fc4283ff9f0845df51ab764cf58acdf285c66 Reviewed-by: Thiago Macieira --- src/corelib/tools/qsimd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp index 07a8b022bc..1b51b591f7 100644 --- a/src/corelib/tools/qsimd.cpp +++ b/src/corelib/tools/qsimd.cpp @@ -293,7 +293,7 @@ static void cpuidFeatures07_00(uint &ebx, uint &ecx, uint &edx) #endif } -#ifdef Q_OS_WIN +#if defined(Q_OS_WIN) && !(defined(Q_CC_GNU) || defined(Q_CC_GHS)) // fallback overload in case this intrinsic does not exist: unsigned __int64 _xgetbv(unsigned int); inline quint64 _xgetbv(__int64) { return 0; } #endif From 76dfda1ad12cc42cdd832aed1edbe5f76b0cbb2d Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 21 Jan 2019 13:46:11 +0100 Subject: [PATCH 0874/1650] Use RAII to handle setting of default locale in tst_QString Various tests were setting the default locale and relying on cleanup() to "restore" the C locale; which needn't actually be the locale we started out in and, in any case, was the wrong locale for some tests. So handle this via an RAII class that records the actual prior locale and restores it on destruction. Fixes: QTBUG-73116 Change-Id: If44f7cb8c6e0ce81be396ac1ea8bab7038a86729 Reviewed-by: Thiago Macieira --- .../corelib/tools/qstring/tst_qstring.cpp | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index c78cd2276f..e8ed22e427 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -319,10 +319,18 @@ class tst_QString : public QObject template void insert_impl() const { insert_impl(); } void insert_data(bool emptyIsNoop = false); + + class TransientDefaultLocale + { + const QLocale prior; // Records what *was* the default before we set it. + public: + TransientDefaultLocale(const QLocale &transient) { revise(transient); } + void revise(const QLocale &transient) { QLocale::setDefault(transient); } + ~TransientDefaultLocale() { QLocale::setDefault(prior); } + }; + public: tst_QString(); -public slots: - void cleanup(); private slots: void fromStdString(); void toStdString(); @@ -654,11 +662,6 @@ tst_QString::tst_QString() QTextCodec::setCodecForLocale(QTextCodec::codecForName("ISO 8859-1")); } -void tst_QString::cleanup() -{ - QLocale::setDefault(QString("C")); -} - void tst_QString::remove_uint_uint_data() { replace_uint_uint_data(); @@ -4750,7 +4753,7 @@ void tst_QString::arg() is all messed up, because Qt Test itself uses QString::arg(). */ - QLocale::setDefault(QString("de_DE")); + TransientDefaultLocale transient(QString("de_DE")); QString s4( "[%0]" ); QString s5( "[%1]" ); @@ -4898,13 +4901,11 @@ void tst_QString::arg() QCOMPARE(QString("%1").arg(-1., 3, 'g', -1, QChar('x')), QLatin1String("x-1")); QCOMPARE(QString("%1").arg(-100., 3, 'g', -1, QChar('x')), QLatin1String("-100")); - QLocale::setDefault(QString("ar")); + transient.revise(QString("ar")); QCOMPARE( QString("%L1").arg(12345.6789, 10, 'g', 7, QLatin1Char('0')), QString::fromUtf8("\xd9\xa0\xd9\xa1\xd9\xa2\xd9\xac\xd9\xa3\xd9\xa4\xd9\xa5\xd9\xab\xd9\xa6\xd9\xa8") ); // "٠١٢٬٣٤٥٫٦٨" QCOMPARE( QString("%L1").arg(123456789, 13, 10, QLatin1Char('0')), QString("\xd9\xa0\xd9\xa0\xd9\xa1\xd9\xa2\xd9\xa3\xd9\xac\xd9\xa4\xd9\xa5\xd9\xa6\xd9\xac\xd9\xa7\xd9\xa8\xd9\xa9") ); // ٠٠١٢٣٬٤٥٦٬٧٨٩ - - QLocale::setDefault(QLocale::system()); } void tst_QString::number() @@ -6594,14 +6595,14 @@ void tst_QString::arg_locale() QLocale l(QLocale::English, QLocale::UnitedKingdom); QString str("*%L1*%L2*"); - QLocale::setDefault(l); + TransientDefaultLocale transient(l); QCOMPARE(str.arg(123456).arg(1234.56), QString::fromLatin1("*123,456*1,234.56*")); l.setNumberOptions(QLocale::OmitGroupSeparator); - QLocale::setDefault(l); + transient.revise(l); QCOMPARE(str.arg(123456).arg(1234.56), QString::fromLatin1("*123456*1234.56*")); - QLocale::setDefault(QLocale::C); + transient.revise(QLocale::C); QCOMPARE(str.arg(123456).arg(1234.56), QString::fromLatin1("*123456*1234.56*")); } @@ -6615,7 +6616,7 @@ void tst_QString::toUpperLower_icu() QCOMPARE(s.toUpper(), QString::fromLatin1("I")); QCOMPARE(s.toLower(), QString::fromLatin1("i")); - QLocale::setDefault(QLocale(QLocale::Turkish, QLocale::Turkey)); + TransientDefaultLocale transient(QLocale(QLocale::Turkish, QLocale::Turkey)); QCOMPARE(s.toUpper(), QString::fromLatin1("I")); QCOMPARE(s.toLower(), QString::fromLatin1("i")); @@ -6639,8 +6640,6 @@ void tst_QString::toUpperLower_icu() // nothing should happen here QCOMPARE(l.toLower(sup), sup); QCOMPARE(l.toLower(QString::fromLatin1("i")), QString::fromLatin1("i")); - - // the cleanup function will restore the default locale } #endif From 024daeb08c77b75638843f6b3d5a93129ffcb0eb Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sat, 19 Jan 2019 19:54:59 +0100 Subject: [PATCH 0875/1650] tst_QGraphicsItem: stabilize cursor() test The cursor test sometimes fails due to the fact that the topLevel widget has not yet reached it's fullscreen geometry. This means the QGraphicsView is to small and the test will fail. Avoid it by simply removing the topLevel widget since it's not used at all. Change-Id: Ia7b34f283a917a35b6665e6333a01378575a5a04 Reviewed-by: Friedemann Kleint --- .../graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp index 5f269bd520..9a75774927 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp @@ -4148,11 +4148,9 @@ void tst_QGraphicsItem::ensureVisible() void tst_QGraphicsItem::cursor() { QGraphicsScene scene; - QWidget topLevel; - QGraphicsView view(&scene,&topLevel); - topLevel.showMaximized(); - QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); - view.setFixedSize(topLevel.size()); + QGraphicsView view(&scene); + view.showFullScreen(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); QGraphicsRectItem *item1 = scene.addRect(QRectF(-100, 0, 50, 50)); QGraphicsRectItem *item2 = scene.addRect(QRectF(50, 0, 50, 50)); From 730f0df17db53b249b8680a14c40d12107c8e24e Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 22 Jan 2019 12:57:52 +0100 Subject: [PATCH 0876/1650] Windows: Set opengl swap interval whenever we make a new window current Apparently the windows OpenGL implementation associates the swap interval not with the context, but with the window. Fixes: QTBUG-59660 Change-Id: I78c4cc9f8a5815779a7489edfd731a1debb1e590 Reviewed-by: Friedemann Kleint Reviewed-by: Laszlo Agocs Reviewed-by: Simon Hausmann --- src/plugins/platforms/windows/qwindowsglcontext.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp index 851a6c961e..21cb794196 100644 --- a/src/plugins/platforms/windows/qwindowsglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp @@ -1350,10 +1350,10 @@ bool QWindowsGLContext::makeCurrent(QPlatformSurface *surface) // Set the swap interval if (m_staticContext->wglSwapInternalExt) { const int interval = surface->format().swapInterval(); - if (interval >= 0 && m_swapInterval != interval) { + if (m_swapInterval != interval) m_swapInterval = interval; + if (interval >= 0) m_staticContext->wglSwapInternalExt(interval); - } } return success; From 4faf011c3f5f4a739f4ddc54040b5319f7fe5d90 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 10 Jan 2019 17:38:55 +0100 Subject: [PATCH 0877/1650] Document that you shouldn't Q_ENUM() things outside the int range The meta object system stores enums as signed int, probably for performance reasons. This is good enough for about 99% of the use cases. If you try to register larger types and then access them through the metaobject system, you can get undefined behavior. Task-number: QTBUG-71947 Change-Id: I16b395547c22fad10b476c2c2a0768538db0a20e Reviewed-by: Thiago Macieira --- src/corelib/kernel/qobject.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 4680742a3e..42c39f18e3 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -4338,6 +4338,12 @@ QDebug operator<<(QDebug dbg, const QObject *o) in a QVariant, you can convert them to strings. Likewise, passing them to QDebug will print out their names. + Mind that the enum values are stored as signed \c int in the meta object system. + Registering enumerations with values outside the range of values valid for \c int + will lead to overflows and potentially undefined behavior when accessing them through + the meta object system. QML, for example, does access registered enumerations through + the meta object system. + \sa {Qt's Property System} */ @@ -4389,6 +4395,12 @@ QDebug operator<<(QDebug dbg, const QObject *o) used in a QVariant, you can convert them to strings. Likewise, passing them to QDebug will print out their names. + Mind that the enum values are stored as signed \c int in the meta object system. + Registering enumerations with values outside the range of values valid for \c int + will lead to overflows and potentially undefined behavior when accessing them through + the meta object system. QML, for example, does access registered enumerations through + the meta object system. + \sa {Qt's Property System} */ From 230921a7f00d368551ecf5d6457765eae03e9325 Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Mon, 21 Jan 2019 13:18:15 +0100 Subject: [PATCH 0878/1650] fix crash if no screens are available MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: QTBUG-73166 Change-Id: I936672b7a09a540d21e6dcd371f5ffe1e5536b85 Reviewed-by: Tor Arne Vestbø --- src/gui/kernel/qhighdpiscaling.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp index a455aa639d..22e46e0851 100644 --- a/src/gui/kernel/qhighdpiscaling.cpp +++ b/src/gui/kernel/qhighdpiscaling.cpp @@ -313,9 +313,12 @@ void QHighDpiScaling::updateHighDpiScaling() } m_active = m_globalScalingActive || m_screenFactorSet || m_pixelDensityScalingActive; - QPlatformScreen *primaryScreen = QGuiApplication::primaryScreen()->handle(); - qreal sf = screenSubfactor(primaryScreen); - QDpi primaryDpi = primaryScreen->logicalDpi(); + QScreen *primaryScreen = QGuiApplication::primaryScreen(); + if (!primaryScreen) + return; + QPlatformScreen *platformScreen = primaryScreen->handle(); + qreal sf = screenSubfactor(platformScreen); + QDpi primaryDpi = platformScreen->logicalDpi(); m_logicalDpi = QDpi(primaryDpi.first / sf, primaryDpi.second / sf); } From 9f8589befe99f3c4eecf27d9972abfbbc2fead9c Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 18 Jan 2019 20:52:36 +0100 Subject: [PATCH 0879/1650] tst_QString: fix localeAwareCompare() when using ICU tst_QString::localeAwareCompare() is failing since ab448f731ecd8437c7c5c8b96a0e7f419ec3a7ca because the 'C' locale no longer initializes ICU and falls back to simple QString comparison. Fix it by explicitly setting the locale for the testdata to en_US so the QCollator is properly initialized. Task-number: QTBUG-73116 Change-Id: I9d4d55e666c5c52f93298dedb7e22da01a25318d Reviewed-by: Thiago Macieira (cherry picked from commit 9d2923c1b048b519c352c40bf26328dacef9304e) Reviewed-by: Christian Ehrlicher Reviewed-by: Jani Heikkinen --- .../corelib/tools/qstring/tst_qstring.cpp | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index f429bda804..c78cd2276f 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -5521,35 +5521,35 @@ void tst_QString::localeAwareCompare_data() // console.log("\u1111\u1171\u11B6".localeCompare("\ud4db") // example from Unicode 5.0, section 3.7, definition D70 - QTest::newRow("normalize1") << QString() << QString::fromUtf8("o\xCC\x88") << QString::fromUtf8("\xC3\xB6") << 0; + QTest::newRow("normalize1") << QString("en_US") << QString::fromUtf8("o\xCC\x88") << QString::fromUtf8("\xC3\xB6") << 0; // examples from Unicode 5.0, chapter 3.11 - QTest::newRow("normalize2") << QString() << QString::fromUtf8("\xC3\xA4\xCC\xA3") << QString::fromUtf8("a\xCC\xA3\xCC\x88") << 0; - QTest::newRow("normalize3") << QString() << QString::fromUtf8("a\xCC\x88\xCC\xA3") << QString::fromUtf8("a\xCC\xA3\xCC\x88") << 0; - QTest::newRow("normalize4") << QString() << QString::fromUtf8("\xE1\xBA\xA1\xCC\x88") << QString::fromUtf8("a\xCC\xA3\xCC\x88") << 0; - QTest::newRow("normalize5") << QString() << QString::fromUtf8("\xC3\xA4\xCC\x86") << QString::fromUtf8("a\xCC\x88\xCC\x86") << 0; - QTest::newRow("normalize6") << QString() << QString::fromUtf8("\xC4\x83\xCC\x88") << QString::fromUtf8("a\xCC\x86\xCC\x88") << 0; + QTest::newRow("normalize2") << QString("en_US") << QString::fromUtf8("\xC3\xA4\xCC\xA3") << QString::fromUtf8("a\xCC\xA3\xCC\x88") << 0; + QTest::newRow("normalize3") << QString("en_US") << QString::fromUtf8("a\xCC\x88\xCC\xA3") << QString::fromUtf8("a\xCC\xA3\xCC\x88") << 0; + QTest::newRow("normalize4") << QString("en_US") << QString::fromUtf8("\xE1\xBA\xA1\xCC\x88") << QString::fromUtf8("a\xCC\xA3\xCC\x88") << 0; + QTest::newRow("normalize5") << QString("en_US") << QString::fromUtf8("\xC3\xA4\xCC\x86") << QString::fromUtf8("a\xCC\x88\xCC\x86") << 0; + QTest::newRow("normalize6") << QString("en_US") << QString::fromUtf8("\xC4\x83\xCC\x88") << QString::fromUtf8("a\xCC\x86\xCC\x88") << 0; // example from Unicode 5.0, chapter 3.12 - QTest::newRow("normalize7") << QString() << QString::fromUtf8("\xE1\x84\x91\xE1\x85\xB1\xE1\x86\xB6") << QString::fromUtf8("\xED\x93\x9B") << 0; + QTest::newRow("normalize7") << QString("en_US") << QString::fromUtf8("\xE1\x84\x91\xE1\x85\xB1\xE1\x86\xB6") << QString::fromUtf8("\xED\x93\x9B") << 0; // examples from UTS 10, Unicode Collation Algorithm - QTest::newRow("normalize8") << QString() << QString::fromUtf8("\xE2\x84\xAB") << QString::fromUtf8("\xC3\x85") << 0; - QTest::newRow("normalize9") << QString() << QString::fromUtf8("\xE2\x84\xAB") << QString::fromUtf8("A\xCC\x8A") << 0; - QTest::newRow("normalize10") << QString() << QString::fromUtf8("x\xCC\x9B\xCC\xA3") << QString::fromUtf8("x\xCC\xA3\xCC\x9B") << 0; - QTest::newRow("normalize11") << QString() << QString::fromUtf8("\xE1\xBB\xB1") << QString::fromUtf8("\xE1\xBB\xA5\xCC\x9B") << 0; - QTest::newRow("normalize12") << QString() << QString::fromUtf8("\xE1\xBB\xB1") << QString::fromUtf8("u\xCC\x9B\xCC\xA3") << 0; - QTest::newRow("normalize13") << QString() << QString::fromUtf8("\xE1\xBB\xB1") << QString::fromUtf8("\xC6\xB0\xCC\xA3") << 0; - QTest::newRow("normalize14") << QString() << QString::fromUtf8("\xE1\xBB\xB1") << QString::fromUtf8("u\xCC\xA3\xCC\x9B") << 0; + QTest::newRow("normalize8") << QString("en_US") << QString::fromUtf8("\xE2\x84\xAB") << QString::fromUtf8("\xC3\x85") << 0; + QTest::newRow("normalize9") << QString("en_US") << QString::fromUtf8("\xE2\x84\xAB") << QString::fromUtf8("A\xCC\x8A") << 0; + QTest::newRow("normalize10") << QString("en_US") << QString::fromUtf8("x\xCC\x9B\xCC\xA3") << QString::fromUtf8("x\xCC\xA3\xCC\x9B") << 0; + QTest::newRow("normalize11") << QString("en_US") << QString::fromUtf8("\xE1\xBB\xB1") << QString::fromUtf8("\xE1\xBB\xA5\xCC\x9B") << 0; + QTest::newRow("normalize12") << QString("en_US") << QString::fromUtf8("\xE1\xBB\xB1") << QString::fromUtf8("u\xCC\x9B\xCC\xA3") << 0; + QTest::newRow("normalize13") << QString("en_US") << QString::fromUtf8("\xE1\xBB\xB1") << QString::fromUtf8("\xC6\xB0\xCC\xA3") << 0; + QTest::newRow("normalize14") << QString("en_US") << QString::fromUtf8("\xE1\xBB\xB1") << QString::fromUtf8("u\xCC\xA3\xCC\x9B") << 0; // examples from UAX 15, Unicode Normalization Forms - QTest::newRow("normalize15") << QString() << QString::fromUtf8("\xC3\x87") << QString::fromUtf8("C\xCC\xA7") << 0; - QTest::newRow("normalize16") << QString() << QString::fromUtf8("q\xCC\x87\xCC\xA3") << QString::fromUtf8("q\xCC\xA3\xCC\x87") << 0; - QTest::newRow("normalize17") << QString() << QString::fromUtf8("\xEA\xB0\x80") << QString::fromUtf8("\xE1\x84\x80\xE1\x85\xA1") << 0; - QTest::newRow("normalize18") << QString() << QString::fromUtf8("\xE2\x84\xAB") << QString::fromUtf8("A\xCC\x8A") << 0; - QTest::newRow("normalize19") << QString() << QString::fromUtf8("\xE2\x84\xA6") << QString::fromUtf8("\xCE\xA9") << 0; - QTest::newRow("normalize20") << QString() << QString::fromUtf8("\xC3\x85") << QString::fromUtf8("A\xCC\x8A") << 0; - QTest::newRow("normalize21") << QString() << QString::fromUtf8("\xC3\xB4") << QString::fromUtf8("o\xCC\x82") << 0; - QTest::newRow("normalize22") << QString() << QString::fromUtf8("\xE1\xB9\xA9") << QString::fromUtf8("s\xCC\xA3\xCC\x87") << 0; - QTest::newRow("normalize23") << QString() << QString::fromUtf8("\xE1\xB8\x8B\xCC\xA3") << QString::fromUtf8("d\xCC\xA3\xCC\x87") << 0; - QTest::newRow("normalize24") << QString() << QString::fromUtf8("\xE1\xB8\x8B\xCC\xA3") << QString::fromUtf8("\xE1\xB8\x8D\xCC\x87") << 0; - QTest::newRow("normalize25") << QString() << QString::fromUtf8("q\xCC\x87\xCC\xA3") << QString::fromUtf8("q\xCC\xA3\xCC\x87") << 0; + QTest::newRow("normalize15") << QString("en_US") << QString::fromUtf8("\xC3\x87") << QString::fromUtf8("C\xCC\xA7") << 0; + QTest::newRow("normalize16") << QString("en_US") << QString::fromUtf8("q\xCC\x87\xCC\xA3") << QString::fromUtf8("q\xCC\xA3\xCC\x87") << 0; + QTest::newRow("normalize17") << QString("en_US") << QString::fromUtf8("\xEA\xB0\x80") << QString::fromUtf8("\xE1\x84\x80\xE1\x85\xA1") << 0; + QTest::newRow("normalize18") << QString("en_US") << QString::fromUtf8("\xE2\x84\xAB") << QString::fromUtf8("A\xCC\x8A") << 0; + QTest::newRow("normalize19") << QString("en_US") << QString::fromUtf8("\xE2\x84\xA6") << QString::fromUtf8("\xCE\xA9") << 0; + QTest::newRow("normalize20") << QString("en_US") << QString::fromUtf8("\xC3\x85") << QString::fromUtf8("A\xCC\x8A") << 0; + QTest::newRow("normalize21") << QString("en_US") << QString::fromUtf8("\xC3\xB4") << QString::fromUtf8("o\xCC\x82") << 0; + QTest::newRow("normalize22") << QString("en_US") << QString::fromUtf8("\xE1\xB9\xA9") << QString::fromUtf8("s\xCC\xA3\xCC\x87") << 0; + QTest::newRow("normalize23") << QString("en_US") << QString::fromUtf8("\xE1\xB8\x8B\xCC\xA3") << QString::fromUtf8("d\xCC\xA3\xCC\x87") << 0; + QTest::newRow("normalize24") << QString("en_US") << QString::fromUtf8("\xE1\xB8\x8B\xCC\xA3") << QString::fromUtf8("\xE1\xB8\x8D\xCC\x87") << 0; + QTest::newRow("normalize25") << QString("en_US") << QString::fromUtf8("q\xCC\x87\xCC\xA3") << QString::fromUtf8("q\xCC\xA3\xCC\x87") << 0; } From 7d1af8fa957c86fdbb4b0ab86dc2adc726c66bd9 Mon Sep 17 00:00:00 2001 From: Antti Kokko Date: Wed, 9 Jan 2019 10:09:42 +0200 Subject: [PATCH 0880/1650] Add changes file for Qt 5.12.1 Change-Id: Ib791ad498a92cd0dfe7312f4867d36789694e1fb Reviewed-by: Gatis Paeglis Reviewed-by: Shawn Rutledge --- dist/changes-5.12.1 | 167 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 dist/changes-5.12.1 diff --git a/dist/changes-5.12.1 b/dist/changes-5.12.1 new file mode 100644 index 0000000000..7f1bf9dded --- /dev/null +++ b/dist/changes-5.12.1 @@ -0,0 +1,167 @@ +Qt 5.12.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.12.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.12 series is binary compatible with the 5.11.x series. +Applications compiled for 5.11 will continue to run with 5.12. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Important Behavior Changes * +**************************************************************************** + + - qmake / WinRT: + * Cross-builds will now ignore pre-set values of %INCLUDE% and %LIB% + when building target executables. If necessary, use configure's -I and + -L switches when building Qt, and pass QMAKE_INCDIR and QMAKE_LIBDIR + on qmake's command line when building own projects. + +**************************************************************************** +* Documentation * +**************************************************************************** + + - Fixed the icons for the "file save" action that were inaccurate + representations of a 3.5-inch floppy disk (the cut edge was on the wrong + side). Now all floppy representations are physically accurate. + +**************************************************************************** +* QtCore * +**************************************************************************** + + - [QTBUG-71256] QString, QByteArray and QLocale's toDouble return an infinity + on overflow (since 5.7), while setting ok to false; this was at odds with + their documented behavior of returning 0 on failure. The documentation now + reflects the actual behavior. + - [QTBUG-71868] QString, QByteArray and QLocale's toFloat returned an + infinity on double-overflow (since 5.7) but returned 0 on a finite double + outside float's range, while setting ok to false; this was at odds with + their documented behavior of returning 0 on any failure. They also + succeeded, returning zero, on underflow of float's range, unless double + underflowed, where they failed. Changed the handling of values outside + float's range to match that of values outside double's range: fail, + returning an infinity on overflow or zero on underflow. The documentation + now reflects the revised behavior, which matches toDouble(). + + - QCborStreamReader: + * [QTBUG-71426] Made setDevice() clear the last error. + + - QCollator: + * [QTBUG-58621] Added support for collation in the C locale, albeit this is + only well-defined for ASCII. Collation sort keys remain unsupported on + Darwin. + + - QContiguousCache: + * [QTBUG-52125] Fixed a memory leak. + + - QObject: + * [QTBUG-32340] Fixed a bug that caused isSignalConnected() to return + true if the signal was connected and later disconnected. + * [QTBUG-71550] Fixed a bug that caused isSignalConnected() not to + report signals that were connected by the QML engine. + + - QPluginLoader: + * [QTBUG-71443] Fixed the parsing of ELF headers (Linux, FreeBSD, Solaris, + etc.), which could cause certain valid plugins to not be deteced as + valid. + + - QRegularExpression: + * [QTBUG-72539] The wildcardToRegularExpression method now returns a + properly anchored pattern. + + - QSettings: + * [QTBUG-72007] Fixed QSettings parsing of blank spaces after comment lines + in INI-style configuration files. + + - QStringListModel: + * setData will now emit the dataChanged() signal only if the string set + is different from the one already contained in the model + + - QSysInfo: + * [QTBUG-72489] Now returns "Mojave" in prettyProductName() for macOS + 10.14. + + - QUrl: + * [QTBUG-71973] Changed the normalization done by + QUrl::NormalizePathSegments) to match what web browsers do for non-local + URLs. + +**************************************************************************** +* QtGui * +**************************************************************************** + + - Text: + * Fixed a bug where eliding text could change the height of its bounding + rectangle for certain fonts. + * Improved appearance of monochrome text on some platforms. + * Fixed so ShowTabsAndSpaces will use the correct font. + +**************************************************************************** +* QtSql * +**************************************************************************** + + - PostgreSQL: + * Added support for PostgreSQL 11 + +**************************************************************************** +* QtWidgets * +**************************************************************************** + + - Reverted a Qt 5.12.0 behavior change in QToolTip that made plain tooltip + text be wrapped automatically. + - [QTBUG-72844] Fixed a regression related to accepting a Drag'n'Drop event. + - [QTBUG-27110] Reverted a change that caused a regression related to + styling a QListView using CSS. + + - QWidgetLineControl/security: + * Zero-out the string that contains a password entered into the + QLineEdit + * Preallocate a buffer for the string that contains the entered value + when the QLineEdit serves as a password input field to minimize + reallocations. + +**************************************************************************** +* Platform Specific Changes * +**************************************************************************** + + - Android: + * QClipboard now supports HTML and URI data. + + - Windows: + * Reduced the number of font engines that are created when loading new + fonts, fixing crashes in some special cases where a large number of + fonts are created during a short period of time. + + - X11: + * [QTBUG-71296] Fixed a bug with open/close hand cursors not being shown + correctly. + * [QTBUG-46626][QTBUG-70756] Fixed a bug with dialogs hidden by other + windows in certain use cases. + +**************************************************************************** +* Third-Party Code * +**************************************************************************** + + - [QTBUG-65503] Removed xkbcommon from bundled sources. This library is + present on all supported platforms. The minimal required version now is + 0.5.0. + - Updated bundled SQLite to version 3.26.0. + +**************************************************************************** +* Tools * +**************************************************************************** + + - moc now parses enum struct the same way as enum class therefore that + keyword can be used with the Q_ENUM macro as well as Q_FLAG and + Q_DECLARE_FLAGS. + From 76ee79b8b9c412a77bb51f127ab102f2451a7bbb Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Thu, 17 Jan 2019 13:32:40 +0100 Subject: [PATCH 0881/1650] qtbearer networkmanager: fix whitespace Change-Id: I7802e33e21fa882468b4c8e68677d4881b95d15c Reviewed-by: Lars Knoll --- src/plugins/bearer/networkmanager/qnetworkmanagerservice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h index 65e618d15f..c879083faf 100644 --- a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h +++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h @@ -243,7 +243,7 @@ public: // bool setConnections(); Q_SIGNALS: - void propertiesChanged(QMap ); + void propertiesChanged(QMap); void propertiesReady(); private Q_SLOTS: From 77b969cb844297ce920ad502121112f7e9f8cac8 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Fri, 11 Jan 2019 13:33:35 +0100 Subject: [PATCH 0882/1650] OCSP - simplify feature test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make it more like feature 'dtls' test. Change-Id: I29f5e9337d99440015431a8cfb001f5fb28e1c5f Reviewed-by: Mårten Nordheim Reviewed-by: Edward Welbourne --- src/network/configure.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/network/configure.json b/src/network/configure.json index 9cd731eaea..c3b2f4e581 100644 --- a/src/network/configure.json +++ b/src/network/configure.json @@ -195,10 +195,6 @@ "#if defined(OPENSSL_NO_OCSP) || defined(OPENSSL_NO_TLSEXT)", "# error OpenSSL without OCSP stapling", "#endif" - ], - "main": [ - "(void)SSL_get_tlsext_status_ocsp_resp(nullptr, nullptr);", - "(void)d2i_OCSP_RESPONSE(nullptr, nullptr, 0);" ] }, "use": "openssl" From 503ff495aac77e957f711f19275ab1754228cfeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Thu, 10 Jan 2019 14:17:29 +0100 Subject: [PATCH 0883/1650] Update manual qsslsocket test to use HTTP/2 instead of spdy Some of the spdy/3 tests don't pass anymore because those services no longer support spdy/3. Solve this by updating it to HTTP/2 (h2). Change-Id: Ib3ef6109b75f4298fed15c1c7922deca35459df9 Reviewed-by: Timur Pocheptsov Reviewed-by: Edward Welbourne --- tests/manual/qsslsocket/main.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/manual/qsslsocket/main.cpp b/tests/manual/qsslsocket/main.cpp index b2cc1b5f23..58da520c07 100644 --- a/tests/manual/qsslsocket/main.cpp +++ b/tests/manual/qsslsocket/main.cpp @@ -91,21 +91,21 @@ void tst_QSslSocket::nextProtocolNegotiation_data() << QSslConfiguration::NextProtocolNegotiationNegotiated; tag = host.toLocal8Bit(); - tag.append("-spdy/3"); + tag.append("-h2"); QTest::newRow(tag) << true << host - << (QList() << QSslConfiguration::NextProtocolSpdy3_0) - << QByteArray(QSslConfiguration::NextProtocolSpdy3_0) + << (QList() << QSslConfiguration::ALPNProtocolHTTP2) + << QByteArray(QSslConfiguration::ALPNProtocolHTTP2) << QSslConfiguration::NextProtocolNegotiationNegotiated; tag = host.toLocal8Bit(); - tag.append("-spdy/3-and-http/1.1"); + tag.append("-h2-and-http/1.1"); QTest::newRow(tag) << true << host - << (QList() << QSslConfiguration::NextProtocolSpdy3_0 << QSslConfiguration::NextProtocolHttp1_1) - << QByteArray(QSslConfiguration::NextProtocolSpdy3_0) + << (QList() << QSslConfiguration::ALPNProtocolHTTP2 << QSslConfiguration::NextProtocolHttp1_1) + << QByteArray(QSslConfiguration::ALPNProtocolHTTP2) << QSslConfiguration::NextProtocolNegotiationNegotiated; } } From 8c0a7a46c691f7acad169f5949d3b3d76a227614 Mon Sep 17 00:00:00 2001 From: Samuli Piippo Date: Wed, 9 Jan 2019 13:01:01 +0000 Subject: [PATCH 0884/1650] egl_viv: cast EGLNative return types from vivante functions All vivante functions return void* even when the actual native type (EGLNativeDisplayType, EGLNativeWindowType, etc.) might be typedef'ed as something else, as they do when the CFLAGS from egl.pc are now used. Task-number: QTBUG-73038 Change-Id: I7650b691663201d03d8c15ead155aa3c231fba29 Reviewed-by: Laszlo Agocs --- .../deviceintegration/eglfs_viv/qeglfsvivintegration.cpp | 4 ++-- .../deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.cpp index 763a4a462b..2fc076ad0c 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.cpp @@ -65,7 +65,7 @@ void QEglFSVivIntegration::platformInit() VivanteInit(); mNativeDisplay = fbGetDisplay(); #else - mNativeDisplay = fbGetDisplayByIndex(framebufferIndex()); + mNativeDisplay = static_cast(fbGetDisplayByIndex(framebufferIndex())); #endif fbGetDisplayGeometry(mNativeDisplay, &width, &height); @@ -88,7 +88,7 @@ EGLNativeWindowType QEglFSVivIntegration::createNativeWindow(QPlatformWindow *wi Q_UNUSED(window) Q_UNUSED(format) - EGLNativeWindowType eglWindow = fbCreateWindow(mNativeDisplay, 0, 0, size.width(), size.height()); + EGLNativeWindowType eglWindow = static_cast(fbCreateWindow(mNativeDisplay, 0, 0, size.width(), size.height())); return eglWindow; } diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.cpp index 61e2f17766..3bdae239cd 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.cpp @@ -60,7 +60,7 @@ void QEglFSVivWaylandIntegration::platformInit() } mWaylandDisplay = wl_display_create(); - mNativeDisplay = fbGetDisplay(mWaylandDisplay); + mNativeDisplay = static_cast(fbGetDisplay(mWaylandDisplay)); fbGetDisplayGeometry(mNativeDisplay, &width, &height); mScreenSize.setHeight(height); mScreenSize.setWidth(width); @@ -81,7 +81,7 @@ EGLNativeWindowType QEglFSVivWaylandIntegration::createNativeWindow(QPlatformWin Q_UNUSED(window) Q_UNUSED(format) - EGLNativeWindowType eglWindow = fbCreateWindow(mNativeDisplay, 0, 0, size.width(), size.height()); + EGLNativeWindowType eglWindow = static_cast(fbCreateWindow(mNativeDisplay, 0, 0, size.width(), size.height())); return eglWindow; } From 9822d57d858068cfe5a07281ef069ef8c4c7b7b3 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 21 Jan 2019 09:56:26 +0100 Subject: [PATCH 0885/1650] Stabilize tst_QItemDelegate::dateTimeEditor() Add qWaitForWindowExposed() for the toplevel and use QTRY_VERIFY() for finding the delegates consistently. Change-Id: I430088a91b5cc1a8f856d0a58aba066b1baf179b Reviewed-by: Frederik Gladhorn --- .../qitemdelegate/tst_qitemdelegate.cpp | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp index a8f6906056..5a789a1aa2 100644 --- a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp +++ b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp @@ -727,6 +727,16 @@ void tst_QItemDelegate::dateTimeEditor_data() << QDate(2006, 10, 31); } +static QDateTimeEdit *findDateTimeEdit(const QWidget *widget) +{ + const auto dateTimeEditors = widget->findChildren(); + for (auto dateTimeEditor : dateTimeEditors) { + if (qstrcmp(dateTimeEditor->metaObject()->className(), "QDateTimeEdit") == 0) + return dateTimeEditor; + } + return nullptr; +} + void tst_QItemDelegate::dateTimeEditor() { QFETCH(QTime, time); @@ -742,17 +752,24 @@ void tst_QItemDelegate::dateTimeEditor() item3->setData(Qt::DisplayRole, QDateTime(date, time)); QTableWidget widget(1, 3); + widget.setWindowTitle(QLatin1String(QTest::currentTestFunction()) + + QLatin1String("::") + + QLatin1String(QTest::currentDataTag())); widget.setItem(0, 0, item1); widget.setItem(0, 1, item2); widget.setItem(0, 2, item3); widget.show(); + QVERIFY(QTest::qWaitForWindowExposed(&widget)); + QApplication::setActiveWindow(&widget); widget.editItem(item1); QTestEventLoop::instance().enterLoop(1); - QTimeEdit *timeEditor = widget.viewport()->findChild(); - QVERIFY(timeEditor); + + QTimeEdit *timeEditor = nullptr; + auto viewport = widget.viewport(); + QTRY_VERIFY( (timeEditor = viewport->findChild()) ); QCOMPARE(timeEditor->time(), time); // The data must actually be different in order for the model // to be updated. @@ -763,8 +780,8 @@ void tst_QItemDelegate::dateTimeEditor() widget.setFocus(); widget.editItem(item2); - QTRY_VERIFY(widget.viewport()->findChild()); - QDateEdit *dateEditor = widget.viewport()->findChild(); + QDateEdit *dateEditor = nullptr; + QTRY_VERIFY( (dateEditor = viewport->findChild()) ); QCOMPARE(dateEditor->date(), date); dateEditor->setDate(date.addDays(60)); @@ -774,12 +791,8 @@ void tst_QItemDelegate::dateTimeEditor() QTestEventLoop::instance().enterLoop(1); - QList dateTimeEditors = widget.findChildren(); - QDateTimeEdit *dateTimeEditor = 0; - foreach(dateTimeEditor, dateTimeEditors) - if (dateTimeEditor->metaObject()->className() == QLatin1String("QDateTimeEdit")) - break; - QVERIFY(dateTimeEditor); + QDateTimeEdit *dateTimeEditor = nullptr; + QTRY_VERIFY( (dateTimeEditor = findDateTimeEdit(viewport)) ); QCOMPARE(dateTimeEditor->date(), date); QCOMPARE(dateTimeEditor->time(), time); dateTimeEditor->setTime(time.addSecs(600)); From e0567d137df4ff3978f767fa723ae05a7b0ab546 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Fri, 27 Jul 2018 17:46:04 +0200 Subject: [PATCH 0886/1650] Add QStringList::indexOf/lastIndexOf for QStringView and QLatin1String Change-Id: I42eac69c1f7ab88441d464b9d325139defe32b03 Reviewed-by: Thiago Macieira --- src/corelib/tools/qlist.h | 53 +++++++++++---- src/corelib/tools/qstringlist.cpp | 50 +++++++++++++++ src/corelib/tools/qstringlist.h | 26 ++++++++ .../tools/qstringlist/tst_qstringlist.cpp | 64 ++++++++++++++----- 4 files changed, 165 insertions(+), 28 deletions(-) diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index fe8a1407e2..6643288bd5 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -118,6 +118,11 @@ struct Q_CORE_EXPORT QListData { inline void **end() const Q_DECL_NOTHROW { return d->array + d->end; } }; +namespace QtPrivate { + template int indexOf(const QList &list, const U &u, int from); + template int lastIndexOf(const QList &list, const U &u, int from); +} + template class QList #ifndef Q_QDOC @@ -136,6 +141,8 @@ public: QListData::InlineWithPaddingLayout >::type>::type {}; private: + template friend int QtPrivate::indexOf(const QList &list, const U &u, int from); + template friend int QtPrivate::lastIndexOf(const QList &list, const U &u, int from); struct Node { void *v; #if defined(Q_CC_BOR) Q_INLINE_TEMPLATE T &t(); @@ -975,35 +982,57 @@ inline void QList::append(const QList &t) template Q_OUTOFLINE_TEMPLATE int QList::indexOf(const T &t, int from) const { + return QtPrivate::indexOf(*this, t, from); +} + +namespace QtPrivate +{ +template +int indexOf(const QList &list, const U &u, int from) +{ + typedef typename QList::Node Node; + if (from < 0) - from = qMax(from + p.size(), 0); - if (from < p.size()) { - Node *n = reinterpret_cast(p.at(from -1)); - Node *e = reinterpret_cast(p.end()); + from = qMax(from + list.p.size(), 0); + if (from < list.p.size()) { + Node *n = reinterpret_cast(list.p.at(from -1)); + Node *e = reinterpret_cast(list.p.end()); while (++n != e) - if (n->t() == t) - return int(n - reinterpret_cast(p.begin())); + if (n->t() == u) + return int(n - reinterpret_cast(list.p.begin())); } return -1; } +} template Q_OUTOFLINE_TEMPLATE int QList::lastIndexOf(const T &t, int from) const { + return QtPrivate::lastIndexOf(*this, t, from); +} + +namespace QtPrivate +{ +template +int lastIndexOf(const QList &list, const U &u, int from) +{ + typedef typename QList::Node Node; + if (from < 0) - from += p.size(); - else if (from >= p.size()) - from = p.size()-1; + from += list.p.size(); + else if (from >= list.p.size()) + from = list.p.size()-1; if (from >= 0) { - Node *b = reinterpret_cast(p.begin()); - Node *n = reinterpret_cast(p.at(from + 1)); + Node *b = reinterpret_cast(list.p.begin()); + Node *n = reinterpret_cast(list.p.at(from + 1)); while (n-- != b) { - if (n->t() == t) + if (n->t() == u) return n - b; } } return -1; } +} template Q_OUTOFLINE_TEMPLATE bool QList::contains(const T &t) const diff --git a/src/corelib/tools/qstringlist.cpp b/src/corelib/tools/qstringlist.cpp index ec6de08805..cc6eaf8ad2 100644 --- a/src/corelib/tools/qstringlist.cpp +++ b/src/corelib/tools/qstringlist.cpp @@ -376,6 +376,56 @@ bool QtPrivate::QStringList_contains(const QStringList *that, QLatin1String str, return stringList_contains(*that, str, cs); } +/*! + \fn bool QStringList::indexOf(QStringView str, int from) const + \overload + \since 5.13 + + Returns the index position of the first occurrence of \a str in + the list, searching forward from index position \a from. Returns + -1 if no item matched. + + \sa lastIndexOf(), contains() + */ + +/*! + \fn bool QStringList::indexOf(QLatin1String str, int from) const + \overload + \since 5.13 + + Returns the index position of the first occurrence of \a str in + the list, searching forward from index position \a from. Returns + -1 if no item matched. + + \sa lastIndexOf(), contains() + */ + +/*! + \fn bool QStringList::lastIndexOf(QStringView str, int from) const + \overload + \since 5.13 + + Returns the index position of the last occurrence of \a str in + the list, searching backward from index position \a from. If \a + from is -1 (the default), the search starts at the last item. + Returns -1 if no item matched. + + \sa indexOf(), contains() + */ + +/*! + \fn bool QStringList::lastIndexOf(QLatin1String str, int from) const + \overload + \since 5.13 + + Returns the index position of the last occurrence of \a str in + the list, searching backward from index position \a from. If \a + from is -1 (the default), the search starts at the last item. + Returns -1 if no item matched. + + \sa indexOf(), contains() + */ + #ifndef QT_NO_REGEXP /*! \fn QStringList QStringList::filter(const QRegExp &rx) const diff --git a/src/corelib/tools/qstringlist.h b/src/corelib/tools/qstringlist.h index 10cbad04d6..b6c48488df 100644 --- a/src/corelib/tools/qstringlist.h +++ b/src/corelib/tools/qstringlist.h @@ -132,6 +132,12 @@ public: inline QStringList &operator<<(const QList &l) { *this += l; return *this; } + inline int indexOf(QStringView str, int from = 0) const; + inline int indexOf(QLatin1String str, int from = 0) const; + + inline int lastIndexOf(QStringView str, int from = -1) const; + inline int lastIndexOf(QLatin1String str, int from = -1) const; + #ifndef QT_NO_REGEXP inline int indexOf(const QRegExp &rx, int from = 0) const; inline int lastIndexOf(const QRegExp &rx, int from = -1) const; @@ -249,6 +255,26 @@ inline QStringList operator+(const QList &one, const QStringList &other return n; } +inline int QStringList::indexOf(QStringView string, int from) const +{ + return QtPrivate::indexOf(*this, string, from); +} + +inline int QStringList::indexOf(QLatin1String string, int from) const +{ + return QtPrivate::indexOf(*this, string, from); +} + +inline int QStringList::lastIndexOf(QStringView string, int from) const +{ + return QtPrivate::lastIndexOf(*this, string, from); +} + +inline int QStringList::lastIndexOf(QLatin1String string, int from) const +{ + return QtPrivate::lastIndexOf(*this, string, from); +} + #ifndef QT_NO_REGEXP inline QStringList &QListSpecialMethods::replaceInStrings(const QRegExp &rx, const QString &after) { diff --git a/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp b/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp index a3aec4c299..42bdf62a93 100644 --- a/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp +++ b/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp @@ -43,7 +43,9 @@ private slots: void removeDuplicates(); void removeDuplicates_data(); void contains(); + void indexOf_data(); void indexOf(); + void lastIndexOf_data(); void lastIndexOf(); void indexOf_regExp(); @@ -141,20 +143,52 @@ void tst_QStringList::lastIndexOf_regExp() } +void tst_QStringList::indexOf_data() +{ + QTest::addColumn("search"); + QTest::addColumn("from"); + QTest::addColumn("expectedResult"); + + QTest::newRow("harald") << "harald" << 0 << 0; + QTest::newRow("trond") << "trond" << 0 << 1; + QTest::newRow("vohi") << "vohi" << 0 << 2; + QTest::newRow("harald-1") << "harald" << 1 << 3; + + QTest::newRow("hans") << "hans" << 0 << -1; + QTest::newRow("trond-1") << "trond" << 2 << -1; + QTest::newRow("harald-2") << "harald" << -1 << 3; + QTest::newRow("vohi-1") << "vohi" << -3 << 2; +} + void tst_QStringList::indexOf() { QStringList list; list << "harald" << "trond" << "vohi" << "harald"; - QCOMPARE(list.indexOf("harald"), 0); - QCOMPARE(list.indexOf("trond"), 1); - QCOMPARE(list.indexOf("vohi"), 2); - QCOMPARE(list.indexOf("harald", 1), 3); + QFETCH(QString, search); + QFETCH(int, from); + QFETCH(int, expectedResult); - QCOMPARE(list.indexOf("hans"), -1); - QCOMPARE(list.indexOf("trond", 2), -1); - QCOMPARE(list.indexOf("harald", -1), 3); - QCOMPARE(list.indexOf("vohi", -3), 2); + QCOMPARE(list.indexOf(search, from), expectedResult); + QCOMPARE(list.indexOf(QStringView(search), from), expectedResult); + QCOMPARE(list.indexOf(QLatin1String(search.toLatin1()), from), expectedResult); +} + +void tst_QStringList::lastIndexOf_data() +{ + QTest::addColumn("search"); + QTest::addColumn("from"); + QTest::addColumn("expectedResult"); + + QTest::newRow("harald") << "harald" << -1 << 3; + QTest::newRow("trond") << "trond" << -1 << 1; + QTest::newRow("vohi") << "vohi" << -1 << 2; + QTest::newRow("harald-1") << "harald" << 2 << 0; + + QTest::newRow("hans") << "hans" << -1 << -1; + QTest::newRow("vohi-1") << "vohi" << 1 << -1; + QTest::newRow("vohi-2") << "vohi" << -1 << 2; + QTest::newRow("vohi-3") << "vohi" << -3 << -1; } void tst_QStringList::lastIndexOf() @@ -162,15 +196,13 @@ void tst_QStringList::lastIndexOf() QStringList list; list << "harald" << "trond" << "vohi" << "harald"; - QCOMPARE(list.lastIndexOf("harald"), 3); - QCOMPARE(list.lastIndexOf("trond"), 1); - QCOMPARE(list.lastIndexOf("vohi"), 2); - QCOMPARE(list.lastIndexOf("harald", 2), 0); + QFETCH(QString, search); + QFETCH(int, from); + QFETCH(int, expectedResult); - QCOMPARE(list.lastIndexOf("hans"), -1); - QCOMPARE(list.lastIndexOf("vohi", 1), -1); - QCOMPARE(list.lastIndexOf("vohi", -1), 2); - QCOMPARE(list.lastIndexOf("vohi", -3), -1); + QCOMPARE(list.lastIndexOf(search, from), expectedResult); + QCOMPARE(list.lastIndexOf(QStringView(search), from), expectedResult); + QCOMPARE(list.lastIndexOf(QLatin1String(search.toLatin1()), from), expectedResult); } void tst_QStringList::filter() From 7cc6f78dd448992c9a9cb31e001b908d44028516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Fri, 24 Aug 2018 17:37:36 +0200 Subject: [PATCH 0887/1650] Schannel support Adds support for Schannel, an SSL backend for Windows, as an alternative to OpenSSL. [ChangeLog][QtNetwork][Ssl] Added support for Schannel on Desktop Windows. To build Qt with Schannel support use '-schannel' during configure. Task-number: QTBUG-62637 Change-Id: Ic4fb8ed3657dab994f9f4a4ac5cbddc7001a0a46 Reviewed-by: Timur Pocheptsov --- src/network/configure.json | 21 +- src/network/ssl/qsslcertificate.cpp | 3 + src/network/ssl/qsslcertificate_p.h | 14 + src/network/ssl/qsslcertificate_qt.cpp | 6 +- src/network/ssl/qsslcertificate_schannel.cpp | 62 + src/network/ssl/qsslconfiguration.cpp | 4 + src/network/ssl/qsslellipticcurve.cpp | 2 + src/network/ssl/qsslkey_schannel.cpp | 174 ++ .../ssl/qsslpresharedkeyauthenticator.cpp | 2 + src/network/ssl/qsslsocket.cpp | 4 + src/network/ssl/qsslsocket.h | 2 +- src/network/ssl/qsslsocket_p.h | 4 +- src/network/ssl/qsslsocket_schannel.cpp | 1912 +++++++++++++++++ src/network/ssl/qsslsocket_schannel_p.h | 155 ++ src/network/ssl/ssl.pri | 13 + .../qsslcertificate/tst_qsslcertificate.cpp | 4 +- .../auto/network/ssl/qsslkey/tst_qsslkey.cpp | 14 +- .../network/ssl/qsslsocket/tst_qsslsocket.cpp | 49 +- 18 files changed, 2428 insertions(+), 17 deletions(-) create mode 100644 src/network/ssl/qsslcertificate_schannel.cpp create mode 100644 src/network/ssl/qsslkey_schannel.cpp create mode 100644 src/network/ssl/qsslsocket_schannel.cpp create mode 100644 src/network/ssl/qsslsocket_schannel_p.h diff --git a/src/network/configure.json b/src/network/configure.json index c3b2f4e581..f87e0b12ab 100644 --- a/src/network/configure.json +++ b/src/network/configure.json @@ -18,6 +18,7 @@ "ocsp": "boolean", "sctp": "boolean", "securetransport": "boolean", + "schannel": "boolean", "ssl": "boolean", "system-proxies": "boolean" } @@ -243,13 +244,13 @@ "autoDetect": "!config.winrt && !config.wasm", "enable": "input.openssl == 'yes' || input.openssl == 'runtime'", "disable": "input.openssl == 'no' || input.openssl == 'linked' || input.ssl == 'no'", - "condition": "!features.securetransport && libs.openssl_headers" + "condition": "!features.securetransport && !features.schannel && libs.openssl_headers" }, "openssl-linked": { "label": " Qt directly linked to OpenSSL", "autoDetect": false, "enable": "input.openssl == 'linked'", - "condition": "!features.securetransport && libs.openssl", + "condition": "!features.securetransport && !features.schannel && libs.openssl", "output": [ "privateFeature", { "type": "define", "name": "QT_LINKED_OPENSSL" } @@ -264,9 +265,18 @@ { "type": "define", "name": "QT_SECURETRANSPORT" } ] }, + "schannel": { + "label": "Schannel", + "disable": "input.schannel == 'no' || input.ssl == 'no'", + "condition": "input.schannel == 'yes' && config.win32 && !config.winrt && (input.openssl == '' || input.openssl == 'no')", + "output": [ + "publicFeature", + { "type": "define", "name": "QT_SCHANNEL" } + ] + }, "ssl": { "label": "SSL", - "condition": "config.winrt || features.securetransport || features.openssl", + "condition": "config.winrt || features.securetransport || features.openssl || features.schannel", "output": [ "publicFeature", "feature" ] }, "dtls": { @@ -412,6 +422,11 @@ For example: "args": "securetransport", "condition": "config.darwin" }, + { + "type": "feature", + "args": "schannel", + "condition": "config.win32 && !config.winrt" + }, "openssl", "openssl-linked", "opensslv11", diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index d153e0b929..0156b5bf96 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -121,6 +121,9 @@ #ifdef QT_SECURETRANSPORT #include "qsslsocket_mac_p.h" #endif +#if QT_CONFIG(schannel) +#include "qsslsocket_schannel_p.h" +#endif #include "qssl_p.h" #include "qsslcertificate.h" diff --git a/src/network/ssl/qsslcertificate_p.h b/src/network/ssl/qsslcertificate_p.h index 2dbc4145af..4b331d4c4e 100644 --- a/src/network/ssl/qsslcertificate_p.h +++ b/src/network/ssl/qsslcertificate_p.h @@ -75,6 +75,10 @@ struct ASN1_OBJECT; #include #endif +#if QT_CONFIG(schannel) +#include +#endif + QT_BEGIN_NAMESPACE // forward declaration @@ -95,6 +99,10 @@ public: #ifndef QT_NO_OPENSSL if (x509) q_X509_free(x509); +#endif +#if QT_CONFIG(schannel) + if (certificateContext) + CertFreeCertificateContext(certificateContext); #endif } @@ -143,6 +151,12 @@ public: static QSslCertificate QSslCertificate_from_Certificate(ABI::Windows::Security::Cryptography::Certificates::ICertificate *iCertificate); #endif + +#if QT_CONFIG(schannel) + const CERT_CONTEXT *certificateContext = nullptr; + + static QSslCertificate QSslCertificate_from_CERT_CONTEXT(const CERT_CONTEXT *certificateContext); +#endif }; QT_END_NAMESPACE diff --git a/src/network/ssl/qsslcertificate_qt.cpp b/src/network/ssl/qsslcertificate_qt.cpp index dfdfd529e5..2bd5b3b412 100644 --- a/src/network/ssl/qsslcertificate_qt.cpp +++ b/src/network/ssl/qsslcertificate_qt.cpp @@ -139,7 +139,7 @@ QDateTime QSslCertificate::expiryDate() const return d->notValidAfter; } -#ifndef Q_OS_WINRT // implemented in qsslcertificate_winrt.cpp +#if !defined(Q_OS_WINRT) && !QT_CONFIG(schannel) // implemented in qsslcertificate_{winrt,schannel}.cpp Qt::HANDLE QSslCertificate::handle() const { Q_UNIMPLEMENTED(); @@ -206,6 +206,10 @@ void QSslCertificatePrivate::init(const QByteArray &data, QSsl::EncodingFormat f : certificatesFromDer(data, 1); if (!certs.isEmpty()) { *this = *certs.first().d; +#if QT_CONFIG(schannel) + if (certificateContext) + certificateContext = CertDuplicateCertificateContext(certificateContext); +#endif } } } diff --git a/src/network/ssl/qsslcertificate_schannel.cpp b/src/network/ssl/qsslcertificate_schannel.cpp new file mode 100644 index 0000000000..5ea713612a --- /dev/null +++ b/src/network/ssl/qsslcertificate_schannel.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsslcertificate.h" +#include "qsslcertificate_p.h" + +#include + +QT_BEGIN_NAMESPACE + +QSslCertificate QSslCertificatePrivate::QSslCertificate_from_CERT_CONTEXT(const CERT_CONTEXT *certificateContext) +{ + QByteArray derData = QByteArray((const char *)certificateContext->pbCertEncoded, + certificateContext->cbCertEncoded); + + QSslCertificate certificate(derData, QSsl::Der); + certificate.d->certificateContext = CertDuplicateCertificateContext(certificateContext); + return certificate; +} + +Qt::HANDLE QSslCertificate::handle() const +{ + return Qt::HANDLE(d->certificateContext); +} + +QT_END_NAMESPACE diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp index 4697a5f90f..7e92d3a526 100644 --- a/src/network/ssl/qsslconfiguration.cpp +++ b/src/network/ssl/qsslconfiguration.cpp @@ -587,6 +587,8 @@ void QSslConfiguration::setPrivateKey(const QSslKey &key) ciphers. You can revert to using the entire set by calling setCiphers() with the list returned by QSslSocket::supportedCiphers(). + \note This is not currently supported in the Schannel backend. + \sa setCiphers(), QSslSocket::supportedCiphers() */ QList QSslConfiguration::ciphers() const @@ -602,6 +604,8 @@ QList QSslConfiguration::ciphers() const Restricting the cipher suite must be done before the handshake phase, where the session cipher is chosen. + \note This is not currently supported in the Schannel backend. + \sa ciphers(), QSslSocket::supportedCiphers() */ void QSslConfiguration::setCiphers(const QList &ciphers) diff --git a/src/network/ssl/qsslellipticcurve.cpp b/src/network/ssl/qsslellipticcurve.cpp index 88baa1ff6c..5608d32fa7 100644 --- a/src/network/ssl/qsslellipticcurve.cpp +++ b/src/network/ssl/qsslellipticcurve.cpp @@ -64,6 +64,8 @@ QT_BEGIN_NAMESPACE QSslEllipticCurve instances can be compared for equality and can be used as keys in QHash and QSet. They cannot be used as key in a QMap. + + \note This class is currently only supported in OpenSSL. */ /*! diff --git a/src/network/ssl/qsslkey_schannel.cpp b/src/network/ssl/qsslkey_schannel.cpp new file mode 100644 index 0000000000..5694068860 --- /dev/null +++ b/src/network/ssl/qsslkey_schannel.cpp @@ -0,0 +1,174 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qssl_p.h" +#include "qsslkey.h" +#include "qsslkey_p.h" +#include "qsslcertificate_p.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +namespace { +const wchar_t *getName(QSslKeyPrivate::Cipher cipher) +{ + switch (cipher) { + case QSslKeyPrivate::Cipher::DesCbc: + return BCRYPT_DES_ALGORITHM; + case QSslKeyPrivate::Cipher::DesEde3Cbc: + return BCRYPT_3DES_ALGORITHM; + case QSslKeyPrivate::Cipher::Rc2Cbc: + return BCRYPT_RC2_ALGORITHM; + } + Q_UNREACHABLE(); +} + +BCRYPT_ALG_HANDLE getHandle(QSslKeyPrivate::Cipher cipher) +{ + BCRYPT_ALG_HANDLE handle; + NTSTATUS status = BCryptOpenAlgorithmProvider( + &handle, // phAlgorithm + getName(cipher), // pszAlgId + nullptr, // pszImplementation + 0 // dwFlags + ); + if (status < 0) { + qCWarning(lcSsl, "Failed to open algorithm handle (%ld)!", status); + return nullptr; + } + + return handle; +} + +BCRYPT_KEY_HANDLE generateSymmetricKey(BCRYPT_ALG_HANDLE handle, + const QByteArray &key) +{ + BCRYPT_KEY_HANDLE keyHandle; + NTSTATUS status = BCryptGenerateSymmetricKey( + handle, // hAlgorithm + &keyHandle, // phKey + nullptr, // pbKeyObject (can ignore) + 0, // cbKeyObject (also ignoring) + reinterpret_cast(const_cast(key.data())), // pbSecret + ULONG(key.length()), // cbSecret + 0 // dwFlags + ); + if (status < 0) { + qCWarning(lcSsl, "Failed to generate symmetric key (%ld)!", status); + return nullptr; + } + + status = BCryptSetProperty( + keyHandle, // hObject + BCRYPT_CHAINING_MODE, // pszProperty + reinterpret_cast(const_cast(BCRYPT_CHAIN_MODE_CBC)), // pbInput + ARRAYSIZE(BCRYPT_CHAIN_MODE_CBC), // cbInput + 0 // dwFlags + ); + if (status < 0) { + BCryptDestroyKey(keyHandle); + qCWarning(lcSsl, "Failed to change the symmetric key's chaining mode (%ld)!", status); + return nullptr; + } + return keyHandle; +} + +QByteArray doCrypt(QSslKeyPrivate::Cipher cipher, const QByteArray &data, const QByteArray &key, + const QByteArray &iv, bool encrypt) +{ + BCRYPT_ALG_HANDLE handle = getHandle(cipher); + if (!handle) + return {}; + auto handleDealloc = qScopeGuard([&handle]() { + BCryptCloseAlgorithmProvider(handle, 0); + }); + + BCRYPT_KEY_HANDLE keyHandle = generateSymmetricKey(handle, key); + if (!keyHandle) + return {}; + auto keyHandleDealloc = qScopeGuard([&keyHandle]() { + BCryptDestroyKey(keyHandle); + }); + + QByteArray ivCopy = iv; // This gets modified, so we take a copy + + ULONG sizeNeeded = 0; + QVarLengthArray output; + auto cryptFunction = encrypt ? BCryptEncrypt : BCryptDecrypt; + for (int i = 0; i < 2; i++) { + output.resize(int(sizeNeeded)); + auto input = reinterpret_cast(const_cast(data.data())); + // Need to call it twice because the first iteration lets us know the size needed. + NTSTATUS status = cryptFunction( + keyHandle, // hKey + input, // pbInput + ULONG(data.length()), // cbInput + nullptr, // pPaddingInfo + reinterpret_cast(ivCopy.data()), // pbIV + ULONG(ivCopy.length()), // cbIV + sizeNeeded ? output.data() : nullptr, // pbOutput + ULONG(output.length()), // cbOutput + &sizeNeeded, // pcbResult + BCRYPT_BLOCK_PADDING // dwFlags + ); + if (status < 0) { + qCWarning(lcSsl, "%s failed (%ld)!", encrypt ? "Encrypt" : "Decrypt", status); + return {}; + } + } + + return QByteArray(reinterpret_cast(output.constData()), int(sizeNeeded)); +} +} // anonymous namespace + +QByteArray QSslKeyPrivate::decrypt(Cipher cipher, const QByteArray &data, const QByteArray &key, + const QByteArray &iv) +{ + return doCrypt(cipher, data, key, iv, false); +} + +QByteArray QSslKeyPrivate::encrypt(Cipher cipher, const QByteArray &data, const QByteArray &key, + const QByteArray &iv) +{ + return doCrypt(cipher, data, key, iv, true); +} + +QT_END_NAMESPACE diff --git a/src/network/ssl/qsslpresharedkeyauthenticator.cpp b/src/network/ssl/qsslpresharedkeyauthenticator.cpp index 3bb2719026..01e1501763 100644 --- a/src/network/ssl/qsslpresharedkeyauthenticator.cpp +++ b/src/network/ssl/qsslpresharedkeyauthenticator.cpp @@ -94,6 +94,8 @@ QSslPreSharedKeyAuthenticatorPrivate::QSslPreSharedKeyAuthenticatorPrivate() \note PSK ciphersuites are supported only when using OpenSSL 1.0.1 (or greater) as the SSL backend. + \note PSK is currently only supported in OpenSSL. + \sa QSslSocket */ diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index a6c86837ea..a58f0b7e61 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -203,6 +203,7 @@ does not require this certificate to be valid. This is useful when you want to display peer certificate details to the user without affecting the actual SSL handshake. This mode is the default for servers. + Note: In Schannel this value acts the same as VerifyNone. \value VerifyPeer QSslSocket will request a certificate from the peer during the SSL handshake phase, and requires that this certificate is @@ -322,6 +323,9 @@ #ifdef QT_SECURETRANSPORT #include "qsslsocket_mac_p.h" #endif +#if QT_CONFIG(schannel) +#include "qsslsocket_schannel_p.h" +#endif #include "qsslconfiguration_p.h" #include diff --git a/src/network/ssl/qsslsocket.h b/src/network/ssl/qsslsocket.h index c66ebdde54..cf68aeeaf0 100644 --- a/src/network/ssl/qsslsocket.h +++ b/src/network/ssl/qsslsocket.h @@ -228,7 +228,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_flushWriteBuffer()) Q_PRIVATE_SLOT(d_func(), void _q_flushReadBuffer()) Q_PRIVATE_SLOT(d_func(), void _q_resumeImplementation()) -#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) && !QT_CONFIG(schannel) Q_PRIVATE_SLOT(d_func(), void _q_caRootLoaded(QSslCertificate,QSslCertificate)) #endif friend class QSslSocketBackendPrivate; diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h index 5115613695..3c37d5ad86 100644 --- a/src/network/ssl/qsslsocket_p.h +++ b/src/network/ssl/qsslsocket_p.h @@ -171,7 +171,7 @@ public: void _q_flushWriteBuffer(); void _q_flushReadBuffer(); void _q_resumeImplementation(); -#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) && !QT_CONFIG(schannel) virtual void _q_caRootLoaded(QSslCertificate,QSslCertificate) = 0; #endif @@ -209,7 +209,7 @@ protected: bool flushTriggered; }; -#if QT_CONFIG(securetransport) +#if QT_CONFIG(securetransport) || QT_CONFIG(schannel) // Implemented in qsslsocket_qt.cpp QByteArray _q_makePkcs12(const QList &certs, const QSslKey &key, const QString &passPhrase); #endif diff --git a/src/network/ssl/qsslsocket_schannel.cpp b/src/network/ssl/qsslsocket_schannel.cpp new file mode 100644 index 0000000000..e5f31a3fcf --- /dev/null +++ b/src/network/ssl/qsslsocket_schannel.cpp @@ -0,0 +1,1912 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// #define QSSLSOCKET_DEBUG + +#include "qssl_p.h" +#include "qsslsocket.h" +#include "qsslsocket_schannel_p.h" +#include "qsslcertificate.h" +#include "qsslcertificateextension.h" +#include "qsslcertificate_p.h" +#include "qsslcipher_p.h" + +#include +#include +#include +#include +#include + +#define SECURITY_WIN32 +#include +#include + +// Not defined in MinGW +#ifndef SECBUFFER_ALERT +#define SECBUFFER_ALERT 17 +#endif +#ifndef SECPKG_ATTR_APPLICATION_PROTOCOL +#define SECPKG_ATTR_APPLICATION_PROTOCOL 35 +#endif + +// Another missing MinGW define +#ifndef SEC_E_APPLICATION_PROTOCOL_MISMATCH +#define SEC_E_APPLICATION_PROTOCOL_MISMATCH _HRESULT_TYPEDEF_(0x80090367L) +#endif + +// Also not defined in MinGW....... +#ifndef SP_PROT_TLS1_SERVER +#define SP_PROT_TLS1_SERVER 0x00000040 +#endif +#ifndef SP_PROT_TLS1_CLIENT +#define SP_PROT_TLS1_CLIENT 0x00000080 +#endif +#ifndef SP_PROT_TLS1_0_SERVER +#define SP_PROT_TLS1_0_SERVER SP_PROT_TLS1_SERVER +#endif +#ifndef SP_PROT_TLS1_0_CLIENT +#define SP_PROT_TLS1_0_CLIENT SP_PROT_TLS1_CLIENT +#endif +#ifndef SP_PROT_TLS1_0 +#define SP_PROT_TLS1_0 (SP_PROT_TLS1_0_CLIENT | SP_PROT_TLS1_0_SERVER) +#endif +#ifndef SP_PROT_TLS1_1_SERVER +#define SP_PROT_TLS1_1_SERVER 0x00000100 +#endif +#ifndef SP_PROT_TLS1_1_CLIENT +#define SP_PROT_TLS1_1_CLIENT 0x00000200 +#endif +#ifndef SP_PROT_TLS1_1 +#define SP_PROT_TLS1_1 (SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_1_SERVER) +#endif +#ifndef SP_PROT_TLS1_2_SERVER +#define SP_PROT_TLS1_2_SERVER 0x00000400 +#endif +#ifndef SP_PROT_TLS1_2_CLIENT +#define SP_PROT_TLS1_2_CLIENT 0x00000800 +#endif +#ifndef SP_PROT_TLS1_2 +#define SP_PROT_TLS1_2 (SP_PROT_TLS1_2_CLIENT | SP_PROT_TLS1_2_SERVER) +#endif +#ifndef SP_PROT_TLS1_3_SERVER +#define SP_PROT_TLS1_3_SERVER 0x00001000 +#endif +#ifndef SP_PROT_TLS1_3_CLIENT +#define SP_PROT_TLS1_3_CLIENT 0x00002000 +#endif +#ifndef SP_PROT_TLS1_3 +#define SP_PROT_TLS1_3 (SP_PROT_TLS1_3_CLIENT | SP_PROT_TLS1_3_SERVER) +#endif + +/* + @future!: + + - Transmitting intermediate certificates + - Look for a way to avoid putting intermediate certificates in the certificate store + - No documentation on how to send the chain + - A stackoverflow question on this from 3 years ago implies schannel only sends intermediate + certificates if it's "in the system or user certificate store". + - https://stackoverflow.com/q/30156584/2493610 + - This can be done by users, but we shouldn't add any and all local intermediate + certs to the stores automatically. + - PSK support + - Was added in Windows 10 (it seems), documentation at time of writing is sparse/non-existent. + - Specifically about how to supply credentials when they're requested. + - Or how to recognize that they're requested in the first place. + - Skip certificate verification. + - Check if "PSK-only" is still required to do PSK _at all_ (all-around bad solution). + - Check if SEC_I_INCOMPLETE_CREDENTIALS is still returned for both "missing certificate" and + "missing PSK" when calling InitializeSecurityContext in "performHandshake". + + Medium priority: + - Setting cipher-suites (or ALG_ID) + - People have survived without it in WinRT + - ALPN: + For HTTP2. Note: Windows 8.1 and up ONLY. + + Low priority: + - Possibly make RAII wrappers for SecBuffer (which I commonly create QScopeGuards for) + - Perform the '@future' optimization in "transmit()" + +*/ + +QT_BEGIN_NAMESPACE + +namespace { +SecBuffer createSecBuffer(void *ptr, unsigned long length, unsigned long bufferType) +{ + return SecBuffer{ length, bufferType, ptr }; +} + +SecBuffer createSecBuffer(QByteArray &buffer, unsigned long bufferType) +{ + return createSecBuffer(buffer.data(), static_cast(buffer.length()), bufferType); +} + +QString schannelErrorToString(qint32 status) +{ + switch (status) { + case SEC_E_INSUFFICIENT_MEMORY: + return QSslSocket::tr("Insufficient memory"); + case SEC_E_INTERNAL_ERROR: + return QSslSocket::tr("Internal error"); + case SEC_E_INVALID_HANDLE: + return QSslSocket::tr("An internal handle was invalid"); + case SEC_E_INVALID_TOKEN: + return QSslSocket::tr("An internal token was invalid"); + case SEC_E_LOGON_DENIED: + // According to the link below we get this error when Schannel receives TLS1_ALERT_ACCESS_DENIED + // https://docs.microsoft.com/en-us/windows/desktop/secauthn/schannel-error-codes-for-tls-and-ssl-alerts + return QSslSocket::tr("Access denied"); + case SEC_E_NO_AUTHENTICATING_AUTHORITY: + return QSslSocket::tr("No authority could be contacted for authorization"); + case SEC_E_NO_CREDENTIALS: + return QSslSocket::tr("No credentials"); + case SEC_E_TARGET_UNKNOWN: + return QSslSocket::tr("The target is unknown or unreachable"); + case SEC_E_UNSUPPORTED_FUNCTION: + return QSslSocket::tr("An unsupported function was requested"); + case SEC_E_WRONG_PRINCIPAL: + // SNI error + return QSslSocket::tr("The hostname provided does not match the one received from the peer"); + case SEC_E_APPLICATION_PROTOCOL_MISMATCH: + return QSslSocket::tr("No common protocol exists between the client and the server"); + case SEC_E_ILLEGAL_MESSAGE: + return QSslSocket::tr("Unexpected or badly-formatted message received"); + case SEC_E_ENCRYPT_FAILURE: + return QSslSocket::tr("The data could not be encrypted"); + case SEC_E_ALGORITHM_MISMATCH: + return QSslSocket::tr("No cipher suites in common"); + case SEC_E_UNKNOWN_CREDENTIALS: + // This can mean "invalid argument" in some cases... + return QSslSocket::tr("The credentials were not recognized / Invalid argument"); + case SEC_E_MESSAGE_ALTERED: + // According to the Internet it also triggers for messages that are out of order. + // https://microsoft.public.platformsdk.security.narkive.com/4JAvlMvD/help-please-schannel-security-contexts-and-decryptmessage + return QSslSocket::tr("The message was tampered with, damaged or out of sequence."); + case SEC_E_OUT_OF_SEQUENCE: + return QSslSocket::tr("A message was received out of sequence."); + case SEC_E_CONTEXT_EXPIRED: + return QSslSocket::tr("The TLS/SSL connection has been closed"); + default: + return QSslSocket::tr("Unknown error occurred: %1").arg(status); + } +} + +DWORD toSchannelProtocol(QSsl::SslProtocol protocol) +{ + DWORD protocols = SP_PROT_NONE; + switch (protocol) { + case QSsl::UnknownProtocol: + return DWORD(-1); + case QSsl::DtlsV1_0: + case QSsl::DtlsV1_2: + case QSsl::DtlsV1_0OrLater: + case QSsl::DtlsV1_2OrLater: + return DWORD(-1); // Not supported at the moment (@future) + case QSsl::AnyProtocol: + protocols = SP_PROT_TLS1_0 | SP_PROT_TLS1_1 | SP_PROT_TLS1_2; + // @future Add TLS 1.3 when supported by Windows! + break; + case QSsl::SslV2: + case QSsl::SslV3: + return DWORD(-1); // Not supported + case QSsl::TlsV1SslV3: + protocols = SP_PROT_TLS1_0; + break; + case QSsl::TlsV1_0: + protocols = SP_PROT_TLS1_0; + break; + case QSsl::TlsV1_1: + protocols = SP_PROT_TLS1_1; + break; + case QSsl::TlsV1_2: + protocols = SP_PROT_TLS1_2; + break; + case QSsl::TlsV1_3: + if ((false)) // @future[0/1] Replace with version check once it's supported in Windows + protocols = SP_PROT_TLS1_3; + else + protocols = DWORD(-1); + break; + case QSsl::SecureProtocols: // TLS v1.0 and later is currently considered secure + case QSsl::TlsV1_0OrLater: + // For the "OrLater" protocols we fall through from one to the next, adding all of them + // in ascending order + protocols = SP_PROT_TLS1_0; + Q_FALLTHROUGH(); + case QSsl::TlsV1_1OrLater: + protocols |= SP_PROT_TLS1_1; + Q_FALLTHROUGH(); + case QSsl::TlsV1_2OrLater: + protocols |= SP_PROT_TLS1_2; + Q_FALLTHROUGH(); + case QSsl::TlsV1_3OrLater: + if ((false)) // @future[1/1] Also replace this with a version check + protocols |= SP_PROT_TLS1_3; + else if (protocol == QSsl::TlsV1_3OrLater) + protocols = DWORD(-1); // if TlsV1_3OrLater was specifically chosen we should fail + break; + } + return protocols; +} + +/*! + \internal + Used when converting the established session's \a protocol back to + Qt's own SslProtocol type. + + Only one protocol should be passed in at a time. +*/ +QSsl::SslProtocol toQtSslProtocol(DWORD protocol) +{ +#define MAP_PROTOCOL(sp_protocol, q_protocol) \ + if (protocol & sp_protocol) { \ + Q_ASSERT(!(protocol & ~sp_protocol)); \ + return q_protocol; \ + } + + MAP_PROTOCOL(SP_PROT_TLS1_0, QSsl::TlsV1_0) + MAP_PROTOCOL(SP_PROT_TLS1_1, QSsl::TlsV1_1) + MAP_PROTOCOL(SP_PROT_TLS1_2, QSsl::TlsV1_2) + MAP_PROTOCOL(SP_PROT_TLS1_3, QSsl::TlsV1_3) +#undef MAP_PROTOCOL + Q_UNREACHABLE(); + return QSsl::UnknownProtocol; +} + +/*! + \internal + Used by verifyCertContext to check if a client cert is used by a server or vice versa. +*/ +bool netscapeWrongCertType(const QList &extensions, bool isClient) +{ + const auto netscapeIt = std::find_if( + extensions.cbegin(), extensions.cend(), + [](const QSslCertificateExtension &extension) { + const auto netscapeCertType = QStringLiteral("2.16.840.1.113730.1.1"); + return extension.oid() == netscapeCertType; + }); + if (netscapeIt != extensions.cend()) { + const QByteArray netscapeCertTypeByte = netscapeIt->value().toByteArray(); + int netscapeCertType = 0; + QDataStream dataStream(netscapeCertTypeByte); + dataStream >> netscapeCertType; + if (dataStream.status() != QDataStream::Status::Ok) + return true; + const int expectedPeerCertType = isClient ? NETSCAPE_SSL_SERVER_AUTH_CERT_TYPE + : NETSCAPE_SSL_CLIENT_AUTH_CERT_TYPE; + if ((netscapeCertType & expectedPeerCertType) == 0) + return true; + } + return false; +} + +/*! + \internal + Used by verifyCertContext to check the basicConstraints certificate + extension to see if the certificate is a certificate authority. + Returns false if the certificate does not have the basicConstraints + extension or if it is not a certificate authority. +*/ +bool isCertificateAuthority(const QList &extensions) +{ + auto it = std::find_if(extensions.cbegin(), extensions.cend(), + [](const QSslCertificateExtension &extension) { + return extension.name() == QLatin1String("basicConstraints"); + }); + if (it != extensions.cend()) { + QVariantMap basicConstraints = it->value().toMap(); + return basicConstraints.value(QLatin1String("ca"), false).toBool(); + } + return false; +} + +/*! + \internal + Returns true if the attributes we requested from the context/handshake have + been given. +*/ +bool matchesContextRequirements(DWORD attributes, DWORD requirements, + QSslSocket::PeerVerifyMode verifyMode, + bool isClient) +{ +#ifdef QSSLSOCKET_DEBUG +#define DEBUG_WARN(message) qCWarning(lcSsl, message) +#else +#define DEBUG_WARN(message) +#endif + +#define CHECK_ATTRIBUTE(attributeName) \ + do { \ + const DWORD req##attributeName = isClient ? ISC_REQ_##attributeName : ASC_REQ_##attributeName; \ + const DWORD ret##attributeName = isClient ? ISC_RET_##attributeName : ASC_RET_##attributeName; \ + if (!(requirements & req##attributeName) != !(attributes & ret##attributeName)) { \ + DEBUG_WARN("Missing attribute \"" #attributeName "\""); \ + return false; \ + } \ + } while (false) + + CHECK_ATTRIBUTE(CONFIDENTIALITY); + CHECK_ATTRIBUTE(REPLAY_DETECT); + CHECK_ATTRIBUTE(SEQUENCE_DETECT); + CHECK_ATTRIBUTE(STREAM); + if (verifyMode == QSslSocket::PeerVerifyMode::VerifyPeer) + CHECK_ATTRIBUTE(MUTUAL_AUTH); + + // This one is manual because there is no server / ASC_ version + if (isClient) { + const auto reqManualCredValidation = ISC_REQ_MANUAL_CRED_VALIDATION; + const auto retManualCredValidation = ISC_RET_MANUAL_CRED_VALIDATION; + if (!(requirements & reqManualCredValidation) != !(attributes & retManualCredValidation)) { + DEBUG_WARN("Missing attribute \"MANUAL_CRED_VALIDATION\""); + return false; + } + } + + return true; +#undef CHECK_ATTRIBUTE +#undef DEBUG_WARN +} + +template +Required const_reinterpret_cast(Actual *p) +{ + return Required(p); +} + +} // anonymous namespace + +bool QSslSocketPrivate::s_loadRootCertsOnDemand = true; +bool QSslSocketPrivate::s_loadedCiphersAndCerts = false; +Q_GLOBAL_STATIC_WITH_ARGS(QMutex, qt_schannel_mutex, (QMutex::Recursive)) + +void QSslSocketPrivate::ensureInitialized() +{ + const QMutexLocker locker(qt_schannel_mutex); + if (s_loadedCiphersAndCerts) + return; + s_loadedCiphersAndCerts = true; + + setDefaultCaCertificates(systemCaCertificates()); + s_loadRootCertsOnDemand = true; // setDefaultCaCertificates sets it to false, re-enable it. + + resetDefaultCiphers(); +} + +void QSslSocketPrivate::resetDefaultCiphers() +{ + setDefaultSupportedCiphers(QSslSocketBackendPrivate::defaultCiphers()); + setDefaultCiphers(QSslSocketBackendPrivate::defaultCiphers()); +} + +void QSslSocketPrivate::resetDefaultEllipticCurves() +{ + Q_UNIMPLEMENTED(); +} + +bool QSslSocketPrivate::supportsSsl() +{ + return true; +} + +QList QSslSocketPrivate::systemCaCertificates() +{ + // Copied from qsslsocket_openssl.cpp's systemCaCertificates function. + QList systemCerts; + auto hSystemStore = QHCertStorePointer(CertOpenSystemStore(0, L"ROOT")); + if (hSystemStore) { + PCCERT_CONTEXT pc = nullptr; + while ((pc = CertFindCertificateInStore(hSystemStore.get(), X509_ASN_ENCODING, 0, + CERT_FIND_ANY, nullptr, pc))) { + systemCerts.append(QSslCertificatePrivate::QSslCertificate_from_CERT_CONTEXT(pc)); + } + } + return systemCerts; +} + +long QSslSocketPrivate::sslLibraryVersionNumber() +{ + const auto os = QOperatingSystemVersion::current(); + return (os.majorVersion() << 24) | ((os.minorVersion() & 0xFF) << 16) | (os.microVersion() & 0xFFFF); +} + +QString QSslSocketPrivate::sslLibraryVersionString() +{ + const auto os = QOperatingSystemVersion::current(); + return QString::fromLatin1("Secure Channel, %1 %2.%3.%4") + .arg(os.name(), + QString::number(os.majorVersion()), + QString::number(os.minorVersion()), + QString::number(os.microVersion())); +} + +long QSslSocketPrivate::sslLibraryBuildVersionNumber() +{ + // There is no separate build version + return sslLibraryVersionNumber(); +} + +QString QSslSocketPrivate::sslLibraryBuildVersionString() +{ + const auto os = QOperatingSystemVersion::current(); + return QString::fromLatin1("%1.%2.%3") + .arg(QString::number(os.majorVersion()), + QString::number(os.minorVersion()), + QString::number(os.microVersion())); +} + +QSslSocketBackendPrivate::QSslSocketBackendPrivate() +{ + SecInvalidateHandle(&credentialHandle); + SecInvalidateHandle(&contextHandle); + ensureInitialized(); +} + +QSslSocketBackendPrivate::~QSslSocketBackendPrivate() +{ + closeCertificateStores(); + deallocateContext(); + freeCredentialsHandle(); + CertFreeCertificateContext(localCertContext); +} + +bool QSslSocketBackendPrivate::sendToken(void *token, unsigned long tokenLength, bool emitError) +{ + if (tokenLength == 0) + return true; + const qint64 written = plainSocket->write(static_cast(token), tokenLength); + if (written != qint64(tokenLength)) { + // Failed to write/buffer everything or an error occurred + if (emitError) + setErrorAndEmit(plainSocket->error(), plainSocket->errorString()); + return false; + } + return true; +} + +QString QSslSocketBackendPrivate::targetName() const +{ + // Used for SNI extension + return verificationPeerName.isEmpty() ? q_func()->peerName() : verificationPeerName; +} + +ULONG QSslSocketBackendPrivate::getContextRequirements() +{ + const bool isClient = mode == QSslSocket::SslClientMode; + ULONG req = 0; + + req |= ISC_REQ_ALLOCATE_MEMORY; // Allocate memory for buffers automatically + req |= ISC_REQ_CONFIDENTIALITY; // Encrypt messages + req |= ISC_REQ_REPLAY_DETECT; // Detect replayed messages + req |= ISC_REQ_SEQUENCE_DETECT; // Detect out of sequence messages + req |= ISC_REQ_STREAM; // Support a stream-oriented connection + + if (isClient) { + req |= ISC_REQ_MANUAL_CRED_VALIDATION; // Manually validate certificate + } else { + switch (configuration.peerVerifyMode) { + case QSslSocket::PeerVerifyMode::VerifyNone: + // There doesn't seem to be a way to ask for an optional client cert :-( + case QSslSocket::PeerVerifyMode::AutoVerifyPeer: + case QSslSocket::PeerVerifyMode::QueryPeer: + break; + case QSslSocket::PeerVerifyMode::VerifyPeer: + req |= ISC_REQ_MUTUAL_AUTH; + break; + } + } + + return req; +} + +bool QSslSocketBackendPrivate::acquireCredentialsHandle() +{ + Q_ASSERT(schannelState == SchannelState::InitializeHandshake); + + const bool isClient = mode == QSslSocket::SslClientMode; + const DWORD protocols = toSchannelProtocol(configuration.protocol); + if (protocols == DWORD(-1)) { + setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError, + QSslSocket::tr("Invalid protocol chosen")); + return false; + } + + const CERT_CHAIN_CONTEXT *chainContext = nullptr; + auto freeCertChain = qScopeGuard([&chainContext]() { + if (chainContext) + CertFreeCertificateChain(chainContext); + }); + + DWORD certsCount = 0; + // Set up our certificate stores before trying to use one... + initializeCertificateStores(); + + // Check if user has specified a certificate chain but it could not be loaded. + // This happens if there was something wrong with the certificate chain or there was no private + // key. + if (!configuration.localCertificateChain.isEmpty() && !localCertificateStore) + return true; // 'true' because "tst_QSslSocket::setEmptyKey" expects us to not disconnect + + if (localCertificateStore != nullptr) { + CERT_CHAIN_FIND_BY_ISSUER_PARA findParam; + ZeroMemory(&findParam, sizeof(findParam)); + findParam.cbSize = sizeof(findParam); + findParam.pszUsageIdentifier = isClient ? szOID_PKIX_KP_CLIENT_AUTH : szOID_PKIX_KP_SERVER_AUTH; + + // There should only be one chain in our store, so.. we grab that one. + chainContext = CertFindChainInStore(localCertificateStore.get(), + X509_ASN_ENCODING, + 0, + CERT_CHAIN_FIND_BY_ISSUER, + &findParam, + nullptr); + if (!chainContext) { + setErrorAndEmit(QAbstractSocket::SocketError::SslInvalidUserDataError, + QSslSocket::tr("The certificate provided can not be used for a %1.") + .arg(isClient ? QSslSocket::tr("client") + : QSslSocket::tr("server"))); + return false; + } + Q_ASSERT(chainContext->cChain == 1); + Q_ASSERT(chainContext->rgpChain[0]); + Q_ASSERT(chainContext->rgpChain[0]->cbSize >= 1); + Q_ASSERT(chainContext->rgpChain[0]->rgpElement[0]); + Q_ASSERT(!localCertContext); + localCertContext = CertDuplicateCertificateContext(chainContext->rgpChain[0] + ->rgpElement[0] + ->pCertContext); + certsCount = 1; + Q_ASSERT(localCertContext); + } + + SCHANNEL_CRED cred{ + SCHANNEL_CRED_VERSION, // dwVersion + certsCount, // cCreds + &localCertContext, // paCred (certificate(s) containing a private key for authentication) + nullptr, // hRootStore + + 0, // cMappers (reserved) + nullptr, // aphMappers (reserved) + + 0, // cSupportedAlgs + nullptr, // palgSupportedAlgs (nullptr = system default) @future: QSslCipher-related + + protocols, // grbitEnabledProtocols + 0, // dwMinimumCipherStrength (0 = system default) + 0, // dwMaximumCipherStrength (0 = system default) + 0, // dwSessionLifespan (0 = schannel default, 10 hours) + SCH_CRED_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT + | SCH_CRED_NO_DEFAULT_CREDS, // dwFlags + 0 // dwCredFormat (must be 0) + }; + + TimeStamp expiration{}; + auto status = AcquireCredentialsHandle(nullptr, // pszPrincipal (unused) + const_cast(UNISP_NAME), // pszPackage + isClient ? SECPKG_CRED_OUTBOUND : SECPKG_CRED_INBOUND, // fCredentialUse + nullptr, // pvLogonID (unused) + &cred, // pAuthData + nullptr, // pGetKeyFn (unused) + nullptr, // pvGetKeyArgument (unused) + &credentialHandle, // phCredential + &expiration // ptsExpir + ); + + if (status != SEC_E_OK) { + setErrorAndEmit(QAbstractSocket::SslInternalError, schannelErrorToString(status)); + return false; + } + return true; +} + +void QSslSocketBackendPrivate::deallocateContext() +{ + if (SecIsValidHandle(&contextHandle)) { + DeleteSecurityContext(&contextHandle); + SecInvalidateHandle(&contextHandle); + } +} + +void QSslSocketBackendPrivate::freeCredentialsHandle() +{ + if (SecIsValidHandle(&credentialHandle)) { + FreeCredentialsHandle(&credentialHandle); + SecInvalidateHandle(&credentialHandle); + } +} + +void QSslSocketBackendPrivate::closeCertificateStores() +{ + localCertificateStore.reset(); + peerCertificateStore.reset(); + caCertificateStore.reset(); +} + +bool QSslSocketBackendPrivate::createContext() +{ + Q_ASSERT(SecIsValidHandle(&credentialHandle)); + Q_ASSERT(schannelState == SchannelState::InitializeHandshake); + Q_ASSERT(mode == QSslSocket::SslClientMode); + ULONG contextReq = getContextRequirements(); + + SecBuffer outBuffers[3]; + outBuffers[0] = createSecBuffer(nullptr, 0, SECBUFFER_TOKEN); + outBuffers[1] = createSecBuffer(nullptr, 0, SECBUFFER_ALERT); + outBuffers[2] = createSecBuffer(nullptr, 0, SECBUFFER_EMPTY); + auto freeBuffers = qScopeGuard([&outBuffers]() { + for (auto i = 0ull; i < ARRAYSIZE(outBuffers); i++) { + if (outBuffers[i].pvBuffer) + FreeContextBuffer(outBuffers[i].pvBuffer); + } + }); + SecBufferDesc outputBufferDesc{ + SECBUFFER_VERSION, + ARRAYSIZE(outBuffers), + outBuffers + }; + + TimeStamp expiry; + + auto status = InitializeSecurityContext(&credentialHandle, // phCredential + nullptr, // phContext + const_reinterpret_cast(targetName().utf16()), // pszTargetName + contextReq, // fContextReq + 0, // Reserved1 + 0, // TargetDataRep (unused) + nullptr, // pInput (no input at the moment @future: alpn) + 0, // Reserved2 + &contextHandle, // phNewContext + &outputBufferDesc, // pOutput + &contextAttributes, // pfContextAttr + &expiry // ptsExpiry + ); + + // This is the first call to InitializeSecurityContext, so theoretically "CONTINUE_NEEDED" + // should be the only non-error return-code here. + if (status != SEC_I_CONTINUE_NEEDED) { + setErrorAndEmit(QAbstractSocket::SslInternalError, + QSslSocket::tr("Error creating SSL context (%1)").arg(schannelErrorToString(status))); + return false; + } + + if (!sendToken(outBuffers[0].pvBuffer, outBuffers[0].cbBuffer)) + return false; + schannelState = SchannelState::PerformHandshake; + return true; +} + +bool QSslSocketBackendPrivate::acceptContext() +{ + Q_ASSERT(SecIsValidHandle(&credentialHandle)); + Q_ASSERT(schannelState == SchannelState::InitializeHandshake); + Q_ASSERT(mode == QSslSocket::SslServerMode); + ULONG contextReq = getContextRequirements(); + + intermediateBuffer += plainSocket->read(16384); + if (intermediateBuffer.isEmpty()) + return true; // definitely need more data.. + + SecBuffer inBuffers[2]; + inBuffers[0] = createSecBuffer(intermediateBuffer, SECBUFFER_TOKEN); + inBuffers[1] = createSecBuffer(nullptr, 0, SECBUFFER_EMPTY); + SecBufferDesc inputBufferDesc{ + SECBUFFER_VERSION, + ARRAYSIZE(inBuffers), + inBuffers + }; + + SecBuffer outBuffers[3]; + outBuffers[0] = createSecBuffer(nullptr, 0, SECBUFFER_TOKEN); + outBuffers[1] = createSecBuffer(nullptr, 0, SECBUFFER_ALERT); + outBuffers[2] = createSecBuffer(nullptr, 0, SECBUFFER_EMPTY); + auto freeBuffers = qScopeGuard([&outBuffers]() { + for (auto i = 0ull; i < ARRAYSIZE(outBuffers); i++) { + if (outBuffers[i].pvBuffer) + FreeContextBuffer(outBuffers[i].pvBuffer); + } + }); + SecBufferDesc outputBufferDesc{ + SECBUFFER_VERSION, + ARRAYSIZE(outBuffers), + outBuffers + }; + + TimeStamp expiry; + auto status = AcceptSecurityContext( + &credentialHandle, // phCredential + nullptr, // phContext + &inputBufferDesc, // pInput + contextReq, // fContextReq + 0, // TargetDataRep (unused) + &contextHandle, // phNewContext + &outputBufferDesc, // pOutput + &contextAttributes, // pfContextAttr + &expiry // ptsTimeStamp + ); + + if (inBuffers[1].BufferType == SECBUFFER_EXTRA) { + // https://docs.microsoft.com/en-us/windows/desktop/secauthn/extra-buffers-returned-by-schannel + // inBuffers[1].cbBuffer indicates the amount of bytes _NOT_ processed, the rest need to + // be stored. + intermediateBuffer = intermediateBuffer.right(int(inBuffers[1].cbBuffer)); + } else if (status != SEC_E_INCOMPLETE_MESSAGE) { + intermediateBuffer.clear(); + } + + if (status != SEC_I_CONTINUE_NEEDED) { + setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError, + QSslSocket::tr("Error creating SSL context (%1)").arg(schannelErrorToString(status))); + return false; + } + if (!sendToken(outBuffers[0].pvBuffer, outBuffers[0].cbBuffer)) + return false; + schannelState = SchannelState::PerformHandshake; + return true; +} + +bool QSslSocketBackendPrivate::performHandshake() +{ + if (plainSocket->state() == QAbstractSocket::UnconnectedState) { + setErrorAndEmit(QAbstractSocket::RemoteHostClosedError, + QSslSocket::tr("The TLS/SSL connection has been closed")); + return false; + } + Q_ASSERT(SecIsValidHandle(&credentialHandle)); + Q_ASSERT(SecIsValidHandle(&contextHandle)); + Q_ASSERT(schannelState == SchannelState::PerformHandshake); + +#ifdef QSSLSOCKET_DEBUG + qCDebug(lcSsl) << "Bytes available from socket:" << plainSocket->bytesAvailable(); + qCDebug(lcSsl) << "intermediateBuffer size:" << intermediateBuffer.size(); +#endif + + intermediateBuffer += plainSocket->read(16384); + if (intermediateBuffer.isEmpty()) + return true; // no data, will fail + + SecBuffer inputBuffers[2]; + inputBuffers[0] = createSecBuffer(intermediateBuffer, SECBUFFER_TOKEN); + inputBuffers[1] = createSecBuffer(nullptr, 0, SECBUFFER_EMPTY); + SecBufferDesc inputBufferDesc{ + SECBUFFER_VERSION, + ARRAYSIZE(inputBuffers), + inputBuffers + }; + + SecBuffer outBuffers[3]; + outBuffers[0] = createSecBuffer(nullptr, 0, SECBUFFER_TOKEN); + outBuffers[1] = createSecBuffer(nullptr, 0, SECBUFFER_ALERT); + outBuffers[2] = createSecBuffer(nullptr, 0, SECBUFFER_EMPTY); + auto freeBuffers = qScopeGuard([&outBuffers]() { + for (auto i = 0ull; i < ARRAYSIZE(outBuffers); i++) { + if (outBuffers[i].pvBuffer) + FreeContextBuffer(outBuffers[i].pvBuffer); + } + }); + SecBufferDesc outputBufferDesc{ + SECBUFFER_VERSION, + ARRAYSIZE(outBuffers), + outBuffers + }; + + ULONG contextReq = getContextRequirements(); + TimeStamp expiry; + auto status = InitializeSecurityContext(&credentialHandle, // phCredential + &contextHandle, // phContext + const_reinterpret_cast(targetName().utf16()), // pszTargetName + contextReq, // fContextReq + 0, // Reserved1 + 0, // TargetDataRep (unused) + &inputBufferDesc, // pInput + 0, // Reserved2 + nullptr, // phNewContext (we already have one) + &outputBufferDesc, // pOutput + &contextAttributes, // pfContextAttr + &expiry // ptsExpiry + ); + + if (inputBuffers[1].BufferType == SECBUFFER_EXTRA) { + // https://docs.microsoft.com/en-us/windows/desktop/secauthn/extra-buffers-returned-by-schannel + // inputBuffers[1].cbBuffer indicates the amount of bytes _NOT_ processed, the rest need to + // be stored. + intermediateBuffer = intermediateBuffer.right(int(inputBuffers[1].cbBuffer)); + } else { + // Clear the buffer if we weren't asked for more data + if (status != SEC_E_INCOMPLETE_MESSAGE) + intermediateBuffer.clear(); + } + switch (status) { + case SEC_E_OK: + // Need to transmit a final token in the handshake if 'cbBuffer' is non-zero. + if (!sendToken(outBuffers[0].pvBuffer, outBuffers[0].cbBuffer)) + return false; + schannelState = SchannelState::VerifyHandshake; + return true; + case SEC_I_CONTINUE_NEEDED: + if (!sendToken(outBuffers[0].pvBuffer, outBuffers[0].cbBuffer)) + return false; + // Must call InitializeSecurityContext again later (done through continueHandshake) + return true; + case SEC_I_INCOMPLETE_CREDENTIALS: + // Schannel takes care of picking certificate to send (other than the one we can specify), + // so if we get here then that means we don't have a certificate the server accepts. + setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError, + QSslSocket::tr("Server did not accept any certificate we could present.")); + return false; + case SEC_I_CONTEXT_EXPIRED: + // "The message sender has finished using the connection and has initiated a shutdown." + if (outBuffers[0].BufferType == SECBUFFER_TOKEN) { + if (!sendToken(outBuffers[0].pvBuffer, outBuffers[0].cbBuffer)) + return false; + } + if (!shutdown) { // we did not initiate this + setErrorAndEmit(QAbstractSocket::RemoteHostClosedError, + QSslSocket::tr("The TLS/SSL connection has been closed")); + } + return true; + case SEC_E_INCOMPLETE_MESSAGE: + // Simply incomplete, wait for more data + return true; + case SEC_E_ALGORITHM_MISMATCH: + setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError, + QSslSocket::tr("Algorithm mismatch")); + shutdown = true; // skip sending the "Shutdown" alert + return false; + } + + // Note: We can get here if the connection is using TLS 1.2 and the server certificate uses + // MD5, which is not allowed in Schannel. This causes an "invalid token" error during handshake. + // (If you came here investigating an error: md5 is insecure, update your certificate) + setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError, + QSslSocket::tr("Handshake failed: %1").arg(schannelErrorToString(status))); + return false; +} + +bool QSslSocketBackendPrivate::verifyHandshake() +{ + Q_Q(QSslSocket); + + const bool isClient = mode == QSslSocket::SslClientMode; +#define CHECK_STATUS(status) \ + if (status != SEC_E_OK) { \ + setErrorAndEmit(QAbstractSocket::SslInternalError, \ + QSslSocket::tr("Failed to query the TLS context: %1") \ + .arg(schannelErrorToString(status))); \ + return false; \ + } + + // Everything is set up, now make sure there's nothing wrong and query some attributes... + if (!matchesContextRequirements(contextAttributes, getContextRequirements(), + configuration.peerVerifyMode, isClient)) { + setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError, + QSslSocket::tr("Did not get the required attributes for the connection.")); + return false; + } + + // Get stream sizes (to know the max size of a message and the size of the header and trailer) + auto status = QueryContextAttributes(&contextHandle, + SECPKG_ATTR_STREAM_SIZES, + &streamSizes); + CHECK_STATUS(status); + + // Get session cipher info + status = QueryContextAttributes(&contextHandle, + SECPKG_ATTR_CONNECTION_INFO, + &connectionInfo); + CHECK_STATUS(status); +#undef CHECK_STATUS + + // Verify certificate + CERT_CONTEXT *certificateContext = nullptr; + auto freeCertificate = qScopeGuard([&certificateContext]() { + if (certificateContext) + CertFreeCertificateContext(certificateContext); + }); + status = QueryContextAttributes(&contextHandle, + SECPKG_ATTR_REMOTE_CERT_CONTEXT, + &certificateContext); + + // QueryPeer can (currently) not work in Schannel since Schannel itself doesn't have a way to + // ask for a certificate and then still be OK if it's not received. + // To work around this we don't request a certificate at all for QueryPeer. + // For servers AutoVerifyPeer is supposed to be treated the same as QueryPeer. + // This means that servers using Schannel will only request client certificate for "VerifyPeer". + if ((!isClient && configuration.peerVerifyMode == QSslSocket::PeerVerifyMode::VerifyPeer) + || (isClient && configuration.peerVerifyMode != QSslSocket::PeerVerifyMode::VerifyNone + && configuration.peerVerifyMode != QSslSocket::PeerVerifyMode::QueryPeer)) { + if (status != SEC_E_OK) { +#ifdef QSSLSOCKET_DEBUG + qCDebug(lcSsl) << "Couldn't retrieve peer certificate, status:" + << schannelErrorToString(status); +#endif + const QSslError error{ QSslError::NoPeerCertificate }; + sslErrors += error; + emit q->peerVerifyError(error); + if (q->state() != QAbstractSocket::ConnectedState) + return false; + } + } + + // verifyCertContext returns false if the user disconnected while it was checking errors. + if (certificateContext && sslErrors.isEmpty() && !verifyCertContext(certificateContext)) + return false; + + if (!checkSslErrors() || state != QAbstractSocket::ConnectedState) { +#ifdef QSSLSOCKET_DEBUG + qCDebug(lcSsl) << __func__ << "was unsuccessful. Paused:" << paused; +#endif + // If we're paused then checkSslErrors returned false, but it's not an error + return paused && state == QAbstractSocket::ConnectedState; + } + + schannelState = SchannelState::Done; + peerCertVerified = true; + return true; +} + +bool QSslSocketBackendPrivate::renegotiate() +{ + SecBuffer outBuffers[3]; + outBuffers[0] = createSecBuffer(nullptr, 0, SECBUFFER_TOKEN); + outBuffers[1] = createSecBuffer(nullptr, 0, SECBUFFER_ALERT); + outBuffers[2] = createSecBuffer(nullptr, 0, SECBUFFER_EMPTY); + auto freeBuffers = qScopeGuard([&outBuffers]() { + for (auto i = 0ull; i < ARRAYSIZE(outBuffers); i++) { + if (outBuffers[i].pvBuffer) + FreeContextBuffer(outBuffers[i].pvBuffer); + } + }); + SecBufferDesc outputBufferDesc{ + SECBUFFER_VERSION, + ARRAYSIZE(outBuffers), + outBuffers + }; + + ULONG contextReq = getContextRequirements(); + TimeStamp expiry; + SECURITY_STATUS status; + if (mode == QSslSocket::SslClientMode) { + status = InitializeSecurityContext(&credentialHandle, // phCredential + &contextHandle, // phContext + const_reinterpret_cast(targetName().utf16()), // pszTargetName + contextReq, // fContextReq + 0, // Reserved1 + 0, // TargetDataRep (unused) + nullptr, // pInput (nullptr for renegotiate) + 0, // Reserved2 + nullptr, // phNewContext (we already have one) + &outputBufferDesc, // pOutput + &contextAttributes, // pfContextAttr + &expiry // ptsExpiry + ); + } else { + status = AcceptSecurityContext( + &credentialHandle, // phCredential + &contextHandle, // phContext + nullptr, // pInput + contextReq, // fContextReq + 0, // TargetDataRep (unused) + nullptr, // phNewContext + &outputBufferDesc, // pOutput + &contextAttributes, // pfContextAttr, + &expiry // ptsTimeStamp + ); + } + if (status == SEC_I_CONTINUE_NEEDED) { + schannelState = SchannelState::PerformHandshake; + return sendToken(outBuffers[0].pvBuffer, outBuffers[0].cbBuffer); + } + setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError, + QSslSocket::tr("Renegotiation was unsuccessful: %1").arg(schannelErrorToString(status))); + return false; +} + +/*! + \internal + reset the state in preparation for reuse of socket +*/ +void QSslSocketBackendPrivate::reset() +{ + closeCertificateStores(); // certificate stores could've changed + deallocateContext(); + freeCredentialsHandle(); // in case we already had one (@future: session resumption requires re-use) + + connectionInfo = {}; + streamSizes = {}; + + CertFreeCertificateContext(localCertContext); + localCertContext = nullptr; + + contextAttributes = 0; + intermediateBuffer.clear(); + schannelState = SchannelState::InitializeHandshake; + + connectionEncrypted = false; + shutdown = false; + peerCertVerified = false; + renegotiating = false; +} + +void QSslSocketBackendPrivate::startClientEncryption() +{ + if (connectionEncrypted) + return; // let's not mess up the connection... + reset(); + continueHandshake(); +} + +void QSslSocketBackendPrivate::startServerEncryption() +{ + if (connectionEncrypted) + return; // let's not mess up the connection... + reset(); + continueHandshake(); +} + +void QSslSocketBackendPrivate::transmit() +{ + Q_Q(QSslSocket); + + // Can happen if called through QSslSocket::abort->QSslSocket::close->QSslSocket::flush->here + if (plainSocket->state() == QAbstractSocket::SocketState::UnconnectedState) + return; + + if (schannelState != SchannelState::Done) { + continueHandshake(); + return; + } + + if (connectionEncrypted) { // encrypt data in writeBuffer and write it to plainSocket + qint64 totalBytesWritten = 0; + qint64 writeBufferSize; + while ((writeBufferSize = writeBuffer.size()) > 0) { + QByteArray plaintext; + { + // Try to read 'cbMaximumMessage' bytes from buffer before encrypting. + int size = int(std::min(writeBufferSize, qint64(streamSizes.cbMaximumMessage))); + plaintext.resize(size); + // Use peek() here instead of read() so we don't lose data if encryption fails. + qint64 copied = writeBuffer.peek(plaintext.data(), size); + Q_ASSERT(copied == size); + } + QByteArray header(int(streamSizes.cbHeader), '\0'); + QByteArray trailer(int(streamSizes.cbTrailer), '\0'); + + SecBuffer inputBuffers[4]{ + // @future[0/1]: optimize by using one container for all fields... + createSecBuffer(header, SECBUFFER_STREAM_HEADER), + createSecBuffer(plaintext, SECBUFFER_DATA), + createSecBuffer(trailer, SECBUFFER_STREAM_TRAILER), + createSecBuffer(nullptr, 0, SECBUFFER_EMPTY) + }; + SecBufferDesc message{ + SECBUFFER_VERSION, + ARRAYSIZE(inputBuffers), + inputBuffers + }; + auto status = EncryptMessage(&contextHandle, 0, &message, 0); + if (status != SEC_E_OK) { + setErrorAndEmit(QAbstractSocket::SslInternalError, + QSslSocket::tr("Schannel failed to encrypt data: %1") + .arg(schannelErrorToString(status))); + return; + } + // Data was encrypted successfully, so we free() what we peek()ed earlier + writeBuffer.free(plaintext.length()); + + // trailer has been observed to change size, so resize them all (when needed) to be safe + header = header.left(int(inputBuffers[0].cbBuffer)); + plaintext = plaintext.left(int(inputBuffers[1].cbBuffer)); + trailer = trailer.left(int(inputBuffers[2].cbBuffer)); + const qint64 bytesWritten = plainSocket->write(header // @future[1/1]: ...because they need to be merged + + plaintext + + trailer); +#ifdef QSSLSOCKET_DEBUG + qCDebug(lcSsl) << "Wrote" << bytesWritten << "of total" + << header.length() + plaintext.length() + trailer.length() << "bytes"; +#endif + if (bytesWritten >= 0) { + totalBytesWritten += bytesWritten; + } else { + setErrorAndEmit(plainSocket->error(), plainSocket->errorString()); + return; + } + } + + if (totalBytesWritten > 0) { + // Don't emit bytesWritten() recursively. + if (!emittedBytesWritten) { + emittedBytesWritten = true; + emit q->bytesWritten(totalBytesWritten); + emittedBytesWritten = false; + } + emit q->channelBytesWritten(0, totalBytesWritten); + } + } + + if (connectionEncrypted) { // Decrypt data from remote + int totalRead = 0; + bool hadIncompleteData = false; + while (!readBufferMaxSize || buffer.size() < readBufferMaxSize) { + QByteArray ciphertext; + if (intermediateBuffer.length()) { +#ifdef QSSLSOCKET_DEBUG + qCDebug(lcSsl) << "Restoring data from intermediateBuffer:" + << intermediateBuffer.length() << "bytes"; +#endif + ciphertext.swap(intermediateBuffer); + } + int initialLength = ciphertext.length(); + ciphertext += plainSocket->read(16384); +#ifdef QSSLSOCKET_DEBUG + qCDebug(lcSsl) << "Read" << ciphertext.length() - initialLength + << "encrypted bytes from the socket"; +#endif + if (ciphertext.length() == 0 || (hadIncompleteData && initialLength == ciphertext.length())) { +#ifdef QSSLSOCKET_DEBUG + qCDebug(lcSsl) << (hadIncompleteData ? "No new data received, leaving loop!" + : "Nothing to decrypt, leaving loop!"); +#endif + if (ciphertext.length()) // We have data, it came from intermediateBuffer, swap back + intermediateBuffer.swap(ciphertext); + break; + } + hadIncompleteData = false; +#ifdef QSSLSOCKET_DEBUG + qCDebug(lcSsl) << "Total amount of bytes to decrypt:" << ciphertext.length(); +#endif + + SecBuffer dataBuffer[4]{ + createSecBuffer(ciphertext, SECBUFFER_DATA), + createSecBuffer(nullptr, 0, SECBUFFER_EMPTY), + createSecBuffer(nullptr, 0, SECBUFFER_EMPTY), + createSecBuffer(nullptr, 0, SECBUFFER_EMPTY) + }; + SecBufferDesc message{ + SECBUFFER_VERSION, + ARRAYSIZE(dataBuffer), + dataBuffer + }; + auto status = DecryptMessage(&contextHandle, &message, 0, nullptr); + if (status == SEC_E_OK || status == SEC_I_RENEGOTIATE || status == SEC_I_CONTEXT_EXPIRED) { + // There can still be 0 output even if it succeeds, this is fine + if (dataBuffer[1].cbBuffer > 0) { + // It is always decrypted in-place. + // But [0] is the STREAM_HEADER, [1] is the DATA and [2] is the STREAM_TRAILER. + // The pointers in all of those still point into the 'ciphertext' byte array. + buffer.append(static_cast(dataBuffer[1].pvBuffer), + dataBuffer[1].cbBuffer); + totalRead += dataBuffer[1].cbBuffer; +#ifdef QSSLSOCKET_DEBUG + qCDebug(lcSsl) << "Decrypted" << dataBuffer[1].cbBuffer + << "bytes. New read buffer size:" << buffer.size(); +#endif + } + if (dataBuffer[3].BufferType == SECBUFFER_EXTRA) { + // https://docs.microsoft.com/en-us/windows/desktop/secauthn/extra-buffers-returned-by-schannel + // dataBuffer[3].cbBuffer indicates the amount of bytes _NOT_ processed, + // the rest need to be stored. +#ifdef QSSLSOCKET_DEBUG + qCDebug(lcSsl) << "We've got excess data, moving it to the intermediate buffer:" + << dataBuffer[3].cbBuffer << "bytes"; +#endif + intermediateBuffer = ciphertext.right(int(dataBuffer[3].cbBuffer)); + } + } else if (status == SEC_E_INCOMPLETE_MESSAGE) { + // Need more data before we can decrypt.. to the buffer it goes! +#ifdef QSSLSOCKET_DEBUG + qCDebug(lcSsl, "We didn't have enough data to decrypt anything, will try again!"); +#endif + Q_ASSERT(intermediateBuffer.isEmpty()); + intermediateBuffer.swap(ciphertext); + // We try again, but if we don't get any more data then we leave + hadIncompleteData = true; + } else if (status == SEC_E_INVALID_HANDLE) { + // I don't think this should happen, if it does we're done... + qCWarning(lcSsl, "The internal SSPI handle is invalid!"); + Q_UNREACHABLE(); + } else if (status == SEC_E_INVALID_TOKEN) { + qCWarning(lcSsl, "Got SEC_E_INVALID_TOKEN!"); + Q_UNREACHABLE(); // Happened once due to a bug, but shouldn't generally happen(?) + } else if (status == SEC_E_MESSAGE_ALTERED) { + // The message has been altered, disconnect now. + shutdown = true; // skips sending the shutdown alert + disconnectFromHost(); + setErrorAndEmit(QAbstractSocket::SslInternalError, + schannelErrorToString(status)); + break; + } else if (status == SEC_E_OUT_OF_SEQUENCE) { + // @todo: I don't know if this one is actually "fatal".. + // This path might never be hit as it seems this is for connection-oriented connections, + // while SEC_E_MESSAGE_ALTERED is for stream-oriented ones (what we use). + shutdown = true; // skips sending the shutdown alert + disconnectFromHost(); + setErrorAndEmit(QAbstractSocket::SslInternalError, + schannelErrorToString(status)); + break; + } else if (status == SEC_I_CONTEXT_EXPIRED) { + // 'remote' has initiated a shutdown + disconnectFromHost(); + setErrorAndEmit(QAbstractSocket::RemoteHostClosedError, + schannelErrorToString(status)); + break; + } else if (status == SEC_I_RENEGOTIATE) { + // 'remote' wants to renegotiate +#ifdef QSSLSOCKET_DEBUG + qCDebug(lcSsl, "The peer wants to renegotiate."); +#endif + schannelState = SchannelState::Renegotiate; + renegotiating = true; + // We need to call 'continueHandshake' or else there's no guarantee it ever gets called + continueHandshake(); + break; + } + } + + if (totalRead) { + if (readyReadEmittedPointer) + *readyReadEmittedPointer = true; + emit q->readyRead(); + emit q->channelReadyRead(0); + } + } +} + +void QSslSocketBackendPrivate::sendShutdown() +{ + const bool isClient = mode == QSslSocket::SslClientMode; + DWORD shutdownToken = SCHANNEL_SHUTDOWN; + SecBuffer buffer = createSecBuffer(&shutdownToken, sizeof(SCHANNEL_SHUTDOWN), SECBUFFER_TOKEN); + SecBufferDesc token{ + SECBUFFER_VERSION, + 1, + &buffer + }; + auto status = ApplyControlToken(&contextHandle, &token); + + if (status != SEC_E_OK) { +#ifdef QSSLSOCKET_DEBUG + qCDebug(lcSsl) << "Failed to apply shutdown control token:" << schannelErrorToString(status); +#endif + return; + } + + SecBuffer outBuffers[3]; + outBuffers[0] = createSecBuffer(nullptr, 0, SECBUFFER_TOKEN); + outBuffers[1] = createSecBuffer(nullptr, 0, SECBUFFER_ALERT); + outBuffers[2] = createSecBuffer(nullptr, 0, SECBUFFER_EMPTY); + auto freeBuffers = qScopeGuard([&outBuffers]() { + for (auto i = 0ull; i < ARRAYSIZE(outBuffers); i++) { + if (outBuffers[i].pvBuffer) + FreeContextBuffer(outBuffers[i].pvBuffer); + } + }); + SecBufferDesc outputBufferDesc{ + SECBUFFER_VERSION, + ARRAYSIZE(outBuffers), + outBuffers + }; + + ULONG contextReq = getContextRequirements(); + TimeStamp expiry; + if (isClient) { + status = InitializeSecurityContext(&credentialHandle, // phCredential + &contextHandle, // phContext + const_reinterpret_cast(targetName().utf16()), // pszTargetName + contextReq, // fContextReq + 0, // Reserved1 + 0, // TargetDataRep (unused) + nullptr, // pInput + 0, // Reserved2 + nullptr, // phNewContext (we already have one) + &outputBufferDesc, // pOutput + &contextAttributes, // pfContextAttr + &expiry // ptsExpiry + ); + } else { + status = AcceptSecurityContext( + &credentialHandle, // phCredential + &contextHandle, // phContext + nullptr, // pInput + contextReq, // fContextReq + 0, // TargetDataRep (unused) + nullptr, // phNewContext + &outputBufferDesc, // pOutput + &contextAttributes, // pfContextAttr, + &expiry // ptsTimeStamp + ); + } + if (status == SEC_E_OK || status == SEC_I_CONTEXT_EXPIRED) { + if (!sendToken(outBuffers[0].pvBuffer, outBuffers[0].cbBuffer, false)) { + // We failed to send the shutdown message, but it's not that important since we're + // shutting down anyway. + return; + } + } else { +#ifdef QSSLSOCKET_DEBUG + qCDebug(lcSsl) << "Failed to initialize shutdown:" << schannelErrorToString(status); +#endif + } +} + +void QSslSocketBackendPrivate::disconnectFromHost() +{ + if (SecIsValidHandle(&contextHandle)) { + if (!shutdown) { + shutdown = true; + if (plainSocket->state() != QAbstractSocket::UnconnectedState) { + if (connectionEncrypted) { + // Read as much as possible because this is likely our last chance + qint64 tempMax = readBufferMaxSize; + readBufferMaxSize = 0; + transmit(); + readBufferMaxSize = tempMax; + sendShutdown(); + } + } + } + } + if (plainSocket->state() != QAbstractSocket::UnconnectedState) + plainSocket->disconnectFromHost(); +} + +void QSslSocketBackendPrivate::disconnected() +{ + shutdown = true; + connectionEncrypted = false; + deallocateContext(); + freeCredentialsHandle(); +} + +QSslCipher QSslSocketBackendPrivate::sessionCipher() const +{ + if (!connectionEncrypted) + return QSslCipher(); + return QSslCipher(QStringLiteral("Schannel"), sessionProtocol()); +} + +QSsl::SslProtocol QSslSocketBackendPrivate::sessionProtocol() const +{ + if (!connectionEncrypted) + return QSsl::SslProtocol::UnknownProtocol; + return toQtSslProtocol(connectionInfo.dwProtocol); +} + +void QSslSocketBackendPrivate::continueHandshake() +{ + Q_Q(QSslSocket); + const bool isServer = mode == QSslSocket::SslServerMode; + switch (schannelState) { + case SchannelState::InitializeHandshake: + if (!SecIsValidHandle(&credentialHandle) && !acquireCredentialsHandle()) { + disconnectFromHost(); + return; + } + if (!SecIsValidHandle(&credentialHandle)) // Needed to support tst_QSslSocket::setEmptyKey + return; + if (!SecIsValidHandle(&contextHandle) && !(isServer ? acceptContext() : createContext())) { + disconnectFromHost(); + return; + } + if (schannelState != SchannelState::PerformHandshake) + break; + Q_FALLTHROUGH(); + case SchannelState::PerformHandshake: + if (!performHandshake()) { + disconnectFromHost(); + return; + } + if (schannelState != SchannelState::VerifyHandshake) + break; + Q_FALLTHROUGH(); + case SchannelState::VerifyHandshake: + // if we're in shutdown or renegotiating then we might not need to verify + // (since we already did) + if (!peerCertVerified && !verifyHandshake()) { + shutdown = true; // Skip sending shutdown alert + q->abort(); // We don't want to send buffered data + disconnectFromHost(); + return; + } + if (schannelState != SchannelState::Done) + break; + Q_FALLTHROUGH(); + case SchannelState::Done: + // connectionEncrypted is already true if we come here from a renegotiation + if (!connectionEncrypted) { + connectionEncrypted = true; // all is done + emit q->encrypted(); + } + renegotiating = false; + if (pendingClose) { + pendingClose = false; + disconnectFromHost(); + } else { + transmit(); + } + break; + case SchannelState::Renegotiate: + if (!renegotiate()) { + disconnectFromHost(); + return; + } + break; + } +} + +QList QSslSocketBackendPrivate::defaultCiphers() +{ + QList ciphers; + // @temp (I hope), stolen from qsslsocket_winrt.cpp + const QString protocolStrings[] = { QStringLiteral("TLSv1"), QStringLiteral("TLSv1.1"), + QStringLiteral("TLSv1.2"), QStringLiteral("TLSv1.3") }; + const QSsl::SslProtocol protocols[] = { QSsl::TlsV1_0, QSsl::TlsV1_1, + QSsl::TlsV1_2, QSsl::TlsV1_3 }; + const int size = ARRAYSIZE(protocols); + Q_STATIC_ASSERT(size == ARRAYSIZE(protocolStrings)); + ciphers.reserve(size); + for (int i = 0; i < size; ++i) { + QSslCipher cipher; + cipher.d->isNull = false; + cipher.d->name = QStringLiteral("Schannel"); + cipher.d->protocol = protocols[i]; + cipher.d->protocolString = protocolStrings[i]; + ciphers.append(cipher); + } + + return ciphers; +} + +QList QSslSocketBackendPrivate::verify(const QList &certificateChain, + const QString &hostName) +{ + Q_UNUSED(certificateChain); + Q_UNUSED(hostName); + + Q_UNIMPLEMENTED(); + return {}; // @future implement(?) +} + +bool QSslSocketBackendPrivate::importPkcs12(QIODevice *device, QSslKey *key, QSslCertificate *cert, + QList *caCertificates, + const QByteArray &passPhrase) +{ + Q_UNUSED(device); + Q_UNUSED(key); + Q_UNUSED(cert); + Q_UNUSED(caCertificates); + Q_UNUSED(passPhrase); + // @future: can load into its own certificate store (encountered problems extracting key). + Q_UNIMPLEMENTED(); + return false; +} + +/* + Copied from qsslsocket_mac.cpp, which was copied from qsslsocket_openssl.cpp +*/ +bool QSslSocketBackendPrivate::checkSslErrors() +{ + if (sslErrors.isEmpty()) + return true; + Q_Q(QSslSocket); + + emit q->sslErrors(sslErrors); + + const bool doVerifyPeer = configuration.peerVerifyMode == QSslSocket::VerifyPeer + || (configuration.peerVerifyMode == QSslSocket::AutoVerifyPeer + && mode == QSslSocket::SslClientMode); + const bool doEmitSslError = !verifyErrorsHaveBeenIgnored(); + // check whether we need to emit an SSL handshake error + if (doVerifyPeer && doEmitSslError) { + if (q->pauseMode() & QAbstractSocket::PauseOnSslErrors) { + pauseSocketNotifiers(q); + paused = true; + } else { + setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError, + sslErrors.constFirst().errorString()); + plainSocket->disconnectFromHost(); + } + return false; + } + + return true; +} + +void QSslSocketBackendPrivate::initializeCertificateStores() +{ + //// helper function which turns a chain into a certificate store + auto createStoreFromCertificateChain = [](const QList certChain, const QSslKey &privateKey) { + const wchar_t *passphrase = L""; + // Need to embed the private key in the certificate + QByteArray pkcs12 = _q_makePkcs12(certChain, + privateKey, + QString::fromWCharArray(passphrase, 0)); + CRYPT_DATA_BLOB pfxBlob; + pfxBlob.cbData = DWORD(pkcs12.length()); + pfxBlob.pbData = reinterpret_cast(pkcs12.data()); + return QHCertStorePointer(PFXImportCertStore(&pfxBlob, passphrase, 0)); + }; + + if (!configuration.localCertificateChain.isEmpty()) { + if (configuration.privateKey.isNull()) { + setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError, + QSslSocket::tr("Cannot provide a certificate with no key")); + return; + } + if (localCertificateStore == nullptr) { + localCertificateStore = createStoreFromCertificateChain(configuration.localCertificateChain, + configuration.privateKey); + if (localCertificateStore == nullptr) + qCWarning(lcSsl, "Failed to load certificate chain!"); + } + } + + if (!configuration.caCertificates.isEmpty() && !caCertificateStore) { + caCertificateStore = createStoreFromCertificateChain(configuration.caCertificates, + {}); // No private key for the CA certs + } +} + +bool QSslSocketBackendPrivate::verifyCertContext(CERT_CONTEXT *certContext) +{ + Q_ASSERT(certContext); + Q_Q(QSslSocket); + + const bool isClient = mode == QSslSocket::SslClientMode; + + // Create a collection of stores so we can pass in multiple stores as additional locations to + // search for the certificate chain + auto tempCertCollection = QHCertStorePointer(CertOpenStore(CERT_STORE_PROV_COLLECTION, + X509_ASN_ENCODING, + 0, + CERT_STORE_CREATE_NEW_FLAG, + nullptr)); + if (!tempCertCollection) { +#ifdef QSSLSOCKET_DEBUG + qCWarning(lcSsl, "Failed to create certificate store collection!"); +#endif + return false; + } + + if (rootCertOnDemandLoadingAllowed()) { + // @future(maybe): following the OpenSSL backend these certificates should be added into + // the Ca list, not just included during verification. + // That being said, it's not trivial to add the root certificates (if and only if they + // came from the system root store). And I don't see this mentioned in our documentation. + auto rootStore = QHCertStorePointer(CertOpenSystemStore(0, L"ROOT")); + if (!rootStore) { +#ifdef QSSLSOCKET_DEBUG + qCWarning(lcSsl, "Failed to open the system root CA certificate store!"); +#endif + return false; + } else if (!CertAddStoreToCollection(tempCertCollection.get(), rootStore.get(), 0, 1)) { +#ifdef QSSLSOCKET_DEBUG + qCWarning(lcSsl, "Failed to add the system root CA certificate store to the certificate store collection!"); +#endif + return false; + } + } + if (caCertificateStore) { + if (!CertAddStoreToCollection(tempCertCollection.get(), caCertificateStore.get(), 0, 1)) { +#ifdef QSSLSOCKET_DEBUG + qCWarning(lcSsl, "Failed to add the user's CA certificate store to the certificate store collection!"); +#endif + return false; + } + } + + if (!CertAddStoreToCollection(tempCertCollection.get(), certContext->hCertStore, 0, 0)) { +#ifdef QSSLSOCKET_DEBUG + qCWarning(lcSsl, "Failed to add certificate's origin store to the certificate store collection!"); +#endif + return false; + } + + CERT_CHAIN_PARA parameters; + ZeroMemory(¶meters, sizeof(parameters)); + parameters.cbSize = sizeof(CERT_CHAIN_PARA); + parameters.RequestedUsage.dwType = USAGE_MATCH_TYPE_AND; + parameters.RequestedUsage.Usage.cUsageIdentifier = 1; + LPSTR oid = LPSTR(isClient ? szOID_PKIX_KP_SERVER_AUTH + : szOID_PKIX_KP_CLIENT_AUTH); + parameters.RequestedUsage.Usage.rgpszUsageIdentifier = &oid; + + configuration.peerCertificate.clear(); + configuration.peerCertificateChain.clear(); + const CERT_CHAIN_CONTEXT *chainContext = nullptr; + auto freeCertChain = qScopeGuard([&chainContext]() { + if (chainContext) + CertFreeCertificateChain(chainContext); + }); + BOOL status = CertGetCertificateChain(nullptr, // hChainEngine, default + certContext, // pCertContext + nullptr, // pTime, 'now' + tempCertCollection.get(), // hAdditionalStore, additional cert store + ¶meters, // pChainPara + CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT, // dwFlags + nullptr, // reserved + &chainContext // ppChainContext + ); + if (status == FALSE || !chainContext || chainContext->cChain == 0) { + QSslError error(QSslError::UnableToVerifyFirstCertificate); + sslErrors += error; + emit q->peerVerifyError(error); + return q->state() == QAbstractSocket::ConnectedState; + } + + // Helper-function to get a QSslCertificate given a CERT_CHAIN_ELEMENT + static auto getCertificateFromChainElement = [](CERT_CHAIN_ELEMENT *element) { + if (!element) + return QSslCertificate(); + + const CERT_CONTEXT *certContext = element->pCertContext; + return QSslCertificatePrivate::QSslCertificate_from_CERT_CONTEXT(certContext); + }; + + // Pick a chain to use as the certificate chain, if multiple are available: + // According to https://docs.microsoft.com/en-gb/windows/desktop/api/wincrypt/ns-wincrypt-_cert_chain_context + // this seems to be the best way to get a trusted chain. + CERT_SIMPLE_CHAIN *chain = chainContext->rgpChain[chainContext->cChain - 1]; + + if (chain->TrustStatus.dwErrorStatus & CERT_TRUST_IS_PARTIAL_CHAIN) { + auto error = QSslError(QSslError::SslError::UnableToGetIssuerCertificate, + getCertificateFromChainElement(chain->rgpElement[chain->cElement - 1])); + sslErrors += error; + emit q->peerVerifyError(error); + if (q->state() != QAbstractSocket::ConnectedState) + return false; + } + if (chain->TrustStatus.dwErrorStatus & CERT_TRUST_INVALID_BASIC_CONSTRAINTS) { + // @Note: This is actually one of two errors: + // "either the certificate cannot be used to issue other certificates, or the chain path length has been exceeded." + // But here we are checking the chain's status, so we assume the "issuing" error cannot occur here. + auto error = QSslError(QSslError::PathLengthExceeded); + sslErrors += error; + emit q->peerVerifyError(error); + if (q->state() != QAbstractSocket::ConnectedState) + return false; + } + static const DWORD leftoverCertChainErrorMask = CERT_TRUST_IS_CYCLIC | CERT_TRUST_INVALID_EXTENSION + | CERT_TRUST_INVALID_POLICY_CONSTRAINTS | CERT_TRUST_INVALID_NAME_CONSTRAINTS + | CERT_TRUST_CTL_IS_NOT_TIME_VALID | CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID + | CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE; + if (chain->TrustStatus.dwErrorStatus & leftoverCertChainErrorMask) { + auto error = QSslError(QSslError::SslError::UnspecifiedError); + sslErrors += error; + emit q->peerVerifyError(error); + if (q->state() != QAbstractSocket::ConnectedState) + return false; + } + + DWORD verifyDepth = chain->cElement; + if (configuration.peerVerifyDepth > 0 && DWORD(configuration.peerVerifyDepth) < verifyDepth) + verifyDepth = DWORD(configuration.peerVerifyDepth); + + for (DWORD i = 0; i < verifyDepth; i++) { + CERT_CHAIN_ELEMENT *element = chain->rgpElement[i]; + QSslCertificate certificate = getCertificateFromChainElement(element); + const QList extensions = certificate.extensions(); + +#ifdef QSSLSOCKET_DEBUG + qCDebug(lcSsl) << "issuer:" << certificate.issuerDisplayName() + << "\nsubject:" << certificate.subjectDisplayName() + << "\nQSslCertificate info:" << certificate + << "\nextended error info:" << element->pwszExtendedErrorInfo + << "\nerror status:" << element->TrustStatus.dwErrorStatus; +#endif + + configuration.peerCertificateChain.append(certificate); + + if (certificate.isBlacklisted()) { + const auto error = QSslError(QSslError::CertificateBlacklisted, certificate); + sslErrors += error; + emit q->peerVerifyError(error); + if (q->state() != QAbstractSocket::ConnectedState) + return false; + } + + LONG result = CertVerifyTimeValidity(nullptr /*== now */, element->pCertContext->pCertInfo); + if (result != 0) { + auto error = QSslError(result == -1 ? QSslError::CertificateNotYetValid + : QSslError::CertificateExpired, + certificate); + sslErrors += error; + emit q->peerVerifyError(error); + if (q->state() != QAbstractSocket::ConnectedState) + return false; + } + + //// Errors + if (element->TrustStatus.dwErrorStatus & CERT_TRUST_IS_NOT_TIME_VALID) { + // handled right above + Q_ASSERT(!sslErrors.isEmpty()); + } + if (element->TrustStatus.dwErrorStatus & CERT_TRUST_IS_REVOKED) { + auto error = QSslError(QSslError::CertificateRevoked, certificate); + sslErrors += error; + emit q->peerVerifyError(error); + if (q->state() != QAbstractSocket::ConnectedState) + return false; + } + if (element->TrustStatus.dwErrorStatus & CERT_TRUST_IS_NOT_SIGNATURE_VALID) { + auto error = QSslError(QSslError::CertificateSignatureFailed, certificate); + sslErrors += error; + emit q->peerVerifyError(error); + if (q->state() != QAbstractSocket::ConnectedState) + return false; + } + + // While netscape shouldn't be relevant now it defined an extension which is + // still in use. Schannel does not check this automatically, so we do it here. + // It is used to differentiate between client and server certificates. + if (netscapeWrongCertType(extensions, isClient)) + element->TrustStatus.dwErrorStatus |= CERT_TRUST_IS_NOT_VALID_FOR_USAGE; + + if (element->TrustStatus.dwErrorStatus & CERT_TRUST_IS_NOT_VALID_FOR_USAGE) { + auto error = QSslError(QSslError::InvalidPurpose, certificate); + sslErrors += error; + emit q->peerVerifyError(error); + if (q->state() != QAbstractSocket::ConnectedState) + return false; + } + if (element->TrustStatus.dwErrorStatus & CERT_TRUST_IS_UNTRUSTED_ROOT) { + // Override this error if we have the certificate inside our trusted CAs list. + const bool isTrustedRoot = configuration.caCertificates.contains(certificate); + if (!isTrustedRoot) { + auto error = QSslError(QSslError::CertificateUntrusted, certificate); + sslErrors += error; + emit q->peerVerifyError(error); + if (q->state() != QAbstractSocket::ConnectedState) + return false; + } + } + static const DWORD certRevocationCheckUnavailableError = CERT_TRUST_IS_OFFLINE_REVOCATION + | CERT_TRUST_REVOCATION_STATUS_UNKNOWN; + if (element->TrustStatus.dwErrorStatus & certRevocationCheckUnavailableError) { + // @future(maybe): Do something with this + } + + // Dumping ground of errors that don't fit our specific errors + static const DWORD leftoverCertErrorMask = CERT_TRUST_IS_CYCLIC + | CERT_TRUST_INVALID_EXTENSION | CERT_TRUST_INVALID_NAME_CONSTRAINTS + | CERT_TRUST_INVALID_POLICY_CONSTRAINTS + | CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT + | CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT + | CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT + | CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT + | CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT; + if (element->TrustStatus.dwErrorStatus & leftoverCertErrorMask) { + auto error = QSslError(QSslError::UnspecifiedError, certificate); + sslErrors += error; + emit q->peerVerifyError(error); + if (q->state() != QAbstractSocket::ConnectedState) + return false; + } + if (element->TrustStatus.dwErrorStatus & CERT_TRUST_INVALID_BASIC_CONSTRAINTS) { + auto it = std::find_if(extensions.cbegin(), extensions.cend(), + [](const QSslCertificateExtension &extension) { + return extension.name() == QLatin1String("basicConstraints"); + }); + if (it != extensions.cend()) { + // @Note: This is actually one of two errors: + // "either the certificate cannot be used to issue other certificates, + // or the chain path length has been exceeded." + QVariantMap basicConstraints = it->value().toMap(); + QSslError error; + if (i > 0 && !basicConstraints.value(QLatin1String("ca"), false).toBool()) + error = QSslError(QSslError::InvalidPurpose, certificate); + else + error = QSslError(QSslError::PathLengthExceeded, certificate); + sslErrors += error; + emit q->peerVerifyError(error); + if (q->state() != QAbstractSocket::ConnectedState) + return false; + } + } + if (element->TrustStatus.dwErrorStatus & CERT_TRUST_IS_EXPLICIT_DISTRUST) { + auto error = QSslError(QSslError::CertificateBlacklisted, certificate); + sslErrors += error; + emit q->peerVerifyError(error); + if (q->state() != QAbstractSocket::ConnectedState) + return false; + } + + if (element->TrustStatus.dwInfoStatus & CERT_TRUST_IS_SELF_SIGNED) { + // If it's self-signed *and* a CA then we can assume it's a root CA certificate + // and we can ignore the "self-signed" note: + // We check the basicConstraints certificate extension when possible, but this didn't + // exist for version 1, so we can only guess in that case + const bool isRootCertificateAuthority = isCertificateAuthority(extensions) + || certificate.version() == "1"; + + // Root certificate tends to be signed by themselves, so ignore self-signed status. + if (!isRootCertificateAuthority) { + auto error = QSslError(QSslError::SelfSignedCertificate, certificate); + sslErrors += error; + emit q->peerVerifyError(error); + if (q->state() != QAbstractSocket::ConnectedState) + return false; + } + } + } + + if (!configuration.peerCertificateChain.isEmpty()) + configuration.peerCertificate = configuration.peerCertificateChain.first(); + + // @Note: Somewhat copied from qsslsocket_mac.cpp + const bool doVerifyPeer = configuration.peerVerifyMode == QSslSocket::VerifyPeer + || (configuration.peerVerifyMode == QSslSocket::AutoVerifyPeer + && mode == QSslSocket::SslClientMode); + // Check the peer certificate itself. First try the subject's common name + // (CN) as a wildcard, then try all alternate subject name DNS entries the + // same way. + if (!configuration.peerCertificate.isNull()) { + // but only if we're a client connecting to a server + // if we're the server, don't check CN + if (mode == QSslSocket::SslClientMode) { + const QString peerName(verificationPeerName.isEmpty() ? q->peerName() : verificationPeerName); + if (!isMatchingHostname(configuration.peerCertificate, peerName)) { + // No matches in common names or alternate names. + const QSslError error(QSslError::HostNameMismatch, configuration.peerCertificate); + sslErrors += error; + emit q->peerVerifyError(error); + if (q->state() != QAbstractSocket::ConnectedState) + return false; + } + } + } else if (doVerifyPeer) { + // No peer certificate presented. Report as error if the socket + // expected one. + const QSslError error(QSslError::NoPeerCertificate); + sslErrors += error; + emit q->peerVerifyError(error); + if (q->state() != QAbstractSocket::ConnectedState) + return false; + } + + return true; +} + +bool QSslSocketBackendPrivate::rootCertOnDemandLoadingAllowed() +{ + return allowRootCertOnDemandLoading && s_loadRootCertsOnDemand; +} + +QT_END_NAMESPACE diff --git a/src/network/ssl/qsslsocket_schannel_p.h b/src/network/ssl/qsslsocket_schannel_p.h new file mode 100644 index 0000000000..9879e2fc60 --- /dev/null +++ b/src/network/ssl/qsslsocket_schannel_p.h @@ -0,0 +1,155 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSSLSOCKET_SCHANNEL_P_H +#define QSSLSOCKET_SCHANNEL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_REQUIRE_CONFIG(schannel); + +#include + +#include "qsslsocket_p.h" + +#define SECURITY_WIN32 +#include +#include +#undef SECURITY_WIN32 + +#include + +QT_BEGIN_NAMESPACE + +struct QHCertStoreDeleter { + void operator()(HCERTSTORE store) + { + CertCloseStore(store, 0); + } +}; +typedef std::unique_ptr QHCertStorePointer; + +class QSslSocketBackendPrivate final : public QSslSocketPrivate +{ + Q_DISABLE_COPY_MOVE(QSslSocketBackendPrivate) + Q_DECLARE_PUBLIC(QSslSocket) +public: + QSslSocketBackendPrivate(); + ~QSslSocketBackendPrivate(); + + // Platform specific functions + void startClientEncryption() override; + void startServerEncryption() override; + void transmit() override; + void disconnectFromHost() override; + void disconnected() override; + QSslCipher sessionCipher() const override; + QSsl::SslProtocol sessionProtocol() const override; + void continueHandshake() override; + + static QList defaultCiphers(); + static QList verify(const QList &certificateChain, + const QString &hostName); + static bool importPkcs12(QIODevice *device, QSslKey *key, QSslCertificate *cert, + QList *caCertificates, const QByteArray &passPhrase); + +private: + enum class SchannelState { + InitializeHandshake, // create and transmit context (client)/accept context (server) + PerformHandshake, // get token back, process it + VerifyHandshake, // Verify that things are OK + Done, // Connection encrypted! + Renegotiate // Renegotiating! + } schannelState = SchannelState::InitializeHandshake; + + void reset(); + bool acquireCredentialsHandle(); + ULONG getContextRequirements(); + bool createContext(); // for clients + bool acceptContext(); // for server + bool performHandshake(); + bool verifyHandshake(); + bool renegotiate(); + + bool sendToken(void *token, unsigned long tokenLength, bool emitError = true); + QString targetName() const; + + bool checkSslErrors(); + void deallocateContext(); + void freeCredentialsHandle(); + void closeCertificateStores(); + void sendShutdown(); + + void initializeCertificateStores(); + bool verifyCertContext(CERT_CONTEXT *certContext); + + bool rootCertOnDemandLoadingAllowed(); + + SecPkgContext_ConnectionInfo connectionInfo = {}; + SecPkgContext_StreamSizes streamSizes = {}; + + CredHandle credentialHandle; // Initialized in ctor + CtxtHandle contextHandle; // Initialized in ctor + + QByteArray intermediateBuffer; // data which is left-over or incomplete + + QHCertStorePointer localCertificateStore = nullptr; + QHCertStorePointer peerCertificateStore = nullptr; + QHCertStorePointer caCertificateStore = nullptr; + + const CERT_CONTEXT *localCertContext = nullptr; + + ULONG contextAttributes = 0; + + bool renegotiating = false; + bool peerCertVerified = false; +}; + +QT_END_NAMESPACE + +#endif // QSSLSOCKET_SCHANNEL_P_H diff --git a/src/network/ssl/ssl.pri b/src/network/ssl/ssl.pri index b5603c1258..0bb460b797 100644 --- a/src/network/ssl/ssl.pri +++ b/src/network/ssl/ssl.pri @@ -49,6 +49,19 @@ qtConfig(ssl) { ssl/qsslellipticcurve_dummy.cpp } + qtConfig(schannel) { + HEADERS += ssl/qsslsocket_schannel_p.h + SOURCES += ssl/qsslsocket_schannel.cpp \ + ssl/qsslcertificate_schannel.cpp \ + ssl/qsslkey_schannel.cpp \ + ssl/qsslkey_qt.cpp \ + ssl/qssldiffiehellmanparameters_dummy.cpp \ + ssl/qsslellipticcurve_dummy.cpp \ + ssl/qsslsocket_qt.cpp + + LIBS_PRIVATE += "-lSecur32" "-lCrypt32" "-lbcrypt" "-lncrypt" + } + qtConfig(securetransport) { HEADERS += ssl/qsslsocket_mac_p.h SOURCES += ssl/qssldiffiehellmanparameters_dummy.cpp \ diff --git a/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp b/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp index 7f8580ddd6..88be13f41d 100644 --- a/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp +++ b/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp @@ -814,7 +814,7 @@ void tst_QSslCertificate::task256066toPem() void tst_QSslCertificate::nulInCN() { -#if defined(QT_SECURETRANSPORT) || defined(Q_OS_WINRT) +#if defined(QT_SECURETRANSPORT) || defined(Q_OS_WINRT) || QT_CONFIG(schannel) QSKIP("Generic QSslCertificatePrivate fails this test"); #endif QList certList = @@ -833,7 +833,7 @@ void tst_QSslCertificate::nulInCN() void tst_QSslCertificate::nulInSan() { -#if defined(QT_SECURETRANSPORT) || defined(Q_OS_WINRT) +#if defined(QT_SECURETRANSPORT) || defined(Q_OS_WINRT) || QT_CONFIG(schannel) QSKIP("Generic QSslCertificatePrivate fails this test"); #endif QList certList = diff --git a/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp b/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp index 70001f7375..28476fce5b 100644 --- a/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp +++ b/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp @@ -165,9 +165,9 @@ void tst_QSslKey::createPlainTestRows(bool pemOnly) foreach (KeyInfo keyInfo, keyInfoList) { if (pemOnly && keyInfo.format != QSsl::EncodingFormat::Pem) continue; -#ifdef Q_OS_WINRT +#if defined(Q_OS_WINRT) || QT_CONFIG(schannel) if (keyInfo.fileInfo.fileName().contains("RC2-64")) - continue; // WinRT treats RC2 as 128 bit + continue; // WinRT/Schannel treats RC2 as 128 bit #endif #if !defined(QT_NO_SSL) && defined(QT_NO_OPENSSL) // generic backend if (keyInfo.fileInfo.fileName().contains(QRegularExpression("-aes\\d\\d\\d-"))) @@ -599,11 +599,11 @@ void tst_QSslKey::encrypt() QFETCH(QByteArray, cipherText); QByteArray iv("abcdefgh"); -#ifdef Q_OS_WINRT - QEXPECT_FAIL("RC2-40-CBC, length 0", "WinRT treats RC2 as 128-bit", Abort); - QEXPECT_FAIL("RC2-40-CBC, length 8", "WinRT treats RC2 as 128-bit", Abort); - QEXPECT_FAIL("RC2-64-CBC, length 0", "WinRT treats RC2 as 128-bit", Abort); - QEXPECT_FAIL("RC2-64-CBC, length 8", "WinRT treats RC2 as 128-bit", Abort); +#if defined(Q_OS_WINRT) || QT_CONFIG(schannel) + QEXPECT_FAIL("RC2-40-CBC, length 0", "WinRT/Schannel treats RC2 as 128-bit", Abort); + QEXPECT_FAIL("RC2-40-CBC, length 8", "WinRT/Schannel treats RC2 as 128-bit", Abort); + QEXPECT_FAIL("RC2-64-CBC, length 0", "WinRT/Schannel treats RC2 as 128-bit", Abort); + QEXPECT_FAIL("RC2-64-CBC, length 8", "WinRT/Schannel treats RC2 as 128-bit", Abort); #endif QByteArray encrypted = QSslKeyPrivate::encrypt(cipher, plainText, key, iv); QCOMPARE(encrypted, cipherText); diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index afba37c1f0..ca6029685d 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -641,6 +641,10 @@ void tst_QSslSocket::sslErrors() QFETCH(int, port); QSslSocketPtr socket = newSocket(); +#if QT_CONFIG(schannel) + // Needs to be < 1.2 because of the old certificate and <= 1.0 because of the mail server + socket->setProtocol(QSsl::SslProtocol::TlsV1_0); +#endif QSignalSpy sslErrorsSpy(socket.data(), SIGNAL(sslErrors(QList))); QSignalSpy peerVerifyErrorSpy(socket.data(), SIGNAL(peerVerifyError(QSslError))); @@ -720,6 +724,9 @@ void tst_QSslSocket::connectToHostEncrypted() return; QSslSocketPtr socket = newSocket(); +#if QT_CONFIG(schannel) // old certificate not supported with TLS 1.2 + socket->setProtocol(QSsl::SslProtocol::TlsV1_1); +#endif this->socket = socket.data(); QVERIFY(socket->addCaCertificates(testDataDir + "certs/qt-test-server-cacert.pem")); #ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND @@ -753,6 +760,9 @@ void tst_QSslSocket::connectToHostEncryptedWithVerificationPeerName() return; QSslSocketPtr socket = newSocket(); +#if QT_CONFIG(schannel) // old certificate not supported with TLS 1.2 + socket->setProtocol(QSsl::SslProtocol::TlsV1_1); +#endif this->socket = socket.data(); socket->addCaCertificates(testDataDir + "certs/qt-test-server-cacert.pem"); @@ -1413,6 +1423,11 @@ void tst_QSslSocket::setLocalCertificateChain() loop.exec(); QList chain = socket->peerCertificateChain(); +#if QT_CONFIG(schannel) + QEXPECT_FAIL("", "Schannel cannot send intermediate certificates not " + "located in a system certificate store", + Abort); +#endif QCOMPARE(chain.size(), 2); QCOMPARE(chain[0].serialNumber(), QByteArray("10:a0:ad:77:58:f6:6e:ae:46:93:a3:43:f9:59:8a:9e")); QCOMPARE(chain[1].serialNumber(), QByteArray("3b:eb:99:c5:ea:d8:0b:5d:0b:97:5d:4f:06:75:4b:e1")); @@ -1480,6 +1495,9 @@ void tst_QSslSocket::setSslConfiguration() QSslSocketPtr socket = newSocket(); QFETCH(QSslConfiguration, configuration); socket->setSslConfiguration(configuration); +#if QT_CONFIG(schannel) // old certificate not supported with TLS 1.2 + socket->setProtocol(QSsl::SslProtocol::TlsV1_1); +#endif this->socket = socket.data(); socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443); QFETCH(bool, works); @@ -2174,6 +2192,9 @@ void tst_QSslSocket::verifyMode() return; QSslSocket socket; +#if QT_CONFIG(schannel) // old certificate not supported with TLS 1.2 + socket.setProtocol(QSsl::SslProtocol::TlsV1_1); +#endif QCOMPARE(socket.peerVerifyMode(), QSslSocket::AutoVerifyPeer); socket.setPeerVerifyMode(QSslSocket::VerifyNone); QCOMPARE(socket.peerVerifyMode(), QSslSocket::VerifyNone); @@ -2474,6 +2495,9 @@ void tst_QSslSocket::abortOnSslErrors() void tst_QSslSocket::readFromClosedSocket() { QSslSocketPtr socket = newSocket(); +#if QT_CONFIG(schannel) // old certificate not supported with TLS 1.2 + socket->setProtocol(QSsl::SslProtocol::TlsV1_1); +#endif socket->ignoreSslErrors(); socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443); socket->ignoreSslErrors(); @@ -3222,6 +3246,11 @@ void tst_QSslSocket::verifyClientCertificate() return; QFETCH(QSslSocket::PeerVerifyMode, peerVerifyMode); +#if QT_CONFIG(schannel) + if (peerVerifyMode == QSslSocket::QueryPeer || peerVerifyMode == QSslSocket::AutoVerifyPeer) + QSKIP("Schannel doesn't tackle requesting a certificate and not receiving one."); +#endif + SslServer server; server.addCaCertificates = testDataDir + "certs/bogus-ca.crt"; server.ignoreSslErrors = false; @@ -3252,6 +3281,14 @@ void tst_QSslSocket::verifyClientCertificate() // check server socket QVERIFY(server.socket); +#if QT_CONFIG(schannel) + // As additional info to the QEXPECT_FAIL below: + // This is because schannel treats it as an error (client side) if you don't have a certificate + // when asked for one. + QEXPECT_FAIL("NoCert:VerifyPeer", + "The client disconnects first, which causes the event " + "loop to quit before the server disconnects.", Continue); +#endif QCOMPARE(server.socket->state(), expectedState); QCOMPARE(server.socket->isEncrypted(), works); @@ -3260,6 +3297,13 @@ void tst_QSslSocket::verifyClientCertificate() QVERIFY(server.socket->peerCertificateChain().isEmpty()); } else { QCOMPARE(server.socket->peerCertificate(), clientCerts.first()); +#if QT_CONFIG(schannel) + if (clientCerts.count() == 1 && server.socket->peerCertificateChain().count() == 2) { + QEXPECT_FAIL("", + "Schannel includes the entire chain, not just the leaf and intermediates", + Continue); + } +#endif QCOMPARE(server.socket->peerCertificateChain(), clientCerts); } @@ -3270,7 +3314,7 @@ void tst_QSslSocket::verifyClientCertificate() void tst_QSslSocket::readBufferMaxSize() { -#ifdef QT_SECURETRANSPORT +#if defined(QT_SECURETRANSPORT) || QT_CONFIG(schannel) // QTBUG-55170: // SecureTransport back-end was ignoring read-buffer // size limit, resulting (potentially) in a constantly @@ -3806,6 +3850,9 @@ void tst_QSslSocket::pskServer() { #ifdef Q_OS_WINRT QSKIP("Server-side encryption is not implemented on WinRT."); +#endif +#if QT_CONFIG(schannel) + QSKIP("Schannel does not have PSK support implemented."); #endif QFETCH_GLOBAL(bool, setProxy); if (!QSslSocket::supportsSsl() || setProxy) From e823c351c6226765ccfe66e2ee93a2797dcc9721 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 26 Nov 2018 11:22:07 +0100 Subject: [PATCH 0888/1650] Fix resolve() on fonts returned from QWidget::font() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set the inherited properties as resolved on the font, so non-default values are passed on in contexts that does resolve logic like QPainter. One test is updated as it actually tests what it is supposed to on more configurations. Fixes: QTBUG-39560 Change-Id: Ief668e992ccdc091337a259a4c1306a00e67c73f Reviewed-by: Tor Arne Vestbø --- src/widgets/kernel/qwidget.cpp | 20 ++++++++++++++++++- src/widgets/kernel/qwidget_p.h | 4 +++- src/widgets/styles/qstylesheetstyle.cpp | 11 ++++++---- .../widgets/kernel/qwidget/tst_qwidget.cpp | 13 ++++++++++++ .../qstylesheetstyle/tst_qstylesheetstyle.cpp | 4 ++-- 5 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 9f7c486148..6227996ff8 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -247,6 +247,7 @@ QWidgetPrivate::QWidgetPrivate(int version) #ifndef QT_NO_TOOLTIP , toolTipDuration(-1) #endif + , directFontResolveMask(0) , inheritedFontResolveMask(0) , inheritedPaletteResolveMask(0) , leftmargin(0) @@ -4751,6 +4752,18 @@ QFont QWidgetPrivate::naturalWidgetFont(uint inheritedMask) const return naturalFont; } +/*! + \internal + + Returns a font suitable for inheritance, where only locally set attributes are considered resolved. +*/ +QFont QWidgetPrivate::localFont() const +{ + QFont localfont = data.fnt; + localfont.resolve(directFontResolveMask); + return localfont; +} + /*! \internal @@ -4762,7 +4775,7 @@ QFont QWidgetPrivate::naturalWidgetFont(uint inheritedMask) const void QWidgetPrivate::resolveFont() { QFont naturalFont = naturalWidgetFont(inheritedFontResolveMask); - QFont resolvedFont = data.fnt.resolve(naturalFont); + QFont resolvedFont = localFont().resolve(naturalFont); setFont_helper(resolvedFont); } @@ -4801,6 +4814,11 @@ void QWidgetPrivate::updateFont(const QFont &font) inheritedFontResolveMask = 0; } uint newMask = data.fnt.resolve() | inheritedFontResolveMask; + // Set the font as also having resolved inherited traits, so the result of reading QWidget::font() + // isn't all weak information, but save the original mask to be able to let new changes on the + // parent widget font propagate correctly. + directFontResolveMask = data.fnt.resolve(); + data.fnt.resolve(newMask); for (int i = 0; i < children.size(); ++i) { QWidget *w = qobject_cast(children.at(i)); diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 6f1ce67c4c..0d7e9e26ba 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -383,10 +383,11 @@ public: void updateFont(const QFont &); inline void setFont_helper(const QFont &font) { - if (data.fnt.resolve() == font.resolve() && data.fnt == font) + if (directFontResolveMask == font.resolve() && data.fnt == font) return; updateFont(font); } + QFont localFont() const; void resolveFont(); QFont naturalWidgetFont(uint inheritedMask) const; @@ -729,6 +730,7 @@ public: #endif // Other variables. + uint directFontResolveMask; uint inheritedFontResolveMask; uint inheritedPaletteResolveMask; short leftmargin; diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 96c6fdf2e2..7c1c0ca3d8 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -2642,7 +2642,7 @@ void QStyleSheetStyle::setPalette(QWidget *w) QRenderRule rule = renderRule(w, PseudoElement_None, map[i].state | extendedPseudoClass(w)); if (i == 0) { if (!w->property("_q_styleSheetWidgetFont").isValid()) { - saveWidgetFont(w, w->font()); + saveWidgetFont(w, w->d_func()->localFont()); } updateStyleSheetFont(w); if (ew != w) @@ -6025,7 +6025,7 @@ void QStyleSheetStyle::updateStyleSheetFont(QWidget* w) const unsetStyleSheetFont(w); if (rule.font.resolve()) { - QFont wf = w->font(); + QFont wf = w->d_func()->localFont(); styleSheetCaches->customFontWidgets.insert(w, {wf, rule.font.resolve()}); QFont font = rule.font.resolve(wf); @@ -6033,7 +6033,9 @@ void QStyleSheetStyle::updateStyleSheetFont(QWidget* w) const w->setFont(font); } } else { - QFont font = rule.font.resolve(w->font()); + QFont wf = w->d_func()->localFont(); + QFont font = rule.font.resolve(wf); + font.resolve(wf.resolve() | rule.font.resolve()); if ((!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation)) && isNaturalChild(w) && qobject_cast(w->parent())) { @@ -6041,10 +6043,11 @@ void QStyleSheetStyle::updateStyleSheetFont(QWidget* w) const font = font.resolve(static_cast(w->parent())->font()); } - if (w->data->fnt == font) + if (wf.resolve() == font.resolve() && wf == font) return; w->data->fnt = font; + w->d_func()->directFontResolveMask = font.resolve(); QEvent e(QEvent::FontChange); QApplication::sendEvent(w, &e); diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 360e6986f6..3b9c9060fa 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -166,6 +166,7 @@ private slots: void getSetCheck(); void fontPropagation(); void fontPropagation2(); + void fontPropagation3(); void palettePropagation(); void palettePropagation2(); void enabledPropagation(); @@ -819,6 +820,18 @@ void tst_QWidget::fontPropagation2() QVERIFY(child5->font().italic()); } +void tst_QWidget::fontPropagation3() +{ + QWidget parent; + QWidget *child = new QWidget(&parent); + parent.setFont(QFont("Monospace", 9)); + QImage image(32, 32, QImage::Format_RGB32); + QPainter p(&image); + p.setFont(child->font()); + QCOMPARE(p.font().family(), child->font().family()); + QCOMPARE(p.font().pointSize(), child->font().pointSize()); +} + void tst_QWidget::palettePropagation() { QScopedPointer testWidget(new QWidget); diff --git a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp index 03f24ba151..0e5c40f1b6 100644 --- a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp +++ b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp @@ -741,9 +741,9 @@ void tst_QStyleSheetStyle::fontPropagation() QCOMPARE(FONTSIZE(pb), 20); QWidget window; - window.setStyleSheet("* { font-size: 10pt }"); + window.setStyleSheet("* { font-size: 9pt }"); pb.setParent(&window); - QCOMPARE(FONTSIZE(pb), 10); + QCOMPARE(FONTSIZE(pb), 9); window.setStyleSheet(""); QCOMPARE(FONTSIZE(pb), buttonFontSize); From a20c52dffcef05f9ee44ed4cf3a729a19b1c2ab9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 14 Jan 2019 14:21:10 +0100 Subject: [PATCH 0889/1650] Use requestUpdate instead of timer in a few GL examples Change-Id: I235ad367fe693c86ef5a0844fde0573371b284db Reviewed-by: Laszlo Agocs --- examples/opengl/contextinfo/renderwindow.cpp | 13 ++++++++----- examples/opengl/contextinfo/renderwindow.h | 3 +++ examples/opengl/hellowindow/hellowindow.cpp | 13 ++++++++++--- examples/opengl/hellowindow/hellowindow.h | 5 +++-- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/examples/opengl/contextinfo/renderwindow.cpp b/examples/opengl/contextinfo/renderwindow.cpp index 2ac2a38afb..21b7434be6 100644 --- a/examples/opengl/contextinfo/renderwindow.cpp +++ b/examples/opengl/contextinfo/renderwindow.cpp @@ -181,6 +181,13 @@ void RenderWindow::setupVertexAttribs() m_vbo.release(); } +bool RenderWindow::event(QEvent *ev) +{ + if (ev->type() == QEvent::UpdateRequest) + render(); + return QWindow::event(ev); +} + void RenderWindow::render() { if (!m_context->makeCurrent(this)) { @@ -227,9 +234,5 @@ void RenderWindow::render() m_angle += 1.0f; - // Instead of 0 wait a few more milliseconds before rendering again. This is - // only here to make the UI widgets more responsive on slower machines. We - // can afford it since our rendering is so lightweight. - const int interval = 5; - QTimer::singleShot(interval, this, &RenderWindow::render); + requestUpdate(); } diff --git a/examples/opengl/contextinfo/renderwindow.h b/examples/opengl/contextinfo/renderwindow.h index c148b71c3c..1b4a79dfcf 100644 --- a/examples/opengl/contextinfo/renderwindow.h +++ b/examples/opengl/contextinfo/renderwindow.h @@ -72,6 +72,9 @@ signals: void ready(); void error(const QString &msg); +protected: + bool event(QEvent *ev) override; + private slots: void render(); diff --git a/examples/opengl/hellowindow/hellowindow.cpp b/examples/opengl/hellowindow/hellowindow.cpp index a978e19b79..1c1259de13 100644 --- a/examples/opengl/hellowindow/hellowindow.cpp +++ b/examples/opengl/hellowindow/hellowindow.cpp @@ -98,6 +98,15 @@ void HelloWindow::exposeEvent(QExposeEvent *) m_renderer->render(); } +bool HelloWindow::event(QEvent *ev) +{ + if (ev->type() == QEvent::UpdateRequest) { + m_renderer->render(); + requestUpdate(); + } + return QWindow::event(ev); +} + void HelloWindow::mousePressEvent(QMouseEvent *) { updateColor(); @@ -132,7 +141,7 @@ void Renderer::setAnimating(HelloWindow *window, bool animating) if (animating) { m_windows << window; if (m_windows.size() == 1) - QTimer::singleShot(0, this, &Renderer::render); + window->requestUpdate(); } else { m_currentWindow = 0; m_windows.removeOne(window); @@ -196,8 +205,6 @@ void Renderer::render() m_context->swapBuffers(surface); m_fAngle += 1.0f; - - QTimer::singleShot(0, this, &Renderer::render); } Q_GLOBAL_STATIC(QMutex, initMutex) diff --git a/examples/opengl/hellowindow/hellowindow.h b/examples/opengl/hellowindow/hellowindow.h index e92e45a125..e6d7970cfc 100644 --- a/examples/opengl/hellowindow/hellowindow.h +++ b/examples/opengl/hellowindow/hellowindow.h @@ -112,11 +112,12 @@ public: QColor color() const; void updateColor(); +protected: + bool event(QEvent *ev) override; void exposeEvent(QExposeEvent *event) override; - -private: void mousePressEvent(QMouseEvent *) override; +private: int m_colorIndex; QColor m_color; const QSharedPointer m_renderer; From df65087192df4f4e1dd92435e836a225ca003a18 Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Sat, 19 Jan 2019 12:41:31 +1000 Subject: [PATCH 0890/1650] wasm: remove BINARYEN_METHOD from link line MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This has been removed in emscripten compler version 1.38.23 and will cause building apps to fail. Change-Id: I7e58053ce06053f6f1d577377b503cabb035bb58 Fixes: QTBUG-73143 Reviewed-by: Morten Johan Sørvig --- mkspecs/wasm-emscripten/qmake.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/mkspecs/wasm-emscripten/qmake.conf b/mkspecs/wasm-emscripten/qmake.conf index 2539770b51..e7b45d312d 100644 --- a/mkspecs/wasm-emscripten/qmake.conf +++ b/mkspecs/wasm-emscripten/qmake.conf @@ -20,7 +20,6 @@ EMCC_COMMON_LFLAGS = \ -s NO_EXIT_RUNTIME=0 \ -s ERROR_ON_UNDEFINED_SYMBOLS=1 \ --bind \ - -s \"BINARYEN_METHOD=\'native-wasm\'\" \ -s \"BINARYEN_TRAP_MODE=\'clamp\'\" # The -s arguments can also be used with release builds, From 0c007a87be88f44151616b7251cfed5508913e0f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 11 Dec 2018 22:02:59 -0800 Subject: [PATCH 0891/1650] Fix change-of-sign warnings in ICC 19 error #68: integer conversion resulted in a change of sign Change-Id: I4ac1156702324f0fb814fffd156f80962df6b4a7 Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qdrawhelper_sse4.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qdrawhelper_sse4.cpp b/src/gui/painting/qdrawhelper_sse4.cpp index e3cc1dd43e..f6c2f11eaf 100644 --- a/src/gui/painting/qdrawhelper_sse4.cpp +++ b/src/gui/painting/qdrawhelper_sse4.cpp @@ -174,7 +174,7 @@ template static inline void convertARGBFromRGBA64PM_sse4(uint *buffer, const QRgba64 *src, int count) { int i = 0; - const __m128i alphaMask = _mm_set1_epi64x(Q_UINT64_C(0xffff) << 48); + const __m128i alphaMask = _mm_set1_epi64x(qint64(Q_UINT64_C(0xffff) << 48)); const __m128i alphaMask32 = _mm_set1_epi32(0xff000000); const __m128i rgbaMask = _mm_setr_epi8(2, 1, 0, 3, 6, 5, 4, 7, 10, 9, 8, 11, 14, 13, 12, 15); const __m128i zero = _mm_setzero_si128(); From a905d9d91c229ea2760c54e5375ece35aa081b7a Mon Sep 17 00:00:00 2001 From: Lars Schmertmann Date: Wed, 9 Jan 2019 12:58:49 +0100 Subject: [PATCH 0892/1650] Reorder the elements of the Android manifest to fix a lint warning Incorrect order of elements in manifest --------------------------------------- The tag should appear after the elements which declare which version you need, which features you need, which libraries you need, and so on. In the past there have been subtle bugs (such as themes not getting applied correctly) when the tag appears before some of these other elements, so it's best to order your manifest in the logical dependency order. Change-Id: I647c6eed71b678f4df65a00fbd51135b93959e11 Reviewed-by: Edward Welbourne Reviewed-by: BogDan Vatra --- src/android/templates/AndroidManifest.xml | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/android/templates/AndroidManifest.xml b/src/android/templates/AndroidManifest.xml index 966ce23b14..678ba4f0bd 100644 --- a/src/android/templates/AndroidManifest.xml +++ b/src/android/templates/AndroidManifest.xml @@ -1,5 +1,17 @@ + + + + + + + + + + - - - - - - - - - From c590aa678d5c27162b0ca7191fa76b1d3a112767 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 23 Nov 2018 20:05:42 +0100 Subject: [PATCH 0893/1650] Cleanup SimpleTreeModel example Cleanup the SimpleTreeModel example: - include own headers first - use nullptr - add sanity checks Change-Id: If57d608e3919368b2022ff86aede8de9c2ba7369 Reviewed-by: Luca Beldi Reviewed-by: Sze Howe Koh --- examples/widgets/doc/src/simpletreemodel.qdoc | 5 ++- .../itemviews/simpletreemodel/treeitem.cpp | 18 +++++----- .../itemviews/simpletreemodel/treeitem.h | 8 ++--- .../itemviews/simpletreemodel/treemodel.cpp | 35 ++++++++----------- .../itemviews/simpletreemodel/treemodel.h | 2 +- 5 files changed, 31 insertions(+), 37 deletions(-) diff --git a/examples/widgets/doc/src/simpletreemodel.qdoc b/examples/widgets/doc/src/simpletreemodel.qdoc index a50197b04d..f5fe93897c 100644 --- a/examples/widgets/doc/src/simpletreemodel.qdoc +++ b/examples/widgets/doc/src/simpletreemodel.qdoc @@ -170,9 +170,8 @@ \snippet itemviews/simpletreemodel/treeitem.cpp 5 - Column data is returned by the \c data() function, taking advantage of - QList's ability to provide sensible default values if the column number - is out of range: + Column data is returned by the \c data() function. The bounds are checked + before accessing the container with the data: \snippet itemviews/simpletreemodel/treeitem.cpp 6 diff --git a/examples/widgets/itemviews/simpletreemodel/treeitem.cpp b/examples/widgets/itemviews/simpletreemodel/treeitem.cpp index e11639ff67..41fe24e737 100644 --- a/examples/widgets/itemviews/simpletreemodel/treeitem.cpp +++ b/examples/widgets/itemviews/simpletreemodel/treeitem.cpp @@ -54,16 +54,12 @@ A container for items of data supplied by the simple tree model. */ -#include - #include "treeitem.h" //! [0] -TreeItem::TreeItem(const QList &data, TreeItem *parent) -{ - m_parentItem = parent; - m_itemData = data; -} +TreeItem::TreeItem(const QVector &data, TreeItem *parent) + : m_itemData(data), m_parentItem(parent) +{} //! [0] //! [1] @@ -83,7 +79,9 @@ void TreeItem::appendChild(TreeItem *item) //! [3] TreeItem *TreeItem::child(int row) { - return m_childItems.value(row); + if (row < 0 || row >= m_childItems.size()) + return nullptr; + return m_childItems.at(row); } //! [3] @@ -104,7 +102,9 @@ int TreeItem::columnCount() const //! [6] QVariant TreeItem::data(int column) const { - return m_itemData.value(column); + if (column < 0 || column >= m_itemData.size()) + return QVariant(); + return m_itemData.at(column); } //! [6] diff --git a/examples/widgets/itemviews/simpletreemodel/treeitem.h b/examples/widgets/itemviews/simpletreemodel/treeitem.h index 8d0bb49627..390433597d 100644 --- a/examples/widgets/itemviews/simpletreemodel/treeitem.h +++ b/examples/widgets/itemviews/simpletreemodel/treeitem.h @@ -51,14 +51,14 @@ #ifndef TREEITEM_H #define TREEITEM_H -#include #include +#include //! [0] class TreeItem { public: - explicit TreeItem(const QList &data, TreeItem *parentItem = 0); + explicit TreeItem(const QVector &data, TreeItem *parentItem = nullptr); ~TreeItem(); void appendChild(TreeItem *child); @@ -71,8 +71,8 @@ public: TreeItem *parentItem(); private: - QList m_childItems; - QList m_itemData; + QVector m_childItems; + QVector m_itemData; TreeItem *m_parentItem; }; //! [0] diff --git a/examples/widgets/itemviews/simpletreemodel/treemodel.cpp b/examples/widgets/itemviews/simpletreemodel/treemodel.cpp index 1de970d398..cfa65846ed 100644 --- a/examples/widgets/itemviews/simpletreemodel/treemodel.cpp +++ b/examples/widgets/itemviews/simpletreemodel/treemodel.cpp @@ -55,8 +55,8 @@ models. */ -#include "treeitem.h" #include "treemodel.h" +#include "treeitem.h" #include @@ -64,10 +64,8 @@ TreeModel::TreeModel(const QString &data, QObject *parent) : QAbstractItemModel(parent) { - QList rootData; - rootData << "Title" << "Summary"; - rootItem = new TreeItem(rootData); - setupModelData(data.split(QString("\n")), rootItem); + rootItem = new TreeItem({tr("Title"), tr("Summary")}); + setupModelData(data.split('\n'), rootItem); } //! [0] @@ -83,8 +81,7 @@ int TreeModel::columnCount(const QModelIndex &parent) const { if (parent.isValid()) return static_cast(parent.internalPointer())->columnCount(); - else - return rootItem->columnCount(); + return rootItem->columnCount(); } //! [2] @@ -107,7 +104,7 @@ QVariant TreeModel::data(const QModelIndex &index, int role) const Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const { if (!index.isValid()) - return 0; + return Qt::NoItemFlags; return QAbstractItemModel::flags(index); } @@ -125,8 +122,7 @@ QVariant TreeModel::headerData(int section, Qt::Orientation orientation, //! [5] //! [6] -QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) - const +QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) const { if (!hasIndex(row, column, parent)) return QModelIndex(); @@ -141,8 +137,7 @@ QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) TreeItem *childItem = parentItem->child(row); if (childItem) return createIndex(row, column, childItem); - else - return QModelIndex(); + return QModelIndex(); } //! [6] @@ -180,8 +175,8 @@ int TreeModel::rowCount(const QModelIndex &parent) const void TreeModel::setupModelData(const QStringList &lines, TreeItem *parent) { - QList parents; - QList indentations; + QVector parents; + QVector indentations; parents << parent; indentations << 0; @@ -195,14 +190,15 @@ void TreeModel::setupModelData(const QStringList &lines, TreeItem *parent) position++; } - QString lineData = lines[number].mid(position).trimmed(); + const QString lineData = lines[number].mid(position).trimmed(); if (!lineData.isEmpty()) { // Read the column data from the rest of the line. - QStringList columnStrings = lineData.split("\t", QString::SkipEmptyParts); - QList columnData; - for (int column = 0; column < columnStrings.count(); ++column) - columnData << columnStrings[column]; + const QStringList columnStrings = lineData.split('\t', QString::SkipEmptyParts); + QVector columnData; + columnData.reserve(columnStrings.count()); + for (const QString &columnString : columnStrings) + columnData << columnString; if (position > indentations.last()) { // The last child of the current parent is now the new parent @@ -222,7 +218,6 @@ void TreeModel::setupModelData(const QStringList &lines, TreeItem *parent) // Append a new item to the current parent's list of children. parents.last()->appendChild(new TreeItem(columnData, parents.last())); } - ++number; } } diff --git a/examples/widgets/itemviews/simpletreemodel/treemodel.h b/examples/widgets/itemviews/simpletreemodel/treemodel.h index 800728fb82..76fd03f112 100644 --- a/examples/widgets/itemviews/simpletreemodel/treemodel.h +++ b/examples/widgets/itemviews/simpletreemodel/treemodel.h @@ -63,7 +63,7 @@ class TreeModel : public QAbstractItemModel Q_OBJECT public: - explicit TreeModel(const QString &data, QObject *parent = 0); + explicit TreeModel(const QString &data, QObject *parent = nullptr); ~TreeModel(); QVariant data(const QModelIndex &index, int role) const override; From aa32510430d6a5e58cb456faeb072d9f189872fe Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sun, 2 Dec 2018 14:11:13 +0100 Subject: [PATCH 0894/1650] Cleanup Widgets examples - nullptr Cleanup the widgets examples - replace 0 with nullptr Change-Id: Id4bf119b9a41f6d10117f3a613a6e604128fa196 Reviewed-by: Konstantin Shegunov Reviewed-by: Edward Welbourne Reviewed-by: Paul Wicking --- .../widgets/animation/animatedtiles/main.cpp | 2 +- examples/widgets/animation/easing/window.h | 2 +- .../widgets/animation/moveblocks/main.cpp | 3 ++- .../animation/stickman/graphicsview.cpp | 4 +++- .../widgets/animation/stickman/graphicsview.h | 2 +- .../widgets/animation/stickman/lifecycle.cpp | 7 +++---- .../widgets/animation/stickman/stickman.cpp | 3 +-- .../animation/sub-attaq/animationmanager.cpp | 2 +- examples/widgets/animation/sub-attaq/boat.cpp | 5 +++-- examples/widgets/animation/sub-attaq/boat_p.h | 19 ++++++++++++------- .../animation/sub-attaq/mainwindow.cpp | 3 ++- .../widgets/animation/sub-attaq/mainwindow.h | 2 +- .../animation/sub-attaq/pixmapitem.cpp | 3 ++- .../widgets/animation/sub-attaq/pixmapitem.h | 2 +- .../animation/sub-attaq/qanimationstate.cpp | 2 +- .../widgets/animation/sub-attaq/states.cpp | 7 ++----- examples/widgets/desktop/systray/main.cpp | 2 +- examples/widgets/desktop/systray/window.cpp | 2 +- .../dialogs/classwizard/classwizard.cpp | 4 ++-- examples/widgets/dialogs/findfiles/window.cpp | 4 ++-- .../dialogs/standarddialogs/dialog.cpp | 4 ++-- .../embeddeddialogs/customproxy.cpp | 4 ++-- .../graphicsview/embeddeddialogs/main.cpp | 2 +- .../layouts/borderlayout/borderlayout.cpp | 9 +++------ .../widgets/layouts/flowlayout/flowlayout.cpp | 5 ++--- .../mainwindows/mainwindow/colorswatch.cpp | 8 ++++---- .../mainwindows/mainwindow/toolbar.cpp | 6 +++--- .../widgets/mainwindows/mdi/mainwindow.cpp | 6 +++--- .../widgets/mainwindows/sdi/mainwindow.cpp | 2 +- .../widgets/widgets/analogclock/analogclock.h | 2 +- examples/widgets/widgets/calculator/button.h | 2 +- .../widgets/widgets/calculator/calculator.h | 2 +- .../widgets/charactermap/characterwidget.h | 2 +- .../widgets/charactermap/mainwindow.cpp | 2 +- .../widgets/widgets/codeeditor/codeeditor.h | 2 +- .../widgets/digitalclock/digitalclock.h | 2 +- .../widgets/widgets/elidedlabel/elidedlabel.h | 2 +- .../widgets/widgets/elidedlabel/testwidget.h | 2 +- examples/widgets/widgets/groupbox/window.h | 2 +- examples/widgets/widgets/lineedits/window.cpp | 2 +- examples/widgets/widgets/movie/movieplayer.h | 2 +- .../widgets/widgets/scribble/scribblearea.h | 2 +- .../widgets/widgets/shapedclock/shapedclock.h | 2 +- .../widgets/widgets/sliders/slidersgroup.h | 2 +- .../widgets/widgets/styles/widgetgallery.h | 2 +- .../widgets/stylesheet/stylesheeteditor.h | 2 +- .../widgets/tablet/tabletapplication.h | 5 ++--- examples/widgets/widgets/tetrix/tetrixboard.h | 2 +- .../widgets/widgets/tooltips/sortingbox.cpp | 4 ++-- .../widgets/widgets/validators/ledwidget.h | 2 +- .../widgets/validators/localeselector.h | 2 +- examples/widgets/widgets/wiggly/dialog.h | 2 +- .../widgets/widgets/wiggly/wigglywidget.h | 2 +- .../widgets/windowflags/previewwindow.h | 2 +- 54 files changed, 91 insertions(+), 90 deletions(-) diff --git a/examples/widgets/animation/animatedtiles/main.cpp b/examples/widgets/animation/animatedtiles/main.cpp index 8edd64e482..553b620e41 100644 --- a/examples/widgets/animation/animatedtiles/main.cpp +++ b/examples/widgets/animation/animatedtiles/main.cpp @@ -69,7 +69,7 @@ class Button : public QGraphicsWidget { Q_OBJECT public: - Button(const QPixmap &pixmap, QGraphicsItem *parent = 0) + Button(const QPixmap &pixmap, QGraphicsItem *parent = nullptr) : QGraphicsWidget(parent), _pix(pixmap) { setAcceptHoverEvents(true); diff --git a/examples/widgets/animation/easing/window.h b/examples/widgets/animation/easing/window.h index 2b7b2a5bf3..541377a981 100644 --- a/examples/widgets/animation/easing/window.h +++ b/examples/widgets/animation/easing/window.h @@ -66,7 +66,7 @@ public: class Window : public QWidget { Q_OBJECT public: - Window(QWidget *parent = 0); + Window(QWidget *parent = nullptr); private slots: void curveChanged(int row); void pathChanged(int index); diff --git a/examples/widgets/animation/moveblocks/main.cpp b/examples/widgets/animation/moveblocks/main.cpp index e59b17cbf9..d03b57cd5e 100644 --- a/examples/widgets/animation/moveblocks/main.cpp +++ b/examples/widgets/animation/moveblocks/main.cpp @@ -169,7 +169,8 @@ class GraphicsView : public QGraphicsView { Q_OBJECT public: - GraphicsView(QGraphicsScene *scene, QWidget *parent = NULL) : QGraphicsView(scene, parent) + GraphicsView(QGraphicsScene *scene, QWidget *parent = nullptr) + : QGraphicsView(scene, parent) { } diff --git a/examples/widgets/animation/stickman/graphicsview.cpp b/examples/widgets/animation/stickman/graphicsview.cpp index 9cb57fcd9e..7058e15345 100644 --- a/examples/widgets/animation/stickman/graphicsview.cpp +++ b/examples/widgets/animation/stickman/graphicsview.cpp @@ -55,7 +55,9 @@ #include #include -GraphicsView::GraphicsView(QWidget *parent) : QGraphicsView(parent), m_editor(0) {} +GraphicsView::GraphicsView(QWidget *parent) + : QGraphicsView(parent), m_editor(nullptr) +{} void GraphicsView::keyPressEvent(QKeyEvent *e) { diff --git a/examples/widgets/animation/stickman/graphicsview.h b/examples/widgets/animation/stickman/graphicsview.h index 56396bb780..361fee219d 100644 --- a/examples/widgets/animation/stickman/graphicsview.h +++ b/examples/widgets/animation/stickman/graphicsview.h @@ -58,7 +58,7 @@ class GraphicsView: public QGraphicsView { Q_OBJECT public: - GraphicsView(QWidget *parent = 0); + GraphicsView(QWidget *parent = nullptr); protected: void resizeEvent(QResizeEvent *event) override; diff --git a/examples/widgets/animation/stickman/lifecycle.cpp b/examples/widgets/animation/stickman/lifecycle.cpp index 5d4c406b2e..046e3f4cd1 100644 --- a/examples/widgets/animation/stickman/lifecycle.cpp +++ b/examples/widgets/animation/stickman/lifecycle.cpp @@ -175,9 +175,8 @@ void LifeCycle::addActivity(const QString &fileName, Qt::Key key, QObject *sende QState *state = makeState(m_alive, fileName); m_alive->addTransition(new KeyPressTransition(m_keyReceiver, key, state)); - if((sender != NULL) || (signal != NULL)) { + if (sender || signal) m_alive->addTransition(sender, signal, state); - } } QState *LifeCycle::makeState(QState *parentState, const QString &animationFileName) @@ -192,7 +191,7 @@ QState *LifeCycle::makeState(QState *parentState, const QString &animationFileNa } const int frameCount = animation.totalFrames(); - QState *previousState = 0; + QState *previousState = nullptr; for (int i=0; isetObjectName(QString::fromLatin1("frame %0").arg(i)); - if (previousState == 0) + if (previousState == nullptr) topLevel->setInitialState(frameState); else //! [2] diff --git a/examples/widgets/animation/stickman/stickman.cpp b/examples/widgets/animation/stickman/stickman.cpp index 8b183d87d5..5725f64eec 100644 --- a/examples/widgets/animation/stickman/stickman.cpp +++ b/examples/widgets/animation/stickman/stickman.cpp @@ -176,8 +176,7 @@ Node *StickMan::node(int idx) const { if (idx >= 0 && idx < NodeCount) return m_nodes[idx]; - else - return 0; + return nullptr; } void StickMan::timerEvent(QTimerEvent *) diff --git a/examples/widgets/animation/sub-attaq/animationmanager.cpp b/examples/widgets/animation/sub-attaq/animationmanager.cpp index 62dac7852a..e3dc27f37f 100644 --- a/examples/widgets/animation/sub-attaq/animationmanager.cpp +++ b/examples/widgets/animation/sub-attaq/animationmanager.cpp @@ -56,7 +56,7 @@ #include // the universe's only animation manager -AnimationManager *AnimationManager::instance = 0; +AnimationManager *AnimationManager::instance = nullptr; AnimationManager::AnimationManager() { diff --git a/examples/widgets/animation/sub-attaq/boat.cpp b/examples/widgets/animation/sub-attaq/boat.cpp index 9f4feba2ec..9037d54878 100644 --- a/examples/widgets/animation/sub-attaq/boat.cpp +++ b/examples/widgets/animation/sub-attaq/boat.cpp @@ -92,8 +92,9 @@ static QAbstractAnimation *setupDestroyAnimation(Boat *boat) -Boat::Boat() : PixmapItem(QString("boat"), GraphicsScene::Big), - speed(0), bombsAlreadyLaunched(0), direction(Boat::None), movementAnimation(0) +Boat::Boat() + : PixmapItem(QString("boat"), GraphicsScene::Big), + speed(0), bombsAlreadyLaunched(0), direction(Boat::None) { setZValue(4); setFlags(QGraphicsItem::ItemIsFocusable); diff --git a/examples/widgets/animation/sub-attaq/boat_p.h b/examples/widgets/animation/sub-attaq/boat_p.h index de11ff9555..8ebfeb27f5 100644 --- a/examples/widgets/animation/sub-attaq/boat_p.h +++ b/examples/widgets/animation/sub-attaq/boat_p.h @@ -146,7 +146,8 @@ private: class MoveStateRight : public QState { public: - explicit MoveStateRight(Boat *boat,QState *parent = 0) : QState(parent), boat(boat) + explicit MoveStateRight(Boat *boat, QState *parent = nullptr) + : QState(parent), boat(boat) { } protected: @@ -163,7 +164,8 @@ private: class MoveStateLeft : public QState { public: - explicit MoveStateLeft(Boat *boat,QState *parent = 0) : QState(parent), boat(boat) + explicit MoveStateLeft(Boat *boat, QState *parent = nullptr) + : QState(parent), boat(boat) { } protected: @@ -180,7 +182,8 @@ private: class StopState : public QState { public: - explicit StopState(Boat *boat,QState *parent = 0) : QState(parent), boat(boat) + explicit StopState(Boat *boat, QState *parent = nullptr) + : QState(parent), boat(boat) { } protected: @@ -198,13 +201,14 @@ private: class LaunchStateRight : public QState { public: - explicit LaunchStateRight(Boat *boat,QState *parent = 0) : QState(parent), boat(boat) + explicit LaunchStateRight(Boat *boat, QState *parent = nullptr) + : QState(parent), boat(boat) { } protected: void onEntry(QEvent *) override { - Bomb *b = new Bomb(); + Bomb *b = new Bomb; b->setPos(boat->x()+boat->size().width(),boat->y()); GraphicsScene *scene = static_cast(boat->scene()); scene->addItem(b); @@ -219,13 +223,14 @@ private: class LaunchStateLeft : public QState { public: - explicit LaunchStateLeft(Boat *boat,QState *parent = 0) : QState(parent), boat(boat) + explicit LaunchStateLeft(Boat *boat, QState *parent = nullptr) + : QState(parent), boat(boat) { } protected: void onEntry(QEvent *) override { - Bomb *b = new Bomb(); + Bomb *b = new Bomb; b->setPos(boat->x() - b->size().width(), boat->y()); GraphicsScene *scene = static_cast(boat->scene()); scene->addItem(b); diff --git a/examples/widgets/animation/sub-attaq/mainwindow.cpp b/examples/widgets/animation/sub-attaq/mainwindow.cpp index b08a7d9f98..a4bb15b383 100644 --- a/examples/widgets/animation/sub-attaq/mainwindow.cpp +++ b/examples/widgets/animation/sub-attaq/mainwindow.cpp @@ -63,7 +63,8 @@ # include #endif -MainWindow::MainWindow() : QMainWindow(0) +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) { QMenu *file = menuBar()->addMenu(tr("&File")); diff --git a/examples/widgets/animation/sub-attaq/mainwindow.h b/examples/widgets/animation/sub-attaq/mainwindow.h index 8d3cc85cd1..c4fb9d324d 100644 --- a/examples/widgets/animation/sub-attaq/mainwindow.h +++ b/examples/widgets/animation/sub-attaq/mainwindow.h @@ -62,7 +62,7 @@ class MainWindow : public QMainWindow { Q_OBJECT public: - MainWindow(); + MainWindow(QWidget *parent = nullptr); private: GraphicsScene *scene; diff --git a/examples/widgets/animation/sub-attaq/pixmapitem.cpp b/examples/widgets/animation/sub-attaq/pixmapitem.cpp index 0723cdfb5d..9475d5c3f8 100644 --- a/examples/widgets/animation/sub-attaq/pixmapitem.cpp +++ b/examples/widgets/animation/sub-attaq/pixmapitem.cpp @@ -54,7 +54,8 @@ //Qt #include -PixmapItem::PixmapItem(const QString &fileName,GraphicsScene::Mode mode, QGraphicsItem * parent) : QGraphicsObject(parent) +PixmapItem::PixmapItem(const QString &fileName,GraphicsScene::Mode mode, QGraphicsItem * parent) + : QGraphicsObject(parent) { if (mode == GraphicsScene::Big) pix = QPixmap(QStringLiteral(":/big/") + fileName); diff --git a/examples/widgets/animation/sub-attaq/pixmapitem.h b/examples/widgets/animation/sub-attaq/pixmapitem.h index de8ed67a38..ec5c01857f 100644 --- a/examples/widgets/animation/sub-attaq/pixmapitem.h +++ b/examples/widgets/animation/sub-attaq/pixmapitem.h @@ -60,7 +60,7 @@ class PixmapItem : public QGraphicsObject { public: - PixmapItem(const QString &fileName, GraphicsScene::Mode mode, QGraphicsItem * parent = 0); + PixmapItem(const QString &fileName, GraphicsScene::Mode mode, QGraphicsItem *parent = nullptr); PixmapItem(const QString &fileName, QGraphicsScene *scene); QSizeF size() const; QRectF boundingRect() const override; diff --git a/examples/widgets/animation/sub-attaq/qanimationstate.cpp b/examples/widgets/animation/sub-attaq/qanimationstate.cpp index fc0da7cea2..ef88df8abe 100644 --- a/examples/widgets/animation/sub-attaq/qanimationstate.cpp +++ b/examples/widgets/animation/sub-attaq/qanimationstate.cpp @@ -84,7 +84,7 @@ machine.start(); Constructs a new state with the given \a parent state. */ QAnimationState::QAnimationState(QState *parent) - : QState(parent), m_animation(0) + : QState(parent), m_animation(nullptr) { } diff --git a/examples/widgets/animation/sub-attaq/states.cpp b/examples/widgets/animation/sub-attaq/states.cpp index 8a3a97a20f..cda10ccdaf 100644 --- a/examples/widgets/animation/sub-attaq/states.cpp +++ b/examples/widgets/animation/sub-attaq/states.cpp @@ -67,11 +67,8 @@ #include PlayState::PlayState(GraphicsScene *scene, QState *parent) - : QState(parent), - scene(scene), - machine(0), - currentLevel(0), - score(0) + : QState(parent), scene(scene), machine(nullptr), + currentLevel(0), score(0) { } diff --git a/examples/widgets/desktop/systray/main.cpp b/examples/widgets/desktop/systray/main.cpp index 49b0e10412..4e3e628767 100644 --- a/examples/widgets/desktop/systray/main.cpp +++ b/examples/widgets/desktop/systray/main.cpp @@ -62,7 +62,7 @@ int main(int argc, char *argv[]) QApplication app(argc, argv); if (!QSystemTrayIcon::isSystemTrayAvailable()) { - QMessageBox::critical(0, QObject::tr("Systray"), + QMessageBox::critical(nullptr, QObject::tr("Systray"), QObject::tr("I couldn't detect any system tray " "on this system.")); return 1; diff --git a/examples/widgets/desktop/systray/window.cpp b/examples/widgets/desktop/systray/window.cpp index 05944c92a7..31fcd84821 100644 --- a/examples/widgets/desktop/systray/window.cpp +++ b/examples/widgets/desktop/systray/window.cpp @@ -176,7 +176,7 @@ void Window::showMessage() //! [6] void Window::messageClicked() { - QMessageBox::information(0, tr("Systray"), + QMessageBox::information(nullptr, tr("Systray"), tr("Sorry, I already gave what help I could.\n" "Maybe you should try asking a human?")); } diff --git a/examples/widgets/dialogs/classwizard/classwizard.cpp b/examples/widgets/dialogs/classwizard/classwizard.cpp index 3eab2f5fb2..81adf85b0d 100644 --- a/examples/widgets/dialogs/classwizard/classwizard.cpp +++ b/examples/widgets/dialogs/classwizard/classwizard.cpp @@ -139,7 +139,7 @@ void ClassWizard::accept() QFile headerFile(outputDir + '/' + header); if (!headerFile.open(QFile::WriteOnly | QFile::Text)) { - QMessageBox::warning(0, QObject::tr("Simple Wizard"), + QMessageBox::warning(nullptr, QObject::tr("Simple Wizard"), QObject::tr("Cannot write file %1:\n%2") .arg(headerFile.fileName()) .arg(headerFile.errorString())); @@ -195,7 +195,7 @@ void ClassWizard::accept() QFile implementationFile(outputDir + '/' + implementation); if (!implementationFile.open(QFile::WriteOnly | QFile::Text)) { - QMessageBox::warning(0, QObject::tr("Simple Wizard"), + QMessageBox::warning(nullptr, QObject::tr("Simple Wizard"), QObject::tr("Cannot write file %1:\n%2") .arg(implementationFile.fileName()) .arg(implementationFile.errorString())); diff --git a/examples/widgets/dialogs/findfiles/window.cpp b/examples/widgets/dialogs/findfiles/window.cpp index 1b16cdcd35..e1f7ccdcc4 100644 --- a/examples/widgets/dialogs/findfiles/window.cpp +++ b/examples/widgets/dialogs/findfiles/window.cpp @@ -182,7 +182,7 @@ QStringList Window::findFiles(const QStringList &files, const QString &text) for (int i = 0; i < files.size(); ++i) { progressDialog.setValue(i); - progressDialog.setLabelText(tr("Searching file number %1 of %n...", 0, files.size()).arg(i)); + progressDialog.setLabelText(tr("Searching file number %1 of %n...", nullptr, files.size()).arg(i)); QCoreApplication::processEvents(); //! [6] @@ -237,7 +237,7 @@ void Window::showFiles(const QStringList &paths) filesTable->setItem(row, 0, fileNameItem); filesTable->setItem(row, 1, sizeItem); } - filesFoundLabel->setText(tr("%n file(s) found (Double click on a file to open it)", 0, paths.size())); + filesFoundLabel->setText(tr("%n file(s) found (Double click on a file to open it)", nullptr, paths.size())); filesFoundLabel->setWordWrap(true); } //! [8] diff --git a/examples/widgets/dialogs/standarddialogs/dialog.cpp b/examples/widgets/dialogs/standarddialogs/dialog.cpp index 74a4131b38..4b59aab887 100644 --- a/examples/widgets/dialogs/standarddialogs/dialog.cpp +++ b/examples/widgets/dialogs/standarddialogs/dialog.cpp @@ -65,7 +65,7 @@ class DialogOptionsWidget : public QGroupBox { public: - explicit DialogOptionsWidget(QWidget *parent = 0); + explicit DialogOptionsWidget(QWidget *parent = nullptr); void addCheckBox(const QString &text, int value); void addSpacer(); @@ -492,7 +492,7 @@ void Dialog::questionMessage() void Dialog::warningMessage() { QMessageBox msgBox(QMessageBox::Warning, tr("QMessageBox::warning()"), - MESSAGE, 0, this); + MESSAGE, nullptr, this); msgBox.setDetailedText(MESSAGE_DETAILS); msgBox.addButton(tr("Save &Again"), QMessageBox::AcceptRole); msgBox.addButton(tr("&Continue"), QMessageBox::RejectRole); diff --git a/examples/widgets/graphicsview/embeddeddialogs/customproxy.cpp b/examples/widgets/graphicsview/embeddeddialogs/customproxy.cpp index c181a03e85..f510ebc07f 100644 --- a/examples/widgets/graphicsview/embeddeddialogs/customproxy.cpp +++ b/examples/widgets/graphicsview/embeddeddialogs/customproxy.cpp @@ -55,7 +55,7 @@ #include CustomProxy::CustomProxy(QGraphicsItem *parent, Qt::WindowFlags wFlags) - : QGraphicsProxyWidget(parent, wFlags), popupShown(false), currentPopup(0) + : QGraphicsProxyWidget(parent, wFlags), popupShown(false), currentPopup(nullptr) { timeLine = new QTimeLine(250, this); connect(timeLine, &QTimeLine::valueChanged, @@ -133,7 +133,7 @@ QVariant CustomProxy::itemChange(GraphicsItemChange change, const QVariant &valu currentPopup->installSceneEventFilter(this); } else if (scene()) { currentPopup->removeSceneEventFilter(this); - currentPopup = 0; + currentPopup = nullptr; } } else if (currentPopup && change == ItemSceneHasChanged) { currentPopup->installSceneEventFilter(this); diff --git a/examples/widgets/graphicsview/embeddeddialogs/main.cpp b/examples/widgets/graphicsview/embeddeddialogs/main.cpp index cbd5dd5890..501405e3ff 100644 --- a/examples/widgets/graphicsview/embeddeddialogs/main.cpp +++ b/examples/widgets/graphicsview/embeddeddialogs/main.cpp @@ -66,7 +66,7 @@ int main(int argc, char *argv[]) for (int y = 0; y < gridSize; ++y) { for (int x = 0; x < gridSize; ++x) { - CustomProxy *proxy = new CustomProxy(0, Qt::Window); + CustomProxy *proxy = new CustomProxy(nullptr, Qt::Window); proxy->setWidget(new EmbeddedDialog); QRectF rect = proxy->boundingRect(); diff --git a/examples/widgets/layouts/borderlayout/borderlayout.cpp b/examples/widgets/layouts/borderlayout/borderlayout.cpp index 9b142584c9..c929d3b2a4 100644 --- a/examples/widgets/layouts/borderlayout/borderlayout.cpp +++ b/examples/widgets/layouts/borderlayout/borderlayout.cpp @@ -98,10 +98,7 @@ int BorderLayout::count() const QLayoutItem *BorderLayout::itemAt(int index) const { ItemWrapper *wrapper = list.value(index); - if (wrapper) - return wrapper->item; - else - return 0; + return wrapper ? wrapper->item : nullptr; } QSize BorderLayout::minimumSize() const @@ -111,7 +108,7 @@ QSize BorderLayout::minimumSize() const void BorderLayout::setGeometry(const QRect &rect) { - ItemWrapper *center = 0; + ItemWrapper *center = nullptr; int eastWidth = 0; int westWidth = 0; int northHeight = 0; @@ -189,7 +186,7 @@ QLayoutItem *BorderLayout::takeAt(int index) ItemWrapper *layoutStruct = list.takeAt(index); return layoutStruct->item; } - return 0; + return nullptr; } void BorderLayout::add(QLayoutItem *item, Position position) diff --git a/examples/widgets/layouts/flowlayout/flowlayout.cpp b/examples/widgets/layouts/flowlayout/flowlayout.cpp index 9203da0ba1..b7064d98b1 100644 --- a/examples/widgets/layouts/flowlayout/flowlayout.cpp +++ b/examples/widgets/layouts/flowlayout/flowlayout.cpp @@ -116,8 +116,7 @@ QLayoutItem *FlowLayout::takeAt(int index) { if (index >= 0 && index < itemList.size()) return itemList.takeAt(index); - else - return 0; + return nullptr; } //! [5] @@ -215,7 +214,7 @@ int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const return -1; } else if (parent->isWidgetType()) { QWidget *pw = static_cast(parent); - return pw->style()->pixelMetric(pm, 0, pw); + return pw->style()->pixelMetric(pm, nullptr, pw); } else { return static_cast(parent)->spacing(); } diff --git a/examples/widgets/mainwindows/mainwindow/colorswatch.cpp b/examples/widgets/mainwindows/mainwindow/colorswatch.cpp index 720f9a2085..240a04c897 100644 --- a/examples/widgets/mainwindows/mainwindow/colorswatch.cpp +++ b/examples/widgets/mainwindows/mainwindow/colorswatch.cpp @@ -584,7 +584,7 @@ void ColorSwatch::changeVerticalTitleBar(bool on) QSize BlueTitleBar::minimumSizeHint() const { QDockWidget *dw = qobject_cast(parentWidget()); - Q_ASSERT(dw != 0); + Q_ASSERT(dw); QSize result(leftPm.width() + rightPm.width(), centerPm.height()); if (dw->features() & QDockWidget::DockWidgetVerticalTitleBar) result.transpose(); @@ -605,7 +605,7 @@ void BlueTitleBar::paintEvent(QPaintEvent*) QRect rect = this->rect(); QDockWidget *dw = qobject_cast(parentWidget()); - Q_ASSERT(dw != 0); + Q_ASSERT(dw); if (dw->features() & QDockWidget::DockWidgetVerticalTitleBar) { QSize s = rect.size(); @@ -632,7 +632,7 @@ void BlueTitleBar::mouseReleaseEvent(QMouseEvent *event) QRect rect = this->rect(); QDockWidget *dw = qobject_cast(parentWidget()); - Q_ASSERT(dw != 0); + Q_ASSERT(dw); if (dw->features() & QDockWidget::DockWidgetVerticalTitleBar) { QPoint p = pos; @@ -676,7 +676,7 @@ void BlueTitleBar::mouseReleaseEvent(QMouseEvent *event) void BlueTitleBar::updateMask() { QDockWidget *dw = qobject_cast(parent()); - Q_ASSERT(dw != 0); + Q_ASSERT(dw); QRect rect = dw->rect(); QPixmap bitmap(dw->size()); diff --git a/examples/widgets/mainwindows/mainwindow/toolbar.cpp b/examples/widgets/mainwindows/mainwindow/toolbar.cpp index 7c96f5b1be..096d3df5a8 100644 --- a/examples/widgets/mainwindows/mainwindow/toolbar.cpp +++ b/examples/widgets/mainwindows/mainwindow/toolbar.cpp @@ -208,7 +208,7 @@ ToolBar::ToolBar(const QString &title, QWidget *parent) void ToolBar::updateMenu() { QMainWindow *mainWindow = qobject_cast(parentWidget()); - Q_ASSERT(mainWindow != 0); + Q_ASSERT(mainWindow); const Qt::ToolBarArea area = mainWindow->toolBarArea(this); const Qt::ToolBarAreas areas = allowedAreas(); @@ -313,7 +313,7 @@ void ToolBar::place(Qt::ToolBarArea area, bool p) return; QMainWindow *mainWindow = qobject_cast(parentWidget()); - Q_ASSERT(mainWindow != 0); + Q_ASSERT(mainWindow); mainWindow->addToolBar(area, this); @@ -355,7 +355,7 @@ void ToolBar::placeBottom(bool p) void ToolBar::insertToolBarBreak() { QMainWindow *mainWindow = qobject_cast(parentWidget()); - Q_ASSERT(mainWindow != 0); + Q_ASSERT(mainWindow); mainWindow->insertToolBarBreak(this); } diff --git a/examples/widgets/mainwindows/mdi/mainwindow.cpp b/examples/widgets/mainwindows/mdi/mainwindow.cpp index 188de1893e..1e87c5a747 100644 --- a/examples/widgets/mainwindows/mdi/mainwindow.cpp +++ b/examples/widgets/mainwindows/mdi/mainwindow.cpp @@ -242,7 +242,7 @@ void MainWindow::about() void MainWindow::updateMenus() { - bool hasMdiChild = (activeMdiChild() != 0); + bool hasMdiChild = (activeMdiChild() != nullptr); saveAct->setEnabled(hasMdiChild); saveAsAct->setEnabled(hasMdiChild); #ifndef QT_NO_CLIPBOARD @@ -483,7 +483,7 @@ MdiChild *MainWindow::activeMdiChild() const { if (QMdiSubWindow *activeSubWindow = mdiArea->activeSubWindow()) return qobject_cast(activeSubWindow->widget()); - return 0; + return nullptr; } QMdiSubWindow *MainWindow::findMdiChild(const QString &fileName) const @@ -495,7 +495,7 @@ QMdiSubWindow *MainWindow::findMdiChild(const QString &fileName) const if (mdiChild->currentFile() == canonicalFilePath) return window; } - return 0; + return nullptr; } void MainWindow::switchLayoutDirection() diff --git a/examples/widgets/mainwindows/sdi/mainwindow.cpp b/examples/widgets/mainwindows/sdi/mainwindow.cpp index d44f7c918d..f3e3af8a1b 100644 --- a/examples/widgets/mainwindows/sdi/mainwindow.cpp +++ b/examples/widgets/mainwindows/sdi/mainwindow.cpp @@ -478,5 +478,5 @@ MainWindow *MainWindow::findMainWindow(const QString &fileName) const return mainWin; } - return 0; + return nullptr; } diff --git a/examples/widgets/widgets/analogclock/analogclock.h b/examples/widgets/widgets/analogclock/analogclock.h index 19e580d1ac..e2486a915f 100644 --- a/examples/widgets/widgets/analogclock/analogclock.h +++ b/examples/widgets/widgets/analogclock/analogclock.h @@ -59,7 +59,7 @@ class AnalogClock : public QWidget Q_OBJECT public: - AnalogClock(QWidget *parent = 0); + AnalogClock(QWidget *parent = nullptr); protected: void paintEvent(QPaintEvent *event) override; diff --git a/examples/widgets/widgets/calculator/button.h b/examples/widgets/widgets/calculator/button.h index 057640700f..7c6f26867f 100644 --- a/examples/widgets/widgets/calculator/button.h +++ b/examples/widgets/widgets/calculator/button.h @@ -59,7 +59,7 @@ class Button : public QToolButton Q_OBJECT public: - explicit Button(const QString &text, QWidget *parent = 0); + explicit Button(const QString &text, QWidget *parent = nullptr); QSize sizeHint() const override; }; diff --git a/examples/widgets/widgets/calculator/calculator.h b/examples/widgets/widgets/calculator/calculator.h index 6d7e336347..937de185e7 100644 --- a/examples/widgets/widgets/calculator/calculator.h +++ b/examples/widgets/widgets/calculator/calculator.h @@ -64,7 +64,7 @@ class Calculator : public QWidget Q_OBJECT public: - Calculator(QWidget *parent = 0); + Calculator(QWidget *parent = nullptr); private slots: void digitClicked(); diff --git a/examples/widgets/widgets/charactermap/characterwidget.h b/examples/widgets/widgets/charactermap/characterwidget.h index 53add51e6f..34e061e96b 100644 --- a/examples/widgets/widgets/charactermap/characterwidget.h +++ b/examples/widgets/widgets/charactermap/characterwidget.h @@ -68,7 +68,7 @@ class CharacterWidget : public QWidget Q_OBJECT public: - CharacterWidget(QWidget *parent = 0); + CharacterWidget(QWidget *parent = nullptr); QSize sizeHint() const override; public slots: diff --git a/examples/widgets/widgets/charactermap/mainwindow.cpp b/examples/widgets/widgets/charactermap/mainwindow.cpp index 76bd8f7799..1b6f77bf30 100644 --- a/examples/widgets/widgets/charactermap/mainwindow.cpp +++ b/examples/widgets/widgets/charactermap/mainwindow.cpp @@ -188,7 +188,7 @@ void MainWindow::filterChanged(int f) const QFontComboBox::FontFilter filter = filterCombo->itemData(f).value(); fontCombo->setFontFilters(filter); - statusBar()->showMessage(tr("%n font(s) found", 0, fontCombo->count())); + statusBar()->showMessage(tr("%n font(s) found", nullptr, fontCombo->count())); } void MainWindow::findSizes(const QFont &font) diff --git a/examples/widgets/widgets/codeeditor/codeeditor.h b/examples/widgets/widgets/codeeditor/codeeditor.h index 65be76d81d..fcfc188cf2 100644 --- a/examples/widgets/widgets/codeeditor/codeeditor.h +++ b/examples/widgets/widgets/codeeditor/codeeditor.h @@ -70,7 +70,7 @@ class CodeEditor : public QPlainTextEdit Q_OBJECT public: - CodeEditor(QWidget *parent = 0); + CodeEditor(QWidget *parent = nullptr); void lineNumberAreaPaintEvent(QPaintEvent *event); int lineNumberAreaWidth(); diff --git a/examples/widgets/widgets/digitalclock/digitalclock.h b/examples/widgets/widgets/digitalclock/digitalclock.h index 4365b965bf..31c12f39ab 100644 --- a/examples/widgets/widgets/digitalclock/digitalclock.h +++ b/examples/widgets/widgets/digitalclock/digitalclock.h @@ -59,7 +59,7 @@ class DigitalClock : public QLCDNumber Q_OBJECT public: - DigitalClock(QWidget *parent = 0); + DigitalClock(QWidget *parent = nullptr); private slots: void showTime(); diff --git a/examples/widgets/widgets/elidedlabel/elidedlabel.h b/examples/widgets/widgets/elidedlabel/elidedlabel.h index 8a2a40f49a..9d4fe5fef3 100644 --- a/examples/widgets/widgets/elidedlabel/elidedlabel.h +++ b/examples/widgets/widgets/elidedlabel/elidedlabel.h @@ -65,7 +65,7 @@ class ElidedLabel : public QFrame Q_PROPERTY(bool isElided READ isElided) public: - explicit ElidedLabel(const QString &text, QWidget *parent = 0); + explicit ElidedLabel(const QString &text, QWidget *parent = nullptr); void setText(const QString &text); const QString & text() const { return content; } diff --git a/examples/widgets/widgets/elidedlabel/testwidget.h b/examples/widgets/widgets/elidedlabel/testwidget.h index 840bc98b40..cd309d2316 100644 --- a/examples/widgets/widgets/elidedlabel/testwidget.h +++ b/examples/widgets/widgets/elidedlabel/testwidget.h @@ -64,7 +64,7 @@ class TestWidget : public QWidget Q_OBJECT public: - TestWidget(QWidget *parent = 0); + TestWidget(QWidget *parent = nullptr); protected: void resizeEvent(QResizeEvent *event) override; diff --git a/examples/widgets/widgets/groupbox/window.h b/examples/widgets/widgets/groupbox/window.h index 566fafa151..1f041fd003 100644 --- a/examples/widgets/widgets/groupbox/window.h +++ b/examples/widgets/widgets/groupbox/window.h @@ -63,7 +63,7 @@ class Window : public QWidget Q_OBJECT public: - Window(QWidget *parent = 0); + Window(QWidget *parent = nullptr); private: QGroupBox *createFirstExclusiveGroup(); diff --git a/examples/widgets/widgets/lineedits/window.cpp b/examples/widgets/widgets/lineedits/window.cpp index 47324589b7..0926f6f20b 100644 --- a/examples/widgets/widgets/lineedits/window.cpp +++ b/examples/widgets/widgets/lineedits/window.cpp @@ -206,7 +206,7 @@ void Window::validatorChanged(int index) { switch (index) { case 0: - validatorLineEdit->setValidator(0); + validatorLineEdit->setValidator(nullptr); break; case 1: validatorLineEdit->setValidator(new QIntValidator( diff --git a/examples/widgets/widgets/movie/movieplayer.h b/examples/widgets/widgets/movie/movieplayer.h index 9fa9604025..7d143bd37c 100644 --- a/examples/widgets/widgets/movie/movieplayer.h +++ b/examples/widgets/widgets/movie/movieplayer.h @@ -70,7 +70,7 @@ class MoviePlayer : public QWidget Q_OBJECT public: - MoviePlayer(QWidget *parent = 0); + MoviePlayer(QWidget *parent = nullptr); void openFile(const QString &fileName); private slots: diff --git a/examples/widgets/widgets/scribble/scribblearea.h b/examples/widgets/widgets/scribble/scribblearea.h index 7729fb5b89..100c45e133 100644 --- a/examples/widgets/widgets/scribble/scribblearea.h +++ b/examples/widgets/widgets/scribble/scribblearea.h @@ -62,7 +62,7 @@ class ScribbleArea : public QWidget Q_OBJECT public: - ScribbleArea(QWidget *parent = 0); + ScribbleArea(QWidget *parent = nullptr); bool openImage(const QString &fileName); bool saveImage(const QString &fileName, const char *fileFormat); diff --git a/examples/widgets/widgets/shapedclock/shapedclock.h b/examples/widgets/widgets/shapedclock/shapedclock.h index 6468d21618..a854d956b3 100644 --- a/examples/widgets/widgets/shapedclock/shapedclock.h +++ b/examples/widgets/widgets/shapedclock/shapedclock.h @@ -59,7 +59,7 @@ class ShapedClock : public QWidget Q_OBJECT public: - ShapedClock(QWidget *parent = 0); + ShapedClock(QWidget *parent = nullptr); QSize sizeHint() const override; protected: diff --git a/examples/widgets/widgets/sliders/slidersgroup.h b/examples/widgets/widgets/sliders/slidersgroup.h index 76dcbee0d8..7be8a3b4f8 100644 --- a/examples/widgets/widgets/sliders/slidersgroup.h +++ b/examples/widgets/widgets/sliders/slidersgroup.h @@ -66,7 +66,7 @@ class SlidersGroup : public QGroupBox public: SlidersGroup(Qt::Orientation orientation, const QString &title, - QWidget *parent = 0); + QWidget *parent = nullptr); signals: void valueChanged(int value); diff --git a/examples/widgets/widgets/styles/widgetgallery.h b/examples/widgets/widgets/styles/widgetgallery.h index ec6edff536..9ee65c21c4 100644 --- a/examples/widgets/widgets/styles/widgetgallery.h +++ b/examples/widgets/widgets/styles/widgetgallery.h @@ -78,7 +78,7 @@ class WidgetGallery : public QDialog Q_OBJECT public: - WidgetGallery(QWidget *parent = 0); + WidgetGallery(QWidget *parent = nullptr); private slots: void changeStyle(const QString &styleName); diff --git a/examples/widgets/widgets/stylesheet/stylesheeteditor.h b/examples/widgets/widgets/stylesheet/stylesheeteditor.h index 65a3018adb..f51af7877c 100644 --- a/examples/widgets/widgets/stylesheet/stylesheeteditor.h +++ b/examples/widgets/widgets/stylesheet/stylesheeteditor.h @@ -60,7 +60,7 @@ class StyleSheetEditor : public QDialog Q_OBJECT public: - StyleSheetEditor(QWidget *parent = 0); + StyleSheetEditor(QWidget *parent = nullptr); private slots: void on_styleCombo_activated(const QString &styleName); diff --git a/examples/widgets/widgets/tablet/tabletapplication.h b/examples/widgets/widgets/tablet/tabletapplication.h index 6b3b2a1730..9b4a4f1886 100644 --- a/examples/widgets/widgets/tablet/tabletapplication.h +++ b/examples/widgets/widgets/tablet/tabletapplication.h @@ -61,15 +61,14 @@ class TabletApplication : public QApplication Q_OBJECT public: - TabletApplication(int &argv, char **args) - : QApplication(argv, args) {} + using QApplication::QApplication; bool event(QEvent *event) override; void setCanvas(TabletCanvas *canvas) { m_canvas = canvas; } private: - TabletCanvas *m_canvas; + TabletCanvas *m_canvas = nullptr; }; //! [0] diff --git a/examples/widgets/widgets/tetrix/tetrixboard.h b/examples/widgets/widgets/tetrix/tetrixboard.h index 7c6871dfbd..86bcfa4d6e 100644 --- a/examples/widgets/widgets/tetrix/tetrixboard.h +++ b/examples/widgets/widgets/tetrix/tetrixboard.h @@ -67,7 +67,7 @@ class TetrixBoard : public QFrame Q_OBJECT public: - TetrixBoard(QWidget *parent = 0); + TetrixBoard(QWidget *parent = nullptr); void setNextPieceLabel(QLabel *label); QSize sizeHint() const override; diff --git a/examples/widgets/widgets/tooltips/sortingbox.cpp b/examples/widgets/widgets/tooltips/sortingbox.cpp index 766815e8e9..5f8d96f110 100644 --- a/examples/widgets/widgets/tooltips/sortingbox.cpp +++ b/examples/widgets/widgets/tooltips/sortingbox.cpp @@ -64,7 +64,7 @@ SortingBox::SortingBox(QWidget *parent) setBackgroundRole(QPalette::Base); //! [2] - itemInMotion = 0; + itemInMotion = nullptr; //! [3] newCircleButton = createToolButton(tr("New Circle"), @@ -179,7 +179,7 @@ void SortingBox::mouseReleaseEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton && itemInMotion) { moveItemTo(event->pos()); - itemInMotion = 0; + itemInMotion = nullptr; } } //! [13] diff --git a/examples/widgets/widgets/validators/ledwidget.h b/examples/widgets/widgets/validators/ledwidget.h index dcbfb176c2..c4b406db23 100644 --- a/examples/widgets/widgets/validators/ledwidget.h +++ b/examples/widgets/widgets/validators/ledwidget.h @@ -59,7 +59,7 @@ class LEDWidget : public QLabel { Q_OBJECT public: - LEDWidget(QWidget *parent = 0); + LEDWidget(QWidget *parent = nullptr); public slots: void flash(); diff --git a/examples/widgets/widgets/validators/localeselector.h b/examples/widgets/widgets/validators/localeselector.h index 05290eae81..611e2da66e 100644 --- a/examples/widgets/widgets/validators/localeselector.h +++ b/examples/widgets/widgets/validators/localeselector.h @@ -58,7 +58,7 @@ class LocaleSelector : public QComboBox Q_OBJECT public: - LocaleSelector(QWidget *parent = 0); + LocaleSelector(QWidget *parent = nullptr); signals: void localeSelected(const QLocale &locale); diff --git a/examples/widgets/widgets/wiggly/dialog.h b/examples/widgets/widgets/wiggly/dialog.h index a0981dc6b6..357b6354b5 100644 --- a/examples/widgets/widgets/wiggly/dialog.h +++ b/examples/widgets/widgets/wiggly/dialog.h @@ -59,7 +59,7 @@ class Dialog : public QDialog Q_OBJECT public: - explicit Dialog(QWidget *parent = 0); + explicit Dialog(QWidget *parent = nullptr); }; //! [0] diff --git a/examples/widgets/widgets/wiggly/wigglywidget.h b/examples/widgets/widgets/wiggly/wigglywidget.h index 58a7d045e1..1d909c34da 100644 --- a/examples/widgets/widgets/wiggly/wigglywidget.h +++ b/examples/widgets/widgets/wiggly/wigglywidget.h @@ -60,7 +60,7 @@ class WigglyWidget : public QWidget Q_OBJECT public: - WigglyWidget(QWidget *parent = 0); + WigglyWidget(QWidget *parent = nullptr); public slots: void setText(const QString &newText) { text = newText; } diff --git a/examples/widgets/widgets/windowflags/previewwindow.h b/examples/widgets/widgets/windowflags/previewwindow.h index e9efd09507..9bb487e8ab 100644 --- a/examples/widgets/widgets/windowflags/previewwindow.h +++ b/examples/widgets/widgets/windowflags/previewwindow.h @@ -64,7 +64,7 @@ class PreviewWindow : public QWidget Q_OBJECT public: - PreviewWindow(QWidget *parent = 0); + PreviewWindow(QWidget *parent = nullptr); void setWindowFlags(Qt::WindowFlags flags); From e0dc6dce222173bfa8fe20e1f33d24de70ea9fdd Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 17 Dec 2018 08:18:08 +0100 Subject: [PATCH 0895/1650] Android: Set minimum supported version to android-21 With the current distribution, this is 90% of active devices, and it was released in 2014. Qt 5.12 is LTS and will continue to support older Android versions for a long time to come. This is to reduce the testing needed on outdated platforms and allow ourselves to use some newer APIs unconditionally in Qt. Android 21 was chosen because it is the minimum version that supports 64 bit builds. [ChangeLog][Android] Increased the minimum supported Android version to Android 5.0 (API level 21). Fixes: QTBUG-70508 Change-Id: Ia7b4345e42ca05a25a292f11ccbb8cbd692cf8f0 Reviewed-by: BogDan Vatra --- configure.pri | 8 +--- mkspecs/features/android/sdk.prf | 2 +- src/android/jar/jar.pro | 1 - .../qtproject/qt5/android/ExtractStyle.java | 42 +++++-------------- .../qt5/android/QtActivityDelegate.java | 16 ++++--- .../android/bindings/QtActivityLoader.java | 2 +- src/android/templates/AndroidManifest.xml | 2 +- src/corelib/io/qstandardpaths_android.cpp | 14 ++----- .../eglconvenience/qeglplatformcontext.cpp | 8 ---- .../android/androidjniaccessibility.cpp | 5 +-- .../platforms/android/extract-dummy.cpp | 10 ----- src/plugins/platforms/android/extract.cpp | 40 ------------------ src/tools/androiddeployqt/main.cpp | 4 +- 13 files changed, 27 insertions(+), 127 deletions(-) diff --git a/configure.pri b/configure.pri index 1e8f93a41e..df890a7c49 100644 --- a/configure.pri +++ b/configure.pri @@ -618,14 +618,8 @@ defineTest(qtConfOutput_prepareOptions) { target_arch = armeabi-v7a platform = $$eval(config.input.android-ndk-platform) - isEmpty(platform): equals(target_arch, arm64-v8a): \ - platform = android-21 - - isEmpty(platform): equals(target_arch, x86_64): \ - platform = android-21 - isEmpty(platform): \ - platform = android-16 ### the windows configure disagrees ... + platform = android-21 $${currentConfig}.output.devicePro += \ "DEFAULT_ANDROID_SDK_ROOT = $$val_escape(sdk_root)" \ diff --git a/mkspecs/features/android/sdk.prf b/mkspecs/features/android/sdk.prf index eee7ac2d5d..fe7b9a27bd 100644 --- a/mkspecs/features/android/sdk.prf +++ b/mkspecs/features/android/sdk.prf @@ -1,6 +1,6 @@ API_VERSION_TO_USE = $$(ANDROID_API_VERSION) isEmpty(API_VERSION_TO_USE): API_VERSION_TO_USE = $$API_VERSION -isEmpty(API_VERSION_TO_USE): API_VERSION_TO_USE = android-16 +isEmpty(API_VERSION_TO_USE): API_VERSION_TO_USE = android-21 ANDROID_JAR_FILE = $$ANDROID_SDK_ROOT/platforms/$$API_VERSION_TO_USE/android.jar !exists($$ANDROID_JAR_FILE) { diff --git a/src/android/jar/jar.pro b/src/android/jar/jar.pro index bda15a0a00..ac6fc79968 100644 --- a/src/android/jar/jar.pro +++ b/src/android/jar/jar.pro @@ -2,7 +2,6 @@ TARGET = QtAndroid CONFIG += java DESTDIR = $$[QT_INSTALL_PREFIX/get]/jar -API_VERSION = android-16 PATHPREFIX = $$PWD/src/org/qtproject/qt5/android/ diff --git a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java index 3f74383a82..e6de354ac4 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java +++ b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java @@ -89,8 +89,6 @@ import android.view.inputmethod.EditorInfo; public class ExtractStyle { - native static int[] extractChunkInfo(byte[] chunkData); - native static int[] extractNativeChunkInfo(int nativeChunk); native static int[] extractChunkInfo20(byte[] chunkData); native static int[] extractNativeChunkInfo20(long nativeChunk); @@ -345,10 +343,7 @@ public class ExtractStyle { } public void drawPatch(Bitmap bmp, byte[] chunks, RectF dst, Paint paint) { - if (Build.VERSION.SDK_INT > 19) - chunkData = extractChunkInfo20(chunks); - else - chunkData = extractChunkInfo(chunks); + chunkData = extractChunkInfo20(chunks); } } @@ -698,10 +693,6 @@ public class ExtractStyle { json.put("thicknessRatio",gradientStateClass.getField("mThicknessRatio").getFloat(obj)); json.put("innerRadius",gradientStateClass.getField("mInnerRadius").getInt(obj)); json.put("thickness",gradientStateClass.getField("mThickness").getInt(obj)); - if (Build.VERSION.SDK_INT < 20) { - json.put("solidColor",gradientStateClass.getField("mSolidColor").getInt(obj)); - json.put("strokeColor",gradientStateClass.getField("mStrokeColor").getInt(obj)); - } } catch (Exception e) { e.printStackTrace(); } @@ -802,14 +793,7 @@ public class ExtractStyle { Object state = getAccessibleField(NinePatchDrawable.class, "mNinePatchState").get(d); np = (NinePatch) getAccessibleField(state.getClass(), "mNinePatch").get(state); } - if (Build.VERSION.SDK_INT < 19) - return getJsonChunkInfo(extractChunkInfo((byte[]) getAccessibleField(np.getClass(), "mChunk").get(np))); - else - { - if (Build.VERSION.SDK_INT > 19) - return getJsonChunkInfo(extractNativeChunkInfo20(getAccessibleField(np.getClass(), "mNativeChunk").getLong(np))); - return getJsonChunkInfo(extractNativeChunkInfo(getAccessibleField(np.getClass(), "mNativeChunk").getInt(np))); - } + return getJsonChunkInfo(extractNativeChunkInfo20(getAccessibleField(np.getClass(), "mNativeChunk").getLong(np))); } class DrawableCache @@ -1016,16 +1000,12 @@ public class ExtractStyle { json.put("gravity", bitmapDrawable.getGravity()); json.put("tileModeX", bitmapDrawable.getTileModeX()); json.put("tileModeY", bitmapDrawable.getTileModeY()); - if (Build.VERSION.SDK_INT >= 18) { - json.put("antialias", (Boolean) BitmapDrawable.class.getMethod("hasAntiAlias").invoke(bitmapDrawable)); - json.put("mipMap", (Boolean) BitmapDrawable.class.getMethod("hasMipMap").invoke(bitmapDrawable)); - } - if (Build.VERSION.SDK_INT >= 21) { - json.put("tintMode", (PorterDuff.Mode) BitmapDrawable.class.getMethod("getTintMode").invoke(bitmapDrawable)); - ColorStateList tintList = (ColorStateList) BitmapDrawable.class.getMethod("getTint").invoke(bitmapDrawable); - if (tintList != null) - json.put("tintList", getColorStateList(tintList)); - } + json.put("antialias", (Boolean) BitmapDrawable.class.getMethod("hasAntiAlias").invoke(bitmapDrawable)); + json.put("mipMap", (Boolean) BitmapDrawable.class.getMethod("hasMipMap").invoke(bitmapDrawable)); + json.put("tintMode", (PorterDuff.Mode) BitmapDrawable.class.getMethod("getTintMode").invoke(bitmapDrawable)); + ColorStateList tintList = (ColorStateList) BitmapDrawable.class.getMethod("getTint").invoke(bitmapDrawable); + if (tintList != null) + json.put("tintList", getColorStateList(tintList)); } catch (Exception e) { e.printStackTrace(); } @@ -1758,10 +1738,8 @@ public class ExtractStyle { json.put("Switch_switchPadding", a.getDimensionPixelSize(getField(styleableClass, "Switch_switchPadding"), 0)); json.put("Switch_thumbTextPadding", a.getDimensionPixelSize(getField(styleableClass, "Switch_thumbTextPadding"), 0)); - if (Build.VERSION.SDK_INT >= 21) { - json.put("Switch_showText", a.getBoolean(getField(styleableClass, "Switch_showText"), true)); - json.put("Switch_splitTrack", a.getBoolean(getField(styleableClass, "Switch_splitTrack"), false)); - } + json.put("Switch_showText", a.getBoolean(getField(styleableClass, "Switch_showText"), true)); + json.put("Switch_splitTrack", a.getBoolean(getField(styleableClass, "Switch_splitTrack"), false)); a.recycle(); jsonWriter.name(styleName).value(json); diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index 02033859e9..4485ed6338 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -161,15 +161,13 @@ public class QtActivityDelegate m_activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); m_activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); try { - if (Build.VERSION.SDK_INT >= 19) { - int flags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; - flags |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE; - flags |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; - flags |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; - flags |= View.SYSTEM_UI_FLAG_FULLSCREEN; - flags |= View.class.getDeclaredField("SYSTEM_UI_FLAG_IMMERSIVE_STICKY").getInt(null); - m_activity.getWindow().getDecorView().setSystemUiVisibility(flags | View.INVISIBLE); - } + int flags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; + flags |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE; + flags |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; + flags |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; + flags |= View.SYSTEM_UI_FLAG_FULLSCREEN; + flags |= View.class.getDeclaredField("SYSTEM_UI_FLAG_IMMERSIVE_STICKY").getInt(null); + m_activity.getWindow().getDecorView().setSystemUiVisibility(flags | View.INVISIBLE); } catch (Exception e) { e.printStackTrace(); } diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivityLoader.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivityLoader.java index 759daf4393..6beb5e3161 100644 --- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivityLoader.java +++ b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivityLoader.java @@ -132,7 +132,7 @@ public class QtActivityLoader extends QtLoader { return; } - if (Build.VERSION.SDK_INT < 16) { + if (Build.VERSION.SDK_INT < 21) { // fatal error, show the error and quit AlertDialog errorDialog = new AlertDialog.Builder(m_activity).create(); if (m_contextInfo.metaData.containsKey("android.app.unsupported_android_version")) diff --git a/src/android/templates/AndroidManifest.xml b/src/android/templates/AndroidManifest.xml index 966ce23b14..67a4a429f6 100644 --- a/src/android/templates/AndroidManifest.xml +++ b/src/android/templates/AndroidManifest.xml @@ -70,7 +70,7 @@ - + " << ncp->rgrc[0] << ' ' << ncp->rgrc[1] << ' ' << ncp->rgrc[2] << ' ' << ncp->lppos->cx << ',' << ncp->lppos->cy; @@ -973,7 +973,7 @@ QWindowsBaseWindow *QWindowsBaseWindow::baseWindowOf(const QWindow *w) HWND QWindowsBaseWindow::handleOf(const QWindow *w) { const QWindowsBaseWindow *bw = QWindowsBaseWindow::baseWindowOf(w); - return bw ? bw->handle() : HWND(0); + return bw ? bw->handle() : HWND(nullptr); } bool QWindowsBaseWindow::isTopLevel_sys() const @@ -999,7 +999,7 @@ QMargins QWindowsBaseWindow::frameMargins_sys() const void QWindowsBaseWindow::hide_sys() // Normal hide, do not activate other windows. { - SetWindowPos(handle(),0 , 0, 0, 0, 0, + SetWindowPos(handle(), nullptr , 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); } @@ -1068,7 +1068,7 @@ QWindowsForeignWindow::QWindowsForeignWindow(QWindow *window, HWND hwnd) void QWindowsForeignWindow::setParent(const QPlatformWindow *newParentWindow) { const bool wasTopLevel = isTopLevel_sys(); - const HWND newParent = newParentWindow ? reinterpret_cast(newParentWindow->winId()) : HWND(0); + const HWND newParent = newParentWindow ? reinterpret_cast(newParentWindow->winId()) : HWND(nullptr); const bool isTopLevel = !newParent; const DWORD oldStyle = style(); qCDebug(lcQpaWindows) << __FUNCTION__ << window() << "newParent=" @@ -1299,7 +1299,7 @@ void QWindowsWindow::destroyWindow() #endif DestroyWindow(m_data.hwnd); context->removeWindow(m_data.hwnd); - m_data.hwnd = 0; + m_data.hwnd = nullptr; } } @@ -1348,7 +1348,7 @@ void QWindowsWindow::setDropSiteEnabled(bool dropEnabled) CoLockObjectExternal(m_dropTarget, false, true); m_dropTarget->Release(); RevokeDragDrop(m_data.hwnd); - m_dropTarget = 0; + m_dropTarget = nullptr; } #endif // QT_CONFIG(clipboard) && QT_CONFIG(draganddrop) } @@ -1491,7 +1491,7 @@ void QWindowsWindow::updateTransientParent() const return; // QTBUG-34503, // a popup stays on top, no parent, see also WindowCreationData::fromWindow(). // Update transient parent. const HWND oldTransientParent = GetWindow(m_data.hwnd, GW_OWNER); - HWND newTransientParent = 0; + HWND newTransientParent = nullptr; if (const QWindow *tp = window()->transientParent()) if (const QWindowsWindow *tw = QWindowsWindow::windowsWindowOf(tp)) if (!tw->testFlag(WithinDestroy)) // Prevent destruction by parent window (QTBUG-35499, QTBUG-36666) @@ -1584,7 +1584,7 @@ void QWindowsWindow::show_sys() const if (fakedMaximize) { setStyle(style() & ~WS_MAXIMIZEBOX); - SetWindowPos(m_data.hwnd, 0, 0, 0, 0, 0, + SetWindowPos(m_data.hwnd, nullptr, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_FRAMECHANGED); } @@ -1604,7 +1604,7 @@ void QWindowsWindow::setParent_sys(const QPlatformWindow *parent) { // Use GetAncestor instead of GetParent, as GetParent can return owner window for toplevels HWND oldParentHWND = parentHwnd(); - HWND newParentHWND = 0; + HWND newParentHWND = nullptr; if (parent) { const QWindowsWindow *parentW = static_cast(parent); newParentHWND = parentW->handle(); @@ -1614,13 +1614,13 @@ void QWindowsWindow::setParent_sys(const QPlatformWindow *parent) // NULL handle means desktop window, which also has its proper handle -> disambiguate HWND desktopHwnd = GetDesktopWindow(); if (oldParentHWND == desktopHwnd) - oldParentHWND = 0; + oldParentHWND = nullptr; if (newParentHWND == desktopHwnd) - newParentHWND = 0; + newParentHWND = nullptr; if (newParentHWND != oldParentHWND) { - const bool wasTopLevel = oldParentHWND == 0; - const bool isTopLevel = newParentHWND == 0; + const bool wasTopLevel = oldParentHWND == nullptr; + const bool isTopLevel = newParentHWND == nullptr; setFlag(WithinSetParent); SetParent(m_data.hwnd, newParentHWND); @@ -1847,7 +1847,7 @@ void QWindowsWindow::releaseDC() { if (m_hdc) { ReleaseDC(handle(), m_hdc); - m_hdc = 0; + m_hdc = nullptr; } } @@ -1881,7 +1881,7 @@ bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message, // GL software rendering (QTBUG-58178) and Windows 7/Aero off with some AMD cards // (QTBUG-60527) need InvalidateRect() to suppress artifacts while resizing. if (testFlag(OpenGLSurface) && (isSoftwareGl() || !dwmIsCompositionEnabled())) - InvalidateRect(hwnd, 0, false); + InvalidateRect(hwnd, nullptr, false); BeginPaint(hwnd, &ps); @@ -1889,7 +1889,7 @@ bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message, if (Q_UNLIKELY(!dwmIsCompositionEnabled()) && ((testFlag(OpenGLSurface) && testFlag(OpenGLDoubleBuffered)) || testFlag(VulkanSurface))) { - SelectClipRgn(ps.hdc, NULL); + SelectClipRgn(ps.hdc, nullptr); } // If the a window is obscured by another window (such as a child window) @@ -2100,7 +2100,7 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowStates newState) // it before applying the normal geometry. if (windowVisibility_sys(m_data.hwnd) == QWindow::Maximized) ShowWindow(m_data.hwnd, SW_SHOWNOACTIVATE); - SetWindowPos(m_data.hwnd, 0, m_savedFrameGeometry.x(), m_savedFrameGeometry.y(), + SetWindowPos(m_data.hwnd, nullptr, m_savedFrameGeometry.x(), m_savedFrameGeometry.y(), m_savedFrameGeometry.width(), m_savedFrameGeometry.height(), swpf); if (!wasSync) clearFlag(SynchronousGeometryChangeEvent); @@ -2286,7 +2286,7 @@ static HRGN qRegionToWinRegion(const QRegion ®ion) void QWindowsWindow::setMask(const QRegion ®ion) { if (region.isEmpty()) { - SetWindowRgn(m_data.hwnd, 0, true); + SetWindowRgn(m_data.hwnd, nullptr, true); return; } const HRGN winRegion = qRegionToWinRegion(region); @@ -2319,7 +2319,7 @@ void QWindowsWindow::requestActivateWindow() if (QGuiApplication::applicationState() != Qt::ApplicationActive && QWindowsNativeInterface::windowActivationBehavior() == QWindowsWindowFunctions::AlwaysActivateWindow) { if (const HWND foregroundWindow = GetForegroundWindow()) { - foregroundThread = GetWindowThreadProcessId(foregroundWindow, NULL); + foregroundThread = GetWindowThreadProcessId(foregroundWindow, nullptr); if (foregroundThread && foregroundThread != currentThread) attached = AttachThreadInput(foregroundThread, currentThread, TRUE) == TRUE; if (attached) { @@ -2353,7 +2353,7 @@ bool QWindowsWindow::setKeyboardGrabEnabled(bool grab) context->setKeyGrabber(window()); } else { if (context->keyGrabber() == window()) - context->setKeyGrabber(0); + context->setKeyGrabber(nullptr); } return true; } @@ -2653,7 +2653,7 @@ static HICON createHIcon(const QIcon &icon, int xSize, int ySize) if (!pm.isNull()) return qt_pixmapToWinHICON(pm); } - return 0; + return nullptr; } void QWindowsWindow::setWindowIcon(const QIcon &icon) @@ -2711,7 +2711,7 @@ void QWindowsWindow::setCustomMargins(const QMargins &newCustomMargins) newFrame.moveTo(topLeft); qCDebug(lcQpaWindows) << __FUNCTION__ << oldCustomMargins << "->" << newCustomMargins << currentFrameGeometry << "->" << newFrame; - SetWindowPos(m_data.hwnd, 0, newFrame.x(), newFrame.y(), newFrame.width(), newFrame.height(), SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE); + SetWindowPos(m_data.hwnd, nullptr, newFrame.x(), newFrame.y(), newFrame.width(), newFrame.height(), SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE); } } diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp index fbb5c3b9ec..7980826b49 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp @@ -90,7 +90,7 @@ HWND hwndForAccessible(const QAccessibleInterface *accessible) return QWindowsBaseWindow::handleOf(window); } } - return NULL; + return nullptr; } void clearVariant(VARIANT *variant) From 698078680fc5a6870177af285fa50c0d8a7c0bc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Wed, 9 Jan 2019 16:14:42 +0100 Subject: [PATCH 0976/1650] Schannel: Add ALPN support [ChangeLog][QtNetwork][SSL] The Schannel backend now supports ALPN and thus HTTP/2. Change-Id: I1819a936ec3c9e0118b9dad12681f791262d4db2 Reviewed-by: Timur Pocheptsov --- src/network/ssl/qsslsocket_schannel.cpp | 95 ++++++++++++++++++- tests/auto/network/access/http2/tst_http2.cpp | 3 +- .../network/ssl/qsslsocket/tst_qsslsocket.cpp | 22 ++++- 3 files changed, 114 insertions(+), 6 deletions(-) diff --git a/src/network/ssl/qsslsocket_schannel.cpp b/src/network/ssl/qsslsocket_schannel.cpp index e5f31a3fcf..b10bd546c7 100644 --- a/src/network/ssl/qsslsocket_schannel.cpp +++ b/src/network/ssl/qsslsocket_schannel.cpp @@ -57,6 +57,11 @@ #include #include +#if NTDDI_VERSION >= NTDDI_WINBLUE && !defined(Q_CC_MINGW) +// ALPN = Application Layer Protocol Negotiation +#define SUPPORTS_ALPN 1 +#endif + // Not defined in MinGW #ifndef SECBUFFER_ALERT #define SECBUFFER_ALERT 17 @@ -391,6 +396,40 @@ Required const_reinterpret_cast(Actual *p) return Required(p); } +#ifdef SUPPORTS_ALPN +bool supportsAlpn() +{ + return QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows8_1; +} + +QByteArray createAlpnString(const QByteArrayList &nextAllowedProtocols) +{ + QByteArray alpnString; + if (!nextAllowedProtocols.isEmpty() && supportsAlpn()) { + const QByteArray names = [&nextAllowedProtocols]() { + QByteArray protocolString; + for (QByteArray proto : nextAllowedProtocols) { + if (proto.size() > 255) { + qCWarning(lcSsl) << "TLS ALPN extension" << proto + << "is too long and will be truncated to 255 characters."; + proto = proto.left(255); + } + protocolString += char(proto.length()) + proto; + } + return protocolString; + }(); + + const quint16 namesSize = names.size(); + const quint32 alpnId = SecApplicationProtocolNegotiationExt_ALPN; + const quint32 totalSize = sizeof(alpnId) + sizeof(namesSize) + namesSize; + alpnString = QByteArray::fromRawData(reinterpret_cast(&totalSize), sizeof(totalSize)) + + QByteArray::fromRawData(reinterpret_cast(&alpnId), sizeof(alpnId)) + + QByteArray::fromRawData(reinterpret_cast(&namesSize), sizeof(namesSize)) + + names; + } + return alpnString; +} +#endif // SUPPORTS_ALPN } // anonymous namespace bool QSslSocketPrivate::s_loadRootCertsOnDemand = true; @@ -684,13 +723,28 @@ bool QSslSocketBackendPrivate::createContext() TimeStamp expiry; + SecBufferDesc alpnBufferDesc; + bool useAlpn = false; +#ifdef SUPPORTS_ALPN + configuration.nextProtocolNegotiationStatus = QSslConfiguration::NextProtocolNegotiationNone; + QByteArray alpnString = createAlpnString(configuration.nextAllowedProtocols); + useAlpn = !alpnString.isEmpty(); + SecBuffer alpnBuffers[1]; + alpnBuffers[0] = createSecBuffer(alpnString, SECBUFFER_APPLICATION_PROTOCOLS); + alpnBufferDesc = { + SECBUFFER_VERSION, + ARRAYSIZE(alpnBuffers), + alpnBuffers + }; +#endif + auto status = InitializeSecurityContext(&credentialHandle, // phCredential nullptr, // phContext const_reinterpret_cast(targetName().utf16()), // pszTargetName contextReq, // fContextReq 0, // Reserved1 0, // TargetDataRep (unused) - nullptr, // pInput (no input at the moment @future: alpn) + useAlpn ? &alpnBufferDesc : nullptr, // pInput 0, // Reserved2 &contextHandle, // phNewContext &outputBufferDesc, // pOutput @@ -725,7 +779,19 @@ bool QSslSocketBackendPrivate::acceptContext() SecBuffer inBuffers[2]; inBuffers[0] = createSecBuffer(intermediateBuffer, SECBUFFER_TOKEN); - inBuffers[1] = createSecBuffer(nullptr, 0, SECBUFFER_EMPTY); + +#ifdef SUPPORTS_ALPN + configuration.nextProtocolNegotiationStatus = QSslConfiguration::NextProtocolNegotiationNone; + // The string must be alive when we call AcceptSecurityContext + QByteArray alpnString = createAlpnString(configuration.nextAllowedProtocols); + if (!alpnString.isEmpty()) { + inBuffers[1] = createSecBuffer(alpnString, SECBUFFER_APPLICATION_PROTOCOLS); + } else +#endif + { + inBuffers[1] = createSecBuffer(nullptr, 0, SECBUFFER_EMPTY); + } + SecBufferDesc inputBufferDesc{ SECBUFFER_VERSION, ARRAYSIZE(inBuffers), @@ -931,6 +997,31 @@ bool QSslSocketBackendPrivate::verifyHandshake() SECPKG_ATTR_CONNECTION_INFO, &connectionInfo); CHECK_STATUS(status); + +#ifdef SUPPORTS_ALPN + if (!configuration.nextAllowedProtocols.isEmpty() && supportsAlpn()) { + SecPkgContext_ApplicationProtocol alpn; + status = QueryContextAttributes(&contextHandle, + SECPKG_ATTR_APPLICATION_PROTOCOL, + &alpn); + CHECK_STATUS(status); + if (alpn.ProtoNegoStatus == SecApplicationProtocolNegotiationStatus_Success) { + QByteArray negotiatedProto = QByteArray((const char *)alpn.ProtocolId, + alpn.ProtocolIdSize); + if (!configuration.nextAllowedProtocols.contains(negotiatedProto)) { + setErrorAndEmit(QAbstractSocket::SslHandshakeFailedError, + QSslSocket::tr("Unwanted protocol was negotiated")); + return false; + } + configuration.nextNegotiatedProtocol = negotiatedProto; + configuration.nextProtocolNegotiationStatus = QSslConfiguration::NextProtocolNegotiationNegotiated; + } else { + configuration.nextNegotiatedProtocol = ""; + configuration.nextProtocolNegotiationStatus = QSslConfiguration::NextProtocolNegotiationUnsupported; + } + } +#endif // supports ALPN + #undef CHECK_STATUS // Verify certificate diff --git a/tests/auto/network/access/http2/tst_http2.cpp b/tests/auto/network/access/http2/tst_http2.cpp index 235b78c34a..bbb314128b 100644 --- a/tests/auto/network/access/http2/tst_http2.cpp +++ b/tests/auto/network/access/http2/tst_http2.cpp @@ -50,7 +50,8 @@ #include "emulationdetector.h" -#if !defined(QT_NO_OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(OPENSSL_NO_TLSEXT) +#if (!defined(QT_NO_OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(OPENSSL_NO_TLSEXT)) \ + || QT_CONFIG(schannel) // HTTP/2 over TLS requires ALPN/NPN to negotiate the protocol version. const bool clearTextHTTP2 = false; #else diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index f34a0e8665..1c27901844 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -74,6 +74,16 @@ typedef QSharedPointer QSslSocketPtr; #endif #endif // QT_NO_SSL +// Detect ALPN (Application-Layer Protocol Negotiation) support +#undef ALPN_SUPPORTED // Undef the variable first to be safe +#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(OPENSSL_NO_TLSEXT) +#define ALPN_SUPPORTED 1 +#endif + +#if QT_CONFIG(schannel) && !defined(Q_CC_MINGW) +#define ALPN_SUPPORTED 1 +#endif + #if defined Q_OS_HPUX && defined Q_CC_GNU // This error is delivered every time we try to use the fluke CA // certificate. For now we work around this bug. Task 202317. @@ -3416,12 +3426,20 @@ void tst_QSslSocket::setEmptyDefaultConfiguration() // this test should be last, void tst_QSslSocket::allowedProtocolNegotiation() { -#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(OPENSSL_NO_TLSEXT) +#ifndef ALPN_SUPPORTED + QSKIP("ALPN is unsupported, skipping test"); +#endif + +#if QT_CONFIG(schannel) + if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8_1) + QSKIP("ALPN is not supported on this version of Windows using Schannel."); +#endif QFETCH_GLOBAL(bool, setProxy); if (setProxy) return; + const QByteArray expectedNegotiated("cool-protocol"); QList serverProtos; serverProtos << expectedNegotiated << "not-so-cool-protocol"; @@ -3449,8 +3467,6 @@ void tst_QSslSocket::allowedProtocolNegotiation() QVERIFY(server.socket->sslConfiguration().nextNegotiatedProtocol() == clientSocket.sslConfiguration().nextNegotiatedProtocol()); QVERIFY(server.socket->sslConfiguration().nextNegotiatedProtocol() == expectedNegotiated); - -#endif // OPENSSL_VERSION_NUMBER } #ifndef QT_NO_OPENSSL From 6358f8e3020bed3aa2fc750f8ed1a8390821bc2f Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 21 Dec 2018 09:08:32 +0100 Subject: [PATCH 0977/1650] QtGui: Unify license headers Change-Id: I0a2553b95b099fdfa83d42e71bdf9a192a6588c7 Reviewed-by: Jani Heikkinen --- .../code/src_gui_math3d_qquaternion.cpp | 49 +++++++----- .../code/src_gui_opengl_qopenglbuffer.cpp | 49 +++++++----- .../code/src_gui_opengl_qopengldebug.cpp | 49 +++++++----- .../code/src_gui_opengl_qopenglfunctions.cpp | 49 +++++++----- .../code/src_gui_vulkan_qvulkanfunctions.cpp | 49 +++++++----- .../code/src_gui_vulkan_qvulkaninstance.cpp | 49 +++++++----- .../code/src_gui_vulkan_qvulkanwindow.cpp | 49 +++++++----- .../kernel/qplatformgraphicsbufferhelper.cpp | 2 +- .../kernel/qplatformgraphicsbufferhelper.h | 2 +- src/gui/kernel/qrasterwindow.cpp | 74 +++++++++---------- src/gui/kernel/qshapedpixmapdndwindow.cpp | 2 +- src/gui/kernel/qshapedpixmapdndwindow_p.h | 2 +- src/gui/kernel/qtestsupport_gui.cpp | 2 +- src/gui/kernel/qtestsupport_gui.h | 2 +- .../qopenglfunctions_4_4_compatibility.cpp | 2 +- src/gui/opengl/qopenglfunctions_4_4_core.cpp | 2 +- .../qopenglfunctions_4_5_compatibility.h | 2 +- src/gui/opengl/qopenglfunctions_4_5_core.cpp | 2 +- src/gui/painting/qpathsimplifier.cpp | 2 +- src/gui/painting/qpathsimplifier_p.h | 2 +- src/gui/text/qdistancefield.cpp | 2 +- src/gui/text/qdistancefield_p.h | 2 +- src/gui/text/qstatictext.cpp | 2 +- src/gui/text/qstatictext.h | 2 +- src/gui/text/qstatictext_p.h | 2 +- src/gui/util/qlayoutpolicy.cpp | 2 +- src/gui/util/qlayoutpolicy_p.h | 2 +- src/gui/util/qshaderlanguage.cpp | 2 +- src/gui/util/qshaderlanguage_p.h | 2 +- src/gui/util/qshadernode.cpp | 2 +- src/gui/util/qshadernode_p.h | 2 +- src/gui/util/qtexturefilehandler_p.h | 2 +- 32 files changed, 271 insertions(+), 194 deletions(-) diff --git a/src/gui/doc/snippets/code/src_gui_math3d_qquaternion.cpp b/src/gui/doc/snippets/code/src_gui_math3d_qquaternion.cpp index b5cd00d5aa..8da438e3a7 100644 --- a/src/gui/doc/snippets/code/src_gui_math3d_qquaternion.cpp +++ b/src/gui/doc/snippets/code/src_gui_math3d_qquaternion.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/gui/doc/snippets/code/src_gui_opengl_qopenglbuffer.cpp b/src/gui/doc/snippets/code/src_gui_opengl_qopenglbuffer.cpp index 4a4a6fe16d..57dc909598 100644 --- a/src/gui/doc/snippets/code/src_gui_opengl_qopenglbuffer.cpp +++ b/src/gui/doc/snippets/code/src_gui_opengl_qopenglbuffer.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/gui/doc/snippets/code/src_gui_opengl_qopengldebug.cpp b/src/gui/doc/snippets/code/src_gui_opengl_qopengldebug.cpp index 4ab84deb3e..e82447a174 100644 --- a/src/gui/doc/snippets/code/src_gui_opengl_qopengldebug.cpp +++ b/src/gui/doc/snippets/code/src_gui_opengl_qopengldebug.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtWidgets module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/gui/doc/snippets/code/src_gui_opengl_qopenglfunctions.cpp b/src/gui/doc/snippets/code/src_gui_opengl_qopenglfunctions.cpp index 68a20dcb7c..e072c110f2 100644 --- a/src/gui/doc/snippets/code/src_gui_opengl_qopenglfunctions.cpp +++ b/src/gui/doc/snippets/code/src_gui_opengl_qopenglfunctions.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/gui/doc/snippets/code/src_gui_vulkan_qvulkanfunctions.cpp b/src/gui/doc/snippets/code/src_gui_vulkan_qvulkanfunctions.cpp index 77c5444df5..0d13873f38 100644 --- a/src/gui/doc/snippets/code/src_gui_vulkan_qvulkanfunctions.cpp +++ b/src/gui/doc/snippets/code/src_gui_vulkan_qvulkanfunctions.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/gui/doc/snippets/code/src_gui_vulkan_qvulkaninstance.cpp b/src/gui/doc/snippets/code/src_gui_vulkan_qvulkaninstance.cpp index c4dd9fea18..14ef9ed2d4 100644 --- a/src/gui/doc/snippets/code/src_gui_vulkan_qvulkaninstance.cpp +++ b/src/gui/doc/snippets/code/src_gui_vulkan_qvulkaninstance.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/gui/doc/snippets/code/src_gui_vulkan_qvulkanwindow.cpp b/src/gui/doc/snippets/code/src_gui_vulkan_qvulkanwindow.cpp index 65eca4a77f..81d51233a3 100644 --- a/src/gui/doc/snippets/code/src_gui_vulkan_qvulkanwindow.cpp +++ b/src/gui/doc/snippets/code/src_gui_vulkan_qvulkanwindow.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtGui module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/gui/kernel/qplatformgraphicsbufferhelper.cpp b/src/gui/kernel/qplatformgraphicsbufferhelper.cpp index c98aead5c2..c67e6d15cb 100644 --- a/src/gui/kernel/qplatformgraphicsbufferhelper.cpp +++ b/src/gui/kernel/qplatformgraphicsbufferhelper.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtPlatformSupport module of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/gui/kernel/qplatformgraphicsbufferhelper.h b/src/gui/kernel/qplatformgraphicsbufferhelper.h index 6307f54a3e..bfe61713d4 100644 --- a/src/gui/kernel/qplatformgraphicsbufferhelper.h +++ b/src/gui/kernel/qplatformgraphicsbufferhelper.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtPlatformSupport module of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/gui/kernel/qrasterwindow.cpp b/src/gui/kernel/qrasterwindow.cpp index c88654e794..70d87347c3 100644 --- a/src/gui/kernel/qrasterwindow.cpp +++ b/src/gui/kernel/qrasterwindow.cpp @@ -1,41 +1,41 @@ /**************************************************************************** - ** - ** Copyright (C) 2016 The Qt Company Ltd. - ** Contact: https://www.qt.io/licensing/ - ** - ** This file is part of the QtGui module of the Qt Toolkit. - ** - ** $QT_BEGIN_LICENSE:LGPL$ - ** Commercial License Usage - ** Licensees holding valid commercial Qt licenses may use this file in - ** accordance with the commercial license agreement provided with the - ** Software or, alternatively, in accordance with the terms contained in - ** a written agreement between you and The Qt Company. For licensing terms - ** and conditions see https://www.qt.io/terms-conditions. For further - ** information use the contact form at https://www.qt.io/contact-us. - ** - ** GNU Lesser General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU Lesser - ** General Public License version 3 as published by the Free Software - ** Foundation and appearing in the file LICENSE.LGPL3 included in the - ** packaging of this file. Please review the following information to - ** ensure the GNU Lesser General Public License version 3 requirements - ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. - ** - ** GNU General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU - ** General Public License version 2.0 or (at your option) the GNU General - ** Public license version 3 or any later version approved by the KDE Free - ** Qt Foundation. The licenses are as published by the Free Software - ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 - ** included in the packaging of this file. Please review the following - ** information to ensure the GNU General Public License requirements will - ** be met: https://www.gnu.org/licenses/gpl-2.0.html and - ** https://www.gnu.org/licenses/gpl-3.0.html. - ** - ** $QT_END_LICENSE$ - ** - ****************************************************************************/ +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ #include "qrasterwindow.h" diff --git a/src/gui/kernel/qshapedpixmapdndwindow.cpp b/src/gui/kernel/qshapedpixmapdndwindow.cpp index 8509eb0961..1a85a5e853 100644 --- a/src/gui/kernel/qshapedpixmapdndwindow.cpp +++ b/src/gui/kernel/qshapedpixmapdndwindow.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/gui/kernel/qshapedpixmapdndwindow_p.h b/src/gui/kernel/qshapedpixmapdndwindow_p.h index 072e7c6aea..d9a6ea4888 100644 --- a/src/gui/kernel/qshapedpixmapdndwindow_p.h +++ b/src/gui/kernel/qshapedpixmapdndwindow_p.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/gui/kernel/qtestsupport_gui.cpp b/src/gui/kernel/qtestsupport_gui.cpp index 8a6f662274..7aad4d8c7d 100644 --- a/src/gui/kernel/qtestsupport_gui.cpp +++ b/src/gui/kernel/qtestsupport_gui.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtTest module of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/gui/kernel/qtestsupport_gui.h b/src/gui/kernel/qtestsupport_gui.h index 82a81e9214..1f0c4f0960 100644 --- a/src/gui/kernel/qtestsupport_gui.h +++ b/src/gui/kernel/qtestsupport_gui.h @@ -3,7 +3,7 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtTest module of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/gui/opengl/qopenglfunctions_4_4_compatibility.cpp b/src/gui/opengl/qopenglfunctions_4_4_compatibility.cpp index a33efd0b95..5c7170b8fa 100644 --- a/src/gui/opengl/qopenglfunctions_4_4_compatibility.cpp +++ b/src/gui/opengl/qopenglfunctions_4_4_compatibility.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB) ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtWidgets module of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/gui/opengl/qopenglfunctions_4_4_core.cpp b/src/gui/opengl/qopenglfunctions_4_4_core.cpp index 019a70087a..54833f9058 100644 --- a/src/gui/opengl/qopenglfunctions_4_4_core.cpp +++ b/src/gui/opengl/qopenglfunctions_4_4_core.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB) ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtWidgets module of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/gui/opengl/qopenglfunctions_4_5_compatibility.h b/src/gui/opengl/qopenglfunctions_4_5_compatibility.h index 7a97085a85..a809c1c90b 100644 --- a/src/gui/opengl/qopenglfunctions_4_5_compatibility.h +++ b/src/gui/opengl/qopenglfunctions_4_5_compatibility.h @@ -4,7 +4,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtWidgets module of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/gui/opengl/qopenglfunctions_4_5_core.cpp b/src/gui/opengl/qopenglfunctions_4_5_core.cpp index 27c0223cf9..a47ebb9ee9 100644 --- a/src/gui/opengl/qopenglfunctions_4_5_core.cpp +++ b/src/gui/opengl/qopenglfunctions_4_5_core.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB) ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtWidgets module of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/gui/painting/qpathsimplifier.cpp b/src/gui/painting/qpathsimplifier.cpp index 40585ec502..4251840bbc 100644 --- a/src/gui/painting/qpathsimplifier.cpp +++ b/src/gui/painting/qpathsimplifier.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtDeclarative module of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/gui/painting/qpathsimplifier_p.h b/src/gui/painting/qpathsimplifier_p.h index 6ef298f6bf..6c0062c592 100644 --- a/src/gui/painting/qpathsimplifier_p.h +++ b/src/gui/painting/qpathsimplifier_p.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtDeclarative module of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/gui/text/qdistancefield.cpp b/src/gui/text/qdistancefield.cpp index e7ca00b3a9..82bb617733 100644 --- a/src/gui/text/qdistancefield.cpp +++ b/src/gui/text/qdistancefield.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtDeclarative module of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/gui/text/qdistancefield_p.h b/src/gui/text/qdistancefield_p.h index 27ab84332c..31cdf7edd2 100644 --- a/src/gui/text/qdistancefield_p.h +++ b/src/gui/text/qdistancefield_p.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtDeclarative module of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp index 0026e3edfb..dd894f4d32 100644 --- a/src/gui/text/qstatictext.cpp +++ b/src/gui/text/qstatictext.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the test suite of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/gui/text/qstatictext.h b/src/gui/text/qstatictext.h index e6a196d865..ada0456b8f 100644 --- a/src/gui/text/qstatictext.h +++ b/src/gui/text/qstatictext.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the test suite of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/gui/text/qstatictext_p.h b/src/gui/text/qstatictext_p.h index c4023488ff..4ec09297c5 100644 --- a/src/gui/text/qstatictext_p.h +++ b/src/gui/text/qstatictext_p.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the test suite of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/gui/util/qlayoutpolicy.cpp b/src/gui/util/qlayoutpolicy.cpp index b2b18c0c8b..507df44a45 100644 --- a/src/gui/util/qlayoutpolicy.cpp +++ b/src/gui/util/qlayoutpolicy.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the Qt Quick Layouts module of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/gui/util/qlayoutpolicy_p.h b/src/gui/util/qlayoutpolicy_p.h index a729a57e8b..d92896e6e3 100644 --- a/src/gui/util/qlayoutpolicy_p.h +++ b/src/gui/util/qlayoutpolicy_p.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the Qt Quick Layouts module of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/gui/util/qshaderlanguage.cpp b/src/gui/util/qshaderlanguage.cpp index f9192f5ff3..efd607ba60 100644 --- a/src/gui/util/qshaderlanguage.cpp +++ b/src/gui/util/qshaderlanguage.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the Qt Quick Layouts module of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/gui/util/qshaderlanguage_p.h b/src/gui/util/qshaderlanguage_p.h index e392a6c7bb..3af967b8c6 100644 --- a/src/gui/util/qshaderlanguage_p.h +++ b/src/gui/util/qshaderlanguage_p.h @@ -3,7 +3,7 @@ ** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the Qt Quick Layouts module of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/gui/util/qshadernode.cpp b/src/gui/util/qshadernode.cpp index 676667ddcf..e570880d1d 100644 --- a/src/gui/util/qshadernode.cpp +++ b/src/gui/util/qshadernode.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the Qt Quick Layouts module of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/gui/util/qshadernode_p.h b/src/gui/util/qshadernode_p.h index 494c87bc18..12ff9b2a2c 100644 --- a/src/gui/util/qshadernode_p.h +++ b/src/gui/util/qshadernode_p.h @@ -3,7 +3,7 @@ ** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the Qt Quick Layouts module of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/gui/util/qtexturefilehandler_p.h b/src/gui/util/qtexturefilehandler_p.h index b808d3e7db..3d4f42526f 100644 --- a/src/gui/util/qtexturefilehandler_p.h +++ b/src/gui/util/qtexturefilehandler_p.h @@ -3,7 +3,7 @@ ** Copyright (C) 2017 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtQuick module of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage From ee561f6fbc031c2c3eb77cf384b9a17ad04e860c Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 21 Dec 2018 11:40:34 +0100 Subject: [PATCH 0978/1650] QtConcurrent: Unify license headers Change-Id: I9492ca18805c9663d48820424557595b8bc7eaa0 Reviewed-by: Jani Heikkinen --- src/concurrent/qtconcurrent_global.h | 2 +- src/concurrent/qtconcurrentcompilertest.h | 2 +- src/concurrent/qtconcurrentexception.h | 2 +- src/concurrent/qtconcurrentfilter.cpp | 2 +- src/concurrent/qtconcurrentfilter.h | 2 +- src/concurrent/qtconcurrentfilterkernel.h | 2 +- src/concurrent/qtconcurrentfunctionwrappers.h | 2 +- src/concurrent/qtconcurrentiteratekernel.cpp | 2 +- src/concurrent/qtconcurrentiteratekernel.h | 2 +- src/concurrent/qtconcurrentmap.cpp | 2 +- src/concurrent/qtconcurrentmap.h | 2 +- src/concurrent/qtconcurrentmapkernel.h | 2 +- src/concurrent/qtconcurrentmedian.h | 2 +- src/concurrent/qtconcurrentreducekernel.h | 2 +- src/concurrent/qtconcurrentrun.cpp | 2 +- src/concurrent/qtconcurrentrun.h | 2 +- src/concurrent/qtconcurrentrunbase.h | 2 +- src/concurrent/qtconcurrentstoredfunctioncall.h | 2 +- src/concurrent/qtconcurrentthreadengine.cpp | 2 +- src/concurrent/qtconcurrentthreadengine.h | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/concurrent/qtconcurrent_global.h b/src/concurrent/qtconcurrent_global.h index b02abd63ea..83c6028e20 100644 --- a/src/concurrent/qtconcurrent_global.h +++ b/src/concurrent/qtconcurrent_global.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the QtConcurrent module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/concurrent/qtconcurrentcompilertest.h b/src/concurrent/qtconcurrentcompilertest.h index 70f82e9904..cddfd06ca1 100644 --- a/src/concurrent/qtconcurrentcompilertest.h +++ b/src/concurrent/qtconcurrentcompilertest.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the QtConcurrent module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/concurrent/qtconcurrentexception.h b/src/concurrent/qtconcurrentexception.h index 9da53fd9e2..8a3986a1a3 100644 --- a/src/concurrent/qtconcurrentexception.h +++ b/src/concurrent/qtconcurrentexception.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the QtConcurrent module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/concurrent/qtconcurrentfilter.cpp b/src/concurrent/qtconcurrentfilter.cpp index c0cbbd3f3d..606a9dbe03 100644 --- a/src/concurrent/qtconcurrentfilter.cpp +++ b/src/concurrent/qtconcurrentfilter.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the QtConcurrent module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/concurrent/qtconcurrentfilter.h b/src/concurrent/qtconcurrentfilter.h index acc794fad8..d01b351ad0 100644 --- a/src/concurrent/qtconcurrentfilter.h +++ b/src/concurrent/qtconcurrentfilter.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the QtConcurrent module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/concurrent/qtconcurrentfilterkernel.h b/src/concurrent/qtconcurrentfilterkernel.h index 4ef5ac0cee..9cbea2e671 100644 --- a/src/concurrent/qtconcurrentfilterkernel.h +++ b/src/concurrent/qtconcurrentfilterkernel.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the QtConcurrent module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/concurrent/qtconcurrentfunctionwrappers.h b/src/concurrent/qtconcurrentfunctionwrappers.h index 0f9eb46999..734bb29df1 100644 --- a/src/concurrent/qtconcurrentfunctionwrappers.h +++ b/src/concurrent/qtconcurrentfunctionwrappers.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the QtConcurrent module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/concurrent/qtconcurrentiteratekernel.cpp b/src/concurrent/qtconcurrentiteratekernel.cpp index 11bdb7e8cd..b65f712547 100644 --- a/src/concurrent/qtconcurrentiteratekernel.cpp +++ b/src/concurrent/qtconcurrentiteratekernel.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the QtConcurrent module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/concurrent/qtconcurrentiteratekernel.h b/src/concurrent/qtconcurrentiteratekernel.h index b543833776..89fd3d2592 100644 --- a/src/concurrent/qtconcurrentiteratekernel.h +++ b/src/concurrent/qtconcurrentiteratekernel.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the QtConcurrent module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/concurrent/qtconcurrentmap.cpp b/src/concurrent/qtconcurrentmap.cpp index a8f1d6496e..157ea14b32 100644 --- a/src/concurrent/qtconcurrentmap.cpp +++ b/src/concurrent/qtconcurrentmap.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the QtConcurrent module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/concurrent/qtconcurrentmap.h b/src/concurrent/qtconcurrentmap.h index ed1f7cedd1..151f03cf56 100644 --- a/src/concurrent/qtconcurrentmap.h +++ b/src/concurrent/qtconcurrentmap.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the QtConcurrent module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/concurrent/qtconcurrentmapkernel.h b/src/concurrent/qtconcurrentmapkernel.h index e8df668791..3424124118 100644 --- a/src/concurrent/qtconcurrentmapkernel.h +++ b/src/concurrent/qtconcurrentmapkernel.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the QtConcurrent module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/concurrent/qtconcurrentmedian.h b/src/concurrent/qtconcurrentmedian.h index 864b2d33d5..cec2431d6f 100644 --- a/src/concurrent/qtconcurrentmedian.h +++ b/src/concurrent/qtconcurrentmedian.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the QtConcurrent module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/concurrent/qtconcurrentreducekernel.h b/src/concurrent/qtconcurrentreducekernel.h index d1a283eb53..0fbc40e02e 100644 --- a/src/concurrent/qtconcurrentreducekernel.h +++ b/src/concurrent/qtconcurrentreducekernel.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the QtConcurrent module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/concurrent/qtconcurrentrun.cpp b/src/concurrent/qtconcurrentrun.cpp index e2e3b3f3af..bbd1f5ec62 100644 --- a/src/concurrent/qtconcurrentrun.cpp +++ b/src/concurrent/qtconcurrentrun.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the QtConcurrent module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/concurrent/qtconcurrentrun.h b/src/concurrent/qtconcurrentrun.h index 7963294ebf..6001010a78 100644 --- a/src/concurrent/qtconcurrentrun.h +++ b/src/concurrent/qtconcurrentrun.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the QtConcurrent module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/concurrent/qtconcurrentrunbase.h b/src/concurrent/qtconcurrentrunbase.h index 303838b73e..aaa1245856 100644 --- a/src/concurrent/qtconcurrentrunbase.h +++ b/src/concurrent/qtconcurrentrunbase.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the QtConcurrent module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/concurrent/qtconcurrentstoredfunctioncall.h b/src/concurrent/qtconcurrentstoredfunctioncall.h index 32a0214a88..209832e5bb 100644 --- a/src/concurrent/qtconcurrentstoredfunctioncall.h +++ b/src/concurrent/qtconcurrentstoredfunctioncall.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the QtConcurrent module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/concurrent/qtconcurrentthreadengine.cpp b/src/concurrent/qtconcurrentthreadengine.cpp index 8d6bd0efb2..968720cbbe 100644 --- a/src/concurrent/qtconcurrentthreadengine.cpp +++ b/src/concurrent/qtconcurrentthreadengine.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the QtConcurrent module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage diff --git a/src/concurrent/qtconcurrentthreadengine.h b/src/concurrent/qtconcurrentthreadengine.h index 69e42018e6..af413707e4 100644 --- a/src/concurrent/qtconcurrentthreadengine.h +++ b/src/concurrent/qtconcurrentthreadengine.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the QtConcurrent module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage From 44cf8cea8e5f496cab637930a942611b9026994a Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 21 Dec 2018 11:55:30 +0100 Subject: [PATCH 0979/1650] QtOpenGL: Unify license headers Change-Id: Ia25b8f9833bd3d941ef73dcc7c6590063fe65329 Reviewed-by: Jani Heikkinen --- .../snippets/code/src_opengl_qglbuffer.cpp | 49 ++++++++++++------- .../snippets/code/src_opengl_qglfunctions.cpp | 49 ++++++++++++------- .../code/src_opengl_qgraphicsshadereffect.cpp | 49 ++++++++++++------- src/opengl/qtopenglglobal.h | 2 +- 4 files changed, 91 insertions(+), 58 deletions(-) diff --git a/src/opengl/doc/snippets/code/src_opengl_qglbuffer.cpp b/src/opengl/doc/snippets/code/src_opengl_qglbuffer.cpp index c9e49826ae..11ef88ab37 100644 --- a/src/opengl/doc/snippets/code/src_opengl_qglbuffer.cpp +++ b/src/opengl/doc/snippets/code/src_opengl_qglbuffer.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtOpenGL module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/opengl/doc/snippets/code/src_opengl_qglfunctions.cpp b/src/opengl/doc/snippets/code/src_opengl_qglfunctions.cpp index 673186dca9..c848ae7ede 100644 --- a/src/opengl/doc/snippets/code/src_opengl_qglfunctions.cpp +++ b/src/opengl/doc/snippets/code/src_opengl_qglfunctions.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtOpenGL module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/opengl/doc/snippets/code/src_opengl_qgraphicsshadereffect.cpp b/src/opengl/doc/snippets/code/src_opengl_qgraphicsshadereffect.cpp index d53b73e837..461e96e094 100644 --- a/src/opengl/doc/snippets/code/src_opengl_qgraphicsshadereffect.cpp +++ b/src/opengl/doc/snippets/code/src_opengl_qgraphicsshadereffect.cpp @@ -3,9 +3,9 @@ ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtOpenGL module of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ +** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the @@ -14,24 +14,35 @@ ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: ** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** diff --git a/src/opengl/qtopenglglobal.h b/src/opengl/qtopenglglobal.h index 6d03264e27..0e821f87b8 100644 --- a/src/opengl/qtopenglglobal.h +++ b/src/opengl/qtopenglglobal.h @@ -3,7 +3,7 @@ ** Copyright (C) 2016 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the QtCore module of the Qt Toolkit. +** This file is part of the QtOpenGL module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage From 11ae0e772cccd3028771c1380f077c605224cc19 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 23 Jan 2019 13:03:44 +0100 Subject: [PATCH 0980/1650] Consume the -skip option in qtbase/configure ...and yield a warning that -skip has no effect in a qtbase build. This is consistent with configure's help output and enables us to always pass "-skip qtwhatnot", whether we're calling top-level or qtbase configure. Change-Id: Ie5b0791a6000d1d78b1367658ad86a92b2ec6a6a Fixes: QTBUG-71253 Reviewed-by: Oliver Wolff Reviewed-by: Kai Koehne --- mkspecs/features/qt_configure.prf | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index c45439c3ef..9998d6971c 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -333,6 +333,15 @@ defineTest(qtConfParseCommandLine) { type = boolean } + isEmpty(type):contains(opt, "skip") { + isEmpty(skipOptionWarningAdded) { + qtConfAddWarning("Command line option -skip is only effective in top-level builds.") + skipOptionWarningAdded = 1 + } + $$qtConfGetNextCommandlineArg() + next() + } + isEmpty(type) { qtConfAddError("Unknown command line option '$$c'.") return() From c2b0bca98429853bcd1f91dff5ae44742b48bc1f Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 24 Jan 2019 15:06:19 +0100 Subject: [PATCH 0981/1650] configure: Respect -continue in qtConfParseCommandLine If configure is called with -continue, it should not stop processing command line arguments after encountering an invalid one. Example: configure ... -continue -quack -no-feature-gui would ignore everything after -quack. Change-Id: Ia5f0cb13414c9c0c7246ff0c72f8e935fe6dca3c Fixes: QTBUG-72912 Reviewed-by: Lars Knoll --- mkspecs/features/qt_configure.prf | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index 9998d6971c..7ca65c92b3 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -344,7 +344,10 @@ defineTest(qtConfParseCommandLine) { isEmpty(type) { qtConfAddError("Unknown command line option '$$c'.") - return() + equals(config.input.continue, yes): \ + next() + else: \ + return() } call = "qtConfCommandline_$${type}" From 775b5e26315f96b29840198a089f82edea52e1a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 22 Jan 2019 16:30:44 +0100 Subject: [PATCH 0982/1650] Remove requirement to lock graphics buffer before getting total size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QPlatformGraphicsBuffer::byteCount() shouldn't need locking unless bytesPerLine() is implemented in a way that requires it, in which case the assert should be in the subclass. Change-Id: I0fdb04c0a3ab042408d6d17b2759509853573d16 Reviewed-by: Laszlo Agocs Reviewed-by: Tor Arne Vestbø --- src/gui/kernel/qplatformgraphicsbuffer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gui/kernel/qplatformgraphicsbuffer.cpp b/src/gui/kernel/qplatformgraphicsbuffer.cpp index cc01efd6db..d361a8fc12 100644 --- a/src/gui/kernel/qplatformgraphicsbuffer.cpp +++ b/src/gui/kernel/qplatformgraphicsbuffer.cpp @@ -237,7 +237,6 @@ uchar *QPlatformGraphicsBuffer::data() */ int QPlatformGraphicsBuffer::byteCount() const { - Q_ASSERT(isLocked() & SWReadAccess); return size().height() * bytesPerLine(); } From 5d181961ea28da07128384aa5144c67d07f87a3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 16 Jan 2019 14:26:02 +0100 Subject: [PATCH 0983/1650] macOS: Don't check for stale SDK unless target needs to be remade Also catches some more variants of SDK mismatch, such as Xcode not being installed at all, or the SDK missing. Change-Id: I184aaa571ef0ea722ca64c54f665462dabc17533 Reviewed-by: Joerg Bornemann Reviewed-by: Timur Pocheptsov Reviewed-by: Simon Hausmann --- mkspecs/features/mac/sdk.mk | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/mkspecs/features/mac/sdk.mk b/mkspecs/features/mac/sdk.mk index c0266f2139..c40f58c987 100644 --- a/mkspecs/features/mac/sdk.mk +++ b/mkspecs/features/mac/sdk.mk @@ -1,12 +1,25 @@ -CURRENT_MAC_SDK_VERSION := $(shell DEVELOPER_DIR=$(EXPORT_QMAKE_XCODE_DEVELOPER_PATH) /usr/bin/xcrun --sdk $(EXPORT_QMAKE_MAC_SDK) -show-sdk-version) -ifneq ($(CURRENT_MAC_SDK_VERSION),$(EXPORT_QMAKE_MAC_SDK_VERSION)) - $(info The platform SDK has been changed from version $(EXPORT_QMAKE_MAC_SDK_VERSION) to version $(CURRENT_MAC_SDK_VERSION).) - $(info This requires a fresh build. Please wipe the build directory completely,) - $(info including any .qmake.stash and .qmake.cache files generated by qmake.) - # FIXME: Ideally this should be advertised as just running make distclean, or we - # should even do it automatically by having proper makefile dependencies between - # .qmake.stash and the SDK version, but as qmake doesn't seem to be consistent in - # how it deals with .qmake.stash as a dependency we need to defer that until later. - $(error ^) +ifeq ($(QT_MAC_SDK_NO_VERSION_CHECK),) + CHECK_SDK_COMMAND = /usr/bin/xcrun --sdk $(EXPORT_QMAKE_MAC_SDK) -show-sdk-version 2>&1 + CURRENT_MAC_SDK_VERSION := $(shell DEVELOPER_DIR=$(EXPORT_QMAKE_XCODE_DEVELOPER_PATH) $(CHECK_SDK_COMMAND)) + ifneq ($(CURRENT_MAC_SDK_VERSION),$(EXPORT_QMAKE_MAC_SDK_VERSION)) + # We don't want to complain about out of date SDK unless the target needs to be remade. + # This covers use-cases such as running 'make check' after moving the build to a + # computer without Xcode or with a different Xcode version. + TARGET_UP_TO_DATE := $(shell QT_MAC_SDK_NO_VERSION_CHECK=1 $(MAKE) --question $(QMAKE_TARGET) && echo 1 || echo 0) + ifeq ($(TARGET_UP_TO_DATE),0) + ifneq ($(findstring missing DEVELOPER_DIR path,$(CURRENT_MAC_SDK_VERSION)),) + $(info The developer dir $(EXPORT_QMAKE_XCODE_DEVELOPER_PATH) is no longer valid.) + else ifneq ($(findstring SDK "$(EXPORT_QMAKE_MAC_SDK)" cannot be located,$(CURRENT_MAC_SDK_VERSION)),) + $(info The developer dir $(EXPORT_QMAKE_XCODE_DEVELOPER_PATH) no longer contains the $(EXPORT_QMAKE_MAC_SDK_VERSION) platform SDK.) + else ifneq ($(CURRENT_MAC_SDK_VERSION),) + $(info The platform SDK has been changed from version $(EXPORT_QMAKE_MAC_SDK_VERSION) to version $(CURRENT_MAC_SDK_VERSION).) + else + $(info Unknown error resolving current platform SDK version.) + endif + $(info This requires a fresh build. Please wipe the build directory completely,) + $(info including any .qmake.stash and .qmake.cache files generated by qmake.) + $(error ^) + endif + endif endif From cf53ed97a113751f3130543e3a1e853d45817dd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 28 Jan 2019 15:18:48 +0100 Subject: [PATCH 0984/1650] macOS: Apply alpha channel to surface format even when non-default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Relying on QSurfaceFormat() to check whether or not we should set the alpha channel size makes it impossible to tweak other properties of the surface format without also having to set the alpha. There's no need to do such as broad comparison, we can check the alpha channel size for its default value instead. Change-Id: Iac31d37c9460eb3e7ec5ee15902f7e5addb48178 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoawindow.mm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index df1ad82592..b0f0d51ecb 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -227,8 +227,9 @@ QSurfaceFormat QCocoaWindow::format() const // Upgrade the default surface format to include an alpha channel. The default RGB format // causes Cocoa to spend an unreasonable amount of time converting it to RGBA internally. - if (format == QSurfaceFormat()) + if (format.alphaBufferSize() < 0) format.setAlphaBufferSize(8); + return format; } From 6abed98e8781a0eebb908e32b9a88cc87492da4d Mon Sep 17 00:00:00 2001 From: David Edmundson Date: Mon, 31 Dec 2018 00:38:05 +0000 Subject: [PATCH 0985/1650] Fixups for GL_CONTEXT_LOST in QOpenGLExtensionMatcher Fixes the rest of the places we use the pattern of emptying the OpenGL error stack to be able to handle GL_CONTEXT_LOST. Change-Id: Ic45024fc6df84d70d60c48831fa586f889af0c0b Reviewed-by: Allan Sandfeld Jensen --- src/gui/opengl/qopengl.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/gui/opengl/qopengl.cpp b/src/gui/opengl/qopengl.cpp index 3a476978e7..987cbe7c12 100644 --- a/src/gui/opengl/qopengl.cpp +++ b/src/gui/opengl/qopengl.cpp @@ -62,6 +62,10 @@ QT_BEGIN_NAMESPACE typedef const GLubyte * (QOPENGLF_APIENTRYP qt_glGetStringi)(GLenum, GLuint); #endif +#ifndef GL_CONTEXT_LOST +#define GL_CONTEXT_LOST 0x0507 +#endif + QOpenGLExtensionMatcher::QOpenGLExtensionMatcher() { QOpenGLContext *ctx = QOpenGLContext::currentContext(); @@ -82,8 +86,13 @@ QOpenGLExtensionMatcher::QOpenGLExtensionMatcher() } else { #ifdef QT_OPENGL_3 // clear error state - while (funcs->glGetError()) {} - + while (true) { // Clear error state. + GLenum error = funcs->glGetError(); + if (error == GL_NO_ERROR) + break; + if (error == GL_CONTEXT_LOST) + return; + }; qt_glGetStringi glGetStringi = (qt_glGetStringi)ctx->getProcAddress("glGetStringi"); if (!glGetStringi) From 201dde1f313ab42b34fe96bd0c630beccca4960e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 29 Jan 2019 09:14:25 +0100 Subject: [PATCH 0986/1650] QFileDialog: Fix deprecation warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix: dialogs/qfiledialog.cpp:3698:43: warning: ‘QDir& QDir::operator=(const QString&)’ is deprecated: Use QDir::setPath() instead [-Wdeprecated-declarations] dir = getEnvironmentVariable(path2); Change-Id: If8d93374cf2900974bcbd14caf2b1ef488409518 Reviewed-by: Christian Ehrlicher --- src/widgets/dialogs/qfiledialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index eb3479b3e0..edaa7854ba 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -3695,7 +3695,7 @@ void QFileDialogPrivate::_q_goToDirectory(const QString &path) } QDir dir(path2); if (!dir.exists()) - dir = getEnvironmentVariable(path2); + dir.setPath(getEnvironmentVariable(path2)); if (dir.exists() || path2.isEmpty() || path2 == model->myComputer().toString()) { _q_enterDirectory(index); From 3615e8aaa158cc88edf539a2252f96a8c635b4cd Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Tue, 11 Dec 2018 10:32:56 +0100 Subject: [PATCH 0987/1650] Doc: Correct minor link issue in qwidget.cpp Change-Id: I3b69a18c65b75f3e0014a12284904af208ef058d Reviewed-by: Paul Wicking Reviewed-by: Venugopal Shivashankar --- src/widgets/kernel/qwidget.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index c66fc098a1..19599cc008 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -4509,8 +4509,7 @@ void QWidget::setForegroundRole(QPalette::ColorRole role) style, depend on third party APIs to render the content of widgets, and these styles typically do not follow the palette. Because of this, assigning roles to a widget's palette is not guaranteed to change the - appearance of the widget. Instead, you may choose to apply a \l - styleSheet. + appearance of the widget. Instead, you may choose to apply a \l {styleSheet}. \warning Do not use this function in conjunction with \l{Qt Style Sheets}. When using style sheets, the palette of a widget can be customized using From 9906cc57ed3eed64d534f43c677bb16e08561bb6 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Tue, 15 Jan 2019 09:58:34 +0100 Subject: [PATCH 0988/1650] testlib: Add BXPASS and BXFAIL Prioritize blacklisting over QEXPECT_FAIL so that a test that is blacklisted no longer fails if QEXPECT_FAIL returns true unexpectedly. To reflect this state properly, the two values of BXPASS and BXFAIL were added to testlib's output. [ChangeLog][Important Behavior Changes][QtTestLib] Blacklisting of tests will be taken into account for XPASS and XFAIL. A blacklisted test that causes an XPASS will no longer be a fail. Task-number: QTBUG-72928 Change-Id: Ia2232fdc714d405fa3fd9aea6c89eb2836bc5950 Reviewed-by: Edward Welbourne --- src/testlib/qabstracttestlogger_p.h | 4 +++- src/testlib/qappletestlogger.cpp | 4 ++++ src/testlib/qplaintestlogger.cpp | 4 ++++ src/testlib/qtaptestlogger.cpp | 6 ++++-- src/testlib/qteamcitylogger.cpp | 4 ++++ src/testlib/qtestlog.cpp | 18 ++++++++++++++++++ src/testlib/qtestlog_p.h | 2 ++ src/testlib/qtestresult.cpp | 13 ++++++++++--- src/testlib/qxmltestlogger.cpp | 4 ++++ src/testlib/qxunittestlogger.cpp | 13 ++++++++++--- .../selftests/blacklisted/tst_blacklisted.cpp | 6 +++--- .../selftests/expected_blacklisted.lightxml | 8 ++++---- .../selftests/expected_blacklisted.teamcity | 3 +-- .../testlib/selftests/expected_blacklisted.txt | 6 +++--- .../testlib/selftests/expected_blacklisted.xml | 8 ++++---- .../selftests/expected_blacklisted.xunitxml | 11 +++-------- 16 files changed, 81 insertions(+), 33 deletions(-) diff --git a/src/testlib/qabstracttestlogger_p.h b/src/testlib/qabstracttestlogger_p.h index 018361b81e..a64e7ea96f 100644 --- a/src/testlib/qabstracttestlogger_p.h +++ b/src/testlib/qabstracttestlogger_p.h @@ -69,7 +69,9 @@ public: Fail, XPass, BlacklistedPass, - BlacklistedFail + BlacklistedFail, + BlacklistedXPass, + BlacklistedXFail }; enum MessageTypes { diff --git a/src/testlib/qappletestlogger.cpp b/src/testlib/qappletestlogger.cpp index 2c1005ad80..8e75da88f8 100644 --- a/src/testlib/qappletestlogger.cpp +++ b/src/testlib/qappletestlogger.cpp @@ -101,6 +101,10 @@ static IncidentClassification incidentTypeToClassification(QAbstractTestLogger:: return IncidentClassification(QtWarningMsg, "bpass"); case QAbstractTestLogger::BlacklistedFail: return IncidentClassification(QtInfoMsg, "bfail"); + case QAbstractTestLogger::BlacklistedXPass: + return IncidentClassification(QtWarningMsg, "bxpass"); + case QAbstractTestLogger::BlacklistedXFail: + return IncidentClassification(QtInfoMsg, "bxfail"); } return IncidentClassification(QtFatalMsg, nullptr); } diff --git a/src/testlib/qplaintestlogger.cpp b/src/testlib/qplaintestlogger.cpp index 853515f2d9..ed53dcdde8 100644 --- a/src/testlib/qplaintestlogger.cpp +++ b/src/testlib/qplaintestlogger.cpp @@ -89,6 +89,10 @@ namespace QTest { return "BPASS "; case QAbstractTestLogger::BlacklistedFail: return "BFAIL "; + case QAbstractTestLogger::BlacklistedXPass: + return "BXPASS "; + case QAbstractTestLogger::BlacklistedXFail: + return "BXFAIL "; } return "??????"; } diff --git a/src/testlib/qtaptestlogger.cpp b/src/testlib/qtaptestlogger.cpp index a81d9d5c8b..540b36e273 100644 --- a/src/testlib/qtaptestlogger.cpp +++ b/src/testlib/qtaptestlogger.cpp @@ -123,13 +123,15 @@ void QTapTestLogger::addIncident(IncidentTypes type, const char *description, return; } - bool ok = type == Pass || type == XPass || type == BlacklistedPass; + bool ok = type == Pass || type == XPass || type == BlacklistedPass || type == BlacklistedXPass; QTestCharBuffer directive; - if (type == XFail || type == XPass || type == BlacklistedFail || type == BlacklistedPass) + if (type == XFail || type == XPass || type == BlacklistedFail || type == BlacklistedPass + || type == BlacklistedXFail || type == BlacklistedXPass) { // We treat expected or blacklisted failures/passes as TODO-failures/passes, // which should be treated as soft issues by consumers. Not all do though :/ QTest::qt_asprintf(&directive, " # TODO %s", description); + } int testNumber = QTestLog::totalCount(); if (type == XFail) { diff --git a/src/testlib/qteamcitylogger.cpp b/src/testlib/qteamcitylogger.cpp index 9cfbe92b7d..577c8e70cd 100644 --- a/src/testlib/qteamcitylogger.cpp +++ b/src/testlib/qteamcitylogger.cpp @@ -66,6 +66,10 @@ namespace QTest { return "BPASS"; case QAbstractTestLogger::BlacklistedFail: return "BFAIL"; + case QAbstractTestLogger::BlacklistedXPass: + return "BXPASS"; + case QAbstractTestLogger::BlacklistedXFail: + return "BXFAIL"; } return "??????"; } diff --git a/src/testlib/qtestlog.cpp b/src/testlib/qtestlog.cpp index 1268730cc6..3285a6d8a7 100644 --- a/src/testlib/qtestlog.cpp +++ b/src/testlib/qtestlog.cpp @@ -455,6 +455,24 @@ void QTestLog::addBFail(const char *msg, const char *file, int line) QTest::TestLoggers::addIncident(QAbstractTestLogger::BlacklistedFail, msg, file, line); } +void QTestLog::addBXPass(const char *msg, const char *file, int line) +{ + QTEST_ASSERT(msg); + QTEST_ASSERT(file); + + ++QTest::blacklists; + + QTest::TestLoggers::addIncident(QAbstractTestLogger::BlacklistedXPass, msg, file, line); +} + +void QTestLog::addBXFail(const char *msg, const char *file, int line) +{ + QTEST_ASSERT(msg); + QTEST_ASSERT(file); + + QTest::TestLoggers::addIncident(QAbstractTestLogger::BlacklistedXFail, msg, file, line); +} + void QTestLog::addSkip(const char *msg, const char *file, int line) { QTEST_ASSERT(msg); diff --git a/src/testlib/qtestlog_p.h b/src/testlib/qtestlog_p.h index 600c078ce2..0bdd6290e1 100644 --- a/src/testlib/qtestlog_p.h +++ b/src/testlib/qtestlog_p.h @@ -80,6 +80,8 @@ public: static void addXPass(const char *msg, const char *file, int line); static void addBPass(const char *msg); static void addBFail(const char *msg, const char *file, int line); + static void addBXPass(const char *msg, const char *file, int line); + static void addBXFail(const char *msg, const char *file, int line); static void addSkip(const char *msg, const char *file, int line); static void addBenchmarkResult(const QBenchmarkResult &result); diff --git a/src/testlib/qtestresult.cpp b/src/testlib/qtestresult.cpp index 88e3407c90..a7a4807e06 100644 --- a/src/testlib/qtestresult.cpp +++ b/src/testlib/qtestresult.cpp @@ -218,17 +218,24 @@ static bool checkStatement(bool statement, const char *msg, const char *file, in { if (statement) { if (QTest::expectFailMode) { - QTestLog::addXPass(msg, file, line); + if (QTest::blacklistCurrentTest) + QTestLog::addBXPass(msg, file, line); + else + QTestLog::addXPass(msg, file, line); + + QTest::failed = true; bool doContinue = (QTest::expectFailMode == QTest::Continue); clearExpectFail(); - QTest::failed = true; return doContinue; } return true; } if (QTest::expectFailMode) { - QTestLog::addXFail(QTest::expectFailComment, file, line); + if (QTest::blacklistCurrentTest) + QTestLog::addBXFail(QTest::expectFailComment, file, line); + else + QTestLog::addXFail(QTest::expectFailComment, file, line); bool doContinue = (QTest::expectFailMode == QTest::Continue); clearExpectFail(); return doContinue; diff --git a/src/testlib/qxmltestlogger.cpp b/src/testlib/qxmltestlogger.cpp index 7153c016c5..c47042c3a0 100644 --- a/src/testlib/qxmltestlogger.cpp +++ b/src/testlib/qxmltestlogger.cpp @@ -91,6 +91,10 @@ namespace QTest { return "bpass"; case QAbstractTestLogger::BlacklistedFail: return "bfail"; + case QAbstractTestLogger::BlacklistedXPass: + return "bxpass"; + case QAbstractTestLogger::BlacklistedXFail: + return "bxfail"; } return "??????"; } diff --git a/src/testlib/qxunittestlogger.cpp b/src/testlib/qxunittestlogger.cpp index ec33c29ae5..336edb5994 100644 --- a/src/testlib/qxunittestlogger.cpp +++ b/src/testlib/qxunittestlogger.cpp @@ -180,6 +180,13 @@ void QXunitTestLogger::addIncident(IncidentTypes type, const char *description, ++failureCounter; typeBuf = "bfail"; break; + case QAbstractTestLogger::BlacklistedXPass: + typeBuf = "bxpass"; + break; + case QAbstractTestLogger::BlacklistedXFail: + ++failureCounter; + typeBuf = "bxfail"; + break; default: typeBuf = "??????"; break; @@ -212,11 +219,11 @@ void QXunitTestLogger::addIncident(IncidentTypes type, const char *description, if (!strcmp(oldResult, "pass")) { overwrite = true; } - else if (!strcmp(oldResult, "bpass")) { + else if (!strcmp(oldResult, "bpass") || !strcmp(oldResult, "bxfail")) { overwrite = (type == QAbstractTestLogger::XPass || type == QAbstractTestLogger::Fail) || (type == QAbstractTestLogger::XFail) - || (type == QAbstractTestLogger::BlacklistedFail); + || (type == QAbstractTestLogger::BlacklistedFail) || (type == QAbstractTestLogger::BlacklistedXPass); } - else if (!strcmp(oldResult, "bfail")) { + else if (!strcmp(oldResult, "bfail") || !strcmp(oldResult, "bxpass")) { overwrite = (type == QAbstractTestLogger::XPass || type == QAbstractTestLogger::Fail) || (type == QAbstractTestLogger::XFail); } else if (!strcmp(oldResult, "xfail")) { diff --git a/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp b/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp index 8578752e22..b25489ca00 100644 --- a/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp +++ b/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp @@ -64,14 +64,14 @@ void tst_Blacklisted::fail() void tst_Blacklisted::xfail() { - QEXPECT_FAIL("", "This test should XFAIL then BFAIL", Abort); + QEXPECT_FAIL("", "This test should BXFAIL then BPASS", Abort); QVERIFY(false); } void tst_Blacklisted::xpass() { - QEXPECT_FAIL("", "This test should XPASS", Abort); - QVERIFY2(true, "This test should XPASS, blacklist ignored for XPASS"); + QEXPECT_FAIL("", "This test should BXPASS", Abort); + QVERIFY2(true, "This test should BXPASS"); } void tst_Blacklisted::messages() diff --git a/tests/auto/testlib/selftests/expected_blacklisted.lightxml b/tests/auto/testlib/selftests/expected_blacklisted.lightxml index 4193628e7c..5cf62ed104 100644 --- a/tests/auto/testlib/selftests/expected_blacklisted.lightxml +++ b/tests/auto/testlib/selftests/expected_blacklisted.lightxml @@ -24,15 +24,15 @@ - - + + - - + + diff --git a/tests/auto/testlib/selftests/expected_blacklisted.teamcity b/tests/auto/testlib/selftests/expected_blacklisted.teamcity index 8180a7ce76..42b75b752b 100644 --- a/tests/auto/testlib/selftests/expected_blacklisted.teamcity +++ b/tests/auto/testlib/selftests/expected_blacklisted.teamcity @@ -7,10 +7,9 @@ ##teamcity[testStarted name='fail()' flowId='tst_Blacklisted'] ##teamcity[testFinished name='fail()' flowId='tst_Blacklisted'] ##teamcity[testStarted name='xfail()' flowId='tst_Blacklisted'] -##teamcity[testStdOut name='xfail()' out='XFAIL |[Loc: qtbase/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp(0)|]: This test should XFAIL then BFAIL' flowId='tst_Blacklisted'] +##teamcity[testFinished name='xfail()' flowId='tst_Blacklisted'] ##teamcity[testFinished name='xfail()' flowId='tst_Blacklisted'] ##teamcity[testStarted name='xpass()' flowId='tst_Blacklisted'] -##teamcity[testFailed name='xpass()' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp(0)|]' details='|'true|' returned TRUE unexpectedly. (This test should XPASS, blacklist ignored for XPASS)' flowId='tst_Blacklisted'] ##teamcity[testFinished name='xpass()' flowId='tst_Blacklisted'] ##teamcity[testStarted name='messages()' flowId='tst_Blacklisted'] ##teamcity[testStdOut name='messages()' out='QWARN: This is a warning that should not appear in silent test output|nWARNING |[Loc: qtbase/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp(0)|]: This is an internal testlib warning that should not appear in silent test output|nQDEBUG: This is a debug message that should not appear in silent test output|nQSYSTEM: This is a critical message that should not appear in silent test output|nQINFO: This is an info message that should not appear in silent test output|nINFO |[Loc: qtbase/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp(0)|]: This is an internal testlib info message that should not appear in silent test output|nQFATAL: This is a fatal error message that should still appear in silent test output' flowId='tst_Blacklisted'] diff --git a/tests/auto/testlib/selftests/expected_blacklisted.txt b/tests/auto/testlib/selftests/expected_blacklisted.txt index 6fa2403b59..fccaa7d8c3 100644 --- a/tests/auto/testlib/selftests/expected_blacklisted.txt +++ b/tests/auto/testlib/selftests/expected_blacklisted.txt @@ -6,10 +6,10 @@ SKIP : tst_Blacklisted::skip() This test should SKIP Loc: [qtbase/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp(0)] BFAIL : tst_Blacklisted::fail() 'false' returned FALSE. (This test should BFAIL) Loc: [qtbase/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp(0)] -XFAIL : tst_Blacklisted::xfail() This test should XFAIL then BFAIL +BXFAIL : tst_Blacklisted::xfail() This test should BXFAIL then BPASS Loc: [qtbase/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp(0)] BPASS : tst_Blacklisted::xfail() -XPASS : tst_Blacklisted::xpass() 'true' returned TRUE unexpectedly. (This test should XPASS, blacklist ignored for XPASS) +BXPASS : tst_Blacklisted::xpass() 'true' returned TRUE unexpectedly. (This test should BXPASS) Loc: [qtbase/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp(0)] QWARN : tst_Blacklisted::messages() This is a warning that should not appear in silent test output WARNING: tst_Blacklisted::messages() This is an internal testlib warning that should not appear in silent test output @@ -22,5 +22,5 @@ INFO : tst_Blacklisted::messages() This is an internal testlib info message th QFATAL : tst_Blacklisted::messages() This is a fatal error message that should still appear in silent test output BFAIL : tst_Blacklisted::messages() Received a fatal error. Loc: [Unknown file(0)] -Totals: 1 passed, 1 failed, 1 skipped, 4 blacklisted, 0ms +Totals: 1 passed, 0 failed, 1 skipped, 5 blacklisted, 0ms ********* Finished testing of tst_Blacklisted ********* diff --git a/tests/auto/testlib/selftests/expected_blacklisted.xml b/tests/auto/testlib/selftests/expected_blacklisted.xml index 443bc6b199..04d7e6c828 100644 --- a/tests/auto/testlib/selftests/expected_blacklisted.xml +++ b/tests/auto/testlib/selftests/expected_blacklisted.xml @@ -26,15 +26,15 @@ - - + + - - + + diff --git a/tests/auto/testlib/selftests/expected_blacklisted.xunitxml b/tests/auto/testlib/selftests/expected_blacklisted.xunitxml index 2752bc18b4..6e192687fb 100644 --- a/tests/auto/testlib/selftests/expected_blacklisted.xunitxml +++ b/tests/auto/testlib/selftests/expected_blacklisted.xunitxml @@ -1,5 +1,5 @@ - + @@ -11,12 +11,8 @@ - - - - - - + + @@ -28,7 +24,6 @@ - From 481db443d502c8ebc169b7256cb696428cf02199 Mon Sep 17 00:00:00 2001 From: Ryan Chu Date: Sun, 27 Jan 2019 23:10:55 +0100 Subject: [PATCH 0989/1650] Regenerate TLS certificates after docker machine resumes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After the system reboots, the docker machine is created, but in a stopped state. As stated in the docker docs, you might get errors when attempting to connect to a machine or pull an image from Docker Hub. For instance, Error checking TLS connection: ... The solution is to regenerate TLS certificates of docker machine after machine resums. Change-Id: I8781ac0f0790aeda6cc778aee9c44d03c2b788d3 Reviewed-by: Jędrzej Nowacki Reviewed-by: Timur Pocheptsov Reviewed-by: Volker Hilsheimer --- tests/auto/testserver.pri | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/auto/testserver.pri b/tests/auto/testserver.pri index 54c8b51d49..73008ea8b3 100644 --- a/tests/auto/testserver.pri +++ b/tests/auto/testserver.pri @@ -154,12 +154,14 @@ isEmpty(TESTSERVER_VERSION) { MACHINE_STATE_CMD = \ docker-machine ls -q --filter "State=Running" --filter "Name=^qt-test-server\$\$" MACHINE_START_CMD = docker-machine start qt-test-server + MACHINE_RECERT = docker-machine regenerate-certs -f qt-test-server PowerShell { testserver_pretest.commands += \ - $$TEST_CMD if (!($$MACHINE_STATE_CMD)) {$$MACHINE_START_CMD} && + $$TEST_CMD if (!($$MACHINE_STATE_CMD)) {$$MACHINE_START_CMD; $$MACHINE_RECERT} && } else { testserver_pretest.commands += \ - $(if $(shell $$MACHINE_STATE_CMD),,$(shell $$MACHINE_START_CMD > /dev/null)) + $(if $(shell $$MACHINE_STATE_CMD),,\ + $(shell $$MACHINE_START_CMD > /dev/null && $$MACHINE_RECERT > /dev/null)) } } From 4514cf27b27a9b334d49b969760856751d0b227a Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 28 Jan 2019 08:22:33 +0100 Subject: [PATCH 0990/1650] Fix default font properties when using raw fonts for text layouts When a QRawFont is set explicitly on the layout, we would get certain font properties from the QTextCharFormat instead. But when the properties had not been set on the QTextCharFormat, we would get the default values which were always 0/false, not the actual default values used in QFont. Instead, we calculate a QFont query based on the format and use the properties from this. This will give us the correct default values in the cases where they are not overridden. Change-Id: I53e5103739164c3d9eafaf76fcb4e8bda57bd12a Reviewed-by: Lars Knoll --- src/gui/text/qtextengine.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 506df0664d..9ed497839c 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1398,11 +1398,12 @@ void QTextEngine::shapeText(int item) const #ifndef QT_NO_RAWFONT if (useRawFont) { QTextCharFormat f = format(&si); - kerningEnabled = f.fontKerning(); + QFont font = f.font(); + kerningEnabled = font.kerning(); shapingEnabled = QFontEngine::scriptRequiresOpenType(QChar::Script(si.analysis.script)) - || (f.fontStyleStrategy() & QFont::PreferNoShaping) == 0; - wordSpacing = QFixed::fromReal(f.fontWordSpacing()); - letterSpacing = QFixed::fromReal(f.fontLetterSpacing()); + || (font.styleStrategy() & QFont::PreferNoShaping) == 0; + wordSpacing = QFixed::fromReal(font.wordSpacing()); + letterSpacing = QFixed::fromReal(font.letterSpacing()); letterSpacingIsAbsolute = true; } else #endif From 70b3e1fcc532026e164ae08a35981cfd56bc4e4b Mon Sep 17 00:00:00 2001 From: Jesus Fernandez Date: Thu, 10 Jan 2019 16:46:40 +0100 Subject: [PATCH 0991/1650] Fix unused parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Iafad6313fcf74e42c11628ce9ee0f797abfcb6ca Reviewed-by: Thiago Macieira Reviewed-by: Mårten Nordheim Reviewed-by: Edward Welbourne --- src/corelib/tools/qsimd.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp index 1b51b591f7..e44307f28d 100644 --- a/src/corelib/tools/qsimd.cpp +++ b/src/corelib/tools/qsimd.cpp @@ -290,6 +290,10 @@ static void cpuidFeatures07_00(uint &ebx, uint &ecx, uint &edx) ebx = info[1]; ecx = info[2]; edx = info[3]; +#else + Q_UNUSED(ebx); + Q_UNUSED(ecx); + Q_UNUSED(edx); #endif } From 64e8e69d25e08ad81cdb5fb8c2897bc3c0283c9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 11 Jan 2019 06:57:48 +0100 Subject: [PATCH 0992/1650] =?UTF-8?q?Cocoa:=20Don=E2=80=99t=20cache=20acce?= =?UTF-8?q?ssibility=20role?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The object role may in some cases (e.g. when using Qt Quick Loaders) be changed after construction, and we don’t have RoleChanged events. Change-Id: Idb246c1c1206221cacd93c83cbd07a0e3d98cb0e Fixes: QTBUG-72967 Reviewed-by: Frederik Gladhorn Reviewed-by: Jan Arve Sæther --- .../platforms/cocoa/qcocoaaccessibilityelement.mm | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index a1176da33f..f26263261c 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -100,7 +100,6 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of } @implementation QMacAccessibilityElement { - NSString *role; QAccessible::Id axid; } @@ -110,9 +109,6 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of self = [super init]; if (self) { axid = anId; - QAccessibleInterface *iface = QAccessible::accessibleInterface(axid); - Q_ASSERT(iface); - role = QCocoaAccessible::macRole(iface); } return self; @@ -276,11 +272,12 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of } if ([attribute isEqualToString:NSAccessibilityRoleAttribute]) { - return role; + return QCocoaAccessible::macRole(iface); } else if ([attribute isEqualToString:NSAccessibilitySubroleAttribute]) { return QCocoaAccessible::macSubrole(iface); } else if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) { - return NSAccessibilityRoleDescription(role, [self accessibilityAttributeValue:NSAccessibilitySubroleAttribute]); + return NSAccessibilityRoleDescription(QCocoaAccessible::macRole(iface), + [self accessibilityAttributeValue:NSAccessibilitySubroleAttribute]); } else if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) { return QCocoaAccessible::unignoredChildren(iface); } else if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) { From a4767bb9e022b97cdf3a1750dd58f87e7d17ef79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Sun, 21 Oct 2018 22:13:34 +0200 Subject: [PATCH 0993/1650] Wasm: remove debug output. Change-Id: Ieb9c06203626854f9b7c561563c3261510230803 Reviewed-by: Lorn Potter --- src/plugins/platforms/wasm/qwasmwindow.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/platforms/wasm/qwasmwindow.cpp b/src/plugins/platforms/wasm/qwasmwindow.cpp index c4167be71e..25a0190053 100644 --- a/src/plugins/platforms/wasm/qwasmwindow.cpp +++ b/src/plugins/platforms/wasm/qwasmwindow.cpp @@ -53,7 +53,6 @@ QWasmWindow::QWasmWindow(QWindow *w, QWasmCompositor *compositor, QWasmBackingSt m_needsCompositor = w->surfaceType() != QSurface::OpenGLSurface; static int serialNo = 0; m_winid = ++serialNo; - qWarning("QWasmWindow %p: %p 0x%x\n", this, w, uint(m_winid)); m_compositor->addWindow(this); From aa98e6eabe91f5de159141cb2156150b76258ce5 Mon Sep 17 00:00:00 2001 From: Lars Schmertmann Date: Wed, 23 Jan 2019 07:52:53 +0100 Subject: [PATCH 0994/1650] Add a string to the Android manifest to fix a lint warning Unused resources ---------------- Unused resources make applications larger and slow down builds. Amends e3689949ba5b23decb0ea85741a3f4829696788e. The string was introduced there but not added to the manifest. Task-number: QTBUG-72895 Change-Id: Id07e02074feb15ace2c99e6ace51d8fe407877fa Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/android/templates/AndroidManifest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/android/templates/AndroidManifest.xml b/src/android/templates/AndroidManifest.xml index 678ba4f0bd..100fc99e80 100644 --- a/src/android/templates/AndroidManifest.xml +++ b/src/android/templates/AndroidManifest.xml @@ -48,6 +48,7 @@ + From 744be250bf8dbd3e5065662f55a4655c14aa512c Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 28 Jan 2019 10:25:55 +0100 Subject: [PATCH 0995/1650] Fix building offscreen QPA with Qt XCB Only builds without XCB or with system XCB Change-Id: I1161c5b78c92308ac63c2e2907b9a5d8477ab2f0 Reviewed-by: Gatis Paeglis --- src/plugins/platforms/offscreen/offscreen.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/offscreen/offscreen.pro b/src/plugins/platforms/offscreen/offscreen.pro index 6652cefd86..392ee8bed1 100644 --- a/src/plugins/platforms/offscreen/offscreen.pro +++ b/src/plugins/platforms/offscreen/offscreen.pro @@ -17,7 +17,7 @@ HEADERS = qoffscreenintegration.h \ OTHER_FILES += offscreen.json -qtConfig(xlib):qtConfig(opengl):!qtConfig(opengles2) { +qtConfig(system-xcb):qtConfig(xlib):qtConfig(opengl):!qtConfig(opengles2) { SOURCES += qoffscreenintegration_x11.cpp HEADERS += qoffscreenintegration_x11.h QT += glx_support-private From 49ca66583a46f136b48d31fc5488b5ad69fe7e7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tony=20Saraj=C3=A4rvi?= Date: Mon, 21 Jan 2019 12:07:05 +0200 Subject: [PATCH 0996/1650] Expand blacklisting of qthreadpool to cover linux distros Task-number: QTBUG-38594 Change-Id: I07dccf8ac6ab07e61ddf6090037ea344449724f8 Reviewed-by: Heikki Halmet --- tests/auto/corelib/thread/qthreadpool/BLACKLIST | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/corelib/thread/qthreadpool/BLACKLIST b/tests/auto/corelib/thread/qthreadpool/BLACKLIST index 1c392ce96c..fc49731687 100644 --- a/tests/auto/corelib/thread/qthreadpool/BLACKLIST +++ b/tests/auto/corelib/thread/qthreadpool/BLACKLIST @@ -1,2 +1,3 @@ [expiryTimeoutRace] osx +linux From 5d885c8325f1c1567d08b580399dfd6ce4c5ab97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tony=20Saraj=C3=A4rvi?= Date: Mon, 21 Jan 2019 12:29:32 +0200 Subject: [PATCH 0997/1650] Blacklist qtimer/basic_chrono on macos due to flakiness Task-number: QTBUG-73168 Change-Id: I56b45b7f474bdad73f6cd8514b42475e6107b6be Reviewed-by: Kai Koehne --- tests/auto/corelib/kernel/qtimer/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/corelib/kernel/qtimer/BLACKLIST b/tests/auto/corelib/kernel/qtimer/BLACKLIST index e5136624d8..c31e15f171 100644 --- a/tests/auto/corelib/kernel/qtimer/BLACKLIST +++ b/tests/auto/corelib/kernel/qtimer/BLACKLIST @@ -1,3 +1,5 @@ [remainingTime] windows osx +[basic_chrono] +macos From f383fa4b9c64e319cb9b8a63ca88368ad752db27 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Wed, 30 Jan 2019 01:31:30 +0100 Subject: [PATCH 0998/1650] png: initialize color_type to 0 Fixes ==12==WARNING: MemorySanitizer: use-of-uninitialized-value #0 0x6b8179 in setup_qt /src/qtbase/src/gui/image/qpnghandler.cpp:247:9 on fuzzed file Change-Id: I772d536a0db91665dc16e94751ef507de1064376 Reviewed-by: Eirik Aavitsland --- src/gui/image/qpnghandler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index 8ae03d5d38..110ee1670b 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -234,7 +234,7 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scal png_uint_32 width; png_uint_32 height; int bit_depth; - int color_type; + int color_type = 0; png_bytep trans_alpha = 0; png_color_16p trans_color_p = 0; int num_trans; @@ -678,7 +678,7 @@ QImage::Format QPngHandlerPrivate::readImageFormat() { QImage::Format format = QImage::Format_Invalid; png_uint_32 width, height; - int bit_depth, color_type; + int bit_depth, color_type = 0; png_colorp palette; int num_palette; png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0); From 0bde49bd92b0d4366b91c5cdd1585e0e1fb623bc Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 25 Jan 2019 22:09:46 +0100 Subject: [PATCH 0999/1650] QPictureIO::read(): don't work on dangling pointer QPictureIO::read() is using pictureFormat() when the format has to be guessed. pictureFormat() returns a QByteArray which was implicit casted into a char* and then pointed to uninitialized memory. Fix it by using a QByteArray instead a plain char*. Change-Id: If9ae286ed68134af597f0b0c779789e40f9efaed Reviewed-by: Thiago Macieira --- src/gui/image/qpicture.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp index 7eede5ee26..2f2f85f68d 100644 --- a/src/gui/image/qpicture.cpp +++ b/src/gui/image/qpicture.cpp @@ -1866,7 +1866,7 @@ QList QPictureIO::outputFormats() bool QPictureIO::read() { QFile file; - const char *picture_format; + QByteArray picture_format; QPictureHandler *h; if (d->iodev) { // read from io device @@ -1882,7 +1882,7 @@ bool QPictureIO::read() if (d->frmt.isEmpty()) { // Try to guess format picture_format = pictureFormat(d->iodev); // get picture format - if (!picture_format) { + if (picture_format.isEmpty()) { if (file.isOpen()) { // unknown format file.close(); d->iodev = 0; From 9501e92841d0a97ff5083f0000947a2e795f61a2 Mon Sep 17 00:00:00 2001 From: Jesus Fernandez Date: Wed, 13 Dec 2017 13:43:49 +0100 Subject: [PATCH 1000/1650] Replace executedQuery when executing a new query Only the first successful query was stored in the variable. When a new query is executed the function QSqlResult::setActive was not replacing the last executed query. Fixes: QTBUG-28883 Change-Id: Ib4938c42e6264f9edd0764b4a392da7988f68fc0 Reviewed-by: Andy Shaw --- src/sql/kernel/qsqlresult.cpp | 2 +- .../sql/kernel/qsqlquery/tst_qsqlquery.cpp | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/sql/kernel/qsqlresult.cpp b/src/sql/kernel/qsqlresult.cpp index 915a980bf0..589088238b 100644 --- a/src/sql/kernel/qsqlresult.cpp +++ b/src/sql/kernel/qsqlresult.cpp @@ -386,7 +386,7 @@ const QSqlDriver *QSqlResult::driver() const void QSqlResult::setActive(bool active) { Q_D(QSqlResult); - if (active && d->executedQuery.isEmpty()) + if (active) d->executedQuery = d->sql; d->active = active; diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp index c4cf2e752f..710f26b72d 100644 --- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp @@ -158,6 +158,8 @@ private slots: void lastInsertId(); void lastQuery_data() { generic_data(); } void lastQuery(); + void lastQueryTwoQueries_data() { generic_data(); } + void lastQueryTwoQueries(); void bindBool_data() { generic_data(); } void bindBool(); void psql_bindWithDoubleColonCastOperator_data() { generic_data("QPSQL"); } @@ -2813,6 +2815,25 @@ void tst_QSqlQuery::lastQuery() QCOMPARE( q.executedQuery(), sql ); } +void tst_QSqlQuery::lastQueryTwoQueries() +{ + QFETCH(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + QSqlQuery q(db); + + QString sql = QLatin1String("select * from ") + qtest; + QVERIFY_SQL(q, exec(sql)); + QCOMPARE(q.lastQuery(), sql); + QCOMPARE(q.executedQuery(), sql); + + sql = QLatin1String("select id from ") + qtest; + QVERIFY_SQL(q, exec(sql)); + QCOMPARE(q.lastQuery(), sql); + QCOMPARE(q.executedQuery(), sql); +} + void tst_QSqlQuery::psql_bindWithDoubleColonCastOperator() { QFETCH( QString, dbName ); From d8d2025f06d653b4402651576ede94cf35710d77 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 29 Jan 2019 15:39:57 +0100 Subject: [PATCH 1001/1650] Avoid picking worse formats when matching compatible formats Like we do with fully matching format, pick the first matching one, instead of the last matching one. Fixes: QTBUG-72785 Change-Id: I466e0152a229348b6a3786d5464d1f8ab325d67a Reviewed-by: Gatis Paeglis --- src/platformsupport/glxconvenience/qglxconvenience.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/platformsupport/glxconvenience/qglxconvenience.cpp b/src/platformsupport/glxconvenience/qglxconvenience.cpp index d7cc36627a..238f31994d 100644 --- a/src/platformsupport/glxconvenience/qglxconvenience.cpp +++ b/src/platformsupport/glxconvenience/qglxconvenience.cpp @@ -241,6 +241,8 @@ GLXFBConfig qglx_findConfig(Display *display, int screen , QSurfaceFormat format if (requestedAlpha && actualAlpha < requestedAlpha) continue; compatibleCandidate = candidate; + if (!compatibleCandidate) // Only pick up the first compatible one offered by the server + compatibleCandidate = candidate; if (requestedRed && actualRed != requestedRed) continue; From 8915904e2a56d46bdedf64f9a7a5e331ae9d00e1 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Fri, 25 Jan 2019 12:10:34 +0100 Subject: [PATCH 1002/1650] QMacStyle - fix a weird NSBox geometry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For some reason, displayRectIgnoringOpacity renders NSBox with a smaller height than we asked. So let's ask for more and translate. Change-Id: I6e03ad99d1ccf746c89d58dd37d53d0087f15282 Fixes: QTBUG-71741 Reviewed-by: Tor Arne Vestbø --- src/plugins/styles/mac/qmacstyle_mac.mm | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index 50a657e774..13ef98b840 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -2996,7 +2996,20 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai // inContext:, but only in light mode. In dark mode, we use a custom NSBox subclass, // QDarkNSBox, of type NSBoxCustom. Its appearance is close enough to the real thing so // we can use this for now. - d->drawNSViewInRect(box, opt->rect, p, ^(CGContextRef ctx, const CGRect &rect) { + auto adjustedRect = opt->rect; + bool needTranslation = false; + if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave + && !qt_mac_applicationIsInDarkMode()) { + // Another surprise from AppKit (SDK 10.14) - -displayRectIgnoringOpacity: + // is different from drawRect: for some Apple-known reason box is smaller + // in height than we need, resulting in tab buttons sitting too high/not + // centered. Attempts to play with insets etc did not work - the same wrong + // height. Simple translation is not working (too much space "at bottom"), + // so we make it bigger and translate (otherwise it's clipped at bottom btw). + adjustedRect.adjust(0, 0, 0, 3); + needTranslation = true; + } + d->drawNSViewInRect(box, adjustedRect, p, ^(CGContextRef ctx, const CGRect &rect) { if (QTabWidget *tabWidget = qobject_cast(opt->styleObject)) clipTabBarFrame(opt, this, ctx); CGContextTranslateCTM(ctx, 0, rect.origin.y + rect.size.height); @@ -3005,6 +3018,8 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai || [box isMemberOfClass:QDarkNSBox.class]) { [box drawRect:rect]; } else { + if (needTranslation) + CGContextTranslateCTM(ctx, 0.0, 4.0); [box displayRectIgnoringOpacity:box.bounds inContext:NSGraphicsContext.currentContext]; } }); From 93a803a6de27d9eb57931c431b5f3d074914f693 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Klitzing?= Date: Wed, 28 Nov 2018 14:03:02 +0100 Subject: [PATCH 1003/1650] Fix session resumption with OpenSSL 1.1 OpenSSL 1.1.0 and higher requires SSL_shutdown to mark a session as resumable. QHttpNetworkConnection/Channel tries to re-use one shared SSL context (and the session) for its 'channels'. The session is marked as non-resumable without shutdown sent/received. This makes it useless for QHttpNetworkConnection. See: https://github.com/openssl/openssl/issues/1550 Fixes: QTBUG-71967 Change-Id: Iaaceb18c4c5a090f997f9850981a27f04f1f8b06 Reviewed-by: Edward Welbourne Reviewed-by: Timur Pocheptsov --- src/network/ssl/qsslsocket_openssl.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 2c6c35ef24..b5b098502d 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -418,6 +418,10 @@ bool QSslSocketBackendPrivate::initSslContext() void QSslSocketBackendPrivate::destroySslContext() { if (ssl) { + // We do not send a shutdown alert here. Just mark the session as + // resumable for qhttpnetworkconnection's "optimization", otherwise + // OpenSSL won't start a session resumption. + q_SSL_shutdown(ssl); q_SSL_free(ssl); ssl = nullptr; } From 02280535bea08395871722f733aaaed70c992260 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 10 Dec 2018 14:59:49 +0100 Subject: [PATCH 1004/1650] Update bundled Freetype to 2.9.1 This is required to support the new emoji font on Android 9. [ChangeLog][Freetype] Upgraded bundled Freetype version to 2.9.1. This also adds support for the latest emoji font in use on Android 9. Fixes: QTBUG-70657 Change-Id: I99be72f0d23c20aca122b8fdadd4ded87b2edce1 Reviewed-by: Konstantin Ritt --- src/3rdparty/freetype/README | 18 +- src/3rdparty/freetype/builds/unix/ftsystem.c | 2 +- src/3rdparty/freetype/docs/CHANGES | 728 +++- src/3rdparty/freetype/docs/CUSTOMIZE | 8 +- src/3rdparty/freetype/docs/DEBUG | 4 +- src/3rdparty/freetype/docs/FTL.TXT | 4 +- src/3rdparty/freetype/docs/LICENSE.TXT | 6 +- src/3rdparty/freetype/docs/TODO | 2 +- .../include/freetype/config/ftconfig.h | 150 +- .../include/freetype/config/ftheader.h | 148 +- .../include/freetype/config/ftoption.h | 341 +- .../include/freetype/config/ftstdlib.h | 15 +- .../freetype/include/freetype/freetype.h | 1381 +++++--- .../freetype/include/freetype/ftadvanc.h | 8 +- .../freetype/include/freetype/ftbbox.h | 10 +- .../freetype/include/freetype/ftbdf.h | 8 +- .../freetype/include/freetype/ftbitmap.h | 10 +- .../freetype/include/freetype/ftbzip2.h | 8 +- .../freetype/include/freetype/ftcache.h | 31 +- .../freetype/include/freetype/ftchapters.h | 4 + .../freetype/include/freetype/ftcid.h | 14 +- .../freetype/include/freetype/ftdriver.h | 1225 +++++++ .../freetype/include/freetype/fterrdef.h | 8 +- .../freetype/include/freetype/fterrors.h | 28 +- .../freetype/include/freetype/ftfntfmt.h | 11 +- .../freetype/include/freetype/ftgasp.h | 27 +- .../freetype/include/freetype/ftglyph.h | 23 +- .../freetype/include/freetype/ftgxval.h | 16 +- .../freetype/include/freetype/ftgzip.h | 21 +- .../freetype/include/freetype/ftimage.h | 81 +- .../freetype/include/freetype/ftincrem.h | 21 +- .../freetype/include/freetype/ftlcdfil.h | 198 +- .../freetype/include/freetype/ftlist.h | 8 +- .../freetype/include/freetype/ftlzw.h | 8 +- .../freetype/include/freetype/ftmac.h | 17 +- src/3rdparty/freetype/include/freetype/ftmm.h | 367 +- .../freetype/include/freetype/ftmodapi.h | 94 +- .../freetype/include/freetype/ftmoderr.h | 10 +- .../freetype/include/freetype/ftotval.h | 20 +- .../freetype/include/freetype/ftoutln.h | 28 +- .../freetype/include/freetype/ftparams.h | 205 ++ .../freetype/include/freetype/ftpfr.h | 14 +- .../freetype/include/freetype/ftrender.h | 11 +- .../freetype/include/freetype/ftsizes.h | 8 +- .../freetype/include/freetype/ftsnames.h | 147 +- .../freetype/include/freetype/ftstroke.h | 20 +- .../freetype/include/freetype/ftsynth.h | 8 +- .../freetype/include/freetype/ftsystem.h | 10 +- .../freetype/include/freetype/fttrigon.h | 8 +- .../freetype/include/freetype/fttypes.h | 10 +- .../freetype/include/freetype/ftwinfnt.h | 10 +- .../include/freetype/internal/autohint.h | 8 +- .../include/freetype/internal/cffotypes.h | 108 + .../include/freetype/internal/cfftypes.h | 412 +++ .../include/freetype/internal/ftcalc.h | 52 +- .../include/freetype/internal/ftdebug.h | 8 +- .../include/freetype/internal/ftdrv.h | 400 +++ .../include/freetype/internal/ftgloadr.h | 28 +- .../include/freetype/internal/fthash.h | 136 + .../include/freetype/internal/ftmemory.h | 23 +- .../include/freetype/internal/ftobjs.h | 216 +- .../include/freetype/internal/ftpic.h | 8 +- .../include/freetype/internal/ftpsprop.h | 48 + .../include/freetype/internal/ftrfork.h | 15 +- .../include/freetype/internal/ftserv.h | 305 +- .../include/freetype/internal/ftstream.h | 14 +- .../include/freetype/internal/fttrace.h | 11 +- .../include/freetype/internal/ftvalid.h | 8 +- .../include/freetype/internal/internal.h | 10 +- .../include/freetype/internal/psaux.h | 511 ++- .../include/freetype/internal/pshints.h | 8 +- .../freetype/internal/services/svbdf.h | 8 +- .../freetype/internal/services/svcfftl.h | 112 + .../freetype/internal/services/svcid.h | 8 +- .../freetype/internal/services/svfntfmt.h | 8 +- .../freetype/internal/services/svgldict.h | 15 +- .../freetype/internal/services/svgxval.h | 8 +- .../freetype/internal/services/svkern.h | 8 +- .../freetype/internal/services/svmetric.h | 153 + .../include/freetype/internal/services/svmm.h | 113 +- .../freetype/internal/services/svotval.h | 8 +- .../freetype/internal/services/svpfr.h | 8 +- .../freetype/internal/services/svpostnm.h | 8 +- .../freetype/internal/services/svprop.h | 11 +- .../freetype/internal/services/svpscmap.h | 8 +- .../freetype/internal/services/svpsinfo.h | 8 +- .../freetype/internal/services/svsfnt.h | 8 +- .../freetype/internal/services/svttcmap.h | 8 +- .../freetype/internal/services/svtteng.h | 8 +- .../freetype/internal/services/svttglyf.h | 8 +- .../freetype/internal/services/svwinfnt.h | 8 +- .../freetype/include/freetype/internal/sfnt.h | 48 +- .../include/freetype/internal/t1types.h | 10 +- .../include/freetype/internal/tttypes.h | 283 +- .../freetype/include/freetype/t1tables.h | 21 +- .../freetype/include/freetype/ttnameid.h | 635 ++-- .../freetype/include/freetype/tttables.h | 371 +- .../freetype/include/freetype/tttags.h | 18 +- src/3rdparty/freetype/include/ft2build.h | 8 +- src/3rdparty/freetype/qt_attribution.json | 2 +- src/3rdparty/freetype/src/Jamfile | 2 +- src/3rdparty/freetype/src/autofit/Jamfile | 4 +- src/3rdparty/freetype/src/autofit/afangles.c | 2 +- src/3rdparty/freetype/src/autofit/afblue.c | 654 +++- src/3rdparty/freetype/src/autofit/afblue.cin | 2 +- src/3rdparty/freetype/src/autofit/afblue.dat | 819 ++++- src/3rdparty/freetype/src/autofit/afblue.h | 377 +- src/3rdparty/freetype/src/autofit/afblue.hin | 70 +- src/3rdparty/freetype/src/autofit/afcjk.c | 242 +- src/3rdparty/freetype/src/autofit/afcjk.h | 8 +- src/3rdparty/freetype/src/autofit/afcover.h | 2 +- src/3rdparty/freetype/src/autofit/afdummy.c | 13 +- src/3rdparty/freetype/src/autofit/afdummy.h | 8 +- src/3rdparty/freetype/src/autofit/aferrors.h | 11 +- src/3rdparty/freetype/src/autofit/afglobal.c | 52 +- src/3rdparty/freetype/src/autofit/afglobal.h | 29 +- src/3rdparty/freetype/src/autofit/afhints.c | 260 +- src/3rdparty/freetype/src/autofit/afhints.h | 17 +- src/3rdparty/freetype/src/autofit/afindic.c | 42 +- src/3rdparty/freetype/src/autofit/afindic.h | 8 +- src/3rdparty/freetype/src/autofit/aflatin.c | 1623 ++++++--- src/3rdparty/freetype/src/autofit/aflatin.h | 18 +- src/3rdparty/freetype/src/autofit/aflatin2.c | 70 +- src/3rdparty/freetype/src/autofit/aflatin2.h | 13 +- src/3rdparty/freetype/src/autofit/afloader.c | 593 +++- src/3rdparty/freetype/src/autofit/afloader.h | 13 +- src/3rdparty/freetype/src/autofit/afmodule.c | 231 +- src/3rdparty/freetype/src/autofit/afmodule.h | 10 +- src/3rdparty/freetype/src/autofit/afpic.c | 4 +- src/3rdparty/freetype/src/autofit/afpic.h | 10 +- src/3rdparty/freetype/src/autofit/afranges.c | 1218 ++++--- src/3rdparty/freetype/src/autofit/afranges.h | 12 +- src/3rdparty/freetype/src/autofit/afscript.h | 337 +- src/3rdparty/freetype/src/autofit/afshaper.c | 683 ++++ src/3rdparty/freetype/src/autofit/afshaper.h | 72 + src/3rdparty/freetype/src/autofit/afstyles.h | 296 +- src/3rdparty/freetype/src/autofit/aftypes.h | 78 +- src/3rdparty/freetype/src/autofit/afwarp.c | 5 +- src/3rdparty/freetype/src/autofit/afwarp.h | 8 +- src/3rdparty/freetype/src/autofit/afwrtsys.h | 8 +- src/3rdparty/freetype/src/autofit/autofit.c | 27 +- src/3rdparty/freetype/src/autofit/module.mk | 2 +- src/3rdparty/freetype/src/autofit/rules.mk | 6 +- src/3rdparty/freetype/src/base/Jamfile | 8 +- src/3rdparty/freetype/src/base/basepic.c | 2 +- src/3rdparty/freetype/src/base/basepic.h | 8 +- src/3rdparty/freetype/src/base/ftadvanc.c | 27 +- src/3rdparty/freetype/src/base/ftapi.c | 4 +- src/3rdparty/freetype/src/base/ftbase.c | 13 +- src/3rdparty/freetype/src/base/ftbase.h | 14 +- src/3rdparty/freetype/src/base/ftbbox.c | 28 +- src/3rdparty/freetype/src/base/ftbdf.c | 2 +- src/3rdparty/freetype/src/base/ftbitmap.c | 86 +- src/3rdparty/freetype/src/base/ftcalc.c | 158 +- src/3rdparty/freetype/src/base/ftcid.c | 2 +- src/3rdparty/freetype/src/base/ftdbgmem.c | 43 +- src/3rdparty/freetype/src/base/ftdebug.c | 4 +- src/3rdparty/freetype/src/base/ftfntfmt.c | 2 +- src/3rdparty/freetype/src/base/ftfstype.c | 2 +- src/3rdparty/freetype/src/base/ftgasp.c | 2 +- src/3rdparty/freetype/src/base/ftgloadr.c | 2 +- src/3rdparty/freetype/src/base/ftglyph.c | 68 +- src/3rdparty/freetype/src/base/ftgxval.c | 4 +- src/3rdparty/freetype/src/base/fthash.c | 339 ++ src/3rdparty/freetype/src/base/ftinit.c | 92 +- src/3rdparty/freetype/src/base/ftlcdfil.c | 315 +- src/3rdparty/freetype/src/base/ftmac.c | 46 +- src/3rdparty/freetype/src/base/ftmm.c | 298 +- src/3rdparty/freetype/src/base/ftobjs.c | 922 +++-- src/3rdparty/freetype/src/base/ftotval.c | 2 +- src/3rdparty/freetype/src/base/ftoutln.c | 45 +- src/3rdparty/freetype/src/base/ftpatent.c | 246 +- src/3rdparty/freetype/src/base/ftpfr.c | 2 +- src/3rdparty/freetype/src/base/ftpic.c | 2 +- src/3rdparty/freetype/src/base/ftpsprop.c | 285 ++ src/3rdparty/freetype/src/base/ftrfork.c | 129 +- src/3rdparty/freetype/src/base/ftsnames.c | 60 +- src/3rdparty/freetype/src/base/ftstream.c | 4 +- src/3rdparty/freetype/src/base/ftstroke.c | 9 +- src/3rdparty/freetype/src/base/ftsynth.c | 6 +- src/3rdparty/freetype/src/base/ftsystem.c | 2 +- src/3rdparty/freetype/src/base/fttrigon.c | 5 +- src/3rdparty/freetype/src/base/fttype1.c | 2 +- src/3rdparty/freetype/src/base/ftutil.c | 18 +- src/3rdparty/freetype/src/base/ftver.rc | 61 + src/3rdparty/freetype/src/base/ftwinfnt.c | 2 +- src/3rdparty/freetype/src/base/md5.c | 57 +- src/3rdparty/freetype/src/base/rules.mk | 6 +- src/3rdparty/freetype/src/bdf/Jamfile | 2 +- src/3rdparty/freetype/src/bdf/README | 2 +- src/3rdparty/freetype/src/bdf/bdf.c | 3 +- src/3rdparty/freetype/src/bdf/bdf.h | 27 +- src/3rdparty/freetype/src/bdf/bdfdrivr.c | 188 +- src/3rdparty/freetype/src/bdf/bdfdrivr.h | 6 +- src/3rdparty/freetype/src/bdf/bdferror.h | 8 +- src/3rdparty/freetype/src/bdf/bdflib.c | 625 ++-- src/3rdparty/freetype/src/bzip2/Jamfile | 2 +- src/3rdparty/freetype/src/bzip2/ftbzip2.c | 6 +- src/3rdparty/freetype/src/bzip2/rules.mk | 2 +- src/3rdparty/freetype/src/cache/Jamfile | 2 +- src/3rdparty/freetype/src/cache/ftcache.c | 11 +- src/3rdparty/freetype/src/cache/ftcbasic.c | 91 +- src/3rdparty/freetype/src/cache/ftccache.c | 28 +- src/3rdparty/freetype/src/cache/ftccache.h | 40 +- src/3rdparty/freetype/src/cache/ftccback.h | 9 +- src/3rdparty/freetype/src/cache/ftccmap.c | 21 +- src/3rdparty/freetype/src/cache/ftcerror.h | 11 +- src/3rdparty/freetype/src/cache/ftcglyph.c | 4 +- src/3rdparty/freetype/src/cache/ftcglyph.h | 14 +- src/3rdparty/freetype/src/cache/ftcimage.c | 4 +- src/3rdparty/freetype/src/cache/ftcimage.h | 12 +- src/3rdparty/freetype/src/cache/ftcmanag.c | 39 +- src/3rdparty/freetype/src/cache/ftcmanag.h | 10 +- src/3rdparty/freetype/src/cache/ftcmru.c | 12 +- src/3rdparty/freetype/src/cache/ftcmru.h | 16 +- src/3rdparty/freetype/src/cache/ftcsbits.c | 8 +- src/3rdparty/freetype/src/cache/ftcsbits.h | 12 +- src/3rdparty/freetype/src/cache/rules.mk | 2 +- src/3rdparty/freetype/src/cff/Jamfile | 11 +- src/3rdparty/freetype/src/cff/cff.c | 19 +- src/3rdparty/freetype/src/cff/cffcmap.c | 39 +- src/3rdparty/freetype/src/cff/cffcmap.h | 10 +- src/3rdparty/freetype/src/cff/cffdrivr.c | 598 +++- src/3rdparty/freetype/src/cff/cffdrivr.h | 8 +- src/3rdparty/freetype/src/cff/cfferrs.h | 10 +- src/3rdparty/freetype/src/cff/cffgload.c | 2481 +------------- src/3rdparty/freetype/src/cff/cffgload.h | 192 +- src/3rdparty/freetype/src/cff/cffload.c | 1061 +++++- src/3rdparty/freetype/src/cff/cffload.h | 62 +- src/3rdparty/freetype/src/cff/cffobjs.c | 235 +- src/3rdparty/freetype/src/cff/cffobjs.h | 112 +- src/3rdparty/freetype/src/cff/cffparse.c | 621 +++- src/3rdparty/freetype/src/cff/cffparse.h | 64 +- src/3rdparty/freetype/src/cff/cffpic.c | 2 +- src/3rdparty/freetype/src/cff/cffpic.h | 43 +- src/3rdparty/freetype/src/cff/cfftoken.h | 61 +- src/3rdparty/freetype/src/cff/module.mk | 2 +- src/3rdparty/freetype/src/cff/rules.mk | 19 +- src/3rdparty/freetype/src/cid/Jamfile | 2 +- src/3rdparty/freetype/src/cid/ciderrs.h | 10 +- src/3rdparty/freetype/src/cid/cidgload.c | 123 +- src/3rdparty/freetype/src/cid/cidgload.h | 8 +- src/3rdparty/freetype/src/cid/cidload.c | 171 +- src/3rdparty/freetype/src/cid/cidload.h | 8 +- src/3rdparty/freetype/src/cid/cidobjs.c | 50 +- src/3rdparty/freetype/src/cid/cidobjs.h | 8 +- src/3rdparty/freetype/src/cid/cidparse.c | 115 +- src/3rdparty/freetype/src/cid/cidparse.h | 8 +- src/3rdparty/freetype/src/cid/cidriver.c | 82 +- src/3rdparty/freetype/src/cid/cidriver.h | 8 +- src/3rdparty/freetype/src/cid/cidtoken.h | 2 +- src/3rdparty/freetype/src/cid/module.mk | 2 +- src/3rdparty/freetype/src/cid/rules.mk | 2 +- src/3rdparty/freetype/src/cid/type1cid.c | 8 +- src/3rdparty/freetype/src/gxvalid/Jamfile | 2 +- src/3rdparty/freetype/src/gxvalid/README | 16 +- src/3rdparty/freetype/src/gxvalid/gxvalid.c | 16 +- src/3rdparty/freetype/src/gxvalid/gxvalid.h | 10 +- src/3rdparty/freetype/src/gxvalid/gxvbsln.c | 2 +- src/3rdparty/freetype/src/gxvalid/gxvcommn.c | 29 +- src/3rdparty/freetype/src/gxvalid/gxvcommn.h | 14 +- src/3rdparty/freetype/src/gxvalid/gxverror.h | 10 +- src/3rdparty/freetype/src/gxvalid/gxvfeat.c | 2 +- src/3rdparty/freetype/src/gxvalid/gxvfeat.h | 8 +- src/3rdparty/freetype/src/gxvalid/gxvfgen.c | 4 +- src/3rdparty/freetype/src/gxvalid/gxvjust.c | 4 +- src/3rdparty/freetype/src/gxvalid/gxvkern.c | 6 +- src/3rdparty/freetype/src/gxvalid/gxvlcar.c | 4 +- src/3rdparty/freetype/src/gxvalid/gxvmod.c | 14 +- src/3rdparty/freetype/src/gxvalid/gxvmod.h | 8 +- src/3rdparty/freetype/src/gxvalid/gxvmort.c | 4 +- src/3rdparty/freetype/src/gxvalid/gxvmort.h | 8 +- src/3rdparty/freetype/src/gxvalid/gxvmort0.c | 2 +- src/3rdparty/freetype/src/gxvalid/gxvmort1.c | 4 +- src/3rdparty/freetype/src/gxvalid/gxvmort2.c | 2 +- src/3rdparty/freetype/src/gxvalid/gxvmort4.c | 2 +- src/3rdparty/freetype/src/gxvalid/gxvmort5.c | 2 +- src/3rdparty/freetype/src/gxvalid/gxvmorx.c | 4 +- src/3rdparty/freetype/src/gxvalid/gxvmorx.h | 8 +- src/3rdparty/freetype/src/gxvalid/gxvmorx0.c | 2 +- src/3rdparty/freetype/src/gxvalid/gxvmorx1.c | 2 +- src/3rdparty/freetype/src/gxvalid/gxvmorx2.c | 2 +- src/3rdparty/freetype/src/gxvalid/gxvmorx4.c | 2 +- src/3rdparty/freetype/src/gxvalid/gxvmorx5.c | 2 +- src/3rdparty/freetype/src/gxvalid/gxvopbd.c | 2 +- src/3rdparty/freetype/src/gxvalid/gxvprop.c | 2 +- src/3rdparty/freetype/src/gxvalid/gxvtrak.c | 6 +- src/3rdparty/freetype/src/gxvalid/module.mk | 2 +- src/3rdparty/freetype/src/gxvalid/rules.mk | 2 +- src/3rdparty/freetype/src/gzip/Jamfile | 2 +- src/3rdparty/freetype/src/gzip/ftgzip.c | 38 +- src/3rdparty/freetype/src/gzip/ftzconf.h | 284 ++ src/3rdparty/freetype/src/gzip/rules.mk | 8 +- src/3rdparty/freetype/src/gzip/zlib.h | 4 +- src/3rdparty/freetype/src/gzip/zutil.h | 2 +- src/3rdparty/freetype/src/lzw/Jamfile | 2 +- src/3rdparty/freetype/src/lzw/ftlzw.c | 4 +- src/3rdparty/freetype/src/lzw/ftzopen.c | 16 +- src/3rdparty/freetype/src/lzw/ftzopen.h | 8 +- src/3rdparty/freetype/src/lzw/rules.mk | 2 +- src/3rdparty/freetype/src/otvalid/Jamfile | 2 +- src/3rdparty/freetype/src/otvalid/module.mk | 2 +- src/3rdparty/freetype/src/otvalid/otvalid.c | 5 +- src/3rdparty/freetype/src/otvalid/otvalid.h | 8 +- src/3rdparty/freetype/src/otvalid/otvbase.c | 35 +- src/3rdparty/freetype/src/otvalid/otvcommn.c | 32 +- src/3rdparty/freetype/src/otvalid/otvcommn.h | 60 +- src/3rdparty/freetype/src/otvalid/otverror.h | 10 +- src/3rdparty/freetype/src/otvalid/otvgdef.c | 113 +- src/3rdparty/freetype/src/otvalid/otvgpos.c | 56 +- src/3rdparty/freetype/src/otvalid/otvgpos.h | 8 +- src/3rdparty/freetype/src/otvalid/otvgsub.c | 36 +- src/3rdparty/freetype/src/otvalid/otvjstf.c | 2 +- src/3rdparty/freetype/src/otvalid/otvmath.c | 24 +- src/3rdparty/freetype/src/otvalid/otvmod.c | 12 +- src/3rdparty/freetype/src/otvalid/otvmod.h | 8 +- src/3rdparty/freetype/src/otvalid/rules.mk | 2 +- src/3rdparty/freetype/src/pcf/Jamfile | 2 +- src/3rdparty/freetype/src/pcf/README | 4 +- src/3rdparty/freetype/src/pcf/pcf.c | 8 +- src/3rdparty/freetype/src/pcf/pcf.h | 20 +- src/3rdparty/freetype/src/pcf/pcfdrivr.c | 259 +- src/3rdparty/freetype/src/pcf/pcfdrivr.h | 6 +- src/3rdparty/freetype/src/pcf/pcferror.h | 8 +- src/3rdparty/freetype/src/pcf/pcfread.c | 470 ++- src/3rdparty/freetype/src/pcf/pcfread.h | 6 +- src/3rdparty/freetype/src/pcf/pcfutil.h | 6 +- src/3rdparty/freetype/src/pfr/Jamfile | 2 +- src/3rdparty/freetype/src/pfr/module.mk | 2 +- src/3rdparty/freetype/src/pfr/pfr.c | 11 +- src/3rdparty/freetype/src/pfr/pfrcmap.c | 18 +- src/3rdparty/freetype/src/pfr/pfrcmap.h | 8 +- src/3rdparty/freetype/src/pfr/pfrdrivr.c | 41 +- src/3rdparty/freetype/src/pfr/pfrdrivr.h | 8 +- src/3rdparty/freetype/src/pfr/pfrerror.h | 10 +- src/3rdparty/freetype/src/pfr/pfrgload.c | 67 +- src/3rdparty/freetype/src/pfr/pfrgload.h | 8 +- src/3rdparty/freetype/src/pfr/pfrload.c | 190 +- src/3rdparty/freetype/src/pfr/pfrload.h | 23 +- src/3rdparty/freetype/src/pfr/pfrobjs.c | 45 +- src/3rdparty/freetype/src/pfr/pfrobjs.h | 8 +- src/3rdparty/freetype/src/pfr/pfrsbit.c | 219 +- src/3rdparty/freetype/src/pfr/pfrsbit.h | 11 +- src/3rdparty/freetype/src/pfr/pfrtypes.h | 122 +- src/3rdparty/freetype/src/pfr/rules.mk | 2 +- src/3rdparty/freetype/src/psaux/Jamfile | 12 +- src/3rdparty/freetype/src/psaux/afmparse.c | 11 +- src/3rdparty/freetype/src/psaux/afmparse.h | 8 +- src/3rdparty/freetype/src/psaux/cffdecode.c | 2370 +++++++++++++ src/3rdparty/freetype/src/psaux/cffdecode.h | 64 + src/3rdparty/freetype/src/psaux/module.mk | 2 +- src/3rdparty/freetype/src/psaux/psarrst.c | 241 ++ src/3rdparty/freetype/src/psaux/psarrst.h | 100 + src/3rdparty/freetype/src/psaux/psaux.c | 25 +- src/3rdparty/freetype/src/psaux/psauxerr.h | 10 +- src/3rdparty/freetype/src/psaux/psauxmod.c | 122 +- src/3rdparty/freetype/src/psaux/psauxmod.h | 17 +- src/3rdparty/freetype/src/psaux/psblues.c | 582 ++++ src/3rdparty/freetype/src/psaux/psblues.h | 185 + src/3rdparty/freetype/src/psaux/psconv.c | 10 +- src/3rdparty/freetype/src/psaux/psconv.h | 8 +- src/3rdparty/freetype/src/psaux/pserror.c | 52 + src/3rdparty/freetype/src/psaux/pserror.h | 119 + src/3rdparty/freetype/src/psaux/psfixed.h | 95 + src/3rdparty/freetype/src/psaux/psfont.c | 567 +++ src/3rdparty/freetype/src/psaux/psfont.h | 134 + src/3rdparty/freetype/src/psaux/psft.c | 890 +++++ src/3rdparty/freetype/src/psaux/psft.h | 167 + src/3rdparty/freetype/src/psaux/psglue.h | 144 + src/3rdparty/freetype/src/psaux/pshints.c | 1939 +++++++++++ src/3rdparty/freetype/src/psaux/pshints.h | 288 ++ src/3rdparty/freetype/src/psaux/psintrp.c | 3040 +++++++++++++++++ src/3rdparty/freetype/src/psaux/psintrp.h | 83 + src/3rdparty/freetype/src/psaux/psobjs.c | 799 ++++- src/3rdparty/freetype/src/psaux/psobjs.h | 109 +- src/3rdparty/freetype/src/psaux/psread.c | 112 + src/3rdparty/freetype/src/psaux/psread.h | 68 + src/3rdparty/freetype/src/psaux/psstack.c | 328 ++ src/3rdparty/freetype/src/psaux/psstack.h | 121 + src/3rdparty/freetype/src/psaux/pstypes.h | 78 + src/3rdparty/freetype/src/psaux/rules.mk | 19 +- src/3rdparty/freetype/src/psaux/t1cmap.c | 64 +- src/3rdparty/freetype/src/psaux/t1cmap.h | 8 +- src/3rdparty/freetype/src/psaux/t1decode.c | 530 ++- src/3rdparty/freetype/src/psaux/t1decode.h | 18 +- src/3rdparty/freetype/src/pshinter/Jamfile | 2 +- src/3rdparty/freetype/src/pshinter/module.mk | 2 +- src/3rdparty/freetype/src/pshinter/pshalgo.c | 18 +- src/3rdparty/freetype/src/pshinter/pshalgo.h | 8 +- src/3rdparty/freetype/src/pshinter/pshglob.c | 8 +- src/3rdparty/freetype/src/pshinter/pshglob.h | 8 +- src/3rdparty/freetype/src/pshinter/pshinter.c | 10 +- src/3rdparty/freetype/src/pshinter/pshmod.c | 14 +- src/3rdparty/freetype/src/pshinter/pshmod.h | 8 +- src/3rdparty/freetype/src/pshinter/pshnterr.h | 10 +- src/3rdparty/freetype/src/pshinter/pshpic.c | 2 +- src/3rdparty/freetype/src/pshinter/pshpic.h | 8 +- src/3rdparty/freetype/src/pshinter/pshrec.c | 8 +- src/3rdparty/freetype/src/pshinter/pshrec.h | 8 +- src/3rdparty/freetype/src/pshinter/rules.mk | 2 +- src/3rdparty/freetype/src/psnames/Jamfile | 2 +- src/3rdparty/freetype/src/psnames/module.mk | 2 +- src/3rdparty/freetype/src/psnames/psmodule.c | 63 +- src/3rdparty/freetype/src/psnames/psmodule.h | 8 +- src/3rdparty/freetype/src/psnames/psnamerr.h | 10 +- src/3rdparty/freetype/src/psnames/psnames.c | 6 +- src/3rdparty/freetype/src/psnames/pspic.c | 2 +- src/3rdparty/freetype/src/psnames/pspic.h | 8 +- src/3rdparty/freetype/src/psnames/pstables.h | 94 +- src/3rdparty/freetype/src/psnames/rules.mk | 2 +- src/3rdparty/freetype/src/raster/Jamfile | 2 +- src/3rdparty/freetype/src/raster/ftmisc.h | 8 +- src/3rdparty/freetype/src/raster/ftraster.c | 97 +- src/3rdparty/freetype/src/raster/ftraster.h | 10 +- src/3rdparty/freetype/src/raster/ftrend1.c | 144 +- src/3rdparty/freetype/src/raster/ftrend1.h | 8 +- src/3rdparty/freetype/src/raster/module.mk | 2 +- src/3rdparty/freetype/src/raster/raster.c | 6 +- src/3rdparty/freetype/src/raster/rasterrs.h | 10 +- src/3rdparty/freetype/src/raster/rastpic.c | 2 +- src/3rdparty/freetype/src/raster/rastpic.h | 8 +- src/3rdparty/freetype/src/raster/rules.mk | 2 +- src/3rdparty/freetype/src/sfnt/Jamfile | 2 +- src/3rdparty/freetype/src/sfnt/module.mk | 2 +- src/3rdparty/freetype/src/sfnt/pngshim.c | 118 +- src/3rdparty/freetype/src/sfnt/pngshim.h | 11 +- src/3rdparty/freetype/src/sfnt/rules.mk | 2 +- src/3rdparty/freetype/src/sfnt/sfdriver.c | 1003 +++++- src/3rdparty/freetype/src/sfnt/sfdriver.h | 8 +- src/3rdparty/freetype/src/sfnt/sferrors.h | 11 +- src/3rdparty/freetype/src/sfnt/sfnt.c | 26 +- src/3rdparty/freetype/src/sfnt/sfntpic.c | 2 +- src/3rdparty/freetype/src/sfnt/sfntpic.h | 8 +- src/3rdparty/freetype/src/sfnt/sfobjs.c | 441 ++- src/3rdparty/freetype/src/sfnt/sfobjs.h | 8 +- src/3rdparty/freetype/src/sfnt/ttbdf.c | 15 +- src/3rdparty/freetype/src/sfnt/ttbdf.h | 12 +- src/3rdparty/freetype/src/sfnt/ttcmap.c | 537 ++- src/3rdparty/freetype/src/sfnt/ttcmap.h | 10 +- src/3rdparty/freetype/src/sfnt/ttcmapc.h | 2 +- src/3rdparty/freetype/src/sfnt/ttkern.c | 17 +- src/3rdparty/freetype/src/sfnt/ttkern.h | 8 +- src/3rdparty/freetype/src/sfnt/ttload.c | 164 +- src/3rdparty/freetype/src/sfnt/ttload.h | 8 +- src/3rdparty/freetype/src/sfnt/ttmtx.c | 48 +- src/3rdparty/freetype/src/sfnt/ttmtx.h | 8 +- src/3rdparty/freetype/src/sfnt/ttpost.c | 30 +- src/3rdparty/freetype/src/sfnt/ttpost.h | 10 +- src/3rdparty/freetype/src/sfnt/ttsbit.c | 402 ++- src/3rdparty/freetype/src/sfnt/ttsbit.h | 8 +- src/3rdparty/freetype/src/smooth/Jamfile | 2 +- src/3rdparty/freetype/src/smooth/ftgrays.c | 1406 ++++---- src/3rdparty/freetype/src/smooth/ftgrays.h | 10 +- src/3rdparty/freetype/src/smooth/ftsmerrs.h | 10 +- src/3rdparty/freetype/src/smooth/ftsmooth.c | 385 +-- src/3rdparty/freetype/src/smooth/ftsmooth.h | 17 +- src/3rdparty/freetype/src/smooth/ftspic.c | 2 +- src/3rdparty/freetype/src/smooth/ftspic.h | 8 +- src/3rdparty/freetype/src/smooth/module.mk | 2 +- src/3rdparty/freetype/src/smooth/rules.mk | 2 +- src/3rdparty/freetype/src/smooth/smooth.c | 6 +- src/3rdparty/freetype/src/tools/afblue.pl | 17 +- src/3rdparty/freetype/src/tools/apinames.c | 33 +- .../freetype/src/tools/docmaker/content.py | 66 +- .../freetype/src/tools/docmaker/docbeauty.py | 18 +- .../freetype/src/tools/docmaker/docmaker.py | 26 +- .../freetype/src/tools/docmaker/formatter.py | 7 +- .../freetype/src/tools/docmaker/sources.py | 34 +- .../freetype/src/tools/docmaker/tohtml.py | 184 +- .../freetype/src/tools/docmaker/utils.py | 2 +- .../freetype/src/tools/ftfuzzer/README | 81 + .../freetype/src/tools/ftfuzzer/ftfuzzer.cc | 428 +++ .../freetype/src/tools/ftfuzzer/ftmutator.cc | 314 ++ .../src/tools/ftfuzzer/rasterfuzzer.cc | 129 + .../freetype/src/tools/ftfuzzer/runinput.cc | 58 + .../freetype/src/tools/ftrandom/Makefile | 26 +- .../freetype/src/tools/ftrandom/README | 79 +- .../freetype/src/tools/ftrandom/ftrandom.c | 161 +- src/3rdparty/freetype/src/tools/glnames.py | 87 +- src/3rdparty/freetype/src/tools/no-copyright | 4 + .../freetype/src/tools/update-copyright-year | 2 +- src/3rdparty/freetype/src/truetype/Jamfile | 2 +- src/3rdparty/freetype/src/truetype/module.mk | 2 +- src/3rdparty/freetype/src/truetype/rules.mk | 2 +- src/3rdparty/freetype/src/truetype/truetype.c | 20 +- src/3rdparty/freetype/src/truetype/ttdriver.c | 205 +- src/3rdparty/freetype/src/truetype/ttdriver.h | 8 +- src/3rdparty/freetype/src/truetype/tterrors.h | 11 +- src/3rdparty/freetype/src/truetype/ttgload.c | 789 +++-- src/3rdparty/freetype/src/truetype/ttgload.h | 8 +- src/3rdparty/freetype/src/truetype/ttgxvar.c | 2850 +++++++++++++--- src/3rdparty/freetype/src/truetype/ttgxvar.h | 305 +- src/3rdparty/freetype/src/truetype/ttinterp.c | 1468 ++++---- src/3rdparty/freetype/src/truetype/ttinterp.h | 169 +- src/3rdparty/freetype/src/truetype/ttobjs.c | 415 ++- src/3rdparty/freetype/src/truetype/ttobjs.h | 20 +- src/3rdparty/freetype/src/truetype/ttpic.c | 2 +- src/3rdparty/freetype/src/truetype/ttpic.h | 29 +- src/3rdparty/freetype/src/truetype/ttpload.c | 81 +- src/3rdparty/freetype/src/truetype/ttpload.h | 8 +- src/3rdparty/freetype/src/truetype/ttsubpix.c | 39 +- src/3rdparty/freetype/src/truetype/ttsubpix.h | 13 +- src/3rdparty/freetype/src/type1/Jamfile | 2 +- src/3rdparty/freetype/src/type1/module.mk | 2 +- src/3rdparty/freetype/src/type1/rules.mk | 2 +- src/3rdparty/freetype/src/type1/t1afm.c | 35 +- src/3rdparty/freetype/src/type1/t1afm.h | 8 +- src/3rdparty/freetype/src/type1/t1driver.c | 126 +- src/3rdparty/freetype/src/type1/t1driver.h | 8 +- src/3rdparty/freetype/src/type1/t1errors.h | 10 +- src/3rdparty/freetype/src/type1/t1gload.c | 127 +- src/3rdparty/freetype/src/type1/t1gload.h | 8 +- src/3rdparty/freetype/src/type1/t1load.c | 290 +- src/3rdparty/freetype/src/type1/t1load.h | 27 +- src/3rdparty/freetype/src/type1/t1objs.c | 66 +- src/3rdparty/freetype/src/type1/t1objs.h | 14 +- src/3rdparty/freetype/src/type1/t1parse.c | 4 +- src/3rdparty/freetype/src/type1/t1parse.h | 8 +- src/3rdparty/freetype/src/type1/t1tokens.h | 2 +- src/3rdparty/freetype/src/type1/type1.c | 15 +- src/3rdparty/freetype/src/type42/Jamfile | 2 +- src/3rdparty/freetype/src/type42/module.mk | 2 +- src/3rdparty/freetype/src/type42/rules.mk | 2 +- src/3rdparty/freetype/src/type42/t42drivr.c | 54 +- src/3rdparty/freetype/src/type42/t42drivr.h | 8 +- src/3rdparty/freetype/src/type42/t42error.h | 10 +- src/3rdparty/freetype/src/type42/t42objs.c | 18 +- src/3rdparty/freetype/src/type42/t42objs.h | 8 +- src/3rdparty/freetype/src/type42/t42parse.c | 55 +- src/3rdparty/freetype/src/type42/t42parse.h | 8 +- src/3rdparty/freetype/src/type42/t42types.h | 8 +- src/3rdparty/freetype/src/type42/type42.c | 8 +- src/3rdparty/freetype/src/winfonts/Jamfile | 2 +- src/3rdparty/freetype/src/winfonts/fnterrs.h | 10 +- src/3rdparty/freetype/src/winfonts/module.mk | 2 +- src/3rdparty/freetype/src/winfonts/rules.mk | 2 +- src/3rdparty/freetype/src/winfonts/winfnt.c | 135 +- src/3rdparty/freetype/src/winfonts/winfnt.h | 8 +- .../itemviews/qheaderview/tst_qheaderview.cpp | 4 + 539 files changed, 45591 insertions(+), 13889 deletions(-) create mode 100644 src/3rdparty/freetype/include/freetype/ftdriver.h create mode 100644 src/3rdparty/freetype/include/freetype/ftparams.h create mode 100644 src/3rdparty/freetype/include/freetype/internal/cffotypes.h create mode 100644 src/3rdparty/freetype/include/freetype/internal/cfftypes.h create mode 100644 src/3rdparty/freetype/include/freetype/internal/ftdrv.h create mode 100644 src/3rdparty/freetype/include/freetype/internal/fthash.h create mode 100644 src/3rdparty/freetype/include/freetype/internal/ftpsprop.h create mode 100644 src/3rdparty/freetype/include/freetype/internal/services/svcfftl.h create mode 100644 src/3rdparty/freetype/include/freetype/internal/services/svmetric.h create mode 100644 src/3rdparty/freetype/src/autofit/afshaper.c create mode 100644 src/3rdparty/freetype/src/autofit/afshaper.h create mode 100644 src/3rdparty/freetype/src/base/fthash.c create mode 100644 src/3rdparty/freetype/src/base/ftpsprop.c create mode 100644 src/3rdparty/freetype/src/base/ftver.rc create mode 100644 src/3rdparty/freetype/src/gzip/ftzconf.h create mode 100644 src/3rdparty/freetype/src/psaux/cffdecode.c create mode 100644 src/3rdparty/freetype/src/psaux/cffdecode.h create mode 100644 src/3rdparty/freetype/src/psaux/psarrst.c create mode 100644 src/3rdparty/freetype/src/psaux/psarrst.h create mode 100644 src/3rdparty/freetype/src/psaux/psblues.c create mode 100644 src/3rdparty/freetype/src/psaux/psblues.h create mode 100644 src/3rdparty/freetype/src/psaux/pserror.c create mode 100644 src/3rdparty/freetype/src/psaux/pserror.h create mode 100644 src/3rdparty/freetype/src/psaux/psfixed.h create mode 100644 src/3rdparty/freetype/src/psaux/psfont.c create mode 100644 src/3rdparty/freetype/src/psaux/psfont.h create mode 100644 src/3rdparty/freetype/src/psaux/psft.c create mode 100644 src/3rdparty/freetype/src/psaux/psft.h create mode 100644 src/3rdparty/freetype/src/psaux/psglue.h create mode 100644 src/3rdparty/freetype/src/psaux/pshints.c create mode 100644 src/3rdparty/freetype/src/psaux/pshints.h create mode 100644 src/3rdparty/freetype/src/psaux/psintrp.c create mode 100644 src/3rdparty/freetype/src/psaux/psintrp.h create mode 100644 src/3rdparty/freetype/src/psaux/psread.c create mode 100644 src/3rdparty/freetype/src/psaux/psread.h create mode 100644 src/3rdparty/freetype/src/psaux/psstack.c create mode 100644 src/3rdparty/freetype/src/psaux/psstack.h create mode 100644 src/3rdparty/freetype/src/psaux/pstypes.h create mode 100644 src/3rdparty/freetype/src/tools/ftfuzzer/README create mode 100644 src/3rdparty/freetype/src/tools/ftfuzzer/ftfuzzer.cc create mode 100644 src/3rdparty/freetype/src/tools/ftfuzzer/ftmutator.cc create mode 100644 src/3rdparty/freetype/src/tools/ftfuzzer/rasterfuzzer.cc create mode 100644 src/3rdparty/freetype/src/tools/ftfuzzer/runinput.cc diff --git a/src/3rdparty/freetype/README b/src/3rdparty/freetype/README index ed62e1dee7..c23b99e18a 100644 --- a/src/3rdparty/freetype/README +++ b/src/3rdparty/freetype/README @@ -1,7 +1,7 @@ - FreeType 2.6.1 + FreeType 2.9.1 ============== - Homepage: http://www.freetype.org + Homepage: https://www.freetype.org FreeType is a freely available software library to render fonts. @@ -20,17 +20,17 @@ documentation is available as a separate package from our sites. Go to - http://download.savannah.gnu.org/releases/freetype/ + https://download.savannah.gnu.org/releases/freetype/ and download one of the following files. - freetype-doc-2.6.1.tar.bz2 - freetype-doc-2.6.1.tar.gz - ftdoc261.zip + freetype-doc-2.9.1.tar.bz2 + freetype-doc-2.9.1.tar.gz + ftdoc291.zip To view the documentation online, go to - http://www.freetype.org/freetype2/documentation.html + https://www.freetype.org/freetype2/documentation.html Mailing Lists @@ -46,7 +46,7 @@ The lists are moderated; see - http://www.freetype.org/contact.html + https://www.freetype.org/contact.html how to subscribe. @@ -71,7 +71,7 @@ ---------------------------------------------------------------------- -Copyright 2006-2015 by +Copyright 2006-2018 by David Turner, Robert Wilhelm, and Werner Lemberg. This file is part of the FreeType project, and may only be used, diff --git a/src/3rdparty/freetype/builds/unix/ftsystem.c b/src/3rdparty/freetype/builds/unix/ftsystem.c index d7513d9e96..8fdbeb0f62 100644 --- a/src/3rdparty/freetype/builds/unix/ftsystem.c +++ b/src/3rdparty/freetype/builds/unix/ftsystem.c @@ -4,7 +4,7 @@ /* */ /* Unix-specific FreeType low-level system interface (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/docs/CHANGES b/src/3rdparty/freetype/docs/CHANGES index ffc686b466..a6d088af49 100644 --- a/src/3rdparty/freetype/docs/CHANGES +++ b/src/3rdparty/freetype/docs/CHANGES @@ -1,3 +1,681 @@ +CHANGES BETWEEN 2.9 and 2.9.1 + + I. IMPORTANT BUG FIXES + + - Type 1 fonts containing flex features were not rendered + correctly (bug introduced in version 2.9). + + - CVE-2018-6942: Older FreeType versions can crash with certain + malformed variation fonts. + + http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-6942 + + + II. MISCELLANEOUS + + - Bug fix: Multiple calls to `FT_Get_MM_Var' returned garbage. + + - The base extensions `ftlcdfil' and `ftfntfmt' are now part of + the base module (and thus no longer configurable in file + `modules.cfg'). + + - Emboldening of bitmaps didn't work correctly sometimes, showing + various artifacts (bug introduced in version 2.8.1). + + - Use of the `freetype-config' script to get compilation and + linking options is deprecated since it doesn't support + cross-compiling, among other deficiencies. Instead, you should + use the `pkg-config' interface. + + The `configure' script no longer installs `freetype-config' by + default. For backwards compatibility, a new configure option + `--enable-freetype-config' is provided that reverts this + decision. + + - The auto-hinter script ranges have been updated for Unicode 11. + No support for new scripts have been added, however, with the + exception of Georgian Mtavruli. + + - Support for cmake has been improved. + + - The next release will remove support for Position Independent + Code as needed by systems that prohibit automatic address + fixups, such as BREW. [Compilation with modern compilers that + use flags like `-fPIC' or `-fPIE' is not affected.] + + +====================================================================== + +CHANGES BETWEEN 2.8.1 and 2.9 + + I. IMPORTANT BUG FIXES + + - Advance width values of variation fonts were often wrong. + + - More fixes for variation font support; you should update to this + version if you want to support them. + + + II. IMPORTANT CHANGES + + - As a GSoC project, Ewald Hew extended the new (Adobe) CFF engine + to handle Type 1 fonts also, thus greatly improving the + rendering of this format. This is the new default. The old + engine is still available if the configuration macro + `T1_CONFIG_OPTION_OLD_ENGINE' gets defined; using the + `hinting-engine' property of the `type1' driver module you can + then switch between the two engines. + + - A new function, `FT_Set_Named_Instance', can be used to set or + change the current named instance. + + - Starting with this FreeType version, resetting variation + coordinates will return to the currently selected named + instance. Previously, FreeType returned to the base font (i.e., + no instance set). + + + III. MISCELLANEOUS + + - The `face_flags' field of the `FT_Face' structure has a new bit, + `FT_FACE_FLAG_VARIATION', which is set if a variation font has + been altered with `FT_Set_MM_Design_Coordinates', + `FT_Set_Var_Design_Coordinates', or + `FT_Set_Var_Blend_Coordinates'. + + - If the current face is a named instance, the new macro + `FT_IS_NAMED_INSTANCE' returns true. + + - `FT_IS_VARIATION' is a new macro that returns true whenever a + face object has been altered by `FT_Set_MM_Design_Coordinates', + `FT_Set_Var_Design_Coordinates', or + `FT_Set_Var_Blend_Coordinates'. + + - Changing the design coordinates of a variation font with + `FT_Set_Var_Design_Coordinates' or + `FT_Set_Var_Blend_Coordinates' does not influence the named + instance index value (only `FT_Set_Named_Instance' does that). + + - Special PostScript names for named instances are only returned + if the named instance is set with `FT_Set_Named_Instance' (and + the font has corresponding entries in its `fvar' table). If + `FT_IS_VARIATION' returns true, the algorithmically derived + PostScript name is provided, not looking up special entries for + named instances. + + - A new function `FT_Done_MM_Var' is provided to free the memory + returned in a call to `FT_Get_MM_Var'. + + - On platforms using the `configure' script, the installed + `ftoption.h' file now correctly reflects configuration options + like `--with-harfbuzz'. + + - Better support to build FreeType as a DLL on Windows using + Visual C. + + - All data specific to driver modules is now collected in a single + file, `FT_DRIVER_H'. Consequently, the macros + `FT_AUTOHINTER_H', `FT_CFF_DRIVER_H', `FT_TRUETYPE_DRIVER_H', + and `FT_PCF_DRIVER_H' still work but are deprecated. + + - Some fuzzer fixes to better reject malformed fonts. + + - The `ftbench' demo program has a new test for opening a new face + and loading some glyphs. + + - The `ftbench' demo program has a new option `-j' to specify the + last glyph index to be used in the tests. + + - The `ftgrid' demo program has a new option `-n' to suppress + display of named instances of variation fonts. + + - The `ttdebug' demo program can now show a stack trace (key `K') + and switch between hexadecimal and decimal display of integers + (key `I'). + + +====================================================================== + +CHANGES BETWEEN 2.8 and 2.8.1 + + I. IMPORTANT BUG FIXES + + - B/W hinting of TrueType fonts didn't work properly if + interpreter version 38 or 40 was selected. + + - Some severe problems within the handling of TrueType Variation + Fonts were found and fixed. + + - Function `FT_Set_Var_Design_Coordinates' didn't correctly handle + the case with less input coordinates than axes. + + + II. IMPORTANT CHANGES + + - By default, FreeType now offers high quality LCD-optimized + output without resorting to ClearType techniques of resolution + tripling and filtering. In this method, called Harmony, each + color channel is generated separately after shifting the glyph + outline, capitalizing on the fact that the color grids on LCD + panels are shifted by a third of a pixel. This output is + indistinguishable from ClearType with a light 3-tap filter. + + + III. MISCELLANEOUS + + - Using the new function `FT_Get_Var_Axis_Flags', an application + can access the `flags' field of a variation axis (introduced in + OpenType version 1.8.2) + + - More sanity checks. + + - The internal representation of buffers for LCD rendering has + changed (to be more precise, the amount of padding gets computed + differently). Applications that use the FreeType API are not + affected. + + - To reset all design axis values of a variation font to its + default values you can now say + + error = FT_Set_Var_Design_Coordinates( face, 0, NULL ); + + This also works with functions `FT_Set_MM_Design_Coordinates' + and `FT_Set_MM_Blend_Coordinates'. + + - FreeType now synthesizes a missing Unicode cmap for (older) + TrueType fonts also if glyph names are available. + + - FreeType has improved handling of BDF fonts without the + `POINT_SIZE', `RESOLUTION_X', or `RESOLUTION_Y' properties; the + library now uses the values of the `SIZE' keyword if they are + missing. Previously, `SIZE' was completely ignored, and + FreeType used heuristic values instead. + + - Multiple calls to `FT_Bitmap_Convert' do work now as advertised. + Previously, they failed with an assertion error if there was an + empty bitmap between non-empty ones. + + - The warping option has moved from `light' to `normal' hinting + where it replaces the original hinting algorithm. The `light' + mode is now always void of any hinting in x-direction. + + - 16bit compiler support is now officially ended. We didn't + provide any maintenance since many years, and given that there + were no error or problem reports either it seems that it is no + longer needed. + + - The `ftgrid' demo program can now toggle the display of grid + lines with the `G' key. + + - The `ftgrid' demo program can toggle a different set of colors + (suitable to color-blind people) with the `C' key. + + - The `ftgrid' demo program now supports the `-e' command line + option to select a cmap. + + - The `ftdump' demo program has a new command line option `-t' to + output the SFNT table list. + + +====================================================================== + +CHANGES BETWEEN 2.7.1 and 2.8 + + I. IMPORTANT CHANGES + + - Support for OpenType Variation Fonts is now complete. The last + missing part was handling the `VVAR' and `MVAR' tables, which is + available with this release. + + - A new function `FT_Face_Properties' allows the control of some + module and library properties per font. Currently, the + following properties can be handled: stem darkening, LCD filter + weights, and the random seed for the `random' CFF operator. + + - The PCF change to show more `colourful' family names (introduced + in version 2.7.1) was too radical; it can now be configured with + PCF_CONFIG_OPTION_LONG_FAMILY_NAMES at compile time. If + activated, it can be switched off at run time with the new pcf + property `no-long-family-names'. If the `FREETYPE_PROPERTIES' + environment variable is available, you can say + + FREETYPE_PROPERTIES=pcf:no-long-family-names=1 + + - Support for the following scripts has been added to the + auto-hinter. + + Adlam, Avestan, Bamum, Buhid, Carian, Chakma, Coptic, Cypriot, + Deseret, Glagolitic, Gothic, Kayah, Lisu, N'Ko, Ol Chiki, Old + Turkic, Osage, Osmanya, Saurashtra, Shavian, Sundanese, Tai + Viet, Tifinagh, Unified Canadian Syllabics, Vai + + + II. IMPORTANT BUG FIXES + + - `Light' auto-hinting mode no longer uses TrueType metrics for + TrueType fonts. This bug was introduced in version 2.4.6, + causing horizontal scaling also. Almost all GNU/Linux + distributions (with Fedora as a notable exception) disabled the + corresponding patch for good reasons; chances are thus high that + you won't notice a difference. + + If optical backward compatibility for legacy applications is + necessary, you might enable the AF_CONFIG_OPTION_TT_SIZE_METRICS + configuration option. However, it is strongly recommended to + avoid that, adjusting font sizes instead. + + - Global size metrics values in the `FT_Size_Metrics' structure + can be different for TrueType fonts. Reason is that in older + FreeType versions the metrics were rounded differently to + integer pixels compared to all other font formats, yielding an + inconsistent behaviour if you used non-native hinting. Starting + with this version, global size metrics for TrueType fonts are + handled the same as other font formats: `ascender' gets rounded + up, `descender' gets rounded down, `height' gets normally + rounded, and `max_advance' gets normally rounded, too. + + If you need more precise values of (global) ascender, descender, + height, or `max_advance', please take the corresponding values + from the `FT_Face' structure and scale them manually. + + - If a TrueType font gets loaded with FT_LOAD_NO_HINTING, FreeType + now scales the font linearly again (bug introduced in version + 2.4.6). + + - CVE-2017-8105, CVE-2017-8287: Older FreeType versions have + out-of-bounds writes caused by heap-based buffer overflows + related to Type 1 fonts. + + https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-8105 + https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-8287 + + + III. MISCELLANEOUS + + - A new function `FT_Set_Default_Properties' has been added to + parse the `FREETYPE_PROPERTIES' environment variable + (previously, it was internal only). `FT_Init_FreeType' always + call this function, but `FT_New_Library' does not (similar to + `FT_Add_Default_Modules'). + + - To be in sync with OpenType version 1.7 and newer, macros + + FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY, + FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY, + TT_NAME_ID_PREFERRED_FAMILY + TT_NAME_ID_PREFERRED_SUBFAMILY + + are renamed to + + FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_FAMILY, + FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_SUBFAMILY, + TT_NAME_ID_TYPOGRAPHIC_FAMILY + TT_NAME_ID_TYPOGRAPHIC_SUBFAMILY + + The old macro names are deprecated (but still available). + + - Support for SFNT `name' tables has been improved. + + . Format 1 `name' tables are now supported. Use new function + `FT_Get_Sfnt_LangTag' to access associated language tags. + + . Language, encoding, and name IDs have been updated to OpenType + version 1.8.1. + + - The new CFF engine now handles the `random' operator. All CFF + opcodes are now supported. + + - The CFF module has a new property `random-seed' to control the + pseudo-random number generation for the `random' operator. + + - The `freetype-config' script is now a wrapper of `pkg-config' if + this program is available in the path. + + - FT_LOAD_TARGET_LCD is now a variant of FT_LOAD_TARGET_LIGHT; + this should provide better rendering results. + + - A mode to display light auto-hinting with subpixel positioning + has been added to `ftdiff'. + + +====================================================================== + +CHANGES BETWEEN 2.7 and 2.7.1 + + I. IMPORTANT CHANGES + + - Support for the new CFF2 font format as introduced with OpenType + 1.8 has been contributed by Dave Arnolds from Adobe. + + - Preliminary support for variation fonts as specified in OpenType + 1.8 (in addition to the already existing support for Adobe's MM + and Apple's GX formats). Dave Arnolds contributed handling of + advance width change variation; more will come in the next + version. + + + II. IMPORTANT BUG FIXES + + - Handling of raw CID fonts was partially broken (bug introduced + in 2.6.4). + + - CVE-2016-10328: Older FreeType versions had an out-of-bounds + write caused by a heap-based buffer overflow related to the CFF + fonts. + + https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-10328 + + + III. MISCELLANEOUS + + - Some limits for TrueType bytecode execution have been tightened + to speed up FreeType's handling of malformed fonts, in + particular to quickly abort endless loops. + + - The number of twilight points can no longer be set to an + arbitrarily large value. + + - The total number of jump opcode instructions (like JMPR) with + negative arguments is dynamically restricted; the same holds + for the total number of iterations in LOOPCALL opcodes. + + The dynamic limits are based on the number of points in a glyph + and the number of CVT entries. Please report if you encounter a + font where the selected values are not adequate. + + - PCF family names are made more `colourful'; they now include the + foundry and information whether they contain wide characters. + For example, you no longer get `Fixed' but rather `Sony Fixed' + or `Misc Fixed Wide'. + + - A new function `FT_Get_Var_Blend_Coordinates' (with its alias + name `FT_Get_MM_Blend_Coordinates') to retrieve the normalized + blend coordinates of the currently selected variation instance + has been added to the Multiple Masters interface. + + - A new function `FT_Get_Var_Design_Coordinates' to retrieve the + design coordinates of the currently selected variation instance + has been added to the Multiple Masters interface. + + - A new load flag `FT_LOAD_BITMAP_METRICS_ONLY' to retrieve bitmap + information without loading the (embedded) bitmap itself. + + - Retrieving advance widths from bitmap strikes (using + `FT_Get_Advance' and `FT_Get_Advances') have been sped up. + + - The usual round of fuzzer fixes to better reject malformed + fonts. + + - The `ftmulti' demo program can now switch engines with key `H'. + + - The `ftstring' demo program can now show some built-in, + non-latin sample strings (to be selected with the TAB key). + + - The `ftview' demo program can now switch between a font's + charmaps using the TAB key. + + +====================================================================== + +CHANGES BETWEEN 2.6.5 and 2.7 + + I. IMPORTANT CHANGES + + - As announced earlier, the 2.7.x series now uses the new subpixel + hinting mode as the default, emulating a modern version of + ClearType. + + This change inevitably leads to different rendering results, and + you might change the `TT_CONFIG_OPTION_SUBPIXEL_HINTING' + configuration option to adapt it to your taste (or use the new + `FREETYPE_PROPERTIES' environment variable). See the + corresponding entry below for version 2.6.4, which gives more + information. + + - A new option `FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES' has been + introduced. If set (which is the default), an environment + variable `FREETYPE_PROPERTIES' can be used to control driver + properties. Example: + + FREETYPE_PROPERTIES=truetype:interpreter-version=35 \ + cff:no-stem-darkening=1 \ + autofitter:warping=1 + + This allows to select, say, the subpixel hinting mode at runtime + for a given application. See file `ftoption.h' for more. + + + II. IMPORTANT BUG FIXES + + - After loading a named instance of a GX variation font, the + `face_index' value in the returned `FT_Face' structure now + correctly holds the named instance index in the upper 16bits as + documented. + + + III. MISCELLANEOUS + + - A new macro `FT_IS_NAMED_INSTANCE' to test whether a given face + is a named instance. + + - More fixes to GX font handling. + + - Apple's `GETVARIATION' bytecode operator (needed for GX + variation font support) has been implemented. + + - Another round of fuzzer fixes, mainly to reject invalid fonts + faster. + + - Handling of raw CID fonts was broken (bug introduced in version + 2.6.4). + + - The smooth rasterizer has been streamlined to make it faster by + approx. 20%. + + - The `ftgrid' demo program now understands command line option + `-d' to give start-up design coordinates. + + - The `ftdump' demo program has a new command line option `-p' to + dump TrueType bytecode instructions. + + +====================================================================== + +CHANGES BETWEEN 2.6.4 and 2.6.5 + + I. IMPORTANT BUG FIXES + + - Compilation works again on Mac OS X (bug introduced in version + 2.6.4). + + + II. IMPORTANT CHANGES + + - The new subpixel hinting mode is now disabled by default; it + will be enabled by default in the forthcoming 2.7.x series. + Main reason for reverting this feature is the principle of least + surprise: a sudden change in appearance of all fonts (even if + the rendering improves for almost all recent fonts) should not + be expected in a new micro version of a series. + + +====================================================================== + +CHANGES BETWEEN 2.6.3 and 2.6.4 + + I. IMPORTANT CHANGES + + - A new subpixel hinting mode has been contributed by Nikolaus + Waxweiler, which is now the default rendering mode for TrueType + fonts. It implements (almost everything of) version 40 of the + bytecode engine. + + The existing code base in FreeType (the `Infinality code') was + stripped to the bare minimum and all configurability removed in + the name of speed and simplicity. The configurability was + mainly aimed at legacy fonts like Arial, Times New Roman, or + Courier. [Legacy fonts are fonts that modify vertical stems to + achieve clean black-and-white bitmaps.] The new mode focuses on + applying a minimal set of rules to all fonts indiscriminately so + that modern and web fonts render well while legacy fonts render + okay. + + Activation of the subpixel hinting support can be controlled + with the `TT_CONFIG_OPTION_SUBPIXEL_HINTING' configuration + option at compile time: If set to value 1, you get the old + Infinality mode (which was never the default due to its + slowness). Value 2 activates the new subpixel hinting mode, and + value 3 activates both. The default is value 2. + + At run time, you can select the subpixel hinting mode with the + `interpreter-version' property (provided you have compiled in + the corresponding hinting mode); see `ftttdrv.h' for more. + + - Support for the following scripts has been added to the + auto-hinter. + + Armenian, Cherokee, Ethiopic, Georgian, Gujarati, Gurmukhi, + Malayalam, Sinhala, Tamil + + + II. MISCELLANEOUS + + - Type 42 fonts as created by LilyPond are now supported. + + - Minor rendering improvements in the auto-hinter. + + - For experimental reasons, the old CFF engine now supports all + CFF operators except `random', including the deprecated Multiple + Masters instructions. This allows the display of fonts like + `ITCGaramondMM-It.otf' (without font variations, though). + + - Another round of fixes to improve handling of invalid fonts. + + - The `ftgrid' demo program now displays the rendered pixels also; + this can be switched off with the `b' key. Selection of various + LCD filtering modes can be done with the `L' key. + + - The demo programs have been extended to allow selection of all + available TrueType bytecode engines. + + - A very early beta version of a new, Qt based demo program called + `ftinspect' is part of the source code bundle; it will + eventually supersede the other demo programs. Currently, you + have to compile it manually with `qmake; make'; note that many + features are still missing. + + +====================================================================== + +CHANGES BETWEEN 2.6.2 and 2.6.3 + + I. IMPORTANT CHANGES + + - Khmer, Myanmar, Bengali, and Kannada script support has been + added to the auto-hinter. + + + II. MISCELLANEOUS + + - Better support of Indic scripts like Devanagari by using a + top-to-bottom hinting flow. + + - All FreeType macros starting with two underscores have been + renamed to avoid a violation of both the C and C++ standards. + Example: Header macros of the form `__FOO_H__' are now called + `FOO_H_'. In most cases, this should be completely transparent + to the user. The exception to this is `__FTERRORS_H__', which + must be sometimes undefined by the user to get FreeType error + strings: Both this form and the new `FTERRORS_H_' macro are + accepted for backward compatibility. + + - Minor improvements mainly to the Type 1 driver. + + - The new CFF engine now supports all Type 2 operators except + `random'. + + - The macro `_STANDALONE_', used for compiling the B/W and smooth + rasterizers as stand-alone modules, has been renamed to + `STANDALONE_', since macro names starting with an underscore and + followed by an uppercase letter are reserved in both C and C++. + + - Function `FT_Library_SetLcdFilterWeights' now also activates + custom LCD filter weights (instead of just adjusting them). + + - Support for `unpatented hinting' has been completely removed: + Consequently, the two functions `FT_Face_CheckTrueTypePatents' + and `FT_Face_SetUnpatentedHinting' now return always false, + doing nothing. + + - The `ftgamma' demo program has been modernized; the gamma grid + display has been moved from `ftview' to this program. + + - In `ftview', it is now possible to cycle through the available + LCD filtering modes. + + +====================================================================== + +CHANGES BETWEEN 2.6.1 and 2.6.2 + + I. IMPORTANT CHANGES + + - The auto-hinter now supports stem darkening, to be controlled by + the new `no-stem-darkening' and `darkening-parameters' + properties. This is an experimental feature contributed by + Nikolaus Waxweiler, and the interface might change in a future + release. + + - By default, stem darkening is now switched off (for both the CFF + engine and the auto-hinter). The main reason is that you need + linear alpha blending and gamma correction to get correct + rendering results, and the latter is not yet available in most + freely available rendering stacks like X11. Applying stem + darkening without proper gamma correction leads to far too dark + rendering results. + + - The meaning of `FT_RENDER_MODE_LIGHT' has been slightly + modified. It now essentially means `no hinting along the + horizontal axis'; in particular, no change of glyph advance + widths. Consequently, the auto-hinter is used for all scalable + font formats except for CFF. It is planned that other + font-specific rendering engines (TrueType, Type 1) will follow. + + + II. MISCELLANEOUS + + - The default LCD filter has been changed to be normalized and + color-balanced. + + - For better compatibility with FontConfig, function + `FT_Library_SetLcdFilter' accepts a new enumeration value + `FT_LCD_FILTER_LEGACY1' (which has the same meaning as + `FT_LCD_FILTER_LEGACY'). + + - A large number of bugs have been detected by using the libFuzzer + framework, which should further improve handling of invalid + fonts. Thanks again to Kostya Serebryany and Bungeman! + + - `TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES', a new configuration + option, controls the maximum number of executed opcodes within a + bytecode program. You don't want to change this except for very + special situations (e.g., making a library fuzzer spend less + time to handle broken fonts). + + - The smooth renderer has been made faster. + + - The `ftstring' demo program now supports subpixel rendering; use + key `l' to cycle through the LCD modes. + + - The `ftstring' demo program now supports colour rendering; use + the `space' key to cycle through various colour combinations. + + - The graphical demo programs now use a default gamma value of 1.8 + (instead of 1.2). + + +====================================================================== + CHANGES BETWEEN 2.6 and 2.6.1 I. IMPORTANT BUG FIXES @@ -150,17 +828,17 @@ CHANGES BETWEEN 2.5.5 and 2.6 compiler warnings. - Function `FT_Bitmap_New' has been renamed to `FT_Bitmap_Init', - since this name better reflects its function. For backwards + since this name better reflects its function. For backward compatibility, the old function name is still available. - Function `FT_Get_X11_Font_Format' has been renamed to `FT_Get_Font_Format', since this name better reflects its - function. For backwards compatibility, the old function name is + function. For backward compatibility, the old function name is still available. Additionally, the header file macro for this function has been renamed to `FT_FONT_FORMATS_H' (the old name `FT_XFREE86_H' is - retained for backwards compatibility). + retained for backward compatibility). - Various improvements to the `ftgrid' demo program. @@ -200,7 +878,7 @@ CHANGES BETWEEN 2.5.3 and 2.5.4 I. IMPORTANT BUG FIXES - A variant of vulnerability CVE-2014-2240 was identified - (cf. http://savannah.nongnu.org/bugs/?43661) and fixed in the + (cf. https://savannah.nongnu.org/bugs/?43661) and fixed in the new CFF driver. All users should upgrade. - The new auto-hinter code using HarfBuzz crashed for some invalid @@ -271,7 +949,7 @@ CHANGES BETWEEN 2.5.2 and 2.5.3 I. IMPORTANT BUG FIXES - A vulnerability (CVE-2014-2240) was identified and fixed in the - new CFF driver (cf. http://savannah.nongnu.org/bugs/?41697). + new CFF driver (cf. https://savannah.nongnu.org/bugs/?41697). All users should upgrade. - More bug fixes related to correct positioning of composite @@ -304,7 +982,7 @@ CHANGES BETWEEN 2.5.2 and 2.5.3 and install FreeType again. With FreeType's `configure' script the procedure boils down to - configure, build, and install Freetype, then configure, compile, + configure, build, and install FreeType, then configure, compile, and install HarfBuzz, then configure, compile, and install FreeType again (after executing `make distclean'). @@ -594,7 +1272,7 @@ index ebcf189..3f2ce6b 100644 II. MISCELLANEOUS - The (top-level) `configure' script now respects the MAKE - environment variable to specify a `make' binary. For backwards + environment variable to specify a `make' binary. For backward compatibility, GNUMAKE still overrides MAKE, though. - The `ftview' and `ftdiff' demo programs have been redesigned, @@ -643,7 +1321,7 @@ CHANGES BETWEEN 2.4.10 and 2.4.11 - Subpixel hinting support has been contributed by Infinality, based on Greg Hitchcock's whitepaper at - http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx + https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx Originally, it was a separate patch available from @@ -1513,7 +2191,7 @@ CHANGES BETWEEN 2.3.0 and 2.2.1 of the library, mainly due to patent issues. For more information see: - http://lists.gnu.org/archive/html/freetype/2006-09/msg00064.html + https://lists.gnu.org/archive/html/freetype/2006-09/msg00064.html A new configuration macro FT_CONFIG_OPTION_SUBPIXEL_RENDERING has been introduced in `ftoption.h'; manually define it in this @@ -1616,7 +2294,7 @@ CHANGES BETWEEN 2.2 and 2.1.10 We provide patches for most of those rogue clients. See the following page for more information: - http://www.freetype.org/freetype2/patches/rogue-patches.html + https://www.freetype.org/freetype2/patches/rogue-patches.html Note that, as a convenience to our Unix desktop users, version 2.2 is *binary* compatible with FreeType 2.1.7, which means that @@ -1728,7 +2406,7 @@ CHANGES BETWEEN 2.2 and 2.1.10 - Rudimentary support for Adobe's new `SING Glyphlet' format. See - http://www.adobe.com/products/indesign/sing_gaiji.html + https://www.adobe.com/content/dam/acom/en/devnet/font/pdfs/5148.SING_Tutorial.pdf for more information. @@ -1813,7 +2491,7 @@ CHANGES BETWEEN 2.1.10 and 2.1.9 probably using a different pitch, and to further manipulate it. - A new API `FT_Outline_Embolden' (in FT_OUTLINE_H) gives finer - control how outlines are embolded. + control how outlines are emboldened. - `FT_GlyphSlot_Embolden' (in FT_SYNTHESIS_H) now handles bitmaps also (code contributed by Chia I Wu). Note that this function @@ -1932,7 +2610,7 @@ CHANGES BETWEEN 2.1.8 and 2.1.7 correctly treated as a CID, similar to FreeType's CID driver module. Note that CID CMap support is still missing. - - The FT_FACE_FLAGS_GLYPH_NAMES flag is now set correctly for all + - The FT_FACE_FLAG_GLYPH_NAMES flag is now set correctly for all font formats. - Some subsetted Type 1 fonts weren't parsed correctly. This bug @@ -2223,7 +2901,7 @@ CHANGES BETWEEN 2.1.5 and 2.1.4 - FT_ENCODING_MS_{SJIS,GB2312,BIG5,WANSUNG,JOHAB} are now deprecated in favour of - FT_ENCODING_{SJIS,GB2312,GIB5,WANSONG,JOHAB} -- those encodings + FT_ENCODING_{SJIS,GB2312,BIG5,WANSUNG,JOHAB} -- those encodings are not specific to Microsoft. @@ -2405,7 +3083,7 @@ CHANGES BETWEEN 2.1.3 and 2.1.2 quality since many nasty defaults have been suppressed. Please visit the web page: - http://www.freetype.org/hinting/smooth-hinting.html + https://www.freetype.org/hinting/smooth-hinting.html for additional details on this topic. @@ -2425,12 +3103,12 @@ CHANGES BETWEEN 2.1.3 and 2.1.2 FT_LOAD_TARGET_MONO :: Hint and render for 1-bit displays. FT_LOAD_TARGET_LCD :: Hint and render for horizontal RGB or - BGR sub-pixel displays (like LCD + BGR subpixel displays (like LCD screens). THIS IS STILL EXPERIMENTAL! FT_LOAD_TARGET_LCD_V :: Same as FT_LOAD_TARGET_LCD, for - vertical sub-pixel displays (like + vertical subpixel displays (like rotated LCD screens). THIS IS STILL EXPERIMENTAL! @@ -2664,7 +3342,7 @@ CHANGES BETWEEN 2.1.0 and 2.0.9 - The FreeType 2 redesign has begun. More information can be found at this URL: - http://www.freetype.org/freetype2/redesign.html + https://www.freetype.org/freetype2/redesign.html The following internal changes have been performed within the sources of this release: @@ -3255,13 +3933,7 @@ CHANGES BETWEEN 2.0.2 and 2.0.1 For more information, see section I of the following document: - http://www.freetype.org/ - freetype2/docs/tutorial/step1.html - - or - - http://freetype.sourceforge.net/ - freetype2/docs/tutorial/step1.html + https://www.freetype.org/freetype2/docs/tutorial/step1.html - Many, many comments have been added to the public source file in order to automatically generate the API Reference through the @@ -3270,7 +3942,7 @@ CHANGES BETWEEN 2.0.2 and 2.0.1 The latter has been updated to support the grouping of sections in chapters and better index sort. See: - http://www.freetype.org/freetype2/docs/reference/ft2-toc.html + https://www.freetype.org/freetype2/docs/reference/ft2-toc.html III. CHANGES TO THE BUILD PROCESS @@ -3644,7 +4316,7 @@ BETA-8 (RELEASE CANDIDATE) CHANGES automatically when needed. - Reformatted all modules source code in order to get rid of the - basic data types redifinitions (i.e. `TT_Int' instead of `FT_Int', + basic data types redefinitions (i.e. `TT_Int' instead of `FT_Int', `T1_Fixed' instead of `FT_Fixed'). Hence the format-specific prefixes like `TT_', `T1_', `T2_' and `CID_' are only used for relevant structures. @@ -4345,7 +5017,7 @@ Extensions support: ------------------------------------------------------------------------ -Copyright 2000-2015 by +Copyright 2000-2018 by David Turner, Robert Wilhelm, and Werner Lemberg. This file is part of the FreeType project, and may only be used, diff --git a/src/3rdparty/freetype/docs/CUSTOMIZE b/src/3rdparty/freetype/docs/CUSTOMIZE index 42fc313811..916be32754 100644 --- a/src/3rdparty/freetype/docs/CUSTOMIZE +++ b/src/3rdparty/freetype/docs/CUSTOMIZE @@ -117,15 +117,15 @@ IV. Overriding default configuration and module headers name the configuration headers. To do so, you need a custom `ft2build.h' whose content can be as simple as: - #ifndef __FT2_BUILD_MY_PLATFORM_H__ - #define __FT2_BUILD_MY_PLATFORM_H__ + #ifndef FT2_BUILD_MY_PLATFORM_H_ + #define FT2_BUILD_MY_PLATFORM_H_ #define FT_CONFIG_OPTIONS_H #define FT_CONFIG_MODULES_H #include - #endif /* __FT2_BUILD_MY_PLATFORM_H__ */ + #endif /* FT2_BUILD_MY_PLATFORM_H_ */ Place those files in a separate directory, e.g., @@ -139,7 +139,7 @@ IV. Overriding default configuration and module headers ---------------------------------------------------------------------- -Copyright 2003-2015 by +Copyright 2003-2018 by David Turner, Robert Wilhelm, and Werner Lemberg. This file is part of the FreeType project, and may only be used, diff --git a/src/3rdparty/freetype/docs/DEBUG b/src/3rdparty/freetype/docs/DEBUG index ab2c769ac5..751eaf028a 100644 --- a/src/3rdparty/freetype/docs/DEBUG +++ b/src/3rdparty/freetype/docs/DEBUG @@ -6,7 +6,7 @@ I. Configuration macros There are several ways to enable debugging features in a FreeType 2 builds. This is controlled through the definition of special macros -located in the file `ftoptions.h'. The macros are: +located in the file `ftoption.h'. The macros are: FT_DEBUG_LEVEL_ERROR @@ -191,7 +191,7 @@ behaviour of FreeType at runtime. ------------------------------------------------------------------------ -Copyright 2002-2015 by +Copyright 2002-2018 by David Turner, Robert Wilhelm, and Werner Lemberg. This file is part of the FreeType project, and may only be used, diff --git a/src/3rdparty/freetype/docs/FTL.TXT b/src/3rdparty/freetype/docs/FTL.TXT index bbaba33f47..c406d150fa 100644 --- a/src/3rdparty/freetype/docs/FTL.TXT +++ b/src/3rdparty/freetype/docs/FTL.TXT @@ -48,7 +48,7 @@ Introduction encourage you to use the following text: """ - Portions of this software are copyright The FreeType + Portions of this software are copyright © The FreeType Project (www.freetype.org). All rights reserved. """ @@ -163,7 +163,7 @@ Legal Terms Our home page can be found at - http://www.freetype.org + https://www.freetype.org --- end of FTL.TXT --- diff --git a/src/3rdparty/freetype/docs/LICENSE.TXT b/src/3rdparty/freetype/docs/LICENSE.TXT index 99dc342d76..af5a1c50f6 100644 --- a/src/3rdparty/freetype/docs/LICENSE.TXT +++ b/src/3rdparty/freetype/docs/LICENSE.TXT @@ -23,9 +23,11 @@ any of your projects or products. GPL. Note that the FTL is incompatible with GPLv2 due to its advertisement clause. -The contributed BDF and PCF drivers come with a license similar to that +The contributed BDF and PCF drivers come with a license similar to that of the X Window System. It is compatible to the above two licenses (see -file src/bdf/README and src/pcf/README). +file src/bdf/README and src/pcf/README). The same holds for the files +`fthash.c' and `fthash.h'; their code was part of the BDF driver in +earlier FreeType versions. The gzip module uses the zlib license (see src/gzip/zlib.h) which too is compatible to the above two licenses. diff --git a/src/3rdparty/freetype/docs/TODO b/src/3rdparty/freetype/docs/TODO index 43eeae349e..1a443a2edc 100644 --- a/src/3rdparty/freetype/docs/TODO +++ b/src/3rdparty/freetype/docs/TODO @@ -27,7 +27,7 @@ Other bugs have been registered at the savannah bugzilla of FreeType. ------------------------------------------------------------------------ -Copyright 2001-2015 by +Copyright 2001-2018 by David Turner, Robert Wilhelm, and Werner Lemberg. This file is part of the FreeType project, and may only be used, diff --git a/src/3rdparty/freetype/include/freetype/config/ftconfig.h b/src/3rdparty/freetype/include/freetype/config/ftconfig.h index d4d79936df..eedebf4082 100644 --- a/src/3rdparty/freetype/include/freetype/config/ftconfig.h +++ b/src/3rdparty/freetype/include/freetype/config/ftconfig.h @@ -4,7 +4,7 @@ /* */ /* ANSI-specific configuration file (specification only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -35,8 +35,8 @@ /* */ /*************************************************************************/ -#ifndef __FTCONFIG_H__ -#define __FTCONFIG_H__ +#ifndef FTCONFIG_H_ +#define FTCONFIG_H_ #include #include FT_CONFIG_OPTIONS_H @@ -73,11 +73,11 @@ FT_BEGIN_HEADER /* The size of an `int' type. */ #if FT_UINT_MAX == 0xFFFFUL -#define FT_SIZEOF_INT (16 / FT_CHAR_BIT) +#define FT_SIZEOF_INT ( 16 / FT_CHAR_BIT ) #elif FT_UINT_MAX == 0xFFFFFFFFUL -#define FT_SIZEOF_INT (32 / FT_CHAR_BIT) +#define FT_SIZEOF_INT ( 32 / FT_CHAR_BIT ) #elif FT_UINT_MAX > 0xFFFFFFFFUL && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFUL -#define FT_SIZEOF_INT (64 / FT_CHAR_BIT) +#define FT_SIZEOF_INT ( 64 / FT_CHAR_BIT ) #else #error "Unsupported size of `int' type!" #endif @@ -85,11 +85,11 @@ FT_BEGIN_HEADER /* The size of a `long' type. A five-byte `long' (as used e.g. on the */ /* DM642) is recognized but avoided. */ #if FT_ULONG_MAX == 0xFFFFFFFFUL -#define FT_SIZEOF_LONG (32 / FT_CHAR_BIT) +#define FT_SIZEOF_LONG ( 32 / FT_CHAR_BIT ) #elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFUL -#define FT_SIZEOF_LONG (32 / FT_CHAR_BIT) +#define FT_SIZEOF_LONG ( 32 / FT_CHAR_BIT ) #elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFUL -#define FT_SIZEOF_LONG (64 / FT_CHAR_BIT) +#define FT_SIZEOF_LONG ( 64 / FT_CHAR_BIT ) #else #error "Unsupported size of `long' type!" #endif @@ -143,6 +143,14 @@ FT_BEGIN_HEADER #endif + /* Fix compiler warning with sgi compiler */ +#if defined( __sgi ) && !defined( __GNUC__ ) +#if defined( _COMPILER_VERSION ) && ( _COMPILER_VERSION >= 730 ) +#pragma set woff 3505 +#endif +#endif + + /*************************************************************************/ /* */ /*
    */ @@ -228,12 +236,12 @@ FT_BEGIN_HEADER #endif -#if FT_SIZEOF_INT == (32 / FT_CHAR_BIT) +#if FT_SIZEOF_INT == ( 32 / FT_CHAR_BIT ) typedef signed int FT_Int32; typedef unsigned int FT_UInt32; -#elif FT_SIZEOF_LONG == (32 / FT_CHAR_BIT) +#elif FT_SIZEOF_LONG == ( 32 / FT_CHAR_BIT ) typedef signed long FT_Int32; typedef unsigned long FT_UInt32; @@ -244,12 +252,12 @@ FT_BEGIN_HEADER /* look up an integer type that is at least 32 bits */ -#if FT_SIZEOF_INT >= (32 / FT_CHAR_BIT) +#if FT_SIZEOF_INT >= ( 32 / FT_CHAR_BIT ) typedef int FT_Fast; typedef unsigned int FT_UFast; -#elif FT_SIZEOF_LONG >= (32 / FT_CHAR_BIT) +#elif FT_SIZEOF_LONG >= ( 32 / FT_CHAR_BIT ) typedef long FT_Fast; typedef unsigned long FT_UFast; @@ -259,7 +267,7 @@ FT_BEGIN_HEADER /* determine whether we have a 64-bit int type for platforms without */ /* Autoconf */ -#if FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) +#if FT_SIZEOF_LONG == ( 64 / FT_CHAR_BIT ) /* FT_LONG64 must be defined if a 64-bit type is available */ #define FT_LONG64 @@ -275,7 +283,13 @@ FT_BEGIN_HEADER /* */ #elif !defined( __STDC__ ) || defined( FT_CONFIG_OPTION_FORCE_INT64 ) -#if defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */ +#if defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 199901L + +#define FT_LONG64 +#define FT_INT64 long long int +#define FT_UINT64 unsigned long long int + +#elif defined( _MSC_VER ) && _MSC_VER >= 900 /* Visual C++ (and Intel C++) */ /* this compiler provides the __int64 type */ #define FT_LONG64 @@ -309,7 +323,7 @@ FT_BEGIN_HEADER #define FT_INT64 long long int #define FT_UINT64 unsigned long long int -#endif /* _MSC_VER */ +#endif /* __STDC_VERSION__ >= 199901L */ #endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */ @@ -319,6 +333,15 @@ FT_BEGIN_HEADER #endif +#ifdef _WIN64 + /* only 64bit Windows uses the LLP64 data model, i.e., */ + /* 32bit integers, 64bit pointers */ +#define FT_UINT_TO_POINTER( x ) (void*)(unsigned __int64)(x) +#else +#define FT_UINT_TO_POINTER( x ) (void*)(unsigned long)(x) +#endif + + /*************************************************************************/ /* */ /* miscellaneous */ @@ -332,15 +355,24 @@ FT_BEGIN_HEADER /* typeof condition taken from gnulib's `intprops.h' header file */ -#if ( __GNUC__ >= 2 || \ - defined( __IBM__TYPEOF__ ) || \ - ( __SUNPRO_C >= 0x5110 && !__STDC__ ) ) -#define FT_TYPEOF( type ) (__typeof__ (type)) +#if ( ( defined( __GNUC__ ) && __GNUC__ >= 2 ) || \ + ( defined( __IBMC__ ) && __IBMC__ >= 1210 && \ + defined( __IBM__TYPEOF__ ) ) || \ + ( defined( __SUNPRO_C ) && __SUNPRO_C >= 0x5110 && !__STDC__ ) ) +#define FT_TYPEOF( type ) ( __typeof__ ( type ) ) #else #define FT_TYPEOF( type ) /* empty */ #endif + /* Use FT_LOCAL and FT_LOCAL_DEF to declare and define, respectively, */ + /* a function that gets used only within the scope of a module. */ + /* Normally, both the header and source code files for such a */ + /* function are within a single module directory. */ + /* */ + /* Intra-module arrays should be tagged with FT_LOCAL_ARRAY and */ + /* FT_LOCAL_ARRAY_DEF. */ + /* */ #ifdef FT_MAKE_OPTION_SINGLE_OBJECT #define FT_LOCAL( x ) static x @@ -362,6 +394,12 @@ FT_BEGIN_HEADER #define FT_LOCAL_ARRAY_DEF( x ) const x + /* Use FT_BASE and FT_BASE_DEF to declare and define, respectively, */ + /* functions that are used in more than a single module. In the */ + /* current setup this implies that the declaration is in a header */ + /* file in the `include/freetype/internal' directory, and the */ + /* function body is in a file in `src/base'. */ + /* */ #ifndef FT_BASE #ifdef __cplusplus @@ -384,14 +422,63 @@ FT_BEGIN_HEADER #endif /* !FT_BASE_DEF */ + /* When compiling FreeType as a DLL or DSO with hidden visibility */ + /* some systems/compilers need a special attribute in front OR after */ + /* the return type of function declarations. */ + /* */ + /* Two macros are used within the FreeType source code to define */ + /* exported library functions: FT_EXPORT and FT_EXPORT_DEF. */ + /* */ + /* FT_EXPORT( return_type ) */ + /* */ + /* is used in a function declaration, as in */ + /* */ + /* FT_EXPORT( FT_Error ) */ + /* FT_Init_FreeType( FT_Library* alibrary ); */ + /* */ + /* */ + /* FT_EXPORT_DEF( return_type ) */ + /* */ + /* is used in a function definition, as in */ + /* */ + /* FT_EXPORT_DEF( FT_Error ) */ + /* FT_Init_FreeType( FT_Library* alibrary ) */ + /* { */ + /* ... some code ... */ + /* return FT_Err_Ok; */ + /* } */ + /* */ + /* You can provide your own implementation of FT_EXPORT and */ + /* FT_EXPORT_DEF here if you want. */ + /* */ + /* To export a variable, use FT_EXPORT_VAR. */ + /* */ #ifndef FT_EXPORT -#ifdef __cplusplus +#ifdef FT2_BUILD_LIBRARY + +#if defined( _WIN32 ) && ( defined( _DLL ) || defined( DLL_EXPORT ) ) +#define FT_EXPORT( x ) __declspec( dllexport ) x +#elif defined( __GNUC__ ) && __GNUC__ >= 4 +#define FT_EXPORT( x ) __attribute__(( visibility( "default" ) )) x +#elif defined( __cplusplus ) #define FT_EXPORT( x ) extern "C" x #else #define FT_EXPORT( x ) extern x #endif +#else + +#if defined( FT2_DLLIMPORT ) +#define FT_EXPORT( x ) __declspec( dllimport ) x +#elif defined( __cplusplus ) +#define FT_EXPORT( x ) extern "C" x +#else +#define FT_EXPORT( x ) extern x +#endif + +#endif + #endif /* !FT_EXPORT */ @@ -416,6 +503,7 @@ FT_BEGIN_HEADER #endif /* !FT_EXPORT_VAR */ + /* The following macros are needed to compile the library with a */ /* C++ compiler and with 16bit compilers. */ /* */ @@ -427,7 +515,13 @@ FT_BEGIN_HEADER /* functions which are accessed by (global) function pointers. */ /* */ /* */ - /* FT_CALLBACK_DEF is used to _define_ a callback function. */ + /* FT_CALLBACK_DEF is used to _define_ a callback function, */ + /* located in the same source code file as the structure that uses */ + /* it. */ + /* */ + /* FT_BASE_CALLBACK and FT_BASE_CALLBACK_DEF are used to declare */ + /* and define a callback function, respectively, in a similar way */ + /* as FT_BASE and FT_BASE_DEF work. */ /* */ /* FT_CALLBACK_TABLE is used to _declare_ a constant variable that */ /* contains pointers to callback functions. */ @@ -447,6 +541,16 @@ FT_BEGIN_HEADER #endif #endif /* FT_CALLBACK_DEF */ +#ifndef FT_BASE_CALLBACK +#ifdef __cplusplus +#define FT_BASE_CALLBACK( x ) extern "C" x +#define FT_BASE_CALLBACK_DEF( x ) extern "C" x +#else +#define FT_BASE_CALLBACK( x ) extern x +#define FT_BASE_CALLBACK_DEF( x ) x +#endif +#endif /* FT_BASE_CALLBACK */ + #ifndef FT_CALLBACK_TABLE #ifdef __cplusplus #define FT_CALLBACK_TABLE extern "C" @@ -461,7 +565,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCONFIG_H__ */ +#endif /* FTCONFIG_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/config/ftheader.h b/src/3rdparty/freetype/include/freetype/config/ftheader.h index 55f833db0f..702f77cc42 100644 --- a/src/3rdparty/freetype/include/freetype/config/ftheader.h +++ b/src/3rdparty/freetype/include/freetype/config/ftheader.h @@ -4,7 +4,7 @@ /* */ /* Build macros of the FreeType 2 library. */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -15,8 +15,8 @@ /* */ /***************************************************************************/ -#ifndef __FT_HEADER_H__ -#define __FT_HEADER_H__ +#ifndef FTHEADER_H_ +#define FTHEADER_H_ /*@***********************************************************************/ @@ -315,6 +315,19 @@ #define FT_RENDER_H + /************************************************************************* + * + * @macro: + * FT_DRIVER_H + * + * @description: + * A macro used in #include statements to name the file containing + * structures and macros related to the driver modules. + * + */ +#define FT_DRIVER_H + + /************************************************************************* * * @macro: @@ -324,8 +337,10 @@ * A macro used in #include statements to name the file containing * structures and macros related to the auto-hinting module. * + * Deprecated since version 2.9; use @FT_DRIVER_H instead. + * */ -#define FT_AUTOHINTER_H +#define FT_AUTOHINTER_H FT_DRIVER_H /************************************************************************* @@ -337,8 +352,10 @@ * A macro used in #include statements to name the file containing * structures and macros related to the CFF driver module. * + * Deprecated since version 2.9; use @FT_DRIVER_H instead. + * */ -#define FT_CFF_DRIVER_H +#define FT_CFF_DRIVER_H FT_DRIVER_H /************************************************************************* @@ -350,8 +367,25 @@ * A macro used in #include statements to name the file containing * structures and macros related to the TrueType driver module. * + * Deprecated since version 2.9; use @FT_DRIVER_H instead. + * */ -#define FT_TRUETYPE_DRIVER_H +#define FT_TRUETYPE_DRIVER_H FT_DRIVER_H + + + /************************************************************************* + * + * @macro: + * FT_PCF_DRIVER_H + * + * @description: + * A macro used in #include statements to name the file containing + * structures and macros related to the PCF driver module. + * + * Deprecated since version 2.9; use @FT_DRIVER_H instead. + * + */ +#define FT_PCF_DRIVER_H FT_DRIVER_H /************************************************************************* @@ -541,63 +575,6 @@ #define FT_CACHE_H - /************************************************************************* - * - * @macro: - * FT_CACHE_IMAGE_H - * - * @description: - * A macro used in #include statements to name the file containing the - * `glyph image' API of the FreeType~2 cache sub-system. - * - * It is used to define a cache for @FT_Glyph elements. You can also - * use the API defined in @FT_CACHE_SMALL_BITMAPS_H if you only need to - * store small glyph bitmaps, as it will use less memory. - * - * This macro is deprecated. Simply include @FT_CACHE_H to have all - * glyph image-related cache declarations. - * - */ -#define FT_CACHE_IMAGE_H FT_CACHE_H - - - /************************************************************************* - * - * @macro: - * FT_CACHE_SMALL_BITMAPS_H - * - * @description: - * A macro used in #include statements to name the file containing the - * `small bitmaps' API of the FreeType~2 cache sub-system. - * - * It is used to define a cache for small glyph bitmaps in a relatively - * memory-efficient way. You can also use the API defined in - * @FT_CACHE_IMAGE_H if you want to cache arbitrary glyph images, - * including scalable outlines. - * - * This macro is deprecated. Simply include @FT_CACHE_H to have all - * small bitmaps-related cache declarations. - * - */ -#define FT_CACHE_SMALL_BITMAPS_H FT_CACHE_H - - - /************************************************************************* - * - * @macro: - * FT_CACHE_CHARMAP_H - * - * @description: - * A macro used in #include statements to name the file containing the - * `charmap' API of the FreeType~2 cache sub-system. - * - * This macro is deprecated. Simply include @FT_CACHE_H to have all - * charmap-based cache declarations. - * - */ -#define FT_CACHE_CHARMAP_H FT_CACHE_H - - /************************************************************************* * * @macro: @@ -747,18 +724,6 @@ #define FT_LCD_FILTER_H - /************************************************************************* - * - * @macro: - * FT_UNPATENTED_HINTING_H - * - * @description: - * A macro used in #include statements to name the file containing the - * FreeType~2 API which performs color filtering for subpixel rendering. - */ -#define FT_UNPATENTED_HINTING_H - - /************************************************************************* * * @macro: @@ -766,7 +731,7 @@ * * @description: * A macro used in #include statements to name the file containing the - * FreeType~2 API which performs color filtering for subpixel rendering. + * FreeType~2 API which performs incremental glyph loading. */ #define FT_INCREMENTAL_H @@ -797,25 +762,30 @@ /* */ + /* These header files don't need to be included by the user. */ #define FT_ERROR_DEFINITIONS_H +#define FT_PARAMETER_TAGS_H + /* Deprecated macros. */ +#define FT_UNPATENTED_HINTING_H +#define FT_TRUETYPE_UNPATENTED_H + + /* FT_CACHE_H is the only header file needed for the cache subsystem. */ +#define FT_CACHE_IMAGE_H FT_CACHE_H +#define FT_CACHE_SMALL_BITMAPS_H FT_CACHE_H +#define FT_CACHE_CHARMAP_H FT_CACHE_H /* The internals of the cache sub-system are no longer exposed. We */ /* default to FT_CACHE_H at the moment just in case, but we know of */ /* no rogue client that uses them. */ /* */ -#define FT_CACHE_MANAGER_H -#define FT_CACHE_INTERNAL_MRU_H -#define FT_CACHE_INTERNAL_MANAGER_H -#define FT_CACHE_INTERNAL_CACHE_H -#define FT_CACHE_INTERNAL_GLYPH_H -#define FT_CACHE_INTERNAL_IMAGE_H -#define FT_CACHE_INTERNAL_SBITS_H - - -#define FT_INCREMENTAL_H - -#define FT_TRUETYPE_UNPATENTED_H +#define FT_CACHE_MANAGER_H FT_CACHE_H +#define FT_CACHE_INTERNAL_MRU_H FT_CACHE_H +#define FT_CACHE_INTERNAL_MANAGER_H FT_CACHE_H +#define FT_CACHE_INTERNAL_CACHE_H FT_CACHE_H +#define FT_CACHE_INTERNAL_GLYPH_H FT_CACHE_H +#define FT_CACHE_INTERNAL_IMAGE_H FT_CACHE_H +#define FT_CACHE_INTERNAL_SBITS_H FT_CACHE_H /* @@ -828,7 +798,7 @@ #endif /* FT2_BUILD_LIBRARY */ -#endif /* __FT2_BUILD_H__ */ +#endif /* FTHEADER_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/config/ftoption.h b/src/3rdparty/freetype/include/freetype/config/ftoption.h index 4970945d15..4bcab2af5c 100644 --- a/src/3rdparty/freetype/include/freetype/config/ftoption.h +++ b/src/3rdparty/freetype/include/freetype/config/ftoption.h @@ -4,7 +4,7 @@ /* */ /* User-selectable configuration macros (specification only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTOPTION_H__ -#define __FTOPTION_H__ +#ifndef FTOPTION_H_ +#define FTOPTION_H_ #include @@ -75,22 +75,52 @@ FT_BEGIN_HEADER /*************************************************************************/ + /*#***********************************************************************/ + /* */ + /* If you enable this configuration option, FreeType recognizes an */ + /* environment variable called `FREETYPE_PROPERTIES', which can be used */ + /* to control the various font drivers and modules. The controllable */ + /* properties are listed in the section @properties. */ + /* */ + /* You have to undefine this configuration option on platforms that lack */ + /* the concept of environment variables (and thus don't have the */ + /* `getenv' function), for example Windows CE. */ + /* */ + /* `FREETYPE_PROPERTIES' has the following syntax form (broken here into */ + /* multiple lines for better readability). */ + /* */ + /* { */ + /* */ + /* ':' */ + /* '=' */ + /* */ + /* ':' */ + /* '=' */ + /* ... */ + /* } */ + /* */ + /* Example: */ + /* */ + /* FREETYPE_PROPERTIES=truetype:interpreter-version=35 \ */ + /* cff:no-stem-darkening=1 \ */ + /* autofitter:warping=1 */ + /* */ +#define FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + + /*************************************************************************/ /* */ - /* Uncomment the line below if you want to activate sub-pixel rendering */ - /* (a.k.a. LCD rendering, or ClearType) in this build of the library. */ + /* Uncomment the line below if you want to activate LCD rendering */ + /* technology similar to ClearType in this build of the library. This */ + /* technology triples the resolution in the direction color subpixels. */ + /* To mitigate color fringes inherent to this technology, you also need */ + /* to explicitly set up LCD filtering. */ /* */ /* Note that this feature is covered by several Microsoft patents */ /* and should not be activated in any default build of the library. */ - /* */ - /* This macro has no impact on the FreeType API, only on its */ - /* _implementation_. For example, using FT_RENDER_MODE_LCD when calling */ - /* FT_Render_Glyph still generates a bitmap that is 3 times wider than */ - /* the original size in case this macro isn't defined; however, each */ - /* triplet of subpixels has R=G=B. */ - /* */ - /* This is done to allow FreeType clients to run unmodified, forcing */ - /* them to display normal gray-level anti-aliased glyphs. */ + /* When this macro is not defined, FreeType offers alternative LCD */ + /* rendering technology that produces excellent output without LCD */ + /* filtering. */ /* */ /* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ @@ -184,6 +214,10 @@ FT_BEGIN_HEADER /* Do not #undef this macro here since the build system might define */ /* it for certain configurations only. */ /* */ + /* If you use a build system like cmake or the `configure' script, */ + /* options set by those programs have precendence, overwriting the */ + /* value here with the configured one. */ + /* */ /* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ @@ -200,6 +234,10 @@ FT_BEGIN_HEADER /* */ /* Define this macro if you want to enable this `feature'. */ /* */ + /* If you use a build system like cmake or the `configure' script, */ + /* options set by those programs have precendence, overwriting the */ + /* value here with the configured one. */ + /* */ /* #define FT_CONFIG_OPTION_USE_BZIP2 */ @@ -225,6 +263,10 @@ FT_BEGIN_HEADER /* */ /* Define this macro if you want to enable this `feature'. */ /* */ + /* If you use a build system like cmake or the `configure' script, */ + /* options set by those programs have precendence, overwriting the */ + /* value here with the configured one. */ + /* */ /* #define FT_CONFIG_OPTION_USE_PNG */ @@ -238,51 +280,13 @@ FT_BEGIN_HEADER /* */ /* Define this macro if you want to enable this `feature'. */ /* */ + /* If you use a build system like cmake or the `configure' script, */ + /* options set by those programs have precendence, overwriting the */ + /* value here with the configured one. */ + /* */ /* #define FT_CONFIG_OPTION_USE_HARFBUZZ */ - /*************************************************************************/ - /* */ - /* DLL export compilation */ - /* */ - /* When compiling FreeType as a DLL, some systems/compilers need a */ - /* special keyword in front OR after the return type of function */ - /* declarations. */ - /* */ - /* Two macros are used within the FreeType source code to define */ - /* exported library functions: FT_EXPORT and FT_EXPORT_DEF. */ - /* */ - /* FT_EXPORT( return_type ) */ - /* */ - /* is used in a function declaration, as in */ - /* */ - /* FT_EXPORT( FT_Error ) */ - /* FT_Init_FreeType( FT_Library* alibrary ); */ - /* */ - /* */ - /* FT_EXPORT_DEF( return_type ) */ - /* */ - /* is used in a function definition, as in */ - /* */ - /* FT_EXPORT_DEF( FT_Error ) */ - /* FT_Init_FreeType( FT_Library* alibrary ) */ - /* { */ - /* ... some code ... */ - /* return FT_Err_Ok; */ - /* } */ - /* */ - /* You can provide your own implementation of FT_EXPORT and */ - /* FT_EXPORT_DEF here if you want. If you leave them undefined, they */ - /* will be later automatically defined as `extern return_type' to */ - /* allow normal compilation. */ - /* */ - /* Do not #undef these macros here since the build system might define */ - /* them for certain configurations only. */ - /* */ -/* #define FT_EXPORT(x) extern x */ -/* #define FT_EXPORT_DEF(x) x */ - - /*************************************************************************/ /* */ /* Glyph Postscript Names handling */ @@ -297,7 +301,7 @@ FT_BEGIN_HEADER /* */ /* - The TrueType driver will provide its own set of glyph names, */ /* if you build it to support postscript names in the TrueType */ - /* `post' table. */ + /* `post' table, but will not synthesize a missing Unicode charmap. */ /* */ /* - The Type 1 driver will not be able to synthesize a Unicode */ /* charmap out of the glyphs found in the fonts. */ @@ -492,7 +496,21 @@ FT_BEGIN_HEADER /* code will be used. */ /* */ /* Setting this macro is needed for systems that prohibit address */ - /* fixups, such as BREW. */ + /* fixups, such as BREW. [Note that standard compilers like gcc or */ + /* clang handle PIC generation automatically; you don't have to set */ + /* FT_CONFIG_OPTION_PIC, which is only necessary for very special */ + /* compilers.] */ + /* */ + /* Note that FT_CONFIG_OPTION_PIC support is not available for all */ + /* modules (see `modules.cfg' for a complete list). For building with */ + /* FT_CONFIG_OPTION_PIC support, do the following. */ + /* */ + /* 0. Clone the repository. */ + /* 1. Define FT_CONFIG_OPTION_PIC. */ + /* 2. Remove all subdirectories in `src' that don't have */ + /* FT_CONFIG_OPTION_PIC support. */ + /* 3. Comment out the corresponding modules in `modules.cfg'. */ + /* 4. Compile. */ /* */ /* #define FT_CONFIG_OPTION_PIC */ @@ -586,73 +604,62 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile */ - /* EXPERIMENTAL subpixel hinting support into the TrueType driver. This */ - /* replaces the native TrueType hinting mechanism when anything but */ - /* FT_RENDER_MODE_MONO is requested. */ + /* subpixel hinting support into the TrueType driver. This modifies the */ + /* TrueType hinting mechanism when anything but FT_RENDER_MODE_MONO is */ + /* requested. */ /* */ - /* Enabling this causes the TrueType driver to ignore instructions under */ - /* certain conditions. This is done in accordance with the guide here, */ - /* with some minor differences: */ + /* In particular, it modifies the bytecode interpreter to interpret (or */ + /* not) instructions in a certain way so that all TrueType fonts look */ + /* like they do in a Windows ClearType (DirectWrite) environment. See */ + /* [1] for a technical overview on what this means. See `ttinterp.h' */ + /* for more details on the LEAN option. */ /* */ - /* http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */ + /* There are three possible values. */ /* */ - /* By undefining this, you only compile the code necessary to hint */ - /* TrueType glyphs with native TT hinting. */ + /* Value 1: */ + /* This value is associated with the `Infinality' moniker, */ + /* contributed by an individual nicknamed Infinality with the goal of */ + /* making TrueType fonts render better than on Windows. A high */ + /* amount of configurability and flexibility, down to rules for */ + /* single glyphs in fonts, but also very slow. Its experimental and */ + /* slow nature and the original developer losing interest meant that */ + /* this option was never enabled in default builds. */ /* */ - /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */ - /* defined. */ + /* The corresponding interpreter version is v38. */ /* */ -/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - - /*************************************************************************/ + /* Value 2: */ + /* The new default mode for the TrueType driver. The Infinality code */ + /* base was stripped to the bare minimum and all configurability */ + /* removed in the name of speed and simplicity. The configurability */ + /* was mainly aimed at legacy fonts like Arial, Times New Roman, or */ + /* Courier. Legacy fonts are fonts that modify vertical stems to */ + /* achieve clean black-and-white bitmaps. The new mode focuses on */ + /* applying a minimal set of rules to all fonts indiscriminately so */ + /* that modern and web fonts render well while legacy fonts render */ + /* okay. */ /* */ - /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */ - /* of the TrueType bytecode interpreter is used that doesn't implement */ - /* any of the patented opcodes and algorithms. The patents related to */ - /* TrueType hinting have expired worldwide since May 2010; this option */ - /* is now deprecated. */ + /* The corresponding interpreter version is v40. */ /* */ - /* Note that the TT_CONFIG_OPTION_UNPATENTED_HINTING macro is *ignored* */ - /* if you define TT_CONFIG_OPTION_BYTECODE_INTERPRETER; in other words, */ - /* either define TT_CONFIG_OPTION_BYTECODE_INTERPRETER or */ - /* TT_CONFIG_OPTION_UNPATENTED_HINTING but not both at the same time. */ + /* Value 3: */ + /* Compile both, making both v38 and v40 available (the latter is the */ + /* default). */ /* */ - /* This macro is only useful for a small number of font files (mostly */ - /* for Asian scripts) that require bytecode interpretation to properly */ - /* load glyphs. For all other fonts, this produces unpleasant results, */ - /* thus the unpatented interpreter is never used to load glyphs from */ - /* TrueType fonts unless one of the following two options is used. */ + /* By undefining these, you get rendering behavior like on Windows */ + /* without ClearType, i.e., Windows XP without ClearType enabled and */ + /* Win9x (interpreter version v35). Or not, depending on how much */ + /* hinting blood and testing tears the font designer put into a given */ + /* font. If you define one or both subpixel hinting options, you can */ + /* switch between between v35 and the ones you define (using */ + /* `FT_Property_Set'). */ /* */ - /* - The unpatented interpreter is explicitly activated by the user */ - /* through the FT_PARAM_TAG_UNPATENTED_HINTING parameter tag */ - /* when opening the FT_Face. */ + /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be */ + /* defined. */ /* */ - /* - FreeType detects that the FT_Face corresponds to one of the */ - /* `trick' fonts (e.g., `Mingliu') it knows about. The font engine */ - /* contains a hard-coded list of font names and other matching */ - /* parameters (see function `tt_face_init' in file */ - /* `src/truetype/ttobjs.c'). */ + /* [1] https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */ /* */ - /* Here a sample code snippet for using FT_PARAM_TAG_UNPATENTED_HINTING. */ - /* */ - /* { */ - /* FT_Parameter parameter; */ - /* FT_Open_Args open_args; */ - /* */ - /* */ - /* parameter.tag = FT_PARAM_TAG_UNPATENTED_HINTING; */ - /* */ - /* open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; */ - /* open_args.pathname = my_font_pathname; */ - /* open_args.num_params = 1; */ - /* open_args.params = ¶meter; */ - /* */ - /* error = FT_Open_Face( library, &open_args, index, &face ); */ - /* ... */ - /* } */ - /* */ -/* #define TT_CONFIG_OPTION_UNPATENTED_HINTING */ +/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING 1 */ +#define TT_CONFIG_OPTION_SUBPIXEL_HINTING 2 +/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING ( 1 | 2 ) */ /*************************************************************************/ @@ -668,7 +675,7 @@ FT_BEGIN_HEADER /* composite flags array which can be used to disambiguate, but old */ /* fonts will not have them. */ /* */ - /* http://www.microsoft.com/typography/otspec/glyf.htm */ + /* https://www.microsoft.com/typography/otspec/glyf.htm */ /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6glyf.html */ /* */ #undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED @@ -692,6 +699,24 @@ FT_BEGIN_HEADER #define TT_CONFIG_OPTION_BDF + /*************************************************************************/ + /* */ + /* Option TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES controls the maximum */ + /* number of bytecode instructions executed for a single run of the */ + /* bytecode interpreter, needed to prevent infinite loops. You don't */ + /* want to change this except for very special situations (e.g., making */ + /* a library fuzzer spend less time to handle broken fonts). */ + /* */ + /* It is not expected that this value is ever modified by a configuring */ + /* script; instead, it gets surrounded with #ifndef ... #endif so that */ + /* the value can be set as a preprocessor option on the compiler's */ + /* command line. */ + /* */ +#ifndef TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES +#define TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES 1000000L +#endif + + /*************************************************************************/ /*************************************************************************/ /**** ****/ @@ -747,6 +772,16 @@ FT_BEGIN_HEADER #undef T1_CONFIG_OPTION_NO_MM_SUPPORT + /*************************************************************************/ + /* */ + /* T1_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe Type 1 */ + /* engine gets compiled into FreeType. If defined, it is possible to */ + /* switch between the two engines using the `hinting-engine' property of */ + /* the type1 driver module. */ + /* */ +/* #define T1_CONFIG_OPTION_OLD_ENGINE */ + + /*************************************************************************/ /*************************************************************************/ /**** ****/ @@ -762,8 +797,8 @@ FT_BEGIN_HEADER /* possible to set up the default values of the four control points that */ /* define the stem darkening behaviour of the (new) CFF engine. For */ /* more details please read the documentation of the */ - /* `darkening-parameters' property of the cff driver module (file */ - /* `ftcffdrv.h'), which allows the control at run-time. */ + /* `darkening-parameters' property (file `ftdriver.h'), which allows the */ + /* control at run-time. */ /* */ /* Do *not* undefine these macros! */ /* */ @@ -790,6 +825,33 @@ FT_BEGIN_HEADER /* #define CFF_CONFIG_OPTION_OLD_ENGINE */ + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** P C F D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* There are many PCF fonts just called `Fixed' which look completely */ + /* different, and which have nothing to do with each other. When */ + /* selecting `Fixed' in KDE or Gnome one gets results that appear rather */ + /* random, the style changes often if one changes the size and one */ + /* cannot select some fonts at all. This option makes the PCF module */ + /* prepend the foundry name (plus a space) to the family name. */ + /* */ + /* We also check whether we have `wide' characters; all put together, we */ + /* get family names like `Sony Fixed' or `Misc Fixed Wide'. */ + /* */ + /* If this option is activated, it can be controlled with the */ + /* `no-long-family-names' property of the pcf driver module. */ + /* */ +/* #define PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */ + + /*************************************************************************/ /*************************************************************************/ /**** ****/ @@ -808,7 +870,9 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ - /* Compile autofit module with Indic script support. */ + /* Compile autofit module with fallback Indic script support, covering */ + /* some scripts that the `latin' submodule of the autofit module doesn't */ + /* (yet) handle. */ /* */ #define AF_CONFIG_OPTION_INDIC @@ -822,11 +886,31 @@ FT_BEGIN_HEADER /* */ /* This experimental option is active only if the rendering mode is */ /* FT_RENDER_MODE_LIGHT; you can switch warping on and off with the */ - /* `warping' property of the auto-hinter (see file `ftautoh.h' for more */ + /* `warping' property of the auto-hinter (see file `ftdriver.h' for more */ /* information; by default it is switched off). */ /* */ #define AF_CONFIG_OPTION_USE_WARPER + /*************************************************************************/ + /* */ + /* Use TrueType-like size metrics for `light' auto-hinting. */ + /* */ + /* It is strongly recommended to avoid this option, which exists only to */ + /* help some legacy applications retain its appearance and behaviour */ + /* with respect to auto-hinted TrueType fonts. */ + /* */ + /* The very reason this option exists at all are GNU/Linux distributions */ + /* like Fedora that did not un-patch the following change (which was */ + /* present in FreeType between versions 2.4.6 and 2.7.1, inclusive). */ + /* */ + /* 2011-07-16 Steven Chu */ + /* */ + /* [truetype] Fix metrics on size request for scalable fonts. */ + /* */ + /* This problematic commit is now reverted (more or less). */ + /* */ +/* #define AF_CONFIG_OPTION_TT_SIZE_METRICS */ + /* */ @@ -838,14 +922,21 @@ FT_BEGIN_HEADER /* - * This macro is defined if either unpatented or native TrueType - * hinting is requested by the definitions above. + * This macro is defined if native TrueType hinting is requested by the + * definitions above. */ #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER #define TT_USE_BYTECODE_INTERPRETER -#undef TT_CONFIG_OPTION_UNPATENTED_HINTING -#elif defined TT_CONFIG_OPTION_UNPATENTED_HINTING -#define TT_USE_BYTECODE_INTERPRETER + +#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 1 +#define TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY +#endif + +#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 2 +#define TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL +#endif +#endif #endif @@ -880,7 +971,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTOPTION_H__ */ +#endif /* FTOPTION_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/config/ftstdlib.h b/src/3rdparty/freetype/include/freetype/config/ftstdlib.h index 4b471d4d15..42f9a06e43 100644 --- a/src/3rdparty/freetype/include/freetype/config/ftstdlib.h +++ b/src/3rdparty/freetype/include/freetype/config/ftstdlib.h @@ -5,7 +5,7 @@ /* ANSI-specific library and header configuration file (specification */ /* only). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,14 +23,13 @@ /* FreeType normally requires. It also defines macros to rename the */ /* standard functions within the FreeType source code. */ /* */ - /* Load a file which defines __FTSTDLIB_H__ before this one to override */ - /* it. */ + /* Load a file which defines FTSTDLIB_H_ before this one to override it. */ /* */ /*************************************************************************/ -#ifndef __FTSTDLIB_H__ -#define __FTSTDLIB_H__ +#ifndef FTSTDLIB_H_ +#define FTSTDLIB_H_ #include @@ -64,6 +63,7 @@ #define FT_INT_MAX INT_MAX #define FT_INT_MIN INT_MIN #define FT_UINT_MAX UINT_MAX +#define FT_LONG_MIN LONG_MIN #define FT_LONG_MAX LONG_MAX #define FT_ULONG_MAX ULONG_MAX @@ -142,7 +142,8 @@ /**********************************************************************/ -#define ft_atol atol +#define ft_strtol strtol +#define ft_getenv getenv /**********************************************************************/ @@ -168,7 +169,7 @@ #include -#endif /* __FTSTDLIB_H__ */ +#endif /* FTSTDLIB_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/freetype.h b/src/3rdparty/freetype/include/freetype/freetype.h index b6247f510f..96644046e4 100644 --- a/src/3rdparty/freetype/include/freetype/freetype.h +++ b/src/3rdparty/freetype/include/freetype/freetype.h @@ -4,7 +4,7 @@ /* */ /* FreeType high-level API and common types (specification only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FREETYPE_H__ -#define __FREETYPE_H__ +#ifndef FREETYPE_H_ +#define FREETYPE_H_ #ifndef FT_FREETYPE_H @@ -138,24 +138,26 @@ FT_BEGIN_HEADER /* FT_FACE_FLAG_TRICKY */ /* FT_FACE_FLAG_KERNING */ /* FT_FACE_FLAG_MULTIPLE_MASTERS */ + /* FT_FACE_FLAG_VARIATION */ /* FT_FACE_FLAG_GLYPH_NAMES */ /* FT_FACE_FLAG_EXTERNAL_STREAM */ /* FT_FACE_FLAG_HINTER */ - /* FT_FACE_FLAG_TRICKY */ /* */ /* FT_HAS_HORIZONTAL */ /* FT_HAS_VERTICAL */ /* FT_HAS_KERNING */ /* FT_HAS_FIXED_SIZES */ /* FT_HAS_GLYPH_NAMES */ - /* FT_HAS_MULTIPLE_MASTERS */ /* FT_HAS_COLOR */ + /* FT_HAS_MULTIPLE_MASTERS */ /* */ /* FT_IS_SFNT */ /* FT_IS_SCALABLE */ /* FT_IS_FIXED_WIDTH */ /* FT_IS_CID_KEYED */ /* FT_IS_TRICKY */ + /* FT_IS_NAMED_INSTANCE */ + /* FT_IS_VARIATION */ /* */ /* FT_STYLE_FLAG_BOLD */ /* FT_STYLE_FLAG_ITALIC */ @@ -176,6 +178,7 @@ FT_BEGIN_HEADER /* FT_Done_Face */ /* FT_Reference_Face */ /* FT_New_Memory_Face */ + /* FT_Face_Properties */ /* FT_Open_Face */ /* FT_Open_Args */ /* FT_Parameter */ @@ -266,8 +269,8 @@ FT_BEGIN_HEADER /* FT_Glyph_Metrics */ /* */ /* */ - /* A structure used to model the metrics of a single glyph. The */ - /* values are expressed in 26.6 fractional pixel format; if the flag */ + /* A structure to model the metrics of a single glyph. The values */ + /* are expressed in 26.6 fractional pixel format; if the flag */ /* @FT_LOAD_NO_SCALE has been used while loading the glyph, values */ /* are expressed in font units instead. */ /* */ @@ -306,6 +309,11 @@ FT_BEGIN_HEADER /* `horiAdvance' or `vertAdvance'; you have to manually adjust these */ /* values to account for the added width and height. */ /* */ + /* FreeType doesn't use the `VORG' table data for CFF fonts because */ + /* it doesn't have an interface to quickly retrieve the glyph height. */ + /* The y~coordinate of the vertical origin can be simply computed as */ + /* `vertBearingY + height' after loading a glyph. */ + /* */ typedef struct FT_Glyph_Metrics_ { FT_Pos width; @@ -350,10 +358,10 @@ FT_BEGIN_HEADER /* */ /* */ /* Windows FNT: */ - /* The nominal size given in a FNT font is not reliable. Thus when */ - /* the driver finds it incorrect, it sets `size' to some calculated */ - /* values and sets `x_ppem' and `y_ppem' to the pixel width and */ - /* height given in the font, respectively. */ + /* The nominal size given in a FNT font is not reliable. If the */ + /* driver finds it incorrect, it sets `size' to some calculated */ + /* values, and `x_ppem' and `y_ppem' to the pixel width and height */ + /* given in the font, respectively. */ /* */ /* TrueType embedded bitmaps: */ /* `size', `width', and `height' values are not contained in the */ @@ -422,9 +430,9 @@ FT_BEGIN_HEADER /* FT_Module */ /* */ /* */ - /* A handle to a given FreeType module object. Each module can be a */ + /* A handle to a given FreeType module object. A module can be a */ /* font driver, a renderer, or anything else that provides services */ - /* to the formers. */ + /* to the former. */ /* */ typedef struct FT_ModuleRec_* FT_Module; @@ -435,8 +443,8 @@ FT_BEGIN_HEADER /* FT_Driver */ /* */ /* */ - /* A handle to a given FreeType font driver object. Each font driver */ - /* is a special module capable of creating faces from font files. */ + /* A handle to a given FreeType font driver object. A font driver */ + /* is a module capable of creating faces from font files. */ /* */ typedef struct FT_DriverRec_* FT_Driver; @@ -447,10 +455,10 @@ FT_BEGIN_HEADER /* FT_Renderer */ /* */ /* */ - /* A handle to a given FreeType renderer. A renderer is a special */ - /* module in charge of converting a glyph image to a bitmap, when */ - /* necessary. Each renderer supports a given glyph image format, and */ - /* one or more target surface depths. */ + /* A handle to a given FreeType renderer. A renderer is a module in */ + /* charge of converting a glyph's outline image to a bitmap. It */ + /* supports a single glyph image format, and one or more target */ + /* surface depths. */ /* */ typedef struct FT_RendererRec_* FT_Renderer; @@ -468,15 +476,15 @@ FT_BEGIN_HEADER /* FT_Face */ /* */ /* */ - /* A handle to a given typographic face object. A face object models */ - /* a given typeface, in a given style. */ + /* A handle to a typographic face object. A face object models a */ + /* given typeface, in a given style. */ /* */ /* */ - /* Each face object also owns a single @FT_GlyphSlot object, as well */ + /* A face object also owns a single @FT_GlyphSlot object, as well */ /* as one or more @FT_Size objects. */ /* */ /* Use @FT_New_Face or @FT_Open_Face to create a new face object from */ - /* a given filepathname or a custom input stream. */ + /* a given filepath or a custom input stream. */ /* */ /* Use @FT_Done_Face to destroy it (along with its slot and sizes). */ /* */ @@ -501,11 +509,11 @@ FT_BEGIN_HEADER /* FT_Size */ /* */ /* */ - /* A handle to an object used to model a face scaled to a given */ + /* A handle to an object that models a face scaled to a given */ /* character size. */ /* */ /* */ - /* Each @FT_Face has an _active_ @FT_Size object that is used by */ + /* An @FT_Face has one _active_ @FT_Size object that is used by */ /* functions like @FT_Load_Glyph to determine the scaling */ /* transformation that in turn is used to load and hint glyphs and */ /* metrics. */ @@ -532,9 +540,8 @@ FT_BEGIN_HEADER /* FT_GlyphSlot */ /* */ /* */ - /* A handle to a given `glyph slot'. A slot is a container where it */ - /* is possible to load any of the glyphs contained in its parent */ - /* face. */ + /* A handle to a given `glyph slot'. A slot is a container that can */ + /* hold any of the glyphs contained in its parent face. */ /* */ /* In other words, each time you call @FT_Load_Glyph or */ /* @FT_Load_Char, the slot's content is erased by the new glyph data, */ @@ -553,13 +560,14 @@ FT_BEGIN_HEADER /* FT_CharMap */ /* */ /* */ - /* A handle to a given character map. A charmap is used to translate */ - /* character codes in a given encoding into glyph indexes for its */ - /* parent's face. Some font formats may provide several charmaps per */ - /* font. */ + /* A handle to a character map (usually abbreviated to `charmap'). A */ + /* charmap is used to translate character codes in a given encoding */ + /* into glyph indexes for its parent's face. Some font formats may */ + /* provide several charmaps per font. */ /* */ /* Each face object owns zero or more charmaps, but only one of them */ - /* can be `active' and used by @FT_Get_Char_Index or @FT_Load_Char. */ + /* can be `active', providing the data used by @FT_Get_Char_Index or */ + /* @FT_Load_Char. */ /* */ /* The list of available charmaps in a face is available through the */ /* `face->num_charmaps' and `face->charmaps' fields of @FT_FaceRec. */ @@ -570,7 +578,8 @@ FT_BEGIN_HEADER /* */ /* When a new face is created (either through @FT_New_Face or */ /* @FT_Open_Face), the library looks for a Unicode charmap within */ - /* the list and automatically activates it. */ + /* the list and automatically activates it. If there is no Unicode */ + /* charmap, FreeType doesn't set an `active' charmap. */ /* */ /* */ /* See @FT_CharMapRec for the publicly accessible fields of a given */ @@ -616,8 +625,8 @@ FT_BEGIN_HEADER /* FT_Encoding */ /* */ /* */ - /* An enumeration used to specify character sets supported by */ - /* charmaps. Used in the @FT_Select_Charmap API function. */ + /* An enumeration to specify character sets supported by charmaps. */ + /* Used in the @FT_Select_Charmap API function. */ /* */ /* */ /* Despite the name, this enumeration lists specific character */ @@ -631,19 +640,18 @@ FT_BEGIN_HEADER /* The encoding value~0 is reserved. */ /* */ /* FT_ENCODING_UNICODE :: */ - /* Corresponds to the Unicode character set. This value covers */ - /* all versions of the Unicode repertoire, including ASCII and */ - /* Latin-1. Most fonts include a Unicode charmap, but not all */ - /* of them. */ + /* The Unicode character set. This value covers all versions of */ + /* the Unicode repertoire, including ASCII and Latin-1. Most fonts */ + /* include a Unicode charmap, but not all of them. */ /* */ /* For example, if you want to access Unicode value U+1F028 (and */ /* the font contains it), use value 0x1F028 as the input value for */ /* @FT_Get_Char_Index. */ /* */ /* FT_ENCODING_MS_SYMBOL :: */ - /* Corresponds to the Microsoft Symbol encoding, used to encode */ - /* mathematical symbols and wingdings. For more information, see */ - /* `http://www.microsoft.com/typography/otspec/recom.htm', */ + /* Microsoft Symbol encoding, used to encode mathematical symbols */ + /* and wingdings. For more information, see */ + /* `https://www.microsoft.com/typography/otspec/recom.htm', */ /* `http://www.kostis.net/charsets/symbol.htm', and */ /* `http://www.kostis.net/charsets/wingding.htm'. */ /* */ @@ -651,60 +659,60 @@ FT_BEGIN_HEADER /* Area) in the range U+F020-U+F0FF. */ /* */ /* FT_ENCODING_SJIS :: */ - /* Corresponds to Japanese SJIS encoding. More info at */ - /* at `http://en.wikipedia.org/wiki/Shift_JIS'. */ - /* See note on multi-byte encodings below. */ + /* Shift JIS encoding for Japanese. More info at */ + /* `https://en.wikipedia.org/wiki/Shift_JIS'. See note on */ + /* multi-byte encodings below. */ /* */ - /* FT_ENCODING_GB2312 :: */ - /* Corresponds to an encoding system for Simplified Chinese as used */ - /* used in mainland China. */ + /* FT_ENCODING_PRC :: */ + /* Corresponds to encoding systems mainly for Simplified Chinese as */ + /* used in People's Republic of China (PRC). The encoding layout */ + /* is based on GB~2312 and its supersets GBK and GB~18030. */ /* */ /* FT_ENCODING_BIG5 :: */ /* Corresponds to an encoding system for Traditional Chinese as */ /* used in Taiwan and Hong Kong. */ /* */ /* FT_ENCODING_WANSUNG :: */ - /* Corresponds to the Korean encoding system known as Wansung. */ + /* Corresponds to the Korean encoding system known as Extended */ + /* Wansung (MS Windows code page 949). */ /* For more information see */ - /* `https://msdn.microsoft.com/en-US/goglobal/cc305154'. */ + /* `https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/bestfit949.txt'. */ /* */ /* FT_ENCODING_JOHAB :: */ /* The Korean standard character set (KS~C 5601-1992), which */ /* corresponds to MS Windows code page 1361. This character set */ - /* includes all possible Hangeul character combinations. */ + /* includes all possible Hangul character combinations. */ /* */ /* FT_ENCODING_ADOBE_LATIN_1 :: */ /* Corresponds to a Latin-1 encoding as defined in a Type~1 */ /* PostScript font. It is limited to 256 character codes. */ /* */ /* FT_ENCODING_ADOBE_STANDARD :: */ - /* Corresponds to the Adobe Standard encoding, as found in Type~1, */ - /* CFF, and OpenType/CFF fonts. It is limited to 256 character */ - /* codes. */ + /* Adobe Standard encoding, as found in Type~1, CFF, and */ + /* OpenType/CFF fonts. It is limited to 256 character codes. */ /* */ /* FT_ENCODING_ADOBE_EXPERT :: */ - /* Corresponds to the Adobe Expert encoding, as found in Type~1, */ - /* CFF, and OpenType/CFF fonts. It is limited to 256 character */ - /* codes. */ + /* Adobe Expert encoding, as found in Type~1, CFF, and OpenType/CFF */ + /* fonts. It is limited to 256 character codes. */ /* */ /* FT_ENCODING_ADOBE_CUSTOM :: */ /* Corresponds to a custom encoding, as found in Type~1, CFF, and */ /* OpenType/CFF fonts. It is limited to 256 character codes. */ /* */ /* FT_ENCODING_APPLE_ROMAN :: */ - /* Corresponds to the 8-bit Apple roman encoding. Many TrueType */ - /* and OpenType fonts contain a charmap for this encoding, since */ - /* older versions of Mac OS are able to use it. */ + /* Apple roman encoding. Many TrueType and OpenType fonts contain */ + /* a charmap for this 8-bit encoding, since older versions of Mac */ + /* OS are able to use it. */ /* */ /* FT_ENCODING_OLD_LATIN_2 :: */ - /* This value is deprecated and was never used nor reported by */ + /* This value is deprecated and was neither used nor reported by */ /* FreeType. Don't use or test for it. */ /* */ /* FT_ENCODING_MS_SJIS :: */ /* Same as FT_ENCODING_SJIS. Deprecated. */ /* */ /* FT_ENCODING_MS_GB2312 :: */ - /* Same as FT_ENCODING_GB2312. Deprecated. */ + /* Same as FT_ENCODING_PRC. Deprecated. */ /* */ /* FT_ENCODING_MS_BIG5 :: */ /* Same as FT_ENCODING_BIG5. Deprecated. */ @@ -716,11 +724,12 @@ FT_BEGIN_HEADER /* Same as FT_ENCODING_JOHAB. Deprecated. */ /* */ /* */ - /* By default, FreeType automatically synthesizes a Unicode charmap */ - /* for PostScript fonts, using their glyph names dictionaries. */ - /* However, it also reports the encodings defined explicitly in the */ - /* font file, for the cases when they are needed, with the Adobe */ - /* values as well. */ + /* By default, FreeType enables a Unicode charmap and tags it with */ + /* FT_ENCODING_UNICODE when it is either provided or can be generated */ + /* from PostScript glyph name dictionaries in the font file. */ + /* All other encodings are considered legacy and tagged only if */ + /* explicitly defined in the font file. Otherwise, FT_ENCODING_NONE */ + /* is used. */ /* */ /* FT_ENCODING_NONE is set by the BDF and PCF drivers if the charmap */ /* is neither Unicode nor ISO-8859-1 (otherwise it is set to */ @@ -737,21 +746,21 @@ FT_BEGIN_HEADER /* Russian). */ /* */ /* FT_ENCODING_NONE is set if `platform_id' is @TT_PLATFORM_MACINTOSH */ - /* and `encoding_id' is not @TT_MAC_ID_ROMAN (otherwise it is set to */ + /* and `encoding_id' is not `TT_MAC_ID_ROMAN' (otherwise it is set to */ /* FT_ENCODING_APPLE_ROMAN). */ /* */ /* If `platform_id' is @TT_PLATFORM_MACINTOSH, use the function */ /* @FT_Get_CMap_Language_ID to query the Mac language ID that may */ /* be needed to be able to distinguish Apple encoding variants. See */ /* */ - /* http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/Readme.txt */ + /* https://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/Readme.txt */ /* */ /* to get an idea how to do that. Basically, if the language ID */ /* is~0, don't use it, otherwise subtract 1 from the language ID. */ /* Then examine `encoding_id'. If, for example, `encoding_id' is */ - /* @TT_MAC_ID_ROMAN and the language ID (minus~1) is */ + /* `TT_MAC_ID_ROMAN' and the language ID (minus~1) is */ /* `TT_MAC_LANGID_GREEK', it is the Greek encoding, not Roman. */ - /* @TT_MAC_ID_ARABIC with `TT_MAC_LANGID_FARSI' means the Farsi */ + /* `TT_MAC_ID_ARABIC' with `TT_MAC_LANGID_FARSI' means the Farsi */ /* variant the Arabic encoding. */ /* */ typedef enum FT_Encoding_ @@ -762,14 +771,15 @@ FT_BEGIN_HEADER FT_ENC_TAG( FT_ENCODING_UNICODE, 'u', 'n', 'i', 'c' ), FT_ENC_TAG( FT_ENCODING_SJIS, 's', 'j', 'i', 's' ), - FT_ENC_TAG( FT_ENCODING_GB2312, 'g', 'b', ' ', ' ' ), + FT_ENC_TAG( FT_ENCODING_PRC, 'g', 'b', ' ', ' ' ), FT_ENC_TAG( FT_ENCODING_BIG5, 'b', 'i', 'g', '5' ), FT_ENC_TAG( FT_ENCODING_WANSUNG, 'w', 'a', 'n', 's' ), FT_ENC_TAG( FT_ENCODING_JOHAB, 'j', 'o', 'h', 'a' ), - /* for backwards compatibility */ + /* for backward compatibility */ + FT_ENCODING_GB2312 = FT_ENCODING_PRC, FT_ENCODING_MS_SJIS = FT_ENCODING_SJIS, - FT_ENCODING_MS_GB2312 = FT_ENCODING_GB2312, + FT_ENCODING_MS_GB2312 = FT_ENCODING_PRC, FT_ENCODING_MS_BIG5 = FT_ENCODING_BIG5, FT_ENCODING_MS_WANSUNG = FT_ENCODING_WANSUNG, FT_ENCODING_MS_JOHAB = FT_ENCODING_JOHAB, @@ -794,7 +804,7 @@ FT_BEGIN_HEADER #define ft_encoding_latin_1 FT_ENCODING_ADOBE_LATIN_1 #define ft_encoding_latin_2 FT_ENCODING_OLD_LATIN_2 #define ft_encoding_sjis FT_ENCODING_SJIS -#define ft_encoding_gb2312 FT_ENCODING_GB2312 +#define ft_encoding_gb2312 FT_ENCODING_PRC #define ft_encoding_big5 FT_ENCODING_BIG5 #define ft_encoding_wansung FT_ENCODING_WANSUNG #define ft_encoding_johab FT_ENCODING_JOHAB @@ -821,11 +831,11 @@ FT_BEGIN_HEADER /* */ /* platform_id :: An ID number describing the platform for the */ /* following encoding ID. This comes directly from */ - /* the TrueType specification and should be emulated */ - /* for other formats. */ + /* the TrueType specification and gets emulated for */ + /* other formats. */ /* */ /* encoding_id :: A platform specific encoding number. This also */ - /* comes from the TrueType specification and should be */ + /* comes from the TrueType specification and gets */ /* emulated similarly. */ /* */ typedef struct FT_CharMapRec_ @@ -853,8 +863,8 @@ FT_BEGIN_HEADER /* FT_Face_Internal */ /* */ /* */ - /* An opaque handle to an `FT_Face_InternalRec' structure, used to */ - /* model private data of a given @FT_Face object. */ + /* An opaque handle to an `FT_Face_InternalRec' structure that models */ + /* the private data of a given @FT_Face object. */ /* */ /* This structure might change between releases of FreeType~2 and is */ /* not generally available to client applications. */ @@ -874,7 +884,7 @@ FT_BEGIN_HEADER /* */ /* num_faces :: The number of faces in the font file. Some */ /* font formats can have multiple faces in */ - /* a font file. */ + /* a single font file. */ /* */ /* face_index :: This field holds two different values. */ /* Bits 0-15 are the index of the face in the */ @@ -882,38 +892,50 @@ FT_BEGIN_HEADER /* are set to~0 if there is only one face in */ /* the font file. */ /* */ - /* Bits 16-30 are relevant to GX variation */ - /* fonts only, holding the named instance */ - /* index for the current face index (starting */ - /* with value~1; value~0 indicates font access */ - /* without GX variation data). For non-GX */ - /* fonts, bits 16-30 are ignored. If we have */ - /* the third named instance of face~4, say, */ - /* `face_index' is set to 0x00030004. */ + /* [Since 2.6.1] Bits 16-30 are relevant to GX */ + /* and OpenType variation fonts only, holding */ + /* the named instance index for the current */ + /* face index (starting with value~1; value~0 */ + /* indicates font access without a named */ + /* instance). For non-variation fonts, bits */ + /* 16-30 are ignored. If we have the third */ + /* named instance of face~4, say, `face_index' */ + /* is set to 0x00030004. */ /* */ /* Bit 31 is always zero (this is, */ /* `face_index' is always a positive value). */ /* */ + /* [Since 2.9] Changing the design coordinates */ + /* with @FT_Set_Var_Design_Coordinates or */ + /* @FT_Set_Var_Blend_Coordinates does not */ + /* influence the named instance index value */ + /* (only @FT_Set_Named_Instance does that). */ + /* */ /* face_flags :: A set of bit flags that give important */ /* information about the face; see */ /* @FT_FACE_FLAG_XXX for the details. */ /* */ /* style_flags :: The lower 16~bits contain a set of bit */ /* flags indicating the style of the face; see */ - /* @FT_STYLE_FLAG_XXX for the details. Bits */ - /* 16-30 hold the number of named instances */ - /* available for the current face if we have a */ - /* GX variation (sub)font. Bit 31 is always */ - /* zero (this is, `style_flags' is always a */ - /* positive value). */ + /* @FT_STYLE_FLAG_XXX for the details. */ + /* */ + /* [Since 2.6.1] Bits 16-30 hold the number */ + /* of named instances available for the */ + /* current face if we have a GX or OpenType */ + /* variation (sub)font. Bit 31 is always zero */ + /* (this is, `style_flags' is always a */ + /* positive value). Note that a variation */ + /* font has always at least one named */ + /* instance, namely the default instance. */ /* */ /* num_glyphs :: The number of glyphs in the face. If the */ /* face is scalable and has sbits (see */ /* `num_fixed_sizes'), it is set to the number */ /* of outline glyphs. */ /* */ - /* For CID-keyed fonts, this value gives the */ - /* highest CID used in the font. */ + /* For CID-keyed fonts (not in an SFNT */ + /* wrapper) this value gives the highest CID */ + /* used in the font. */ /* */ /* family_name :: The face's family name. This is an ASCII */ /* string, usually in English, that describes */ @@ -952,6 +974,10 @@ FT_BEGIN_HEADER /* strikes in the face. It is set to NULL if */ /* there is no bitmap strike. */ /* */ + /* Note that FreeType tries to sanitize the */ + /* strike data since they are sometimes sloppy */ + /* or incorrect, but this can easily fail. */ + /* */ /* num_charmaps :: The number of charmaps in the face. */ /* */ /* charmaps :: An array of the charmaps of the face. */ @@ -987,8 +1013,8 @@ FT_BEGIN_HEADER /* expressed in font units. For font formats */ /* not having this information, it is set to */ /* `bbox.yMin'. Note that this field is */ - /* usually negative. Only relevant for */ - /* scalable formats. */ + /* negative for values below the baseline. */ + /* Only relevant for scalable formats. */ /* */ /* height :: This value is the vertical distance */ /* between two consecutive baselines, */ @@ -1031,6 +1057,15 @@ FT_BEGIN_HEADER /* Fields may be changed after a call to @FT_Attach_File or */ /* @FT_Attach_Stream. */ /* */ + /* For an OpenType variation font, the values of the following fields */ + /* can change after a call to @FT_Set_Var_Design_Coordinates (and */ + /* friends) if the font contains an `MVAR' table: `ascender', */ + /* `descender', `height', `underline_position', and */ + /* `underline_thickness'. */ + /* */ + /* Especially for TrueType fonts see also the documentation for */ + /* @FT_Size_Metrics. */ + /* */ typedef struct FT_FaceRec_ { FT_Long num_faces; @@ -1102,49 +1137,51 @@ FT_BEGIN_HEADER /* */ /* */ /* FT_FACE_FLAG_SCALABLE :: */ - /* Indicates that the face contains outline glyphs. This doesn't */ - /* prevent bitmap strikes, i.e., a face can have both this and */ - /* and @FT_FACE_FLAG_FIXED_SIZES set. */ + /* The face contains outline glyphs. Note that a face can contain */ + /* bitmap strikes also, i.e., a face can have both this flag and */ + /* @FT_FACE_FLAG_FIXED_SIZES set. */ /* */ /* FT_FACE_FLAG_FIXED_SIZES :: */ - /* Indicates that the face contains bitmap strikes. See also the */ + /* The face contains bitmap strikes. See also the */ /* `num_fixed_sizes' and `available_sizes' fields of @FT_FaceRec. */ /* */ /* FT_FACE_FLAG_FIXED_WIDTH :: */ - /* Indicates that the face contains fixed-width characters (like */ - /* Courier, Lucido, MonoType, etc.). */ + /* The face contains fixed-width characters (like Courier, Lucida, */ + /* MonoType, etc.). */ /* */ /* FT_FACE_FLAG_SFNT :: */ - /* Indicates that the face uses the `sfnt' storage scheme. For */ - /* now, this means TrueType and OpenType. */ + /* The face uses the SFNT storage scheme. For now, this means */ + /* TrueType and OpenType. */ /* */ /* FT_FACE_FLAG_HORIZONTAL :: */ - /* Indicates that the face contains horizontal glyph metrics. This */ - /* should be set for all common formats. */ + /* The face contains horizontal glyph metrics. This should be set */ + /* for all common formats. */ /* */ /* FT_FACE_FLAG_VERTICAL :: */ - /* Indicates that the face contains vertical glyph metrics. This */ - /* is only available in some formats, not all of them. */ + /* The face contains vertical glyph metrics. This is only */ + /* available in some formats, not all of them. */ /* */ /* FT_FACE_FLAG_KERNING :: */ - /* Indicates that the face contains kerning information. If set, */ - /* the kerning distance can be retrieved through the function */ - /* @FT_Get_Kerning. Otherwise the function always return the */ - /* vector (0,0). Note that FreeType doesn't handle kerning data */ - /* from the `GPOS' table (as present in some OpenType fonts). */ + /* The face contains kerning information. If set, the kerning */ + /* distance can be retrieved using the function @FT_Get_Kerning. */ + /* Otherwise the function always return the vector (0,0). Note */ + /* that FreeType doesn't handle kerning data from the SFNT `GPOS' */ + /* table (as present in many OpenType fonts). */ /* */ /* FT_FACE_FLAG_FAST_GLYPHS :: */ /* THIS FLAG IS DEPRECATED. DO NOT USE OR TEST IT. */ /* */ /* FT_FACE_FLAG_MULTIPLE_MASTERS :: */ - /* Indicates that the font contains multiple masters and is capable */ - /* of interpolating between them. See the multiple-masters */ - /* specific API for details. */ + /* The face contains multiple masters and is capable of */ + /* interpolating between them. Supported formats are Adobe MM, */ + /* TrueType GX, and OpenType variation fonts. */ + /* */ + /* See section @multiple_masters for API details. */ /* */ /* FT_FACE_FLAG_GLYPH_NAMES :: */ - /* Indicates that the font contains glyph names that can be */ - /* retrieved through @FT_Get_Glyph_Name. Note that some TrueType */ - /* fonts contain broken glyph name tables. Use the function */ + /* The face contains glyph names, which can be retrieved using */ + /* @FT_Get_Glyph_Name. Note that some TrueType fonts contain */ + /* broken glyph name tables. Use the function */ /* @FT_Has_PS_Glyph_Names when needed. */ /* */ /* FT_FACE_FLAG_EXTERNAL_STREAM :: */ @@ -1153,31 +1190,31 @@ FT_BEGIN_HEADER /* when @FT_Done_Face is called. Don't read or test this flag. */ /* */ /* FT_FACE_FLAG_HINTER :: */ - /* Set if the font driver has a hinting machine of its own. For */ - /* example, with TrueType fonts, it makes sense to use data from */ - /* the SFNT `gasp' table only if the native TrueType hinting engine */ - /* (with the bytecode interpreter) is available and active. */ + /* The font driver has a hinting machine of its own. For example, */ + /* with TrueType fonts, it makes sense to use data from the SFNT */ + /* `gasp' table only if the native TrueType hinting engine (with */ + /* the bytecode interpreter) is available and active. */ /* */ /* FT_FACE_FLAG_CID_KEYED :: */ - /* Set if the font is CID-keyed. In that case, the font is not */ - /* accessed by glyph indices but by CID values. For subsetted */ - /* CID-keyed fonts this has the consequence that not all index */ - /* values are a valid argument to FT_Load_Glyph. Only the CID */ - /* values for which corresponding glyphs in the subsetted font */ - /* exist make FT_Load_Glyph return successfully; in all other cases */ - /* you get an `FT_Err_Invalid_Argument' error. */ + /* The face is CID-keyed. In that case, the face is not accessed */ + /* by glyph indices but by CID values. For subsetted CID-keyed */ + /* fonts this has the consequence that not all index values are a */ + /* valid argument to @FT_Load_Glyph. Only the CID values for which */ + /* corresponding glyphs in the subsetted font exist make */ + /* `FT_Load_Glyph' return successfully; in all other cases you get */ + /* an `FT_Err_Invalid_Argument' error. */ /* */ - /* Note that CID-keyed fonts that are in an SFNT wrapper don't */ - /* have this flag set since the glyphs are accessed in the normal */ - /* way (using contiguous indices); the `CID-ness' isn't visible to */ - /* the application. */ + /* Note that CID-keyed fonts that are in an SFNT wrapper (this is, */ + /* all OpenType/CFF fonts) don't have this flag set since the */ + /* glyphs are accessed in the normal way (using contiguous */ + /* indices); the `CID-ness' isn't visible to the application. */ /* */ /* FT_FACE_FLAG_TRICKY :: */ - /* Set if the font is `tricky', this is, it always needs the */ - /* font format's native hinting engine to get a reasonable result. */ - /* A typical example is the Chinese font `mingli.ttf' that uses */ - /* TrueType bytecode instructions to move and scale all of its */ - /* subglyphs. */ + /* The face is `tricky', this is, it always needs the font format's */ + /* native hinting engine to get a reasonable result. A typical */ + /* example is the old Chinese font `mingli.ttf' (but not */ + /* `mingliu.ttc') that uses TrueType bytecode instructions to move */ + /* and scale all of its subglyphs. */ /* */ /* It is not possible to auto-hint such fonts using */ /* @FT_LOAD_FORCE_AUTOHINT; it will also ignore */ @@ -1189,8 +1226,15 @@ FT_BEGIN_HEADER /* tricky fonts; they are hard-coded in file `ttobjs.c'. */ /* */ /* FT_FACE_FLAG_COLOR :: */ - /* Set if the font has color glyph tables. To access color glyphs */ - /* use @FT_LOAD_COLOR. */ + /* [Since 2.5.1] The face has color glyph tables. To access color */ + /* glyphs use @FT_LOAD_COLOR. */ + /* */ + /* FT_FACE_FLAG_VARIATION :: */ + /* [Since 2.9] Set if the current face (or named instance) has been */ + /* altered with @FT_Set_MM_Design_Coordinates, */ + /* @FT_Set_Var_Design_Coordinates, or */ + /* @FT_Set_Var_Blend_Coordinates. This flag is unset by a call to */ + /* @FT_Set_Named_Instance. */ /* */ #define FT_FACE_FLAG_SCALABLE ( 1L << 0 ) #define FT_FACE_FLAG_FIXED_SIZES ( 1L << 1 ) @@ -1207,6 +1251,7 @@ FT_BEGIN_HEADER #define FT_FACE_FLAG_CID_KEYED ( 1L << 12 ) #define FT_FACE_FLAG_TRICKY ( 1L << 13 ) #define FT_FACE_FLAG_COLOR ( 1L << 14 ) +#define FT_FACE_FLAG_VARIATION ( 1L << 15 ) /************************************************************************* @@ -1223,7 +1268,7 @@ FT_BEGIN_HEADER * */ #define FT_HAS_HORIZONTAL( face ) \ - ( face->face_flags & FT_FACE_FLAG_HORIZONTAL ) + ( (face)->face_flags & FT_FACE_FLAG_HORIZONTAL ) /************************************************************************* @@ -1237,7 +1282,7 @@ FT_BEGIN_HEADER * */ #define FT_HAS_VERTICAL( face ) \ - ( face->face_flags & FT_FACE_FLAG_VERTICAL ) + ( (face)->face_flags & FT_FACE_FLAG_VERTICAL ) /************************************************************************* @@ -1251,7 +1296,7 @@ FT_BEGIN_HEADER * */ #define FT_HAS_KERNING( face ) \ - ( face->face_flags & FT_FACE_FLAG_KERNING ) + ( (face)->face_flags & FT_FACE_FLAG_KERNING ) /************************************************************************* @@ -1262,11 +1307,11 @@ FT_BEGIN_HEADER * @description: * A macro that returns true whenever a face object contains a scalable * font face (true for TrueType, Type~1, Type~42, CID, OpenType/CFF, - * and PFR font formats. + * and PFR font formats). * */ #define FT_IS_SCALABLE( face ) \ - ( face->face_flags & FT_FACE_FLAG_SCALABLE ) + ( (face)->face_flags & FT_FACE_FLAG_SCALABLE ) /************************************************************************* @@ -1285,7 +1330,7 @@ FT_BEGIN_HEADER * */ #define FT_IS_SFNT( face ) \ - ( face->face_flags & FT_FACE_FLAG_SFNT ) + ( (face)->face_flags & FT_FACE_FLAG_SFNT ) /************************************************************************* @@ -1300,7 +1345,7 @@ FT_BEGIN_HEADER * */ #define FT_IS_FIXED_WIDTH( face ) \ - ( face->face_flags & FT_FACE_FLAG_FIXED_WIDTH ) + ( (face)->face_flags & FT_FACE_FLAG_FIXED_WIDTH ) /************************************************************************* @@ -1315,7 +1360,7 @@ FT_BEGIN_HEADER * */ #define FT_HAS_FIXED_SIZES( face ) \ - ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES ) + ( (face)->face_flags & FT_FACE_FLAG_FIXED_SIZES ) /************************************************************************* @@ -1341,7 +1386,7 @@ FT_BEGIN_HEADER * */ #define FT_HAS_GLYPH_NAMES( face ) \ - ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) + ( (face)->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) /************************************************************************* @@ -1356,7 +1401,47 @@ FT_BEGIN_HEADER * */ #define FT_HAS_MULTIPLE_MASTERS( face ) \ - ( face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) + ( (face)->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) + + + /************************************************************************* + * + * @macro: + * FT_IS_NAMED_INSTANCE( face ) + * + * @description: + * A macro that returns true whenever a face object is a named instance + * of a GX or OpenType variation font. + * + * [Since 2.9] Changing the design coordinates with + * @FT_Set_Var_Design_Coordinates or @FT_Set_Var_Blend_Coordinates does + * not influence the return value of this macro (only + * @FT_Set_Named_Instance does that). + * + * @since: + * 2.7 + * + */ +#define FT_IS_NAMED_INSTANCE( face ) \ + ( (face)->face_index & 0x7FFF0000L ) + + + /************************************************************************* + * + * @macro: + * FT_IS_VARIATION( face ) + * + * @description: + * A macro that returns true whenever a face object has been altered + * by @FT_Set_MM_Design_Coordinates, @FT_Set_Var_Design_Coordinates, or + * @FT_Set_Var_Blend_Coordinates. + * + * @since: + * 2.9 + * + */ +#define FT_IS_VARIATION( face ) \ + ( (face)->face_flags & FT_FACE_FLAG_VARIATION ) /************************************************************************* @@ -1374,7 +1459,7 @@ FT_BEGIN_HEADER * */ #define FT_IS_CID_KEYED( face ) \ - ( face->face_flags & FT_FACE_FLAG_CID_KEYED ) + ( (face)->face_flags & FT_FACE_FLAG_CID_KEYED ) /************************************************************************* @@ -1388,7 +1473,7 @@ FT_BEGIN_HEADER * */ #define FT_IS_TRICKY( face ) \ - ( face->face_flags & FT_FACE_FLAG_TRICKY ) + ( (face)->face_flags & FT_FACE_FLAG_TRICKY ) /************************************************************************* @@ -1400,9 +1485,12 @@ FT_BEGIN_HEADER * A macro that returns true whenever a face object contains * tables for color glyphs. * + * @since: + * 2.5.1 + * */ #define FT_HAS_COLOR( face ) \ - ( face->face_flags & FT_FACE_FLAG_COLOR ) + ( (face)->face_flags & FT_FACE_FLAG_COLOR ) /*************************************************************************/ @@ -1411,15 +1499,15 @@ FT_BEGIN_HEADER /* FT_STYLE_FLAG_XXX */ /* */ /* */ - /* A list of bit flags used to indicate the style of a given face. */ - /* These are used in the `style_flags' field of @FT_FaceRec. */ + /* A list of bit flags to indicate the style of a given face. These */ + /* are used in the `style_flags' field of @FT_FaceRec. */ /* */ /* */ /* FT_STYLE_FLAG_ITALIC :: */ - /* Indicates that a given face style is italic or oblique. */ + /* The face style is italic or oblique. */ /* */ /* FT_STYLE_FLAG_BOLD :: */ - /* Indicates that a given face is bold. */ + /* The face is bold. */ /* */ /* */ /* The style information as provided by FreeType is very basic. More */ @@ -1460,43 +1548,93 @@ FT_BEGIN_HEADER /* hence the term `ppem' (pixels per EM). It is also */ /* referred to as `nominal height'. */ /* */ - /* x_scale :: A 16.16 fractional scaling value used to convert */ + /* x_scale :: A 16.16 fractional scaling value to convert */ /* horizontal metrics from font units to 26.6 */ /* fractional pixels. Only relevant for scalable */ /* font formats. */ /* */ - /* y_scale :: A 16.16 fractional scaling value used to convert */ + /* y_scale :: A 16.16 fractional scaling value to convert */ /* vertical metrics from font units to 26.6 */ /* fractional pixels. Only relevant for scalable */ /* font formats. */ /* */ - /* ascender :: The ascender in 26.6 fractional pixels. See */ - /* @FT_FaceRec for the details. */ + /* ascender :: The ascender in 26.6 fractional pixels, rounded up */ + /* to an integer value. See @FT_FaceRec for the */ + /* details. */ /* */ - /* descender :: The descender in 26.6 fractional pixels. See */ - /* @FT_FaceRec for the details. */ + /* descender :: The descender in 26.6 fractional pixels, rounded */ + /* down to an integer value. See @FT_FaceRec for the */ + /* details. */ /* */ - /* height :: The height in 26.6 fractional pixels. See */ - /* @FT_FaceRec for the details. */ + /* height :: The height in 26.6 fractional pixels, rounded to */ + /* an integer value. See @FT_FaceRec for the */ + /* details. */ /* */ /* max_advance :: The maximum advance width in 26.6 fractional */ - /* pixels. See @FT_FaceRec for the details. */ + /* pixels, rounded to an integer value. See */ + /* @FT_FaceRec for the details. */ /* */ /* */ /* The scaling values, if relevant, are determined first during a */ /* size changing operation. The remaining fields are then set by the */ /* driver. For scalable formats, they are usually set to scaled */ - /* values of the corresponding fields in @FT_FaceRec. */ + /* values of the corresponding fields in @FT_FaceRec. Some values */ + /* like ascender or descender are rounded for historical reasons; */ + /* more precise values (for outline fonts) can be derived by scaling */ + /* the corresponding @FT_FaceRec values manually, with code similar */ + /* to the following. */ /* */ - /* Note that due to glyph hinting, these values might not be exact */ - /* for certain fonts. Thus they must be treated as unreliable */ - /* with an error margin of at least one pixel! */ + /* { */ + /* scaled_ascender = FT_MulFix( face->ascender, */ + /* size_metrics->y_scale ); */ + /* } */ + /* */ + /* Note that due to glyph hinting and the selected rendering mode */ + /* these values are usually not exact; consequently, they must be */ + /* treated as unreliable with an error margin of at least one pixel! */ /* */ /* Indeed, the only way to get the exact metrics is to render _all_ */ /* glyphs. As this would be a definite performance hit, it is up to */ /* client applications to perform such computations. */ /* */ - /* The FT_Size_Metrics structure is valid for bitmap fonts also. */ + /* The `FT_Size_Metrics' structure is valid for bitmap fonts also. */ + /* */ + /* */ + /* *TrueType* *fonts* *with* *native* *bytecode* *hinting* */ + /* */ + /* All applications that handle TrueType fonts with native hinting */ + /* must be aware that TTFs expect different rounding of vertical font */ + /* dimensions. The application has to cater for this, especially if */ + /* it wants to rely on a TTF's vertical data (for example, to */ + /* properly align box characters vertically). */ + /* */ + /* Only the application knows _in_ _advance_ that it is going to use */ + /* native hinting for TTFs! FreeType, on the other hand, selects the */ + /* hinting mode not at the time of creating an @FT_Size object but */ + /* much later, namely while calling @FT_Load_Glyph. */ + /* */ + /* Here is some pseudo code that illustrates a possible solution. */ + /* */ + /* { */ + /* font_format = FT_Get_Font_Format( face ); */ + /* */ + /* if ( !strcmp( font_format, "TrueType" ) && */ + /* do_native_bytecode_hinting ) */ + /* { */ + /* ascender = ROUND( FT_MulFix( face->ascender, */ + /* size_metrics->y_scale ) ); */ + /* descender = ROUND( FT_MulFix( face->descender, */ + /* size_metrics->y_scale ) ); */ + /* } */ + /* else */ + /* { */ + /* ascender = size_metrics->ascender; */ + /* descender = size_metrics->descender; */ + /* } */ + /* */ + /* height = size_metrics->height; */ + /* max_advance = size_metrics->max_advance; */ + /* } */ /* */ typedef struct FT_Size_Metrics_ { @@ -1636,32 +1774,27 @@ FT_BEGIN_HEADER /* contained in the glyph slot. Typically */ /* @FT_GLYPH_FORMAT_BITMAP, */ /* @FT_GLYPH_FORMAT_OUTLINE, or */ - /* @FT_GLYPH_FORMAT_COMPOSITE, but others are */ - /* possible. */ + /* @FT_GLYPH_FORMAT_COMPOSITE, but other values */ + /* are possible. */ /* */ - /* bitmap :: This field is used as a bitmap descriptor */ - /* when the slot format is */ - /* @FT_GLYPH_FORMAT_BITMAP. Note that the */ - /* address and content of the bitmap buffer can */ - /* change between calls of @FT_Load_Glyph and a */ - /* few other functions. */ + /* bitmap :: This field is used as a bitmap descriptor. */ + /* Note that the address and content of the */ + /* bitmap buffer can change between calls of */ + /* @FT_Load_Glyph and a few other functions. */ /* */ /* bitmap_left :: The bitmap's left bearing expressed in */ - /* integer pixels. Only valid if the format is */ - /* @FT_GLYPH_FORMAT_BITMAP, this is, if the */ - /* glyph slot contains a bitmap. */ + /* integer pixels. */ /* */ /* bitmap_top :: The bitmap's top bearing expressed in integer */ - /* pixels. Remember that this is the distance */ - /* from the baseline to the top-most glyph */ - /* scanline, upwards y~coordinates being */ - /* *positive*. */ + /* pixels. This is the distance from the */ + /* baseline to the top-most glyph scanline, */ + /* upwards y~coordinates being *positive*. */ /* */ /* outline :: The outline descriptor for the current glyph */ /* image if its format is */ /* @FT_GLYPH_FORMAT_OUTLINE. Once a glyph is */ /* loaded, `outline' can be transformed, */ - /* distorted, embolded, etc. However, it must */ + /* distorted, emboldened, etc. However, it must */ /* not be freed. */ /* */ /* num_subglyphs :: The number of subglyphs in a composite glyph. */ @@ -1677,15 +1810,13 @@ FT_BEGIN_HEADER /* control_data :: Certain font drivers can also return the */ /* control data for a given glyph image (e.g. */ /* TrueType bytecode, Type~1 charstrings, etc.). */ - /* This field is a pointer to such data. */ + /* This field is a pointer to such data; it is */ + /* currently internal to FreeType. */ /* */ /* control_len :: This is the length in bytes of the control */ - /* data. */ + /* data. Currently internal to FreeType. */ /* */ - /* other :: Really wicked formats can use this pointer to */ - /* present their own glyph image to client */ - /* applications. Note that the application */ - /* needs to know about the image format. */ + /* other :: Reserved. */ /* */ /* lsb_delta :: The difference between hinted and unhinted */ /* left side bearing while auto-hinting is */ @@ -1699,10 +1830,12 @@ FT_BEGIN_HEADER /* If @FT_Load_Glyph is called with default flags (see */ /* @FT_LOAD_DEFAULT) the glyph image is loaded in the glyph slot in */ /* its native format (e.g., an outline glyph for TrueType and Type~1 */ - /* formats). */ + /* formats). [Since 2.9] The prospective bitmap metrics are */ + /* calculated according to @FT_LOAD_TARGET_XXX and other flags even */ + /* for the outline glyph, even if @FT_LOAD_RENDER is not set. */ /* */ /* This image can later be converted into a bitmap by calling */ - /* @FT_Render_Glyph. This function finds the current renderer for */ + /* @FT_Render_Glyph. This function searches the current renderer for */ /* the native image's format, then invokes it. */ /* */ /* The renderer is in charge of transforming the native image through */ @@ -1714,34 +1847,65 @@ FT_BEGIN_HEADER /* position (e.g., coordinates (0,0) on the baseline). Of course, */ /* `slot->format' is also changed to @FT_GLYPH_FORMAT_BITMAP. */ /* */ - /* */ /* Here is a small pseudo code fragment that shows how to use */ - /* `lsb_delta' and `rsb_delta': */ + /* `lsb_delta' and `rsb_delta' to do fractional positioning of */ + /* glyphs: */ /* */ /* { */ - /* FT_Pos origin_x = 0; */ - /* FT_Pos prev_rsb_delta = 0; */ + /* FT_GlyphSlot slot = face->glyph; */ + /* FT_Pos origin_x = 0; */ /* */ /* */ /* for all glyphs do */ - /* */ - /* */ /* */ /* */ - /* if ( prev_rsb_delta - face->glyph->lsb_delta >= 32 ) */ - /* origin_x -= 64; */ - /* else if ( prev_rsb_delta - face->glyph->lsb_delta < -32 ) */ - /* origin_x += 64; */ - /* */ - /* prev_rsb_delta = face->glyph->rsb_delta; */ + /* FT_Outline_Translate( slot->outline, origin_x & 63, 0 ); */ /* */ /* */ /* */ - /* origin_x += face->glyph->advance.x; */ + /* */ + /* */ + /* origin_x += slot->advance.x; */ + /* origin_x += slot->rsb_delta - slot->lsb_delta; */ /* endfor */ /* } */ /* */ + /* Here is another small pseudo code fragment that shows how to use */ + /* `lsb_delta' and `rsb_delta' to improve integer positioning of */ + /* glyphs: */ + /* */ + /* { */ + /* FT_GlyphSlot slot = face->glyph; */ + /* FT_Pos origin_x = 0; */ + /* FT_Pos prev_rsb_delta = 0; */ + /* */ + /* */ + /* for all glyphs do */ + /* */ + /* */ + /* */ + /* */ + /* if ( prev_rsb_delta - slot->lsb_delta > 32 ) */ + /* origin_x -= 64; */ + /* else if ( prev_rsb_delta - slot->lsb_delta < -31 ) */ + /* origin_x += 64; */ + /* */ + /* prev_rsb_delta = slot->rsb_delta; */ + /* */ + /* */ + /* */ + /* origin_x += slot->advance.x; */ + /* endfor */ + /* } */ + /* */ + /* If you use strong auto-hinting, you *must* apply these delta */ + /* values! Otherwise you will experience far too large inter-glyph */ + /* spacing at small rendering sizes in most cases. Note that it */ + /* doesn't harm to use the above code for other hinting modes also, */ + /* since the delta values are zero then. */ + /* */ typedef struct FT_GlyphSlotRec_ { FT_Library library; @@ -1806,7 +1970,8 @@ FT_BEGIN_HEADER /* */ /* In case you want to provide your own memory allocating routines, */ /* use @FT_New_Library instead, followed by a call to */ - /* @FT_Add_Default_Modules (or a series of calls to @FT_Add_Module). */ + /* @FT_Add_Default_Modules (or a series of calls to @FT_Add_Module) */ + /* and @FT_Set_Default_Properties. */ /* */ /* See the documentation of @FT_Library and @FT_Face for */ /* multi-threading issues. */ @@ -1814,6 +1979,11 @@ FT_BEGIN_HEADER /* If you need reference-counting (cf. @FT_Reference_Library), use */ /* @FT_New_Library and @FT_Done_Library. */ /* */ + /* If compilation option FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES is */ + /* set, this function reads the `FREETYPE_PROPERTIES' environment */ + /* variable to control driver properties. See section @properties */ + /* for more. */ + /* */ FT_EXPORT( FT_Error ) FT_Init_FreeType( FT_Library *alibrary ); @@ -1884,8 +2054,8 @@ FT_BEGIN_HEADER /* FT_Parameter */ /* */ /* */ - /* A simple structure used to pass more or less generic parameters to */ - /* @FT_Open_Face. */ + /* A simple structure to pass more or less generic parameters to */ + /* @FT_Open_Face and @FT_Face_Properties. */ /* */ /* */ /* tag :: A four-byte identification tag. */ @@ -1893,8 +2063,8 @@ FT_BEGIN_HEADER /* data :: A pointer to the parameter data. */ /* */ /* */ - /* The ID and function of parameters are driver-specific. See the */ - /* various FT_PARAM_TAG_XXX flags for more information. */ + /* The ID and function of parameters are driver-specific. See */ + /* section @parameter_tags for more information. */ /* */ typedef struct FT_Parameter_ { @@ -1910,9 +2080,9 @@ FT_BEGIN_HEADER /* FT_Open_Args */ /* */ /* */ - /* A structure used to indicate how to open a new font file or */ - /* stream. A pointer to such a structure can be used as a parameter */ - /* for the functions @FT_Open_Face and @FT_Attach_Stream. */ + /* A structure to indicate how to open a new font file or stream. A */ + /* pointer to such a structure can be used as a parameter for the */ + /* functions @FT_Open_Face and @FT_Attach_Stream. */ /* */ /* */ /* flags :: A set of bit flags indicating how to use the */ @@ -1927,9 +2097,10 @@ FT_BEGIN_HEADER /* stream :: A handle to a source stream object. */ /* */ /* driver :: This field is exclusively used by @FT_Open_Face; */ - /* it simply specifies the font driver to use to open */ - /* the face. If set to~0, FreeType tries to load the */ - /* face with each one of the drivers in its list. */ + /* it simply specifies the font driver to use for */ + /* opening the face. If set to NULL, FreeType tries */ + /* to load the face with each one of the drivers in */ + /* its list. */ /* */ /* num_params :: The number of extra parameters. */ /* */ @@ -1942,7 +2113,7 @@ FT_BEGIN_HEADER /* */ /* If the @FT_OPEN_MEMORY bit is set, assume that this is a */ /* memory file of `memory_size' bytes, located at `memory_address'. */ - /* The data are are not copied, and the client is responsible for */ + /* The data are not copied, and the client is responsible for */ /* releasing and destroying them _after_ the corresponding call to */ /* @FT_Done_Face. */ /* */ @@ -1959,7 +2130,7 @@ FT_BEGIN_HEADER /* `num_params' and `params' is used. They are ignored otherwise. */ /* */ /* Ideally, both the `pathname' and `params' fields should be tagged */ - /* as `const'; this is missing for API backwards compatibility. In */ + /* as `const'; this is missing for API backward compatibility. In */ /* other words, applications should treat them as read-only. */ /* */ typedef struct FT_Open_Args_ @@ -1982,7 +2153,7 @@ FT_BEGIN_HEADER /* FT_New_Face */ /* */ /* */ - /* This function calls @FT_Open_Face to open a font by its pathname. */ + /* Call @FT_Open_Face to open a font by its pathname. */ /* */ /* */ /* library :: A handle to the library resource. */ @@ -2017,8 +2188,8 @@ FT_BEGIN_HEADER /* FT_New_Memory_Face */ /* */ /* */ - /* This function calls @FT_Open_Face to open a font that has been */ - /* loaded into memory. */ + /* Call @FT_Open_Face to open a font that has been loaded into */ + /* memory. */ /* */ /* */ /* library :: A handle to the library resource. */ @@ -2070,20 +2241,21 @@ FT_BEGIN_HEADER /* with value~0). Set it to~0 if there is only one */ /* face in the font file. */ /* */ - /* Bits 16-30 are relevant to GX variation fonts only, */ - /* specifying the named instance index for the current */ - /* face index (starting with value~1; value~0 makes */ - /* FreeType ignore named instances). For non-GX fonts, */ - /* bits 16-30 are ignored. Assuming that you want to */ - /* access the third named instance in face~4, */ - /* `face_index' should be set to 0x00030004. If you */ - /* want to access face~4 without GX variation handling, */ - /* simply set `face_index' to value~4. */ + /* [Since 2.6.1] Bits 16-30 are relevant to GX and */ + /* OpenType variation fonts only, specifying the named */ + /* instance index for the current face index (starting */ + /* with value~1; value~0 makes FreeType ignore named */ + /* instances). For non-variation fonts, bits 16-30 are */ + /* ignored. Assuming that you want to access the third */ + /* named instance in face~4, `face_index' should be set */ + /* to 0x00030004. If you want to access face~4 without */ + /* variation handling, simply set `face_index' to */ + /* value~4. */ /* */ - /* FT_Open_Face and its siblings can be used to quickly */ - /* check whether the font format of a given font */ - /* resource is supported by FreeType. In general, if */ - /* the `face_index' argument is negative, the */ + /* `FT_Open_Face' and its siblings can be used to */ + /* quickly check whether the font format of a given */ + /* font resource is supported by FreeType. In general, */ + /* if the `face_index' argument is negative, the */ /* function's return value is~0 if the font format is */ /* recognized, or non-zero otherwise. The function */ /* allocates a more or less empty face handle in */ @@ -2092,10 +2264,10 @@ FT_BEGIN_HEADER /* `face->num_faces' and `face->style_flags'. For any */ /* negative value of `face_index', `face->num_faces' */ /* gives the number of faces within the font file. For */ - /* the negative value `-(N+1)' (with `N' a 16-bit */ - /* value), bits 16-30 in `face->style_flags' give the */ - /* number of named instances in face `N' if we have a */ - /* GX variation font (or zero otherwise). After */ + /* the negative value `-(N+1)' (with `N' a non-negative */ + /* 16-bit value), bits 16-30 in `face->style_flags' */ + /* give the number of named instances in face `N' if we */ + /* have a variation font (or zero otherwise). After */ /* examination, the returned @FT_Face structure should */ /* be deallocated with a call to @FT_Done_Face. */ /* */ @@ -2202,7 +2374,7 @@ FT_BEGIN_HEADER /* FT_Attach_File */ /* */ /* */ - /* This function calls @FT_Attach_Stream to attach a file. */ + /* Call @FT_Attach_Stream to attach a file. */ /* */ /* */ /* face :: The target face object. */ @@ -2246,7 +2418,7 @@ FT_BEGIN_HEADER /* */ /* Client applications are expected to know what they are doing */ /* when invoking this function. Most drivers simply do not implement */ - /* file attachments. */ + /* file or stream attachments. */ /* */ FT_EXPORT( FT_Error ) FT_Attach_Stream( FT_Face face, @@ -2309,7 +2481,10 @@ FT_BEGIN_HEADER /* FT_Select_Size */ /* */ /* */ - /* Select a bitmap strike. */ + /* Select a bitmap strike. To be more precise, this function sets */ + /* the scaling factors of the active @FT_Size object in a face so */ + /* that bitmaps from this particular strike are taken by */ + /* @FT_Load_Glyph and friends. */ /* */ /* */ /* face :: A handle to a target face object. */ @@ -2321,6 +2496,20 @@ FT_BEGIN_HEADER /* */ /* FreeType error code. 0~means success. */ /* */ + /* */ + /* For bitmaps embedded in outline fonts it is common that only a */ + /* subset of the available glyphs at a given ppem value is available. */ + /* FreeType silently uses outlines if there is no bitmap for a given */ + /* glyph index. */ + /* */ + /* For GX and OpenType variation fonts, a bitmap strike makes sense */ + /* only if the default instance is active (this is, no glyph */ + /* variation takes place); otherwise, FreeType simply ignores bitmap */ + /* strikes. The same is true for all named instances that are */ + /* different from the default instance. */ + /* */ + /* Don't use this function if you are using the FreeType cache API. */ + /* */ FT_EXPORT( FT_Error ) FT_Select_Size( FT_Face face, FT_Int strike_index ); @@ -2332,17 +2521,26 @@ FT_BEGIN_HEADER /* FT_Size_Request_Type */ /* */ /* */ - /* An enumeration type that lists the supported size request types. */ + /* An enumeration type that lists the supported size request types, */ + /* i.e., what input size (in font units) maps to the requested output */ + /* size (in pixels, as computed from the arguments of */ + /* @FT_Size_Request). */ /* */ /* */ /* FT_SIZE_REQUEST_TYPE_NOMINAL :: */ /* The nominal size. The `units_per_EM' field of @FT_FaceRec is */ /* used to determine both scaling values. */ /* */ + /* This is the standard scaling found in most applications. In */ + /* particular, use this size request type for TrueType fonts if */ + /* they provide optical scaling or something similar. Note, */ + /* however, that `units_per_EM' is a rather abstract value which */ + /* bears no relation to the actual size of the glyphs in a font. */ + /* */ /* FT_SIZE_REQUEST_TYPE_REAL_DIM :: */ - /* The real dimension. The sum of the the `ascender' and (minus */ - /* of) the `descender' fields of @FT_FaceRec are used to determine */ - /* both scaling values. */ + /* The real dimension. The sum of the `ascender' and (minus of) */ + /* the `descender' fields of @FT_FaceRec is used to determine both */ + /* scaling values. */ /* */ /* FT_SIZE_REQUEST_TYPE_BBOX :: */ /* The font bounding box. The width and height of the `bbox' field */ @@ -2387,27 +2585,36 @@ FT_BEGIN_HEADER /* FT_Size_RequestRec */ /* */ /* */ - /* A structure used to model a size request. */ + /* A structure to model a size request. */ /* */ /* */ /* type :: See @FT_Size_Request_Type. */ /* */ - /* width :: The desired width. */ + /* width :: The desired width, given as a 26.6 fractional */ + /* point value (with 72pt = 1in). */ /* */ - /* height :: The desired height. */ + /* height :: The desired height, given as a 26.6 fractional */ + /* point value (with 72pt = 1in). */ /* */ - /* horiResolution :: The horizontal resolution. If set to zero, */ - /* `width' is treated as a 26.6 fractional pixel */ - /* value. */ + /* horiResolution :: The horizontal resolution (dpi, i.e., pixels per */ + /* inch). If set to zero, `width' is treated as a */ + /* 26.6 fractional *pixel* value, which gets */ + /* internally rounded to an integer. */ /* */ - /* vertResolution :: The vertical resolution. If set to zero, */ - /* `height' is treated as a 26.6 fractional pixel */ - /* value. */ + /* vertResolution :: The vertical resolution (dpi, i.e., pixels per */ + /* inch). If set to zero, `height' is treated as a */ + /* 26.6 fractional *pixel* value, which gets */ + /* internally rounded to an integer. */ /* */ /* */ - /* If `width' is zero, then the horizontal scaling value is set equal */ + /* If `width' is zero, the horizontal scaling value is set equal */ /* to the vertical scaling value, and vice versa. */ /* */ + /* If `type' is FT_SIZE_REQUEST_TYPE_SCALES, `width' and `height' are */ + /* interpreted directly as 16.16 fractional scaling values, without */ + /* any further modification, and both `horiResolution' and */ + /* `vertResolution' are ignored. */ + /* */ typedef struct FT_Size_RequestRec_ { FT_Size_Request_Type type; @@ -2457,7 +2664,11 @@ FT_BEGIN_HEADER /* size is dependent entirely on how the size is defined in the */ /* source face. The font designer chooses the final size of each */ /* glyph relative to this size. For more information refer to */ - /* `http://www.freetype.org/freetype2/docs/glyphs/glyphs-2.html' */ + /* `https://www.freetype.org/freetype2/docs/glyphs/glyphs-2.html'. */ + /* */ + /* Contrary to @FT_Set_Char_Size, this function doesn't have special */ + /* code to normalize zero-valued widths, heights, or resolutions */ + /* (which lead to errors in most cases). */ /* */ /* Don't use this function if you are using the FreeType cache API. */ /* */ @@ -2472,8 +2683,7 @@ FT_BEGIN_HEADER /* FT_Set_Char_Size */ /* */ /* */ - /* This function calls @FT_Request_Size to request the nominal size */ - /* (in points). */ + /* Call @FT_Request_Size to request the nominal size (in points). */ /* */ /* */ /* face :: A handle to a target face object. */ @@ -2491,6 +2701,10 @@ FT_BEGIN_HEADER /* FreeType error code. 0~means success. */ /* */ /* */ + /* While this function allows fractional points as input values, the */ + /* resulting ppem value for the given resolution is always rounded to */ + /* the nearest integer. */ + /* */ /* If either the character width or height is zero, it is set equal */ /* to the other value. */ /* */ @@ -2516,8 +2730,7 @@ FT_BEGIN_HEADER /* FT_Set_Pixel_Sizes */ /* */ /* */ - /* This function calls @FT_Request_Size to request the nominal size */ - /* (in pixels). */ + /* Call @FT_Request_Size to request the nominal size (in pixels). */ /* */ /* */ /* face :: A handle to the target face object. */ @@ -2531,8 +2744,8 @@ FT_BEGIN_HEADER /* FreeType error code. 0~means success. */ /* */ /* */ - /* You should not rely on the resulting glyphs matching, or being */ - /* constrained, to this pixel size. Refer to @FT_Request_Size to */ + /* You should not rely on the resulting glyphs matching or being */ + /* constrained to this pixel size. Refer to @FT_Request_Size to */ /* understand how requested sizes relate to actual sizes. */ /* */ /* Don't use this function if you are using the FreeType cache API. */ @@ -2549,8 +2762,7 @@ FT_BEGIN_HEADER /* FT_Load_Glyph */ /* */ /* */ - /* A function used to load a single glyph into the glyph slot of a */ - /* face object. */ + /* Load a glyph into the glyph slot of a face object. */ /* */ /* */ /* face :: A handle to the target face object where the glyph */ @@ -2579,6 +2791,10 @@ FT_BEGIN_HEADER /* don't have a corresponding glyph in the font). See the discussion */ /* of the @FT_FACE_FLAG_CID_KEYED flag for more details. */ /* */ + /* If you receive `FT_Err_Glyph_Too_Big', try getting the glyph */ + /* outline at EM size, then scale it manually and fill it as a */ + /* graphics operation. */ + /* */ FT_EXPORT( FT_Error ) FT_Load_Glyph( FT_Face face, FT_UInt glyph_index, @@ -2591,8 +2807,8 @@ FT_BEGIN_HEADER /* FT_Load_Char */ /* */ /* */ - /* A function used to load a single glyph into the glyph slot of a */ - /* face object, according to its character code. */ + /* Load a glyph into the glyph slot of a face object, accessed by its */ + /* character code. */ /* */ /* */ /* face :: A handle to a target face object where the glyph */ @@ -2614,6 +2830,14 @@ FT_BEGIN_HEADER /* */ /* This function simply calls @FT_Get_Char_Index and @FT_Load_Glyph. */ /* */ + /* Many fonts contain glyphs that can't be loaded by this function */ + /* since its glyph indices are not listed in any of the font's */ + /* charmaps. */ + /* */ + /* If no active cmap is set up (i.e., `face->charmap' is zero), the */ + /* call to @FT_Get_Char_Index is omitted, and the function behaves */ + /* identically to @FT_Load_Glyph. */ + /* */ FT_EXPORT( FT_Error ) FT_Load_Char( FT_Face face, FT_ULong char_code, @@ -2626,8 +2850,8 @@ FT_BEGIN_HEADER * FT_LOAD_XXX * * @description: - * A list of bit field constants used with @FT_Load_Glyph to indicate - * what kind of operations to perform during glyph loading. + * A list of bit field constants for @FT_Load_Glyph to indicate what + * kind of operations to perform during glyph loading. * * @values: * FT_LOAD_DEFAULT :: @@ -2639,13 +2863,13 @@ FT_BEGIN_HEADER * The bitmap data can be accessed from the glyph slot (see note * below). * - * 2. If no embedded bitmap is searched or found, FreeType looks for a - * scalable outline. If one is found, it is loaded from the font - * file, scaled to device pixels, then `hinted' to the pixel grid - * in order to optimize it. The outline data can be accessed from - * the glyph slot (see note below). + * 2. If no embedded bitmap is searched for or found, FreeType looks + * for a scalable outline. If one is found, it is loaded from + * the font file, scaled to device pixels, then `hinted' to the + * pixel grid in order to optimize it. The outline data can be + * accessed from the glyph slot (see note below). * - * Note that by default, the glyph loader doesn't render outlines into + * Note that by default the glyph loader doesn't render outlines into * bitmaps. The following flags are used to modify this default * behaviour to more specific and useful cases. * @@ -2692,13 +2916,13 @@ FT_BEGIN_HEADER * various font formats. * * FT_LOAD_FORCE_AUTOHINT :: - * Indicates that the auto-hinter is preferred over the font's native - * hinter. See also the note below. + * Prefer the auto-hinter over the font's native hinter. See also + * the note below. * * FT_LOAD_PEDANTIC :: - * Indicates that the font driver should perform pedantic verifications - * during glyph loading. This is mostly used to detect broken glyphs - * in fonts. By default, FreeType tries to handle broken fonts also. + * Make the font driver perform pedantic verifications during glyph + * loading. This is mostly used to detect broken glyphs in fonts. + * By default, FreeType tries to handle broken fonts also. * * In particular, errors from the TrueType bytecode engine are not * passed to the application if this flag is not set; this might @@ -2706,17 +2930,16 @@ FT_BEGIN_HEADER * bytecode is buggy. * * FT_LOAD_NO_RECURSE :: - * Indicate that the font driver should not load composite glyphs - * recursively. Instead, it should set the `num_subglyph' and - * `subglyphs' values of the glyph slot accordingly, and set - * `glyph->format' to @FT_GLYPH_FORMAT_COMPOSITE. The description of - * subglyphs can then be accessed with @FT_Get_SubGlyph_Info. + * Don't load composite glyphs recursively. Instead, the font + * driver should set the `num_subglyph' and `subglyphs' values of + * the glyph slot accordingly, and set `glyph->format' to + * @FT_GLYPH_FORMAT_COMPOSITE. The description of subglyphs can + * then be accessed with @FT_Get_SubGlyph_Info. * * This flag implies @FT_LOAD_NO_SCALE and @FT_LOAD_IGNORE_TRANSFORM. * * FT_LOAD_IGNORE_TRANSFORM :: - * Indicates that the transform matrix set by @FT_Set_Transform should - * be ignored. + * Ignore the transform matrix set by @FT_Set_Transform. * * FT_LOAD_MONOCHROME :: * This flag is used with @FT_LOAD_RENDER to indicate that you want to @@ -2728,31 +2951,37 @@ FT_BEGIN_HEADER * monochrome-optimized hinting algorithm is used. * * FT_LOAD_LINEAR_DESIGN :: - * Indicates that the `linearHoriAdvance' and `linearVertAdvance' - * fields of @FT_GlyphSlotRec should be kept in font units. See - * @FT_GlyphSlotRec for details. + * Keep `linearHoriAdvance' and `linearVertAdvance' fields of + * @FT_GlyphSlotRec in font units. See @FT_GlyphSlotRec for + * details. * * FT_LOAD_NO_AUTOHINT :: - * Disable auto-hinter. See also the note below. + * Disable the auto-hinter. See also the note below. * * FT_LOAD_COLOR :: - * This flag is used to request loading of color embedded-bitmap - * images. The resulting color bitmaps, if available, will have the - * @FT_PIXEL_MODE_BGRA format. When the flag is not used and color - * bitmaps are found, they will be converted to 256-level gray - * bitmaps transparently. Those bitmaps will be in the + * [Since 2.5] Load embedded color bitmap images. The resulting color + * bitmaps, if available, will have the @FT_PIXEL_MODE_BGRA format. + * If the flag is not set and color bitmaps are found, they are + * converted to 256-level gray bitmaps transparently, using the * @FT_PIXEL_MODE_GRAY format. * * FT_LOAD_COMPUTE_METRICS :: - * This flag sets computing glyph metrics without the use of bundled - * metrics tables (for example, the `hdmx' table in TrueType fonts). - * Well-behaving fonts have optimized bundled metrics and these should - * be used. This flag is mainly used by font validating or font - * editing applications, which need to ignore, verify, or edit those - * tables. + * [Since 2.6.1] Compute glyph metrics from the glyph data, without + * the use of bundled metrics tables (for example, the `hdmx' table in + * TrueType fonts). This flag is mainly used by font validating or + * font editing applications, which need to ignore, verify, or edit + * those tables. * * Currently, this flag is only implemented for TrueType fonts. * + * FT_LOAD_BITMAP_METRICS_ONLY :: + * [Since 2.7.1] Request loading of the metrics and bitmap image + * information of a (possibly embedded) bitmap glyph without + * allocating or copying the bitmap image data itself. No effect if + * the target glyph is not a bitmap image. + * + * This flag unsets @FT_LOAD_RENDER. + * * FT_LOAD_CROP_BITMAP :: * Ignored. Deprecated. * @@ -2796,13 +3025,14 @@ FT_BEGIN_HEADER #define FT_LOAD_MONOCHROME ( 1L << 12 ) #define FT_LOAD_LINEAR_DESIGN ( 1L << 13 ) #define FT_LOAD_NO_AUTOHINT ( 1L << 15 ) - /* Bits 16..19 are used by `FT_LOAD_TARGET_' */ + /* Bits 16-19 are used by `FT_LOAD_TARGET_' */ #define FT_LOAD_COLOR ( 1L << 20 ) #define FT_LOAD_COMPUTE_METRICS ( 1L << 21 ) +#define FT_LOAD_BITMAP_METRICS_ONLY ( 1L << 22 ) /* */ - /* used internally only by certain font drivers! */ + /* used internally only by certain font drivers */ #define FT_LOAD_ADVANCE_ONLY ( 1L << 8 ) #define FT_LOAD_SBITS_ONLY ( 1L << 14 ) @@ -2813,29 +3043,40 @@ FT_BEGIN_HEADER * FT_LOAD_TARGET_XXX * * @description: - * A list of values that are used to select a specific hinting algorithm - * to use by the hinter. You should OR one of these values to your - * `load_flags' when calling @FT_Load_Glyph. + * A list of values to select a specific hinting algorithm for the + * hinter. You should OR one of these values to your `load_flags' + * when calling @FT_Load_Glyph. * - * Note that font's native hinters may ignore the hinting algorithm you - * have specified (e.g., the TrueType bytecode interpreter). You can set - * @FT_LOAD_FORCE_AUTOHINT to ensure that the auto-hinter is used. - * - * Also note that @FT_LOAD_TARGET_LIGHT is an exception, in that it - * always implies @FT_LOAD_FORCE_AUTOHINT. + * Note that a font's native hinters may ignore the hinting algorithm + * you have specified (e.g., the TrueType bytecode interpreter). You + * can set @FT_LOAD_FORCE_AUTOHINT to ensure that the auto-hinter is + * used. * * @values: * FT_LOAD_TARGET_NORMAL :: - * This corresponds to the default hinting algorithm, optimized for - * standard gray-level rendering. For monochrome output, use - * @FT_LOAD_TARGET_MONO instead. + * The default hinting algorithm, optimized for standard gray-level + * rendering. For monochrome output, use @FT_LOAD_TARGET_MONO + * instead. * * FT_LOAD_TARGET_LIGHT :: - * A lighter hinting algorithm for non-monochrome modes. Many - * generated glyphs are more fuzzy but better resemble its original - * shape. A bit like rendering on Mac OS~X. + * A lighter hinting algorithm for gray-level modes. Many generated + * glyphs are fuzzier but better resemble their original shape. This + * is achieved by snapping glyphs to the pixel grid only vertically + * (Y-axis), as is done by FreeType's new CFF engine or Microsoft's + * ClearType font renderer. This preserves inter-glyph spacing in + * horizontal text. The snapping is done either by the native font + * driver, if the driver itself and the font support it, or by the + * auto-hinter. * - * As a special exception, this target implies @FT_LOAD_FORCE_AUTOHINT. + * Advance widths are rounded to integer values; however, using the + * `lsb_delta' and `rsb_delta' fields of @FT_GlyphSlotRec, it is + * possible to get fractional advance widths for subpixel positioning + * (which is recommended to use). + * + * If configuration option AF_CONFIG_OPTION_TT_SIZE_METRICS is active, + * TrueType-like metrics are used to make this mode behave similarly + * as in unpatched FreeType versions between 2.4.6 and 2.7.1 + * (inclusive). * * FT_LOAD_TARGET_MONO :: * Strong hinting algorithm that should only be used for monochrome @@ -2843,7 +3084,7 @@ FT_BEGIN_HEADER * in non-monochrome modes. * * FT_LOAD_TARGET_LCD :: - * A variant of @FT_LOAD_TARGET_NORMAL optimized for horizontally + * A variant of @FT_LOAD_TARGET_LIGHT optimized for horizontally * decimated LCD displays. * * FT_LOAD_TARGET_LCD_V :: @@ -2856,7 +3097,7 @@ FT_BEGIN_HEADER * * If @FT_LOAD_RENDER is also set, the glyph is rendered in the * corresponding mode (i.e., the mode that matches the used algorithm - * best). An exeption is FT_LOAD_TARGET_MONO since it implies + * best). An exception is FT_LOAD_TARGET_MONO since it implies * @FT_LOAD_MONOCHROME. * * You can use a hinting algorithm that doesn't correspond to the same @@ -2871,6 +3112,13 @@ FT_BEGIN_HEADER * FT_Render_Glyph( face->glyph, FT_RENDER_MODE_LCD ); * } * + * In general, you should stick with one rendering mode. For example, + * switching between @FT_LOAD_TARGET_NORMAL and @FT_LOAD_TARGET_MONO + * enforces a lot of recomputation for TrueType fonts, which is slow. + * Another reason is caching: Selecting a different mode usually causes + * changes in both the outlines and the rasterized bitmaps; it is thus + * necessary to empty the cache after a mode switch to avoid false hits. + * */ #define FT_LOAD_TARGET_( x ) ( (FT_Int32)( (x) & 15 ) << 16 ) @@ -2900,18 +3148,17 @@ FT_BEGIN_HEADER /* FT_Set_Transform */ /* */ /* */ - /* A function used to set the transformation that is applied to glyph */ - /* images when they are loaded into a glyph slot through */ - /* @FT_Load_Glyph. */ + /* Set the transformation that is applied to glyph images when they */ + /* are loaded into a glyph slot through @FT_Load_Glyph. */ /* */ /* */ /* face :: A handle to the source face object. */ /* */ /* */ - /* matrix :: A pointer to the transformation's 2x2 matrix. Use~0 for */ - /* the identity matrix. */ - /* delta :: A pointer to the translation vector. Use~0 for the null */ - /* vector. */ + /* matrix :: A pointer to the transformation's 2x2 matrix. Use NULL */ + /* for the identity matrix. */ + /* delta :: A pointer to the translation vector. Use NULL for the */ + /* null vector. */ /* */ /* */ /* The transformation is only applied to scalable image formats after */ @@ -2934,20 +3181,22 @@ FT_BEGIN_HEADER /* FT_Render_Mode */ /* */ /* */ - /* An enumeration type that lists the render modes supported by */ - /* FreeType~2. Each mode corresponds to a specific type of scanline */ - /* conversion performed on the outline. */ + /* Render modes supported by FreeType~2. Each mode corresponds to a */ + /* specific type of scanline conversion performed on the outline. */ /* */ /* For bitmap fonts and embedded bitmaps the `bitmap->pixel_mode' */ /* field in the @FT_GlyphSlotRec structure gives the format of the */ /* returned bitmap. */ /* */ - /* All modes except @FT_RENDER_MODE_MONO use 256 levels of opacity. */ + /* All modes except @FT_RENDER_MODE_MONO use 256 levels of opacity, */ + /* indicating pixel coverage. Use linear alpha blending and gamma */ + /* correction to correctly render non-monochrome glyph bitmaps onto a */ + /* surface; see @FT_Render_Glyph. */ /* */ /* */ /* FT_RENDER_MODE_NORMAL :: */ - /* This is the default render mode; it corresponds to 8-bit */ - /* anti-aliased bitmaps. */ + /* Default render mode; it corresponds to 8-bit anti-aliased */ + /* bitmaps. */ /* */ /* FT_RENDER_MODE_LIGHT :: */ /* This is equivalent to @FT_RENDER_MODE_NORMAL. It is only */ @@ -2960,23 +3209,25 @@ FT_BEGIN_HEADER /* opacity). */ /* */ /* FT_RENDER_MODE_LCD :: */ - /* This mode corresponds to horizontal RGB and BGR sub-pixel */ + /* This mode corresponds to horizontal RGB and BGR subpixel */ /* displays like LCD screens. It produces 8-bit bitmaps that are */ /* 3~times the width of the original glyph outline in pixels, and */ /* which use the @FT_PIXEL_MODE_LCD mode. */ /* */ /* FT_RENDER_MODE_LCD_V :: */ - /* This mode corresponds to vertical RGB and BGR sub-pixel displays */ + /* This mode corresponds to vertical RGB and BGR subpixel displays */ /* (like PDA screens, rotated LCD displays, etc.). It produces */ /* 8-bit bitmaps that are 3~times the height of the original */ /* glyph outline in pixels and use the @FT_PIXEL_MODE_LCD_V mode. */ /* */ /* */ - /* The LCD-optimized glyph bitmaps produced by FT_Render_Glyph can be */ - /* filtered to reduce color-fringes by using @FT_Library_SetLcdFilter */ - /* (not active in the default builds). It is up to the caller to */ - /* either call @FT_Library_SetLcdFilter (if available) or do the */ - /* filtering itself. */ + /* Should you define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your */ + /* `ftoption.h', which enables patented ClearType-style rendering, */ + /* the LCD-optimized glyph bitmaps should be filtered to reduce color */ + /* fringes inherent to this technology. You can either set up LCD */ + /* filtering with @FT_Library_SetLcdFilter or @FT_Face_Properties, */ + /* or do the filtering yourself. The default FreeType LCD rendering */ + /* technology does not require filtering. */ /* */ /* The selected render mode only affects vector glyphs of a font. */ /* Embedded bitmaps often have a different pixel mode like */ @@ -3017,16 +3268,93 @@ FT_BEGIN_HEADER /* convert. */ /* */ /* */ - /* render_mode :: This is the render mode used to render the glyph */ - /* image into a bitmap. See @FT_Render_Mode for a */ - /* list of possible values. */ + /* render_mode :: The render mode used to render the glyph image into */ + /* a bitmap. See @FT_Render_Mode for a list of */ + /* possible values. */ /* */ /* */ /* FreeType error code. 0~means success. */ /* */ /* */ /* To get meaningful results, font scaling values must be set with */ - /* functions like @FT_Set_Char_Size before calling FT_Render_Glyph. */ + /* functions like @FT_Set_Char_Size before calling `FT_Render_Glyph'. */ + /* */ + /* When FreeType outputs a bitmap of a glyph, it really outputs an */ + /* alpha coverage map. If a pixel is completely covered by a */ + /* filled-in outline, the bitmap contains 0xFF at that pixel, meaning */ + /* that 0xFF/0xFF fraction of that pixel is covered, meaning the */ + /* pixel is 100% black (or 0% bright). If a pixel is only 50% */ + /* covered (value 0x80), the pixel is made 50% black (50% bright or a */ + /* middle shade of grey). 0% covered means 0% black (100% bright or */ + /* white). */ + /* */ + /* On high-DPI screens like on smartphones and tablets, the pixels */ + /* are so small that their chance of being completely covered and */ + /* therefore completely black are fairly good. On the low-DPI */ + /* screens, however, the situation is different. The pixels are too */ + /* large for most of the details of a glyph and shades of gray are */ + /* the norm rather than the exception. */ + /* */ + /* This is relevant because all our screens have a second problem: */ + /* they are not linear. 1~+~1 is not~2. Twice the value does not */ + /* result in twice the brightness. When a pixel is only 50% covered, */ + /* the coverage map says 50% black, and this translates to a pixel */ + /* value of 128 when you use 8~bits per channel (0-255). However, */ + /* this does not translate to 50% brightness for that pixel on our */ + /* sRGB and gamma~2.2 screens. Due to their non-linearity, they */ + /* dwell longer in the darks and only a pixel value of about 186 */ + /* results in 50% brightness -- 128 ends up too dark on both bright */ + /* and dark backgrounds. The net result is that dark text looks */ + /* burnt-out, pixely and blotchy on bright background, bright text */ + /* too frail on dark backgrounds, and colored text on colored */ + /* background (for example, red on green) seems to have dark halos or */ + /* `dirt' around it. The situation is especially ugly for diagonal */ + /* stems like in `w' glyph shapes where the quality of FreeType's */ + /* anti-aliasing depends on the correct display of grays. On */ + /* high-DPI screens where smaller, fully black pixels reign supreme, */ + /* this doesn't matter, but on our low-DPI screens with all the gray */ + /* shades, it does. 0% and 100% brightness are the same things in */ + /* linear and non-linear space, just all the shades in-between */ + /* aren't. */ + /* */ + /* The blending function for placing text over a background is */ + /* */ + /* { */ + /* dst = alpha * src + (1 - alpha) * dst , */ + /* } */ + /* */ + /* which is known as the OVER operator. */ + /* */ + /* To correctly composite an antialiased pixel of a glyph onto a */ + /* surface, */ + /* */ + /* 1. take the foreground and background colors (e.g., in sRGB space) */ + /* and apply gamma to get them in a linear space, */ + /* */ + /* 2. use OVER to blend the two linear colors using the glyph pixel */ + /* as the alpha value (remember, the glyph bitmap is an alpha */ + /* coverage bitmap), and */ + /* */ + /* 3. apply inverse gamma to the blended pixel and write it back to */ + /* the image. */ + /* */ + /* Internal testing at Adobe found that a target inverse gamma of~1.8 */ + /* for step~3 gives good results across a wide range of displays with */ + /* an sRGB gamma curve or a similar one. */ + /* */ + /* This process can cost performance. There is an approximation that */ + /* does not need to know about the background color; see */ + /* https://bel.fi/alankila/lcd/ and */ + /* https://bel.fi/alankila/lcd/alpcor.html for details. */ + /* */ + /* *ATTENTION*: Linear blending is even more important when dealing */ + /* with subpixel-rendered glyphs to prevent color-fringing! A */ + /* subpixel-rendered glyph must first be filtered with a filter that */ + /* gives equal weight to the three color primaries and does not */ + /* exceed a sum of 0x100, see section @lcd_filtering. Then the */ + /* only difference to gray linear blending is that subpixel-rendered */ + /* linear blending is done 3~times per pixel: red foreground subpixel */ + /* to red background subpixel and so on for green and blue. */ /* */ FT_EXPORT( FT_Error ) FT_Render_Glyph( FT_GlyphSlot slot, @@ -3039,17 +3367,15 @@ FT_BEGIN_HEADER /* FT_Kerning_Mode */ /* */ /* */ - /* An enumeration used to specify which kerning values to return in */ + /* An enumeration to specify the format of kerning values returned by */ /* @FT_Get_Kerning. */ /* */ /* */ /* FT_KERNING_DEFAULT :: Return grid-fitted kerning distances in */ - /* pixels (value is~0). Whether they are */ - /* scaled depends on @FT_LOAD_NO_SCALE. */ + /* 26.6 fractional pixels. */ /* */ /* FT_KERNING_UNFITTED :: Return un-grid-fitted kerning distances in */ - /* 26.6 fractional pixels. Whether they are */ - /* scaled depends on @FT_LOAD_NO_SCALE. */ + /* 26.6 fractional pixels. */ /* */ /* FT_KERNING_UNSCALED :: Return the kerning vector in original font */ /* units. */ @@ -3059,9 +3385,13 @@ FT_BEGIN_HEADER /* FreeType heuristically scale down kerning distances at small ppem */ /* values so that they don't become too big. */ /* */ + /* Both FT_KERNING_DEFAULT and FT_KERNING_UNFITTED use the current */ + /* horizontal scaling factor (as set e.g. with @FT_Set_Char_Size) to */ + /* convert font units to pixels. */ + /* */ typedef enum FT_Kerning_Mode_ { - FT_KERNING_DEFAULT = 0, + FT_KERNING_DEFAULT = 0, FT_KERNING_UNFITTED, FT_KERNING_UNSCALED @@ -3081,7 +3411,7 @@ FT_BEGIN_HEADER /* FT_Get_Kerning */ /* */ /* */ - /* Return the kerning vector between two glyphs of a same face. */ + /* Return the kerning vector between two glyphs of the same face. */ /* */ /* */ /* face :: A handle to a source face object. */ @@ -3109,6 +3439,10 @@ FT_BEGIN_HEADER /* kernings, are out of the scope of this API function -- they can be */ /* implemented through format-specific interfaces. */ /* */ + /* Kerning for OpenType fonts implemented in a `GPOS' table is not */ + /* supported; use @FT_HAS_KERNING to find out whether a font has data */ + /* that can be extracted with `FT_Get_Kerning'. */ + /* */ FT_EXPORT( FT_Error ) FT_Get_Kerning( FT_Face face, FT_UInt left_glyph, @@ -3148,7 +3482,7 @@ FT_BEGIN_HEADER /* @FT_Attach_Stream). */ /* */ /* Only very few AFM files come with track kerning data; please refer */ - /* to the Adobe's AFM specification for more details. */ + /* to Adobe's AFM specification for more details. */ /* */ FT_EXPORT( FT_Error ) FT_Get_Track_Kerning( FT_Face face, @@ -3194,7 +3528,7 @@ FT_BEGIN_HEADER /* `.notdef'). */ /* */ /* This function always returns an error if the config macro */ - /* `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is not defined in `ftoptions.h'. */ + /* `FT_CONFIG_OPTION_NO_GLYPH_NAMES' is not defined in `ftoption.h'. */ /* */ FT_EXPORT( FT_Error ) FT_Get_Glyph_Name( FT_Face face, @@ -3210,7 +3544,7 @@ FT_BEGIN_HEADER /* */ /* */ /* Retrieve the ASCII PostScript name of a given face, if available. */ - /* This only works with PostScript and TrueType fonts. */ + /* This only works with PostScript, TrueType, and OpenType fonts. */ /* */ /* */ /* face :: A handle to the source face object. */ @@ -3222,6 +3556,20 @@ FT_BEGIN_HEADER /* The returned pointer is owned by the face and is destroyed with */ /* it. */ /* */ + /* For variation fonts, this string changes if you select a different */ + /* instance, and you have to call `FT_Get_PostScript_Name' again to */ + /* retrieve it. FreeType follows Adobe TechNote #5902, `Generating */ + /* PostScript Names for Fonts Using OpenType Font Variations'. */ + /* */ + /* https://download.macromedia.com/pub/developer/opentype/tech-notes/5902.AdobePSNameGeneration.html */ + /* */ + /* [Since 2.9] Special PostScript names for named instances are only */ + /* returned if the named instance is set with @FT_Set_Named_Instance */ + /* (and the font has corresponding entries in its `fvar' table). If */ + /* @FT_IS_VARIATION returns true, the algorithmically derived */ + /* PostScript name is provided, not looking up special entries for */ + /* named instances. */ + /* */ FT_EXPORT( const char* ) FT_Get_Postscript_Name( FT_Face face ); @@ -3281,7 +3629,8 @@ FT_BEGIN_HEADER /* the face (i.e., if it is not listed in the `face->charmaps' */ /* table). */ /* */ - /* It also fails if a type~14 charmap is selected. */ + /* It also fails if an OpenType type~14 charmap is selected (which */ + /* doesn't map character codes to glyph indices at all). */ /* */ FT_EXPORT( FT_Error ) FT_Set_Charmap( FT_Face face, @@ -3316,7 +3665,7 @@ FT_BEGIN_HEADER /* */ /* */ /* Return the glyph index of a given character code. This function */ - /* uses a charmap object to do the mapping. */ + /* uses the currently selected charmap to do the mapping. */ /* */ /* */ /* face :: A handle to the source face object. */ @@ -3350,9 +3699,8 @@ FT_BEGIN_HEADER /* FT_Get_First_Char */ /* */ /* */ - /* This function is used to return the first character code in the */ - /* current charmap of a given face. It also returns the */ - /* corresponding glyph index. */ + /* Return the first character code in the current charmap of a given */ + /* face, together with its corresponding glyph index. */ /* */ /* */ /* face :: A handle to the source face object. */ @@ -3365,7 +3713,7 @@ FT_BEGIN_HEADER /* The charmap's first character code. */ /* */ /* */ - /* You should use this function with @FT_Get_Next_Char to be able to */ + /* You should use this function together with @FT_Get_Next_Char to */ /* parse all character codes available in a given charmap. The code */ /* should look like this: */ /* */ @@ -3405,12 +3753,13 @@ FT_BEGIN_HEADER /* FT_Get_Next_Char */ /* */ /* */ - /* This function is used to return the next character code in the */ - /* current charmap of a given face following the value `char_code', */ - /* as well as the corresponding glyph index. */ + /* Return the next character code in the current charmap of a given */ + /* face following the value `char_code', as well as the corresponding */ + /* glyph index. */ /* */ /* */ /* face :: A handle to the source face object. */ + /* */ /* char_code :: The starting character code. */ /* */ /* */ @@ -3423,7 +3772,7 @@ FT_BEGIN_HEADER /* */ /* You should use this function with @FT_Get_First_Char to walk */ /* over all character codes available in a given charmap. See the */ - /* note for this function for a simple code example. */ + /* note for that function for a simple code example. */ /* */ /* Note that `*agindex' is set to~0 when there are no more codes in */ /* the charmap. */ @@ -3434,14 +3783,112 @@ FT_BEGIN_HEADER FT_UInt *agindex ); + /************************************************************************* + * + * @function: + * FT_Face_Properties + * + * @description: + * Set or override certain (library or module-wide) properties on a + * face-by-face basis. Useful for finer-grained control and avoiding + * locks on shared structures (threads can modify their own faces as + * they see fit). + * + * Contrary to @FT_Property_Set, this function uses @FT_Parameter so + * that you can pass multiple properties to the target face in one call. + * Note that only a subset of the available properties can be + * controlled. + * + * * @FT_PARAM_TAG_STEM_DARKENING (stem darkening, corresponding to the + * property `no-stem-darkening' provided by the `autofit', `cff', + * `type1', and `t1cid' modules; see @no-stem-darkening). + * + * * @FT_PARAM_TAG_LCD_FILTER_WEIGHTS (LCD filter weights, corresponding + * to function @FT_Library_SetLcdFilterWeights). + * + * * @FT_PARAM_TAG_RANDOM_SEED (seed value for the CFF, Type~1, and CID + * `random' operator, corresponding to the `random-seed' property + * provided by the `cff', `type1', and `t1cid' modules; see + * @random-seed). + * + * Pass NULL as `data' in @FT_Parameter for a given tag to reset the + * option and use the library or module default again. + * + * @input: + * face :: + * A handle to the source face object. + * + * num_properties :: + * The number of properties that follow. + * + * properties :: + * A handle to an @FT_Parameter array with `num_properties' elements. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * Here an example that sets three properties. You must define + * FT_CONFIG_OPTION_SUBPIXEL_RENDERING to make the LCD filter examples + * work. + * + * { + * FT_Parameter property1; + * FT_Bool darken_stems = 1; + * + * FT_Parameter property2; + * FT_LcdFiveTapFilter custom_weight = + * { 0x11, 0x44, 0x56, 0x44, 0x11 }; + * + * FT_Parameter property3; + * FT_Int32 random_seed = 314159265; + * + * FT_Parameter properties[3] = { property1, + * property2, + * property3 }; + * + * + * property1.tag = FT_PARAM_TAG_STEM_DARKENING; + * property1.data = &darken_stems; + * + * property2.tag = FT_PARAM_TAG_LCD_FILTER_WEIGHTS; + * property2.data = custom_weight; + * + * property3.tag = FT_PARAM_TAG_RANDOM_SEED; + * property3.data = &random_seed; + * + * FT_Face_Properties( face, 3, properties ); + * } + * + * The next example resets a single property to its default value. + * + * { + * FT_Parameter property; + * + * + * property.tag = FT_PARAM_TAG_LCD_FILTER_WEIGHTS; + * property.data = NULL; + * + * FT_Face_Properties( face, 1, &property ); + * } + * + * @since: + * 2.8 + * + */ + FT_EXPORT( FT_Error ) + FT_Face_Properties( FT_Face face, + FT_UInt num_properties, + FT_Parameter* properties ); + + /*************************************************************************/ /* */ /* */ /* FT_Get_Name_Index */ /* */ /* */ - /* Return the glyph index of a given glyph name. This function uses */ - /* driver specific objects to do the translation. */ + /* Return the glyph index of a given glyph name. */ /* */ /* */ /* face :: A handle to the source face object. */ @@ -3462,8 +3909,10 @@ FT_BEGIN_HEADER * FT_SUBGLYPH_FLAG_XXX * * @description: - * A list of constants used to describe subglyphs. Please refer to the - * TrueType specification for the meaning of the various flags. + * A list of constants describing subglyphs. Please refer to the + * `glyf' table description in the OpenType specification for the + * meaning of the various flags (which get synthesized for + * non-OpenType subglyphs). * * @values: * FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS :: @@ -3524,7 +3973,7 @@ FT_BEGIN_HEADER * @note: * The values of `*p_arg1', `*p_arg2', and `*p_transform' must be * interpreted depending on the flags returned in `*p_flags'. See the - * TrueType specification for details. + * OpenType specification for details. * */ FT_EXPORT( FT_Error ) @@ -3550,7 +3999,7 @@ FT_BEGIN_HEADER /* and subsetting restrictions associated with a font. */ /* */ /* See */ - /* http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/FontPolicies.pdf */ + /* https://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/FontPolicies.pdf */ /* for more details. */ /* */ /* */ @@ -3564,33 +4013,31 @@ FT_BEGIN_HEADER /* the font software copyright owner. */ /* */ /* FT_FSTYPE_PREVIEW_AND_PRINT_EMBEDDING :: */ - /* If this bit is set, the font may be embedded and temporarily */ - /* loaded on the remote system. Documents containing Preview & */ - /* Print fonts must be opened `read-only'; no edits can be applied */ - /* to the document. */ + /* The font may be embedded and temporarily loaded on the remote */ + /* system. Documents containing Preview & Print fonts must be */ + /* opened `read-only'; no edits can be applied to the document. */ /* */ /* FT_FSTYPE_EDITABLE_EMBEDDING :: */ - /* If this bit is set, the font may be embedded but must only be */ - /* installed temporarily on other systems. In contrast to Preview */ - /* & Print fonts, documents containing editable fonts may be opened */ - /* for reading, editing is permitted, and changes may be saved. */ + /* The font may be embedded but must only be installed temporarily */ + /* on other systems. In contrast to Preview & Print fonts, */ + /* documents containing editable fonts may be opened for reading, */ + /* editing is permitted, and changes may be saved. */ /* */ /* FT_FSTYPE_NO_SUBSETTING :: */ - /* If this bit is set, the font may not be subsetted prior to */ - /* embedding. */ + /* The font may not be subsetted prior to embedding. */ /* */ /* FT_FSTYPE_BITMAP_EMBEDDING_ONLY :: */ - /* If this bit is set, only bitmaps contained in the font may be */ - /* embedded; no outline data may be embedded. If there are no */ - /* bitmaps available in the font, then the font is unembeddable. */ + /* Only bitmaps contained in the font may be embedded; no outline */ + /* data may be embedded. If there are no bitmaps available in the */ + /* font, then the font is unembeddable. */ /* */ /* */ /* The flags are ORed together, thus more than a single value can be */ /* returned. */ /* */ - /* While the fsType flags can indicate that a font may be embedded, a */ - /* license with the font vendor may be separately required to use the */ - /* font in this way. */ + /* While the `fsType' flags can indicate that a font may be embedded, */ + /* a license with the font vendor may be separately required to use */ + /* the font in this way. */ /* */ #define FT_FSTYPE_INSTALLABLE_EMBEDDING 0x0000 #define FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING 0x0002 @@ -3606,13 +4053,13 @@ FT_BEGIN_HEADER /* FT_Get_FSType_Flags */ /* */ /* */ - /* Return the fsType flags for a font. */ + /* Return the `fsType' flags for a font. */ /* */ /* */ /* face :: A handle to the source face object. */ /* */ /* */ - /* The fsType flags, @FT_FSTYPE_XXX. */ + /* The `fsType' flags, see @FT_FSTYPE_XXX. */ /* */ /* */ /* Use this function rather than directly reading the `fs_type' field */ @@ -3632,39 +4079,51 @@ FT_BEGIN_HEADER /* glyph_variants */ /* */ /* */ - /* Glyph Variants */ + /* Unicode Variation Sequences */ /* */ /* <Abstract> */ - /* The FreeType~2 interface to Unicode Ideographic Variation */ - /* Sequences (IVS), using the SFNT cmap format~14. */ + /* The FreeType~2 interface to Unicode Variation Sequences (UVS), */ + /* using the SFNT cmap format~14. */ /* */ /* <Description> */ - /* Many CJK characters have variant forms. They are a sort of grey */ - /* area somewhere between being totally irrelevant and semantically */ - /* distinct; for this reason, the Unicode consortium decided to */ - /* introduce Ideographic Variation Sequences (IVS), consisting of a */ - /* Unicode base character and one of 240 variant selectors */ - /* (U+E0100-U+E01EF), instead of further extending the already huge */ - /* code range for CJK characters. */ + /* Many characters, especially for CJK scripts, have variant forms. */ + /* They are a sort of grey area somewhere between being totally */ + /* irrelevant and semantically distinct; for this reason, the Unicode */ + /* consortium decided to introduce Variation Sequences (VS), */ + /* consisting of a Unicode base character and a variation selector */ + /* instead of further extending the already huge number of */ + /* characters. */ /* */ - /* An IVS is registered and unique; for further details please refer */ - /* to Unicode Technical Standard #37, the Ideographic Variation */ - /* Database: */ + /* Unicode maintains two different sets, namely `Standardized */ + /* Variation Sequences' and registered `Ideographic Variation */ + /* Sequences' (IVS), collected in the `Ideographic Variation */ + /* Database' (IVD). */ /* */ - /* http://www.unicode.org/reports/tr37/ */ + /* https://unicode.org/Public/UCD/latest/ucd/StandardizedVariants.txt */ + /* https://unicode.org/reports/tr37/ */ + /* https://unicode.org/ivd/ */ /* */ - /* To date (November 2014), the character with the most variants is */ - /* U+9089, having 32 such IVS. */ + /* To date (January 2017), the character with the most ideographic */ + /* variations is U+9089, having 32 such IVS. */ /* */ - /* Adobe and MS decided to support IVS with a new cmap subtable */ - /* (format~14). It is an odd subtable because it is not a mapping of */ - /* input code points to glyphs, but contains lists of all variants */ - /* supported by the font. */ + /* Three Mongolian Variation Selectors have the values U+180B-U+180D; */ + /* 256 generic Variation Selectors are encoded in the ranges */ + /* U+FE00-U+FE0F and U+E0100-U+E01EF. IVS currently use Variation */ + /* Selectors from the range U+E0100-U+E01EF only. */ /* */ - /* A variant may be either `default' or `non-default'. A default */ - /* variant is the one you will get for that code point if you look it */ - /* up in the standard Unicode cmap. A non-default variant is a */ - /* different glyph. */ + /* A VS consists of the base character value followed by a single */ + /* Variation Selector. For example, to get the first variation of */ + /* U+9089, you have to write the character sequence `U+9089 U+E0100'. */ + /* */ + /* Adobe and MS decided to support both standardized and ideographic */ + /* VS with a new cmap subtable (format~14). It is an odd subtable */ + /* because it is not a mapping of input code points to glyphs, but */ + /* contains lists of all variations supported by the font. */ + /* */ + /* A variation may be either `default' or `non-default' for a given */ + /* font. A default variation is the one you will get for that code */ + /* point if you look it up in the standard Unicode cmap. A */ + /* non-default variation is a different glyph. */ /* */ /*************************************************************************/ @@ -3720,8 +4179,8 @@ FT_BEGIN_HEADER /* FT_Face_GetCharVariantIsDefault */ /* */ /* <Description> */ - /* Check whether this variant of this Unicode character is the one to */ - /* be found in the `cmap'. */ + /* Check whether this variation of this Unicode character is the one */ + /* to be found in the `cmap'. */ /* */ /* <Input> */ /* face :: */ @@ -3735,7 +4194,7 @@ FT_BEGIN_HEADER /* */ /* <Return> */ /* 1~if found in the standard (Unicode) cmap, 0~if found in the */ - /* variation selector cmap, or -1 if it is not a variant. */ + /* variation selector cmap, or -1 if it is not a variation. */ /* */ /* <Note> */ /* This function is only meaningful if the font has a variation */ @@ -3756,7 +4215,7 @@ FT_BEGIN_HEADER /* FT_Face_GetVariantSelectors */ /* */ /* <Description> */ - /* Return a zero-terminated list of Unicode variant selectors found */ + /* Return a zero-terminated list of Unicode variation selectors found */ /* in the font. */ /* */ /* <Input> */ @@ -3765,7 +4224,7 @@ FT_BEGIN_HEADER /* */ /* <Return> */ /* A pointer to an array of selector code points, or NULL if there is */ - /* no valid variant selector cmap subtable. */ + /* no valid variation selector cmap subtable. */ /* */ /* <Note> */ /* The last item in the array is~0; the array is owned by the */ @@ -3785,7 +4244,7 @@ FT_BEGIN_HEADER /* FT_Face_GetVariantsOfChar */ /* */ /* <Description> */ - /* Return a zero-terminated list of Unicode variant selectors found */ + /* Return a zero-terminated list of Unicode variation selectors found */ /* for the specified character code. */ /* */ /* <Input> */ @@ -3796,7 +4255,7 @@ FT_BEGIN_HEADER /* The character codepoint in Unicode. */ /* */ /* <Return> */ - /* A pointer to an array of variant selector code points that are */ + /* A pointer to an array of variation selector code points that are */ /* active for the given character, or NULL if the corresponding list */ /* is empty. */ /* */ @@ -3820,19 +4279,19 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* Return a zero-terminated list of Unicode character codes found for */ - /* the specified variant selector. */ + /* the specified variation selector. */ /* */ /* <Input> */ /* face :: */ /* A handle to the source face object. */ /* */ /* variantSelector :: */ - /* The variant selector code point in Unicode. */ + /* The variation selector code point in Unicode. */ /* */ /* <Return> */ /* A list of all the code points that are specified by this selector */ /* (both default and non-default codes are returned) or NULL if there */ - /* is no valid cmap or the variant selector is invalid. */ + /* is no valid cmap or the variation selector is invalid. */ /* */ /* <Note> */ /* The last item in the array is~0; the array is owned by the */ @@ -3882,16 +4341,17 @@ FT_BEGIN_HEADER /* FT_MulDiv */ /* */ /* <Description> */ - /* A very simple function used to perform the computation `(a*b)/c' */ - /* with maximum accuracy (it uses a 64-bit intermediate integer */ - /* whenever necessary). */ + /* Compute `(a*b)/c' with maximum accuracy, using a 64-bit */ + /* intermediate integer whenever necessary. */ /* */ /* This function isn't necessarily as fast as some processor specific */ /* operations, but is at least completely portable. */ /* */ /* <Input> */ /* a :: The first multiplier. */ + /* */ /* b :: The second multiplier. */ + /* */ /* c :: The divisor. */ /* */ /* <Return> */ @@ -3911,12 +4371,12 @@ FT_BEGIN_HEADER /* FT_MulFix */ /* */ /* <Description> */ - /* A very simple function used to perform the computation */ - /* `(a*b)/0x10000' with maximum accuracy. Most of the time this is */ - /* used to multiply a given value by a 16.16 fixed-point factor. */ + /* Compute `(a*b)/0x10000' with maximum accuracy. Its main use is to */ + /* multiply a given value by a 16.16 fixed-point factor. */ /* */ /* <Input> */ /* a :: The first multiplier. */ + /* */ /* b :: The second multiplier. Use a 16.16 factor here whenever */ /* possible (see note below). */ /* */ @@ -3945,12 +4405,12 @@ FT_BEGIN_HEADER /* FT_DivFix */ /* */ /* <Description> */ - /* A very simple function used to perform the computation */ - /* `(a*0x10000)/b' with maximum accuracy. Most of the time, this is */ - /* used to divide a given value by a 16.16 fixed-point factor. */ + /* Compute `(a*0x10000)/b' with maximum accuracy. Its main use is to */ + /* divide a given value by a 16.16 fixed-point factor. */ /* */ /* <Input> */ /* a :: The numerator. */ + /* */ /* b :: The denominator. Use a 16.16 factor here. */ /* */ /* <Return> */ @@ -3967,15 +4427,18 @@ FT_BEGIN_HEADER /* FT_RoundFix */ /* */ /* <Description> */ - /* A very simple function used to round a 16.16 fixed number. */ + /* Round a 16.16 fixed number. */ /* */ /* <Input> */ /* a :: The number to be rounded. */ /* */ /* <Return> */ - /* `a' rounded to nearest 16.16 fixed integer, halfway cases away */ + /* `a' rounded to the nearest 16.16 fixed integer, halfway cases away */ /* from zero. */ /* */ + /* <Note> */ + /* The function uses wrap-around arithmetic. */ + /* */ FT_EXPORT( FT_Fixed ) FT_RoundFix( FT_Fixed a ); @@ -3986,8 +4449,7 @@ FT_BEGIN_HEADER /* FT_CeilFix */ /* */ /* <Description> */ - /* A very simple function used to compute the ceiling function of a */ - /* 16.16 fixed number. */ + /* Compute the smallest following integer of a 16.16 fixed number. */ /* */ /* <Input> */ /* a :: The number for which the ceiling function is to be computed. */ @@ -3995,6 +4457,9 @@ FT_BEGIN_HEADER /* <Return> */ /* `a' rounded towards plus infinity. */ /* */ + /* <Note> */ + /* The function uses wrap-around arithmetic. */ + /* */ FT_EXPORT( FT_Fixed ) FT_CeilFix( FT_Fixed a ); @@ -4005,8 +4470,7 @@ FT_BEGIN_HEADER /* FT_FloorFix */ /* */ /* <Description> */ - /* A very simple function used to compute the floor function of a */ - /* 16.16 fixed number. */ + /* Compute the largest previous integer of a 16.16 fixed number. */ /* */ /* <Input> */ /* a :: The number for which the floor function is to be computed. */ @@ -4092,7 +4556,7 @@ FT_BEGIN_HEADER * */ #define FREETYPE_MAJOR 2 -#define FREETYPE_MINOR 6 +#define FREETYPE_MINOR 9 #define FREETYPE_PATCH 1 @@ -4138,20 +4602,13 @@ FT_BEGIN_HEADER /* FT_Face_CheckTrueTypePatents */ /* */ /* <Description> */ - /* Parse all bytecode instructions of a TrueType font file to check */ - /* whether any of the patented opcodes are used. This is only useful */ - /* if you want to be able to use the unpatented hinter with */ - /* fonts that do *not* use these opcodes. */ - /* */ - /* Note that this function parses *all* glyph instructions in the */ - /* font file, which may be slow. */ + /* Deprecated, does nothing. */ /* */ /* <Input> */ /* face :: A face handle. */ /* */ /* <Return> */ - /* 1~if this is a TrueType font that uses one of the patented */ - /* opcodes, 0~otherwise. */ + /* Always returns false. */ /* */ /* <Note> */ /* Since May 2010, TrueType hinting is no longer patented. */ @@ -4169,9 +4626,7 @@ FT_BEGIN_HEADER /* FT_Face_SetUnpatentedHinting */ /* */ /* <Description> */ - /* Enable or disable the unpatented hinter for a given face. */ - /* Only enable it if you have determined that the face doesn't */ - /* use any patented opcodes (see @FT_Face_CheckTrueTypePatents). */ + /* Deprecated, does nothing. */ /* */ /* <Input> */ /* face :: A face handle. */ @@ -4179,9 +4634,7 @@ FT_BEGIN_HEADER /* value :: New boolean setting. */ /* */ /* <Return> */ - /* The old setting value. This will always be false if this is not */ - /* an SFNT font, or if the unpatented hinter is not compiled in this */ - /* instance of the library. */ + /* Always returns false. */ /* */ /* <Note> */ /* Since May 2010, TrueType hinting is no longer patented. */ @@ -4198,7 +4651,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FREETYPE_H__ */ +#endif /* FREETYPE_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftadvanc.h b/src/3rdparty/freetype/include/freetype/ftadvanc.h index b4d2aed567..f78e8b1a9d 100644 --- a/src/3rdparty/freetype/include/freetype/ftadvanc.h +++ b/src/3rdparty/freetype/include/freetype/ftadvanc.h @@ -4,7 +4,7 @@ /* */ /* Quick computation of advance widths (specification only). */ /* */ -/* Copyright 2008-2015 by */ +/* Copyright 2008-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTADVANC_H__ -#define __FTADVANC_H__ +#ifndef FTADVANC_H_ +#define FTADVANC_H_ #include <ft2build.h> @@ -181,7 +181,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTADVANC_H__ */ +#endif /* FTADVANC_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftbbox.h b/src/3rdparty/freetype/include/freetype/ftbbox.h index 9d9d040767..f9eb70b137 100644 --- a/src/3rdparty/freetype/include/freetype/ftbbox.h +++ b/src/3rdparty/freetype/include/freetype/ftbbox.h @@ -4,7 +4,7 @@ /* */ /* FreeType exact bbox computation (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -27,8 +27,8 @@ /*************************************************************************/ -#ifndef __FTBBOX_H__ -#define __FTBBOX_H__ +#ifndef FTBBOX_H_ +#define FTBBOX_H_ #include <ft2build.h> @@ -61,7 +61,7 @@ FT_BEGIN_HEADER /* Compute the exact bounding box of an outline. This is slower */ /* than computing the control box. However, it uses an advanced */ /* algorithm that returns _very_ quickly when the two boxes */ - /* coincide. Otherwise, the outline Bézier arcs are traversed to */ + /* coincide. Otherwise, the outline Bezier arcs are traversed to */ /* extract their extrema. */ /* */ /* <Input> */ @@ -90,7 +90,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTBBOX_H__ */ +#endif /* FTBBOX_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftbdf.h b/src/3rdparty/freetype/include/freetype/ftbdf.h index 0bdabf481c..1b6dea6586 100644 --- a/src/3rdparty/freetype/include/freetype/ftbdf.h +++ b/src/3rdparty/freetype/include/freetype/ftbdf.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing BDF-specific strings (specification). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTBDF_H__ -#define __FTBDF_H__ +#ifndef FTBDF_H_ +#define FTBDF_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -204,7 +204,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTBDF_H__ */ +#endif /* FTBDF_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftbitmap.h b/src/3rdparty/freetype/include/freetype/ftbitmap.h index 46cc47b7d1..a43187cad4 100644 --- a/src/3rdparty/freetype/include/freetype/ftbitmap.h +++ b/src/3rdparty/freetype/include/freetype/ftbitmap.h @@ -4,7 +4,7 @@ /* */ /* FreeType utility functions for bitmaps (specification). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTBITMAP_H__ -#define __FTBITMAP_H__ +#ifndef FTBITMAP_H_ +#define FTBITMAP_H_ #include <ft2build.h> @@ -97,7 +97,7 @@ FT_BEGIN_HEADER FT_EXPORT( FT_Error ) FT_Bitmap_Copy( FT_Library library, const FT_Bitmap *source, - FT_Bitmap *target); + FT_Bitmap *target ); /*************************************************************************/ @@ -234,7 +234,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTBITMAP_H__ */ +#endif /* FTBITMAP_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftbzip2.h b/src/3rdparty/freetype/include/freetype/ftbzip2.h index c25f9469df..6edfa031b5 100644 --- a/src/3rdparty/freetype/include/freetype/ftbzip2.h +++ b/src/3rdparty/freetype/include/freetype/ftbzip2.h @@ -4,7 +4,7 @@ /* */ /* Bzip2-compressed stream support. */ /* */ -/* Copyright 2010-2015 by */ +/* Copyright 2010-2018 by */ /* Joel Klinghed. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTBZIP2_H__ -#define __FTBZIP2_H__ +#ifndef FTBZIP2_H_ +#define FTBZIP2_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -96,7 +96,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTBZIP2_H__ */ +#endif /* FTBZIP2_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftcache.h b/src/3rdparty/freetype/include/freetype/ftcache.h index 68525bb829..52d5f00e06 100644 --- a/src/3rdparty/freetype/include/freetype/ftcache.h +++ b/src/3rdparty/freetype/include/freetype/ftcache.h @@ -4,7 +4,7 @@ /* */ /* FreeType Cache subsystem (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTCACHE_H__ -#define __FTCACHE_H__ +#ifndef FTCACHE_H_ +#define FTCACHE_H_ #include <ft2build.h> @@ -540,13 +540,6 @@ FT_BEGIN_HEADER FTC_FaceID face_id ); - /*************************************************************************/ - /* */ - /* <Section> */ - /* cache_subsystem */ - /* */ - /*************************************************************************/ - /************************************************************************* * * @type: @@ -623,14 +616,6 @@ FT_BEGIN_HEADER FT_UInt32 char_code ); - /*************************************************************************/ - /* */ - /* <Section> */ - /* cache_subsystem */ - /* */ - /*************************************************************************/ - - /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ @@ -749,7 +734,7 @@ FT_BEGIN_HEADER /* aglyph :: The corresponding @FT_Glyph object. 0~in case of */ /* failure. */ /* */ - /* anode :: Used to return the address of of the corresponding cache */ + /* anode :: Used to return the address of the corresponding cache */ /* node after incrementing its reference count (see note */ /* below). */ /* */ @@ -802,7 +787,7 @@ FT_BEGIN_HEADER /* aglyph :: The corresponding @FT_Glyph object. 0~in case of */ /* failure. */ /* */ - /* anode :: Used to return the address of of the corresponding */ + /* anode :: Used to return the address of the corresponding */ /* cache node after incrementing its reference count */ /* (see note below). */ /* */ @@ -957,7 +942,7 @@ FT_BEGIN_HEADER /* <Output> */ /* sbit :: A handle to a small bitmap descriptor. */ /* */ - /* anode :: Used to return the address of of the corresponding cache */ + /* anode :: Used to return the address of the corresponding cache */ /* node after incrementing its reference count (see note */ /* below). */ /* */ @@ -1012,7 +997,7 @@ FT_BEGIN_HEADER /* <Output> */ /* sbit :: A handle to a small bitmap descriptor. */ /* */ - /* anode :: Used to return the address of of the corresponding */ + /* anode :: Used to return the address of the corresponding */ /* cache node after incrementing its reference count */ /* (see note below). */ /* */ @@ -1051,7 +1036,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCACHE_H__ */ +#endif /* FTCACHE_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftchapters.h b/src/3rdparty/freetype/include/freetype/ftchapters.h index ab4389530e..51257bb7ca 100644 --- a/src/3rdparty/freetype/include/freetype/ftchapters.h +++ b/src/3rdparty/freetype/include/freetype/ftchapters.h @@ -76,7 +76,11 @@ /* <Sections> */ /* auto_hinter */ /* cff_driver */ +/* t1_cid_driver */ /* tt_driver */ +/* pcf_driver */ +/* properties */ +/* parameter_tags */ /* */ /***************************************************************************/ diff --git a/src/3rdparty/freetype/include/freetype/ftcid.h b/src/3rdparty/freetype/include/freetype/ftcid.h index 05741c85b7..5e9100a67c 100644 --- a/src/3rdparty/freetype/include/freetype/ftcid.h +++ b/src/3rdparty/freetype/include/freetype/ftcid.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing CID font information (specification). */ /* */ -/* Copyright 2007-2015 by */ +/* Copyright 2007-2018 by */ /* Dereg Clegg and Michael Toftdal. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTCID_H__ -#define __FTCID_H__ +#ifndef FTCID_H_ +#define FTCID_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -87,7 +87,7 @@ FT_BEGIN_HEADER FT_Get_CID_Registry_Ordering_Supplement( FT_Face face, const char* *registry, const char* *ordering, - FT_Int *supplement); + FT_Int *supplement ); /********************************************************************** @@ -97,8 +97,8 @@ FT_BEGIN_HEADER * * @description: * Retrieve the type of the input face, CID keyed or not. In - * constrast to the @FT_IS_CID_KEYED macro this function returns - * successfully also for CID-keyed fonts in an SNFT wrapper. + * contrast to the @FT_IS_CID_KEYED macro this function returns + * successfully also for CID-keyed fonts in an SFNT wrapper. * * @input: * face :: @@ -162,7 +162,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCID_H__ */ +#endif /* FTCID_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftdriver.h b/src/3rdparty/freetype/include/freetype/ftdriver.h new file mode 100644 index 0000000000..e90475b2af --- /dev/null +++ b/src/3rdparty/freetype/include/freetype/ftdriver.h @@ -0,0 +1,1225 @@ +/***************************************************************************/ +/* */ +/* ftdriver.h */ +/* */ +/* FreeType API for controlling driver modules (specification only). */ +/* */ +/* Copyright 2017-2018 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef FTDRIVER_H_ +#define FTDRIVER_H_ + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_PARAMETER_TAGS_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /************************************************************************** + * + * @section: + * auto_hinter + * + * @title: + * The auto-hinter + * + * @abstract: + * Controlling the auto-hinting module. + * + * @description: + * While FreeType's auto-hinter doesn't expose API functions by itself, + * it is possible to control its behaviour with @FT_Property_Set and + * @FT_Property_Get. The following lists the available properties + * together with the necessary macros and structures. + * + * Note that the auto-hinter's module name is `autofitter' for + * historical reasons. + * + * Available properties are @increase-x-height, @no-stem-darkening + * (experimental), @darkening-parameters (experimental), @warping + * (experimental), @glyph-to-script-map (experimental), @fallback-script + * (experimental), and @default-script (experimental), as documented in + * the @properties section. + * + */ + + + /************************************************************************** + * + * @section: + * cff_driver + * + * @title: + * The CFF driver + * + * @abstract: + * Controlling the CFF driver module. + * + * @description: + * While FreeType's CFF driver doesn't expose API functions by itself, + * it is possible to control its behaviour with @FT_Property_Set and + * @FT_Property_Get. + * + * The CFF driver's module name is `cff'. + * + * Available properties are @hinting-engine, @no-stem-darkening, + * @darkening-parameters, and @random-seed, as documented in the + * @properties section. + * + * + * *Hinting* *and* *antialiasing* *principles* *of* *the* *new* *engine* + * + * The rasterizer is positioning horizontal features (e.g., ascender + * height & x-height, or crossbars) on the pixel grid and minimizing the + * amount of antialiasing applied to them, while placing vertical + * features (vertical stems) on the pixel grid without hinting, thus + * representing the stem position and weight accurately. Sometimes the + * vertical stems may be only partially black. In this context, + * `antialiasing' means that stems are not positioned exactly on pixel + * borders, causing a fuzzy appearance. + * + * There are two principles behind this approach. + * + * 1) No hinting in the horizontal direction: Unlike `superhinted' + * TrueType, which changes glyph widths to accommodate regular + * inter-glyph spacing, Adobe's approach is `faithful to the design' in + * representing both the glyph width and the inter-glyph spacing + * designed for the font. This makes the screen display as close as it + * can be to the result one would get with infinite resolution, while + * preserving what is considered the key characteristics of each glyph. + * Note that the distances between unhinted and grid-fitted positions at + * small sizes are comparable to kerning values and thus would be + * noticeable (and distracting) while reading if hinting were applied. + * + * One of the reasons to not hint horizontally is antialiasing for LCD + * screens: The pixel geometry of modern displays supplies three + * vertical subpixels as the eye moves horizontally across each visible + * pixel. On devices where we can be certain this characteristic is + * present a rasterizer can take advantage of the subpixels to add + * increments of weight. In Western writing systems this turns out to + * be the more critical direction anyway; the weights and spacing of + * vertical stems (see above) are central to Armenian, Cyrillic, Greek, + * and Latin type designs. Even when the rasterizer uses greyscale + * antialiasing instead of color (a necessary compromise when one + * doesn't know the screen characteristics), the unhinted vertical + * features preserve the design's weight and spacing much better than + * aliased type would. + * + * 2) Alignment in the vertical direction: Weights and spacing along the + * y~axis are less critical; what is much more important is the visual + * alignment of related features (like cap-height and x-height). The + * sense of alignment for these is enhanced by the sharpness of grid-fit + * edges, while the cruder vertical resolution (full pixels instead of + * 1/3 pixels) is less of a problem. + * + * On the technical side, horizontal alignment zones for ascender, + * x-height, and other important height values (traditionally called + * `blue zones') as defined in the font are positioned independently, + * each being rounded to the nearest pixel edge, taking care of + * overshoot suppression at small sizes, stem darkening, and scaling. + * + * Hstems (this is, hint values defined in the font to help align + * horizontal features) that fall within a blue zone are said to be + * `captured' and are aligned to that zone. Uncaptured stems are moved + * in one of four ways, top edge up or down, bottom edge up or down. + * Unless there are conflicting hstems, the smallest movement is taken + * to minimize distortion. + * + */ + + + /************************************************************************** + * + * @section: + * pcf_driver + * + * @title: + * The PCF driver + * + * @abstract: + * Controlling the PCF driver module. + * + * @description: + * While FreeType's PCF driver doesn't expose API functions by itself, + * it is possible to control its behaviour with @FT_Property_Set and + * @FT_Property_Get. Right now, there is a single property + * @no-long-family-names available if FreeType is compiled with + * PCF_CONFIG_OPTION_LONG_FAMILY_NAMES. + * + * The PCF driver's module name is `pcf'. + * + */ + + + /************************************************************************** + * + * @section: + * t1_cid_driver + * + * @title: + * The Type 1 and CID drivers + * + * @abstract: + * Controlling the Type~1 and CID driver modules. + * + * @description: + * It is possible to control the behaviour of FreeType's Type~1 and + * Type~1 CID drivers with @FT_Property_Set and @FT_Property_Get. + * + * Behind the scenes, both drivers use the Adobe CFF engine for hinting; + * however, the used properties must be specified separately. + * + * The Type~1 driver's module name is `type1'; the CID driver's module + * name is `t1cid'. + * + * Available properties are @hinting-engine, @no-stem-darkening, + * @darkening-parameters, and @random-seed, as documented in the + * @properties section. + * + * Please see the @cff_driver section for more details on the new + * hinting engine. + * + */ + + + /************************************************************************** + * + * @section: + * tt_driver + * + * @title: + * The TrueType driver + * + * @abstract: + * Controlling the TrueType driver module. + * + * @description: + * While FreeType's TrueType driver doesn't expose API functions by + * itself, it is possible to control its behaviour with @FT_Property_Set + * and @FT_Property_Get. The following lists the available properties + * together with the necessary macros and structures. + * + * The TrueType driver's module name is `truetype'. + * + * A single property @interpreter-version is available, as documented in + * the @properties section. + * + * We start with a list of definitions, kindly provided by Greg + * Hitchcock. + * + * _Bi-Level_ _Rendering_ + * + * Monochromatic rendering, exclusively used in the early days of + * TrueType by both Apple and Microsoft. Microsoft's GDI interface + * supported hinting of the right-side bearing point, such that the + * advance width could be non-linear. Most often this was done to + * achieve some level of glyph symmetry. To enable reasonable + * performance (e.g., not having to run hinting on all glyphs just to + * get the widths) there was a bit in the head table indicating if the + * side bearing was hinted, and additional tables, `hdmx' and `LTSH', to + * cache hinting widths across multiple sizes and device aspect ratios. + * + * _Font_ _Smoothing_ + * + * Microsoft's GDI implementation of anti-aliasing. Not traditional + * anti-aliasing as the outlines were hinted before the sampling. The + * widths matched the bi-level rendering. + * + * _ClearType_ _Rendering_ + * + * Technique that uses physical subpixels to improve rendering on LCD + * (and other) displays. Because of the higher resolution, many methods + * of improving symmetry in glyphs through hinting the right-side + * bearing were no longer necessary. This lead to what GDI calls + * `natural widths' ClearType, see + * http://www.beatstamm.com/typography/RTRCh4.htm#Sec21. Since hinting + * has extra resolution, most non-linearity went away, but it is still + * possible for hints to change the advance widths in this mode. + * + * _ClearType_ _Compatible_ _Widths_ + * + * One of the earliest challenges with ClearType was allowing the + * implementation in GDI to be selected without requiring all UI and + * documents to reflow. To address this, a compatible method of + * rendering ClearType was added where the font hints are executed once + * to determine the width in bi-level rendering, and then re-run in + * ClearType, with the difference in widths being absorbed in the font + * hints for ClearType (mostly in the white space of hints); see + * http://www.beatstamm.com/typography/RTRCh4.htm#Sec20. Somewhat by + * definition, compatible width ClearType allows for non-linear widths, + * but only when the bi-level version has non-linear widths. + * + * _ClearType_ _Subpixel_ _Positioning_ + * + * One of the nice benefits of ClearType is the ability to more crisply + * display fractional widths; unfortunately, the GDI model of integer + * bitmaps did not support this. However, the WPF and Direct Write + * frameworks do support fractional widths. DWrite calls this `natural + * mode', not to be confused with GDI's `natural widths'. Subpixel + * positioning, in the current implementation of Direct Write, + * unfortunately does not support hinted advance widths, see + * http://www.beatstamm.com/typography/RTRCh4.htm#Sec22. Note that the + * TrueType interpreter fully allows the advance width to be adjusted in + * this mode, just the DWrite client will ignore those changes. + * + * _ClearType_ _Backward_ _Compatibility_ + * + * This is a set of exceptions made in the TrueType interpreter to + * minimize hinting techniques that were problematic with the extra + * resolution of ClearType; see + * http://www.beatstamm.com/typography/RTRCh4.htm#Sec1 and + * https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx. + * This technique is not to be confused with ClearType compatible + * widths. ClearType backward compatibility has no direct impact on + * changing advance widths, but there might be an indirect impact on + * disabling some deltas. This could be worked around in backward + * compatibility mode. + * + * _Native_ _ClearType_ _Mode_ + * + * (Not to be confused with `natural widths'.) This mode removes all + * the exceptions in the TrueType interpreter when running with + * ClearType. Any issues on widths would still apply, though. + * + */ + + + /************************************************************************** + * + * @section: + * properties + * + * @title: + * Driver properties + * + * @abstract: + * Controlling driver modules. + * + * @description: + * Driver modules can be controlled by setting and unsetting properties, + * using the functions @FT_Property_Set and @FT_Property_Get. This + * section documents the available properties, together with auxiliary + * macros and structures. + * + */ + + + /************************************************************************** + * + * @enum: + * FT_HINTING_XXX + * + * @description: + * A list of constants used for the @hinting-engine property to + * select the hinting engine for CFF, Type~1, and CID fonts. + * + * @values: + * FT_HINTING_FREETYPE :: + * Use the old FreeType hinting engine. + * + * FT_HINTING_ADOBE :: + * Use the hinting engine contributed by Adobe. + * + * @since: + * 2.9 + * + */ +#define FT_HINTING_FREETYPE 0 +#define FT_HINTING_ADOBE 1 + + /* these constants (introduced in 2.4.12) are deprecated */ +#define FT_CFF_HINTING_FREETYPE FT_HINTING_FREETYPE +#define FT_CFF_HINTING_ADOBE FT_HINTING_ADOBE + + + /************************************************************************** + * + * @property: + * hinting-engine + * + * @description: + * Thanks to Adobe, which contributed a new hinting (and parsing) + * engine, an application can select between `freetype' and `adobe' if + * compiled with CFF_CONFIG_OPTION_OLD_ENGINE. If this configuration + * macro isn't defined, `hinting-engine' does nothing. + * + * The same holds for the Type~1 and CID modules if compiled with + * T1_CONFIG_OPTION_OLD_ENGINE. + * + * For the `cff' module, the default engine is `freetype' if + * CFF_CONFIG_OPTION_OLD_ENGINE is defined, and `adobe' otherwise. + * + * For both the `type1' and `t1cid' modules, the default engine is + * `freetype' if T1_CONFIG_OPTION_OLD_ENGINE is defined, and `adobe' + * otherwise. + * + * The following example code demonstrates how to select Adobe's hinting + * engine for the `cff' module (omitting the error handling). + * + * { + * FT_Library library; + * FT_UInt hinting_engine = FT_CFF_HINTING_ADOBE; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "cff", + * "hinting-engine", &hinting_engine ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * This property can be set via the `FREETYPE_PROPERTIES' environment + * variable (using values `adobe' or `freetype'). + * + * @since: + * 2.4.12 (for `cff' module) + * + * 2.9 (for `type1' and `t1cid' modules) + * + */ + + + /************************************************************************** + * + * @property: + * no-stem-darkening + * + * @description: + * All glyphs that pass through the auto-hinter will be emboldened + * unless this property is set to TRUE. The same is true for the CFF, + * Type~1, and CID font modules if the `Adobe' engine is selected (which + * is the default). + * + * Stem darkening emboldens glyphs at smaller sizes to make them more + * readable on common low-DPI screens when using linear alpha blending + * and gamma correction, see @FT_Render_Glyph. When not using linear + * alpha blending and gamma correction, glyphs will appear heavy and + * fuzzy! + * + * Gamma correction essentially lightens fonts since shades of grey are + * shifted to higher pixel values (=~higher brightness) to match the + * original intention to the reality of our screens. The side-effect is + * that glyphs `thin out'. Mac OS~X and Adobe's proprietary font + * rendering library implement a counter-measure: stem darkening at + * smaller sizes where shades of gray dominate. By emboldening a glyph + * slightly in relation to its pixel size, individual pixels get higher + * coverage of filled-in outlines and are therefore `blacker'. This + * counteracts the `thinning out' of glyphs, making text remain readable + * at smaller sizes. + * + * By default, the Adobe engines for CFF, Type~1, and CID fonts darken + * stems at smaller sizes, regardless of hinting, to enhance contrast. + * Setting this property, stem darkening gets switched off. + * + * For the auto-hinter, stem-darkening is experimental currently and + * thus switched off by default (this is, `no-stem-darkening' is set to + * TRUE by default). Total consistency with the CFF driver is not + * achieved right now because the emboldening method differs and glyphs + * must be scaled down on the Y-axis to keep outline points inside their + * precomputed blue zones. The smaller the size (especially 9ppem and + * down), the higher the loss of emboldening versus the CFF driver. + * + * Note that stem darkening is never applied if @FT_LOAD_NO_SCALE is + * set. + * + * { + * FT_Library library; + * FT_Bool no_stem_darkening = TRUE; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "cff", + * "no-stem-darkening", &no_stem_darkening ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * This property can be set via the `FREETYPE_PROPERTIES' environment + * variable (using values 1 and 0 for `on' and `off', respectively). + * It can also be set per face using @FT_Face_Properties with + * @FT_PARAM_TAG_STEM_DARKENING. + * + * @since: + * 2.4.12 (for `cff' module) + * + * 2.6.2 (for `autofitter' module) + * + * 2.9 (for `type1' and `t1cid' modules) + * + */ + + + /************************************************************************** + * + * @property: + * darkening-parameters + * + * @description: + * By default, the Adobe hinting engine, as used by the CFF, Type~1, and + * CID font drivers, darkens stems as follows (if the + * `no-stem-darkening' property isn't set): + * + * { + * stem width <= 0.5px: darkening amount = 0.4px + * stem width = 1px: darkening amount = 0.275px + * stem width = 1.667px: darkening amount = 0.275px + * stem width >= 2.333px: darkening amount = 0px + * } + * + * and piecewise linear in-between. At configuration time, these four + * control points can be set with the macro + * `CFF_CONFIG_OPTION_DARKENING_PARAMETERS'; the CFF, Type~1, and CID + * drivers share these values. At runtime, the control points can be + * changed using the `darkening-parameters' property, as the following + * example demonstrates for the Type~1 driver. + * + * { + * FT_Library library; + * FT_Int darken_params[8] = { 500, 300, // x1, y1 + * 1000, 200, // x2, y2 + * 1500, 100, // x3, y3 + * 2000, 0 }; // x4, y4 + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "type1", + * "darkening-parameters", darken_params ); + * } + * + * The x~values give the stem width, and the y~values the darkening + * amount. The unit is 1000th of pixels. All coordinate values must be + * positive; the x~values must be monotonically increasing; the + * y~values must be monotonically decreasing and smaller than or + * equal to 500 (corresponding to half a pixel); the slope of each + * linear piece must be shallower than -1 (e.g., -.4). + * + * The auto-hinter provides this property, too, as an experimental + * feature. See @no-stem-darkening for more. + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * This property can be set via the `FREETYPE_PROPERTIES' environment + * variable, using eight comma-separated integers without spaces. Here + * the above example, using `\' to break the line for readability. + * + * { + * FREETYPE_PROPERTIES=\ + * type1:darkening-parameters=500,300,1000,200,1500,100,2000,0 + * } + * + * @since: + * 2.5.1 (for `cff' module) + * + * 2.6.2 (for `autofitter' module) + * + * 2.9 (for `type1' and `t1cid' modules) + * + */ + + + /************************************************************************** + * + * @property: + * random-seed + * + * @description: + * By default, the seed value for the CFF `random' operator and the + * similar `0 28 callothersubr pop' command for the Type~1 and CID + * drivers is set to a random value. However, mainly for debugging + * purposes, it is often necessary to use a known value as a seed so + * that the pseudo-random number sequences generated by `random' are + * repeatable. + * + * The `random-seed' property does that. Its argument is a signed 32bit + * integer; if the value is zero or negative, the seed given by the + * `intitialRandomSeed' private DICT operator in a CFF file gets used + * (or a default value if there is no such operator). If the value is + * positive, use it instead of `initialRandomSeed', which is + * consequently ignored. + * + * @note: + * This property can be set via the `FREETYPE_PROPERTIES' environment + * variable. It can also be set per face using @FT_Face_Properties with + * @FT_PARAM_TAG_RANDOM_SEED. + * + * @since: + * 2.8 (for `cff' module) + * + * 2.9 (for `type1' and `t1cid' modules) + * + */ + + + /************************************************************************** + * + * @property: + * no-long-family-names + * + * @description: + * If PCF_CONFIG_OPTION_LONG_FAMILY_NAMES is active while compiling + * FreeType, the PCF driver constructs long family names. + * + * There are many PCF fonts just called `Fixed' which look completely + * different, and which have nothing to do with each other. When + * selecting `Fixed' in KDE or Gnome one gets results that appear rather + * random, the style changes often if one changes the size and one + * cannot select some fonts at all. The improve this situation, the PCF + * module prepends the foundry name (plus a space) to the family name. + * It also checks whether there are `wide' characters; all put together, + * family names like `Sony Fixed' or `Misc Fixed Wide' are constructed. + * + * If `no-long-family-names' is set, this feature gets switched off. + * + * { + * FT_Library library; + * FT_Bool no_long_family_names = TRUE; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "pcf", + * "no-long-family-names", + * &no_long_family_names ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * This property can be set via the `FREETYPE_PROPERTIES' environment + * variable (using values 1 and 0 for `on' and `off', respectively). + * + * @since: + * 2.8 + */ + + + /************************************************************************** + * + * @enum: + * TT_INTERPRETER_VERSION_XXX + * + * @description: + * A list of constants used for the @interpreter-version property to + * select the hinting engine for Truetype fonts. + * + * The numeric value in the constant names represents the version + * number as returned by the `GETINFO' bytecode instruction. + * + * @values: + * TT_INTERPRETER_VERSION_35 :: + * Version~35 corresponds to MS rasterizer v.1.7 as used e.g. in + * Windows~98; only grayscale and B/W rasterizing is supported. + * + * TT_INTERPRETER_VERSION_38 :: + * Version~38 corresponds to MS rasterizer v.1.9; it is roughly + * equivalent to the hinting provided by DirectWrite ClearType (as can + * be found, for example, in the Internet Explorer~9 running on + * Windows~7). It is used in FreeType to select the `Infinality' + * subpixel hinting code. The code may be removed in a future + * version. + * + * TT_INTERPRETER_VERSION_40 :: + * Version~40 corresponds to MS rasterizer v.2.1; it is roughly + * equivalent to the hinting provided by DirectWrite ClearType (as can + * be found, for example, in Microsoft's Edge Browser on Windows~10). + * It is used in FreeType to select the `minimal' subpixel hinting + * code, a stripped-down and higher performance version of the + * `Infinality' code. + * + * @note: + * This property controls the behaviour of the bytecode interpreter + * and thus how outlines get hinted. It does *not* control how glyph + * get rasterized! In particular, it does not control subpixel color + * filtering. + * + * If FreeType has not been compiled with the configuration option + * TT_CONFIG_OPTION_SUBPIXEL_HINTING, selecting version~38 or~40 causes + * an `FT_Err_Unimplemented_Feature' error. + * + * Depending on the graphics framework, Microsoft uses different + * bytecode and rendering engines. As a consequence, the version + * numbers returned by a call to the `GETINFO' bytecode instruction are + * more convoluted than desired. + * + * Here are two tables that try to shed some light on the possible + * values for the MS rasterizer engine, together with the additional + * features introduced by it. + * + * { + * GETINFO framework version feature + * ------------------------------------------------------------------- + * 3 GDI (Win 3.1), v1.0 16-bit, first version + * TrueImage + * 33 GDI (Win NT 3.1), v1.5 32-bit + * HP Laserjet + * 34 GDI (Win 95) v1.6 font smoothing, + * new SCANTYPE opcode + * 35 GDI (Win 98/2000) v1.7 (UN)SCALED_COMPONENT_OFFSET + * bits in composite glyphs + * 36 MGDI (Win CE 2) v1.6+ classic ClearType + * 37 GDI (XP and later), v1.8 ClearType + * GDI+ old (before Vista) + * 38 GDI+ old (Vista, Win 7), v1.9 subpixel ClearType, + * WPF Y-direction ClearType, + * additional error checking + * 39 DWrite (before Win 8) v2.0 subpixel ClearType flags + * in GETINFO opcode, + * bug fixes + * 40 GDI+ (after Win 7), v2.1 Y-direction ClearType flag + * DWrite (Win 8) in GETINFO opcode, + * Gray ClearType + * } + * + * The `version' field gives a rough orientation only, since some + * applications provided certain features much earlier (as an example, + * Microsoft Reader used subpixel and Y-direction ClearType already in + * Windows 2000). Similarly, updates to a given framework might include + * improved hinting support. + * + * { + * version sampling rendering comment + * x y x y + * -------------------------------------------------------------- + * v1.0 normal normal B/W B/W bi-level + * v1.6 high high gray gray grayscale + * v1.8 high normal color-filter B/W (GDI) ClearType + * v1.9 high high color-filter gray Color ClearType + * v2.1 high normal gray B/W Gray ClearType + * v2.1 high high gray gray Gray ClearType + * } + * + * Color and Gray ClearType are the two available variants of + * `Y-direction ClearType', meaning grayscale rasterization along the + * Y-direction; the name used in the TrueType specification for this + * feature is `symmetric smoothing'. `Classic ClearType' is the + * original algorithm used before introducing a modified version in + * Win~XP. Another name for v1.6's grayscale rendering is `font + * smoothing', and `Color ClearType' is sometimes also called `DWrite + * ClearType'. To differentiate between today's Color ClearType and the + * earlier ClearType variant with B/W rendering along the vertical axis, + * the latter is sometimes called `GDI ClearType'. + * + * `Normal' and `high' sampling describe the (virtual) resolution to + * access the rasterized outline after the hinting process. `Normal' + * means 1 sample per grid line (i.e., B/W). In the current Microsoft + * implementation, `high' means an extra virtual resolution of 16x16 (or + * 16x1) grid lines per pixel for bytecode instructions like `MIRP'. + * After hinting, these 16 grid lines are mapped to 6x5 (or 6x1) grid + * lines for color filtering if Color ClearType is activated. + * + * Note that `Gray ClearType' is essentially the same as v1.6's + * grayscale rendering. However, the GETINFO instruction handles it + * differently: v1.6 returns bit~12 (hinting for grayscale), while v2.1 + * returns bits~13 (hinting for ClearType), 18 (symmetrical smoothing), + * and~19 (Gray ClearType). Also, this mode respects bits 2 and~3 for + * the version~1 gasp table exclusively (like Color ClearType), while + * v1.6 only respects the values of version~0 (bits 0 and~1). + * + * Keep in mind that the features of the above interpreter versions + * might not map exactly to FreeType features or behavior because it is + * a fundamentally different library with different internals. + * + */ +#define TT_INTERPRETER_VERSION_35 35 +#define TT_INTERPRETER_VERSION_38 38 +#define TT_INTERPRETER_VERSION_40 40 + + + /************************************************************************** + * + * @property: + * interpreter-version + * + * @description: + * Currently, three versions are available, two representing the + * bytecode interpreter with subpixel hinting support (old `Infinality' + * code and new stripped-down and higher performance `minimal' code) and + * one without, respectively. The default is subpixel support if + * TT_CONFIG_OPTION_SUBPIXEL_HINTING is defined, and no subpixel support + * otherwise (since it isn't available then). + * + * If subpixel hinting is on, many TrueType bytecode instructions behave + * differently compared to B/W or grayscale rendering (except if `native + * ClearType' is selected by the font). Microsoft's main idea is to + * render at a much increased horizontal resolution, then sampling down + * the created output to subpixel precision. However, many older fonts + * are not suited to this and must be specially taken care of by + * applying (hardcoded) tweaks in Microsoft's interpreter. + * + * Details on subpixel hinting and some of the necessary tweaks can be + * found in Greg Hitchcock's whitepaper at + * `https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx'. + * Note that FreeType currently doesn't really `subpixel hint' (6x1, 6x2, + * or 6x5 supersampling) like discussed in the paper. Depending on the + * chosen interpreter, it simply ignores instructions on vertical stems + * to arrive at very similar results. + * + * The following example code demonstrates how to deactivate subpixel + * hinting (omitting the error handling). + * + * { + * FT_Library library; + * FT_Face face; + * FT_UInt interpreter_version = TT_INTERPRETER_VERSION_35; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "truetype", + * "interpreter-version", + * &interpreter_version ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * This property can be set via the `FREETYPE_PROPERTIES' environment + * variable (using values `35', `38', or `40'). + * + * @since: + * 2.5 + */ + + + /************************************************************************** + * + * @property: + * glyph-to-script-map + * + * @description: + * *Experimental* *only* + * + * The auto-hinter provides various script modules to hint glyphs. + * Examples of supported scripts are Latin or CJK. Before a glyph is + * auto-hinted, the Unicode character map of the font gets examined, and + * the script is then determined based on Unicode character ranges, see + * below. + * + * OpenType fonts, however, often provide much more glyphs than + * character codes (small caps, superscripts, ligatures, swashes, etc.), + * to be controlled by so-called `features'. Handling OpenType features + * can be quite complicated and thus needs a separate library on top of + * FreeType. + * + * The mapping between glyph indices and scripts (in the auto-hinter + * sense, see the @FT_AUTOHINTER_SCRIPT_XXX values) is stored as an + * array with `num_glyphs' elements, as found in the font's @FT_Face + * structure. The `glyph-to-script-map' property returns a pointer to + * this array, which can be modified as needed. Note that the + * modification should happen before the first glyph gets processed by + * the auto-hinter so that the global analysis of the font shapes + * actually uses the modified mapping. + * + * The following example code demonstrates how to access it (omitting + * the error handling). + * + * { + * FT_Library library; + * FT_Face face; + * FT_Prop_GlyphToScriptMap prop; + * + * + * FT_Init_FreeType( &library ); + * FT_New_Face( library, "foo.ttf", 0, &face ); + * + * prop.face = face; + * + * FT_Property_Get( library, "autofitter", + * "glyph-to-script-map", &prop ); + * + * // adjust `prop.map' as needed right here + * + * FT_Load_Glyph( face, ..., FT_LOAD_FORCE_AUTOHINT ); + * } + * + * @since: + * 2.4.11 + * + */ + + + /************************************************************************** + * + * @enum: + * FT_AUTOHINTER_SCRIPT_XXX + * + * @description: + * *Experimental* *only* + * + * A list of constants used for the @glyph-to-script-map property to + * specify the script submodule the auto-hinter should use for hinting a + * particular glyph. + * + * @values: + * FT_AUTOHINTER_SCRIPT_NONE :: + * Don't auto-hint this glyph. + * + * FT_AUTOHINTER_SCRIPT_LATIN :: + * Apply the latin auto-hinter. For the auto-hinter, `latin' is a + * very broad term, including Cyrillic and Greek also since characters + * from those scripts share the same design constraints. + * + * By default, characters from the following Unicode ranges are + * assigned to this submodule. + * + * { + * U+0020 - U+007F // Basic Latin (no control characters) + * U+00A0 - U+00FF // Latin-1 Supplement (no control characters) + * U+0100 - U+017F // Latin Extended-A + * U+0180 - U+024F // Latin Extended-B + * U+0250 - U+02AF // IPA Extensions + * U+02B0 - U+02FF // Spacing Modifier Letters + * U+0300 - U+036F // Combining Diacritical Marks + * U+0370 - U+03FF // Greek and Coptic + * U+0400 - U+04FF // Cyrillic + * U+0500 - U+052F // Cyrillic Supplement + * U+1D00 - U+1D7F // Phonetic Extensions + * U+1D80 - U+1DBF // Phonetic Extensions Supplement + * U+1DC0 - U+1DFF // Combining Diacritical Marks Supplement + * U+1E00 - U+1EFF // Latin Extended Additional + * U+1F00 - U+1FFF // Greek Extended + * U+2000 - U+206F // General Punctuation + * U+2070 - U+209F // Superscripts and Subscripts + * U+20A0 - U+20CF // Currency Symbols + * U+2150 - U+218F // Number Forms + * U+2460 - U+24FF // Enclosed Alphanumerics + * U+2C60 - U+2C7F // Latin Extended-C + * U+2DE0 - U+2DFF // Cyrillic Extended-A + * U+2E00 - U+2E7F // Supplemental Punctuation + * U+A640 - U+A69F // Cyrillic Extended-B + * U+A720 - U+A7FF // Latin Extended-D + * U+FB00 - U+FB06 // Alphab. Present. Forms (Latin Ligatures) + * U+1D400 - U+1D7FF // Mathematical Alphanumeric Symbols + * U+1F100 - U+1F1FF // Enclosed Alphanumeric Supplement + * } + * + * FT_AUTOHINTER_SCRIPT_CJK :: + * Apply the CJK auto-hinter, covering Chinese, Japanese, Korean, old + * Vietnamese, and some other scripts. + * + * By default, characters from the following Unicode ranges are + * assigned to this submodule. + * + * { + * U+1100 - U+11FF // Hangul Jamo + * U+2E80 - U+2EFF // CJK Radicals Supplement + * U+2F00 - U+2FDF // Kangxi Radicals + * U+2FF0 - U+2FFF // Ideographic Description Characters + * U+3000 - U+303F // CJK Symbols and Punctuation + * U+3040 - U+309F // Hiragana + * U+30A0 - U+30FF // Katakana + * U+3100 - U+312F // Bopomofo + * U+3130 - U+318F // Hangul Compatibility Jamo + * U+3190 - U+319F // Kanbun + * U+31A0 - U+31BF // Bopomofo Extended + * U+31C0 - U+31EF // CJK Strokes + * U+31F0 - U+31FF // Katakana Phonetic Extensions + * U+3200 - U+32FF // Enclosed CJK Letters and Months + * U+3300 - U+33FF // CJK Compatibility + * U+3400 - U+4DBF // CJK Unified Ideographs Extension A + * U+4DC0 - U+4DFF // Yijing Hexagram Symbols + * U+4E00 - U+9FFF // CJK Unified Ideographs + * U+A960 - U+A97F // Hangul Jamo Extended-A + * U+AC00 - U+D7AF // Hangul Syllables + * U+D7B0 - U+D7FF // Hangul Jamo Extended-B + * U+F900 - U+FAFF // CJK Compatibility Ideographs + * U+FE10 - U+FE1F // Vertical forms + * U+FE30 - U+FE4F // CJK Compatibility Forms + * U+FF00 - U+FFEF // Halfwidth and Fullwidth Forms + * U+1B000 - U+1B0FF // Kana Supplement + * U+1D300 - U+1D35F // Tai Xuan Hing Symbols + * U+1F200 - U+1F2FF // Enclosed Ideographic Supplement + * U+20000 - U+2A6DF // CJK Unified Ideographs Extension B + * U+2A700 - U+2B73F // CJK Unified Ideographs Extension C + * U+2B740 - U+2B81F // CJK Unified Ideographs Extension D + * U+2F800 - U+2FA1F // CJK Compatibility Ideographs Supplement + * } + * + * FT_AUTOHINTER_SCRIPT_INDIC :: + * Apply the indic auto-hinter, covering all major scripts from the + * Indian sub-continent and some other related scripts like Thai, Lao, + * or Tibetan. + * + * By default, characters from the following Unicode ranges are + * assigned to this submodule. + * + * { + * U+0900 - U+0DFF // Indic Range + * U+0F00 - U+0FFF // Tibetan + * U+1900 - U+194F // Limbu + * U+1B80 - U+1BBF // Sundanese + * U+A800 - U+A82F // Syloti Nagri + * U+ABC0 - U+ABFF // Meetei Mayek + * U+11800 - U+118DF // Sharada + * } + * + * Note that currently Indic support is rudimentary only, missing blue + * zone support. + * + * @since: + * 2.4.11 + * + */ +#define FT_AUTOHINTER_SCRIPT_NONE 0 +#define FT_AUTOHINTER_SCRIPT_LATIN 1 +#define FT_AUTOHINTER_SCRIPT_CJK 2 +#define FT_AUTOHINTER_SCRIPT_INDIC 3 + + + /************************************************************************** + * + * @struct: + * FT_Prop_GlyphToScriptMap + * + * @description: + * *Experimental* *only* + * + * The data exchange structure for the @glyph-to-script-map property. + * + * @since: + * 2.4.11 + * + */ + typedef struct FT_Prop_GlyphToScriptMap_ + { + FT_Face face; + FT_UShort* map; + + } FT_Prop_GlyphToScriptMap; + + + /************************************************************************** + * + * @property: + * fallback-script + * + * @description: + * *Experimental* *only* + * + * If no auto-hinter script module can be assigned to a glyph, a + * fallback script gets assigned to it (see also the + * @glyph-to-script-map property). By default, this is + * @FT_AUTOHINTER_SCRIPT_CJK. Using the `fallback-script' property, + * this fallback value can be changed. + * + * { + * FT_Library library; + * FT_UInt fallback_script = FT_AUTOHINTER_SCRIPT_NONE; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "autofitter", + * "fallback-script", &fallback_script ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * It's important to use the right timing for changing this value: The + * creation of the glyph-to-script map that eventually uses the + * fallback script value gets triggered either by setting or reading a + * face-specific property like @glyph-to-script-map, or by auto-hinting + * any glyph from that face. In particular, if you have already created + * an @FT_Face structure but not loaded any glyph (using the + * auto-hinter), a change of the fallback script will affect this face. + * + * @since: + * 2.4.11 + * + */ + + + /************************************************************************** + * + * @property: + * default-script + * + * @description: + * *Experimental* *only* + * + * If FreeType gets compiled with FT_CONFIG_OPTION_USE_HARFBUZZ to make + * the HarfBuzz library access OpenType features for getting better + * glyph coverages, this property sets the (auto-fitter) script to be + * used for the default (OpenType) script data of a font's GSUB table. + * Features for the default script are intended for all scripts not + * explicitly handled in GSUB; an example is a `dlig' feature, + * containing the combination of the characters `T', `E', and `L' to + * form a `TEL' ligature. + * + * By default, this is @FT_AUTOHINTER_SCRIPT_LATIN. Using the + * `default-script' property, this default value can be changed. + * + * { + * FT_Library library; + * FT_UInt default_script = FT_AUTOHINTER_SCRIPT_NONE; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "autofitter", + * "default-script", &default_script ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * It's important to use the right timing for changing this value: The + * creation of the glyph-to-script map that eventually uses the + * default script value gets triggered either by setting or reading a + * face-specific property like @glyph-to-script-map, or by auto-hinting + * any glyph from that face. In particular, if you have already created + * an @FT_Face structure but not loaded any glyph (using the + * auto-hinter), a change of the default script will affect this face. + * + * @since: + * 2.5.3 + * + */ + + + /************************************************************************** + * + * @property: + * increase-x-height + * + * @description: + * For ppem values in the range 6~<= ppem <= `increase-x-height', round + * up the font's x~height much more often than normally. If the value + * is set to~0, which is the default, this feature is switched off. Use + * this property to improve the legibility of small font sizes if + * necessary. + * + * { + * FT_Library library; + * FT_Face face; + * FT_Prop_IncreaseXHeight prop; + * + * + * FT_Init_FreeType( &library ); + * FT_New_Face( library, "foo.ttf", 0, &face ); + * FT_Set_Char_Size( face, 10 * 64, 0, 72, 0 ); + * + * prop.face = face; + * prop.limit = 14; + * + * FT_Property_Set( library, "autofitter", + * "increase-x-height", &prop ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * Set this value right after calling @FT_Set_Char_Size, but before + * loading any glyph (using the auto-hinter). + * + * @since: + * 2.4.11 + * + */ + + + /************************************************************************** + * + * @struct: + * FT_Prop_IncreaseXHeight + * + * @description: + * The data exchange structure for the @increase-x-height property. + * + */ + typedef struct FT_Prop_IncreaseXHeight_ + { + FT_Face face; + FT_UInt limit; + + } FT_Prop_IncreaseXHeight; + + + /************************************************************************** + * + * @property: + * warping + * + * @description: + * *Experimental* *only* + * + * If FreeType gets compiled with option AF_CONFIG_OPTION_USE_WARPER to + * activate the warp hinting code in the auto-hinter, this property + * switches warping on and off. + * + * Warping only works in `normal' auto-hinting mode replacing it. + * The idea of the code is to slightly scale and shift a glyph along + * the non-hinted dimension (which is usually the horizontal axis) so + * that as much of its segments are aligned (more or less) to the grid. + * To find out a glyph's optimal scaling and shifting value, various + * parameter combinations are tried and scored. + * + * By default, warping is off. The example below shows how to switch on + * warping (omitting the error handling). + * + * { + * FT_Library library; + * FT_Bool warping = 1; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "autofitter", + * "warping", &warping ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * This property can be set via the `FREETYPE_PROPERTIES' environment + * variable (using values 1 and 0 for `on' and `off', respectively). + * + * The warping code can also change advance widths. Have a look at the + * `lsb_delta' and `rsb_delta' fields in the @FT_GlyphSlotRec structure + * for details on improving inter-glyph distances while rendering. + * + * Since warping is a global property of the auto-hinter it is best to + * change its value before rendering any face. Otherwise, you should + * reload all faces that get auto-hinted in `normal' hinting mode. + * + * @since: + * 2.6 + * + */ + + + /* */ + + +FT_END_HEADER + + +#endif /* FTDRIVER_H_ */ + + +/* END */ diff --git a/src/3rdparty/freetype/include/freetype/fterrdef.h b/src/3rdparty/freetype/include/freetype/fterrdef.h index d865da7127..8ffd346ca8 100644 --- a/src/3rdparty/freetype/include/freetype/fterrdef.h +++ b/src/3rdparty/freetype/include/freetype/fterrdef.h @@ -4,7 +4,7 @@ /* */ /* FreeType error codes (specification). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -231,6 +231,10 @@ "invalid PostScript (post) table format" ) FT_ERRORDEF_( Invalid_Post_Table, 0x9B, "invalid PostScript (post) table" ) + FT_ERRORDEF_( DEF_In_Glyf_Bytecode, 0x9C, + "found FDEF or IDEF opcode in glyf bytecode" ) + FT_ERRORDEF_( Missing_Bitmap, 0x9D, + "missing bitmap in strike" ) /* CFF, CID, and Type 1 errors */ @@ -243,7 +247,7 @@ FT_ERRORDEF_( No_Unicode_Glyph_Name, 0xA3, "no Unicode glyph name found" ) FT_ERRORDEF_( Glyph_Too_Big, 0xA4, - "glyph to big for hinting" ) + "glyph too big for hinting" ) /* BDF errors */ diff --git a/src/3rdparty/freetype/include/freetype/fterrors.h b/src/3rdparty/freetype/include/freetype/fterrors.h index 0507b9ad7d..f6ee5c24e2 100644 --- a/src/3rdparty/freetype/include/freetype/fterrors.h +++ b/src/3rdparty/freetype/include/freetype/fterrors.h @@ -4,7 +4,7 @@ /* */ /* FreeType error code handling (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -38,15 +38,15 @@ /* The configuration macro FT_CONFIG_OPTION_USE_MODULE_ERRORS can be */ /* defined in `ftoption.h' in order to make the higher byte indicate */ /* the module where the error has happened (this is not compatible */ - /* with standard builds of FreeType 2, however). See the file */ + /* with standard builds of FreeType~2, however). See the file */ /* `ftmoderr.h' for more details. */ /* */ /* *Error* *Message* *Strings* */ /* */ /* Error definitions are set up with special macros that allow client */ /* applications to build a table of error message strings. The */ - /* strings are not included in a normal build of FreeType 2 to */ - /* save space (most client applications do not use them). */ + /* strings are not included in a normal build of FreeType~2 to save */ + /* space (most client applications do not use them). */ /* */ /* To do so, you have to define the following macros before including */ /* this file. */ @@ -72,13 +72,13 @@ /* */ /* This macro ends the list. */ /* */ - /* Additionally, you have to undefine `__FTERRORS_H__' before */ - /* #including this file. */ + /* Additionally, you have to undefine `FTERRORS_H_' before #including */ + /* this file. */ /* */ /* Here is a simple example. */ /* */ /* { */ - /* #undef __FTERRORS_H__ */ + /* #undef FTERRORS_H_ */ /* #define FT_ERRORDEF( e, v, s ) { e, s }, */ /* #define FT_ERROR_START_LIST { */ /* #define FT_ERROR_END_LIST { 0, NULL } }; */ @@ -99,7 +99,17 @@ /* */ -#ifndef __FTERRORS_H__ + /* In previous FreeType versions we used `__FTERRORS_H__'. However, */ + /* using two successive underscores in a non-system symbol name */ + /* violates the C (and C++) standard, so it was changed to the */ + /* current form. In spite of this, we have to make */ + /* */ + /* #undefine __FTERRORS_H__ */ + /* */ + /* work for backward compatibility. */ + /* */ +#if !( defined( FTERRORS_H_ ) && defined ( __FTERRORS_H__ ) ) +#define FTERRORS_H_ #define __FTERRORS_H__ @@ -210,7 +220,7 @@ #undef FT_ERR_PREFIX #endif -#endif /* __FTERRORS_H__ */ +#endif /* !(FTERRORS_H_ && __FTERRORS_H__) */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftfntfmt.h b/src/3rdparty/freetype/include/freetype/ftfntfmt.h index 1f8ff28f10..cc86efac23 100644 --- a/src/3rdparty/freetype/include/freetype/ftfntfmt.h +++ b/src/3rdparty/freetype/include/freetype/ftfntfmt.h @@ -4,7 +4,7 @@ /* */ /* Support functions for font formats. */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTFNTFMT_H__ -#define __FTFNTFMT_H__ +#ifndef FTFNTFMT_H_ +#define FTFNTFMT_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -89,4 +89,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTFNTFMT_H__ */ +#endif /* FTFNTFMT_H_ */ + + +/* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftgasp.h b/src/3rdparty/freetype/include/freetype/ftgasp.h index 9a9b6321b3..fc1248ff48 100644 --- a/src/3rdparty/freetype/include/freetype/ftgasp.h +++ b/src/3rdparty/freetype/include/freetype/ftgasp.h @@ -4,7 +4,7 @@ /* */ /* Access of TrueType's `gasp' table (specification). */ /* */ -/* Copyright 2007-2015 by */ +/* Copyright 2007-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef _FT_GASP_H_ -#define _FT_GASP_H_ +#ifndef FTGASP_H_ +#define FTGASP_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -29,6 +29,9 @@ #endif +FT_BEGIN_HEADER + + /*************************************************************************** * * @section: @@ -92,8 +95,8 @@ #define FT_GASP_NO_TABLE -1 #define FT_GASP_DO_GRIDFIT 0x01 #define FT_GASP_DO_GRAY 0x02 +#define FT_GASP_SYMMETRIC_GRIDFIT 0x04 #define FT_GASP_SYMMETRIC_SMOOTHING 0x08 -#define FT_GASP_SYMMETRIC_GRIDFIT 0x10 /************************************************************************* @@ -102,17 +105,25 @@ * FT_Get_Gasp * * @description: - * Read the `gasp' table from a TrueType or OpenType font file and - * return the entry corresponding to a given character pixel size. + * For a TrueType or OpenType font file, return the rasterizer behaviour + * flags from the font's `gasp' table corresponding to a given + * character pixel size. * * @input: * face :: The source face handle. + * * ppem :: The vertical character pixel size. * * @return: * Bit flags (see @FT_GASP_XXX), or @FT_GASP_NO_TABLE if there is no * `gasp' table in the face. * + * @note: + * If you want to use the MM functionality of OpenType variation fonts + * (i.e., using @FT_Set_Var_Design_Coordinates and friends), call this + * function *after* setting an instance since the return values can + * change. + * * @since: * 2.3.0 */ @@ -123,7 +134,9 @@ /* */ -#endif /* _FT_GASP_H_ */ +FT_END_HEADER + +#endif /* FTGASP_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftglyph.h b/src/3rdparty/freetype/include/freetype/ftglyph.h index 803ad39621..5f3fc009cd 100644 --- a/src/3rdparty/freetype/include/freetype/ftglyph.h +++ b/src/3rdparty/freetype/include/freetype/ftglyph.h @@ -4,7 +4,7 @@ /* */ /* FreeType convenience functions to handle glyphs (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -29,8 +29,8 @@ /*************************************************************************/ -#ifndef __FTGLYPH_H__ -#define __FTGLYPH_H__ +#ifndef FTGLYPH_H_ +#define FTGLYPH_H_ #include <ft2build.h> @@ -231,6 +231,12 @@ FT_BEGIN_HEADER /* <Return> */ /* FreeType error code. 0~means success. */ /* */ + /* <Note> */ + /* Because `*aglyph->advance.x' and '*aglyph->advance.y' are 16.16 */ + /* fixed-point numbers, `slot->advance.x' and `slot->advance.y' */ + /* (which are in 26.6 fixed-point format) must be in the range */ + /* ]-32768;32768[. */ + /* */ FT_EXPORT( FT_Error ) FT_Get_Glyph( FT_GlyphSlot slot, FT_Glyph *aglyph ); @@ -341,10 +347,10 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* Return a glyph's `control box'. The control box encloses all the */ - /* outline's points, including Bézier control points. Though it */ + /* outline's points, including Bezier control points. Though it */ /* coincides with the exact bounding box for most glyphs, it can be */ /* slightly larger in some situations (like when rotating an outline */ - /* that contains Bézier outside arcs). */ + /* that contains Bezier outside arcs). */ /* */ /* Computing the control box is very fast, while getting the bounding */ /* box can take much more time as it needs to walk over all segments */ @@ -453,7 +459,7 @@ FT_BEGIN_HEADER /* */ /* */ /* // load glyph */ - /* error = FT_Load_Char( face, glyph_index, FT_LOAD_DEFAUT ); */ + /* error = FT_Load_Char( face, glyph_index, FT_LOAD_DEFAULT ); */ /* */ /* // extract glyph image */ /* error = FT_Get_Glyph( face->glyph, &glyph ); */ @@ -566,6 +572,9 @@ FT_BEGIN_HEADER /* <Note> */ /* The result is undefined if either `a' or `b' is zero. */ /* */ + /* Since the function uses wrap-around arithmetic, results become */ + /* meaningless if the arguments are very large. */ + /* */ FT_EXPORT( void ) FT_Matrix_Multiply( const FT_Matrix* a, FT_Matrix* b ); @@ -594,7 +603,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTGLYPH_H__ */ +#endif /* FTGLYPH_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftgxval.h b/src/3rdparty/freetype/include/freetype/ftgxval.h index 0e9ac1dad3..8382d59954 100644 --- a/src/3rdparty/freetype/include/freetype/ftgxval.h +++ b/src/3rdparty/freetype/include/freetype/ftgxval.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for validating TrueTypeGX/AAT tables (specification). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* Masatake YAMATO, Redhat K.K, */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -25,8 +25,8 @@ /***************************************************************************/ -#ifndef __FTGXVAL_H__ -#define __FTGXVAL_H__ +#ifndef FTGXVAL_H_ +#define FTGXVAL_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -101,15 +101,15 @@ FT_BEGIN_HEADER * The number of tables checked in this module. Use it as a parameter * for the `table-length' argument of function @FT_TrueTypeGX_Validate. */ -#define FT_VALIDATE_GX_LENGTH (FT_VALIDATE_GX_LAST_INDEX + 1) +#define FT_VALIDATE_GX_LENGTH ( FT_VALIDATE_GX_LAST_INDEX + 1 ) /* */ /* Up to 0x1000 is used by otvalid. Ox2xxx is reserved for feature OT extension. */ -#define FT_VALIDATE_GX_START 0x4000 -#define FT_VALIDATE_GX_BITFIELD( tag ) \ - ( FT_VALIDATE_GX_START << FT_VALIDATE_##tag##_INDEX ) +#define FT_VALIDATE_GX_START 0x4000 +#define FT_VALIDATE_GX_BITFIELD( tag ) \ + ( FT_VALIDATE_GX_START << FT_VALIDATE_##tag##_INDEX ) /********************************************************************** @@ -351,7 +351,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTGXVAL_H__ */ +#endif /* FTGXVAL_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftgzip.h b/src/3rdparty/freetype/include/freetype/ftgzip.h index b3a532d5e1..db033da0ed 100644 --- a/src/3rdparty/freetype/include/freetype/ftgzip.h +++ b/src/3rdparty/freetype/include/freetype/ftgzip.h @@ -4,7 +4,7 @@ /* */ /* Gzip-compressed stream support. */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTGZIP_H__ -#define __FTGZIP_H__ +#ifndef FTGZIP_H_ +#define FTGZIP_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -117,11 +117,11 @@ FT_BEGIN_HEADER * * @inout: * output_len :: - * Before calling the function, this is the the total size of the - * output buffer, which must be large enough to hold the entire - * uncompressed data (so the size of the uncompressed data must be - * known in advance). After calling the function, `output_len' is the - * size of the used data in `output'. + * Before calling the function, this is the total size of the output + * buffer, which must be large enough to hold the entire uncompressed + * data (so the size of the uncompressed data must be known in + * advance). After calling the function, `output_len' is the size of + * the used data in `output'. * * @return: * FreeType error code. 0~means success. @@ -129,6 +129,9 @@ FT_BEGIN_HEADER * @note: * This function may return `FT_Err_Unimplemented_Feature' if your build * of FreeType was not compiled with zlib support. + * + * @since: + * 2.5.1 */ FT_EXPORT( FT_Error ) FT_Gzip_Uncompress( FT_Memory memory, @@ -142,7 +145,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTGZIP_H__ */ +#endif /* FTGZIP_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftimage.h b/src/3rdparty/freetype/include/freetype/ftimage.h index 82f284c4f9..79ede1959d 100644 --- a/src/3rdparty/freetype/include/freetype/ftimage.h +++ b/src/3rdparty/freetype/include/freetype/ftimage.h @@ -5,7 +5,7 @@ /* FreeType glyph image formats and default raster interface */ /* (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,12 +24,12 @@ /*************************************************************************/ -#ifndef __FTIMAGE_H__ -#define __FTIMAGE_H__ +#ifndef FTIMAGE_H_ +#define FTIMAGE_H_ - /* _STANDALONE_ is from ftgrays.c */ -#ifndef _STANDALONE_ + /* STANDALONE_ is from ftgrays.c */ +#ifndef STANDALONE_ #include <ft2build.h> #endif @@ -169,13 +169,13 @@ FT_BEGIN_HEADER /* @FT_RENDER_MODE_LCD_V. */ /* */ /* FT_PIXEL_MODE_BGRA :: */ - /* An image with four 8-bit channels per pixel, representing a */ - /* color image (such as emoticons) with alpha channel. For each */ - /* pixel, the format is BGRA, which means, the blue channel comes */ - /* first in memory. The color channels are pre-multiplied and in */ - /* the sRGB colorspace. For example, full red at half-translucent */ - /* opacity will be represented as `00,00,80,80', not `00,00,FF,80'. */ - /* See also @FT_LOAD_COLOR. */ + /* [Since 2.5] An image with four 8-bit channels per pixel, */ + /* representing a color image (such as emoticons) with alpha */ + /* channel. For each pixel, the format is BGRA, which means, the */ + /* blue channel comes first in memory. The color channels are */ + /* pre-multiplied and in the sRGB colorspace. For example, full */ + /* red at half-translucent opacity will be represented as */ + /* `00,00,80,80', not `00,00,FF,80'. See also @FT_LOAD_COLOR. */ /* */ typedef enum FT_Pixel_Mode_ { @@ -301,11 +301,11 @@ FT_BEGIN_HEADER /* each outline point's type. */ /* */ /* If bit~0 is unset, the point is `off' the curve, */ - /* i.e., a Bézier control point, while it is `on' if */ + /* i.e., a Bezier control point, while it is `on' if */ /* set. */ /* */ /* Bit~1 is meaningful for `off' points only. If set, */ - /* it indicates a third-order Bézier arc control point; */ + /* it indicates a third-order Bezier arc control point; */ /* and a second-order control point if unset. */ /* */ /* If bit~2 is set, bits 5-7 contain the drop-out mode */ @@ -532,7 +532,7 @@ FT_BEGIN_HEADER /* A function pointer type used to describe the signature of a `conic */ /* to' function during outline walking or decomposition. */ /* */ - /* A `conic to' is emitted to indicate a second-order Bézier arc in */ + /* A `conic to' is emitted to indicate a second-order Bezier arc in */ /* the outline. */ /* */ /* <Input> */ @@ -564,12 +564,12 @@ FT_BEGIN_HEADER /* A function pointer type used to describe the signature of a `cubic */ /* to' function during outline walking or decomposition. */ /* */ - /* A `cubic to' is emitted to indicate a third-order Bézier arc. */ + /* A `cubic to' is emitted to indicate a third-order Bezier arc. */ /* */ /* <Input> */ - /* control1 :: A pointer to the first Bézier control point. */ + /* control1 :: A pointer to the first Bezier control point. */ /* */ - /* control2 :: A pointer to the second Bézier control point. */ + /* control2 :: A pointer to the second Bezier control point. */ /* */ /* to :: A pointer to the target end point. */ /* */ @@ -595,16 +595,16 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* A structure to hold various function pointers used during outline */ - /* decomposition in order to emit segments, conic, and cubic Béziers. */ + /* decomposition in order to emit segments, conic, and cubic Beziers. */ /* */ /* <Fields> */ /* move_to :: The `move to' emitter. */ /* */ /* line_to :: The segment emitter. */ /* */ - /* conic_to :: The second-order Bézier arc emitter. */ + /* conic_to :: The second-order Bezier arc emitter. */ /* */ - /* cubic_to :: The third-order Bézier arc emitter. */ + /* cubic_to :: The third-order Bezier arc emitter. */ /* */ /* shift :: The shift that is applied to coordinates before they */ /* are sent to the emitter. */ @@ -619,7 +619,7 @@ FT_BEGIN_HEADER /* */ /* { */ /* x' = (x << shift) - delta */ - /* y' = (x << shift) - delta */ + /* y' = (y << shift) - delta */ /* } */ /* */ /* Set the values of `shift' and `delta' to~0 to get the original */ @@ -701,7 +701,7 @@ FT_BEGIN_HEADER /* */ /* FT_GLYPH_FORMAT_OUTLINE :: */ /* The glyph image is a vectorial outline made of line segments */ - /* and Bézier arcs; it can be described as an @FT_Outline; you */ + /* and Bezier arcs; it can be described as an @FT_Outline; you */ /* generally want to access the `outline' field of the */ /* @FT_GlyphSlotRec structure to read it. */ /* */ @@ -747,7 +747,7 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* A raster is a scan converter, in charge of rendering an outline into */ - /* a a bitmap. This section contains the public API for rasters. */ + /* a bitmap. This section contains the public API for rasters. */ /* */ /* Note that in FreeType 2, all rasters are now encapsulated within */ /* specific modules called `renderers'. See `ftrender.h' for more */ @@ -860,16 +860,6 @@ FT_BEGIN_HEADER /* This can be used to write anti-aliased outlines directly to a */ /* given background bitmap, and even perform translucency. */ /* */ - /* Note that the `count' field cannot be greater than a fixed value */ - /* defined by the `FT_MAX_GRAY_SPANS' configuration macro in */ - /* `ftoption.h'. By default, this value is set to~32, which means */ - /* that if there are more than 32~spans on a given scanline, the */ - /* callback is called several times with the same `y' parameter in */ - /* order to draw all callbacks. */ - /* */ - /* Otherwise, the callback is only called once per scan-line, and */ - /* only for those scanlines that do have `gray' pixels on them. */ - /* */ typedef void (*FT_SpanFunc)( int y, int count, @@ -1074,24 +1064,24 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* FreeType used to provide an area of memory called the `render */ - /* pool' available to all registered rasters. This was not thread */ - /* safe however and now FreeType never allocates this pool. NULL */ - /* is always passed in as pool_base. */ + /* pool' available to all registered rasterizers. This was not */ + /* thread safe, however, and now FreeType never allocates this pool. */ /* */ - /* This function is called each time the render pool changes, or just */ - /* after a new raster object is created. */ + /* This function is called after a new raster object is created. */ /* */ /* <Input> */ /* raster :: A handle to the new raster object. */ /* */ - /* pool_base :: The address in memory of the render pool. */ + /* pool_base :: Previously, the address in memory of the render pool. */ + /* Set this to NULL. */ /* */ - /* pool_size :: The size in bytes of the render pool. */ + /* pool_size :: Previously, the size in bytes of the render pool. */ + /* Set this to 0. */ /* */ /* <Note> */ - /* Rasters should ignore the render pool and rely on dynamic or stack */ - /* allocation if they want to (a handle to the memory allocator is */ - /* passed to the raster constructor). */ + /* Rasterizers should rely on dynamic or stack allocation if they */ + /* want to (a handle to the memory allocator is passed to the */ + /* rasterizer constructor). */ /* */ typedef void (*FT_Raster_ResetFunc)( FT_Raster raster, @@ -1190,6 +1180,7 @@ FT_BEGIN_HEADER typedef struct FT_Raster_Funcs_ { FT_Glyph_Format glyph_format; + FT_Raster_NewFunc raster_new; FT_Raster_ResetFunc raster_reset; FT_Raster_SetModeFunc raster_set_mode; @@ -1203,7 +1194,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTIMAGE_H__ */ +#endif /* FTIMAGE_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftincrem.h b/src/3rdparty/freetype/include/freetype/ftincrem.h index 840af25b05..44619f941e 100644 --- a/src/3rdparty/freetype/include/freetype/ftincrem.h +++ b/src/3rdparty/freetype/include/freetype/ftincrem.h @@ -4,7 +4,7 @@ /* */ /* FreeType incremental loading (specification). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,11 +16,12 @@ /***************************************************************************/ -#ifndef __FTINCREM_H__ -#define __FTINCREM_H__ +#ifndef FTINCREM_H_ +#define FTINCREM_H_ #include <ft2build.h> #include FT_FREETYPE_H +#include FT_PARAMETER_TAGS_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" @@ -331,24 +332,12 @@ FT_BEGIN_HEADER typedef FT_Incremental_InterfaceRec* FT_Incremental_Interface; - /*************************************************************************** - * - * @constant: - * FT_PARAM_TAG_INCREMENTAL - * - * @description: - * A constant used as the tag of @FT_Parameter structures to indicate - * an incremental loading object to be used by FreeType. - * - */ -#define FT_PARAM_TAG_INCREMENTAL FT_MAKE_TAG( 'i', 'n', 'c', 'r' ) - /* */ FT_END_HEADER -#endif /* __FTINCREM_H__ */ +#endif /* FTINCREM_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftlcdfil.h b/src/3rdparty/freetype/include/freetype/ftlcdfil.h index 4cd999a4b3..2a27196cbb 100644 --- a/src/3rdparty/freetype/include/freetype/ftlcdfil.h +++ b/src/3rdparty/freetype/include/freetype/ftlcdfil.h @@ -5,7 +5,7 @@ /* FreeType API for color filtering of subpixel bitmap glyphs */ /* (specification). */ /* */ -/* Copyright 2006-2015 by */ +/* Copyright 2006-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,11 +17,12 @@ /***************************************************************************/ -#ifndef __FT_LCD_FILTER_H__ -#define __FT_LCD_FILTER_H__ +#ifndef FTLCDFIL_H_ +#define FTLCDFIL_H_ #include <ft2build.h> #include FT_FREETYPE_H +#include FT_PARAMETER_TAGS_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" @@ -41,56 +42,92 @@ FT_BEGIN_HEADER * LCD Filtering * * @abstract: - * Reduce color fringes of LCD-optimized bitmaps. + * Reduce color fringes of subpixel-rendered bitmaps. * * @description: - * The @FT_Library_SetLcdFilter API can be used to specify a low-pass - * filter, which is then applied to LCD-optimized bitmaps generated - * through @FT_Render_Glyph. This is useful to reduce color fringes - * that would occur with unfiltered rendering. + * Should you #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your + * `ftoption.h', which enables patented ClearType-style rendering, + * the LCD-optimized glyph bitmaps should be filtered to reduce color + * fringes inherent to this technology. The default FreeType LCD + * rendering uses different technology, and API described below, + * although available, does nothing. * - * Note that no filter is active by default, and that this function is - * *not* implemented in default builds of the library. You need to - * #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING in your `ftoption.h' file - * in order to activate it. + * ClearType-style LCD rendering exploits the color-striped structure of + * LCD pixels, increasing the available resolution in the direction of + * the stripe (usually horizontal RGB) by a factor of~3. Since these + * subpixels are color pixels, using them unfiltered creates severe + * color fringes. Use the @FT_Library_SetLcdFilter API to specify a + * low-pass filter, which is then applied to subpixel-rendered bitmaps + * generated through @FT_Render_Glyph. The filter sacrifices some of + * the higher resolution to reduce color fringes, making the glyph image + * slightly blurrier. Positional improvements will remain. * - * FreeType generates alpha coverage maps, which are linear by nature. - * For instance, the value 0x80 in bitmap representation means that - * (within numerical precision) 0x80/0xFF fraction of that pixel is - * covered by the glyph's outline. The blending function for placing - * text over a background is + * A filter should have two properties: * - * { - * dst = alpha * src + (1 - alpha) * dst , - * } + * 1) It should be normalized, meaning the sum of the 5~components + * should be 256 (0x100). It is possible to go above or under this + * target sum, however: going under means tossing out contrast, going + * over means invoking clamping and thereby non-linearities that + * increase contrast somewhat at the expense of greater distortion + * and color-fringing. Contrast is better enhanced through stem + * darkening. * - * which is known as OVER. However, when calculating the output of the - * OVER operator, the source colors should first be transformed to a - * linear color space, then alpha blended in that space, and transformed - * back to the output color space. + * 2) It should be color-balanced, meaning a filter `{~a, b, c, b, a~}' + * where a~+ b~=~c. It distributes the computed coverage for one + * subpixel to all subpixels equally, sacrificing some won resolution + * but drastically reducing color-fringing. Positioning improvements + * remain! Note that color-fringing can only really be minimized + * when using a color-balanced filter and alpha-blending the glyph + * onto a surface in linear space; see @FT_Render_Glyph. * - * When linear light blending is used, the default FIR5 filtering - * weights (as given by FT_LCD_FILTER_DEFAULT) are no longer optimal, as - * they have been designed for black on white rendering while lacking - * gamma correction. To preserve color neutrality, weights for a FIR5 - * filter should be chosen according to two free parameters `a' and `c', - * and the FIR weights should be + * Regarding the form, a filter can be a `boxy' filter or a `beveled' + * filter. Boxy filters are sharper but are less forgiving of non-ideal + * gamma curves of a screen (viewing angles!), beveled filters are + * fuzzier but more tolerant. * - * { - * [a - c, a + c, 2 * a, a + c, a - c] . - * } + * Examples: * - * This formula generates equal weights for all the color primaries - * across the filter kernel, which makes it colorless. One suggested - * set of weights is + * - [0x10 0x40 0x70 0x40 0x10] is beveled and neither balanced nor + * normalized. * - * { - * [0x10, 0x50, 0x60, 0x50, 0x10] , - * } + * - [0x1A 0x33 0x4D 0x33 0x1A] is beveled and balanced but not + * normalized. * - * where `a' has value 0x30 and `b' value 0x20. The weights in filter - * may have a sum larger than 0x100, which increases coloration slightly - * but also improves contrast. + * - [0x19 0x33 0x66 0x4c 0x19] is beveled and normalized but not + * balanced. + * + * - [0x00 0x4c 0x66 0x4c 0x00] is boxily beveled and normalized but not + * balanced. + * + * - [0x00 0x55 0x56 0x55 0x00] is boxy, normalized, and almost + * balanced. + * + * - [0x08 0x4D 0x56 0x4D 0x08] is beveled, normalized and, almost + * balanced. + * + * The filter affects glyph bitmaps rendered through @FT_Render_Glyph, + * @FT_Load_Glyph, and @FT_Load_Char. It does _not_ affect the output + * of @FT_Outline_Render and @FT_Outline_Get_Bitmap. + * + * If this feature is activated, the dimensions of LCD glyph bitmaps are + * either wider or taller than the dimensions of the corresponding + * outline with regard to the pixel grid. For example, for + * @FT_RENDER_MODE_LCD, the filter adds 3~subpixels to the left, and + * 3~subpixels to the right. The bitmap offset values are adjusted + * accordingly, so clients shouldn't need to modify their layout and + * glyph positioning code when enabling the filter. + * + * It is important to understand that linear alpha blending and gamma + * correction is critical for correctly rendering glyphs onto surfaces + * without artifacts and even more critical when subpixel rendering is + * involved. + * + * Each of the 3~alpha values (subpixels) is independently used to blend + * one color channel. That is, red alpha blends the red channel of the + * text color with the red channel of the background pixel. The + * distribution of density values by the color-balanced filter assumes + * alpha blending is done in linear space; only then color artifacts + * cancel out. */ @@ -111,10 +148,23 @@ FT_BEGIN_HEADER * The default filter reduces color fringes considerably, at the cost * of a slight blurriness in the output. * + * It is a beveled, normalized, and color-balanced five-tap filter + * that is more forgiving to screens with non-ideal gamma curves and + * viewing angles. Note that while color-fringing is reduced, it can + * only be minimized by using linear alpha blending and gamma + * correction to render glyphs onto surfaces. The default filter + * weights are [0x08 0x4D 0x56 0x4D 0x08]. + * * FT_LCD_FILTER_LIGHT :: - * The light filter is a variant that produces less blurriness at the - * cost of slightly more color fringes than the default one. It might - * be better, depending on taste, your monitor, or your personal vision. + * The light filter is a variant that is sharper at the cost of + * slightly more color fringes than the default one. + * + * It is a boxy, normalized, and color-balanced three-tap filter that + * is less forgiving to screens with non-ideal gamma curves and + * viewing angles. This filter works best when the rendering system + * uses linear alpha blending and gamma correction to render glyphs + * onto surfaces. The light filter weights are + * [0x00 0x55 0x56 0x55 0x00]. * * FT_LCD_FILTER_LEGACY :: * This filter corresponds to the original libXft color filter. It @@ -126,14 +176,23 @@ FT_BEGIN_HEADER * This filter is only provided for comparison purposes, and might be * disabled or stay unsupported in the future. * + * FT_LCD_FILTER_LEGACY1 :: + * For historical reasons, the FontConfig library returns a different + * enumeration value for legacy LCD filtering. To make code work that + * (incorrectly) forwards FontConfig's enumeration value to + * @FT_Library_SetLcdFilter without proper mapping, it is thus easiest + * to have another enumeration value, which is completely equal to + * `FT_LCD_FILTER_LEGACY'. + * * @since: - * 2.3.0 + * 2.3.0 (`FT_LCD_FILTER_LEGACY1' since 2.6.2) */ typedef enum FT_LcdFilter_ { FT_LCD_FILTER_NONE = 0, FT_LCD_FILTER_DEFAULT = 1, FT_LCD_FILTER_LIGHT = 2, + FT_LCD_FILTER_LEGACY1 = 3, FT_LCD_FILTER_LEGACY = 16, FT_LCD_FILTER_MAX /* do not remove */ @@ -176,22 +235,6 @@ FT_BEGIN_HEADER * defined in your build of the library, which should correspond to all * default builds of FreeType. * - * The filter affects glyph bitmaps rendered through @FT_Render_Glyph, - * @FT_Outline_Get_Bitmap, @FT_Load_Glyph, and @FT_Load_Char. - * - * It does _not_ affect the output of @FT_Outline_Render and - * @FT_Outline_Get_Bitmap. - * - * If this feature is activated, the dimensions of LCD glyph bitmaps are - * either larger or taller than the dimensions of the corresponding - * outline with regards to the pixel grid. For example, for - * @FT_RENDER_MODE_LCD, the filter adds up to 3~pixels to the left, and - * up to 3~pixels to the right. - * - * The bitmap offset values are adjusted correctly, so clients shouldn't - * need to modify their layout and glyph positioning code when enabling - * the filter. - * * @since: * 2.3.0 */ @@ -206,11 +249,8 @@ FT_BEGIN_HEADER * FT_Library_SetLcdFilterWeights * * @description: - * Use this function to override the filter weights selected by - * @FT_Library_SetLcdFilter. By default, FreeType uses the quintuple - * (0x00, 0x55, 0x56, 0x55, 0x00) for FT_LCD_FILTER_LIGHT, and (0x10, - * 0x40, 0x70, 0x40, 0x10) for FT_LCD_FILTER_DEFAULT and - * FT_LCD_FILTER_LEGACY. + * This function can be used to enable LCD filter with custom weights, + * instead of using presets in @FT_Library_SetLcdFilter. * * @input: * library :: @@ -230,8 +270,8 @@ FT_BEGIN_HEADER * defined in your build of the library, which should correspond to all * default builds of FreeType. * - * This function must be called after @FT_Library_SetLcdFilter to have - * any effect. + * LCD filter weights can also be set per face using @FT_Face_Properties + * with @FT_PARAM_TAG_LCD_FILTER_WEIGHTS. * * @since: * 2.4.0 @@ -240,12 +280,30 @@ FT_BEGIN_HEADER FT_Library_SetLcdFilterWeights( FT_Library library, unsigned char *weights ); + + /* + * @type: + * FT_LcdFiveTapFilter + * + * @description: + * A typedef for passing the five LCD filter weights to + * @FT_Face_Properties within an @FT_Parameter structure. + * + * @since: + * 2.8 + * + */ +#define FT_LCD_FILTER_FIVE_TAPS 5 + + typedef FT_Byte FT_LcdFiveTapFilter[FT_LCD_FILTER_FIVE_TAPS]; + + /* */ FT_END_HEADER -#endif /* __FT_LCD_FILTER_H__ */ +#endif /* FTLCDFIL_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftlist.h b/src/3rdparty/freetype/include/freetype/ftlist.h index 12b48c78f7..117473b96a 100644 --- a/src/3rdparty/freetype/include/freetype/ftlist.h +++ b/src/3rdparty/freetype/include/freetype/ftlist.h @@ -4,7 +4,7 @@ /* */ /* Generic list support for FreeType (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,8 +24,8 @@ /*************************************************************************/ -#ifndef __FTLIST_H__ -#define __FTLIST_H__ +#ifndef FTLIST_H_ +#define FTLIST_H_ #include <ft2build.h> @@ -270,7 +270,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTLIST_H__ */ +#endif /* FTLIST_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftlzw.h b/src/3rdparty/freetype/include/freetype/ftlzw.h index d3ec28e554..1615912d62 100644 --- a/src/3rdparty/freetype/include/freetype/ftlzw.h +++ b/src/3rdparty/freetype/include/freetype/ftlzw.h @@ -4,7 +4,7 @@ /* */ /* LZW-compressed stream support. */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTLZW_H__ -#define __FTLZW_H__ +#ifndef FTLZW_H_ +#define FTLZW_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -93,7 +93,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTLZW_H__ */ +#endif /* FTLZW_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftmac.h b/src/3rdparty/freetype/include/freetype/ftmac.h index 14c55cfe2b..c1e497ca2d 100644 --- a/src/3rdparty/freetype/include/freetype/ftmac.h +++ b/src/3rdparty/freetype/include/freetype/ftmac.h @@ -4,7 +4,7 @@ /* */ /* Additional Mac-specific API. */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -25,8 +25,8 @@ /***************************************************************************/ -#ifndef __FTMAC_H__ -#define __FTMAC_H__ +#ifndef FTMAC_H_ +#define FTMAC_H_ #include <ft2build.h> @@ -35,11 +35,12 @@ FT_BEGIN_HEADER -/* gcc-3.4.1 and later can warn about functions tagged as deprecated */ + /* gcc-3.1 and later can warn about functions tagged as deprecated */ #ifndef FT_DEPRECATED_ATTRIBUTE -#if defined(__GNUC__) && \ - ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) -#define FT_DEPRECATED_ATTRIBUTE __attribute__((deprecated)) +#if defined( __GNUC__ ) && \ + ( ( __GNUC__ >= 4 ) || \ + ( ( __GNUC__ == 3 ) && ( __GNUC_MINOR__ >= 1 ) ) ) +#define FT_DEPRECATED_ATTRIBUTE __attribute__(( deprecated )) #else #define FT_DEPRECATED_ATTRIBUTE #endif @@ -268,7 +269,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTMAC_H__ */ +#endif /* FTMAC_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftmm.h b/src/3rdparty/freetype/include/freetype/ftmm.h index 6ef47987e6..9948102c14 100644 --- a/src/3rdparty/freetype/include/freetype/ftmm.h +++ b/src/3rdparty/freetype/include/freetype/ftmm.h @@ -4,7 +4,7 @@ /* */ /* FreeType Multiple Master font interface (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTMM_H__ -#define __FTMM_H__ +#ifndef FTMM_H_ +#define FTMM_H_ #include <ft2build.h> @@ -43,11 +43,10 @@ FT_BEGIN_HEADER /* Master fonts, i.e., the selection of specific design instances by */ /* setting design axis coordinates. */ /* */ - /* George Williams has extended this interface to make it work with */ - /* both Type~1 Multiple Masters fonts and GX distortable (var) */ - /* fonts. Some of these routines only work with MM fonts, others */ - /* will work with both types. They are similar enough that a */ - /* consistent interface makes sense. */ + /* Besides Adobe MM fonts, the interface supports Apple's TrueType GX */ + /* and OpenType variation fonts. Some of the routines only work with */ + /* Adobe MM fonts, others will work with all three types. They are */ + /* similar enough that a consistent interface makes sense. */ /* */ /*************************************************************************/ @@ -58,10 +57,11 @@ FT_BEGIN_HEADER /* FT_MM_Axis */ /* */ /* <Description> */ - /* A simple structure used to model a given axis in design space for */ - /* Multiple Masters fonts. */ + /* A structure to model a given axis in design space for Multiple */ + /* Masters fonts. */ /* */ - /* This structure can't be used for GX var fonts. */ + /* This structure can't be used for TrueType GX or OpenType variation */ + /* fonts. */ /* */ /* <Fields> */ /* name :: The axis's name. */ @@ -85,10 +85,11 @@ FT_BEGIN_HEADER /* FT_Multi_Master */ /* */ /* <Description> */ - /* A structure used to model the axes and space of a Multiple Masters */ + /* A structure to model the axes and space of a Multiple Masters */ /* font. */ /* */ - /* This structure can't be used for GX var fonts. */ + /* This structure can't be used for TrueType GX or OpenType variation */ + /* fonts. */ /* */ /* <Fields> */ /* num_axis :: Number of axes. Cannot exceed~4. */ @@ -115,27 +116,35 @@ FT_BEGIN_HEADER /* FT_Var_Axis */ /* */ /* <Description> */ - /* A simple structure used to model a given axis in design space for */ - /* Multiple Masters and GX var fonts. */ + /* A structure to model a given axis in design space for Multiple */ + /* Masters, TrueType GX, and OpenType variation fonts. */ /* */ /* <Fields> */ /* name :: The axis's name. */ - /* Not always meaningful for GX. */ + /* Not always meaningful for TrueType GX or OpenType */ + /* variation fonts. */ /* */ /* minimum :: The axis's minimum design coordinate. */ /* */ /* def :: The axis's default design coordinate. */ - /* FreeType computes meaningful default values for MM; it */ - /* is then an integer value, not in 16.16 format. */ + /* FreeType computes meaningful default values for Adobe */ + /* MM fonts. */ /* */ /* maximum :: The axis's maximum design coordinate. */ /* */ - /* tag :: The axis's tag (the GX equivalent to `name'). */ - /* FreeType provides default values for MM if possible. */ + /* tag :: The axis's tag (the equivalent to `name' for TrueType */ + /* GX and OpenType variation fonts). FreeType provides */ + /* default values for Adobe MM fonts if possible. */ /* */ - /* strid :: The entry in `name' table (another GX version of */ - /* `name'). */ - /* Not meaningful for MM. */ + /* strid :: The axis name entry in the font's `name' table. This */ + /* is another (and often better) version of the `name' */ + /* field for TrueType GX or OpenType variation fonts. Not */ + /* meaningful for Adobe MM fonts. */ + /* */ + /* <Note> */ + /* The fields `minimum', `def', and `maximum' are 16.16 fractional */ + /* values for TrueType GX and OpenType variation fonts. For Adobe MM */ + /* fonts, the values are integers. */ /* */ typedef struct FT_Var_Axis_ { @@ -157,20 +166,26 @@ FT_BEGIN_HEADER /* FT_Var_Named_Style */ /* */ /* <Description> */ - /* A simple structure used to model a named style in a GX var font. */ + /* A structure to model a named instance in a TrueType GX or OpenType */ + /* variation font. */ /* */ - /* This structure can't be used for MM fonts. */ + /* This structure can't be used for Adobe MM fonts. */ /* */ /* <Fields> */ - /* coords :: The design coordinates for this style. */ + /* coords :: The design coordinates for this instance. */ /* This is an array with one entry for each axis. */ /* */ - /* strid :: The entry in `name' table identifying this style. */ + /* strid :: The entry in `name' table identifying this instance. */ + /* */ + /* psid :: The entry in `name' table identifying a PostScript name */ + /* for this instance. Value 0xFFFF indicates a missing */ + /* entry. */ /* */ typedef struct FT_Var_Named_Style_ { FT_Fixed* coords; FT_UInt strid; + FT_UInt psid; /* since 2.7.1 */ } FT_Var_Named_Style; @@ -181,31 +196,43 @@ FT_BEGIN_HEADER /* FT_MM_Var */ /* */ /* <Description> */ - /* A structure used to model the axes and space of a Multiple Masters */ - /* or GX var distortable font. */ + /* A structure to model the axes and space of an Adobe MM, TrueType */ + /* GX, or OpenType variation font. */ /* */ - /* Some fields are specific to one format and not to the other. */ + /* Some fields are specific to one format and not to the others. */ /* */ /* <Fields> */ /* num_axis :: The number of axes. The maximum value is~4 for */ - /* MM; no limit in GX. */ + /* Adobe MM fonts; no limit in TrueType GX or */ + /* OpenType variation fonts. */ /* */ /* num_designs :: The number of designs; should be normally */ - /* 2^num_axis for MM fonts. Not meaningful for GX */ + /* 2^num_axis for Adobe MM fonts. Not meaningful */ + /* for TrueType GX or OpenType variation fonts */ /* (where every glyph could have a different */ /* number of designs). */ /* */ - /* num_namedstyles :: The number of named styles; only meaningful for */ - /* GX that allows certain design coordinates to */ - /* have a string ID (in the `name' table) */ - /* associated with them. The font can tell the */ - /* user that, for example, Weight=1.5 is `Bold'. */ + /* num_namedstyles :: The number of named styles; a `named style' is */ + /* a tuple of design coordinates that has a string */ + /* ID (in the `name' table) associated with it. */ + /* The font can tell the user that, for example, */ + /* [Weight=1.5,Width=1.1] is `Bold'. Another name */ + /* for `named style' is `named instance'. */ + /* */ + /* For Adobe Multiple Masters fonts, this value is */ + /* always zero because the format does not support */ + /* named styles. */ /* */ /* axis :: An axis descriptor table. */ - /* GX fonts contain slightly more data than MM. */ + /* TrueType GX and OpenType variation fonts */ + /* contain slightly more data than Adobe MM fonts. */ + /* Memory management of this pointer is done */ + /* internally by FreeType. */ /* */ - /* namedstyle :: A named style table. */ - /* Only meaningful with GX. */ + /* namedstyle :: A named style (instance) table. */ + /* Only meaningful for TrueType GX and OpenType */ + /* variation fonts. Memory management of this */ + /* pointer is done internally by FreeType. */ /* */ typedef struct FT_MM_Var_ { @@ -224,9 +251,10 @@ FT_BEGIN_HEADER /* FT_Get_Multi_Master */ /* */ /* <Description> */ - /* Retrieve the Multiple Master descriptor of a given font. */ + /* Retrieve a variation descriptor of a given Adobe MM font. */ /* */ - /* This function can't be used with GX fonts. */ + /* This function can't be used with TrueType GX or OpenType variation */ + /* fonts. */ /* */ /* <Input> */ /* face :: A handle to the source face. */ @@ -248,14 +276,17 @@ FT_BEGIN_HEADER /* FT_Get_MM_Var */ /* */ /* <Description> */ - /* Retrieve the Multiple Master/GX var descriptor of a given font. */ + /* Retrieve a variation descriptor for a given font. */ + /* */ + /* This function works with all supported variation formats. */ /* */ /* <Input> */ /* face :: A handle to the source face. */ /* */ /* <Output> */ - /* amaster :: The Multiple Masters/GX var descriptor. */ - /* Allocates a data structure, which the user must free. */ + /* amaster :: The variation descriptor. */ + /* Allocates a data structure, which the user must */ + /* deallocate with a call to @FT_Done_MM_Var after use. */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ @@ -265,16 +296,37 @@ FT_BEGIN_HEADER FT_MM_Var* *amaster ); + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Done_MM_Var */ + /* */ + /* <Description> */ + /* Free the memory allocated by @FT_Get_MM_Var. */ + /* */ + /* <Input> */ + /* library :: A handle of the face's parent library object that was */ + /* used in the call to @FT_Get_MM_Var to create `amaster'. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_EXPORT( FT_Error ) + FT_Done_MM_Var( FT_Library library, + FT_MM_Var *amaster ); + + /*************************************************************************/ /* */ /* <Function> */ /* FT_Set_MM_Design_Coordinates */ /* */ /* <Description> */ - /* For Multiple Masters fonts, choose an interpolated font design */ - /* through design coordinates. */ + /* For Adobe MM fonts, choose an interpolated font design through */ + /* design coordinates. */ /* */ - /* This function can't be used with GX fonts. */ + /* This function can't be used with TrueType GX or OpenType variation */ + /* fonts. */ /* */ /* <InOut> */ /* face :: A handle to the source face. */ @@ -290,6 +342,15 @@ FT_BEGIN_HEADER /* <Return> */ /* FreeType error code. 0~means success. */ /* */ + /* <Note> */ + /* [Since 2.8.1] To reset all axes to the default values, call the */ + /* function with `num_coords' set to zero and `coords' set to NULL. */ + /* */ + /* [Since 2.9] If `num_coords' is larger than zero, this function */ + /* sets the @FT_FACE_FLAG_VARIATION bit in @FT_Face's `face_flags' */ + /* field (i.e., @FT_IS_VARIATION will return true). If `num_coords' */ + /* is zero, this bit flag gets unset. */ + /* */ FT_EXPORT( FT_Error ) FT_Set_MM_Design_Coordinates( FT_Face face, FT_UInt num_coords, @@ -302,8 +363,9 @@ FT_BEGIN_HEADER /* FT_Set_Var_Design_Coordinates */ /* */ /* <Description> */ - /* For Multiple Master or GX Var fonts, choose an interpolated font */ - /* design through design coordinates. */ + /* Choose an interpolated font design through design coordinates. */ + /* */ + /* This function works with all supported variation formats. */ /* */ /* <InOut> */ /* face :: A handle to the source face. */ @@ -319,20 +381,66 @@ FT_BEGIN_HEADER /* <Return> */ /* FreeType error code. 0~means success. */ /* */ + /* <Note> */ + /* [Since 2.8.1] To reset all axes to the default values, call the */ + /* function with `num_coords' set to zero and `coords' set to NULL. */ + /* [Since 2.9] `Default values' means the currently selected named */ + /* instance (or the base font if no named instance is selected). */ + /* */ + /* [Since 2.9] If `num_coords' is larger than zero, this function */ + /* sets the @FT_FACE_FLAG_VARIATION bit in @FT_Face's `face_flags' */ + /* field (i.e., @FT_IS_VARIATION will return true). If `num_coords' */ + /* is zero, this bit flag gets unset. */ + /* */ FT_EXPORT( FT_Error ) FT_Set_Var_Design_Coordinates( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Var_Design_Coordinates */ + /* */ + /* <Description> */ + /* Get the design coordinates of the currently selected interpolated */ + /* font. */ + /* */ + /* This function works with all supported variation formats. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* num_coords :: The number of design coordinates to retrieve. If it */ + /* is larger than the number of axes, set the excess */ + /* values to~0. */ + /* */ + /* <Output> */ + /* coords :: The design coordinates array. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Since> */ + /* 2.7.1 */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Var_Design_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + /*************************************************************************/ /* */ /* <Function> */ /* FT_Set_MM_Blend_Coordinates */ /* */ /* <Description> */ - /* For Multiple Masters and GX var fonts, choose an interpolated font */ - /* design through normalized blend coordinates. */ + /* Choose an interpolated font design through normalized blend */ + /* coordinates. */ + /* */ + /* This function works with all supported variation formats. */ /* */ /* <InOut> */ /* face :: A handle to the source face. */ @@ -344,17 +452,64 @@ FT_BEGIN_HEADER /* use default values for the remaining axes. */ /* */ /* coords :: The design coordinates array (each element must be */ - /* between 0 and 1.0). */ + /* between 0 and 1.0 for Adobe MM fonts, and between */ + /* -1.0 and 1.0 for TrueType GX and OpenType variation */ + /* fonts). */ /* */ /* <Return> */ /* FreeType error code. 0~means success. */ /* */ + /* <Note> */ + /* [Since 2.8.1] To reset all axes to the default values, call the */ + /* function with `num_coords' set to zero and `coords' set to NULL. */ + /* [Since 2.9] `Default values' means the currently selected named */ + /* instance (or the base font if no named instance is selected). */ + /* */ + /* [Since 2.9] If `num_coords' is larger than zero, this function */ + /* sets the @FT_FACE_FLAG_VARIATION bit in @FT_Face's `face_flags' */ + /* field (i.e., @FT_IS_VARIATION will return true). If `num_coords' */ + /* is zero, this bit flag gets unset. */ + /* */ FT_EXPORT( FT_Error ) FT_Set_MM_Blend_Coordinates( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_MM_Blend_Coordinates */ + /* */ + /* <Description> */ + /* Get the normalized blend coordinates of the currently selected */ + /* interpolated font. */ + /* */ + /* This function works with all supported variation formats. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* num_coords :: The number of normalized blend coordinates to */ + /* retrieve. If it is larger than the number of axes, */ + /* set the excess values to~0.5 for Adobe MM fonts, and */ + /* to~0 for TrueType GX and OpenType variation fonts. */ + /* */ + /* <Output> */ + /* coords :: The normalized blend coordinates array. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Since> */ + /* 2.7.1 */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_MM_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + /*************************************************************************/ /* */ /* <Function> */ @@ -368,12 +523,116 @@ FT_BEGIN_HEADER FT_UInt num_coords, FT_Fixed* coords ); + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Var_Blend_Coordinates */ + /* */ + /* <Description> */ + /* This is another name of @FT_Get_MM_Blend_Coordinates. */ + /* */ + /* <Since> */ + /* 2.7.1 */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Var_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + + /*************************************************************************/ + /* */ + /* <Enum> */ + /* FT_VAR_AXIS_FLAG_XXX */ + /* */ + /* <Description> */ + /* A list of bit flags used in the return value of */ + /* @FT_Get_Var_Axis_Flags. */ + /* */ + /* <Values> */ + /* FT_VAR_AXIS_FLAG_HIDDEN :: */ + /* The variation axis should not be exposed to user interfaces. */ + /* */ + /* <Since> */ + /* 2.8.1 */ + /* */ +#define FT_VAR_AXIS_FLAG_HIDDEN 1 + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Var_Axis_Flags */ + /* */ + /* <Description> */ + /* Get the `flags' field of an OpenType Variation Axis Record. */ + /* */ + /* Not meaningful for Adobe MM fonts (`*flags' is always zero). */ + /* */ + /* <Input> */ + /* master :: The variation descriptor. */ + /* */ + /* axis_index :: The index of the requested variation axis. */ + /* */ + /* <Output> */ + /* flags :: The `flags' field. See @FT_VAR_AXIS_FLAG_XXX for */ + /* possible values. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Since> */ + /* 2.8.1 */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Var_Axis_Flags( FT_MM_Var* master, + FT_UInt axis_index, + FT_UInt* flags ); + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Named_Instance */ + /* */ + /* <Description> */ + /* Set or change the current named instance. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* instance_index :: The index of the requested instance, starting */ + /* with value 1. If set to value 0, FreeType */ + /* switches to font access without a named */ + /* instance. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The function uses the value of `instance_index' to set bits 16-30 */ + /* of the face's `face_index' field. It also resets any variation */ + /* applied to the font, and the @FT_FACE_FLAG_VARIATION bit of the */ + /* face's `face_flags' field gets reset to zero (i.e., */ + /* @FT_IS_VARIATION will return false). */ + /* */ + /* For Adobe MM fonts (which don't have named instances) this */ + /* function simply resets the current face to the default instance. */ + /* */ + /* <Since> */ + /* 2.9 */ + /* */ + FT_EXPORT( FT_Error ) + FT_Set_Named_Instance( FT_Face face, + FT_UInt instance_index ); + /* */ FT_END_HEADER -#endif /* __FTMM_H__ */ +#endif /* FTMM_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftmodapi.h b/src/3rdparty/freetype/include/freetype/ftmodapi.h index 544279a68a..a6eb876ebe 100644 --- a/src/3rdparty/freetype/include/freetype/ftmodapi.h +++ b/src/3rdparty/freetype/include/freetype/ftmodapi.h @@ -4,7 +4,7 @@ /* */ /* FreeType modules public interface (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTMODAPI_H__ -#define __FTMODAPI_H__ +#ifndef FTMODAPI_H_ +#define FTMODAPI_H_ #include <ft2build.h> @@ -89,6 +89,7 @@ FT_BEGIN_HEADER /* */ /* FT_Property_Set */ /* FT_Property_Get */ + /* FT_Set_Default_Properties */ /* */ /* FT_New_Library */ /* FT_Done_Library */ @@ -111,12 +112,14 @@ FT_BEGIN_HEADER #define FT_MODULE_HINTER 4 /* this module is a glyph hinter */ #define FT_MODULE_STYLER 8 /* this module is a styler */ -#define FT_MODULE_DRIVER_SCALABLE 0x100 /* the driver supports */ +#define FT_MODULE_DRIVER_SCALABLE 0x100 /* the driver supports */ /* scalable fonts */ -#define FT_MODULE_DRIVER_NO_OUTLINES 0x200 /* the driver does not */ +#define FT_MODULE_DRIVER_NO_OUTLINES 0x200 /* the driver does not */ /* support vector outlines */ -#define FT_MODULE_DRIVER_HAS_HINTER 0x400 /* the driver provides its */ +#define FT_MODULE_DRIVER_HAS_HINTER 0x400 /* the driver provides its */ /* own hinter */ +#define FT_MODULE_DRIVER_HINTS_LIGHTLY 0x800 /* the driver's hinter */ + /* produces LIGHT hints */ /* deprecated values */ @@ -125,9 +128,10 @@ FT_BEGIN_HEADER #define ft_module_hinter FT_MODULE_HINTER #define ft_module_styler FT_MODULE_STYLER -#define ft_module_driver_scalable FT_MODULE_DRIVER_SCALABLE -#define ft_module_driver_no_outlines FT_MODULE_DRIVER_NO_OUTLINES -#define ft_module_driver_has_hinter FT_MODULE_DRIVER_HAS_HINTER +#define ft_module_driver_scalable FT_MODULE_DRIVER_SCALABLE +#define ft_module_driver_no_outlines FT_MODULE_DRIVER_NO_OUTLINES +#define ft_module_driver_has_hinter FT_MODULE_DRIVER_HAS_HINTER +#define ft_module_driver_hints_lightly FT_MODULE_DRIVER_HINTS_LIGHTLY typedef FT_Pointer FT_Module_Interface; @@ -319,16 +323,15 @@ FT_BEGIN_HEADER * The module name. * * property_name :: - * The property name. Properties are described in the `Synopsis' - * subsection of the module's documentation. + * The property name. Properties are described in section + * @properties. * * Note that only a few modules have properties. * * value :: * A generic pointer to a variable or structure that gives the new * value of the property. The exact definition of `value' is - * dependent on the property; see the `Synopsis' subsection of the - * module's documentation. + * dependent on the property; see section @properties. * * @return: * FreeType error code. 0~means success. @@ -386,15 +389,14 @@ FT_BEGIN_HEADER * The module name. * * property_name :: - * The property name. Properties are described in the `Synopsis' - * subsection of the module's documentation. + * The property name. Properties are described in section + * @properties. * * @inout: * value :: * A generic pointer to a variable or structure that gives the * value of the property. The exact definition of `value' is - * dependent on the property; see the `Synopsis' subsection of the - * module's documentation. + * dependent on the property; see section @properties. * * @return: * FreeType error code. 0~means success. @@ -434,6 +436,50 @@ FT_BEGIN_HEADER void* value ); + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Set_Default_Properties */ + /* */ + /* <Description> */ + /* If compilation option FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES is */ + /* set, this function reads the `FREETYPE_PROPERTIES' environment */ + /* variable to control driver properties. See section @properties */ + /* for more. */ + /* */ + /* If the compilation option is not set, this function does nothing. */ + /* */ + /* `FREETYPE_PROPERTIES' has the following syntax form (broken here */ + /* into multiple lines for better readability). */ + /* */ + /* { */ + /* <optional whitespace> */ + /* <module-name1> ':' */ + /* <property-name1> '=' <property-value1> */ + /* <whitespace> */ + /* <module-name2> ':' */ + /* <property-name2> '=' <property-value2> */ + /* ... */ + /* } */ + /* */ + /* Example: */ + /* */ + /* { */ + /* FREETYPE_PROPERTIES=truetype:interpreter-version=35 \ */ + /* cff:no-stem-darkening=1 \ */ + /* autofitter:warping=1 */ + /* } */ + /* */ + /* <InOut> */ + /* library :: A handle to a new library object. */ + /* */ + /* <Since> */ + /* 2.8 */ + /* */ + FT_EXPORT( void ) + FT_Set_Default_Properties( FT_Library library ); + + /*************************************************************************/ /* */ /* <Function> */ @@ -474,8 +520,9 @@ FT_BEGIN_HEADER /* valid for the life of the @FT_Library object. */ /* */ /* Normally, you would call this function (followed by a call to */ - /* @FT_Add_Default_Modules or a series of calls to @FT_Add_Module) */ - /* instead of @FT_Init_FreeType to initialize the FreeType library. */ + /* @FT_Add_Default_Modules or a series of calls to @FT_Add_Module, */ + /* and a call to @FT_Set_Default_Properties) instead of */ + /* @FT_Init_FreeType to initialize the FreeType library. */ /* */ /* Don't use @FT_Done_FreeType but @FT_Done_Library to destroy a */ /* library instance. */ @@ -610,12 +657,7 @@ FT_BEGIN_HEADER * The library doesn't implement any kind of bytecode interpreter. * * FT_TRUETYPE_ENGINE_TYPE_UNPATENTED :: - * The library implements a bytecode interpreter that doesn't - * support the patented operations of the TrueType virtual machine. - * - * Its main use is to load certain Asian fonts that position and - * scale glyph components with bytecode instructions. It produces - * bad output for most other fonts. + * Deprecated and removed. * * FT_TRUETYPE_ENGINE_TYPE_PATENTED :: * The library implements a bytecode interpreter that covers @@ -663,7 +705,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTMODAPI_H__ */ +#endif /* FTMODAPI_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftmoderr.h b/src/3rdparty/freetype/include/freetype/ftmoderr.h index 9d7f981409..e0fc1312bd 100644 --- a/src/3rdparty/freetype/include/freetype/ftmoderr.h +++ b/src/3rdparty/freetype/include/freetype/ftmoderr.h @@ -4,7 +4,7 @@ /* */ /* FreeType module error offsets (specification). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -74,7 +74,7 @@ /* with something like */ /* */ /* { */ - /* #undef __FTMODERR_H__ */ + /* #undef FTMODERR_H_ */ /* #define FT_MODERRDEF( e, v, s ) { FT_Mod_Err_ ## e, s }, */ /* #define FT_MODERR_START_LIST { */ /* #define FT_MODERR_END_LIST { 0, 0 } }; */ @@ -91,8 +91,8 @@ /*************************************************************************/ -#ifndef __FTMODERR_H__ -#define __FTMODERR_H__ +#ifndef FTMODERR_H_ +#define FTMODERR_H_ /*******************************************************************/ @@ -188,7 +188,7 @@ #undef FT_NEED_EXTERN_C -#endif /* __FTMODERR_H__ */ +#endif /* FTMODERR_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftotval.h b/src/3rdparty/freetype/include/freetype/ftotval.h index e744b713fb..26731c2b9f 100644 --- a/src/3rdparty/freetype/include/freetype/ftotval.h +++ b/src/3rdparty/freetype/include/freetype/ftotval.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for validating OpenType tables (specification). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -27,8 +27,8 @@ /***************************************************************************/ -#ifndef __FTOTVAL_H__ -#define __FTOTVAL_H__ +#ifndef FTOTVAL_H_ +#define FTOTVAL_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -106,12 +106,12 @@ FT_BEGIN_HEADER #define FT_VALIDATE_JSTF 0x1000 #define FT_VALIDATE_MATH 0x2000 -#define FT_VALIDATE_OT FT_VALIDATE_BASE | \ - FT_VALIDATE_GDEF | \ - FT_VALIDATE_GPOS | \ - FT_VALIDATE_GSUB | \ - FT_VALIDATE_JSTF | \ - FT_VALIDATE_MATH +#define FT_VALIDATE_OT ( FT_VALIDATE_BASE | \ + FT_VALIDATE_GDEF | \ + FT_VALIDATE_GPOS | \ + FT_VALIDATE_GSUB | \ + FT_VALIDATE_JSTF | \ + FT_VALIDATE_MATH ) /********************************************************************** * @@ -198,7 +198,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTOTVAL_H__ */ +#endif /* FTOTVAL_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftoutln.h b/src/3rdparty/freetype/include/freetype/ftoutln.h index b6ec70de8c..89389a49b7 100644 --- a/src/3rdparty/freetype/include/freetype/ftoutln.h +++ b/src/3rdparty/freetype/include/freetype/ftoutln.h @@ -5,7 +5,7 @@ /* Support for the FT_Outline type used to store glyph shapes of */ /* most scalable font formats (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __FTOUTLN_H__ -#define __FTOUTLN_H__ +#ifndef FTOUTLN_H_ +#define FTOUTLN_H_ #include <ft2build.h> @@ -89,7 +89,7 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* Walk over an outline's structure to decompose it into individual */ - /* segments and Bézier arcs. This function also emits `move to' */ + /* segments and Bezier arcs. This function also emits `move to' */ /* operations to indicate the start of new contours in the outline. */ /* */ /* <Input> */ @@ -115,6 +115,10 @@ FT_BEGIN_HEADER /* outline for stroking purposes (otherwise it would result in a */ /* visible dot when round caps are used). */ /* */ + /* Similarly, the function returns success for an empty outline also */ + /* (doing nothing, this is, not calling any emitter); if necessary, */ + /* you should filter this out, too. */ + /* */ FT_EXPORT( FT_Error ) FT_Outline_Decompose( FT_Outline* outline, const FT_Outline_Funcs* func_interface, @@ -186,9 +190,6 @@ FT_BEGIN_HEADER /* If the outline's `owner' field is not set, only the outline */ /* descriptor will be released. */ /* */ - /* The reason why this function takes an `library' parameter is */ - /* simply to use ft_mem_free(). */ - /* */ FT_EXPORT( FT_Error ) FT_Outline_Done( FT_Library library, FT_Outline* outline ); @@ -213,6 +214,10 @@ FT_BEGIN_HEADER /* <Return> */ /* FreeType error code. 0~means success. */ /* */ + /* <Note> */ + /* An empty outline, or an outline with a single point only is also */ + /* valid. */ + /* */ FT_EXPORT( FT_Error ) FT_Outline_Check( FT_Outline* outline ); @@ -224,10 +229,10 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* Return an outline's `control box'. The control box encloses all */ - /* the outline's points, including Bézier control points. Though it */ + /* the outline's points, including Bezier control points. Though it */ /* coincides with the exact bounding box for most glyphs, it can be */ /* slightly larger in some situations (like when rotating an outline */ - /* that contains Bézier outside arcs). */ + /* that contains Bezier outside arcs). */ /* */ /* Computing the control box is very fast, while getting the bounding */ /* box can take much more time as it needs to walk over all segments */ @@ -377,6 +382,9 @@ FT_BEGIN_HEADER /* @FT_Outline_Embolden, which uses the same strength in both */ /* directions. */ /* */ + /* <Since> */ + /* 2.4.10 */ + /* */ FT_EXPORT( FT_Error ) FT_Outline_EmboldenXY( FT_Outline* outline, FT_Pos xstrength, @@ -563,7 +571,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTOUTLN_H__ */ +#endif /* FTOUTLN_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftparams.h b/src/3rdparty/freetype/include/freetype/ftparams.h new file mode 100644 index 0000000000..5a9006c505 --- /dev/null +++ b/src/3rdparty/freetype/include/freetype/ftparams.h @@ -0,0 +1,205 @@ +/***************************************************************************/ +/* */ +/* ftparams.h */ +/* */ +/* FreeType API for possible FT_Parameter tags (specification only). */ +/* */ +/* Copyright 2017-2018 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef FTPARAMS_H_ +#define FTPARAMS_H_ + +#include <ft2build.h> +#include FT_FREETYPE_H + +#ifdef FREETYPE_H +#error "freetype.h of FreeType 1 has been loaded!" +#error "Please fix the directory search order for header files" +#error "so that freetype.h of FreeType 2 is found first." +#endif + + +FT_BEGIN_HEADER + + + /************************************************************************** + * + * @section: + * parameter_tags + * + * @title: + * Parameter Tags + * + * @abstract: + * Macros for driver property and font loading parameter tags. + * + * @description: + * This section contains macros for the @FT_Parameter structure that are + * used with various functions to activate some special functionality or + * different behaviour of various components of FreeType. + * + */ + + + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_FAMILY + * + * @description: + * A tag for @FT_Parameter to make @FT_Open_Face ignore typographic + * family names in the `name' table (introduced in OpenType version + * 1.4). Use this for backward compatibility with legacy systems that + * have a four-faces-per-family restriction. + * + * @since: + * 2.8 + * + */ +#define FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_FAMILY \ + FT_MAKE_TAG( 'i', 'g', 'p', 'f' ) + + + /* this constant is deprecated */ +#define FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY \ + FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_FAMILY + + + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_SUBFAMILY + * + * @description: + * A tag for @FT_Parameter to make @FT_Open_Face ignore typographic + * subfamily names in the `name' table (introduced in OpenType version + * 1.4). Use this for backward compatibility with legacy systems that + * have a four-faces-per-family restriction. + * + * @since: + * 2.8 + * + */ +#define FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_SUBFAMILY \ + FT_MAKE_TAG( 'i', 'g', 'p', 's' ) + + + /* this constant is deprecated */ +#define FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY \ + FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_SUBFAMILY + + + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_INCREMENTAL + * + * @description: + * An @FT_Parameter tag to be used with @FT_Open_Face to indicate + * incremental glyph loading. + * + */ +#define FT_PARAM_TAG_INCREMENTAL \ + FT_MAKE_TAG( 'i', 'n', 'c', 'r' ) + + + /************************************************************************** + * + * @constant: + * FT_PARAM_TAG_LCD_FILTER_WEIGHTS + * + * @description: + * An @FT_Parameter tag to be used with @FT_Face_Properties. The + * corresponding argument specifies the five LCD filter weights for a + * given face (if using @FT_LOAD_TARGET_LCD, for example), overriding + * the global default values or the values set up with + * @FT_Library_SetLcdFilterWeights. + * + * @since: + * 2.8 + * + */ +#define FT_PARAM_TAG_LCD_FILTER_WEIGHTS \ + FT_MAKE_TAG( 'l', 'c', 'd', 'f' ) + + + /************************************************************************** + * + * @constant: + * FT_PARAM_TAG_RANDOM_SEED + * + * @description: + * An @FT_Parameter tag to be used with @FT_Face_Properties. The + * corresponding 32bit signed integer argument overrides the font + * driver's random seed value with a face-specific one; see + * @random-seed. + * + * @since: + * 2.8 + * + */ +#define FT_PARAM_TAG_RANDOM_SEED \ + FT_MAKE_TAG( 's', 'e', 'e', 'd' ) + + + /************************************************************************** + * + * @constant: + * FT_PARAM_TAG_STEM_DARKENING + * + * @description: + * An @FT_Parameter tag to be used with @FT_Face_Properties. The + * corresponding Boolean argument specifies whether to apply stem + * darkening, overriding the global default values or the values set up + * with @FT_Property_Set (see @no-stem-darkening). + * + * This is a passive setting that only takes effect if the font driver + * or autohinter honors it, which the CFF, Type~1, and CID drivers + * always do, but the autohinter only in `light' hinting mode (as of + * version 2.9). + * + * @since: + * 2.8 + * + */ +#define FT_PARAM_TAG_STEM_DARKENING \ + FT_MAKE_TAG( 'd', 'a', 'r', 'k' ) + + + /*************************************************************************** + * + * @constant: + * FT_PARAM_TAG_UNPATENTED_HINTING + * + * @description: + * Deprecated, no effect. + * + * Previously: A constant used as the tag of an @FT_Parameter structure to + * indicate that unpatented methods only should be used by the TrueType + * bytecode interpreter for a typeface opened by @FT_Open_Face. + * + */ +#define FT_PARAM_TAG_UNPATENTED_HINTING \ + FT_MAKE_TAG( 'u', 'n', 'p', 'a' ) + + + /* */ + + +FT_END_HEADER + + +#endif /* FTPARAMS_H_ */ + + +/* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftpfr.h b/src/3rdparty/freetype/include/freetype/ftpfr.h index a1c02a2f5e..a69cc482dc 100644 --- a/src/3rdparty/freetype/include/freetype/ftpfr.h +++ b/src/3rdparty/freetype/include/freetype/ftpfr.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing PFR-specific data (specification only). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTPFR_H__ -#define __FTPFR_H__ +#ifndef FTPFR_H_ +#define FTPFR_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -71,7 +71,7 @@ FT_BEGIN_HEADER * * ametrics_x_scale :: * A 16.16 fixed-point number used to scale distance expressed - * in metrics units to device sub-pixels. This is equivalent to + * in metrics units to device subpixels. This is equivalent to * `face->size->x_scale', but for metrics only. Optional (parameter * can be NULL). * @@ -123,7 +123,7 @@ FT_BEGIN_HEADER * mode, which always returns distances converted to outline units. * * You can use the value of the `x_scale' and `y_scale' parameters - * returned by @FT_Get_PFR_Metrics to scale these to device sub-pixels. + * returned by @FT_Get_PFR_Metrics to scale these to device subpixels. */ FT_EXPORT( FT_Error ) FT_Get_PFR_Kerning( FT_Face face, @@ -154,7 +154,7 @@ FT_BEGIN_HEADER * * @note: * You can use the `x_scale' or `y_scale' results of @FT_Get_PFR_Metrics - * to convert the advance to device sub-pixels (i.e., 1/64th of pixels). + * to convert the advance to device subpixels (i.e., 1/64th of pixels). */ FT_EXPORT( FT_Error ) FT_Get_PFR_Advance( FT_Face face, @@ -166,7 +166,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTPFR_H__ */ +#endif /* FTPFR_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftrender.h b/src/3rdparty/freetype/include/freetype/ftrender.h index ec8da700b1..fa8ad22b98 100644 --- a/src/3rdparty/freetype/include/freetype/ftrender.h +++ b/src/3rdparty/freetype/include/freetype/ftrender.h @@ -4,7 +4,7 @@ /* */ /* FreeType renderer modules public interface (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTRENDER_H__ -#define __FTRENDER_H__ +#ifndef FTRENDER_H_ +#define FTRENDER_H_ #include <ft2build.h> @@ -75,6 +75,7 @@ FT_BEGIN_HEADER { FT_Long glyph_size; FT_Glyph_Format glyph_format; + FT_Glyph_InitFunc glyph_init; FT_Glyph_DoneFunc glyph_done; FT_Glyph_CopyFunc glyph_copy; @@ -87,7 +88,7 @@ FT_BEGIN_HEADER typedef FT_Error (*FT_Renderer_RenderFunc)( FT_Renderer renderer, FT_GlyphSlot slot, - FT_UInt mode, + FT_Render_Mode mode, const FT_Vector* origin ); typedef FT_Error @@ -226,7 +227,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTRENDER_H__ */ +#endif /* FTRENDER_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftsizes.h b/src/3rdparty/freetype/include/freetype/ftsizes.h index bef8424715..72cb08bf2a 100644 --- a/src/3rdparty/freetype/include/freetype/ftsizes.h +++ b/src/3rdparty/freetype/include/freetype/ftsizes.h @@ -4,7 +4,7 @@ /* */ /* FreeType size objects management (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -25,8 +25,8 @@ /*************************************************************************/ -#ifndef __FTSIZES_H__ -#define __FTSIZES_H__ +#ifndef FTSIZES_H_ +#define FTSIZES_H_ #include <ft2build.h> @@ -153,7 +153,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTSIZES_H__ */ +#endif /* FTSIZES_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftsnames.h b/src/3rdparty/freetype/include/freetype/ftsnames.h index 0f7fbe1744..8eb8d70ff7 100644 --- a/src/3rdparty/freetype/include/freetype/ftsnames.h +++ b/src/3rdparty/freetype/include/freetype/ftsnames.h @@ -2,12 +2,12 @@ /* */ /* ftsnames.h */ /* */ -/* Simple interface to access SFNT name tables (which are used */ +/* Simple interface to access SFNT `name' tables (which are used */ /* to hold font names, copyright info, notices, etc.) (specification). */ /* */ /* This is _not_ used to retrieve glyph names! */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,12 +19,13 @@ /***************************************************************************/ -#ifndef __FT_SFNT_NAMES_H__ -#define __FT_SFNT_NAMES_H__ +#ifndef FTSNAMES_H_ +#define FTSNAMES_H_ #include <ft2build.h> #include FT_FREETYPE_H +#include FT_PARAMETER_TAGS_H #ifdef FREETYPE_H #error "freetype.h of FreeType 1 has been loaded!" @@ -49,7 +50,7 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* The TrueType and OpenType specifications allow the inclusion of */ - /* a special `names table' in font files. This table contains */ + /* a special names table (`name') in font files. This table contains */ /* textual (and internationalized) information regarding the font, */ /* like family name, copyright, version, etc. */ /* */ @@ -70,30 +71,37 @@ FT_BEGIN_HEADER /* */ /* <Fields> */ /* platform_id :: The platform ID for `string'. */ + /* See @TT_PLATFORM_XXX for possible values. */ /* */ /* encoding_id :: The encoding ID for `string'. */ + /* See @TT_APPLE_ID_XXX, @TT_MAC_ID_XXX, */ + /* @TT_ISO_ID_XXX, @TT_MS_ID_XXX, and @TT_ADOBE_ID_XXX */ + /* for possible values. */ /* */ /* language_id :: The language ID for `string'. */ + /* See @TT_MAC_LANGID_XXX and @TT_MS_LANGID_XXX for */ + /* possible values. */ + /* */ + /* Registered OpenType values for `language_id' are */ + /* always smaller than 0x8000; values equal or larger */ + /* than 0x8000 usually indicate a language tag string */ + /* (introduced in OpenType version 1.6). Use function */ + /* @FT_Get_Sfnt_LangTag with `language_id' as its */ + /* argument to retrieve the associated language tag. */ /* */ /* name_id :: An identifier for `string'. */ + /* See @TT_NAME_ID_XXX for possible values. */ /* */ /* string :: The `name' string. Note that its format differs */ - /* depending on the (platform,encoding) pair. It can */ - /* be a Pascal String, a UTF-16 one, etc. */ - /* */ - /* Generally speaking, the string is not */ - /* zero-terminated. Please refer to the TrueType */ - /* specification for details. */ + /* depending on the (platform,encoding) pair, being */ + /* either a string of bytes (without a terminating */ + /* NULL byte) or containing UTF-16BE entities. */ /* */ /* string_len :: The length of `string' in bytes. */ /* */ /* <Note> */ - /* Possible values for `platform_id', `encoding_id', `language_id', */ - /* and `name_id' are given in the file `ttnameid.h'. For details */ - /* please refer to the TrueType or OpenType specification. */ - /* */ - /* See also @TT_PLATFORM_XXX, @TT_APPLE_ID_XXX, @TT_MAC_ID_XXX, */ - /* @TT_ISO_ID_XXX, and @TT_MS_ID_XXX. */ + /* Please refer to the TrueType or OpenType specification for more */ + /* details. */ /* */ typedef struct FT_SfntName_ { @@ -103,7 +111,7 @@ FT_BEGIN_HEADER FT_UShort name_id; FT_Byte* string; /* this string is *not* null-terminated! */ - FT_UInt string_len; /* in bytes */ + FT_UInt string_len; /* in bytes */ } FT_SfntName; @@ -147,54 +155,99 @@ FT_BEGIN_HEADER /* */ /* <Note> */ /* The `string' array returned in the `aname' structure is not */ - /* null-terminated. The application should deallocate it if it is no */ - /* longer in use. */ + /* null-terminated. Note that you don't have to deallocate `string' */ + /* by yourself; FreeType takes care of it if you call @FT_Done_Face. */ /* */ /* Use @FT_Get_Sfnt_Name_Count to get the total number of available */ /* `name' table entries, then do a loop until you get the right */ /* platform, encoding, and name ID. */ /* */ + /* `name' table format~1 entries can use language tags also, see */ + /* @FT_Get_Sfnt_LangTag. */ + /* */ FT_EXPORT( FT_Error ) FT_Get_Sfnt_Name( FT_Face face, FT_UInt idx, FT_SfntName *aname ); - /*************************************************************************** - * - * @constant: - * FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY - * - * @description: - * A constant used as the tag of @FT_Parameter structures to make - * FT_Open_Face() ignore preferred family subfamily names in `name' - * table since OpenType version 1.4. For backwards compatibility with - * legacy systems that have a 4-face-per-family restriction. - * - */ -#define FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY FT_MAKE_TAG( 'i', 'g', 'p', 'f' ) + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_SfntLangTag */ + /* */ + /* <Description> */ + /* A structure to model a language tag entry from an SFNT `name' */ + /* table. */ + /* */ + /* <Fields> */ + /* string :: The language tag string, encoded in UTF-16BE */ + /* (without trailing NULL bytes). */ + /* */ + /* string_len :: The length of `string' in *bytes*. */ + /* */ + /* <Note> */ + /* Please refer to the TrueType or OpenType specification for more */ + /* details. */ + /* */ + /* <Since> */ + /* 2.8 */ + /* */ + typedef struct FT_SfntLangTag_ + { + FT_Byte* string; /* this string is *not* null-terminated! */ + FT_UInt string_len; /* in bytes */ + + } FT_SfntLangTag; - /*************************************************************************** - * - * @constant: - * FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY - * - * @description: - * A constant used as the tag of @FT_Parameter structures to make - * FT_Open_Face() ignore preferred subfamily names in `name' table since - * OpenType version 1.4. For backwards compatibility with legacy - * systems that have a 4-face-per-family restriction. - * - */ -#define FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY FT_MAKE_TAG( 'i', 'g', 'p', 's' ) + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Get_Sfnt_LangTag */ + /* */ + /* <Description> */ + /* Retrieve the language tag associated with a language ID of an SFNT */ + /* `name' table entry. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* langID :: The language ID, as returned by @FT_Get_Sfnt_Name. */ + /* This is always a value larger than 0x8000. */ + /* */ + /* <Output> */ + /* alangTag :: The language tag associated with the `name' table */ + /* entry's language ID. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + /* <Note> */ + /* The `string' array returned in the `alangTag' structure is not */ + /* null-terminated. Note that you don't have to deallocate `string' */ + /* by yourself; FreeType takes care of it if you call @FT_Done_Face. */ + /* */ + /* Only `name' table format~1 supports language tags. For format~0 */ + /* tables, this function always returns FT_Err_Invalid_Table. For */ + /* invalid format~1 language ID values, FT_Err_Invalid_Argument is */ + /* returned. */ + /* */ + /* <Since> */ + /* 2.8 */ + /* */ + FT_EXPORT( FT_Error ) + FT_Get_Sfnt_LangTag( FT_Face face, + FT_UInt langID, + FT_SfntLangTag *alangTag ); + /* */ FT_END_HEADER -#endif /* __FT_SFNT_NAMES_H__ */ +#endif /* FTSNAMES_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftstroke.h b/src/3rdparty/freetype/include/freetype/ftstroke.h index 7ebb1e7404..44b6fbe19f 100644 --- a/src/3rdparty/freetype/include/freetype/ftstroke.h +++ b/src/3rdparty/freetype/include/freetype/ftstroke.h @@ -4,7 +4,7 @@ /* */ /* FreeType path stroker (specification). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FT_STROKE_H__ -#define __FT_STROKE_H__ +#ifndef FTSTROKE_H_ +#define FTSTROKE_H_ #include <ft2build.h> #include FT_OUTLINE_H @@ -136,7 +136,7 @@ FT_BEGIN_HEADER * FT_STROKER_LINEJOIN_MITER_VARIABLE generates a mitered line * join as used in XPS. FT_STROKER_LINEJOIN_MITER is an alias * for FT_STROKER_LINEJOIN_MITER_VARIABLE, retained for - * backwards compatibility. + * backward compatibility. */ typedef enum FT_Stroker_LineJoin_ { @@ -466,7 +466,7 @@ FT_BEGIN_HEADER * FT_Stroker_ConicTo * * @description: - * `Draw' a single quadratic Bézier in the stroker's current sub-path, + * `Draw' a single quadratic Bezier in the stroker's current sub-path, * from the last position. * * @input: @@ -474,7 +474,7 @@ FT_BEGIN_HEADER * The target stroker handle. * * control :: - * A pointer to a Bézier control point. + * A pointer to a Bezier control point. * * to :: * A pointer to the destination point. @@ -498,7 +498,7 @@ FT_BEGIN_HEADER * FT_Stroker_CubicTo * * @description: - * `Draw' a single cubic Bézier in the stroker's current sub-path, + * `Draw' a single cubic Bezier in the stroker's current sub-path, * from the last position. * * @input: @@ -506,10 +506,10 @@ FT_BEGIN_HEADER * The target stroker handle. * * control1 :: - * A pointer to the first Bézier control point. + * A pointer to the first Bezier control point. * * control2 :: - * A pointer to second Bézier control point. + * A pointer to second Bezier control point. * * to :: * A pointer to the destination point. @@ -774,7 +774,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FT_STROKE_H__ */ +#endif /* FTSTROKE_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftsynth.h b/src/3rdparty/freetype/include/freetype/ftsynth.h index fbcbad871a..ff9fb43d96 100644 --- a/src/3rdparty/freetype/include/freetype/ftsynth.h +++ b/src/3rdparty/freetype/include/freetype/ftsynth.h @@ -5,7 +5,7 @@ /* FreeType synthesizing code for emboldening and slanting */ /* (specification). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -41,8 +41,8 @@ /* adapted to the particular needs. */ -#ifndef __FTSYNTH_H__ -#define __FTSYNTH_H__ +#ifndef FTSYNTH_H_ +#define FTSYNTH_H_ #include <ft2build.h> @@ -78,7 +78,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTSYNTH_H__ */ +#endif /* FTSYNTH_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftsystem.h b/src/3rdparty/freetype/include/freetype/ftsystem.h index 2bc999910b..f6b1629ef2 100644 --- a/src/3rdparty/freetype/include/freetype/ftsystem.h +++ b/src/3rdparty/freetype/include/freetype/ftsystem.h @@ -4,7 +4,7 @@ /* */ /* FreeType low-level system interface definition (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTSYSTEM_H__ -#define __FTSYSTEM_H__ +#ifndef FTSYSTEM_H_ +#define FTSYSTEM_H_ #include <ft2build.h> @@ -290,7 +290,7 @@ FT_BEGIN_HEADER * The stream size in bytes. * * In case of compressed streams where the size is unknown before - * actually doing the decompression, the value is set to 0x7FFFFFFF. + * actually doing the decompression, the value is set to 0x7FFFFFFF. * (Note that this size value can occur for normal streams also; it is * thus just a hint.) * @@ -349,7 +349,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTSYSTEM_H__ */ +#endif /* FTSYSTEM_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/fttrigon.h b/src/3rdparty/freetype/include/freetype/fttrigon.h index 485ec51587..2e3f3f1f73 100644 --- a/src/3rdparty/freetype/include/freetype/fttrigon.h +++ b/src/3rdparty/freetype/include/freetype/fttrigon.h @@ -4,7 +4,7 @@ /* */ /* FreeType trigonometric functions (specification). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTTRIGON_H__ -#define __FTTRIGON_H__ +#ifndef FTTRIGON_H_ +#define FTTRIGON_H_ #include FT_FREETYPE_H @@ -344,7 +344,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTTRIGON_H__ */ +#endif /* FTTRIGON_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/fttypes.h b/src/3rdparty/freetype/include/freetype/fttypes.h index 706a1be4ef..f638c2e54f 100644 --- a/src/3rdparty/freetype/include/freetype/fttypes.h +++ b/src/3rdparty/freetype/include/freetype/fttypes.h @@ -4,7 +4,7 @@ /* */ /* FreeType simple types definitions (specification only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTTYPES_H__ -#define __FTTYPES_H__ +#ifndef FTTYPES_H_ +#define FTTYPES_H_ #include <ft2build.h> @@ -425,7 +425,7 @@ FT_BEGIN_HEADER /* The address of the FreeType object that is under finalization. */ /* Its client data is accessed through its `generic' field. */ /* */ - typedef void (*FT_Generic_Finalizer)(void* object); + typedef void (*FT_Generic_Finalizer)( void* object ); /*************************************************************************/ @@ -596,7 +596,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTTYPES_H__ */ +#endif /* FTTYPES_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ftwinfnt.h b/src/3rdparty/freetype/include/freetype/ftwinfnt.h index caedaa1cc7..461c65b779 100644 --- a/src/3rdparty/freetype/include/freetype/ftwinfnt.h +++ b/src/3rdparty/freetype/include/freetype/ftwinfnt.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing Windows fnt-specific data. */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTWINFNT_H__ -#define __FTWINFNT_H__ +#ifndef FTWINFNT_H_ +#define FTWINFNT_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -78,7 +78,7 @@ FT_BEGIN_HEADER * Mac Roman encoding. * * FT_WinFNT_ID_OEM :: - * From Michael Pöttgen <michael@poettgen.de>: + * From Michael Poettgen <michael@poettgen.de>: * * The `Windows Font Mapping' article says that FT_WinFNT_ID_OEM * is used for the charset of vector fonts, like `modern.fon', @@ -264,7 +264,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTWINFNT_H__ */ +#endif /* FTWINFNT_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/autohint.h b/src/3rdparty/freetype/include/freetype/internal/autohint.h index 8d5a9773cb..f4d308f68c 100644 --- a/src/3rdparty/freetype/include/freetype/internal/autohint.h +++ b/src/3rdparty/freetype/include/freetype/internal/autohint.h @@ -4,7 +4,7 @@ /* */ /* High-level `autohint' module-specific interface (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,8 +24,8 @@ /*************************************************************************/ -#ifndef __AUTOHINT_H__ -#define __AUTOHINT_H__ +#ifndef AUTOHINT_H_ +#define AUTOHINT_H_ /*************************************************************************/ @@ -238,7 +238,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __AUTOHINT_H__ */ +#endif /* AUTOHINT_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/cffotypes.h b/src/3rdparty/freetype/include/freetype/internal/cffotypes.h new file mode 100644 index 0000000000..57e7591d41 --- /dev/null +++ b/src/3rdparty/freetype/include/freetype/internal/cffotypes.h @@ -0,0 +1,108 @@ +/***************************************************************************/ +/* */ +/* cffotypes.h */ +/* */ +/* Basic OpenType/CFF object type definitions (specification). */ +/* */ +/* Copyright 2017-2018 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef CFFOTYPES_H_ +#define CFFOTYPES_H_ + +#include <ft2build.h> +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_CFF_TYPES_H +#include FT_INTERNAL_TRUETYPE_TYPES_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H + + +FT_BEGIN_HEADER + + + typedef TT_Face CFF_Face; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* CFF_Size */ + /* */ + /* <Description> */ + /* A handle to an OpenType size object. */ + /* */ + typedef struct CFF_SizeRec_ + { + FT_SizeRec root; + FT_ULong strike_index; /* 0xFFFFFFFF to indicate invalid */ + + } CFF_SizeRec, *CFF_Size; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* CFF_GlyphSlot */ + /* */ + /* <Description> */ + /* A handle to an OpenType glyph slot object. */ + /* */ + typedef struct CFF_GlyphSlotRec_ + { + FT_GlyphSlotRec root; + + FT_Bool hint; + FT_Bool scaled; + + FT_Fixed x_scale; + FT_Fixed y_scale; + + } CFF_GlyphSlotRec, *CFF_GlyphSlot; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* CFF_Internal */ + /* */ + /* <Description> */ + /* The interface to the `internal' field of `FT_Size'. */ + /* */ + typedef struct CFF_InternalRec_ + { + PSH_Globals topfont; + PSH_Globals subfonts[CFF_MAX_CID_FONTS]; + + } CFF_InternalRec, *CFF_Internal; + + + /*************************************************************************/ + /* */ + /* Subglyph transformation record. */ + /* */ + typedef struct CFF_Transform_ + { + FT_Fixed xx, xy; /* transformation matrix coefficients */ + FT_Fixed yx, yy; + FT_F26Dot6 ox, oy; /* offsets */ + + } CFF_Transform; + + +FT_END_HEADER + + +#endif /* CFFOTYPES_H_ */ + + +/* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/cfftypes.h b/src/3rdparty/freetype/include/freetype/internal/cfftypes.h new file mode 100644 index 0000000000..7c07e1a376 --- /dev/null +++ b/src/3rdparty/freetype/include/freetype/internal/cfftypes.h @@ -0,0 +1,412 @@ +/***************************************************************************/ +/* */ +/* cfftypes.h */ +/* */ +/* Basic OpenType/CFF type definitions and interface (specification */ +/* only). */ +/* */ +/* Copyright 1996-2018 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef CFFTYPES_H_ +#define CFFTYPES_H_ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_TYPE1_TABLES_H +#include FT_INTERNAL_SERVICE_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include FT_INTERNAL_POSTSCRIPT_HINTS_H +#include FT_INTERNAL_TYPE1_TYPES_H + + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* CFF_IndexRec */ + /* */ + /* <Description> */ + /* A structure used to model a CFF Index table. */ + /* */ + /* <Fields> */ + /* stream :: The source input stream. */ + /* */ + /* start :: The position of the first index byte in the */ + /* input stream. */ + /* */ + /* count :: The number of elements in the index. */ + /* */ + /* off_size :: The size in bytes of object offsets in index. */ + /* */ + /* data_offset :: The position of first data byte in the index's */ + /* bytes. */ + /* */ + /* data_size :: The size of the data table in this index. */ + /* */ + /* offsets :: A table of element offsets in the index. Must be */ + /* loaded explicitly. */ + /* */ + /* bytes :: If the index is loaded in memory, its bytes. */ + /* */ + typedef struct CFF_IndexRec_ + { + FT_Stream stream; + FT_ULong start; + FT_UInt hdr_size; + FT_UInt count; + FT_Byte off_size; + FT_ULong data_offset; + FT_ULong data_size; + + FT_ULong* offsets; + FT_Byte* bytes; + + } CFF_IndexRec, *CFF_Index; + + + typedef struct CFF_EncodingRec_ + { + FT_UInt format; + FT_ULong offset; + + FT_UInt count; + FT_UShort sids [256]; /* avoid dynamic allocations */ + FT_UShort codes[256]; + + } CFF_EncodingRec, *CFF_Encoding; + + + typedef struct CFF_CharsetRec_ + { + + FT_UInt format; + FT_ULong offset; + + FT_UShort* sids; + FT_UShort* cids; /* the inverse mapping of `sids'; only needed */ + /* for CID-keyed fonts */ + FT_UInt max_cid; + FT_UInt num_glyphs; + + } CFF_CharsetRec, *CFF_Charset; + + + /* cf. similar fields in file `ttgxvar.h' from the `truetype' module */ + + typedef struct CFF_VarData_ + { +#if 0 + FT_UInt itemCount; /* not used; always zero */ + FT_UInt shortDeltaCount; /* not used; always zero */ +#endif + + FT_UInt regionIdxCount; /* number of region indexes */ + FT_UInt* regionIndices; /* array of `regionIdxCount' indices; */ + /* these index `varRegionList' */ + } CFF_VarData; + + + /* contribution of one axis to a region */ + typedef struct CFF_AxisCoords_ + { + FT_Fixed startCoord; + FT_Fixed peakCoord; /* zero peak means no effect (factor = 1) */ + FT_Fixed endCoord; + + } CFF_AxisCoords; + + + typedef struct CFF_VarRegion_ + { + CFF_AxisCoords* axisList; /* array of axisCount records */ + + } CFF_VarRegion; + + + typedef struct CFF_VStoreRec_ + { + FT_UInt dataCount; + CFF_VarData* varData; /* array of dataCount records */ + /* vsindex indexes this array */ + FT_UShort axisCount; + FT_UInt regionCount; /* total number of regions defined */ + CFF_VarRegion* varRegionList; + + } CFF_VStoreRec, *CFF_VStore; + + + /* forward reference */ + typedef struct CFF_FontRec_* CFF_Font; + + + /* This object manages one cached blend vector. */ + /* */ + /* There is a BlendRec for Private DICT parsing in each subfont */ + /* and a BlendRec for charstrings in CF2_Font instance data. */ + /* A cached BV may be used across DICTs or Charstrings if inputs */ + /* have not changed. */ + /* */ + /* `usedBV' is reset at the start of each parse or charstring. */ + /* vsindex cannot be changed after a BV is used. */ + /* */ + /* Note: NDV is long (32/64 bit), while BV is 16.16 (FT_Int32). */ + typedef struct CFF_BlendRec_ + { + FT_Bool builtBV; /* blendV has been built */ + FT_Bool usedBV; /* blendV has been used */ + CFF_Font font; /* top level font struct */ + FT_UInt lastVsindex; /* last vsindex used */ + FT_UInt lenNDV; /* normDV length (aka numAxes) */ + FT_Fixed* lastNDV; /* last NDV used */ + FT_UInt lenBV; /* BlendV length (aka numMasters) */ + FT_Int32* BV; /* current blendV (per DICT/glyph) */ + + } CFF_BlendRec, *CFF_Blend; + + + typedef struct CFF_FontRecDictRec_ + { + FT_UInt version; + FT_UInt notice; + FT_UInt copyright; + FT_UInt full_name; + FT_UInt family_name; + FT_UInt weight; + FT_Bool is_fixed_pitch; + FT_Fixed italic_angle; + FT_Fixed underline_position; + FT_Fixed underline_thickness; + FT_Int paint_type; + FT_Int charstring_type; + FT_Matrix font_matrix; + FT_Bool has_font_matrix; + FT_ULong units_per_em; /* temporarily used as scaling value also */ + FT_Vector font_offset; + FT_ULong unique_id; + FT_BBox font_bbox; + FT_Pos stroke_width; + FT_ULong charset_offset; + FT_ULong encoding_offset; + FT_ULong charstrings_offset; + FT_ULong private_offset; + FT_ULong private_size; + FT_Long synthetic_base; + FT_UInt embedded_postscript; + + /* these should only be used for the top-level font dictionary */ + FT_UInt cid_registry; + FT_UInt cid_ordering; + FT_Long cid_supplement; + + FT_Long cid_font_version; + FT_Long cid_font_revision; + FT_Long cid_font_type; + FT_ULong cid_count; + FT_ULong cid_uid_base; + FT_ULong cid_fd_array_offset; + FT_ULong cid_fd_select_offset; + FT_UInt cid_font_name; + + /* the next fields come from the data of the deprecated */ + /* `MultipleMaster' operator; they are needed to parse the (also */ + /* deprecated) `blend' operator in Type 2 charstrings */ + FT_UShort num_designs; + FT_UShort num_axes; + + /* fields for CFF2 */ + FT_ULong vstore_offset; + FT_UInt maxstack; + + } CFF_FontRecDictRec, *CFF_FontRecDict; + + + /* forward reference */ + typedef struct CFF_SubFontRec_* CFF_SubFont; + + + typedef struct CFF_PrivateRec_ + { + FT_Byte num_blue_values; + FT_Byte num_other_blues; + FT_Byte num_family_blues; + FT_Byte num_family_other_blues; + + FT_Pos blue_values[14]; + FT_Pos other_blues[10]; + FT_Pos family_blues[14]; + FT_Pos family_other_blues[10]; + + FT_Fixed blue_scale; + FT_Pos blue_shift; + FT_Pos blue_fuzz; + FT_Pos standard_width; + FT_Pos standard_height; + + FT_Byte num_snap_widths; + FT_Byte num_snap_heights; + FT_Pos snap_widths[13]; + FT_Pos snap_heights[13]; + FT_Bool force_bold; + FT_Fixed force_bold_threshold; + FT_Int lenIV; + FT_Int language_group; + FT_Fixed expansion_factor; + FT_Long initial_random_seed; + FT_ULong local_subrs_offset; + FT_Pos default_width; + FT_Pos nominal_width; + + /* fields for CFF2 */ + FT_UInt vsindex; + CFF_SubFont subfont; + + } CFF_PrivateRec, *CFF_Private; + + + typedef struct CFF_FDSelectRec_ + { + FT_Byte format; + FT_UInt range_count; + + /* that's the table, taken from the file `as is' */ + FT_Byte* data; + FT_UInt data_size; + + /* small cache for format 3 only */ + FT_UInt cache_first; + FT_UInt cache_count; + FT_Byte cache_fd; + + } CFF_FDSelectRec, *CFF_FDSelect; + + + /* A SubFont packs a font dict and a private dict together. They are */ + /* needed to support CID-keyed CFF fonts. */ + typedef struct CFF_SubFontRec_ + { + CFF_FontRecDictRec font_dict; + CFF_PrivateRec private_dict; + + /* fields for CFF2 */ + CFF_BlendRec blend; /* current blend vector */ + FT_UInt lenNDV; /* current length NDV or zero */ + FT_Fixed* NDV; /* ptr to current NDV or NULL */ + + /* `blend_stack' is a writable buffer to hold blend results. */ + /* This buffer is to the side of the normal cff parser stack; */ + /* `cff_parse_blend' and `cff_blend_doBlend' push blend results here. */ + /* The normal stack then points to these values instead of the DICT */ + /* because all other operators in Private DICT clear the stack. */ + /* `blend_stack' could be cleared at each operator other than blend. */ + /* Blended values are stored as 5-byte fixed point values. */ + + FT_Byte* blend_stack; /* base of stack allocation */ + FT_Byte* blend_top; /* first empty slot */ + FT_UInt blend_used; /* number of bytes in use */ + FT_UInt blend_alloc; /* number of bytes allocated */ + + CFF_IndexRec local_subrs_index; + FT_Byte** local_subrs; /* array of pointers */ + /* into Local Subrs INDEX data */ + + FT_UInt32 random; + + } CFF_SubFontRec; + + +#define CFF_MAX_CID_FONTS 256 + + + typedef struct CFF_FontRec_ + { + FT_Library library; + FT_Stream stream; + FT_Memory memory; /* TODO: take this from stream->memory? */ + FT_ULong base_offset; /* offset to start of CFF */ + FT_UInt num_faces; + FT_UInt num_glyphs; + + FT_Byte version_major; + FT_Byte version_minor; + FT_Byte header_size; + + FT_UInt top_dict_length; /* cff2 only */ + + FT_Bool cff2; + + CFF_IndexRec name_index; + CFF_IndexRec top_dict_index; + CFF_IndexRec global_subrs_index; + + CFF_EncodingRec encoding; + CFF_CharsetRec charset; + + CFF_IndexRec charstrings_index; + CFF_IndexRec font_dict_index; + CFF_IndexRec private_index; + CFF_IndexRec local_subrs_index; + + FT_String* font_name; + + /* array of pointers into Global Subrs INDEX data */ + FT_Byte** global_subrs; + + /* array of pointers into String INDEX data stored at string_pool */ + FT_UInt num_strings; + FT_Byte** strings; + FT_Byte* string_pool; + FT_ULong string_pool_size; + + CFF_SubFontRec top_font; + FT_UInt num_subfonts; + CFF_SubFont subfonts[CFF_MAX_CID_FONTS]; + + CFF_FDSelectRec fd_select; + + /* interface to PostScript hinter */ + PSHinter_Service pshinter; + + /* interface to Postscript Names service */ + FT_Service_PsCMaps psnames; + + /* interface to CFFLoad service */ + const void* cffload; + + /* since version 2.3.0 */ + PS_FontInfoRec* font_info; /* font info dictionary */ + + /* since version 2.3.6 */ + FT_String* registry; + FT_String* ordering; + + /* since version 2.4.12 */ + FT_Generic cf2_instance; + + /* since version 2.7.1 */ + CFF_VStoreRec vstore; /* parsed vstore structure */ + + /* since version 2.9 */ + PS_FontExtraRec* font_extra; + + } CFF_FontRec; + + +FT_END_HEADER + +#endif /* CFFTYPES_H_ */ + + +/* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/ftcalc.h b/src/3rdparty/freetype/include/freetype/internal/ftcalc.h index 67ade7e5f9..818a812359 100644 --- a/src/3rdparty/freetype/include/freetype/internal/ftcalc.h +++ b/src/3rdparty/freetype/include/freetype/internal/ftcalc.h @@ -4,7 +4,7 @@ /* */ /* Arithmetic computations (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTCALC_H__ -#define __FTCALC_H__ +#ifndef FTCALC_H_ +#define FTCALC_H_ #include <ft2build.h> @@ -47,7 +47,7 @@ FT_BEGIN_HEADER FT_MulFix_arm( FT_Int32 a, FT_Int32 b ) { - register FT_Int32 t, t2; + FT_Int32 t, t2; __asm @@ -80,7 +80,7 @@ FT_BEGIN_HEADER FT_MulFix_arm( FT_Int32 a, FT_Int32 b ) { - register FT_Int32 t, t2; + FT_Int32 t, t2; __asm__ __volatile__ ( @@ -116,7 +116,7 @@ FT_BEGIN_HEADER FT_MulFix_i386( FT_Int32 a, FT_Int32 b ) { - register FT_Int32 result; + FT_Int32 result; __asm__ __volatile__ ( @@ -152,7 +152,7 @@ FT_BEGIN_HEADER FT_MulFix_i386( FT_Int32 a, FT_Int32 b ) { - register FT_Int32 result; + FT_Int32 result; __asm { @@ -399,20 +399,46 @@ FT_BEGIN_HEADER #endif /* 0 */ -#define INT_TO_F26DOT6( x ) ( (FT_Long)(x) << 6 ) -#define INT_TO_F2DOT14( x ) ( (FT_Long)(x) << 14 ) -#define INT_TO_FIXED( x ) ( (FT_Long)(x) << 16 ) -#define F2DOT14_TO_FIXED( x ) ( (FT_Long)(x) << 2 ) -#define FLOAT_TO_FIXED( x ) ( (FT_Long)( x * 65536.0 ) ) +#define INT_TO_F26DOT6( x ) ( (FT_Long)(x) * 64 ) /* << 6 */ +#define INT_TO_F2DOT14( x ) ( (FT_Long)(x) * 16384 ) /* << 14 */ +#define INT_TO_FIXED( x ) ( (FT_Long)(x) * 65536 ) /* << 16 */ +#define F2DOT14_TO_FIXED( x ) ( (FT_Long)(x) * 4 ) /* << 2 */ #define FIXED_TO_INT( x ) ( FT_RoundFix( x ) >> 16 ) #define ROUND_F26DOT6( x ) ( x >= 0 ? ( ( (x) + 32 ) & -64 ) \ : ( -( ( 32 - (x) ) & -64 ) ) ) + /* + * The following macros have two purposes. + * + * . Tag places where overflow is expected and harmless. + * + * . Avoid run-time sanitizer errors. + * + * Use with care! + */ +#define ADD_LONG( a, b ) \ + (FT_Long)( (FT_ULong)(a) + (FT_ULong)(b) ) +#define SUB_LONG( a, b ) \ + (FT_Long)( (FT_ULong)(a) - (FT_ULong)(b) ) +#define MUL_LONG( a, b ) \ + (FT_Long)( (FT_ULong)(a) * (FT_ULong)(b) ) +#define NEG_LONG( a ) \ + (FT_Long)( (FT_ULong)0 - (FT_ULong)(a) ) + +#define ADD_INT32( a, b ) \ + (FT_Int32)( (FT_UInt32)(a) + (FT_UInt32)(b) ) +#define SUB_INT32( a, b ) \ + (FT_Int32)( (FT_UInt32)(a) - (FT_UInt32)(b) ) +#define MUL_INT32( a, b ) \ + (FT_Int32)( (FT_UInt32)(a) * (FT_UInt32)(b) ) +#define NEG_INT32( a ) \ + (FT_Int32)( (FT_UInt32)0 - (FT_UInt32)(a) ) + FT_END_HEADER -#endif /* __FTCALC_H__ */ +#endif /* FTCALC_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/ftdebug.h b/src/3rdparty/freetype/include/freetype/internal/ftdebug.h index 216c73031e..292a4eedb8 100644 --- a/src/3rdparty/freetype/include/freetype/internal/ftdebug.h +++ b/src/3rdparty/freetype/include/freetype/internal/ftdebug.h @@ -4,7 +4,7 @@ /* */ /* Debugging and logging component (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,8 +21,8 @@ /***************************************************************************/ -#ifndef __FTDEBUG_H__ -#define __FTDEBUG_H__ +#ifndef FTDEBUG_H_ +#define FTDEBUG_H_ #include <ft2build.h> @@ -249,7 +249,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTDEBUG_H__ */ +#endif /* FTDEBUG_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/ftdrv.h b/src/3rdparty/freetype/include/freetype/internal/ftdrv.h new file mode 100644 index 0000000000..58dd35a933 --- /dev/null +++ b/src/3rdparty/freetype/include/freetype/internal/ftdrv.h @@ -0,0 +1,400 @@ +/***************************************************************************/ +/* */ +/* ftdrv.h */ +/* */ +/* FreeType internal font driver interface (specification). */ +/* */ +/* Copyright 1996-2018 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef FTDRV_H_ +#define FTDRV_H_ + + +#include <ft2build.h> +#include FT_MODULE_H + + +FT_BEGIN_HEADER + + + typedef FT_Error + (*FT_Face_InitFunc)( FT_Stream stream, + FT_Face face, + FT_Int typeface_index, + FT_Int num_params, + FT_Parameter* parameters ); + + typedef void + (*FT_Face_DoneFunc)( FT_Face face ); + + + typedef FT_Error + (*FT_Size_InitFunc)( FT_Size size ); + + typedef void + (*FT_Size_DoneFunc)( FT_Size size ); + + + typedef FT_Error + (*FT_Slot_InitFunc)( FT_GlyphSlot slot ); + + typedef void + (*FT_Slot_DoneFunc)( FT_GlyphSlot slot ); + + + typedef FT_Error + (*FT_Size_RequestFunc)( FT_Size size, + FT_Size_Request req ); + + typedef FT_Error + (*FT_Size_SelectFunc)( FT_Size size, + FT_ULong size_index ); + + typedef FT_Error + (*FT_Slot_LoadFunc)( FT_GlyphSlot slot, + FT_Size size, + FT_UInt glyph_index, + FT_Int32 load_flags ); + + + typedef FT_Error + (*FT_Face_GetKerningFunc)( FT_Face face, + FT_UInt left_glyph, + FT_UInt right_glyph, + FT_Vector* kerning ); + + + typedef FT_Error + (*FT_Face_AttachFunc)( FT_Face face, + FT_Stream stream ); + + + typedef FT_Error + (*FT_Face_GetAdvancesFunc)( FT_Face face, + FT_UInt first, + FT_UInt count, + FT_Int32 flags, + FT_Fixed* advances ); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Driver_ClassRec */ + /* */ + /* <Description> */ + /* The font driver class. This structure mostly contains pointers to */ + /* driver methods. */ + /* */ + /* <Fields> */ + /* root :: The parent module. */ + /* */ + /* face_object_size :: The size of a face object in bytes. */ + /* */ + /* size_object_size :: The size of a size object in bytes. */ + /* */ + /* slot_object_size :: The size of a glyph object in bytes. */ + /* */ + /* init_face :: The format-specific face constructor. */ + /* */ + /* done_face :: The format-specific face destructor. */ + /* */ + /* init_size :: The format-specific size constructor. */ + /* */ + /* done_size :: The format-specific size destructor. */ + /* */ + /* init_slot :: The format-specific slot constructor. */ + /* */ + /* done_slot :: The format-specific slot destructor. */ + /* */ + /* */ + /* load_glyph :: A function handle to load a glyph to a slot. */ + /* This field is mandatory! */ + /* */ + /* get_kerning :: A function handle to return the unscaled */ + /* kerning for a given pair of glyphs. Can be */ + /* set to 0 if the format doesn't support */ + /* kerning. */ + /* */ + /* attach_file :: This function handle is used to read */ + /* additional data for a face from another */ + /* file/stream. For example, this can be used to */ + /* add data from AFM or PFM files on a Type 1 */ + /* face, or a CIDMap on a CID-keyed face. */ + /* */ + /* get_advances :: A function handle used to return advance */ + /* widths of `count' glyphs (in font units), */ + /* starting at `first'. The `vertical' flag must */ + /* be set to get vertical advance heights. The */ + /* `advances' buffer is caller-allocated. */ + /* The idea of this function is to be able to */ + /* perform device-independent text layout without */ + /* loading a single glyph image. */ + /* */ + /* request_size :: A handle to a function used to request the new */ + /* character size. Can be set to 0 if the */ + /* scaling done in the base layer suffices. */ + /* */ + /* select_size :: A handle to a function used to select a new */ + /* fixed size. It is used only if */ + /* @FT_FACE_FLAG_FIXED_SIZES is set. Can be set */ + /* to 0 if the scaling done in the base layer */ + /* suffices. */ + /* <Note> */ + /* Most function pointers, with the exception of `load_glyph', can be */ + /* set to 0 to indicate a default behaviour. */ + /* */ + typedef struct FT_Driver_ClassRec_ + { + FT_Module_Class root; + + FT_Long face_object_size; + FT_Long size_object_size; + FT_Long slot_object_size; + + FT_Face_InitFunc init_face; + FT_Face_DoneFunc done_face; + + FT_Size_InitFunc init_size; + FT_Size_DoneFunc done_size; + + FT_Slot_InitFunc init_slot; + FT_Slot_DoneFunc done_slot; + + FT_Slot_LoadFunc load_glyph; + + FT_Face_GetKerningFunc get_kerning; + FT_Face_AttachFunc attach_file; + FT_Face_GetAdvancesFunc get_advances; + + /* since version 2.2 */ + FT_Size_RequestFunc request_size; + FT_Size_SelectFunc select_size; + + } FT_Driver_ClassRec, *FT_Driver_Class; + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_DECLARE_DRIVER */ + /* */ + /* <Description> */ + /* Used to create a forward declaration of an FT_Driver_ClassRec */ + /* struct instance. */ + /* */ + /* <Macro> */ + /* FT_DEFINE_DRIVER */ + /* */ + /* <Description> */ + /* Used to initialize an instance of FT_Driver_ClassRec struct. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is defined a `create' function has to be */ + /* called with a pointer where the allocated structure is returned. */ + /* And when it is no longer needed a `destroy' function needs to be */ + /* called to release that allocation. */ + /* */ + /* `ftinit.c' (ft_create_default_module_classes) already contains a */ + /* mechanism to call these functions for the default modules */ + /* described in `ftmodule.h'. */ + /* */ + /* Notice that the created `create' and `destroy' functions call */ + /* `pic_init' and `pic_free' to allow you to manually allocate and */ + /* initialize any additional global data, like a module specific */ + /* interface, and put them in the global pic container defined in */ + /* `ftpic.h'. If you don't need them just implement the functions as */ + /* empty to resolve the link error. Also the `pic_init' and */ + /* `pic_free' functions should be declared in `pic.h', to be referred */ + /* by driver definition calling `FT_DEFINE_DRIVER' in following. */ + /* */ + /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ + /* allocated in the global scope (or the scope where the macro is */ + /* used). */ + /* */ +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DECLARE_DRIVER( class_ ) \ + FT_CALLBACK_TABLE \ + const FT_Driver_ClassRec class_; + +#define FT_DEFINE_DRIVER( \ + class_, \ + flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_, \ + face_object_size_, \ + size_object_size_, \ + slot_object_size_, \ + init_face_, \ + done_face_, \ + init_size_, \ + done_size_, \ + init_slot_, \ + done_slot_, \ + load_glyph_, \ + get_kerning_, \ + attach_file_, \ + get_advances_, \ + request_size_, \ + select_size_ ) \ + FT_CALLBACK_TABLE_DEF \ + const FT_Driver_ClassRec class_ = \ + { \ + FT_DEFINE_ROOT_MODULE( flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_ ) \ + \ + face_object_size_, \ + size_object_size_, \ + slot_object_size_, \ + \ + init_face_, \ + done_face_, \ + \ + init_size_, \ + done_size_, \ + \ + init_slot_, \ + done_slot_, \ + \ + load_glyph_, \ + \ + get_kerning_, \ + attach_file_, \ + get_advances_, \ + \ + request_size_, \ + select_size_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DECLARE_DRIVER( class_ ) FT_DECLARE_MODULE( class_ ) + +#define FT_DEFINE_DRIVER( \ + class_, \ + flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_, \ + face_object_size_, \ + size_object_size_, \ + slot_object_size_, \ + init_face_, \ + done_face_, \ + init_size_, \ + done_size_, \ + init_slot_, \ + done_slot_, \ + load_glyph_, \ + get_kerning_, \ + attach_file_, \ + get_advances_, \ + request_size_, \ + select_size_ ) \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_Module_Class* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + FT_Driver_Class dclazz = (FT_Driver_Class)clazz; \ + \ + \ + class_ ## _pic_free( library ); \ + if ( dclazz ) \ + FT_FREE( dclazz ); \ + } \ + \ + \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_Module_Class** output_class ) \ + { \ + FT_Driver_Class clazz = NULL; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + \ + if ( FT_ALLOC( clazz, sizeof ( *clazz ) ) ) \ + return error; \ + \ + error = class_ ## _pic_init( library ); \ + if ( error ) \ + { \ + FT_FREE( clazz ); \ + return error; \ + } \ + \ + FT_DEFINE_ROOT_MODULE( flags_, \ + size_, \ + name_, \ + version_, \ + requires_, \ + interface_, \ + init_, \ + done_, \ + get_interface_ ) \ + \ + clazz->face_object_size = face_object_size_; \ + clazz->size_object_size = size_object_size_; \ + clazz->slot_object_size = slot_object_size_; \ + \ + clazz->init_face = init_face_; \ + clazz->done_face = done_face_; \ + \ + clazz->init_size = init_size_; \ + clazz->done_size = done_size_; \ + \ + clazz->init_slot = init_slot_; \ + clazz->done_slot = done_slot_; \ + \ + clazz->load_glyph = load_glyph_; \ + \ + clazz->get_kerning = get_kerning_; \ + clazz->attach_file = attach_file_; \ + clazz->get_advances = get_advances_; \ + \ + clazz->request_size = request_size_; \ + clazz->select_size = select_size_; \ + \ + *output_class = (FT_Module_Class*)clazz; \ + \ + return FT_Err_Ok; \ + } + + +#endif /* FT_CONFIG_OPTION_PIC */ + +FT_END_HEADER + +#endif /* FTDRV_H_ */ + + +/* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/ftgloadr.h b/src/3rdparty/freetype/include/freetype/internal/ftgloadr.h index 970dd70cc3..a002fdbfca 100644 --- a/src/3rdparty/freetype/include/freetype/internal/ftgloadr.h +++ b/src/3rdparty/freetype/include/freetype/internal/ftgloadr.h @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph loader (specification). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTGLOADR_H__ -#define __FTGLOADR_H__ +#ifndef FTGLOADR_H_ +#define FTGLOADR_H_ #include <ft2build.h> @@ -36,24 +36,6 @@ FT_BEGIN_HEADER /* The glyph loader is an internal object used to load several glyphs */ /* together (for example, in the case of composites). */ /* */ - /* <Note> */ - /* The glyph loader implementation is not part of the high-level API, */ - /* hence the forward structure declaration. */ - /* */ - typedef struct FT_GlyphLoaderRec_* FT_GlyphLoader ; - - -#if 0 /* moved to freetype.h in version 2.2 */ -#define FT_SUBGLYPH_FLAG_ARGS_ARE_WORDS 1 -#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES 2 -#define FT_SUBGLYPH_FLAG_ROUND_XY_TO_GRID 4 -#define FT_SUBGLYPH_FLAG_SCALE 8 -#define FT_SUBGLYPH_FLAG_XY_SCALE 0x40 -#define FT_SUBGLYPH_FLAG_2X2 0x80 -#define FT_SUBGLYPH_FLAG_USE_MY_METRICS 0x200 -#endif - - typedef struct FT_SubGlyphRec_ { FT_Int index; @@ -89,7 +71,7 @@ FT_BEGIN_HEADER void* other; /* for possible future extension? */ - } FT_GlyphLoaderRec; + } FT_GlyphLoaderRec, *FT_GlyphLoader; /* create new empty glyph loader */ @@ -166,7 +148,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTGLOADR_H__ */ +#endif /* FTGLOADR_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/fthash.h b/src/3rdparty/freetype/include/freetype/internal/fthash.h new file mode 100644 index 0000000000..f22f9d5d39 --- /dev/null +++ b/src/3rdparty/freetype/include/freetype/internal/fthash.h @@ -0,0 +1,136 @@ +/***************************************************************************/ +/* */ +/* fthash.h */ +/* */ +/* Hashing functions (specification). */ +/* */ +/***************************************************************************/ + +/* + * Copyright 2000 Computing Research Labs, New Mexico State University + * Copyright 2001-2015 + * Francesco Zappa Nardelli + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT + * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + /*************************************************************************/ + /* */ + /* This file is based on code from bdf.c,v 1.22 2000/03/16 20:08:50 */ + /* */ + /* taken from Mark Leisher's xmbdfed package */ + /* */ + /*************************************************************************/ + + +#ifndef FTHASH_H_ +#define FTHASH_H_ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + typedef union FT_Hashkey_ + { + FT_Int num; + const char* str; + + } FT_Hashkey; + + + typedef struct FT_HashnodeRec_ + { + FT_Hashkey key; + size_t data; + + } FT_HashnodeRec; + + typedef struct FT_HashnodeRec_ *FT_Hashnode; + + + typedef FT_ULong + (*FT_Hash_LookupFunc)( FT_Hashkey* key ); + + typedef FT_Bool + (*FT_Hash_CompareFunc)( FT_Hashkey* a, + FT_Hashkey* b ); + + + typedef struct FT_HashRec_ + { + FT_UInt limit; + FT_UInt size; + FT_UInt used; + + FT_Hash_LookupFunc lookup; + FT_Hash_CompareFunc compare; + + FT_Hashnode* table; + + } FT_HashRec; + + typedef struct FT_HashRec_ *FT_Hash; + + + FT_Error + ft_hash_str_init( FT_Hash hash, + FT_Memory memory ); + + FT_Error + ft_hash_num_init( FT_Hash hash, + FT_Memory memory ); + + void + ft_hash_str_free( FT_Hash hash, + FT_Memory memory ); + +#define ft_hash_num_free ft_hash_str_free + + FT_Error + ft_hash_str_insert( const char* key, + size_t data, + FT_Hash hash, + FT_Memory memory ); + + FT_Error + ft_hash_num_insert( FT_Int num, + size_t data, + FT_Hash hash, + FT_Memory memory ); + + size_t* + ft_hash_str_lookup( const char* key, + FT_Hash hash ); + + size_t* + ft_hash_num_lookup( FT_Int num, + FT_Hash hash ); + + +FT_END_HEADER + + +#endif /* FTHASH_H_ */ + + +/* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/ftmemory.h b/src/3rdparty/freetype/include/freetype/internal/ftmemory.h index c0c553b4fc..054eaec31f 100644 --- a/src/3rdparty/freetype/include/freetype/internal/ftmemory.h +++ b/src/3rdparty/freetype/include/freetype/internal/ftmemory.h @@ -4,7 +4,7 @@ /* */ /* The FreeType memory management macros (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTMEMORY_H__ -#define __FTMEMORY_H__ +#ifndef FTMEMORY_H_ +#define FTMEMORY_H_ #include <ft2build.h> @@ -65,13 +65,15 @@ FT_BEGIN_HEADER #ifdef __cplusplus - extern "C++" +extern "C++" +{ template <typename T> inline T* cplusplus_typeof( T*, void *v ) { return static_cast <T*> ( v ); } +} #define FT_ASSIGNP( p, val ) (p) = cplusplus_typeof( (p), (val) ) @@ -106,10 +108,12 @@ FT_BEGIN_HEADER /* * The allocation functions return a pointer, and the error code - * is written to through the `p_error' parameter. See below for - * for documentation. + * is written to through the `p_error' parameter. */ + /* The `q' variants of the functions below (`q' for `quick') don't fill */ + /* the allocated or reallocated memory with zero bytes. */ + FT_BASE( FT_Pointer ) ft_mem_alloc( FT_Memory memory, FT_Long size, @@ -141,6 +145,9 @@ FT_BEGIN_HEADER const void* P ); + /* The `Q' variants of the macros below (`Q' for `quick') don't fill */ + /* the allocated or reallocated memory with zero bytes. */ + #define FT_MEM_ALLOC( ptr, size ) \ FT_ASSIGNP_INNER( ptr, ft_mem_alloc( memory, \ (FT_Long)(size), \ @@ -203,7 +210,7 @@ FT_BEGIN_HEADER NULL, \ &error ) ) -#define FT_MEM_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz) \ +#define FT_MEM_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz ) \ FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \ (FT_Long)(itmsz), \ (FT_Long)(oldcnt), \ @@ -380,7 +387,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTMEMORY_H__ */ +#endif /* FTMEMORY_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/ftobjs.h b/src/3rdparty/freetype/include/freetype/internal/ftobjs.h index da5582dc3f..1c3c6ad456 100644 --- a/src/3rdparty/freetype/include/freetype/internal/ftobjs.h +++ b/src/3rdparty/freetype/include/freetype/internal/ftobjs.h @@ -4,7 +4,7 @@ /* */ /* The FreeType private base classes (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,8 +23,8 @@ /*************************************************************************/ -#ifndef __FTOBJS_H__ -#define __FTOBJS_H__ +#ifndef FTOBJS_H_ +#define FTOBJS_H_ #include <ft2build.h> #include FT_RENDER_H @@ -36,6 +36,7 @@ #include FT_INTERNAL_AUTOHINT_H #include FT_INTERNAL_SERVICE_H #include FT_INTERNAL_PIC_H +#include FT_INTERNAL_CALC_H #ifdef FT_CONFIG_OPTION_INCREMENTAL #include FT_INCREMENTAL_H @@ -84,14 +85,30 @@ FT_BEGIN_HEADER : y + ( 3 * x >> 3 ) ) /* we use FT_TYPEOF to suppress signedness compilation warnings */ -#define FT_PAD_FLOOR( x, n ) ( (x) & ~FT_TYPEOF( x )( (n)-1 ) ) -#define FT_PAD_ROUND( x, n ) FT_PAD_FLOOR( (x) + ((n)/2), n ) -#define FT_PAD_CEIL( x, n ) FT_PAD_FLOOR( (x) + ((n)-1), n ) +#define FT_PAD_FLOOR( x, n ) ( (x) & ~FT_TYPEOF( x )( (n) - 1 ) ) +#define FT_PAD_ROUND( x, n ) FT_PAD_FLOOR( (x) + (n) / 2, n ) +#define FT_PAD_CEIL( x, n ) FT_PAD_FLOOR( (x) + (n) - 1, n ) #define FT_PIX_FLOOR( x ) ( (x) & ~FT_TYPEOF( x )63 ) #define FT_PIX_ROUND( x ) FT_PIX_FLOOR( (x) + 32 ) #define FT_PIX_CEIL( x ) FT_PIX_FLOOR( (x) + 63 ) + /* specialized versions (for signed values) */ + /* that don't produce run-time errors due to integer overflow */ +#define FT_PAD_ROUND_LONG( x, n ) FT_PAD_FLOOR( ADD_LONG( (x), (n) / 2 ), \ + n ) +#define FT_PAD_CEIL_LONG( x, n ) FT_PAD_FLOOR( ADD_LONG( (x), (n) - 1 ), \ + n ) +#define FT_PIX_ROUND_LONG( x ) FT_PIX_FLOOR( ADD_LONG( (x), 32 ) ) +#define FT_PIX_CEIL_LONG( x ) FT_PIX_FLOOR( ADD_LONG( (x), 63 ) ) + +#define FT_PAD_ROUND_INT32( x, n ) FT_PAD_FLOOR( ADD_INT32( (x), (n) / 2 ), \ + n ) +#define FT_PAD_CEIL_INT32( x, n ) FT_PAD_FLOOR( ADD_INT32( (x), (n) - 1 ), \ + n ) +#define FT_PIX_ROUND_INT32( x ) FT_PIX_FLOOR( ADD_INT32( (x), 32 ) ) +#define FT_PIX_CEIL_INT32( x ) FT_PIX_FLOOR( ADD_INT32( (x), 63 ) ) + /* * character classification functions -- since these are used to parse @@ -138,8 +155,8 @@ FT_BEGIN_HEADER } FT_CMapRec; - /* typecase any pointer to a charmap handle */ -#define FT_CMAP( x ) ((FT_CMap)( x )) + /* typecast any pointer to a charmap handle */ +#define FT_CMAP( x ) ( (FT_CMap)( x ) ) /* obvious macros */ #define FT_CMAP_PLATFORM_ID( x ) FT_CMAP( x )->charmap.platform_id @@ -193,6 +210,7 @@ FT_BEGIN_HEADER typedef struct FT_CMap_ClassRec_ { FT_ULong size; + FT_CMap_InitFunc init; FT_CMap_DoneFunc done; FT_CMap_CharIndexFunc char_index; @@ -294,6 +312,27 @@ FT_BEGIN_HEADER FT_CMap_Done( FT_CMap cmap ); + /* adds LCD padding to Min and Max boundaries */ + FT_BASE( void ) + ft_lcd_padding( FT_Pos* Min, + FT_Pos* Max, + FT_GlyphSlot slot ); + +#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING + + typedef void (*FT_Bitmap_LcdFilterFunc)( FT_Bitmap* bitmap, + FT_Render_Mode render_mode, + FT_Byte* weights ); + + + /* This is the default LCD filter, an in-place, 5-tap FIR filter. */ + FT_BASE( void ) + ft_lcd_filter_fir( FT_Bitmap* bitmap, + FT_Render_Mode mode, + FT_LcdFiveTapFilter weights ); + +#endif /* FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ + /*************************************************************************/ /* */ /* <Struct> */ @@ -341,11 +380,20 @@ FT_BEGIN_HEADER /* this data when first opened. This field exists only if */ /* @FT_CONFIG_OPTION_INCREMENTAL is defined. */ /* */ - /* ignore_unpatented_hinter :: */ - /* This boolean flag instructs the glyph loader to ignore the */ - /* native font hinter, if one is found. This is exclusively used */ - /* in the case when the unpatented hinter is compiled within the */ - /* library. */ + /* no_stem_darkening :: */ + /* Overrides the module-level default, see @stem-darkening[cff], */ + /* for example. FALSE and TRUE toggle stem darkening on and off, */ + /* respectively, value~-1 means to use the module/driver default. */ + /* */ + /* random_seed :: */ + /* If positive, override the seed value for the CFF `random' */ + /* operator. Value~0 means to use the font's value. Value~-1 */ + /* means to use the CFF driver's default. */ + /* */ + /* lcd_weights :: */ + /* lcd_filter_func :: */ + /* If subpixel rendering is activated, the LCD filtering weights */ + /* and callback function. */ /* */ /* refcount :: */ /* A counter initialized to~1 at the time an @FT_Face structure is */ @@ -355,9 +403,9 @@ FT_BEGIN_HEADER /* */ typedef struct FT_Face_InternalRec_ { - FT_Matrix transform_matrix; - FT_Vector transform_delta; - FT_Int transform_flags; + FT_Matrix transform_matrix; + FT_Vector transform_delta; + FT_Int transform_flags; FT_ServiceCacheRec services; @@ -365,8 +413,15 @@ FT_BEGIN_HEADER FT_Incremental_InterfaceRec* incremental_interface; #endif - FT_Bool ignore_unpatented_hinter; - FT_Int refcount; + FT_Char no_stem_darkening; + FT_Int32 random_seed; + +#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING + FT_LcdFiveTapFilter lcd_weights; /* filter weights, if any */ + FT_Bitmap_LcdFilterFunc lcd_filter_func; /* filtering callback */ +#endif + + FT_Int refcount; } FT_Face_InternalRec; @@ -419,8 +474,6 @@ FT_BEGIN_HEADER } FT_GlyphSlot_InternalRec; -#if 0 - /*************************************************************************/ /* */ /* <Struct> */ @@ -428,18 +481,26 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* This structure contains the internal fields of each FT_Size */ - /* object. Currently, it's empty. */ + /* object. */ + /* */ + /* <Fields> */ + /* module_data :: Data specific to a driver module. */ + /* */ + /* autohint_mode :: The used auto-hinting mode. */ + /* */ + /* autohint_metrics :: Metrics used by the auto-hinter. */ /* */ /*************************************************************************/ typedef struct FT_Size_InternalRec_ { - /* empty */ + void* module_data; + + FT_Render_Mode autohint_mode; + FT_Size_Metrics autohint_metrics; } FT_Size_InternalRec; -#endif - /*************************************************************************/ /*************************************************************************/ @@ -479,7 +540,8 @@ FT_BEGIN_HEADER /* typecast an object to an FT_Module */ -#define FT_MODULE( x ) ((FT_Module)( x )) +#define FT_MODULE( x ) ( (FT_Module)(x) ) + #define FT_MODULE_CLASS( x ) FT_MODULE( x )->clazz #define FT_MODULE_LIBRARY( x ) FT_MODULE( x )->library #define FT_MODULE_MEMORY( x ) FT_MODULE( x )->memory @@ -506,6 +568,9 @@ FT_BEGIN_HEADER #define FT_DRIVER_HAS_HINTER( x ) ( FT_MODULE_CLASS( x )->module_flags & \ FT_MODULE_DRIVER_HAS_HINTER ) +#define FT_DRIVER_HINTS_LIGHTLY( x ) ( FT_MODULE_CLASS( x )->module_flags & \ + FT_MODULE_DRIVER_HINTS_LIGHTLY ) + /*************************************************************************/ /* */ @@ -534,7 +599,16 @@ FT_BEGIN_HEADER FT_BASE( FT_Pointer ) ft_module_get_service( FT_Module module, - const char* service_id ); + const char* service_id, + FT_Bool global ); + +#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + FT_BASE( FT_Error ) + ft_property_string_set( FT_Library library, + const FT_String* module_name, + const FT_String* property_name, + FT_String* value ); +#endif /* */ @@ -553,9 +627,9 @@ FT_BEGIN_HEADER /* a few macros used to perform easy typecasts with minimal brain damage */ -#define FT_FACE( x ) ((FT_Face)(x)) -#define FT_SIZE( x ) ((FT_Size)(x)) -#define FT_SLOT( x ) ((FT_GlyphSlot)(x)) +#define FT_FACE( x ) ( (FT_Face)(x) ) +#define FT_SIZE( x ) ( (FT_Size)(x) ) +#define FT_SLOT( x ) ( (FT_GlyphSlot)(x) ) #define FT_FACE_DRIVER( x ) FT_FACE( x )->driver #define FT_FACE_LIBRARY( x ) FT_FACE_DRIVER( x )->root.library @@ -656,6 +730,12 @@ FT_BEGIN_HEADER ft_glyphslot_free_bitmap( FT_GlyphSlot slot ); + /* Preset bitmap metrics of an outline glyphslot prior to rendering. */ + FT_BASE( void ) + ft_glyphslot_preset_bitmap( FT_GlyphSlot slot, + FT_Render_Mode mode, + const FT_Vector* origin ); + /* Allocate a new bitmap buffer in a glyph slot. */ FT_BASE( FT_Error ) ft_glyphslot_alloc_bitmap( FT_GlyphSlot slot, @@ -682,10 +762,10 @@ FT_BEGIN_HEADER /*************************************************************************/ -#define FT_RENDERER( x ) ((FT_Renderer)( x )) -#define FT_GLYPH( x ) ((FT_Glyph)( x )) -#define FT_BITMAP_GLYPH( x ) ((FT_BitmapGlyph)( x )) -#define FT_OUTLINE_GLYPH( x ) ((FT_OutlineGlyph)( x )) +#define FT_RENDERER( x ) ( (FT_Renderer)(x) ) +#define FT_GLYPH( x ) ( (FT_Glyph)(x) ) +#define FT_BITMAP_GLYPH( x ) ( (FT_BitmapGlyph)(x) ) +#define FT_OUTLINE_GLYPH( x ) ( (FT_OutlineGlyph)(x) ) typedef struct FT_RendererRec_ @@ -716,7 +796,7 @@ FT_BEGIN_HEADER /* typecast a module into a driver easily */ -#define FT_DRIVER( x ) ((FT_Driver)(x)) +#define FT_DRIVER( x ) ( (FT_Driver)(x) ) /* typecast a module as a driver, and get its driver class */ #define FT_DRIVER_CLASS( x ) FT_DRIVER( x )->clazz @@ -769,19 +849,7 @@ FT_BEGIN_HEADER /* This hook is used by the TrueType debugger. It must be set to an */ /* alternate truetype bytecode interpreter function. */ -#define FT_DEBUG_HOOK_TRUETYPE 0 - - - /* Set this debug hook to a non-null pointer to force unpatented hinting */ - /* for all faces when both TT_USE_BYTECODE_INTERPRETER and */ - /* TT_CONFIG_OPTION_UNPATENTED_HINTING are defined. This is only used */ - /* during debugging. */ -#define FT_DEBUG_HOOK_UNPATENTED_HINTING 1 - - - typedef void (*FT_Bitmap_LcdFilterFunc)( FT_Bitmap* bitmap, - FT_Render_Mode render_mode, - FT_Library library ); +#define FT_DEBUG_HOOK_TRUETYPE 0 /*************************************************************************/ @@ -822,20 +890,12 @@ FT_BEGIN_HEADER /* handle to the current renderer for the */ /* FT_GLYPH_FORMAT_OUTLINE format. */ /* */ - /* auto_hinter :: XXX */ + /* auto_hinter :: The auto-hinter module interface. */ /* */ - /* raster_pool :: The raster object's render pool. This can */ - /* ideally be changed dynamically at run-time. */ - /* */ - /* raster_pool_size :: The size of the render pool in bytes. */ - /* */ - /* debug_hooks :: XXX */ - /* */ - /* lcd_filter :: If subpixel rendering is activated, the */ - /* selected LCD filter mode. */ - /* */ - /* lcd_extra :: If subpixel rendering is activated, the number */ - /* of extra pixels needed for the LCD filter. */ + /* debug_hooks :: An array of four function pointers that allow */ + /* debuggers to hook into a font format's */ + /* interpreter. Currently, only the TrueType */ + /* bytecode debugger uses this. */ /* */ /* lcd_weights :: If subpixel rendering is activated, the LCD */ /* filter weights, if any. */ @@ -844,7 +904,7 @@ FT_BEGIN_HEADER /* filtering callback function. */ /* */ /* pic_container :: Contains global structs and tables, instead */ - /* of defining them globallly. */ + /* of defining them globally. */ /* */ /* refcount :: A counter initialized to~1 at the time an */ /* @FT_Library structure is created. */ @@ -868,16 +928,10 @@ FT_BEGIN_HEADER FT_Renderer cur_renderer; /* current outline renderer */ FT_Module auto_hinter; - FT_Byte* raster_pool; /* scan-line conversion */ - /* render pool */ - FT_ULong raster_pool_size; /* size of render pool in bytes */ - FT_DebugHook_Func debug_hooks[4]; #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING - FT_LcdFilter lcd_filter; - FT_Int lcd_extra; /* number of extra pixels */ - FT_Byte lcd_weights[7]; /* filter weights, if any */ + FT_LcdFiveTapFilter lcd_weights; /* filter weights, if any */ FT_Bitmap_LcdFilterFunc lcd_filter_func; /* filtering callback */ #endif @@ -982,8 +1036,8 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* Used to initialize an instance of FT_Outline_Funcs struct. */ - /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */ - /* be called with a pre-allocated structure to be filled. */ + /* When FT_CONFIG_OPTION_PIC is defined an init function will need */ + /* to be called with a pre-allocated structure to be filled. */ /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ /* allocated in the global scope (or the scope where the macro */ /* is used). */ @@ -1041,8 +1095,8 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* Used to initialize an instance of FT_Raster_Funcs struct. */ - /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */ - /* be called with a pre-allocated structure to be filled. */ + /* When FT_CONFIG_OPTION_PIC is defined an init function will need */ + /* to be called with a pre-allocated structure to be filled. */ /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ /* allocated in the global scope (or the scope where the macro */ /* is used). */ @@ -1101,8 +1155,8 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* Used to initialize an instance of FT_Glyph_Class struct. */ - /* When FT_CONFIG_OPTION_PIC is defined an init funtion will need to */ - /* be called with a pre-allocated stcture to be filled. */ + /* When FT_CONFIG_OPTION_PIC is defined an init function will need */ + /* to be called with a pre-allocated structure to be filled. */ /* When FT_CONFIG_OPTION_PIC is not defined the struct will be */ /* allocated in the global scope (or the scope where the macro */ /* is used). */ @@ -1175,11 +1229,11 @@ FT_BEGIN_HEADER /* <Description> */ /* Used to initialize an instance of FT_Renderer_Class struct. */ /* */ - /* When FT_CONFIG_OPTION_PIC is defined a `create' funtion will need */ - /* to be called with a pointer where the allocated structure is */ + /* When FT_CONFIG_OPTION_PIC is defined a `create' function will */ + /* need to be called with a pointer where the allocated structure is */ /* returned. And when it is no longer needed a `destroy' function */ /* needs to be called to release that allocation. */ - /* `fcinit.c' (ft_create_default_module_classes) already contains */ + /* `ftinit.c' (ft_create_default_module_classes) already contains */ /* a mechanism to call these functions for the default modules */ /* described in `ftmodule.h'. */ /* */ @@ -1379,11 +1433,11 @@ FT_BEGIN_HEADER /* <Description> */ /* Used to initialize an instance of an FT_Module_Class struct. */ /* */ - /* When FT_CONFIG_OPTION_PIC is defined a `create' funtion needs to */ - /* be called with a pointer where the allocated structure is */ + /* When FT_CONFIG_OPTION_PIC is defined a `create' function needs */ + /* to be called with a pointer where the allocated structure is */ /* returned. And when it is no longer needed a `destroy' function */ /* needs to be called to release that allocation. */ - /* `fcinit.c' (ft_create_default_module_classes) already contains */ + /* `ftinit.c' (ft_create_default_module_classes) already contains */ /* a mechanism to call these functions for the default modules */ /* described in `ftmodule.h'. */ /* */ @@ -1565,7 +1619,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTOBJS_H__ */ +#endif /* FTOBJS_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/ftpic.h b/src/3rdparty/freetype/include/freetype/internal/ftpic.h index 7f9154f419..5214f05989 100644 --- a/src/3rdparty/freetype/include/freetype/internal/ftpic.h +++ b/src/3rdparty/freetype/include/freetype/internal/ftpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services (declaration). */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2018 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,8 +23,8 @@ /*************************************************************************/ -#ifndef __FTPIC_H__ -#define __FTPIC_H__ +#ifndef FTPIC_H_ +#define FTPIC_H_ FT_BEGIN_HEADER @@ -65,7 +65,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTPIC_H__ */ +#endif /* FTPIC_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/ftpsprop.h b/src/3rdparty/freetype/include/freetype/internal/ftpsprop.h new file mode 100644 index 0000000000..abbb62862b --- /dev/null +++ b/src/3rdparty/freetype/include/freetype/internal/ftpsprop.h @@ -0,0 +1,48 @@ +/***************************************************************************/ +/* */ +/* ftpsprop.h */ +/* */ +/* Get and set properties of PostScript drivers (specification). */ +/* */ +/* Copyright 2017-2018 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef FTPSPROP_H_ +#define FTPSPROP_H_ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + FT_BASE_CALLBACK( FT_Error ) + ps_property_set( FT_Module module, /* PS_Driver */ + const char* property_name, + const void* value, + FT_Bool value_is_string ); + + FT_BASE_CALLBACK( FT_Error ) + ps_property_get( FT_Module module, /* PS_Driver */ + const char* property_name, + void* value ); + + +FT_END_HEADER + + +#endif /* FTPSPROP_H_ */ + + +/* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/ftrfork.h b/src/3rdparty/freetype/include/freetype/internal/ftrfork.h index da61ca75b5..1aca48a0e7 100644 --- a/src/3rdparty/freetype/include/freetype/internal/ftrfork.h +++ b/src/3rdparty/freetype/include/freetype/internal/ftrfork.h @@ -4,7 +4,7 @@ /* */ /* Embedded resource forks accessor (specification). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* Masatake YAMATO and Redhat K.K. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,8 +21,8 @@ /***************************************************************************/ -#ifndef __FTRFORK_H__ -#define __FTRFORK_H__ +#ifndef FTRFORK_H_ +#define FTRFORK_H_ #include <ft2build.h> @@ -43,11 +43,12 @@ FT_BEGIN_HEADER typedef struct FT_RFork_Ref_ { - FT_UShort res_id; - FT_Long offset; + FT_Short res_id; + FT_Long offset; } FT_RFork_Ref; + #ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK typedef FT_Error (*ft_raccess_guess_func)( FT_Library library, @@ -227,7 +228,7 @@ FT_BEGIN_HEADER /* sort_by_res_id :: */ /* A Boolean to sort the fragmented resource by their ids. */ /* The fragmented resources for `POST' resource should be sorted */ - /* to restore Type1 font properly. For `snft' resources, sorting */ + /* to restore Type1 font properly. For `sfnt' resources, sorting */ /* may induce a different order of the faces in comparison to that */ /* by QuickDraw API. */ /* */ @@ -260,7 +261,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTRFORK_H__ */ +#endif /* FTRFORK_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/ftserv.h b/src/3rdparty/freetype/include/freetype/internal/ftserv.h index 11a0c7f3de..e01c1679b5 100644 --- a/src/3rdparty/freetype/include/freetype/internal/ftserv.h +++ b/src/3rdparty/freetype/include/freetype/internal/ftserv.h @@ -4,7 +4,7 @@ /* */ /* The FreeType services (specification only). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -28,8 +28,8 @@ /*************************************************************************/ -#ifndef __FTSERV_H__ -#define __FTSERV_H__ +#ifndef FTSERV_H_ +#define FTSERV_H_ FT_BEGIN_HEADER @@ -109,27 +109,27 @@ FT_BEGIN_HEADER */ #ifdef __cplusplus -#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \ - FT_BEGIN_STMNT \ - FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ - FT_Pointer _tmp_; \ - FT_Pointer* _pptr_ = (FT_Pointer*)&(ptr); \ - \ - \ - _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \ - *_pptr_ = _tmp_; \ +#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ + FT_Pointer _tmp_; \ + FT_Pointer* _pptr_ = (FT_Pointer*)&(ptr); \ + \ + \ + _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id, 1 ); \ + *_pptr_ = _tmp_; \ FT_END_STMNT #else /* !C++ */ -#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \ - FT_BEGIN_STMNT \ - FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ - FT_Pointer _tmp_; \ - \ - \ - _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id ); \ - ptr = _tmp_; \ +#define FT_FACE_FIND_GLOBAL_SERVICE( face, ptr, id ) \ + FT_BEGIN_STMNT \ + FT_Module module = FT_MODULE( FT_FACE( face )->driver ); \ + FT_Pointer _tmp_; \ + \ + \ + _tmp_ = ft_module_get_service( module, FT_SERVICE_ID_ ## id, 1 ); \ + ptr = _tmp_; \ FT_END_STMNT #endif /* !C++ */ @@ -167,6 +167,7 @@ FT_BEGIN_HEADER /* FT_DEFINE_SERVICEDESCREC5 */ /* FT_DEFINE_SERVICEDESCREC6 */ /* FT_DEFINE_SERVICEDESCREC7 */ + /* FT_DEFINE_SERVICEDESCREC8 */ /* */ /* <Description> */ /* Used to initialize an array of FT_ServiceDescRec structures. */ @@ -283,6 +284,78 @@ FT_BEGIN_HEADER { NULL, NULL } \ }; +#define FT_DEFINE_SERVICEDESCREC8( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, \ + serv_id_5, serv_data_5, \ + serv_id_6, serv_data_6, \ + serv_id_7, serv_data_7, \ + serv_id_8, serv_data_8 ) \ + static const FT_ServiceDescRec class_[] = \ + { \ + { serv_id_1, serv_data_1 }, \ + { serv_id_2, serv_data_2 }, \ + { serv_id_3, serv_data_3 }, \ + { serv_id_4, serv_data_4 }, \ + { serv_id_5, serv_data_5 }, \ + { serv_id_6, serv_data_6 }, \ + { serv_id_7, serv_data_7 }, \ + { serv_id_8, serv_data_8 }, \ + { NULL, NULL } \ + }; + +#define FT_DEFINE_SERVICEDESCREC9( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, \ + serv_id_5, serv_data_5, \ + serv_id_6, serv_data_6, \ + serv_id_7, serv_data_7, \ + serv_id_8, serv_data_8, \ + serv_id_9, serv_data_9 ) \ + static const FT_ServiceDescRec class_[] = \ + { \ + { serv_id_1, serv_data_1 }, \ + { serv_id_2, serv_data_2 }, \ + { serv_id_3, serv_data_3 }, \ + { serv_id_4, serv_data_4 }, \ + { serv_id_5, serv_data_5 }, \ + { serv_id_6, serv_data_6 }, \ + { serv_id_7, serv_data_7 }, \ + { serv_id_8, serv_data_8 }, \ + { serv_id_9, serv_data_9 }, \ + { NULL, NULL } \ + }; + +#define FT_DEFINE_SERVICEDESCREC10( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, \ + serv_id_5, serv_data_5, \ + serv_id_6, serv_data_6, \ + serv_id_7, serv_data_7, \ + serv_id_8, serv_data_8, \ + serv_id_9, serv_data_9, \ + serv_id_10, serv_data_10 ) \ + static const FT_ServiceDescRec class_[] = \ + { \ + { serv_id_1, serv_data_1 }, \ + { serv_id_2, serv_data_2 }, \ + { serv_id_3, serv_data_3 }, \ + { serv_id_4, serv_data_4 }, \ + { serv_id_5, serv_data_5 }, \ + { serv_id_6, serv_data_6 }, \ + { serv_id_7, serv_data_7 }, \ + { serv_id_8, serv_data_8 }, \ + { serv_id_9, serv_data_9 }, \ + { serv_id_10, serv_data_10 }, \ + { NULL, NULL } \ + }; + #else /* FT_CONFIG_OPTION_PIC */ #define FT_DEFINE_SERVICEDESCREC1( class_, \ @@ -510,7 +583,7 @@ FT_BEGIN_HEADER \ FT_Error \ FT_Create_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec** output_class) \ + FT_ServiceDescRec** output_class ) \ { \ FT_ServiceDescRec* clazz = NULL; \ FT_Error error; \ @@ -561,7 +634,7 @@ FT_BEGIN_HEADER \ FT_Error \ FT_Create_Class_ ## class_( FT_Library library, \ - FT_ServiceDescRec** output_class) \ + FT_ServiceDescRec** output_class ) \ { \ FT_ServiceDescRec* clazz = NULL; \ FT_Error error; \ @@ -593,6 +666,183 @@ FT_BEGIN_HEADER return FT_Err_Ok; \ } +#define FT_DEFINE_SERVICEDESCREC8( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, \ + serv_id_5, serv_data_5, \ + serv_id_6, serv_data_6, \ + serv_id_7, serv_data_7, \ + serv_id_8, serv_data_8 ) \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + \ + \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec** output_class ) \ + { \ + FT_ServiceDescRec* clazz = NULL; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + \ + if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 9 ) ) \ + return error; \ + \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = serv_id_3; \ + clazz[2].serv_data = serv_data_3; \ + clazz[3].serv_id = serv_id_4; \ + clazz[3].serv_data = serv_data_4; \ + clazz[4].serv_id = serv_id_5; \ + clazz[4].serv_data = serv_data_5; \ + clazz[5].serv_id = serv_id_6; \ + clazz[5].serv_data = serv_data_6; \ + clazz[6].serv_id = serv_id_7; \ + clazz[6].serv_data = serv_data_7; \ + clazz[7].serv_id = serv_id_8; \ + clazz[7].serv_data = serv_data_8; \ + clazz[8].serv_id = NULL; \ + clazz[8].serv_data = NULL; \ + \ + *output_class = clazz; \ + \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC9( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, \ + serv_id_5, serv_data_5, \ + serv_id_6, serv_data_6, \ + serv_id_7, serv_data_7, \ + serv_id_8, serv_data_8, \ + serv_id_9, serv_data_9 ) \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + \ + \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec** output_class ) \ + { \ + FT_ServiceDescRec* clazz = NULL; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + \ + if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 10 ) ) \ + return error; \ + \ + clazz[0].serv_id = serv_id_1; \ + clazz[0].serv_data = serv_data_1; \ + clazz[1].serv_id = serv_id_2; \ + clazz[1].serv_data = serv_data_2; \ + clazz[2].serv_id = serv_id_3; \ + clazz[2].serv_data = serv_data_3; \ + clazz[3].serv_id = serv_id_4; \ + clazz[3].serv_data = serv_data_4; \ + clazz[4].serv_id = serv_id_5; \ + clazz[4].serv_data = serv_data_5; \ + clazz[5].serv_id = serv_id_6; \ + clazz[5].serv_data = serv_data_6; \ + clazz[6].serv_id = serv_id_7; \ + clazz[6].serv_data = serv_data_7; \ + clazz[7].serv_id = serv_id_8; \ + clazz[7].serv_data = serv_data_8; \ + clazz[8].serv_id = serv_id_9; \ + clazz[8].serv_data = serv_data_9; \ + clazz[9].serv_id = NULL; \ + clazz[9].serv_data = NULL; \ + \ + *output_class = clazz; \ + \ + return FT_Err_Ok; \ + } + +#define FT_DEFINE_SERVICEDESCREC10( class_, \ + serv_id_1, serv_data_1, \ + serv_id_2, serv_data_2, \ + serv_id_3, serv_data_3, \ + serv_id_4, serv_data_4, \ + serv_id_5, serv_data_5, \ + serv_id_6, serv_data_6, \ + serv_id_7, serv_data_7, \ + serv_id_8, serv_data_8, \ + serv_id_9, serv_data_9, \ + serv_id_10, serv_data_10 ) \ + void \ + FT_Destroy_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec* clazz ) \ + { \ + FT_Memory memory = library->memory; \ + \ + \ + if ( clazz ) \ + FT_FREE( clazz ); \ + } \ + \ + FT_Error \ + FT_Create_Class_ ## class_( FT_Library library, \ + FT_ServiceDescRec** output_class ) \ + { \ + FT_ServiceDescRec* clazz = NULL; \ + FT_Error error; \ + FT_Memory memory = library->memory; \ + \ + \ + if ( FT_ALLOC( clazz, sizeof ( *clazz ) * 11 ) ) \ + return error; \ + \ + clazz[ 0].serv_id = serv_id_1; \ + clazz[ 0].serv_data = serv_data_1; \ + clazz[ 1].serv_id = serv_id_2; \ + clazz[ 1].serv_data = serv_data_2; \ + clazz[ 2].serv_id = serv_id_3; \ + clazz[ 2].serv_data = serv_data_3; \ + clazz[ 3].serv_id = serv_id_4; \ + clazz[ 3].serv_data = serv_data_4; \ + clazz[ 4].serv_id = serv_id_5; \ + clazz[ 4].serv_data = serv_data_5; \ + clazz[ 5].serv_id = serv_id_6; \ + clazz[ 5].serv_data = serv_data_6; \ + clazz[ 6].serv_id = serv_id_7; \ + clazz[ 6].serv_data = serv_data_7; \ + clazz[ 7].serv_id = serv_id_8; \ + clazz[ 7].serv_data = serv_data_8; \ + clazz[ 8].serv_id = serv_id_9; \ + clazz[ 8].serv_data = serv_data_9; \ + clazz[ 9].serv_id = serv_id_10; \ + clazz[ 9].serv_data = serv_data_10; \ + clazz[10].serv_id = NULL; \ + clazz[10].serv_data = NULL; \ + \ + *output_class = clazz; \ + \ + return FT_Err_Ok; \ + } + #endif /* FT_CONFIG_OPTION_PIC */ @@ -635,6 +885,7 @@ FT_BEGIN_HEADER { FT_Pointer service_POSTSCRIPT_FONT_NAME; FT_Pointer service_MULTI_MASTERS; + FT_Pointer service_METRICS_VARIATIONS; FT_Pointer service_GLYPH_DICT; FT_Pointer service_PFR_METRICS; FT_Pointer service_WINFNT; @@ -655,7 +906,7 @@ FT_BEGIN_HEADER * FT_FACE_LOOKUP_SERVICE * * @description: - * This macro is used to lookup a service from a face's driver module + * This macro is used to look up a service from a face's driver module * using its cache. * * @input: @@ -735,10 +986,13 @@ FT_BEGIN_HEADER */ #define FT_SERVICE_BDF_H <freetype/internal/services/svbdf.h> +#define FT_SERVICE_CFF_TABLE_LOAD_H <freetype/internal/services/svcfftl.h> #define FT_SERVICE_CID_H <freetype/internal/services/svcid.h> +#define FT_SERVICE_FONT_FORMAT_H <freetype/internal/services/svfntfmt.h> #define FT_SERVICE_GLYPH_DICT_H <freetype/internal/services/svgldict.h> #define FT_SERVICE_GX_VALIDATE_H <freetype/internal/services/svgxval.h> #define FT_SERVICE_KERNING_H <freetype/internal/services/svkern.h> +#define FT_SERVICE_METRICS_VARIATIONS_H <freetype/internal/services/svmetric.h> #define FT_SERVICE_MULTIPLE_MASTERS_H <freetype/internal/services/svmm.h> #define FT_SERVICE_OPENTYPE_VALIDATE_H <freetype/internal/services/svotval.h> #define FT_SERVICE_PFR_H <freetype/internal/services/svpfr.h> @@ -748,16 +1002,15 @@ FT_BEGIN_HEADER #define FT_SERVICE_PROPERTIES_H <freetype/internal/services/svprop.h> #define FT_SERVICE_SFNT_H <freetype/internal/services/svsfnt.h> #define FT_SERVICE_TRUETYPE_ENGINE_H <freetype/internal/services/svtteng.h> +#define FT_SERVICE_TRUETYPE_GLYF_H <freetype/internal/services/svttglyf.h> #define FT_SERVICE_TT_CMAP_H <freetype/internal/services/svttcmap.h> #define FT_SERVICE_WINFNT_H <freetype/internal/services/svwinfnt.h> -#define FT_SERVICE_FONT_FORMAT_H <freetype/internal/services/svfntfmt.h> -#define FT_SERVICE_TRUETYPE_GLYF_H <freetype/internal/services/svttglyf.h> /* */ FT_END_HEADER -#endif /* __FTSERV_H__ */ +#endif /* FTSERV_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/ftstream.h b/src/3rdparty/freetype/include/freetype/internal/ftstream.h index 384e5df305..f90002fe77 100644 --- a/src/3rdparty/freetype/include/freetype/internal/ftstream.h +++ b/src/3rdparty/freetype/include/freetype/internal/ftstream.h @@ -4,7 +4,7 @@ /* */ /* Stream handling (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTSTREAM_H__ -#define __FTSTREAM_H__ +#ifndef FTSTREAM_H_ +#define FTSTREAM_H_ #include <ft2build.h> @@ -165,8 +165,8 @@ FT_BEGIN_HEADER #define FT_BYTE_U32( p, i, s ) ( FT_UINT32( FT_BYTE_( p, i ) ) << (s) ) -#define FT_PEEK_SHORT( p ) FT_INT16( FT_BYTE_U16( p, 0, 8) | \ - FT_BYTE_U16( p, 1, 0) ) +#define FT_PEEK_SHORT( p ) FT_INT16( FT_BYTE_U16( p, 0, 8 ) | \ + FT_BYTE_U16( p, 1, 0 ) ) #define FT_PEEK_USHORT( p ) FT_UINT16( FT_BYTE_U16( p, 0, 8 ) | \ FT_BYTE_U16( p, 1, 0 ) ) @@ -502,7 +502,7 @@ FT_BEGIN_HEADER #define FT_STREAM_READ_AT( position, buffer, count ) \ FT_SET_ERROR( FT_Stream_ReadAt( stream, \ (FT_ULong)(position), \ - (FT_Byte*)buffer, \ + (FT_Byte*)(buffer), \ (FT_ULong)(count) ) ) #define FT_STREAM_READ_FIELDS( fields, object ) \ @@ -530,7 +530,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTSTREAM_H__ */ +#endif /* FTSTREAM_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/fttrace.h b/src/3rdparty/freetype/include/freetype/internal/fttrace.h index 9d28d214d6..8092e41fd7 100644 --- a/src/3rdparty/freetype/include/freetype/internal/fttrace.h +++ b/src/3rdparty/freetype/include/freetype/internal/fttrace.h @@ -4,7 +4,7 @@ /* */ /* Tracing handling (specification only). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -39,6 +39,7 @@ FT_TRACE_DEF( mm ) /* MM interface (ftmm.c) */ FT_TRACE_DEF( raccess ) /* resource fork accessor (ftrfork.c) */ FT_TRACE_DEF( synth ) /* bold/slant synthesizer (ftsynth.c) */ FT_TRACE_DEF( bitmap ) /* bitmap checksum (ftobjs.c) */ +FT_TRACE_DEF( psprops ) /* PS driver properties (ftpsprop.c) */ /* Cache sub-system */ FT_TRACE_DEF( cache ) /* cache sub-system (ftcache.c, etc.) */ @@ -66,20 +67,19 @@ FT_TRACE_DEF( ttgxvar ) /* TrueType GX var handler (ttgxvar.c) */ FT_TRACE_DEF( t1afm ) FT_TRACE_DEF( t1driver ) FT_TRACE_DEF( t1gload ) -FT_TRACE_DEF( t1hint ) FT_TRACE_DEF( t1load ) FT_TRACE_DEF( t1objs ) FT_TRACE_DEF( t1parse ) /* PostScript helper module `psaux' */ FT_TRACE_DEF( t1decode ) +FT_TRACE_DEF( cffdecode ) FT_TRACE_DEF( psobjs ) FT_TRACE_DEF( psconv ) /* PostScript hinting module `pshinter' */ FT_TRACE_DEF( pshrec ) -FT_TRACE_DEF( pshalgo1 ) -FT_TRACE_DEF( pshalgo2 ) +FT_TRACE_DEF( pshalgo ) /* Type 2 driver components */ FT_TRACE_DEF( cffdriver ) @@ -96,7 +96,6 @@ FT_TRACE_DEF( cf2interp ) FT_TRACE_DEF( t42 ) /* CID driver components */ -FT_TRACE_DEF( cidafm ) FT_TRACE_DEF( ciddriver ) FT_TRACE_DEF( cidgload ) FT_TRACE_DEF( cidload ) @@ -148,7 +147,7 @@ FT_TRACE_DEF( afcjk ) FT_TRACE_DEF( aflatin ) FT_TRACE_DEF( aflatin2 ) FT_TRACE_DEF( afwarp ) -FT_TRACE_DEF( afharfbuzz ) +FT_TRACE_DEF( afshaper ) FT_TRACE_DEF( afglobal ) /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/ftvalid.h b/src/3rdparty/freetype/include/freetype/internal/ftvalid.h index 9cda6eef5f..cad47a556d 100644 --- a/src/3rdparty/freetype/include/freetype/internal/ftvalid.h +++ b/src/3rdparty/freetype/include/freetype/internal/ftvalid.h @@ -4,7 +4,7 @@ /* */ /* FreeType validation support (specification). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTVALID_H__ -#define __FTVALID_H__ +#ifndef FTVALID_H_ +#define FTVALID_H_ #include <ft2build.h> #include FT_CONFIG_STANDARD_LIBRARY_H /* for ft_setjmp and ft_longjmp */ @@ -153,7 +153,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTVALID_H__ */ +#endif /* FTVALID_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/internal.h b/src/3rdparty/freetype/include/freetype/internal/internal.h index 809ce59c92..8f546e443b 100644 --- a/src/3rdparty/freetype/include/freetype/internal/internal.h +++ b/src/3rdparty/freetype/include/freetype/internal/internal.h @@ -4,7 +4,7 @@ /* */ /* Internal header files (specification only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -30,7 +30,8 @@ #define FT_INTERNAL_MEMORY_H <freetype/internal/ftmemory.h> #define FT_INTERNAL_DEBUG_H <freetype/internal/ftdebug.h> #define FT_INTERNAL_CALC_H <freetype/internal/ftcalc.h> -#define FT_INTERNAL_DRIVER_H <freetype/internal/ftdriver.h> +#define FT_INTERNAL_HASH_H <freetype/internal/fthash.h> +#define FT_INTERNAL_DRIVER_H <freetype/internal/ftdrv.h> #define FT_INTERNAL_TRACE_H <freetype/internal/fttrace.h> #define FT_INTERNAL_GLYPH_LOADER_H <freetype/internal/ftgloadr.h> #define FT_INTERNAL_SFNT_H <freetype/internal/sfnt.h> @@ -43,10 +44,13 @@ #define FT_INTERNAL_POSTSCRIPT_AUX_H <freetype/internal/psaux.h> #define FT_INTERNAL_POSTSCRIPT_HINTS_H <freetype/internal/pshints.h> -#define FT_INTERNAL_POSTSCRIPT_GLOBALS_H <freetype/internal/psglobal.h> +#define FT_INTERNAL_POSTSCRIPT_PROPS_H <freetype/internal/ftpsprop.h> #define FT_INTERNAL_AUTOHINT_H <freetype/internal/autohint.h> +#define FT_INTERNAL_CFF_TYPES_H <freetype/internal/cfftypes.h> +#define FT_INTERNAL_CFF_OBJECTS_TYPES_H <freetype/internal/cffotypes.h> + #if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ diff --git a/src/3rdparty/freetype/include/freetype/internal/psaux.h b/src/3rdparty/freetype/include/freetype/internal/psaux.h index 1c5f784f52..f77380d25f 100644 --- a/src/3rdparty/freetype/include/freetype/internal/psaux.h +++ b/src/3rdparty/freetype/include/freetype/internal/psaux.h @@ -5,7 +5,7 @@ /* Auxiliary functions and data structures related to PostScript fonts */ /* (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,19 +17,40 @@ /***************************************************************************/ -#ifndef __PSAUX_H__ -#define __PSAUX_H__ +#ifndef PSAUX_H_ +#define PSAUX_H_ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_TYPE1_TYPES_H +#include FT_INTERNAL_HASH_H +#include FT_INTERNAL_TRUETYPE_TYPES_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H +#include FT_INTERNAL_CFF_TYPES_H +#include FT_INTERNAL_CFF_OBJECTS_TYPES_H + FT_BEGIN_HEADER + /***********************************************************************/ + /* */ + /* PostScript modules driver class. */ + /* */ + typedef struct PS_DriverRec_ + { + FT_DriverRec root; + + FT_UInt hinting_engine; + FT_Bool no_stem_darkening; + FT_Int darken_params[8]; + FT_Int32 random_seed; + + } PS_DriverRec, *PS_Driver; + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -438,6 +459,202 @@ FT_BEGIN_HEADER } PS_ParserRec; + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PS BUILDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + typedef struct PS_Builder_ PS_Builder; + typedef const struct PS_Builder_FuncsRec_* PS_Builder_Funcs; + + typedef struct PS_Builder_FuncsRec_ + { + void + (*init)( PS_Builder* ps_builder, + void* builder, + FT_Bool is_t1 ); + + void + (*done)( PS_Builder* builder ); + + } PS_Builder_FuncsRec; + + + /*************************************************************************/ + /* */ + /* <Structure> */ + /* PS_Builder */ + /* */ + /* <Description> */ + /* A structure used during glyph loading to store its outline. */ + /* */ + /* <Fields> */ + /* memory :: The current memory object. */ + /* */ + /* face :: The current face object. */ + /* */ + /* glyph :: The current glyph slot. */ + /* */ + /* loader :: XXX */ + /* */ + /* base :: The base glyph outline. */ + /* */ + /* current :: The current glyph outline. */ + /* */ + /* pos_x :: The horizontal translation (if composite glyph). */ + /* */ + /* pos_y :: The vertical translation (if composite glyph). */ + /* */ + /* left_bearing :: The left side bearing point. */ + /* */ + /* advance :: The horizontal advance vector. */ + /* */ + /* bbox :: Unused. */ + /* */ + /* path_begun :: A flag which indicates that a new path has begun. */ + /* */ + /* load_points :: If this flag is not set, no points are loaded. */ + /* */ + /* no_recurse :: Set but not used. */ + /* */ + /* metrics_only :: A boolean indicating that we only want to compute */ + /* the metrics of a given glyph, not load all of its */ + /* points. */ + /* */ + /* is_t1 :: Set if current font type is Type 1. */ + /* */ + /* funcs :: An array of function pointers for the builder. */ + /* */ + struct PS_Builder_ + { + FT_Memory memory; + FT_Face face; + CFF_GlyphSlot glyph; + FT_GlyphLoader loader; + FT_Outline* base; + FT_Outline* current; + + FT_Pos* pos_x; + FT_Pos* pos_y; + + FT_Vector* left_bearing; + FT_Vector* advance; + + FT_BBox* bbox; /* bounding box */ + FT_Bool path_begun; + FT_Bool load_points; + FT_Bool no_recurse; + + FT_Bool metrics_only; + FT_Bool is_t1; + + PS_Builder_FuncsRec funcs; + + }; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PS DECODER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + +#define PS_MAX_OPERANDS 48 +#define PS_MAX_SUBRS_CALLS 16 /* maximum subroutine nesting; */ + /* only 10 are allowed but there exist */ + /* fonts like `HiraKakuProN-W3.ttf' */ + /* (Hiragino Kaku Gothic ProN W3; */ + /* 8.2d6e1; 2014-12-19) that exceed */ + /* this limit */ + + /* execution context charstring zone */ + + typedef struct PS_Decoder_Zone_ + { + FT_Byte* base; + FT_Byte* limit; + FT_Byte* cursor; + + } PS_Decoder_Zone; + + + typedef FT_Error + (*CFF_Decoder_Get_Glyph_Callback)( TT_Face face, + FT_UInt glyph_index, + FT_Byte** pointer, + FT_ULong* length ); + + typedef void + (*CFF_Decoder_Free_Glyph_Callback)( TT_Face face, + FT_Byte** pointer, + FT_ULong length ); + + + typedef struct PS_Decoder_ + { + PS_Builder builder; + + FT_Fixed stack[PS_MAX_OPERANDS + 1]; + FT_Fixed* top; + + PS_Decoder_Zone zones[PS_MAX_SUBRS_CALLS + 1]; + PS_Decoder_Zone* zone; + + FT_Int flex_state; + FT_Int num_flex_vectors; + FT_Vector flex_vectors[7]; + + CFF_Font cff; + CFF_SubFont current_subfont; /* for current glyph_index */ + FT_Generic* cf2_instance; + + FT_Pos* glyph_width; + FT_Bool width_only; + FT_Int num_hints; + + FT_UInt num_locals; + FT_UInt num_globals; + + FT_Int locals_bias; + FT_Int globals_bias; + + FT_Byte** locals; + FT_Byte** globals; + + FT_Byte** glyph_names; /* for pure CFF fonts only */ + FT_UInt num_glyphs; /* number of glyphs in font */ + + FT_Render_Mode hint_mode; + + FT_Bool seac; + + CFF_Decoder_Get_Glyph_Callback get_glyph_callback; + CFF_Decoder_Free_Glyph_Callback free_glyph_callback; + + /* Type 1 stuff */ + FT_Service_PsCMaps psnames; /* for seac */ + + FT_Int lenIV; /* internal for sub routine calls */ + FT_UInt* locals_len; /* array of subrs length (optional) */ + FT_Hash locals_hash; /* used if `num_subrs' was massaged */ + + FT_Matrix font_matrix; + FT_Vector font_offset; + + PS_Blend blend; /* for multiple master support */ + + FT_Long* buildchar; + FT_UInt len_buildchar; + + } PS_Decoder; + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -652,10 +869,23 @@ FT_BEGIN_HEADER void (*done)( T1_Decoder decoder ); +#ifdef T1_CONFIG_OPTION_OLD_ENGINE FT_Error - (*parse_charstrings)( T1_Decoder decoder, - FT_Byte* base, - FT_UInt len ); + (*parse_charstrings_old)( T1_Decoder decoder, + FT_Byte* base, + FT_UInt len ); +#else + FT_Error + (*parse_metrics)( T1_Decoder decoder, + FT_Byte* base, + FT_UInt len ); +#endif + + FT_Error + (*parse_charstrings)( PS_Decoder* decoder, + FT_Byte* charstring_base, + FT_ULong charstring_len ); + } T1_Decoder_FuncsRec; @@ -678,6 +908,7 @@ FT_BEGIN_HEADER FT_Int num_subrs; FT_Byte** subrs; FT_UInt* subrs_len; /* array of subrs length (optional) */ + FT_Hash subrs_hash; /* used if `num_subrs' was massaged */ FT_Matrix font_matrix; FT_Vector font_offset; @@ -698,9 +929,258 @@ FT_BEGIN_HEADER FT_Bool seac; + FT_Generic cf2_instance; + } T1_DecoderRec; + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CFF BUILDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + typedef struct CFF_Builder_ CFF_Builder; + + + typedef FT_Error + (*CFF_Builder_Check_Points_Func)( CFF_Builder* builder, + FT_Int count ); + + typedef void + (*CFF_Builder_Add_Point_Func)( CFF_Builder* builder, + FT_Pos x, + FT_Pos y, + FT_Byte flag ); + typedef FT_Error + (*CFF_Builder_Add_Point1_Func)( CFF_Builder* builder, + FT_Pos x, + FT_Pos y ); + typedef FT_Error + (*CFF_Builder_Start_Point_Func)( CFF_Builder* builder, + FT_Pos x, + FT_Pos y ); + typedef void + (*CFF_Builder_Close_Contour_Func)( CFF_Builder* builder ); + + typedef FT_Error + (*CFF_Builder_Add_Contour_Func)( CFF_Builder* builder ); + + typedef const struct CFF_Builder_FuncsRec_* CFF_Builder_Funcs; + + typedef struct CFF_Builder_FuncsRec_ + { + void + (*init)( CFF_Builder* builder, + TT_Face face, + CFF_Size size, + CFF_GlyphSlot glyph, + FT_Bool hinting ); + + void + (*done)( CFF_Builder* builder ); + + CFF_Builder_Check_Points_Func check_points; + CFF_Builder_Add_Point_Func add_point; + CFF_Builder_Add_Point1_Func add_point1; + CFF_Builder_Add_Contour_Func add_contour; + CFF_Builder_Start_Point_Func start_point; + CFF_Builder_Close_Contour_Func close_contour; + + } CFF_Builder_FuncsRec; + + + /*************************************************************************/ + /* */ + /* <Structure> */ + /* CFF_Builder */ + /* */ + /* <Description> */ + /* A structure used during glyph loading to store its outline. */ + /* */ + /* <Fields> */ + /* memory :: The current memory object. */ + /* */ + /* face :: The current face object. */ + /* */ + /* glyph :: The current glyph slot. */ + /* */ + /* loader :: The current glyph loader. */ + /* */ + /* base :: The base glyph outline. */ + /* */ + /* current :: The current glyph outline. */ + /* */ + /* pos_x :: The horizontal translation (if composite glyph). */ + /* */ + /* pos_y :: The vertical translation (if composite glyph). */ + /* */ + /* left_bearing :: The left side bearing point. */ + /* */ + /* advance :: The horizontal advance vector. */ + /* */ + /* bbox :: Unused. */ + /* */ + /* path_begun :: A flag which indicates that a new path has begun. */ + /* */ + /* load_points :: If this flag is not set, no points are loaded. */ + /* */ + /* no_recurse :: Set but not used. */ + /* */ + /* metrics_only :: A boolean indicating that we only want to compute */ + /* the metrics of a given glyph, not load all of its */ + /* points. */ + /* */ + /* hints_funcs :: Auxiliary pointer for hinting. */ + /* */ + /* hints_globals :: Auxiliary pointer for hinting. */ + /* */ + /* funcs :: A table of method pointers for this object. */ + /* */ + struct CFF_Builder_ + { + FT_Memory memory; + TT_Face face; + CFF_GlyphSlot glyph; + FT_GlyphLoader loader; + FT_Outline* base; + FT_Outline* current; + + FT_Pos pos_x; + FT_Pos pos_y; + + FT_Vector left_bearing; + FT_Vector advance; + + FT_BBox bbox; /* bounding box */ + + FT_Bool path_begun; + FT_Bool load_points; + FT_Bool no_recurse; + + FT_Bool metrics_only; + + void* hints_funcs; /* hinter-specific */ + void* hints_globals; /* hinter-specific */ + + CFF_Builder_FuncsRec funcs; + }; + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CFF DECODER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + +#define CFF_MAX_OPERANDS 48 +#define CFF_MAX_SUBRS_CALLS 16 /* maximum subroutine nesting; */ + /* only 10 are allowed but there exist */ + /* fonts like `HiraKakuProN-W3.ttf' */ + /* (Hiragino Kaku Gothic ProN W3; */ + /* 8.2d6e1; 2014-12-19) that exceed */ + /* this limit */ +#define CFF_MAX_TRANS_ELEMENTS 32 + + /* execution context charstring zone */ + + typedef struct CFF_Decoder_Zone_ + { + FT_Byte* base; + FT_Byte* limit; + FT_Byte* cursor; + + } CFF_Decoder_Zone; + + + typedef struct CFF_Decoder_ + { + CFF_Builder builder; + CFF_Font cff; + + FT_Fixed stack[CFF_MAX_OPERANDS + 1]; + FT_Fixed* top; + + CFF_Decoder_Zone zones[CFF_MAX_SUBRS_CALLS + 1]; + CFF_Decoder_Zone* zone; + + FT_Int flex_state; + FT_Int num_flex_vectors; + FT_Vector flex_vectors[7]; + + FT_Pos glyph_width; + FT_Pos nominal_width; + + FT_Bool read_width; + FT_Bool width_only; + FT_Int num_hints; + FT_Fixed buildchar[CFF_MAX_TRANS_ELEMENTS]; + + FT_UInt num_locals; + FT_UInt num_globals; + + FT_Int locals_bias; + FT_Int globals_bias; + + FT_Byte** locals; + FT_Byte** globals; + + FT_Byte** glyph_names; /* for pure CFF fonts only */ + FT_UInt num_glyphs; /* number of glyphs in font */ + + FT_Render_Mode hint_mode; + + FT_Bool seac; + + CFF_SubFont current_subfont; /* for current glyph_index */ + + CFF_Decoder_Get_Glyph_Callback get_glyph_callback; + CFF_Decoder_Free_Glyph_Callback free_glyph_callback; + + } CFF_Decoder; + + + typedef const struct CFF_Decoder_FuncsRec_* CFF_Decoder_Funcs; + + typedef struct CFF_Decoder_FuncsRec_ + { + void + (*init)( CFF_Decoder* decoder, + TT_Face face, + CFF_Size size, + CFF_GlyphSlot slot, + FT_Bool hinting, + FT_Render_Mode hint_mode, + CFF_Decoder_Get_Glyph_Callback get_callback, + CFF_Decoder_Free_Glyph_Callback free_callback ); + + FT_Error + (*prepare)( CFF_Decoder* decoder, + CFF_Size size, + FT_UInt glyph_index ); + +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + FT_Error + (*parse_charstrings_old)( CFF_Decoder* decoder, + FT_Byte* charstring_base, + FT_ULong charstring_len, + FT_Bool in_dict ); +#endif + + FT_Error + (*parse_charstrings)( PS_Decoder* decoder, + FT_Byte* charstring_base, + FT_ULong charstring_len ); + + } CFF_Decoder_FuncsRec; + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -808,14 +1288,29 @@ FT_BEGIN_HEADER FT_Offset length, FT_UShort seed ); + FT_UInt32 + (*cff_random)( FT_UInt32 r ); + + void + (*ps_decoder_init)( PS_Decoder* ps_decoder, + void* decoder, + FT_Bool is_t1 ); + + void + (*t1_make_subfont)( FT_Face face, + PS_Private priv, + CFF_SubFont subfont ); + T1_CMap_Classes t1_cmap_classes; /* fields after this comment line were added after version 2.1.10 */ const AFM_Parser_FuncsRec* afm_parser_funcs; + const CFF_Decoder_FuncsRec* cff_decoder_funcs; + } PSAux_ServiceRec, *PSAux_Service; - /* backwards-compatible type definition */ + /* backward compatible type definition */ typedef PSAux_ServiceRec PSAux_Interface; @@ -871,7 +1366,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSAUX_H__ */ +#endif /* PSAUX_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/pshints.h b/src/3rdparty/freetype/include/freetype/internal/pshints.h index 12aaabacd4..d29314ec2e 100644 --- a/src/3rdparty/freetype/include/freetype/internal/pshints.h +++ b/src/3rdparty/freetype/include/freetype/internal/pshints.h @@ -6,7 +6,7 @@ /* recorders (specification only). These are used to support native */ /* T1/T2 hints in the `type1', `cid', and `cff' font drivers. */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,8 +18,8 @@ /***************************************************************************/ -#ifndef __PSHINTS_H__ -#define __PSHINTS_H__ +#ifndef PSHINTS_H_ +#define PSHINTS_H_ #include <ft2build.h> @@ -716,7 +716,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSHINTS_H__ */ +#endif /* PSHINTS_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/services/svbdf.h b/src/3rdparty/freetype/include/freetype/internal/services/svbdf.h index 865b53687d..4a9ec20075 100644 --- a/src/3rdparty/freetype/include/freetype/internal/services/svbdf.h +++ b/src/3rdparty/freetype/include/freetype/internal/services/svbdf.h @@ -4,7 +4,7 @@ /* */ /* The FreeType BDF services (specification). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVBDF_H__ -#define __SVBDF_H__ +#ifndef SVBDF_H_ +#define SVBDF_H_ #include FT_BDF_H #include FT_INTERNAL_SERVICE_H @@ -76,7 +76,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVBDF_H__ */ +#endif /* SVBDF_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/services/svcfftl.h b/src/3rdparty/freetype/include/freetype/internal/services/svcfftl.h new file mode 100644 index 0000000000..db623e6840 --- /dev/null +++ b/src/3rdparty/freetype/include/freetype/internal/services/svcfftl.h @@ -0,0 +1,112 @@ +/***************************************************************************/ +/* */ +/* svcfftl.h */ +/* */ +/* The FreeType CFF tables loader service (specification). */ +/* */ +/* Copyright 2017-2018 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef SVCFFTL_H_ +#define SVCFFTL_H_ + +#include FT_INTERNAL_SERVICE_H +#include FT_INTERNAL_CFF_TYPES_H + + +FT_BEGIN_HEADER + + +#define FT_SERVICE_ID_CFF_LOAD "cff-load" + + + typedef FT_UShort + (*FT_Get_Standard_Encoding_Func)( FT_UInt charcode ); + + typedef FT_Error + (*FT_Load_Private_Dict_Func)( CFF_Font font, + CFF_SubFont subfont, + FT_UInt lenNDV, + FT_Fixed* NDV ); + + typedef FT_Byte + (*FT_FD_Select_Get_Func)( CFF_FDSelect fdselect, + FT_UInt glyph_index ); + + typedef FT_Bool + (*FT_Blend_Check_Vector_Func)( CFF_Blend blend, + FT_UInt vsindex, + FT_UInt lenNDV, + FT_Fixed* NDV ); + + typedef FT_Error + (*FT_Blend_Build_Vector_Func)( CFF_Blend blend, + FT_UInt vsindex, + FT_UInt lenNDV, + FT_Fixed* NDV ); + + + FT_DEFINE_SERVICE( CFFLoad ) + { + FT_Get_Standard_Encoding_Func get_standard_encoding; + FT_Load_Private_Dict_Func load_private_dict; + FT_FD_Select_Get_Func fd_select_get; + FT_Blend_Check_Vector_Func blend_check_vector; + FT_Blend_Build_Vector_Func blend_build_vector; + }; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_CFFLOADREC( class_, \ + get_standard_encoding_, \ + load_private_dict_, \ + fd_select_get_, \ + blend_check_vector_, \ + blend_build_vector_ ) \ + static const FT_Service_CFFLoadRec class_ = \ + { \ + get_standard_encoding_, \ + load_private_dict_, \ + fd_select_get_, \ + blend_check_vector_, \ + blend_build_vector_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_CFFLOADREC( class_, \ + get_standard_encoding_, \ + load_private_dict_, \ + fd_select_get_, \ + blend_check_vector_, \ + blend_build_vector_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Service_CFFLoadRec* clazz ) \ + { \ + clazz->get_standard_encoding = get_standard_encoding_; \ + clazz->load_private_dict = load_private_dict_; \ + clazz->fd_select_get = fd_select_get_; \ + clazz->blend_check_vector = blend_check_vector_; \ + clazz->blend_build_vector = blend_build_vector_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + +FT_END_HEADER + + +#endif + + +/* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/services/svcid.h b/src/3rdparty/freetype/include/freetype/internal/services/svcid.h index 4a535a6f42..cb59ac6a29 100644 --- a/src/3rdparty/freetype/include/freetype/internal/services/svcid.h +++ b/src/3rdparty/freetype/include/freetype/internal/services/svcid.h @@ -4,7 +4,7 @@ /* */ /* The FreeType CID font services (specification). */ /* */ -/* Copyright 2007-2015 by */ +/* Copyright 2007-2018 by */ /* Derek Clegg and Michael Toftdal. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVCID_H__ -#define __SVCID_H__ +#ifndef SVCID_H_ +#define SVCID_H_ #include FT_INTERNAL_SERVICE_H @@ -84,7 +84,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVCID_H__ */ +#endif /* SVCID_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/services/svfntfmt.h b/src/3rdparty/freetype/include/freetype/internal/services/svfntfmt.h index f8b3617364..3b732be1a1 100644 --- a/src/3rdparty/freetype/include/freetype/internal/services/svfntfmt.h +++ b/src/3rdparty/freetype/include/freetype/internal/services/svfntfmt.h @@ -4,7 +4,7 @@ /* */ /* The FreeType font format service (specification only). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVFNTFMT_H__ -#define __SVFNTFMT_H__ +#ifndef SVFNTFMT_H_ +#define SVFNTFMT_H_ #include FT_INTERNAL_SERVICE_H @@ -49,7 +49,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVFNTFMT_H__ */ +#endif /* SVFNTFMT_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/services/svgldict.h b/src/3rdparty/freetype/include/freetype/internal/services/svgldict.h index f78bca5d77..f1a68e3110 100644 --- a/src/3rdparty/freetype/include/freetype/internal/services/svgldict.h +++ b/src/3rdparty/freetype/include/freetype/internal/services/svgldict.h @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph dictionary services (specification). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVGLDICT_H__ -#define __SVGLDICT_H__ +#ifndef SVGLDICT_H_ +#define SVGLDICT_H_ #include FT_INTERNAL_SERVICE_H @@ -56,7 +56,7 @@ FT_BEGIN_HEADER #define FT_DEFINE_SERVICE_GLYPHDICTREC( class_, \ get_name_, \ - name_index_) \ + name_index_ ) \ static const FT_Service_GlyphDictRec class_ = \ { \ get_name_, name_index_ \ @@ -66,7 +66,7 @@ FT_BEGIN_HEADER #define FT_DEFINE_SERVICE_GLYPHDICTREC( class_, \ get_name_, \ - name_index_) \ + name_index_ ) \ void \ FT_Init_Class_ ## class_( FT_Library library, \ FT_Service_GlyphDictRec* clazz ) \ @@ -85,4 +85,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVGLDICT_H__ */ +#endif /* SVGLDICT_H_ */ + + +/* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/services/svgxval.h b/src/3rdparty/freetype/include/freetype/internal/services/svgxval.h index 59cc3b7048..ed79ebeaa8 100644 --- a/src/3rdparty/freetype/include/freetype/internal/services/svgxval.h +++ b/src/3rdparty/freetype/include/freetype/internal/services/svgxval.h @@ -4,7 +4,7 @@ /* */ /* FreeType API for validating TrueTypeGX/AAT tables (specification). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -25,8 +25,8 @@ /***************************************************************************/ -#ifndef __SVGXVAL_H__ -#define __SVGXVAL_H__ +#ifndef SVGXVAL_H_ +#define SVGXVAL_H_ #include FT_GX_VALIDATE_H #include FT_INTERNAL_VALIDATE_H @@ -66,7 +66,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVGXVAL_H__ */ +#endif /* SVGXVAL_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/services/svkern.h b/src/3rdparty/freetype/include/freetype/internal/services/svkern.h index bc26f15941..c7e8f6ef27 100644 --- a/src/3rdparty/freetype/include/freetype/internal/services/svkern.h +++ b/src/3rdparty/freetype/include/freetype/internal/services/svkern.h @@ -4,7 +4,7 @@ /* */ /* The FreeType Kerning service (specification). */ /* */ -/* Copyright 2006-2015 by */ +/* Copyright 2006-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVKERN_H__ -#define __SVKERN_H__ +#ifndef SVKERN_H_ +#define SVKERN_H_ #include FT_INTERNAL_SERVICE_H #include FT_TRUETYPE_TABLES_H @@ -45,7 +45,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVKERN_H__ */ +#endif /* SVKERN_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/services/svmetric.h b/src/3rdparty/freetype/include/freetype/internal/services/svmetric.h new file mode 100644 index 0000000000..abaacddbbe --- /dev/null +++ b/src/3rdparty/freetype/include/freetype/internal/services/svmetric.h @@ -0,0 +1,153 @@ +/***************************************************************************/ +/* */ +/* svmetric.h */ +/* */ +/* The FreeType services for metrics variations (specification). */ +/* */ +/* Copyright 2016-2018 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef SVMETRIC_H_ +#define SVMETRIC_H_ + +#include FT_INTERNAL_SERVICE_H + + +FT_BEGIN_HEADER + + + /* + * A service to manage the `HVAR, `MVAR', and `VVAR' OpenType tables. + * + */ + +#define FT_SERVICE_ID_METRICS_VARIATIONS "metrics-variations" + + + /* HVAR */ + + typedef FT_Error + (*FT_HAdvance_Adjust_Func)( FT_Face face, + FT_UInt gindex, + FT_Int *avalue ); + + typedef FT_Error + (*FT_LSB_Adjust_Func)( FT_Face face, + FT_UInt gindex, + FT_Int *avalue ); + + typedef FT_Error + (*FT_RSB_Adjust_Func)( FT_Face face, + FT_UInt gindex, + FT_Int *avalue ); + + /* VVAR */ + + typedef FT_Error + (*FT_VAdvance_Adjust_Func)( FT_Face face, + FT_UInt gindex, + FT_Int *avalue ); + + typedef FT_Error + (*FT_TSB_Adjust_Func)( FT_Face face, + FT_UInt gindex, + FT_Int *avalue ); + + typedef FT_Error + (*FT_BSB_Adjust_Func)( FT_Face face, + FT_UInt gindex, + FT_Int *avalue ); + + typedef FT_Error + (*FT_VOrg_Adjust_Func)( FT_Face face, + FT_UInt gindex, + FT_Int *avalue ); + + /* MVAR */ + + typedef void + (*FT_Metrics_Adjust_Func)( FT_Face face ); + + + FT_DEFINE_SERVICE( MetricsVariations ) + { + FT_HAdvance_Adjust_Func hadvance_adjust; + FT_LSB_Adjust_Func lsb_adjust; + FT_RSB_Adjust_Func rsb_adjust; + + FT_VAdvance_Adjust_Func vadvance_adjust; + FT_TSB_Adjust_Func tsb_adjust; + FT_BSB_Adjust_Func bsb_adjust; + FT_VOrg_Adjust_Func vorg_adjust; + + FT_Metrics_Adjust_Func metrics_adjust; + }; + + +#ifndef FT_CONFIG_OPTION_PIC + +#define FT_DEFINE_SERVICE_METRICSVARIATIONSREC( class_, \ + hadvance_adjust_, \ + lsb_adjust_, \ + rsb_adjust_, \ + vadvance_adjust_, \ + tsb_adjust_, \ + bsb_adjust_, \ + vorg_adjust_, \ + metrics_adjust_ ) \ + static const FT_Service_MetricsVariationsRec class_ = \ + { \ + hadvance_adjust_, \ + lsb_adjust_, \ + rsb_adjust_, \ + vadvance_adjust_, \ + tsb_adjust_, \ + bsb_adjust_, \ + vorg_adjust_, \ + metrics_adjust_ \ + }; + +#else /* FT_CONFIG_OPTION_PIC */ + +#define FT_DEFINE_SERVICE_METRICSVARIATIONSREC( class_, \ + hadvance_adjust_, \ + lsb_adjust_, \ + rsb_adjust_, \ + vadvance_adjust_, \ + tsb_adjust_, \ + bsb_adjust_, \ + vorg_adjust_, \ + metrics_adjust_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Service_MetricsVariationsRec* clazz ) \ + { \ + clazz->hadvance_adjust = hadvance_adjust_; \ + clazz->lsb_adjust = lsb_adjust_; \ + clazz->rsb_adjust = rsb_adjust_; \ + clazz->vadvance_adjust = vadvance_adjust_; \ + clazz->tsb_adjust = tsb_adjust_; \ + clazz->bsb_adjust = bsb_adjust_; \ + clazz->vorg_adjust = vorg_adjust_; \ + clazz->metrics_adjust = metrics_adjust_; \ + } + +#endif /* FT_CONFIG_OPTION_PIC */ + + /* */ + + +FT_END_HEADER + +#endif /* SVMETRIC_H_ */ + + +/* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/services/svmm.h b/src/3rdparty/freetype/include/freetype/internal/services/svmm.h index f2cecfbb3b..bcbb38e2ce 100644 --- a/src/3rdparty/freetype/include/freetype/internal/services/svmm.h +++ b/src/3rdparty/freetype/include/freetype/internal/services/svmm.h @@ -4,7 +4,7 @@ /* */ /* The FreeType Multiple Masters and GX var services (specification). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVMM_H__ -#define __SVMM_H__ +#ifndef SVMM_H_ +#define SVMM_H_ #include FT_INTERNAL_SERVICE_H @@ -48,56 +48,115 @@ FT_BEGIN_HEADER FT_UInt num_coords, FT_Long* coords ); + /* use return value -1 to indicate that the new coordinates */ + /* are equal to the current ones; no changes are thus needed */ typedef FT_Error (*FT_Set_Var_Design_Func)( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ); + /* use return value -1 to indicate that the new coordinates */ + /* are equal to the current ones; no changes are thus needed */ typedef FT_Error (*FT_Set_MM_Blend_Func)( FT_Face face, FT_UInt num_coords, FT_Long* coords ); + typedef FT_Error + (*FT_Get_Var_Design_Func)( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + typedef FT_Error + (*FT_Set_Instance_Func)( FT_Face face, + FT_UInt instance_index ); + + typedef FT_Error + (*FT_Get_MM_Blend_Func)( FT_Face face, + FT_UInt num_coords, + FT_Long* coords ); + + typedef FT_Error + (*FT_Get_Var_Blend_Func)( FT_Face face, + FT_UInt *num_coords, + FT_Fixed* *coords, + FT_Fixed* *normalizedcoords, + FT_MM_Var* *mm_var ); + + typedef void + (*FT_Done_Blend_Func)( FT_Face ); + FT_DEFINE_SERVICE( MultiMasters ) { FT_Get_MM_Func get_mm; FT_Set_MM_Design_Func set_mm_design; FT_Set_MM_Blend_Func set_mm_blend; + FT_Get_MM_Blend_Func get_mm_blend; FT_Get_MM_Var_Func get_mm_var; FT_Set_Var_Design_Func set_var_design; + FT_Get_Var_Design_Func get_var_design; + FT_Set_Instance_Func set_instance; + + /* for internal use; only needed for code sharing between modules */ + FT_Get_Var_Blend_Func get_var_blend; + FT_Done_Blend_Func done_blend; }; #ifndef FT_CONFIG_OPTION_PIC -#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ - get_mm_, \ - set_mm_design_, \ - set_mm_blend_, \ - get_mm_var_, \ - set_var_design_ ) \ - static const FT_Service_MultiMastersRec class_ = \ - { \ - get_mm_, set_mm_design_, set_mm_blend_, get_mm_var_, set_var_design_ \ +#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ + get_mm_, \ + set_mm_design_, \ + set_mm_blend_, \ + get_mm_blend_, \ + get_mm_var_, \ + set_var_design_, \ + get_var_design_, \ + set_instance_, \ + get_var_blend_, \ + done_blend_ ) \ + static const FT_Service_MultiMastersRec class_ = \ + { \ + get_mm_, \ + set_mm_design_, \ + set_mm_blend_, \ + get_mm_blend_, \ + get_mm_var_, \ + set_var_design_, \ + get_var_design_, \ + set_instance_, \ + get_var_blend_, \ + done_blend_ \ }; #else /* FT_CONFIG_OPTION_PIC */ -#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ - get_mm_, \ - set_mm_design_, \ - set_mm_blend_, \ - get_mm_var_, \ - set_var_design_ ) \ - void \ - FT_Init_Class_ ## class_( FT_Service_MultiMastersRec* clazz ) \ - { \ - clazz->get_mm = get_mm_; \ - clazz->set_mm_design = set_mm_design_; \ - clazz->set_mm_blend = set_mm_blend_; \ - clazz->get_mm_var = get_mm_var_; \ - clazz->set_var_design = set_var_design_; \ +#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_, \ + get_mm_, \ + set_mm_design_, \ + set_mm_blend_, \ + get_mm_blend_, \ + get_mm_var_, \ + set_var_design_, \ + get_var_design_, \ + set_instance_, \ + get_var_blend_, \ + done_blend_ ) \ + void \ + FT_Init_Class_ ## class_( FT_Service_MultiMastersRec* clazz ) \ + { \ + clazz->get_mm = get_mm_; \ + clazz->set_mm_design = set_mm_design_; \ + clazz->set_mm_blend = set_mm_blend_; \ + clazz->get_mm_blend = get_mm_blend_; \ + clazz->get_mm_var = get_mm_var_; \ + clazz->set_var_design = set_var_design_; \ + clazz->get_var_design = get_var_design_; \ + clazz->set_instance = set_instance_; \ + clazz->get_var_blend = get_var_blend_; \ + clazz->done_blend = done_blend_; \ } #endif /* FT_CONFIG_OPTION_PIC */ @@ -107,7 +166,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVMM_H__ */ +#endif /* SVMM_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/services/svotval.h b/src/3rdparty/freetype/include/freetype/internal/services/svotval.h index a82a6420fd..31294296a6 100644 --- a/src/3rdparty/freetype/include/freetype/internal/services/svotval.h +++ b/src/3rdparty/freetype/include/freetype/internal/services/svotval.h @@ -4,7 +4,7 @@ /* */ /* The FreeType OpenType validation service (specification). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVOTVAL_H__ -#define __SVOTVAL_H__ +#ifndef SVOTVAL_H_ +#define SVOTVAL_H_ #include FT_OPENTYPE_VALIDATE_H #include FT_INTERNAL_VALIDATE_H @@ -49,7 +49,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVOTVAL_H__ */ +#endif /* SVOTVAL_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/services/svpfr.h b/src/3rdparty/freetype/include/freetype/internal/services/svpfr.h index d4eb1693d0..e65d57e91b 100644 --- a/src/3rdparty/freetype/include/freetype/internal/services/svpfr.h +++ b/src/3rdparty/freetype/include/freetype/internal/services/svpfr.h @@ -4,7 +4,7 @@ /* */ /* Internal PFR service functions (specification). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVPFR_H__ -#define __SVPFR_H__ +#ifndef SVPFR_H_ +#define SVPFR_H_ #include FT_PFR_H #include FT_INTERNAL_SERVICE_H @@ -60,7 +60,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVPFR_H__ */ +#endif /* SVPFR_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/services/svpostnm.h b/src/3rdparty/freetype/include/freetype/internal/services/svpostnm.h index a89f79e479..4a49d8b053 100644 --- a/src/3rdparty/freetype/include/freetype/internal/services/svpostnm.h +++ b/src/3rdparty/freetype/include/freetype/internal/services/svpostnm.h @@ -4,7 +4,7 @@ /* */ /* The FreeType PostScript name services (specification). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVPOSTNM_H__ -#define __SVPOSTNM_H__ +#ifndef SVPOSTNM_H_ +#define SVPOSTNM_H_ #include FT_INTERNAL_SERVICE_H @@ -75,7 +75,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVPOSTNM_H__ */ +#endif /* SVPOSTNM_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/services/svprop.h b/src/3rdparty/freetype/include/freetype/internal/services/svprop.h index c9f07ce33a..adc0bcf439 100644 --- a/src/3rdparty/freetype/include/freetype/internal/services/svprop.h +++ b/src/3rdparty/freetype/include/freetype/internal/services/svprop.h @@ -4,7 +4,7 @@ /* */ /* The FreeType property service (specification). */ /* */ -/* Copyright 2012-2015 by */ +/* Copyright 2012-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVPROP_H__ -#define __SVPROP_H__ +#ifndef SVPROP_H_ +#define SVPROP_H_ FT_BEGIN_HEADER @@ -29,7 +29,8 @@ FT_BEGIN_HEADER typedef FT_Error (*FT_Properties_SetFunc)( FT_Module module, const char* property_name, - const void* value ); + const void* value, + FT_Bool value_is_string ); typedef FT_Error (*FT_Properties_GetFunc)( FT_Module module, @@ -75,7 +76,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVPROP_H__ */ +#endif /* SVPROP_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/services/svpscmap.h b/src/3rdparty/freetype/include/freetype/internal/services/svpscmap.h index 66da6e1043..5589575b92 100644 --- a/src/3rdparty/freetype/include/freetype/internal/services/svpscmap.h +++ b/src/3rdparty/freetype/include/freetype/internal/services/svpscmap.h @@ -4,7 +4,7 @@ /* */ /* The FreeType PostScript charmap service (specification). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVPSCMAP_H__ -#define __SVPSCMAP_H__ +#ifndef SVPSCMAP_H_ +#define SVPSCMAP_H_ #include FT_INTERNAL_OBJECTS_H @@ -171,7 +171,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVPSCMAP_H__ */ +#endif /* SVPSCMAP_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/services/svpsinfo.h b/src/3rdparty/freetype/include/freetype/internal/services/svpsinfo.h index 752a266025..408f406dfa 100644 --- a/src/3rdparty/freetype/include/freetype/internal/services/svpsinfo.h +++ b/src/3rdparty/freetype/include/freetype/internal/services/svpsinfo.h @@ -4,7 +4,7 @@ /* */ /* The FreeType PostScript info service (specification). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVPSINFO_H__ -#define __SVPSINFO_H__ +#ifndef SVPSINFO_H_ +#define SVPSINFO_H_ #include FT_INTERNAL_SERVICE_H #include FT_INTERNAL_TYPE1_TYPES_H @@ -105,7 +105,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVPSINFO_H__ */ +#endif /* SVPSINFO_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/services/svsfnt.h b/src/3rdparty/freetype/include/freetype/internal/services/svsfnt.h index 252ae1cf5e..e8b37bc47f 100644 --- a/src/3rdparty/freetype/include/freetype/internal/services/svsfnt.h +++ b/src/3rdparty/freetype/include/freetype/internal/services/svsfnt.h @@ -4,7 +4,7 @@ /* */ /* The FreeType SFNT table loading service (specification). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVSFNT_H__ -#define __SVSFNT_H__ +#ifndef SVSFNT_H_ +#define SVSFNT_H_ #include FT_INTERNAL_SERVICE_H #include FT_TRUETYPE_TABLES_H @@ -97,7 +97,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVSFNT_H__ */ +#endif /* SVSFNT_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/services/svttcmap.h b/src/3rdparty/freetype/include/freetype/internal/services/svttcmap.h index cd95b9ab81..cd0e6fda6f 100644 --- a/src/3rdparty/freetype/include/freetype/internal/services/svttcmap.h +++ b/src/3rdparty/freetype/include/freetype/internal/services/svttcmap.h @@ -4,7 +4,7 @@ /* */ /* The FreeType TrueType/sfnt cmap extra information service. */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* Masatake YAMATO, Redhat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -19,8 +19,8 @@ /* Development of this service is support of Information-technology Promotion Agency, Japan. */ -#ifndef __SVTTCMAP_H__ -#define __SVTTCMAP_H__ +#ifndef SVTTCMAP_H_ +#define SVTTCMAP_H_ #include FT_INTERNAL_SERVICE_H #include FT_TRUETYPE_TABLES_H @@ -100,7 +100,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVTTCMAP_H__ */ +#endif /* SVTTCMAP_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/services/svtteng.h b/src/3rdparty/freetype/include/freetype/internal/services/svtteng.h index 272ee8c055..92e3c541f5 100644 --- a/src/3rdparty/freetype/include/freetype/internal/services/svtteng.h +++ b/src/3rdparty/freetype/include/freetype/internal/services/svtteng.h @@ -4,7 +4,7 @@ /* */ /* The FreeType TrueType engine query service (specification). */ /* */ -/* Copyright 2006-2015 by */ +/* Copyright 2006-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVTTENG_H__ -#define __SVTTENG_H__ +#ifndef SVTTENG_H_ +#define SVTTENG_H_ #include FT_INTERNAL_SERVICE_H #include FT_MODULE_H @@ -47,7 +47,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVTTENG_H__ */ +#endif /* SVTTENG_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/services/svttglyf.h b/src/3rdparty/freetype/include/freetype/internal/services/svttglyf.h index f5cb76a9f8..16fac1ca18 100644 --- a/src/3rdparty/freetype/include/freetype/internal/services/svttglyf.h +++ b/src/3rdparty/freetype/include/freetype/internal/services/svttglyf.h @@ -4,7 +4,7 @@ /* */ /* The FreeType TrueType glyph service. */ /* */ -/* Copyright 2007-2015 by */ +/* Copyright 2007-2018 by */ /* David Turner. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -15,8 +15,8 @@ /* */ /***************************************************************************/ -#ifndef __SVTTGLYF_H__ -#define __SVTTGLYF_H__ +#ifndef SVTTGLYF_H_ +#define SVTTGLYF_H_ #include FT_INTERNAL_SERVICE_H #include FT_TRUETYPE_TABLES_H @@ -63,7 +63,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVTTGLYF_H__ */ +#endif /* SVTTGLYF_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/services/svwinfnt.h b/src/3rdparty/freetype/include/freetype/internal/services/svwinfnt.h index 0036929b2f..80d481cbd1 100644 --- a/src/3rdparty/freetype/include/freetype/internal/services/svwinfnt.h +++ b/src/3rdparty/freetype/include/freetype/internal/services/svwinfnt.h @@ -4,7 +4,7 @@ /* */ /* The FreeType Windows FNT/FONT service (specification). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SVWINFNT_H__ -#define __SVWINFNT_H__ +#ifndef SVWINFNT_H_ +#define SVWINFNT_H_ #include FT_INTERNAL_SERVICE_H #include FT_WINFONTS_H @@ -44,7 +44,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SVWINFNT_H__ */ +#endif /* SVWINFNT_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/sfnt.h b/src/3rdparty/freetype/include/freetype/internal/sfnt.h index 30f53bf09c..fb1e327aeb 100644 --- a/src/3rdparty/freetype/include/freetype/internal/sfnt.h +++ b/src/3rdparty/freetype/include/freetype/internal/sfnt.h @@ -4,7 +4,7 @@ /* */ /* High-level `sfnt' driver interface (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SFNT_H__ -#define __SFNT_H__ +#ifndef SFNT_H_ +#define SFNT_H_ #include <ft2build.h> @@ -455,6 +455,37 @@ FT_BEGIN_HEADER FT_String** name ); + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* TT_Get_Name_ID_Func */ + /* */ + /* <Description> */ + /* Search whether an ENGLISH version for a given name ID is in the */ + /* `name' table. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face object. */ + /* */ + /* nameid :: The name id of the name record to return. */ + /* */ + /* <Out> */ + /* win :: If non-negative, an index into the `name' table with */ + /* the corresponding (3,1) or (3,0) Windows entry. */ + /* */ + /* apple :: If non-negative, an index into the `name' table with */ + /* the corresponding (1,0) Apple entry. */ + /* */ + /* <Return> */ + /* 1 if there is either a win or apple entry (or both), 0 otheriwse. */ + /* */ + typedef FT_Bool + (*TT_Get_Name_ID_Func)( TT_Face face, + FT_UShort nameid, + FT_Int *win, + FT_Int *apple ); + + /*************************************************************************/ /* */ /* <FuncType> */ @@ -588,6 +619,7 @@ FT_BEGIN_HEADER TT_Get_Metrics_Func get_metrics; TT_Get_Name_Func get_name; + TT_Get_Name_ID_Func get_name_id; } SFNT_Interface; @@ -628,7 +660,8 @@ FT_BEGIN_HEADER set_sbit_strike_, \ load_strike_metrics_, \ get_metrics_, \ - get_name_ ) \ + get_name_, \ + get_name_id_ ) \ static const SFNT_Interface class_ = \ { \ goto_table_, \ @@ -661,6 +694,7 @@ FT_BEGIN_HEADER load_strike_metrics_, \ get_metrics_, \ get_name_, \ + get_name_id_ \ }; #else /* FT_CONFIG_OPTION_PIC */ @@ -699,7 +733,8 @@ FT_BEGIN_HEADER set_sbit_strike_, \ load_strike_metrics_, \ get_metrics_, \ - get_name_ ) \ + get_name_, \ + get_name_id_ ) \ void \ FT_Init_Class_ ## class_( FT_Library library, \ SFNT_Interface* clazz ) \ @@ -736,13 +771,14 @@ FT_BEGIN_HEADER clazz->load_strike_metrics = load_strike_metrics_; \ clazz->get_metrics = get_metrics_; \ clazz->get_name = get_name_; \ + clazz->get_name_id = get_name_id_; \ } #endif /* FT_CONFIG_OPTION_PIC */ FT_END_HEADER -#endif /* __SFNT_H__ */ +#endif /* SFNT_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/t1types.h b/src/3rdparty/freetype/include/freetype/internal/t1types.h index 029acc4009..2118e33674 100644 --- a/src/3rdparty/freetype/include/freetype/internal/t1types.h +++ b/src/3rdparty/freetype/include/freetype/internal/t1types.h @@ -5,7 +5,7 @@ /* Basic Type1/Type2 type definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,14 +17,15 @@ /***************************************************************************/ -#ifndef __T1TYPES_H__ -#define __T1TYPES_H__ +#ifndef T1TYPES_H_ +#define T1TYPES_H_ #include <ft2build.h> #include FT_TYPE1_TABLES_H #include FT_INTERNAL_POSTSCRIPT_HINTS_H #include FT_INTERNAL_SERVICE_H +#include FT_INTERNAL_HASH_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H @@ -107,6 +108,7 @@ FT_BEGIN_HEADER FT_Int num_subrs; FT_Byte** subrs; FT_UInt* subrs_len; + FT_Hash subrs_hash; FT_Int num_glyphs; FT_String** glyph_names; /* array of glyph names */ @@ -249,7 +251,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1TYPES_H__ */ +#endif /* T1TYPES_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/internal/tttypes.h b/src/3rdparty/freetype/include/freetype/internal/tttypes.h index 1507a7c57a..10dd336a89 100644 --- a/src/3rdparty/freetype/include/freetype/internal/tttypes.h +++ b/src/3rdparty/freetype/include/freetype/internal/tttypes.h @@ -5,7 +5,7 @@ /* Basic SFNT/TrueType type definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __TTTYPES_H__ -#define __TTTYPES_H__ +#ifndef TTTYPES_H_ +#define TTTYPES_H_ #include <ft2build.h> @@ -148,7 +148,7 @@ FT_BEGIN_HEADER /* <Fields> */ /* See */ /* */ - /* http://www.w3.org/TR/WOFF/#WOFFHeader */ + /* https://www.w3.org/TR/WOFF/#WOFFHeader */ /* */ typedef struct WOFF_HeaderRec_ { @@ -185,7 +185,7 @@ FT_BEGIN_HEADER /* */ /* CompLength :: Compressed table length (in bytes). */ /* */ - /* OrigLength :: Unompressed table length (in bytes). */ + /* OrigLength :: Uncompressed table length (in bytes). */ /* */ /* CheckSum :: The table checksum. This value can be ignored. */ /* */ @@ -243,7 +243,7 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* <Struct> */ - /* TT_NameEntryRec */ + /* TT_NameRec */ /* */ /* <Description> */ /* A structure modeling TrueType name records. Name records are used */ @@ -267,7 +267,7 @@ FT_BEGIN_HEADER /* string :: A pointer to the string's bytes. Note that these */ /* are usually UTF-16 encoded characters. */ /* */ - typedef struct TT_NameEntryRec_ + typedef struct TT_NameRec_ { FT_UShort platformID; FT_UShort encodingID; @@ -279,9 +279,39 @@ FT_BEGIN_HEADER /* this last field is not defined in the spec */ /* but used by the FreeType engine */ - FT_Byte* string; + FT_Byte* string; - } TT_NameEntryRec, *TT_NameEntry; + } TT_NameRec, *TT_Name; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* TT_LangTagRec */ + /* */ + /* <Description> */ + /* A structure modeling language tag records in SFNT `name' tables, */ + /* introduced in OpenType version 1.6. */ + /* */ + /* <Fields> */ + /* stringLength :: The length of the string in bytes. */ + /* */ + /* stringOffset :: The offset to the string in the `name' table. */ + /* */ + /* string :: A pointer to the string's bytes. Note that these */ + /* are UTF-16BE encoded characters. */ + /* */ + typedef struct TT_LangTagRec_ + { + FT_UShort stringLength; + FT_ULong stringOffset; + + /* this last field is not defined in the spec */ + /* but used by the FreeType engine */ + + FT_Byte* string; + + } TT_LangTagRec, *TT_LangTag; /*************************************************************************/ @@ -293,24 +323,30 @@ FT_BEGIN_HEADER /* A structure modeling the TrueType name table. */ /* */ /* <Fields> */ - /* format :: The format of the name table. */ + /* format :: The format of the name table. */ /* */ - /* numNameRecords :: The number of names in table. */ + /* numNameRecords :: The number of names in table. */ /* */ - /* storageOffset :: The offset of the name table in the `name' */ - /* TrueType table. */ + /* storageOffset :: The offset of the name table in the `name' */ + /* TrueType table. */ /* */ - /* names :: An array of name records. */ + /* names :: An array of name records. */ /* */ - /* stream :: the file's input stream. */ + /* numLangTagRecords :: The number of language tags in table. */ + /* */ + /* langTags :: An array of language tag records. */ + /* */ + /* stream :: The file's input stream. */ /* */ typedef struct TT_NameTableRec_ { - FT_UShort format; - FT_UInt numNameRecords; - FT_UInt storageOffset; - TT_NameEntryRec* names; - FT_Stream stream; + FT_UShort format; + FT_UInt numNameRecords; + FT_UInt storageOffset; + TT_NameRec* names; + FT_UInt numLangTagRecords; + TT_LangTagRec* langTags; + FT_Stream stream; } TT_NameTableRec, *TT_NameTable; @@ -1060,6 +1096,34 @@ FT_BEGIN_HEADER } TT_SbitTableType; + /* OpenType 1.8 brings new tables for variation font support; */ + /* to make the old MM and GX fonts still work we need to check */ + /* the presence (and validity) of the functionality provided */ + /* by those tables. The following flag macros are for the */ + /* field `variation_support'. */ + /* */ + /* Note that `fvar' gets checked immediately at font loading, */ + /* while the other features are only loaded if MM support is */ + /* actually requested. */ + + /* FVAR */ +#define TT_FACE_FLAG_VAR_FVAR ( 1 << 0 ) + + /* HVAR */ +#define TT_FACE_FLAG_VAR_HADVANCE ( 1 << 1 ) +#define TT_FACE_FLAG_VAR_LSB ( 1 << 2 ) +#define TT_FACE_FLAG_VAR_RSB ( 1 << 3 ) + + /* VVAR */ +#define TT_FACE_FLAG_VAR_VADVANCE ( 1 << 4 ) +#define TT_FACE_FLAG_VAR_TSB ( 1 << 5 ) +#define TT_FACE_FLAG_VAR_BSB ( 1 << 6 ) +#define TT_FACE_FLAG_VAR_VORG ( 1 << 7 ) + + /* MVAR */ +#define TT_FACE_FLAG_VAR_MVAR ( 1 << 8 ) + + /*************************************************************************/ /* */ /* TrueType Face Type */ @@ -1161,6 +1225,11 @@ FT_BEGIN_HEADER /* */ /* psnames :: A pointer to the PostScript names service. */ /* */ + /* mm :: A pointer to the Multiple Masters service. */ + /* */ + /* var :: A pointer to the Metrics Variations */ + /* service. */ + /* */ /* hdmx :: The face's horizontal device metrics */ /* (`hdmx' table). This table is optional in */ /* TrueType/OpenType fonts. */ @@ -1182,18 +1251,6 @@ FT_BEGIN_HEADER /* file `ttconfig.h' for comments on the */ /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES option. */ /* */ - /* num_locations :: The number of glyph locations in this */ - /* TrueType file. This should be */ - /* identical to the number of glyphs. */ - /* Ignored for Type 2 fonts. */ - /* */ - /* glyph_locations :: An array of longs. These are offsets to */ - /* glyph data within the `glyf' table. */ - /* Ignored for Type 2 font faces. */ - /* */ - /* glyf_len :: The length of the `glyf' table. Needed */ - /* for malformed `loca' tables. */ - /* */ /* font_program_size :: Size in bytecodes of the face's font */ /* program. 0 if none defined. Ignored for */ /* Type 2 fonts. */ @@ -1219,22 +1276,21 @@ FT_BEGIN_HEADER /* units. Comes from the `cvt ' table. */ /* Ignored for Type 2 fonts. */ /* */ - /* num_kern_pairs :: The number of kerning pairs present in the */ - /* font file. The engine only loads the */ - /* first horizontal format 0 kern table it */ - /* finds in the font file. Ignored for */ - /* Type 2 fonts. */ - /* */ - /* kern_table_index :: The index of the kerning table in the font */ - /* kerning directory. Ignored for Type 2 */ - /* fonts. */ - /* */ /* interpreter :: A pointer to the TrueType bytecode */ /* interpreters field is also used to hook */ /* the debugger in `ttdebug'. */ /* */ - /* unpatented_hinting :: If true, use only unpatented methods in */ - /* the bytecode interpreter. */ + /* extra :: Reserved for third-party font drivers. */ + /* */ + /* postscript_name :: The PS name of the font. Used by the */ + /* postscript name service. */ + /* */ + /* glyf_len :: The length of the `glyf' table. Needed */ + /* for malformed `loca' tables. */ + /* */ + /* glyf_offset :: The file offset of the `glyf' table. */ + /* */ + /* is_cff2 :: Set if the font format is CFF2. */ /* */ /* doblend :: A boolean which is set if the font should */ /* be blended (this is for GX var). */ @@ -1243,10 +1299,94 @@ FT_BEGIN_HEADER /* variation tables (rather like Multiple */ /* Master data). */ /* */ - /* extra :: Reserved for third-party font drivers. */ + /* variation_support :: Flags that indicate which OpenType */ + /* functionality related to font variation */ + /* support is present, valid, and usable. */ + /* For example, TT_FACE_FLAG_VAR_FVAR is only */ + /* set if we have at least one design axis. */ /* */ - /* postscript_name :: The PS name of the font. Used by the */ - /* postscript name service. */ + /* var_postscript_prefix :: */ + /* The PostScript name prefix needed for */ + /* constructing a variation font instance's */ + /* PS name . */ + /* */ + /* var_postscript_prefix_len :: */ + /* The length of the `var_postscript_prefix' */ + /* string. */ + /* */ + /* horz_metrics_size :: The size of the `hmtx' table. */ + /* */ + /* vert_metrics_size :: The size of the `vmtx' table. */ + /* */ + /* num_locations :: The number of glyph locations in this */ + /* TrueType file. This should be */ + /* identical to the number of glyphs. */ + /* Ignored for Type 2 fonts. */ + /* */ + /* glyph_locations :: An array of longs. These are offsets to */ + /* glyph data within the `glyf' table. */ + /* Ignored for Type 2 font faces. */ + /* */ + /* hdmx_table :: A pointer to the `hdmx' table. */ + /* */ + /* hdmx_table_size :: The size of the `hdmx' table. */ + /* */ + /* hdmx_record_count :: The number of hdmx records. */ + /* */ + /* hdmx_record_size :: The size of a single hdmx record. */ + /* */ + /* hdmx_record_sizes :: An array holding the ppem sizes available */ + /* in the `hdmx' table. */ + /* */ + /* sbit_table :: A pointer to the font's embedded bitmap */ + /* location table. */ + /* */ + /* sbit_table_size :: The size of `sbit_table'. */ + /* */ + /* sbit_table_type :: The sbit table type (CBLC, sbix, etc.). */ + /* */ + /* sbit_num_strikes :: The number of sbit strikes exposed by */ + /* FreeType's API, omitting invalid strikes. */ + /* */ + /* sbit_strike_map :: A mapping between the strike indices */ + /* exposed by the API and the indices used in */ + /* the font's sbit table. */ + /* */ + /* kern_table :: A pointer to the `kern' table. */ + /* */ + /* kern_table_size :: The size of the `kern' table. */ + /* */ + /* num_kern_tables :: The number of supported kern subtables */ + /* (up to 32; FreeType recognizes only */ + /* horizontal ones with format 0). */ + /* */ + /* kern_avail_bits :: The availability status of kern subtables; */ + /* if bit n is set, table n is available. */ + /* */ + /* kern_order_bits :: The sortedness status of kern subtables; */ + /* if bit n is set, table n is sorted. */ + /* */ + /* bdf :: Data related to an SFNT font's `bdf' */ + /* table; see `tttypes.h'. */ + /* */ + /* horz_metrics_offset :: The file offset of the `hmtx' table. */ + /* */ + /* vert_metrics_offset :: The file offset of the `vmtx' table. */ + /* */ + /* sph_found_func_flags :: Flags identifying special bytecode */ + /* functions (used by the v38 implementation */ + /* of the bytecode interpreter). */ + /* */ + /* sph_compatibility_mode :: */ + /* This flag is set if we are in ClearType */ + /* backward compatibility mode (used by the */ + /* v38 implementation of the bytecode */ + /* interpreter). */ + /* */ + /* ebdt_start :: The file offset of the sbit data table */ + /* (CBDT, bdat, etc.). */ + /* */ + /* ebdt_size :: The size of the sbit data table. */ /* */ typedef struct TT_FaceRec_ { @@ -1291,6 +1431,19 @@ FT_BEGIN_HEADER /* handle glyph names <-> unicode & Mac values */ void* psnames; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + /* a typeless pointer to the FT_Service_MultiMasters table used to */ + /* handle variation fonts */ + void* mm; + + /* a typeless pointer to the FT_Service_MetricsVariationsRec table */ + /* used to handle the HVAR, VVAR, and MVAR OpenType tables */ + void* var; +#endif + + /* a typeless pointer to the PostScript Aux service */ + void* psaux; + /***********************************************************************/ /* */ @@ -1314,7 +1467,7 @@ FT_BEGIN_HEADER /***********************************************************************/ /* */ - /* TrueType-specific fields (ignored by the OTF-Type2 driver) */ + /* TrueType-specific fields (ignored by the CFF driver) */ /* */ /***********************************************************************/ @@ -1334,10 +1487,6 @@ FT_BEGIN_HEADER /* used to hook the debugger for the `ttdebug' utility. */ TT_Interpreter interpreter; -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - /* Use unpatented hinting only. */ - FT_Bool unpatented_hinting; -#endif /***********************************************************************/ /* */ @@ -1351,18 +1500,24 @@ FT_BEGIN_HEADER const char* postscript_name; FT_ULong glyf_len; + FT_ULong glyf_offset; /* since 2.7.1 */ + + FT_Bool is_cff2; /* since 2.7.1 */ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT FT_Bool doblend; GX_Blend blend; + + FT_UInt32 variation_support; /* since 2.7.1 */ + + const char* var_postscript_prefix; /* since 2.7.2 */ + FT_UInt var_postscript_prefix_len; /* since 2.7.2 */ + #endif /* since version 2.2 */ - FT_Byte* horz_metrics; FT_ULong horz_metrics_size; - - FT_Byte* vert_metrics; FT_ULong vert_metrics_size; FT_ULong num_locations; /* in broken TTF, gid > 0xFFFF */ @@ -1378,6 +1533,7 @@ FT_BEGIN_HEADER FT_ULong sbit_table_size; TT_SbitTableType sbit_table_type; FT_UInt sbit_num_strikes; + FT_UInt* sbit_strike_map; FT_Byte* kern_table; FT_ULong kern_table_size; @@ -1393,12 +1549,18 @@ FT_BEGIN_HEADER FT_ULong horz_metrics_offset; FT_ULong vert_metrics_offset; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* since 2.4.12 */ FT_ULong sph_found_func_flags; /* special functions found */ /* for this face */ FT_Bool sph_compatibility_mode; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + /* since 2.7 */ + FT_ULong ebdt_start; /* either `CBDT', `EBDT', or `bdat' */ + FT_ULong ebdt_size; +#endif } TT_FaceRec; @@ -1492,8 +1654,6 @@ FT_BEGIN_HEADER FT_Vector pp1; FT_Vector pp2; - FT_ULong glyf_offset; - /* the zone where we load our glyphs */ TT_GlyphZoneRec base; TT_GlyphZoneRec zone; @@ -1515,12 +1675,15 @@ FT_BEGIN_HEADER FT_Byte* cursor; FT_Byte* limit; + /* since version 2.6.2 */ + FT_ListRec composites; + } TT_LoaderRec; FT_END_HEADER -#endif /* __TTTYPES_H__ */ +#endif /* TTTYPES_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/t1tables.h b/src/3rdparty/freetype/include/freetype/t1tables.h index a6ea415af5..3503c2616b 100644 --- a/src/3rdparty/freetype/include/freetype/t1tables.h +++ b/src/3rdparty/freetype/include/freetype/t1tables.h @@ -5,7 +5,7 @@ /* Basic Type 1/Type 2 tables definitions and interface (specification */ /* only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __T1TABLES_H__ -#define __T1TABLES_H__ +#ifndef T1TABLES_H_ +#define T1TABLES_H_ #include <ft2build.h> @@ -291,7 +291,7 @@ FT_BEGIN_HEADER } PS_DesignMapRec, *PS_DesignMap; - /* backwards-compatible definition */ + /* backward compatible definition */ typedef PS_DesignMapRec T1_DesignMap; @@ -326,7 +326,7 @@ FT_BEGIN_HEADER } PS_BlendRec, *PS_Blend; - /* backwards-compatible definition */ + /* backward compatible definition */ typedef PS_BlendRec T1_Blend; @@ -554,6 +554,9 @@ FT_BEGIN_HEADER /* T1_ENCODING_TYPE_ISOLATIN1 :: */ /* T1_ENCODING_TYPE_EXPERT :: */ /* */ + /* <Since> */ + /* 2.4.8 */ + /* */ typedef enum T1_EncodingType_ { T1_ENCODING_TYPE_NONE = 0, @@ -622,6 +625,9 @@ FT_BEGIN_HEADER /* PS_DICT_FS_TYPE :: */ /* PS_DICT_ITALIC_ANGLE :: */ /* */ + /* <Since> */ + /* 2.4.8 */ + /* */ typedef enum PS_Dict_Keys_ { /* conventionally in the font dictionary */ @@ -743,6 +749,9 @@ FT_BEGIN_HEADER * If the font's format is not PostScript-based, this function returns * the `FT_Err_Invalid_Argument' error code. * + * @since: + * 2.4.8 + * */ FT_EXPORT( FT_Long ) FT_Get_PS_Font_Value( FT_Face face, @@ -755,7 +764,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1TABLES_H__ */ +#endif /* T1TABLES_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/ttnameid.h b/src/3rdparty/freetype/include/freetype/ttnameid.h index c9585f2413..8605183dc7 100644 --- a/src/3rdparty/freetype/include/freetype/ttnameid.h +++ b/src/3rdparty/freetype/include/freetype/ttnameid.h @@ -4,7 +4,7 @@ /* */ /* TrueType name ID definitions (specification only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTNAMEID_H__ -#define __TTNAMEID_H__ +#ifndef TTNAMEID_H_ +#define TTNAMEID_H_ #include <ft2build.h> @@ -36,7 +36,7 @@ FT_BEGIN_HEADER /*************************************************************************/ /* */ /* Possible values for the `platform' identifier code in the name */ - /* records of the TTF `name' table. */ + /* records of an SFNT `name' table. */ /* */ /*************************************************************************/ @@ -119,14 +119,19 @@ FT_BEGIN_HEADER * TT_APPLE_ID_VARIANT_SELECTOR :: * From Adobe, not Apple. Not a normal cmap. Specifies variations * on a real cmap. + * + * TT_APPLE_ID_FULL_UNICODE :: + * Used for fallback fonts that provide complete Unicode coverage with + * a type~13 cmap. */ -#define TT_APPLE_ID_DEFAULT 0 /* Unicode 1.0 */ -#define TT_APPLE_ID_UNICODE_1_1 1 /* specify Hangul at U+34xx */ -#define TT_APPLE_ID_ISO_10646 2 /* deprecated */ -#define TT_APPLE_ID_UNICODE_2_0 3 /* or later */ +#define TT_APPLE_ID_DEFAULT 0 /* Unicode 1.0 */ +#define TT_APPLE_ID_UNICODE_1_1 1 /* specify Hangul at U+34xx */ +#define TT_APPLE_ID_ISO_10646 2 /* deprecated */ +#define TT_APPLE_ID_UNICODE_2_0 3 /* or later */ #define TT_APPLE_ID_UNICODE_32 4 /* 2.0 or later, full repertoire */ -#define TT_APPLE_ID_VARIANT_SELECTOR 5 /* variation selector data */ +#define TT_APPLE_ID_VARIANT_SELECTOR 5 /* variation selector data */ +#define TT_APPLE_ID_FULL_UNICODE 6 /* used with type 13 cmaps */ /*********************************************************************** @@ -137,42 +142,6 @@ FT_BEGIN_HEADER * @description: * A list of valid values for the `encoding_id' for * @TT_PLATFORM_MACINTOSH charmaps and name entries. - * - * @values: - * TT_MAC_ID_ROMAN :: - * TT_MAC_ID_JAPANESE :: - * TT_MAC_ID_TRADITIONAL_CHINESE :: - * TT_MAC_ID_KOREAN :: - * TT_MAC_ID_ARABIC :: - * TT_MAC_ID_HEBREW :: - * TT_MAC_ID_GREEK :: - * TT_MAC_ID_RUSSIAN :: - * TT_MAC_ID_RSYMBOL :: - * TT_MAC_ID_DEVANAGARI :: - * TT_MAC_ID_GURMUKHI :: - * TT_MAC_ID_GUJARATI :: - * TT_MAC_ID_ORIYA :: - * TT_MAC_ID_BENGALI :: - * TT_MAC_ID_TAMIL :: - * TT_MAC_ID_TELUGU :: - * TT_MAC_ID_KANNADA :: - * TT_MAC_ID_MALAYALAM :: - * TT_MAC_ID_SINHALESE :: - * TT_MAC_ID_BURMESE :: - * TT_MAC_ID_KHMER :: - * TT_MAC_ID_THAI :: - * TT_MAC_ID_LAOTIAN :: - * TT_MAC_ID_GEORGIAN :: - * TT_MAC_ID_ARMENIAN :: - * TT_MAC_ID_MALDIVIAN :: - * TT_MAC_ID_SIMPLIFIED_CHINESE :: - * TT_MAC_ID_TIBETAN :: - * TT_MAC_ID_MONGOLIAN :: - * TT_MAC_ID_GEEZ :: - * TT_MAC_ID_SLAVIC :: - * TT_MAC_ID_VIETNAMESE :: - * TT_MAC_ID_SINDHI :: - * TT_MAC_ID_UNINTERP :: */ #define TT_MAC_ID_ROMAN 0 @@ -247,44 +216,47 @@ FT_BEGIN_HEADER * * @values: * TT_MS_ID_SYMBOL_CS :: - * Corresponds to Microsoft symbol encoding. See - * @FT_ENCODING_MS_SYMBOL. + * Microsoft symbol encoding. See @FT_ENCODING_MS_SYMBOL. * * TT_MS_ID_UNICODE_CS :: - * Corresponds to a Microsoft WGL4 charmap, matching Unicode. See + * Microsoft WGL4 charmap, matching Unicode. See * @FT_ENCODING_UNICODE. * * TT_MS_ID_SJIS :: - * Corresponds to SJIS Japanese encoding. See @FT_ENCODING_SJIS. + * Shift JIS Japanese encoding. See @FT_ENCODING_SJIS. * - * TT_MS_ID_GB2312 :: - * Corresponds to Simplified Chinese as used in Mainland China. See - * @FT_ENCODING_GB2312. + * TT_MS_ID_PRC :: + * Chinese encodings as used in the People's Republic of China (PRC). + * This means the encodings GB~2312 and its supersets GBK and + * GB~18030. See @FT_ENCODING_PRC. * * TT_MS_ID_BIG_5 :: - * Corresponds to Traditional Chinese as used in Taiwan and Hong Kong. - * See @FT_ENCODING_BIG5. + * Traditional Chinese as used in Taiwan and Hong Kong. See + * @FT_ENCODING_BIG5. * * TT_MS_ID_WANSUNG :: - * Corresponds to Korean Wansung encoding. See @FT_ENCODING_WANSUNG. + * Korean Extended Wansung encoding. See @FT_ENCODING_WANSUNG. * * TT_MS_ID_JOHAB :: - * Corresponds to Johab encoding. See @FT_ENCODING_JOHAB. + * Korean Johab encoding. See @FT_ENCODING_JOHAB. * * TT_MS_ID_UCS_4 :: - * Corresponds to UCS-4 or UTF-32 charmaps. This has been added to - * the OpenType specification version 1.4 (mid-2001.) + * UCS-4 or UTF-32 charmaps. This has been added to the OpenType + * specification version 1.4 (mid-2001). */ #define TT_MS_ID_SYMBOL_CS 0 #define TT_MS_ID_UNICODE_CS 1 #define TT_MS_ID_SJIS 2 -#define TT_MS_ID_GB2312 3 +#define TT_MS_ID_PRC 3 #define TT_MS_ID_BIG_5 4 #define TT_MS_ID_WANSUNG 5 #define TT_MS_ID_JOHAB 6 #define TT_MS_ID_UCS_4 10 + /* this value is deprecated */ +#define TT_MS_ID_GB2312 TT_MS_ID_PRC + /*********************************************************************** * @@ -312,17 +284,22 @@ FT_BEGIN_HEADER #define TT_ADOBE_ID_LATIN_1 3 - /*************************************************************************/ - /* */ - /* Possible values of the language identifier field in the name records */ - /* of the TTF `name' table if the `platform' identifier code is */ - /* TT_PLATFORM_MACINTOSH. These values are also used as return values */ - /* for function @FT_Get_CMap_Language_ID. */ - /* */ - /* The canonical source for the Apple assigned Language ID's is at */ - /* */ - /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6name.html */ - /* */ + /*********************************************************************** + * + * @enum: + * TT_MAC_LANGID_XXX + * + * @description: + * Possible values of the language identifier field in the name records + * of the SFNT `name' table if the `platform' identifier code is + * @TT_PLATFORM_MACINTOSH. These values are also used as return values + * for function @FT_Get_CMap_Language_ID. + * + * The canonical source for Apple's IDs is + * + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6name.html + */ + #define TT_MAC_LANGID_ENGLISH 0 #define TT_MAC_LANGID_FRENCH 1 #define TT_MAC_LANGID_GERMAN 2 @@ -433,15 +410,6 @@ FT_BEGIN_HEADER #define TT_MAC_LANGID_JAVANESE 138 #define TT_MAC_LANGID_SUNDANESE 139 - -#if 0 /* these seem to be errors that have been dropped */ - -#define TT_MAC_LANGID_SCOTTISH_GAELIC 140 -#define TT_MAC_LANGID_IRISH_GAELIC 141 - -#endif - - /* The following codes are new as of 2000-03-10 */ #define TT_MAC_LANGID_GALICIAN 140 #define TT_MAC_LANGID_AFRIKAANS 141 @@ -456,18 +424,30 @@ FT_BEGIN_HEADER #define TT_MAC_LANGID_AZERBAIJANI_ROMAN_SCRIPT 150 - /*************************************************************************/ - /* */ - /* Possible values of the language identifier field in the name records */ - /* of the TTF `name' table if the `platform' identifier code is */ - /* TT_PLATFORM_MICROSOFT. */ - /* */ - /* The canonical source for the MS assigned LCIDs is */ - /* */ - /* http://www.microsoft.com/globaldev/reference/lcid-all.mspx */ - /* */ + /*********************************************************************** + * + * @enum: + * TT_MS_LANGID_XXX + * + * @description: + * Possible values of the language identifier field in the name records + * of the SFNT `name' table if the `platform' identifier code is + * @TT_PLATFORM_MICROSOFT. These values are also used as return values + * for function @FT_Get_CMap_Language_ID. + * + * The canonical source for Microsoft's IDs is + * + * https://www.microsoft.com/globaldev/reference/lcid-all.mspx , + * + * however, we only provide macros for language identifiers present in + * the OpenType specification: Microsoft has abandoned the concept of + * LCIDs (language code identifiers), and format~1 of the `name' table + * provides a better mechanism for languages not covered here. + * + * More legacy values not listed in the reference can be found in the + * @FT_TRUETYPE_IDS_H header file. + */ -#define TT_MS_LANGID_ARABIC_GENERAL 0x0001 #define TT_MS_LANGID_ARABIC_SAUDI_ARABIA 0x0401 #define TT_MS_LANGID_ARABIC_IRAQ 0x0801 #define TT_MS_LANGID_ARABIC_EGYPT 0x0C01 @@ -485,39 +465,20 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_ARABIC_BAHRAIN 0x3C01 #define TT_MS_LANGID_ARABIC_QATAR 0x4001 #define TT_MS_LANGID_BULGARIAN_BULGARIA 0x0402 -#define TT_MS_LANGID_CATALAN_SPAIN 0x0403 -#define TT_MS_LANGID_CHINESE_GENERAL 0x0004 +#define TT_MS_LANGID_CATALAN_CATALAN 0x0403 #define TT_MS_LANGID_CHINESE_TAIWAN 0x0404 #define TT_MS_LANGID_CHINESE_PRC 0x0804 #define TT_MS_LANGID_CHINESE_HONG_KONG 0x0C04 #define TT_MS_LANGID_CHINESE_SINGAPORE 0x1004 - -#if 1 /* this looks like the correct value */ -#define TT_MS_LANGID_CHINESE_MACAU 0x1404 -#else /* but beware, Microsoft may change its mind... - the most recent Word reference has the following: */ -#define TT_MS_LANGID_CHINESE_MACAU TT_MS_LANGID_CHINESE_HONG_KONG -#endif - -#if 0 /* used only with .NET `cultures'; commented out */ -#define TT_MS_LANGID_CHINESE_TRADITIONAL 0x7C04 -#endif - +#define TT_MS_LANGID_CHINESE_MACAO 0x1404 #define TT_MS_LANGID_CZECH_CZECH_REPUBLIC 0x0405 #define TT_MS_LANGID_DANISH_DENMARK 0x0406 #define TT_MS_LANGID_GERMAN_GERMANY 0x0407 #define TT_MS_LANGID_GERMAN_SWITZERLAND 0x0807 #define TT_MS_LANGID_GERMAN_AUSTRIA 0x0C07 #define TT_MS_LANGID_GERMAN_LUXEMBOURG 0x1007 -#define TT_MS_LANGID_GERMAN_LIECHTENSTEI 0x1407 +#define TT_MS_LANGID_GERMAN_LIECHTENSTEIN 0x1407 #define TT_MS_LANGID_GREEK_GREECE 0x0408 - - /* don't ask what this one means... It is commented out currently. */ -#if 0 -#define TT_MS_LANGID_GREEK_GREECE2 0x2008 -#endif - -#define TT_MS_LANGID_ENGLISH_GENERAL 0x0009 #define TT_MS_LANGID_ENGLISH_UNITED_STATES 0x0409 #define TT_MS_LANGID_ENGLISH_UNITED_KINGDOM 0x0809 #define TT_MS_LANGID_ENGLISH_AUSTRALIA 0x0C09 @@ -531,14 +492,12 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_ENGLISH_TRINIDAD 0x2C09 #define TT_MS_LANGID_ENGLISH_ZIMBABWE 0x3009 #define TT_MS_LANGID_ENGLISH_PHILIPPINES 0x3409 -#define TT_MS_LANGID_ENGLISH_INDONESIA 0x3809 -#define TT_MS_LANGID_ENGLISH_HONG_KONG 0x3C09 #define TT_MS_LANGID_ENGLISH_INDIA 0x4009 #define TT_MS_LANGID_ENGLISH_MALAYSIA 0x4409 #define TT_MS_LANGID_ENGLISH_SINGAPORE 0x4809 #define TT_MS_LANGID_SPANISH_SPAIN_TRADITIONAL_SORT 0x040A #define TT_MS_LANGID_SPANISH_MEXICO 0x080A -#define TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT 0x0C0A +#define TT_MS_LANGID_SPANISH_SPAIN_MODERN_SORT 0x0C0A #define TT_MS_LANGID_SPANISH_GUATEMALA 0x100A #define TT_MS_LANGID_SPANISH_COSTA_RICA 0x140A #define TT_MS_LANGID_SPANISH_PANAMA 0x180A @@ -557,9 +516,6 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_SPANISH_NICARAGUA 0x4C0A #define TT_MS_LANGID_SPANISH_PUERTO_RICO 0x500A #define TT_MS_LANGID_SPANISH_UNITED_STATES 0x540A - /* The following ID blatantly violate MS specs by using a */ - /* sublanguage > 0x1F. */ -#define TT_MS_LANGID_SPANISH_LATIN_AMERICA 0xE40AU #define TT_MS_LANGID_FINNISH_FINLAND 0x040B #define TT_MS_LANGID_FRENCH_FRANCE 0x040C #define TT_MS_LANGID_FRENCH_BELGIUM 0x080C @@ -567,27 +523,13 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_FRENCH_SWITZERLAND 0x100C #define TT_MS_LANGID_FRENCH_LUXEMBOURG 0x140C #define TT_MS_LANGID_FRENCH_MONACO 0x180C -#define TT_MS_LANGID_FRENCH_WEST_INDIES 0x1C0C -#define TT_MS_LANGID_FRENCH_REUNION 0x200C -#define TT_MS_LANGID_FRENCH_CONGO 0x240C - /* which was formerly: */ -#define TT_MS_LANGID_FRENCH_ZAIRE TT_MS_LANGID_FRENCH_CONGO -#define TT_MS_LANGID_FRENCH_SENEGAL 0x280C -#define TT_MS_LANGID_FRENCH_CAMEROON 0x2C0C -#define TT_MS_LANGID_FRENCH_COTE_D_IVOIRE 0x300C -#define TT_MS_LANGID_FRENCH_MALI 0x340C -#define TT_MS_LANGID_FRENCH_MOROCCO 0x380C -#define TT_MS_LANGID_FRENCH_HAITI 0x3C0C - /* and another violation of the spec (see 0xE40AU) */ -#define TT_MS_LANGID_FRENCH_NORTH_AFRICA 0xE40CU #define TT_MS_LANGID_HEBREW_ISRAEL 0x040D #define TT_MS_LANGID_HUNGARIAN_HUNGARY 0x040E #define TT_MS_LANGID_ICELANDIC_ICELAND 0x040F #define TT_MS_LANGID_ITALIAN_ITALY 0x0410 #define TT_MS_LANGID_ITALIAN_SWITZERLAND 0x0810 #define TT_MS_LANGID_JAPANESE_JAPAN 0x0411 -#define TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA 0x0412 -#define TT_MS_LANGID_KOREAN_JOHAB_KOREA 0x0812 +#define TT_MS_LANGID_KOREAN_KOREA 0x0412 #define TT_MS_LANGID_DUTCH_NETHERLANDS 0x0413 #define TT_MS_LANGID_DUTCH_BELGIUM 0x0813 #define TT_MS_LANGID_NORWEGIAN_NORWAY_BOKMAL 0x0414 @@ -595,26 +537,17 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_POLISH_POLAND 0x0415 #define TT_MS_LANGID_PORTUGUESE_BRAZIL 0x0416 #define TT_MS_LANGID_PORTUGUESE_PORTUGAL 0x0816 -#define TT_MS_LANGID_RHAETO_ROMANIC_SWITZERLAND 0x0417 +#define TT_MS_LANGID_ROMANSH_SWITZERLAND 0x0417 #define TT_MS_LANGID_ROMANIAN_ROMANIA 0x0418 -#define TT_MS_LANGID_MOLDAVIAN_MOLDAVIA 0x0818 #define TT_MS_LANGID_RUSSIAN_RUSSIA 0x0419 -#define TT_MS_LANGID_RUSSIAN_MOLDAVIA 0x0819 #define TT_MS_LANGID_CROATIAN_CROATIA 0x041A #define TT_MS_LANGID_SERBIAN_SERBIA_LATIN 0x081A #define TT_MS_LANGID_SERBIAN_SERBIA_CYRILLIC 0x0C1A - -#if 0 /* this used to be this value, but it looks like we were wrong */ -#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA 0x101A -#else /* current sources say */ #define TT_MS_LANGID_CROATIAN_BOSNIA_HERZEGOVINA 0x101A #define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZEGOVINA 0x141A - /* and XPsp2 Platform SDK added (2004-07-26) */ - /* Names are shortened to be significant within 40 chars. */ #define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_LATIN 0x181A -#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_CYRILLIC 0x181A -#endif - +#define TT_MS_LANGID_SERBIAN_BOSNIA_HERZ_CYRILLIC 0x1C1A +#define TT_MS_LANGID_BOSNIAN_BOSNIA_HERZ_CYRILLIC 0x201A #define TT_MS_LANGID_SLOVAK_SLOVAKIA 0x041B #define TT_MS_LANGID_ALBANIAN_ALBANIA 0x041C #define TT_MS_LANGID_SWEDISH_SWEDEN 0x041D @@ -622,36 +555,30 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_THAI_THAILAND 0x041E #define TT_MS_LANGID_TURKISH_TURKEY 0x041F #define TT_MS_LANGID_URDU_PAKISTAN 0x0420 -#define TT_MS_LANGID_URDU_INDIA 0x0820 #define TT_MS_LANGID_INDONESIAN_INDONESIA 0x0421 #define TT_MS_LANGID_UKRAINIAN_UKRAINE 0x0422 #define TT_MS_LANGID_BELARUSIAN_BELARUS 0x0423 -#define TT_MS_LANGID_SLOVENE_SLOVENIA 0x0424 +#define TT_MS_LANGID_SLOVENIAN_SLOVENIA 0x0424 #define TT_MS_LANGID_ESTONIAN_ESTONIA 0x0425 #define TT_MS_LANGID_LATVIAN_LATVIA 0x0426 #define TT_MS_LANGID_LITHUANIAN_LITHUANIA 0x0427 -#define TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA 0x0827 #define TT_MS_LANGID_TAJIK_TAJIKISTAN 0x0428 -#define TT_MS_LANGID_FARSI_IRAN 0x0429 #define TT_MS_LANGID_VIETNAMESE_VIET_NAM 0x042A #define TT_MS_LANGID_ARMENIAN_ARMENIA 0x042B #define TT_MS_LANGID_AZERI_AZERBAIJAN_LATIN 0x042C #define TT_MS_LANGID_AZERI_AZERBAIJAN_CYRILLIC 0x082C -#define TT_MS_LANGID_BASQUE_SPAIN 0x042D -#define TT_MS_LANGID_SORBIAN_GERMANY 0x042E +#define TT_MS_LANGID_BASQUE_BASQUE 0x042D +#define TT_MS_LANGID_UPPER_SORBIAN_GERMANY 0x042E +#define TT_MS_LANGID_LOWER_SORBIAN_GERMANY 0x082E #define TT_MS_LANGID_MACEDONIAN_MACEDONIA 0x042F -#define TT_MS_LANGID_SUTU_SOUTH_AFRICA 0x0430 -#define TT_MS_LANGID_TSONGA_SOUTH_AFRICA 0x0431 -#define TT_MS_LANGID_TSWANA_SOUTH_AFRICA 0x0432 -#define TT_MS_LANGID_VENDA_SOUTH_AFRICA 0x0433 -#define TT_MS_LANGID_XHOSA_SOUTH_AFRICA 0x0434 -#define TT_MS_LANGID_ZULU_SOUTH_AFRICA 0x0435 +#define TT_MS_LANGID_SETSWANA_SOUTH_AFRICA 0x0432 +#define TT_MS_LANGID_ISIXHOSA_SOUTH_AFRICA 0x0434 +#define TT_MS_LANGID_ISIZULU_SOUTH_AFRICA 0x0435 #define TT_MS_LANGID_AFRIKAANS_SOUTH_AFRICA 0x0436 #define TT_MS_LANGID_GEORGIAN_GEORGIA 0x0437 #define TT_MS_LANGID_FAEROESE_FAEROE_ISLANDS 0x0438 #define TT_MS_LANGID_HINDI_INDIA 0x0439 #define TT_MS_LANGID_MALTESE_MALTA 0x043A - /* Added by XPsp2 Platform SDK (2004-07-26) */ #define TT_MS_LANGID_SAMI_NORTHERN_NORWAY 0x043B #define TT_MS_LANGID_SAMI_NORTHERN_SWEDEN 0x083B #define TT_MS_LANGID_SAMI_NORTHERN_FINLAND 0x0C3B @@ -661,37 +588,21 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_SAMI_SOUTHERN_SWEDEN 0x1C3B #define TT_MS_LANGID_SAMI_SKOLT_FINLAND 0x203B #define TT_MS_LANGID_SAMI_INARI_FINLAND 0x243B - /* ... and we also keep our old identifier... */ -#define TT_MS_LANGID_SAAMI_LAPONIA 0x043B - -#if 0 /* this seems to be a previous inversion */ -#define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043C -#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083C -#else -#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083C -#define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043C -#endif - -#define TT_MS_LANGID_YIDDISH_GERMANY 0x043D +#define TT_MS_LANGID_IRISH_IRELAND 0x083C #define TT_MS_LANGID_MALAY_MALAYSIA 0x043E #define TT_MS_LANGID_MALAY_BRUNEI_DARUSSALAM 0x083E -#define TT_MS_LANGID_KAZAK_KAZAKSTAN 0x043F -#define TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN /* Cyrillic*/ 0x0440 - /* alias declared in Windows 2000 */ -#define TT_MS_LANGID_KIRGHIZ_KIRGHIZ_REPUBLIC \ - TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN - -#define TT_MS_LANGID_SWAHILI_KENYA 0x0441 +#define TT_MS_LANGID_KAZAKH_KAZAKHSTAN 0x043F +#define TT_MS_LANGID_KYRGYZ_KYRGYZSTAN /* Cyrillic*/ 0x0440 +#define TT_MS_LANGID_KISWAHILI_KENYA 0x0441 #define TT_MS_LANGID_TURKMEN_TURKMENISTAN 0x0442 #define TT_MS_LANGID_UZBEK_UZBEKISTAN_LATIN 0x0443 #define TT_MS_LANGID_UZBEK_UZBEKISTAN_CYRILLIC 0x0843 -#define TT_MS_LANGID_TATAR_TATARSTAN 0x0444 +#define TT_MS_LANGID_TATAR_RUSSIA 0x0444 #define TT_MS_LANGID_BENGALI_INDIA 0x0445 #define TT_MS_LANGID_BENGALI_BANGLADESH 0x0845 #define TT_MS_LANGID_PUNJABI_INDIA 0x0446 -#define TT_MS_LANGID_PUNJABI_ARABIC_PAKISTAN 0x0846 #define TT_MS_LANGID_GUJARATI_INDIA 0x0447 -#define TT_MS_LANGID_ORIYA_INDIA 0x0448 +#define TT_MS_LANGID_ODIA_INDIA 0x0448 #define TT_MS_LANGID_TAMIL_INDIA 0x0449 #define TT_MS_LANGID_TELUGU_INDIA 0x044A #define TT_MS_LANGID_KANNADA_INDIA 0x044B @@ -700,142 +611,241 @@ FT_BEGIN_HEADER #define TT_MS_LANGID_MARATHI_INDIA 0x044E #define TT_MS_LANGID_SANSKRIT_INDIA 0x044F #define TT_MS_LANGID_MONGOLIAN_MONGOLIA /* Cyrillic */ 0x0450 -#define TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIAN 0x0850 -#define TT_MS_LANGID_TIBETAN_CHINA 0x0451 - /* Don't use the next constant! It has */ - /* (1) the wrong spelling (Dzonghka) */ - /* (2) Microsoft doesn't officially define it -- */ - /* at least it is not in the List of Local */ - /* ID Values. */ - /* (3) Dzongkha is not the same language as */ - /* Tibetan, so merging it is wrong anyway. */ - /* */ - /* TT_MS_LANGID_TIBETAN_BHUTAN is correct, BTW. */ -#define TT_MS_LANGID_DZONGHKA_BHUTAN 0x0851 - -#if 0 - /* the following used to be defined */ -#define TT_MS_LANGID_TIBETAN_BHUTAN 0x0451 - /* ... but it was changed; */ -#else - /* So we will continue to #define it, but with the correct value */ -#define TT_MS_LANGID_TIBETAN_BHUTAN TT_MS_LANGID_DZONGHKA_BHUTAN -#endif - -#define TT_MS_LANGID_WELSH_WALES 0x0452 +#define TT_MS_LANGID_MONGOLIAN_PRC 0x0850 +#define TT_MS_LANGID_TIBETAN_PRC 0x0451 +#define TT_MS_LANGID_WELSH_UNITED_KINGDOM 0x0452 #define TT_MS_LANGID_KHMER_CAMBODIA 0x0453 #define TT_MS_LANGID_LAO_LAOS 0x0454 -#define TT_MS_LANGID_BURMESE_MYANMAR 0x0455 -#define TT_MS_LANGID_GALICIAN_SPAIN 0x0456 +#define TT_MS_LANGID_GALICIAN_GALICIAN 0x0456 #define TT_MS_LANGID_KONKANI_INDIA 0x0457 -#define TT_MS_LANGID_MANIPURI_INDIA /* Bengali */ 0x0458 -#define TT_MS_LANGID_SINDHI_INDIA /* Arabic */ 0x0459 -#define TT_MS_LANGID_SINDHI_PAKISTAN 0x0859 - /* Missing a LCID for Sindhi in Devanagari script */ #define TT_MS_LANGID_SYRIAC_SYRIA 0x045A -#define TT_MS_LANGID_SINHALESE_SRI_LANKA 0x045B -#define TT_MS_LANGID_CHEROKEE_UNITED_STATES 0x045C +#define TT_MS_LANGID_SINHALA_SRI_LANKA 0x045B #define TT_MS_LANGID_INUKTITUT_CANADA 0x045D +#define TT_MS_LANGID_INUKTITUT_CANADA_LATIN 0x085D #define TT_MS_LANGID_AMHARIC_ETHIOPIA 0x045E -#define TT_MS_LANGID_TAMAZIGHT_MOROCCO /* Arabic */ 0x045F -#define TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN 0x085F - /* Missing a LCID for Tifinagh script */ -#define TT_MS_LANGID_KASHMIRI_PAKISTAN /* Arabic */ 0x0460 - /* Spelled this way by XPsp2 Platform SDK (2004-07-26) */ - /* script is yet unclear... might be Arabic, Nagari or Sharada */ -#define TT_MS_LANGID_KASHMIRI_SASIA 0x0860 - /* ... and aliased (by MS) for compatibility reasons. */ -#define TT_MS_LANGID_KASHMIRI_INDIA TT_MS_LANGID_KASHMIRI_SASIA +#define TT_MS_LANGID_TAMAZIGHT_ALGERIA 0x085F #define TT_MS_LANGID_NEPALI_NEPAL 0x0461 -#define TT_MS_LANGID_NEPALI_INDIA 0x0861 #define TT_MS_LANGID_FRISIAN_NETHERLANDS 0x0462 #define TT_MS_LANGID_PASHTO_AFGHANISTAN 0x0463 #define TT_MS_LANGID_FILIPINO_PHILIPPINES 0x0464 #define TT_MS_LANGID_DHIVEHI_MALDIVES 0x0465 - /* alias declared in Windows 2000 */ -#define TT_MS_LANGID_DIVEHI_MALDIVES TT_MS_LANGID_DHIVEHI_MALDIVES -#define TT_MS_LANGID_EDO_NIGERIA 0x0466 -#define TT_MS_LANGID_FULFULDE_NIGERIA 0x0467 #define TT_MS_LANGID_HAUSA_NIGERIA 0x0468 -#define TT_MS_LANGID_IBIBIO_NIGERIA 0x0469 #define TT_MS_LANGID_YORUBA_NIGERIA 0x046A #define TT_MS_LANGID_QUECHUA_BOLIVIA 0x046B #define TT_MS_LANGID_QUECHUA_ECUADOR 0x086B #define TT_MS_LANGID_QUECHUA_PERU 0x0C6B -#define TT_MS_LANGID_SEPEDI_SOUTH_AFRICA 0x046C - /* Also spelled by XPsp2 Platform SDK (2004-07-26) */ -#define TT_MS_LANGID_SOTHO_SOUTHERN_SOUTH_AFRICA \ - TT_MS_LANGID_SEPEDI_SOUTH_AFRICA - /* language codes 0x046D, 0x046E and 0x046F are (still) unknown. */ +#define TT_MS_LANGID_SESOTHO_SA_LEBOA_SOUTH_AFRICA 0x046C +#define TT_MS_LANGID_BASHKIR_RUSSIA 0x046D +#define TT_MS_LANGID_LUXEMBOURGISH_LUXEMBOURG 0x046E +#define TT_MS_LANGID_GREENLANDIC_GREENLAND 0x046F #define TT_MS_LANGID_IGBO_NIGERIA 0x0470 +#define TT_MS_LANGID_YI_PRC 0x0478 +#define TT_MS_LANGID_MAPUDUNGUN_CHILE 0x047A +#define TT_MS_LANGID_MOHAWK_MOHAWK 0x047C +#define TT_MS_LANGID_BRETON_FRANCE 0x047E +#define TT_MS_LANGID_UIGHUR_PRC 0x0480 +#define TT_MS_LANGID_MAORI_NEW_ZEALAND 0x0481 +#define TT_MS_LANGID_OCCITAN_FRANCE 0x0482 +#define TT_MS_LANGID_CORSICAN_FRANCE 0x0483 +#define TT_MS_LANGID_ALSATIAN_FRANCE 0x0484 +#define TT_MS_LANGID_YAKUT_RUSSIA 0x0485 +#define TT_MS_LANGID_KICHE_GUATEMALA 0x0486 +#define TT_MS_LANGID_KINYARWANDA_RWANDA 0x0487 +#define TT_MS_LANGID_WOLOF_SENEGAL 0x0488 +#define TT_MS_LANGID_DARI_AFGHANISTAN 0x048C + + /* */ + + + /* legacy macro definitions not present in OpenType 1.8.1 */ +#define TT_MS_LANGID_ARABIC_GENERAL 0x0001 +#define TT_MS_LANGID_CATALAN_SPAIN \ + TT_MS_LANGID_CATALAN_CATALAN +#define TT_MS_LANGID_CHINESE_GENERAL 0x0004 +#define TT_MS_LANGID_CHINESE_MACAU \ + TT_MS_LANGID_CHINESE_MACAO +#define TT_MS_LANGID_GERMAN_LIECHTENSTEI \ + TT_MS_LANGID_GERMAN_LIECHTENSTEIN +#define TT_MS_LANGID_ENGLISH_GENERAL 0x0009 +#define TT_MS_LANGID_ENGLISH_INDONESIA 0x3809 +#define TT_MS_LANGID_ENGLISH_HONG_KONG 0x3C09 +#define TT_MS_LANGID_SPANISH_SPAIN_INTERNATIONAL_SORT \ + TT_MS_LANGID_SPANISH_SPAIN_MODERN_SORT +#define TT_MS_LANGID_SPANISH_LATIN_AMERICA 0xE40AU +#define TT_MS_LANGID_FRENCH_WEST_INDIES 0x1C0C +#define TT_MS_LANGID_FRENCH_REUNION 0x200C +#define TT_MS_LANGID_FRENCH_CONGO 0x240C + /* which was formerly: */ +#define TT_MS_LANGID_FRENCH_ZAIRE \ + TT_MS_LANGID_FRENCH_CONGO +#define TT_MS_LANGID_FRENCH_SENEGAL 0x280C +#define TT_MS_LANGID_FRENCH_CAMEROON 0x2C0C +#define TT_MS_LANGID_FRENCH_COTE_D_IVOIRE 0x300C +#define TT_MS_LANGID_FRENCH_MALI 0x340C +#define TT_MS_LANGID_FRENCH_MOROCCO 0x380C +#define TT_MS_LANGID_FRENCH_HAITI 0x3C0C +#define TT_MS_LANGID_FRENCH_NORTH_AFRICA 0xE40CU +#define TT_MS_LANGID_KOREAN_EXTENDED_WANSUNG_KOREA \ + TT_MS_LANGID_KOREAN_KOREA +#define TT_MS_LANGID_KOREAN_JOHAB_KOREA 0x0812 +#define TT_MS_LANGID_RHAETO_ROMANIC_SWITZERLAND \ + TT_MS_LANGID_ROMANSH_SWITZERLAND +#define TT_MS_LANGID_MOLDAVIAN_MOLDAVIA 0x0818 +#define TT_MS_LANGID_RUSSIAN_MOLDAVIA 0x0819 +#define TT_MS_LANGID_URDU_INDIA 0x0820 +#define TT_MS_LANGID_CLASSIC_LITHUANIAN_LITHUANIA 0x0827 +#define TT_MS_LANGID_SLOVENE_SLOVENIA \ + TT_MS_LANGID_SLOVENIAN_SLOVENIA +#define TT_MS_LANGID_FARSI_IRAN 0x0429 +#define TT_MS_LANGID_BASQUE_SPAIN \ + TT_MS_LANGID_BASQUE_BASQUE +#define TT_MS_LANGID_SORBIAN_GERMANY \ + TT_MS_LANGID_UPPER_SORBIAN_GERMANY +#define TT_MS_LANGID_SUTU_SOUTH_AFRICA 0x0430 +#define TT_MS_LANGID_TSONGA_SOUTH_AFRICA 0x0431 +#define TT_MS_LANGID_TSWANA_SOUTH_AFRICA \ + TT_MS_LANGID_SETSWANA_SOUTH_AFRICA +#define TT_MS_LANGID_VENDA_SOUTH_AFRICA 0x0433 +#define TT_MS_LANGID_XHOSA_SOUTH_AFRICA \ + TT_MS_LANGID_ISIXHOSA_SOUTH_AFRICA +#define TT_MS_LANGID_ZULU_SOUTH_AFRICA \ + TT_MS_LANGID_ISIZULU_SOUTH_AFRICA +#define TT_MS_LANGID_SAAMI_LAPONIA 0x043B + /* the next two values are incorrectly inverted */ +#define TT_MS_LANGID_IRISH_GAELIC_IRELAND 0x043C +#define TT_MS_LANGID_SCOTTISH_GAELIC_UNITED_KINGDOM 0x083C +#define TT_MS_LANGID_YIDDISH_GERMANY 0x043D +#define TT_MS_LANGID_KAZAK_KAZAKSTAN \ + TT_MS_LANGID_KAZAKH_KAZAKHSTAN +#define TT_MS_LANGID_KIRGHIZ_KIRGHIZ_REPUBLIC \ + TT_MS_LANGID_KYRGYZ_KYRGYZSTAN +#define TT_MS_LANGID_KIRGHIZ_KIRGHIZSTAN \ + TT_MS_LANGID_KYRGYZ_KYRGYZSTAN +#define TT_MS_LANGID_SWAHILI_KENYA \ + TT_MS_LANGID_KISWAHILI_KENYA +#define TT_MS_LANGID_TATAR_TATARSTAN \ + TT_MS_LANGID_TATAR_RUSSIA +#define TT_MS_LANGID_PUNJABI_ARABIC_PAKISTAN 0x0846 +#define TT_MS_LANGID_ORIYA_INDIA \ + TT_MS_LANGID_ODIA_INDIA +#define TT_MS_LANGID_MONGOLIAN_MONGOLIA_MONGOLIAN \ + TT_MS_LANGID_MONGOLIAN_PRC +#define TT_MS_LANGID_TIBETAN_CHINA \ + TT_MS_LANGID_TIBETAN_PRC +#define TT_MS_LANGID_DZONGHKA_BHUTAN 0x0851 +#define TT_MS_LANGID_TIBETAN_BHUTAN \ + TT_MS_LANGID_DZONGHKA_BHUTAN +#define TT_MS_LANGID_WELSH_WALES \ + TT_MS_LANGID_WELSH_UNITED_KINGDOM +#define TT_MS_LANGID_BURMESE_MYANMAR 0x0455 +#define TT_MS_LANGID_GALICIAN_SPAIN \ + TT_MS_LANGID_GALICIAN_GALICIAN +#define TT_MS_LANGID_MANIPURI_INDIA /* Bengali */ 0x0458 +#define TT_MS_LANGID_SINDHI_INDIA /* Arabic */ 0x0459 +#define TT_MS_LANGID_SINDHI_PAKISTAN 0x0859 +#define TT_MS_LANGID_SINHALESE_SRI_LANKA \ + TT_MS_LANGID_SINHALA_SRI_LANKA +#define TT_MS_LANGID_CHEROKEE_UNITED_STATES 0x045C +#define TT_MS_LANGID_TAMAZIGHT_MOROCCO /* Arabic */ 0x045F +#define TT_MS_LANGID_TAMAZIGHT_MOROCCO_LATIN \ + TT_MS_LANGID_TAMAZIGHT_ALGERIA +#define TT_MS_LANGID_KASHMIRI_PAKISTAN /* Arabic */ 0x0460 +#define TT_MS_LANGID_KASHMIRI_SASIA 0x0860 +#define TT_MS_LANGID_KASHMIRI_INDIA \ + TT_MS_LANGID_KASHMIRI_SASIA +#define TT_MS_LANGID_NEPALI_INDIA 0x0861 +#define TT_MS_LANGID_DIVEHI_MALDIVES \ + TT_MS_LANGID_DHIVEHI_MALDIVES +#define TT_MS_LANGID_EDO_NIGERIA 0x0466 +#define TT_MS_LANGID_FULFULDE_NIGERIA 0x0467 +#define TT_MS_LANGID_IBIBIO_NIGERIA 0x0469 +#define TT_MS_LANGID_SEPEDI_SOUTH_AFRICA \ + TT_MS_LANGID_SESOTHO_SA_LEBOA_SOUTH_AFRICA +#define TT_MS_LANGID_SOTHO_SOUTHERN_SOUTH_AFRICA \ + TT_MS_LANGID_SESOTHO_SA_LEBOA_SOUTH_AFRICA #define TT_MS_LANGID_KANURI_NIGERIA 0x0471 #define TT_MS_LANGID_OROMO_ETHIOPIA 0x0472 #define TT_MS_LANGID_TIGRIGNA_ETHIOPIA 0x0473 #define TT_MS_LANGID_TIGRIGNA_ERYTHREA 0x0873 - /* also spelled in the `Passport SDK' list as: */ -#define TT_MS_LANGID_TIGRIGNA_ERYTREA TT_MS_LANGID_TIGRIGNA_ERYTHREA +#define TT_MS_LANGID_TIGRIGNA_ERYTREA \ + TT_MS_LANGID_TIGRIGNA_ERYTHREA #define TT_MS_LANGID_GUARANI_PARAGUAY 0x0474 #define TT_MS_LANGID_HAWAIIAN_UNITED_STATES 0x0475 #define TT_MS_LANGID_LATIN 0x0476 #define TT_MS_LANGID_SOMALI_SOMALIA 0x0477 - /* Note: Yi does not have a (proper) ISO 639-2 code, since it is mostly */ - /* not written (but OTOH the peculiar writing system is worth */ - /* studying). */ -#define TT_MS_LANGID_YI_CHINA 0x0478 +#define TT_MS_LANGID_YI_CHINA \ + TT_MS_LANGID_YI_PRC #define TT_MS_LANGID_PAPIAMENTU_NETHERLANDS_ANTILLES 0x0479 - /* language codes from 0x047A to 0x047F are (still) unknown. */ -#define TT_MS_LANGID_UIGHUR_CHINA 0x0480 -#define TT_MS_LANGID_MAORI_NEW_ZEALAND 0x0481 - -#if 0 /* not deemed useful for fonts */ -#define TT_MS_LANGID_HUMAN_INTERFACE_DEVICE 0x04FF -#endif +#define TT_MS_LANGID_UIGHUR_CHINA \ + TT_MS_LANGID_UIGHUR_PRC - /*************************************************************************/ - /* */ - /* Possible values of the `name' identifier field in the name records of */ - /* the TTF `name' table. These values are platform independent. */ - /* */ -#define TT_NAME_ID_COPYRIGHT 0 -#define TT_NAME_ID_FONT_FAMILY 1 -#define TT_NAME_ID_FONT_SUBFAMILY 2 -#define TT_NAME_ID_UNIQUE_ID 3 -#define TT_NAME_ID_FULL_NAME 4 -#define TT_NAME_ID_VERSION_STRING 5 -#define TT_NAME_ID_PS_NAME 6 -#define TT_NAME_ID_TRADEMARK 7 + /*********************************************************************** + * + * @enum: + * TT_NAME_ID_XXX + * + * @description: + * Possible values of the `name' identifier field in the name records of + * an SFNT `name' table. These values are platform independent. + */ + +#define TT_NAME_ID_COPYRIGHT 0 +#define TT_NAME_ID_FONT_FAMILY 1 +#define TT_NAME_ID_FONT_SUBFAMILY 2 +#define TT_NAME_ID_UNIQUE_ID 3 +#define TT_NAME_ID_FULL_NAME 4 +#define TT_NAME_ID_VERSION_STRING 5 +#define TT_NAME_ID_PS_NAME 6 +#define TT_NAME_ID_TRADEMARK 7 /* the following values are from the OpenType spec */ -#define TT_NAME_ID_MANUFACTURER 8 -#define TT_NAME_ID_DESIGNER 9 -#define TT_NAME_ID_DESCRIPTION 10 -#define TT_NAME_ID_VENDOR_URL 11 -#define TT_NAME_ID_DESIGNER_URL 12 -#define TT_NAME_ID_LICENSE 13 -#define TT_NAME_ID_LICENSE_URL 14 +#define TT_NAME_ID_MANUFACTURER 8 +#define TT_NAME_ID_DESIGNER 9 +#define TT_NAME_ID_DESCRIPTION 10 +#define TT_NAME_ID_VENDOR_URL 11 +#define TT_NAME_ID_DESIGNER_URL 12 +#define TT_NAME_ID_LICENSE 13 +#define TT_NAME_ID_LICENSE_URL 14 /* number 15 is reserved */ -#define TT_NAME_ID_PREFERRED_FAMILY 16 -#define TT_NAME_ID_PREFERRED_SUBFAMILY 17 -#define TT_NAME_ID_MAC_FULL_NAME 18 +#define TT_NAME_ID_TYPOGRAPHIC_FAMILY 16 +#define TT_NAME_ID_TYPOGRAPHIC_SUBFAMILY 17 +#define TT_NAME_ID_MAC_FULL_NAME 18 /* The following code is new as of 2000-01-21 */ -#define TT_NAME_ID_SAMPLE_TEXT 19 +#define TT_NAME_ID_SAMPLE_TEXT 19 /* This is new in OpenType 1.3 */ -#define TT_NAME_ID_CID_FINDFONT_NAME 20 +#define TT_NAME_ID_CID_FINDFONT_NAME 20 /* This is new in OpenType 1.5 */ -#define TT_NAME_ID_WWS_FAMILY 21 -#define TT_NAME_ID_WWS_SUBFAMILY 22 +#define TT_NAME_ID_WWS_FAMILY 21 +#define TT_NAME_ID_WWS_SUBFAMILY 22 + + /* This is new in OpenType 1.7 */ +#define TT_NAME_ID_LIGHT_BACKGROUND 23 +#define TT_NAME_ID_DARK_BACKGROUND 24 + + /* This is new in OpenType 1.8 */ +#define TT_NAME_ID_VARIATIONS_PREFIX 25 + + /* these two values are deprecated */ +#define TT_NAME_ID_PREFERRED_FAMILY TT_NAME_ID_TYPOGRAPHIC_FAMILY +#define TT_NAME_ID_PREFERRED_SUBFAMILY TT_NAME_ID_TYPOGRAPHIC_SUBFAMILY - /*************************************************************************/ - /* */ - /* Bit mask values for the Unicode Ranges from the TTF `OS2 ' table. */ - /* */ - /* Updated 08-Nov-2008. */ - /* */ + /*********************************************************************** + * + * @enum: + * TT_UCR_XXX + * + * @description: + * Possible bit mask values for the `ulUnicodeRangeX' fields in an SFNT + * `OS/2' table. + */ + + /* ulUnicodeRange1 */ + /* --------------- */ /* Bit 0 Basic Latin */ #define TT_UCR_BASIC_LATIN (1L << 0) /* U+0020-U+007E */ @@ -857,7 +867,7 @@ FT_BEGIN_HEADER /* U+A700-U+A71F */ /* Bit 6 Combining Diacritical Marks */ /* Combining Diacritical Marks Supplement */ -#define TT_UCR_COMBINING_DIACRITICS (1L << 6) /* U+0300-U+036F */ +#define TT_UCR_COMBINING_DIACRITICAL_MARKS (1L << 6) /* U+0300-U+036F */ /* U+1DC0-U+1DFF */ /* Bit 7 Greek and Coptic */ #define TT_UCR_GREEK (1L << 7) /* U+0370-U+03FF */ @@ -925,12 +935,17 @@ FT_BEGIN_HEADER /* Supplemental Punctuation */ #define TT_UCR_GENERAL_PUNCTUATION (1L << 31) /* U+2000-U+206F */ /* U+2E00-U+2E7F */ + + /* ulUnicodeRange2 */ + /* --------------- */ + /* Bit 32 Superscripts And Subscripts */ #define TT_UCR_SUPERSCRIPTS_SUBSCRIPTS (1L << 0) /* U+2070-U+209F */ /* Bit 33 Currency Symbols */ #define TT_UCR_CURRENCY_SYMBOLS (1L << 1) /* U+20A0-U+20CF */ /* Bit 34 Combining Diacritical Marks For Symbols */ -#define TT_UCR_COMBINING_DIACRITICS_SYMB (1L << 2) /* U+20D0-U+20FF */ +#define TT_UCR_COMBINING_DIACRITICAL_MARKS_SYMB \ + (1L << 2) /* U+20D0-U+20FF */ /* Bit 35 Letterlike Symbols */ #define TT_UCR_LETTERLIKE_SYMBOLS (1L << 3) /* U+2100-U+214F */ /* Bit 36 Number Forms */ @@ -996,13 +1011,13 @@ FT_BEGIN_HEADER /* Bit 57 High Surrogates */ /* High Private Use Surrogates */ /* Low Surrogates */ - /* */ + /* According to OpenType specs v.1.3+, */ /* setting bit 57 implies that there is */ /* at least one codepoint beyond the */ /* Basic Multilingual Plane that is */ /* supported by this font. So it really */ - /* means >= U+10000 */ + /* means >= U+10000. */ #define TT_UCR_SURROGATES (1L << 25) /* U+D800-U+DB7F */ /* U+DB80-U+DBFF */ /* U+DC00-U+DFFF */ @@ -1034,7 +1049,11 @@ FT_BEGIN_HEADER /* Bit 62 Alphabetic Presentation Forms */ #define TT_UCR_ALPHABETIC_PRESENTATION_FORMS (1L << 30) /* U+FB00-U+FB4F */ /* Bit 63 Arabic Presentation Forms-A */ -#define TT_UCR_ARABIC_PRESENTATIONS_A (1L << 31) /* U+FB50-U+FDFF */ +#define TT_UCR_ARABIC_PRESENTATION_FORMS_A (1L << 31) /* U+FB50-U+FDFF */ + + /* ulUnicodeRange3 */ + /* --------------- */ + /* Bit 64 Combining Half Marks */ #define TT_UCR_COMBINING_HALF_MARKS (1L << 0) /* U+FE20-U+FE2F */ /* Bit 65 Vertical forms */ @@ -1044,7 +1063,7 @@ FT_BEGIN_HEADER /* Bit 66 Small Form Variants */ #define TT_UCR_SMALL_FORM_VARIANTS (1L << 2) /* U+FE50-U+FE6F */ /* Bit 67 Arabic Presentation Forms-B */ -#define TT_UCR_ARABIC_PRESENTATIONS_B (1L << 3) /* U+FE70-U+FEFE */ +#define TT_UCR_ARABIC_PRESENTATION_FORMS_B (1L << 3) /* U+FE70-U+FEFE */ /* Bit 68 Halfwidth and Fullwidth Forms */ #define TT_UCR_HALFWIDTH_FULLWIDTH_FORMS (1L << 4) /* U+FF00-U+FFEF */ /* Bit 69 Specials */ @@ -1123,6 +1142,10 @@ FT_BEGIN_HEADER #define TT_UCR_TAI_LE (1L << 30) /* U+1950-U+197F */ /* Bit 95 New Tai Lue */ #define TT_UCR_NEW_TAI_LUE (1L << 31) /* U+1980-U+19DF */ + + /* ulUnicodeRange4 */ + /* --------------- */ + /* Bit 96 Buginese */ #define TT_UCR_BUGINESE (1L << 0) /* U+1A00-U+1A1F */ /* Bit 97 Glagolitic */ @@ -1191,47 +1214,23 @@ FT_BEGIN_HEADER /*U+1F000-U+1F02F*/ /* Bit 123-127 Reserved for process-internal usage */ + /* */ - /*************************************************************************/ - /* */ - /* Some compilers have a very limited length of identifiers. */ - /* */ -#if defined( __TURBOC__ ) && __TURBOC__ < 0x0410 || defined( __PACIFIC__ ) -#define HAVE_LIMIT_ON_IDENTS -#endif + /* for backward compatibility with older FreeType versions */ +#define TT_UCR_ARABIC_PRESENTATION_A \ + TT_UCR_ARABIC_PRESENTATION_FORMS_A +#define TT_UCR_ARABIC_PRESENTATION_B \ + TT_UCR_ARABIC_PRESENTATION_FORMS_B - -#ifndef HAVE_LIMIT_ON_IDENTS - - - /*************************************************************************/ - /* */ - /* Here some alias #defines in order to be clearer. */ - /* */ - /* These are not always #defined to stay within the 31~character limit, */ - /* which some compilers have. */ - /* */ - /* Credits go to Dave Hoo <dhoo@flash.net> for pointing out that modern */ - /* Borland compilers (read: from BC++ 3.1 on) can increase this limit. */ - /* If you get a warning with such a compiler, use the -i40 switch. */ - /* */ -#define TT_UCR_ARABIC_PRESENTATION_FORMS_A \ - TT_UCR_ARABIC_PRESENTATIONS_A -#define TT_UCR_ARABIC_PRESENTATION_FORMS_B \ - TT_UCR_ARABIC_PRESENTATIONS_B - -#define TT_UCR_COMBINING_DIACRITICAL_MARKS \ - TT_UCR_COMBINING_DIACRITICS -#define TT_UCR_COMBINING_DIACRITICAL_MARKS_SYMB \ - TT_UCR_COMBINING_DIACRITICS_SYMB - - -#endif /* !HAVE_LIMIT_ON_IDENTS */ +#define TT_UCR_COMBINING_DIACRITICS \ + TT_UCR_COMBINING_DIACRITICAL_MARKS +#define TT_UCR_COMBINING_DIACRITICS_SYMB \ + TT_UCR_COMBINING_DIACRITICAL_MARKS_SYMB FT_END_HEADER -#endif /* __TTNAMEID_H__ */ +#endif /* TTNAMEID_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/tttables.h b/src/3rdparty/freetype/include/freetype/tttables.h index 1568f40364..ce6a61779c 100644 --- a/src/3rdparty/freetype/include/freetype/tttables.h +++ b/src/3rdparty/freetype/include/freetype/tttables.h @@ -5,7 +5,7 @@ /* Basic SFNT/TrueType tables definitions and interface */ /* (specification only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __TTTABLES_H__ -#define __TTTABLES_H__ +#ifndef TTTABLES_H_ +#define TTTABLES_H_ #include <ft2build.h> @@ -45,8 +45,9 @@ FT_BEGIN_HEADER /* TrueType specific table types and functions. */ /* */ /* <Description> */ - /* This section contains the definition of TrueType-specific tables */ - /* as well as some routines used to access and process them. */ + /* This section contains definitions of some basic tables specific to */ + /* TrueType and OpenType as well as some routines used to access and */ + /* process them. */ /* */ /* <Order> */ /* TT_Header */ @@ -76,8 +77,8 @@ FT_BEGIN_HEADER /* TT_Header */ /* */ /* <Description> */ - /* A structure used to model a TrueType font header table. All */ - /* fields follow the TrueType specification. */ + /* A structure to model a TrueType font header table. All fields */ + /* follow the OpenType specification. */ /* */ typedef struct TT_Header_ { @@ -114,9 +115,9 @@ FT_BEGIN_HEADER /* TT_HoriHeader */ /* */ /* <Description> */ - /* A structure used to model a TrueType horizontal header, the `hhea' */ + /* A structure to model a TrueType horizontal header, the `hhea' */ /* table, as well as the corresponding horizontal metrics table, */ - /* i.e., the `hmtx' table. */ + /* `hmtx'. */ /* */ /* <Fields> */ /* Version :: The table version. */ @@ -131,7 +132,7 @@ FT_BEGIN_HEADER /* glyphs found in the font (maybe ASCII). */ /* */ /* You should use the `sTypoAscender' field */ - /* of the OS/2 table instead if you want */ + /* of the `OS/2' table instead if you want */ /* the correct one. */ /* */ /* Descender :: The font's descender, i.e., the distance */ @@ -145,7 +146,7 @@ FT_BEGIN_HEADER /* glyphs found in the font (maybe ASCII). */ /* */ /* You should use the `sTypoDescender' */ - /* field of the OS/2 table instead if you */ + /* field of the `OS/2' table instead if you */ /* want the correct one. */ /* */ /* Line_Gap :: The font's line gap, i.e., the distance */ @@ -175,6 +176,8 @@ FT_BEGIN_HEADER /* caret_Slope_Run :: The run coefficient of the cursor's */ /* slope. */ /* */ + /* caret_Offset :: The cursor's offset for slanted fonts. */ + /* */ /* Reserved :: 8~reserved bytes. */ /* */ /* metric_Data_Format :: Always~0. */ @@ -188,13 +191,10 @@ FT_BEGIN_HEADER /* short_metrics :: A pointer into the `hmtx' table. */ /* */ /* <Note> */ - /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */ - /* be identical except for the names of their fields, */ - /* which are different. */ - /* */ - /* This ensures that a single function in the `ttload' */ - /* module is able to read both the horizontal and vertical */ - /* headers. */ + /* For an OpenType variation font, the values of the following fields */ + /* can change after a call to @FT_Set_Var_Design_Coordinates (and */ + /* friends) if the font contains an `MVAR' table: `caret_Slope_Rise', */ + /* `caret_Slope_Run', and `caret_Offset'. */ /* */ typedef struct TT_HoriHeader_ { @@ -217,9 +217,9 @@ FT_BEGIN_HEADER FT_Short metric_Data_Format; FT_UShort number_Of_HMetrics; - /* The following fields are not defined by the TrueType specification */ + /* The following fields are not defined by the OpenType specification */ /* but they are used to connect the metrics header to the relevant */ - /* `HMTX' table. */ + /* `hmtx' table. */ void* long_metrics; void* short_metrics; @@ -234,8 +234,8 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* A structure used to model a TrueType vertical header, the `vhea' */ - /* table, as well as the corresponding vertical metrics table, i.e., */ - /* the `vmtx' table. */ + /* table, as well as the corresponding vertical metrics table, */ + /* `vmtx'. */ /* */ /* <Fields> */ /* Version :: The table version. */ @@ -251,8 +251,8 @@ FT_BEGIN_HEADER /* ASCII). */ /* */ /* You should use the `sTypoAscender' */ - /* field of the OS/2 table instead if you */ - /* want the correct one. */ + /* field of the `OS/2' table instead if */ + /* you want the correct one. */ /* */ /* Descender :: The font's descender, i.e., the */ /* distance from the baseline to the */ @@ -266,8 +266,8 @@ FT_BEGIN_HEADER /* ASCII). */ /* */ /* You should use the `sTypoDescender' */ - /* field of the OS/2 table instead if you */ - /* want the correct one. */ + /* field of the `OS/2' table instead if */ + /* you want the correct one. */ /* */ /* Line_Gap :: The font's line gap, i.e., the distance */ /* to add to the ascender and descender to */ @@ -297,30 +297,26 @@ FT_BEGIN_HEADER /* slope. */ /* */ /* caret_Offset :: The cursor's offset for slanted fonts. */ - /* This value is `reserved' in vmtx */ - /* version 1.0. */ /* */ /* Reserved :: 8~reserved bytes. */ /* */ /* metric_Data_Format :: Always~0. */ /* */ - /* number_Of_HMetrics :: Number of VMetrics entries in the */ + /* number_Of_VMetrics :: Number of VMetrics entries in the */ /* `vmtx' table -- this value can be */ /* smaller than the total number of glyphs */ /* in the font. */ /* */ - /* long_metrics :: A pointer into the `vmtx' table. */ + /* long_metrics :: A pointer into the `vmtx' table. */ /* */ - /* short_metrics :: A pointer into the `vmtx' table. */ + /* short_metrics :: A pointer into the `vmtx' table. */ /* */ /* <Note> */ - /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */ - /* be identical except for the names of their fields, */ - /* which are different. */ - /* */ - /* This ensures that a single function in the `ttload' */ - /* module is able to read both the horizontal and vertical */ - /* headers. */ + /* For an OpenType variation font, the values of the following fields */ + /* can change after a call to @FT_Set_Var_Design_Coordinates (and */ + /* friends) if the font contains an `MVAR' table: `Ascender', */ + /* `Descender', `Line_Gap', `caret_Slope_Rise', `caret_Slope_Run', */ + /* and `caret_Offset'. */ /* */ typedef struct TT_VertHeader_ { @@ -331,9 +327,9 @@ FT_BEGIN_HEADER FT_UShort advance_Height_Max; /* advance height maximum */ - FT_Short min_Top_Side_Bearing; /* minimum left-sb or top-sb */ - FT_Short min_Bottom_Side_Bearing; /* minimum right-sb or bottom-sb */ - FT_Short yMax_Extent; /* xmax or ymax extents */ + FT_Short min_Top_Side_Bearing; /* minimum top-sb */ + FT_Short min_Bottom_Side_Bearing; /* minimum bottom-sb */ + FT_Short yMax_Extent; /* ymax extents */ FT_Short caret_Slope_Rise; FT_Short caret_Slope_Run; FT_Short caret_Offset; @@ -343,9 +339,9 @@ FT_BEGIN_HEADER FT_Short metric_Data_Format; FT_UShort number_Of_VMetrics; - /* The following fields are not defined by the TrueType specification */ - /* but they're used to connect the metrics header to the relevant */ - /* `HMTX' or `VMTX' table. */ + /* The following fields are not defined by the OpenType specification */ + /* but they are used to connect the metrics header to the relevant */ + /* `vmtx' table. */ void* long_metrics; void* short_metrics; @@ -359,12 +355,28 @@ FT_BEGIN_HEADER /* TT_OS2 */ /* */ /* <Description> */ - /* A structure used to model a TrueType OS/2 table. All fields */ - /* comply to the OpenType specification. */ + /* A structure to model a TrueType `OS/2' table. All fields comply */ + /* to the OpenType specification. */ /* */ - /* Note that we now support old Mac fonts that do not include an OS/2 */ - /* table. In this case, the `version' field is always set to 0xFFFF. */ + /* Note that we now support old Mac fonts that do not include an */ + /* `OS/2' table. In this case, the `version' field is always set to */ + /* 0xFFFF. */ /* */ + /* <Note> */ + /* For an OpenType variation font, the values of the following fields */ + /* can change after a call to @FT_Set_Var_Design_Coordinates (and */ + /* friends) if the font contains an `MVAR' table: `sCapHeight', */ + /* `sTypoAscender', `sTypoDescender', `sTypoLineGap', `sxHeight', */ + /* `usWinAscent', `usWinDescent', `yStrikeoutPosition', */ + /* `yStrikeoutSize', `ySubscriptXOffset', `ySubScriptXSize', */ + /* `ySubscriptYOffset', `ySubscriptYSize', `ySuperscriptXOffset', */ + /* `ySuperscriptXSize', `ySuperscriptYOffset', and */ + /* `ySuperscriptYSize'. */ + /* */ + /* Possible values for bits in the `ulUnicodeRangeX' fields are given */ + /* by the @TT_UCR_XXX macros. */ + /* */ + typedef struct TT_OS2_ { FT_UShort version; /* 0x0001 - more or 0xFFFF */ @@ -429,10 +441,16 @@ FT_BEGIN_HEADER /* TT_Postscript */ /* */ /* <Description> */ - /* A structure used to model a TrueType PostScript table. All fields */ - /* comply to the TrueType specification. This structure does not */ - /* reference the PostScript glyph names, which can be nevertheless */ - /* accessed with the `ttpost' module. */ + /* A structure to model a TrueType `post' table. All fields comply */ + /* to the OpenType specification. This structure does not reference */ + /* a font's PostScript glyph names; use @FT_Get_Glyph_Name to */ + /* retrieve them. */ + /* */ + /* <Note> */ + /* For an OpenType variation font, the values of the following fields */ + /* can change after a call to @FT_Set_Var_Design_Coordinates (and */ + /* friends) if the font contains an `MVAR' table: `underlinePosition' */ + /* and `underlineThickness'. */ /* */ typedef struct TT_Postscript_ { @@ -446,8 +464,8 @@ FT_BEGIN_HEADER FT_ULong minMemType1; FT_ULong maxMemType1; - /* Glyph names follow in the file, but we don't */ - /* load them by default. See the ttpost.c file. */ + /* Glyph names follow in the `post' table, but we don't */ + /* load them by default. */ } TT_Postscript; @@ -458,8 +476,8 @@ FT_BEGIN_HEADER /* TT_PCLT */ /* */ /* <Description> */ - /* A structure used to model a TrueType PCLT table. All fields */ - /* comply to the TrueType specification. */ + /* A structure to model a TrueType `PCLT' table. All fields comply */ + /* to the OpenType specification. */ /* */ typedef struct TT_PCLT_ { @@ -488,9 +506,9 @@ FT_BEGIN_HEADER /* TT_MaxProfile */ /* */ /* <Description> */ - /* The maximum profile is a table containing many max values, which */ - /* can be used to pre-allocate arrays. This ensures that no memory */ - /* allocation occurs during a glyph load. */ + /* The maximum profile (`maxp') table contains many max values, which */ + /* can be used to pre-allocate arrays for speeding up glyph loading */ + /* and hinting. */ /* */ /* <Fields> */ /* version :: The version number. */ @@ -500,21 +518,19 @@ FT_BEGIN_HEADER /* */ /* maxPoints :: The maximum number of points in a */ /* non-composite TrueType glyph. See also */ - /* the structure element */ /* `maxCompositePoints'. */ /* */ /* maxContours :: The maximum number of contours in a */ /* non-composite TrueType glyph. See also */ - /* the structure element */ /* `maxCompositeContours'. */ /* */ /* maxCompositePoints :: The maximum number of points in a */ - /* composite TrueType glyph. See also the */ - /* structure element `maxPoints'. */ + /* composite TrueType glyph. See also */ + /* `maxPoints'. */ /* */ /* maxCompositeContours :: The maximum number of contours in a */ - /* composite TrueType glyph. See also the */ - /* structure element `maxContours'. */ + /* composite TrueType glyph. See also */ + /* `maxContours'. */ /* */ /* maxZones :: The maximum number of zones used for */ /* glyph hinting. */ @@ -575,8 +591,9 @@ FT_BEGIN_HEADER /* FT_Sfnt_Tag */ /* */ /* <Description> */ - /* An enumeration used to specify the index of an SFNT table. */ - /* Used in the @FT_Get_Sfnt_Table API function. */ + /* An enumeration to specify indices of SFNT tables loaded and parsed */ + /* by FreeType during initialization of an SFNT font. Used in the */ + /* @FT_Get_Sfnt_Table API function. */ /* */ /* <Values> */ /* FT_SFNT_HEAD :: To access the font's @TT_Header structure. */ @@ -587,7 +604,7 @@ FT_BEGIN_HEADER /* */ /* FT_SFNT_HHEA :: To access the font's @TT_HoriHeader structure. */ /* */ - /* FT_SFNT_VHEA :: To access the font's @TT_VertHeader struture. */ + /* FT_SFNT_VHEA :: To access the font's @TT_VertHeader structure. */ /* */ /* FT_SFNT_POST :: To access the font's @TT_Postscript structure. */ /* */ @@ -624,7 +641,7 @@ FT_BEGIN_HEADER /* FT_Get_Sfnt_Table */ /* */ /* <Description> */ - /* Return a pointer to a given SFNT table within a face. */ + /* Return a pointer to a given SFNT table stored within a face. */ /* */ /* <Input> */ /* face :: A handle to the source. */ @@ -632,7 +649,7 @@ FT_BEGIN_HEADER /* tag :: The index of the SFNT table. */ /* */ /* <Return> */ - /* A type-less pointer to the table. This will be~0 in case of */ + /* A type-less pointer to the table. This will be NULL in case of */ /* error, or if the corresponding table was not found *OR* loaded */ /* from the file. */ /* */ @@ -661,70 +678,70 @@ FT_BEGIN_HEADER FT_Sfnt_Tag tag ); - /************************************************************************** - * - * @function: - * FT_Load_Sfnt_Table - * - * @description: - * Load any font table into client memory. - * - * @input: - * face :: - * A handle to the source face. - * - * tag :: - * The four-byte tag of the table to load. Use the value~0 if you want - * to access the whole font file. Otherwise, you can use one of the - * definitions found in the @FT_TRUETYPE_TAGS_H file, or forge a new - * one with @FT_MAKE_TAG. - * - * offset :: - * The starting offset in the table (or file if tag == 0). - * - * @output: - * buffer :: - * The target buffer address. The client must ensure that the memory - * array is big enough to hold the data. - * - * @inout: - * length :: - * If the `length' parameter is NULL, then try to load the whole table. - * Return an error code if it fails. - * - * Else, if `*length' is~0, exit immediately while returning the - * table's (or file) full size in it. - * - * Else the number of bytes to read from the table or file, from the - * starting offset. - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * If you need to determine the table's length you should first call this - * function with `*length' set to~0, as in the following example: - * - * { - * FT_ULong length = 0; - * - * - * error = FT_Load_Sfnt_Table( face, tag, 0, NULL, &length ); - * if ( error ) { ... table does not exist ... } - * - * buffer = malloc( length ); - * if ( buffer == NULL ) { ... not enough memory ... } - * - * error = FT_Load_Sfnt_Table( face, tag, 0, buffer, &length ); - * if ( error ) { ... could not load table ... } - * } - * - * Note that structures like @TT_Header or @TT_OS2 can't be used with - * this function; they are limited to @FT_Get_Sfnt_Table. Reason is that - * those structures depend on the processor architecture, with varying - * size (e.g. 32bit vs. 64bit) or order (big endian vs. little endian). - * - */ + /************************************************************************** + * + * @function: + * FT_Load_Sfnt_Table + * + * @description: + * Load any SFNT font table into client memory. + * + * @input: + * face :: + * A handle to the source face. + * + * tag :: + * The four-byte tag of the table to load. Use value~0 if you want + * to access the whole font file. Otherwise, you can use one of the + * definitions found in the @FT_TRUETYPE_TAGS_H file, or forge a new + * one with @FT_MAKE_TAG. + * + * offset :: + * The starting offset in the table (or file if tag~==~0). + * + * @output: + * buffer :: + * The target buffer address. The client must ensure that the memory + * array is big enough to hold the data. + * + * @inout: + * length :: + * If the `length' parameter is NULL, try to load the whole table. + * Return an error code if it fails. + * + * Else, if `*length' is~0, exit immediately while returning the + * table's (or file) full size in it. + * + * Else the number of bytes to read from the table or file, from the + * starting offset. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * If you need to determine the table's length you should first call this + * function with `*length' set to~0, as in the following example: + * + * { + * FT_ULong length = 0; + * + * + * error = FT_Load_Sfnt_Table( face, tag, 0, NULL, &length ); + * if ( error ) { ... table does not exist ... } + * + * buffer = malloc( length ); + * if ( buffer == NULL ) { ... not enough memory ... } + * + * error = FT_Load_Sfnt_Table( face, tag, 0, buffer, &length ); + * if ( error ) { ... could not load table ... } + * } + * + * Note that structures like @TT_Header or @TT_OS2 can't be used with + * this function; they are limited to @FT_Get_Sfnt_Table. Reason is that + * those structures depend on the processor architecture, with varying + * size (e.g. 32bit vs. 64bit) or order (big endian vs. little endian). + * + */ FT_EXPORT( FT_Error ) FT_Load_Sfnt_Table( FT_Face face, FT_ULong tag, @@ -733,41 +750,41 @@ FT_BEGIN_HEADER FT_ULong* length ); - /************************************************************************** - * - * @function: - * FT_Sfnt_Table_Info - * - * @description: - * Return information on an SFNT table. - * - * @input: - * face :: - * A handle to the source face. - * - * table_index :: - * The index of an SFNT table. The function returns - * FT_Err_Table_Missing for an invalid value. - * - * @inout: - * tag :: - * The name tag of the SFNT table. If the value is NULL, `table_index' - * is ignored, and `length' returns the number of SFNT tables in the - * font. - * - * @output: - * length :: - * The length of the SFNT table (or the number of SFNT tables, depending - * on `tag'). - * - * @return: - * FreeType error code. 0~means success. - * - * @note: - * While parsing fonts, FreeType handles SFNT tables with length zero as - * missing. - * - */ + /************************************************************************** + * + * @function: + * FT_Sfnt_Table_Info + * + * @description: + * Return information on an SFNT table. + * + * @input: + * face :: + * A handle to the source face. + * + * table_index :: + * The index of an SFNT table. The function returns + * FT_Err_Table_Missing for an invalid value. + * + * @inout: + * tag :: + * The name tag of the SFNT table. If the value is NULL, `table_index' + * is ignored, and `length' returns the number of SFNT tables in the + * font. + * + * @output: + * length :: + * The length of the SFNT table (or the number of SFNT tables, depending + * on `tag'). + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * While parsing fonts, FreeType handles SFNT tables with length zero as + * missing. + * + */ FT_EXPORT( FT_Error ) FT_Sfnt_Table_Info( FT_Face face, FT_UInt table_index, @@ -781,16 +798,16 @@ FT_BEGIN_HEADER /* FT_Get_CMap_Language_ID */ /* */ /* <Description> */ - /* Return TrueType/sfnt specific cmap language ID. Definitions of */ - /* language ID values are in `ttnameid.h'. */ + /* Return cmap language ID as specified in the OpenType standard. */ + /* Definitions of language ID values are in file @FT_TRUETYPE_IDS_H. */ /* */ /* <Input> */ /* charmap :: */ /* The target charmap. */ /* */ /* <Return> */ - /* The language ID of `charmap'. If `charmap' doesn't belong to a */ - /* TrueType/sfnt face, just return~0 as the default value. */ + /* The language ID of `charmap'. If `charmap' doesn't belong to an */ + /* SFNT face, just return~0 as the default value. */ /* */ /* For a format~14 cmap (to access Unicode IVS), the return value is */ /* 0xFFFFFFFF. */ @@ -805,15 +822,15 @@ FT_BEGIN_HEADER /* FT_Get_CMap_Format */ /* */ /* <Description> */ - /* Return TrueType/sfnt specific cmap format. */ + /* Return the format of an SFNT `cmap' table. */ /* */ /* <Input> */ /* charmap :: */ /* The target charmap. */ /* */ /* <Return> */ - /* The format of `charmap'. If `charmap' doesn't belong to a */ - /* TrueType/sfnt face, return -1. */ + /* The format of `charmap'. If `charmap' doesn't belong to an SFNT */ + /* face, return -1. */ /* */ FT_EXPORT( FT_Long ) FT_Get_CMap_Format( FT_CharMap charmap ); @@ -823,7 +840,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTTABLES_H__ */ +#endif /* TTTABLES_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/freetype/tttags.h b/src/3rdparty/freetype/include/freetype/tttags.h index 3836c7bbfd..e5cee68a15 100644 --- a/src/3rdparty/freetype/include/freetype/tttags.h +++ b/src/3rdparty/freetype/include/freetype/tttags.h @@ -4,7 +4,7 @@ /* */ /* Tags for TrueType and OpenType tables (specification only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTAGS_H__ -#define __TTAGS_H__ +#ifndef TTAGS_H_ +#define TTAGS_H_ #include <ft2build.h> @@ -43,6 +43,7 @@ FT_BEGIN_HEADER #define TTAG_CBDT FT_MAKE_TAG( 'C', 'B', 'D', 'T' ) #define TTAG_CBLC FT_MAKE_TAG( 'C', 'B', 'L', 'C' ) #define TTAG_CFF FT_MAKE_TAG( 'C', 'F', 'F', ' ' ) +#define TTAG_CFF2 FT_MAKE_TAG( 'C', 'F', 'F', '2' ) #define TTAG_CID FT_MAKE_TAG( 'C', 'I', 'D', ' ' ) #define TTAG_cmap FT_MAKE_TAG( 'c', 'm', 'a', 'p' ) #define TTAG_cvar FT_MAKE_TAG( 'c', 'v', 'a', 'r' ) @@ -61,6 +62,7 @@ FT_BEGIN_HEADER #define TTAG_GPOS FT_MAKE_TAG( 'G', 'P', 'O', 'S' ) #define TTAG_GSUB FT_MAKE_TAG( 'G', 'S', 'U', 'B' ) #define TTAG_gvar FT_MAKE_TAG( 'g', 'v', 'a', 'r' ) +#define TTAG_HVAR FT_MAKE_TAG( 'H', 'V', 'A', 'R' ) #define TTAG_hdmx FT_MAKE_TAG( 'h', 'd', 'm', 'x' ) #define TTAG_head FT_MAKE_TAG( 'h', 'e', 'a', 'd' ) #define TTAG_hhea FT_MAKE_TAG( 'h', 'h', 'e', 'a' ) @@ -79,6 +81,7 @@ FT_BEGIN_HEADER #define TTAG_MMSD FT_MAKE_TAG( 'M', 'M', 'S', 'D' ) #define TTAG_mort FT_MAKE_TAG( 'm', 'o', 'r', 't' ) #define TTAG_morx FT_MAKE_TAG( 'm', 'o', 'r', 'x' ) +#define TTAG_MVAR FT_MAKE_TAG( 'M', 'V', 'A', 'R' ) #define TTAG_name FT_MAKE_TAG( 'n', 'a', 'm', 'e' ) #define TTAG_opbd FT_MAKE_TAG( 'o', 'p', 'b', 'd' ) #define TTAG_OS2 FT_MAKE_TAG( 'O', 'S', '/', '2' ) @@ -100,12 +103,19 @@ FT_BEGIN_HEADER #define TTAG_VDMX FT_MAKE_TAG( 'V', 'D', 'M', 'X' ) #define TTAG_vhea FT_MAKE_TAG( 'v', 'h', 'e', 'a' ) #define TTAG_vmtx FT_MAKE_TAG( 'v', 'm', 't', 'x' ) +#define TTAG_VVAR FT_MAKE_TAG( 'V', 'V', 'A', 'R' ) #define TTAG_wOFF FT_MAKE_TAG( 'w', 'O', 'F', 'F' ) +/* used by "Keyboard.dfont" on legacy Mac OS X */ +#define TTAG_0xA5kbd FT_MAKE_TAG( 0xA5, 'k', 'b', 'd' ) + +/* used by "LastResort.dfont" on legacy Mac OS X */ +#define TTAG_0xA5lst FT_MAKE_TAG( 0xA5, 'l', 's', 't' ) + FT_END_HEADER -#endif /* __TTAGS_H__ */ +#endif /* TTAGS_H_ */ /* END */ diff --git a/src/3rdparty/freetype/include/ft2build.h b/src/3rdparty/freetype/include/ft2build.h index 419b80ae44..e7ce99bc94 100644 --- a/src/3rdparty/freetype/include/ft2build.h +++ b/src/3rdparty/freetype/include/ft2build.h @@ -4,7 +4,7 @@ /* */ /* FreeType 2 build and setup macros. */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -31,12 +31,12 @@ /*************************************************************************/ -#ifndef __FT2BUILD_H__ -#define __FT2BUILD_H__ +#ifndef FT2BUILD_H_ +#define FT2BUILD_H_ #include <freetype/config/ftheader.h> -#endif /* __FT2BUILD_H__ */ +#endif /* FT2BUILD_H_ */ /* END */ diff --git a/src/3rdparty/freetype/qt_attribution.json b/src/3rdparty/freetype/qt_attribution.json index f46541cf2e..b046ebc860 100644 --- a/src/3rdparty/freetype/qt_attribution.json +++ b/src/3rdparty/freetype/qt_attribution.json @@ -7,7 +7,7 @@ "Description": "FreeType is a freely available software library to render fonts.", "Homepage": "http://www.freetype.org", - "Version": "2.6.1", + "Version": "2.9.1", "License": "Freetype Project License or GNU General Public License v2.0 only", "LicenseId": "FTL OR GPL-2.0", diff --git a/src/3rdparty/freetype/src/Jamfile b/src/3rdparty/freetype/src/Jamfile index 65e061910d..562480c94a 100644 --- a/src/3rdparty/freetype/src/Jamfile +++ b/src/3rdparty/freetype/src/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src Jamfile # -# Copyright 2001-2015 by +# Copyright 2001-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/autofit/Jamfile b/src/3rdparty/freetype/src/autofit/Jamfile index 5cd0b46108..01b866ec61 100644 --- a/src/3rdparty/freetype/src/autofit/Jamfile +++ b/src/3rdparty/freetype/src/autofit/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/autofit Jamfile # -# Copyright 2003-2015 by +# Copyright 2003-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -33,8 +33,8 @@ SubDir FT2_TOP src autofit ; afmodule afpic afranges + afshaper afwarp - hbshim ; if $(FT2_AUTOFIT2) diff --git a/src/3rdparty/freetype/src/autofit/afangles.c b/src/3rdparty/freetype/src/autofit/afangles.c index 1b1eb31fe7..c65a3ae23e 100644 --- a/src/3rdparty/freetype/src/autofit/afangles.c +++ b/src/3rdparty/freetype/src/autofit/afangles.c @@ -5,7 +5,7 @@ /* Routines used to compute vector angles with limited accuracy */ /* and very high speed. It also contains sorting routines (body). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/src/autofit/afblue.c b/src/3rdparty/freetype/src/autofit/afblue.c index b871e0c651..e4078fd044 100644 --- a/src/3rdparty/freetype/src/autofit/afblue.c +++ b/src/3rdparty/freetype/src/autofit/afblue.c @@ -7,7 +7,7 @@ /* */ /* Auto-fitter data for blue strings (body). */ /* */ -/* Copyright 2013-2015 by */ +/* Copyright 2013-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,139 +26,411 @@ af_blue_strings[] = { /* */ - '\xD8', '\xA7', '\xD8', '\xA5', '\xD9', '\x84', '\xD9', '\x83', '\xD8', '\xB7', '\xD8', '\xB8', /* ا إ ل ك ط ظ */ + '\xF0', '\x9E', '\xA4', '\x8C', ' ', '\xF0', '\x9E', '\xA4', '\x85', ' ', '\xF0', '\x9E', '\xA4', '\x88', ' ', '\xF0', '\x9E', '\xA4', '\x8F', ' ', '\xF0', '\x9E', '\xA4', '\x94', ' ', '\xF0', '\x9E', '\xA4', '\x9A', /* 𞤌 𞤅 𞤈 𞤏 𞤔 𞤚 */ '\0', - '\xD8', '\xAA', '\xD8', '\xAB', '\xD8', '\xB7', '\xD8', '\xB8', '\xD9', '\x83', /* ت ث ط ظ ك */ + '\xF0', '\x9E', '\xA4', '\x82', ' ', '\xF0', '\x9E', '\xA4', '\x96', /* 𞤂 𞤖 */ + '\0', + '\xF0', '\x9E', '\xA4', '\xAC', ' ', '\xF0', '\x9E', '\xA4', '\xAE', ' ', '\xF0', '\x9E', '\xA4', '\xBB', ' ', '\xF0', '\x9E', '\xA4', '\xBC', ' ', '\xF0', '\x9E', '\xA4', '\xBE', /* 𞤬 𞤮 𞤻 𞤼 𞤾 */ + '\0', + '\xF0', '\x9E', '\xA4', '\xA4', ' ', '\xF0', '\x9E', '\xA4', '\xA8', ' ', '\xF0', '\x9E', '\xA4', '\xA9', ' ', '\xF0', '\x9E', '\xA4', '\xAD', ' ', '\xF0', '\x9E', '\xA4', '\xB4', ' ', '\xF0', '\x9E', '\xA4', '\xB8', ' ', '\xF0', '\x9E', '\xA4', '\xBA', ' ', '\xF0', '\x9E', '\xA5', '\x80', /* 𞤤 𞤨 𞤩 𞤭 𞤴 𞤸 𞤺 𞥀 */ + '\0', + '\xD8', '\xA7', ' ', '\xD8', '\xA5', ' ', '\xD9', '\x84', ' ', '\xD9', '\x83', ' ', '\xD8', '\xB7', ' ', '\xD8', '\xB8', /* ا إ ل ك ط ظ */ + '\0', + '\xD8', '\xAA', ' ', '\xD8', '\xAB', ' ', '\xD8', '\xB7', ' ', '\xD8', '\xB8', ' ', '\xD9', '\x83', /* ت ث ط ظ ك */ '\0', '\xD9', '\x80', /* ـ */ '\0', - '\xD0', '\x91', '\xD0', '\x92', '\xD0', '\x95', '\xD0', '\x9F', '\xD0', '\x97', '\xD0', '\x9E', '\xD0', '\xA1', '\xD0', '\xAD', /* БВЕПЗОСЭ */ + '\xD4', '\xB1', ' ', '\xD5', '\x84', ' ', '\xD5', '\x92', ' ', '\xD5', '\x8D', ' ', '\xD4', '\xB2', ' ', '\xD4', '\xB3', ' ', '\xD4', '\xB4', ' ', '\xD5', '\x95', /* Ա Մ Ւ Ս Բ Գ Դ Օ */ '\0', - '\xD0', '\x91', '\xD0', '\x92', '\xD0', '\x95', '\xD0', '\xA8', '\xD0', '\x97', '\xD0', '\x9E', '\xD0', '\xA1', '\xD0', '\xAD', /* БВЕШЗОСЭ */ + '\xD5', '\x92', ' ', '\xD5', '\x88', ' ', '\xD4', '\xB4', ' ', '\xD5', '\x83', ' ', '\xD5', '\x87', ' ', '\xD5', '\x8D', ' ', '\xD5', '\x8F', ' ', '\xD5', '\x95', /* Ւ Ո Դ Ճ Շ Ս Տ Օ */ '\0', - '\xD1', '\x85', '\xD0', '\xBF', '\xD0', '\xBD', '\xD1', '\x88', '\xD0', '\xB5', '\xD0', '\xB7', '\xD0', '\xBE', '\xD1', '\x81', /* хпншезос */ + '\xD5', '\xA5', ' ', '\xD5', '\xA7', ' ', '\xD5', '\xAB', ' ', '\xD5', '\xB4', ' ', '\xD5', '\xBE', ' ', '\xD6', '\x86', ' ', '\xD5', '\xB3', /* ե է ի մ վ ֆ ճ */ '\0', - '\xD1', '\x80', '\xD1', '\x83', '\xD1', '\x84', /* руф */ + '\xD5', '\xA1', ' ', '\xD5', '\xB5', ' ', '\xD6', '\x82', ' ', '\xD5', '\xBD', ' ', '\xD5', '\xA3', ' ', '\xD5', '\xB7', ' ', '\xD6', '\x80', ' ', '\xD6', '\x85', /* ա յ ւ ս գ շ ր օ */ '\0', - '\xE0', '\xA4', '\x95', '\xE0', '\xA4', '\xAE', '\xE0', '\xA4', '\x85', '\xE0', '\xA4', '\x86', '\xE0', '\xA4', '\xA5', '\xE0', '\xA4', '\xA7', '\xE0', '\xA4', '\xAD', '\xE0', '\xA4', '\xB6', /* क म अ आ थ ध भ श */ + '\xD5', '\xB0', ' ', '\xD5', '\xB8', ' ', '\xD5', '\xB3', ' ', '\xD5', '\xA1', ' ', '\xD5', '\xA5', ' ', '\xD5', '\xAE', ' ', '\xD5', '\xBD', ' ', '\xD6', '\x85', /* հ ո ճ ա ե ծ ս օ */ '\0', - '\xE0', '\xA4', '\x88', '\xE0', '\xA4', '\x90', '\xE0', '\xA4', '\x93', '\xE0', '\xA4', '\x94', '\xE0', '\xA4', '\xBF', '\xE0', '\xA5', '\x80', '\xE0', '\xA5', '\x8B', '\xE0', '\xA5', '\x8C', /* ई ऐ ओ औ ि ी ो ौ */ + '\xD5', '\xA2', ' ', '\xD5', '\xA8', ' ', '\xD5', '\xAB', ' ', '\xD5', '\xAC', ' ', '\xD5', '\xB2', ' ', '\xD5', '\xBA', ' ', '\xD6', '\x83', ' ', '\xD6', '\x81', /* բ ը ի լ ղ պ փ ց */ '\0', - '\xE0', '\xA4', '\x95', '\xE0', '\xA4', '\xAE', '\xE0', '\xA4', '\x85', '\xE0', '\xA4', '\x86', '\xE0', '\xA4', '\xA5', '\xE0', '\xA4', '\xA7', '\xE0', '\xA4', '\xAD', '\xE0', '\xA4', '\xB6', /* क म अ आ थ ध भ श */ + '\xF0', '\x90', '\xAC', '\x80', ' ', '\xF0', '\x90', '\xAC', '\x81', ' ', '\xF0', '\x90', '\xAC', '\x90', ' ', '\xF0', '\x90', '\xAC', '\x9B', /* 𐬀 𐬁 𐬐 𐬛 */ '\0', - '\xE0', '\xA5', '\x81', '\xE0', '\xA5', '\x83', /* ु ृ */ + '\xF0', '\x90', '\xAC', '\x80', ' ', '\xF0', '\x90', '\xAC', '\x81', /* 𐬀 𐬁 */ '\0', - '\xCE', '\x93', '\xCE', '\x92', '\xCE', '\x95', '\xCE', '\x96', '\xCE', '\x98', '\xCE', '\x9F', '\xCE', '\xA9', /* ΓΒΕΖΘΟΩ */ + '\xEA', '\x9A', '\xA7', ' ', '\xEA', '\x9A', '\xA8', ' ', '\xEA', '\x9B', '\x9B', ' ', '\xEA', '\x9B', '\x89', ' ', '\xEA', '\x9B', '\x81', ' ', '\xEA', '\x9B', '\x88', ' ', '\xEA', '\x9B', '\xAB', ' ', '\xEA', '\x9B', '\xAF', /* ꚧ ꚨ ꛛ ꛉ ꛁ ꛈ ꛫ ꛯ */ '\0', - '\xCE', '\x92', '\xCE', '\x94', '\xCE', '\x96', '\xCE', '\x9E', '\xCE', '\x98', '\xCE', '\x9F', /* ΒΔΖΞΘΟ */ + '\xEA', '\x9A', '\xAD', ' ', '\xEA', '\x9A', '\xB3', ' ', '\xEA', '\x9A', '\xB6', ' ', '\xEA', '\x9B', '\xAC', ' ', '\xEA', '\x9A', '\xA2', ' ', '\xEA', '\x9A', '\xBD', ' ', '\xEA', '\x9B', '\xAF', ' ', '\xEA', '\x9B', '\xB2', /* ꚭ ꚳ ꚶ ꛬ ꚢ ꚽ ꛯ ꛲ */ '\0', - '\xCE', '\xB2', '\xCE', '\xB8', '\xCE', '\xB4', '\xCE', '\xB6', '\xCE', '\xBB', '\xCE', '\xBE', /* βθδζλξ */ + '\xE0', '\xA6', '\x85', ' ', '\xE0', '\xA6', '\xA1', ' ', '\xE0', '\xA6', '\xA4', ' ', '\xE0', '\xA6', '\xA8', ' ', '\xE0', '\xA6', '\xAC', ' ', '\xE0', '\xA6', '\xAD', ' ', '\xE0', '\xA6', '\xB2', ' ', '\xE0', '\xA6', '\x95', /* অ ড ত ন ব ভ ল ক */ '\0', - '\xCE', '\xB1', '\xCE', '\xB5', '\xCE', '\xB9', '\xCE', '\xBF', '\xCF', '\x80', '\xCF', '\x83', '\xCF', '\x84', '\xCF', '\x89', /* αειοπστω */ + '\xE0', '\xA6', '\x87', ' ', '\xE0', '\xA6', '\x9F', ' ', '\xE0', '\xA6', '\xA0', ' ', '\xE0', '\xA6', '\xBF', ' ', '\xE0', '\xA7', '\x80', ' ', '\xE0', '\xA7', '\x88', ' ', '\xE0', '\xA7', '\x97', /* ই ট ঠ ি ী ৈ ৗ */ '\0', - '\xCE', '\xB2', '\xCE', '\xB3', '\xCE', '\xB7', '\xCE', '\xBC', '\xCF', '\x81', '\xCF', '\x86', '\xCF', '\x87', '\xCF', '\x88', /* βγημρφχψ */ + '\xE0', '\xA6', '\x93', ' ', '\xE0', '\xA6', '\x8F', ' ', '\xE0', '\xA6', '\xA1', ' ', '\xE0', '\xA6', '\xA4', ' ', '\xE0', '\xA6', '\xA8', ' ', '\xE0', '\xA6', '\xAC', ' ', '\xE0', '\xA6', '\xB2', ' ', '\xE0', '\xA6', '\x95', /* ও এ ড ত ন ব ল ক */ '\0', - '\xD7', '\x91', '\xD7', '\x93', '\xD7', '\x94', '\xD7', '\x97', '\xD7', '\x9A', '\xD7', '\x9B', '\xD7', '\x9D', '\xD7', '\xA1', /* בדהחךכםס */ + '\xE1', '\x9D', '\x90', ' ', '\xE1', '\x9D', '\x88', /* ᝐ ᝈ */ '\0', - '\xD7', '\x91', '\xD7', '\x98', '\xD7', '\x9B', '\xD7', '\x9D', '\xD7', '\xA1', '\xD7', '\xA6', /* בטכםסצ */ + '\xE1', '\x9D', '\x85', ' ', '\xE1', '\x9D', '\x8A', ' ', '\xE1', '\x9D', '\x8E', /* ᝅ ᝊ ᝎ */ '\0', - '\xD7', '\xA7', '\xD7', '\x9A', '\xD7', '\x9F', '\xD7', '\xA3', '\xD7', '\xA5', /* קךןףץ */ + '\xE1', '\x9D', '\x82', ' ', '\xE1', '\x9D', '\x83', ' ', '\xE1', '\x9D', '\x89', ' ', '\xE1', '\x9D', '\x8C', /* ᝂ ᝃ ᝉ ᝌ */ '\0', - '\xE0', '\xBA', '\xB2', '\xE0', '\xBA', '\x94', '\xE0', '\xBA', '\xAD', '\xE0', '\xBA', '\xA1', '\xE0', '\xBA', '\xA5', '\xE0', '\xBA', '\xA7', '\xE0', '\xBA', '\xA3', '\xE0', '\xBA', '\x87', /* າ ດ ອ ມ ລ ວ ຣ ງ */ + '\xE1', '\x9D', '\x80', ' ', '\xE1', '\x9D', '\x83', ' ', '\xE1', '\x9D', '\x86', ' ', '\xE1', '\x9D', '\x89', ' ', '\xE1', '\x9D', '\x8B', ' ', '\xE1', '\x9D', '\x8F', ' ', '\xE1', '\x9D', '\x91', /* ᝀ ᝃ ᝆ ᝉ ᝋ ᝏ ᝑ */ '\0', - '\xE0', '\xBA', '\xB2', '\xE0', '\xBA', '\xAD', '\xE0', '\xBA', '\x9A', '\xE0', '\xBA', '\x8D', '\xE0', '\xBA', '\xA3', '\xE0', '\xBA', '\xAE', '\xE0', '\xBA', '\xA7', '\xE0', '\xBA', '\xA2', /* າ ອ ບ ຍ ຣ ຮ ວ ຢ */ + '\xE1', '\x97', '\x9C', ' ', '\xE1', '\x96', '\xB4', ' ', '\xE1', '\x90', '\x81', ' ', '\xE1', '\x92', '\xA3', ' ', '\xE1', '\x91', '\xAB', ' ', '\xE1', '\x91', '\x8E', ' ', '\xE1', '\x94', '\x91', ' ', '\xE1', '\x97', '\xB0', /* ᗜ ᖴ ᐁ ᒣ ᑫ ᑎ ᔑ ᗰ */ '\0', - '\xE0', '\xBA', '\x9B', '\xE0', '\xBA', '\xA2', '\xE0', '\xBA', '\x9F', '\xE0', '\xBA', '\x9D', /* ປ ຢ ຟ ຝ */ + '\xE1', '\x97', '\xB6', ' ', '\xE1', '\x96', '\xB5', ' ', '\xE1', '\x92', '\xA7', ' ', '\xE1', '\x90', '\x83', ' ', '\xE1', '\x91', '\x8C', ' ', '\xE1', '\x92', '\x8D', ' ', '\xE1', '\x94', '\x91', ' ', '\xE1', '\x97', '\xA2', /* ᗶ ᖵ ᒧ ᐃ ᑌ ᒍ ᔑ ᗢ */ '\0', - '\xE0', '\xBB', '\x82', '\xE0', '\xBB', '\x84', '\xE0', '\xBB', '\x83', /* ໂ ໄ ໃ */ + '\xE1', '\x93', '\x93', ' ', '\xE1', '\x93', '\x95', ' ', '\xE1', '\x93', '\x80', ' ', '\xE1', '\x93', '\x82', ' ', '\xE1', '\x93', '\x84', ' ', '\xE1', '\x95', '\x84', ' ', '\xE1', '\x95', '\x86', ' ', '\xE1', '\x98', '\xA3', /* ᓓ ᓕ ᓀ ᓂ ᓄ ᕄ ᕆ ᘣ */ '\0', - '\xE0', '\xBA', '\x87', '\xE0', '\xBA', '\x8A', '\xE0', '\xBA', '\x96', '\xE0', '\xBA', '\xBD', '\xE0', '\xBB', '\x86', '\xE0', '\xBA', '\xAF', /* ງ ຊ ຖ ຽ ໆ ຯ */ + '\xE1', '\x95', '\x83', ' ', '\xE1', '\x93', '\x82', ' ', '\xE1', '\x93', '\x80', ' ', '\xE1', '\x95', '\x82', ' ', '\xE1', '\x93', '\x97', ' ', '\xE1', '\x93', '\x9A', ' ', '\xE1', '\x95', '\x86', ' ', '\xE1', '\x98', '\xA3', /* ᕃ ᓂ ᓀ ᕂ ᓗ ᓚ ᕆ ᘣ */ '\0', - 'T', 'H', 'E', 'Z', 'O', 'C', 'Q', 'S', /* THEZOCQS */ + '\xE1', '\x90', '\xAA', ' ', '\xE1', '\x99', '\x86', ' ', '\xE1', '\xA3', '\x98', ' ', '\xE1', '\x90', '\xA2', ' ', '\xE1', '\x92', '\xBE', ' ', '\xE1', '\xA3', '\x97', ' ', '\xE1', '\x94', '\x86', /* ᐪ ᙆ ᣘ ᐢ ᒾ ᣗ ᔆ */ '\0', - 'H', 'E', 'Z', 'L', 'O', 'C', 'U', 'S', /* HEZLOCUS */ + '\xE1', '\x99', '\x86', ' ', '\xE1', '\x97', '\xAE', ' ', '\xE1', '\x92', '\xBB', ' ', '\xE1', '\x90', '\x9E', ' ', '\xE1', '\x94', '\x86', ' ', '\xE1', '\x92', '\xA1', ' ', '\xE1', '\x92', '\xA2', ' ', '\xE1', '\x93', '\x91', /* ᙆ ᗮ ᒻ ᐞ ᔆ ᒡ ᒢ ᓑ */ '\0', - 'f', 'i', 'j', 'k', 'd', 'b', 'h', /* fijkdbh */ + '\xF0', '\x90', '\x8A', '\xA7', ' ', '\xF0', '\x90', '\x8A', '\xAB', ' ', '\xF0', '\x90', '\x8A', '\xAC', ' ', '\xF0', '\x90', '\x8A', '\xAD', ' ', '\xF0', '\x90', '\x8A', '\xB1', ' ', '\xF0', '\x90', '\x8A', '\xBA', ' ', '\xF0', '\x90', '\x8A', '\xBC', ' ', '\xF0', '\x90', '\x8A', '\xBF', /* 𐊧 𐊫 𐊬 𐊭 𐊱 𐊺 𐊼 𐊿 */ '\0', - 'x', 'z', 'r', 'o', 'e', 's', 'c', /* xzroesc */ + '\xF0', '\x90', '\x8A', '\xA3', ' ', '\xF0', '\x90', '\x8A', '\xA7', ' ', '\xF0', '\x90', '\x8A', '\xB7', ' ', '\xF0', '\x90', '\x8B', '\x80', ' ', '\xF0', '\x90', '\x8A', '\xAB', ' ', '\xF0', '\x90', '\x8A', '\xB8', ' ', '\xF0', '\x90', '\x8B', '\x89', /* 𐊣 𐊧 𐊷 𐋀 𐊫 𐊸 𐋉 */ '\0', - 'p', 'q', 'g', 'j', 'y', /* pqgjy */ + '\xF0', '\x91', '\x84', '\x83', ' ', '\xF0', '\x91', '\x84', '\x85', ' ', '\xF0', '\x91', '\x84', '\x89', ' ', '\xF0', '\x91', '\x84', '\x99', ' ', '\xF0', '\x91', '\x84', '\x97', /* 𑄃 𑄅 𑄉 𑄙 𑄗 */ '\0', - '\xE2', '\x82', '\x80', '\xE2', '\x82', '\x83', '\xE2', '\x82', '\x85', '\xE2', '\x82', '\x87', '\xE2', '\x82', '\x88', /* ₀₃₅₇₈ */ + '\xF0', '\x91', '\x84', '\x85', ' ', '\xF0', '\x91', '\x84', '\x9B', ' ', '\xF0', '\x91', '\x84', '\x9D', ' ', '\xF0', '\x91', '\x84', '\x97', ' ', '\xF0', '\x91', '\x84', '\x93', /* 𑄅 𑄛 𑄝 𑄗 𑄓 */ '\0', - '\xE2', '\x82', '\x80', '\xE2', '\x82', '\x81', '\xE2', '\x82', '\x82', '\xE2', '\x82', '\x83', '\xE2', '\x82', '\x88', /* ₀₁₂₃₈ */ + '\xF0', '\x91', '\x84', '\x96', '\xF0', '\x91', '\x84', '\xB3', '\xF0', '\x91', '\x84', '\xA2', ' ', '\xF0', '\x91', '\x84', '\x98', '\xF0', '\x91', '\x84', '\xB3', '\xF0', '\x91', '\x84', '\xA2', ' ', '\xF0', '\x91', '\x84', '\x99', '\xF0', '\x91', '\x84', '\xB3', '\xF0', '\x91', '\x84', '\xA2', ' ', '\xF0', '\x91', '\x84', '\xA4', '\xF0', '\x91', '\x84', '\xB3', '\xF0', '\x91', '\x84', '\xA2', ' ', '\xF0', '\x91', '\x84', '\xA5', '\xF0', '\x91', '\x84', '\xB3', '\xF0', '\x91', '\x84', '\xA2', /* 𑄖𑄳𑄢 𑄘𑄳𑄢 𑄙𑄳𑄢 𑄤𑄳𑄢 𑄥𑄳𑄢 */ '\0', - '\xE1', '\xB5', '\xA2', '\xE2', '\xB1', '\xBC', '\xE2', '\x82', '\x95', '\xE2', '\x82', '\x96', '\xE2', '\x82', '\x97', /* ᵢⱼₕₖₗ */ + '\xE1', '\x8F', '\x86', ' ', '\xE1', '\x8E', '\xBB', ' ', '\xE1', '\x8E', '\xAC', ' ', '\xE1', '\x8F', '\x83', ' ', '\xE1', '\x8E', '\xA4', ' ', '\xE1', '\x8F', '\xA3', ' ', '\xE1', '\x8E', '\xA6', ' ', '\xE1', '\x8F', '\x95', /* Ꮖ Ꮋ Ꭼ Ꮓ Ꭴ Ꮳ Ꭶ Ꮥ */ '\0', - '\xE2', '\x82', '\x90', '\xE2', '\x82', '\x91', '\xE2', '\x82', '\x92', '\xE2', '\x82', '\x93', '\xE2', '\x82', '\x99', '\xE2', '\x82', '\x9B', '\xE1', '\xB5', '\xA5', '\xE1', '\xB5', '\xA4', '\xE1', '\xB5', '\xA3', /* ₐₑₒₓₙₛᵥᵤᵣ */ + '\xEA', '\xAE', '\x92', ' ', '\xEA', '\xAE', '\xA4', ' ', '\xEA', '\xAE', '\xB6', ' ', '\xEA', '\xAD', '\xB4', ' ', '\xEA', '\xAD', '\xBE', ' ', '\xEA', '\xAE', '\x97', ' ', '\xEA', '\xAE', '\x9D', ' ', '\xEA', '\xAE', '\xBF', /* ꮒ ꮤ ꮶ ꭴ ꭾ ꮗ ꮝ ꮿ */ '\0', - '\xE1', '\xB5', '\xA6', '\xE1', '\xB5', '\xA7', '\xE1', '\xB5', '\xA8', '\xE1', '\xB5', '\xA9', '\xE2', '\x82', '\x9A', /* ᵦᵧᵨᵩₚ */ + '\xEA', '\xAE', '\x96', ' ', '\xEA', '\xAD', '\xBC', ' ', '\xEA', '\xAE', '\x93', ' ', '\xEA', '\xAE', '\xA0', ' ', '\xEA', '\xAE', '\xB3', ' ', '\xEA', '\xAD', '\xB6', ' ', '\xEA', '\xAE', '\xA5', ' ', '\xEA', '\xAE', '\xBB', /* ꮖ ꭼ ꮓ ꮠ ꮳ ꭶ ꮥ ꮻ */ '\0', - '\xE2', '\x81', '\xB0', '\xC2', '\xB3', '\xE2', '\x81', '\xB5', '\xE2', '\x81', '\xB7', '\xE1', '\xB5', '\x80', '\xE1', '\xB4', '\xB4', '\xE1', '\xB4', '\xB1', '\xE1', '\xB4', '\xBC', /* ⁰³⁵⁷ᵀᴴᴱᴼ */ + '\xE1', '\x8F', '\xB8', ' ', '\xEA', '\xAE', '\x90', ' ', '\xEA', '\xAD', '\xB9', ' ', '\xEA', '\xAD', '\xBB', /* ᏸ ꮐ ꭹ ꭻ */ '\0', - '\xE2', '\x81', '\xB0', '\xC2', '\xB9', '\xC2', '\xB2', '\xC2', '\xB3', '\xE1', '\xB4', '\xB1', '\xE1', '\xB4', '\xB8', '\xE1', '\xB4', '\xBC', '\xE1', '\xB5', '\x81', /* ⁰¹²³ᴱᴸᴼᵁ */ + '\xE2', '\xB2', '\x8C', ' ', '\xE2', '\xB2', '\x8E', ' ', '\xE2', '\xB2', '\xA0', ' ', '\xE2', '\xB3', '\x9E', ' ', '\xE2', '\xB2', '\x9E', ' ', '\xE2', '\xB2', '\x90', ' ', '\xE2', '\xB2', '\xA4', ' ', '\xE2', '\xB3', '\x8A', /* Ⲍ Ⲏ Ⲡ Ⳟ Ⲟ Ⲑ Ⲥ Ⳋ */ '\0', - '\xE1', '\xB5', '\x87', '\xE1', '\xB5', '\x88', '\xE1', '\xB5', '\x8F', '\xCA', '\xB0', '\xCA', '\xB2', '\xE1', '\xB6', '\xA0', '\xE2', '\x81', '\xB1', /* ᵇᵈᵏʰʲᶠⁱ */ + '\xE2', '\xB3', '\x90', ' ', '\xE2', '\xB3', '\x98', ' ', '\xE2', '\xB3', '\x9E', ' ', '\xE2', '\xB2', '\x8E', ' ', '\xE2', '\xB2', '\x9E', ' ', '\xE2', '\xB2', '\x90', ' ', '\xE2', '\xB3', '\x9C', ' ', '\xE2', '\xB2', '\xB0', /* Ⳑ Ⳙ Ⳟ Ⲏ Ⲟ Ⲑ Ⳝ Ⲱ */ '\0', - '\xE1', '\xB5', '\x89', '\xE1', '\xB5', '\x92', '\xCA', '\xB3', '\xCB', '\xA2', '\xCB', '\xA3', '\xE1', '\xB6', '\x9C', '\xE1', '\xB6', '\xBB', /* ᵉᵒʳˢˣᶜᶻ */ + '\xE2', '\xB2', '\x8D', ' ', '\xE2', '\xB2', '\x8F', ' ', '\xE2', '\xB2', '\xA1', ' ', '\xE2', '\xB3', '\x9F', ' ', '\xE2', '\xB2', '\x9F', ' ', '\xE2', '\xB2', '\x91', ' ', '\xE2', '\xB2', '\xA5', ' ', '\xE2', '\xB3', '\x8B', /* ⲍ ⲏ ⲡ ⳟ ⲟ ⲑ ⲥ ⳋ */ '\0', - '\xE1', '\xB5', '\x96', '\xCA', '\xB8', '\xE1', '\xB5', '\x8D', /* ᵖʸᵍ */ + '\xE2', '\xB3', '\x91', ' ', '\xE2', '\xB3', '\x99', ' ', '\xE2', '\xB3', '\x9F', ' ', '\xE2', '\xB2', '\x8F', ' ', '\xE2', '\xB2', '\x9F', ' ', '\xE2', '\xB2', '\x91', ' ', '\xE2', '\xB3', '\x9D', ' ', '\xE2', '\xB3', '\x92', /* ⳑ ⳙ ⳟ ⲏ ⲟ ⲑ ⳝ Ⳓ */ '\0', - '\xE0', '\xB0', '\x87', '\xE0', '\xB0', '\x8C', '\xE0', '\xB0', '\x99', '\xE0', '\xB0', '\x9E', '\xE0', '\xB0', '\xA3', '\xE0', '\xB0', '\xB1', '\xE0', '\xB1', '\xAF', /* ఇ ఌ ఙ ఞ ణ ఱ ౯ */ + '\xF0', '\x90', '\xA0', '\x8D', ' ', '\xF0', '\x90', '\xA0', '\x99', ' ', '\xF0', '\x90', '\xA0', '\xB3', ' ', '\xF0', '\x90', '\xA0', '\xB1', ' ', '\xF0', '\x90', '\xA0', '\x85', ' ', '\xF0', '\x90', '\xA0', '\x93', ' ', '\xF0', '\x90', '\xA0', '\xA3', ' ', '\xF0', '\x90', '\xA0', '\xA6', /* 𐠍 𐠙 𐠳 𐠱 𐠅 𐠓 𐠣 𐠦 */ '\0', - '\xE0', '\xB0', '\x85', '\xE0', '\xB0', '\x95', '\xE0', '\xB0', '\x9A', '\xE0', '\xB0', '\xB0', '\xE0', '\xB0', '\xBD', '\xE0', '\xB1', '\xA8', '\xE0', '\xB1', '\xAC', /* అ క చ ర ఽ ౨ ౬ */ + '\xF0', '\x90', '\xA0', '\x83', ' ', '\xF0', '\x90', '\xA0', '\x8A', ' ', '\xF0', '\x90', '\xA0', '\x9B', ' ', '\xF0', '\x90', '\xA0', '\xA3', ' ', '\xF0', '\x90', '\xA0', '\xB3', ' ', '\xF0', '\x90', '\xA0', '\xB5', ' ', '\xF0', '\x90', '\xA0', '\x90', /* 𐠃 𐠊 𐠛 𐠣 𐠳 𐠵 𐠐 */ '\0', - '\xE0', '\xB8', '\x9A', '\xE0', '\xB9', '\x80', '\xE0', '\xB9', '\x81', '\xE0', '\xB8', '\xAD', '\xE0', '\xB8', '\x81', '\xE0', '\xB8', '\xB2', /* บ เ แ อ ก า */ + '\xF0', '\x90', '\xA0', '\x88', ' ', '\xF0', '\x90', '\xA0', '\x8F', ' ', '\xF0', '\x90', '\xA0', '\x96', /* 𐠈 𐠏 𐠖 */ '\0', - '\xE0', '\xB8', '\x9A', '\xE0', '\xB8', '\x9B', '\xE0', '\xB8', '\xA9', '\xE0', '\xB8', '\xAF', '\xE0', '\xB8', '\xAD', '\xE0', '\xB8', '\xA2', '\xE0', '\xB8', '\xAE', /* บ ป ษ ฯ อ ย ฮ */ + '\xD0', '\x91', ' ', '\xD0', '\x92', ' ', '\xD0', '\x95', ' ', '\xD0', '\x9F', ' ', '\xD0', '\x97', ' ', '\xD0', '\x9E', ' ', '\xD0', '\xA1', ' ', '\xD0', '\xAD', /* Б В Е П З О С Э */ '\0', - '\xE0', '\xB8', '\x9B', '\xE0', '\xB8', '\x9D', '\xE0', '\xB8', '\x9F', /* ป ฝ ฟ */ + '\xD0', '\x91', ' ', '\xD0', '\x92', ' ', '\xD0', '\x95', ' ', '\xD0', '\xA8', ' ', '\xD0', '\x97', ' ', '\xD0', '\x9E', ' ', '\xD0', '\xA1', ' ', '\xD0', '\xAD', /* Б В Е Ш З О С Э */ '\0', - '\xE0', '\xB9', '\x82', '\xE0', '\xB9', '\x83', '\xE0', '\xB9', '\x84', /* โ ใ ไ */ + '\xD1', '\x85', ' ', '\xD0', '\xBF', ' ', '\xD0', '\xBD', ' ', '\xD1', '\x88', ' ', '\xD0', '\xB5', ' ', '\xD0', '\xB7', ' ', '\xD0', '\xBE', ' ', '\xD1', '\x81', /* х п н ш е з о с */ '\0', - '\xE0', '\xB8', '\x8E', '\xE0', '\xB8', '\x8F', '\xE0', '\xB8', '\xA4', '\xE0', '\xB8', '\xA6', /* ฎ ฏ ฤ ฦ */ + '\xD1', '\x80', ' ', '\xD1', '\x83', ' ', '\xD1', '\x84', /* р у ф */ '\0', - '\xE0', '\xB8', '\x8D', '\xE0', '\xB8', '\x90', /* ญ ฐ */ + '\xF0', '\x90', '\x90', '\x82', ' ', '\xF0', '\x90', '\x90', '\x84', ' ', '\xF0', '\x90', '\x90', '\x8B', ' ', '\xF0', '\x90', '\x90', '\x97', ' ', '\xF0', '\x90', '\x90', '\x91', /* 𐐂 𐐄 𐐋 𐐗 𐐑 */ '\0', - '\xE0', '\xB9', '\x90', '\xE0', '\xB9', '\x91', '\xE0', '\xB9', '\x93', /* ๐ ๑ ๓ */ + '\xF0', '\x90', '\x90', '\x80', ' ', '\xF0', '\x90', '\x90', '\x82', ' ', '\xF0', '\x90', '\x90', '\x84', ' ', '\xF0', '\x90', '\x90', '\x97', ' ', '\xF0', '\x90', '\x90', '\x9B', /* 𐐀 𐐂 𐐄 𐐗 𐐛 */ + '\0', + '\xF0', '\x90', '\x90', '\xAA', ' ', '\xF0', '\x90', '\x90', '\xAC', ' ', '\xF0', '\x90', '\x90', '\xB3', ' ', '\xF0', '\x90', '\x90', '\xBF', ' ', '\xF0', '\x90', '\x90', '\xB9', /* 𐐪 𐐬 𐐳 𐐿 𐐹 */ + '\0', + '\xF0', '\x90', '\x90', '\xA8', ' ', '\xF0', '\x90', '\x90', '\xAA', ' ', '\xF0', '\x90', '\x90', '\xAC', ' ', '\xF0', '\x90', '\x90', '\xBF', ' ', '\xF0', '\x90', '\x91', '\x83', /* 𐐨 𐐪 𐐬 𐐿 𐑃 */ + '\0', + '\xE0', '\xA4', '\x95', ' ', '\xE0', '\xA4', '\xAE', ' ', '\xE0', '\xA4', '\x85', ' ', '\xE0', '\xA4', '\x86', ' ', '\xE0', '\xA4', '\xA5', ' ', '\xE0', '\xA4', '\xA7', ' ', '\xE0', '\xA4', '\xAD', ' ', '\xE0', '\xA4', '\xB6', /* क म अ आ थ ध भ श */ + '\0', + '\xE0', '\xA4', '\x88', ' ', '\xE0', '\xA4', '\x90', ' ', '\xE0', '\xA4', '\x93', ' ', '\xE0', '\xA4', '\x94', ' ', '\xE0', '\xA4', '\xBF', ' ', '\xE0', '\xA5', '\x80', ' ', '\xE0', '\xA5', '\x8B', ' ', '\xE0', '\xA5', '\x8C', /* ई ऐ ओ औ ि ी ो ौ */ + '\0', + '\xE0', '\xA4', '\x95', ' ', '\xE0', '\xA4', '\xAE', ' ', '\xE0', '\xA4', '\x85', ' ', '\xE0', '\xA4', '\x86', ' ', '\xE0', '\xA4', '\xA5', ' ', '\xE0', '\xA4', '\xA7', ' ', '\xE0', '\xA4', '\xAD', ' ', '\xE0', '\xA4', '\xB6', /* क म अ आ थ ध भ श */ + '\0', + '\xE0', '\xA5', '\x81', ' ', '\xE0', '\xA5', '\x83', /* ु ृ */ + '\0', + '\xE1', '\x88', '\x80', ' ', '\xE1', '\x88', '\x83', ' ', '\xE1', '\x8B', '\x98', ' ', '\xE1', '\x8D', '\x90', ' ', '\xE1', '\x88', '\x9B', ' ', '\xE1', '\x89', '\xA0', ' ', '\xE1', '\x8B', '\x8B', ' ', '\xE1', '\x8B', '\x90', /* ሀ ሃ ዘ ፐ ማ በ ዋ ዐ */ + '\0', + '\xE1', '\x88', '\x88', ' ', '\xE1', '\x88', '\x90', ' ', '\xE1', '\x89', '\xA0', ' ', '\xE1', '\x8B', '\x98', ' ', '\xE1', '\x88', '\x80', ' ', '\xE1', '\x88', '\xAA', ' ', '\xE1', '\x8B', '\x90', ' ', '\xE1', '\x8C', '\xA8', /* ለ ሐ በ ዘ ሀ ሪ ዐ ጨ */ + '\0', + '\xE1', '\x83', '\x92', ' ', '\xE1', '\x83', '\x93', ' ', '\xE1', '\x83', '\x94', ' ', '\xE1', '\x83', '\x95', ' ', '\xE1', '\x83', '\x97', ' ', '\xE1', '\x83', '\x98', ' ', '\xE1', '\x83', '\x9D', ' ', '\xE1', '\x83', '\xA6', /* გ დ ე ვ თ ი ო ღ */ + '\0', + '\xE1', '\x83', '\x90', ' ', '\xE1', '\x83', '\x96', ' ', '\xE1', '\x83', '\x9B', ' ', '\xE1', '\x83', '\xA1', ' ', '\xE1', '\x83', '\xA8', ' ', '\xE1', '\x83', '\xAB', ' ', '\xE1', '\x83', '\xAE', ' ', '\xE1', '\x83', '\x9E', /* ა ზ მ ს შ ძ ხ პ */ + '\0', + '\xE1', '\x83', '\xA1', ' ', '\xE1', '\x83', '\xAE', ' ', '\xE1', '\x83', '\xA5', ' ', '\xE1', '\x83', '\x96', ' ', '\xE1', '\x83', '\x9B', ' ', '\xE1', '\x83', '\xA8', ' ', '\xE1', '\x83', '\xA9', ' ', '\xE1', '\x83', '\xAC', /* ს ხ ქ ზ მ შ ჩ წ */ + '\0', + '\xE1', '\x83', '\x94', ' ', '\xE1', '\x83', '\x95', ' ', '\xE1', '\x83', '\x9F', ' ', '\xE1', '\x83', '\xA2', ' ', '\xE1', '\x83', '\xA3', ' ', '\xE1', '\x83', '\xA4', ' ', '\xE1', '\x83', '\xA5', ' ', '\xE1', '\x83', '\xA7', /* ე ვ ჟ ტ უ ფ ქ ყ */ + '\0', + '\xE1', '\x82', '\xB1', ' ', '\xE1', '\x82', '\xA7', ' ', '\xE1', '\x82', '\xB9', ' ', '\xE1', '\x82', '\xBC', ' ', '\xE1', '\x82', '\xA4', ' ', '\xE1', '\x82', '\xA5', ' ', '\xE1', '\x82', '\xB3', ' ', '\xE1', '\x82', '\xBA', /* Ⴑ Ⴇ Ⴙ Ⴜ Ⴄ Ⴅ Ⴓ Ⴚ */ + '\0', + '\xE1', '\x82', '\xA4', ' ', '\xE1', '\x82', '\xA5', ' ', '\xE1', '\x82', '\xA7', ' ', '\xE1', '\x82', '\xA8', ' ', '\xE1', '\x82', '\xA6', ' ', '\xE1', '\x82', '\xB1', ' ', '\xE1', '\x82', '\xAA', ' ', '\xE1', '\x82', '\xAB', /* Ⴄ Ⴅ Ⴇ Ⴈ Ⴆ Ⴑ Ⴊ Ⴋ */ + '\0', + '\xE2', '\xB4', '\x81', ' ', '\xE2', '\xB4', '\x97', ' ', '\xE2', '\xB4', '\x82', ' ', '\xE2', '\xB4', '\x84', ' ', '\xE2', '\xB4', '\x85', ' ', '\xE2', '\xB4', '\x87', ' ', '\xE2', '\xB4', '\x94', ' ', '\xE2', '\xB4', '\x96', /* ⴁ ⴗ ⴂ ⴄ ⴅ ⴇ ⴔ ⴖ */ + '\0', + '\xE2', '\xB4', '\x88', ' ', '\xE2', '\xB4', '\x8C', ' ', '\xE2', '\xB4', '\x96', ' ', '\xE2', '\xB4', '\x8E', ' ', '\xE2', '\xB4', '\x83', ' ', '\xE2', '\xB4', '\x86', ' ', '\xE2', '\xB4', '\x8B', ' ', '\xE2', '\xB4', '\xA2', /* ⴈ ⴌ ⴖ ⴎ ⴃ ⴆ ⴋ ⴢ */ + '\0', + '\xE2', '\xB4', '\x90', ' ', '\xE2', '\xB4', '\x91', ' ', '\xE2', '\xB4', '\x93', ' ', '\xE2', '\xB4', '\x95', ' ', '\xE2', '\xB4', '\x99', ' ', '\xE2', '\xB4', '\x9B', ' ', '\xE2', '\xB4', '\xA1', ' ', '\xE2', '\xB4', '\xA3', /* ⴐ ⴑ ⴓ ⴕ ⴙ ⴛ ⴡ ⴣ */ + '\0', + '\xE2', '\xB4', '\x84', ' ', '\xE2', '\xB4', '\x85', ' ', '\xE2', '\xB4', '\x94', ' ', '\xE2', '\xB4', '\x95', ' ', '\xE2', '\xB4', '\x81', ' ', '\xE2', '\xB4', '\x82', ' ', '\xE2', '\xB4', '\x98', ' ', '\xE2', '\xB4', '\x9D', /* ⴄ ⴅ ⴔ ⴕ ⴁ ⴂ ⴘ ⴝ */ + '\0', + '\xE1', '\xB2', '\x9C', ' ', '\xE1', '\xB2', '\x9F', ' ', '\xE1', '\xB2', '\xB3', ' ', '\xE1', '\xB2', '\xB8', ' ', '\xE1', '\xB2', '\x92', ' ', '\xE1', '\xB2', '\x94', ' ', '\xE1', '\xB2', '\x9D', ' ', '\xE1', '\xB2', '\xB4', /* Ნ Ჟ Ჳ Ჸ Გ Ე Ო Ჴ */ + '\0', + '\xE1', '\xB2', '\x98', ' ', '\xE1', '\xB2', '\xB2', ' ', '\xE1', '\xB2', '\x9D', ' ', '\xE1', '\xB2', '\xA9', ' ', '\xE1', '\xB2', '\x9B', ' ', '\xE1', '\xB2', '\xA8', ' ', '\xE1', '\xB2', '\xAF', ' ', '\xE1', '\xB2', '\xBD', /* Ი Ჲ Ო Ჩ Მ Შ Ჯ Ჽ */ + '\0', + '\xE2', '\xB0', '\x85', ' ', '\xE2', '\xB0', '\x94', ' ', '\xE2', '\xB0', '\xAA', ' ', '\xE2', '\xB0', '\x84', ' ', '\xE2', '\xB0', '\x82', ' ', '\xE2', '\xB0', '\x8A', ' ', '\xE2', '\xB0', '\xAB', ' ', '\xE2', '\xB0', '\x8B', /* Ⰵ Ⱄ Ⱚ Ⰴ Ⰲ Ⰺ Ⱛ Ⰻ */ + '\0', + '\xE2', '\xB0', '\x85', ' ', '\xE2', '\xB0', '\x84', ' ', '\xE2', '\xB0', '\x82', ' ', '\xE2', '\xB0', '\xAA', ' ', '\xE2', '\xB0', '\x9E', ' ', '\xE2', '\xB0', '\xA1', ' ', '\xE2', '\xB0', '\x8A', ' ', '\xE2', '\xB0', '\x94', /* Ⰵ Ⰴ Ⰲ Ⱚ Ⱎ Ⱑ Ⰺ Ⱄ */ + '\0', + '\xE2', '\xB0', '\xB5', ' ', '\xE2', '\xB1', '\x84', ' ', '\xE2', '\xB1', '\x9A', ' ', '\xE2', '\xB0', '\xB4', ' ', '\xE2', '\xB0', '\xB2', ' ', '\xE2', '\xB0', '\xBA', ' ', '\xE2', '\xB1', '\x9B', ' ', '\xE2', '\xB0', '\xBB', /* ⰵ ⱄ ⱚ ⰴ ⰲ ⰺ ⱛ ⰻ */ + '\0', + '\xE2', '\xB0', '\xB5', ' ', '\xE2', '\xB0', '\xB4', ' ', '\xE2', '\xB0', '\xB2', ' ', '\xE2', '\xB1', '\x9A', ' ', '\xE2', '\xB1', '\x8E', ' ', '\xE2', '\xB1', '\x91', ' ', '\xE2', '\xB0', '\xBA', ' ', '\xE2', '\xB1', '\x84', /* ⰵ ⰴ ⰲ ⱚ ⱎ ⱑ ⰺ ⱄ */ + '\0', + '\xF0', '\x90', '\x8C', '\xB2', ' ', '\xF0', '\x90', '\x8C', '\xB6', ' ', '\xF0', '\x90', '\x8D', '\x80', ' ', '\xF0', '\x90', '\x8D', '\x84', ' ', '\xF0', '\x90', '\x8C', '\xB4', ' ', '\xF0', '\x90', '\x8D', '\x83', ' ', '\xF0', '\x90', '\x8D', '\x88', ' ', '\xF0', '\x90', '\x8C', '\xBE', /* 𐌲 𐌶 𐍀 𐍄 𐌴 𐍃 𐍈 𐌾 */ + '\0', + '\xF0', '\x90', '\x8C', '\xB6', ' ', '\xF0', '\x90', '\x8C', '\xB4', ' ', '\xF0', '\x90', '\x8D', '\x83', ' ', '\xF0', '\x90', '\x8D', '\x88', /* 𐌶 𐌴 𐍃 𐍈 */ + '\0', + '\xCE', '\x93', ' ', '\xCE', '\x92', ' ', '\xCE', '\x95', ' ', '\xCE', '\x96', ' ', '\xCE', '\x98', ' ', '\xCE', '\x9F', ' ', '\xCE', '\xA9', /* Γ Β Ε Ζ Θ Ο Ω */ + '\0', + '\xCE', '\x92', ' ', '\xCE', '\x94', ' ', '\xCE', '\x96', ' ', '\xCE', '\x9E', ' ', '\xCE', '\x98', ' ', '\xCE', '\x9F', /* Β Δ Ζ Ξ Θ Ο */ + '\0', + '\xCE', '\xB2', ' ', '\xCE', '\xB8', ' ', '\xCE', '\xB4', ' ', '\xCE', '\xB6', ' ', '\xCE', '\xBB', ' ', '\xCE', '\xBE', /* β θ δ ζ λ ξ */ + '\0', + '\xCE', '\xB1', ' ', '\xCE', '\xB5', ' ', '\xCE', '\xB9', ' ', '\xCE', '\xBF', ' ', '\xCF', '\x80', ' ', '\xCF', '\x83', ' ', '\xCF', '\x84', ' ', '\xCF', '\x89', /* α ε ι ο π σ τ ω */ + '\0', + '\xCE', '\xB2', ' ', '\xCE', '\xB3', ' ', '\xCE', '\xB7', ' ', '\xCE', '\xBC', ' ', '\xCF', '\x81', ' ', '\xCF', '\x86', ' ', '\xCF', '\x87', ' ', '\xCF', '\x88', /* β γ η μ ρ φ χ ψ */ + '\0', + '\xE0', '\xAA', '\xA4', ' ', '\xE0', '\xAA', '\xA8', ' ', '\xE0', '\xAA', '\x8B', ' ', '\xE0', '\xAA', '\x8C', ' ', '\xE0', '\xAA', '\x9B', ' ', '\xE0', '\xAA', '\x9F', ' ', '\xE0', '\xAA', '\xB0', ' ', '\xE0', '\xAB', '\xA6', /* ત ન ઋ ઌ છ ટ ર ૦ */ + '\0', + '\xE0', '\xAA', '\x96', ' ', '\xE0', '\xAA', '\x97', ' ', '\xE0', '\xAA', '\x98', ' ', '\xE0', '\xAA', '\x9E', ' ', '\xE0', '\xAA', '\x87', ' ', '\xE0', '\xAA', '\x88', ' ', '\xE0', '\xAA', '\xA0', ' ', '\xE0', '\xAA', '\x9C', /* ખ ગ ઘ ઞ ઇ ઈ ઠ જ */ + '\0', + '\xE0', '\xAA', '\x88', ' ', '\xE0', '\xAA', '\x8A', ' ', '\xE0', '\xAA', '\xBF', ' ', '\xE0', '\xAB', '\x80', ' ', '\xE0', '\xAA', '\xB2', '\xE0', '\xAB', '\x80', ' ', '\xE0', '\xAA', '\xB6', '\xE0', '\xAB', '\x8D', '\xE0', '\xAA', '\x9A', '\xE0', '\xAA', '\xBF', ' ', '\xE0', '\xAA', '\x9C', '\xE0', '\xAA', '\xBF', ' ', '\xE0', '\xAA', '\xB8', '\xE0', '\xAB', '\x80', /* ઈ ઊ િ ી લી શ્ચિ જિ સી */ + '\0', + '\xE0', '\xAB', '\x81', ' ', '\xE0', '\xAB', '\x83', ' ', '\xE0', '\xAB', '\x84', ' ', '\xE0', '\xAA', '\x96', '\xE0', '\xAB', '\x81', ' ', '\xE0', '\xAA', '\x9B', '\xE0', '\xAB', '\x83', ' ', '\xE0', '\xAA', '\x9B', '\xE0', '\xAB', '\x84', /* ુ ૃ ૄ ખુ છૃ છૄ */ + '\0', + '\xE0', '\xAB', '\xA6', ' ', '\xE0', '\xAB', '\xA7', ' ', '\xE0', '\xAB', '\xA8', ' ', '\xE0', '\xAB', '\xA9', ' ', '\xE0', '\xAB', '\xAD', /* ૦ ૧ ૨ ૩ ૭ */ + '\0', + '\xE0', '\xA8', '\x95', ' ', '\xE0', '\xA8', '\x97', ' ', '\xE0', '\xA8', '\x99', ' ', '\xE0', '\xA8', '\x9A', ' ', '\xE0', '\xA8', '\x9C', ' ', '\xE0', '\xA8', '\xA4', ' ', '\xE0', '\xA8', '\xA7', ' ', '\xE0', '\xA8', '\xB8', /* ਕ ਗ ਙ ਚ ਜ ਤ ਧ ਸ */ + '\0', + '\xE0', '\xA8', '\x95', ' ', '\xE0', '\xA8', '\x97', ' ', '\xE0', '\xA8', '\x99', ' ', '\xE0', '\xA8', '\x9A', ' ', '\xE0', '\xA8', '\x9C', ' ', '\xE0', '\xA8', '\xA4', ' ', '\xE0', '\xA8', '\xA7', ' ', '\xE0', '\xA8', '\xB8', /* ਕ ਗ ਙ ਚ ਜ ਤ ਧ ਸ */ + '\0', + '\xE0', '\xA8', '\x87', ' ', '\xE0', '\xA8', '\x88', ' ', '\xE0', '\xA8', '\x89', ' ', '\xE0', '\xA8', '\x8F', ' ', '\xE0', '\xA8', '\x93', ' ', '\xE0', '\xA9', '\xB3', ' ', '\xE0', '\xA8', '\xBF', ' ', '\xE0', '\xA9', '\x80', /* ਇ ਈ ਉ ਏ ਓ ੳ ਿ ੀ */ + '\0', + '\xE0', '\xA8', '\x85', ' ', '\xE0', '\xA8', '\x8F', ' ', '\xE0', '\xA8', '\x93', ' ', '\xE0', '\xA8', '\x97', ' ', '\xE0', '\xA8', '\x9C', ' ', '\xE0', '\xA8', '\xA0', ' ', '\xE0', '\xA8', '\xB0', ' ', '\xE0', '\xA8', '\xB8', /* ਅ ਏ ਓ ਗ ਜ ਠ ਰ ਸ */ + '\0', + '\xE0', '\xA9', '\xA6', ' ', '\xE0', '\xA9', '\xA7', ' ', '\xE0', '\xA9', '\xA8', ' ', '\xE0', '\xA9', '\xA9', ' ', '\xE0', '\xA9', '\xAD', /* ੦ ੧ ੨ ੩ ੭ */ + '\0', + '\xD7', '\x91', ' ', '\xD7', '\x93', ' ', '\xD7', '\x94', ' ', '\xD7', '\x97', ' ', '\xD7', '\x9A', ' ', '\xD7', '\x9B', ' ', '\xD7', '\x9D', ' ', '\xD7', '\xA1', /* ב ד ה ח ך כ ם ס */ + '\0', + '\xD7', '\x91', ' ', '\xD7', '\x98', ' ', '\xD7', '\x9B', ' ', '\xD7', '\x9D', ' ', '\xD7', '\xA1', ' ', '\xD7', '\xA6', /* ב ט כ ם ס צ */ + '\0', + '\xD7', '\xA7', ' ', '\xD7', '\x9A', ' ', '\xD7', '\x9F', ' ', '\xD7', '\xA3', ' ', '\xD7', '\xA5', /* ק ך ן ף ץ */ + '\0', + '\xE0', '\xB2', '\x87', ' ', '\xE0', '\xB2', '\x8A', ' ', '\xE0', '\xB2', '\x90', ' ', '\xE0', '\xB2', '\xA3', ' ', '\xE0', '\xB2', '\xB8', '\xE0', '\xB2', '\xBE', ' ', '\xE0', '\xB2', '\xA8', '\xE0', '\xB2', '\xBE', ' ', '\xE0', '\xB2', '\xA6', '\xE0', '\xB2', '\xBE', ' ', '\xE0', '\xB2', '\xB0', '\xE0', '\xB2', '\xBE', /* ಇ ಊ ಐ ಣ ಸಾ ನಾ ದಾ ರಾ */ + '\0', + '\xE0', '\xB2', '\x85', ' ', '\xE0', '\xB2', '\x89', ' ', '\xE0', '\xB2', '\x8E', ' ', '\xE0', '\xB2', '\xB2', ' ', '\xE0', '\xB3', '\xA6', ' ', '\xE0', '\xB3', '\xA8', ' ', '\xE0', '\xB3', '\xAC', ' ', '\xE0', '\xB3', '\xAD', /* ಅ ಉ ಎ ಲ ೦ ೨ ೬ ೭ */ + '\0', + '\xEA', '\xA4', '\x85', ' ', '\xEA', '\xA4', '\x8F', ' ', '\xEA', '\xA4', '\x81', ' ', '\xEA', '\xA4', '\x8B', ' ', '\xEA', '\xA4', '\x80', ' ', '\xEA', '\xA4', '\x8D', /* ꤅ ꤏ ꤁ ꤋ ꤀ ꤍ */ + '\0', + '\xEA', '\xA4', '\x88', ' ', '\xEA', '\xA4', '\x98', ' ', '\xEA', '\xA4', '\x80', ' ', '\xEA', '\xA4', '\x8D', ' ', '\xEA', '\xA4', '\xA2', /* ꤈ ꤘ ꤀ ꤍ ꤢ */ + '\0', + '\xEA', '\xA4', '\x96', ' ', '\xEA', '\xA4', '\xA1', /* ꤖ ꤡ */ + '\0', + '\xEA', '\xA4', '\x91', ' ', '\xEA', '\xA4', '\x9C', ' ', '\xEA', '\xA4', '\x9E', /* ꤑ ꤜ ꤞ */ + '\0', + '\xEA', '\xA4', '\x91', '\xEA', '\xA4', '\xAC', ' ', '\xEA', '\xA4', '\x9C', '\xEA', '\xA4', '\xAD', ' ', '\xEA', '\xA4', '\x94', '\xEA', '\xA4', '\xAC', /* ꤑ꤬ ꤜ꤭ ꤔ꤬ */ + '\0', + '\xE1', '\x9E', '\x81', ' ', '\xE1', '\x9E', '\x91', ' ', '\xE1', '\x9E', '\x93', ' ', '\xE1', '\x9E', '\xA7', ' ', '\xE1', '\x9E', '\xA9', ' ', '\xE1', '\x9E', '\xB6', /* ខ ទ ន ឧ ឩ ា */ + '\0', + '\xE1', '\x9E', '\x80', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x80', ' ', '\xE1', '\x9E', '\x80', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x81', ' ', '\xE1', '\x9E', '\x80', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x82', ' ', '\xE1', '\x9E', '\x80', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x90', /* ក្ក ក្ខ ក្គ ក្ថ */ + '\0', + '\xE1', '\x9E', '\x81', ' ', '\xE1', '\x9E', '\x83', ' ', '\xE1', '\x9E', '\x85', ' ', '\xE1', '\x9E', '\x8B', ' ', '\xE1', '\x9E', '\x94', ' ', '\xE1', '\x9E', '\x98', ' ', '\xE1', '\x9E', '\x99', ' ', '\xE1', '\x9E', '\xB2', /* ខ ឃ ច ឋ ប ម យ ឲ */ + '\0', + '\xE1', '\x9E', '\x8F', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x9A', ' ', '\xE1', '\x9E', '\x9A', '\xE1', '\x9F', '\x80', ' ', '\xE1', '\x9E', '\xB2', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x99', ' ', '\xE1', '\x9E', '\xA2', '\xE1', '\x9E', '\xBF', /* ត្រ រៀ ឲ្យ អឿ */ + '\0', + '\xE1', '\x9E', '\x93', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x8F', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x9A', '\xE1', '\x9F', '\x83', ' ', '\xE1', '\x9E', '\x84', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x81', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x99', ' ', '\xE1', '\x9E', '\x80', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x94', '\xE1', '\x9F', '\x80', ' ', '\xE1', '\x9E', '\x85', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x9A', '\xE1', '\x9F', '\x80', ' ', '\xE1', '\x9E', '\x93', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x8F', '\xE1', '\x9E', '\xBF', ' ', '\xE1', '\x9E', '\x9B', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x94', '\xE1', '\x9E', '\xBF', /* ន្ត្រៃ ង្ខ្យ ក្បៀ ច្រៀ ន្តឿ ល្បឿ */ + '\0', + '\xE1', '\xA7', '\xA0', ' ', '\xE1', '\xA7', '\xA1', /* ᧠ ᧡ */ + '\0', + '\xE1', '\xA7', '\xB6', ' ', '\xE1', '\xA7', '\xB9', /* ᧶ ᧹ */ + '\0', + '\xE0', '\xBA', '\xB2', ' ', '\xE0', '\xBA', '\x94', ' ', '\xE0', '\xBA', '\xAD', ' ', '\xE0', '\xBA', '\xA1', ' ', '\xE0', '\xBA', '\xA5', ' ', '\xE0', '\xBA', '\xA7', ' ', '\xE0', '\xBA', '\xA3', ' ', '\xE0', '\xBA', '\x87', /* າ ດ ອ ມ ລ ວ ຣ ງ */ + '\0', + '\xE0', '\xBA', '\xB2', ' ', '\xE0', '\xBA', '\xAD', ' ', '\xE0', '\xBA', '\x9A', ' ', '\xE0', '\xBA', '\x8D', ' ', '\xE0', '\xBA', '\xA3', ' ', '\xE0', '\xBA', '\xAE', ' ', '\xE0', '\xBA', '\xA7', ' ', '\xE0', '\xBA', '\xA2', /* າ ອ ບ ຍ ຣ ຮ ວ ຢ */ + '\0', + '\xE0', '\xBA', '\x9B', ' ', '\xE0', '\xBA', '\xA2', ' ', '\xE0', '\xBA', '\x9F', ' ', '\xE0', '\xBA', '\x9D', /* ປ ຢ ຟ ຝ */ + '\0', + '\xE0', '\xBB', '\x82', ' ', '\xE0', '\xBB', '\x84', ' ', '\xE0', '\xBB', '\x83', /* ໂ ໄ ໃ */ + '\0', + '\xE0', '\xBA', '\x87', ' ', '\xE0', '\xBA', '\x8A', ' ', '\xE0', '\xBA', '\x96', ' ', '\xE0', '\xBA', '\xBD', ' ', '\xE0', '\xBB', '\x86', ' ', '\xE0', '\xBA', '\xAF', /* ງ ຊ ຖ ຽ ໆ ຯ */ + '\0', + 'T', ' ', 'H', ' ', 'E', ' ', 'Z', ' ', 'O', ' ', 'C', ' ', 'Q', ' ', 'S', /* T H E Z O C Q S */ + '\0', + 'H', ' ', 'E', ' ', 'Z', ' ', 'L', ' ', 'O', ' ', 'C', ' ', 'U', ' ', 'S', /* H E Z L O C U S */ + '\0', + 'f', ' ', 'i', ' ', 'j', ' ', 'k', ' ', 'd', ' ', 'b', ' ', 'h', /* f i j k d b h */ + '\0', + 'u', ' ', 'v', ' ', 'x', ' ', 'z', ' ', 'o', ' ', 'e', ' ', 's', ' ', 'c', /* u v x z o e s c */ + '\0', + 'n', ' ', 'r', ' ', 'x', ' ', 'z', ' ', 'o', ' ', 'e', ' ', 's', ' ', 'c', /* n r x z o e s c */ + '\0', + 'p', ' ', 'q', ' ', 'g', ' ', 'j', ' ', 'y', /* p q g j y */ + '\0', + '\xE2', '\x82', '\x80', ' ', '\xE2', '\x82', '\x83', ' ', '\xE2', '\x82', '\x85', ' ', '\xE2', '\x82', '\x87', ' ', '\xE2', '\x82', '\x88', /* ₀ ₃ ₅ ₇ ₈ */ + '\0', + '\xE2', '\x82', '\x80', ' ', '\xE2', '\x82', '\x81', ' ', '\xE2', '\x82', '\x82', ' ', '\xE2', '\x82', '\x83', ' ', '\xE2', '\x82', '\x88', /* ₀ ₁ ₂ ₃ ₈ */ + '\0', + '\xE1', '\xB5', '\xA2', ' ', '\xE2', '\xB1', '\xBC', ' ', '\xE2', '\x82', '\x95', ' ', '\xE2', '\x82', '\x96', ' ', '\xE2', '\x82', '\x97', /* ᵢ ⱼ ₕ ₖ ₗ */ + '\0', + '\xE2', '\x82', '\x90', ' ', '\xE2', '\x82', '\x91', ' ', '\xE2', '\x82', '\x92', ' ', '\xE2', '\x82', '\x93', ' ', '\xE2', '\x82', '\x99', ' ', '\xE2', '\x82', '\x9B', ' ', '\xE1', '\xB5', '\xA5', ' ', '\xE1', '\xB5', '\xA4', ' ', '\xE1', '\xB5', '\xA3', /* ₐ ₑ ₒ ₓ ₙ ₛ ᵥ ᵤ ᵣ */ + '\0', + '\xE1', '\xB5', '\xA6', ' ', '\xE1', '\xB5', '\xA7', ' ', '\xE1', '\xB5', '\xA8', ' ', '\xE1', '\xB5', '\xA9', ' ', '\xE2', '\x82', '\x9A', /* ᵦ ᵧ ᵨ ᵩ ₚ */ + '\0', + '\xE2', '\x81', '\xB0', ' ', '\xC2', '\xB3', ' ', '\xE2', '\x81', '\xB5', ' ', '\xE2', '\x81', '\xB7', ' ', '\xE1', '\xB5', '\x80', ' ', '\xE1', '\xB4', '\xB4', ' ', '\xE1', '\xB4', '\xB1', ' ', '\xE1', '\xB4', '\xBC', /* ⁰ ³ ⁵ ⁷ ᵀ ᴴ ᴱ ᴼ */ + '\0', + '\xE2', '\x81', '\xB0', ' ', '\xC2', '\xB9', ' ', '\xC2', '\xB2', ' ', '\xC2', '\xB3', ' ', '\xE1', '\xB4', '\xB1', ' ', '\xE1', '\xB4', '\xB8', ' ', '\xE1', '\xB4', '\xBC', ' ', '\xE1', '\xB5', '\x81', /* ⁰ ¹ ² ³ ᴱ ᴸ ᴼ ᵁ */ + '\0', + '\xE1', '\xB5', '\x87', ' ', '\xE1', '\xB5', '\x88', ' ', '\xE1', '\xB5', '\x8F', ' ', '\xCA', '\xB0', ' ', '\xCA', '\xB2', ' ', '\xE1', '\xB6', '\xA0', ' ', '\xE2', '\x81', '\xB1', /* ᵇ ᵈ ᵏ ʰ ʲ ᶠ ⁱ */ + '\0', + '\xE1', '\xB5', '\x89', ' ', '\xE1', '\xB5', '\x92', ' ', '\xCA', '\xB3', ' ', '\xCB', '\xA2', ' ', '\xCB', '\xA3', ' ', '\xE1', '\xB6', '\x9C', ' ', '\xE1', '\xB6', '\xBB', /* ᵉ ᵒ ʳ ˢ ˣ ᶜ ᶻ */ + '\0', + '\xE1', '\xB5', '\x96', ' ', '\xCA', '\xB8', ' ', '\xE1', '\xB5', '\x8D', /* ᵖ ʸ ᵍ */ + '\0', + '\xEA', '\x93', '\xA1', ' ', '\xEA', '\x93', '\xA7', ' ', '\xEA', '\x93', '\xB1', ' ', '\xEA', '\x93', '\xB6', ' ', '\xEA', '\x93', '\xA9', ' ', '\xEA', '\x93', '\x9A', ' ', '\xEA', '\x93', '\xB5', ' ', '\xEA', '\x93', '\xB3', /* ꓡ ꓧ ꓱ ꓶ ꓩ ꓚ ꓵ ꓳ */ + '\0', + '\xEA', '\x93', '\x95', ' ', '\xEA', '\x93', '\x9C', ' ', '\xEA', '\x93', '\x9E', ' ', '\xEA', '\x93', '\xA1', ' ', '\xEA', '\x93', '\x9B', ' ', '\xEA', '\x93', '\xA2', ' ', '\xEA', '\x93', '\xB3', ' ', '\xEA', '\x93', '\xB4', /* ꓕ ꓜ ꓞ ꓡ ꓛ ꓢ ꓳ ꓴ */ + '\0', + '\xE0', '\xB4', '\x92', ' ', '\xE0', '\xB4', '\x9F', ' ', '\xE0', '\xB4', '\xA0', ' ', '\xE0', '\xB4', '\xB1', ' ', '\xE0', '\xB4', '\x9A', ' ', '\xE0', '\xB4', '\xAA', ' ', '\xE0', '\xB4', '\x9A', '\xE0', '\xB5', '\x8D', '\xE0', '\xB4', '\x9A', ' ', '\xE0', '\xB4', '\xAA', '\xE0', '\xB5', '\x8D', '\xE0', '\xB4', '\xAA', /* ഒ ട ഠ റ ച പ ച്ച പ്പ */ + '\0', + '\xE0', '\xB4', '\x9F', ' ', '\xE0', '\xB4', '\xA0', ' ', '\xE0', '\xB4', '\xA7', ' ', '\xE0', '\xB4', '\xB6', ' ', '\xE0', '\xB4', '\x98', ' ', '\xE0', '\xB4', '\x9A', ' ', '\xE0', '\xB4', '\xA5', ' ', '\xE0', '\xB4', '\xB2', /* ട ഠ ധ ശ ഘ ച ഥ ല */ + '\0', + '\xE1', '\x80', '\x81', ' ', '\xE1', '\x80', '\x82', ' ', '\xE1', '\x80', '\x84', ' ', '\xE1', '\x80', '\x92', ' ', '\xE1', '\x80', '\x9D', ' ', '\xE1', '\x81', '\xA5', ' ', '\xE1', '\x81', '\x8A', ' ', '\xE1', '\x81', '\x8B', /* ခ ဂ င ဒ ဝ ၥ ၊ ။ */ + '\0', + '\xE1', '\x80', '\x84', ' ', '\xE1', '\x80', '\x8E', ' ', '\xE1', '\x80', '\x92', ' ', '\xE1', '\x80', '\x95', ' ', '\xE1', '\x80', '\x97', ' ', '\xE1', '\x80', '\x9D', ' ', '\xE1', '\x81', '\x8A', ' ', '\xE1', '\x81', '\x8B', /* င ဎ ဒ ပ ဗ ဝ ၊ ။ */ + '\0', + '\xE1', '\x80', '\xA9', ' ', '\xE1', '\x80', '\xBC', ' ', '\xE1', '\x81', '\x8D', ' ', '\xE1', '\x81', '\x8F', ' ', '\xE1', '\x81', '\x86', ' ', '\xE1', '\x80', '\xAB', ' ', '\xE1', '\x80', '\xAD', /* ဩ ြ ၍ ၏ ၆ ါ ိ */ + '\0', + '\xE1', '\x80', '\x89', ' ', '\xE1', '\x80', '\x8A', ' ', '\xE1', '\x80', '\xA5', ' ', '\xE1', '\x80', '\xA9', ' ', '\xE1', '\x80', '\xA8', ' ', '\xE1', '\x81', '\x82', ' ', '\xE1', '\x81', '\x85', ' ', '\xE1', '\x81', '\x89', /* ဉ ည ဥ ဩ ဨ ၂ ၅ ၉ */ + '\0', + '\xDF', '\x90', ' ', '\xDF', '\x89', ' ', '\xDF', '\x92', ' ', '\xDF', '\x9F', ' ', '\xDF', '\x96', ' ', '\xDF', '\x9C', ' ', '\xDF', '\xA0', ' ', '\xDF', '\xA5', /* ߐ ߉ ߒ ߟ ߖ ߜ ߠ ߥ */ + '\0', + '\xDF', '\x80', ' ', '\xDF', '\x98', ' ', '\xDF', '\xA1', ' ', '\xDF', '\xA0', ' ', '\xDF', '\xA5', /* ߀ ߘ ߡ ߠ ߥ */ + '\0', + '\xDF', '\x8F', ' ', '\xDF', '\x9B', ' ', '\xDF', '\x8B', /* ߏ ߛ ߋ */ + '\0', + '\xDF', '\x8E', ' ', '\xDF', '\x8F', ' ', '\xDF', '\x9B', ' ', '\xDF', '\x8B', /* ߎ ߏ ߛ ߋ */ + '\0', + '\xE1', '\xB1', '\x9B', ' ', '\xE1', '\xB1', '\x9C', ' ', '\xE1', '\xB1', '\x9D', ' ', '\xE1', '\xB1', '\xA1', ' ', '\xE1', '\xB1', '\xA2', ' ', '\xE1', '\xB1', '\xA5', /* ᱛ ᱜ ᱝ ᱡ ᱢ ᱥ */ + '\0', + '\xF0', '\x90', '\xB0', '\x97', ' ', '\xF0', '\x90', '\xB0', '\x98', ' ', '\xF0', '\x90', '\xB0', '\xA7', /* 𐰗 𐰘 𐰧 */ + '\0', + '\xF0', '\x90', '\xB0', '\x89', ' ', '\xF0', '\x90', '\xB0', '\x97', ' ', '\xF0', '\x90', '\xB0', '\xA6', ' ', '\xF0', '\x90', '\xB0', '\xA7', /* 𐰉 𐰗 𐰦 𐰧 */ + '\0', + '\xF0', '\x90', '\x92', '\xBE', ' ', '\xF0', '\x90', '\x93', '\x8D', ' ', '\xF0', '\x90', '\x93', '\x92', ' ', '\xF0', '\x90', '\x93', '\x93', ' ', '\xF0', '\x90', '\x92', '\xBB', ' ', '\xF0', '\x90', '\x93', '\x82', ' ', '\xF0', '\x90', '\x92', '\xB5', ' ', '\xF0', '\x90', '\x93', '\x86', /* 𐒾 𐓍 𐓒 𐓓 𐒻 𐓂 𐒵 𐓆 */ + '\0', + '\xF0', '\x90', '\x92', '\xB0', ' ', '\xF0', '\x90', '\x93', '\x8D', ' ', '\xF0', '\x90', '\x93', '\x82', ' ', '\xF0', '\x90', '\x92', '\xBF', ' ', '\xF0', '\x90', '\x93', '\x8E', ' ', '\xF0', '\x90', '\x92', '\xB9', /* 𐒰 𐓍 𐓂 𐒿 𐓎 𐒹 */ + '\0', + '\xF0', '\x90', '\x92', '\xBC', ' ', '\xF0', '\x90', '\x92', '\xBD', ' ', '\xF0', '\x90', '\x92', '\xBE', /* 𐒼 𐒽 𐒾 */ + '\0', + '\xF0', '\x90', '\x93', '\xB5', ' ', '\xF0', '\x90', '\x93', '\xB6', ' ', '\xF0', '\x90', '\x93', '\xBA', ' ', '\xF0', '\x90', '\x93', '\xBB', ' ', '\xF0', '\x90', '\x93', '\x9D', ' ', '\xF0', '\x90', '\x93', '\xA3', ' ', '\xF0', '\x90', '\x93', '\xAA', ' ', '\xF0', '\x90', '\x93', '\xAE', /* 𐓵 𐓶 𐓺 𐓻 𐓝 𐓣 𐓪 𐓮 */ + '\0', + '\xF0', '\x90', '\x93', '\x98', ' ', '\xF0', '\x90', '\x93', '\x9A', ' ', '\xF0', '\x90', '\x93', '\xA3', ' ', '\xF0', '\x90', '\x93', '\xB5', ' ', '\xF0', '\x90', '\x93', '\xA1', ' ', '\xF0', '\x90', '\x93', '\xA7', ' ', '\xF0', '\x90', '\x93', '\xAA', ' ', '\xF0', '\x90', '\x93', '\xB6', /* 𐓘 𐓚 𐓣 𐓵 𐓡 𐓧 𐓪 𐓶 */ + '\0', + '\xF0', '\x90', '\x93', '\xA4', ' ', '\xF0', '\x90', '\x93', '\xA6', ' ', '\xF0', '\x90', '\x93', '\xB8', ' ', '\xF0', '\x90', '\x93', '\xB9', ' ', '\xF0', '\x90', '\x93', '\x9B', /* 𐓤 𐓦 𐓸 𐓹 𐓛 */ + '\0', + '\xF0', '\x90', '\x93', '\xA4', ' ', '\xF0', '\x90', '\x93', '\xA5', ' ', '\xF0', '\x90', '\x93', '\xA6', /* 𐓤 𐓥 𐓦 */ + '\0', + '\xF0', '\x90', '\x92', '\x86', ' ', '\xF0', '\x90', '\x92', '\x89', ' ', '\xF0', '\x90', '\x92', '\x90', ' ', '\xF0', '\x90', '\x92', '\x92', ' ', '\xF0', '\x90', '\x92', '\x98', ' ', '\xF0', '\x90', '\x92', '\x9B', ' ', '\xF0', '\x90', '\x92', '\xA0', ' ', '\xF0', '\x90', '\x92', '\xA3', /* 𐒆 𐒉 𐒐 𐒒 𐒘 𐒛 𐒠 𐒣 */ + '\0', + '\xF0', '\x90', '\x92', '\x80', ' ', '\xF0', '\x90', '\x92', '\x82', ' ', '\xF0', '\x90', '\x92', '\x86', ' ', '\xF0', '\x90', '\x92', '\x88', ' ', '\xF0', '\x90', '\x92', '\x8A', ' ', '\xF0', '\x90', '\x92', '\x92', ' ', '\xF0', '\x90', '\x92', '\xA0', ' ', '\xF0', '\x90', '\x92', '\xA9', /* 𐒀 𐒂 𐒆 𐒈 𐒊 𐒒 𐒠 𐒩 */ + '\0', + '\xEA', '\xA2', '\x9C', ' ', '\xEA', '\xA2', '\x9E', ' ', '\xEA', '\xA2', '\xB3', ' ', '\xEA', '\xA2', '\x82', ' ', '\xEA', '\xA2', '\x96', ' ', '\xEA', '\xA2', '\x92', ' ', '\xEA', '\xA2', '\x9D', ' ', '\xEA', '\xA2', '\x9B', /* ꢜ ꢞ ꢳ ꢂ ꢖ ꢒ ꢝ ꢛ */ + '\0', + '\xEA', '\xA2', '\x82', ' ', '\xEA', '\xA2', '\xA8', ' ', '\xEA', '\xA2', '\xBA', ' ', '\xEA', '\xA2', '\xA4', ' ', '\xEA', '\xA2', '\x8E', /* ꢂ ꢨ ꢺ ꢤ ꢎ */ + '\0', + '\xF0', '\x90', '\x91', '\x95', ' ', '\xF0', '\x90', '\x91', '\x99', /* 𐑕 𐑙 */ + '\0', + '\xF0', '\x90', '\x91', '\x94', ' ', '\xF0', '\x90', '\x91', '\x96', ' ', '\xF0', '\x90', '\x91', '\x97', ' ', '\xF0', '\x90', '\x91', '\xB9', ' ', '\xF0', '\x90', '\x91', '\xBB', /* 𐑔 𐑖 𐑗 𐑹 𐑻 */ + '\0', + '\xF0', '\x90', '\x91', '\x9F', ' ', '\xF0', '\x90', '\x91', '\xA3', /* 𐑟 𐑣 */ + '\0', + '\xF0', '\x90', '\x91', '\xB1', ' ', '\xF0', '\x90', '\x91', '\xB2', ' ', '\xF0', '\x90', '\x91', '\xB3', ' ', '\xF0', '\x90', '\x91', '\xB4', ' ', '\xF0', '\x90', '\x91', '\xB8', ' ', '\xF0', '\x90', '\x91', '\xBA', ' ', '\xF0', '\x90', '\x91', '\xBC', /* 𐑱 𐑲 𐑳 𐑴 𐑸 𐑺 𐑼 */ + '\0', + '\xF0', '\x90', '\x91', '\xB4', ' ', '\xF0', '\x90', '\x91', '\xBB', ' ', '\xF0', '\x90', '\x91', '\xB9', /* 𐑴 𐑻 𐑹 */ + '\0', + '\xE0', '\xB6', '\x89', ' ', '\xE0', '\xB6', '\x9A', ' ', '\xE0', '\xB6', '\x9D', ' ', '\xE0', '\xB6', '\xB3', ' ', '\xE0', '\xB6', '\xB4', ' ', '\xE0', '\xB6', '\xBA', ' ', '\xE0', '\xB6', '\xBD', ' ', '\xE0', '\xB7', '\x86', /* ඉ ක ඝ ඳ ප ය ල ෆ */ + '\0', + '\xE0', '\xB6', '\x91', ' ', '\xE0', '\xB6', '\x94', ' ', '\xE0', '\xB6', '\x9D', ' ', '\xE0', '\xB6', '\xA2', ' ', '\xE0', '\xB6', '\xA7', ' ', '\xE0', '\xB6', '\xAE', ' ', '\xE0', '\xB6', '\xB0', ' ', '\xE0', '\xB6', '\xBB', /* එ ඔ ඝ ජ ට ථ ධ ර */ + '\0', + '\xE0', '\xB6', '\xAF', ' ', '\xE0', '\xB6', '\xB3', ' ', '\xE0', '\xB6', '\x8B', ' ', '\xE0', '\xB6', '\xBD', ' ', '\xE0', '\xB6', '\xAD', '\xE0', '\xB7', '\x96', ' ', '\xE0', '\xB6', '\xAD', '\xE0', '\xB7', '\x94', ' ', '\xE0', '\xB6', '\xB6', '\xE0', '\xB7', '\x94', ' ', '\xE0', '\xB6', '\xAF', '\xE0', '\xB7', '\x94', /* ද ඳ උ ල තූ තු බු දු */ + '\0', + '\xE1', '\xAE', '\x8B', ' ', '\xE1', '\xAE', '\x9E', ' ', '\xE1', '\xAE', '\xAE', ' ', '\xE1', '\xAE', '\xBD', ' ', '\xE1', '\xAE', '\xB0', ' ', '\xE1', '\xAE', '\x88', /* ᮋ ᮞ ᮮ ᮽ ᮰ ᮈ */ + '\0', + '\xE1', '\xAE', '\x84', ' ', '\xE1', '\xAE', '\x94', ' ', '\xE1', '\xAE', '\x95', ' ', '\xE1', '\xAE', '\x97', ' ', '\xE1', '\xAE', '\xB0', ' ', '\xE1', '\xAE', '\x86', ' ', '\xE1', '\xAE', '\x88', ' ', '\xE1', '\xAE', '\x89', /* ᮄ ᮔ ᮕ ᮗ ᮰ ᮆ ᮈ ᮉ */ + '\0', + '\xE1', '\xAE', '\xBC', ' ', '\xE1', '\xB3', '\x84', /* ᮼ ᳄ */ + '\0', + '\xEA', '\xAA', '\x86', ' ', '\xEA', '\xAA', '\x94', ' ', '\xEA', '\xAA', '\x92', ' ', '\xEA', '\xAA', '\x96', ' ', '\xEA', '\xAA', '\xAB', /* ꪆ ꪔ ꪒ ꪖ ꪫ */ + '\0', + '\xEA', '\xAA', '\x89', ' ', '\xEA', '\xAA', '\xAB', ' ', '\xEA', '\xAA', '\xAE', /* ꪉ ꪫ ꪮ */ + '\0', + '\xE0', '\xAE', '\x89', ' ', '\xE0', '\xAE', '\x92', ' ', '\xE0', '\xAE', '\x93', ' ', '\xE0', '\xAE', '\xB1', ' ', '\xE0', '\xAE', '\x88', ' ', '\xE0', '\xAE', '\x95', ' ', '\xE0', '\xAE', '\x99', ' ', '\xE0', '\xAE', '\x9A', /* உ ஒ ஓ ற ஈ க ங ச */ + '\0', + '\xE0', '\xAE', '\x95', ' ', '\xE0', '\xAE', '\x9A', ' ', '\xE0', '\xAE', '\xB2', ' ', '\xE0', '\xAE', '\xB6', ' ', '\xE0', '\xAE', '\x89', ' ', '\xE0', '\xAE', '\x99', ' ', '\xE0', '\xAE', '\x9F', ' ', '\xE0', '\xAE', '\xAA', /* க ச ல ஶ உ ங ட ப */ + '\0', + '\xE0', '\xB0', '\x87', ' ', '\xE0', '\xB0', '\x8C', ' ', '\xE0', '\xB0', '\x99', ' ', '\xE0', '\xB0', '\x9E', ' ', '\xE0', '\xB0', '\xA3', ' ', '\xE0', '\xB0', '\xB1', ' ', '\xE0', '\xB1', '\xAF', /* ఇ ఌ ఙ ఞ ణ ఱ ౯ */ + '\0', + '\xE0', '\xB0', '\x85', ' ', '\xE0', '\xB0', '\x95', ' ', '\xE0', '\xB0', '\x9A', ' ', '\xE0', '\xB0', '\xB0', ' ', '\xE0', '\xB0', '\xBD', ' ', '\xE0', '\xB1', '\xA8', ' ', '\xE0', '\xB1', '\xAC', /* అ క చ ర ఽ ౨ ౬ */ + '\0', + '\xE0', '\xB8', '\x9A', ' ', '\xE0', '\xB9', '\x80', ' ', '\xE0', '\xB9', '\x81', ' ', '\xE0', '\xB8', '\xAD', ' ', '\xE0', '\xB8', '\x81', ' ', '\xE0', '\xB8', '\xB2', /* บ เ แ อ ก า */ + '\0', + '\xE0', '\xB8', '\x9A', ' ', '\xE0', '\xB8', '\x9B', ' ', '\xE0', '\xB8', '\xA9', ' ', '\xE0', '\xB8', '\xAF', ' ', '\xE0', '\xB8', '\xAD', ' ', '\xE0', '\xB8', '\xA2', ' ', '\xE0', '\xB8', '\xAE', /* บ ป ษ ฯ อ ย ฮ */ + '\0', + '\xE0', '\xB8', '\x9B', ' ', '\xE0', '\xB8', '\x9D', ' ', '\xE0', '\xB8', '\x9F', /* ป ฝ ฟ */ + '\0', + '\xE0', '\xB9', '\x82', ' ', '\xE0', '\xB9', '\x83', ' ', '\xE0', '\xB9', '\x84', /* โ ใ ไ */ + '\0', + '\xE0', '\xB8', '\x8E', ' ', '\xE0', '\xB8', '\x8F', ' ', '\xE0', '\xB8', '\xA4', ' ', '\xE0', '\xB8', '\xA6', /* ฎ ฏ ฤ ฦ */ + '\0', + '\xE0', '\xB8', '\x8D', ' ', '\xE0', '\xB8', '\x90', /* ญ ฐ */ + '\0', + '\xE0', '\xB9', '\x90', ' ', '\xE0', '\xB9', '\x91', ' ', '\xE0', '\xB9', '\x93', /* ๐ ๑ ๓ */ + '\0', + '\xE2', '\xB5', '\x94', ' ', '\xE2', '\xB5', '\x99', ' ', '\xE2', '\xB5', '\x9B', ' ', '\xE2', '\xB5', '\x9E', ' ', '\xE2', '\xB4', '\xB5', ' ', '\xE2', '\xB4', '\xBC', ' ', '\xE2', '\xB4', '\xB9', ' ', '\xE2', '\xB5', '\x8E', /* ⵔ ⵙ ⵛ ⵞ ⴵ ⴼ ⴹ ⵎ */ + '\0', + '\xEA', '\x97', '\x8D', ' ', '\xEA', '\x98', '\x96', ' ', '\xEA', '\x98', '\x99', ' ', '\xEA', '\x98', '\x9C', ' ', '\xEA', '\x96', '\x9C', ' ', '\xEA', '\x96', '\x9D', ' ', '\xEA', '\x94', '\x85', ' ', '\xEA', '\x95', '\xA2', /* ꗍ ꘖ ꘙ ꘜ ꖜ ꖝ ꔅ ꕢ */ + '\0', + '\xEA', '\x97', '\x8D', ' ', '\xEA', '\x98', '\x96', ' ', '\xEA', '\x98', '\x99', ' ', '\xEA', '\x97', '\x9E', ' ', '\xEA', '\x94', '\x85', ' ', '\xEA', '\x95', '\xA2', ' ', '\xEA', '\x96', '\x9C', ' ', '\xEA', '\x94', '\x86', /* ꗍ ꘖ ꘙ ꗞ ꔅ ꕢ ꖜ ꔆ */ #ifdef AF_CONFIG_OPTION_CJK '\0', - '\xE4', '\xBB', '\x96', '\xE4', '\xBB', '\xAC', '\xE4', '\xBD', '\xA0', '\xE4', '\xBE', '\x86', '\xE5', '\x80', '\x91', '\xE5', '\x88', '\xB0', '\xE5', '\x92', '\x8C', '\xE5', '\x9C', '\xB0', /* 他们你來們到和地 */ - '\xE5', '\xAF', '\xB9', '\xE5', '\xB0', '\x8D', '\xE5', '\xB0', '\xB1', '\xE5', '\xB8', '\xAD', '\xE6', '\x88', '\x91', '\xE6', '\x97', '\xB6', '\xE6', '\x99', '\x82', '\xE6', '\x9C', '\x83', /* 对對就席我时時會 */ - '\xE6', '\x9D', '\xA5', '\xE7', '\x82', '\xBA', '\xE8', '\x83', '\xBD', '\xE8', '\x88', '\xB0', '\xE8', '\xAA', '\xAA', '\xE8', '\xAF', '\xB4', '\xE8', '\xBF', '\x99', '\xE9', '\x80', '\x99', /* 来為能舰說说这這 */ - '\xE9', '\xBD', '\x8A', '|', /* 齊 | */ - '\xE5', '\x86', '\x9B', '\xE5', '\x90', '\x8C', '\xE5', '\xB7', '\xB2', '\xE6', '\x84', '\xBF', '\xE6', '\x97', '\xA2', '\xE6', '\x98', '\x9F', '\xE6', '\x98', '\xAF', '\xE6', '\x99', '\xAF', /* 军同已愿既星是景 */ - '\xE6', '\xB0', '\x91', '\xE7', '\x85', '\xA7', '\xE7', '\x8E', '\xB0', '\xE7', '\x8F', '\xBE', '\xE7', '\x90', '\x86', '\xE7', '\x94', '\xA8', '\xE7', '\xBD', '\xAE', '\xE8', '\xA6', '\x81', /* 民照现現理用置要 */ - '\xE8', '\xBB', '\x8D', '\xE9', '\x82', '\xA3', '\xE9', '\x85', '\x8D', '\xE9', '\x87', '\x8C', '\xE9', '\x96', '\x8B', '\xE9', '\x9B', '\xB7', '\xE9', '\x9C', '\xB2', '\xE9', '\x9D', '\xA2', /* 軍那配里開雷露面 */ - '\xE9', '\xA1', '\xBE', /* 顾 */ + '\xE4', '\xBB', '\x96', ' ', '\xE4', '\xBB', '\xAC', ' ', '\xE4', '\xBD', '\xA0', ' ', '\xE4', '\xBE', '\x86', ' ', '\xE5', '\x80', '\x91', ' ', '\xE5', '\x88', '\xB0', ' ', '\xE5', '\x92', '\x8C', ' ', '\xE5', '\x9C', '\xB0', /* 他 们 你 來 們 到 和 地 */ + ' ', '\xE5', '\xAF', '\xB9', ' ', '\xE5', '\xB0', '\x8D', ' ', '\xE5', '\xB0', '\xB1', ' ', '\xE5', '\xB8', '\xAD', ' ', '\xE6', '\x88', '\x91', ' ', '\xE6', '\x97', '\xB6', ' ', '\xE6', '\x99', '\x82', ' ', '\xE6', '\x9C', '\x83', /* 对 對 就 席 我 时 時 會 */ + ' ', '\xE6', '\x9D', '\xA5', ' ', '\xE7', '\x82', '\xBA', ' ', '\xE8', '\x83', '\xBD', ' ', '\xE8', '\x88', '\xB0', ' ', '\xE8', '\xAA', '\xAA', ' ', '\xE8', '\xAF', '\xB4', ' ', '\xE8', '\xBF', '\x99', ' ', '\xE9', '\x80', '\x99', /* 来 為 能 舰 說 说 这 這 */ + ' ', '\xE9', '\xBD', '\x8A', ' ', '|', /* 齊 | */ + ' ', '\xE5', '\x86', '\x9B', ' ', '\xE5', '\x90', '\x8C', ' ', '\xE5', '\xB7', '\xB2', ' ', '\xE6', '\x84', '\xBF', ' ', '\xE6', '\x97', '\xA2', ' ', '\xE6', '\x98', '\x9F', ' ', '\xE6', '\x98', '\xAF', ' ', '\xE6', '\x99', '\xAF', /* 军 同 已 愿 既 星 是 景 */ + ' ', '\xE6', '\xB0', '\x91', ' ', '\xE7', '\x85', '\xA7', ' ', '\xE7', '\x8E', '\xB0', ' ', '\xE7', '\x8F', '\xBE', ' ', '\xE7', '\x90', '\x86', ' ', '\xE7', '\x94', '\xA8', ' ', '\xE7', '\xBD', '\xAE', ' ', '\xE8', '\xA6', '\x81', /* 民 照 现 現 理 用 置 要 */ + ' ', '\xE8', '\xBB', '\x8D', ' ', '\xE9', '\x82', '\xA3', ' ', '\xE9', '\x85', '\x8D', ' ', '\xE9', '\x87', '\x8C', ' ', '\xE9', '\x96', '\x8B', ' ', '\xE9', '\x9B', '\xB7', ' ', '\xE9', '\x9C', '\xB2', ' ', '\xE9', '\x9D', '\xA2', /* 軍 那 配 里 開 雷 露 面 */ + ' ', '\xE9', '\xA1', '\xBE', /* 顾 */ '\0', - '\xE4', '\xB8', '\xAA', '\xE4', '\xB8', '\xBA', '\xE4', '\xBA', '\xBA', '\xE4', '\xBB', '\x96', '\xE4', '\xBB', '\xA5', '\xE4', '\xBB', '\xAC', '\xE4', '\xBD', '\xA0', '\xE4', '\xBE', '\x86', /* 个为人他以们你來 */ - '\xE5', '\x80', '\x8B', '\xE5', '\x80', '\x91', '\xE5', '\x88', '\xB0', '\xE5', '\x92', '\x8C', '\xE5', '\xA4', '\xA7', '\xE5', '\xAF', '\xB9', '\xE5', '\xB0', '\x8D', '\xE5', '\xB0', '\xB1', /* 個們到和大对對就 */ - '\xE6', '\x88', '\x91', '\xE6', '\x97', '\xB6', '\xE6', '\x99', '\x82', '\xE6', '\x9C', '\x89', '\xE6', '\x9D', '\xA5', '\xE7', '\x82', '\xBA', '\xE8', '\xA6', '\x81', '\xE8', '\xAA', '\xAA', /* 我时時有来為要說 */ - '\xE8', '\xAF', '\xB4', '|', /* 说 | */ - '\xE4', '\xB8', '\xBB', '\xE4', '\xBA', '\x9B', '\xE5', '\x9B', '\xA0', '\xE5', '\xAE', '\x83', '\xE6', '\x83', '\xB3', '\xE6', '\x84', '\x8F', '\xE7', '\x90', '\x86', '\xE7', '\x94', '\x9F', /* 主些因它想意理生 */ - '\xE7', '\x95', '\xB6', '\xE7', '\x9C', '\x8B', '\xE7', '\x9D', '\x80', '\xE7', '\xBD', '\xAE', '\xE8', '\x80', '\x85', '\xE8', '\x87', '\xAA', '\xE8', '\x91', '\x97', '\xE8', '\xA3', '\xA1', /* 當看着置者自著裡 */ - '\xE8', '\xBF', '\x87', '\xE8', '\xBF', '\x98', '\xE8', '\xBF', '\x9B', '\xE9', '\x80', '\xB2', '\xE9', '\x81', '\x8E', '\xE9', '\x81', '\x93', '\xE9', '\x82', '\x84', '\xE9', '\x87', '\x8C', /* 过还进進過道還里 */ - '\xE9', '\x9D', '\xA2', /* 面 */ + '\xE4', '\xB8', '\xAA', ' ', '\xE4', '\xB8', '\xBA', ' ', '\xE4', '\xBA', '\xBA', ' ', '\xE4', '\xBB', '\x96', ' ', '\xE4', '\xBB', '\xA5', ' ', '\xE4', '\xBB', '\xAC', ' ', '\xE4', '\xBD', '\xA0', ' ', '\xE4', '\xBE', '\x86', /* 个 为 人 他 以 们 你 來 */ + ' ', '\xE5', '\x80', '\x8B', ' ', '\xE5', '\x80', '\x91', ' ', '\xE5', '\x88', '\xB0', ' ', '\xE5', '\x92', '\x8C', ' ', '\xE5', '\xA4', '\xA7', ' ', '\xE5', '\xAF', '\xB9', ' ', '\xE5', '\xB0', '\x8D', ' ', '\xE5', '\xB0', '\xB1', /* 個 們 到 和 大 对 對 就 */ + ' ', '\xE6', '\x88', '\x91', ' ', '\xE6', '\x97', '\xB6', ' ', '\xE6', '\x99', '\x82', ' ', '\xE6', '\x9C', '\x89', ' ', '\xE6', '\x9D', '\xA5', ' ', '\xE7', '\x82', '\xBA', ' ', '\xE8', '\xA6', '\x81', ' ', '\xE8', '\xAA', '\xAA', /* 我 时 時 有 来 為 要 說 */ + ' ', '\xE8', '\xAF', '\xB4', ' ', '|', /* 说 | */ + ' ', '\xE4', '\xB8', '\xBB', ' ', '\xE4', '\xBA', '\x9B', ' ', '\xE5', '\x9B', '\xA0', ' ', '\xE5', '\xAE', '\x83', ' ', '\xE6', '\x83', '\xB3', ' ', '\xE6', '\x84', '\x8F', ' ', '\xE7', '\x90', '\x86', ' ', '\xE7', '\x94', '\x9F', /* 主 些 因 它 想 意 理 生 */ + ' ', '\xE7', '\x95', '\xB6', ' ', '\xE7', '\x9C', '\x8B', ' ', '\xE7', '\x9D', '\x80', ' ', '\xE7', '\xBD', '\xAE', ' ', '\xE8', '\x80', '\x85', ' ', '\xE8', '\x87', '\xAA', ' ', '\xE8', '\x91', '\x97', ' ', '\xE8', '\xA3', '\xA1', /* 當 看 着 置 者 自 著 裡 */ + ' ', '\xE8', '\xBF', '\x87', ' ', '\xE8', '\xBF', '\x98', ' ', '\xE8', '\xBF', '\x9B', ' ', '\xE9', '\x80', '\xB2', ' ', '\xE9', '\x81', '\x8E', ' ', '\xE9', '\x81', '\x93', ' ', '\xE9', '\x82', '\x84', ' ', '\xE9', '\x87', '\x8C', /* 过 还 进 進 過 道 還 里 */ + ' ', '\xE9', '\x9D', '\xA2', /* 面 */ #ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT '\0', - '\xE4', '\xBA', '\x9B', '\xE4', '\xBB', '\xAC', '\xE4', '\xBD', '\xA0', '\xE4', '\xBE', '\x86', '\xE5', '\x80', '\x91', '\xE5', '\x88', '\xB0', '\xE5', '\x92', '\x8C', '\xE5', '\x9C', '\xB0', /* 些们你來們到和地 */ - '\xE5', '\xA5', '\xB9', '\xE5', '\xB0', '\x86', '\xE5', '\xB0', '\x87', '\xE5', '\xB0', '\xB1', '\xE5', '\xB9', '\xB4', '\xE5', '\xBE', '\x97', '\xE6', '\x83', '\x85', '\xE6', '\x9C', '\x80', /* 她将將就年得情最 */ - '\xE6', '\xA0', '\xB7', '\xE6', '\xA8', '\xA3', '\xE7', '\x90', '\x86', '\xE8', '\x83', '\xBD', '\xE8', '\xAA', '\xAA', '\xE8', '\xAF', '\xB4', '\xE8', '\xBF', '\x99', '\xE9', '\x80', '\x99', /* 样樣理能說说这這 */ - '\xE9', '\x80', '\x9A', '|', /* 通 | */ - '\xE5', '\x8D', '\xB3', '\xE5', '\x90', '\x97', '\xE5', '\x90', '\xA7', '\xE5', '\x90', '\xAC', '\xE5', '\x91', '\xA2', '\xE5', '\x93', '\x81', '\xE5', '\x93', '\x8D', '\xE5', '\x97', '\x8E', /* 即吗吧听呢品响嗎 */ - '\xE5', '\xB8', '\x88', '\xE5', '\xB8', '\xAB', '\xE6', '\x94', '\xB6', '\xE6', '\x96', '\xAD', '\xE6', '\x96', '\xB7', '\xE6', '\x98', '\x8E', '\xE7', '\x9C', '\xBC', '\xE9', '\x96', '\x93', /* 师師收断斷明眼間 */ - '\xE9', '\x97', '\xB4', '\xE9', '\x99', '\x85', '\xE9', '\x99', '\x88', '\xE9', '\x99', '\x90', '\xE9', '\x99', '\xA4', '\xE9', '\x99', '\xB3', '\xE9', '\x9A', '\x8F', '\xE9', '\x9A', '\x9B', /* 间际陈限除陳随際 */ - '\xE9', '\x9A', '\xA8', /* 隨 */ + ' ', '\xE4', '\xBA', '\x9B', ' ', '\xE4', '\xBB', '\xAC', ' ', '\xE4', '\xBD', '\xA0', ' ', '\xE4', '\xBE', '\x86', ' ', '\xE5', '\x80', '\x91', ' ', '\xE5', '\x88', '\xB0', ' ', '\xE5', '\x92', '\x8C', ' ', '\xE5', '\x9C', '\xB0', /* 些 们 你 來 們 到 和 地 */ + ' ', '\xE5', '\xA5', '\xB9', ' ', '\xE5', '\xB0', '\x86', ' ', '\xE5', '\xB0', '\x87', ' ', '\xE5', '\xB0', '\xB1', ' ', '\xE5', '\xB9', '\xB4', ' ', '\xE5', '\xBE', '\x97', ' ', '\xE6', '\x83', '\x85', ' ', '\xE6', '\x9C', '\x80', /* 她 将 將 就 年 得 情 最 */ + ' ', '\xE6', '\xA0', '\xB7', ' ', '\xE6', '\xA8', '\xA3', ' ', '\xE7', '\x90', '\x86', ' ', '\xE8', '\x83', '\xBD', ' ', '\xE8', '\xAA', '\xAA', ' ', '\xE8', '\xAF', '\xB4', ' ', '\xE8', '\xBF', '\x99', ' ', '\xE9', '\x80', '\x99', /* 样 樣 理 能 說 说 这 這 */ + ' ', '\xE9', '\x80', '\x9A', ' ', '|', /* 通 | */ + ' ', '\xE5', '\x8D', '\xB3', ' ', '\xE5', '\x90', '\x97', ' ', '\xE5', '\x90', '\xA7', ' ', '\xE5', '\x90', '\xAC', ' ', '\xE5', '\x91', '\xA2', ' ', '\xE5', '\x93', '\x81', ' ', '\xE5', '\x93', '\x8D', ' ', '\xE5', '\x97', '\x8E', /* 即 吗 吧 听 呢 品 响 嗎 */ + ' ', '\xE5', '\xB8', '\x88', ' ', '\xE5', '\xB8', '\xAB', ' ', '\xE6', '\x94', '\xB6', ' ', '\xE6', '\x96', '\xAD', ' ', '\xE6', '\x96', '\xB7', ' ', '\xE6', '\x98', '\x8E', ' ', '\xE7', '\x9C', '\xBC', ' ', '\xE9', '\x96', '\x93', /* 师 師 收 断 斷 明 眼 間 */ + ' ', '\xE9', '\x97', '\xB4', ' ', '\xE9', '\x99', '\x85', ' ', '\xE9', '\x99', '\x88', ' ', '\xE9', '\x99', '\x90', ' ', '\xE9', '\x99', '\xA4', ' ', '\xE9', '\x99', '\xB3', ' ', '\xE9', '\x9A', '\x8F', ' ', '\xE9', '\x9A', '\x9B', /* 间 际 陈 限 除 陳 随 際 */ + ' ', '\xE9', '\x9A', '\xA8', /* 隨 */ '\0', - '\xE4', '\xBA', '\x8B', '\xE5', '\x89', '\x8D', '\xE5', '\xAD', '\xB8', '\xE5', '\xB0', '\x86', '\xE5', '\xB0', '\x87', '\xE6', '\x83', '\x85', '\xE6', '\x83', '\xB3', '\xE6', '\x88', '\x96', /* 事前學将將情想或 */ - '\xE6', '\x94', '\xBF', '\xE6', '\x96', '\xAF', '\xE6', '\x96', '\xB0', '\xE6', '\xA0', '\xB7', '\xE6', '\xA8', '\xA3', '\xE6', '\xB0', '\x91', '\xE6', '\xB2', '\x92', '\xE6', '\xB2', '\xA1', /* 政斯新样樣民沒没 */ - '\xE7', '\x84', '\xB6', '\xE7', '\x89', '\xB9', '\xE7', '\x8E', '\xB0', '\xE7', '\x8F', '\xBE', '\xE7', '\x90', '\x83', '\xE7', '\xAC', '\xAC', '\xE7', '\xB6', '\x93', '\xE8', '\xB0', '\x81', /* 然特现現球第經谁 */ - '\xE8', '\xB5', '\xB7', '|', /* 起 | */ - '\xE4', '\xBE', '\x8B', '\xE5', '\x88', '\xA5', '\xE5', '\x88', '\xAB', '\xE5', '\x88', '\xB6', '\xE5', '\x8A', '\xA8', '\xE5', '\x8B', '\x95', '\xE5', '\x90', '\x97', '\xE5', '\x97', '\x8E', /* 例別别制动動吗嗎 */ - '\xE5', '\xA2', '\x9E', '\xE6', '\x8C', '\x87', '\xE6', '\x98', '\x8E', '\xE6', '\x9C', '\x9D', '\xE6', '\x9C', '\x9F', '\xE6', '\x9E', '\x84', '\xE7', '\x89', '\xA9', '\xE7', '\xA1', '\xAE', /* 增指明朝期构物确 */ - '\xE7', '\xA7', '\x8D', '\xE8', '\xAA', '\xBF', '\xE8', '\xB0', '\x83', '\xE8', '\xB2', '\xBB', '\xE8', '\xB4', '\xB9', '\xE9', '\x82', '\xA3', '\xE9', '\x83', '\xBD', '\xE9', '\x96', '\x93', /* 种調调費费那都間 */ - '\xE9', '\x97', '\xB4', /* 间 */ + '\xE4', '\xBA', '\x8B', ' ', '\xE5', '\x89', '\x8D', ' ', '\xE5', '\xAD', '\xB8', ' ', '\xE5', '\xB0', '\x86', ' ', '\xE5', '\xB0', '\x87', ' ', '\xE6', '\x83', '\x85', ' ', '\xE6', '\x83', '\xB3', ' ', '\xE6', '\x88', '\x96', /* 事 前 學 将 將 情 想 或 */ + ' ', '\xE6', '\x94', '\xBF', ' ', '\xE6', '\x96', '\xAF', ' ', '\xE6', '\x96', '\xB0', ' ', '\xE6', '\xA0', '\xB7', ' ', '\xE6', '\xA8', '\xA3', ' ', '\xE6', '\xB0', '\x91', ' ', '\xE6', '\xB2', '\x92', ' ', '\xE6', '\xB2', '\xA1', /* 政 斯 新 样 樣 民 沒 没 */ + ' ', '\xE7', '\x84', '\xB6', ' ', '\xE7', '\x89', '\xB9', ' ', '\xE7', '\x8E', '\xB0', ' ', '\xE7', '\x8F', '\xBE', ' ', '\xE7', '\x90', '\x83', ' ', '\xE7', '\xAC', '\xAC', ' ', '\xE7', '\xB6', '\x93', ' ', '\xE8', '\xB0', '\x81', /* 然 特 现 現 球 第 經 谁 */ + ' ', '\xE8', '\xB5', '\xB7', ' ', '|', /* 起 | */ + ' ', '\xE4', '\xBE', '\x8B', ' ', '\xE5', '\x88', '\xA5', ' ', '\xE5', '\x88', '\xAB', ' ', '\xE5', '\x88', '\xB6', ' ', '\xE5', '\x8A', '\xA8', ' ', '\xE5', '\x8B', '\x95', ' ', '\xE5', '\x90', '\x97', ' ', '\xE5', '\x97', '\x8E', /* 例 別 别 制 动 動 吗 嗎 */ + ' ', '\xE5', '\xA2', '\x9E', ' ', '\xE6', '\x8C', '\x87', ' ', '\xE6', '\x98', '\x8E', ' ', '\xE6', '\x9C', '\x9D', ' ', '\xE6', '\x9C', '\x9F', ' ', '\xE6', '\x9E', '\x84', ' ', '\xE7', '\x89', '\xA9', ' ', '\xE7', '\xA1', '\xAE', /* 增 指 明 朝 期 构 物 确 */ + ' ', '\xE7', '\xA7', '\x8D', ' ', '\xE8', '\xAA', '\xBF', ' ', '\xE8', '\xB0', '\x83', ' ', '\xE8', '\xB2', '\xBB', ' ', '\xE8', '\xB4', '\xB9', ' ', '\xE9', '\x82', '\xA3', ' ', '\xE9', '\x83', '\xBD', ' ', '\xE9', '\x96', '\x93', /* 种 調 调 費 费 那 都 間 */ + ' ', '\xE9', '\x97', '\xB4', /* 间 */ #endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */ #endif /* AF_CONFIG_OPTION_CJK */ '\0', @@ -171,10 +443,77 @@ af_blue_stringsets[] = { /* */ + { AF_BLUE_STRING_ADLAM_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_ADLAM_CAPITAL_BOTTOM, 0 }, + { AF_BLUE_STRING_ADLAM_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_ADLAM_SMALL_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, { AF_BLUE_STRING_ARABIC_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, { AF_BLUE_STRING_ARABIC_BOTTOM, 0 }, { AF_BLUE_STRING_ARABIC_JOIN, AF_BLUE_PROPERTY_LATIN_NEUTRAL }, { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_ARMENIAN_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_ARMENIAN_CAPITAL_BOTTOM, 0 }, + { AF_BLUE_STRING_ARMENIAN_SMALL_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_ARMENIAN_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_ARMENIAN_SMALL_BOTTOM, 0 }, + { AF_BLUE_STRING_ARMENIAN_SMALL_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_AVESTAN_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_AVESTAN_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_BAMUM_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_BAMUM_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_BENGALI_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_BENGALI_HEAD, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_BENGALI_BASE, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_NEUTRAL | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_BENGALI_BASE, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_BUHID_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_BUHID_LARGE, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_BUHID_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_BUHID_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_CHAKMA_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_CHAKMA_BOTTOM, 0 }, + { AF_BLUE_STRING_CHAKMA_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_CANADIAN_SYLLABICS_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_CANADIAN_SYLLABICS_BOTTOM, 0 }, + { AF_BLUE_STRING_CANADIAN_SYLLABICS_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_CANADIAN_SYLLABICS_SMALL_BOTTOM, 0 }, + { AF_BLUE_STRING_CANADIAN_SYLLABICS_SUPS_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_CANADIAN_SYLLABICS_SUPS_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_CARIAN_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_CARIAN_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_CHEROKEE_CAPITAL, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_CHEROKEE_CAPITAL, 0 }, + { AF_BLUE_STRING_CHEROKEE_SMALL_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_CHEROKEE_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_CHEROKEE_SMALL, 0 }, + { AF_BLUE_STRING_CHEROKEE_SMALL_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_COPTIC_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_COPTIC_CAPITAL_BOTTOM, 0 }, + { AF_BLUE_STRING_COPTIC_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_COPTIC_SMALL_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_CYPRIOT_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_CYPRIOT_BOTTOM, 0 }, + { AF_BLUE_STRING_CYPRIOT_SMALL, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_CYPRIOT_SMALL, 0 }, + { AF_BLUE_STRING_MAX, 0 }, { AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, { AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM, 0 }, { AF_BLUE_STRING_CYRILLIC_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | @@ -190,6 +529,40 @@ { AF_BLUE_STRING_DEVANAGARI_BASE, 0 }, { AF_BLUE_STRING_DEVANAGARI_BOTTOM, 0 }, { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_DESERET_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_DESERET_CAPITAL_BOTTOM, 0 }, + { AF_BLUE_STRING_DESERET_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_DESERET_SMALL_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_ETHIOPIC_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_ETHIOPIC_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_BOTTOM, 0 }, + { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_DESCENDER, 0 }, + { AF_BLUE_STRING_GEORGIAN_MTAVRULI_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_GEORGIAN_MTAVRULI_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_BOTTOM, 0 }, + { AF_BLUE_STRING_GEORGIAN_NUSKHURI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_GEORGIAN_NUSKHURI_BOTTOM, 0 }, + { AF_BLUE_STRING_GEORGIAN_NUSKHURI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_GEORGIAN_NUSKHURI_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_GLAGOLITIC_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_GLAGOLITIC_CAPITAL_BOTTOM, 0 }, + { AF_BLUE_STRING_GLAGOLITIC_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_GLAGOLITIC_SMALL_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_GOTHIC_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_GOTHIC_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, { AF_BLUE_STRING_GREEK_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, { AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM, 0 }, { AF_BLUE_STRING_GREEK_SMALL_BETA_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, @@ -198,24 +571,60 @@ { AF_BLUE_STRING_GREEK_SMALL, 0 }, { AF_BLUE_STRING_GREEK_SMALL_DESCENDER, 0 }, { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_GUJARATI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_GUJARATI_BOTTOM, 0 }, + { AF_BLUE_STRING_GUJARATI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_GUJARATI_DESCENDER, 0 }, + { AF_BLUE_STRING_GUJARATI_DIGIT_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_GURMUKHI_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_GURMUKHI_HEAD, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_GURMUKHI_BASE, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_NEUTRAL | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_GURMUKHI_BOTTOM, 0 }, + { AF_BLUE_STRING_GURMUKHI_DIGIT_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_MAX, 0 }, { AF_BLUE_STRING_HEBREW_TOP, AF_BLUE_PROPERTY_LATIN_TOP | AF_BLUE_PROPERTY_LATIN_LONG }, { AF_BLUE_STRING_HEBREW_BOTTOM, 0 }, { AF_BLUE_STRING_HEBREW_DESCENDER, 0 }, { AF_BLUE_STRING_MAX, 0 }, - { AF_BLUE_STRING_LAO_TOP, AF_BLUE_PROPERTY_LATIN_TOP | - AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, - { AF_BLUE_STRING_LAO_BOTTOM, 0 }, - { AF_BLUE_STRING_LAO_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, - { AF_BLUE_STRING_LAO_LARGE_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, - { AF_BLUE_STRING_LAO_DESCENDER, 0 }, - { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_KAYAH_LI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_KAYAH_LI_BOTTOM, 0 }, + { AF_BLUE_STRING_KAYAH_LI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_KAYAH_LI_DESCENDER, 0 }, + { AF_BLUE_STRING_KAYAH_LI_LARGE_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_KHMER_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_KHMER_SUBSCRIPT_TOP, AF_BLUE_PROPERTY_LATIN_SUB_TOP }, + { AF_BLUE_STRING_KHMER_BOTTOM, 0 }, + { AF_BLUE_STRING_KHMER_DESCENDER, 0 }, + { AF_BLUE_STRING_KHMER_LARGE_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_KHMER_SYMBOLS_WAXING_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_KANNADA_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_KANNADA_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_LAO_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_LAO_BOTTOM, 0 }, + { AF_BLUE_STRING_LAO_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_LAO_LARGE_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_LAO_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, { AF_BLUE_STRING_LATIN_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, { AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM, 0 }, { AF_BLUE_STRING_LATIN_SMALL_F_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, - { AF_BLUE_STRING_LATIN_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + { AF_BLUE_STRING_LATIN_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP | AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, - { AF_BLUE_STRING_LATIN_SMALL, 0 }, + { AF_BLUE_STRING_LATIN_SMALL_BOTTOM, 0 }, { AF_BLUE_STRING_LATIN_SMALL_DESCENDER, 0 }, { AF_BLUE_STRING_MAX, 0 }, { AF_BLUE_STRING_LATIN_SUBS_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, @@ -234,9 +643,73 @@ { AF_BLUE_STRING_LATIN_SUPS_SMALL, 0 }, { AF_BLUE_STRING_LATIN_SUPS_SMALL_DESCENDER, 0 }, { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_LISU_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_LISU_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_MALAYALAM_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_MALAYALAM_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_MYANMAR_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_MYANMAR_BOTTOM, 0 }, + { AF_BLUE_STRING_MYANMAR_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_MYANMAR_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_NKO_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_NKO_BOTTOM, 0 }, + { AF_BLUE_STRING_NKO_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_NKO_SMALL_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_OL_CHIKI, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_OL_CHIKI, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_OLD_TURKIC_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_OLD_TURKIC_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_OSAGE_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_OSAGE_CAPITAL_BOTTOM, 0 }, + { AF_BLUE_STRING_OSAGE_CAPITAL_DESCENDER, 0 }, + { AF_BLUE_STRING_OSAGE_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_OSAGE_SMALL_BOTTOM, 0 }, + { AF_BLUE_STRING_OSAGE_SMALL_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_OSAGE_SMALL_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_OSMANYA_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_OSMANYA_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_SAURASHTRA_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_SAURASHTRA_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_SHAVIAN_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_SHAVIAN_BOTTOM, 0 }, + { AF_BLUE_STRING_SHAVIAN_DESCENDER, 0 }, + { AF_BLUE_STRING_SHAVIAN_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, + { AF_BLUE_STRING_SHAVIAN_SMALL_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_SINHALA_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_SINHALA_BOTTOM, 0 }, + { AF_BLUE_STRING_SINHALA_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_SUNDANESE_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_SUNDANESE_BOTTOM, 0 }, + { AF_BLUE_STRING_SUNDANESE_DESCENDER, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_TAMIL_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_TAMIL_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_TAI_VIET_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_TAI_VIET_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, { AF_BLUE_STRING_TELUGU_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, { AF_BLUE_STRING_TELUGU_BOTTOM, 0 }, { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_TIFINAGH, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_TIFINAGH, 0 }, + { AF_BLUE_STRING_MAX, 0 }, { AF_BLUE_STRING_THAI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, { AF_BLUE_STRING_THAI_BOTTOM, 0 }, @@ -246,6 +719,9 @@ { AF_BLUE_STRING_THAI_LARGE_DESCENDER, 0 }, { AF_BLUE_STRING_THAI_DIGIT_TOP, 0 }, { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_VAI_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_VAI_BOTTOM, 0 }, + { AF_BLUE_STRING_MAX, 0 }, #ifdef AF_CONFIG_OPTION_CJK { AF_BLUE_STRING_CJK_TOP, AF_BLUE_PROPERTY_CJK_TOP }, { AF_BLUE_STRING_CJK_BOTTOM, 0 }, diff --git a/src/3rdparty/freetype/src/autofit/afblue.cin b/src/3rdparty/freetype/src/autofit/afblue.cin index b303a4b2b0..4913e2eb6f 100644 --- a/src/3rdparty/freetype/src/autofit/afblue.cin +++ b/src/3rdparty/freetype/src/autofit/afblue.cin @@ -4,7 +4,7 @@ /* */ /* Auto-fitter data for blue strings (body). */ /* */ -/* Copyright 2013-2015 by */ +/* Copyright 2013-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/src/autofit/afblue.dat b/src/3rdparty/freetype/src/autofit/afblue.dat index 1b52378ed3..bc2f0d2754 100644 --- a/src/3rdparty/freetype/src/autofit/afblue.dat +++ b/src/3rdparty/freetype/src/autofit/afblue.dat @@ -2,7 +2,7 @@ // // Auto-fitter data for blue strings. // -// Copyright 2013-2015 by +// Copyright 2013-2018 by // David Turner, Robert Wilhelm, and Werner Lemberg. // // This file is part of the FreeType project, and may only be used, @@ -20,9 +20,8 @@ // labels separated by whitespace and followed by a colon (everything in a // single line); the first label gives the name of the enumeration template, // the second the name of the array template, and the third the name of the -// `maximum' template, holding the size of the largest array element. The -// script then fills the corresponding templates (indicated by `@' -// characters around the name). +// `maximum' template. The script then fills the corresponding templates +// (indicated by `@' characters around the name). // // A section contains one or more data records. Each data record consists // of two or more lines. The first line holds the enumeration name, and the @@ -30,15 +29,20 @@ // // There are two possible representations for array data. // -// - A string of characters in UTF-8 encoding enclosed in double quotes, -// using C syntax. There can be only one string per line, thus the -// starting and ending double quote must be the first and last character -// in the line, respectively, ignoring whitespace before and after the -// string. Space characters within the string are ignored too. If there -// are multiple strings (in multiple lines), they are concatenated to a -// single string. In the output, a string gets represented as a series of -// singles bytes, followed by a zero byte. The enumeration values simply -// hold byte offsets to the start of the corresponding strings. +// - A string of characters or character clusters (for example, representing +// Aksharas, Devanagari syllables) in UTF-8 encoding enclosed in double +// quotes, using C syntax, where the elements are separated by spaces. +// There can be only one string per line, thus the starting and ending +// double quote must be the first and last character in the line, +// respectively, ignoring whitespace before and after the string. If +// there are multiple strings (in multiple lines), they are concatenated +// to a single string. In the output, a string gets represented as a +// series of singles bytes, followed by a zero byte. The enumeration +// values simply hold byte offsets to the start of the corresponding +// strings. +// +// For strings, the `maximum' template holds the maximum number of +// non-space characters in all strings. // // - Data blocks enclosed in balanced braces, which get copied verbatim and // which can span multiple lines. The opening brace of a block must be @@ -47,6 +51,9 @@ // character after each block and counts the number of blocks to set the // enumeration values. // +// For data blocks, the `maximum' template holds the maximum number of +// array elements. +// // A section can contain either strings only or data blocks only. // // A comment line starts with `//'; it gets removed. A preprocessor @@ -58,8 +65,8 @@ // values; this essentially means that the maximum values can easily be too // large. Given that the purpose of those values is to create local // fixed-size arrays at compile time for further processing of the blue zone -// data, this isn't a problem. Note the the final zero byte of a string is -// not counted. Note also that the count holds the number of UTF-8 encoded +// data, this isn't a problem. Note the final zero byte of a string is not +// counted. Note also that the count holds the number of UTF-8 encoded // characters, not bytes. @@ -67,6 +74,15 @@ AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN: + AF_BLUE_STRING_ADLAM_CAPITAL_TOP + "𞤌 𞤅 𞤈 𞤏 𞤔 𞤚" + AF_BLUE_STRING_ADLAM_CAPITAL_BOTTOM + "𞤂 𞤖" + AF_BLUE_STRING_ADLAM_SMALL_TOP + "𞤬 𞤮 𞤻 𞤼 𞤾" + AF_BLUE_STRING_ADLAM_SMALL_BOTTOM + "𞤤 𞤨 𞤩 𞤭 𞤴 𞤸 𞤺 𞥀" + AF_BLUE_STRING_ARABIC_TOP "ا إ ل ك ط ظ" AF_BLUE_STRING_ARABIC_BOTTOM @@ -79,17 +95,113 @@ AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN: AF_BLUE_STRING_ARABIC_JOIN "ـ" - AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP - "БВЕПЗОСЭ" - AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM - "БВЕШЗОСЭ" - AF_BLUE_STRING_CYRILLIC_SMALL - "хпншезос" - AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER - "руф" + AF_BLUE_STRING_ARMENIAN_CAPITAL_TOP + "Ա Մ Ւ Ս Բ Գ Դ Օ" + AF_BLUE_STRING_ARMENIAN_CAPITAL_BOTTOM + "Ւ Ո Դ Ճ Շ Ս Տ Օ" + AF_BLUE_STRING_ARMENIAN_SMALL_ASCENDER + "ե է ի մ վ ֆ ճ" + AF_BLUE_STRING_ARMENIAN_SMALL_TOP + "ա յ ւ ս գ շ ր օ" + AF_BLUE_STRING_ARMENIAN_SMALL_BOTTOM + "հ ո ճ ա ե ծ ս օ" + AF_BLUE_STRING_ARMENIAN_SMALL_DESCENDER + "բ ը ի լ ղ պ փ ց" + + AF_BLUE_STRING_AVESTAN_TOP + "𐬀 𐬁 𐬐 𐬛" + AF_BLUE_STRING_AVESTAN_BOTTOM + "𐬀 𐬁" + + AF_BLUE_STRING_BAMUM_TOP + "ꚧ ꚨ ꛛ ꛉ ꛁ ꛈ ꛫ ꛯ" + AF_BLUE_STRING_BAMUM_BOTTOM + "ꚭ ꚳ ꚶ ꛬ ꚢ ꚽ ꛯ ꛲" + + AF_BLUE_STRING_BENGALI_BASE + "অ ড ত ন ব ভ ল ক" + AF_BLUE_STRING_BENGALI_TOP + "ই ট ঠ ি ী ৈ ৗ" + AF_BLUE_STRING_BENGALI_HEAD + "ও এ ড ত ন ব ল ক" + + AF_BLUE_STRING_BUHID_TOP + "ᝐ ᝈ" + AF_BLUE_STRING_BUHID_LARGE + "ᝅ ᝊ ᝎ" + AF_BLUE_STRING_BUHID_SMALL + "ᝂ ᝃ ᝉ ᝌ" + AF_BLUE_STRING_BUHID_BOTTOM + "ᝀ ᝃ ᝆ ᝉ ᝋ ᝏ ᝑ" + + AF_BLUE_STRING_CANADIAN_SYLLABICS_TOP + "ᗜ ᖴ ᐁ ᒣ ᑫ ᑎ ᔑ ᗰ" + AF_BLUE_STRING_CANADIAN_SYLLABICS_BOTTOM + "ᗶ ᖵ ᒧ ᐃ ᑌ ᒍ ᔑ ᗢ" + AF_BLUE_STRING_CANADIAN_SYLLABICS_SMALL_TOP + "ᓓ ᓕ ᓀ ᓂ ᓄ ᕄ ᕆ ᘣ" + AF_BLUE_STRING_CANADIAN_SYLLABICS_SMALL_BOTTOM + "ᕃ ᓂ ᓀ ᕂ ᓗ ᓚ ᕆ ᘣ" + AF_BLUE_STRING_CANADIAN_SYLLABICS_SUPS_TOP + "ᐪ ᙆ ᣘ ᐢ ᒾ ᣗ ᔆ" + AF_BLUE_STRING_CANADIAN_SYLLABICS_SUPS_BOTTOM + "ᙆ ᗮ ᒻ ᐞ ᔆ ᒡ ᒢ ᓑ" + + AF_BLUE_STRING_CARIAN_TOP + "𐊧 𐊫 𐊬 𐊭 𐊱 𐊺 𐊼 𐊿" + AF_BLUE_STRING_CARIAN_BOTTOM + "𐊣 𐊧 𐊷 𐋀 𐊫 𐊸 𐋉" + + AF_BLUE_STRING_CHAKMA_TOP + "𑄃 𑄅 𑄉 𑄙 𑄗" + AF_BLUE_STRING_CHAKMA_BOTTOM + "𑄅 𑄛 𑄝 𑄗 𑄓" + AF_BLUE_STRING_CHAKMA_DESCENDER + "𑄖𑄳𑄢 𑄘𑄳𑄢 𑄙𑄳𑄢 𑄤𑄳𑄢 𑄥𑄳𑄢" + + AF_BLUE_STRING_CHEROKEE_CAPITAL + "Ꮖ Ꮋ Ꭼ Ꮓ Ꭴ Ꮳ Ꭶ Ꮥ" + AF_BLUE_STRING_CHEROKEE_SMALL_ASCENDER + "ꮒ ꮤ ꮶ ꭴ ꭾ ꮗ ꮝ ꮿ" + AF_BLUE_STRING_CHEROKEE_SMALL + "ꮖ ꭼ ꮓ ꮠ ꮳ ꭶ ꮥ ꮻ" + AF_BLUE_STRING_CHEROKEE_SMALL_DESCENDER + "ᏸ ꮐ ꭹ ꭻ" + + AF_BLUE_STRING_COPTIC_CAPITAL_TOP + "Ⲍ Ⲏ Ⲡ Ⳟ Ⲟ Ⲑ Ⲥ Ⳋ" + AF_BLUE_STRING_COPTIC_CAPITAL_BOTTOM + "Ⳑ Ⳙ Ⳟ Ⲏ Ⲟ Ⲑ Ⳝ Ⲱ" + AF_BLUE_STRING_COPTIC_SMALL_TOP + "ⲍ ⲏ ⲡ ⳟ ⲟ ⲑ ⲥ ⳋ" + AF_BLUE_STRING_COPTIC_SMALL_BOTTOM + "ⳑ ⳙ ⳟ ⲏ ⲟ ⲑ ⳝ Ⳓ" + + AF_BLUE_STRING_CYPRIOT_TOP + "𐠍 𐠙 𐠳 𐠱 𐠅 𐠓 𐠣 𐠦" + AF_BLUE_STRING_CYPRIOT_BOTTOM + "𐠃 𐠊 𐠛 𐠣 𐠳 𐠵 𐠐" + AF_BLUE_STRING_CYPRIOT_SMALL + "𐠈 𐠏 𐠖" + + AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP + "Б В Е П З О С Э" + AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM + "Б В Е Ш З О С Э" + AF_BLUE_STRING_CYRILLIC_SMALL + "х п н ш е з о с" + AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER + "р у ф" + + AF_BLUE_STRING_DESERET_CAPITAL_TOP + "𐐂 𐐄 𐐋 𐐗 𐐑" + AF_BLUE_STRING_DESERET_CAPITAL_BOTTOM + "𐐀 𐐂 𐐄 𐐗 𐐛" + AF_BLUE_STRING_DESERET_SMALL_TOP + "𐐪 𐐬 𐐳 𐐿 𐐹" + AF_BLUE_STRING_DESERET_SMALL_BOTTOM + "𐐨 𐐪 𐐬 𐐿 𐑃" - // we separate the letters with spaces to avoid ligatures; - // this is just for convenience to simplify reading AF_BLUE_STRING_DEVANAGARI_BASE "क म अ आ थ ध भ श" AF_BLUE_STRING_DEVANAGARI_TOP @@ -102,23 +214,124 @@ AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN: AF_BLUE_STRING_DEVANAGARI_BOTTOM "ु ृ" + AF_BLUE_STRING_ETHIOPIC_TOP + "ሀ ሃ ዘ ፐ ማ በ ዋ ዐ" + AF_BLUE_STRING_ETHIOPIC_BOTTOM + "ለ ሐ በ ዘ ሀ ሪ ዐ ጨ" + + AF_BLUE_STRING_GEORGIAN_MKHEDRULI_TOP + "გ დ ე ვ თ ი ო ღ" + AF_BLUE_STRING_GEORGIAN_MKHEDRULI_BOTTOM + "ა ზ მ ს შ ძ ხ პ" + AF_BLUE_STRING_GEORGIAN_MKHEDRULI_ASCENDER + "ს ხ ქ ზ მ შ ჩ წ" + AF_BLUE_STRING_GEORGIAN_MKHEDRULI_DESCENDER + "ე ვ ჟ ტ უ ფ ქ ყ" + + AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_TOP + "Ⴑ Ⴇ Ⴙ Ⴜ Ⴄ Ⴅ Ⴓ Ⴚ" + AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_BOTTOM + "Ⴄ Ⴅ Ⴇ Ⴈ Ⴆ Ⴑ Ⴊ Ⴋ" + + AF_BLUE_STRING_GEORGIAN_NUSKHURI_TOP + "ⴁ ⴗ ⴂ ⴄ ⴅ ⴇ ⴔ ⴖ" + AF_BLUE_STRING_GEORGIAN_NUSKHURI_BOTTOM + "ⴈ ⴌ ⴖ ⴎ ⴃ ⴆ ⴋ ⴢ" + AF_BLUE_STRING_GEORGIAN_NUSKHURI_ASCENDER + "ⴐ ⴑ ⴓ ⴕ ⴙ ⴛ ⴡ ⴣ" + AF_BLUE_STRING_GEORGIAN_NUSKHURI_DESCENDER + "ⴄ ⴅ ⴔ ⴕ ⴁ ⴂ ⴘ ⴝ" + + AF_BLUE_STRING_GEORGIAN_MTAVRULI_TOP + "Ნ Ჟ Ჳ Ჸ Გ Ე Ო Ჴ" + AF_BLUE_STRING_GEORGIAN_MTAVRULI_BOTTOM + "Ი Ჲ Ო Ჩ Მ Შ Ჯ Ჽ" + + AF_BLUE_STRING_GLAGOLITIC_CAPITAL_TOP + "Ⰵ Ⱄ Ⱚ Ⰴ Ⰲ Ⰺ Ⱛ Ⰻ" + AF_BLUE_STRING_GLAGOLITIC_CAPITAL_BOTTOM + "Ⰵ Ⰴ Ⰲ Ⱚ Ⱎ Ⱑ Ⰺ Ⱄ" + AF_BLUE_STRING_GLAGOLITIC_SMALL_TOP + "ⰵ ⱄ ⱚ ⰴ ⰲ ⰺ ⱛ ⰻ" + AF_BLUE_STRING_GLAGOLITIC_SMALL_BOTTOM + "ⰵ ⰴ ⰲ ⱚ ⱎ ⱑ ⰺ ⱄ" + + AF_BLUE_STRING_GOTHIC_TOP + "𐌲 𐌶 𐍀 𐍄 𐌴 𐍃 𐍈 𐌾" + AF_BLUE_STRING_GOTHIC_BOTTOM + "𐌶 𐌴 𐍃 𐍈" + AF_BLUE_STRING_GREEK_CAPITAL_TOP - "ΓΒΕΖΘΟΩ" + "Γ Β Ε Ζ Θ Ο Ω" AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM - "ΒΔΖΞΘΟ" + "Β Δ Ζ Ξ Θ Ο" AF_BLUE_STRING_GREEK_SMALL_BETA_TOP - "βθδζλξ" + "β θ δ ζ λ ξ" AF_BLUE_STRING_GREEK_SMALL - "αειοπστω" + "α ε ι ο π σ τ ω" AF_BLUE_STRING_GREEK_SMALL_DESCENDER - "βγημρφχψ" + "β γ η μ ρ φ χ ψ" + + AF_BLUE_STRING_GUJARATI_TOP + "ત ન ઋ ઌ છ ટ ર ૦" + AF_BLUE_STRING_GUJARATI_BOTTOM + "ખ ગ ઘ ઞ ઇ ઈ ઠ જ" + AF_BLUE_STRING_GUJARATI_ASCENDER + "ઈ ઊ િ ી લી શ્ચિ જિ સી" + AF_BLUE_STRING_GUJARATI_DESCENDER + "ુ ૃ ૄ ખુ છૃ છૄ" + AF_BLUE_STRING_GUJARATI_DIGIT_TOP + "૦ ૧ ૨ ૩ ૭" + + AF_BLUE_STRING_GURMUKHI_BASE + "ਕ ਗ ਙ ਚ ਜ ਤ ਧ ਸ" + AF_BLUE_STRING_GURMUKHI_HEAD + "ਕ ਗ ਙ ਚ ਜ ਤ ਧ ਸ" + AF_BLUE_STRING_GURMUKHI_TOP + "ਇ ਈ ਉ ਏ ਓ ੳ ਿ ੀ" + AF_BLUE_STRING_GURMUKHI_BOTTOM + "ਅ ਏ ਓ ਗ ਜ ਠ ਰ ਸ" + AF_BLUE_STRING_GURMUKHI_DIGIT_TOP + "੦ ੧ ੨ ੩ ੭" AF_BLUE_STRING_HEBREW_TOP - "בדהחךכםס" + "ב ד ה ח ך כ ם ס" AF_BLUE_STRING_HEBREW_BOTTOM - "בטכםסצ" + "ב ט כ ם ס צ" AF_BLUE_STRING_HEBREW_DESCENDER - "קךןףץ" + "ק ך ן ף ץ" + + AF_BLUE_STRING_KANNADA_TOP + "ಇ ಊ ಐ ಣ ಸಾ ನಾ ದಾ ರಾ" + AF_BLUE_STRING_KANNADA_BOTTOM + "ಅ ಉ ಎ ಲ ೦ ೨ ೬ ೭" + + AF_BLUE_STRING_KAYAH_LI_TOP + "꤅ ꤏ ꤁ ꤋ ꤀ ꤍ" + AF_BLUE_STRING_KAYAH_LI_BOTTOM + "꤈ ꤘ ꤀ ꤍ ꤢ" + AF_BLUE_STRING_KAYAH_LI_ASCENDER + "ꤖ ꤡ" + AF_BLUE_STRING_KAYAH_LI_DESCENDER + "ꤑ ꤜ ꤞ" + AF_BLUE_STRING_KAYAH_LI_LARGE_DESCENDER + "ꤑ꤬ ꤜ꤭ ꤔ꤬" + + AF_BLUE_STRING_KHMER_TOP + "ខ ទ ន ឧ ឩ ា" + AF_BLUE_STRING_KHMER_SUBSCRIPT_TOP + "ក្ក ក្ខ ក្គ ក្ថ" + AF_BLUE_STRING_KHMER_BOTTOM + "ខ ឃ ច ឋ ប ម យ ឲ" + AF_BLUE_STRING_KHMER_DESCENDER + "ត្រ រៀ ឲ្យ អឿ" + AF_BLUE_STRING_KHMER_LARGE_DESCENDER + "ន្ត្រៃ ង្ខ្យ ក្បៀ ច្រៀ ន្តឿ ល្បឿ" + + AF_BLUE_STRING_KHMER_SYMBOLS_WAXING_TOP + "᧠ ᧡" + AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM + "᧶ ᧹" AF_BLUE_STRING_LAO_TOP "າ ດ ອ ມ ລ ວ ຣ ງ" @@ -132,43 +345,139 @@ AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN: "ງ ຊ ຖ ຽ ໆ ຯ" AF_BLUE_STRING_LATIN_CAPITAL_TOP - "THEZOCQS" + "T H E Z O C Q S" AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM - "HEZLOCUS" + "H E Z L O C U S" AF_BLUE_STRING_LATIN_SMALL_F_TOP - "fijkdbh" - AF_BLUE_STRING_LATIN_SMALL - "xzroesc" + "f i j k d b h" + AF_BLUE_STRING_LATIN_SMALL_TOP + "u v x z o e s c" + AF_BLUE_STRING_LATIN_SMALL_BOTTOM + "n r x z o e s c" AF_BLUE_STRING_LATIN_SMALL_DESCENDER - "pqgjy" + "p q g j y" // we assume that both the subscript and superscript ranges // don't contain oldstyle digits (actually, most fonts probably // have digits only in those ranges) AF_BLUE_STRING_LATIN_SUBS_CAPITAL_TOP - "₀₃₅₇₈" + "₀ ₃ ₅ ₇ ₈" AF_BLUE_STRING_LATIN_SUBS_CAPITAL_BOTTOM - "₀₁₂₃₈" + "₀ ₁ ₂ ₃ ₈" AF_BLUE_STRING_LATIN_SUBS_SMALL_F_TOP - "ᵢⱼₕₖₗ" + "ᵢ ⱼ ₕ ₖ ₗ" AF_BLUE_STRING_LATIN_SUBS_SMALL - "ₐₑₒₓₙₛᵥᵤᵣ" + "ₐ ₑ ₒ ₓ ₙ ₛ ᵥ ᵤ ᵣ" AF_BLUE_STRING_LATIN_SUBS_SMALL_DESCENDER - "ᵦᵧᵨᵩₚ" + "ᵦ ᵧ ᵨ ᵩ ₚ" AF_BLUE_STRING_LATIN_SUPS_CAPITAL_TOP - "⁰³⁵⁷ᵀᴴᴱᴼ" + "⁰ ³ ⁵ ⁷ ᵀ ᴴ ᴱ ᴼ" AF_BLUE_STRING_LATIN_SUPS_CAPITAL_BOTTOM - "⁰¹²³ᴱᴸᴼᵁ" + "⁰ ¹ ² ³ ᴱ ᴸ ᴼ ᵁ" AF_BLUE_STRING_LATIN_SUPS_SMALL_F_TOP - "ᵇᵈᵏʰʲᶠⁱ" + "ᵇ ᵈ ᵏ ʰ ʲ ᶠ ⁱ" AF_BLUE_STRING_LATIN_SUPS_SMALL - "ᵉᵒʳˢˣᶜᶻ" + "ᵉ ᵒ ʳ ˢ ˣ ᶜ ᶻ" AF_BLUE_STRING_LATIN_SUPS_SMALL_DESCENDER - "ᵖʸᵍ" + "ᵖ ʸ ᵍ" + + AF_BLUE_STRING_LISU_TOP + "ꓡ ꓧ ꓱ ꓶ ꓩ ꓚ ꓵ ꓳ" + AF_BLUE_STRING_LISU_BOTTOM + "ꓕ ꓜ ꓞ ꓡ ꓛ ꓢ ꓳ ꓴ" + + AF_BLUE_STRING_MALAYALAM_TOP + "ഒ ട ഠ റ ച പ ച്ച പ്പ" + AF_BLUE_STRING_MALAYALAM_BOTTOM + "ട ഠ ധ ശ ഘ ച ഥ ല" + + AF_BLUE_STRING_MYANMAR_TOP + "ခ ဂ င ဒ ဝ ၥ ၊ ။" + AF_BLUE_STRING_MYANMAR_BOTTOM + "င ဎ ဒ ပ ဗ ဝ ၊ ။" + AF_BLUE_STRING_MYANMAR_ASCENDER + "ဩ ြ ၍ ၏ ၆ ါ ိ" + AF_BLUE_STRING_MYANMAR_DESCENDER + "ဉ ည ဥ ဩ ဨ ၂ ၅ ၉" + + AF_BLUE_STRING_NKO_TOP + "ߐ ߉ ߒ ߟ ߖ ߜ ߠ ߥ" + AF_BLUE_STRING_NKO_BOTTOM + "߀ ߘ ߡ ߠ ߥ" + AF_BLUE_STRING_NKO_SMALL_TOP + "ߏ ߛ ߋ" + AF_BLUE_STRING_NKO_SMALL_BOTTOM + "ߎ ߏ ߛ ߋ" + + AF_BLUE_STRING_OL_CHIKI + "ᱛ ᱜ ᱝ ᱡ ᱢ ᱥ" + + AF_BLUE_STRING_OLD_TURKIC_TOP + "𐰗 𐰘 𐰧" + AF_BLUE_STRING_OLD_TURKIC_BOTTOM + "𐰉 𐰗 𐰦 𐰧" + + AF_BLUE_STRING_OSAGE_CAPITAL_TOP + "𐒾 𐓍 𐓒 𐓓 𐒻 𐓂 𐒵 𐓆" + AF_BLUE_STRING_OSAGE_CAPITAL_BOTTOM + "𐒰 𐓍 𐓂 𐒿 𐓎 𐒹" + AF_BLUE_STRING_OSAGE_CAPITAL_DESCENDER + "𐒼 𐒽 𐒾" + AF_BLUE_STRING_OSAGE_SMALL_TOP + "𐓵 𐓶 𐓺 𐓻 𐓝 𐓣 𐓪 𐓮" + AF_BLUE_STRING_OSAGE_SMALL_BOTTOM + "𐓘 𐓚 𐓣 𐓵 𐓡 𐓧 𐓪 𐓶" + AF_BLUE_STRING_OSAGE_SMALL_ASCENDER + "𐓤 𐓦 𐓸 𐓹 𐓛" + AF_BLUE_STRING_OSAGE_SMALL_DESCENDER + "𐓤 𐓥 𐓦" + + AF_BLUE_STRING_OSMANYA_TOP + "𐒆 𐒉 𐒐 𐒒 𐒘 𐒛 𐒠 𐒣" + AF_BLUE_STRING_OSMANYA_BOTTOM + "𐒀 𐒂 𐒆 𐒈 𐒊 𐒒 𐒠 𐒩" + + AF_BLUE_STRING_SAURASHTRA_TOP + "ꢜ ꢞ ꢳ ꢂ ꢖ ꢒ ꢝ ꢛ" + AF_BLUE_STRING_SAURASHTRA_BOTTOM + "ꢂ ꢨ ꢺ ꢤ ꢎ" + + AF_BLUE_STRING_SHAVIAN_TOP + "𐑕 𐑙" + AF_BLUE_STRING_SHAVIAN_BOTTOM + "𐑔 𐑖 𐑗 𐑹 𐑻" + AF_BLUE_STRING_SHAVIAN_DESCENDER + "𐑟 𐑣" + AF_BLUE_STRING_SHAVIAN_SMALL_TOP + "𐑱 𐑲 𐑳 𐑴 𐑸 𐑺 𐑼" + AF_BLUE_STRING_SHAVIAN_SMALL_BOTTOM + "𐑴 𐑻 𐑹" + + AF_BLUE_STRING_SINHALA_TOP + "ඉ ක ඝ ඳ ප ය ල ෆ" + AF_BLUE_STRING_SINHALA_BOTTOM + "එ ඔ ඝ ජ ට ථ ධ ර" + AF_BLUE_STRING_SINHALA_DESCENDER + "ද ඳ උ ල තූ තු බු දු" + + AF_BLUE_STRING_SUNDANESE_TOP + "ᮋ ᮞ ᮮ ᮽ ᮰ ᮈ" + AF_BLUE_STRING_SUNDANESE_BOTTOM + "ᮄ ᮔ ᮕ ᮗ ᮰ ᮆ ᮈ ᮉ" + AF_BLUE_STRING_SUNDANESE_DESCENDER + "ᮼ ᳄" + + AF_BLUE_STRING_TAI_VIET_TOP + "ꪆ ꪔ ꪒ ꪖ ꪫ" + AF_BLUE_STRING_TAI_VIET_BOTTOM + "ꪉ ꪫ ꪮ" + + AF_BLUE_STRING_TAMIL_TOP + "உ ஒ ஓ ற ஈ க ங ச" + AF_BLUE_STRING_TAMIL_BOTTOM + "க ச ல ஶ உ ங ட ப" - // we separate the letters with spaces to avoid ligatures; - // this is just for convenience to simplify reading AF_BLUE_STRING_TELUGU_TOP "ఇ ఌ ఙ ఞ ణ ఱ ౯" AF_BLUE_STRING_TELUGU_BOTTOM @@ -189,48 +498,56 @@ AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN: AF_BLUE_STRING_THAI_DIGIT_TOP "๐ ๑ ๓" + AF_BLUE_STRING_TIFINAGH + "ⵔ ⵙ ⵛ ⵞ ⴵ ⴼ ⴹ ⵎ" + + AF_BLUE_STRING_VAI_TOP + "ꗍ ꘖ ꘙ ꘜ ꖜ ꖝ ꔅ ꕢ" + AF_BLUE_STRING_VAI_BOTTOM + "ꗍ ꘖ ꘙ ꗞ ꔅ ꕢ ꖜ ꔆ" + #ifdef AF_CONFIG_OPTION_CJK AF_BLUE_STRING_CJK_TOP - "他们你來們到和地" - "对對就席我时時會" - "来為能舰說说这這" - "齊 |" - "军同已愿既星是景" - "民照现現理用置要" - "軍那配里開雷露面" - "顾" + "他 们 你 來 們 到 和 地" + " 对 對 就 席 我 时 時 會" + " 来 為 能 舰 說 说 这 這" + " 齊 |" + " 军 同 已 愿 既 星 是 景" + " 民 照 现 現 理 用 置 要" + " 軍 那 配 里 開 雷 露 面" + " 顾" AF_BLUE_STRING_CJK_BOTTOM - "个为人他以们你來" - "個們到和大对對就" - "我时時有来為要說" - "说 |" - "主些因它想意理生" - "當看着置者自著裡" - "过还进進過道還里" - "面" + "个 为 人 他 以 们 你 來" + " 個 們 到 和 大 对 對 就" + " 我 时 時 有 来 為 要 說" + " 说 |" + " 主 些 因 它 想 意 理 生" + " 當 看 着 置 者 自 著 裡" + " 过 还 进 進 過 道 還 里" + " 面" #ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT AF_BLUE_STRING_CJK_LEFT - "些们你來們到和地" - "她将將就年得情最" - "样樣理能說说这這" - "通 |" - "即吗吧听呢品响嗎" - "师師收断斷明眼間" - "间际陈限除陳随際" - "隨" + " 些 们 你 來 們 到 和 地" + " 她 将 將 就 年 得 情 最" + " 样 樣 理 能 說 说 这 這" + " 通 |" + " 即 吗 吧 听 呢 品 响 嗎" + " 师 師 收 断 斷 明 眼 間" + " 间 际 陈 限 除 陳 随 際" + " 隨" AF_BLUE_STRING_CJK_RIGHT - "事前學将將情想或" - "政斯新样樣民沒没" - "然特现現球第經谁" - "起 |" - "例別别制动動吗嗎" - "增指明朝期构物确" - "种調调費费那都間" - "间" + "事 前 學 将 將 情 想 或" + " 政 斯 新 样 樣 民 沒 没" + " 然 特 现 現 球 第 經 谁" + " 起 |" + " 例 別 别 制 动 動 吗 嗎" + " 增 指 明 朝 期 构 物 确" + " 种 調 调 費 费 那 都 間" + " 间" #endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */ @@ -262,6 +579,14 @@ AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN: // respectively. Only horizontal blue zones (i.e., adjusting vertical // coordinate values) are supported. // +// Some scripts like Khmer need character composition to get all necessary +// blue zones, since Unicode only provides an abstract data model that +// doesn't represent all possible glyph shapes. For such character +// clusters, the HarfBuzz library is used to convert them into the +// corresponding glyphs. The largest glyph element (where `largest' can be +// either `largest ascender' or `largest descender') then defines the +// corresponding flat or round extremum. +// // For the latin auto-hinter, the overshoot should be larger than the // reference for top zones, and vice versa for bottom zones. // @@ -272,6 +597,21 @@ AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN: // // If not set, take the minimum values. // +// Mutually exclusive with `LATIN_SUB_TOP'. +// +// LATIN_SUB_TOP +// For all glyphs of a character cluster, compute the maximum flat +// and round coordinate values of each component, then take the +// smallest of the maximum values. The idea is to get the top of +// subscript glyphs, as used in Khmer, for example. Note that +// this mechanism doesn't work for ordinary ligatures. +// +// This flags indicates a secondary blue zone: It gets removed if +// there is a non-LATIN_SUB_TOP blue zone at the same coordinate +// value (after scaling). +// +// Mutually exclusive with `LATIN_TOP'. +// // LATIN_NEUTRAL // Ignore round extrema and define the blue zone with flat values only. // Both top and bottom of contours can match. This is useful for @@ -307,11 +647,11 @@ AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN: // // Characters in a blue string are *not* automatically classified. Instead, // first come the characters used for the overshoot value, then the -// character `|', then the characters used for the reference value. The -// blue zone is then set up by the mean values of all reference values and -// all overshoot values, respectively. Both horizontal and vertical blue -// zones (i.e., adjusting vertical and horizontal coordinate values, -// respectively) are supported. +// character `|', then the characters used for the reference value +// (everything separated by space characters). The blue zone is then set up +// by the mean values of all reference values and all overshoot values, +// respectively. Both horizontal and vertical blue zones (i.e., adjusting +// vertical and horizontal coordinate values, respectively) are supported. // // For the cjk auto-hinter, the overshoot should be smaller than the // reference for top zones, and vice versa for bottom zones. @@ -331,12 +671,103 @@ AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN: AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN: + AF_BLUE_STRINGSET_ADLM + { AF_BLUE_STRING_ADLAM_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_ADLAM_CAPITAL_BOTTOM, 0 } + { AF_BLUE_STRING_ADLAM_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_ADLAM_SMALL_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + AF_BLUE_STRINGSET_ARAB { AF_BLUE_STRING_ARABIC_TOP, AF_BLUE_PROPERTY_LATIN_TOP } { AF_BLUE_STRING_ARABIC_BOTTOM, 0 } { AF_BLUE_STRING_ARABIC_JOIN, AF_BLUE_PROPERTY_LATIN_NEUTRAL } { AF_BLUE_STRING_MAX, 0 } + AF_BLUE_STRINGSET_ARMN + { AF_BLUE_STRING_ARMENIAN_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_ARMENIAN_CAPITAL_BOTTOM, 0 } + { AF_BLUE_STRING_ARMENIAN_SMALL_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_ARMENIAN_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_ARMENIAN_SMALL_BOTTOM, 0 } + { AF_BLUE_STRING_ARMENIAN_SMALL_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_AVST + { AF_BLUE_STRING_AVESTAN_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_AVESTAN_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_BAMU + { AF_BLUE_STRING_BAMUM_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_BAMUM_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_BENG + { AF_BLUE_STRING_BENGALI_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_BENGALI_HEAD, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_BENGALI_BASE, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_NEUTRAL | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_BENGALI_BASE, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_BUHD + { AF_BLUE_STRING_BUHID_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_BUHID_LARGE, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_BUHID_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_BUHID_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_CAKM + { AF_BLUE_STRING_CHAKMA_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_CHAKMA_BOTTOM, 0 } + { AF_BLUE_STRING_CHAKMA_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_CANS + { AF_BLUE_STRING_CANADIAN_SYLLABICS_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_CANADIAN_SYLLABICS_BOTTOM, 0 } + { AF_BLUE_STRING_CANADIAN_SYLLABICS_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_CANADIAN_SYLLABICS_SMALL_BOTTOM, 0 } + { AF_BLUE_STRING_CANADIAN_SYLLABICS_SUPS_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_CANADIAN_SYLLABICS_SUPS_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_CARI + { AF_BLUE_STRING_CARIAN_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_CARIAN_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_CHER + { AF_BLUE_STRING_CHEROKEE_CAPITAL, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_CHEROKEE_CAPITAL, 0 } + { AF_BLUE_STRING_CHEROKEE_SMALL_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_CHEROKEE_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_CHEROKEE_SMALL, 0 } + { AF_BLUE_STRING_CHEROKEE_SMALL_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_COPT + { AF_BLUE_STRING_COPTIC_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_COPTIC_CAPITAL_BOTTOM, 0 } + { AF_BLUE_STRING_COPTIC_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_COPTIC_SMALL_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_CPRT + { AF_BLUE_STRING_CYPRIOT_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_CYPRIOT_BOTTOM, 0 } + { AF_BLUE_STRING_CYPRIOT_SMALL, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_CYPRIOT_SMALL, 0 } + { AF_BLUE_STRING_MAX, 0 } + AF_BLUE_STRINGSET_CYRL { AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } { AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM, 0 } @@ -356,6 +787,52 @@ AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN: { AF_BLUE_STRING_DEVANAGARI_BOTTOM, 0 } { AF_BLUE_STRING_MAX, 0 } + AF_BLUE_STRINGSET_DSRT + { AF_BLUE_STRING_DESERET_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_DESERET_CAPITAL_BOTTOM, 0 } + { AF_BLUE_STRING_DESERET_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_DESERET_SMALL_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_ETHI + { AF_BLUE_STRING_ETHIOPIC_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_ETHIOPIC_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_GEOR + { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_BOTTOM, 0 } + { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_GEORGIAN_MKHEDRULI_DESCENDER, 0 } + { AF_BLUE_STRING_GEORGIAN_MTAVRULI_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_GEORGIAN_MTAVRULI_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_GEOK + { AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_BOTTOM, 0 } + { AF_BLUE_STRING_GEORGIAN_NUSKHURI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_GEORGIAN_NUSKHURI_BOTTOM, 0 } + { AF_BLUE_STRING_GEORGIAN_NUSKHURI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_GEORGIAN_NUSKHURI_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_GLAG + { AF_BLUE_STRING_GLAGOLITIC_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_GLAGOLITIC_CAPITAL_BOTTOM, 0 } + { AF_BLUE_STRING_GLAGOLITIC_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_GLAGOLITIC_SMALL_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_GOTH + { AF_BLUE_STRING_GOTHIC_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_GOTHIC_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + AF_BLUE_STRINGSET_GREK { AF_BLUE_STRING_GREEK_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } { AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM, 0 } @@ -366,6 +843,25 @@ AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN: { AF_BLUE_STRING_GREEK_SMALL_DESCENDER, 0 } { AF_BLUE_STRING_MAX, 0 } + AF_BLUE_STRINGSET_GUJR + { AF_BLUE_STRING_GUJARATI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_GUJARATI_BOTTOM, 0 } + { AF_BLUE_STRING_GUJARATI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_GUJARATI_DESCENDER, 0 } + { AF_BLUE_STRING_GUJARATI_DIGIT_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_GURU + { AF_BLUE_STRING_GURMUKHI_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_GURMUKHI_HEAD, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_GURMUKHI_BASE, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_NEUTRAL | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_GURMUKHI_BOTTOM, 0 } + { AF_BLUE_STRING_GURMUKHI_DIGIT_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_MAX, 0 } + AF_BLUE_STRINGSET_HEBR { AF_BLUE_STRING_HEBREW_TOP, AF_BLUE_PROPERTY_LATIN_TOP | AF_BLUE_PROPERTY_LATIN_LONG } @@ -373,22 +869,51 @@ AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN: { AF_BLUE_STRING_HEBREW_DESCENDER, 0 } { AF_BLUE_STRING_MAX, 0 } + AF_BLUE_STRINGSET_KALI + { AF_BLUE_STRING_KAYAH_LI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_KAYAH_LI_BOTTOM, 0 } + { AF_BLUE_STRING_KAYAH_LI_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_KAYAH_LI_DESCENDER, 0 } + { AF_BLUE_STRING_KAYAH_LI_LARGE_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_KHMR + { AF_BLUE_STRING_KHMER_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_KHMER_SUBSCRIPT_TOP, AF_BLUE_PROPERTY_LATIN_SUB_TOP } + { AF_BLUE_STRING_KHMER_BOTTOM, 0 } + { AF_BLUE_STRING_KHMER_DESCENDER, 0 } + { AF_BLUE_STRING_KHMER_LARGE_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_KHMS + { AF_BLUE_STRING_KHMER_SYMBOLS_WAXING_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_KNDA + { AF_BLUE_STRING_KANNADA_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_KANNADA_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + AF_BLUE_STRINGSET_LAO - { AF_BLUE_STRING_LAO_TOP, AF_BLUE_PROPERTY_LATIN_TOP | - AF_BLUE_PROPERTY_LATIN_X_HEIGHT } - { AF_BLUE_STRING_LAO_BOTTOM, 0 } - { AF_BLUE_STRING_LAO_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } - { AF_BLUE_STRING_LAO_LARGE_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } - { AF_BLUE_STRING_LAO_DESCENDER, 0 } - { AF_BLUE_STRING_MAX, 0 } + { AF_BLUE_STRING_LAO_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_LAO_BOTTOM, 0 } + { AF_BLUE_STRING_LAO_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_LAO_LARGE_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_LAO_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } AF_BLUE_STRINGSET_LATN { AF_BLUE_STRING_LATIN_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } { AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM, 0 } { AF_BLUE_STRING_LATIN_SMALL_F_TOP, AF_BLUE_PROPERTY_LATIN_TOP } - { AF_BLUE_STRING_LATIN_SMALL, AF_BLUE_PROPERTY_LATIN_TOP | + { AF_BLUE_STRING_LATIN_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP | AF_BLUE_PROPERTY_LATIN_X_HEIGHT } - { AF_BLUE_STRING_LATIN_SMALL, 0 } + { AF_BLUE_STRING_LATIN_SMALL_BOTTOM, 0 } { AF_BLUE_STRING_LATIN_SMALL_DESCENDER, 0 } { AF_BLUE_STRING_MAX, 0 } @@ -412,11 +937,107 @@ AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN: { AF_BLUE_STRING_LATIN_SUPS_SMALL_DESCENDER, 0 } { AF_BLUE_STRING_MAX, 0 } + AF_BLUE_STRINGSET_LISU + { AF_BLUE_STRING_LISU_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_LISU_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_MLYM + { AF_BLUE_STRING_MALAYALAM_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_MALAYALAM_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_MYMR + { AF_BLUE_STRING_MYANMAR_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_MYANMAR_BOTTOM, 0 } + { AF_BLUE_STRING_MYANMAR_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_MYANMAR_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_NKOO + { AF_BLUE_STRING_NKO_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_NKO_BOTTOM, 0 } + { AF_BLUE_STRING_NKO_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_NKO_SMALL_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_NONE + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_OLCK + { AF_BLUE_STRING_OL_CHIKI, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_OL_CHIKI, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_ORKH + { AF_BLUE_STRING_OLD_TURKIC_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_OLD_TURKIC_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_OSGE + { AF_BLUE_STRING_OSAGE_CAPITAL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_OSAGE_CAPITAL_BOTTOM, 0 } + { AF_BLUE_STRING_OSAGE_CAPITAL_DESCENDER, 0 } + { AF_BLUE_STRING_OSAGE_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_OSAGE_SMALL_BOTTOM, 0 } + { AF_BLUE_STRING_OSAGE_SMALL_ASCENDER, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_OSAGE_SMALL_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_OSMA + { AF_BLUE_STRING_OSMANYA_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_OSMANYA_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_SAUR + { AF_BLUE_STRING_SAURASHTRA_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_SAURASHTRA_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_SHAW + { AF_BLUE_STRING_SHAVIAN_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_SHAVIAN_BOTTOM, 0 } + { AF_BLUE_STRING_SHAVIAN_DESCENDER, 0 } + { AF_BLUE_STRING_SHAVIAN_SMALL_TOP, AF_BLUE_PROPERTY_LATIN_TOP | + AF_BLUE_PROPERTY_LATIN_X_HEIGHT } + { AF_BLUE_STRING_SHAVIAN_SMALL_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_SINH + { AF_BLUE_STRING_SINHALA_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_SINHALA_BOTTOM, 0 } + { AF_BLUE_STRING_SINHALA_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_SUND + { AF_BLUE_STRING_SUNDANESE_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_SUNDANESE_BOTTOM, 0 } + { AF_BLUE_STRING_SUNDANESE_DESCENDER, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_TAML + { AF_BLUE_STRING_TAMIL_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_TAMIL_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + + AF_BLUE_STRINGSET_TAVT + { AF_BLUE_STRING_TAI_VIET_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_TAI_VIET_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } + AF_BLUE_STRINGSET_TELU { AF_BLUE_STRING_TELUGU_TOP, AF_BLUE_PROPERTY_LATIN_TOP } { AF_BLUE_STRING_TELUGU_BOTTOM, 0 } { AF_BLUE_STRING_MAX, 0 } + AF_BLUE_STRINGSET_TFNG + { AF_BLUE_STRING_TIFINAGH, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_TIFINAGH, 0 } + { AF_BLUE_STRING_MAX, 0 } + AF_BLUE_STRINGSET_THAI { AF_BLUE_STRING_THAI_TOP, AF_BLUE_PROPERTY_LATIN_TOP | AF_BLUE_PROPERTY_LATIN_X_HEIGHT } @@ -428,6 +1049,10 @@ AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN: { AF_BLUE_STRING_THAI_DIGIT_TOP, 0 } { AF_BLUE_STRING_MAX, 0 } + AF_BLUE_STRINGSET_VAII + { AF_BLUE_STRING_VAI_TOP, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_VAI_BOTTOM, 0 } + { AF_BLUE_STRING_MAX, 0 } #ifdef AF_CONFIG_OPTION_CJK diff --git a/src/3rdparty/freetype/src/autofit/afblue.h b/src/3rdparty/freetype/src/autofit/afblue.h index c26a9c792b..de31e259c3 100644 --- a/src/3rdparty/freetype/src/autofit/afblue.h +++ b/src/3rdparty/freetype/src/autofit/afblue.h @@ -7,7 +7,7 @@ /* */ /* Auto-fitter data for blue strings (specification). */ /* */ -/* Copyright 2013-2015 by */ +/* Copyright 2013-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,8 +19,8 @@ /***************************************************************************/ -#ifndef __AFBLUE_H__ -#define __AFBLUE_H__ +#ifndef AFBLUE_H_ +#define AFBLUE_H_ FT_BEGIN_HEADER @@ -28,32 +28,35 @@ FT_BEGIN_HEADER /* an auxiliary macro to decode a UTF-8 character -- since we only use */ /* hard-coded, self-converted data, no error checking is performed */ -#define GET_UTF8_CHAR( ch, p ) \ - ch = (unsigned char)*p++; \ - if ( ch >= 0x80 ) \ - { \ - FT_UInt len; \ - \ - \ - if ( ch < 0xE0 ) \ - { \ - len = 1; \ - ch &= 0x1F; \ - } \ - else if ( ch < 0xF0 ) \ - { \ - len = 2; \ - ch &= 0x0F; \ - } \ - else \ - { \ - len = 3; \ - ch &= 0x07; \ - } \ - \ - for ( ; len > 0; len-- ) \ - ch = ( ch << 6 ) | ( *p++ & 0x3F ); \ - } +#define GET_UTF8_CHAR( ch, p ) \ + do \ + { \ + ch = (unsigned char)*p++; \ + if ( ch >= 0x80 ) \ + { \ + FT_UInt len_; \ + \ + \ + if ( ch < 0xE0 ) \ + { \ + len_ = 1; \ + ch &= 0x1F; \ + } \ + else if ( ch < 0xF0 ) \ + { \ + len_ = 2; \ + ch &= 0x0F; \ + } \ + else \ + { \ + len_ = 3; \ + ch &= 0x07; \ + } \ + \ + for ( ; len_ > 0; len_-- ) \ + ch = ( ch << 6 ) | ( *p++ & 0x3F ); \ + } \ + } while ( 0 ) /*************************************************************************/ @@ -74,63 +77,199 @@ FT_BEGIN_HEADER typedef enum AF_Blue_String_ { - AF_BLUE_STRING_ARABIC_TOP = 0, - AF_BLUE_STRING_ARABIC_BOTTOM = 13, - AF_BLUE_STRING_ARABIC_JOIN = 24, - AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP = 27, - AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM = 44, - AF_BLUE_STRING_CYRILLIC_SMALL = 61, - AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER = 78, - AF_BLUE_STRING_DEVANAGARI_BASE = 85, - AF_BLUE_STRING_DEVANAGARI_TOP = 110, - AF_BLUE_STRING_DEVANAGARI_HEAD = 135, - AF_BLUE_STRING_DEVANAGARI_BOTTOM = 160, - AF_BLUE_STRING_GREEK_CAPITAL_TOP = 167, - AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM = 182, - AF_BLUE_STRING_GREEK_SMALL_BETA_TOP = 195, - AF_BLUE_STRING_GREEK_SMALL = 208, - AF_BLUE_STRING_GREEK_SMALL_DESCENDER = 225, - AF_BLUE_STRING_HEBREW_TOP = 242, - AF_BLUE_STRING_HEBREW_BOTTOM = 259, - AF_BLUE_STRING_HEBREW_DESCENDER = 272, - AF_BLUE_STRING_LAO_TOP = 283, - AF_BLUE_STRING_LAO_BOTTOM = 308, - AF_BLUE_STRING_LAO_ASCENDER = 333, - AF_BLUE_STRING_LAO_LARGE_ASCENDER = 346, - AF_BLUE_STRING_LAO_DESCENDER = 356, - AF_BLUE_STRING_LATIN_CAPITAL_TOP = 375, - AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM = 384, - AF_BLUE_STRING_LATIN_SMALL_F_TOP = 393, - AF_BLUE_STRING_LATIN_SMALL = 401, - AF_BLUE_STRING_LATIN_SMALL_DESCENDER = 409, - AF_BLUE_STRING_LATIN_SUBS_CAPITAL_TOP = 415, - AF_BLUE_STRING_LATIN_SUBS_CAPITAL_BOTTOM = 431, - AF_BLUE_STRING_LATIN_SUBS_SMALL_F_TOP = 447, - AF_BLUE_STRING_LATIN_SUBS_SMALL = 463, - AF_BLUE_STRING_LATIN_SUBS_SMALL_DESCENDER = 491, - AF_BLUE_STRING_LATIN_SUPS_CAPITAL_TOP = 507, - AF_BLUE_STRING_LATIN_SUPS_CAPITAL_BOTTOM = 531, - AF_BLUE_STRING_LATIN_SUPS_SMALL_F_TOP = 553, - AF_BLUE_STRING_LATIN_SUPS_SMALL = 573, - AF_BLUE_STRING_LATIN_SUPS_SMALL_DESCENDER = 592, - AF_BLUE_STRING_TELUGU_TOP = 601, - AF_BLUE_STRING_TELUGU_BOTTOM = 623, - AF_BLUE_STRING_THAI_TOP = 645, - AF_BLUE_STRING_THAI_BOTTOM = 664, - AF_BLUE_STRING_THAI_ASCENDER = 686, - AF_BLUE_STRING_THAI_LARGE_ASCENDER = 696, - AF_BLUE_STRING_THAI_DESCENDER = 706, - AF_BLUE_STRING_THAI_LARGE_DESCENDER = 719, - AF_BLUE_STRING_THAI_DIGIT_TOP = 726, - af_blue_1_1 = 735, + AF_BLUE_STRING_ADLAM_CAPITAL_TOP = 0, + AF_BLUE_STRING_ADLAM_CAPITAL_BOTTOM = 30, + AF_BLUE_STRING_ADLAM_SMALL_TOP = 40, + AF_BLUE_STRING_ADLAM_SMALL_BOTTOM = 65, + AF_BLUE_STRING_ARABIC_TOP = 105, + AF_BLUE_STRING_ARABIC_BOTTOM = 123, + AF_BLUE_STRING_ARABIC_JOIN = 138, + AF_BLUE_STRING_ARMENIAN_CAPITAL_TOP = 141, + AF_BLUE_STRING_ARMENIAN_CAPITAL_BOTTOM = 165, + AF_BLUE_STRING_ARMENIAN_SMALL_ASCENDER = 189, + AF_BLUE_STRING_ARMENIAN_SMALL_TOP = 210, + AF_BLUE_STRING_ARMENIAN_SMALL_BOTTOM = 234, + AF_BLUE_STRING_ARMENIAN_SMALL_DESCENDER = 258, + AF_BLUE_STRING_AVESTAN_TOP = 282, + AF_BLUE_STRING_AVESTAN_BOTTOM = 302, + AF_BLUE_STRING_BAMUM_TOP = 312, + AF_BLUE_STRING_BAMUM_BOTTOM = 344, + AF_BLUE_STRING_BENGALI_BASE = 376, + AF_BLUE_STRING_BENGALI_TOP = 408, + AF_BLUE_STRING_BENGALI_HEAD = 436, + AF_BLUE_STRING_BUHID_TOP = 468, + AF_BLUE_STRING_BUHID_LARGE = 476, + AF_BLUE_STRING_BUHID_SMALL = 488, + AF_BLUE_STRING_BUHID_BOTTOM = 504, + AF_BLUE_STRING_CANADIAN_SYLLABICS_TOP = 532, + AF_BLUE_STRING_CANADIAN_SYLLABICS_BOTTOM = 564, + AF_BLUE_STRING_CANADIAN_SYLLABICS_SMALL_TOP = 596, + AF_BLUE_STRING_CANADIAN_SYLLABICS_SMALL_BOTTOM = 628, + AF_BLUE_STRING_CANADIAN_SYLLABICS_SUPS_TOP = 660, + AF_BLUE_STRING_CANADIAN_SYLLABICS_SUPS_BOTTOM = 688, + AF_BLUE_STRING_CARIAN_TOP = 720, + AF_BLUE_STRING_CARIAN_BOTTOM = 760, + AF_BLUE_STRING_CHAKMA_TOP = 795, + AF_BLUE_STRING_CHAKMA_BOTTOM = 820, + AF_BLUE_STRING_CHAKMA_DESCENDER = 845, + AF_BLUE_STRING_CHEROKEE_CAPITAL = 910, + AF_BLUE_STRING_CHEROKEE_SMALL_ASCENDER = 942, + AF_BLUE_STRING_CHEROKEE_SMALL = 974, + AF_BLUE_STRING_CHEROKEE_SMALL_DESCENDER = 1006, + AF_BLUE_STRING_COPTIC_CAPITAL_TOP = 1022, + AF_BLUE_STRING_COPTIC_CAPITAL_BOTTOM = 1054, + AF_BLUE_STRING_COPTIC_SMALL_TOP = 1086, + AF_BLUE_STRING_COPTIC_SMALL_BOTTOM = 1118, + AF_BLUE_STRING_CYPRIOT_TOP = 1150, + AF_BLUE_STRING_CYPRIOT_BOTTOM = 1190, + AF_BLUE_STRING_CYPRIOT_SMALL = 1225, + AF_BLUE_STRING_CYRILLIC_CAPITAL_TOP = 1240, + AF_BLUE_STRING_CYRILLIC_CAPITAL_BOTTOM = 1264, + AF_BLUE_STRING_CYRILLIC_SMALL = 1288, + AF_BLUE_STRING_CYRILLIC_SMALL_DESCENDER = 1312, + AF_BLUE_STRING_DESERET_CAPITAL_TOP = 1321, + AF_BLUE_STRING_DESERET_CAPITAL_BOTTOM = 1346, + AF_BLUE_STRING_DESERET_SMALL_TOP = 1371, + AF_BLUE_STRING_DESERET_SMALL_BOTTOM = 1396, + AF_BLUE_STRING_DEVANAGARI_BASE = 1421, + AF_BLUE_STRING_DEVANAGARI_TOP = 1453, + AF_BLUE_STRING_DEVANAGARI_HEAD = 1485, + AF_BLUE_STRING_DEVANAGARI_BOTTOM = 1517, + AF_BLUE_STRING_ETHIOPIC_TOP = 1525, + AF_BLUE_STRING_ETHIOPIC_BOTTOM = 1557, + AF_BLUE_STRING_GEORGIAN_MKHEDRULI_TOP = 1589, + AF_BLUE_STRING_GEORGIAN_MKHEDRULI_BOTTOM = 1621, + AF_BLUE_STRING_GEORGIAN_MKHEDRULI_ASCENDER = 1653, + AF_BLUE_STRING_GEORGIAN_MKHEDRULI_DESCENDER = 1685, + AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_TOP = 1717, + AF_BLUE_STRING_GEORGIAN_ASOMTAVRULI_BOTTOM = 1749, + AF_BLUE_STRING_GEORGIAN_NUSKHURI_TOP = 1781, + AF_BLUE_STRING_GEORGIAN_NUSKHURI_BOTTOM = 1813, + AF_BLUE_STRING_GEORGIAN_NUSKHURI_ASCENDER = 1845, + AF_BLUE_STRING_GEORGIAN_NUSKHURI_DESCENDER = 1877, + AF_BLUE_STRING_GEORGIAN_MTAVRULI_TOP = 1909, + AF_BLUE_STRING_GEORGIAN_MTAVRULI_BOTTOM = 1941, + AF_BLUE_STRING_GLAGOLITIC_CAPITAL_TOP = 1973, + AF_BLUE_STRING_GLAGOLITIC_CAPITAL_BOTTOM = 2005, + AF_BLUE_STRING_GLAGOLITIC_SMALL_TOP = 2037, + AF_BLUE_STRING_GLAGOLITIC_SMALL_BOTTOM = 2069, + AF_BLUE_STRING_GOTHIC_TOP = 2101, + AF_BLUE_STRING_GOTHIC_BOTTOM = 2141, + AF_BLUE_STRING_GREEK_CAPITAL_TOP = 2161, + AF_BLUE_STRING_GREEK_CAPITAL_BOTTOM = 2182, + AF_BLUE_STRING_GREEK_SMALL_BETA_TOP = 2200, + AF_BLUE_STRING_GREEK_SMALL = 2218, + AF_BLUE_STRING_GREEK_SMALL_DESCENDER = 2242, + AF_BLUE_STRING_GUJARATI_TOP = 2266, + AF_BLUE_STRING_GUJARATI_BOTTOM = 2298, + AF_BLUE_STRING_GUJARATI_ASCENDER = 2330, + AF_BLUE_STRING_GUJARATI_DESCENDER = 2380, + AF_BLUE_STRING_GUJARATI_DIGIT_TOP = 2413, + AF_BLUE_STRING_GURMUKHI_BASE = 2433, + AF_BLUE_STRING_GURMUKHI_HEAD = 2465, + AF_BLUE_STRING_GURMUKHI_TOP = 2497, + AF_BLUE_STRING_GURMUKHI_BOTTOM = 2529, + AF_BLUE_STRING_GURMUKHI_DIGIT_TOP = 2561, + AF_BLUE_STRING_HEBREW_TOP = 2581, + AF_BLUE_STRING_HEBREW_BOTTOM = 2605, + AF_BLUE_STRING_HEBREW_DESCENDER = 2623, + AF_BLUE_STRING_KANNADA_TOP = 2638, + AF_BLUE_STRING_KANNADA_BOTTOM = 2682, + AF_BLUE_STRING_KAYAH_LI_TOP = 2714, + AF_BLUE_STRING_KAYAH_LI_BOTTOM = 2738, + AF_BLUE_STRING_KAYAH_LI_ASCENDER = 2758, + AF_BLUE_STRING_KAYAH_LI_DESCENDER = 2766, + AF_BLUE_STRING_KAYAH_LI_LARGE_DESCENDER = 2778, + AF_BLUE_STRING_KHMER_TOP = 2799, + AF_BLUE_STRING_KHMER_SUBSCRIPT_TOP = 2823, + AF_BLUE_STRING_KHMER_BOTTOM = 2863, + AF_BLUE_STRING_KHMER_DESCENDER = 2895, + AF_BLUE_STRING_KHMER_LARGE_DESCENDER = 2929, + AF_BLUE_STRING_KHMER_SYMBOLS_WAXING_TOP = 3016, + AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM = 3024, + AF_BLUE_STRING_LAO_TOP = 3032, + AF_BLUE_STRING_LAO_BOTTOM = 3064, + AF_BLUE_STRING_LAO_ASCENDER = 3096, + AF_BLUE_STRING_LAO_LARGE_ASCENDER = 3112, + AF_BLUE_STRING_LAO_DESCENDER = 3124, + AF_BLUE_STRING_LATIN_CAPITAL_TOP = 3148, + AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM = 3164, + AF_BLUE_STRING_LATIN_SMALL_F_TOP = 3180, + AF_BLUE_STRING_LATIN_SMALL_TOP = 3194, + AF_BLUE_STRING_LATIN_SMALL_BOTTOM = 3210, + AF_BLUE_STRING_LATIN_SMALL_DESCENDER = 3226, + AF_BLUE_STRING_LATIN_SUBS_CAPITAL_TOP = 3236, + AF_BLUE_STRING_LATIN_SUBS_CAPITAL_BOTTOM = 3256, + AF_BLUE_STRING_LATIN_SUBS_SMALL_F_TOP = 3276, + AF_BLUE_STRING_LATIN_SUBS_SMALL = 3296, + AF_BLUE_STRING_LATIN_SUBS_SMALL_DESCENDER = 3332, + AF_BLUE_STRING_LATIN_SUPS_CAPITAL_TOP = 3352, + AF_BLUE_STRING_LATIN_SUPS_CAPITAL_BOTTOM = 3383, + AF_BLUE_STRING_LATIN_SUPS_SMALL_F_TOP = 3412, + AF_BLUE_STRING_LATIN_SUPS_SMALL = 3438, + AF_BLUE_STRING_LATIN_SUPS_SMALL_DESCENDER = 3463, + AF_BLUE_STRING_LISU_TOP = 3474, + AF_BLUE_STRING_LISU_BOTTOM = 3506, + AF_BLUE_STRING_MALAYALAM_TOP = 3538, + AF_BLUE_STRING_MALAYALAM_BOTTOM = 3582, + AF_BLUE_STRING_MYANMAR_TOP = 3614, + AF_BLUE_STRING_MYANMAR_BOTTOM = 3646, + AF_BLUE_STRING_MYANMAR_ASCENDER = 3678, + AF_BLUE_STRING_MYANMAR_DESCENDER = 3706, + AF_BLUE_STRING_NKO_TOP = 3738, + AF_BLUE_STRING_NKO_BOTTOM = 3762, + AF_BLUE_STRING_NKO_SMALL_TOP = 3777, + AF_BLUE_STRING_NKO_SMALL_BOTTOM = 3786, + AF_BLUE_STRING_OL_CHIKI = 3798, + AF_BLUE_STRING_OLD_TURKIC_TOP = 3822, + AF_BLUE_STRING_OLD_TURKIC_BOTTOM = 3837, + AF_BLUE_STRING_OSAGE_CAPITAL_TOP = 3857, + AF_BLUE_STRING_OSAGE_CAPITAL_BOTTOM = 3897, + AF_BLUE_STRING_OSAGE_CAPITAL_DESCENDER = 3927, + AF_BLUE_STRING_OSAGE_SMALL_TOP = 3942, + AF_BLUE_STRING_OSAGE_SMALL_BOTTOM = 3982, + AF_BLUE_STRING_OSAGE_SMALL_ASCENDER = 4022, + AF_BLUE_STRING_OSAGE_SMALL_DESCENDER = 4047, + AF_BLUE_STRING_OSMANYA_TOP = 4062, + AF_BLUE_STRING_OSMANYA_BOTTOM = 4102, + AF_BLUE_STRING_SAURASHTRA_TOP = 4142, + AF_BLUE_STRING_SAURASHTRA_BOTTOM = 4174, + AF_BLUE_STRING_SHAVIAN_TOP = 4194, + AF_BLUE_STRING_SHAVIAN_BOTTOM = 4204, + AF_BLUE_STRING_SHAVIAN_DESCENDER = 4229, + AF_BLUE_STRING_SHAVIAN_SMALL_TOP = 4239, + AF_BLUE_STRING_SHAVIAN_SMALL_BOTTOM = 4274, + AF_BLUE_STRING_SINHALA_TOP = 4289, + AF_BLUE_STRING_SINHALA_BOTTOM = 4321, + AF_BLUE_STRING_SINHALA_DESCENDER = 4353, + AF_BLUE_STRING_SUNDANESE_TOP = 4397, + AF_BLUE_STRING_SUNDANESE_BOTTOM = 4421, + AF_BLUE_STRING_SUNDANESE_DESCENDER = 4453, + AF_BLUE_STRING_TAI_VIET_TOP = 4461, + AF_BLUE_STRING_TAI_VIET_BOTTOM = 4481, + AF_BLUE_STRING_TAMIL_TOP = 4493, + AF_BLUE_STRING_TAMIL_BOTTOM = 4525, + AF_BLUE_STRING_TELUGU_TOP = 4557, + AF_BLUE_STRING_TELUGU_BOTTOM = 4585, + AF_BLUE_STRING_THAI_TOP = 4613, + AF_BLUE_STRING_THAI_BOTTOM = 4637, + AF_BLUE_STRING_THAI_ASCENDER = 4665, + AF_BLUE_STRING_THAI_LARGE_ASCENDER = 4677, + AF_BLUE_STRING_THAI_DESCENDER = 4689, + AF_BLUE_STRING_THAI_LARGE_DESCENDER = 4705, + AF_BLUE_STRING_THAI_DIGIT_TOP = 4713, + AF_BLUE_STRING_TIFINAGH = 4725, + AF_BLUE_STRING_VAI_TOP = 4757, + AF_BLUE_STRING_VAI_BOTTOM = 4789, + af_blue_1_1 = 4820, #ifdef AF_CONFIG_OPTION_CJK AF_BLUE_STRING_CJK_TOP = af_blue_1_1 + 1, - AF_BLUE_STRING_CJK_BOTTOM = af_blue_1_1 + 153, - af_blue_1_1_1 = af_blue_1_1 + 304, + AF_BLUE_STRING_CJK_BOTTOM = af_blue_1_1 + 203, + af_blue_1_1_1 = af_blue_1_1 + 404, #ifdef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT AF_BLUE_STRING_CJK_LEFT = af_blue_1_1_1 + 1, - AF_BLUE_STRING_CJK_RIGHT = af_blue_1_1_1 + 153, - af_blue_1_1_2 = af_blue_1_1_1 + 304, + AF_BLUE_STRING_CJK_RIGHT = af_blue_1_1_1 + 204, + af_blue_1_1_2 = af_blue_1_1_1 + 405, #else af_blue_1_1_2 = af_blue_1_1_1 + 0, #endif /* AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT */ @@ -164,9 +303,10 @@ FT_BEGIN_HEADER /* blue string can't be used in more than a single writing system, which */ /* is a safe bet. */ #define AF_BLUE_PROPERTY_LATIN_TOP ( 1U << 0 ) /* must have value 1 */ -#define AF_BLUE_PROPERTY_LATIN_NEUTRAL ( 1U << 1 ) -#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT ( 1U << 2 ) -#define AF_BLUE_PROPERTY_LATIN_LONG ( 1U << 3 ) +#define AF_BLUE_PROPERTY_LATIN_SUB_TOP ( 1U << 1 ) +#define AF_BLUE_PROPERTY_LATIN_NEUTRAL ( 1U << 2 ) +#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT ( 1U << 3 ) +#define AF_BLUE_PROPERTY_LATIN_LONG ( 1U << 4 ) #define AF_BLUE_PROPERTY_CJK_TOP ( 1U << 0 ) /* must have value 1 */ #define AF_BLUE_PROPERTY_CJK_HORIZ ( 1U << 1 ) /* must have value 2 */ @@ -180,18 +320,59 @@ FT_BEGIN_HEADER typedef enum AF_Blue_Stringset_ { - AF_BLUE_STRINGSET_ARAB = 0, - AF_BLUE_STRINGSET_CYRL = 4, - AF_BLUE_STRINGSET_DEVA = 10, - AF_BLUE_STRINGSET_GREK = 16, - AF_BLUE_STRINGSET_HEBR = 23, - AF_BLUE_STRINGSET_LAO = 27, - AF_BLUE_STRINGSET_LATN = 33, - AF_BLUE_STRINGSET_LATB = 40, - AF_BLUE_STRINGSET_LATP = 47, - AF_BLUE_STRINGSET_TELU = 54, - AF_BLUE_STRINGSET_THAI = 57, - af_blue_2_1 = 65, + AF_BLUE_STRINGSET_ADLM = 0, + AF_BLUE_STRINGSET_ARAB = 5, + AF_BLUE_STRINGSET_ARMN = 9, + AF_BLUE_STRINGSET_AVST = 16, + AF_BLUE_STRINGSET_BAMU = 19, + AF_BLUE_STRINGSET_BENG = 22, + AF_BLUE_STRINGSET_BUHD = 27, + AF_BLUE_STRINGSET_CAKM = 32, + AF_BLUE_STRINGSET_CANS = 36, + AF_BLUE_STRINGSET_CARI = 43, + AF_BLUE_STRINGSET_CHER = 46, + AF_BLUE_STRINGSET_COPT = 53, + AF_BLUE_STRINGSET_CPRT = 58, + AF_BLUE_STRINGSET_CYRL = 63, + AF_BLUE_STRINGSET_DEVA = 69, + AF_BLUE_STRINGSET_DSRT = 75, + AF_BLUE_STRINGSET_ETHI = 80, + AF_BLUE_STRINGSET_GEOR = 83, + AF_BLUE_STRINGSET_GEOK = 90, + AF_BLUE_STRINGSET_GLAG = 97, + AF_BLUE_STRINGSET_GOTH = 102, + AF_BLUE_STRINGSET_GREK = 105, + AF_BLUE_STRINGSET_GUJR = 112, + AF_BLUE_STRINGSET_GURU = 118, + AF_BLUE_STRINGSET_HEBR = 124, + AF_BLUE_STRINGSET_KALI = 128, + AF_BLUE_STRINGSET_KHMR = 134, + AF_BLUE_STRINGSET_KHMS = 140, + AF_BLUE_STRINGSET_KNDA = 143, + AF_BLUE_STRINGSET_LAO = 146, + AF_BLUE_STRINGSET_LATN = 152, + AF_BLUE_STRINGSET_LATB = 159, + AF_BLUE_STRINGSET_LATP = 166, + AF_BLUE_STRINGSET_LISU = 173, + AF_BLUE_STRINGSET_MLYM = 176, + AF_BLUE_STRINGSET_MYMR = 179, + AF_BLUE_STRINGSET_NKOO = 184, + AF_BLUE_STRINGSET_NONE = 189, + AF_BLUE_STRINGSET_OLCK = 190, + AF_BLUE_STRINGSET_ORKH = 193, + AF_BLUE_STRINGSET_OSGE = 196, + AF_BLUE_STRINGSET_OSMA = 204, + AF_BLUE_STRINGSET_SAUR = 207, + AF_BLUE_STRINGSET_SHAW = 210, + AF_BLUE_STRINGSET_SINH = 216, + AF_BLUE_STRINGSET_SUND = 220, + AF_BLUE_STRINGSET_TAML = 224, + AF_BLUE_STRINGSET_TAVT = 227, + AF_BLUE_STRINGSET_TELU = 230, + AF_BLUE_STRINGSET_TFNG = 233, + AF_BLUE_STRINGSET_THAI = 236, + AF_BLUE_STRINGSET_VAII = 244, + af_blue_2_1 = 247, #ifdef AF_CONFIG_OPTION_CJK AF_BLUE_STRINGSET_HANI = af_blue_2_1 + 0, af_blue_2_1_1 = af_blue_2_1 + 2, @@ -227,7 +408,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __AFBLUE_H__ */ +#endif /* AFBLUE_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/autofit/afblue.hin b/src/3rdparty/freetype/src/autofit/afblue.hin index ad43fe6cef..682147cb30 100644 --- a/src/3rdparty/freetype/src/autofit/afblue.hin +++ b/src/3rdparty/freetype/src/autofit/afblue.hin @@ -4,7 +4,7 @@ /* */ /* Auto-fitter data for blue strings (specification). */ /* */ -/* Copyright 2013-2015 by */ +/* Copyright 2013-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __AFBLUE_H__ -#define __AFBLUE_H__ +#ifndef AFBLUE_H_ +#define AFBLUE_H_ FT_BEGIN_HEADER @@ -25,32 +25,35 @@ FT_BEGIN_HEADER /* an auxiliary macro to decode a UTF-8 character -- since we only use */ /* hard-coded, self-converted data, no error checking is performed */ -#define GET_UTF8_CHAR( ch, p ) \ - ch = (unsigned char)*p++; \ - if ( ch >= 0x80 ) \ - { \ - FT_UInt len; \ - \ - \ - if ( ch < 0xE0 ) \ - { \ - len = 1; \ - ch &= 0x1F; \ - } \ - else if ( ch < 0xF0 ) \ - { \ - len = 2; \ - ch &= 0x0F; \ - } \ - else \ - { \ - len = 3; \ - ch &= 0x07; \ - } \ - \ - for ( ; len > 0; len-- ) \ - ch = ( ch << 6 ) | ( *p++ & 0x3F ); \ - } +#define GET_UTF8_CHAR( ch, p ) \ + do \ + { \ + ch = (unsigned char)*p++; \ + if ( ch >= 0x80 ) \ + { \ + FT_UInt len_; \ + \ + \ + if ( ch < 0xE0 ) \ + { \ + len_ = 1; \ + ch &= 0x1F; \ + } \ + else if ( ch < 0xF0 ) \ + { \ + len_ = 2; \ + ch &= 0x0F; \ + } \ + else \ + { \ + len_ = 3; \ + ch &= 0x07; \ + } \ + \ + for ( ; len_ > 0; len_-- ) \ + ch = ( ch << 6 ) | ( *p++ & 0x3F ); \ + } \ + } while ( 0 ) /*************************************************************************/ @@ -97,9 +100,10 @@ FT_BEGIN_HEADER /* blue string can't be used in more than a single writing system, which */ /* is a safe bet. */ #define AF_BLUE_PROPERTY_LATIN_TOP ( 1U << 0 ) /* must have value 1 */ -#define AF_BLUE_PROPERTY_LATIN_NEUTRAL ( 1U << 1 ) -#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT ( 1U << 2 ) -#define AF_BLUE_PROPERTY_LATIN_LONG ( 1U << 3 ) +#define AF_BLUE_PROPERTY_LATIN_SUB_TOP ( 1U << 1 ) +#define AF_BLUE_PROPERTY_LATIN_NEUTRAL ( 1U << 2 ) +#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT ( 1U << 3 ) +#define AF_BLUE_PROPERTY_LATIN_LONG ( 1U << 4 ) #define AF_BLUE_PROPERTY_CJK_TOP ( 1U << 0 ) /* must have value 1 */ #define AF_BLUE_PROPERTY_CJK_HORIZ ( 1U << 1 ) /* must have value 2 */ @@ -136,7 +140,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __AFBLUE_H__ */ +#endif /* AFBLUE_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/autofit/afcjk.c b/src/3rdparty/freetype/src/autofit/afcjk.c index 0ade4be40b..21b6bffa33 100644 --- a/src/3rdparty/freetype/src/autofit/afcjk.c +++ b/src/3rdparty/freetype/src/autofit/afcjk.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines for CJK writing system (body). */ /* */ -/* Copyright 2006-2015 by */ +/* Copyright 2006-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,9 +16,9 @@ /***************************************************************************/ /* - * The algorithm is based on akito's autohint patch, available here: + * The algorithm is based on akito's autohint patch, archived at * - * http://www.kde.gr.jp/~akito/patch/freetype2/ + * https://web.archive.org/web/20051219160454/http://www.kde.gr.jp:80/~akito/patch/freetype2/2.1.7/ * */ @@ -29,13 +29,13 @@ #include "afglobal.h" #include "afpic.h" #include "aflatin.h" +#include "afcjk.h" #ifdef AF_CONFIG_OPTION_CJK #undef AF_CONFIG_OPTION_CJK_BLUE_HANI_VERT -#include "afcjk.h" #include "aferrors.h" @@ -88,7 +88,6 @@ { FT_Error error; FT_ULong glyph_index; - FT_Long y_offset; int dim; AF_CJKMetricsRec dummy[1]; AF_Scaler scaler = &dummy->root.scaler; @@ -101,45 +100,61 @@ AF_ScriptClass script_class = AF_SCRIPT_CLASSES_GET [style_class->script]; - FT_UInt32 standard_char; + void* shaper_buf; + const char* p; +#ifdef FT_DEBUG_LEVEL_TRACE + FT_ULong ch = 0; +#endif - standard_char = script_class->standard_char1; - af_get_char_index( &metrics->root, - standard_char, - &glyph_index, - &y_offset ); - if ( !glyph_index ) + p = script_class->standard_charstring; + shaper_buf = af_shaper_buf_create( face ); + + /* We check a list of standard characters. The first match wins. */ + + glyph_index = 0; + while ( *p ) { - if ( script_class->standard_char2 ) - { - standard_char = script_class->standard_char2; - af_get_char_index( &metrics->root, - standard_char, - &glyph_index, - &y_offset ); - if ( !glyph_index ) - { - if ( script_class->standard_char3 ) - { - standard_char = script_class->standard_char3; - af_get_char_index( &metrics->root, - standard_char, - &glyph_index, - &y_offset ); - if ( !glyph_index ) - goto Exit; - } - else - goto Exit; - } - } - else - goto Exit; + unsigned int num_idx; + +#ifdef FT_DEBUG_LEVEL_TRACE + const char* p_old; +#endif + + + while ( *p == ' ' ) + p++; + +#ifdef FT_DEBUG_LEVEL_TRACE + p_old = p; + GET_UTF8_CHAR( ch, p_old ); +#endif + + /* reject input that maps to more than a single glyph */ + p = af_shaper_get_cluster( p, &metrics->root, shaper_buf, &num_idx ); + if ( num_idx > 1 ) + continue; + + /* otherwise exit loop if we have a result */ + glyph_index = af_shaper_get_elem( &metrics->root, + shaper_buf, + 0, + NULL, + NULL ); + if ( glyph_index ) + break; } + af_shaper_buf_destroy( face, shaper_buf ); + + if ( !glyph_index ) + goto Exit; + + if ( !glyph_index ) + goto Exit; + FT_TRACE5(( "standard character: U+%04lX (glyph index %d)\n", - standard_char, glyph_index )); + ch, glyph_index )); error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); if ( error || face->glyph->outline.n_points <= 0 ) @@ -177,6 +192,12 @@ if ( error ) goto Exit; + /* + * We assume that the glyphs selected for the stem width + * computation are `featureless' enough so that the linking + * algorithm works fine without adjustments of its scoring + * function. + */ af_latin_hints_link_segments( hints, 0, NULL, @@ -275,6 +296,8 @@ AF_Blue_Stringset bss = sc->blue_stringset; const AF_Blue_StringRec* bs = &af_blue_stringsets[bss]; + void* shaper_buf; + /* we walk over the blue character strings as specified in the */ /* style's entry in the `af_blue_stringset' array, computing its */ @@ -284,6 +307,8 @@ "==========================\n" "\n" )); + shaper_buf = af_shaper_buf_create( face ); + for ( ; bs->string != AF_BLUE_STRING_MAX; bs++ ) { const char* p = &af_blue_strings[bs->string]; @@ -322,26 +347,47 @@ while ( *p ) { - FT_ULong ch; FT_ULong glyph_index; - FT_Long y_offset; FT_Pos best_pos; /* same as points.y or points.x, resp. */ FT_Int best_point; FT_Vector* points; + unsigned int num_idx; - GET_UTF8_CHAR( ch, p ); +#ifdef FT_DEBUG_LEVEL_TRACE + const char* p_old; + FT_ULong ch; +#endif + + + while ( *p == ' ' ) + p++; + +#ifdef FT_DEBUG_LEVEL_TRACE + p_old = p; + GET_UTF8_CHAR( ch, p_old ); +#endif /* switch to characters that define flat values */ - if ( ch == '|' ) + if ( *p == '|' ) { fill = 0; FT_TRACE5(( " [reference values]\n" )); + p++; continue; } + /* reject input that maps to more than a single glyph */ + p = af_shaper_get_cluster( p, &metrics->root, shaper_buf, &num_idx ); + if ( num_idx > 1 ) + continue; + /* load the character in the face -- skip unknown or empty ones */ - af_get_char_index( &metrics->root, ch, &glyph_index, &y_offset ); + glyph_index = af_shaper_get_elem( &metrics->root, + shaper_buf, + 0, + NULL, + NULL ); if ( glyph_index == 0 ) { FT_TRACE5(( " U+%04lX unavailable\n", ch )); @@ -350,9 +396,9 @@ error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); outline = face->glyph->outline; - if ( error || outline.n_points <= 0 ) + if ( error || outline.n_points <= 2 ) { - FT_TRACE5(( " U+%04lX contains no outlines\n", ch )); + FT_TRACE5(( " U+%04lX contains no (usable) outlines\n", ch )); continue; } @@ -431,7 +477,8 @@ fills[num_fills++] = best_pos; else flats[num_flats++] = best_pos; - } + + } /* end while loop */ if ( num_flats == 0 && num_fills == 0 ) { @@ -498,7 +545,10 @@ FT_TRACE5(( " -> reference = %ld\n" " overshoot = %ld\n", *blue_ref, *blue_shoot )); - } + + } /* end for loop */ + + af_shaper_buf_destroy( face, shaper_buf ); FT_TRACE5(( "\n" )); @@ -512,27 +562,36 @@ af_cjk_metrics_check_digits( AF_CJKMetrics metrics, FT_Face face ) { - FT_UInt i; FT_Bool started = 0, same_width = 1; - FT_Fixed advance, old_advance = 0; + FT_Fixed advance = 0, old_advance = 0; + + void* shaper_buf; + + /* in all supported charmaps, digits have character codes 0x30-0x39 */ + const char digits[] = "0 1 2 3 4 5 6 7 8 9"; + const char* p; - /* digit `0' is 0x30 in all supported charmaps */ - for ( i = 0x30; i <= 0x39; i++ ) + p = digits; + shaper_buf = af_shaper_buf_create( face ); + + while ( *p ) { - FT_ULong glyph_index; - FT_Long y_offset; + FT_ULong glyph_index; + unsigned int num_idx; - af_get_char_index( &metrics->root, i, &glyph_index, &y_offset ); - if ( glyph_index == 0 ) + /* reject input that maps to more than a single glyph */ + p = af_shaper_get_cluster( p, &metrics->root, shaper_buf, &num_idx ); + if ( num_idx > 1 ) continue; - if ( FT_Get_Advance( face, glyph_index, - FT_LOAD_NO_SCALE | - FT_LOAD_NO_HINTING | - FT_LOAD_IGNORE_TRANSFORM, - &advance ) ) + glyph_index = af_shaper_get_elem( &metrics->root, + shaper_buf, + 0, + &advance, + NULL ); + if ( !glyph_index ) continue; if ( started ) @@ -550,6 +609,8 @@ } } + af_shaper_buf_destroy( face, shaper_buf ); + metrics->root.digits_have_same_width = same_width; } @@ -688,6 +749,22 @@ } + /* Extract standard_width from writing system/script specific */ + /* metrics class. */ + + FT_LOCAL_DEF( void ) + af_cjk_get_standard_widths( AF_CJKMetrics metrics, + FT_Pos* stdHW, + FT_Pos* stdVW ) + { + if ( stdHW ) + *stdHW = metrics->axis[AF_DIMENSION_VERT].standard_width; + + if ( stdVW ) + *stdVW = metrics->axis[AF_DIMENSION_HORZ].standard_width; + } + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -889,15 +966,12 @@ if ( seg2 ) { - seg2->num_linked++; if ( seg2->link != seg1 ) { seg1->link = NULL; if ( seg2->score < dist_threshold || seg1->score < seg2->score * 4 ) seg1->serif = seg2->link; - else - seg2->num_linked--; } } } @@ -1014,7 +1088,7 @@ /* insert a new edge in the list and */ /* sort according to the position */ error = af_axis_hints_new_edge( axis, seg->pos, - (AF_Direction)seg->dir, + (AF_Direction)seg->dir, 0, memory, &edge ); if ( error ) goto Exit; @@ -1324,9 +1398,9 @@ other_flags |= AF_LATIN_HINTS_VERT_SNAP; /* - * We adjust stems to full pixels only if we don't use the `light' mode. + * We adjust stems to full pixels unless in `light' or `lcd' mode. */ - if ( mode != FT_RENDER_MODE_LIGHT ) + if ( mode != FT_RENDER_MODE_LIGHT && mode != FT_RENDER_MODE_LCD ) other_flags |= AF_LATIN_HINTS_STEM_ADJUST; if ( mode == FT_RENDER_MODE_MONO ) @@ -1451,7 +1525,7 @@ } if ( dist < 54 ) - dist += ( 54 - dist ) / 2 ; + dist += ( 54 - dist ) / 2; else if ( dist < 3 * 64 ) { FT_Pos delta; @@ -2198,13 +2272,7 @@ goto Exit; /* analyze glyph outline */ -#ifdef AF_CONFIG_OPTION_USE_WARPER - if ( ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT && - AF_HINTS_DO_WARP( hints ) ) || - AF_HINTS_DO_HORIZONTAL( hints ) ) -#else if ( AF_HINTS_DO_HORIZONTAL( hints ) ) -#endif { error = af_cjk_hints_detect_features( hints, AF_DIMENSION_HORZ ); if ( error ) @@ -2230,9 +2298,9 @@ { #ifdef AF_CONFIG_OPTION_USE_WARPER - if ( dim == AF_DIMENSION_HORZ && - metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT && - AF_HINTS_DO_WARP( hints ) ) + if ( dim == AF_DIMENSION_HORZ && + metrics->root.scaler.render_mode == FT_RENDER_MODE_NORMAL && + AF_HINTS_DO_WARP( hints ) ) { AF_WarperRec warper; FT_Fixed scale; @@ -2277,12 +2345,13 @@ sizeof ( AF_CJKMetricsRec ), - (AF_WritingSystem_InitMetricsFunc) af_cjk_metrics_init, - (AF_WritingSystem_ScaleMetricsFunc)af_cjk_metrics_scale, - (AF_WritingSystem_DoneMetricsFunc) NULL, + (AF_WritingSystem_InitMetricsFunc) af_cjk_metrics_init, /* style_metrics_init */ + (AF_WritingSystem_ScaleMetricsFunc)af_cjk_metrics_scale, /* style_metrics_scale */ + (AF_WritingSystem_DoneMetricsFunc) NULL, /* style_metrics_done */ + (AF_WritingSystem_GetStdWidthsFunc)af_cjk_get_standard_widths, /* style_metrics_getstdw */ - (AF_WritingSystem_InitHintsFunc) af_cjk_hints_init, - (AF_WritingSystem_ApplyHintsFunc) af_cjk_hints_apply + (AF_WritingSystem_InitHintsFunc) af_cjk_hints_init, /* style_hints_init */ + (AF_WritingSystem_ApplyHintsFunc) af_cjk_hints_apply /* style_hints_apply */ ) @@ -2296,12 +2365,13 @@ sizeof ( AF_CJKMetricsRec ), - (AF_WritingSystem_InitMetricsFunc) NULL, - (AF_WritingSystem_ScaleMetricsFunc)NULL, - (AF_WritingSystem_DoneMetricsFunc) NULL, + (AF_WritingSystem_InitMetricsFunc) NULL, /* style_metrics_init */ + (AF_WritingSystem_ScaleMetricsFunc)NULL, /* style_metrics_scale */ + (AF_WritingSystem_DoneMetricsFunc) NULL, /* style_metrics_done */ + (AF_WritingSystem_GetStdWidthsFunc)NULL, /* style_metrics_getstdw */ - (AF_WritingSystem_InitHintsFunc) NULL, - (AF_WritingSystem_ApplyHintsFunc) NULL + (AF_WritingSystem_InitHintsFunc) NULL, /* style_hints_init */ + (AF_WritingSystem_ApplyHintsFunc) NULL /* style_hints_apply */ ) diff --git a/src/3rdparty/freetype/src/autofit/afcjk.h b/src/3rdparty/freetype/src/autofit/afcjk.h index e395e74a01..d229c0c9cf 100644 --- a/src/3rdparty/freetype/src/autofit/afcjk.h +++ b/src/3rdparty/freetype/src/autofit/afcjk.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines for CJK writing system (specification). */ /* */ -/* Copyright 2006-2015 by */ +/* Copyright 2006-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __AFCJK_H__ -#define __AFCJK_H__ +#ifndef AFCJK_H_ +#define AFCJK_H_ #include "afhints.h" #include "aflatin.h" @@ -135,7 +135,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __AFCJK_H__ */ +#endif /* AFCJK_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/autofit/afcover.h b/src/3rdparty/freetype/src/autofit/afcover.h index 520e8a4ae0..6eeb8fc9fb 100644 --- a/src/3rdparty/freetype/src/autofit/afcover.h +++ b/src/3rdparty/freetype/src/autofit/afcover.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter coverages (specification only). */ /* */ -/* Copyright 2013-2015 by */ +/* Copyright 2013-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/src/autofit/afdummy.c b/src/3rdparty/freetype/src/autofit/afdummy.c index 18dd301d10..f30c517cbb 100644 --- a/src/3rdparty/freetype/src/autofit/afdummy.c +++ b/src/3rdparty/freetype/src/autofit/afdummy.c @@ -5,7 +5,7 @@ /* Auto-fitter dummy routines to be used if no hinting should be */ /* performed (body). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -62,12 +62,13 @@ sizeof ( AF_StyleMetricsRec ), - (AF_WritingSystem_InitMetricsFunc) NULL, - (AF_WritingSystem_ScaleMetricsFunc)NULL, - (AF_WritingSystem_DoneMetricsFunc) NULL, + (AF_WritingSystem_InitMetricsFunc) NULL, /* style_metrics_init */ + (AF_WritingSystem_ScaleMetricsFunc)NULL, /* style_metrics_scale */ + (AF_WritingSystem_DoneMetricsFunc) NULL, /* style_metrics_done */ + (AF_WritingSystem_GetStdWidthsFunc)NULL, /* style_metrics_getstdw */ - (AF_WritingSystem_InitHintsFunc) af_dummy_hints_init, - (AF_WritingSystem_ApplyHintsFunc) af_dummy_hints_apply + (AF_WritingSystem_InitHintsFunc) af_dummy_hints_init, /* style_hints_init */ + (AF_WritingSystem_ApplyHintsFunc) af_dummy_hints_apply /* style_hints_apply */ ) diff --git a/src/3rdparty/freetype/src/autofit/afdummy.h b/src/3rdparty/freetype/src/autofit/afdummy.h index b4fdc78e39..b382acd92a 100644 --- a/src/3rdparty/freetype/src/autofit/afdummy.h +++ b/src/3rdparty/freetype/src/autofit/afdummy.h @@ -5,7 +5,7 @@ /* Auto-fitter dummy routines to be used if no hinting should be */ /* performed (specification). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __AFDUMMY_H__ -#define __AFDUMMY_H__ +#ifndef AFDUMMY_H_ +#define AFDUMMY_H_ #include "aftypes.h" @@ -34,7 +34,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __AFDUMMY_H__ */ +#endif /* AFDUMMY_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/autofit/aferrors.h b/src/3rdparty/freetype/src/autofit/aferrors.h index 7b416e470d..e5de54360f 100644 --- a/src/3rdparty/freetype/src/autofit/aferrors.h +++ b/src/3rdparty/freetype/src/autofit/aferrors.h @@ -4,7 +4,7 @@ /* */ /* Autofitter error codes (specification only). */ /* */ -/* Copyright 2005-2015 by */ +/* Copyright 2005-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __AFERRORS_H__ -#define __AFERRORS_H__ +#ifndef AFERRORS_H_ +#define AFERRORS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX AF_Err_ @@ -36,6 +36,7 @@ #include FT_ERRORS_H -#endif /* __AFERRORS_H__ */ +#endif /* AFERRORS_H_ */ + /* END */ diff --git a/src/3rdparty/freetype/src/autofit/afglobal.c b/src/3rdparty/freetype/src/autofit/afglobal.c index b071cc76fb..3d09c53e8a 100644 --- a/src/3rdparty/freetype/src/autofit/afglobal.c +++ b/src/3rdparty/freetype/src/autofit/afglobal.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter routines to compute global hinting values (body). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,7 +18,7 @@ #include "afglobal.h" #include "afranges.h" -#include "hbshim.h" +#include "afshaper.h" #include FT_INTERNAL_DEBUG_H @@ -42,13 +42,14 @@ #undef SCRIPT -#define SCRIPT( s, S, d, h, sc1, sc2, sc3 ) \ +#define SCRIPT( s, S, d, h, H, ss ) \ AF_DEFINE_SCRIPT_CLASS( \ af_ ## s ## _script_class, \ AF_SCRIPT_ ## S, \ af_ ## s ## _uniranges, \ af_ ## s ## _nonbase_uniranges, \ - sc1, sc2, sc3 ) + AF_ ## H, \ + ss ) #include "afscript.h" @@ -83,7 +84,7 @@ #undef SCRIPT -#define SCRIPT( s, S, d, h, sc1, sc2, sc3 ) \ +#define SCRIPT( s, S, d, h, H, ss ) \ &af_ ## s ## _script_class, FT_LOCAL_ARRAY_DEF( AF_ScriptClass ) @@ -167,7 +168,7 @@ AF_Script_UniRange range; - if ( script_class->script_uni_ranges == NULL ) + if ( !script_class->script_uni_ranges ) continue; /* @@ -240,23 +241,23 @@ else { /* get glyphs not directly addressable by cmap */ - af_get_coverage( globals, style_class, gstyles ); + af_shaper_get_coverage( globals, style_class, gstyles, 0 ); } } - /* handle the default OpenType features of the default script ... */ - af_get_coverage( globals, AF_STYLE_CLASSES_GET[dflt], gstyles ); - - /* ... and the remaining default OpenType features */ + /* handle the remaining default OpenType features ... */ for ( ss = 0; AF_STYLE_CLASSES_GET[ss]; ss++ ) { AF_StyleClass style_class = AF_STYLE_CLASSES_GET[ss]; - if ( ss != dflt && style_class->coverage == AF_COVERAGE_DEFAULT ) - af_get_coverage( globals, style_class, gstyles ); + if ( style_class->coverage == AF_COVERAGE_DEFAULT ) + af_shaper_get_coverage( globals, style_class, gstyles, 0 ); } + /* ... and finally the default OpenType features of the default script */ + af_shaper_get_coverage( globals, AF_STYLE_CLASSES_GET[dflt], gstyles, 1 ); + /* mark ASCII digits */ for ( i = 0x30; i <= 0x39; i++ ) { @@ -350,14 +351,21 @@ (FT_ULong)face->num_glyphs * sizeof ( FT_UShort ) ) ) goto Exit; - globals->face = face; - globals->glyph_count = face->num_glyphs; + globals->face = face; + globals->glyph_count = face->num_glyphs; /* right after the globals structure come the glyph styles */ - globals->glyph_styles = (FT_UShort*)( globals + 1 ); - globals->module = module; + globals->glyph_styles = (FT_UShort*)( globals + 1 ); + globals->module = module; + globals->stem_darkening_for_ppem = 0; + globals->darken_x = 0; + globals->darken_y = 0; + globals->standard_vertical_width = 0; + globals->standard_horizontal_width = 0; + globals->scale_down_factor = 0; #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ globals->hb_font = hb_ft_font_create( face, NULL ); + globals->hb_buf = hb_buffer_create(); #endif error = af_face_globals_compute_style_coverage( globals ); @@ -403,13 +411,11 @@ #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ hb_font_destroy( globals->hb_font ); - globals->hb_font = NULL; + hb_buffer_destroy( globals->hb_buf ); #endif - globals->glyph_count = 0; - globals->glyph_styles = NULL; /* no need to free this one! */ - globals->face = NULL; - + /* no need to free `globals->glyph_styles'; */ + /* it is part of the `globals' array */ FT_FREE( globals ); } } @@ -447,7 +453,7 @@ [style_class->writing_system]; metrics = globals->metrics[style]; - if ( metrics == NULL ) + if ( !metrics ) { /* create the global metrics object if necessary */ FT_Memory memory = globals->face->memory; diff --git a/src/3rdparty/freetype/src/autofit/afglobal.h b/src/3rdparty/freetype/src/autofit/afglobal.h index ffb2f86066..489ed46d9e 100644 --- a/src/3rdparty/freetype/src/autofit/afglobal.h +++ b/src/3rdparty/freetype/src/autofit/afglobal.h @@ -5,7 +5,7 @@ /* Auto-fitter routines to compute global hinting values */ /* (specification). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,13 +17,13 @@ /***************************************************************************/ -#ifndef __AFGLOBAL_H__ -#define __AFGLOBAL_H__ +#ifndef AFGLOBAL_H_ +#define AFGLOBAL_H_ #include "aftypes.h" #include "afmodule.h" -#include "hbshim.h" +#include "afshaper.h" FT_BEGIN_HEADER @@ -34,7 +34,7 @@ FT_BEGIN_HEADER #undef SCRIPT -#define SCRIPT( s, S, d, h, sc1, sc2, sc3 ) \ +#define SCRIPT( s, S, d, h, H, ss ) \ AF_DECLARE_SCRIPT_CLASS( af_ ## s ## _script_class ) #include "afscript.h" @@ -110,6 +110,7 @@ FT_BEGIN_HEADER #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ hb_font_t* hb_font; + hb_buffer_t* hb_buf; /* for feature comparison */ #endif /* per-face auto-hinter properties */ @@ -117,6 +118,22 @@ FT_BEGIN_HEADER AF_StyleMetrics metrics[AF_STYLE_MAX]; + /* Compute darkening amount once per size. Use this to check whether */ + /* darken_{x,y} needs to be recomputed. */ + FT_UShort stem_darkening_for_ppem; + /* Copy from e.g. AF_LatinMetrics.axis[AF_DIMENSION_HORZ] */ + /* to compute the darkening amount. */ + FT_Pos standard_vertical_width; + /* Copy from e.g. AF_LatinMetrics.axis[AF_DIMENSION_VERT] */ + /* to compute the darkening amount. */ + FT_Pos standard_horizontal_width; + /* The actual amount to darken a glyph along the X axis. */ + FT_Pos darken_x; + /* The actual amount to darken a glyph along the Y axis. */ + FT_Pos darken_y; + /* Amount to scale down by to keep emboldened points */ + /* on the Y-axis in pre-computed blue zones. */ + FT_Fixed scale_down_factor; AF_Module module; /* to access global properties */ } AF_FaceGlobalsRec; @@ -150,7 +167,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __AFGLOBAL_H__ */ +#endif /* AFGLOBAL_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/autofit/afhints.c b/src/3rdparty/freetype/src/autofit/afhints.c index 37482ebd1f..0666dbc8e2 100644 --- a/src/3rdparty/freetype/src/autofit/afhints.c +++ b/src/3rdparty/freetype/src/autofit/afhints.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines (body). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -45,7 +45,7 @@ if ( axis->num_segments < AF_SEGMENTS_EMBEDDED ) { - if ( axis->segments == NULL ) + if ( !axis->segments ) { axis->segments = axis->embedded.segments; axis->max_segments = AF_SEGMENTS_EMBEDDED; @@ -99,6 +99,7 @@ af_axis_hints_new_edge( AF_AxisHints axis, FT_Int fpos, AF_Direction dir, + FT_Bool top_to_bottom_hinting, FT_Memory memory, AF_Edge *anedge ) { @@ -109,7 +110,7 @@ if ( axis->num_edges < AF_EDGES_EMBEDDED ) { - if ( axis->edges == NULL ) + if ( !axis->edges ) { axis->edges = axis->embedded.edges; axis->max_edges = AF_EDGES_EMBEDDED; @@ -153,7 +154,8 @@ while ( edge > edges ) { - if ( edge[-1].fpos < fpos ) + if ( top_to_bottom_hinting ? ( edge[-1].fpos > fpos ) + : ( edge[-1].fpos < fpos ) ) break; /* we want the edge with same position and minor direction */ @@ -219,6 +221,82 @@ #define AF_INDEX_NUM( ptr, base ) (int)( (ptr) ? ( (ptr) - (base) ) : -1 ) + static char* + af_print_idx( char* p, + int idx ) + { + if ( idx == -1 ) + { + p[0] = '-'; + p[1] = '-'; + p[2] = '\0'; + } + else + ft_sprintf( p, "%d", idx ); + + return p; + } + + + static int + af_get_segment_index( AF_GlyphHints hints, + int point_idx, + int dimension ) + { + AF_AxisHints axis = &hints->axis[dimension]; + AF_Point point = hints->points + point_idx; + AF_Segment segments = axis->segments; + AF_Segment limit = segments + axis->num_segments; + AF_Segment segment; + + + for ( segment = segments; segment < limit; segment++ ) + { + if ( segment->first <= segment->last ) + { + if ( point >= segment->first && point <= segment->last ) + break; + } + else + { + AF_Point p = segment->first; + + + for (;;) + { + if ( point == p ) + goto Exit; + + if ( p == segment->last ) + break; + + p = p->next; + } + } + } + + Exit: + if ( segment == limit ) + return -1; + + return (int)( segment - segments ); + } + + + static int + af_get_edge_index( AF_GlyphHints hints, + int segment_idx, + int dimension ) + { + AF_AxisHints axis = &hints->axis[dimension]; + AF_Edge edges = axis->edges; + AF_Segment segment = axis->segments + segment_idx; + + + return segment_idx == -1 ? -1 : AF_INDEX_NUM( segment->edge, edges ); + } + + #ifdef __cplusplus extern "C" { #endif @@ -226,30 +304,63 @@ af_glyph_hints_dump_points( AF_GlyphHints hints, FT_Bool to_stdout ) { - AF_Point points = hints->points; - AF_Point limit = points + hints->num_points; - AF_Point point; + AF_Point points = hints->points; + AF_Point limit = points + hints->num_points; + AF_Point* contour = hints->contours; + AF_Point* climit = contour + hints->num_contours; + AF_Point point; AF_DUMP(( "Table of points:\n" )); if ( hints->num_points ) - AF_DUMP(( " [ index | xorg | yorg | xscale | yscale" - " | xfit | yfit | flags ]\n" )); + { + AF_DUMP(( " index hedge hseg vedge vseg flags " + /* " XXXXX XXXXX XXXXX XXXXX XXXXX XXXXXX" */ + " xorg yorg xscale yscale xfit yfit" )); + /* " XXXXX XXXXX XXXX.XX XXXX.XX XXXX.XX XXXX.XX" */ + } else AF_DUMP(( " (none)\n" )); for ( point = points; point < limit; point++ ) - AF_DUMP(( " [ %5d | %5d | %5d | %6.2f | %6.2f" - " | %5.2f | %5.2f | %c ]\n", - AF_INDEX_NUM( point, points ), + { + int point_idx = AF_INDEX_NUM( point, points ); + int segment_idx_0 = af_get_segment_index( hints, point_idx, 0 ); + int segment_idx_1 = af_get_segment_index( hints, point_idx, 1 ); + + char buf1[16], buf2[16], buf3[16], buf4[16]; + + + /* insert extra newline at the beginning of a contour */ + if ( contour < climit && *contour == point ) + { + AF_DUMP(( "\n" )); + contour++; + } + + AF_DUMP(( " %5d %5s %5s %5s %5s %s" + " %5d %5d %7.2f %7.2f %7.2f %7.2f\n", + point_idx, + af_print_idx( buf1, + af_get_edge_index( hints, segment_idx_1, 1 ) ), + af_print_idx( buf2, segment_idx_1 ), + af_print_idx( buf3, + af_get_edge_index( hints, segment_idx_0, 0 ) ), + af_print_idx( buf4, segment_idx_0 ), + ( point->flags & AF_FLAG_NEAR ) + ? " near " + : ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) + ? " weak " + : "strong", + point->fx, point->fy, point->ox / 64.0, point->oy / 64.0, point->x / 64.0, - point->y / 64.0, - ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) ? 'w' : ' ')); + point->y / 64.0 )); + } AF_DUMP(( "\n" )); } #ifdef __cplusplus @@ -306,31 +417,39 @@ AF_Segment limit = segments + axis->num_segments; AF_Segment seg; + char buf1[16], buf2[16], buf3[16]; + AF_DUMP(( "Table of %s segments:\n", dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" )); if ( axis->num_segments ) - AF_DUMP(( " [ index | pos | dir | from" - " | to | link | serif | edge" - " | height | extra | flags ]\n" )); + { + AF_DUMP(( " index pos delta dir from to " + /* " XXXXX XXXXX XXXXX XXXXX XXXX XXXX" */ + " link serif edge" + /* " XXXX XXXXX XXXX" */ + " height extra flags\n" )); + /* " XXXXXX XXXXX XXXXXXXXXXX" */ + } else AF_DUMP(( " (none)\n" )); for ( seg = segments; seg < limit; seg++ ) - AF_DUMP(( " [ %5d | %5.2g | %5s | %4d" - " | %4d | %4d | %5d | %4d" - " | %6d | %5d | %11s ]\n", + AF_DUMP(( " %5d %5d %5d %5s %4d %4d" + " %4s %5s %4s" + " %6d %5d %11s\n", AF_INDEX_NUM( seg, segments ), - dimension == AF_DIMENSION_HORZ - ? (int)seg->first->ox / 64.0 - : (int)seg->first->oy / 64.0, + seg->pos, + seg->delta, af_dir_str( (AF_Direction)seg->dir ), AF_INDEX_NUM( seg->first, points ), AF_INDEX_NUM( seg->last, points ), - AF_INDEX_NUM( seg->link, segments ), - AF_INDEX_NUM( seg->serif, segments ), - AF_INDEX_NUM( seg->edge, edges ), + + af_print_idx( buf1, AF_INDEX_NUM( seg->link, segments ) ), + af_print_idx( buf2, AF_INDEX_NUM( seg->serif, segments ) ), + af_print_idx( buf3, AF_INDEX_NUM( seg->edge, edges ) ), + seg->height, seg->height - ( seg->max_coord - seg->min_coord ), af_edge_flags_to_string( seg->flags ) )); @@ -397,15 +516,15 @@ return FT_THROW( Invalid_Argument ); seg = &axis->segments[idx]; - *offset = ( dim == AF_DIMENSION_HORZ ) ? seg->first->ox - : seg->first->oy; + *offset = ( dim == AF_DIMENSION_HORZ ) ? seg->first->fx + : seg->first->fy; if ( seg->edge ) *is_blue = (FT_Bool)( seg->edge->blue_edge != 0 ); else *is_blue = FALSE; if ( *is_blue ) - *blue_offset = seg->edge->blue_edge->cur; + *blue_offset = seg->edge->blue_edge->org; else *blue_offset = 0; @@ -435,28 +554,43 @@ AF_Edge limit = edges + axis->num_edges; AF_Edge edge; + char buf1[16], buf2[16]; + /* * note: AF_DIMENSION_HORZ corresponds to _vertical_ edges * since they have a constant X coordinate. */ - AF_DUMP(( "Table of %s edges:\n", - dimension == AF_DIMENSION_HORZ ? "vertical" - : "horizontal" )); + if ( dimension == AF_DIMENSION_HORZ ) + AF_DUMP(( "Table of %s edges (1px=%.2fu, 10u=%.2fpx):\n", + "vertical", + 65536.0 * 64.0 / hints->x_scale, + 10.0 * hints->x_scale / 65536.0 / 64.0 )); + else + AF_DUMP(( "Table of %s edges (1px=%.2fu, 10u=%.2fpx):\n", + "horizontal", + 65536.0 * 64.0 / hints->y_scale, + 10.0 * hints->y_scale / 65536.0 / 64.0 )); + if ( axis->num_edges ) - AF_DUMP(( " [ index | pos | dir | link" - " | serif | blue | opos | pos | flags ]\n" )); + { + AF_DUMP(( " index pos dir link serif" + /* " XXXXX XXXX.XX XXXXX XXXX XXXXX" */ + " blue opos pos flags\n" )); + /* " X XXXX.XX XXXX.XX XXXXXXXXXXX" */ + } else AF_DUMP(( " (none)\n" )); for ( edge = edges; edge < limit; edge++ ) - AF_DUMP(( " [ %5d | %5.2g | %5s | %4d" - " | %5d | %c | %5.2f | %5.2f | %11s ]\n", + AF_DUMP(( " %5d %7.2f %5s %4s %5s" + " %c %7.2f %7.2f %11s\n", AF_INDEX_NUM( edge, edges ), (int)edge->opos / 64.0, af_dir_str( (AF_Direction)edge->dir ), - AF_INDEX_NUM( edge->link, edges ), - AF_INDEX_NUM( edge->serif, edges ), + af_print_idx( buf1, AF_INDEX_NUM( edge->link, edges ) ), + af_print_idx( buf2, AF_INDEX_NUM( edge->serif, edges ) ), + edge->blue_edge ? 'y' : 'n', edge->opos / 64.0, edge->pos / 64.0, @@ -622,7 +756,7 @@ if ( new_max <= AF_CONTOURS_EMBEDDED ) { - if ( hints->contours == NULL ) + if ( !hints->contours ) { hints->contours = hints->embedded.contours; hints->max_contours = AF_CONTOURS_EMBEDDED; @@ -651,7 +785,7 @@ if ( new_max <= AF_POINTS_EMBEDDED ) { - if ( hints->points == NULL ) + if ( !hints->points ) { hints->points = hints->embedded.points; hints->max_points = AF_POINTS_EMBEDDED; @@ -702,18 +836,26 @@ AF_Point point; AF_Point point_limit = points + hints->num_points; + /* value 20 in `near_limit' is heuristic */ + FT_UInt units_per_em = hints->metrics->scaler.face->units_per_EM; + FT_Int near_limit = 20 * units_per_em / 2048; + /* compute coordinates & Bezier flags, next and prev */ { FT_Vector* vec = outline->points; char* tag = outline->tags; - AF_Point end = points + outline->contours[0]; + FT_Short endpoint = outline->contours[0]; + AF_Point end = points + endpoint; AF_Point prev = end; FT_Int contour_index = 0; for ( point = points; point < point_limit; point++, vec++, tag++ ) { + FT_Pos out_x, out_y; + + point->in_dir = (FT_Char)AF_DIR_NONE; point->out_dir = (FT_Char)AF_DIR_NONE; @@ -722,6 +864,9 @@ point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta; point->oy = point->y = FT_MulFix( vec->y, y_scale ) + y_delta; + end->fx = (FT_Short)outline->points[endpoint].x; + end->fy = (FT_Short)outline->points[endpoint].y; + switch ( FT_CURVE_TAG( *tag ) ) { case FT_CURVE_TAG_CONIC: @@ -734,6 +879,12 @@ point->flags = AF_FLAG_NONE; } + out_x = point->fx - prev->fx; + out_y = point->fy - prev->fy; + + if ( FT_ABS( out_x ) + FT_ABS( out_y ) < near_limit ) + prev->flags |= AF_FLAG_NEAR; + point->prev = prev; prev->next = point; prev = point; @@ -742,8 +893,9 @@ { if ( ++contour_index < outline->n_contours ) { - end = points + outline->contours[contour_index]; - prev = end; + endpoint = outline->contours[contour_index]; + end = points + endpoint; + prev = end; } } } @@ -769,17 +921,15 @@ * Compute directions of `in' and `out' vectors. * * Note that distances between points that are very near to each - * other are accumulated. In other words, the auto-hinter + * other are accumulated. In other words, the auto-hinter either * prepends the small vectors between near points to the first - * non-near vector. All intermediate points are tagged as - * weak; the directions are adjusted also to be equal to the - * accumulated one. + * non-near vector, or the sum of small vector lengths exceeds a + * threshold, thus `grouping' the small vectors. All intermediate + * points are tagged as weak; the directions are adjusted also to + * be equal to the accumulated one. */ - /* value 20 in `near_limit' is heuristic */ - FT_UInt units_per_em = hints->metrics->scaler.face->units_per_EM; - FT_Int near_limit = 20 * units_per_em / 2048; - FT_Int near_limit2 = 2 * near_limit - 1; + FT_Int near_limit2 = 2 * near_limit - 1; AF_Point* contour; AF_Point* contour_limit = hints->contours + hints->num_contours; @@ -826,7 +976,7 @@ /* now loop over all points of the contour to get */ /* `in' and `out' vector directions */ - curr = first; + curr = first; /* * We abuse the `u' and `v' fields to store index deltas to the @@ -849,7 +999,7 @@ point = next; - next = point->next; + next = point->next; out_x += next->fx - point->fx; out_y += next->fy - point->fy; @@ -1045,7 +1195,7 @@ AF_Point point, first, last; - if ( edge == NULL ) + if ( !edge ) continue; first = seg->first; @@ -1071,7 +1221,7 @@ AF_Point point, first, last; - if ( edge == NULL ) + if ( !edge ) continue; first = seg->first; diff --git a/src/3rdparty/freetype/src/autofit/afhints.h b/src/3rdparty/freetype/src/autofit/afhints.h index a64c7a4b11..3326ebc44e 100644 --- a/src/3rdparty/freetype/src/autofit/afhints.h +++ b/src/3rdparty/freetype/src/autofit/afhints.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines (specification). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __AFHINTS_H__ -#define __AFHINTS_H__ +#ifndef AFHINTS_H_ +#define AFHINTS_H_ #include "aftypes.h" @@ -62,7 +62,7 @@ FT_BEGIN_HEADER * * by David Turner and Werner Lemberg * - * http://www.tug.org/TUGboat/Articles/tb24-3/lemberg.pdf + * https://www.tug.org/TUGboat/Articles/tb24-3/lemberg.pdf * * with appropriate updates. * @@ -221,6 +221,9 @@ FT_BEGIN_HEADER /* candidates for weak interpolation have this flag set */ #define AF_FLAG_WEAK_INTERPOLATION ( 1U << 4 ) + /* the distance to the next point is very small */ +#define AF_FLAG_NEAR ( 1U << 5 ) + /* edge hint flags */ #define AF_EDGE_NORMAL 0 @@ -257,6 +260,7 @@ FT_BEGIN_HEADER FT_Byte flags; /* edge/segment flags for this segment */ FT_Char dir; /* segment direction */ FT_Short pos; /* position of segment */ + FT_Short delta; /* deviation from segment position */ FT_Short min_coord; /* minimum coordinate of segment */ FT_Short max_coord; /* maximum coordinate of segment */ FT_Short height; /* the hinted segment height */ @@ -266,7 +270,6 @@ FT_BEGIN_HEADER AF_Segment link; /* (stem) link segment */ AF_Segment serif; /* primary segment for serifs */ - FT_Pos num_linked; /* number of linked segments */ FT_Pos score; /* used during stem matching */ FT_Pos len; /* used during stem matching */ @@ -289,7 +292,6 @@ FT_BEGIN_HEADER AF_Width blue_edge; /* non-NULL if this is a blue edge */ AF_Edge link; /* link edge */ AF_Edge serif; /* primary edge for serifs */ - FT_Short num_linked; /* number of linked edges */ FT_Int score; /* used during stem matching */ AF_Segment first; /* first segment in edge */ @@ -419,6 +421,7 @@ FT_BEGIN_HEADER af_axis_hints_new_edge( AF_AxisHints axis, FT_Int fpos, AF_Direction dir, + FT_Bool top_to_bottom_hinting, FT_Memory memory, AF_Edge *edge ); @@ -472,7 +475,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __AFHINTS_H__ */ +#endif /* AFHINTS_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/autofit/afindic.c b/src/3rdparty/freetype/src/autofit/afindic.c index 05b6bdd887..dfbea5f34c 100644 --- a/src/3rdparty/freetype/src/autofit/afindic.c +++ b/src/3rdparty/freetype/src/autofit/afindic.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines for Indic writing system (body). */ /* */ -/* Copyright 2007-2015 by */ +/* Copyright 2007-2018 by */ /* Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,13 +18,13 @@ #include "aftypes.h" #include "aflatin.h" +#include "afcjk.h" #ifdef AF_CONFIG_OPTION_INDIC #include "afindic.h" #include "aferrors.h" -#include "afcjk.h" #ifdef AF_CONFIG_OPTION_USE_WARPER @@ -89,6 +89,22 @@ } + /* Extract standard_width from writing system/script specific */ + /* metrics class. */ + + static void + af_indic_get_standard_widths( AF_CJKMetrics metrics, + FT_Pos* stdHW, + FT_Pos* stdVW ) + { + if ( stdHW ) + *stdHW = metrics->axis[AF_DIMENSION_VERT].standard_width; + + if ( stdVW ) + *stdVW = metrics->axis[AF_DIMENSION_HORZ].standard_width; + } + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -105,12 +121,13 @@ sizeof ( AF_CJKMetricsRec ), - (AF_WritingSystem_InitMetricsFunc) af_indic_metrics_init, - (AF_WritingSystem_ScaleMetricsFunc)af_indic_metrics_scale, - (AF_WritingSystem_DoneMetricsFunc) NULL, + (AF_WritingSystem_InitMetricsFunc) af_indic_metrics_init, /* style_metrics_init */ + (AF_WritingSystem_ScaleMetricsFunc)af_indic_metrics_scale, /* style_metrics_scale */ + (AF_WritingSystem_DoneMetricsFunc) NULL, /* style_metrics_done */ + (AF_WritingSystem_GetStdWidthsFunc)af_indic_get_standard_widths, /* style_metrics_getstdw */ - (AF_WritingSystem_InitHintsFunc) af_indic_hints_init, - (AF_WritingSystem_ApplyHintsFunc) af_indic_hints_apply + (AF_WritingSystem_InitHintsFunc) af_indic_hints_init, /* style_hints_init */ + (AF_WritingSystem_ApplyHintsFunc) af_indic_hints_apply /* style_hints_apply */ ) @@ -124,12 +141,13 @@ sizeof ( AF_CJKMetricsRec ), - (AF_WritingSystem_InitMetricsFunc) NULL, - (AF_WritingSystem_ScaleMetricsFunc)NULL, - (AF_WritingSystem_DoneMetricsFunc) NULL, + (AF_WritingSystem_InitMetricsFunc) NULL, /* style_metrics_init */ + (AF_WritingSystem_ScaleMetricsFunc)NULL, /* style_metrics_scale */ + (AF_WritingSystem_DoneMetricsFunc) NULL, /* style_metrics_done */ + (AF_WritingSystem_GetStdWidthsFunc)NULL, /* style_metrics_getstdw */ - (AF_WritingSystem_InitHintsFunc) NULL, - (AF_WritingSystem_ApplyHintsFunc) NULL + (AF_WritingSystem_InitHintsFunc) NULL, /* style_hints_init */ + (AF_WritingSystem_ApplyHintsFunc) NULL /* style_hints_apply */ ) diff --git a/src/3rdparty/freetype/src/autofit/afindic.h b/src/3rdparty/freetype/src/autofit/afindic.h index 4c36908ada..5688738e6e 100644 --- a/src/3rdparty/freetype/src/autofit/afindic.h +++ b/src/3rdparty/freetype/src/autofit/afindic.h @@ -5,7 +5,7 @@ /* Auto-fitter hinting routines for Indic writing system */ /* (specification). */ /* */ -/* Copyright 2007-2015 by */ +/* Copyright 2007-2018 by */ /* Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __AFINDIC_H__ -#define __AFINDIC_H__ +#ifndef AFINDIC_H_ +#define AFINDIC_H_ #include "afhints.h" @@ -35,7 +35,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __AFINDIC_H__ */ +#endif /* AFINDIC_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/autofit/aflatin.c b/src/3rdparty/freetype/src/autofit/aflatin.c index 363f72114b..9f1b54056f 100644 --- a/src/3rdparty/freetype/src/autofit/aflatin.c +++ b/src/3rdparty/freetype/src/autofit/aflatin.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter hinting routines for latin writing system (body). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -79,7 +79,6 @@ { FT_Error error; FT_ULong glyph_index; - FT_Long y_offset; int dim; AF_LatinMetricsRec dummy[1]; AF_Scaler scaler = &dummy->root.scaler; @@ -92,52 +91,63 @@ AF_ScriptClass script_class = AF_SCRIPT_CLASSES_GET [style_class->script]; - FT_UInt32 standard_char; + void* shaper_buf; + const char* p; +#ifdef FT_DEBUG_LEVEL_TRACE + FT_ULong ch = 0; +#endif + + p = script_class->standard_charstring; + shaper_buf = af_shaper_buf_create( face ); /* - * We check more than a single standard character to catch features - * like `c2sc' (small caps from caps) that don't contain lowercase - * letters by definition, or other features that mainly operate on - * numerals. + * We check a list of standard characters to catch features like + * `c2sc' (small caps from caps) that don't contain lowercase letters + * by definition, or other features that mainly operate on numerals. + * The first match wins. */ - standard_char = script_class->standard_char1; - af_get_char_index( &metrics->root, - standard_char, - &glyph_index, - &y_offset ); - if ( !glyph_index ) + glyph_index = 0; + while ( *p ) { - if ( script_class->standard_char2 ) - { - standard_char = script_class->standard_char2; - af_get_char_index( &metrics->root, - standard_char, - &glyph_index, - &y_offset ); - if ( !glyph_index ) - { - if ( script_class->standard_char3 ) - { - standard_char = script_class->standard_char3; - af_get_char_index( &metrics->root, - standard_char, - &glyph_index, - &y_offset ); - if ( !glyph_index ) - goto Exit; - } - else - goto Exit; - } - } - else - goto Exit; + unsigned int num_idx; + +#ifdef FT_DEBUG_LEVEL_TRACE + const char* p_old; +#endif + + + while ( *p == ' ' ) + p++; + +#ifdef FT_DEBUG_LEVEL_TRACE + p_old = p; + GET_UTF8_CHAR( ch, p_old ); +#endif + + /* reject input that maps to more than a single glyph */ + p = af_shaper_get_cluster( p, &metrics->root, shaper_buf, &num_idx ); + if ( num_idx > 1 ) + continue; + + /* otherwise exit loop if we have a result */ + glyph_index = af_shaper_get_elem( &metrics->root, + shaper_buf, + 0, + NULL, + NULL ); + if ( glyph_index ) + break; } + af_shaper_buf_destroy( face, shaper_buf ); + + if ( !glyph_index ) + goto Exit; + FT_TRACE5(( "standard character: U+%04lX (glyph index %d)\n", - standard_char, glyph_index )); + ch, glyph_index )); error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); if ( error || face->glyph->outline.n_points <= 0 ) @@ -255,6 +265,45 @@ } + static void + af_latin_sort_blue( FT_UInt count, + AF_LatinBlue* table ) + { + FT_UInt i, j; + AF_LatinBlue swap; + + + /* we sort from bottom to top */ + for ( i = 1; i < count; i++ ) + { + for ( j = i; j > 0; j-- ) + { + FT_Pos a, b; + + + if ( table[j - 1]->flags & ( AF_LATIN_BLUE_TOP | + AF_LATIN_BLUE_SUB_TOP ) ) + a = table[j - 1]->ref.org; + else + a = table[j - 1]->shoot.org; + + if ( table[j]->flags & ( AF_LATIN_BLUE_TOP | + AF_LATIN_BLUE_SUB_TOP ) ) + b = table[j]->ref.org; + else + b = table[j]->shoot.org; + + if ( b >= a ) + break; + + swap = table[j]; + table[j] = table[j - 1]; + table[j - 1] = swap; + } + } + } + + /* Find all blue zones. Flat segments give the reference points, */ /* round segments the overshoot positions. */ @@ -280,6 +329,8 @@ FT_Pos flat_threshold = FLAT_THRESHOLD( metrics->units_per_em ); + void* shaper_buf; + /* we walk over the blue character strings as specified in the */ /* style's entry in the `af_blue_stringset' array */ @@ -288,11 +339,15 @@ "============================\n" "\n" )); + shaper_buf = af_shaper_buf_create( face ); + for ( ; bs->string != AF_BLUE_STRING_MAX; bs++ ) { const char* p = &af_blue_strings[bs->string]; FT_Pos* blue_ref; FT_Pos* blue_shoot; + FT_Pos ascender; + FT_Pos descender; #ifdef FT_DEBUG_LEVEL_TRACE @@ -311,6 +366,11 @@ FT_TRACE5(( "top" )); have_flag = 1; } + else if ( AF_LATIN_IS_SUB_TOP_BLUE( bs ) ) + { + FT_TRACE5(( "sub top" )); + have_flag = 1; + } if ( AF_LATIN_IS_NEUTRAL_BLUE( bs ) ) { @@ -344,394 +404,482 @@ num_flats = 0; num_rounds = 0; + ascender = 0; + descender = 0; while ( *p ) { - FT_ULong ch; FT_ULong glyph_index; FT_Long y_offset; - FT_Pos best_y; /* same as points.y */ FT_Int best_point, best_contour_first, best_contour_last; FT_Vector* points; - FT_Bool round = 0; + + FT_Pos best_y_extremum; /* same as points.y */ + FT_Bool best_round = 0; + + unsigned int i, num_idx; + +#ifdef FT_DEBUG_LEVEL_TRACE + const char* p_old; + FT_ULong ch; +#endif - GET_UTF8_CHAR( ch, p ); + while ( *p == ' ' ) + p++; - /* load the character in the face -- skip unknown or empty ones */ - af_get_char_index( &metrics->root, ch, &glyph_index, &y_offset ); - if ( glyph_index == 0 ) +#ifdef FT_DEBUG_LEVEL_TRACE + p_old = p; + GET_UTF8_CHAR( ch, p_old ); +#endif + + p = af_shaper_get_cluster( p, &metrics->root, shaper_buf, &num_idx ); + + if ( !num_idx ) { FT_TRACE5(( " U+%04lX unavailable\n", ch )); continue; } - error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); - outline = face->glyph->outline; - /* reject glyphs that don't produce any rendering */ - if ( error || outline.n_points <= 2 ) + if ( AF_LATIN_IS_TOP_BLUE( bs ) ) + best_y_extremum = FT_INT_MIN; + else + best_y_extremum = FT_INT_MAX; + + /* iterate over all glyph elements of the character cluster */ + /* and get the data of the `biggest' one */ + for ( i = 0; i < num_idx; i++ ) { - FT_TRACE5(( " U+%04lX contains no (usable) outlines\n", ch )); - continue; - } - - /* now compute min or max point indices and coordinates */ - points = outline.points; - best_point = -1; - best_y = 0; /* make compiler happy */ - best_contour_first = 0; /* ditto */ - best_contour_last = 0; /* ditto */ - - { - FT_Int nn; - FT_Int first = 0; - FT_Int last = -1; + FT_Pos best_y; + FT_Bool round = 0; - for ( nn = 0; nn < outline.n_contours; first = last + 1, nn++ ) + /* load the character in the face -- skip unknown or empty ones */ + glyph_index = af_shaper_get_elem( &metrics->root, + shaper_buf, + i, + NULL, + &y_offset ); + if ( glyph_index == 0 ) { - FT_Int old_best_point = best_point; - FT_Int pp; - - - last = outline.contours[nn]; - - /* Avoid single-point contours since they are never rasterized. */ - /* In some fonts, they correspond to mark attachment points */ - /* that are way outside of the glyph's real outline. */ - if ( last <= first ) - continue; - - if ( AF_LATIN_IS_TOP_BLUE( bs ) ) - { - for ( pp = first; pp <= last; pp++ ) - if ( best_point < 0 || points[pp].y > best_y ) - { - best_point = pp; - best_y = points[pp].y; - } - } - else - { - for ( pp = first; pp <= last; pp++ ) - if ( best_point < 0 || points[pp].y < best_y ) - { - best_point = pp; - best_y = points[pp].y; - } - } - - if ( best_point != old_best_point ) - { - best_contour_first = first; - best_contour_last = last; - } - } - } - - /* now check whether the point belongs to a straight or round */ - /* segment; we first need to find in which contour the extremum */ - /* lies, then inspect its previous and next points */ - if ( best_point >= 0 ) - { - FT_Pos best_x = points[best_point].x; - FT_Int prev, next; - FT_Int best_segment_first, best_segment_last; - FT_Int best_on_point_first, best_on_point_last; - FT_Pos dist; - - - best_segment_first = best_point; - best_segment_last = best_point; - - if ( FT_CURVE_TAG( outline.tags[best_point] ) == FT_CURVE_TAG_ON ) - { - best_on_point_first = best_point; - best_on_point_last = best_point; - } - else - { - best_on_point_first = -1; - best_on_point_last = -1; + FT_TRACE5(( " U+%04lX unavailable\n", ch )); + continue; } - /* look for the previous and next points on the contour */ - /* that are not on the same Y coordinate, then threshold */ - /* the `closeness'... */ - prev = best_point; - next = prev; - - do + error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); + outline = face->glyph->outline; + /* reject glyphs that don't produce any rendering */ + if ( error || outline.n_points <= 2 ) { - if ( prev > best_contour_first ) - prev--; +#ifdef FT_DEBUG_LEVEL_TRACE + if ( num_idx == 1 ) + FT_TRACE5(( " U+%04lX contains no (usable) outlines\n", ch )); else - prev = best_contour_last; + FT_TRACE5(( " component %d of cluster starting with U+%04lX" + " contains no (usable) outlines\n", i, ch )); +#endif + continue; + } - dist = FT_ABS( points[prev].y - best_y ); - /* accept a small distance or a small angle (both values are */ - /* heuristic; value 20 corresponds to approx. 2.9 degrees) */ - if ( dist > 5 ) - if ( FT_ABS( points[prev].x - best_x ) <= 20 * dist ) - break; + /* now compute min or max point indices and coordinates */ + points = outline.points; + best_point = -1; + best_y = 0; /* make compiler happy */ + best_contour_first = 0; /* ditto */ + best_contour_last = 0; /* ditto */ - best_segment_first = prev; - - if ( FT_CURVE_TAG( outline.tags[prev] ) == FT_CURVE_TAG_ON ) - { - best_on_point_first = prev; - if ( best_on_point_last < 0 ) - best_on_point_last = prev; - } - - } while ( prev != best_point ); - - do { - if ( next < best_contour_last ) - next++; - else - next = best_contour_first; + FT_Int nn; + FT_Int first = 0; + FT_Int last = -1; - dist = FT_ABS( points[next].y - best_y ); - if ( dist > 5 ) - if ( FT_ABS( points[next].x - best_x ) <= 20 * dist ) - break; - best_segment_last = next; - - if ( FT_CURVE_TAG( outline.tags[next] ) == FT_CURVE_TAG_ON ) + for ( nn = 0; nn < outline.n_contours; first = last + 1, nn++ ) { - best_on_point_last = next; - if ( best_on_point_first < 0 ) - best_on_point_first = next; - } - - } while ( next != best_point ); - - if ( AF_LATIN_IS_LONG_BLUE( bs ) ) - { - /* If this flag is set, we have an additional constraint to */ - /* get the blue zone distance: Find a segment of the topmost */ - /* (or bottommost) contour that is longer than a heuristic */ - /* threshold. This ensures that small bumps in the outline */ - /* are ignored (for example, the `vertical serifs' found in */ - /* many Hebrew glyph designs). */ - - /* If this segment is long enough, we are done. Otherwise, */ - /* search the segment next to the extremum that is long */ - /* enough, has the same direction, and a not too large */ - /* vertical distance from the extremum. Note that the */ - /* algorithm doesn't check whether the found segment is */ - /* actually the one (vertically) nearest to the extremum. */ - - /* heuristic threshold value */ - FT_Pos length_threshold = metrics->units_per_em / 25; + FT_Int old_best_point = best_point; + FT_Int pp; - dist = FT_ABS( points[best_segment_last].x - - points[best_segment_first].x ); + last = outline.contours[nn]; - if ( dist < length_threshold && - best_segment_last - best_segment_first + 2 <= - best_contour_last - best_contour_first ) - { - /* heuristic threshold value */ - FT_Pos height_threshold = metrics->units_per_em / 4; - - FT_Int first; - FT_Int last; - FT_Bool hit; - - /* we intentionally declare these two variables */ - /* outside of the loop since various compilers emit */ - /* incorrect warning messages otherwise, talking about */ - /* `possibly uninitialized variables' */ - FT_Int p_first = 0; /* make compiler happy */ - FT_Int p_last = 0; - - FT_Bool left2right; - - - /* compute direction */ - prev = best_point; - - do - { - if ( prev > best_contour_first ) - prev--; - else - prev = best_contour_last; - - if ( points[prev].x != best_x ) - break; - - } while ( prev != best_point ); - - /* skip glyph for the degenerate case */ - if ( prev == best_point ) + /* Avoid single-point contours since they are never */ + /* rasterized. In some fonts, they correspond to mark */ + /* attachment points that are way outside of the glyph's */ + /* real outline. */ + if ( last <= first ) continue; - left2right = FT_BOOL( points[prev].x < points[best_point].x ); - - first = best_segment_last; - last = first; - hit = 0; - - do + if ( AF_LATIN_IS_TOP_BLUE( bs ) || + AF_LATIN_IS_SUB_TOP_BLUE( bs ) ) { - FT_Bool l2r; - FT_Pos d; - - - if ( !hit ) + for ( pp = first; pp <= last; pp++ ) { - /* no hit; adjust first point */ - first = last; - - /* also adjust first and last on point */ - if ( FT_CURVE_TAG( outline.tags[first] ) == - FT_CURVE_TAG_ON ) + if ( best_point < 0 || points[pp].y > best_y ) { - p_first = first; - p_last = first; + best_point = pp; + best_y = points[pp].y; + ascender = FT_MAX( ascender, best_y + y_offset ); } else + descender = FT_MIN( descender, points[pp].y + y_offset ); + } + } + else + { + for ( pp = first; pp <= last; pp++ ) + { + if ( best_point < 0 || points[pp].y < best_y ) { - p_first = -1; - p_last = -1; + best_point = pp; + best_y = points[pp].y; + descender = FT_MIN( descender, best_y + y_offset ); + } + else + ascender = FT_MAX( ascender, points[pp].y + y_offset ); + } + } + + if ( best_point != old_best_point ) + { + best_contour_first = first; + best_contour_last = last; + } + } + } + + /* now check whether the point belongs to a straight or round */ + /* segment; we first need to find in which contour the extremum */ + /* lies, then inspect its previous and next points */ + if ( best_point >= 0 ) + { + FT_Pos best_x = points[best_point].x; + FT_Int prev, next; + FT_Int best_segment_first, best_segment_last; + FT_Int best_on_point_first, best_on_point_last; + FT_Pos dist; + + + best_segment_first = best_point; + best_segment_last = best_point; + + if ( FT_CURVE_TAG( outline.tags[best_point] ) == FT_CURVE_TAG_ON ) + { + best_on_point_first = best_point; + best_on_point_last = best_point; + } + else + { + best_on_point_first = -1; + best_on_point_last = -1; + } + + /* look for the previous and next points on the contour */ + /* that are not on the same Y coordinate, then threshold */ + /* the `closeness'... */ + prev = best_point; + next = prev; + + do + { + if ( prev > best_contour_first ) + prev--; + else + prev = best_contour_last; + + dist = FT_ABS( points[prev].y - best_y ); + /* accept a small distance or a small angle (both values are */ + /* heuristic; value 20 corresponds to approx. 2.9 degrees) */ + if ( dist > 5 ) + if ( FT_ABS( points[prev].x - best_x ) <= 20 * dist ) + break; + + best_segment_first = prev; + + if ( FT_CURVE_TAG( outline.tags[prev] ) == FT_CURVE_TAG_ON ) + { + best_on_point_first = prev; + if ( best_on_point_last < 0 ) + best_on_point_last = prev; + } + + } while ( prev != best_point ); + + do + { + if ( next < best_contour_last ) + next++; + else + next = best_contour_first; + + dist = FT_ABS( points[next].y - best_y ); + if ( dist > 5 ) + if ( FT_ABS( points[next].x - best_x ) <= 20 * dist ) + break; + + best_segment_last = next; + + if ( FT_CURVE_TAG( outline.tags[next] ) == FT_CURVE_TAG_ON ) + { + best_on_point_last = next; + if ( best_on_point_first < 0 ) + best_on_point_first = next; + } + + } while ( next != best_point ); + + if ( AF_LATIN_IS_LONG_BLUE( bs ) ) + { + /* If this flag is set, we have an additional constraint to */ + /* get the blue zone distance: Find a segment of the topmost */ + /* (or bottommost) contour that is longer than a heuristic */ + /* threshold. This ensures that small bumps in the outline */ + /* are ignored (for example, the `vertical serifs' found in */ + /* many Hebrew glyph designs). */ + + /* If this segment is long enough, we are done. Otherwise, */ + /* search the segment next to the extremum that is long */ + /* enough, has the same direction, and a not too large */ + /* vertical distance from the extremum. Note that the */ + /* algorithm doesn't check whether the found segment is */ + /* actually the one (vertically) nearest to the extremum. */ + + /* heuristic threshold value */ + FT_Pos length_threshold = metrics->units_per_em / 25; + + + dist = FT_ABS( points[best_segment_last].x - + points[best_segment_first].x ); + + if ( dist < length_threshold && + best_segment_last - best_segment_first + 2 <= + best_contour_last - best_contour_first ) + { + /* heuristic threshold value */ + FT_Pos height_threshold = metrics->units_per_em / 4; + + FT_Int first; + FT_Int last; + FT_Bool hit; + + /* we intentionally declare these two variables */ + /* outside of the loop since various compilers emit */ + /* incorrect warning messages otherwise, talking about */ + /* `possibly uninitialized variables' */ + FT_Int p_first = 0; /* make compiler happy */ + FT_Int p_last = 0; + + FT_Bool left2right; + + + /* compute direction */ + prev = best_point; + + do + { + if ( prev > best_contour_first ) + prev--; + else + prev = best_contour_last; + + if ( points[prev].x != best_x ) + break; + + } while ( prev != best_point ); + + /* skip glyph for the degenerate case */ + if ( prev == best_point ) + continue; + + left2right = FT_BOOL( points[prev].x < points[best_point].x ); + + first = best_segment_last; + last = first; + hit = 0; + + do + { + FT_Bool l2r; + FT_Pos d; + + + if ( !hit ) + { + /* no hit; adjust first point */ + first = last; + + /* also adjust first and last on point */ + if ( FT_CURVE_TAG( outline.tags[first] ) == + FT_CURVE_TAG_ON ) + { + p_first = first; + p_last = first; + } + else + { + p_first = -1; + p_last = -1; + } + + hit = 1; } - hit = 1; - } + if ( last < best_contour_last ) + last++; + else + last = best_contour_first; - if ( last < best_contour_last ) - last++; - else - last = best_contour_first; - - if ( FT_ABS( best_y - points[first].y ) > height_threshold ) - { - /* vertical distance too large */ - hit = 0; - continue; - } - - /* same test as above */ - dist = FT_ABS( points[last].y - points[first].y ); - if ( dist > 5 ) - if ( FT_ABS( points[last].x - points[first].x ) <= - 20 * dist ) + if ( FT_ABS( best_y - points[first].y ) > height_threshold ) { + /* vertical distance too large */ hit = 0; continue; } - if ( FT_CURVE_TAG( outline.tags[last] ) == FT_CURVE_TAG_ON ) - { - p_last = last; - if ( p_first < 0 ) - p_first = last; - } - - l2r = FT_BOOL( points[first].x < points[last].x ); - d = FT_ABS( points[last].x - points[first].x ); - - if ( l2r == left2right && - d >= length_threshold ) - { - /* all constraints are met; update segment after finding */ - /* its end */ - do - { - if ( last < best_contour_last ) - last++; - else - last = best_contour_first; - - d = FT_ABS( points[last].y - points[first].y ); - if ( d > 5 ) - if ( FT_ABS( points[next].x - points[first].x ) <= - 20 * dist ) - { - if ( last > best_contour_first ) - last--; - else - last = best_contour_last; - break; - } - - p_last = last; - - if ( FT_CURVE_TAG( outline.tags[last] ) == - FT_CURVE_TAG_ON ) + /* same test as above */ + dist = FT_ABS( points[last].y - points[first].y ); + if ( dist > 5 ) + if ( FT_ABS( points[last].x - points[first].x ) <= + 20 * dist ) { - p_last = last; - if ( p_first < 0 ) - p_first = last; + hit = 0; + continue; } - } while ( last != best_segment_first ); + if ( FT_CURVE_TAG( outline.tags[last] ) == FT_CURVE_TAG_ON ) + { + p_last = last; + if ( p_first < 0 ) + p_first = last; + } - best_y = points[first].y; + l2r = FT_BOOL( points[first].x < points[last].x ); + d = FT_ABS( points[last].x - points[first].x ); - best_segment_first = first; - best_segment_last = last; + if ( l2r == left2right && + d >= length_threshold ) + { + /* all constraints are met; update segment after */ + /* finding its end */ + do + { + if ( last < best_contour_last ) + last++; + else + last = best_contour_first; - best_on_point_first = p_first; - best_on_point_last = p_last; + d = FT_ABS( points[last].y - points[first].y ); + if ( d > 5 ) + if ( FT_ABS( points[next].x - points[first].x ) <= + 20 * dist ) + { + if ( last > best_contour_first ) + last--; + else + last = best_contour_last; + break; + } - break; - } + p_last = last; - } while ( last != best_segment_first ); + if ( FT_CURVE_TAG( outline.tags[last] ) == + FT_CURVE_TAG_ON ) + { + p_last = last; + if ( p_first < 0 ) + p_first = last; + } + + } while ( last != best_segment_first ); + + best_y = points[first].y; + + best_segment_first = first; + best_segment_last = last; + + best_on_point_first = p_first; + best_on_point_last = p_last; + + break; + } + + } while ( last != best_segment_first ); + } + } + + /* for computing blue zones, we add the y offset as returned */ + /* by the currently used OpenType feature -- for example, */ + /* superscript glyphs might be identical to subscript glyphs */ + /* with a vertical shift */ + best_y += y_offset; + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( num_idx == 1 ) + FT_TRACE5(( " U+%04lX: best_y = %5ld", ch, best_y )); + else + FT_TRACE5(( " component %d of cluster starting with U+%04lX:" + " best_y = %5ld", i, ch, best_y )); +#endif + + /* now set the `round' flag depending on the segment's kind: */ + /* */ + /* - if the horizontal distance between the first and last */ + /* `on' point is larger than a heuristic threshold */ + /* we have a flat segment */ + /* - if either the first or the last point of the segment is */ + /* an `off' point, the segment is round, otherwise it is */ + /* flat */ + if ( best_on_point_first >= 0 && + best_on_point_last >= 0 && + ( FT_ABS( points[best_on_point_last].x - + points[best_on_point_first].x ) ) > + flat_threshold ) + round = 0; + else + round = FT_BOOL( + FT_CURVE_TAG( outline.tags[best_segment_first] ) != + FT_CURVE_TAG_ON || + FT_CURVE_TAG( outline.tags[best_segment_last] ) != + FT_CURVE_TAG_ON ); + + if ( round && AF_LATIN_IS_NEUTRAL_BLUE( bs ) ) + { + /* only use flat segments for a neutral blue zone */ + FT_TRACE5(( " (round, skipped)\n" )); + continue; + } + + FT_TRACE5(( " (%s)\n", round ? "round" : "flat" )); + } + + if ( AF_LATIN_IS_TOP_BLUE( bs ) ) + { + if ( best_y > best_y_extremum ) + { + best_y_extremum = best_y; + best_round = round; + } + } + else + { + if ( best_y < best_y_extremum ) + { + best_y_extremum = best_y; + best_round = round; } } - /* for computing blue zones, we add the y offset as returned */ - /* by the currently used OpenType feature -- for example, */ - /* superscript glyphs might be identical to subscript glyphs */ - /* with a vertical shift */ - best_y += y_offset; + } /* end for loop */ - FT_TRACE5(( " U+%04lX: best_y = %5ld", ch, best_y )); - - /* now set the `round' flag depending on the segment's kind: */ - /* */ - /* - if the horizontal distance between the first and last */ - /* `on' point is larger than a heuristic threshold */ - /* we have a flat segment */ - /* - if either the first or the last point of the segment is */ - /* an `off' point, the segment is round, otherwise it is */ - /* flat */ - if ( best_on_point_first >= 0 && - best_on_point_last >= 0 && - ( FT_ABS( points[best_on_point_last].x - - points[best_on_point_first].x ) ) > - flat_threshold ) - round = 0; + if ( !( best_y_extremum == FT_INT_MIN || + best_y_extremum == FT_INT_MAX ) ) + { + if ( best_round ) + rounds[num_rounds++] = best_y_extremum; else - round = FT_BOOL( - FT_CURVE_TAG( outline.tags[best_segment_first] ) != - FT_CURVE_TAG_ON || - FT_CURVE_TAG( outline.tags[best_segment_last] ) != - FT_CURVE_TAG_ON ); - - if ( round && AF_LATIN_IS_NEUTRAL_BLUE( bs ) ) - { - /* only use flat segments for a neutral blue zone */ - FT_TRACE5(( " (round, skipped)\n" )); - continue; - } - - FT_TRACE5(( " (%s)\n", round ? "round" : "flat" )); + flats[num_flats++] = best_y_extremum; } - if ( round ) - rounds[num_rounds++] = best_y; - else - flats[num_flats++] = best_y; - } + } /* end while loop */ if ( num_flats == 0 && num_rounds == 0 ) { @@ -781,7 +929,8 @@ FT_Bool over_ref = FT_BOOL( shoot > ref ); - if ( AF_LATIN_IS_TOP_BLUE( bs ) ^ over_ref ) + if ( ( AF_LATIN_IS_TOP_BLUE( bs ) || + AF_LATIN_IS_SUB_TOP_BLUE( bs) ) ^ over_ref ) { *blue_ref = *blue_shoot = ( shoot + ref ) / 2; @@ -791,9 +940,14 @@ } } + blue->ascender = ascender; + blue->descender = descender; + blue->flags = 0; if ( AF_LATIN_IS_TOP_BLUE( bs ) ) blue->flags |= AF_LATIN_BLUE_TOP; + if ( AF_LATIN_IS_SUB_TOP_BLUE( bs ) ) + blue->flags |= AF_LATIN_BLUE_SUB_TOP; if ( AF_LATIN_IS_NEUTRAL_BLUE( bs ) ) blue->flags |= AF_LATIN_BLUE_NEUTRAL; @@ -808,6 +962,63 @@ FT_TRACE5(( " -> reference = %ld\n" " overshoot = %ld\n", *blue_ref, *blue_shoot )); + + } /* end for loop */ + + af_shaper_buf_destroy( face, shaper_buf ); + + /* we finally check whether blue zones are ordered; */ + /* `ref' and `shoot' values of two blue zones must not overlap */ + if ( axis->blue_count ) + { + FT_UInt i; + AF_LatinBlue blue_sorted[AF_BLUE_STRINGSET_MAX_LEN + 2]; + + + for ( i = 0; i < axis->blue_count; i++ ) + blue_sorted[i] = &axis->blues[i]; + + /* sort bottoms of blue zones... */ + af_latin_sort_blue( axis->blue_count, blue_sorted ); + + /* ...and adjust top values if necessary */ + for ( i = 0; i < axis->blue_count - 1; i++ ) + { + FT_Pos* a; + FT_Pos* b; + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_Bool a_is_top = 0; +#endif + + + if ( blue_sorted[i]->flags & ( AF_LATIN_BLUE_TOP | + AF_LATIN_BLUE_SUB_TOP ) ) + { + a = &blue_sorted[i]->shoot.org; +#ifdef FT_DEBUG_LEVEL_TRACE + a_is_top = 1; +#endif + } + else + a = &blue_sorted[i]->ref.org; + + if ( blue_sorted[i + 1]->flags & ( AF_LATIN_BLUE_TOP | + AF_LATIN_BLUE_SUB_TOP ) ) + b = &blue_sorted[i + 1]->shoot.org; + else + b = &blue_sorted[i + 1]->ref.org; + + if ( *a > *b ) + { + *a = *b; + FT_TRACE5(( "blue zone overlap:" + " adjusting %s %d to %ld\n", + a_is_top ? "overshoot" : "reference", + blue_sorted[i] - axis->blues, + *a )); + } + } } FT_TRACE5(( "\n" )); @@ -822,27 +1033,36 @@ af_latin_metrics_check_digits( AF_LatinMetrics metrics, FT_Face face ) { - FT_UInt i; FT_Bool started = 0, same_width = 1; - FT_Fixed advance, old_advance = 0; + FT_Fixed advance = 0, old_advance = 0; + + void* shaper_buf; + + /* in all supported charmaps, digits have character codes 0x30-0x39 */ + const char digits[] = "0 1 2 3 4 5 6 7 8 9"; + const char* p; - /* digit `0' is 0x30 in all supported charmaps */ - for ( i = 0x30; i <= 0x39; i++ ) + p = digits; + shaper_buf = af_shaper_buf_create( face ); + + while ( *p ) { - FT_ULong glyph_index; - FT_Long y_offset; + FT_ULong glyph_index; + unsigned int num_idx; - af_get_char_index( &metrics->root, i, &glyph_index, &y_offset ); - if ( glyph_index == 0 ) + /* reject input that maps to more than a single glyph */ + p = af_shaper_get_cluster( p, &metrics->root, shaper_buf, &num_idx ); + if ( num_idx > 1 ) continue; - if ( FT_Get_Advance( face, glyph_index, - FT_LOAD_NO_SCALE | - FT_LOAD_NO_HINTING | - FT_LOAD_IGNORE_TRANSFORM, - &advance ) ) + glyph_index = af_shaper_get_elem( &metrics->root, + shaper_buf, + 0, + &advance, + NULL ); + if ( !glyph_index ) continue; if ( started ) @@ -860,6 +1080,8 @@ } } + af_shaper_buf_destroy( face, shaper_buf ); + metrics->root.digits_have_same_width = same_width; } @@ -947,7 +1169,7 @@ FT_UInt ppem; - scaled = FT_MulFix( blue->shoot.org, scaler->y_scale ); + scaled = FT_MulFix( blue->shoot.org, scale ); ppem = metrics->root.scaler.face->size->metrics.x_ppem; limit = metrics->root.globals->increase_x_height; threshold = 40; @@ -973,18 +1195,52 @@ #endif if ( dim == AF_DIMENSION_VERT ) { - scale = FT_MulDiv( scale, fitted, scaled ); + FT_Pos max_height; + FT_Pos dist; + FT_Fixed new_scale; - FT_TRACE5(( - "af_latin_metrics_scale_dim:" - " x height alignment (style `%s'):\n" - " " - " vertical scaling changed from %.4f to %.4f (by %d%%)\n" - "\n", - af_style_names[metrics->root.style_class->style], - axis->org_scale / 65536.0, - scale / 65536.0, - ( fitted - scaled ) * 100 / scaled )); + + new_scale = FT_MulDiv( scale, fitted, scaled ); + + /* the scaling should not change the result by more than two pixels */ + max_height = metrics->units_per_em; + + for ( nn = 0; nn < Axis->blue_count; nn++ ) + { + max_height = FT_MAX( max_height, Axis->blues[nn].ascender ); + max_height = FT_MAX( max_height, -Axis->blues[nn].descender ); + } + + dist = FT_ABS( FT_MulFix( max_height, new_scale - scale ) ); + dist &= ~127; + + if ( dist == 0 ) + { + FT_TRACE5(( + "af_latin_metrics_scale_dim:" + " x height alignment (style `%s'):\n" + " " + " vertical scaling changed from %.5f to %.5f (by %d%%)\n" + "\n", + af_style_names[metrics->root.style_class->style], + scale / 65536.0, + new_scale / 65536.0, + ( fitted - scaled ) * 100 / scaled )); + + scale = new_scale; + } +#ifdef FT_DEBUG_LEVEL_TRACE + else + { + FT_TRACE5(( + "af_latin_metrics_scale_dim:" + " x height alignment (style `%s'):\n" + " " + " excessive vertical scaling abandoned\n" + "\n", + af_style_names[metrics->root.style_class->style] )); + } +#endif } } } @@ -1115,21 +1371,63 @@ #endif blue->flags |= AF_LATIN_BLUE_ACTIVE; - - FT_TRACE5(( " reference %d: %d scaled to %.2f%s\n" - " overshoot %d: %d scaled to %.2f%s\n", - nn, - blue->ref.org, - blue->ref.fit / 64.0, - blue->flags & AF_LATIN_BLUE_ACTIVE ? "" - : " (inactive)", - nn, - blue->shoot.org, - blue->shoot.fit / 64.0, - blue->flags & AF_LATIN_BLUE_ACTIVE ? "" - : " (inactive)" )); } } + + /* use sub-top blue zone only if it doesn't overlap with */ + /* another (non-sup-top) blue zone; otherwise, the */ + /* effect would be similar to a neutral blue zone, which */ + /* is not desired here */ + for ( nn = 0; nn < axis->blue_count; nn++ ) + { + AF_LatinBlue blue = &axis->blues[nn]; + FT_UInt i; + + + if ( !( blue->flags & AF_LATIN_BLUE_SUB_TOP ) ) + continue; + if ( !( blue->flags & AF_LATIN_BLUE_ACTIVE ) ) + continue; + + for ( i = 0; i < axis->blue_count; i++ ) + { + AF_LatinBlue b = &axis->blues[i]; + + + if ( b->flags & AF_LATIN_BLUE_SUB_TOP ) + continue; + if ( !( b->flags & AF_LATIN_BLUE_ACTIVE ) ) + continue; + + if ( b->ref.fit <= blue->shoot.fit && + b->shoot.fit >= blue->ref.fit ) + { + blue->flags &= ~AF_LATIN_BLUE_ACTIVE; + break; + } + } + } + +#ifdef FT_DEBUG_LEVEL_TRACE + for ( nn = 0; nn < axis->blue_count; nn++ ) + { + AF_LatinBlue blue = &axis->blues[nn]; + + + FT_TRACE5(( " reference %d: %d scaled to %.2f%s\n" + " overshoot %d: %d scaled to %.2f%s\n", + nn, + blue->ref.org, + blue->ref.fit / 64.0, + blue->flags & AF_LATIN_BLUE_ACTIVE ? "" + : " (inactive)", + nn, + blue->shoot.org, + blue->shoot.fit / 64.0, + blue->flags & AF_LATIN_BLUE_ACTIVE ? "" + : " (inactive)" )); + } +#endif } } @@ -1149,6 +1447,22 @@ } + /* Extract standard_width from writing system/script specific */ + /* metrics class. */ + + FT_LOCAL_DEF( void ) + af_latin_get_standard_widths( AF_LatinMetrics metrics, + FT_Pos* stdHW, + FT_Pos* stdVW ) + { + if ( stdHW ) + *stdHW = metrics->axis[AF_DIMENSION_VERT].standard_width; + + if ( stdVW ) + *stdVW = metrics->axis[AF_DIMENSION_HORZ].standard_width; + } + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -1215,18 +1529,35 @@ /* do each contour separately */ for ( ; contour < contour_limit; contour++ ) { - AF_Point point = contour[0]; - AF_Point last = point->prev; - int on_edge = 0; - FT_Pos min_pos = 32000; /* minimum segment pos != min_coord */ - FT_Pos max_pos = -32000; /* maximum segment pos != max_coord */ - FT_Pos min_on_pos = 32000; - FT_Pos max_on_pos = -32000; - FT_Bool passed; + AF_Point point = contour[0]; + AF_Point last = point->prev; + int on_edge = 0; + /* we call values measured along a segment (point->v) */ + /* `coordinates', and values orthogonal to it (point->u) */ + /* `positions' */ + FT_Pos min_pos = 32000; + FT_Pos max_pos = -32000; + FT_Pos min_coord = 32000; + FT_Pos max_coord = -32000; + FT_UShort min_flags = AF_FLAG_NONE; + FT_UShort max_flags = AF_FLAG_NONE; + FT_Pos min_on_coord = 32000; + FT_Pos max_on_coord = -32000; + + FT_Bool passed; + + AF_Segment prev_segment = NULL; + + FT_Pos prev_min_pos = min_pos; + FT_Pos prev_max_pos = max_pos; + FT_Pos prev_min_coord = min_coord; + FT_Pos prev_max_coord = max_coord; + FT_UShort prev_min_flags = min_flags; + FT_UShort prev_max_flags = max_flags; + FT_Pos prev_min_on_coord = min_on_coord; + FT_Pos prev_max_on_coord = max_on_coord; - if ( point == last ) /* skip singletons -- just in case */ - continue; if ( FT_ABS( last->out_dir ) == major_dir && FT_ABS( point->out_dir ) == major_dir ) @@ -1257,51 +1588,187 @@ if ( on_edge ) { + /* get minimum and maximum position */ u = point->u; if ( u < min_pos ) min_pos = u; if ( u > max_pos ) max_pos = u; - /* get minimum and maximum coordinate of on points */ + /* get minimum and maximum coordinate together with flags */ + v = point->v; + if ( v < min_coord ) + { + min_coord = v; + min_flags = point->flags; + } + if ( v > max_coord ) + { + max_coord = v; + max_flags = point->flags; + } + + /* get minimum and maximum coordinate of `on' points */ if ( !( point->flags & AF_FLAG_CONTROL ) ) { v = point->v; - if ( v < min_on_pos ) - min_on_pos = v; - if ( v > max_on_pos ) - max_on_pos = v; + if ( v < min_on_coord ) + min_on_coord = v; + if ( v > max_on_coord ) + max_on_coord = v; } if ( point->out_dir != segment_dir || point == last ) { - /* we are just leaving an edge; record a new segment! */ - segment->last = point; - segment->pos = (FT_Short)( ( min_pos + max_pos ) >> 1 ); + /* check whether the new segment's start point is identical to */ + /* the previous segment's end point; for example, this might */ + /* happen for spikes */ - /* a segment is round if either its first or last point */ - /* is a control point, and the length of the on points */ - /* inbetween doesn't exceed a heuristic limit */ - if ( ( segment->first->flags | point->flags ) & AF_FLAG_CONTROL && - ( max_on_pos - min_on_pos ) < flat_threshold ) - segment->flags |= AF_EDGE_ROUND; + if ( !prev_segment || segment->first != prev_segment->last ) + { + /* points are different: we are just leaving an edge, thus */ + /* record a new segment */ - /* compute segment size */ - min_pos = max_pos = point->v; + segment->last = point; + segment->pos = (FT_Short)( ( min_pos + max_pos ) >> 1 ); + segment->delta = (FT_Short)( ( max_pos - min_pos ) >> 1 ); - v = segment->first->v; - if ( v < min_pos ) - min_pos = v; - if ( v > max_pos ) - max_pos = v; + /* a segment is round if either its first or last point */ + /* is a control point, and the length of the on points */ + /* inbetween doesn't exceed a heuristic limit */ + if ( ( min_flags | max_flags ) & AF_FLAG_CONTROL && + ( max_on_coord - min_on_coord ) < flat_threshold ) + segment->flags |= AF_EDGE_ROUND; - segment->min_coord = (FT_Short)min_pos; - segment->max_coord = (FT_Short)max_pos; - segment->height = (FT_Short)( segment->max_coord - - segment->min_coord ); + segment->min_coord = (FT_Short)min_coord; + segment->max_coord = (FT_Short)max_coord; + segment->height = segment->max_coord - segment->min_coord; + + prev_segment = segment; + prev_min_pos = min_pos; + prev_max_pos = max_pos; + prev_min_coord = min_coord; + prev_max_coord = max_coord; + prev_min_flags = min_flags; + prev_max_flags = max_flags; + prev_min_on_coord = min_on_coord; + prev_max_on_coord = max_on_coord; + } + else + { + /* points are the same: we don't create a new segment but */ + /* merge the current segment with the previous one */ + + if ( prev_segment->last->in_dir == point->in_dir ) + { + /* we have identical directions (this can happen for */ + /* degenerate outlines that move zig-zag along the main */ + /* axis without changing the coordinate value of the other */ + /* axis, and where the segments have just been merged): */ + /* unify segments */ + + /* update constraints */ + + if ( prev_min_pos < min_pos ) + min_pos = prev_min_pos; + if ( prev_max_pos > max_pos ) + max_pos = prev_max_pos; + + if ( prev_min_coord < min_coord ) + { + min_coord = prev_min_coord; + min_flags = prev_min_flags; + } + if ( prev_max_coord > max_coord ) + { + max_coord = prev_max_coord; + max_flags = prev_max_flags; + } + + if ( prev_min_on_coord < min_on_coord ) + min_on_coord = prev_min_on_coord; + if ( prev_max_on_coord > max_on_coord ) + max_on_coord = prev_max_on_coord; + + prev_segment->last = point; + prev_segment->pos = (FT_Short)( ( min_pos + + max_pos ) >> 1 ); + prev_segment->delta = (FT_Short)( ( max_pos - + min_pos ) >> 1 ); + + if ( ( min_flags | max_flags ) & AF_FLAG_CONTROL && + ( max_on_coord - min_on_coord ) < flat_threshold ) + prev_segment->flags |= AF_EDGE_ROUND; + else + prev_segment->flags &= ~AF_EDGE_ROUND; + + prev_segment->min_coord = (FT_Short)min_coord; + prev_segment->max_coord = (FT_Short)max_coord; + prev_segment->height = prev_segment->max_coord - + prev_segment->min_coord; + } + else + { + /* we have different directions; use the properties of the */ + /* longer segment and discard the other one */ + + if ( FT_ABS( prev_max_coord - prev_min_coord ) > + FT_ABS( max_coord - min_coord ) ) + { + /* discard current segment */ + + if ( min_pos < prev_min_pos ) + prev_min_pos = min_pos; + if ( max_pos > prev_max_pos ) + prev_max_pos = max_pos; + + prev_segment->last = point; + prev_segment->pos = (FT_Short)( ( prev_min_pos + + prev_max_pos ) >> 1 ); + prev_segment->delta = (FT_Short)( ( prev_max_pos - + prev_min_pos ) >> 1 ); + } + else + { + /* discard previous segment */ + + if ( prev_min_pos < min_pos ) + min_pos = prev_min_pos; + if ( prev_max_pos > max_pos ) + max_pos = prev_max_pos; + + segment->last = point; + segment->pos = (FT_Short)( ( min_pos + max_pos ) >> 1 ); + segment->delta = (FT_Short)( ( max_pos - min_pos ) >> 1 ); + + if ( ( min_flags | max_flags ) & AF_FLAG_CONTROL && + ( max_on_coord - min_on_coord ) < flat_threshold ) + segment->flags |= AF_EDGE_ROUND; + + segment->min_coord = (FT_Short)min_coord; + segment->max_coord = (FT_Short)max_coord; + segment->height = segment->max_coord - + segment->min_coord; + + *prev_segment = *segment; + + prev_min_pos = min_pos; + prev_max_pos = max_pos; + prev_min_coord = min_coord; + prev_max_coord = max_coord; + prev_min_flags = min_flags; + prev_max_flags = max_flags; + prev_min_on_coord = min_on_coord; + prev_max_on_coord = max_on_coord; + } + } + + axis->num_segments--; + } on_edge = 0; segment = NULL; + /* fall through */ } } @@ -1314,7 +1781,12 @@ passed = 1; } - if ( !on_edge && FT_ABS( point->out_dir ) == major_dir ) + /* if we are not on an edge, check whether the major direction */ + /* coincides with the current point's `out' direction, or */ + /* whether we have a single-point contour */ + if ( !on_edge && + ( FT_ABS( point->out_dir ) == major_dir || + point == point->prev ) ) { /* this is the start of a new segment! */ segment_dir = (AF_Direction)point->out_dir; @@ -1330,17 +1802,42 @@ segment->first = point; segment->last = point; - min_pos = max_pos = point->u; + /* `af_axis_hints_new_segment' reallocates memory, */ + /* thus we have to refresh the `prev_segment' pointer */ + if ( prev_segment ) + prev_segment = segment - 1; + + min_pos = max_pos = point->u; + min_coord = max_coord = point->v; + min_flags = max_flags = point->flags; if ( point->flags & AF_FLAG_CONTROL ) { - min_on_pos = 32000; - max_on_pos = -32000; + min_on_coord = 32000; + max_on_coord = -32000; } else - min_on_pos = max_on_pos = point->v; + min_on_coord = max_on_coord = point->v; on_edge = 1; + + if ( point == point->prev ) + { + /* we have a one-point segment: this is a one-point */ + /* contour with `in' and `out' direction set to */ + /* AF_DIR_NONE */ + segment->pos = (FT_Short)min_pos; + + if (point->flags & AF_FLAG_CONTROL) + segment->flags |= AF_EDGE_ROUND; + + segment->min_coord = (FT_Short)point->v; + segment->max_coord = (FT_Short)point->v; + segment->height = 0; + + on_edge = 0; + segment = NULL; + } } point = point->next; @@ -1552,6 +2049,16 @@ FT_Memory memory = hints->memory; AF_LatinAxis laxis = &((AF_LatinMetrics)hints->metrics)->axis[dim]; +#ifdef FT_CONFIG_OPTION_PIC + AF_FaceGlobals globals = hints->metrics->globals; +#endif + + AF_StyleClass style_class = hints->metrics->style_class; + AF_ScriptClass script_class = AF_SCRIPT_CLASSES_GET + [style_class->script]; + + FT_Bool top_to_bottom_hinting = 0; + AF_Segment segments = axis->segments; AF_Segment segment_limit = segments + axis->num_segments; AF_Segment seg; @@ -1562,6 +2069,7 @@ FT_Fixed scale; FT_Pos edge_distance_threshold; FT_Pos segment_length_threshold; + FT_Pos segment_width_threshold; axis->num_edges = 0; @@ -1574,15 +2082,24 @@ : AF_DIR_RIGHT; #endif + if ( dim == AF_DIMENSION_VERT ) + top_to_bottom_hinting = script_class->top_to_bottom_hinting; + /* * We ignore all segments that are less than 1 pixel in length * to avoid many problems with serif fonts. We compute the * corresponding threshold in font units. */ if ( dim == AF_DIMENSION_HORZ ) - segment_length_threshold = FT_DivFix( 64, hints->y_scale ); + segment_length_threshold = FT_DivFix( 64, hints->y_scale ); else - segment_length_threshold = 0; + segment_length_threshold = 0; + + /* + * Similarly, we ignore segments that have a width delta + * larger than 0.5px (i.e., a width larger than 1px). + */ + segment_width_threshold = FT_DivFix( 32, scale ); /*********************************************************************/ /* */ @@ -1615,7 +2132,11 @@ FT_Int ee; - if ( seg->height < segment_length_threshold ) + /* ignore too short segments, too wide ones, and, in this loop, */ + /* one-point segments without a direction */ + if ( seg->height < segment_length_threshold || + seg->delta > segment_width_threshold || + seg->dir == AF_DIR_NONE ) continue; /* A special case for serif edges: If they are smaller than */ @@ -1651,6 +2172,7 @@ /* sort according to the position */ error = af_axis_hints_new_edge( axis, seg->pos, (AF_Direction)seg->dir, + top_to_bottom_hinting, memory, &edge ); if ( error ) goto Exit; @@ -1676,6 +2198,44 @@ } } + /* we loop again over all segments to catch one-point segments */ + /* without a direction: if possible, link them to existing edges */ + for ( seg = segments; seg < segment_limit; seg++ ) + { + AF_Edge found = NULL; + FT_Int ee; + + + if ( seg->dir != AF_DIR_NONE ) + continue; + + /* look for an edge corresponding to the segment */ + for ( ee = 0; ee < axis->num_edges; ee++ ) + { + AF_Edge edge = axis->edges + ee; + FT_Pos dist; + + + dist = seg->pos - edge->fpos; + if ( dist < 0 ) + dist = -dist; + + if ( dist < edge_distance_threshold ) + { + found = edge; + break; + } + } + + /* one-point segments without a match are ignored */ + if ( found ) + { + seg->edge_next = found->first; + found->last->edge_next = seg; + found->last = seg; + } + } + /******************************************************************/ /* */ @@ -1753,7 +2313,7 @@ seg->serif->edge && seg->serif->edge != edge ); - if ( ( seg->link && seg->link->edge != NULL ) || is_serif ) + if ( ( seg->link && seg->link->edge ) || is_serif ) { AF_Edge edge2; AF_Segment seg2; @@ -1906,7 +2466,8 @@ /* the major direction) -- this assumes the TrueType convention */ /* for the orientation of contours */ is_top_blue = - (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_TOP ) != 0 ); + (FT_Byte)( ( blue->flags & ( AF_LATIN_BLUE_TOP | + AF_LATIN_BLUE_SUB_TOP ) ) != 0 ); is_neutral_blue = (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_NEUTRAL ) != 0); is_major_dir = @@ -2019,23 +2580,23 @@ other_flags |= AF_LATIN_HINTS_VERT_SNAP; /* - * We adjust stems to full pixels only if we don't use the `light' mode. + * We adjust stems to full pixels unless in `light' or `lcd' mode. */ - if ( mode != FT_RENDER_MODE_LIGHT ) + if ( mode != FT_RENDER_MODE_LIGHT && mode != FT_RENDER_MODE_LCD ) other_flags |= AF_LATIN_HINTS_STEM_ADJUST; if ( mode == FT_RENDER_MODE_MONO ) other_flags |= AF_LATIN_HINTS_MONO; /* - * In `light' hinting mode we disable horizontal hinting completely. + * In `light' or `lcd' mode we disable horizontal hinting completely. * We also do it if the face is italic. * * However, if warping is enabled (which only works in `light' hinting * mode), advance widths get adjusted, too. */ - if ( mode == FT_RENDER_MODE_LIGHT || - ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0 ) + if ( mode == FT_RENDER_MODE_LIGHT || mode == FT_RENDER_MODE_LCD || + ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0 ) scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL; #ifdef AF_CONFIG_OPTION_USE_WARPER @@ -2115,6 +2676,7 @@ af_latin_compute_stem_width( AF_GlyphHints hints, AF_Dimension dim, FT_Pos width, + FT_Pos base_delta, FT_UInt base_flags, FT_UInt stem_flags ) { @@ -2192,7 +2754,39 @@ dist += delta; } else - dist = ( dist + 32 ) & ~63; + { + /* A stem's end position depends on two values: the start */ + /* position and the stem length. The former gets usually */ + /* rounded to the grid, while the latter gets rounded also if it */ + /* exceeds a certain length (see below in this function). This */ + /* `double rounding' can lead to a great difference to the */ + /* original, unhinted position; this normally doesn't matter for */ + /* large PPEM values, but for small sizes it can easily make */ + /* outlines collide. For this reason, we adjust the stem length */ + /* by a small amount depending on the PPEM value in case the */ + /* former and latter rounding both point into the same */ + /* direction. */ + + FT_Pos bdelta = 0; + + + if ( ( ( width > 0 ) && ( base_delta > 0 ) ) || + ( ( width < 0 ) && ( base_delta < 0 ) ) ) + { + FT_UInt ppem = metrics->root.scaler.face->size->metrics.x_ppem; + + + if ( ppem < 10 ) + bdelta = base_delta; + else if ( ppem < 30 ) + bdelta = ( base_delta * (FT_Pos)( 30 - ppem ) ) / 20; + + if ( bdelta < 0 ) + bdelta = -bdelta; + } + + dist = ( dist - bdelta + 32 ) & ~63; + } } } else @@ -2281,11 +2875,17 @@ AF_Edge base_edge, AF_Edge stem_edge ) { - FT_Pos dist = stem_edge->opos - base_edge->opos; + FT_Pos dist, base_delta; + FT_Pos fitted_width; - FT_Pos fitted_width = af_latin_compute_stem_width( hints, dim, dist, - base_edge->flags, - stem_edge->flags ); + + dist = stem_edge->opos - base_edge->opos; + base_delta = base_edge->pos - base_edge->opos; + + fitted_width = af_latin_compute_stem_width( hints, dim, + dist, base_delta, + base_edge->flags, + stem_edge->flags ); stem_edge->pos = base_edge->pos + fitted_width; @@ -2336,8 +2936,18 @@ AF_Edge anchor = NULL; FT_Int has_serifs = 0; +#ifdef FT_CONFIG_OPTION_PIC + AF_FaceGlobals globals = hints->metrics->globals; +#endif + + AF_StyleClass style_class = hints->metrics->style_class; + AF_ScriptClass script_class = AF_SCRIPT_CLASSES_GET + [style_class->script]; + + FT_Bool top_to_bottom_hinting = 0; + #ifdef FT_DEBUG_LEVEL_TRACE - FT_UInt num_actions = 0; + FT_UInt num_actions = 0; #endif @@ -2345,6 +2955,9 @@ dim == AF_DIMENSION_VERT ? "horizontal" : "vertical", af_style_names[hints->metrics->style_class->style] )); + if ( dim == AF_DIMENSION_VERT ) + top_to_bottom_hinting = script_class->top_to_bottom_hinting; + /* we begin by aligning all stems relative to the blue zone */ /* if needed -- that's only for horizontal edges */ @@ -2480,7 +3093,8 @@ org_len = edge2->opos - edge->opos; - cur_len = af_latin_compute_stem_width( hints, dim, org_len, + cur_len = af_latin_compute_stem_width( hints, dim, + org_len, 0, edge->flags, edge2->flags ); @@ -2549,7 +3163,8 @@ org_len = edge2->opos - edge->opos; org_center = org_pos + ( org_len >> 1 ); - cur_len = af_latin_compute_stem_width( hints, dim, org_len, + cur_len = af_latin_compute_stem_width( hints, dim, + org_len, 0, edge->flags, edge2->flags ); @@ -2609,7 +3224,8 @@ org_len = edge2->opos - edge->opos; org_center = org_pos + ( org_len >> 1 ); - cur_len = af_latin_compute_stem_width( hints, dim, org_len, + cur_len = af_latin_compute_stem_width( hints, dim, + org_len, 0, edge->flags, edge2->flags ); @@ -2640,16 +3256,25 @@ edge->flags |= AF_EDGE_DONE; edge2->flags |= AF_EDGE_DONE; - if ( edge > edges && edge->pos < edge[-1].pos ) + if ( edge > edges && + ( top_to_bottom_hinting ? ( edge->pos > edge[-1].pos ) + : ( edge->pos < edge[-1].pos ) ) ) { + /* don't move if stem would (almost) disappear otherwise; */ + /* the ad-hoc value 16 corresponds to 1/4px */ + if ( edge->link && FT_ABS( edge->link->pos - edge[-1].pos ) > 16 ) + { #ifdef FT_DEBUG_LEVEL_TRACE - FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n", - edge - edges, edge->pos / 64.0, edge[-1].pos / 64.0 )); + FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n", + edge - edges, + edge->pos / 64.0, + edge[-1].pos / 64.0 )); - num_actions++; + num_actions++; #endif - edge->pos = edge[-1].pos; + edge->pos = edge[-1].pos; + } } } } @@ -2801,29 +3426,46 @@ #endif edge->flags |= AF_EDGE_DONE; - if ( edge > edges && edge->pos < edge[-1].pos ) + if ( edge > edges && + ( top_to_bottom_hinting ? ( edge->pos > edge[-1].pos ) + : ( edge->pos < edge[-1].pos ) ) ) { + /* don't move if stem would (almost) disappear otherwise; */ + /* the ad-hoc value 16 corresponds to 1/4px */ + if ( edge->link && FT_ABS( edge->link->pos - edge[-1].pos ) > 16 ) + { #ifdef FT_DEBUG_LEVEL_TRACE - FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n", - edge - edges, edge->pos / 64.0, edge[-1].pos / 64.0 )); + FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n", + edge - edges, + edge->pos / 64.0, + edge[-1].pos / 64.0 )); - num_actions++; + num_actions++; #endif - edge->pos = edge[-1].pos; + edge->pos = edge[-1].pos; + } } - if ( edge + 1 < edge_limit && - edge[1].flags & AF_EDGE_DONE && - edge->pos > edge[1].pos ) + if ( edge + 1 < edge_limit && + edge[1].flags & AF_EDGE_DONE && + ( top_to_bottom_hinting ? ( edge->pos < edge[1].pos ) + : ( edge->pos > edge[1].pos ) ) ) { + /* don't move if stem would (almost) disappear otherwise; */ + /* the ad-hoc value 16 corresponds to 1/4px */ + if ( edge->link && FT_ABS( edge->link->pos - edge[-1].pos ) > 16 ) + { #ifdef FT_DEBUG_LEVEL_TRACE - FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n", - edge - edges, edge->pos / 64.0, edge[1].pos / 64.0 )); + FT_TRACE5(( " BOUND: edge %d (pos=%.2f) moved to %.2f\n", + edge - edges, + edge->pos / 64.0, + edge[1].pos / 64.0 )); - num_actions++; + num_actions++; #endif - edge->pos = edge[1].pos; + edge->pos = edge[1].pos; + } } } } @@ -2855,13 +3497,7 @@ goto Exit; /* analyze glyph outline */ -#ifdef AF_CONFIG_OPTION_USE_WARPER - if ( ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT && - AF_HINTS_DO_WARP( hints ) ) || - AF_HINTS_DO_HORIZONTAL( hints ) ) -#else if ( AF_HINTS_DO_HORIZONTAL( hints ) ) -#endif { axis = &metrics->axis[AF_DIMENSION_HORZ]; error = af_latin_hints_detect_features( hints, @@ -2891,9 +3527,9 @@ for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) { #ifdef AF_CONFIG_OPTION_USE_WARPER - if ( dim == AF_DIMENSION_HORZ && - metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT && - AF_HINTS_DO_WARP( hints ) ) + if ( dim == AF_DIMENSION_HORZ && + metrics->root.scaler.render_mode == FT_RENDER_MODE_NORMAL && + AF_HINTS_DO_WARP( hints ) ) { AF_WarperRec warper; FT_Fixed scale; @@ -2941,12 +3577,13 @@ sizeof ( AF_LatinMetricsRec ), - (AF_WritingSystem_InitMetricsFunc) af_latin_metrics_init, - (AF_WritingSystem_ScaleMetricsFunc)af_latin_metrics_scale, - (AF_WritingSystem_DoneMetricsFunc) NULL, + (AF_WritingSystem_InitMetricsFunc) af_latin_metrics_init, /* style_metrics_init */ + (AF_WritingSystem_ScaleMetricsFunc)af_latin_metrics_scale, /* style_metrics_scale */ + (AF_WritingSystem_DoneMetricsFunc) NULL, /* style_metrics_done */ + (AF_WritingSystem_GetStdWidthsFunc)af_latin_get_standard_widths, /* style_metrics_getstdw */ - (AF_WritingSystem_InitHintsFunc) af_latin_hints_init, - (AF_WritingSystem_ApplyHintsFunc) af_latin_hints_apply + (AF_WritingSystem_InitHintsFunc) af_latin_hints_init, /* style_hints_init */ + (AF_WritingSystem_ApplyHintsFunc) af_latin_hints_apply /* style_hints_apply */ ) diff --git a/src/3rdparty/freetype/src/autofit/aflatin.h b/src/3rdparty/freetype/src/autofit/aflatin.h index 6855492ca3..432cccce4e 100644 --- a/src/3rdparty/freetype/src/autofit/aflatin.h +++ b/src/3rdparty/freetype/src/autofit/aflatin.h @@ -5,7 +5,7 @@ /* Auto-fitter hinting routines for latin writing system */ /* (specification). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __AFLATIN_H__ -#define __AFLATIN_H__ +#ifndef AFLATIN_H_ +#define AFLATIN_H_ #include "afhints.h" @@ -53,6 +53,8 @@ FT_BEGIN_HEADER #define AF_LATIN_IS_TOP_BLUE( b ) \ ( (b)->properties & AF_BLUE_PROPERTY_LATIN_TOP ) +#define AF_LATIN_IS_SUB_TOP_BLUE( b ) \ + ( (b)->properties & AF_BLUE_PROPERTY_LATIN_SUB_TOP ) #define AF_LATIN_IS_NEUTRAL_BLUE( b ) \ ( (b)->properties & AF_BLUE_PROPERTY_LATIN_NEUTRAL ) #define AF_LATIN_IS_X_HEIGHT_BLUE( b ) \ @@ -65,8 +67,10 @@ FT_BEGIN_HEADER #define AF_LATIN_BLUE_ACTIVE ( 1U << 0 ) /* zone height is <= 3/4px */ #define AF_LATIN_BLUE_TOP ( 1U << 1 ) /* we have a top blue zone */ -#define AF_LATIN_BLUE_NEUTRAL ( 1U << 2 ) /* we have neutral blue zone */ -#define AF_LATIN_BLUE_ADJUSTMENT ( 1U << 3 ) /* used for scale adjustment */ +#define AF_LATIN_BLUE_SUB_TOP ( 1U << 2 ) /* we have a subscript top */ + /* blue zone */ +#define AF_LATIN_BLUE_NEUTRAL ( 1U << 3 ) /* we have neutral blue zone */ +#define AF_LATIN_BLUE_ADJUSTMENT ( 1U << 4 ) /* used for scale adjustment */ /* optimization */ @@ -74,6 +78,8 @@ FT_BEGIN_HEADER { AF_WidthRec ref; AF_WidthRec shoot; + FT_Pos ascender; + FT_Pos descender; FT_UInt flags; } AF_LatinBlueRec, *AF_LatinBlue; @@ -182,7 +188,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __AFLATIN_H__ */ +#endif /* AFLATIN_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/autofit/aflatin2.c b/src/3rdparty/freetype/src/autofit/aflatin2.c index 0380ffc04c..5c71378118 100644 --- a/src/3rdparty/freetype/src/autofit/aflatin2.c +++ b/src/3rdparty/freetype/src/autofit/aflatin2.c @@ -1,10 +1,15 @@ +/* ATTENTION: This file doesn't compile. It is only here as a reference */ +/* of an alternative latin hinting algorithm that was always */ +/* marked as experimental. */ + + /***************************************************************************/ /* */ /* aflatin2.c */ /* */ /* Auto-fitter hinting routines for latin writing system (body). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,6 +23,9 @@ #include FT_ADVANCES_H + +#ifdef FT_OPTION_AUTOFIT2 + #include "afglobal.h" #include "aflatin.h" #include "aflatin2.h" @@ -693,6 +701,22 @@ } + /* Extract standard_width from writing system/script specific */ + /* metrics class. */ + + FT_LOCAL_DEF( void ) + af_latin2_get_standard_widths( AF_LatinMetrics metrics, + FT_Pos* stdHW, + FT_Pos* stdVW ) + { + if ( stdHW ) + *stdHW = metrics->axis[AF_DIMENSION_VERT].standard_width; + + if ( stdVW ) + *stdVW = metrics->axis[AF_DIMENSION_HORZ].standard_width; + } + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -1179,7 +1203,7 @@ /* insert a new edge in the list and */ /* sort according to the position */ - error = af_axis_hints_new_edge( axis, seg->pos, seg->dir, + error = af_axis_hints_new_edge( axis, seg->pos, seg->dir, 0, memory, &edge ); if ( error ) goto Exit; @@ -1282,7 +1306,7 @@ seg->serif->edge && seg->serif->edge != edge ); - if ( ( seg->link && seg->link->edge != NULL ) || is_serif ) + if ( ( seg->link && seg->link->edge ) || is_serif ) { AF_Edge edge2; AF_Segment seg2; @@ -1534,20 +1558,20 @@ other_flags |= AF_LATIN_HINTS_VERT_SNAP; /* - * We adjust stems to full pixels only if we don't use the `light' mode. + * We adjust stems to full pixels unless in `light' or `lcd' mode. */ - if ( mode != FT_RENDER_MODE_LIGHT ) + if ( mode != FT_RENDER_MODE_LIGHT && mode != FT_RENDER_MODE_LCD ) other_flags |= AF_LATIN_HINTS_STEM_ADJUST; if ( mode == FT_RENDER_MODE_MONO ) other_flags |= AF_LATIN_HINTS_MONO; /* - * In `light' hinting mode we disable horizontal hinting completely. + * In `light' or `lcd' mode we disable horizontal hinting completely. * We also do it if the face is italic. */ - if ( mode == FT_RENDER_MODE_LIGHT || - ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0 ) + if ( mode == FT_RENDER_MODE_LIGHT || mode == FT_RENDER_MODE_LCD || + ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0 ) scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL; #ifdef AF_CONFIG_OPTION_USE_WARPER @@ -2316,13 +2340,7 @@ goto Exit; /* analyze glyph outline */ -#ifdef AF_CONFIG_OPTION_USE_WARPER - if ( ( metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT && - AF_HINTS_DO_WARP( hints ) ) || - AF_HINTS_DO_HORIZONTAL( hints ) ) -#else if ( AF_HINTS_DO_HORIZONTAL( hints ) ) -#endif { error = af_latin2_hints_detect_features( hints, AF_DIMENSION_HORZ ); if ( error ) @@ -2342,9 +2360,9 @@ for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) { #ifdef AF_CONFIG_OPTION_USE_WARPER - if ( dim == AF_DIMENSION_HORZ && - metrics->root.scaler.render_mode == FT_RENDER_MODE_LIGHT && - AF_HINTS_DO_WARP( hints ) ) + if ( dim == AF_DIMENSION_HORZ && + metrics->root.scaler.render_mode == FT_RENDER_MODE_NORMAL && + AF_HINTS_DO_WARP( hints ) ) { AF_WarperRec warper; FT_Fixed scale; @@ -2389,13 +2407,21 @@ sizeof ( AF_LatinMetricsRec ), - (AF_WritingSystem_InitMetricsFunc) af_latin2_metrics_init, - (AF_WritingSystem_ScaleMetricsFunc)af_latin2_metrics_scale, - (AF_WritingSystem_DoneMetricsFunc) NULL, + (AF_WritingSystem_InitMetricsFunc) af_latin2_metrics_init, /* style_metrics_init */ + (AF_WritingSystem_ScaleMetricsFunc)af_latin2_metrics_scale, /* style_metrics_scale */ + (AF_WritingSystem_DoneMetricsFunc) NULL, /* style_metrics_done */ + (AF_WritingSystem_GetStdWidthsFunc)af_latin2_get_standard_widths, /* style_metrics_getstdw */ - (AF_WritingSystem_InitHintsFunc) af_latin2_hints_init, - (AF_WritingSystem_ApplyHintsFunc) af_latin2_hints_apply + (AF_WritingSystem_InitHintsFunc) af_latin2_hints_init, /* style_hints_init */ + (AF_WritingSystem_ApplyHintsFunc) af_latin2_hints_apply /* style_hints_apply */ ) +#else /* !FT_OPTION_AUTOFIT2 */ + + /* ANSI C doesn't like empty source files */ + typedef int _af_latin2_dummy; + +#endif /* !FT_OPTION_AUTOFIT2 */ + /* END */ diff --git a/src/3rdparty/freetype/src/autofit/aflatin2.h b/src/3rdparty/freetype/src/autofit/aflatin2.h index 9326753130..0129dc707e 100644 --- a/src/3rdparty/freetype/src/autofit/aflatin2.h +++ b/src/3rdparty/freetype/src/autofit/aflatin2.h @@ -1,3 +1,8 @@ +/* ATTENTION: This file doesn't compile. It is only here as a reference */ +/* of an alternative latin hinting algorithm that was always */ +/* marked as experimental. */ + + /***************************************************************************/ /* */ /* aflatin2.h */ @@ -5,7 +10,7 @@ /* Auto-fitter hinting routines for latin writing system */ /* (specification). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +22,8 @@ /***************************************************************************/ -#ifndef __AFLATIN2_H__ -#define __AFLATIN2_H__ +#ifndef AFLATIN2_H_ +#define AFLATIN2_H_ #include "afhints.h" @@ -35,7 +40,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __AFLATIN_H__ */ +#endif /* AFLATIN_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/autofit/afloader.c b/src/3rdparty/freetype/src/autofit/afloader.c index 722ffd31ec..a55550b338 100644 --- a/src/3rdparty/freetype/src/autofit/afloader.c +++ b/src/3rdparty/freetype/src/autofit/afloader.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter glyph loading routines (body). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,6 +23,8 @@ #include "afmodule.h" #include "afpic.h" +#include FT_INTERNAL_CALC_H + /* Initialize glyph loader. */ @@ -49,7 +51,7 @@ loader->face = face; loader->globals = (AF_FaceGlobals)face->autohint.data; - if ( loader->globals == NULL ) + if ( !loader->globals ) { error = af_face_globals_new( face, &loader->globals, module ); if ( !error ) @@ -76,41 +78,324 @@ } - /* Do the main work of `af_loader_load_glyph'. Note that we never */ - /* have to deal with composite glyphs as those get loaded into */ - /* FT_GLYPH_FORMAT_OUTLINE by the recursed `FT_Load_Glyph' function. */ - /* In the rare cases where FT_LOAD_NO_RECURSE is set, it implies */ - /* FT_LOAD_NO_SCALE and as such the auto-hinter is never called. */ +#define af_intToFixed( i ) \ + ( (FT_Fixed)( (FT_UInt32)(i) << 16 ) ) +#define af_fixedToInt( x ) \ + ( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) ) +#define af_floatToFixed( f ) \ + ( (FT_Fixed)( (f) * 65536.0 + 0.5 ) ) + static FT_Error - af_loader_load_g( AF_Loader loader, - AF_Scaler scaler, - FT_UInt glyph_index, - FT_Int32 load_flags ) + af_loader_embolden_glyph_in_slot( AF_Loader loader, + FT_Face face, + AF_StyleMetrics style_metrics ) { - FT_Error error; - FT_Face face = loader->face; - AF_StyleMetrics metrics = loader->metrics; - AF_GlyphHints hints = loader->hints; - FT_GlyphSlot slot = face->glyph; - FT_Slot_Internal internal = slot->internal; - FT_GlyphLoader gloader = internal->loader; - FT_Int32 flags; + FT_Error error = FT_Err_Ok; + + FT_GlyphSlot slot = face->glyph; + AF_FaceGlobals globals = loader->globals; + AF_WritingSystemClass writing_system_class; + + FT_Size_Metrics* size_metrics = &face->size->internal->autohint_metrics; + + FT_Pos stdVW = 0; + FT_Pos stdHW = 0; + + FT_Bool size_changed = size_metrics->x_ppem != + globals->stem_darkening_for_ppem; + + FT_Fixed em_size = af_intToFixed( face->units_per_EM ); + FT_Fixed em_ratio = FT_DivFix( af_intToFixed( 1000 ), em_size ); + + FT_Matrix scale_down_matrix = { 0x10000L, 0, 0, 0x10000L }; - flags = load_flags | FT_LOAD_LINEAR_DESIGN; - error = FT_Load_Glyph( face, glyph_index, flags ); + /* Skip stem darkening for broken fonts. */ + if ( !face->units_per_EM ) + { + error = FT_ERR( Corrupted_Font_Header ); + goto Exit; + } + + /* + * We depend on the writing system (script analyzers) to supply + * standard widths for the script of the glyph we are looking at. If + * it can't deliver, stem darkening is disabled. + */ + writing_system_class = + AF_WRITING_SYSTEM_CLASSES_GET[style_metrics->style_class->writing_system]; + + if ( writing_system_class->style_metrics_getstdw ) + writing_system_class->style_metrics_getstdw( style_metrics, + &stdHW, + &stdVW ); + else + { + error = FT_ERR( Unimplemented_Feature ); + goto Exit; + } + + if ( size_changed || + ( stdVW > 0 && stdVW != globals->standard_vertical_width ) ) + { + FT_Fixed darken_by_font_units_x, darken_x; + + + darken_by_font_units_x = + af_intToFixed( af_loader_compute_darkening( loader, + face, + stdVW ) ); + darken_x = FT_DivFix( FT_MulFix( darken_by_font_units_x, + size_metrics->x_scale ), + em_ratio ); + + globals->standard_vertical_width = stdVW; + globals->stem_darkening_for_ppem = size_metrics->x_ppem; + globals->darken_x = af_fixedToInt( darken_x ); + } + + if ( size_changed || + ( stdHW > 0 && stdHW != globals->standard_horizontal_width ) ) + { + FT_Fixed darken_by_font_units_y, darken_y; + + + darken_by_font_units_y = + af_intToFixed( af_loader_compute_darkening( loader, + face, + stdHW ) ); + darken_y = FT_DivFix( FT_MulFix( darken_by_font_units_y, + size_metrics->y_scale ), + em_ratio ); + + globals->standard_horizontal_width = stdHW; + globals->stem_darkening_for_ppem = size_metrics->x_ppem; + globals->darken_y = af_fixedToInt( darken_y ); + + /* + * Scale outlines down on the Y-axis to keep them inside their blue + * zones. The stronger the emboldening, the stronger the downscaling + * (plus heuristical padding to prevent outlines still falling out + * their zones due to rounding). + * + * Reason: `FT_Outline_Embolden' works by shifting the rightmost + * points of stems farther to the right, and topmost points farther + * up. This positions points on the Y-axis outside their + * pre-computed blue zones and leads to distortion when applying the + * hints in the code further below. Code outside this emboldening + * block doesn't know we are presenting it with modified outlines the + * analyzer didn't see! + * + * An unfortunate side effect of downscaling is that the emboldening + * effect is slightly decreased. The loss becomes more pronounced + * versus the CFF driver at smaller sizes, e.g., at 9ppem and below. + */ + globals->scale_down_factor = + FT_DivFix( em_size - ( darken_by_font_units_y + af_intToFixed( 8 ) ), + em_size ); + } + + FT_Outline_EmboldenXY( &slot->outline, + globals->darken_x, + globals->darken_y ); + + scale_down_matrix.yy = globals->scale_down_factor; + FT_Outline_Transform( &slot->outline, &scale_down_matrix ); + + Exit: + return error; + } + + + /* Load the glyph at index into the current slot of a face and hint it. */ + + FT_LOCAL_DEF( FT_Error ) + af_loader_load_glyph( AF_Loader loader, + AF_Module module, + FT_Face face, + FT_UInt glyph_index, + FT_Int32 load_flags ) + { + FT_Error error; + + FT_Size size = face->size; + FT_Size_Internal size_internal = size->internal; + FT_GlyphSlot slot = face->glyph; + FT_Slot_Internal slot_internal = slot->internal; + FT_GlyphLoader gloader = slot_internal->loader; + + AF_GlyphHints hints = loader->hints; + AF_ScalerRec scaler; + AF_StyleMetrics style_metrics; + FT_UInt style_options = AF_STYLE_NONE_DFLT; + AF_StyleClass style_class; + AF_WritingSystemClass writing_system_class; + +#ifdef FT_CONFIG_OPTION_PIC + AF_FaceGlobals globals = loader->globals; +#endif + + + if ( !size ) + return FT_THROW( Invalid_Size_Handle ); + + FT_ZERO( &scaler ); + + if ( !size_internal->autohint_metrics.x_scale || + size_internal->autohint_mode != FT_LOAD_TARGET_MODE( load_flags ) ) + { + /* switching between hinting modes usually means different scaling */ + /* values; this later on enforces recomputation of everything */ + /* related to the current size */ + + size_internal->autohint_mode = FT_LOAD_TARGET_MODE( load_flags ); + size_internal->autohint_metrics = size->metrics; + +#ifdef AF_CONFIG_OPTION_TT_SIZE_METRICS + { + FT_Size_Metrics* size_metrics = &size_internal->autohint_metrics; + + + /* set metrics to integer values and adjust scaling accordingly; */ + /* this is the same setup as with TrueType fonts, cf. function */ + /* `tt_size_reset' in file `ttobjs.c' */ + size_metrics->ascender = FT_PIX_ROUND( + FT_MulFix( face->ascender, + size_metrics->y_scale ) ); + size_metrics->descender = FT_PIX_ROUND( + FT_MulFix( face->descender, + size_metrics->y_scale ) ); + size_metrics->height = FT_PIX_ROUND( + FT_MulFix( face->height, + size_metrics->y_scale ) ); + + size_metrics->x_scale = FT_DivFix( size_metrics->x_ppem << 6, + face->units_per_EM ); + size_metrics->y_scale = FT_DivFix( size_metrics->y_ppem << 6, + face->units_per_EM ); + size_metrics->max_advance = FT_PIX_ROUND( + FT_MulFix( face->max_advance_width, + size_metrics->x_scale ) ); + } +#endif /* AF_CONFIG_OPTION_TT_SIZE_METRICS */ + } + + /* + * TODO: This code currently doesn't support fractional advance widths, + * i.e., placing hinted glyphs at anything other than integer + * x-positions. This is only relevant for the warper code, which + * scales and shifts glyphs to optimize blackness of stems (hinting on + * the x-axis by nature places things on pixel integers, hinting on the + * y-axis only, i.e., LIGHT mode, doesn't touch the x-axis). The delta + * values of the scaler would need to be adjusted. + */ + scaler.face = face; + scaler.x_scale = size_internal->autohint_metrics.x_scale; + scaler.x_delta = 0; + scaler.y_scale = size_internal->autohint_metrics.y_scale; + scaler.y_delta = 0; + + scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags ); + scaler.flags = 0; + + /* note that the fallback style can't be changed anymore */ + /* after the first call of `af_loader_load_glyph' */ + error = af_loader_reset( loader, module, face ); if ( error ) goto Exit; - loader->transformed = internal->glyph_transformed; +#ifdef FT_OPTION_AUTOFIT2 + /* XXX: undocumented hook to activate the latin2 writing system. */ + if ( load_flags & ( 1UL << 20 ) ) + style_options = AF_STYLE_LTN2_DFLT; +#endif + + /* + * Glyphs (really code points) are assigned to scripts. Script + * analysis is done lazily: For each glyph that passes through here, + * the corresponding script analyzer is called, but returns immediately + * if it has been run already. + */ + error = af_face_globals_get_metrics( loader->globals, glyph_index, + style_options, &style_metrics ); + if ( error ) + goto Exit; + + style_class = style_metrics->style_class; + writing_system_class = + AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system]; + + loader->metrics = style_metrics; + + if ( writing_system_class->style_metrics_scale ) + writing_system_class->style_metrics_scale( style_metrics, &scaler ); + else + style_metrics->scaler = scaler; + + if ( writing_system_class->style_hints_init ) + { + error = writing_system_class->style_hints_init( hints, + style_metrics ); + if ( error ) + goto Exit; + } + + /* + * Do the main work of `af_loader_load_glyph'. Note that we never have + * to deal with composite glyphs as those get loaded into + * FT_GLYPH_FORMAT_OUTLINE by the recursed `FT_Load_Glyph' function. + * In the rare cases where FT_LOAD_NO_RECURSE is set, it implies + * FT_LOAD_NO_SCALE and as such the auto-hinter is never called. + */ + load_flags |= FT_LOAD_NO_SCALE | + FT_LOAD_IGNORE_TRANSFORM | + FT_LOAD_LINEAR_DESIGN; + load_flags &= ~FT_LOAD_RENDER; + + error = FT_Load_Glyph( face, glyph_index, load_flags ); + if ( error ) + goto Exit; + + /* + * Apply stem darkening (emboldening) here before hints are applied to + * the outline. Glyphs are scaled down proportionally to the + * emboldening so that curve points don't fall outside their + * precomputed blue zones. + * + * Any emboldening done by the font driver (e.g., the CFF driver) + * doesn't reach here because the autohinter loads the unprocessed + * glyphs in font units for analysis (functions `af_*_metrics_init_*') + * and then above to prepare it for the rasterizers by itself, + * independently of the font driver. So emboldening must be done here, + * within the autohinter. + * + * All glyphs to be autohinted pass through here one by one. The + * standard widths can therefore change from one glyph to the next, + * depending on what script a glyph is assigned to (each script has its + * own set of standard widths and other metrics). The darkening amount + * must therefore be recomputed for each size and + * `standard_{vertical,horizontal}_width' change. + * + * Ignore errors and carry on without emboldening. + * + */ + + /* stem darkening only works well in `light' mode */ + if ( scaler.render_mode == FT_RENDER_MODE_LIGHT && + ( !face->internal->no_stem_darkening || + ( face->internal->no_stem_darkening < 0 && + !module->no_stem_darkening ) ) ) + af_loader_embolden_glyph_in_slot( loader, face, style_metrics ); + + loader->transformed = slot_internal->glyph_transformed; if ( loader->transformed ) { FT_Matrix inverse; - loader->trans_matrix = internal->glyph_matrix; - loader->trans_delta = internal->glyph_delta; + loader->trans_matrix = slot_internal->glyph_matrix; + loader->trans_delta = slot_internal->glyph_delta; inverse = loader->trans_matrix; if ( !FT_Matrix_Invert( &inverse ) ) @@ -126,8 +411,8 @@ loader->trans_delta.x, loader->trans_delta.y ); - /* compute original horizontal phantom points (and ignore */ - /* vertical ones) */ + /* compute original horizontal phantom points */ + /* (and ignore vertical ones) */ loader->pp1.x = hints->x_delta; loader->pp1.y = hints->y_delta; loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance, @@ -138,30 +423,21 @@ if ( slot->outline.n_points == 0 ) goto Hint_Metrics; - /* now load the slot image into the auto-outline and run the */ - /* automatic hinting process */ - { -#ifdef FT_CONFIG_OPTION_PIC - AF_FaceGlobals globals = loader->globals; -#endif - AF_StyleClass style_class = metrics->style_class; - AF_WritingSystemClass writing_system_class = - AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system]; - - - if ( writing_system_class->style_hints_apply ) - writing_system_class->style_hints_apply( glyph_index, - hints, - &gloader->base.outline, - metrics ); - } + /* now load the slot image into the auto-outline */ + /* and run the automatic hinting process */ + if ( writing_system_class->style_hints_apply ) + writing_system_class->style_hints_apply( glyph_index, + hints, + &gloader->base.outline, + style_metrics ); /* we now need to adjust the metrics according to the change in */ /* width/positioning that occurred during the hinting process */ - if ( scaler->render_mode != FT_RENDER_MODE_LIGHT ) + if ( scaler.render_mode != FT_RENDER_MODE_LIGHT ) { - FT_Pos old_rsb, old_lsb, new_lsb; - FT_Pos pp1x_uh, pp2x_uh; + FT_Pos old_rsb, old_lsb, new_lsb; + FT_Pos pp1x_uh, pp2x_uh; + AF_AxisHints axis = &hints->axis[AF_DIMENSION_HORZ]; AF_Edge edge1 = axis->edges; /* leftmost edge */ AF_Edge edge2 = edge1 + @@ -171,12 +447,12 @@ if ( axis->num_edges > 1 && AF_HINTS_DO_ADVANCE( hints ) ) { old_rsb = loader->pp2.x - edge2->opos; - old_lsb = edge1->opos; + /* loader->pp1.x is always zero at this point of time */ + old_lsb = edge1->opos /* - loader->pp1.x */; new_lsb = edge1->pos; /* remember unhinted values to later account */ /* for rounding errors */ - pp1x_uh = new_lsb - old_lsb; pp2x_uh = edge2->pos + old_rsb; @@ -207,21 +483,23 @@ FT_Pos pp2x = loader->pp2.x; - loader->pp1.x = FT_PIX_ROUND( pp1x ); - loader->pp2.x = FT_PIX_ROUND( pp2x ); + loader->pp1.x = FT_PIX_ROUND( pp1x + hints->xmin_delta ); + loader->pp2.x = FT_PIX_ROUND( pp2x + hints->xmax_delta ); slot->lsb_delta = loader->pp1.x - pp1x; slot->rsb_delta = loader->pp2.x - pp2x; } } + /* `light' mode uses integer advance widths */ + /* but sets `lsb_delta' and `rsb_delta' */ else { FT_Pos pp1x = loader->pp1.x; FT_Pos pp2x = loader->pp2.x; - loader->pp1.x = FT_PIX_ROUND( pp1x + hints->xmin_delta ); - loader->pp2.x = FT_PIX_ROUND( pp2x + hints->xmax_delta ); + loader->pp1.x = FT_PIX_ROUND( pp1x ); + loader->pp2.x = FT_PIX_ROUND( pp2x ); slot->lsb_delta = loader->pp1.x - pp1x; slot->rsb_delta = loader->pp2.x - pp2x; @@ -242,8 +520,8 @@ vvector.x = slot->metrics.vertBearingX - slot->metrics.horiBearingX; vvector.y = slot->metrics.vertBearingY - slot->metrics.horiBearingY; - vvector.x = FT_MulFix( vvector.x, metrics->scaler.x_scale ); - vvector.y = FT_MulFix( vvector.y, metrics->scaler.y_scale ); + vvector.x = FT_MulFix( vvector.x, style_metrics->scaler.x_scale ); + vvector.y = FT_MulFix( vvector.y, style_metrics->scaler.y_scale ); /* transform the hinted outline if needed */ if ( loader->transformed ) @@ -251,12 +529,12 @@ FT_Outline_Transform( &gloader->base.outline, &loader->trans_matrix ); FT_Vector_Transform( &vvector, &loader->trans_matrix ); } -#if 1 + /* we must translate our final outline by -pp1.x and compute */ /* the new metrics */ if ( loader->pp1.x ) FT_Outline_Translate( &gloader->base.outline, -loader->pp1.x, 0 ); -#endif + FT_Outline_Get_CBox( &gloader->base.outline, &bbox ); bbox.xMin = FT_PIX_FLOOR( bbox.xMin ); @@ -275,20 +553,14 @@ /* for mono-width fonts (like Andale, Courier, etc.) we need */ /* to keep the original rounded advance width; ditto for */ /* digits if all have the same advance width */ -#if 0 - if ( !FT_IS_FIXED_WIDTH( slot->face ) ) - slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; - else - slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, - x_scale ); -#else - if ( scaler->render_mode != FT_RENDER_MODE_LIGHT && + if ( scaler.render_mode != FT_RENDER_MODE_LIGHT && ( FT_IS_FIXED_WIDTH( slot->face ) || ( af_face_globals_is_digit( loader->globals, glyph_index ) && - metrics->digits_have_same_width ) ) ) + style_metrics->digits_have_same_width ) ) ) { - slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance, - metrics->scaler.x_scale ); + slot->metrics.horiAdvance = + FT_MulFix( slot->metrics.horiAdvance, + style_metrics->scaler.x_scale ); /* Set delta values to 0. Otherwise code that uses them is */ /* going to ruin the fixed advance width. */ @@ -301,23 +573,13 @@ if ( slot->metrics.horiAdvance ) slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; } -#endif slot->metrics.vertAdvance = FT_MulFix( slot->metrics.vertAdvance, - metrics->scaler.y_scale ); + style_metrics->scaler.y_scale ); slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance ); slot->metrics.vertAdvance = FT_PIX_ROUND( slot->metrics.vertAdvance ); -#if 0 - /* reassign all outline fields except flags to protect them */ - slot->outline.n_contours = internal->loader->base.outline.n_contours; - slot->outline.n_points = internal->loader->base.outline.n_points; - slot->outline.points = internal->loader->base.outline.points; - slot->outline.tags = internal->loader->base.outline.tags; - slot->outline.contours = internal->loader->base.outline.contours; -#endif - slot->format = FT_GLYPH_FORMAT_OUTLINE; } @@ -326,82 +588,133 @@ } - /* Load a glyph. */ - - FT_LOCAL_DEF( FT_Error ) - af_loader_load_glyph( AF_Loader loader, - AF_Module module, - FT_Face face, - FT_UInt gindex, - FT_Int32 load_flags ) + /* + * Compute amount of font units the face should be emboldened by, in + * analogy to the CFF driver's `cf2_computeDarkening' function. See there + * for details of the algorithm. + * + * XXX: Currently a crude adaption of the original algorithm. Do better? + */ + FT_LOCAL_DEF( FT_Int32 ) + af_loader_compute_darkening( AF_Loader loader, + FT_Face face, + FT_Pos standard_width ) { - FT_Error error; - FT_Size size = face->size; - AF_ScalerRec scaler; + AF_Module module = loader->globals->module; + + FT_UShort units_per_EM; + FT_Fixed ppem, em_ratio; + FT_Fixed stem_width, stem_width_per_1000, scaled_stem, darken_amount; + FT_Int log_base_2; + FT_Int x1, y1, x2, y2, x3, y3, x4, y4; - if ( !size ) - return FT_THROW( Invalid_Size_Handle ); + ppem = FT_MAX( af_intToFixed( 4 ), + af_intToFixed( face->size->metrics.x_ppem ) ); + units_per_EM = face->units_per_EM; - FT_ZERO( &scaler ); - - scaler.face = face; - scaler.x_scale = size->metrics.x_scale; - scaler.x_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */ - scaler.y_scale = size->metrics.y_scale; - scaler.y_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */ - - scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags ); - scaler.flags = 0; /* XXX: fix this */ - - error = af_loader_reset( loader, module, face ); - if ( !error ) + em_ratio = FT_DivFix( af_intToFixed( 1000 ), + af_intToFixed ( units_per_EM ) ); + if ( em_ratio < af_floatToFixed( .01 ) ) { - AF_StyleMetrics metrics; - FT_UInt options = AF_STYLE_NONE_DFLT; + /* If something goes wrong, don't embolden. */ + return 0; + } + + x1 = module->darken_params[0]; + y1 = module->darken_params[1]; + x2 = module->darken_params[2]; + y2 = module->darken_params[3]; + x3 = module->darken_params[4]; + y3 = module->darken_params[5]; + x4 = module->darken_params[6]; + y4 = module->darken_params[7]; + + if ( standard_width <= 0 ) + { + stem_width = af_intToFixed( 75 ); /* taken from cf2font.c */ + stem_width_per_1000 = stem_width; + } + else + { + stem_width = af_intToFixed( standard_width ); + stem_width_per_1000 = FT_MulFix( stem_width, em_ratio ); + } + + log_base_2 = FT_MSB( (FT_UInt32)stem_width_per_1000 ) + + FT_MSB( (FT_UInt32)ppem ); + + if ( log_base_2 >= 46 ) + { + /* possible overflow */ + scaled_stem = af_intToFixed( x4 ); + } + else + scaled_stem = FT_MulFix( stem_width_per_1000, ppem ); + + /* now apply the darkening parameters */ + if ( scaled_stem < af_intToFixed( x1 ) ) + darken_amount = FT_DivFix( af_intToFixed( y1 ), ppem ); + + else if ( scaled_stem < af_intToFixed( x2 ) ) + { + FT_Int xdelta = x2 - x1; + FT_Int ydelta = y2 - y1; + FT_Int x = stem_width_per_1000 - + FT_DivFix( af_intToFixed( x1 ), ppem ); -#ifdef FT_OPTION_AUTOFIT2 - /* XXX: undocumented hook to activate the latin2 writing system */ - if ( load_flags & ( 1UL << 20 ) ) - options = AF_STYLE_LTN2_DFLT; -#endif + if ( !xdelta ) + goto Try_x3; - error = af_face_globals_get_metrics( loader->globals, gindex, - options, &metrics ); - if ( !error ) + darken_amount = FT_MulDiv( x, ydelta, xdelta ) + + FT_DivFix( af_intToFixed( y1 ), ppem ); + } + + else if ( scaled_stem < af_intToFixed( x3 ) ) + { + Try_x3: { -#ifdef FT_CONFIG_OPTION_PIC - AF_FaceGlobals globals = loader->globals; -#endif - AF_StyleClass style_class = metrics->style_class; - AF_WritingSystemClass writing_system_class = - AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system]; + FT_Int xdelta = x3 - x2; + FT_Int ydelta = y3 - y2; + FT_Int x = stem_width_per_1000 - + FT_DivFix( af_intToFixed( x2 ), ppem ); - loader->metrics = metrics; + if ( !xdelta ) + goto Try_x4; - if ( writing_system_class->style_metrics_scale ) - writing_system_class->style_metrics_scale( metrics, &scaler ); - else - metrics->scaler = scaler; - - load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM; - load_flags &= ~FT_LOAD_RENDER; - - if ( writing_system_class->style_hints_init ) - { - error = writing_system_class->style_hints_init( loader->hints, - metrics ); - if ( error ) - goto Exit; - } - - error = af_loader_load_g( loader, &scaler, gindex, load_flags ); + darken_amount = FT_MulDiv( x, ydelta, xdelta ) + + FT_DivFix( af_intToFixed( y2 ), ppem ); } } - Exit: - return error; + + else if ( scaled_stem < af_intToFixed( x4 ) ) + { + Try_x4: + { + FT_Int xdelta = x4 - x3; + FT_Int ydelta = y4 - y3; + FT_Int x = stem_width_per_1000 - + FT_DivFix( af_intToFixed( x3 ), ppem ); + + + if ( !xdelta ) + goto Use_y4; + + darken_amount = FT_MulDiv( x, ydelta, xdelta ) + + FT_DivFix( af_intToFixed( y3 ), ppem ); + } + } + + else + { + Use_y4: + darken_amount = FT_DivFix( af_intToFixed( y4 ), ppem ); + } + + /* Convert darken_amount from per 1000 em to true character space. */ + return af_fixedToInt( FT_DivFix( darken_amount, em_ratio ) ); } diff --git a/src/3rdparty/freetype/src/autofit/afloader.h b/src/3rdparty/freetype/src/autofit/afloader.h index 37cfd14239..d4d72d1583 100644 --- a/src/3rdparty/freetype/src/autofit/afloader.h +++ b/src/3rdparty/freetype/src/autofit/afloader.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter glyph loading routines (specification). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __AFLOADER_H__ -#define __AFLOADER_H__ +#ifndef AFLOADER_H_ +#define AFLOADER_H_ #include "afhints.h" #include "afmodule.h" @@ -75,12 +75,17 @@ FT_BEGIN_HEADER FT_UInt gindex, FT_Int32 load_flags ); + FT_LOCAL_DEF( FT_Int32 ) + af_loader_compute_darkening( AF_Loader loader, + FT_Face face, + FT_Pos standard_width ); + /* */ FT_END_HEADER -#endif /* __AFLOADER_H__ */ +#endif /* AFLOADER_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/autofit/afmodule.c b/src/3rdparty/freetype/src/autofit/afmodule.c index bbf1372518..dcaa17a27e 100644 --- a/src/3rdparty/freetype/src/autofit/afmodule.c +++ b/src/3rdparty/freetype/src/autofit/afmodule.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter module implementation (body). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -56,7 +56,7 @@ #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H -#include FT_AUTOHINTER_H +#include FT_DRIVER_H #include FT_SERVICE_PROPERTIES_H @@ -104,21 +104,45 @@ } +#ifdef FT_CONFIG_OPTION_PIC + +#undef AF_SCRIPT_CLASSES_GET +#define AF_SCRIPT_CLASSES_GET \ + ( GET_PIC( ft_module->library )->af_script_classes ) + +#undef AF_STYLE_CLASSES_GET +#define AF_STYLE_CLASSES_GET \ + ( GET_PIC( ft_module->library )->af_style_classes ) + +#endif + + static FT_Error af_property_set( FT_Module ft_module, const char* property_name, - const void* value ) + const void* value, + FT_Bool value_is_string ) { FT_Error error = FT_Err_Ok; AF_Module module = (AF_Module)ft_module; +#ifndef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + FT_UNUSED( value_is_string ); +#endif + if ( !ft_strcmp( property_name, "fallback-script" ) ) { - FT_UInt* fallback_script = (FT_UInt*)value; + FT_UInt* fallback_script; + FT_UInt ss; - FT_UInt ss; +#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + if ( value_is_string ) + return FT_THROW( Invalid_Argument ); +#endif + + fallback_script = (FT_UInt*)value; /* We translate the fallback script to a fallback style that uses */ /* `fallback-script' as its script and `AF_COVERAGE_NONE' as its */ @@ -147,19 +171,33 @@ } else if ( !ft_strcmp( property_name, "default-script" ) ) { - FT_UInt* default_script = (FT_UInt*)value; + FT_UInt* default_script; +#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + if ( value_is_string ) + return FT_THROW( Invalid_Argument ); +#endif + + default_script = (FT_UInt*)value; + module->default_script = *default_script; return error; } else if ( !ft_strcmp( property_name, "increase-x-height" ) ) { - FT_Prop_IncreaseXHeight* prop = (FT_Prop_IncreaseXHeight*)value; + FT_Prop_IncreaseXHeight* prop; AF_FaceGlobals globals; +#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + if ( value_is_string ) + return FT_THROW( Invalid_Argument ); +#endif + + prop = (FT_Prop_IncreaseXHeight*)value; + error = af_property_get_face_globals( prop->face, &globals, module ); if ( !error ) globals->increase_x_height = prop->limit; @@ -169,14 +207,119 @@ #ifdef AF_CONFIG_OPTION_USE_WARPER else if ( !ft_strcmp( property_name, "warping" ) ) { - FT_Bool* warping = (FT_Bool*)value; +#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + if ( value_is_string ) + { + const char* s = (const char*)value; + long w = ft_strtol( s, NULL, 10 ); - module->warping = *warping; + if ( w == 0 ) + module->warping = 0; + else if ( w == 1 ) + module->warping = 1; + else + return FT_THROW( Invalid_Argument ); + } + else +#endif + { + FT_Bool* warping = (FT_Bool*)value; + + + module->warping = *warping; + } return error; } #endif /* AF_CONFIG_OPTION_USE_WARPER */ + else if ( !ft_strcmp( property_name, "darkening-parameters" ) ) + { + FT_Int* darken_params; + FT_Int x1, y1, x2, y2, x3, y3, x4, y4; + +#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + FT_Int dp[8]; + + + if ( value_is_string ) + { + const char* s = (const char*)value; + char* ep; + int i; + + + /* eight comma-separated numbers */ + for ( i = 0; i < 7; i++ ) + { + dp[i] = (FT_Int)ft_strtol( s, &ep, 10 ); + if ( *ep != ',' || s == ep ) + return FT_THROW( Invalid_Argument ); + + s = ep + 1; + } + + dp[7] = (FT_Int)ft_strtol( s, &ep, 10 ); + if ( !( *ep == '\0' || *ep == ' ' ) || s == ep ) + return FT_THROW( Invalid_Argument ); + + darken_params = dp; + } + else +#endif + darken_params = (FT_Int*)value; + + x1 = darken_params[0]; + y1 = darken_params[1]; + x2 = darken_params[2]; + y2 = darken_params[3]; + x3 = darken_params[4]; + y3 = darken_params[5]; + x4 = darken_params[6]; + y4 = darken_params[7]; + + if ( x1 < 0 || x2 < 0 || x3 < 0 || x4 < 0 || + y1 < 0 || y2 < 0 || y3 < 0 || y4 < 0 || + x1 > x2 || x2 > x3 || x3 > x4 || + y1 > 500 || y2 > 500 || y3 > 500 || y4 > 500 ) + return FT_THROW( Invalid_Argument ); + + module->darken_params[0] = x1; + module->darken_params[1] = y1; + module->darken_params[2] = x2; + module->darken_params[3] = y2; + module->darken_params[4] = x3; + module->darken_params[5] = y3; + module->darken_params[6] = x4; + module->darken_params[7] = y4; + + return error; + } + else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) + { +#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + if ( value_is_string ) + { + const char* s = (const char*)value; + long nsd = ft_strtol( s, NULL, 10 ); + + + if ( !nsd ) + module->no_stem_darkening = FALSE; + else + module->no_stem_darkening = TRUE; + } + else +#endif + { + FT_Bool* no_stem_darkening = (FT_Bool*)value; + + + module->no_stem_darkening = *no_stem_darkening; + } + + return error; + } FT_TRACE0(( "af_property_set: missing property `%s'\n", property_name )); @@ -253,6 +396,33 @@ return error; } #endif /* AF_CONFIG_OPTION_USE_WARPER */ + else if ( !ft_strcmp( property_name, "darkening-parameters" ) ) + { + FT_Int* darken_params = module->darken_params; + FT_Int* val = (FT_Int*)value; + + + val[0] = darken_params[0]; + val[1] = darken_params[1]; + val[2] = darken_params[2]; + val[3] = darken_params[3]; + val[4] = darken_params[4]; + val[5] = darken_params[5]; + val[6] = darken_params[6]; + val[7] = darken_params[7]; + + return error; + } + else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) + { + FT_Bool no_stem_darkening = module->no_stem_darkening; + FT_Bool* val = (FT_Bool*)value; + + + *val = no_stem_darkening; + + return error; + } FT_TRACE0(( "af_property_get: missing property `%s'\n", property_name )); @@ -262,12 +432,14 @@ FT_DEFINE_SERVICE_PROPERTIESREC( af_service_properties, - (FT_Properties_SetFunc)af_property_set, - (FT_Properties_GetFunc)af_property_get ) + + (FT_Properties_SetFunc)af_property_set, /* set_property */ + (FT_Properties_GetFunc)af_property_get ) /* get_property */ FT_DEFINE_SERVICEDESCREC1( af_services, + FT_SERVICE_ID_PROPERTIES, &AF_SERVICE_PROPERTIES_GET ) @@ -299,11 +471,21 @@ AF_Module module = (AF_Module)ft_module; - module->fallback_style = AF_STYLE_FALLBACK; - module->default_script = AF_SCRIPT_DEFAULT; + module->fallback_style = AF_STYLE_FALLBACK; + module->default_script = AF_SCRIPT_DEFAULT; #ifdef AF_CONFIG_OPTION_USE_WARPER - module->warping = 0; + module->warping = 0; #endif + module->no_stem_darkening = TRUE; + + module->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1; + module->darken_params[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1; + module->darken_params[2] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2; + module->darken_params[3] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2; + module->darken_params[4] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3; + module->darken_params[5] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3; + module->darken_params[6] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4; + module->darken_params[7] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4; return FT_Err_Ok; } @@ -350,9 +532,16 @@ error = af_loader_load_glyph( loader, module, slot->face, glyph_index, load_flags ); - af_glyph_hints_dump_points( hints, 0 ); - af_glyph_hints_dump_segments( hints, 0 ); - af_glyph_hints_dump_edges( hints, 0 ); +#ifdef FT_DEBUG_LEVEL_TRACE + if ( ft_trace_levels[FT_COMPONENT] ) + { +#endif + af_glyph_hints_dump_points( hints, 0 ); + af_glyph_hints_dump_segments( hints, 0 ); + af_glyph_hints_dump_edges( hints, 0 ); +#ifdef FT_DEBUG_LEVEL_TRACE + } +#endif af_loader_done( loader ); @@ -383,6 +572,7 @@ FT_DEFINE_AUTOHINTER_INTERFACE( af_autofitter_interface, + NULL, /* reset_face */ NULL, /* get_global_hints */ NULL, /* done_global_hints */ @@ -401,9 +591,10 @@ (const void*)&AF_INTERFACE_GET, - (FT_Module_Constructor)af_autofitter_init, - (FT_Module_Destructor) af_autofitter_done, - (FT_Module_Requester) af_get_interface ) + (FT_Module_Constructor)af_autofitter_init, /* module_init */ + (FT_Module_Destructor) af_autofitter_done, /* module_done */ + (FT_Module_Requester) af_get_interface /* get_interface */ + ) /* END */ diff --git a/src/3rdparty/freetype/src/autofit/afmodule.h b/src/3rdparty/freetype/src/autofit/afmodule.h index b9c2fd8a2d..56f64eaf23 100644 --- a/src/3rdparty/freetype/src/autofit/afmodule.h +++ b/src/3rdparty/freetype/src/autofit/afmodule.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter module implementation (specification). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __AFMODULE_H__ -#define __AFMODULE_H__ +#ifndef AFMODULE_H_ +#define AFMODULE_H_ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H @@ -41,6 +41,8 @@ FT_BEGIN_HEADER #ifdef AF_CONFIG_OPTION_USE_WARPER FT_Bool warping; #endif + FT_Bool no_stem_darkening; + FT_Int darken_params[8]; } AF_ModuleRec, *AF_Module; @@ -50,7 +52,7 @@ FT_DECLARE_MODULE( autofit_module_class ) FT_END_HEADER -#endif /* __AFMODULE_H__ */ +#endif /* AFMODULE_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/autofit/afpic.c b/src/3rdparty/freetype/src/autofit/afpic.c index 5589e612cf..d48d016a0e 100644 --- a/src/3rdparty/freetype/src/autofit/afpic.c +++ b/src/3rdparty/freetype/src/autofit/afpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for autofit module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2018 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -122,7 +122,7 @@ #include "afwrtsys.h" #undef SCRIPT -#define SCRIPT( s, S, d, h, sc1, sc2, sc3 ) \ +#define SCRIPT( s, S, d, h, H, sss ) \ FT_Init_Class_af_ ## s ## _script_class( \ &container->af_script_classes_rec[ss++] ); diff --git a/src/3rdparty/freetype/src/autofit/afpic.h b/src/3rdparty/freetype/src/autofit/afpic.h index 9b45069f5d..0c73456785 100644 --- a/src/3rdparty/freetype/src/autofit/afpic.h +++ b/src/3rdparty/freetype/src/autofit/afpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for autofit module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2018 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __AFPIC_H__ -#define __AFPIC_H__ +#ifndef AFPIC_H_ +#define AFPIC_H_ #include FT_INTERNAL_PIC_H @@ -69,7 +69,7 @@ FT_BEGIN_HEADER #define GET_PIC( lib ) \ - ( (AFModulePIC*)((lib)->pic_container.autofit) ) + ( (AFModulePIC*)( (lib)->pic_container.autofit ) ) #define AF_SERVICES_GET \ ( GET_PIC( library )->af_services ) @@ -99,7 +99,7 @@ FT_END_HEADER /* */ -#endif /* __AFPIC_H__ */ +#endif /* AFPIC_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/autofit/afranges.c b/src/3rdparty/freetype/src/autofit/afranges.c index 13c221364c..cf67fafb11 100644 --- a/src/3rdparty/freetype/src/autofit/afranges.c +++ b/src/3rdparty/freetype/src/autofit/afranges.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter Unicode script ranges (body). */ /* */ -/* Copyright 2013-2015 by */ +/* Copyright 2013-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -52,61 +52,230 @@ /* not be affected by blue zones, regardless of whether this is a */ /* spacing or no-spacing glyph */ - /* the `ta_xxxx_nonbase_uniranges' ranges must be strict subsets */ - /* of the corresponding `ta_xxxx_uniranges' ranges */ + /* the `af_xxxx_nonbase_uniranges' ranges must be strict subsets */ + /* of the corresponding `af_xxxx_uniranges' ranges */ + + + const AF_Script_UniRangeRec af_adlm_uniranges[] = + { + AF_UNIRANGE_REC( 0x1E900, 0x1E95F ), /* Adlam */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_adlm_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x1D944, 0x1E94A ), + AF_UNIRANGE_REC( 0, 0 ) + }; const AF_Script_UniRangeRec af_arab_uniranges[] = { - AF_UNIRANGE_REC( 0x0600UL, 0x06FFUL ), /* Arabic */ - AF_UNIRANGE_REC( 0x0750UL, 0x07FFUL ), /* Arabic Supplement */ - AF_UNIRANGE_REC( 0x08A0UL, 0x08FFUL ), /* Arabic Extended-A */ - AF_UNIRANGE_REC( 0xFB50UL, 0xFDFFUL ), /* Arabic Presentation Forms-A */ - AF_UNIRANGE_REC( 0xFE70UL, 0xFEFFUL ), /* Arabic Presentation Forms-B */ - AF_UNIRANGE_REC( 0x1EE00UL, 0x1EEFFUL ), /* Arabic Mathematical Alphabetic Symbols */ - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x0600, 0x06FF ), /* Arabic */ + AF_UNIRANGE_REC( 0x0750, 0x07FF ), /* Arabic Supplement */ + AF_UNIRANGE_REC( 0x08A0, 0x08FF ), /* Arabic Extended-A */ + AF_UNIRANGE_REC( 0xFB50, 0xFDFF ), /* Arabic Presentation Forms-A */ + AF_UNIRANGE_REC( 0xFE70, 0xFEFF ), /* Arabic Presentation Forms-B */ + AF_UNIRANGE_REC( 0x1EE00, 0x1EEFF ), /* Arabic Mathematical Alphabetic Symbols */ + AF_UNIRANGE_REC( 0, 0 ) }; const AF_Script_UniRangeRec af_arab_nonbase_uniranges[] = { - AF_UNIRANGE_REC( 0x0600UL, 0x0605UL ), - AF_UNIRANGE_REC( 0x0610UL, 0x061AUL ), - AF_UNIRANGE_REC( 0x064BUL, 0x065FUL ), - AF_UNIRANGE_REC( 0x0670UL, 0x0670UL ), - AF_UNIRANGE_REC( 0x06D6UL, 0x06DCUL ), - AF_UNIRANGE_REC( 0x06DFUL, 0x06E4UL ), - AF_UNIRANGE_REC( 0x06E7UL, 0x06E8UL ), - AF_UNIRANGE_REC( 0x06EAUL, 0x06EDUL ), - AF_UNIRANGE_REC( 0x08E3UL, 0x08FFUL ), - AF_UNIRANGE_REC( 0xFBB2UL, 0xFBC1UL ), - AF_UNIRANGE_REC( 0xFE70UL, 0xFE70UL ), - AF_UNIRANGE_REC( 0xFE72UL, 0xFE72UL ), - AF_UNIRANGE_REC( 0xFE74UL, 0xFE74UL ), - AF_UNIRANGE_REC( 0xFE76UL, 0xFE76UL ), - AF_UNIRANGE_REC( 0xFE78UL, 0xFE78UL ), - AF_UNIRANGE_REC( 0xFE7AUL, 0xFE7AUL ), - AF_UNIRANGE_REC( 0xFE7CUL, 0xFE7CUL ), - AF_UNIRANGE_REC( 0xFE7EUL, 0xFE7EUL ), - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x0600, 0x0605 ), + AF_UNIRANGE_REC( 0x0610, 0x061A ), + AF_UNIRANGE_REC( 0x064B, 0x065F ), + AF_UNIRANGE_REC( 0x0670, 0x0670 ), + AF_UNIRANGE_REC( 0x06D6, 0x06DC ), + AF_UNIRANGE_REC( 0x06DF, 0x06E4 ), + AF_UNIRANGE_REC( 0x06E7, 0x06E8 ), + AF_UNIRANGE_REC( 0x06EA, 0x06ED ), + AF_UNIRANGE_REC( 0x08D4, 0x08E1 ), + AF_UNIRANGE_REC( 0x08D3, 0x08FF ), + AF_UNIRANGE_REC( 0xFBB2, 0xFBC1 ), + AF_UNIRANGE_REC( 0xFE70, 0xFE70 ), + AF_UNIRANGE_REC( 0xFE72, 0xFE72 ), + AF_UNIRANGE_REC( 0xFE74, 0xFE74 ), + AF_UNIRANGE_REC( 0xFE76, 0xFE76 ), + AF_UNIRANGE_REC( 0xFE78, 0xFE78 ), + AF_UNIRANGE_REC( 0xFE7A, 0xFE7A ), + AF_UNIRANGE_REC( 0xFE7C, 0xFE7C ), + AF_UNIRANGE_REC( 0xFE7E, 0xFE7E ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_armn_uniranges[] = + { + AF_UNIRANGE_REC( 0x0530, 0x058F ), /* Armenian */ + AF_UNIRANGE_REC( 0xFB13, 0xFB17 ), /* Alphab. Present. Forms (Armenian) */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_armn_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0559, 0x055F ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_avst_uniranges[] = + { + AF_UNIRANGE_REC( 0x10B00, 0x10B3F ), /* Avestan */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_avst_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x10B39, 0x10B3F ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_bamu_uniranges[] = + { + AF_UNIRANGE_REC( 0xA6A0, 0xA6FF ), /* Bamum */ +#if 0 + /* The characters in the Bamum supplement are pictograms, */ + /* not (directly) related to the syllabic Bamum script */ + AF_UNIRANGE_REC( 0x16800, 0x16A3F ), /* Bamum Supplement */ +#endif + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_bamu_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0xA6F0, 0xA6F1 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_beng_uniranges[] = + { + AF_UNIRANGE_REC( 0x0980, 0x09FF ), /* Bengali */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_beng_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0981, 0x0981 ), + AF_UNIRANGE_REC( 0x09BC, 0x09BC ), + AF_UNIRANGE_REC( 0x09C1, 0x09C4 ), + AF_UNIRANGE_REC( 0x09CD, 0x09CD ), + AF_UNIRANGE_REC( 0x09E2, 0x09E3 ), + AF_UNIRANGE_REC( 0x09FE, 0x09FE ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_buhd_uniranges[] = + { + AF_UNIRANGE_REC( 0x1740, 0x175F ), /* Buhid */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_buhd_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x1752, 0x1753 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_cakm_uniranges[] = + { + AF_UNIRANGE_REC( 0x11100, 0x1114F ), /* Chakma */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_cakm_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x11100, 0x11102 ), + AF_UNIRANGE_REC( 0x11127, 0x11134 ), + AF_UNIRANGE_REC( 0x11146, 0x11146 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_cans_uniranges[] = + { + AF_UNIRANGE_REC( 0x1400, 0x167F ), /* Unified Canadian Aboriginal Syllabics */ + AF_UNIRANGE_REC( 0x18B0, 0x18FF ), /* Unified Canadian Aboriginal Syllabics Extended */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_cans_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_cari_uniranges[] = + { + AF_UNIRANGE_REC( 0x102A0, 0x102DF ), /* Carian */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_cari_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_cher_uniranges[] = + { + AF_UNIRANGE_REC( 0x13A0, 0x13FF ), /* Cherokee */ + AF_UNIRANGE_REC( 0xAB70, 0xABBF ), /* Cherokee Supplement */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_cher_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_copt_uniranges[] = + { + AF_UNIRANGE_REC( 0x2C80, 0x2CFF ), /* Coptic */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_copt_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x2CEF, 0x2CF1 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_cprt_uniranges[] = + { + AF_UNIRANGE_REC( 0x10800, 0x1083F ), /* Cypriot */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_cprt_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) }; const AF_Script_UniRangeRec af_cyrl_uniranges[] = { - AF_UNIRANGE_REC( 0x0400UL, 0x04FFUL ), /* Cyrillic */ - AF_UNIRANGE_REC( 0x0500UL, 0x052FUL ), /* Cyrillic Supplement */ - AF_UNIRANGE_REC( 0x2DE0UL, 0x2DFFUL ), /* Cyrillic Extended-A */ - AF_UNIRANGE_REC( 0xA640UL, 0xA69FUL ), /* Cyrillic Extended-B */ - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x0400, 0x04FF ), /* Cyrillic */ + AF_UNIRANGE_REC( 0x0500, 0x052F ), /* Cyrillic Supplement */ + AF_UNIRANGE_REC( 0x2DE0, 0x2DFF ), /* Cyrillic Extended-A */ + AF_UNIRANGE_REC( 0xA640, 0xA69F ), /* Cyrillic Extended-B */ + AF_UNIRANGE_REC( 0x1C80, 0x1C8F ), /* Cyrillic Extended-C */ + AF_UNIRANGE_REC( 0, 0 ) }; const AF_Script_UniRangeRec af_cyrl_nonbase_uniranges[] = { - AF_UNIRANGE_REC( 0x0483UL, 0x0489UL ), - AF_UNIRANGE_REC( 0x2DE0UL, 0x2DFFUL ), - AF_UNIRANGE_REC( 0xA66FUL, 0xA67FUL ), - AF_UNIRANGE_REC( 0xA69EUL, 0xA69FUL ), - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x0483, 0x0489 ), + AF_UNIRANGE_REC( 0x2DE0, 0x2DFF ), + AF_UNIRANGE_REC( 0xA66F, 0xA67F ), + AF_UNIRANGE_REC( 0xA69E, 0xA69F ), + AF_UNIRANGE_REC( 0, 0 ) }; @@ -116,420 +285,696 @@ const AF_Script_UniRangeRec af_deva_uniranges[] = { - AF_UNIRANGE_REC( 0x0900UL, 0x093BUL ), /* Devanagari */ + AF_UNIRANGE_REC( 0x0900, 0x093B ), /* Devanagari */ /* omitting U+093C nukta */ - AF_UNIRANGE_REC( 0x093DUL, 0x0950UL ), /* ... continued */ + AF_UNIRANGE_REC( 0x093D, 0x0950 ), /* ... continued */ /* omitting U+0951 udatta, U+0952 anudatta */ - AF_UNIRANGE_REC( 0x0953UL, 0x0963UL ), /* ... continued */ + AF_UNIRANGE_REC( 0x0953, 0x0963 ), /* ... continued */ /* omitting U+0964 danda, U+0965 double danda */ - AF_UNIRANGE_REC( 0x0966UL, 0x097FUL ), /* ... continued */ - AF_UNIRANGE_REC( 0x20B9UL, 0x20B9UL ), /* (new) Rupee sign */ - AF_UNIRANGE_REC( 0xA8E0UL, 0xA8FFUL ), /* Devanagari Extended */ - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x0966, 0x097F ), /* ... continued */ + AF_UNIRANGE_REC( 0x20B9, 0x20B9 ), /* (new) Rupee sign */ + AF_UNIRANGE_REC( 0xA8E0, 0xA8FF ), /* Devanagari Extended */ + AF_UNIRANGE_REC( 0, 0 ) }; const AF_Script_UniRangeRec af_deva_nonbase_uniranges[] = { - AF_UNIRANGE_REC( 0x0900UL, 0x0902UL ), - AF_UNIRANGE_REC( 0x093AUL, 0x093AUL ), - AF_UNIRANGE_REC( 0x0941UL, 0x0948UL ), - AF_UNIRANGE_REC( 0x094DUL, 0x094DUL ), - AF_UNIRANGE_REC( 0x0953UL, 0x0957UL ), - AF_UNIRANGE_REC( 0x0962UL, 0x0963UL ), - AF_UNIRANGE_REC( 0xA8E0UL, 0xA8F1UL ), - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x0900, 0x0902 ), + AF_UNIRANGE_REC( 0x093A, 0x093A ), + AF_UNIRANGE_REC( 0x0941, 0x0948 ), + AF_UNIRANGE_REC( 0x094D, 0x094D ), + AF_UNIRANGE_REC( 0x0953, 0x0957 ), + AF_UNIRANGE_REC( 0x0962, 0x0963 ), + AF_UNIRANGE_REC( 0xA8E0, 0xA8F1 ), + AF_UNIRANGE_REC( 0xA8FF, 0xA8FF ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_dsrt_uniranges[] = + { + AF_UNIRANGE_REC( 0x10400, 0x1044F ), /* Deseret */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_dsrt_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_ethi_uniranges[] = + { + AF_UNIRANGE_REC( 0x1200, 0x137F ), /* Ethiopic */ + AF_UNIRANGE_REC( 0x1380, 0x139F ), /* Ethiopic Supplement */ + AF_UNIRANGE_REC( 0x2D80, 0x2DDF ), /* Ethiopic Extended */ + AF_UNIRANGE_REC( 0xAB00, 0xAB2F ), /* Ethiopic Extended-A */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_ethi_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x135D, 0x135F ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_geor_uniranges[] = + { + AF_UNIRANGE_REC( 0x10D0, 0x10FF ), /* Georgian (Mkhedruli) */ + AF_UNIRANGE_REC( 0x1C90, 0x1CBF ), /* Georgian Extended (Mtavruli) */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_geor_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_geok_uniranges[] = + { + /* Khutsuri */ + AF_UNIRANGE_REC( 0x10A0, 0x10CD ), /* Georgian (Asomtavruli) */ + AF_UNIRANGE_REC( 0x2D00, 0x2D2D ), /* Georgian Supplement (Nuskhuri) */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_geok_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_glag_uniranges[] = + { + AF_UNIRANGE_REC( 0x2C00, 0x2C5F ), /* Glagolitic */ + AF_UNIRANGE_REC( 0x1E000, 0x1E02F ), /* Glagolitic Supplement */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_glag_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x1E000, 0x1E02F ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_goth_uniranges[] = + { + AF_UNIRANGE_REC( 0x10330, 0x1034F ), /* Gothic */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_goth_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) }; const AF_Script_UniRangeRec af_grek_uniranges[] = { - AF_UNIRANGE_REC( 0x0370UL, 0x03FFUL ), /* Greek and Coptic */ - AF_UNIRANGE_REC( 0x1F00UL, 0x1FFFUL ), /* Greek Extended */ - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x0370, 0x03FF ), /* Greek and Coptic */ + AF_UNIRANGE_REC( 0x1F00, 0x1FFF ), /* Greek Extended */ + AF_UNIRANGE_REC( 0, 0 ) }; const AF_Script_UniRangeRec af_grek_nonbase_uniranges[] = { - AF_UNIRANGE_REC( 0x037AUL, 0x037AUL ), - AF_UNIRANGE_REC( 0x0384UL, 0x0385UL ), - AF_UNIRANGE_REC( 0x1FBDUL, 0x1FC1UL ), - AF_UNIRANGE_REC( 0x1FCDUL, 0x1FCFUL ), - AF_UNIRANGE_REC( 0x1FDDUL, 0x1FDFUL ), - AF_UNIRANGE_REC( 0x1FEDUL, 0x1FEFUL ), - AF_UNIRANGE_REC( 0x1FFDUL, 0x1FFEUL ), - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - - const AF_Script_UniRangeRec af_hebr_uniranges[] = - { - AF_UNIRANGE_REC( 0x0590UL, 0x05FFUL ), /* Hebrew */ - AF_UNIRANGE_REC( 0xFB1DUL, 0xFB4FUL ), /* Alphab. Present. Forms (Hebrew) */ - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - const AF_Script_UniRangeRec af_hebr_nonbase_uniranges[] = - { - AF_UNIRANGE_REC( 0x0591UL, 0x05BFUL ), - AF_UNIRANGE_REC( 0x05C1UL, 0x05C2UL ), - AF_UNIRANGE_REC( 0x05C4UL, 0x05C5UL ), - AF_UNIRANGE_REC( 0x05C7UL, 0x05C7UL ), - AF_UNIRANGE_REC( 0xFB1EUL, 0xFB1EUL ), - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - - const AF_Script_UniRangeRec af_lao_uniranges[] = - { - AF_UNIRANGE_REC( 0x0E80UL, 0x0EFFUL ), /* Lao */ - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - const AF_Script_UniRangeRec af_lao_nonbase_uniranges[] = - { - AF_UNIRANGE_REC( 0x0EB1UL, 0x0EB1UL ), - AF_UNIRANGE_REC( 0x0EB4UL, 0x0EBCUL ), - AF_UNIRANGE_REC( 0x0EC8UL, 0x0ECDUL ), - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - - const AF_Script_UniRangeRec af_latn_uniranges[] = - { - AF_UNIRANGE_REC( 0x0020UL, 0x007FUL ), /* Basic Latin (no control chars) */ - AF_UNIRANGE_REC( 0x00A0UL, 0x00A9UL ), /* Latin-1 Supplement (no control chars) */ - AF_UNIRANGE_REC( 0x00ABUL, 0x00B1UL ), /* ... continued */ - AF_UNIRANGE_REC( 0x00B4UL, 0x00B8UL ), /* ... continued */ - AF_UNIRANGE_REC( 0x00BBUL, 0x00FFUL ), /* ... continued */ - AF_UNIRANGE_REC( 0x0100UL, 0x017FUL ), /* Latin Extended-A */ - AF_UNIRANGE_REC( 0x0180UL, 0x024FUL ), /* Latin Extended-B */ - AF_UNIRANGE_REC( 0x0250UL, 0x02AFUL ), /* IPA Extensions */ - AF_UNIRANGE_REC( 0x02B9UL, 0x02DFUL ), /* Spacing Modifier Letters */ - AF_UNIRANGE_REC( 0x02E5UL, 0x02FFUL ), /* ... continued */ - AF_UNIRANGE_REC( 0x0300UL, 0x036FUL ), /* Combining Diacritical Marks */ - AF_UNIRANGE_REC( 0x1AB0UL, 0x1ABEUL ), /* Combining Diacritical Marks Extended */ - AF_UNIRANGE_REC( 0x1D00UL, 0x1D2BUL ), /* Phonetic Extensions */ - AF_UNIRANGE_REC( 0x1D6BUL, 0x1D77UL ), /* ... continued */ - AF_UNIRANGE_REC( 0x1D79UL, 0x1D7FUL ), /* ... continued */ - AF_UNIRANGE_REC( 0x1D80UL, 0x1D9AUL ), /* Phonetic Extensions Supplement */ - AF_UNIRANGE_REC( 0x1DC0UL, 0x1DFFUL ), /* Combining Diacritical Marks Supplement */ - AF_UNIRANGE_REC( 0x1E00UL, 0x1EFFUL ), /* Latin Extended Additional */ - AF_UNIRANGE_REC( 0x2000UL, 0x206FUL ), /* General Punctuation */ - AF_UNIRANGE_REC( 0x20A0UL, 0x20B8UL ), /* Currency Symbols ... */ - AF_UNIRANGE_REC( 0x20BAUL, 0x20CFUL ), /* ... except new Rupee sign */ - AF_UNIRANGE_REC( 0x2150UL, 0x218FUL ), /* Number Forms */ - AF_UNIRANGE_REC( 0x2C60UL, 0x2C7BUL ), /* Latin Extended-C */ - AF_UNIRANGE_REC( 0x2C7EUL, 0x2C7FUL ), /* ... continued */ - AF_UNIRANGE_REC( 0x2E00UL, 0x2E7FUL ), /* Supplemental Punctuation */ - AF_UNIRANGE_REC( 0xA720UL, 0xA76FUL ), /* Latin Extended-D */ - AF_UNIRANGE_REC( 0xA771UL, 0xA7F7UL ), /* ... continued */ - AF_UNIRANGE_REC( 0xA7FAUL, 0xA7FFUL ), /* ... continued */ - AF_UNIRANGE_REC( 0xAB30UL, 0xAB5BUL ), /* Latin Extended-E */ - AF_UNIRANGE_REC( 0xAB60UL, 0xAB6FUL ), /* ... continued */ - AF_UNIRANGE_REC( 0xFB00UL, 0xFB06UL ), /* Alphab. Present. Forms (Latin Ligs) */ - AF_UNIRANGE_REC( 0x1D400UL, 0x1D7FFUL ), /* Mathematical Alphanumeric Symbols */ - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - const AF_Script_UniRangeRec af_latn_nonbase_uniranges[] = - { - AF_UNIRANGE_REC( 0x005EUL, 0x0060UL ), - AF_UNIRANGE_REC( 0x007EUL, 0x007EUL ), - AF_UNIRANGE_REC( 0x00A8UL, 0x00A9UL ), - AF_UNIRANGE_REC( 0x00AEUL, 0x00B0UL ), - AF_UNIRANGE_REC( 0x00B4UL, 0x00B4UL ), - AF_UNIRANGE_REC( 0x00B8UL, 0x00B8UL ), - AF_UNIRANGE_REC( 0x00BCUL, 0x00BEUL ), - AF_UNIRANGE_REC( 0x02B9UL, 0x02DFUL ), - AF_UNIRANGE_REC( 0x02E5UL, 0x02FFUL ), - AF_UNIRANGE_REC( 0x0300UL, 0x036FUL ), - AF_UNIRANGE_REC( 0x1AB0UL, 0x1ABEUL ), - AF_UNIRANGE_REC( 0x1DC0UL, 0x1DFFUL ), - AF_UNIRANGE_REC( 0x2017UL, 0x2017UL ), - AF_UNIRANGE_REC( 0x203EUL, 0x203EUL ), - AF_UNIRANGE_REC( 0xA788UL, 0xA788UL ), - AF_UNIRANGE_REC( 0xA7F8UL, 0xA7FAUL ), - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - - const AF_Script_UniRangeRec af_latb_uniranges[] = - { - AF_UNIRANGE_REC( 0x1D62UL, 0x1D6AUL ), /* some small subscript letters */ - AF_UNIRANGE_REC( 0x2080UL, 0x209CUL ), /* subscript digits and letters */ - AF_UNIRANGE_REC( 0x2C7CUL, 0x2C7CUL ), /* latin subscript small letter j */ - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - const AF_Script_UniRangeRec af_latb_nonbase_uniranges[] = - { - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - - const AF_Script_UniRangeRec af_latp_uniranges[] = - { - AF_UNIRANGE_REC( 0x00AAUL, 0x00AAUL ), /* feminine ordinal indicator */ - AF_UNIRANGE_REC( 0x00B2UL, 0x00B3UL ), /* superscript two and three */ - AF_UNIRANGE_REC( 0x00B9UL, 0x00BAUL ), /* superscript one, masc. ord. indic. */ - AF_UNIRANGE_REC( 0x02B0UL, 0x02B8UL ), /* some latin superscript mod. letters */ - AF_UNIRANGE_REC( 0x02E0UL, 0x02E4UL ), /* some IPA modifier letters */ - AF_UNIRANGE_REC( 0x1D2CUL, 0x1D61UL ), /* latin superscript modifier letters */ - AF_UNIRANGE_REC( 0x1D78UL, 0x1D78UL ), /* modifier letter cyrillic en */ - AF_UNIRANGE_REC( 0x1D9BUL, 0x1DBFUL ), /* more modifier letters */ - AF_UNIRANGE_REC( 0x2070UL, 0x207FUL ), /* superscript digits and letters */ - AF_UNIRANGE_REC( 0x2C7DUL, 0x2C7DUL ), /* modifier letter capital v */ - AF_UNIRANGE_REC( 0xA770UL, 0xA770UL ), /* modifier letter us */ - AF_UNIRANGE_REC( 0xA7F8UL, 0xA7F9UL ), /* more modifier letters */ - AF_UNIRANGE_REC( 0xAB5CUL, 0xAB5FUL ), /* more modifier letters */ - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - const AF_Script_UniRangeRec af_latp_nonbase_uniranges[] = - { - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - - const AF_Script_UniRangeRec af_none_uniranges[] = - { - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - const AF_Script_UniRangeRec af_none_nonbase_uniranges[] = - { - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - - const AF_Script_UniRangeRec af_telu_uniranges[] = - { - AF_UNIRANGE_REC( 0x0C00UL, 0x0C7FUL ), /* Telugu */ - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - const AF_Script_UniRangeRec af_telu_nonbase_uniranges[] = - { - AF_UNIRANGE_REC( 0x0C00UL, 0x0C00UL ), - AF_UNIRANGE_REC( 0x0C3EUL, 0x0C40UL ), - AF_UNIRANGE_REC( 0x0C46UL, 0x0C56UL ), - AF_UNIRANGE_REC( 0x0C62UL, 0x0C63UL ), - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - - const AF_Script_UniRangeRec af_thai_uniranges[] = - { - AF_UNIRANGE_REC( 0x0E00UL, 0x0E7FUL ), /* Thai */ - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - const AF_Script_UniRangeRec af_thai_nonbase_uniranges[] = - { - AF_UNIRANGE_REC( 0x0E31UL, 0x0E31UL ), - AF_UNIRANGE_REC( 0x0E34UL, 0x0E3AUL ), - AF_UNIRANGE_REC( 0x0E47UL, 0x0E4EUL ), - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - -#ifdef AF_CONFIG_OPTION_INDIC - - const AF_Script_UniRangeRec af_beng_uniranges[] = - { - AF_UNIRANGE_REC( 0x0980UL, 0x09FFUL ), /* Bengali */ - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - const AF_Script_UniRangeRec af_beng_nonbase_uniranges[] = - { - AF_UNIRANGE_REC( 0x0981UL, 0x0981UL ), - AF_UNIRANGE_REC( 0x09BCUL, 0x09BCUL ), - AF_UNIRANGE_REC( 0x09C1UL, 0x09C4UL ), - AF_UNIRANGE_REC( 0x09CDUL, 0x09CDUL ), - AF_UNIRANGE_REC( 0x09E2UL, 0x09E3UL ), - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x037A, 0x037A ), + AF_UNIRANGE_REC( 0x0384, 0x0385 ), + AF_UNIRANGE_REC( 0x1FBD, 0x1FC1 ), + AF_UNIRANGE_REC( 0x1FCD, 0x1FCF ), + AF_UNIRANGE_REC( 0x1FDD, 0x1FDF ), + AF_UNIRANGE_REC( 0x1FED, 0x1FEF ), + AF_UNIRANGE_REC( 0x1FFD, 0x1FFE ), + AF_UNIRANGE_REC( 0, 0 ) }; const AF_Script_UniRangeRec af_gujr_uniranges[] = { - AF_UNIRANGE_REC( 0x0A80UL, 0x0AFFUL ), /* Gujarati */ - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x0A80, 0x0AFF ), /* Gujarati */ + AF_UNIRANGE_REC( 0, 0 ) }; const AF_Script_UniRangeRec af_gujr_nonbase_uniranges[] = { - AF_UNIRANGE_REC( 0x0A81UL, 0x0A82UL ), - AF_UNIRANGE_REC( 0x0ABCUL, 0x0ABCUL ), - AF_UNIRANGE_REC( 0x0AC1UL, 0x0AC8UL ), - AF_UNIRANGE_REC( 0x0ACDUL, 0x0ACDUL ), - AF_UNIRANGE_REC( 0x0AE2UL, 0x0AE3UL ), - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x0A81, 0x0A82 ), + AF_UNIRANGE_REC( 0x0ABC, 0x0ABC ), + AF_UNIRANGE_REC( 0x0AC1, 0x0AC8 ), + AF_UNIRANGE_REC( 0x0ACD, 0x0ACD ), + AF_UNIRANGE_REC( 0x0AE2, 0x0AE3 ), + AF_UNIRANGE_REC( 0x0AFA, 0x0AFF ), + AF_UNIRANGE_REC( 0, 0 ) }; const AF_Script_UniRangeRec af_guru_uniranges[] = { - AF_UNIRANGE_REC( 0x0A00UL, 0x0A7FUL ), /* Gurmukhi */ - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x0A00, 0x0A7F ), /* Gurmukhi */ + AF_UNIRANGE_REC( 0, 0 ) }; const AF_Script_UniRangeRec af_guru_nonbase_uniranges[] = { - AF_UNIRANGE_REC( 0x0A01UL, 0x0A02UL ), - AF_UNIRANGE_REC( 0x0A3CUL, 0x0A3EUL ), - AF_UNIRANGE_REC( 0x0A41UL, 0x0A51UL ), - AF_UNIRANGE_REC( 0x0A70UL, 0x0A71UL ), - AF_UNIRANGE_REC( 0x0A75UL, 0x0A75UL ), - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x0A01, 0x0A02 ), + AF_UNIRANGE_REC( 0x0A3C, 0x0A3C ), + AF_UNIRANGE_REC( 0x0A41, 0x0A51 ), + AF_UNIRANGE_REC( 0x0A70, 0x0A71 ), + AF_UNIRANGE_REC( 0x0A75, 0x0A75 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_hebr_uniranges[] = + { + AF_UNIRANGE_REC( 0x0590, 0x05FF ), /* Hebrew */ + AF_UNIRANGE_REC( 0xFB1D, 0xFB4F ), /* Alphab. Present. Forms (Hebrew) */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_hebr_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0591, 0x05BF ), + AF_UNIRANGE_REC( 0x05C1, 0x05C2 ), + AF_UNIRANGE_REC( 0x05C4, 0x05C5 ), + AF_UNIRANGE_REC( 0x05C7, 0x05C7 ), + AF_UNIRANGE_REC( 0xFB1E, 0xFB1E ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_kali_uniranges[] = + { + AF_UNIRANGE_REC( 0xA900, 0xA92F ), /* Kayah Li */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_kali_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0xA926, 0xA92D ), + AF_UNIRANGE_REC( 0, 0 ) }; const AF_Script_UniRangeRec af_knda_uniranges[] = { - AF_UNIRANGE_REC( 0x0C80UL, 0x0CFFUL ), /* Kannada */ - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x0C80, 0x0CFF ), /* Kannada */ + AF_UNIRANGE_REC( 0, 0 ) }; const AF_Script_UniRangeRec af_knda_nonbase_uniranges[] = { - AF_UNIRANGE_REC( 0x0C81UL, 0x0C81UL ), - AF_UNIRANGE_REC( 0x0CBCUL, 0x0CBCUL ), - AF_UNIRANGE_REC( 0x0CBFUL, 0x0CBFUL ), - AF_UNIRANGE_REC( 0x0CC6UL, 0x0CC6UL ), - AF_UNIRANGE_REC( 0x0CCCUL, 0x0CCDUL ), - AF_UNIRANGE_REC( 0x0CE2UL, 0x0CE3UL ), - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x0C81, 0x0C81 ), + AF_UNIRANGE_REC( 0x0CBC, 0x0CBC ), + AF_UNIRANGE_REC( 0x0CBF, 0x0CBF ), + AF_UNIRANGE_REC( 0x0CC6, 0x0CC6 ), + AF_UNIRANGE_REC( 0x0CCC, 0x0CCD ), + AF_UNIRANGE_REC( 0x0CE2, 0x0CE3 ), + AF_UNIRANGE_REC( 0, 0 ) }; - const AF_Script_UniRangeRec af_limb_uniranges[] = + const AF_Script_UniRangeRec af_khmr_uniranges[] = { - AF_UNIRANGE_REC( 0x1900UL, 0x194FUL ), /* Limbu */ - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x1780, 0x17FF ), /* Khmer */ + AF_UNIRANGE_REC( 0, 0 ) }; - const AF_Script_UniRangeRec af_limb_nonbase_uniranges[] = + const AF_Script_UniRangeRec af_khmr_nonbase_uniranges[] = { - AF_UNIRANGE_REC( 0x1920UL, 0x1922UL ), - AF_UNIRANGE_REC( 0x1927UL, 0x1934UL ), - AF_UNIRANGE_REC( 0x1937UL, 0x193BUL ), - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x17B7, 0x17BD ), + AF_UNIRANGE_REC( 0x17C6, 0x17C6 ), + AF_UNIRANGE_REC( 0x17C9, 0x17D3 ), + AF_UNIRANGE_REC( 0x17DD, 0x17DD ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_khms_uniranges[] = + { + AF_UNIRANGE_REC( 0x19E0, 0x19FF ), /* Khmer Symbols */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_khms_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_lao_uniranges[] = + { + AF_UNIRANGE_REC( 0x0E80, 0x0EFF ), /* Lao */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_lao_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0EB1, 0x0EB1 ), + AF_UNIRANGE_REC( 0x0EB4, 0x0EBC ), + AF_UNIRANGE_REC( 0x0EC8, 0x0ECD ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_latn_uniranges[] = + { + AF_UNIRANGE_REC( 0x0020, 0x007F ), /* Basic Latin (no control chars) */ + AF_UNIRANGE_REC( 0x00A0, 0x00A9 ), /* Latin-1 Supplement (no control chars) */ + AF_UNIRANGE_REC( 0x00AB, 0x00B1 ), /* ... continued */ + AF_UNIRANGE_REC( 0x00B4, 0x00B8 ), /* ... continued */ + AF_UNIRANGE_REC( 0x00BB, 0x00FF ), /* ... continued */ + AF_UNIRANGE_REC( 0x0100, 0x017F ), /* Latin Extended-A */ + AF_UNIRANGE_REC( 0x0180, 0x024F ), /* Latin Extended-B */ + AF_UNIRANGE_REC( 0x0250, 0x02AF ), /* IPA Extensions */ + AF_UNIRANGE_REC( 0x02B9, 0x02DF ), /* Spacing Modifier Letters */ + AF_UNIRANGE_REC( 0x02E5, 0x02FF ), /* ... continued */ + AF_UNIRANGE_REC( 0x0300, 0x036F ), /* Combining Diacritical Marks */ + AF_UNIRANGE_REC( 0x1AB0, 0x1ABE ), /* Combining Diacritical Marks Extended */ + AF_UNIRANGE_REC( 0x1D00, 0x1D2B ), /* Phonetic Extensions */ + AF_UNIRANGE_REC( 0x1D6B, 0x1D77 ), /* ... continued */ + AF_UNIRANGE_REC( 0x1D79, 0x1D7F ), /* ... continued */ + AF_UNIRANGE_REC( 0x1D80, 0x1D9A ), /* Phonetic Extensions Supplement */ + AF_UNIRANGE_REC( 0x1DC0, 0x1DFF ), /* Combining Diacritical Marks Supplement */ + AF_UNIRANGE_REC( 0x1E00, 0x1EFF ), /* Latin Extended Additional */ + AF_UNIRANGE_REC( 0x2000, 0x206F ), /* General Punctuation */ + AF_UNIRANGE_REC( 0x20A0, 0x20B8 ), /* Currency Symbols ... */ + AF_UNIRANGE_REC( 0x20BA, 0x20CF ), /* ... except new Rupee sign */ + AF_UNIRANGE_REC( 0x2150, 0x218F ), /* Number Forms */ + AF_UNIRANGE_REC( 0x2C60, 0x2C7B ), /* Latin Extended-C */ + AF_UNIRANGE_REC( 0x2C7E, 0x2C7F ), /* ... continued */ + AF_UNIRANGE_REC( 0x2E00, 0x2E7F ), /* Supplemental Punctuation */ + AF_UNIRANGE_REC( 0xA720, 0xA76F ), /* Latin Extended-D */ + AF_UNIRANGE_REC( 0xA771, 0xA7F7 ), /* ... continued */ + AF_UNIRANGE_REC( 0xA7FA, 0xA7FF ), /* ... continued */ + AF_UNIRANGE_REC( 0xAB30, 0xAB5B ), /* Latin Extended-E */ + AF_UNIRANGE_REC( 0xAB60, 0xAB6F ), /* ... continued */ + AF_UNIRANGE_REC( 0xFB00, 0xFB06 ), /* Alphab. Present. Forms (Latin Ligs) */ + AF_UNIRANGE_REC( 0x1D400, 0x1D7FF ), /* Mathematical Alphanumeric Symbols */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_latn_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x005E, 0x0060 ), + AF_UNIRANGE_REC( 0x007E, 0x007E ), + AF_UNIRANGE_REC( 0x00A8, 0x00A9 ), + AF_UNIRANGE_REC( 0x00AE, 0x00B0 ), + AF_UNIRANGE_REC( 0x00B4, 0x00B4 ), + AF_UNIRANGE_REC( 0x00B8, 0x00B8 ), + AF_UNIRANGE_REC( 0x00BC, 0x00BE ), + AF_UNIRANGE_REC( 0x02B9, 0x02DF ), + AF_UNIRANGE_REC( 0x02E5, 0x02FF ), + AF_UNIRANGE_REC( 0x0300, 0x036F ), + AF_UNIRANGE_REC( 0x1AB0, 0x1ABE ), + AF_UNIRANGE_REC( 0x1DC0, 0x1DFF ), + AF_UNIRANGE_REC( 0x2017, 0x2017 ), + AF_UNIRANGE_REC( 0x203E, 0x203E ), + AF_UNIRANGE_REC( 0xA788, 0xA788 ), + AF_UNIRANGE_REC( 0xA7F8, 0xA7FA ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_latb_uniranges[] = + { + AF_UNIRANGE_REC( 0x1D62, 0x1D6A ), /* some small subscript letters */ + AF_UNIRANGE_REC( 0x2080, 0x209C ), /* subscript digits and letters */ + AF_UNIRANGE_REC( 0x2C7C, 0x2C7C ), /* latin subscript small letter j */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_latb_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_latp_uniranges[] = + { + AF_UNIRANGE_REC( 0x00AA, 0x00AA ), /* feminine ordinal indicator */ + AF_UNIRANGE_REC( 0x00B2, 0x00B3 ), /* superscript two and three */ + AF_UNIRANGE_REC( 0x00B9, 0x00BA ), /* superscript one, masc. ord. indic. */ + AF_UNIRANGE_REC( 0x02B0, 0x02B8 ), /* some latin superscript mod. letters */ + AF_UNIRANGE_REC( 0x02E0, 0x02E4 ), /* some IPA modifier letters */ + AF_UNIRANGE_REC( 0x1D2C, 0x1D61 ), /* latin superscript modifier letters */ + AF_UNIRANGE_REC( 0x1D78, 0x1D78 ), /* modifier letter cyrillic en */ + AF_UNIRANGE_REC( 0x1D9B, 0x1DBF ), /* more modifier letters */ + AF_UNIRANGE_REC( 0x2070, 0x207F ), /* superscript digits and letters */ + AF_UNIRANGE_REC( 0x2C7D, 0x2C7D ), /* modifier letter capital v */ + AF_UNIRANGE_REC( 0xA770, 0xA770 ), /* modifier letter us */ + AF_UNIRANGE_REC( 0xA7F8, 0xA7F9 ), /* more modifier letters */ + AF_UNIRANGE_REC( 0xAB5C, 0xAB5F ), /* more modifier letters */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_latp_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_lisu_uniranges[] = + { + AF_UNIRANGE_REC( 0xA4D0, 0xA4FF ), /* Lisu */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_lisu_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) }; const AF_Script_UniRangeRec af_mlym_uniranges[] = { - AF_UNIRANGE_REC( 0x0D00UL, 0x0D7FUL ), /* Malayalam */ - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x0D00, 0x0D7F ), /* Malayalam */ + AF_UNIRANGE_REC( 0, 0 ) }; const AF_Script_UniRangeRec af_mlym_nonbase_uniranges[] = { - AF_UNIRANGE_REC( 0x0D01UL, 0x0D01UL ), - AF_UNIRANGE_REC( 0x0D4DUL, 0x0D4EUL ), - AF_UNIRANGE_REC( 0x0D62UL, 0x0D63UL ), - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x0D00, 0x0D01 ), + AF_UNIRANGE_REC( 0x0D3B, 0x0D3C ), + AF_UNIRANGE_REC( 0x0D4D, 0x0D4E ), + AF_UNIRANGE_REC( 0x0D62, 0x0D63 ), + AF_UNIRANGE_REC( 0, 0 ) }; - const AF_Script_UniRangeRec af_orya_uniranges[] = + const AF_Script_UniRangeRec af_mymr_uniranges[] = { - AF_UNIRANGE_REC( 0x0B00UL, 0x0B7FUL ), /* Oriya */ - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x1000, 0x109F ), /* Myanmar */ + AF_UNIRANGE_REC( 0xA9E0, 0xA9FF ), /* Myanmar Extended-B */ + AF_UNIRANGE_REC( 0xAA60, 0xAA7F ), /* Myanmar Extended-A */ + AF_UNIRANGE_REC( 0, 0 ) }; - const AF_Script_UniRangeRec af_orya_nonbase_uniranges[] = + const AF_Script_UniRangeRec af_mymr_nonbase_uniranges[] = { - AF_UNIRANGE_REC( 0x0B01UL, 0x0B02UL ), - AF_UNIRANGE_REC( 0x0B3CUL, 0x0B3CUL ), - AF_UNIRANGE_REC( 0x0B3FUL, 0x0B3FUL ), - AF_UNIRANGE_REC( 0x0B41UL, 0x0B44UL ), - AF_UNIRANGE_REC( 0x0B4DUL, 0x0B56UL ), - AF_UNIRANGE_REC( 0x0B62UL, 0x0B63UL ), - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x102D, 0x1030 ), + AF_UNIRANGE_REC( 0x1032, 0x1037 ), + AF_UNIRANGE_REC( 0x103A, 0x103A ), + AF_UNIRANGE_REC( 0x103D, 0x103E ), + AF_UNIRANGE_REC( 0x1058, 0x1059 ), + AF_UNIRANGE_REC( 0x105E, 0x1060 ), + AF_UNIRANGE_REC( 0x1071, 0x1074 ), + AF_UNIRANGE_REC( 0x1082, 0x1082 ), + AF_UNIRANGE_REC( 0x1085, 0x1086 ), + AF_UNIRANGE_REC( 0x108D, 0x108D ), + AF_UNIRANGE_REC( 0xA9E5, 0xA9E5 ), + AF_UNIRANGE_REC( 0xAA7C, 0xAA7C ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_nkoo_uniranges[] = + { + AF_UNIRANGE_REC( 0x07C0, 0x07FF ), /* N'Ko */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_nkoo_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x07EB, 0x07F5 ), + AF_UNIRANGE_REC( 0x07FD, 0x07FD ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_none_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_none_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_olck_uniranges[] = + { + AF_UNIRANGE_REC( 0x1C50, 0x1C7F ), /* Ol Chiki */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_olck_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_orkh_uniranges[] = + { + AF_UNIRANGE_REC( 0x10C00, 0x10C4F ), /* Old Turkic */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_orkh_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_osge_uniranges[] = + { + AF_UNIRANGE_REC( 0x104B0, 0x104FF ), /* Osage */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_osge_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_osma_uniranges[] = + { + AF_UNIRANGE_REC( 0x10480, 0x104AF ), /* Osmanya */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_osma_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_saur_uniranges[] = + { + AF_UNIRANGE_REC( 0xA880, 0xA8DF ), /* Saurashtra */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_saur_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0xA880, 0xA881 ), + AF_UNIRANGE_REC( 0xA8B4, 0xA8C5 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_shaw_uniranges[] = + { + AF_UNIRANGE_REC( 0x10450, 0x1047F ), /* Shavian */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_shaw_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) }; const AF_Script_UniRangeRec af_sinh_uniranges[] = { - AF_UNIRANGE_REC( 0x0D80UL, 0x0DFFUL ), /* Sinhala */ - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x0D80, 0x0DFF ), /* Sinhala */ + AF_UNIRANGE_REC( 0, 0 ) }; const AF_Script_UniRangeRec af_sinh_nonbase_uniranges[] = { - AF_UNIRANGE_REC( 0x0DCAUL, 0x0DCAUL ), - AF_UNIRANGE_REC( 0x0DD2UL, 0x0DD6UL ), - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x0DCA, 0x0DCA ), + AF_UNIRANGE_REC( 0x0DD2, 0x0DD6 ), + AF_UNIRANGE_REC( 0, 0 ) }; const AF_Script_UniRangeRec af_sund_uniranges[] = { - AF_UNIRANGE_REC( 0x1B80UL, 0x1BBFUL ), /* Sundanese */ - AF_UNIRANGE_REC( 0x1CC0UL, 0x1CCFUL ), /* Sundanese Supplement */ - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x1B80, 0x1BBF ), /* Sundanese */ + AF_UNIRANGE_REC( 0x1CC0, 0x1CCF ), /* Sundanese Supplement */ + AF_UNIRANGE_REC( 0, 0 ) }; const AF_Script_UniRangeRec af_sund_nonbase_uniranges[] = { - AF_UNIRANGE_REC( 0x1B80UL, 0x1B82UL ), - AF_UNIRANGE_REC( 0x1BA1UL, 0x1BADUL ), - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - - const AF_Script_UniRangeRec af_sylo_uniranges[] = - { - AF_UNIRANGE_REC( 0xA800UL, 0xA82FUL ), /* Syloti Nagri */ - AF_UNIRANGE_REC( 0UL, 0UL ) - }; - - const AF_Script_UniRangeRec af_sylo_nonbase_uniranges[] = - { - AF_UNIRANGE_REC( 0xA802UL, 0xA802UL ), - AF_UNIRANGE_REC( 0xA806UL, 0xA806UL ), - AF_UNIRANGE_REC( 0xA80BUL, 0xA80BUL ), - AF_UNIRANGE_REC( 0xA825UL, 0xA826UL ), - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x1B80, 0x1B82 ), + AF_UNIRANGE_REC( 0x1BA1, 0x1BAD ), + AF_UNIRANGE_REC( 0, 0 ) }; const AF_Script_UniRangeRec af_taml_uniranges[] = { - AF_UNIRANGE_REC( 0x0B80UL, 0x0BFFUL ), /* Tamil */ - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x0B80, 0x0BFF ), /* Tamil */ + AF_UNIRANGE_REC( 0, 0 ) }; const AF_Script_UniRangeRec af_taml_nonbase_uniranges[] = { - AF_UNIRANGE_REC( 0x0B82UL, 0x0B82UL ), - AF_UNIRANGE_REC( 0x0BC0UL, 0x0BC2UL ), - AF_UNIRANGE_REC( 0x0BCDUL, 0x0BCDUL ), - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x0B82, 0x0B82 ), + AF_UNIRANGE_REC( 0x0BC0, 0x0BC2 ), + AF_UNIRANGE_REC( 0x0BCD, 0x0BCD ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_tavt_uniranges[] = + { + AF_UNIRANGE_REC( 0xAA80, 0xAADF ), /* Tai Viet */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_tavt_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0xAAB0, 0xAAB0 ), + AF_UNIRANGE_REC( 0xAAB2, 0xAAB4 ), + AF_UNIRANGE_REC( 0xAAB7, 0xAAB8 ), + AF_UNIRANGE_REC( 0xAABE, 0xAABF ), + AF_UNIRANGE_REC( 0xAAC1, 0xAAC1 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_telu_uniranges[] = + { + AF_UNIRANGE_REC( 0x0C00, 0x0C7F ), /* Telugu */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_telu_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0C00, 0x0C00 ), + AF_UNIRANGE_REC( 0x0C04, 0x0C04 ), + AF_UNIRANGE_REC( 0x0C3E, 0x0C40 ), + AF_UNIRANGE_REC( 0x0C46, 0x0C56 ), + AF_UNIRANGE_REC( 0x0C62, 0x0C63 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_thai_uniranges[] = + { + AF_UNIRANGE_REC( 0x0E00, 0x0E7F ), /* Thai */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_thai_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0E31, 0x0E31 ), + AF_UNIRANGE_REC( 0x0E34, 0x0E3A ), + AF_UNIRANGE_REC( 0x0E47, 0x0E4E ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_tfng_uniranges[] = + { + AF_UNIRANGE_REC( 0x2D30, 0x2D7F ), /* Tifinagh */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_tfng_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_vaii_uniranges[] = + { + AF_UNIRANGE_REC( 0xA500, 0xA63F ), /* Vai */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_vaii_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0, 0 ) + }; + + +#ifdef AF_CONFIG_OPTION_INDIC + + const AF_Script_UniRangeRec af_limb_uniranges[] = + { + AF_UNIRANGE_REC( 0x1900, 0x194F ), /* Limbu */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_limb_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x1920, 0x1922 ), + AF_UNIRANGE_REC( 0x1927, 0x1934 ), + AF_UNIRANGE_REC( 0x1937, 0x193B ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_orya_uniranges[] = + { + AF_UNIRANGE_REC( 0x0B00, 0x0B7F ), /* Oriya */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_orya_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x0B01, 0x0B02 ), + AF_UNIRANGE_REC( 0x0B3C, 0x0B3C ), + AF_UNIRANGE_REC( 0x0B3F, 0x0B3F ), + AF_UNIRANGE_REC( 0x0B41, 0x0B44 ), + AF_UNIRANGE_REC( 0x0B4D, 0x0B56 ), + AF_UNIRANGE_REC( 0x0B62, 0x0B63 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + + const AF_Script_UniRangeRec af_sylo_uniranges[] = + { + AF_UNIRANGE_REC( 0xA800, 0xA82F ), /* Syloti Nagri */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_sylo_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0xA802, 0xA802 ), + AF_UNIRANGE_REC( 0xA806, 0xA806 ), + AF_UNIRANGE_REC( 0xA80B, 0xA80B ), + AF_UNIRANGE_REC( 0xA825, 0xA826 ), + AF_UNIRANGE_REC( 0, 0 ) }; const AF_Script_UniRangeRec af_tibt_uniranges[] = { - AF_UNIRANGE_REC( 0x0F00UL, 0x0FFFUL ), /* Tibetan */ - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x0F00, 0x0FFF ), /* Tibetan */ + AF_UNIRANGE_REC( 0, 0 ) }; const AF_Script_UniRangeRec af_tibt_nonbase_uniranges[] = { - AF_UNIRANGE_REC( 0x0F18UL, 0x0F19UL ), - AF_UNIRANGE_REC( 0x0F35UL, 0x0F35UL ), - AF_UNIRANGE_REC( 0x0F37UL, 0x0F37UL ), - AF_UNIRANGE_REC( 0x0F39UL, 0x0F39UL ), - AF_UNIRANGE_REC( 0x0F3EUL, 0x0F3FUL ), - AF_UNIRANGE_REC( 0x0F71UL, 0x0F7EUL ), - AF_UNIRANGE_REC( 0x0F80UL, 0x0F84UL ), - AF_UNIRANGE_REC( 0x0F86UL, 0x0F87UL ), - AF_UNIRANGE_REC( 0x0F8DUL, 0x0FBCUL ), - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x0F18, 0x0F19 ), + AF_UNIRANGE_REC( 0x0F35, 0x0F35 ), + AF_UNIRANGE_REC( 0x0F37, 0x0F37 ), + AF_UNIRANGE_REC( 0x0F39, 0x0F39 ), + AF_UNIRANGE_REC( 0x0F3E, 0x0F3F ), + AF_UNIRANGE_REC( 0x0F71, 0x0F7E ), + AF_UNIRANGE_REC( 0x0F80, 0x0F84 ), + AF_UNIRANGE_REC( 0x0F86, 0x0F87 ), + AF_UNIRANGE_REC( 0x0F8D, 0x0FBC ), + AF_UNIRANGE_REC( 0, 0 ) }; #endif /* !AF_CONFIG_OPTION_INDIC */ @@ -540,44 +985,47 @@ const AF_Script_UniRangeRec af_hani_uniranges[] = { - AF_UNIRANGE_REC( 0x1100UL, 0x11FFUL ), /* Hangul Jamo */ - AF_UNIRANGE_REC( 0x2E80UL, 0x2EFFUL ), /* CJK Radicals Supplement */ - AF_UNIRANGE_REC( 0x2F00UL, 0x2FDFUL ), /* Kangxi Radicals */ - AF_UNIRANGE_REC( 0x2FF0UL, 0x2FFFUL ), /* Ideographic Description Characters */ - AF_UNIRANGE_REC( 0x3000UL, 0x303FUL ), /* CJK Symbols and Punctuation */ - AF_UNIRANGE_REC( 0x3040UL, 0x309FUL ), /* Hiragana */ - AF_UNIRANGE_REC( 0x30A0UL, 0x30FFUL ), /* Katakana */ - AF_UNIRANGE_REC( 0x3100UL, 0x312FUL ), /* Bopomofo */ - AF_UNIRANGE_REC( 0x3130UL, 0x318FUL ), /* Hangul Compatibility Jamo */ - AF_UNIRANGE_REC( 0x3190UL, 0x319FUL ), /* Kanbun */ - AF_UNIRANGE_REC( 0x31A0UL, 0x31BFUL ), /* Bopomofo Extended */ - AF_UNIRANGE_REC( 0x31C0UL, 0x31EFUL ), /* CJK Strokes */ - AF_UNIRANGE_REC( 0x31F0UL, 0x31FFUL ), /* Katakana Phonetic Extensions */ - AF_UNIRANGE_REC( 0x3300UL, 0x33FFUL ), /* CJK Compatibility */ - AF_UNIRANGE_REC( 0x3400UL, 0x4DBFUL ), /* CJK Unified Ideographs Extension A */ - AF_UNIRANGE_REC( 0x4DC0UL, 0x4DFFUL ), /* Yijing Hexagram Symbols */ - AF_UNIRANGE_REC( 0x4E00UL, 0x9FFFUL ), /* CJK Unified Ideographs */ - AF_UNIRANGE_REC( 0xA960UL, 0xA97FUL ), /* Hangul Jamo Extended-A */ - AF_UNIRANGE_REC( 0xAC00UL, 0xD7AFUL ), /* Hangul Syllables */ - AF_UNIRANGE_REC( 0xD7B0UL, 0xD7FFUL ), /* Hangul Jamo Extended-B */ - AF_UNIRANGE_REC( 0xF900UL, 0xFAFFUL ), /* CJK Compatibility Ideographs */ - AF_UNIRANGE_REC( 0xFE10UL, 0xFE1FUL ), /* Vertical forms */ - AF_UNIRANGE_REC( 0xFE30UL, 0xFE4FUL ), /* CJK Compatibility Forms */ - AF_UNIRANGE_REC( 0xFF00UL, 0xFFEFUL ), /* Halfwidth and Fullwidth Forms */ - AF_UNIRANGE_REC( 0x1B000UL, 0x1B0FFUL ), /* Kana Supplement */ - AF_UNIRANGE_REC( 0x1D300UL, 0x1D35FUL ), /* Tai Xuan Hing Symbols */ - AF_UNIRANGE_REC( 0x20000UL, 0x2A6DFUL ), /* CJK Unified Ideographs Extension B */ - AF_UNIRANGE_REC( 0x2A700UL, 0x2B73FUL ), /* CJK Unified Ideographs Extension C */ - AF_UNIRANGE_REC( 0x2B740UL, 0x2B81FUL ), /* CJK Unified Ideographs Extension D */ - AF_UNIRANGE_REC( 0x2F800UL, 0x2FA1FUL ), /* CJK Compatibility Ideographs Supplement */ - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x1100, 0x11FF ), /* Hangul Jamo */ + AF_UNIRANGE_REC( 0x2E80, 0x2EFF ), /* CJK Radicals Supplement */ + AF_UNIRANGE_REC( 0x2F00, 0x2FDF ), /* Kangxi Radicals */ + AF_UNIRANGE_REC( 0x2FF0, 0x2FFF ), /* Ideographic Description Characters */ + AF_UNIRANGE_REC( 0x3000, 0x303F ), /* CJK Symbols and Punctuation */ + AF_UNIRANGE_REC( 0x3040, 0x309F ), /* Hiragana */ + AF_UNIRANGE_REC( 0x30A0, 0x30FF ), /* Katakana */ + AF_UNIRANGE_REC( 0x3100, 0x312F ), /* Bopomofo */ + AF_UNIRANGE_REC( 0x3130, 0x318F ), /* Hangul Compatibility Jamo */ + AF_UNIRANGE_REC( 0x3190, 0x319F ), /* Kanbun */ + AF_UNIRANGE_REC( 0x31A0, 0x31BF ), /* Bopomofo Extended */ + AF_UNIRANGE_REC( 0x31C0, 0x31EF ), /* CJK Strokes */ + AF_UNIRANGE_REC( 0x31F0, 0x31FF ), /* Katakana Phonetic Extensions */ + AF_UNIRANGE_REC( 0x3300, 0x33FF ), /* CJK Compatibility */ + AF_UNIRANGE_REC( 0x3400, 0x4DBF ), /* CJK Unified Ideographs Extension A */ + AF_UNIRANGE_REC( 0x4DC0, 0x4DFF ), /* Yijing Hexagram Symbols */ + AF_UNIRANGE_REC( 0x4E00, 0x9FFF ), /* CJK Unified Ideographs */ + AF_UNIRANGE_REC( 0xA960, 0xA97F ), /* Hangul Jamo Extended-A */ + AF_UNIRANGE_REC( 0xAC00, 0xD7AF ), /* Hangul Syllables */ + AF_UNIRANGE_REC( 0xD7B0, 0xD7FF ), /* Hangul Jamo Extended-B */ + AF_UNIRANGE_REC( 0xF900, 0xFAFF ), /* CJK Compatibility Ideographs */ + AF_UNIRANGE_REC( 0xFE10, 0xFE1F ), /* Vertical forms */ + AF_UNIRANGE_REC( 0xFE30, 0xFE4F ), /* CJK Compatibility Forms */ + AF_UNIRANGE_REC( 0xFF00, 0xFFEF ), /* Halfwidth and Fullwidth Forms */ + AF_UNIRANGE_REC( 0x1B000, 0x1B0FF ), /* Kana Supplement */ + AF_UNIRANGE_REC( 0x1B100, 0x1B12F ), /* Kana Extended-A */ + AF_UNIRANGE_REC( 0x1D300, 0x1D35F ), /* Tai Xuan Hing Symbols */ + AF_UNIRANGE_REC( 0x20000, 0x2A6DF ), /* CJK Unified Ideographs Extension B */ + AF_UNIRANGE_REC( 0x2A700, 0x2B73F ), /* CJK Unified Ideographs Extension C */ + AF_UNIRANGE_REC( 0x2B740, 0x2B81F ), /* CJK Unified Ideographs Extension D */ + AF_UNIRANGE_REC( 0x2B820, 0x2CEAF ), /* CJK Unified Ideographs Extension E */ + AF_UNIRANGE_REC( 0x2CEB0, 0x2EBEF ), /* CJK Unified Ideographs Extension F */ + AF_UNIRANGE_REC( 0x2F800, 0x2FA1F ), /* CJK Compatibility Ideographs Supplement */ + AF_UNIRANGE_REC( 0, 0 ) }; const AF_Script_UniRangeRec af_hani_nonbase_uniranges[] = { - AF_UNIRANGE_REC( 0x302AUL, 0x302FUL ), - AF_UNIRANGE_REC( 0x3190UL, 0x319FUL ), - AF_UNIRANGE_REC( 0UL, 0UL ) + AF_UNIRANGE_REC( 0x302A, 0x302F ), + AF_UNIRANGE_REC( 0x3190, 0x319F ), + AF_UNIRANGE_REC( 0, 0 ) }; #endif /* !AF_CONFIG_OPTION_CJK */ diff --git a/src/3rdparty/freetype/src/autofit/afranges.h b/src/3rdparty/freetype/src/autofit/afranges.h index b080873e77..ba3b5e7ccb 100644 --- a/src/3rdparty/freetype/src/autofit/afranges.h +++ b/src/3rdparty/freetype/src/autofit/afranges.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter Unicode script ranges (specification). */ /* */ -/* Copyright 2013-2015 by */ +/* Copyright 2013-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __AFRANGES_H__ -#define __AFRANGES_H__ +#ifndef AFRANGES_H_ +#define AFRANGES_H_ #include "aftypes.h" @@ -26,13 +26,13 @@ FT_BEGIN_HEADER #undef SCRIPT -#define SCRIPT( s, S, d, h, sc1, sc2, sc3 ) \ +#define SCRIPT( s, S, d, h, H, ss ) \ extern const AF_Script_UniRangeRec af_ ## s ## _uniranges[]; #include "afscript.h" #undef SCRIPT -#define SCRIPT( s, S, d, h, sc1, sc2, sc3 ) \ +#define SCRIPT( s, S, d, h, H, ss ) \ extern const AF_Script_UniRangeRec af_ ## s ## _nonbase_uniranges[]; #include "afscript.h" @@ -41,7 +41,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __AFRANGES_H__ */ +#endif /* AFRANGES_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/autofit/afscript.h b/src/3rdparty/freetype/src/autofit/afscript.h index b92e84f5ff..623a1734a6 100644 --- a/src/3rdparty/freetype/src/autofit/afscript.h +++ b/src/3rdparty/freetype/src/autofit/afscript.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter scripts (specification only). */ /* */ -/* Copyright 2013-2015 by */ +/* Copyright 2013-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -30,129 +30,349 @@ /* use `HB_SCRIPT_INVALID' as the HarfBuzz script name tag for */ /* them. */ + SCRIPT( adlm, ADLM, + "Adlam", + HB_SCRIPT_ADLAM, + HINTING_BOTTOM_TO_TOP, + "\xF0\x9E\xA4\x8C \xF0\x9E\xA4\xAE" ) /* 𞤌 𞤮 */ + SCRIPT( arab, ARAB, "Arabic", HB_SCRIPT_ARABIC, - 0x644, 0x62D, 0x640 ) /* ل ح ـ */ + HINTING_BOTTOM_TO_TOP, + "\xD9\x84 \xD8\xAD \xD9\x80" ) /* ل ح ـ */ + + SCRIPT( armn, ARMN, + "Armenian", + HB_SCRIPT_ARMENIAN, + HINTING_BOTTOM_TO_TOP, + "\xD5\xBD \xD5\x8D" ) /* ս Ս */ + + SCRIPT( avst, AVST, + "Avestan", + HB_SCRIPT_AVESTAN, + HINTING_BOTTOM_TO_TOP, + "\xF0\x90\xAC\x9A" ) /* 𐬚 */ + + SCRIPT( bamu, BAMU, + "Bamum", + HB_SCRIPT_BAMUM, + HINTING_BOTTOM_TO_TOP, + "\xEA\x9B\x81 \xEA\x9B\xAF" ) /* ꛁ ꛯ */ + + /* there are no simple forms for letters; we thus use two digit shapes */ + SCRIPT( beng, BENG, + "Bengali", + HB_SCRIPT_BENGALI, + HINTING_TOP_TO_BOTTOM, + "\xE0\xA7\xA6 \xE0\xA7\xAA" ) /* ০ ৪ */ + + SCRIPT( buhd, BUHD, + "Buhid", + HB_SCRIPT_BUHID, + HINTING_BOTTOM_TO_TOP, + "\xE1\x9D\x8B \xE1\x9D\x8F" ) /* ᝋ ᝏ */ + + SCRIPT( cakm, CAKM, + "Chakma", + HB_SCRIPT_CHAKMA, + HINTING_BOTTOM_TO_TOP, + "\xF0\x91\x84\xA4 \xF0\x91\x84\x89 \xF0\x91\x84\x9B" ) /* 𑄤 𑄉 𑄛 */ + + SCRIPT( cans, CANS, + "Canadian Syllabics", + HB_SCRIPT_CANADIAN_SYLLABICS, + HINTING_BOTTOM_TO_TOP, + "\xE1\x91\x8C \xE1\x93\x9A" ) /* ᑌ ᓚ */ + + SCRIPT( cari, CARI, + "Carian", + HB_SCRIPT_CARIAN, + HINTING_BOTTOM_TO_TOP, + "\xF0\x90\x8A\xAB \xF0\x90\x8B\x89" ) /* 𐊫 𐋉 */ + + SCRIPT( cher, CHER, + "Cherokee", + HB_SCRIPT_CHEROKEE, + HINTING_BOTTOM_TO_TOP, + "\xE1\x8E\xA4 \xE1\x8F\x85 \xEA\xAE\x95" ) /* Ꭴ Ꮕ ꮕ */ + + SCRIPT( copt, COPT, + "Coptic", + HB_SCRIPT_COPTIC, + HINTING_BOTTOM_TO_TOP, + "\xE2\xB2\x9E \xE2\xB2\x9F" ) /* Ⲟ ⲟ */ + + SCRIPT( cprt, CPRT, + "Cypriot", + HB_SCRIPT_CYPRIOT, + HINTING_BOTTOM_TO_TOP, + "\xF0\x90\xA0\x85 \xF0\x90\xA0\xA3" ) /* 𐠅 𐠣 */ SCRIPT( cyrl, CYRL, "Cyrillic", HB_SCRIPT_CYRILLIC, - 0x43E, 0x41E, 0x0 ) /* о О */ + HINTING_BOTTOM_TO_TOP, + "\xD0\xBE \xD0\x9E" ) /* о О */ SCRIPT( deva, DEVA, "Devanagari", HB_SCRIPT_DEVANAGARI, - 0x920, 0x935, 0x91F ) /* ठ व ट */ + HINTING_TOP_TO_BOTTOM, + "\xE0\xA4\xA0 \xE0\xA4\xB5 \xE0\xA4\x9F" ) /* ठ व ट */ + + SCRIPT( dsrt, DSRT, + "Deseret", + HB_SCRIPT_DESERET, + HINTING_BOTTOM_TO_TOP, + "\xF0\x90\x90\x84 \xF0\x90\x90\xAC" ) /* 𐐄 𐐬 */ + + SCRIPT( ethi, ETHI, + "Ethiopic", + HB_SCRIPT_ETHIOPIC, + HINTING_BOTTOM_TO_TOP, + "\xE1\x8B\x90" ) /* ዐ */ + + SCRIPT( geor, GEOR, + "Georgian (Mkhedruli)", + HB_SCRIPT_GEORGIAN, + HINTING_BOTTOM_TO_TOP, + "\xE1\x83\x98 \xE1\x83\x94 \xE1\x83\x90 \xE1\xB2\xBF" ) /* ი ე ა Ი */ + + SCRIPT( geok, GEOK, + "Georgian (Khutsuri)", + HB_SCRIPT_INVALID, + HINTING_BOTTOM_TO_TOP, + "\xE1\x82\xB6 \xE1\x82\xB1 \xE2\xB4\x99" ) /* Ⴖ Ⴑ ⴙ */ + + SCRIPT( glag, GLAG, + "Glagolitic", + HB_SCRIPT_GLAGOLITIC, + HINTING_BOTTOM_TO_TOP, + "\xE2\xB0\x95 \xE2\xB1\x85" ) /* Ⱅ ⱅ */ + + SCRIPT( goth, GOTH, + "Gothic", + HB_SCRIPT_GOTHIC, + HINTING_TOP_TO_BOTTOM, + "\xF0\x90\x8C\xB4 \xF0\x90\x8C\xBE \xF0\x90\x8D\x83" ) /* 𐌴 𐌾 𐍃 */ SCRIPT( grek, GREK, "Greek", HB_SCRIPT_GREEK, - 0x3BF, 0x39F, 0x0 ) /* ο Ο */ + HINTING_BOTTOM_TO_TOP, + "\xCE\xBF \xCE\x9F" ) /* ο Ο */ + + SCRIPT( gujr, GUJR, + "Gujarati", + HB_SCRIPT_GUJARATI, + HINTING_BOTTOM_TO_TOP, + "\xE0\xAA\x9F \xE0\xAB\xA6" ) /* ટ ૦ */ + + SCRIPT( guru, GURU, + "Gurmukhi", + HB_SCRIPT_GURMUKHI, + HINTING_TOP_TO_BOTTOM, + "\xE0\xA8\xA0 \xE0\xA8\xB0 \xE0\xA9\xA6" ) /* ਠ ਰ ੦ */ SCRIPT( hebr, HEBR, "Hebrew", HB_SCRIPT_HEBREW, - 0x5DD, 0x0, 0x0 ) /* ם */ + HINTING_BOTTOM_TO_TOP, + "\xD7\x9D" ) /* ם */ + + SCRIPT( kali, KALI, + "Kayah Li", + HB_SCRIPT_KAYAH_LI, + HINTING_BOTTOM_TO_TOP, + "\xEA\xA4\x8D \xEA\xA4\x80" ) /* ꤍ ꤀ */ + + /* only digit zero has a simple shape in the Khmer script */ + SCRIPT( khmr, KHMR, + "Khmer", + HB_SCRIPT_KHMER, + HINTING_BOTTOM_TO_TOP, + "\xE1\x9F\xA0" ) /* ០ */ + + SCRIPT( khms, KHMS, + "Khmer Symbols", + HB_SCRIPT_INVALID, + HINTING_BOTTOM_TO_TOP, + "\xE1\xA7\xA1 \xE1\xA7\xAA" ) /* ᧡ ᧪ */ + + SCRIPT( knda, KNDA, + "Kannada", + HB_SCRIPT_KANNADA, + HINTING_BOTTOM_TO_TOP, + "\xE0\xB3\xA6 \xE0\xB2\xAC" ) /* ೦ ಬ */ /* only digit zero has a simple shape in the Lao script */ SCRIPT( lao, LAO, "Lao", HB_SCRIPT_LAO, - 0xED0, 0x0, 0x0 ) /* ໐ */ + HINTING_BOTTOM_TO_TOP, + "\xE0\xBB\x90" ) /* ໐ */ SCRIPT( latn, LATN, "Latin", HB_SCRIPT_LATIN, - 'o', 'O', '0' ) + HINTING_BOTTOM_TO_TOP, + "o O 0" ) SCRIPT( latb, LATB, "Latin Subscript Fallback", HB_SCRIPT_INVALID, - 0x2092, 0x2080, 0x0 ) /* ₒ ₀ */ + HINTING_BOTTOM_TO_TOP, + "\xE2\x82\x92 \xE2\x82\x80" ) /* ₒ ₀ */ SCRIPT( latp, LATP, "Latin Superscript Fallback", HB_SCRIPT_INVALID, - 0x1D52, 0x1D3C, 0x2070 ) /* ᵒ ᴼ ⁰ */ + HINTING_BOTTOM_TO_TOP, + "\xE1\xB5\x92 \xE1\xB4\xBC \xE2\x81\xB0" ) /* ᵒ ᴼ ⁰ */ + + SCRIPT( lisu, LISU, + "Lisu", + HB_SCRIPT_LISU, + HINTING_BOTTOM_TO_TOP, + "\xEA\x93\xB3" ) /* ꓳ */ + + SCRIPT( mlym, MLYM, + "Malayalam", + HB_SCRIPT_MALAYALAM, + HINTING_BOTTOM_TO_TOP, + "\xE0\xB4\xA0 \xE0\xB4\xB1" ) /* ഠ റ */ + + SCRIPT( mymr, MYMR, + "Myanmar", + HB_SCRIPT_MYANMAR, + HINTING_BOTTOM_TO_TOP, + "\xE1\x80\x9D \xE1\x80\x84 \xE1\x80\x82" ) /* ဝ င ဂ */ + + SCRIPT( nkoo, NKOO, + "N'Ko", + HB_SCRIPT_NKO, + HINTING_BOTTOM_TO_TOP, + "\xDF\x8B \xDF\x80" ) /* ߋ ߀ */ SCRIPT( none, NONE, "no script", HB_SCRIPT_INVALID, - 0x0, 0x0, 0x0 ) + HINTING_BOTTOM_TO_TOP, + "" ) + + SCRIPT( olck, OLCK, + "Ol Chiki", + HB_SCRIPT_OL_CHIKI, + HINTING_BOTTOM_TO_TOP, + "\xE1\xB1\x9B" ) /* ᱛ */ + + SCRIPT( orkh, ORKH, + "Old Turkic", + HB_SCRIPT_OLD_TURKIC, + HINTING_BOTTOM_TO_TOP, + "\xF0\x90\xB0\x97" ) /* 𐰗 */ + + SCRIPT( osge, OSGE, + "Osage", + HB_SCRIPT_OSAGE, + HINTING_BOTTOM_TO_TOP, + "\xF0\x90\x93\x82 \xF0\x90\x93\xAA" ) /* 𐓂 𐓪 */ + + SCRIPT( osma, OSMA, + "Osmanya", + HB_SCRIPT_OSMANYA, + HINTING_BOTTOM_TO_TOP, + "\xF0\x90\x92\x86 \xF0\x90\x92\xA0" ) /* 𐒆 𐒠 */ + + SCRIPT( saur, SAUR, + "Saurashtra", + HB_SCRIPT_SAURASHTRA, + HINTING_BOTTOM_TO_TOP, + "\xEA\xA2\x9D \xEA\xA3\x90" ) /* ꢝ ꣐ */ + + SCRIPT( shaw, SHAW, + "Shavian", + HB_SCRIPT_SHAVIAN, + HINTING_BOTTOM_TO_TOP, + "\xF0\x90\x91\xB4" ) /* 𐑴 */ + + SCRIPT( sinh, SINH, + "Sinhala", + HB_SCRIPT_SINHALA, + HINTING_BOTTOM_TO_TOP, + "\xE0\xB6\xA7" ) /* ට */ + + /* only digit zero has a simple (round) shape in the Sundanese script */ + SCRIPT( sund, SUND, + "Sundanese", + HB_SCRIPT_SUNDANESE, + HINTING_BOTTOM_TO_TOP, + "\xE1\xAE\xB0" ) /* ᮰ */ + + /* only digit zero has a simple (round) shape in the Tamil script */ + SCRIPT( taml, TAML, + "Tamil", + HB_SCRIPT_TAMIL, + HINTING_BOTTOM_TO_TOP, + "\xE0\xAF\xA6" ) /* ௦ */ + + SCRIPT( tavt, TAVT, + "Tai Viet", + HB_SCRIPT_TAI_VIET, + HINTING_BOTTOM_TO_TOP, + "\xEA\xAA\x92 \xEA\xAA\xAB" ) /* ꪒ ꪫ */ /* there are no simple forms for letters; we thus use two digit shapes */ SCRIPT( telu, TELU, "Telugu", HB_SCRIPT_TELUGU, - 0xC66, 0xC67, 0x0 ) /* ౦ ౧ */ + HINTING_BOTTOM_TO_TOP, + "\xE0\xB1\xA6 \xE0\xB1\xA7" ) /* ౦ ౧ */ + + SCRIPT( tfng, TFNG, + "Tifinagh", + HB_SCRIPT_TIFINAGH, + HINTING_BOTTOM_TO_TOP, + "\xE2\xB5\x94" ) /* ⵔ */ SCRIPT( thai, THAI, "Thai", HB_SCRIPT_THAI, - 0xE32, 0xE45, 0xE50 ) /* า ๅ ๐ */ + HINTING_BOTTOM_TO_TOP, + "\xE0\xB8\xB2 \xE0\xB9\x85 \xE0\xB9\x90" ) /* า ๅ ๐ */ + + SCRIPT( vaii, VAII, + "Vai", + HB_SCRIPT_VAI, + HINTING_BOTTOM_TO_TOP, + "\xEA\x98\x93 \xEA\x96\x9C \xEA\x96\xB4" ) /* ꘓ ꖜ ꖴ */ #ifdef AF_CONFIG_OPTION_INDIC - SCRIPT( beng, BENG, - "Bengali", - HB_SCRIPT_BENGALI, - 'o', 0x0, 0x0 ) /* XXX */ - - SCRIPT( gujr, GUJR, - "Gujarati", - HB_SCRIPT_GUJARATI, - 'o', 0x0, 0x0 ) /* XXX */ - - SCRIPT( guru, GURU, - "Gurmukhi", - HB_SCRIPT_GURMUKHI, - 'o', 0x0, 0x0 ) /* XXX */ - - SCRIPT( knda, KNDA, - "Kannada", - HB_SCRIPT_KANNADA, - 'o', 0x0, 0x0 ) /* XXX */ - SCRIPT( limb, LIMB, "Limbu", HB_SCRIPT_LIMBU, - 'o', 0x0, 0x0 ) /* XXX */ - - SCRIPT( mlym, MLYM, - "Malayalam", - HB_SCRIPT_MALAYALAM, - 'o', 0x0, 0x0 ) /* XXX */ + HINTING_BOTTOM_TO_TOP, + "o" ) /* XXX */ SCRIPT( orya, ORYA, "Oriya", HB_SCRIPT_ORIYA, - 'o', 0x0, 0x0 ) /* XXX */ - - SCRIPT( sinh, SINH, - "Sinhala", - HB_SCRIPT_SINHALA, - 'o', 0x0, 0x0 ) /* XXX */ - - SCRIPT( sund, SUND, - "Sundanese", - HB_SCRIPT_SUNDANESE, - 'o', 0x0, 0x0 ) /* XXX */ + HINTING_BOTTOM_TO_TOP, + "o" ) /* XXX */ SCRIPT( sylo, SYLO, "Syloti Nagri", HB_SCRIPT_SYLOTI_NAGRI, - 'o', 0x0, 0x0 ) /* XXX */ - - SCRIPT( taml, TAML, - "Tamil", - HB_SCRIPT_TAMIL, - 'o', 0x0, 0x0 ) /* XXX */ + HINTING_BOTTOM_TO_TOP, + "o" ) /* XXX */ SCRIPT( tibt, TIBT, "Tibetan", HB_SCRIPT_TIBETAN, - 'o', 0x0, 0x0 ) /* XXX */ + HINTING_BOTTOM_TO_TOP, + "o" ) /* XXX */ #endif /* AF_CONFIG_OPTION_INDIC */ @@ -161,7 +381,8 @@ SCRIPT( hani, HANI, "CJKV ideographs", HB_SCRIPT_HAN, - 0x7530, 0x56D7, 0x0 ) /* 田囗 */ + HINTING_BOTTOM_TO_TOP, + "\xE7\x94\xB0 \xE5\x9B\x97" ) /* 田 囗 */ #endif /* AF_CONFIG_OPTION_CJK */ diff --git a/src/3rdparty/freetype/src/autofit/afshaper.c b/src/3rdparty/freetype/src/autofit/afshaper.c new file mode 100644 index 0000000000..f30828173c --- /dev/null +++ b/src/3rdparty/freetype/src/autofit/afshaper.c @@ -0,0 +1,683 @@ +/***************************************************************************/ +/* */ +/* afshaper.c */ +/* */ +/* HarfBuzz interface for accessing OpenType features (body). */ +/* */ +/* Copyright 2013-2018 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_ADVANCES_H +#include "afglobal.h" +#include "aftypes.h" +#include "afshaper.h" + +#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_afshaper + + + /* + * We use `sets' (in the HarfBuzz sense, which comes quite near to the + * usual mathematical meaning) to manage both lookups and glyph indices. + * + * 1. For each coverage, collect lookup IDs in a set. Note that an + * auto-hinter `coverage' is represented by one `feature', and a + * feature consists of an arbitrary number of (font specific) `lookup's + * that actually do the mapping job. Please check the OpenType + * specification for more details on features and lookups. + * + * 2. Create glyph ID sets from the corresponding lookup sets. + * + * 3. The glyph set corresponding to AF_COVERAGE_DEFAULT is computed + * with all lookups specific to the OpenType script activated. It + * relies on the order of AF_DEFINE_STYLE_CLASS entries so that + * special coverages (like `oldstyle figures') don't get overwritten. + * + */ + + + /* load coverage tags */ +#undef COVERAGE +#define COVERAGE( name, NAME, description, \ + tag1, tag2, tag3, tag4 ) \ + static const hb_tag_t name ## _coverage[] = \ + { \ + HB_TAG( tag1, tag2, tag3, tag4 ), \ + HB_TAG_NONE \ + }; + + +#include "afcover.h" + + + /* define mapping between coverage tags and AF_Coverage */ +#undef COVERAGE +#define COVERAGE( name, NAME, description, \ + tag1, tag2, tag3, tag4 ) \ + name ## _coverage, + + + static const hb_tag_t* coverages[] = + { +#include "afcover.h" + + NULL /* AF_COVERAGE_DEFAULT */ + }; + + + /* load HarfBuzz script tags */ +#undef SCRIPT +#define SCRIPT( s, S, d, h, H, ss ) h, + + + static const hb_script_t scripts[] = + { +#include "afscript.h" + }; + + + FT_Error + af_shaper_get_coverage( AF_FaceGlobals globals, + AF_StyleClass style_class, + FT_UShort* gstyles, + FT_Bool default_script ) + { + hb_face_t* face; + + hb_set_t* gsub_lookups = NULL; /* GSUB lookups for a given script */ + hb_set_t* gsub_glyphs = NULL; /* glyphs covered by GSUB lookups */ + hb_set_t* gpos_lookups = NULL; /* GPOS lookups for a given script */ + hb_set_t* gpos_glyphs = NULL; /* glyphs covered by GPOS lookups */ + + hb_script_t script; + const hb_tag_t* coverage_tags; + hb_tag_t script_tags[] = { HB_TAG_NONE, + HB_TAG_NONE, + HB_TAG_NONE, + HB_TAG_NONE }; + + hb_codepoint_t idx; +#ifdef FT_DEBUG_LEVEL_TRACE + int count; +#endif + + + if ( !globals || !style_class || !gstyles ) + return FT_THROW( Invalid_Argument ); + + face = hb_font_get_face( globals->hb_font ); + + coverage_tags = coverages[style_class->coverage]; + script = scripts[style_class->script]; + + /* Convert a HarfBuzz script tag into the corresponding OpenType */ + /* tag or tags -- some Indic scripts like Devanagari have an old */ + /* and a new set of features. */ + hb_ot_tags_from_script( script, + &script_tags[0], + &script_tags[1] ); + + /* `hb_ot_tags_from_script' usually returns HB_OT_TAG_DEFAULT_SCRIPT */ + /* as the second tag. We change that to HB_TAG_NONE except for the */ + /* default script. */ + if ( default_script ) + { + if ( script_tags[0] == HB_TAG_NONE ) + script_tags[0] = HB_OT_TAG_DEFAULT_SCRIPT; + else + { + if ( script_tags[1] == HB_TAG_NONE ) + script_tags[1] = HB_OT_TAG_DEFAULT_SCRIPT; + else if ( script_tags[1] != HB_OT_TAG_DEFAULT_SCRIPT ) + script_tags[2] = HB_OT_TAG_DEFAULT_SCRIPT; + } + } + else + { + /* we use non-standard tags like `khms' for special purposes; */ + /* HarfBuzz maps them to `DFLT', which we don't want to handle here */ + if ( script_tags[0] == HB_OT_TAG_DEFAULT_SCRIPT ) + goto Exit; + + if ( script_tags[1] == HB_OT_TAG_DEFAULT_SCRIPT ) + script_tags[1] = HB_TAG_NONE; + } + + gsub_lookups = hb_set_create(); + hb_ot_layout_collect_lookups( face, + HB_OT_TAG_GSUB, + script_tags, + NULL, + coverage_tags, + gsub_lookups ); + + if ( hb_set_is_empty( gsub_lookups ) ) + goto Exit; /* nothing to do */ + + FT_TRACE4(( "GSUB lookups (style `%s'):\n" + " ", + af_style_names[style_class->style] )); + +#ifdef FT_DEBUG_LEVEL_TRACE + count = 0; +#endif + + gsub_glyphs = hb_set_create(); + for ( idx = HB_SET_VALUE_INVALID; hb_set_next( gsub_lookups, &idx ); ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE4(( " %d", idx )); + count++; +#endif + + /* get output coverage of GSUB feature */ + hb_ot_layout_lookup_collect_glyphs( face, + HB_OT_TAG_GSUB, + idx, + NULL, + NULL, + NULL, + gsub_glyphs ); + } + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !count ) + FT_TRACE4(( " (none)" )); + FT_TRACE4(( "\n\n" )); +#endif + + FT_TRACE4(( "GPOS lookups (style `%s'):\n" + " ", + af_style_names[style_class->style] )); + + gpos_lookups = hb_set_create(); + hb_ot_layout_collect_lookups( face, + HB_OT_TAG_GPOS, + script_tags, + NULL, + coverage_tags, + gpos_lookups ); + +#ifdef FT_DEBUG_LEVEL_TRACE + count = 0; +#endif + + gpos_glyphs = hb_set_create(); + for ( idx = HB_SET_VALUE_INVALID; hb_set_next( gpos_lookups, &idx ); ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE4(( " %d", idx )); + count++; +#endif + + /* get input coverage of GPOS feature */ + hb_ot_layout_lookup_collect_glyphs( face, + HB_OT_TAG_GPOS, + idx, + NULL, + gpos_glyphs, + NULL, + NULL ); + } + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !count ) + FT_TRACE4(( " (none)" )); + FT_TRACE4(( "\n\n" )); +#endif + + /* + * We now check whether we can construct blue zones, using glyphs + * covered by the feature only. In case there is not a single zone + * (this is, not a single character is covered), we skip this coverage. + * + */ + if ( style_class->coverage != AF_COVERAGE_DEFAULT ) + { + AF_Blue_Stringset bss = style_class->blue_stringset; + const AF_Blue_StringRec* bs = &af_blue_stringsets[bss]; + + FT_Bool found = 0; + + + for ( ; bs->string != AF_BLUE_STRING_MAX; bs++ ) + { + const char* p = &af_blue_strings[bs->string]; + + + while ( *p ) + { + hb_codepoint_t ch; + + + GET_UTF8_CHAR( ch, p ); + + for ( idx = HB_SET_VALUE_INVALID; hb_set_next( gsub_lookups, + &idx ); ) + { + hb_codepoint_t gidx = FT_Get_Char_Index( globals->face, ch ); + + + if ( hb_ot_layout_lookup_would_substitute( face, idx, + &gidx, 1, 1 ) ) + { + found = 1; + break; + } + } + } + } + + if ( !found ) + { + FT_TRACE4(( " no blue characters found; style skipped\n" )); + goto Exit; + } + } + + /* + * Various OpenType features might use the same glyphs at different + * vertical positions; for example, superscript and subscript glyphs + * could be the same. However, the auto-hinter is completely + * agnostic of OpenType features after the feature analysis has been + * completed: The engine then simply receives a glyph index and returns a + * hinted and usually rendered glyph. + * + * Consider the superscript feature of font `pala.ttf': Some of the + * glyphs are `real', this is, they have a zero vertical offset, but + * most of them are small caps glyphs shifted up to the superscript + * position (this is, the `sups' feature is present in both the GSUB and + * GPOS tables). The code for blue zones computation actually uses a + * feature's y offset so that the `real' glyphs get correct hints. But + * later on it is impossible to decide whether a glyph index belongs to, + * say, the small caps or superscript feature. + * + * For this reason, we don't assign a style to a glyph if the current + * feature covers the glyph in both the GSUB and the GPOS tables. This + * is quite a broad condition, assuming that + * + * (a) glyphs that get used in multiple features are present in a + * feature without vertical shift, + * + * and + * + * (b) a feature's GPOS data really moves the glyph vertically. + * + * Not fulfilling condition (a) makes a font larger; it would also + * reduce the number of glyphs that could be addressed directly without + * using OpenType features, so this assumption is rather strong. + * + * Condition (b) is much weaker, and there might be glyphs which get + * missed. However, the OpenType features we are going to handle are + * primarily located in GSUB, and HarfBuzz doesn't provide an API to + * directly get the necessary information from the GPOS table. A + * possible solution might be to directly parse the GPOS table to find + * out whether a glyph gets shifted vertically, but this is something I + * would like to avoid if not really necessary. + * + * Note that we don't follow this logic for the default coverage. + * Complex scripts like Devanagari have mandatory GPOS features to + * position many glyph elements, using mark-to-base or mark-to-ligature + * tables; the number of glyphs missed due to condition (b) would be far + * too large. + * + */ + if ( style_class->coverage != AF_COVERAGE_DEFAULT ) + hb_set_subtract( gsub_glyphs, gpos_glyphs ); + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE4(( " glyphs without GPOS data (`*' means already assigned)" )); + count = 0; +#endif + + for ( idx = HB_SET_VALUE_INVALID; hb_set_next( gsub_glyphs, &idx ); ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !( count % 10 ) ) + FT_TRACE4(( "\n" + " " )); + + FT_TRACE4(( " %d", idx )); + count++; +#endif + + /* glyph indices returned by `hb_ot_layout_lookup_collect_glyphs' */ + /* can be arbitrary: some fonts use fake indices for processing */ + /* internal to GSUB or GPOS, which is fully valid */ + if ( idx >= (hb_codepoint_t)globals->glyph_count ) + continue; + + if ( gstyles[idx] == AF_STYLE_UNASSIGNED ) + gstyles[idx] = (FT_UShort)style_class->style; +#ifdef FT_DEBUG_LEVEL_TRACE + else + FT_TRACE4(( "*" )); +#endif + } + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !count ) + FT_TRACE4(( "\n" + " (none)" )); + FT_TRACE4(( "\n\n" )); +#endif + + Exit: + hb_set_destroy( gsub_lookups ); + hb_set_destroy( gsub_glyphs ); + hb_set_destroy( gpos_lookups ); + hb_set_destroy( gpos_glyphs ); + + return FT_Err_Ok; + } + + + /* construct HarfBuzz features */ +#undef COVERAGE +#define COVERAGE( name, NAME, description, \ + tag1, tag2, tag3, tag4 ) \ + static const hb_feature_t name ## _feature[] = \ + { \ + { \ + HB_TAG( tag1, tag2, tag3, tag4 ), \ + 1, 0, (unsigned int)-1 \ + } \ + }; + + +#include "afcover.h" + + + /* define mapping between HarfBuzz features and AF_Coverage */ +#undef COVERAGE +#define COVERAGE( name, NAME, description, \ + tag1, tag2, tag3, tag4 ) \ + name ## _feature, + + + static const hb_feature_t* features[] = + { +#include "afcover.h" + + NULL /* AF_COVERAGE_DEFAULT */ + }; + + + void* + af_shaper_buf_create( FT_Face face ) + { + FT_UNUSED( face ); + + return (void*)hb_buffer_create(); + } + + + void + af_shaper_buf_destroy( FT_Face face, + void* buf ) + { + FT_UNUSED( face ); + + hb_buffer_destroy( (hb_buffer_t*)buf ); + } + + + const char* + af_shaper_get_cluster( const char* p, + AF_StyleMetrics metrics, + void* buf_, + unsigned int* count ) + { + AF_StyleClass style_class; + const hb_feature_t* feature; + FT_Int upem; + const char* q; + int len; + + hb_buffer_t* buf = (hb_buffer_t*)buf_; + hb_font_t* font; + hb_codepoint_t dummy; + + + upem = (FT_Int)metrics->globals->face->units_per_EM; + style_class = metrics->style_class; + feature = features[style_class->coverage]; + + font = metrics->globals->hb_font; + + /* we shape at a size of units per EM; this means font units */ + hb_font_set_scale( font, upem, upem ); + + while ( *p == ' ' ) + p++; + + /* count bytes up to next space (or end of buffer) */ + q = p; + while ( !( *q == ' ' || *q == '\0' ) ) + GET_UTF8_CHAR( dummy, q ); + len = (int)( q - p ); + + /* feed character(s) to the HarfBuzz buffer */ + hb_buffer_clear_contents( buf ); + hb_buffer_add_utf8( buf, p, len, 0, len ); + + /* we let HarfBuzz guess the script and writing direction */ + hb_buffer_guess_segment_properties( buf ); + + /* shape buffer, which means conversion from character codes to */ + /* glyph indices, possibly applying a feature */ + hb_shape( font, buf, feature, feature ? 1 : 0 ); + + if ( feature ) + { + hb_buffer_t* hb_buf = metrics->globals->hb_buf; + + unsigned int gcount; + hb_glyph_info_t* ginfo; + + unsigned int hb_gcount; + hb_glyph_info_t* hb_ginfo; + + + /* we have to check whether applying a feature does actually change */ + /* glyph indices; otherwise the affected glyph or glyphs aren't */ + /* available at all in the feature */ + + hb_buffer_clear_contents( hb_buf ); + hb_buffer_add_utf8( hb_buf, p, len, 0, len ); + hb_buffer_guess_segment_properties( hb_buf ); + hb_shape( font, hb_buf, NULL, 0 ); + + ginfo = hb_buffer_get_glyph_infos( buf, &gcount ); + hb_ginfo = hb_buffer_get_glyph_infos( hb_buf, &hb_gcount ); + + if ( gcount == hb_gcount ) + { + unsigned int i; + + + for (i = 0; i < gcount; i++ ) + if ( ginfo[i].codepoint != hb_ginfo[i].codepoint ) + break; + + if ( i == gcount ) + { + /* both buffers have identical glyph indices */ + hb_buffer_clear_contents( buf ); + } + } + } + + *count = hb_buffer_get_length( buf ); + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( feature && *count > 1 ) + FT_TRACE1(( "af_shaper_get_cluster:" + " input character mapped to multiple glyphs\n" )); +#endif + + return q; + } + + + FT_ULong + af_shaper_get_elem( AF_StyleMetrics metrics, + void* buf_, + unsigned int idx, + FT_Long* advance, + FT_Long* y_offset ) + { + hb_buffer_t* buf = (hb_buffer_t*)buf_; + hb_glyph_info_t* ginfo; + hb_glyph_position_t* gpos; + unsigned int gcount; + + FT_UNUSED( metrics ); + + + ginfo = hb_buffer_get_glyph_infos( buf, &gcount ); + gpos = hb_buffer_get_glyph_positions( buf, &gcount ); + + if ( idx >= gcount ) + return 0; + + if ( advance ) + *advance = gpos[idx].x_advance; + if ( y_offset ) + *y_offset = gpos[idx].y_offset; + + return ginfo[idx].codepoint; + } + + +#else /* !FT_CONFIG_OPTION_USE_HARFBUZZ */ + + + FT_Error + af_shaper_get_coverage( AF_FaceGlobals globals, + AF_StyleClass style_class, + FT_UShort* gstyles, + FT_Bool default_script ) + { + FT_UNUSED( globals ); + FT_UNUSED( style_class ); + FT_UNUSED( gstyles ); + FT_UNUSED( default_script ); + + return FT_Err_Ok; + } + + + void* + af_shaper_buf_create( FT_Face face ) + { + FT_Error error; + FT_Memory memory = face->memory; + FT_ULong* buf; + + + FT_MEM_ALLOC( buf, sizeof ( FT_ULong ) ); + + return (void*)buf; + } + + + void + af_shaper_buf_destroy( FT_Face face, + void* buf ) + { + FT_Memory memory = face->memory; + + + FT_FREE( buf ); + } + + + const char* + af_shaper_get_cluster( const char* p, + AF_StyleMetrics metrics, + void* buf_, + unsigned int* count ) + { + FT_Face face = metrics->globals->face; + FT_ULong ch, dummy = 0; + FT_ULong* buf = (FT_ULong*)buf_; + + + while ( *p == ' ' ) + p++; + + GET_UTF8_CHAR( ch, p ); + + /* since we don't have an engine to handle clusters, */ + /* we scan the characters but return zero */ + while ( !( *p == ' ' || *p == '\0' ) ) + GET_UTF8_CHAR( dummy, p ); + + if ( dummy ) + { + *buf = 0; + *count = 0; + } + else + { + *buf = FT_Get_Char_Index( face, ch ); + *count = 1; + } + + return p; + } + + + FT_ULong + af_shaper_get_elem( AF_StyleMetrics metrics, + void* buf_, + unsigned int idx, + FT_Long* advance, + FT_Long* y_offset ) + { + FT_Face face = metrics->globals->face; + FT_ULong glyph_index = *(FT_ULong*)buf_; + + FT_UNUSED( idx ); + + + if ( advance ) + FT_Get_Advance( face, + glyph_index, + FT_LOAD_NO_SCALE | + FT_LOAD_NO_HINTING | + FT_LOAD_IGNORE_TRANSFORM, + advance ); + + if ( y_offset ) + *y_offset = 0; + + return glyph_index; + } + + +#endif /* !FT_CONFIG_OPTION_USE_HARFBUZZ */ + + +/* END */ diff --git a/src/3rdparty/freetype/src/autofit/afshaper.h b/src/3rdparty/freetype/src/autofit/afshaper.h new file mode 100644 index 0000000000..7efd9f6a4e --- /dev/null +++ b/src/3rdparty/freetype/src/autofit/afshaper.h @@ -0,0 +1,72 @@ +/***************************************************************************/ +/* */ +/* afshaper.h */ +/* */ +/* HarfBuzz interface for accessing OpenType features (specification). */ +/* */ +/* Copyright 2013-2018 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef AFSHAPER_H_ +#define AFSHAPER_H_ + + +#include <ft2build.h> +#include FT_FREETYPE_H + + +#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ + +#include <hb.h> +#include <hb-ot.h> +#include <hb-ft.h> + +#endif + + +FT_BEGIN_HEADER + + FT_Error + af_shaper_get_coverage( AF_FaceGlobals globals, + AF_StyleClass style_class, + FT_UShort* gstyles, + FT_Bool default_script ); + + + void* + af_shaper_buf_create( FT_Face face ); + + void + af_shaper_buf_destroy( FT_Face face, + void* buf ); + + const char* + af_shaper_get_cluster( const char* p, + AF_StyleMetrics metrics, + void* buf_, + unsigned int* count ); + + FT_ULong + af_shaper_get_elem( AF_StyleMetrics metrics, + void* buf_, + unsigned int idx, + FT_Long* x_advance, + FT_Long* y_offset ); + + /* */ + +FT_END_HEADER + +#endif /* AFSHAPER_H_ */ + + +/* END */ diff --git a/src/3rdparty/freetype/src/autofit/afstyles.h b/src/3rdparty/freetype/src/autofit/afstyles.h index 87663c9ee7..e2688b3fc2 100644 --- a/src/3rdparty/freetype/src/autofit/afstyles.h +++ b/src/3rdparty/freetype/src/autofit/afstyles.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter styles (specification only). */ /* */ -/* Copyright 2013-2015 by */ +/* Copyright 2013-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -52,10 +52,10 @@ #undef META_STYLE_LATIN #define META_STYLE_LATIN( s, S, ds ) \ STYLE_LATIN( s, S, c2cp, C2CP, ds, \ - "petite capticals from capitals", \ + "petite capitals from capitals", \ PETITE_CAPITALS_FROM_CAPITALS ) \ STYLE_LATIN( s, S, c2sc, C2SC, ds, \ - "small capticals from capitals", \ + "small capitals from capitals", \ SMALL_CAPITALS_FROM_CAPITALS ) \ STYLE_LATIN( s, S, ordn, ORDN, ds, \ "ordinals", \ @@ -83,6 +83,13 @@ DEFAULT ) + STYLE( adlm_dflt, ADLM_DFLT, + "Adlam default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_ADLM, + AF_BLUE_STRINGSET_ADLM, + AF_COVERAGE_DEFAULT ) + STYLE( arab_dflt, ARAB_DFLT, "Arabic default style", AF_WRITING_SYSTEM_LATIN, @@ -90,6 +97,83 @@ AF_BLUE_STRINGSET_ARAB, AF_COVERAGE_DEFAULT ) + STYLE( armn_dflt, ARMN_DFLT, + "Armenian default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_ARMN, + AF_BLUE_STRINGSET_ARMN, + AF_COVERAGE_DEFAULT ) + + STYLE( avst_dflt, AVST_DFLT, + "Avestan default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_AVST, + AF_BLUE_STRINGSET_AVST, + AF_COVERAGE_DEFAULT ) + + STYLE( bamu_dflt, BAMU_DFLT, + "Bamum default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_BAMU, + AF_BLUE_STRINGSET_BAMU, + AF_COVERAGE_DEFAULT ) + + STYLE( beng_dflt, BENG_DFLT, + "Bengali default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_BENG, + AF_BLUE_STRINGSET_BENG, + AF_COVERAGE_DEFAULT ) + + STYLE( buhd_dflt, BUHD_DFLT, + "Buhid default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_BUHD, + AF_BLUE_STRINGSET_BUHD, + AF_COVERAGE_DEFAULT ) + + STYLE( cakm_dflt, CAKM_DFLT, + "Chakma default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_CAKM, + AF_BLUE_STRINGSET_CAKM, + AF_COVERAGE_DEFAULT ) + + STYLE( cans_dflt, CANS_DFLT, + "Canadian Syllabics default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_CANS, + AF_BLUE_STRINGSET_CANS, + AF_COVERAGE_DEFAULT ) + + STYLE( cari_dflt, CARI_DFLT, + "Carian default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_CARI, + AF_BLUE_STRINGSET_CARI, + AF_COVERAGE_DEFAULT ) + + STYLE( cher_dflt, CHER_DFLT, + "Cherokee default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_CHER, + AF_BLUE_STRINGSET_CHER, + AF_COVERAGE_DEFAULT ) + + STYLE( copt_dflt, COPT_DFLT, + "Coptic default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_COPT, + AF_BLUE_STRINGSET_COPT, + AF_COVERAGE_DEFAULT ) + + STYLE( cprt_dflt, CPRT_DFLT, + "Cypriot default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_CPRT, + AF_BLUE_STRINGSET_CPRT, + AF_COVERAGE_DEFAULT ) + META_STYLE_LATIN( cyrl, CYRL, "Cyrillic" ) STYLE( deva_dflt, DEVA_DFLT, @@ -99,8 +183,64 @@ AF_BLUE_STRINGSET_DEVA, AF_COVERAGE_DEFAULT ) + STYLE( dsrt_dflt, DSRT_DFLT, + "Deseret default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_DSRT, + AF_BLUE_STRINGSET_DSRT, + AF_COVERAGE_DEFAULT ) + + STYLE( ethi_dflt, ETHI_DFLT, + "Ethiopic default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_ETHI, + AF_BLUE_STRINGSET_ETHI, + AF_COVERAGE_DEFAULT ) + + STYLE( geor_dflt, GEOR_DFLT, + "Georgian (Mkhedruli) default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_GEOR, + AF_BLUE_STRINGSET_GEOR, + AF_COVERAGE_DEFAULT ) + + STYLE( geok_dflt, GEOK_DFLT, + "Georgian (Khutsuri) default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_GEOK, + AF_BLUE_STRINGSET_GEOK, + AF_COVERAGE_DEFAULT ) + + STYLE( glag_dflt, GLAG_DFLT, + "Glagolitic default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_GLAG, + AF_BLUE_STRINGSET_GLAG, + AF_COVERAGE_DEFAULT ) + + STYLE( goth_dflt, GOTH_DFLT, + "Gothic default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_GOTH, + AF_BLUE_STRINGSET_GOTH, + AF_COVERAGE_DEFAULT ) + META_STYLE_LATIN( grek, GREK, "Greek" ) + STYLE( gujr_dflt, GUJR_DFLT, + "Gujarati default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_GUJR, + AF_BLUE_STRINGSET_GUJR, + AF_COVERAGE_DEFAULT ) + + STYLE( guru_dflt, GURU_DFLT, + "Gurmukhi default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_GURU, + AF_BLUE_STRINGSET_GURU, + AF_COVERAGE_DEFAULT ) + STYLE( hebr_dflt, HEBR_DFLT, "Hebrew default style", AF_WRITING_SYSTEM_LATIN, @@ -108,6 +248,34 @@ AF_BLUE_STRINGSET_HEBR, AF_COVERAGE_DEFAULT ) + STYLE( kali_dflt, KALI_DFLT, + "Kayah Li default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_KALI, + AF_BLUE_STRINGSET_KALI, + AF_COVERAGE_DEFAULT ) + + STYLE( khmr_dflt, KHMR_DFLT, + "Khmer default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_KHMR, + AF_BLUE_STRINGSET_KHMR, + AF_COVERAGE_DEFAULT ) + + STYLE( khms_dflt, KHMS_DFLT, + "Khmer Symbols default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_KHMS, + AF_BLUE_STRINGSET_KHMS, + AF_COVERAGE_DEFAULT ) + + STYLE( knda_dflt, KNDA_DFLT, + "Kannada default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_KNDA, + AF_BLUE_STRINGSET_KNDA, + AF_COVERAGE_DEFAULT ) + STYLE( lao_dflt, LAO_DFLT, "Lao default style", AF_WRITING_SYSTEM_LATIN, @@ -140,11 +308,109 @@ AF_COVERAGE_DEFAULT ) #endif + STYLE( lisu_dflt, LISU_DFLT, + "Lisu default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_LISU, + AF_BLUE_STRINGSET_LISU, + AF_COVERAGE_DEFAULT ) + + STYLE( mlym_dflt, MLYM_DFLT, + "Malayalam default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_MLYM, + AF_BLUE_STRINGSET_MLYM, + AF_COVERAGE_DEFAULT ) + + STYLE( mymr_dflt, MYMR_DFLT, + "Myanmar default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_MYMR, + AF_BLUE_STRINGSET_MYMR, + AF_COVERAGE_DEFAULT ) + + STYLE( nkoo_dflt, NKOO_DFLT, + "N'Ko default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_NKOO, + AF_BLUE_STRINGSET_NKOO, + AF_COVERAGE_DEFAULT ) + STYLE( none_dflt, NONE_DFLT, "no style", AF_WRITING_SYSTEM_DUMMY, AF_SCRIPT_NONE, - (AF_Blue_Stringset)0, + AF_BLUE_STRINGSET_NONE, + AF_COVERAGE_DEFAULT ) + + STYLE( olck_dflt, OLCK_DFLT, + "Ol Chiki default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_OLCK, + AF_BLUE_STRINGSET_OLCK, + AF_COVERAGE_DEFAULT ) + + STYLE( orkh_dflt, ORKH_DFLT, + "Old Turkic default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_ORKH, + AF_BLUE_STRINGSET_ORKH, + AF_COVERAGE_DEFAULT ) + + STYLE( osge_dflt, OSGE_DFLT, + "Osage default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_OSGE, + AF_BLUE_STRINGSET_OSGE, + AF_COVERAGE_DEFAULT ) + + STYLE( osma_dflt, OSMA_DFLT, + "Osmanya default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_OSMA, + AF_BLUE_STRINGSET_OSMA, + AF_COVERAGE_DEFAULT ) + + STYLE( saur_dflt, SAUR_DFLT, + "Saurashtra default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_SAUR, + AF_BLUE_STRINGSET_SAUR, + AF_COVERAGE_DEFAULT ) + + STYLE( shaw_dflt, SHAW_DFLT, + "Shavian default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_SHAW, + AF_BLUE_STRINGSET_SHAW, + AF_COVERAGE_DEFAULT ) + + STYLE( sinh_dflt, SINH_DFLT, + "Sinhala default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_SINH, + AF_BLUE_STRINGSET_SINH, + AF_COVERAGE_DEFAULT ) + + STYLE( sund_dflt, SUND_DFLT, + "Sundanese default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_SUND, + AF_BLUE_STRINGSET_SUND, + AF_COVERAGE_DEFAULT ) + + STYLE( taml_dflt, TAML_DFLT, + "Tamil default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_TAML, + AF_BLUE_STRINGSET_TAML, + AF_COVERAGE_DEFAULT ) + + STYLE( tavt_dflt, TAVT_DFLT, + "Tai Viet default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_TAVT, + AF_BLUE_STRINGSET_TAVT, AF_COVERAGE_DEFAULT ) STYLE( telu_dflt, TELU_DFLT, @@ -154,6 +420,13 @@ AF_BLUE_STRINGSET_TELU, AF_COVERAGE_DEFAULT ) + STYLE( tfng_dflt, TFNG_DFLT, + "Tifinagh default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_TFNG, + AF_BLUE_STRINGSET_TFNG, + AF_COVERAGE_DEFAULT ) + STYLE( thai_dflt, THAI_DFLT, "Thai default style", AF_WRITING_SYSTEM_LATIN, @@ -161,6 +434,13 @@ AF_BLUE_STRINGSET_THAI, AF_COVERAGE_DEFAULT ) + STYLE( vaii_dflt, VAII_DFLT, + "Vai default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_VAII, + AF_BLUE_STRINGSET_VAII, + AF_COVERAGE_DEFAULT ) + #ifdef AF_CONFIG_OPTION_INDIC /* no blue stringset support for the Indic writing system yet */ @@ -173,17 +453,9 @@ (AF_Blue_Stringset)0, \ AF_COVERAGE_DEFAULT ) - STYLE_DEFAULT_INDIC( beng, BENG, "Bengali" ) - STYLE_DEFAULT_INDIC( gujr, GUJR, "Gujarati" ) - STYLE_DEFAULT_INDIC( guru, GURU, "Gurmukhi" ) - STYLE_DEFAULT_INDIC( knda, KNDA, "Kannada" ) STYLE_DEFAULT_INDIC( limb, LIMB, "Limbu" ) - STYLE_DEFAULT_INDIC( mlym, MLYM, "Malayalam" ) STYLE_DEFAULT_INDIC( orya, ORYA, "Oriya" ) - STYLE_DEFAULT_INDIC( sinh, SINH, "Sinhala" ) - STYLE_DEFAULT_INDIC( sund, SUND, "Sundanese" ) STYLE_DEFAULT_INDIC( sylo, SYLO, "Syloti Nagri" ) - STYLE_DEFAULT_INDIC( taml, TAML, "Tamil" ) STYLE_DEFAULT_INDIC( tibt, TIBT, "Tibetan" ) #endif /* AF_CONFIG_OPTION_INDIC */ diff --git a/src/3rdparty/freetype/src/autofit/aftypes.h b/src/3rdparty/freetype/src/autofit/aftypes.h index 43b38006c2..6bd8c895b2 100644 --- a/src/3rdparty/freetype/src/autofit/aftypes.h +++ b/src/3rdparty/freetype/src/autofit/aftypes.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter types (specification only). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,15 +22,15 @@ * Its main feature is the ability to differentiate between different * writing systems and scripts in order to apply specific rules. * - * The code has also been compartmentized into several entities that + * The code has also been compartmentalized into several entities that * should make algorithmic experimentation easier than with the old * code. * *************************************************************************/ -#ifndef __AFTYPES_H__ -#define __AFTYPES_H__ +#ifndef AFTYPES_H_ +#define AFTYPES_H_ #include <ft2build.h> @@ -76,9 +76,9 @@ extern void* _af_debug_hints; typedef struct AF_WidthRec_ { - FT_Pos org; /* original position/width in font units */ - FT_Pos cur; /* current/scaled position/width in device sub-pixels */ - FT_Pos fit; /* current/fitted position/width in device sub-pixels */ + FT_Pos org; /* original position/width in font units */ + FT_Pos cur; /* current/scaled position/width in device subpixels */ + FT_Pos fit; /* current/fitted position/width in device subpixels */ } AF_WidthRec, *AF_Width; @@ -211,12 +211,17 @@ extern void* _af_debug_hints; typedef void (*AF_WritingSystem_DoneMetricsFunc)( AF_StyleMetrics metrics ); + typedef void + (*AF_WritingSystem_GetStdWidthsFunc)( AF_StyleMetrics metrics, + FT_Pos* stdHW, + FT_Pos* stdVW ); + typedef FT_Error (*AF_WritingSystem_InitHintsFunc)( AF_GlyphHints hints, AF_StyleMetrics metrics ); - typedef void + typedef FT_Error (*AF_WritingSystem_ApplyHintsFunc)( FT_UInt glyph_index, AF_GlyphHints hints, FT_Outline* outline, @@ -250,7 +255,7 @@ extern void* _af_debug_hints; * outline according to the results of the glyph analyzer. */ -#define __AFWRTSYS_H__ /* don't load header files */ +#define AFWRTSYS_H_ /* don't load header files */ #undef WRITING_SYSTEM #define WRITING_SYSTEM( ws, WS ) \ AF_WRITING_SYSTEM_ ## WS, @@ -265,7 +270,7 @@ extern void* _af_debug_hints; } AF_WritingSystem; -#undef __AFWRTSYS_H__ +#undef AFWRTSYS_H_ typedef struct AF_WritingSystemClassRec_ @@ -276,6 +281,7 @@ extern void* _af_debug_hints; AF_WritingSystem_InitMetricsFunc style_metrics_init; AF_WritingSystem_ScaleMetricsFunc style_metrics_scale; AF_WritingSystem_DoneMetricsFunc style_metrics_done; + AF_WritingSystem_GetStdWidthsFunc style_metrics_getstdw; AF_WritingSystem_InitHintsFunc style_hints_init; AF_WritingSystem_ApplyHintsFunc style_hints_apply; @@ -303,7 +309,7 @@ extern void* _af_debug_hints; */ #undef SCRIPT -#define SCRIPT( s, S, d, h, sc1, sc2, sc3 ) \ +#define SCRIPT( s, S, d, h, H, ss ) \ AF_SCRIPT_ ## S, /* The list of known scripts. */ @@ -337,9 +343,9 @@ extern void* _af_debug_hints; AF_Script_UniRange script_uni_ranges; AF_Script_UniRange script_uni_nonbase_ranges; - FT_UInt32 standard_char1; /* for default width and height */ - FT_UInt32 standard_char2; /* ditto */ - FT_UInt32 standard_char3; /* ditto */ + FT_Bool top_to_bottom_hinting; + + const char* standard_charstring; /* for default width and height */ } AF_ScriptClassRec; @@ -475,6 +481,10 @@ extern void* _af_debug_hints; } AF_StyleMetricsRec; +#define AF_HINTING_BOTTOM_TO_TOP 0 +#define AF_HINTING_TOP_TO_BOTTOM 1 + + /* Declare and define vtables for classes */ #ifndef FT_CONFIG_OPTION_PIC @@ -489,6 +499,7 @@ extern void* _af_debug_hints; m_init, \ m_scale, \ m_done, \ + m_stdw, \ h_init, \ h_apply ) \ FT_CALLBACK_TABLE_DEF \ @@ -501,6 +512,7 @@ extern void* _af_debug_hints; m_init, \ m_scale, \ m_done, \ + m_stdw, \ \ h_init, \ h_apply \ @@ -516,18 +528,16 @@ extern void* _af_debug_hints; script, \ ranges, \ nonbase_ranges, \ - std_char1, \ - std_char2, \ - std_char3 ) \ + top_to_bottom, \ + std_charstring ) \ FT_CALLBACK_TABLE_DEF \ const AF_ScriptClassRec script_class = \ { \ script, \ ranges, \ nonbase_ranges, \ - std_char1, \ - std_char2, \ - std_char3 \ + top_to_bottom, \ + std_charstring, \ }; @@ -565,21 +575,23 @@ extern void* _af_debug_hints; m_init, \ m_scale, \ m_done, \ + m_stdw, \ h_init, \ h_apply ) \ FT_LOCAL_DEF( void ) \ FT_Init_Class_ ## writing_system_class( AF_WritingSystemClassRec* ac ) \ { \ - ac->writing_system = system; \ + ac->writing_system = system; \ \ - ac->style_metrics_size = m_size; \ + ac->style_metrics_size = m_size; \ \ - ac->style_metrics_init = m_init; \ - ac->style_metrics_scale = m_scale; \ - ac->style_metrics_done = m_done; \ + ac->style_metrics_init = m_init; \ + ac->style_metrics_scale = m_scale; \ + ac->style_metrics_done = m_done; \ + ac->style_metrics_getstdw = m_stdw; \ \ - ac->style_hints_init = h_init; \ - ac->style_hints_apply = h_apply; \ + ac->style_hints_init = h_init; \ + ac->style_hints_apply = h_apply; \ } @@ -592,18 +604,16 @@ extern void* _af_debug_hints; script_, \ ranges, \ nonbase_ranges, \ - std_char1, \ - std_char2, \ - std_char3 ) \ + top_to_bottom, \ + std_charstring ) \ FT_LOCAL_DEF( void ) \ FT_Init_Class_ ## script_class( AF_ScriptClassRec* ac ) \ { \ ac->script = script_; \ ac->script_uni_ranges = ranges; \ ac->script_uni_nonbase_ranges = nonbase_ranges; \ - ac->standard_char1 = std_char1; \ - ac->standard_char2 = std_char2; \ - ac->standard_char3 = std_char3; \ + ac->top_to_bottom_hinting = top_to_bottom; \ + ac->standard_charstring = std_charstring; \ } @@ -635,7 +645,7 @@ extern void* _af_debug_hints; FT_END_HEADER -#endif /* __AFTYPES_H__ */ +#endif /* AFTYPES_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/autofit/afwarp.c b/src/3rdparty/freetype/src/autofit/afwarp.c index 59af4f02bd..2a75ea7b35 100644 --- a/src/3rdparty/freetype/src/autofit/afwarp.c +++ b/src/3rdparty/freetype/src/autofit/afwarp.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter warping algorithm (body). */ /* */ -/* Copyright 2006-2015 by */ +/* Copyright 2006-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -98,7 +98,6 @@ if ( xx1min + w < warper->x2min ) xx1min = warper->x2min - w; - xx1max = warper->x1max; if ( xx1max + w > warper->x2max ) xx1max = warper->x2max - w; @@ -193,7 +192,7 @@ warper->best_scale = org_scale; warper->best_delta = org_delta; - warper->best_score = INT_MIN; + warper->best_score = FT_INT_MIN; warper->best_distort = 0; axis = &hints->axis[dim]; diff --git a/src/3rdparty/freetype/src/autofit/afwarp.h b/src/3rdparty/freetype/src/autofit/afwarp.h index 6069b6b277..520b1be907 100644 --- a/src/3rdparty/freetype/src/autofit/afwarp.h +++ b/src/3rdparty/freetype/src/autofit/afwarp.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter warping algorithm (specification). */ /* */ -/* Copyright 2006-2015 by */ +/* Copyright 2006-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __AFWARP_H__ -#define __AFWARP_H__ +#ifndef AFWARP_H_ +#define AFWARP_H_ #include "afhints.h" @@ -58,7 +58,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __AFWARP_H__ */ +#endif /* AFWARP_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/autofit/afwrtsys.h b/src/3rdparty/freetype/src/autofit/afwrtsys.h index 4aa89d2356..4675f3242d 100644 --- a/src/3rdparty/freetype/src/autofit/afwrtsys.h +++ b/src/3rdparty/freetype/src/autofit/afwrtsys.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter writing systems (specification only). */ /* */ -/* Copyright 2013-2015 by */ +/* Copyright 2013-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __AFWRTSYS_H__ -#define __AFWRTSYS_H__ +#ifndef AFWRTSYS_H_ +#define AFWRTSYS_H_ /* Since preprocessor directives can't create other preprocessor */ /* directives, we have to include the header files manually. */ @@ -30,7 +30,7 @@ #include "aflatin2.h" #endif -#endif /* __AFWRTSYS_H__ */ +#endif /* AFWRTSYS_H_ */ /* The following part can be included multiple times. */ diff --git a/src/3rdparty/freetype/src/autofit/autofit.c b/src/3rdparty/freetype/src/autofit/autofit.c index b6ed4a0ff1..c1605160a1 100644 --- a/src/3rdparty/freetype/src/autofit/autofit.c +++ b/src/3rdparty/freetype/src/autofit/autofit.c @@ -4,7 +4,7 @@ /* */ /* Auto-fitter module (body). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,29 +18,22 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> -#include "afpic.c" + #include "afangles.c" #include "afblue.c" +#include "afcjk.c" +#include "afdummy.c" #include "afglobal.c" #include "afhints.c" - -#include "afranges.c" - -#include "afdummy.c" -#include "aflatin.c" -#ifdef FT_OPTION_AUTOFIT2 -#include "aflatin2.c" -#endif -#include "afcjk.c" #include "afindic.c" - -#include "hbshim.c" - +#include "aflatin.c" +#include "aflatin2.c" #include "afloader.c" #include "afmodule.c" - -#ifdef AF_CONFIG_OPTION_USE_WARPER +#include "afpic.c" +#include "afranges.c" +#include "afshaper.c" #include "afwarp.c" -#endif + /* END */ diff --git a/src/3rdparty/freetype/src/autofit/module.mk b/src/3rdparty/freetype/src/autofit/module.mk index 33214387f5..ff05f83e7e 100644 --- a/src/3rdparty/freetype/src/autofit/module.mk +++ b/src/3rdparty/freetype/src/autofit/module.mk @@ -3,7 +3,7 @@ # -# Copyright 2003-2015 by +# Copyright 2003-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/autofit/rules.mk b/src/3rdparty/freetype/src/autofit/rules.mk index 6ef959f1ba..75171b412c 100644 --- a/src/3rdparty/freetype/src/autofit/rules.mk +++ b/src/3rdparty/freetype/src/autofit/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2003-2015 by +# Copyright 2003-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -40,8 +40,8 @@ AUTOF_DRV_SRC := $(AUTOF_DIR)/afangles.c \ $(AUTOF_DIR)/afmodule.c \ $(AUTOF_DIR)/afpic.c \ $(AUTOF_DIR)/afranges.c \ - $(AUTOF_DIR)/afwarp.c \ - $(AUTOF_DIR)/hbshim.c + $(AUTOF_DIR)/afshaper.c \ + $(AUTOF_DIR)/afwarp.c # AUTOF driver headers # diff --git a/src/3rdparty/freetype/src/base/Jamfile b/src/3rdparty/freetype/src/base/Jamfile index e39fb096b2..4994c1b4ca 100644 --- a/src/3rdparty/freetype/src/base/Jamfile +++ b/src/3rdparty/freetype/src/base/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/base Jamfile # -# Copyright 2001-2015 by +# Copyright 2001-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -21,10 +21,14 @@ SubDir FT2_TOP $(FT2_SRC_DIR) base ; ftadvanc ftcalc ftdbgmem + ftfntfmt ftgloadr + fthash + ftlcdfil ftobjs ftoutln ftpic + ftpsprop ftrfork ftsnames ftstream @@ -49,13 +53,11 @@ SubDir FT2_TOP $(FT2_SRC_DIR) base ; ftbitmap ftcid ftdebug - ftfntfmt ftfstype ftgasp ftglyph ftgxval ftinit - ftlcdfil ftmm ftotval ftpatent diff --git a/src/3rdparty/freetype/src/base/basepic.c b/src/3rdparty/freetype/src/base/basepic.c index 9850ed96a4..bc80406441 100644 --- a/src/3rdparty/freetype/src/base/basepic.c +++ b/src/3rdparty/freetype/src/base/basepic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for base. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2018 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/src/base/basepic.h b/src/3rdparty/freetype/src/base/basepic.h index c5d7cbf5ab..492d1ede56 100644 --- a/src/3rdparty/freetype/src/base/basepic.h +++ b/src/3rdparty/freetype/src/base/basepic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for base. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2018 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __BASEPIC_H__ -#define __BASEPIC_H__ +#ifndef BASEPIC_H_ +#define BASEPIC_H_ #include FT_INTERNAL_PIC_H @@ -85,7 +85,7 @@ FT_END_HEADER /* */ -#endif /* __BASEPIC_H__ */ +#endif /* BASEPIC_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/base/ftadvanc.c b/src/3rdparty/freetype/src/base/ftadvanc.c index f12908f518..230c84d6ad 100644 --- a/src/3rdparty/freetype/src/base/ftadvanc.c +++ b/src/3rdparty/freetype/src/base/ftadvanc.c @@ -4,7 +4,7 @@ /* */ /* Quick computation of advance widths (body). */ /* */ -/* Copyright 2008-2015 by */ +/* Copyright 2008-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -36,7 +36,7 @@ if ( flags & FT_LOAD_NO_SCALE ) return FT_Err_Ok; - if ( face->size == NULL ) + if ( !face->size ) return FT_THROW( Invalid_Size_Handle ); if ( flags & FT_LOAD_VERTICAL_LAYOUT ) @@ -60,8 +60,11 @@ /* - unscaled load */ /* - unhinted load */ /* - light-hinted load */ + /* - if a variations font, it must have an `HVAR' or `VVAR' */ + /* table (thus the old MM or GX fonts don't qualify; this */ + /* gets checked by the driver-specific functions) */ -#define LOAD_ADVANCE_FAST_CHECK( flags ) \ +#define LOAD_ADVANCE_FAST_CHECK( face, flags ) \ ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) || \ FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT ) @@ -87,7 +90,7 @@ return FT_THROW( Invalid_Glyph_Index ); func = face->driver->clazz->get_advances; - if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) ) + if ( func && LOAD_ADVANCE_FAST_CHECK( face, flags ) ) { FT_Error error; @@ -113,9 +116,12 @@ FT_Int32 flags, FT_Fixed *padvances ) { + FT_Error error = FT_Err_Ok; + FT_Face_GetAdvancesFunc func; - FT_UInt num, end, nn; - FT_Error error = FT_Err_Ok; + + FT_UInt num, end, nn; + FT_Int factor; if ( !face ) @@ -133,7 +139,7 @@ return FT_Err_Ok; func = face->driver->clazz->get_advances; - if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) ) + if ( func && LOAD_ADVANCE_FAST_CHECK( face, flags ) ) { error = func( face, start, count, flags, padvances ); if ( !error ) @@ -149,16 +155,17 @@ return FT_THROW( Unimplemented_Feature ); flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY; + factor = ( flags & FT_LOAD_NO_SCALE ) ? 1 : 1024; for ( nn = 0; nn < count; nn++ ) { error = FT_Load_Glyph( face, start + nn, flags ); if ( error ) break; - /* scale from 26.6 to 16.16 */ + /* scale from 26.6 to 16.16, unless NO_SCALE was requested */ padvances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT ) - ? face->glyph->advance.y << 10 - : face->glyph->advance.x << 10; + ? face->glyph->advance.y * factor + : face->glyph->advance.x * factor; } return error; diff --git a/src/3rdparty/freetype/src/base/ftapi.c b/src/3rdparty/freetype/src/base/ftapi.c index f22a181b59..32d6e95d19 100644 --- a/src/3rdparty/freetype/src/base/ftapi.c +++ b/src/3rdparty/freetype/src/base/ftapi.c @@ -4,7 +4,7 @@ /* */ /* The FreeType compatibility functions (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -38,7 +38,7 @@ /*************************************************************************/ /*************************************************************************/ - /* backwards compatibility API */ + /* backward compatibility API */ FT_BASE_DEF( void ) FT_New_Memory_Stream( FT_Library library, diff --git a/src/3rdparty/freetype/src/base/ftbase.c b/src/3rdparty/freetype/src/base/ftbase.c index 253dfb7236..f914b9b247 100644 --- a/src/3rdparty/freetype/src/base/ftbase.c +++ b/src/3rdparty/freetype/src/base/ftbase.c @@ -4,7 +4,7 @@ /* */ /* Single object library component (body only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,25 +17,26 @@ #include <ft2build.h> - #define FT_MAKE_OPTION_SINGLE_OBJECT -#include "ftpic.c" #include "basepic.c" #include "ftadvanc.c" #include "ftcalc.c" #include "ftdbgmem.c" +#include "ftfntfmt.c" #include "ftgloadr.c" +#include "fthash.c" +#include "ftlcdfil.c" +#include "ftmac.c" #include "ftobjs.c" #include "ftoutln.c" +#include "ftpic.c" +#include "ftpsprop.c" #include "ftrfork.c" #include "ftsnames.c" #include "ftstream.c" #include "fttrigon.c" #include "ftutil.c" -#ifdef FT_MACINTOSH -#include "ftmac.c" -#endif /* END */ diff --git a/src/3rdparty/freetype/src/base/ftbase.h b/src/3rdparty/freetype/src/base/ftbase.h index e37fefa411..7e8cfad959 100644 --- a/src/3rdparty/freetype/src/base/ftbase.h +++ b/src/3rdparty/freetype/src/base/ftbase.h @@ -2,9 +2,9 @@ /* */ /* ftbase.h */ /* */ -/* The FreeType private functions used in base module (specification). */ +/* Private functions used in the `base' module (specification). */ /* */ -/* Copyright 2008-2015 by */ +/* Copyright 2008-2018 by */ /* David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTBASE_H__ -#define __FTBASE_H__ +#ifndef FTBASE_H_ +#define FTBASE_H_ #include <ft2build.h> @@ -27,6 +27,8 @@ FT_BEGIN_HEADER +#ifdef FT_CONFIG_OPTION_MAC_FONTS + /* MacOS resource fork cannot exceed 16MB at least for Carbon code; */ /* see https://support.microsoft.com/en-us/kb/130437 */ #define FT_MAC_RFORK_MAX_LEN 0x00FFFFFFUL @@ -65,10 +67,12 @@ FT_BEGIN_HEADER ft_raccess_rule_by_darwin_vfs( FT_Library library, FT_UInt rule_index ); #endif +#endif /* FT_CONFIG_OPTION_MAC_FONTS */ + FT_END_HEADER -#endif /* __FTBASE_H__ */ +#endif /* FTBASE_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/base/ftbbox.c b/src/3rdparty/freetype/src/base/ftbbox.c index 10df98de6a..151e85c97a 100644 --- a/src/3rdparty/freetype/src/base/ftbbox.c +++ b/src/3rdparty/freetype/src/base/ftbbox.c @@ -4,7 +4,7 @@ /* */ /* FreeType bbox computation (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -423,12 +423,15 @@ } - FT_DEFINE_OUTLINE_FUNCS(bbox_interface, - (FT_Outline_MoveTo_Func) BBox_Move_To, - (FT_Outline_LineTo_Func) BBox_Line_To, - (FT_Outline_ConicTo_Func)BBox_Conic_To, - (FT_Outline_CubicTo_Func)BBox_Cubic_To, - 0, 0 + FT_DEFINE_OUTLINE_FUNCS( + bbox_interface, + + (FT_Outline_MoveTo_Func) BBox_Move_To, /* move_to */ + (FT_Outline_LineTo_Func) BBox_Line_To, /* line_to */ + (FT_Outline_ConicTo_Func)BBox_Conic_To, /* conic_to */ + (FT_Outline_CubicTo_Func)BBox_Cubic_To, /* cubic_to */ + 0, /* shift */ + 0 /* delta */ ) @@ -457,6 +460,7 @@ { abbox->xMin = abbox->xMax = 0; abbox->yMin = abbox->yMax = 0; + return 0; } @@ -468,10 +472,10 @@ for ( n = 0; n < outline->n_points; n++ ) { - FT_UPDATE_BBOX( vec, cbox); + FT_UPDATE_BBOX( vec, cbox ); if ( FT_CURVE_TAG( outline->tags[n] ) == FT_CURVE_TAG_ON ) - FT_UPDATE_BBOX( vec, bbox); + FT_UPDATE_BBOX( vec, bbox ); vec++; } @@ -487,8 +491,10 @@ TBBox_Rec user; #ifdef FT_CONFIG_OPTION_PIC - FT_Outline_Funcs bbox_interface; - Init_Class_bbox_interface(&bbox_interface); + FT_Outline_Funcs bbox_interface; + + + Init_Class_bbox_interface( &bbox_interface ); #endif user.bbox = bbox; diff --git a/src/3rdparty/freetype/src/base/ftbdf.c b/src/3rdparty/freetype/src/base/ftbdf.c index aa72ddcdf9..c4ea502fbc 100644 --- a/src/3rdparty/freetype/src/base/ftbdf.c +++ b/src/3rdparty/freetype/src/base/ftbdf.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing BDF-specific strings (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/src/base/ftbitmap.c b/src/3rdparty/freetype/src/base/ftbitmap.c index a54572aaa2..a9746663fa 100644 --- a/src/3rdparty/freetype/src/base/ftbitmap.c +++ b/src/3rdparty/freetype/src/base/ftbitmap.c @@ -4,7 +4,7 @@ /* */ /* FreeType utility functions for bitmaps (body). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -76,7 +76,7 @@ source_pitch_sign = source->pitch < 0 ? -1 : 1; target_pitch_sign = target->pitch < 0 ? -1 : 1; - if ( source->buffer == NULL ) + if ( !source->buffer ) { *target = *source; if ( source_pitch_sign != target_pitch_sign ) @@ -153,38 +153,36 @@ FT_UInt ypixels ) { FT_Error error; - int pitch; - int new_pitch; + unsigned int pitch; + unsigned int new_pitch; FT_UInt bpp; - FT_UInt i, width, height; + FT_UInt width, height; unsigned char* buffer = NULL; width = bitmap->width; height = bitmap->rows; - pitch = bitmap->pitch; - if ( pitch < 0 ) - pitch = -pitch; + pitch = (unsigned int)FT_ABS( bitmap->pitch ); switch ( bitmap->pixel_mode ) { case FT_PIXEL_MODE_MONO: bpp = 1; - new_pitch = (int)( ( width + xpixels + 7 ) >> 3 ); + new_pitch = ( width + xpixels + 7 ) >> 3; break; case FT_PIXEL_MODE_GRAY2: bpp = 2; - new_pitch = (int)( ( width + xpixels + 3 ) >> 2 ); + new_pitch = ( width + xpixels + 3 ) >> 2; break; case FT_PIXEL_MODE_GRAY4: bpp = 4; - new_pitch = (int)( ( width + xpixels + 1 ) >> 1 ); + new_pitch = ( width + xpixels + 1 ) >> 1; break; case FT_PIXEL_MODE_GRAY: case FT_PIXEL_MODE_LCD: case FT_PIXEL_MODE_LCD_V: bpp = 8; - new_pitch = (int)( width + xpixels ); + new_pitch = width + xpixels; break; default: return FT_THROW( Invalid_Glyph_Format ); @@ -194,7 +192,7 @@ if ( ypixels == 0 && new_pitch <= pitch ) { /* zero the padding */ - FT_UInt bit_width = (FT_UInt)pitch * 8; + FT_UInt bit_width = pitch * 8; FT_UInt bit_last = ( width + xpixels ) * bpp; @@ -226,7 +224,7 @@ } /* otherwise allocate new buffer */ - if ( FT_QALLOC_MULT( buffer, new_pitch, bitmap->rows + ypixels ) ) + if ( FT_QALLOC_MULT( buffer, bitmap->rows + ypixels, new_pitch ) ) return error; /* new rows get added at the top of the bitmap, */ @@ -235,31 +233,60 @@ { FT_UInt len = ( width * bpp + 7 ) >> 3; + unsigned char* in = bitmap->buffer; + unsigned char* out = buffer; - for ( i = 0; i < bitmap->rows; i++ ) - FT_MEM_COPY( buffer + (FT_UInt)new_pitch * ( ypixels + i ), - bitmap->buffer + (FT_UInt)pitch * i, - len ); + unsigned char* limit = bitmap->buffer + pitch * bitmap->rows; + unsigned int delta = new_pitch - len; + + + FT_MEM_ZERO( out, new_pitch * ypixels ); + out += new_pitch * ypixels; + + while ( in < limit ) + { + FT_MEM_COPY( out, in, len ); + in += pitch; + out += len; + + /* we use FT_QALLOC_MULT, which doesn't zero out the buffer; */ + /* consequently, we have to manually zero out the remaining bytes */ + FT_MEM_ZERO( out, delta ); + out += delta; + } } else { FT_UInt len = ( width * bpp + 7 ) >> 3; + unsigned char* in = bitmap->buffer; + unsigned char* out = buffer; - for ( i = 0; i < bitmap->rows; i++ ) - FT_MEM_COPY( buffer + (FT_UInt)new_pitch * i, - bitmap->buffer + (FT_UInt)pitch * i, - len ); + unsigned char* limit = bitmap->buffer + pitch * bitmap->rows; + unsigned int delta = new_pitch - len; + + + while ( in < limit ) + { + FT_MEM_COPY( out, in, len ); + in += pitch; + out += len; + + FT_MEM_ZERO( out, delta ); + out += delta; + } + + FT_MEM_ZERO( out, new_pitch * ypixels ); } FT_FREE( bitmap->buffer ); bitmap->buffer = buffer; - if ( bitmap->pitch < 0 ) - new_pitch = -new_pitch; - /* set pitch only, width and height are left untouched */ - bitmap->pitch = new_pitch; + if ( bitmap->pitch < 0 ) + bitmap->pitch = -(int)new_pitch; + else + bitmap->pitch = (int)new_pitch; return FT_Err_Ok; } @@ -351,7 +378,7 @@ } /* for each row */ - for ( y = 0; y < bitmap->rows ; y++ ) + for ( y = 0; y < bitmap->rows; y++ ) { /* * Horizontally: @@ -444,7 +471,7 @@ * A gamma of 2.2 is fair to assume. And then, we need to * undo the premultiplication too. * - * http://accessibility.kde.org/hsl-adjusted.php + * https://accessibility.kde.org/hsl-adjusted.php * * We do the computation with integers only, applying a gamma of 2.0. * We guarantee 32-bit arithmetic to avoid overflow but the resulting @@ -534,8 +561,7 @@ (FT_ULong)target->rows > FT_ULONG_MAX / (FT_ULong)target_pitch ) return FT_THROW( Invalid_Argument ); - if ( target->rows * (FT_ULong)target_pitch > old_size && - FT_QREALLOC( target->buffer, + if ( FT_QREALLOC( target->buffer, old_size, target->rows * (FT_UInt)target_pitch ) ) return error; diff --git a/src/3rdparty/freetype/src/base/ftcalc.c b/src/3rdparty/freetype/src/base/ftcalc.c index 619a08b3a0..f4ff45f8ef 100644 --- a/src/3rdparty/freetype/src/base/ftcalc.c +++ b/src/3rdparty/freetype/src/base/ftcalc.c @@ -4,7 +4,7 @@ /* */ /* Arithmetic computations (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -68,14 +68,15 @@ #define FT_COMPONENT trace_calc - /* transfer sign leaving a positive number */ -#define FT_MOVE_SIGN( x, s ) \ - FT_BEGIN_STMNT \ - if ( x < 0 ) \ - { \ - x = -x; \ - s = -s; \ - } \ + /* transfer sign, leaving a positive number; */ + /* we need an unsigned value to safely negate INT_MIN (or LONG_MIN) */ +#define FT_MOVE_SIGN( x, x_unsigned, s ) \ + FT_BEGIN_STMNT \ + if ( x < 0 ) \ + { \ + x_unsigned = 0U - (x_unsigned); \ + s = -s; \ + } \ FT_END_STMNT /* The following three functions are available regardless of whether */ @@ -86,7 +87,7 @@ FT_EXPORT_DEF( FT_Fixed ) FT_RoundFix( FT_Fixed a ) { - return ( a + 0x8000L - ( a < 0 ) ) & ~0xFFFFL; + return ( ADD_LONG( a, 0x8000L - ( a < 0 ) ) ) & ~0xFFFFL; } @@ -95,7 +96,7 @@ FT_EXPORT_DEF( FT_Fixed ) FT_CeilFix( FT_Fixed a ) { - return ( a + 0xFFFFL ) & ~0xFFFFL; + return ( ADD_LONG( a, 0xFFFFL ) ) & ~0xFFFFL; } @@ -179,20 +180,20 @@ FT_Long d_; - FT_MOVE_SIGN( a_, s ); - FT_MOVE_SIGN( b_, s ); - FT_MOVE_SIGN( c_, s ); - a = (FT_UInt64)a_; b = (FT_UInt64)b_; c = (FT_UInt64)c_; + FT_MOVE_SIGN( a_, a, s ); + FT_MOVE_SIGN( b_, b, s ); + FT_MOVE_SIGN( c_, c, s ); + d = c > 0 ? ( a * b + ( c >> 1 ) ) / c : 0x7FFFFFFFUL; d_ = (FT_Long)d; - return s < 0 ? -d_ : d_; + return s < 0 ? NEG_LONG( d_ ) : d_; } @@ -208,20 +209,20 @@ FT_Long d_; - FT_MOVE_SIGN( a_, s ); - FT_MOVE_SIGN( b_, s ); - FT_MOVE_SIGN( c_, s ); - a = (FT_UInt64)a_; b = (FT_UInt64)b_; c = (FT_UInt64)c_; + FT_MOVE_SIGN( a_, a, s ); + FT_MOVE_SIGN( b_, b, s ); + FT_MOVE_SIGN( c_, c, s ); + d = c > 0 ? a * b / c : 0x7FFFFFFFUL; d_ = (FT_Long)d; - return s < 0 ? -d_ : d_; + return s < 0 ? NEG_LONG( d_ ) : d_; } @@ -233,7 +234,7 @@ { #ifdef FT_MULFIX_ASSEMBLER - return FT_MULFIX_ASSEMBLER( a_, b_ ); + return FT_MULFIX_ASSEMBLER( (FT_Int32)a_, (FT_Int32)b_ ); #else @@ -257,18 +258,18 @@ FT_Long q_; - FT_MOVE_SIGN( a_, s ); - FT_MOVE_SIGN( b_, s ); - a = (FT_UInt64)a_; b = (FT_UInt64)b_; + FT_MOVE_SIGN( a_, a, s ); + FT_MOVE_SIGN( b_, b, s ); + q = b > 0 ? ( ( a << 16 ) + ( b >> 1 ) ) / b : 0x7FFFFFFFUL; q_ = (FT_Long)q; - return s < 0 ? -q_ : q_; + return s < 0 ? NEG_LONG( q_ ) : q_; } @@ -422,14 +423,14 @@ /* XXX: this function does not allow 64-bit arguments */ - FT_MOVE_SIGN( a_, s ); - FT_MOVE_SIGN( b_, s ); - FT_MOVE_SIGN( c_, s ); - a = (FT_UInt32)a_; b = (FT_UInt32)b_; c = (FT_UInt32)c_; + FT_MOVE_SIGN( a_, a, s ); + FT_MOVE_SIGN( b_, b, s ); + FT_MOVE_SIGN( c_, c, s ); + if ( c == 0 ) a = 0x7FFFFFFFUL; @@ -449,13 +450,13 @@ FT_Add64( &temp, &temp2, &temp ); /* last attempt to ditch long division */ - a = temp.hi == 0 ? temp.lo / c - : ft_div64by32( temp.hi, temp.lo, c ); + a = ( temp.hi == 0 ) ? temp.lo / c + : ft_div64by32( temp.hi, temp.lo, c ); } a_ = (FT_Long)a; - return s < 0 ? -a_ : a_; + return s < 0 ? NEG_LONG( a_ ) : a_; } @@ -470,14 +471,14 @@ /* XXX: this function does not allow 64-bit arguments */ - FT_MOVE_SIGN( a_, s ); - FT_MOVE_SIGN( b_, s ); - FT_MOVE_SIGN( c_, s ); - a = (FT_UInt32)a_; b = (FT_UInt32)b_; c = (FT_UInt32)c_; + FT_MOVE_SIGN( a_, a, s ); + FT_MOVE_SIGN( b_, b, s ); + FT_MOVE_SIGN( c_, c, s ); + if ( c == 0 ) a = 0x7FFFFFFFUL; @@ -492,13 +493,13 @@ ft_multo64( a, b, &temp ); /* last attempt to ditch long division */ - a = temp.hi == 0 ? temp.lo / c - : ft_div64by32( temp.hi, temp.lo, c ); + a = ( temp.hi == 0 ) ? temp.lo / c + : ft_div64by32( temp.hi, temp.lo, c ); } a_ = (FT_Long)a; - return s < 0 ? -a_ : a_; + return s < 0 ? NEG_LONG( a_ ) : a_; } @@ -575,12 +576,12 @@ /* XXX: this function does not allow 64-bit arguments */ - FT_MOVE_SIGN( a_, s ); - FT_MOVE_SIGN( b_, s ); - a = (FT_UInt32)a_; b = (FT_UInt32)b_; + FT_MOVE_SIGN( a_, a, s ); + FT_MOVE_SIGN( b_, b, s ); + if ( a + ( b >> 8 ) <= 8190UL ) a = ( a * b + 0x8000UL ) >> 16; else @@ -594,7 +595,7 @@ a_ = (FT_Long)a; - return s < 0 ? -a_ : a_; + return s < 0 ? NEG_LONG( a_ ) : a_; #endif /* 0 */ @@ -614,12 +615,12 @@ /* XXX: this function does not allow 64-bit arguments */ - FT_MOVE_SIGN( a_, s ); - FT_MOVE_SIGN( b_, s ); - a = (FT_UInt32)a_; b = (FT_UInt32)b_; + FT_MOVE_SIGN( a_, a, s ); + FT_MOVE_SIGN( b_, b, s ); + if ( b == 0 ) { /* check for division by 0 */ @@ -647,7 +648,7 @@ q_ = (FT_Long)q; - return s < 0 ? -q_ : q_; + return s < 0 ? NEG_LONG( q_ ) : q_; } @@ -666,13 +667,19 @@ if ( !a || !b ) return; - xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx ); - xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy ); - yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx ); - yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy ); + xx = ADD_LONG( FT_MulFix( a->xx, b->xx ), + FT_MulFix( a->xy, b->yx ) ); + xy = ADD_LONG( FT_MulFix( a->xx, b->xy ), + FT_MulFix( a->xy, b->yy ) ); + yx = ADD_LONG( FT_MulFix( a->yx, b->xx ), + FT_MulFix( a->yy, b->yx ) ); + yy = ADD_LONG( FT_MulFix( a->yx, b->xy ), + FT_MulFix( a->yy, b->yy ) ); - b->xx = xx; b->xy = xy; - b->yx = yx; b->yy = yy; + b->xx = xx; + b->xy = xy; + b->yx = yx; + b->yy = yy; } @@ -722,13 +729,19 @@ if ( !a || !b ) return; - xx = FT_MulDiv( a->xx, b->xx, val ) + FT_MulDiv( a->xy, b->yx, val ); - xy = FT_MulDiv( a->xx, b->xy, val ) + FT_MulDiv( a->xy, b->yy, val ); - yx = FT_MulDiv( a->yx, b->xx, val ) + FT_MulDiv( a->yy, b->yx, val ); - yy = FT_MulDiv( a->yx, b->xy, val ) + FT_MulDiv( a->yy, b->yy, val ); + xx = ADD_LONG( FT_MulDiv( a->xx, b->xx, val ), + FT_MulDiv( a->xy, b->yx, val ) ); + xy = ADD_LONG( FT_MulDiv( a->xx, b->xy, val ), + FT_MulDiv( a->xy, b->yy, val ) ); + yx = ADD_LONG( FT_MulDiv( a->yx, b->xx, val ), + FT_MulDiv( a->yy, b->yx, val ) ); + yy = ADD_LONG( FT_MulDiv( a->yx, b->xy, val ), + FT_MulDiv( a->yy, b->yy, val ) ); - b->xx = xx; b->xy = xy; - b->yx = yx; b->yy = yy; + b->xx = xx; + b->xy = xy; + b->yx = yx; + b->yy = yy; } @@ -747,11 +760,10 @@ if ( !vector || !matrix ) return; - xz = FT_MulDiv( vector->x, matrix->xx, val ) + - FT_MulDiv( vector->y, matrix->xy, val ); - - yz = FT_MulDiv( vector->x, matrix->yx, val ) + - FT_MulDiv( vector->y, matrix->yy, val ); + xz = ADD_LONG( FT_MulDiv( vector->x, matrix->xx, val ), + FT_MulDiv( vector->y, matrix->xy, val ) ); + yz = ADD_LONG( FT_MulDiv( vector->x, matrix->yx, val ), + FT_MulDiv( vector->y, matrix->yy, val ) ); vector->x = xz; vector->y = yz; @@ -770,12 +782,12 @@ FT_Int sx = 1, sy = 1, shift; - FT_MOVE_SIGN( x_, sx ); - FT_MOVE_SIGN( y_, sy ); - x = (FT_UInt32)x_; y = (FT_UInt32)y_; + FT_MOVE_SIGN( x_, x, sx ); + FT_MOVE_SIGN( y_, y, sy ); + /* trivial cases */ if ( x == 0 ) { @@ -913,11 +925,13 @@ FT_Int result; - if ( (FT_ULong)FT_ABS( in_x ) + (FT_ULong)FT_ABS( out_y ) <= 131071UL && - (FT_ULong)FT_ABS( in_y ) + (FT_ULong)FT_ABS( out_x ) <= 131071UL ) + /* we silently ignore overflow errors, since such large values */ + /* lead to even more (harmless) rendering errors later on */ + if ( ADD_LONG( FT_ABS( in_x ), FT_ABS( out_y ) ) <= 131071L && + ADD_LONG( FT_ABS( in_y ), FT_ABS( out_x ) ) <= 131071L ) { - FT_Long z1 = in_x * out_y; - FT_Long z2 = in_y * out_x; + FT_Long z1 = MUL_LONG( in_x, out_y ); + FT_Long z2 = MUL_LONG( in_y, out_x ); if ( z1 > z2 ) diff --git a/src/3rdparty/freetype/src/base/ftcid.c b/src/3rdparty/freetype/src/base/ftcid.c index 0734881b71..f5184649bf 100644 --- a/src/3rdparty/freetype/src/base/ftcid.c +++ b/src/3rdparty/freetype/src/base/ftcid.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing CID font information. */ /* */ -/* Copyright 2007-2015 by */ +/* Copyright 2007-2018 by */ /* Derek Clegg and Michael Toftdal. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/src/base/ftdbgmem.c b/src/3rdparty/freetype/src/base/ftdbgmem.c index 6f20313b34..c33d8acb4e 100644 --- a/src/3rdparty/freetype/src/base/ftdbgmem.c +++ b/src/3rdparty/freetype/src/base/ftdbgmem.c @@ -4,7 +4,7 @@ /* */ /* Memory debugger (body). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -268,7 +268,7 @@ ft_mem_table_alloc( table, new_size * (FT_Long)sizeof ( FT_MemNode ) ); - if ( new_buckets == NULL ) + if ( !new_buckets ) return; FT_ARRAY_ZERO( new_buckets, new_size ); @@ -309,7 +309,7 @@ table = (FT_MemTable)memory->alloc( memory, sizeof ( *table ) ); - if ( table == NULL ) + if ( !table ) goto Exit; FT_ZERO( table ); @@ -367,7 +367,8 @@ { printf( "leaked memory block at address %p, size %8ld in (%s:%ld)\n", - node->address, node->size, + (void*)node->address, + node->size, FT_FILENAME( node->source->file_name ), node->source->line_no ); @@ -462,10 +463,10 @@ (FT_UInt32)( 5 * _ft_debug_lineno ); pnode = &table->sources[hash % FT_MEM_SOURCE_BUCKETS]; - for ( ;; ) + for (;;) { node = *pnode; - if ( node == NULL ) + if ( !node ) break; if ( node->file_name == _ft_debug_file && @@ -476,7 +477,7 @@ } node = (FT_MemSource)ft_mem_table_alloc( table, sizeof ( *node ) ); - if ( node == NULL ) + if ( !node ) ft_mem_debug_panic( "not enough memory to perform memory debugging\n" ); @@ -544,7 +545,7 @@ /* we need to create a new node in this table */ node = (FT_MemNode)ft_mem_table_alloc( table, sizeof ( *node ) ); - if ( node == NULL ) + if ( !node ) ft_mem_debug_panic( "not enough memory to run memory tests" ); node->address = address; @@ -716,7 +717,7 @@ FT_MemTable table = (FT_MemTable)memory->user; - if ( block == NULL ) + if ( !block ) ft_mem_debug_panic( "trying to free NULL in (%s:%ld)", FT_FILENAME( _ft_debug_file ), _ft_debug_lineno ); @@ -754,7 +755,7 @@ /* the following is valid according to ANSI C */ #if 0 - if ( block == NULL || cur_size == 0 ) + if ( !block || !cur_size ) ft_mem_debug_panic( "trying to reallocate NULL in (%s:%ld)", file_name, line_no ); #endif @@ -798,7 +799,7 @@ return NULL; new_block = (FT_Pointer)ft_mem_table_alloc( table, new_size ); - if ( new_block == NULL ) + if ( !new_block ) return NULL; ft_mem_table_set( table, (FT_Byte*)new_block, new_size, delta ); @@ -825,7 +826,7 @@ FT_Int result = 0; - if ( getenv( "FT2_DEBUG_MEMORY" ) ) + if ( ft_getenv( "FT2_DEBUG_MEMORY" ) ) { table = ft_mem_table_new( memory ); if ( table ) @@ -838,10 +839,10 @@ memory->realloc = ft_mem_debug_realloc; memory->free = ft_mem_debug_free; - p = getenv( "FT2_ALLOC_TOTAL_MAX" ); - if ( p != NULL ) + p = ft_getenv( "FT2_ALLOC_TOTAL_MAX" ); + if ( p ) { - FT_Long total_max = ft_atol( p ); + FT_Long total_max = ft_strtol( p, NULL, 10 ); if ( total_max > 0 ) @@ -851,10 +852,10 @@ } } - p = getenv( "FT2_ALLOC_COUNT_MAX" ); - if ( p != NULL ) + p = ft_getenv( "FT2_ALLOC_COUNT_MAX" ); + if ( p ) { - FT_Long total_count = ft_atol( p ); + FT_Long total_count = ft_strtol( p, NULL, 10 ); if ( total_count > 0 ) @@ -864,10 +865,10 @@ } } - p = getenv( "FT2_KEEP_ALIVE" ); - if ( p != NULL ) + p = ft_getenv( "FT2_KEEP_ALIVE" ); + if ( p ) { - FT_Long keep_alive = ft_atol( p ); + FT_Long keep_alive = ft_strtol( p, NULL, 10 ); if ( keep_alive > 0 ) diff --git a/src/3rdparty/freetype/src/base/ftdebug.c b/src/3rdparty/freetype/src/base/ftdebug.c index 03e18a8699..fe26309101 100644 --- a/src/3rdparty/freetype/src/base/ftdebug.c +++ b/src/3rdparty/freetype/src/base/ftdebug.c @@ -4,7 +4,7 @@ /* */ /* Debugging and logging component (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -161,7 +161,7 @@ FT_BASE_DEF( void ) ft_debug_init( void ) { - const char* ft2_debug = getenv( "FT2_DEBUG" ); + const char* ft2_debug = ft_getenv( "FT2_DEBUG" ); if ( ft2_debug ) diff --git a/src/3rdparty/freetype/src/base/ftfntfmt.c b/src/3rdparty/freetype/src/base/ftfntfmt.c index 98e7431a2b..a2900ceb09 100644 --- a/src/3rdparty/freetype/src/base/ftfntfmt.c +++ b/src/3rdparty/freetype/src/base/ftfntfmt.c @@ -4,7 +4,7 @@ /* */ /* FreeType utility file for font formats (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/src/base/ftfstype.c b/src/3rdparty/freetype/src/base/ftfstype.c index cd3458f73e..e6cdf6e2ec 100644 --- a/src/3rdparty/freetype/src/base/ftfstype.c +++ b/src/3rdparty/freetype/src/base/ftfstype.c @@ -4,7 +4,7 @@ /* */ /* FreeType utility file to access FSType data (body). */ /* */ -/* Copyright 2008-2015 by */ +/* Copyright 2008-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/src/base/ftgasp.c b/src/3rdparty/freetype/src/base/ftgasp.c index bbd257c479..4f80bba630 100644 --- a/src/3rdparty/freetype/src/base/ftgasp.c +++ b/src/3rdparty/freetype/src/base/ftgasp.c @@ -4,7 +4,7 @@ /* */ /* Access of TrueType's `gasp' table (body). */ /* */ -/* Copyright 2007-2015 by */ +/* Copyright 2007-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/src/base/ftgloadr.c b/src/3rdparty/freetype/src/base/ftgloadr.c index 7e28638b27..47202496b9 100644 --- a/src/3rdparty/freetype/src/base/ftgloadr.c +++ b/src/3rdparty/freetype/src/base/ftgloadr.c @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph loader (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/src/base/ftglyph.c b/src/3rdparty/freetype/src/base/ftglyph.c index cb7fc37787..6759aa25d0 100644 --- a/src/3rdparty/freetype/src/base/ftglyph.c +++ b/src/3rdparty/freetype/src/base/ftglyph.c @@ -4,7 +4,7 @@ /* */ /* FreeType convenience functions to handle glyphs (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -125,23 +125,25 @@ FT_BitmapGlyph glyph = (FT_BitmapGlyph)bitmap_glyph; - cbox->xMin = glyph->left << 6; - cbox->xMax = cbox->xMin + (FT_Pos)( glyph->bitmap.width << 6 ); - cbox->yMax = glyph->top << 6; - cbox->yMin = cbox->yMax - (FT_Pos)( glyph->bitmap.rows << 6 ); + cbox->xMin = glyph->left * 64; + cbox->xMax = cbox->xMin + (FT_Pos)( glyph->bitmap.width * 64 ); + cbox->yMax = glyph->top * 64; + cbox->yMin = cbox->yMax - (FT_Pos)( glyph->bitmap.rows * 64 ); } - FT_DEFINE_GLYPH(ft_bitmap_glyph_class, + FT_DEFINE_GLYPH( + ft_bitmap_glyph_class, + sizeof ( FT_BitmapGlyphRec ), FT_GLYPH_FORMAT_BITMAP, - ft_bitmap_glyph_init, - ft_bitmap_glyph_done, - ft_bitmap_glyph_copy, - 0, /* FT_Glyph_TransformFunc */ - ft_bitmap_glyph_bbox, - 0 /* FT_Glyph_PrepareFunc */ + ft_bitmap_glyph_init, /* FT_Glyph_InitFunc glyph_init */ + ft_bitmap_glyph_done, /* FT_Glyph_DoneFunc glyph_done */ + ft_bitmap_glyph_copy, /* FT_Glyph_CopyFunc glyph_copy */ + NULL, /* FT_Glyph_TransformFunc glyph_transform */ + ft_bitmap_glyph_bbox, /* FT_Glyph_GetBBoxFunc glyph_bbox */ + NULL /* FT_Glyph_PrepareFunc glyph_prepare */ ) @@ -260,16 +262,18 @@ } - FT_DEFINE_GLYPH( ft_outline_glyph_class, + FT_DEFINE_GLYPH( + ft_outline_glyph_class, + sizeof ( FT_OutlineGlyphRec ), FT_GLYPH_FORMAT_OUTLINE, - ft_outline_glyph_init, - ft_outline_glyph_done, - ft_outline_glyph_copy, - ft_outline_glyph_transform, - ft_outline_glyph_bbox, - ft_outline_glyph_prepare + ft_outline_glyph_init, /* FT_Glyph_InitFunc glyph_init */ + ft_outline_glyph_done, /* FT_Glyph_DoneFunc glyph_done */ + ft_outline_glyph_copy, /* FT_Glyph_CopyFunc glyph_copy */ + ft_outline_glyph_transform, /* FT_Glyph_TransformFunc glyph_transform */ + ft_outline_glyph_bbox, /* FT_Glyph_GetBBoxFunc glyph_bbox */ + ft_outline_glyph_prepare /* FT_Glyph_PrepareFunc glyph_prepare */ ) @@ -403,13 +407,29 @@ if ( error ) goto Exit; - /* copy advance while converting it to 16.16 format */ - glyph->advance.x = slot->advance.x << 10; - glyph->advance.y = slot->advance.y << 10; + /* copy advance while converting 26.6 to 16.16 format */ + if ( slot->advance.x >= 0x8000L * 64 || + slot->advance.x <= -0x8000L * 64 ) + { + FT_ERROR(( "FT_Get_Glyph: advance width too large\n" )); + error = FT_THROW( Invalid_Argument ); + goto Exit2; + } + if ( slot->advance.y >= 0x8000L * 64 || + slot->advance.y <= -0x8000L * 64 ) + { + FT_ERROR(( "FT_Get_Glyph: advance height too large\n" )); + error = FT_THROW( Invalid_Argument ); + goto Exit2; + } + + glyph->advance.x = slot->advance.x * 1024; + glyph->advance.y = slot->advance.y * 1024; /* now import the image from the glyph slot */ error = clazz->glyph_init( glyph, slot ); + Exit2: /* if an error occurred, destroy the glyph */ if ( error ) FT_Done_Glyph( glyph ); @@ -542,8 +562,8 @@ /* we render the glyph into a glyph bitmap using a `dummy' glyph slot */ /* then calling FT_Render_Glyph_Internal() */ - FT_MEM_ZERO( &dummy, sizeof ( dummy ) ); - FT_MEM_ZERO( &dummy_internal, sizeof ( dummy_internal ) ); + FT_ZERO( &dummy ); + FT_ZERO( &dummy_internal ); dummy.internal = &dummy_internal; dummy.library = library; dummy.format = clazz->glyph_format; diff --git a/src/3rdparty/freetype/src/base/ftgxval.c b/src/3rdparty/freetype/src/base/ftgxval.c index 58868f2e86..19e2d6acb5 100644 --- a/src/3rdparty/freetype/src/base/ftgxval.c +++ b/src/3rdparty/freetype/src/base/ftgxval.c @@ -2,9 +2,9 @@ /* */ /* ftgxval.c */ /* */ -/* FreeType API for validating TrueTyepGX/AAT tables (body). */ +/* FreeType API for validating TrueTypeGX/AAT tables (body). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* Masatake YAMATO, Redhat K.K, */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ diff --git a/src/3rdparty/freetype/src/base/fthash.c b/src/3rdparty/freetype/src/base/fthash.c new file mode 100644 index 0000000000..21bc8dd5b4 --- /dev/null +++ b/src/3rdparty/freetype/src/base/fthash.c @@ -0,0 +1,339 @@ +/***************************************************************************/ +/* */ +/* fthash.c */ +/* */ +/* Hashing functions (body). */ +/* */ +/***************************************************************************/ + +/* + * Copyright 2000 Computing Research Labs, New Mexico State University + * Copyright 2001-2015 + * Francesco Zappa Nardelli + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT + * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + /*************************************************************************/ + /* */ + /* This file is based on code from bdf.c,v 1.22 2000/03/16 20:08:50 */ + /* */ + /* taken from Mark Leisher's xmbdfed package */ + /* */ + /*************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_HASH_H +#include FT_INTERNAL_MEMORY_H + + +#define INITIAL_HT_SIZE 241 + + + static FT_ULong + hash_str_lookup( FT_Hashkey* key ) + { + const char* kp = key->str; + FT_ULong res = 0; + + + /* Mocklisp hash function. */ + while ( *kp ) + res = ( res << 5 ) - res + (FT_ULong)*kp++; + + return res; + } + + + static FT_ULong + hash_num_lookup( FT_Hashkey* key ) + { + FT_ULong num = (FT_ULong)key->num; + FT_ULong res; + + + /* Mocklisp hash function. */ + res = num & 0xFF; + res = ( res << 5 ) - res + ( ( num >> 8 ) & 0xFF ); + res = ( res << 5 ) - res + ( ( num >> 16 ) & 0xFF ); + res = ( res << 5 ) - res + ( ( num >> 24 ) & 0xFF ); + + return res; + } + + + static FT_Bool + hash_str_compare( FT_Hashkey* a, + FT_Hashkey* b ) + { + if ( a->str[0] == b->str[0] && + ft_strcmp( a->str, b->str ) == 0 ) + return 1; + + return 0; + } + + + static FT_Bool + hash_num_compare( FT_Hashkey* a, + FT_Hashkey* b ) + { + if ( a->num == b->num ) + return 1; + + return 0; + } + + + static FT_Hashnode* + hash_bucket( FT_Hashkey key, + FT_Hash hash ) + { + FT_ULong res = 0; + FT_Hashnode* bp = hash->table; + FT_Hashnode* ndp; + + + res = (hash->lookup)( &key ); + + ndp = bp + ( res % hash->size ); + while ( *ndp ) + { + if ( (hash->compare)( &(*ndp)->key, &key ) ) + break; + + ndp--; + if ( ndp < bp ) + ndp = bp + ( hash->size - 1 ); + } + + return ndp; + } + + + static FT_Error + hash_rehash( FT_Hash hash, + FT_Memory memory ) + { + FT_Hashnode* obp = hash->table; + FT_Hashnode* bp; + FT_Hashnode* nbp; + + FT_UInt i, sz = hash->size; + FT_Error error = FT_Err_Ok; + + + hash->size <<= 1; + hash->limit = hash->size / 3; + + if ( FT_NEW_ARRAY( hash->table, hash->size ) ) + goto Exit; + + for ( i = 0, bp = obp; i < sz; i++, bp++ ) + { + if ( *bp ) + { + nbp = hash_bucket( (*bp)->key, hash ); + *nbp = *bp; + } + } + + FT_FREE( obp ); + + Exit: + return error; + } + + + static FT_Error + hash_init( FT_Hash hash, + FT_Bool is_num, + FT_Memory memory ) + { + FT_UInt sz = INITIAL_HT_SIZE; + FT_Error error; + + + hash->size = sz; + hash->limit = sz / 3; + hash->used = 0; + + if ( is_num ) + { + hash->lookup = hash_num_lookup; + hash->compare = hash_num_compare; + } + else + { + hash->lookup = hash_str_lookup; + hash->compare = hash_str_compare; + } + + FT_MEM_NEW_ARRAY( hash->table, sz ); + + return error; + } + + + FT_Error + ft_hash_str_init( FT_Hash hash, + FT_Memory memory ) + { + return hash_init( hash, 0, memory ); + } + + + FT_Error + ft_hash_num_init( FT_Hash hash, + FT_Memory memory ) + { + return hash_init( hash, 1, memory ); + } + + + void + ft_hash_str_free( FT_Hash hash, + FT_Memory memory ) + { + if ( hash ) + { + FT_UInt sz = hash->size; + FT_Hashnode* bp = hash->table; + FT_UInt i; + + + for ( i = 0; i < sz; i++, bp++ ) + FT_FREE( *bp ); + + FT_FREE( hash->table ); + } + } + + + /* `ft_hash_num_free' is the same as `ft_hash_str_free' */ + + + static FT_Error + hash_insert( FT_Hashkey key, + size_t data, + FT_Hash hash, + FT_Memory memory ) + { + FT_Hashnode nn; + FT_Hashnode* bp = hash_bucket( key, hash ); + FT_Error error = FT_Err_Ok; + + + nn = *bp; + if ( !nn ) + { + if ( FT_NEW( nn ) ) + goto Exit; + *bp = nn; + + nn->key = key; + nn->data = data; + + if ( hash->used >= hash->limit ) + { + error = hash_rehash( hash, memory ); + if ( error ) + goto Exit; + } + + hash->used++; + } + else + nn->data = data; + + Exit: + return error; + } + + + FT_Error + ft_hash_str_insert( const char* key, + size_t data, + FT_Hash hash, + FT_Memory memory ) + { + FT_Hashkey hk; + + + hk.str = key; + + return hash_insert( hk, data, hash, memory ); + } + + + FT_Error + ft_hash_num_insert( FT_Int num, + size_t data, + FT_Hash hash, + FT_Memory memory ) + { + FT_Hashkey hk; + + + hk.num = num; + + return hash_insert( hk, data, hash, memory ); + } + + + static size_t* + hash_lookup( FT_Hashkey key, + FT_Hash hash ) + { + FT_Hashnode* np = hash_bucket( key, hash ); + + + return (*np) ? &(*np)->data + : NULL; + } + + + size_t* + ft_hash_str_lookup( const char* key, + FT_Hash hash ) + { + FT_Hashkey hk; + + + hk.str = key; + + return hash_lookup( hk, hash ); + } + + + size_t* + ft_hash_num_lookup( FT_Int num, + FT_Hash hash ) + { + FT_Hashkey hk; + + + hk.num = num; + + return hash_lookup( hk, hash ); + } + + +/* END */ diff --git a/src/3rdparty/freetype/src/base/ftinit.c b/src/3rdparty/freetype/src/base/ftinit.c index b65a91d06c..1fa4721094 100644 --- a/src/3rdparty/freetype/src/base/ftinit.c +++ b/src/3rdparty/freetype/src/base/ftinit.c @@ -4,7 +4,7 @@ /* */ /* FreeType initialization layer (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -226,6 +226,94 @@ } +#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + +#define MAX_LENGTH 128 + + /* documentation is in ftmodapi.h */ + + FT_EXPORT_DEF( void ) + FT_Set_Default_Properties( FT_Library library ) + { + const char* env; + const char* p; + const char* q; + + char module_name[MAX_LENGTH + 1]; + char property_name[MAX_LENGTH + 1]; + char property_value[MAX_LENGTH + 1]; + + int i; + + + env = ft_getenv( "FREETYPE_PROPERTIES" ); + if ( !env ) + return; + + for ( p = env; *p; p++ ) + { + /* skip leading whitespace and separators */ + if ( *p == ' ' || *p == '\t' ) + continue; + + /* read module name, followed by `:' */ + q = p; + for ( i = 0; i < MAX_LENGTH; i++ ) + { + if ( !*p || *p == ':' ) + break; + module_name[i] = *p++; + } + module_name[i] = '\0'; + + if ( !*p || *p != ':' || p == q ) + break; + + /* read property name, followed by `=' */ + q = ++p; + for ( i = 0; i < MAX_LENGTH; i++ ) + { + if ( !*p || *p == '=' ) + break; + property_name[i] = *p++; + } + property_name[i] = '\0'; + + if ( !*p || *p != '=' || p == q ) + break; + + /* read property value, followed by whitespace (if any) */ + q = ++p; + for ( i = 0; i < MAX_LENGTH; i++ ) + { + if ( !*p || *p == ' ' || *p == '\t' ) + break; + property_value[i] = *p++; + } + property_value[i] = '\0'; + + if ( !( *p == '\0' || *p == ' ' || *p == '\t' ) || p == q ) + break; + + /* we completely ignore errors */ + ft_property_string_set( library, + module_name, + property_name, + property_value ); + } + } + +#else + + FT_EXPORT_DEF( void ) + FT_Set_Default_Properties( FT_Library library ) + { + FT_UNUSED( library ); + } + +#endif + + /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_Error ) @@ -256,6 +344,8 @@ else FT_Add_Default_Modules( *alibrary ); + FT_Set_Default_Properties( *alibrary ); + return error; } diff --git a/src/3rdparty/freetype/src/base/ftlcdfil.c b/src/3rdparty/freetype/src/base/ftlcdfil.c index ff6f7e98ce..8d314df080 100644 --- a/src/3rdparty/freetype/src/base/ftlcdfil.c +++ b/src/3rdparty/freetype/src/base/ftlcdfil.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for color filtering of subpixel bitmap glyphs (body). */ /* */ -/* Copyright 2006-2015 by */ +/* Copyright 2006-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -29,142 +29,140 @@ /* define USE_LEGACY to implement the legacy filter */ #define USE_LEGACY - /* FIR filter used by the default and light filters */ - static void - _ft_lcd_filter_fir( FT_Bitmap* bitmap, - FT_Render_Mode mode, - FT_Library library ) - { - FT_Byte* weights = library->lcd_weights; - FT_UInt width = (FT_UInt)bitmap->width; - FT_UInt height = (FT_UInt)bitmap->rows; +#define FT_SHIFTCLAMP( x ) ( x >>= 8, (FT_Byte)( x > 255 ? 255 : x ) ) + /* add padding according to filter weights */ + FT_BASE_DEF (void) + ft_lcd_padding( FT_Pos* Min, + FT_Pos* Max, + FT_GlyphSlot slot ) + { + FT_Byte* lcd_weights; + FT_Bitmap_LcdFilterFunc lcd_filter_func; + + + /* Per-face LCD filtering takes priority if set up. */ + if ( slot->face && slot->face->internal->lcd_filter_func ) + { + lcd_weights = slot->face->internal->lcd_weights; + lcd_filter_func = slot->face->internal->lcd_filter_func; + } + else + { + lcd_weights = slot->library->lcd_weights; + lcd_filter_func = slot->library->lcd_filter_func; + } + + if ( lcd_filter_func == ft_lcd_filter_fir ) + { + *Min -= lcd_weights[0] ? 43 : + lcd_weights[1] ? 22 : 0; + *Max += lcd_weights[4] ? 43 : + lcd_weights[3] ? 22 : 0; + } + } + + + /* FIR filter used by the default and light filters */ + FT_BASE_DEF( void ) + ft_lcd_filter_fir( FT_Bitmap* bitmap, + FT_Render_Mode mode, + FT_LcdFiveTapFilter weights ) + { + FT_UInt width = (FT_UInt)bitmap->width; + FT_UInt height = (FT_UInt)bitmap->rows; + FT_Int pitch = bitmap->pitch; + FT_Byte* origin = bitmap->buffer; + + + /* take care of bitmap flow */ + if ( pitch > 0 && height > 0 ) + origin += pitch * (FT_Int)( height - 1 ); + /* horizontal in-place FIR filter */ - if ( mode == FT_RENDER_MODE_LCD && width >= 4 ) + if ( mode == FT_RENDER_MODE_LCD && width >= 2 ) { - FT_Byte* line = bitmap->buffer; + FT_Byte* line = origin; - /* take care of bitmap flow */ - if ( bitmap->pitch < 0 ) - line -= bitmap->pitch * (FT_Int)( bitmap->rows - 1 ); + /* `fir' must be at least 32 bit wide, since the sum of */ + /* the values in `weights' can exceed 0xFF */ - /* `fir' and `pix' must be at least 32 bit wide, since the sum of */ - /* the values in `weights' can exceed 0xFF */ - - for ( ; height > 0; height--, line += bitmap->pitch ) + for ( ; height > 0; height--, line -= pitch ) { - FT_UInt fir[4]; /* below, `pix' is used as the 5th element */ - FT_UInt val1, xx; + FT_UInt fir[5]; + FT_UInt val, xx; - val1 = line[0]; - fir[0] = weights[2] * val1; - fir[1] = weights[3] * val1; - fir[2] = weights[4] * val1; - fir[3] = 0; + val = line[0]; + fir[2] = weights[2] * val; + fir[3] = weights[3] * val; + fir[4] = weights[4] * val; - val1 = line[1]; - fir[0] += weights[1] * val1; - fir[1] += weights[2] * val1; - fir[2] += weights[3] * val1; - fir[3] += weights[4] * val1; + val = line[1]; + fir[1] = fir[2] + weights[1] * val; + fir[2] = fir[3] + weights[2] * val; + fir[3] = fir[4] + weights[3] * val; + fir[4] = weights[4] * val; for ( xx = 2; xx < width; xx++ ) { - FT_UInt val, pix; - - val = line[xx]; - pix = fir[0] + weights[0] * val; - fir[0] = fir[1] + weights[1] * val; - fir[1] = fir[2] + weights[2] * val; - fir[2] = fir[3] + weights[3] * val; - fir[3] = weights[4] * val; + fir[0] = fir[1] + weights[0] * val; + fir[1] = fir[2] + weights[1] * val; + fir[2] = fir[3] + weights[2] * val; + fir[3] = fir[4] + weights[3] * val; + fir[4] = weights[4] * val; - pix >>= 8; - pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); - line[xx - 2] = (FT_Byte)pix; + line[xx - 2] = FT_SHIFTCLAMP( fir[0] ); } - { - FT_UInt pix; - - - pix = fir[0] >> 8; - pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); - line[xx - 2] = (FT_Byte)pix; - - pix = fir[1] >> 8; - pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); - line[xx - 1] = (FT_Byte)pix; - } + line[xx - 2] = FT_SHIFTCLAMP( fir[1] ); + line[xx - 1] = FT_SHIFTCLAMP( fir[2] ); } } /* vertical in-place FIR filter */ - else if ( mode == FT_RENDER_MODE_LCD_V && height >= 4 ) + else if ( mode == FT_RENDER_MODE_LCD_V && height >= 2 ) { - FT_Byte* column = bitmap->buffer; - FT_Int pitch = bitmap->pitch; + FT_Byte* column = origin; - /* take care of bitmap flow */ - if ( bitmap->pitch < 0 ) - column -= bitmap->pitch * (FT_Int)( bitmap->rows - 1 ); - for ( ; width > 0; width--, column++ ) { FT_Byte* col = column; - FT_UInt fir[4]; /* below, `pix' is used as the 5th element */ - FT_UInt val1, yy; + FT_UInt fir[5]; + FT_UInt val, yy; - val1 = col[0]; - fir[0] = weights[2] * val1; - fir[1] = weights[3] * val1; - fir[2] = weights[4] * val1; - fir[3] = 0; - col += pitch; + val = col[0]; + fir[2] = weights[2] * val; + fir[3] = weights[3] * val; + fir[4] = weights[4] * val; + col -= pitch; - val1 = col[0]; - fir[0] += weights[1] * val1; - fir[1] += weights[2] * val1; - fir[2] += weights[3] * val1; - fir[3] += weights[4] * val1; - col += pitch; + val = col[0]; + fir[1] = fir[2] + weights[1] * val; + fir[2] = fir[3] + weights[2] * val; + fir[3] = fir[4] + weights[3] * val; + fir[4] = weights[4] * val; + col -= pitch; - for ( yy = 2; yy < height; yy++ ) + for ( yy = 2; yy < height; yy++, col -= pitch ) { - FT_UInt val, pix; - - val = col[0]; - pix = fir[0] + weights[0] * val; - fir[0] = fir[1] + weights[1] * val; - fir[1] = fir[2] + weights[2] * val; - fir[2] = fir[3] + weights[3] * val; - fir[3] = weights[4] * val; + fir[0] = fir[1] + weights[0] * val; + fir[1] = fir[2] + weights[1] * val; + fir[2] = fir[3] + weights[2] * val; + fir[3] = fir[4] + weights[3] * val; + fir[4] = weights[4] * val; - pix >>= 8; - pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); - col[-2 * pitch] = (FT_Byte)pix; - col += pitch; + col[pitch * 2] = FT_SHIFTCLAMP( fir[0] ); } - { - FT_UInt pix; - - - pix = fir[0] >> 8; - pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); - col[-2 * pitch] = (FT_Byte)pix; - - pix = fir[1] >> 8; - pix |= (FT_UInt)-(FT_Int)( pix >> 8 ); - col[-pitch] = (FT_Byte)pix; - } + col[pitch * 2] = FT_SHIFTCLAMP( fir[1] ); + col[pitch] = FT_SHIFTCLAMP( fir[2] ); } } } @@ -176,11 +174,12 @@ static void _ft_lcd_filter_legacy( FT_Bitmap* bitmap, FT_Render_Mode mode, - FT_Library library ) + FT_Byte* weights ) { - FT_UInt width = (FT_UInt)bitmap->width; - FT_UInt height = (FT_UInt)bitmap->rows; - FT_Int pitch = bitmap->pitch; + FT_UInt width = (FT_UInt)bitmap->width; + FT_UInt height = (FT_UInt)bitmap->rows; + FT_Int pitch = bitmap->pitch; + FT_Byte* origin = bitmap->buffer; static const unsigned int filters[3][3] = { @@ -189,36 +188,34 @@ { 65538 * 1/13, 65538 * 1/6, 65538 * 9/13 } }; - FT_UNUSED( library ); + FT_UNUSED( weights ); + /* take care of bitmap flow */ + if ( pitch > 0 && height > 0 ) + origin += pitch * (FT_Int)( height - 1 ); + /* horizontal in-place intra-pixel filter */ if ( mode == FT_RENDER_MODE_LCD && width >= 3 ) { - FT_Byte* line = bitmap->buffer; + FT_Byte* line = origin; - /* take care of bitmap flow */ - if ( bitmap->pitch < 0 ) - line -= bitmap->pitch * (FT_Int)( bitmap->rows - 1 ); - - for ( ; height > 0; height--, line += pitch ) + for ( ; height > 0; height--, line -= pitch ) { FT_UInt xx; for ( xx = 0; xx < width; xx += 3 ) { - FT_UInt r = 0; - FT_UInt g = 0; - FT_UInt b = 0; + FT_UInt r, g, b; FT_UInt p; p = line[xx]; - r += filters[0][0] * p; - g += filters[0][1] * p; - b += filters[0][2] * p; + r = filters[0][0] * p; + g = filters[0][1] * p; + b = filters[0][2] * p; p = line[xx + 1]; r += filters[1][0] * p; @@ -238,31 +235,24 @@ } else if ( mode == FT_RENDER_MODE_LCD_V && height >= 3 ) { - FT_Byte* column = bitmap->buffer; + FT_Byte* column = origin; - /* take care of bitmap flow */ - if ( bitmap->pitch < 0 ) - column -= bitmap->pitch * (FT_Int)( bitmap->rows - 1 ); - for ( ; width > 0; width--, column++ ) { - FT_Byte* col = column; - FT_Byte* col_end = col + (FT_Int)height * pitch; + FT_Byte* col = column - 2 * pitch; - for ( ; col < col_end; col += 3 * pitch ) + for ( ; height > 0; height -= 3, col -= 3 * pitch ) { - FT_UInt r = 0; - FT_UInt g = 0; - FT_UInt b = 0; + FT_UInt r, g, b; FT_UInt p; p = col[0]; - r += filters[0][0] * p; - g += filters[0][1] * p; - b += filters[0][2] * p; + r = filters[0][0] * p; + g = filters[0][1] * p; + b = filters[0][2] * p; p = col[pitch]; r += filters[1][0] * p; @@ -276,7 +266,7 @@ col[0] = (FT_Byte)( r / 65536 ); col[pitch] = (FT_Byte)( g / 65536 ); - col[2 * pitch] = (FT_Byte)( b / 65536 ); + col[pitch * 2] = (FT_Byte)( b / 65536 ); } } } @@ -295,7 +285,8 @@ if ( !weights ) return FT_THROW( Invalid_Argument ); - ft_memcpy( library->lcd_weights, weights, 5 ); + ft_memcpy( library->lcd_weights, weights, FT_LCD_FILTER_FIVE_TAPS ); + library->lcd_filter_func = ft_lcd_filter_fir; return FT_Err_Ok; } @@ -305,12 +296,10 @@ FT_Library_SetLcdFilter( FT_Library library, FT_LcdFilter filter ) { - static const FT_Byte light_filter[5] = - { 0x00, 0x55, 0x56, 0x55, 0x00 }; - /* the values here sum up to a value larger than 256, */ - /* providing a cheap gamma correction */ - static const FT_Byte default_filter[5] = - { 0x10, 0x40, 0x70, 0x40, 0x10 }; + static const FT_LcdFiveTapFilter default_weights = + { 0x08, 0x4d, 0x56, 0x4d, 0x08 }; + static const FT_LcdFiveTapFilter light_weights = + { 0x00, 0x55, 0x56, 0x55, 0x00 }; if ( !library ) @@ -320,42 +309,27 @@ { case FT_LCD_FILTER_NONE: library->lcd_filter_func = NULL; - library->lcd_extra = 0; break; case FT_LCD_FILTER_DEFAULT: -#if defined( FT_FORCE_LEGACY_LCD_FILTER ) - - library->lcd_filter_func = _ft_lcd_filter_legacy; - library->lcd_extra = 0; - -#elif defined( FT_FORCE_LIGHT_LCD_FILTER ) - - ft_memcpy( library->lcd_weights, light_filter, 5 ); - library->lcd_filter_func = _ft_lcd_filter_fir; - library->lcd_extra = 2; - -#else - - ft_memcpy( library->lcd_weights, default_filter, 5 ); - library->lcd_filter_func = _ft_lcd_filter_fir; - library->lcd_extra = 2; - -#endif - + ft_memcpy( library->lcd_weights, + default_weights, + FT_LCD_FILTER_FIVE_TAPS ); + library->lcd_filter_func = ft_lcd_filter_fir; break; case FT_LCD_FILTER_LIGHT: - ft_memcpy( library->lcd_weights, light_filter, 5 ); - library->lcd_filter_func = _ft_lcd_filter_fir; - library->lcd_extra = 2; + ft_memcpy( library->lcd_weights, + light_weights, + FT_LCD_FILTER_FIVE_TAPS ); + library->lcd_filter_func = ft_lcd_filter_fir; break; #ifdef USE_LEGACY case FT_LCD_FILTER_LEGACY: + case FT_LCD_FILTER_LEGACY1: library->lcd_filter_func = _ft_lcd_filter_legacy; - library->lcd_extra = 0; break; #endif @@ -364,13 +338,24 @@ return FT_THROW( Invalid_Argument ); } - library->lcd_filter = filter; - return FT_Err_Ok; } #else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ + /* add padding according to accommodate outline shifts */ + FT_BASE_DEF (void) + ft_lcd_padding( FT_Pos* Min, + FT_Pos* Max, + FT_GlyphSlot slot ) + { + FT_UNUSED( slot ); + + *Min -= 21; + *Max += 21; + } + + FT_EXPORT_DEF( FT_Error ) FT_Library_SetLcdFilterWeights( FT_Library library, unsigned char *weights ) diff --git a/src/3rdparty/freetype/src/base/ftmac.c b/src/3rdparty/freetype/src/base/ftmac.c index 114bbb6391..fd4c0cc274 100644 --- a/src/3rdparty/freetype/src/base/ftmac.c +++ b/src/3rdparty/freetype/src/base/ftmac.c @@ -8,7 +8,7 @@ /* This file is for Mac OS X only; see builds/mac/ftoldmac.c for */ /* classic platforms built by MPW. */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -71,6 +71,9 @@ #include FT_INTERNAL_STREAM_H #include "ftbase.h" + +#ifdef FT_MACINTOSH + /* This is for Mac OS X. Without redefinition, OS_INLINE */ /* expands to `static inline' which doesn't survive the */ /* -ansi compilation flag of GCC. */ @@ -118,8 +121,6 @@ #endif -#ifdef FT_MACINTOSH - /* This function is deprecated because FSSpec is deprecated in Mac OS X */ FT_EXPORT_DEF( FT_Error ) FT_GetFile_From_Mac_Name( const char* fontName, @@ -228,7 +229,7 @@ if ( !fontName || !face_index ) - return FT_THROW( Invalid_Argument) ; + return FT_THROW( Invalid_Argument); err = FT_GetFileRef_From_Mac_ATS_Name( fontName, &ref, face_index ); if ( err ) @@ -605,7 +606,7 @@ for (;;) { post_data = Get1Resource( TTAG_POST, res_id++ ); - if ( post_data == NULL ) + if ( !post_data ) break; /* we are done */ code = (*post_data)[0]; @@ -644,7 +645,7 @@ for (;;) { post_data = Get1Resource( TTAG_POST, res_id++ ); - if ( post_data == NULL ) + if ( !post_data ) break; /* we are done */ post_size = (FT_ULong)GetHandleSize( post_data ) - 2; @@ -655,7 +656,7 @@ if ( last_code != -1 ) { /* we are done adding a chunk, fill in the size field */ - if ( size_p != NULL ) + if ( size_p ) { *size_p++ = (FT_Byte)( pfb_chunk_size & 0xFF ); *size_p++ = (FT_Byte)( ( pfb_chunk_size >> 8 ) & 0xFF ); @@ -743,7 +744,7 @@ sfnt = GetResource( TTAG_sfnt, sfnt_id ); - if ( sfnt == NULL ) + if ( !sfnt ) return FT_THROW( Invalid_Handle ); sfnt_size = (FT_ULong)GetHandleSize( sfnt ); @@ -821,7 +822,7 @@ return FT_THROW( Cannot_Open_Resource ); num_faces_in_res = 0; - for ( res_index = 1; ; ++res_index ) + for ( res_index = 1; ; res_index++ ) { short num_faces_in_fond; @@ -942,13 +943,14 @@ /* if it works, fine. */ error = FT_New_Face_From_Suitcase( library, pathname, face_index, aface ); - if ( error == 0 ) - return error; + if ( error ) + { + /* let it fall through to normal loader (.ttf, .otf, etc.); */ + /* we signal this by returning no error and no FT_Face */ + *aface = NULL; + } - /* let it fall through to normal loader (.ttf, .otf, etc.); */ - /* we signal this by returning no error and no FT_Face */ - *aface = NULL; - return 0; + return FT_Err_Ok; } @@ -982,12 +984,13 @@ /* try resourcefork based font: LWFN, FFIL */ error = FT_New_Face_From_Resource( library, (UInt8 *)pathname, face_index, aface ); - if ( error != 0 || *aface != NULL ) + if ( error || *aface ) return error; /* let it fall through to normal loader (.ttf, .otf, etc.) */ args.flags = FT_OPEN_PATHNAME; args.pathname = (char*)pathname; + return FT_Open_Face( library, &args, face_index, aface ); } @@ -1002,7 +1005,7 @@ /* accepts an FSRef instead of a path. */ /* */ /* This function is deprecated because Carbon data types (FSRef) */ - /* are not cross-platform, and thus not suitable for the freetype API. */ + /* are not cross-platform, and thus not suitable for the FreeType API. */ FT_EXPORT_DEF( FT_Error ) FT_New_Face_From_FSRef( FT_Library library, const FSRef* ref, @@ -1027,7 +1030,7 @@ error = FT_THROW( Cannot_Open_Resource ); error = FT_New_Face_From_Resource( library, pathname, face_index, aface ); - if ( error != 0 || *aface != NULL ) + if ( error || *aface ) return error; /* fallback to datafork font */ @@ -1074,7 +1077,12 @@ #endif } -#endif /* FT_MACINTOSH */ +#else /* !FT_MACINTOSH */ + + /* ANSI C doesn't like empty source files */ + typedef int _ft_mac_dummy; + +#endif /* !FT_MACINTOSH */ /* END */ diff --git a/src/3rdparty/freetype/src/base/ftmm.c b/src/3rdparty/freetype/src/base/ftmm.c index 7c012aa438..800441bcac 100644 --- a/src/3rdparty/freetype/src/base/ftmm.c +++ b/src/3rdparty/freetype/src/base/ftmm.c @@ -4,7 +4,7 @@ /* */ /* Multiple Master font support (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,6 +22,7 @@ #include FT_MULTIPLE_MASTERS_H #include FT_INTERNAL_OBJECTS_H #include FT_SERVICE_MULTIPLE_MASTERS_H +#include FT_SERVICE_METRICS_VARIATIONS_H /*************************************************************************/ @@ -62,6 +63,34 @@ } + static FT_Error + ft_face_get_mvar_service( FT_Face face, + FT_Service_MetricsVariations *aservice ) + { + FT_Error error; + + + *aservice = NULL; + + if ( !face ) + return FT_THROW( Invalid_Face_Handle ); + + error = FT_ERR( Invalid_Argument ); + + if ( FT_HAS_MULTIPLE_MASTERS( face ) ) + { + FT_FACE_LOOKUP_SERVICE( face, + *aservice, + METRICS_VARIATIONS ); + + if ( *aservice ) + error = FT_Err_Ok; + } + + return error; + } + + /* documentation is in ftmm.h */ FT_EXPORT_DEF( FT_Error ) @@ -116,6 +145,25 @@ } + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Done_MM_Var( FT_Library library, + FT_MM_Var* amaster ) + { + FT_Memory memory; + + + if ( !library ) + return FT_THROW( Invalid_Library_Handle ); + + memory = library->memory; + FT_FREE( amaster ); + + return FT_Err_Ok; + } + + /* documentation is in ftmm.h */ FT_EXPORT_DEF( FT_Error ) @@ -129,7 +177,7 @@ /* check of `face' delayed to `ft_face_get_mm_service' */ - if ( !coords ) + if ( num_coords && !coords ) return FT_THROW( Invalid_Argument ); error = ft_face_get_mm_service( face, &service ); @@ -140,6 +188,13 @@ error = service->set_mm_design( face, num_coords, coords ); } + /* enforce recomputation of auto-hinting data */ + if ( !error && face->autohint.finalizer ) + { + face->autohint.finalizer( face->autohint.data ); + face->autohint.data = NULL; + } + return error; } @@ -150,6 +205,54 @@ FT_Set_Var_Design_Coordinates( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ) + { + FT_Error error; + FT_Service_MultiMasters service_mm = NULL; + FT_Service_MetricsVariations service_mvar = NULL; + + + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( num_coords && !coords ) + return FT_THROW( Invalid_Argument ); + + error = ft_face_get_mm_service( face, &service_mm ); + if ( !error ) + { + error = FT_ERR( Invalid_Argument ); + if ( service_mm->set_var_design ) + error = service_mm->set_var_design( face, num_coords, coords ); + + /* internal error code -1 means `no change'; we can exit immediately */ + if ( error == -1 ) + return FT_Err_Ok; + } + + if ( !error ) + { + (void)ft_face_get_mvar_service( face, &service_mvar ); + + if ( service_mvar && service_mvar->metrics_adjust ) + service_mvar->metrics_adjust( face ); + } + + /* enforce recomputation of auto-hinting data */ + if ( !error && face->autohint.finalizer ) + { + face->autohint.finalizer( face->autohint.data ); + face->autohint.data = NULL; + } + + return error; + } + + + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Var_Design_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) { FT_Error error; FT_Service_MultiMasters service; @@ -164,8 +267,8 @@ if ( !error ) { error = FT_ERR( Invalid_Argument ); - if ( service->set_var_design ) - error = service->set_var_design( face, num_coords, coords ); + if ( service->get_var_design ) + error = service->get_var_design( face, num_coords, coords ); } return error; @@ -179,21 +282,41 @@ FT_UInt num_coords, FT_Fixed* coords ) { - FT_Error error; - FT_Service_MultiMasters service; + FT_Error error; + FT_Service_MultiMasters service_mm = NULL; + FT_Service_MetricsVariations service_mvar = NULL; /* check of `face' delayed to `ft_face_get_mm_service' */ - if ( !coords ) + if ( num_coords && !coords ) return FT_THROW( Invalid_Argument ); - error = ft_face_get_mm_service( face, &service ); + error = ft_face_get_mm_service( face, &service_mm ); if ( !error ) { error = FT_ERR( Invalid_Argument ); - if ( service->set_mm_blend ) - error = service->set_mm_blend( face, num_coords, coords ); + if ( service_mm->set_mm_blend ) + error = service_mm->set_mm_blend( face, num_coords, coords ); + + /* internal error code -1 means `no change'; we can exit immediately */ + if ( error == -1 ) + return FT_Err_Ok; + } + + if ( !error ) + { + (void)ft_face_get_mvar_service( face, &service_mvar ); + + if ( service_mvar && service_mvar->metrics_adjust ) + service_mvar->metrics_adjust( face ); + } + + /* enforce recomputation of auto-hinting data */ + if ( !error && face->autohint.finalizer ) + { + face->autohint.finalizer( face->autohint.data ); + face->autohint.data = NULL; } return error; @@ -209,6 +332,54 @@ FT_Set_Var_Blend_Coordinates( FT_Face face, FT_UInt num_coords, FT_Fixed* coords ) + { + FT_Error error; + FT_Service_MultiMasters service_mm = NULL; + FT_Service_MetricsVariations service_mvar = NULL; + + + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( num_coords && !coords ) + return FT_THROW( Invalid_Argument ); + + error = ft_face_get_mm_service( face, &service_mm ); + if ( !error ) + { + error = FT_ERR( Invalid_Argument ); + if ( service_mm->set_mm_blend ) + error = service_mm->set_mm_blend( face, num_coords, coords ); + + /* internal error code -1 means `no change'; we can exit immediately */ + if ( error == -1 ) + return FT_Err_Ok; + } + + if ( !error ) + { + (void)ft_face_get_mvar_service( face, &service_mvar ); + + if ( service_mvar && service_mvar->metrics_adjust ) + service_mvar->metrics_adjust( face ); + } + + /* enforce recomputation of auto-hinting data */ + if ( !error && face->autohint.finalizer ) + { + face->autohint.finalizer( face->autohint.data ); + face->autohint.data = NULL; + } + + return error; + } + + + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_MM_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) { FT_Error error; FT_Service_MultiMasters service; @@ -223,8 +394,111 @@ if ( !error ) { error = FT_ERR( Invalid_Argument ); - if ( service->set_mm_blend ) - error = service->set_mm_blend( face, num_coords, coords ); + if ( service->get_mm_blend ) + error = service->get_mm_blend( face, num_coords, coords ); + } + + return error; + } + + + /* documentation is in ftmm.h */ + + /* This is exactly the same as the previous function. It exists for */ + /* orthogonality. */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Var_Blend_Coordinates( FT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Error error; + FT_Service_MultiMasters service; + + + /* check of `face' delayed to `ft_face_get_mm_service' */ + + if ( !coords ) + return FT_THROW( Invalid_Argument ); + + error = ft_face_get_mm_service( face, &service ); + if ( !error ) + { + error = FT_ERR( Invalid_Argument ); + if ( service->get_mm_blend ) + error = service->get_mm_blend( face, num_coords, coords ); + } + + return error; + } + + + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Var_Axis_Flags( FT_MM_Var* master, + FT_UInt axis_index, + FT_UInt* flags ) + { + FT_UShort* axis_flags; + + + if ( !master || !flags ) + return FT_THROW( Invalid_Argument ); + + if ( axis_index >= master->num_axis ) + return FT_THROW( Invalid_Argument ); + + /* the axis flags array immediately follows the data of `master' */ + axis_flags = (FT_UShort*)&( master[1] ); + *flags = axis_flags[axis_index]; + + return FT_Err_Ok; + } + + + /* documentation is in ftmm.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Set_Named_Instance( FT_Face face, + FT_UInt instance_index ) + { + FT_Error error; + + FT_Service_MultiMasters service_mm = NULL; + FT_Service_MetricsVariations service_mvar = NULL; + + + /* check of `face' delayed to `ft_face_get_mm_service' */ + + error = ft_face_get_mm_service( face, &service_mm ); + if ( !error ) + { + error = FT_ERR( Invalid_Argument ); + if ( service_mm->set_instance ) + error = service_mm->set_instance( face, instance_index ); + } + + if ( !error ) + { + (void)ft_face_get_mvar_service( face, &service_mvar ); + + if ( service_mvar && service_mvar->metrics_adjust ) + service_mvar->metrics_adjust( face ); + } + + /* enforce recomputation of auto-hinting data */ + if ( !error && face->autohint.finalizer ) + { + face->autohint.finalizer( face->autohint.data ); + face->autohint.data = NULL; + } + + if ( !error ) + { + face->face_index = ( instance_index << 16 ) | + ( face->face_index & 0xFFFFL ); + face->face_flags &= ~FT_FACE_FLAG_VARIATION; } return error; diff --git a/src/3rdparty/freetype/src/base/ftobjs.c b/src/3rdparty/freetype/src/base/ftobjs.c index f0c2e77fcc..8d07e35ae3 100644 --- a/src/3rdparty/freetype/src/base/ftobjs.c +++ b/src/3rdparty/freetype/src/base/ftobjs.c @@ -4,7 +4,7 @@ /* */ /* The FreeType private base classes (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,12 +19,16 @@ #include <ft2build.h> #include FT_LIST_H #include FT_OUTLINE_H +#include FT_FONT_FORMATS_H + #include FT_INTERNAL_VALIDATE_H #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_RFORK_H #include FT_INTERNAL_STREAM_H -#include FT_INTERNAL_SFNT_H /* for SFNT_Load_Table_Func */ +#include FT_INTERNAL_SFNT_H /* for SFNT_Load_Table_Func */ +#include FT_INTERNAL_POSTSCRIPT_AUX_H /* for PS_Driver */ + #include FT_TRUETYPE_TABLES_H #include FT_TRUETYPE_TAGS_H #include FT_TRUETYPE_IDS_H @@ -37,6 +41,8 @@ #include FT_SERVICE_KERNING_H #include FT_SERVICE_TRUETYPE_ENGINE_H +#include FT_DRIVER_H + #ifdef FT_CONFIG_OPTION_MAC_FONTS #include "ftbase.h" #endif @@ -55,7 +61,18 @@ #pragma warning( disable : 4244 ) #endif /* _MSC_VER */ - /* it's easiest to include `md5.c' directly */ + /* It's easiest to include `md5.c' directly. However, since OpenSSL */ + /* also provides the same functions, there might be conflicts if */ + /* both FreeType and OpenSSL are built as static libraries. For */ + /* this reason, we put the MD5 stuff into the `FT_' namespace. */ +#define MD5_u32plus FT_MD5_u32plus +#define MD5_CTX FT_MD5_CTX +#define MD5_Init FT_MD5_Init +#define MD5_Update FT_MD5_Update +#define MD5_Final FT_MD5_Final + +#undef HAVE_OPENSSL + #include "md5.c" #if defined( _MSC_VER ) @@ -68,6 +85,15 @@ #define GRID_FIT_METRICS + /* forward declaration */ + static FT_Error + ft_open_face_internal( FT_Library library, + const FT_Open_Args* args, + FT_Long face_index, + FT_Face *aface, + FT_Bool test_mac_fonts ); + + FT_BASE_DEF( FT_Pointer ) ft_service_list_lookup( FT_ServiceDesc service_descriptors, const char* service_id ) @@ -304,6 +330,138 @@ } + FT_BASE_DEF( void ) + ft_glyphslot_preset_bitmap( FT_GlyphSlot slot, + FT_Render_Mode mode, + const FT_Vector* origin ) + { + FT_Outline* outline = &slot->outline; + FT_Bitmap* bitmap = &slot->bitmap; + + FT_Pixel_Mode pixel_mode; + + FT_BBox cbox; + FT_Pos x_shift = 0; + FT_Pos y_shift = 0; + FT_Pos x_left, y_top; + FT_Pos width, height, pitch; + + + if ( slot->internal && ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) ) + return; + + if ( origin ) + { + x_shift = origin->x; + y_shift = origin->y; + } + + /* compute the control box, and grid-fit it, */ + /* taking into account the origin shift */ + FT_Outline_Get_CBox( outline, &cbox ); + + cbox.xMin += x_shift; + cbox.yMin += y_shift; + cbox.xMax += x_shift; + cbox.yMax += y_shift; + + switch ( mode ) + { + case FT_RENDER_MODE_MONO: + pixel_mode = FT_PIXEL_MODE_MONO; +#if 1 + /* undocumented but confirmed: bbox values get rounded */ + /* unless the rounded box can collapse for a narrow glyph */ + if ( cbox.xMax - cbox.xMin < 64 ) + { + cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); + cbox.xMax = FT_PIX_CEIL_LONG( cbox.xMax ); + } + else + { + cbox.xMin = FT_PIX_ROUND_LONG( cbox.xMin ); + cbox.xMax = FT_PIX_ROUND_LONG( cbox.xMax ); + } + + if ( cbox.yMax - cbox.yMin < 64 ) + { + cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); + cbox.yMax = FT_PIX_CEIL_LONG( cbox.yMax ); + } + else + { + cbox.yMin = FT_PIX_ROUND_LONG( cbox.yMin ); + cbox.yMax = FT_PIX_ROUND_LONG( cbox.yMax ); + } +#else + cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); + cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); + cbox.xMax = FT_PIX_CEIL_LONG( cbox.xMax ); + cbox.yMax = FT_PIX_CEIL_LONG( cbox.yMax ); +#endif + break; + + case FT_RENDER_MODE_LCD: + pixel_mode = FT_PIXEL_MODE_LCD; + ft_lcd_padding( &cbox.xMin, &cbox.xMax, slot ); + goto Round; + + case FT_RENDER_MODE_LCD_V: + pixel_mode = FT_PIXEL_MODE_LCD_V; + ft_lcd_padding( &cbox.yMin, &cbox.yMax, slot ); + goto Round; + + case FT_RENDER_MODE_NORMAL: + case FT_RENDER_MODE_LIGHT: + default: + pixel_mode = FT_PIXEL_MODE_GRAY; + Round: + cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); + cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); + cbox.xMax = FT_PIX_CEIL_LONG( cbox.xMax ); + cbox.yMax = FT_PIX_CEIL_LONG( cbox.yMax ); + } + + x_shift = SUB_LONG( x_shift, cbox.xMin ); + y_shift = SUB_LONG( y_shift, cbox.yMin ); + + x_left = cbox.xMin >> 6; + y_top = cbox.yMax >> 6; + + width = ( (FT_ULong)cbox.xMax - (FT_ULong)cbox.xMin ) >> 6; + height = ( (FT_ULong)cbox.yMax - (FT_ULong)cbox.yMin ) >> 6; + + switch ( pixel_mode ) + { + case FT_PIXEL_MODE_MONO: + pitch = ( ( width + 15 ) >> 4 ) << 1; + break; + + case FT_PIXEL_MODE_LCD: + width *= 3; + pitch = FT_PAD_CEIL( width, 4 ); + break; + + case FT_PIXEL_MODE_LCD_V: + height *= 3; + /* fall through */ + + case FT_PIXEL_MODE_GRAY: + default: + pitch = width; + } + + slot->bitmap_left = (FT_Int)x_left; + slot->bitmap_top = (FT_Int)y_top; + + bitmap->pixel_mode = (unsigned char)pixel_mode; + bitmap->num_grays = 256; + bitmap->width = (unsigned int)width; + bitmap->rows = (unsigned int)height; + bitmap->pitch = pitch; + } + + FT_BASE_DEF( void ) ft_glyphslot_set_bitmap( FT_GlyphSlot slot, FT_Byte* buffer ) @@ -442,7 +600,8 @@ Exit: - FT_TRACE4(( "FT_New_GlyphSlot: Return %d\n", error )); + FT_TRACE4(( "FT_New_GlyphSlot: Return 0x%x\n", error )); + return error; } @@ -555,34 +714,42 @@ if ( vertical ) { metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX ); - metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY ); + metrics->horiBearingY = FT_PIX_CEIL_LONG( metrics->horiBearingY ); - right = FT_PIX_CEIL( metrics->vertBearingX + metrics->width ); - bottom = FT_PIX_CEIL( metrics->vertBearingY + metrics->height ); + right = FT_PIX_CEIL_LONG( ADD_LONG( metrics->vertBearingX, + metrics->width ) ); + bottom = FT_PIX_CEIL_LONG( ADD_LONG( metrics->vertBearingY, + metrics->height ) ); metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX ); metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY ); - metrics->width = right - metrics->vertBearingX; - metrics->height = bottom - metrics->vertBearingY; + metrics->width = SUB_LONG( right, + metrics->vertBearingX ); + metrics->height = SUB_LONG( bottom, + metrics->vertBearingY ); } else { metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX ); metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY ); - right = FT_PIX_CEIL ( metrics->horiBearingX + metrics->width ); - bottom = FT_PIX_FLOOR( metrics->horiBearingY - metrics->height ); + right = FT_PIX_CEIL_LONG( ADD_LONG( metrics->horiBearingX, + metrics->width ) ); + bottom = FT_PIX_FLOOR( SUB_LONG( metrics->horiBearingY, + metrics->height ) ); metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX ); - metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY ); + metrics->horiBearingY = FT_PIX_CEIL_LONG( metrics->horiBearingY ); - metrics->width = right - metrics->horiBearingX; - metrics->height = metrics->horiBearingY - bottom; + metrics->width = SUB_LONG( right, + metrics->horiBearingX ); + metrics->height = SUB_LONG( metrics->horiBearingY, + bottom ); } - metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance ); - metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance ); + metrics->horiAdvance = FT_PIX_ROUND_LONG( metrics->horiAdvance ); + metrics->vertAdvance = FT_PIX_ROUND_LONG( metrics->vertAdvance ); } #endif /* GRID_FIT_METRICS */ @@ -630,13 +797,20 @@ load_flags &= ~FT_LOAD_RENDER; } + if ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) + load_flags &= ~FT_LOAD_RENDER; + /* * Determine whether we need to auto-hint or not. * The general rules are: * - * - Do only auto-hinting if we have a hinter module, a scalable font - * format dealing with outlines, and no transforms except simple - * slants and/or rotations by integer multiples of 90 degrees. + * - Do only auto-hinting if we have + * + * - a hinter module, + * - a scalable font format dealing with outlines, + * - not a tricky font, and + * - no transforms except simple slants and/or rotations by + * integer multiples of 90 degrees. * * - Then, auto-hint if FT_LOAD_FORCE_AUTOHINT is set or if we don't * have a native font hinter. @@ -666,8 +840,15 @@ else { FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags ); + FT_Bool is_light_type1; + /* only the new Adobe engine (for both CFF and Type 1) is `light'; */ + /* we use `strstr' to catch both `Type 1' and `CID Type 1' */ + is_light_type1 = + ft_strstr( FT_Get_Font_Format( face ), "Type 1" ) != NULL && + ((PS_Driver)driver)->hinting_engine == FT_HINTING_ADOBE; + /* the check for `num_locations' assures that we actually */ /* test for instructions in a TTF and not in a CFF-based OTF */ /* */ @@ -675,8 +856,9 @@ /* check the size of the `fpgm' and `prep' tables, too -- */ /* the assumption is that there don't exist real TTFs where */ /* both `fpgm' and `prep' tables are missing */ - if ( mode == FT_RENDER_MODE_LIGHT || - face->internal->ignore_unpatented_hinter || + if ( ( mode == FT_RENDER_MODE_LIGHT && + ( !FT_DRIVER_HINTS_LIGHTLY( driver ) && + !is_light_type1 ) ) || ( FT_IS_SFNT( face ) && ttface->num_locations && ttface->max_profile.maxSizeOfInstructions == 0 && @@ -696,8 +878,8 @@ /* XXX: This is really a temporary hack that should disappear */ /* promptly with FreeType 2.1! */ /* */ - if ( FT_HAS_FIXED_SIZES( face ) && - ( load_flags & FT_LOAD_NO_BITMAP ) == 0 ) + if ( FT_HAS_FIXED_SIZES( face ) && + ( load_flags & FT_LOAD_NO_BITMAP ) == 0 ) { error = driver->clazz->load_glyph( slot, face->size, glyph_index, @@ -765,7 +947,7 @@ /* compute the linear advance in 16.16 pixels */ if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 && - ( FT_IS_SCALABLE( face ) ) ) + FT_IS_SCALABLE( face ) ) { FT_Size_Metrics* metrics = &face->size->metrics; @@ -813,28 +995,37 @@ } } - FT_TRACE5(( " x advance: %d\n" , slot->advance.x )); - FT_TRACE5(( " y advance: %d\n" , slot->advance.y )); - - FT_TRACE5(( " linear x advance: %d\n" , slot->linearHoriAdvance )); - FT_TRACE5(( " linear y advance: %d\n" , slot->linearVertAdvance )); - - /* do we need to render the image now? */ + /* do we need to render the image or preset the bitmap now? */ if ( !error && + ( load_flags & FT_LOAD_NO_SCALE ) == 0 && slot->format != FT_GLYPH_FORMAT_BITMAP && - slot->format != FT_GLYPH_FORMAT_COMPOSITE && - load_flags & FT_LOAD_RENDER ) + slot->format != FT_GLYPH_FORMAT_COMPOSITE ) { FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags ); - if ( mode == FT_RENDER_MODE_NORMAL && - (load_flags & FT_LOAD_MONOCHROME ) ) + if ( mode == FT_RENDER_MODE_NORMAL && + load_flags & FT_LOAD_MONOCHROME ) mode = FT_RENDER_MODE_MONO; - error = FT_Render_Glyph( slot, mode ); + if ( load_flags & FT_LOAD_RENDER ) + error = FT_Render_Glyph( slot, mode ); + else + ft_glyphslot_preset_bitmap( slot, mode, NULL ); } + FT_TRACE5(( "FT_Load_Glyph: index %d, flags %x\n", + glyph_index, load_flags )); + FT_TRACE5(( " x advance: %f\n", slot->advance.x / 64.0 )); + FT_TRACE5(( " y advance: %f\n", slot->advance.y / 64.0 )); + FT_TRACE5(( " linear x advance: %f\n", + slot->linearHoriAdvance / 65536.0 )); + FT_TRACE5(( " linear y advance: %f\n", + slot->linearVertAdvance / 65536.0 )); + FT_TRACE5(( " bitmap %dx%d, mode %d\n", + slot->bitmap.width, slot->bitmap.rows, + slot->bitmap.pixel_mode )); + Exit: return error; } @@ -1091,7 +1282,7 @@ end = first + face->num_charmaps; /* points after the last one */ - for ( cur = first; cur < end; ++cur ) + for ( cur = first; cur < end; cur++ ) { if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE && cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR && @@ -1162,6 +1353,8 @@ } #endif + face->internal->random_seed = -1; + if ( clazz->init_face ) error = clazz->init_face( *astream, face, @@ -1226,7 +1419,7 @@ args.pathname = (char*)pathname; args.stream = NULL; - return FT_Open_Face( library, &args, face_index, aface ); + return ft_open_face_internal( library, &args, face_index, aface, 1 ); } #endif @@ -1253,7 +1446,7 @@ args.memory_size = file_size; args.stream = NULL; - return FT_Open_Face( library, &args, face_index, aface ); + return ft_open_face_internal( library, &args, face_index, aface, 1 ); } @@ -1288,7 +1481,7 @@ /* Finalizer for a memory stream; gets called by FT_Done_Face(). */ /* It frees the memory it uses. */ - /* From ftmac.c. */ + /* From `ftmac.c'. */ static void memory_stream_close( FT_Stream stream ) { @@ -1304,7 +1497,7 @@ /* Create a new memory stream from a buffer and a size. */ - /* From ftmac.c. */ + /* From `ftmac.c'. */ static FT_Error new_memory_stream( FT_Library library, FT_Byte* base, @@ -1324,7 +1517,7 @@ return FT_THROW( Invalid_Argument ); *astream = NULL; - memory = library->memory; + memory = library->memory; if ( FT_NEW( stream ) ) goto Exit; @@ -1340,7 +1533,7 @@ /* Create a new FT_Face given a buffer and a driver name. */ - /* from ftmac.c */ + /* From `ftmac.c'. */ FT_LOCAL_DEF( FT_Error ) open_face_from_buffer( FT_Library library, FT_Byte* base, @@ -1366,11 +1559,11 @@ return error; } - args.flags = FT_OPEN_STREAM; + args.flags = FT_OPEN_STREAM; args.stream = stream; if ( driver_name ) { - args.flags = args.flags | FT_OPEN_DRIVER; + args.flags = args.flags | FT_OPEN_DRIVER; args.driver = FT_Get_Module( library, driver_name ); } @@ -1384,9 +1577,9 @@ face_index &= 0x7FFF0000L; /* retain GX data */ #endif - error = FT_Open_Face( library, &args, face_index, aface ); + error = ft_open_face_internal( library, &args, face_index, aface, 0 ); - if ( error == FT_Err_Ok ) + if ( !error ) (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; else #ifdef FT_MACINTOSH @@ -1407,7 +1600,7 @@ /* Type 1 and CID-keyed font drivers should recognize sfnt-wrapped */ /* format too. Here, since we can't expect that the TrueType font */ - /* driver is loaded unconditially, we must parse the font by */ + /* driver is loaded unconditionally, we must parse the font by */ /* ourselves. We are only interested in the name of the table and */ /* the offset. */ @@ -1472,6 +1665,7 @@ if ( face_index >= 0 && pstable_index == face_index ) return FT_Err_Ok; } + return FT_THROW( Table_Missing ); } @@ -1509,14 +1703,29 @@ if ( error ) goto Exit; - if ( FT_Stream_Seek( stream, pos + offset ) ) + if ( offset > stream->size ) + { + FT_TRACE2(( "open_face_PS_from_sfnt_stream: invalid table offset\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + else if ( length > stream->size - offset ) + { + FT_TRACE2(( "open_face_PS_from_sfnt_stream: invalid table length\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + error = FT_Stream_Seek( stream, pos + offset ); + if ( error ) goto Exit; if ( FT_ALLOC( sfnt_ps, (FT_Long)length ) ) goto Exit; error = FT_Stream_Read( stream, (FT_Byte *)sfnt_ps, length ); - if ( error ) { + if ( error ) + { FT_FREE( sfnt_ps ); goto Exit; } @@ -1562,6 +1771,7 @@ { FT_Error error = FT_ERR( Cannot_Open_Resource ); FT_Memory memory = library->memory; + FT_Byte* pfb_data = NULL; int i, type, flags; FT_ULong len; @@ -1577,12 +1787,12 @@ /* Find the length of all the POST resources, concatenated. Assume */ /* worst case (each resource in its own section). */ pfb_len = 0; - for ( i = 0; i < resource_cnt; ++i ) + for ( i = 0; i < resource_cnt; i++ ) { error = FT_Stream_Seek( stream, (FT_ULong)offsets[i] ); if ( error ) goto Exit; - if ( FT_READ_ULONG( temp ) ) + if ( FT_READ_ULONG( temp ) ) /* actually LONG */ goto Exit; /* FT2 allocator takes signed long buffer length, @@ -1590,12 +1800,15 @@ */ FT_TRACE4(( " POST fragment #%d: length=0x%08x" " total pfb_len=0x%08x\n", - i, temp, pfb_len + temp + 6)); + i, temp, pfb_len + temp + 6 )); + if ( FT_MAC_RFORK_MAX_LEN < temp || FT_MAC_RFORK_MAX_LEN - temp < pfb_len + 6 ) { FT_TRACE2(( " MacOS resource length cannot exceed" - " 0x%08x\n", FT_MAC_RFORK_MAX_LEN )); + " 0x%08x\n", + FT_MAC_RFORK_MAX_LEN )); + error = FT_THROW( Invalid_Offset ); goto Exit; } @@ -1603,15 +1816,20 @@ pfb_len += temp + 6; } - FT_TRACE2(( " total buffer size to concatenate %d" - " POST fragments: 0x%08x\n", - resource_cnt, pfb_len + 2)); - if ( pfb_len + 2 < 6 ) { + FT_TRACE2(( " total buffer size to concatenate" + " %d POST fragments: 0x%08x\n", + resource_cnt, pfb_len + 2 )); + + if ( pfb_len + 2 < 6 ) + { FT_TRACE2(( " too long fragment length makes" - " pfb_len confused: pfb_len=0x%08x\n", pfb_len )); + " pfb_len confused: pfb_len=0x%08x\n", + pfb_len )); + error = FT_THROW( Array_Too_Large ); goto Exit; } + if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) ) goto Exit; @@ -1624,9 +1842,10 @@ pfb_pos = 6; pfb_lenpos = 2; - len = 0; + len = 0; type = 1; - for ( i = 0; i < resource_cnt; ++i ) + + for ( i = 0; i < resource_cnt; i++ ) { error = FT_Stream_Seek( stream, (FT_ULong)offsets[i] ); if ( error ) @@ -1645,18 +1864,24 @@ if ( FT_READ_USHORT( flags ) ) goto Exit2; - FT_TRACE3(( "POST fragment[%d]: offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n", - i, offsets[i], rlen, flags )); + + FT_TRACE3(( "POST fragment[%d]:" + " offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n", + i, offsets[i], rlen, flags )); error = FT_ERR( Array_Too_Large ); - /* postpone the check of rlen longer than buffer until FT_Stream_Read() */ + + /* postpone the check of `rlen longer than buffer' */ + /* until `FT_Stream_Read' */ + if ( ( flags >> 8 ) == 0 ) /* Comment, should not be loaded */ { - FT_TRACE3(( " Skip POST fragment #%d because it is a comment\n", i )); + FT_TRACE3(( " Skip POST fragment #%d because it is a comment\n", + i )); continue; } - /* the flags are part of the resource, so rlen >= 2. */ + /* the flags are part of the resource, so rlen >= 2, */ /* but some fonts declare rlen = 0 for empty fragment */ if ( rlen > 2 ) rlen -= 2; @@ -1668,9 +1893,12 @@ else { FT_TRACE3(( " Write POST fragment #%d header (4-byte) to buffer" - " %p + 0x%08x\n", i, pfb_data, pfb_lenpos )); + " %p + 0x%08x\n", + i, pfb_data, pfb_lenpos )); + if ( pfb_lenpos + 3 > pfb_len + 2 ) goto Exit2; + pfb_data[pfb_lenpos ] = (FT_Byte)( len ); pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 ); pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 ); @@ -1680,13 +1908,16 @@ break; FT_TRACE3(( " Write POST fragment #%d header (6-byte) to buffer" - " %p + 0x%08x\n", i, pfb_data, pfb_pos )); + " %p + 0x%08x\n", + i, pfb_data, pfb_pos )); + if ( pfb_pos + 6 > pfb_len + 2 ) goto Exit2; + pfb_data[pfb_pos++] = 0x80; type = flags >> 8; - len = rlen; + len = rlen; pfb_data[pfb_pos++] = (FT_Byte)type; pfb_lenpos = pfb_pos; @@ -1700,14 +1931,18 @@ goto Exit2; FT_TRACE3(( " Load POST fragment #%d (%d byte) to buffer" - " %p + 0x%08x\n", i, rlen, pfb_data, pfb_pos )); + " %p + 0x%08x\n", + i, rlen, pfb_data, pfb_pos )); + error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen ); if ( error ) goto Exit2; + pfb_pos += rlen; } error = FT_ERR( Array_Too_Large ); + if ( pfb_pos + 2 > pfb_len + 2 ) goto Exit2; pfb_data[pfb_pos++] = 0x80; @@ -1728,11 +1963,12 @@ aface ); Exit2: - if ( error == FT_ERR( Array_Too_Large ) ) + if ( FT_ERR_EQ( error, Array_Too_Large ) ) FT_TRACE2(( " Abort due to too-short buffer to store" " all POST fragments\n" )); - else if ( error == FT_ERR( Invalid_Offset ) ) + else if ( FT_ERR_EQ( error, Invalid_Offset ) ) FT_TRACE2(( " Abort due to invalid offset in a POST fragment\n" )); + if ( error ) error = FT_ERR( Cannot_Open_Resource ); FT_FREE( pfb_data ); @@ -1764,8 +2000,8 @@ FT_Long face_index_in_resource = 0; - if ( face_index == -1 ) - face_index = 0; + if ( face_index < 0 ) + face_index = -face_index - 1; if ( face_index >= resource_cnt ) return FT_THROW( Cannot_Open_Resource ); @@ -1776,7 +2012,7 @@ if ( FT_READ_LONG( rlen ) ) goto Exit; - if ( rlen == -1 ) + if ( rlen < 1 ) return FT_THROW( Cannot_Open_Resource ); if ( (FT_ULong)rlen > FT_MAC_RFORK_MAX_LEN ) return FT_THROW( Invalid_Offset ); @@ -1790,7 +2026,8 @@ goto Exit; /* rewind sfnt stream before open_face_PS_from_sfnt_stream() */ - if ( FT_Stream_Seek( stream, flag_offset + 4 ) ) + error = FT_Stream_Seek( stream, flag_offset + 4 ); + if ( error ) goto Exit; if ( FT_ALLOC( sfnt_data, rlen ) ) @@ -1828,19 +2065,19 @@ { FT_Memory memory = library->memory; FT_Error error; - FT_Long map_offset, rdara_pos; + FT_Long map_offset, rdata_pos; FT_Long *data_offsets; FT_Long count; error = FT_Raccess_Get_HeaderInfo( library, stream, resource_offset, - &map_offset, &rdara_pos ); + &map_offset, &rdata_pos ); if ( error ) return error; /* POST resources must be sorted to concatenate properly */ error = FT_Raccess_Get_DataOffsets( library, stream, - map_offset, rdara_pos, + map_offset, rdata_pos, TTAG_POST, TRUE, &data_offsets, &count ); if ( !error ) @@ -1857,7 +2094,7 @@ /* sfnt resources should not be sorted to preserve the face order by QuickDraw API */ error = FT_Raccess_Get_DataOffsets( library, stream, - map_offset, rdara_pos, + map_offset, rdata_pos, TTAG_sfnt, FALSE, &data_offsets, &count ); if ( !error ) @@ -1890,7 +2127,7 @@ FT_Long dlen, offset; - if ( NULL == stream ) + if ( !stream ) return FT_THROW( Invalid_Stream_Operation ); error = FT_Stream_Seek( stream, 0 ); @@ -1964,13 +2201,15 @@ { FT_TRACE3(( "Skip rule %d: darwin vfs resource fork" " is already checked and" - " no font is found\n", i )); + " no font is found\n", + i )); continue; } if ( errors[i] ) { - FT_TRACE3(( "Error[%d] has occurred in rule %d\n", errors[i], i )); + FT_TRACE3(( "Error 0x%x has occurred in rule %d\n", + errors[i], i )); continue; } @@ -2079,6 +2318,17 @@ const FT_Open_Args* args, FT_Long face_index, FT_Face *aface ) + { + return ft_open_face_internal( library, args, face_index, aface, 1 ); + } + + + static FT_Error + ft_open_face_internal( FT_Library library, + const FT_Open_Args* args, + FT_Long face_index, + FT_Face *aface, + FT_Bool test_mac_fonts ) { FT_Error error; FT_Driver driver = NULL; @@ -2090,6 +2340,23 @@ FT_Module* cur; FT_Module* limit; +#ifndef FT_CONFIG_OPTION_MAC_FONTS + FT_UNUSED( test_mac_fonts ); +#endif + + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE3(( "FT_Open_Face: " )); + if ( face_index < 0 ) + FT_TRACE3(( "Requesting number of faces and named instances\n")); + else + { + FT_TRACE3(( "Requesting face %ld", face_index & 0xFFFFL )); + if ( face_index & 0x7FFF0000L ) + FT_TRACE3(( ", named instance %ld", face_index >> 16 )); + FT_TRACE3(( "\n" )); + } +#endif /* test for valid `library' delayed to `FT_Stream_New' */ @@ -2167,11 +2434,13 @@ goto Success; #ifdef FT_CONFIG_OPTION_MAC_FONTS - if ( ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 && + if ( test_mac_fonts && + ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 && FT_ERR_EQ( error, Table_Missing ) ) { /* TrueType but essential tables are missing */ - if ( FT_Stream_Seek( stream, 0 ) ) + error = FT_Stream_Seek( stream, 0 ); + if ( error ) break; error = open_face_PS_from_sfnt_stream( library, @@ -2203,16 +2472,20 @@ goto Fail2; #if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS ) - error = load_mac_face( library, stream, face_index, aface, args ); - if ( !error ) + if ( test_mac_fonts ) { - /* We don't want to go to Success here. We've already done that. */ - /* On the other hand, if we succeeded we still need to close this */ - /* stream (we opened a different stream which extracted the */ - /* interesting information out of this stream here. That stream */ - /* will still be open and the face will point to it). */ - FT_Stream_Free( stream, external_stream ); - return error; + error = load_mac_face( library, stream, face_index, aface, args ); + if ( !error ) + { + /* We don't want to go to Success here. We've already done */ + /* that. On the other hand, if we succeeded we still need to */ + /* close this stream (we opened a different stream which */ + /* extracted the interesting information out of this stream */ + /* here. That stream will still be open and the face will */ + /* point to it). */ + FT_Stream_Free( stream, external_stream ); + return error; + } } if ( FT_ERR_NEQ( error, Unknown_File_Format ) ) @@ -2285,11 +2558,24 @@ if ( bsize->height < 0 ) - bsize->height = (FT_Short)-bsize->height; + bsize->height = -bsize->height; if ( bsize->x_ppem < 0 ) - bsize->x_ppem = (FT_Short)-bsize->x_ppem; + bsize->x_ppem = -bsize->x_ppem; if ( bsize->y_ppem < 0 ) bsize->y_ppem = -bsize->y_ppem; + + /* check whether negation actually has worked */ + if ( bsize->height < 0 || bsize->x_ppem < 0 || bsize->y_ppem < 0 ) + { + FT_TRACE0(( "FT_Open_Face:" + " Invalid bitmap dimensions for strike %d," + " now disabled\n", i )); + bsize->width = 0; + bsize->height = 0; + bsize->size = 0; + bsize->x_ppem = 0; + bsize->y_ppem = 0; + } } } @@ -2307,6 +2593,13 @@ internal->transform_delta.y = 0; internal->refcount = 1; + + internal->no_stem_darkening = -1; + +#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING + /* Per-face filtering can only be set up by FT_Face_Properties */ + internal->lcd_filter_func = NULL; +#endif } if ( aface ) @@ -2323,7 +2616,20 @@ destroy_face( memory, face, driver ); Exit: - FT_TRACE4(( "FT_Open_Face: Return %d\n", error )); +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !error && face_index < 0 ) + { + FT_TRACE3(( "FT_Open_Face: The font has %ld face%s\n" + " and %ld named instance%s for face %ld\n", + face->num_faces, + face->num_faces == 1 ? "" : "s", + face->style_flags >> 16, + ( face->style_flags >> 16 ) == 1 ? "" : "s", + -face_index - 1 )); + } +#endif + + FT_TRACE4(( "FT_Open_Face: Return 0x%x\n", error )); return error; } @@ -2464,6 +2770,8 @@ FT_Size size = NULL; FT_ListNode node = NULL; + FT_Size_Internal internal = NULL; + if ( !face ) return FT_THROW( Invalid_Face_Handle ); @@ -2486,8 +2794,10 @@ size->face = face; - /* for now, do not use any internal fields in size objects */ - size->internal = NULL; + if ( FT_NEW( internal ) ) + goto Exit; + + size->internal = internal; if ( clazz->init_size ) error = clazz->init_size( size ); @@ -2589,6 +2899,9 @@ w = FT_PIX_ROUND( w ); h = FT_PIX_ROUND( h ); + if ( !w || !h ) + return FT_THROW( Invalid_Pixel_Size ); + for ( i = 0; i < face->num_fixed_sizes; i++ ) { FT_Bitmap_Size* bsize = face->available_sizes + i; @@ -2608,6 +2921,8 @@ } } + FT_TRACE3(( "FT_Match_Size: no matching bitmap strike\n" )); + return FT_THROW( Invalid_Pixel_Size ); } @@ -2706,18 +3021,6 @@ metrics->height = bsize->height << 6; metrics->max_advance = bsize->x_ppem; } - - FT_TRACE5(( "FT_Select_Metrics:\n" )); - FT_TRACE5(( " x scale: %d (%f)\n", - metrics->x_scale, metrics->x_scale / 65536.0 )); - FT_TRACE5(( " y scale: %d (%f)\n", - metrics->y_scale, metrics->y_scale / 65536.0 )); - FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 )); - FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 )); - FT_TRACE5(( " height: %f\n", metrics->height / 64.0 )); - FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 )); - FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem )); - FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem )); } @@ -2826,18 +3129,6 @@ metrics->x_scale = 1L << 16; metrics->y_scale = 1L << 16; } - - FT_TRACE5(( "FT_Request_Metrics:\n" )); - FT_TRACE5(( " x scale: %d (%f)\n", - metrics->x_scale, metrics->x_scale / 65536.0 )); - FT_TRACE5(( " y scale: %d (%f)\n", - metrics->y_scale, metrics->y_scale / 65536.0 )); - FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 )); - FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 )); - FT_TRACE5(( " height: %f\n", metrics->height / 64.0 )); - FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 )); - FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem )); - FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem )); } @@ -2847,6 +3138,7 @@ FT_Select_Size( FT_Face face, FT_Int strike_index ) { + FT_Error error = FT_Err_Ok; FT_Driver_Class clazz; @@ -2860,36 +3152,37 @@ if ( clazz->select_size ) { - FT_Error error; - - error = clazz->select_size( face->size, (FT_ULong)strike_index ); -#ifdef FT_DEBUG_LEVEL_TRACE - { - FT_Size_Metrics* metrics = &face->size->metrics; + FT_TRACE5(( "FT_Select_Size (%s driver):\n", + face->driver->root.clazz->module_name )); + } + else + { + FT_Select_Metrics( face, (FT_ULong)strike_index ); - - FT_TRACE5(( "FT_Select_Size (font driver's `select_size'):\n" )); - FT_TRACE5(( " x scale: %d (%f)\n", - metrics->x_scale, metrics->x_scale / 65536.0 )); - FT_TRACE5(( " y scale: %d (%f)\n", - metrics->y_scale, metrics->y_scale / 65536.0 )); - FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 )); - FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 )); - FT_TRACE5(( " height: %f\n", metrics->height / 64.0 )); - FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 )); - FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem )); - FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem )); - } -#endif - - return error; + FT_TRACE5(( "FT_Select_Size:\n" )); } - FT_Select_Metrics( face, (FT_ULong)strike_index ); +#ifdef FT_DEBUG_LEVEL_TRACE + { + FT_Size_Metrics* metrics = &face->size->metrics; - return FT_Err_Ok; + + FT_TRACE5(( " x scale: %d (%f)\n", + metrics->x_scale, metrics->x_scale / 65536.0 )); + FT_TRACE5(( " y scale: %d (%f)\n", + metrics->y_scale, metrics->y_scale / 65536.0 )); + FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 )); + FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 )); + FT_TRACE5(( " height: %f\n", metrics->height / 64.0 )); + FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 )); + FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem )); + FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem )); + } +#endif + + return error; } @@ -2899,6 +3192,7 @@ FT_Request_Size( FT_Face face, FT_Size_Request req ) { + FT_Error error = FT_Err_Ok; FT_Driver_Class clazz; FT_ULong strike_index; @@ -2910,59 +3204,60 @@ req->type >= FT_SIZE_REQUEST_TYPE_MAX ) return FT_THROW( Invalid_Argument ); + /* signal the auto-hinter to recompute its size metrics */ + /* (if requested) */ + face->size->internal->autohint_metrics.x_scale = 0; + clazz = face->driver->clazz; if ( clazz->request_size ) { - FT_Error error; - - error = clazz->request_size( face->size, req ); -#ifdef FT_DEBUG_LEVEL_TRACE - { - FT_Size_Metrics* metrics = &face->size->metrics; - - - FT_TRACE5(( "FT_Request_Size (font driver's `request_size'):\n" )); - FT_TRACE5(( " x scale: %d (%f)\n", - metrics->x_scale, metrics->x_scale / 65536.0 )); - FT_TRACE5(( " y scale: %d (%f)\n", - metrics->y_scale, metrics->y_scale / 65536.0 )); - FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 )); - FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 )); - FT_TRACE5(( " height: %f\n", metrics->height / 64.0 )); - FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 )); - FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem )); - FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem )); - } -#endif - - return error; + FT_TRACE5(( "FT_Request_Size (%s driver):\n", + face->driver->root.clazz->module_name )); } - - /* - * The reason that a driver doesn't have `request_size' defined is - * either that the scaling here suffices or that the supported formats - * are bitmap-only and size matching is not implemented. - * - * In the latter case, a simple size matching is done. - */ - if ( !FT_IS_SCALABLE( face ) && FT_HAS_FIXED_SIZES( face ) ) + else if ( !FT_IS_SCALABLE( face ) && FT_HAS_FIXED_SIZES( face ) ) { - FT_Error error; - - + /* + * The reason that a driver doesn't have `request_size' defined is + * either that the scaling here suffices or that the supported formats + * are bitmap-only and size matching is not implemented. + * + * In the latter case, a simple size matching is done. + */ error = FT_Match_Size( face, req, 0, &strike_index ); if ( error ) return error; return FT_Select_Size( face, (FT_Int)strike_index ); } + else + { + FT_Request_Metrics( face, req ); - FT_Request_Metrics( face, req ); + FT_TRACE5(( "FT_Request_Size:\n" )); + } - return FT_Err_Ok; +#ifdef FT_DEBUG_LEVEL_TRACE + { + FT_Size_Metrics* metrics = &face->size->metrics; + + + FT_TRACE5(( " x scale: %d (%f)\n", + metrics->x_scale, metrics->x_scale / 65536.0 )); + FT_TRACE5(( " y scale: %d (%f)\n", + metrics->y_scale, metrics->y_scale / 65536.0 )); + FT_TRACE5(( " ascender: %f\n", metrics->ascender / 64.0 )); + FT_TRACE5(( " descender: %f\n", metrics->descender / 64.0 )); + FT_TRACE5(( " height: %f\n", metrics->height / 64.0 )); + FT_TRACE5(( " max advance: %f\n", metrics->max_advance / 64.0 )); + FT_TRACE5(( " x ppem: %d\n", metrics->x_ppem )); + FT_TRACE5(( " y ppem: %d\n", metrics->y_ppem )); + } +#endif + + return error; } @@ -3327,7 +3622,7 @@ FT_CMap cmap = NULL; - if ( clazz == NULL || charmap == NULL || charmap->face == NULL ) + if ( !clazz || !charmap || !charmap->face ) return FT_THROW( Invalid_Argument ); face = charmap->face; @@ -3454,6 +3749,85 @@ } + /* documentation is in freetype.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Face_Properties( FT_Face face, + FT_UInt num_properties, + FT_Parameter* properties ) + { + FT_Error error = FT_Err_Ok; + + + if ( num_properties > 0 && !properties ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + for ( ; num_properties > 0; num_properties-- ) + { + if ( properties->tag == FT_PARAM_TAG_STEM_DARKENING ) + { + if ( properties->data ) + { + if ( *( (FT_Bool*)properties->data ) == TRUE ) + face->internal->no_stem_darkening = FALSE; + else + face->internal->no_stem_darkening = TRUE; + } + else + { + /* use module default */ + face->internal->no_stem_darkening = -1; + } + } + else if ( properties->tag == FT_PARAM_TAG_LCD_FILTER_WEIGHTS ) + { +#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING + if ( properties->data ) + { + ft_memcpy( face->internal->lcd_weights, + properties->data, + FT_LCD_FILTER_FIVE_TAPS ); + face->internal->lcd_filter_func = ft_lcd_filter_fir; + } +#else + error = FT_THROW( Unimplemented_Feature ); + goto Exit; +#endif + } + else if ( properties->tag == FT_PARAM_TAG_RANDOM_SEED ) + { + if ( properties->data ) + { + face->internal->random_seed = *( (FT_Int32*)properties->data ); + if ( face->internal->random_seed < 0 ) + face->internal->random_seed = 0; + } + else + { + /* use module default */ + face->internal->random_seed = -1; + } + } + else + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + if ( error ) + break; + + properties++; + } + + Exit: + return error; + } + + /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_UInt ) @@ -3472,19 +3846,21 @@ FT_CMap ucmap = FT_CMAP( face->charmap ); - if ( charmap != NULL ) + if ( charmap ) { FT_CMap vcmap = FT_CMAP( charmap ); if ( charcode > 0xFFFFFFFFUL ) { - FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); + FT_TRACE1(( "FT_Face_GetCharVariantIndex:" + " too large charcode" )); FT_TRACE1(( " 0x%x is truncated\n", charcode )); } if ( variantSelector > 0xFFFFFFFFUL ) { - FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" )); + FT_TRACE1(( "FT_Face_GetCharVariantIndex:" + " too large variantSelector" )); FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); } @@ -3513,19 +3889,21 @@ FT_CharMap charmap = find_variant_selector_charmap( face ); - if ( charmap != NULL ) + if ( charmap ) { FT_CMap vcmap = FT_CMAP( charmap ); if ( charcode > 0xFFFFFFFFUL ) { - FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); + FT_TRACE1(( "FT_Face_GetCharVariantIsDefault:" + " too large charcode" )); FT_TRACE1(( " 0x%x is truncated\n", charcode )); } if ( variantSelector > 0xFFFFFFFFUL ) { - FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" )); + FT_TRACE1(( "FT_Face_GetCharVariantIsDefault:" + " too large variantSelector" )); FT_TRACE1(( " 0x%x is truncated\n", variantSelector )); } @@ -3552,7 +3930,7 @@ FT_CharMap charmap = find_variant_selector_charmap( face ); - if ( charmap != NULL ) + if ( charmap ) { FT_CMap vcmap = FT_CMAP( charmap ); FT_Memory memory = FT_FACE_MEMORY( face ); @@ -3580,7 +3958,7 @@ FT_CharMap charmap = find_variant_selector_charmap( face ); - if ( charmap != NULL ) + if ( charmap ) { FT_CMap vcmap = FT_CMAP( charmap ); FT_Memory memory = FT_FACE_MEMORY( face ); @@ -3588,7 +3966,7 @@ if ( charcode > 0xFFFFFFFFUL ) { - FT_TRACE1(( "FT_Get_Char_Index: too large charcode" )); + FT_TRACE1(( "FT_Face_GetVariantsOfChar: too large charcode" )); FT_TRACE1(( " 0x%x is truncated\n", charcode )); } @@ -3614,7 +3992,7 @@ FT_CharMap charmap = find_variant_selector_charmap( face ); - if ( charmap != NULL ) + if ( charmap ) { FT_CMap vcmap = FT_CMAP( charmap ); FT_Memory memory = FT_FACE_MEMORY( face ); @@ -3742,7 +4120,7 @@ if ( face && FT_IS_SFNT( face ) ) { FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); - if ( service != NULL ) + if ( service ) table = service->get_table( face, tag ); } @@ -3766,7 +4144,7 @@ return FT_THROW( Invalid_Face_Handle ); FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); - if ( service == NULL ) + if ( !service ) return FT_THROW( Unimplemented_Feature ); return service->load_table( face, tag, offset, buffer, length ); @@ -3791,7 +4169,7 @@ return FT_THROW( Invalid_Face_Handle ); FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); - if ( service == NULL ) + if ( !service ) return FT_THROW( Unimplemented_Feature ); return service->table_info( face, table_index, tag, &offset, length ); @@ -3813,7 +4191,7 @@ face = charmap->face; FT_FACE_FIND_SERVICE( face, service, TT_CMAP ); - if ( service == NULL ) + if ( !service ) return 0; if ( service->get_cmap_info( charmap, &cmap_info )) return 0; @@ -3837,7 +4215,7 @@ face = charmap->face; FT_FACE_FIND_SERVICE( face, service, TT_CMAP ); - if ( service == NULL ) + if ( !service ) return -1; if ( service->get_cmap_info( charmap, &cmap_info )) return -1; @@ -4156,8 +4534,17 @@ #undef FT_COMPONENT #define FT_COMPONENT trace_bitmap - /* we convert to a single bitmap format for computing the checksum */ - if ( !error ) + /* + * Computing the MD5 checksum is expensive, unnecessarily distorting a + * possible profiling of FreeType if compiled with tracing support. For + * this reason, we execute the following code only if explicitly + * requested. + */ + + /* we use FT_TRACE3 in this block */ + if ( !error && + ft_trace_levels[trace_bitmap] >= 3 && + slot->bitmap.buffer ) { FT_Bitmap bitmap; FT_Error err; @@ -4165,24 +4552,35 @@ FT_Bitmap_Init( &bitmap ); - /* this also converts the bitmap flow to `down' (i.e., pitch > 0) */ + /* we convert to a single bitmap format for computing the checksum */ + /* this also converts the bitmap flow to `down' (i.e., pitch > 0) */ err = FT_Bitmap_Convert( library, &slot->bitmap, &bitmap, 1 ); if ( !err ) { MD5_CTX ctx; unsigned char md5[16]; - int i; - unsigned int rows = bitmap.rows; - unsigned int pitch = (unsigned int)bitmap.pitch; + unsigned long coverage = 0; + int i, j; + int rows = (int)bitmap.rows; + int pitch = bitmap.pitch; + FT_TRACE3(( "FT_Render_Glyph: bitmap %dx%d, mode %d\n", + rows, pitch, slot->bitmap.pixel_mode )); + + for ( i = 0; i < rows; i++ ) + for ( j = 0; j < pitch; j++ ) + coverage += bitmap.buffer[i * pitch + j]; + + FT_TRACE3(( " Total coverage: %lu\n", coverage )); + MD5_Init( &ctx ); - MD5_Update( &ctx, bitmap.buffer, rows * pitch ); + if ( bitmap.buffer ) + MD5_Update( &ctx, bitmap.buffer, + (unsigned long)rows * (unsigned long)pitch ); MD5_Final( md5, &ctx ); - FT_TRACE3(( "MD5 checksum for %dx%d bitmap:\n" - " ", - rows, pitch )); + FT_TRACE3(( " MD5 checksum: " )); for ( i = 0; i < 16; i++ ) FT_TRACE3(( "%02X", md5[i] )); FT_TRACE3(( "\n" )); @@ -4191,6 +4589,52 @@ FT_Bitmap_Done( library, &bitmap ); } + /* + * Dump bitmap in Netpbm format (PBM or PGM). + */ + + /* we use FT_TRACE7 in this block */ + if ( !error && + ft_trace_levels[trace_bitmap] >= 7 && + slot->bitmap.rows < 128U && + slot->bitmap.width < 128U && + slot->bitmap.buffer ) + { + int rows = (int)slot->bitmap.rows; + int width = (int)slot->bitmap.width; + int pitch = slot->bitmap.pitch; + int i, j, m; + unsigned char* topleft = slot->bitmap.buffer; + + if ( pitch < 0 ) + topleft -= pitch * ( rows - 1 ); + + FT_TRACE7(( "Netpbm image: start\n" )); + switch ( slot->bitmap.pixel_mode ) + { + case FT_PIXEL_MODE_MONO: + FT_TRACE7(( "P1 %d %d\n", width, rows )); + for ( i = 0; i < rows; i++ ) + { + for ( j = 0; j < width; ) + for ( m = 128; m > 0 && j < width; m >>= 1, j++ ) + FT_TRACE7(( " %d", ( topleft[i * pitch + j / 8] & m ) != 0 )); + FT_TRACE7(( "\n" )); + } + break; + + default: + FT_TRACE7(( "P2 %d %d 255\n", width, rows )); + for ( i = 0; i < rows; i++ ) + { + for ( j = 0; j < width; j += 1 ) + FT_TRACE7(( " %3u", topleft[i * pitch + j] )); + FT_TRACE7(( "\n" )); + } + } + FT_TRACE7(( "Netpbm image: end\n" )); + } + #undef FT_COMPONENT #define FT_COMPONENT trace_objs @@ -4282,7 +4726,7 @@ { FT_Error error; FT_Memory memory; - FT_Module module; + FT_Module module = NULL; FT_UInt nn; @@ -4295,7 +4739,7 @@ if ( !clazz ) return FT_THROW( Invalid_Argument ); - /* check freetype version */ + /* check FreeType version */ if ( clazz->module_requires > FREETYPE_VER_FIXED ) return FT_THROW( Invalid_Version ); @@ -4434,7 +4878,8 @@ FT_BASE_DEF( FT_Pointer ) ft_module_get_service( FT_Module module, - const char* service_id ) + const char* service_id, + FT_Bool global ) { FT_Pointer result = NULL; @@ -4447,7 +4892,7 @@ if ( module->clazz->get_interface ) result = module->clazz->get_interface( module, service_id ); - if ( result == NULL ) + if ( global && !result ) { /* we didn't find it, look in all other modules then */ FT_Library library = module->library; @@ -4464,7 +4909,7 @@ if ( cur[0]->clazz->get_interface ) { result = cur[0]->clazz->get_interface( cur[0], service_id ); - if ( result != NULL ) + if ( result ) break; } } @@ -4523,7 +4968,8 @@ const FT_String* module_name, const FT_String* property_name, void* value, - FT_Bool set ) + FT_Bool set, + FT_Bool value_is_string ) { FT_Module* cur; FT_Module* limit; @@ -4593,8 +5039,13 @@ return FT_THROW( Unimplemented_Feature ); } - return set ? service->set_property( cur[0], property_name, value ) - : service->get_property( cur[0], property_name, value ); + return set ? service->set_property( cur[0], + property_name, + value, + value_is_string ) + : service->get_property( cur[0], + property_name, + value ); } @@ -4610,7 +5061,8 @@ module_name, property_name, (void*)value, - TRUE ); + TRUE, + FALSE ); } @@ -4626,10 +5078,33 @@ module_name, property_name, value, + FALSE, FALSE ); } +#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + + /* this variant is used for handling the FREETYPE_PROPERTIES */ + /* environment variable */ + + FT_BASE_DEF( FT_Error ) + ft_property_string_set( FT_Library library, + const FT_String* module_name, + const FT_String* property_name, + FT_String* value ) + { + return ft_property_do( library, + module_name, + property_name, + (void*)value, + TRUE, + TRUE ); + } + +#endif + + /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ @@ -4688,10 +5163,6 @@ goto Fail; #endif - /* we don't use raster_pool anymore. */ - library->raster_pool_size = 0; - library->raster_pool = NULL; - library->version_major = FREETYPE_MAJOR; library->version_minor = FREETYPE_MINOR; library->version_patch = FREETYPE_PATCH; @@ -4706,9 +5177,9 @@ #ifdef FT_CONFIG_OPTION_PIC Fail: ft_pic_container_destroy( library ); -#endif FT_FREE( library ); return error; +#endif } @@ -4885,7 +5356,8 @@ service = (FT_Service_TrueTypeEngine) ft_module_get_service( module, - FT_SERVICE_ID_TRUETYPE_ENGINE ); + FT_SERVICE_ID_TRUETYPE_ENGINE, + 0 ); if ( service ) result = service->engine_type; } diff --git a/src/3rdparty/freetype/src/base/ftotval.c b/src/3rdparty/freetype/src/base/ftotval.c index 786457ba2a..a2944a7950 100644 --- a/src/3rdparty/freetype/src/base/ftotval.c +++ b/src/3rdparty/freetype/src/base/ftotval.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for validating OpenType tables (body). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/src/base/ftoutln.c b/src/3rdparty/freetype/src/base/ftoutln.c index 35cc9f5569..cb91321deb 100644 --- a/src/3rdparty/freetype/src/base/ftoutln.c +++ b/src/3rdparty/freetype/src/base/ftoutln.c @@ -4,7 +4,7 @@ /* */ /* FreeType outline management (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -42,7 +42,7 @@ static - const FT_Outline null_outline = { 0, 0, 0, 0, 0, 0 }; + const FT_Outline null_outline = { 0, 0, NULL, NULL, NULL, 0 }; /* documentation is in ftoutln.h */ @@ -286,12 +286,13 @@ FT_TRACE5(( "FT_Outline_Decompose: Done\n", n )); return FT_Err_Ok; - Exit: - FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error )); - return error; - Invalid_Outline: - return FT_THROW( Invalid_Outline ); + error = FT_THROW( Invalid_Outline ); + /* fall through */ + + Exit: + FT_TRACE5(( "FT_Outline_Decompose: Error 0x%x\n", error )); + return error; } @@ -415,11 +416,14 @@ if ( source == target ) return FT_Err_Ok; - FT_ARRAY_COPY( target->points, source->points, source->n_points ); + if ( source->n_points ) + { + FT_ARRAY_COPY( target->points, source->points, source->n_points ); + FT_ARRAY_COPY( target->tags, source->tags, source->n_points ); + } - FT_ARRAY_COPY( target->tags, source->tags, source->n_points ); - - FT_ARRAY_COPY( target->contours, source->contours, source->n_contours ); + if ( source->n_contours ) + FT_ARRAY_COPY( target->contours, source->contours, source->n_contours ); /* copy all flags, except the `FT_OUTLINE_OWNER' one */ is_owner = target->flags & FT_OUTLINE_OWNER; @@ -537,8 +541,8 @@ for ( n = 0; n < outline->n_points; n++ ) { - vec->x += xOffset; - vec->y += yOffset; + vec->x = ADD_LONG( vec->x, xOffset ); + vec->y = ADD_LONG( vec->y, yOffset ); vec++; } } @@ -942,6 +946,9 @@ l_in = 0; last = outline->contours[c]; + /* pacify compiler */ + in.x = in.y = anchor.x = anchor.y = 0; + /* Counter j cycles though the points; counter i advances only */ /* when points are moved; anchor k marks the first moved point. */ for ( i = last, j = first, k = -1; @@ -1074,13 +1081,17 @@ FT_Int last = outline->contours[c]; - v_prev = points[last]; + v_prev.x = points[last].x >> xshift; + v_prev.y = points[last].y >> yshift; for ( n = first; n <= last; n++ ) { - v_cur = points[n]; - area += ( ( v_cur.y - v_prev.y ) >> yshift ) * - ( ( v_cur.x + v_prev.x ) >> xshift ); + v_cur.x = points[n].x >> xshift; + v_cur.y = points[n].y >> yshift; + + area = ADD_LONG( area, + ( v_cur.y - v_prev.y ) * ( v_cur.x + v_prev.x ) ); + v_prev = v_cur; } diff --git a/src/3rdparty/freetype/src/base/ftpatent.c b/src/3rdparty/freetype/src/base/ftpatent.c index bf2b0855c9..e23ee2e3f4 100644 --- a/src/3rdparty/freetype/src/base/ftpatent.c +++ b/src/3rdparty/freetype/src/base/ftpatent.c @@ -3,9 +3,9 @@ /* ftpatent.c */ /* */ /* FreeType API for checking patented TrueType bytecode instructions */ -/* (body). */ +/* (body). Obsolete, retained for backward compatibility. */ /* */ -/* Copyright 2007-2015 by */ +/* Copyright 2007-2018 by */ /* David Turner. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -25,238 +25,14 @@ #include FT_SERVICE_TRUETYPE_GLYF_H - static FT_Bool - _tt_check_patents_in_range( FT_Stream stream, - FT_ULong size ) - { - FT_Bool result = FALSE; - FT_Error error; - FT_Bytes p, end; - - - if ( FT_FRAME_ENTER( size ) ) - return 0; - - p = stream->cursor; - end = p + size; - - while ( p < end ) - { - switch (p[0]) - { - case 0x06: /* SPvTL // */ - case 0x07: /* SPvTL + */ - case 0x08: /* SFvTL // */ - case 0x09: /* SFvTL + */ - case 0x0A: /* SPvFS */ - case 0x0B: /* SFvFS */ - result = TRUE; - goto Exit; - - case 0x40: - if ( p + 1 >= end ) - goto Exit; - - p += p[1] + 2; - break; - - case 0x41: - if ( p + 1 >= end ) - goto Exit; - - p += p[1] * 2 + 2; - break; - - case 0x71: /* DELTAP2 */ - case 0x72: /* DELTAP3 */ - case 0x73: /* DELTAC0 */ - case 0x74: /* DELTAC1 */ - case 0x75: /* DELTAC2 */ - result = TRUE; - goto Exit; - - case 0xB0: - case 0xB1: - case 0xB2: - case 0xB3: - case 0xB4: - case 0xB5: - case 0xB6: - case 0xB7: - p += ( p[0] - 0xB0 ) + 2; - break; - - case 0xB8: - case 0xB9: - case 0xBA: - case 0xBB: - case 0xBC: - case 0xBD: - case 0xBE: - case 0xBF: - p += ( p[0] - 0xB8 ) * 2 + 3; - break; - - default: - p += 1; - break; - } - } - - Exit: - FT_UNUSED( error ); - FT_FRAME_EXIT(); - return result; - } - - - static FT_Bool - _tt_check_patents_in_table( FT_Face face, - FT_ULong tag ) - { - FT_Stream stream = face->stream; - FT_Error error = FT_Err_Ok; - FT_Service_SFNT_Table service; - FT_Bool result = FALSE; - - - FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE ); - - if ( service ) - { - FT_UInt i = 0; - FT_ULong tag_i = 0, offset_i = 0, length_i = 0; - - - for ( i = 0; !error && tag_i != tag ; i++ ) - error = service->table_info( face, i, - &tag_i, &offset_i, &length_i ); - - if ( error || - FT_STREAM_SEEK( offset_i ) ) - goto Exit; - - result = _tt_check_patents_in_range( stream, length_i ); - } - - Exit: - return result; - } - - - static FT_Bool - _tt_face_check_patents( FT_Face face ) - { - FT_Stream stream = face->stream; - FT_UInt gindex; - FT_Error error; - FT_Bool result; - - FT_Service_TTGlyf service; - - - result = _tt_check_patents_in_table( face, TTAG_fpgm ); - if ( result ) - goto Exit; - - result = _tt_check_patents_in_table( face, TTAG_prep ); - if ( result ) - goto Exit; - - FT_FACE_FIND_SERVICE( face, service, TT_GLYF ); - if ( service == NULL ) - goto Exit; - - for ( gindex = 0; gindex < (FT_UInt)face->num_glyphs; gindex++ ) - { - FT_ULong offset, num_ins, size; - FT_Int num_contours; - - - offset = service->get_location( face, gindex, &size ); - if ( size == 0 ) - continue; - - if ( FT_STREAM_SEEK( offset ) || - FT_READ_SHORT( num_contours ) ) - continue; - - if ( num_contours >= 0 ) /* simple glyph */ - { - if ( FT_STREAM_SKIP( 8 + num_contours * 2 ) ) - continue; - } - else /* compound glyph */ - { - FT_Bool has_instr = 0; - - - if ( FT_STREAM_SKIP( 8 ) ) - continue; - - /* now read each component */ - for (;;) - { - FT_UInt flags, toskip; - - - if( FT_READ_USHORT( flags ) ) - break; - - toskip = 2 + 1 + 1; - - if ( ( flags & ( 1 << 0 ) ) != 0 ) /* ARGS_ARE_WORDS */ - toskip += 2; - - if ( ( flags & ( 1 << 3 ) ) != 0 ) /* WE_HAVE_A_SCALE */ - toskip += 2; - else if ( ( flags & ( 1 << 6 ) ) != 0 ) /* WE_HAVE_X_Y_SCALE */ - toskip += 4; - else if ( ( flags & ( 1 << 7 ) ) != 0 ) /* WE_HAVE_A_2x2 */ - toskip += 8; - - if ( ( flags & ( 1 << 8 ) ) != 0 ) /* WE_HAVE_INSTRUCTIONS */ - has_instr = 1; - - if ( FT_STREAM_SKIP( toskip ) ) - goto NextGlyph; - - if ( ( flags & ( 1 << 5 ) ) == 0 ) /* MORE_COMPONENTS */ - break; - } - - if ( !has_instr ) - goto NextGlyph; - } - - if ( FT_READ_USHORT( num_ins ) ) - continue; - - result = _tt_check_patents_in_range( stream, num_ins ); - if ( result ) - goto Exit; - - NextGlyph: - ; - } - - Exit: - return result; - } - - /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_Bool ) FT_Face_CheckTrueTypePatents( FT_Face face ) { - FT_Bool result = FALSE; + FT_UNUSED( face ); - - if ( face && FT_IS_SFNT( face ) ) - result = _tt_face_check_patents( face ); - - return result; + return FALSE; } @@ -266,22 +42,10 @@ FT_Face_SetUnpatentedHinting( FT_Face face, FT_Bool value ) { - FT_Bool result = FALSE; - - -#if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \ - !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER ) - if ( face && FT_IS_SFNT( face ) ) - { - result = !face->internal->ignore_unpatented_hinter; - face->internal->ignore_unpatented_hinter = !value; - } -#else FT_UNUSED( face ); FT_UNUSED( value ); -#endif - return result; + return FALSE; } /* END */ diff --git a/src/3rdparty/freetype/src/base/ftpfr.c b/src/3rdparty/freetype/src/base/ftpfr.c index 39f089e3e9..bfe13520eb 100644 --- a/src/3rdparty/freetype/src/base/ftpfr.c +++ b/src/3rdparty/freetype/src/base/ftpfr.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing PFR-specific data (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/src/base/ftpic.c b/src/3rdparty/freetype/src/base/ftpic.c index 6c4b1cd4e6..1492e1809a 100644 --- a/src/3rdparty/freetype/src/base/ftpic.c +++ b/src/3rdparty/freetype/src/base/ftpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services (body). */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2018 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/src/base/ftpsprop.c b/src/3rdparty/freetype/src/base/ftpsprop.c new file mode 100644 index 0000000000..459b5e6054 --- /dev/null +++ b/src/3rdparty/freetype/src/base/ftpsprop.c @@ -0,0 +1,285 @@ +/***************************************************************************/ +/* */ +/* ftpsprop.c */ +/* */ +/* Get and set properties of PostScript drivers (body). */ +/* See `ftdriver.h' for available properties. */ +/* */ +/* Copyright 2017-2018 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_DRIVER_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H +#include FT_INTERNAL_OBJECTS_H +#include FT_INTERNAL_POSTSCRIPT_PROPS_H + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_psprops + + + FT_BASE_CALLBACK_DEF( FT_Error ) + ps_property_set( FT_Module module, /* PS_Driver */ + const char* property_name, + const void* value, + FT_Bool value_is_string ) + { + FT_Error error = FT_Err_Ok; + PS_Driver driver = (PS_Driver)module; + +#ifndef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + FT_UNUSED( value_is_string ); +#endif + + + if ( !ft_strcmp( property_name, "darkening-parameters" ) ) + { + FT_Int* darken_params; + FT_Int x1, y1, x2, y2, x3, y3, x4, y4; + +#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + FT_Int dp[8]; + + + if ( value_is_string ) + { + const char* s = (const char*)value; + char* ep; + int i; + + + /* eight comma-separated numbers */ + for ( i = 0; i < 7; i++ ) + { + dp[i] = (FT_Int)ft_strtol( s, &ep, 10 ); + if ( *ep != ',' || s == ep ) + return FT_THROW( Invalid_Argument ); + + s = ep + 1; + } + + dp[7] = (FT_Int)ft_strtol( s, &ep, 10 ); + if ( !( *ep == '\0' || *ep == ' ' ) || s == ep ) + return FT_THROW( Invalid_Argument ); + + darken_params = dp; + } + else +#endif + darken_params = (FT_Int*)value; + + x1 = darken_params[0]; + y1 = darken_params[1]; + x2 = darken_params[2]; + y2 = darken_params[3]; + x3 = darken_params[4]; + y3 = darken_params[5]; + x4 = darken_params[6]; + y4 = darken_params[7]; + + if ( x1 < 0 || x2 < 0 || x3 < 0 || x4 < 0 || + y1 < 0 || y2 < 0 || y3 < 0 || y4 < 0 || + x1 > x2 || x2 > x3 || x3 > x4 || + y1 > 500 || y2 > 500 || y3 > 500 || y4 > 500 ) + return FT_THROW( Invalid_Argument ); + + driver->darken_params[0] = x1; + driver->darken_params[1] = y1; + driver->darken_params[2] = x2; + driver->darken_params[3] = y2; + driver->darken_params[4] = x3; + driver->darken_params[5] = y3; + driver->darken_params[6] = x4; + driver->darken_params[7] = y4; + + return error; + } + + else if ( !ft_strcmp( property_name, "hinting-engine" ) ) + { +#if defined( CFF_CONFIG_OPTION_OLD_ENGINE ) || \ + defined( T1_CONFIG_OPTION_OLD_ENGINE ) + const char* module_name = module->clazz->module_name; +#endif + + +#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + if ( value_is_string ) + { + const char* s = (const char*)value; + + + if ( !ft_strcmp( s, "adobe" ) ) + driver->hinting_engine = FT_HINTING_ADOBE; + +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + else if ( !ft_strcmp( module_name, "cff" ) && + !ft_strcmp( s, "freetype" ) ) + driver->hinting_engine = FT_HINTING_FREETYPE; +#endif + +#ifdef T1_CONFIG_OPTION_OLD_ENGINE + else if ( ( !ft_strcmp( module_name, "type1" ) || + !ft_strcmp( module_name, "t1cid" ) ) && + !ft_strcmp( s, "freetype" ) ) + driver->hinting_engine = FT_HINTING_FREETYPE; +#endif + + else + return FT_THROW( Invalid_Argument ); + } + else +#endif /* FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES */ + { + FT_UInt* hinting_engine = (FT_UInt*)value; + + + if ( *hinting_engine == FT_HINTING_ADOBE +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + || ( *hinting_engine == FT_HINTING_FREETYPE && + !ft_strcmp( module_name, "cff" ) ) +#endif +#ifdef T1_CONFIG_OPTION_OLD_ENGINE + || ( *hinting_engine == FT_HINTING_FREETYPE && + ( !ft_strcmp( module_name, "type1" ) || + !ft_strcmp( module_name, "t1cid" ) ) ) +#endif + ) + driver->hinting_engine = *hinting_engine; + else + error = FT_ERR( Unimplemented_Feature ); + + return error; + } + } + + else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) + { +#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + if ( value_is_string ) + { + const char* s = (const char*)value; + long nsd = ft_strtol( s, NULL, 10 ); + + + if ( !nsd ) + driver->no_stem_darkening = FALSE; + else + driver->no_stem_darkening = TRUE; + } + else +#endif + { + FT_Bool* no_stem_darkening = (FT_Bool*)value; + + + driver->no_stem_darkening = *no_stem_darkening; + } + + return error; + } + + else if ( !ft_strcmp( property_name, "random-seed" ) ) + { + FT_Int32 random_seed; + + +#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + if ( value_is_string ) + { + const char* s = (const char*)value; + + + random_seed = (FT_Int32)ft_strtol( s, NULL, 10 ); + } + else +#endif + random_seed = *(FT_Int32*)value; + + if ( random_seed < 0 ) + random_seed = 0; + + driver->random_seed = random_seed; + + return error; + } + + FT_TRACE0(( "ps_property_set: missing property `%s'\n", + property_name )); + return FT_THROW( Missing_Property ); + } + + + FT_BASE_CALLBACK_DEF( FT_Error ) + ps_property_get( FT_Module module, /* PS_Driver */ + const char* property_name, + void* value ) + { + FT_Error error = FT_Err_Ok; + PS_Driver driver = (PS_Driver)module; + + + if ( !ft_strcmp( property_name, "darkening-parameters" ) ) + { + FT_Int* darken_params = driver->darken_params; + FT_Int* val = (FT_Int*)value; + + + val[0] = darken_params[0]; + val[1] = darken_params[1]; + val[2] = darken_params[2]; + val[3] = darken_params[3]; + val[4] = darken_params[4]; + val[5] = darken_params[5]; + val[6] = darken_params[6]; + val[7] = darken_params[7]; + + return error; + } + + else if ( !ft_strcmp( property_name, "hinting-engine" ) ) + { + FT_UInt hinting_engine = driver->hinting_engine; + FT_UInt* val = (FT_UInt*)value; + + + *val = hinting_engine; + + return error; + } + + else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) + { + FT_Bool no_stem_darkening = driver->no_stem_darkening; + FT_Bool* val = (FT_Bool*)value; + + + *val = no_stem_darkening; + + return error; + } + + FT_TRACE0(( "ps_property_get: missing property `%s'\n", + property_name )); + return FT_THROW( Missing_Property ); + } + + +/* END */ diff --git a/src/3rdparty/freetype/src/base/ftrfork.c b/src/3rdparty/freetype/src/base/ftrfork.c index c30c76678e..c3a2b9151a 100644 --- a/src/3rdparty/freetype/src/base/ftrfork.c +++ b/src/3rdparty/freetype/src/base/ftrfork.c @@ -4,7 +4,7 @@ /* */ /* Embedded resource forks accessor (body). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* Masatake YAMATO and Redhat K.K. */ /* */ /* FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are */ @@ -56,7 +56,7 @@ { FT_Error error; unsigned char head[16], head2[16]; - FT_Long map_pos, rdata_len; + FT_Long map_pos, map_len, rdata_len; int allzeros, allmatch, i; FT_Long type_list; @@ -67,12 +67,15 @@ if ( error ) return error; - error = FT_Stream_Read( stream, (FT_Byte *)head, 16 ); + error = FT_Stream_Read( stream, (FT_Byte*)head, 16 ); if ( error ) return error; /* ensure positive values */ - if ( head[0] >= 0x80 || head[4] >= 0x80 || head[8] >= 0x80 ) + if ( head[0] >= 0x80 || + head[4] >= 0x80 || + head[8] >= 0x80 || + head[12] >= 0x80 ) return FT_THROW( Unknown_File_Format ); *rdata_pos = ( head[ 0] << 24 ) | @@ -87,14 +90,36 @@ ( head[ 9] << 16 ) | ( head[10] << 8 ) | head[11]; + map_len = ( head[12] << 24 ) | + ( head[13] << 16 ) | + ( head[14] << 8 ) | + head[15]; - /* map_len = head[12] .. head[15] */ - - if ( *rdata_pos != map_pos - rdata_len || map_pos == 0 ) + /* the map must not be empty */ + if ( !map_pos ) return FT_THROW( Unknown_File_Format ); - if ( FT_LONG_MAX - rfork_offset < *rdata_pos || - FT_LONG_MAX - rfork_offset < map_pos ) + /* check whether rdata and map overlap */ + if ( *rdata_pos < map_pos ) + { + if ( *rdata_pos > map_pos - rdata_len ) + return FT_THROW( Unknown_File_Format ); + } + else + { + if ( map_pos > *rdata_pos - map_len ) + return FT_THROW( Unknown_File_Format ); + } + + /* check whether end of rdata or map exceeds stream size */ + if ( FT_LONG_MAX - rdata_len < *rdata_pos || + FT_LONG_MAX - map_len < map_pos || + + FT_LONG_MAX - ( *rdata_pos + rdata_len ) < rfork_offset || + FT_LONG_MAX - ( map_pos + map_len ) < rfork_offset || + + (FT_ULong)( rfork_offset + *rdata_pos + rdata_len ) > stream->size || + (FT_ULong)( rfork_offset + map_pos + map_len ) > stream->size ) return FT_THROW( Unknown_File_Format ); *rdata_pos += rfork_offset; @@ -112,7 +137,7 @@ allzeros = 1; allmatch = 1; - for ( i = 0; i < 16; ++i ) + for ( i = 0; i < 16; i++ ) { if ( head2[i] != 0 ) allzeros = 0; @@ -124,15 +149,14 @@ /* If we have reached this point then it is probably a mac resource */ /* file. Now, does it contain any interesting resources? */ - /* Skip handle to next resource map, the file resource number, and */ - /* attributes. */ + (void)FT_STREAM_SKIP( 4 /* skip handle to next resource map */ + 2 /* skip file resource number */ + 2 ); /* skip attributes */ - if ( FT_READ_USHORT( type_list ) ) + if ( FT_READ_SHORT( type_list ) ) return error; - if ( type_list == -1 ) + if ( type_list < 0 ) return FT_THROW( Unknown_File_Format ); error = FT_Stream_Seek( stream, (FT_ULong)( map_pos + type_list ) ); @@ -181,15 +205,34 @@ if ( error ) return error; - if ( FT_READ_USHORT( cnt ) ) + if ( FT_READ_SHORT( cnt ) ) return error; cnt++; - for ( i = 0; i < cnt; ++i ) + /* `rpos' is a signed 16bit integer offset to resource records; the */ + /* size of a resource record is 12 bytes. The map header is 28 bytes, */ + /* and a type list needs 10 bytes or more. If we assume that the name */ + /* list is empty and we have only a single entry in the type list, */ + /* there can be at most */ + /* */ + /* (32768 - 28 - 10) / 12 = 2727 */ + /* */ + /* resources. */ + /* */ + /* A type list starts with a two-byte counter, followed by 10-byte */ + /* type records. Assuming that there are no resources, the number of */ + /* type records can be at most */ + /* */ + /* (32768 - 28 - 2) / 8 = 4079 */ + /* */ + if ( cnt > 4079 ) + return FT_THROW( Invalid_Table ); + + for ( i = 0; i < cnt; i++ ) { if ( FT_READ_LONG( tag_internal ) || - FT_READ_USHORT( subcnt ) || - FT_READ_USHORT( rpos ) ) + FT_READ_SHORT( subcnt ) || + FT_READ_SHORT( rpos ) ) return error; FT_TRACE2(( "Resource tags: %c%c%c%c\n", @@ -205,6 +248,11 @@ *count = subcnt + 1; rpos += map_offset; + /* a zero count might be valid in the resource specification, */ + /* however, it is completely useless to us */ + if ( *count < 1 || *count > 2727 ) + return FT_THROW( Invalid_Table ); + error = FT_Stream_Seek( stream, (FT_ULong)rpos ); if ( error ) return error; @@ -212,35 +260,50 @@ if ( FT_NEW_ARRAY( ref, *count ) ) return error; - for ( j = 0; j < *count; ++j ) + for ( j = 0; j < *count; j++ ) { - if ( FT_READ_USHORT( ref[j].res_id ) ) + if ( FT_READ_SHORT( ref[j].res_id ) ) goto Exit; - if ( FT_STREAM_SKIP( 2 ) ) /* resource name */ + if ( FT_STREAM_SKIP( 2 ) ) /* resource name offset */ goto Exit; - if ( FT_READ_LONG( temp ) ) + if ( FT_READ_LONG( temp ) ) /* attributes (8bit), offset (24bit) */ goto Exit; - if ( FT_STREAM_SKIP( 4 ) ) /* mbz */ + if ( FT_STREAM_SKIP( 4 ) ) /* mbz */ goto Exit; + /* + * According to Inside Macintosh: More Macintosh Toolbox, + * "Resource IDs" (1-46), there are some reserved IDs. + * However, FreeType2 is not a font synthesizer, no need + * to check the acceptable resource ID. + */ + if ( temp < 0 ) + { + error = FT_THROW( Invalid_Table ); + goto Exit; + } + ref[j].offset = temp & 0xFFFFFFL; + FT_TRACE3(( " [%d]:" " resource_id=0x%04x, offset=0x%08x\n", - j, ref[j].res_id, ref[j].offset )); + j, (FT_UShort)ref[j].res_id, ref[j].offset )); } - if (sort_by_res_id) + if ( sort_by_res_id ) { - ft_qsort( ref, (size_t)*count, sizeof ( FT_RFork_Ref ), - ( int(*)(const void*, const void*) ) - ft_raccess_sort_ref_by_id ); + ft_qsort( ref, + (size_t)*count, + sizeof ( FT_RFork_Ref ), + ( int(*)(const void*, + const void*) )ft_raccess_sort_ref_by_id ); FT_TRACE3(( " -- sort resources by their ids --\n" )); - for ( j = 0; j < *count; ++ j ) { + + for ( j = 0; j < *count; j++ ) FT_TRACE3(( " [%d]:" " resource_id=0x%04x, offset=0x%08x\n", j, ref[j].res_id, ref[j].offset )); - } } if ( FT_NEW_ARRAY( offsets_internal, *count ) ) @@ -250,7 +313,7 @@ * gap between reference IDs are acceptable? * further investigation on Apple implementation is needed. */ - for ( j = 0; j < *count; ++j ) + for ( j = 0; j < *count; j++ ) offsets_internal[j] = rdata_pos + ref[j].offset; *offsets = offsets_internal; @@ -403,7 +466,7 @@ errors[i] = FT_Err_Ok; if ( errors[i] ) - continue ; + continue; errors[i] = (FT_RACCESS_GUESS_TABLE_GET[i].func)( library, stream, base_name, @@ -415,7 +478,7 @@ } -#ifndef FT_MACINTOSH +#if defined( FT_CONFIG_OPTION_MAC_FONTS ) && !defined( FT_MACINTOSH ) static FT_RFork_Rule raccess_get_rule_type_from_rule_index( FT_Library library, FT_UInt rule_index ) diff --git a/src/3rdparty/freetype/src/base/ftsnames.c b/src/3rdparty/freetype/src/base/ftsnames.c index 80304e5c85..90ea1e2be7 100644 --- a/src/3rdparty/freetype/src/base/ftsnames.c +++ b/src/3rdparty/freetype/src/base/ftsnames.c @@ -7,7 +7,7 @@ /* */ /* This is _not_ used to retrieve glyph names! */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,6 +20,8 @@ #include <ft2build.h> +#include FT_INTERNAL_DEBUG_H + #include FT_SFNT_NAMES_H #include FT_INTERNAL_TRUETYPE_TYPES_H #include FT_INTERNAL_STREAM_H @@ -54,11 +56,11 @@ if ( idx < (FT_UInt)ttface->num_names ) { - TT_NameEntryRec* entry = ttface->name_table.names + idx; + TT_Name entry = ttface->name_table.names + idx; /* load name on demand */ - if ( entry->stringLength > 0 && entry->string == NULL ) + if ( entry->stringLength > 0 && !entry->string ) { FT_Memory memory = face->memory; FT_Stream stream = face->stream; @@ -88,6 +90,58 @@ } + /* documentation is in ftsnames.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Get_Sfnt_LangTag( FT_Face face, + FT_UInt langID, + FT_SfntLangTag *alangTag ) + { + FT_Error error = FT_ERR( Invalid_Argument ); + + + if ( alangTag && face && FT_IS_SFNT( face ) ) + { + TT_Face ttface = (TT_Face)face; + + + if ( ttface->name_table.format != 1 ) + return FT_THROW( Invalid_Table ); + + if ( langID > 0x8000U && + langID - 0x8000U < ttface->name_table.numLangTagRecords ) + { + TT_LangTag entry = ttface->name_table.langTags + + ( langID - 0x8000U ); + + + /* load name on demand */ + if ( entry->stringLength > 0 && !entry->string ) + { + FT_Memory memory = face->memory; + FT_Stream stream = face->stream; + + + if ( FT_NEW_ARRAY ( entry->string, entry->stringLength ) || + FT_STREAM_SEEK( entry->stringOffset ) || + FT_STREAM_READ( entry->string, entry->stringLength ) ) + { + FT_FREE( entry->string ); + entry->stringLength = 0; + } + } + + alangTag->string = (FT_Byte*)entry->string; + alangTag->string_len = entry->stringLength; + + error = FT_Err_Ok; + } + } + + return error; + } + + #endif /* TT_CONFIG_OPTION_SFNT_NAMES */ diff --git a/src/3rdparty/freetype/src/base/ftstream.c b/src/3rdparty/freetype/src/base/ftstream.c index b68f3f82d2..18df7dcfef 100644 --- a/src/3rdparty/freetype/src/base/ftstream.c +++ b/src/3rdparty/freetype/src/base/ftstream.c @@ -4,7 +4,7 @@ /* */ /* I/O stream support (body). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -778,7 +778,7 @@ case ft_frame_short_be: case ft_frame_ushort_be: /* read a 2-byte big-endian short */ - value = FT_NEXT_USHORT( cursor) ; + value = FT_NEXT_USHORT( cursor ); sign_shift = 16; break; diff --git a/src/3rdparty/freetype/src/base/ftstroke.c b/src/3rdparty/freetype/src/base/ftstroke.c index fecb3cc25c..6ae1819067 100644 --- a/src/3rdparty/freetype/src/base/ftstroke.c +++ b/src/3rdparty/freetype/src/base/ftstroke.c @@ -4,7 +4,7 @@ /* */ /* FreeType path stroker (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -712,9 +712,10 @@ FT_Outline* outline ) { /* copy point locations */ - FT_ARRAY_COPY( outline->points + outline->n_points, - border->points, - border->num_points ); + if ( border->num_points ) + FT_ARRAY_COPY( outline->points + outline->n_points, + border->points, + border->num_points ); /* copy tags */ { diff --git a/src/3rdparty/freetype/src/base/ftsynth.c b/src/3rdparty/freetype/src/base/ftsynth.c index cd68533957..c28346707b 100644 --- a/src/3rdparty/freetype/src/base/ftsynth.c +++ b/src/3rdparty/freetype/src/base/ftsynth.c @@ -4,7 +4,7 @@ /* */ /* FreeType synthesizing code for emboldening and slanting (body). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -123,14 +123,14 @@ /* * XXX: overflow check for 16-bit system, for compatibility - * with FT_GlyphSlot_Embolden() since freetype-2.1.10. + * with FT_GlyphSlot_Embolden() since FreeType 2.1.10. * unfortunately, this function return no informations * about the cause of error. */ if ( ( ystr >> 6 ) > FT_INT_MAX || ( ystr >> 6 ) < FT_INT_MIN ) { FT_TRACE1(( "FT_GlyphSlot_Embolden:" )); - FT_TRACE1(( "too strong embolding parameter ystr=%d\n", ystr )); + FT_TRACE1(( "too strong emboldening parameter ystr=%d\n", ystr )); return; } error = FT_GlyphSlot_Own_Bitmap( slot ); diff --git a/src/3rdparty/freetype/src/base/ftsystem.c b/src/3rdparty/freetype/src/base/ftsystem.c index 1938fd8917..6adebdb938 100644 --- a/src/3rdparty/freetype/src/base/ftsystem.c +++ b/src/3rdparty/freetype/src/base/ftsystem.c @@ -4,7 +4,7 @@ /* */ /* ANSI-specific FreeType low-level system interface (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/src/base/fttrigon.c b/src/3rdparty/freetype/src/base/fttrigon.c index 5b24304c2f..d6dd098c42 100644 --- a/src/3rdparty/freetype/src/base/fttrigon.c +++ b/src/3rdparty/freetype/src/base/fttrigon.c @@ -4,7 +4,7 @@ /* */ /* FreeType trigonometric functions (body). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -71,7 +71,8 @@ /* 0x40000000 comes from regression analysis between true */ /* and CORDIC hypotenuse, so it minimizes the error */ - val = (FT_Fixed)( ( (FT_Int64)val * FT_TRIG_SCALE + 0x40000000UL ) >> 32 ); + val = (FT_Fixed)( + ( (FT_UInt64)val * FT_TRIG_SCALE + 0x40000000UL ) >> 32 ); return s < 0 ? -val : val; } diff --git a/src/3rdparty/freetype/src/base/fttype1.c b/src/3rdparty/freetype/src/base/fttype1.c index c549382afd..aa8f8ccbbb 100644 --- a/src/3rdparty/freetype/src/base/fttype1.c +++ b/src/3rdparty/freetype/src/base/fttype1.c @@ -4,7 +4,7 @@ /* */ /* FreeType utility file for PS names support (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/src/base/ftutil.c b/src/3rdparty/freetype/src/base/ftutil.c index f5b72db708..4de5f2c145 100644 --- a/src/3rdparty/freetype/src/base/ftutil.c +++ b/src/3rdparty/freetype/src/base/ftutil.c @@ -4,7 +4,7 @@ /* */ /* FreeType utility file for memory and list management (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -74,7 +74,7 @@ if ( size > 0 ) { block = memory->alloc( memory, size ); - if ( block == NULL ) + if ( !block ) error = FT_THROW( Out_Of_Memory ); } else if ( size < 0 ) @@ -135,25 +135,27 @@ ft_mem_free( memory, block ); block = NULL; } - else if ( new_count > FT_INT_MAX/item_size ) + else if ( new_count > FT_INT_MAX / item_size ) { error = FT_THROW( Array_Too_Large ); } else if ( cur_count == 0 ) { - FT_ASSERT( block == NULL ); + FT_ASSERT( !block ); - block = ft_mem_alloc( memory, new_count*item_size, &error ); + block = memory->alloc( memory, new_count * item_size ); + if ( block == NULL ) + error = FT_THROW( Out_Of_Memory ); } else { FT_Pointer block2; - FT_Long cur_size = cur_count*item_size; - FT_Long new_size = new_count*item_size; + FT_Long cur_size = cur_count * item_size; + FT_Long new_size = new_count * item_size; block2 = memory->realloc( memory, cur_size, new_size, block ); - if ( block2 == NULL ) + if ( !block2 ) error = FT_THROW( Out_Of_Memory ); else block = block2; diff --git a/src/3rdparty/freetype/src/base/ftver.rc b/src/3rdparty/freetype/src/base/ftver.rc new file mode 100644 index 0000000000..a2903d5883 --- /dev/null +++ b/src/3rdparty/freetype/src/base/ftver.rc @@ -0,0 +1,61 @@ +/***************************************************************************/ +/* */ +/* ftver.rc */ +/* */ +/* FreeType VERSIONINFO resource for Windows DLLs. */ +/* */ +/* Copyright 2018 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include<windows.h> + +#define FT_VERSION 2,9,1,0 +#define FT_VERSION_STR "2.9.1" + +VS_VERSION_INFO VERSIONINFO +FILEVERSION FT_VERSION +PRODUCTVERSION FT_VERSION +FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG +FILEFLAGS VS_FF_DEBUG +#endif +#ifdef _DLL +FILETYPE VFT_DLL +#define FT_FILENAME "freetype.dll" +#else +FILETYPE VFT_STATIC_LIB +#define FT_FILENAME "freetype.lib" +#endif +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + BEGIN + VALUE "CompanyName", "The FreeType Project" + VALUE "FileDescription", "Font Rendering Library" + VALUE "FileVersion", FT_VERSION_STR + VALUE "ProductName", "FreeType" + VALUE "ProductVersion", FT_VERSION_STR + VALUE "LegalCopyright", "\251 2018 The FreeType Project www.freetype.org. All rights reserved." + VALUE "InternalName", "freetype" + VALUE "OriginalFilename", FT_FILENAME + END + END + + BLOCK "VarFileInfo" + BEGIN + /* The following line should only be modified for localized versions. */ + /* It consists of any number of WORD,WORD pairs, with each pair */ + /* describing a "language,codepage" combination supported by the file. */ + VALUE "Translation", 0x409, 1252 + END +END diff --git a/src/3rdparty/freetype/src/base/ftwinfnt.c b/src/3rdparty/freetype/src/base/ftwinfnt.c index 76a19af983..11bd28afb7 100644 --- a/src/3rdparty/freetype/src/base/ftwinfnt.c +++ b/src/3rdparty/freetype/src/base/ftwinfnt.c @@ -4,7 +4,7 @@ /* */ /* FreeType API for accessing Windows FNT specific info (body). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/src/base/md5.c b/src/3rdparty/freetype/src/base/md5.c index 52d96accd3..b235e17a56 100644 --- a/src/3rdparty/freetype/src/base/md5.c +++ b/src/3rdparty/freetype/src/base/md5.c @@ -63,12 +63,19 @@ (a) += (b); /* - * SET reads 4 input bytes in little-endian byte order and stores them - * in a properly aligned word in host byte order. + * SET reads 4 input bytes in little-endian byte order and stores them in a + * properly aligned word in host byte order. * - * The check for little-endian architectures that tolerate unaligned - * memory accesses is just an optimization. Nothing will break if it - * doesn't work. + * The check for little-endian architectures that tolerate unaligned memory + * accesses is just an optimization. Nothing will break if it fails to detect + * a suitable architecture. + * + * Unfortunately, this optimization may be a C strict aliasing rules violation + * if the caller's data buffer has effective type that cannot be aliased by + * MD5_u32plus. In practice, this problem may occur if these MD5 routines are + * inlined into a calling function, or with future and dangerously advanced + * link-time optimizations. For the time being, keeping these MD5 routines in + * their own translation unit avoids the problem. */ #if defined(__i386__) || defined(__x86_64__) || defined(__vax__) #define SET(n) \ @@ -87,8 +94,8 @@ #endif /* - * This processes one or more 64-byte data blocks, but does NOT update - * the bit counters. There are no alignment requirements. + * This processes one or more 64-byte data blocks, but does NOT update the bit + * counters. There are no alignment requirements. */ static const void *body(MD5_CTX *ctx, const void *data, unsigned long size) { @@ -242,6 +249,12 @@ void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size) memcpy(ctx->buffer, data, size); } +#define OUT(dst, src) \ + (dst)[0] = (unsigned char)(src); \ + (dst)[1] = (unsigned char)((src) >> 8); \ + (dst)[2] = (unsigned char)((src) >> 16); \ + (dst)[3] = (unsigned char)((src) >> 24); + void MD5_Final(unsigned char *result, MD5_CTX *ctx) { unsigned long used, available; @@ -262,33 +275,15 @@ void MD5_Final(unsigned char *result, MD5_CTX *ctx) memset(&ctx->buffer[used], 0, available - 8); ctx->lo <<= 3; - ctx->buffer[56] = ctx->lo; - ctx->buffer[57] = ctx->lo >> 8; - ctx->buffer[58] = ctx->lo >> 16; - ctx->buffer[59] = ctx->lo >> 24; - ctx->buffer[60] = ctx->hi; - ctx->buffer[61] = ctx->hi >> 8; - ctx->buffer[62] = ctx->hi >> 16; - ctx->buffer[63] = ctx->hi >> 24; + OUT(&ctx->buffer[56], ctx->lo) + OUT(&ctx->buffer[60], ctx->hi) body(ctx, ctx->buffer, 64); - result[0] = ctx->a; - result[1] = ctx->a >> 8; - result[2] = ctx->a >> 16; - result[3] = ctx->a >> 24; - result[4] = ctx->b; - result[5] = ctx->b >> 8; - result[6] = ctx->b >> 16; - result[7] = ctx->b >> 24; - result[8] = ctx->c; - result[9] = ctx->c >> 8; - result[10] = ctx->c >> 16; - result[11] = ctx->c >> 24; - result[12] = ctx->d; - result[13] = ctx->d >> 8; - result[14] = ctx->d >> 16; - result[15] = ctx->d >> 24; + OUT(&result[0], ctx->a) + OUT(&result[4], ctx->b) + OUT(&result[8], ctx->c) + OUT(&result[12], ctx->d) memset(ctx, 0, sizeof(*ctx)); } diff --git a/src/3rdparty/freetype/src/base/rules.mk b/src/3rdparty/freetype/src/base/rules.mk index 1852e08613..e9805bd068 100644 --- a/src/3rdparty/freetype/src/base/rules.mk +++ b/src/3rdparty/freetype/src/base/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2015 by +# Copyright 1996-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -40,10 +40,14 @@ BASE_SRC := $(BASE_DIR)/basepic.c \ $(BASE_DIR)/ftadvanc.c \ $(BASE_DIR)/ftcalc.c \ $(BASE_DIR)/ftdbgmem.c \ + $(BASE_DIR)/ftfntfmt.c \ $(BASE_DIR)/ftgloadr.c \ + $(BASE_DIR)/fthash.c \ + $(BASE_DIR)/ftlcdfil.c \ $(BASE_DIR)/ftobjs.c \ $(BASE_DIR)/ftoutln.c \ $(BASE_DIR)/ftpic.c \ + $(BASE_DIR)/ftpsprop.c \ $(BASE_DIR)/ftrfork.c \ $(BASE_DIR)/ftsnames.c \ $(BASE_DIR)/ftstream.c \ diff --git a/src/3rdparty/freetype/src/bdf/Jamfile b/src/3rdparty/freetype/src/bdf/Jamfile index 86b85fa3e4..d9e441c188 100644 --- a/src/3rdparty/freetype/src/bdf/Jamfile +++ b/src/3rdparty/freetype/src/bdf/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/bdf Jamfile # -# Copyright 2002-2015 by +# Copyright 2002-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/bdf/README b/src/3rdparty/freetype/src/bdf/README index b761aba2b2..996ac2d2aa 100644 --- a/src/3rdparty/freetype/src/bdf/README +++ b/src/3rdparty/freetype/src/bdf/README @@ -13,7 +13,7 @@ This code implements a BDF driver for the FreeType library, following the Adobe Specification V 2.2. The specification of the BDF font format is available from Adobe's web site: - http://partners.adobe.com/public/developer/en/font/5005.BDF_Spec.pdf + https://www.adobe.com/content/dam/acom/en/devnet/font/pdfs/5005.BDF_Spec.pdf Many good bitmap fonts in bdf format come with XFree86 (www.XFree86.org). They do not define vertical metrics, because the X Consortium BDF diff --git a/src/3rdparty/freetype/src/bdf/bdf.c b/src/3rdparty/freetype/src/bdf/bdf.c index f95fb76225..e54df6649b 100644 --- a/src/3rdparty/freetype/src/bdf/bdf.c +++ b/src/3rdparty/freetype/src/bdf/bdf.c @@ -24,9 +24,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#define FT_MAKE_OPTION_SINGLE_OBJECT +#define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> + #include "bdflib.c" #include "bdfdrivr.c" diff --git a/src/3rdparty/freetype/src/bdf/bdf.h b/src/3rdparty/freetype/src/bdf/bdf.h index f24d925d8f..9012727c7e 100644 --- a/src/3rdparty/freetype/src/bdf/bdf.h +++ b/src/3rdparty/freetype/src/bdf/bdf.h @@ -22,8 +22,8 @@ */ -#ifndef __BDF_H__ -#define __BDF_H__ +#ifndef BDF_H_ +#define BDF_H_ /* @@ -33,6 +33,7 @@ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_HASH_H FT_BEGIN_HEADER @@ -157,24 +158,6 @@ FT_BEGIN_HEADER } bdf_glyph_t; - typedef struct _hashnode_ - { - const char* key; - size_t data; - - } _hashnode, *hashnode; - - - typedef struct hashtable_ - { - unsigned int limit; - unsigned int size; - unsigned int used; - hashnode* table; - - } hashtable; - - typedef struct bdf_glyphlist_t_ { unsigned short pad; /* Pad to 4-byte boundary. */ @@ -238,7 +221,7 @@ FT_BEGIN_HEADER bdf_property_t* user_props; unsigned long nuser_props; - hashtable proptbl; + FT_HashRec proptbl; } bdf_font_t; @@ -291,7 +274,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __BDF_H__ */ +#endif /* BDF_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/bdf/bdfdrivr.c b/src/3rdparty/freetype/src/bdf/bdfdrivr.c index 404af517e5..ca937f89ce 100644 --- a/src/3rdparty/freetype/src/bdf/bdfdrivr.c +++ b/src/3rdparty/freetype/src/bdf/bdfdrivr.c @@ -276,7 +276,7 @@ THE SOFTWARE. len = lengths[nn]; - if ( src == NULL ) + if ( !src ) continue; /* separate elements with a space */ @@ -373,7 +373,7 @@ THE SOFTWARE. /* we have a bdf font: let's construct the face object */ face->bdffont = font; - /* BDF could not have multiple face in single font file. + /* BDF cannot have multiple faces in a single font file. * XXX: non-zero face_index is already invalid argument, but * Type1, Type42 driver has a convention to return * an invalid argument error when the font could be @@ -423,7 +423,7 @@ THE SOFTWARE. else bdfface->family_name = NULL; - if ( ( error = bdf_interpret_style( face ) ) != 0 ) + if ( FT_SET_ERROR( bdf_interpret_style( face ) ) ) goto Exit; /* the number of glyphs (with one slot for the undefined glyph */ @@ -437,46 +437,156 @@ THE SOFTWARE. { FT_Bitmap_Size* bsize = bdfface->available_sizes; FT_Short resolution_x = 0, resolution_y = 0; + long value; - FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) ); + FT_ZERO( bsize ); + + /* sanity checks */ + if ( font->font_ascent > 0x7FFF || font->font_ascent < -0x7FFF ) + { + font->font_ascent = font->font_ascent < 0 ? -0x7FFF : 0x7FFF; + FT_TRACE0(( "BDF_Face_Init: clamping font ascent to value %d\n", + font->font_ascent )); + } + if ( font->font_descent > 0x7FFF || font->font_descent < -0x7FFF ) + { + font->font_descent = font->font_descent < 0 ? -0x7FFF : 0x7FFF; + FT_TRACE0(( "BDF_Face_Init: clamping font descent to value %d\n", + font->font_descent )); + } bsize->height = (FT_Short)( font->font_ascent + font->font_descent ); prop = bdf_get_font_property( font, "AVERAGE_WIDTH" ); if ( prop ) - bsize->width = (FT_Short)( ( prop->value.l + 5 ) / 10 ); + { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( prop->value.l < 0 ) + FT_TRACE0(( "BDF_Face_Init: negative average width\n" )); +#endif + if ( prop->value.l > 0x7FFFL * 10 - 5 || + prop->value.l < -( 0x7FFFL * 10 - 5 ) ) + { + bsize->width = 0x7FFF; + FT_TRACE0(( "BDF_Face_Init: clamping average width to value %d\n", + bsize->width )); + } + else + bsize->width = FT_ABS( (FT_Short)( ( prop->value.l + 5 ) / 10 ) ); + } else - bsize->width = (FT_Short)( bsize->height * 2/3 ); + { + /* this is a heuristical value */ + bsize->width = (FT_Short)FT_MulDiv( bsize->height, 2, 3 ); + } prop = bdf_get_font_property( font, "POINT_SIZE" ); if ( prop ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( prop->value.l < 0 ) + FT_TRACE0(( "BDF_Face_Init: negative point size\n" )); +#endif /* convert from 722.7 decipoints to 72 points per inch */ - bsize->size = - (FT_Pos)( ( prop->value.l * 64 * 7200 + 36135L ) / 72270L ); + if ( prop->value.l > 0x504C2L || /* 0x7FFF * 72270/7200 */ + prop->value.l < -0x504C2L ) + { + bsize->size = 0x7FFF; + FT_TRACE0(( "BDF_Face_Init: clamping point size to value %d\n", + bsize->size )); + } + else + bsize->size = FT_MulDiv( FT_ABS( prop->value.l ), + 64 * 7200, + 72270L ); + } + else if ( font->point_size ) + { + if ( font->point_size > 0x7FFF ) + { + bsize->size = 0x7FFF; + FT_TRACE0(( "BDF_Face_Init: clamping point size to value %d\n", + bsize->size )); + } + else + bsize->size = (FT_Pos)font->point_size << 6; + } else - bsize->size = bsize->width << 6; + { + /* this is a heuristical value */ + bsize->size = bsize->width * 64; + } prop = bdf_get_font_property( font, "PIXEL_SIZE" ); if ( prop ) - bsize->y_ppem = (FT_Short)prop->value.l << 6; + { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( prop->value.l < 0 ) + FT_TRACE0(( "BDF_Face_Init: negative pixel size\n" )); +#endif + if ( prop->value.l > 0x7FFF || prop->value.l < -0x7FFF ) + { + bsize->y_ppem = 0x7FFF << 6; + FT_TRACE0(( "BDF_Face_Init: clamping pixel size to value %d\n", + bsize->y_ppem )); + } + else + bsize->y_ppem = FT_ABS( (FT_Short)prop->value.l ) << 6; + } prop = bdf_get_font_property( font, "RESOLUTION_X" ); if ( prop ) - resolution_x = (FT_Short)prop->value.l; + value = prop->value.l; + else + value = (long)font->resolution_x; + if ( value ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( value < 0 ) + FT_TRACE0(( "BDF_Face_Init: negative X resolution\n" )); +#endif + if ( value > 0x7FFF || value < -0x7FFF ) + { + resolution_x = 0x7FFF; + FT_TRACE0(( "BDF_Face_Init: clamping X resolution to value %d\n", + resolution_x )); + } + else + resolution_x = FT_ABS( (FT_Short)value ); + } prop = bdf_get_font_property( font, "RESOLUTION_Y" ); if ( prop ) - resolution_y = (FT_Short)prop->value.l; + value = prop->value.l; + else + value = (long)font->resolution_y; + if ( value ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + if ( value < 0 ) + FT_TRACE0(( "BDF_Face_Init: negative Y resolution\n" )); +#endif + if ( value > 0x7FFF || value < -0x7FFF ) + { + resolution_y = 0x7FFF; + FT_TRACE0(( "BDF_Face_Init: clamping Y resolution to value %d\n", + resolution_y )); + } + else + resolution_y = FT_ABS( (FT_Short)value ); + } if ( bsize->y_ppem == 0 ) { bsize->y_ppem = bsize->size; if ( resolution_y ) - bsize->y_ppem = bsize->y_ppem * resolution_y / 72; + bsize->y_ppem = FT_MulDiv( bsize->y_ppem, resolution_y, 72 ); } if ( resolution_x && resolution_y ) - bsize->x_ppem = bsize->y_ppem * resolution_x / resolution_y; + bsize->x_ppem = FT_MulDiv( bsize->y_ppem, + resolution_x, + resolution_y ); else bsize->x_ppem = bsize->y_ppem; } @@ -545,7 +655,11 @@ THE SOFTWARE. if ( !ft_strcmp( s, "10646" ) || ( !ft_strcmp( s, "8859" ) && !ft_strcmp( face->charset_encoding, "1" ) ) ) - unicode_charmap = 1; + unicode_charmap = 1; + /* another name for ASCII */ + else if ( !ft_strcmp( s, "646.1991" ) && + !ft_strcmp( face->charset_encoding, "IRV" ) ) + unicode_charmap = 1; } { @@ -566,12 +680,6 @@ THE SOFTWARE. } error = FT_CMap_New( &bdf_cmap_class, NULL, &charmap, NULL ); - -#if 0 - /* Select default charmap */ - if ( bdfface->num_charmaps ) - bdfface->charmap = bdfface->charmaps[0]; -#endif } goto Exit; @@ -705,7 +813,7 @@ THE SOFTWARE. bitmap->rows = glyph.bbx.height; bitmap->width = glyph.bbx.width; - if ( glyph.bpr > INT_MAX ) + if ( glyph.bpr > FT_INT_MAX ) FT_TRACE1(( "BDF_Glyph_Load: too large pitch %d is truncated\n", glyph.bpr )); bitmap->pitch = (int)glyph.bpr; /* same as FT_Bitmap.pitch */ @@ -824,8 +932,8 @@ THE SOFTWARE. static const FT_Service_BDFRec bdf_service_bdf = { - (FT_BDF_GetCharsetIdFunc)bdf_get_charset_id, - (FT_BDF_GetPropertyFunc) bdf_get_bdf_property + (FT_BDF_GetCharsetIdFunc)bdf_get_charset_id, /* get_charset_id */ + (FT_BDF_GetPropertyFunc) bdf_get_bdf_property /* get_property */ }; @@ -866,32 +974,32 @@ THE SOFTWARE. 0x10000L, 0x20000L, - 0, + NULL, /* module-specific interface */ - 0, /* FT_Module_Constructor */ - 0, /* FT_Module_Destructor */ - bdf_driver_requester + NULL, /* FT_Module_Constructor module_init */ + NULL, /* FT_Module_Destructor module_done */ + bdf_driver_requester /* FT_Module_Requester get_interface */ }, sizeof ( BDF_FaceRec ), sizeof ( FT_SizeRec ), sizeof ( FT_GlyphSlotRec ), - BDF_Face_Init, - BDF_Face_Done, - 0, /* FT_Size_InitFunc */ - 0, /* FT_Size_DoneFunc */ - 0, /* FT_Slot_InitFunc */ - 0, /* FT_Slot_DoneFunc */ + BDF_Face_Init, /* FT_Face_InitFunc init_face */ + BDF_Face_Done, /* FT_Face_DoneFunc done_face */ + NULL, /* FT_Size_InitFunc init_size */ + NULL, /* FT_Size_DoneFunc done_size */ + NULL, /* FT_Slot_InitFunc init_slot */ + NULL, /* FT_Slot_DoneFunc done_slot */ - BDF_Glyph_Load, + BDF_Glyph_Load, /* FT_Slot_LoadFunc load_glyph */ - 0, /* FT_Face_GetKerningFunc */ - 0, /* FT_Face_AttachFunc */ - 0, /* FT_Face_GetAdvancesFunc */ + NULL, /* FT_Face_GetKerningFunc get_kerning */ + NULL, /* FT_Face_AttachFunc attach_file */ + NULL, /* FT_Face_GetAdvancesFunc get_advances */ - BDF_Size_Request, - BDF_Size_Select + BDF_Size_Request, /* FT_Size_RequestFunc request_size */ + BDF_Size_Select /* FT_Size_SelectFunc select_size */ }; diff --git a/src/3rdparty/freetype/src/bdf/bdfdrivr.h b/src/3rdparty/freetype/src/bdf/bdfdrivr.h index 3c61d644f4..94550818c1 100644 --- a/src/3rdparty/freetype/src/bdf/bdfdrivr.h +++ b/src/3rdparty/freetype/src/bdf/bdfdrivr.h @@ -25,8 +25,8 @@ THE SOFTWARE. */ -#ifndef __BDFDRIVR_H__ -#define __BDFDRIVR_H__ +#ifndef BDFDRIVR_H_ +#define BDFDRIVR_H_ #include <ft2build.h> #include FT_INTERNAL_DRIVER_H @@ -74,7 +74,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __BDFDRIVR_H__ */ +#endif /* BDFDRIVR_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/bdf/bdferror.h b/src/3rdparty/freetype/src/bdf/bdferror.h index ea545aca06..b462c7d3b5 100644 --- a/src/3rdparty/freetype/src/bdf/bdferror.h +++ b/src/3rdparty/freetype/src/bdf/bdferror.h @@ -26,12 +26,12 @@ /* */ /*************************************************************************/ -#ifndef __BDFERROR_H__ -#define __BDFERROR_H__ +#ifndef BDFERROR_H_ +#define BDFERROR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX BDF_Err_ @@ -39,7 +39,7 @@ #include FT_ERRORS_H -#endif /* __BDFERROR_H__ */ +#endif /* BDFERROR_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/bdf/bdflib.c b/src/3rdparty/freetype/src/bdf/bdflib.c index 414deb58ad..2f5c99d544 100644 --- a/src/3rdparty/freetype/src/bdf/bdflib.c +++ b/src/3rdparty/freetype/src/bdf/bdflib.c @@ -201,6 +201,7 @@ #define ACMSG14 "Glyph %ld extra columns removed.\n" #define ACMSG15 "Incorrect glyph count: %ld indicated but %ld found.\n" #define ACMSG16 "Glyph %ld missing columns padded with zero bits.\n" +#define ACMSG17 "Adjusting number of glyphs to %ld.\n" /* Error messages. */ #define ERRMSG1 "[line %ld] Missing `%s' line.\n" @@ -218,164 +219,6 @@ #define DBGMSG2 " (0x%lX)\n" - /*************************************************************************/ - /* */ - /* Hash table utilities for the properties. */ - /* */ - /*************************************************************************/ - - /* XXX: Replace this with FreeType's hash functions */ - - -#define INITIAL_HT_SIZE 241 - - typedef void - (*hash_free_func)( hashnode node ); - - static hashnode* - hash_bucket( const char* key, - hashtable* ht ) - { - const char* kp = key; - unsigned long res = 0; - hashnode* bp = ht->table, *ndp; - - - /* Mocklisp hash function. */ - while ( *kp ) - res = ( res << 5 ) - res + (unsigned long)*kp++; - - ndp = bp + ( res % ht->size ); - while ( *ndp ) - { - kp = (*ndp)->key; - if ( kp[0] == key[0] && ft_strcmp( kp, key ) == 0 ) - break; - ndp--; - if ( ndp < bp ) - ndp = bp + ( ht->size - 1 ); - } - - return ndp; - } - - - static FT_Error - hash_rehash( hashtable* ht, - FT_Memory memory ) - { - hashnode* obp = ht->table, *bp, *nbp; - unsigned int i, sz = ht->size; - FT_Error error = FT_Err_Ok; - - - ht->size <<= 1; - ht->limit = ht->size / 3; - - if ( FT_NEW_ARRAY( ht->table, ht->size ) ) - goto Exit; - - for ( i = 0, bp = obp; i < sz; i++, bp++ ) - { - if ( *bp ) - { - nbp = hash_bucket( (*bp)->key, ht ); - *nbp = *bp; - } - } - FT_FREE( obp ); - - Exit: - return error; - } - - - static FT_Error - hash_init( hashtable* ht, - FT_Memory memory ) - { - unsigned int sz = INITIAL_HT_SIZE; - FT_Error error = FT_Err_Ok; - - - ht->size = sz; - ht->limit = sz / 3; - ht->used = 0; - - if ( FT_NEW_ARRAY( ht->table, sz ) ) - goto Exit; - - Exit: - return error; - } - - - static void - hash_free( hashtable* ht, - FT_Memory memory ) - { - if ( ht != 0 ) - { - unsigned int i, sz = ht->size; - hashnode* bp = ht->table; - - - for ( i = 0; i < sz; i++, bp++ ) - FT_FREE( *bp ); - - FT_FREE( ht->table ); - } - } - - - static FT_Error - hash_insert( char* key, - size_t data, - hashtable* ht, - FT_Memory memory ) - { - hashnode nn; - hashnode* bp = hash_bucket( key, ht ); - FT_Error error = FT_Err_Ok; - - - nn = *bp; - if ( !nn ) - { - if ( FT_NEW( nn ) ) - goto Exit; - *bp = nn; - - nn->key = key; - nn->data = data; - - if ( ht->used >= ht->limit ) - { - error = hash_rehash( ht, memory ); - if ( error ) - goto Exit; - } - ht->used++; - } - else - nn->data = data; - - Exit: - return error; - } - - - static hashnode - hash_lookup( const char* key, - hashtable* ht ) - { - hashnode *np = hash_bucket( key, ht ); - - - return *np; - } - - /*************************************************************************/ /* */ /* Utility types and functions. */ @@ -432,6 +275,7 @@ _bdf_list_t list; FT_Memory memory; + unsigned long size; /* the stream size */ } _bdf_parse_t; @@ -832,14 +676,6 @@ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - static const unsigned char odigits[32] = - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - }; - static const unsigned char ddigits[32] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x03, @@ -857,81 +693,41 @@ }; - /* Routine to convert an ASCII string into an unsigned long integer. */ + /* Routine to convert a decimal ASCII string to an unsigned long integer. */ static unsigned long - _bdf_atoul( char* s, - char** end, - unsigned int base ) + _bdf_atoul( char* s ) { - unsigned long v; - const unsigned char* dmap; + unsigned long v; if ( s == 0 || *s == 0 ) return 0; - /* Make sure the radix is something recognizable. Default to 10. */ - switch ( base ) + for ( v = 0; sbitset( ddigits, *s ); s++ ) { - case 8: - dmap = odigits; - break; - case 16: - dmap = hdigits; - break; - default: - base = 10; - dmap = ddigits; - break; + if ( v < ( FT_ULONG_MAX - 9 ) / 10 ) + v = v * 10 + a2i[(int)*s]; + else + { + v = FT_ULONG_MAX; + break; + } } - /* Check for the special hex prefix. */ - if ( *s == '0' && - ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) ) - { - base = 16; - dmap = hdigits; - s += 2; - } - - for ( v = 0; sbitset( dmap, *s ); s++ ) - v = v * base + a2i[(int)*s]; - - if ( end != 0 ) - *end = s; - return v; } - /* Routine to convert an ASCII string into a signed long integer. */ + /* Routine to convert a decimal ASCII string to a signed long integer. */ static long - _bdf_atol( char* s, - char** end, - int base ) + _bdf_atol( char* s ) { - long v, neg; - const unsigned char* dmap; + long v, neg; if ( s == 0 || *s == 0 ) return 0; - /* Make sure the radix is something recognizable. Default to 10. */ - switch ( base ) - { - case 8: - dmap = odigits; - break; - case 16: - dmap = hdigits; - break; - default: - base = 10; - dmap = ddigits; - break; - } - /* Check for a minus sign. */ neg = 0; if ( *s == '-' ) @@ -940,100 +736,56 @@ neg = 1; } - /* Check for the special hex prefix. */ - if ( *s == '0' && - ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) ) + for ( v = 0; sbitset( ddigits, *s ); s++ ) { - base = 16; - dmap = hdigits; - s += 2; + if ( v < ( FT_LONG_MAX - 9 ) / 10 ) + v = v * 10 + a2i[(int)*s]; + else + { + v = FT_LONG_MAX; + break; + } } - for ( v = 0; sbitset( dmap, *s ); s++ ) - v = v * base + a2i[(int)*s]; - - if ( end != 0 ) - *end = s; - return ( !neg ) ? v : -v; } - /* Routine to convert an ASCII string into an unsigned short integer. */ + /* Routine to convert a decimal ASCII string to an unsigned short integer. */ static unsigned short - _bdf_atous( char* s, - char** end, - unsigned int base ) + _bdf_atous( char* s ) { - unsigned short v; - const unsigned char* dmap; + unsigned short v; if ( s == 0 || *s == 0 ) return 0; - /* Make sure the radix is something recognizable. Default to 10. */ - switch ( base ) + for ( v = 0; sbitset( ddigits, *s ); s++ ) { - case 8: - dmap = odigits; - break; - case 16: - dmap = hdigits; - break; - default: - base = 10; - dmap = ddigits; - break; + if ( v < ( FT_USHORT_MAX - 9 ) / 10 ) + v = (unsigned short)( v * 10 + a2i[(int)*s] ); + else + { + v = FT_USHORT_MAX; + break; + } } - /* Check for the special hex prefix. */ - if ( *s == '0' && - ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) ) - { - base = 16; - dmap = hdigits; - s += 2; - } - - for ( v = 0; sbitset( dmap, *s ); s++ ) - v = (unsigned short)( v * base + a2i[(int)*s] ); - - if ( end != 0 ) - *end = s; - return v; } - /* Routine to convert an ASCII string into a signed short integer. */ + /* Routine to convert a decimal ASCII string to a signed short integer. */ static short - _bdf_atos( char* s, - char** end, - int base ) + _bdf_atos( char* s ) { - short v, neg; - const unsigned char* dmap; + short v, neg; if ( s == 0 || *s == 0 ) return 0; - /* Make sure the radix is something recognizable. Default to 10. */ - switch ( base ) - { - case 8: - dmap = odigits; - break; - case 16: - dmap = hdigits; - break; - default: - base = 10; - dmap = ddigits; - break; - } - /* Check for a minus. */ neg = 0; if ( *s == '-' ) @@ -1042,21 +794,17 @@ neg = 1; } - /* Check for the special hex prefix. */ - if ( *s == '0' && - ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) ) + for ( v = 0; sbitset( ddigits, *s ); s++ ) { - base = 16; - dmap = hdigits; - s += 2; + if ( v < ( SHRT_MAX - 9 ) / 10 ) + v = (short)( v * 10 + a2i[(int)*s] ); + else + { + v = SHRT_MAX; + break; + } } - for ( v = 0; sbitset( dmap, *s ); s++ ) - v = (short)( v * base + a2i[(int)*s] ); - - if ( end != 0 ) - *end = s; - return (short)( ( !neg ) ? v : -v ); } @@ -1096,7 +844,7 @@ /* First check whether the property has */ /* already been added or not. If it has, then */ /* simply ignore it. */ - if ( hash_lookup( name, &(font->proptbl) ) ) + if ( ft_hash_str_lookup( name, &(font->proptbl) ) ) goto Exit; if ( FT_RENEW_ARRAY( font->user_props, @@ -1121,7 +869,7 @@ n = _num_bdf_properties + font->nuser_props; - error = hash_insert( p->name, n, &(font->proptbl), memory ); + error = ft_hash_str_insert( p->name, n, &(font->proptbl), memory ); if ( error ) goto Exit; @@ -1132,25 +880,23 @@ } - FT_LOCAL_DEF( bdf_property_t * ) + FT_LOCAL_DEF( bdf_property_t* ) bdf_get_property( char* name, bdf_font_t* font ) { - hashnode hn; - size_t propid; + size_t* propid; if ( name == 0 || *name == 0 ) return 0; - if ( ( hn = hash_lookup( name, &(font->proptbl) ) ) == 0 ) + if ( ( propid = ft_hash_str_lookup( name, &(font->proptbl) ) ) == NULL ) return 0; - propid = hn->data; - if ( propid >= _num_bdf_properties ) - return font->user_props + ( propid - _num_bdf_properties ); + if ( *propid >= _num_bdf_properties ) + return font->user_props + ( *propid - _num_bdf_properties ); - return (bdf_property_t*)_bdf_properties + propid; + return (bdf_property_t*)_bdf_properties + *propid; } @@ -1163,30 +909,30 @@ /* Parse flags. */ -#define _BDF_START 0x0001U -#define _BDF_FONT_NAME 0x0002U -#define _BDF_SIZE 0x0004U -#define _BDF_FONT_BBX 0x0008U -#define _BDF_PROPS 0x0010U -#define _BDF_GLYPHS 0x0020U -#define _BDF_GLYPH 0x0040U -#define _BDF_ENCODING 0x0080U -#define _BDF_SWIDTH 0x0100U -#define _BDF_DWIDTH 0x0200U -#define _BDF_BBX 0x0400U -#define _BDF_BITMAP 0x0800U +#define BDF_START_ 0x0001U +#define BDF_FONT_NAME_ 0x0002U +#define BDF_SIZE_ 0x0004U +#define BDF_FONT_BBX_ 0x0008U +#define BDF_PROPS_ 0x0010U +#define BDF_GLYPHS_ 0x0020U +#define BDF_GLYPH_ 0x0040U +#define BDF_ENCODING_ 0x0080U +#define BDF_SWIDTH_ 0x0100U +#define BDF_DWIDTH_ 0x0200U +#define BDF_BBX_ 0x0400U +#define BDF_BITMAP_ 0x0800U -#define _BDF_SWIDTH_ADJ 0x1000U +#define BDF_SWIDTH_ADJ_ 0x1000U -#define _BDF_GLYPH_BITS ( _BDF_GLYPH | \ - _BDF_ENCODING | \ - _BDF_SWIDTH | \ - _BDF_DWIDTH | \ - _BDF_BBX | \ - _BDF_BITMAP ) +#define BDF_GLYPH_BITS_ ( BDF_GLYPH_ | \ + BDF_ENCODING_ | \ + BDF_SWIDTH_ | \ + BDF_DWIDTH_ | \ + BDF_BBX_ | \ + BDF_BITMAP_ ) -#define _BDF_GLYPH_WIDTH_CHECK 0x40000000UL -#define _BDF_GLYPH_HEIGHT_CHECK 0x80000000UL +#define BDF_GLYPH_WIDTH_CHECK_ 0x40000000UL +#define BDF_GLYPH_HEIGHT_CHECK_ 0x80000000UL static FT_Error @@ -1358,8 +1104,7 @@ char* value, unsigned long lineno ) { - size_t propid; - hashnode hn; + size_t* propid; bdf_property_t *prop, *fp; FT_Memory memory = font->memory; FT_Error error = FT_Err_Ok; @@ -1368,11 +1113,12 @@ /* First, check whether the property already exists in the font. */ - if ( ( hn = hash_lookup( name, (hashtable *)font->internal ) ) != 0 ) + if ( ( propid = ft_hash_str_lookup( name, + (FT_Hash)font->internal ) ) != NULL ) { /* The property already exists in the font, so simply replace */ /* the value of the property with the current value. */ - fp = font->props + hn->data; + fp = font->props + *propid; switch ( fp->format ) { @@ -1388,11 +1134,11 @@ break; case BDF_INTEGER: - fp->value.l = _bdf_atol( value, 0, 10 ); + fp->value.l = _bdf_atol( value ); break; case BDF_CARDINAL: - fp->value.ul = _bdf_atoul( value, 0, 10 ); + fp->value.ul = _bdf_atoul( value ); break; default: @@ -1404,16 +1150,16 @@ /* See whether this property type exists yet or not. */ /* If not, create it. */ - hn = hash_lookup( name, &(font->proptbl) ); - if ( hn == 0 ) + propid = ft_hash_str_lookup( name, &(font->proptbl) ); + if ( !propid ) { error = bdf_create_property( name, BDF_ATOM, font ); if ( error ) goto Exit; - hn = hash_lookup( name, &(font->proptbl) ); + propid = ft_hash_str_lookup( name, &(font->proptbl) ); } - /* Allocate another property if this is overflow. */ + /* Allocate another property if this is overflowing. */ if ( font->props_used == font->props_size ) { if ( font->props_size == 0 ) @@ -1430,15 +1176,14 @@ } fp = font->props + font->props_size; - FT_MEM_ZERO( fp, sizeof ( bdf_property_t ) ); + FT_ZERO( fp ); font->props_size++; } - propid = hn->data; - if ( propid >= _num_bdf_properties ) - prop = font->user_props + ( propid - _num_bdf_properties ); + if ( *propid >= _num_bdf_properties ) + prop = font->user_props + ( *propid - _num_bdf_properties ); else - prop = (bdf_property_t*)_bdf_properties + propid; + prop = (bdf_property_t*)_bdf_properties + *propid; fp = font->props + font->props_used; @@ -1458,11 +1203,11 @@ break; case BDF_INTEGER: - fp->value.l = _bdf_atol( value, 0, 10 ); + fp->value.l = _bdf_atol( value ); break; case BDF_CARDINAL: - fp->value.ul = _bdf_atoul( value, 0, 10 ); + fp->value.ul = _bdf_atoul( value ); break; } @@ -1471,10 +1216,10 @@ if ( _bdf_strncmp( name, "COMMENT", 7 ) != 0 ) { /* Add the property to the font property table. */ - error = hash_insert( fp->name, - font->props_used, - (hashtable *)font->internal, - memory ); + error = ft_hash_str_insert( fp->name, + font->props_used, + (FT_Hash)font->internal, + memory ); if ( error ) goto Exit; } @@ -1565,7 +1310,7 @@ } /* The very first thing expected is the number of glyphs. */ - if ( !( p->flags & _BDF_GLYPHS ) ) + if ( !( p->flags & BDF_GLYPHS_ ) ) { if ( _bdf_strncmp( line, "CHARS", 5 ) != 0 ) { @@ -1577,7 +1322,14 @@ error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; - p->cnt = font->glyphs_size = _bdf_atoul( p->list.field[1], 0, 10 ); + p->cnt = font->glyphs_size = _bdf_atoul( p->list.field[1] ); + + /* We need at least 20 bytes per glyph. */ + if ( p->cnt > p->size / 20 ) + { + p->cnt = font->glyphs_size = p->size / 20; + FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG17, p->cnt )); + } /* Make sure the number of glyphs is non-zero. */ if ( p->cnt == 0 ) @@ -1595,7 +1347,7 @@ if ( FT_NEW_ARRAY( font->glyphs, font->glyphs_size ) ) goto Exit; - p->flags |= _BDF_GLYPHS; + p->flags |= BDF_GLYPHS_; goto Exit; } @@ -1603,7 +1355,7 @@ /* Check for the ENDFONT field. */ if ( _bdf_strncmp( line, "ENDFONT", 7 ) == 0 ) { - if ( p->flags & _BDF_GLYPH_BITS ) + if ( p->flags & BDF_GLYPH_BITS_ ) { /* Missing ENDCHAR field. */ FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "ENDCHAR" )); @@ -1617,7 +1369,7 @@ sizeof ( bdf_glyph_t ), by_encoding ); - p->flags &= ~_BDF_START; + p->flags &= ~BDF_START_; goto Exit; } @@ -1626,14 +1378,14 @@ if ( _bdf_strncmp( line, "ENDCHAR", 7 ) == 0 ) { p->glyph_enc = 0; - p->flags &= ~_BDF_GLYPH_BITS; + p->flags &= ~BDF_GLYPH_BITS_; goto Exit; } /* Check whether a glyph is being scanned but should be */ /* ignored because it is an unencoded glyph. */ - if ( ( p->flags & _BDF_GLYPH ) && + if ( ( p->flags & BDF_GLYPH_ ) && p->glyph_enc == -1 && p->opts->keep_unencoded == 0 ) goto Exit; @@ -1641,6 +1393,14 @@ /* Check for the STARTCHAR field. */ if ( _bdf_strncmp( line, "STARTCHAR", 9 ) == 0 ) { + if ( p->flags & BDF_GLYPH_BITS_ ) + { + /* Missing ENDCHAR field. */ + FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "ENDCHAR" )); + error = FT_THROW( Missing_Startchar_Field ); + goto Exit; + } + /* Set the character name in the parse info first until the */ /* encoding can be checked for an unencoded character. */ FT_FREE( p->glyph_name ); @@ -1665,7 +1425,7 @@ FT_MEM_COPY( p->glyph_name, s, slen + 1 ); - p->flags |= _BDF_GLYPH; + p->flags |= BDF_GLYPH_; FT_TRACE4(( DBGMSG1, lineno, s )); @@ -1675,7 +1435,7 @@ /* Check for the ENCODING field. */ if ( _bdf_strncmp( line, "ENCODING", 8 ) == 0 ) { - if ( !( p->flags & _BDF_GLYPH ) ) + if ( !( p->flags & BDF_GLYPH_ ) ) { /* Missing STARTCHAR field. */ FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "STARTCHAR" )); @@ -1687,7 +1447,7 @@ if ( error ) goto Exit; - p->glyph_enc = _bdf_atol( p->list.field[1], 0, 10 ); + p->glyph_enc = _bdf_atol( p->list.field[1] ); /* Normalize negative encoding values. The specification only */ /* allows -1, but we can be more generous here. */ @@ -1696,7 +1456,7 @@ /* Check for alternative encoding format. */ if ( p->glyph_enc == -1 && p->list.used > 2 ) - p->glyph_enc = _bdf_atol( p->list.field[2], 0, 10 ); + p->glyph_enc = _bdf_atol( p->list.field[2] ); if ( p->glyph_enc < -1 ) p->glyph_enc = -1; @@ -1773,20 +1533,25 @@ glyph = font->unencoded + font->unencoded_used; glyph->name = p->glyph_name; glyph->encoding = (long)font->unencoded_used++; + + /* Reset the initial glyph info. */ + p->glyph_name = NULL; } else + { /* Free up the glyph name if the unencoded shouldn't be */ /* kept. */ FT_FREE( p->glyph_name ); + } p->glyph_name = NULL; } /* Clear the flags that might be added when width and height are */ /* checked for consistency. */ - p->flags &= ~( _BDF_GLYPH_WIDTH_CHECK | _BDF_GLYPH_HEIGHT_CHECK ); + p->flags &= ~( BDF_GLYPH_WIDTH_CHECK_ | BDF_GLYPH_HEIGHT_CHECK_ ); - p->flags |= _BDF_ENCODING; + p->flags |= BDF_ENCODING_; goto Exit; } @@ -1798,16 +1563,16 @@ glyph = font->glyphs + ( font->glyphs_used - 1 ); /* Check whether a bitmap is being constructed. */ - if ( p->flags & _BDF_BITMAP ) + if ( p->flags & BDF_BITMAP_ ) { /* If there are more rows than are specified in the glyph metrics, */ /* ignore the remaining lines. */ if ( p->row >= (unsigned long)glyph->bbx.height ) { - if ( !( p->flags & _BDF_GLYPH_HEIGHT_CHECK ) ) + if ( !( p->flags & BDF_GLYPH_HEIGHT_CHECK_ ) ) { FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG13, glyph->encoding )); - p->flags |= _BDF_GLYPH_HEIGHT_CHECK; + p->flags |= BDF_GLYPH_HEIGHT_CHECK_; font->modified = 1; } @@ -1832,10 +1597,10 @@ /* If any line has not enough columns, */ /* indicate they have been padded with zero bits. */ if ( i < nibbles && - !( p->flags & _BDF_GLYPH_WIDTH_CHECK ) ) + !( p->flags & BDF_GLYPH_WIDTH_CHECK_ ) ) { FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG16, glyph->encoding )); - p->flags |= _BDF_GLYPH_WIDTH_CHECK; + p->flags |= BDF_GLYPH_WIDTH_CHECK_; font->modified = 1; } @@ -1847,10 +1612,10 @@ /* If any line has extra columns, indicate they have been removed. */ if ( i == nibbles && sbitset( hdigits, line[nibbles] ) && - !( p->flags & _BDF_GLYPH_WIDTH_CHECK ) ) + !( p->flags & BDF_GLYPH_WIDTH_CHECK_ ) ) { FT_TRACE2(( "_bdf_parse_glyphs: " ACMSG14, glyph->encoding )); - p->flags |= _BDF_GLYPH_WIDTH_CHECK; + p->flags |= BDF_GLYPH_WIDTH_CHECK_; font->modified = 1; } @@ -1861,15 +1626,15 @@ /* Expect the SWIDTH (scalable width) field next. */ if ( _bdf_strncmp( line, "SWIDTH", 6 ) == 0 ) { - if ( !( p->flags & _BDF_ENCODING ) ) + if ( !( p->flags & BDF_ENCODING_ ) ) goto Missing_Encoding; error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; - glyph->swidth = (unsigned short)_bdf_atoul( p->list.field[1], 0, 10 ); - p->flags |= _BDF_SWIDTH; + glyph->swidth = (unsigned short)_bdf_atoul( p->list.field[1] ); + p->flags |= BDF_SWIDTH_; goto Exit; } @@ -1877,16 +1642,16 @@ /* Expect the DWIDTH (scalable width) field next. */ if ( _bdf_strncmp( line, "DWIDTH", 6 ) == 0 ) { - if ( !( p->flags & _BDF_ENCODING ) ) + if ( !( p->flags & BDF_ENCODING_ ) ) goto Missing_Encoding; error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; - glyph->dwidth = (unsigned short)_bdf_atoul( p->list.field[1], 0, 10 ); + glyph->dwidth = (unsigned short)_bdf_atoul( p->list.field[1] ); - if ( !( p->flags & _BDF_SWIDTH ) ) + if ( !( p->flags & BDF_SWIDTH_ ) ) { /* Missing SWIDTH field. Emit an auto correction message and set */ /* the scalable width from the device width. */ @@ -1898,24 +1663,24 @@ font->resolution_x ) ); } - p->flags |= _BDF_DWIDTH; + p->flags |= BDF_DWIDTH_; goto Exit; } /* Expect the BBX field next. */ if ( _bdf_strncmp( line, "BBX", 3 ) == 0 ) { - if ( !( p->flags & _BDF_ENCODING ) ) + if ( !( p->flags & BDF_ENCODING_ ) ) goto Missing_Encoding; error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; - glyph->bbx.width = _bdf_atous( p->list.field[1], 0, 10 ); - glyph->bbx.height = _bdf_atous( p->list.field[2], 0, 10 ); - glyph->bbx.x_offset = _bdf_atos( p->list.field[3], 0, 10 ); - glyph->bbx.y_offset = _bdf_atos( p->list.field[4], 0, 10 ); + glyph->bbx.width = _bdf_atous( p->list.field[1] ); + glyph->bbx.height = _bdf_atous( p->list.field[2] ); + glyph->bbx.x_offset = _bdf_atos( p->list.field[3] ); + glyph->bbx.y_offset = _bdf_atos( p->list.field[4] ); /* Generate the ascent and descent of the character. */ glyph->bbx.ascent = (short)( glyph->bbx.height + glyph->bbx.y_offset ); @@ -1932,7 +1697,7 @@ p->minlb = (short)FT_MIN( glyph->bbx.x_offset, p->minlb ); p->maxlb = (short)FT_MAX( glyph->bbx.x_offset, p->maxlb ); - if ( !( p->flags & _BDF_DWIDTH ) ) + if ( !( p->flags & BDF_DWIDTH_ ) ) { /* Missing DWIDTH field. Emit an auto correction message and set */ /* the device width to the glyph width. */ @@ -1961,12 +1726,12 @@ else _bdf_set_glyph_modified( font->nmod, glyph->encoding ); - p->flags |= _BDF_SWIDTH_ADJ; + p->flags |= BDF_SWIDTH_ADJ_; font->modified = 1; } } - p->flags |= _BDF_BBX; + p->flags |= BDF_BBX_; goto Exit; } @@ -1976,7 +1741,7 @@ unsigned long bitmap_size; - if ( !( p->flags & _BDF_BBX ) ) + if ( !( p->flags & BDF_BBX_ ) ) { /* Missing BBX field. */ FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG1, lineno, "BBX" )); @@ -2001,7 +1766,7 @@ goto Exit; p->row = 0; - p->flags |= _BDF_BITMAP; + p->flags |= BDF_BITMAP_; goto Exit; } @@ -2016,7 +1781,7 @@ error = FT_THROW( Missing_Encoding_Field ); Exit: - if ( error && ( p->flags & _BDF_GLYPH ) ) + if ( error && ( p->flags & BDF_GLYPH_ ) ) FT_FREE( p->glyph_name ); return error; @@ -2080,7 +1845,7 @@ p->font->modified = 1; } - p->flags &= ~_BDF_PROPS; + p->flags &= ~BDF_PROPS_; *next = _bdf_parse_glyphs; goto Exit; @@ -2178,7 +1943,7 @@ goto Exit; } - if ( !( p->flags & _BDF_START ) ) + if ( !( p->flags & BDF_START_ ) ) { memory = p->memory; @@ -2190,7 +1955,7 @@ goto Exit; } - p->flags = _BDF_START; + p->flags = BDF_START_; font = p->font = 0; if ( FT_NEW( font ) ) @@ -2205,22 +1970,22 @@ bdf_property_t* prop; - error = hash_init( &(font->proptbl), memory ); + error = ft_hash_str_init( &(font->proptbl), memory ); if ( error ) goto Exit; for ( i = 0, prop = (bdf_property_t*)_bdf_properties; i < _num_bdf_properties; i++, prop++ ) { - error = hash_insert( prop->name, i, - &(font->proptbl), memory ); + error = ft_hash_str_insert( prop->name, i, + &(font->proptbl), memory ); if ( error ) goto Exit; } } - if ( FT_ALLOC( p->font->internal, sizeof ( hashtable ) ) ) + if ( FT_ALLOC( p->font->internal, sizeof ( FT_HashRec ) ) ) goto Exit; - error = hash_init( (hashtable *)p->font->internal,memory ); + error = ft_hash_str_init( (FT_Hash)p->font->internal, memory ); if ( error ) goto Exit; p->font->spacing = p->opts->font_spacing; @@ -2232,7 +1997,7 @@ /* Check for the start of the properties. */ if ( _bdf_strncmp( line, "STARTPROPERTIES", 15 ) == 0 ) { - if ( !( p->flags & _BDF_FONT_BBX ) ) + if ( !( p->flags & BDF_FONT_BBX_ ) ) { /* Missing the FONTBOUNDINGBOX field. */ FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "FONTBOUNDINGBOX" )); @@ -2243,8 +2008,18 @@ error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); if ( error ) goto Exit; + /* at this point, `p->font' can't be NULL */ - p->cnt = p->font->props_size = _bdf_atoul( p->list.field[1], 0, 10 ); + p->cnt = p->font->props_size = _bdf_atoul( p->list.field[1] ); + /* We need at least 4 bytes per property. */ + if ( p->cnt > p->size / 4 ) + { + p->font->props_size = 0; + + FT_ERROR(( "_bdf_parse_glyphs: " ERRMSG5, lineno, "STARTPROPERTIES" )); + error = FT_THROW( Invalid_Argument ); + goto Exit; + } if ( FT_NEW_ARRAY( p->font->props, p->cnt ) ) { @@ -2252,7 +2027,7 @@ goto Exit; } - p->flags |= _BDF_PROPS; + p->flags |= BDF_PROPS_; *next = _bdf_parse_properties; goto Exit; @@ -2261,7 +2036,7 @@ /* Check for the FONTBOUNDINGBOX field. */ if ( _bdf_strncmp( line, "FONTBOUNDINGBOX", 15 ) == 0 ) { - if ( !( p->flags & _BDF_SIZE ) ) + if ( !( p->flags & BDF_SIZE_ ) ) { /* Missing the SIZE field. */ FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "SIZE" )); @@ -2273,18 +2048,18 @@ if ( error ) goto Exit; - p->font->bbx.width = _bdf_atous( p->list.field[1], 0, 10 ); - p->font->bbx.height = _bdf_atous( p->list.field[2], 0, 10 ); + p->font->bbx.width = _bdf_atous( p->list.field[1] ); + p->font->bbx.height = _bdf_atous( p->list.field[2] ); - p->font->bbx.x_offset = _bdf_atos( p->list.field[3], 0, 10 ); - p->font->bbx.y_offset = _bdf_atos( p->list.field[4], 0, 10 ); + p->font->bbx.x_offset = _bdf_atos( p->list.field[3] ); + p->font->bbx.y_offset = _bdf_atos( p->list.field[4] ); p->font->bbx.ascent = (short)( p->font->bbx.height + p->font->bbx.y_offset ); p->font->bbx.descent = (short)( -p->font->bbx.y_offset ); - p->flags |= _BDF_FONT_BBX; + p->flags |= BDF_FONT_BBX_; goto Exit; } @@ -2319,7 +2094,7 @@ if ( error ) goto Exit; - p->flags |= _BDF_FONT_NAME; + p->flags |= BDF_FONT_NAME_; goto Exit; } @@ -2327,7 +2102,7 @@ /* Check for the SIZE field. */ if ( _bdf_strncmp( line, "SIZE", 4 ) == 0 ) { - if ( !( p->flags & _BDF_FONT_NAME ) ) + if ( !( p->flags & BDF_FONT_NAME_ ) ) { /* Missing the FONT field. */ FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "FONT" )); @@ -2339,9 +2114,9 @@ if ( error ) goto Exit; - p->font->point_size = _bdf_atoul( p->list.field[1], 0, 10 ); - p->font->resolution_x = _bdf_atoul( p->list.field[2], 0, 10 ); - p->font->resolution_y = _bdf_atoul( p->list.field[3], 0, 10 ); + p->font->point_size = _bdf_atoul( p->list.field[1] ); + p->font->resolution_x = _bdf_atoul( p->list.field[2] ); + p->font->resolution_y = _bdf_atoul( p->list.field[3] ); /* Check for the bits per pixel field. */ if ( p->list.used == 5 ) @@ -2349,7 +2124,7 @@ unsigned short bpp; - bpp = (unsigned short)_bdf_atos( p->list.field[4], 0, 10 ); + bpp = (unsigned short)_bdf_atos( p->list.field[4] ); /* Only values 1, 2, 4, 8 are allowed for greymap fonts. */ if ( bpp > 4 ) @@ -2367,7 +2142,7 @@ else p->font->bpp = 1; - p->flags |= _BDF_SIZE; + p->flags |= BDF_SIZE_; goto Exit; } @@ -2378,7 +2153,7 @@ char nbuf[128]; - if ( !( p->flags & _BDF_FONT_BBX ) ) + if ( !( p->flags & BDF_FONT_BBX_ ) ) { /* Missing the FONTBOUNDINGBOX field. */ FT_ERROR(( "_bdf_parse_start: " ERRMSG1, lineno, "FONTBOUNDINGBOX" )); @@ -2447,6 +2222,7 @@ memory = NULL; p->opts = (bdf_options_t*)( ( opts != 0 ) ? opts : &_bdf_opts ); p->minlb = 32767; + p->size = stream->size; p->memory = extmemory; /* only during font creation */ _bdf_list_init( &p->list, extmemory ); @@ -2518,27 +2294,27 @@ p->font->bbx.height = (unsigned short)( p->maxas + p->maxds ); } - if ( p->flags & _BDF_SWIDTH_ADJ ) + if ( p->flags & BDF_SWIDTH_ADJ_ ) FT_TRACE2(( "bdf_load_font: " ACMSG8 )); } } - if ( p->flags & _BDF_START ) + if ( p->flags & BDF_START_ ) { /* The ENDFONT field was never reached or did not exist. */ - if ( !( p->flags & _BDF_GLYPHS ) ) + if ( !( p->flags & BDF_GLYPHS_ ) ) { /* Error happened while parsing header. */ FT_ERROR(( "bdf_load_font: " ERRMSG2, lineno )); error = FT_THROW( Corrupted_Font_Header ); - goto Exit; + goto Fail; } else { /* Error happened when parsing glyphs. */ FT_ERROR(( "bdf_load_font: " ERRMSG3, lineno )); error = FT_THROW( Corrupted_Font_Glyphs ); - goto Exit; + goto Fail; } } @@ -2557,7 +2333,7 @@ p->font->comments[p->font->comments_len] = 0; } } - else if ( error == FT_Err_Ok ) + else if ( !error ) error = FT_THROW( Invalid_File_Format ); *font = p->font; @@ -2569,6 +2345,7 @@ memory = extmemory; + FT_FREE( p->glyph_name ); FT_FREE( p ); } @@ -2604,7 +2381,7 @@ /* Free up the internal hash table of property names. */ if ( font->internal ) { - hash_free( (hashtable *)font->internal, memory ); + ft_hash_str_free( (FT_Hash)font->internal, memory ); FT_FREE( font->internal ); } @@ -2649,7 +2426,7 @@ FT_FREE( font->overflow.glyphs ); /* bdf_cleanup */ - hash_free( &(font->proptbl), memory ); + ft_hash_str_free( &(font->proptbl), memory ); /* Free up the user defined properties. */ for ( prop = font->user_props, i = 0; @@ -2670,15 +2447,15 @@ bdf_get_font_property( bdf_font_t* font, const char* name ) { - hashnode hn; + size_t* propid; if ( font == 0 || font->props_size == 0 || name == 0 || *name == 0 ) return 0; - hn = hash_lookup( name, (hashtable *)font->internal ); + propid = ft_hash_str_lookup( name, (FT_Hash)font->internal ); - return hn ? ( font->props + hn->data ) : 0; + return propid ? ( font->props + *propid ) : 0; } diff --git a/src/3rdparty/freetype/src/bzip2/Jamfile b/src/3rdparty/freetype/src/bzip2/Jamfile index 53f850e6f2..3548eab597 100644 --- a/src/3rdparty/freetype/src/bzip2/Jamfile +++ b/src/3rdparty/freetype/src/bzip2/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/bzip2 Jamfile # -# Copyright 2010-2015 by +# Copyright 2010-2018 by # Joel Klinghed # # based on `src/lzw/Jamfile' diff --git a/src/3rdparty/freetype/src/bzip2/ftbzip2.c b/src/3rdparty/freetype/src/bzip2/ftbzip2.c index cf94733762..16019485a9 100644 --- a/src/3rdparty/freetype/src/bzip2/ftbzip2.c +++ b/src/3rdparty/freetype/src/bzip2/ftbzip2.c @@ -8,7 +8,7 @@ /* parse compressed PCF fonts, as found with many X11 server */ /* distributions. */ /* */ -/* Copyright 2010-2015 by */ +/* Copyright 2010-2018 by */ /* Joel Klinghed. */ /* */ /* based on `src/gzip/ftgzip.c' */ @@ -32,7 +32,7 @@ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX Bzip2_Err_ @@ -180,7 +180,7 @@ bzstream->next_in = (char*)zip->buffer; if ( BZ2_bzDecompressInit( bzstream, 0, 0 ) != BZ_OK || - bzstream->next_in == NULL ) + !bzstream->next_in ) error = FT_THROW( Invalid_File_Format ); Exit: diff --git a/src/3rdparty/freetype/src/bzip2/rules.mk b/src/3rdparty/freetype/src/bzip2/rules.mk index 7040588c1b..95954d7520 100644 --- a/src/3rdparty/freetype/src/bzip2/rules.mk +++ b/src/3rdparty/freetype/src/bzip2/rules.mk @@ -2,7 +2,7 @@ # FreeType 2 BZIP2 support configuration rules # -# Copyright 2010-2015 by +# Copyright 2010-2018 by # Joel Klinghed. # # based on `src/lzw/rules.mk' diff --git a/src/3rdparty/freetype/src/cache/Jamfile b/src/3rdparty/freetype/src/cache/Jamfile index 1d2bb29392..53f4c7b603 100644 --- a/src/3rdparty/freetype/src/cache/Jamfile +++ b/src/3rdparty/freetype/src/cache/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/cache Jamfile # -# Copyright 2001-2015 by +# Copyright 2001-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/cache/ftcache.c b/src/3rdparty/freetype/src/cache/ftcache.c index 8de527acab..1b425af911 100644 --- a/src/3rdparty/freetype/src/cache/ftcache.c +++ b/src/3rdparty/freetype/src/cache/ftcache.c @@ -4,7 +4,7 @@ /* */ /* The FreeType Caching sub-system (body only). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,15 +17,16 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT - #include <ft2build.h> -#include "ftcmru.c" -#include "ftcmanag.c" + +#include "ftcbasic.c" #include "ftccache.c" #include "ftccmap.c" #include "ftcglyph.c" #include "ftcimage.c" +#include "ftcmanag.c" +#include "ftcmru.c" #include "ftcsbits.c" -#include "ftcbasic.c" + /* END */ diff --git a/src/3rdparty/freetype/src/cache/ftcbasic.c b/src/3rdparty/freetype/src/cache/ftcbasic.c index ac3290cef4..994aa12286 100644 --- a/src/3rdparty/freetype/src/cache/ftcbasic.c +++ b/src/3rdparty/freetype/src/cache/ftcbasic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType basic cache interface (body). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -237,12 +237,14 @@ { { sizeof ( FTC_BasicFamilyRec ), - ftc_basic_family_compare, - ftc_basic_family_init, - 0, /* FTC_MruNode_ResetFunc */ - 0 /* FTC_MruNode_DoneFunc */ + + ftc_basic_family_compare, /* FTC_MruNode_CompareFunc node_compare */ + ftc_basic_family_init, /* FTC_MruNode_InitFunc node_init */ + NULL, /* FTC_MruNode_ResetFunc node_reset */ + NULL /* FTC_MruNode_DoneFunc node_done */ }, - ftc_basic_family_load_glyph + + ftc_basic_family_load_glyph /* FTC_IFamily_LoadGlyphFunc family_load_glyph */ }; @@ -250,16 +252,17 @@ const FTC_GCacheClassRec ftc_basic_image_cache_class = { { - ftc_inode_new, - ftc_inode_weight, - ftc_gnode_compare, - ftc_basic_gnode_compare_faceid, - ftc_inode_free, + ftc_inode_new, /* FTC_Node_NewFunc node_new */ + ftc_inode_weight, /* FTC_Node_WeightFunc node_weight */ + ftc_gnode_compare, /* FTC_Node_CompareFunc node_compare */ + ftc_basic_gnode_compare_faceid, /* FTC_Node_CompareFunc node_remove_faceid */ + ftc_inode_free, /* FTC_Node_FreeFunc node_free */ sizeof ( FTC_GCacheRec ), - ftc_gcache_init, - ftc_gcache_done + ftc_gcache_init, /* FTC_Cache_InitFunc cache_init */ + ftc_gcache_done /* FTC_Cache_DoneFunc cache_done */ }, + (FTC_MruListClass)&ftc_basic_image_family_class }; @@ -301,10 +304,18 @@ if ( anode ) *anode = NULL; - if ( (FT_ULong)( type->flags - FT_INT_MIN ) > FT_UINT_MAX ) + /* + * Internal `FTC_BasicAttr->load_flags' is of type `FT_UInt', + * but public `FT_ImageType->flags' is of type `FT_Int32'. + * + * On 16bit systems, higher bits of type->flags cannot be handled. + */ +#if 0xFFFFFFFFUL > FT_UINT_MAX + if ( (type->flags & (FT_ULong)FT_UINT_MAX) ) FT_TRACE1(( "FTC_ImageCache_Lookup:" " higher bits in load_flags 0x%x are dropped\n", (FT_ULong)type->flags & ~((FT_ULong)FT_UINT_MAX) )); +#endif query.attrs.scaler.face_id = type->face_id; query.attrs.scaler.width = type->width; @@ -374,11 +385,18 @@ if ( anode ) *anode = NULL; - /* `FT_Load_Glyph' and `FT_Load_Char' take FT_UInt flags */ + /* + * Internal `FTC_BasicAttr->load_flags' is of type `FT_UInt', + * but public `FT_Face->face_flags' is of type `FT_Long'. + * + * On long > int systems, higher bits of load_flags cannot be handled. + */ +#if FT_ULONG_MAX > FT_UINT_MAX if ( load_flags > FT_UINT_MAX ) FT_TRACE1(( "FTC_ImageCache_LookupScaler:" " higher bits in load_flags 0x%x are dropped\n", load_flags & ~((FT_ULong)FT_UINT_MAX) )); +#endif query.attrs.scaler = scaler[0]; query.attrs.load_flags = (FT_UInt)load_flags; @@ -419,11 +437,12 @@ { { sizeof ( FTC_BasicFamilyRec ), - ftc_basic_family_compare, - ftc_basic_family_init, - 0, /* FTC_MruNode_ResetFunc */ - 0 /* FTC_MruNode_DoneFunc */ + ftc_basic_family_compare, /* FTC_MruNode_CompareFunc node_compare */ + ftc_basic_family_init, /* FTC_MruNode_InitFunc node_init */ + NULL, /* FTC_MruNode_ResetFunc node_reset */ + NULL /* FTC_MruNode_DoneFunc node_done */ }, + ftc_basic_family_get_count, ftc_basic_family_load_bitmap }; @@ -433,16 +452,17 @@ const FTC_GCacheClassRec ftc_basic_sbit_cache_class = { { - ftc_snode_new, - ftc_snode_weight, - ftc_snode_compare, - ftc_basic_gnode_compare_faceid, - ftc_snode_free, + ftc_snode_new, /* FTC_Node_NewFunc node_new */ + ftc_snode_weight, /* FTC_Node_WeightFunc node_weight */ + ftc_snode_compare, /* FTC_Node_CompareFunc node_compare */ + ftc_basic_gnode_compare_faceid, /* FTC_Node_CompareFunc node_remove_faceid */ + ftc_snode_free, /* FTC_Node_FreeFunc node_free */ sizeof ( FTC_GCacheRec ), - ftc_gcache_init, - ftc_gcache_done + ftc_gcache_init, /* FTC_Cache_InitFunc cache_init */ + ftc_gcache_done /* FTC_Cache_DoneFunc cache_done */ }, + (FTC_MruListClass)&ftc_basic_sbit_family_class }; @@ -482,10 +502,18 @@ *ansbit = NULL; - if ( (FT_ULong)( type->flags - FT_INT_MIN ) > FT_UINT_MAX ) + /* + * Internal `FTC_BasicAttr->load_flags' is of type `FT_UInt', + * but public `FT_ImageType->flags' is of type `FT_Int32'. + * + * On 16bit systems, higher bits of type->flags cannot be handled. + */ +#if 0xFFFFFFFFUL > FT_UINT_MAX + if ( (type->flags & (FT_ULong)FT_UINT_MAX) ) FT_TRACE1(( "FTC_ImageCache_Lookup:" " higher bits in load_flags 0x%x are dropped\n", (FT_ULong)type->flags & ~((FT_ULong)FT_UINT_MAX) )); +#endif query.attrs.scaler.face_id = type->face_id; query.attrs.scaler.width = type->width; @@ -557,11 +585,18 @@ *ansbit = NULL; - /* `FT_Load_Glyph' and `FT_Load_Char' take FT_UInt flags */ + /* + * Internal `FTC_BasicAttr->load_flags' is of type `FT_UInt', + * but public `FT_Face->face_flags' is of type `FT_Long'. + * + * On long > int systems, higher bits of load_flags cannot be handled. + */ +#if FT_ULONG_MAX > FT_UINT_MAX if ( load_flags > FT_UINT_MAX ) FT_TRACE1(( "FTC_ImageCache_LookupScaler:" " higher bits in load_flags 0x%x are dropped\n", load_flags & ~((FT_ULong)FT_UINT_MAX) )); +#endif query.attrs.scaler = scaler[0]; query.attrs.load_flags = (FT_UInt)load_flags; diff --git a/src/3rdparty/freetype/src/cache/ftccache.c b/src/3rdparty/freetype/src/cache/ftccache.c index d8c5b99681..12ec585a25 100644 --- a/src/3rdparty/freetype/src/cache/ftccache.c +++ b/src/3rdparty/freetype/src/cache/ftccache.c @@ -4,7 +4,7 @@ /* */ /* The FreeType internal cache interface (body). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -85,7 +85,7 @@ /* get a top bucket for specified hash from cache, - * body for FTC_NODE__TOP_FOR_HASH( cache, hash ) + * body for FTC_NODE_TOP_FOR_HASH( cache, hash ) */ FT_LOCAL_DEF( FTC_Node* ) ftc_get_top_node_for_hash( FTC_Cache cache, @@ -147,7 +147,7 @@ for (;;) { node = *pnode; - if ( node == NULL ) + if ( !node ) break; if ( node->hash & ( mask + 1 ) ) @@ -224,7 +224,7 @@ ftc_node_hash_unlink( FTC_Node node0, FTC_Cache cache ) { - FTC_Node *pnode = FTC_NODE__TOP_FOR_HASH( cache, node0->hash ); + FTC_Node *pnode = FTC_NODE_TOP_FOR_HASH( cache, node0->hash ); for (;;) @@ -232,7 +232,7 @@ FTC_Node node = *pnode; - if ( node == NULL ) + if ( !node ) { FT_TRACE0(( "ftc_node_hash_unlink: unknown node\n" )); return; @@ -257,7 +257,7 @@ ftc_node_hash_link( FTC_Node node, FTC_Cache cache ) { - FTC_Node *pnode = FTC_NODE__TOP_FOR_HASH( cache, node->hash ); + FTC_Node *pnode = FTC_NODE_TOP_FOR_HASH( cache, node->hash ); node->link = *pnode; @@ -288,7 +288,7 @@ cache = manager->caches[node->cache_index]; #ifdef FT_DEBUG_ERROR - if ( cache == NULL ) + if ( !cache ) { FT_TRACE0(( "ftc_node_destroy: invalid node handle\n" )); return; @@ -494,18 +494,18 @@ FTC_Node_CompareFunc compare = cache->clazz.node_compare; - if ( cache == NULL || anode == NULL ) + if ( !cache || !anode ) return FT_THROW( Invalid_Argument ); /* Go to the `top' node of the list sharing same masked hash */ - bucket = pnode = FTC_NODE__TOP_FOR_HASH( cache, hash ); + bucket = pnode = FTC_NODE_TOP_FOR_HASH( cache, hash ); /* Lookup a node with exactly same hash and queried properties. */ /* NOTE: _nodcomp() may change the linked list to reduce memory. */ for (;;) { node = *pnode; - if ( node == NULL ) + if ( !node ) goto NewNode; if ( node->hash == hash && @@ -518,12 +518,12 @@ if ( list_changed ) { /* Update bucket by modified linked list */ - bucket = pnode = FTC_NODE__TOP_FOR_HASH( cache, hash ); + bucket = pnode = FTC_NODE_TOP_FOR_HASH( cache, hash ); /* Update pnode by modified linked list */ while ( *pnode != node ) { - if ( *pnode == NULL ) + if ( !*pnode ) { FT_ERROR(( "FTC_Cache_Lookup: oops!!! node missing\n" )); goto NewNode; @@ -576,13 +576,13 @@ FTC_Node* pnode = bucket; - for ( ;; ) + for (;;) { FTC_Node node = *pnode; FT_Bool list_changed = FALSE; - if ( node == NULL ) + if ( !node ) break; if ( cache->clazz.node_remove_faceid( node, face_id, diff --git a/src/3rdparty/freetype/src/cache/ftccache.h b/src/3rdparty/freetype/src/cache/ftccache.h index 4e17c7afef..859c547e46 100644 --- a/src/3rdparty/freetype/src/cache/ftccache.h +++ b/src/3rdparty/freetype/src/cache/ftccache.h @@ -4,7 +4,7 @@ /* */ /* FreeType internal cache interface (specification). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,16 +16,16 @@ /***************************************************************************/ -#ifndef __FTCCACHE_H__ -#define __FTCCACHE_H__ +#ifndef FTCCACHE_H_ +#define FTCCACHE_H_ #include "ftcmru.h" FT_BEGIN_HEADER -#define _FTC_FACE_ID_HASH( i ) \ - ( ( (FT_Offset)(i) >> 3 ) ^ ( (FT_Offset)(i) << 7 ) ) +#define FTC_FACE_ID_HASH( i ) \ + ( ( (FT_Offset)(i) >> 3 ) ^ ( (FT_Offset)(i) << 7 ) ) /* handle to cache object */ typedef struct FTC_CacheRec_* FTC_Cache; @@ -69,11 +69,11 @@ FT_BEGIN_HEADER #define FTC_NODE( x ) ( (FTC_Node)(x) ) #define FTC_NODE_P( x ) ( (FTC_Node*)(x) ) -#define FTC_NODE__NEXT( x ) FTC_NODE( (x)->mru.next ) -#define FTC_NODE__PREV( x ) FTC_NODE( (x)->mru.prev ) +#define FTC_NODE_NEXT( x ) FTC_NODE( (x)->mru.next ) +#define FTC_NODE_PREV( x ) FTC_NODE( (x)->mru.prev ) #ifdef FTC_INLINE -#define FTC_NODE__TOP_FOR_HASH( cache, hash ) \ +#define FTC_NODE_TOP_FOR_HASH( cache, hash ) \ ( ( cache )->buckets + \ ( ( ( ( hash ) & ( cache )->mask ) < ( cache )->p ) \ ? ( ( hash ) & ( ( cache )->mask * 2 + 1 ) ) \ @@ -82,7 +82,7 @@ FT_BEGIN_HEADER FT_LOCAL( FTC_Node* ) ftc_get_top_node_for_hash( FTC_Cache cache, FT_Offset hash ); -#define FTC_NODE__TOP_FOR_HASH( cache, hash ) \ +#define FTC_NODE_TOP_FOR_HASH( cache, hash ) \ ftc_get_top_node_for_hash( ( cache ), ( hash ) ) #endif @@ -220,15 +220,15 @@ FT_BEGIN_HEADER node = NULL; \ \ /* Go to the `top' node of the list sharing same masked hash */ \ - _bucket = _pnode = FTC_NODE__TOP_FOR_HASH( _cache, _hash ); \ + _bucket = _pnode = FTC_NODE_TOP_FOR_HASH( _cache, _hash ); \ \ /* Look up a node with identical hash and queried properties. */ \ /* NOTE: _nodcomp() may change the linked list to reduce memory. */ \ for (;;) \ { \ _node = *_pnode; \ - if ( _node == NULL ) \ - goto _NewNode; \ + if ( !_node ) \ + goto NewNode_; \ \ if ( _node->hash == _hash && \ _nodcomp( _node, query, _cache, &_list_changed ) ) \ @@ -240,15 +240,15 @@ FT_BEGIN_HEADER if ( _list_changed ) \ { \ /* Update _bucket by possibly modified linked list */ \ - _bucket = _pnode = FTC_NODE__TOP_FOR_HASH( _cache, _hash ); \ + _bucket = _pnode = FTC_NODE_TOP_FOR_HASH( _cache, _hash ); \ \ /* Update _pnode by possibly modified linked list */ \ while ( *_pnode != _node ) \ { \ - if ( *_pnode == NULL ) \ + if ( !*_pnode ) \ { \ FT_ERROR(( "FTC_CACHE_LOOKUP_CMP: oops!!! node missing\n" )); \ - goto _NewNode; \ + goto NewNode_; \ } \ else \ _pnode = &((*_pnode)->link); \ @@ -273,12 +273,12 @@ FT_BEGIN_HEADER FTC_MruNode_Up( (FTC_MruNode*)_nl, \ (FTC_MruNode)_node ); \ } \ - goto _Ok; \ + goto Ok_; \ \ - _NewNode: \ + NewNode_: \ error = FTC_Cache_NewNode( _cache, _hash, query, &_node ); \ \ - _Ok: \ + Ok_: \ node = _node; \ FT_END_STMNT @@ -325,7 +325,7 @@ FT_BEGIN_HEADER break; \ \ _try_done = FTC_Manager_FlushN( _try_manager, _try_count ); \ - if ( _try_done > 0 && ( list_changed ) ) \ + if ( _try_done > 0 && list_changed != NULL ) \ *(FT_Bool*)( list_changed ) = TRUE; \ \ if ( _try_done == 0 ) \ @@ -346,7 +346,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCCACHE_H__ */ +#endif /* FTCCACHE_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/cache/ftccback.h b/src/3rdparty/freetype/src/cache/ftccback.h index b3237d5a3f..e51d8d6e55 100644 --- a/src/3rdparty/freetype/src/cache/ftccback.h +++ b/src/3rdparty/freetype/src/cache/ftccback.h @@ -4,7 +4,7 @@ /* */ /* Callback functions of the caching sub-system (specification only). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -15,8 +15,8 @@ /* */ /***************************************************************************/ -#ifndef __FTCCBACK_H__ -#define __FTCCBACK_H__ +#ifndef FTCCBACK_H_ +#define FTCCBACK_H_ #include <ft2build.h> #include FT_CACHE_H @@ -86,6 +86,7 @@ FTC_Manager manager ); -#endif /* __FTCCBACK_H__ */ +#endif /* FTCCBACK_H_ */ + /* END */ diff --git a/src/3rdparty/freetype/src/cache/ftccmap.c b/src/3rdparty/freetype/src/cache/ftccmap.c index b8262220c4..d20b0f48fe 100644 --- a/src/3rdparty/freetype/src/cache/ftccmap.c +++ b/src/3rdparty/freetype/src/cache/ftccmap.c @@ -4,7 +4,7 @@ /* */ /* FreeType CharMap cache (body) */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -50,7 +50,7 @@ /* compute a query/node hash */ #define FTC_CMAP_HASH( faceid, index, charcode ) \ - ( _FTC_FACE_ID_HASH( faceid ) + 211 * (index) + \ + ( FTC_FACE_ID_HASH( faceid ) + 211 * (index) + \ ( (charcode) / FTC_CMAP_INDICES_MAX ) ) /* the charmap query */ @@ -201,15 +201,15 @@ static const FTC_CacheClassRec ftc_cmap_cache_class = { - ftc_cmap_node_new, - ftc_cmap_node_weight, - ftc_cmap_node_compare, - ftc_cmap_node_remove_faceid, - ftc_cmap_node_free, + ftc_cmap_node_new, /* FTC_Node_NewFunc node_new */ + ftc_cmap_node_weight, /* FTC_Node_WeightFunc node_weight */ + ftc_cmap_node_compare, /* FTC_Node_CompareFunc node_compare */ + ftc_cmap_node_remove_faceid, /* FTC_Node_CompareFunc node_remove_faceid */ + ftc_cmap_node_free, /* FTC_Node_FreeFunc node_free */ sizeof ( FTC_CacheRec ), - ftc_cache_init, - ftc_cache_done, + ftc_cache_init, /* FTC_Cache_InitFunc cache_init */ + ftc_cache_done, /* FTC_Cache_DoneFunc cache_done */ }; @@ -259,9 +259,6 @@ return 0; } - if ( !face_id ) - return 0; - query.face_id = face_id; query.cmap_index = (FT_UInt)cmap_index; query.char_code = char_code; diff --git a/src/3rdparty/freetype/src/cache/ftcerror.h b/src/3rdparty/freetype/src/cache/ftcerror.h index 15adec58de..a26cd5935b 100644 --- a/src/3rdparty/freetype/src/cache/ftcerror.h +++ b/src/3rdparty/freetype/src/cache/ftcerror.h @@ -4,7 +4,7 @@ /* */ /* Caching sub-system error codes (specification only). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __FTCERROR_H__ -#define __FTCERROR_H__ +#ifndef FTCERROR_H_ +#define FTCERROR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX FTC_Err_ @@ -36,6 +36,7 @@ #include FT_ERRORS_H -#endif /* __FTCERROR_H__ */ +#endif /* FTCERROR_H_ */ + /* END */ diff --git a/src/3rdparty/freetype/src/cache/ftcglyph.c b/src/3rdparty/freetype/src/cache/ftcglyph.c index 343b8a7793..782cc0ed09 100644 --- a/src/3rdparty/freetype/src/cache/ftcglyph.c +++ b/src/3rdparty/freetype/src/cache/ftcglyph.c @@ -4,7 +4,7 @@ /* */ /* FreeType Glyph Image (FT_Glyph) cache (body). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -106,7 +106,7 @@ FTC_Family_Init( FTC_Family family, FTC_Cache cache ) { - FTC_GCacheClass clazz = FTC_CACHE__GCACHE_CLASS( cache ); + FTC_GCacheClass clazz = FTC_CACHE_GCACHE_CLASS( cache ); family->clazz = clazz->family_class; diff --git a/src/3rdparty/freetype/src/cache/ftcglyph.h b/src/3rdparty/freetype/src/cache/ftcglyph.h index 6cadbe2c10..23c24d223f 100644 --- a/src/3rdparty/freetype/src/cache/ftcglyph.h +++ b/src/3rdparty/freetype/src/cache/ftcglyph.h @@ -4,7 +4,7 @@ /* */ /* FreeType abstract glyph cache (specification). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -113,8 +113,8 @@ /*************************************************************************/ -#ifndef __FTCGLYPH_H__ -#define __FTCGLYPH_H__ +#ifndef FTCGLYPH_H_ +#define FTCGLYPH_H_ #include <ft2build.h> @@ -245,10 +245,10 @@ FT_BEGIN_HEADER #define FTC_GCACHE_CLASS( x ) ((FTC_GCacheClass)(x)) -#define FTC_CACHE__GCACHE_CLASS( x ) \ +#define FTC_CACHE_GCACHE_CLASS( x ) \ FTC_GCACHE_CLASS( FTC_CACHE(x)->org_class ) -#define FTC_CACHE__FAMILY_CLASS( x ) \ - ( (FTC_MruListClass)FTC_CACHE__GCACHE_CLASS( x )->family_class ) +#define FTC_CACHE_FAMILY_CLASS( x ) \ + ( (FTC_MruListClass)FTC_CACHE_GCACHE_CLASS( x )->family_class ) /* convenience function; use it instead of FTC_Manager_Register_Cache */ @@ -323,7 +323,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCGLYPH_H__ */ +#endif /* FTCGLYPH_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/cache/ftcimage.c b/src/3rdparty/freetype/src/cache/ftcimage.c index f519a6179c..77a100153e 100644 --- a/src/3rdparty/freetype/src/cache/ftcimage.c +++ b/src/3rdparty/freetype/src/cache/ftcimage.c @@ -4,7 +4,7 @@ /* */ /* FreeType Image cache (body). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -70,7 +70,7 @@ FTC_GNode gnode = FTC_GNODE( inode ); FTC_Family family = gquery->family; FT_UInt gindex = gquery->gindex; - FTC_IFamilyClass clazz = FTC_CACHE__IFAMILY_CLASS( cache ); + FTC_IFamilyClass clazz = FTC_CACHE_IFAMILY_CLASS( cache ); /* initialize its inner fields */ diff --git a/src/3rdparty/freetype/src/cache/ftcimage.h b/src/3rdparty/freetype/src/cache/ftcimage.h index b312eaa3d9..24a221053b 100644 --- a/src/3rdparty/freetype/src/cache/ftcimage.h +++ b/src/3rdparty/freetype/src/cache/ftcimage.h @@ -4,7 +4,7 @@ /* */ /* FreeType Generic Image cache (specification) */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -32,8 +32,8 @@ /*************************************************************************/ -#ifndef __FTCIMAGE_H__ -#define __FTCIMAGE_H__ +#ifndef FTCIMAGE_H_ +#define FTCIMAGE_H_ #include <ft2build.h> @@ -72,8 +72,8 @@ FT_BEGIN_HEADER #define FTC_IFAMILY_CLASS( x ) ((FTC_IFamilyClass)(x)) -#define FTC_CACHE__IFAMILY_CLASS( x ) \ - FTC_IFAMILY_CLASS( FTC_CACHE__GCACHE_CLASS(x)->family_class ) +#define FTC_CACHE_IFAMILY_CLASS( x ) \ + FTC_IFAMILY_CLASS( FTC_CACHE_GCACHE_CLASS(x)->family_class ) /* can be used as a @FTC_Node_FreeFunc */ @@ -101,7 +101,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCIMAGE_H__ */ +#endif /* FTCIMAGE_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/cache/ftcmanag.c b/src/3rdparty/freetype/src/cache/ftcmanag.c index 658614c8db..2bcd9df502 100644 --- a/src/3rdparty/freetype/src/cache/ftcmanag.c +++ b/src/3rdparty/freetype/src/cache/ftcmanag.c @@ -4,7 +4,7 @@ /* */ /* FreeType Cache Manager (body). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -156,10 +156,11 @@ const FTC_MruListClassRec ftc_size_list_class = { sizeof ( FTC_SizeNodeRec ), - ftc_size_node_compare, - ftc_size_node_init, - ftc_size_node_reset, - ftc_size_node_done + + ftc_size_node_compare, /* FTC_MruNode_CompareFunc node_compare */ + ftc_size_node_init, /* FTC_MruNode_InitFunc node_init */ + ftc_size_node_reset, /* FTC_MruNode_ResetFunc node_reset */ + ftc_size_node_done /* FTC_MruNode_DoneFunc node_done */ }; @@ -296,10 +297,10 @@ { sizeof ( FTC_FaceNodeRec), - ftc_face_node_compare, - ftc_face_node_init, - 0, /* FTC_MruNode_ResetFunc */ - ftc_face_node_done + ftc_face_node_compare, /* FTC_MruNode_CompareFunc node_compare */ + ftc_face_node_init, /* FTC_MruNode_InitFunc node_init */ + NULL, /* FTC_MruNode_ResetFunc node_reset */ + ftc_face_node_done /* FTC_MruNode_DoneFunc node_done */ }; @@ -314,7 +315,7 @@ FTC_MruNode mrunode; - if ( !aface || !face_id ) + if ( !aface ) return FT_THROW( Invalid_Argument ); *aface = NULL; @@ -494,7 +495,7 @@ else weight += cache->clazz.node_weight( node, cache ); - node = FTC_NODE__NEXT( node ); + node = FTC_NODE_NEXT( node ); } while ( node != first ); @@ -513,7 +514,7 @@ do { count++; - node = FTC_NODE__NEXT( node ); + node = FTC_NODE_NEXT( node ); } while ( node != first ); @@ -552,17 +553,17 @@ manager->num_nodes )); #endif - if ( manager->cur_weight < manager->max_weight || first == NULL ) + if ( manager->cur_weight < manager->max_weight || !first ) return; /* go to last node -- it's a circular list */ - node = FTC_NODE__PREV( first ); + node = FTC_NODE_PREV( first ); do { FTC_Node prev; - prev = ( node == first ) ? NULL : FTC_NODE__PREV( node ); + prev = ( node == first ) ? NULL : FTC_NODE_PREV( node ); if ( node->ref_count <= 0 ) ftc_node_destroy( node, manager ); @@ -637,14 +638,14 @@ /* try to remove `count' nodes from the list */ - if ( first == NULL ) /* empty list! */ + if ( !first ) /* empty list! */ return 0; /* go to last node - it's a circular list */ - node = FTC_NODE__PREV(first); + node = FTC_NODE_PREV(first); for ( result = 0; result < count; ) { - FTC_Node prev = FTC_NODE__PREV( node ); + FTC_Node prev = FTC_NODE_PREV( node ); /* don't touch locked nodes */ @@ -672,7 +673,7 @@ FT_UInt nn; - if ( !manager || !face_id ) + if ( !manager ) return; /* this will remove all FTC_SizeNode that correspond to diff --git a/src/3rdparty/freetype/src/cache/ftcmanag.h b/src/3rdparty/freetype/src/cache/ftcmanag.h index c6787b72c5..b4b4755356 100644 --- a/src/3rdparty/freetype/src/cache/ftcmanag.h +++ b/src/3rdparty/freetype/src/cache/ftcmanag.h @@ -4,7 +4,7 @@ /* */ /* FreeType Cache Manager (specification). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -59,8 +59,8 @@ /*************************************************************************/ -#ifndef __FTCMANAG_H__ -#define __FTCMANAG_H__ +#ifndef FTCMANAG_H_ +#define FTCMANAG_H_ #include <ft2build.h> @@ -161,7 +161,7 @@ FT_BEGIN_HEADER (a)->y_res == (b)->y_res ) ) ) #define FTC_SCALER_HASH( q ) \ - ( _FTC_FACE_ID_HASH( (q)->face_id ) + \ + ( FTC_FACE_ID_HASH( (q)->face_id ) + \ (q)->width + (q)->height*7 + \ ( (q)->pixel ? 0 : ( (q)->x_res*33 ^ (q)->y_res*61 ) ) ) @@ -169,7 +169,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCMANAG_H__ */ +#endif /* FTCMANAG_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/cache/ftcmru.c b/src/3rdparty/freetype/src/cache/ftcmru.c index 10ce4f301e..1087be4d89 100644 --- a/src/3rdparty/freetype/src/cache/ftcmru.c +++ b/src/3rdparty/freetype/src/cache/ftcmru.c @@ -4,7 +4,7 @@ /* */ /* FreeType MRU support (body). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -76,7 +76,7 @@ FTC_MruNode first = *plist; - FT_ASSERT( first != NULL ); + FT_ASSERT( first ); if ( first != node ) { @@ -126,7 +126,7 @@ FTC_MruNode prev, next; - FT_ASSERT( first != NULL ); + FT_ASSERT( first ); #ifdef FT_DEBUG_ERROR { @@ -238,7 +238,7 @@ FTC_MruNode *anode ) { FT_Error error; - FTC_MruNode node = NULL; + FTC_MruNode node = NULL; FT_Memory memory = list->memory; @@ -296,7 +296,7 @@ node = FTC_MruList_Find( list, key ); - if ( node == NULL ) + if ( !node ) return FTC_MruList_New( list, key, anode ); *anode = node; @@ -332,7 +332,7 @@ first = list->nodes; - while ( first && ( selection == NULL || selection( first, key ) ) ) + while ( first && ( !selection || selection( first, key ) ) ) { FTC_MruList_Remove( list, first ); first = list->nodes; diff --git a/src/3rdparty/freetype/src/cache/ftcmru.h b/src/3rdparty/freetype/src/cache/ftcmru.h index c0c35f934b..82396b917d 100644 --- a/src/3rdparty/freetype/src/cache/ftcmru.h +++ b/src/3rdparty/freetype/src/cache/ftcmru.h @@ -4,7 +4,7 @@ /* */ /* Simple MRU list-cache (specification). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -40,8 +40,8 @@ /*************************************************************************/ -#ifndef __FTCMRU_H__ -#define __FTCMRU_H__ +#ifndef FTCMRU_H_ +#define FTCMRU_H_ #include <ft2build.h> @@ -108,6 +108,7 @@ FT_BEGIN_HEADER typedef struct FTC_MruListClassRec_ { FT_Offset node_size; + FTC_MruNode_CompareFunc node_compare; FTC_MruNode_InitFunc node_init; FTC_MruNode_ResetFunc node_reset; @@ -115,6 +116,7 @@ FT_BEGIN_HEADER } FTC_MruListClassRec; + typedef struct FTC_MruListRec_ { FT_UInt num_nodes; @@ -181,15 +183,15 @@ FT_BEGIN_HEADER FTC_MruNode_Up( _pfirst, _node ); \ \ node = _node; \ - goto _MruOk; \ + goto MruOk_; \ } \ _node = _node->next; \ \ - } while ( _node != _first) ; \ + } while ( _node != _first); \ } \ \ error = FTC_MruList_New( (list), (key), (FTC_MruNode*)(void*)&(node) ); \ - _MruOk: \ + MruOk_: \ ; \ FT_END_STMNT @@ -240,7 +242,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCMRU_H__ */ +#endif /* FTCMRU_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/cache/ftcsbits.c b/src/3rdparty/freetype/src/cache/ftcsbits.c index 8141719167..018f1ecdb7 100644 --- a/src/3rdparty/freetype/src/cache/ftcsbits.c +++ b/src/3rdparty/freetype/src/cache/ftcsbits.c @@ -4,7 +4,7 @@ /* */ /* FreeType sbits manager (body). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -53,6 +53,8 @@ pitch = -pitch; size = (FT_ULong)pitch * bitmap->rows; + if ( !size ) + return FT_Err_Ok; if ( !FT_ALLOC( sbit->buffer, size ) ) FT_MEM_COPY( sbit->buffer, bitmap->buffer, size ); @@ -215,7 +217,7 @@ FT_UInt gindex = gquery->gindex; FTC_Family family = gquery->family; - FTC_SFamilyClass clazz = FTC_CACHE__SFAMILY_CLASS( cache ); + FTC_SFamilyClass clazz = FTC_CACHE_SFAMILY_CLASS( cache ); FT_UInt total; FT_UInt node_count; @@ -376,7 +378,7 @@ * */ - if ( sbit->buffer == NULL && sbit->width == 255 ) + if ( !sbit->buffer && sbit->width == 255 ) { FT_ULong size; FT_Error error; diff --git a/src/3rdparty/freetype/src/cache/ftcsbits.h b/src/3rdparty/freetype/src/cache/ftcsbits.h index 5a2fa1ac80..206a1bb3fc 100644 --- a/src/3rdparty/freetype/src/cache/ftcsbits.h +++ b/src/3rdparty/freetype/src/cache/ftcsbits.h @@ -4,7 +4,7 @@ /* */ /* A small-bitmap cache (specification). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTCSBITS_H__ -#define __FTCSBITS_H__ +#ifndef FTCSBITS_H_ +#define FTCSBITS_H_ #include <ft2build.h> @@ -64,8 +64,8 @@ FT_BEGIN_HEADER #define FTC_SFAMILY_CLASS( x ) ((FTC_SFamilyClass)(x)) -#define FTC_CACHE__SFAMILY_CLASS( x ) \ - FTC_SFAMILY_CLASS( FTC_CACHE__GCACHE_CLASS( x )->family_class ) +#define FTC_CACHE_SFAMILY_CLASS( x ) \ + FTC_SFAMILY_CLASS( FTC_CACHE_GCACHE_CLASS( x )->family_class ) FT_LOCAL( void ) @@ -97,7 +97,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTCSBITS_H__ */ +#endif /* FTCSBITS_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/cache/rules.mk b/src/3rdparty/freetype/src/cache/rules.mk index 6d5cf344b3..558935976d 100644 --- a/src/3rdparty/freetype/src/cache/rules.mk +++ b/src/3rdparty/freetype/src/cache/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2000-2015 by +# Copyright 2000-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/cff/Jamfile b/src/3rdparty/freetype/src/cff/Jamfile index deec0792ce..53c904fcfe 100644 --- a/src/3rdparty/freetype/src/cff/Jamfile +++ b/src/3rdparty/freetype/src/cff/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/cff Jamfile # -# Copyright 2001-2015 by +# Copyright 2001-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -23,15 +23,6 @@ SubDir FT2_TOP $(FT2_SRC_DIR) cff ; cffobjs cffparse cffpic - cf2arrst - cf2blues - cf2error - cf2font - cf2ft - cf2hints - cf2intrp - cf2read - cf2stack ; } else diff --git a/src/3rdparty/freetype/src/cff/cff.c b/src/3rdparty/freetype/src/cff/cff.c index bb2cfb5253..1a755d5dad 100644 --- a/src/3rdparty/freetype/src/cff/cff.c +++ b/src/3rdparty/freetype/src/cff/cff.c @@ -4,7 +4,7 @@ /* */ /* FreeType OpenType driver component (body only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,25 +17,14 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT - #include <ft2build.h> -#include "cffpic.c" +#include "cffcmap.c" #include "cffdrivr.c" +#include "cffgload.c" #include "cffparse.c" +#include "cffpic.c" #include "cffload.c" #include "cffobjs.c" -#include "cffgload.c" -#include "cffcmap.c" - -#include "cf2arrst.c" -#include "cf2blues.c" -#include "cf2error.c" -#include "cf2font.c" -#include "cf2ft.c" -#include "cf2hints.c" -#include "cf2intrp.c" -#include "cf2read.c" -#include "cf2stack.c" /* END */ diff --git a/src/3rdparty/freetype/src/cff/cffcmap.c b/src/3rdparty/freetype/src/cff/cffcmap.c index e7538e9840..e45ae1127b 100644 --- a/src/3rdparty/freetype/src/cff/cffcmap.c +++ b/src/3rdparty/freetype/src/cff/cffcmap.c @@ -4,7 +4,7 @@ /* */ /* CFF character mapping table (cmap) support (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -104,15 +104,21 @@ } - FT_DEFINE_CMAP_CLASS(cff_cmap_encoding_class_rec, + FT_DEFINE_CMAP_CLASS( + cff_cmap_encoding_class_rec, + sizeof ( CFF_CMapStdRec ), - (FT_CMap_InitFunc) cff_cmap_encoding_init, - (FT_CMap_DoneFunc) cff_cmap_encoding_done, - (FT_CMap_CharIndexFunc)cff_cmap_encoding_char_index, - (FT_CMap_CharNextFunc) cff_cmap_encoding_char_next, + (FT_CMap_InitFunc) cff_cmap_encoding_init, /* init */ + (FT_CMap_DoneFunc) cff_cmap_encoding_done, /* done */ + (FT_CMap_CharIndexFunc)cff_cmap_encoding_char_index, /* char_index */ + (FT_CMap_CharNextFunc) cff_cmap_encoding_char_next, /* char_next */ - NULL, NULL, NULL, NULL, NULL + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL /* variantchar_list */ ) @@ -202,15 +208,22 @@ } - FT_DEFINE_CMAP_CLASS(cff_cmap_unicode_class_rec, + FT_DEFINE_CMAP_CLASS( + cff_cmap_unicode_class_rec, + sizeof ( PS_UnicodesRec ), - (FT_CMap_InitFunc) cff_cmap_unicode_init, - (FT_CMap_DoneFunc) cff_cmap_unicode_done, - (FT_CMap_CharIndexFunc)cff_cmap_unicode_char_index, - (FT_CMap_CharNextFunc) cff_cmap_unicode_char_next, + (FT_CMap_InitFunc) cff_cmap_unicode_init, /* init */ + (FT_CMap_DoneFunc) cff_cmap_unicode_done, /* done */ + (FT_CMap_CharIndexFunc)cff_cmap_unicode_char_index, /* char_index */ + (FT_CMap_CharNextFunc) cff_cmap_unicode_char_next, /* char_next */ - NULL, NULL, NULL, NULL, NULL + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL /* variantchar_list */ ) + /* END */ diff --git a/src/3rdparty/freetype/src/cff/cffcmap.h b/src/3rdparty/freetype/src/cff/cffcmap.h index 6eaed636ec..856a43dd1b 100644 --- a/src/3rdparty/freetype/src/cff/cffcmap.h +++ b/src/3rdparty/freetype/src/cff/cffcmap.h @@ -4,7 +4,7 @@ /* */ /* CFF character mapping table (cmap) support (specification). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,10 +16,10 @@ /***************************************************************************/ -#ifndef __CFFCMAP_H__ -#define __CFFCMAP_H__ +#ifndef CFFCMAP_H_ +#define CFFCMAP_H_ -#include "cffobjs.h" +#include FT_INTERNAL_CFF_OBJECTS_TYPES_H FT_BEGIN_HEADER @@ -61,7 +61,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CFFCMAP_H__ */ +#endif /* CFFCMAP_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/cff/cffdrivr.c b/src/3rdparty/freetype/src/cff/cffdrivr.c index a718b7a002..df896848da 100644 --- a/src/3rdparty/freetype/src/cff/cffdrivr.c +++ b/src/3rdparty/freetype/src/cff/cffdrivr.c @@ -4,7 +4,7 @@ /* */ /* OpenType font driver implementation (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,16 +21,25 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H +#include FT_INTERNAL_POSTSCRIPT_PROPS_H #include FT_SERVICE_CID_H #include FT_SERVICE_POSTSCRIPT_INFO_H #include FT_SERVICE_POSTSCRIPT_NAME_H #include FT_SERVICE_TT_CMAP_H +#include FT_SERVICE_CFF_TABLE_LOAD_H #include "cffdrivr.h" #include "cffgload.h" #include "cffload.h" #include "cffcmap.h" #include "cffparse.h" +#include "cffobjs.h" + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include FT_SERVICE_MULTIPLE_MASTERS_H +#include FT_SERVICE_METRICS_VARIATIONS_H +#endif #include "cfferrs.h" #include "cffpic.h" @@ -38,7 +47,7 @@ #include FT_SERVICE_FONT_FORMAT_H #include FT_SERVICE_GLYPH_DICT_H #include FT_SERVICE_PROPERTIES_H -#include FT_CFF_DRIVER_H +#include FT_DRIVER_H /*************************************************************************/ @@ -207,6 +216,13 @@ if ( flags & FT_LOAD_VERTICAL_LAYOUT ) { +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + /* no fast retrieval for blended MM fonts without VVAR table */ + if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) && + !( ttface->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) + return FT_THROW( Unimplemented_Feature ); +#endif + /* check whether we have data from the `vmtx' table at all; */ /* otherwise we extract the info from the CFF glyphstrings */ /* (instead of synthesizing a global value using the `OS/2' */ @@ -225,13 +241,22 @@ &dummy, &ah ); - FT_TRACE5(( " idx %d: advance height %d font units\n", - start + nn, ah )); + FT_TRACE5(( " idx %d: advance height %d font unit%s\n", + start + nn, + ah, + ah == 1 ? "" : "s" )); advances[nn] = ah; } } else { +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + /* no fast retrieval for blended MM fonts without HVAR table */ + if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) && + !( ttface->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) + return FT_THROW( Unimplemented_Feature ); +#endif + /* check whether we have data from the `hmtx' table at all */ if ( !ttface->horizontal.number_Of_HMetrics ) goto Missing_Table; @@ -247,8 +272,10 @@ &dummy, &aw ); - FT_TRACE5(( " idx %d: advance width %d font units\n", - start + nn, aw )); + FT_TRACE5(( " idx %d: advance width %d font unit%s\n", + start + nn, + aw, + aw == 1 ? "" : "s" )); advances[nn] = aw; } } @@ -291,6 +318,35 @@ FT_Error error; + /* CFF2 table does not have glyph names; */ + /* we need to use `post' table method */ + if ( font->version_major == 2 ) + { + FT_Library library = FT_FACE_LIBRARY( face ); + FT_Module sfnt_module = FT_Get_Module( library, "sfnt" ); + FT_Service_GlyphDict service = + (FT_Service_GlyphDict)ft_module_get_service( + sfnt_module, + FT_SERVICE_ID_GLYPH_DICT, + 0 ); + + + if ( service && service->get_name ) + return service->get_name( FT_FACE( face ), + glyph_index, + buffer, + buffer_max ); + else + { + FT_ERROR(( "cff_get_glyph_name:" + " cannot get glyph name from a CFF2 font\n" + " " + " without the `PSNames' module\n" )); + error = FT_THROW( Missing_Module ); + goto Exit; + } + } + if ( !font->psnames ) { FT_ERROR(( "cff_get_glyph_name:" @@ -332,6 +388,31 @@ cff = (CFF_FontRec *)face->extra.data; charset = &cff->charset; + /* CFF2 table does not have glyph names; */ + /* we need to use `post' table method */ + if ( cff->version_major == 2 ) + { + FT_Library library = FT_FACE_LIBRARY( face ); + FT_Module sfnt_module = FT_Get_Module( library, "sfnt" ); + FT_Service_GlyphDict service = + (FT_Service_GlyphDict)ft_module_get_service( + sfnt_module, + FT_SERVICE_ID_GLYPH_DICT, + 0 ); + + + if ( service && service->name_index ) + return service->name_index( FT_FACE( face ), glyph_name ); + else + { + FT_ERROR(( "cff_get_name_index:" + " cannot get glyph index from a CFF2 font\n" + " " + " without the `PSNames' module\n" )); + return 0; + } + } + FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); if ( !psnames ) return 0; @@ -358,8 +439,9 @@ FT_DEFINE_SERVICE_GLYPHDICTREC( cff_service_glyph_dict, - (FT_GlyphDict_GetNameFunc) cff_get_glyph_name, - (FT_GlyphDict_NameIndexFunc)cff_get_name_index + + (FT_GlyphDict_GetNameFunc) cff_get_glyph_name, /* get_name */ + (FT_GlyphDict_NameIndexFunc)cff_get_name_index /* name_index */ ) @@ -383,11 +465,11 @@ FT_Error error = FT_Err_Ok; - if ( cff && cff->font_info == NULL ) + if ( cff && !cff->font_info ) { - CFF_FontRecDict dict = &cff->top_font.font_dict; + CFF_FontRecDict dict = &cff->top_font.font_dict; PS_FontInfoRec *font_info = NULL; - FT_Memory memory = face->root.memory; + FT_Memory memory = face->root.memory; if ( FT_ALLOC( font_info, sizeof ( *font_info ) ) ) @@ -419,13 +501,94 @@ } + static FT_Error + cff_ps_get_font_extra( CFF_Face face, + PS_FontExtraRec* afont_extra ) + { + CFF_Font cff = (CFF_Font)face->extra.data; + FT_Error error = FT_Err_Ok; + + + if ( cff && cff->font_extra == NULL ) + { + CFF_FontRecDict dict = &cff->top_font.font_dict; + PS_FontExtraRec* font_extra = NULL; + FT_Memory memory = face->root.memory; + FT_String* embedded_postscript; + + + if ( FT_ALLOC( font_extra, sizeof ( *font_extra ) ) ) + goto Fail; + + font_extra->fs_type = 0U; + + embedded_postscript = cff_index_get_sid_string( + cff, + dict->embedded_postscript ); + if ( embedded_postscript ) + { + FT_String* start_fstype; + FT_String* start_def; + + + /* Identify the XYZ integer in `/FSType XYZ def' substring. */ + if ( ( start_fstype = ft_strstr( embedded_postscript, + "/FSType" ) ) != NULL && + ( start_def = ft_strstr( start_fstype + + sizeof ( "/FSType" ) - 1, + "def" ) ) != NULL ) + { + FT_String* s; + + + for ( s = start_fstype + sizeof ( "/FSType" ) - 1; + s != start_def; + s++ ) + { + if ( *s >= '0' && *s <= '9' ) + { + if ( font_extra->fs_type >= ( FT_USHORT_MAX - 9 ) / 10 ) + { + /* Overflow - ignore the FSType value. */ + font_extra->fs_type = 0U; + break; + } + + font_extra->fs_type *= 10; + font_extra->fs_type += (FT_UShort)( *s - '0' ); + } + else if ( *s != ' ' && *s != '\n' && *s != '\r' ) + { + /* Non-whitespace character between `/FSType' and next `def' */ + /* - ignore the FSType value. */ + font_extra->fs_type = 0U; + break; + } + } + } + } + + cff->font_extra = font_extra; + } + + if ( cff ) + *afont_extra = *cff->font_extra; + + Fail: + return error; + } + + FT_DEFINE_SERVICE_PSINFOREC( cff_service_ps_info, - (PS_GetFontInfoFunc) cff_ps_get_font_info, - (PS_GetFontExtraFunc) NULL, - (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names, - (PS_GetFontPrivateFunc)NULL, /* unsupported with CFF fonts */ - (PS_GetFontValueFunc) NULL /* not implemented */ + + (PS_GetFontInfoFunc) cff_ps_get_font_info, /* ps_get_font_info */ + (PS_GetFontExtraFunc) cff_ps_get_font_extra, /* ps_get_font_extra */ + (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names, /* ps_has_glyph_names */ + /* unsupported with CFF fonts */ + (PS_GetFontPrivateFunc)NULL, /* ps_get_font_private */ + /* not implemented */ + (PS_GetFontValueFunc) NULL /* ps_get_font_value */ ) @@ -444,14 +607,15 @@ /* following the OpenType specification 1.7, we return the name stored */ /* in the `name' table for a CFF wrapped into an SFNT container */ - if ( sfnt ) + if ( FT_IS_SFNT( FT_FACE( face ) ) && sfnt ) { FT_Library library = FT_FACE_LIBRARY( face ); FT_Module sfnt_module = FT_Get_Module( library, "sfnt" ); FT_Service_PsFontName service = (FT_Service_PsFontName)ft_module_get_service( sfnt_module, - FT_SERVICE_ID_POSTSCRIPT_FONT_NAME ); + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, + 0 ); if ( service && service->get_ps_font_name ) @@ -464,7 +628,8 @@ FT_DEFINE_SERVICE_PSFONTNAMEREC( cff_service_ps_name, - (FT_PsName_GetFunc)cff_get_ps_name + + (FT_PsName_GetFunc)cff_get_ps_name /* get_ps_font_name */ ) @@ -489,21 +654,21 @@ FT_Library library = FT_FACE_LIBRARY( face ); - cmap_info->language = 0; - cmap_info->format = 0; - if ( cmap->clazz != &CFF_CMAP_ENCODING_CLASS_REC_GET && cmap->clazz != &CFF_CMAP_UNICODE_CLASS_REC_GET ) { FT_Module sfnt = FT_Get_Module( library, "sfnt" ); FT_Service_TTCMaps service = (FT_Service_TTCMaps)ft_module_get_service( sfnt, - FT_SERVICE_ID_TT_CMAP ); + FT_SERVICE_ID_TT_CMAP, + 0 ); if ( service && service->get_cmap_info ) error = service->get_cmap_info( charmap, cmap_info ); } + else + error = FT_THROW( Invalid_CharMap_Format ); return error; } @@ -511,7 +676,8 @@ FT_DEFINE_SERVICE_TTCMAPSREC( cff_service_get_cmap_info, - (TT_CMap_Info_GetFunc)cff_get_cmap_info + + (TT_CMap_Info_GetFunc)cff_get_cmap_info /* get_cmap_info */ ) @@ -542,7 +708,7 @@ if ( registry ) { - if ( cff->registry == NULL ) + if ( !cff->registry ) cff->registry = cff_index_get_sid_string( cff, dict->cid_registry ); *registry = cff->registry; @@ -550,7 +716,7 @@ if ( ordering ) { - if ( cff->ordering == NULL ) + if ( !cff->ordering ) cff->ordering = cff_index_get_sid_string( cff, dict->cid_ordering ); *ordering = cff->ordering; @@ -641,9 +807,13 @@ FT_DEFINE_SERVICE_CIDREC( cff_service_cid_info, - (FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros, - (FT_CID_GetIsInternallyCIDKeyedFunc) cff_get_is_cid, - (FT_CID_GetCIDFromGlyphIndexFunc) cff_get_cid_from_glyph_index + + (FT_CID_GetRegistryOrderingSupplementFunc) + cff_get_ros, /* get_ros */ + (FT_CID_GetIsInternallyCIDKeyedFunc) + cff_get_is_cid, /* get_is_cid */ + (FT_CID_GetCIDFromGlyphIndexFunc) + cff_get_cid_from_glyph_index /* get_cid_from_glyph_index */ ) @@ -651,133 +821,166 @@ * PROPERTY SERVICE * */ - static FT_Error - cff_property_set( FT_Module module, /* CFF_Driver */ - const char* property_name, - const void* value ) - { - FT_Error error = FT_Err_Ok; - CFF_Driver driver = (CFF_Driver)module; - - - if ( !ft_strcmp( property_name, "darkening-parameters" ) ) - { - FT_Int* darken_params = (FT_Int*)value; - - FT_Int x1 = darken_params[0]; - FT_Int y1 = darken_params[1]; - FT_Int x2 = darken_params[2]; - FT_Int y2 = darken_params[3]; - FT_Int x3 = darken_params[4]; - FT_Int y3 = darken_params[5]; - FT_Int x4 = darken_params[6]; - FT_Int y4 = darken_params[7]; - - - if ( x1 < 0 || x2 < 0 || x3 < 0 || x4 < 0 || - y1 < 0 || y2 < 0 || y3 < 0 || y4 < 0 || - x1 > x2 || x2 > x3 || x3 > x4 || - y1 > 500 || y2 > 500 || y3 > 500 || y4 > 500 ) - return FT_THROW( Invalid_Argument ); - - driver->darken_params[0] = x1; - driver->darken_params[1] = y1; - driver->darken_params[2] = x2; - driver->darken_params[3] = y2; - driver->darken_params[4] = x3; - driver->darken_params[5] = y3; - driver->darken_params[6] = x4; - driver->darken_params[7] = y4; - - return error; - } - else if ( !ft_strcmp( property_name, "hinting-engine" ) ) - { - FT_UInt* hinting_engine = (FT_UInt*)value; - - -#ifndef CFF_CONFIG_OPTION_OLD_ENGINE - if ( *hinting_engine != FT_CFF_HINTING_ADOBE ) - error = FT_ERR( Unimplemented_Feature ); - else -#endif - driver->hinting_engine = *hinting_engine; - - return error; - } - else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) - { - FT_Bool* no_stem_darkening = (FT_Bool*)value; - - - driver->no_stem_darkening = *no_stem_darkening; - - return error; - } - - FT_TRACE0(( "cff_property_set: missing property `%s'\n", - property_name )); - return FT_THROW( Missing_Property ); - } - - - static FT_Error - cff_property_get( FT_Module module, /* CFF_Driver */ - const char* property_name, - const void* value ) - { - FT_Error error = FT_Err_Ok; - CFF_Driver driver = (CFF_Driver)module; - - - if ( !ft_strcmp( property_name, "darkening-parameters" ) ) - { - FT_Int* darken_params = driver->darken_params; - FT_Int* val = (FT_Int*)value; - - - val[0] = darken_params[0]; - val[1] = darken_params[1]; - val[2] = darken_params[2]; - val[3] = darken_params[3]; - val[4] = darken_params[4]; - val[5] = darken_params[5]; - val[6] = darken_params[6]; - val[7] = darken_params[7]; - - return error; - } - else if ( !ft_strcmp( property_name, "hinting-engine" ) ) - { - FT_UInt hinting_engine = driver->hinting_engine; - FT_UInt* val = (FT_UInt*)value; - - - *val = hinting_engine; - - return error; - } - else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) - { - FT_Bool no_stem_darkening = driver->no_stem_darkening; - FT_Bool* val = (FT_Bool*)value; - - - *val = no_stem_darkening; - - return error; - } - - FT_TRACE0(( "cff_property_get: missing property `%s'\n", - property_name )); - return FT_THROW( Missing_Property ); - } - FT_DEFINE_SERVICE_PROPERTIESREC( cff_service_properties, - (FT_Properties_SetFunc)cff_property_set, - (FT_Properties_GetFunc)cff_property_get ) + + (FT_Properties_SetFunc)ps_property_set, /* set_property */ + (FT_Properties_GetFunc)ps_property_get ) /* get_property */ + + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + + /* + * MULTIPLE MASTER SERVICE + * + */ + + static FT_Error + cff_set_mm_blend( CFF_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + return mm->set_mm_blend( FT_FACE( face ), num_coords, coords ); + } + + + static FT_Error + cff_get_mm_blend( CFF_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + return mm->get_mm_blend( FT_FACE( face ), num_coords, coords ); + } + + + static FT_Error + cff_get_mm_var( CFF_Face face, + FT_MM_Var* *master ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + return mm->get_mm_var( FT_FACE( face ), master ); + } + + + static FT_Error + cff_set_var_design( CFF_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + return mm->set_var_design( FT_FACE( face ), num_coords, coords ); + } + + + static FT_Error + cff_get_var_design( CFF_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + return mm->get_var_design( FT_FACE( face ), num_coords, coords ); + } + + + static FT_Error + cff_set_instance( CFF_Face face, + FT_UInt instance_index ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + return mm->set_instance( FT_FACE( face ), instance_index ); + } + + + FT_DEFINE_SERVICE_MULTIMASTERSREC( + cff_service_multi_masters, + + (FT_Get_MM_Func) NULL, /* get_mm */ + (FT_Set_MM_Design_Func) NULL, /* set_mm_design */ + (FT_Set_MM_Blend_Func) cff_set_mm_blend, /* set_mm_blend */ + (FT_Get_MM_Blend_Func) cff_get_mm_blend, /* get_mm_blend */ + (FT_Get_MM_Var_Func) cff_get_mm_var, /* get_mm_var */ + (FT_Set_Var_Design_Func)cff_set_var_design, /* set_var_design */ + (FT_Get_Var_Design_Func)cff_get_var_design, /* get_var_design */ + (FT_Set_Instance_Func) cff_set_instance, /* set_instance */ + + (FT_Get_Var_Blend_Func) cff_get_var_blend, /* get_var_blend */ + (FT_Done_Blend_Func) cff_done_blend /* done_blend */ + ) + + + /* + * METRICS VARIATIONS SERVICE + * + */ + + static FT_Error + cff_hadvance_adjust( CFF_Face face, + FT_UInt gindex, + FT_Int *avalue ) + { + FT_Service_MetricsVariations var = (FT_Service_MetricsVariations)face->var; + + + return var->hadvance_adjust( FT_FACE( face ), gindex, avalue ); + } + + + static void + cff_metrics_adjust( CFF_Face face ) + { + FT_Service_MetricsVariations var = (FT_Service_MetricsVariations)face->var; + + + var->metrics_adjust( FT_FACE( face ) ); + } + + + FT_DEFINE_SERVICE_METRICSVARIATIONSREC( + cff_service_metrics_variations, + + (FT_HAdvance_Adjust_Func)cff_hadvance_adjust, /* hadvance_adjust */ + (FT_LSB_Adjust_Func) NULL, /* lsb_adjust */ + (FT_RSB_Adjust_Func) NULL, /* rsb_adjust */ + + (FT_VAdvance_Adjust_Func)NULL, /* vadvance_adjust */ + (FT_TSB_Adjust_Func) NULL, /* tsb_adjust */ + (FT_BSB_Adjust_Func) NULL, /* bsb_adjust */ + (FT_VOrg_Adjust_Func) NULL, /* vorg_adjust */ + + (FT_Metrics_Adjust_Func) cff_metrics_adjust /* metrics_adjust */ + ) +#endif + + + /* + * CFFLOAD SERVICE + * + */ + + FT_DEFINE_SERVICE_CFFLOADREC( + cff_service_cff_load, + + (FT_Get_Standard_Encoding_Func)cff_get_standard_encoding, + (FT_Load_Private_Dict_Func) cff_load_private_dict, + (FT_FD_Select_Get_Func) cff_fd_select_get, + (FT_Blend_Check_Vector_Func) cff_blend_check_vector, + (FT_Blend_Build_Vector_Func) cff_blend_build_vector + ) /*************************************************************************/ @@ -792,26 +995,60 @@ /*************************************************************************/ /*************************************************************************/ -#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES - FT_DEFINE_SERVICEDESCREC7( +#if !defined FT_CONFIG_OPTION_NO_GLYPH_NAMES && \ + defined TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_DEFINE_SERVICEDESCREC10( cff_services, + + FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF, + FT_SERVICE_ID_MULTI_MASTERS, &CFF_SERVICE_MULTI_MASTERS_GET, + FT_SERVICE_ID_METRICS_VARIATIONS, &CFF_SERVICE_METRICS_VAR_GET, + FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_GLYPH_DICT, &CFF_SERVICE_GLYPH_DICT_GET, + FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET, + FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET, + FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET, + FT_SERVICE_ID_CFF_LOAD, &CFF_SERVICE_CFF_LOAD_GET + ) +#elif !defined FT_CONFIG_OPTION_NO_GLYPH_NAMES + FT_DEFINE_SERVICEDESCREC8( + cff_services, + FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF, FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, FT_SERVICE_ID_GLYPH_DICT, &CFF_SERVICE_GLYPH_DICT_GET, FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET, FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET, - FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET + FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET, + FT_SERVICE_ID_CFF_LOAD, &CFF_SERVICE_CFF_LOAD_GET + ) +#elif defined TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_DEFINE_SERVICEDESCREC9( + cff_services, + + FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF, + FT_SERVICE_ID_MULTI_MASTERS, &CFF_SERVICE_MULTI_MASTERS_GET, + FT_SERVICE_ID_METRICS_VARIATIONS, &CFF_SERVICE_METRICS_VAR_GET, + FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, + FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, + FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET, + FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET, + FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET, + FT_SERVICE_ID_CFF_LOAD, &CFF_SERVICE_CFF_LOAD_GET ) #else - FT_DEFINE_SERVICEDESCREC6( + FT_DEFINE_SERVICEDESCREC7( cff_services, + FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_CFF, FT_SERVICE_ID_POSTSCRIPT_INFO, &CFF_SERVICE_PS_INFO_GET, FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &CFF_SERVICE_PS_NAME_GET, FT_SERVICE_ID_TT_CMAP, &CFF_SERVICE_GET_CMAP_INFO_GET, FT_SERVICE_ID_CID, &CFF_SERVICE_CID_INFO_GET, - FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET + FT_SERVICE_ID_PROPERTIES, &CFF_SERVICE_PROPERTIES_GET, + FT_SERVICE_ID_CFF_LOAD, &CFF_SERVICE_CFF_LOAD_GET ) #endif @@ -835,7 +1072,7 @@ #endif result = ft_service_list_lookup( CFF_SERVICES_GET, module_interface ); - if ( result != NULL ) + if ( result ) return result; /* `driver' is not yet evaluated in non-PIC mode */ @@ -865,42 +1102,41 @@ FT_DEFINE_DRIVER( cff_driver_class, - FT_MODULE_FONT_DRIVER | - FT_MODULE_DRIVER_SCALABLE | - FT_MODULE_DRIVER_HAS_HINTER, + FT_MODULE_FONT_DRIVER | + FT_MODULE_DRIVER_SCALABLE | + FT_MODULE_DRIVER_HAS_HINTER | + FT_MODULE_DRIVER_HINTS_LIGHTLY, - sizeof ( CFF_DriverRec ), + sizeof ( PS_DriverRec ), "cff", 0x10000L, 0x20000L, - 0, /* module-specific interface */ + NULL, /* module-specific interface */ - cff_driver_init, - cff_driver_done, - cff_get_interface, + cff_driver_init, /* FT_Module_Constructor module_init */ + cff_driver_done, /* FT_Module_Destructor module_done */ + cff_get_interface, /* FT_Module_Requester get_interface */ - /* now the specific driver fields */ sizeof ( TT_FaceRec ), sizeof ( CFF_SizeRec ), sizeof ( CFF_GlyphSlotRec ), - cff_face_init, - cff_face_done, - cff_size_init, - cff_size_done, - cff_slot_init, - cff_slot_done, + cff_face_init, /* FT_Face_InitFunc init_face */ + cff_face_done, /* FT_Face_DoneFunc done_face */ + cff_size_init, /* FT_Size_InitFunc init_size */ + cff_size_done, /* FT_Size_DoneFunc done_size */ + cff_slot_init, /* FT_Slot_InitFunc init_slot */ + cff_slot_done, /* FT_Slot_DoneFunc done_slot */ - cff_glyph_load, + cff_glyph_load, /* FT_Slot_LoadFunc load_glyph */ - cff_get_kerning, - 0, /* FT_Face_AttachFunc */ - cff_get_advances, + cff_get_kerning, /* FT_Face_GetKerningFunc get_kerning */ + NULL, /* FT_Face_AttachFunc attach_file */ + cff_get_advances, /* FT_Face_GetAdvancesFunc get_advances */ - cff_size_request, - - CFF_SIZE_SELECT + cff_size_request, /* FT_Size_RequestFunc request_size */ + CFF_SIZE_SELECT /* FT_Size_SelectFunc select_size */ ) diff --git a/src/3rdparty/freetype/src/cff/cffdrivr.h b/src/3rdparty/freetype/src/cff/cffdrivr.h index 9527f5e149..ad7c3ad70a 100644 --- a/src/3rdparty/freetype/src/cff/cffdrivr.h +++ b/src/3rdparty/freetype/src/cff/cffdrivr.h @@ -4,7 +4,7 @@ /* */ /* High-level OpenType driver interface (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CFFDRIVER_H__ -#define __CFFDRIVER_H__ +#ifndef CFFDRIVER_H_ +#define CFFDRIVER_H_ #include <ft2build.h> @@ -32,7 +32,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CFFDRIVER_H__ */ +#endif /* CFFDRIVER_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/cff/cfferrs.h b/src/3rdparty/freetype/src/cff/cfferrs.h index 543bdb07c2..b2e1bfaf9d 100644 --- a/src/3rdparty/freetype/src/cff/cfferrs.h +++ b/src/3rdparty/freetype/src/cff/cfferrs.h @@ -4,7 +4,7 @@ /* */ /* CFF error codes (specification only). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __CFFERRS_H__ -#define __CFFERRS_H__ +#ifndef CFFERRS_H_ +#define CFFERRS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX CFF_Err_ @@ -36,7 +36,7 @@ #include FT_ERRORS_H -#endif /* __CFFERRS_H__ */ +#endif /* CFFERRS_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/cff/cffgload.c b/src/3rdparty/freetype/src/cff/cffgload.c index 5f57403e22..c58471ce86 100644 --- a/src/3rdparty/freetype/src/cff/cffgload.c +++ b/src/3rdparty/freetype/src/cff/cffgload.c @@ -4,7 +4,7 @@ /* */ /* OpenType Glyph Loader (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,13 +20,13 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H +#include FT_INTERNAL_CALC_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H #include FT_OUTLINE_H -#include FT_CFF_DRIVER_H +#include FT_DRIVER_H -#include "cffobjs.h" #include "cffload.h" #include "cffgload.h" -#include "cf2ft.h" /* for cf2_decoder_parse_charstrings */ #include "cfferrs.h" @@ -41,618 +41,6 @@ #define FT_COMPONENT trace_cffgload -#ifdef CFF_CONFIG_OPTION_OLD_ENGINE - - typedef enum CFF_Operator_ - { - cff_op_unknown = 0, - - cff_op_rmoveto, - cff_op_hmoveto, - cff_op_vmoveto, - - cff_op_rlineto, - cff_op_hlineto, - cff_op_vlineto, - - cff_op_rrcurveto, - cff_op_hhcurveto, - cff_op_hvcurveto, - cff_op_rcurveline, - cff_op_rlinecurve, - cff_op_vhcurveto, - cff_op_vvcurveto, - - cff_op_flex, - cff_op_hflex, - cff_op_hflex1, - cff_op_flex1, - - cff_op_endchar, - - cff_op_hstem, - cff_op_vstem, - cff_op_hstemhm, - cff_op_vstemhm, - - cff_op_hintmask, - cff_op_cntrmask, - cff_op_dotsection, /* deprecated, acts as no-op */ - - cff_op_abs, - cff_op_add, - cff_op_sub, - cff_op_div, - cff_op_neg, - cff_op_random, - cff_op_mul, - cff_op_sqrt, - - cff_op_blend, - - cff_op_drop, - cff_op_exch, - cff_op_index, - cff_op_roll, - cff_op_dup, - - cff_op_put, - cff_op_get, - cff_op_store, - cff_op_load, - - cff_op_and, - cff_op_or, - cff_op_not, - cff_op_eq, - cff_op_ifelse, - - cff_op_callsubr, - cff_op_callgsubr, - cff_op_return, - - /* Type 1 opcodes: invalid but seen in real life */ - cff_op_hsbw, - cff_op_closepath, - cff_op_callothersubr, - cff_op_pop, - cff_op_seac, - cff_op_sbw, - cff_op_setcurrentpoint, - - /* do not remove */ - cff_op_max - - } CFF_Operator; - - -#define CFF_COUNT_CHECK_WIDTH 0x80 -#define CFF_COUNT_EXACT 0x40 -#define CFF_COUNT_CLEAR_STACK 0x20 - - /* count values which have the `CFF_COUNT_CHECK_WIDTH' flag set are */ - /* used for checking the width and requested numbers of arguments */ - /* only; they are set to zero afterwards */ - - /* the other two flags are informative only and unused currently */ - - static const FT_Byte cff_argument_counts[] = - { - 0, /* unknown */ - - 2 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, /* rmoveto */ - 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, - 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, - - 0 | CFF_COUNT_CLEAR_STACK, /* rlineto */ - 0 | CFF_COUNT_CLEAR_STACK, - 0 | CFF_COUNT_CLEAR_STACK, - - 0 | CFF_COUNT_CLEAR_STACK, /* rrcurveto */ - 0 | CFF_COUNT_CLEAR_STACK, - 0 | CFF_COUNT_CLEAR_STACK, - 0 | CFF_COUNT_CLEAR_STACK, - 0 | CFF_COUNT_CLEAR_STACK, - 0 | CFF_COUNT_CLEAR_STACK, - 0 | CFF_COUNT_CLEAR_STACK, - - 13, /* flex */ - 7, - 9, - 11, - - 0 | CFF_COUNT_CHECK_WIDTH, /* endchar */ - - 2 | CFF_COUNT_CHECK_WIDTH, /* hstem */ - 2 | CFF_COUNT_CHECK_WIDTH, - 2 | CFF_COUNT_CHECK_WIDTH, - 2 | CFF_COUNT_CHECK_WIDTH, - - 0 | CFF_COUNT_CHECK_WIDTH, /* hintmask */ - 0 | CFF_COUNT_CHECK_WIDTH, /* cntrmask */ - 0, /* dotsection */ - - 1, /* abs */ - 2, - 2, - 2, - 1, - 0, - 2, - 1, - - 1, /* blend */ - - 1, /* drop */ - 2, - 1, - 2, - 1, - - 2, /* put */ - 1, - 4, - 3, - - 2, /* and */ - 2, - 1, - 2, - 4, - - 1, /* callsubr */ - 1, - 0, - - 2, /* hsbw */ - 0, - 0, - 0, - 5, /* seac */ - 4, /* sbw */ - 2 /* setcurrentpoint */ - }; - -#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ - - - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** *********/ - /********** GENERIC CHARSTRING PARSING *********/ - /********** *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* cff_builder_init */ - /* */ - /* <Description> */ - /* Initializes a given glyph builder. */ - /* */ - /* <InOut> */ - /* builder :: A pointer to the glyph builder to initialize. */ - /* */ - /* <Input> */ - /* face :: The current face object. */ - /* */ - /* size :: The current size object. */ - /* */ - /* glyph :: The current glyph object. */ - /* */ - /* hinting :: Whether hinting is active. */ - /* */ - static void - cff_builder_init( CFF_Builder* builder, - TT_Face face, - CFF_Size size, - CFF_GlyphSlot glyph, - FT_Bool hinting ) - { - builder->path_begun = 0; - builder->load_points = 1; - - builder->face = face; - builder->glyph = glyph; - builder->memory = face->root.memory; - - if ( glyph ) - { - FT_GlyphLoader loader = glyph->root.internal->loader; - - - builder->loader = loader; - builder->base = &loader->base.outline; - builder->current = &loader->current.outline; - FT_GlyphLoader_Rewind( loader ); - - builder->hints_globals = NULL; - builder->hints_funcs = NULL; - - if ( hinting && size ) - { - CFF_Internal internal = (CFF_Internal)size->root.internal; - - - builder->hints_globals = (void *)internal->topfont; - builder->hints_funcs = glyph->root.internal->glyph_hints; - } - } - - builder->pos_x = 0; - builder->pos_y = 0; - - builder->left_bearing.x = 0; - builder->left_bearing.y = 0; - builder->advance.x = 0; - builder->advance.y = 0; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* cff_builder_done */ - /* */ - /* <Description> */ - /* Finalizes a given glyph builder. Its contents can still be used */ - /* after the call, but the function saves important information */ - /* within the corresponding glyph slot. */ - /* */ - /* <Input> */ - /* builder :: A pointer to the glyph builder to finalize. */ - /* */ - static void - cff_builder_done( CFF_Builder* builder ) - { - CFF_GlyphSlot glyph = builder->glyph; - - - if ( glyph ) - glyph->root.outline = *builder->base; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* cff_compute_bias */ - /* */ - /* <Description> */ - /* Computes the bias value in dependence of the number of glyph */ - /* subroutines. */ - /* */ - /* <Input> */ - /* in_charstring_type :: The `CharstringType' value of the top DICT */ - /* dictionary. */ - /* */ - /* num_subrs :: The number of glyph subroutines. */ - /* */ - /* <Return> */ - /* The bias value. */ - static FT_Int - cff_compute_bias( FT_Int in_charstring_type, - FT_UInt num_subrs ) - { - FT_Int result; - - - if ( in_charstring_type == 1 ) - result = 0; - else if ( num_subrs < 1240 ) - result = 107; - else if ( num_subrs < 33900U ) - result = 1131; - else - result = 32768U; - - return result; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* cff_decoder_init */ - /* */ - /* <Description> */ - /* Initializes a given glyph decoder. */ - /* */ - /* <InOut> */ - /* decoder :: A pointer to the glyph builder to initialize. */ - /* */ - /* <Input> */ - /* face :: The current face object. */ - /* */ - /* size :: The current size object. */ - /* */ - /* slot :: The current glyph object. */ - /* */ - /* hinting :: Whether hinting is active. */ - /* */ - /* hint_mode :: The hinting mode. */ - /* */ - FT_LOCAL_DEF( void ) - cff_decoder_init( CFF_Decoder* decoder, - TT_Face face, - CFF_Size size, - CFF_GlyphSlot slot, - FT_Bool hinting, - FT_Render_Mode hint_mode ) - { - CFF_Font cff = (CFF_Font)face->extra.data; - - - /* clear everything */ - FT_MEM_ZERO( decoder, sizeof ( *decoder ) ); - - /* initialize builder */ - cff_builder_init( &decoder->builder, face, size, slot, hinting ); - - /* initialize Type2 decoder */ - decoder->cff = cff; - decoder->num_globals = cff->global_subrs_index.count; - decoder->globals = cff->global_subrs; - decoder->globals_bias = cff_compute_bias( - cff->top_font.font_dict.charstring_type, - decoder->num_globals ); - - decoder->hint_mode = hint_mode; - } - - - /* this function is used to select the subfont */ - /* and the locals subrs array */ - FT_LOCAL_DEF( FT_Error ) - cff_decoder_prepare( CFF_Decoder* decoder, - CFF_Size size, - FT_UInt glyph_index ) - { - CFF_Builder *builder = &decoder->builder; - CFF_Font cff = (CFF_Font)builder->face->extra.data; - CFF_SubFont sub = &cff->top_font; - FT_Error error = FT_Err_Ok; - - - /* manage CID fonts */ - if ( cff->num_subfonts ) - { - FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, glyph_index ); - - - if ( fd_index >= cff->num_subfonts ) - { - FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - FT_TRACE3(( " in subfont %d:\n", fd_index )); - - sub = cff->subfonts[fd_index]; - - if ( builder->hints_funcs && size ) - { - CFF_Internal internal = (CFF_Internal)size->root.internal; - - - /* for CFFs without subfonts, this value has already been set */ - builder->hints_globals = (void *)internal->subfonts[fd_index]; - } - } - - decoder->num_locals = sub->local_subrs_index.count; - decoder->locals = sub->local_subrs; - decoder->locals_bias = cff_compute_bias( - decoder->cff->top_font.font_dict.charstring_type, - decoder->num_locals ); - - decoder->glyph_width = sub->private_dict.default_width; - decoder->nominal_width = sub->private_dict.nominal_width; - - decoder->current_subfont = sub; /* for Adobe's CFF handler */ - - Exit: - return error; - } - - - /* check that there is enough space for `count' more points */ - FT_LOCAL_DEF( FT_Error ) - cff_check_points( CFF_Builder* builder, - FT_Int count ) - { - return FT_GLYPHLOADER_CHECK_POINTS( builder->loader, count, 0 ); - } - - - /* add a new point, do not check space */ - FT_LOCAL_DEF( void ) - cff_builder_add_point( CFF_Builder* builder, - FT_Pos x, - FT_Pos y, - FT_Byte flag ) - { - FT_Outline* outline = builder->current; - - - if ( builder->load_points ) - { - FT_Vector* point = outline->points + outline->n_points; - FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; - -#ifdef CFF_CONFIG_OPTION_OLD_ENGINE - CFF_Driver driver = (CFF_Driver)FT_FACE_DRIVER( builder->face ); - - - if ( driver->hinting_engine == FT_CFF_HINTING_FREETYPE ) - { - point->x = x >> 16; - point->y = y >> 16; - } - else -#endif - { - /* cf2_decoder_parse_charstrings uses 16.16 coordinates */ - point->x = x >> 10; - point->y = y >> 10; - } - *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC ); - } - - outline->n_points++; - } - - - /* check space for a new on-curve point, then add it */ - FT_LOCAL_DEF( FT_Error ) - cff_builder_add_point1( CFF_Builder* builder, - FT_Pos x, - FT_Pos y ) - { - FT_Error error; - - - error = cff_check_points( builder, 1 ); - if ( !error ) - cff_builder_add_point( builder, x, y, 1 ); - - return error; - } - - - /* check space for a new contour, then add it */ - static FT_Error - cff_builder_add_contour( CFF_Builder* builder ) - { - FT_Outline* outline = builder->current; - FT_Error error; - - - if ( !builder->load_points ) - { - outline->n_contours++; - return FT_Err_Ok; - } - - error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 ); - if ( !error ) - { - if ( outline->n_contours > 0 ) - outline->contours[outline->n_contours - 1] = - (short)( outline->n_points - 1 ); - - outline->n_contours++; - } - - return error; - } - - - /* if a path was begun, add its first on-curve point */ - FT_LOCAL_DEF( FT_Error ) - cff_builder_start_point( CFF_Builder* builder, - FT_Pos x, - FT_Pos y ) - { - FT_Error error = FT_Err_Ok; - - - /* test whether we are building a new contour */ - if ( !builder->path_begun ) - { - builder->path_begun = 1; - error = cff_builder_add_contour( builder ); - if ( !error ) - error = cff_builder_add_point1( builder, x, y ); - } - - return error; - } - - - /* close the current contour */ - FT_LOCAL_DEF( void ) - cff_builder_close_contour( CFF_Builder* builder ) - { - FT_Outline* outline = builder->current; - FT_Int first; - - - if ( !outline ) - return; - - first = outline->n_contours <= 1 - ? 0 : outline->contours[outline->n_contours - 2] + 1; - - /* We must not include the last point in the path if it */ - /* is located on the first point. */ - if ( outline->n_points > 1 ) - { - FT_Vector* p1 = outline->points + first; - FT_Vector* p2 = outline->points + outline->n_points - 1; - FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1; - - - /* `delete' last point only if it coincides with the first */ - /* point and if it is not a control point (which can happen). */ - if ( p1->x == p2->x && p1->y == p2->y ) - if ( *control == FT_CURVE_TAG_ON ) - outline->n_points--; - } - - if ( outline->n_contours > 0 ) - { - /* Don't add contours only consisting of one point, i.e., */ - /* check whether begin point and last point are the same. */ - if ( first == outline->n_points - 1 ) - { - outline->n_contours--; - outline->n_points--; - } - else - outline->contours[outline->n_contours - 1] = - (short)( outline->n_points - 1 ); - } - } - - - FT_LOCAL_DEF( FT_Int ) - cff_lookup_glyph_by_stdcharcode( CFF_Font cff, - FT_Int charcode ) - { - FT_UInt n; - FT_UShort glyph_sid; - - - /* CID-keyed fonts don't have glyph names */ - if ( !cff->charset.sids ) - return -1; - - /* check range of standard char code */ - if ( charcode < 0 || charcode > 255 ) - return -1; - - /* Get code to SID mapping from `cff_standard_encoding'. */ - glyph_sid = cff_get_standard_encoding( (FT_UInt)charcode ); - - for ( n = 0; n < cff->num_glyphs; n++ ) - { - if ( cff->charset.sids[n] == glyph_sid ) - return (FT_Int)n; - } - - return -1; - } - - FT_LOCAL_DEF( FT_Error ) cff_get_glyph_data( TT_Face face, FT_UInt glyph_index, @@ -680,7 +68,7 @@ #endif /* FT_CONFIG_OPTION_INCREMENTAL */ { - CFF_Font cff = (CFF_Font)(face->extra.data); + CFF_Font cff = (CFF_Font)(face->extra.data); return cff_index_access_element( &cff->charstrings_index, glyph_index, @@ -724,1811 +112,6 @@ } -#ifdef CFF_CONFIG_OPTION_OLD_ENGINE - - static FT_Error - cff_operator_seac( CFF_Decoder* decoder, - FT_Pos asb, - FT_Pos adx, - FT_Pos ady, - FT_Int bchar, - FT_Int achar ) - { - FT_Error error; - CFF_Builder* builder = &decoder->builder; - FT_Int bchar_index, achar_index; - TT_Face face = decoder->builder.face; - FT_Vector left_bearing, advance; - FT_Byte* charstring; - FT_ULong charstring_len; - FT_Pos glyph_width; - - - if ( decoder->seac ) - { - FT_ERROR(( "cff_operator_seac: invalid nested seac\n" )); - return FT_THROW( Syntax_Error ); - } - - adx += decoder->builder.left_bearing.x; - ady += decoder->builder.left_bearing.y; - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - /* Incremental fonts don't necessarily have valid charsets. */ - /* They use the character code, not the glyph index, in this case. */ - if ( face->root.internal->incremental_interface ) - { - bchar_index = bchar; - achar_index = achar; - } - else -#endif /* FT_CONFIG_OPTION_INCREMENTAL */ - { - CFF_Font cff = (CFF_Font)(face->extra.data); - - - bchar_index = cff_lookup_glyph_by_stdcharcode( cff, bchar ); - achar_index = cff_lookup_glyph_by_stdcharcode( cff, achar ); - } - - if ( bchar_index < 0 || achar_index < 0 ) - { - FT_ERROR(( "cff_operator_seac:" - " invalid seac character code arguments\n" )); - return FT_THROW( Syntax_Error ); - } - - /* If we are trying to load a composite glyph, do not load the */ - /* accent character and return the array of subglyphs. */ - if ( builder->no_recurse ) - { - FT_GlyphSlot glyph = (FT_GlyphSlot)builder->glyph; - FT_GlyphLoader loader = glyph->internal->loader; - FT_SubGlyph subg; - - - /* reallocate subglyph array if necessary */ - error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 ); - if ( error ) - goto Exit; - - subg = loader->current.subglyphs; - - /* subglyph 0 = base character */ - subg->index = bchar_index; - subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES | - FT_SUBGLYPH_FLAG_USE_MY_METRICS; - subg->arg1 = 0; - subg->arg2 = 0; - subg++; - - /* subglyph 1 = accent character */ - subg->index = achar_index; - subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; - subg->arg1 = (FT_Int)( adx >> 16 ); - subg->arg2 = (FT_Int)( ady >> 16 ); - - /* set up remaining glyph fields */ - glyph->num_subglyphs = 2; - glyph->subglyphs = loader->base.subglyphs; - glyph->format = FT_GLYPH_FORMAT_COMPOSITE; - - loader->current.num_subglyphs = 2; - } - - FT_GlyphLoader_Prepare( builder->loader ); - - /* First load `bchar' in builder */ - error = cff_get_glyph_data( face, (FT_UInt)bchar_index, - &charstring, &charstring_len ); - if ( !error ) - { - /* the seac operator must not be nested */ - decoder->seac = TRUE; - error = cff_decoder_parse_charstrings( decoder, charstring, - charstring_len ); - decoder->seac = FALSE; - - cff_free_glyph_data( face, &charstring, charstring_len ); - - if ( error ) - goto Exit; - } - - /* Save the left bearing, advance and glyph width of the base */ - /* character as they will be erased by the next load. */ - - left_bearing = builder->left_bearing; - advance = builder->advance; - glyph_width = decoder->glyph_width; - - builder->left_bearing.x = 0; - builder->left_bearing.y = 0; - - builder->pos_x = adx - asb; - builder->pos_y = ady; - - /* Now load `achar' on top of the base outline. */ - error = cff_get_glyph_data( face, (FT_UInt)achar_index, - &charstring, &charstring_len ); - if ( !error ) - { - /* the seac operator must not be nested */ - decoder->seac = TRUE; - error = cff_decoder_parse_charstrings( decoder, charstring, - charstring_len ); - decoder->seac = FALSE; - - cff_free_glyph_data( face, &charstring, charstring_len ); - - if ( error ) - goto Exit; - } - - /* Restore the left side bearing, advance and glyph width */ - /* of the base character. */ - builder->left_bearing = left_bearing; - builder->advance = advance; - decoder->glyph_width = glyph_width; - - builder->pos_x = 0; - builder->pos_y = 0; - - Exit: - return error; - } - - - /*************************************************************************/ - /* */ - /* <Function> */ - /* cff_decoder_parse_charstrings */ - /* */ - /* <Description> */ - /* Parses a given Type 2 charstrings program. */ - /* */ - /* <InOut> */ - /* decoder :: The current Type 1 decoder. */ - /* */ - /* <Input> */ - /* charstring_base :: The base of the charstring stream. */ - /* */ - /* charstring_len :: The length in bytes of the charstring stream. */ - /* */ - /* <Return> */ - /* FreeType error code. 0 means success. */ - /* */ - FT_LOCAL_DEF( FT_Error ) - cff_decoder_parse_charstrings( CFF_Decoder* decoder, - FT_Byte* charstring_base, - FT_ULong charstring_len ) - { - FT_Error error; - CFF_Decoder_Zone* zone; - FT_Byte* ip; - FT_Byte* limit; - CFF_Builder* builder = &decoder->builder; - FT_Pos x, y; - FT_Fixed seed; - FT_Fixed* stack; - FT_Int charstring_type = - decoder->cff->top_font.font_dict.charstring_type; - - T2_Hints_Funcs hinter; - - - /* set default width */ - decoder->num_hints = 0; - decoder->read_width = 1; - - /* compute random seed from stack address of parameter */ - seed = (FT_Fixed)( ( (FT_Offset)(char*)&seed ^ - (FT_Offset)(char*)&decoder ^ - (FT_Offset)(char*)&charstring_base ) & - FT_ULONG_MAX ); - seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL; - if ( seed == 0 ) - seed = 0x7384; - - /* initialize the decoder */ - decoder->top = decoder->stack; - decoder->zone = decoder->zones; - zone = decoder->zones; - stack = decoder->top; - - hinter = (T2_Hints_Funcs)builder->hints_funcs; - - builder->path_begun = 0; - - zone->base = charstring_base; - limit = zone->limit = charstring_base + charstring_len; - ip = zone->cursor = zone->base; - - error = FT_Err_Ok; - - x = builder->pos_x; - y = builder->pos_y; - - /* begin hints recording session, if any */ - if ( hinter ) - hinter->open( hinter->hints ); - - /* now execute loop */ - while ( ip < limit ) - { - CFF_Operator op; - FT_Byte v; - - - /********************************************************************/ - /* */ - /* Decode operator or operand */ - /* */ - v = *ip++; - if ( v >= 32 || v == 28 ) - { - FT_Int shift = 16; - FT_Int32 val; - - - /* this is an operand, push it on the stack */ - - /* if we use shifts, all computations are done with unsigned */ - /* values; the conversion to a signed value is the last step */ - if ( v == 28 ) - { - if ( ip + 1 >= limit ) - goto Syntax_Error; - val = (FT_Short)( ( (FT_UShort)ip[0] << 8 ) | ip[1] ); - ip += 2; - } - else if ( v < 247 ) - val = (FT_Int32)v - 139; - else if ( v < 251 ) - { - if ( ip >= limit ) - goto Syntax_Error; - val = ( (FT_Int32)v - 247 ) * 256 + *ip++ + 108; - } - else if ( v < 255 ) - { - if ( ip >= limit ) - goto Syntax_Error; - val = -( (FT_Int32)v - 251 ) * 256 - *ip++ - 108; - } - else - { - if ( ip + 3 >= limit ) - goto Syntax_Error; - val = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) | - ( (FT_UInt32)ip[1] << 16 ) | - ( (FT_UInt32)ip[2] << 8 ) | - (FT_UInt32)ip[3] ); - ip += 4; - if ( charstring_type == 2 ) - shift = 0; - } - if ( decoder->top - stack >= CFF_MAX_OPERANDS ) - goto Stack_Overflow; - - val = (FT_Int32)( (FT_UInt32)val << shift ); - *decoder->top++ = val; - -#ifdef FT_DEBUG_LEVEL_TRACE - if ( !( val & 0xFFFFL ) ) - FT_TRACE4(( " %hd", (FT_Short)( (FT_UInt32)val >> 16 ) )); - else - FT_TRACE4(( " %.2f", val / 65536.0 )); -#endif - - } - else - { - /* The specification says that normally arguments are to be taken */ - /* from the bottom of the stack. However, this seems not to be */ - /* correct, at least for Acroread 7.0.8 on GNU/Linux: It pops the */ - /* arguments similar to a PS interpreter. */ - - FT_Fixed* args = decoder->top; - FT_Int num_args = (FT_Int)( args - decoder->stack ); - FT_Int req_args; - - - /* find operator */ - op = cff_op_unknown; - - switch ( v ) - { - case 1: - op = cff_op_hstem; - break; - case 3: - op = cff_op_vstem; - break; - case 4: - op = cff_op_vmoveto; - break; - case 5: - op = cff_op_rlineto; - break; - case 6: - op = cff_op_hlineto; - break; - case 7: - op = cff_op_vlineto; - break; - case 8: - op = cff_op_rrcurveto; - break; - case 9: - op = cff_op_closepath; - break; - case 10: - op = cff_op_callsubr; - break; - case 11: - op = cff_op_return; - break; - case 12: - { - if ( ip >= limit ) - goto Syntax_Error; - v = *ip++; - - switch ( v ) - { - case 0: - op = cff_op_dotsection; - break; - case 1: /* this is actually the Type1 vstem3 operator */ - op = cff_op_vstem; - break; - case 2: /* this is actually the Type1 hstem3 operator */ - op = cff_op_hstem; - break; - case 3: - op = cff_op_and; - break; - case 4: - op = cff_op_or; - break; - case 5: - op = cff_op_not; - break; - case 6: - op = cff_op_seac; - break; - case 7: - op = cff_op_sbw; - break; - case 8: - op = cff_op_store; - break; - case 9: - op = cff_op_abs; - break; - case 10: - op = cff_op_add; - break; - case 11: - op = cff_op_sub; - break; - case 12: - op = cff_op_div; - break; - case 13: - op = cff_op_load; - break; - case 14: - op = cff_op_neg; - break; - case 15: - op = cff_op_eq; - break; - case 16: - op = cff_op_callothersubr; - break; - case 17: - op = cff_op_pop; - break; - case 18: - op = cff_op_drop; - break; - case 20: - op = cff_op_put; - break; - case 21: - op = cff_op_get; - break; - case 22: - op = cff_op_ifelse; - break; - case 23: - op = cff_op_random; - break; - case 24: - op = cff_op_mul; - break; - case 26: - op = cff_op_sqrt; - break; - case 27: - op = cff_op_dup; - break; - case 28: - op = cff_op_exch; - break; - case 29: - op = cff_op_index; - break; - case 30: - op = cff_op_roll; - break; - case 33: - op = cff_op_setcurrentpoint; - break; - case 34: - op = cff_op_hflex; - break; - case 35: - op = cff_op_flex; - break; - case 36: - op = cff_op_hflex1; - break; - case 37: - op = cff_op_flex1; - break; - default: - FT_TRACE4(( " unknown op (12, %d)\n", v )); - break; - } - } - break; - case 13: - op = cff_op_hsbw; - break; - case 14: - op = cff_op_endchar; - break; - case 16: - op = cff_op_blend; - break; - case 18: - op = cff_op_hstemhm; - break; - case 19: - op = cff_op_hintmask; - break; - case 20: - op = cff_op_cntrmask; - break; - case 21: - op = cff_op_rmoveto; - break; - case 22: - op = cff_op_hmoveto; - break; - case 23: - op = cff_op_vstemhm; - break; - case 24: - op = cff_op_rcurveline; - break; - case 25: - op = cff_op_rlinecurve; - break; - case 26: - op = cff_op_vvcurveto; - break; - case 27: - op = cff_op_hhcurveto; - break; - case 29: - op = cff_op_callgsubr; - break; - case 30: - op = cff_op_vhcurveto; - break; - case 31: - op = cff_op_hvcurveto; - break; - default: - FT_TRACE4(( " unknown op (%d)\n", v )); - break; - } - - if ( op == cff_op_unknown ) - continue; - - /* check arguments */ - req_args = cff_argument_counts[op]; - if ( req_args & CFF_COUNT_CHECK_WIDTH ) - { - if ( num_args > 0 && decoder->read_width ) - { - /* If `nominal_width' is non-zero, the number is really a */ - /* difference against `nominal_width'. Else, the number here */ - /* is truly a width, not a difference against `nominal_width'. */ - /* If the font does not set `nominal_width', then */ - /* `nominal_width' defaults to zero, and so we can set */ - /* `glyph_width' to `nominal_width' plus number on the stack */ - /* -- for either case. */ - - FT_Int set_width_ok; - - - switch ( op ) - { - case cff_op_hmoveto: - case cff_op_vmoveto: - set_width_ok = num_args & 2; - break; - - case cff_op_hstem: - case cff_op_vstem: - case cff_op_hstemhm: - case cff_op_vstemhm: - case cff_op_rmoveto: - case cff_op_hintmask: - case cff_op_cntrmask: - set_width_ok = num_args & 1; - break; - - case cff_op_endchar: - /* If there is a width specified for endchar, we either have */ - /* 1 argument or 5 arguments. We like to argue. */ - set_width_ok = ( num_args == 5 ) || ( num_args == 1 ); - break; - - default: - set_width_ok = 0; - break; - } - - if ( set_width_ok ) - { - decoder->glyph_width = decoder->nominal_width + - ( stack[0] >> 16 ); - - if ( decoder->width_only ) - { - /* we only want the advance width; stop here */ - break; - } - - /* Consumed an argument. */ - num_args--; - } - } - - decoder->read_width = 0; - req_args = 0; - } - - req_args &= 0x000F; - if ( num_args < req_args ) - goto Stack_Underflow; - args -= req_args; - num_args -= req_args; - - /* At this point, `args' points to the first argument of the */ - /* operand in case `req_args' isn't zero. Otherwise, we have */ - /* to adjust `args' manually. */ - - /* Note that we only pop arguments from the stack which we */ - /* really need and can digest so that we can continue in case */ - /* of superfluous stack elements. */ - - switch ( op ) - { - case cff_op_hstem: - case cff_op_vstem: - case cff_op_hstemhm: - case cff_op_vstemhm: - /* the number of arguments is always even here */ - FT_TRACE4(( - op == cff_op_hstem ? " hstem\n" : - ( op == cff_op_vstem ? " vstem\n" : - ( op == cff_op_hstemhm ? " hstemhm\n" : " vstemhm\n" ) ) )); - - if ( hinter ) - hinter->stems( hinter->hints, - ( op == cff_op_hstem || op == cff_op_hstemhm ), - num_args / 2, - args - ( num_args & ~1 ) ); - - decoder->num_hints += num_args / 2; - args = stack; - break; - - case cff_op_hintmask: - case cff_op_cntrmask: - FT_TRACE4(( op == cff_op_hintmask ? " hintmask" : " cntrmask" )); - - /* implement vstem when needed -- */ - /* the specification doesn't say it, but this also works */ - /* with the 'cntrmask' operator */ - /* */ - if ( num_args > 0 ) - { - if ( hinter ) - hinter->stems( hinter->hints, - 0, - num_args / 2, - args - ( num_args & ~1 ) ); - - decoder->num_hints += num_args / 2; - } - - /* In a valid charstring there must be at least one byte */ - /* after `hintmask' or `cntrmask' (e.g., for a `return' */ - /* instruction). Additionally, there must be space for */ - /* `num_hints' bits. */ - - if ( ( ip + ( ( decoder->num_hints + 7 ) >> 3 ) ) >= limit ) - goto Syntax_Error; - - if ( hinter ) - { - if ( op == cff_op_hintmask ) - hinter->hintmask( hinter->hints, - (FT_UInt)builder->current->n_points, - (FT_UInt)decoder->num_hints, - ip ); - else - hinter->counter( hinter->hints, - (FT_UInt)decoder->num_hints, - ip ); - } - -#ifdef FT_DEBUG_LEVEL_TRACE - { - FT_UInt maskbyte; - - - FT_TRACE4(( " (maskbytes:" )); - - for ( maskbyte = 0; - maskbyte < (FT_UInt)( ( decoder->num_hints + 7 ) >> 3 ); - maskbyte++, ip++ ) - FT_TRACE4(( " 0x%02X", *ip )); - - FT_TRACE4(( ")\n" )); - } -#else - ip += ( decoder->num_hints + 7 ) >> 3; -#endif - args = stack; - break; - - case cff_op_rmoveto: - FT_TRACE4(( " rmoveto\n" )); - - cff_builder_close_contour( builder ); - builder->path_begun = 0; - x += args[-2]; - y += args[-1]; - args = stack; - break; - - case cff_op_vmoveto: - FT_TRACE4(( " vmoveto\n" )); - - cff_builder_close_contour( builder ); - builder->path_begun = 0; - y += args[-1]; - args = stack; - break; - - case cff_op_hmoveto: - FT_TRACE4(( " hmoveto\n" )); - - cff_builder_close_contour( builder ); - builder->path_begun = 0; - x += args[-1]; - args = stack; - break; - - case cff_op_rlineto: - FT_TRACE4(( " rlineto\n" )); - - if ( cff_builder_start_point( builder, x, y ) || - cff_check_points( builder, num_args / 2 ) ) - goto Fail; - - if ( num_args < 2 ) - goto Stack_Underflow; - - args -= num_args & ~1; - while ( args < decoder->top ) - { - x += args[0]; - y += args[1]; - cff_builder_add_point( builder, x, y, 1 ); - args += 2; - } - args = stack; - break; - - case cff_op_hlineto: - case cff_op_vlineto: - { - FT_Int phase = ( op == cff_op_hlineto ); - - - FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n" - : " vlineto\n" )); - - if ( num_args < 0 ) - goto Stack_Underflow; - - /* there exist subsetted fonts (found in PDFs) */ - /* which call `hlineto' without arguments */ - if ( num_args == 0 ) - break; - - if ( cff_builder_start_point( builder, x, y ) || - cff_check_points( builder, num_args ) ) - goto Fail; - - args = stack; - while ( args < decoder->top ) - { - if ( phase ) - x += args[0]; - else - y += args[0]; - - if ( cff_builder_add_point1( builder, x, y ) ) - goto Fail; - - args++; - phase ^= 1; - } - args = stack; - } - break; - - case cff_op_rrcurveto: - { - FT_Int nargs; - - - FT_TRACE4(( " rrcurveto\n" )); - - if ( num_args < 6 ) - goto Stack_Underflow; - - nargs = num_args - num_args % 6; - - if ( cff_builder_start_point( builder, x, y ) || - cff_check_points( builder, nargs / 2 ) ) - goto Fail; - - args -= nargs; - while ( args < decoder->top ) - { - x += args[0]; - y += args[1]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[2]; - y += args[3]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[4]; - y += args[5]; - cff_builder_add_point( builder, x, y, 1 ); - args += 6; - } - args = stack; - } - break; - - case cff_op_vvcurveto: - { - FT_Int nargs; - - - FT_TRACE4(( " vvcurveto\n" )); - - if ( num_args < 4 ) - goto Stack_Underflow; - - /* if num_args isn't of the form 4n or 4n+1, */ - /* we enforce it by clearing the second bit */ - - nargs = num_args & ~2; - - if ( cff_builder_start_point( builder, x, y ) ) - goto Fail; - - args -= nargs; - - if ( nargs & 1 ) - { - x += args[0]; - args++; - nargs--; - } - - if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) ) - goto Fail; - - while ( args < decoder->top ) - { - y += args[0]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[1]; - y += args[2]; - cff_builder_add_point( builder, x, y, 0 ); - y += args[3]; - cff_builder_add_point( builder, x, y, 1 ); - args += 4; - } - args = stack; - } - break; - - case cff_op_hhcurveto: - { - FT_Int nargs; - - - FT_TRACE4(( " hhcurveto\n" )); - - if ( num_args < 4 ) - goto Stack_Underflow; - - /* if num_args isn't of the form 4n or 4n+1, */ - /* we enforce it by clearing the second bit */ - - nargs = num_args & ~2; - - if ( cff_builder_start_point( builder, x, y ) ) - goto Fail; - - args -= nargs; - if ( nargs & 1 ) - { - y += args[0]; - args++; - nargs--; - } - - if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) ) - goto Fail; - - while ( args < decoder->top ) - { - x += args[0]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[1]; - y += args[2]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[3]; - cff_builder_add_point( builder, x, y, 1 ); - args += 4; - } - args = stack; - } - break; - - case cff_op_vhcurveto: - case cff_op_hvcurveto: - { - FT_Int phase; - FT_Int nargs; - - - FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto\n" - : " hvcurveto\n" )); - - if ( cff_builder_start_point( builder, x, y ) ) - goto Fail; - - if ( num_args < 4 ) - goto Stack_Underflow; - - /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */ - /* we enforce it by clearing the second bit */ - - nargs = num_args & ~2; - - args -= nargs; - if ( cff_check_points( builder, ( nargs / 4 ) * 3 ) ) - goto Stack_Underflow; - - phase = ( op == cff_op_hvcurveto ); - - while ( nargs >= 4 ) - { - nargs -= 4; - if ( phase ) - { - x += args[0]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[1]; - y += args[2]; - cff_builder_add_point( builder, x, y, 0 ); - y += args[3]; - if ( nargs == 1 ) - x += args[4]; - cff_builder_add_point( builder, x, y, 1 ); - } - else - { - y += args[0]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[1]; - y += args[2]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[3]; - if ( nargs == 1 ) - y += args[4]; - cff_builder_add_point( builder, x, y, 1 ); - } - args += 4; - phase ^= 1; - } - args = stack; - } - break; - - case cff_op_rlinecurve: - { - FT_Int num_lines; - FT_Int nargs; - - - FT_TRACE4(( " rlinecurve\n" )); - - if ( num_args < 8 ) - goto Stack_Underflow; - - nargs = num_args & ~1; - num_lines = ( nargs - 6 ) / 2; - - if ( cff_builder_start_point( builder, x, y ) || - cff_check_points( builder, num_lines + 3 ) ) - goto Fail; - - args -= nargs; - - /* first, add the line segments */ - while ( num_lines > 0 ) - { - x += args[0]; - y += args[1]; - cff_builder_add_point( builder, x, y, 1 ); - args += 2; - num_lines--; - } - - /* then the curve */ - x += args[0]; - y += args[1]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[2]; - y += args[3]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[4]; - y += args[5]; - cff_builder_add_point( builder, x, y, 1 ); - args = stack; - } - break; - - case cff_op_rcurveline: - { - FT_Int num_curves; - FT_Int nargs; - - - FT_TRACE4(( " rcurveline\n" )); - - if ( num_args < 8 ) - goto Stack_Underflow; - - nargs = num_args - 2; - nargs = nargs - nargs % 6 + 2; - num_curves = ( nargs - 2 ) / 6; - - if ( cff_builder_start_point( builder, x, y ) || - cff_check_points( builder, num_curves * 3 + 2 ) ) - goto Fail; - - args -= nargs; - - /* first, add the curves */ - while ( num_curves > 0 ) - { - x += args[0]; - y += args[1]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[2]; - y += args[3]; - cff_builder_add_point( builder, x, y, 0 ); - x += args[4]; - y += args[5]; - cff_builder_add_point( builder, x, y, 1 ); - args += 6; - num_curves--; - } - - /* then the final line */ - x += args[0]; - y += args[1]; - cff_builder_add_point( builder, x, y, 1 ); - args = stack; - } - break; - - case cff_op_hflex1: - { - FT_Pos start_y; - - - FT_TRACE4(( " hflex1\n" )); - - /* adding five more points: 4 control points, 1 on-curve point */ - /* -- make sure we have enough space for the start point if it */ - /* needs to be added */ - if ( cff_builder_start_point( builder, x, y ) || - cff_check_points( builder, 6 ) ) - goto Fail; - - /* record the starting point's y position for later use */ - start_y = y; - - /* first control point */ - x += args[0]; - y += args[1]; - cff_builder_add_point( builder, x, y, 0 ); - - /* second control point */ - x += args[2]; - y += args[3]; - cff_builder_add_point( builder, x, y, 0 ); - - /* join point; on curve, with y-value the same as the last */ - /* control point's y-value */ - x += args[4]; - cff_builder_add_point( builder, x, y, 1 ); - - /* third control point, with y-value the same as the join */ - /* point's y-value */ - x += args[5]; - cff_builder_add_point( builder, x, y, 0 ); - - /* fourth control point */ - x += args[6]; - y += args[7]; - cff_builder_add_point( builder, x, y, 0 ); - - /* ending point, with y-value the same as the start */ - x += args[8]; - y = start_y; - cff_builder_add_point( builder, x, y, 1 ); - - args = stack; - break; - } - - case cff_op_hflex: - { - FT_Pos start_y; - - - FT_TRACE4(( " hflex\n" )); - - /* adding six more points; 4 control points, 2 on-curve points */ - if ( cff_builder_start_point( builder, x, y ) || - cff_check_points( builder, 6 ) ) - goto Fail; - - /* record the starting point's y-position for later use */ - start_y = y; - - /* first control point */ - x += args[0]; - cff_builder_add_point( builder, x, y, 0 ); - - /* second control point */ - x += args[1]; - y += args[2]; - cff_builder_add_point( builder, x, y, 0 ); - - /* join point; on curve, with y-value the same as the last */ - /* control point's y-value */ - x += args[3]; - cff_builder_add_point( builder, x, y, 1 ); - - /* third control point, with y-value the same as the join */ - /* point's y-value */ - x += args[4]; - cff_builder_add_point( builder, x, y, 0 ); - - /* fourth control point */ - x += args[5]; - y = start_y; - cff_builder_add_point( builder, x, y, 0 ); - - /* ending point, with y-value the same as the start point's */ - /* y-value -- we don't add this point, though */ - x += args[6]; - cff_builder_add_point( builder, x, y, 1 ); - - args = stack; - break; - } - - case cff_op_flex1: - { - FT_Pos start_x, start_y; /* record start x, y values for */ - /* alter use */ - FT_Fixed dx = 0, dy = 0; /* used in horizontal/vertical */ - /* algorithm below */ - FT_Int horizontal, count; - FT_Fixed* temp; - - - FT_TRACE4(( " flex1\n" )); - - /* adding six more points; 4 control points, 2 on-curve points */ - if ( cff_builder_start_point( builder, x, y ) || - cff_check_points( builder, 6 ) ) - goto Fail; - - /* record the starting point's x, y position for later use */ - start_x = x; - start_y = y; - - /* XXX: figure out whether this is supposed to be a horizontal */ - /* or vertical flex; the Type 2 specification is vague... */ - - temp = args; - - /* grab up to the last argument */ - for ( count = 5; count > 0; count-- ) - { - dx += temp[0]; - dy += temp[1]; - temp += 2; - } - - if ( dx < 0 ) - dx = -dx; - if ( dy < 0 ) - dy = -dy; - - /* strange test, but here it is... */ - horizontal = ( dx > dy ); - - for ( count = 5; count > 0; count-- ) - { - x += args[0]; - y += args[1]; - cff_builder_add_point( builder, x, y, - (FT_Bool)( count == 3 ) ); - args += 2; - } - - /* is last operand an x- or y-delta? */ - if ( horizontal ) - { - x += args[0]; - y = start_y; - } - else - { - x = start_x; - y += args[0]; - } - - cff_builder_add_point( builder, x, y, 1 ); - - args = stack; - break; - } - - case cff_op_flex: - { - FT_UInt count; - - - FT_TRACE4(( " flex\n" )); - - if ( cff_builder_start_point( builder, x, y ) || - cff_check_points( builder, 6 ) ) - goto Fail; - - for ( count = 6; count > 0; count-- ) - { - x += args[0]; - y += args[1]; - cff_builder_add_point( builder, x, y, - (FT_Bool)( count == 4 || count == 1 ) ); - args += 2; - } - - args = stack; - } - break; - - case cff_op_seac: - FT_TRACE4(( " seac\n" )); - - error = cff_operator_seac( decoder, - args[0], args[1], args[2], - (FT_Int)( args[3] >> 16 ), - (FT_Int)( args[4] >> 16 ) ); - - /* add current outline to the glyph slot */ - FT_GlyphLoader_Add( builder->loader ); - - /* return now! */ - FT_TRACE4(( "\n" )); - return error; - - case cff_op_endchar: - FT_TRACE4(( " endchar\n" )); - - /* We are going to emulate the seac operator. */ - if ( num_args >= 4 ) - { - /* Save glyph width so that the subglyphs don't overwrite it. */ - FT_Pos glyph_width = decoder->glyph_width; - - - error = cff_operator_seac( decoder, - 0L, args[-4], args[-3], - (FT_Int)( args[-2] >> 16 ), - (FT_Int)( args[-1] >> 16 ) ); - - decoder->glyph_width = glyph_width; - } - else - { - cff_builder_close_contour( builder ); - - /* close hints recording session */ - if ( hinter ) - { - if ( hinter->close( hinter->hints, - (FT_UInt)builder->current->n_points ) ) - goto Syntax_Error; - - /* apply hints to the loaded glyph outline now */ - error = hinter->apply( hinter->hints, - builder->current, - (PSH_Globals)builder->hints_globals, - decoder->hint_mode ); - if ( error ) - goto Fail; - } - - /* add current outline to the glyph slot */ - FT_GlyphLoader_Add( builder->loader ); - } - - /* return now! */ - FT_TRACE4(( "\n" )); - return error; - - case cff_op_abs: - FT_TRACE4(( " abs\n" )); - - if ( args[0] < 0 ) - args[0] = -args[0]; - args++; - break; - - case cff_op_add: - FT_TRACE4(( " add\n" )); - - args[0] += args[1]; - args++; - break; - - case cff_op_sub: - FT_TRACE4(( " sub\n" )); - - args[0] -= args[1]; - args++; - break; - - case cff_op_div: - FT_TRACE4(( " div\n" )); - - args[0] = FT_DivFix( args[0], args[1] ); - args++; - break; - - case cff_op_neg: - FT_TRACE4(( " neg\n" )); - - args[0] = -args[0]; - args++; - break; - - case cff_op_random: - { - FT_Fixed Rand; - - - FT_TRACE4(( " rand\n" )); - - Rand = seed; - if ( Rand >= 0x8000L ) - Rand++; - - args[0] = Rand; - seed = FT_MulFix( seed, 0x10000L - seed ); - if ( seed == 0 ) - seed += 0x2873; - args++; - } - break; - - case cff_op_mul: - FT_TRACE4(( " mul\n" )); - - args[0] = FT_MulFix( args[0], args[1] ); - args++; - break; - - case cff_op_sqrt: - FT_TRACE4(( " sqrt\n" )); - - if ( args[0] > 0 ) - { - FT_Int count = 9; - FT_Fixed root = args[0]; - FT_Fixed new_root; - - - for (;;) - { - new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1; - if ( new_root == root || count <= 0 ) - break; - root = new_root; - } - args[0] = new_root; - } - else - args[0] = 0; - args++; - break; - - case cff_op_drop: - /* nothing */ - FT_TRACE4(( " drop\n" )); - - break; - - case cff_op_exch: - { - FT_Fixed tmp; - - - FT_TRACE4(( " exch\n" )); - - tmp = args[0]; - args[0] = args[1]; - args[1] = tmp; - args += 2; - } - break; - - case cff_op_index: - { - FT_Int idx = (FT_Int)( args[0] >> 16 ); - - - FT_TRACE4(( " index\n" )); - - if ( idx < 0 ) - idx = 0; - else if ( idx > num_args - 2 ) - idx = num_args - 2; - args[0] = args[-( idx + 1 )]; - args++; - } - break; - - case cff_op_roll: - { - FT_Int count = (FT_Int)( args[0] >> 16 ); - FT_Int idx = (FT_Int)( args[1] >> 16 ); - - - FT_TRACE4(( " roll\n" )); - - if ( count <= 0 ) - count = 1; - - args -= count; - if ( args < stack ) - goto Stack_Underflow; - - if ( idx >= 0 ) - { - while ( idx > 0 ) - { - FT_Fixed tmp = args[count - 1]; - FT_Int i; - - - for ( i = count - 2; i >= 0; i-- ) - args[i + 1] = args[i]; - args[0] = tmp; - idx--; - } - } - else - { - while ( idx < 0 ) - { - FT_Fixed tmp = args[0]; - FT_Int i; - - - for ( i = 0; i < count - 1; i++ ) - args[i] = args[i + 1]; - args[count - 1] = tmp; - idx++; - } - } - args += count; - } - break; - - case cff_op_dup: - FT_TRACE4(( " dup\n" )); - - args[1] = args[0]; - args += 2; - break; - - case cff_op_put: - { - FT_Fixed val = args[0]; - FT_Int idx = (FT_Int)( args[1] >> 16 ); - - - FT_TRACE4(( " put\n" )); - - if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS ) - decoder->buildchar[idx] = val; - } - break; - - case cff_op_get: - { - FT_Int idx = (FT_Int)( args[0] >> 16 ); - FT_Fixed val = 0; - - - FT_TRACE4(( " get\n" )); - - if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS ) - val = decoder->buildchar[idx]; - - args[0] = val; - args++; - } - break; - - case cff_op_store: - FT_TRACE4(( " store\n")); - - goto Unimplemented; - - case cff_op_load: - FT_TRACE4(( " load\n" )); - - goto Unimplemented; - - case cff_op_dotsection: - /* this operator is deprecated and ignored by the parser */ - FT_TRACE4(( " dotsection\n" )); - break; - - case cff_op_closepath: - /* this is an invalid Type 2 operator; however, there */ - /* exist fonts which are incorrectly converted from probably */ - /* Type 1 to CFF, and some parsers seem to accept it */ - - FT_TRACE4(( " closepath (invalid op)\n" )); - - args = stack; - break; - - case cff_op_hsbw: - /* this is an invalid Type 2 operator; however, there */ - /* exist fonts which are incorrectly converted from probably */ - /* Type 1 to CFF, and some parsers seem to accept it */ - - FT_TRACE4(( " hsbw (invalid op)\n" )); - - decoder->glyph_width = decoder->nominal_width + ( args[1] >> 16 ); - - decoder->builder.left_bearing.x = args[0]; - decoder->builder.left_bearing.y = 0; - - x = decoder->builder.pos_x + args[0]; - y = decoder->builder.pos_y; - args = stack; - break; - - case cff_op_sbw: - /* this is an invalid Type 2 operator; however, there */ - /* exist fonts which are incorrectly converted from probably */ - /* Type 1 to CFF, and some parsers seem to accept it */ - - FT_TRACE4(( " sbw (invalid op)\n" )); - - decoder->glyph_width = decoder->nominal_width + ( args[2] >> 16 ); - - decoder->builder.left_bearing.x = args[0]; - decoder->builder.left_bearing.y = args[1]; - - x = decoder->builder.pos_x + args[0]; - y = decoder->builder.pos_y + args[1]; - args = stack; - break; - - case cff_op_setcurrentpoint: - /* this is an invalid Type 2 operator; however, there */ - /* exist fonts which are incorrectly converted from probably */ - /* Type 1 to CFF, and some parsers seem to accept it */ - - FT_TRACE4(( " setcurrentpoint (invalid op)\n" )); - - x = decoder->builder.pos_x + args[0]; - y = decoder->builder.pos_y + args[1]; - args = stack; - break; - - case cff_op_callothersubr: - /* this is an invalid Type 2 operator; however, there */ - /* exist fonts which are incorrectly converted from probably */ - /* Type 1 to CFF, and some parsers seem to accept it */ - - FT_TRACE4(( " callothersubr (invalid op)\n" )); - - /* subsequent `pop' operands should add the arguments, */ - /* this is the implementation described for `unknown' other */ - /* subroutines in the Type1 spec. */ - /* */ - /* XXX Fix return arguments (see discussion below). */ - args -= 2 + ( args[-2] >> 16 ); - if ( args < stack ) - goto Stack_Underflow; - break; - - case cff_op_pop: - /* this is an invalid Type 2 operator; however, there */ - /* exist fonts which are incorrectly converted from probably */ - /* Type 1 to CFF, and some parsers seem to accept it */ - - FT_TRACE4(( " pop (invalid op)\n" )); - - /* XXX Increasing `args' is wrong: After a certain number of */ - /* `pop's we get a stack overflow. Reason for doing it is */ - /* code like this (actually found in a CFF font): */ - /* */ - /* 17 1 3 callothersubr */ - /* pop */ - /* callsubr */ - /* */ - /* Since we handle `callothersubr' as a no-op, and */ - /* `callsubr' needs at least one argument, `pop' can't be a */ - /* no-op too as it basically should be. */ - /* */ - /* The right solution would be to provide real support for */ - /* `callothersubr' as done in `t1decode.c', however, given */ - /* the fact that CFF fonts with `pop' are invalid, it is */ - /* questionable whether it is worth the time. */ - args++; - break; - - case cff_op_and: - { - FT_Fixed cond = args[0] && args[1]; - - - FT_TRACE4(( " and\n" )); - - args[0] = cond ? 0x10000L : 0; - args++; - } - break; - - case cff_op_or: - { - FT_Fixed cond = args[0] || args[1]; - - - FT_TRACE4(( " or\n" )); - - args[0] = cond ? 0x10000L : 0; - args++; - } - break; - - case cff_op_eq: - { - FT_Fixed cond = !args[0]; - - - FT_TRACE4(( " eq\n" )); - - args[0] = cond ? 0x10000L : 0; - args++; - } - break; - - case cff_op_ifelse: - { - FT_Fixed cond = ( args[2] <= args[3] ); - - - FT_TRACE4(( " ifelse\n" )); - - if ( !cond ) - args[0] = args[1]; - args++; - } - break; - - case cff_op_callsubr: - { - FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) + - decoder->locals_bias ); - - - FT_TRACE4(( " callsubr (idx %d, entering level %d)\n", - idx, - zone - decoder->zones + 1 )); - - if ( idx >= decoder->num_locals ) - { - FT_ERROR(( "cff_decoder_parse_charstrings:" - " invalid local subr index\n" )); - goto Syntax_Error; - } - - if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS ) - { - FT_ERROR(( "cff_decoder_parse_charstrings:" - " too many nested subrs\n" )); - goto Syntax_Error; - } - - zone->cursor = ip; /* save current instruction pointer */ - - zone++; - zone->base = decoder->locals[idx]; - zone->limit = decoder->locals[idx + 1]; - zone->cursor = zone->base; - - if ( !zone->base || zone->limit == zone->base ) - { - FT_ERROR(( "cff_decoder_parse_charstrings:" - " invoking empty subrs\n" )); - goto Syntax_Error; - } - - decoder->zone = zone; - ip = zone->base; - limit = zone->limit; - } - break; - - case cff_op_callgsubr: - { - FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) + - decoder->globals_bias ); - - - FT_TRACE4(( " callgsubr (idx %d, entering level %d)\n", - idx, - zone - decoder->zones + 1 )); - - if ( idx >= decoder->num_globals ) - { - FT_ERROR(( "cff_decoder_parse_charstrings:" - " invalid global subr index\n" )); - goto Syntax_Error; - } - - if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS ) - { - FT_ERROR(( "cff_decoder_parse_charstrings:" - " too many nested subrs\n" )); - goto Syntax_Error; - } - - zone->cursor = ip; /* save current instruction pointer */ - - zone++; - zone->base = decoder->globals[idx]; - zone->limit = decoder->globals[idx + 1]; - zone->cursor = zone->base; - - if ( !zone->base || zone->limit == zone->base ) - { - FT_ERROR(( "cff_decoder_parse_charstrings:" - " invoking empty subrs\n" )); - goto Syntax_Error; - } - - decoder->zone = zone; - ip = zone->base; - limit = zone->limit; - } - break; - - case cff_op_return: - FT_TRACE4(( " return (leaving level %d)\n", - decoder->zone - decoder->zones )); - - if ( decoder->zone <= decoder->zones ) - { - FT_ERROR(( "cff_decoder_parse_charstrings:" - " unexpected return\n" )); - goto Syntax_Error; - } - - decoder->zone--; - zone = decoder->zone; - ip = zone->cursor; - limit = zone->limit; - break; - - default: - Unimplemented: - FT_ERROR(( "Unimplemented opcode: %d", ip[-1] )); - - if ( ip[-1] == 12 ) - FT_ERROR(( " %d", ip[0] )); - FT_ERROR(( "\n" )); - - return FT_THROW( Unimplemented_Feature ); - } - - decoder->top = args; - - if ( decoder->top - stack >= CFF_MAX_OPERANDS ) - goto Stack_Overflow; - - } /* general operator processing */ - - } /* while ip < limit */ - - FT_TRACE4(( "..end..\n\n" )); - - Fail: - return error; - - Syntax_Error: - FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" )); - return FT_THROW( Invalid_File_Format ); - - Stack_Underflow: - FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" )); - return FT_THROW( Too_Few_Arguments ); - - Stack_Overflow: - FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" )); - return FT_THROW( Stack_Overflow ); - } - -#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ - - /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ @@ -2559,11 +142,14 @@ FT_Int glyph_index; CFF_Font cff = (CFF_Font)face->other; + PSAux_Service psaux = (PSAux_Service)face->psaux; + const CFF_Decoder_Funcs decoder_funcs = psaux->cff_decoder_funcs; + *max_advance = 0; /* Initialize load decoder */ - cff_decoder_init( &decoder, face, 0, 0, 0, 0 ); + decoder_funcs->init( &decoder, face, 0, 0, 0, 0, 0, 0 ); decoder.builder.metrics_only = 1; decoder.builder.load_points = 0; @@ -2582,11 +168,12 @@ &charstring, &charstring_len ); if ( !error ) { - error = cff_decoder_prepare( &decoder, size, glyph_index ); + error = decoder_funcs->prepare( &decoder, size, glyph_index ); if ( !error ) - error = cff_decoder_parse_charstrings( &decoder, - charstring, - charstring_len ); + error = decoder_funcs->parse_charstrings_old( &decoder, + charstring, + charstring_len, + 0 ); cff_free_glyph_data( face, &charstring, &charstring_len ); } @@ -2612,10 +199,14 @@ { FT_Error error; CFF_Decoder decoder; + PS_Decoder psdecoder; TT_Face face = (TT_Face)glyph->root.face; FT_Bool hinting, scaled, force_scaling; CFF_Font cff = (CFF_Font)face->extra.data; + PSAux_Service psaux = (PSAux_Service)face->psaux; + const CFF_Decoder_Funcs decoder_funcs = psaux->cff_decoder_funcs; + FT_Matrix font_matrix; FT_Vector font_offset; @@ -2805,7 +396,7 @@ { #ifdef CFF_CONFIG_OPTION_OLD_ENGINE - CFF_Driver driver = (CFF_Driver)FT_FACE_DRIVER( face ); + PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( face ); #endif @@ -2813,9 +404,12 @@ FT_ULong charstring_len; - cff_decoder_init( &decoder, face, size, glyph, hinting, - FT_LOAD_TARGET_MODE( load_flags ) ); + decoder_funcs->init( &decoder, face, size, glyph, hinting, + FT_LOAD_TARGET_MODE( load_flags ), + cff_get_glyph_data, + cff_free_glyph_data ); + /* this is for pure CFFs */ if ( load_flags & FT_LOAD_ADVANCE_ONLY ) decoder.width_only = TRUE; @@ -2828,22 +422,25 @@ if ( error ) goto Glyph_Build_Finished; - error = cff_decoder_prepare( &decoder, size, glyph_index ); + error = decoder_funcs->prepare( &decoder, size, glyph_index ); if ( error ) goto Glyph_Build_Finished; #ifdef CFF_CONFIG_OPTION_OLD_ENGINE /* choose which CFF renderer to use */ - if ( driver->hinting_engine == FT_CFF_HINTING_FREETYPE ) - error = cff_decoder_parse_charstrings( &decoder, - charstring, - charstring_len ); + if ( driver->hinting_engine == FT_HINTING_FREETYPE ) + error = decoder_funcs->parse_charstrings_old( &decoder, + charstring, + charstring_len, + 0 ); else #endif { - error = cf2_decoder_parse_charstrings( &decoder, - charstring, - charstring_len ); + psaux->ps_decoder_init( &psdecoder, &decoder, FALSE ); + + error = decoder_funcs->parse_charstrings( &psdecoder, + charstring, + charstring_len ); /* Adobe's engine uses 16.16 numbers everywhere; */ /* as a consequence, glyphs larger than 2000ppem get rejected */ @@ -2856,9 +453,9 @@ force_scaling = TRUE; glyph->hint = hinting; - error = cf2_decoder_parse_charstrings( &decoder, - charstring, - charstring_len ); + error = decoder_funcs->parse_charstrings( &psdecoder, + charstring, + charstring_len ); } } @@ -2896,7 +493,7 @@ Glyph_Build_Finished: /* save new glyph tables, if no error */ if ( !error ) - cff_builder_done( &decoder.builder ); + decoder.builder.funcs.done( &decoder.builder ); /* XXX: anything to do for broken glyph entry? */ } diff --git a/src/3rdparty/freetype/src/cff/cffgload.h b/src/3rdparty/freetype/src/cff/cffgload.h index 5f2655f3d9..803f3974fc 100644 --- a/src/3rdparty/freetype/src/cff/cffgload.h +++ b/src/3rdparty/freetype/src/cff/cffgload.h @@ -4,7 +4,7 @@ /* */ /* OpenType Glyph Loader (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,125 +16,17 @@ /***************************************************************************/ -#ifndef __CFFGLOAD_H__ -#define __CFFGLOAD_H__ +#ifndef CFFGLOAD_H_ +#define CFFGLOAD_H_ #include <ft2build.h> #include FT_FREETYPE_H -#include "cffobjs.h" +#include FT_INTERNAL_CFF_OBJECTS_TYPES_H FT_BEGIN_HEADER - -#define CFF_MAX_OPERANDS 48 -#define CFF_MAX_SUBRS_CALLS 16 /* maximum subroutine nesting; */ - /* only 10 are allowed but there exist */ - /* fonts like `HiraKakuProN-W3.ttf' */ - /* (Hiragino Kaku Gothic ProN W3; */ - /* 8.2d6e1; 2014-12-19) that exceed */ - /* this limit */ -#define CFF_MAX_TRANS_ELEMENTS 32 - - - /*************************************************************************/ - /* */ - /* <Structure> */ - /* CFF_Builder */ - /* */ - /* <Description> */ - /* A structure used during glyph loading to store its outline. */ - /* */ - /* <Fields> */ - /* memory :: The current memory object. */ - /* */ - /* face :: The current face object. */ - /* */ - /* glyph :: The current glyph slot. */ - /* */ - /* loader :: The current glyph loader. */ - /* */ - /* base :: The base glyph outline. */ - /* */ - /* current :: The current glyph outline. */ - /* */ - /* pos_x :: The horizontal translation (if composite glyph). */ - /* */ - /* pos_y :: The vertical translation (if composite glyph). */ - /* */ - /* left_bearing :: The left side bearing point. */ - /* */ - /* advance :: The horizontal advance vector. */ - /* */ - /* bbox :: Unused. */ - /* */ - /* path_begun :: A flag which indicates that a new path has begun. */ - /* */ - /* load_points :: If this flag is not set, no points are loaded. */ - /* */ - /* no_recurse :: Set but not used. */ - /* */ - /* metrics_only :: A boolean indicating that we only want to compute */ - /* the metrics of a given glyph, not load all of its */ - /* points. */ - /* */ - /* hints_funcs :: Auxiliary pointer for hinting. */ - /* */ - /* hints_globals :: Auxiliary pointer for hinting. */ - /* */ - typedef struct CFF_Builder_ - { - FT_Memory memory; - TT_Face face; - CFF_GlyphSlot glyph; - FT_GlyphLoader loader; - FT_Outline* base; - FT_Outline* current; - - FT_Pos pos_x; - FT_Pos pos_y; - - FT_Vector left_bearing; - FT_Vector advance; - - FT_BBox bbox; /* bounding box */ - FT_Bool path_begun; - FT_Bool load_points; - FT_Bool no_recurse; - - FT_Bool metrics_only; - - void* hints_funcs; /* hinter-specific */ - void* hints_globals; /* hinter-specific */ - - } CFF_Builder; - - - FT_LOCAL( FT_Error ) - cff_check_points( CFF_Builder* builder, - FT_Int count ); - - FT_LOCAL( void ) - cff_builder_add_point( CFF_Builder* builder, - FT_Pos x, - FT_Pos y, - FT_Byte flag ); - FT_LOCAL( FT_Error ) - cff_builder_add_point1( CFF_Builder* builder, - FT_Pos x, - FT_Pos y ); - FT_LOCAL( FT_Error ) - cff_builder_start_point( CFF_Builder* builder, - FT_Pos x, - FT_Pos y ); - FT_LOCAL( void ) - cff_builder_close_contour( CFF_Builder* builder ); - - - FT_LOCAL( FT_Int ) - cff_lookup_glyph_by_stdcharcode( CFF_Font cff, - FT_Int charcode ); FT_LOCAL( FT_Error ) cff_get_glyph_data( TT_Face face, FT_UInt glyph_index, @@ -146,74 +38,6 @@ FT_BEGIN_HEADER FT_ULong length ); - /* execution context charstring zone */ - - typedef struct CFF_Decoder_Zone_ - { - FT_Byte* base; - FT_Byte* limit; - FT_Byte* cursor; - - } CFF_Decoder_Zone; - - - typedef struct CFF_Decoder_ - { - CFF_Builder builder; - CFF_Font cff; - - FT_Fixed stack[CFF_MAX_OPERANDS + 1]; - FT_Fixed* top; - - CFF_Decoder_Zone zones[CFF_MAX_SUBRS_CALLS + 1]; - CFF_Decoder_Zone* zone; - - FT_Int flex_state; - FT_Int num_flex_vectors; - FT_Vector flex_vectors[7]; - - FT_Pos glyph_width; - FT_Pos nominal_width; - - FT_Bool read_width; - FT_Bool width_only; - FT_Int num_hints; - FT_Fixed buildchar[CFF_MAX_TRANS_ELEMENTS]; - - FT_UInt num_locals; - FT_UInt num_globals; - - FT_Int locals_bias; - FT_Int globals_bias; - - FT_Byte** locals; - FT_Byte** globals; - - FT_Byte** glyph_names; /* for pure CFF fonts only */ - FT_UInt num_glyphs; /* number of glyphs in font */ - - FT_Render_Mode hint_mode; - - FT_Bool seac; - - CFF_SubFont current_subfont; /* for current glyph_index */ - - } CFF_Decoder; - - - FT_LOCAL( void ) - cff_decoder_init( CFF_Decoder* decoder, - TT_Face face, - CFF_Size size, - CFF_GlyphSlot slot, - FT_Bool hinting, - FT_Render_Mode hint_mode ); - - FT_LOCAL( FT_Error ) - cff_decoder_prepare( CFF_Decoder* decoder, - CFF_Size size, - FT_UInt glyph_index ); - #if 0 /* unused until we support pure CFF fonts */ /* Compute the maximum advance width of a font through quick parsing */ @@ -223,12 +47,6 @@ FT_BEGIN_HEADER #endif /* 0 */ -#ifdef CFF_CONFIG_OPTION_OLD_ENGINE - FT_LOCAL( FT_Error ) - cff_decoder_parse_charstrings( CFF_Decoder* decoder, - FT_Byte* charstring_base, - FT_ULong charstring_len ); -#endif FT_LOCAL( FT_Error ) cff_slot_load( CFF_GlyphSlot glyph, @@ -239,7 +57,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CFFGLOAD_H__ */ +#endif /* CFFGLOAD_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/cff/cffload.c b/src/3rdparty/freetype/src/cff/cffload.c index c61222d651..1c6fe51566 100644 --- a/src/3rdparty/freetype/src/cff/cffload.c +++ b/src/3rdparty/freetype/src/cff/cffload.c @@ -4,7 +4,7 @@ /* */ /* OpenType and CFF data/program tables loader (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,6 +22,12 @@ #include FT_INTERNAL_STREAM_H #include FT_TRUETYPE_TAGS_H #include FT_TYPE1_TABLES_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include FT_MULTIPLE_MASTERS_H +#include FT_SERVICE_MULTIPLE_MASTERS_H +#endif #include "cffload.h" #include "cffparse.h" @@ -29,6 +35,9 @@ #include "cfferrs.h" +#define FT_FIXED_ONE ( (FT_Fixed)0x10000 ) + + #if 1 static const FT_UShort cff_isoadobe_charset[229] = @@ -225,19 +234,33 @@ static FT_Error cff_index_init( CFF_Index idx, FT_Stream stream, - FT_Bool load ) + FT_Bool load, + FT_Bool cff2 ) { FT_Error error; FT_Memory memory = stream->memory; - FT_UShort count; + FT_UInt count; - FT_MEM_ZERO( idx, sizeof ( *idx ) ); + FT_ZERO( idx ); idx->stream = stream; idx->start = FT_STREAM_POS(); - if ( !FT_READ_USHORT( count ) && - count > 0 ) + + if ( cff2 ) + { + if ( FT_READ_ULONG( count ) ) + goto Exit; + idx->hdr_size = 5; + } + else + { + if ( FT_READ_USHORT( count ) ) + goto Exit; + idx->hdr_size = 3; + } + + if ( count > 0 ) { FT_Byte offsize; FT_ULong size; @@ -258,7 +281,7 @@ idx->off_size = offsize; size = (FT_ULong)( count + 1 ) * offsize; - idx->data_offset = idx->start + 3 + size; + idx->data_offset = idx->start + idx->hdr_size + size; if ( FT_STREAM_SKIP( size - offsize ) ) goto Exit; @@ -310,7 +333,7 @@ FT_FRAME_RELEASE( idx->bytes ); FT_FREE( idx->offsets ); - FT_MEM_ZERO( idx, sizeof ( *idx ) ); + FT_ZERO( idx ); } } @@ -323,7 +346,7 @@ FT_Memory memory = stream->memory; - if ( idx->count > 0 && idx->offsets == NULL ) + if ( idx->count > 0 && !idx->offsets ) { FT_Byte offsize = idx->off_size; FT_ULong data_size; @@ -335,7 +358,7 @@ data_size = (FT_ULong)( idx->count + 1 ) * offsize; if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) || - FT_STREAM_SEEK( idx->start + 3 ) || + FT_STREAM_SEEK( idx->start + idx->hdr_size ) || FT_FRAME_ENTER( data_size ) ) goto Exit; @@ -382,28 +405,31 @@ static FT_Error cff_index_get_pointers( CFF_Index idx, FT_Byte*** table, - FT_Byte** pool ) + FT_Byte** pool, + FT_ULong* pool_size ) { FT_Error error = FT_Err_Ok; FT_Memory memory = idx->stream->memory; FT_Byte** t = NULL; FT_Byte* new_bytes = NULL; + FT_ULong new_size; *table = NULL; - if ( idx->offsets == NULL ) + if ( !idx->offsets ) { error = cff_index_load_offsets( idx ); if ( error ) goto Exit; } - if ( idx->count > 0 && - !FT_NEW_ARRAY( t, idx->count + 1 ) && - ( !pool || !FT_ALLOC( new_bytes, - idx->data_size + idx->count ) ) ) + new_size = idx->data_size + idx->count; + + if ( idx->count > 0 && + !FT_NEW_ARRAY( t, idx->count + 1 ) && + ( !pool || !FT_ALLOC( new_bytes, new_size ) ) ) { FT_ULong n, cur_offset; FT_ULong extra = 0; @@ -459,6 +485,8 @@ if ( pool ) *pool = new_bytes; + if ( pool_size ) + *pool_size = new_size; } Exit: @@ -488,7 +516,7 @@ FT_ULong pos = element * idx->off_size; - if ( FT_STREAM_SEEK( idx->start + 3 + pos ) ) + if ( FT_STREAM_SEEK( idx->start + idx->hdr_size + pos ) ) goto Exit; off1 = cff_index_read_offset( idx, &error ); @@ -501,8 +529,8 @@ { element++; off2 = cff_index_read_offset( idx, &error ); - } - while ( off2 == 0 && element < idx->count ); + + } while ( off2 == 0 && element < idx->count ); } } else /* use offsets table */ @@ -584,20 +612,26 @@ FT_UInt element ) { CFF_Index idx = &font->name_index; - FT_Memory memory = idx->stream->memory; + FT_Memory memory; FT_Byte* bytes; FT_ULong byte_len; FT_Error error; FT_String* name = 0; + if ( !idx->stream ) /* CFF2 does not include a name index */ + goto Exit; + + memory = idx->stream->memory; + error = cff_index_access_element( idx, element, &bytes, &byte_len ); if ( error ) goto Exit; if ( !FT_ALLOC( name, byte_len + 1 ) ) { - FT_MEM_COPY( name, bytes, byte_len ); + if ( byte_len ) + FT_MEM_COPY( name, bytes, byte_len ); name[byte_len] = 0; } cff_index_forget_element( idx, &bytes ); @@ -719,6 +753,11 @@ FT_Byte fd = 0; + /* if there is no FDSelect, return zero */ + /* Note: CFF2 with just one Font Dict has no FDSelect */ + if ( !fdselect->data ) + goto Exit; + switch ( fdselect->format ) { case 0: @@ -771,6 +810,7 @@ ; } + Exit: return fd; } @@ -809,7 +849,7 @@ /* When multiple GIDs map to the same CID, we choose the lowest */ /* GID. This is not described in any spec, but it matches the */ /* behaviour of recent Acroread versions. */ - for ( j = (FT_Long)num_glyphs - 1; j >= 0 ; j-- ) + for ( j = (FT_Long)num_glyphs - 1; j >= 0; j-- ) charset->cids[charset->sids[j]] = (FT_UShort)j; charset->max_cid = max_cid; @@ -871,8 +911,8 @@ FT_UShort glyph_sid; - /* If the the offset is greater than 2, we have to parse the */ - /* charset table. */ + /* If the offset is greater than 2, we have to parse the charset */ + /* table. */ if ( offset > 2 ) { FT_UInt j; @@ -1048,6 +1088,523 @@ } + static void + cff_vstore_done( CFF_VStoreRec* vstore, + FT_Memory memory ) + { + FT_UInt i; + + + /* free regionList and axisLists */ + if ( vstore->varRegionList ) + { + for ( i = 0; i < vstore->regionCount; i++ ) + FT_FREE( vstore->varRegionList[i].axisList ); + } + FT_FREE( vstore->varRegionList ); + + /* free varData and indices */ + if ( vstore->varData ) + { + for ( i = 0; i < vstore->dataCount; i++ ) + FT_FREE( vstore->varData[i].regionIndices ); + } + FT_FREE( vstore->varData ); + } + + + /* convert 2.14 to Fixed */ + #define FT_fdot14ToFixed( x ) ( (FT_Fixed)( (FT_ULong)(x) << 2 ) ) + + + static FT_Error + cff_vstore_load( CFF_VStoreRec* vstore, + FT_Stream stream, + FT_ULong base_offset, + FT_ULong offset ) + { + FT_Memory memory = stream->memory; + FT_Error error = FT_ERR( Invalid_File_Format ); + + FT_ULong* dataOffsetArray = NULL; + FT_UInt i, j; + + + /* no offset means no vstore to parse */ + if ( offset ) + { + FT_UInt vsOffset; + FT_UInt format; + FT_ULong regionListOffset; + + + /* we need to parse the table to determine its size; */ + /* skip table length */ + if ( FT_STREAM_SEEK( base_offset + offset ) || + FT_STREAM_SKIP( 2 ) ) + goto Exit; + + /* actual variation store begins after the length */ + vsOffset = FT_STREAM_POS(); + + /* check the header */ + if ( FT_READ_USHORT( format ) ) + goto Exit; + if ( format != 1 ) + { + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* read top level fields */ + if ( FT_READ_ULONG( regionListOffset ) || + FT_READ_USHORT( vstore->dataCount ) ) + goto Exit; + + /* make temporary copy of item variation data offsets; */ + /* we'll parse region list first, then come back */ + if ( FT_NEW_ARRAY( dataOffsetArray, vstore->dataCount ) ) + goto Exit; + + for ( i = 0; i < vstore->dataCount; i++ ) + { + if ( FT_READ_ULONG( dataOffsetArray[i] ) ) + goto Exit; + } + + /* parse regionList and axisLists */ + if ( FT_STREAM_SEEK( vsOffset + regionListOffset ) || + FT_READ_USHORT( vstore->axisCount ) || + FT_READ_USHORT( vstore->regionCount ) ) + goto Exit; + + if ( FT_NEW_ARRAY( vstore->varRegionList, vstore->regionCount ) ) + goto Exit; + + for ( i = 0; i < vstore->regionCount; i++ ) + { + CFF_VarRegion* region = &vstore->varRegionList[i]; + + + if ( FT_NEW_ARRAY( region->axisList, vstore->axisCount ) ) + goto Exit; + + for ( j = 0; j < vstore->axisCount; j++ ) + { + CFF_AxisCoords* axis = ®ion->axisList[j]; + + FT_Int16 start14, peak14, end14; + + + if ( FT_READ_SHORT( start14 ) || + FT_READ_SHORT( peak14 ) || + FT_READ_SHORT( end14 ) ) + goto Exit; + + axis->startCoord = FT_fdot14ToFixed( start14 ); + axis->peakCoord = FT_fdot14ToFixed( peak14 ); + axis->endCoord = FT_fdot14ToFixed( end14 ); + } + } + + /* use dataOffsetArray now to parse varData items */ + if ( FT_NEW_ARRAY( vstore->varData, vstore->dataCount ) ) + goto Exit; + + for ( i = 0; i < vstore->dataCount; i++ ) + { + CFF_VarData* data = &vstore->varData[i]; + + + if ( FT_STREAM_SEEK( vsOffset + dataOffsetArray[i] ) ) + goto Exit; + + /* ignore `itemCount' and `shortDeltaCount' */ + /* because CFF2 has no delta sets */ + if ( FT_STREAM_SKIP( 4 ) ) + goto Exit; + + /* Note: just record values; consistency is checked later */ + /* by cff_blend_build_vector when it consumes `vstore' */ + + if ( FT_READ_USHORT( data->regionIdxCount ) ) + goto Exit; + + if ( FT_NEW_ARRAY( data->regionIndices, data->regionIdxCount ) ) + goto Exit; + + for ( j = 0; j < data->regionIdxCount; j++ ) + { + if ( FT_READ_USHORT( data->regionIndices[j] ) ) + goto Exit; + } + } + } + + error = FT_Err_Ok; + + Exit: + FT_FREE( dataOffsetArray ); + if ( error ) + cff_vstore_done( vstore, memory ); + + return error; + } + + + /* Clear blend stack (after blend values are consumed). */ + /* */ + /* TODO: Should do this in cff_run_parse, but subFont */ + /* ref is not available there. */ + /* */ + /* Allocation is not changed when stack is cleared. */ + FT_LOCAL_DEF( void ) + cff_blend_clear( CFF_SubFont subFont ) + { + subFont->blend_top = subFont->blend_stack; + subFont->blend_used = 0; + } + + + /* Blend numOperands on the stack, */ + /* store results into the first numBlends values, */ + /* then pop remaining arguments. */ + /* */ + /* This is comparable to `cf2_doBlend' but */ + /* the cffparse stack is different and can't be written. */ + /* Blended values are written to a different buffer, */ + /* using reserved operator 255. */ + /* */ + /* Blend calculation is done in 16.16 fixed point. */ + FT_LOCAL_DEF( FT_Error ) + cff_blend_doBlend( CFF_SubFont subFont, + CFF_Parser parser, + FT_UInt numBlends ) + { + FT_UInt delta; + FT_UInt base; + FT_UInt i, j; + FT_UInt size; + + CFF_Blend blend = &subFont->blend; + + FT_Memory memory = subFont->blend.font->memory; /* for FT_REALLOC */ + FT_Error error = FT_Err_Ok; /* for FT_REALLOC */ + + /* compute expected number of operands for this blend */ + FT_UInt numOperands = (FT_UInt)( numBlends * blend->lenBV ); + FT_UInt count = (FT_UInt)( parser->top - 1 - parser->stack ); + + + if ( numOperands > count ) + { + FT_TRACE4(( " cff_blend_doBlend: Stack underflow %d argument%s\n", + count, + count == 1 ? "" : "s" )); + + error = FT_THROW( Stack_Underflow ); + goto Exit; + } + + /* check whether we have room for `numBlends' values at `blend_top' */ + size = 5 * numBlends; /* add 5 bytes per entry */ + if ( subFont->blend_used + size > subFont->blend_alloc ) + { + FT_Byte* blend_stack_old = subFont->blend_stack; + FT_Byte* blend_top_old = subFont->blend_top; + + + /* increase or allocate `blend_stack' and reset `blend_top'; */ + /* prepare to append `numBlends' values to the buffer */ + if ( FT_REALLOC( subFont->blend_stack, + subFont->blend_alloc, + subFont->blend_alloc + size ) ) + goto Exit; + + subFont->blend_top = subFont->blend_stack + subFont->blend_used; + subFont->blend_alloc += size; + + /* iterate over the parser stack and adjust pointers */ + /* if the reallocated buffer has a different address */ + if ( blend_stack_old && + subFont->blend_stack != blend_stack_old ) + { + FT_PtrDist offset = subFont->blend_stack - blend_stack_old; + FT_Byte** p; + + + for ( p = parser->stack; p < parser->top; p++ ) + { + if ( *p >= blend_stack_old && *p < blend_top_old ) + *p += offset; + } + } + } + subFont->blend_used += size; + + base = count - numOperands; /* index of first blend arg */ + delta = base + numBlends; /* index of first delta arg */ + + for ( i = 0; i < numBlends; i++ ) + { + const FT_Int32* weight = &blend->BV[1]; + FT_UInt32 sum; + + + /* convert inputs to 16.16 fixed point */ + sum = cff_parse_num( parser, &parser->stack[i + base] ) * 0x10000; + + for ( j = 1; j < blend->lenBV; j++ ) + sum += cff_parse_num( parser, &parser->stack[delta++] ) * *weight++; + + /* point parser stack to new value on blend_stack */ + parser->stack[i + base] = subFont->blend_top; + + /* Push blended result as Type 2 5-byte fixed point number. This */ + /* will not conflict with actual DICTs because 255 is a reserved */ + /* opcode in both CFF and CFF2 DICTs. See `cff_parse_num' for */ + /* decode of this, which rounds to an integer. */ + *subFont->blend_top++ = 255; + *subFont->blend_top++ = (FT_Byte)( sum >> 24 ); + *subFont->blend_top++ = (FT_Byte)( sum >> 16 ); + *subFont->blend_top++ = (FT_Byte)( sum >> 8 ); + *subFont->blend_top++ = (FT_Byte)sum; + } + + /* leave only numBlends results on parser stack */ + parser->top = &parser->stack[base + numBlends]; + + Exit: + return error; + } + + + /* Compute a blend vector from variation store index and normalized */ + /* vector based on pseudo-code in OpenType Font Variations Overview. */ + /* */ + /* Note: lenNDV == 0 produces a default blend vector, (1,0,0,...). */ + FT_LOCAL_DEF( FT_Error ) + cff_blend_build_vector( CFF_Blend blend, + FT_UInt vsindex, + FT_UInt lenNDV, + FT_Fixed* NDV ) + { + FT_Error error = FT_Err_Ok; /* for FT_REALLOC */ + FT_Memory memory = blend->font->memory; /* for FT_REALLOC */ + + FT_UInt len; + CFF_VStore vs; + CFF_VarData* varData; + FT_UInt master; + + + FT_ASSERT( lenNDV == 0 || NDV ); + + blend->builtBV = FALSE; + + vs = &blend->font->vstore; + + /* VStore and fvar must be consistent */ + if ( lenNDV != 0 && lenNDV != vs->axisCount ) + { + FT_TRACE4(( " cff_blend_build_vector: Axis count mismatch\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + if ( vsindex >= vs->dataCount ) + { + FT_TRACE4(( " cff_blend_build_vector: vsindex out of range\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* select the item variation data structure */ + varData = &vs->varData[vsindex]; + + /* prepare buffer for the blend vector */ + len = varData->regionIdxCount + 1; /* add 1 for default component */ + if ( FT_REALLOC( blend->BV, + blend->lenBV * sizeof( *blend->BV ), + len * sizeof( *blend->BV ) ) ) + goto Exit; + + blend->lenBV = len; + + /* outer loop steps through master designs to be blended */ + for ( master = 0; master < len; master++ ) + { + FT_UInt j; + FT_UInt idx; + CFF_VarRegion* varRegion; + + + /* default factor is always one */ + if ( master == 0 ) + { + blend->BV[master] = FT_FIXED_ONE; + FT_TRACE4(( " build blend vector len %d\n" + " [ %f ", + len, + blend->BV[master] / 65536.0 )); + continue; + } + + /* VStore array does not include default master, so subtract one */ + idx = varData->regionIndices[master - 1]; + varRegion = &vs->varRegionList[idx]; + + if ( idx >= vs->regionCount ) + { + FT_TRACE4(( " cff_blend_build_vector:" + " region index out of range\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* Note: `lenNDV' could be zero. */ + /* In that case, build default blend vector (1,0,0...). */ + if ( !lenNDV ) + { + blend->BV[master] = 0; + continue; + } + + /* In the normal case, initialize each component to 1 */ + /* before inner loop. */ + blend->BV[master] = FT_FIXED_ONE; /* default */ + + /* inner loop steps through axes in this region */ + for ( j = 0; j < lenNDV; j++ ) + { + CFF_AxisCoords* axis = &varRegion->axisList[j]; + FT_Fixed axisScalar; + + + /* compute the scalar contribution of this axis; */ + /* ignore invalid ranges */ + if ( axis->startCoord > axis->peakCoord || + axis->peakCoord > axis->endCoord ) + axisScalar = FT_FIXED_ONE; + + else if ( axis->startCoord < 0 && + axis->endCoord > 0 && + axis->peakCoord != 0 ) + axisScalar = FT_FIXED_ONE; + + /* peak of 0 means ignore this axis */ + else if ( axis->peakCoord == 0 ) + axisScalar = FT_FIXED_ONE; + + /* ignore this region if coords are out of range */ + else if ( NDV[j] < axis->startCoord || + NDV[j] > axis->endCoord ) + axisScalar = 0; + + /* calculate a proportional factor */ + else + { + if ( NDV[j] == axis->peakCoord ) + axisScalar = FT_FIXED_ONE; + else if ( NDV[j] < axis->peakCoord ) + axisScalar = FT_DivFix( NDV[j] - axis->startCoord, + axis->peakCoord - axis->startCoord ); + else + axisScalar = FT_DivFix( axis->endCoord - NDV[j], + axis->endCoord - axis->peakCoord ); + } + + /* take product of all the axis scalars */ + blend->BV[master] = FT_MulFix( blend->BV[master], axisScalar ); + } + + FT_TRACE4(( ", %f ", + blend->BV[master] / 65536.0 )); + } + + FT_TRACE4(( "]\n" )); + + /* record the parameters used to build the blend vector */ + blend->lastVsindex = vsindex; + + if ( lenNDV != 0 ) + { + /* user has set a normalized vector */ + if ( FT_REALLOC( blend->lastNDV, + blend->lenNDV * sizeof ( *NDV ), + lenNDV * sizeof ( *NDV ) ) ) + goto Exit; + + FT_MEM_COPY( blend->lastNDV, + NDV, + lenNDV * sizeof ( *NDV ) ); + } + + blend->lenNDV = lenNDV; + blend->builtBV = TRUE; + + Exit: + return error; + } + + + /* `lenNDV' is zero for default vector; */ + /* return TRUE if blend vector needs to be built. */ + FT_LOCAL_DEF( FT_Bool ) + cff_blend_check_vector( CFF_Blend blend, + FT_UInt vsindex, + FT_UInt lenNDV, + FT_Fixed* NDV ) + { + if ( !blend->builtBV || + blend->lastVsindex != vsindex || + blend->lenNDV != lenNDV || + ( lenNDV && + ft_memcmp( NDV, + blend->lastNDV, + lenNDV * sizeof ( *NDV ) ) != 0 ) ) + { + /* need to build blend vector */ + return TRUE; + } + + return FALSE; + } + + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + + FT_LOCAL_DEF( FT_Error ) + cff_get_var_blend( CFF_Face face, + FT_UInt *num_coords, + FT_Fixed* *coords, + FT_Fixed* *normalizedcoords, + FT_MM_Var* *mm_var ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + return mm->get_var_blend( FT_FACE( face ), + num_coords, + coords, + normalizedcoords, + mm_var ); + } + + + FT_LOCAL_DEF( void ) + cff_done_blend( CFF_Face face ) + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + + if (mm) + mm->done_blend( FT_FACE( face ) ); + } + +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + + static void cff_encoding_done( CFF_Encoding encoding ) { @@ -1300,26 +1857,156 @@ } + /* Parse private dictionary; first call is always from `cff_face_init', */ + /* so NDV has not been set for CFF2 variation. */ + /* */ + /* `cff_slot_load' must call this function each time NDV changes. */ + FT_LOCAL_DEF( FT_Error ) + cff_load_private_dict( CFF_Font font, + CFF_SubFont subfont, + FT_UInt lenNDV, + FT_Fixed* NDV ) + { + FT_Error error = FT_Err_Ok; + CFF_ParserRec parser; + CFF_FontRecDict top = &subfont->font_dict; + CFF_Private priv = &subfont->private_dict; + FT_Stream stream = font->stream; + FT_UInt stackSize; + + + /* store handle needed to access memory, vstore for blend; */ + /* we need this for clean-up even if there is no private DICT */ + subfont->blend.font = font; + subfont->blend.usedBV = FALSE; /* clear state */ + + if ( !top->private_offset || !top->private_size ) + goto Exit2; /* no private DICT, do nothing */ + + /* set defaults */ + FT_ZERO( priv ); + + priv->blue_shift = 7; + priv->blue_fuzz = 1; + priv->lenIV = -1; + priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L ); + priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 ); + + /* provide inputs for blend calculations */ + priv->subfont = subfont; + subfont->lenNDV = lenNDV; + subfont->NDV = NDV; + + /* add 1 for the operator */ + stackSize = font->cff2 ? font->top_font.font_dict.maxstack + 1 + : CFF_MAX_STACK_DEPTH + 1; + + if ( cff_parser_init( &parser, + font->cff2 ? CFF2_CODE_PRIVATE : CFF_CODE_PRIVATE, + priv, + font->library, + stackSize, + top->num_designs, + top->num_axes ) ) + goto Exit; + + if ( FT_STREAM_SEEK( font->base_offset + top->private_offset ) || + FT_FRAME_ENTER( top->private_size ) ) + goto Exit; + + FT_TRACE4(( " private dictionary:\n" )); + error = cff_parser_run( &parser, + (FT_Byte*)stream->cursor, + (FT_Byte*)stream->limit ); + FT_FRAME_EXIT(); + + if ( error ) + goto Exit; + + /* ensure that `num_blue_values' is even */ + priv->num_blue_values &= ~1; + + /* sanitize `initialRandomSeed' to be a positive value, if necessary; */ + /* this is not mandated by the specification but by our implementation */ + if ( priv->initial_random_seed < 0 ) + priv->initial_random_seed = -priv->initial_random_seed; + else if ( priv->initial_random_seed == 0 ) + priv->initial_random_seed = 987654321; + + /* some sanitizing to avoid overflows later on; */ + /* the upper limits are ad-hoc values */ + if ( priv->blue_shift > 1000 || priv->blue_shift < 0 ) + { + FT_TRACE2(( "cff_load_private_dict:" + " setting unlikely BlueShift value %d to default (7)\n", + priv->blue_shift )); + priv->blue_shift = 7; + } + + if ( priv->blue_fuzz > 1000 || priv->blue_fuzz < 0 ) + { + FT_TRACE2(( "cff_load_private_dict:" + " setting unlikely BlueFuzz value %d to default (1)\n", + priv->blue_fuzz )); + priv->blue_fuzz = 1; + } + + Exit: + /* clean up */ + cff_blend_clear( subfont ); /* clear blend stack */ + cff_parser_done( &parser ); /* free parser stack */ + + Exit2: + /* no clean up (parser not initialized) */ + return error; + } + + + /* There are 3 ways to call this function, distinguished by code. */ + /* */ + /* . CFF_CODE_TOPDICT for either a CFF Top DICT or a CFF Font DICT */ + /* . CFF2_CODE_TOPDICT for CFF2 Top DICT */ + /* . CFF2_CODE_FONTDICT for CFF2 Font DICT */ + static FT_Error - cff_subfont_load( CFF_SubFont font, + cff_subfont_load( CFF_SubFont subfont, CFF_Index idx, FT_UInt font_index, FT_Stream stream, FT_ULong base_offset, - FT_Library library ) + FT_UInt code, + CFF_Font font, + CFF_Face face ) { FT_Error error; CFF_ParserRec parser; FT_Byte* dict = NULL; FT_ULong dict_len; - CFF_FontRecDict top = &font->font_dict; - CFF_Private priv = &font->private_dict; + CFF_FontRecDict top = &subfont->font_dict; + CFF_Private priv = &subfont->private_dict; + + PSAux_Service psaux = (PSAux_Service)face->psaux; + + FT_Bool cff2 = FT_BOOL( code == CFF2_CODE_TOPDICT || + code == CFF2_CODE_FONTDICT ); + FT_UInt stackSize = cff2 ? CFF2_DEFAULT_STACK + : CFF_MAX_STACK_DEPTH; - cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict, library ); + /* Note: We use default stack size for CFF2 Font DICT because */ + /* Top and Font DICTs are not allowed to have blend operators. */ + error = cff_parser_init( &parser, + code, + &subfont->font_dict, + font->library, + stackSize, + 0, + 0 ); + if ( error ) + goto Exit; /* set defaults */ - FT_MEM_ZERO( top, sizeof ( *top ) ); + FT_ZERO( top ); top->underline_position = -( 100L << 16 ); top->underline_thickness = 50L << 16; @@ -1342,14 +2029,35 @@ top->cid_ordering = 0xFFFFU; top->cid_font_name = 0xFFFFU; - error = cff_index_access_element( idx, font_index, &dict, &dict_len ); + /* set default stack size */ + top->maxstack = cff2 ? CFF2_DEFAULT_STACK : 48; + + if ( idx->count ) /* count is nonzero for a real index */ + error = cff_index_access_element( idx, font_index, &dict, &dict_len ); + else + { + /* CFF2 has a fake top dict index; */ + /* simulate `cff_index_access_element' */ + + /* Note: macros implicitly use `stream' and set `error' */ + if ( FT_STREAM_SEEK( idx->data_offset ) || + FT_FRAME_EXTRACT( idx->data_size, dict ) ) + goto Exit; + + dict_len = idx->data_size; + } + if ( !error ) { FT_TRACE4(( " top dictionary:\n" )); error = cff_parser_run( &parser, dict, dict + dict_len ); } - cff_index_forget_element( idx, &dict ); + /* clean up regardless of error */ + if ( idx->count ) + cff_index_forget_element( idx, &dict ); + else + FT_FRAME_RELEASE( dict ); if ( error ) goto Exit; @@ -1358,34 +2066,63 @@ if ( top->cid_registry != 0xFFFFU ) goto Exit; - /* parse the private dictionary, if any */ - if ( top->private_offset && top->private_size ) + /* Parse the private dictionary, if any. */ + /* */ + /* CFF2 does not have a private dictionary in the Top DICT */ + /* but may have one in a Font DICT. We need to parse */ + /* the latter here in order to load any local subrs. */ + error = cff_load_private_dict( font, subfont, 0, 0 ); + if ( error ) + goto Exit; + + if ( !cff2 ) { - /* set defaults */ - FT_MEM_ZERO( priv, sizeof ( *priv ) ); + /* + * Initialize the random number generator. + * + * . If we have a face-specific seed, use it. + * If non-zero, update it to a positive value. + * + * . Otherwise, use the seed from the CFF driver. + * If non-zero, update it to a positive value. + * + * . If the random value is zero, use the seed given by the subfont's + * `initialRandomSeed' value. + * + */ + if ( face->root.internal->random_seed == -1 ) + { + PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( face ); - priv->blue_shift = 7; - priv->blue_fuzz = 1; - priv->lenIV = -1; - priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L ); - priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 ); - cff_parser_init( &parser, CFF_CODE_PRIVATE, priv, library ); + subfont->random = (FT_UInt32)driver->random_seed; + if ( driver->random_seed ) + { + do + { + driver->random_seed = + (FT_Int32)psaux->cff_random( (FT_UInt32)driver->random_seed ); - if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) || - FT_FRAME_ENTER( font->font_dict.private_size ) ) - goto Exit; + } while ( driver->random_seed < 0 ); + } + } + else + { + subfont->random = (FT_UInt32)face->root.internal->random_seed; + if ( face->root.internal->random_seed ) + { + do + { + face->root.internal->random_seed = + (FT_Int32)psaux->cff_random( + (FT_UInt32)face->root.internal->random_seed ); - FT_TRACE4(( " private dictionary:\n" )); - error = cff_parser_run( &parser, - (FT_Byte*)stream->cursor, - (FT_Byte*)stream->limit ); - FT_FRAME_EXIT(); - if ( error ) - goto Exit; + } while ( face->root.internal->random_seed < 0 ); + } + } - /* ensure that `num_blue_values' is even */ - priv->num_blue_values &= ~1; + if ( !subfont->random ) + subfont->random = (FT_UInt32)priv->initial_random_seed; } /* read the local subrs, if any */ @@ -1395,17 +2132,19 @@ priv->local_subrs_offset ) ) goto Exit; - error = cff_index_init( &font->local_subrs_index, stream, 1 ); + error = cff_index_init( &subfont->local_subrs_index, stream, 1, cff2 ); if ( error ) goto Exit; - error = cff_index_get_pointers( &font->local_subrs_index, - &font->local_subrs, NULL ); + error = cff_index_get_pointers( &subfont->local_subrs_index, + &subfont->local_subrs, NULL, NULL ); if ( error ) goto Exit; } Exit: + cff_parser_done( &parser ); /* free parser stack */ + return error; } @@ -1418,6 +2157,10 @@ { cff_index_done( &subfont->local_subrs_index ); FT_FREE( subfont->local_subrs ); + + FT_FREE( subfont->blend.lastNDV ); + FT_FREE( subfont->blend.BV ); + FT_FREE( subfont->blend_stack ); } } @@ -1427,18 +2170,19 @@ FT_Stream stream, FT_Int face_index, CFF_Font font, - FT_Bool pure_cff ) + CFF_Face face, + FT_Bool pure_cff, + FT_Bool cff2 ) { static const FT_Frame_Field cff_header_fields[] = { #undef FT_STRUCTURE #define FT_STRUCTURE CFF_FontRec - FT_FRAME_START( 4 ), + FT_FRAME_START( 3 ), FT_FRAME_BYTE( version_major ), FT_FRAME_BYTE( version_minor ), FT_FRAME_BYTE( header_size ), - FT_FRAME_BYTE( absolute_offsize ), FT_FRAME_END }; @@ -1453,42 +2197,133 @@ FT_ZERO( font ); FT_ZERO( &string_index ); - font->stream = stream; - font->memory = memory; - dict = &font->top_font.font_dict; - base_offset = FT_STREAM_POS(); + dict = &font->top_font.font_dict; + base_offset = FT_STREAM_POS(); + + font->library = library; + font->stream = stream; + font->memory = memory; + font->cff2 = cff2; + font->base_offset = base_offset; /* read CFF font header */ if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) ) goto Exit; - /* check format */ - if ( font->version_major != 1 || - font->header_size < 4 || - font->absolute_offsize > 4 ) + if ( cff2 ) { - FT_TRACE2(( " not a CFF font header\n" )); - error = FT_THROW( Unknown_File_Format ); - goto Exit; + if ( font->version_major != 2 || + font->header_size < 5 ) + { + FT_TRACE2(( " not a CFF2 font header\n" )); + error = FT_THROW( Unknown_File_Format ); + goto Exit; + } + + if ( FT_READ_USHORT( font->top_dict_length ) ) + goto Exit; + } + else + { + FT_Byte absolute_offset; + + + if ( FT_READ_BYTE( absolute_offset ) ) + goto Exit; + + if ( font->version_major != 1 || + font->header_size < 4 || + absolute_offset > 4 ) + { + FT_TRACE2(( " not a CFF font header\n" )); + error = FT_THROW( Unknown_File_Format ); + goto Exit; + } } /* skip the rest of the header */ - if ( FT_STREAM_SKIP( font->header_size - 4 ) ) + if ( FT_STREAM_SEEK( base_offset + font->header_size ) ) + { + /* For pure CFFs we have read only four bytes so far. Contrary to */ + /* other formats like SFNT those bytes doesn't define a signature; */ + /* it is thus possible that the font isn't a CFF at all. */ + if ( pure_cff ) + { + FT_TRACE2(( " not a CFF file\n" )); + error = FT_THROW( Unknown_File_Format ); + } goto Exit; + } - /* read the name, top dict, string and global subrs index */ - if ( FT_SET_ERROR( cff_index_init( &font->name_index, - stream, 0 ) ) || - FT_SET_ERROR( cff_index_init( &font->font_dict_index, - stream, 0 ) ) || - FT_SET_ERROR( cff_index_init( &string_index, - stream, 1 ) ) || - FT_SET_ERROR( cff_index_init( &font->global_subrs_index, - stream, 1 ) ) || - FT_SET_ERROR( cff_index_get_pointers( &string_index, - &font->strings, - &font->string_pool ) ) ) - goto Exit; + if ( cff2 ) + { + /* For CFF2, the top dict data immediately follow the header */ + /* and the length is stored in the header `offSize' field; */ + /* there is no index for it. */ + /* */ + /* Use the `font_dict_index' to save the current position */ + /* and length of data, but leave count at zero as an indicator. */ + FT_ZERO( &font->font_dict_index ); + + font->font_dict_index.data_offset = FT_STREAM_POS(); + font->font_dict_index.data_size = font->top_dict_length; + + /* skip the top dict data for now, we will parse it later */ + if ( FT_STREAM_SKIP( font->top_dict_length ) ) + goto Exit; + + /* next, read the global subrs index */ + if ( FT_SET_ERROR( cff_index_init( &font->global_subrs_index, + stream, 1, cff2 ) ) ) + goto Exit; + } + else + { + /* for CFF, read the name, top dict, string and global subrs index */ + if ( FT_SET_ERROR( cff_index_init( &font->name_index, + stream, 0, cff2 ) ) ) + { + if ( pure_cff ) + { + FT_TRACE2(( " not a CFF file\n" )); + error = FT_THROW( Unknown_File_Format ); + } + goto Exit; + } + + /* if we have an empty font name, */ + /* it must be the only font in the CFF */ + if ( font->name_index.count > 1 && + font->name_index.data_size < font->name_index.count ) + { + /* for pure CFFs, we still haven't checked enough bytes */ + /* to be sure that it is a CFF at all */ + error = pure_cff ? FT_THROW( Unknown_File_Format ) + : FT_THROW( Invalid_File_Format ); + goto Exit; + } + + if ( FT_SET_ERROR( cff_index_init( &font->font_dict_index, + stream, 0, cff2 ) ) || + FT_SET_ERROR( cff_index_init( &string_index, + stream, 1, cff2 ) ) || + FT_SET_ERROR( cff_index_init( &font->global_subrs_index, + stream, 1, cff2 ) ) || + FT_SET_ERROR( cff_index_get_pointers( &string_index, + &font->strings, + &font->string_pool, + &font->string_pool_size ) ) ) + goto Exit; + + /* there must be a Top DICT index entry for each name index entry */ + if ( font->name_index.count > font->font_dict_index.count ) + { + FT_ERROR(( "cff_font_load:" + " not enough entries in Top DICT index\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + } font->num_strings = string_index.count; @@ -1534,34 +2369,48 @@ subfont_index, stream, base_offset, - library ); + cff2 ? CFF2_CODE_TOPDICT : CFF_CODE_TOPDICT, + font, + face ); if ( error ) goto Exit; if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) ) goto Exit; - error = cff_index_init( &font->charstrings_index, stream, 0 ); + error = cff_index_init( &font->charstrings_index, stream, 0, cff2 ); if ( error ) goto Exit; - /* now, check for a CID font */ - if ( dict->cid_registry != 0xFFFFU ) + /* now, check for a CID or CFF2 font */ + if ( dict->cid_registry != 0xFFFFU || + cff2 ) { CFF_IndexRec fd_index; CFF_SubFont sub = NULL; FT_UInt idx; + /* for CFF2, read the Variation Store if available; */ + /* this must follow the Top DICT parse and precede any Private DICT */ + error = cff_vstore_load( &font->vstore, + stream, + base_offset, + dict->vstore_offset ); + if ( error ) + goto Exit; + /* this is a CID-keyed font, we must now allocate a table of */ /* sub-fonts, then load each of them separately */ if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) ) goto Exit; - error = cff_index_init( &fd_index, stream, 0 ); + error = cff_index_init( &fd_index, stream, 0, cff2 ); if ( error ) goto Exit; + /* Font Dicts are not limited to 256 for CFF2. */ + /* TODO: support this for CFF2 */ if ( fd_index.count > CFF_MAX_CID_FONTS ) { FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" )); @@ -1582,17 +2431,26 @@ { sub = font->subfonts[idx]; FT_TRACE4(( "parsing subfont %u\n", idx )); - error = cff_subfont_load( sub, &fd_index, idx, - stream, base_offset, library ); + error = cff_subfont_load( sub, + &fd_index, + idx, + stream, + base_offset, + cff2 ? CFF2_CODE_FONTDICT + : CFF_CODE_TOPDICT, + font, + face ); if ( error ) goto Fail_CID; } - /* now load the FD Select array */ - error = CFF_Load_FD_Select( &font->fd_select, - font->charstrings_index.count, - stream, - base_offset + dict->cid_fd_select_offset ); + /* now load the FD Select array; */ + /* CFF2 omits FDSelect if there is only one FD */ + if ( !cff2 || fd_index.count > 1 ) + error = CFF_Load_FD_Select( &font->fd_select, + font->charstrings_index.count, + stream, + base_offset + dict->cid_fd_select_offset ); Fail_CID: cff_index_done( &fd_index ); @@ -1614,13 +2472,13 @@ font->num_glyphs = font->charstrings_index.count; error = cff_index_get_pointers( &font->global_subrs_index, - &font->global_subrs, NULL ); + &font->global_subrs, NULL, NULL ); if ( error ) goto Exit; /* read the Charset and Encoding tables if available */ - if ( font->num_glyphs > 0 ) + if ( !cff2 && font->num_glyphs > 0 ) { FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff ); @@ -1668,7 +2526,7 @@ cff_index_done( &font->charstrings_index ); /* release font dictionaries, but only if working with */ - /* a CID keyed CFF font */ + /* a CID keyed CFF font or a CFF2 font */ if ( font->num_subfonts > 0 ) { for ( idx = 0; idx < font->num_subfonts; idx++ ) @@ -1680,6 +2538,7 @@ cff_encoding_done( &font->encoding ); cff_charset_done( &font->charset, font->stream ); + cff_vstore_done( &font->vstore, memory ); cff_subfont_done( memory, &font->top_font ); @@ -1697,6 +2556,8 @@ font->cf2_instance.finalizer( font->cf2_instance.data ); FT_FREE( font->cf2_instance.data ); } + + FT_FREE( font->font_extra ); } diff --git a/src/3rdparty/freetype/src/cff/cffload.h b/src/3rdparty/freetype/src/cff/cffload.h index 459e7b0446..14d14e2112 100644 --- a/src/3rdparty/freetype/src/cff/cffload.h +++ b/src/3rdparty/freetype/src/cff/cffload.h @@ -4,7 +4,7 @@ /* */ /* OpenType & CFF data/program tables loader (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,12 +16,14 @@ /***************************************************************************/ -#ifndef __CFFLOAD_H__ -#define __CFFLOAD_H__ +#ifndef CFFLOAD_H_ +#define CFFLOAD_H_ #include <ft2build.h> -#include "cfftypes.h" +#include FT_INTERNAL_CFF_TYPES_H +#include "cffparse.h" +#include FT_INTERNAL_CFF_OBJECTS_TYPES_H /* for CFF_Face */ FT_BEGIN_HEADER @@ -60,24 +62,64 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) - cff_font_load( FT_Library library, - FT_Stream stream, - FT_Int face_index, - CFF_Font font, - FT_Bool pure_cff ); + cff_font_load( FT_Library library, + FT_Stream stream, + FT_Int face_index, + CFF_Font font, + CFF_Face face, + FT_Bool pure_cff, + FT_Bool cff2 ); FT_LOCAL( void ) cff_font_done( CFF_Font font ); + FT_LOCAL( FT_Error ) + cff_load_private_dict( CFF_Font font, + CFF_SubFont subfont, + FT_UInt lenNDV, + FT_Fixed* NDV ); + FT_LOCAL( FT_Byte ) cff_fd_select_get( CFF_FDSelect fdselect, FT_UInt glyph_index ); + FT_LOCAL( FT_Bool ) + cff_blend_check_vector( CFF_Blend blend, + FT_UInt vsindex, + FT_UInt lenNDV, + FT_Fixed* NDV ); + + FT_LOCAL( FT_Error ) + cff_blend_build_vector( CFF_Blend blend, + FT_UInt vsindex, + FT_UInt lenNDV, + FT_Fixed* NDV ); + + FT_LOCAL( void ) + cff_blend_clear( CFF_SubFont subFont ); + + FT_LOCAL( FT_Error ) + cff_blend_doBlend( CFF_SubFont subfont, + CFF_Parser parser, + FT_UInt numBlends ); + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_LOCAL( FT_Error ) + cff_get_var_blend( CFF_Face face, + FT_UInt *num_coords, + FT_Fixed* *coords, + FT_Fixed* *normalizedcoords, + FT_MM_Var* *mm_var ); + + FT_LOCAL( void ) + cff_done_blend( CFF_Face face ); +#endif + FT_END_HEADER -#endif /* __CFFLOAD_H__ */ +#endif /* CFFLOAD_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/cff/cffobjs.c b/src/3rdparty/freetype/src/cff/cffobjs.c index 0e0d5b034b..a2d7aec65e 100644 --- a/src/3rdparty/freetype/src/cff/cffobjs.c +++ b/src/3rdparty/freetype/src/cff/cffobjs.c @@ -4,7 +4,7 @@ /* */ /* OpenType objects manager (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -25,8 +25,15 @@ #include FT_TRUETYPE_IDS_H #include FT_TRUETYPE_TAGS_H #include FT_INTERNAL_SFNT_H -#include FT_CFF_DRIVER_H +#include FT_DRIVER_H +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include FT_MULTIPLE_MASTERS_H +#include FT_SERVICE_MULTIPLE_MASTERS_H +#include FT_SERVICE_METRICS_VARIATIONS_H +#endif + +#include FT_INTERNAL_CFF_OBJECTS_TYPES_H #include "cffobjs.h" #include "cffload.h" #include "cffcmap.h" @@ -34,6 +41,9 @@ #include "cfferrs.h" +#include FT_INTERNAL_POSTSCRIPT_AUX_H +#include FT_SERVICE_CFF_TABLE_LOAD_H + /*************************************************************************/ /* */ @@ -49,9 +59,6 @@ /* */ /* SIZE FUNCTIONS */ /* */ - /* Note that we store the global hints in the size's `internal' root */ - /* field. */ - /* */ /*************************************************************************/ @@ -75,10 +82,11 @@ FT_LOCAL_DEF( void ) cff_size_done( FT_Size cffsize ) /* CFF_Size */ { + FT_Memory memory = cffsize->face->memory; CFF_Size size = (CFF_Size)cffsize; CFF_Face face = (CFF_Face)size->root.face; CFF_Font font = (CFF_Font)face->extra.data; - CFF_Internal internal = (CFF_Internal)cffsize->internal; + CFF_Internal internal = (CFF_Internal)cffsize->internal->module_data; if ( internal ) @@ -98,7 +106,7 @@ funcs->destroy( internal->subfonts[i - 1] ); } - /* `internal' is freed by destroy_size (in ftobjs.c) */ + FT_FREE( internal ); } } @@ -114,7 +122,7 @@ FT_UInt n, count; - FT_MEM_ZERO( priv, sizeof ( *priv ) ); + FT_ZERO( priv ); count = priv->num_blue_values = cpriv->num_blue_values; for ( n = 0; n < count; n++ ) @@ -194,7 +202,7 @@ goto Exit; } - cffsize->internal = (FT_Size_Internal)(void*)internal; + cffsize->internal->module_data = internal; } size->strike_index = 0xFFFFFFFFUL; @@ -224,7 +232,7 @@ { CFF_Face face = (CFF_Face)size->face; CFF_Font font = (CFF_Font)face->extra.data; - CFF_Internal internal = (CFF_Internal)size->internal; + CFF_Internal internal = (CFF_Internal)size->internal->module_data; FT_Long top_upm = (FT_Long)font->top_font.font_dict.units_per_em; FT_UInt i; @@ -296,7 +304,7 @@ { CFF_Face cffface = (CFF_Face)size->face; CFF_Font font = (CFF_Font)cffface->extra.data; - CFF_Internal internal = (CFF_Internal)size->internal; + CFF_Internal internal = (CFF_Internal)size->internal->module_data; FT_Long top_upm = (FT_Long)font->top_font.font_dict.units_per_em; FT_UInt i; @@ -405,7 +413,7 @@ remove_subset_prefix( FT_String* name ) { FT_Int32 idx = 0; - FT_Int32 length = (FT_Int32)strlen( name ) + 1; + FT_Int32 length = (FT_Int32)ft_strlen( name ) + 1; FT_Bool continue_search = 1; @@ -442,15 +450,15 @@ FT_Int32 family_name_length, style_name_length; - family_name_length = (FT_Int32)strlen( family_name ); - style_name_length = (FT_Int32)strlen( style_name ); + family_name_length = (FT_Int32)ft_strlen( family_name ); + style_name_length = (FT_Int32)ft_strlen( style_name ); if ( family_name_length > style_name_length ) { FT_Int idx; - for ( idx = 1; idx <= style_name_length; ++idx ) + for ( idx = 1; idx <= style_name_length; idx++ ) { if ( family_name[family_name_length - idx] != style_name[style_name_length - idx] ) @@ -469,7 +477,7 @@ family_name[idx] == ' ' || family_name[idx] == '_' || family_name[idx] == '+' ) ) - --idx; + idx--; if ( idx > 0 ) family_name[idx + 1] = '\0'; @@ -490,13 +498,16 @@ SFNT_Service sfnt; FT_Service_PsCMaps psnames; PSHinter_Service pshinter; + PSAux_Service psaux; + FT_Service_CFFLoad cffload; FT_Bool pure_cff = 1; + FT_Bool cff2 = 0; FT_Bool sfnt_format = 0; FT_Library library = cffface->driver->root.library; - sfnt = (SFNT_Service)FT_Get_Module_Interface( - library, "sfnt" ); + sfnt = (SFNT_Service)FT_Get_Module_Interface( library, + "sfnt" ); if ( !sfnt ) { FT_ERROR(( "cff_face_init: cannot access `sfnt' module\n" )); @@ -506,8 +517,20 @@ FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); - pshinter = (PSHinter_Service)FT_Get_Module_Interface( - library, "pshinter" ); + pshinter = (PSHinter_Service)FT_Get_Module_Interface( library, + "pshinter" ); + + psaux = (PSAux_Service)FT_Get_Module_Interface( library, + "psaux" ); + if ( !psaux ) + { + FT_ERROR(( "cff_face_init: cannot access `psaux' module\n" )); + error = FT_THROW( Missing_Module ); + goto Exit; + } + face->psaux = psaux; + + FT_FACE_FIND_GLOBAL_SERVICE( face, cffload, CFF_LOAD ); FT_TRACE2(( "CFF driver\n" )); @@ -516,6 +539,7 @@ goto Exit; /* check whether we have a valid OpenType file */ + FT_TRACE2(( " " )); error = sfnt->init_face( stream, face, face_index, num_params, params ); if ( !error ) { @@ -553,8 +577,18 @@ goto Exit; } - /* now load the CFF part of the file */ - error = face->goto_table( face, TTAG_CFF, stream, 0 ); + /* now load the CFF part of the file; */ + /* give priority to CFF2 */ + error = face->goto_table( face, TTAG_CFF2, stream, 0 ); + if ( !error ) + { + cff2 = 1; + face->is_cff2 = cff2; + } + + if ( FT_ERR_EQ( error, Table_Missing ) ) + error = face->goto_table( face, TTAG_CFF, stream, 0 ); + if ( error ) goto Exit; } @@ -579,17 +613,27 @@ goto Exit; face->extra.data = cff; - error = cff_font_load( library, stream, face_index, cff, pure_cff ); + error = cff_font_load( library, + stream, + face_index, + cff, + face, + pure_cff, + cff2 ); if ( error ) goto Exit; /* if we are performing a simple font format check, exit immediately */ /* (this is here for pure CFF) */ if ( face_index < 0 ) + { + cffface->num_faces = (FT_Long)cff->num_faces; return FT_Err_Ok; + } cff->pshinter = pshinter; cff->psnames = psnames; + cff->cffload = cffload; cffface->face_index = face_index & 0xFFFF; @@ -622,22 +666,78 @@ FT_TRACE4(( "SIDs\n" )); /* dump string index, including default strings for convenience */ - for ( idx = 0; idx < cff->num_strings + 390; idx++ ) + for ( idx = 0; idx <= 390; idx++ ) { s = cff_index_get_sid_string( cff, idx ); if ( s ) - FT_TRACE4((" %5d %s\n", idx, s )); + FT_TRACE4(( " %5d %s\n", idx, s )); + } + + /* In Multiple Master CFFs, two SIDs hold the Normalize Design */ + /* Vector (NDV) and Convert Design Vector (CDV) charstrings, */ + /* which may contain NULL bytes in the middle of the data, too. */ + /* We thus access `cff->strings' directly. */ + for ( idx = 1; idx < cff->num_strings; idx++ ) + { + FT_Byte* s1 = cff->strings[idx - 1]; + FT_Byte* s2 = cff->strings[idx]; + FT_PtrDist s1len = s2 - s1 - 1; /* without the final NULL byte */ + FT_PtrDist l; + + + FT_TRACE4(( " %5d ", idx + 390 )); + for ( l = 0; l < s1len; l++ ) + FT_TRACE4(( "%c", s1[l] )); + FT_TRACE4(( "\n" )); + } + + /* print last element */ + if ( cff->num_strings ) + { + FT_Byte* s1 = cff->strings[cff->num_strings - 1]; + FT_Byte* s2 = cff->string_pool + cff->string_pool_size; + FT_PtrDist s1len = s2 - s1 - 1; + FT_PtrDist l; + + + FT_TRACE4(( " %5d ", cff->num_strings + 390 )); + for ( l = 0; l < s1len; l++ ) + FT_TRACE4(( "%c", s1[l] )); + FT_TRACE4(( "\n" )); } } #endif /* FT_DEBUG_LEVEL_TRACE */ +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + { + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + FT_Service_MetricsVariations var = (FT_Service_MetricsVariations)face->var; + + FT_UInt instance_index = (FT_UInt)face_index >> 16; + + + if ( FT_HAS_MULTIPLE_MASTERS( cffface ) && + mm && + instance_index > 0 ) + { + error = mm->set_instance( cffface, instance_index ); + if ( error ) + goto Exit; + + if ( var ) + var->metrics_adjust( cffface ); + } + } +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + if ( !dict->has_font_matrix ) dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM; - /* Normalize the font matrix so that `matrix->yy' is 1; the */ - /* scaling is done with `units_per_em' then (at this point, */ - /* it already contains the scaling factor, but without */ - /* normalization of the matrix). */ + /* Normalize the font matrix so that `matrix->yy' is 1; if */ + /* it is zero, we use `matrix->yx' instead. The scaling is */ + /* done with `units_per_em' then (at this point, it already */ + /* contains the scaling factor, but without normalization */ + /* of the matrix). */ /* */ /* Note that the offsets must be expressed in integer font */ /* units. */ @@ -646,9 +746,12 @@ FT_Matrix* matrix = &dict->font_matrix; FT_Vector* offset = &dict->font_offset; FT_ULong* upm = &dict->units_per_em; - FT_Fixed temp = FT_ABS( matrix->yy ); + FT_Fixed temp; + temp = matrix->yy ? FT_ABS( matrix->yy ) + : FT_ABS( matrix->yx ); + if ( temp != 0x10000L ) { *upm = (FT_ULong)FT_DivFix( (FT_Long)*upm, temp ); @@ -716,7 +819,10 @@ matrix = &sub->font_matrix; offset = &sub->font_offset; upm = &sub->units_per_em; - temp = FT_ABS( matrix->yy ); + + temp = matrix->yy ? FT_ABS( matrix->yy ) + : FT_ABS( matrix->yx ); + if ( temp != 0x10000L ) { @@ -762,7 +868,8 @@ cffface->height = (FT_Short)( ( cffface->units_per_EM * 12 ) / 10 ); if ( cffface->height < cffface->ascender - cffface->descender ) - cffface->height = (FT_Short)( cffface->ascender - cffface->descender ); + cffface->height = (FT_Short)( cffface->ascender - + cffface->descender ); cffface->underline_position = (FT_Short)( dict->underline_position >> 16 ); @@ -770,28 +877,33 @@ (FT_Short)( dict->underline_thickness >> 16 ); /* retrieve font family & style name */ - cffface->family_name = cff_index_get_name( - cff, - (FT_UInt)( face_index & 0xFFFF ) ); + if ( dict->family_name ) + { + char* family_name; + + + family_name = cff_index_get_sid_string( cff, dict->family_name ); + if ( family_name ) + cffface->family_name = cff_strcpy( memory, family_name ); + } + + if ( !cffface->family_name ) + { + cffface->family_name = cff_index_get_name( + cff, + (FT_UInt)( face_index & 0xFFFF ) ); + if ( cffface->family_name ) + remove_subset_prefix( cffface->family_name ); + } + if ( cffface->family_name ) { char* full = cff_index_get_sid_string( cff, dict->full_name ); char* fullp = full; char* family = cffface->family_name; - char* family_name = NULL; - remove_subset_prefix( cffface->family_name ); - - if ( dict->family_name ) - { - family_name = cff_index_get_sid_string( cff, - dict->family_name ); - if ( family_name ) - family = family_name; - } - /* We try to extract the style name from the full name. */ /* We need to ignore spaces and dashes during the search. */ if ( full && family ) @@ -906,7 +1018,6 @@ cffface->style_flags = flags; } - #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */ /* has unset this flag because of the 3.0 `post' table. */ @@ -917,7 +1028,6 @@ if ( dict->cid_registry != 0xFFFFU && pure_cff ) cffface->face_flags |= FT_FACE_FLAG_CID_KEYED; - /*******************************************************************/ /* */ /* Compute char maps. */ @@ -968,7 +1078,7 @@ error = FT_Err_Ok; /* if no Unicode charmap was previously selected, select this one */ - if ( cffface->charmap == NULL && nn != (FT_UInt)cffface->num_charmaps ) + if ( !cffface->charmap && nn != (FT_UInt)cffface->num_charmaps ) cffface->charmap = cffface->charmaps[nn]; Skip_Unicode: @@ -1036,23 +1146,30 @@ FT_FREE( face->extra.data ); } } + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + cff_done_blend( face ); + face->blend = NULL; +#endif } FT_LOCAL_DEF( FT_Error ) cff_driver_init( FT_Module module ) /* CFF_Driver */ { - CFF_Driver driver = (CFF_Driver)module; + PS_Driver driver = (PS_Driver)module; + + FT_UInt32 seed; /* set default property values, cf. `ftcffdrv.h' */ #ifdef CFF_CONFIG_OPTION_OLD_ENGINE - driver->hinting_engine = FT_CFF_HINTING_FREETYPE; + driver->hinting_engine = FT_HINTING_FREETYPE; #else - driver->hinting_engine = FT_CFF_HINTING_ADOBE; + driver->hinting_engine = FT_HINTING_ADOBE; #endif - driver->no_stem_darkening = FALSE; + driver->no_stem_darkening = TRUE; driver->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1; driver->darken_params[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1; @@ -1063,6 +1180,18 @@ driver->darken_params[6] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4; driver->darken_params[7] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4; + /* compute random seed from some memory addresses */ + seed = (FT_UInt32)( (FT_Offset)(char*)&seed ^ + (FT_Offset)(char*)&module ^ + (FT_Offset)(char*)module->memory ); + seed = seed ^ ( seed >> 10 ) ^ ( seed >> 20 ); + + driver->random_seed = (FT_Int32)seed; + if ( driver->random_seed < 0 ) + driver->random_seed = -driver->random_seed; + else if ( driver->random_seed == 0 ) + driver->random_seed = 123456789; + return FT_Err_Ok; } diff --git a/src/3rdparty/freetype/src/cff/cffobjs.h b/src/3rdparty/freetype/src/cff/cffobjs.h index 3cc953143b..616a25b3b5 100644 --- a/src/3rdparty/freetype/src/cff/cffobjs.h +++ b/src/3rdparty/freetype/src/cff/cffobjs.h @@ -4,7 +4,7 @@ /* */ /* OpenType objects manager (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,116 +16,16 @@ /***************************************************************************/ -#ifndef __CFFOBJS_H__ -#define __CFFOBJS_H__ +#ifndef CFFOBJS_H_ +#define CFFOBJS_H_ #include <ft2build.h> -#include FT_INTERNAL_OBJECTS_H -#include "cfftypes.h" -#include FT_INTERNAL_TRUETYPE_TYPES_H -#include FT_SERVICE_POSTSCRIPT_CMAPS_H -#include FT_INTERNAL_POSTSCRIPT_HINTS_H FT_BEGIN_HEADER - /*************************************************************************/ - /* */ - /* <Type> */ - /* CFF_Driver */ - /* */ - /* <Description> */ - /* A handle to an OpenType driver object. */ - /* */ - typedef struct CFF_DriverRec_* CFF_Driver; - - typedef TT_Face CFF_Face; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* CFF_Size */ - /* */ - /* <Description> */ - /* A handle to an OpenType size object. */ - /* */ - typedef struct CFF_SizeRec_ - { - FT_SizeRec root; - FT_ULong strike_index; /* 0xFFFFFFFF to indicate invalid */ - - } CFF_SizeRec, *CFF_Size; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* CFF_GlyphSlot */ - /* */ - /* <Description> */ - /* A handle to an OpenType glyph slot object. */ - /* */ - typedef struct CFF_GlyphSlotRec_ - { - FT_GlyphSlotRec root; - - FT_Bool hint; - FT_Bool scaled; - - FT_Fixed x_scale; - FT_Fixed y_scale; - - } CFF_GlyphSlotRec, *CFF_GlyphSlot; - - - /*************************************************************************/ - /* */ - /* <Type> */ - /* CFF_Internal */ - /* */ - /* <Description> */ - /* The interface to the `internal' field of `FT_Size'. */ - /* */ - typedef struct CFF_InternalRec_ - { - PSH_Globals topfont; - PSH_Globals subfonts[CFF_MAX_CID_FONTS]; - - } CFF_InternalRec, *CFF_Internal; - - - /*************************************************************************/ - /* */ - /* Subglyph transformation record. */ - /* */ - typedef struct CFF_Transform_ - { - FT_Fixed xx, xy; /* transformation matrix coefficients */ - FT_Fixed yx, yy; - FT_F26Dot6 ox, oy; /* offsets */ - - } CFF_Transform; - - - /***********************************************************************/ - /* */ - /* CFF driver class. */ - /* */ - typedef struct CFF_DriverRec_ - { - FT_DriverRec root; - - FT_UInt hinting_engine; - FT_Bool no_stem_darkening; - - FT_Int darken_params[8]; - - } CFF_DriverRec; - - FT_LOCAL( FT_Error ) cff_size_init( FT_Size size ); /* CFF_Size */ @@ -171,15 +71,15 @@ FT_BEGIN_HEADER /* Driver functions */ /* */ FT_LOCAL( FT_Error ) - cff_driver_init( FT_Module module ); /* CFF_Driver */ + cff_driver_init( FT_Module module ); /* PS_Driver */ FT_LOCAL( void ) - cff_driver_done( FT_Module module ); /* CFF_Driver */ + cff_driver_done( FT_Module module ); /* PS_Driver */ FT_END_HEADER -#endif /* __CFFOBJS_H__ */ +#endif /* CFFOBJS_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/cff/cffparse.c b/src/3rdparty/freetype/src/cff/cffparse.c index 063b3517c5..b9611cf548 100644 --- a/src/3rdparty/freetype/src/cff/cffparse.c +++ b/src/3rdparty/freetype/src/cff/cffparse.c @@ -4,7 +4,7 @@ /* */ /* CFF token stream parser (body) */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,9 +20,12 @@ #include "cffparse.h" #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H #include "cfferrs.h" #include "cffpic.h" +#include "cffload.h" /*************************************************************************/ @@ -35,18 +38,52 @@ #define FT_COMPONENT trace_cffparse - FT_LOCAL_DEF( void ) + FT_LOCAL_DEF( FT_Error ) cff_parser_init( CFF_Parser parser, FT_UInt code, void* object, - FT_Library library) + FT_Library library, + FT_UInt stackSize, + FT_UShort num_designs, + FT_UShort num_axes ) { - FT_MEM_ZERO( parser, sizeof ( *parser ) ); + FT_Memory memory = library->memory; /* for FT_NEW_ARRAY */ + FT_Error error; /* for FT_NEW_ARRAY */ + + FT_ZERO( parser ); + +#if 0 parser->top = parser->stack; +#endif parser->object_code = code; parser->object = object; parser->library = library; + parser->num_designs = num_designs; + parser->num_axes = num_axes; + + /* allocate the stack buffer */ + if ( FT_NEW_ARRAY( parser->stack, stackSize ) ) + { + FT_FREE( parser->stack ); + goto Exit; + } + + parser->stackSize = stackSize; + parser->top = parser->stack; /* empty stack */ + + Exit: + return error; + } + + + FT_LOCAL_DEF( void ) + cff_parser_done( CFF_Parser parser ) + { + FT_Memory memory = parser->library->memory; /* for FT_FREE */ + + + FT_FREE( parser->stack ); } @@ -120,6 +157,22 @@ 1000000000L }; + /* maximum values allowed for multiplying */ + /* with the corresponding `power_tens' element */ + static const FT_Long power_ten_limits[] = + { + FT_LONG_MAX / 1L, + FT_LONG_MAX / 10L, + FT_LONG_MAX / 100L, + FT_LONG_MAX / 1000L, + FT_LONG_MAX / 10000L, + FT_LONG_MAX / 100000L, + FT_LONG_MAX / 1000000L, + FT_LONG_MAX / 10000000L, + FT_LONG_MAX / 100000000L, + FT_LONG_MAX / 1000000000L, + }; + /* read a real */ static FT_Fixed @@ -397,28 +450,66 @@ /* read a number, either integer or real */ - static FT_Long - cff_parse_num( FT_Byte** d ) + FT_LOCAL_DEF( FT_Long ) + cff_parse_num( CFF_Parser parser, + FT_Byte** d ) { - return **d == 30 ? ( cff_parse_real( d[0], d[1], 0, NULL ) >> 16 ) - : cff_parse_integer( d[0], d[1] ); + if ( **d == 30 ) + { + /* binary-coded decimal is truncated to integer */ + return cff_parse_real( *d, parser->limit, 0, NULL ) >> 16; + } + + else if ( **d == 255 ) + { + /* 16.16 fixed point is used internally for CFF2 blend results. */ + /* Since these are trusted values, a limit check is not needed. */ + + /* After the 255, 4 bytes give the number. */ + /* The blend value is converted to integer, with rounding; */ + /* due to the right-shift we don't need the lowest byte. */ +#if 0 + return (FT_Short)( + ( ( ( (FT_UInt32)*( d[0] + 1 ) << 24 ) | + ( (FT_UInt32)*( d[0] + 2 ) << 16 ) | + ( (FT_UInt32)*( d[0] + 3 ) << 8 ) | + (FT_UInt32)*( d[0] + 4 ) ) + 0x8000U ) >> 16 ); +#else + return (FT_Short)( + ( ( ( (FT_UInt32)*( d[0] + 1 ) << 16 ) | + ( (FT_UInt32)*( d[0] + 2 ) << 8 ) | + (FT_UInt32)*( d[0] + 3 ) ) + 0x80U ) >> 8 ); +#endif + } + + else + return cff_parse_integer( *d, parser->limit ); } /* read a floating point number, either integer or real */ static FT_Fixed - do_fixed( FT_Byte** d, - FT_Long scaling ) + do_fixed( CFF_Parser parser, + FT_Byte** d, + FT_Long scaling ) { if ( **d == 30 ) - return cff_parse_real( d[0], d[1], scaling, NULL ); + return cff_parse_real( *d, parser->limit, scaling, NULL ); else { - FT_Long val = cff_parse_integer( d[0], d[1] ); + FT_Long val = cff_parse_integer( *d, parser->limit ); if ( scaling ) + { + if ( FT_ABS( val ) > power_ten_limits[scaling] ) + { + val = val > 0 ? 0x7FFFFFFFL : -0x7FFFFFFFL; + goto Overflow; + } + val *= power_tens[scaling]; + } if ( val > 0x7FFF ) { @@ -442,19 +533,21 @@ /* read a floating point number, either integer or real */ static FT_Fixed - cff_parse_fixed( FT_Byte** d ) + cff_parse_fixed( CFF_Parser parser, + FT_Byte** d ) { - return do_fixed( d, 0 ); + return do_fixed( parser, d, 0 ); } /* read a floating point number, either integer or real, */ /* but return `10^scaling' times the number read in */ static FT_Fixed - cff_parse_fixed_scaled( FT_Byte** d, - FT_Long scaling ) + cff_parse_fixed_scaled( CFF_Parser parser, + FT_Byte** d, + FT_Long scaling ) { - return do_fixed( d, scaling ); + return do_fixed( parser, d, scaling ); } @@ -462,13 +555,14 @@ /* and return it as precise as possible -- `scaling' returns */ /* the scaling factor (as a power of 10) */ static FT_Fixed - cff_parse_fixed_dynamic( FT_Byte** d, - FT_Long* scaling ) + cff_parse_fixed_dynamic( CFF_Parser parser, + FT_Byte** d, + FT_Long* scaling ) { FT_ASSERT( scaling ); if ( **d == 30 ) - return cff_parse_real( d[0], d[1], 0, scaling ); + return cff_parse_real( *d, parser->limit, 0, scaling ); else { FT_Long number; @@ -516,7 +610,11 @@ if ( parser->top >= parser->stack + 6 ) { - FT_Long scaling; + FT_Fixed values[6]; + FT_Long scalings[6]; + + FT_Long min_scaling, max_scaling; + int i; error = FT_Err_Ok; @@ -525,22 +623,36 @@ /* We expect a well-formed font matrix, this is, the matrix elements */ /* `xx' and `yy' are of approximately the same magnitude. To avoid */ - /* loss of precision, we use the magnitude of element `xx' to scale */ - /* all other elements. The scaling factor is then contained in the */ - /* `units_per_em' value. */ + /* loss of precision, we use the magnitude of the largest matrix */ + /* element to scale all other elements. The scaling factor is then */ + /* contained in the `units_per_em' value. */ - matrix->xx = cff_parse_fixed_dynamic( data++, &scaling ); + max_scaling = FT_LONG_MIN; + min_scaling = FT_LONG_MAX; - scaling = -scaling; + for ( i = 0; i < 6; i++ ) + { + values[i] = cff_parse_fixed_dynamic( parser, data++, &scalings[i] ); + if ( values[i] ) + { + if ( scalings[i] > max_scaling ) + max_scaling = scalings[i]; + if ( scalings[i] < min_scaling ) + min_scaling = scalings[i]; + } + } - if ( scaling < 0 || scaling > 9 ) + if ( max_scaling < -9 || + max_scaling > 0 || + ( max_scaling - min_scaling ) < 0 || + ( max_scaling - min_scaling ) > 9 ) { /* Return default matrix in case of unlikely values. */ FT_TRACE1(( "cff_parse_font_matrix:" - " strange scaling value for xx element (%d),\n" + " strange scaling values (minimum %d, maximum %d),\n" " " - " using default matrix\n", scaling )); + " using default matrix\n", min_scaling, max_scaling )); matrix->xx = 0x10000L; matrix->yx = 0; @@ -553,13 +665,42 @@ goto Exit; } - matrix->yx = cff_parse_fixed_scaled( data++, scaling ); - matrix->xy = cff_parse_fixed_scaled( data++, scaling ); - matrix->yy = cff_parse_fixed_scaled( data++, scaling ); - offset->x = cff_parse_fixed_scaled( data++, scaling ); - offset->y = cff_parse_fixed_scaled( data, scaling ); + for ( i = 0; i < 6; i++ ) + { + FT_Fixed value = values[i]; + FT_Long divisor, half_divisor; - *upm = (FT_ULong)power_tens[scaling]; + + if ( !value ) + continue; + + divisor = power_tens[max_scaling - scalings[i]]; + half_divisor = divisor >> 1; + + if ( value < 0 ) + { + if ( FT_LONG_MIN + half_divisor < value ) + values[i] = ( value - half_divisor ) / divisor; + else + values[i] = FT_LONG_MIN / divisor; + } + else + { + if ( FT_LONG_MAX - half_divisor > value ) + values[i] = ( value + half_divisor ) / divisor; + else + values[i] = FT_LONG_MAX / divisor; + } + } + + matrix->xx = values[0]; + matrix->yx = values[1]; + matrix->xy = values[2]; + matrix->yy = values[3]; + offset->x = values[4]; + offset->y = values[5]; + + *upm = (FT_ULong)power_tens[-max_scaling]; FT_TRACE4(( " [%f %f %f %f %f %f]\n", (double)matrix->xx / *upm / 65536, @@ -588,10 +729,10 @@ if ( parser->top >= parser->stack + 4 ) { - bbox->xMin = FT_RoundFix( cff_parse_fixed( data++ ) ); - bbox->yMin = FT_RoundFix( cff_parse_fixed( data++ ) ); - bbox->xMax = FT_RoundFix( cff_parse_fixed( data++ ) ); - bbox->yMax = FT_RoundFix( cff_parse_fixed( data ) ); + bbox->xMin = FT_RoundFix( cff_parse_fixed( parser, data++ ) ); + bbox->yMin = FT_RoundFix( cff_parse_fixed( parser, data++ ) ); + bbox->xMax = FT_RoundFix( cff_parse_fixed( parser, data++ ) ); + bbox->yMax = FT_RoundFix( cff_parse_fixed( parser, data ) ); error = FT_Err_Ok; FT_TRACE4(( " [%d %d %d %d]\n", @@ -620,7 +761,7 @@ FT_Long tmp; - tmp = cff_parse_num( data++ ); + tmp = cff_parse_num( parser, data++ ); if ( tmp < 0 ) { FT_ERROR(( "cff_parse_private_dict: Invalid dictionary size\n" )); @@ -629,7 +770,7 @@ } dict->private_size = (FT_ULong)tmp; - tmp = cff_parse_num( data ); + tmp = cff_parse_num( parser, data ); if ( tmp < 0 ) { FT_ERROR(( "cff_parse_private_dict: Invalid dictionary offset\n" )); @@ -649,6 +790,56 @@ } + /* The `MultipleMaster' operator comes before any */ + /* top DICT operators that contain T2 charstrings. */ + + static FT_Error + cff_parse_multiple_master( CFF_Parser parser ) + { + CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; + FT_Error error; + + +#ifdef FT_DEBUG_LEVEL_TRACE + /* beautify tracing message */ + if ( ft_trace_levels[FT_COMPONENT] < 4 ) + FT_TRACE1(( "Multiple Master CFFs not supported yet," + " handling first master design only\n" )); + else + FT_TRACE1(( " (not supported yet," + " handling first master design only)\n" )); +#endif + + error = FT_ERR( Stack_Underflow ); + + /* currently, we handle only the first argument */ + if ( parser->top >= parser->stack + 5 ) + { + FT_Long num_designs = cff_parse_num( parser, parser->stack ); + + + if ( num_designs > 16 || num_designs < 2 ) + { + FT_ERROR(( "cff_parse_multiple_master:" + " Invalid number of designs\n" )); + error = FT_THROW( Invalid_File_Format ); + } + else + { + dict->num_designs = (FT_UShort)num_designs; + dict->num_axes = (FT_UShort)( parser->top - parser->stack - 4 ); + + parser->num_designs = dict->num_designs; + parser->num_axes = dict->num_axes; + + error = FT_Err_Ok; + } + } + + return error; + } + + static FT_Error cff_parse_cid_ros( CFF_Parser parser ) { @@ -661,11 +852,11 @@ if ( parser->top >= parser->stack + 3 ) { - dict->cid_registry = (FT_UInt)cff_parse_num( data++ ); - dict->cid_ordering = (FT_UInt)cff_parse_num( data++ ); + dict->cid_registry = (FT_UInt)cff_parse_num( parser, data++ ); + dict->cid_ordering = (FT_UInt)cff_parse_num( parser, data++ ); if ( **data == 30 ) FT_TRACE1(( "cff_parse_cid_ros: real supplement is rounded\n" )); - dict->cid_supplement = cff_parse_num( data ); + dict->cid_supplement = cff_parse_num( parser, data ); if ( dict->cid_supplement < 0 ) FT_TRACE1(( "cff_parse_cid_ros: negative supplement %d is found\n", dict->cid_supplement )); @@ -681,6 +872,125 @@ } + static FT_Error + cff_parse_vsindex( CFF_Parser parser ) + { + /* vsindex operator can only be used in a Private DICT */ + CFF_Private priv = (CFF_Private)parser->object; + FT_Byte** data = parser->stack; + CFF_Blend blend; + FT_Error error; + + + if ( !priv || !priv->subfont ) + { + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + blend = &priv->subfont->blend; + + if ( blend->usedBV ) + { + FT_ERROR(( " cff_parse_vsindex: vsindex not allowed after blend\n" )); + error = FT_THROW( Syntax_Error ); + goto Exit; + } + + priv->vsindex = (FT_UInt)cff_parse_num( parser, data++ ); + + FT_TRACE4(( " %d\n", priv->vsindex )); + + error = FT_Err_Ok; + + Exit: + return error; + } + + + static FT_Error + cff_parse_blend( CFF_Parser parser ) + { + /* blend operator can only be used in a Private DICT */ + CFF_Private priv = (CFF_Private)parser->object; + CFF_SubFont subFont; + CFF_Blend blend; + FT_UInt numBlends; + FT_Error error; + + + if ( !priv || !priv->subfont ) + { + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + subFont = priv->subfont; + blend = &subFont->blend; + + if ( cff_blend_check_vector( blend, + priv->vsindex, + subFont->lenNDV, + subFont->NDV ) ) + { + error = cff_blend_build_vector( blend, + priv->vsindex, + subFont->lenNDV, + subFont->NDV ); + if ( error ) + goto Exit; + } + + numBlends = (FT_UInt)cff_parse_num( parser, parser->top - 1 ); + if ( numBlends > parser->stackSize ) + { + FT_ERROR(( "cff_parse_blend: Invalid number of blends\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + FT_TRACE4(( " %d value%s blended\n", + numBlends, + numBlends == 1 ? "" : "s" )); + + error = cff_blend_doBlend( subFont, parser, numBlends ); + + blend->usedBV = TRUE; + + Exit: + return error; + } + + + /* maxstack operator increases parser and operand stacks for CFF2 */ + static FT_Error + cff_parse_maxstack( CFF_Parser parser ) + { + /* maxstack operator can only be used in a Top DICT */ + CFF_FontRecDict dict = (CFF_FontRecDict)parser->object; + FT_Byte** data = parser->stack; + FT_Error error = FT_Err_Ok; + + + if ( !dict ) + { + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + dict->maxstack = (FT_UInt)cff_parse_num( parser, data++ ); + if ( dict->maxstack > CFF2_MAX_STACK ) + dict->maxstack = CFF2_MAX_STACK; + if ( dict->maxstack < CFF2_DEFAULT_STACK ) + dict->maxstack = CFF2_DEFAULT_STACK; + + FT_TRACE4(( " %d\n", dict->maxstack )); + + Exit: + return error; + } + + #define CFF_FIELD_NUM( code, name, id ) \ CFF_FIELD( code, name, id, cff_kind_num ) #define CFF_FIELD_FIXED( code, name, id ) \ @@ -692,9 +1002,6 @@ #define CFF_FIELD_BOOL( code, name, id ) \ CFF_FIELD( code, name, id, cff_kind_bool ) -#define CFFCODE_TOPDICT 0x1000 -#define CFFCODE_PRIVATE 0x2000 - #ifndef FT_CONFIG_OPTION_PIC @@ -715,6 +1022,15 @@ 0, 0 \ }, +#define CFF_FIELD_BLEND( code, id ) \ + { \ + cff_kind_blend, \ + code | CFFCODE, \ + 0, 0, \ + cff_parse_blend, \ + 0, 0 \ + }, + #define CFF_FIELD( code, name, id, kind ) \ { \ kind, \ @@ -758,6 +1074,16 @@ id \ }, +#define CFF_FIELD_BLEND( code, id ) \ + { \ + cff_kind_blend, \ + code | CFFCODE, \ + 0, 0, \ + cff_parse_blend, \ + 0, 0, \ + id \ + }, + #define CFF_FIELD( code, name, id, kind ) \ { \ kind, \ @@ -824,6 +1150,8 @@ #define CFF_FIELD_DELTA( code, name, max, id ) i++; #undef CFF_FIELD_CALLBACK #define CFF_FIELD_CALLBACK( code, name, id ) i++; +#undef CFF_FIELD_BLEND +#define CFF_FIELD_BLEND( code, id ) i++; #include "cfftoken.h" @@ -871,6 +1199,17 @@ clazz[i].count_offset = FT_FIELD_OFFSET( num_ ## name_ ); \ i++; +#undef CFF_FIELD_BLEND +#define CFF_FIELD_BLEND( code_, id_ ) \ + clazz[i].kind = cff_kind_blend; \ + clazz[i].code = code_ | CFFCODE; \ + clazz[i].offset = 0; \ + clazz[i].size = 0; \ + clazz[i].reader = cff_parse_blend; \ + clazz[i].array_max = 0; \ + clazz[i].count_offset = 0; \ + i++; + #include "cfftoken.h" clazz[i].kind = 0; @@ -921,6 +1260,18 @@ clazz[i].id = id_; \ i++; +#undef CFF_FIELD_BLEND +#define CFF_FIELD_BLEND( code_, id_ ) \ + clazz[i].kind = cff_kind_blend; \ + clazz[i].code = code_ | CFFCODE; \ + clazz[i].offset = 0; \ + clazz[i].size = 0; \ + clazz[i].reader = cff_parse_blend; \ + clazz[i].array_max = 0; \ + clazz[i].count_offset = 0; \ + clazz[i].id = id_; \ + i++; + #include "cfftoken.h" clazz[i].kind = 0; @@ -950,9 +1301,14 @@ FT_Byte* start, FT_Byte* limit ) { +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + PSAux_Service psaux; +#endif + FT_Byte* p = start; FT_Error error = FT_Err_Ok; FT_Library library = parser->library; + FT_UNUSED( library ); @@ -965,14 +1321,16 @@ { FT_UInt v = *p; - - if ( v >= 27 && v != 31 ) + /* Opcode 31 is legacy MM T2 operator, not a number. */ + /* Opcode 255 is reserved and should not appear in fonts; */ + /* it is used internally for CFF2 blends. */ + if ( v >= 27 && v != 31 && v != 255 ) { /* it's a number; we will push its position on the stack */ - if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH ) + if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize ) goto Stack_Overflow; - *parser->top ++ = p; + *parser->top++ = p; /* now, skip it */ if ( v == 30 ) @@ -1001,19 +1359,159 @@ else if ( v > 246 ) p += 1; } +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + else if ( v == 31 ) + { + /* a Type 2 charstring */ + + CFF_Decoder decoder; + CFF_FontRec cff_rec; + FT_Byte* charstring_base; + FT_ULong charstring_len; + + FT_Fixed* stack; + FT_Byte* q; + + + charstring_base = ++p; + + /* search `endchar' operator */ + for (;;) + { + if ( p >= limit ) + goto Exit; + if ( *p == 14 ) + break; + p++; + } + + charstring_len = (FT_ULong)( p - charstring_base ) + 1; + + /* construct CFF_Decoder object */ + FT_ZERO( &decoder ); + FT_ZERO( &cff_rec ); + + cff_rec.top_font.font_dict.num_designs = parser->num_designs; + cff_rec.top_font.font_dict.num_axes = parser->num_axes; + decoder.cff = &cff_rec; + + psaux = (PSAux_Service)FT_Get_Module_Interface( library, "psaux" ); + if ( !psaux ) + { + FT_ERROR(( "cff_parser_run: cannot access `psaux' module\n" )); + error = FT_THROW( Missing_Module ); + goto Exit; + } + + error = psaux->cff_decoder_funcs->parse_charstrings_old( + &decoder, charstring_base, charstring_len, 1 ); + + /* Now copy the stack data in the temporary decoder object, */ + /* converting it back to charstring number representations */ + /* (this is ugly, I know). */ + /* */ + /* We overwrite the original top DICT charstring under the */ + /* assumption that the charstring representation of the result */ + /* of `cff_decoder_parse_charstrings' is shorter, which should */ + /* be always true. */ + + q = charstring_base - 1; + stack = decoder.stack; + + while ( stack < decoder.top ) + { + FT_ULong num; + FT_Bool neg; + + + if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize ) + goto Stack_Overflow; + + *parser->top++ = q; + + if ( *stack < 0 ) + { + num = (FT_ULong)-*stack; + neg = 1; + } + else + { + num = (FT_ULong)*stack; + neg = 0; + } + + if ( num & 0xFFFFU ) + { + if ( neg ) + num = (FT_ULong)-num; + + *q++ = 255; + *q++ = ( num & 0xFF000000U ) >> 24; + *q++ = ( num & 0x00FF0000U ) >> 16; + *q++ = ( num & 0x0000FF00U ) >> 8; + *q++ = num & 0x000000FFU; + } + else + { + num >>= 16; + + if ( neg ) + { + if ( num <= 107 ) + *q++ = (FT_Byte)( 139 - num ); + else if ( num <= 1131 ) + { + *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 251 ); + *q++ = (FT_Byte)( ( num - 108 ) & 0xFF ); + } + else + { + num = (FT_ULong)-num; + + *q++ = 28; + *q++ = (FT_Byte)( num >> 8 ); + *q++ = (FT_Byte)( num & 0xFF ); + } + } + else + { + if ( num <= 107 ) + *q++ = (FT_Byte)( num + 139 ); + else if ( num <= 1131 ) + { + *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 247 ); + *q++ = (FT_Byte)( ( num - 108 ) & 0xFF ); + } + else + { + *q++ = 28; + *q++ = (FT_Byte)( num >> 8 ); + *q++ = (FT_Byte)( num & 0xFF ); + } + } + } + + stack++; + } + } +#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ else { /* This is not a number, hence it's an operator. Compute its code */ /* and look for it in our current list. */ FT_UInt code; - FT_UInt num_args = (FT_UInt) - ( parser->top - parser->stack ); + FT_UInt num_args; const CFF_Field_Handler* field; + if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize ) + goto Stack_Overflow; + + num_args = (FT_UInt)( parser->top - parser->stack ); *parser->top = p; - code = v; + code = v; + if ( v == 12 ) { /* two byte operator */ @@ -1048,15 +1546,15 @@ case cff_kind_bool: case cff_kind_string: case cff_kind_num: - val = cff_parse_num( parser->stack ); + val = cff_parse_num( parser, parser->stack ); goto Store_Number; case cff_kind_fixed: - val = cff_parse_fixed( parser->stack ); + val = cff_parse_fixed( parser, parser->stack ); goto Store_Number; case cff_kind_fixed_thousand: - val = cff_parse_fixed_scaled( parser->stack, 3 ); + val = cff_parse_fixed_scaled( parser, parser->stack, 3 ); Store_Number: switch ( field->size ) @@ -1125,7 +1623,7 @@ val = 0; while ( num_args > 0 ) { - val += cff_parse_num( data++ ); + val = ADD_LONG( val, cff_parse_num( parser, data++ ) ); switch ( field->size ) { case (8 / FT_CHAR_BIT): @@ -1154,7 +1652,7 @@ } break; - default: /* callback */ + default: /* callback or blend */ error = field->reader( parser ); if ( error ) goto Exit; @@ -1168,7 +1666,10 @@ Found: /* clear stack */ - parser->top = parser->stack; + /* TODO: could clear blend stack here, */ + /* but we don't have access to subFont */ + if ( field->kind != cff_kind_blend ) + parser->top = parser->stack; } p++; } diff --git a/src/3rdparty/freetype/src/cff/cffparse.h b/src/3rdparty/freetype/src/cff/cffparse.h index 8ad02ea1e2..8a8caeca44 100644 --- a/src/3rdparty/freetype/src/cff/cffparse.h +++ b/src/3rdparty/freetype/src/cff/cffparse.h @@ -4,7 +4,7 @@ /* */ /* CFF token stream parser (specification) */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,45 +16,74 @@ /***************************************************************************/ -#ifndef __CFF_PARSE_H__ -#define __CFF_PARSE_H__ +#ifndef CFFPARSE_H_ +#define CFFPARSE_H_ #include <ft2build.h> -#include "cfftypes.h" +#include FT_INTERNAL_CFF_TYPES_H #include FT_INTERNAL_OBJECTS_H FT_BEGIN_HEADER + /* CFF uses constant parser stack size; */ + /* CFF2 can increase from default 193 */ #define CFF_MAX_STACK_DEPTH 96 -#define CFF_CODE_TOPDICT 0x1000 -#define CFF_CODE_PRIVATE 0x2000 + /* + * There are plans to remove the `maxstack' operator in a forthcoming + * revision of the CFF2 specification, increasing the (then static) stack + * size to 513. By making the default stack size equal to the maximum + * stack size, the operator is essentially disabled, which has the + * desired effect in FreeType. + */ +#define CFF2_MAX_STACK 513 +#define CFF2_DEFAULT_STACK 513 + +#define CFF_CODE_TOPDICT 0x1000 +#define CFF_CODE_PRIVATE 0x2000 +#define CFF2_CODE_TOPDICT 0x3000 +#define CFF2_CODE_FONTDICT 0x4000 +#define CFF2_CODE_PRIVATE 0x5000 typedef struct CFF_ParserRec_ { - FT_Library library; - FT_Byte* start; - FT_Byte* limit; - FT_Byte* cursor; + FT_Library library; + FT_Byte* start; + FT_Byte* limit; + FT_Byte* cursor; - FT_Byte* stack[CFF_MAX_STACK_DEPTH + 1]; - FT_Byte** top; + FT_Byte** stack; + FT_Byte** top; + FT_UInt stackSize; /* allocated size */ - FT_UInt object_code; - void* object; + FT_UInt object_code; + void* object; + + FT_UShort num_designs; /* a copy of `CFF_FontRecDict->num_designs' */ + FT_UShort num_axes; /* a copy of `CFF_FontRecDict->num_axes' */ } CFF_ParserRec, *CFF_Parser; - FT_LOCAL( void ) + FT_LOCAL( FT_Long ) + cff_parse_num( CFF_Parser parser, + FT_Byte** d ); + + FT_LOCAL( FT_Error ) cff_parser_init( CFF_Parser parser, FT_UInt code, void* object, - FT_Library library); + FT_Library library, + FT_UInt stackSize, + FT_UShort num_designs, + FT_UShort num_axes ); + + FT_LOCAL( void ) + cff_parser_done( CFF_Parser parser ); FT_LOCAL( FT_Error ) cff_parser_run( CFF_Parser parser, @@ -72,6 +101,7 @@ FT_BEGIN_HEADER cff_kind_bool, cff_kind_delta, cff_kind_callback, + cff_kind_blend, cff_kind_max /* do not remove */ }; @@ -100,7 +130,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CFF_PARSE_H__ */ +#endif /* CFFPARSE_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/cff/cffpic.c b/src/3rdparty/freetype/src/cff/cffpic.c index d40dec50e9..08b74c7cf2 100644 --- a/src/3rdparty/freetype/src/cff/cffpic.c +++ b/src/3rdparty/freetype/src/cff/cffpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for cff module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2018 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/src/cff/cffpic.h b/src/3rdparty/freetype/src/cff/cffpic.h index 9a221a7b7e..8ba4203a8d 100644 --- a/src/3rdparty/freetype/src/cff/cffpic.h +++ b/src/3rdparty/freetype/src/cff/cffpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for cff module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2018 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,13 +16,12 @@ /***************************************************************************/ -#ifndef __CFFPIC_H__ -#define __CFFPIC_H__ +#ifndef CFFPIC_H_ +#define CFFPIC_H_ #include FT_INTERNAL_PIC_H - #ifndef FT_CONFIG_OPTION_PIC #define CFF_SERVICE_PS_INFO_GET cff_service_ps_info @@ -32,6 +31,9 @@ #define CFF_SERVICE_CID_INFO_GET cff_service_cid_info #define CFF_SERVICE_PROPERTIES_GET cff_service_properties #define CFF_SERVICES_GET cff_services +#define CFF_SERVICE_MULTI_MASTERS_GET cff_service_multi_masters +#define CFF_SERVICE_METRICS_VAR_GET cff_service_metrics_variations +#define CFF_SERVICE_CFF_LOAD_GET cff_service_cff_load #define CFF_CMAP_ENCODING_CLASS_REC_GET cff_cmap_encoding_class_rec #define CFF_CMAP_UNICODE_CLASS_REC_GET cff_cmap_unicode_class_rec #define CFF_FIELD_HANDLERS_GET cff_field_handlers @@ -45,22 +47,27 @@ #include FT_SERVICE_TT_CMAP_H #include FT_SERVICE_CID_H #include FT_SERVICE_PROPERTIES_H +#include FT_SERVICE_MULTIPLE_MASTERS_H +#include FT_SERVICE_METRICS_VARIATIONS_H FT_BEGIN_HEADER typedef struct CffModulePIC_ { - FT_ServiceDescRec* cff_services; - CFF_Field_Handler* cff_field_handlers; - FT_Service_PsInfoRec cff_service_ps_info; - FT_Service_GlyphDictRec cff_service_glyph_dict; - FT_Service_PsFontNameRec cff_service_ps_name; - FT_Service_TTCMapsRec cff_service_get_cmap_info; - FT_Service_CIDRec cff_service_cid_info; - FT_Service_PropertiesRec cff_service_properties; - FT_CMap_ClassRec cff_cmap_encoding_class_rec; - FT_CMap_ClassRec cff_cmap_unicode_class_rec; + FT_ServiceDescRec* cff_services; + CFF_Field_Handler* cff_field_handlers; + FT_Service_PsInfoRec cff_service_ps_info; + FT_Service_GlyphDictRec cff_service_glyph_dict; + FT_Service_PsFontNameRec cff_service_ps_name; + FT_Service_TTCMapsRec cff_service_get_cmap_info; + FT_Service_CIDRec cff_service_cid_info; + FT_Service_PropertiesRec cff_service_properties; + FT_Service_MultiMastersRec cff_service_multi_masters; + FT_Service_MetricsVariationsRec cff_service_metrics_variations; + FT_Service_CFFLoadRec cff_service_cff_load; + FT_CMap_ClassRec cff_cmap_encoding_class_rec; + FT_CMap_ClassRec cff_cmap_unicode_class_rec; } CffModulePIC; @@ -82,6 +89,12 @@ FT_BEGIN_HEADER ( GET_PIC( library )->cff_service_properties ) #define CFF_SERVICES_GET \ ( GET_PIC( library )->cff_services ) +#define CFF_SERVICE_MULTI_MASTERS_GET \ + ( GET_PIC( library )->cff_service_multi_masters ) +#define CFF_SERVICE_METRICS_VAR_GET \ + ( GET_PIC( library )->cff_service_metrics_variations ) +#define CFF_SERVICE_CFF_LOAD_GET \ + ( GET_PIC( library )->cff_service_cff_load ) #define CFF_CMAP_ENCODING_CLASS_REC_GET \ ( GET_PIC( library )->cff_cmap_encoding_class_rec ) #define CFF_CMAP_UNICODE_CLASS_REC_GET \ @@ -102,7 +115,7 @@ FT_END_HEADER /* */ -#endif /* __CFFPIC_H__ */ +#endif /* CFFPIC_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/cff/cfftoken.h b/src/3rdparty/freetype/src/cff/cfftoken.h index 5b32076ab8..fec1ca20bd 100644 --- a/src/3rdparty/freetype/src/cff/cfftoken.h +++ b/src/3rdparty/freetype/src/cff/cfftoken.h @@ -4,7 +4,7 @@ /* */ /* CFF token definitions (specification only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,7 +20,7 @@ #define FT_STRUCTURE CFF_FontRecDictRec #undef CFFCODE -#define CFFCODE CFFCODE_TOPDICT +#define CFFCODE CFF_CODE_TOPDICT CFF_FIELD_STRING ( 0, version, "Version" ) CFF_FIELD_STRING ( 1, notice, "Notice" ) @@ -38,6 +38,9 @@ CFF_FIELD_NUM ( 13, unique_id, "UniqueID" ) CFF_FIELD_CALLBACK( 5, font_bbox, "FontBBox" ) CFF_FIELD_NUM ( 0x108, stroke_width, "StrokeWidth" ) +#if 0 + CFF_FIELD_DELTA ( 14, xuid, 16, "XUID" ) +#endif CFF_FIELD_NUM ( 15, charset_offset, "charset" ) CFF_FIELD_NUM ( 16, encoding_offset, "Encoding" ) CFF_FIELD_NUM ( 17, charstrings_offset, "CharStrings" ) @@ -48,8 +51,13 @@ #if 0 CFF_FIELD_STRING ( 0x116, base_font_name, "BaseFontName" ) CFF_FIELD_DELTA ( 0x117, base_font_blend, 16, "BaseFontBlend" ) +#endif + + /* the next two operators were removed from the Type2 specification */ + /* in version 16-March-2000 */ CFF_FIELD_CALLBACK( 0x118, multiple_master, "MultipleMaster" ) - CFF_FIELD_CALLBACK( 0x119, blend_axis_types, "BlendAxisTypes" ) +#if 0 + CFF_FIELD_CALLBACK( 0x11A, blend_axis_types, "BlendAxisTypes" ) #endif CFF_FIELD_CALLBACK( 0x11E, cid_ros, "ROS" ) @@ -70,7 +78,7 @@ #undef FT_STRUCTURE #define FT_STRUCTURE CFF_PrivateRec #undef CFFCODE -#define CFFCODE CFFCODE_PRIVATE +#define CFFCODE CFF_CODE_PRIVATE CFF_FIELD_DELTA ( 6, blue_values, 14, "BlueValues" ) CFF_FIELD_DELTA ( 7, other_blues, 10, "OtherBlues" ) @@ -94,4 +102,49 @@ CFF_FIELD_NUM ( 21, nominal_width, "nominalWidthX" ) +#undef FT_STRUCTURE +#define FT_STRUCTURE CFF_FontRecDictRec +#undef CFFCODE +#define CFFCODE CFF2_CODE_TOPDICT + + CFF_FIELD_CALLBACK( 0x107, font_matrix, "FontMatrix" ) + CFF_FIELD_NUM ( 17, charstrings_offset, "CharStrings" ) + CFF_FIELD_NUM ( 0x124, cid_fd_array_offset, "FDArray" ) + CFF_FIELD_NUM ( 0x125, cid_fd_select_offset, "FDSelect" ) + CFF_FIELD_NUM ( 24, vstore_offset, "vstore" ) + CFF_FIELD_CALLBACK( 25, maxstack, "maxstack" ) + + +#undef FT_STRUCTURE +#define FT_STRUCTURE CFF_FontRecDictRec +#undef CFFCODE +#define CFFCODE CFF2_CODE_FONTDICT + + CFF_FIELD_CALLBACK( 18, private_dict, "Private" ) + CFF_FIELD_CALLBACK( 0x107, font_matrix, "FontMatrix" ) + + +#undef FT_STRUCTURE +#define FT_STRUCTURE CFF_PrivateRec +#undef CFFCODE +#define CFFCODE CFF2_CODE_PRIVATE + + CFF_FIELD_DELTA ( 6, blue_values, 14, "BlueValues" ) + CFF_FIELD_DELTA ( 7, other_blues, 10, "OtherBlues" ) + CFF_FIELD_DELTA ( 8, family_blues, 14, "FamilyBlues" ) + CFF_FIELD_DELTA ( 9, family_other_blues, 10, "FamilyOtherBlues" ) + CFF_FIELD_FIXED_1000( 0x109, blue_scale, "BlueScale" ) + CFF_FIELD_NUM ( 0x10A, blue_shift, "BlueShift" ) + CFF_FIELD_NUM ( 0x10B, blue_fuzz, "BlueFuzz" ) + CFF_FIELD_NUM ( 10, standard_width, "StdHW" ) + CFF_FIELD_NUM ( 11, standard_height, "StdVW" ) + CFF_FIELD_DELTA ( 0x10C, snap_widths, 13, "StemSnapH" ) + CFF_FIELD_DELTA ( 0x10D, snap_heights, 13, "StemSnapV" ) + CFF_FIELD_NUM ( 0x111, language_group, "LanguageGroup" ) + CFF_FIELD_FIXED ( 0x112, expansion_factor, "ExpansionFactor" ) + CFF_FIELD_CALLBACK ( 22, vsindex, "vsindex" ) + CFF_FIELD_BLEND ( 23, "blend" ) + CFF_FIELD_NUM ( 19, local_subrs_offset, "Subrs" ) + + /* END */ diff --git a/src/3rdparty/freetype/src/cff/module.mk b/src/3rdparty/freetype/src/cff/module.mk index ba08ebcb79..8013d5dcab 100644 --- a/src/3rdparty/freetype/src/cff/module.mk +++ b/src/3rdparty/freetype/src/cff/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2015 by +# Copyright 1996-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/cff/rules.mk b/src/3rdparty/freetype/src/cff/rules.mk index 7f6e857e28..bce672927e 100644 --- a/src/3rdparty/freetype/src/cff/rules.mk +++ b/src/3rdparty/freetype/src/cff/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2015 by +# Copyright 1996-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -32,27 +32,14 @@ CFF_DRV_SRC := $(CFF_DIR)/cffcmap.c \ $(CFF_DIR)/cffload.c \ $(CFF_DIR)/cffobjs.c \ $(CFF_DIR)/cffparse.c \ - $(CFF_DIR)/cffpic.c \ - $(CFF_DIR)/cf2arrst.c \ - $(CFF_DIR)/cf2blues.c \ - $(CFF_DIR)/cf2error.c \ - $(CFF_DIR)/cf2font.c \ - $(CFF_DIR)/cf2ft.c \ - $(CFF_DIR)/cf2hints.c \ - $(CFF_DIR)/cf2intrp.c \ - $(CFF_DIR)/cf2read.c \ - $(CFF_DIR)/cf2stack.c + $(CFF_DIR)/cffpic.c # CFF driver headers # CFF_DRV_H := $(CFF_DRV_SRC:%.c=%.h) \ $(CFF_DIR)/cfferrs.h \ - $(CFF_DIR)/cfftoken.h \ - $(CFF_DIR)/cfftypes.h \ - $(CFF_DIR)/cf2fixed.h \ - $(CFF_DIR)/cf2glue.h \ - $(CFF_DIR)/cf2types.h + $(CFF_DIR)/cfftoken.h # CFF driver object(s) diff --git a/src/3rdparty/freetype/src/cid/Jamfile b/src/3rdparty/freetype/src/cid/Jamfile index 64e1523157..1c232fda3f 100644 --- a/src/3rdparty/freetype/src/cid/Jamfile +++ b/src/3rdparty/freetype/src/cid/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/cid Jamfile # -# Copyright 2001-2015 by +# Copyright 2001-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/cid/ciderrs.h b/src/3rdparty/freetype/src/cid/ciderrs.h index 5e0e776ee1..a5a86e3fc6 100644 --- a/src/3rdparty/freetype/src/cid/ciderrs.h +++ b/src/3rdparty/freetype/src/cid/ciderrs.h @@ -4,7 +4,7 @@ /* */ /* CID error codes (specification only). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __CIDERRS_H__ -#define __CIDERRS_H__ +#ifndef CIDERRS_H_ +#define CIDERRS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX CID_Err_ @@ -35,7 +35,7 @@ #include FT_ERRORS_H -#endif /* __CIDERRS_H__ */ +#endif /* CIDERRS_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/cid/cidgload.c b/src/3rdparty/freetype/src/cid/cidgload.c index d00674fe0d..d14f9a2cc9 100644 --- a/src/3rdparty/freetype/src/cid/cidgload.c +++ b/src/3rdparty/freetype/src/cid/cidgload.c @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 Glyph Loader (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,6 +24,10 @@ #include FT_OUTLINE_H #include FT_INTERNAL_CALC_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H +#include FT_INTERNAL_CFF_TYPES_H +#include FT_DRIVER_H + #include "ciderrs.h" @@ -52,9 +56,11 @@ FT_ULong glyph_length = 0; PSAux_Service psaux = (PSAux_Service)face->psaux; + FT_Bool force_scaling = FALSE; + #ifdef FT_CONFIG_OPTION_INCREMENTAL - FT_Incremental_InterfaceRec *inc = - face->root.internal->incremental_interface; + FT_Incremental_InterfaceRec *inc = + face->root.internal->incremental_interface; #endif @@ -100,7 +106,7 @@ /* and charstring offset from the CIDMap. */ { FT_UInt entry_len = (FT_UInt)( cid->fd_bytes + cid->gd_bytes ); - FT_ULong off1; + FT_ULong off1, off2; if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset + @@ -108,18 +114,23 @@ FT_FRAME_ENTER( 2 * entry_len ) ) goto Exit; - p = (FT_Byte*)stream->cursor; - fd_select = cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); - off1 = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ); - p += cid->fd_bytes; - glyph_length = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ) - off1; + p = (FT_Byte*)stream->cursor; + fd_select = cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); + off1 = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ); + p += cid->fd_bytes; + off2 = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ); FT_FRAME_EXIT(); - if ( fd_select >= (FT_ULong)cid->num_dicts ) + if ( fd_select >= (FT_ULong)cid->num_dicts || + off2 > stream->size || + off1 > off2 ) { + FT_TRACE0(( "cid_load_glyph: invalid glyph stream offsets\n" )); error = FT_THROW( Invalid_Offset ); goto Exit; } + + glyph_length = off2 - off1; if ( glyph_length == 0 ) goto Exit; if ( FT_ALLOC( charstring, glyph_length ) ) @@ -137,9 +148,10 @@ /* Set up subrs */ - decoder->num_subrs = cid_subrs->num_subrs; - decoder->subrs = cid_subrs->code; - decoder->subrs_len = 0; + decoder->num_subrs = cid_subrs->num_subrs; + decoder->subrs = cid_subrs->code; + decoder->subrs_len = 0; + decoder->subrs_hash = NULL; /* Set up font matrix */ dict = cid->font_dicts + fd_select; @@ -152,17 +164,69 @@ /* Adjustment for seed bytes. */ cs_offset = decoder->lenIV >= 0 ? (FT_UInt)decoder->lenIV : 0; + if ( cs_offset > glyph_length ) + { + FT_TRACE0(( "cid_load_glyph: invalid glyph stream offsets\n" )); + error = FT_THROW( Invalid_Offset ); + goto Exit; + } /* Decrypt only if lenIV >= 0. */ if ( decoder->lenIV >= 0 ) psaux->t1_decrypt( charstring, glyph_length, 4330 ); - error = decoder->funcs.parse_charstrings( - decoder, charstring + cs_offset, - glyph_length - cs_offset ); - } + /* choose which renderer to use */ +#ifdef T1_CONFIG_OPTION_OLD_ENGINE + if ( ( (PS_Driver)FT_FACE_DRIVER( face ) )->hinting_engine == + FT_HINTING_FREETYPE || + decoder->builder.metrics_only ) + error = psaux->t1_decoder_funcs->parse_charstrings_old( + decoder, + charstring + cs_offset, + glyph_length - cs_offset ); +#else + if ( decoder->builder.metrics_only ) + error = psaux->t1_decoder_funcs->parse_metrics( + decoder, + charstring + cs_offset, + glyph_length - cs_offset ); +#endif + else + { + PS_Decoder psdecoder; + CFF_SubFontRec subfont; - FT_FREE( charstring ); + + psaux->ps_decoder_init( &psdecoder, decoder, TRUE ); + + psaux->t1_make_subfont( FT_FACE( face ), + &dict->private_dict, + &subfont ); + psdecoder.current_subfont = &subfont; + + error = psaux->t1_decoder_funcs->parse_charstrings( + &psdecoder, + charstring + cs_offset, + glyph_length - cs_offset ); + + /* Adobe's engine uses 16.16 numbers everywhere; */ + /* as a consequence, glyphs larger than 2000ppem get rejected */ + if ( FT_ERR_EQ( error, Glyph_Too_Big ) ) + { + /* this time, we retry unhinted and scale up the glyph later on */ + /* (the engine uses and sets the hardcoded value 0x10000 / 64 = */ + /* 0x400 for both `x_scale' and `y_scale' in this case) */ + ((CID_GlyphSlot)decoder->builder.glyph)->hint = FALSE; + + force_scaling = TRUE; + + error = psaux->t1_decoder_funcs->parse_charstrings( + &psdecoder, + charstring + cs_offset, + glyph_length - cs_offset ); + } + } + } #ifdef FT_CONFIG_OPTION_INCREMENTAL @@ -188,6 +252,10 @@ #endif /* FT_CONFIG_OPTION_INCREMENTAL */ Exit: + FT_FREE( charstring ); + + ((CID_GlyphSlot)decoder->builder.glyph)->scaled = force_scaling; + return error; } @@ -276,10 +344,12 @@ T1_DecoderRec decoder; CID_Face face = (CID_Face)cidglyph->face; FT_Bool hinting; + FT_Bool scaled; PSAux_Service psaux = (PSAux_Service)face->psaux; FT_Matrix font_matrix; FT_Vector font_offset; + FT_Bool must_finish_decoder = FALSE; if ( glyph_index >= (FT_UInt)face->root.num_glyphs ) @@ -299,7 +369,10 @@ hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 && ( load_flags & FT_LOAD_NO_HINTING ) == 0 ); + scaled = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ); + glyph->hint = hinting; + glyph->scaled = scaled; cidglyph->format = FT_GLYPH_FORMAT_OUTLINE; error = psaux->t1_decoder_funcs->init( &decoder, @@ -317,6 +390,8 @@ /* TODO: initialize decoder.len_buildchar and decoder.buildchar */ /* if we ever support CID-keyed multiple master fonts */ + must_finish_decoder = TRUE; + /* set up the decoder */ decoder.builder.no_recurse = FT_BOOL( ( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 ) ); @@ -325,12 +400,18 @@ if ( error ) goto Exit; + /* copy flags back for forced scaling */ + hinting = glyph->hint; + scaled = glyph->scaled; + font_matrix = decoder.font_matrix; font_offset = decoder.font_offset; /* save new glyph tables */ psaux->t1_decoder_funcs->done( &decoder ); + must_finish_decoder = FALSE; + /* now set the metrics -- this is rather simple, as */ /* the left side bearing is the xMin, and the top side */ /* bearing the yMax */ @@ -398,7 +479,7 @@ metrics->vertAdvance += font_offset.y; } - if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) + if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || scaled ) { /* scale the outline and the metrics */ FT_Int n; @@ -439,6 +520,10 @@ } Exit: + + if ( must_finish_decoder ) + psaux->t1_decoder_funcs->done( &decoder ); + return error; } diff --git a/src/3rdparty/freetype/src/cid/cidgload.h b/src/3rdparty/freetype/src/cid/cidgload.h index 4a10ce505c..4811852ae4 100644 --- a/src/3rdparty/freetype/src/cid/cidgload.h +++ b/src/3rdparty/freetype/src/cid/cidgload.h @@ -4,7 +4,7 @@ /* */ /* OpenType Glyph Loader (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CIDGLOAD_H__ -#define __CIDGLOAD_H__ +#ifndef CIDGLOAD_H_ +#define CIDGLOAD_H_ #include <ft2build.h> @@ -45,7 +45,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CIDGLOAD_H__ */ +#endif /* CIDGLOAD_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/cid/cidload.c b/src/3rdparty/freetype/src/cid/cidload.c index e23b82f673..27cd09b3c3 100644 --- a/src/3rdparty/freetype/src/cid/cidload.c +++ b/src/3rdparty/freetype/src/cid/cidload.c @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 font loader (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -215,6 +215,7 @@ { CID_FaceInfo cid = &face->cid; FT_Memory memory = face->root.memory; + FT_Stream stream = parser->stream; FT_Error error = FT_Err_Ok; FT_Long num_dicts; @@ -227,6 +228,31 @@ goto Exit; } + /* + * A single entry in the FDArray must (at least) contain the following + * structure elements. + * + * %ADOBeginFontDict 18 + * X dict begin 13 + * /FontMatrix [X X X X] 22 + * /Private X dict begin 22 + * end 4 + * end 4 + * %ADOEndFontDict 16 + * + * This needs 18+13+22+22+4+4+16=99 bytes or more. Normally, you also + * need a `dup X' at the very beginning and a `put' at the end, so a + * rough guess using 100 bytes as the minimum is justified. + */ + if ( (FT_ULong)num_dicts > stream->size / 100 ) + { + FT_TRACE0(( "parse_fd_array: adjusting FDArray size" + " (from %d to %d)\n", + num_dicts, + stream->size / 100 )); + num_dicts = (FT_Long)( stream->size / 100 ); + } + if ( !cid->font_dicts ) { FT_Int n; @@ -395,7 +421,14 @@ cur = parser->root.cursor; } + + if ( !face->cid.num_dicts ) + { + FT_ERROR(( "cid_parse_dict: No font dictionary found\n" )); + return FT_THROW( Invalid_File_Format ); + } } + return parser->root.error; } @@ -428,12 +461,8 @@ FT_Byte* p; - /* Check for possible overflow. */ - if ( num_subrs == FT_UINT_MAX ) - { - error = FT_THROW( Syntax_Error ); - goto Fail; - } + if ( !num_subrs ) + continue; /* reallocate offsets array if needed */ if ( num_subrs + 1 > max_offsets ) @@ -467,14 +496,25 @@ /* offsets must be ordered */ for ( count = 1; count <= num_subrs; count++ ) if ( offsets[count - 1] > offsets[count] ) + { + FT_ERROR(( "cid_read_subrs: offsets are not ordered\n" )); + error = FT_THROW( Invalid_File_Format ); goto Fail; + } + + if ( offsets[num_subrs] > stream->size - cid->data_offset ) + { + FT_ERROR(( "cid_read_subrs: too large `subrs' offsets\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } /* now, compute the size of subrs charstrings, */ /* allocate, and read them */ data_len = offsets[num_subrs] - offsets[0]; if ( FT_NEW_ARRAY( subr->code, num_subrs + 1 ) || - FT_ALLOC( subr->code[0], data_len ) ) + FT_ALLOC( subr->code[0], data_len ) ) goto Fail; if ( FT_STREAM_SEEK( cid->data_offset + offsets[0] ) || @@ -533,7 +573,7 @@ { FT_UNUSED( face ); - FT_MEM_ZERO( loader, sizeof ( *loader ) ); + FT_ZERO( loader ); } @@ -654,6 +694,12 @@ CID_Parser* parser; FT_Memory memory = face->root.memory; FT_Error error; + FT_Int n; + + CID_FaceInfo cid = &face->cid; + + FT_ULong binary_length; + FT_ULong entry_len; cid_init_loader( &loader, face ); @@ -678,22 +724,117 @@ if ( parser->binary_length ) { + if ( parser->binary_length > + face->root.stream->size - parser->data_offset ) + { + FT_TRACE0(( "cid_face_open: adjusting length of binary data\n" + " (from %d to %d bytes)\n", + parser->binary_length, + face->root.stream->size - parser->data_offset )); + parser->binary_length = face->root.stream->size - + parser->data_offset; + } + /* we must convert the data section from hexadecimal to binary */ - if ( FT_ALLOC( face->binary_data, parser->binary_length ) || - cid_hex_to_binary( face->binary_data, parser->binary_length, - parser->data_offset, face ) ) + if ( FT_ALLOC( face->binary_data, parser->binary_length ) || + FT_SET_ERROR( cid_hex_to_binary( face->binary_data, + parser->binary_length, + parser->data_offset, + face ) ) ) goto Exit; FT_Stream_OpenMemory( face->cid_stream, face->binary_data, parser->binary_length ); - face->cid.data_offset = 0; + cid->data_offset = 0; } else { - *face->cid_stream = *face->root.stream; - face->cid.data_offset = loader.parser.data_offset; + *face->cid_stream = *face->root.stream; + cid->data_offset = loader.parser.data_offset; } + /* sanity tests */ + + if ( cid->fd_bytes < 0 || cid->gd_bytes < 1 ) + { + FT_ERROR(( "cid_parse_dict:" + " Invalid `FDBytes' or `GDBytes' value\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* allow at most 32bit offsets */ + if ( cid->fd_bytes > 4 || cid->gd_bytes > 4 ) + { + FT_ERROR(( "cid_parse_dict:" + " Values of `FDBytes' or `GDBytes' larger than 4\n" + " " + " are not supported\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + binary_length = face->cid_stream->size - cid->data_offset; + entry_len = (FT_ULong)( cid->fd_bytes + cid->gd_bytes ); + + for ( n = 0; n < cid->num_dicts; n++ ) + { + CID_FaceDict dict = cid->font_dicts + n; + + + if ( dict->sd_bytes < 0 || + ( dict->num_subrs && dict->sd_bytes < 1 ) ) + { + FT_ERROR(( "cid_parse_dict: Invalid `SDBytes' value\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + if ( dict->sd_bytes > 4 ) + { + FT_ERROR(( "cid_parse_dict:" + " Values of `SDBytes' larger than 4" + " are not supported\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + if ( dict->subrmap_offset > binary_length ) + { + FT_ERROR(( "cid_parse_dict: Invalid `SubrMapOffset' value\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* `num_subrs' is scanned as a signed integer */ + if ( (FT_Int)dict->num_subrs < 0 || + ( dict->sd_bytes && + dict->num_subrs > ( binary_length - dict->subrmap_offset ) / + (FT_UInt)dict->sd_bytes ) ) + { + FT_ERROR(( "cid_parse_dict: Invalid `SubrCount' value\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + } + + if ( cid->cidmap_offset > binary_length ) + { + FT_ERROR(( "cid_parse_dict: Invalid `CIDMapOffset' value\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + if ( entry_len && + cid->cid_count > + ( binary_length - cid->cidmap_offset ) / entry_len ) + { + FT_ERROR(( "cid_parse_dict: Invalid `CIDCount' value\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* we can now safely proceed */ error = cid_read_subrs( face ); Exit: diff --git a/src/3rdparty/freetype/src/cid/cidload.h b/src/3rdparty/freetype/src/cid/cidload.h index d7776d2f88..3f8bd08620 100644 --- a/src/3rdparty/freetype/src/cid/cidload.h +++ b/src/3rdparty/freetype/src/cid/cidload.h @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 font loader (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CIDLOAD_H__ -#define __CIDLOAD_H__ +#ifndef CIDLOAD_H_ +#define CIDLOAD_H_ #include <ft2build.h> @@ -47,7 +47,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CIDLOAD_H__ */ +#endif /* CIDLOAD_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/cid/cidobjs.c b/src/3rdparty/freetype/src/cid/cidobjs.c index bf1519bc6e..77afe1c875 100644 --- a/src/3rdparty/freetype/src/cid/cidobjs.c +++ b/src/3rdparty/freetype/src/cid/cidobjs.c @@ -4,7 +4,7 @@ /* */ /* CID objects manager (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,6 +26,7 @@ #include FT_SERVICE_POSTSCRIPT_CMAPS_H #include FT_INTERNAL_POSTSCRIPT_AUX_H #include FT_INTERNAL_POSTSCRIPT_HINTS_H +#include FT_DRIVER_H #include "ciderrs.h" @@ -113,16 +114,16 @@ CID_Size size = (CID_Size)cidsize; - if ( cidsize->internal ) + if ( cidsize->internal->module_data ) { PSH_Globals_Funcs funcs; funcs = cid_size_get_globals_funcs( size ); if ( funcs ) - funcs->destroy( (PSH_Globals)cidsize->internal ); + funcs->destroy( (PSH_Globals)cidsize->internal->module_data ); - cidsize->internal = NULL; + cidsize->internal->module_data = NULL; } } @@ -145,7 +146,7 @@ error = funcs->create( cidsize->face->memory, priv, &globals ); if ( !error ) - cidsize->internal = (FT_Size_Internal)(void*)globals; + cidsize->internal->module_data = globals; } return error; @@ -164,7 +165,7 @@ funcs = cid_size_get_globals_funcs( (CID_Size)size ); if ( funcs ) - funcs->set_scale( (PSH_Globals)size->internal, + funcs->set_scale( (PSH_Globals)size->internal->module_data, size->metrics.x_scale, size->metrics.y_scale, 0, 0 ); @@ -463,9 +464,42 @@ /* FreeType error code. 0 means success. */ /* */ FT_LOCAL_DEF( FT_Error ) - cid_driver_init( FT_Module driver ) + cid_driver_init( FT_Module module ) { - FT_UNUSED( driver ); + PS_Driver driver = (PS_Driver)module; + + FT_UInt32 seed; + + + /* set default property values, cf. `ftt1drv.h' */ +#ifdef T1_CONFIG_OPTION_OLD_ENGINE + driver->hinting_engine = FT_HINTING_FREETYPE; +#else + driver->hinting_engine = FT_HINTING_ADOBE; +#endif + + driver->no_stem_darkening = TRUE; + + driver->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1; + driver->darken_params[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1; + driver->darken_params[2] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2; + driver->darken_params[3] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2; + driver->darken_params[4] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3; + driver->darken_params[5] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3; + driver->darken_params[6] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4; + driver->darken_params[7] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4; + + /* compute random seed from some memory addresses */ + seed = (FT_UInt32)( (FT_Offset)(char*)&seed ^ + (FT_Offset)(char*)&module ^ + (FT_Offset)(char*)module->memory ); + seed = seed ^ ( seed >> 10 ) ^ ( seed >> 20 ); + + driver->random_seed = (FT_Int32)seed; + if ( driver->random_seed < 0 ) + driver->random_seed = -driver->random_seed; + else if ( driver->random_seed == 0 ) + driver->random_seed = 123456789; return FT_Err_Ok; } diff --git a/src/3rdparty/freetype/src/cid/cidobjs.h b/src/3rdparty/freetype/src/cid/cidobjs.h index e9095ca68e..0221f017dd 100644 --- a/src/3rdparty/freetype/src/cid/cidobjs.h +++ b/src/3rdparty/freetype/src/cid/cidobjs.h @@ -4,7 +4,7 @@ /* */ /* CID objects manager (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CIDOBJS_H__ -#define __CIDOBJS_H__ +#ifndef CIDOBJS_H_ +#define CIDOBJS_H_ #include <ft2build.h> @@ -148,7 +148,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CIDOBJS_H__ */ +#endif /* CIDOBJS_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/cid/cidparse.c b/src/3rdparty/freetype/src/cid/cidparse.c index c276949779..b1c7f3cb2c 100644 --- a/src/3rdparty/freetype/src/cid/cidparse.c +++ b/src/3rdparty/freetype/src/cid/cidparse.c @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 parser (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -47,6 +47,12 @@ /*************************************************************************/ +#define STARTDATA "StartData" +#define STARTDATA_LEN ( sizeof ( STARTDATA ) - 1 ) +#define SFNTS "/sfnts" +#define SFNTS_LEN ( sizeof ( SFNTS ) - 1 ) + + FT_LOCAL_DEF( FT_Error ) cid_parser_new( CID_Parser* parser, FT_Stream stream, @@ -59,7 +65,7 @@ FT_Byte *arg1, *arg2; - FT_MEM_ZERO( parser, sizeof ( *parser ) ); + FT_ZERO( parser ); psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); parser->stream = stream; @@ -85,9 +91,29 @@ /* now, read the rest of the file until we find */ /* `StartData' or `/sfnts' */ { - FT_Byte buffer[256 + 10]; - FT_ULong read_len = 256 + 10; - FT_Byte* p = buffer; + /* + * The algorithm is as follows (omitting the case with less than 256 + * bytes to fill for simplicity). + * + * 1. Fill the buffer with 256 + STARTDATA_LEN bytes. + * + * 2. Search for the STARTDATA and SFNTS strings at positions + * buffer[0], buffer[1], ..., + * buffer[255 + STARTDATA_LEN - SFNTS_LEN]. + * + * 3. Move the last STARTDATA_LEN bytes to buffer[0]. + * + * 4. Fill the buffer with 256 bytes, starting at STARTDATA_LEN. + * + * 5. Repeat with step 2. + * + */ + FT_Byte buffer[256 + STARTDATA_LEN + 1]; + + /* values for the first loop */ + FT_ULong read_len = 256 + STARTDATA_LEN; + FT_ULong read_offset = 0; + FT_Byte* p = buffer; for ( offset = FT_STREAM_POS(); ; offset += 256 ) @@ -96,40 +122,48 @@ stream_len = stream->size - FT_STREAM_POS(); - if ( stream_len == 0 ) + + read_len = FT_MIN( read_len, stream_len ); + if ( FT_STREAM_READ( p, read_len ) ) + goto Exit; + + /* ensure that we do not compare with data beyond the buffer */ + p[read_len] = '\0'; + + limit = p + read_len - SFNTS_LEN; + + for ( p = buffer; p < limit; p++ ) + { + if ( p[0] == 'S' && + ft_strncmp( (char*)p, STARTDATA, STARTDATA_LEN ) == 0 ) + { + /* save offset of binary data after `StartData' */ + offset += (FT_ULong)( p - buffer ) + STARTDATA_LEN + 1; + goto Found; + } + else if ( p[1] == 's' && + ft_strncmp( (char*)p, SFNTS, SFNTS_LEN ) == 0 ) + { + offset += (FT_ULong)( p - buffer ) + SFNTS_LEN + 1; + goto Found; + } + } + + if ( read_offset + read_len < STARTDATA_LEN ) { FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" )); error = FT_THROW( Invalid_File_Format ); goto Exit; } - read_len = FT_MIN( read_len, stream_len ); - if ( FT_STREAM_READ( p, read_len ) ) - goto Exit; + FT_MEM_MOVE( buffer, + buffer + read_offset + read_len - STARTDATA_LEN, + STARTDATA_LEN ); - if ( read_len < 256 ) - p[read_len] = '\0'; - - limit = p + read_len - 10; - - for ( p = buffer; p < limit; p++ ) - { - if ( p[0] == 'S' && ft_strncmp( (char*)p, "StartData", 9 ) == 0 ) - { - /* save offset of binary data after `StartData' */ - offset += (FT_ULong)( p - buffer + 10 ); - goto Found; - } - else if ( p[1] == 's' && ft_strncmp( (char*)p, "/sfnts", 6 ) == 0 ) - { - offset += (FT_ULong)( p - buffer + 7 ); - goto Found; - } - } - - FT_MEM_MOVE( buffer, p, 10 ); - read_len = 256; - p = buffer + 10; + /* values for the next loop */ + read_len = 256; + read_offset = STARTDATA_LEN; + p = buffer + read_offset; } } @@ -165,7 +199,7 @@ limit = parser->root.limit; cur = parser->root.cursor; - while ( cur < limit ) + while ( cur <= limit - SFNTS_LEN ) { if ( parser->root.error ) { @@ -173,11 +207,13 @@ goto Exit; } - if ( cur[0] == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 ) + if ( cur[0] == 'S' && + cur <= limit - STARTDATA_LEN && + ft_strncmp( (char*)cur, STARTDATA, STARTDATA_LEN ) == 0 ) { if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 ) { - FT_Long tmp = ft_atol( (const char *)arg2 ); + FT_Long tmp = ft_strtol( (const char *)arg2, NULL, 10 ); if ( tmp < 0 ) @@ -191,7 +227,8 @@ goto Exit; } - else if ( cur[1] == 's' && ft_strncmp( (char*)cur, "/sfnts", 6 ) == 0 ) + else if ( cur[1] == 's' && + ft_strncmp( (char*)cur, SFNTS, SFNTS_LEN ) == 0 ) { FT_TRACE2(( "cid_parser_new: cannot handle Type 11 fonts\n" )); error = FT_THROW( Unknown_File_Format ); @@ -216,6 +253,12 @@ } +#undef STARTDATA +#undef STARTDATA_LEN +#undef SFNTS +#undef SFNTS_LEN + + FT_LOCAL_DEF( void ) cid_parser_done( CID_Parser* parser ) { diff --git a/src/3rdparty/freetype/src/cid/cidparse.h b/src/3rdparty/freetype/src/cid/cidparse.h index f581bb43ff..61602f7674 100644 --- a/src/3rdparty/freetype/src/cid/cidparse.h +++ b/src/3rdparty/freetype/src/cid/cidparse.h @@ -4,7 +4,7 @@ /* */ /* CID-keyed Type1 parser (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CIDPARSE_H__ -#define __CIDPARSE_H__ +#ifndef CIDPARSE_H_ +#define CIDPARSE_H_ #include <ft2build.h> @@ -117,7 +117,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CIDPARSE_H__ */ +#endif /* CIDPARSE_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/cid/cidriver.c b/src/3rdparty/freetype/src/cid/cidriver.c index 07c4cc410b..d9faf353ea 100644 --- a/src/3rdparty/freetype/src/cid/cidriver.c +++ b/src/3rdparty/freetype/src/cid/cidriver.c @@ -4,7 +4,7 @@ /* */ /* CID driver interface (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,6 +20,7 @@ #include "cidriver.h" #include "cidgload.h" #include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_POSTSCRIPT_PROPS_H #include "ciderrs.h" @@ -27,6 +28,10 @@ #include FT_SERVICE_FONT_FORMAT_H #include FT_SERVICE_POSTSCRIPT_INFO_H #include FT_SERVICE_CID_H +#include FT_SERVICE_PROPERTIES_H +#include FT_DRIVER_H + +#include FT_INTERNAL_POSTSCRIPT_AUX_H /*************************************************************************/ @@ -59,7 +64,7 @@ static const FT_Service_PsFontNameRec cid_service_ps_name = { - (FT_PsName_GetFunc) cid_get_postscript_name + (FT_PsName_GetFunc)cid_get_postscript_name /* get_ps_font_name */ }; @@ -88,11 +93,14 @@ static const FT_Service_PsInfoRec cid_service_ps_info = { - (PS_GetFontInfoFunc) cid_ps_get_font_info, - (PS_GetFontExtraFunc) cid_ps_get_font_extra, - (PS_HasGlyphNamesFunc) NULL, /* unsupported with CID fonts */ - (PS_GetFontPrivateFunc)NULL, /* unsupported */ - (PS_GetFontValueFunc) NULL /* not implemented */ + (PS_GetFontInfoFunc) cid_ps_get_font_info, /* ps_get_font_info */ + (PS_GetFontExtraFunc) cid_ps_get_font_extra, /* ps_get_font_extra */ + /* unsupported with CID fonts */ + (PS_HasGlyphNamesFunc) NULL, /* ps_has_glyph_names */ + /* unsupported */ + (PS_GetFontPrivateFunc)NULL, /* ps_get_font_private */ + /* not implemented */ + (PS_GetFontValueFunc) NULL /* ps_get_font_value */ }; @@ -155,12 +163,27 @@ static const FT_Service_CIDRec cid_service_cid_info = { - (FT_CID_GetRegistryOrderingSupplementFunc)cid_get_ros, - (FT_CID_GetIsInternallyCIDKeyedFunc) cid_get_is_cid, - (FT_CID_GetCIDFromGlyphIndexFunc) cid_get_cid_from_glyph_index + (FT_CID_GetRegistryOrderingSupplementFunc) + cid_get_ros, /* get_ros */ + (FT_CID_GetIsInternallyCIDKeyedFunc) + cid_get_is_cid, /* get_is_cid */ + (FT_CID_GetCIDFromGlyphIndexFunc) + cid_get_cid_from_glyph_index /* get_cid_from_glyph_index */ }; + /* + * PROPERTY SERVICE + * + */ + + FT_DEFINE_SERVICE_PROPERTIESREC( + cid_service_properties, + + (FT_Properties_SetFunc)ps_property_set, /* set_property */ + (FT_Properties_GetFunc)ps_property_get ) /* get_property */ + + /* * SERVICE LIST * @@ -172,6 +195,7 @@ { FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &cid_service_ps_name }, { FT_SERVICE_ID_POSTSCRIPT_INFO, &cid_service_ps_info }, { FT_SERVICE_ID_CID, &cid_service_cid_info }, + { FT_SERVICE_ID_PROPERTIES, &cid_service_properties }, { NULL, NULL } }; @@ -190,46 +214,42 @@ FT_CALLBACK_TABLE_DEF const FT_Driver_ClassRec t1cid_driver_class = { - /* first of all, the FT_Module_Class fields */ { FT_MODULE_FONT_DRIVER | FT_MODULE_DRIVER_SCALABLE | FT_MODULE_DRIVER_HAS_HINTER, + sizeof ( PS_DriverRec ), - sizeof ( FT_DriverRec ), "t1cid", /* module name */ 0x10000L, /* version 1.0 of driver */ 0x20000L, /* requires FreeType 2.0 */ - 0, + NULL, /* module-specific interface */ - cid_driver_init, - cid_driver_done, - cid_get_interface + cid_driver_init, /* FT_Module_Constructor module_init */ + cid_driver_done, /* FT_Module_Destructor module_done */ + cid_get_interface /* FT_Module_Requester get_interface */ }, - /* then the other font drivers fields */ sizeof ( CID_FaceRec ), sizeof ( CID_SizeRec ), sizeof ( CID_GlyphSlotRec ), - cid_face_init, - cid_face_done, + cid_face_init, /* FT_Face_InitFunc init_face */ + cid_face_done, /* FT_Face_DoneFunc done_face */ + cid_size_init, /* FT_Size_InitFunc init_size */ + cid_size_done, /* FT_Size_DoneFunc done_size */ + cid_slot_init, /* FT_Slot_InitFunc init_slot */ + cid_slot_done, /* FT_Slot_DoneFunc done_slot */ - cid_size_init, - cid_size_done, - cid_slot_init, - cid_slot_done, + cid_slot_load_glyph, /* FT_Slot_LoadFunc load_glyph */ - cid_slot_load_glyph, + NULL, /* FT_Face_GetKerningFunc get_kerning */ + NULL, /* FT_Face_AttachFunc attach_file */ + NULL, /* FT_Face_GetAdvancesFunc get_advances */ - 0, /* FT_Face_GetKerningFunc */ - 0, /* FT_Face_AttachFunc */ - - 0, /* FT_Face_GetAdvancesFunc */ - - cid_size_request, - 0 /* FT_Size_SelectFunc */ + cid_size_request, /* FT_Size_RequestFunc request_size */ + NULL /* FT_Size_SelectFunc select_size */ }; diff --git a/src/3rdparty/freetype/src/cid/cidriver.h b/src/3rdparty/freetype/src/cid/cidriver.h index e5b8678464..59d9ded901 100644 --- a/src/3rdparty/freetype/src/cid/cidriver.h +++ b/src/3rdparty/freetype/src/cid/cidriver.h @@ -4,7 +4,7 @@ /* */ /* High-level CID driver interface (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __CIDRIVER_H__ -#define __CIDRIVER_H__ +#ifndef CIDRIVER_H_ +#define CIDRIVER_H_ #include <ft2build.h> @@ -37,7 +37,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __CIDRIVER_H__ */ +#endif /* CIDRIVER_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/cid/cidtoken.h b/src/3rdparty/freetype/src/cid/cidtoken.h index 82eae0ca6b..b0e2dac6aa 100644 --- a/src/3rdparty/freetype/src/cid/cidtoken.h +++ b/src/3rdparty/freetype/src/cid/cidtoken.h @@ -4,7 +4,7 @@ /* */ /* CID token definitions (specification only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/src/cid/module.mk b/src/3rdparty/freetype/src/cid/module.mk index e312a3ca1a..9010e339a4 100644 --- a/src/3rdparty/freetype/src/cid/module.mk +++ b/src/3rdparty/freetype/src/cid/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2015 by +# Copyright 1996-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/cid/rules.mk b/src/3rdparty/freetype/src/cid/rules.mk index 282f2aad7a..94333bda06 100644 --- a/src/3rdparty/freetype/src/cid/rules.mk +++ b/src/3rdparty/freetype/src/cid/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2015 by +# Copyright 1996-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/cid/type1cid.c b/src/3rdparty/freetype/src/cid/type1cid.c index 0d54ca7f44..61770e3f1e 100644 --- a/src/3rdparty/freetype/src/cid/type1cid.c +++ b/src/3rdparty/freetype/src/cid/type1cid.c @@ -4,7 +4,7 @@ /* */ /* FreeType OpenType driver component (body only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,13 +17,13 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT - #include <ft2build.h> -#include "cidparse.c" + +#include "cidgload.c" #include "cidload.c" #include "cidobjs.c" +#include "cidparse.c" #include "cidriver.c" -#include "cidgload.c" /* END */ diff --git a/src/3rdparty/freetype/src/gxvalid/Jamfile b/src/3rdparty/freetype/src/gxvalid/Jamfile index d367cad77c..74f3c51ff0 100644 --- a/src/3rdparty/freetype/src/gxvalid/Jamfile +++ b/src/3rdparty/freetype/src/gxvalid/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/gxvalid Jamfile # -# Copyright 2005-2015 by +# Copyright 2005-2018 by # suzuki toshiya, Masatake YAMATO and Red Hat K.K. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/gxvalid/README b/src/3rdparty/freetype/src/gxvalid/README index 60f2fc185e..af8128e0e7 100644 --- a/src/3rdparty/freetype/src/gxvalid/README +++ b/src/3rdparty/freetype/src/gxvalid/README @@ -9,7 +9,7 @@ gxvalid: TrueType GX validator additional tables in TrueType font which are used by `QuickDraw GX Text', Apple Advanced Typography (AAT). In addition, gxvalid can validates `kern' tables which have been extended for AAT. Like the - otvalid module, gxvalid uses Freetype 2's validator framework + otvalid module, gxvalid uses FreeType 2's validator framework (ftvalid). You can link gxvalid with your program; before running your own layout @@ -287,11 +287,11 @@ gxvalid: TrueType GX validator 4-5. invalid feature number (117/183) ------------------------------------- - The GX/AAT extension can include 255 different layout features, but - popular layout features are predefined (see - http://developer.apple.com/fonts/Registry/index.html). Some fonts - include feature numbers which are incompatible with the predefined - feature registry. + The GX/AAT extension can include 255 different layout features, + but popular layout features are predefined (see + https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html). + Some fonts include feature numbers which are incompatible with the + predefined feature registry. In our survey, there are 140 fonts including `feat' table. @@ -413,7 +413,7 @@ gxvalid: TrueType GX validator format assured for Windows and OS/2 support is only subtable format 0. The Microsoft TrueType specification also describes subtable format 2, but does not mention which platforms support - it. Aubtable formats 1, 3, and higher are documented as reserved + it. Subtable formats 1, 3, and higher are documented as reserved for future use. Therefore, the classic version can store subtable formats 0 and 2, at least. `ttfdump.exe', a font tool provided by Microsoft, ignores the subtable format written in the subtable @@ -518,7 +518,7 @@ gxvalid: TrueType GX validator ------------------------------------------------------------------------ -Copyright 2004-2015 by +Copyright 2004-2018 by suzuki toshiya, Masatake YAMATO, Red hat K.K., David Turner, Robert Wilhelm, and Werner Lemberg. diff --git a/src/3rdparty/freetype/src/gxvalid/gxvalid.c b/src/3rdparty/freetype/src/gxvalid/gxvalid.c index 7b5b0914db..d0577a247e 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvalid.c +++ b/src/3rdparty/freetype/src/gxvalid/gxvalid.c @@ -4,7 +4,7 @@ /* */ /* FreeType validator for TrueTypeGX/AAT tables (body only). */ /* */ -/* Copyright 2005-2015 by */ +/* Copyright 2005-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -16,15 +16,17 @@ /* */ /***************************************************************************/ -#define FT_MAKE_OPTION_SINGLE_OBJECT +#define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> -#include "gxvfeat.c" -#include "gxvcommn.c" #include "gxvbsln.c" -#include "gxvtrak.c" +#include "gxvcommn.c" +#include "gxvfeat.c" #include "gxvjust.c" +#include "gxvkern.c" +#include "gxvlcar.c" +#include "gxvmod.c" #include "gxvmort.c" #include "gxvmort0.c" #include "gxvmort1.c" @@ -37,11 +39,9 @@ #include "gxvmorx2.c" #include "gxvmorx4.c" #include "gxvmorx5.c" -#include "gxvkern.c" #include "gxvopbd.c" #include "gxvprop.c" -#include "gxvlcar.c" -#include "gxvmod.c" +#include "gxvtrak.c" /* END */ diff --git a/src/3rdparty/freetype/src/gxvalid/gxvalid.h b/src/3rdparty/freetype/src/gxvalid/gxvalid.h index 8c227d0e0b..19f0379982 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvalid.h +++ b/src/3rdparty/freetype/src/gxvalid/gxvalid.h @@ -2,9 +2,9 @@ /* */ /* gxvalid.h */ /* */ -/* TrueTyeeGX/AAT table validation (specification only). */ +/* TrueTypeGX/AAT table validation (specification only). */ /* */ -/* Copyright 2005-2015 by */ +/* Copyright 2005-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -25,8 +25,8 @@ /***************************************************************************/ -#ifndef __GXVALID_H__ -#define __GXVALID_H__ +#ifndef GXVALID_H_ +#define GXVALID_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -102,7 +102,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __GXVALID_H__ */ +#endif /* GXVALID_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/gxvalid/gxvbsln.c b/src/3rdparty/freetype/src/gxvalid/gxvbsln.c index 1b17a5d033..c367d38483 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvbsln.c +++ b/src/3rdparty/freetype/src/gxvalid/gxvbsln.c @@ -4,7 +4,7 @@ /* */ /* TrueTypeGX/AAT bsln table validation (body). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ diff --git a/src/3rdparty/freetype/src/gxvalid/gxvcommn.c b/src/3rdparty/freetype/src/gxvalid/gxvcommn.c index 93f6ffbe23..b96601108b 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvcommn.c +++ b/src/3rdparty/freetype/src/gxvalid/gxvcommn.c @@ -4,7 +4,7 @@ /* */ /* TrueTypeGX/AAT common tables validation (body). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -454,7 +454,7 @@ } - /* ================= Segment Single Format 2 Loolup Table ============== */ + /* ================= Segment Single Format 2 Lookup Table ============== */ /* * Apple spec says: * @@ -789,7 +789,7 @@ FT_INVALID_FORMAT; func = fmt_funcs_table[format]; - if ( func == NULL ) + if ( !func ) FT_INVALID_FORMAT; func( p, limit, gxvalid ); @@ -900,7 +900,7 @@ for ( i = 0; i < nnames; i++ ) { if ( FT_Get_Sfnt_Name( gxvalid->face, i, &name ) != FT_Err_Ok ) - continue ; + continue; if ( name.name_id == name_index ) goto Out; @@ -972,7 +972,7 @@ FT_UShort i; - ft_memset( nGlyphInClass, 0, 256 ); + FT_MEM_ZERO( nGlyphInClass, 256 ); for ( i = 0; i < nGlyphs; i++ ) @@ -1159,13 +1159,9 @@ case GXV_GLYPHOFFSET_LONG: glyphOffset.l = FT_NEXT_LONG( p ); break; - - default: - GXV_SET_ERR_IF_PARANOID( FT_INVALID_FORMAT ); - goto Exit; } - if ( NULL != gxvalid->statetable.entry_validate_func ) + if ( gxvalid->statetable.entry_validate_func ) gxvalid->statetable.entry_validate_func( state, flags, &glyphOffset, @@ -1174,7 +1170,6 @@ gxvalid ); } - Exit: *length_p = (FT_UShort)( p - table ); GXV_EXIT; @@ -1249,10 +1244,10 @@ if ( stateSize > 0xFF ) FT_INVALID_DATA; - if ( gxvalid->statetable.optdata_load_func != NULL ) + if ( gxvalid->statetable.optdata_load_func ) gxvalid->statetable.optdata_load_func( p, limit, gxvalid ); - if ( gxvalid->statetable.subtable_setup_func != NULL) + if ( gxvalid->statetable.subtable_setup_func ) setup_func = gxvalid->statetable.subtable_setup_func; else setup_func = gxv_StateTable_subtable_setup; @@ -1477,7 +1472,7 @@ if ( ( p + ( maxEntry + 1 ) * entrySize ) > limit ) FT_INVALID_TOO_SHORT; - for (entry = 0; entry <= maxEntry ; entry++ ) + for (entry = 0; entry <= maxEntry; entry++ ) { FT_UShort newState_idx; FT_UShort flags; @@ -1539,7 +1534,7 @@ goto Exit; } - if ( NULL != gxvalid->xstatetable.entry_validate_func ) + if ( gxvalid->xstatetable.entry_validate_func ) gxvalid->xstatetable.entry_validate_func( state, flags, &glyphOffset, @@ -1596,10 +1591,10 @@ GXV_TRACE(( "StateTable Subtables\n" )); - if ( gxvalid->xstatetable.optdata_load_func != NULL ) + if ( gxvalid->xstatetable.optdata_load_func ) gxvalid->xstatetable.optdata_load_func( p, limit, gxvalid ); - if ( gxvalid->xstatetable.subtable_setup_func != NULL ) + if ( gxvalid->xstatetable.subtable_setup_func ) setup_func = gxvalid->xstatetable.subtable_setup_func; else setup_func = gxv_XStateTable_subtable_setup; diff --git a/src/3rdparty/freetype/src/gxvalid/gxvcommn.h b/src/3rdparty/freetype/src/gxvalid/gxvcommn.h index b24608c257..8e4ff9cafc 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvcommn.h +++ b/src/3rdparty/freetype/src/gxvalid/gxvcommn.h @@ -4,7 +4,7 @@ /* */ /* TrueTypeGX/AAT common tables validation (specification). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -39,8 +39,8 @@ */ -#ifndef __GXVCOMMN_H__ -#define __GXVCOMMN_H__ +#ifndef GXVCOMMN_H_ +#define GXVCOMMN_H_ #include <ft2build.h> @@ -338,7 +338,7 @@ FT_BEGIN_HEADER \ \ for ( b = p; b < (FT_Bytes)p + len; b++ ) \ - FT_TRACE1(("\\x%02x", *b)) ; \ + FT_TRACE1(("\\x%02x", *b)); \ } \ FT_END_STMNT @@ -350,9 +350,9 @@ FT_BEGIN_HEADER \ for ( b = p; b < (FT_Bytes)p + len; b++ ) \ if ( 0x40 < *b && *b < 0x7E ) \ - FT_TRACE1(("%c", *b)) ; \ + FT_TRACE1(("%c", *b)); \ else \ - FT_TRACE1(("\\x%02x", *b)) ; \ + FT_TRACE1(("\\x%02x", *b)); \ } \ FT_END_STMNT @@ -576,7 +576,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __GXVCOMMN_H__ */ +#endif /* GXVCOMMN_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/gxvalid/gxverror.h b/src/3rdparty/freetype/src/gxvalid/gxverror.h index 6bbc23aa03..d1151258a9 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxverror.h +++ b/src/3rdparty/freetype/src/gxvalid/gxverror.h @@ -4,7 +4,7 @@ /* */ /* TrueTypeGX/AAT validation module error codes (specification only). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -32,12 +32,12 @@ /* */ /*************************************************************************/ -#ifndef __GXVERROR_H__ -#define __GXVERROR_H__ +#ifndef GXVERROR_H_ +#define GXVERROR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX GXV_Err_ @@ -45,7 +45,7 @@ #include FT_ERRORS_H -#endif /* __GXVERROR_H__ */ +#endif /* GXVERROR_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/gxvalid/gxvfeat.c b/src/3rdparty/freetype/src/gxvalid/gxvfeat.c index 0da9777642..2c805d1d11 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvfeat.c +++ b/src/3rdparty/freetype/src/gxvalid/gxvfeat.c @@ -4,7 +4,7 @@ /* */ /* TrueTypeGX/AAT feat table validation (body). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ diff --git a/src/3rdparty/freetype/src/gxvalid/gxvfeat.h b/src/3rdparty/freetype/src/gxvalid/gxvfeat.h index b617df5d53..2d943806c1 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvfeat.h +++ b/src/3rdparty/freetype/src/gxvalid/gxvfeat.h @@ -4,7 +4,7 @@ /* */ /* TrueTypeGX/AAT feat table validation (specification). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -25,8 +25,8 @@ /***************************************************************************/ -#ifndef __GXVFEAT_H__ -#define __GXVFEAT_H__ +#ifndef GXVFEAT_H_ +#define GXVFEAT_H_ #include "gxvalid.h" @@ -167,7 +167,7 @@ }; -#endif /* __GXVFEAT_H__ */ +#endif /* GXVFEAT_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/gxvalid/gxvfgen.c b/src/3rdparty/freetype/src/gxvalid/gxvfgen.c index 75c5e20d22..840c0f3524 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvfgen.c +++ b/src/3rdparty/freetype/src/gxvalid/gxvfgen.c @@ -5,7 +5,7 @@ /* Generate feature registry data for gxv `feat' validator. */ /* This program is derived from gxfeatreg.c in gxlayout. */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* Masatake YAMATO and Redhat K.K. */ /* */ /* This file may only be used, */ @@ -21,7 +21,7 @@ /* gxfeatreg.c */ /* */ /* Database of font features pre-defined by Apple Computer, Inc. */ -/* http://developer.apple.com/fonts/Registry/ */ +/* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html */ /* (body). */ /* */ /* Copyright 2003 by */ diff --git a/src/3rdparty/freetype/src/gxvalid/gxvjust.c b/src/3rdparty/freetype/src/gxvalid/gxvjust.c index 55b44bc2a8..00c4293195 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvjust.c +++ b/src/3rdparty/freetype/src/gxvalid/gxvjust.c @@ -4,7 +4,7 @@ /* */ /* TrueTypeGX/AAT just table validation (body). */ /* */ -/* Copyright 2005-2015 by */ +/* Copyright 2005-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -152,7 +152,7 @@ FT_Bytes limit, GXV_Validator gxvalid ) { - FT_Bytes p = table ; + FT_Bytes p = table; FT_Bytes wdc_end = table + GXV_JUST_DATA( wdc_offset_max ); FT_UInt i; diff --git a/src/3rdparty/freetype/src/gxvalid/gxvkern.c b/src/3rdparty/freetype/src/gxvalid/gxvkern.c index f257c03760..9c0efd7a4f 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvkern.c +++ b/src/3rdparty/freetype/src/gxvalid/gxvkern.c @@ -4,7 +4,7 @@ /* */ /* TrueTypeGX/AAT kern table validation (body). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -693,7 +693,7 @@ GXV_NAME_ENTER( "validating coverage" ); - GXV_TRACE(( "interprete coverage 0x%04x by Apple style\n", coverage )); + GXV_TRACE(( "interpret coverage 0x%04x by Apple style\n", coverage )); if ( KERN_IS_NEW( gxvalid ) ) { @@ -728,7 +728,7 @@ } } - GXV_TRACE(( "cannot interprete coverage, broken kern subtable\n" )); + GXV_TRACE(( "cannot interpret coverage, broken kern subtable\n" )); Exit: GXV_EXIT; diff --git a/src/3rdparty/freetype/src/gxvalid/gxvlcar.c b/src/3rdparty/freetype/src/gxvalid/gxvlcar.c index af589fdb6f..0f261a9ace 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvlcar.c +++ b/src/3rdparty/freetype/src/gxvalid/gxvlcar.c @@ -4,7 +4,7 @@ /* */ /* TrueTypeGX/AAT lcar table validation (body). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -114,7 +114,7 @@ +------ lcar --------------------+ | | | +===============+ | - | | looup header | | + | | lookup header | | | +===============+ | | | BinSrchHeader | | | +===============+ | diff --git a/src/3rdparty/freetype/src/gxvalid/gxvmod.c b/src/3rdparty/freetype/src/gxvalid/gxvmod.c index 17a02e7b8b..1a3c862927 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvmod.c +++ b/src/3rdparty/freetype/src/gxvalid/gxvmod.c @@ -4,7 +4,7 @@ /* */ /* FreeType's TrueTypeGX/AAT validation module implementation (body). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -235,14 +235,14 @@ static const FT_Service_GXvalidateRec gxvalid_interface = { - gxv_validate + gxv_validate /* validate */ }; static const FT_Service_CKERNvalidateRec ckernvalid_interface = { - classic_kern_validate + classic_kern_validate /* validate */ }; @@ -274,11 +274,11 @@ 0x10000L, 0x20000L, - 0, /* module-specific interface */ + NULL, /* module-specific interface */ - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) gxvalid_get_service + (FT_Module_Constructor)NULL, /* module_init */ + (FT_Module_Destructor) NULL, /* module_done */ + (FT_Module_Requester) gxvalid_get_service /* get_interface */ }; diff --git a/src/3rdparty/freetype/src/gxvalid/gxvmod.h b/src/3rdparty/freetype/src/gxvalid/gxvmod.h index 1ff2cfc8bb..745c62e105 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvmod.h +++ b/src/3rdparty/freetype/src/gxvalid/gxvmod.h @@ -5,7 +5,7 @@ /* FreeType's TrueTypeGX/AAT validation module implementation */ /* (specification). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -26,8 +26,8 @@ /***************************************************************************/ -#ifndef __GXVMOD_H__ -#define __GXVMOD_H__ +#ifndef GXVMOD_H_ +#define GXVMOD_H_ #include <ft2build.h> #include FT_MODULE_H @@ -45,7 +45,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __GXVMOD_H__ */ +#endif /* GXVMOD_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/gxvalid/gxvmort.c b/src/3rdparty/freetype/src/gxvalid/gxvmort.c index a9e7a58fea..b361cb2b9d 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvmort.c +++ b/src/3rdparty/freetype/src/gxvalid/gxvmort.c @@ -4,7 +4,7 @@ /* */ /* TrueTypeGX/AAT mort table validation (body). */ /* */ -/* Copyright 2005-2015 by */ +/* Copyright 2005-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -205,7 +205,7 @@ FT_INVALID_FORMAT; func = fmt_funcs_table[type]; - if ( func == NULL ) + if ( !func ) GXV_TRACE(( "morx type %d is reserved\n", type )); func( p, p + rest, gxvalid ); diff --git a/src/3rdparty/freetype/src/gxvalid/gxvmort.h b/src/3rdparty/freetype/src/gxvalid/gxvmort.h index c95391b61f..d8030645e9 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvmort.h +++ b/src/3rdparty/freetype/src/gxvalid/gxvmort.h @@ -4,7 +4,7 @@ /* */ /* TrueTypeGX/AAT common definition for mort table (specification). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -25,8 +25,8 @@ /***************************************************************************/ -#ifndef __GXVMORT_H__ -#define __GXVMORT_H__ +#ifndef GXVMORT_H_ +#define GXVMORT_H_ #include "gxvalid.h" #include "gxvcommn.h" @@ -88,7 +88,7 @@ GXV_Validator gxvalid ); -#endif /* __GXVMORT_H__ */ +#endif /* GXVMORT_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/gxvalid/gxvmort0.c b/src/3rdparty/freetype/src/gxvalid/gxvmort0.c index 0cace35ae2..95cf53d5eb 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvmort0.c +++ b/src/3rdparty/freetype/src/gxvalid/gxvmort0.c @@ -5,7 +5,7 @@ /* TrueTypeGX/AAT mort table validation */ /* body for type0 (Indic Script Rearrangement) subtable. */ /* */ -/* Copyright 2005-2015 by */ +/* Copyright 2005-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ diff --git a/src/3rdparty/freetype/src/gxvalid/gxvmort1.c b/src/3rdparty/freetype/src/gxvalid/gxvmort1.c index aa02df5a99..a7683a17b0 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvmort1.c +++ b/src/3rdparty/freetype/src/gxvalid/gxvmort1.c @@ -5,7 +5,7 @@ /* TrueTypeGX/AAT mort table validation */ /* body for type1 (Contextual Substitution) subtable. */ /* */ -/* Copyright 2005-2015 by */ +/* Copyright 2005-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -192,7 +192,7 @@ GXV_NAME_ENTER( "validating contents of substitutionTable" ); - for ( i = 0; i < num_gids ; i ++ ) + for ( i = 0; i < num_gids; i++ ) { FT_UShort dst_gid; diff --git a/src/3rdparty/freetype/src/gxvalid/gxvmort2.c b/src/3rdparty/freetype/src/gxvalid/gxvmort2.c index 6f56c94ca7..c23c2775a1 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvmort2.c +++ b/src/3rdparty/freetype/src/gxvalid/gxvmort2.c @@ -5,7 +5,7 @@ /* TrueTypeGX/AAT mort table validation */ /* body for type2 (Ligature Substitution) subtable. */ /* */ -/* Copyright 2005-2015 by */ +/* Copyright 2005-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ diff --git a/src/3rdparty/freetype/src/gxvalid/gxvmort4.c b/src/3rdparty/freetype/src/gxvalid/gxvmort4.c index 535f37716d..9d21a5fc29 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvmort4.c +++ b/src/3rdparty/freetype/src/gxvalid/gxvmort4.c @@ -5,7 +5,7 @@ /* TrueTypeGX/AAT mort table validation */ /* body for type4 (Non-Contextual Glyph Substitution) subtable. */ /* */ -/* Copyright 2005-2015 by */ +/* Copyright 2005-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ diff --git a/src/3rdparty/freetype/src/gxvalid/gxvmort5.c b/src/3rdparty/freetype/src/gxvalid/gxvmort5.c index fb2f915fce..42cb428aa8 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvmort5.c +++ b/src/3rdparty/freetype/src/gxvalid/gxvmort5.c @@ -5,7 +5,7 @@ /* TrueTypeGX/AAT mort table validation */ /* body for type5 (Contextual Glyph Insertion) subtable. */ /* */ -/* Copyright 2005-2015 by */ +/* Copyright 2005-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ diff --git a/src/3rdparty/freetype/src/gxvalid/gxvmorx.c b/src/3rdparty/freetype/src/gxvalid/gxvmorx.c index 1c6b3f2973..9fd6e6b971 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvmorx.c +++ b/src/3rdparty/freetype/src/gxvalid/gxvmorx.c @@ -4,7 +4,7 @@ /* */ /* TrueTypeGX/AAT morx table validation (body). */ /* */ -/* Copyright 2005-2015 by */ +/* Copyright 2005-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -98,7 +98,7 @@ FT_INVALID_FORMAT; func = fmt_funcs_table[type]; - if ( func == NULL ) + if ( !func ) GXV_TRACE(( "morx type %d is reserved\n", type )); func( p, p + rest, gxvalid ); diff --git a/src/3rdparty/freetype/src/gxvalid/gxvmorx.h b/src/3rdparty/freetype/src/gxvalid/gxvmorx.h index 60efdfd0ce..6d9925e92b 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvmorx.h +++ b/src/3rdparty/freetype/src/gxvalid/gxvmorx.h @@ -4,7 +4,7 @@ /* */ /* TrueTypeGX/AAT common definition for morx table (specification). */ /* */ -/* Copyright 2005-2015 by */ +/* Copyright 2005-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -25,8 +25,8 @@ /***************************************************************************/ -#ifndef __GXVMORX_H__ -#define __GXVMORX_H__ +#ifndef GXVMORX_H_ +#define GXVMORX_H_ #include "gxvalid.h" @@ -62,7 +62,7 @@ GXV_Validator gxvalid ); -#endif /* __GXVMORX_H__ */ +#endif /* GXVMORX_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/gxvalid/gxvmorx0.c b/src/3rdparty/freetype/src/gxvalid/gxvmorx0.c index e340baa5e4..302261b7fa 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvmorx0.c +++ b/src/3rdparty/freetype/src/gxvalid/gxvmorx0.c @@ -5,7 +5,7 @@ /* TrueTypeGX/AAT morx table validation */ /* body for type0 (Indic Script Rearrangement) subtable. */ /* */ -/* Copyright 2005-2015 by */ +/* Copyright 2005-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ diff --git a/src/3rdparty/freetype/src/gxvalid/gxvmorx1.c b/src/3rdparty/freetype/src/gxvalid/gxvmorx1.c index 7ba290914d..890ca74b1d 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvmorx1.c +++ b/src/3rdparty/freetype/src/gxvalid/gxvmorx1.c @@ -5,7 +5,7 @@ /* TrueTypeGX/AAT morx table validation */ /* body for type1 (Contextual Substitution) subtable. */ /* */ -/* Copyright 2005-2015 by */ +/* Copyright 2005-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ diff --git a/src/3rdparty/freetype/src/gxvalid/gxvmorx2.c b/src/3rdparty/freetype/src/gxvalid/gxvmorx2.c index 51e305580f..3135031d45 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvmorx2.c +++ b/src/3rdparty/freetype/src/gxvalid/gxvmorx2.c @@ -5,7 +5,7 @@ /* TrueTypeGX/AAT morx table validation */ /* body for type2 (Ligature Substitution) subtable. */ /* */ -/* Copyright 2005-2015 by */ +/* Copyright 2005-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ diff --git a/src/3rdparty/freetype/src/gxvalid/gxvmorx4.c b/src/3rdparty/freetype/src/gxvalid/gxvmorx4.c index c42677d45b..1e2397b0c5 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvmorx4.c +++ b/src/3rdparty/freetype/src/gxvalid/gxvmorx4.c @@ -5,7 +5,7 @@ /* TrueTypeGX/AAT morx table validation */ /* body for "morx" type4 (Non-Contextual Glyph Substitution) subtable. */ /* */ -/* Copyright 2005-2015 by */ +/* Copyright 2005-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ diff --git a/src/3rdparty/freetype/src/gxvalid/gxvmorx5.c b/src/3rdparty/freetype/src/gxvalid/gxvmorx5.c index 7ac872f9d7..db4f9290c8 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvmorx5.c +++ b/src/3rdparty/freetype/src/gxvalid/gxvmorx5.c @@ -5,7 +5,7 @@ /* TrueTypeGX/AAT morx table validation */ /* body for type5 (Contextual Glyph Insertion) subtable. */ /* */ -/* Copyright 2005-2015 by */ +/* Copyright 2005-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ diff --git a/src/3rdparty/freetype/src/gxvalid/gxvopbd.c b/src/3rdparty/freetype/src/gxvalid/gxvopbd.c index 7cd5163b17..e2c167ea59 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvopbd.c +++ b/src/3rdparty/freetype/src/gxvalid/gxvopbd.c @@ -4,7 +4,7 @@ /* */ /* TrueTypeGX/AAT opbd table validation (body). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ diff --git a/src/3rdparty/freetype/src/gxvalid/gxvprop.c b/src/3rdparty/freetype/src/gxvalid/gxvprop.c index ecc3c94d2c..a67b6bdd00 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvprop.c +++ b/src/3rdparty/freetype/src/gxvalid/gxvprop.c @@ -4,7 +4,7 @@ /* */ /* TrueTypeGX/AAT prop table validation (body). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ diff --git a/src/3rdparty/freetype/src/gxvalid/gxvtrak.c b/src/3rdparty/freetype/src/gxvalid/gxvtrak.c index c4d29e4dff..d501b5014b 100644 --- a/src/3rdparty/freetype/src/gxvalid/gxvtrak.c +++ b/src/3rdparty/freetype/src/gxvalid/gxvtrak.c @@ -4,7 +4,7 @@ /* */ /* TrueTypeGX/AAT trak table validation (body). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ @@ -111,7 +111,7 @@ GXV_LIMIT_CHECK( nTracks * ( 4 + 2 + 2 ) ); - for ( i = 0; i < nTracks; i ++ ) + for ( i = 0; i < nTracks; i++ ) { p = table + i * ( 4 + 2 + 2 ); track = FT_NEXT_LONG( p ); @@ -125,7 +125,7 @@ gxv_sfntName_validate( nameIndex, 256, 32767, gxvalid ); - for ( j = i; j < nTracks; j ++ ) + for ( j = i; j < nTracks; j++ ) { p = table + j * ( 4 + 2 + 2 ); t = FT_NEXT_LONG( p ); diff --git a/src/3rdparty/freetype/src/gxvalid/module.mk b/src/3rdparty/freetype/src/gxvalid/module.mk index 1d7649478e..b64879dcee 100644 --- a/src/3rdparty/freetype/src/gxvalid/module.mk +++ b/src/3rdparty/freetype/src/gxvalid/module.mk @@ -2,7 +2,7 @@ # FreeType 2 gxvalid module definition # -# Copyright 2004-2015 by +# Copyright 2004-2018 by # suzuki toshiya, Masatake YAMATO, Red Hat K.K., # David Turner, Robert Wilhelm, and Werner Lemberg. # diff --git a/src/3rdparty/freetype/src/gxvalid/rules.mk b/src/3rdparty/freetype/src/gxvalid/rules.mk index 44a2d43250..3a17c030a6 100644 --- a/src/3rdparty/freetype/src/gxvalid/rules.mk +++ b/src/3rdparty/freetype/src/gxvalid/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2004-2015 by +# Copyright 2004-2018 by # suzuki toshiya, Masatake YAMATO, Red Hat K.K., # David Turner, Robert Wilhelm, and Werner Lemberg. # diff --git a/src/3rdparty/freetype/src/gzip/Jamfile b/src/3rdparty/freetype/src/gzip/Jamfile index 0944a5f2c4..a7b4c8c950 100644 --- a/src/3rdparty/freetype/src/gzip/Jamfile +++ b/src/3rdparty/freetype/src/gzip/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/gzip Jamfile # -# Copyright 2001-2015 by +# Copyright 2001-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/gzip/ftgzip.c b/src/3rdparty/freetype/src/gzip/ftgzip.c index 422035c00b..f8011c2dd8 100644 --- a/src/3rdparty/freetype/src/gzip/ftgzip.c +++ b/src/3rdparty/freetype/src/gzip/ftgzip.c @@ -8,7 +8,7 @@ /* parse compressed PCF fonts, as found with many X11 server */ /* distributions. */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -30,7 +30,7 @@ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX Gzip_Err_ @@ -51,17 +51,29 @@ #else /* !FT_CONFIG_OPTION_SYSTEM_ZLIB */ - /* In this case, we include our own modified sources of the ZLib */ - /* within the "ftgzip" component. The modifications were necessary */ - /* to #include all files without conflicts, as well as preventing */ - /* the definition of "extern" functions that may cause linking */ - /* conflicts when a program is linked with both FreeType and the */ - /* original ZLib. */ + /* In this case, we include our own modified sources of the ZLib */ + /* within the `gzip' component. The modifications were necessary */ + /* to #include all files without conflicts, as well as preventing */ + /* the definition of `extern' functions that may cause linking */ + /* conflicts when a program is linked with both FreeType and the */ + /* original ZLib. */ #ifndef USE_ZLIB_ZCALLOC -#define MY_ZCALLOC /* prevent all zcalloc() & zfree() in zutils.c */ +#define MY_ZCALLOC /* prevent all zcalloc() & zfree() in zutil.c */ #endif + /* Note that our `zlib.h' includes `ftzconf.h' instead of `zconf.h'; */ + /* the main reason is that even a global `zlib.h' includes `zconf.h' */ + /* with */ + /* */ + /* #include "zconf.h" */ + /* */ + /* instead of the expected */ + /* */ + /* #include <zconf.h> */ + /* */ + /* so that configuration with `FT_CONFIG_OPTION_SYSTEM_ZLIB' might */ + /* include the wrong `zconf.h' file, leading to errors. */ #include "zlib.h" #undef SLOW @@ -305,7 +317,7 @@ zstream->next_in = zip->buffer; if ( inflateInit2( zstream, -MAX_WBITS ) != Z_OK || - zstream->next_in == NULL ) + !zstream->next_in ) error = FT_THROW( Invalid_File_Format ); Exit: @@ -691,9 +703,13 @@ } error = FT_Err_Ok; } + + if ( zip_size ) + stream->size = zip_size; + else + stream->size = 0x7FFFFFFFL; /* don't know the real size! */ } - stream->size = 0x7FFFFFFFL; /* don't know the real size! */ stream->pos = 0; stream->base = NULL; stream->read = ft_gzip_stream_io; diff --git a/src/3rdparty/freetype/src/gzip/ftzconf.h b/src/3rdparty/freetype/src/gzip/ftzconf.h new file mode 100644 index 0000000000..3abf0ba03b --- /dev/null +++ b/src/3rdparty/freetype/src/gzip/ftzconf.h @@ -0,0 +1,284 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef _ZCONF_H +#define _ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflateParams z_deflateParams +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateReset z_inflateReset +# define compress z_compress +# define compress2 z_compress2 +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table + +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) +# define WIN32 +#endif +#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386) +# ifndef __32BIT__ +# define __32BIT__ +# endif +#endif +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif + +/* WinCE doesn't have errno.h */ +#ifdef _WIN32_WCE +# define NO_ERRNO_H +#endif + + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#if defined(MSDOS) && !defined(__32BIT__) +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC) +# define STDC +#endif +#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__) +# ifndef STDC +# define STDC +# endif +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Old Borland C and LCC incorrectly complains about missing returns: */ +#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500) +# define NEED_DUMMY_RETURN +#endif + +#if defined(__LCC__) +# define NEED_DUMMY_RETURN +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +#endif +#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) +# ifndef __32BIT__ +# define SMALL_MEDIUM +# define FAR _far +# endif +#endif + +/* Compile with -DZLIB_DLL for Windows DLL support */ +#if defined(ZLIB_DLL) +# if defined(_WINDOWS) || defined(WINDOWS) +# ifdef FAR +# undef FAR +# endif +# include <windows.h> +# define ZEXPORT(x) x WINAPI +# ifdef WIN32 +# define ZEXPORTVA(x) x WINAPIV +# else +# define ZEXPORTVA(x) x FAR _cdecl _export +# endif +# endif +# if defined (__BORLANDC__) +# if (__BORLANDC__ >= 0x0500) && defined (WIN32) +# include <windows.h> +# define ZEXPORT(x) x __declspec(dllexport) WINAPI +# define ZEXPORTRVA(x) x __declspec(dllexport) WINAPIV +# else +# if defined (_Windows) && defined (__DLL__) +# define ZEXPORT(x) x _export +# define ZEXPORTVA(x) x _export +# endif +# endif +# endif +#endif + + +#ifndef ZEXPORT +# define ZEXPORT(x) static x +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA(x) static x +#endif +#ifndef ZEXTERN +# define ZEXTERN(x) static x +#endif +#ifndef ZEXTERNDEF +# define ZEXTERNDEF(x) static x +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(MACOS) && !defined(TARGET_OS_MAC) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#ifdef HAVE_UNISTD_H +# include <sys/types.h> /* for off_t */ +# include <unistd.h> /* for SEEK_* and off_t */ +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(inflate_blocks,"INBL") +# pragma map(inflate_blocks_new,"INBLNE") +# pragma map(inflate_blocks_free,"INBLFR") +# pragma map(inflate_blocks_reset,"INBLRE") +# pragma map(inflate_codes_free,"INCOFR") +# pragma map(inflate_codes,"INCO") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_flush,"INFLU") +# pragma map(inflate_mask,"INMA") +# pragma map(inflate_set_dictionary,"INSEDI2") +# pragma map(inflate_copyright,"INCOPY") +# pragma map(inflate_trees_bits,"INTRBI") +# pragma map(inflate_trees_dynamic,"INTRDY") +# pragma map(inflate_trees_fixed,"INTRFI") +# pragma map(inflate_trees_free,"INTRFR") +#endif + +#endif /* _ZCONF_H */ diff --git a/src/3rdparty/freetype/src/gzip/rules.mk b/src/3rdparty/freetype/src/gzip/rules.mk index a8f74ec3c3..1a2e48bebd 100644 --- a/src/3rdparty/freetype/src/gzip/rules.mk +++ b/src/3rdparty/freetype/src/gzip/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2002-2015 by +# Copyright 2002-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -34,12 +34,13 @@ endif # gzip support sources # -# All source and header files get loaded by `ftgzip.c' only if SYTEM_ZLIB is -# not defined (regardless whether we have a `single' or a `multi' build). +# All source and header files get loaded by `ftgzip.c' only if SYSTEM_ZLIB +# is not defined (regardless whether we have a `single' or a `multi' build). # However, it doesn't harm if we add everything as a dependency # unconditionally. # GZIP_DRV_SRCS := $(GZIP_DIR)/adler32.c \ + $(GZIP_DIR)/ftzconf.h \ $(GZIP_DIR)/infblock.c \ $(GZIP_DIR)/infblock.h \ $(GZIP_DIR)/infcodes.c \ @@ -50,7 +51,6 @@ GZIP_DRV_SRCS := $(GZIP_DIR)/adler32.c \ $(GZIP_DIR)/inftrees.h \ $(GZIP_DIR)/infutil.c \ $(GZIP_DIR)/infutil.h \ - $(GZIP_DIR)/zconf.h \ $(GZIP_DIR)/zlib.h \ $(GZIP_DIR)/zutil.c \ $(GZIP_DIR)/zutil.h diff --git a/src/3rdparty/freetype/src/gzip/zlib.h b/src/3rdparty/freetype/src/gzip/zlib.h index 50d0d3f146..a4e82c6a02 100644 --- a/src/3rdparty/freetype/src/gzip/zlib.h +++ b/src/3rdparty/freetype/src/gzip/zlib.h @@ -31,7 +31,7 @@ #ifndef _ZLIB_H #define _ZLIB_H -#include "zconf.h" +#include "ftzconf.h" #ifdef __cplusplus extern "C" { @@ -560,7 +560,7 @@ ZEXTERN(int) inflateInit2 OF((z_streamp strm, inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the success - case, the application may save the current current value of total_in which + case, the application may save the current value of total_in which indicates where valid compressed data was found. In the error case, the application may repeatedly call inflateSync, providing more input each time, until success or end of the input data. diff --git a/src/3rdparty/freetype/src/gzip/zutil.h b/src/3rdparty/freetype/src/gzip/zutil.h index 1949270998..c9688cd9c0 100644 --- a/src/3rdparty/freetype/src/gzip/zutil.h +++ b/src/3rdparty/freetype/src/gzip/zutil.h @@ -182,7 +182,7 @@ typedef unsigned long ulg; #endif /* Diagnostic functions */ -#if defined(DEBUG) && !defined(_WIN32_WCE) +#ifdef DEBUG # include <stdio.h> extern int z_verbose; extern void z_error OF((char *m)); diff --git a/src/3rdparty/freetype/src/lzw/Jamfile b/src/3rdparty/freetype/src/lzw/Jamfile index 91effe20c4..cb83aa4a56 100644 --- a/src/3rdparty/freetype/src/lzw/Jamfile +++ b/src/3rdparty/freetype/src/lzw/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/lzw Jamfile # -# Copyright 2004-2015 by +# Copyright 2004-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/lzw/ftlzw.c b/src/3rdparty/freetype/src/lzw/ftlzw.c index 2f4e3b0f1d..cb46f93c68 100644 --- a/src/3rdparty/freetype/src/lzw/ftlzw.c +++ b/src/3rdparty/freetype/src/lzw/ftlzw.c @@ -8,7 +8,7 @@ /* be used to parse compressed PCF fonts, as found with many X11 server */ /* distributions. */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* Albert Chin-A-Young. */ /* */ /* based on code in `src/gzip/ftgzip.c' */ @@ -31,7 +31,7 @@ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX LZW_Err_ diff --git a/src/3rdparty/freetype/src/lzw/ftzopen.c b/src/3rdparty/freetype/src/lzw/ftzopen.c index f96bb73d98..2b868ba9f2 100644 --- a/src/3rdparty/freetype/src/lzw/ftzopen.c +++ b/src/3rdparty/freetype/src/lzw/ftzopen.c @@ -8,7 +8,7 @@ /* be used to parse compressed PCF fonts, as found with many X11 server */ /* distributions. */ /* */ -/* Copyright 2005-2015 by */ +/* Copyright 2005-2018 by */ /* David Turner. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -42,7 +42,12 @@ state->buf_total += count; state->in_eof = FT_BOOL( count < state->num_bits ); state->buf_offset = 0; - state->buf_size = ( state->buf_size << 3 ) - ( state->num_bits - 1 ); + + state->buf_size <<= 3; + if ( state->buf_size > state->num_bits ) + state->buf_size -= state->num_bits - 1; + else + return -1; /* not enough data */ if ( count == 0 ) /* end of file */ return -1; @@ -66,7 +71,10 @@ { if ( state->free_ent >= state->free_bits ) { - state->num_bits = ++num_bits; + state->num_bits = ++num_bits; + if ( num_bits > LZW_MAX_BITS ) + return -1; + state->free_bits = state->num_bits < state->max_bits ? (FT_UInt)( ( 1UL << num_bits ) - 256 ) : state->max_free + 1; @@ -366,7 +374,7 @@ { while ( state->stack_top > 0 ) { - --state->stack_top; + state->stack_top--; if ( buffer ) buffer[result] = state->stack[state->stack_top]; diff --git a/src/3rdparty/freetype/src/lzw/ftzopen.h b/src/3rdparty/freetype/src/lzw/ftzopen.h index d35e380595..4fd267eb90 100644 --- a/src/3rdparty/freetype/src/lzw/ftzopen.h +++ b/src/3rdparty/freetype/src/lzw/ftzopen.h @@ -8,7 +8,7 @@ /* be used to parse compressed PCF fonts, as found with many X11 server */ /* distributions. */ /* */ -/* Copyright 2005-2015 by */ +/* Copyright 2005-2018 by */ /* David Turner. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,8 +19,8 @@ /* */ /***************************************************************************/ -#ifndef __FT_ZOPEN_H__ -#define __FT_ZOPEN_H__ +#ifndef FTZOPEN_H_ +#define FTZOPEN_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -166,7 +166,7 @@ /* */ -#endif /* __FT_ZOPEN_H__ */ +#endif /* FTZOPEN_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/lzw/rules.mk b/src/3rdparty/freetype/src/lzw/rules.mk index ab1c02fb50..18933c41c2 100644 --- a/src/3rdparty/freetype/src/lzw/rules.mk +++ b/src/3rdparty/freetype/src/lzw/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2004-2015 by +# Copyright 2004-2018 by # Albert Chin-A-Young. # # based on `src/lzw/rules.mk' diff --git a/src/3rdparty/freetype/src/otvalid/Jamfile b/src/3rdparty/freetype/src/otvalid/Jamfile index 461a222174..21b8e0cb0f 100644 --- a/src/3rdparty/freetype/src/otvalid/Jamfile +++ b/src/3rdparty/freetype/src/otvalid/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/otvalid Jamfile # -# Copyright 2004-2015 by +# Copyright 2004-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/otvalid/module.mk b/src/3rdparty/freetype/src/otvalid/module.mk index 3d8c0d9f2e..34f3dab32f 100644 --- a/src/3rdparty/freetype/src/otvalid/module.mk +++ b/src/3rdparty/freetype/src/otvalid/module.mk @@ -3,7 +3,7 @@ # -# Copyright 2004-2015 by +# Copyright 2004-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/otvalid/otvalid.c b/src/3rdparty/freetype/src/otvalid/otvalid.c index ca597d707c..4423ca1012 100644 --- a/src/3rdparty/freetype/src/otvalid/otvalid.c +++ b/src/3rdparty/freetype/src/otvalid/otvalid.c @@ -4,7 +4,7 @@ /* */ /* FreeType validator for OpenType tables (body only). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -15,8 +15,8 @@ /* */ /***************************************************************************/ -#define FT_MAKE_OPTION_SINGLE_OBJECT +#define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> #include "otvbase.c" @@ -28,4 +28,5 @@ #include "otvmath.c" #include "otvmod.c" + /* END */ diff --git a/src/3rdparty/freetype/src/otvalid/otvalid.h b/src/3rdparty/freetype/src/otvalid/otvalid.h index 3475deb7a2..d7801abae5 100644 --- a/src/3rdparty/freetype/src/otvalid/otvalid.h +++ b/src/3rdparty/freetype/src/otvalid/otvalid.h @@ -4,7 +4,7 @@ /* */ /* OpenType table validation (specification only). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __OTVALID_H__ -#define __OTVALID_H__ +#ifndef OTVALID_H_ +#define OTVALID_H_ #include <ft2build.h> @@ -72,7 +72,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __OTVALID_H__ */ +#endif /* OTVALID_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/otvalid/otvbase.c b/src/3rdparty/freetype/src/otvalid/otvbase.c index 24038c63b7..a01d45c707 100644 --- a/src/3rdparty/freetype/src/otvalid/otvbase.c +++ b/src/3rdparty/freetype/src/otvalid/otvbase.c @@ -4,7 +4,7 @@ /* */ /* OpenType BASE table validation (body). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -284,22 +284,41 @@ OTV_Validator otvalid = &otvalidrec; FT_Bytes p = table; FT_UInt table_size; + FT_UShort version; OTV_OPTIONAL_TABLE( HorizAxis ); OTV_OPTIONAL_TABLE( VertAxis ); + OTV_OPTIONAL_TABLE32( itemVarStore ); + otvalid->root = ftvalid; FT_TRACE3(( "validating BASE table\n" )); OTV_INIT; - OTV_LIMIT_CHECK( 6 ); + OTV_LIMIT_CHECK( 4 ); - if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ + if ( FT_NEXT_USHORT( p ) != 1 ) /* majorVersion */ FT_INVALID_FORMAT; - table_size = 6; + version = FT_NEXT_USHORT( p ); /* minorVersion */ + + table_size = 8; + switch ( version ) + { + case 0: + OTV_LIMIT_CHECK( 4 ); + break; + + case 1: + OTV_LIMIT_CHECK( 8 ); + table_size += 4; + break; + + default: + FT_INVALID_FORMAT; + } OTV_OPTIONAL_OFFSET( HorizAxis ); OTV_SIZE_CHECK( HorizAxis ); @@ -311,6 +330,14 @@ if ( VertAxis ) otv_Axis_validate( table + VertAxis, otvalid ); + if ( version > 0 ) + { + OTV_OPTIONAL_OFFSET32( itemVarStore ); + OTV_SIZE_CHECK32( itemVarStore ); + if ( itemVarStore ) + OTV_TRACE(( " [omitting itemVarStore validation]\n" )); /* XXX */ + } + FT_TRACE4(( "\n" )); } diff --git a/src/3rdparty/freetype/src/otvalid/otvcommn.c b/src/3rdparty/freetype/src/otvalid/otvcommn.c index 103ffba3e8..0ccfb03c08 100644 --- a/src/3rdparty/freetype/src/otvalid/otvcommn.c +++ b/src/3rdparty/freetype/src/otvalid/otvcommn.c @@ -4,7 +4,7 @@ /* */ /* OpenType common tables validation (body). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -68,7 +68,7 @@ OTV_LIMIT_CHECK( GlyphCount * 2 ); /* GlyphArray */ - for ( i = 0; i < GlyphCount; ++i ) + for ( i = 0; i < GlyphCount; i++ ) { FT_UInt gid; @@ -313,19 +313,26 @@ OTV_NAME_ENTER( "Device" ); - OTV_LIMIT_CHECK( 8 ); + OTV_LIMIT_CHECK( 6 ); StartSize = FT_NEXT_USHORT( p ); EndSize = FT_NEXT_USHORT( p ); DeltaFormat = FT_NEXT_USHORT( p ); - if ( DeltaFormat < 1 || DeltaFormat > 3 ) - FT_INVALID_FORMAT; + if ( DeltaFormat == 0x8000U ) + { + /* VariationIndex, nothing to do */ + } + else + { + if ( DeltaFormat < 1 || DeltaFormat > 3 ) + FT_INVALID_FORMAT; - if ( EndSize < StartSize ) - FT_INVALID_DATA; + if ( EndSize < StartSize ) + FT_INVALID_DATA; - count = EndSize - StartSize + 1; - OTV_LIMIT_CHECK( ( 1 << DeltaFormat ) * count / 8 ); /* DeltaValue */ + count = EndSize - StartSize + 1; + OTV_LIMIT_CHECK( ( 1 << DeltaFormat ) * count / 8 ); /* DeltaValue */ + } OTV_EXIT; } @@ -347,7 +354,7 @@ OTV_Validator otvalid ) { FT_Bytes p = table; - FT_UInt LookupType, SubTableCount; + FT_UInt LookupType, LookupFlag, SubTableCount; OTV_Validate_Func validate; @@ -355,7 +362,7 @@ OTV_LIMIT_CHECK( 6 ); LookupType = FT_NEXT_USHORT( p ); - p += 2; /* skip LookupFlag */ + LookupFlag = FT_NEXT_USHORT( p ); SubTableCount = FT_NEXT_USHORT( p ); OTV_TRACE(( " (type %d)\n", LookupType )); @@ -373,6 +380,9 @@ for ( ; SubTableCount > 0; SubTableCount-- ) validate( table + FT_NEXT_USHORT( p ), otvalid ); + if ( LookupFlag & 0x10 ) + OTV_LIMIT_CHECK( 2 ); /* MarkFilteringSet */ + OTV_EXIT; } diff --git a/src/3rdparty/freetype/src/otvalid/otvcommn.h b/src/3rdparty/freetype/src/otvalid/otvcommn.h index 3aebf0200d..a392784cf1 100644 --- a/src/3rdparty/freetype/src/otvalid/otvcommn.h +++ b/src/3rdparty/freetype/src/otvalid/otvcommn.h @@ -4,7 +4,7 @@ /* */ /* OpenType common tables validation (specification). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __OTVCOMMN_H__ -#define __OTVCOMMN_H__ +#ifndef OTVCOMMN_H_ +#define OTVCOMMN_H_ #include <ft2build.h> @@ -67,29 +67,38 @@ FT_BEGIN_HEADER #undef FT_INVALID_ -#define FT_INVALID_( _error ) \ +#define FT_INVALID_( _error ) \ ft_validator_error( otvalid->root, FT_THROW( _error ) ) #define OTV_OPTIONAL_TABLE( _table ) FT_UShort _table; \ FT_Bytes _table ## _p +#define OTV_OPTIONAL_TABLE32( _table ) FT_ULong _table; \ + FT_Bytes _table ## _p + #define OTV_OPTIONAL_OFFSET( _offset ) \ FT_BEGIN_STMNT \ _offset ## _p = p; \ _offset = FT_NEXT_USHORT( p ); \ FT_END_STMNT -#define OTV_LIMIT_CHECK( _count ) \ - FT_BEGIN_STMNT \ +#define OTV_OPTIONAL_OFFSET32( _offset ) \ + FT_BEGIN_STMNT \ + _offset ## _p = p; \ + _offset = FT_NEXT_ULONG( p ); \ + FT_END_STMNT + +#define OTV_LIMIT_CHECK( _count ) \ + FT_BEGIN_STMNT \ if ( p + (_count) > otvalid->root->limit ) \ - FT_INVALID_TOO_SHORT; \ + FT_INVALID_TOO_SHORT; \ FT_END_STMNT #define OTV_SIZE_CHECK( _size ) \ FT_BEGIN_STMNT \ if ( _size > 0 && _size < table_size ) \ { \ - if ( otvalid->root->level == FT_VALIDATE_PARANOID ) \ + if ( otvalid->root->level == FT_VALIDATE_PARANOID ) \ FT_INVALID_OFFSET; \ else \ { \ @@ -102,12 +111,33 @@ FT_BEGIN_HEADER " set to zero.\n" \ "\n", #_size )); \ \ - /* always assume 16bit entities */ \ _size = pp[0] = pp[1] = 0; \ } \ } \ FT_END_STMNT +#define OTV_SIZE_CHECK32( _size ) \ + FT_BEGIN_STMNT \ + if ( _size > 0 && _size < table_size ) \ + { \ + if ( otvalid->root->level == FT_VALIDATE_PARANOID ) \ + FT_INVALID_OFFSET; \ + else \ + { \ + /* strip off `const' */ \ + FT_Byte* pp = (FT_Byte*)_size ## _p; \ + \ + \ + FT_TRACE3(( "\n" \ + "Invalid offset to optional table `%s'" \ + " set to zero.\n" \ + "\n", #_size )); \ + \ + _size = pp[0] = pp[1] = pp[2] = pp[3] = 0; \ + } \ + } \ + FT_END_STMNT + #define OTV_NAME_(x) #x #define OTV_NAME(x) OTV_NAME_(x) @@ -146,11 +176,11 @@ FT_BEGIN_HEADER #define OTV_INIT otvalid->debug_indent = 0 -#define OTV_ENTER \ - FT_BEGIN_STMNT \ - otvalid->debug_indent += 2; \ - FT_TRACE4(( "%*.s", otvalid->debug_indent, 0 )); \ - FT_TRACE4(( "%s table\n", \ +#define OTV_ENTER \ + FT_BEGIN_STMNT \ + otvalid->debug_indent += 2; \ + FT_TRACE4(( "%*.s", otvalid->debug_indent, 0 )); \ + FT_TRACE4(( "%s table\n", \ otvalid->debug_function_name[otvalid->nesting_level] )); \ FT_END_STMNT @@ -431,7 +461,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __OTVCOMMN_H__ */ +#endif /* OTVCOMMN_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/otvalid/otverror.h b/src/3rdparty/freetype/src/otvalid/otverror.h index 214795e170..2fcf42e387 100644 --- a/src/3rdparty/freetype/src/otvalid/otverror.h +++ b/src/3rdparty/freetype/src/otvalid/otverror.h @@ -4,7 +4,7 @@ /* */ /* OpenType validation module error codes (specification only). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __OTVERROR_H__ -#define __OTVERROR_H__ +#ifndef OTVERROR_H_ +#define OTVERROR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX OTV_Err_ @@ -36,7 +36,7 @@ #include FT_ERRORS_H -#endif /* __OTVERROR_H__ */ +#endif /* OTVERROR_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/otvalid/otvgdef.c b/src/3rdparty/freetype/src/otvalid/otvgdef.c index 8269d2f5b8..08f3171541 100644 --- a/src/3rdparty/freetype/src/otvalid/otvgdef.c +++ b/src/3rdparty/freetype/src/otvalid/otvgdef.c @@ -4,7 +4,7 @@ /* */ /* OpenType GDEF table validation (body). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -68,7 +68,7 @@ OTV_LIMIT_CHECK( GlyphCount * 2 ); otvalid->nesting_level++; - func = otvalid->func[otvalid->nesting_level]; + func = otvalid->func[otvalid->nesting_level]; otvalid->extra1 = 0; for ( ; GlyphCount > 0; GlyphCount-- ) @@ -133,6 +133,40 @@ } + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** MARK GLYPH SETS *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + static void + otv_MarkGlyphSets_validate( FT_Bytes table, + OTV_Validator otvalid ) + { + FT_Bytes p = table; + FT_UInt MarkGlyphSetCount; + + + OTV_NAME_ENTER( "MarkGlyphSets" ); + + p += 2; /* skip Format */ + + OTV_LIMIT_CHECK( 2 ); + MarkGlyphSetCount = FT_NEXT_USHORT( p ); + + OTV_TRACE(( " (MarkGlyphSetCount = %d)\n", MarkGlyphSetCount )); + + OTV_LIMIT_CHECK( MarkGlyphSetCount * 4 ); /* CoverageOffsets */ + + for ( ; MarkGlyphSetCount > 0; MarkGlyphSetCount-- ) + otv_Coverage_validate( table + FT_NEXT_ULONG( p ), otvalid, -1 ); + + OTV_EXIT; + } + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -152,14 +186,18 @@ { OTV_ValidatorRec otvalidrec; OTV_Validator otvalid = &otvalidrec; - FT_Bytes p = table; + FT_Bytes p = table; FT_UInt table_size; - FT_Bool need_MarkAttachClassDef; + FT_UShort version; + FT_Bool need_MarkAttachClassDef = 1; OTV_OPTIONAL_TABLE( GlyphClassDef ); OTV_OPTIONAL_TABLE( AttachListOffset ); OTV_OPTIONAL_TABLE( LigCaretListOffset ); OTV_OPTIONAL_TABLE( MarkAttachClassDef ); + OTV_OPTIONAL_TABLE( MarkGlyphSetsDef ); + + OTV_OPTIONAL_TABLE32( itemVarStore ); otvalid->root = ftvalid; @@ -167,24 +205,49 @@ FT_TRACE3(( "validating GDEF table\n" )); OTV_INIT; - OTV_LIMIT_CHECK( 12 ); + OTV_LIMIT_CHECK( 4 ); - if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ + if ( FT_NEXT_USHORT( p ) != 1 ) /* majorVersion */ FT_INVALID_FORMAT; - /* MarkAttachClassDef has been added to the OpenType */ - /* specification without increasing GDEF's version, */ - /* so we use this ugly hack to find out whether the */ - /* table is needed actually. */ + version = FT_NEXT_USHORT( p ); /* minorVersion */ - need_MarkAttachClassDef = FT_BOOL( - otv_GSUBGPOS_have_MarkAttachmentType_flag( gsub ) || - otv_GSUBGPOS_have_MarkAttachmentType_flag( gpos ) ); + table_size = 10; + switch ( version ) + { + case 0: + /* MarkAttachClassDef has been added to the OpenType */ + /* specification without increasing GDEF's version, */ + /* so we use this ugly hack to find out whether the */ + /* table is needed actually. */ - if ( need_MarkAttachClassDef ) - table_size = 12; /* OpenType >= 1.2 */ - else - table_size = 10; /* OpenType < 1.2 */ + need_MarkAttachClassDef = FT_BOOL( + otv_GSUBGPOS_have_MarkAttachmentType_flag( gsub ) || + otv_GSUBGPOS_have_MarkAttachmentType_flag( gpos ) ); + + if ( need_MarkAttachClassDef ) + { + OTV_LIMIT_CHECK( 8 ); + table_size += 2; + } + else + OTV_LIMIT_CHECK( 6 ); /* OpenType < 1.2 */ + + break; + + case 2: + OTV_LIMIT_CHECK( 10 ); + table_size += 4; + break; + + case 3: + OTV_LIMIT_CHECK( 14 ); + table_size += 8; + break; + + default: + FT_INVALID_FORMAT; + } otvalid->glyph_count = glyph_count; @@ -217,6 +280,22 @@ otv_ClassDef_validate( table + MarkAttachClassDef, otvalid ); } + if ( version > 0 ) + { + OTV_OPTIONAL_OFFSET( MarkGlyphSetsDef ); + OTV_SIZE_CHECK( MarkGlyphSetsDef ); + if ( MarkGlyphSetsDef ) + otv_MarkGlyphSets_validate( table + MarkGlyphSetsDef, otvalid ); + } + + if ( version > 2 ) + { + OTV_OPTIONAL_OFFSET32( itemVarStore ); + OTV_SIZE_CHECK32( itemVarStore ); + if ( itemVarStore ) + OTV_TRACE(( " [omitting itemVarStore validation]\n" )); /* XXX */ + } + FT_TRACE4(( "\n" )); } diff --git a/src/3rdparty/freetype/src/otvalid/otvgpos.c b/src/3rdparty/freetype/src/otvalid/otvgpos.c index 44c43c53a1..696b35cae6 100644 --- a/src/3rdparty/freetype/src/otvalid/otvgpos.c +++ b/src/3rdparty/freetype/src/otvalid/otvgpos.c @@ -4,7 +4,7 @@ /* */ /* OpenType GPOS table validation (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -130,7 +130,7 @@ otv_MarkArray_validate( table + Array1, otvalid ); otvalid->nesting_level++; - func = otvalid->func[otvalid->nesting_level]; + func = otvalid->func[otvalid->nesting_level]; otvalid->extra1 = ClassCount; func( table + Array2, otvalid ); @@ -218,10 +218,6 @@ OTV_LIMIT_CHECK( 2 ); OTV_OPTIONAL_OFFSET( device ); - /* XXX: this value is usually too small, especially if the current */ - /* ValueRecord is part of an array -- getting the correct table */ - /* size is probably not worth the trouble */ - table_size = p - otvalid->extra3; OTV_SIZE_CHECK( device ); @@ -271,7 +267,7 @@ case 3: { - FT_UInt table_size; + FT_UInt table_size; OTV_OPTIONAL_TABLE( XDeviceTable ); OTV_OPTIONAL_TABLE( YDeviceTable ); @@ -426,6 +422,8 @@ /*************************************************************************/ /*************************************************************************/ + /* sets otvalid->extra3 (pointer to base table) */ + static void otv_PairSet_validate( FT_Bytes table, FT_UInt format1, @@ -438,6 +436,8 @@ OTV_NAME_ENTER( "PairSet" ); + otvalid->extra3 = table; + OTV_LIMIT_CHECK( 2 ); PairValueCount = FT_NEXT_USHORT( p ); @@ -483,8 +483,6 @@ OTV_TRACE(( " (format %d)\n", PosFormat )); - otvalid->extra3 = table; - switch ( PosFormat ) { case 1: /* PairPosFormat1 */ @@ -537,7 +535,9 @@ otv_ClassDef_validate( table + ClassDef2, otvalid ); OTV_LIMIT_CHECK( ClassCount1 * ClassCount2 * - ( len_value1 + len_value2 ) ); + ( len_value1 + len_value2 ) ); + + otvalid->extra3 = table; /* Class1Record */ for ( ; ClassCount1 > 0; ClassCount1-- ) @@ -985,20 +985,42 @@ { OTV_ValidatorRec validrec; OTV_Validator otvalid = &validrec; - FT_Bytes p = table; + FT_Bytes p = table; + FT_UInt table_size; + FT_UShort version; FT_UInt ScriptList, FeatureList, LookupList; + OTV_OPTIONAL_TABLE32( featureVariations ); + otvalid->root = ftvalid; FT_TRACE3(( "validating GPOS table\n" )); OTV_INIT; - OTV_LIMIT_CHECK( 10 ); + OTV_LIMIT_CHECK( 4 ); - if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ + if ( FT_NEXT_USHORT( p ) != 1 ) /* majorVersion */ FT_INVALID_FORMAT; + version = FT_NEXT_USHORT( p ); /* minorVersion */ + + table_size = 10; + switch ( version ) + { + case 0: + OTV_LIMIT_CHECK( 6 ); + break; + + case 1: + OTV_LIMIT_CHECK( 10 ); + table_size += 4; + break; + + default: + FT_INVALID_FORMAT; + } + ScriptList = FT_NEXT_USHORT( p ); FeatureList = FT_NEXT_USHORT( p ); LookupList = FT_NEXT_USHORT( p ); @@ -1014,6 +1036,14 @@ otv_ScriptList_validate( table + ScriptList, table + FeatureList, otvalid ); + if ( version > 0 ) + { + OTV_OPTIONAL_OFFSET32( featureVariations ); + OTV_SIZE_CHECK32( featureVariations ); + if ( featureVariations ) + OTV_TRACE(( " [omitting featureVariations validation]\n" )); /* XXX */ + } + FT_TRACE4(( "\n" )); } diff --git a/src/3rdparty/freetype/src/otvalid/otvgpos.h b/src/3rdparty/freetype/src/otvalid/otvgpos.h index a792bd9519..95f9ac3ee8 100644 --- a/src/3rdparty/freetype/src/otvalid/otvgpos.h +++ b/src/3rdparty/freetype/src/otvalid/otvgpos.h @@ -4,7 +4,7 @@ /* */ /* OpenType GPOS table validator (specification). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __OTVGPOS_H__ -#define __OTVGPOS_H__ +#ifndef OTVGPOS_H_ +#define OTVGPOS_H_ FT_BEGIN_HEADER @@ -30,7 +30,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __OTVGPOS_H__ */ +#endif /* OTVGPOS_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/otvalid/otvgsub.c b/src/3rdparty/freetype/src/otvalid/otvgsub.c index 0f8b02cd20..d35ea67f30 100644 --- a/src/3rdparty/freetype/src/otvalid/otvgsub.c +++ b/src/3rdparty/freetype/src/otvalid/otvgsub.c @@ -4,7 +4,7 @@ /* */ /* OpenType GSUB table validation (body). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -552,19 +552,41 @@ OTV_ValidatorRec otvalidrec; OTV_Validator otvalid = &otvalidrec; FT_Bytes p = table; + FT_UInt table_size; + FT_UShort version; FT_UInt ScriptList, FeatureList, LookupList; + OTV_OPTIONAL_TABLE32( featureVariations ); + otvalid->root = ftvalid; FT_TRACE3(( "validating GSUB table\n" )); OTV_INIT; - OTV_LIMIT_CHECK( 10 ); + OTV_LIMIT_CHECK( 4 ); - if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ + if ( FT_NEXT_USHORT( p ) != 1 ) /* majorVersion */ FT_INVALID_FORMAT; + version = FT_NEXT_USHORT( p ); /* minorVersion */ + + table_size = 10; + switch ( version ) + { + case 0: + OTV_LIMIT_CHECK( 6 ); + break; + + case 1: + OTV_LIMIT_CHECK( 10 ); + table_size += 4; + break; + + default: + FT_INVALID_FORMAT; + } + ScriptList = FT_NEXT_USHORT( p ); FeatureList = FT_NEXT_USHORT( p ); LookupList = FT_NEXT_USHORT( p ); @@ -580,6 +602,14 @@ otv_ScriptList_validate( table + ScriptList, table + FeatureList, otvalid ); + if ( version > 0 ) + { + OTV_OPTIONAL_OFFSET32( featureVariations ); + OTV_SIZE_CHECK32( featureVariations ); + if ( featureVariations ) + OTV_TRACE(( " [omitting featureVariations validation]\n" )); /* XXX */ + } + FT_TRACE4(( "\n" )); } diff --git a/src/3rdparty/freetype/src/otvalid/otvjstf.c b/src/3rdparty/freetype/src/otvalid/otvjstf.c index fe68a60f60..94d4af90f6 100644 --- a/src/3rdparty/freetype/src/otvalid/otvjstf.c +++ b/src/3rdparty/freetype/src/otvalid/otvjstf.c @@ -4,7 +4,7 @@ /* */ /* OpenType JSTF table validation (body). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/src/otvalid/otvmath.c b/src/3rdparty/freetype/src/otvalid/otvmath.c index db3d5f8f52..b9800f60a2 100644 --- a/src/3rdparty/freetype/src/otvalid/otvmath.c +++ b/src/3rdparty/freetype/src/otvalid/otvmath.c @@ -4,7 +4,7 @@ /* */ /* OpenType MATH table validation (body). */ /* */ -/* Copyright 2007-2015 by */ +/* Copyright 2007-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* Written by George Williams. */ @@ -60,7 +60,7 @@ table_size = 2 * ( 56 + 51 ); p += 4 * 2; /* First 4 constants have no device tables */ - for ( i = 0; i < 51; ++i ) + for ( i = 0; i < 51; i++ ) { p += 2; /* skip the value */ OTV_OPTIONAL_OFFSET( DeviceTableOffset ); @@ -88,7 +88,7 @@ FT_Int isItalic ) { FT_Bytes p = table; - FT_UInt i, cnt, table_size ; + FT_UInt i, cnt, table_size; OTV_OPTIONAL_TABLE( Coverage ); OTV_OPTIONAL_TABLE( DeviceTableOffset ); @@ -110,7 +110,7 @@ OTV_SIZE_CHECK( Coverage ); otv_Coverage_validate( table + Coverage, otvalid, (FT_Int)cnt ); - for ( i = 0; i < cnt; ++i ) + for ( i = 0; i < cnt; i++ ) { p += 2; /* Skip the value */ OTV_OPTIONAL_OFFSET( DeviceTableOffset ); @@ -151,7 +151,7 @@ table_size = 4 + 4 * cnt; /* Heights */ - for ( i = 0; i < cnt; ++i ) + for ( i = 0; i < cnt; i++ ) { p += 2; /* Skip the value */ OTV_OPTIONAL_OFFSET( DeviceTableOffset ); @@ -161,7 +161,7 @@ } /* One more Kerning value */ - for ( i = 0; i < cnt + 1; ++i ) + for ( i = 0; i < cnt + 1; i++ ) { p += 2; /* Skip the value */ OTV_OPTIONAL_OFFSET( DeviceTableOffset ); @@ -198,9 +198,9 @@ OTV_SIZE_CHECK( Coverage ); otv_Coverage_validate( table + Coverage, otvalid, (FT_Int)cnt ); - for ( i = 0; i < cnt; ++i ) + for ( i = 0; i < cnt; i++ ) { - for ( j = 0; j < 4; ++j ) + for ( j = 0; j < 4; j++ ) { OTV_OPTIONAL_OFFSET( MKRecordOffset ); OTV_SIZE_CHECK( MKRecordOffset ); @@ -296,7 +296,7 @@ if ( DeviceTableOffset ) otv_Device_validate( table + DeviceTableOffset, otvalid ); - for ( i = 0; i < pcnt; ++i ) + for ( i = 0; i < pcnt; i++ ) { FT_UInt gid; @@ -332,7 +332,7 @@ OTV_LIMIT_CHECK( 4 * vcnt ); table_size = 4 + 4 * vcnt; - for ( i = 0; i < vcnt; ++i ) + for ( i = 0; i < vcnt; i++ ) { FT_UInt gid; @@ -384,14 +384,14 @@ if ( HCoverage ) otv_Coverage_validate( table + HCoverage, otvalid, (FT_Int)hcnt ); - for ( i = 0; i < vcnt; ++i ) + for ( i = 0; i < vcnt; i++ ) { OTV_OPTIONAL_OFFSET( Offset ); OTV_SIZE_CHECK( Offset ); otv_MathGlyphConstruction_validate( table + Offset, otvalid ); } - for ( i = 0; i < hcnt; ++i ) + for ( i = 0; i < hcnt; i++ ) { OTV_OPTIONAL_OFFSET( Offset ); OTV_SIZE_CHECK( Offset ); diff --git a/src/3rdparty/freetype/src/otvalid/otvmod.c b/src/3rdparty/freetype/src/otvalid/otvmod.c index 92f851398d..89ee449d16 100644 --- a/src/3rdparty/freetype/src/otvalid/otvmod.c +++ b/src/3rdparty/freetype/src/otvalid/otvmod.c @@ -4,7 +4,7 @@ /* */ /* FreeType's OpenType validation module implementation (body). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -240,7 +240,7 @@ static const FT_Service_OTvalidateRec otvalid_interface = { - otv_validate + otv_validate /* validate */ }; @@ -271,11 +271,11 @@ 0x10000L, 0x20000L, - 0, /* module-specific interface */ + NULL, /* module-specific interface */ - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) otvalid_get_service + (FT_Module_Constructor)NULL, /* module_init */ + (FT_Module_Destructor) NULL, /* module_done */ + (FT_Module_Requester) otvalid_get_service /* get_interface */ }; diff --git a/src/3rdparty/freetype/src/otvalid/otvmod.h b/src/3rdparty/freetype/src/otvalid/otvmod.h index c3a0234e9e..6917bccee5 100644 --- a/src/3rdparty/freetype/src/otvalid/otvmod.h +++ b/src/3rdparty/freetype/src/otvalid/otvmod.h @@ -5,7 +5,7 @@ /* FreeType's OpenType validation module implementation */ /* (specification). */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __OTVMOD_H__ -#define __OTVMOD_H__ +#ifndef OTVMOD_H_ +#define OTVMOD_H_ #include <ft2build.h> @@ -37,7 +37,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __OTVMOD_H__ */ +#endif /* OTVMOD_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/otvalid/rules.mk b/src/3rdparty/freetype/src/otvalid/rules.mk index 56d749cc97..d4fc723740 100644 --- a/src/3rdparty/freetype/src/otvalid/rules.mk +++ b/src/3rdparty/freetype/src/otvalid/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2004-2015 by +# Copyright 2004-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/pcf/Jamfile b/src/3rdparty/freetype/src/pcf/Jamfile index f4789ea625..7b92b12ddc 100644 --- a/src/3rdparty/freetype/src/pcf/Jamfile +++ b/src/3rdparty/freetype/src/pcf/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/pcf Jamfile # -# Copyright 2001-2015 by +# Copyright 2001-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/pcf/README b/src/3rdparty/freetype/src/pcf/README index 10eff15fbe..09ea970eda 100644 --- a/src/3rdparty/freetype/src/pcf/README +++ b/src/3rdparty/freetype/src/pcf/README @@ -41,8 +41,8 @@ value given as argument into the corresponding glyph number. Known problems ************** -- dealing explicitly with encodings breaks the uniformity of freetype2 - api. +- dealing explicitly with encodings breaks the uniformity of FreeType 2 + API. - except for encodings properties, client applications have no visibility of the PCF_Face object. This means that applications diff --git a/src/3rdparty/freetype/src/pcf/pcf.c b/src/3rdparty/freetype/src/pcf/pcf.c index 11d5b7b2a0..8ffd6e280b 100644 --- a/src/3rdparty/freetype/src/pcf/pcf.c +++ b/src/3rdparty/freetype/src/pcf/pcf.c @@ -26,11 +26,11 @@ THE SOFTWARE. #define FT_MAKE_OPTION_SINGLE_OBJECT - - #include <ft2build.h> -#include "pcfutil.c" -#include "pcfread.c" + #include "pcfdrivr.c" +#include "pcfread.c" +#include "pcfutil.c" + /* END */ diff --git a/src/3rdparty/freetype/src/pcf/pcf.h b/src/3rdparty/freetype/src/pcf/pcf.h index c0da503412..f0390cb1eb 100644 --- a/src/3rdparty/freetype/src/pcf/pcf.h +++ b/src/3rdparty/freetype/src/pcf/pcf.h @@ -25,8 +25,8 @@ THE SOFTWARE. */ -#ifndef __PCF_H__ -#define __PCF_H__ +#ifndef PCF_H_ +#define PCF_H_ #include <ft2build.h> @@ -163,6 +163,15 @@ FT_BEGIN_HEADER } PCF_FaceRec, *PCF_Face; + typedef struct PCF_DriverRec_ + { + FT_DriverRec root; + + FT_Bool no_long_family_names; + + } PCF_DriverRec, *PCF_Driver; + + /* macros for pcf font format */ #define LSBFirst 0 @@ -226,12 +235,13 @@ FT_BEGIN_HEADER #define GLYPHPADOPTIONS 4 /* I'm not sure about this */ FT_LOCAL( FT_Error ) - pcf_load_font( FT_Stream, - PCF_Face ); + pcf_load_font( FT_Stream stream, + PCF_Face face, + FT_Long face_index ); FT_END_HEADER -#endif /* __PCF_H__ */ +#endif /* PCF_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/pcf/pcfdrivr.c b/src/3rdparty/freetype/src/pcf/pcfdrivr.c index 8d2ed7cf4d..0119d94853 100644 --- a/src/3rdparty/freetype/src/pcf/pcfdrivr.c +++ b/src/3rdparty/freetype/src/pcf/pcfdrivr.c @@ -49,6 +49,8 @@ THE SOFTWARE. #include FT_SERVICE_BDF_H #include FT_SERVICE_FONT_FORMAT_H +#include FT_SERVICE_PROPERTIES_H +#include FT_DRIVER_H /*************************************************************************/ @@ -271,7 +273,7 @@ THE SOFTWARE. FT_TRACE2(( "PCF driver\n" )); - error = pcf_load_font( stream, face ); + error = pcf_load_font( stream, face, face_index ); if ( error ) { PCF_Face_Done( pcfface ); @@ -286,6 +288,7 @@ THE SOFTWARE. /* this didn't work, try gzip support! */ + FT_TRACE2(( " ... try gzip stream\n" )); error2 = FT_Stream_OpenGzip( &face->comp_stream, stream ); if ( FT_ERR_EQ( error2, Unimplemented_Feature ) ) goto Fail; @@ -301,6 +304,7 @@ THE SOFTWARE. /* this didn't work, try LZW support! */ + FT_TRACE2(( " ... try LZW stream\n" )); error3 = FT_Stream_OpenLZW( &face->comp_stream, stream ); if ( FT_ERR_EQ( error3, Unimplemented_Feature ) ) goto Fail; @@ -316,6 +320,7 @@ THE SOFTWARE. /* this didn't work, try Bzip2 support! */ + FT_TRACE2(( " ... try Bzip2 stream\n" )); error4 = FT_Stream_OpenBzip2( &face->comp_stream, stream ); if ( FT_ERR_EQ( error4, Unimplemented_Feature ) ) goto Fail; @@ -332,7 +337,7 @@ THE SOFTWARE. stream = pcfface->stream; - error = pcf_load_font( stream, face ); + error = pcf_load_font( stream, face, face_index ); if ( error ) goto Fail; @@ -351,7 +356,9 @@ THE SOFTWARE. * an invalid argument error when the font could be * opened by the specified driver. */ - if ( face_index > 0 && ( face_index & 0xFFFF ) > 0 ) + if ( face_index < 0 ) + goto Exit; + else if ( face_index > 0 && ( face_index & 0xFFFF ) > 0 ) { FT_ERROR(( "PCF_Face_Init: invalid face index\n" )); PCF_Face_Done( pcfface ); @@ -380,7 +387,11 @@ THE SOFTWARE. if ( !ft_strcmp( s, "10646" ) || ( !ft_strcmp( s, "8859" ) && !ft_strcmp( face->charset_encoding, "1" ) ) ) - unicode_charmap = 1; + unicode_charmap = 1; + /* another name for ASCII */ + else if ( !ft_strcmp( s, "646.1991" ) && + !ft_strcmp( face->charset_encoding, "IRV" ) ) + unicode_charmap = 1; } } @@ -402,12 +413,6 @@ THE SOFTWARE. } error = FT_CMap_New( &pcf_cmap_class, NULL, &charmap, NULL ); - -#if 0 - /* Select default charmap */ - if ( pcfface->num_charmaps ) - pcfface->charmap = pcfface->charmaps[0]; -#endif } } @@ -490,8 +495,6 @@ THE SOFTWARE. PCF_Metric metric; FT_ULong bytes; - FT_UNUSED( load_flags ); - FT_TRACE1(( "PCF_Glyph_Load: glyph index %d\n", glyph_index )); @@ -521,11 +524,6 @@ THE SOFTWARE. bitmap->num_grays = 1; bitmap->pixel_mode = FT_PIXEL_MODE_MONO; - FT_TRACE6(( "BIT_ORDER %d ; BYTE_ORDER %d ; GLYPH_PAD %d\n", - PCF_BIT_ORDER( face->bitmapsFormat ), - PCF_BYTE_ORDER( face->bitmapsFormat ), - PCF_GLYPH_PAD( face->bitmapsFormat ) )); - switch ( PCF_GLYPH_PAD( face->bitmapsFormat ) ) { case 1: @@ -548,6 +546,24 @@ THE SOFTWARE. return FT_THROW( Invalid_File_Format ); } + slot->format = FT_GLYPH_FORMAT_BITMAP; + slot->bitmap_left = metric->leftSideBearing; + slot->bitmap_top = metric->ascent; + + slot->metrics.horiAdvance = (FT_Pos)( metric->characterWidth * 64 ); + slot->metrics.horiBearingX = (FT_Pos)( metric->leftSideBearing * 64 ); + slot->metrics.horiBearingY = (FT_Pos)( metric->ascent * 64 ); + slot->metrics.width = (FT_Pos)( ( metric->rightSideBearing - + metric->leftSideBearing ) * 64 ); + slot->metrics.height = (FT_Pos)( bitmap->rows * 64 ); + + ft_synthesize_vertical_metrics( &slot->metrics, + ( face->accel.fontAscent + + face->accel.fontDescent ) * 64 ); + + if ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) + goto Exit; + /* XXX: to do: are there cases that need repadding the bitmap? */ bytes = (FT_ULong)bitmap->pitch * bitmap->rows; @@ -580,21 +596,6 @@ THE SOFTWARE. } } - slot->format = FT_GLYPH_FORMAT_BITMAP; - slot->bitmap_left = metric->leftSideBearing; - slot->bitmap_top = metric->ascent; - - slot->metrics.horiAdvance = (FT_Pos)( metric->characterWidth * 64 ); - slot->metrics.horiBearingX = (FT_Pos)( metric->leftSideBearing * 64 ); - slot->metrics.horiBearingY = (FT_Pos)( metric->ascent * 64 ); - slot->metrics.width = (FT_Pos)( ( metric->rightSideBearing - - metric->leftSideBearing ) * 64 ); - slot->metrics.height = (FT_Pos)( bitmap->rows * 64 ); - - ft_synthesize_vertical_metrics( &slot->metrics, - ( face->accel.fontAscent + - face->accel.fontDescent ) * 64 ); - Exit: return error; } @@ -615,7 +616,7 @@ THE SOFTWARE. prop = pcf_find_property( face, prop_name ); - if ( prop != NULL ) + if ( prop ) { if ( prop->isString ) { @@ -624,19 +625,23 @@ THE SOFTWARE. } else { - if ( prop->value.l > 0x7FFFFFFFL || prop->value.l < ( -1 - 0x7FFFFFFFL ) ) + if ( prop->value.l > 0x7FFFFFFFL || + prop->value.l < ( -1 - 0x7FFFFFFFL ) ) { - FT_TRACE1(( "pcf_get_bdf_property: " )); - FT_TRACE1(( "too large integer 0x%x is truncated\n" )); + FT_TRACE1(( "pcf_get_bdf_property:" )); + FT_TRACE1(( " too large integer 0x%x is truncated\n" )); } - /* Apparently, the PCF driver loads all properties as signed integers! - * This really doesn't seem to be a problem, because this is - * sufficient for any meaningful values. + + /* + * The PCF driver loads all properties as signed integers. + * This really doesn't seem to be a problem, because this is + * sufficient for any meaningful values. */ aproperty->type = BDF_PROPERTY_TYPE_INTEGER; aproperty->u.integer = (FT_Int32)prop->value.l; } - return 0; + + return FT_Err_Ok; } return FT_THROW( Invalid_Argument ); @@ -651,17 +656,127 @@ THE SOFTWARE. *acharset_encoding = face->charset_encoding; *acharset_registry = face->charset_registry; - return 0; + return FT_Err_Ok; } static const FT_Service_BDFRec pcf_service_bdf = { - (FT_BDF_GetCharsetIdFunc)pcf_get_charset_id, - (FT_BDF_GetPropertyFunc) pcf_get_bdf_property + (FT_BDF_GetCharsetIdFunc)pcf_get_charset_id, /* get_charset_id */ + (FT_BDF_GetPropertyFunc) pcf_get_bdf_property /* get_property */ }; + /* + * PROPERTY SERVICE + * + */ + static FT_Error + pcf_property_set( FT_Module module, /* PCF_Driver */ + const char* property_name, + const void* value, + FT_Bool value_is_string ) + { +#ifdef PCF_CONFIG_OPTION_LONG_FAMILY_NAMES + + FT_Error error = FT_Err_Ok; + PCF_Driver driver = (PCF_Driver)module; + +#ifndef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + FT_UNUSED( value_is_string ); +#endif + + + if ( !ft_strcmp( property_name, "no-long-family-names" ) ) + { +#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + if ( value_is_string ) + { + const char* s = (const char*)value; + long lfn = ft_strtol( s, NULL, 10 ); + + + if ( lfn == 0 ) + driver->no_long_family_names = 0; + else if ( lfn == 1 ) + driver->no_long_family_names = 1; + else + return FT_THROW( Invalid_Argument ); + } + else +#endif + { + FT_Bool* no_long_family_names = (FT_Bool*)value; + + + driver->no_long_family_names = *no_long_family_names; + } + + return error; + } + +#else /* !PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */ + + FT_UNUSED( module ); + FT_UNUSED( value ); + FT_UNUSED( value_is_string ); +#ifndef FT_DEBUG_LEVEL_TRACE + FT_UNUSED( property_name ); +#endif + +#endif /* !PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */ + + FT_TRACE0(( "pcf_property_set: missing property `%s'\n", + property_name )); + return FT_THROW( Missing_Property ); + } + + + static FT_Error + pcf_property_get( FT_Module module, /* PCF_Driver */ + const char* property_name, + const void* value ) + { +#ifdef PCF_CONFIG_OPTION_LONG_FAMILY_NAMES + + FT_Error error = FT_Err_Ok; + PCF_Driver driver = (PCF_Driver)module; + + + if ( !ft_strcmp( property_name, "no-long-family-names" ) ) + { + FT_Bool no_long_family_names = driver->no_long_family_names; + FT_Bool* val = (FT_Bool*)value; + + + *val = no_long_family_names; + + return error; + } + +#else /* !PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */ + + FT_UNUSED( module ); + FT_UNUSED( value ); +#ifndef FT_DEBUG_LEVEL_TRACE + FT_UNUSED( property_name ); +#endif + +#endif /* !PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */ + + FT_TRACE0(( "pcf_property_get: missing property `%s'\n", + property_name )); + return FT_THROW( Missing_Property ); + } + + + FT_DEFINE_SERVICE_PROPERTIESREC( + pcf_service_properties, + + (FT_Properties_SetFunc)pcf_property_set, /* set_property */ + (FT_Properties_GetFunc)pcf_property_get ) /* get_property */ + + /* * * SERVICE LIST @@ -672,6 +787,7 @@ THE SOFTWARE. { { FT_SERVICE_ID_BDF, &pcf_service_bdf }, { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_PCF }, + { FT_SERVICE_ID_PROPERTIES, &pcf_service_properties }, { NULL, NULL } }; @@ -686,44 +802,67 @@ THE SOFTWARE. } + FT_CALLBACK_DEF( FT_Error ) + pcf_driver_init( FT_Module module ) /* PCF_Driver */ + { +#ifdef PCF_CONFIG_OPTION_LONG_FAMILY_NAMES + PCF_Driver driver = (PCF_Driver)module; + + + driver->no_long_family_names = 0; +#else + FT_UNUSED( module ); +#endif + + return FT_Err_Ok; + } + + + FT_CALLBACK_DEF( void ) + pcf_driver_done( FT_Module module ) /* PCF_Driver */ + { + FT_UNUSED( module ); + } + + FT_CALLBACK_TABLE_DEF const FT_Driver_ClassRec pcf_driver_class = { { FT_MODULE_FONT_DRIVER | FT_MODULE_DRIVER_NO_OUTLINES, - sizeof ( FT_DriverRec ), + sizeof ( PCF_DriverRec ), "pcf", 0x10000L, 0x20000L, - 0, + NULL, /* module-specific interface */ - 0, /* FT_Module_Constructor */ - 0, /* FT_Module_Destructor */ - pcf_driver_requester + pcf_driver_init, /* FT_Module_Constructor module_init */ + pcf_driver_done, /* FT_Module_Destructor module_done */ + pcf_driver_requester /* FT_Module_Requester get_interface */ }, sizeof ( PCF_FaceRec ), sizeof ( FT_SizeRec ), sizeof ( FT_GlyphSlotRec ), - PCF_Face_Init, - PCF_Face_Done, - 0, /* FT_Size_InitFunc */ - 0, /* FT_Size_DoneFunc */ - 0, /* FT_Slot_InitFunc */ - 0, /* FT_Slot_DoneFunc */ + PCF_Face_Init, /* FT_Face_InitFunc init_face */ + PCF_Face_Done, /* FT_Face_DoneFunc done_face */ + NULL, /* FT_Size_InitFunc init_size */ + NULL, /* FT_Size_DoneFunc done_size */ + NULL, /* FT_Slot_InitFunc init_slot */ + NULL, /* FT_Slot_DoneFunc done_slot */ - PCF_Glyph_Load, + PCF_Glyph_Load, /* FT_Slot_LoadFunc load_glyph */ - 0, /* FT_Face_GetKerningFunc */ - 0, /* FT_Face_AttachFunc */ - 0, /* FT_Face_GetAdvancesFunc */ + NULL, /* FT_Face_GetKerningFunc get_kerning */ + NULL, /* FT_Face_AttachFunc attach_file */ + NULL, /* FT_Face_GetAdvancesFunc get_advances */ - PCF_Size_Request, - PCF_Size_Select + PCF_Size_Request, /* FT_Size_RequestFunc request_size */ + PCF_Size_Select /* FT_Size_SelectFunc select_size */ }; diff --git a/src/3rdparty/freetype/src/pcf/pcfdrivr.h b/src/3rdparty/freetype/src/pcf/pcfdrivr.h index 54614951b5..29d30497cd 100644 --- a/src/3rdparty/freetype/src/pcf/pcfdrivr.h +++ b/src/3rdparty/freetype/src/pcf/pcfdrivr.h @@ -25,8 +25,8 @@ THE SOFTWARE. */ -#ifndef __PCFDRIVR_H__ -#define __PCFDRIVR_H__ +#ifndef PCFDRIVR_H_ +#define PCFDRIVR_H_ #include <ft2build.h> #include FT_INTERNAL_DRIVER_H @@ -42,7 +42,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PCFDRIVR_H__ */ +#endif /* PCFDRIVR_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/pcf/pcferror.h b/src/3rdparty/freetype/src/pcf/pcferror.h index e51fff8ea6..add8ef2230 100644 --- a/src/3rdparty/freetype/src/pcf/pcferror.h +++ b/src/3rdparty/freetype/src/pcf/pcferror.h @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __PCFERROR_H__ -#define __PCFERROR_H__ +#ifndef PCFERROR_H_ +#define PCFERROR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX PCF_Err_ @@ -35,7 +35,7 @@ #include FT_ERRORS_H -#endif /* __PCFERROR_H__ */ +#endif /* PCFERROR_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/pcf/pcfread.c b/src/3rdparty/freetype/src/pcf/pcfread.c index afa1480771..537da0dc79 100644 --- a/src/3rdparty/freetype/src/pcf/pcfread.c +++ b/src/3rdparty/freetype/src/pcf/pcfread.c @@ -50,8 +50,15 @@ THE SOFTWARE. #ifdef FT_DEBUG_LEVEL_TRACE static const char* const tableNames[] = { - "prop", "accl", "mtrcs", "bmps", "imtrcs", - "enc", "swidth", "names", "accel" + "properties", + "accelerators", + "metrics", + "bitmaps", + "ink metrics", + "encodings", + "swidths", + "glyph names", + "BDF accelerators" }; #endif @@ -102,13 +109,27 @@ THE SOFTWARE. FT_STREAM_READ_FIELDS( pcf_toc_header, toc ) ) return FT_THROW( Cannot_Open_Resource ); - if ( toc->version != PCF_FILE_VERSION || - toc->count > FT_ARRAY_MAX( face->toc.tables ) || - toc->count == 0 ) + if ( toc->version != PCF_FILE_VERSION || + toc->count == 0 ) return FT_THROW( Invalid_File_Format ); + if ( stream->size < 16 ) + return FT_THROW( Invalid_File_Format ); + + /* we need 16 bytes per TOC entry, */ + /* and there can be most 9 tables */ + if ( toc->count > ( stream->size >> 4 ) || + toc->count > 9 ) + { + FT_TRACE0(( "pcf_read_TOC: adjusting number of tables" + " (from %d to %d)\n", + toc->count, + FT_MIN( stream->size >> 4, 9 ) )); + toc->count = FT_MIN( stream->size >> 4, 9 ); + } + if ( FT_NEW_ARRAY( face->toc.tables, toc->count ) ) - return FT_THROW( Out_Of_Memory ); + return error; tables = face->toc.tables; for ( n = 0; n < toc->count; n++ ) @@ -221,8 +242,8 @@ THE SOFTWARE. if ( tables[i].type == (FT_UInt)( 1 << j ) ) name = tableNames[j]; - FT_TRACE4(( " %d: type=%s, format=0x%X, " - "size=%ld (0x%lX), offset=%ld (0x%lX)\n", + FT_TRACE4(( " %d: type=%s, format=0x%X," + " size=%ld (0x%lX), offset=%ld (0x%lX)\n", i, name, tables[i].format, tables[i].size, tables[i].size, @@ -308,7 +329,7 @@ THE SOFTWARE. /* parsing normal metrics */ - fields = PCF_BYTE_ORDER( format ) == MSBFirst + fields = ( PCF_BYTE_ORDER( format ) == MSBFirst ) ? pcf_metric_msb_header : pcf_metric_header; @@ -332,6 +353,17 @@ THE SOFTWARE. metric->attributes = 0; } + FT_TRACE5(( " width=%d," + " lsb=%d, rsb=%d," + " ascent=%d, descent=%d," + " attributes=%d\n", + metric->characterWidth, + metric->leftSideBearing, + metric->rightSideBearing, + metric->ascent, + metric->descent, + metric->attributes )); + Exit: return error; } @@ -431,7 +463,7 @@ THE SOFTWARE. int i; - for ( i = 0 ; i < face->nprops && !found; i++ ) + for ( i = 0; i < face->nprops && !found; i++ ) { if ( !ft_strcmp( properties[i].name, prop ) ) found = 1; @@ -450,7 +482,7 @@ THE SOFTWARE. { PCF_ParseProperty props = NULL; PCF_Property properties = NULL; - FT_ULong nprops, i; + FT_ULong nprops, orig_nprops, i; FT_ULong format, size; FT_Error error; FT_Memory memory = FT_FACE( face )->memory; @@ -470,32 +502,43 @@ THE SOFTWARE. if ( FT_READ_ULONG_LE( format ) ) goto Bail; - FT_TRACE4(( "pcf_get_properties:\n" )); - - FT_TRACE4(( " format = %ld\n", format )); + FT_TRACE4(( "pcf_get_properties:\n" + " format: 0x%lX (%s)\n", + format, + PCF_BYTE_ORDER( format ) == MSBFirst ? "MSB" : "LSB" )); if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) goto Bail; if ( PCF_BYTE_ORDER( format ) == MSBFirst ) - (void)FT_READ_ULONG( nprops ); + (void)FT_READ_ULONG( orig_nprops ); else - (void)FT_READ_ULONG_LE( nprops ); + (void)FT_READ_ULONG_LE( orig_nprops ); if ( error ) goto Bail; - FT_TRACE4(( " nprop = %d (truncate %d props)\n", - (int)nprops, nprops - (FT_ULong)(int)nprops )); - - nprops = (FT_ULong)(int)nprops; + FT_TRACE4(( " number of properties: %ld\n", orig_nprops )); /* rough estimate */ - if ( nprops > size / PCF_PROPERTY_SIZE ) + if ( orig_nprops > size / PCF_PROPERTY_SIZE ) { error = FT_THROW( Invalid_Table ); goto Bail; } + /* as a heuristic limit to avoid excessive allocation in */ + /* gzip bombs (i.e., very small, invalid input data that */ + /* pretends to expand to an insanely large file) we only */ + /* load the first 256 properties */ + if ( orig_nprops > 256 ) + { + FT_TRACE0(( "pcf_get_properties:" + " only loading first 256 properties\n" )); + nprops = 256; + } + else + nprops = orig_nprops; + face->nprops = (int)nprops; if ( FT_NEW_ARRAY( props, nprops ) ) @@ -515,14 +558,23 @@ THE SOFTWARE. } } + /* this skip will only work if we really have an extremely large */ + /* number of properties; it will fail for fake data, avoiding an */ + /* unnecessarily large allocation later on */ + if ( FT_STREAM_SKIP( ( orig_nprops - nprops ) * PCF_PROPERTY_SIZE ) ) + { + error = FT_THROW( Invalid_Stream_Skip ); + goto Bail; + } + /* pad the property array */ /* */ /* clever here - nprops is the same as the number of odd-units read, */ /* as only isStringProp are odd length (Keith Packard) */ /* */ - if ( nprops & 3 ) + if ( orig_nprops & 3 ) { - i = 4 - ( nprops & 3 ); + i = 4 - ( orig_nprops & 3 ); if ( FT_STREAM_SKIP( i ) ) { error = FT_THROW( Invalid_Stream_Skip ); @@ -537,15 +589,24 @@ THE SOFTWARE. if ( error ) goto Bail; - FT_TRACE4(( " string_size = %ld\n", string_size )); + FT_TRACE4(( " string size: %ld\n", string_size )); /* rough estimate */ - if ( string_size > size - nprops * PCF_PROPERTY_SIZE ) + if ( string_size > size - orig_nprops * PCF_PROPERTY_SIZE ) { error = FT_THROW( Invalid_Table ); goto Bail; } + /* the strings in the `strings' array are PostScript strings, */ + /* which can have a maximum length of 65536 characters each */ + if ( string_size > 16777472 ) /* 256 * (65536 + 1) */ + { + FT_TRACE0(( "pcf_get_properties:" + " loading only 16777472 bytes of strings array\n" )); + string_size = 16777472; + } + /* allocate one more byte so that we have a final null byte */ if ( FT_NEW_ARRAY( strings, string_size + 1 ) ) goto Bail; @@ -559,6 +620,7 @@ THE SOFTWARE. face->properties = properties; + FT_TRACE4(( "\n" )); for ( i = 0; i < nprops; i++ ) { FT_Long name_offset = props[i].name; @@ -621,7 +683,7 @@ THE SOFTWARE. FT_Memory memory = FT_FACE( face )->memory; FT_ULong format, size; PCF_Metric metrics = NULL; - FT_ULong nmetrics, i; + FT_ULong nmetrics, orig_nmetrics, i; error = pcf_seek_to_table_type( stream, @@ -636,6 +698,13 @@ THE SOFTWARE. if ( FT_READ_ULONG_LE( format ) ) goto Bail; + FT_TRACE4(( "pcf_get_metrics:\n" + " format: 0x%lX (%s, %s)\n", + format, + PCF_BYTE_ORDER( format ) == MSBFirst ? "MSB" : "LSB", + PCF_FORMAT_MATCH( format, PCF_COMPRESSED_METRICS ) ? + "compressed" : "uncompressed" )); + if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) && !PCF_FORMAT_MATCH( format, PCF_COMPRESSED_METRICS ) ) return FT_THROW( Invalid_File_Format ); @@ -643,61 +712,70 @@ THE SOFTWARE. if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) { if ( PCF_BYTE_ORDER( format ) == MSBFirst ) - (void)FT_READ_ULONG( nmetrics ); + (void)FT_READ_ULONG( orig_nmetrics ); else - (void)FT_READ_ULONG_LE( nmetrics ); + (void)FT_READ_ULONG_LE( orig_nmetrics ); } else { if ( PCF_BYTE_ORDER( format ) == MSBFirst ) - (void)FT_READ_USHORT( nmetrics ); + (void)FT_READ_USHORT( orig_nmetrics ); else - (void)FT_READ_USHORT_LE( nmetrics ); + (void)FT_READ_USHORT_LE( orig_nmetrics ); } if ( error ) return FT_THROW( Invalid_File_Format ); - face->nmetrics = nmetrics; - - if ( !nmetrics ) - return FT_THROW( Invalid_Table ); - - FT_TRACE4(( "pcf_get_metrics:\n" )); - - FT_TRACE4(( " number of metrics: %d\n", nmetrics )); + FT_TRACE4(( " number of metrics: %ld\n", orig_nmetrics )); /* rough estimate */ if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) { - if ( nmetrics > size / PCF_METRIC_SIZE ) + if ( orig_nmetrics > size / PCF_METRIC_SIZE ) return FT_THROW( Invalid_Table ); } else { - if ( nmetrics > size / PCF_COMPRESSED_METRIC_SIZE ) + if ( orig_nmetrics > size / PCF_COMPRESSED_METRIC_SIZE ) return FT_THROW( Invalid_Table ); } + if ( !orig_nmetrics ) + return FT_THROW( Invalid_Table ); + + /* PCF is a format from ancient times; Unicode was in its */ + /* infancy, and widely used two-byte character sets for CJK */ + /* scripts (Big 5, GB 2312, JIS X 0208, etc.) did have at most */ + /* 15000 characters. Even the more exotic CNS 11643 and CCCII */ + /* standards, which were essentially three-byte character sets, */ + /* provided less then 65536 assigned characters. */ + /* */ + /* While technically possible to have a larger number of glyphs */ + /* in PCF files, we thus limit the number to 65536. */ + if ( orig_nmetrics > 65536 ) + { + FT_TRACE0(( "pcf_get_metrics:" + " only loading first 65536 metrics\n" )); + nmetrics = 65536; + } + else + nmetrics = orig_nmetrics; + + face->nmetrics = nmetrics; + if ( FT_NEW_ARRAY( face->metrics, nmetrics ) ) - return FT_THROW( Out_Of_Memory ); + return error; metrics = face->metrics; + + FT_TRACE4(( "\n" )); for ( i = 0; i < nmetrics; i++, metrics++ ) { + FT_TRACE5(( " idx %ld:", i )); error = pcf_get_metric( stream, format, metrics ); metrics->bits = 0; - FT_TRACE5(( " idx %d: width=%d, " - "lsb=%d, rsb=%d, ascent=%d, descent=%d, swidth=%d\n", - i, - metrics->characterWidth, - metrics->leftSideBearing, - metrics->rightSideBearing, - metrics->ascent, - metrics->descent, - metrics->attributes )); - if ( error ) break; @@ -705,7 +783,7 @@ THE SOFTWARE. /* compute a glyph's bitmap dimensions, thus setting them to zero in */ /* case of an error disables this particular glyph only */ if ( metrics->rightSideBearing < metrics->leftSideBearing || - metrics->ascent + metrics->descent < 0 ) + metrics->ascent < -metrics->descent ) { metrics->characterWidth = 0; metrics->leftSideBearing = 0; @@ -735,7 +813,7 @@ THE SOFTWARE. FT_Long* offsets = NULL; FT_Long bitmapSizes[GLYPHPADOPTIONS]; FT_ULong format, size; - FT_ULong nbitmaps, i, sizebitmaps = 0; + FT_ULong nbitmaps, orig_nbitmaps, i, sizebitmaps = 0; error = pcf_seek_to_table_type( stream, @@ -753,18 +831,42 @@ THE SOFTWARE. format = FT_GET_ULONG_LE(); if ( PCF_BYTE_ORDER( format ) == MSBFirst ) - nbitmaps = FT_GET_ULONG(); + orig_nbitmaps = FT_GET_ULONG(); else - nbitmaps = FT_GET_ULONG_LE(); + orig_nbitmaps = FT_GET_ULONG_LE(); FT_Stream_ExitFrame( stream ); + FT_TRACE4(( "pcf_get_bitmaps:\n" + " format: 0x%lX\n" + " (%s, %s,\n" + " padding=%d bit%s, scanning=%d bit%s)\n", + format, + PCF_BYTE_ORDER( format ) == MSBFirst + ? "most significant byte first" + : "least significant byte first", + PCF_BIT_ORDER( format ) == MSBFirst + ? "most significant bit first" + : "least significant bit first", + 8 << PCF_GLYPH_PAD_INDEX( format ), + ( 8 << PCF_GLYPH_PAD_INDEX( format ) ) == 1 ? "" : "s", + 8 << PCF_SCAN_UNIT_INDEX( format ), + ( 8 << PCF_SCAN_UNIT_INDEX( format ) ) == 1 ? "" : "s" )); + if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) return FT_THROW( Invalid_File_Format ); - FT_TRACE4(( "pcf_get_bitmaps:\n" )); + FT_TRACE4(( " number of bitmaps: %ld\n", orig_nbitmaps )); - FT_TRACE4(( " number of bitmaps: %d\n", nbitmaps )); + /* see comment in `pcf_get_metrics' */ + if ( orig_nbitmaps > 65536 ) + { + FT_TRACE0(( "pcf_get_bitmaps:" + " only loading first 65536 bitmaps\n" )); + nbitmaps = 65536; + } + else + nbitmaps = orig_nbitmaps; if ( nbitmaps != face->nmetrics ) return FT_THROW( Invalid_File_Format ); @@ -772,6 +874,7 @@ THE SOFTWARE. if ( FT_NEW_ARRAY( offsets, nbitmaps ) ) return error; + FT_TRACE5(( "\n" )); for ( i = 0; i < nbitmaps; i++ ) { if ( PCF_BYTE_ORDER( format ) == MSBFirst ) @@ -779,7 +882,7 @@ THE SOFTWARE. else (void)FT_READ_LONG_LE( offsets[i] ); - FT_TRACE5(( " bitmap %d: offset %ld (0x%lX)\n", + FT_TRACE5(( " bitmap %ld: offset %ld (0x%lX)\n", i, offsets[i], offsets[i] )); } if ( error ) @@ -796,17 +899,19 @@ THE SOFTWARE. sizebitmaps = (FT_ULong)bitmapSizes[PCF_GLYPH_PAD_INDEX( format )]; - FT_TRACE4(( " padding %d implies a size of %ld\n", - i, bitmapSizes[i] )); + FT_TRACE4(( " %ld-bit padding implies a size of %ld\n", + 8 << i, bitmapSizes[i] )); } - FT_TRACE4(( " %d bitmaps, padding index %ld\n", + FT_TRACE4(( " %ld bitmaps, using %ld-bit padding\n", nbitmaps, - PCF_GLYPH_PAD_INDEX( format ) )); - FT_TRACE4(( " bitmap size = %d\n", sizebitmaps )); + 8 << PCF_GLYPH_PAD_INDEX( format ) )); + FT_TRACE4(( " bitmap size: %ld\n", sizebitmaps )); FT_UNUSED( sizebitmaps ); /* only used for debugging */ + /* right now, we only check the bitmap offsets; */ + /* actual bitmaps are only loaded on demand */ for ( i = 0; i < nbitmaps; i++ ) { /* rough estimate */ @@ -814,7 +919,7 @@ THE SOFTWARE. ( (FT_ULong)offsets[i] > size ) ) { FT_TRACE0(( "pcf_get_bitmaps:" - " invalid offset to bitmap data of glyph %d\n", i )); + " invalid offset to bitmap data of glyph %ld\n", i )); } else face->metrics[i].bits = stream->pos + (FT_ULong)offsets[i]; @@ -838,7 +943,7 @@ THE SOFTWARE. int firstCol, lastCol; int firstRow, lastRow; FT_ULong nencoding; - int encodingOffset; + FT_UShort encodingOffset; int i, j; FT_ULong k; PCF_Encoding encoding = NULL; @@ -878,10 +983,20 @@ THE SOFTWARE. FT_Stream_ExitFrame( stream ); + FT_TRACE4(( "pcf_get_encodings:\n" + " format: 0x%lX (%s)\n", + format, + PCF_BYTE_ORDER( format ) == MSBFirst ? "MSB" : "LSB" )); + if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) return FT_THROW( Invalid_File_Format ); - /* sanity checks */ + FT_TRACE4(( " firstCol 0x%X, lastCol 0x%X\n" + " firstRow 0x%X, lastRow 0x%X\n", + firstCol, lastCol, + firstRow, lastRow )); + + /* sanity checks; we limit numbers of rows and columns to 256 */ if ( firstCol < 0 || firstCol > lastCol || lastCol > 0xFF || @@ -890,35 +1005,36 @@ THE SOFTWARE. lastRow > 0xFF ) return FT_THROW( Invalid_Table ); - FT_TRACE4(( "pdf_get_encodings:\n" )); - - FT_TRACE4(( " firstCol %d, lastCol %d, firstRow %d, lastRow %d\n", - firstCol, lastCol, firstRow, lastRow )); - nencoding = (FT_ULong)( lastCol - firstCol + 1 ) * (FT_ULong)( lastRow - firstRow + 1 ); if ( FT_NEW_ARRAY( encoding, nencoding ) ) - return FT_THROW( Out_Of_Memory ); + return error; error = FT_Stream_EnterFrame( stream, 2 * nencoding ); if ( error ) goto Bail; + FT_TRACE5(( "\n" )); + k = 0; for ( i = firstRow; i <= lastRow; i++ ) { for ( j = firstCol; j <= lastCol; j++ ) { + /* X11's reference implementation uses the equivalent to */ + /* `FT_GET_SHORT', however PCF fonts with more than 32768 */ + /* characters (e.g. `unifont.pcf') clearly show that an */ + /* unsigned value is needed. */ if ( PCF_BYTE_ORDER( format ) == MSBFirst ) - encodingOffset = FT_GET_SHORT(); + encodingOffset = FT_GET_USHORT(); else - encodingOffset = FT_GET_SHORT_LE(); + encodingOffset = FT_GET_USHORT_LE(); - if ( encodingOffset > -1 ) + if ( encodingOffset != 0xFFFFU ) { encoding[k].enc = i * 256 + j; - encoding[k].glyph = (FT_UShort)encodingOffset; + encoding[k].glyph = encodingOffset; FT_TRACE5(( " code %d (0x%04X): idx %d\n", encoding[k].enc, encoding[k].enc, encoding[k].glyph )); @@ -1009,6 +1125,15 @@ THE SOFTWARE. if ( FT_READ_ULONG_LE( format ) ) goto Bail; + FT_TRACE4(( "pcf_get_accel%s:\n" + " format: 0x%lX (%s, %s)\n", + type == PCF_BDF_ACCELERATORS ? " (getting BDF accelerators)" + : "", + format, + PCF_BYTE_ORDER( format ) == MSBFirst ? "MSB" : "LSB", + PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) ? + "accelerated" : "not accelerated" )); + if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) && !PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) ) goto Bail; @@ -1024,12 +1149,43 @@ THE SOFTWARE. goto Bail; } + FT_TRACE5(( " noOverlap=%s, constantMetrics=%s," + " terminalFont=%s, constantWidth=%s\n" + " inkInside=%s, inkMetrics=%s, drawDirection=%s\n" + " fontAscent=%ld, fontDescent=%ld, maxOverlap=%ld\n", + accel->noOverlap ? "yes" : "no", + accel->constantMetrics ? "yes" : "no", + accel->terminalFont ? "yes" : "no", + accel->constantWidth ? "yes" : "no", + accel->inkInside ? "yes" : "no", + accel->inkMetrics ? "yes" : "no", + accel->drawDirection ? "RTL" : "LTR", + accel->fontAscent, + accel->fontDescent, + accel->maxOverlap )); + + /* sanity checks */ + if ( FT_ABS( accel->fontAscent ) > 0x7FFF ) + { + accel->fontAscent = accel->fontAscent < 0 ? -0x7FFF : 0x7FFF; + FT_TRACE0(( "pfc_get_accel: clamping font ascent to value %d\n", + accel->fontAscent )); + } + if ( FT_ABS( accel->fontDescent ) > 0x7FFF ) + { + accel->fontDescent = accel->fontDescent < 0 ? -0x7FFF : 0x7FFF; + FT_TRACE0(( "pfc_get_accel: clamping font descent to value %d\n", + accel->fontDescent )); + } + + FT_TRACE5(( " minbounds:" )); error = pcf_get_metric( stream, format & ( ~PCF_FORMAT_MASK ), &(accel->minbounds) ); if ( error ) goto Bail; + FT_TRACE5(( " maxbounds:" )); error = pcf_get_metric( stream, format & ( ~PCF_FORMAT_MASK ), &(accel->maxbounds) ); @@ -1038,12 +1194,14 @@ THE SOFTWARE. if ( PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) ) { + FT_TRACE5(( " ink minbounds:" )); error = pcf_get_metric( stream, format & ( ~PCF_FORMAT_MASK ), &(accel->ink_minbounds) ); if ( error ) goto Bail; + FT_TRACE5(( " ink maxbounds:" )); error = pcf_get_metric( stream, format & ( ~PCF_FORMAT_MASK ), &(accel->ink_maxbounds) ); @@ -1052,7 +1210,7 @@ THE SOFTWARE. } else { - accel->ink_minbounds = accel->minbounds; /* I'm not sure about this */ + accel->ink_minbounds = accel->minbounds; accel->ink_maxbounds = accel->maxbounds; } @@ -1141,7 +1299,7 @@ THE SOFTWARE. len = lengths[nn]; - if ( src == NULL ) + if ( !src ) continue; /* separate elements with a space */ @@ -1173,8 +1331,10 @@ THE SOFTWARE. FT_LOCAL_DEF( FT_Error ) pcf_load_font( FT_Stream stream, - PCF_Face face ) + PCF_Face face, + FT_Long face_index ) { + FT_Face root = FT_FACE( face ); FT_Error error; FT_Memory memory = FT_FACE( face )->memory; FT_Bool hasBDFAccelerators; @@ -1184,6 +1344,13 @@ THE SOFTWARE. if ( error ) goto Exit; + root->num_faces = 1; + root->face_index = 0; + + /* If we are performing a simple font format check, exit immediately. */ + if ( face_index < 0 ) + return FT_Err_Ok; + error = pcf_get_properties( stream, face ); if ( error ) goto Exit; @@ -1226,13 +1393,9 @@ THE SOFTWARE. /* now construct the face object */ { - FT_Face root = FT_FACE( face ); PCF_Property prop; - root->num_faces = 1; - root->face_index = 0; - root->face_flags |= FT_FACE_FLAG_FIXED_SIZES | FT_FACE_FLAG_HORIZONTAL | FT_FACE_FLAG_FAST_GLYPHS; @@ -1240,14 +1403,81 @@ THE SOFTWARE. if ( face->accel.constantWidth ) root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; - if ( ( error = pcf_interpret_style( face ) ) != 0 ) - goto Exit; + if ( FT_SET_ERROR( pcf_interpret_style( face ) ) ) + goto Exit; prop = pcf_find_property( face, "FAMILY_NAME" ); if ( prop && prop->isString ) { - if ( FT_STRDUP( root->family_name, prop->value.atom ) ) - goto Exit; + +#ifdef PCF_CONFIG_OPTION_LONG_FAMILY_NAMES + + PCF_Driver driver = (PCF_Driver)FT_FACE_DRIVER( face ); + + + if ( !driver->no_long_family_names ) + { + /* Prepend the foundry name plus a space to the family name. */ + /* There are many fonts just called `Fixed' which look */ + /* completely different, and which have nothing to do with each */ + /* other. When selecting `Fixed' in KDE or Gnome one gets */ + /* results that appear rather random, the style changes often if */ + /* one changes the size and one cannot select some fonts at all. */ + /* */ + /* We also check whether we have `wide' characters; all put */ + /* together, we get family names like `Sony Fixed' or `Misc */ + /* Fixed Wide'. */ + + PCF_Property foundry_prop, point_size_prop, average_width_prop; + + int l = ft_strlen( prop->value.atom ) + 1; + int wide = 0; + + + foundry_prop = pcf_find_property( face, "FOUNDRY" ); + point_size_prop = pcf_find_property( face, "POINT_SIZE" ); + average_width_prop = pcf_find_property( face, "AVERAGE_WIDTH" ); + + if ( point_size_prop && average_width_prop ) + { + if ( average_width_prop->value.l >= point_size_prop->value.l ) + { + /* This font is at least square shaped or even wider */ + wide = 1; + l += ft_strlen( " Wide" ); + } + } + + if ( foundry_prop && foundry_prop->isString ) + { + l += ft_strlen( foundry_prop->value.atom ) + 1; + + if ( FT_NEW_ARRAY( root->family_name, l ) ) + goto Exit; + + ft_strcpy( root->family_name, foundry_prop->value.atom ); + ft_strcat( root->family_name, " " ); + ft_strcat( root->family_name, prop->value.atom ); + } + else + { + if ( FT_NEW_ARRAY( root->family_name, l ) ) + goto Exit; + + ft_strcpy( root->family_name, prop->value.atom ); + } + + if ( wide ) + ft_strcat( root->family_name, " Wide" ); + } + else + +#endif /* PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */ + + { + if ( FT_STRDUP( root->family_name, prop->value.atom ) ) + goto Exit; + } } else root->family_name = NULL; @@ -1270,7 +1500,7 @@ THE SOFTWARE. FT_Short resolution_x = 0, resolution_y = 0; - FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) ); + FT_ZERO( bsize ); /* for simplicity, we take absolute values of integer properties */ @@ -1282,8 +1512,16 @@ THE SOFTWARE. if ( face->accel.fontAscent + face->accel.fontDescent < 0 ) FT_TRACE0(( "pcf_load_font: negative height\n" )); #endif - bsize->height = FT_ABS( (FT_Short)( face->accel.fontAscent + - face->accel.fontDescent ) ); + if ( FT_ABS( face->accel.fontAscent + + face->accel.fontDescent ) > 0x7FFF ) + { + bsize->height = 0x7FFF; + FT_TRACE0(( "pcf_load_font: clamping height to value %d\n", + bsize->height )); + } + else + bsize->height = FT_ABS( (FT_Short)( face->accel.fontAscent + + face->accel.fontDescent ) ); prop = pcf_find_property( face, "AVERAGE_WIDTH" ); if ( prop ) @@ -1292,10 +1530,20 @@ THE SOFTWARE. if ( prop->value.l < 0 ) FT_TRACE0(( "pcf_load_font: negative average width\n" )); #endif - bsize->width = FT_ABS( (FT_Short)( ( prop->value.l ) + 5 ) / 10 ); + if ( ( FT_ABS( prop->value.l ) > 0x7FFFL * 10 - 5 ) ) + { + bsize->width = 0x7FFF; + FT_TRACE0(( "pcf_load_font: clamping average width to value %d\n", + bsize->width )); + } + else + bsize->width = FT_ABS( (FT_Short)( ( prop->value.l + 5 ) / 10 ) ); } else + { + /* this is a heuristical value */ bsize->width = (FT_Short)FT_MulDiv( bsize->height, 2, 3 ); + } prop = pcf_find_property( face, "POINT_SIZE" ); if ( prop ) @@ -1305,9 +1553,16 @@ THE SOFTWARE. FT_TRACE0(( "pcf_load_font: negative point size\n" )); #endif /* convert from 722.7 decipoints to 72 points per inch */ - bsize->size = FT_MulDiv( FT_ABS( prop->value.l ), - 64 * 7200, - 72270L ); + if ( FT_ABS( prop->value.l ) > 0x504C2L ) /* 0x7FFF * 72270/7200 */ + { + bsize->size = 0x7FFF; + FT_TRACE0(( "pcf_load_font: clamping point size to value %d\n", + bsize->size )); + } + else + bsize->size = FT_MulDiv( FT_ABS( prop->value.l ), + 64 * 7200, + 72270L ); } prop = pcf_find_property( face, "PIXEL_SIZE" ); @@ -1317,7 +1572,14 @@ THE SOFTWARE. if ( prop->value.l < 0 ) FT_TRACE0(( "pcf_load_font: negative pixel size\n" )); #endif - bsize->y_ppem = FT_ABS( (FT_Short)prop->value.l ) << 6; + if ( FT_ABS( prop->value.l ) > 0x7FFF ) + { + bsize->y_ppem = 0x7FFF << 6; + FT_TRACE0(( "pcf_load_font: clamping pixel size to value %d\n", + bsize->y_ppem )); + } + else + bsize->y_ppem = FT_ABS( (FT_Short)prop->value.l ) << 6; } prop = pcf_find_property( face, "RESOLUTION_X" ); @@ -1327,7 +1589,14 @@ THE SOFTWARE. if ( prop->value.l < 0 ) FT_TRACE0(( "pcf_load_font: negative X resolution\n" )); #endif - resolution_x = FT_ABS( (FT_Short)prop->value.l ); + if ( FT_ABS( prop->value.l ) > 0x7FFF ) + { + resolution_x = 0x7FFF; + FT_TRACE0(( "pcf_load_font: clamping X resolution to value %d\n", + resolution_x )); + } + else + resolution_x = FT_ABS( (FT_Short)prop->value.l ); } prop = pcf_find_property( face, "RESOLUTION_Y" ); @@ -1337,7 +1606,14 @@ THE SOFTWARE. if ( prop->value.l < 0 ) FT_TRACE0(( "pcf_load_font: negative Y resolution\n" )); #endif - resolution_y = FT_ABS( (FT_Short)prop->value.l ); + if ( FT_ABS( prop->value.l ) > 0x7FFF ) + { + resolution_y = 0x7FFF; + FT_TRACE0(( "pcf_load_font: clamping Y resolution to value %d\n", + resolution_y )); + } + else + resolution_y = FT_ABS( (FT_Short)prop->value.l ); } if ( bsize->y_ppem == 0 ) diff --git a/src/3rdparty/freetype/src/pcf/pcfread.h b/src/3rdparty/freetype/src/pcf/pcfread.h index c9524f1346..bed30e5030 100644 --- a/src/3rdparty/freetype/src/pcf/pcfread.h +++ b/src/3rdparty/freetype/src/pcf/pcfread.h @@ -25,8 +25,8 @@ THE SOFTWARE. */ -#ifndef __PCFREAD_H__ -#define __PCFREAD_H__ +#ifndef PCFREAD_H_ +#define PCFREAD_H_ #include <ft2build.h> @@ -39,7 +39,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PCFREAD_H__ */ +#endif /* PCFREAD_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/pcf/pcfutil.h b/src/3rdparty/freetype/src/pcf/pcfutil.h index ce10fb541d..be986e756b 100644 --- a/src/3rdparty/freetype/src/pcf/pcfutil.h +++ b/src/3rdparty/freetype/src/pcf/pcfutil.h @@ -25,8 +25,8 @@ THE SOFTWARE. */ -#ifndef __PCFUTIL_H__ -#define __PCFUTIL_H__ +#ifndef PCFUTIL_H_ +#define PCFUTIL_H_ #include <ft2build.h> @@ -49,7 +49,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PCFUTIL_H__ */ +#endif /* PCFUTIL_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/pfr/Jamfile b/src/3rdparty/freetype/src/pfr/Jamfile index c5b35be870..cb55a7ee89 100644 --- a/src/3rdparty/freetype/src/pfr/Jamfile +++ b/src/3rdparty/freetype/src/pfr/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/pfr Jamfile # -# Copyright 2002-2015 by +# Copyright 2002-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/pfr/module.mk b/src/3rdparty/freetype/src/pfr/module.mk index 3f5a47e888..27fec8e5f6 100644 --- a/src/3rdparty/freetype/src/pfr/module.mk +++ b/src/3rdparty/freetype/src/pfr/module.mk @@ -3,7 +3,7 @@ # -# Copyright 2002-2015 by +# Copyright 2002-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/pfr/pfr.c b/src/3rdparty/freetype/src/pfr/pfr.c index 96e67300a5..1760882fcd 100644 --- a/src/3rdparty/freetype/src/pfr/pfr.c +++ b/src/3rdparty/freetype/src/pfr/pfr.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR driver component. */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -15,15 +15,16 @@ /* */ /***************************************************************************/ -#define FT_MAKE_OPTION_SINGLE_OBJECT +#define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> -#include "pfrload.c" -#include "pfrgload.c" #include "pfrcmap.c" -#include "pfrobjs.c" #include "pfrdrivr.c" +#include "pfrgload.c" +#include "pfrload.c" +#include "pfrobjs.c" #include "pfrsbit.c" + /* END */ diff --git a/src/3rdparty/freetype/src/pfr/pfrcmap.c b/src/3rdparty/freetype/src/pfr/pfrcmap.c index 88ff55a806..60643780a1 100644 --- a/src/3rdparty/freetype/src/pfr/pfrcmap.c +++ b/src/3rdparty/freetype/src/pfr/pfrcmap.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR cmap handling (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -130,7 +130,7 @@ } if ( gchar->char_code < char_code ) - min = mid+1; + min = mid + 1; else max = mid; } @@ -161,12 +161,16 @@ { sizeof ( PFR_CMapRec ), - (FT_CMap_InitFunc) pfr_cmap_init, - (FT_CMap_DoneFunc) pfr_cmap_done, - (FT_CMap_CharIndexFunc)pfr_cmap_char_index, - (FT_CMap_CharNextFunc) pfr_cmap_char_next, + (FT_CMap_InitFunc) pfr_cmap_init, /* init */ + (FT_CMap_DoneFunc) pfr_cmap_done, /* done */ + (FT_CMap_CharIndexFunc)pfr_cmap_char_index, /* char_index */ + (FT_CMap_CharNextFunc) pfr_cmap_char_next, /* char_next */ - NULL, NULL, NULL, NULL, NULL + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL /* variantchar_list */ }; diff --git a/src/3rdparty/freetype/src/pfr/pfrcmap.h b/src/3rdparty/freetype/src/pfr/pfrcmap.h index 87e1e5b942..c70a0c83c5 100644 --- a/src/3rdparty/freetype/src/pfr/pfrcmap.h +++ b/src/3rdparty/freetype/src/pfr/pfrcmap.h @@ -4,7 +4,7 @@ /* */ /* FreeType PFR cmap handling (specification). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PFRCMAP_H__ -#define __PFRCMAP_H__ +#ifndef PFRCMAP_H_ +#define PFRCMAP_H_ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H @@ -40,7 +40,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PFRCMAP_H__ */ +#endif /* PFRCMAP_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/pfr/pfrdrivr.c b/src/3rdparty/freetype/src/pfr/pfrdrivr.c index 875374889c..6c7e50128a 100644 --- a/src/3rdparty/freetype/src/pfr/pfrdrivr.c +++ b/src/3rdparty/freetype/src/pfr/pfrdrivr.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR driver interface (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -139,9 +139,9 @@ static const FT_Service_PfrMetricsRec pfr_metrics_service_rec = { - pfr_get_metrics, - pfr_face_get_kerning, - pfr_get_advance + pfr_get_metrics, /* get_metrics */ + pfr_face_get_kerning, /* get_kerning */ + pfr_get_advance /* get_advance */ }; @@ -181,31 +181,32 @@ 0x10000L, 0x20000L, - NULL, + NULL, /* module-specific interface */ - 0, /* FT_Module_Constructor */ - 0, /* FT_Module_Destructor */ - pfr_get_service + NULL, /* FT_Module_Constructor module_init */ + NULL, /* FT_Module_Destructor module_done */ + pfr_get_service /* FT_Module_Requester get_interface */ }, sizeof ( PFR_FaceRec ), sizeof ( PFR_SizeRec ), sizeof ( PFR_SlotRec ), - pfr_face_init, - pfr_face_done, - 0, /* FT_Size_InitFunc */ - 0, /* FT_Size_DoneFunc */ - pfr_slot_init, - pfr_slot_done, + pfr_face_init, /* FT_Face_InitFunc init_face */ + pfr_face_done, /* FT_Face_DoneFunc done_face */ + NULL, /* FT_Size_InitFunc init_size */ + NULL, /* FT_Size_DoneFunc done_size */ + pfr_slot_init, /* FT_Slot_InitFunc init_slot */ + pfr_slot_done, /* FT_Slot_DoneFunc done_slot */ - pfr_slot_load, + pfr_slot_load, /* FT_Slot_LoadFunc load_glyph */ - pfr_get_kerning, - 0, /* FT_Face_AttachFunc */ - 0, /* FT_Face_GetAdvancesFunc */ - 0, /* FT_Size_RequestFunc */ - 0, /* FT_Size_SelectFunc */ + pfr_get_kerning, /* FT_Face_GetKerningFunc get_kerning */ + NULL, /* FT_Face_AttachFunc attach_file */ + NULL, /* FT_Face_GetAdvancesFunc get_advances */ + + NULL, /* FT_Size_RequestFunc request_size */ + NULL, /* FT_Size_SelectFunc select_size */ }; diff --git a/src/3rdparty/freetype/src/pfr/pfrdrivr.h b/src/3rdparty/freetype/src/pfr/pfrdrivr.h index b5be4709c8..cab852789b 100644 --- a/src/3rdparty/freetype/src/pfr/pfrdrivr.h +++ b/src/3rdparty/freetype/src/pfr/pfrdrivr.h @@ -4,7 +4,7 @@ /* */ /* High-level Type PFR driver interface (specification). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PFRDRIVR_H__ -#define __PFRDRIVR_H__ +#ifndef PFRDRIVR_H_ +#define PFRDRIVR_H_ #include <ft2build.h> @@ -37,7 +37,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PFRDRIVR_H__ */ +#endif /* PFRDRIVR_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/pfr/pfrerror.h b/src/3rdparty/freetype/src/pfr/pfrerror.h index 978e7b2d34..7027c818e8 100644 --- a/src/3rdparty/freetype/src/pfr/pfrerror.h +++ b/src/3rdparty/freetype/src/pfr/pfrerror.h @@ -4,7 +4,7 @@ /* */ /* PFR error codes (specification only). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __PFRERROR_H__ -#define __PFRERROR_H__ +#ifndef PFRERROR_H_ +#define PFRERROR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX PFR_Err_ @@ -35,7 +35,7 @@ #include FT_ERRORS_H -#endif /* __PFRERROR_H__ */ +#endif /* PFRERROR_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/pfr/pfrgload.c b/src/3rdparty/freetype/src/pfr/pfrgload.c index 88df06a03d..b7990196b6 100644 --- a/src/3rdparty/freetype/src/pfr/pfrgload.c +++ b/src/3rdparty/freetype/src/pfr/pfrgload.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR glyph loader (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -92,8 +92,8 @@ if ( outline->n_contours > 0 ) first = outline->contours[outline->n_contours - 1]; - /* if the last point falls on the same location than the first one */ - /* we need to delete it */ + /* if the last point falls on the same location as the first one */ + /* we need to delete it */ if ( last > first ) { FT_Vector* p1 = outline->points + first; @@ -215,8 +215,10 @@ /* check that there is space for a new contour and a new point */ error = FT_GLYPHLOADER_CHECK_POINTS( loader, 1, 1 ); if ( !error ) + { /* add new start point */ error = pfr_glyph_line_to( glyph, to ); + } return error; } @@ -304,8 +306,8 @@ glyph->y_control = glyph->x_control + x_count; - mask = 0; - x = 0; + mask = 0; + x = 0; for ( i = 0; i < count; i++ ) { @@ -331,10 +333,10 @@ mask >>= 1; } - /* XXX: for now we ignore the secondary stroke and edge definitions */ - /* since we don't want to support native PFR hinting */ - /* */ - if ( flags & PFR_GLYPH_EXTRA_ITEMS ) + /* XXX: we ignore the secondary stroke and edge definitions */ + /* since we don't support native PFR hinting */ + /* */ + if ( flags & PFR_GLYPH_SINGLE_EXTRA_ITEMS ) { error = pfr_extra_items_skip( &p, limit ); if ( error ) @@ -366,27 +368,27 @@ switch ( format >> 4 ) { - case 0: /* end glyph */ + case 0: /* end glyph */ FT_TRACE6(( "- end glyph" )); args_count = 0; break; - case 1: /* general line operation */ + case 1: /* general line operation */ FT_TRACE6(( "- general line" )); goto Line1; - case 4: /* move to inside contour */ + case 4: /* move to inside contour */ FT_TRACE6(( "- move to inside" )); goto Line1; - case 5: /* move to outside contour */ + case 5: /* move to outside contour */ FT_TRACE6(( "- move to outside" )); Line1: args_format = format_low; args_count = 1; break; - case 2: /* horizontal line to */ + case 2: /* horizontal line to */ FT_TRACE6(( "- horizontal line to cx.%d", format_low )); if ( format_low >= x_count ) goto Failure; @@ -396,7 +398,7 @@ args_count = 0; break; - case 3: /* vertical line to */ + case 3: /* vertical line to */ FT_TRACE6(( "- vertical line to cy.%d", format_low )); if ( format_low >= y_count ) goto Failure; @@ -406,19 +408,19 @@ args_count = 0; break; - case 6: /* horizontal to vertical curve */ + case 6: /* horizontal to vertical curve */ FT_TRACE6(( "- hv curve " )); args_format = 0xB8E; args_count = 3; break; - case 7: /* vertical to horizontal curve */ + case 7: /* vertical to horizontal curve */ FT_TRACE6(( "- vh curve" )); args_format = 0xE2B; args_count = 3; break; - default: /* general curve to */ + default: /* general curve to */ FT_TRACE6(( "- general curve" )); args_count = 4; args_format = format_low; @@ -439,14 +441,14 @@ { case 0: /* 8-bit index */ PFR_CHECK( 1 ); - idx = PFR_NEXT_BYTE( p ); + idx = PFR_NEXT_BYTE( p ); if ( idx >= x_count ) goto Failure; cur->x = glyph->x_control[idx]; FT_TRACE7(( " cx#%d", idx )); break; - case 1: /* 16-bit value */ + case 1: /* 16-bit absolute value */ PFR_CHECK( 2 ); cur->x = PFR_NEXT_SHORT( p ); FT_TRACE7(( " x.%d", cur->x )); @@ -516,22 +518,22 @@ /* */ switch ( format >> 4 ) { - case 0: /* end glyph => EXIT */ + case 0: /* end glyph => EXIT */ pfr_glyph_end( glyph ); goto Exit; - case 1: /* line operations */ + case 1: /* line operations */ case 2: case 3: error = pfr_glyph_line_to( glyph, pos ); goto Test_Error; - case 4: /* move to inside contour */ - case 5: /* move to outside contour */ + case 4: /* move to inside contour */ + case 5: /* move to outside contour */ error = pfr_glyph_move_to( glyph, pos ); goto Test_Error; - default: /* curve operations */ + default: /* curve operations */ error = pfr_glyph_curve_to( glyph, pos, pos + 1, pos + 2 ); Test_Error: /* test error condition */ @@ -577,10 +579,11 @@ /* ignore extra items when present */ /* */ - if ( flags & PFR_GLYPH_EXTRA_ITEMS ) + if ( flags & PFR_GLYPH_COMPOUND_EXTRA_ITEMS ) { error = pfr_extra_items_skip( &p, limit ); - if (error) goto Exit; + if ( error ) + goto Exit; } /* we can't rely on the FT_GlyphLoader to load sub-glyphs, because */ @@ -753,8 +756,10 @@ count = glyph->num_subs - old_count; - FT_TRACE4(( "compound glyph with %d elements (offset %lu):\n", - count, offset )); + FT_TRACE4(( "compound glyph with %d element%s (offset %lu):\n", + count, + count == 1 ? "" : "s", + offset )); /* now, load each individual glyph */ for ( n = 0; n < count; n++ ) @@ -807,7 +812,9 @@ /* proceed to next sub-glyph */ } - FT_TRACE4(( "end compound glyph with %d elements\n", count )); + FT_TRACE4(( "end compound glyph with %d element%s\n", + count, + count == 1 ? "" : "s" )); } else { diff --git a/src/3rdparty/freetype/src/pfr/pfrgload.h b/src/3rdparty/freetype/src/pfr/pfrgload.h index c7c8da15a1..01f48d7706 100644 --- a/src/3rdparty/freetype/src/pfr/pfrgload.h +++ b/src/3rdparty/freetype/src/pfr/pfrgload.h @@ -4,7 +4,7 @@ /* */ /* FreeType PFR glyph loader (specification). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PFRGLOAD_H__ -#define __PFRGLOAD_H__ +#ifndef PFRGLOAD_H_ +#define PFRGLOAD_H_ #include "pfrtypes.h" @@ -43,7 +43,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PFRGLOAD_H__ */ +#endif /* PFRGLOAD_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/pfr/pfrload.c b/src/3rdparty/freetype/src/pfr/pfrload.c index ec7311df56..2776da462a 100644 --- a/src/3rdparty/freetype/src/pfr/pfrload.c +++ b/src/3rdparty/freetype/src/pfr/pfrload.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR loader (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -26,6 +26,93 @@ #define FT_COMPONENT trace_pfr + /* + * The overall structure of a PFR file is as follows. + * + * PFR header + * 58 bytes (contains nPhysFonts) + * + * Logical font directory (size at most 2^16 bytes) + * 2 bytes (nLogFonts) + * + nLogFonts * 5 bytes + * + * ==> nLogFonts <= 13106 + * + * Logical font section (size at most 2^24 bytes) + * nLogFonts * logFontRecord + * + * logFontRecord (size at most 2^16 bytes) + * 12 bytes (fontMatrix) + * + 1 byte (flags) + * + 0-5 bytes (depending on `flags') + * + 0-(1+255*(2+255)) = 0-65536 (depending on `flags') + * + 5 bytes (physical font info) + * + 0-1 bytes (depending on PFR header) + * + * ==> minimum size 18 bytes + * + * Physical font section (size at most 2^24 bytes) + * nPhysFonts * (physFontRecord + * + nBitmapSizes * nBmapChars * bmapCharRecord) + * + * physFontRecord (size at most 2^24 bytes) + * 14 bytes (font info) + * + 1 byte (flags) + * + 0-2 (depending on `flags') + * + 0-? (structure too complicated to be shown here; depending on + * `flags'; contains `nBitmapSizes' and `nBmapChars') + * + 3 bytes (nAuxBytes) + * + nAuxBytes + * + 1 byte (nBlueValues) + * + 2 * nBlueValues + * + 6 bytes (hinting data) + * + 2 bytes (nCharacters) + * + nCharacters * (4-10 bytes) (depending on `flags') + * + * ==> minimum size 27 bytes + * + * bmapCharRecord + * 4-7 bytes + * + * Glyph program strings (three possible types: simpleGps, compoundGps, + * and bitmapGps; size at most 2^24 bytes) + * simpleGps (size at most 2^16 bytes) + * 1 byte (flags) + * 1-2 bytes (n[XY]orus, depending on `flags') + * 0-(64+512*2) = 0-1088 bytes (depending on `n[XY]orus') + * 0-? (structure too complicated to be shown here; depending on + * `flags') + * 1-? glyph data (faintly resembling PS Type 1 charstrings) + * + * ==> minimum size 3 bytes + * + * compoundGps (size at most 2^16 bytes) + * 1 byte (nElements <= 63, flags) + * + 0-(1+255*(2+255)) = 0-65536 (depending on `flags') + * + nElements * (6-14 bytes) + * + * bitmapGps (size at most 2^16 bytes) + * 1 byte (flags) + * 3-13 bytes (position info, depending on `flags') + * 0-? bitmap data + * + * ==> minimum size 4 bytes + * + * PFR trailer + * 8 bytes + * + * + * ==> minimum size of a valid PFR: + * 58 (header) + * + 2 (nLogFonts) + * + 27 (1 physFontRecord) + * + 8 (trailer) + * ----- + * 95 bytes + * + */ + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -75,7 +162,8 @@ if ( extra->type == item_type ) { error = extra->parser( p, p + item_size, item_data ); - if ( error ) goto Exit; + if ( error ) + goto Exit; break; } @@ -183,7 +271,8 @@ { result = 0; } - return result; + + return result; } @@ -206,9 +295,26 @@ FT_UInt result = 0; - if ( FT_STREAM_SEEK( section_offset ) || FT_READ_USHORT( count ) ) + if ( FT_STREAM_SEEK( section_offset ) || + FT_READ_USHORT( count ) ) goto Exit; + /* check maximum value and a rough minimum size: */ + /* - no more than 13106 log fonts */ + /* - we need 5 bytes for a log header record */ + /* - we need at least 18 bytes for a log font record */ + /* - the overall size is at least 95 bytes plus the */ + /* log header and log font records */ + if ( count > ( ( 1 << 16 ) - 2 ) / 5 || + 2 + count * 5 >= stream->size - section_offset || + 95 + count * ( 5 + 18 ) >= stream->size ) + { + FT_ERROR(( "pfr_log_font_count:" + " invalid number of logical fonts\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + result = count; Exit: @@ -254,13 +360,14 @@ FT_UInt local; - if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) ) + if ( FT_STREAM_SEEK( offset ) || + FT_FRAME_ENTER( size ) ) goto Exit; p = stream->cursor; limit = p + size; - PFR_CHECK(13); + PFR_CHECK( 13 ); log_font->matrix[0] = PFR_NEXT_LONG( p ); log_font->matrix[1] = PFR_NEXT_LONG( p ); @@ -276,7 +383,7 @@ if ( flags & PFR_LOG_2BYTE_STROKE ) local++; - if ( (flags & PFR_LINE_JOIN_MASK) == PFR_LINE_JOIN_MITER ) + if ( ( flags & PFR_LINE_JOIN_MASK ) == PFR_LINE_JOIN_MITER ) local += 3; } if ( flags & PFR_LOG_BOLD ) @@ -308,10 +415,11 @@ if ( flags & PFR_LOG_EXTRA_ITEMS ) { error = pfr_extra_items_skip( &p, limit ); - if (error) goto Fail; + if ( error ) + goto Fail; } - PFR_CHECK(5); + PFR_CHECK( 5 ); log_font->phys_size = PFR_NEXT_USHORT( p ); log_font->phys_offset = PFR_NEXT_ULONG( p ); if ( size_increment ) @@ -358,7 +466,7 @@ PFR_CHECK( 5 ); - p += 3; /* skip bctSize */ + p += 3; /* skip bctSize */ flags0 = PFR_NEXT_BYTE( p ); count = PFR_NEXT_BYTE( p ); @@ -434,12 +542,12 @@ } - /* Load font ID. This is a so-called "unique" name that is rather - * long and descriptive (like "Tiresias ScreenFont v7.51"). + /* Load font ID. This is a so-called `unique' name that is rather + * long and descriptive (like `Tiresias ScreenFont v7.51'). * * Note that a PFR font's family name is contained in an *undocumented* - * string of the "auxiliary data" portion of a physical font record. This - * may also contain the "real" style name! + * string of the `auxiliary data' portion of a physical font record. This + * may also contain the `real' style name! * * If no family name is present, the font ID is used instead for the * family. @@ -454,7 +562,7 @@ FT_UInt len = (FT_UInt)( limit - p ); - if ( phy_font->font_id != NULL ) + if ( phy_font->font_id ) goto Exit; if ( FT_ALLOC( phy_font->font_id, len + 1 ) ) @@ -481,7 +589,7 @@ FT_Memory memory = phy_font->memory; - if ( phy_font->vertical.stem_snaps != NULL ) + if ( phy_font->vertical.stem_snaps ) goto Exit; PFR_CHECK( 1 ); @@ -507,7 +615,7 @@ Too_Short: error = FT_THROW( Invalid_Table ); - FT_ERROR(( "pfr_exta_item_load_stem_snaps:" + FT_ERROR(( "pfr_extra_item_load_stem_snaps:" " invalid stem snaps table\n" )); goto Exit; } @@ -525,8 +633,6 @@ FT_Memory memory = phy_font->memory; - FT_TRACE2(( "pfr_extra_item_load_kerning_pairs()\n" )); - if ( FT_NEW( item ) ) goto Exit; @@ -612,7 +718,6 @@ } - static const PFR_ExtraItemRec pfr_phy_font_extra_items[] = { { 1, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_bitmap_info }, @@ -623,7 +728,8 @@ }; - /* Loads a name from the auxiliary data. Since this extracts undocumented + /* + * Load a name from the auxiliary data. Since this extracts undocumented * strings from the font file, we need to be careful here. */ static FT_Error @@ -637,12 +743,14 @@ FT_UInt n, ok; + if ( *astring ) + FT_FREE( *astring ); + if ( len > 0 && p[len - 1] == 0 ) len--; - /* check that each character is ASCII for making sure not to - load garbage - */ + /* check that each character is ASCII */ + /* for making sure not to load garbage */ ok = ( len > 0 ); for ( n = 0; n < len; n++ ) if ( p[n] < 32 || p[n] > 127 ) @@ -659,6 +767,7 @@ FT_MEM_COPY( result, p, len ); result[len] = 0; } + Exit: *astring = result; return error; @@ -729,7 +838,8 @@ phy_font->kern_items = NULL; phy_font->kern_items_tail = &phy_font->kern_items; - if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) ) + if ( FT_STREAM_SEEK( offset ) || + FT_FRAME_ENTER( size ) ) goto Exit; phy_font->cursor = stream->cursor; @@ -757,16 +867,16 @@ /* load the extra items when present */ if ( flags & PFR_PHY_EXTRA_ITEMS ) { - error = pfr_extra_items_parse( &p, limit, - pfr_phy_font_extra_items, phy_font ); + error = pfr_extra_items_parse( &p, limit, + pfr_phy_font_extra_items, phy_font ); if ( error ) goto Fail; } - /* In certain fonts, the auxiliary bytes contain interesting */ - /* information. These are not in the specification but can be */ - /* guessed by looking at the content of a few PFR0 fonts. */ + /* In certain fonts, the auxiliary bytes contain interesting */ + /* information. These are not in the specification but can be */ + /* guessed by looking at the content of a few PFR0 fonts. */ PFR_CHECK( 3 ); num_aux = PFR_NEXT_ULONG( p ); @@ -776,7 +886,7 @@ FT_Byte* q2; - PFR_CHECK( num_aux ); + PFR_CHECK_SIZE( num_aux ); p += num_aux; while ( num_aux > 0 ) @@ -797,9 +907,8 @@ switch ( type ) { case 1: - /* this seems to correspond to the font's family name, - * padded to 16-bits with one zero when necessary - */ + /* this seems to correspond to the font's family name, padded to */ + /* an even number of bytes with a zero byte appended if needed */ error = pfr_aux_name_load( q, length - 4U, memory, &phy_font->family_name ); if ( error ) @@ -817,9 +926,8 @@ break; case 3: - /* this seems to correspond to the font's style name, - * padded to 16-bits with one zero when necessary - */ + /* this seems to correspond to the font's style name, padded to */ + /* an even number of bytes with a zero byte appended if needed */ error = pfr_aux_name_load( q, length - 4U, memory, &phy_font->style_name ); if ( error ) @@ -867,9 +975,6 @@ phy_font->num_chars = count = PFR_NEXT_USHORT( p ); phy_font->chars_offset = offset + (FT_Offset)( p - stream->cursor ); - if ( FT_NEW_ARRAY( phy_font->chars, count ) ) - goto Fail; - Size = 1 + 1 + 2; if ( flags & PFR_PHY_2BYTE_CHARCODE ) Size += 1; @@ -886,7 +991,10 @@ if ( flags & PFR_PHY_3BYTE_GPS_OFFSET ) Size += 1; - PFR_CHECK( count * Size ); + PFR_CHECK_SIZE( count * Size ); + + if ( FT_NEW_ARRAY( phy_font->chars, count ) ) + goto Fail; for ( n = 0; n < count; n++ ) { diff --git a/src/3rdparty/freetype/src/pfr/pfrload.h b/src/3rdparty/freetype/src/pfr/pfrload.h index 0a512346b6..36e809a762 100644 --- a/src/3rdparty/freetype/src/pfr/pfrload.h +++ b/src/3rdparty/freetype/src/pfr/pfrload.h @@ -4,7 +4,7 @@ /* */ /* FreeType PFR loader (specification). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PFRLOAD_H__ -#define __PFRLOAD_H__ +#ifndef PFRLOAD_H_ +#define PFRLOAD_H_ #include "pfrobjs.h" #include FT_INTERNAL_STREAM_H @@ -25,14 +25,19 @@ FT_BEGIN_HEADER + /* some size checks should be always done (mainly to prevent */ + /* excessive allocation for malformed data), ... */ +#define PFR_CHECK_SIZE( x ) do \ + { \ + if ( p + (x) > limit ) \ + goto Too_Short; \ + } while ( 0 ) + + /* ... and some only if intensive checking is explicitly requested */ #ifdef PFR_CONFIG_NO_CHECKS #define PFR_CHECK( x ) do { } while ( 0 ) #else -#define PFR_CHECK( x ) do \ - { \ - if ( p + (x) > limit ) \ - goto Too_Short; \ - } while ( 0 ) +#define PFR_CHECK PFR_CHECK_SIZE #endif #define PFR_NEXT_BYTE( p ) FT_NEXT_BYTE( p ) @@ -112,7 +117,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PFRLOAD_H__ */ +#endif /* PFRLOAD_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/pfr/pfrobjs.c b/src/3rdparty/freetype/src/pfr/pfrobjs.c index b854b00ba8..737b97b5ff 100644 --- a/src/3rdparty/freetype/src/pfr/pfrobjs.c +++ b/src/3rdparty/freetype/src/pfr/pfrobjs.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR object methods (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -118,9 +118,11 @@ /* load the face */ error = pfr_log_font_load( - &face->log_font, stream, (FT_UInt)( face_index & 0xFFFF ), - face->header.log_dir_offset, - FT_BOOL( face->header.phy_font_max_size_high != 0 ) ); + &face->log_font, + stream, + (FT_UInt)( face_index & 0xFFFF ), + face->header.log_dir_offset, + FT_BOOL( face->header.phy_font_max_size_high != 0 ) ); if ( error ) goto Exit; @@ -141,8 +143,8 @@ pfrface->face_flags |= FT_FACE_FLAG_SCALABLE; - /* if all characters point to the same gps_offset 0, we */ - /* assume that the font only contains bitmaps */ + /* if gps_offset == 0 for all characters, we */ + /* assume that the font only contains bitmaps */ { FT_UInt nn; @@ -164,7 +166,7 @@ } } - if ( (phy_font->flags & PFR_PHY_PROPORTIONAL) == 0 ) + if ( ( phy_font->flags & PFR_PHY_PROPORTIONAL ) == 0 ) pfrface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; if ( phy_font->flags & PFR_PHY_VERTICAL ) @@ -178,16 +180,16 @@ if ( phy_font->num_kern_pairs > 0 ) pfrface->face_flags |= FT_FACE_FLAG_KERNING; - /* If no family name was found in the "undocumented" auxiliary + /* If no family name was found in the `undocumented' auxiliary * data, use the font ID instead. This sucks but is better than * nothing. */ pfrface->family_name = phy_font->family_name; - if ( pfrface->family_name == NULL ) + if ( !pfrface->family_name ) pfrface->family_name = phy_font->font_id; /* note that the style name can be NULL in certain PFR fonts, - * probably meaning "Regular" + * probably meaning `Regular' */ pfrface->style_name = phy_font->style_name; @@ -262,15 +264,9 @@ charmap.encoding = FT_ENCODING_UNICODE; error = FT_CMap_New( &pfr_cmap_class_rec, NULL, &charmap, NULL ); - -#if 0 - /* Select default charmap */ - if ( pfrface->num_charmaps ) - pfrface->charmap = pfrface->charmaps[0]; -#endif } - /* check whether we've loaded any kerning pairs */ + /* check whether we have loaded any kerning pairs */ if ( phy_font->num_kern_pairs ) pfrface->face_flags |= FT_FACE_FLAG_KERNING; } @@ -340,8 +336,12 @@ /* try to load an embedded bitmap */ if ( ( load_flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP ) ) == 0 ) { - error = pfr_slot_load_bitmap( slot, size, gindex ); - if ( error == 0 ) + error = pfr_slot_load_bitmap( + slot, + size, + gindex, + ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) != 0 ); + if ( !error ) goto Exit; } @@ -402,7 +402,7 @@ pfrslot->linearHoriAdvance = metrics->horiAdvance; pfrslot->linearVertAdvance = metrics->vertAdvance; - /* make-up vertical metrics(?) */ + /* make up vertical metrics(?) */ metrics->vertBearingX = 0; metrics->vertBearingY = 0; @@ -522,8 +522,8 @@ FT_UInt probe = power * size; FT_UInt extra = count - power; FT_Byte* base = stream->cursor; - FT_Bool twobytes = FT_BOOL( item->flags & 1 ); - FT_Bool twobyte_adj = FT_BOOL( item->flags & 2 ); + FT_Bool twobytes = FT_BOOL( item->flags & PFR_KERN_2BYTE_CHAR ); + FT_Bool twobyte_adj = FT_BOOL( item->flags & PFR_KERN_2BYTE_ADJ ); FT_Byte* p; FT_UInt32 cpair; @@ -596,4 +596,5 @@ return error; } + /* END */ diff --git a/src/3rdparty/freetype/src/pfr/pfrobjs.h b/src/3rdparty/freetype/src/pfr/pfrobjs.h index e990b45a0a..59c709f58d 100644 --- a/src/3rdparty/freetype/src/pfr/pfrobjs.h +++ b/src/3rdparty/freetype/src/pfr/pfrobjs.h @@ -4,7 +4,7 @@ /* */ /* FreeType PFR object methods (specification). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PFROBJS_H__ -#define __PFROBJS_H__ +#ifndef PFROBJS_H_ +#define PFROBJS_H_ #include "pfrtypes.h" @@ -90,7 +90,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PFROBJS_H__ */ +#endif /* PFROBJS_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/pfr/pfrsbit.c b/src/3rdparty/freetype/src/pfr/pfrsbit.c index bb5df5c9f9..ba909ddca7 100644 --- a/src/3rdparty/freetype/src/pfr/pfrsbit.c +++ b/src/3rdparty/freetype/src/pfr/pfrsbit.c @@ -4,7 +4,7 @@ /* */ /* FreeType PFR bitmap loader (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -37,11 +37,11 @@ typedef struct PFR_BitWriter_ { - FT_Byte* line; /* current line start */ - FT_Int pitch; /* line size in bytes */ - FT_UInt width; /* width in pixels/bits */ - FT_UInt rows; /* number of remaining rows to scan */ - FT_UInt total; /* total number of bits to draw */ + FT_Byte* line; /* current line start */ + FT_Int pitch; /* line size in bytes */ + FT_UInt width; /* width in pixels/bits */ + FT_UInt rows; /* number of remaining rows to scan */ + FT_UInt total; /* total number of bits to draw */ } PFR_BitWriterRec, *PFR_BitWriter; @@ -277,49 +277,99 @@ pfr_lookup_bitmap_data( FT_Byte* base, FT_Byte* limit, FT_UInt count, - FT_UInt flags, + FT_UInt* flags, FT_UInt char_code, FT_ULong* found_offset, FT_ULong* found_size ) { - FT_UInt left, right, char_len; - FT_Bool two = FT_BOOL( flags & 1 ); + FT_UInt min, max, char_len; + FT_Bool two = FT_BOOL( *flags & PFR_BITMAP_2BYTE_CHARCODE ); FT_Byte* buff; char_len = 4; - if ( two ) char_len += 1; - if ( flags & 2 ) char_len += 1; - if ( flags & 4 ) char_len += 1; + if ( two ) + char_len += 1; + if ( *flags & PFR_BITMAP_2BYTE_SIZE ) + char_len += 1; + if ( *flags & PFR_BITMAP_3BYTE_OFFSET ) + char_len += 1; - left = 0; - right = count; - - while ( left < right ) + if ( !( *flags & PFR_BITMAP_CHARCODES_VALIDATED ) ) { - FT_UInt middle, code; + FT_Byte* p; + FT_Byte* lim; + FT_UInt code; + FT_Long prev_code; - middle = ( left + right ) >> 1; - buff = base + middle * char_len; + *flags |= PFR_BITMAP_VALID_CHARCODES; + prev_code = -1; + lim = base + count * char_len; - /* check that we are not outside of the table -- */ - /* this is possible with broken fonts... */ - if ( buff + char_len > limit ) - goto Fail; + if ( lim > limit ) + { + FT_TRACE0(( "pfr_lookup_bitmap_data:" + " number of bitmap records too large,\n" + " " + " thus ignoring all bitmaps in this strike\n" )); + *flags &= ~PFR_BITMAP_VALID_CHARCODES; + } + else + { + /* check whether records are sorted by code */ + for ( p = base; p < lim; p += char_len ) + { + if ( two ) + code = FT_PEEK_USHORT( p ); + else + code = *p; + + if ( (FT_Long)code <= prev_code ) + { + FT_TRACE0(( "pfr_lookup_bitmap_data:" + " bitmap records are not sorted,\n" + " " + " thus ignoring all bitmaps in this strike\n" )); + *flags &= ~PFR_BITMAP_VALID_CHARCODES; + break; + } + + prev_code = code; + } + } + + *flags |= PFR_BITMAP_CHARCODES_VALIDATED; + } + + /* ignore bitmaps in case table is not valid */ + /* (this might be sanitized, but PFR is dead...) */ + if ( !( *flags & PFR_BITMAP_VALID_CHARCODES ) ) + goto Fail; + + min = 0; + max = count; + + /* binary search */ + while ( min < max ) + { + FT_UInt mid, code; + + + mid = ( min + max ) >> 1; + buff = base + mid * char_len; if ( two ) code = PFR_NEXT_USHORT( buff ); else code = PFR_NEXT_BYTE( buff ); - if ( code == char_code ) - goto Found_It; - - if ( code < char_code ) - left = middle; + if ( char_code < code ) + max = mid; + else if ( char_code > code ) + min = mid + 1; else - right = middle; + goto Found_It; } Fail: @@ -329,20 +379,20 @@ return; Found_It: - if ( flags & 2 ) + if ( *flags & PFR_BITMAP_2BYTE_SIZE ) *found_size = PFR_NEXT_USHORT( buff ); else *found_size = PFR_NEXT_BYTE( buff ); - if ( flags & 4 ) + if ( *flags & PFR_BITMAP_3BYTE_OFFSET ) *found_offset = PFR_NEXT_ULONG( buff ); else *found_offset = PFR_NEXT_USHORT( buff ); } - /* load bitmap metrics. "*padvance" must be set to the default value */ - /* before calling this function... */ + /* load bitmap metrics. `*padvance' must be set to the default value */ + /* before calling this function */ /* */ static FT_Error pfr_load_bitmap_metrics( FT_Byte** pdata, @@ -357,7 +407,6 @@ { FT_Error error = FT_Err_Ok; FT_Byte flags; - FT_Char c; FT_Byte b; FT_Byte* p = *pdata; FT_Long xpos, ypos, advance; @@ -377,9 +426,9 @@ { case 0: PFR_CHECK( 1 ); - c = PFR_NEXT_INT8( p ); - xpos = c >> 4; - ypos = ( (FT_Char)( c << 4 ) ) >> 4; + b = PFR_NEXT_BYTE( p ); + xpos = (FT_Char)b >> 4; + ypos = ( (FT_Char)( b << 4 ) ) >> 4; break; case 1: @@ -445,7 +494,7 @@ case 1: PFR_CHECK( 1 ); - advance = PFR_NEXT_INT8( p ) << 8; + advance = PFR_NEXT_INT8( p ) * 256; break; case 2: @@ -510,8 +559,7 @@ break; default: - FT_ERROR(( "pfr_read_bitmap_data: invalid image type\n" )); - error = FT_THROW( Invalid_File_Format ); + ; } } @@ -530,7 +578,8 @@ FT_LOCAL( FT_Error ) pfr_slot_load_bitmap( PFR_Slot glyph, PFR_Size size, - FT_UInt glyph_index ) + FT_UInt glyph_index, + FT_Bool metrics_only ) { FT_Error error; PFR_Face face = (PFR_Face) glyph->root.face; @@ -544,7 +593,7 @@ character = &phys->chars[glyph_index]; - /* Look-up a bitmap strike corresponding to the current */ + /* look up a bitmap strike corresponding to the current */ /* character dimensions */ { FT_UInt n; @@ -555,9 +604,7 @@ { if ( strike->x_ppm == (FT_UInt)size->root.metrics.x_ppem && strike->y_ppm == (FT_UInt)size->root.metrics.y_ppem ) - { goto Found_Strike; - } strike++; } @@ -568,17 +615,20 @@ Found_Strike: - /* Now lookup the glyph's position within the file */ + /* now look up the glyph's position within the file */ { FT_UInt char_len; char_len = 4; - if ( strike->flags & 1 ) char_len += 1; - if ( strike->flags & 2 ) char_len += 1; - if ( strike->flags & 4 ) char_len += 1; + if ( strike->flags & PFR_BITMAP_2BYTE_CHARCODE ) + char_len += 1; + if ( strike->flags & PFR_BITMAP_2BYTE_SIZE ) + char_len += 1; + if ( strike->flags & PFR_BITMAP_3BYTE_OFFSET ) + char_len += 1; - /* Access data directly in the frame to speed lookups */ + /* access data directly in the frame to speed lookups */ if ( FT_STREAM_SEEK( phys->bct_offset + strike->bct_offset ) || FT_FRAME_ENTER( char_len * strike->num_bitmaps ) ) goto Exit; @@ -586,7 +636,7 @@ pfr_lookup_bitmap_data( stream->cursor, stream->limit, strike->num_bitmaps, - strike->flags, + &strike->flags, character->char_code, &gps_offset, &gps_size ); @@ -595,7 +645,7 @@ if ( gps_size == 0 ) { - /* Could not find a bitmap program string for this glyph */ + /* could not find a bitmap program string for this glyph */ error = FT_THROW( Invalid_Argument ); goto Exit; } @@ -617,8 +667,8 @@ glyph->root.linearHoriAdvance = advance; - /* compute default advance, i.e., scaled advance. This can be */ - /* overridden in the bitmap header of certain glyphs. */ + /* compute default advance, i.e., scaled advance; this can be */ + /* overridden in the bitmap header of certain glyphs */ advance = FT_MulDiv( (FT_Fixed)size->root.metrics.x_ppem << 8, character->advance, (FT_Long)phys->metrics_resolution ); @@ -633,6 +683,55 @@ &xpos, &ypos, &xsize, &ysize, &advance, &format ); + if ( error ) + goto Exit1; + + /* + * Before allocating the target bitmap, we check whether the given + * bitmap dimensions are valid, depending on the image format. + * + * Format 0: We have a stream of pixels (with 8 pixels per byte). + * + * (xsize * ysize + 7) / 8 <= gps_size + * + * Format 1: Run-length encoding; the high nibble holds the number of + * white bits, the low nibble the number of black bits. In + * other words, a single byte can represent at most 15 + * pixels. + * + * xsize * ysize <= 15 * gps_size + * + * Format 2: Run-length encoding; the high byte holds the number of + * white bits, the low byte the number of black bits. In + * other words, two bytes can represent at most 255 pixels. + * + * xsize * ysize <= 255 * (gps_size + 1) / 2 + */ + switch ( format ) + { + case 0: + if ( ( (FT_ULong)xsize * ysize + 7 ) / 8 > gps_size ) + error = FT_THROW( Invalid_Table ); + break; + case 1: + if ( (FT_ULong)xsize * ysize > 15 * gps_size ) + error = FT_THROW( Invalid_Table ); + break; + case 2: + if ( (FT_ULong)xsize * ysize > 255 * ( ( gps_size + 1 ) / 2 ) ) + error = FT_THROW( Invalid_Table ); + break; + default: + FT_ERROR(( "pfr_slot_load_bitmap: invalid image type\n" )); + error = FT_THROW( Invalid_Table ); + } + + if ( error ) + { + if ( FT_ERR_EQ( error, Invalid_Table ) ) + FT_ERROR(( "pfr_slot_load_bitmap: invalid bitmap dimensions\n" )); + goto Exit1; + } /* * XXX: on 16bit systems we return an error for huge bitmaps @@ -666,8 +765,8 @@ /* XXX: needs casts to fit FT_Glyph_Metrics.{width|height} */ glyph->root.metrics.width = (FT_Pos)xsize << 6; glyph->root.metrics.height = (FT_Pos)ysize << 6; - glyph->root.metrics.horiBearingX = xpos << 6; - glyph->root.metrics.horiBearingY = ypos << 6; + glyph->root.metrics.horiBearingX = xpos * 64; + glyph->root.metrics.horiBearingY = ypos * 64; glyph->root.metrics.horiAdvance = FT_PIX_ROUND( ( advance >> 2 ) ); glyph->root.metrics.vertBearingX = - glyph->root.metrics.width >> 1; glyph->root.metrics.vertBearingY = 0; @@ -677,6 +776,9 @@ glyph->root.bitmap_left = (FT_Int)xpos; glyph->root.bitmap_top = (FT_Int)( ypos + (FT_Long)ysize ); + if ( metrics_only ) + goto Exit1; + /* Allocate and read bitmap data */ { FT_ULong len = (FT_ULong)glyph->root.bitmap.pitch * ysize; @@ -684,17 +786,17 @@ error = ft_glyphslot_alloc_bitmap( &glyph->root, len ); if ( !error ) - { error = pfr_load_bitmap_bits( p, stream->limit, format, - FT_BOOL(face->header.color_flags & 2), + FT_BOOL( face->header.color_flags & + PFR_FLAG_INVERT_BITMAP ), &glyph->root.bitmap ); - } } } + Exit1: FT_FRAME_EXIT(); } @@ -702,4 +804,5 @@ return error; } + /* END */ diff --git a/src/3rdparty/freetype/src/pfr/pfrsbit.h b/src/3rdparty/freetype/src/pfr/pfrsbit.h index 0db2cd5ebd..07b27bc06c 100644 --- a/src/3rdparty/freetype/src/pfr/pfrsbit.h +++ b/src/3rdparty/freetype/src/pfr/pfrsbit.h @@ -4,7 +4,7 @@ /* */ /* FreeType PFR bitmap loader (specification). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PFRSBIT_H__ -#define __PFRSBIT_H__ +#ifndef PFRSBIT_H_ +#define PFRSBIT_H_ #include "pfrobjs.h" @@ -26,11 +26,12 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) pfr_slot_load_bitmap( PFR_Slot glyph, PFR_Size size, - FT_UInt glyph_index ); + FT_UInt glyph_index, + FT_Bool metrics_only ); FT_END_HEADER -#endif /* __PFR_SBIT_H__ */ +#endif /* PFRSBIT_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/pfr/pfrtypes.h b/src/3rdparty/freetype/src/pfr/pfrtypes.h index 5ffb1b14ee..058d6aadc9 100644 --- a/src/3rdparty/freetype/src/pfr/pfrtypes.h +++ b/src/3rdparty/freetype/src/pfr/pfrtypes.h @@ -4,7 +4,7 @@ /* */ /* FreeType PFR data structures (specification only). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PFRTYPES_H__ -#define __PFRTYPES_H__ +#ifndef PFRTYPES_H_ +#define PFRTYPES_H_ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H @@ -69,12 +69,8 @@ FT_BEGIN_HEADER /* used in `color_flags' field of the PFR_Header */ - typedef enum PFR_HeaderFlags_ - { - PFR_FLAG_BLACK_PIXEL = 1, - PFR_FLAG_INVERT_BITMAP = 2 - - } PFR_HeaderFlags; +#define PFR_FLAG_BLACK_PIXEL 0x01U +#define PFR_FLAG_INVERT_BITMAP 0x02U /************************************************************************/ @@ -96,36 +92,27 @@ FT_BEGIN_HEADER } PFR_LogFontRec, *PFR_LogFont; - typedef enum PFR_LogFlags_ - { - PFR_LOG_EXTRA_ITEMS = 0x40, - PFR_LOG_2BYTE_BOLD = 0x20, - PFR_LOG_BOLD = 0x10, - PFR_LOG_2BYTE_STROKE = 8, - PFR_LOG_STROKE = 4, - PFR_LINE_JOIN_MASK = 3 +#define PFR_LINE_JOIN_MITER 0x00U +#define PFR_LINE_JOIN_ROUND 0x01U +#define PFR_LINE_JOIN_BEVEL 0x02U +#define PFR_LINE_JOIN_MASK ( PFR_LINE_JOIN_ROUND | PFR_LINE_JOIN_BEVEL ) - } PFR_LogFlags; - - - typedef enum PFR_LineJoinFlags_ - { - PFR_LINE_JOIN_MITER = 0, - PFR_LINE_JOIN_ROUND = 1, - PFR_LINE_JOIN_BEVEL = 2 - - } PFR_LineJoinFlags; +#define PFR_LOG_STROKE 0x04U +#define PFR_LOG_2BYTE_STROKE 0x08U +#define PFR_LOG_BOLD 0x10U +#define PFR_LOG_2BYTE_BOLD 0x20U +#define PFR_LOG_EXTRA_ITEMS 0x40U /************************************************************************/ - typedef enum PFR_BitmapFlags_ - { - PFR_BITMAP_3BYTE_OFFSET = 4, - PFR_BITMAP_2BYTE_SIZE = 2, - PFR_BITMAP_2BYTE_CHARCODE = 1 +#define PFR_BITMAP_2BYTE_CHARCODE 0x01U +#define PFR_BITMAP_2BYTE_SIZE 0x02U +#define PFR_BITMAP_3BYTE_OFFSET 0x04U - } PFR_BitmapFlags; + /*not part of the specification but used for implementation */ +#define PFR_BITMAP_CHARCODES_VALIDATED 0x40U +#define PFR_BITMAP_VALID_CHARCODES 0x80U typedef struct PFR_BitmapCharRec_ @@ -137,15 +124,11 @@ FT_BEGIN_HEADER } PFR_BitmapCharRec, *PFR_BitmapChar; - typedef enum PFR_StrikeFlags_ - { - PFR_STRIKE_2BYTE_COUNT = 0x10, - PFR_STRIKE_3BYTE_OFFSET = 0x08, - PFR_STRIKE_3BYTE_SIZE = 0x04, - PFR_STRIKE_2BYTE_YPPM = 0x02, - PFR_STRIKE_2BYTE_XPPM = 0x01 - - } PFR_StrikeFlags; +#define PFR_STRIKE_2BYTE_XPPM 0x01U +#define PFR_STRIKE_2BYTE_YPPM 0x02U +#define PFR_STRIKE_3BYTE_SIZE 0x04U +#define PFR_STRIKE_3BYTE_OFFSET 0x08U +#define PFR_STRIKE_2BYTE_COUNT 0x10U typedef struct PFR_StrikeRec_ @@ -266,38 +249,29 @@ FT_BEGIN_HEADER } PFR_PhyFontRec, *PFR_PhyFont; - typedef enum PFR_PhyFlags_ - { - PFR_PHY_EXTRA_ITEMS = 0x80, - PFR_PHY_3BYTE_GPS_OFFSET = 0x20, - PFR_PHY_2BYTE_GPS_SIZE = 0x10, - PFR_PHY_ASCII_CODE = 0x08, - PFR_PHY_PROPORTIONAL = 0x04, - PFR_PHY_2BYTE_CHARCODE = 0x02, - PFR_PHY_VERTICAL = 0x01 - - } PFR_PhyFlags; +#define PFR_PHY_VERTICAL 0x01U +#define PFR_PHY_2BYTE_CHARCODE 0x02U +#define PFR_PHY_PROPORTIONAL 0x04U +#define PFR_PHY_ASCII_CODE 0x08U +#define PFR_PHY_2BYTE_GPS_SIZE 0x10U +#define PFR_PHY_3BYTE_GPS_OFFSET 0x20U +#define PFR_PHY_EXTRA_ITEMS 0x80U - typedef enum PFR_KernFlags_ - { - PFR_KERN_2BYTE_CHAR = 0x01, - PFR_KERN_2BYTE_ADJ = 0x02 - - } PFR_KernFlags; +#define PFR_KERN_2BYTE_CHAR 0x01U +#define PFR_KERN_2BYTE_ADJ 0x02U /************************************************************************/ - typedef enum PFR_GlyphFlags_ - { - PFR_GLYPH_IS_COMPOUND = 0x80, - PFR_GLYPH_EXTRA_ITEMS = 0x08, - PFR_GLYPH_1BYTE_XYCOUNT = 0x04, - PFR_GLYPH_XCOUNT = 0x02, - PFR_GLYPH_YCOUNT = 0x01 +#define PFR_GLYPH_YCOUNT 0x01U +#define PFR_GLYPH_XCOUNT 0x02U +#define PFR_GLYPH_1BYTE_XYCOUNT 0x04U - } PFR_GlyphFlags; +#define PFR_GLYPH_SINGLE_EXTRA_ITEMS 0x08U +#define PFR_GLYPH_COMPOUND_EXTRA_ITEMS 0x40U + +#define PFR_GLYPH_IS_COMPOUND 0x80U /* controlled coordinate */ @@ -321,14 +295,10 @@ FT_BEGIN_HEADER } PFR_SubGlyphRec, *PFR_SubGlyph; - typedef enum PFR_SubgGlyphFlags_ - { - PFR_SUBGLYPH_3BYTE_OFFSET = 0x80, - PFR_SUBGLYPH_2BYTE_SIZE = 0x40, - PFR_SUBGLYPH_YSCALE = 0x20, - PFR_SUBGLYPH_XSCALE = 0x10 - - } PFR_SubGlyphFlags; +#define PFR_SUBGLYPH_XSCALE 0x10U +#define PFR_SUBGLYPH_YSCALE 0x20U +#define PFR_SUBGLYPH_2BYTE_SIZE 0x40U +#define PFR_SUBGLYPH_3BYTE_OFFSET 0x80U typedef struct PFR_GlyphRec_ @@ -356,7 +326,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PFRTYPES_H__ */ +#endif /* PFRTYPES_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/pfr/rules.mk b/src/3rdparty/freetype/src/pfr/rules.mk index e665460103..3acb795696 100644 --- a/src/3rdparty/freetype/src/pfr/rules.mk +++ b/src/3rdparty/freetype/src/pfr/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2002-2015 by +# Copyright 2002-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/psaux/Jamfile b/src/3rdparty/freetype/src/psaux/Jamfile index 6793f0d581..a231d5974f 100644 --- a/src/3rdparty/freetype/src/psaux/Jamfile +++ b/src/3rdparty/freetype/src/psaux/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/psaux Jamfile # -# Copyright 2001-2015 by +# Copyright 2001-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -22,6 +22,16 @@ SubDir FT2_TOP $(FT2_SRC_DIR) psaux ; psobjs t1cmap t1decode + cffdecode + psarrst + psblues + pserror + psfont + psft + pshints + psintrp + psread + psstack ; } else diff --git a/src/3rdparty/freetype/src/psaux/afmparse.c b/src/3rdparty/freetype/src/psaux/afmparse.c index 3ad44ec724..0c33d5949b 100644 --- a/src/3rdparty/freetype/src/psaux/afmparse.c +++ b/src/3rdparty/freetype/src/psaux/afmparse.c @@ -4,7 +4,7 @@ /* */ /* AFM parser (body). */ /* */ -/* Copyright 2006-2015 by */ +/* Copyright 2006-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,6 +20,8 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_POSTSCRIPT_AUX_H +#ifndef T1_CONFIG_OPTION_NO_AFM + #include "afmparse.h" #include "psconv.h" @@ -973,5 +975,12 @@ return error; } +#else /* T1_CONFIG_OPTION_NO_AFM */ + + /* ANSI C doesn't like empty source files */ + typedef int _afm_parse_dummy; + +#endif /* T1_CONFIG_OPTION_NO_AFM */ + /* END */ diff --git a/src/3rdparty/freetype/src/psaux/afmparse.h b/src/3rdparty/freetype/src/psaux/afmparse.h index f922c4ebde..86f852a247 100644 --- a/src/3rdparty/freetype/src/psaux/afmparse.h +++ b/src/3rdparty/freetype/src/psaux/afmparse.h @@ -4,7 +4,7 @@ /* */ /* AFM parser (specification). */ /* */ -/* Copyright 2006-2015 by */ +/* Copyright 2006-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __AFMPARSE_H__ -#define __AFMPARSE_H__ +#ifndef AFMPARSE_H_ +#define AFMPARSE_H_ #include <ft2build.h> @@ -83,7 +83,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __AFMPARSE_H__ */ +#endif /* AFMPARSE_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/psaux/cffdecode.c b/src/3rdparty/freetype/src/psaux/cffdecode.c new file mode 100644 index 0000000000..80d622c0e1 --- /dev/null +++ b/src/3rdparty/freetype/src/psaux/cffdecode.c @@ -0,0 +1,2370 @@ +/***************************************************************************/ +/* */ +/* cffdecode.c */ +/* */ +/* PostScript CFF (Type 2) decoding routines (body). */ +/* */ +/* Copyright 2017-2018 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_SERVICE_H +#include FT_SERVICE_CFF_TABLE_LOAD_H + +#include "cffdecode.h" +#include "psobjs.h" + +#include "psauxerr.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_cffdecode + + +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + + typedef enum CFF_Operator_ + { + cff_op_unknown = 0, + + cff_op_rmoveto, + cff_op_hmoveto, + cff_op_vmoveto, + + cff_op_rlineto, + cff_op_hlineto, + cff_op_vlineto, + + cff_op_rrcurveto, + cff_op_hhcurveto, + cff_op_hvcurveto, + cff_op_rcurveline, + cff_op_rlinecurve, + cff_op_vhcurveto, + cff_op_vvcurveto, + + cff_op_flex, + cff_op_hflex, + cff_op_hflex1, + cff_op_flex1, + + cff_op_endchar, + + cff_op_hstem, + cff_op_vstem, + cff_op_hstemhm, + cff_op_vstemhm, + + cff_op_hintmask, + cff_op_cntrmask, + cff_op_dotsection, /* deprecated, acts as no-op */ + + cff_op_abs, + cff_op_add, + cff_op_sub, + cff_op_div, + cff_op_neg, + cff_op_random, + cff_op_mul, + cff_op_sqrt, + + cff_op_blend, + + cff_op_drop, + cff_op_exch, + cff_op_index, + cff_op_roll, + cff_op_dup, + + cff_op_put, + cff_op_get, + cff_op_store, + cff_op_load, + + cff_op_and, + cff_op_or, + cff_op_not, + cff_op_eq, + cff_op_ifelse, + + cff_op_callsubr, + cff_op_callgsubr, + cff_op_return, + + /* Type 1 opcodes: invalid but seen in real life */ + cff_op_hsbw, + cff_op_closepath, + cff_op_callothersubr, + cff_op_pop, + cff_op_seac, + cff_op_sbw, + cff_op_setcurrentpoint, + + /* do not remove */ + cff_op_max + + } CFF_Operator; + + +#define CFF_COUNT_CHECK_WIDTH 0x80 +#define CFF_COUNT_EXACT 0x40 +#define CFF_COUNT_CLEAR_STACK 0x20 + + /* count values which have the `CFF_COUNT_CHECK_WIDTH' flag set are */ + /* used for checking the width and requested numbers of arguments */ + /* only; they are set to zero afterwards */ + + /* the other two flags are informative only and unused currently */ + + static const FT_Byte cff_argument_counts[] = + { + 0, /* unknown */ + + 2 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, /* rmoveto */ + 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, + 1 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, + + 0 | CFF_COUNT_CLEAR_STACK, /* rlineto */ + 0 | CFF_COUNT_CLEAR_STACK, + 0 | CFF_COUNT_CLEAR_STACK, + + 0 | CFF_COUNT_CLEAR_STACK, /* rrcurveto */ + 0 | CFF_COUNT_CLEAR_STACK, + 0 | CFF_COUNT_CLEAR_STACK, + 0 | CFF_COUNT_CLEAR_STACK, + 0 | CFF_COUNT_CLEAR_STACK, + 0 | CFF_COUNT_CLEAR_STACK, + 0 | CFF_COUNT_CLEAR_STACK, + + 13, /* flex */ + 7, + 9, + 11, + + 0 | CFF_COUNT_CHECK_WIDTH, /* endchar */ + + 2 | CFF_COUNT_CHECK_WIDTH, /* hstem */ + 2 | CFF_COUNT_CHECK_WIDTH, + 2 | CFF_COUNT_CHECK_WIDTH, + 2 | CFF_COUNT_CHECK_WIDTH, + + 0 | CFF_COUNT_CHECK_WIDTH, /* hintmask */ + 0 | CFF_COUNT_CHECK_WIDTH, /* cntrmask */ + 0, /* dotsection */ + + 1, /* abs */ + 2, + 2, + 2, + 1, + 0, + 2, + 1, + + 1, /* blend */ + + 1, /* drop */ + 2, + 1, + 2, + 1, + + 2, /* put */ + 1, + 4, + 3, + + 2, /* and */ + 2, + 1, + 2, + 4, + + 1, /* callsubr */ + 1, + 0, + + 2, /* hsbw */ + 0, + 0, + 0, + 5, /* seac */ + 4, /* sbw */ + 2 /* setcurrentpoint */ + }; + + + static FT_Error + cff_operator_seac( CFF_Decoder* decoder, + FT_Pos asb, + FT_Pos adx, + FT_Pos ady, + FT_Int bchar, + FT_Int achar ) + { + FT_Error error; + CFF_Builder* builder = &decoder->builder; + FT_Int bchar_index, achar_index; + TT_Face face = decoder->builder.face; + FT_Vector left_bearing, advance; + FT_Byte* charstring; + FT_ULong charstring_len; + FT_Pos glyph_width; + + + if ( decoder->seac ) + { + FT_ERROR(( "cff_operator_seac: invalid nested seac\n" )); + return FT_THROW( Syntax_Error ); + } + + adx += decoder->builder.left_bearing.x; + ady += decoder->builder.left_bearing.y; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* Incremental fonts don't necessarily have valid charsets. */ + /* They use the character code, not the glyph index, in this case. */ + if ( face->root.internal->incremental_interface ) + { + bchar_index = bchar; + achar_index = achar; + } + else +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + { + CFF_Font cff = (CFF_Font)(face->extra.data); + + + bchar_index = cff_lookup_glyph_by_stdcharcode( cff, bchar ); + achar_index = cff_lookup_glyph_by_stdcharcode( cff, achar ); + } + + if ( bchar_index < 0 || achar_index < 0 ) + { + FT_ERROR(( "cff_operator_seac:" + " invalid seac character code arguments\n" )); + return FT_THROW( Syntax_Error ); + } + + /* If we are trying to load a composite glyph, do not load the */ + /* accent character and return the array of subglyphs. */ + if ( builder->no_recurse ) + { + FT_GlyphSlot glyph = (FT_GlyphSlot)builder->glyph; + FT_GlyphLoader loader = glyph->internal->loader; + FT_SubGlyph subg; + + + /* reallocate subglyph array if necessary */ + error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 ); + if ( error ) + goto Exit; + + subg = loader->current.subglyphs; + + /* subglyph 0 = base character */ + subg->index = bchar_index; + subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES | + FT_SUBGLYPH_FLAG_USE_MY_METRICS; + subg->arg1 = 0; + subg->arg2 = 0; + subg++; + + /* subglyph 1 = accent character */ + subg->index = achar_index; + subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; + subg->arg1 = (FT_Int)( adx >> 16 ); + subg->arg2 = (FT_Int)( ady >> 16 ); + + /* set up remaining glyph fields */ + glyph->num_subglyphs = 2; + glyph->subglyphs = loader->base.subglyphs; + glyph->format = FT_GLYPH_FORMAT_COMPOSITE; + + loader->current.num_subglyphs = 2; + } + + FT_GlyphLoader_Prepare( builder->loader ); + + /* First load `bchar' in builder */ + error = decoder->get_glyph_callback( face, (FT_UInt)bchar_index, + &charstring, &charstring_len ); + if ( !error ) + { + /* the seac operator must not be nested */ + decoder->seac = TRUE; + error = cff_decoder_parse_charstrings( decoder, charstring, + charstring_len, 0 ); + decoder->seac = FALSE; + + decoder->free_glyph_callback( face, &charstring, charstring_len ); + + if ( error ) + goto Exit; + } + + /* Save the left bearing, advance and glyph width of the base */ + /* character as they will be erased by the next load. */ + + left_bearing = builder->left_bearing; + advance = builder->advance; + glyph_width = decoder->glyph_width; + + builder->left_bearing.x = 0; + builder->left_bearing.y = 0; + + builder->pos_x = adx - asb; + builder->pos_y = ady; + + /* Now load `achar' on top of the base outline. */ + error = decoder->get_glyph_callback( face, (FT_UInt)achar_index, + &charstring, &charstring_len ); + if ( !error ) + { + /* the seac operator must not be nested */ + decoder->seac = TRUE; + error = cff_decoder_parse_charstrings( decoder, charstring, + charstring_len, 0 ); + decoder->seac = FALSE; + + decoder->free_glyph_callback( face, &charstring, charstring_len ); + + if ( error ) + goto Exit; + } + + /* Restore the left side bearing, advance and glyph width */ + /* of the base character. */ + builder->left_bearing = left_bearing; + builder->advance = advance; + decoder->glyph_width = glyph_width; + + builder->pos_x = 0; + builder->pos_y = 0; + + Exit: + return error; + } + +#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ + + + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********** *********/ + /********** *********/ + /********** GENERIC CHARSTRING PARSING *********/ + /********** *********/ + /********** *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cff_compute_bias */ + /* */ + /* <Description> */ + /* Computes the bias value in dependence of the number of glyph */ + /* subroutines. */ + /* */ + /* <Input> */ + /* in_charstring_type :: The `CharstringType' value of the top DICT */ + /* dictionary. */ + /* */ + /* num_subrs :: The number of glyph subroutines. */ + /* */ + /* <Return> */ + /* The bias value. */ + static FT_Int + cff_compute_bias( FT_Int in_charstring_type, + FT_UInt num_subrs ) + { + FT_Int result; + + + if ( in_charstring_type == 1 ) + result = 0; + else if ( num_subrs < 1240 ) + result = 107; + else if ( num_subrs < 33900U ) + result = 1131; + else + result = 32768U; + + return result; + } + + + FT_LOCAL_DEF( FT_Int ) + cff_lookup_glyph_by_stdcharcode( CFF_Font cff, + FT_Int charcode ) + { + FT_UInt n; + FT_UShort glyph_sid; + + FT_Service_CFFLoad cffload; + + + /* CID-keyed fonts don't have glyph names */ + if ( !cff->charset.sids ) + return -1; + + /* check range of standard char code */ + if ( charcode < 0 || charcode > 255 ) + return -1; + +#if 0 + /* retrieve cffload from list of current modules */ + FT_Service_CFFLoad cffload; + + + FT_FACE_FIND_GLOBAL_SERVICE( face, cffload, CFF_LOAD ); + if ( !cffload ) + { + FT_ERROR(( "cff_lookup_glyph_by_stdcharcode:" + " the `cffload' module is not available\n" )); + return FT_THROW( Unimplemented_Feature ); + } +#endif + + cffload = (FT_Service_CFFLoad)cff->cffload; + + /* Get code to SID mapping from `cff_standard_encoding'. */ + glyph_sid = cffload->get_standard_encoding( (FT_UInt)charcode ); + + for ( n = 0; n < cff->num_glyphs; n++ ) + { + if ( cff->charset.sids[n] == glyph_sid ) + return (FT_Int)n; + } + + return -1; + } + + +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cff_decoder_parse_charstrings */ + /* */ + /* <Description> */ + /* Parses a given Type 2 charstrings program. */ + /* */ + /* <InOut> */ + /* decoder :: The current Type 1 decoder. */ + /* */ + /* <Input> */ + /* charstring_base :: The base of the charstring stream. */ + /* */ + /* charstring_len :: The length in bytes of the charstring stream. */ + /* */ + /* in_dict :: Set to 1 if function is called from top or */ + /* private DICT (needed for Multiple Master CFFs). */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + cff_decoder_parse_charstrings( CFF_Decoder* decoder, + FT_Byte* charstring_base, + FT_ULong charstring_len, + FT_Bool in_dict ) + { + FT_Error error; + CFF_Decoder_Zone* zone; + FT_Byte* ip; + FT_Byte* limit; + CFF_Builder* builder = &decoder->builder; + FT_Pos x, y; + FT_Fixed* stack; + FT_Int charstring_type = + decoder->cff->top_font.font_dict.charstring_type; + FT_UShort num_designs = + decoder->cff->top_font.font_dict.num_designs; + FT_UShort num_axes = + decoder->cff->top_font.font_dict.num_axes; + + T2_Hints_Funcs hinter; + + + /* set default width */ + decoder->num_hints = 0; + decoder->read_width = 1; + + /* initialize the decoder */ + decoder->top = decoder->stack; + decoder->zone = decoder->zones; + zone = decoder->zones; + stack = decoder->top; + + hinter = (T2_Hints_Funcs)builder->hints_funcs; + + builder->path_begun = 0; + + zone->base = charstring_base; + limit = zone->limit = charstring_base + charstring_len; + ip = zone->cursor = zone->base; + + error = FT_Err_Ok; + + x = builder->pos_x; + y = builder->pos_y; + + /* begin hints recording session, if any */ + if ( hinter ) + hinter->open( hinter->hints ); + + /* now execute loop */ + while ( ip < limit ) + { + CFF_Operator op; + FT_Byte v; + + + /********************************************************************/ + /* */ + /* Decode operator or operand */ + /* */ + v = *ip++; + if ( v >= 32 || v == 28 ) + { + FT_Int shift = 16; + FT_Int32 val; + + + /* this is an operand, push it on the stack */ + + /* if we use shifts, all computations are done with unsigned */ + /* values; the conversion to a signed value is the last step */ + if ( v == 28 ) + { + if ( ip + 1 >= limit ) + goto Syntax_Error; + val = (FT_Short)( ( (FT_UShort)ip[0] << 8 ) | ip[1] ); + ip += 2; + } + else if ( v < 247 ) + val = (FT_Int32)v - 139; + else if ( v < 251 ) + { + if ( ip >= limit ) + goto Syntax_Error; + val = ( (FT_Int32)v - 247 ) * 256 + *ip++ + 108; + } + else if ( v < 255 ) + { + if ( ip >= limit ) + goto Syntax_Error; + val = -( (FT_Int32)v - 251 ) * 256 - *ip++ - 108; + } + else + { + if ( ip + 3 >= limit ) + goto Syntax_Error; + val = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) | + ( (FT_UInt32)ip[1] << 16 ) | + ( (FT_UInt32)ip[2] << 8 ) | + (FT_UInt32)ip[3] ); + ip += 4; + if ( charstring_type == 2 ) + shift = 0; + } + if ( decoder->top - stack >= CFF_MAX_OPERANDS ) + goto Stack_Overflow; + + val = (FT_Int32)( (FT_UInt32)val << shift ); + *decoder->top++ = val; + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( !( val & 0xFFFFL ) ) + FT_TRACE4(( " %hd", (FT_Short)( (FT_UInt32)val >> 16 ) )); + else + FT_TRACE4(( " %.5f", val / 65536.0 )); +#endif + + } + else + { + /* The specification says that normally arguments are to be taken */ + /* from the bottom of the stack. However, this seems not to be */ + /* correct, at least for Acroread 7.0.8 on GNU/Linux: It pops the */ + /* arguments similar to a PS interpreter. */ + + FT_Fixed* args = decoder->top; + FT_Int num_args = (FT_Int)( args - decoder->stack ); + FT_Int req_args; + + + /* find operator */ + op = cff_op_unknown; + + switch ( v ) + { + case 1: + op = cff_op_hstem; + break; + case 3: + op = cff_op_vstem; + break; + case 4: + op = cff_op_vmoveto; + break; + case 5: + op = cff_op_rlineto; + break; + case 6: + op = cff_op_hlineto; + break; + case 7: + op = cff_op_vlineto; + break; + case 8: + op = cff_op_rrcurveto; + break; + case 9: + op = cff_op_closepath; + break; + case 10: + op = cff_op_callsubr; + break; + case 11: + op = cff_op_return; + break; + case 12: + if ( ip >= limit ) + goto Syntax_Error; + v = *ip++; + + switch ( v ) + { + case 0: + op = cff_op_dotsection; + break; + case 1: /* this is actually the Type1 vstem3 operator */ + op = cff_op_vstem; + break; + case 2: /* this is actually the Type1 hstem3 operator */ + op = cff_op_hstem; + break; + case 3: + op = cff_op_and; + break; + case 4: + op = cff_op_or; + break; + case 5: + op = cff_op_not; + break; + case 6: + op = cff_op_seac; + break; + case 7: + op = cff_op_sbw; + break; + case 8: + op = cff_op_store; + break; + case 9: + op = cff_op_abs; + break; + case 10: + op = cff_op_add; + break; + case 11: + op = cff_op_sub; + break; + case 12: + op = cff_op_div; + break; + case 13: + op = cff_op_load; + break; + case 14: + op = cff_op_neg; + break; + case 15: + op = cff_op_eq; + break; + case 16: + op = cff_op_callothersubr; + break; + case 17: + op = cff_op_pop; + break; + case 18: + op = cff_op_drop; + break; + case 20: + op = cff_op_put; + break; + case 21: + op = cff_op_get; + break; + case 22: + op = cff_op_ifelse; + break; + case 23: + op = cff_op_random; + break; + case 24: + op = cff_op_mul; + break; + case 26: + op = cff_op_sqrt; + break; + case 27: + op = cff_op_dup; + break; + case 28: + op = cff_op_exch; + break; + case 29: + op = cff_op_index; + break; + case 30: + op = cff_op_roll; + break; + case 33: + op = cff_op_setcurrentpoint; + break; + case 34: + op = cff_op_hflex; + break; + case 35: + op = cff_op_flex; + break; + case 36: + op = cff_op_hflex1; + break; + case 37: + op = cff_op_flex1; + break; + default: + FT_TRACE4(( " unknown op (12, %d)\n", v )); + break; + } + break; + case 13: + op = cff_op_hsbw; + break; + case 14: + op = cff_op_endchar; + break; + case 16: + op = cff_op_blend; + break; + case 18: + op = cff_op_hstemhm; + break; + case 19: + op = cff_op_hintmask; + break; + case 20: + op = cff_op_cntrmask; + break; + case 21: + op = cff_op_rmoveto; + break; + case 22: + op = cff_op_hmoveto; + break; + case 23: + op = cff_op_vstemhm; + break; + case 24: + op = cff_op_rcurveline; + break; + case 25: + op = cff_op_rlinecurve; + break; + case 26: + op = cff_op_vvcurveto; + break; + case 27: + op = cff_op_hhcurveto; + break; + case 29: + op = cff_op_callgsubr; + break; + case 30: + op = cff_op_vhcurveto; + break; + case 31: + op = cff_op_hvcurveto; + break; + default: + FT_TRACE4(( " unknown op (%d)\n", v )); + break; + } + + if ( op == cff_op_unknown ) + continue; + + /* in Multiple Master CFFs, T2 charstrings can appear in */ + /* dictionaries, but some operators are prohibited */ + if ( in_dict ) + { + switch ( op ) + { + case cff_op_hstem: + case cff_op_vstem: + case cff_op_vmoveto: + case cff_op_rlineto: + case cff_op_hlineto: + case cff_op_vlineto: + case cff_op_rrcurveto: + case cff_op_hstemhm: + case cff_op_hintmask: + case cff_op_cntrmask: + case cff_op_rmoveto: + case cff_op_hmoveto: + case cff_op_vstemhm: + case cff_op_rcurveline: + case cff_op_rlinecurve: + case cff_op_vvcurveto: + case cff_op_hhcurveto: + case cff_op_vhcurveto: + case cff_op_hvcurveto: + case cff_op_hflex: + case cff_op_flex: + case cff_op_hflex1: + case cff_op_flex1: + case cff_op_callsubr: + case cff_op_callgsubr: + goto MM_Error; + + default: + break; + } + } + + /* check arguments */ + req_args = cff_argument_counts[op]; + if ( req_args & CFF_COUNT_CHECK_WIDTH ) + { + if ( num_args > 0 && decoder->read_width ) + { + /* If `nominal_width' is non-zero, the number is really a */ + /* difference against `nominal_width'. Else, the number here */ + /* is truly a width, not a difference against `nominal_width'. */ + /* If the font does not set `nominal_width', then */ + /* `nominal_width' defaults to zero, and so we can set */ + /* `glyph_width' to `nominal_width' plus number on the stack */ + /* -- for either case. */ + + FT_Int set_width_ok; + + + switch ( op ) + { + case cff_op_hmoveto: + case cff_op_vmoveto: + set_width_ok = num_args & 2; + break; + + case cff_op_hstem: + case cff_op_vstem: + case cff_op_hstemhm: + case cff_op_vstemhm: + case cff_op_rmoveto: + case cff_op_hintmask: + case cff_op_cntrmask: + set_width_ok = num_args & 1; + break; + + case cff_op_endchar: + /* If there is a width specified for endchar, we either have */ + /* 1 argument or 5 arguments. We like to argue. */ + set_width_ok = in_dict + ? 0 + : ( ( num_args == 5 ) || ( num_args == 1 ) ); + break; + + default: + set_width_ok = 0; + break; + } + + if ( set_width_ok ) + { + decoder->glyph_width = decoder->nominal_width + + ( stack[0] >> 16 ); + + if ( decoder->width_only ) + { + /* we only want the advance width; stop here */ + break; + } + + /* Consumed an argument. */ + num_args--; + } + } + + decoder->read_width = 0; + req_args = 0; + } + + req_args &= 0x000F; + if ( num_args < req_args ) + goto Stack_Underflow; + args -= req_args; + num_args -= req_args; + + /* At this point, `args' points to the first argument of the */ + /* operand in case `req_args' isn't zero. Otherwise, we have */ + /* to adjust `args' manually. */ + + /* Note that we only pop arguments from the stack which we */ + /* really need and can digest so that we can continue in case */ + /* of superfluous stack elements. */ + + switch ( op ) + { + case cff_op_hstem: + case cff_op_vstem: + case cff_op_hstemhm: + case cff_op_vstemhm: + /* the number of arguments is always even here */ + FT_TRACE4(( + op == cff_op_hstem ? " hstem\n" : + ( op == cff_op_vstem ? " vstem\n" : + ( op == cff_op_hstemhm ? " hstemhm\n" : " vstemhm\n" ) ) )); + + if ( hinter ) + hinter->stems( hinter->hints, + ( op == cff_op_hstem || op == cff_op_hstemhm ), + num_args / 2, + args - ( num_args & ~1 ) ); + + decoder->num_hints += num_args / 2; + args = stack; + break; + + case cff_op_hintmask: + case cff_op_cntrmask: + FT_TRACE4(( op == cff_op_hintmask ? " hintmask" : " cntrmask" )); + + /* implement vstem when needed -- */ + /* the specification doesn't say it, but this also works */ + /* with the 'cntrmask' operator */ + /* */ + if ( num_args > 0 ) + { + if ( hinter ) + hinter->stems( hinter->hints, + 0, + num_args / 2, + args - ( num_args & ~1 ) ); + + decoder->num_hints += num_args / 2; + } + + /* In a valid charstring there must be at least one byte */ + /* after `hintmask' or `cntrmask' (e.g., for a `return' */ + /* instruction). Additionally, there must be space for */ + /* `num_hints' bits. */ + + if ( ( ip + ( ( decoder->num_hints + 7 ) >> 3 ) ) >= limit ) + goto Syntax_Error; + + if ( hinter ) + { + if ( op == cff_op_hintmask ) + hinter->hintmask( hinter->hints, + (FT_UInt)builder->current->n_points, + (FT_UInt)decoder->num_hints, + ip ); + else + hinter->counter( hinter->hints, + (FT_UInt)decoder->num_hints, + ip ); + } + +#ifdef FT_DEBUG_LEVEL_TRACE + { + FT_UInt maskbyte; + + + FT_TRACE4(( " (maskbytes:" )); + + for ( maskbyte = 0; + maskbyte < (FT_UInt)( ( decoder->num_hints + 7 ) >> 3 ); + maskbyte++, ip++ ) + FT_TRACE4(( " 0x%02X", *ip )); + + FT_TRACE4(( ")\n" )); + } +#else + ip += ( decoder->num_hints + 7 ) >> 3; +#endif + args = stack; + break; + + case cff_op_rmoveto: + FT_TRACE4(( " rmoveto\n" )); + + cff_builder_close_contour( builder ); + builder->path_begun = 0; + x = ADD_LONG( x, args[-2] ); + y = ADD_LONG( y, args[-1] ); + args = stack; + break; + + case cff_op_vmoveto: + FT_TRACE4(( " vmoveto\n" )); + + cff_builder_close_contour( builder ); + builder->path_begun = 0; + y = ADD_LONG( y, args[-1] ); + args = stack; + break; + + case cff_op_hmoveto: + FT_TRACE4(( " hmoveto\n" )); + + cff_builder_close_contour( builder ); + builder->path_begun = 0; + x = ADD_LONG( x, args[-1] ); + args = stack; + break; + + case cff_op_rlineto: + FT_TRACE4(( " rlineto\n" )); + + if ( cff_builder_start_point( builder, x, y ) || + cff_check_points( builder, num_args / 2 ) ) + goto Fail; + + if ( num_args < 2 ) + goto Stack_Underflow; + + args -= num_args & ~1; + while ( args < decoder->top ) + { + x = ADD_LONG( x, args[0] ); + y = ADD_LONG( y, args[1] ); + cff_builder_add_point( builder, x, y, 1 ); + args += 2; + } + args = stack; + break; + + case cff_op_hlineto: + case cff_op_vlineto: + { + FT_Int phase = ( op == cff_op_hlineto ); + + + FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n" + : " vlineto\n" )); + + if ( num_args < 0 ) + goto Stack_Underflow; + + /* there exist subsetted fonts (found in PDFs) */ + /* which call `hlineto' without arguments */ + if ( num_args == 0 ) + break; + + if ( cff_builder_start_point( builder, x, y ) || + cff_check_points( builder, num_args ) ) + goto Fail; + + args = stack; + while ( args < decoder->top ) + { + if ( phase ) + x = ADD_LONG( x, args[0] ); + else + y = ADD_LONG( y, args[0] ); + + if ( cff_builder_add_point1( builder, x, y ) ) + goto Fail; + + args++; + phase ^= 1; + } + args = stack; + } + break; + + case cff_op_rrcurveto: + { + FT_Int nargs; + + + FT_TRACE4(( " rrcurveto\n" )); + + if ( num_args < 6 ) + goto Stack_Underflow; + + nargs = num_args - num_args % 6; + + if ( cff_builder_start_point( builder, x, y ) || + cff_check_points( builder, nargs / 2 ) ) + goto Fail; + + args -= nargs; + while ( args < decoder->top ) + { + x = ADD_LONG( x, args[0] ); + y = ADD_LONG( y, args[1] ); + cff_builder_add_point( builder, x, y, 0 ); + + x = ADD_LONG( x, args[2] ); + y = ADD_LONG( y, args[3] ); + cff_builder_add_point( builder, x, y, 0 ); + + x = ADD_LONG( x, args[4] ); + y = ADD_LONG( y, args[5] ); + cff_builder_add_point( builder, x, y, 1 ); + + args += 6; + } + args = stack; + } + break; + + case cff_op_vvcurveto: + { + FT_Int nargs; + + + FT_TRACE4(( " vvcurveto\n" )); + + if ( num_args < 4 ) + goto Stack_Underflow; + + /* if num_args isn't of the form 4n or 4n+1, */ + /* we enforce it by clearing the second bit */ + + nargs = num_args & ~2; + + if ( cff_builder_start_point( builder, x, y ) ) + goto Fail; + + args -= nargs; + + if ( nargs & 1 ) + { + x = ADD_LONG( x, args[0] ); + args++; + nargs--; + } + + if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) ) + goto Fail; + + while ( args < decoder->top ) + { + y = ADD_LONG( y, args[0] ); + cff_builder_add_point( builder, x, y, 0 ); + + x = ADD_LONG( x, args[1] ); + y = ADD_LONG( y, args[2] ); + cff_builder_add_point( builder, x, y, 0 ); + + y = ADD_LONG( y, args[3] ); + cff_builder_add_point( builder, x, y, 1 ); + + args += 4; + } + args = stack; + } + break; + + case cff_op_hhcurveto: + { + FT_Int nargs; + + + FT_TRACE4(( " hhcurveto\n" )); + + if ( num_args < 4 ) + goto Stack_Underflow; + + /* if num_args isn't of the form 4n or 4n+1, */ + /* we enforce it by clearing the second bit */ + + nargs = num_args & ~2; + + if ( cff_builder_start_point( builder, x, y ) ) + goto Fail; + + args -= nargs; + if ( nargs & 1 ) + { + y = ADD_LONG( y, args[0] ); + args++; + nargs--; + } + + if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) ) + goto Fail; + + while ( args < decoder->top ) + { + x = ADD_LONG( x, args[0] ); + cff_builder_add_point( builder, x, y, 0 ); + + x = ADD_LONG( x, args[1] ); + y = ADD_LONG( y, args[2] ); + cff_builder_add_point( builder, x, y, 0 ); + + x = ADD_LONG( x, args[3] ); + cff_builder_add_point( builder, x, y, 1 ); + + args += 4; + } + args = stack; + } + break; + + case cff_op_vhcurveto: + case cff_op_hvcurveto: + { + FT_Int phase; + FT_Int nargs; + + + FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto\n" + : " hvcurveto\n" )); + + if ( cff_builder_start_point( builder, x, y ) ) + goto Fail; + + if ( num_args < 4 ) + goto Stack_Underflow; + + /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */ + /* we enforce it by clearing the second bit */ + + nargs = num_args & ~2; + + args -= nargs; + if ( cff_check_points( builder, ( nargs / 4 ) * 3 ) ) + goto Stack_Underflow; + + phase = ( op == cff_op_hvcurveto ); + + while ( nargs >= 4 ) + { + nargs -= 4; + if ( phase ) + { + x = ADD_LONG( x, args[0] ); + cff_builder_add_point( builder, x, y, 0 ); + + x = ADD_LONG( x, args[1] ); + y = ADD_LONG( y, args[2] ); + cff_builder_add_point( builder, x, y, 0 ); + + y = ADD_LONG( y, args[3] ); + if ( nargs == 1 ) + x = ADD_LONG( x, args[4] ); + cff_builder_add_point( builder, x, y, 1 ); + } + else + { + y = ADD_LONG( y, args[0] ); + cff_builder_add_point( builder, x, y, 0 ); + + x = ADD_LONG( x, args[1] ); + y = ADD_LONG( y, args[2] ); + cff_builder_add_point( builder, x, y, 0 ); + + x = ADD_LONG( x, args[3] ); + if ( nargs == 1 ) + y = ADD_LONG( y, args[4] ); + cff_builder_add_point( builder, x, y, 1 ); + } + args += 4; + phase ^= 1; + } + args = stack; + } + break; + + case cff_op_rlinecurve: + { + FT_Int num_lines; + FT_Int nargs; + + + FT_TRACE4(( " rlinecurve\n" )); + + if ( num_args < 8 ) + goto Stack_Underflow; + + nargs = num_args & ~1; + num_lines = ( nargs - 6 ) / 2; + + if ( cff_builder_start_point( builder, x, y ) || + cff_check_points( builder, num_lines + 3 ) ) + goto Fail; + + args -= nargs; + + /* first, add the line segments */ + while ( num_lines > 0 ) + { + x = ADD_LONG( x, args[0] ); + y = ADD_LONG( y, args[1] ); + cff_builder_add_point( builder, x, y, 1 ); + + args += 2; + num_lines--; + } + + /* then the curve */ + x = ADD_LONG( x, args[0] ); + y = ADD_LONG( y, args[1] ); + cff_builder_add_point( builder, x, y, 0 ); + + x = ADD_LONG( x, args[2] ); + y = ADD_LONG( y, args[3] ); + cff_builder_add_point( builder, x, y, 0 ); + + x = ADD_LONG( x, args[4] ); + y = ADD_LONG( y, args[5] ); + cff_builder_add_point( builder, x, y, 1 ); + + args = stack; + } + break; + + case cff_op_rcurveline: + { + FT_Int num_curves; + FT_Int nargs; + + + FT_TRACE4(( " rcurveline\n" )); + + if ( num_args < 8 ) + goto Stack_Underflow; + + nargs = num_args - 2; + nargs = nargs - nargs % 6 + 2; + num_curves = ( nargs - 2 ) / 6; + + if ( cff_builder_start_point( builder, x, y ) || + cff_check_points( builder, num_curves * 3 + 2 ) ) + goto Fail; + + args -= nargs; + + /* first, add the curves */ + while ( num_curves > 0 ) + { + x = ADD_LONG( x, args[0] ); + y = ADD_LONG( y, args[1] ); + cff_builder_add_point( builder, x, y, 0 ); + + x = ADD_LONG( x, args[2] ); + y = ADD_LONG( y, args[3] ); + cff_builder_add_point( builder, x, y, 0 ); + + x = ADD_LONG( x, args[4] ); + y = ADD_LONG( y, args[5] ); + cff_builder_add_point( builder, x, y, 1 ); + + args += 6; + num_curves--; + } + + /* then the final line */ + x = ADD_LONG( x, args[0] ); + y = ADD_LONG( y, args[1] ); + cff_builder_add_point( builder, x, y, 1 ); + + args = stack; + } + break; + + case cff_op_hflex1: + { + FT_Pos start_y; + + + FT_TRACE4(( " hflex1\n" )); + + /* adding five more points: 4 control points, 1 on-curve point */ + /* -- make sure we have enough space for the start point if it */ + /* needs to be added */ + if ( cff_builder_start_point( builder, x, y ) || + cff_check_points( builder, 6 ) ) + goto Fail; + + /* record the starting point's y position for later use */ + start_y = y; + + /* first control point */ + x = ADD_LONG( x, args[0] ); + y = ADD_LONG( y, args[1] ); + cff_builder_add_point( builder, x, y, 0 ); + + /* second control point */ + x = ADD_LONG( x, args[2] ); + y = ADD_LONG( y, args[3] ); + cff_builder_add_point( builder, x, y, 0 ); + + /* join point; on curve, with y-value the same as the last */ + /* control point's y-value */ + x = ADD_LONG( x, args[4] ); + cff_builder_add_point( builder, x, y, 1 ); + + /* third control point, with y-value the same as the join */ + /* point's y-value */ + x = ADD_LONG( x, args[5] ); + cff_builder_add_point( builder, x, y, 0 ); + + /* fourth control point */ + x = ADD_LONG( x, args[6] ); + y = ADD_LONG( y, args[7] ); + cff_builder_add_point( builder, x, y, 0 ); + + /* ending point, with y-value the same as the start */ + x = ADD_LONG( x, args[8] ); + y = start_y; + cff_builder_add_point( builder, x, y, 1 ); + + args = stack; + break; + } + + case cff_op_hflex: + { + FT_Pos start_y; + + + FT_TRACE4(( " hflex\n" )); + + /* adding six more points; 4 control points, 2 on-curve points */ + if ( cff_builder_start_point( builder, x, y ) || + cff_check_points( builder, 6 ) ) + goto Fail; + + /* record the starting point's y-position for later use */ + start_y = y; + + /* first control point */ + x = ADD_LONG( x, args[0] ); + cff_builder_add_point( builder, x, y, 0 ); + + /* second control point */ + x = ADD_LONG( x, args[1] ); + y = ADD_LONG( y, args[2] ); + cff_builder_add_point( builder, x, y, 0 ); + + /* join point; on curve, with y-value the same as the last */ + /* control point's y-value */ + x = ADD_LONG( x, args[3] ); + cff_builder_add_point( builder, x, y, 1 ); + + /* third control point, with y-value the same as the join */ + /* point's y-value */ + x = ADD_LONG( x, args[4] ); + cff_builder_add_point( builder, x, y, 0 ); + + /* fourth control point */ + x = ADD_LONG( x, args[5] ); + y = start_y; + cff_builder_add_point( builder, x, y, 0 ); + + /* ending point, with y-value the same as the start point's */ + /* y-value -- we don't add this point, though */ + x = ADD_LONG( x, args[6] ); + cff_builder_add_point( builder, x, y, 1 ); + + args = stack; + break; + } + + case cff_op_flex1: + { + FT_Pos start_x, start_y; /* record start x, y values for */ + /* alter use */ + FT_Fixed dx = 0, dy = 0; /* used in horizontal/vertical */ + /* algorithm below */ + FT_Int horizontal, count; + FT_Fixed* temp; + + + FT_TRACE4(( " flex1\n" )); + + /* adding six more points; 4 control points, 2 on-curve points */ + if ( cff_builder_start_point( builder, x, y ) || + cff_check_points( builder, 6 ) ) + goto Fail; + + /* record the starting point's x, y position for later use */ + start_x = x; + start_y = y; + + /* XXX: figure out whether this is supposed to be a horizontal */ + /* or vertical flex; the Type 2 specification is vague... */ + + temp = args; + + /* grab up to the last argument */ + for ( count = 5; count > 0; count-- ) + { + dx = ADD_LONG( dx, temp[0] ); + dy = ADD_LONG( dy, temp[1] ); + temp += 2; + } + + if ( dx < 0 ) + dx = -dx; + if ( dy < 0 ) + dy = -dy; + + /* strange test, but here it is... */ + horizontal = ( dx > dy ); + + for ( count = 5; count > 0; count-- ) + { + x = ADD_LONG( x, args[0] ); + y = ADD_LONG( y, args[1] ); + cff_builder_add_point( builder, x, y, + (FT_Bool)( count == 3 ) ); + args += 2; + } + + /* is last operand an x- or y-delta? */ + if ( horizontal ) + { + x = ADD_LONG( x, args[0] ); + y = start_y; + } + else + { + x = start_x; + y = ADD_LONG( y, args[0] ); + } + + cff_builder_add_point( builder, x, y, 1 ); + + args = stack; + break; + } + + case cff_op_flex: + { + FT_UInt count; + + + FT_TRACE4(( " flex\n" )); + + if ( cff_builder_start_point( builder, x, y ) || + cff_check_points( builder, 6 ) ) + goto Fail; + + for ( count = 6; count > 0; count-- ) + { + x = ADD_LONG( x, args[0] ); + y = ADD_LONG( y, args[1] ); + cff_builder_add_point( builder, x, y, + (FT_Bool)( count == 4 || count == 1 ) ); + args += 2; + } + + args = stack; + } + break; + + case cff_op_seac: + FT_TRACE4(( " seac\n" )); + + error = cff_operator_seac( decoder, + args[0], args[1], args[2], + (FT_Int)( args[3] >> 16 ), + (FT_Int)( args[4] >> 16 ) ); + + /* add current outline to the glyph slot */ + FT_GlyphLoader_Add( builder->loader ); + + /* return now! */ + FT_TRACE4(( "\n" )); + return error; + + case cff_op_endchar: + /* in dictionaries, `endchar' simply indicates end of data */ + if ( in_dict ) + return error; + + FT_TRACE4(( " endchar\n" )); + + /* We are going to emulate the seac operator. */ + if ( num_args >= 4 ) + { + /* Save glyph width so that the subglyphs don't overwrite it. */ + FT_Pos glyph_width = decoder->glyph_width; + + + error = cff_operator_seac( decoder, + 0L, args[-4], args[-3], + (FT_Int)( args[-2] >> 16 ), + (FT_Int)( args[-1] >> 16 ) ); + + decoder->glyph_width = glyph_width; + } + else + { + cff_builder_close_contour( builder ); + + /* close hints recording session */ + if ( hinter ) + { + if ( hinter->close( hinter->hints, + (FT_UInt)builder->current->n_points ) ) + goto Syntax_Error; + + /* apply hints to the loaded glyph outline now */ + error = hinter->apply( hinter->hints, + builder->current, + (PSH_Globals)builder->hints_globals, + decoder->hint_mode ); + if ( error ) + goto Fail; + } + + /* add current outline to the glyph slot */ + FT_GlyphLoader_Add( builder->loader ); + } + + /* return now! */ + FT_TRACE4(( "\n" )); + return error; + + case cff_op_abs: + FT_TRACE4(( " abs\n" )); + + if ( args[0] < 0 ) + { + if ( args[0] == FT_LONG_MIN ) + args[0] = FT_LONG_MAX; + else + args[0] = -args[0]; + } + args++; + break; + + case cff_op_add: + FT_TRACE4(( " add\n" )); + + args[0] = ADD_LONG( args[0], args[1] ); + args++; + break; + + case cff_op_sub: + FT_TRACE4(( " sub\n" )); + + args[0] = SUB_LONG( args[0], args[1] ); + args++; + break; + + case cff_op_div: + FT_TRACE4(( " div\n" )); + + args[0] = FT_DivFix( args[0], args[1] ); + args++; + break; + + case cff_op_neg: + FT_TRACE4(( " neg\n" )); + + if ( args[0] == FT_LONG_MIN ) + args[0] = FT_LONG_MAX; + args[0] = -args[0]; + args++; + break; + + case cff_op_random: + FT_TRACE4(( " random\n" )); + + /* only use the lower 16 bits of `random' */ + /* to generate a number in the range (0;1] */ + args[0] = (FT_Fixed) + ( ( decoder->current_subfont->random & 0xFFFF ) + 1 ); + args++; + + decoder->current_subfont->random = + cff_random( decoder->current_subfont->random ); + break; + + case cff_op_mul: + FT_TRACE4(( " mul\n" )); + + args[0] = FT_MulFix( args[0], args[1] ); + args++; + break; + + case cff_op_sqrt: + FT_TRACE4(( " sqrt\n" )); + + if ( args[0] > 0 ) + { + FT_Fixed root = args[0]; + FT_Fixed new_root; + + + for (;;) + { + new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1; + if ( new_root == root ) + break; + root = new_root; + } + args[0] = new_root; + } + else + args[0] = 0; + args++; + break; + + case cff_op_drop: + /* nothing */ + FT_TRACE4(( " drop\n" )); + + break; + + case cff_op_exch: + { + FT_Fixed tmp; + + + FT_TRACE4(( " exch\n" )); + + tmp = args[0]; + args[0] = args[1]; + args[1] = tmp; + args += 2; + } + break; + + case cff_op_index: + { + FT_Int idx = (FT_Int)( args[0] >> 16 ); + + + FT_TRACE4(( " index\n" )); + + if ( idx < 0 ) + idx = 0; + else if ( idx > num_args - 2 ) + idx = num_args - 2; + args[0] = args[-( idx + 1 )]; + args++; + } + break; + + case cff_op_roll: + { + FT_Int count = (FT_Int)( args[0] >> 16 ); + FT_Int idx = (FT_Int)( args[1] >> 16 ); + + + FT_TRACE4(( " roll\n" )); + + if ( count <= 0 ) + count = 1; + + args -= count; + if ( args < stack ) + goto Stack_Underflow; + + if ( idx >= 0 ) + { + while ( idx > 0 ) + { + FT_Fixed tmp = args[count - 1]; + FT_Int i; + + + for ( i = count - 2; i >= 0; i-- ) + args[i + 1] = args[i]; + args[0] = tmp; + idx--; + } + } + else + { + while ( idx < 0 ) + { + FT_Fixed tmp = args[0]; + FT_Int i; + + + for ( i = 0; i < count - 1; i++ ) + args[i] = args[i + 1]; + args[count - 1] = tmp; + idx++; + } + } + args += count; + } + break; + + case cff_op_dup: + FT_TRACE4(( " dup\n" )); + + args[1] = args[0]; + args += 2; + break; + + case cff_op_put: + { + FT_Fixed val = args[0]; + FT_Int idx = (FT_Int)( args[1] >> 16 ); + + + FT_TRACE4(( " put\n" )); + + /* the Type2 specification before version 16-March-2000 */ + /* didn't give a hard-coded size limit of the temporary */ + /* storage array; instead, an argument of the */ + /* `MultipleMaster' operator set the size */ + if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS ) + decoder->buildchar[idx] = val; + } + break; + + case cff_op_get: + { + FT_Int idx = (FT_Int)( args[0] >> 16 ); + FT_Fixed val = 0; + + + FT_TRACE4(( " get\n" )); + + if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS ) + val = decoder->buildchar[idx]; + + args[0] = val; + args++; + } + break; + + case cff_op_store: + /* this operator was removed from the Type2 specification */ + /* in version 16-March-2000 */ + + /* since we currently don't handle interpolation of multiple */ + /* master fonts, this is a no-op */ + FT_TRACE4(( " store\n" )); + break; + + case cff_op_load: + /* this operator was removed from the Type2 specification */ + /* in version 16-March-2000 */ + { + FT_Int reg_idx = (FT_Int)args[0]; + FT_Int idx = (FT_Int)args[1]; + FT_Int count = (FT_Int)args[2]; + + + FT_TRACE4(( " load\n" )); + + /* since we currently don't handle interpolation of multiple */ + /* master fonts, we store a vector [1 0 0 ...] in the */ + /* temporary storage array regardless of the Registry index */ + if ( reg_idx >= 0 && reg_idx <= 2 && + idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS && + count >= 0 && count <= num_axes ) + { + FT_Int end, i; + + + end = FT_MIN( idx + count, CFF_MAX_TRANS_ELEMENTS ); + + if ( idx < end ) + decoder->buildchar[idx] = 1 << 16; + + for ( i = idx + 1; i < end; i++ ) + decoder->buildchar[i] = 0; + } + } + break; + + case cff_op_blend: + /* this operator was removed from the Type2 specification */ + /* in version 16-March-2000 */ + { + FT_Int num_results = (FT_Int)( args[0] >> 16 ); + + + FT_TRACE4(( " blend\n" )); + + if ( num_results < 0 ) + goto Syntax_Error; + + if ( num_results * (FT_Int)num_designs > num_args ) + goto Stack_Underflow; + + /* since we currently don't handle interpolation of multiple */ + /* master fonts, return the `num_results' values of the */ + /* first master */ + args -= num_results * ( num_designs - 1 ); + num_args -= num_results * ( num_designs - 1 ); + } + break; + + case cff_op_dotsection: + /* this operator is deprecated and ignored by the parser */ + FT_TRACE4(( " dotsection\n" )); + break; + + case cff_op_closepath: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " closepath (invalid op)\n" )); + + args = stack; + break; + + case cff_op_hsbw: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " hsbw (invalid op)\n" )); + + decoder->glyph_width = + ADD_LONG( decoder->nominal_width, ( args[1] >> 16 ) ); + + decoder->builder.left_bearing.x = args[0]; + decoder->builder.left_bearing.y = 0; + + x = ADD_LONG( decoder->builder.pos_x, args[0] ); + y = decoder->builder.pos_y; + args = stack; + break; + + case cff_op_sbw: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " sbw (invalid op)\n" )); + + decoder->glyph_width = + ADD_LONG( decoder->nominal_width, ( args[2] >> 16 ) ); + + decoder->builder.left_bearing.x = args[0]; + decoder->builder.left_bearing.y = args[1]; + + x = ADD_LONG( decoder->builder.pos_x, args[0] ); + y = ADD_LONG( decoder->builder.pos_y, args[1] ); + args = stack; + break; + + case cff_op_setcurrentpoint: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " setcurrentpoint (invalid op)\n" )); + + x = ADD_LONG( decoder->builder.pos_x, args[0] ); + y = ADD_LONG( decoder->builder.pos_y, args[1] ); + args = stack; + break; + + case cff_op_callothersubr: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " callothersubr (invalid op)\n" )); + + /* subsequent `pop' operands should add the arguments, */ + /* this is the implementation described for `unknown' other */ + /* subroutines in the Type1 spec. */ + /* */ + /* XXX Fix return arguments (see discussion below). */ + args -= 2 + ( args[-2] >> 16 ); + if ( args < stack ) + goto Stack_Underflow; + break; + + case cff_op_pop: + /* this is an invalid Type 2 operator; however, there */ + /* exist fonts which are incorrectly converted from probably */ + /* Type 1 to CFF, and some parsers seem to accept it */ + + FT_TRACE4(( " pop (invalid op)\n" )); + + /* XXX Increasing `args' is wrong: After a certain number of */ + /* `pop's we get a stack overflow. Reason for doing it is */ + /* code like this (actually found in a CFF font): */ + /* */ + /* 17 1 3 callothersubr */ + /* pop */ + /* callsubr */ + /* */ + /* Since we handle `callothersubr' as a no-op, and */ + /* `callsubr' needs at least one argument, `pop' can't be a */ + /* no-op too as it basically should be. */ + /* */ + /* The right solution would be to provide real support for */ + /* `callothersubr' as done in `t1decode.c', however, given */ + /* the fact that CFF fonts with `pop' are invalid, it is */ + /* questionable whether it is worth the time. */ + args++; + break; + + case cff_op_and: + { + FT_Fixed cond = ( args[0] && args[1] ); + + + FT_TRACE4(( " and\n" )); + + args[0] = cond ? 0x10000L : 0; + args++; + } + break; + + case cff_op_or: + { + FT_Fixed cond = ( args[0] || args[1] ); + + + FT_TRACE4(( " or\n" )); + + args[0] = cond ? 0x10000L : 0; + args++; + } + break; + + case cff_op_not: + { + FT_Fixed cond = !args[0]; + + + FT_TRACE4(( " not\n" )); + + args[0] = cond ? 0x10000L : 0; + args++; + } + break; + + case cff_op_eq: + { + FT_Fixed cond = ( args[0] == args[1] ); + + + FT_TRACE4(( " eq\n" )); + + args[0] = cond ? 0x10000L : 0; + args++; + } + break; + + case cff_op_ifelse: + { + FT_Fixed cond = ( args[2] <= args[3] ); + + + FT_TRACE4(( " ifelse\n" )); + + if ( !cond ) + args[0] = args[1]; + args++; + } + break; + + case cff_op_callsubr: + { + FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) + + decoder->locals_bias ); + + + FT_TRACE4(( " callsubr (idx %d, entering level %d)\n", + idx, + zone - decoder->zones + 1 )); + + if ( idx >= decoder->num_locals ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" + " invalid local subr index\n" )); + goto Syntax_Error; + } + + if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" + " too many nested subrs\n" )); + goto Syntax_Error; + } + + zone->cursor = ip; /* save current instruction pointer */ + + zone++; + zone->base = decoder->locals[idx]; + zone->limit = decoder->locals[idx + 1]; + zone->cursor = zone->base; + + if ( !zone->base || zone->limit == zone->base ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" + " invoking empty subrs\n" )); + goto Syntax_Error; + } + + decoder->zone = zone; + ip = zone->base; + limit = zone->limit; + } + break; + + case cff_op_callgsubr: + { + FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) + + decoder->globals_bias ); + + + FT_TRACE4(( " callgsubr (idx %d, entering level %d)\n", + idx, + zone - decoder->zones + 1 )); + + if ( idx >= decoder->num_globals ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" + " invalid global subr index\n" )); + goto Syntax_Error; + } + + if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" + " too many nested subrs\n" )); + goto Syntax_Error; + } + + zone->cursor = ip; /* save current instruction pointer */ + + zone++; + zone->base = decoder->globals[idx]; + zone->limit = decoder->globals[idx + 1]; + zone->cursor = zone->base; + + if ( !zone->base || zone->limit == zone->base ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" + " invoking empty subrs\n" )); + goto Syntax_Error; + } + + decoder->zone = zone; + ip = zone->base; + limit = zone->limit; + } + break; + + case cff_op_return: + FT_TRACE4(( " return (leaving level %d)\n", + decoder->zone - decoder->zones )); + + if ( decoder->zone <= decoder->zones ) + { + FT_ERROR(( "cff_decoder_parse_charstrings:" + " unexpected return\n" )); + goto Syntax_Error; + } + + decoder->zone--; + zone = decoder->zone; + ip = zone->cursor; + limit = zone->limit; + break; + + default: + FT_ERROR(( "Unimplemented opcode: %d", ip[-1] )); + + if ( ip[-1] == 12 ) + FT_ERROR(( " %d", ip[0] )); + FT_ERROR(( "\n" )); + + return FT_THROW( Unimplemented_Feature ); + } + + decoder->top = args; + + if ( decoder->top - stack >= CFF_MAX_OPERANDS ) + goto Stack_Overflow; + + } /* general operator processing */ + + } /* while ip < limit */ + + FT_TRACE4(( "..end..\n\n" )); + + Fail: + return error; + + MM_Error: + FT_TRACE4(( "cff_decoder_parse_charstrings:" + " invalid opcode found in top DICT charstring\n")); + return FT_THROW( Invalid_File_Format ); + + Syntax_Error: + FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" )); + return FT_THROW( Invalid_File_Format ); + + Stack_Underflow: + FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" )); + return FT_THROW( Too_Few_Arguments ); + + Stack_Overflow: + FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" )); + return FT_THROW( Stack_Overflow ); + } + +#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cff_decoder_init */ + /* */ + /* <Description> */ + /* Initializes a given glyph decoder. */ + /* */ + /* <InOut> */ + /* decoder :: A pointer to the glyph builder to initialize. */ + /* */ + /* <Input> */ + /* face :: The current face object. */ + /* */ + /* size :: The current size object. */ + /* */ + /* slot :: The current glyph object. */ + /* */ + /* hinting :: Whether hinting is active. */ + /* */ + /* hint_mode :: The hinting mode. */ + /* */ + FT_LOCAL_DEF( void ) + cff_decoder_init( CFF_Decoder* decoder, + TT_Face face, + CFF_Size size, + CFF_GlyphSlot slot, + FT_Bool hinting, + FT_Render_Mode hint_mode, + CFF_Decoder_Get_Glyph_Callback get_callback, + CFF_Decoder_Free_Glyph_Callback free_callback ) + { + CFF_Font cff = (CFF_Font)face->extra.data; + + + /* clear everything */ + FT_ZERO( decoder ); + + /* initialize builder */ + cff_builder_init( &decoder->builder, face, size, slot, hinting ); + + /* initialize Type2 decoder */ + decoder->cff = cff; + decoder->num_globals = cff->global_subrs_index.count; + decoder->globals = cff->global_subrs; + decoder->globals_bias = cff_compute_bias( + cff->top_font.font_dict.charstring_type, + decoder->num_globals ); + + decoder->hint_mode = hint_mode; + + decoder->get_glyph_callback = get_callback; + decoder->free_glyph_callback = free_callback; + } + + + /* this function is used to select the subfont */ + /* and the locals subrs array */ + FT_LOCAL_DEF( FT_Error ) + cff_decoder_prepare( CFF_Decoder* decoder, + CFF_Size size, + FT_UInt glyph_index ) + { + CFF_Builder *builder = &decoder->builder; + CFF_Font cff = (CFF_Font)builder->face->extra.data; + CFF_SubFont sub = &cff->top_font; + FT_Error error = FT_Err_Ok; + + FT_Service_CFFLoad cffload = (FT_Service_CFFLoad)cff->cffload; + + + /* manage CID fonts */ + if ( cff->num_subfonts ) + { + FT_Byte fd_index = cffload->fd_select_get( &cff->fd_select, + glyph_index ); + + + if ( fd_index >= cff->num_subfonts ) + { + FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + FT_TRACE3(( " in subfont %d:\n", fd_index )); + + sub = cff->subfonts[fd_index]; + + if ( builder->hints_funcs && size ) + { + FT_Size ftsize = FT_SIZE( size ); + CFF_Internal internal = (CFF_Internal)ftsize->internal->module_data; + + + /* for CFFs without subfonts, this value has already been set */ + builder->hints_globals = (void *)internal->subfonts[fd_index]; + } + } + + decoder->num_locals = sub->local_subrs_index.count; + decoder->locals = sub->local_subrs; + decoder->locals_bias = cff_compute_bias( + decoder->cff->top_font.font_dict.charstring_type, + decoder->num_locals ); + + decoder->glyph_width = sub->private_dict.default_width; + decoder->nominal_width = sub->private_dict.nominal_width; + + decoder->current_subfont = sub; + + Exit: + return error; + } + + +/* END */ diff --git a/src/3rdparty/freetype/src/psaux/cffdecode.h b/src/3rdparty/freetype/src/psaux/cffdecode.h new file mode 100644 index 0000000000..0d4f5fef63 --- /dev/null +++ b/src/3rdparty/freetype/src/psaux/cffdecode.h @@ -0,0 +1,64 @@ +/***************************************************************************/ +/* */ +/* cffdecode.h */ +/* */ +/* PostScript CFF (Type 2) decoding routines (specification). */ +/* */ +/* Copyright 2017-2018 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef CFFDECODE_H_ +#define CFFDECODE_H_ + + +#include <ft2build.h> +#include FT_INTERNAL_POSTSCRIPT_AUX_H + + +FT_BEGIN_HEADER + + FT_LOCAL( void ) + cff_decoder_init( CFF_Decoder* decoder, + TT_Face face, + CFF_Size size, + CFF_GlyphSlot slot, + FT_Bool hinting, + FT_Render_Mode hint_mode, + CFF_Decoder_Get_Glyph_Callback get_callback, + CFF_Decoder_Free_Glyph_Callback free_callback ); + + FT_LOCAL( FT_Error ) + cff_decoder_prepare( CFF_Decoder* decoder, + CFF_Size size, + FT_UInt glyph_index ); + + + FT_LOCAL( FT_Int ) + cff_lookup_glyph_by_stdcharcode( CFF_Font cff, + FT_Int charcode ); + + +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + FT_LOCAL( FT_Error ) + cff_decoder_parse_charstrings( CFF_Decoder* decoder, + FT_Byte* charstring_base, + FT_ULong charstring_len, + FT_Bool in_dict ); +#endif + + +FT_END_HEADER + +#endif + + +/* END */ diff --git a/src/3rdparty/freetype/src/psaux/module.mk b/src/3rdparty/freetype/src/psaux/module.mk index 1d90e14ce4..6584d075a2 100644 --- a/src/3rdparty/freetype/src/psaux/module.mk +++ b/src/3rdparty/freetype/src/psaux/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2015 by +# Copyright 1996-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/psaux/psarrst.c b/src/3rdparty/freetype/src/psaux/psarrst.c new file mode 100644 index 0000000000..a8780947f9 --- /dev/null +++ b/src/3rdparty/freetype/src/psaux/psarrst.c @@ -0,0 +1,241 @@ +/***************************************************************************/ +/* */ +/* psarrst.c */ +/* */ +/* Adobe's code for Array Stacks (body). */ +/* */ +/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#include "psft.h" +#include FT_INTERNAL_DEBUG_H + +#include "psglue.h" +#include "psarrst.h" + +#include "pserror.h" + + + /* + * CF2_ArrStack uses an error pointer, to enable shared errors. + * Shared errors are necessary when multiple objects allow the program + * to continue after detecting errors. Only the first error should be + * recorded. + */ + + FT_LOCAL_DEF( void ) + cf2_arrstack_init( CF2_ArrStack arrstack, + FT_Memory memory, + FT_Error* error, + size_t sizeItem ) + { + FT_ASSERT( arrstack ); + + /* initialize the structure */ + arrstack->memory = memory; + arrstack->error = error; + arrstack->sizeItem = sizeItem; + arrstack->allocated = 0; + arrstack->chunk = 10; /* chunks of 10 items */ + arrstack->count = 0; + arrstack->totalSize = 0; + arrstack->ptr = NULL; + } + + + FT_LOCAL_DEF( void ) + cf2_arrstack_finalize( CF2_ArrStack arrstack ) + { + FT_Memory memory = arrstack->memory; /* for FT_FREE */ + + + FT_ASSERT( arrstack ); + + arrstack->allocated = 0; + arrstack->count = 0; + arrstack->totalSize = 0; + + /* free the data buffer */ + FT_FREE( arrstack->ptr ); + } + + + /* allocate or reallocate the buffer size; */ + /* return false on memory error */ + static FT_Bool + cf2_arrstack_setNumElements( CF2_ArrStack arrstack, + size_t numElements ) + { + FT_ASSERT( arrstack ); + + { + FT_Error error = FT_Err_Ok; /* for FT_REALLOC */ + FT_Memory memory = arrstack->memory; /* for FT_REALLOC */ + + size_t newSize = numElements * arrstack->sizeItem; + + + if ( numElements > FT_LONG_MAX / arrstack->sizeItem ) + goto exit; + + + FT_ASSERT( newSize > 0 ); /* avoid realloc with zero size */ + + if ( !FT_REALLOC( arrstack->ptr, arrstack->totalSize, newSize ) ) + { + arrstack->allocated = numElements; + arrstack->totalSize = newSize; + + if ( arrstack->count > numElements ) + { + /* we truncated the list! */ + CF2_SET_ERROR( arrstack->error, Stack_Overflow ); + arrstack->count = numElements; + return FALSE; + } + + return TRUE; /* success */ + } + } + + exit: + /* if there's not already an error, store this one */ + CF2_SET_ERROR( arrstack->error, Out_Of_Memory ); + + return FALSE; + } + + + /* set the count, ensuring allocation is sufficient */ + FT_LOCAL_DEF( void ) + cf2_arrstack_setCount( CF2_ArrStack arrstack, + size_t numElements ) + { + FT_ASSERT( arrstack ); + + if ( numElements > arrstack->allocated ) + { + /* expand the allocation first */ + if ( !cf2_arrstack_setNumElements( arrstack, numElements ) ) + return; + } + + arrstack->count = numElements; + } + + + /* clear the count */ + FT_LOCAL_DEF( void ) + cf2_arrstack_clear( CF2_ArrStack arrstack ) + { + FT_ASSERT( arrstack ); + + arrstack->count = 0; + } + + + /* current number of items */ + FT_LOCAL_DEF( size_t ) + cf2_arrstack_size( const CF2_ArrStack arrstack ) + { + FT_ASSERT( arrstack ); + + return arrstack->count; + } + + + FT_LOCAL_DEF( void* ) + cf2_arrstack_getBuffer( const CF2_ArrStack arrstack ) + { + FT_ASSERT( arrstack ); + + return arrstack->ptr; + } + + + /* return pointer to the given element */ + FT_LOCAL_DEF( void* ) + cf2_arrstack_getPointer( const CF2_ArrStack arrstack, + size_t idx ) + { + void* newPtr; + + + FT_ASSERT( arrstack ); + + if ( idx >= arrstack->count ) + { + /* overflow */ + CF2_SET_ERROR( arrstack->error, Stack_Overflow ); + idx = 0; /* choose safe default */ + } + + newPtr = (FT_Byte*)arrstack->ptr + idx * arrstack->sizeItem; + + return newPtr; + } + + + /* push (append) an element at the end of the list; */ + /* return false on memory error */ + /* TODO: should there be a length param for extra checking? */ + FT_LOCAL_DEF( void ) + cf2_arrstack_push( CF2_ArrStack arrstack, + const void* ptr ) + { + FT_ASSERT( arrstack ); + + if ( arrstack->count == arrstack->allocated ) + { + /* grow the buffer by one chunk */ + if ( !cf2_arrstack_setNumElements( + arrstack, arrstack->allocated + arrstack->chunk ) ) + { + /* on error, ignore the push */ + return; + } + } + + FT_ASSERT( ptr ); + + { + size_t offset = arrstack->count * arrstack->sizeItem; + void* newPtr = (FT_Byte*)arrstack->ptr + offset; + + + FT_MEM_COPY( newPtr, ptr, arrstack->sizeItem ); + arrstack->count += 1; + } + } + + +/* END */ diff --git a/src/3rdparty/freetype/src/psaux/psarrst.h b/src/3rdparty/freetype/src/psaux/psarrst.h new file mode 100644 index 0000000000..b3568eb61f --- /dev/null +++ b/src/3rdparty/freetype/src/psaux/psarrst.h @@ -0,0 +1,100 @@ +/***************************************************************************/ +/* */ +/* psarrst.h */ +/* */ +/* Adobe's code for Array Stacks (specification). */ +/* */ +/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#ifndef PSARRST_H_ +#define PSARRST_H_ + + +#include "pserror.h" + + +FT_BEGIN_HEADER + + + /* need to define the struct here (not opaque) so it can be allocated by */ + /* clients */ + typedef struct CF2_ArrStackRec_ + { + FT_Memory memory; + FT_Error* error; + + size_t sizeItem; /* bytes per element */ + size_t allocated; /* items allocated */ + size_t chunk; /* allocation increment in items */ + size_t count; /* number of elements allocated */ + size_t totalSize; /* total bytes allocated */ + + void* ptr; /* ptr to data */ + + } CF2_ArrStackRec, *CF2_ArrStack; + + + FT_LOCAL( void ) + cf2_arrstack_init( CF2_ArrStack arrstack, + FT_Memory memory, + FT_Error* error, + size_t sizeItem ); + FT_LOCAL( void ) + cf2_arrstack_finalize( CF2_ArrStack arrstack ); + + FT_LOCAL( void ) + cf2_arrstack_setCount( CF2_ArrStack arrstack, + size_t numElements ); + FT_LOCAL( void ) + cf2_arrstack_clear( CF2_ArrStack arrstack ); + FT_LOCAL( size_t ) + cf2_arrstack_size( const CF2_ArrStack arrstack ); + + FT_LOCAL( void* ) + cf2_arrstack_getBuffer( const CF2_ArrStack arrstack ); + FT_LOCAL( void* ) + cf2_arrstack_getPointer( const CF2_ArrStack arrstack, + size_t idx ); + + FT_LOCAL( void ) + cf2_arrstack_push( CF2_ArrStack arrstack, + const void* ptr ); + + +FT_END_HEADER + + +#endif /* PSARRST_H_ */ + + +/* END */ diff --git a/src/3rdparty/freetype/src/psaux/psaux.c b/src/3rdparty/freetype/src/psaux/psaux.c index 7f1d9aa595..fb447fcdbb 100644 --- a/src/3rdparty/freetype/src/psaux/psaux.c +++ b/src/3rdparty/freetype/src/psaux/psaux.c @@ -4,7 +4,7 @@ /* */ /* FreeType auxiliary PostScript driver component (body only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,18 +17,25 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT - #include <ft2build.h> -#include "psobjs.c" -#include "psauxmod.c" -#include "t1decode.c" -#include "t1cmap.c" -#ifndef T1_CONFIG_OPTION_NO_AFM #include "afmparse.c" -#endif - +#include "psauxmod.c" #include "psconv.c" +#include "psobjs.c" +#include "t1cmap.c" +#include "t1decode.c" +#include "cffdecode.c" + +#include "psarrst.c" +#include "psblues.c" +#include "pserror.c" +#include "psfont.c" +#include "psft.c" +#include "pshints.c" +#include "psintrp.c" +#include "psread.c" +#include "psstack.c" /* END */ diff --git a/src/3rdparty/freetype/src/psaux/psauxerr.h b/src/3rdparty/freetype/src/psaux/psauxerr.h index 97712f0795..cc33fd2eea 100644 --- a/src/3rdparty/freetype/src/psaux/psauxerr.h +++ b/src/3rdparty/freetype/src/psaux/psauxerr.h @@ -4,7 +4,7 @@ /* */ /* PS auxiliary module error codes (specification only). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __PSAUXERR_H__ -#define __PSAUXERR_H__ +#ifndef PSAUXERR_H_ +#define PSAUXERR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX PSaux_Err_ @@ -36,7 +36,7 @@ #include FT_ERRORS_H -#endif /* __PSAUXERR_H__ */ +#endif /* PSAUXERR_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/psaux/psauxmod.c b/src/3rdparty/freetype/src/psaux/psauxmod.c index 06fcab0c4a..ee497085cc 100644 --- a/src/3rdparty/freetype/src/psaux/psauxmod.c +++ b/src/3rdparty/freetype/src/psaux/psauxmod.c @@ -4,7 +4,7 @@ /* */ /* FreeType auxiliary PostScript module implementation (body). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,6 +21,8 @@ #include "psobjs.h" #include "t1decode.h" #include "t1cmap.h" +#include "psft.h" +#include "cffdecode.h" #ifndef T1_CONFIG_OPTION_NO_AFM #include "afmparse.h" @@ -30,52 +32,69 @@ FT_CALLBACK_TABLE_DEF const PS_Table_FuncsRec ps_table_funcs = { - ps_table_new, - ps_table_done, - ps_table_add, - ps_table_release + ps_table_new, /* init */ + ps_table_done, /* done */ + ps_table_add, /* add */ + ps_table_release /* release */ }; FT_CALLBACK_TABLE_DEF const PS_Parser_FuncsRec ps_parser_funcs = { - ps_parser_init, - ps_parser_done, - ps_parser_skip_spaces, - ps_parser_skip_PS_token, - ps_parser_to_int, - ps_parser_to_fixed, - ps_parser_to_bytes, - ps_parser_to_coord_array, - ps_parser_to_fixed_array, - ps_parser_to_token, - ps_parser_to_token_array, - ps_parser_load_field, - ps_parser_load_field_table + ps_parser_init, /* init */ + ps_parser_done, /* done */ + + ps_parser_skip_spaces, /* skip_spaces */ + ps_parser_skip_PS_token, /* skip_PS_token */ + + ps_parser_to_int, /* to_int */ + ps_parser_to_fixed, /* to_fixed */ + ps_parser_to_bytes, /* to_bytes */ + ps_parser_to_coord_array, /* to_coord_array */ + ps_parser_to_fixed_array, /* to_fixed_array */ + ps_parser_to_token, /* to_token */ + ps_parser_to_token_array, /* to_token_array */ + + ps_parser_load_field, /* load_field */ + ps_parser_load_field_table /* load_field_table */ + }; + + + FT_CALLBACK_TABLE_DEF + const PS_Builder_FuncsRec ps_builder_funcs = + { + ps_builder_init, /* init */ + ps_builder_done /* done */ }; FT_CALLBACK_TABLE_DEF const T1_Builder_FuncsRec t1_builder_funcs = { - t1_builder_init, - t1_builder_done, - t1_builder_check_points, - t1_builder_add_point, - t1_builder_add_point1, - t1_builder_add_contour, - t1_builder_start_point, - t1_builder_close_contour + t1_builder_init, /* init */ + t1_builder_done, /* done */ + + t1_builder_check_points, /* check_points */ + t1_builder_add_point, /* add_point */ + t1_builder_add_point1, /* add_point1 */ + t1_builder_add_contour, /* add_contour */ + t1_builder_start_point, /* start_point */ + t1_builder_close_contour /* close_contour */ }; FT_CALLBACK_TABLE_DEF const T1_Decoder_FuncsRec t1_decoder_funcs = { - t1_decoder_init, - t1_decoder_done, - t1_decoder_parse_charstrings + t1_decoder_init, /* init */ + t1_decoder_done, /* done */ +#ifdef T1_CONFIG_OPTION_OLD_ENGINE + t1_decoder_parse_charstrings, /* parse_charstrings_old */ +#else + t1_decoder_parse_metrics, /* parse_metrics */ +#endif + cf2_decoder_parse_charstrings /* parse_charstrings */ }; @@ -83,9 +102,9 @@ FT_CALLBACK_TABLE_DEF const AFM_Parser_FuncsRec afm_parser_funcs = { - afm_parser_init, - afm_parser_done, - afm_parser_parse + afm_parser_init, /* init */ + afm_parser_done, /* done */ + afm_parser_parse /* parse */ }; #endif @@ -100,6 +119,34 @@ }; + FT_CALLBACK_TABLE_DEF + const CFF_Builder_FuncsRec cff_builder_funcs = + { + cff_builder_init, /* init */ + cff_builder_done, /* done */ + + cff_check_points, /* check_points */ + cff_builder_add_point, /* add_point */ + cff_builder_add_point1, /* add_point1 */ + cff_builder_add_contour, /* add_contour */ + cff_builder_start_point, /* start_point */ + cff_builder_close_contour /* close_contour */ + }; + + + FT_CALLBACK_TABLE_DEF + const CFF_Decoder_FuncsRec cff_decoder_funcs = + { + cff_decoder_init, /* init */ + cff_decoder_prepare, /* prepare */ + +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + cff_decoder_parse_charstrings, /* parse_charstrings_old */ +#endif + cf2_decoder_parse_charstrings /* parse_charstrings */ + }; + + static const PSAux_Interface psaux_interface = { @@ -108,6 +155,9 @@ &t1_builder_funcs, &t1_decoder_funcs, t1_decrypt, + cff_random, + ps_decoder_init, + t1_make_subfont, (const T1_CMap_ClassesRec*) &t1_cmap_classes, @@ -116,6 +166,8 @@ #else 0, #endif + + &cff_decoder_funcs, }; @@ -130,9 +182,9 @@ &psaux_interface, /* module-specific interface */ - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 + (FT_Module_Constructor)NULL, /* module_init */ + (FT_Module_Destructor) NULL, /* module_done */ + (FT_Module_Requester) NULL /* get_interface */ }; diff --git a/src/3rdparty/freetype/src/psaux/psauxmod.h b/src/3rdparty/freetype/src/psaux/psauxmod.h index ae6a8f9383..f30978f022 100644 --- a/src/3rdparty/freetype/src/psaux/psauxmod.h +++ b/src/3rdparty/freetype/src/psaux/psauxmod.h @@ -4,7 +4,7 @@ /* */ /* FreeType auxiliary PostScript module implementation (specification). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,13 +16,15 @@ /***************************************************************************/ -#ifndef __PSAUXMOD_H__ -#define __PSAUXMOD_H__ +#ifndef PSAUXMOD_H_ +#define PSAUXMOD_H_ #include <ft2build.h> #include FT_MODULE_H +#include FT_INTERNAL_POSTSCRIPT_AUX_H + FT_BEGIN_HEADER @@ -31,12 +33,19 @@ FT_BEGIN_HEADER #endif + FT_CALLBACK_TABLE + const CFF_Builder_FuncsRec cff_builder_funcs; + + FT_CALLBACK_TABLE + const PS_Builder_FuncsRec ps_builder_funcs; + + FT_EXPORT_VAR( const FT_Module_Class ) psaux_driver_class; FT_END_HEADER -#endif /* __PSAUXMOD_H__ */ +#endif /* PSAUXMOD_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/psaux/psblues.c b/src/3rdparty/freetype/src/psaux/psblues.c new file mode 100644 index 0000000000..ae39d03c77 --- /dev/null +++ b/src/3rdparty/freetype/src/psaux/psblues.c @@ -0,0 +1,582 @@ +/***************************************************************************/ +/* */ +/* psblues.c */ +/* */ +/* Adobe's code for handling Blue Zones (body). */ +/* */ +/* Copyright 2009-2014 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#include "psft.h" +#include FT_INTERNAL_DEBUG_H + +#include "psblues.h" +#include "pshints.h" +#include "psfont.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_cf2blues + + + /* + * For blue values, the FreeType parser produces an array of integers, + * while the Adobe CFF engine produces an array of fixed. + * Define a macro to convert FreeType to fixed. + */ +#define cf2_blueToFixed( x ) cf2_intToFixed( x ) + + + FT_LOCAL_DEF( void ) + cf2_blues_init( CF2_Blues blues, + CF2_Font font ) + { + /* pointer to parsed font object */ + PS_Decoder* decoder = font->decoder; + + CF2_Fixed zoneHeight; + CF2_Fixed maxZoneHeight = 0; + CF2_Fixed csUnitsPerPixel; + + size_t numBlueValues; + size_t numOtherBlues; + size_t numFamilyBlues; + size_t numFamilyOtherBlues; + + FT_Pos* blueValues; + FT_Pos* otherBlues; + FT_Pos* familyBlues; + FT_Pos* familyOtherBlues; + + size_t i; + CF2_Fixed emBoxBottom, emBoxTop; + +#if 0 + CF2_Int unitsPerEm = font->unitsPerEm; + + + if ( unitsPerEm == 0 ) + unitsPerEm = 1000; +#endif + + FT_ZERO( blues ); + blues->scale = font->innerTransform.d; + + cf2_getBlueMetrics( decoder, + &blues->blueScale, + &blues->blueShift, + &blues->blueFuzz ); + + cf2_getBlueValues( decoder, &numBlueValues, &blueValues ); + cf2_getOtherBlues( decoder, &numOtherBlues, &otherBlues ); + cf2_getFamilyBlues( decoder, &numFamilyBlues, &familyBlues ); + cf2_getFamilyOtherBlues( decoder, &numFamilyOtherBlues, &familyOtherBlues ); + + /* + * synthetic em box hint heuristic + * + * Apply this when ideographic dictionary (LanguageGroup 1) has no + * real alignment zones. Adobe tools generate dummy zones at -250 and + * 1100 for a 1000 unit em. Fonts with ICF-based alignment zones + * should not enable the heuristic. When the heuristic is enabled, + * the font's blue zones are ignored. + * + */ + + /* get em box from OS/2 typoAscender/Descender */ + /* TODO: FreeType does not parse these metrics. Skip them for now. */ +#if 0 + FCM_getHorizontalLineMetrics( &e, + font->font, + &ascender, + &descender, + &linegap ); + if ( ascender - descender == unitsPerEm ) + { + emBoxBottom = cf2_intToFixed( descender ); + emBoxTop = cf2_intToFixed( ascender ); + } + else +#endif + { + emBoxBottom = CF2_ICF_Bottom; + emBoxTop = CF2_ICF_Top; + } + + if ( cf2_getLanguageGroup( decoder ) == 1 && + ( numBlueValues == 0 || + ( numBlueValues == 4 && + cf2_blueToFixed( blueValues[0] ) < emBoxBottom && + cf2_blueToFixed( blueValues[1] ) < emBoxBottom && + cf2_blueToFixed( blueValues[2] ) > emBoxTop && + cf2_blueToFixed( blueValues[3] ) > emBoxTop ) ) ) + { + /* + * Construct hint edges suitable for synthetic ghost hints at top + * and bottom of em box. +-CF2_MIN_COUNTER allows for unhinted + * features above or below the last hinted edge. This also gives a + * net 1 pixel boost to the height of ideographic glyphs. + * + * Note: Adjust synthetic hints outward by epsilon (0x.0001) to + * avoid interference. E.g., some fonts have real hints at + * 880 and -120. + */ + + blues->emBoxBottomEdge.csCoord = emBoxBottom - CF2_FIXED_EPSILON; + blues->emBoxBottomEdge.dsCoord = cf2_fixedRound( + FT_MulFix( + blues->emBoxBottomEdge.csCoord, + blues->scale ) ) - + CF2_MIN_COUNTER; + blues->emBoxBottomEdge.scale = blues->scale; + blues->emBoxBottomEdge.flags = CF2_GhostBottom | + CF2_Locked | + CF2_Synthetic; + + blues->emBoxTopEdge.csCoord = emBoxTop + CF2_FIXED_EPSILON + + 2 * font->darkenY; + blues->emBoxTopEdge.dsCoord = cf2_fixedRound( + FT_MulFix( + blues->emBoxTopEdge.csCoord, + blues->scale ) ) + + CF2_MIN_COUNTER; + blues->emBoxTopEdge.scale = blues->scale; + blues->emBoxTopEdge.flags = CF2_GhostTop | + CF2_Locked | + CF2_Synthetic; + + blues->doEmBoxHints = TRUE; /* enable the heuristic */ + + return; + } + + /* copy `BlueValues' and `OtherBlues' to a combined array of top and */ + /* bottom zones */ + for ( i = 0; i < numBlueValues; i += 2 ) + { + blues->zone[blues->count].csBottomEdge = + cf2_blueToFixed( blueValues[i] ); + blues->zone[blues->count].csTopEdge = + cf2_blueToFixed( blueValues[i + 1] ); + + zoneHeight = SUB_INT32( blues->zone[blues->count].csTopEdge, + blues->zone[blues->count].csBottomEdge ); + + if ( zoneHeight < 0 ) + { + FT_TRACE4(( "cf2_blues_init: ignoring negative zone height\n" )); + continue; /* reject this zone */ + } + + if ( zoneHeight > maxZoneHeight ) + { + /* take maximum before darkening adjustment */ + /* so overshoot suppression point doesn't change */ + maxZoneHeight = zoneHeight; + } + + /* adjust both edges of top zone upward by twice darkening amount */ + if ( i != 0 ) + { + blues->zone[blues->count].csTopEdge += 2 * font->darkenY; + blues->zone[blues->count].csBottomEdge += 2 * font->darkenY; + } + + /* first `BlueValue' is bottom zone; others are top */ + if ( i == 0 ) + { + blues->zone[blues->count].bottomZone = + TRUE; + blues->zone[blues->count].csFlatEdge = + blues->zone[blues->count].csTopEdge; + } + else + { + blues->zone[blues->count].bottomZone = + FALSE; + blues->zone[blues->count].csFlatEdge = + blues->zone[blues->count].csBottomEdge; + } + + blues->count += 1; + } + + for ( i = 0; i < numOtherBlues; i += 2 ) + { + blues->zone[blues->count].csBottomEdge = + cf2_blueToFixed( otherBlues[i] ); + blues->zone[blues->count].csTopEdge = + cf2_blueToFixed( otherBlues[i + 1] ); + + zoneHeight = SUB_INT32( blues->zone[blues->count].csTopEdge, + blues->zone[blues->count].csBottomEdge ); + + if ( zoneHeight < 0 ) + { + FT_TRACE4(( "cf2_blues_init: ignoring negative zone height\n" )); + continue; /* reject this zone */ + } + + if ( zoneHeight > maxZoneHeight ) + { + /* take maximum before darkening adjustment */ + /* so overshoot suppression point doesn't change */ + maxZoneHeight = zoneHeight; + } + + /* Note: bottom zones are not adjusted for darkening amount */ + + /* all OtherBlues are bottom zone */ + blues->zone[blues->count].bottomZone = + TRUE; + blues->zone[blues->count].csFlatEdge = + blues->zone[blues->count].csTopEdge; + + blues->count += 1; + } + + /* Adjust for FamilyBlues */ + + /* Search for the nearest flat edge in `FamilyBlues' or */ + /* `FamilyOtherBlues'. According to the Black Book, any matching edge */ + /* must be within one device pixel */ + + csUnitsPerPixel = FT_DivFix( cf2_intToFixed( 1 ), blues->scale ); + + /* loop on all zones in this font */ + for ( i = 0; i < blues->count; i++ ) + { + size_t j; + CF2_Fixed minDiff; + CF2_Fixed flatFamilyEdge, diff; + /* value for this font */ + CF2_Fixed flatEdge = blues->zone[i].csFlatEdge; + + + if ( blues->zone[i].bottomZone ) + { + /* In a bottom zone, the top edge is the flat edge. */ + /* Search `FamilyOtherBlues' for bottom zones; look for closest */ + /* Family edge that is within the one pixel threshold. */ + + minDiff = CF2_FIXED_MAX; + + for ( j = 0; j < numFamilyOtherBlues; j += 2 ) + { + /* top edge */ + flatFamilyEdge = cf2_blueToFixed( familyOtherBlues[j + 1] ); + + diff = cf2_fixedAbs( SUB_INT32( flatEdge, flatFamilyEdge ) ); + + if ( diff < minDiff && diff < csUnitsPerPixel ) + { + blues->zone[i].csFlatEdge = flatFamilyEdge; + minDiff = diff; + + if ( diff == 0 ) + break; + } + } + + /* check the first member of FamilyBlues, which is a bottom zone */ + if ( numFamilyBlues >= 2 ) + { + /* top edge */ + flatFamilyEdge = cf2_blueToFixed( familyBlues[1] ); + + diff = cf2_fixedAbs( SUB_INT32( flatEdge, flatFamilyEdge ) ); + + if ( diff < minDiff && diff < csUnitsPerPixel ) + blues->zone[i].csFlatEdge = flatFamilyEdge; + } + } + else + { + /* In a top zone, the bottom edge is the flat edge. */ + /* Search `FamilyBlues' for top zones; skip first zone, which is a */ + /* bottom zone; look for closest Family edge that is within the */ + /* one pixel threshold */ + + minDiff = CF2_FIXED_MAX; + + for ( j = 2; j < numFamilyBlues; j += 2 ) + { + /* bottom edge */ + flatFamilyEdge = cf2_blueToFixed( familyBlues[j] ); + + /* adjust edges of top zone upward by twice darkening amount */ + flatFamilyEdge += 2 * font->darkenY; /* bottom edge */ + + diff = cf2_fixedAbs( SUB_INT32( flatEdge, flatFamilyEdge ) ); + + if ( diff < minDiff && diff < csUnitsPerPixel ) + { + blues->zone[i].csFlatEdge = flatFamilyEdge; + minDiff = diff; + + if ( diff == 0 ) + break; + } + } + } + } + + /* TODO: enforce separation of zones, including BlueFuzz */ + + /* Adjust BlueScale; similar to AdjustBlueScale() in coretype */ + /* `bcsetup.c'. */ + + if ( maxZoneHeight > 0 ) + { + if ( blues->blueScale > FT_DivFix( cf2_intToFixed( 1 ), + maxZoneHeight ) ) + { + /* clamp at maximum scale */ + blues->blueScale = FT_DivFix( cf2_intToFixed( 1 ), + maxZoneHeight ); + } + + /* + * TODO: Revisit the bug fix for 613448. The minimum scale + * requirement catches a number of library fonts. For + * example, with default BlueScale (.039625) and 0.4 minimum, + * the test below catches any font with maxZoneHeight < 10.1. + * There are library fonts ranging from 2 to 10 that get + * caught, including e.g., Eurostile LT Std Medium with + * maxZoneHeight of 6. + * + */ +#if 0 + if ( blueScale < .4 / maxZoneHeight ) + { + tetraphilia_assert( 0 ); + /* clamp at minimum scale, per bug 0613448 fix */ + blueScale = .4 / maxZoneHeight; + } +#endif + + } + + /* + * Suppress overshoot and boost blue zones at small sizes. Boost + * amount varies linearly from 0.5 pixel near 0 to 0 pixel at + * blueScale cutoff. + * Note: This boost amount is different from the coretype heuristic. + * + */ + + if ( blues->scale < blues->blueScale ) + { + blues->suppressOvershoot = TRUE; + + /* Change rounding threshold for `dsFlatEdge'. */ + /* Note: constant changed from 0.5 to 0.6 to avoid a problem with */ + /* 10ppem Arial */ + + blues->boost = cf2_doubleToFixed( .6 ) - + FT_MulDiv( cf2_doubleToFixed ( .6 ), + blues->scale, + blues->blueScale ); + if ( blues->boost > 0x7FFF ) + { + /* boost must remain less than 0.5, or baseline could go negative */ + blues->boost = 0x7FFF; + } + } + + /* boost and darkening have similar effects; don't do both */ + if ( font->stemDarkened ) + blues->boost = 0; + + /* set device space alignment for each zone; */ + /* apply boost amount before rounding flat edge */ + + for ( i = 0; i < blues->count; i++ ) + { + if ( blues->zone[i].bottomZone ) + blues->zone[i].dsFlatEdge = cf2_fixedRound( + FT_MulFix( + blues->zone[i].csFlatEdge, + blues->scale ) - + blues->boost ); + else + blues->zone[i].dsFlatEdge = cf2_fixedRound( + FT_MulFix( + blues->zone[i].csFlatEdge, + blues->scale ) + + blues->boost ); + } + } + + + /* + * Check whether `stemHint' is captured by one of the blue zones. + * + * Zero, one or both edges may be valid; only valid edges can be + * captured. For compatibility with CoolType, search top and bottom + * zones in the same pass (see `BlueLock'). If a hint is captured, + * return true and position the edge(s) in one of 3 ways: + * + * 1) If `BlueScale' suppresses overshoot, position the captured edge + * at the flat edge of the zone. + * 2) If overshoot is not suppressed and `BlueShift' requires + * overshoot, position the captured edge a minimum of 1 device pixel + * from the flat edge. + * 3) If overshoot is not suppressed or required, position the captured + * edge at the nearest device pixel. + * + */ + FT_LOCAL_DEF( FT_Bool ) + cf2_blues_capture( const CF2_Blues blues, + CF2_Hint bottomHintEdge, + CF2_Hint topHintEdge ) + { + /* TODO: validate? */ + CF2_Fixed csFuzz = blues->blueFuzz; + + /* new position of captured edge */ + CF2_Fixed dsNew; + + /* amount that hint is moved when positioned */ + CF2_Fixed dsMove = 0; + + FT_Bool captured = FALSE; + CF2_UInt i; + + + /* assert edge flags are consistent */ + FT_ASSERT( !cf2_hint_isTop( bottomHintEdge ) && + !cf2_hint_isBottom( topHintEdge ) ); + + /* TODO: search once without blue fuzz for compatibility with coretype? */ + for ( i = 0; i < blues->count; i++ ) + { + if ( blues->zone[i].bottomZone && + cf2_hint_isBottom( bottomHintEdge ) ) + { + if ( SUB_INT32( blues->zone[i].csBottomEdge, csFuzz ) <= + bottomHintEdge->csCoord && + bottomHintEdge->csCoord <= + ADD_INT32( blues->zone[i].csTopEdge, csFuzz ) ) + { + /* bottom edge captured by bottom zone */ + + if ( blues->suppressOvershoot ) + dsNew = blues->zone[i].dsFlatEdge; + + else if ( SUB_INT32( blues->zone[i].csTopEdge, + bottomHintEdge->csCoord ) >= + blues->blueShift ) + { + /* guarantee minimum of 1 pixel overshoot */ + dsNew = FT_MIN( + cf2_fixedRound( bottomHintEdge->dsCoord ), + blues->zone[i].dsFlatEdge - cf2_intToFixed( 1 ) ); + } + + else + { + /* simply round captured edge */ + dsNew = cf2_fixedRound( bottomHintEdge->dsCoord ); + } + + dsMove = SUB_INT32( dsNew, bottomHintEdge->dsCoord ); + captured = TRUE; + + break; + } + } + + if ( !blues->zone[i].bottomZone && cf2_hint_isTop( topHintEdge ) ) + { + if ( SUB_INT32( blues->zone[i].csBottomEdge, csFuzz ) <= + topHintEdge->csCoord && + topHintEdge->csCoord <= + ADD_INT32( blues->zone[i].csTopEdge, csFuzz ) ) + { + /* top edge captured by top zone */ + + if ( blues->suppressOvershoot ) + dsNew = blues->zone[i].dsFlatEdge; + + else if ( SUB_INT32( topHintEdge->csCoord, + blues->zone[i].csBottomEdge ) >= + blues->blueShift ) + { + /* guarantee minimum of 1 pixel overshoot */ + dsNew = FT_MAX( + cf2_fixedRound( topHintEdge->dsCoord ), + blues->zone[i].dsFlatEdge + cf2_intToFixed( 1 ) ); + } + + else + { + /* simply round captured edge */ + dsNew = cf2_fixedRound( topHintEdge->dsCoord ); + } + + dsMove = SUB_INT32( dsNew, topHintEdge->dsCoord ); + captured = TRUE; + + break; + } + } + } + + if ( captured ) + { + /* move both edges and flag them `locked' */ + if ( cf2_hint_isValid( bottomHintEdge ) ) + { + bottomHintEdge->dsCoord = ADD_INT32( bottomHintEdge->dsCoord, + dsMove ); + cf2_hint_lock( bottomHintEdge ); + } + + if ( cf2_hint_isValid( topHintEdge ) ) + { + topHintEdge->dsCoord = ADD_INT32( topHintEdge->dsCoord, dsMove ); + cf2_hint_lock( topHintEdge ); + } + } + + return captured; + } + + +/* END */ diff --git a/src/3rdparty/freetype/src/psaux/psblues.h b/src/3rdparty/freetype/src/psaux/psblues.h new file mode 100644 index 0000000000..25ef6849c7 --- /dev/null +++ b/src/3rdparty/freetype/src/psaux/psblues.h @@ -0,0 +1,185 @@ +/***************************************************************************/ +/* */ +/* psblues.h */ +/* */ +/* Adobe's code for handling Blue Zones (specification). */ +/* */ +/* Copyright 2009-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + + /* + * A `CF2_Blues' object stores the blue zones (horizontal alignment + * zones) of a font. These are specified in the CFF private dictionary + * by `BlueValues', `OtherBlues', `FamilyBlues', and `FamilyOtherBlues'. + * Each zone is defined by a top and bottom edge in character space. + * Further, each zone is either a top zone or a bottom zone, as recorded + * by `bottomZone'. + * + * The maximum number of `BlueValues' and `FamilyBlues' is 7 each. + * However, these are combined to produce a total of 7 zones. + * Similarly, the maximum number of `OtherBlues' and `FamilyOtherBlues' + * is 5 and these are combined to produce an additional 5 zones. + * + * Blue zones are used to `capture' hints and force them to a common + * alignment point. This alignment is recorded in device space in + * `dsFlatEdge'. Except for this value, a `CF2_Blues' object could be + * constructed independently of scaling. Construction may occur once + * the matrix is known. Other features implemented in the Capture + * method are overshoot suppression, overshoot enforcement, and Blue + * Boost. + * + * Capture is determined by `BlueValues' and `OtherBlues', but the + * alignment point may be adjusted to the scaled flat edge of + * `FamilyBlues' or `FamilyOtherBlues'. No alignment is done to the + * curved edge of a zone. + * + */ + + +#ifndef PSBLUES_H_ +#define PSBLUES_H_ + + +#include "psglue.h" + + +FT_BEGIN_HEADER + + + /* + * `CF2_Hint' is shared by `cf2hints.h' and + * `cf2blues.h', but `cf2blues.h' depends on + * `cf2hints.h', so define it here. Note: The typedef is in + * `cf2glue.h'. + * + */ + enum + { + CF2_GhostBottom = 0x1, /* a single bottom edge */ + CF2_GhostTop = 0x2, /* a single top edge */ + CF2_PairBottom = 0x4, /* the bottom edge of a stem hint */ + CF2_PairTop = 0x8, /* the top edge of a stem hint */ + CF2_Locked = 0x10, /* this edge has been aligned */ + /* by a blue zone */ + CF2_Synthetic = 0x20 /* this edge was synthesized */ + }; + + + /* + * Default value for OS/2 typoAscender/Descender when their difference + * is not equal to `unitsPerEm'. The default is based on -250 and 1100 + * in `CF2_Blues', assuming 1000 units per em here. + * + */ + enum + { + CF2_ICF_Top = cf2_intToFixed( 880 ), + CF2_ICF_Bottom = cf2_intToFixed( -120 ) + }; + + + /* + * Constant used for hint adjustment and for synthetic em box hint + * placement. + */ +#define CF2_MIN_COUNTER cf2_doubleToFixed( 0.5 ) + + + /* shared typedef is in cf2glue.h */ + struct CF2_HintRec_ + { + CF2_UInt flags; /* attributes of the edge */ + size_t index; /* index in original stem hint array */ + /* (if not synthetic) */ + CF2_Fixed csCoord; + CF2_Fixed dsCoord; + CF2_Fixed scale; + }; + + + typedef struct CF2_BlueRec_ + { + CF2_Fixed csBottomEdge; + CF2_Fixed csTopEdge; + CF2_Fixed csFlatEdge; /* may be from either local or Family zones */ + CF2_Fixed dsFlatEdge; /* top edge of bottom zone or bottom edge */ + /* of top zone (rounded) */ + FT_Bool bottomZone; + + } CF2_BlueRec; + + + /* max total blue zones is 12 */ + enum + { + CF2_MAX_BLUES = 7, + CF2_MAX_OTHERBLUES = 5 + }; + + + typedef struct CF2_BluesRec_ + { + CF2_Fixed scale; + CF2_UInt count; + FT_Bool suppressOvershoot; + FT_Bool doEmBoxHints; + + CF2_Fixed blueScale; + CF2_Fixed blueShift; + CF2_Fixed blueFuzz; + + CF2_Fixed boost; + + CF2_HintRec emBoxTopEdge; + CF2_HintRec emBoxBottomEdge; + + CF2_BlueRec zone[CF2_MAX_BLUES + CF2_MAX_OTHERBLUES]; + + } CF2_BluesRec, *CF2_Blues; + + + FT_LOCAL( void ) + cf2_blues_init( CF2_Blues blues, + CF2_Font font ); + FT_LOCAL( FT_Bool ) + cf2_blues_capture( const CF2_Blues blues, + CF2_Hint bottomHintEdge, + CF2_Hint topHintEdge ); + + +FT_END_HEADER + + +#endif /* PSBLUES_H_ */ + + +/* END */ diff --git a/src/3rdparty/freetype/src/psaux/psconv.c b/src/3rdparty/freetype/src/psaux/psconv.c index aca741204f..a03385000d 100644 --- a/src/3rdparty/freetype/src/psaux/psconv.c +++ b/src/3rdparty/freetype/src/psaux/psconv.c @@ -4,7 +4,7 @@ /* */ /* Some convenience conversions (body). */ /* */ -/* Copyright 2006-2015 by */ +/* Copyright 2006-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -111,6 +111,10 @@ p++; if ( p == limit ) goto Bad; + + /* only a single sign is allowed */ + if ( *p == '-' || *p == '+' ) + return 0; } num_limit = 0x7FFFFFFFL / base; @@ -215,6 +219,10 @@ p++; if ( p == limit ) goto Bad; + + /* only a single sign is allowed */ + if ( *p == '-' || *p == '+' ) + return 0; } /* read the integer part */ diff --git a/src/3rdparty/freetype/src/psaux/psconv.h b/src/3rdparty/freetype/src/psaux/psconv.h index 10f1ff7fb1..d643ffcfc2 100644 --- a/src/3rdparty/freetype/src/psaux/psconv.h +++ b/src/3rdparty/freetype/src/psaux/psconv.h @@ -4,7 +4,7 @@ /* */ /* Some convenience conversions (specification). */ /* */ -/* Copyright 2006-2015 by */ +/* Copyright 2006-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSCONV_H__ -#define __PSCONV_H__ +#ifndef PSCONV_H_ +#define PSCONV_H_ #include <ft2build.h> @@ -65,7 +65,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSCONV_H__ */ +#endif /* PSCONV_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/psaux/pserror.c b/src/3rdparty/freetype/src/psaux/pserror.c new file mode 100644 index 0000000000..9169e5222d --- /dev/null +++ b/src/3rdparty/freetype/src/psaux/pserror.c @@ -0,0 +1,52 @@ +/***************************************************************************/ +/* */ +/* pserror.c */ +/* */ +/* Adobe's code for error handling (body). */ +/* */ +/* Copyright 2006-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#include "psft.h" +#include "pserror.h" + + + FT_LOCAL_DEF( void ) + cf2_setError( FT_Error* error, + FT_Error value ) + { + if ( error && !*error ) + *error = value; + } + + +/* END */ diff --git a/src/3rdparty/freetype/src/psaux/pserror.h b/src/3rdparty/freetype/src/psaux/pserror.h new file mode 100644 index 0000000000..13d52062bf --- /dev/null +++ b/src/3rdparty/freetype/src/psaux/pserror.h @@ -0,0 +1,119 @@ +/***************************************************************************/ +/* */ +/* pserror.h */ +/* */ +/* Adobe's code for error handling (specification). */ +/* */ +/* Copyright 2006-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#ifndef PSERROR_H_ +#define PSERROR_H_ + + +#include FT_MODULE_ERRORS_H + +#undef FTERRORS_H_ + +#undef FT_ERR_PREFIX +#define FT_ERR_PREFIX CF2_Err_ +#define FT_ERR_BASE FT_Mod_Err_CF2 + + +#include FT_ERRORS_H +#include "psft.h" + + +FT_BEGIN_HEADER + + + /* + * A poor-man error facility. + * + * This code being written in vanilla C, doesn't have the luxury of a + * language-supported exception mechanism such as the one available in + * Java. Instead, we are stuck with using error codes that must be + * carefully managed and preserved. However, it is convenient for us to + * model our error mechanism on a Java-like exception mechanism. + * When we assign an error code we are thus `throwing' an error. + * + * The preservation of an error code is done by coding convention. + * Upon a function call if the error code is anything other than + * `FT_Err_Ok', which is guaranteed to be zero, we + * will return without altering that error. This will allow the + * error to propagate and be handled at the appropriate location in + * the code. + * + * This allows a style of code where the error code is initialized + * up front and a block of calls are made with the error code only + * being checked after the block. If a new error occurs, the original + * error will be preserved and a functional no-op should result in any + * subsequent function that has an initial error code not equal to + * `FT_Err_Ok'. + * + * Errors are encoded by calling the `FT_THROW' macro. For example, + * + * { + * FT_Error e; + * + * + * ... + * e = FT_THROW( Out_Of_Memory ); + * } + * + */ + + + /* Set error code to a particular value. */ + FT_LOCAL( void ) + cf2_setError( FT_Error* error, + FT_Error value ); + + + /* + * A macro that conditionally sets an error code. + * + * This macro will first check whether `error' is set; + * if not, it will set it to `e'. + * + */ +#define CF2_SET_ERROR( error, e ) \ + cf2_setError( error, FT_THROW( e ) ) + + +FT_END_HEADER + + +#endif /* PSERROR_H_ */ + + +/* END */ diff --git a/src/3rdparty/freetype/src/psaux/psfixed.h b/src/3rdparty/freetype/src/psaux/psfixed.h new file mode 100644 index 0000000000..219589e7fc --- /dev/null +++ b/src/3rdparty/freetype/src/psaux/psfixed.h @@ -0,0 +1,95 @@ +/***************************************************************************/ +/* */ +/* psfixed.h */ +/* */ +/* Adobe's code for Fixed Point Mathematics (specification only). */ +/* */ +/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#ifndef PSFIXED_H_ +#define PSFIXED_H_ + + +FT_BEGIN_HEADER + + + /* rasterizer integer and fixed point arithmetic must be 32-bit */ + +#define CF2_Fixed CF2_F16Dot16 + typedef FT_Int32 CF2_Frac; /* 2.30 fixed point */ + + +#define CF2_FIXED_MAX ( (CF2_Fixed)0x7FFFFFFFL ) +#define CF2_FIXED_MIN ( (CF2_Fixed)0x80000000L ) +#define CF2_FIXED_ONE ( (CF2_Fixed)0x10000L ) +#define CF2_FIXED_EPSILON ( (CF2_Fixed)0x0001 ) + + /* in C 89, left and right shift of negative numbers is */ + /* implementation specific behaviour in the general case */ + +#define cf2_intToFixed( i ) \ + ( (CF2_Fixed)( (FT_UInt32)(i) << 16 ) ) +#define cf2_fixedToInt( x ) \ + ( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) ) +#define cf2_fixedRound( x ) \ + ( (CF2_Fixed)( ( (FT_UInt32)(x) + 0x8000U ) & 0xFFFF0000UL ) ) +#define cf2_doubleToFixed( f ) \ + ( (CF2_Fixed)( (f) * 65536.0 + 0.5 ) ) +#define cf2_fixedAbs( x ) \ + ( (x) < 0 ? NEG_INT32( x ) : (x) ) +#define cf2_fixedFloor( x ) \ + ( (CF2_Fixed)( (FT_UInt32)(x) & 0xFFFF0000UL ) ) +#define cf2_fixedFraction( x ) \ + ( (x) - cf2_fixedFloor( x ) ) +#define cf2_fracToFixed( x ) \ + ( (x) < 0 ? -( ( -(x) + 0x2000 ) >> 14 ) \ + : ( ( (x) + 0x2000 ) >> 14 ) ) + + + /* signed numeric types */ + typedef enum CF2_NumberType_ + { + CF2_NumberFixed, /* 16.16 */ + CF2_NumberFrac, /* 2.30 */ + CF2_NumberInt /* 32.0 */ + + } CF2_NumberType; + + +FT_END_HEADER + + +#endif /* PSFIXED_H_ */ + + +/* END */ diff --git a/src/3rdparty/freetype/src/psaux/psfont.c b/src/3rdparty/freetype/src/psaux/psfont.c new file mode 100644 index 0000000000..dde67a739d --- /dev/null +++ b/src/3rdparty/freetype/src/psaux/psfont.c @@ -0,0 +1,567 @@ +/***************************************************************************/ +/* */ +/* psfont.c */ +/* */ +/* Adobe's code for font instances (body). */ +/* */ +/* Copyright 2007-2014 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#include <ft2build.h> +#include FT_INTERNAL_CALC_H + +#include "psft.h" + +#include "psglue.h" +#include "psfont.h" +#include "pserror.h" +#include "psintrp.h" + + + /* Compute a stem darkening amount in character space. */ + static void + cf2_computeDarkening( CF2_Fixed emRatio, + CF2_Fixed ppem, + CF2_Fixed stemWidth, + CF2_Fixed* darkenAmount, + CF2_Fixed boldenAmount, + FT_Bool stemDarkened, + FT_Int* darkenParams ) + { + /* + * Total darkening amount is computed in 1000 unit character space + * using the modified 5 part curve as Adobe's Avalon rasterizer. + * The darkening amount is smaller for thicker stems. + * It becomes zero when the stem is thicker than 2.333 pixels. + * + * By default, we use + * + * darkenAmount = 0.4 pixels if scaledStem <= 0.5 pixels, + * darkenAmount = 0.275 pixels if 1 <= scaledStem <= 1.667 pixels, + * darkenAmount = 0 pixel if scaledStem >= 2.333 pixels, + * + * and piecewise linear in-between: + * + * + * darkening + * ^ + * | + * | (x1,y1) + * |--------+ + * | \ + * | \ + * | \ (x3,y3) + * | +----------+ + * | (x2,y2) \ + * | \ + * | \ + * | +----------------- + * | (x4,y4) + * +---------------------------------------------> stem + * thickness + * + * + * This corresponds to the following values for the + * `darkening-parameters' property: + * + * (x1, y1) = (500, 400) + * (x2, y2) = (1000, 275) + * (x3, y3) = (1667, 275) + * (x4, y4) = (2333, 0) + * + */ + + /* Internal calculations are done in units per thousand for */ + /* convenience. The x axis is scaled stem width in */ + /* thousandths of a pixel. That is, 1000 is 1 pixel. */ + /* The y axis is darkening amount in thousandths of a pixel.*/ + /* In the code, below, dividing by ppem and */ + /* adjusting for emRatio converts darkenAmount to character */ + /* space (font units). */ + CF2_Fixed stemWidthPer1000, scaledStem; + FT_Int logBase2; + + + *darkenAmount = 0; + + if ( boldenAmount == 0 && !stemDarkened ) + return; + + /* protect against range problems and divide by zero */ + if ( emRatio < cf2_doubleToFixed( .01 ) ) + return; + + if ( stemDarkened ) + { + FT_Int x1 = darkenParams[0]; + FT_Int y1 = darkenParams[1]; + FT_Int x2 = darkenParams[2]; + FT_Int y2 = darkenParams[3]; + FT_Int x3 = darkenParams[4]; + FT_Int y3 = darkenParams[5]; + FT_Int x4 = darkenParams[6]; + FT_Int y4 = darkenParams[7]; + + + /* convert from true character space to 1000 unit character space; */ + /* add synthetic emboldening effect */ + + /* `stemWidthPer1000' will not overflow for a legitimate font */ + + stemWidthPer1000 = FT_MulFix( stemWidth + boldenAmount, emRatio ); + + /* `scaledStem' can easily overflow, so we must clamp its maximum */ + /* value; the test doesn't need to be precise, but must be */ + /* conservative. The clamp value (default 2333) where */ + /* `darkenAmount' is zero is well below the overflow value of */ + /* 32767. */ + /* */ + /* FT_MSB computes the integer part of the base 2 logarithm. The */ + /* number of bits for the product is 1 or 2 more than the sum of */ + /* logarithms; remembering that the 16 lowest bits of the fraction */ + /* are dropped this is correct to within a factor of almost 4. */ + /* For example, 0x80.0000 * 0x80.0000 = 0x4000.0000 is 23+23 and */ + /* is flagged as possible overflow because 0xFF.FFFF * 0xFF.FFFF = */ + /* 0xFFFF.FE00 is also 23+23. */ + + logBase2 = FT_MSB( (FT_UInt32)stemWidthPer1000 ) + + FT_MSB( (FT_UInt32)ppem ); + + if ( logBase2 >= 46 ) + /* possible overflow */ + scaledStem = cf2_intToFixed( x4 ); + else + scaledStem = FT_MulFix( stemWidthPer1000, ppem ); + + /* now apply the darkening parameters */ + + if ( scaledStem < cf2_intToFixed( x1 ) ) + *darkenAmount = FT_DivFix( cf2_intToFixed( y1 ), ppem ); + + else if ( scaledStem < cf2_intToFixed( x2 ) ) + { + FT_Int xdelta = x2 - x1; + FT_Int ydelta = y2 - y1; + FT_Int x = stemWidthPer1000 - + FT_DivFix( cf2_intToFixed( x1 ), ppem ); + + + if ( !xdelta ) + goto Try_x3; + + *darkenAmount = FT_MulDiv( x, ydelta, xdelta ) + + FT_DivFix( cf2_intToFixed( y1 ), ppem ); + } + + else if ( scaledStem < cf2_intToFixed( x3 ) ) + { + Try_x3: + { + FT_Int xdelta = x3 - x2; + FT_Int ydelta = y3 - y2; + FT_Int x = stemWidthPer1000 - + FT_DivFix( cf2_intToFixed( x2 ), ppem ); + + + if ( !xdelta ) + goto Try_x4; + + *darkenAmount = FT_MulDiv( x, ydelta, xdelta ) + + FT_DivFix( cf2_intToFixed( y2 ), ppem ); + } + } + + else if ( scaledStem < cf2_intToFixed( x4 ) ) + { + Try_x4: + { + FT_Int xdelta = x4 - x3; + FT_Int ydelta = y4 - y3; + FT_Int x = stemWidthPer1000 - + FT_DivFix( cf2_intToFixed( x3 ), ppem ); + + + if ( !xdelta ) + goto Use_y4; + + *darkenAmount = FT_MulDiv( x, ydelta, xdelta ) + + FT_DivFix( cf2_intToFixed( y3 ), ppem ); + } + } + + else + { + Use_y4: + *darkenAmount = FT_DivFix( cf2_intToFixed( y4 ), ppem ); + } + + /* use half the amount on each side and convert back to true */ + /* character space */ + *darkenAmount = FT_DivFix( *darkenAmount, 2 * emRatio ); + } + + /* add synthetic emboldening effect in character space */ + *darkenAmount += boldenAmount / 2; + } + + + /* set up values for the current FontDict and matrix; */ + /* called for each glyph to be rendered */ + + /* caller's transform is adjusted for subpixel positioning */ + static void + cf2_font_setup( CF2_Font font, + const CF2_Matrix* transform ) + { + /* pointer to parsed font object */ + PS_Decoder* decoder = font->decoder; + + FT_Bool needExtraSetup = FALSE; + + CFF_VStoreRec* vstore; + FT_Bool hasVariations = FALSE; + + /* character space units */ + CF2_Fixed boldenX = font->syntheticEmboldeningAmountX; + CF2_Fixed boldenY = font->syntheticEmboldeningAmountY; + + CFF_SubFont subFont; + CF2_Fixed ppem; + + CF2_UInt lenNormalizedV = 0; + FT_Fixed* normalizedV = NULL; + + /* clear previous error */ + font->error = FT_Err_Ok; + + /* if a CID fontDict has changed, we need to recompute some cached */ + /* data */ + subFont = cf2_getSubfont( decoder ); + if ( font->lastSubfont != subFont ) + { + font->lastSubfont = subFont; + needExtraSetup = TRUE; + } + + if ( !font->isT1 ) + { + FT_Service_CFFLoad cffload = (FT_Service_CFFLoad)font->cffload; + + + /* check for variation vectors */ + vstore = cf2_getVStore( decoder ); + hasVariations = ( vstore->dataCount != 0 ); + + if ( hasVariations ) + { +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + /* check whether Private DICT in this subfont needs to be reparsed */ + font->error = cf2_getNormalizedVector( decoder, + &lenNormalizedV, + &normalizedV ); + if ( font->error ) + return; + + if ( cffload->blend_check_vector( &subFont->blend, + subFont->private_dict.vsindex, + lenNormalizedV, + normalizedV ) ) + { + /* blend has changed, reparse */ + cffload->load_private_dict( decoder->cff, + subFont, + lenNormalizedV, + normalizedV ); + needExtraSetup = TRUE; + } +#endif + + /* copy from subfont */ + font->blend.font = subFont->blend.font; + + /* clear state of charstring blend */ + font->blend.usedBV = FALSE; + + /* initialize value for charstring */ + font->vsindex = subFont->private_dict.vsindex; + + /* store vector inputs for blends in charstring */ + font->lenNDV = lenNormalizedV; + font->NDV = normalizedV; + } + } + + /* if ppem has changed, we need to recompute some cached data */ + /* note: because of CID font matrix concatenation, ppem and transform */ + /* do not necessarily track. */ + ppem = cf2_getPpemY( decoder ); + if ( font->ppem != ppem ) + { + font->ppem = ppem; + needExtraSetup = TRUE; + } + + /* copy hinted flag on each call */ + font->hinted = (FT_Bool)( font->renderingFlags & CF2_FlagsHinted ); + + /* determine if transform has changed; */ + /* include Fontmatrix but ignore translation */ + if ( ft_memcmp( transform, + &font->currentTransform, + 4 * sizeof ( CF2_Fixed ) ) != 0 ) + { + /* save `key' information for `cache of one' matrix data; */ + /* save client transform, without the translation */ + font->currentTransform = *transform; + font->currentTransform.tx = + font->currentTransform.ty = cf2_intToFixed( 0 ); + + /* TODO: FreeType transform is simple scalar; for now, use identity */ + /* for outer */ + font->innerTransform = *transform; + font->outerTransform.a = + font->outerTransform.d = cf2_intToFixed( 1 ); + font->outerTransform.b = + font->outerTransform.c = cf2_intToFixed( 0 ); + + needExtraSetup = TRUE; + } + + /* + * font->darkened is set to true if there is a stem darkening request or + * the font is synthetic emboldened. + * font->darkened controls whether to adjust blue zones, winding order, + * and hinting. + * + */ + if ( font->stemDarkened != ( font->renderingFlags & CF2_FlagsDarkened ) ) + { + font->stemDarkened = + (FT_Bool)( font->renderingFlags & CF2_FlagsDarkened ); + + /* blue zones depend on darkened flag */ + needExtraSetup = TRUE; + } + + /* recompute variables that are dependent on transform or FontDict or */ + /* darken flag */ + if ( needExtraSetup ) + { + /* StdVW is found in the private dictionary; */ + /* recompute darkening amounts whenever private dictionary or */ + /* transform change */ + /* Note: a rendering flag turns darkening on or off, so we want to */ + /* store the `on' amounts; */ + /* darkening amount is computed in character space */ + /* TODO: testing size-dependent darkening here; */ + /* what to do for rotations? */ + + CF2_Fixed emRatio; + CF2_Fixed stdHW; + CF2_Int unitsPerEm = font->unitsPerEm; + + + if ( unitsPerEm == 0 ) + unitsPerEm = 1000; + + ppem = FT_MAX( cf2_intToFixed( 4 ), + font->ppem ); /* use minimum ppem of 4 */ + +#if 0 + /* since vstem is measured in the x-direction, we use the `a' member */ + /* of the fontMatrix */ + emRatio = cf2_fixedFracMul( cf2_intToFixed( 1000 ), fontMatrix->a ); +#endif + + /* Freetype does not preserve the fontMatrix when parsing; use */ + /* unitsPerEm instead. */ + /* TODO: check precision of this */ + emRatio = cf2_intToFixed( 1000 ) / unitsPerEm; + font->stdVW = cf2_getStdVW( decoder ); + + if ( font->stdVW <= 0 ) + font->stdVW = FT_DivFix( cf2_intToFixed( 75 ), emRatio ); + + if ( boldenX > 0 ) + { + /* Ensure that boldenX is at least 1 pixel for synthetic bold font */ + /* (similar to what Avalon does) */ + boldenX = FT_MAX( boldenX, + FT_DivFix( cf2_intToFixed( unitsPerEm ), ppem ) ); + + /* Synthetic emboldening adds at least 1 pixel to darkenX, while */ + /* stem darkening adds at most half pixel. Since the purpose of */ + /* stem darkening (readability at small sizes) is met with */ + /* synthetic emboldening, no need to add stem darkening for a */ + /* synthetic bold font. */ + cf2_computeDarkening( emRatio, + ppem, + font->stdVW, + &font->darkenX, + boldenX, + FALSE, + font->darkenParams ); + } + else + cf2_computeDarkening( emRatio, + ppem, + font->stdVW, + &font->darkenX, + 0, + font->stemDarkened, + font->darkenParams ); + +#if 0 + /* since hstem is measured in the y-direction, we use the `d' member */ + /* of the fontMatrix */ + /* TODO: use the same units per em as above; check this */ + emRatio = cf2_fixedFracMul( cf2_intToFixed( 1000 ), fontMatrix->d ); +#endif + + /* set the default stem width, because it must be the same for all */ + /* family members; */ + /* choose a constant for StdHW that depends on font contrast */ + stdHW = cf2_getStdHW( decoder ); + + if ( stdHW > 0 && font->stdVW > MUL_INT32( 2, stdHW ) ) + font->stdHW = FT_DivFix( cf2_intToFixed( 75 ), emRatio ); + else + { + /* low contrast font gets less hstem darkening */ + font->stdHW = FT_DivFix( cf2_intToFixed( 110 ), emRatio ); + } + + cf2_computeDarkening( emRatio, + ppem, + font->stdHW, + &font->darkenY, + boldenY, + font->stemDarkened, + font->darkenParams ); + + if ( font->darkenX != 0 || font->darkenY != 0 ) + font->darkened = TRUE; + else + font->darkened = FALSE; + + font->reverseWinding = FALSE; /* initial expectation is CCW */ + + /* compute blue zones for this instance */ + cf2_blues_init( &font->blues, font ); + + } /* needExtraSetup */ + } + + + /* equivalent to AdobeGetOutline */ + FT_LOCAL_DEF( FT_Error ) + cf2_getGlyphOutline( CF2_Font font, + CF2_Buffer charstring, + const CF2_Matrix* transform, + CF2_F16Dot16* glyphWidth ) + { + FT_Error lastError = FT_Err_Ok; + + FT_Vector translation; + +#if 0 + FT_Vector advancePoint; +#endif + + CF2_Fixed advWidth = 0; + FT_Bool needWinding; + + + /* Note: use both integer and fraction for outlines. This allows bbox */ + /* to come out directly. */ + + translation.x = transform->tx; + translation.y = transform->ty; + + /* set up values based on transform */ + cf2_font_setup( font, transform ); + if ( font->error ) + goto exit; /* setup encountered an error */ + + /* reset darken direction */ + font->reverseWinding = FALSE; + + /* winding order only affects darkening */ + needWinding = font->darkened; + + while ( 1 ) + { + /* reset output buffer */ + cf2_outline_reset( &font->outline ); + + /* build the outline, passing the full translation */ + cf2_interpT2CharString( font, + charstring, + (CF2_OutlineCallbacks)&font->outline, + &translation, + FALSE, + 0, + 0, + &advWidth ); + + if ( font->error ) + goto exit; + + if ( !needWinding ) + break; + + /* check winding order */ + if ( font->outline.root.windingMomentum >= 0 ) /* CFF is CCW */ + break; + + /* invert darkening and render again */ + /* TODO: this should be a parameter to getOutline-computeOffset */ + font->reverseWinding = TRUE; + + needWinding = FALSE; /* exit after next iteration */ + } + + /* finish storing client outline */ + cf2_outline_close( &font->outline ); + + exit: + /* FreeType just wants the advance width; there is no translation */ + *glyphWidth = advWidth; + + /* free resources and collect errors from objects we've used */ + cf2_setError( &font->error, lastError ); + + return font->error; + } + + +/* END */ diff --git a/src/3rdparty/freetype/src/psaux/psfont.h b/src/3rdparty/freetype/src/psaux/psfont.h new file mode 100644 index 0000000000..e611ac4bdc --- /dev/null +++ b/src/3rdparty/freetype/src/psaux/psfont.h @@ -0,0 +1,134 @@ +/***************************************************************************/ +/* */ +/* psfont.h */ +/* */ +/* Adobe's code for font instances (specification). */ +/* */ +/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#ifndef PSFONT_H_ +#define PSFONT_H_ + + +#include FT_SERVICE_CFF_TABLE_LOAD_H + +#include "psft.h" +#include "psblues.h" + + +FT_BEGIN_HEADER + + +#define CF2_OPERAND_STACK_SIZE 48 +#define CF2_MAX_SUBR 16 /* maximum subroutine nesting; */ + /* only 10 are allowed but there exist */ + /* fonts like `HiraKakuProN-W3.ttf' */ + /* (Hiragino Kaku Gothic ProN W3; */ + /* 8.2d6e1; 2014-12-19) that exceed */ + /* this limit */ +#define CF2_STORAGE_SIZE 32 + + + /* typedef is in `cf2glue.h' */ + struct CF2_FontRec_ + { + FT_Memory memory; + FT_Error error; /* shared error for this instance */ + + FT_Bool isT1; + FT_Bool isCFF2; + CF2_RenderingFlags renderingFlags; + + /* variables that depend on Transform: */ + /* the following have zero translation; */ + /* inner * outer = font * original */ + + CF2_Matrix currentTransform; /* original client matrix */ + CF2_Matrix innerTransform; /* for hinting; erect, scaled */ + CF2_Matrix outerTransform; /* post hinting; includes rotations */ + CF2_Fixed ppem; /* transform-dependent */ + + /* variation data */ + CFF_BlendRec blend; /* cached charstring blend vector */ + CF2_UInt vsindex; /* current vsindex */ + CF2_UInt lenNDV; /* current length NDV or zero */ + FT_Fixed* NDV; /* ptr to current NDV or NULL */ + + CF2_Int unitsPerEm; + + CF2_Fixed syntheticEmboldeningAmountX; /* character space units */ + CF2_Fixed syntheticEmboldeningAmountY; /* character space units */ + + /* FreeType related members */ + CF2_OutlineRec outline; /* freetype glyph outline functions */ + PS_Decoder* decoder; + CFF_SubFont lastSubfont; /* FreeType parsed data; */ + /* top font or subfont */ + + /* these flags can vary from one call to the next */ + FT_Bool hinted; + FT_Bool darkened; /* true if stemDarkened or synthetic bold */ + /* i.e. darkenX != 0 || darkenY != 0 */ + FT_Bool stemDarkened; + + FT_Int darkenParams[8]; /* 1000 unit character space */ + + /* variables that depend on both FontDict and Transform */ + CF2_Fixed stdVW; /* in character space; depends on dict entry */ + CF2_Fixed stdHW; /* in character space; depends on dict entry */ + CF2_Fixed darkenX; /* character space units */ + CF2_Fixed darkenY; /* depends on transform */ + /* and private dict (StdVW) */ + FT_Bool reverseWinding; /* darken assuming */ + /* counterclockwise winding */ + + CF2_BluesRec blues; /* computed zone data */ + + FT_Service_CFFLoad cffload; /* pointer to cff functions */ + }; + + + FT_LOCAL( FT_Error ) + cf2_getGlyphOutline( CF2_Font font, + CF2_Buffer charstring, + const CF2_Matrix* transform, + CF2_F16Dot16* glyphWidth ); + + +FT_END_HEADER + + +#endif /* PSFONT_H_ */ + + +/* END */ diff --git a/src/3rdparty/freetype/src/psaux/psft.c b/src/3rdparty/freetype/src/psaux/psft.c new file mode 100644 index 0000000000..1f750174a1 --- /dev/null +++ b/src/3rdparty/freetype/src/psaux/psft.c @@ -0,0 +1,890 @@ +/***************************************************************************/ +/* */ +/* psft.c */ +/* */ +/* FreeType Glue Component to Adobe's Interpreter (body). */ +/* */ +/* Copyright 2013-2014 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#include "psft.h" +#include FT_INTERNAL_DEBUG_H + +#include "psfont.h" +#include "pserror.h" +#include "psobjs.h" +#include "cffdecode.h" + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include FT_MULTIPLE_MASTERS_H +#include FT_SERVICE_MULTIPLE_MASTERS_H +#endif + +#include FT_SERVICE_CFF_TABLE_LOAD_H + + +#define CF2_MAX_SIZE cf2_intToFixed( 2000 ) /* max ppem */ + + + /* + * This check should avoid most internal overflow cases. Clients should + * generally respond to `Glyph_Too_Big' by getting a glyph outline + * at EM size, scaling it and filling it as a graphics operation. + * + */ + static FT_Error + cf2_checkTransform( const CF2_Matrix* transform, + CF2_Int unitsPerEm ) + { + CF2_Fixed maxScale; + + + FT_ASSERT( unitsPerEm > 0 ); + + if ( transform->a <= 0 || transform->d <= 0 ) + return FT_THROW( Invalid_Size_Handle ); + + FT_ASSERT( transform->b == 0 && transform->c == 0 ); + FT_ASSERT( transform->tx == 0 && transform->ty == 0 ); + + if ( unitsPerEm > 0x7FFF ) + return FT_THROW( Glyph_Too_Big ); + + maxScale = FT_DivFix( CF2_MAX_SIZE, cf2_intToFixed( unitsPerEm ) ); + + if ( transform->a > maxScale || transform->d > maxScale ) + return FT_THROW( Glyph_Too_Big ); + + return FT_Err_Ok; + } + + + static void + cf2_setGlyphWidth( CF2_Outline outline, + CF2_Fixed width ) + { + PS_Decoder* decoder = outline->decoder; + + + FT_ASSERT( decoder ); + + if ( !decoder->builder.is_t1 ) + *decoder->glyph_width = cf2_fixedToInt( width ); + } + + + /* Clean up font instance. */ + static void + cf2_free_instance( void* ptr ) + { + CF2_Font font = (CF2_Font)ptr; + + + if ( font ) + { + FT_Memory memory = font->memory; + + + FT_FREE( font->blend.lastNDV ); + FT_FREE( font->blend.BV ); + } + } + + + /********************************************/ + /* */ + /* functions for handling client outline; */ + /* FreeType uses coordinates in 26.6 format */ + /* */ + /********************************************/ + + static void + cf2_builder_moveTo( CF2_OutlineCallbacks callbacks, + const CF2_CallbackParams params ) + { + /* downcast the object pointer */ + CF2_Outline outline = (CF2_Outline)callbacks; + PS_Builder* builder; + + (void)params; /* only used in debug mode */ + + + FT_ASSERT( outline && outline->decoder ); + FT_ASSERT( params->op == CF2_PathOpMoveTo ); + + builder = &outline->decoder->builder; + + /* note: two successive moves simply close the contour twice */ + ps_builder_close_contour( builder ); + builder->path_begun = 0; + } + + + static void + cf2_builder_lineTo( CF2_OutlineCallbacks callbacks, + const CF2_CallbackParams params ) + { + FT_Error error; + + /* downcast the object pointer */ + CF2_Outline outline = (CF2_Outline)callbacks; + PS_Builder* builder; + + + FT_ASSERT( outline && outline->decoder ); + FT_ASSERT( params->op == CF2_PathOpLineTo ); + + builder = &outline->decoder->builder; + + if ( !builder->path_begun ) + { + /* record the move before the line; also check points and set */ + /* `path_begun' */ + error = ps_builder_start_point( builder, + params->pt0.x, + params->pt0.y ); + if ( error ) + { + if ( !*callbacks->error ) + *callbacks->error = error; + return; + } + } + + /* `ps_builder_add_point1' includes a check_points call for one point */ + error = ps_builder_add_point1( builder, + params->pt1.x, + params->pt1.y ); + if ( error ) + { + if ( !*callbacks->error ) + *callbacks->error = error; + return; + } + } + + + static void + cf2_builder_cubeTo( CF2_OutlineCallbacks callbacks, + const CF2_CallbackParams params ) + { + FT_Error error; + + /* downcast the object pointer */ + CF2_Outline outline = (CF2_Outline)callbacks; + PS_Builder* builder; + + + FT_ASSERT( outline && outline->decoder ); + FT_ASSERT( params->op == CF2_PathOpCubeTo ); + + builder = &outline->decoder->builder; + + if ( !builder->path_begun ) + { + /* record the move before the line; also check points and set */ + /* `path_begun' */ + error = ps_builder_start_point( builder, + params->pt0.x, + params->pt0.y ); + if ( error ) + { + if ( !*callbacks->error ) + *callbacks->error = error; + return; + } + } + + /* prepare room for 3 points: 2 off-curve, 1 on-curve */ + error = ps_builder_check_points( builder, 3 ); + if ( error ) + { + if ( !*callbacks->error ) + *callbacks->error = error; + return; + } + + ps_builder_add_point( builder, + params->pt1.x, + params->pt1.y, 0 ); + ps_builder_add_point( builder, + params->pt2.x, + params->pt2.y, 0 ); + ps_builder_add_point( builder, + params->pt3.x, + params->pt3.y, 1 ); + } + + + static void + cf2_outline_init( CF2_Outline outline, + FT_Memory memory, + FT_Error* error ) + { + FT_ZERO( outline ); + + outline->root.memory = memory; + outline->root.error = error; + + outline->root.moveTo = cf2_builder_moveTo; + outline->root.lineTo = cf2_builder_lineTo; + outline->root.cubeTo = cf2_builder_cubeTo; + } + + + /* get scaling and hint flag from GlyphSlot */ + static void + cf2_getScaleAndHintFlag( PS_Decoder* decoder, + CF2_Fixed* x_scale, + CF2_Fixed* y_scale, + FT_Bool* hinted, + FT_Bool* scaled ) + { + FT_ASSERT( decoder && decoder->builder.glyph ); + + /* note: FreeType scale includes a factor of 64 */ + *hinted = decoder->builder.glyph->hint; + *scaled = decoder->builder.glyph->scaled; + + if ( *hinted ) + { + *x_scale = ADD_INT32( decoder->builder.glyph->x_scale, 32 ) / 64; + *y_scale = ADD_INT32( decoder->builder.glyph->y_scale, 32 ) / 64; + } + else + { + /* for unhinted outlines, `cff_slot_load' does the scaling, */ + /* thus render at `unity' scale */ + + *x_scale = 0x0400; /* 1/64 as 16.16 */ + *y_scale = 0x0400; + } + } + + + /* get units per em from `FT_Face' */ + /* TODO: should handle font matrix concatenation? */ + static FT_UShort + cf2_getUnitsPerEm( PS_Decoder* decoder ) + { + FT_ASSERT( decoder && decoder->builder.face ); + FT_ASSERT( decoder->builder.face->units_per_EM ); + + return decoder->builder.face->units_per_EM; + } + + + /* Main entry point: Render one glyph. */ + FT_LOCAL_DEF( FT_Error ) + cf2_decoder_parse_charstrings( PS_Decoder* decoder, + FT_Byte* charstring_base, + FT_ULong charstring_len ) + { + FT_Memory memory; + FT_Error error = FT_Err_Ok; + CF2_Font font; + + FT_Bool is_t1 = decoder->builder.is_t1; + + + FT_ASSERT( decoder && + ( is_t1 || decoder->cff ) ); + + if ( is_t1 && !decoder->current_subfont ) + { + FT_ERROR(( "cf2_decoder_parse_charstrings (Type 1): " + "SubFont missing. Use `t1_make_subfont' first\n" )); + return FT_THROW( Invalid_Table ); + } + + memory = decoder->builder.memory; + + /* CF2 data is saved here across glyphs */ + font = (CF2_Font)decoder->cf2_instance->data; + + /* on first glyph, allocate instance structure */ + if ( !decoder->cf2_instance->data ) + { + decoder->cf2_instance->finalizer = + (FT_Generic_Finalizer)cf2_free_instance; + + if ( FT_ALLOC( decoder->cf2_instance->data, + sizeof ( CF2_FontRec ) ) ) + return FT_THROW( Out_Of_Memory ); + + font = (CF2_Font)decoder->cf2_instance->data; + + font->memory = memory; + + if ( !is_t1 ) + font->cffload = (FT_Service_CFFLoad)decoder->cff->cffload; + + /* initialize a client outline, to be shared by each glyph rendered */ + cf2_outline_init( &font->outline, font->memory, &font->error ); + } + + /* save decoder; it is a stack variable and will be different on each */ + /* call */ + font->decoder = decoder; + font->outline.decoder = decoder; + + { + /* build parameters for Adobe engine */ + + PS_Builder* builder = &decoder->builder; + PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( builder->face ); + + FT_Bool no_stem_darkening_driver = + driver->no_stem_darkening; + FT_Char no_stem_darkening_font = + builder->face->internal->no_stem_darkening; + + /* local error */ + FT_Error error2 = FT_Err_Ok; + CF2_BufferRec buf; + CF2_Matrix transform; + CF2_F16Dot16 glyphWidth; + + FT_Bool hinted; + FT_Bool scaled; + + + /* FreeType has already looked up the GID; convert to */ + /* `RegionBuffer', assuming that the input has been validated */ + FT_ASSERT( charstring_base + charstring_len >= charstring_base ); + + FT_ZERO( &buf ); + buf.start = + buf.ptr = charstring_base; + buf.end = charstring_base + charstring_len; + + FT_ZERO( &transform ); + + cf2_getScaleAndHintFlag( decoder, + &transform.a, + &transform.d, + &hinted, + &scaled ); + + if ( is_t1 ) + font->isCFF2 = FALSE; + else + { + /* copy isCFF2 boolean from TT_Face to CF2_Font */ + font->isCFF2 = ((TT_Face)builder->face)->is_cff2; + } + font->isT1 = is_t1; + + font->renderingFlags = 0; + if ( hinted ) + font->renderingFlags |= CF2_FlagsHinted; + if ( scaled && ( !no_stem_darkening_font || + ( no_stem_darkening_font < 0 && + !no_stem_darkening_driver ) ) ) + font->renderingFlags |= CF2_FlagsDarkened; + + font->darkenParams[0] = driver->darken_params[0]; + font->darkenParams[1] = driver->darken_params[1]; + font->darkenParams[2] = driver->darken_params[2]; + font->darkenParams[3] = driver->darken_params[3]; + font->darkenParams[4] = driver->darken_params[4]; + font->darkenParams[5] = driver->darken_params[5]; + font->darkenParams[6] = driver->darken_params[6]; + font->darkenParams[7] = driver->darken_params[7]; + + /* now get an outline for this glyph; */ + /* also get units per em to validate scale */ + font->unitsPerEm = (CF2_Int)cf2_getUnitsPerEm( decoder ); + + if ( scaled ) + { + error2 = cf2_checkTransform( &transform, font->unitsPerEm ); + if ( error2 ) + return error2; + } + + error2 = cf2_getGlyphOutline( font, &buf, &transform, &glyphWidth ); + if ( error2 ) + return FT_ERR( Invalid_File_Format ); + + cf2_setGlyphWidth( &font->outline, glyphWidth ); + + return FT_Err_Ok; + } + } + + + /* get pointer to current FreeType subfont (based on current glyphID) */ + FT_LOCAL_DEF( CFF_SubFont ) + cf2_getSubfont( PS_Decoder* decoder ) + { + FT_ASSERT( decoder && decoder->current_subfont ); + + return decoder->current_subfont; + } + + + /* get pointer to VStore structure */ + FT_LOCAL_DEF( CFF_VStore ) + cf2_getVStore( PS_Decoder* decoder ) + { + FT_ASSERT( decoder && decoder->cff ); + + return &decoder->cff->vstore; + } + + + /* get maxstack value from CFF2 Top DICT */ + FT_LOCAL_DEF( FT_UInt ) + cf2_getMaxstack( PS_Decoder* decoder ) + { + FT_ASSERT( decoder && decoder->cff ); + + return decoder->cff->top_font.font_dict.maxstack; + } + + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + /* Get normalized design vector for current render request; */ + /* return pointer and length. */ + /* */ + /* Note: Uses FT_Fixed not CF2_Fixed for the vector. */ + FT_LOCAL_DEF( FT_Error ) + cf2_getNormalizedVector( PS_Decoder* decoder, + CF2_UInt *len, + FT_Fixed* *vec ) + { + TT_Face face; + FT_Service_MultiMasters mm; + + + FT_ASSERT( decoder && decoder->builder.face ); + FT_ASSERT( vec && len ); + FT_ASSERT( !decoder->builder.is_t1 ); + + face = (TT_Face)decoder->builder.face; + mm = (FT_Service_MultiMasters)face->mm; + + return mm->get_var_blend( FT_FACE( face ), len, NULL, vec, NULL ); + } +#endif + + + /* get `y_ppem' from `CFF_Size' */ + FT_LOCAL_DEF( CF2_Fixed ) + cf2_getPpemY( PS_Decoder* decoder ) + { + FT_ASSERT( decoder && + decoder->builder.face && + decoder->builder.face->size ); + + /* + * Note that `y_ppem' can be zero if there wasn't a call to + * `FT_Set_Char_Size' or something similar. However, this isn't a + * problem since we come to this place in the code only if + * FT_LOAD_NO_SCALE is set (the other case gets caught by + * `cf2_checkTransform'). The ppem value is needed to compute the stem + * darkening, which is disabled for getting the unscaled outline. + * + */ + return cf2_intToFixed( + decoder->builder.face->size->metrics.y_ppem ); + } + + + /* get standard stem widths for the current subfont; */ + /* FreeType stores these as integer font units */ + /* (note: variable names seem swapped) */ + FT_LOCAL_DEF( CF2_Fixed ) + cf2_getStdVW( PS_Decoder* decoder ) + { + FT_ASSERT( decoder && decoder->current_subfont ); + + return cf2_intToFixed( + decoder->current_subfont->private_dict.standard_height ); + } + + + FT_LOCAL_DEF( CF2_Fixed ) + cf2_getStdHW( PS_Decoder* decoder ) + { + FT_ASSERT( decoder && decoder->current_subfont ); + + return cf2_intToFixed( + decoder->current_subfont->private_dict.standard_width ); + } + + + /* note: FreeType stores 1000 times the actual value for `BlueScale' */ + FT_LOCAL_DEF( void ) + cf2_getBlueMetrics( PS_Decoder* decoder, + CF2_Fixed* blueScale, + CF2_Fixed* blueShift, + CF2_Fixed* blueFuzz ) + { + FT_ASSERT( decoder && decoder->current_subfont ); + + *blueScale = FT_DivFix( + decoder->current_subfont->private_dict.blue_scale, + cf2_intToFixed( 1000 ) ); + *blueShift = cf2_intToFixed( + decoder->current_subfont->private_dict.blue_shift ); + *blueFuzz = cf2_intToFixed( + decoder->current_subfont->private_dict.blue_fuzz ); + } + + + /* get blue values counts and arrays; the FreeType parser has validated */ + /* the counts and verified that each is an even number */ + FT_LOCAL_DEF( void ) + cf2_getBlueValues( PS_Decoder* decoder, + size_t* count, + FT_Pos* *data ) + { + FT_ASSERT( decoder && decoder->current_subfont ); + + *count = decoder->current_subfont->private_dict.num_blue_values; + *data = (FT_Pos*) + &decoder->current_subfont->private_dict.blue_values; + } + + + FT_LOCAL_DEF( void ) + cf2_getOtherBlues( PS_Decoder* decoder, + size_t* count, + FT_Pos* *data ) + { + FT_ASSERT( decoder && decoder->current_subfont ); + + *count = decoder->current_subfont->private_dict.num_other_blues; + *data = (FT_Pos*) + &decoder->current_subfont->private_dict.other_blues; + } + + + FT_LOCAL_DEF( void ) + cf2_getFamilyBlues( PS_Decoder* decoder, + size_t* count, + FT_Pos* *data ) + { + FT_ASSERT( decoder && decoder->current_subfont ); + + *count = decoder->current_subfont->private_dict.num_family_blues; + *data = (FT_Pos*) + &decoder->current_subfont->private_dict.family_blues; + } + + + FT_LOCAL_DEF( void ) + cf2_getFamilyOtherBlues( PS_Decoder* decoder, + size_t* count, + FT_Pos* *data ) + { + FT_ASSERT( decoder && decoder->current_subfont ); + + *count = decoder->current_subfont->private_dict.num_family_other_blues; + *data = (FT_Pos*) + &decoder->current_subfont->private_dict.family_other_blues; + } + + + FT_LOCAL_DEF( CF2_Int ) + cf2_getLanguageGroup( PS_Decoder* decoder ) + { + FT_ASSERT( decoder && decoder->current_subfont ); + + return decoder->current_subfont->private_dict.language_group; + } + + + /* convert unbiased subroutine index to `CF2_Buffer' and */ + /* return 0 on success */ + FT_LOCAL_DEF( CF2_Int ) + cf2_initGlobalRegionBuffer( PS_Decoder* decoder, + CF2_Int subrNum, + CF2_Buffer buf ) + { + CF2_UInt idx; + + + FT_ASSERT( decoder ); + + FT_ZERO( buf ); + + idx = (CF2_UInt)( subrNum + decoder->globals_bias ); + if ( idx >= decoder->num_globals ) + return TRUE; /* error */ + + FT_ASSERT( decoder->globals ); + + buf->start = + buf->ptr = decoder->globals[idx]; + buf->end = decoder->globals[idx + 1]; + + return FALSE; /* success */ + } + + + /* convert AdobeStandardEncoding code to CF2_Buffer; */ + /* used for seac component */ + FT_LOCAL_DEF( FT_Error ) + cf2_getSeacComponent( PS_Decoder* decoder, + CF2_Int code, + CF2_Buffer buf ) + { + CF2_Int gid; + FT_Byte* charstring; + FT_ULong len; + FT_Error error; + + + FT_ASSERT( decoder ); + FT_ASSERT( !decoder->builder.is_t1 ); + + FT_ZERO( buf ); + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + /* Incremental fonts don't necessarily have valid charsets. */ + /* They use the character code, not the glyph index, in this case. */ + if ( decoder->builder.face->internal->incremental_interface ) + gid = code; + else +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + { + gid = cff_lookup_glyph_by_stdcharcode( decoder->cff, code ); + if ( gid < 0 ) + return FT_THROW( Invalid_Glyph_Format ); + } + + error = decoder->get_glyph_callback( (TT_Face)decoder->builder.face, + (CF2_UInt)gid, + &charstring, + &len ); + /* TODO: for now, just pass the FreeType error through */ + if ( error ) + return error; + + /* assume input has been validated */ + FT_ASSERT( charstring + len >= charstring ); + + buf->start = charstring; + buf->end = charstring + len; + buf->ptr = buf->start; + + return FT_Err_Ok; + } + + + FT_LOCAL_DEF( void ) + cf2_freeSeacComponent( PS_Decoder* decoder, + CF2_Buffer buf ) + { + FT_ASSERT( decoder ); + FT_ASSERT( !decoder->builder.is_t1 ); + + decoder->free_glyph_callback( (TT_Face)decoder->builder.face, + (FT_Byte**)&buf->start, + (FT_ULong)( buf->end - buf->start ) ); + } + + + FT_LOCAL_DEF( FT_Error ) + cf2_getT1SeacComponent( PS_Decoder* decoder, + FT_UInt glyph_index, + CF2_Buffer buf ) + { + FT_Data glyph_data; + FT_Error error = FT_Err_Ok; + T1_Face face = (T1_Face)decoder->builder.face; + T1_Font type1 = &face->type1; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + FT_Incremental_InterfaceRec *inc = + face->root.internal->incremental_interface; + + + /* For incremental fonts get the character data using the */ + /* callback function. */ + if ( inc ) + error = inc->funcs->get_glyph_data( inc->object, + glyph_index, &glyph_data ); + else +#endif + /* For ordinary fonts get the character data stored in the face record. */ + { + glyph_data.pointer = type1->charstrings[glyph_index]; + glyph_data.length = (FT_Int)type1->charstrings_len[glyph_index]; + } + + if ( !error ) + { + FT_Byte* charstring_base = (FT_Byte*)glyph_data.pointer; + FT_ULong charstring_len = (FT_ULong)glyph_data.length; + + + FT_ASSERT( charstring_base + charstring_len >= charstring_base ); + + FT_ZERO( buf ); + buf->start = + buf->ptr = charstring_base; + buf->end = charstring_base + charstring_len; + } + + return error; + } + + + FT_LOCAL_DEF( void ) + cf2_freeT1SeacComponent( PS_Decoder* decoder, + CF2_Buffer buf ) + { + T1_Face face; + FT_Data data; + + + FT_ASSERT( decoder ); + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + face = (T1_Face)decoder->builder.face; + + data.pointer = buf->start; + data.length = (FT_Int)( buf->end - buf->start ); + + if ( face->root.internal->incremental_interface ) + face->root.internal->incremental_interface->funcs->free_glyph_data( + face->root.internal->incremental_interface->object, + &data ); +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + } + + + FT_LOCAL_DEF( CF2_Int ) + cf2_initLocalRegionBuffer( PS_Decoder* decoder, + CF2_Int subrNum, + CF2_Buffer buf ) + { + CF2_UInt idx; + + + FT_ASSERT( decoder ); + + FT_ZERO( buf ); + + idx = (CF2_UInt)( subrNum + decoder->locals_bias ); + if ( idx >= decoder->num_locals ) + return TRUE; /* error */ + + FT_ASSERT( decoder->locals ); + + buf->start = decoder->locals[idx]; + + if ( decoder->builder.is_t1 ) + { + /* The Type 1 driver stores subroutines without the seed bytes. */ + /* The CID driver stores subroutines with seed bytes. This */ + /* case is taken care of when decoder->subrs_len == 0. */ + if ( decoder->locals_len ) + buf->end = buf->start + decoder->locals_len[idx]; + else + { + /* We are using subroutines from a CID font. We must adjust */ + /* for the seed bytes. */ + buf->start += ( decoder->lenIV >= 0 ? decoder->lenIV : 0 ); + buf->end = decoder->locals[idx + 1]; + } + + if ( !buf->start ) + { + FT_ERROR(( "cf2_initLocalRegionBuffer (Type 1 mode):" + " invoking empty subrs\n" )); + } + } + else + { + buf->end = decoder->locals[idx + 1]; + } + + buf->ptr = buf->start; + + return FALSE; /* success */ + } + + + FT_LOCAL_DEF( CF2_Fixed ) + cf2_getDefaultWidthX( PS_Decoder* decoder ) + { + FT_ASSERT( decoder && decoder->current_subfont ); + + return cf2_intToFixed( + decoder->current_subfont->private_dict.default_width ); + } + + + FT_LOCAL_DEF( CF2_Fixed ) + cf2_getNominalWidthX( PS_Decoder* decoder ) + { + FT_ASSERT( decoder && decoder->current_subfont ); + + return cf2_intToFixed( + decoder->current_subfont->private_dict.nominal_width ); + } + + + FT_LOCAL_DEF( void ) + cf2_outline_reset( CF2_Outline outline ) + { + PS_Decoder* decoder = outline->decoder; + + + FT_ASSERT( decoder ); + + outline->root.windingMomentum = 0; + + FT_GlyphLoader_Rewind( decoder->builder.loader ); + } + + + FT_LOCAL_DEF( void ) + cf2_outline_close( CF2_Outline outline ) + { + PS_Decoder* decoder = outline->decoder; + + + FT_ASSERT( decoder ); + + ps_builder_close_contour( &decoder->builder ); + + FT_GlyphLoader_Add( decoder->builder.loader ); + } + + +/* END */ diff --git a/src/3rdparty/freetype/src/psaux/psft.h b/src/3rdparty/freetype/src/psaux/psft.h new file mode 100644 index 0000000000..ab172110bb --- /dev/null +++ b/src/3rdparty/freetype/src/psaux/psft.h @@ -0,0 +1,167 @@ +/***************************************************************************/ +/* */ +/* psft.h */ +/* */ +/* FreeType Glue Component to Adobe's Interpreter (specification). */ +/* */ +/* Copyright 2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#ifndef PSFT_H_ +#define PSFT_H_ + + +#include "pstypes.h" + + + /* TODO: disable asserts for now */ +#define CF2_NDEBUG + + +#include FT_SYSTEM_H + +#include "psglue.h" +#include FT_INTERNAL_POSTSCRIPT_AUX_H /* for PS_Decoder */ + + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + cf2_decoder_parse_charstrings( PS_Decoder* decoder, + FT_Byte* charstring_base, + FT_ULong charstring_len ); + + FT_LOCAL( CFF_SubFont ) + cf2_getSubfont( PS_Decoder* decoder ); + + FT_LOCAL( CFF_VStore ) + cf2_getVStore( PS_Decoder* decoder ); + + FT_LOCAL( FT_UInt ) + cf2_getMaxstack( PS_Decoder* decoder ); + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_LOCAL( FT_Error ) + cf2_getNormalizedVector( PS_Decoder* decoder, + CF2_UInt *len, + FT_Fixed* *vec ); +#endif + + FT_LOCAL( CF2_Fixed ) + cf2_getPpemY( PS_Decoder* decoder ); + FT_LOCAL( CF2_Fixed ) + cf2_getStdVW( PS_Decoder* decoder ); + FT_LOCAL( CF2_Fixed ) + cf2_getStdHW( PS_Decoder* decoder ); + + FT_LOCAL( void ) + cf2_getBlueMetrics( PS_Decoder* decoder, + CF2_Fixed* blueScale, + CF2_Fixed* blueShift, + CF2_Fixed* blueFuzz ); + FT_LOCAL( void ) + cf2_getBlueValues( PS_Decoder* decoder, + size_t* count, + FT_Pos* *data ); + FT_LOCAL( void ) + cf2_getOtherBlues( PS_Decoder* decoder, + size_t* count, + FT_Pos* *data ); + FT_LOCAL( void ) + cf2_getFamilyBlues( PS_Decoder* decoder, + size_t* count, + FT_Pos* *data ); + FT_LOCAL( void ) + cf2_getFamilyOtherBlues( PS_Decoder* decoder, + size_t* count, + FT_Pos* *data ); + + FT_LOCAL( CF2_Int ) + cf2_getLanguageGroup( PS_Decoder* decoder ); + + FT_LOCAL( CF2_Int ) + cf2_initGlobalRegionBuffer( PS_Decoder* decoder, + CF2_Int subrNum, + CF2_Buffer buf ); + FT_LOCAL( FT_Error ) + cf2_getSeacComponent( PS_Decoder* decoder, + CF2_Int code, + CF2_Buffer buf ); + FT_LOCAL( void ) + cf2_freeSeacComponent( PS_Decoder* decoder, + CF2_Buffer buf ); + FT_LOCAL( CF2_Int ) + cf2_initLocalRegionBuffer( PS_Decoder* decoder, + CF2_Int subrNum, + CF2_Buffer buf ); + + FT_LOCAL( CF2_Fixed ) + cf2_getDefaultWidthX( PS_Decoder* decoder ); + FT_LOCAL( CF2_Fixed ) + cf2_getNominalWidthX( PS_Decoder* decoder ); + + + FT_LOCAL( FT_Error ) + cf2_getT1SeacComponent( PS_Decoder* decoder, + FT_UInt glyph_index, + CF2_Buffer buf ); + FT_LOCAL( void ) + cf2_freeT1SeacComponent( PS_Decoder* decoder, + CF2_Buffer buf ); + + /* + * FreeType client outline + * + * process output from the charstring interpreter + */ + typedef struct CF2_OutlineRec_ + { + CF2_OutlineCallbacksRec root; /* base class must be first */ + PS_Decoder* decoder; + + } CF2_OutlineRec, *CF2_Outline; + + + FT_LOCAL( void ) + cf2_outline_reset( CF2_Outline outline ); + FT_LOCAL( void ) + cf2_outline_close( CF2_Outline outline ); + + +FT_END_HEADER + + +#endif /* PSFT_H_ */ + + +/* END */ diff --git a/src/3rdparty/freetype/src/psaux/psglue.h b/src/3rdparty/freetype/src/psaux/psglue.h new file mode 100644 index 0000000000..5545e12a5b --- /dev/null +++ b/src/3rdparty/freetype/src/psaux/psglue.h @@ -0,0 +1,144 @@ +/***************************************************************************/ +/* */ +/* psglue.h */ +/* */ +/* Adobe's code for shared stuff (specification only). */ +/* */ +/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#ifndef PSGLUE_H_ +#define PSGLUE_H_ + + +/* common includes for other modules */ +#include "pserror.h" +#include "psfixed.h" +#include "psarrst.h" +#include "psread.h" + + +FT_BEGIN_HEADER + + + /* rendering parameters */ + + /* apply hints to rendered glyphs */ +#define CF2_FlagsHinted 1 + /* for testing */ +#define CF2_FlagsDarkened 2 + + /* type for holding the flags */ + typedef CF2_Int CF2_RenderingFlags; + + + /* elements of a glyph outline */ + typedef enum CF2_PathOp_ + { + CF2_PathOpMoveTo = 1, /* change the current point */ + CF2_PathOpLineTo = 2, /* line */ + CF2_PathOpQuadTo = 3, /* quadratic curve */ + CF2_PathOpCubeTo = 4 /* cubic curve */ + + } CF2_PathOp; + + + /* a matrix of fixed point values */ + typedef struct CF2_Matrix_ + { + CF2_F16Dot16 a; + CF2_F16Dot16 b; + CF2_F16Dot16 c; + CF2_F16Dot16 d; + CF2_F16Dot16 tx; + CF2_F16Dot16 ty; + + } CF2_Matrix; + + + /* these typedefs are needed by more than one header file */ + /* and gcc compiler doesn't allow redefinition */ + typedef struct CF2_FontRec_ CF2_FontRec, *CF2_Font; + typedef struct CF2_HintRec_ CF2_HintRec, *CF2_Hint; + + + /* A common structure for all callback parameters. */ + /* */ + /* Some members may be unused. For example, `pt0' is not used for */ + /* `moveTo' and `pt3' is not used for `quadTo'. The initial point `pt0' */ + /* is included for each path element for generality; curve conversions */ + /* need it. The `op' parameter allows one function to handle multiple */ + /* element types. */ + + typedef struct CF2_CallbackParamsRec_ + { + FT_Vector pt0; + FT_Vector pt1; + FT_Vector pt2; + FT_Vector pt3; + + CF2_Int op; + + } CF2_CallbackParamsRec, *CF2_CallbackParams; + + + /* forward reference */ + typedef struct CF2_OutlineCallbacksRec_ CF2_OutlineCallbacksRec, + *CF2_OutlineCallbacks; + + /* callback function pointers */ + typedef void + (*CF2_Callback_Type)( CF2_OutlineCallbacks callbacks, + const CF2_CallbackParams params ); + + + struct CF2_OutlineCallbacksRec_ + { + CF2_Callback_Type moveTo; + CF2_Callback_Type lineTo; + CF2_Callback_Type quadTo; + CF2_Callback_Type cubeTo; + + CF2_Int windingMomentum; /* for winding order detection */ + + FT_Memory memory; + FT_Error* error; + }; + + +FT_END_HEADER + + +#endif /* PSGLUE_H_ */ + + +/* END */ diff --git a/src/3rdparty/freetype/src/psaux/pshints.c b/src/3rdparty/freetype/src/psaux/pshints.c new file mode 100644 index 0000000000..3615196425 --- /dev/null +++ b/src/3rdparty/freetype/src/psaux/pshints.c @@ -0,0 +1,1939 @@ +/***************************************************************************/ +/* */ +/* pshints.c */ +/* */ +/* Adobe's code for handling CFF hints (body). */ +/* */ +/* Copyright 2007-2014 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#include "psft.h" +#include FT_INTERNAL_DEBUG_H + +#include "psglue.h" +#include "psfont.h" +#include "pshints.h" +#include "psintrp.h" + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_cf2hints + + + typedef struct CF2_HintMoveRec_ + { + size_t j; /* index of upper hint map edge */ + CF2_Fixed moveUp; /* adjustment to optimum position */ + + } CF2_HintMoveRec, *CF2_HintMove; + + + /* Compute angular momentum for winding order detection. It is called */ + /* for all lines and curves, but not necessarily in element order. */ + static CF2_Int + cf2_getWindingMomentum( CF2_Fixed x1, + CF2_Fixed y1, + CF2_Fixed x2, + CF2_Fixed y2 ) + { + /* cross product of pt1 position from origin with pt2 position from */ + /* pt1; we reduce the precision so that the result fits into 32 bits */ + + return ( x1 >> 16 ) * ( SUB_INT32( y2, y1 ) >> 16 ) - + ( y1 >> 16 ) * ( SUB_INT32( x2, x1 ) >> 16 ); + } + + + /* + * Construct from a StemHint; this is used as a parameter to + * `cf2_blues_capture'. + * `hintOrigin' is the character space displacement of a seac accent. + * Adjust stem hint for darkening here. + * + */ + static void + cf2_hint_init( CF2_Hint hint, + const CF2_ArrStack stemHintArray, + size_t indexStemHint, + const CF2_Font font, + CF2_Fixed hintOrigin, + CF2_Fixed scale, + FT_Bool bottom ) + { + CF2_Fixed width; + const CF2_StemHintRec* stemHint; + + + FT_ZERO( hint ); + + stemHint = (const CF2_StemHintRec*)cf2_arrstack_getPointer( + stemHintArray, + indexStemHint ); + + width = SUB_INT32( stemHint->max, stemHint->min ); + + if ( width == cf2_intToFixed( -21 ) ) + { + /* ghost bottom */ + + if ( bottom ) + { + hint->csCoord = stemHint->max; + hint->flags = CF2_GhostBottom; + } + else + hint->flags = 0; + } + + else if ( width == cf2_intToFixed( -20 ) ) + { + /* ghost top */ + + if ( bottom ) + hint->flags = 0; + else + { + hint->csCoord = stemHint->min; + hint->flags = CF2_GhostTop; + } + } + + else if ( width < 0 ) + { + /* inverted pair */ + + /* + * Hints with negative widths were produced by an early version of a + * non-Adobe font tool. The Type 2 spec allows edge (ghost) hints + * with negative widths, but says + * + * All other negative widths have undefined meaning. + * + * CoolType has a silent workaround that negates the hint width; for + * permissive mode, we do the same here. + * + * Note: Such fonts cannot use ghost hints, but should otherwise work. + * Note: Some poor hints in our faux fonts can produce negative + * widths at some blends. For example, see a light weight of + * `u' in ASerifMM. + * + */ + if ( bottom ) + { + hint->csCoord = stemHint->max; + hint->flags = CF2_PairBottom; + } + else + { + hint->csCoord = stemHint->min; + hint->flags = CF2_PairTop; + } + } + + else + { + /* normal pair */ + + if ( bottom ) + { + hint->csCoord = stemHint->min; + hint->flags = CF2_PairBottom; + } + else + { + hint->csCoord = stemHint->max; + hint->flags = CF2_PairTop; + } + } + + /* Now that ghost hints have been detected, adjust this edge for */ + /* darkening. Bottoms are not changed; tops are incremented by twice */ + /* `darkenY'. */ + if ( cf2_hint_isTop( hint ) ) + hint->csCoord = ADD_INT32( hint->csCoord, 2 * font->darkenY ); + + hint->csCoord = ADD_INT32( hint->csCoord, hintOrigin ); + hint->scale = scale; + hint->index = indexStemHint; /* index in original stem hint array */ + + /* if original stem hint has been used, use the same position */ + if ( hint->flags != 0 && stemHint->used ) + { + if ( cf2_hint_isTop( hint ) ) + hint->dsCoord = stemHint->maxDS; + else + hint->dsCoord = stemHint->minDS; + + cf2_hint_lock( hint ); + } + else + hint->dsCoord = FT_MulFix( hint->csCoord, scale ); + } + + + /* initialize an invalid hint map element */ + static void + cf2_hint_initZero( CF2_Hint hint ) + { + FT_ZERO( hint ); + } + + + FT_LOCAL_DEF( FT_Bool ) + cf2_hint_isValid( const CF2_Hint hint ) + { + return (FT_Bool)( hint->flags != 0 ); + } + + + static FT_Bool + cf2_hint_isPair( const CF2_Hint hint ) + { + return (FT_Bool)( ( hint->flags & + ( CF2_PairBottom | CF2_PairTop ) ) != 0 ); + } + + + static FT_Bool + cf2_hint_isPairTop( const CF2_Hint hint ) + { + return (FT_Bool)( ( hint->flags & CF2_PairTop ) != 0 ); + } + + + FT_LOCAL_DEF( FT_Bool ) + cf2_hint_isTop( const CF2_Hint hint ) + { + return (FT_Bool)( ( hint->flags & + ( CF2_PairTop | CF2_GhostTop ) ) != 0 ); + } + + + FT_LOCAL_DEF( FT_Bool ) + cf2_hint_isBottom( const CF2_Hint hint ) + { + return (FT_Bool)( ( hint->flags & + ( CF2_PairBottom | CF2_GhostBottom ) ) != 0 ); + } + + + static FT_Bool + cf2_hint_isLocked( const CF2_Hint hint ) + { + return (FT_Bool)( ( hint->flags & CF2_Locked ) != 0 ); + } + + + static FT_Bool + cf2_hint_isSynthetic( const CF2_Hint hint ) + { + return (FT_Bool)( ( hint->flags & CF2_Synthetic ) != 0 ); + } + + + FT_LOCAL_DEF( void ) + cf2_hint_lock( CF2_Hint hint ) + { + hint->flags |= CF2_Locked; + } + + + FT_LOCAL_DEF( void ) + cf2_hintmap_init( CF2_HintMap hintmap, + CF2_Font font, + CF2_HintMap initialMap, + CF2_ArrStack hintMoves, + CF2_Fixed scale ) + { + FT_ZERO( hintmap ); + + /* copy parameters from font instance */ + hintmap->hinted = font->hinted; + hintmap->scale = scale; + hintmap->font = font; + hintmap->initialHintMap = initialMap; + /* will clear in `cf2_hintmap_adjustHints' */ + hintmap->hintMoves = hintMoves; + } + + + static FT_Bool + cf2_hintmap_isValid( const CF2_HintMap hintmap ) + { + return hintmap->isValid; + } + + + static void + cf2_hintmap_dump( CF2_HintMap hintmap ) + { +#ifdef FT_DEBUG_LEVEL_TRACE + CF2_UInt i; + + + FT_TRACE6(( " index csCoord dsCoord scale flags\n" )); + + for ( i = 0; i < hintmap->count; i++ ) + { + CF2_Hint hint = &hintmap->edge[i]; + + + FT_TRACE6(( " %3d %7.2f %7.2f %5d %s%s%s%s\n", + hint->index, + hint->csCoord / 65536.0, + hint->dsCoord / ( hint->scale * 1.0 ), + hint->scale, + ( cf2_hint_isPair( hint ) ? "p" : "g" ), + ( cf2_hint_isTop( hint ) ? "t" : "b" ), + ( cf2_hint_isLocked( hint ) ? "L" : ""), + ( cf2_hint_isSynthetic( hint ) ? "S" : "" ) )); + } +#else + FT_UNUSED( hintmap ); +#endif + } + + + /* transform character space coordinate to device space using hint map */ + static CF2_Fixed + cf2_hintmap_map( CF2_HintMap hintmap, + CF2_Fixed csCoord ) + { + if ( hintmap->count == 0 || ! hintmap->hinted ) + { + /* there are no hints; use uniform scale and zero offset */ + return FT_MulFix( csCoord, hintmap->scale ); + } + else + { + /* start linear search from last hit */ + CF2_UInt i = hintmap->lastIndex; + + + FT_ASSERT( hintmap->lastIndex < CF2_MAX_HINT_EDGES ); + + /* search up */ + while ( i < hintmap->count - 1 && + csCoord >= hintmap->edge[i + 1].csCoord ) + i += 1; + + /* search down */ + while ( i > 0 && csCoord < hintmap->edge[i].csCoord ) + i -= 1; + + hintmap->lastIndex = i; + + if ( i == 0 && csCoord < hintmap->edge[0].csCoord ) + { + /* special case for points below first edge: use uniform scale */ + return ADD_INT32( FT_MulFix( SUB_INT32( csCoord, + hintmap->edge[0].csCoord ), + hintmap->scale ), + hintmap->edge[0].dsCoord ); + } + else + { + /* + * Note: entries with duplicate csCoord are allowed. + * Use edge[i], the highest entry where csCoord >= entry[i].csCoord + */ + return ADD_INT32( FT_MulFix( SUB_INT32( csCoord, + hintmap->edge[i].csCoord ), + hintmap->edge[i].scale ), + hintmap->edge[i].dsCoord ); + } + } + } + + + /* + * This hinting policy moves a hint pair in device space so that one of + * its two edges is on a device pixel boundary (its fractional part is + * zero). `cf2_hintmap_insertHint' guarantees no overlap in CS + * space. Ensure here that there is no overlap in DS. + * + * In the first pass, edges are adjusted relative to adjacent hints. + * Those that are below have already been adjusted. Those that are + * above have not yet been adjusted. If a hint above blocks an + * adjustment to an optimal position, we will try again in a second + * pass. The second pass is top-down. + * + */ + + static void + cf2_hintmap_adjustHints( CF2_HintMap hintmap ) + { + size_t i, j; + + + cf2_arrstack_clear( hintmap->hintMoves ); /* working storage */ + + /* + * First pass is bottom-up (font hint order) without look-ahead. + * Locked edges are already adjusted. + * Unlocked edges begin with dsCoord from `initialHintMap'. + * Save edges that are not optimally adjusted in `hintMoves' array, + * and process them in second pass. + */ + + for ( i = 0; i < hintmap->count; i++ ) + { + FT_Bool isPair = cf2_hint_isPair( &hintmap->edge[i] ); + + + /* index of upper edge (same value for ghost hint) */ + j = isPair ? i + 1 : i; + + FT_ASSERT( j < hintmap->count ); + FT_ASSERT( cf2_hint_isValid( &hintmap->edge[i] ) ); + FT_ASSERT( cf2_hint_isValid( &hintmap->edge[j] ) ); + FT_ASSERT( cf2_hint_isLocked( &hintmap->edge[i] ) == + cf2_hint_isLocked( &hintmap->edge[j] ) ); + + if ( !cf2_hint_isLocked( &hintmap->edge[i] ) ) + { + /* hint edge is not locked, we can adjust it */ + CF2_Fixed fracDown = cf2_fixedFraction( hintmap->edge[i].dsCoord ); + CF2_Fixed fracUp = cf2_fixedFraction( hintmap->edge[j].dsCoord ); + + /* calculate all four possibilities; moves down are negative */ + CF2_Fixed downMoveDown = 0 - fracDown; + CF2_Fixed upMoveDown = 0 - fracUp; + CF2_Fixed downMoveUp = ( fracDown == 0 ) + ? 0 + : cf2_intToFixed( 1 ) - fracDown; + CF2_Fixed upMoveUp = ( fracUp == 0 ) + ? 0 + : cf2_intToFixed( 1 ) - fracUp; + + /* smallest move up */ + CF2_Fixed moveUp = FT_MIN( downMoveUp, upMoveUp ); + /* smallest move down */ + CF2_Fixed moveDown = FT_MAX( downMoveDown, upMoveDown ); + + /* final amount to move edge or edge pair */ + CF2_Fixed move; + + CF2_Fixed downMinCounter = CF2_MIN_COUNTER; + CF2_Fixed upMinCounter = CF2_MIN_COUNTER; + FT_Bool saveEdge = FALSE; + + + /* minimum counter constraint doesn't apply when adjacent edges */ + /* are synthetic */ + /* TODO: doesn't seem a big effect; for now, reduce the code */ +#if 0 + if ( i == 0 || + cf2_hint_isSynthetic( &hintmap->edge[i - 1] ) ) + downMinCounter = 0; + + if ( j >= hintmap->count - 1 || + cf2_hint_isSynthetic( &hintmap->edge[j + 1] ) ) + upMinCounter = 0; +#endif + + /* is there room to move up? */ + /* there is if we are at top of array or the next edge is at or */ + /* beyond proposed move up? */ + if ( j >= hintmap->count - 1 || + hintmap->edge[j + 1].dsCoord >= + ADD_INT32( hintmap->edge[j].dsCoord, + moveUp + upMinCounter ) ) + { + /* there is room to move up; is there also room to move down? */ + if ( i == 0 || + hintmap->edge[i - 1].dsCoord <= + ADD_INT32( hintmap->edge[i].dsCoord, + moveDown - downMinCounter ) ) + { + /* move smaller absolute amount */ + move = ( -moveDown < moveUp ) ? moveDown : moveUp; /* optimum */ + } + else + move = moveUp; + } + else + { + /* is there room to move down? */ + if ( i == 0 || + hintmap->edge[i - 1].dsCoord <= + ADD_INT32( hintmap->edge[i].dsCoord, + moveDown - downMinCounter ) ) + { + move = moveDown; + /* true if non-optimum move */ + saveEdge = (FT_Bool)( moveUp < -moveDown ); + } + else + { + /* no room to move either way without overlapping or reducing */ + /* the counter too much */ + move = 0; + saveEdge = TRUE; + } + } + + /* Identify non-moves and moves down that aren't optimal, and save */ + /* them for second pass. */ + /* Do this only if there is an unlocked edge above (which could */ + /* possibly move). */ + if ( saveEdge && + j < hintmap->count - 1 && + !cf2_hint_isLocked( &hintmap->edge[j + 1] ) ) + { + CF2_HintMoveRec savedMove; + + + savedMove.j = j; + /* desired adjustment in second pass */ + savedMove.moveUp = moveUp - move; + + cf2_arrstack_push( hintmap->hintMoves, &savedMove ); + } + + /* move the edge(s) */ + hintmap->edge[i].dsCoord = ADD_INT32( hintmap->edge[i].dsCoord, + move ); + if ( isPair ) + hintmap->edge[j].dsCoord = ADD_INT32( hintmap->edge[j].dsCoord, + move ); + } + + /* assert there are no overlaps in device space */ + FT_ASSERT( i == 0 || + hintmap->edge[i - 1].dsCoord <= hintmap->edge[i].dsCoord ); + FT_ASSERT( i < j || + hintmap->edge[i].dsCoord <= hintmap->edge[j].dsCoord ); + + /* adjust the scales, avoiding divide by zero */ + if ( i > 0 ) + { + if ( hintmap->edge[i].csCoord != hintmap->edge[i - 1].csCoord ) + hintmap->edge[i - 1].scale = + FT_DivFix( SUB_INT32( hintmap->edge[i].dsCoord, + hintmap->edge[i - 1].dsCoord ), + SUB_INT32( hintmap->edge[i].csCoord, + hintmap->edge[i - 1].csCoord ) ); + } + + if ( isPair ) + { + if ( hintmap->edge[j].csCoord != hintmap->edge[j - 1].csCoord ) + hintmap->edge[j - 1].scale = + FT_DivFix( SUB_INT32( hintmap->edge[j].dsCoord, + hintmap->edge[j - 1].dsCoord ), + SUB_INT32( hintmap->edge[j].csCoord, + hintmap->edge[j - 1].csCoord ) ); + + i += 1; /* skip upper edge on next loop */ + } + } + + /* second pass tries to move non-optimal hints up, in case there is */ + /* room now */ + for ( i = cf2_arrstack_size( hintmap->hintMoves ); i > 0; i-- ) + { + CF2_HintMove hintMove = (CF2_HintMove) + cf2_arrstack_getPointer( hintmap->hintMoves, i - 1 ); + + + j = hintMove->j; + + /* this was tested before the push, above */ + FT_ASSERT( j < hintmap->count - 1 ); + + /* is there room to move up? */ + if ( hintmap->edge[j + 1].dsCoord >= + ADD_INT32( hintmap->edge[j].dsCoord, + hintMove->moveUp + CF2_MIN_COUNTER ) ) + { + /* there is more room now, move edge up */ + hintmap->edge[j].dsCoord = ADD_INT32( hintmap->edge[j].dsCoord, + hintMove->moveUp ); + + if ( cf2_hint_isPair( &hintmap->edge[j] ) ) + { + FT_ASSERT( j > 0 ); + hintmap->edge[j - 1].dsCoord = + ADD_INT32( hintmap->edge[j - 1].dsCoord, hintMove->moveUp ); + } + } + } + } + + + /* insert hint edges into map, sorted by csCoord */ + static void + cf2_hintmap_insertHint( CF2_HintMap hintmap, + CF2_Hint bottomHintEdge, + CF2_Hint topHintEdge ) + { + CF2_UInt indexInsert; + + /* set default values, then check for edge hints */ + FT_Bool isPair = TRUE; + CF2_Hint firstHintEdge = bottomHintEdge; + CF2_Hint secondHintEdge = topHintEdge; + + + /* one or none of the input params may be invalid when dealing with */ + /* edge hints; at least one edge must be valid */ + FT_ASSERT( cf2_hint_isValid( bottomHintEdge ) || + cf2_hint_isValid( topHintEdge ) ); + + /* determine how many and which edges to insert */ + if ( !cf2_hint_isValid( bottomHintEdge ) ) + { + /* insert only the top edge */ + firstHintEdge = topHintEdge; + isPair = FALSE; + } + else if ( !cf2_hint_isValid( topHintEdge ) ) + { + /* insert only the bottom edge */ + isPair = FALSE; + } + + /* paired edges must be in proper order */ + if ( isPair && + topHintEdge->csCoord < bottomHintEdge->csCoord ) + return; + + /* linear search to find index value of insertion point */ + indexInsert = 0; + for ( ; indexInsert < hintmap->count; indexInsert++ ) + { + if ( hintmap->edge[indexInsert].csCoord >= firstHintEdge->csCoord ) + break; + } + + FT_TRACE7(( " Got hint at %.2f (%.2f)\n", + firstHintEdge->csCoord / 65536.0, + firstHintEdge->dsCoord / 65536.0 )); + if ( isPair ) + FT_TRACE7(( " Got hint at %.2f (%.2f)\n", + secondHintEdge->csCoord / 65536.0, + secondHintEdge->dsCoord / 65536.0 )); + + /* + * Discard any hints that overlap in character space. Most often, this + * is while building the initial map, where captured hints from all + * zones are combined. Define overlap to include hints that `touch' + * (overlap zero). Hiragino Sans/Gothic fonts have numerous hints that + * touch. Some fonts have non-ideographic glyphs that overlap our + * synthetic hints. + * + * Overlap also occurs when darkening stem hints that are close. + * + */ + if ( indexInsert < hintmap->count ) + { + /* we are inserting before an existing edge: */ + /* verify that an existing edge is not the same */ + if ( hintmap->edge[indexInsert].csCoord == firstHintEdge->csCoord ) + return; /* ignore overlapping stem hint */ + + /* verify that a new pair does not straddle the next edge */ + if ( isPair && + hintmap->edge[indexInsert].csCoord <= secondHintEdge->csCoord ) + return; /* ignore overlapping stem hint */ + + /* verify that we are not inserting between paired edges */ + if ( cf2_hint_isPairTop( &hintmap->edge[indexInsert] ) ) + return; /* ignore overlapping stem hint */ + } + + /* recompute device space locations using initial hint map */ + if ( cf2_hintmap_isValid( hintmap->initialHintMap ) && + !cf2_hint_isLocked( firstHintEdge ) ) + { + if ( isPair ) + { + /* Use hint map to position the center of stem, and nominal scale */ + /* to position the two edges. This preserves the stem width. */ + CF2_Fixed midpoint = + cf2_hintmap_map( + hintmap->initialHintMap, + ADD_INT32( secondHintEdge->csCoord, + firstHintEdge->csCoord ) / 2 ); + CF2_Fixed halfWidth = + FT_MulFix( SUB_INT32( secondHintEdge->csCoord, + firstHintEdge->csCoord ) / 2, + hintmap->scale ); + + + firstHintEdge->dsCoord = SUB_INT32( midpoint, halfWidth ); + secondHintEdge->dsCoord = ADD_INT32( midpoint, halfWidth ); + } + else + firstHintEdge->dsCoord = cf2_hintmap_map( hintmap->initialHintMap, + firstHintEdge->csCoord ); + } + + /* + * Discard any hints that overlap in device space; this can occur + * because locked hints have been moved to align with blue zones. + * + * TODO: Although we might correct this later during adjustment, we + * don't currently have a way to delete a conflicting hint once it has + * been inserted. See v2.030 MinionPro-Regular, 12 ppem darkened, + * initial hint map for second path, glyph 945 (the perispomeni (tilde) + * in U+1F6E, Greek omega with psili and perispomeni). Darkening is + * 25. Pair 667,747 initially conflicts in design space with top edge + * 660. This is because 667 maps to 7.87, and the top edge was + * captured by a zone at 8.0. The pair is later successfully inserted + * in a zone without the top edge. In this zone it is adjusted to 8.0, + * and no longer conflicts with the top edge in design space. This + * means it can be included in yet a later zone which does have the top + * edge hint. This produces a small mismatch between the first and + * last points of this path, even though the hint masks are the same. + * The density map difference is tiny (1/256). + * + */ + + if ( indexInsert > 0 ) + { + /* we are inserting after an existing edge */ + if ( firstHintEdge->dsCoord < hintmap->edge[indexInsert - 1].dsCoord ) + return; + } + + if ( indexInsert < hintmap->count ) + { + /* we are inserting before an existing edge */ + if ( isPair ) + { + if ( secondHintEdge->dsCoord > hintmap->edge[indexInsert].dsCoord ) + return; + } + else + { + if ( firstHintEdge->dsCoord > hintmap->edge[indexInsert].dsCoord ) + return; + } + } + + /* make room to insert */ + { + CF2_UInt iSrc = hintmap->count - 1; + CF2_UInt iDst = isPair ? hintmap->count + 1 : hintmap->count; + + CF2_UInt count = hintmap->count - indexInsert; + + + if ( iDst >= CF2_MAX_HINT_EDGES ) + { + FT_TRACE4(( "cf2_hintmap_insertHint: too many hintmaps\n" )); + return; + } + + while ( count-- ) + hintmap->edge[iDst--] = hintmap->edge[iSrc--]; + + /* insert first edge */ + hintmap->edge[indexInsert] = *firstHintEdge; /* copy struct */ + hintmap->count += 1; + + FT_TRACE7(( " Inserting hint %.2f (%.2f)\n", + firstHintEdge->csCoord / 65536.0, + firstHintEdge->dsCoord / 65536.0 )); + + if ( isPair ) + { + /* insert second edge */ + hintmap->edge[indexInsert + 1] = *secondHintEdge; /* copy struct */ + hintmap->count += 1; + + FT_TRACE7(( " Inserting hint %.2f (%.2f)\n", + secondHintEdge->csCoord / 65536.0, + secondHintEdge->dsCoord / 65536.0 )); + + } + } + + return; + } + + + /* + * Build a map from hints and mask. + * + * This function may recur one level if `hintmap->initialHintMap' is not yet + * valid. + * If `initialMap' is true, simply build initial map. + * + * Synthetic hints are used in two ways. A hint at zero is inserted, if + * needed, in the initial hint map, to prevent translations from + * propagating across the origin. If synthetic em box hints are enabled + * for ideographic dictionaries, then they are inserted in all hint + * maps, including the initial one. + * + */ + FT_LOCAL_DEF( void ) + cf2_hintmap_build( CF2_HintMap hintmap, + CF2_ArrStack hStemHintArray, + CF2_ArrStack vStemHintArray, + CF2_HintMask hintMask, + CF2_Fixed hintOrigin, + FT_Bool initialMap ) + { + FT_Byte* maskPtr; + + CF2_Font font = hintmap->font; + CF2_HintMaskRec tempHintMask; + + size_t bitCount, i; + FT_Byte maskByte; + + + /* check whether initial map is constructed */ + if ( !initialMap && !cf2_hintmap_isValid( hintmap->initialHintMap ) ) + { + /* make recursive call with initialHintMap and temporary mask; */ + /* temporary mask will get all bits set, below */ + cf2_hintmask_init( &tempHintMask, hintMask->error ); + cf2_hintmap_build( hintmap->initialHintMap, + hStemHintArray, + vStemHintArray, + &tempHintMask, + hintOrigin, + TRUE ); + } + + if ( !cf2_hintmask_isValid( hintMask ) ) + { + /* without a hint mask, assume all hints are active */ + cf2_hintmask_setAll( hintMask, + cf2_arrstack_size( hStemHintArray ) + + cf2_arrstack_size( vStemHintArray ) ); + if ( !cf2_hintmask_isValid( hintMask ) ) + { + if ( font->isT1 ) + { + /* no error, just continue unhinted */ + *hintMask->error = FT_Err_Ok; + hintmap->hinted = FALSE; + } + return; /* too many stem hints */ + } + } + + /* begin by clearing the map */ + hintmap->count = 0; + hintmap->lastIndex = 0; + + /* make a copy of the hint mask so we can modify it */ + tempHintMask = *hintMask; + maskPtr = cf2_hintmask_getMaskPtr( &tempHintMask ); + + /* use the hStem hints only, which are first in the mask */ + bitCount = cf2_arrstack_size( hStemHintArray ); + + /* Defense-in-depth. Should never return here. */ + if ( bitCount > hintMask->bitCount ) + return; + + /* synthetic embox hints get highest priority */ + if ( font->blues.doEmBoxHints ) + { + CF2_HintRec dummy; + + + cf2_hint_initZero( &dummy ); /* invalid hint map element */ + + /* ghost bottom */ + cf2_hintmap_insertHint( hintmap, + &font->blues.emBoxBottomEdge, + &dummy ); + /* ghost top */ + cf2_hintmap_insertHint( hintmap, + &dummy, + &font->blues.emBoxTopEdge ); + } + + /* insert hints captured by a blue zone or already locked (higher */ + /* priority) */ + for ( i = 0, maskByte = 0x80; i < bitCount; i++ ) + { + if ( maskByte & *maskPtr ) + { + /* expand StemHint into two `CF2_Hint' elements */ + CF2_HintRec bottomHintEdge, topHintEdge; + + + cf2_hint_init( &bottomHintEdge, + hStemHintArray, + i, + font, + hintOrigin, + hintmap->scale, + TRUE /* bottom */ ); + cf2_hint_init( &topHintEdge, + hStemHintArray, + i, + font, + hintOrigin, + hintmap->scale, + FALSE /* top */ ); + + if ( cf2_hint_isLocked( &bottomHintEdge ) || + cf2_hint_isLocked( &topHintEdge ) || + cf2_blues_capture( &font->blues, + &bottomHintEdge, + &topHintEdge ) ) + { + /* insert captured hint into map */ + cf2_hintmap_insertHint( hintmap, &bottomHintEdge, &topHintEdge ); + + *maskPtr &= ~maskByte; /* turn off the bit for this hint */ + } + } + + if ( ( i & 7 ) == 7 ) + { + /* move to next mask byte */ + maskPtr++; + maskByte = 0x80; + } + else + maskByte >>= 1; + } + + /* initial hint map includes only captured hints plus maybe one at 0 */ + + /* + * TODO: There is a problem here because we are trying to build a + * single hint map containing all captured hints. It is + * possible for there to be conflicts between captured hints, + * either because of darkening or because the hints are in + * separate hint zones (we are ignoring hint zones for the + * initial map). An example of the latter is MinionPro-Regular + * v2.030 glyph 883 (Greek Capital Alpha with Psili) at 15ppem. + * A stem hint for the psili conflicts with the top edge hint + * for the base character. The stem hint gets priority because + * of its sort order. In glyph 884 (Greek Capital Alpha with + * Psili and Oxia), the top of the base character gets a stem + * hint, and the psili does not. This creates different initial + * maps for the two glyphs resulting in different renderings of + * the base character. Will probably defer this either as not + * worth the cost or as a font bug. I don't think there is any + * good reason for an accent to be captured by an alignment + * zone. -darnold 2/12/10 + */ + + if ( initialMap ) + { + /* Apply a heuristic that inserts a point for (0,0), unless it's */ + /* already covered by a mapping. This locks the baseline for glyphs */ + /* that have no baseline hints. */ + + if ( hintmap->count == 0 || + hintmap->edge[0].csCoord > 0 || + hintmap->edge[hintmap->count - 1].csCoord < 0 ) + { + /* all edges are above 0 or all edges are below 0; */ + /* construct a locked edge hint at 0 */ + + CF2_HintRec edge, invalid; + + + cf2_hint_initZero( &edge ); + + edge.flags = CF2_GhostBottom | + CF2_Locked | + CF2_Synthetic; + edge.scale = hintmap->scale; + + cf2_hint_initZero( &invalid ); + cf2_hintmap_insertHint( hintmap, &edge, &invalid ); + } + } + else + { + /* insert remaining hints */ + + maskPtr = cf2_hintmask_getMaskPtr( &tempHintMask ); + + for ( i = 0, maskByte = 0x80; i < bitCount; i++ ) + { + if ( maskByte & *maskPtr ) + { + CF2_HintRec bottomHintEdge, topHintEdge; + + + cf2_hint_init( &bottomHintEdge, + hStemHintArray, + i, + font, + hintOrigin, + hintmap->scale, + TRUE /* bottom */ ); + cf2_hint_init( &topHintEdge, + hStemHintArray, + i, + font, + hintOrigin, + hintmap->scale, + FALSE /* top */ ); + + cf2_hintmap_insertHint( hintmap, &bottomHintEdge, &topHintEdge ); + } + + if ( ( i & 7 ) == 7 ) + { + /* move to next mask byte */ + maskPtr++; + maskByte = 0x80; + } + else + maskByte >>= 1; + } + } + + FT_TRACE6(( initialMap ? "flags: [p]air [g]host [t]op " + "[b]ottom [L]ocked [S]ynthetic\n" + "Initial hintmap\n" + : "Hints:\n" )); + cf2_hintmap_dump( hintmap ); + + /* + * Note: The following line is a convenient place to break when + * debugging hinting. Examine `hintmap->edge' for the list of + * enabled hints, then step over the call to see the effect of + * adjustment. We stop here first on the recursive call that + * creates the initial map, and then on each counter group and + * hint zone. + */ + + /* adjust positions of hint edges that are not locked to blue zones */ + cf2_hintmap_adjustHints( hintmap ); + + FT_TRACE6(( "(adjusted)\n" )); + cf2_hintmap_dump( hintmap ); + + /* save the position of all hints that were used in this hint map; */ + /* if we use them again, we'll locate them in the same position */ + if ( !initialMap ) + { + for ( i = 0; i < hintmap->count; i++ ) + { + if ( !cf2_hint_isSynthetic( &hintmap->edge[i] ) ) + { + /* Note: include both valid and invalid edges */ + /* Note: top and bottom edges are copied back separately */ + CF2_StemHint stemhint = (CF2_StemHint) + cf2_arrstack_getPointer( hStemHintArray, + hintmap->edge[i].index ); + + + if ( cf2_hint_isTop( &hintmap->edge[i] ) ) + stemhint->maxDS = hintmap->edge[i].dsCoord; + else + stemhint->minDS = hintmap->edge[i].dsCoord; + + stemhint->used = TRUE; + } + } + } + + /* hint map is ready to use */ + hintmap->isValid = TRUE; + + /* remember this mask has been used */ + cf2_hintmask_setNew( hintMask, FALSE ); + } + + + FT_LOCAL_DEF( void ) + cf2_glyphpath_init( CF2_GlyphPath glyphpath, + CF2_Font font, + CF2_OutlineCallbacks callbacks, + CF2_Fixed scaleY, + /* CF2_Fixed hShift, */ + CF2_ArrStack hStemHintArray, + CF2_ArrStack vStemHintArray, + CF2_HintMask hintMask, + CF2_Fixed hintOriginY, + const CF2_Blues blues, + const FT_Vector* fractionalTranslation ) + { + FT_ZERO( glyphpath ); + + glyphpath->font = font; + glyphpath->callbacks = callbacks; + + cf2_arrstack_init( &glyphpath->hintMoves, + font->memory, + &font->error, + sizeof ( CF2_HintMoveRec ) ); + + cf2_hintmap_init( &glyphpath->initialHintMap, + font, + &glyphpath->initialHintMap, + &glyphpath->hintMoves, + scaleY ); + cf2_hintmap_init( &glyphpath->firstHintMap, + font, + &glyphpath->initialHintMap, + &glyphpath->hintMoves, + scaleY ); + cf2_hintmap_init( &glyphpath->hintMap, + font, + &glyphpath->initialHintMap, + &glyphpath->hintMoves, + scaleY ); + + glyphpath->scaleX = font->innerTransform.a; + glyphpath->scaleC = font->innerTransform.c; + glyphpath->scaleY = font->innerTransform.d; + + glyphpath->fractionalTranslation = *fractionalTranslation; + +#if 0 + glyphpath->hShift = hShift; /* for fauxing */ +#endif + + glyphpath->hStemHintArray = hStemHintArray; + glyphpath->vStemHintArray = vStemHintArray; + glyphpath->hintMask = hintMask; /* ptr to current mask */ + glyphpath->hintOriginY = hintOriginY; + glyphpath->blues = blues; + glyphpath->darken = font->darkened; /* TODO: should we make copies? */ + glyphpath->xOffset = font->darkenX; + glyphpath->yOffset = font->darkenY; + glyphpath->miterLimit = 2 * FT_MAX( + cf2_fixedAbs( glyphpath->xOffset ), + cf2_fixedAbs( glyphpath->yOffset ) ); + + /* .1 character space unit */ + glyphpath->snapThreshold = cf2_doubleToFixed( 0.1 ); + + glyphpath->moveIsPending = TRUE; + glyphpath->pathIsOpen = FALSE; + glyphpath->pathIsClosing = FALSE; + glyphpath->elemIsQueued = FALSE; + } + + + FT_LOCAL_DEF( void ) + cf2_glyphpath_finalize( CF2_GlyphPath glyphpath ) + { + cf2_arrstack_finalize( &glyphpath->hintMoves ); + } + + + /* + * Hint point in y-direction and apply outerTransform. + * Input `current' hint map (which is actually delayed by one element). + * Input x,y point in Character Space. + * Output x,y point in Device Space, including translation. + */ + static void + cf2_glyphpath_hintPoint( CF2_GlyphPath glyphpath, + CF2_HintMap hintmap, + FT_Vector* ppt, + CF2_Fixed x, + CF2_Fixed y ) + { + FT_Vector pt; /* hinted point in upright DS */ + + + pt.x = ADD_INT32( FT_MulFix( glyphpath->scaleX, x ), + FT_MulFix( glyphpath->scaleC, y ) ); + pt.y = cf2_hintmap_map( hintmap, y ); + + ppt->x = ADD_INT32( + FT_MulFix( glyphpath->font->outerTransform.a, pt.x ), + ADD_INT32( + FT_MulFix( glyphpath->font->outerTransform.c, pt.y ), + glyphpath->fractionalTranslation.x ) ); + ppt->y = ADD_INT32( + FT_MulFix( glyphpath->font->outerTransform.b, pt.x ), + ADD_INT32( + FT_MulFix( glyphpath->font->outerTransform.d, pt.y ), + glyphpath->fractionalTranslation.y ) ); + } + + + /* + * From two line segments, (u1,u2) and (v1,v2), compute a point of + * intersection on the corresponding lines. + * Return false if no intersection is found, or if the intersection is + * too far away from the ends of the line segments, u2 and v1. + * + */ + static FT_Bool + cf2_glyphpath_computeIntersection( CF2_GlyphPath glyphpath, + const FT_Vector* u1, + const FT_Vector* u2, + const FT_Vector* v1, + const FT_Vector* v2, + FT_Vector* intersection ) + { + /* + * Let `u' be a zero-based vector from the first segment, `v' from the + * second segment. + * Let `w 'be the zero-based vector from `u1' to `v1'. + * `perp' is the `perpendicular dot product'; see + * https://mathworld.wolfram.com/PerpDotProduct.html. + * `s' is the parameter for the parametric line for the first segment + * (`u'). + * + * See notation in + * http://softsurfer.com/Archive/algorithm_0104/algorithm_0104B.htm. + * Calculations are done in 16.16, but must handle the squaring of + * line lengths in character space. We scale all vectors by 1/32 to + * avoid overflow. This allows values up to 4095 to be squared. The + * scale factor cancels in the divide. + * + * TODO: the scale factor could be computed from UnitsPerEm. + * + */ + +#define cf2_perp( a, b ) \ + ( FT_MulFix( a.x, b.y ) - FT_MulFix( a.y, b.x ) ) + + /* round and divide by 32 */ +#define CF2_CS_SCALE( x ) \ + ( ( (x) + 0x10 ) >> 5 ) + + FT_Vector u, v, w; /* scaled vectors */ + CF2_Fixed denominator, s; + + + u.x = CF2_CS_SCALE( SUB_INT32( u2->x, u1->x ) ); + u.y = CF2_CS_SCALE( SUB_INT32( u2->y, u1->y ) ); + v.x = CF2_CS_SCALE( SUB_INT32( v2->x, v1->x ) ); + v.y = CF2_CS_SCALE( SUB_INT32( v2->y, v1->y ) ); + w.x = CF2_CS_SCALE( SUB_INT32( v1->x, u1->x ) ); + w.y = CF2_CS_SCALE( SUB_INT32( v1->y, u1->y ) ); + + denominator = cf2_perp( u, v ); + + if ( denominator == 0 ) + return FALSE; /* parallel or coincident lines */ + + s = FT_DivFix( cf2_perp( w, v ), denominator ); + + intersection->x = ADD_INT32( u1->x, + FT_MulFix( s, SUB_INT32( u2->x, u1->x ) ) ); + intersection->y = ADD_INT32( u1->y, + FT_MulFix( s, SUB_INT32( u2->y, u1->y ) ) ); + + + /* + * Special case snapping for horizontal and vertical lines. + * This cleans up intersections and reduces problems with winding + * order detection. + * Sample case is sbc cd KozGoPr6N-Medium.otf 20 16685. + * Note: these calculations are in character space. + * + */ + + if ( u1->x == u2->x && + cf2_fixedAbs( SUB_INT32( intersection->x, + u1->x ) ) < glyphpath->snapThreshold ) + intersection->x = u1->x; + if ( u1->y == u2->y && + cf2_fixedAbs( SUB_INT32( intersection->y, + u1->y ) ) < glyphpath->snapThreshold ) + intersection->y = u1->y; + + if ( v1->x == v2->x && + cf2_fixedAbs( SUB_INT32( intersection->x, + v1->x ) ) < glyphpath->snapThreshold ) + intersection->x = v1->x; + if ( v1->y == v2->y && + cf2_fixedAbs( SUB_INT32( intersection->y, + v1->y ) ) < glyphpath->snapThreshold ) + intersection->y = v1->y; + + /* limit the intersection distance from midpoint of u2 and v1 */ + if ( cf2_fixedAbs( intersection->x - ADD_INT32( u2->x, v1->x ) / 2 ) > + glyphpath->miterLimit || + cf2_fixedAbs( intersection->y - ADD_INT32( u2->y, v1->y ) / 2 ) > + glyphpath->miterLimit ) + return FALSE; + + return TRUE; + } + + + /* + * Push the cached element (glyphpath->prevElem*) to the outline + * consumer. When a darkening offset is used, the end point of the + * cached element may be adjusted to an intersection point or we may + * synthesize a connecting line to the current element. If we are + * closing a subpath, we may also generate a connecting line to the start + * point. + * + * This is where Character Space (CS) is converted to Device Space (DS) + * using a hint map. This calculation must use a HintMap that was valid + * at the time the element was saved. For the first point in a subpath, + * that is a saved HintMap. For most elements, it just means the caller + * has delayed building a HintMap from the current HintMask. + * + * Transform each point with outerTransform and call the outline + * callbacks. This is a general 3x3 transform: + * + * x' = a*x + c*y + tx, y' = b*x + d*y + ty + * + * but it uses 4 elements from CF2_Font and the translation part + * from CF2_GlyphPath. + * + */ + static void + cf2_glyphpath_pushPrevElem( CF2_GlyphPath glyphpath, + CF2_HintMap hintmap, + FT_Vector* nextP0, + FT_Vector nextP1, + FT_Bool close ) + { + CF2_CallbackParamsRec params; + + FT_Vector* prevP0; + FT_Vector* prevP1; + + FT_Vector intersection = { 0, 0 }; + FT_Bool useIntersection = FALSE; + + + FT_ASSERT( glyphpath->prevElemOp == CF2_PathOpLineTo || + glyphpath->prevElemOp == CF2_PathOpCubeTo ); + + if ( glyphpath->prevElemOp == CF2_PathOpLineTo ) + { + prevP0 = &glyphpath->prevElemP0; + prevP1 = &glyphpath->prevElemP1; + } + else + { + prevP0 = &glyphpath->prevElemP2; + prevP1 = &glyphpath->prevElemP3; + } + + /* optimization: if previous and next elements are offset by the same */ + /* amount, then there will be no gap, and no need to compute an */ + /* intersection. */ + if ( prevP1->x != nextP0->x || prevP1->y != nextP0->y ) + { + /* previous element does not join next element: */ + /* adjust end point of previous element to the intersection */ + useIntersection = cf2_glyphpath_computeIntersection( glyphpath, + prevP0, + prevP1, + nextP0, + &nextP1, + &intersection ); + if ( useIntersection ) + { + /* modify the last point of the cached element (either line or */ + /* curve) */ + *prevP1 = intersection; + } + } + + params.pt0 = glyphpath->currentDS; + + switch( glyphpath->prevElemOp ) + { + case CF2_PathOpLineTo: + params.op = CF2_PathOpLineTo; + + /* note: pt2 and pt3 are unused */ + + if ( close ) + { + /* use first hint map if closing */ + cf2_glyphpath_hintPoint( glyphpath, + &glyphpath->firstHintMap, + ¶ms.pt1, + glyphpath->prevElemP1.x, + glyphpath->prevElemP1.y ); + } + else + { + cf2_glyphpath_hintPoint( glyphpath, + hintmap, + ¶ms.pt1, + glyphpath->prevElemP1.x, + glyphpath->prevElemP1.y ); + } + + /* output only non-zero length lines */ + if ( params.pt0.x != params.pt1.x || params.pt0.y != params.pt1.y ) + { + glyphpath->callbacks->lineTo( glyphpath->callbacks, ¶ms ); + + glyphpath->currentDS = params.pt1; + } + break; + + case CF2_PathOpCubeTo: + params.op = CF2_PathOpCubeTo; + + /* TODO: should we intersect the interior joins (p1-p2 and p2-p3)? */ + cf2_glyphpath_hintPoint( glyphpath, + hintmap, + ¶ms.pt1, + glyphpath->prevElemP1.x, + glyphpath->prevElemP1.y ); + cf2_glyphpath_hintPoint( glyphpath, + hintmap, + ¶ms.pt2, + glyphpath->prevElemP2.x, + glyphpath->prevElemP2.y ); + cf2_glyphpath_hintPoint( glyphpath, + hintmap, + ¶ms.pt3, + glyphpath->prevElemP3.x, + glyphpath->prevElemP3.y ); + + glyphpath->callbacks->cubeTo( glyphpath->callbacks, ¶ms ); + + glyphpath->currentDS = params.pt3; + + break; + } + + if ( !useIntersection || close ) + { + /* insert connecting line between end of previous element and start */ + /* of current one */ + /* note: at the end of a subpath, we might do both, so use `nextP0' */ + /* before we change it, below */ + + if ( close ) + { + /* if we are closing the subpath, then nextP0 is in the first */ + /* hint zone */ + cf2_glyphpath_hintPoint( glyphpath, + &glyphpath->firstHintMap, + ¶ms.pt1, + nextP0->x, + nextP0->y ); + } + else + { + cf2_glyphpath_hintPoint( glyphpath, + hintmap, + ¶ms.pt1, + nextP0->x, + nextP0->y ); + } + + if ( params.pt1.x != glyphpath->currentDS.x || + params.pt1.y != glyphpath->currentDS.y ) + { + /* length is nonzero */ + params.op = CF2_PathOpLineTo; + params.pt0 = glyphpath->currentDS; + + /* note: pt2 and pt3 are unused */ + glyphpath->callbacks->lineTo( glyphpath->callbacks, ¶ms ); + + glyphpath->currentDS = params.pt1; + } + } + + if ( useIntersection ) + { + /* return intersection point to caller */ + *nextP0 = intersection; + } + } + + + /* push a MoveTo element based on current point and offset of current */ + /* element */ + static void + cf2_glyphpath_pushMove( CF2_GlyphPath glyphpath, + FT_Vector start ) + { + CF2_CallbackParamsRec params; + + + params.op = CF2_PathOpMoveTo; + params.pt0 = glyphpath->currentDS; + + /* Test if move has really happened yet; it would have called */ + /* `cf2_hintmap_build' to set `isValid'. */ + if ( !cf2_hintmap_isValid( &glyphpath->hintMap ) ) + { + /* we are here iff first subpath is missing a moveto operator: */ + /* synthesize first moveTo to finish initialization of hintMap */ + cf2_glyphpath_moveTo( glyphpath, + glyphpath->start.x, + glyphpath->start.y ); + } + + cf2_glyphpath_hintPoint( glyphpath, + &glyphpath->hintMap, + ¶ms.pt1, + start.x, + start.y ); + + /* note: pt2 and pt3 are unused */ + glyphpath->callbacks->moveTo( glyphpath->callbacks, ¶ms ); + + glyphpath->currentDS = params.pt1; + glyphpath->offsetStart0 = start; + } + + + /* + * All coordinates are in character space. + * On input, (x1, y1) and (x2, y2) give line segment. + * On output, (x, y) give offset vector. + * We use a piecewise approximation to trig functions. + * + * TODO: Offset true perpendicular and proper length + * supply the y-translation for hinting here, too, + * that adds yOffset unconditionally to *y. + */ + static void + cf2_glyphpath_computeOffset( CF2_GlyphPath glyphpath, + CF2_Fixed x1, + CF2_Fixed y1, + CF2_Fixed x2, + CF2_Fixed y2, + CF2_Fixed* x, + CF2_Fixed* y ) + { + CF2_Fixed dx = SUB_INT32( x2, x1 ); + CF2_Fixed dy = SUB_INT32( y2, y1 ); + + + /* note: negative offsets don't work here; negate deltas to change */ + /* quadrants, below */ + if ( glyphpath->font->reverseWinding ) + { + dx = NEG_INT32( dx ); + dy = NEG_INT32( dy ); + } + + *x = *y = 0; + + if ( !glyphpath->darken ) + return; + + /* add momentum for this path element */ + glyphpath->callbacks->windingMomentum = + ADD_INT32( glyphpath->callbacks->windingMomentum, + cf2_getWindingMomentum( x1, y1, x2, y2 ) ); + + /* note: allow mixed integer and fixed multiplication here */ + if ( dx >= 0 ) + { + if ( dy >= 0 ) + { + /* first quadrant, +x +y */ + + if ( dx > MUL_INT32( 2, dy ) ) + { + /* +x */ + *x = 0; + *y = 0; + } + else if ( dy > MUL_INT32( 2, dx ) ) + { + /* +y */ + *x = glyphpath->xOffset; + *y = glyphpath->yOffset; + } + else + { + /* +x +y */ + *x = FT_MulFix( cf2_doubleToFixed( 0.7 ), + glyphpath->xOffset ); + *y = FT_MulFix( cf2_doubleToFixed( 1.0 - 0.7 ), + glyphpath->yOffset ); + } + } + else + { + /* fourth quadrant, +x -y */ + + if ( dx > MUL_INT32( -2, dy ) ) + { + /* +x */ + *x = 0; + *y = 0; + } + else if ( NEG_INT32( dy ) > MUL_INT32( 2, dx ) ) + { + /* -y */ + *x = NEG_INT32( glyphpath->xOffset ); + *y = glyphpath->yOffset; + } + else + { + /* +x -y */ + *x = FT_MulFix( cf2_doubleToFixed( -0.7 ), + glyphpath->xOffset ); + *y = FT_MulFix( cf2_doubleToFixed( 1.0 - 0.7 ), + glyphpath->yOffset ); + } + } + } + else + { + if ( dy >= 0 ) + { + /* second quadrant, -x +y */ + + if ( NEG_INT32( dx ) > MUL_INT32( 2, dy ) ) + { + /* -x */ + *x = 0; + *y = MUL_INT32( 2, glyphpath->yOffset ); + } + else if ( dy > MUL_INT32( -2, dx ) ) + { + /* +y */ + *x = glyphpath->xOffset; + *y = glyphpath->yOffset; + } + else + { + /* -x +y */ + *x = FT_MulFix( cf2_doubleToFixed( 0.7 ), + glyphpath->xOffset ); + *y = FT_MulFix( cf2_doubleToFixed( 1.0 + 0.7 ), + glyphpath->yOffset ); + } + } + else + { + /* third quadrant, -x -y */ + + if ( NEG_INT32( dx ) > MUL_INT32( -2, dy ) ) + { + /* -x */ + *x = 0; + *y = MUL_INT32( 2, glyphpath->yOffset ); + } + else if ( NEG_INT32( dy ) > MUL_INT32( -2, dx ) ) + { + /* -y */ + *x = NEG_INT32( glyphpath->xOffset ); + *y = glyphpath->yOffset; + } + else + { + /* -x -y */ + *x = FT_MulFix( cf2_doubleToFixed( -0.7 ), + glyphpath->xOffset ); + *y = FT_MulFix( cf2_doubleToFixed( 1.0 + 0.7 ), + glyphpath->yOffset ); + } + } + } + } + + + /* + * The functions cf2_glyphpath_{moveTo,lineTo,curveTo,closeOpenPath} are + * called by the interpreter with Character Space (CS) coordinates. Each + * path element is placed into a queue of length one to await the + * calculation of the following element. At that time, the darkening + * offset of the following element is known and joins can be computed, + * including possible modification of this element, before mapping to + * Device Space (DS) and passing it on to the outline consumer. + * + */ + FT_LOCAL_DEF( void ) + cf2_glyphpath_moveTo( CF2_GlyphPath glyphpath, + CF2_Fixed x, + CF2_Fixed y ) + { + cf2_glyphpath_closeOpenPath( glyphpath ); + + /* save the parameters of the move for later, when we'll know how to */ + /* offset it; */ + /* also save last move point */ + glyphpath->currentCS.x = glyphpath->start.x = x; + glyphpath->currentCS.y = glyphpath->start.y = y; + + glyphpath->moveIsPending = TRUE; + + /* ensure we have a valid map with current mask */ + if ( !cf2_hintmap_isValid( &glyphpath->hintMap ) || + cf2_hintmask_isNew( glyphpath->hintMask ) ) + cf2_hintmap_build( &glyphpath->hintMap, + glyphpath->hStemHintArray, + glyphpath->vStemHintArray, + glyphpath->hintMask, + glyphpath->hintOriginY, + FALSE ); + + /* save a copy of current HintMap to use when drawing initial point */ + glyphpath->firstHintMap = glyphpath->hintMap; /* structure copy */ + } + + + FT_LOCAL_DEF( void ) + cf2_glyphpath_lineTo( CF2_GlyphPath glyphpath, + CF2_Fixed x, + CF2_Fixed y ) + { + CF2_Fixed xOffset, yOffset; + FT_Vector P0, P1; + FT_Bool newHintMap; + + /* + * New hints will be applied after cf2_glyphpath_pushPrevElem has run. + * In case this is a synthesized closing line, any new hints should be + * delayed until this path is closed (`cf2_hintmask_isNew' will be + * called again before the next line or curve). + */ + + /* true if new hint map not on close */ + newHintMap = cf2_hintmask_isNew( glyphpath->hintMask ) && + !glyphpath->pathIsClosing; + + /* + * Zero-length lines may occur in the charstring. Because we cannot + * compute darkening offsets or intersections from zero-length lines, + * it is best to remove them and avoid artifacts. However, zero-length + * lines in CS at the start of a new hint map can generate non-zero + * lines in DS due to hint substitution. We detect a change in hint + * map here and pass those zero-length lines along. + */ + + /* + * Note: Find explicitly closed paths here with a conditional + * breakpoint using + * + * !gp->pathIsClosing && gp->start.x == x && gp->start.y == y + * + */ + + if ( glyphpath->currentCS.x == x && + glyphpath->currentCS.y == y && + !newHintMap ) + /* + * Ignore zero-length lines in CS where the hint map is the same + * because the line in DS will also be zero length. + * + * Ignore zero-length lines when we synthesize a closing line because + * the close will be handled in cf2_glyphPath_pushPrevElem. + */ + return; + + cf2_glyphpath_computeOffset( glyphpath, + glyphpath->currentCS.x, + glyphpath->currentCS.y, + x, + y, + &xOffset, + &yOffset ); + + /* construct offset points */ + P0.x = ADD_INT32( glyphpath->currentCS.x, xOffset ); + P0.y = ADD_INT32( glyphpath->currentCS.y, yOffset ); + P1.x = ADD_INT32( x, xOffset ); + P1.y = ADD_INT32( y, yOffset ); + + if ( glyphpath->moveIsPending ) + { + /* emit offset 1st point as MoveTo */ + cf2_glyphpath_pushMove( glyphpath, P0 ); + + glyphpath->moveIsPending = FALSE; /* adjust state machine */ + glyphpath->pathIsOpen = TRUE; + + glyphpath->offsetStart1 = P1; /* record second point */ + } + + if ( glyphpath->elemIsQueued ) + { + FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) || + glyphpath->hintMap.count == 0 ); + + cf2_glyphpath_pushPrevElem( glyphpath, + &glyphpath->hintMap, + &P0, + P1, + FALSE ); + } + + /* queue the current element with offset points */ + glyphpath->elemIsQueued = TRUE; + glyphpath->prevElemOp = CF2_PathOpLineTo; + glyphpath->prevElemP0 = P0; + glyphpath->prevElemP1 = P1; + + /* update current map */ + if ( newHintMap ) + cf2_hintmap_build( &glyphpath->hintMap, + glyphpath->hStemHintArray, + glyphpath->vStemHintArray, + glyphpath->hintMask, + glyphpath->hintOriginY, + FALSE ); + + glyphpath->currentCS.x = x; /* pre-offset current point */ + glyphpath->currentCS.y = y; + } + + + FT_LOCAL_DEF( void ) + cf2_glyphpath_curveTo( CF2_GlyphPath glyphpath, + CF2_Fixed x1, + CF2_Fixed y1, + CF2_Fixed x2, + CF2_Fixed y2, + CF2_Fixed x3, + CF2_Fixed y3 ) + { + CF2_Fixed xOffset1, yOffset1, xOffset3, yOffset3; + FT_Vector P0, P1, P2, P3; + + + /* TODO: ignore zero length portions of curve?? */ + cf2_glyphpath_computeOffset( glyphpath, + glyphpath->currentCS.x, + glyphpath->currentCS.y, + x1, + y1, + &xOffset1, + &yOffset1 ); + cf2_glyphpath_computeOffset( glyphpath, + x2, + y2, + x3, + y3, + &xOffset3, + &yOffset3 ); + + /* add momentum from the middle segment */ + glyphpath->callbacks->windingMomentum = + ADD_INT32( glyphpath->callbacks->windingMomentum, + cf2_getWindingMomentum( x1, y1, x2, y2 ) ); + + /* construct offset points */ + P0.x = ADD_INT32( glyphpath->currentCS.x, xOffset1 ); + P0.y = ADD_INT32( glyphpath->currentCS.y, yOffset1 ); + P1.x = ADD_INT32( x1, xOffset1 ); + P1.y = ADD_INT32( y1, yOffset1 ); + /* note: preserve angle of final segment by using offset3 at both ends */ + P2.x = ADD_INT32( x2, xOffset3 ); + P2.y = ADD_INT32( y2, yOffset3 ); + P3.x = ADD_INT32( x3, xOffset3 ); + P3.y = ADD_INT32( y3, yOffset3 ); + + if ( glyphpath->moveIsPending ) + { + /* emit offset 1st point as MoveTo */ + cf2_glyphpath_pushMove( glyphpath, P0 ); + + glyphpath->moveIsPending = FALSE; + glyphpath->pathIsOpen = TRUE; + + glyphpath->offsetStart1 = P1; /* record second point */ + } + + if ( glyphpath->elemIsQueued ) + { + FT_ASSERT( cf2_hintmap_isValid( &glyphpath->hintMap ) || + glyphpath->hintMap.count == 0 ); + + cf2_glyphpath_pushPrevElem( glyphpath, + &glyphpath->hintMap, + &P0, + P1, + FALSE ); + } + + /* queue the current element with offset points */ + glyphpath->elemIsQueued = TRUE; + glyphpath->prevElemOp = CF2_PathOpCubeTo; + glyphpath->prevElemP0 = P0; + glyphpath->prevElemP1 = P1; + glyphpath->prevElemP2 = P2; + glyphpath->prevElemP3 = P3; + + /* update current map */ + if ( cf2_hintmask_isNew( glyphpath->hintMask ) ) + cf2_hintmap_build( &glyphpath->hintMap, + glyphpath->hStemHintArray, + glyphpath->vStemHintArray, + glyphpath->hintMask, + glyphpath->hintOriginY, + FALSE ); + + glyphpath->currentCS.x = x3; /* pre-offset current point */ + glyphpath->currentCS.y = y3; + } + + + FT_LOCAL_DEF( void ) + cf2_glyphpath_closeOpenPath( CF2_GlyphPath glyphpath ) + { + if ( glyphpath->pathIsOpen ) + { + /* + * A closing line in Character Space line is always generated below + * with `cf2_glyphPath_lineTo'. It may be ignored later if it turns + * out to be zero length in Device Space. + */ + glyphpath->pathIsClosing = TRUE; + + cf2_glyphpath_lineTo( glyphpath, + glyphpath->start.x, + glyphpath->start.y ); + + /* empty the final element from the queue and close the path */ + if ( glyphpath->elemIsQueued ) + cf2_glyphpath_pushPrevElem( glyphpath, + &glyphpath->hintMap, + &glyphpath->offsetStart0, + glyphpath->offsetStart1, + TRUE ); + + /* reset state machine */ + glyphpath->moveIsPending = TRUE; + glyphpath->pathIsOpen = FALSE; + glyphpath->pathIsClosing = FALSE; + glyphpath->elemIsQueued = FALSE; + } + } + + +/* END */ diff --git a/src/3rdparty/freetype/src/psaux/pshints.h b/src/3rdparty/freetype/src/psaux/pshints.h new file mode 100644 index 0000000000..92e37e98ae --- /dev/null +++ b/src/3rdparty/freetype/src/psaux/pshints.h @@ -0,0 +1,288 @@ +/***************************************************************************/ +/* */ +/* pshints.h */ +/* */ +/* Adobe's code for handling CFF hints (body). */ +/* */ +/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#ifndef PSHINT_H_ +#define PSHINT_H_ + +FT_BEGIN_HEADER + + + enum + { + CF2_MAX_HINTS = 96 /* maximum # of hints */ + }; + + + /* + * A HintMask object stores a bit mask that specifies which hints in the + * charstring are active at a given time. Hints in CFF must be declared + * at the start, before any drawing operators, with horizontal hints + * preceding vertical hints. The HintMask is ordered the same way, with + * horizontal hints immediately followed by vertical hints. Clients are + * responsible for knowing how many of each type are present. + * + * The maximum total number of hints is 96, as specified by the CFF + * specification. + * + * A HintMask is built 0 or more times while interpreting a charstring, by + * the HintMask operator. There is only one HintMask, but it is built or + * rebuilt each time there is a hint substitution (HintMask operator) in + * the charstring. A default HintMask with all bits set is built if there + * has been no HintMask operator prior to the first drawing operator. + * + */ + + typedef struct CF2_HintMaskRec_ + { + FT_Error* error; + + FT_Bool isValid; + FT_Bool isNew; + + size_t bitCount; + size_t byteCount; + + FT_Byte mask[( CF2_MAX_HINTS + 7 ) / 8]; + + } CF2_HintMaskRec, *CF2_HintMask; + + + typedef struct CF2_StemHintRec_ + { + FT_Bool used; /* DS positions are valid */ + + CF2_Fixed min; /* original character space value */ + CF2_Fixed max; + + CF2_Fixed minDS; /* DS position after first use */ + CF2_Fixed maxDS; + + } CF2_StemHintRec, *CF2_StemHint; + + + /* + * A HintMap object stores a piecewise linear function for mapping + * y-coordinates from character space to device space, providing + * appropriate pixel alignment to stem edges. + * + * The map is implemented as an array of `CF2_Hint' elements, each + * representing an edge. When edges are paired, as from stem hints, the + * bottom edge must immediately precede the top edge in the array. + * Element character space AND device space positions must both increase + * monotonically in the array. `CF2_Hint' elements are also used as + * parameters to `cf2_blues_capture'. + * + * The `cf2_hintmap_build' method must be called before any drawing + * operation (beginning with a Move operator) and at each hint + * substitution (HintMask operator). + * + * The `cf2_hintmap_map' method is called to transform y-coordinates at + * each drawing operation (move, line, curve). + * + */ + + /* TODO: make this a CF2_ArrStack and add a deep copy method */ + enum + { + CF2_MAX_HINT_EDGES = CF2_MAX_HINTS * 2 + }; + + + typedef struct CF2_HintMapRec_ + { + CF2_Font font; + + /* initial map based on blue zones */ + struct CF2_HintMapRec_* initialHintMap; + + /* working storage for 2nd pass adjustHints */ + CF2_ArrStack hintMoves; + + FT_Bool isValid; + FT_Bool hinted; + + CF2_Fixed scale; + CF2_UInt count; + + /* start search from this index */ + CF2_UInt lastIndex; + + CF2_HintRec edge[CF2_MAX_HINT_EDGES]; /* 192 */ + + } CF2_HintMapRec, *CF2_HintMap; + + + FT_LOCAL( FT_Bool ) + cf2_hint_isValid( const CF2_Hint hint ); + FT_LOCAL( FT_Bool ) + cf2_hint_isTop( const CF2_Hint hint ); + FT_LOCAL( FT_Bool ) + cf2_hint_isBottom( const CF2_Hint hint ); + FT_LOCAL( void ) + cf2_hint_lock( CF2_Hint hint ); + + + FT_LOCAL( void ) + cf2_hintmap_init( CF2_HintMap hintmap, + CF2_Font font, + CF2_HintMap initialMap, + CF2_ArrStack hintMoves, + CF2_Fixed scale ); + FT_LOCAL( void ) + cf2_hintmap_build( CF2_HintMap hintmap, + CF2_ArrStack hStemHintArray, + CF2_ArrStack vStemHintArray, + CF2_HintMask hintMask, + CF2_Fixed hintOrigin, + FT_Bool initialMap ); + + + /* + * GlyphPath is a wrapper for drawing operations that scales the + * coordinates according to the render matrix and HintMap. It also tracks + * open paths to control ClosePath and to insert MoveTo for broken fonts. + * + */ + typedef struct CF2_GlyphPathRec_ + { + /* TODO: gather some of these into a hinting context */ + + CF2_Font font; /* font instance */ + CF2_OutlineCallbacks callbacks; /* outline consumer */ + + + CF2_HintMapRec hintMap; /* current hint map */ + CF2_HintMapRec firstHintMap; /* saved copy */ + CF2_HintMapRec initialHintMap; /* based on all captured hints */ + + CF2_ArrStackRec hintMoves; /* list of hint moves for 2nd pass */ + + CF2_Fixed scaleX; /* matrix a */ + CF2_Fixed scaleC; /* matrix c */ + CF2_Fixed scaleY; /* matrix d */ + + FT_Vector fractionalTranslation; /* including deviceXScale */ +#if 0 + CF2_Fixed hShift; /* character space horizontal shift */ + /* (for fauxing) */ +#endif + + FT_Bool pathIsOpen; /* true after MoveTo */ + FT_Bool pathIsClosing; /* true when synthesizing closepath line */ + FT_Bool darken; /* true if stem darkening */ + FT_Bool moveIsPending; /* true between MoveTo and offset MoveTo */ + + /* references used to call `cf2_hintmap_build', if necessary */ + CF2_ArrStack hStemHintArray; + CF2_ArrStack vStemHintArray; + CF2_HintMask hintMask; /* ptr to the current mask */ + CF2_Fixed hintOriginY; /* copy of current origin */ + const CF2_BluesRec* blues; + + CF2_Fixed xOffset; /* character space offsets */ + CF2_Fixed yOffset; + + /* character space miter limit threshold */ + CF2_Fixed miterLimit; + /* vertical/horizontal snap distance in character space */ + CF2_Fixed snapThreshold; + + FT_Vector offsetStart0; /* first and second points of first */ + FT_Vector offsetStart1; /* element with offset applied */ + + /* current point, character space, before offset */ + FT_Vector currentCS; + /* current point, device space */ + FT_Vector currentDS; + /* start point of subpath, character space */ + FT_Vector start; + + /* the following members constitute the `queue' of one element */ + FT_Bool elemIsQueued; + CF2_Int prevElemOp; + + FT_Vector prevElemP0; + FT_Vector prevElemP1; + FT_Vector prevElemP2; + FT_Vector prevElemP3; + + } CF2_GlyphPathRec, *CF2_GlyphPath; + + + FT_LOCAL( void ) + cf2_glyphpath_init( CF2_GlyphPath glyphpath, + CF2_Font font, + CF2_OutlineCallbacks callbacks, + CF2_Fixed scaleY, + /* CF2_Fixed hShift, */ + CF2_ArrStack hStemHintArray, + CF2_ArrStack vStemHintArray, + CF2_HintMask hintMask, + CF2_Fixed hintOrigin, + const CF2_Blues blues, + const FT_Vector* fractionalTranslation ); + FT_LOCAL( void ) + cf2_glyphpath_finalize( CF2_GlyphPath glyphpath ); + + FT_LOCAL( void ) + cf2_glyphpath_moveTo( CF2_GlyphPath glyphpath, + CF2_Fixed x, + CF2_Fixed y ); + FT_LOCAL( void ) + cf2_glyphpath_lineTo( CF2_GlyphPath glyphpath, + CF2_Fixed x, + CF2_Fixed y ); + FT_LOCAL( void ) + cf2_glyphpath_curveTo( CF2_GlyphPath glyphpath, + CF2_Fixed x1, + CF2_Fixed y1, + CF2_Fixed x2, + CF2_Fixed y2, + CF2_Fixed x3, + CF2_Fixed y3 ); + FT_LOCAL( void ) + cf2_glyphpath_closeOpenPath( CF2_GlyphPath glyphpath ); + + +FT_END_HEADER + + +#endif /* PSHINT_H_ */ + + +/* END */ diff --git a/src/3rdparty/freetype/src/psaux/psintrp.c b/src/3rdparty/freetype/src/psaux/psintrp.c new file mode 100644 index 0000000000..da5a8dad1d --- /dev/null +++ b/src/3rdparty/freetype/src/psaux/psintrp.c @@ -0,0 +1,3040 @@ +/***************************************************************************/ +/* */ +/* psintrp.c */ +/* */ +/* Adobe's CFF Interpreter (body). */ +/* */ +/* Copyright 2007-2014 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#include "psft.h" +#include FT_INTERNAL_DEBUG_H +#include FT_SERVICE_CFF_TABLE_LOAD_H + +#include "psglue.h" +#include "psfont.h" +#include "psstack.h" +#include "pshints.h" +#include "psintrp.h" + +#include "pserror.h" + +#include "psobjs.h" /* for cff_random */ +#include "t1decode.h" /* for t1 seac */ + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_cf2interp + + + FT_LOCAL_DEF( void ) + cf2_hintmask_init( CF2_HintMask hintmask, + FT_Error* error ) + { + FT_ZERO( hintmask ); + + hintmask->error = error; + } + + + FT_LOCAL_DEF( FT_Bool ) + cf2_hintmask_isValid( const CF2_HintMask hintmask ) + { + return hintmask->isValid; + } + + + FT_LOCAL_DEF( FT_Bool ) + cf2_hintmask_isNew( const CF2_HintMask hintmask ) + { + return hintmask->isNew; + } + + + FT_LOCAL_DEF( void ) + cf2_hintmask_setNew( CF2_HintMask hintmask, + FT_Bool val ) + { + hintmask->isNew = val; + } + + + /* clients call `getMaskPtr' in order to iterate */ + /* through hint mask */ + + FT_LOCAL_DEF( FT_Byte* ) + cf2_hintmask_getMaskPtr( CF2_HintMask hintmask ) + { + return hintmask->mask; + } + + + static size_t + cf2_hintmask_setCounts( CF2_HintMask hintmask, + size_t bitCount ) + { + if ( bitCount > CF2_MAX_HINTS ) + { + /* total of h and v stems must be <= 96 */ + CF2_SET_ERROR( hintmask->error, Invalid_Glyph_Format ); + return 0; + } + + hintmask->bitCount = bitCount; + hintmask->byteCount = ( hintmask->bitCount + 7 ) / 8; + + hintmask->isValid = TRUE; + hintmask->isNew = TRUE; + + return bitCount; + } + + + /* consume the hintmask bytes from the charstring, advancing the src */ + /* pointer */ + static void + cf2_hintmask_read( CF2_HintMask hintmask, + CF2_Buffer charstring, + size_t bitCount ) + { + size_t i; + +#ifndef CF2_NDEBUG + /* these are the bits in the final mask byte that should be zero */ + /* Note: this variable is only used in an assert expression below */ + /* and then only if CF2_NDEBUG is not defined */ + CF2_UInt mask = ( 1 << ( -(CF2_Int)bitCount & 7 ) ) - 1; +#endif + + + /* initialize counts and isValid */ + if ( cf2_hintmask_setCounts( hintmask, bitCount ) == 0 ) + return; + + FT_ASSERT( hintmask->byteCount > 0 ); + + FT_TRACE4(( " (maskbytes:" )); + + /* set mask and advance interpreter's charstring pointer */ + for ( i = 0; i < hintmask->byteCount; i++ ) + { + hintmask->mask[i] = (FT_Byte)cf2_buf_readByte( charstring ); + FT_TRACE4(( " 0x%02X", hintmask->mask[i] )); + } + + FT_TRACE4(( ")\n" )); + + /* assert any unused bits in last byte are zero unless there's a prior */ + /* error */ + /* bitCount -> mask, 0 -> 0, 1 -> 7f, 2 -> 3f, ... 6 -> 3, 7 -> 1 */ +#ifndef CF2_NDEBUG + FT_ASSERT( ( hintmask->mask[hintmask->byteCount - 1] & mask ) == 0 || + *hintmask->error ); +#endif + } + + + FT_LOCAL_DEF( void ) + cf2_hintmask_setAll( CF2_HintMask hintmask, + size_t bitCount ) + { + size_t i; + CF2_UInt mask = ( 1 << ( -(CF2_Int)bitCount & 7 ) ) - 1; + + + /* initialize counts and isValid */ + if ( cf2_hintmask_setCounts( hintmask, bitCount ) == 0 ) + return; + + FT_ASSERT( hintmask->byteCount > 0 ); + FT_ASSERT( hintmask->byteCount <= + sizeof ( hintmask->mask ) / sizeof ( hintmask->mask[0] ) ); + + /* set mask to all ones */ + for ( i = 0; i < hintmask->byteCount; i++ ) + hintmask->mask[i] = 0xFF; + + /* clear unused bits */ + /* bitCount -> mask, 0 -> 0, 1 -> 7f, 2 -> 3f, ... 6 -> 3, 7 -> 1 */ + hintmask->mask[hintmask->byteCount - 1] &= ~mask; + } + + + /* Type2 charstring opcodes */ + enum + { + cf2_cmdRESERVED_0, /* 0 */ + cf2_cmdHSTEM, /* 1 */ + cf2_cmdRESERVED_2, /* 2 */ + cf2_cmdVSTEM, /* 3 */ + cf2_cmdVMOVETO, /* 4 */ + cf2_cmdRLINETO, /* 5 */ + cf2_cmdHLINETO, /* 6 */ + cf2_cmdVLINETO, /* 7 */ + cf2_cmdRRCURVETO, /* 8 */ + cf2_cmdCLOSEPATH, /* 9 T1 only */ + cf2_cmdCALLSUBR, /* 10 */ + cf2_cmdRETURN, /* 11 */ + cf2_cmdESC, /* 12 */ + cf2_cmdHSBW, /* 13 T1 only */ + cf2_cmdENDCHAR, /* 14 */ + cf2_cmdVSINDEX, /* 15 */ + cf2_cmdBLEND, /* 16 */ + cf2_cmdRESERVED_17, /* 17 */ + cf2_cmdHSTEMHM, /* 18 */ + cf2_cmdHINTMASK, /* 19 */ + cf2_cmdCNTRMASK, /* 20 */ + cf2_cmdRMOVETO, /* 21 */ + cf2_cmdHMOVETO, /* 22 */ + cf2_cmdVSTEMHM, /* 23 */ + cf2_cmdRCURVELINE, /* 24 */ + cf2_cmdRLINECURVE, /* 25 */ + cf2_cmdVVCURVETO, /* 26 */ + cf2_cmdHHCURVETO, /* 27 */ + cf2_cmdEXTENDEDNMBR, /* 28 */ + cf2_cmdCALLGSUBR, /* 29 */ + cf2_cmdVHCURVETO, /* 30 */ + cf2_cmdHVCURVETO /* 31 */ + }; + + enum + { + cf2_escDOTSECTION, /* 0 */ + cf2_escVSTEM3, /* 1 T1 only */ + cf2_escHSTEM3, /* 2 T1 only */ + cf2_escAND, /* 3 */ + cf2_escOR, /* 4 */ + cf2_escNOT, /* 5 */ + cf2_escSEAC, /* 6 T1 only */ + cf2_escSBW, /* 7 T1 only */ + cf2_escRESERVED_8, /* 8 */ + cf2_escABS, /* 9 */ + cf2_escADD, /* 10 like otherADD */ + cf2_escSUB, /* 11 like otherSUB */ + cf2_escDIV, /* 12 */ + cf2_escRESERVED_13, /* 13 */ + cf2_escNEG, /* 14 */ + cf2_escEQ, /* 15 */ + cf2_escCALLOTHERSUBR,/* 16 T1 only */ + cf2_escPOP, /* 17 T1 only */ + cf2_escDROP, /* 18 */ + cf2_escRESERVED_19, /* 19 */ + cf2_escPUT, /* 20 like otherPUT */ + cf2_escGET, /* 21 like otherGET */ + cf2_escIFELSE, /* 22 like otherIFELSE */ + cf2_escRANDOM, /* 23 like otherRANDOM */ + cf2_escMUL, /* 24 like otherMUL */ + cf2_escRESERVED_25, /* 25 */ + cf2_escSQRT, /* 26 */ + cf2_escDUP, /* 27 like otherDUP */ + cf2_escEXCH, /* 28 like otherEXCH */ + cf2_escINDEX, /* 29 */ + cf2_escROLL, /* 30 */ + cf2_escRESERVED_31, /* 31 */ + cf2_escRESERVED_32, /* 32 */ + cf2_escSETCURRENTPT, /* 33 T1 only */ + cf2_escHFLEX, /* 34 */ + cf2_escFLEX, /* 35 */ + cf2_escHFLEX1, /* 36 */ + cf2_escFLEX1, /* 37 */ + cf2_escRESERVED_38 /* 38 & all higher */ + }; + + + /* `stemHintArray' does not change once we start drawing the outline. */ + static void + cf2_doStems( const CF2_Font font, + CF2_Stack opStack, + CF2_ArrStack stemHintArray, + CF2_Fixed* width, + FT_Bool* haveWidth, + CF2_Fixed hintOffset ) + { + CF2_UInt i; + CF2_UInt count = cf2_stack_count( opStack ); + FT_Bool hasWidthArg = (FT_Bool)( count & 1 ); + + /* variable accumulates delta values from operand stack */ + CF2_Fixed position = hintOffset; + + if ( font->isT1 && !font->decoder->flex_state && !*haveWidth ) + FT_ERROR(( "cf2_doStems (Type 1 mode):" + " No width. Use hsbw/sbw as first op\n" )); + + if ( !font->isT1 && hasWidthArg && !*haveWidth ) + *width = ADD_INT32( cf2_stack_getReal( opStack, 0 ), + cf2_getNominalWidthX( font->decoder ) ); + + if ( font->decoder->width_only ) + goto exit; + + for ( i = hasWidthArg ? 1 : 0; i < count; i += 2 ) + { + /* construct a CF2_StemHint and push it onto the list */ + CF2_StemHintRec stemhint; + + + stemhint.min = + position = ADD_INT32( position, + cf2_stack_getReal( opStack, i ) ); + stemhint.max = + position = ADD_INT32( position, + cf2_stack_getReal( opStack, i + 1 ) ); + + stemhint.used = FALSE; + stemhint.maxDS = + stemhint.minDS = 0; + + cf2_arrstack_push( stemHintArray, &stemhint ); /* defer error check */ + } + + cf2_stack_clear( opStack ); + + exit: + /* cf2_doStems must define a width (may be default) */ + *haveWidth = TRUE; + } + + + static void + cf2_doFlex( CF2_Stack opStack, + CF2_Fixed* curX, + CF2_Fixed* curY, + CF2_GlyphPath glyphPath, + const FT_Bool* readFromStack, + FT_Bool doConditionalLastRead ) + { + CF2_Fixed vals[14]; + CF2_UInt idx; + FT_Bool isHFlex; + CF2_Int top, i, j; + + + vals[0] = *curX; + vals[1] = *curY; + idx = 0; + isHFlex = FT_BOOL( readFromStack[9] == FALSE ); + top = isHFlex ? 9 : 10; + + for ( i = 0; i < top; i++ ) + { + vals[i + 2] = vals[i]; + if ( readFromStack[i] ) + vals[i + 2] = ADD_INT32( vals[i + 2], cf2_stack_getReal( opStack, + idx++ ) ); + } + + if ( isHFlex ) + vals[9 + 2] = *curY; + + if ( doConditionalLastRead ) + { + FT_Bool lastIsX = (FT_Bool)( + cf2_fixedAbs( SUB_INT32( vals[10], *curX ) ) > + cf2_fixedAbs( SUB_INT32( vals[11], *curY ) ) ); + CF2_Fixed lastVal = cf2_stack_getReal( opStack, idx ); + + + if ( lastIsX ) + { + vals[12] = ADD_INT32( vals[10], lastVal ); + vals[13] = *curY; + } + else + { + vals[12] = *curX; + vals[13] = ADD_INT32( vals[11], lastVal ); + } + } + else + { + if ( readFromStack[10] ) + vals[12] = ADD_INT32( vals[10], + cf2_stack_getReal( opStack, idx++ ) ); + else + vals[12] = *curX; + + if ( readFromStack[11] ) + vals[13] = ADD_INT32( vals[11], + cf2_stack_getReal( opStack, idx ) ); + else + vals[13] = *curY; + } + + for ( j = 0; j < 2; j++ ) + cf2_glyphpath_curveTo( glyphPath, vals[j * 6 + 2], + vals[j * 6 + 3], + vals[j * 6 + 4], + vals[j * 6 + 5], + vals[j * 6 + 6], + vals[j * 6 + 7] ); + + cf2_stack_clear( opStack ); + + *curX = vals[12]; + *curY = vals[13]; + } + + + /* Blend numOperands on the stack, */ + /* store results into the first numBlends values, */ + /* then pop remaining arguments. */ + static void + cf2_doBlend( const CFF_Blend blend, + CF2_Stack opStack, + CF2_UInt numBlends ) + { + CF2_UInt delta; + CF2_UInt base; + CF2_UInt i, j; + CF2_UInt numOperands = (CF2_UInt)( numBlends * blend->lenBV ); + + + base = cf2_stack_count( opStack ) - numOperands; + delta = base + numBlends; + + for ( i = 0; i < numBlends; i++ ) + { + const CF2_Fixed* weight = &blend->BV[1]; + + /* start with first term */ + CF2_Fixed sum = cf2_stack_getReal( opStack, i + base ); + + + for ( j = 1; j < blend->lenBV; j++ ) + sum = ADD_INT32( sum, + FT_MulFix( *weight++, + cf2_stack_getReal( opStack, + delta++ ) ) ); + + /* store blended result */ + cf2_stack_setReal( opStack, i + base, sum ); + } + + /* leave only `numBlends' results on stack */ + cf2_stack_pop( opStack, numOperands - numBlends ); + } + + + /* + * `error' is a shared error code used by many objects in this + * routine. Before the code continues from an error, it must check and + * record the error in `*error'. The idea is that this shared + * error code will record the first error encountered. If testing + * for an error anyway, the cost of `goto exit' is small, so we do it, + * even if continuing would be safe. In this case, `lastError' is + * set, so the testing and storing can be done in one place, at `exit'. + * + * Continuing after an error is intended for objects which do their own + * testing of `*error', e.g., array stack functions. This allows us to + * avoid an extra test after the call. + * + * Unimplemented opcodes are ignored. + * + */ + FT_LOCAL_DEF( void ) + cf2_interpT2CharString( CF2_Font font, + CF2_Buffer buf, + CF2_OutlineCallbacks callbacks, + const FT_Vector* translation, + FT_Bool doingSeac, + CF2_Fixed curX, + CF2_Fixed curY, + CF2_Fixed* width ) + { + /* lastError is used for errors that are immediately tested */ + FT_Error lastError = FT_Err_Ok; + + /* pointer to parsed font object */ + PS_Decoder* decoder = font->decoder; + + FT_Error* error = &font->error; + FT_Memory memory = font->memory; + + CF2_Fixed scaleY = font->innerTransform.d; + CF2_Fixed nominalWidthX = cf2_getNominalWidthX( decoder ); + + /* stuff for Type 1 */ + FT_Int known_othersubr_result_cnt = 0; + FT_Bool large_int = FALSE; + FT_Bool initial_map_ready = FALSE; + +#define PS_STORAGE_SIZE 3 + CF2_F16Dot16 results[PS_STORAGE_SIZE]; /* for othersubr results */ + FT_Int result_cnt = 0; + + /* save this for hinting seac accents */ + CF2_Fixed hintOriginY = curY; + + CF2_Stack opStack = NULL; + FT_UInt stackSize; + FT_Byte op1; /* first opcode byte */ + + CF2_F16Dot16 storage[CF2_STORAGE_SIZE]; /* for `put' and `get' */ + CF2_F16Dot16 flexStore[6]; /* for Type 1 flex */ + + /* instruction limit; 20,000,000 matches Avalon */ + FT_UInt32 instructionLimit = 20000000UL; + + CF2_ArrStackRec subrStack; + + FT_Bool haveWidth; + CF2_Buffer charstring = NULL; + + CF2_Int charstringIndex = -1; /* initialize to empty */ + + /* TODO: placeholders for hint structures */ + + /* objects used for hinting */ + CF2_ArrStackRec hStemHintArray; + CF2_ArrStackRec vStemHintArray; + + CF2_HintMaskRec hintMask; + CF2_GlyphPathRec glyphPath; + + + FT_ZERO( &storage ); + FT_ZERO( &results ); + FT_ZERO( &flexStore ); + + /* initialize the remaining objects */ + cf2_arrstack_init( &subrStack, + memory, + error, + sizeof ( CF2_BufferRec ) ); + cf2_arrstack_init( &hStemHintArray, + memory, + error, + sizeof ( CF2_StemHintRec ) ); + cf2_arrstack_init( &vStemHintArray, + memory, + error, + sizeof ( CF2_StemHintRec ) ); + + /* initialize CF2_StemHint arrays */ + cf2_hintmask_init( &hintMask, error ); + + /* initialize path map to manage drawing operations */ + + /* Note: last 4 params are used to handle `MoveToPermissive', which */ + /* may need to call `hintMap.Build' */ + /* TODO: MoveToPermissive is gone; are these still needed? */ + cf2_glyphpath_init( &glyphPath, + font, + callbacks, + scaleY, + /* hShift, */ + &hStemHintArray, + &vStemHintArray, + &hintMask, + hintOriginY, + &font->blues, + translation ); + + /* + * Initialize state for width parsing. From the CFF Spec: + * + * The first stack-clearing operator, which must be one of hstem, + * hstemhm, vstem, vstemhm, cntrmask, hintmask, hmoveto, vmoveto, + * rmoveto, or endchar, takes an additional argument - the width (as + * described earlier), which may be expressed as zero or one numeric + * argument. + * + * What we implement here uses the first validly specified width, but + * does not detect errors for specifying more than one width. + * + * If one of the above operators occurs without explicitly specifying + * a width, we assume the default width. + * + * CFF2 charstrings always return the default width (0). + * + */ + haveWidth = font->isCFF2 ? TRUE : FALSE; + *width = cf2_getDefaultWidthX( decoder ); + + /* + * Note: At this point, all pointers to resources must be NULL + * and all local objects must be initialized. + * There must be no branches to `exit:' above this point. + * + */ + + /* allocate an operand stack */ + stackSize = font->isCFF2 ? cf2_getMaxstack( decoder ) + : CF2_OPERAND_STACK_SIZE; + opStack = cf2_stack_init( memory, error, stackSize ); + + if ( !opStack ) + { + lastError = FT_THROW( Out_Of_Memory ); + goto exit; + } + + /* initialize subroutine stack by placing top level charstring as */ + /* first element (max depth plus one for the charstring) */ + /* Note: Caller owns and must finalize the first charstring. */ + /* Our copy of it does not change that requirement. */ + cf2_arrstack_setCount( &subrStack, CF2_MAX_SUBR + 1 ); + + charstring = (CF2_Buffer)cf2_arrstack_getBuffer( &subrStack ); + *charstring = *buf; /* structure copy */ + + charstringIndex = 0; /* entry is valid now */ + + /* catch errors so far */ + if ( *error ) + goto exit; + + /* main interpreter loop */ + while ( 1 ) + { + if ( font->isT1 ) + FT_ASSERT( known_othersubr_result_cnt == 0 || + result_cnt == 0 ); + + if ( cf2_buf_isEnd( charstring ) ) + { + /* If we've reached the end of the charstring, simulate a */ + /* cf2_cmdRETURN or cf2_cmdENDCHAR. */ + /* We do this for both CFF and CFF2. */ + if ( charstringIndex ) + op1 = cf2_cmdRETURN; /* end of buffer for subroutine */ + else + op1 = cf2_cmdENDCHAR; /* end of buffer for top level charstring */ + } + else + { + op1 = (FT_Byte)cf2_buf_readByte( charstring ); + + /* Explicit RETURN and ENDCHAR in CFF2 should be ignored. */ + /* Note: Trace message will report 0 instead of 11 or 14. */ + if ( ( op1 == cf2_cmdRETURN || op1 == cf2_cmdENDCHAR ) && + font->isCFF2 ) + op1 = cf2_cmdRESERVED_0; + } + + if ( font->isT1 ) + { + if ( !initial_map_ready && + !( op1 == cf2_cmdHSTEM || + op1 == cf2_cmdVSTEM || + op1 == cf2_cmdHSBW || + op1 == cf2_cmdCALLSUBR || + op1 == cf2_cmdRETURN || + op1 == cf2_cmdESC || + op1 == cf2_cmdENDCHAR || + op1 >= 32 /* Numbers */ ) ) + { + /* Skip outline commands first time round. */ + /* `endchar' will trigger initial hintmap build */ + /* and rewind the charstring. */ + cf2_stack_clear( opStack ); + continue; + } + + if ( result_cnt > 0 && + !( op1 == cf2_cmdCALLSUBR || + op1 == cf2_cmdRETURN || + op1 == cf2_cmdESC || + op1 >= 32 /* Numbers */ ) ) + { + /* all operands have been transferred by previous pops */ + result_cnt = 0; + } + + if ( large_int && !( op1 >= 32 || op1 == cf2_escDIV ) ) + { + FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):" + " no `div' after large integer\n" )); + + large_int = FALSE; + } + } + + /* check for errors once per loop */ + if ( *error ) + goto exit; + + instructionLimit--; + if ( instructionLimit == 0 ) + { + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; + } + + switch( op1 ) + { + case cf2_cmdRESERVED_0: + case cf2_cmdRESERVED_2: + case cf2_cmdRESERVED_17: + /* we may get here if we have a prior error */ + FT_TRACE4(( " unknown op (%d)\n", op1 )); + break; + + case cf2_cmdVSINDEX: + FT_TRACE4(( " vsindex\n" )); + + if ( !font->isCFF2 ) + break; /* clear stack & ignore */ + + if ( font->blend.usedBV ) + { + /* vsindex not allowed after blend */ + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; + } + + { + FT_Int temp = cf2_stack_popInt( opStack ); + + + if ( temp >= 0 ) + font->vsindex = (FT_UInt)temp; + } + break; + + case cf2_cmdBLEND: + { + FT_UInt numBlends; + + + FT_TRACE4(( " blend\n" )); + + if ( !font->isCFF2 ) + break; /* clear stack & ignore */ + + /* do we have a `blend' op in a non-variant font? */ + if ( !font->blend.font ) + { + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; + } + + /* check cached blend vector */ + if ( font->cffload->blend_check_vector( &font->blend, + font->vsindex, + font->lenNDV, + font->NDV ) ) + { + lastError = font->cffload->blend_build_vector( &font->blend, + font->vsindex, + font->lenNDV, + font->NDV ); + if ( lastError ) + goto exit; + } + + /* do the blend */ + numBlends = (FT_UInt)cf2_stack_popInt( opStack ); + if ( numBlends > stackSize ) + { + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; + } + + cf2_doBlend( &font->blend, opStack, numBlends ); + + font->blend.usedBV = TRUE; + } + continue; /* do not clear the stack */ + + case cf2_cmdHSTEMHM: + case cf2_cmdHSTEM: + FT_TRACE4(( op1 == cf2_cmdHSTEMHM ? " hstemhm\n" : " hstem\n" )); + + if ( !font->isT1 ) + { + /* never add hints after the mask is computed */ + /* except if in Type 1 mode (no hintmask op) */ + if ( cf2_hintmask_isValid( &hintMask ) ) + { + FT_TRACE4(( "cf2_interpT2CharString:" + " invalid horizontal hint mask\n" )); + break; + } + } + + /* add left-sidebearing correction in Type 1 mode */ + cf2_doStems( font, + opStack, + &hStemHintArray, + width, + &haveWidth, + font->isT1 ? decoder->builder.left_bearing->y + : 0 ); + + if ( decoder->width_only ) + goto exit; + + break; + + case cf2_cmdVSTEMHM: + case cf2_cmdVSTEM: + FT_TRACE4(( op1 == cf2_cmdVSTEMHM ? " vstemhm\n" : " vstem\n" )); + + if ( !font->isT1 ) + { + /* never add hints after the mask is computed */ + /* except if in Type 1 mode (no hintmask op) */ + if ( cf2_hintmask_isValid( &hintMask ) ) + { + FT_TRACE4(( "cf2_interpT2CharString:" + " invalid vertical hint mask\n" )); + break; + } + } + + /* add left-sidebearing correction in Type 1 mode */ + cf2_doStems( font, + opStack, + &vStemHintArray, + width, + &haveWidth, + font->isT1 ? decoder->builder.left_bearing->x + : 0 ); + + if ( decoder->width_only ) + goto exit; + + break; + + case cf2_cmdVMOVETO: + FT_TRACE4(( " vmoveto\n" )); + + if ( font->isT1 && !decoder->flex_state && !haveWidth ) + FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):" + " No width. Use hsbw/sbw as first op\n" )); + + if ( cf2_stack_count( opStack ) > 1 && !haveWidth ) + *width = ADD_INT32( cf2_stack_getReal( opStack, 0 ), + nominalWidthX ); + + /* width is defined or default after this */ + haveWidth = TRUE; + + if ( decoder->width_only ) + goto exit; + + curY = ADD_INT32( curY, cf2_stack_popFixed( opStack ) ); + + if ( !decoder->flex_state ) + cf2_glyphpath_moveTo( &glyphPath, curX, curY ); + + break; + + case cf2_cmdRLINETO: + { + CF2_UInt idx; + CF2_UInt count = cf2_stack_count( opStack ); + + + FT_TRACE4(( " rlineto\n" )); + + for ( idx = 0; idx < count; idx += 2 ) + { + curX = ADD_INT32( curX, cf2_stack_getReal( opStack, + idx + 0 ) ); + curY = ADD_INT32( curY, cf2_stack_getReal( opStack, + idx + 1 ) ); + + cf2_glyphpath_lineTo( &glyphPath, curX, curY ); + } + + cf2_stack_clear( opStack ); + } + continue; /* no need to clear stack again */ + + case cf2_cmdHLINETO: + case cf2_cmdVLINETO: + { + CF2_UInt idx; + CF2_UInt count = cf2_stack_count( opStack ); + + FT_Bool isX = FT_BOOL( op1 == cf2_cmdHLINETO ); + + + FT_TRACE4(( isX ? " hlineto\n" : " vlineto\n" )); + + for ( idx = 0; idx < count; idx++ ) + { + CF2_Fixed v = cf2_stack_getReal( opStack, idx ); + + + if ( isX ) + curX = ADD_INT32( curX, v ); + else + curY = ADD_INT32( curY, v ); + + isX = !isX; + + cf2_glyphpath_lineTo( &glyphPath, curX, curY ); + } + + cf2_stack_clear( opStack ); + } + continue; + + case cf2_cmdRCURVELINE: + case cf2_cmdRRCURVETO: + { + CF2_UInt count = cf2_stack_count( opStack ); + CF2_UInt idx = 0; + + + FT_TRACE4(( op1 == cf2_cmdRCURVELINE ? " rcurveline\n" + : " rrcurveto\n" )); + + while ( idx + 6 <= count ) + { + CF2_Fixed x1, y1, x2, y2, x3, y3; + + + x1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curX ); + y1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), curY ); + x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), x1 ); + y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), y1 ); + x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 4 ), x2 ); + y3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 5 ), y2 ); + + cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); + + curX = x3; + curY = y3; + idx += 6; + } + + if ( op1 == cf2_cmdRCURVELINE ) + { + curX = ADD_INT32( curX, cf2_stack_getReal( opStack, + idx + 0 ) ); + curY = ADD_INT32( curY, cf2_stack_getReal( opStack, + idx + 1 ) ); + + cf2_glyphpath_lineTo( &glyphPath, curX, curY ); + } + + cf2_stack_clear( opStack ); + } + continue; /* no need to clear stack again */ + + case cf2_cmdCLOSEPATH: + if ( !font->isT1 ) + FT_TRACE4(( " unknown op (%d)\n", op1 )); + else + { + FT_TRACE4(( " closepath" )); + + /* if there is no path, `closepath' is a no-op */ + ps_builder_close_contour( &decoder->builder ); + + haveWidth = TRUE; + } + break; + + case cf2_cmdCALLGSUBR: + case cf2_cmdCALLSUBR: + { + CF2_Int subrNum; + + + FT_TRACE4(( op1 == cf2_cmdCALLGSUBR ? " callgsubr" + : " callsubr" )); + + if ( ( !font->isT1 && charstringIndex > CF2_MAX_SUBR ) || + ( font->isT1 && charstringIndex > T1_MAX_SUBRS_CALLS ) ) + { + /* max subr plus one for charstring */ + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; /* overflow of stack */ + } + + /* push our current CFF charstring region on subrStack */ + charstring = (CF2_Buffer) + cf2_arrstack_getPointer( + &subrStack, + (size_t)charstringIndex + 1 ); + + /* set up the new CFF region and pointer */ + subrNum = cf2_stack_popInt( opStack ); + + if ( font->isT1 && decoder->locals_hash ) + { + size_t* val = ft_hash_num_lookup( subrNum, + decoder->locals_hash ); + + + if ( val ) + subrNum = *val; + else + subrNum = -1; + } + + switch ( op1 ) + { + case cf2_cmdCALLGSUBR: + FT_TRACE4(( " (idx %d, entering level %d)\n", + subrNum + decoder->globals_bias, + charstringIndex + 1 )); + + if ( cf2_initGlobalRegionBuffer( decoder, + subrNum, + charstring ) ) + { + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; /* subroutine lookup or stream error */ + } + break; + + default: + /* cf2_cmdCALLSUBR */ + FT_TRACE4(( " (idx %d, entering level %d)\n", + subrNum + decoder->locals_bias, + charstringIndex + 1 )); + + if ( cf2_initLocalRegionBuffer( decoder, + subrNum, + charstring ) ) + { + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; /* subroutine lookup or stream error */ + } + } + + charstringIndex += 1; /* entry is valid now */ + } + continue; /* do not clear the stack */ + + case cf2_cmdRETURN: + FT_TRACE4(( " return (leaving level %d)\n", charstringIndex )); + + if ( charstringIndex < 1 ) + { + /* Note: cannot return from top charstring */ + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; /* underflow of stack */ + } + + /* restore position in previous charstring */ + charstring = (CF2_Buffer) + cf2_arrstack_getPointer( + &subrStack, + (CF2_UInt)--charstringIndex ); + continue; /* do not clear the stack */ + + case cf2_cmdESC: + { + FT_Byte op2 = (FT_Byte)cf2_buf_readByte( charstring ); + + + /* first switch for 2-byte operators handles CFF2 */ + /* and opcodes that are reserved for both CFF and CFF2 */ + switch ( op2 ) + { + case cf2_escHFLEX: + { + static const FT_Bool readFromStack[12] = + { + TRUE /* dx1 */, FALSE /* dy1 */, + TRUE /* dx2 */, TRUE /* dy2 */, + TRUE /* dx3 */, FALSE /* dy3 */, + TRUE /* dx4 */, FALSE /* dy4 */, + TRUE /* dx5 */, FALSE /* dy5 */, + TRUE /* dx6 */, FALSE /* dy6 */ + }; + + + FT_TRACE4(( " hflex\n" )); + + cf2_doFlex( opStack, + &curX, + &curY, + &glyphPath, + readFromStack, + FALSE /* doConditionalLastRead */ ); + } + continue; + + case cf2_escFLEX: + { + static const FT_Bool readFromStack[12] = + { + TRUE /* dx1 */, TRUE /* dy1 */, + TRUE /* dx2 */, TRUE /* dy2 */, + TRUE /* dx3 */, TRUE /* dy3 */, + TRUE /* dx4 */, TRUE /* dy4 */, + TRUE /* dx5 */, TRUE /* dy5 */, + TRUE /* dx6 */, TRUE /* dy6 */ + }; + + + FT_TRACE4(( " flex\n" )); + + cf2_doFlex( opStack, + &curX, + &curY, + &glyphPath, + readFromStack, + FALSE /* doConditionalLastRead */ ); + } + break; /* TODO: why is this not a continue? */ + + case cf2_escHFLEX1: + { + static const FT_Bool readFromStack[12] = + { + TRUE /* dx1 */, TRUE /* dy1 */, + TRUE /* dx2 */, TRUE /* dy2 */, + TRUE /* dx3 */, FALSE /* dy3 */, + TRUE /* dx4 */, FALSE /* dy4 */, + TRUE /* dx5 */, TRUE /* dy5 */, + TRUE /* dx6 */, FALSE /* dy6 */ + }; + + + FT_TRACE4(( " hflex1\n" )); + + cf2_doFlex( opStack, + &curX, + &curY, + &glyphPath, + readFromStack, + FALSE /* doConditionalLastRead */ ); + } + continue; + + case cf2_escFLEX1: + { + static const FT_Bool readFromStack[12] = + { + TRUE /* dx1 */, TRUE /* dy1 */, + TRUE /* dx2 */, TRUE /* dy2 */, + TRUE /* dx3 */, TRUE /* dy3 */, + TRUE /* dx4 */, TRUE /* dy4 */, + TRUE /* dx5 */, TRUE /* dy5 */, + FALSE /* dx6 */, FALSE /* dy6 */ + }; + + + FT_TRACE4(( " flex1\n" )); + + cf2_doFlex( opStack, + &curX, + &curY, + &glyphPath, + readFromStack, + TRUE /* doConditionalLastRead */ ); + } + continue; + + /* these opcodes are always reserved */ + case cf2_escRESERVED_8: + case cf2_escRESERVED_13: + case cf2_escRESERVED_19: + case cf2_escRESERVED_25: + case cf2_escRESERVED_31: + case cf2_escRESERVED_32: + FT_TRACE4(( " unknown op (12, %d)\n", op2 )); + break; + + default: + { + if ( font->isCFF2 || op2 >= cf2_escRESERVED_38 ) + FT_TRACE4(( " unknown op (12, %d)\n", op2 )); + else if ( font->isT1 && result_cnt > 0 && op2 != cf2_escPOP ) + { + /* all operands have been transferred by previous pops */ + result_cnt = 0; + } + else + { + /* second switch for 2-byte operators handles */ + /* CFF and Type 1 */ + switch ( op2 ) + { + + case cf2_escDOTSECTION: + /* something about `flip type of locking' -- ignore it */ + FT_TRACE4(( " dotsection\n" )); + + break; + + case cf2_escVSTEM3: + case cf2_escHSTEM3: + /* + * Type 1: Type 2: + * x0 dx0 x1 dx1 x2 dx2 vstem3 x dx {dxa dxb}* vstem + * y0 dy0 y1 dy1 y2 dy2 hstem3 y dy {dya dyb}* hstem + * relative to lsb point relative to zero + * + */ + { + if ( !font->isT1 ) + FT_TRACE4(( " unknown op (12, %d)\n", op2 )); + else + { + CF2_F16Dot16 v0, v1, v2; + + FT_Bool isV = FT_BOOL( op2 == cf2_escVSTEM3 ); + + + FT_TRACE4(( isV ? " vstem3\n" + : " hstem3\n" )); + + FT_ASSERT( cf2_stack_count( opStack ) == 6 ); + + v0 = cf2_stack_getReal( opStack, 0 ); + v1 = cf2_stack_getReal( opStack, 2 ); + v2 = cf2_stack_getReal( opStack, 4 ); + + cf2_stack_setReal( + opStack, 2, + SUB_INT32( SUB_INT32( v1, v0 ), + cf2_stack_getReal( opStack, 1 ) ) ); + cf2_stack_setReal( + opStack, 4, + SUB_INT32( SUB_INT32( v2, v1 ), + cf2_stack_getReal( opStack, 3 ) ) ); + + /* add left-sidebearing correction */ + cf2_doStems( font, + opStack, + isV ? &vStemHintArray : &hStemHintArray, + width, + &haveWidth, + isV ? decoder->builder.left_bearing->x + : decoder->builder.left_bearing->y ); + + if ( decoder->width_only ) + goto exit; + } + } + break; + + case cf2_escAND: + { + CF2_F16Dot16 arg1; + CF2_F16Dot16 arg2; + + + FT_TRACE4(( " and\n" )); + + arg2 = cf2_stack_popFixed( opStack ); + arg1 = cf2_stack_popFixed( opStack ); + + cf2_stack_pushInt( opStack, arg1 && arg2 ); + } + continue; /* do not clear the stack */ + + case cf2_escOR: + { + CF2_F16Dot16 arg1; + CF2_F16Dot16 arg2; + + + FT_TRACE4(( " or\n" )); + + arg2 = cf2_stack_popFixed( opStack ); + arg1 = cf2_stack_popFixed( opStack ); + + cf2_stack_pushInt( opStack, arg1 || arg2 ); + } + continue; /* do not clear the stack */ + + case cf2_escNOT: + { + CF2_F16Dot16 arg; + + + FT_TRACE4(( " not\n" )); + + arg = cf2_stack_popFixed( opStack ); + + cf2_stack_pushInt( opStack, !arg ); + } + continue; /* do not clear the stack */ + + case cf2_escSEAC: + if ( !font->isT1 ) + FT_TRACE4(( " unknown op (12, %d)\n", op2 )); + else + { + FT_Error error2; + CF2_Int bchar_index, achar_index; + FT_Vector left_bearing, advance; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + T1_Face face = (T1_Face)decoder->builder.face; +#endif + CF2_BufferRec component; + CF2_Fixed dummyWidth; + + CF2_Int achar = cf2_stack_popInt( opStack ); + CF2_Int bchar = cf2_stack_popInt( opStack ); + + FT_Pos ady = cf2_stack_popFixed ( opStack ); + FT_Pos adx = cf2_stack_popFixed ( opStack ); + FT_Pos asb = cf2_stack_popFixed ( opStack ); + + + FT_TRACE4(( " seac\n" )); + + if ( doingSeac ) + { + FT_ERROR(( " nested seac\n" )); + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; /* nested seac */ + } + + if ( decoder->builder.metrics_only ) + { + FT_ERROR(( " unexpected seac\n" )); + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; /* unexpected seac */ + } + + /* `glyph_names' is set to 0 for CID fonts which do */ + /* not include an encoding. How can we deal with */ + /* these? */ +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( decoder->glyph_names == 0 && + !face->root.internal->incremental_interface ) +#else + if ( decoder->glyph_names == 0 ) +#endif /* FT_CONFIG_OPTION_INCREMENTAL */ + { + FT_ERROR(( + "cf2_interpT2CharString: (Type 1 seac)" + " glyph names table not available in this font\n" )); + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; + } + + /* seac weirdness */ + adx += decoder->builder.left_bearing->x; + +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( face->root.internal->incremental_interface ) + { + /* the caller must handle the font encoding also */ + bchar_index = bchar; + achar_index = achar; + } + else +#endif + { + bchar_index = t1_lookup_glyph_by_stdcharcode_ps( + decoder, bchar ); + achar_index = t1_lookup_glyph_by_stdcharcode_ps( + decoder, achar ); + } + + if ( bchar_index < 0 || achar_index < 0 ) + { + FT_ERROR(( + "cf2_interpT2CharString: (Type 1 seac)" + " invalid seac character code arguments\n" )); + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; + } + + /* if we are trying to load a composite glyph, */ + /* do not load the accent character and return */ + /* the array of subglyphs. */ + if ( decoder->builder.no_recurse ) + { + FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph; + FT_GlyphLoader loader = glyph->internal->loader; + FT_SubGlyph subg; + + + /* reallocate subglyph array if necessary */ + error2 = FT_GlyphLoader_CheckSubGlyphs( loader, 2 ); + if ( error2 ) + { + lastError = error2; /* pass FreeType error through */ + goto exit; + } + + subg = loader->current.subglyphs; + + /* subglyph 0 = base character */ + subg->index = bchar_index; + subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES | + FT_SUBGLYPH_FLAG_USE_MY_METRICS; + subg->arg1 = 0; + subg->arg2 = 0; + subg++; + + /* subglyph 1 = accent character */ + subg->index = achar_index; + subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; + subg->arg1 = (FT_Int)FIXED_TO_INT( adx - asb ); + subg->arg2 = (FT_Int)FIXED_TO_INT( ady ); + + /* set up remaining glyph fields */ + glyph->num_subglyphs = 2; + glyph->subglyphs = loader->base.subglyphs; + glyph->format = FT_GLYPH_FORMAT_COMPOSITE; + + loader->current.num_subglyphs = 2; + + goto exit; + } + + /* First load `bchar' in builder */ + /* now load the unscaled outline */ + + /* prepare loader */ + FT_GlyphLoader_Prepare( decoder->builder.loader ); + + error2 = cf2_getT1SeacComponent( decoder, + (FT_UInt)bchar_index, + &component ); + if ( error2 ) + { + lastError = error2; /* pass FreeType error through */ + goto exit; + } + cf2_interpT2CharString( font, + &component, + callbacks, + translation, + TRUE, + 0, + 0, + &dummyWidth ); + cf2_freeT1SeacComponent( decoder, &component ); + + /* save the left bearing and width of the base */ + /* character as they will be erased by the next load */ + + left_bearing = *decoder->builder.left_bearing; + advance = *decoder->builder.advance; + + decoder->builder.left_bearing->x = 0; + decoder->builder.left_bearing->y = 0; + + /* Now load `achar' on top of */ + /* the base outline */ + + error2 = cf2_getT1SeacComponent( decoder, + (FT_UInt)achar_index, + &component ); + if ( error2 ) + { + lastError = error2; /* pass FreeType error through */ + goto exit; + } + cf2_interpT2CharString( font, + &component, + callbacks, + translation, + TRUE, + adx - asb, + ady, + &dummyWidth ); + cf2_freeT1SeacComponent( decoder, &component ); + + /* restore the left side bearing and */ + /* advance width of the base character */ + + *decoder->builder.left_bearing = left_bearing; + *decoder->builder.advance = advance; + + goto exit; + } + break; + + case cf2_escSBW: + if ( !font->isT1 ) + FT_TRACE4(( " unknown op (12, %d)\n", op2 )); + else + { + CF2_Fixed lsb_x, lsb_y; + PS_Builder* builder; + + + FT_TRACE4(( " sbw" )); + + builder = &decoder->builder; + + builder->advance->y = cf2_stack_popFixed( opStack ); + builder->advance->x = cf2_stack_popFixed( opStack ); + + lsb_y = cf2_stack_popFixed( opStack ); + lsb_x = cf2_stack_popFixed( opStack ); + + builder->left_bearing->x = + ADD_INT32( builder->left_bearing->x, lsb_x ); + builder->left_bearing->y = + ADD_INT32( builder->left_bearing->y, lsb_y ); + + haveWidth = TRUE; + + /* the `metrics_only' indicates that we only want */ + /* to compute the glyph's metrics (lsb + advance */ + /* width), not load the rest of it; so exit */ + /* immediately */ + if ( builder->metrics_only ) + goto exit; + + if ( initial_map_ready ) + { + curX = ADD_INT32( curX, lsb_x ); + curY = ADD_INT32( curY, lsb_y ); + } + } + break; + + case cf2_escABS: + { + CF2_F16Dot16 arg; + + + FT_TRACE4(( " abs\n" )); + + arg = cf2_stack_popFixed( opStack ); + + if ( arg < -CF2_FIXED_MAX ) + cf2_stack_pushFixed( opStack, CF2_FIXED_MAX ); + else + cf2_stack_pushFixed( opStack, FT_ABS( arg ) ); + } + continue; /* do not clear the stack */ + + case cf2_escADD: + { + CF2_F16Dot16 summand1; + CF2_F16Dot16 summand2; + + + FT_TRACE4(( " add\n" )); + + summand2 = cf2_stack_popFixed( opStack ); + summand1 = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, + ADD_INT32( summand1, + summand2 ) ); + } + continue; /* do not clear the stack */ + + case cf2_escSUB: + { + CF2_F16Dot16 minuend; + CF2_F16Dot16 subtrahend; + + + FT_TRACE4(( " sub\n" )); + + subtrahend = cf2_stack_popFixed( opStack ); + minuend = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, + SUB_INT32( minuend, subtrahend ) ); + } + continue; /* do not clear the stack */ + + case cf2_escDIV: + { + CF2_F16Dot16 dividend; + CF2_F16Dot16 divisor; + + + FT_TRACE4(( " div\n" )); + + if ( font->isT1 && large_int ) + { + divisor = (CF2_F16Dot16)cf2_stack_popInt( opStack ); + dividend = (CF2_F16Dot16)cf2_stack_popInt( opStack ); + + large_int = FALSE; + } + else + { + divisor = cf2_stack_popFixed( opStack ); + dividend = cf2_stack_popFixed( opStack ); + } + + cf2_stack_pushFixed( opStack, + FT_DivFix( dividend, divisor ) ); + + } + continue; /* do not clear the stack */ + + case cf2_escNEG: + { + CF2_F16Dot16 arg; + + + FT_TRACE4(( " neg\n" )); + + arg = cf2_stack_popFixed( opStack ); + + if ( arg < -CF2_FIXED_MAX ) + cf2_stack_pushFixed( opStack, CF2_FIXED_MAX ); + else + cf2_stack_pushFixed( opStack, -arg ); + } + continue; /* do not clear the stack */ + + case cf2_escEQ: + { + CF2_F16Dot16 arg1; + CF2_F16Dot16 arg2; + + + FT_TRACE4(( " eq\n" )); + + arg2 = cf2_stack_popFixed( opStack ); + arg1 = cf2_stack_popFixed( opStack ); + + cf2_stack_pushInt( opStack, arg1 == arg2 ); + } + continue; /* do not clear the stack */ + + case cf2_escCALLOTHERSUBR: + if ( !font->isT1 ) + FT_TRACE4(( " unknown op (12, %d)\n", op2 )); + else + { + CF2_Int subr_no; + CF2_Int arg_cnt; + CF2_UInt count; + CF2_UInt opIdx = 0; + + + FT_TRACE4(( " callothersubr\n" )); + + subr_no = cf2_stack_popInt( opStack ); + arg_cnt = cf2_stack_popInt( opStack ); + + /*******************************************************/ + /* */ + /* remove all operands to callothersubr from the stack */ + /* */ + /* for handled othersubrs, where we know the number of */ + /* arguments, we increase the stack by the value of */ + /* known_othersubr_result_cnt */ + /* */ + /* for unhandled othersubrs the following pops adjust */ + /* the stack pointer as necessary */ + + count = cf2_stack_count( opStack ); + FT_ASSERT( (CF2_UInt)arg_cnt <= count ); + + opIdx += count - (CF2_UInt)arg_cnt; + + known_othersubr_result_cnt = 0; + result_cnt = 0; + + /* XXX TODO: The checks to `arg_count == <whatever>' */ + /* might not be correct; an othersubr expects a */ + /* certain number of operands on the PostScript stack */ + /* (as opposed to the T1 stack) but it doesn't have to */ + /* put them there by itself; previous othersubrs might */ + /* have left the operands there if they were not */ + /* followed by an appropriate number of pops */ + /* */ + /* On the other hand, Adobe Reader 7.0.8 for Linux */ + /* doesn't accept a font that contains charstrings */ + /* like */ + /* */ + /* 100 200 2 20 callothersubr */ + /* 300 1 20 callothersubr pop */ + /* */ + /* Perhaps this is the reason why BuildCharArray */ + /* exists. */ + + switch ( subr_no ) + { + case 0: /* end flex feature */ + if ( arg_cnt != 3 ) + goto Unexpected_OtherSubr; + + if ( initial_map_ready && + ( !decoder->flex_state || + decoder->num_flex_vectors != 7 ) ) + { + FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):" + " unexpected flex end\n" )); + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; + } + + /* the two `results' are popped */ + /* by the following setcurrentpoint */ + cf2_stack_pushFixed( opStack, curX ); + cf2_stack_pushFixed( opStack, curY ); + known_othersubr_result_cnt = 2; + break; + + case 1: /* start flex feature */ + if ( arg_cnt != 0 ) + goto Unexpected_OtherSubr; + + if ( !initial_map_ready ) + break; + + if ( ps_builder_check_points( &decoder->builder, 6 ) ) + goto exit; + + decoder->flex_state = 1; + decoder->num_flex_vectors = 0; + break; + + case 2: /* add flex vectors */ + { + FT_Int idx; + FT_Int idx2; + + + if ( arg_cnt != 0 ) + goto Unexpected_OtherSubr; + + if ( !initial_map_ready ) + break; + + if ( !decoder->flex_state ) + { + FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):" + " missing flex start\n" )); + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; + } + + /* note that we should not add a point for */ + /* index 0; this will move our current position */ + /* to the flex point without adding any point */ + /* to the outline */ + idx = decoder->num_flex_vectors++; + if ( idx > 0 && idx < 7 ) + { + /* in malformed fonts it is possible to have */ + /* other opcodes in the middle of a flex (which */ + /* don't increase `num_flex_vectors'); we thus */ + /* have to check whether we can add a point */ + + if ( ps_builder_check_points( &decoder->builder, + 1 ) ) + { + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; + } + + /* map: 1->2 2->4 3->6 4->2 5->4 6->6 */ + idx2 = ( idx > 3 ? idx - 3 : idx ) * 2; + + flexStore[idx2 - 2] = curX; + flexStore[idx2 - 1] = curY; + + if ( idx == 3 || idx == 6 ) + cf2_glyphpath_curveTo( &glyphPath, + flexStore[0], + flexStore[1], + flexStore[2], + flexStore[3], + flexStore[4], + flexStore[5] ); + } + } + break; + + case 3: /* change hints */ + if ( arg_cnt != 1 ) + goto Unexpected_OtherSubr; + + if ( initial_map_ready ) + { + /* do not clear hints if initial hintmap */ + /* is not ready - we need to collate all */ + cf2_arrstack_clear( &vStemHintArray ); + cf2_arrstack_clear( &hStemHintArray ); + + cf2_hintmask_init( &hintMask, error ); + hintMask.isValid = FALSE; + hintMask.isNew = TRUE; + } + + known_othersubr_result_cnt = 1; + break; + + case 12: + case 13: + /* counter control hints, clear stack */ + cf2_stack_clear( opStack ); + break; + + case 14: + case 15: + case 16: + case 17: + case 18: /* multiple masters */ + { + PS_Blend blend = decoder->blend; + FT_UInt num_points, nn, mm; + CF2_UInt delta; + CF2_UInt values; + + + if ( !blend ) + { + FT_ERROR(( + "cf2_interpT2CharString:" + " unexpected multiple masters operator\n" )); + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; + } + + num_points = (FT_UInt)subr_no - 13 + + ( subr_no == 18 ); + if ( arg_cnt != (FT_Int)( num_points * + blend->num_designs ) ) + { + FT_ERROR(( + "cf2_interpT2CharString:" + " incorrect number of multiple masters arguments\n" )); + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; + } + + /* We want to compute */ + /* */ + /* a0*w0 + a1*w1 + ... + ak*wk */ + /* */ + /* but we only have a0, a1-a0, a2-a0, ..., ak-a0. */ + /* */ + /* However, given that w0 + w1 + ... + wk == 1, we */ + /* can rewrite it easily as */ + /* */ + /* a0 + (a1-a0)*w1 + (a2-a0)*w2 + ... + (ak-a0)*wk */ + /* */ + /* where k == num_designs-1. */ + /* */ + /* I guess that's why it's written in this `compact' */ + /* form. */ + /* */ + delta = opIdx + num_points; + values = opIdx; + for ( nn = 0; nn < num_points; nn++ ) + { + CF2_Fixed tmp = cf2_stack_getReal( opStack, + values ); + + + for ( mm = 1; mm < blend->num_designs; mm++ ) + tmp = ADD_INT32( tmp, + FT_MulFix( + cf2_stack_getReal( opStack, + delta++ ), + blend->weight_vector[mm] ) ); + + cf2_stack_setReal( opStack, values++, tmp ); + } + cf2_stack_pop( opStack, + (CF2_UInt)arg_cnt - num_points ); + + known_othersubr_result_cnt = (FT_Int)num_points; + break; + } + + case 19: + /* <idx> 1 19 callothersubr */ + /* ==> replace elements starting from index */ + /* cvi( <idx> ) of BuildCharArray with */ + /* WeightVector */ + { + FT_Int idx; + PS_Blend blend = decoder->blend; + + + if ( arg_cnt != 1 || !blend ) + goto Unexpected_OtherSubr; + + idx = cf2_stack_popInt( opStack ); + + if ( idx < 0 || + (FT_UInt)idx + blend->num_designs > + decoder->len_buildchar ) + goto Unexpected_OtherSubr; + + ft_memcpy( &decoder->buildchar[idx], + blend->weight_vector, + blend->num_designs * + sizeof ( blend->weight_vector[0] ) ); + } + break; + + case 20: + /* <arg1> <arg2> 2 20 callothersubr pop */ + /* ==> push <arg1> + <arg2> onto T1 stack */ + { + CF2_F16Dot16 summand1; + CF2_F16Dot16 summand2; + + + if ( arg_cnt != 2 ) + goto Unexpected_OtherSubr; + + summand2 = cf2_stack_popFixed( opStack ); + summand1 = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, + ADD_INT32( summand1, + summand2 ) ); + known_othersubr_result_cnt = 1; + } + break; + + case 21: + /* <arg1> <arg2> 2 21 callothersubr pop */ + /* ==> push <arg1> - <arg2> onto T1 stack */ + { + CF2_F16Dot16 minuend; + CF2_F16Dot16 subtrahend; + + + if ( arg_cnt != 2 ) + goto Unexpected_OtherSubr; + + subtrahend = cf2_stack_popFixed( opStack ); + minuend = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, + SUB_INT32( minuend, + subtrahend ) ); + known_othersubr_result_cnt = 1; + } + break; + + case 22: + /* <arg1> <arg2> 2 22 callothersubr pop */ + /* ==> push <arg1> * <arg2> onto T1 stack */ + { + CF2_F16Dot16 factor1; + CF2_F16Dot16 factor2; + + + if ( arg_cnt != 2 ) + goto Unexpected_OtherSubr; + + factor2 = cf2_stack_popFixed( opStack ); + factor1 = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, + FT_MulFix( factor1, factor2 ) ); + known_othersubr_result_cnt = 1; + } + break; + + case 23: + /* <arg1> <arg2> 2 23 callothersubr pop */ + /* ==> push <arg1> / <arg2> onto T1 stack */ + { + CF2_F16Dot16 dividend; + CF2_F16Dot16 divisor; + + + if ( arg_cnt != 2 ) + goto Unexpected_OtherSubr; + + divisor = cf2_stack_popFixed( opStack ); + dividend = cf2_stack_popFixed( opStack ); + + if ( divisor == 0 ) + goto Unexpected_OtherSubr; + + cf2_stack_pushFixed( opStack, + FT_DivFix( dividend, + divisor ) ); + known_othersubr_result_cnt = 1; + } + break; + + case 24: + /* <val> <idx> 2 24 callothersubr */ + /* ==> set BuildCharArray[cvi( <idx> )] = <val> */ + { + CF2_Int idx; + PS_Blend blend = decoder->blend; + + + if ( arg_cnt != 2 || !blend ) + goto Unexpected_OtherSubr; + + idx = cf2_stack_popInt( opStack ); + + if ( idx < 0 || + (FT_UInt)idx >= decoder->len_buildchar ) + goto Unexpected_OtherSubr; + + decoder->buildchar[idx] = + cf2_stack_popFixed( opStack ); + } + break; + + case 25: + /* <idx> 1 25 callothersubr pop */ + /* ==> push BuildCharArray[cvi( idx )] */ + /* onto T1 stack */ + { + CF2_Int idx; + PS_Blend blend = decoder->blend; + + + if ( arg_cnt != 1 || !blend ) + goto Unexpected_OtherSubr; + + idx = cf2_stack_popInt( opStack ); + + if ( idx < 0 || + (FT_UInt)idx >= decoder->len_buildchar ) + goto Unexpected_OtherSubr; + + cf2_stack_pushFixed( opStack, + decoder->buildchar[idx] ); + known_othersubr_result_cnt = 1; + } + break; + +#if 0 + case 26: + /* <val> mark <idx> */ + /* ==> set BuildCharArray[cvi( <idx> )] = <val>, */ + /* leave mark on T1 stack */ + /* <val> <idx> */ + /* ==> set BuildCharArray[cvi( <idx> )] = <val> */ + XXX which routine has left its mark on the + XXX (PostScript) stack?; + break; +#endif + + case 27: + /* <res1> <res2> <val1> <val2> 4 27 callothersubr pop */ + /* ==> push <res1> onto T1 stack if <val1> <= <val2>, */ + /* otherwise push <res2> */ + { + CF2_F16Dot16 arg1; + CF2_F16Dot16 arg2; + CF2_F16Dot16 cond1; + CF2_F16Dot16 cond2; + + + if ( arg_cnt != 4 ) + goto Unexpected_OtherSubr; + + cond2 = cf2_stack_popFixed( opStack ); + cond1 = cf2_stack_popFixed( opStack ); + arg2 = cf2_stack_popFixed( opStack ); + arg1 = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, + cond1 <= cond2 ? arg1 : arg2 ); + known_othersubr_result_cnt = 1; + } + break; + + case 28: + /* 0 28 callothersubr pop */ + /* ==> push random value from interval [0, 1) */ + /* onto stack */ + { + CF2_F16Dot16 r; + + + if ( arg_cnt != 0 ) + goto Unexpected_OtherSubr; + + /* only use the lower 16 bits of `random' */ + /* to generate a number in the range (0;1] */ + r = (CF2_F16Dot16) + ( ( decoder->current_subfont->random & 0xFFFF ) + 1 ); + + decoder->current_subfont->random = + cff_random( decoder->current_subfont->random ); + + cf2_stack_pushFixed( opStack, r ); + known_othersubr_result_cnt = 1; + } + break; + + default: + if ( arg_cnt >= 0 && subr_no >= 0 ) + { + FT_Int i; + + + FT_ERROR(( + "cf2_interpT2CharString (Type 1 mode):" + " unknown othersubr [%d %d], wish me luck\n", + arg_cnt, subr_no )); + + /* store the unused args */ + /* for this unhandled OtherSubr */ + + if ( arg_cnt > PS_STORAGE_SIZE ) + arg_cnt = PS_STORAGE_SIZE; + result_cnt = arg_cnt; + + for ( i = 1; i <= arg_cnt; i++ ) + results[result_cnt - i] = + cf2_stack_popFixed( opStack ); + + break; + } + /* fall through */ + + Unexpected_OtherSubr: + FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):" + " invalid othersubr [%d %d]\n", + arg_cnt, subr_no )); + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; + } + } + continue; /* do not clear the stack */ + + case cf2_escPOP: + if ( !font->isT1 ) + FT_TRACE4(( " unknown op (12, %d)\n", op2 )); + else + { + FT_TRACE4(( " pop" )); + + if ( known_othersubr_result_cnt > 0 ) + { + known_othersubr_result_cnt--; + /* ignore, we pushed the operands ourselves */ + continue; + } + + if ( result_cnt == 0 ) + { + FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):" + " no more operands for othersubr\n" )); + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; + } + + result_cnt--; + cf2_stack_pushFixed( opStack, results[result_cnt] ); + } + continue; /* do not clear the stack */ + + case cf2_escDROP: + FT_TRACE4(( " drop\n" )); + + (void)cf2_stack_popFixed( opStack ); + continue; /* do not clear the stack */ + + case cf2_escPUT: + { + CF2_F16Dot16 val; + CF2_Int idx; + + + FT_TRACE4(( " put\n" )); + + idx = cf2_stack_popInt( opStack ); + val = cf2_stack_popFixed( opStack ); + + if ( idx >= 0 && idx < CF2_STORAGE_SIZE ) + storage[idx] = val; + } + continue; /* do not clear the stack */ + + case cf2_escGET: + { + CF2_Int idx; + + + FT_TRACE4(( " get\n" )); + + idx = cf2_stack_popInt( opStack ); + + if ( idx >= 0 && idx < CF2_STORAGE_SIZE ) + cf2_stack_pushFixed( opStack, storage[idx] ); + } + continue; /* do not clear the stack */ + + case cf2_escIFELSE: + { + CF2_F16Dot16 arg1; + CF2_F16Dot16 arg2; + CF2_F16Dot16 cond1; + CF2_F16Dot16 cond2; + + + FT_TRACE4(( " ifelse\n" )); + + cond2 = cf2_stack_popFixed( opStack ); + cond1 = cf2_stack_popFixed( opStack ); + arg2 = cf2_stack_popFixed( opStack ); + arg1 = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, + cond1 <= cond2 ? arg1 : arg2 ); + } + continue; /* do not clear the stack */ + + case cf2_escRANDOM: /* in spec */ + { + CF2_F16Dot16 r; + + + FT_TRACE4(( " random\n" )); + + /* only use the lower 16 bits of `random' */ + /* to generate a number in the range (0;1] */ + r = (CF2_F16Dot16) + ( ( decoder->current_subfont->random & 0xFFFF ) + 1 ); + + decoder->current_subfont->random = + cff_random( decoder->current_subfont->random ); + + cf2_stack_pushFixed( opStack, r ); + } + continue; /* do not clear the stack */ + + case cf2_escMUL: + { + CF2_F16Dot16 factor1; + CF2_F16Dot16 factor2; + + + FT_TRACE4(( " mul\n" )); + + factor2 = cf2_stack_popFixed( opStack ); + factor1 = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, + FT_MulFix( factor1, factor2 ) ); + } + continue; /* do not clear the stack */ + + case cf2_escSQRT: + { + CF2_F16Dot16 arg; + + + FT_TRACE4(( " sqrt\n" )); + + arg = cf2_stack_popFixed( opStack ); + if ( arg > 0 ) + { + /* use a start value that doesn't make */ + /* the algorithm's addition overflow */ + FT_Fixed root = arg < 10 ? arg : arg >> 1; + FT_Fixed new_root; + + + /* Babylonian method */ + for (;;) + { + new_root = ( root + FT_DivFix( arg, root ) + 1 ) >> 1; + if ( new_root == root ) + break; + root = new_root; + } + arg = new_root; + } + else + arg = 0; + + cf2_stack_pushFixed( opStack, arg ); + } + continue; /* do not clear the stack */ + + case cf2_escDUP: + { + CF2_F16Dot16 arg; + + + FT_TRACE4(( " dup\n" )); + + arg = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, arg ); + cf2_stack_pushFixed( opStack, arg ); + } + continue; /* do not clear the stack */ + + case cf2_escEXCH: + { + CF2_F16Dot16 arg1; + CF2_F16Dot16 arg2; + + + FT_TRACE4(( " exch\n" )); + + arg2 = cf2_stack_popFixed( opStack ); + arg1 = cf2_stack_popFixed( opStack ); + + cf2_stack_pushFixed( opStack, arg2 ); + cf2_stack_pushFixed( opStack, arg1 ); + } + continue; /* do not clear the stack */ + + case cf2_escINDEX: + { + CF2_Int idx; + CF2_UInt size; + + + FT_TRACE4(( " index\n" )); + + idx = cf2_stack_popInt( opStack ); + size = cf2_stack_count( opStack ); + + if ( size > 0 ) + { + /* for `cf2_stack_getReal', */ + /* index 0 is bottom of stack */ + CF2_UInt gr_idx; + + + if ( idx < 0 ) + gr_idx = size - 1; + else if ( (CF2_UInt)idx >= size ) + gr_idx = 0; + else + gr_idx = size - 1 - (CF2_UInt)idx; + + cf2_stack_pushFixed( opStack, + cf2_stack_getReal( opStack, + gr_idx ) ); + } + } + continue; /* do not clear the stack */ + + case cf2_escROLL: + { + CF2_Int idx; + CF2_Int count; + + + FT_TRACE4(( " roll\n" )); + + idx = cf2_stack_popInt( opStack ); + count = cf2_stack_popInt( opStack ); + + cf2_stack_roll( opStack, count, idx ); + } + continue; /* do not clear the stack */ + + case cf2_escSETCURRENTPT: + if ( !font->isT1 ) + FT_TRACE4(( " unknown op (12, %d)\n", op2 )); + else + { + FT_TRACE4(( " setcurrentpoint" )); + + if ( !initial_map_ready ) + break; + + /* From the T1 specification, section 6.4: */ + /* */ + /* The setcurrentpoint command is used only in */ + /* conjunction with results from OtherSubrs */ + /* procedures. */ + + /* known_othersubr_result_cnt != 0 is already handled */ + /* above. */ + + /* Note, however, that both Ghostscript and Adobe */ + /* Distiller handle this situation by silently */ + /* ignoring the inappropriate `setcurrentpoint' */ + /* instruction. So we do the same. */ +#if 0 + + if ( decoder->flex_state != 1 ) + { + FT_ERROR(( "cf2_interpT2CharString:" + " unexpected `setcurrentpoint'\n" )); + goto Syntax_Error; + } + else + ... +#endif + + curY = cf2_stack_popFixed( opStack ); + curX = cf2_stack_popFixed( opStack ); + + decoder->flex_state = 0; + } + break; + + } /* end of 2nd switch checking op2 */ + } + } + } /* end of 1st switch checking op2 */ + } /* case cf2_cmdESC */ + + break; + + case cf2_cmdHSBW: + if ( !font->isT1 ) + FT_TRACE4(( " unknown op (%d)\n", op1 )); + else + { + CF2_Fixed lsb_x; + PS_Builder* builder; + + + FT_TRACE4(( " hsbw" )); + + builder = &decoder->builder; + + builder->advance->x = cf2_stack_popFixed( opStack ); + builder->advance->y = 0; + + lsb_x = cf2_stack_popFixed( opStack ); + + builder->left_bearing->x = ADD_INT32( builder->left_bearing->x, + lsb_x ); + + haveWidth = TRUE; + + /* the `metrics_only' indicates that we only want to compute */ + /* the glyph's metrics (lsb + advance width), not load the */ + /* rest of it; so exit immediately */ + if ( builder->metrics_only ) + goto exit; + + if ( initial_map_ready ) + curX = ADD_INT32( curX, lsb_x ); + } + break; + + case cf2_cmdENDCHAR: + FT_TRACE4(( " endchar\n" )); + + if ( font->isT1 && !initial_map_ready ) + { + FT_TRACE5(( "cf2_interpT2CharString (Type 1 mode): " + "Build initial hintmap, rewinding...\n" )); + + /* trigger initial hintmap build */ + cf2_glyphpath_moveTo( &glyphPath, curX, curY ); + + initial_map_ready = TRUE; + + /* change hints routine - clear for rewind */ + cf2_arrstack_clear( &vStemHintArray ); + cf2_arrstack_clear( &hStemHintArray ); + + cf2_hintmask_init( &hintMask, error ); + hintMask.isValid = FALSE; + hintMask.isNew = TRUE; + + /* rewind charstring */ + /* some charstrings use endchar from a final subroutine call */ + /* without returning, detect these and exit to the top level */ + /* charstring */ + while ( charstringIndex > 0 ) + { + FT_TRACE4(( " return (leaving level %d)\n", charstringIndex )); + + /* restore position in previous charstring */ + charstring = (CF2_Buffer) + cf2_arrstack_getPointer( + &subrStack, + (CF2_UInt)--charstringIndex ); + } + charstring->ptr = charstring->start; + + break; + } + + if ( cf2_stack_count( opStack ) == 1 || + cf2_stack_count( opStack ) == 5 ) + { + if ( !haveWidth ) + *width = ADD_INT32( cf2_stack_getReal( opStack, 0 ), + nominalWidthX ); + } + + /* width is defined or default after this */ + haveWidth = TRUE; + + if ( decoder->width_only ) + goto exit; + + /* close path if still open */ + cf2_glyphpath_closeOpenPath( &glyphPath ); + + /* disable seac for CFF2 and Type1 */ + /* (charstring ending with args on stack) */ + if ( !font->isCFF2 && !font->isT1 && cf2_stack_count( opStack ) > 1 ) + { + /* must be either 4 or 5 -- */ + /* this is a (deprecated) implied `seac' operator */ + + CF2_Int achar; + CF2_Int bchar; + CF2_BufferRec component; + CF2_Fixed dummyWidth; /* ignore component width */ + FT_Error error2; + + + if ( doingSeac ) + { + lastError = FT_THROW( Invalid_Glyph_Format ); + goto exit; /* nested seac */ + } + + achar = cf2_stack_popInt( opStack ); + bchar = cf2_stack_popInt( opStack ); + + curY = cf2_stack_popFixed( opStack ); + curX = cf2_stack_popFixed( opStack ); + + error2 = cf2_getSeacComponent( decoder, achar, &component ); + if ( error2 ) + { + lastError = error2; /* pass FreeType error through */ + goto exit; + } + cf2_interpT2CharString( font, + &component, + callbacks, + translation, + TRUE, + curX, + curY, + &dummyWidth ); + cf2_freeSeacComponent( decoder, &component ); + + error2 = cf2_getSeacComponent( decoder, bchar, &component ); + if ( error2 ) + { + lastError = error2; /* pass FreeType error through */ + goto exit; + } + cf2_interpT2CharString( font, + &component, + callbacks, + translation, + TRUE, + 0, + 0, + &dummyWidth ); + cf2_freeSeacComponent( decoder, &component ); + } + goto exit; + + case cf2_cmdCNTRMASK: + case cf2_cmdHINTMASK: + /* the final \n in the tracing message gets added in */ + /* `cf2_hintmask_read' (which also traces the mask bytes) */ + FT_TRACE4(( op1 == cf2_cmdCNTRMASK ? " cntrmask" : " hintmask" )); + + /* never add hints after the mask is computed */ + if ( cf2_stack_count( opStack ) > 1 && + cf2_hintmask_isValid( &hintMask ) ) + { + FT_TRACE4(( "cf2_interpT2CharString: invalid hint mask\n" )); + break; + } + + /* if there are arguments on the stack, there this is an */ + /* implied cf2_cmdVSTEMHM */ + cf2_doStems( font, + opStack, + &vStemHintArray, + width, + &haveWidth, + 0 ); + + if ( decoder->width_only ) + goto exit; + + if ( op1 == cf2_cmdHINTMASK ) + { + /* consume the hint mask bytes which follow the operator */ + cf2_hintmask_read( &hintMask, + charstring, + cf2_arrstack_size( &hStemHintArray ) + + cf2_arrstack_size( &vStemHintArray ) ); + } + else + { + /* + * Consume the counter mask bytes which follow the operator: + * Build a temporary hint map, just to place and lock those + * stems participating in the counter mask. These are most + * likely the dominant hstems, and are grouped together in a + * few counter groups, not necessarily in correspondence + * with the hint groups. This reduces the chances of + * conflicts between hstems that are initially placed in + * separate hint groups and then brought together. The + * positions are copied back to `hStemHintArray', so we can + * discard `counterMask' and `counterHintMap'. + * + */ + CF2_HintMapRec counterHintMap; + CF2_HintMaskRec counterMask; + + + cf2_hintmap_init( &counterHintMap, + font, + &glyphPath.initialHintMap, + &glyphPath.hintMoves, + scaleY ); + cf2_hintmask_init( &counterMask, error ); + + cf2_hintmask_read( &counterMask, + charstring, + cf2_arrstack_size( &hStemHintArray ) + + cf2_arrstack_size( &vStemHintArray ) ); + cf2_hintmap_build( &counterHintMap, + &hStemHintArray, + &vStemHintArray, + &counterMask, + 0, + FALSE ); + } + break; + + case cf2_cmdRMOVETO: + FT_TRACE4(( " rmoveto\n" )); + + if ( font->isT1 && !decoder->flex_state && !haveWidth ) + FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):" + " No width. Use hsbw/sbw as first op\n" )); + + if ( cf2_stack_count( opStack ) > 2 && !haveWidth ) + *width = ADD_INT32( cf2_stack_getReal( opStack, 0 ), + nominalWidthX ); + + /* width is defined or default after this */ + haveWidth = TRUE; + + if ( decoder->width_only ) + goto exit; + + curY = ADD_INT32( curY, cf2_stack_popFixed( opStack ) ); + curX = ADD_INT32( curX, cf2_stack_popFixed( opStack ) ); + + if ( !decoder->flex_state ) + cf2_glyphpath_moveTo( &glyphPath, curX, curY ); + + break; + + case cf2_cmdHMOVETO: + FT_TRACE4(( " hmoveto\n" )); + + if ( font->isT1 && !decoder->flex_state && !haveWidth ) + FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):" + " No width. Use hsbw/sbw as first op\n" )); + + if ( cf2_stack_count( opStack ) > 1 && !haveWidth ) + *width = ADD_INT32( cf2_stack_getReal( opStack, 0 ), + nominalWidthX ); + + /* width is defined or default after this */ + haveWidth = TRUE; + + if ( decoder->width_only ) + goto exit; + + curX = ADD_INT32( curX, cf2_stack_popFixed( opStack ) ); + + if ( !decoder->flex_state ) + cf2_glyphpath_moveTo( &glyphPath, curX, curY ); + + break; + + case cf2_cmdRLINECURVE: + { + CF2_UInt count = cf2_stack_count( opStack ); + CF2_UInt idx = 0; + + + FT_TRACE4(( " rlinecurve\n" )); + + while ( idx + 6 < count ) + { + curX = ADD_INT32( curX, cf2_stack_getReal( opStack, + idx + 0 ) ); + curY = ADD_INT32( curY, cf2_stack_getReal( opStack, + idx + 1 ) ); + + cf2_glyphpath_lineTo( &glyphPath, curX, curY ); + idx += 2; + } + + while ( idx < count ) + { + CF2_Fixed x1, y1, x2, y2, x3, y3; + + + x1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curX ); + y1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), curY ); + x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), x1 ); + y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), y1 ); + x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 4 ), x2 ); + y3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 5 ), y2 ); + + cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); + + curX = x3; + curY = y3; + idx += 6; + } + + cf2_stack_clear( opStack ); + } + continue; /* no need to clear stack again */ + + case cf2_cmdVVCURVETO: + { + CF2_UInt count, count1 = cf2_stack_count( opStack ); + CF2_UInt idx = 0; + + + /* if `cf2_stack_count' isn't of the form 4n or 4n+1, */ + /* we enforce it by clearing the second bit */ + /* (and sorting the stack indexing to suit) */ + count = count1 & ~2U; + idx += count1 - count; + + FT_TRACE4(( " vvcurveto\n" )); + + while ( idx < count ) + { + CF2_Fixed x1, y1, x2, y2, x3, y3; + + + if ( ( count - idx ) & 1 ) + { + x1 = ADD_INT32( cf2_stack_getReal( opStack, idx ), curX ); + + idx++; + } + else + x1 = curX; + + y1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curY ); + x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), x1 ); + y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), y1 ); + x3 = x2; + y3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), y2 ); + + cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); + + curX = x3; + curY = y3; + idx += 4; + } + + cf2_stack_clear( opStack ); + } + continue; /* no need to clear stack again */ + + case cf2_cmdHHCURVETO: + { + CF2_UInt count, count1 = cf2_stack_count( opStack ); + CF2_UInt idx = 0; + + + /* if `cf2_stack_count' isn't of the form 4n or 4n+1, */ + /* we enforce it by clearing the second bit */ + /* (and sorting the stack indexing to suit) */ + count = count1 & ~2U; + idx += count1 - count; + + FT_TRACE4(( " hhcurveto\n" )); + + while ( idx < count ) + { + CF2_Fixed x1, y1, x2, y2, x3, y3; + + + if ( ( count - idx ) & 1 ) + { + y1 = ADD_INT32( cf2_stack_getReal( opStack, idx ), curY ); + + idx++; + } + else + y1 = curY; + + x1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curX ); + x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), x1 ); + y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), y1 ); + x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), x2 ); + y3 = y2; + + cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); + + curX = x3; + curY = y3; + idx += 4; + } + + cf2_stack_clear( opStack ); + } + continue; /* no need to clear stack again */ + + case cf2_cmdVHCURVETO: + case cf2_cmdHVCURVETO: + { + CF2_UInt count, count1 = cf2_stack_count( opStack ); + CF2_UInt idx = 0; + + FT_Bool alternate = FT_BOOL( op1 == cf2_cmdHVCURVETO ); + + + /* if `cf2_stack_count' isn't of the form 8n, 8n+1, */ + /* 8n+4, or 8n+5, we enforce it by clearing the */ + /* second bit */ + /* (and sorting the stack indexing to suit) */ + count = count1 & ~2U; + idx += count1 - count; + + FT_TRACE4(( alternate ? " hvcurveto\n" : " vhcurveto\n" )); + + while ( idx < count ) + { + CF2_Fixed x1, x2, x3, y1, y2, y3; + + + if ( alternate ) + { + x1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curX ); + y1 = curY; + x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), x1 ); + y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), y1 ); + y3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), y2 ); + + if ( count - idx == 5 ) + { + x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 4 ), x2 ); + + idx++; + } + else + x3 = x2; + + alternate = FALSE; + } + else + { + x1 = curX; + y1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curY ); + x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), x1 ); + y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), y1 ); + x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), x2 ); + + if ( count - idx == 5 ) + { + y3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 4 ), y2 ); + + idx++; + } + else + y3 = y2; + + alternate = TRUE; + } + + cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 ); + + curX = x3; + curY = y3; + idx += 4; + } + + cf2_stack_clear( opStack ); + } + continue; /* no need to clear stack again */ + + case cf2_cmdEXTENDEDNMBR: + { + CF2_Int v; + + CF2_Int byte1 = cf2_buf_readByte( charstring ); + CF2_Int byte2 = cf2_buf_readByte( charstring ); + + + v = (FT_Short)( ( byte1 << 8 ) | + byte2 ); + + FT_TRACE4(( " %d", v )); + + cf2_stack_pushInt( opStack, v ); + } + continue; + + default: + /* numbers */ + { + if ( /* op1 >= 32 && */ op1 <= 246 ) + { + CF2_Int v; + + + v = op1 - 139; + + FT_TRACE4(( " %d", v )); + + /* -107 .. 107 */ + cf2_stack_pushInt( opStack, v ); + } + + else if ( /* op1 >= 247 && */ op1 <= 250 ) + { + CF2_Int v; + + + v = op1; + v -= 247; + v *= 256; + v += cf2_buf_readByte( charstring ); + v += 108; + + FT_TRACE4(( " %d", v )); + + /* 108 .. 1131 */ + cf2_stack_pushInt( opStack, v ); + } + + else if ( /* op1 >= 251 && */ op1 <= 254 ) + { + CF2_Int v; + + + v = op1; + v -= 251; + v *= 256; + v += cf2_buf_readByte( charstring ); + v = -v - 108; + + FT_TRACE4(( " %d", v )); + + /* -1131 .. -108 */ + cf2_stack_pushInt( opStack, v ); + } + + else /* op1 == 255 */ + { + CF2_Fixed v; + + FT_UInt32 byte1 = (FT_UInt32)cf2_buf_readByte( charstring ); + FT_UInt32 byte2 = (FT_UInt32)cf2_buf_readByte( charstring ); + FT_UInt32 byte3 = (FT_UInt32)cf2_buf_readByte( charstring ); + FT_UInt32 byte4 = (FT_UInt32)cf2_buf_readByte( charstring ); + + + v = (CF2_Fixed)( ( byte1 << 24 ) | + ( byte2 << 16 ) | + ( byte3 << 8 ) | + byte4 ); + + /* + * For Type 1: + * + * According to the specification, values > 32000 or < -32000 + * must be followed by a `div' operator to make the result be + * in the range [-32000;32000]. We expect that the second + * argument of `div' is not a large number. Additionally, we + * don't handle stuff like `<large1> <large2> <num> div <num> + * div' or <large1> <large2> <num> div div'. This is probably + * not allowed anyway. + * + * <large> <num> <num>+ div is not checked but should not be + * allowed as the large value remains untouched. + * + */ + if ( font->isT1 ) + { + if ( v > 32000 || v < -32000 ) + { + if ( large_int ) + FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):" + " no `div' after large integer\n" )); + else + large_int = TRUE; + } + + FT_TRACE4(( " %d", v )); + + cf2_stack_pushInt( opStack, (CF2_Int)v ); + } + else + { + FT_TRACE4(( " %.5fF", v / 65536.0 )); + + cf2_stack_pushFixed( opStack, v ); + } + } + } + continue; /* don't clear stack */ + + } /* end of switch statement checking `op1' */ + + cf2_stack_clear( opStack ); + + } /* end of main interpreter loop */ + + /* we get here if the charstring ends without cf2_cmdENDCHAR */ + FT_TRACE4(( "cf2_interpT2CharString:" + " charstring ends without ENDCHAR\n" )); + + exit: + /* check whether last error seen is also the first one */ + cf2_setError( error, lastError ); + + if ( *error ) + FT_TRACE4(( "charstring error %d\n", *error )); + + /* free resources from objects we've used */ + cf2_glyphpath_finalize( &glyphPath ); + cf2_arrstack_finalize( &vStemHintArray ); + cf2_arrstack_finalize( &hStemHintArray ); + cf2_arrstack_finalize( &subrStack ); + cf2_stack_free( opStack ); + + FT_TRACE4(( "\n" )); + + return; + } + + +/* END */ diff --git a/src/3rdparty/freetype/src/psaux/psintrp.h b/src/3rdparty/freetype/src/psaux/psintrp.h new file mode 100644 index 0000000000..4790aaa302 --- /dev/null +++ b/src/3rdparty/freetype/src/psaux/psintrp.h @@ -0,0 +1,83 @@ +/***************************************************************************/ +/* */ +/* psintrp.h */ +/* */ +/* Adobe's CFF Interpreter (specification). */ +/* */ +/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#ifndef PSINTRP_H_ +#define PSINTRP_H_ + + +#include "psft.h" +#include "pshints.h" + + +FT_BEGIN_HEADER + + + FT_LOCAL( void ) + cf2_hintmask_init( CF2_HintMask hintmask, + FT_Error* error ); + FT_LOCAL( FT_Bool ) + cf2_hintmask_isValid( const CF2_HintMask hintmask ); + FT_LOCAL( FT_Bool ) + cf2_hintmask_isNew( const CF2_HintMask hintmask ); + FT_LOCAL( void ) + cf2_hintmask_setNew( CF2_HintMask hintmask, + FT_Bool val ); + FT_LOCAL( FT_Byte* ) + cf2_hintmask_getMaskPtr( CF2_HintMask hintmask ); + FT_LOCAL( void ) + cf2_hintmask_setAll( CF2_HintMask hintmask, + size_t bitCount ); + + FT_LOCAL( void ) + cf2_interpT2CharString( CF2_Font font, + CF2_Buffer charstring, + CF2_OutlineCallbacks callbacks, + const FT_Vector* translation, + FT_Bool doingSeac, + CF2_Fixed curX, + CF2_Fixed curY, + CF2_Fixed* width ); + + +FT_END_HEADER + + +#endif /* PSINTRP_H_ */ + + +/* END */ diff --git a/src/3rdparty/freetype/src/psaux/psobjs.c b/src/3rdparty/freetype/src/psaux/psobjs.c index 1d3c7e662c..f54bc7e416 100644 --- a/src/3rdparty/freetype/src/psaux/psobjs.c +++ b/src/3rdparty/freetype/src/psaux/psobjs.c @@ -4,7 +4,7 @@ /* */ /* Auxiliary functions for PostScript fonts (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,11 +20,13 @@ #include FT_INTERNAL_POSTSCRIPT_AUX_H #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_CALC_H +#include FT_DRIVER_H #include "psobjs.h" #include "psconv.h" #include "psauxerr.h" +#include "psauxmod.h" /*************************************************************************/ @@ -344,7 +346,7 @@ FT_Byte c = *cur; - ++cur; + cur++; if ( c == '\\' ) { @@ -370,17 +372,17 @@ case '\\': case '(': case ')': - ++cur; + cur++; break; default: /* skip octal escape or ignore backslash */ - for ( i = 0; i < 3 && cur < limit; ++i ) + for ( i = 0; i < 3 && cur < limit; i++ ) { if ( !IS_OCTAL_DIGIT( *cur ) ) break; - ++cur; + cur++; } } } @@ -455,19 +457,19 @@ FT_ASSERT( **acur == '{' ); - for ( cur = *acur; cur < limit && error == FT_Err_Ok; ++cur ) + for ( cur = *acur; cur < limit && error == FT_Err_Ok; cur++ ) { switch ( *cur ) { case '{': - ++embed; + embed++; break; case '}': - --embed; + embed--; if ( embed == 0 ) { - ++cur; + cur++; goto end; } break; @@ -695,7 +697,7 @@ /* ************ otherwise, it is any token **************/ default: token->start = cur; - token->type = ( *cur == '/' ? T1_TOKEN_TYPE_KEY : T1_TOKEN_TYPE_ANY ); + token->type = ( *cur == '/' ) ? T1_TOKEN_TYPE_KEY : T1_TOKEN_TYPE_ANY; ps_parser_skip_PS_token( parser ); cur = parser->cursor; if ( !parser->error ) @@ -750,7 +752,7 @@ if ( !token.type ) break; - if ( tokens != NULL && cur < limit ) + if ( tokens && cur < limit ) *cur = token; cur++; @@ -815,12 +817,12 @@ old_cur = cur; - if ( coords != NULL && count >= max_coords ) + if ( coords && count >= max_coords ) break; /* call PS_Conv_ToFixed() even if coords == NULL */ /* to properly parse number at `cur' */ - *( coords != NULL ? &coords[count] : &dummy ) = + *( coords ? &coords[count] : &dummy ) = (FT_Short)( PS_Conv_ToFixed( &cur, limit, 0 ) >> 16 ); if ( old_cur == cur ) @@ -895,12 +897,12 @@ old_cur = cur; - if ( values != NULL && count >= max_values ) + if ( values && count >= max_values ) break; /* call PS_Conv_ToFixed() even if coords == NULL */ /* to properly parse number at `cur' */ - *( values != NULL ? &values[count] : &dummy ) = + *( values ? &values[count] : &dummy ) = PS_Conv_ToFixed( &cur, limit, power_ten ); if ( old_cur == cur ) @@ -1087,9 +1089,9 @@ for ( ; count > 0; count--, idx++ ) { - FT_Byte* q = (FT_Byte*)objects[idx] + field->offset; + FT_Byte* q = (FT_Byte*)objects[idx] + field->offset; FT_Long val; - FT_String* string; + FT_String* string = NULL; skip_spaces( &cur, limit ); @@ -1172,7 +1174,7 @@ /* for this to work (FT_String**)q must have been */ /* initialized to NULL */ - if ( *(FT_String**)q != NULL ) + if ( *(FT_String**)q ) { FT_TRACE0(( "ps_parser_load_field: overwriting field %s\n", field->ident )); @@ -1217,7 +1219,7 @@ case T1_FIELD_TYPE_MM_BBOX: { FT_Memory memory = parser->memory; - FT_Fixed* temp; + FT_Fixed* temp = NULL; FT_Int result; FT_UInt i; @@ -1551,7 +1553,7 @@ builder->current = &loader->current.outline; FT_GlyphLoader_Rewind( loader ); - builder->hints_globals = size->internal; + builder->hints_globals = size->internal->module_data; builder->hints_funcs = NULL; if ( hinting ) @@ -1718,6 +1720,581 @@ first = outline->n_contours <= 1 ? 0 : outline->contours[outline->n_contours - 2] + 1; + /* in malformed fonts it can happen that a contour was started */ + /* but no points were added */ + if ( outline->n_contours && first == outline->n_points ) + { + outline->n_contours--; + return; + } + + /* We must not include the last point in the path if it */ + /* is located on the first point. */ + if ( outline->n_points > 1 ) + { + FT_Vector* p1 = outline->points + first; + FT_Vector* p2 = outline->points + outline->n_points - 1; + FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1; + + + /* `delete' last point only if it coincides with the first */ + /* point and it is not a control point (which can happen). */ + if ( p1->x == p2->x && p1->y == p2->y ) + if ( *control == FT_CURVE_TAG_ON ) + outline->n_points--; + } + + if ( outline->n_contours > 0 ) + { + /* Don't add contours only consisting of one point, i.e., */ + /* check whether the first and the last point is the same. */ + if ( first == outline->n_points - 1 ) + { + outline->n_contours--; + outline->n_points--; + } + else + outline->contours[outline->n_contours - 1] = + (short)( outline->n_points - 1 ); + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CFF BUILDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cff_builder_init */ + /* */ + /* <Description> */ + /* Initializes a given glyph builder. */ + /* */ + /* <InOut> */ + /* builder :: A pointer to the glyph builder to initialize. */ + /* */ + /* <Input> */ + /* face :: The current face object. */ + /* */ + /* size :: The current size object. */ + /* */ + /* glyph :: The current glyph object. */ + /* */ + /* hinting :: Whether hinting is active. */ + /* */ + FT_LOCAL_DEF( void ) + cff_builder_init( CFF_Builder* builder, + TT_Face face, + CFF_Size size, + CFF_GlyphSlot glyph, + FT_Bool hinting ) + { + builder->path_begun = 0; + builder->load_points = 1; + + builder->face = face; + builder->glyph = glyph; + builder->memory = face->root.memory; + + if ( glyph ) + { + FT_GlyphLoader loader = glyph->root.internal->loader; + + + builder->loader = loader; + builder->base = &loader->base.outline; + builder->current = &loader->current.outline; + FT_GlyphLoader_Rewind( loader ); + + builder->hints_globals = NULL; + builder->hints_funcs = NULL; + + if ( hinting && size ) + { + FT_Size ftsize = FT_SIZE( size ); + CFF_Internal internal = (CFF_Internal)ftsize->internal->module_data; + + if ( internal ) + { + builder->hints_globals = (void *)internal->topfont; + builder->hints_funcs = glyph->root.internal->glyph_hints; + } + } + } + + builder->pos_x = 0; + builder->pos_y = 0; + + builder->left_bearing.x = 0; + builder->left_bearing.y = 0; + builder->advance.x = 0; + builder->advance.y = 0; + + builder->funcs = cff_builder_funcs; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* cff_builder_done */ + /* */ + /* <Description> */ + /* Finalizes a given glyph builder. Its contents can still be used */ + /* after the call, but the function saves important information */ + /* within the corresponding glyph slot. */ + /* */ + /* <Input> */ + /* builder :: A pointer to the glyph builder to finalize. */ + /* */ + FT_LOCAL_DEF( void ) + cff_builder_done( CFF_Builder* builder ) + { + CFF_GlyphSlot glyph = builder->glyph; + + + if ( glyph ) + glyph->root.outline = *builder->base; + } + + + /* check that there is enough space for `count' more points */ + FT_LOCAL_DEF( FT_Error ) + cff_check_points( CFF_Builder* builder, + FT_Int count ) + { + return FT_GLYPHLOADER_CHECK_POINTS( builder->loader, count, 0 ); + } + + + /* add a new point, do not check space */ + FT_LOCAL_DEF( void ) + cff_builder_add_point( CFF_Builder* builder, + FT_Pos x, + FT_Pos y, + FT_Byte flag ) + { + FT_Outline* outline = builder->current; + + + if ( builder->load_points ) + { + FT_Vector* point = outline->points + outline->n_points; + FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; + +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( builder->face ); + + + if ( driver->hinting_engine == FT_HINTING_FREETYPE ) + { + point->x = x >> 16; + point->y = y >> 16; + } + else +#endif + { + /* cf2_decoder_parse_charstrings uses 16.16 coordinates */ + point->x = x >> 10; + point->y = y >> 10; + } + *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC ); + } + + outline->n_points++; + } + + + /* check space for a new on-curve point, then add it */ + FT_LOCAL_DEF( FT_Error ) + cff_builder_add_point1( CFF_Builder* builder, + FT_Pos x, + FT_Pos y ) + { + FT_Error error; + + + error = cff_check_points( builder, 1 ); + if ( !error ) + cff_builder_add_point( builder, x, y, 1 ); + + return error; + } + + + /* check space for a new contour, then add it */ + FT_LOCAL_DEF( FT_Error ) + cff_builder_add_contour( CFF_Builder* builder ) + { + FT_Outline* outline = builder->current; + FT_Error error; + + + if ( !builder->load_points ) + { + outline->n_contours++; + return FT_Err_Ok; + } + + error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 ); + if ( !error ) + { + if ( outline->n_contours > 0 ) + outline->contours[outline->n_contours - 1] = + (short)( outline->n_points - 1 ); + + outline->n_contours++; + } + + return error; + } + + + /* if a path was begun, add its first on-curve point */ + FT_LOCAL_DEF( FT_Error ) + cff_builder_start_point( CFF_Builder* builder, + FT_Pos x, + FT_Pos y ) + { + FT_Error error = FT_Err_Ok; + + + /* test whether we are building a new contour */ + if ( !builder->path_begun ) + { + builder->path_begun = 1; + error = cff_builder_add_contour( builder ); + if ( !error ) + error = cff_builder_add_point1( builder, x, y ); + } + + return error; + } + + + /* close the current contour */ + FT_LOCAL_DEF( void ) + cff_builder_close_contour( CFF_Builder* builder ) + { + FT_Outline* outline = builder->current; + FT_Int first; + + + if ( !outline ) + return; + + first = outline->n_contours <= 1 + ? 0 : outline->contours[outline->n_contours - 2] + 1; + + /* We must not include the last point in the path if it */ + /* is located on the first point. */ + if ( outline->n_points > 1 ) + { + FT_Vector* p1 = outline->points + first; + FT_Vector* p2 = outline->points + outline->n_points - 1; + FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1; + + + /* `delete' last point only if it coincides with the first */ + /* point and if it is not a control point (which can happen). */ + if ( p1->x == p2->x && p1->y == p2->y ) + if ( *control == FT_CURVE_TAG_ON ) + outline->n_points--; + } + + if ( outline->n_contours > 0 ) + { + /* Don't add contours only consisting of one point, i.e., */ + /* check whether begin point and last point are the same. */ + if ( first == outline->n_points - 1 ) + { + outline->n_contours--; + outline->n_points--; + } + else + outline->contours[outline->n_contours - 1] = + (short)( outline->n_points - 1 ); + } + } + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PS BUILDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ps_builder_init */ + /* */ + /* <Description> */ + /* Initializes a given glyph builder. */ + /* */ + /* <InOut> */ + /* builder :: A pointer to the glyph builder to initialize. */ + /* */ + /* <Input> */ + /* face :: The current face object. */ + /* */ + /* size :: The current size object. */ + /* */ + /* glyph :: The current glyph object. */ + /* */ + /* hinting :: Whether hinting should be applied. */ + /* */ + FT_LOCAL_DEF( void ) + ps_builder_init( PS_Builder* ps_builder, + void* builder, + FT_Bool is_t1 ) + { + FT_ZERO( ps_builder ); + + if ( is_t1 ) + { + T1_Builder t1builder = (T1_Builder)builder; + + + ps_builder->memory = t1builder->memory; + ps_builder->face = (FT_Face)t1builder->face; + ps_builder->glyph = (CFF_GlyphSlot)t1builder->glyph; + ps_builder->loader = t1builder->loader; + ps_builder->base = t1builder->base; + ps_builder->current = t1builder->current; + + ps_builder->pos_x = &t1builder->pos_x; + ps_builder->pos_y = &t1builder->pos_y; + + ps_builder->left_bearing = &t1builder->left_bearing; + ps_builder->advance = &t1builder->advance; + + ps_builder->bbox = &t1builder->bbox; + ps_builder->path_begun = 0; + ps_builder->load_points = t1builder->load_points; + ps_builder->no_recurse = t1builder->no_recurse; + + ps_builder->metrics_only = t1builder->metrics_only; + } + else + { + CFF_Builder* cffbuilder = (CFF_Builder*)builder; + + + ps_builder->memory = cffbuilder->memory; + ps_builder->face = (FT_Face)cffbuilder->face; + ps_builder->glyph = cffbuilder->glyph; + ps_builder->loader = cffbuilder->loader; + ps_builder->base = cffbuilder->base; + ps_builder->current = cffbuilder->current; + + ps_builder->pos_x = &cffbuilder->pos_x; + ps_builder->pos_y = &cffbuilder->pos_y; + + ps_builder->left_bearing = &cffbuilder->left_bearing; + ps_builder->advance = &cffbuilder->advance; + + ps_builder->bbox = &cffbuilder->bbox; + ps_builder->path_begun = cffbuilder->path_begun; + ps_builder->load_points = cffbuilder->load_points; + ps_builder->no_recurse = cffbuilder->no_recurse; + + ps_builder->metrics_only = cffbuilder->metrics_only; + } + + ps_builder->is_t1 = is_t1; + ps_builder->funcs = ps_builder_funcs; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ps_builder_done */ + /* */ + /* <Description> */ + /* Finalizes a given glyph builder. Its contents can still be used */ + /* after the call, but the function saves important information */ + /* within the corresponding glyph slot. */ + /* */ + /* <Input> */ + /* builder :: A pointer to the glyph builder to finalize. */ + /* */ + FT_LOCAL_DEF( void ) + ps_builder_done( PS_Builder* builder ) + { + CFF_GlyphSlot glyph = builder->glyph; + + + if ( glyph ) + glyph->root.outline = *builder->base; + } + + + /* check that there is enough space for `count' more points */ + FT_LOCAL_DEF( FT_Error ) + ps_builder_check_points( PS_Builder* builder, + FT_Int count ) + { + return FT_GLYPHLOADER_CHECK_POINTS( builder->loader, count, 0 ); + } + + + /* add a new point, do not check space */ + FT_LOCAL_DEF( void ) + ps_builder_add_point( PS_Builder* builder, + FT_Pos x, + FT_Pos y, + FT_Byte flag ) + { + FT_Outline* outline = builder->current; + + + if ( builder->load_points ) + { + FT_Vector* point = outline->points + outline->n_points; + FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; + +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( builder->face ); + + + if ( !builder->is_t1 && + driver->hinting_engine == FT_HINTING_FREETYPE ) + { + point->x = x >> 16; + point->y = y >> 16; + } + else +#endif +#ifdef T1_CONFIG_OPTION_OLD_ENGINE +#ifndef CFF_CONFIG_OPTION_OLD_ENGINE + PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( builder->face ); +#endif + if ( builder->is_t1 && + driver->hinting_engine == FT_HINTING_FREETYPE ) + { + point->x = FIXED_TO_INT( x ); + point->y = FIXED_TO_INT( y ); + } + else +#endif + { + /* cf2_decoder_parse_charstrings uses 16.16 coordinates */ + point->x = x >> 10; + point->y = y >> 10; + } + *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC ); + } + outline->n_points++; + } + + + /* check space for a new on-curve point, then add it */ + FT_LOCAL_DEF( FT_Error ) + ps_builder_add_point1( PS_Builder* builder, + FT_Pos x, + FT_Pos y ) + { + FT_Error error; + + + error = ps_builder_check_points( builder, 1 ); + if ( !error ) + ps_builder_add_point( builder, x, y, 1 ); + + return error; + } + + + /* check space for a new contour, then add it */ + FT_LOCAL_DEF( FT_Error ) + ps_builder_add_contour( PS_Builder* builder ) + { + FT_Outline* outline = builder->current; + FT_Error error; + + + /* this might happen in invalid fonts */ + if ( !outline ) + { + FT_ERROR(( "ps_builder_add_contour: no outline to add points to\n" )); + return FT_THROW( Invalid_File_Format ); + } + + if ( !builder->load_points ) + { + outline->n_contours++; + return FT_Err_Ok; + } + + error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 ); + if ( !error ) + { + if ( outline->n_contours > 0 ) + outline->contours[outline->n_contours - 1] = + (short)( outline->n_points - 1 ); + + outline->n_contours++; + } + + return error; + } + + + /* if a path was begun, add its first on-curve point */ + FT_LOCAL_DEF( FT_Error ) + ps_builder_start_point( PS_Builder* builder, + FT_Pos x, + FT_Pos y ) + { + FT_Error error = FT_Err_Ok; + + + /* test whether we are building a new contour */ + if ( !builder->path_begun ) + { + builder->path_begun = 1; + error = ps_builder_add_contour( builder ); + if ( !error ) + error = ps_builder_add_point1( builder, x, y ); + } + + return error; + } + + + /* close the current contour */ + FT_LOCAL_DEF( void ) + ps_builder_close_contour( PS_Builder* builder ) + { + FT_Outline* outline = builder->current; + FT_Int first; + + + if ( !outline ) + return; + + first = outline->n_contours <= 1 + ? 0 : outline->contours[outline->n_contours - 2] + 1; + + /* in malformed fonts it can happen that a contour was started */ + /* but no points were added */ + if ( outline->n_contours && first == outline->n_points ) + { + outline->n_contours--; + return; + } + /* We must not include the last point in the path if it */ /* is located on the first point. */ if ( outline->n_points > 1 ) @@ -1758,6 +2335,176 @@ /*************************************************************************/ /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ps_decoder_init */ + /* */ + /* <Description> */ + /* Creates a wrapper decoder for use in the combined */ + /* Type 1 / CFF interpreter. */ + /* */ + /* <InOut> */ + /* ps_decoder :: A pointer to the decoder to initialize. */ + /* */ + /* <Input> */ + /* decoder :: A pointer to the original decoder. */ + /* */ + /* is_t1 :: Flag indicating Type 1 or CFF */ + /* */ + FT_LOCAL_DEF( void ) + ps_decoder_init( PS_Decoder* ps_decoder, + void* decoder, + FT_Bool is_t1 ) + { + FT_ZERO( ps_decoder ); + + if ( is_t1 ) + { + T1_Decoder t1_decoder = (T1_Decoder)decoder; + + + ps_builder_init( &ps_decoder->builder, + &t1_decoder->builder, + is_t1 ); + + ps_decoder->cf2_instance = &t1_decoder->cf2_instance; + ps_decoder->psnames = t1_decoder->psnames; + + ps_decoder->num_glyphs = t1_decoder->num_glyphs; + ps_decoder->glyph_names = t1_decoder->glyph_names; + ps_decoder->hint_mode = t1_decoder->hint_mode; + ps_decoder->blend = t1_decoder->blend; + + ps_decoder->num_locals = (FT_UInt)t1_decoder->num_subrs; + ps_decoder->locals = t1_decoder->subrs; + ps_decoder->locals_len = t1_decoder->subrs_len; + ps_decoder->locals_hash = t1_decoder->subrs_hash; + + ps_decoder->buildchar = t1_decoder->buildchar; + ps_decoder->len_buildchar = t1_decoder->len_buildchar; + + ps_decoder->lenIV = t1_decoder->lenIV; + } + else + { + CFF_Decoder* cff_decoder = (CFF_Decoder*)decoder; + + + ps_builder_init( &ps_decoder->builder, + &cff_decoder->builder, + is_t1 ); + + ps_decoder->cff = cff_decoder->cff; + ps_decoder->cf2_instance = &cff_decoder->cff->cf2_instance; + ps_decoder->current_subfont = cff_decoder->current_subfont; + + ps_decoder->num_globals = cff_decoder->num_globals; + ps_decoder->globals = cff_decoder->globals; + ps_decoder->globals_bias = cff_decoder->globals_bias; + ps_decoder->num_locals = cff_decoder->num_locals; + ps_decoder->locals = cff_decoder->locals; + ps_decoder->locals_bias = cff_decoder->locals_bias; + + ps_decoder->glyph_width = &cff_decoder->glyph_width; + ps_decoder->width_only = cff_decoder->width_only; + + ps_decoder->hint_mode = cff_decoder->hint_mode; + + ps_decoder->get_glyph_callback = cff_decoder->get_glyph_callback; + ps_decoder->free_glyph_callback = cff_decoder->free_glyph_callback; + } + } + + + /* Synthesize a SubFont object for Type 1 fonts, for use in the */ + /* new interpreter to access Private dict data. */ + FT_LOCAL_DEF( void ) + t1_make_subfont( FT_Face face, + PS_Private priv, + CFF_SubFont subfont ) + { + CFF_Private cpriv = &subfont->private_dict; + FT_UInt n, count; + + + FT_ZERO( subfont ); + FT_ZERO( cpriv ); + + count = cpriv->num_blue_values = priv->num_blue_values; + for ( n = 0; n < count; n++ ) + cpriv->blue_values[n] = (FT_Pos)priv->blue_values[n]; + + count = cpriv->num_other_blues = priv->num_other_blues; + for ( n = 0; n < count; n++ ) + cpriv->other_blues[n] = (FT_Pos)priv->other_blues[n]; + + count = cpriv->num_family_blues = priv->num_family_blues; + for ( n = 0; n < count; n++ ) + cpriv->family_blues[n] = (FT_Pos)priv->family_blues[n]; + + count = cpriv->num_family_other_blues = priv->num_family_other_blues; + for ( n = 0; n < count; n++ ) + cpriv->family_other_blues[n] = (FT_Pos)priv->family_other_blues[n]; + + cpriv->blue_scale = priv->blue_scale; + cpriv->blue_shift = (FT_Pos)priv->blue_shift; + cpriv->blue_fuzz = (FT_Pos)priv->blue_fuzz; + + cpriv->standard_width = (FT_Pos)priv->standard_width[0]; + cpriv->standard_height = (FT_Pos)priv->standard_height[0]; + + count = cpriv->num_snap_widths = priv->num_snap_widths; + for ( n = 0; n < count; n++ ) + cpriv->snap_widths[n] = (FT_Pos)priv->snap_widths[n]; + + count = cpriv->num_snap_heights = priv->num_snap_heights; + for ( n = 0; n < count; n++ ) + cpriv->snap_heights[n] = (FT_Pos)priv->snap_heights[n]; + + cpriv->force_bold = priv->force_bold; + cpriv->lenIV = priv->lenIV; + cpriv->language_group = priv->language_group; + cpriv->expansion_factor = priv->expansion_factor; + + cpriv->subfont = subfont; + + + /* Initialize the random number generator. */ + if ( face->internal->random_seed != -1 ) + { + /* If we have a face-specific seed, use it. */ + /* If non-zero, update it to a positive value. */ + subfont->random = (FT_UInt32)face->internal->random_seed; + if ( face->internal->random_seed ) + { + do + { + face->internal->random_seed = (FT_Int32)cff_random( + (FT_UInt32)face->internal->random_seed ); + + } while ( face->internal->random_seed < 0 ); + } + } + if ( !subfont->random ) + { + FT_UInt32 seed; + + + /* compute random seed from some memory addresses */ + seed = (FT_UInt32)( (FT_Offset)(char*)&seed ^ + (FT_Offset)(char*)&face ^ + (FT_Offset)(char*)&subfont ); + seed = seed ^ ( seed >> 10 ) ^ ( seed >> 20 ); + if ( seed == 0 ) + seed = 0x7384; + + subfont->random = seed; + } + } + + FT_LOCAL_DEF( void ) t1_decrypt( FT_Byte* buffer, FT_Offset length, @@ -1771,4 +2518,16 @@ } + FT_LOCAL_DEF( FT_UInt32 ) + cff_random( FT_UInt32 r ) + { + /* a 32bit version of the `xorshift' algorithm */ + r ^= r << 13; + r ^= r >> 17; + r ^= r << 5; + + return r; + } + + /* END */ diff --git a/src/3rdparty/freetype/src/psaux/psobjs.h b/src/3rdparty/freetype/src/psaux/psobjs.h index bf879c1faf..8e0fe5fa4c 100644 --- a/src/3rdparty/freetype/src/psaux/psobjs.h +++ b/src/3rdparty/freetype/src/psaux/psobjs.h @@ -4,7 +4,7 @@ /* */ /* Auxiliary functions for PostScript fonts (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,12 +16,13 @@ /***************************************************************************/ -#ifndef __PSOBJS_H__ -#define __PSOBJS_H__ +#ifndef PSOBJS_H_ +#define PSOBJS_H_ #include <ft2build.h> #include FT_INTERNAL_POSTSCRIPT_AUX_H +#include FT_INTERNAL_CFF_OBJECTS_TYPES_H FT_BEGIN_HEADER @@ -190,6 +191,92 @@ FT_BEGIN_HEADER t1_builder_close_contour( T1_Builder builder ); + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** CFF BUILDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( void ) + cff_builder_init( CFF_Builder* builder, + TT_Face face, + CFF_Size size, + CFF_GlyphSlot glyph, + FT_Bool hinting ); + + FT_LOCAL( void ) + cff_builder_done( CFF_Builder* builder ); + + FT_LOCAL( FT_Error ) + cff_check_points( CFF_Builder* builder, + FT_Int count ); + + FT_LOCAL( void ) + cff_builder_add_point( CFF_Builder* builder, + FT_Pos x, + FT_Pos y, + FT_Byte flag ); + FT_LOCAL( FT_Error ) + cff_builder_add_point1( CFF_Builder* builder, + FT_Pos x, + FT_Pos y ); + FT_LOCAL( FT_Error ) + cff_builder_start_point( CFF_Builder* builder, + FT_Pos x, + FT_Pos y ); + FT_LOCAL( void ) + cff_builder_close_contour( CFF_Builder* builder ); + + FT_LOCAL( FT_Error ) + cff_builder_add_contour( CFF_Builder* builder ); + + + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** PS BUILDER *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL( void ) + ps_builder_init( PS_Builder* ps_builder, + void* builder, + FT_Bool is_t1 ); + + + FT_LOCAL( void ) + ps_builder_done( PS_Builder* builder ); + + FT_LOCAL( FT_Error ) + ps_builder_check_points( PS_Builder* builder, + FT_Int count ); + + FT_LOCAL( void ) + ps_builder_add_point( PS_Builder* builder, + FT_Pos x, + FT_Pos y, + FT_Byte flag ); + + FT_LOCAL( FT_Error ) + ps_builder_add_point1( PS_Builder* builder, + FT_Pos x, + FT_Pos y ); + + FT_LOCAL( FT_Error ) + ps_builder_add_contour( PS_Builder* builder ); + + FT_LOCAL( FT_Error ) + ps_builder_start_point( PS_Builder* builder, + FT_Pos x, + FT_Pos y ); + + FT_LOCAL( void ) + ps_builder_close_contour( PS_Builder* builder ); + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -198,15 +285,29 @@ FT_BEGIN_HEADER /*************************************************************************/ /*************************************************************************/ + FT_LOCAL( void ) + ps_decoder_init( PS_Decoder* ps_decoder, + void* decoder, + FT_Bool is_t1 ); + + FT_LOCAL( void ) + t1_make_subfont( FT_Face face, + PS_Private priv, + CFF_SubFont subfont ); + FT_LOCAL( void ) t1_decrypt( FT_Byte* buffer, FT_Offset length, FT_UShort seed ); + FT_LOCAL( FT_UInt32 ) + cff_random( FT_UInt32 r ); + + FT_END_HEADER -#endif /* __PSOBJS_H__ */ +#endif /* PSOBJS_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/psaux/psread.c b/src/3rdparty/freetype/src/psaux/psread.c new file mode 100644 index 0000000000..719863ce17 --- /dev/null +++ b/src/3rdparty/freetype/src/psaux/psread.c @@ -0,0 +1,112 @@ +/***************************************************************************/ +/* */ +/* psread.c */ +/* */ +/* Adobe's code for stream handling (body). */ +/* */ +/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#include "psft.h" +#include FT_INTERNAL_DEBUG_H + +#include "psglue.h" + +#include "pserror.h" + + + /* Define CF2_IO_FAIL as 1 to enable random errors and random */ + /* value errors in I/O. */ +#define CF2_IO_FAIL 0 + + +#if CF2_IO_FAIL + + /* set the .00 value to a nonzero probability */ + static int + randomError2( void ) + { + /* for region buffer ReadByte (interp) function */ + return (double)rand() / RAND_MAX < .00; + } + + /* set the .00 value to a nonzero probability */ + static CF2_Int + randomValue() + { + return (double)rand() / RAND_MAX < .00 ? rand() : 0; + } + +#endif /* CF2_IO_FAIL */ + + + /* Region Buffer */ + /* */ + /* Can be constructed from a copied buffer managed by */ + /* `FCM_getDatablock'. */ + /* Reads bytes with check for end of buffer. */ + + /* reading past the end of the buffer sets error and returns zero */ + FT_LOCAL_DEF( CF2_Int ) + cf2_buf_readByte( CF2_Buffer buf ) + { + if ( buf->ptr < buf->end ) + { +#if CF2_IO_FAIL + if ( randomError2() ) + { + CF2_SET_ERROR( buf->error, Invalid_Stream_Operation ); + return 0; + } + + return *(buf->ptr)++ + randomValue(); +#else + return *(buf->ptr)++; +#endif + } + else + { + CF2_SET_ERROR( buf->error, Invalid_Stream_Operation ); + return 0; + } + } + + + /* note: end condition can occur without error */ + FT_LOCAL_DEF( FT_Bool ) + cf2_buf_isEnd( CF2_Buffer buf ) + { + return (FT_Bool)( buf->ptr >= buf->end ); + } + + +/* END */ diff --git a/src/3rdparty/freetype/src/psaux/psread.h b/src/3rdparty/freetype/src/psaux/psread.h new file mode 100644 index 0000000000..464b29ba74 --- /dev/null +++ b/src/3rdparty/freetype/src/psaux/psread.h @@ -0,0 +1,68 @@ +/***************************************************************************/ +/* */ +/* psread.h */ +/* */ +/* Adobe's code for stream handling (specification). */ +/* */ +/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#ifndef PSREAD_H_ +#define PSREAD_H_ + + +FT_BEGIN_HEADER + + + typedef struct CF2_BufferRec_ + { + FT_Error* error; + const FT_Byte* start; + const FT_Byte* end; + const FT_Byte* ptr; + + } CF2_BufferRec, *CF2_Buffer; + + + FT_LOCAL( CF2_Int ) + cf2_buf_readByte( CF2_Buffer buf ); + FT_LOCAL( FT_Bool ) + cf2_buf_isEnd( CF2_Buffer buf ); + + +FT_END_HEADER + + +#endif /* PSREAD_H_ */ + + +/* END */ diff --git a/src/3rdparty/freetype/src/psaux/psstack.c b/src/3rdparty/freetype/src/psaux/psstack.c new file mode 100644 index 0000000000..69d063349a --- /dev/null +++ b/src/3rdparty/freetype/src/psaux/psstack.c @@ -0,0 +1,328 @@ +/***************************************************************************/ +/* */ +/* psstack.c */ +/* */ +/* Adobe's code for emulating a CFF stack (body). */ +/* */ +/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#include "psft.h" +#include FT_INTERNAL_DEBUG_H + +#include "psglue.h" +#include "psfont.h" +#include "psstack.h" + +#include "pserror.h" + + + /* Allocate and initialize an instance of CF2_Stack. */ + /* Note: This function returns NULL on error (does not set */ + /* `error'). */ + FT_LOCAL_DEF( CF2_Stack ) + cf2_stack_init( FT_Memory memory, + FT_Error* e, + FT_UInt stackSize ) + { + FT_Error error = FT_Err_Ok; /* for FT_NEW */ + + CF2_Stack stack = NULL; + + + if ( !FT_NEW( stack ) ) + { + /* initialize the structure; FT_NEW zeroes it */ + stack->memory = memory; + stack->error = e; + } + + /* allocate the stack buffer */ + if ( FT_NEW_ARRAY( stack->buffer, stackSize ) ) + { + FT_FREE( stack ); + return NULL; + } + + stack->stackSize = stackSize; + stack->top = stack->buffer; /* empty stack */ + + return stack; + } + + + FT_LOCAL_DEF( void ) + cf2_stack_free( CF2_Stack stack ) + { + if ( stack ) + { + FT_Memory memory = stack->memory; + + /* free the buffer */ + FT_FREE( stack->buffer ); + + /* free the main structure */ + FT_FREE( stack ); + } + } + + + FT_LOCAL_DEF( CF2_UInt ) + cf2_stack_count( CF2_Stack stack ) + { + return (CF2_UInt)( stack->top - stack->buffer ); + } + + + FT_LOCAL_DEF( void ) + cf2_stack_pushInt( CF2_Stack stack, + CF2_Int val ) + { + if ( stack->top == stack->buffer + stack->stackSize ) + { + CF2_SET_ERROR( stack->error, Stack_Overflow ); + return; /* stack overflow */ + } + + stack->top->u.i = val; + stack->top->type = CF2_NumberInt; + stack->top++; + } + + + FT_LOCAL_DEF( void ) + cf2_stack_pushFixed( CF2_Stack stack, + CF2_Fixed val ) + { + if ( stack->top == stack->buffer + stack->stackSize ) + { + CF2_SET_ERROR( stack->error, Stack_Overflow ); + return; /* stack overflow */ + } + + stack->top->u.r = val; + stack->top->type = CF2_NumberFixed; + stack->top++; + } + + + /* this function is only allowed to pop an integer type */ + FT_LOCAL_DEF( CF2_Int ) + cf2_stack_popInt( CF2_Stack stack ) + { + if ( stack->top == stack->buffer ) + { + CF2_SET_ERROR( stack->error, Stack_Underflow ); + return 0; /* underflow */ + } + if ( stack->top[-1].type != CF2_NumberInt ) + { + CF2_SET_ERROR( stack->error, Syntax_Error ); + return 0; /* type mismatch */ + } + + stack->top--; + + return stack->top->u.i; + } + + + /* Note: type mismatch is silently cast */ + /* TODO: check this */ + FT_LOCAL_DEF( CF2_Fixed ) + cf2_stack_popFixed( CF2_Stack stack ) + { + if ( stack->top == stack->buffer ) + { + CF2_SET_ERROR( stack->error, Stack_Underflow ); + return cf2_intToFixed( 0 ); /* underflow */ + } + + stack->top--; + + switch ( stack->top->type ) + { + case CF2_NumberInt: + return cf2_intToFixed( stack->top->u.i ); + case CF2_NumberFrac: + return cf2_fracToFixed( stack->top->u.f ); + default: + return stack->top->u.r; + } + } + + + /* Note: type mismatch is silently cast */ + /* TODO: check this */ + FT_LOCAL_DEF( CF2_Fixed ) + cf2_stack_getReal( CF2_Stack stack, + CF2_UInt idx ) + { + FT_ASSERT( cf2_stack_count( stack ) <= stack->stackSize ); + + if ( idx >= cf2_stack_count( stack ) ) + { + CF2_SET_ERROR( stack->error, Stack_Overflow ); + return cf2_intToFixed( 0 ); /* bounds error */ + } + + switch ( stack->buffer[idx].type ) + { + case CF2_NumberInt: + return cf2_intToFixed( stack->buffer[idx].u.i ); + case CF2_NumberFrac: + return cf2_fracToFixed( stack->buffer[idx].u.f ); + default: + return stack->buffer[idx].u.r; + } + } + + + /* provide random access to stack */ + FT_LOCAL_DEF( void ) + cf2_stack_setReal( CF2_Stack stack, + CF2_UInt idx, + CF2_Fixed val ) + { + if ( idx > cf2_stack_count( stack ) ) + { + CF2_SET_ERROR( stack->error, Stack_Overflow ); + return; + } + + stack->buffer[idx].u.r = val; + stack->buffer[idx].type = CF2_NumberFixed; + } + + + /* discard (pop) num values from stack */ + FT_LOCAL_DEF( void ) + cf2_stack_pop( CF2_Stack stack, + CF2_UInt num ) + { + if ( num > cf2_stack_count( stack ) ) + { + CF2_SET_ERROR( stack->error, Stack_Underflow ); + return; + } + stack->top -= num; + } + + + FT_LOCAL_DEF( void ) + cf2_stack_roll( CF2_Stack stack, + CF2_Int count, + CF2_Int shift ) + { + /* we initialize this variable to avoid compiler warnings */ + CF2_StackNumber last = { { 0 }, CF2_NumberInt }; + + CF2_Int start_idx, idx, i; + + + if ( count < 2 ) + return; /* nothing to do (values 0 and 1), or undefined value */ + + if ( (CF2_UInt)count > cf2_stack_count( stack ) ) + { + CF2_SET_ERROR( stack->error, Stack_Overflow ); + return; + } + + if ( shift < 0 ) + shift = -( ( -shift ) % count ); + else + shift %= count; + + if ( shift == 0 ) + return; /* nothing to do */ + + /* We use the following algorithm to do the rolling, */ + /* which needs two temporary variables only. */ + /* */ + /* Example: */ + /* */ + /* count = 8 */ + /* shift = 2 */ + /* */ + /* stack indices before roll: 7 6 5 4 3 2 1 0 */ + /* stack indices after roll: 1 0 7 6 5 4 3 2 */ + /* */ + /* The value of index 0 gets moved to index 2, while */ + /* the old value of index 2 gets moved to index 4, */ + /* and so on. We thus have the following copying */ + /* chains for shift value 2. */ + /* */ + /* 0 -> 2 -> 4 -> 6 -> 0 */ + /* 1 -> 3 -> 5 -> 7 -> 1 */ + /* */ + /* If `count' and `shift' are incommensurable, we */ + /* have a single chain only. Otherwise, increase */ + /* the start index by 1 after the first chain, then */ + /* do the next chain until all elements in all */ + /* chains are handled. */ + + start_idx = -1; + idx = -1; + for ( i = 0; i < count; i++ ) + { + CF2_StackNumber tmp; + + + if ( start_idx == idx ) + { + start_idx++; + idx = start_idx; + last = stack->buffer[idx]; + } + + idx += shift; + if ( idx >= count ) + idx -= count; + else if ( idx < 0 ) + idx += count; + + tmp = stack->buffer[idx]; + stack->buffer[idx] = last; + last = tmp; + } + } + + + FT_LOCAL_DEF( void ) + cf2_stack_clear( CF2_Stack stack ) + { + stack->top = stack->buffer; + } + + +/* END */ diff --git a/src/3rdparty/freetype/src/psaux/psstack.h b/src/3rdparty/freetype/src/psaux/psstack.h new file mode 100644 index 0000000000..38f7b41c68 --- /dev/null +++ b/src/3rdparty/freetype/src/psaux/psstack.h @@ -0,0 +1,121 @@ +/***************************************************************************/ +/* */ +/* psstack.h */ +/* */ +/* Adobe's code for emulating a CFF stack (specification). */ +/* */ +/* Copyright 2007-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#ifndef PSSTACK_H_ +#define PSSTACK_H_ + + +FT_BEGIN_HEADER + + + /* CFF operand stack; specified maximum of 48 or 192 values */ + typedef struct CF2_StackNumber_ + { + union + { + CF2_Fixed r; /* 16.16 fixed point */ + CF2_Frac f; /* 2.30 fixed point (for font matrix) */ + CF2_Int i; + } u; + + CF2_NumberType type; + + } CF2_StackNumber; + + + typedef struct CF2_StackRec_ + { + FT_Memory memory; + FT_Error* error; + CF2_StackNumber* buffer; + CF2_StackNumber* top; + FT_UInt stackSize; + + } CF2_StackRec, *CF2_Stack; + + + FT_LOCAL( CF2_Stack ) + cf2_stack_init( FT_Memory memory, + FT_Error* error, + FT_UInt stackSize ); + FT_LOCAL( void ) + cf2_stack_free( CF2_Stack stack ); + + FT_LOCAL( CF2_UInt ) + cf2_stack_count( CF2_Stack stack ); + + FT_LOCAL( void ) + cf2_stack_pushInt( CF2_Stack stack, + CF2_Int val ); + FT_LOCAL( void ) + cf2_stack_pushFixed( CF2_Stack stack, + CF2_Fixed val ); + + FT_LOCAL( CF2_Int ) + cf2_stack_popInt( CF2_Stack stack ); + FT_LOCAL( CF2_Fixed ) + cf2_stack_popFixed( CF2_Stack stack ); + + FT_LOCAL( CF2_Fixed ) + cf2_stack_getReal( CF2_Stack stack, + CF2_UInt idx ); + FT_LOCAL( void ) + cf2_stack_setReal( CF2_Stack stack, + CF2_UInt idx, + CF2_Fixed val ); + + FT_LOCAL( void ) + cf2_stack_pop( CF2_Stack stack, + CF2_UInt num ); + + FT_LOCAL( void ) + cf2_stack_roll( CF2_Stack stack, + CF2_Int count, + CF2_Int idx ); + + FT_LOCAL( void ) + cf2_stack_clear( CF2_Stack stack ); + + +FT_END_HEADER + + +#endif /* PSSTACK_H_ */ + + +/* END */ diff --git a/src/3rdparty/freetype/src/psaux/pstypes.h b/src/3rdparty/freetype/src/psaux/pstypes.h new file mode 100644 index 0000000000..dfbaa3d475 --- /dev/null +++ b/src/3rdparty/freetype/src/psaux/pstypes.h @@ -0,0 +1,78 @@ +/***************************************************************************/ +/* */ +/* pstypes.h */ +/* */ +/* Adobe's code for defining data types (specification only). */ +/* */ +/* Copyright 2011-2013 Adobe Systems Incorporated. */ +/* */ +/* This software, and all works of authorship, whether in source or */ +/* object code form as indicated by the copyright notice(s) included */ +/* herein (collectively, the "Work") is made available, and may only be */ +/* used, modified, and distributed under the FreeType Project License, */ +/* LICENSE.TXT. Additionally, subject to the terms and conditions of the */ +/* FreeType Project License, each contributor to the Work hereby grants */ +/* to any individual or legal entity exercising permissions granted by */ +/* the FreeType Project License and this section (hereafter, "You" or */ +/* "Your") a perpetual, worldwide, non-exclusive, no-charge, */ +/* royalty-free, irrevocable (except as stated in this section) patent */ +/* license to make, have made, use, offer to sell, sell, import, and */ +/* otherwise transfer the Work, where such license applies only to those */ +/* patent claims licensable by such contributor that are necessarily */ +/* infringed by their contribution(s) alone or by combination of their */ +/* contribution(s) with the Work to which such contribution(s) was */ +/* submitted. If You institute patent litigation against any entity */ +/* (including a cross-claim or counterclaim in a lawsuit) alleging that */ +/* the Work or a contribution incorporated within the Work constitutes */ +/* direct or contributory patent infringement, then any patent licenses */ +/* granted to You under this License for that Work shall terminate as of */ +/* the date such litigation is filed. */ +/* */ +/* By using, modifying, or distributing the Work you indicate that you */ +/* have read and understood the terms and conditions of the */ +/* FreeType Project License as well as those provided in this section, */ +/* and you accept them fully. */ +/* */ +/***************************************************************************/ + + +#ifndef PSTYPES_H_ +#define PSTYPES_H_ + +#include <ft2build.h> +#include FT_FREETYPE_H + + +FT_BEGIN_HEADER + + + /* + * The data models that we expect to support are as follows: + * + * name char short int long long-long pointer example + * ----------------------------------------------------- + * ILP32 8 16 32 32 64* 32 32-bit MacOS, x86 + * LLP64 8 16 32 32 64 64 x64 + * LP64 8 16 32 64 64 64 64-bit MacOS + * + * *) type may be supported by emulation on a 32-bit architecture + * + */ + + + /* integers at least 32 bits wide */ +#define CF2_UInt FT_UFast +#define CF2_Int FT_Fast + + + /* fixed-float numbers */ + typedef FT_Int32 CF2_F16Dot16; + + +FT_END_HEADER + + +#endif /* PSTYPES_H_ */ + + +/* END */ diff --git a/src/3rdparty/freetype/src/psaux/rules.mk b/src/3rdparty/freetype/src/psaux/rules.mk index 0d2118c014..a87bfe9687 100644 --- a/src/3rdparty/freetype/src/psaux/rules.mk +++ b/src/3rdparty/freetype/src/psaux/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2015 by +# Copyright 1996-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -33,12 +33,25 @@ PSAUX_DRV_SRC := $(PSAUX_DIR)/psobjs.c \ $(PSAUX_DIR)/t1cmap.c \ $(PSAUX_DIR)/afmparse.c \ $(PSAUX_DIR)/psconv.c \ - $(PSAUX_DIR)/psauxmod.c + $(PSAUX_DIR)/psauxmod.c \ + $(PSAUX_DIR)/psarrst.c \ + $(PSAUX_DIR)/psblues.c \ + $(PSAUX_DIR)/pserror.c \ + $(PSAUX_DIR)/psfont.c \ + $(PSAUX_DIR)/psft.c \ + $(PSAUX_DIR)/pshints.c \ + $(PSAUX_DIR)/psintrp.c \ + $(PSAUX_DIR)/psread.c \ + $(PSAUX_DIR)/psstack.c \ + $(PSAUX_DIR)/cffdecode.c # PSAUX driver headers # PSAUX_DRV_H := $(PSAUX_DRV_SRC:%c=%h) \ - $(PSAUX_DIR)/psauxerr.h + $(PSAUX_DIR)/psauxerr.h \ + $(PSAUX_DIR)/psfixed.h \ + $(PSAUX_DIR)/psglue.h \ + $(PSAUX_DIR)/pstypes.h # PSAUX driver object(s) diff --git a/src/3rdparty/freetype/src/psaux/t1cmap.c b/src/3rdparty/freetype/src/psaux/t1cmap.c index 2e2d433fc4..112a7892ba 100644 --- a/src/3rdparty/freetype/src/psaux/t1cmap.c +++ b/src/3rdparty/freetype/src/psaux/t1cmap.c @@ -4,7 +4,7 @@ /* */ /* Type 1 character map support (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -45,7 +45,7 @@ cmap->code_to_sid = is_expert ? psnames->adobe_expert_encoding : psnames->adobe_std_encoding; - FT_ASSERT( cmap->code_to_sid != NULL ); + FT_ASSERT( cmap->code_to_sid ); } @@ -136,12 +136,16 @@ { sizeof ( T1_CMapStdRec ), - (FT_CMap_InitFunc) t1_cmap_standard_init, - (FT_CMap_DoneFunc) t1_cmap_std_done, - (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, - (FT_CMap_CharNextFunc) t1_cmap_std_char_next, + (FT_CMap_InitFunc) t1_cmap_standard_init, /* init */ + (FT_CMap_DoneFunc) t1_cmap_std_done, /* done */ + (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, /* char_index */ + (FT_CMap_CharNextFunc) t1_cmap_std_char_next, /* char_next */ - NULL, NULL, NULL, NULL, NULL + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL /* variantchar_list */ }; @@ -161,12 +165,16 @@ { sizeof ( T1_CMapStdRec ), - (FT_CMap_InitFunc) t1_cmap_expert_init, - (FT_CMap_DoneFunc) t1_cmap_std_done, - (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, - (FT_CMap_CharNextFunc) t1_cmap_std_char_next, + (FT_CMap_InitFunc) t1_cmap_expert_init, /* init */ + (FT_CMap_DoneFunc) t1_cmap_std_done, /* done */ + (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, /* char_index */ + (FT_CMap_CharNextFunc) t1_cmap_std_char_next, /* char_next */ - NULL, NULL, NULL, NULL, NULL + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL /* variantchar_list */ }; @@ -193,7 +201,7 @@ cmap->count = (FT_UInt)encoding->code_last - cmap->first; cmap->indices = encoding->char_index; - FT_ASSERT( cmap->indices != NULL ); + FT_ASSERT( cmap->indices ); FT_ASSERT( encoding->code_first <= encoding->code_last ); return 0; @@ -232,7 +240,7 @@ FT_UInt32 char_code = *pchar_code; - ++char_code; + char_code++; if ( char_code < cmap->first ) char_code = cmap->first; @@ -257,12 +265,16 @@ { sizeof ( T1_CMapCustomRec ), - (FT_CMap_InitFunc) t1_cmap_custom_init, - (FT_CMap_DoneFunc) t1_cmap_custom_done, - (FT_CMap_CharIndexFunc)t1_cmap_custom_char_index, - (FT_CMap_CharNextFunc) t1_cmap_custom_char_next, + (FT_CMap_InitFunc) t1_cmap_custom_init, /* init */ + (FT_CMap_DoneFunc) t1_cmap_custom_done, /* done */ + (FT_CMap_CharIndexFunc)t1_cmap_custom_char_index, /* char_index */ + (FT_CMap_CharNextFunc) t1_cmap_custom_char_next, /* char_next */ - NULL, NULL, NULL, NULL, NULL + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL /* variantchar_list */ }; @@ -343,12 +355,16 @@ { sizeof ( PS_UnicodesRec ), - (FT_CMap_InitFunc) t1_cmap_unicode_init, - (FT_CMap_DoneFunc) t1_cmap_unicode_done, - (FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index, - (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next, + (FT_CMap_InitFunc) t1_cmap_unicode_init, /* init */ + (FT_CMap_DoneFunc) t1_cmap_unicode_done, /* done */ + (FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index, /* char_index */ + (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next, /* char_next */ - NULL, NULL, NULL, NULL, NULL + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL /* variantchar_list */ }; diff --git a/src/3rdparty/freetype/src/psaux/t1cmap.h b/src/3rdparty/freetype/src/psaux/t1cmap.h index b8ba06cc3b..4308e31d2d 100644 --- a/src/3rdparty/freetype/src/psaux/t1cmap.h +++ b/src/3rdparty/freetype/src/psaux/t1cmap.h @@ -4,7 +4,7 @@ /* */ /* Type 1 character map support (specification). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1CMAP_H__ -#define __T1CMAP_H__ +#ifndef T1CMAP_H_ +#define T1CMAP_H_ #include <ft2build.h> #include FT_INTERNAL_OBJECTS_H @@ -99,7 +99,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1CMAP_H__ */ +#endif /* T1CMAP_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/psaux/t1decode.c b/src/3rdparty/freetype/src/psaux/t1decode.c index 2e199286f6..6ad145661f 100644 --- a/src/3rdparty/freetype/src/psaux/t1decode.c +++ b/src/3rdparty/freetype/src/psaux/t1decode.c @@ -4,7 +4,7 @@ /* */ /* PostScript Type 1 decoding routines (body). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,6 +20,7 @@ #include FT_INTERNAL_CALC_H #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_POSTSCRIPT_HINTS_H +#include FT_INTERNAL_HASH_H #include FT_OUTLINE_H #include "t1decode.h" @@ -108,6 +109,56 @@ }; + /*************************************************************************/ + /* */ + /* <Function> */ + /* t1_lookup_glyph_by_stdcharcode_ps */ + /* */ + /* <Description> */ + /* Looks up a given glyph by its StandardEncoding charcode. Used to */ + /* implement the SEAC Type 1 operator in the Adobe engine */ + /* */ + /* <Input> */ + /* face :: The current face object. */ + /* */ + /* charcode :: The character code to look for. */ + /* */ + /* <Return> */ + /* A glyph index in the font face. Returns -1 if the corresponding */ + /* glyph wasn't found. */ + /* */ + FT_LOCAL_DEF( FT_Int ) + t1_lookup_glyph_by_stdcharcode_ps( PS_Decoder* decoder, + FT_Int charcode ) + { + FT_UInt n; + const FT_String* glyph_name; + FT_Service_PsCMaps psnames = decoder->psnames; + + + /* check range of standard char code */ + if ( charcode < 0 || charcode > 255 ) + return -1; + + glyph_name = psnames->adobe_std_strings( + psnames->adobe_std_encoding[charcode]); + + for ( n = 0; n < decoder->num_glyphs; n++ ) + { + FT_String* name = (FT_String*)decoder->glyph_names[n]; + + + if ( name && + name[0] == glyph_name[0] && + ft_strcmp( name, glyph_name ) == 0 ) + return (FT_Int)n; + } + + return -1; + } + + +#ifdef T1_CONFIG_OPTION_OLD_ENGINE /*************************************************************************/ /* */ /* <Function> */ @@ -157,6 +208,15 @@ } + /* parse a single Type 1 glyph */ + FT_LOCAL_DEF( FT_Error ) + t1_decoder_parse_glyph( T1_Decoder decoder, + FT_UInt glyph ) + { + return decoder->parse_callback( decoder, glyph ); + } + + /*************************************************************************/ /* */ /* <Function> */ @@ -404,9 +464,7 @@ ( decoder->buildchar == NULL ) ); if ( decoder->buildchar && decoder->len_buildchar > 0 ) - ft_memset( &decoder->buildchar[0], - 0, - sizeof ( decoder->buildchar[0] ) * decoder->len_buildchar ); + FT_ARRAY_ZERO( decoder->buildchar, decoder->len_buildchar ); FT_TRACE4(( "\n" "Start charstring\n" )); @@ -512,7 +570,7 @@ break; case 12: - if ( ip > limit ) + if ( ip >= limit ) { FT_ERROR(( "t1_decoder_parse_charstrings:" " invalid escape (12+EOF)\n" )); @@ -667,9 +725,9 @@ #ifdef FT_DEBUG_LEVEL_TRACE if ( large_int ) - FT_TRACE4(( " %ld", value )); + FT_TRACE4(( " %d", value )); else - FT_TRACE4(( " %ld", Fix2Int( value ) )); + FT_TRACE4(( " %d", value / 65536 )); #endif *top++ = value; @@ -735,7 +793,7 @@ if ( arg_cnt != 3 ) goto Unexpected_OtherSubr; - if ( decoder->flex_state == 0 || + if ( !decoder->flex_state || decoder->num_flex_vectors != 7 ) { FT_ERROR(( "t1_decoder_parse_charstrings:" @@ -753,13 +811,12 @@ if ( arg_cnt != 0 ) goto Unexpected_OtherSubr; + if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) || + FT_SET_ERROR( t1_builder_check_points( builder, 6 ) ) ) + goto Fail; + decoder->flex_state = 1; decoder->num_flex_vectors = 0; - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok || - ( error = t1_builder_check_points( builder, 6 ) ) - != FT_Err_Ok ) - goto Fail; break; case 2: /* add flex vectors */ @@ -770,7 +827,7 @@ if ( arg_cnt != 0 ) goto Unexpected_OtherSubr; - if ( decoder->flex_state == 0 ) + if ( !decoder->flex_state ) { FT_ERROR(( "t1_decoder_parse_charstrings:" " missing flex start\n" )); @@ -782,10 +839,19 @@ /* point without adding any point to the outline */ idx = decoder->num_flex_vectors++; if ( idx > 0 && idx < 7 ) + { + /* in malformed fonts it is possible to have other */ + /* opcodes in the middle of a flex (which don't */ + /* increase `num_flex_vectors'); we thus have to */ + /* check whether we can add a point */ + if ( FT_SET_ERROR( t1_builder_check_points( builder, 1 ) ) ) + goto Syntax_Error; + t1_builder_add_point( builder, x, y, (FT_Byte)( idx == 3 || idx == 6 ) ); + } } break; @@ -857,7 +923,9 @@ for ( mm = 1; mm < blend->num_designs; mm++ ) - tmp += FT_MulFix( *delta++, blend->weight_vector[mm] ); + tmp = ADD_LONG( tmp, + FT_MulFix( *delta++, + blend->weight_vector[mm] ) ); *values++ = tmp; } @@ -875,7 +943,7 @@ PS_Blend blend = decoder->blend; - if ( arg_cnt != 1 || blend == NULL ) + if ( arg_cnt != 1 || !blend ) goto Unexpected_OtherSubr; idx = Fix2Int( top[0] ); @@ -897,7 +965,7 @@ if ( arg_cnt != 2 ) goto Unexpected_OtherSubr; - top[0] += top[1]; /* XXX (over|under)flow */ + top[0] = ADD_LONG( top[0], top[1] ); known_othersubr_result_cnt = 1; break; @@ -908,7 +976,7 @@ if ( arg_cnt != 2 ) goto Unexpected_OtherSubr; - top[0] -= top[1]; /* XXX (over|under)flow */ + top[0] = SUB_LONG( top[0], top[1] ); known_othersubr_result_cnt = 1; break; @@ -943,7 +1011,7 @@ PS_Blend blend = decoder->blend; - if ( arg_cnt != 2 || blend == NULL ) + if ( arg_cnt != 2 || !blend ) goto Unexpected_OtherSubr; idx = Fix2Int( top[1] ); @@ -964,7 +1032,7 @@ PS_Blend blend = decoder->blend; - if ( arg_cnt != 1 || blend == NULL ) + if ( arg_cnt != 1 || !blend ) goto Unexpected_OtherSubr; idx = Fix2Int( top[0] ); @@ -1122,7 +1190,7 @@ FT_TRACE4(( "BuildCharArray = [ " )); - for ( i = 0; i < decoder->len_buildchar; ++i ) + for ( i = 0; i < decoder->len_buildchar; i++ ) FT_TRACE4(( "%d ", decoder->buildchar[i] )); FT_TRACE4(( "]\n" )); @@ -1140,11 +1208,13 @@ builder->parse_state = T1_Parse_Have_Width; - builder->left_bearing.x += top[0]; - builder->advance.x = top[1]; - builder->advance.y = 0; + builder->left_bearing.x = ADD_LONG( builder->left_bearing.x, + top[0] ); - orig_x = x = builder->pos_x + top[0]; + builder->advance.x = top[1]; + builder->advance.y = 0; + + orig_x = x = ADD_LONG( builder->pos_x, top[0] ); orig_y = y = builder->pos_y; FT_UNUSED( orig_y ); @@ -1170,13 +1240,16 @@ builder->parse_state = T1_Parse_Have_Width; - builder->left_bearing.x += top[0]; - builder->left_bearing.y += top[1]; - builder->advance.x = top[2]; - builder->advance.y = top[3]; + builder->left_bearing.x = ADD_LONG( builder->left_bearing.x, + top[0] ); + builder->left_bearing.y = ADD_LONG( builder->left_bearing.y, + top[1] ); - x = builder->pos_x + top[0]; - y = builder->pos_y + top[1]; + builder->advance.x = top[2]; + builder->advance.y = top[3]; + + x = ADD_LONG( builder->pos_x, top[0] ); + y = ADD_LONG( builder->pos_y, top[1] ); /* the `metrics_only' indicates that we only want to compute */ /* the glyph's metrics (lsb + advance width), not load the */ @@ -1200,17 +1273,17 @@ case op_hlineto: FT_TRACE4(( " hlineto" )); - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok ) + if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ) goto Fail; - x += top[0]; + x = ADD_LONG( x, top[0] ); goto Add_Line; case op_hmoveto: FT_TRACE4(( " hmoveto" )); - x += top[0]; + x = ADD_LONG( x, top[0] ); + if ( !decoder->flex_state ) { if ( builder->parse_state == T1_Parse_Start ) @@ -1222,42 +1295,41 @@ case op_hvcurveto: FT_TRACE4(( " hvcurveto" )); - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok || - ( error = t1_builder_check_points( builder, 3 ) ) - != FT_Err_Ok ) + if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) || + FT_SET_ERROR( t1_builder_check_points( builder, 3 ) ) ) goto Fail; - x += top[0]; + x = ADD_LONG( x, top[0] ); t1_builder_add_point( builder, x, y, 0 ); - x += top[1]; - y += top[2]; + + x = ADD_LONG( x, top[1] ); + y = ADD_LONG( y, top[2] ); t1_builder_add_point( builder, x, y, 0 ); - y += top[3]; + + y = ADD_LONG( y, top[3] ); t1_builder_add_point( builder, x, y, 1 ); break; case op_rlineto: FT_TRACE4(( " rlineto" )); - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok ) + if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ) goto Fail; - x += top[0]; - y += top[1]; + x = ADD_LONG( x, top[0] ); + y = ADD_LONG( y, top[1] ); Add_Line: - if ( ( error = t1_builder_add_point1( builder, x, y ) ) - != FT_Err_Ok ) + if ( FT_SET_ERROR( t1_builder_add_point1( builder, x, y ) ) ) goto Fail; break; case op_rmoveto: FT_TRACE4(( " rmoveto" )); - x += top[0]; - y += top[1]; + x = ADD_LONG( x, top[0] ); + y = ADD_LONG( y, top[1] ); + if ( !decoder->flex_state ) { if ( builder->parse_state == T1_Parse_Start ) @@ -1269,57 +1341,55 @@ case op_rrcurveto: FT_TRACE4(( " rrcurveto" )); - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok || - ( error = t1_builder_check_points( builder, 3 ) ) - != FT_Err_Ok ) + if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) || + FT_SET_ERROR( t1_builder_check_points( builder, 3 ) ) ) goto Fail; - x += top[0]; - y += top[1]; + x = ADD_LONG( x, top[0] ); + y = ADD_LONG( y, top[1] ); t1_builder_add_point( builder, x, y, 0 ); - x += top[2]; - y += top[3]; + x = ADD_LONG( x, top[2] ); + y = ADD_LONG( y, top[3] ); t1_builder_add_point( builder, x, y, 0 ); - x += top[4]; - y += top[5]; + x = ADD_LONG( x, top[4] ); + y = ADD_LONG( y, top[5] ); t1_builder_add_point( builder, x, y, 1 ); break; case op_vhcurveto: FT_TRACE4(( " vhcurveto" )); - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok || - ( error = t1_builder_check_points( builder, 3 ) ) - != FT_Err_Ok ) + if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) || + FT_SET_ERROR( t1_builder_check_points( builder, 3 ) ) ) goto Fail; - y += top[0]; + y = ADD_LONG( y, top[0] ); t1_builder_add_point( builder, x, y, 0 ); - x += top[1]; - y += top[2]; + + x = ADD_LONG( x, top[1] ); + y = ADD_LONG( y, top[2] ); t1_builder_add_point( builder, x, y, 0 ); - x += top[3]; + + x = ADD_LONG( x, top[3] ); t1_builder_add_point( builder, x, y, 1 ); break; case op_vlineto: FT_TRACE4(( " vlineto" )); - if ( ( error = t1_builder_start_point( builder, x, y ) ) - != FT_Err_Ok ) + if ( FT_SET_ERROR( t1_builder_start_point( builder, x, y ) ) ) goto Fail; - y += top[0]; + y = ADD_LONG( y, top[0] ); goto Add_Line; case op_vmoveto: FT_TRACE4(( " vmoveto" )); - y += top[0]; + y = ADD_LONG( y, top[0] ); + if ( !decoder->flex_state ) { if ( builder->parse_state == T1_Parse_Start ) @@ -1335,7 +1405,7 @@ /* otherwise, we divide numbers in 16.16 format -- */ /* in both cases, it is the same operation */ *top = FT_DivFix( top[0], top[1] ); - ++top; + top++; large_int = FALSE; break; @@ -1348,6 +1418,19 @@ FT_TRACE4(( " callsubr" )); idx = Fix2Int( top[0] ); + + if ( decoder->subrs_hash ) + { + size_t* val = ft_hash_num_lookup( idx, + decoder->subrs_hash ); + + + if ( val ) + idx = *val; + else + idx = -1; + } + if ( idx < 0 || idx >= decoder->num_subrs ) { FT_ERROR(( "t1_decoder_parse_charstrings:" @@ -1463,7 +1546,7 @@ /* record vertical hint */ if ( hinter ) { - top[0] += orig_x; + top[0] = ADD_LONG( top[0], orig_x ); hinter->stem( hinter->hints, 0, top ); } break; @@ -1477,9 +1560,9 @@ FT_Pos dx = orig_x; - top[0] += dx; - top[2] += dx; - top[4] += dx; + top[0] = ADD_LONG( top[0], dx ); + top[2] = ADD_LONG( top[2], dx ); + top[4] = ADD_LONG( top[4], dx ); hinter->stem3( hinter->hints, 0, top ); } break; @@ -1555,14 +1638,286 @@ return FT_THROW( Stack_Underflow ); } +#else /* T1_CONFIG_OPTION_OLD_ENGINE */ - /* parse a single Type 1 glyph */ + /*************************************************************************/ + /* */ + /* <Function> */ + /* t1_decoder_parse_metrics */ + /* */ + /* <Description> */ + /* Parses a given Type 1 charstrings program to extract width */ + /* */ + /* <Input> */ + /* decoder :: The current Type 1 decoder. */ + /* */ + /* charstring_base :: The base address of the charstring stream. */ + /* */ + /* charstring_len :: The length in bytes of the charstring stream. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ FT_LOCAL_DEF( FT_Error ) - t1_decoder_parse_glyph( T1_Decoder decoder, - FT_UInt glyph ) + t1_decoder_parse_metrics( T1_Decoder decoder, + FT_Byte* charstring_base, + FT_UInt charstring_len ) { - return decoder->parse_callback( decoder, glyph ); + T1_Decoder_Zone zone; + FT_Byte* ip; + FT_Byte* limit; + T1_Builder builder = &decoder->builder; + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_Bool bol = TRUE; +#endif + + + /* First of all, initialize the decoder */ + decoder->top = decoder->stack; + decoder->zone = decoder->zones; + zone = decoder->zones; + + builder->parse_state = T1_Parse_Start; + + FT_TRACE4(( "\n" + "Start charstring: get width\n" )); + + zone->base = charstring_base; + limit = zone->limit = charstring_base + charstring_len; + ip = zone->cursor = zone->base; + + /* now, execute loop */ + while ( ip < limit ) + { + FT_Long* top = decoder->top; + T1_Operator op = op_none; + FT_Int32 value = 0; + + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( bol ) + { + FT_TRACE5(( " (%d)", decoder->top - decoder->stack )); + bol = FALSE; + } +#endif + + /*********************************************************************/ + /* */ + /* Decode operator or operand */ + /* */ + /* */ + + /* first of all, decompress operator or value */ + switch ( *ip++ ) + { + case 1: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 14: + case 15: + case 21: + case 22: + case 30: + case 31: + goto No_Width; + + case 13: + op = op_hsbw; + break; + + case 12: + if ( ip >= limit ) + { + FT_ERROR(( "t1_decoder_parse_metrics:" + " invalid escape (12+EOF)\n" )); + goto Syntax_Error; + } + + switch ( *ip++ ) + { + case 7: + op = op_sbw; + break; + + default: + goto No_Width; + } + break; + + case 255: /* four bytes integer */ + if ( ip + 4 > limit ) + { + FT_ERROR(( "t1_decoder_parse_metrics:" + " unexpected EOF in integer\n" )); + goto Syntax_Error; + } + + value = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) | + ( (FT_UInt32)ip[1] << 16 ) | + ( (FT_UInt32)ip[2] << 8 ) | + (FT_UInt32)ip[3] ); + ip += 4; + + /* According to the specification, values > 32000 or < -32000 must */ + /* be followed by a `div' operator to make the result be in the */ + /* range [-32000;32000]. We expect that the second argument of */ + /* `div' is not a large number. Additionally, we don't handle */ + /* stuff like `<large1> <large2> <num> div <num> div' or */ + /* <large1> <large2> <num> div div'. This is probably not allowed */ + /* anyway. */ + if ( value > 32000 || value < -32000 ) + { + FT_ERROR(( "t1_decoder_parse_metrics:" + " large integer found for width\n" )); + goto Syntax_Error; + } + else + { + value = (FT_Int32)( (FT_UInt32)value << 16 ); + } + + break; + + default: + if ( ip[-1] >= 32 ) + { + if ( ip[-1] < 247 ) + value = (FT_Int32)ip[-1] - 139; + else + { + if ( ++ip > limit ) + { + FT_ERROR(( "t1_decoder_parse_metrics:" + " unexpected EOF in integer\n" )); + goto Syntax_Error; + } + + if ( ip[-2] < 251 ) + value = ( ( ip[-2] - 247 ) * 256 ) + ip[-1] + 108; + else + value = -( ( ( ip[-2] - 251 ) * 256 ) + ip[-1] + 108 ); + } + + value = (FT_Int32)( (FT_UInt32)value << 16 ); + } + else + { + FT_ERROR(( "t1_decoder_parse_metrics:" + " invalid byte (%d)\n", ip[-1] )); + goto Syntax_Error; + } + } + + /*********************************************************************/ + /* */ + /* Push value on stack, or process operator */ + /* */ + /* */ + if ( op == op_none ) + { + if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS ) + { + FT_ERROR(( "t1_decoder_parse_metrics: stack overflow\n" )); + goto Syntax_Error; + } + +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE4(( " %d", value / 65536 )); +#endif + + *top++ = value; + decoder->top = top; + } + else /* general operator */ + { + FT_Int num_args = t1_args_count[op]; + + + FT_ASSERT( num_args >= 0 ); + + if ( top - decoder->stack < num_args ) + goto Stack_Underflow; + +#ifdef FT_DEBUG_LEVEL_TRACE + + if ( top - decoder->stack != num_args ) + FT_TRACE0(( "t1_decoder_parse_metrics:" + " too much operands on the stack" + " (seen %d, expected %d)\n", + top - decoder->stack, num_args )); + +#endif /* FT_DEBUG_LEVEL_TRACE */ + + top -= num_args; + + switch ( op ) + { + case op_hsbw: + FT_TRACE4(( " hsbw" )); + + builder->parse_state = T1_Parse_Have_Width; + + builder->left_bearing.x = ADD_LONG( builder->left_bearing.x, + top[0] ); + + builder->advance.x = top[1]; + builder->advance.y = 0; + + /* we only want to compute the glyph's metrics */ + /* (lsb + advance width), not load the rest of */ + /* it; so exit immediately */ + return FT_Err_Ok; + + case op_sbw: + FT_TRACE4(( " sbw" )); + + builder->parse_state = T1_Parse_Have_Width; + + builder->left_bearing.x = ADD_LONG( builder->left_bearing.x, + top[0] ); + builder->left_bearing.y = ADD_LONG( builder->left_bearing.y, + top[1] ); + + builder->advance.x = top[2]; + builder->advance.y = top[3]; + + /* we only want to compute the glyph's metrics */ + /* (lsb + advance width), not load the rest of */ + /* it; so exit immediately */ + return FT_Err_Ok; + + default: + FT_ERROR(( "t1_decoder_parse_metrics:" + " unhandled opcode %d\n", op )); + goto Syntax_Error; + } + + } /* general operator processing */ + + } /* while ip < limit */ + + FT_TRACE4(( "..end..\n\n" )); + + No_Width: + FT_ERROR(( "t1_decoder_parse_metrics:" + " no width, found op %d instead\n", + ip[-1] )); + Syntax_Error: + return FT_THROW( Syntax_Error ); + + Stack_Underflow: + return FT_THROW( Stack_Underflow ); } +#endif /* T1_CONFIG_OPTION_OLD_ENGINE */ /* initialize T1 decoder */ @@ -1577,7 +1932,7 @@ FT_Render_Mode hint_mode, T1_Decoder_Callback parse_callback ) { - FT_MEM_ZERO( decoder, sizeof ( *decoder ) ); + FT_ZERO( decoder ); /* retrieve PSNames interface from list of current modules */ { @@ -1617,7 +1972,16 @@ FT_LOCAL_DEF( void ) t1_decoder_done( T1_Decoder decoder ) { + FT_Memory memory = decoder->builder.memory; + + t1_builder_done( &decoder->builder ); + + if ( decoder->cf2_instance.finalizer ) + { + decoder->cf2_instance.finalizer( decoder->cf2_instance.data ); + FT_FREE( decoder->cf2_instance.data ); + } } diff --git a/src/3rdparty/freetype/src/psaux/t1decode.h b/src/3rdparty/freetype/src/psaux/t1decode.h index e83078f719..1d9718d678 100644 --- a/src/3rdparty/freetype/src/psaux/t1decode.h +++ b/src/3rdparty/freetype/src/psaux/t1decode.h @@ -4,7 +4,7 @@ /* */ /* PostScript Type 1 decoding routines (specification). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1DECODE_H__ -#define __T1DECODE_H__ +#ifndef T1DECODE_H_ +#define T1DECODE_H_ #include <ft2build.h> @@ -31,7 +31,11 @@ FT_BEGIN_HEADER FT_CALLBACK_TABLE const T1_Decoder_FuncsRec t1_decoder_funcs; + FT_LOCAL( FT_Int ) + t1_lookup_glyph_by_stdcharcode_ps( PS_Decoder* decoder, + FT_Int charcode ); +#ifdef T1_CONFIG_OPTION_OLD_ENGINE FT_LOCAL( FT_Error ) t1_decoder_parse_glyph( T1_Decoder decoder, FT_UInt glyph_index ); @@ -40,6 +44,12 @@ FT_BEGIN_HEADER t1_decoder_parse_charstrings( T1_Decoder decoder, FT_Byte* base, FT_UInt len ); +#else + FT_LOCAL( FT_Error ) + t1_decoder_parse_metrics( T1_Decoder decoder, + FT_Byte* charstring_base, + FT_UInt charstring_len ); +#endif FT_LOCAL( FT_Error ) t1_decoder_init( T1_Decoder decoder, @@ -58,7 +68,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1DECODE_H__ */ +#endif /* T1DECODE_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/pshinter/Jamfile b/src/3rdparty/freetype/src/pshinter/Jamfile index 6fb3be11c7..3f5f0ae40e 100644 --- a/src/3rdparty/freetype/src/pshinter/Jamfile +++ b/src/3rdparty/freetype/src/pshinter/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/pshinter Jamfile # -# Copyright 2001-2015 by +# Copyright 2001-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/pshinter/module.mk b/src/3rdparty/freetype/src/pshinter/module.mk index 1fd8e55a33..06707be3b4 100644 --- a/src/3rdparty/freetype/src/pshinter/module.mk +++ b/src/3rdparty/freetype/src/pshinter/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2015 by +# Copyright 1996-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/pshinter/pshalgo.c b/src/3rdparty/freetype/src/pshinter/pshalgo.c index 6e654cb1ef..b98077c62e 100644 --- a/src/3rdparty/freetype/src/pshinter/pshalgo.c +++ b/src/3rdparty/freetype/src/pshinter/pshalgo.c @@ -4,7 +4,7 @@ /* */ /* PostScript hinting algorithm (body). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -26,7 +26,7 @@ #undef FT_COMPONENT -#define FT_COMPONENT trace_pshalgo2 +#define FT_COMPONENT trace_pshalgo #ifdef DEBUG_HINTER @@ -779,7 +779,7 @@ * It turns out though that minimizing the total number of lit * pixels is also important, so position C), with one edge * aligned with a pixel boundary is actually preferable - * to A). There are also more possibile positions for C) than + * to A). There are also more possible positions for C) than * for A) or B), so it involves less distortion of the overall * character shape. */ @@ -802,7 +802,7 @@ } /* We choose between B) and C) above based on the amount - * of fractinal stem width; for small amounts, choose + * of fractional stem width; for small amounts, choose * C) always, for large amounts, B) always, and inbetween, * pick whichever one involves less stem movement. */ @@ -898,7 +898,7 @@ static void psh_print_zone( PSH_Zone zone ) { - printf( "zone [scale,delta,min,max] = [%.3f,%.3f,%d,%d]\n", + printf( "zone [scale,delta,min,max] = [%.5f,%.2f,%d,%d]\n", zone->scale / 65536.0, zone->delta / 64.0, zone->min, @@ -1162,7 +1162,7 @@ /* clear all fields */ - FT_MEM_ZERO( glyph, sizeof ( *glyph ) ); + FT_ZERO( glyph ); memory = glyph->memory = globals->memory; @@ -1531,7 +1531,7 @@ } } - if ( point->hint == NULL ) + if ( !point->hint ) { for ( nn = 0; nn < num_hints; nn++ ) { @@ -1572,8 +1572,8 @@ PS_Mask mask = table->hint_masks->masks; FT_UInt num_masks = table->hint_masks->num_masks; FT_UInt first = 0; - FT_Int major_dir = dimension == 0 ? PSH_DIR_VERTICAL - : PSH_DIR_HORIZONTAL; + FT_Int major_dir = ( dimension == 0 ) ? PSH_DIR_VERTICAL + : PSH_DIR_HORIZONTAL; PSH_Dimension dim = &glyph->globals->dimension[dimension]; FT_Fixed scale = dim->scale_mult; FT_Int threshold; diff --git a/src/3rdparty/freetype/src/pshinter/pshalgo.h b/src/3rdparty/freetype/src/pshinter/pshalgo.h index 8373e5ec29..c50683fbec 100644 --- a/src/3rdparty/freetype/src/pshinter/pshalgo.h +++ b/src/3rdparty/freetype/src/pshinter/pshalgo.h @@ -4,7 +4,7 @@ /* */ /* PostScript hinting algorithm (specification). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSHALGO_H__ -#define __PSHALGO_H__ +#ifndef PSHALGO_H_ +#define PSHALGO_H_ #include "pshrec.h" @@ -235,7 +235,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSHALGO_H__ */ +#endif /* PSHALGO_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/pshinter/pshglob.c b/src/3rdparty/freetype/src/pshinter/pshglob.c index 4616bdc6cf..accc04921d 100644 --- a/src/3rdparty/freetype/src/pshinter/pshglob.c +++ b/src/3rdparty/freetype/src/pshinter/pshglob.c @@ -5,7 +5,7 @@ /* PostScript hinter global hinting management (body). */ /* Inspired by the new auto-hinter module. */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -80,7 +80,7 @@ #if 0 - /* org_width is is font units, result in device pixels, 26.6 format */ + /* org_width is in font units, result in device pixels, 26.6 format */ FT_LOCAL_DEF( FT_Pos ) psh_dimension_snap_width( PSH_Dimension dimension, FT_Int org_width ) @@ -227,8 +227,8 @@ } - /* Re-read blue zones from the original fonts and store them into out */ - /* private structure. This function re-orders, sanitizes and */ + /* Re-read blue zones from the original fonts and store them into our */ + /* private structure. This function re-orders, sanitizes, and */ /* fuzz-expands the zones as well. */ static void psh_blues_set_zones( PSH_Blues target, diff --git a/src/3rdparty/freetype/src/pshinter/pshglob.h b/src/3rdparty/freetype/src/pshinter/pshglob.h index c376df7b9f..cf80bf40e6 100644 --- a/src/3rdparty/freetype/src/pshinter/pshglob.h +++ b/src/3rdparty/freetype/src/pshinter/pshglob.h @@ -4,7 +4,7 @@ /* */ /* PostScript hinter global hinting management. */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSHGLOB_H__ -#define __PSHGLOB_H__ +#ifndef PSHGLOB_H_ +#define PSHGLOB_H_ #include FT_FREETYPE_H @@ -190,7 +190,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSHGLOB_H__ */ +#endif /* PSHGLOB_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/pshinter/pshinter.c b/src/3rdparty/freetype/src/pshinter/pshinter.c index 9e65fe2a42..0eedac452d 100644 --- a/src/3rdparty/freetype/src/pshinter/pshinter.c +++ b/src/3rdparty/freetype/src/pshinter/pshinter.c @@ -4,7 +4,7 @@ /* */ /* FreeType PostScript Hinting module */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,13 +17,13 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT - #include <ft2build.h> + +#include "pshalgo.c" +#include "pshglob.c" +#include "pshmod.c" #include "pshpic.c" #include "pshrec.c" -#include "pshglob.c" -#include "pshalgo.c" -#include "pshmod.c" /* END */ diff --git a/src/3rdparty/freetype/src/pshinter/pshmod.c b/src/3rdparty/freetype/src/pshinter/pshmod.c index 961b468506..0b8f6f99b8 100644 --- a/src/3rdparty/freetype/src/pshinter/pshmod.c +++ b/src/3rdparty/freetype/src/pshinter/pshmod.c @@ -4,7 +4,7 @@ /* */ /* FreeType PostScript hinter module implementation (body). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -95,9 +95,11 @@ FT_DEFINE_PSHINTER_INTERFACE( pshinter_interface, + pshinter_get_globals_funcs, pshinter_get_t1_funcs, - pshinter_get_t2_funcs ) + pshinter_get_t2_funcs + ) FT_DEFINE_MODULE( @@ -111,9 +113,9 @@ &PSHINTER_INTERFACE_GET, /* module-specific interface */ - (FT_Module_Constructor)ps_hinter_init, - (FT_Module_Destructor) ps_hinter_done, - (FT_Module_Requester) NULL ) /* no additional interface for now */ - + (FT_Module_Constructor)ps_hinter_init, /* module_init */ + (FT_Module_Destructor) ps_hinter_done, /* module_done */ + (FT_Module_Requester) NULL /* get_interface */ + ) /* END */ diff --git a/src/3rdparty/freetype/src/pshinter/pshmod.h b/src/3rdparty/freetype/src/pshinter/pshmod.h index a58d856533..556de2fbc0 100644 --- a/src/3rdparty/freetype/src/pshinter/pshmod.h +++ b/src/3rdparty/freetype/src/pshinter/pshmod.h @@ -4,7 +4,7 @@ /* */ /* PostScript hinter module interface (specification). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSHMOD_H__ -#define __PSHMOD_H__ +#ifndef PSHMOD_H_ +#define PSHMOD_H_ #include <ft2build.h> @@ -33,7 +33,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSHMOD_H__ */ +#endif /* PSHMOD_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/pshinter/pshnterr.h b/src/3rdparty/freetype/src/pshinter/pshnterr.h index ce790a8ef5..b9d02d2956 100644 --- a/src/3rdparty/freetype/src/pshinter/pshnterr.h +++ b/src/3rdparty/freetype/src/pshinter/pshnterr.h @@ -4,7 +4,7 @@ /* */ /* PS Hinter error codes (specification only). */ /* */ -/* Copyright 2003-2015 by */ +/* Copyright 2003-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __PSHNTERR_H__ -#define __PSHNTERR_H__ +#ifndef PSHNTERR_H_ +#define PSHNTERR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX PSH_Err_ @@ -35,7 +35,7 @@ #include FT_ERRORS_H -#endif /* __PSHNTERR_H__ */ +#endif /* PSHNTERR_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/pshinter/pshpic.c b/src/3rdparty/freetype/src/pshinter/pshpic.c index afd8fb9678..465ad31885 100644 --- a/src/3rdparty/freetype/src/pshinter/pshpic.c +++ b/src/3rdparty/freetype/src/pshinter/pshpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for pshinter module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2018 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/src/pshinter/pshpic.h b/src/3rdparty/freetype/src/pshinter/pshpic.h index ca35cd6fa9..4469ba87c8 100644 --- a/src/3rdparty/freetype/src/pshinter/pshpic.h +++ b/src/3rdparty/freetype/src/pshinter/pshpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for pshinter module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2018 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSHPIC_H__ -#define __PSHPIC_H__ +#ifndef PSHPIC_H_ +#define PSHPIC_H_ #include FT_INTERNAL_PIC_H @@ -57,7 +57,7 @@ FT_END_HEADER /* */ -#endif /* __PSHPIC_H__ */ +#endif /* PSHPIC_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/pshinter/pshrec.c b/src/3rdparty/freetype/src/pshinter/pshrec.c index f8895fc8d6..6648d13d60 100644 --- a/src/3rdparty/freetype/src/pshinter/pshrec.c +++ b/src/3rdparty/freetype/src/pshinter/pshrec.c @@ -4,7 +4,7 @@ /* */ /* FreeType PostScript hints recorder (body). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -818,7 +818,7 @@ ps_hints_init( PS_Hints hints, FT_Memory memory ) { - FT_MEM_ZERO( hints, sizeof ( *hints ) ); + FT_ZERO( hints ); hints->memory = memory; } @@ -1140,7 +1140,7 @@ FT_LOCAL_DEF( void ) t1_hints_funcs_init( T1_Hints_FuncsRec* funcs ) { - FT_MEM_ZERO( (char*)funcs, sizeof ( *funcs ) ); + FT_ZERO( funcs ); funcs->open = (T1_Hints_OpenFunc) t1_hints_open; funcs->close = (T1_Hints_CloseFunc) ps_hints_close; @@ -1206,7 +1206,7 @@ FT_LOCAL_DEF( void ) t2_hints_funcs_init( T2_Hints_FuncsRec* funcs ) { - FT_MEM_ZERO( funcs, sizeof ( *funcs ) ); + FT_ZERO( funcs ); funcs->open = (T2_Hints_OpenFunc) t2_hints_open; funcs->close = (T2_Hints_CloseFunc) ps_hints_close; diff --git a/src/3rdparty/freetype/src/pshinter/pshrec.h b/src/3rdparty/freetype/src/pshinter/pshrec.h index 2b1ad94936..7e3dfe0d53 100644 --- a/src/3rdparty/freetype/src/pshinter/pshrec.h +++ b/src/3rdparty/freetype/src/pshinter/pshrec.h @@ -4,7 +4,7 @@ /* */ /* Postscript (Type1/Type2) hints recorder (specification). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -28,8 +28,8 @@ /**************************************************************************/ -#ifndef __PSHREC_H__ -#define __PSHREC_H__ +#ifndef PSHREC_H_ +#define PSHREC_H_ #include <ft2build.h> @@ -166,7 +166,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PS_HINTER_RECORD_H__ */ +#endif /* PSHREC_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/pshinter/rules.mk b/src/3rdparty/freetype/src/pshinter/rules.mk index 7838e676ec..966690efc2 100644 --- a/src/3rdparty/freetype/src/pshinter/rules.mk +++ b/src/3rdparty/freetype/src/pshinter/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2001-2015 by +# Copyright 2001-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/psnames/Jamfile b/src/3rdparty/freetype/src/psnames/Jamfile index 6dcc8b8e94..a0fd37397a 100644 --- a/src/3rdparty/freetype/src/psnames/Jamfile +++ b/src/3rdparty/freetype/src/psnames/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/psnames Jamfile # -# Copyright 2001-2015 by +# Copyright 2001-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/psnames/module.mk b/src/3rdparty/freetype/src/psnames/module.mk index 3708f60362..410f48a191 100644 --- a/src/3rdparty/freetype/src/psnames/module.mk +++ b/src/3rdparty/freetype/src/psnames/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2015 by +# Copyright 1996-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/psnames/psmodule.c b/src/3rdparty/freetype/src/psnames/psmodule.c index 0f04c2fa7d..8929ebe751 100644 --- a/src/3rdparty/freetype/src/psnames/psmodule.c +++ b/src/3rdparty/freetype/src/psnames/psmodule.c @@ -4,7 +4,7 @@ /* */ /* PSNames module implementation (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,6 +22,22 @@ #include FT_SERVICE_POSTSCRIPT_CMAPS_H #include "psmodule.h" + + /* + * The file `pstables.h' with its arrays and its function + * `ft_get_adobe_glyph_index' is useful for other projects also (for + * example, `pdfium' is using it). However, if used as a C++ header, + * including it in two different source files makes it necessary to use + * `extern const' for the declaration of its arrays, otherwise the data + * would be duplicated as mandated by the C++ standard. + * + * For this reason, we use `DEFINE_PS_TABLES' to guard the function + * definitions, and `DEFINE_PS_TABLES_DATA' to provide both proper array + * declarations and definitions. + */ +#include "pstables.h" +#define DEFINE_PS_TABLES +#define DEFINE_PS_TABLES_DATA #include "pstables.h" #include "psnamerr.h" @@ -525,37 +541,42 @@ FT_DEFINE_SERVICE_PSCMAPSREC( pscmaps_interface, - (PS_Unicode_ValueFunc) ps_unicode_value, - (PS_Unicodes_InitFunc) ps_unicodes_init, - (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index, - (PS_Unicodes_CharNextFunc) ps_unicodes_char_next, - (PS_Macintosh_NameFunc) ps_get_macintosh_name, - (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, + (PS_Unicode_ValueFunc) ps_unicode_value, /* unicode_value */ + (PS_Unicodes_InitFunc) ps_unicodes_init, /* unicodes_init */ + (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index, /* unicodes_char_index */ + (PS_Unicodes_CharNextFunc) ps_unicodes_char_next, /* unicodes_char_next */ - t1_standard_encoding, - t1_expert_encoding ) + (PS_Macintosh_NameFunc) ps_get_macintosh_name, /* macintosh_name */ + (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, /* adobe_std_strings */ + + t1_standard_encoding, /* adobe_std_encoding */ + t1_expert_encoding /* adobe_expert_encoding */ + ) #else FT_DEFINE_SERVICE_PSCMAPSREC( pscmaps_interface, - NULL, - NULL, - NULL, - NULL, - (PS_Macintosh_NameFunc) ps_get_macintosh_name, - (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, + NULL, /* unicode_value */ + NULL, /* unicodes_init */ + NULL, /* unicodes_char_index */ + NULL, /* unicodes_char_next */ - t1_standard_encoding, - t1_expert_encoding ) + (PS_Macintosh_NameFunc) ps_get_macintosh_name, /* macintosh_name */ + (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, /* adobe_std_strings */ + + t1_standard_encoding, /* adobe_std_encoding */ + t1_expert_encoding /* adobe_expert_encoding */ + ) #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ FT_DEFINE_SERVICEDESCREC1( pscmaps_services, + FT_SERVICE_ID_POSTSCRIPT_CMAPS, &PSCMAPS_INTERFACE_GET ) @@ -601,9 +622,11 @@ PUT_PS_NAMES_SERVICE( (void*)&PSCMAPS_INTERFACE_GET ), /* module specific interface */ - (FT_Module_Constructor)NULL, - (FT_Module_Destructor) NULL, - (FT_Module_Requester) PUT_PS_NAMES_SERVICE( psnames_get_service ) ) + + (FT_Module_Constructor)NULL, /* module_init */ + (FT_Module_Destructor) NULL, /* module_done */ + (FT_Module_Requester) PUT_PS_NAMES_SERVICE( psnames_get_service ) /* get_interface */ + ) /* END */ diff --git a/src/3rdparty/freetype/src/psnames/psmodule.h b/src/3rdparty/freetype/src/psnames/psmodule.h index f85f322193..3e94f8b437 100644 --- a/src/3rdparty/freetype/src/psnames/psmodule.h +++ b/src/3rdparty/freetype/src/psnames/psmodule.h @@ -4,7 +4,7 @@ /* */ /* High-level PSNames module interface (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSMODULE_H__ -#define __PSMODULE_H__ +#ifndef PSMODULE_H_ +#define PSMODULE_H_ #include <ft2build.h> @@ -32,7 +32,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __PSMODULE_H__ */ +#endif /* PSMODULE_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/psnames/psnamerr.h b/src/3rdparty/freetype/src/psnames/psnamerr.h index 09cc247b7d..14eb76c99c 100644 --- a/src/3rdparty/freetype/src/psnames/psnamerr.h +++ b/src/3rdparty/freetype/src/psnames/psnamerr.h @@ -4,7 +4,7 @@ /* */ /* PS names module error codes (specification only). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __PSNAMERR_H__ -#define __PSNAMERR_H__ +#ifndef PSNAMERR_H_ +#define PSNAMERR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX PSnames_Err_ @@ -36,7 +36,7 @@ #include FT_ERRORS_H -#endif /* __PSNAMERR_H__ */ +#endif /* PSNAMERR_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/psnames/psnames.c b/src/3rdparty/freetype/src/psnames/psnames.c index a4385961e5..febb80d594 100644 --- a/src/3rdparty/freetype/src/psnames/psnames.c +++ b/src/3rdparty/freetype/src/psnames/psnames.c @@ -4,7 +4,7 @@ /* */ /* FreeType PSNames module component (body only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,10 +17,10 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT - #include <ft2build.h> -#include "pspic.c" + #include "psmodule.c" +#include "pspic.c" /* END */ diff --git a/src/3rdparty/freetype/src/psnames/pspic.c b/src/3rdparty/freetype/src/psnames/pspic.c index 1394f977e0..85a06f3603 100644 --- a/src/3rdparty/freetype/src/psnames/pspic.c +++ b/src/3rdparty/freetype/src/psnames/pspic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for psnames module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2018 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/src/psnames/pspic.h b/src/3rdparty/freetype/src/psnames/pspic.h index 443225af61..889780cc03 100644 --- a/src/3rdparty/freetype/src/psnames/pspic.h +++ b/src/3rdparty/freetype/src/psnames/pspic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for psnames module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2018 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __PSPIC_H__ -#define __PSPIC_H__ +#ifndef PSPIC_H_ +#define PSPIC_H_ #include FT_INTERNAL_PIC_H @@ -62,7 +62,7 @@ FT_END_HEADER /* */ -#endif /* __PSPIC_H__ */ +#endif /* PSPIC_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/psnames/pstables.h b/src/3rdparty/freetype/src/psnames/pstables.h index 3f31c31b18..79545ee039 100644 --- a/src/3rdparty/freetype/src/psnames/pstables.h +++ b/src/3rdparty/freetype/src/psnames/pstables.h @@ -4,7 +4,7 @@ /* */ /* PostScript glyph names. */ /* */ -/* Copyright 2005-2015 by */ +/* Copyright 2005-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,7 +19,16 @@ /* This file has been generated automatically -- do not edit! */ - static const char ft_standard_glyph_names[3696] = +#ifndef DEFINE_PS_TABLES_DATA +#ifdef __cplusplus + extern "C" +#else + extern +#endif +#endif + const char ft_standard_glyph_names[3696] +#ifdef DEFINE_PS_TABLES_DATA + = { '.','n','u','l','l', 0, 'n','o','n','m','a','r','k','i','n','g','r','e','t','u','r','n', 0, @@ -441,14 +450,25 @@ 'R','e','g','u','l','a','r', 0, 'R','o','m','a','n', 0, 'S','e','m','i','b','o','l','d', 0, - }; + } +#endif /* DEFINE_PS_TABLES_DATA */ + ; #define FT_NUM_MAC_NAMES 258 /* Values are offsets into the `ft_standard_glyph_names' table */ - static const short ft_mac_names[FT_NUM_MAC_NAMES] = +#ifndef DEFINE_PS_TABLES_DATA +#ifdef __cplusplus + extern "C" +#else + extern +#endif +#endif + const short ft_mac_names[FT_NUM_MAC_NAMES] +#ifdef DEFINE_PS_TABLES_DATA + = { 253, 0, 6, 261, 267, 274, 283, 294, 301, 309, 758, 330, 340, 351, 360, 365, 371, 378, 385, 391, 396, 400, 404, 410, 415, 420, 424, 430, @@ -469,14 +489,25 @@ 1066,1073,1101,1143,1536,1783,1596,1843,1253,1207,1319,1579,1826,1229, 1270,1313,1323,1171,1290,1332,1211,1235,1276, 169, 175, 182, 189, 200, 209, 218, 225, 232, 239, 246 - }; + } +#endif /* DEFINE_PS_TABLES_DATA */ + ; #define FT_NUM_SID_NAMES 391 /* Values are offsets into the `ft_standard_glyph_names' table */ - static const short ft_sid_names[FT_NUM_SID_NAMES] = +#ifndef DEFINE_PS_TABLES_DATA +#ifdef __cplusplus + extern "C" +#else + extern +#endif +#endif + const short ft_sid_names[FT_NUM_SID_NAMES] +#ifdef DEFINE_PS_TABLES_DATA + = { 253, 261, 267, 274, 283, 294, 301, 309, 319, 330, 340, 351, 360, 365, 371, 378, 385, 391, 396, 400, 404, 410, 415, 420, 424, 430, 436, 441, @@ -506,11 +537,22 @@ 3237,3249,3264,3275,3283,3297,3309,3321,3338,3353,3365,3377,3394,3409, 3418,3430,3442,3454,3471,3483,3498,3506,3518,3530,3542,3559,3574,3586, 3597,3612,3620,3628,3636,3644,3650,3655,3660,3666,3673,3681,3687 - }; + } +#endif /* DEFINE_PS_TABLES_DATA */ + ; /* the following are indices into the SID name table */ - static const unsigned short t1_standard_encoding[256] = +#ifndef DEFINE_PS_TABLES_DATA +#ifdef __cplusplus + extern "C" +#else + extern +#endif +#endif + const unsigned short t1_standard_encoding[256] +#ifdef DEFINE_PS_TABLES_DATA + = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -528,11 +570,22 @@ 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,138, 0,139, 0, 0, 0, 0,140,141,142,143, 0, 0, 0, 0, 0,144, 0, 0, 0,145, 0, 0,146,147,148,149, 0, 0, 0, 0 - }; + } +#endif /* DEFINE_PS_TABLES_DATA */ + ; /* the following are indices into the SID name table */ - static const unsigned short t1_expert_encoding[256] = +#ifndef DEFINE_PS_TABLES_DATA +#ifdef __cplusplus + extern "C" +#else + extern +#endif +#endif + const unsigned short t1_expert_encoding[256] +#ifdef DEFINE_PS_TABLES_DATA + = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -550,7 +603,9 @@ 331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346, 347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362, 363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378 - }; + } +#endif /* DEFINE_PS_TABLES_DATA */ + ; /* @@ -564,7 +619,16 @@ #ifdef FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - static const unsigned char ft_adobe_glyph_list[55997L] = +#ifndef DEFINE_PS_TABLES_DATA +#ifdef __cplusplus + extern "C" +#else + extern +#endif +#endif + const unsigned char ft_adobe_glyph_list[55997L] +#ifdef DEFINE_PS_TABLES_DATA + = { 0, 52, 0,106, 2,167, 3, 63, 4,220, 6,125, 9,143, 10, 23, 11,137, 12,199, 14,246, 15, 87, 16,233, 17,219, 18,104, 19, 88, @@ -4066,9 +4130,12 @@ 248,232,239,239,107,128, 2,144,243,244,242,239,235,101,128, 1, 182,117, 2,218,167,218,178,232,233,242,225,231,225,238, 97,128, 48, 90,235,225,244,225,235,225,238, 97,128, 48,186 - }; + } +#endif /* DEFINE_PS_TABLES_DATA */ + ; +#ifdef DEFINE_PS_TABLES /* * This function searches the compressed table efficiently. */ @@ -4163,6 +4230,7 @@ NotFound: return 0; } +#endif /* DEFINE_PS_TABLES */ #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ diff --git a/src/3rdparty/freetype/src/psnames/rules.mk b/src/3rdparty/freetype/src/psnames/rules.mk index 3c774867fd..4d629d841c 100644 --- a/src/3rdparty/freetype/src/psnames/rules.mk +++ b/src/3rdparty/freetype/src/psnames/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2015 by +# Copyright 1996-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/raster/Jamfile b/src/3rdparty/freetype/src/raster/Jamfile index 71df5689ee..838e7ef57e 100644 --- a/src/3rdparty/freetype/src/raster/Jamfile +++ b/src/3rdparty/freetype/src/raster/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/raster Jamfile # -# Copyright 2001-2015 by +# Copyright 2001-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/raster/ftmisc.h b/src/3rdparty/freetype/src/raster/ftmisc.h index b87e0b62b7..7e40119071 100644 --- a/src/3rdparty/freetype/src/raster/ftmisc.h +++ b/src/3rdparty/freetype/src/raster/ftmisc.h @@ -5,7 +5,7 @@ /* Miscellaneous macros for stand-alone rasterizer (specification */ /* only). */ /* */ -/* Copyright 2005-2015 by */ +/* Copyright 2005-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -24,8 +24,8 @@ /* */ /***************************************************/ -#ifndef __FTMISC_H__ -#define __FTMISC_H__ +#ifndef FTMISC_H_ +#define FTMISC_H_ /* memset */ @@ -136,7 +136,7 @@ return ( s > 0 ) ? d : -d; } -#endif /* __FTMISC_H__ */ +#endif /* FTMISC_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/raster/ftraster.c b/src/3rdparty/freetype/src/raster/ftraster.c index e4bab98728..4354730d54 100644 --- a/src/3rdparty/freetype/src/raster/ftraster.c +++ b/src/3rdparty/freetype/src/raster/ftraster.c @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph rasterizer (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,7 +18,7 @@ /*************************************************************************/ /* */ /* This file can be compiled without the rest of the FreeType engine, by */ - /* defining the _STANDALONE_ macro when compiling it. You also need to */ + /* defining the STANDALONE_ macro when compiling it. You also need to */ /* put the files `ftimage.h' and `ftmisc.h' into the $(incdir) */ /* directory. Typically, you should do something like */ /* */ @@ -27,9 +27,9 @@ /* - copy `include/freetype/ftimage.h' and `src/raster/ftmisc.h' to your */ /* current directory */ /* */ - /* - compile `ftraster' with the _STANDALONE_ macro defined, as in */ + /* - compile `ftraster' with the STANDALONE_ macro defined, as in */ /* */ - /* cc -c -D_STANDALONE_ ftraster.c */ + /* cc -c -DSTANDALONE_ ftraster.c */ /* */ /* The renderer can be initialized with a call to */ /* `ft_standard_raster.raster_new'; a bitmap can be generated */ @@ -47,7 +47,7 @@ /* */ /*************************************************************************/ -#ifdef _STANDALONE_ +#ifdef STANDALONE_ /* The size in bytes of the render pool used by the scan-line converter */ /* to do all of its work. */ @@ -60,7 +60,7 @@ #include "ftmisc.h" #include "ftimage.h" -#else /* !_STANDALONE_ */ +#else /* !STANDALONE_ */ #include <ft2build.h> #include "ftraster.h" @@ -68,7 +68,7 @@ #include "rastpic.h" -#endif /* !_STANDALONE_ */ +#endif /* !STANDALONE_ */ /*************************************************************************/ @@ -173,14 +173,12 @@ #define FT_COMPONENT trace_raster -#ifdef _STANDALONE_ +#ifdef STANDALONE_ /* Auxiliary macros for token concatenation. */ #define FT_ERR_XCAT( x, y ) x ## y #define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) -#define FT_MAX( a, b ) ( (a) > (b) ? (a) : (b) ) - /* This macro is used to indicate that a function parameter is unused. */ /* Its purpose is simply to reduce compiler warnings. Note also that */ /* simply defining it as `(void)x' doesn't avoid warnings with certain */ @@ -226,7 +224,7 @@ raster_done_ \ }; -#else /* !_STANDALONE_ */ +#else /* !STANDALONE_ */ #include FT_INTERNAL_OBJECTS_H @@ -242,7 +240,7 @@ #define Raster_Err_Unsupported Raster_Err_Cannot_Render_Glyph -#endif /* !_STANDALONE_ */ +#endif /* !STANDALONE_ */ #ifndef FT_MEM_SET @@ -251,6 +249,10 @@ #ifndef FT_MEM_ZERO #define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) +#endif + +#ifndef FT_ZERO +#define FT_ZERO( p ) FT_MEM_ZERO( p, sizeof ( *(p) ) ) #endif /* FMulDiv means `Fast MulDiv'; it is used in case where `b' is */ @@ -459,6 +461,12 @@ #define IS_TOP_OVERSHOOT( x ) \ (Bool)( x - FLOOR( x ) >= ras.precision_half ) +#if FT_RENDER_POOL_SIZE > 2048 +#define FT_MAX_BLACK_POOL ( FT_RENDER_POOL_SIZE / sizeof ( Long ) ) +#else +#define FT_MAX_BLACK_POOL ( 2048 / sizeof ( Long ) ) +#endif + /* The most used variables are positioned at the top of the structure. */ /* Thus, their offset can be coded with less opcodes, resulting in a */ /* smaller executable. */ @@ -1512,8 +1520,9 @@ state_bez = y1 < y3 ? Ascending_State : Descending_State; if ( ras.state != state_bez ) { - Bool o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 ) - : IS_TOP_OVERSHOOT( y1 ); + Bool o = ( state_bez == Ascending_State ) + ? IS_BOTTOM_OVERSHOOT( y1 ) + : IS_TOP_OVERSHOOT( y1 ); /* finalize current profile if any */ @@ -1648,8 +1657,9 @@ /* detect a change of direction */ if ( ras.state != state_bez ) { - Bool o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 ) - : IS_TOP_OVERSHOOT( y1 ); + Bool o = ( state_bez == Ascending_State ) + ? IS_BOTTOM_OVERSHOOT( y1 ) + : IS_TOP_OVERSHOOT( y1 ); /* finalize current profile if any */ @@ -2382,7 +2392,7 @@ pxl = e2; /* check that the other pixel isn't set */ - e1 = pxl == e1 ? e2 : e1; + e1 = ( pxl == e1 ) ? e2 : e1; e1 = TRUNC( e1 ); @@ -2583,7 +2593,7 @@ pxl = e2; /* check that the other pixel isn't set */ - e1 = pxl == e1 ? e2 : e1; + e1 = ( pxl == e1 ) ? e2 : e1; e1 = TRUNC( e1 ); @@ -3041,7 +3051,7 @@ /**** a static object. *****/ -#ifdef _STANDALONE_ +#ifdef STANDALONE_ static int @@ -3053,7 +3063,7 @@ *araster = (FT_Raster)&the_raster; - FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) ); + FT_ZERO( &the_raster ); ft_black_init( &the_raster ); return 0; @@ -3068,7 +3078,7 @@ } -#else /* !_STANDALONE_ */ +#else /* !STANDALONE_ */ static int @@ -3102,13 +3112,13 @@ } -#endif /* !_STANDALONE_ */ +#endif /* !STANDALONE_ */ static void - ft_black_reset( black_PRaster raster, - char* pool_base, - Long pool_size ) + ft_black_reset( FT_Raster raster, + PByte pool_base, + ULong pool_size ) { FT_UNUSED( raster ); FT_UNUSED( pool_base ); @@ -3117,20 +3127,20 @@ static int - ft_black_set_mode( black_PRaster raster, - ULong mode, - const char* palette ) + ft_black_set_mode( FT_Raster raster, + ULong mode, + void* args ) { FT_UNUSED( raster ); FT_UNUSED( mode ); - FT_UNUSED( palette ); + FT_UNUSED( args ); return 0; } static int - ft_black_render( black_PRaster raster, + ft_black_render( FT_Raster raster, const FT_Raster_Params* params ) { const FT_Outline* outline = (const FT_Outline*)params->source; @@ -3138,7 +3148,7 @@ black_TWorker worker[1]; - Long buffer[FT_MAX( FT_RENDER_POOL_SIZE, 2048 ) / sizeof ( Long )]; + Long buffer[FT_MAX_BLACK_POOL]; if ( !raster ) @@ -3175,6 +3185,20 @@ if ( !target_map->buffer ) return FT_THROW( Invalid ); + /* reject too large outline coordinates */ + { + FT_Vector* vec = outline->points; + FT_Vector* limit = vec + outline->n_points; + + + for ( ; vec < limit; vec++ ) + { + if ( vec->x < -0x1000000L || vec->x > 0x1000000L || + vec->y < -0x1000000L || vec->y > 0x1000000L ) + return FT_THROW( Invalid ); + } + } + ras.outline = *outline; ras.target = *target_map; @@ -3190,11 +3214,12 @@ FT_GLYPH_FORMAT_OUTLINE, - (FT_Raster_New_Func) ft_black_new, - (FT_Raster_Reset_Func) ft_black_reset, - (FT_Raster_Set_Mode_Func)ft_black_set_mode, - (FT_Raster_Render_Func) ft_black_render, - (FT_Raster_Done_Func) ft_black_done ) + (FT_Raster_New_Func) ft_black_new, /* raster_new */ + (FT_Raster_Reset_Func) ft_black_reset, /* raster_reset */ + (FT_Raster_Set_Mode_Func)ft_black_set_mode, /* raster_set_mode */ + (FT_Raster_Render_Func) ft_black_render, /* raster_render */ + (FT_Raster_Done_Func) ft_black_done /* raster_done */ + ) /* END */ diff --git a/src/3rdparty/freetype/src/raster/ftraster.h b/src/3rdparty/freetype/src/raster/ftraster.h index a270d487b9..40b5d6d321 100644 --- a/src/3rdparty/freetype/src/raster/ftraster.h +++ b/src/3rdparty/freetype/src/raster/ftraster.h @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph rasterizer (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTRASTER_H__ -#define __FTRASTER_H__ +#ifndef FTRASTER_H_ +#define FTRASTER_H_ #include <ft2build.h> @@ -33,14 +33,14 @@ FT_BEGIN_HEADER /* Uncomment the following line if you are using ftraster.c as a */ /* standalone module, fully independent of FreeType. */ /* */ -/* #define _STANDALONE_ */ +/* #define STANDALONE_ */ FT_EXPORT_VAR( const FT_Raster_Funcs ) ft_standard_raster; FT_END_HEADER -#endif /* __FTRASTER_H__ */ +#endif /* FTRASTER_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/raster/ftrend1.c b/src/3rdparty/freetype/src/raster/ftrend1.c index f314392839..a7ce9731d7 100644 --- a/src/3rdparty/freetype/src/raster/ftrend1.c +++ b/src/3rdparty/freetype/src/raster/ftrend1.c @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph rasterizer interface (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -31,12 +31,7 @@ static FT_Error ft_raster1_init( FT_Renderer render ) { - FT_Library library = FT_MODULE_LIBRARY( render ); - - - render->clazz->raster_class->raster_reset( render->raster, - library->raster_pool, - library->raster_pool_size ); + render->clazz->raster_class->raster_reset( render->raster, NULL, 0 ); return FT_Err_Ok; } @@ -88,7 +83,7 @@ FT_GlyphSlot slot, FT_BBox* cbox ) { - FT_MEM_ZERO( cbox, sizeof ( *cbox ) ); + FT_ZERO( cbox ); if ( slot->format == render->glyph_format ) FT_Outline_Get_CBox( &slot->outline, cbox ); @@ -102,12 +97,12 @@ FT_Render_Mode mode, const FT_Vector* origin ) { - FT_Error error; - FT_Outline* outline; - FT_BBox cbox, cbox0; - FT_UInt width, height, pitch; - FT_Bitmap* bitmap; - FT_Memory memory; + FT_Error error = FT_Err_Ok; + FT_Outline* outline = &slot->outline; + FT_Bitmap* bitmap = &slot->bitmap; + FT_Memory memory = render->root.memory; + FT_Pos x_shift = 0; + FT_Pos y_shift = 0; FT_Raster_Params params; @@ -126,60 +121,6 @@ return FT_THROW( Cannot_Render_Glyph ); } - outline = &slot->outline; - - /* translate the outline to the new origin if needed */ - if ( origin ) - FT_Outline_Translate( outline, origin->x, origin->y ); - - /* compute the control box, and grid fit it */ - FT_Outline_Get_CBox( outline, &cbox0 ); - - /* undocumented but confirmed: bbox values get rounded */ -#if 1 - cbox.xMin = FT_PIX_ROUND( cbox0.xMin ); - cbox.yMin = FT_PIX_ROUND( cbox0.yMin ); - cbox.xMax = FT_PIX_ROUND( cbox0.xMax ); - cbox.yMax = FT_PIX_ROUND( cbox0.yMax ); -#else - cbox.xMin = FT_PIX_FLOOR( cbox.xMin ); - cbox.yMin = FT_PIX_FLOOR( cbox.yMin ); - cbox.xMax = FT_PIX_CEIL( cbox.xMax ); - cbox.yMax = FT_PIX_CEIL( cbox.yMax ); -#endif - - /* If either `width' or `height' round to 0, try */ - /* explicitly rounding up/down. In the case of */ - /* glyphs containing only one very narrow feature, */ - /* this gives the drop-out compensation in the scan */ - /* conversion code a chance to do its stuff. */ - width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 ); - if ( width == 0 ) - { - cbox.xMin = FT_PIX_FLOOR( cbox0.xMin ); - cbox.xMax = FT_PIX_CEIL( cbox0.xMax ); - - width = (FT_UInt)( ( cbox.xMax - cbox.xMin ) >> 6 ); - } - - height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 ); - if ( height == 0 ) - { - cbox.yMin = FT_PIX_FLOOR( cbox0.yMin ); - cbox.yMax = FT_PIX_CEIL( cbox0.yMax ); - - height = (FT_UInt)( ( cbox.yMax - cbox.yMin ) >> 6 ); - } - - if ( width > FT_USHORT_MAX || height > FT_USHORT_MAX ) - { - error = FT_THROW( Invalid_Argument ); - goto Exit; - } - - bitmap = &slot->bitmap; - memory = render->root.memory; - /* release old bitmap buffer */ if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) { @@ -187,44 +128,54 @@ slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; } - pitch = ( ( width + 15 ) >> 4 ) << 1; - bitmap->pixel_mode = FT_PIXEL_MODE_MONO; + ft_glyphslot_preset_bitmap( slot, mode, origin ); - bitmap->width = width; - bitmap->rows = height; - bitmap->pitch = (int)pitch; - - if ( FT_ALLOC_MULT( bitmap->buffer, pitch, height ) ) + /* allocate new one */ + if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, bitmap->pitch ) ) goto Exit; slot->internal->flags |= FT_GLYPH_OWN_BITMAP; + x_shift = -slot->bitmap_left * 64; + y_shift = ( (FT_Int)bitmap->rows - slot->bitmap_top ) * 64; + + if ( origin ) + { + x_shift += origin->x; + y_shift += origin->y; + } + /* translate outline to render it into the bitmap */ - FT_Outline_Translate( outline, -cbox.xMin, -cbox.yMin ); + if ( x_shift || y_shift ) + FT_Outline_Translate( outline, x_shift, y_shift ); /* set up parameters */ params.target = bitmap; params.source = outline; - params.flags = 0; + params.flags = FT_RASTER_FLAG_DEFAULT; /* render outline into the bitmap */ error = render->raster_render( render->raster, ¶ms ); - FT_Outline_Translate( outline, cbox.xMin, cbox.yMin ); - - if ( error ) - goto Exit; - - slot->format = FT_GLYPH_FORMAT_BITMAP; - slot->bitmap_left = (FT_Int)( cbox.xMin >> 6 ); - slot->bitmap_top = (FT_Int)( cbox.yMax >> 6 ); - Exit: + if ( !error ) + /* everything is fine; the glyph is now officially a bitmap */ + slot->format = FT_GLYPH_FORMAT_BITMAP; + else if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) + { + FT_FREE( bitmap->buffer ); + slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; + } + + if ( x_shift || y_shift ) + FT_Outline_Translate( outline, -x_shift, -y_shift ); + return error; } - FT_DEFINE_RENDERER( ft_raster1_renderer_class, + FT_DEFINE_RENDERER( + ft_raster1_renderer_class, FT_MODULE_RENDERER, sizeof ( FT_RendererRec ), @@ -233,21 +184,20 @@ 0x10000L, 0x20000L, - 0, /* module specific interface */ + NULL, /* module specific interface */ - (FT_Module_Constructor)ft_raster1_init, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - , + (FT_Module_Constructor)ft_raster1_init, /* module_init */ + (FT_Module_Destructor) NULL, /* module_done */ + (FT_Module_Requester) NULL, /* get_interface */ FT_GLYPH_FORMAT_OUTLINE, - (FT_Renderer_RenderFunc) ft_raster1_render, - (FT_Renderer_TransformFunc)ft_raster1_transform, - (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, - (FT_Renderer_SetModeFunc) ft_raster1_set_mode, + (FT_Renderer_RenderFunc) ft_raster1_render, /* render_glyph */ + (FT_Renderer_TransformFunc)ft_raster1_transform, /* transform_glyph */ + (FT_Renderer_GetCBoxFunc) ft_raster1_get_cbox, /* get_glyph_cbox */ + (FT_Renderer_SetModeFunc) ft_raster1_set_mode, /* set_mode */ - (FT_Raster_Funcs*) &FT_STANDARD_RASTER_GET + (FT_Raster_Funcs*)&FT_STANDARD_RASTER_GET /* raster_class */ ) diff --git a/src/3rdparty/freetype/src/raster/ftrend1.h b/src/3rdparty/freetype/src/raster/ftrend1.h index edc5d13f4c..2abdf2d703 100644 --- a/src/3rdparty/freetype/src/raster/ftrend1.h +++ b/src/3rdparty/freetype/src/raster/ftrend1.h @@ -4,7 +4,7 @@ /* */ /* The FreeType glyph rasterizer interface (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTREND1_H__ -#define __FTREND1_H__ +#ifndef FTREND1_H_ +#define FTREND1_H_ #include <ft2build.h> @@ -32,7 +32,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTREND1_H__ */ +#endif /* FTREND1_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/raster/module.mk b/src/3rdparty/freetype/src/raster/module.mk index 75ea107530..b115f416b2 100644 --- a/src/3rdparty/freetype/src/raster/module.mk +++ b/src/3rdparty/freetype/src/raster/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2015 by +# Copyright 1996-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/raster/raster.c b/src/3rdparty/freetype/src/raster/raster.c index 21bb16de1e..76edd21e1e 100644 --- a/src/3rdparty/freetype/src/raster/raster.c +++ b/src/3rdparty/freetype/src/raster/raster.c @@ -4,7 +4,7 @@ /* */ /* FreeType monochrome rasterer module component (body only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,11 +17,11 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT - #include <ft2build.h> -#include "rastpic.c" + #include "ftraster.c" #include "ftrend1.c" +#include "rastpic.c" /* END */ diff --git a/src/3rdparty/freetype/src/raster/rasterrs.h b/src/3rdparty/freetype/src/raster/rasterrs.h index e7f00bcace..22a3e15340 100644 --- a/src/3rdparty/freetype/src/raster/rasterrs.h +++ b/src/3rdparty/freetype/src/raster/rasterrs.h @@ -4,7 +4,7 @@ /* */ /* monochrome renderer error codes (specification only). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __RASTERRS_H__ -#define __RASTERRS_H__ +#ifndef RASTERRS_H_ +#define RASTERRS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX Raster_Err_ @@ -36,7 +36,7 @@ #include FT_ERRORS_H -#endif /* __RASTERRS_H__ */ +#endif /* RASTERRS_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/raster/rastpic.c b/src/3rdparty/freetype/src/raster/rastpic.c index 77e7ec3f90..1dc8981b8a 100644 --- a/src/3rdparty/freetype/src/raster/rastpic.c +++ b/src/3rdparty/freetype/src/raster/rastpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for raster module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2018 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/src/raster/rastpic.h b/src/3rdparty/freetype/src/raster/rastpic.h index 408996a908..6d0877c423 100644 --- a/src/3rdparty/freetype/src/raster/rastpic.h +++ b/src/3rdparty/freetype/src/raster/rastpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for raster module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2018 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __RASTPIC_H__ -#define __RASTPIC_H__ +#ifndef RASTPIC_H_ +#define RASTPIC_H_ #include FT_INTERNAL_PIC_H @@ -57,7 +57,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __RASTPIC_H__ */ +#endif /* RASTPIC_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/raster/rules.mk b/src/3rdparty/freetype/src/raster/rules.mk index c214b35d37..9aef1f0bab 100644 --- a/src/3rdparty/freetype/src/raster/rules.mk +++ b/src/3rdparty/freetype/src/raster/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2015 by +# Copyright 1996-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/sfnt/Jamfile b/src/3rdparty/freetype/src/sfnt/Jamfile index cc98d1011e..57977fc966 100644 --- a/src/3rdparty/freetype/src/sfnt/Jamfile +++ b/src/3rdparty/freetype/src/sfnt/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/sfnt Jamfile # -# Copyright 2001-2015 by +# Copyright 2001-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/sfnt/module.mk b/src/3rdparty/freetype/src/sfnt/module.mk index 535fe22afd..51ca67e784 100644 --- a/src/3rdparty/freetype/src/sfnt/module.mk +++ b/src/3rdparty/freetype/src/sfnt/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2015 by +# Copyright 1996-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/sfnt/pngshim.c b/src/3rdparty/freetype/src/sfnt/pngshim.c index ea60452635..16020266af 100644 --- a/src/3rdparty/freetype/src/sfnt/pngshim.c +++ b/src/3rdparty/freetype/src/sfnt/pngshim.c @@ -4,7 +4,7 @@ /* */ /* PNG Bitmap glyph support. */ /* */ -/* Copyright 2013-2015 by */ +/* Copyright 2013-2018 by */ /* Google, Inc. */ /* Written by Stuart Gill and Behdad Esfahbod. */ /* */ @@ -24,9 +24,10 @@ #include FT_CONFIG_STANDARD_LIBRARY_H -#ifdef FT_CONFIG_OPTION_USE_PNG +#if defined( TT_CONFIG_OPTION_EMBEDDED_BITMAPS ) && \ + defined( FT_CONFIG_OPTION_USE_PNG ) - /* We always include <stjmp.h>, so make libpng shut up! */ + /* We always include <setjmp.h>, so make libpng shut up! */ #define PNG_SKIP_SETJMP_CHECK 1 #include <png.h> #include "pngshim.h" @@ -48,18 +49,85 @@ } - /* Premultiplies data and converts RGBA bytes => native endian. */ + /* Premultiplies data and converts RGBA bytes => BGRA. */ static void premultiply_data( png_structp png, png_row_infop row_info, png_bytep data ) { - unsigned int i; + unsigned int i = 0, limit; + + /* The `vector_size' attribute was introduced in gcc 3.1, which */ + /* predates clang; the `__BYTE_ORDER__' preprocessor symbol was */ + /* introduced in gcc 4.6 and clang 3.2, respectively. */ + /* `__builtin_shuffle' for gcc was introduced in gcc 4.7.0. */ +#if ( ( defined( __GNUC__ ) && \ + ( ( __GNUC__ >= 5 ) || \ + ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 7 ) ) ) ) || \ + ( defined( __clang__ ) && \ + ( ( __clang_major__ >= 4 ) || \ + ( ( __clang_major__ == 3 ) && ( __clang_minor__ >= 2 ) ) ) ) ) && \ + defined( __OPTIMIZE__ ) && \ + __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + +#ifdef __clang__ + /* the clang documentation doesn't cover the two-argument case of */ + /* `__builtin_shufflevector'; however, it is is implemented since */ + /* version 2.8 */ +#define vector_shuffle __builtin_shufflevector +#else +#define vector_shuffle __builtin_shuffle +#endif + + typedef unsigned short v82 __attribute__(( vector_size( 16 ) )); + + + if ( row_info->rowbytes > 15 ) + { + /* process blocks of 16 bytes in one rush, which gives a nice speed-up */ + limit = row_info->rowbytes - 16 + 1; + for ( ; i < limit; i += 16 ) + { + unsigned char* base = &data[i]; + + v82 s, s0, s1, a; + + /* clang <= 3.9 can't apply scalar values to vectors */ + /* (or rather, it needs a different syntax) */ + v82 n0x80 = { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }; + v82 n0xFF = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + v82 n8 = { 8, 8, 8, 8, 8, 8, 8, 8 }; + + v82 ma = { 1, 1, 3, 3, 5, 5, 7, 7 }; + v82 o1 = { 0, 0xFF, 0, 0xFF, 0, 0xFF, 0, 0xFF }; + v82 m0 = { 1, 0, 3, 2, 5, 4, 7, 6 }; + + + ft_memcpy( &s, base, 16 ); /* RGBA RGBA RGBA RGBA */ + s0 = s & n0xFF; /* R B R B R B R B */ + s1 = s >> n8; /* G A G A G A G A */ + + a = vector_shuffle( s1, ma ); /* A A A A A A A A */ + s1 |= o1; /* G 1 G 1 G 1 G 1 */ + s0 = vector_shuffle( s0, m0 ); /* B R B R B R B R */ + + s0 *= a; + s1 *= a; + s0 += n0x80; + s1 += n0x80; + s0 = ( s0 + ( s0 >> n8 ) ) >> n8; + s1 = ( s1 + ( s1 >> n8 ) ) >> n8; + + s = s0 | ( s1 << n8 ); + ft_memcpy( base, &s, 16 ); + } + } +#endif /* use `vector_size' */ FT_UNUSED( png ); - - for ( i = 0; i < row_info->rowbytes; i += 4 ) + limit = row_info->rowbytes; + for ( ; i < limit; i += 4 ) { unsigned char* base = &data[i]; unsigned int alpha = base[3]; @@ -169,7 +237,7 @@ return; } - memcpy( data, stream->cursor, length ); + ft_memcpy( data, stream->cursor, length ); FT_FRAME_EXIT(); } @@ -184,7 +252,8 @@ FT_Memory memory, FT_Byte* data, FT_UInt png_len, - FT_Bool populate_map_and_metrics ) + FT_Bool populate_map_and_metrics, + FT_Bool metrics_only ) { FT_Bitmap *map = &slot->bitmap; FT_Error error = FT_Err_Ok; @@ -258,9 +327,6 @@ if ( populate_map_and_metrics ) { - FT_ULong size; - - metrics->width = (FT_UShort)imgWidth; metrics->height = (FT_UShort)imgHeight; @@ -276,13 +342,6 @@ error = FT_THROW( Array_Too_Large ); goto DestroyExit; } - - /* this doesn't overflow: 0x7FFF * 0x7FFF * 4 < 2^32 */ - size = map->rows * (FT_ULong)map->pitch; - - error = ft_glyphslot_alloc_bitmap( slot, size ); - if ( error ) - goto DestroyExit; } /* convert palette/gray image to rgb */ @@ -334,6 +393,9 @@ goto DestroyExit; } + if ( metrics_only ) + goto DestroyExit; + switch ( color_type ) { default: @@ -349,6 +411,17 @@ break; } + if ( populate_map_and_metrics ) + { + /* this doesn't overflow: 0x7FFF * 0x7FFF * 4 < 2^32 */ + FT_ULong size = map->rows * (FT_ULong)map->pitch; + + + error = ft_glyphslot_alloc_bitmap( slot, size ); + if ( error ) + goto DestroyExit; + } + if ( FT_NEW_ARRAY( rows, imgHeight ) ) { error = FT_THROW( Out_Of_Memory ); @@ -372,7 +445,12 @@ return error; } -#endif /* FT_CONFIG_OPTION_USE_PNG */ +#else /* !(TT_CONFIG_OPTION_EMBEDDED_BITMAPS && FT_CONFIG_OPTION_USE_PNG) */ + + /* ANSI C doesn't like empty source files */ + typedef int _pngshim_dummy; + +#endif /* !(TT_CONFIG_OPTION_EMBEDDED_BITMAPS && FT_CONFIG_OPTION_USE_PNG) */ /* END */ diff --git a/src/3rdparty/freetype/src/sfnt/pngshim.h b/src/3rdparty/freetype/src/sfnt/pngshim.h index 4cc5c2b3a0..194238c3a2 100644 --- a/src/3rdparty/freetype/src/sfnt/pngshim.h +++ b/src/3rdparty/freetype/src/sfnt/pngshim.h @@ -4,7 +4,7 @@ /* */ /* PNG Bitmap glyph support. */ /* */ -/* Copyright 2013-2015 by */ +/* Copyright 2013-2018 by */ /* Google, Inc. */ /* Written by Stuart Gill and Behdad Esfahbod. */ /* */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __PNGSHIM_H__ -#define __PNGSHIM_H__ +#ifndef PNGSHIM_H_ +#define PNGSHIM_H_ #include <ft2build.h> @@ -38,13 +38,14 @@ FT_BEGIN_HEADER FT_Memory memory, FT_Byte* data, FT_UInt png_len, - FT_Bool populate_map_and_metrics ); + FT_Bool populate_map_and_metrics, + FT_Bool metrics_only ); #endif FT_END_HEADER -#endif /* __PNGSHIM_H__ */ +#endif /* PNGSHIM_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/sfnt/rules.mk b/src/3rdparty/freetype/src/sfnt/rules.mk index 3cc76b3f7a..83acc66a8f 100644 --- a/src/3rdparty/freetype/src/sfnt/rules.mk +++ b/src/3rdparty/freetype/src/sfnt/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2015 by +# Copyright 1996-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/sfnt/sfdriver.c b/src/3rdparty/freetype/src/sfnt/sfdriver.c index 6a3f0d9933..303e1ca9f1 100644 --- a/src/3rdparty/freetype/src/sfnt/sfdriver.c +++ b/src/3rdparty/freetype/src/sfnt/sfdriver.c @@ -4,7 +4,7 @@ /* */ /* High-level SFNT driver interface (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,6 +20,7 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_SFNT_H #include FT_INTERNAL_OBJECTS_H +#include FT_TRUETYPE_IDS_H #include "sfdriver.h" #include "ttload.h" @@ -50,6 +51,11 @@ #include FT_SERVICE_SFNT_H #include FT_SERVICE_TT_CMAP_H +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include FT_MULTIPLE_MASTERS_H +#include FT_SERVICE_MULTIPLE_MASTERS_H +#endif + /*************************************************************************/ /* */ @@ -88,7 +94,7 @@ break; case FT_SFNT_OS2: - table = face->os2.version == 0xFFFFU ? NULL : &face->os2; + table = ( face->os2.version == 0xFFFFU ) ? NULL : &face->os2; break; case FT_SFNT_POST: @@ -139,9 +145,11 @@ FT_DEFINE_SERVICE_SFNT_TABLEREC( sfnt_service_sfnt_table, - (FT_SFNT_TableLoadFunc)tt_face_load_any, - (FT_SFNT_TableGetFunc) get_sfnt_table, - (FT_SFNT_TableInfoFunc)sfnt_table_info ) + + (FT_SFNT_TableLoadFunc)tt_face_load_any, /* load_table */ + (FT_SFNT_TableGetFunc) get_sfnt_table, /* get_table */ + (FT_SFNT_TableInfoFunc)sfnt_table_info /* table_info */ + ) #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES @@ -152,7 +160,7 @@ */ static FT_Error - sfnt_get_glyph_name( TT_Face face, + sfnt_get_glyph_name( FT_Face face, FT_UInt glyph_index, FT_Pointer buffer, FT_UInt buffer_max ) @@ -161,7 +169,7 @@ FT_Error error; - error = tt_face_get_ps_name( face, glyph_index, &gname ); + error = tt_face_get_ps_name( (TT_Face)face, glyph_index, &gname ); if ( !error ) FT_STRCPYN( buffer, gname, buffer_max ); @@ -170,26 +178,26 @@ static FT_UInt - sfnt_get_name_index( TT_Face face, + sfnt_get_name_index( FT_Face face, FT_String* glyph_name ) { - FT_Face root = &face->root; + TT_Face ttface = (TT_Face)face; FT_UInt i, max_gid = FT_UINT_MAX; - if ( root->num_glyphs < 0 ) + if ( face->num_glyphs < 0 ) return 0; - else if ( (FT_ULong)root->num_glyphs < FT_UINT_MAX ) - max_gid = (FT_UInt)root->num_glyphs; + else if ( (FT_ULong)face->num_glyphs < FT_UINT_MAX ) + max_gid = (FT_UInt)face->num_glyphs; else FT_TRACE0(( "Ignore glyph names for invalid GID 0x%08x - 0x%08x\n", - FT_UINT_MAX, root->num_glyphs )); + FT_UINT_MAX, face->num_glyphs )); for ( i = 0; i < max_gid; i++ ) { FT_String* gname; - FT_Error error = tt_face_get_ps_name( face, i, &gname ); + FT_Error error = tt_face_get_ps_name( ttface, i, &gname ); if ( error ) @@ -205,9 +213,10 @@ FT_DEFINE_SERVICE_GLYPHDICTREC( sfnt_service_glyph_dict, - (FT_GlyphDict_GetNameFunc) sfnt_get_glyph_name, - (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index ) + (FT_GlyphDict_GetNameFunc) sfnt_get_glyph_name, /* get_name */ + (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index /* name_index */ + ) #endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ @@ -217,120 +226,850 @@ * */ - static const char* - sfnt_get_ps_name( TT_Face face ) + /* an array representing allowed ASCII characters in a PS string */ + static const unsigned char sfnt_ps_map[16] = { - FT_Int n, found_win, found_apple; - const char* result = NULL; + /* 4 0 C 8 */ + 0x00, 0x00, /* 0x00: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 */ + 0x00, 0x00, /* 0x10: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 */ + 0xDE, 0x7C, /* 0x20: 1 1 0 1 1 1 1 0 0 1 1 1 1 1 0 0 */ + 0xFF, 0xAF, /* 0x30: 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 1 */ + 0xFF, 0xFF, /* 0x40: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 */ + 0xFF, 0xD7, /* 0x50: 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 */ + 0xFF, 0xFF, /* 0x60: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 */ + 0xFF, 0x57 /* 0x70: 1 1 1 1 1 1 1 1 0 1 0 1 0 1 1 1 */ + }; - /* shouldn't happen, but just in case to avoid memory leaks */ - if ( face->postscript_name ) - return face->postscript_name; + static int + sfnt_is_postscript( int c ) + { + unsigned int cc; - /* scan the name table to see whether we have a Postscript name here, */ - /* either in Macintosh or Windows platform encodings */ - found_win = -1; - found_apple = -1; + + if ( c < 0 || c >= 0x80 ) + return 0; + + cc = (unsigned int)c; + + return sfnt_ps_map[cc >> 3] & ( 1 << ( cc & 0x07 ) ); + } + + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + + /* Only ASCII letters and digits are taken for a variation font */ + /* instance's PostScript name. */ + /* */ + /* `ft_isalnum' is a macro, but we need a function here, thus */ + /* this definition. */ + static int + sfnt_is_alphanumeric( int c ) + { + return ft_isalnum( c ); + } + + + /* the implementation of MurmurHash3 is taken and adapted from */ + /* https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp */ + +#define ROTL32( x, r ) ( x << r ) | ( x >> ( 32 - r ) ) + + + static FT_UInt32 + fmix32( FT_UInt32 h ) + { + h ^= h >> 16; + h *= 0x85ebca6b; + h ^= h >> 13; + h *= 0xc2b2ae35; + h ^= h >> 16; + + return h; + } + + + static void + murmur_hash_3_128( const void* key, + const unsigned int len, + FT_UInt32 seed, + void* out ) + { + const FT_Byte* data = (const FT_Byte*)key; + const int nblocks = (int)len / 16; + + FT_UInt32 h1 = seed; + FT_UInt32 h2 = seed; + FT_UInt32 h3 = seed; + FT_UInt32 h4 = seed; + + const FT_UInt32 c1 = 0x239b961b; + const FT_UInt32 c2 = 0xab0e9789; + const FT_UInt32 c3 = 0x38b34ae5; + const FT_UInt32 c4 = 0xa1e38b93; + + const FT_UInt32* blocks = (const FT_UInt32*)( data + nblocks * 16 ); + + int i; + + + for( i = -nblocks; i; i++ ) + { + FT_UInt32 k1 = blocks[i * 4 + 0]; + FT_UInt32 k2 = blocks[i * 4 + 1]; + FT_UInt32 k3 = blocks[i * 4 + 2]; + FT_UInt32 k4 = blocks[i * 4 + 3]; + + + k1 *= c1; + k1 = ROTL32( k1, 15 ); + k1 *= c2; + h1 ^= k1; + + h1 = ROTL32( h1, 19 ); + h1 += h2; + h1 = h1 * 5 + 0x561ccd1b; + + k2 *= c2; + k2 = ROTL32( k2, 16 ); + k2 *= c3; + h2 ^= k2; + + h2 = ROTL32( h2, 17 ); + h2 += h3; + h2 = h2 * 5 + 0x0bcaa747; + + k3 *= c3; + k3 = ROTL32( k3, 17 ); + k3 *= c4; + h3 ^= k3; + + h3 = ROTL32( h3, 15 ); + h3 += h4; + h3 = h3 * 5 + 0x96cd1c35; + + k4 *= c4; + k4 = ROTL32( k4, 18 ); + k4 *= c1; + h4 ^= k4; + + h4 = ROTL32( h4, 13 ); + h4 += h1; + h4 = h4 * 5 + 0x32ac3b17; + } + + { + const FT_Byte* tail = (const FT_Byte*)( data + nblocks * 16 ); + + FT_UInt32 k1 = 0; + FT_UInt32 k2 = 0; + FT_UInt32 k3 = 0; + FT_UInt32 k4 = 0; + + + switch ( len & 15 ) + { + case 15: + k4 ^= (FT_UInt32)tail[14] << 16; + case 14: + k4 ^= (FT_UInt32)tail[13] << 8; + case 13: + k4 ^= (FT_UInt32)tail[12]; + k4 *= c4; + k4 = ROTL32( k4, 18 ); + k4 *= c1; + h4 ^= k4; + + case 12: + k3 ^= (FT_UInt32)tail[11] << 24; + case 11: + k3 ^= (FT_UInt32)tail[10] << 16; + case 10: + k3 ^= (FT_UInt32)tail[9] << 8; + case 9: + k3 ^= (FT_UInt32)tail[8]; + k3 *= c3; + k3 = ROTL32( k3, 17 ); + k3 *= c4; + h3 ^= k3; + + case 8: + k2 ^= (FT_UInt32)tail[7] << 24; + case 7: + k2 ^= (FT_UInt32)tail[6] << 16; + case 6: + k2 ^= (FT_UInt32)tail[5] << 8; + case 5: + k2 ^= (FT_UInt32)tail[4]; + k2 *= c2; + k2 = ROTL32( k2, 16 ); + k2 *= c3; + h2 ^= k2; + + case 4: + k1 ^= (FT_UInt32)tail[3] << 24; + case 3: + k1 ^= (FT_UInt32)tail[2] << 16; + case 2: + k1 ^= (FT_UInt32)tail[1] << 8; + case 1: + k1 ^= (FT_UInt32)tail[0]; + k1 *= c1; + k1 = ROTL32( k1, 15 ); + k1 *= c2; + h1 ^= k1; + } + } + + h1 ^= len; + h2 ^= len; + h3 ^= len; + h4 ^= len; + + h1 += h2; + h1 += h3; + h1 += h4; + + h2 += h1; + h3 += h1; + h4 += h1; + + h1 = fmix32( h1 ); + h2 = fmix32( h2 ); + h3 = fmix32( h3 ); + h4 = fmix32( h4 ); + + h1 += h2; + h1 += h3; + h1 += h4; + + h2 += h1; + h3 += h1; + h4 += h1; + + ((FT_UInt32*)out)[0] = h1; + ((FT_UInt32*)out)[1] = h2; + ((FT_UInt32*)out)[2] = h3; + ((FT_UInt32*)out)[3] = h4; + } + + +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + + + typedef int (*char_type_func)( int c ); + + + /* handling of PID/EID 3/0 and 3/1 is the same */ +#define IS_WIN( n ) ( (n)->platformID == 3 && \ + ( (n)->encodingID == 1 || (n)->encodingID == 0 ) && \ + (n)->languageID == 0x409 ) + +#define IS_APPLE( n ) ( (n)->platformID == 1 && \ + (n)->encodingID == 0 && \ + (n)->languageID == 0 ) + + static char* + get_win_string( FT_Memory memory, + FT_Stream stream, + TT_Name entry, + char_type_func char_type, + FT_Bool report_invalid_characters ) + { + FT_Error error = FT_Err_Ok; + + char* result = NULL; + FT_String* r; + FT_Char* p; + FT_UInt len; + + FT_UNUSED( error ); + + + if ( FT_ALLOC( result, entry->stringLength / 2 + 1 ) ) + return NULL; + + if ( FT_STREAM_SEEK( entry->stringOffset ) || + FT_FRAME_ENTER( entry->stringLength ) ) + { + FT_FREE( result ); + entry->stringLength = 0; + entry->stringOffset = 0; + FT_FREE( entry->string ); + + return NULL; + } + + r = (FT_String*)result; + p = (FT_Char*)stream->cursor; + + for ( len = entry->stringLength / 2; len > 0; len--, p += 2 ) + { + if ( p[0] == 0 ) + { + if ( char_type( p[1] ) ) + *r++ = p[1]; + else + { + if ( report_invalid_characters ) + { + FT_TRACE0(( "get_win_string:" + " Character `%c' (0x%X) invalid in PS name string\n", + p[1], p[1] )); + /* it's not the job of FreeType to correct PS names... */ + *r++ = p[1]; + } + } + } + } + *r = '\0'; + + FT_FRAME_EXIT(); + + return result; + } + + + static char* + get_apple_string( FT_Memory memory, + FT_Stream stream, + TT_Name entry, + char_type_func char_type, + FT_Bool report_invalid_characters ) + { + FT_Error error = FT_Err_Ok; + + char* result = NULL; + FT_String* r; + FT_Char* p; + FT_UInt len; + + FT_UNUSED( error ); + + + if ( FT_ALLOC( result, entry->stringLength + 1 ) ) + return NULL; + + if ( FT_STREAM_SEEK( entry->stringOffset ) || + FT_FRAME_ENTER( entry->stringLength ) ) + { + FT_FREE( result ); + entry->stringOffset = 0; + entry->stringLength = 0; + FT_FREE( entry->string ); + + return NULL; + } + + r = (FT_String*)result; + p = (FT_Char*)stream->cursor; + + for ( len = entry->stringLength; len > 0; len--, p++ ) + { + if ( char_type( *p ) ) + *r++ = *p; + else + { + if ( report_invalid_characters ) + { + FT_TRACE0(( "get_apple_string:" + " Character `%c' (0x%X) invalid in PS name string\n", + *p, *p )); + /* it's not the job of FreeType to correct PS names... */ + *r++ = *p; + } + } + } + *r = '\0'; + + FT_FRAME_EXIT(); + + return result; + } + + + static FT_Bool + sfnt_get_name_id( TT_Face face, + FT_UShort id, + FT_Int *win, + FT_Int *apple ) + { + FT_Int n; + + + *win = -1; + *apple = -1; for ( n = 0; n < face->num_names; n++ ) { - TT_NameEntryRec* name = face->name_table.names + n; + TT_Name name = face->name_table.names + n; - if ( name->nameID == 6 && name->stringLength > 0 ) + if ( name->nameID == id && name->stringLength > 0 ) { - if ( name->platformID == 3 && - name->encodingID == 1 && - name->languageID == 0x409 ) - found_win = n; + if ( IS_WIN( name ) ) + *win = n; - if ( name->platformID == 1 && - name->encodingID == 0 && - name->languageID == 0 ) - found_apple = n; + if ( IS_APPLE( name ) ) + *apple = n; } } - if ( found_win != -1 ) + return ( *win >= 0 ) || ( *apple >= 0 ); + } + + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + + /* + The maximum length of an axis value descriptor. + + We need 65536 different values for the decimal fraction; this fits + nicely into five decimal places. Consequently, it consists of + + . the minus sign if the number is negative, + . up to five characters for the digits before the decimal point, + . the decimal point if there is a fractional part, and + . up to five characters for the digits after the decimal point. + + We also need one byte for the leading `_' character and up to four + bytes for the axis tag. + */ +#define MAX_VALUE_DESCRIPTOR_LEN ( 1 + 5 + 1 + 5 + 1 + 4 ) + + + /* the maximum length of PostScript font names */ +#define MAX_PS_NAME_LEN 127 + + + /* + * Find the shortest decimal representation of a 16.16 fixed point + * number. The function fills `buf' with the result, returning a pointer + * to the position after the representation's last byte. + */ + + static char* + fixed2float( FT_Int fixed, + char* buf ) + { + char* p; + char* q; + char tmp[5]; + + FT_Int int_part; + FT_Int frac_part; + + FT_Int i; + + + p = buf; + + if ( fixed == 0 ) { - FT_Memory memory = face->root.memory; - TT_NameEntryRec* name = face->name_table.names + found_win; - FT_UInt len = name->stringLength / 2; - FT_Error error = FT_Err_Ok; - - FT_UNUSED( error ); - - - if ( !FT_ALLOC( result, name->stringLength + 1 ) ) - { - FT_Stream stream = face->name_table.stream; - FT_String* r = (FT_String*)result; - FT_Char* p; - - - if ( FT_STREAM_SEEK( name->stringOffset ) || - FT_FRAME_ENTER( name->stringLength ) ) - { - FT_FREE( result ); - name->stringLength = 0; - name->stringOffset = 0; - FT_FREE( name->string ); - - goto Exit; - } - - p = (FT_Char*)stream->cursor; - - for ( ; len > 0; len--, p += 2 ) - { - if ( p[0] == 0 && p[1] >= 32 ) - *r++ = p[1]; - } - *r = '\0'; - - FT_FRAME_EXIT(); - } - goto Exit; + *p++ = '0'; + return p; } - if ( found_apple != -1 ) + if ( fixed < 0 ) { - FT_Memory memory = face->root.memory; - TT_NameEntryRec* name = face->name_table.names + found_apple; - FT_UInt len = name->stringLength; - FT_Error error = FT_Err_Ok; + *p++ = '-'; + fixed = -fixed; + } - FT_UNUSED( error ); + int_part = ( fixed >> 16 ) & 0xFFFF; + frac_part = fixed & 0xFFFF; + + /* get digits of integer part (in reverse order) */ + q = tmp; + while ( int_part > 0 ) + { + *q++ = '0' + int_part % 10; + int_part /= 10; + } + + /* copy digits in correct order to buffer */ + while ( q > tmp ) + *p++ = *--q; + + if ( !frac_part ) + return p; + + /* save position of point */ + q = p; + *p++ = '.'; + + /* apply rounding */ + frac_part = frac_part * 10 + 5; + + /* get digits of fractional part */ + for ( i = 0; i < 5; i++ ) + { + *p++ = '0' + (char)( frac_part / 0x10000L ); + + frac_part %= 0x10000L; + if ( !frac_part ) + break; + + frac_part *= 10; + } + + /* + If the remainder stored in `frac_part' (after the last FOR loop) is + smaller than 34480*10, the resulting decimal value minus 0.00001 is + an equivalent representation of `fixed'. + + The above FOR loop always finds the larger of the two values; I + verified this by iterating over all possible fixed point numbers. + + If the remainder is 17232*10, both values are equally good, and we + take the next even number (following IEEE 754's `round to nearest, + ties to even' rounding rule). + + If the remainder is smaller than 17232*10, the lower of the two + numbers is nearer to the exact result (values 17232 and 34480 were + also found by testing all possible fixed point values). + + We use this to find a shorter decimal representation. If not ending + with digit zero, we take the representation with less error. + */ + p--; + if ( p - q == 5 ) /* five digits? */ + { + /* take the representation that has zero as the last digit */ + if ( frac_part < 34480 * 10 && + *p == '1' ) + *p = '0'; + + /* otherwise use the one with less error */ + else if ( frac_part == 17232 * 10 && + *p & 1 ) + *p -= 1; + + else if ( frac_part < 17232 * 10 && + *p != '0' ) + *p -= 1; + } + + /* remove trailing zeros */ + while ( *p == '0' ) + *p-- = '\0'; + + return p + 1; + } - if ( !FT_ALLOC( result, len + 1 ) ) + static const char hexdigits[16] = + { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' + }; + + + static const char* + sfnt_get_var_ps_name( TT_Face face ) + { + FT_Error error; + FT_Memory memory = face->root.memory; + + FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm; + + FT_UInt num_coords; + FT_Fixed* coords; + FT_MM_Var* mm_var; + + FT_Int found, win, apple; + FT_UInt i, j; + + char* result = NULL; + char* p; + + + if ( !face->var_postscript_prefix ) + { + FT_UInt len; + + + /* check whether we have a Variations PostScript Name Prefix */ + found = sfnt_get_name_id( face, + TT_NAME_ID_VARIATIONS_PREFIX, + &win, + &apple ); + if ( !found ) { - FT_Stream stream = face->name_table.stream; + /* otherwise use the typographic family name */ + found = sfnt_get_name_id( face, + TT_NAME_ID_TYPOGRAPHIC_FAMILY, + &win, + &apple ); + } + + if ( !found ) + { + /* as a last resort we try the family name; note that this is */ + /* not in the Adobe TechNote, but GX fonts (which predate the */ + /* TechNote) benefit from this behaviour */ + found = sfnt_get_name_id( face, + TT_NAME_ID_FONT_FAMILY, + &win, + &apple ); + } + + if ( !found ) + { + FT_TRACE0(( "sfnt_get_var_ps_name:" + " Can't construct PS name prefix for font instances\n" )); + return NULL; + } + + /* prefer Windows entries over Apple */ + if ( win != -1 ) + result = get_win_string( face->root.memory, + face->name_table.stream, + face->name_table.names + win, + sfnt_is_alphanumeric, + 0 ); + else + result = get_apple_string( face->root.memory, + face->name_table.stream, + face->name_table.names + apple, + sfnt_is_alphanumeric, + 0 ); + + len = ft_strlen( result ); + + /* sanitize if necessary; we reserve space for 36 bytes (a 128bit */ + /* checksum as a hex number, preceded by `-' and followed by three */ + /* ASCII dots, to be used if the constructed PS name would be too */ + /* long); this is also sufficient for a single instance */ + if ( len > MAX_PS_NAME_LEN - ( 1 + 32 + 3 ) ) + { + len = MAX_PS_NAME_LEN - ( 1 + 32 + 3 ); + result[len] = '\0'; + + FT_TRACE0(( "sfnt_get_var_ps_name:" + " Shortening variation PS name prefix\n" + " " + " to %d characters\n", len )); + } + + face->var_postscript_prefix = result; + face->var_postscript_prefix_len = len; + } + + mm->get_var_blend( FT_FACE( face ), + &num_coords, + &coords, + NULL, + &mm_var ); + + if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) && + !FT_IS_VARIATION( FT_FACE( face ) ) ) + { + SFNT_Service sfnt = (SFNT_Service)face->sfnt; + + FT_Long instance = ( ( face->root.face_index & 0x7FFF0000L ) >> 16 ) - 1; + FT_UInt psid = mm_var->namedstyle[instance].psid; + + char* ps_name = NULL; - if ( FT_STREAM_SEEK( name->stringOffset ) || - FT_STREAM_READ( result, len ) ) + /* try first to load the name string with index `postScriptNameID' */ + if ( psid == 6 || + ( psid > 255 && psid < 32768 ) ) + (void)sfnt->get_name( face, (FT_UShort)psid, &ps_name ); + + if ( ps_name ) + { + result = ps_name; + p = result + ft_strlen( result ) + 1; + + goto check_length; + } + else + { + /* otherwise construct a name using `subfamilyNameID' */ + FT_UInt strid = mm_var->namedstyle[instance].strid; + + char* subfamily_name; + char* s; + + + (void)sfnt->get_name( face, (FT_UShort)strid, &subfamily_name ); + + if ( !subfamily_name ) { - name->stringOffset = 0; - name->stringLength = 0; - FT_FREE( name->string ); - FT_FREE( result ); - goto Exit; + FT_TRACE1(( "sfnt_get_var_ps_name:" + " can't construct named instance PS name;\n" + " " + " trying to construct normal instance PS name\n" )); + goto construct_instance_name; } - ((char*)result)[len] = '\0'; + + /* after the prefix we have character `-' followed by the */ + /* subfamily name (using only characters a-z, A-Z, and 0-9) */ + if ( FT_ALLOC( result, face->var_postscript_prefix_len + + 1 + ft_strlen( subfamily_name ) + 1 ) ) + return NULL; + + ft_strcpy( result, face->var_postscript_prefix ); + + p = result + face->var_postscript_prefix_len; + *p++ = '-'; + + s = subfamily_name; + while ( *s ) + { + if ( ft_isalnum( *s ) ) + *p++ = *s; + s++; + } + *p++ = '\0'; + + FT_FREE( subfamily_name ); + } + } + else + { + FT_Var_Axis* axis; + + + construct_instance_name: + axis = mm_var->axis; + + if ( FT_ALLOC( result, + face->var_postscript_prefix_len + + num_coords * MAX_VALUE_DESCRIPTOR_LEN + 1 ) ) + return NULL; + + p = result; + + ft_strcpy( p, face->var_postscript_prefix ); + p += face->var_postscript_prefix_len; + + for ( i = 0; i < num_coords; i++, coords++, axis++ ) + { + char t; + + + /* omit axis value descriptor if it is identical */ + /* to the default axis value */ + if ( *coords == axis->def ) + continue; + + *p++ = '_'; + p = fixed2float( *coords, p ); + + t = (char)( axis->tag >> 24 ); + if ( t != ' ' && ft_isalnum( t ) ) + *p++ = t; + t = (char)( axis->tag >> 16 ); + if ( t != ' ' && ft_isalnum( t ) ) + *p++ = t; + t = (char)( axis->tag >> 8 ); + if ( t != ' ' && ft_isalnum( t ) ) + *p++ = t; + t = (char)axis->tag; + if ( t != ' ' && ft_isalnum( t ) ) + *p++ = t; } } - Exit: + check_length: + if ( p - result > MAX_PS_NAME_LEN ) + { + /* the PS name is too long; replace the part after the prefix with */ + /* a checksum; we use MurmurHash 3 with a hash length of 128 bit */ + + FT_UInt32 seed = 123456789; + + FT_UInt32 hash[4]; + FT_UInt32* h; + + + murmur_hash_3_128( result, p - result, seed, hash ); + + p = result + face->var_postscript_prefix_len; + *p++ = '-'; + + /* we convert the hash value to hex digits from back to front */ + p += 32 + 3; + h = hash + 3; + + *p-- = '\0'; + *p-- = '.'; + *p-- = '.'; + *p-- = '.'; + + for ( i = 0; i < 4; i++, h-- ) + { + FT_UInt32 v = *h; + + + for ( j = 0; j < 8; j++ ) + { + *p-- = hexdigits[v & 0xF]; + v >>= 4; + } + } + } + + return result; + } + +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + + + static const char* + sfnt_get_ps_name( TT_Face face ) + { + FT_Int found, win, apple; + const char* result = NULL; + + + if ( face->postscript_name ) + return face->postscript_name; + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + if ( face->blend && + ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) || + FT_IS_VARIATION( FT_FACE( face ) ) ) ) + { + face->postscript_name = sfnt_get_var_ps_name( face ); + return face->postscript_name; + } +#endif + + /* scan the name table to see whether we have a Postscript name here, */ + /* either in Macintosh or Windows platform encodings */ + found = sfnt_get_name_id( face, TT_NAME_ID_PS_NAME, &win, &apple ); + if ( !found ) + return NULL; + + /* prefer Windows entries over Apple */ + if ( win != -1 ) + result = get_win_string( face->root.memory, + face->name_table.stream, + face->name_table.names + win, + sfnt_is_postscript, + 1 ); + else + result = get_apple_string( face->root.memory, + face->name_table.stream, + face->name_table.names + apple, + sfnt_is_postscript, + 1 ); + face->postscript_name = result; + return result; } FT_DEFINE_SERVICE_PSFONTNAMEREC( sfnt_service_ps_name, - (FT_PsName_GetFunc)sfnt_get_ps_name ) + + (FT_PsName_GetFunc)sfnt_get_ps_name /* get_ps_font_name */ + ) /* @@ -338,7 +1077,9 @@ */ FT_DEFINE_SERVICE_TTCMAPSREC( tt_service_get_cmap_info, - (TT_CMap_Info_GetFunc)tt_get_cmap_info ) + + (TT_CMap_Info_GetFunc)tt_get_cmap_info /* get_cmap_info */ + ) #ifdef TT_CONFIG_OPTION_BDF @@ -381,8 +1122,10 @@ FT_DEFINE_SERVICE_BDFRec( sfnt_service_bdf, - (FT_BDF_GetCharsetIdFunc)sfnt_get_charset_id, - (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop ) + + (FT_BDF_GetCharsetIdFunc)sfnt_get_charset_id, /* get_charset_id */ + (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop /* get_property */ + ) #endif /* TT_CONFIG_OPTION_BDF */ @@ -395,6 +1138,7 @@ #if defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES && defined TT_CONFIG_OPTION_BDF FT_DEFINE_SERVICEDESCREC5( sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET, FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET, FT_SERVICE_ID_GLYPH_DICT, &SFNT_SERVICE_GLYPH_DICT_GET, @@ -403,6 +1147,7 @@ #elif defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES FT_DEFINE_SERVICEDESCREC4( sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET, FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET, FT_SERVICE_ID_GLYPH_DICT, &SFNT_SERVICE_GLYPH_DICT_GET, @@ -410,6 +1155,7 @@ #elif defined TT_CONFIG_OPTION_BDF FT_DEFINE_SERVICEDESCREC4( sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET, FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET, FT_SERVICE_ID_BDF, &SFNT_SERVICE_BDF_GET, @@ -417,6 +1163,7 @@ #else FT_DEFINE_SERVICEDESCREC3( sfnt_services, + FT_SERVICE_ID_SFNT_TABLE, &SFNT_SERVICE_SFNT_TABLE_GET, FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &SFNT_SERVICE_PS_NAME_GET, FT_SERVICE_ID_TT_CMAP, &TT_SERVICE_CMAP_INFO_GET ) @@ -459,55 +1206,64 @@ FT_DEFINE_SFNT_INTERFACE( sfnt_interface, - tt_face_goto_table, - sfnt_init_face, - sfnt_load_face, - sfnt_done_face, - sfnt_get_interface, + tt_face_goto_table, /* TT_Loader_GotoTableFunc goto_table */ - tt_face_load_any, + sfnt_init_face, /* TT_Init_Face_Func init_face */ + sfnt_load_face, /* TT_Load_Face_Func load_face */ + sfnt_done_face, /* TT_Done_Face_Func done_face */ + sfnt_get_interface, /* FT_Module_Requester get_interface */ - tt_face_load_head, - tt_face_load_hhea, - tt_face_load_cmap, - tt_face_load_maxp, - tt_face_load_os2, - tt_face_load_post, + tt_face_load_any, /* TT_Load_Any_Func load_any */ - tt_face_load_name, - tt_face_free_name, + tt_face_load_head, /* TT_Load_Table_Func load_head */ + tt_face_load_hhea, /* TT_Load_Metrics_Func load_hhea */ + tt_face_load_cmap, /* TT_Load_Table_Func load_cmap */ + tt_face_load_maxp, /* TT_Load_Table_Func load_maxp */ + tt_face_load_os2, /* TT_Load_Table_Func load_os2 */ + tt_face_load_post, /* TT_Load_Table_Func load_post */ - tt_face_load_kern, - tt_face_load_gasp, - tt_face_load_pclt, + tt_face_load_name, /* TT_Load_Table_Func load_name */ + tt_face_free_name, /* TT_Free_Table_Func free_name */ + + tt_face_load_kern, /* TT_Load_Table_Func load_kern */ + tt_face_load_gasp, /* TT_Load_Table_Func load_gasp */ + tt_face_load_pclt, /* TT_Load_Table_Func load_init */ /* see `ttload.h' */ PUT_EMBEDDED_BITMAPS( tt_face_load_bhed ), - + /* TT_Load_Table_Func load_bhed */ PUT_EMBEDDED_BITMAPS( tt_face_load_sbit_image ), + /* TT_Load_SBit_Image_Func load_sbit_image */ /* see `ttpost.h' */ PUT_PS_NAMES( tt_face_get_ps_name ), + /* TT_Get_PS_Name_Func get_psname */ PUT_PS_NAMES( tt_face_free_ps_names ), + /* TT_Free_Table_Func free_psnames */ /* since version 2.1.8 */ - tt_face_get_kerning, + tt_face_get_kerning, /* TT_Face_GetKerningFunc get_kerning */ /* since version 2.2 */ - tt_face_load_font_dir, - tt_face_load_hmtx, + tt_face_load_font_dir, /* TT_Load_Table_Func load_font_dir */ + tt_face_load_hmtx, /* TT_Load_Metrics_Func load_hmtx */ /* see `ttsbit.h' and `sfnt.h' */ PUT_EMBEDDED_BITMAPS( tt_face_load_sbit ), + /* TT_Load_Table_Func load_eblc */ PUT_EMBEDDED_BITMAPS( tt_face_free_sbit ), + /* TT_Free_Table_Func free_eblc */ PUT_EMBEDDED_BITMAPS( tt_face_set_sbit_strike ), + /* TT_Set_SBit_Strike_Func set_sbit_strike */ PUT_EMBEDDED_BITMAPS( tt_face_load_strike_metrics ), + /* TT_Load_Strike_Metrics_Func load_strike_metrics */ - tt_face_get_metrics, + tt_face_get_metrics, /* TT_Get_Metrics_Func get_metrics */ - tt_face_get_name + tt_face_get_name, /* TT_Get_Name_Func get_name */ + sfnt_get_name_id /* TT_Get_Name_ID_Func get_name_id */ ) @@ -523,9 +1279,10 @@ (const void*)&SFNT_INTERFACE_GET, /* module specific interface */ - (FT_Module_Constructor)0, - (FT_Module_Destructor) 0, - (FT_Module_Requester) sfnt_get_interface ) + (FT_Module_Constructor)NULL, /* module_init */ + (FT_Module_Destructor) NULL, /* module_done */ + (FT_Module_Requester) sfnt_get_interface /* get_interface */ + ) /* END */ diff --git a/src/3rdparty/freetype/src/sfnt/sfdriver.h b/src/3rdparty/freetype/src/sfnt/sfdriver.h index 944119cc22..81c22d2887 100644 --- a/src/3rdparty/freetype/src/sfnt/sfdriver.h +++ b/src/3rdparty/freetype/src/sfnt/sfdriver.h @@ -4,7 +4,7 @@ /* */ /* High-level SFNT driver interface (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SFDRIVER_H__ -#define __SFDRIVER_H__ +#ifndef SFDRIVER_H_ +#define SFDRIVER_H_ #include <ft2build.h> @@ -32,7 +32,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SFDRIVER_H__ */ +#endif /* SFDRIVER_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/sfnt/sferrors.h b/src/3rdparty/freetype/src/sfnt/sferrors.h index e3bef3f743..74003d4b38 100644 --- a/src/3rdparty/freetype/src/sfnt/sferrors.h +++ b/src/3rdparty/freetype/src/sfnt/sferrors.h @@ -4,7 +4,7 @@ /* */ /* SFNT error codes (specification only). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __SFERRORS_H__ -#define __SFERRORS_H__ +#ifndef SFERRORS_H_ +#define SFERRORS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX SFNT_Err_ @@ -35,6 +35,7 @@ #include FT_ERRORS_H -#endif /* __SFERRORS_H__ */ +#endif /* SFERRORS_H_ */ + /* END */ diff --git a/src/3rdparty/freetype/src/sfnt/sfnt.c b/src/3rdparty/freetype/src/sfnt/sfnt.c index 0b8b5f4578..8b9a6b345d 100644 --- a/src/3rdparty/freetype/src/sfnt/sfnt.c +++ b/src/3rdparty/freetype/src/sfnt/sfnt.c @@ -4,7 +4,7 @@ /* */ /* Single object library component. */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,27 +17,19 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT - #include <ft2build.h> + +#include "pngshim.c" +#include "sfdriver.c" #include "sfntpic.c" -#include "ttload.c" -#include "ttmtx.c" +#include "sfobjs.c" +#include "ttbdf.c" #include "ttcmap.c" #include "ttkern.c" -#include "sfobjs.c" -#include "sfdriver.c" - -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS -#include "pngshim.c" -#include "ttsbit.c" -#endif - -#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES +#include "ttload.c" +#include "ttmtx.c" #include "ttpost.c" -#endif +#include "ttsbit.c" -#ifdef TT_CONFIG_OPTION_BDF -#include "ttbdf.c" -#endif /* END */ diff --git a/src/3rdparty/freetype/src/sfnt/sfntpic.c b/src/3rdparty/freetype/src/sfnt/sfntpic.c index 2aaf4bcc40..db2d816ce6 100644 --- a/src/3rdparty/freetype/src/sfnt/sfntpic.c +++ b/src/3rdparty/freetype/src/sfnt/sfntpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for sfnt module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2018 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/src/sfnt/sfntpic.h b/src/3rdparty/freetype/src/sfnt/sfntpic.h index d99be6a824..8f43122d81 100644 --- a/src/3rdparty/freetype/src/sfnt/sfntpic.h +++ b/src/3rdparty/freetype/src/sfnt/sfntpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for sfnt module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2018 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SFNTPIC_H__ -#define __SFNTPIC_H__ +#ifndef SFNTPIC_H_ +#define SFNTPIC_H_ #include FT_INTERNAL_PIC_H @@ -106,7 +106,7 @@ FT_END_HEADER /* */ -#endif /* __SFNTPIC_H__ */ +#endif /* SFNTPIC_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/sfnt/sfobjs.c b/src/3rdparty/freetype/src/sfnt/sfobjs.c index 14d3adef21..6ba8509f56 100644 --- a/src/3rdparty/freetype/src/sfnt/sfobjs.c +++ b/src/3rdparty/freetype/src/sfnt/sfobjs.c @@ -4,7 +4,7 @@ /* */ /* SFNT object management (base). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -28,6 +28,12 @@ #include FT_SERVICE_POSTSCRIPT_CMAPS_H #include FT_SFNT_NAMES_H #include FT_GZIP_H + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include FT_SERVICE_MULTIPLE_MASTERS_H +#include FT_SERVICE_METRICS_VARIATIONS_H +#endif + #include "sferrors.h" #ifdef TT_CONFIG_OPTION_BDF @@ -48,8 +54,8 @@ /* convert a UTF-16 name entry to ASCII */ static FT_String* - tt_name_entry_ascii_from_utf16( TT_NameEntry entry, - FT_Memory memory ) + tt_name_ascii_from_utf16( TT_Name entry, + FT_Memory memory ) { FT_String* string = NULL; FT_UInt len, code, n; @@ -83,8 +89,8 @@ /* convert an Apple Roman or symbol name entry to ASCII */ static FT_String* - tt_name_entry_ascii_from_other( TT_NameEntry entry, - FT_Memory memory ) + tt_name_ascii_from_other( TT_Name entry, + FT_Memory memory ) { FT_String* string = NULL; FT_UInt len, code, n; @@ -116,8 +122,8 @@ } - typedef FT_String* (*TT_NameEntry_ConvertFunc)( TT_NameEntry entry, - FT_Memory memory ); + typedef FT_String* (*TT_Name_ConvertFunc)( TT_Name entry, + FT_Memory memory ); /* documentation is in sfnt.h */ @@ -127,20 +133,21 @@ FT_UShort nameid, FT_String** name ) { - FT_Memory memory = face->root.memory; - FT_Error error = FT_Err_Ok; - FT_String* result = NULL; - FT_UShort n; - TT_NameEntryRec* rec; - FT_Int found_apple = -1; - FT_Int found_apple_roman = -1; - FT_Int found_apple_english = -1; - FT_Int found_win = -1; - FT_Int found_unicode = -1; + FT_Memory memory = face->root.memory; + FT_Error error = FT_Err_Ok; + FT_String* result = NULL; + FT_UShort n; + TT_Name rec; - FT_Bool is_english = 0; + FT_Int found_apple = -1; + FT_Int found_apple_roman = -1; + FT_Int found_apple_english = -1; + FT_Int found_win = -1; + FT_Int found_unicode = -1; - TT_NameEntry_ConvertFunc convert; + FT_Bool is_english = 0; + + TT_Name_ConvertFunc convert; FT_ASSERT( name ); @@ -225,7 +232,7 @@ /* all Unicode strings are encoded using UTF-16BE */ case TT_MS_ID_UNICODE_CS: case TT_MS_ID_SYMBOL_CS: - convert = tt_name_entry_ascii_from_utf16; + convert = tt_name_ascii_from_utf16; break; case TT_MS_ID_UCS_4: @@ -234,7 +241,7 @@ /* MsGothic font shipped with Windows Vista shows that this really */ /* means UTF-16 encoded names (UCS-4 values are only used within */ /* charmaps). */ - convert = tt_name_entry_ascii_from_utf16; + convert = tt_name_ascii_from_utf16; break; default: @@ -244,17 +251,17 @@ else if ( found_apple >= 0 ) { rec = face->name_table.names + found_apple; - convert = tt_name_entry_ascii_from_other; + convert = tt_name_ascii_from_other; } else if ( found_unicode >= 0 ) { rec = face->name_table.names + found_unicode; - convert = tt_name_entry_ascii_from_utf16; + convert = tt_name_ascii_from_utf16; } if ( rec && convert ) { - if ( rec->string == NULL ) + if ( !rec->string ) { FT_Stream stream = face->name_table.stream; @@ -304,7 +311,7 @@ { TT_PLATFORM_MICROSOFT, TT_MS_ID_UCS_4, FT_ENCODING_UNICODE }, { TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, FT_ENCODING_UNICODE }, { TT_PLATFORM_MICROSOFT, TT_MS_ID_SJIS, FT_ENCODING_SJIS }, - { TT_PLATFORM_MICROSOFT, TT_MS_ID_GB2312, FT_ENCODING_GB2312 }, + { TT_PLATFORM_MICROSOFT, TT_MS_ID_PRC, FT_ENCODING_PRC }, { TT_PLATFORM_MICROSOFT, TT_MS_ID_BIG_5, FT_ENCODING_BIG5 }, { TT_PLATFORM_MICROSOFT, TT_MS_ID_WANSUNG, FT_ENCODING_WANSUNG }, { TT_PLATFORM_MICROSOFT, TT_MS_ID_JOHAB, FT_ENCODING_JOHAB } @@ -451,10 +458,14 @@ woff.metaOrigLength != 0 ) ) || ( woff.metaLength != 0 && woff.metaOrigLength == 0 ) || ( woff.privOffset == 0 && woff.privLength != 0 ) ) + { + FT_ERROR(( "woff_font_open: invalid WOFF header\n" )); return FT_THROW( Invalid_Table ); + } - if ( FT_ALLOC( sfnt, woff.totalSfntSize ) || - FT_NEW( sfnt_stream ) ) + /* Don't trust `totalSfntSize' before thorough checks. */ + if ( FT_ALLOC( sfnt, 12 + woff.num_tables * 16UL ) || + FT_NEW( sfnt_stream ) ) goto Exit; sfnt_header = sfnt; @@ -521,6 +532,8 @@ if ( table->Tag <= old_tag ) { FT_FRAME_EXIT(); + + FT_ERROR(( "woff_font_open: table tags are not sorted\n" )); error = FT_THROW( Invalid_Table ); goto Exit; } @@ -555,6 +568,7 @@ sfnt_offset > woff.totalSfntSize - table->OrigLength || table->CompLength > table->OrigLength ) { + FT_ERROR(( "woff_font_open: invalid table offsets\n" )); error = FT_THROW( Invalid_Table ); goto Exit; } @@ -580,6 +594,8 @@ if ( woff.metaOffset != woff_offset || woff.metaOffset + woff.metaLength > woff.length ) { + FT_ERROR(( "woff_font_open:" + " invalid `metadata' offset or length\n" )); error = FT_THROW( Invalid_Table ); goto Exit; } @@ -596,6 +612,7 @@ if ( woff.privOffset != woff_offset || woff.privOffset + woff.privLength > woff.length ) { + FT_ERROR(( "woff_font_open: invalid `private' offset or length\n" )); error = FT_THROW( Invalid_Table ); goto Exit; } @@ -607,10 +624,19 @@ if ( sfnt_offset != woff.totalSfntSize || woff_offset != woff.length ) { + FT_ERROR(( "woff_font_open: invalid `sfnt' table structure\n" )); error = FT_THROW( Invalid_Table ); goto Exit; } + /* Now use `totalSfntSize'. */ + if ( FT_REALLOC( sfnt, + 12 + woff.num_tables * 16UL, + woff.totalSfntSize ) ) + goto Exit; + + sfnt_header = sfnt + 12; + /* Write the tables. */ for ( nn = 0; nn < woff.num_tables; nn++ ) @@ -651,6 +677,7 @@ goto Exit; if ( output_len != table->OrigLength ) { + FT_ERROR(( "woff_font_open: compressed table length mismatch\n" )); error = FT_THROW( Invalid_Table ); goto Exit; } @@ -760,6 +787,8 @@ tag != TTAG_OTTO && tag != TTAG_true && tag != TTAG_typ1 && + tag != TTAG_0xA5kbd && + tag != TTAG_0xA5lst && tag != 0x00020000UL ) { FT_TRACE2(( " not a font using the SFNT container format\n" )); @@ -778,6 +807,9 @@ if ( FT_STREAM_READ_FIELDS( ttc_header_fields, &face->ttc_header ) ) return error; + FT_TRACE3(( " with %ld subfonts\n", + face->ttc_header.count )); + if ( face->ttc_header.count == 0 ) return FT_THROW( Invalid_Table ); @@ -852,6 +884,31 @@ FT_FACE_FIND_GLOBAL_SERVICE( face, face->psnames, POSTSCRIPT_CMAPS ); +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + if ( !face->mm ) + { + /* we want the MM interface from the `truetype' module only */ + FT_Module tt_module = FT_Get_Module( library, "truetype" ); + + + face->mm = ft_module_get_service( tt_module, + FT_SERVICE_ID_MULTI_MASTERS, + 0 ); + } + + if ( !face->var ) + { + /* we want the metrics variations interface */ + /* from the `truetype' module only */ + FT_Module tt_module = FT_Get_Module( library, "truetype" ); + + + face->var = ft_module_get_service( tt_module, + FT_SERVICE_ID_METRICS_VARIATIONS, + 0 ); + } +#endif + FT_TRACE2(( "SFNT driver\n" )); error = sfnt_open_font( stream, face ); @@ -861,10 +918,14 @@ /* Stream may have changed in sfnt_open_font. */ stream = face->root.stream; - FT_TRACE2(( "sfnt_init_face: %08p, %ld\n", face, face_instance_index )); + FT_TRACE2(( "sfnt_init_face: %08p, %d\n", face, face_instance_index )); face_index = FT_ABS( face_instance_index ) & 0xFFFF; + /* value -(N+1) requests information on index N */ + if ( face_instance_index < 0 ) + face_index--; + if ( face_index >= face->ttc_header.count ) { if ( face_instance_index >= 0 ) @@ -883,9 +944,22 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT { - FT_ULong fvar_len; + FT_Memory memory = face->root.memory; + + FT_ULong fvar_len; + + FT_ULong version; + FT_ULong offset; + + FT_UShort num_axes; + FT_UShort axis_size; FT_UShort num_instances; - FT_Int instance_index; + FT_UShort instance_size; + + FT_Int instance_index; + + FT_Byte* default_values = NULL; + FT_Byte* instance_values = NULL; instance_index = FT_ABS( face_instance_index ) >> 16; @@ -893,19 +967,106 @@ /* test whether current face is a GX font with named instances */ if ( face->goto_table( face, TTAG_fvar, stream, &fvar_len ) || fvar_len < 20 || - FT_STREAM_SKIP( 12 ) || - FT_READ_USHORT( num_instances ) ) - num_instances = 0; - - /* we support at most 2^15 - 1 instances */ - if ( num_instances >= ( 1U << 15 ) - 1 ) + FT_READ_ULONG( version ) || + FT_READ_USHORT( offset ) || + FT_STREAM_SKIP( 2 ) /* reserved */ || + FT_READ_USHORT( num_axes ) || + FT_READ_USHORT( axis_size ) || + FT_READ_USHORT( num_instances ) || + FT_READ_USHORT( instance_size ) ) { - if ( face_instance_index >= 0 ) - return FT_THROW( Invalid_Argument ); - else - num_instances = 0; + version = 0; + offset = 0; + num_axes = 0; + axis_size = 0; + num_instances = 0; + instance_size = 0; } + /* check that the data is bound by the table length */ + if ( version != 0x00010000UL || + axis_size != 20 || + num_axes == 0 || + /* `num_axes' limit implied by 16-bit `instance_size' */ + num_axes > 0x3FFE || + !( instance_size == 4 + 4 * num_axes || + instance_size == 6 + 4 * num_axes ) || + /* `num_instances' limit implied by limited range of name IDs */ + num_instances > 0x7EFF || + offset + + axis_size * num_axes + + instance_size * num_instances > fvar_len ) + num_instances = 0; + else + face->variation_support |= TT_FACE_FLAG_VAR_FVAR; + + /* + * As documented in the OpenType specification, an entry for the + * default instance may be omitted in the named instance table. In + * particular this means that even if there is no named instance + * table in the font we actually do have a named instance, namely the + * default instance. + * + * For consistency, we always want the default instance in our list + * of named instances. If it is missing, we try to synthesize it + * later on. Here, we have to adjust `num_instances' accordingly. + */ + + if ( ( face->variation_support & TT_FACE_FLAG_VAR_FVAR ) && + !( FT_ALLOC( default_values, num_axes * 4 ) || + FT_ALLOC( instance_values, num_axes * 4 ) ) ) + { + /* the current stream position is 16 bytes after the table start */ + FT_ULong array_start = FT_STREAM_POS() - 16 + offset; + FT_ULong default_value_offset, instance_offset; + + FT_Byte* p; + FT_UInt i; + + + default_value_offset = array_start + 8; + p = default_values; + + for ( i = 0; i < num_axes; i++ ) + { + (void)FT_STREAM_READ_AT( default_value_offset, p, 4 ); + + default_value_offset += axis_size; + p += 4; + } + + instance_offset = array_start + axis_size * num_axes + 4; + + for ( i = 0; i < num_instances; i++ ) + { + (void)FT_STREAM_READ_AT( instance_offset, + instance_values, + num_axes * 4 ); + + if ( !ft_memcmp( default_values, instance_values, num_axes * 4 ) ) + break; + + instance_offset += instance_size; + } + + if ( i == num_instances ) + { + /* no default instance in named instance table; */ + /* we thus have to synthesize it */ + num_instances++; + } + } + + FT_FREE( default_values ); + FT_FREE( instance_values ); + + /* we don't support Multiple Master CFFs yet; */ + /* note that `glyf' or `CFF2' have precedence */ + if ( face->goto_table( face, TTAG_glyf, stream, 0 ) && + face->goto_table( face, TTAG_CFF2, stream, 0 ) && + !face->goto_table( face, TTAG_CFF, stream, 0 ) ) + num_instances = 0; + /* instance indices in `face_instance_index' start with index 1, */ /* thus `>' and not `>=' */ if ( instance_index > num_instances ) @@ -921,7 +1082,7 @@ #endif face->root.num_faces = face->ttc_header.count; - face->root.face_index = face_index; + face->root.face_index = face_instance_index; return error; } @@ -983,8 +1144,10 @@ FT_Bool has_outline; FT_Bool is_apple_sbit; FT_Bool is_apple_sbix; - FT_Bool ignore_preferred_family = FALSE; - FT_Bool ignore_preferred_subfamily = FALSE; + FT_Bool has_CBLC; + FT_Bool has_CBDT; + FT_Bool ignore_typographic_family = FALSE; + FT_Bool ignore_typographic_subfamily = FALSE; SFNT_Service sfnt = (SFNT_Service)face->sfnt; @@ -999,10 +1162,10 @@ for ( i = 0; i < num_params; i++ ) { - if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_FAMILY ) - ignore_preferred_family = TRUE; - else if ( params[i].tag == FT_PARAM_TAG_IGNORE_PREFERRED_SUBFAMILY ) - ignore_preferred_subfamily = TRUE; + if ( params[i].tag == FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_FAMILY ) + ignore_typographic_family = TRUE; + else if ( params[i].tag == FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_SUBFAMILY ) + ignore_typographic_subfamily = TRUE; } } @@ -1027,12 +1190,14 @@ /* do we have outlines in there? */ #ifdef FT_CONFIG_OPTION_INCREMENTAL - has_outline = FT_BOOL( face->root.internal->incremental_interface != 0 || - tt_face_lookup_table( face, TTAG_glyf ) != 0 || - tt_face_lookup_table( face, TTAG_CFF ) != 0 ); + has_outline = FT_BOOL( face->root.internal->incremental_interface || + tt_face_lookup_table( face, TTAG_glyf ) || + tt_face_lookup_table( face, TTAG_CFF ) || + tt_face_lookup_table( face, TTAG_CFF2 ) ); #else - has_outline = FT_BOOL( tt_face_lookup_table( face, TTAG_glyf ) != 0 || - tt_face_lookup_table( face, TTAG_CFF ) != 0 ); + has_outline = FT_BOOL( tt_face_lookup_table( face, TTAG_glyf ) || + tt_face_lookup_table( face, TTAG_CFF ) || + tt_face_lookup_table( face, TTAG_CFF2 ) ); #endif is_apple_sbit = 0; @@ -1061,7 +1226,17 @@ goto Exit; } - if ( face->header.Units_Per_EM == 0 ) + has_CBLC = !face->goto_table( face, TTAG_CBLC, stream, 0 ); + has_CBDT = !face->goto_table( face, TTAG_CBDT, stream, 0 ); + + /* Ignore outlines for CBLC/CBDT fonts. */ + if ( has_CBLC || has_CBDT ) + has_outline = FALSE; + + /* OpenType 1.8.2 introduced limits to this value; */ + /* however, they make sense for older SFNT fonts also */ + if ( face->header.Units_Per_EM < 16 || + face->header.Units_Per_EM > 16384 ) { error = FT_THROW( Invalid_Table ); @@ -1164,30 +1339,10 @@ /* embedded bitmap support */ if ( sfnt->load_eblc ) - { LOAD_( eblc ); - if ( error ) - { - /* a font which contains neither bitmaps nor outlines is */ - /* still valid (although rather useless in most cases); */ - /* however, you can find such stripped fonts in PDFs */ - if ( FT_ERR_EQ( error, Table_Missing ) ) - error = FT_Err_Ok; - else - goto Exit; - } - } + /* consider the pclt, kerning, and gasp tables as optional */ LOAD_( pclt ); - if ( error ) - { - if ( FT_ERR_NEQ( error, Table_Missing ) ) - goto Exit; - - face->pclt.Version = 0; - } - - /* consider the kerning and gasp tables as optional */ LOAD_( gasp ); LOAD_( kern ); @@ -1203,27 +1358,27 @@ face->root.style_name = NULL; if ( face->os2.version != 0xFFFFU && face->os2.fsSelection & 256 ) { - if ( !ignore_preferred_family ) - GET_NAME( PREFERRED_FAMILY, &face->root.family_name ); + if ( !ignore_typographic_family ) + GET_NAME( TYPOGRAPHIC_FAMILY, &face->root.family_name ); if ( !face->root.family_name ) GET_NAME( FONT_FAMILY, &face->root.family_name ); - if ( !ignore_preferred_subfamily ) - GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name ); + if ( !ignore_typographic_subfamily ) + GET_NAME( TYPOGRAPHIC_SUBFAMILY, &face->root.style_name ); if ( !face->root.style_name ) GET_NAME( FONT_SUBFAMILY, &face->root.style_name ); } else { GET_NAME( WWS_FAMILY, &face->root.family_name ); - if ( !face->root.family_name && !ignore_preferred_family ) - GET_NAME( PREFERRED_FAMILY, &face->root.family_name ); + if ( !face->root.family_name && !ignore_typographic_family ) + GET_NAME( TYPOGRAPHIC_FAMILY, &face->root.family_name ); if ( !face->root.family_name ) GET_NAME( FONT_FAMILY, &face->root.family_name ); GET_NAME( WWS_SUBFAMILY, &face->root.style_name ); - if ( !face->root.style_name && !ignore_preferred_subfamily ) - GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name ); + if ( !face->root.style_name && !ignore_typographic_subfamily ) + GET_NAME( TYPOGRAPHIC_SUBFAMILY, &face->root.style_name ); if ( !face->root.style_name ) GET_NAME( FONT_SUBFAMILY, &face->root.style_name ); } @@ -1271,10 +1426,14 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT /* Don't bother to load the tables unless somebody asks for them. */ /* No need to do work which will (probably) not be used. */ - if ( tt_face_lookup_table( face, TTAG_glyf ) != 0 && - tt_face_lookup_table( face, TTAG_fvar ) != 0 && - tt_face_lookup_table( face, TTAG_gvar ) != 0 ) - flags |= FT_FACE_FLAG_MULTIPLE_MASTERS; + if ( face->variation_support & TT_FACE_FLAG_VAR_FVAR ) + { + if ( tt_face_lookup_table( face, TTAG_glyf ) != 0 && + tt_face_lookup_table( face, TTAG_gvar ) != 0 ) + flags |= FT_FACE_FLAG_MULTIPLE_MASTERS; + if ( tt_face_lookup_table( face, TTAG_CFF2 ) != 0 ) + flags |= FT_FACE_FLAG_MULTIPLE_MASTERS; + } #endif root->face_flags = flags; @@ -1317,7 +1476,8 @@ /* Polish the charmaps. */ /* */ /* Try to set the charmap encoding according to the platform & */ - /* encoding ID of each charmap. */ + /* encoding ID of each charmap. Emulate Unicode charmap if one */ + /* is missing. */ /* */ tt_face_build_cmaps( face ); /* ignore errors */ @@ -1325,7 +1485,10 @@ /* set the encoding fields */ { - FT_Int m; + FT_Int m; +#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES + FT_Bool has_unicode = FALSE; +#endif for ( m = 0; m < root->num_charmaps; m++ ) @@ -1336,14 +1499,34 @@ charmap->encoding = sfnt_find_encoding( charmap->platform_id, charmap->encoding_id ); -#if 0 - if ( root->charmap == NULL && - charmap->encoding == FT_ENCODING_UNICODE ) - { - /* set 'root->charmap' to the first Unicode encoding we find */ - root->charmap = charmap; - } -#endif +#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES + + if ( charmap->encoding == FT_ENCODING_UNICODE || + charmap->encoding == FT_ENCODING_MS_SYMBOL ) /* PUA */ + has_unicode = TRUE; + } + + /* synthesize Unicode charmap if one is missing */ + if ( !has_unicode ) + { + FT_CharMapRec cmaprec; + + + cmaprec.face = root; + cmaprec.platform_id = TT_PLATFORM_MICROSOFT; + cmaprec.encoding_id = TT_MS_ID_UNICODE_CS; + cmaprec.encoding = FT_ENCODING_UNICODE; + + + error = FT_CMap_New( (FT_CMap_Class)&tt_cmap_unicode_class_rec, + NULL, &cmaprec, NULL ); + if ( error && + FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) ) + goto Exit; + error = FT_Err_Ok; + +#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ + } } @@ -1355,7 +1538,7 @@ * depths in the FT_Bitmap_Size record. This is a design error. */ { - FT_UInt i, count; + FT_UInt count; count = face->sbit_num_strikes; @@ -1367,6 +1550,9 @@ FT_Short avgwidth = face->os2.xAvgCharWidth; FT_Size_Metrics metrics; + FT_UInt* sbit_strike_map = NULL; + FT_UInt strike_idx, bsize_idx; + if ( em_size == 0 || face->os2.version == 0xFFFFU ) { @@ -1374,31 +1560,50 @@ em_size = 1; } - if ( FT_NEW_ARRAY( root->available_sizes, count ) ) + /* to avoid invalid strike data in the `available_sizes' field */ + /* of `FT_Face', we map `available_sizes' indices to strike */ + /* indices */ + if ( FT_NEW_ARRAY( root->available_sizes, count ) || + FT_NEW_ARRAY( sbit_strike_map, count ) ) goto Exit; - for ( i = 0; i < count; i++ ) + bsize_idx = 0; + for ( strike_idx = 0; strike_idx < count; strike_idx++ ) { - FT_Bitmap_Size* bsize = root->available_sizes + i; + FT_Bitmap_Size* bsize = root->available_sizes + bsize_idx; - error = sfnt->load_strike_metrics( face, i, &metrics ); + error = sfnt->load_strike_metrics( face, strike_idx, &metrics ); if ( error ) - goto Exit; + continue; bsize->height = (FT_Short)( metrics.height >> 6 ); - bsize->width = (FT_Short)( - ( avgwidth * metrics.x_ppem + em_size / 2 ) / em_size ); + bsize->width = (FT_Short)( + ( avgwidth * metrics.x_ppem + em_size / 2 ) / em_size ); bsize->x_ppem = metrics.x_ppem << 6; bsize->y_ppem = metrics.y_ppem << 6; /* assume 72dpi */ bsize->size = metrics.y_ppem << 6; + + /* only use strikes with valid PPEM values */ + if ( bsize->x_ppem && bsize->y_ppem ) + sbit_strike_map[bsize_idx++] = strike_idx; } - root->face_flags |= FT_FACE_FLAG_FIXED_SIZES; - root->num_fixed_sizes = (FT_Int)count; + /* reduce array size to the actually used elements */ + (void)FT_RENEW_ARRAY( sbit_strike_map, count, bsize_idx ); + + /* from now on, all strike indices are mapped */ + /* using `sbit_strike_map' */ + if ( bsize_idx ) + { + face->sbit_strike_map = sbit_strike_map; + + root->face_flags |= FT_FACE_FLAG_FIXED_SIZES; + root->num_fixed_sizes = (FT_Int)bsize_idx; + } } } @@ -1488,9 +1693,9 @@ (FT_Short)( face->vertical_info ? face->vertical.advance_Height_Max : root->height ); - /* See http://www.microsoft.com/OpenType/OTSpec/post.htm -- */ - /* Adjust underline position from top edge to centre of */ - /* stroke to convert TrueType meaning to FreeType meaning. */ + /* See https://www.microsoft.com/typography/otspec/post.htm -- */ + /* Adjust underline position from top edge to centre of */ + /* stroke to convert TrueType meaning to FreeType meaning. */ root->underline_position = face->postscript.underlinePosition - face->postscript.underlineThickness / 2; root->underline_thickness = face->postscript.underlineThickness; @@ -1559,18 +1764,10 @@ face->cmap_size = 0; } - /* freeing the horizontal metrics */ - { - FT_Stream stream = FT_FACE_STREAM( face ); + face->horz_metrics_size = 0; + face->vert_metrics_size = 0; - - FT_FRAME_RELEASE( face->horz_metrics ); - FT_FRAME_RELEASE( face->vert_metrics ); - face->horz_metrics_size = 0; - face->vert_metrics_size = 0; - } - - /* freeing the vertical ones, if any */ + /* freeing vertical metrics, if any */ if ( face->vertical_info ) { FT_FREE( face->vertical.long_metrics ); @@ -1592,9 +1789,13 @@ /* freeing sbit size table */ FT_FREE( face->root.available_sizes ); + FT_FREE( face->sbit_strike_map ); face->root.num_fixed_sizes = 0; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT FT_FREE( face->postscript_name ); + FT_FREE( face->var_postscript_prefix ); +#endif face->sfnt = NULL; } diff --git a/src/3rdparty/freetype/src/sfnt/sfobjs.h b/src/3rdparty/freetype/src/sfnt/sfobjs.h index 455f86772f..1b8d1be5b1 100644 --- a/src/3rdparty/freetype/src/sfnt/sfobjs.h +++ b/src/3rdparty/freetype/src/sfnt/sfobjs.h @@ -4,7 +4,7 @@ /* */ /* SFNT object management (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __SFOBJS_H__ -#define __SFOBJS_H__ +#ifndef SFOBJS_H_ +#define SFOBJS_H_ #include <ft2build.h> @@ -53,7 +53,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __SFDRIVER_H__ */ +#endif /* SFDRIVER_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/sfnt/ttbdf.c b/src/3rdparty/freetype/src/sfnt/ttbdf.c index 098b781a14..534201f229 100644 --- a/src/3rdparty/freetype/src/sfnt/ttbdf.c +++ b/src/3rdparty/freetype/src/sfnt/ttbdf.c @@ -4,7 +4,7 @@ /* */ /* TrueType and OpenType embedded BDF properties (body). */ /* */ -/* Copyright 2005-2015 by */ +/* Copyright 2005-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -48,7 +48,7 @@ FT_Stream stream = FT_FACE(face)->stream; - if ( bdf->table != NULL ) + if ( bdf->table ) FT_FRAME_RELEASE( bdf->table ); bdf->table_end = NULL; @@ -165,7 +165,7 @@ error = FT_ERR( Invalid_Argument ); - if ( size == NULL || property_name == NULL ) + if ( !size || !property_name ) goto Exit; property_len = ft_strlen( property_name ); @@ -177,6 +177,7 @@ FT_UInt _ppem = FT_NEXT_USHORT( p ); FT_UInt _count = FT_NEXT_USHORT( p ); + if ( _ppem == size->metrics.y_ppem ) { count = _count; @@ -193,6 +194,7 @@ { FT_UInt type = FT_PEEK_USHORT( p + 4 ); + if ( ( type & 0x10 ) != 0 ) { FT_UInt32 name_offset = FT_PEEK_ULONG( p ); @@ -244,7 +246,12 @@ return error; } -#endif /* TT_CONFIG_OPTION_BDF */ +#else /* !TT_CONFIG_OPTION_BDF */ + + /* ANSI C doesn't like empty source files */ + typedef int _tt_bdf_dummy; + +#endif /* !TT_CONFIG_OPTION_BDF */ /* END */ diff --git a/src/3rdparty/freetype/src/sfnt/ttbdf.h b/src/3rdparty/freetype/src/sfnt/ttbdf.h index fe4ba489e8..809a663001 100644 --- a/src/3rdparty/freetype/src/sfnt/ttbdf.h +++ b/src/3rdparty/freetype/src/sfnt/ttbdf.h @@ -4,7 +4,7 @@ /* */ /* TrueType and OpenType embedded BDF properties (specification). */ /* */ -/* Copyright 2005-2015 by */ +/* Copyright 2005-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTBDF_H__ -#define __TTBDF_H__ +#ifndef TTBDF_H_ +#define TTBDF_H_ #include <ft2build.h> @@ -28,6 +28,8 @@ FT_BEGIN_HEADER +#ifdef TT_CONFIG_OPTION_BDF + FT_LOCAL( void ) tt_face_free_bdf_props( TT_Face face ); @@ -37,10 +39,12 @@ FT_BEGIN_HEADER const char* property_name, BDF_PropertyRec *aprop ); +#endif /* TT_CONFIG_OPTION_BDF */ + FT_END_HEADER -#endif /* __TTBDF_H__ */ +#endif /* TTBDF_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/sfnt/ttcmap.c b/src/3rdparty/freetype/src/sfnt/ttcmap.c index c4d9abdfe6..996e66485f 100644 --- a/src/3rdparty/freetype/src/sfnt/ttcmap.c +++ b/src/3rdparty/freetype/src/sfnt/ttcmap.c @@ -4,7 +4,7 @@ /* */ /* TrueType character mapping table (cmap) support (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,8 +23,10 @@ #include FT_INTERNAL_VALIDATE_H #include FT_INTERNAL_STREAM_H +#include FT_SERVICE_POSTSCRIPT_CMAPS_H #include "ttload.h" #include "ttcmap.h" +#include "ttpost.h" #include "sfntpic.h" @@ -180,22 +182,24 @@ FT_DEFINE_TT_CMAP( tt_cmap0_class_rec, - sizeof ( TT_CMapRec ), - (FT_CMap_InitFunc) tt_cmap_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap0_char_index, - (FT_CMap_CharNextFunc) tt_cmap0_char_next, + sizeof ( TT_CMapRec ), - NULL, - NULL, - NULL, - NULL, - NULL, + (FT_CMap_InitFunc) tt_cmap_init, /* init */ + (FT_CMap_DoneFunc) NULL, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap0_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap0_char_next, /* char_next */ + + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ 0, - (TT_CMap_ValidateFunc)tt_cmap0_validate, - (TT_CMap_Info_GetFunc)tt_cmap0_get_info ) + (TT_CMap_ValidateFunc)tt_cmap0_validate, /* validate */ + (TT_CMap_Info_GetFunc)tt_cmap0_get_info /* get_cmap_info */ + ) #endif /* TT_CONFIG_CMAP_FORMAT_0 */ @@ -218,10 +222,10 @@ /***** The following charmap lookup and iteration functions all *****/ /***** assume that the value `charcode' fulfills the following. *****/ /***** *****/ - /***** - For one byte characters, `charcode' is simply the *****/ + /***** - For one-byte characters, `charcode' is simply the *****/ /***** character code. *****/ /***** *****/ - /***** - For two byte characters, `charcode' is the 2-byte *****/ + /***** - For two-byte characters, `charcode' is the 2-byte *****/ /***** character code in big endian format. More precisely: *****/ /***** *****/ /***** (charcode >> 8) is the first byte value *****/ @@ -248,11 +252,11 @@ /* subs 518 SUBHEAD[NSUBS] sub-headers array */ /* glyph_ids 518+NSUB*8 USHORT[] glyph ID array */ /* */ - /* The `keys' table is used to map charcode high-bytes to sub-headers. */ + /* The `keys' table is used to map charcode high bytes to sub-headers. */ /* The value of `NSUBS' is the number of sub-headers defined in the */ /* table and is computed by finding the maximum of the `keys' table. */ /* */ - /* Note that for any n, `keys[n]' is a byte offset within the `subs' */ + /* Note that for any `n', `keys[n]' is a byte offset within the `subs' */ /* table, i.e., it is the corresponding sub-header index multiplied */ /* by 8. */ /* */ @@ -265,8 +269,8 @@ /* delta 4 SHORT see below */ /* offset 6 USHORT see below */ /* */ - /* A sub-header defines, for each high-byte, the range of valid */ - /* low-bytes within the charmap. Note that the range defined by `first' */ + /* A sub-header defines, for each high byte, the range of valid */ + /* low bytes within the charmap. Note that the range defined by `first' */ /* and `count' must be completely included in the interval [0..255] */ /* according to the specification. */ /* */ @@ -356,7 +360,7 @@ /* check range within 0..255 */ if ( valid->level >= FT_VALIDATE_PARANOID ) { - if ( first_code >= 256 || first_code + code_count > 256 ) + if ( first_code >= 256 || code_count > 256 - first_code ) FT_INVALID_DATA; } @@ -408,7 +412,7 @@ { FT_UInt char_lo = (FT_UInt)( char_code & 0xFF ); FT_UInt char_hi = (FT_UInt)( char_code >> 8 ); - FT_Byte* p = table + 6; /* keys table */ + FT_Byte* p = table + 6; /* keys table */ FT_Byte* subs = table + 518; /* subheaders table */ FT_Byte* sub; @@ -421,8 +425,8 @@ sub = subs; /* jump to first sub-header */ /* check that the sub-header for this byte is 0, which */ - /* indicates that it is really a valid one-byte value */ - /* Otherwise, return 0 */ + /* indicates that it is really a valid one-byte value; */ + /* otherwise, return 0 */ /* */ p += char_lo * 2; if ( TT_PEEK_USHORT( p ) != 0 ) @@ -441,6 +445,7 @@ if ( sub == subs ) goto Exit; } + result = sub; } @@ -513,8 +518,19 @@ FT_UInt pos, idx; + if ( char_lo >= start + count && charcode <= 0xFF ) + { + /* this happens only for a malformed cmap */ + charcode = 0x100; + continue; + } + if ( offset == 0 ) + { + if ( charcode == 0x100 ) + goto Exit; /* this happens only for a malformed cmap */ goto Next_SubHeader; + } if ( char_lo < start ) { @@ -541,11 +557,20 @@ } } } + + /* if unsuccessful, avoid `charcode' leaving */ + /* the current 256-character block */ + if ( count ) + charcode--; } - /* jump to next sub-header, i.e. higher byte value */ + /* If `charcode' is <= 0xFF, retry with `charcode + 1'. */ + /* Otherwise jump to the next 256-character block and retry. */ Next_SubHeader: - charcode = FT_PAD_FLOOR( charcode, 256 ) + 256; + if ( charcode <= 0xFF ) + charcode++; + else + charcode = FT_PAD_FLOOR( charcode, 0x100 ) + 0x100; } Exit: @@ -571,22 +596,24 @@ FT_DEFINE_TT_CMAP( tt_cmap2_class_rec, - sizeof ( TT_CMapRec ), - (FT_CMap_InitFunc) tt_cmap_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap2_char_index, - (FT_CMap_CharNextFunc) tt_cmap2_char_next, + sizeof ( TT_CMapRec ), - NULL, - NULL, - NULL, - NULL, - NULL, + (FT_CMap_InitFunc) tt_cmap_init, /* init */ + (FT_CMap_DoneFunc) NULL, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap2_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap2_char_next, /* char_next */ + + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ 2, - (TT_CMap_ValidateFunc)tt_cmap2_validate, - (TT_CMap_Info_GetFunc)tt_cmap2_get_info ) + (TT_CMap_ValidateFunc)tt_cmap2_validate, /* validate */ + (TT_CMap_Info_GetFunc)tt_cmap2_get_info /* get_cmap_info */ + ) #endif /* TT_CONFIG_CMAP_FORMAT_2 */ @@ -763,6 +790,9 @@ static void tt_cmap4_next( TT_CMap4 cmap ) { + TT_Face face = (TT_Face)cmap->cmap.cmap.charmap.face; + FT_Byte* limit = face->cmap_table + face->cmap_size; + FT_UInt charcode; @@ -774,7 +804,7 @@ if ( charcode < cmap->cur_start ) charcode = cmap->cur_start; - for ( ;; ) + for (;;) { FT_Byte* values = cmap->cur_values; FT_UInt end = cmap->cur_end; @@ -788,15 +818,19 @@ FT_Byte* p = values + 2 * ( charcode - cmap->cur_start ); + /* if p > limit, the whole segment is invalid */ + if ( p > limit ) + goto Next_Segment; + do { FT_UInt gindex = FT_NEXT_USHORT( p ); - if ( gindex != 0 ) + if ( gindex ) { gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU; - if ( gindex != 0 ) + if ( gindex ) { cmap->cur_charcode = charcode; cmap->cur_gindex = gindex; @@ -812,7 +846,26 @@ FT_UInt gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU; - if ( gindex != 0 ) + if ( gindex >= (FT_UInt)face->root.num_glyphs ) + { + /* we have an invalid glyph index; if there is an overflow, */ + /* we can adjust `charcode', otherwise the whole segment is */ + /* invalid */ + gindex = 0; + + if ( (FT_Int)charcode + delta < 0 && + (FT_Int)end + delta >= 0 ) + charcode = (FT_UInt)( -delta ); + + else if ( (FT_Int)charcode + delta < 0x10000L && + (FT_Int)end + delta >= 0x10000L ) + charcode = (FT_UInt)( 0x10000L - delta ); + + else + goto Next_Segment; + } + + if ( gindex ) { cmap->cur_charcode = charcode; cmap->cur_gindex = gindex; @@ -822,6 +875,7 @@ } } + Next_Segment: /* we need to find another range */ if ( tt_cmap4_set_range( cmap, cmap->cur_range + 1 ) < 0 ) break; @@ -1170,6 +1224,9 @@ FT_UInt32* pcharcode, FT_Bool next ) { + TT_Face face = (TT_Face)cmap->cmap.charmap.face; + FT_Byte* limit = face->cmap_table + face->cmap_size; + FT_UInt num_segs2, start, end, offset; FT_Int delta; FT_UInt max, min, mid, num_segs; @@ -1221,10 +1278,6 @@ if ( mid >= num_segs - 1 && start == 0xFFFFU && end == 0xFFFFU ) { - TT_Face face = (TT_Face)cmap->cmap.charmap.face; - FT_Byte* limit = face->cmap_table + face->cmap_size; - - if ( offset && p + offset + 2 > limit ) { delta = 1; @@ -1245,7 +1298,7 @@ mid = max + 1; /* search in segments before the current segment */ - for ( i = max ; i > 0; i-- ) + for ( i = max; i > 0; i-- ) { FT_UInt prev_end; FT_Byte* old_p; @@ -1347,13 +1400,40 @@ if ( offset ) { p += offset + ( charcode - start ) * 2; + + /* if p > limit, the whole segment is invalid */ + if ( next && p > limit ) + break; + gindex = TT_PEEK_USHORT( p ); - if ( gindex != 0 ) + if ( gindex ) + { gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU; + if ( gindex >= (FT_UInt)face->root.num_glyphs ) + gindex = 0; + } } else + { gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU; + if ( next && gindex >= (FT_UInt)face->root.num_glyphs ) + { + /* we have an invalid glyph index; if there is an overflow, */ + /* we can adjust `charcode', otherwise the whole segment is */ + /* invalid */ + gindex = 0; + + if ( (FT_Int)charcode + delta < 0 && + (FT_Int)end + delta >= 0 ) + charcode = (FT_UInt)( -delta ); + + else if ( (FT_Int)charcode + delta < 0x10000L && + (FT_Int)end + delta >= 0x10000L ) + charcode = (FT_UInt)( 0x10000L - delta ); + } + } + break; } } @@ -1463,21 +1543,24 @@ FT_DEFINE_TT_CMAP( tt_cmap4_class_rec, - sizeof ( TT_CMap4Rec ), - (FT_CMap_InitFunc) tt_cmap4_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap4_char_index, - (FT_CMap_CharNextFunc) tt_cmap4_char_next, - NULL, - NULL, - NULL, - NULL, - NULL, + sizeof ( TT_CMap4Rec ), + + (FT_CMap_InitFunc) tt_cmap4_init, /* init */ + (FT_CMap_DoneFunc) NULL, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap4_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap4_char_next, /* char_next */ + + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ 4, - (TT_CMap_ValidateFunc)tt_cmap4_validate, - (TT_CMap_Info_GetFunc)tt_cmap4_get_info ) + (TT_CMap_ValidateFunc)tt_cmap4_validate, /* validate */ + (TT_CMap_Info_GetFunc)tt_cmap4_get_info /* get_cmap_info */ + ) #endif /* TT_CONFIG_CMAP_FORMAT_4 */ @@ -1630,22 +1713,24 @@ FT_DEFINE_TT_CMAP( tt_cmap6_class_rec, - sizeof ( TT_CMapRec ), - (FT_CMap_InitFunc) tt_cmap_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap6_char_index, - (FT_CMap_CharNextFunc) tt_cmap6_char_next, + sizeof ( TT_CMapRec ), - NULL, - NULL, - NULL, - NULL, - NULL, + (FT_CMap_InitFunc) tt_cmap_init, /* init */ + (FT_CMap_DoneFunc) NULL, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap6_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap6_char_next, /* char_next */ + + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ 6, - (TT_CMap_ValidateFunc)tt_cmap6_validate, - (TT_CMap_Info_GetFunc)tt_cmap6_get_info ) + (TT_CMap_ValidateFunc)tt_cmap6_validate, /* validate */ + (TT_CMap_Info_GetFunc)tt_cmap6_get_info /* get_cmap_info */ + ) #endif /* TT_CONFIG_CMAP_FORMAT_6 */ @@ -1891,7 +1976,10 @@ /* if `gindex' is invalid, the remaining values */ /* in this group are invalid, too */ if ( gindex >= (FT_UInt)face->num_glyphs ) + { + gindex = 0; continue; + } result = char_code; break; @@ -1919,22 +2007,24 @@ FT_DEFINE_TT_CMAP( tt_cmap8_class_rec, - sizeof ( TT_CMapRec ), - (FT_CMap_InitFunc) tt_cmap_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap8_char_index, - (FT_CMap_CharNextFunc) tt_cmap8_char_next, + sizeof ( TT_CMapRec ), - NULL, - NULL, - NULL, - NULL, - NULL, + (FT_CMap_InitFunc) tt_cmap_init, /* init */ + (FT_CMap_DoneFunc) NULL, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap8_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap8_char_next, /* char_next */ + + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ 8, - (TT_CMap_ValidateFunc)tt_cmap8_validate, - (TT_CMap_Info_GetFunc)tt_cmap8_get_info ) + (TT_CMap_ValidateFunc)tt_cmap8_validate, /* validate */ + (TT_CMap_Info_GetFunc)tt_cmap8_get_info /* get_cmap_info */ + ) #endif /* TT_CONFIG_CMAP_FORMAT_8 */ @@ -2089,22 +2179,24 @@ FT_DEFINE_TT_CMAP( tt_cmap10_class_rec, - sizeof ( TT_CMapRec ), - (FT_CMap_InitFunc) tt_cmap_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap10_char_index, - (FT_CMap_CharNextFunc) tt_cmap10_char_next, + sizeof ( TT_CMapRec ), - NULL, - NULL, - NULL, - NULL, - NULL, + (FT_CMap_InitFunc) tt_cmap_init, /* init */ + (FT_CMap_DoneFunc) NULL, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap10_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap10_char_next, /* char_next */ + + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ 10, - (TT_CMap_ValidateFunc)tt_cmap10_validate, - (TT_CMap_Info_GetFunc)tt_cmap10_get_info ) + (TT_CMap_ValidateFunc)tt_cmap10_validate, /* validate */ + (TT_CMap_Info_GetFunc)tt_cmap10_get_info /* get_cmap_info */ + ) #endif /* TT_CONFIG_CMAP_FORMAT_10 */ @@ -2277,7 +2369,10 @@ /* if `gindex' is invalid, the remaining values */ /* in this group are invalid, too */ if ( gindex >= (FT_UInt)face->num_glyphs ) + { + gindex = 0; continue; + } cmap->cur_charcode = char_code; cmap->cur_gindex = gindex; @@ -2440,22 +2535,24 @@ FT_DEFINE_TT_CMAP( tt_cmap12_class_rec, - sizeof ( TT_CMap12Rec ), - (FT_CMap_InitFunc) tt_cmap12_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap12_char_index, - (FT_CMap_CharNextFunc) tt_cmap12_char_next, + sizeof ( TT_CMap12Rec ), - NULL, - NULL, - NULL, - NULL, - NULL, + (FT_CMap_InitFunc) tt_cmap12_init, /* init */ + (FT_CMap_DoneFunc) NULL, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap12_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap12_char_next, /* char_next */ + + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ 12, - (TT_CMap_ValidateFunc)tt_cmap12_validate, - (TT_CMap_Info_GetFunc)tt_cmap12_get_info ) + (TT_CMap_ValidateFunc)tt_cmap12_validate, /* validate */ + (TT_CMap_Info_GetFunc)tt_cmap12_get_info /* get_cmap_info */ + ) #endif /* TT_CONFIG_CMAP_FORMAT_12 */ @@ -2764,22 +2861,24 @@ FT_DEFINE_TT_CMAP( tt_cmap13_class_rec, - sizeof ( TT_CMap13Rec ), - (FT_CMap_InitFunc) tt_cmap13_init, - (FT_CMap_DoneFunc) NULL, - (FT_CMap_CharIndexFunc)tt_cmap13_char_index, - (FT_CMap_CharNextFunc) tt_cmap13_char_next, + sizeof ( TT_CMap13Rec ), - NULL, - NULL, - NULL, - NULL, - NULL, + (FT_CMap_InitFunc) tt_cmap13_init, /* init */ + (FT_CMap_DoneFunc) NULL, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap13_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap13_char_next, /* char_next */ + + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ 13, - (TT_CMap_ValidateFunc)tt_cmap13_validate, - (TT_CMap_Info_GetFunc)tt_cmap13_get_info ) + (TT_CMap_ValidateFunc)tt_cmap13_validate, /* validate */ + (TT_CMap_Info_GetFunc)tt_cmap13_get_info /* get_cmap_info */ + ) #endif /* TT_CONFIG_CMAP_FORMAT_13 */ @@ -2870,7 +2969,7 @@ cmap->max_results = 0; - if ( memory != NULL && cmap->results != NULL ) + if ( memory && cmap->results ) FT_FREE( cmap->results ); } @@ -2962,17 +3061,22 @@ /* through the normal Unicode cmap, no GIDs, just check order) */ if ( defOff != 0 ) { - FT_Byte* defp = table + defOff; - FT_ULong numRanges = TT_NEXT_ULONG( defp ); + FT_Byte* defp = table + defOff; + FT_ULong numRanges; FT_ULong i; - FT_ULong lastBase = 0; + FT_ULong lastBase = 0; + if ( defp + 4 > valid->limit ) + FT_INVALID_TOO_SHORT; + + numRanges = TT_NEXT_ULONG( defp ); + /* defp + numRanges * 4 > valid->limit ? */ if ( numRanges > (FT_ULong)( valid->limit - defp ) / 4 ) FT_INVALID_TOO_SHORT; - for ( i = 0; i < numRanges; ++i ) + for ( i = 0; i < numRanges; i++ ) { FT_ULong base = TT_NEXT_UINT24( defp ); FT_ULong cnt = FT_NEXT_BYTE( defp ); @@ -2991,16 +3095,21 @@ /* and the non-default table (these glyphs are specified here) */ if ( nondefOff != 0 ) { - FT_Byte* ndp = table + nondefOff; - FT_ULong numMappings = TT_NEXT_ULONG( ndp ); - FT_ULong i, lastUni = 0; + FT_Byte* ndp = table + nondefOff; + FT_ULong numMappings; + FT_ULong i, lastUni = 0; - /* numMappings * 4 > (FT_ULong)( valid->limit - ndp ) ? */ - if ( numMappings > ( (FT_ULong)( valid->limit - ndp ) ) / 4 ) + if ( ndp + 4 > valid->limit ) FT_INVALID_TOO_SHORT; - for ( i = 0; i < numMappings; ++i ) + numMappings = TT_NEXT_ULONG( ndp ); + + /* numMappings * 5 > (FT_ULong)( valid->limit - ndp ) ? */ + if ( numMappings > ( (FT_ULong)( valid->limit - ndp ) ) / 5 ) + FT_INVALID_TOO_SHORT; + + for ( i = 0; i < numMappings; i++ ) { FT_ULong uni = TT_NEXT_UINT24( ndp ); FT_ULong gid = TT_NEXT_USHORT( ndp ); @@ -3088,7 +3197,7 @@ if ( char_code < start ) max = mid; - else if ( char_code > start+cnt ) + else if ( char_code > start + cnt ) min = mid + 1; else return TRUE; @@ -3241,7 +3350,7 @@ return NULL; result = cmap14->results; - for ( i = 0; i < count; ++i ) + for ( i = 0; i < count; i++ ) { result[i] = (FT_UInt32)TT_NEXT_UINT24( p ); p += 8; @@ -3266,7 +3375,7 @@ if ( tt_cmap14_ensure( cmap14, ( count + 1 ), memory ) ) return NULL; - for ( q = cmap14->results; count > 0; --count ) + for ( q = cmap14->results; count > 0; count-- ) { FT_UInt32 varSel = TT_NEXT_UINT24( p ); FT_ULong defOff = TT_NEXT_ULONG( p ); @@ -3325,7 +3434,7 @@ if ( tt_cmap14_ensure( cmap14, ( cnt + 1 ), memory ) ) return NULL; - for ( q = cmap14->results; numRanges > 0; --numRanges ) + for ( q = cmap14->results; numRanges > 0; numRanges-- ) { FT_UInt32 uni = (FT_UInt32)TT_NEXT_UINT24( p ); @@ -3362,7 +3471,7 @@ return NULL; ret = cmap14->results; - for ( i = 0; i < numMappings; ++i ) + for ( i = 0; i < numMappings; i++ ) { ret[i] = (FT_UInt32)TT_NEXT_UINT24( p ); p += 2; @@ -3442,14 +3551,14 @@ ni = 1; i = 0; - for ( ;; ) + for (;;) { if ( nuni > duni + dcnt ) { - for ( k = 0; k <= dcnt; ++k ) + for ( k = 0; k <= dcnt; k++ ) ret[i++] = duni + k; - ++di; + di++; if ( di > numRanges ) break; @@ -3463,7 +3572,7 @@ ret[i++] = nuni; /* If it is within the default range then ignore it -- */ /* that should not have happened */ - ++ni; + ni++; if ( ni > numMappings ) break; @@ -3482,7 +3591,7 @@ { ret[i++] = (FT_UInt32)TT_NEXT_UINT24( p ); p += 2; - ++ni; + ni++; } } else if ( di <= numRanges ) @@ -3490,7 +3599,7 @@ /* If we get here then we have run out of all non-default */ /* mappings. We have read one default range which we haven't */ /* stored and there may be others that need to be read. */ - for ( k = 0; k <= dcnt; ++k ) + for ( k = 0; k <= dcnt; k++ ) ret[i++] = duni + k; while ( di < numRanges ) @@ -3498,9 +3607,9 @@ duni = (FT_UInt32)TT_NEXT_UINT24( dp ); dcnt = FT_NEXT_BYTE( dp ); - for ( k = 0; k <= dcnt; ++k ) + for ( k = 0; k <= dcnt; k++ ) ret[i++] = duni + k; - ++di; + di++; } } @@ -3513,27 +3622,133 @@ FT_DEFINE_TT_CMAP( tt_cmap14_class_rec, - sizeof ( TT_CMap14Rec ), - (FT_CMap_InitFunc) tt_cmap14_init, - (FT_CMap_DoneFunc) tt_cmap14_done, - (FT_CMap_CharIndexFunc)tt_cmap14_char_index, - (FT_CMap_CharNextFunc) tt_cmap14_char_next, + sizeof ( TT_CMap14Rec ), - /* Format 14 extension functions */ - (FT_CMap_CharVarIndexFunc) tt_cmap14_char_var_index, - (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault, - (FT_CMap_VariantListFunc) tt_cmap14_variants, - (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants, - (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars, + (FT_CMap_InitFunc) tt_cmap14_init, /* init */ + (FT_CMap_DoneFunc) tt_cmap14_done, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap14_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap14_char_next, /* char_next */ + + /* Format 14 extension functions */ + (FT_CMap_CharVarIndexFunc) tt_cmap14_char_var_index, + (FT_CMap_CharVarIsDefaultFunc)tt_cmap14_char_var_isdefault, + (FT_CMap_VariantListFunc) tt_cmap14_variants, + (FT_CMap_CharVariantListFunc) tt_cmap14_char_variants, + (FT_CMap_VariantCharListFunc) tt_cmap14_variant_chars, 14, - (TT_CMap_ValidateFunc)tt_cmap14_validate, - (TT_CMap_Info_GetFunc)tt_cmap14_get_info ) + (TT_CMap_ValidateFunc)tt_cmap14_validate, /* validate */ + (TT_CMap_Info_GetFunc)tt_cmap14_get_info /* get_cmap_info */ + ) #endif /* TT_CONFIG_CMAP_FORMAT_14 */ + /*************************************************************************/ + /*************************************************************************/ + /***** *****/ + /***** SYNTHETIC UNICODE *****/ + /***** *****/ + /*************************************************************************/ + /*************************************************************************/ + + /* This charmap is generated using postscript glyph names. */ + +#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES + + FT_CALLBACK_DEF( const char * ) + tt_get_glyph_name( TT_Face face, + FT_UInt idx ) + { + FT_String* PSname; + + + tt_face_get_ps_name( face, idx, &PSname ); + + return PSname; + } + + + FT_CALLBACK_DEF( FT_Error ) + tt_cmap_unicode_init( PS_Unicodes unicodes, + FT_Pointer pointer ) + { + TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes ); + FT_Memory memory = FT_FACE_MEMORY( face ); + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; + + FT_UNUSED( pointer ); + + + return psnames->unicodes_init( memory, + unicodes, + face->root.num_glyphs, + (PS_GetGlyphNameFunc)&tt_get_glyph_name, + (PS_FreeGlyphNameFunc)NULL, + (FT_Pointer)face ); + } + + + FT_CALLBACK_DEF( void ) + tt_cmap_unicode_done( PS_Unicodes unicodes ) + { + FT_Face face = FT_CMAP_FACE( unicodes ); + FT_Memory memory = FT_FACE_MEMORY( face ); + + + FT_FREE( unicodes->maps ); + unicodes->num_maps = 0; + } + + + FT_CALLBACK_DEF( FT_UInt ) + tt_cmap_unicode_char_index( PS_Unicodes unicodes, + FT_UInt32 char_code ) + { + TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes ); + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; + + + return psnames->unicodes_char_index( unicodes, char_code ); + } + + + FT_CALLBACK_DEF( FT_UInt32 ) + tt_cmap_unicode_char_next( PS_Unicodes unicodes, + FT_UInt32 *pchar_code ) + { + TT_Face face = (TT_Face)FT_CMAP_FACE( unicodes ); + FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)face->psnames; + + + return psnames->unicodes_char_next( unicodes, pchar_code ); + } + + + FT_DEFINE_TT_CMAP( + tt_cmap_unicode_class_rec, + + sizeof ( PS_UnicodesRec ), + + (FT_CMap_InitFunc) tt_cmap_unicode_init, /* init */ + (FT_CMap_DoneFunc) tt_cmap_unicode_done, /* done */ + (FT_CMap_CharIndexFunc)tt_cmap_unicode_char_index, /* char_index */ + (FT_CMap_CharNextFunc) tt_cmap_unicode_char_next, /* char_next */ + + (FT_CMap_CharVarIndexFunc) NULL, /* char_var_index */ + (FT_CMap_CharVarIsDefaultFunc)NULL, /* char_var_default */ + (FT_CMap_VariantListFunc) NULL, /* variant_list */ + (FT_CMap_CharVariantListFunc) NULL, /* charvariant_list */ + (FT_CMap_VariantCharListFunc) NULL, /* variantchar_list */ + + ~0U, + (TT_CMap_ValidateFunc)NULL, /* validate */ + (TT_CMap_Info_GetFunc)NULL /* get_cmap_info */ + ) + +#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */ + #ifndef FT_CONFIG_OPTION_PIC static const TT_CMap_Class tt_cmap_classes[] = @@ -3668,7 +3883,7 @@ error = clazz->validate( cmap, FT_VALIDATOR( &valid ) ); } - if ( valid.validator.error == 0 ) + if ( !valid.validator.error ) { FT_CMap ttcmap; @@ -3694,7 +3909,7 @@ } } - if ( *pclazz == NULL ) + if ( !*pclazz ) { FT_TRACE0(( "tt_face_build_cmaps:" " unsupported cmap sub-table ignored\n" )); @@ -3713,8 +3928,10 @@ FT_CMap cmap = (FT_CMap)charmap; TT_CMap_Class clazz = (TT_CMap_Class)cmap->clazz; - - return clazz->get_cmap_info( charmap, cmap_info ); + if ( clazz->get_cmap_info ) + return clazz->get_cmap_info( charmap, cmap_info ); + else + return FT_THROW( Invalid_CharMap_Format ); } diff --git a/src/3rdparty/freetype/src/sfnt/ttcmap.h b/src/3rdparty/freetype/src/sfnt/ttcmap.h index b7ea8ee377..d264d99d2c 100644 --- a/src/3rdparty/freetype/src/sfnt/ttcmap.h +++ b/src/3rdparty/freetype/src/sfnt/ttcmap.h @@ -4,7 +4,7 @@ /* */ /* TrueType character mapping table (cmap) support (specification). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTCMAP_H__ -#define __TTCMAP_H__ +#ifndef TTCMAP_H_ +#define TTCMAP_H_ #include <ft2build.h> @@ -141,6 +141,8 @@ FT_BEGIN_HEADER #define TT_VALID_GLYPH_COUNT( x ) TT_VALIDATOR( x )->num_glyphs + FT_CALLBACK_TABLE const TT_CMap_ClassRec tt_cmap_unicode_class_rec; + FT_LOCAL( FT_Error ) tt_face_build_cmaps( TT_Face face ); @@ -152,7 +154,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTCMAP_H__ */ +#endif /* TTCMAP_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/sfnt/ttcmapc.h b/src/3rdparty/freetype/src/sfnt/ttcmapc.h index 4a489402cf..4980e9dd3d 100644 --- a/src/3rdparty/freetype/src/sfnt/ttcmapc.h +++ b/src/3rdparty/freetype/src/sfnt/ttcmapc.h @@ -4,7 +4,7 @@ /* */ /* TT CMAP classes definitions (specification only). */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2018 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/src/sfnt/ttkern.c b/src/3rdparty/freetype/src/sfnt/ttkern.c index 4fccc535ce..68f15a2010 100644 --- a/src/3rdparty/freetype/src/sfnt/ttkern.c +++ b/src/3rdparty/freetype/src/sfnt/ttkern.c @@ -5,7 +5,7 @@ /* Load the basic TrueType kerning table. This doesn't handle */ /* kerning data within the GPOS table at the moment. */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -85,7 +85,7 @@ for ( nn = 0; nn < num_tables; nn++ ) { - FT_UInt num_pairs, length, coverage; + FT_UInt num_pairs, length, coverage, format; FT_Byte* p_next; FT_UInt32 mask = (FT_UInt32)1UL << nn; @@ -107,9 +107,15 @@ if ( p_next > p_limit ) /* handle broken table */ p_next = p_limit; + format = coverage >> 8; + + /* we currently only support format 0 kerning tables */ + if ( format != 0 ) + goto NextTable; + /* only use horizontal kerning tables */ - if ( ( coverage & ~8U ) != 0x0001 || - p + 8 > p_limit ) + if ( ( coverage & 3U ) != 0x0001 || + p + 8 > p_next ) goto NextTable; num_pairs = FT_NEXT_USHORT( p ); @@ -214,8 +220,7 @@ if ( ( face->kern_avail_bits & mask ) == 0 ) goto NextTable; - if ( p + 8 > next ) - goto NextTable; + FT_ASSERT( p + 8 <= next ); /* tested in tt_face_load_kern */ num_pairs = FT_NEXT_USHORT( p ); p += 6; diff --git a/src/3rdparty/freetype/src/sfnt/ttkern.h b/src/3rdparty/freetype/src/sfnt/ttkern.h index 89cb24f07c..4e45d0964b 100644 --- a/src/3rdparty/freetype/src/sfnt/ttkern.h +++ b/src/3rdparty/freetype/src/sfnt/ttkern.h @@ -5,7 +5,7 @@ /* Load the basic TrueType kerning table. This doesn't handle */ /* kerning data within the GPOS table at the moment. */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __TTKERN_H__ -#define __TTKERN_H__ +#ifndef TTKERN_H_ +#define TTKERN_H_ #include <ft2build.h> @@ -46,7 +46,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTKERN_H__ */ +#endif /* TTKERN_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/sfnt/ttload.c b/src/3rdparty/freetype/src/sfnt/ttload.c index c1bd7f0c82..a86a546c3d 100644 --- a/src/3rdparty/freetype/src/sfnt/ttload.c +++ b/src/3rdparty/freetype/src/sfnt/ttload.c @@ -5,7 +5,7 @@ /* Load the basic TrueType tables, i.e., tables that can be either in */ /* TTF or OTF fonts (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -338,7 +338,7 @@ SFNT_HeaderRec sfnt; FT_Error error; FT_Memory memory = stream->memory; - FT_UShort nn, valid_entries; + FT_UShort nn, valid_entries = 0; static const FT_Frame_Field offset_table_fields[] = { @@ -679,7 +679,7 @@ /*************************************************************************/ /* */ /* <Function> */ - /* tt_face_load_max_profile */ + /* tt_face_load_maxp */ /* */ /* <Description> */ /* Loads the maximum profile into a face object. */ @@ -775,15 +775,6 @@ maxProfile->maxTwilightPoints = 0xFFFFU - 4; } - - /* we arbitrarily limit recursion to avoid stack exhaustion */ - if ( maxProfile->maxComponentDepth > 100 ) - { - FT_TRACE0(( "tt_face_load_maxp:" - " abnormally large component depth (%d) set to 100\n", - maxProfile->maxComponentDepth )); - maxProfile->maxComponentDepth = 100; - } } FT_TRACE3(( "numGlyphs: %u\n", maxProfile->numGlyphs )); @@ -817,7 +808,6 @@ FT_Memory memory = stream->memory; FT_ULong table_pos, table_len; FT_ULong storage_start, storage_limit; - FT_UInt count; TT_NameTable table; static const FT_Frame_Field name_table_fields[] = @@ -835,7 +825,7 @@ static const FT_Frame_Field name_record_fields[] = { #undef FT_STRUCTURE -#define FT_STRUCTURE TT_NameEntryRec +#define FT_STRUCTURE TT_NameRec /* no FT_FRAME_START */ FT_FRAME_USHORT( platformID ), @@ -847,6 +837,17 @@ FT_FRAME_END }; + static const FT_Frame_Field langTag_record_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE TT_LangTagRec + + /* no FT_FRAME_START */ + FT_FRAME_USHORT( stringLength ), + FT_FRAME_USHORT( stringOffset ), + FT_FRAME_END + }; + table = &face->name_table; table->stream = stream; @@ -857,18 +858,17 @@ table_pos = FT_STREAM_POS(); - if ( FT_STREAM_READ_FIELDS( name_table_fields, table ) ) goto Exit; - /* Some popular Asian fonts have an invalid `storageOffset' value */ - /* (it should be at least "6 + 12*num_names"). However, the string */ - /* offsets, computed as "storageOffset + entry->stringOffset", are */ - /* valid pointers within the name table... */ - /* */ - /* We thus can't check `storageOffset' right now. */ - /* */ - storage_start = table_pos + 6 + 12*table->numNameRecords; + /* Some popular Asian fonts have an invalid `storageOffset' value (it */ + /* should be at least `6 + 12*numNameRecords'). However, the string */ + /* offsets, computed as `storageOffset + entry->stringOffset', are */ + /* valid pointers within the name table... */ + /* */ + /* We thus can't check `storageOffset' right now. */ + /* */ + storage_start = table_pos + 6 + 12 * table->numNameRecords; storage_limit = table_pos + table_len; if ( storage_start > storage_limit ) @@ -878,18 +878,56 @@ goto Exit; } - /* Allocate the array of name records. */ - count = table->numNameRecords; - table->numNameRecords = 0; + /* `name' format 1 contains additional language tag records, */ + /* which we load first */ + if ( table->format == 1 ) + { + if ( FT_STREAM_SEEK( storage_start ) || + FT_READ_USHORT( table->numLangTagRecords ) ) + goto Exit; - if ( FT_NEW_ARRAY( table->names, count ) || - FT_FRAME_ENTER( count * 12 ) ) + storage_start += 2 + 4 * table->numLangTagRecords; + + /* allocate language tag records array */ + if ( FT_NEW_ARRAY( table->langTags, table->numLangTagRecords ) || + FT_FRAME_ENTER( table->numLangTagRecords * 4 ) ) + goto Exit; + + /* load language tags */ + { + TT_LangTag entry = table->langTags; + TT_LangTag limit = entry + table->numLangTagRecords; + + + for ( ; entry < limit; entry++ ) + { + (void)FT_STREAM_READ_FIELDS( langTag_record_fields, entry ); + + /* check that the langTag string is within the table */ + entry->stringOffset += table_pos + table->storageOffset; + if ( entry->stringOffset < storage_start || + entry->stringOffset + entry->stringLength > storage_limit ) + { + /* invalid entry; ignore it */ + entry->stringLength = 0; + } + } + } + + FT_FRAME_EXIT(); + + (void)FT_STREAM_SEEK( table_pos + 6 ); + } + + /* allocate name records array */ + if ( FT_NEW_ARRAY( table->names, table->numNameRecords ) || + FT_FRAME_ENTER( table->numNameRecords * 12 ) ) goto Exit; - /* Load the name records and determine how much storage is needed */ - /* to hold the strings themselves. */ + /* load name records */ { - TT_NameEntryRec* entry = table->names; + TT_Name entry = table->names; + FT_UInt count = table->numNameRecords; for ( ; count > 0; count-- ) @@ -906,22 +944,37 @@ if ( entry->stringOffset < storage_start || entry->stringOffset + entry->stringLength > storage_limit ) { - /* invalid entry - ignore it */ - entry->stringOffset = 0; - entry->stringLength = 0; + /* invalid entry; ignore it */ continue; } + /* assure that we have a valid language tag ID, and */ + /* that the corresponding langTag entry is valid, too */ + if ( table->format == 1 && entry->languageID >= 0x8000U ) + { + if ( entry->languageID - 0x8000U >= table->numLangTagRecords || + !table->langTags[entry->languageID - 0x8000U].stringLength ) + { + /* invalid entry; ignore it */ + continue; + } + } + entry++; } - table->numNameRecords = (FT_UInt)( entry - table->names ); + /* reduce array size to the actually used elements */ + count = (FT_UInt)( entry - table->names ); + (void)FT_RENEW_ARRAY( table->names, + table->numNameRecords, + count ); + table->numNameRecords = count; } FT_FRAME_EXIT(); /* everything went well, update face->num_names */ - face->num_names = (FT_UShort) table->numNameRecords; + face->num_names = (FT_UShort)table->numNameRecords; Exit: return error; @@ -931,7 +984,7 @@ /*************************************************************************/ /* */ /* <Function> */ - /* tt_face_free_names */ + /* tt_face_free_name */ /* */ /* <Description> */ /* Frees the name records. */ @@ -944,25 +997,36 @@ { FT_Memory memory = face->root.driver->root.memory; TT_NameTable table = &face->name_table; - TT_NameEntry entry = table->names; - FT_UInt count = table->numNameRecords; if ( table->names ) { - for ( ; count > 0; count--, entry++ ) - { - FT_FREE( entry->string ); - entry->stringLength = 0; - } + TT_Name entry = table->names; + TT_Name limit = entry + table->numNameRecords; + + + for ( ; entry < limit; entry++ ) + FT_FREE( entry->string ); - /* free strings table */ FT_FREE( table->names ); } - table->numNameRecords = 0; - table->format = 0; - table->storageOffset = 0; + if ( table->langTags ) + { + TT_LangTag entry = table->langTags; + TT_LangTag limit = entry + table->numLangTagRecords; + + + for ( ; entry < limit; entry++ ) + FT_FREE( entry->string ); + + FT_FREE( table->langTags ); + } + + table->numNameRecords = 0; + table->numLangTagRecords = 0; + table->format = 0; + table->storageOffset = 0; } @@ -1193,8 +1257,8 @@ #define FT_STRUCTURE TT_Postscript FT_FRAME_START( 32 ), - FT_FRAME_ULONG( FormatType ), - FT_FRAME_ULONG( italicAngle ), + FT_FRAME_LONG ( FormatType ), + FT_FRAME_LONG ( italicAngle ), FT_FRAME_SHORT( underlinePosition ), FT_FRAME_SHORT( underlineThickness ), FT_FRAME_ULONG( isFixedPitch ), diff --git a/src/3rdparty/freetype/src/sfnt/ttload.h b/src/3rdparty/freetype/src/sfnt/ttload.h index a6d91c5b70..f94be8b7bd 100644 --- a/src/3rdparty/freetype/src/sfnt/ttload.h +++ b/src/3rdparty/freetype/src/sfnt/ttload.h @@ -5,7 +5,7 @@ /* Load the basic TrueType tables, i.e., tables that can be either in */ /* TTF or OTF fonts (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __TTLOAD_H__ -#define __TTLOAD_H__ +#ifndef TTLOAD_H_ +#define TTLOAD_H_ #include <ft2build.h> @@ -106,7 +106,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTLOAD_H__ */ +#endif /* TTLOAD_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/sfnt/ttmtx.c b/src/3rdparty/freetype/src/sfnt/ttmtx.c index 58309aa496..6ddda95b56 100644 --- a/src/3rdparty/freetype/src/sfnt/ttmtx.c +++ b/src/3rdparty/freetype/src/sfnt/ttmtx.c @@ -4,7 +4,7 @@ /* */ /* Load the metrics tables common to TTF and OTF fonts (body). */ /* */ -/* Copyright 2006-2015 by */ +/* Copyright 2006-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -20,11 +20,24 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_TRUETYPE_TAGS_H + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include FT_SERVICE_METRICS_VARIATIONS_H +#endif + #include "ttmtx.h" #include "sferrors.h" + /* IMPORTANT: The TT_HoriHeader and TT_VertHeader structures should */ + /* be identical except for the names of their fields, */ + /* which are different. */ + /* */ + /* This ensures that `tt_face_load_hmtx' is able to read */ + /* both the horizontal and vertical headers. */ + + /*************************************************************************/ /* */ /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ @@ -214,6 +227,11 @@ FT_ULong table_pos, table_size, table_end; FT_UShort k; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_Service_MetricsVariations var = + (FT_Service_MetricsVariations)face->var; +#endif + if ( vertical ) { @@ -274,6 +292,34 @@ *abearing = 0; *aadvance = 0; } + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + if ( var ) + { + FT_Face f = FT_FACE( face ); + FT_Int a = (FT_Int)*aadvance; + FT_Int b = (FT_Int)*abearing; + + + if ( vertical ) + { + if ( var->vadvance_adjust ) + var->vadvance_adjust( f, gindex, &a ); + if ( var->tsb_adjust ) + var->tsb_adjust( f, gindex, &b ); + } + else + { + if ( var->hadvance_adjust ) + var->hadvance_adjust( f, gindex, &a ); + if ( var->lsb_adjust ) + var->lsb_adjust( f, gindex, &b ); + } + + *aadvance = (FT_UShort)a; + *abearing = (FT_Short)b; + } +#endif } diff --git a/src/3rdparty/freetype/src/sfnt/ttmtx.h b/src/3rdparty/freetype/src/sfnt/ttmtx.h index 096ee062cf..ab00acd795 100644 --- a/src/3rdparty/freetype/src/sfnt/ttmtx.h +++ b/src/3rdparty/freetype/src/sfnt/ttmtx.h @@ -4,7 +4,7 @@ /* */ /* Load the metrics tables common to TTF and OTF fonts (specification). */ /* */ -/* Copyright 2006-2015 by */ +/* Copyright 2006-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTMTX_H__ -#define __TTMTX_H__ +#ifndef TTMTX_H_ +#define TTMTX_H_ #include <ft2build.h> @@ -49,7 +49,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTMTX_H__ */ +#endif /* TTMTX_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/sfnt/ttpost.c b/src/3rdparty/freetype/src/sfnt/ttpost.c index 8d29d1e9f6..6de99ef977 100644 --- a/src/3rdparty/freetype/src/sfnt/ttpost.c +++ b/src/3rdparty/freetype/src/sfnt/ttpost.c @@ -2,10 +2,10 @@ /* */ /* ttpost.c */ /* */ -/* Postcript name table processing for TrueType and OpenType fonts */ +/* PostScript name table processing for TrueType and OpenType fonts */ /* (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -29,6 +29,10 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_TRUETYPE_TAGS_H + + +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES + #include "ttpost.h" #include "sferrors.h" @@ -321,12 +325,13 @@ FT_UNUSED( post_limit ); - /* UNDOCUMENTED! This value appears only in the Apple TT specs. */ if ( FT_READ_USHORT( num_glyphs ) ) goto Exit; /* check the number of glyphs */ - if ( num_glyphs > face->max_profile.numGlyphs || num_glyphs > 258 ) + if ( num_glyphs > face->max_profile.numGlyphs || + num_glyphs > 258 || + num_glyphs < 1 ) { error = FT_THROW( Invalid_File_Format ); goto Exit; @@ -402,7 +407,7 @@ /* now read postscript table */ if ( format == 0x00020000L ) error = load_format_20( face, stream, post_limit ); - else if ( format == 0x00028000L ) + else if ( format == 0x00025000L ) error = load_format_25( face, stream, post_limit ); else error = FT_THROW( Invalid_File_Format ); @@ -441,7 +446,7 @@ FT_FREE( table->glyph_names ); table->num_names = 0; } - else if ( format == 0x00028000L ) + else if ( format == 0x00025000L ) { TT_Post_25 table = &names->names.format_25; @@ -468,8 +473,8 @@ /* idx :: The glyph index. */ /* */ /* <InOut> */ - /* PSname :: The address of a string pointer. Will be NULL in case */ - /* of error, otherwise it is a pointer to the glyph name. */ + /* PSname :: The address of a string pointer. Undefined in case of */ + /* error, otherwise it is a pointer to the glyph name. */ /* */ /* You must not modify the returned string! */ /* */ @@ -537,7 +542,7 @@ *PSname = (FT_String*)table->glyph_names[name_index - 258]; } } - else if ( format == 0x00028000L ) + else if ( format == 0x00025000L ) { TT_Post_25 table = &names->names.format_25; @@ -559,5 +564,12 @@ return FT_Err_Ok; } +#else /* !TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ + + /* ANSI C doesn't like empty source files */ + typedef int _tt_post_dummy; + +#endif /* !TT_CONFIG_OPTION_POSTSCRIPT_NAMES */ + /* END */ diff --git a/src/3rdparty/freetype/src/sfnt/ttpost.h b/src/3rdparty/freetype/src/sfnt/ttpost.h index e3eca02c62..3bec07e445 100644 --- a/src/3rdparty/freetype/src/sfnt/ttpost.h +++ b/src/3rdparty/freetype/src/sfnt/ttpost.h @@ -2,10 +2,10 @@ /* */ /* ttpost.h */ /* */ -/* Postcript name table processing for TrueType and OpenType fonts */ +/* PostScript name table processing for TrueType and OpenType fonts */ /* (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __TTPOST_H__ -#define __TTPOST_H__ +#ifndef TTPOST_H_ +#define TTPOST_H_ #include <ft2build.h> @@ -40,7 +40,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTPOST_H__ */ +#endif /* TTPOST_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/sfnt/ttsbit.c b/src/3rdparty/freetype/src/sfnt/ttsbit.c index 3b351ecfce..33b8640bc3 100644 --- a/src/3rdparty/freetype/src/sfnt/ttsbit.c +++ b/src/3rdparty/freetype/src/sfnt/ttsbit.c @@ -4,7 +4,7 @@ /* */ /* TrueType and OpenType embedded bitmap support (body). */ /* */ -/* Copyright 2005-2015 by */ +/* Copyright 2005-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* Copyright 2013 by Google, Inc. */ @@ -24,6 +24,10 @@ #include FT_INTERNAL_STREAM_H #include FT_TRUETYPE_TAGS_H #include FT_BITMAP_H + + +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + #include "ttsbit.h" #include "sferrors.h" @@ -48,6 +52,7 @@ { FT_Error error; FT_ULong table_size; + FT_ULong table_start; face->sbit_table = NULL; @@ -83,6 +88,8 @@ goto Exit; } + table_start = FT_STREAM_POS(); + switch ( (FT_UInt)face->sbit_table_type ) { case TT_SBIT_TABLE_TYPE_EBLC: @@ -104,7 +111,12 @@ version = FT_NEXT_LONG( p ); num_strikes = FT_NEXT_ULONG( p ); - if ( ( (FT_ULong)version & 0xFFFF0000UL ) != 0x00020000UL ) + /* there's at least one font (FZShuSong-Z01, version 3) */ + /* that uses the wrong byte order for the `version' field */ + if ( ( (FT_ULong)version & 0xFFFF0000UL ) != 0x00020000UL && + ( (FT_ULong)version & 0x0000FFFFUL ) != 0x00000200UL && + ( (FT_ULong)version & 0xFFFF0000UL ) != 0x00030000UL && + ( (FT_ULong)version & 0x0000FFFFUL ) != 0x00000300UL ) { error = FT_THROW( Unknown_File_Format ); goto Exit; @@ -189,12 +201,51 @@ break; default: + /* we ignore unknown table formats */ error = FT_THROW( Unknown_File_Format ); break; } if ( !error ) - FT_TRACE3(( "sbit_num_strikes: %u\n", face->sbit_num_strikes )); + FT_TRACE3(( "tt_face_load_sbit_strikes: found %u strikes\n", + face->sbit_num_strikes )); + + face->ebdt_start = 0; + face->ebdt_size = 0; + + if ( face->sbit_table_type == TT_SBIT_TABLE_TYPE_SBIX ) + { + /* the `sbix' table is self-contained; */ + /* it has no associated data table */ + face->ebdt_start = table_start; + face->ebdt_size = table_size; + } + else if ( face->sbit_table_type != TT_SBIT_TABLE_TYPE_NONE ) + { + FT_ULong ebdt_size; + + + error = face->goto_table( face, TTAG_CBDT, stream, &ebdt_size ); + if ( error ) + error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size ); + if ( error ) + error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size ); + + if ( !error ) + { + face->ebdt_start = FT_STREAM_POS(); + face->ebdt_size = ebdt_size; + } + } + + if ( !face->ebdt_size ) + { + FT_TRACE2(( "tt_face_load_sbit_strikes:" + " no embedded bitmap data table found;\n" + " " + " resetting number of strikes to zero\n" )); + face->sbit_num_strikes = 0; + } return FT_Err_Ok; @@ -238,8 +289,22 @@ FT_ULong strike_index, FT_Size_Metrics* metrics ) { - if ( strike_index >= (FT_ULong)face->sbit_num_strikes ) - return FT_THROW( Invalid_Argument ); + /* we have to test for the existence of `sbit_strike_map' */ + /* because the function gets also used at the very beginning */ + /* to construct `sbit_strike_map' itself */ + if ( face->sbit_strike_map ) + { + if ( strike_index >= (FT_ULong)face->root.num_fixed_sizes ) + return FT_THROW( Invalid_Argument ); + + /* map to real index */ + strike_index = face->sbit_strike_map[strike_index]; + } + else + { + if ( strike_index >= (FT_ULong)face->sbit_num_strikes ) + return FT_THROW( Invalid_Argument ); + } switch ( (FT_UInt)face->sbit_table_type ) { @@ -247,6 +312,8 @@ case TT_SBIT_TABLE_TYPE_CBLC: { FT_Byte* strike; + FT_Char max_before_bl; + FT_Char min_after_bl; strike = face->sbit_table + 8 + strike_index * 48; @@ -256,24 +323,91 @@ metrics->ascender = (FT_Char)strike[16] * 64; /* hori.ascender */ metrics->descender = (FT_Char)strike[17] * 64; /* hori.descender */ - metrics->height = metrics->ascender - metrics->descender; + + /* Due to fuzzy wording in the EBLC documentation, we find both */ + /* positive and negative values for `descender'. Additionally, */ + /* many fonts have both `ascender' and `descender' set to zero */ + /* (which is definitely wrong). MS Windows simply ignores all */ + /* those values... For these reasons we apply some heuristics */ + /* to get a reasonable, non-zero value for the height. */ + + max_before_bl = (FT_Char)strike[24]; + min_after_bl = (FT_Char)strike[25]; + + if ( metrics->descender > 0 ) + { + /* compare sign of descender with `min_after_bl' */ + if ( min_after_bl < 0 ) + metrics->descender = -metrics->descender; + } + + else if ( metrics->descender == 0 ) + { + if ( metrics->ascender == 0 ) + { + FT_TRACE2(( "tt_face_load_strike_metrics:" + " sanitizing invalid ascender and descender\n" + " " + " values for strike %d (%dppem, %dppem)\n", + strike_index, + metrics->x_ppem, metrics->y_ppem )); + + /* sanitize buggy ascender and descender values */ + if ( max_before_bl || min_after_bl ) + { + metrics->ascender = max_before_bl * 64; + metrics->descender = min_after_bl * 64; + } + else + { + metrics->ascender = metrics->y_ppem * 64; + metrics->descender = 0; + } + } + } + +#if 0 + else + ; /* if we have a negative descender, simply use it */ +#endif + + metrics->height = metrics->ascender - metrics->descender; + if ( metrics->height == 0 ) + { + FT_TRACE2(( "tt_face_load_strike_metrics:" + " sanitizing invalid height value\n" + " " + " for strike (%d, %d)\n", + metrics->x_ppem, metrics->y_ppem )); + metrics->height = metrics->y_ppem * 64; + metrics->descender = metrics->ascender - metrics->height; + } /* Is this correct? */ metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB */ strike[18] + /* max_width */ (FT_Char)strike[23] /* min_advance_SB */ ) * 64; + + /* set the scale values (in 16.16 units) so advances */ + /* from the hmtx and vmtx table are scaled correctly */ + metrics->x_scale = FT_MulDiv( metrics->x_ppem, + 64 * 0x10000, + face->header.Units_Per_EM ); + metrics->y_scale = FT_MulDiv( metrics->y_ppem, + 64 * 0x10000, + face->header.Units_Per_EM ); + return FT_Err_Ok; } case TT_SBIT_TABLE_TYPE_SBIX: { FT_Stream stream = face->root.stream; - FT_UInt offset, upem; - FT_UShort ppem, resolution; + FT_UInt offset; + FT_UShort upem, ppem, resolution; TT_HoriHeader *hori; - FT_ULong table_size; - FT_Pos ppem_, upem_; /* to reduce casts */ + FT_Pos ppem_; /* to reduce casts */ FT_Error error; FT_Byte* p; @@ -282,15 +416,11 @@ p = face->sbit_table + 8 + 4 * strike_index; offset = FT_NEXT_ULONG( p ); - error = face->goto_table( face, TTAG_sbix, stream, &table_size ); - if ( error ) - return error; - - if ( offset + 4 > table_size ) + if ( offset + 4 > face->ebdt_size ) return FT_THROW( Invalid_File_Format ); - if ( FT_STREAM_SEEK( FT_STREAM_POS() + offset ) || - FT_FRAME_ENTER( 4 ) ) + if ( FT_STREAM_SEEK( face->ebdt_start + offset ) || + FT_FRAME_ENTER( 4 ) ) return error; ppem = FT_GET_USHORT(); @@ -307,14 +437,25 @@ metrics->y_ppem = ppem; ppem_ = (FT_Pos)ppem; - upem_ = (FT_Pos)upem; - metrics->ascender = ppem_ * hori->Ascender * 64 / upem_; - metrics->descender = ppem_ * hori->Descender * 64 / upem_; - metrics->height = ppem_ * ( hori->Ascender - - hori->Descender + - hori->Line_Gap ) * 64 / upem_; - metrics->max_advance = ppem_ * hori->advance_Width_Max * 64 / upem_; + metrics->ascender = + FT_MulDiv( hori->Ascender, ppem_ * 64, upem ); + metrics->descender = + FT_MulDiv( hori->Descender, ppem_ * 64, upem ); + metrics->height = + FT_MulDiv( hori->Ascender - hori->Descender + hori->Line_Gap, + ppem_ * 64, upem ); + metrics->max_advance = + FT_MulDiv( hori->advance_Width_Max, ppem_ * 64, upem ); + + /* set the scale values (in 16.16 units) so advances */ + /* from the hmtx and vmtx table are scaled correctly */ + metrics->x_scale = FT_MulDiv( metrics->x_ppem, + 64 * 0x10000, + face->header.Units_Per_EM ); + metrics->y_scale = FT_MulDiv( metrics->y_ppem, + 64 * 0x10000, + face->header.Units_Per_EM ); return error; } @@ -352,17 +493,15 @@ FT_ULong strike_index, TT_SBit_MetricsRec* metrics ) { - FT_Error error; + FT_Error error = FT_ERR( Table_Missing ); FT_Stream stream = face->root.stream; - FT_ULong ebdt_size; - error = face->goto_table( face, TTAG_CBDT, stream, &ebdt_size ); - if ( error ) - error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size ); - if ( error ) - error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size ); - if ( error ) + strike_index = face->sbit_strike_map[strike_index]; + + if ( !face->ebdt_size ) + goto Exit; + if ( FT_STREAM_SEEK( face->ebdt_start ) ) goto Exit; decoder->face = face; @@ -373,8 +512,8 @@ decoder->metrics_loaded = 0; decoder->bitmap_allocated = 0; - decoder->ebdt_start = FT_STREAM_POS(); - decoder->ebdt_size = ebdt_size; + decoder->ebdt_start = face->ebdt_start; + decoder->ebdt_size = face->ebdt_size; decoder->eblc_base = face->sbit_table; decoder->eblc_limit = face->sbit_table + face->sbit_table_size; @@ -419,7 +558,8 @@ static FT_Error - tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder ) + tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder decoder, + FT_Bool metrics_only ) { FT_Error error = FT_Err_Ok; FT_UInt width, height; @@ -482,6 +622,9 @@ if ( size == 0 ) goto Exit; /* exit successfully! */ + if ( metrics_only ) + goto Exit; /* only metrics are requested */ + error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size ); if ( error ) goto Exit; @@ -547,13 +690,17 @@ tt_sbit_decoder_load_image( TT_SBitDecoder decoder, FT_UInt glyph_index, FT_Int x_pos, - FT_Int y_pos ); + FT_Int y_pos, + FT_UInt recurse_count, + FT_Bool metrics_only ); - typedef FT_Error (*TT_SBitDecoder_LoadFunc)( TT_SBitDecoder decoder, - FT_Byte* p, - FT_Byte* plimit, - FT_Int x_pos, - FT_Int y_pos ); + typedef FT_Error (*TT_SBitDecoder_LoadFunc)( + TT_SBitDecoder decoder, + FT_Byte* p, + FT_Byte* plimit, + FT_Int x_pos, + FT_Int y_pos, + FT_UInt recurse_count ); static FT_Error @@ -561,7 +708,8 @@ FT_Byte* p, FT_Byte* limit, FT_Int x_pos, - FT_Int y_pos ) + FT_Int y_pos, + FT_UInt recurse_count ) { FT_Error error = FT_Err_Ok; FT_Byte* line; @@ -569,6 +717,8 @@ FT_UInt bit_height, bit_width; FT_Bitmap* bitmap; + FT_UNUSED( recurse_count ); + /* check that we can write the glyph into the bitmap */ bitmap = decoder->bitmap; @@ -700,7 +850,8 @@ FT_Byte* p, FT_Byte* limit, FT_Int x_pos, - FT_Int y_pos ) + FT_Int y_pos, + FT_UInt recurse_count ) { FT_Error error = FT_Err_Ok; FT_Byte* line; @@ -709,6 +860,8 @@ FT_Bitmap* bitmap; FT_UShort rval; + FT_UNUSED( recurse_count ); + /* check that we can write the glyph into the bitmap */ bitmap = decoder->bitmap; @@ -738,6 +891,12 @@ goto Exit; } + if ( !line_bits || !height ) + { + /* nothing to do */ + goto Exit; + } + /* now do the blit */ /* adjust `line' to point to the first byte of the bitmap */ @@ -777,7 +936,7 @@ } *pwrite++ |= ( ( rval >> nbits ) & 0xFF ) & - ( ~( 0xFF << w ) << ( 8 - w - x_pos ) ); + ( ~( 0xFFU << w ) << ( 8 - w - x_pos ) ); rval <<= 8; w = line_bits - w; @@ -824,7 +983,8 @@ FT_Byte* p, FT_Byte* limit, FT_Int x_pos, - FT_Int y_pos ) + FT_Int y_pos, + FT_UInt recurse_count ) { FT_Error error = FT_Err_Ok; FT_UInt num_components, nn; @@ -847,8 +1007,9 @@ goto Fail; } - FT_TRACE3(( "tt_sbit_decoder_load_compound: loading %d components\n", - num_components )); + FT_TRACE3(( "tt_sbit_decoder_load_compound: loading %d component%s\n", + num_components, + num_components == 1 ? "" : "s" )); for ( nn = 0; nn < num_components; nn++ ) { @@ -858,8 +1019,13 @@ /* NB: a recursive call */ - error = tt_sbit_decoder_load_image( decoder, gindex, - x_pos + dx, y_pos + dy ); + error = tt_sbit_decoder_load_image( decoder, + gindex, + x_pos + dx, + y_pos + dy, + recurse_count + 1, + /* request full bitmap image */ + FALSE ); if ( error ) break; } @@ -891,11 +1057,14 @@ FT_Byte* p, FT_Byte* limit, FT_Int x_pos, - FT_Int y_pos ) + FT_Int y_pos, + FT_UInt recurse_count ) { FT_Error error = FT_Err_Ok; FT_ULong png_len; + FT_UNUSED( recurse_count ); + if ( limit - p < 4 ) { @@ -920,6 +1089,7 @@ decoder->stream->memory, p, png_len, + FALSE, FALSE ); Exit: @@ -937,7 +1107,9 @@ FT_ULong glyph_start, FT_ULong glyph_size, FT_Int x_pos, - FT_Int y_pos ) + FT_Int y_pos, + FT_UInt recurse_count, + FT_Bool metrics_only ) { FT_Error error; FT_Stream stream = decoder->stream; @@ -947,7 +1119,8 @@ /* seek into the EBDT table now */ - if ( glyph_start + glyph_size > decoder->ebdt_size ) + if ( !glyph_size || + glyph_start + glyph_size > decoder->ebdt_size ) { error = FT_THROW( Invalid_Argument ); goto Exit; @@ -1058,12 +1231,16 @@ if ( !decoder->bitmap_allocated ) { - error = tt_sbit_decoder_alloc_bitmap( decoder ); + error = tt_sbit_decoder_alloc_bitmap( decoder, metrics_only ); + if ( error ) goto Fail; } - error = loader( decoder, p, p_limit, x_pos, y_pos ); + if ( metrics_only ) + goto Fail; /* this is not an error */ + + error = loader( decoder, p, p_limit, x_pos, y_pos, recurse_count ); } Fail: @@ -1078,13 +1255,10 @@ tt_sbit_decoder_load_image( TT_SBitDecoder decoder, FT_UInt glyph_index, FT_Int x_pos, - FT_Int y_pos ) + FT_Int y_pos, + FT_UInt recurse_count, + FT_Bool metrics_only ) { - /* - * First, we find the correct strike range that applies to this - * glyph index. - */ - FT_Byte* p = decoder->eblc_base + decoder->strike_index_array; FT_Byte* p_limit = decoder->eblc_limit; FT_ULong num_ranges = decoder->strike_index_count; @@ -1092,6 +1266,17 @@ FT_ULong image_start = 0, image_end = 0, image_offset; + /* arbitrary recursion limit */ + if ( recurse_count > 100 ) + { + FT_TRACE4(( "tt_sbit_decoder_load_image:" + " recursion depth exceeded\n" )); + goto Failure; + } + + + /* First, we find the correct strike range that applies to this */ + /* glyph index. */ for ( ; num_ranges > 0; num_ranges-- ) { start = FT_NEXT_USHORT( p ); @@ -1256,16 +1441,25 @@ image_start, image_end, x_pos, - y_pos ); + y_pos, + recurse_count, + metrics_only ); Failure: return FT_THROW( Invalid_Table ); NoBitmap: + if ( recurse_count ) + { + FT_TRACE4(( "tt_sbit_decoder_load_image:" + " missing subglyph sbit with glyph index %d\n", + glyph_index )); + return FT_THROW( Invalid_Composite ); + } + FT_TRACE4(( "tt_sbit_decoder_load_image:" " no sbit found for glyph index %d\n", glyph_index )); - - return FT_THROW( Invalid_Argument ); + return FT_THROW( Missing_Bitmap ); } @@ -1275,10 +1469,10 @@ FT_UInt glyph_index, FT_Stream stream, FT_Bitmap *map, - TT_SBit_MetricsRec *metrics ) + TT_SBit_MetricsRec *metrics, + FT_Bool metrics_only ) { - FT_UInt sbix_pos, strike_offset, glyph_start, glyph_end; - FT_ULong table_size; + FT_UInt strike_offset, glyph_start, glyph_end; FT_Int originOffsetX, originOffsetY; FT_Tag graphicType; FT_Int recurse_depth = 0; @@ -1287,29 +1481,31 @@ FT_Byte* p; FT_UNUSED( map ); +#ifndef FT_CONFIG_OPTION_USE_PNG + FT_UNUSED( metrics_only ); +#endif + strike_index = face->sbit_strike_map[strike_index]; + metrics->width = 0; metrics->height = 0; p = face->sbit_table + 8 + 4 * strike_index; strike_offset = FT_NEXT_ULONG( p ); - error = face->goto_table( face, TTAG_sbix, stream, &table_size ); - if ( error ) - return error; - sbix_pos = FT_STREAM_POS(); - retry: if ( glyph_index > (FT_UInt)face->root.num_glyphs ) return FT_THROW( Invalid_Argument ); - if ( strike_offset >= table_size || - table_size - strike_offset < 4 + glyph_index * 4 + 8 ) + if ( strike_offset >= face->ebdt_size || + face->ebdt_size - strike_offset < 4 + glyph_index * 4 + 8 ) return FT_THROW( Invalid_File_Format ); - if ( FT_STREAM_SEEK( sbix_pos + strike_offset + 4 + glyph_index * 4 ) || - FT_FRAME_ENTER( 8 ) ) + if ( FT_STREAM_SEEK( face->ebdt_start + + strike_offset + 4 + + glyph_index * 4 ) || + FT_FRAME_ENTER( 8 ) ) return error; glyph_start = FT_GET_ULONG(); @@ -1318,14 +1514,14 @@ FT_FRAME_EXIT(); if ( glyph_start == glyph_end ) - return FT_THROW( Invalid_Argument ); - if ( glyph_start > glyph_end || - glyph_end - glyph_start < 8 || - table_size - strike_offset < glyph_end ) + return FT_THROW( Missing_Bitmap ); + if ( glyph_start > glyph_end || + glyph_end - glyph_start < 8 || + face->ebdt_size - strike_offset < glyph_end ) return FT_THROW( Invalid_File_Format ); - if ( FT_STREAM_SEEK( sbix_pos + strike_offset + glyph_start ) || - FT_FRAME_ENTER( glyph_end - glyph_start ) ) + if ( FT_STREAM_SEEK( face->ebdt_start + strike_offset + glyph_start ) || + FT_FRAME_ENTER( glyph_end - glyph_start ) ) return error; originOffsetX = FT_GET_SHORT(); @@ -1356,7 +1552,8 @@ stream->memory, stream->cursor, glyph_end - glyph_start - 8, - TRUE ); + TRUE, + metrics_only ); #else error = FT_THROW( Unimplemented_Feature ); #endif @@ -1416,22 +1613,27 @@ error = tt_sbit_decoder_init( decoder, face, strike_index, metrics ); if ( !error ) { - error = tt_sbit_decoder_load_image( decoder, - glyph_index, - 0, - 0 ); + error = tt_sbit_decoder_load_image( + decoder, + glyph_index, + 0, + 0, + 0, + ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) != 0 ); tt_sbit_decoder_done( decoder ); } } break; case TT_SBIT_TABLE_TYPE_SBIX: - error = tt_face_load_sbix_image( face, - strike_index, - glyph_index, - stream, - map, - metrics ); + error = tt_face_load_sbix_image( + face, + strike_index, + glyph_index, + stream, + map, + metrics, + ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) != 0 ); break; default: @@ -1440,9 +1642,10 @@ } /* Flatten color bitmaps if color was not requested. */ - if ( !error && - !( load_flags & FT_LOAD_COLOR ) && - map->pixel_mode == FT_PIXEL_MODE_BGRA ) + if ( !error && + !( load_flags & FT_LOAD_COLOR ) && + !( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) && + map->pixel_mode == FT_PIXEL_MODE_BGRA ) { FT_Bitmap new_map; FT_Library library = face->root.glyph->library; @@ -1468,5 +1671,12 @@ return error; } +#else /* !TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ -/* EOF */ + /* ANSI C doesn't like empty source files */ + typedef int _tt_sbit_dummy; + +#endif /* !TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + +/* END */ diff --git a/src/3rdparty/freetype/src/sfnt/ttsbit.h b/src/3rdparty/freetype/src/sfnt/ttsbit.h index d4e13aefb8..ce2af3c162 100644 --- a/src/3rdparty/freetype/src/sfnt/ttsbit.h +++ b/src/3rdparty/freetype/src/sfnt/ttsbit.h @@ -4,7 +4,7 @@ /* */ /* TrueType and OpenType embedded bitmap support (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTSBIT_H__ -#define __TTSBIT_H__ +#ifndef TTSBIT_H_ +#define TTSBIT_H_ #include <ft2build.h> @@ -57,7 +57,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTSBIT_H__ */ +#endif /* TTSBIT_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/smooth/Jamfile b/src/3rdparty/freetype/src/smooth/Jamfile index b1887c2c6e..9957d5e915 100644 --- a/src/3rdparty/freetype/src/smooth/Jamfile +++ b/src/3rdparty/freetype/src/smooth/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/smooth Jamfile # -# Copyright 2001-2015 by +# Copyright 2001-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/smooth/ftgrays.c b/src/3rdparty/freetype/src/smooth/ftgrays.c index ba2944559c..803a19e415 100644 --- a/src/3rdparty/freetype/src/smooth/ftgrays.c +++ b/src/3rdparty/freetype/src/smooth/ftgrays.c @@ -4,7 +4,7 @@ /* */ /* A new `perfect' anti-aliasing renderer (body). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,7 +18,7 @@ /*************************************************************************/ /* */ /* This file can be compiled without the rest of the FreeType engine, by */ - /* defining the _STANDALONE_ macro when compiling it. You also need to */ + /* defining the STANDALONE_ macro when compiling it. You also need to */ /* put the files `ftgrays.h' and `ftimage.h' into the current */ /* compilation directory. Typically, you could do something like */ /* */ @@ -27,9 +27,9 @@ /* - copy `include/freetype/ftimage.h' and `src/smooth/ftgrays.h' to the */ /* same directory */ /* */ - /* - compile `ftgrays' with the _STANDALONE_ macro defined, as in */ + /* - compile `ftgrays' with the STANDALONE_ macro defined, as in */ /* */ - /* cc -c -D_STANDALONE_ ftgrays.c */ + /* cc -c -DSTANDALONE_ ftgrays.c */ /* */ /* The renderer can be initialized with a call to */ /* `ft_gray_raster.raster_new'; an anti-aliased bitmap can be generated */ @@ -91,7 +91,7 @@ #define FT_COMPONENT trace_smooth -#ifdef _STANDALONE_ +#ifdef STANDALONE_ /* The size in bytes of the render pool used by the scan-line converter */ @@ -106,6 +106,7 @@ #define FT_BEGIN_STMNT do { #define FT_END_STMNT } while ( 0 ) +#define FT_MIN( a, b ) ( (a) < (b) ? (a) : (b) ) #define FT_MAX( a, b ) ( (a) > (b) ? (a) : (b) ) #define FT_ABS( a ) ( (a) < 0 ? -(a) : (a) ) @@ -135,8 +136,20 @@ #include <string.h> #include <setjmp.h> #include <limits.h> -#define FT_UINT_MAX UINT_MAX -#define FT_INT_MAX INT_MAX +#define FT_CHAR_BIT CHAR_BIT +#define FT_UINT_MAX UINT_MAX +#define FT_INT_MAX INT_MAX +#define FT_ULONG_MAX ULONG_MAX + +#define ADD_LONG( a, b ) \ + (long)( (unsigned long)(a) + (unsigned long)(b) ) +#define SUB_LONG( a, b ) \ + (long)( (unsigned long)(a) - (unsigned long)(b) ) +#define MUL_LONG( a, b ) \ + (long)( (unsigned long)(a) * (unsigned long)(b) ) +#define NEG_LONG( a ) \ + (long)( -(unsigned long)(a) ) + #define ft_memset memset @@ -254,13 +267,14 @@ typedef ptrdiff_t FT_PtrDist; }; -#else /* !_STANDALONE_ */ +#else /* !STANDALONE_ */ #include <ft2build.h> #include "ftgrays.h" #include FT_INTERNAL_OBJECTS_H #include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H #include FT_OUTLINE_H #include "ftsmerrs.h" @@ -272,7 +286,7 @@ typedef ptrdiff_t FT_PtrDist; #define ErrRaster_Memory_Overflow Smooth_Err_Out_Of_Memory -#endif /* !_STANDALONE_ */ +#endif /* !STANDALONE_ */ #ifndef FT_MEM_SET @@ -281,6 +295,10 @@ typedef ptrdiff_t FT_PtrDist; #ifndef FT_MEM_ZERO #define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) +#endif + +#ifndef FT_ZERO +#define FT_ZERO( p ) FT_MEM_ZERO( p, sizeof ( *(p) ) ) #endif /* as usual, for the speed hungry :-) */ @@ -300,7 +318,7 @@ typedef ptrdiff_t FT_PtrDist; #else /* FT_STATIC_RASTER */ -#define RAS_ARG /* empty */ +#define RAS_ARG void #define RAS_ARG_ /* empty */ #define RAS_VAR /* empty */ #define RAS_VAR_ /* empty */ @@ -316,25 +334,26 @@ typedef ptrdiff_t FT_PtrDist; #undef TRUNC #undef SCALED -#define ONE_PIXEL ( 1L << PIXEL_BITS ) +#define ONE_PIXEL ( 1 << PIXEL_BITS ) #define TRUNC( x ) ( (TCoord)( (x) >> PIXEL_BITS ) ) -#define SUBPIXELS( x ) ( (TPos)(x) << PIXEL_BITS ) +#define SUBPIXELS( x ) ( (TPos)(x) * ONE_PIXEL ) #define FLOOR( x ) ( (x) & -ONE_PIXEL ) #define CEILING( x ) ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL ) #define ROUND( x ) ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL ) #if PIXEL_BITS >= 6 -#define UPSCALE( x ) ( (x) << ( PIXEL_BITS - 6 ) ) +#define UPSCALE( x ) ( (x) * ( ONE_PIXEL >> 6 ) ) #define DOWNSCALE( x ) ( (x) >> ( PIXEL_BITS - 6 ) ) #else #define UPSCALE( x ) ( (x) >> ( 6 - PIXEL_BITS ) ) -#define DOWNSCALE( x ) ( (x) << ( 6 - PIXEL_BITS ) ) +#define DOWNSCALE( x ) ( (x) * ( 64 >> PIXEL_BITS ) ) #endif /* Compute `dividend / divisor' and return both its quotient and */ /* remainder, cast to a specific type. This macro also ensures that */ - /* the remainder is always positive. */ + /* the remainder is always positive. We use the remainder to keep */ + /* track of accumulating errors and compensate for them. */ #define FT_DIV_MOD( type, dividend, divisor, quotient, remainder ) \ FT_BEGIN_STMNT \ (quotient) = (type)( (dividend) / (divisor) ); \ @@ -351,7 +370,7 @@ typedef ptrdiff_t FT_PtrDist; /* optimize a division and modulo operation on the same parameters */ /* into a single call to `__aeabi_idivmod'. See */ /* */ - /* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43721 */ + /* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43721 */ #undef FT_DIV_MOD #define FT_DIV_MOD( type, dividend, divisor, quotient, remainder ) \ FT_BEGIN_STMNT \ @@ -366,6 +385,16 @@ typedef ptrdiff_t FT_PtrDist; #endif /* __arm__ */ + /* These macros speed up repetitive divisions by replacing them */ + /* with multiplications and right shifts. */ +#define FT_UDIVPREP( c, b ) \ + long b ## _r = c ? (long)( FT_ULONG_MAX >> PIXEL_BITS ) / ( b ) \ + : 0 +#define FT_UDIV( a, b ) \ + ( ( (unsigned long)( a ) * (unsigned long)( b ## _r ) ) >> \ + ( sizeof( long ) * FT_CHAR_BIT - PIXEL_BITS ) ) + + /*************************************************************************/ /* */ /* TYPE DEFINITIONS */ @@ -375,44 +404,36 @@ typedef ptrdiff_t FT_PtrDist; /* need to define them to "float" or "double" when experimenting with */ /* new algorithms */ - typedef long TCoord; /* integer scanline/pixel coordinate */ - typedef long TPos; /* sub-pixel coordinate */ - - /* determine the type used to store cell areas. This normally takes at */ - /* least PIXEL_BITS*2 + 1 bits. On 16-bit systems, we need to use */ - /* `long' instead of `int', otherwise bad things happen */ - -#if PIXEL_BITS <= 7 - - typedef int TArea; - -#else /* PIXEL_BITS >= 8 */ - - /* approximately determine the size of integers using an ANSI-C header */ -#if FT_UINT_MAX == 0xFFFFU - typedef long TArea; -#else - typedef int TArea; -#endif - -#endif /* PIXEL_BITS >= 8 */ - - - /* maximum number of gray spans in a call to the span callback */ -#define FT_MAX_GRAY_SPANS 32 + typedef long TPos; /* subpixel coordinate */ + typedef int TCoord; /* integer scanline/pixel coordinate */ + typedef int TArea; /* cell areas, coordinate products */ typedef struct TCell_* PCell; typedef struct TCell_ { - TPos x; /* same with gray_TWorker.ex */ + TCoord x; /* same with gray_TWorker.ex */ TCoord cover; /* same with gray_TWorker.cover */ TArea area; PCell next; } TCell; + typedef struct TPixmap_ + { + unsigned char* origin; /* pixmap origin at the bottom-left */ + int pitch; /* pitch to go down one row */ + + } TPixmap; + + /* maximum number of gray cells in the buffer */ +#if FT_RENDER_POOL_SIZE > 2048 +#define FT_MAX_GRAY_POOL ( FT_RENDER_POOL_SIZE / sizeof ( TCell ) ) +#else +#define FT_MAX_GRAY_POOL ( 2048 / sizeof ( TCell ) ) +#endif + #if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ /* We disable the warning `structure was padded due to */ @@ -427,42 +448,25 @@ typedef ptrdiff_t FT_PtrDist; ft_jmp_buf jump_buffer; TCoord ex, ey; - TPos min_ex, max_ex; - TPos min_ey, max_ey; - TPos count_ex, count_ey; + TCoord min_ex, max_ex; + TCoord min_ey, max_ey; TArea area; TCoord cover; int invalid; + PCell* ycells; PCell cells; FT_PtrDist max_cells; FT_PtrDist num_cells; TPos x, y; - FT_Vector bez_stack[32 * 3 + 1]; - int lev_stack[32]; - FT_Outline outline; - FT_Bitmap target; - FT_BBox clip_box; - - FT_Span gray_spans[FT_MAX_GRAY_SPANS]; - int num_gray_spans; + TPixmap target; FT_Raster_Span_Func render_span; void* render_span_data; - int span_y; - - int band_size; - int band_shoot; - - void* buffer; - long buffer_size; - - PCell* ycells; - TPos ycount; } gray_TWorker, *gray_PWorker; @@ -485,95 +489,53 @@ typedef ptrdiff_t FT_PtrDist; } gray_TRaster, *gray_PRaster; +#ifdef FT_DEBUG_LEVEL_TRACE - /*************************************************************************/ - /* */ - /* Initialize the cells table. */ - /* */ + /* to be called while in the debugger -- */ + /* this function causes a compiler warning since it is unused otherwise */ static void - gray_init_cells( RAS_ARG_ void* buffer, - long byte_size ) + gray_dump_cells( RAS_ARG ) { - ras.buffer = buffer; - ras.buffer_size = byte_size; + int y; - ras.ycells = (PCell*) buffer; - ras.cells = NULL; - ras.max_cells = 0; - ras.num_cells = 0; - ras.area = 0; - ras.cover = 0; - ras.invalid = 1; + + for ( y = ras.min_ey; y < ras.max_ey; y++ ) + { + PCell cell = ras.ycells[y - ras.min_ey]; + + + printf( "%3d:", y ); + + for ( ; cell != NULL; cell = cell->next ) + printf( " (%3d, c:%4d, a:%6d)", + cell->x, cell->cover, cell->area ); + printf( "\n" ); + } } - - /*************************************************************************/ - /* */ - /* Compute the outline bounding box. */ - /* */ - static void - gray_compute_cbox( RAS_ARG ) - { - FT_Outline* outline = &ras.outline; - FT_Vector* vec = outline->points; - FT_Vector* limit = vec + outline->n_points; - - - if ( outline->n_points <= 0 ) - { - ras.min_ex = ras.max_ex = 0; - ras.min_ey = ras.max_ey = 0; - return; - } - - ras.min_ex = ras.max_ex = vec->x; - ras.min_ey = ras.max_ey = vec->y; - - vec++; - - for ( ; vec < limit; vec++ ) - { - TPos x = vec->x; - TPos y = vec->y; - - - if ( x < ras.min_ex ) ras.min_ex = x; - if ( x > ras.max_ex ) ras.max_ex = x; - if ( y < ras.min_ey ) ras.min_ey = y; - if ( y > ras.max_ey ) ras.max_ey = y; - } - - /* truncate the bounding box to integer pixels */ - ras.min_ex = ras.min_ex >> 6; - ras.min_ey = ras.min_ey >> 6; - ras.max_ex = ( ras.max_ex + 63 ) >> 6; - ras.max_ey = ( ras.max_ey + 63 ) >> 6; - } +#endif /* FT_DEBUG_LEVEL_TRACE */ /*************************************************************************/ /* */ /* Record the current cell in the table. */ /* */ - static PCell - gray_find_cell( RAS_ARG ) + static void + gray_record_cell( RAS_ARG ) { PCell *pcell, cell; - TPos x = ras.ex; + TCoord x = ras.ex; - if ( x > ras.count_ex ) - x = ras.count_ex; - - pcell = &ras.ycells[ras.ey]; + pcell = &ras.ycells[ras.ey - ras.min_ey]; for (;;) { cell = *pcell; - if ( cell == NULL || cell->x > x ) + if ( !cell || cell->x > x ) break; if ( cell->x == x ) - goto Exit; + goto Found; pcell = &cell->next; } @@ -581,30 +543,21 @@ typedef ptrdiff_t FT_PtrDist; if ( ras.num_cells >= ras.max_cells ) ft_longjmp( ras.jump_buffer, 1 ); + /* insert new cell */ cell = ras.cells + ras.num_cells++; cell->x = x; - cell->area = 0; - cell->cover = 0; + cell->area = ras.area; + cell->cover = ras.cover; cell->next = *pcell; *pcell = cell; - Exit: - return cell; - } + return; - - static void - gray_record_cell( RAS_ARG ) - { - if ( ras.area | ras.cover ) - { - PCell cell = gray_find_cell( RAS_VAR ); - - - cell->area += ras.area; - cell->cover += ras.cover; - } + Found: + /* update old cell */ + cell->area += ras.area; + cell->cover += ras.cover; } @@ -626,59 +579,25 @@ typedef ptrdiff_t FT_PtrDist; /* Note that if a cell is to the left of the clipping region, it is */ /* actually set to the (min_ex-1) horizontal position. */ - /* All cells that are on the left of the clipping region go to the */ - /* min_ex - 1 horizontal position. */ - ey -= ras.min_ey; - - if ( ex > ras.max_ex ) - ex = ras.max_ex; - - ex -= ras.min_ex; - if ( ex < 0 ) - ex = -1; - - /* are we moving to a different cell ? */ - if ( ex != ras.ex || ey != ras.ey ) - { - /* record the current one if it is valid */ - if ( !ras.invalid ) - gray_record_cell( RAS_VAR ); - - ras.area = 0; - ras.cover = 0; - ras.ex = ex; - ras.ey = ey; - } - - ras.invalid = ( (unsigned int)ey >= (unsigned int)ras.count_ey || - ex >= ras.count_ex ); - } - - - /*************************************************************************/ - /* */ - /* Start a new contour at a given cell. */ - /* */ - static void - gray_start_cell( RAS_ARG_ TCoord ex, - TCoord ey ) - { - if ( ex > ras.max_ex ) - ex = (TCoord)( ras.max_ex ); - if ( ex < ras.min_ex ) - ex = (TCoord)( ras.min_ex - 1 ); + ex = ras.min_ex - 1; - ras.area = 0; - ras.cover = 0; - ras.ex = ex - ras.min_ex; - ras.ey = ey - ras.min_ey; - ras.invalid = 0; + /* record the current one if it is valid and substantial */ + if ( !ras.invalid && ( ras.area || ras.cover ) ) + gray_record_cell( RAS_VAR ); - gray_set_cell( RAS_VAR_ ex, ey ); + ras.area = 0; + ras.cover = 0; + ras.ex = ex; + ras.ey = ey; + + ras.invalid = ( ey >= ras.max_ey || ey < ras.min_ey || + ex >= ras.max_ex ); } +#ifndef FT_LONG64 + /*************************************************************************/ /* */ /* Render a scanline as one or more cells. */ @@ -690,17 +609,13 @@ typedef ptrdiff_t FT_PtrDist; TPos x2, TCoord y2 ) { - TCoord ex1, ex2, fx1, fx2, delta, mod; - long p, first, dx; + TCoord ex1, ex2, fx1, fx2, first, dy, delta, mod; + TPos p, dx; int incr; - dx = x2 - x1; - ex1 = TRUNC( x1 ); ex2 = TRUNC( x2 ); - fx1 = (TCoord)( x1 - SUBPIXELS( ex1 ) ); - fx2 = (TCoord)( x2 - SUBPIXELS( ex2 ) ); /* trivial case. Happens often */ if ( y1 == y2 ) @@ -709,26 +624,29 @@ typedef ptrdiff_t FT_PtrDist; return; } + fx1 = (TCoord)( x1 - SUBPIXELS( ex1 ) ); + fx2 = (TCoord)( x2 - SUBPIXELS( ex2 ) ); + /* everything is located in a single cell. That is easy! */ /* */ if ( ex1 == ex2 ) - { - delta = y2 - y1; - ras.area += (TArea)(( fx1 + fx2 ) * delta); - ras.cover += delta; - return; - } + goto End; /* ok, we'll have to render a run of adjacent cells on the same */ /* scanline... */ /* */ - p = ( ONE_PIXEL - fx1 ) * ( y2 - y1 ); - first = ONE_PIXEL; - incr = 1; + dx = x2 - x1; + dy = y2 - y1; - if ( dx < 0 ) + if ( dx > 0 ) { - p = fx1 * ( y2 - y1 ); + p = ( ONE_PIXEL - fx1 ) * dy; + first = ONE_PIXEL; + incr = 1; + } + else + { + p = fx1 * dy; first = 0; incr = -1; dx = -dx; @@ -736,34 +654,31 @@ typedef ptrdiff_t FT_PtrDist; FT_DIV_MOD( TCoord, p, dx, delta, mod ); - ras.area += (TArea)(( fx1 + first ) * delta); + ras.area += (TArea)( ( fx1 + first ) * delta ); ras.cover += delta; - - ex1 += incr; + y1 += delta; + ex1 += incr; gray_set_cell( RAS_VAR_ ex1, ey ); - y1 += delta; if ( ex1 != ex2 ) { TCoord lift, rem; - p = ONE_PIXEL * ( y2 - y1 + delta ); + p = ONE_PIXEL * dy; FT_DIV_MOD( TCoord, p, dx, lift, rem ); - mod -= (int)dx; - do { delta = lift; mod += rem; - if ( mod >= 0 ) + if ( mod >= (TCoord)dx ) { mod -= (TCoord)dx; delta++; } - ras.area += (TArea)(ONE_PIXEL * delta); + ras.area += (TArea)( ONE_PIXEL * delta ); ras.cover += delta; y1 += delta; ex1 += incr; @@ -771,9 +686,13 @@ typedef ptrdiff_t FT_PtrDist; } while ( ex1 != ex2 ); } - delta = y2 - y1; - ras.area += (TArea)(( fx2 + ONE_PIXEL - first ) * delta); - ras.cover += delta; + fx1 = ONE_PIXEL - first; + + End: + dy = y2 - y1; + + ras.area += (TArea)( ( fx1 + fx2 ) * dy ); + ras.cover += dy; } @@ -785,25 +704,22 @@ typedef ptrdiff_t FT_PtrDist; gray_render_line( RAS_ARG_ TPos to_x, TPos to_y ) { - TCoord ey1, ey2, fy1, fy2, mod; - TPos dx, dy, x, x2; - long p, first; - int delta, rem, lift, incr; + TCoord ey1, ey2, fy1, fy2, first, delta, mod; + TPos p, dx, dy, x, x2; + int incr; ey1 = TRUNC( ras.y ); ey2 = TRUNC( to_y ); /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */ - fy1 = (TCoord)( ras.y - SUBPIXELS( ey1 ) ); - fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) ); - - dx = to_x - ras.x; - dy = to_y - ras.y; /* perform vertical clipping */ if ( ( ey1 >= ras.max_ey && ey2 >= ras.max_ey ) || ( ey1 < ras.min_ey && ey2 < ras.min_ey ) ) goto End; + fy1 = (TCoord)( ras.y - SUBPIXELS( ey1 ) ); + fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) ); + /* everything is on a single scanline */ if ( ey1 == ey2 ) { @@ -811,9 +727,10 @@ typedef ptrdiff_t FT_PtrDist; goto End; } - /* vertical line - avoid calling gray_render_scanline */ - incr = 1; + dx = to_x - ras.x; + dy = to_y - ras.y; + /* vertical line - avoid calling gray_render_scanline */ if ( dx == 0 ) { TCoord ex = TRUNC( ras.x ); @@ -821,21 +738,25 @@ typedef ptrdiff_t FT_PtrDist; TArea area; - first = ONE_PIXEL; - if ( dy < 0 ) + if ( dy > 0) + { + first = ONE_PIXEL; + incr = 1; + } + else { first = 0; incr = -1; } - delta = (int)( first - fy1 ); + delta = first - fy1; ras.area += (TArea)two_fx * delta; ras.cover += delta; ey1 += incr; gray_set_cell( RAS_VAR_ ex, ey1 ); - delta = (int)( first + first - ONE_PIXEL ); + delta = first + first - ONE_PIXEL; area = (TArea)two_fx * delta; while ( ey1 != ey2 ) { @@ -846,7 +767,7 @@ typedef ptrdiff_t FT_PtrDist; gray_set_cell( RAS_VAR_ ex, ey1 ); } - delta = (int)( fy2 - ONE_PIXEL + first ); + delta = fy2 - ONE_PIXEL + first; ras.area += (TArea)two_fx * delta; ras.cover += delta; @@ -854,11 +775,13 @@ typedef ptrdiff_t FT_PtrDist; } /* ok, we have to render several scanlines */ - p = ( ONE_PIXEL - fy1 ) * dx; - first = ONE_PIXEL; - incr = 1; - - if ( dy < 0 ) + if ( dy > 0) + { + p = ( ONE_PIXEL - fy1 ) * dx; + first = ONE_PIXEL; + incr = 1; + } + else { p = fy1 * dx; first = 0; @@ -866,34 +789,36 @@ typedef ptrdiff_t FT_PtrDist; dy = -dy; } - FT_DIV_MOD( int, p, dy, delta, mod ); + FT_DIV_MOD( TCoord, p, dy, delta, mod ); x = ras.x + delta; - gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, (TCoord)first ); + gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, first ); ey1 += incr; gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 ); if ( ey1 != ey2 ) { - p = ONE_PIXEL * dx; - FT_DIV_MOD( int, p, dy, lift, rem ); - mod -= (int)dy; + TCoord lift, rem; + + + p = ONE_PIXEL * dx; + FT_DIV_MOD( TCoord, p, dy, lift, rem ); do { delta = lift; mod += rem; - if ( mod >= 0 ) + if ( mod >= (TCoord)dy ) { - mod -= (int)dy; + mod -= (TCoord)dy; delta++; } x2 = x + delta; - gray_render_scanline( RAS_VAR_ ey1, x, - (TCoord)( ONE_PIXEL - first ), x2, - (TCoord)first ); + gray_render_scanline( RAS_VAR_ ey1, + x, ONE_PIXEL - first, + x2, first ); x = x2; ey1 += incr; @@ -901,15 +826,153 @@ typedef ptrdiff_t FT_PtrDist; } while ( ey1 != ey2 ); } - gray_render_scanline( RAS_VAR_ ey1, x, - (TCoord)( ONE_PIXEL - first ), to_x, - fy2 ); + gray_render_scanline( RAS_VAR_ ey1, + x, ONE_PIXEL - first, + to_x, fy2 ); End: ras.x = to_x; ras.y = to_y; } +#else + + /*************************************************************************/ + /* */ + /* Render a straight line across multiple cells in any direction. */ + /* */ + static void + gray_render_line( RAS_ARG_ TPos to_x, + TPos to_y ) + { + TPos dx, dy, fx1, fy1, fx2, fy2; + TCoord ex1, ex2, ey1, ey2; + + + ey1 = TRUNC( ras.y ); + ey2 = TRUNC( to_y ); + + /* perform vertical clipping */ + if ( ( ey1 >= ras.max_ey && ey2 >= ras.max_ey ) || + ( ey1 < ras.min_ey && ey2 < ras.min_ey ) ) + goto End; + + ex1 = TRUNC( ras.x ); + ex2 = TRUNC( to_x ); + + fx1 = ras.x - SUBPIXELS( ex1 ); + fy1 = ras.y - SUBPIXELS( ey1 ); + + dx = to_x - ras.x; + dy = to_y - ras.y; + + if ( ex1 == ex2 && ey1 == ey2 ) /* inside one cell */ + ; + else if ( dy == 0 ) /* ex1 != ex2 */ /* any horizontal line */ + { + ex1 = ex2; + gray_set_cell( RAS_VAR_ ex1, ey1 ); + } + else if ( dx == 0 ) + { + if ( dy > 0 ) /* vertical line up */ + do + { + fy2 = ONE_PIXEL; + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * fx1 * 2; + fy1 = 0; + ey1++; + gray_set_cell( RAS_VAR_ ex1, ey1 ); + } while ( ey1 != ey2 ); + else /* vertical line down */ + do + { + fy2 = 0; + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * fx1 * 2; + fy1 = ONE_PIXEL; + ey1--; + gray_set_cell( RAS_VAR_ ex1, ey1 ); + } while ( ey1 != ey2 ); + } + else /* any other line */ + { + TPos prod = dx * fy1 - dy * fx1; + FT_UDIVPREP( ex1 != ex2, dx ); + FT_UDIVPREP( ey1 != ey2, dy ); + + + /* The fundamental value `prod' determines which side and the */ + /* exact coordinate where the line exits current cell. It is */ + /* also easily updated when moving from one cell to the next. */ + do + { + if ( prod <= 0 && + prod - dx * ONE_PIXEL > 0 ) /* left */ + { + fx2 = 0; + fy2 = (TPos)FT_UDIV( -prod, -dx ); + prod -= dy * ONE_PIXEL; + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); + fx1 = ONE_PIXEL; + fy1 = fy2; + ex1--; + } + else if ( prod - dx * ONE_PIXEL <= 0 && + prod - dx * ONE_PIXEL + dy * ONE_PIXEL > 0 ) /* up */ + { + prod -= dx * ONE_PIXEL; + fx2 = (TPos)FT_UDIV( -prod, dy ); + fy2 = ONE_PIXEL; + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); + fx1 = fx2; + fy1 = 0; + ey1++; + } + else if ( prod - dx * ONE_PIXEL + dy * ONE_PIXEL <= 0 && + prod + dy * ONE_PIXEL >= 0 ) /* right */ + { + prod += dy * ONE_PIXEL; + fx2 = ONE_PIXEL; + fy2 = (TPos)FT_UDIV( prod, dx ); + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); + fx1 = 0; + fy1 = fy2; + ex1++; + } + else /* ( prod + dy * ONE_PIXEL < 0 && + prod > 0 ) down */ + { + fx2 = (TPos)FT_UDIV( prod, -dy ); + fy2 = 0; + prod += dx * ONE_PIXEL; + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); + fx1 = fx2; + fy1 = ONE_PIXEL; + ey1--; + } + + gray_set_cell( RAS_VAR_ ex1, ey1 ); + } while ( ex1 != ex2 || ey1 != ey2 ); + } + + fx2 = to_x - SUBPIXELS( ex2 ); + fy2 = to_y - SUBPIXELS( ey2 ); + + ras.cover += ( fy2 - fy1 ); + ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); + + End: + ras.x = to_x; + ras.y = to_y; + } + +#endif static void gray_split_conic( FT_Vector* base ) @@ -935,73 +998,64 @@ typedef ptrdiff_t FT_PtrDist; gray_render_conic( RAS_ARG_ const FT_Vector* control, const FT_Vector* to ) { + FT_Vector bez_stack[16 * 2 + 1]; /* enough to accommodate bisections */ + FT_Vector* arc = bez_stack; TPos dx, dy; - TPos min, max, y; - int top, level; - int* levels; - FT_Vector* arc; + int draw, split; - levels = ras.lev_stack; - - arc = ras.bez_stack; arc[0].x = UPSCALE( to->x ); arc[0].y = UPSCALE( to->y ); arc[1].x = UPSCALE( control->x ); arc[1].y = UPSCALE( control->y ); arc[2].x = ras.x; arc[2].y = ras.y; - top = 0; + + /* short-cut the arc that crosses the current band */ + if ( ( TRUNC( arc[0].y ) >= ras.max_ey && + TRUNC( arc[1].y ) >= ras.max_ey && + TRUNC( arc[2].y ) >= ras.max_ey ) || + ( TRUNC( arc[0].y ) < ras.min_ey && + TRUNC( arc[1].y ) < ras.min_ey && + TRUNC( arc[2].y ) < ras.min_ey ) ) + { + ras.x = arc[0].x; + ras.y = arc[0].y; + return; + } dx = FT_ABS( arc[2].x + arc[0].x - 2 * arc[1].x ); dy = FT_ABS( arc[2].y + arc[0].y - 2 * arc[1].y ); if ( dx < dy ) dx = dy; - if ( dx < ONE_PIXEL / 4 ) - goto Draw; + /* We can calculate the number of necessary bisections because */ + /* each bisection predictably reduces deviation exactly 4-fold. */ + /* Even 32-bit deviation would vanish after 16 bisections. */ + draw = 1; + while ( dx > ONE_PIXEL / 4 ) + { + dx >>= 2; + draw <<= 1; + } - /* short-cut the arc that crosses the current band */ - min = max = arc[0].y; - - y = arc[1].y; - if ( y < min ) min = y; - if ( y > max ) max = y; - - y = arc[2].y; - if ( y < min ) min = y; - if ( y > max ) max = y; - - if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey ) - goto Draw; - - level = 0; + /* We use decrement counter to count the total number of segments */ + /* to draw starting from 2^level. Before each draw we split as */ + /* many times as there are trailing zeros in the counter. */ do { - dx >>= 2; - level++; - } while ( dx > ONE_PIXEL / 4 ); - - levels[0] = level; - - do - { - level = levels[top]; - if ( level > 0 ) + split = 1; + while ( ( draw & split ) == 0 ) { gray_split_conic( arc ); arc += 2; - top++; - levels[top] = levels[top - 1] = level - 1; - continue; + split <<= 1; } - Draw: gray_render_line( RAS_VAR_ arc[0].x, arc[0].y ); - top--; arc -= 2; - } while ( top >= 0 ); + } while ( --draw ); } @@ -1038,11 +1092,13 @@ typedef ptrdiff_t FT_PtrDist; const FT_Vector* control2, const FT_Vector* to ) { - FT_Vector* arc; - TPos min, max, y; + FT_Vector bez_stack[16 * 3 + 1]; /* enough to accommodate bisections */ + FT_Vector* arc = bez_stack; + TPos dx, dy, dx_, dy_; + TPos dx1, dy1, dx2, dy2; + TPos L, s, s_limit; - arc = ras.bez_stack; arc[0].x = UPSCALE( to->x ); arc[0].y = UPSCALE( to->y ); arc[1].x = UPSCALE( control2->x ); @@ -1052,29 +1108,20 @@ typedef ptrdiff_t FT_PtrDist; arc[3].x = ras.x; arc[3].y = ras.y; - /* Short-cut the arc that crosses the current band. */ - min = max = arc[0].y; - - y = arc[1].y; - if ( y < min ) - min = y; - if ( y > max ) - max = y; - - y = arc[2].y; - if ( y < min ) - min = y; - if ( y > max ) - max = y; - - y = arc[3].y; - if ( y < min ) - min = y; - if ( y > max ) - max = y; - - if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey ) - goto Draw; + /* short-cut the arc that crosses the current band */ + if ( ( TRUNC( arc[0].y ) >= ras.max_ey && + TRUNC( arc[1].y ) >= ras.max_ey && + TRUNC( arc[2].y ) >= ras.max_ey && + TRUNC( arc[3].y ) >= ras.max_ey ) || + ( TRUNC( arc[0].y ) < ras.min_ey && + TRUNC( arc[1].y ) < ras.min_ey && + TRUNC( arc[2].y ) < ras.min_ey && + TRUNC( arc[3].y ) < ras.min_ey ) ) + { + ras.x = arc[0].x; + ras.y = arc[0].y; + return; + } for (;;) { @@ -1083,64 +1130,53 @@ typedef ptrdiff_t FT_PtrDist; /* F. Hain, at */ /* http://www.cis.southalabama.edu/~hain/general/Publications/Bezier/Camera-ready%20CISST02%202.pdf */ - { - TPos dx, dy, dx_, dy_; - TPos dx1, dy1, dx2, dy2; - TPos L, s, s_limit; + /* dx and dy are x and y components of the P0-P3 chord vector. */ + dx = dx_ = arc[3].x - arc[0].x; + dy = dy_ = arc[3].y - arc[0].y; + L = FT_HYPOT( dx_, dy_ ); - /* dx and dy are x and y components of the P0-P3 chord vector. */ - dx = dx_ = arc[3].x - arc[0].x; - dy = dy_ = arc[3].y - arc[0].y; + /* Avoid possible arithmetic overflow below by splitting. */ + if ( L > 32767 ) + goto Split; - L = FT_HYPOT( dx_, dy_ ); + /* Max deviation may be as much as (s/L) * 3/4 (if Hain's v = 1). */ + s_limit = L * (TPos)( ONE_PIXEL / 6 ); - /* Avoid possible arithmetic overflow below by splitting. */ - if ( L > 32767 ) - goto Split; + /* s is L * the perpendicular distance from P1 to the line P0-P3. */ + dx1 = arc[1].x - arc[0].x; + dy1 = arc[1].y - arc[0].y; + s = FT_ABS( SUB_LONG( MUL_LONG( dy, dx1 ), MUL_LONG( dx, dy1 ) ) ); - /* Max deviation may be as much as (s/L) * 3/4 (if Hain's v = 1). */ - s_limit = L * (TPos)( ONE_PIXEL / 6 ); + if ( s > s_limit ) + goto Split; - /* s is L * the perpendicular distance from P1 to the line P0-P3. */ - dx1 = arc[1].x - arc[0].x; - dy1 = arc[1].y - arc[0].y; - s = FT_ABS( dy * dx1 - dx * dy1 ); + /* s is L * the perpendicular distance from P2 to the line P0-P3. */ + dx2 = arc[2].x - arc[0].x; + dy2 = arc[2].y - arc[0].y; + s = FT_ABS( SUB_LONG( MUL_LONG( dy, dx2 ), MUL_LONG( dx, dy2 ) ) ); - if ( s > s_limit ) - goto Split; + if ( s > s_limit ) + goto Split; - /* s is L * the perpendicular distance from P2 to the line P0-P3. */ - dx2 = arc[2].x - arc[0].x; - dy2 = arc[2].y - arc[0].y; - s = FT_ABS( dy * dx2 - dx * dy2 ); + /* Split super curvy segments where the off points are so far + from the chord that the angles P0-P1-P3 or P0-P2-P3 become + acute as detected by appropriate dot products. */ + if ( dx1 * ( dx1 - dx ) + dy1 * ( dy1 - dy ) > 0 || + dx2 * ( dx2 - dx ) + dy2 * ( dy2 - dy ) > 0 ) + goto Split; - if ( s > s_limit ) - goto Split; + gray_render_line( RAS_VAR_ arc[0].x, arc[0].y ); - /* Split super curvy segments where the off points are so far - from the chord that the angles P0-P1-P3 or P0-P2-P3 become - acute as detected by appropriate dot products. */ - if ( dx1 * ( dx1 - dx ) + dy1 * ( dy1 - dy ) > 0 || - dx2 * ( dx2 - dx ) + dy2 * ( dy2 - dy ) > 0 ) - goto Split; + if ( arc == bez_stack ) + return; - /* No reason to split. */ - goto Draw; - } + arc -= 3; + continue; Split: gray_split_cubic( arc ); arc += 3; - continue; - - Draw: - gray_render_line( RAS_VAR_ arc[0].x, arc[0].y ); - - if ( arc == ras.bez_stack ) - return; - - arc -= 3; } } @@ -1152,18 +1188,14 @@ typedef ptrdiff_t FT_PtrDist; TPos x, y; - /* record current cell, if any */ - if ( !ras.invalid ) - gray_record_cell( RAS_VAR ); - /* start to a new position */ x = UPSCALE( to->x ); y = UPSCALE( to->y ); - gray_start_cell( RAS_VAR_ TRUNC( x ), TRUNC( y ) ); + gray_set_cell( RAS_VAR_ TRUNC( x ), TRUNC( y ) ); - worker->x = x; - worker->y = y; + ras.x = x; + ras.y = y; return 0; } @@ -1198,84 +1230,24 @@ typedef ptrdiff_t FT_PtrDist; } - static void - gray_render_span( int y, - int count, - const FT_Span* spans, - gray_PWorker worker ) - { - unsigned char* p; - FT_Bitmap* map = &worker->target; - - - /* first of all, compute the scanline offset */ - p = (unsigned char*)map->buffer - y * map->pitch; - if ( map->pitch >= 0 ) - p += ( map->rows - 1 ) * (unsigned int)map->pitch; - - for ( ; count > 0; count--, spans++ ) - { - unsigned char coverage = spans->coverage; - - - if ( coverage ) - { - /* For small-spans it is faster to do it by ourselves than - * calling `memset'. This is mainly due to the cost of the - * function call. - */ - if ( spans->len >= 8 ) - FT_MEM_SET( p + spans->x, (unsigned char)coverage, spans->len ); - else - { - unsigned char* q = p + spans->x; - - - switch ( spans->len ) - { - case 7: *q++ = (unsigned char)coverage; - case 6: *q++ = (unsigned char)coverage; - case 5: *q++ = (unsigned char)coverage; - case 4: *q++ = (unsigned char)coverage; - case 3: *q++ = (unsigned char)coverage; - case 2: *q++ = (unsigned char)coverage; - case 1: *q = (unsigned char)coverage; - default: - ; - } - } - } - } - } - - static void gray_hline( RAS_ARG_ TCoord x, TCoord y, - TPos area, + TArea coverage, TCoord acount ) { - int coverage; - - - /* compute the coverage line's coverage, depending on the */ - /* outline fill rule */ - /* */ - /* the coverage percentage is area/(PIXEL_BITS*PIXEL_BITS*2) */ - /* */ - coverage = (int)( area >> ( PIXEL_BITS * 2 + 1 - 8 ) ); - /* use range 0..256 */ + /* scale the coverage from 0..(ONE_PIXEL*ONE_PIXEL*2) to 0..256 */ + coverage >>= PIXEL_BITS * 2 + 1 - 8; if ( coverage < 0 ) - coverage = -coverage; + coverage = -coverage - 1; + /* compute the line's coverage depending on the outline fill rule */ if ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL ) { coverage &= 511; - if ( coverage > 256 ) - coverage = 512 - coverage; - else if ( coverage == 256 ) - coverage = 255; + if ( coverage >= 256 ) + coverage = 511 - coverage; } else { @@ -1284,179 +1256,83 @@ typedef ptrdiff_t FT_PtrDist; coverage = 255; } - y += (TCoord)ras.min_ey; - x += (TCoord)ras.min_ex; - - /* FT_Span.x is a 16-bit short, so limit our coordinates appropriately */ - if ( x >= 32767 ) - x = 32767; - - /* FT_Span.y is an integer, so limit our coordinates appropriately */ - if ( y >= FT_INT_MAX ) - y = FT_INT_MAX; - - if ( coverage ) + if ( ras.render_span ) /* for FT_RASTER_FLAG_DIRECT only */ { - FT_Span* span; - int count; + FT_Span span; - /* see whether we can add this span to the current list */ - count = ras.num_gray_spans; - span = ras.gray_spans + count - 1; - if ( count > 0 && - ras.span_y == y && - (int)span->x + span->len == (int)x && - span->coverage == coverage ) + span.x = (short)x; + span.len = (unsigned short)acount; + span.coverage = (unsigned char)coverage; + + ras.render_span( y, 1, &span, ras.render_span_data ); + } + else + { + unsigned char* q = ras.target.origin - ras.target.pitch * y + x; + unsigned char c = (unsigned char)coverage; + + + /* For small-spans it is faster to do it by ourselves than + * calling `memset'. This is mainly due to the cost of the + * function call. + */ + switch ( acount ) { - span->len = (unsigned short)( span->len + acount ); - return; + case 7: *q++ = c; + case 6: *q++ = c; + case 5: *q++ = c; + case 4: *q++ = c; + case 3: *q++ = c; + case 2: *q++ = c; + case 1: *q = c; + case 0: break; + default: + FT_MEM_SET( q, c, acount ); } - - if ( ras.span_y != y || count >= FT_MAX_GRAY_SPANS ) - { - if ( ras.render_span && count > 0 ) - ras.render_span( ras.span_y, count, ras.gray_spans, - ras.render_span_data ); - -#ifdef FT_DEBUG_LEVEL_TRACE - - if ( count > 0 ) - { - int n; - - - FT_TRACE7(( "y = %3d ", ras.span_y )); - span = ras.gray_spans; - for ( n = 0; n < count; n++, span++ ) - FT_TRACE7(( "[%d..%d]:%02x ", - span->x, span->x + span->len - 1, span->coverage )); - FT_TRACE7(( "\n" )); - } - -#endif /* FT_DEBUG_LEVEL_TRACE */ - - ras.num_gray_spans = 0; - ras.span_y = (int)y; - - span = ras.gray_spans; - } - else - span++; - - /* add a gray span to the current list */ - span->x = (short)x; - span->len = (unsigned short)acount; - span->coverage = (unsigned char)coverage; - - ras.num_gray_spans++; } } -#ifdef FT_DEBUG_LEVEL_TRACE - - /* to be called while in the debugger -- */ - /* this function causes a compiler warning since it is unused otherwise */ static void - gray_dump_cells( RAS_ARG ) + gray_sweep( RAS_ARG ) { - int yindex; + int y; - for ( yindex = 0; yindex < ras.ycount; yindex++ ) + for ( y = ras.min_ey; y < ras.max_ey; y++ ) { - PCell cell; - - - printf( "%3d:", yindex ); - - for ( cell = ras.ycells[yindex]; cell != NULL; cell = cell->next ) - printf( " (%3ld, c:%4ld, a:%6d)", cell->x, cell->cover, cell->area ); - printf( "\n" ); - } - } - -#endif /* FT_DEBUG_LEVEL_TRACE */ - - - static void - gray_sweep( RAS_ARG_ const FT_Bitmap* target ) - { - int yindex; - - FT_UNUSED( target ); - - - if ( ras.num_cells == 0 ) - return; - - ras.num_gray_spans = 0; - - FT_TRACE7(( "gray_sweep: start\n" )); - - for ( yindex = 0; yindex < ras.ycount; yindex++ ) - { - PCell cell = ras.ycells[yindex]; - TCoord cover = 0; - TCoord x = 0; + PCell cell = ras.ycells[y - ras.min_ey]; + TCoord x = ras.min_ex; + TArea cover = 0; + TArea area; for ( ; cell != NULL; cell = cell->next ) { - TPos area; + if ( cover != 0 && cell->x > x ) + gray_hline( RAS_VAR_ x, y, cover, cell->x - x ); + cover += (TArea)cell->cover * ( ONE_PIXEL * 2 ); + area = cover - cell->area; - if ( cell->x > x && cover != 0 ) - gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ), - cell->x - x ); - - cover += cell->cover; - area = cover * ( ONE_PIXEL * 2 ) - cell->area; - - if ( area != 0 && cell->x >= 0 ) - gray_hline( RAS_VAR_ cell->x, yindex, area, 1 ); + if ( area != 0 && cell->x >= ras.min_ex ) + gray_hline( RAS_VAR_ cell->x, y, area, 1 ); x = cell->x + 1; } if ( cover != 0 ) - gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ), - ras.count_ex - x ); + gray_hline( RAS_VAR_ x, y, cover, ras.max_ex - x ); } - - if ( ras.render_span && ras.num_gray_spans > 0 ) - ras.render_span( ras.span_y, ras.num_gray_spans, - ras.gray_spans, ras.render_span_data ); - -#ifdef FT_DEBUG_LEVEL_TRACE - - if ( ras.num_gray_spans > 0 ) - { - FT_Span* span; - int n; - - - FT_TRACE7(( "y = %3d ", ras.span_y )); - span = ras.gray_spans; - for ( n = 0; n < ras.num_gray_spans; n++, span++ ) - FT_TRACE7(( "[%d..%d]:%02x ", - span->x, span->x + span->len - 1, span->coverage )); - FT_TRACE7(( "\n" )); - } - - FT_TRACE7(( "gray_sweep: end\n" )); - -#endif /* FT_DEBUG_LEVEL_TRACE */ - } -#ifdef _STANDALONE_ +#ifdef STANDALONE_ /*************************************************************************/ /* */ - /* The following function should only compile in stand-alone mode, */ + /* The following functions should only compile in stand-alone mode, */ /* i.e., when building this component without the rest of FreeType. */ /* */ /*************************************************************************/ @@ -1727,32 +1603,102 @@ typedef ptrdiff_t FT_PtrDist; return 0; Exit: - FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error )); + FT_TRACE5(( "FT_Outline_Decompose: Error 0x%x\n", error )); return error; Invalid_Outline: return FT_THROW( Invalid_Outline ); } -#endif /* _STANDALONE_ */ + /*************************************************************************/ + /* */ + /* <Function> */ + /* FT_Outline_Get_CBox */ + /* */ + /* <Description> */ + /* Return an outline's `control box'. The control box encloses all */ + /* the outline's points, including Bézier control points. Though it */ + /* coincides with the exact bounding box for most glyphs, it can be */ + /* slightly larger in some situations (like when rotating an outline */ + /* that contains Bézier outside arcs). */ + /* */ + /* Computing the control box is very fast, while getting the bounding */ + /* box can take much more time as it needs to walk over all segments */ + /* and arcs in the outline. To get the latter, you can use the */ + /* `ftbbox' component, which is dedicated to this single task. */ + /* */ + /* <Input> */ + /* outline :: A pointer to the source outline descriptor. */ + /* */ + /* <Output> */ + /* acbox :: The outline's control box. */ + /* */ + /* <Note> */ + /* See @FT_Glyph_Get_CBox for a discussion of tricky fonts. */ + /* */ - typedef struct gray_TBand_ + static void + FT_Outline_Get_CBox( const FT_Outline* outline, + FT_BBox *acbox ) { - TPos min, max; + TPos xMin, yMin, xMax, yMax; - } gray_TBand; + + if ( outline && acbox ) + { + if ( outline->n_points == 0 ) + { + xMin = 0; + yMin = 0; + xMax = 0; + yMax = 0; + } + else + { + FT_Vector* vec = outline->points; + FT_Vector* limit = vec + outline->n_points; + + + xMin = xMax = vec->x; + yMin = yMax = vec->y; + vec++; + + for ( ; vec < limit; vec++ ) + { + TPos x, y; + + + x = vec->x; + if ( x < xMin ) xMin = x; + if ( x > xMax ) xMax = x; + + y = vec->y; + if ( y < yMin ) yMin = y; + if ( y > yMax ) yMax = y; + } + } + acbox->xMin = xMin; + acbox->xMax = xMax; + acbox->yMin = yMin; + acbox->yMax = yMax; + } + } + +#endif /* STANDALONE_ */ FT_DEFINE_OUTLINE_FUNCS( func_interface, - (FT_Outline_MoveTo_Func) gray_move_to, - (FT_Outline_LineTo_Func) gray_line_to, - (FT_Outline_ConicTo_Func)gray_conic_to, - (FT_Outline_CubicTo_Func)gray_cubic_to, - 0, - 0 ) + (FT_Outline_MoveTo_Func) gray_move_to, /* move_to */ + (FT_Outline_LineTo_Func) gray_line_to, /* line_to */ + (FT_Outline_ConicTo_Func)gray_conic_to, /* conic_to */ + (FT_Outline_CubicTo_Func)gray_cubic_to, /* cubic_to */ + + 0, /* shift */ + 0 /* delta */ + ) static int @@ -1771,10 +1717,21 @@ typedef ptrdiff_t FT_PtrDist; error = FT_Outline_Decompose( &ras.outline, &func_interface, &ras ); if ( !ras.invalid ) gray_record_cell( RAS_VAR ); + + FT_TRACE7(( "band [%d..%d]: %d cell%s\n", + ras.min_ey, + ras.max_ey, + ras.num_cells, + ras.num_cells == 1 ? "" : "s" )); } else + { error = FT_THROW( Memory_Overflow ); + FT_TRACE7(( "band [%d..%d]: to be bisected\n", + ras.min_ey, ras.max_ey )); + } + return error; } @@ -1782,158 +1739,108 @@ typedef ptrdiff_t FT_PtrDist; static int gray_convert_glyph( RAS_ARG ) { - gray_TBand bands[40]; - gray_TBand* volatile band; - int volatile n, num_bands; - TPos volatile min, max, max_y; - FT_BBox* clip; + const TCoord yMin = ras.min_ey; + const TCoord yMax = ras.max_ey; + const TCoord xMin = ras.min_ex; + const TCoord xMax = ras.max_ex; + TCell buffer[FT_MAX_GRAY_POOL]; + size_t height = (size_t)( yMax - yMin ); + size_t n = FT_MAX_GRAY_POOL / 8; + TCoord y; + TCoord bands[32]; /* enough to accommodate bisections */ + TCoord* band; - /* Set up state in the raster object */ - gray_compute_cbox( RAS_VAR ); - - /* clip to target bitmap, exit if nothing to do */ - clip = &ras.clip_box; - - if ( ras.max_ex <= clip->xMin || ras.min_ex >= clip->xMax || - ras.max_ey <= clip->yMin || ras.min_ey >= clip->yMax ) - return 0; - - if ( ras.min_ex < clip->xMin ) ras.min_ex = clip->xMin; - if ( ras.min_ey < clip->yMin ) ras.min_ey = clip->yMin; - - if ( ras.max_ex > clip->xMax ) ras.max_ex = clip->xMax; - if ( ras.max_ey > clip->yMax ) ras.max_ey = clip->yMax; - - ras.count_ex = ras.max_ex - ras.min_ex; - ras.count_ey = ras.max_ey - ras.min_ey; /* set up vertical bands */ - num_bands = (int)( ( ras.max_ey - ras.min_ey ) / ras.band_size ); - if ( num_bands == 0 ) - num_bands = 1; - if ( num_bands >= 39 ) - num_bands = 39; - - ras.band_shoot = 0; - - min = ras.min_ey; - max_y = ras.max_ey; - - for ( n = 0; n < num_bands; n++, min = max ) + if ( height > n ) { - max = min + ras.band_size; - if ( n == num_bands - 1 || max > max_y ) - max = max_y; + /* two divisions rounded up */ + n = ( height + n - 1 ) / n; + height = ( height + n - 1 ) / n; + } - bands[0].min = min; - bands[0].max = max; - band = bands; + /* memory management */ + n = ( height * sizeof ( PCell ) + sizeof ( TCell ) - 1 ) / sizeof ( TCell ); + + ras.cells = buffer + n; + ras.max_cells = (FT_PtrDist)( FT_MAX_GRAY_POOL - n ); + ras.ycells = (PCell*)buffer; + + for ( y = yMin; y < yMax; ) + { + ras.min_ey = y; + y += height; + ras.max_ey = FT_MIN( y, yMax ); + + band = bands; + band[1] = xMin; + band[0] = xMax; do { - TPos bottom, top, middle; - int error; - - { - PCell cells_max; - int yindex; - long cell_start, cell_end, cell_mod; + TCoord width = band[0] - band[1]; + int error; - ras.ycells = (PCell*)ras.buffer; - ras.ycount = band->max - band->min; - - cell_start = (long)sizeof ( PCell ) * ras.ycount; - cell_mod = cell_start % (long)sizeof ( TCell ); - if ( cell_mod > 0 ) - cell_start += (long)sizeof ( TCell ) - cell_mod; - - cell_end = ras.buffer_size; - cell_end -= cell_end % (long)sizeof ( TCell ); - - cells_max = (PCell)( (char*)ras.buffer + cell_end ); - ras.cells = (PCell)( (char*)ras.buffer + cell_start ); - if ( ras.cells >= cells_max ) - goto ReduceBands; - - ras.max_cells = cells_max - ras.cells; - if ( ras.max_cells < 2 ) - goto ReduceBands; - - for ( yindex = 0; yindex < ras.ycount; yindex++ ) - ras.ycells[yindex] = NULL; - } + FT_MEM_ZERO( ras.ycells, height * sizeof ( PCell ) ); ras.num_cells = 0; ras.invalid = 1; - ras.min_ey = band->min; - ras.max_ey = band->max; - ras.count_ey = band->max - band->min; + ras.min_ex = band[1]; + ras.max_ex = band[0]; error = gray_convert_glyph_inner( RAS_VAR ); if ( !error ) { - gray_sweep( RAS_VAR_ &ras.target ); + gray_sweep( RAS_VAR ); band--; continue; } else if ( error != ErrRaster_Memory_Overflow ) return 1; - ReduceBands: /* render pool overflow; we will reduce the render band by half */ - bottom = band->min; - top = band->max; - middle = bottom + ( ( top - bottom ) >> 1 ); + width >>= 1; - /* This is too complex for a single scanline; there must */ - /* be some problems. */ - if ( middle == bottom ) + /* this should never happen even with tiny rendering pool */ + if ( width == 0 ) { -#ifdef FT_DEBUG_LEVEL_TRACE FT_TRACE7(( "gray_convert_glyph: rotten glyph\n" )); -#endif return 1; } - if ( bottom-top >= ras.band_size ) - ras.band_shoot++; - - band[1].min = bottom; - band[1].max = middle; - band[0].min = middle; - band[0].max = top; band++; + band[1] = band[0]; + band[0] += width; } while ( band >= bands ); } - if ( ras.band_shoot > 8 && ras.band_size > 16 ) - ras.band_size = ras.band_size / 2; - return 0; } static int - gray_raster_render( gray_PRaster raster, + gray_raster_render( FT_Raster raster, const FT_Raster_Params* params ) { - const FT_Outline* outline = (const FT_Outline*)params->source; - const FT_Bitmap* target_map = params->target; + const FT_Outline* outline = (const FT_Outline*)params->source; + const FT_Bitmap* target_map = params->target; + FT_BBox cbox, clip; +#ifndef FT_STATIC_RASTER gray_TWorker worker[1]; - - TCell buffer[FT_MAX( FT_RENDER_POOL_SIZE, 2048 ) / sizeof ( TCell )]; - long buffer_size = sizeof ( buffer ); - int band_size = (int)( buffer_size / - (long)( sizeof ( TCell ) * 8 ) ); +#endif if ( !raster ) return FT_THROW( Invalid_Argument ); + /* this version does not support monochrome rendering */ + if ( !( params->flags & FT_RASTER_FLAG_AA ) ) + return FT_THROW( Invalid_Mode ); + if ( !outline ) return FT_THROW( Invalid_Outline ); @@ -1948,9 +1855,19 @@ typedef ptrdiff_t FT_PtrDist; outline->contours[outline->n_contours - 1] + 1 ) return FT_THROW( Invalid_Outline ); - /* if direct mode is not set, we must have a target bitmap */ - if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) ) + ras.outline = *outline; + + if ( params->flags & FT_RASTER_FLAG_DIRECT ) { + if ( !params->gray_spans ) + return 0; + + ras.render_span = (FT_Raster_Span_Func)params->gray_spans; + ras.render_span_data = params->user; + } + else + { + /* if direct mode is not set, we must have a target bitmap */ if ( !target_map ) return FT_THROW( Invalid_Argument ); @@ -1960,51 +1877,59 @@ typedef ptrdiff_t FT_PtrDist; if ( !target_map->buffer ) return FT_THROW( Invalid_Argument ); + + if ( target_map->pitch < 0 ) + ras.target.origin = target_map->buffer; + else + ras.target.origin = target_map->buffer + + ( target_map->rows - 1 ) * (unsigned int)target_map->pitch; + + ras.target.pitch = target_map->pitch; + + ras.render_span = (FT_Raster_Span_Func)NULL; + ras.render_span_data = NULL; } - /* this version does not support monochrome rendering */ - if ( !( params->flags & FT_RASTER_FLAG_AA ) ) - return FT_THROW( Invalid_Mode ); + FT_Outline_Get_CBox( outline, &cbox ); + + /* reject too large outline coordinates */ + if ( cbox.xMin < -0x1000000L || cbox.xMax > 0x1000000L || + cbox.yMin < -0x1000000L || cbox.yMax > 0x1000000L ) + return FT_THROW( Invalid_Outline ); + + /* truncate the bounding box to integer pixels */ + cbox.xMin = cbox.xMin >> 6; + cbox.yMin = cbox.yMin >> 6; + cbox.xMax = ( cbox.xMax + 63 ) >> 6; + cbox.yMax = ( cbox.yMax + 63 ) >> 6; /* compute clipping box */ if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) ) { /* compute clip box from target pixmap */ - ras.clip_box.xMin = 0; - ras.clip_box.yMin = 0; - ras.clip_box.xMax = (FT_Pos)target_map->width; - ras.clip_box.yMax = (FT_Pos)target_map->rows; + clip.xMin = 0; + clip.yMin = 0; + clip.xMax = (FT_Pos)target_map->width; + clip.yMax = (FT_Pos)target_map->rows; } else if ( params->flags & FT_RASTER_FLAG_CLIP ) - ras.clip_box = params->clip_box; + clip = params->clip_box; else { - ras.clip_box.xMin = -32768L; - ras.clip_box.yMin = -32768L; - ras.clip_box.xMax = 32767L; - ras.clip_box.yMax = 32767L; + clip.xMin = -32768L; + clip.yMin = -32768L; + clip.xMax = 32767L; + clip.yMax = 32767L; } - gray_init_cells( RAS_VAR_ buffer, buffer_size ); + /* clip to target bitmap, exit if nothing to do */ + ras.min_ex = FT_MAX( cbox.xMin, clip.xMin ); + ras.min_ey = FT_MAX( cbox.yMin, clip.yMin ); + ras.max_ex = FT_MIN( cbox.xMax, clip.xMax ); + ras.max_ey = FT_MIN( cbox.yMax, clip.yMax ); - ras.outline = *outline; - ras.num_cells = 0; - ras.invalid = 1; - ras.band_size = band_size; - ras.num_gray_spans = 0; - ras.span_y = 0; - - if ( params->flags & FT_RASTER_FLAG_DIRECT ) - { - ras.render_span = (FT_Raster_Span_Func)params->gray_spans; - ras.render_span_data = params->user; - } - else - { - ras.target = *target_map; - ras.render_span = (FT_Raster_Span_Func)gray_render_span; - ras.render_span_data = &ras; - } + if ( ras.max_ex <= ras.min_ex || ras.max_ey <= ras.min_ey ) + return 0; return gray_convert_glyph( RAS_VAR ); } @@ -2013,7 +1938,7 @@ typedef ptrdiff_t FT_PtrDist; /**** RASTER OBJECT CREATION: In stand-alone mode, we simply use *****/ /**** a static object. *****/ -#ifdef _STANDALONE_ +#ifdef STANDALONE_ static int gray_raster_new( void* memory, @@ -2025,7 +1950,7 @@ typedef ptrdiff_t FT_PtrDist; *araster = (FT_Raster)&the_raster; - FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) ); + FT_ZERO( &the_raster ); return 0; } @@ -2038,7 +1963,7 @@ typedef ptrdiff_t FT_PtrDist; FT_UNUSED( raster ); } -#else /* !_STANDALONE_ */ +#else /* !STANDALONE_ */ static int gray_raster_new( FT_Memory memory, @@ -2068,13 +1993,13 @@ typedef ptrdiff_t FT_PtrDist; FT_FREE( raster ); } -#endif /* !_STANDALONE_ */ +#endif /* !STANDALONE_ */ static void - gray_raster_reset( FT_Raster raster, - char* pool_base, - long pool_size ) + gray_raster_reset( FT_Raster raster, + unsigned char* pool_base, + unsigned long pool_size ) { FT_UNUSED( raster ); FT_UNUSED( pool_base ); @@ -2101,11 +2026,12 @@ typedef ptrdiff_t FT_PtrDist; FT_GLYPH_FORMAT_OUTLINE, - (FT_Raster_New_Func) gray_raster_new, - (FT_Raster_Reset_Func) gray_raster_reset, - (FT_Raster_Set_Mode_Func)gray_raster_set_mode, - (FT_Raster_Render_Func) gray_raster_render, - (FT_Raster_Done_Func) gray_raster_done ) + (FT_Raster_New_Func) gray_raster_new, /* raster_new */ + (FT_Raster_Reset_Func) gray_raster_reset, /* raster_reset */ + (FT_Raster_Set_Mode_Func)gray_raster_set_mode, /* raster_set_mode */ + (FT_Raster_Render_Func) gray_raster_render, /* raster_render */ + (FT_Raster_Done_Func) gray_raster_done /* raster_done */ + ) /* END */ diff --git a/src/3rdparty/freetype/src/smooth/ftgrays.h b/src/3rdparty/freetype/src/smooth/ftgrays.h index 1b5760330c..9e11ca675e 100644 --- a/src/3rdparty/freetype/src/smooth/ftgrays.h +++ b/src/3rdparty/freetype/src/smooth/ftgrays.h @@ -4,7 +4,7 @@ /* */ /* FreeType smooth renderer declaration */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,15 +16,15 @@ /***************************************************************************/ -#ifndef __FTGRAYS_H__ -#define __FTGRAYS_H__ +#ifndef FTGRAYS_H_ +#define FTGRAYS_H_ #ifdef __cplusplus extern "C" { #endif -#ifdef _STANDALONE_ +#ifdef STANDALONE_ #include "ftimage.h" #else #include <ft2build.h> @@ -52,7 +52,7 @@ } #endif -#endif /* __FTGRAYS_H__ */ +#endif /* FTGRAYS_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/smooth/ftsmerrs.h b/src/3rdparty/freetype/src/smooth/ftsmerrs.h index cc38aa1996..226dc1b001 100644 --- a/src/3rdparty/freetype/src/smooth/ftsmerrs.h +++ b/src/3rdparty/freetype/src/smooth/ftsmerrs.h @@ -4,7 +4,7 @@ /* */ /* smooth renderer error codes (specification only). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __FTSMERRS_H__ -#define __FTSMERRS_H__ +#ifndef FTSMERRS_H_ +#define FTSMERRS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX Smooth_Err_ @@ -36,7 +36,7 @@ #include FT_ERRORS_H -#endif /* __FTSMERRS_H__ */ +#endif /* FTSMERRS_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/smooth/ftsmooth.c b/src/3rdparty/freetype/src/smooth/ftsmooth.c index 3620550534..ef176bdf1e 100644 --- a/src/3rdparty/freetype/src/smooth/ftsmooth.c +++ b/src/3rdparty/freetype/src/smooth/ftsmooth.c @@ -4,7 +4,7 @@ /* */ /* Anti-aliasing renderer interface (body). */ /* */ -/* Copyright 2000-2015 by */ +/* Copyright 2000-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -31,12 +31,7 @@ static FT_Error ft_smooth_init( FT_Renderer render ) { - FT_Library library = FT_MODULE_LIBRARY( render ); - - - render->clazz->raster_class->raster_reset( render->raster, - library->raster_pool, - library->raster_pool_size ); + render->clazz->raster_class->raster_reset( render->raster, NULL, 0 ); return 0; } @@ -87,7 +82,7 @@ FT_GlyphSlot slot, FT_BBox* cbox ) { - FT_MEM_ZERO( cbox, sizeof ( *cbox ) ); + FT_ZERO( cbox ); if ( slot->format == render->glyph_format ) FT_Outline_Get_CBox( &slot->outline, cbox ); @@ -102,26 +97,17 @@ const FT_Vector* origin, FT_Render_Mode required_mode ) { - FT_Error error; + FT_Error error = FT_Err_Ok; FT_Outline* outline = &slot->outline; FT_Bitmap* bitmap = &slot->bitmap; FT_Memory memory = render->root.memory; - FT_BBox cbox; FT_Pos x_shift = 0; FT_Pos y_shift = 0; - FT_Pos x_left, y_top; - FT_Pos width, height, pitch; -#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING - FT_Pos height_org, width_org; -#endif - FT_Int hmul = mode == FT_RENDER_MODE_LCD; - FT_Int vmul = mode == FT_RENDER_MODE_LCD_V; + FT_Int hmul = ( mode == FT_RENDER_MODE_LCD ); + FT_Int vmul = ( mode == FT_RENDER_MODE_LCD_V ); FT_Raster_Params params; - FT_Bool have_outline_shifted = FALSE; - FT_Bool have_buffer = FALSE; - /* check glyph image format */ if ( slot->format != render->glyph_format ) @@ -137,91 +123,6 @@ goto Exit; } - if ( origin ) - { - x_shift = origin->x; - y_shift = origin->y; - } - - /* compute the control box, and grid fit it */ - /* taking into account the origin shift */ - FT_Outline_Get_CBox( outline, &cbox ); - - cbox.xMin = FT_PIX_FLOOR( cbox.xMin + x_shift ); - cbox.yMin = FT_PIX_FLOOR( cbox.yMin + y_shift ); - cbox.xMax = FT_PIX_CEIL( cbox.xMax + x_shift ); - cbox.yMax = FT_PIX_CEIL( cbox.yMax + y_shift ); - - x_shift -= cbox.xMin; - y_shift -= cbox.yMin; - - x_left = cbox.xMin >> 6; - y_top = cbox.yMax >> 6; - - width = (FT_ULong)( cbox.xMax - cbox.xMin ) >> 6; - height = (FT_ULong)( cbox.yMax - cbox.yMin ) >> 6; - -#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING - width_org = width; - height_org = height; -#endif - - pitch = width; - if ( hmul ) - { - width *= 3; - pitch = FT_PAD_CEIL( width, 4 ); - } - - if ( vmul ) - height *= 3; - -#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING - - if ( slot->library->lcd_filter_func ) - { - FT_Int extra = slot->library->lcd_extra; - - - if ( hmul ) - { - x_shift += 64 * ( extra >> 1 ); - x_left -= extra >> 1; - width += 3 * extra; - pitch = FT_PAD_CEIL( width, 4 ); - } - - if ( vmul ) - { - y_shift += 64 * ( extra >> 1 ); - y_top += extra >> 1; - height += 3 * extra; - } - } - -#endif - - /* - * XXX: on 16bit system, we return an error for huge bitmap - * to prevent an overflow. - */ - if ( x_left > FT_INT_MAX || y_top > FT_INT_MAX || - x_left < FT_INT_MIN || y_top < FT_INT_MIN ) - { - error = FT_THROW( Invalid_Pixel_Size ); - goto Exit; - } - - /* Required check is (pitch * height < FT_ULONG_MAX), */ - /* but we care realistic cases only. Always pitch <= width. */ - if ( width > 0x7FFF || height > 0x7FFF ) - { - FT_ERROR(( "ft_smooth_render_generic: glyph too large: %u x %u\n", - width, height )); - error = FT_THROW( Raster_Overflow ); - goto Exit; - } - /* release old bitmap buffer */ if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) { @@ -229,30 +130,30 @@ slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; } + ft_glyphslot_preset_bitmap( slot, mode, origin ); + /* allocate new one */ - if ( FT_ALLOC( bitmap->buffer, (FT_ULong)( pitch * height ) ) ) + if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, bitmap->pitch ) ) goto Exit; - else - have_buffer = TRUE; slot->internal->flags |= FT_GLYPH_OWN_BITMAP; - slot->format = FT_GLYPH_FORMAT_BITMAP; - slot->bitmap_left = (FT_Int)x_left; - slot->bitmap_top = (FT_Int)y_top; + x_shift = 64 * -slot->bitmap_left; + y_shift = 64 * -slot->bitmap_top; + if ( bitmap->pixel_mode == FT_PIXEL_MODE_LCD_V ) + y_shift += 64 * (FT_Int)bitmap->rows / 3; + else + y_shift += 64 * (FT_Int)bitmap->rows; - bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; - bitmap->num_grays = 256; - bitmap->width = (unsigned int)width; - bitmap->rows = (unsigned int)height; - bitmap->pitch = pitch; + if ( origin ) + { + x_shift += origin->x; + y_shift += origin->y; + } /* translate outline to render it into the bitmap */ if ( x_shift || y_shift ) - { FT_Outline_Translate( outline, x_shift, y_shift ); - have_outline_shifted = TRUE; - } /* set up parameters */ params.target = bitmap; @@ -299,80 +200,143 @@ if ( error ) goto Exit; - if ( slot->library->lcd_filter_func ) - slot->library->lcd_filter_func( bitmap, mode, slot->library ); + /* finally apply filtering */ + if ( hmul || vmul ) + { + FT_Byte* lcd_weights; + FT_Bitmap_LcdFilterFunc lcd_filter_func; + + + /* Per-face LCD filtering takes priority if set up. */ + if ( slot->face && slot->face->internal->lcd_filter_func ) + { + lcd_weights = slot->face->internal->lcd_weights; + lcd_filter_func = slot->face->internal->lcd_filter_func; + } + else + { + lcd_weights = slot->library->lcd_weights; + lcd_filter_func = slot->library->lcd_filter_func; + } + + if ( lcd_filter_func ) + lcd_filter_func( bitmap, mode, lcd_weights ); + } #else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ - /* render outline into bitmap */ - error = render->raster_render( render->raster, ¶ms ); - if ( error ) - goto Exit; - - /* expand it horizontally */ - if ( hmul ) + if ( hmul ) /* lcd */ { - FT_Byte* line = bitmap->buffer; - FT_UInt hh; + FT_Byte* line; + FT_Byte* temp = NULL; + FT_UInt i, j; + + unsigned int height = bitmap->rows; + unsigned int width = bitmap->width; + int pitch = bitmap->pitch; - for ( hh = height_org; hh > 0; hh--, line += pitch ) + /* Render 3 separate monochrome bitmaps, shifting the outline */ + /* by 1/3 pixel. */ + width /= 3; + + bitmap->buffer += width; + + error = render->raster_render( render->raster, ¶ms ); + if ( error ) + goto Exit; + + FT_Outline_Translate( outline, -21, 0 ); + x_shift -= 21; + bitmap->buffer += width; + + error = render->raster_render( render->raster, ¶ms ); + if ( error ) + goto Exit; + + FT_Outline_Translate( outline, 42, 0 ); + x_shift += 42; + bitmap->buffer -= 2 * width; + + error = render->raster_render( render->raster, ¶ms ); + if ( error ) + goto Exit; + + /* XXX: Rearrange the bytes according to FT_PIXEL_MODE_LCD. */ + /* XXX: It is more efficient to render every third byte above. */ + + if ( FT_ALLOC( temp, (FT_ULong)pitch ) ) + goto Exit; + + for ( i = 0; i < height; i++ ) { - FT_UInt xx; - FT_Byte* end = line + width; - - - for ( xx = width_org; xx > 0; xx-- ) + line = bitmap->buffer + i * (FT_ULong)pitch; + for ( j = 0; j < width; j++ ) { - FT_UInt pixel = line[xx-1]; - - - end[-3] = (FT_Byte)pixel; - end[-2] = (FT_Byte)pixel; - end[-1] = (FT_Byte)pixel; - end -= 3; + temp[3 * j ] = line[j]; + temp[3 * j + 1] = line[j + width]; + temp[3 * j + 2] = line[j + width + width]; } + FT_MEM_COPY( line, temp, pitch ); } - } - /* expand it vertically */ - if ( vmul ) + FT_FREE( temp ); + } + else if ( vmul ) /* lcd_v */ { - FT_Byte* read = bitmap->buffer + ( height - height_org ) * pitch; - FT_Byte* write = bitmap->buffer; - FT_UInt hh; + int pitch = bitmap->pitch; - for ( hh = height_org; hh > 0; hh-- ) - { - ft_memcpy( write, read, pitch ); - write += pitch; + /* Render 3 separate monochrome bitmaps, shifting the outline */ + /* by 1/3 pixel. Triple the pitch to render on each third row. */ + bitmap->pitch *= 3; + bitmap->rows /= 3; - ft_memcpy( write, read, pitch ); - write += pitch; + bitmap->buffer += pitch; - ft_memcpy( write, read, pitch ); - write += pitch; - read += pitch; - } + error = render->raster_render( render->raster, ¶ms ); + if ( error ) + goto Exit; + + FT_Outline_Translate( outline, 0, 21 ); + y_shift += 21; + bitmap->buffer += pitch; + + error = render->raster_render( render->raster, ¶ms ); + if ( error ) + goto Exit; + + FT_Outline_Translate( outline, 0, -42 ); + y_shift -= 42; + bitmap->buffer -= 2 * pitch; + + error = render->raster_render( render->raster, ¶ms ); + if ( error ) + goto Exit; + + bitmap->pitch /= 3; + bitmap->rows *= 3; } + else /* grayscale */ + error = render->raster_render( render->raster, ¶ms ); #endif /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ - /* everything is fine; don't deallocate buffer */ - have_buffer = FALSE; - - error = FT_Err_Ok; - Exit: - if ( have_outline_shifted ) - FT_Outline_Translate( outline, -x_shift, -y_shift ); - if ( have_buffer ) + if ( !error ) + { + /* everything is fine; the glyph is now officially a bitmap */ + slot->format = FT_GLYPH_FORMAT_BITMAP; + } + else if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) { FT_FREE( bitmap->buffer ); slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; } + if ( x_shift || y_shift ) + FT_Outline_Translate( outline, -x_shift, -y_shift ); + return error; } @@ -399,14 +363,8 @@ FT_Render_Mode mode, const FT_Vector* origin ) { - FT_Error error; - - error = ft_smooth_render_generic( render, slot, mode, origin, - FT_RENDER_MODE_LCD ); - if ( !error ) - slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD; - - return error; + return ft_smooth_render_generic( render, slot, mode, origin, + FT_RENDER_MODE_LCD ); } @@ -417,18 +375,13 @@ FT_Render_Mode mode, const FT_Vector* origin ) { - FT_Error error; - - error = ft_smooth_render_generic( render, slot, mode, origin, - FT_RENDER_MODE_LCD_V ); - if ( !error ) - slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD_V; - - return error; + return ft_smooth_render_generic( render, slot, mode, origin, + FT_RENDER_MODE_LCD_V ); } - FT_DEFINE_RENDERER( ft_smooth_renderer_class, + FT_DEFINE_RENDERER( + ft_smooth_renderer_class, FT_MODULE_RENDERER, sizeof ( FT_RendererRec ), @@ -437,25 +390,25 @@ 0x10000L, 0x20000L, - 0, /* module specific interface */ + NULL, /* module specific interface */ - (FT_Module_Constructor)ft_smooth_init, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - , + (FT_Module_Constructor)ft_smooth_init, /* module_init */ + (FT_Module_Destructor) NULL, /* module_done */ + (FT_Module_Requester) NULL, /* get_interface */ FT_GLYPH_FORMAT_OUTLINE, - (FT_Renderer_RenderFunc) ft_smooth_render, - (FT_Renderer_TransformFunc)ft_smooth_transform, - (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, - (FT_Renderer_SetModeFunc) ft_smooth_set_mode, + (FT_Renderer_RenderFunc) ft_smooth_render, /* render_glyph */ + (FT_Renderer_TransformFunc)ft_smooth_transform, /* transform_glyph */ + (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, /* get_glyph_cbox */ + (FT_Renderer_SetModeFunc) ft_smooth_set_mode, /* set_mode */ - (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET + (FT_Raster_Funcs*)&FT_GRAYS_RASTER_GET /* raster_class */ ) - FT_DEFINE_RENDERER( ft_smooth_lcd_renderer_class, + FT_DEFINE_RENDERER( + ft_smooth_lcd_renderer_class, FT_MODULE_RENDERER, sizeof ( FT_RendererRec ), @@ -464,24 +417,25 @@ 0x10000L, 0x20000L, - 0, /* module specific interface */ + NULL, /* module specific interface */ - (FT_Module_Constructor)ft_smooth_init, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - , + (FT_Module_Constructor)ft_smooth_init, /* module_init */ + (FT_Module_Destructor) NULL, /* module_done */ + (FT_Module_Requester) NULL, /* get_interface */ FT_GLYPH_FORMAT_OUTLINE, - (FT_Renderer_RenderFunc) ft_smooth_render_lcd, - (FT_Renderer_TransformFunc)ft_smooth_transform, - (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, - (FT_Renderer_SetModeFunc) ft_smooth_set_mode, + (FT_Renderer_RenderFunc) ft_smooth_render_lcd, /* render_glyph */ + (FT_Renderer_TransformFunc)ft_smooth_transform, /* transform_glyph */ + (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, /* get_glyph_cbox */ + (FT_Renderer_SetModeFunc) ft_smooth_set_mode, /* set_mode */ - (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET + (FT_Raster_Funcs*)&FT_GRAYS_RASTER_GET /* raster_class */ ) - FT_DEFINE_RENDERER( ft_smooth_lcdv_renderer_class, + + FT_DEFINE_RENDERER( + ft_smooth_lcdv_renderer_class, FT_MODULE_RENDERER, sizeof ( FT_RendererRec ), @@ -490,21 +444,20 @@ 0x10000L, 0x20000L, - 0, /* module specific interface */ + NULL, /* module specific interface */ - (FT_Module_Constructor)ft_smooth_init, - (FT_Module_Destructor) 0, - (FT_Module_Requester) 0 - , + (FT_Module_Constructor)ft_smooth_init, /* module_init */ + (FT_Module_Destructor) NULL, /* module_done */ + (FT_Module_Requester) NULL, /* get_interface */ FT_GLYPH_FORMAT_OUTLINE, - (FT_Renderer_RenderFunc) ft_smooth_render_lcd_v, - (FT_Renderer_TransformFunc)ft_smooth_transform, - (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, - (FT_Renderer_SetModeFunc) ft_smooth_set_mode, + (FT_Renderer_RenderFunc) ft_smooth_render_lcd_v, /* render_glyph */ + (FT_Renderer_TransformFunc)ft_smooth_transform, /* transform_glyph */ + (FT_Renderer_GetCBoxFunc) ft_smooth_get_cbox, /* get_glyph_cbox */ + (FT_Renderer_SetModeFunc) ft_smooth_set_mode, /* set_mode */ - (FT_Raster_Funcs*) &FT_GRAYS_RASTER_GET + (FT_Raster_Funcs*)&FT_GRAYS_RASTER_GET /* raster_class */ ) diff --git a/src/3rdparty/freetype/src/smooth/ftsmooth.h b/src/3rdparty/freetype/src/smooth/ftsmooth.h index 765018c239..c76ffc5034 100644 --- a/src/3rdparty/freetype/src/smooth/ftsmooth.h +++ b/src/3rdparty/freetype/src/smooth/ftsmooth.h @@ -4,7 +4,7 @@ /* */ /* Anti-aliasing renderer interface (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTSMOOTH_H__ -#define __FTSMOOTH_H__ +#ifndef FTSMOOTH_H_ +#define FTSMOOTH_H_ #include <ft2build.h> @@ -27,23 +27,16 @@ FT_BEGIN_HEADER -#ifndef FT_CONFIG_OPTION_NO_STD_RASTER - FT_DECLARE_RENDERER( ft_std_renderer_class ) -#endif - -#ifndef FT_CONFIG_OPTION_NO_SMOOTH_RASTER FT_DECLARE_RENDERER( ft_smooth_renderer_class ) FT_DECLARE_RENDERER( ft_smooth_lcd_renderer_class ) - FT_DECLARE_RENDERER( ft_smooth_lcd_v_renderer_class ) -#endif - + FT_DECLARE_RENDERER( ft_smooth_lcdv_renderer_class ) FT_END_HEADER -#endif /* __FTSMOOTH_H__ */ +#endif /* FTSMOOTH_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/smooth/ftspic.c b/src/3rdparty/freetype/src/smooth/ftspic.c index 8e6ed57eec..10f04cf4cc 100644 --- a/src/3rdparty/freetype/src/smooth/ftspic.c +++ b/src/3rdparty/freetype/src/smooth/ftspic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for smooth module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2018 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/src/smooth/ftspic.h b/src/3rdparty/freetype/src/smooth/ftspic.h index 071afcff20..80fb64cff4 100644 --- a/src/3rdparty/freetype/src/smooth/ftspic.h +++ b/src/3rdparty/freetype/src/smooth/ftspic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for smooth module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2018 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __FTSPIC_H__ -#define __FTSPIC_H__ +#ifndef FTSPIC_H_ +#define FTSPIC_H_ #include FT_INTERNAL_PIC_H @@ -69,7 +69,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __FTSPIC_H__ */ +#endif /* FTSPIC_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/smooth/module.mk b/src/3rdparty/freetype/src/smooth/module.mk index 740936f5b1..5b8bc3be3b 100644 --- a/src/3rdparty/freetype/src/smooth/module.mk +++ b/src/3rdparty/freetype/src/smooth/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2015 by +# Copyright 1996-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/smooth/rules.mk b/src/3rdparty/freetype/src/smooth/rules.mk index f00ebd5f15..f30824a367 100644 --- a/src/3rdparty/freetype/src/smooth/rules.mk +++ b/src/3rdparty/freetype/src/smooth/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2015 by +# Copyright 1996-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/smooth/smooth.c b/src/3rdparty/freetype/src/smooth/smooth.c index 4ca4344c89..5249a8931e 100644 --- a/src/3rdparty/freetype/src/smooth/smooth.c +++ b/src/3rdparty/freetype/src/smooth/smooth.c @@ -4,7 +4,7 @@ /* */ /* FreeType anti-aliasing rasterer module component (body only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,11 +17,11 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT - #include <ft2build.h> -#include "ftspic.c" + #include "ftgrays.c" #include "ftsmooth.c" +#include "ftspic.c" /* END */ diff --git a/src/3rdparty/freetype/src/tools/afblue.pl b/src/3rdparty/freetype/src/tools/afblue.pl index 56b6452348..7c6f1a7df1 100644 --- a/src/3rdparty/freetype/src/tools/afblue.pl +++ b/src/3rdparty/freetype/src/tools/afblue.pl @@ -5,7 +5,7 @@ # # Process a blue zone character data file. # -# Copyright 2013-2015 by +# Copyright 2013-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, @@ -38,7 +38,8 @@ my $curr_max; # Name of the current maximum value. my $curr_enum_element; # Name of the current enumeration element. my $curr_offset; # The offset relative to current aux. variable. -my $curr_elem_size; # The size of the current string or block. +my $curr_elem_size; # The number of non-space characters in the current string or + # the number of elements in the current block. my $have_sections = 0; # Boolean; set if start of a section has been seen. my $have_strings; # Boolean; set if current section contains strings. @@ -159,12 +160,14 @@ sub convert_ascii_chars # A series of ASCII characters in the printable range. my $s = shift; - # We ignore spaces. - $s =~ s/ //g; + # We reduce multiple space characters to a single one. + $s =~ s/ +/ /g; - my $count = $s =~ s/\G(.)/'$1', /g; - $curr_offset += $count; - $curr_elem_size += $count; + # Count all non-space characters. Note that `()' applies a list context + # to the capture that is used to count the elements. + $curr_elem_size += () = $s =~ /[^ ]/g; + + $curr_offset += $s =~ s/\G(.)/'$1', /g; return $s; } diff --git a/src/3rdparty/freetype/src/tools/apinames.c b/src/3rdparty/freetype/src/tools/apinames.c index 9f81b1a6c7..06c3260430 100644 --- a/src/3rdparty/freetype/src/tools/apinames.c +++ b/src/3rdparty/freetype/src/tools/apinames.c @@ -22,7 +22,7 @@ #include <ctype.h> #define PROGRAM_NAME "apinames" -#define PROGRAM_VERSION "0.2" +#define PROGRAM_VERSION "0.3" #define LINEBUFF_SIZE 1024 @@ -32,7 +32,8 @@ typedef enum OutputFormat_ OUTPUT_WINDOWS_DEF, /* output a Windows .DEF file for Visual C++ or Mingw */ OUTPUT_BORLAND_DEF, /* output a Windows .DEF file for Borland C++ */ OUTPUT_WATCOM_LBC, /* output a Watcom Linker Command File */ - OUTPUT_NETWARE_IMP /* output a NetWare ImportFile */ + OUTPUT_NETWARE_IMP, /* output a NetWare ImportFile */ + OUTPUT_GNU_VERMAP /* output a version map for GNU or Solaris linker */ } OutputFormat; @@ -90,14 +91,14 @@ names_add( const char* name, max_names += (max_names >> 1) + 4; the_names = (NameRec*)realloc( the_names, sizeof ( the_names[0] ) * max_names ); - if ( the_names == NULL ) + if ( !the_names ) panic( "not enough memory" ); } nm = &the_names[num_names++]; nm->hash = h; nm->name = (char*)malloc( len+1 ); - if ( nm->name == NULL ) + if ( !nm->name ) panic( "not enough memory" ); memcpy( nm->name, name, len ); @@ -159,7 +160,7 @@ names_dump( FILE* out, char temp[512]; - if ( dll_name == NULL ) + if ( !dll_name ) { fprintf( stderr, "you must provide a DLL name with the -d option!\n" ); @@ -168,7 +169,7 @@ names_dump( FILE* out, /* we must omit the .dll suffix from the library name */ dot = strchr( dll_name, '.' ); - if ( dot != NULL ) + if ( dot ) { int len = dot - dll_name; @@ -190,7 +191,7 @@ names_dump( FILE* out, case OUTPUT_NETWARE_IMP: { - if ( dll_name != NULL ) + if ( dll_name ) fprintf( out, " (%s)\n", dll_name ); for ( nn = 0; nn < num_names - 1; nn++ ) fprintf( out, " %s,\n", the_names[nn].name ); @@ -198,6 +199,15 @@ names_dump( FILE* out, } break; + case OUTPUT_GNU_VERMAP: + { + fprintf( out, "{\n\tglobal:\n" ); + for ( nn = 0; nn < num_names; nn++ ) + fprintf( out, "\t\t%s;\n", the_names[nn].name ); + fprintf( out, "\tlocal:\n\t\t*;\n};\n" ); + } + break; + default: /* LIST */ for ( nn = 0; nn < num_names; nn++ ) fprintf( out, "%s\n", the_names[nn].name ); @@ -323,6 +333,7 @@ usage( void ) " -wB : output .DEF file for Borland C++\n" " -wW : output Watcom Linker Response File\n" " -wN : output NetWare Import File\n" + " -wL : output version map for GNU or Solaris linker\n" "\n"; fprintf( stderr, @@ -371,7 +382,7 @@ int main( int argc, const char* const* argv ) arg += 2; out = fopen( arg, "wt" ); - if ( out == NULL ) + if ( !out ) { fprintf( stderr, "could not open '%s' for writing\n", argv[2] ); exit(3); @@ -410,6 +421,10 @@ int main( int argc, const char* const* argv ) format = OUTPUT_NETWARE_IMP; break; + case 'L': + format = OUTPUT_GNU_VERMAP; + break; + case 0: break; @@ -440,7 +455,7 @@ int main( int argc, const char* const* argv ) { FILE* file = fopen( argv[0], "rb" ); - if ( file == NULL ) + if ( !file ) fprintf( stderr, "unable to open '%s'\n", argv[0] ); else { diff --git a/src/3rdparty/freetype/src/tools/docmaker/content.py b/src/3rdparty/freetype/src/tools/docmaker/content.py index 1961878a7d..198780aee4 100644 --- a/src/3rdparty/freetype/src/tools/docmaker/content.py +++ b/src/3rdparty/freetype/src/tools/docmaker/content.py @@ -3,7 +3,7 @@ # # Parse comment blocks to build content blocks (library file). # -# Copyright 2002-2015 by +# Copyright 2002-2018 by # David Turner. # # This file is part of the FreeType project, and may only be used, @@ -46,9 +46,26 @@ re_code_end = re.compile( r"(\s*)}\s*$" ) # -# A regular expression to isolate identifiers from other text. +# A regular expression to isolate identifiers from other text. Two syntax +# forms are supported: # -re_identifier = re.compile( r'((?:\w|-)*)' ) +# <name> +# <name>[<id>] +# +# where both `<name>' and `<id>' consist of alphanumeric characters, `_', +# and `-'. Use `<id>' if there are multiple, valid `<name>' entries; in the +# index, `<id>' will be appended in parentheses. +# +# For example, +# +# stem_darkening[autofit] +# +# becomes `stem_darkening (autofit)' in the index. +# +re_identifier = re.compile( r""" + ((?:\w|-)+ + (?:\[(?:\w|-)+\])?) + """, re.VERBOSE ) # @@ -92,7 +109,7 @@ class DocCode: def dump( self, prefix = "", width = 60 ): lines = self.dump_lines( 0, width ) for l in lines: - print prefix + l + print( prefix + l ) def dump_lines( self, margin = 0, width = 60 ): result = [] @@ -122,7 +139,7 @@ class DocPara: def dump( self, prefix = "", width = 60 ): lines = self.dump_lines( 0, width ) for l in lines: - print prefix + l + print( prefix + l ) def dump_lines( self, margin = 0, width = 60 ): cur = "" # current line @@ -226,13 +243,13 @@ class DocField: def dump( self, prefix = "" ): if self.field: - print prefix + self.field + " ::" + print( prefix + self.field + " ::" ) prefix = prefix + "----" first = 1 for p in self.items: if not first: - print "" + print( "" ) p.dump( prefix ) first = 0 @@ -313,10 +330,10 @@ class DocMarkup: return None def dump( self, margin ): - print " " * margin + "<" + self.tag + ">" + print( " " * margin + "<" + self.tag + ">" ) for f in self.fields: f.dump( " " ) - print " " * margin + "</" + self.tag + ">" + print( " " * margin + "</" + self.tag + ">" ) ################################################################ @@ -436,15 +453,32 @@ class ContentProcessor: markup_lines = [] first = 1 + margin = -1 + in_code = 0 + for line in content: - found = None - for t in re_markup_tags: - m = t.match( line ) + if in_code: + m = re_code_end.match( line ) + if m and len( m.group( 1 ) ) <= margin: + in_code = 0 + margin = -1 + else: + m = re_code_start.match( line ) if m: - found = string.lower( m.group( 1 ) ) - prefix = len( m.group( 0 ) ) - line = " " * prefix + line[prefix:] # remove markup from line - break + in_code = 1 + margin = len( m.group( 1 ) ) + + found = None + + if not in_code: + for t in re_markup_tags: + m = t.match( line ) + if m: + found = string.lower( m.group( 1 ) ) + prefix = len( m.group( 0 ) ) + # remove markup from line + line = " " * prefix + line[prefix:] + break # is it the start of a new markup section ? if found: diff --git a/src/3rdparty/freetype/src/tools/docmaker/docbeauty.py b/src/3rdparty/freetype/src/tools/docmaker/docbeauty.py index 3ddf4a94a1..0b021fa6c9 100644 --- a/src/3rdparty/freetype/src/tools/docmaker/docbeauty.py +++ b/src/3rdparty/freetype/src/tools/docmaker/docbeauty.py @@ -10,9 +10,7 @@ from sources import * from content import * from utils import * -import utils - -import sys, os, time, string, getopt +import sys, os, string, getopt content_processor = ContentProcessor() @@ -40,13 +38,13 @@ def beautify_block( block ): def usage(): - print "\nDocBeauty 0.1 Usage information\n" - print " docbeauty [options] file1 [file2 ...]\n" - print "using the following options:\n" - print " -h : print this page" - print " -b : backup original files with the 'orig' extension" - print "" - print " --backup : same as -b" + print( "\nDocBeauty 0.1 Usage information\n" ) + print( " docbeauty [options] file1 [file2 ...]\n" ) + print( "using the following options:\n" ) + print( " -h : print this page" ) + print( " -b : backup original files with the 'orig' extension" ) + print( "" ) + print( " --backup : same as -b" ) def main( argv ): diff --git a/src/3rdparty/freetype/src/tools/docmaker/docmaker.py b/src/3rdparty/freetype/src/tools/docmaker/docmaker.py index de82d930f5..eb49afb0a0 100644 --- a/src/3rdparty/freetype/src/tools/docmaker/docmaker.py +++ b/src/3rdparty/freetype/src/tools/docmaker/docmaker.py @@ -4,7 +4,7 @@ # # Convert source code markup to HTML documentation. # -# Copyright 2002-2015 by +# Copyright 2002-2018 by # David Turner. # # This file is part of the FreeType project, and may only be used, @@ -31,21 +31,21 @@ from tohtml import * import utils -import sys, os, time, string, glob, getopt +import sys, glob, getopt def usage(): - print "\nDocMaker Usage information\n" - print " docmaker [options] file1 [file2 ...]\n" - print "using the following options:\n" - print " -h : print this page" - print " -t : set project title, as in '-t \"My Project\"'" - print " -o : set output directory, as in '-o mydir'" - print " -p : set documentation prefix, as in '-p ft2'" - print "" - print " --title : same as -t, as in '--title=\"My Project\"'" - print " --output : same as -o, as in '--output=mydir'" - print " --prefix : same as -p, as in '--prefix=ft2'" + print( "\nDocMaker Usage information\n" ) + print( " docmaker [options] file1 [file2 ...]\n" ) + print( "using the following options:\n" ) + print( " -h : print this page" ) + print( " -t : set project title, as in '-t \"My Project\"'" ) + print( " -o : set output directory, as in '-o mydir'" ) + print( " -p : set documentation prefix, as in '-p ft2'" ) + print( "" ) + print( " --title : same as -t, as in '--title=\"My Project\"'" ) + print( " --output : same as -o, as in '--output=mydir'" ) + print( " --prefix : same as -p, as in '--prefix=ft2'" ) def main( argv ): diff --git a/src/3rdparty/freetype/src/tools/docmaker/formatter.py b/src/3rdparty/freetype/src/tools/docmaker/formatter.py index f0a8808c47..2708fd40d6 100644 --- a/src/3rdparty/freetype/src/tools/docmaker/formatter.py +++ b/src/3rdparty/freetype/src/tools/docmaker/formatter.py @@ -3,7 +3,7 @@ # # Convert parsed content blocks to a structured document (library file). # -# Copyright 2002-2015 by +# Copyright 2002-2018 by # David Turner. # # This file is part of the FreeType project, and may only be used, @@ -56,6 +56,11 @@ class Formatter: self.block_index = self.identifiers.keys() self.block_index.sort( key = index_key ) + # also add section names to dictionary (without making them appear + # in the index) + for section in self.sections: + self.add_identifier( section.name, section ) + def add_identifier( self, name, block ): if name in self.identifiers: # duplicate name! diff --git a/src/3rdparty/freetype/src/tools/docmaker/sources.py b/src/3rdparty/freetype/src/tools/docmaker/sources.py index be38132d1d..e3b95e0faa 100644 --- a/src/3rdparty/freetype/src/tools/docmaker/sources.py +++ b/src/3rdparty/freetype/src/tools/docmaker/sources.py @@ -3,7 +3,7 @@ # # Convert source code comments to multi-line blocks (library file). # -# Copyright 2002-2015 by +# Copyright 2002-2018 by # David Turner. # # This file is part of the FreeType project, and may only be used, @@ -29,7 +29,7 @@ # -import fileinput, re, sys, os, string +import fileinput, re, string ################################################################ @@ -138,12 +138,24 @@ re_markup_tags = [re_markup_tag1, re_markup_tag2] # # A regular expression to detect a cross reference, after markup tags have -# been stripped off. Group 1 is the reference, group 2 the rest of the -# line. +# been stripped off. # -# A cross reference consists of letters, digits, or characters `-' and `_'. +# Two syntax forms are supported: # -re_crossref = re.compile( r'@((?:\w|-)*)(.*)' ) # @foo +# @<name> +# @<name>[<id>] +# +# where both `<name>' and `<id>' consist of alphanumeric characters, `_', +# and `-'. Use `<id>' if there are multiple, valid `<name>' entries. +# +# Example: @foo[bar] +# +re_crossref = re.compile( r""" + @ + (?P<name>(?:\w|-)+ + (?:\[(?:\w|-)+\])?) + (?P<rest>.*) + """, re.VERBOSE ) # # Two regular expressions to detect italic and bold markup, respectively. @@ -159,7 +171,7 @@ re_bold = re.compile( r"\*((?:\w|-)(?:\w|'|-)*)\*(.*)" ) # *bold* # # This regular expression code to identify an URL has been taken from # -# http://mail.python.org/pipermail/tutor/2002-September/017228.html +# https://mail.python.org/pipermail/tutor/2002-September/017228.html # # (with slight modifications). # @@ -284,10 +296,10 @@ class SourceBlock: # debugging only -- not used in normal operations def dump( self ): if self.content: - print "{{{content start---" + print( "{{{content start---" ) for l in self.content: - print l - print "---content end}}}" + print( l ) + print( "---content end}}}" ) return fmt = "" @@ -295,7 +307,7 @@ class SourceBlock: fmt = repr( self.format.id ) + " " for line in self.lines: - print line + print( line ) ################################################################ diff --git a/src/3rdparty/freetype/src/tools/docmaker/tohtml.py b/src/3rdparty/freetype/src/tools/docmaker/tohtml.py index bc6bcf0511..9f318a2a49 100644 --- a/src/3rdparty/freetype/src/tools/docmaker/tohtml.py +++ b/src/3rdparty/freetype/src/tools/docmaker/tohtml.py @@ -3,7 +3,7 @@ # # A sub-class container of the `Formatter' class to produce HTML. # -# Copyright 2002-2015 by +# Copyright 2002-2018 by # David Turner. # # This file is part of the FreeType project, and may only be used, @@ -25,7 +25,7 @@ import time # The following strings define the HTML header used by all generated pages. html_header_1 = """\ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" -"http://www.w3.org/TR/html4/loose.dtd"> +"https://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> @@ -164,7 +164,8 @@ html_footer = """\ """ # The header and footer used for each section. -section_title_header = "<h1>" +section_title_header1 = '<h1 id="' +section_title_header2 = '">' section_title_footer = "</h1>" # The header and footer used for code segments. @@ -309,7 +310,14 @@ class HtmlFormatter( Formatter ): def make_block_url( self, block, name = None ): if name == None: name = block.name - return self.make_section_url( block.section ) + "#" + name + + try: + section_url = self.make_section_url( block.section ) + except: + # we already have a section + section_url = self.make_section_url( block ) + + return section_url + "#" + name def make_html_word( self, word ): """Analyze a simple word to detect cross-references and markup.""" @@ -317,11 +325,27 @@ class HtmlFormatter( Formatter ): m = re_crossref.match( word ) if m: try: - name = m.group( 1 ) - rest = m.group( 2 ) + name = m.group( 'name' ) + rest = m.group( 'rest' ) block = self.identifiers[name] url = self.make_block_url( block ) - return '<a href="' + url + '">' + name + '</a>' + rest + # display `foo[bar]' as `foo' + name = re.sub( r'\[.*\]', '', name ) + # normalize url, following RFC 3986 + url = string.replace( url, "[", "(" ) + url = string.replace( url, "]", ")" ) + + try: + # for sections, display title + url = ( '‘<a href="' + url + '">' + + block.title + '</a>’' + + rest ) + except: + url = ( '<a href="' + url + '">' + + name + '</a>' + + rest ) + + return url except: # we detected a cross-reference to an unknown item sys.stderr.write( "WARNING: undefined cross reference" @@ -366,7 +390,7 @@ class HtmlFormatter( Formatter ): """Convert a code sequence to HTML.""" line = code_header + '\n' for l in lines: - line = line + html_quote( l ) + '\n' + line = line + html_quote( l ).rstrip() + '\n' return line + code_footer @@ -382,7 +406,7 @@ class HtmlFormatter( Formatter ): return string.join( lines, '\n' ) def print_html_items( self, items ): - print self.make_html_items( items ) + print( self.make_html_items( items ) ) def print_html_field( self, field ): if field.name: @@ -390,10 +414,10 @@ class HtmlFormatter( Formatter ): + field.name + "</b></td><td>" ) - print self.make_html_items( field.items ) + print( self.make_html_items( field.items ) ) if field.name: - print "</td></tr></table>" + print( "</td></tr></table>" ) def html_source_quote( self, line, block_name = None ): result = "" @@ -417,16 +441,22 @@ class HtmlFormatter( Formatter ): id = block.name # link to a field ID if possible - for markup in block.markups: - if markup.tag == 'values': - for field in markup.fields: - if field.name: - id = name + try: + for markup in block.markups: + if markup.tag == 'values': + for field in markup.fields: + if field.name: + id = name + + result = ( result + prefix + + '<a href="' + + self.make_block_url( block, id ) + + '">' + name + '</a>' ) + except: + # sections don't have `markups'; however, we don't + # want references to sections here anyway + result = result + html_quote( line[:length] ) - result = ( result + prefix - + '<a href="' - + self.make_block_url( block, id ) - + '">' + name + '</a>' ) else: result = result + html_quote( line[:length] ) @@ -438,14 +468,14 @@ class HtmlFormatter( Formatter ): return result def print_html_field_list( self, fields ): - print '<table class="fields">' + print( '<table class="fields">' ) for field in fields: - print ( '<tr><td class="val" id="' + field.name + '">' - + field.name - + '</td><td class="desc">' ) + print( '<tr><td class="val" id="' + field.name + '">' + + field.name + + '</td><td class="desc">' ) self.print_html_items( field.items ) - print "</td></tr>" - print "</table>" + print( "</td></tr>" ) + print( "</table>" ) def print_html_markup( self, markup ): table_fields = [] @@ -469,7 +499,7 @@ class HtmlFormatter( Formatter ): # formatting the index # def index_enter( self ): - print self.html_index_header + print( self.html_index_header ) self.index_items = {} def index_name_enter( self, name ): @@ -482,7 +512,7 @@ class HtmlFormatter( Formatter ): count = len( self.block_index ) rows = ( count + self.columns - 1 ) // self.columns - print '<table class="index">' + print( '<table class="index">' ) for r in range( rows ): line = "<tr>" for c in range( self.columns ): @@ -490,20 +520,26 @@ class HtmlFormatter( Formatter ): if i < count: bname = self.block_index[r + c * rows] url = self.index_items[bname] + # display `foo[bar]' as `foo (bar)' + bname = string.replace( bname, "[", " (" ) + bname = string.replace( bname, "]", ")" ) + # normalize url, following RFC 3986 + url = string.replace( url, "[", "(" ) + url = string.replace( url, "]", ")" ) line = ( line + '<td><a href="' + url + '">' + bname + '</a></td>' ) else: line = line + '<td></td>' line = line + "</tr>" - print line + print( line ) - print "</table>" + print( "</table>" ) print( index_footer_start + self.file_prefix + "toc.html" + index_footer_end ) - print self.html_footer + print( self.html_footer ) self.index_items = {} @@ -517,25 +553,25 @@ class HtmlFormatter( Formatter ): # formatting the table of contents # def toc_enter( self ): - print self.html_toc_header - print "<h1>Table of Contents</h1>" + print( self.html_toc_header ) + print( "<h1>Table of Contents</h1>" ) def toc_chapter_enter( self, chapter ): - print chapter_header + string.join( chapter.title ) + chapter_inter - print '<table class="toc">' + print( chapter_header + string.join( chapter.title ) + chapter_inter ) + print( '<table class="toc">' ) def toc_section_enter( self, section ): - print ( '<tr><td class="link">' - + '<a href="' + self.make_section_url( section ) + '">' - + section.title + '</a></td><td class="desc">' ) - print self.make_html_para( section.abstract ) + print( '<tr><td class="link">' + + '<a href="' + self.make_section_url( section ) + '">' + + section.title + '</a></td><td class="desc">' ) + print( self.make_html_para( section.abstract ) ) def toc_section_exit( self, section ): - print "</td></tr>" + print( "</td></tr>" ) def toc_chapter_exit( self, chapter ): - print "</table>" - print chapter_footer + print( "</table>" ) + print( chapter_footer ) def toc_index( self, index_filename ): print( chapter_header @@ -547,7 +583,7 @@ class HtmlFormatter( Formatter ): + self.file_prefix + "index.html" + toc_footer_end ) - print self.html_footer + print( self.html_footer ) def toc_dump( self, toc_filename = None, index_filename = None ): if toc_filename == None: @@ -562,9 +598,11 @@ class HtmlFormatter( Formatter ): # formatting sections # def section_enter( self, section ): - print self.html_header + print( self.html_header ) - print section_title_header + section.title + section_title_footer + print( section_title_header1 + section.name + section_title_header2 + + section.title + + section_title_footer ) maxwidth = 0 for b in section.blocks.values(): @@ -574,8 +612,8 @@ class HtmlFormatter( Formatter ): width = 70 # XXX magic number if maxwidth > 0: # print section synopsis - print section_synopsis_header - print '<table class="synopsis">' + print( section_synopsis_header ) + print( '<table class="synopsis">' ) columns = width // maxwidth if columns < 1: @@ -601,26 +639,38 @@ class HtmlFormatter( Formatter ): # even omit it completely) line = line + " " else: - line = ( line + '<a href="#' + name + '">' + url = name + # display `foo[bar]' as `foo' + name = re.sub( r'\[.*\]', '', name ) + # normalize url, following RFC 3986 + url = string.replace( url, "[", "(" ) + url = string.replace( url, "]", ")" ) + line = ( line + '<a href="#' + url + '">' + name + '</a>' ) line = line + '</td>' line = line + "</tr>" - print line + print( line ) - print "</table>" - print section_synopsis_footer + print( "</table>" ) + print( section_synopsis_footer ) - print description_header - print self.make_html_items( section.description ) - print description_footer + print( description_header ) + print( self.make_html_items( section.description ) ) + print( description_footer ) def block_enter( self, block ): - print block_header + print( block_header ) # place html anchor if needed if block.name: - print( '<h3 id="' + block.name + '">' + block.name + '</h3>' ) + url = block.name + # display `foo[bar]' as `foo' + name = re.sub( r'\[.*\]', '', block.name ) + # normalize url, following RFC 3986 + url = string.replace( url, "[", "(" ) + url = string.replace( url, "]", ")" ) + print( '<h3 id="' + url + '">' + name + '</h3>' ) # dump the block C source lines now if block.code: @@ -636,28 +686,28 @@ class HtmlFormatter( Formatter ): # + " '" + block.source.filename + "'.\n" ) if header: - print ( header_location_header - + 'Defined in ' + header + '.' - + header_location_footer ) + print( header_location_header + + 'Defined in ' + header + '.' + + header_location_footer ) - print source_header + print( source_header ) for l in block.code: - print self.html_source_quote( l, block.name ) - print source_footer + print( self.html_source_quote( l, block.name ) ) + print( source_footer ) def markup_enter( self, markup, block ): if markup.tag == "description": - print description_header + print( description_header ) else: - print marker_header + markup.tag + marker_inter + print( marker_header + markup.tag + marker_inter ) self.print_html_markup( markup ) def markup_exit( self, markup, block ): if markup.tag == "description": - print description_footer + print( description_footer ) else: - print marker_footer + print( marker_footer ) def block_exit( self, block ): print( block_footer_start + self.file_prefix + "index.html" @@ -665,7 +715,7 @@ class HtmlFormatter( Formatter ): + block_footer_end ) def section_exit( self, section ): - print html_footer + print( html_footer ) def section_dump_all( self ): for section in self.sections: diff --git a/src/3rdparty/freetype/src/tools/docmaker/utils.py b/src/3rdparty/freetype/src/tools/docmaker/utils.py index 254083e92e..f40f1674a0 100644 --- a/src/3rdparty/freetype/src/tools/docmaker/utils.py +++ b/src/3rdparty/freetype/src/tools/docmaker/utils.py @@ -3,7 +3,7 @@ # # Auxiliary functions for the `docmaker' tool (library file). # -# Copyright 2002-2015 by +# Copyright 2002-2018 by # David Turner. # # This file is part of the FreeType project, and may only be used, diff --git a/src/3rdparty/freetype/src/tools/ftfuzzer/README b/src/3rdparty/freetype/src/tools/ftfuzzer/README new file mode 100644 index 0000000000..09d8e9f325 --- /dev/null +++ b/src/3rdparty/freetype/src/tools/ftfuzzer/README @@ -0,0 +1,81 @@ +ftfuzzer +======== + + +ftfuzzer.cc +----------- + +This file contains a target function for FreeType fuzzing. It can be +used with libFuzzer (https://llvm.org/docs/LibFuzzer.html) or +potentially any other similar fuzzer. + +Usage: + + 1. Build `libfreetype.a' and `ftfuzzer.cc' using the most recent + clang compiler with these flags: + + # for fuzzer coverage feedback + -fsanitize-coverage=edge,8bit-counters + # for bug checking + -fsanitize=address,signed-integer-overflow,shift + + You also need the header files from the `libarchive' library + (https://www.libarchive.org/) for handling tar files (see file + `ftmutator.cc' below for more). + + 2. Link with `libFuzzer' (it contains `main') and `libarchive'. + + 3. Run the fuzzer on some test corpus. + +The exact flags and commands may vary. + + https://github.com/google/oss-fuzz/tree/master/projects/freetype2 + +There is a continuous fuzzing bot that runs ftfuzzer. + + https://oss-fuzz.com + +(You need an account to be able to see coverage reports and the like +on oss-fuzz.com.) + +Check the bot configuration for the most current settings. + + +ftmutator.cc +------------ + +FreeType has the ability to `attach' auxiliary files to a font file, +providing additional information. The main usage is to load AFM files +for PostScript Type 1 fonts. + +However, libFuzzer currently only supports mutation of a single input +file. For this reason, `ftmutator.cc' contains a custom fuzzer +mutator that uses an uncompressed tar file archive as the input. The +first file in such a tarball gets opened by FreeType as a font, all +other files are treated as input for `FT_Attach_Stream'. + +Compilation is similar to `ftfuzzer.c'. + + +runinput.cc +----------- + +To run the target function on a set of input files, this file contains +a convenience `main' function. Link it with `ftfuzzer.cc', +`libfreetype.a', and `libarchive' and run like + + ./a.out my_tests_inputs/* + +---------------------------------------------------------------------- + +Copyright 2015-2018 by +David Turner, Robert Wilhelm, and Werner Lemberg. + +This file is part of the FreeType project, and may only be used, +modified, and distributed under the terms of the FreeType project +license, LICENSE.TXT. By continuing to use, modify, or distribute +this file you indicate that you have read the license and understand +and accept it fully. + + +--- end of README --- diff --git a/src/3rdparty/freetype/src/tools/ftfuzzer/ftfuzzer.cc b/src/3rdparty/freetype/src/tools/ftfuzzer/ftfuzzer.cc new file mode 100644 index 0000000000..acf2bc9820 --- /dev/null +++ b/src/3rdparty/freetype/src/tools/ftfuzzer/ftfuzzer.cc @@ -0,0 +1,428 @@ +// ftfuzzer.cc +// +// A fuzzing function to test FreeType with libFuzzer. +// +// Copyright 2015-2018 by +// David Turner, Robert Wilhelm, and Werner Lemberg. +// +// This file is part of the FreeType project, and may only be used, +// modified, and distributed under the terms of the FreeType project +// license, LICENSE.TXT. By continuing to use, modify, or distribute +// this file you indicate that you have read the license and +// understand and accept it fully. + + +// we use `unique_ptr', `decltype', and other gimmicks defined since C++11 +#if __cplusplus < 201103L +# error "a C++11 compiler is needed" +#endif + +#include <archive.h> +#include <archive_entry.h> + +#include <assert.h> +#include <stdint.h> + +#include <memory> +#include <vector> + + + using namespace std; + + +#include <ft2build.h> + +#include FT_FREETYPE_H +#include FT_GLYPH_H +#include FT_CACHE_H +#include FT_CACHE_CHARMAP_H +#include FT_CACHE_IMAGE_H +#include FT_CACHE_SMALL_BITMAPS_H +#include FT_SYNTHESIS_H +#include FT_ADVANCES_H +#include FT_OUTLINE_H +#include FT_BBOX_H +#include FT_MODULE_H +#include FT_DRIVER_H +#include FT_MULTIPLE_MASTERS_H + + + static FT_Library library; + static int InitResult; + + + struct FT_Global + { + FT_Global() + { + InitResult = FT_Init_FreeType( &library ); + if ( InitResult ) + return; + + // try to activate Adobe's CFF engine; it might not be the default + unsigned int cff_hinting_engine = FT_HINTING_ADOBE; + FT_Property_Set( library, + "cff", + "hinting-engine", &cff_hinting_engine ); + } + + ~FT_Global() + { + FT_Done_FreeType( library ); + } + }; + + FT_Global global_ft; + + + // We want to select n values at random (without repetition), + // with 0 < n <= N. The algorithm is taken from TAoCP, Vol. 2 + // (Algorithm S, selection sampling technique) + struct Random + { + int n; + int N; + + int t; // total number of values so far + int m; // number of selected values so far + + uint32_t r; // the current pseudo-random number + + Random( int n_, + int N_ ) + : n( n_ ), + N( N_ ) + { + t = 0; + m = 0; + + // Ideally, this should depend on the input file, + // for example, taking the sha256 as input; + // however, this is overkill for fuzzying tests. + r = 12345; + } + + int get() + { + if ( m >= n ) + return -1; + + Redo: + // We can't use `rand': different C libraries might provide + // different implementations of this function. As a replacement, + // we use a 32bit version of the `xorshift' algorithm. + r ^= r << 13; + r ^= r >> 17; + r ^= r << 5; + + double U = double( r ) / UINT32_MAX; + + if ( ( N - t ) * U >= ( n - m ) ) + { + t++; + goto Redo; + } + + t++; + m++; + + return t; + } + }; + + + static int + archive_read_entry_data( struct archive *ar, + vector<FT_Byte> *vw ) + { + int r; + const FT_Byte* buff; + size_t size; + int64_t offset; + + for (;;) + { + r = archive_read_data_block( ar, + reinterpret_cast<const void**>( &buff ), + &size, + &offset ); + if ( r == ARCHIVE_EOF ) + return ARCHIVE_OK; + if ( r != ARCHIVE_OK ) + return r; + + vw->insert( vw->end(), buff, buff + size ); + } + } + + + static vector<vector<FT_Byte>> + parse_data( const uint8_t* data, + size_t size ) + { + struct archive_entry* entry; + int r; + vector<vector<FT_Byte>> files; + + unique_ptr<struct archive, + decltype ( archive_read_free )*> a( archive_read_new(), + archive_read_free ); + + // activate reading of uncompressed tar archives + archive_read_support_format_tar( a.get() ); + + // the need for `const_cast' was removed with libarchive commit be4d4dd + if ( !( r = archive_read_open_memory( + a.get(), + const_cast<void*>(static_cast<const void*>( data ) ), + size ) ) ) + { + unique_ptr<struct archive, + decltype ( archive_read_close )*> a_open( a.get(), + archive_read_close ); + + // read files contained in archive + for (;;) + { + r = archive_read_next_header( a_open.get(), &entry ); + if ( r == ARCHIVE_EOF ) + break; + if ( r != ARCHIVE_OK ) + break; + + vector<FT_Byte> entry_data; + r = archive_read_entry_data( a.get(), &entry_data ); + if ( r != ARCHIVE_OK ) + break; + + files.push_back( move( entry_data ) ); + } + } + + if ( files.size() == 0 ) + files.emplace_back( data, data + size ); + + return files; + } + + + static void + setIntermediateAxis( FT_Face face ) + { + // only handle Multiple Masters and GX variation fonts + if ( !FT_HAS_MULTIPLE_MASTERS( face ) ) + return; + + // get variation data for current instance + FT_MM_Var* variations_ptr = nullptr; + if ( FT_Get_MM_Var( face, &variations_ptr ) ) + return; + + unique_ptr<FT_MM_Var, + decltype ( free )*> variations( variations_ptr, free ); + vector<FT_Fixed> coords( variations->num_axis ); + + // select an arbitrary instance + for ( unsigned int i = 0; i < variations->num_axis; i++ ) + coords[i] = ( variations->axis[i].minimum + + variations->axis[i].def ) / 2; + + if ( FT_Set_Var_Design_Coordinates( face, + FT_UInt( coords.size() ), + coords.data() ) ) + return; + } + + + // the interface function to the libFuzzer library + extern "C" int + LLVMFuzzerTestOneInput( const uint8_t* data, + size_t size_ ) + { + assert( !InitResult ); + + if ( size_ < 1 ) + return 0; + + const vector<vector<FT_Byte>>& files = parse_data( data, size_ ); + + FT_Face face; + FT_Int32 load_flags = FT_LOAD_DEFAULT; +#if 0 + FT_Render_Mode render_mode = FT_RENDER_MODE_NORMAL; +#endif + + // We use a conservative approach here, at the cost of calling + // `FT_New_Face' quite often. The idea is that the fuzzer should be + // able to try all faces and named instances of a font, expecting that + // some faces don't work for various reasons, e.g., a broken subfont, or + // an unsupported NFNT bitmap font in a Mac dfont resource that holds + // more than a single font. + + // get number of faces + if ( FT_New_Memory_Face( library, + files[0].data(), + (FT_Long)files[0].size(), + -1, + &face ) ) + return 0; + long num_faces = face->num_faces; + FT_Done_Face( face ); + + // loop over up to 20 arbitrarily selected faces + // from index range [0;num-faces-1] + long max_face_cnt = num_faces < 20 + ? num_faces + : 20; + + Random faces_pool( (int)max_face_cnt, (int)num_faces ); + + for ( long face_cnt = 0; + face_cnt < max_face_cnt; + face_cnt++ ) + { + long face_index = faces_pool.get() - 1; + + // get number of instances + if ( FT_New_Memory_Face( library, + files[0].data(), + (FT_Long)files[0].size(), + -( face_index + 1 ), + &face ) ) + continue; + long num_instances = face->style_flags >> 16; + FT_Done_Face( face ); + + // loop over the face without instance (index 0) + // and up to 20 arbitrarily selected instances + // from index range [1;num_instances] + long max_instance_cnt = num_instances < 20 + ? num_instances + : 20; + + Random instances_pool( (int)max_instance_cnt, (int)num_instances ); + + for ( long instance_cnt = 0; + instance_cnt <= max_instance_cnt; + instance_cnt++ ) + { + long instance_index = 0; + + if ( !instance_cnt ) + { + if ( FT_New_Memory_Face( library, + files[0].data(), + (FT_Long)files[0].size(), + face_index, + &face ) ) + continue; + } + else + { + instance_index = instances_pool.get(); + + if ( FT_New_Memory_Face( library, + files[0].data(), + (FT_Long)files[0].size(), + ( instance_index << 16 ) + face_index, + &face ) ) + continue; + } + + // if we have more than a single input file coming from an archive, + // attach them (starting with the second file) using the order given + // in the archive + for ( size_t files_index = 1; + files_index < files.size(); + files_index++ ) + { + FT_Open_Args open_args = {}; + open_args.flags = FT_OPEN_MEMORY; + open_args.memory_base = files[files_index].data(); + open_args.memory_size = (FT_Long)files[files_index].size(); + + // the last archive element will be eventually used as the + // attachment + FT_Attach_Stream( face, &open_args ); + } + + // loop over an arbitrary size for outlines + // and up to ten arbitrarily selected bitmap strike sizes + // from the range [0;num_fixed_sizes - 1] + int max_size_cnt = face->num_fixed_sizes < 10 + ? face->num_fixed_sizes + : 10; + + Random sizes_pool( max_size_cnt, face->num_fixed_sizes ); + + for ( int size_cnt = 0; + size_cnt <= max_size_cnt; + size_cnt++ ) + { + FT_Int32 flags = load_flags; + + int size_index = 0; + + if ( !size_cnt ) + { + // set up 20pt at 72dpi as an arbitrary size + if ( FT_Set_Char_Size( face, 20 * 64, 20 * 64, 72, 72 ) ) + continue; + flags |= FT_LOAD_NO_BITMAP; + } + else + { + // bitmap strikes are not active for font variations + if ( instance_index ) + continue; + + size_index = sizes_pool.get() - 1; + + if ( FT_Select_Size( face, size_index ) ) + continue; + flags |= FT_LOAD_COLOR; + } + + // test MM interface only for a face without a selected instance + // and without a selected bitmap strike + if ( !instance_index && !size_cnt ) + setIntermediateAxis( face ); + + // loop over all glyphs + for ( unsigned int glyph_index = 0; + glyph_index < (unsigned int)face->num_glyphs; + glyph_index++ ) + { + if ( FT_Load_Glyph( face, glyph_index, flags ) ) + continue; + + // Rendering is the most expensive and the least interesting part. + // + // if ( FT_Render_Glyph( face->glyph, render_mode) ) + // continue; + // FT_GlyphSlot_Embolden( face->glyph ); + +#if 0 + FT_Glyph glyph; + if ( !FT_Get_Glyph( face->glyph, &glyph ) ) + FT_Done_Glyph( glyph ); + + FT_Outline* outline = &face->glyph->outline; + FT_Matrix rot30 = { 0xDDB4, -0x8000, 0x8000, 0xDDB4 }; + + FT_Outline_Transform( outline, &rot30 ); + + FT_BBox bbox; + FT_Outline_Get_BBox( outline, &bbox ); +#endif + } + } + FT_Done_Face( face ); + } + } + + return 0; + } + + +// END diff --git a/src/3rdparty/freetype/src/tools/ftfuzzer/ftmutator.cc b/src/3rdparty/freetype/src/tools/ftfuzzer/ftmutator.cc new file mode 100644 index 0000000000..ae4b140404 --- /dev/null +++ b/src/3rdparty/freetype/src/tools/ftfuzzer/ftmutator.cc @@ -0,0 +1,314 @@ +// ftmutator.cc +// +// A custom fuzzer mutator to test for FreeType with libFuzzer. +// +// Copyright 2015-2018 by +// David Turner, Robert Wilhelm, and Werner Lemberg. +// +// This file is part of the FreeType project, and may only be used, +// modified, and distributed under the terms of the FreeType project +// license, LICENSE.TXT. By continuing to use, modify, or distribute +// this file you indicate that you have read the license and +// understand and accept it fully. + + +// Since `tar' is not a valid format for input to FreeType, treat any input +// that looks like `tar' as multiple files and mutate them separately. +// +// In the future, a variation of this may be used to guide mutation on a +// logically higher level. + + +// we use `unique_ptr', `decltype', and other gimmicks defined since C++11 +#if __cplusplus < 201103L +# error "a C++11 compiler is needed" +#endif + +#include <cstdint> +#include <cassert> +#include <cstdio> +#include <cstdlib> +#include <cstddef> +#include <cstring> +#include <iostream> + +#include <memory> +#include <vector> + +#include <archive.h> +#include <archive_entry.h> + +#include "FuzzerInterface.h" + + + using namespace std; + + + // This function should be defined by `ftfuzzer.cc'. + extern "C" int + LLVMFuzzerTestOneInput( const uint8_t* Data, + size_t Size ); + + + static void + check_result( struct archive* a, + int r ) + { + if ( r == ARCHIVE_OK ) + return; + + const char* m = archive_error_string( a ); + write( 1, m, strlen( m ) ); + exit( 1 ); + } + + + static int + archive_read_entry_data( struct archive *ar, + vector<uint8_t> *vw ) + { + int r; + const uint8_t* buff; + size_t size; + int64_t offset; + + for (;;) + { + r = archive_read_data_block( ar, + reinterpret_cast<const void**>( &buff ), + &size, + &offset ); + if ( r == ARCHIVE_EOF ) + return ARCHIVE_OK; + if ( r != ARCHIVE_OK ) + return r; + + vw->insert( vw->end(), buff, buff + size ); + } + } + + + static vector<vector<uint8_t>> + parse_data( const uint8_t* data, + size_t size ) + { + struct archive_entry* entry; + int r; + vector<vector<uint8_t>> files; + + unique_ptr<struct archive, + decltype ( archive_read_free )*> a( archive_read_new(), + archive_read_free ); + + // activate reading of uncompressed tar archives + archive_read_support_format_tar( a.get() ); + + // the need for `const_cast' was removed with libarchive commit be4d4dd + if ( !( r = archive_read_open_memory( + a.get(), + const_cast<void*>(static_cast<const void*>( data ) ), + size ) ) ) + { + unique_ptr<struct archive, + decltype ( archive_read_close )*> a_open( a.get(), + archive_read_close ); + + // read files contained in archive + for (;;) + { + r = archive_read_next_header( a_open.get(), &entry ); + if ( r == ARCHIVE_EOF ) + break; + if ( r != ARCHIVE_OK ) + break; + + vector<uint8_t> entry_data; + r = archive_read_entry_data( a.get(), &entry_data ); + if ( entry_data.size() == 0 ) + continue; + + files.push_back( move( entry_data ) ); + if ( r != ARCHIVE_OK ) + break; + } + } + + return files; + } + + + class FTFuzzer + : public fuzzer::UserSuppliedFuzzer + { + + public: + FTFuzzer( fuzzer::FuzzerRandomBase* Rand ) + : fuzzer::UserSuppliedFuzzer( Rand ) {} + + + int + TargetFunction( const uint8_t* Data, + size_t Size ) + { + return LLVMFuzzerTestOneInput( Data, Size ); + } + + + // Custom mutator. + virtual size_t + Mutate( uint8_t* Data, + size_t Size, + size_t MaxSize ) + { + vector<vector<uint8_t>> files = parse_data( Data, Size ); + + // If the file was not recognized as a tar file, treat it as non-tar. + if ( files.size() == 0 ) + return fuzzer::UserSuppliedFuzzer::Mutate( Data, Size, MaxSize ); + + // This is somewhat `white box' on tar. The tar format uses 512 byte + // blocks. One block as header for each file, two empty blocks of 0's + // at the end. File data is padded to fill its last block. + size_t used_blocks = files.size() + 2; + for ( const auto& file : files ) + used_blocks += ( file.size() + 511 ) / 512; + + size_t max_blocks = MaxSize / 512; + + // If the input is big, it will need to be downsized. If the original + // tar file was too big, it may have been clipped to fit. In this + // case it may not be possible to properly write out the data, as + // there may not be enough space for the trailing two blocks. Start + // dropping file data or files from the end. + for ( size_t i = files.size(); + i-- > 1 && used_blocks > max_blocks; ) + { + size_t blocks_to_free = used_blocks - max_blocks; + size_t blocks_currently_used_by_file_data = + ( files[i].size() + 511 ) / 512; + + if ( blocks_currently_used_by_file_data >= blocks_to_free ) + { + files[i].resize( ( blocks_currently_used_by_file_data - + blocks_to_free ) * 512 ); + used_blocks -= blocks_to_free; + continue; + } + + files.pop_back(); + used_blocks -= blocks_currently_used_by_file_data + 1; + } + + // If we get down to one file, don't use tar. + if ( files.size() == 1 ) + { + memcpy( Data, files[0].data(), files[0].size() ); + return fuzzer::UserSuppliedFuzzer::Mutate( Data, + files[0].size(), + MaxSize ); + } + + size_t free_blocks = max_blocks - used_blocks; + + // Allow each file to use up as much of the currently available space + // it can. If it uses or gives up blocks, add them or remove them + // from the pool. + for ( auto&& file : files ) + { + size_t blocks_currently_used_by_file = ( file.size() + 511 ) / 512; + size_t blocks_available = blocks_currently_used_by_file + + free_blocks; + size_t max_size = blocks_available * 512; + size_t data_size = file.size(); + + file.resize( max_size ); + file.resize( fuzzer::UserSuppliedFuzzer::Mutate( file.data(), + data_size, + max_size ) ); + + size_t blocks_now_used_by_file = ( file.size() + 511 ) / 512; + free_blocks = free_blocks + + blocks_currently_used_by_file - + blocks_now_used_by_file; + } + + unique_ptr<struct archive, + decltype ( archive_write_free )*> a( archive_write_new(), + archive_write_free ); + + check_result( a.get(), archive_write_add_filter_none( a.get() ) ); + check_result( a.get(), archive_write_set_format_ustar( a.get() ) ); + + // `used' may not be correct until after the archive is closed. + size_t used = 0xbadbeef; + check_result( a.get(), archive_write_open_memory( a.get(), + Data, + MaxSize, + &used ) ); + + { + unique_ptr<struct archive, + decltype ( archive_write_close )*> a_open( a.get(), + archive_write_close ); + + int file_index = 0; + for ( const auto& file : files ) + { + unique_ptr<struct archive_entry, + decltype ( archive_entry_free )*> + e( archive_entry_new2( a_open.get() ), + archive_entry_free ); + + char name_buffer[100]; + snprintf( name_buffer, 100, "file%d", file_index++ ); + + archive_entry_set_pathname( e.get(), name_buffer ); + archive_entry_set_size( e.get(), file.size() ); + archive_entry_set_filetype( e.get(), AE_IFREG ); + archive_entry_set_perm( e.get(), 0644 ); + + check_result( a_open.get(), + archive_write_header( a_open.get(), e.get() ) ); + archive_write_data( a_open.get(), file.data(), file.size() ); + check_result( a_open.get(), + archive_write_finish_entry( a_open.get() ) ); + } + } + + return used; + } + + + // Cross `Data1' and `Data2', write up to `MaxOutSize' bytes into `Out', + // return the number of bytes written, which should be positive. + virtual size_t + CrossOver( const uint8_t* Data1, + size_t Size1, + const uint8_t* Data2, + size_t Size2, + uint8_t* Out, + size_t MaxOutSize ) + { + return fuzzer::UserSuppliedFuzzer::CrossOver( Data1, + Size1, + Data2, + Size2, + Out, + MaxOutSize ); + } + + }; // end of FTFuzzer class + + + int + main( int argc, + char* *argv ) + { + fuzzer::FuzzerRandomLibc Rand( 0 ); + FTFuzzer F( &Rand ); + + fuzzer::FuzzerDriver( argc, argv, F ); + } + + +// END diff --git a/src/3rdparty/freetype/src/tools/ftfuzzer/rasterfuzzer.cc b/src/3rdparty/freetype/src/tools/ftfuzzer/rasterfuzzer.cc new file mode 100644 index 0000000000..c69b95ea0f --- /dev/null +++ b/src/3rdparty/freetype/src/tools/ftfuzzer/rasterfuzzer.cc @@ -0,0 +1,129 @@ +// rasterfuzzer.cc +// +// A fuzzing function to test FreeType's rasterizers with libFuzzer. +// +// Copyright 2016-2018 by +// David Turner, Robert Wilhelm, and Werner Lemberg. +// +// This file is part of the FreeType project, and may only be used, +// modified, and distributed under the terms of the FreeType project +// license, LICENSE.TXT. By continuing to use, modify, or distribute +// this file you indicate that you have read the license and +// understand and accept it fully. + + +#include <stdint.h> + +#include <vector> + + + using namespace std; + + +#include <ft2build.h> + +#include FT_FREETYPE_H +#include FT_IMAGE_H +#include FT_OUTLINE_H + + + static FT_Library library; + static int InitResult; + + + struct FT_Global { + FT_Global() { + InitResult = FT_Init_FreeType( &library ); + } + ~FT_Global() { + FT_Done_FreeType( library ); + } + }; + + FT_Global global_ft; + + + extern "C" int + LLVMFuzzerTestOneInput( const uint8_t* data, + size_t size_ ) + { + unsigned char pixels[4]; + + FT_Bitmap bitmap_mono = { + 1, // rows + 1, // width + 4, // pitch + pixels, // buffer + 2, // num_grays + FT_PIXEL_MODE_MONO, // pixel_mode + 0, // palette_mode + NULL // palette + }; + + FT_Bitmap bitmap_gray = { + 1, // rows + 1, // width + 4, // pitch + pixels, // buffer + 256, // num_grays + FT_PIXEL_MODE_GRAY, // pixel_mode + 0, // palette_mode + NULL // palette + }; + + const size_t vsize = sizeof ( FT_Vector ); + const size_t tsize = sizeof ( char ); + + // we use the input data for both points and tags + short n_points = short( size_ / ( vsize + tsize ) ); + if ( n_points <= 2 ) + return 0; + + FT_Vector* points = reinterpret_cast<FT_Vector*>( + const_cast<uint8_t*>( + data ) ); + char* tags = reinterpret_cast<char*>( + const_cast<uint8_t*>( + data + size_t( n_points ) * vsize ) ); + + // to reduce the number of invalid outlines that are immediately + // rejected in `FT_Outline_Render', limit values to 2^18 pixels + // (i.e., 2^24 bits) + for ( short i = 0; i < n_points; i++ ) + { + if ( points[i].x == LONG_MIN ) + points[i].x = 0; + else if ( points[i].x < 0 ) + points[i].x = -( -points[i].x & 0xFFFFFF ) - 1; + else + points[i].x = ( points[i].x & 0xFFFFFF ) + 1; + + if ( points[i].y == LONG_MIN ) + points[i].y = 0; + else if ( points[i].y < 0 ) + points[i].y = -( -points[i].y & 0xFFFFFF ) - 1; + else + points[i].y = ( points[i].y & 0xFFFFFF ) + 1; + } + + short contours[1]; + contours[0] = n_points - 1; + + FT_Outline outline = + { + 1, // n_contours + n_points, // n_points + points, // points + tags, // tags + contours, // contours + FT_OUTLINE_NONE // flags + }; + + FT_Outline_Get_Bitmap( library, &outline, &bitmap_mono ); + FT_Outline_Get_Bitmap( library, &outline, &bitmap_gray ); + + return 0; + } + + +// END diff --git a/src/3rdparty/freetype/src/tools/ftfuzzer/runinput.cc b/src/3rdparty/freetype/src/tools/ftfuzzer/runinput.cc new file mode 100644 index 0000000000..2b02f57580 --- /dev/null +++ b/src/3rdparty/freetype/src/tools/ftfuzzer/runinput.cc @@ -0,0 +1,58 @@ +// runinput.cc +// +// A `main' function for fuzzers like `ftfuzzer.cc'. +// +// Copyright 2015-2018 by +// David Turner, Robert Wilhelm, and Werner Lemberg. +// +// This file is part of the FreeType project, and may only be used, +// modified, and distributed under the terms of the FreeType project +// license, LICENSE.TXT. By continuing to use, modify, or distribute +// this file you indicate that you have read the license and +// understand and accept it fully. + + +#include <assert.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <stdint.h> + + + extern "C" void + LLVMFuzzerTestOneInput( const uint8_t* data, + size_t size ); + + + unsigned char a[1 << 24]; + + + int + main( int argc, + char* *argv ) + { + assert( argc >= 2 ); + + for ( int i = 1; i < argc; i++ ) + { + fprintf( stderr, "%s\n", argv[i] ); + + FILE* f = fopen( argv[i], "r" ); + assert( f ); + + size_t n = fread( a, 1, sizeof ( a ), f ); + fclose( f ); + if ( !n ) + continue; + + unsigned char* b = (unsigned char*)malloc( n ); + memcpy( b, a, n ); + + LLVMFuzzerTestOneInput( b, n ); + + free( b ); + } + } + + +// END diff --git a/src/3rdparty/freetype/src/tools/ftrandom/Makefile b/src/3rdparty/freetype/src/tools/ftrandom/Makefile index 2e619299cd..24dc49c563 100644 --- a/src/3rdparty/freetype/src/tools/ftrandom/Makefile +++ b/src/3rdparty/freetype/src/tools/ftrandom/Makefile @@ -5,7 +5,12 @@ TOP_DIR ?= ../../.. OBJ_DIR ?= $(TOP_DIR)/objs -# The setup below is for gcc on a Unix-like platform. +# The setup below is for gcc on a Unix-like platform, +# where FreeType has been set up to create a static library +# (which is the default). + +VPATH = $(OBJ_DIR) \ + $(OBJ_DIR)/.libs SRC_DIR = $(TOP_DIR)/src/tools/ftrandom @@ -20,16 +25,21 @@ WFLAGS = -Wmissing-prototypes \ -Wchar-subscripts \ -Wsequence-point CFLAGS = $(WFLAGS) \ - -g \ - -I $(TOP_DIR)/include + -g +INCLUDES = -I $(TOP_DIR)/include +LDFLAGS = LIBS = -lm \ - -L $(OBJ_DIR) \ - -lfreetype \ - -lz + -lz \ + -lpng \ + -lbz2 \ + -lharfbuzz all: $(OBJ_DIR)/ftrandom -$(OBJ_DIR)/ftrandom: $(SRC_DIR)/ftrandom.c $(OBJ_DIR)/libfreetype.a - $(CC) -o $(OBJ_DIR)/ftrandom $(CFLAGS) $(SRC_DIR)/ftrandom.c $(LIBS) +$(OBJ_DIR)/ftrandom.o: $(SRC_DIR)/ftrandom.c + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $< + +$(OBJ_DIR)/ftrandom: $(OBJ_DIR)/ftrandom.o libfreetype.a + $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) # EOF diff --git a/src/3rdparty/freetype/src/tools/ftrandom/README b/src/3rdparty/freetype/src/tools/ftrandom/README index 71bf05323d..7c610864b6 100644 --- a/src/3rdparty/freetype/src/tools/ftrandom/README +++ b/src/3rdparty/freetype/src/tools/ftrandom/README @@ -1,48 +1,69 @@ ftrandom --------- +======== This program expects a set of directories containing good fonts, and a set of extensions of fonts to be tested. It will randomly pick a font, copy it, -introduce and error and then test it. +introduce an error and then test it. -The FreeType tests are quite basic: +The FreeType tests are quite basic; for each erroneous font ftrandom - For each erroneous font it - forks off a new tester; - initializes the library; - opens each font in the file; - loads each glyph; - (optionally reviewing the contours of the glyph) - (optionally rasterizing) - closes the face. + . forks off a new tester, + . initializes the library, + . opens each font in the file, + . loads each glyph, + . optionally reviews the contours of the glyph, + . optionally rasterizes the glyph, and + . closes the face. -If the tester exits with a signal, or takes longer than 20 seconds then -ftrandom saves the erroneous font and continues. If the tester exits -normally or with an error, then the superstructure removes the test font and -continues. +If a tester takes longer than 20 seconds, ftrandom saves the erroneous font +and continues. If the tester exits normally or with an error, then the +superstructure removes the test font and continues. -Arguments are: + +Command line options +-------------------- --all Test every font in the directory(ies) no matter - what its extension (some CID-keyed fonts have no - extension). - --check-outlines Call FT_Outline_Decompose on each glyph. + what its extension. + --check-outlines Call `FT_Outline_Decompose' on each glyph. --dir <dir> Append <dir> to the list of directories to search - for good fonts. + for good fonts. No recursive search. --error-count <cnt> Introduce <cnt> single-byte errors into the - erroneous fonts. + erroneous fonts (default: 1). --error-fraction <frac> Multiply the file size of the font by <frac> and introduce that many errors into the erroneous - font file. - --ext <ext> Add <ext> to the set of font types tested. Known - extensions are `ttf', `otf', `ttc', `cid', `pfb', - `pfa', `bdf', `pcf', `pfr', `fon', `otb', and - `cff'. + font file. <frac> should be in the range [0;1] + (default: 0.0). + --ext <ext> Add <ext> to the set of font types tested. --help Print out this list of options. --nohints Specify FT_LOAD_NO_HINTING when loading glyphs. - --rasterize Call FT_Render_Glyph as well as loading it. + --rasterize Call `FT_Render_Glyph' as well as loading it. --result <dir> This is the directory in which test files are placed. --test <file> Run a single test on a pre-generated testcase. - Done in the current process so it can be debugged - more easily. + This is done in the current process so it can be + debugged more easily. + +The default font extensions tested by ftrandom are + + .ttf .otf .ttc .cid .pfb .pfa .bdf .pcf .pfr .fon .otb .cff + +The default font directory is controlled by the macro `GOOD_FONTS_DIR' in +the source code (and can be thus specified during compilation); its default +value is + + /usr/local/share/fonts + +The default result directory is `results' (in the current directory). + + +Compilation +----------- + +Two possible solutions. + +. Run ftrandom within a debugging tool like `valgrind' to catch various + memory issues. + +. Compile FreeType with sanitizer flags as provided by gcc or clang, for + example, then link it with ftrandom. diff --git a/src/3rdparty/freetype/src/tools/ftrandom/ftrandom.c b/src/3rdparty/freetype/src/tools/ftrandom/ftrandom.c index 9a5b632673..ab5cfc98b6 100644 --- a/src/3rdparty/freetype/src/tools/ftrandom/ftrandom.c +++ b/src/3rdparty/freetype/src/tools/ftrandom/ftrandom.c @@ -29,6 +29,9 @@ /* This file is now part of the FreeType library */ +#define _XOPEN_SOURCE 500 /* for `kill', `strdup', `random', and `srandom' */ + + #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -38,7 +41,6 @@ #include <sys/wait.h> #include <unistd.h> #include <dirent.h> -#include <math.h> #include <signal.h> #include <time.h> @@ -56,7 +58,7 @@ static int rasterize = false; static char* results_dir = "results"; -#define GOOD_FONTS_DIR "/home/wl/freetype-testfonts" +#define GOOD_FONTS_DIR "/usr/local/share/fonts" static char* default_dir_list[] = { @@ -81,28 +83,31 @@ NULL }; - static int error_count = 1; - static int error_fraction = 0; + static unsigned int error_count = 1; + static double error_fraction = 0.0; static FT_F26Dot6 font_size = 12 * 64; static struct fontlist { char* name; - int len; + long len; unsigned int isbinary: 1; unsigned int isascii: 1; unsigned int ishex: 1; } *fontlist; - static int fcnt; + static unsigned int fcnt; static int FT_MoveTo( const FT_Vector *to, void *user ) { + FT_UNUSED( to ); + FT_UNUSED( user ); + return 0; } @@ -111,6 +116,9 @@ FT_LineTo( const FT_Vector *to, void *user ) { + FT_UNUSED( to ); + FT_UNUSED( user ); + return 0; } @@ -120,6 +128,10 @@ const FT_Vector *to, void *user ) { + FT_UNUSED( _cp ); + FT_UNUSED( to ); + FT_UNUSED( user ); + return 0; } @@ -130,6 +142,11 @@ const FT_Vector *to, void *user ) { + FT_UNUSED( cp1 ); + FT_UNUSED( cp2 ); + FT_UNUSED( to ); + FT_UNUSED( user ); + return 0; } @@ -147,8 +164,8 @@ static void TestFace( FT_Face face ) { - int gid; - int load_flags = FT_LOAD_DEFAULT; + unsigned int gid; + int load_flags = FT_LOAD_DEFAULT; if ( check_outlines && @@ -160,7 +177,7 @@ FT_Set_Char_Size( face, 0, font_size, 72, 72 ); - for ( gid = 0; gid < face->num_glyphs; ++gid ) + for ( gid = 0; gid < face->num_glyphs; gid++ ) { if ( check_outlines && FT_IS_SCALABLE( face ) ) @@ -202,19 +219,21 @@ TestFace( face ); else { - int i, num; + long i, num; num = face->num_faces; FT_Done_Face( face ); - for ( i = 0; i < num; ++i ) + for ( i = 0; i < num; i++ ) { if ( !FT_New_Face( context, testfont, i, &face ) ) TestFace( face ); } } + FT_Done_FreeType( context ); + exit( 0 ); } @@ -227,16 +246,16 @@ char* pt; - if ( extensions == NULL ) + if ( !extensions ) return true; pt = strrchr( filename, '.' ); - if ( pt == NULL ) + if ( !pt ) return false; if ( pt < strrchr( filename, '/' ) ) return false; - for ( i = 0; extensions[i] != NULL; ++i ) + for ( i = 0; extensions[i] != NULL; i++ ) if ( strcasecmp( pt + 1, extensions[i] ) == 0 || strcasecmp( pt, extensions[i] ) == 0 ) return true; @@ -254,7 +273,7 @@ item->isbinary = item->isascii = item->ishex = false; foo = fopen( item->name, "rb" ); - if ( foo != NULL ) + if ( foo ) { /* Try to guess the file type from the first few characters... */ int ch1 = getc( foo ); @@ -281,8 +300,8 @@ else if ( ch1 == '%' && ch2 == '!' ) { /* Random PostScript */ - if ( strstr( item->name, ".pfa" ) != NULL || - strstr( item->name, ".PFA" ) != NULL ) + if ( strstr( item->name, ".pfa" ) || + strstr( item->name, ".PFA" ) ) item->ishex = true; else item->isascii = true; @@ -329,22 +348,23 @@ FindFonts( char** fontdirs, char** extensions ) { - int i, max; - char buffer[1025]; - struct stat statb; + int i; + unsigned int max; + char buffer[1025]; + struct stat statb; max = 0; fcnt = 0; - for ( i = 0; fontdirs[i] != NULL; ++i ) + for ( i = 0; fontdirs[i] != NULL; i++ ) { DIR* examples; struct dirent* ent; examples = opendir( fontdirs[i] ); - if ( examples == NULL ) + if ( !examples ) { fprintf( stderr, "Can't open example font directory `%s'\n", @@ -358,13 +378,13 @@ "%s/%s", fontdirs[i], ent->d_name ); if ( stat( buffer, &statb ) == -1 || S_ISDIR( statb.st_mode ) ) continue; - if ( extensions == NULL || extmatch( buffer, extensions ) ) + if ( !extensions || extmatch( buffer, extensions ) ) { if ( fcnt >= max ) { max += 100; fontlist = realloc( fontlist, max * sizeof ( struct fontlist ) ); - if ( fontlist == NULL ) + if ( !fontlist ) { fprintf( stderr, "Can't allocate memory\n" ); exit( 1 ); @@ -375,7 +395,7 @@ fontlist[fcnt].len = statb.st_size; figurefiletype( &fontlist[fcnt] ); - ++fcnt; + fcnt++; } } @@ -392,13 +412,13 @@ } - static int + static unsigned int getErrorCnt( struct fontlist* item ) { - if ( error_count == 0 && error_fraction == 0 ) + if ( error_count == 0 && error_fraction == 0.0 ) return 0; - return error_count + ceil( error_fraction * item->len ); + return error_count + (unsigned int)( error_fraction * item->len ); } @@ -417,21 +437,21 @@ copyfont( struct fontlist* item, char* newfont ) { - static char buffer[8096]; - FILE *good, *new; - int len; - int i, err_cnt; + static char buffer[8096]; + FILE *good, *newf; + size_t len; + unsigned int i, err_cnt; good = fopen( item->name, "r" ); - if ( good == NULL ) + if ( !good ) { fprintf( stderr, "Can't open `%s'\n", item->name ); return false; } - new = fopen( newfont, "w+" ); - if ( new == NULL ) + newf = fopen( newfont, "w+" ); + if ( !newf ) { fprintf( stderr, "Can't create temporary output file `%s'\n", newfont ); @@ -439,19 +459,19 @@ } while ( ( len = fread( buffer, 1, sizeof ( buffer ), good ) ) > 0 ) - fwrite( buffer, 1, len, new ); + fwrite( buffer, 1, len, newf ); fclose( good ); err_cnt = getErrorCnt( item ); - for ( i = 0; i < err_cnt; ++i ) + for ( i = 0; i < err_cnt; i++ ) { - fseek( new, getRandom( 0, item->len - 1 ), SEEK_SET ); + fseek( newf, getRandom( 0, (int)( item->len - 1 ) ), SEEK_SET ); if ( item->isbinary ) - putc( getRandom( 0, 0xFF ), new ); + putc( getRandom( 0, 0xFF ), newf ); else if ( item->isascii ) - putc( getRandom( 0x20, 0x7E ), new ); + putc( getRandom( 0x20, 0x7E ), newf ); else { int hex = getRandom( 0, 15 ); @@ -462,18 +482,18 @@ else hex += 'A' - 10; - putc( hex, new ); + putc( hex, newf ); } } - if ( ferror( new ) ) + if ( ferror( newf ) ) { - fclose( new ); + fclose( newf ); unlink( newfont ); return false; } - fclose( new ); + fclose( newf ); return true; } @@ -484,6 +504,8 @@ static void abort_test( int sig ) { + FT_UNUSED( sig ); + /* If a time-out happens, then kill the child */ kill( child_pid, SIGFPE ); write( 2, "Timeout... ", 11 ); @@ -493,7 +515,7 @@ static void do_test( void ) { - int i = getRandom( 0, fcnt - 1 ); + int i = getRandom( 0, (int)( fcnt - 1 ) ); static int test_num = 0; char buffer[1024]; @@ -534,22 +556,42 @@ usage( FILE* out, char* name ) { + char** d = default_dir_list; + char** e = default_ext_list; + + fprintf( out, "%s [options] -- Generate random erroneous fonts\n" " and attempt to parse them with FreeType.\n\n", name ); fprintf( out, " --all All non-directory files are assumed to be fonts.\n" ); fprintf( out, " --check-outlines Make sure we can parse the outlines of each glyph.\n" ); - fprintf( out, " --dir <path> Append <path> to list of font search directories.\n" ); - fprintf( out, " --error-count <cnt> Introduce <cnt> single byte errors into each font.\n" ); + fprintf( out, " --dir <path> Append <path> to list of font search directories\n" + " (no recursive search).\n" ); + fprintf( out, " --error-count <cnt> Introduce <cnt> single byte errors into each font\n" + " (default: 1)\n" ); fprintf( out, " --error-fraction <frac> Introduce <frac>*filesize single byte errors\n" - " into each font.\n" ); + " into each font (default: 0.0).\n" ); fprintf( out, " --ext <ext> Add <ext> to list of extensions indicating fonts.\n" ); fprintf( out, " --help Print this.\n" ); fprintf( out, " --nohints Turn off hinting.\n" ); fprintf( out, " --rasterize Attempt to rasterize each glyph.\n" ); - fprintf( out, " --results <dir> Directory in which to place the test fonts.\n" ); + fprintf( out, " --results <path> Place the created test fonts into <path>\n" + " (default: `results')\n" ); fprintf( out, " --size <float> Use the given font size for the tests.\n" ); fprintf( out, " --test <file> Run a single test on an already existing file.\n" ); + fprintf( out, "\n" ); + + fprintf( out, "Default font extensions:\n" ); + fprintf( out, " " ); + while ( *e ) + fprintf( out, " .%s", *e++ ); + fprintf( out, "\n" ); + + fprintf( out, "Default font directories:\n" ); + fprintf( out, " " ); + while ( *d ) + fprintf( out, " %s", *d++ ); + fprintf( out, "\n" ); } @@ -564,17 +606,17 @@ char* testfile = NULL; - dirs = calloc( argc + 1, sizeof ( char ** ) ); - exts = calloc( argc + 1, sizeof ( char ** ) ); + dirs = calloc( (size_t)( argc + 1 ), sizeof ( char ** ) ); + exts = calloc( (size_t)( argc + 1 ), sizeof ( char ** ) ); - for ( i = 1; i < argc; ++i ) + for ( i = 1; i < argc; i++ ) { char* pt = argv[i]; char* end; if ( pt[0] == '-' && pt[1] == '-' ) - ++pt; + pt++; if ( strcmp( pt, "-all" ) == 0 ) allexts = true; @@ -585,9 +627,9 @@ else if ( strcmp( pt, "-error-count" ) == 0 ) { if ( !rset ) - error_fraction = 0; + error_fraction = 0.0; rset = true; - error_count = strtol( argv[++i], &end, 10 ); + error_count = (unsigned int)strtoul( argv[++i], &end, 10 ); if ( *end != '\0' ) { fprintf( stderr, "Bad value for error-count: %s\n", argv[i] ); @@ -605,6 +647,11 @@ fprintf( stderr, "Bad value for error-fraction: %s\n", argv[i] ); exit( 1 ); } + if ( error_fraction < 0.0 || error_fraction > 1.0 ) + { + fprintf( stderr, "error-fraction must be in the range [0;1]\n" ); + exit( 1 ); + } } else if ( strcmp( pt, "-ext" ) == 0 ) exts[ecnt++] = argv[++i]; @@ -654,11 +701,11 @@ dirs = default_dir_list; } - if ( testfile != NULL ) + if ( testfile ) ExecuteTest( testfile ); /* This should never return */ time( &now ); - srandom( now ); + srandom( (unsigned int)now ); FindFonts( dirs, exts ); mkdir( results_dir, 0755 ); diff --git a/src/3rdparty/freetype/src/tools/glnames.py b/src/3rdparty/freetype/src/tools/glnames.py index 0ad554c72d..b048d29364 100644 --- a/src/3rdparty/freetype/src/tools/glnames.py +++ b/src/3rdparty/freetype/src/tools/glnames.py @@ -6,7 +6,7 @@ # -# Copyright 1996-2015 by +# Copyright 1996-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, @@ -151,7 +151,7 @@ mac_standard_names = \ # The list of standard `SID' glyph names. For the official list, # see Annex A of document at # -# http://partners.adobe.com/public/developer/en/font/5176.CFF.pdf . +# https://www.adobe.com/content/dam/acom/en/devnet/font/pdfs/5176.CFF.pdf . # sid_standard_names = \ [ @@ -415,7 +415,7 @@ t1_expert_encoding = \ # This data has been taken literally from the files `glyphlist.txt' # and `zapfdingbats.txt' version 2.0, Sept 2002. It is available from # -# http://sourceforge.net/adobe/aglfn/ +# https://github.com/adobe-type-tools/agl-aglfn # adobe_glyph_list = """\ A;0041 @@ -4920,8 +4920,17 @@ class StringTable: def dump( self, file ): write = file.write - write( " static const char " + self.master_table + - "[" + repr( self.total ) + "] =\n" ) + write( "#ifndef DEFINE_PS_TABLES_DATA\n" ) + write( "#ifdef __cplusplus\n" ) + write( ' extern "C"\n' ) + write( "#else\n" ) + write( " extern\n" ) + write( "#endif\n" ) + write( "#endif\n" ) + write( " const char " + self.master_table + + "[" + repr( self.total ) + "]\n" ) + write( "#ifdef DEFINE_PS_TABLES_DATA\n" ) + write( " =\n" ) write( " {\n" ) line = "" @@ -4930,7 +4939,10 @@ class StringTable: line += string.join( ( re.findall( ".", name ) ), "','" ) line += "', 0,\n" - write( line + " };\n\n\n" ) + write( line ) + write( " }\n" ) + write( "#endif /* DEFINE_PS_TABLES_DATA */\n" ) + write( " ;\n\n\n" ) def dump_sublist( self, file, table_name, macro_name, sublist ): write = file.write @@ -4938,8 +4950,17 @@ class StringTable: write( " /* Values are offsets into the `" + self.master_table + "' table */\n\n" ) - write( " static const short " + table_name + - "[" + macro_name + "] =\n" ) + write( "#ifndef DEFINE_PS_TABLES_DATA\n" ) + write( "#ifdef __cplusplus\n" ) + write( ' extern "C"\n' ) + write( "#else\n" ) + write( " extern\n" ) + write( "#endif\n" ) + write( "#endif\n" ) + write( " const short " + table_name + + "[" + macro_name + "]\n" ) + write( "#ifdef DEFINE_PS_TABLES_DATA\n" ) + write( " =\n" ) write( " {\n" ) line = " " @@ -4955,7 +4976,11 @@ class StringTable: col = 0 comma = ",\n " - write( line + "\n };\n\n\n" ) + write( line ) + write( "\n" ) + write( " }\n" ) + write( "#endif /* DEFINE_PS_TABLES_DATA */\n" ) + write( " ;\n\n\n" ) # We now store the Adobe Glyph List in compressed form. The list is put @@ -5188,8 +5213,17 @@ def dump_encoding( file, encoding_name, encoding_list ): write = file.write write( " /* the following are indices into the SID name table */\n" ) - write( " static const unsigned short " + encoding_name + - "[" + repr( len( encoding_list ) ) + "] =\n" ) + write( "#ifndef DEFINE_PS_TABLES_DATA\n" ) + write( "#ifdef __cplusplus\n" ) + write( ' extern "C"\n' ) + write( "#else\n" ) + write( " extern\n" ) + write( "#endif\n" ) + write( "#endif\n" ) + write( " const unsigned short " + encoding_name + + "[" + repr( len( encoding_list ) ) + "]\n" ) + write( "#ifdef DEFINE_PS_TABLES_DATA\n" ) + write( " =\n" ) write( " {\n" ) line = " " @@ -5204,14 +5238,27 @@ def dump_encoding( file, encoding_name, encoding_list ): col = 0 comma = ",\n " - write( line + "\n };\n\n\n" ) + write( line ) + write( "\n" ) + write( " }\n" ) + write( "#endif /* DEFINE_PS_TABLES_DATA */\n" ) + write( " ;\n\n\n" ) def dump_array( the_array, write, array_name ): """dumps a given encoding""" - write( " static const unsigned char " + array_name + - "[" + repr( len( the_array ) ) + "L] =\n" ) + write( "#ifndef DEFINE_PS_TABLES_DATA\n" ) + write( "#ifdef __cplusplus\n" ) + write( ' extern "C"\n' ) + write( "#else\n" ) + write( " extern\n" ) + write( "#endif\n" ) + write( "#endif\n" ) + write( " const unsigned char " + array_name + + "[" + repr( len( the_array ) ) + "L]\n" ) + write( "#ifdef DEFINE_PS_TABLES_DATA\n" ) + write( " =\n" ) write( " {\n" ) line = "" @@ -5232,7 +5279,11 @@ def dump_array( the_array, write, array_name ): write( line ) line = "" - write( line + "\n };\n\n\n" ) + write( line ) + write( "\n" ) + write( " }\n" ) + write( "#endif /* DEFINE_PS_TABLES_DATA */\n" ) + write( " ;\n\n\n" ) def main(): @@ -5242,7 +5293,7 @@ def main(): print __doc__ % sys.argv[0] sys.exit( 1 ) - file = open( sys.argv[1], "w\n" ) + file = open( sys.argv[1], "wb" ) write = file.write count_sid = len( sid_standard_names ) @@ -5267,7 +5318,7 @@ def main(): write( "/* */\n" ) write( "/* PostScript glyph names. */\n" ) write( "/* */\n" ) - write( "/* Copyright 2005-2015 by */\n" ) + write( "/* Copyright 2005-2018 by */\n" ) write( "/* David Turner, Robert Wilhelm, and Werner Lemberg. */\n" ) write( "/* */\n" ) write( "/* This file is part of the FreeType project, and may only be used, */\n" ) @@ -5327,6 +5378,7 @@ def main(): # write the lookup routine now # write( """\ +#ifdef DEFINE_PS_TABLES /* * This function searches the compressed table efficiently. */ @@ -5421,6 +5473,7 @@ def main(): NotFound: return 0; } +#endif /* DEFINE_PS_TABLES */ #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */ diff --git a/src/3rdparty/freetype/src/tools/no-copyright b/src/3rdparty/freetype/src/tools/no-copyright index 5011e3fb62..d639aa4a84 100644 --- a/src/3rdparty/freetype/src/tools/no-copyright +++ b/src/3rdparty/freetype/src/tools/no-copyright @@ -14,6 +14,9 @@ builds/unix/pkg.m4 docs/FTL.TXT docs/GPLv2.TXT # +include/freetype/internal/fthash.h +# +src/base/fthash.c src/base/md5.c src/base/md5.h # @@ -56,6 +59,7 @@ src/gzip/zlib.h src/gzip/zutil.c src/gzip/zutil.h # +src/tools/apinames.c src/tools/ftrandom/ftrandom.c # # EOF diff --git a/src/3rdparty/freetype/src/tools/update-copyright-year b/src/3rdparty/freetype/src/tools/update-copyright-year index 107754183d..934f11cf02 100644 --- a/src/3rdparty/freetype/src/tools/update-copyright-year +++ b/src/3rdparty/freetype/src/tools/update-copyright-year @@ -2,7 +2,7 @@ eval '(exit $?0)' && eval 'exec perl -wS -i "$0" ${1+"$@"}' & eval 'exec perl -wS -i "$0" $argv:q' if 0; -# Copyright 2015 by +# Copyright 2015-2018 by # Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/truetype/Jamfile b/src/3rdparty/freetype/src/truetype/Jamfile index 88cc26f2b1..e321fba14a 100644 --- a/src/3rdparty/freetype/src/truetype/Jamfile +++ b/src/3rdparty/freetype/src/truetype/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/truetype Jamfile # -# Copyright 2001-2015 by +# Copyright 2001-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/truetype/module.mk b/src/3rdparty/freetype/src/truetype/module.mk index c6dc6fa6e7..16bc9c8b20 100644 --- a/src/3rdparty/freetype/src/truetype/module.mk +++ b/src/3rdparty/freetype/src/truetype/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2015 by +# Copyright 1996-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/truetype/rules.mk b/src/3rdparty/freetype/src/truetype/rules.mk index 1db16ba35f..e16113f128 100644 --- a/src/3rdparty/freetype/src/truetype/rules.mk +++ b/src/3rdparty/freetype/src/truetype/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2015 by +# Copyright 1996-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/truetype/truetype.c b/src/3rdparty/freetype/src/truetype/truetype.c index f929437dc1..484370975c 100644 --- a/src/3rdparty/freetype/src/truetype/truetype.c +++ b/src/3rdparty/freetype/src/truetype/truetype.c @@ -4,7 +4,7 @@ /* */ /* FreeType TrueType driver component (body only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,22 +17,16 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT - #include <ft2build.h> -#include "ttpic.c" + #include "ttdriver.c" /* driver interface */ -#include "ttpload.c" /* tables loader */ #include "ttgload.c" /* glyph loader */ -#include "ttobjs.c" /* object manager */ - -#ifdef TT_USE_BYTECODE_INTERPRETER -#include "ttinterp.c" -#include "ttsubpix.c" -#endif - -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT #include "ttgxvar.c" /* gx distortable font */ -#endif +#include "ttinterp.c" +#include "ttobjs.c" /* object manager */ +#include "ttpic.c" +#include "ttpload.c" /* tables loader */ +#include "ttsubpix.c" /* END */ diff --git a/src/3rdparty/freetype/src/truetype/ttdriver.c b/src/3rdparty/freetype/src/truetype/ttdriver.c index 08b30c95ad..820cafbb8d 100644 --- a/src/3rdparty/freetype/src/truetype/ttdriver.c +++ b/src/3rdparty/freetype/src/truetype/ttdriver.c @@ -4,7 +4,7 @@ /* */ /* TrueType font driver implementation (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -25,12 +25,13 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT #include FT_MULTIPLE_MASTERS_H #include FT_SERVICE_MULTIPLE_MASTERS_H +#include FT_SERVICE_METRICS_VARIATIONS_H #endif #include FT_SERVICE_TRUETYPE_ENGINE_H #include FT_SERVICE_TRUETYPE_GLYF_H #include FT_SERVICE_PROPERTIES_H -#include FT_TRUETYPE_DRIVER_H +#include FT_DRIVER_H #include "ttdriver.h" #include "ttgload.h" @@ -61,23 +62,50 @@ static FT_Error tt_property_set( FT_Module module, /* TT_Driver */ const char* property_name, - const void* value ) + const void* value, + FT_Bool value_is_string ) { FT_Error error = FT_Err_Ok; TT_Driver driver = (TT_Driver)module; +#ifndef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + FT_UNUSED( value_is_string ); +#endif + if ( !ft_strcmp( property_name, "interpreter-version" ) ) { - FT_UInt* interpreter_version = (FT_UInt*)value; + FT_UInt interpreter_version; -#ifndef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( *interpreter_version != TT_INTERPRETER_VERSION_35 ) - error = FT_ERR( Unimplemented_Feature ); +#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES + if ( value_is_string ) + { + const char* s = (const char*)value; + + + interpreter_version = (FT_UInt)ft_strtol( s, NULL, 10 ); + } else #endif - driver->interpreter_version = *interpreter_version; + { + FT_UInt* iv = (FT_UInt*)value; + + + interpreter_version = *iv; + } + + if ( interpreter_version == TT_INTERPRETER_VERSION_35 +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + || interpreter_version == TT_INTERPRETER_VERSION_38 +#endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + || interpreter_version == TT_INTERPRETER_VERSION_40 +#endif + ) + driver->interpreter_version = interpreter_version; + else + error = FT_ERR( Unimplemented_Feature ); return error; } @@ -117,8 +145,10 @@ FT_DEFINE_SERVICE_PROPERTIESREC( tt_service_properties, - (FT_Properties_SetFunc)tt_property_set, - (FT_Properties_GetFunc)tt_property_get ) + + (FT_Properties_SetFunc)tt_property_set, /* set_property */ + (FT_Properties_GetFunc)tt_property_get /* get_property */ + ) /*************************************************************************/ @@ -194,13 +224,20 @@ FT_Fixed *advances ) { FT_UInt nn; - TT_Face face = (TT_Face) ttface; + TT_Face face = (TT_Face)ttface; /* XXX: TODO: check for sbits */ if ( flags & FT_LOAD_VERTICAL_LAYOUT ) { +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + /* no fast retrieval for blended MM fonts without VVAR table */ + if ( ( FT_IS_NAMED_INSTANCE( ttface ) || FT_IS_VARIATION( ttface ) ) && + !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) + return FT_THROW( Unimplemented_Feature ); +#endif + for ( nn = 0; nn < count; nn++ ) { FT_Short tsb; @@ -214,6 +251,13 @@ } else { +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + /* no fast retrieval for blended MM fonts without HVAR table */ + if ( ( FT_IS_NAMED_INSTANCE( ttface ) || FT_IS_VARIATION( ttface ) ) && + !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) + return FT_THROW( Unimplemented_Feature ); +#endif + for ( nn = 0; nn < count; nn++ ) { FT_Short lsb; @@ -228,6 +272,7 @@ return FT_Err_Ok; } + /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ @@ -259,15 +304,17 @@ /* use the scaled metrics, even when tt_size_reset fails */ FT_Select_Metrics( size->face, strike_index ); - tt_size_reset( ttsize ); /* ignore return value */ + tt_size_reset( ttsize, 0 ); /* ignore return value */ } else { - SFNT_Service sfnt = (SFNT_Service) ttface->sfnt; - FT_Size_Metrics* metrics = &size->metrics; + SFNT_Service sfnt = (SFNT_Service)ttface->sfnt; + FT_Size_Metrics* size_metrics = &size->metrics; - error = sfnt->load_strike_metrics( ttface, strike_index, metrics ); + error = sfnt->load_strike_metrics( ttface, + strike_index, + size_metrics ); if ( error ) ttsize->strike_index = 0xFFFFFFFFUL; } @@ -291,7 +338,7 @@ if ( FT_HAS_FIXED_SIZES( size->face ) ) { TT_Face ttface = (TT_Face)size->face; - SFNT_Service sfnt = (SFNT_Service) ttface->sfnt; + SFNT_Service sfnt = (SFNT_Service)ttface->sfnt; FT_ULong strike_index; @@ -309,8 +356,28 @@ if ( FT_IS_SCALABLE( size->face ) ) { - error = tt_size_reset( ttsize ); - ttsize->root.metrics = ttsize->metrics; + error = tt_size_reset( ttsize, 0 ); + +#ifdef TT_USE_BYTECODE_INTERPRETER + /* for the `MPS' bytecode instruction we need the point size */ + if ( !error ) + { + FT_UInt resolution = + ttsize->metrics->x_ppem > ttsize->metrics->y_ppem + ? req->horiResolution + : req->vertResolution; + + + /* if we don't have a resolution value, assume 72dpi */ + if ( req->type == FT_SIZE_REQUEST_TYPE_SCALES || + !resolution ) + resolution = 72; + + ttsize->point_size = FT_MulDiv( ttsize->ttmetrics.ppem, + 64 * 72, + resolution ); + } +#endif } return error; @@ -392,6 +459,11 @@ load_flags |= FT_LOAD_NO_HINTING; } + /* use hinted metrics only if we load a glyph with hinting */ + size->metrics = ( load_flags & FT_LOAD_NO_HINTING ) + ? &ttsize->metrics + : &size->hinted_metrics; + /* now load the glyph outline if necessary */ error = TT_Load_Glyph( size, slot, glyph_index, load_flags ); @@ -415,24 +487,46 @@ /*************************************************************************/ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_DEFINE_SERVICE_MULTIMASTERSREC( tt_service_gx_multi_masters, - (FT_Get_MM_Func) NULL, - (FT_Set_MM_Design_Func) NULL, - (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, - (FT_Get_MM_Var_Func) TT_Get_MM_Var, - (FT_Set_Var_Design_Func)TT_Set_Var_Design ) -#endif + + (FT_Get_MM_Func) NULL, /* get_mm */ + (FT_Set_MM_Design_Func) NULL, /* set_mm_design */ + (FT_Set_MM_Blend_Func) TT_Set_MM_Blend, /* set_mm_blend */ + (FT_Get_MM_Blend_Func) TT_Get_MM_Blend, /* get_mm_blend */ + (FT_Get_MM_Var_Func) TT_Get_MM_Var, /* get_mm_var */ + (FT_Set_Var_Design_Func)TT_Set_Var_Design, /* set_var_design */ + (FT_Get_Var_Design_Func)TT_Get_Var_Design, /* get_var_design */ + (FT_Set_Instance_Func) TT_Set_Named_Instance, /* set_instance */ + + (FT_Get_Var_Blend_Func) tt_get_var_blend, /* get_var_blend */ + (FT_Done_Blend_Func) tt_done_blend /* done_blend */ + ) + + FT_DEFINE_SERVICE_METRICSVARIATIONSREC( + tt_service_metrics_variations, + + (FT_HAdvance_Adjust_Func)tt_hadvance_adjust, /* hadvance_adjust */ + (FT_LSB_Adjust_Func) NULL, /* lsb_adjust */ + (FT_RSB_Adjust_Func) NULL, /* rsb_adjust */ + + (FT_VAdvance_Adjust_Func)tt_vadvance_adjust, /* vadvance_adjust */ + (FT_TSB_Adjust_Func) NULL, /* tsb_adjust */ + (FT_BSB_Adjust_Func) NULL, /* bsb_adjust */ + (FT_VOrg_Adjust_Func) NULL, /* vorg_adjust */ + + (FT_Metrics_Adjust_Func) tt_apply_mvar /* metrics_adjust */ + ) + +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + static const FT_Service_TrueTypeEngineRec tt_service_truetype_engine = { #ifdef TT_USE_BYTECODE_INTERPRETER -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - FT_TRUETYPE_ENGINE_TYPE_UNPATENTED -#else FT_TRUETYPE_ENGINE_TYPE_PATENTED -#endif #else /* !TT_USE_BYTECODE_INTERPRETER */ @@ -441,21 +535,28 @@ #endif /* TT_USE_BYTECODE_INTERPRETER */ }; + FT_DEFINE_SERVICE_TTGLYFREC( tt_service_truetype_glyf, - (TT_Glyf_GetLocationFunc)tt_face_get_location ) + + (TT_Glyf_GetLocationFunc)tt_face_get_location /* get_location */ + ) + #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - FT_DEFINE_SERVICEDESCREC5( + FT_DEFINE_SERVICEDESCREC6( tt_services, - FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TRUETYPE, - FT_SERVICE_ID_MULTI_MASTERS, &TT_SERVICE_GX_MULTI_MASTERS_GET, - FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, - FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET, - FT_SERVICE_ID_PROPERTIES, &TT_SERVICE_PROPERTIES_GET ) + + FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TRUETYPE, + FT_SERVICE_ID_MULTI_MASTERS, &TT_SERVICE_GX_MULTI_MASTERS_GET, + FT_SERVICE_ID_METRICS_VARIATIONS, &TT_SERVICE_METRICS_VARIATIONS_GET, + FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, + FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET, + FT_SERVICE_ID_PROPERTIES, &TT_SERVICE_PROPERTIES_GET ) #else FT_DEFINE_SERVICEDESCREC4( tt_services, + FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TRUETYPE, FT_SERVICE_ID_TRUETYPE_ENGINE, &tt_service_truetype_engine, FT_SERVICE_ID_TT_GLYF, &TT_SERVICE_TRUETYPE_GLYF_GET, @@ -483,7 +584,7 @@ #endif result = ft_service_list_lookup( TT_SERVICES_GET, tt_interface ); - if ( result != NULL ) + if ( result ) return result; #ifndef FT_CONFIG_OPTION_PIC @@ -534,31 +635,31 @@ 0x10000L, /* driver version == 1.0 */ 0x20000L, /* driver requires FreeType 2.0 or above */ - (void*)0, /* driver specific interface */ + NULL, /* module-specific interface */ - tt_driver_init, - tt_driver_done, - tt_get_interface, + tt_driver_init, /* FT_Module_Constructor module_init */ + tt_driver_done, /* FT_Module_Destructor module_done */ + tt_get_interface, /* FT_Module_Requester get_interface */ sizeof ( TT_FaceRec ), sizeof ( TT_SizeRec ), sizeof ( FT_GlyphSlotRec ), - tt_face_init, - tt_face_done, - tt_size_init, - tt_size_done, - tt_slot_init, - 0, /* FT_Slot_DoneFunc */ + tt_face_init, /* FT_Face_InitFunc init_face */ + tt_face_done, /* FT_Face_DoneFunc done_face */ + tt_size_init, /* FT_Size_InitFunc init_size */ + tt_size_done, /* FT_Size_DoneFunc done_size */ + tt_slot_init, /* FT_Slot_InitFunc init_slot */ + NULL, /* FT_Slot_DoneFunc done_slot */ - tt_glyph_load, + tt_glyph_load, /* FT_Slot_LoadFunc load_glyph */ - tt_get_kerning, - 0, /* FT_Face_AttachFunc */ - tt_get_advances, + tt_get_kerning, /* FT_Face_GetKerningFunc get_kerning */ + NULL, /* FT_Face_AttachFunc attach_file */ + tt_get_advances, /* FT_Face_GetAdvancesFunc get_advances */ - tt_size_request, - TT_SIZE_SELECT + tt_size_request, /* FT_Size_RequestFunc request_size */ + TT_SIZE_SELECT /* FT_Size_SelectFunc select_size */ ) diff --git a/src/3rdparty/freetype/src/truetype/ttdriver.h b/src/3rdparty/freetype/src/truetype/ttdriver.h index 6cacd60966..707aa68edf 100644 --- a/src/3rdparty/freetype/src/truetype/ttdriver.h +++ b/src/3rdparty/freetype/src/truetype/ttdriver.h @@ -4,7 +4,7 @@ /* */ /* High-level TrueType driver interface (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTDRIVER_H__ -#define __TTDRIVER_H__ +#ifndef TTDRIVER_H_ +#define TTDRIVER_H_ #include <ft2build.h> @@ -32,7 +32,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTDRIVER_H__ */ +#endif /* TTDRIVER_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/truetype/tterrors.h b/src/3rdparty/freetype/src/truetype/tterrors.h index ba32cf744c..88bca3a04a 100644 --- a/src/3rdparty/freetype/src/truetype/tterrors.h +++ b/src/3rdparty/freetype/src/truetype/tterrors.h @@ -4,7 +4,7 @@ /* */ /* TrueType error codes (specification only). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __TTERRORS_H__ -#define __TTERRORS_H__ +#ifndef TTERRORS_H_ +#define TTERRORS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX TT_Err_ @@ -36,6 +36,7 @@ #include FT_ERRORS_H -#endif /* __TTERRORS_H__ */ +#endif /* TTERRORS_H_ */ + /* END */ diff --git a/src/3rdparty/freetype/src/truetype/ttgload.c b/src/3rdparty/freetype/src/truetype/ttgload.c index a792ad44a0..39d9c3f736 100644 --- a/src/3rdparty/freetype/src/truetype/ttgload.c +++ b/src/3rdparty/freetype/src/truetype/ttgload.c @@ -4,7 +4,7 @@ /* */ /* TrueType Glyph Loader (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,12 +18,14 @@ #include <ft2build.h> #include FT_INTERNAL_DEBUG_H +#include FT_CONFIG_CONFIG_H #include FT_INTERNAL_CALC_H #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H #include FT_TRUETYPE_TAGS_H #include FT_OUTLINE_H -#include FT_TRUETYPE_DRIVER_H +#include FT_DRIVER_H +#include FT_LIST_H #include "ttgload.h" #include "ttpload.h" @@ -85,7 +87,7 @@ /*************************************************************************/ /* */ /* Return the vertical metrics in font units for a given glyph. */ - /* See macro `TT_LOADER_SET_PP' below for explanations. */ + /* See function `tt_loader_set_pp' below for explanations. */ /* */ FT_LOCAL_DEF( void ) TT_Get_VMetrics( TT_Face face, @@ -121,7 +123,7 @@ FT_UInt glyph_index ) { TT_Face face = loader->face; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); #endif @@ -152,7 +154,7 @@ loader->top_bearing = top_bearing; loader->vadvance = advance_height; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 && loader->exec ) { @@ -161,10 +163,10 @@ /* This may not be the right place for this, but it works... */ /* Note that we have to unconditionally load the tweaks since */ /* it is possible that glyphs individually switch ClearType's */ - /* backwards compatibility mode on and off. */ + /* backward compatibility mode on and off. */ sph_set_tweaks( loader, glyph_index ); } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ if ( !loader->linear_def ) { @@ -193,39 +195,39 @@ if ( face->root.internal->incremental_interface && face->root.internal->incremental_interface->funcs->get_glyph_metrics ) { - FT_Incremental_MetricsRec metrics; + FT_Incremental_MetricsRec incr_metrics; FT_Error error; - metrics.bearing_x = loader->left_bearing; - metrics.bearing_y = 0; - metrics.advance = loader->advance; - metrics.advance_v = 0; + incr_metrics.bearing_x = loader->left_bearing; + incr_metrics.bearing_y = 0; + incr_metrics.advance = loader->advance; + incr_metrics.advance_v = 0; error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( face->root.internal->incremental_interface->object, - glyph_index, FALSE, &metrics ); + glyph_index, FALSE, &incr_metrics ); if ( error ) goto Exit; - left_bearing = (FT_Short)metrics.bearing_x; - advance_width = (FT_UShort)metrics.advance; + left_bearing = (FT_Short)incr_metrics.bearing_x; + advance_width = (FT_UShort)incr_metrics.advance; #if 0 /* GWW: Do I do the same for vertical metrics? */ - metrics.bearing_x = 0; - metrics.bearing_y = loader->top_bearing; - metrics.advance = loader->vadvance; + incr_metrics.bearing_x = 0; + incr_metrics.bearing_y = loader->top_bearing; + incr_metrics.advance = loader->vadvance; error = face->root.internal->incremental_interface->funcs->get_glyph_metrics( face->root.internal->incremental_interface->object, - glyph_index, TRUE, &metrics ); + glyph_index, TRUE, &incr_metrics ); if ( error ) goto Exit; - top_bearing = (FT_Short)metrics.bearing_y; - advance_height = (FT_UShort)metrics.advance; + top_bearing = (FT_Short)incr_metrics.bearing_y; + advance_height = (FT_UShort)incr_metrics.advance; #endif /* 0 */ @@ -331,7 +333,6 @@ FT_Outline* outline; FT_UShort n_ins; FT_Int n_points; - FT_ULong tmp; FT_Byte *flag, *flag_limit; FT_Byte c, count; @@ -397,18 +398,21 @@ FT_TRACE5(( " Instructions size: %u\n", n_ins )); - /* check it */ - if ( ( limit - p ) < n_ins ) - { - FT_TRACE0(( "TT_Load_Simple_Glyph: instruction count mismatch\n" )); - error = FT_THROW( Too_Many_Hints ); - goto Fail; - } - #ifdef TT_USE_BYTECODE_INTERPRETER if ( IS_HINTED( load->load_flags ) ) { + FT_ULong tmp; + + + /* check instructions size */ + if ( ( limit - p ) < n_ins ) + { + FT_TRACE1(( "TT_Load_Simple_Glyph: instruction count mismatch\n" )); + error = FT_THROW( Too_Many_Hints ); + goto Fail; + } + /* we don't trust `maxSizeOfInstructions' in the `maxp' table */ /* and thus update the bytecode array size by ourselves */ @@ -426,7 +430,8 @@ load->glyph->control_len = n_ins; load->glyph->control_data = load->exec->glyphIns; - FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins ); + if ( n_ins ) + FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins ); } #endif /* TT_USE_BYTECODE_INTERPRETER */ @@ -439,7 +444,7 @@ flag = (FT_Byte*)outline->tags; flag_limit = flag + n_points; - FT_ASSERT( flag != NULL ); + FT_ASSERT( flag ); while ( flag < flag_limit ) { @@ -659,6 +664,52 @@ } while ( subglyph->flags & MORE_COMPONENTS ); gloader->current.num_subglyphs = num_subglyphs; + FT_TRACE5(( " %d component%s\n", + num_subglyphs, + num_subglyphs > 1 ? "s" : "" )); + +#ifdef FT_DEBUG_LEVEL_TRACE + { + FT_UInt i; + + + subglyph = gloader->current.subglyphs; + + for ( i = 0; i < num_subglyphs; i++ ) + { + if ( num_subglyphs > 1 ) + FT_TRACE7(( " subglyph %d:\n", i )); + + FT_TRACE7(( " glyph index: %d\n", subglyph->index )); + + if ( subglyph->flags & ARGS_ARE_XY_VALUES ) + FT_TRACE7(( " offset: x=%d, y=%d\n", + subglyph->arg1, + subglyph->arg2 )); + else + FT_TRACE7(( " matching points: base=%d, component=%d\n", + subglyph->arg1, + subglyph->arg2 )); + + if ( subglyph->flags & WE_HAVE_A_SCALE ) + FT_TRACE7(( " scaling: %f\n", + subglyph->transform.xx / 65536.0 )); + else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE ) + FT_TRACE7(( " scaling: x=%f, y=%f\n", + subglyph->transform.xx / 65536.0, + subglyph->transform.yy / 65536.0 )); + else if ( subglyph->flags & WE_HAVE_A_2X2 ) + FT_TRACE7(( " scaling: xx=%f, yx=%f\n" + " xy=%f, yy=%f\n", + subglyph->transform.xx / 65536.0, + subglyph->transform.yx / 65536.0, + subglyph->transform.xy / 65536.0, + subglyph->transform.yy / 65536.0 )); + + subglyph++; + } + } +#endif /* FT_DEBUG_LEVEL_TRACE */ #ifdef TT_USE_BYTECODE_INTERPRETER @@ -730,7 +781,8 @@ TT_Hint_Glyph( TT_Loader loader, FT_Bool is_composite ) { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \ + defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL TT_Face face = loader->face; TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); #endif @@ -749,7 +801,7 @@ { FT_TRACE1(( "TT_Hint_Glyph: too long instructions" )); FT_TRACE1(( " (0x%lx byte) is truncated\n", - loader->glyph->control_len )); + loader->glyph->control_len )); } n_ins = loader->glyph->control_len; @@ -771,8 +823,8 @@ } else { - loader->exec->metrics.x_scale = loader->size->metrics.x_scale; - loader->exec->metrics.y_scale = loader->size->metrics.y_scale; + loader->exec->metrics.x_scale = loader->size->metrics->x_scale; + loader->exec->metrics.y_scale = loader->size->metrics->y_scale; } #endif @@ -813,13 +865,23 @@ #endif - /* save glyph phantom points */ - loader->pp1 = zone->cur[zone->n_points - 4]; - loader->pp2 = zone->cur[zone->n_points - 3]; - loader->pp3 = zone->cur[zone->n_points - 2]; - loader->pp4 = zone->cur[zone->n_points - 1]; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* Save possibly modified glyph phantom points unless in v40 backward */ + /* compatibility mode, where no movement on the x axis means no reason */ + /* to change bearings or advance widths. */ + if ( !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 && + loader->exec->backward_compatibility ) ) + { +#endif + loader->pp1 = zone->cur[zone->n_points - 4]; + loader->pp2 = zone->cur[zone->n_points - 3]; + loader->pp3 = zone->cur[zone->n_points - 2]; + loader->pp4 = zone->cur[zone->n_points - 1]; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + } +#endif -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) { if ( loader->exec->sph_tweak_flags & SPH_TWEAK_DEEMBOLDEN ) @@ -828,7 +890,7 @@ else if ( loader->exec->sph_tweak_flags & SPH_TWEAK_EMBOLDEN ) FT_Outline_EmboldenXY( &loader->gloader->current.outline, 24, 0 ); } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ return FT_Err_Ok; } @@ -872,13 +934,24 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - if ( loader->face->doblend ) + if ( FT_IS_NAMED_INSTANCE( FT_FACE( loader->face ) ) || + FT_IS_VARIATION( FT_FACE( loader->face ) ) ) { /* Deltas apply to the unscaled data. */ error = TT_Vary_Apply_Glyph_Deltas( loader->face, loader->glyph_index, outline, (FT_UInt)n_points ); + + /* recalculate linear horizontal and vertical advances */ + /* if we don't have HVAR and VVAR, respectively */ + if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) + loader->linear = outline->points[n_points - 3].x - + outline->points[n_points - 4].x; + if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) + loader->vadvance = outline->points[n_points - 1].x - + outline->points[n_points - 2].x; + if ( error ) return error; } @@ -894,12 +967,12 @@ } { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY TT_Face face = loader->face; TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); FT_String* family = face->root.family_name; - FT_UInt ppem = loader->size->metrics.x_ppem; + FT_UInt ppem = loader->size->metrics->x_ppem; FT_String* style = face->root.style_name; FT_UInt x_scale_factor = 1000; #endif @@ -913,7 +986,7 @@ FT_Bool do_scale = FALSE; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) { @@ -928,9 +1001,9 @@ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 || x_scale_factor != 1000 ) { - x_scale = FT_MulDiv( loader->size->metrics.x_scale, + x_scale = FT_MulDiv( loader->size->metrics->x_scale, (FT_Long)x_scale_factor, 1000 ); - y_scale = loader->size->metrics.y_scale; + y_scale = loader->size->metrics->y_scale; /* compensate for any scaling by de/emboldening; */ /* the amount was determined via experimentation */ @@ -944,14 +1017,14 @@ } else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ { /* scale the glyph */ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) { - x_scale = loader->size->metrics.x_scale; - y_scale = loader->size->metrics.y_scale; + x_scale = loader->size->metrics->x_scale; + y_scale = loader->size->metrics->y_scale; do_scale = TRUE; } @@ -964,9 +1037,24 @@ vec->x = FT_MulFix( vec->x, x_scale ); vec->y = FT_MulFix( vec->y, y_scale ); } + } +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + /* if we have a HVAR table, `pp1' and/or `pp2' are already adjusted */ + if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) || + !IS_HINTED( loader->load_flags ) ) +#endif + { loader->pp1 = outline->points[n_points - 4]; loader->pp2 = outline->points[n_points - 3]; + } + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + /* if we have a VVAR table, `pp3' and/or `pp4' are already adjusted */ + if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) || + !IS_HINTED( loader->load_flags ) ) +#endif + { loader->pp3 = outline->points[n_points - 2]; loader->pp4 = outline->points[n_points - 1]; } @@ -1075,7 +1163,7 @@ : -subglyph->transform.yx; int c = subglyph->transform.xy > 0 ? subglyph->transform.xy : -subglyph->transform.xy; - int d = subglyph->transform.yy > 0 ? subglyph->transform.yy + int d = subglyph->transform.yy > 0 ? subglyph->transform.yy : -subglyph->transform.yy; int m = a > b ? a : b; int n = c > d ? c : d; @@ -1109,8 +1197,8 @@ if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) ) { - FT_Fixed x_scale = loader->size->metrics.x_scale; - FT_Fixed y_scale = loader->size->metrics.y_scale; + FT_Fixed x_scale = loader->size->metrics->x_scale; + FT_Fixed y_scale = loader->size->metrics->y_scale; x = FT_MulFix( x, x_scale ); @@ -1118,8 +1206,28 @@ if ( subglyph->flags & ROUND_XY_TO_GRID ) { - x = FT_PIX_ROUND( x ); - y = FT_PIX_ROUND( y ); + TT_Face face = loader->face; + TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); + + + if ( IS_HINTED( loader->load_flags ) ) + { + /* + * We round the horizontal offset only if there is hinting along + * the x axis; this corresponds to integer advance width values. + * + * Theoretically, a glyph's bytecode can toggle ClearType's + * `backward compatibility' mode, which would allow modification + * of the advance width. In reality, however, applications + * neither allow nor expect modified advance widths if subpixel + * rendering is active. + * + */ + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_35 ) + x = FT_PIX_ROUND( x ); + + y = FT_PIX_ROUND( y ); + } } } } @@ -1321,49 +1429,72 @@ * (3) for everything else. * */ + static void + tt_loader_set_pp( TT_Loader loader ) + { + FT_Bool subpixel_hinting = 0; + FT_Bool grayscale = 0; + FT_Bool use_aw_2 = 0; + #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING + TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( loader->face ); +#endif -#define TT_LOADER_SET_PP( loader ) \ - do \ - { \ - FT_Bool subpixel_hinting_ = loader->exec \ - ? loader->exec->subpixel_hinting \ - : 0; \ - FT_Bool grayscale_ = loader->exec \ - ? loader->exec->grayscale \ - : 0; \ - FT_Bool use_aw_2_ = (FT_Bool)( subpixel_hinting_ && \ - grayscale_ ); \ - \ - \ - (loader)->pp1.x = (loader)->bbox.xMin - (loader)->left_bearing; \ - (loader)->pp1.y = 0; \ - (loader)->pp2.x = (loader)->pp1.x + (loader)->advance; \ - (loader)->pp2.y = 0; \ - \ - (loader)->pp3.x = use_aw_2_ ? (loader)->advance / 2 : 0; \ - (loader)->pp3.y = (loader)->bbox.yMax + (loader)->top_bearing; \ - (loader)->pp4.x = use_aw_2_ ? (loader)->advance / 2 : 0; \ - (loader)->pp4.y = (loader)->pp3.y - (loader)->vadvance; \ - } while ( 0 ) -#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) + { + subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting + : 0; + grayscale = loader->exec ? loader->exec->grayscale + : 0; + } +#endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 ) + { + subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting_lean + : 0; + grayscale = loader->exec ? loader->exec->grayscale_cleartype + : 0; + } +#endif -#define TT_LOADER_SET_PP( loader ) \ - do \ - { \ - (loader)->pp1.x = (loader)->bbox.xMin - (loader)->left_bearing; \ - (loader)->pp1.y = 0; \ - (loader)->pp2.x = (loader)->pp1.x + (loader)->advance; \ - (loader)->pp2.y = 0; \ - \ - (loader)->pp3.x = 0; \ - (loader)->pp3.y = (loader)->bbox.yMax + (loader)->top_bearing; \ - (loader)->pp4.x = 0; \ - (loader)->pp4.y = (loader)->pp3.y - (loader)->vadvance; \ - } while ( 0 ) + use_aw_2 = (FT_Bool)( subpixel_hinting && grayscale ); -#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + loader->pp1.x = loader->bbox.xMin - loader->left_bearing; + loader->pp1.y = 0; + loader->pp2.x = loader->pp1.x + loader->advance; + loader->pp2.y = 0; + + loader->pp3.x = use_aw_2 ? loader->advance / 2 : 0; + loader->pp3.y = loader->bbox.yMax + loader->top_bearing; + loader->pp4.x = use_aw_2 ? loader->advance / 2 : 0; + loader->pp4.y = loader->pp3.y - loader->vadvance; + } + + + /* a utility function to retrieve i-th node from given FT_List */ + static FT_ListNode + ft_list_get_node_at( FT_List list, + FT_UInt idx ) + { + FT_ListNode cur; + + + if ( !list ) + return NULL; + + for ( cur = list->head; cur; cur = cur->next ) + { + if ( !idx ) + return cur; + + idx--; + } + + return NULL; + } /*************************************************************************/ @@ -1395,13 +1526,17 @@ #endif - /* some fonts have an incorrect value of `maxComponentDepth', */ - /* thus we allow depth 1 to catch the majority of them */ - if ( recurse_count > 1 && - recurse_count > face->max_profile.maxComponentDepth ) +#ifdef FT_DEBUG_LEVEL_TRACE + if ( recurse_count ) + FT_TRACE5(( " nesting level: %d\n", recurse_count )); +#endif + + /* some fonts have an incorrect value of `maxComponentDepth' */ + if ( recurse_count > face->max_profile.maxComponentDepth ) { - error = FT_THROW( Invalid_Composite ); - goto Exit; + FT_TRACE1(( "load_truetype_glyph: maxComponentDepth set to %d\n", + recurse_count )); + face->max_profile.maxComponentDepth = (FT_UShort)recurse_count; } #ifndef FT_CONFIG_OPTION_INCREMENTAL @@ -1417,8 +1552,8 @@ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) { - x_scale = loader->size->metrics.x_scale; - y_scale = loader->size->metrics.y_scale; + x_scale = loader->size->metrics->x_scale; + y_scale = loader->size->metrics->y_scale; } else { @@ -1447,7 +1582,7 @@ offset = 0; loader->byte_len = glyph_data.length; - FT_MEM_ZERO( &inc_stream, sizeof ( inc_stream ) ); + FT_ZERO( &inc_stream ); FT_Stream_OpenMemory( &inc_stream, glyph_data.pointer, (FT_ULong)glyph_data.length ); @@ -1465,10 +1600,10 @@ { #ifdef FT_CONFIG_OPTION_INCREMENTAL /* for the incremental interface, `glyf_offset' is always zero */ - if ( !loader->glyf_offset && + if ( !face->glyf_offset && !face->root.internal->incremental_interface ) #else - if ( !loader->glyf_offset ) + if ( !face->glyf_offset ) #endif /* FT_CONFIG_OPTION_INCREMENTAL */ { FT_TRACE2(( "no `glyf' table but non-zero `loca' entry\n" )); @@ -1477,7 +1612,7 @@ } error = face->access_glyph_frame( loader, glyph_index, - loader->glyf_offset + offset, + face->glyf_offset + offset, (FT_UInt)loader->byte_len ); if ( error ) goto Exit; @@ -1516,7 +1651,7 @@ /* must initialize points before (possibly) overriding */ /* glyph metrics from the incremental interface */ - TT_LOADER_SET_PP( loader ); + tt_loader_set_pp( loader ); #ifdef FT_CONFIG_OPTION_INCREMENTAL tt_get_metrics_incr_overrides( loader, glyph_index ); @@ -1524,7 +1659,8 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - if ( loader->face->doblend ) + if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) || + FT_IS_VARIATION( FT_FACE( face ) ) ) { /* a small outline structure with four elements for */ /* communication with `TT_Vary_Apply_Glyph_Deltas' */ @@ -1567,6 +1703,14 @@ loader->pp3.y = points[2].y; loader->pp4.x = points[3].x; loader->pp4.y = points[3].y; + + + /* recalculate linear horizontal and vertical advances */ + /* if we don't have HVAR and VVAR, respectively */ + if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) + loader->linear = loader->pp2.x - loader->pp1.x; + if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) + loader->vadvance = loader->pp4.x - loader->pp3.x; } #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ @@ -1591,7 +1735,7 @@ /* must initialize phantom points before (possibly) overriding */ /* glyph metrics from the incremental interface */ - TT_LOADER_SET_PP( loader ); + tt_loader_set_pp( loader ); #ifdef FT_CONFIG_OPTION_INCREMENTAL tt_get_metrics_incr_overrides( loader, glyph_index ); @@ -1625,12 +1769,53 @@ /***********************************************************************/ /* otherwise, load a composite! */ - else if ( loader->n_contours == -1 ) + else if ( loader->n_contours < 0 ) { + FT_Memory memory = face->root.memory; + FT_UInt start_point; FT_UInt start_contour; FT_ULong ins_pos; /* position of composite instructions, if any */ + FT_ListNode node, node2; + + + /* normalize the `n_contours' value */ + loader->n_contours = -1; + + /* + * We store the glyph index directly in the `node->data' pointer, + * following the glib solution (cf. macro `GUINT_TO_POINTER') with a + * double cast to make this portable. Note, however, that this needs + * pointers with a width of at least 32 bits. + */ + + + /* clear the nodes filled by sibling chains */ + node = ft_list_get_node_at( &loader->composites, recurse_count ); + for ( node2 = node; node2; node2 = node2->next ) + node2->data = (void*)FT_ULONG_MAX; + + /* check whether we already have a composite glyph with this index */ + if ( FT_List_Find( &loader->composites, + FT_UINT_TO_POINTER( glyph_index ) ) ) + { + FT_TRACE1(( "TT_Load_Composite_Glyph:" + " infinite recursion detected\n" )); + error = FT_THROW( Invalid_Composite ); + goto Exit; + } + + else if ( node ) + node->data = FT_UINT_TO_POINTER( glyph_index ); + + else + { + if ( FT_NEW( node ) ) + goto Exit; + node->data = FT_UINT_TO_POINTER( glyph_index ); + FT_List_Add( &loader->composites, node ); + } start_point = (FT_UInt)gloader->base.outline.n_points; start_contour = (FT_UInt)gloader->base.outline.n_contours; @@ -1649,7 +1834,8 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - if ( face->doblend ) + if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) || + FT_IS_VARIATION( FT_FACE( face ) ) ) { short i, limit; FT_SubGlyph subglyph; @@ -1659,8 +1845,6 @@ char* tags = NULL; short* contours = NULL; - FT_Memory memory = face->root.memory; - limit = (short)gloader->current.num_subglyphs; @@ -1669,6 +1853,10 @@ outline.n_points = (short)( gloader->current.num_subglyphs + 4 ); outline.n_contours = outline.n_points; + outline.points = NULL; + outline.tags = NULL; + outline.contours = NULL; + if ( FT_NEW_ARRAY( points, outline.n_points ) || FT_NEW_ARRAY( tags, outline.n_points ) || FT_NEW_ARRAY( contours, outline.n_points ) ) @@ -1716,22 +1904,22 @@ /* this call provides additional offsets */ /* for each component's translation */ - if ( ( error = TT_Vary_Apply_Glyph_Deltas( - face, - glyph_index, - &outline, - (FT_UInt)outline.n_points ) ) != 0 ) + if ( FT_SET_ERROR( TT_Vary_Apply_Glyph_Deltas( + face, + glyph_index, + &outline, + (FT_UInt)outline.n_points ) ) ) goto Exit1; subglyph = gloader->current.subglyphs; for ( i = 0; i < limit; i++, subglyph++ ) { - /* XXX: overflow check for subglyph->{arg1,arg2}. */ - /* Deltas must be within signed 16-bit, */ - /* but the restriction of summed deltas is not clear */ - subglyph->arg1 = (FT_Int16)points[i].x; - subglyph->arg2 = (FT_Int16)points[i].y; + if ( subglyph->flags & ARGS_ARE_XY_VALUES ) + { + subglyph->arg1 = (FT_Int16)points[i].x; + subglyph->arg2 = (FT_Int16)points[i].y; + } } loader->pp1.x = points[i + 0].x; @@ -1744,6 +1932,13 @@ loader->pp4.x = points[i + 3].x; loader->pp4.y = points[i + 3].y; + /* recalculate linear horizontal and vertical advances */ + /* if we don't have HVAR and VVAR, respectively */ + if ( !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) + loader->linear = loader->pp2.x - loader->pp1.x; + if ( !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) + loader->vadvance = loader->pp4.x - loader->pp3.x; + Exit1: FT_FREE( outline.points ); FT_FREE( outline.tags ); @@ -1803,6 +1998,9 @@ { FT_Vector pp[4]; + FT_Int linear_hadvance; + FT_Int linear_vadvance; + /* Each time we call load_truetype_glyph in this loop, the */ /* value of `gloader.base.subglyphs' can change due to table */ @@ -1815,6 +2013,9 @@ pp[2] = loader->pp3; pp[3] = loader->pp4; + linear_hadvance = loader->linear; + linear_vadvance = loader->vadvance; + num_base_points = (FT_UInt)gloader->base.outline.n_points; error = load_truetype_glyph( loader, @@ -1834,6 +2035,9 @@ loader->pp2 = pp[1]; loader->pp3 = pp[2]; loader->pp4 = pp[3]; + + loader->linear = linear_hadvance; + loader->vadvance = linear_vadvance; } num_points = (FT_UInt)gloader->base.outline.n_points; @@ -1874,12 +2078,6 @@ } } } - else - { - /* invalid composite count (negative but not -1) */ - error = FT_THROW( Invalid_Outline ); - goto Exit; - } /***********************************************************************/ /***********************************************************************/ @@ -1908,7 +2106,8 @@ FT_UInt glyph_index ) { TT_Face face = loader->face; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \ + defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); #endif @@ -1920,7 +2119,7 @@ y_scale = 0x10000L; if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) - y_scale = size->root.metrics.y_scale; + y_scale = size->metrics->y_scale; if ( glyph->format != FT_GLYPH_FORMAT_COMPOSITE ) FT_Outline_Get_CBox( &glyph->outline, &bbox ); @@ -1935,20 +2134,27 @@ glyph->metrics.horiBearingY = bbox.yMax; glyph->metrics.horiAdvance = loader->pp2.x - loader->pp1.x; - /* adjust advance width to the value contained in the hdmx table */ - /* unless FT_LOAD_COMPUTE_METRICS is set */ - if ( !face->postscript.isFixedPitch && - IS_HINTED( loader->load_flags ) && - !( loader->load_flags & FT_LOAD_COMPUTE_METRICS ) ) + /* Adjust advance width to the value contained in the hdmx table */ + /* unless FT_LOAD_COMPUTE_METRICS is set or backward compatibility */ + /* mode of the v40 interpreter is active. See `ttinterp.h' for */ + /* details on backward compatibility mode. */ + if ( +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 && + ( loader->exec && loader->exec->backward_compatibility ) ) && +#endif + !face->postscript.isFixedPitch && + IS_HINTED( loader->load_flags ) && + !( loader->load_flags & FT_LOAD_COMPUTE_METRICS ) ) { FT_Byte* widthp; widthp = tt_face_get_device_metrics( face, - size->root.metrics.x_ppem, + size->metrics->x_ppem, glyph_index ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) { @@ -1966,7 +2172,7 @@ } else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ { if ( widthp ) @@ -1975,8 +2181,8 @@ } /* set glyph dimensions */ - glyph->metrics.width = bbox.xMax - bbox.xMin; - glyph->metrics.height = bbox.yMax - bbox.yMin; + glyph->metrics.width = SUB_LONG( bbox.xMax, bbox.xMin ); + glyph->metrics.height = SUB_LONG( bbox.yMax, bbox.yMin ); /* Now take care of vertical metrics. In the case where there is */ /* no vertical information within the font (relatively common), */ @@ -2012,7 +2218,8 @@ /* table in the font. Otherwise, we use the */ /* values defined in the horizontal header. */ - height = (FT_Short)FT_DivFix( bbox.yMax - bbox.yMin, + height = (FT_Short)FT_DivFix( SUB_LONG( bbox.yMax, + bbox.yMin ), y_scale ); if ( face->os2.version != 0xFFFFU ) advance = (FT_Pos)( face->os2.sTypoAscender - @@ -2027,7 +2234,7 @@ #ifdef FT_CONFIG_OPTION_INCREMENTAL { FT_Incremental_InterfaceRec* incr; - FT_Incremental_MetricsRec metrics; + FT_Incremental_MetricsRec incr_metrics; FT_Error error; @@ -2037,19 +2244,19 @@ /* overriding metrics for this glyph. */ if ( incr && incr->funcs->get_glyph_metrics ) { - metrics.bearing_x = 0; - metrics.bearing_y = top; - metrics.advance = advance; + incr_metrics.bearing_x = 0; + incr_metrics.bearing_y = top; + incr_metrics.advance = advance; error = incr->funcs->get_glyph_metrics( incr->object, glyph_index, TRUE, - &metrics ); + &incr_metrics ); if ( error ) return error; - top = metrics.bearing_y; - advance = metrics.advance; + top = incr_metrics.bearing_y; + advance = incr_metrics.advance; } } @@ -2091,7 +2298,7 @@ SFNT_Service sfnt; FT_Stream stream; FT_Error error; - TT_SBit_MetricsRec metrics; + TT_SBit_MetricsRec sbit_metrics; face = (TT_Face)glyph->face; @@ -2104,34 +2311,34 @@ (FT_UInt)load_flags, stream, &glyph->bitmap, - &metrics ); + &sbit_metrics ); if ( !error ) { glyph->outline.n_points = 0; glyph->outline.n_contours = 0; - glyph->metrics.width = (FT_Pos)metrics.width * 64; - glyph->metrics.height = (FT_Pos)metrics.height * 64; + glyph->metrics.width = (FT_Pos)sbit_metrics.width * 64; + glyph->metrics.height = (FT_Pos)sbit_metrics.height * 64; - glyph->metrics.horiBearingX = (FT_Pos)metrics.horiBearingX * 64; - glyph->metrics.horiBearingY = (FT_Pos)metrics.horiBearingY * 64; - glyph->metrics.horiAdvance = (FT_Pos)metrics.horiAdvance * 64; + glyph->metrics.horiBearingX = (FT_Pos)sbit_metrics.horiBearingX * 64; + glyph->metrics.horiBearingY = (FT_Pos)sbit_metrics.horiBearingY * 64; + glyph->metrics.horiAdvance = (FT_Pos)sbit_metrics.horiAdvance * 64; - glyph->metrics.vertBearingX = (FT_Pos)metrics.vertBearingX * 64; - glyph->metrics.vertBearingY = (FT_Pos)metrics.vertBearingY * 64; - glyph->metrics.vertAdvance = (FT_Pos)metrics.vertAdvance * 64; + glyph->metrics.vertBearingX = (FT_Pos)sbit_metrics.vertBearingX * 64; + glyph->metrics.vertBearingY = (FT_Pos)sbit_metrics.vertBearingY * 64; + glyph->metrics.vertAdvance = (FT_Pos)sbit_metrics.vertAdvance * 64; glyph->format = FT_GLYPH_FORMAT_BITMAP; if ( load_flags & FT_LOAD_VERTICAL_LAYOUT ) { - glyph->bitmap_left = metrics.vertBearingX; - glyph->bitmap_top = metrics.vertBearingY; + glyph->bitmap_left = sbit_metrics.vertBearingX; + glyph->bitmap_top = sbit_metrics.vertBearingY; } else { - glyph->bitmap_left = metrics.horiBearingX; - glyph->bitmap_top = metrics.horiBearingY; + glyph->bitmap_left = sbit_metrics.horiBearingX; + glyph->bitmap_top = sbit_metrics.horiBearingY; } } @@ -2148,19 +2355,23 @@ FT_Int32 load_flags, FT_Bool glyf_table_only ) { - FT_Error error; - TT_Face face; FT_Stream stream; + #ifdef TT_USE_BYTECODE_INTERPRETER + FT_Error error; FT_Bool pedantic = FT_BOOL( load_flags & FT_LOAD_PEDANTIC ); +#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \ + defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( (TT_Face)glyph->face ); +#endif #endif face = (TT_Face)glyph->face; stream = face->root.stream; - FT_MEM_ZERO( loader, sizeof ( TT_LoaderRec ) ); + FT_ZERO( loader ); #ifdef TT_USE_BYTECODE_INTERPRETER @@ -2168,11 +2379,13 @@ if ( IS_HINTED( load_flags ) && !glyf_table_only ) { TT_ExecContext exec; - FT_Bool grayscale; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face ); + FT_Bool grayscale = TRUE; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + FT_Bool subpixel_hinting_lean; + FT_Bool grayscale_cleartype; +#endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY FT_Bool subpixel_hinting = FALSE; #if 0 @@ -2184,7 +2397,7 @@ FT_Bool subpixel_positioned; FT_Bool gray_cleartype; #endif -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ FT_Bool reexecute = FALSE; @@ -2205,7 +2418,32 @@ if ( !exec ) return FT_THROW( Could_Not_Find_Context ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 ) + { + subpixel_hinting_lean = + FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != + FT_RENDER_MODE_MONO ); + grayscale_cleartype = + FT_BOOL( subpixel_hinting_lean && + !( ( load_flags & + FT_LOAD_TARGET_LCD ) || + ( load_flags & + FT_LOAD_TARGET_LCD_V ) ) ); + exec->vertical_lcd_lean = + FT_BOOL( subpixel_hinting_lean && + ( load_flags & + FT_LOAD_TARGET_LCD_V ) ); + } + else + { + subpixel_hinting_lean = FALSE; + grayscale_cleartype = FALSE; + exec->vertical_lcd_lean = FALSE; + } +#endif + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) { @@ -2262,18 +2500,23 @@ } else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - { +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 ) + grayscale = FT_BOOL( !subpixel_hinting_lean && + FT_LOAD_TARGET_MODE( load_flags ) != + FT_RENDER_MODE_MONO ); + else +#endif grayscale = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != - FT_RENDER_MODE_MONO ); - } + FT_RENDER_MODE_MONO ); error = TT_Load_Context( exec, face, size ); if ( error ) return error; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 ) { @@ -2301,9 +2544,37 @@ } else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ { + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 ) + { + /* a change from mono to subpixel rendering (and vice versa) */ + /* requires a re-execution of the CVT program */ + if ( subpixel_hinting_lean != exec->subpixel_hinting_lean ) + { + FT_TRACE4(( "tt_loader_init: subpixel hinting change," + " re-executing `prep' table\n" )); + + exec->subpixel_hinting_lean = subpixel_hinting_lean; + reexecute = TRUE; + } + + /* a change from colored to grayscale subpixel rendering (and */ + /* vice versa) requires a re-execution of the CVT program */ + if ( grayscale_cleartype != exec->grayscale_cleartype ) + { + FT_TRACE4(( "tt_loader_init: grayscale subpixel hinting change," + " re-executing `prep' table\n" )); + + exec->grayscale_cleartype = grayscale_cleartype; + reexecute = TRUE; + } + } +#endif + /* a change from mono to grayscale rendering (and vice versa) */ /* requires a re-execution of the CVT program */ if ( grayscale != exec->grayscale ) @@ -2336,10 +2607,11 @@ if ( exec->GS.instruct_control & 2 ) exec->GS = tt_default_graphics_state; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* check whether we have a font hinted for ClearType -- */ /* note that this flag can also be modified in a glyph's bytecode */ - if ( exec->GS.instruct_control & 4 ) + if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 && + exec->GS.instruct_control & 4 ) exec->ignore_x_mode = 0; #endif @@ -2350,32 +2622,6 @@ #endif /* TT_USE_BYTECODE_INTERPRETER */ - /* seek to the beginning of the glyph table -- for Type 42 fonts */ - /* the table might be accessed from a Postscript stream or something */ - /* else... */ - -#ifdef FT_CONFIG_OPTION_INCREMENTAL - - if ( face->root.internal->incremental_interface ) - loader->glyf_offset = 0; - else - -#endif - - { - error = face->goto_table( face, TTAG_glyf, stream, 0 ); - - if ( FT_ERR_EQ( error, Table_Missing ) ) - loader->glyf_offset = 0; - else if ( error ) - { - FT_ERROR(( "tt_loader_init: could not access glyph table\n" )); - return error; - } - else - loader->glyf_offset = FT_STREAM_POS(); - } - /* get face's glyph loader */ if ( !glyf_table_only ) { @@ -2393,10 +2639,23 @@ loader->glyph = (FT_GlyphSlot)glyph; loader->stream = stream; + loader->composites.head = NULL; + loader->composites.tail = NULL; + return FT_Err_Ok; } + static void + tt_loader_done( TT_Loader loader ) + { + FT_List_Finalize( &loader->composites, + NULL, + loader->face->root.memory, + NULL ); + } + + /*************************************************************************/ /* */ /* <Function> */ @@ -2433,39 +2692,108 @@ FT_Error error; TT_LoaderRec loader; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#define IS_DEFAULT_INSTANCE ( !( FT_IS_NAMED_INSTANCE( glyph->face ) || \ + FT_IS_VARIATION( glyph->face ) ) ) +#else +#define IS_DEFAULT_INSTANCE 1 +#endif + FT_TRACE1(( "TT_Load_Glyph: glyph index %d\n", glyph_index )); #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - /* try to load embedded bitmap if any */ - /* */ - /* XXX: The convention should be emphasized in */ - /* the documents because it can be confusing. */ + /* try to load embedded bitmap (if any) */ if ( size->strike_index != 0xFFFFFFFFUL && - ( load_flags & FT_LOAD_NO_BITMAP ) == 0 ) + ( load_flags & FT_LOAD_NO_BITMAP ) == 0 && + IS_DEFAULT_INSTANCE ) { + FT_Fixed x_scale = size->root.metrics.x_scale; + FT_Fixed y_scale = size->root.metrics.y_scale; + + error = load_sbit_image( size, glyph, glyph_index, load_flags ); - if ( !error ) + if ( FT_ERR_EQ( error, Missing_Bitmap ) ) + { + /* the bitmap strike is incomplete and misses the requested glyph; */ + /* if we have a bitmap-only font, return an empty glyph */ + if ( !FT_IS_SCALABLE( glyph->face ) ) + { + TT_Face face = (TT_Face)glyph->face; + + FT_Short left_bearing = 0; + FT_Short top_bearing = 0; + + FT_UShort advance_width = 0; + FT_UShort advance_height = 0; + + + /* to return an empty glyph, however, we need metrics data */ + /* from the `hmtx' (or `vmtx') table; the assumption is that */ + /* empty glyphs are missing intentionally, representing */ + /* whitespace - not having at least horizontal metrics is */ + /* thus considered an error */ + if ( !face->horz_metrics_size ) + return error; + + /* we now construct an empty bitmap glyph */ + TT_Get_HMetrics( face, glyph_index, + &left_bearing, + &advance_width ); + TT_Get_VMetrics( face, glyph_index, + 0, + &top_bearing, + &advance_height ); + + glyph->outline.n_points = 0; + glyph->outline.n_contours = 0; + + glyph->metrics.width = 0; + glyph->metrics.height = 0; + + glyph->metrics.horiBearingX = FT_MulFix( left_bearing, x_scale ); + glyph->metrics.horiBearingY = 0; + glyph->metrics.horiAdvance = FT_MulFix( advance_width, x_scale ); + + glyph->metrics.vertBearingX = 0; + glyph->metrics.vertBearingY = FT_MulFix( top_bearing, y_scale ); + glyph->metrics.vertAdvance = FT_MulFix( advance_height, y_scale ); + + glyph->format = FT_GLYPH_FORMAT_BITMAP; + glyph->bitmap.pixel_mode = FT_PIXEL_MODE_MONO; + + glyph->bitmap_left = 0; + glyph->bitmap_top = 0; + + return FT_Err_Ok; + } + } + else if ( error ) + { + /* return error if font is not scalable */ + if ( !FT_IS_SCALABLE( glyph->face ) ) + return error; + } + else { if ( FT_IS_SCALABLE( glyph->face ) ) { /* for the bbox we need the header only */ (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE ); (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE ); + tt_loader_done( &loader ); glyph->linearHoriAdvance = loader.linear; glyph->linearVertAdvance = loader.vadvance; /* sanity checks: if `xxxAdvance' in the sbit metric */ /* structure isn't set, use `linearXXXAdvance' */ if ( !glyph->metrics.horiAdvance && glyph->linearHoriAdvance ) - glyph->metrics.horiAdvance = - FT_MulFix( glyph->linearHoriAdvance, - size->root.metrics.x_scale ); + glyph->metrics.horiAdvance = FT_MulFix( glyph->linearHoriAdvance, + x_scale ); if ( !glyph->metrics.vertAdvance && glyph->linearVertAdvance ) - glyph->metrics.vertAdvance = - FT_MulFix( glyph->linearVertAdvance, - size->root.metrics.y_scale ); + glyph->metrics.vertAdvance = FT_MulFix( glyph->linearVertAdvance, + y_scale ); } return FT_Err_Ok; @@ -2476,14 +2804,20 @@ /* if FT_LOAD_NO_SCALE is not set, `ttmetrics' must be valid */ if ( !( load_flags & FT_LOAD_NO_SCALE ) && !size->ttmetrics.valid ) - return FT_THROW( Invalid_Size_Handle ); + { + error = FT_THROW( Invalid_Size_Handle ); + goto Exit; + } if ( load_flags & FT_LOAD_SBITS_ONLY ) - return FT_THROW( Invalid_Argument ); + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } error = tt_loader_init( &loader, size, glyph, load_flags, FALSE ); if ( error ) - return error; + goto Exit; glyph->format = FT_GLYPH_FORMAT_OUTLINE; glyph->num_subglyphs = 0; @@ -2548,14 +2882,23 @@ error = compute_glyph_metrics( &loader, glyph_index ); } + tt_loader_done( &loader ); + /* Set the `high precision' bit flag. */ /* This is _critical_ to get correct output for monochrome */ /* TrueType glyphs at all sizes using the bytecode interpreter. */ /* */ if ( !( load_flags & FT_LOAD_NO_SCALE ) && - size->root.metrics.y_ppem < 24 ) + size->metrics->y_ppem < 24 ) glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION; + Exit: +#ifdef FT_DEBUG_LEVEL_TRACE + if ( error ) + FT_TRACE1(( " failed (error code 0x%x)\n", + error )); +#endif + return error; } diff --git a/src/3rdparty/freetype/src/truetype/ttgload.h b/src/3rdparty/freetype/src/truetype/ttgload.h index 8e3255e106..d237cfd284 100644 --- a/src/3rdparty/freetype/src/truetype/ttgload.h +++ b/src/3rdparty/freetype/src/truetype/ttgload.h @@ -4,7 +4,7 @@ /* */ /* TrueType Glyph Loader (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTGLOAD_H__ -#define __TTGLOAD_H__ +#ifndef TTGLOAD_H_ +#define TTGLOAD_H_ #include <ft2build.h> @@ -56,7 +56,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTGLOAD_H__ */ +#endif /* TTGLOAD_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/truetype/ttgxvar.c b/src/3rdparty/freetype/src/truetype/ttgxvar.c index dd9e250c94..29ab2a4efd 100644 --- a/src/3rdparty/freetype/src/truetype/ttgxvar.c +++ b/src/3rdparty/freetype/src/truetype/ttgxvar.c @@ -4,7 +4,7 @@ /* */ /* TrueType GX Font Variation loader */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* David Turner, Robert Wilhelm, Werner Lemberg, and George Williams. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,10 +22,6 @@ /* */ /* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6[fgca]var.html */ /* */ - /* The documentation for `fvar' is inconsistent. At one point it says */ - /* that `countSizePairs' should be 3, at another point 2. It should */ - /* be 2. */ - /* */ /* The documentation for `gvar' is not intelligible; `cvar' refers you */ /* to `gvar' and is thus also incomprehensible. */ /* */ @@ -49,7 +45,9 @@ #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H #include FT_TRUETYPE_TAGS_H +#include FT_TRUETYPE_IDS_H #include FT_MULTIPLE_MASTERS_H +#include FT_LIST_H #include "ttpload.h" #include "ttgxvar.h" @@ -62,8 +60,11 @@ #define FT_Stream_FTell( stream ) \ (FT_ULong)( (stream)->cursor - (stream)->base ) -#define FT_Stream_SeekSet( stream, off ) \ - ( (stream)->cursor = (stream)->base + (off) ) +#define FT_Stream_SeekSet( stream, off ) \ + (stream)->cursor = \ + ( (off) < (FT_ULong)( (stream)->limit - (stream)->base ) ) \ + ? (stream)->base + (off) \ + : (stream)->limit /*************************************************************************/ @@ -112,6 +113,8 @@ /* <Input> */ /* stream :: The data stream. */ /* */ + /* size :: The size of the table holding the data. */ + /* */ /* <Output> */ /* point_cnt :: The number of points read. A zero value means that */ /* all points in the glyph will be affected, without */ @@ -123,6 +126,7 @@ /* */ static FT_UShort* ft_var_readpackedpoints( FT_Stream stream, + FT_ULong size, FT_UInt *point_cnt ) { FT_UShort *points = NULL; @@ -149,48 +153,55 @@ n |= FT_GET_BYTE(); } - if ( FT_NEW_ARRAY( points, n ) ) + if ( n > size ) + { + FT_TRACE1(( "ft_var_readpackedpoints: number of points too large\n" )); + return NULL; + } + + /* in the nested loops below we increase `i' twice; */ + /* it is faster to simply allocate one more slot */ + /* than to add another test within the loop */ + if ( FT_NEW_ARRAY( points, n + 1 ) ) return NULL; *point_cnt = n; - i = 0; + first = 0; + i = 0; while ( i < n ) { runcnt = FT_GET_BYTE(); if ( runcnt & GX_PT_POINTS_ARE_WORDS ) { runcnt &= GX_PT_POINT_RUN_COUNT_MASK; - first = FT_GET_USHORT(); + first += FT_GET_USHORT(); points[i++] = first; - if ( runcnt < 1 || i + runcnt > n ) - goto Exit; - /* first point not included in run count */ for ( j = 0; j < runcnt; j++ ) { first += FT_GET_USHORT(); points[i++] = first; + if ( i >= n ) + break; } } else { - first = FT_GET_BYTE(); + first += FT_GET_BYTE(); points[i++] = first; - if ( runcnt < 1 || i + runcnt > n ) - goto Exit; - for ( j = 0; j < runcnt; j++ ) { first += FT_GET_BYTE(); points[i++] = first; + if ( i >= n ) + break; } } } - Exit: return points; } @@ -212,6 +223,8 @@ /* <Input> */ /* stream :: The data stream. */ /* */ + /* size :: The size of the table holding the data. */ + /* */ /* delta_cnt :: The number of deltas to be read. */ /* */ /* <Return> */ @@ -222,6 +235,7 @@ /* */ static FT_Short* ft_var_readpackeddeltas( FT_Stream stream, + FT_ULong size, FT_UInt delta_cnt ) { FT_Short *deltas = NULL; @@ -233,6 +247,12 @@ FT_UNUSED( error ); + if ( delta_cnt > size ) + { + FT_TRACE1(( "ft_var_readpackeddeltas: number of points too large\n" )); + return NULL; + } + if ( FT_NEW_ARRAY( deltas, delta_cnt ) ) return NULL; @@ -303,7 +323,7 @@ FT_TRACE2(( "AVAR " )); - blend->avar_checked = TRUE; + blend->avar_loaded = TRUE; error = face->goto_table( face, TTAG_avar, stream, &table_len ); if ( error ) { @@ -327,7 +347,7 @@ if ( axisCount != (FT_Long)blend->mmvar->num_axis ) { - FT_TRACE2(( "ft_var_load_avar: number of axes in `avar' and `cvar'\n" + FT_TRACE2(( "ft_var_load_avar: number of axes in `avar' and `fvar'\n" " table are different\n" )); goto Exit; } @@ -341,7 +361,8 @@ FT_TRACE5(( " axis %d:\n", i )); segment->pairCount = FT_GET_USHORT(); - if ( FT_NEW_ARRAY( segment->correspondence, segment->pairCount ) ) + if ( (FT_ULong)segment->pairCount * 4 > table_len || + FT_NEW_ARRAY( segment->correspondence, segment->pairCount ) ) { /* Failure. Free everything we have done so far. We must do */ /* it right now since loading the `avar' table is optional. */ @@ -360,7 +381,7 @@ segment->correspondence[j].fromCoord = FT_GET_SHORT() * 4; segment->correspondence[j].toCoord = FT_GET_SHORT() * 4; - FT_TRACE5(( " mapping %.4f to %.4f\n", + FT_TRACE5(( " mapping %.5f to %.5f\n", segment->correspondence[j].fromCoord / 65536.0, segment->correspondence[j].toCoord / 65536.0 )); } @@ -373,6 +394,999 @@ } + /* some macros we need */ +#define FT_FIXED_ONE ( (FT_Fixed)0x10000 ) + +#define FT_fdot14ToFixed( x ) \ + ( (FT_Fixed)( (FT_ULong)(x) << 2 ) ) +#define FT_intToFixed( i ) \ + ( (FT_Fixed)( (FT_ULong)(i) << 16 ) ) +#define FT_fixedToInt( x ) \ + ( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) ) + + + static FT_Error + ft_var_load_item_variation_store( TT_Face face, + FT_ULong offset, + GX_ItemVarStore itemStore ) + { + FT_Stream stream = FT_FACE_STREAM( face ); + FT_Memory memory = stream->memory; + + FT_Error error; + FT_UShort format; + FT_ULong region_offset; + FT_UInt i, j, k; + FT_UInt shortDeltaCount; + + GX_Blend blend = face->blend; + GX_ItemVarData varData; + + FT_ULong* dataOffsetArray = NULL; + + + if ( FT_STREAM_SEEK( offset ) || + FT_READ_USHORT( format ) ) + goto Exit; + + if ( format != 1 ) + { + FT_TRACE2(( "ft_var_load_item_variation_store: bad store format %d\n", + format )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + /* read top level fields */ + if ( FT_READ_ULONG( region_offset ) || + FT_READ_USHORT( itemStore->dataCount ) ) + goto Exit; + + /* we need at least one entry in `itemStore->varData' */ + if ( !itemStore->dataCount ) + { + FT_TRACE2(( "ft_var_load_item_variation_store: missing varData\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + /* make temporary copy of item variation data offsets; */ + /* we will parse region list first, then come back */ + if ( FT_NEW_ARRAY( dataOffsetArray, itemStore->dataCount ) ) + goto Exit; + + for ( i = 0; i < itemStore->dataCount; i++ ) + { + if ( FT_READ_ULONG( dataOffsetArray[i] ) ) + goto Exit; + } + + /* parse array of region records (region list) */ + if ( FT_STREAM_SEEK( offset + region_offset ) ) + goto Exit; + + if ( FT_READ_USHORT( itemStore->axisCount ) || + FT_READ_USHORT( itemStore->regionCount ) ) + goto Exit; + + if ( itemStore->axisCount != (FT_Long)blend->mmvar->num_axis ) + { + FT_TRACE2(( "ft_var_load_item_variation_store:" + " number of axes in item variation store\n" + " " + " and `fvar' table are different\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + if ( FT_NEW_ARRAY( itemStore->varRegionList, itemStore->regionCount ) ) + goto Exit; + + for ( i = 0; i < itemStore->regionCount; i++ ) + { + GX_AxisCoords axisCoords; + + + if ( FT_NEW_ARRAY( itemStore->varRegionList[i].axisList, + itemStore->axisCount ) ) + goto Exit; + + axisCoords = itemStore->varRegionList[i].axisList; + + for ( j = 0; j < itemStore->axisCount; j++ ) + { + FT_Short start, peak, end; + + + if ( FT_READ_SHORT( start ) || + FT_READ_SHORT( peak ) || + FT_READ_SHORT( end ) ) + goto Exit; + + axisCoords[j].startCoord = FT_fdot14ToFixed( start ); + axisCoords[j].peakCoord = FT_fdot14ToFixed( peak ); + axisCoords[j].endCoord = FT_fdot14ToFixed( end ); + } + } + + /* end of region list parse */ + + /* use dataOffsetArray now to parse varData items */ + if ( FT_NEW_ARRAY( itemStore->varData, itemStore->dataCount ) ) + goto Exit; + + for ( i = 0; i < itemStore->dataCount; i++ ) + { + varData = &itemStore->varData[i]; + + if ( FT_STREAM_SEEK( offset + dataOffsetArray[i] ) ) + goto Exit; + + if ( FT_READ_USHORT( varData->itemCount ) || + FT_READ_USHORT( shortDeltaCount ) || + FT_READ_USHORT( varData->regionIdxCount ) ) + goto Exit; + + /* check some data consistency */ + if ( shortDeltaCount > varData->regionIdxCount ) + { + FT_TRACE2(( "bad short count %d or region count %d\n", + shortDeltaCount, + varData->regionIdxCount )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + if ( varData->regionIdxCount > itemStore->regionCount ) + { + FT_TRACE2(( "inconsistent regionCount %d in varData[%d]\n", + varData->regionIdxCount, + i )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + /* parse region indices */ + if ( FT_NEW_ARRAY( varData->regionIndices, + varData->regionIdxCount ) ) + goto Exit; + + for ( j = 0; j < varData->regionIdxCount; j++ ) + { + if ( FT_READ_USHORT( varData->regionIndices[j] ) ) + goto Exit; + + if ( varData->regionIndices[j] >= itemStore->regionCount ) + { + FT_TRACE2(( "bad region index %d\n", + varData->regionIndices[j] )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + } + + /* Parse delta set. */ + /* */ + /* On input, deltas are (shortDeltaCount + regionIdxCount) bytes */ + /* each; on output, deltas are expanded to `regionIdxCount' shorts */ + /* each. */ + if ( FT_NEW_ARRAY( varData->deltaSet, + varData->regionIdxCount * varData->itemCount ) ) + goto Exit; + + /* the delta set is stored as a 2-dimensional array of shorts; */ + /* sign-extend signed bytes to signed shorts */ + for ( j = 0; j < varData->itemCount * varData->regionIdxCount; ) + { + for ( k = 0; k < shortDeltaCount; k++, j++ ) + { + /* read the short deltas */ + FT_Short delta; + + + if ( FT_READ_SHORT( delta ) ) + goto Exit; + + varData->deltaSet[j] = delta; + } + + for ( ; k < varData->regionIdxCount; k++, j++ ) + { + /* read the (signed) byte deltas */ + FT_Char delta; + + + if ( FT_READ_CHAR( delta ) ) + goto Exit; + + varData->deltaSet[j] = delta; + } + } + } + + Exit: + FT_FREE( dataOffsetArray ); + + return error; + } + + + static FT_Error + ft_var_load_delta_set_index_mapping( TT_Face face, + FT_ULong offset, + GX_DeltaSetIdxMap map, + GX_ItemVarStore itemStore ) + { + FT_Stream stream = FT_FACE_STREAM( face ); + FT_Memory memory = stream->memory; + + FT_Error error; + + FT_UShort format; + FT_UInt entrySize; + FT_UInt innerBitCount; + FT_UInt innerIndexMask; + FT_UInt i, j; + + + if ( FT_STREAM_SEEK( offset ) || + FT_READ_USHORT( format ) || + FT_READ_USHORT( map->mapCount ) ) + goto Exit; + + if ( format & 0xFFC0 ) + { + FT_TRACE2(( "bad map format %d\n", format )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + /* bytes per entry: 1, 2, 3, or 4 */ + entrySize = ( ( format & 0x0030 ) >> 4 ) + 1; + innerBitCount = ( format & 0x000F ) + 1; + innerIndexMask = ( 1 << innerBitCount ) - 1; + + if ( FT_NEW_ARRAY( map->innerIndex, map->mapCount ) ) + goto Exit; + + if ( FT_NEW_ARRAY( map->outerIndex, map->mapCount ) ) + goto Exit; + + for ( i = 0; i < map->mapCount; i++ ) + { + FT_UInt mapData = 0; + FT_UInt outerIndex, innerIndex; + + + /* read map data one unsigned byte at a time, big endian */ + for ( j = 0; j < entrySize; j++ ) + { + FT_Byte data; + + + if ( FT_READ_BYTE( data ) ) + goto Exit; + + mapData = ( mapData << 8 ) | data; + } + + outerIndex = mapData >> innerBitCount; + + if ( outerIndex >= itemStore->dataCount ) + { + FT_TRACE2(( "outerIndex[%d] == %d out of range\n", + i, + outerIndex )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + map->outerIndex[i] = outerIndex; + + innerIndex = mapData & innerIndexMask; + + if ( innerIndex >= itemStore->varData[outerIndex].itemCount ) + { + FT_TRACE2(( "innerIndex[%d] == %d out of range\n", + i, + innerIndex )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + map->innerIndex[i] = innerIndex; + } + + Exit: + return error; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_var_load_hvvar */ + /* */ + /* <Description> */ + /* If `vertical' is zero, parse the `HVAR' table and set */ + /* `blend->hvar_loaded' to TRUE. On success, `blend->hvar_checked' */ + /* is set to TRUE. */ + /* */ + /* If `vertical' is not zero, parse the `VVAR' table and set */ + /* `blend->vvar_loaded' to TRUE. On success, `blend->vvar_checked' */ + /* is set to TRUE. */ + /* */ + /* Some memory may remain allocated on error; it is always freed in */ + /* `tt_done_blend', however. */ + /* */ + /* <InOut> */ + /* face :: The font face. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + static FT_Error + ft_var_load_hvvar( TT_Face face, + FT_Bool vertical ) + { + FT_Stream stream = FT_FACE_STREAM( face ); + FT_Memory memory = stream->memory; + + GX_Blend blend = face->blend; + + GX_HVVarTable table; + + FT_Error error; + FT_UShort majorVersion; + FT_ULong table_len; + FT_ULong table_offset; + FT_ULong store_offset; + FT_ULong widthMap_offset; + + + if ( vertical ) + { + blend->vvar_loaded = TRUE; + + FT_TRACE2(( "VVAR " )); + + error = face->goto_table( face, TTAG_VVAR, stream, &table_len ); + } + else + { + blend->hvar_loaded = TRUE; + + FT_TRACE2(( "HVAR " )); + + error = face->goto_table( face, TTAG_HVAR, stream, &table_len ); + } + + if ( error ) + { + FT_TRACE2(( "is missing\n" )); + goto Exit; + } + + table_offset = FT_STREAM_POS(); + + /* skip minor version */ + if ( FT_READ_USHORT( majorVersion ) || + FT_STREAM_SKIP( 2 ) ) + goto Exit; + + if ( majorVersion != 1 ) + { + FT_TRACE2(( "bad table version %d\n", majorVersion )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + if ( FT_READ_ULONG( store_offset ) || + FT_READ_ULONG( widthMap_offset ) ) + goto Exit; + + if ( vertical ) + { + if ( FT_NEW( blend->vvar_table ) ) + goto Exit; + table = blend->vvar_table; + } + else + { + if ( FT_NEW( blend->hvar_table ) ) + goto Exit; + table = blend->hvar_table; + } + + error = ft_var_load_item_variation_store( + face, + table_offset + store_offset, + &table->itemStore ); + if ( error ) + goto Exit; + + if ( widthMap_offset ) + { + error = ft_var_load_delta_set_index_mapping( + face, + table_offset + widthMap_offset, + &table->widthMap, + &table->itemStore ); + if ( error ) + goto Exit; + } + + FT_TRACE2(( "loaded\n" )); + error = FT_Err_Ok; + + Exit: + if ( !error ) + { + if ( vertical ) + { + blend->vvar_checked = TRUE; + + /* FreeType doesn't provide functions to quickly retrieve */ + /* TSB, BSB, or VORG values; we thus don't have to implement */ + /* support for those three item variation stores. */ + + face->variation_support |= TT_FACE_FLAG_VAR_VADVANCE; + } + else + { + blend->hvar_checked = TRUE; + + /* FreeType doesn't provide functions to quickly retrieve */ + /* LSB or RSB values; we thus don't have to implement */ + /* support for those two item variation stores. */ + + face->variation_support |= TT_FACE_FLAG_VAR_HADVANCE; + } + } + + return error; + } + + + static FT_Int + ft_var_get_item_delta( TT_Face face, + GX_ItemVarStore itemStore, + FT_UInt outerIndex, + FT_UInt innerIndex ) + { + GX_ItemVarData varData; + FT_Short* deltaSet; + + FT_UInt master, j; + FT_Fixed netAdjustment = 0; /* accumulated adjustment */ + FT_Fixed scaledDelta; + FT_Fixed delta; + + + /* See pseudo code from `Font Variations Overview' */ + /* in the OpenType specification. */ + + varData = &itemStore->varData[outerIndex]; + deltaSet = &varData->deltaSet[varData->regionIdxCount * innerIndex]; + + /* outer loop steps through master designs to be blended */ + for ( master = 0; master < varData->regionIdxCount; master++ ) + { + FT_Fixed scalar = FT_FIXED_ONE; + FT_UInt regionIndex = varData->regionIndices[master]; + + GX_AxisCoords axis = itemStore->varRegionList[regionIndex].axisList; + + + /* inner loop steps through axes in this region */ + for ( j = 0; j < itemStore->axisCount; j++, axis++ ) + { + FT_Fixed axisScalar; + + + /* compute the scalar contribution of this axis; */ + /* ignore invalid ranges */ + if ( axis->startCoord > axis->peakCoord || + axis->peakCoord > axis->endCoord ) + axisScalar = FT_FIXED_ONE; + + else if ( axis->startCoord < 0 && + axis->endCoord > 0 && + axis->peakCoord != 0 ) + axisScalar = FT_FIXED_ONE; + + /* peak of 0 means ignore this axis */ + else if ( axis->peakCoord == 0 ) + axisScalar = FT_FIXED_ONE; + + /* ignore this region if coords are out of range */ + else if ( face->blend->normalizedcoords[j] < axis->startCoord || + face->blend->normalizedcoords[j] > axis->endCoord ) + axisScalar = 0; + + /* calculate a proportional factor */ + else + { + if ( face->blend->normalizedcoords[j] == axis->peakCoord ) + axisScalar = FT_FIXED_ONE; + else if ( face->blend->normalizedcoords[j] < axis->peakCoord ) + axisScalar = + FT_DivFix( face->blend->normalizedcoords[j] - axis->startCoord, + axis->peakCoord - axis->startCoord ); + else + axisScalar = + FT_DivFix( axis->endCoord - face->blend->normalizedcoords[j], + axis->endCoord - axis->peakCoord ); + } + + /* take product of all the axis scalars */ + scalar = FT_MulFix( scalar, axisScalar ); + + } /* per-axis loop */ + + /* get the scaled delta for this region */ + delta = FT_intToFixed( deltaSet[master] ); + scaledDelta = FT_MulFix( scalar, delta ); + + /* accumulate the adjustments from each region */ + netAdjustment = netAdjustment + scaledDelta; + + } /* per-region loop */ + + return FT_fixedToInt( netAdjustment ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_hvadvance_adjust */ + /* */ + /* <Description> */ + /* Apply `HVAR' advance width or `VVAR' advance height adjustment of */ + /* a given glyph. */ + /* */ + /* <Input> */ + /* gindex :: The glyph index. */ + /* */ + /* vertical :: If set, handle `VVAR' table. */ + /* */ + /* <InOut> */ + /* face :: The font face. */ + /* */ + /* adelta :: Points to width or height value that gets modified. */ + /* */ + static FT_Error + tt_hvadvance_adjust( TT_Face face, + FT_UInt gindex, + FT_Int *avalue, + FT_Bool vertical ) + { + FT_Error error = FT_Err_Ok; + FT_UInt innerIndex, outerIndex; + FT_Int delta; + + GX_HVVarTable table; + + + if ( !face->doblend || !face->blend ) + goto Exit; + + if ( vertical ) + { + if ( !face->blend->vvar_loaded ) + { + /* initialize vvar table */ + face->blend->vvar_error = ft_var_load_hvvar( face, 1 ); + } + + if ( !face->blend->vvar_checked ) + { + error = face->blend->vvar_error; + goto Exit; + } + + table = face->blend->vvar_table; + } + else + { + if ( !face->blend->hvar_loaded ) + { + /* initialize hvar table */ + face->blend->hvar_error = ft_var_load_hvvar( face, 0 ); + } + + if ( !face->blend->hvar_checked ) + { + error = face->blend->hvar_error; + goto Exit; + } + + table = face->blend->hvar_table; + } + + /* advance width or height adjustments are always present in an */ + /* `HVAR' or `VVAR' table; no need to test for this capability */ + + if ( table->widthMap.innerIndex ) + { + FT_UInt idx = gindex; + + + if ( idx >= table->widthMap.mapCount ) + idx = table->widthMap.mapCount - 1; + + /* trust that HVAR parser has checked indices */ + outerIndex = table->widthMap.outerIndex[idx]; + innerIndex = table->widthMap.innerIndex[idx]; + } + else + { + GX_ItemVarData varData; + + + /* no widthMap data */ + outerIndex = 0; + innerIndex = gindex; + + varData = &table->itemStore.varData[outerIndex]; + if ( gindex >= varData->itemCount ) + { + FT_TRACE2(( "gindex %d out of range\n", gindex )); + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + } + + delta = ft_var_get_item_delta( face, + &table->itemStore, + outerIndex, + innerIndex ); + + FT_TRACE5(( "%s value %d adjusted by %d unit%s (%s)\n", + vertical ? "vertical height" : "horizontal width", + *avalue, + delta, + delta == 1 ? "" : "s", + vertical ? "VVAR" : "HVAR" )); + + *avalue += delta; + + Exit: + return error; + } + + + FT_LOCAL_DEF( FT_Error ) + tt_hadvance_adjust( TT_Face face, + FT_UInt gindex, + FT_Int *avalue ) + { + return tt_hvadvance_adjust( face, gindex, avalue, 0 ); + } + + + FT_LOCAL_DEF( FT_Error ) + tt_vadvance_adjust( TT_Face face, + FT_UInt gindex, + FT_Int *avalue ) + { + return tt_hvadvance_adjust( face, gindex, avalue, 1 ); + } + + +#define GX_VALUE_SIZE 8 + + /* all values are FT_Short or FT_UShort entities; */ + /* we treat them consistently as FT_Short */ +#define GX_VALUE_CASE( tag, dflt ) \ + case MVAR_TAG_ ## tag : \ + p = (FT_Short*)&face->dflt; \ + break + +#define GX_GASP_CASE( idx ) \ + case MVAR_TAG_GASP_ ## idx : \ + if ( idx < face->gasp.numRanges - 1 ) \ + p = (FT_Short*)&face->gasp.gaspRanges[idx].maxPPEM; \ + else \ + p = NULL; \ + break + + + static FT_Short* + ft_var_get_value_pointer( TT_Face face, + FT_ULong mvar_tag ) + { + FT_Short* p; + + + switch ( mvar_tag ) + { + GX_GASP_CASE( 0 ); + GX_GASP_CASE( 1 ); + GX_GASP_CASE( 2 ); + GX_GASP_CASE( 3 ); + GX_GASP_CASE( 4 ); + GX_GASP_CASE( 5 ); + GX_GASP_CASE( 6 ); + GX_GASP_CASE( 7 ); + GX_GASP_CASE( 8 ); + GX_GASP_CASE( 9 ); + + GX_VALUE_CASE( CPHT, os2.sCapHeight ); + GX_VALUE_CASE( HASC, os2.sTypoAscender ); + GX_VALUE_CASE( HCLA, os2.usWinAscent ); + GX_VALUE_CASE( HCLD, os2.usWinDescent ); + GX_VALUE_CASE( HCOF, horizontal.caret_Offset ); + GX_VALUE_CASE( HCRN, horizontal.caret_Slope_Run ); + GX_VALUE_CASE( HCRS, horizontal.caret_Slope_Rise ); + GX_VALUE_CASE( HDSC, os2.sTypoDescender ); + GX_VALUE_CASE( HLGP, os2.sTypoLineGap ); + GX_VALUE_CASE( SBXO, os2.ySubscriptXOffset); + GX_VALUE_CASE( SBXS, os2.ySubscriptXSize ); + GX_VALUE_CASE( SBYO, os2.ySubscriptYOffset ); + GX_VALUE_CASE( SBYS, os2.ySubscriptYSize ); + GX_VALUE_CASE( SPXO, os2.ySuperscriptXOffset ); + GX_VALUE_CASE( SPXS, os2.ySuperscriptXSize ); + GX_VALUE_CASE( SPYO, os2.ySuperscriptYOffset ); + GX_VALUE_CASE( SPYS, os2.ySuperscriptYSize ); + GX_VALUE_CASE( STRO, os2.yStrikeoutPosition ); + GX_VALUE_CASE( STRS, os2.yStrikeoutSize ); + GX_VALUE_CASE( UNDO, postscript.underlinePosition ); + GX_VALUE_CASE( UNDS, postscript.underlineThickness ); + GX_VALUE_CASE( VASC, vertical.Ascender ); + GX_VALUE_CASE( VCOF, vertical.caret_Offset ); + GX_VALUE_CASE( VCRN, vertical.caret_Slope_Run ); + GX_VALUE_CASE( VCRS, vertical.caret_Slope_Rise ); + GX_VALUE_CASE( VDSC, vertical.Descender ); + GX_VALUE_CASE( VLGP, vertical.Line_Gap ); + GX_VALUE_CASE( XHGT, os2.sxHeight ); + + default: + /* ignore unknown tag */ + p = NULL; + } + + return p; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_var_load_mvar */ + /* */ + /* <Description> */ + /* Parse the `MVAR' table. */ + /* */ + /* Some memory may remain allocated on error; it is always freed in */ + /* `tt_done_blend', however. */ + /* */ + /* <InOut> */ + /* face :: The font face. */ + /* */ + static void + ft_var_load_mvar( TT_Face face ) + { + FT_Stream stream = FT_FACE_STREAM( face ); + FT_Memory memory = stream->memory; + + GX_Blend blend = face->blend; + GX_ItemVarStore itemStore; + GX_Value value, limit; + + FT_Error error; + FT_UShort majorVersion; + FT_ULong table_len; + FT_ULong table_offset; + FT_UShort store_offset; + FT_ULong records_offset; + + + FT_TRACE2(( "MVAR " )); + + error = face->goto_table( face, TTAG_MVAR, stream, &table_len ); + if ( error ) + { + FT_TRACE2(( "is missing\n" )); + return; + } + + table_offset = FT_STREAM_POS(); + + /* skip minor version */ + if ( FT_READ_USHORT( majorVersion ) || + FT_STREAM_SKIP( 2 ) ) + return; + + if ( majorVersion != 1 ) + { + FT_TRACE2(( "bad table version %d\n", majorVersion )); + return; + } + + if ( FT_NEW( blend->mvar_table ) ) + return; + + /* skip reserved entry and value record size */ + if ( FT_STREAM_SKIP( 4 ) || + FT_READ_USHORT( blend->mvar_table->valueCount ) || + FT_READ_USHORT( store_offset ) ) + return; + + records_offset = FT_STREAM_POS(); + + error = ft_var_load_item_variation_store( + face, + table_offset + store_offset, + &blend->mvar_table->itemStore ); + if ( error ) + return; + + if ( FT_NEW_ARRAY( blend->mvar_table->values, + blend->mvar_table->valueCount ) ) + return; + + if ( FT_STREAM_SEEK( records_offset ) || + FT_FRAME_ENTER( blend->mvar_table->valueCount * GX_VALUE_SIZE ) ) + return; + + value = blend->mvar_table->values; + limit = value + blend->mvar_table->valueCount; + itemStore = &blend->mvar_table->itemStore; + + for ( ; value < limit; value++ ) + { + value->tag = FT_GET_ULONG(); + value->outerIndex = FT_GET_USHORT(); + value->innerIndex = FT_GET_USHORT(); + + if ( value->outerIndex >= itemStore->dataCount || + value->innerIndex >= itemStore->varData[value->outerIndex] + .itemCount ) + { + error = FT_THROW( Invalid_Table ); + break; + } + } + + FT_FRAME_EXIT(); + + if ( error ) + return; + + FT_TRACE2(( "loaded\n" )); + + value = blend->mvar_table->values; + limit = value + blend->mvar_table->valueCount; + + /* save original values of the data MVAR is going to modify */ + for ( ; value < limit; value++ ) + { + FT_Short* p = ft_var_get_value_pointer( face, value->tag ); + + + if ( p ) + value->unmodified = *p; +#ifdef FT_DEBUG_LEVEL_TRACE + else + FT_TRACE1(( "ft_var_load_mvar: Ignoring unknown tag `%c%c%c%c'\n", + (FT_Char)( value->tag >> 24 ), + (FT_Char)( value->tag >> 16 ), + (FT_Char)( value->tag >> 8 ), + (FT_Char)( value->tag ) )); +#endif + } + + face->variation_support |= TT_FACE_FLAG_VAR_MVAR; + } + + + static FT_Error + tt_size_reset_iterator( FT_ListNode node, + void* user ) + { + TT_Size size = (TT_Size)node->data; + + FT_UNUSED( user ); + + + tt_size_reset( size, 1 ); + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_apply_mvar */ + /* */ + /* <Description> */ + /* Apply `MVAR' table adjustments. */ + /* */ + /* <InOut> */ + /* face :: The font face. */ + /* */ + FT_LOCAL_DEF( void ) + tt_apply_mvar( TT_Face face ) + { + GX_Blend blend = face->blend; + GX_Value value, limit; + + + if ( !( face->variation_support & TT_FACE_FLAG_VAR_MVAR ) ) + return; + + value = blend->mvar_table->values; + limit = value + blend->mvar_table->valueCount; + + for ( ; value < limit; value++ ) + { + FT_Short* p = ft_var_get_value_pointer( face, value->tag ); + FT_Int delta; + + + delta = ft_var_get_item_delta( face, + &blend->mvar_table->itemStore, + value->outerIndex, + value->innerIndex ); + + if ( p ) + { + FT_TRACE5(( "value %c%c%c%c (%d unit%s) adjusted by %d unit%s (MVAR)\n", + (FT_Char)( value->tag >> 24 ), + (FT_Char)( value->tag >> 16 ), + (FT_Char)( value->tag >> 8 ), + (FT_Char)( value->tag ), + value->unmodified, + value->unmodified == 1 ? "" : "s", + delta, + delta == 1 ? "" : "s" )); + + /* since we handle both signed and unsigned values as FT_Short, */ + /* ensure proper overflow arithmetic */ + *p = (FT_Short)( value->unmodified + (FT_Short)delta ); + } + } + + /* adjust all derived values */ + { + FT_Face root = &face->root; + + + if ( face->os2.version != 0xFFFFU ) + { + if ( face->os2.sTypoAscender || face->os2.sTypoDescender ) + { + root->ascender = face->os2.sTypoAscender; + root->descender = face->os2.sTypoDescender; + + root->height = root->ascender - root->descender + + face->os2.sTypoLineGap; + } + else + { + root->ascender = (FT_Short)face->os2.usWinAscent; + root->descender = -(FT_Short)face->os2.usWinDescent; + + root->height = root->ascender - root->descender; + } + } + + root->underline_position = face->postscript.underlinePosition - + face->postscript.underlineThickness / 2; + root->underline_thickness = face->postscript.underlineThickness; + + /* iterate over all FT_Size objects and call `tt_size_reset' */ + /* to propagate the metrics changes */ + FT_List_Iterate( &root->sizes_list, + tt_size_reset_iterator, + NULL ); + } + } + + typedef struct GX_GVar_Head_ { FT_Long version; @@ -434,10 +1448,10 @@ FT_TRACE2(( "GVAR " )); - if ( ( error = face->goto_table( face, - TTAG_gvar, - stream, - &table_len ) ) != 0 ) + if ( FT_SET_ERROR( face->goto_table( face, + TTAG_gvar, + stream, + &table_len ) ) ) { FT_TRACE2(( "is missing\n" )); goto Exit; @@ -447,10 +1461,6 @@ if ( FT_STREAM_READ_FIELDS( gvar_fields, &gvar_head ) ) goto Exit; - blend->tuplecount = gvar_head.globalCoordCount; - blend->gv_glyphcnt = gvar_head.glyphCount; - offsetToData = gvar_start + gvar_head.offsetToData; - if ( gvar_head.version != 0x00010000L ) { FT_TRACE1(( "bad table version\n" )); @@ -458,8 +1468,6 @@ goto Exit; } - FT_TRACE2(( "loaded\n" )); - if ( gvar_head.axisCount != (FT_UShort)blend->mmvar->num_axis ) { FT_TRACE1(( "ft_var_load_gvar: number of axes in `gvar' and `cvar'\n" @@ -468,8 +1476,36 @@ goto Exit; } - FT_TRACE5(( "gvar: there are %d shared coordinates:\n", - blend->tuplecount )); + /* rough sanity check, ignoring offsets */ + if ( (FT_ULong)gvar_head.globalCoordCount * gvar_head.axisCount > + table_len / 2 ) + { + FT_TRACE1(( "ft_var_load_gvar:" + " invalid number of global coordinates\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + /* rough sanity check: offsets can be either 2 or 4 bytes */ + if ( (FT_ULong)gvar_head.glyphCount * + ( ( gvar_head.flags & 1 ) ? 4 : 2 ) > table_len ) + { + FT_TRACE1(( "ft_var_load_gvar: invalid number of glyphs\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + FT_TRACE2(( "loaded\n" )); + + blend->gvar_size = table_len; + blend->tuplecount = gvar_head.globalCoordCount; + blend->gv_glyphcnt = gvar_head.glyphCount; + offsetToData = gvar_start + gvar_head.offsetToData; + + FT_TRACE5(( "gvar: there %s %d shared coordinate%s:\n", + blend->tuplecount == 1 ? "is" : "are", + blend->tuplecount, + blend->tuplecount == 1 ? "" : "s" )); if ( FT_NEW_ARRAY( blend->glyphoffsets, blend->gv_glyphcnt + 1 ) ) goto Exit; @@ -511,11 +1547,11 @@ for ( i = 0; i < blend->tuplecount; i++ ) { FT_TRACE5(( " [ " )); - for ( j = 0 ; j < (FT_UInt)gvar_head.axisCount; j++ ) + for ( j = 0; j < (FT_UInt)gvar_head.axisCount; j++ ) { blend->tuplecoords[i * gvar_head.axisCount + j] = FT_GET_SHORT() * 4; /* convert to FT_Fixed */ - FT_TRACE5(( "%.4f ", + FT_TRACE5(( "%.5f ", blend->tuplecoords[i * gvar_head.axisCount + j] / 65536.0 )); } FT_TRACE5(( "]\n" )); @@ -571,8 +1607,13 @@ for ( i = 0; i < blend->num_axis; i++ ) { - FT_TRACE6(( " axis coordinate %d (%.4f):\n", + FT_TRACE6(( " axis coordinate %d (%.5f):\n", i, blend->normalizedcoords[i] / 65536.0 )); + if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) ) + FT_TRACE6(( " intermediate coordinates %d (%.5f, %.5f):\n", + i, + im_start_coords[i] / 65536.0, + im_end_coords[i] / 65536.0 )); /* It's not clear why (for intermediate tuples) we don't need */ /* to check against start/end -- the documentation says we don't. */ @@ -585,71 +1626,257 @@ continue; } - else if ( blend->normalizedcoords[i] == 0 ) + if ( blend->normalizedcoords[i] == 0 ) { FT_TRACE6(( " axis coordinate is zero, stop\n" )); apply = 0; break; } - else if ( ( blend->normalizedcoords[i] < 0 && tuple_coords[i] > 0 ) || - ( blend->normalizedcoords[i] > 0 && tuple_coords[i] < 0 ) ) + if ( blend->normalizedcoords[i] == tuple_coords[i] ) { - FT_TRACE6(( " tuple coordinate value %.4f is exceeded, stop\n", + FT_TRACE6(( " tuple coordinate value %.5f fits perfectly\n", tuple_coords[i] / 65536.0 )); - apply = 0; - break; + /* `apply' does not change */ + continue; } - else if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) ) + if ( !( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) ) { - FT_TRACE6(( " tuple coordinate value %.4f fits\n", - tuple_coords[i] / 65536.0 )); /* not an intermediate tuple */ - apply = FT_MulFix( apply, - blend->normalizedcoords[i] > 0 - ? blend->normalizedcoords[i] - : -blend->normalizedcoords[i] ); - } - else if ( blend->normalizedcoords[i] < im_start_coords[i] || - blend->normalizedcoords[i] > im_end_coords[i] ) - { - FT_TRACE6(( " intermediate tuple range [%.4f;%.4f] is exceeded," - " stop\n", - im_start_coords[i] / 65536.0, - im_end_coords[i] / 65536.0 )); - apply = 0; - break; - } + if ( blend->normalizedcoords[i] < FT_MIN( 0, tuple_coords[i] ) || + blend->normalizedcoords[i] > FT_MAX( 0, tuple_coords[i] ) ) + { + FT_TRACE6(( " tuple coordinate value %.5f is exceeded, stop\n", + tuple_coords[i] / 65536.0 )); + apply = 0; + break; + } - else if ( blend->normalizedcoords[i] < tuple_coords[i] ) - { - FT_TRACE6(( " intermediate tuple range [%.4f;%.4f] fits\n", - im_start_coords[i] / 65536.0, - im_end_coords[i] / 65536.0 )); + FT_TRACE6(( " tuple coordinate value %.5f fits\n", + tuple_coords[i] / 65536.0 )); apply = FT_MulDiv( apply, - blend->normalizedcoords[i] - im_start_coords[i], - tuple_coords[i] - im_start_coords[i] ); + blend->normalizedcoords[i], + tuple_coords[i] ); } - else { - FT_TRACE6(( " intermediate tuple range [%.4f;%.4f] fits\n", - im_start_coords[i] / 65536.0, - im_end_coords[i] / 65536.0 )); - apply = FT_MulDiv( apply, - im_end_coords[i] - blend->normalizedcoords[i], - im_end_coords[i] - tuple_coords[i] ); + /* intermediate tuple */ + + if ( blend->normalizedcoords[i] < im_start_coords[i] || + blend->normalizedcoords[i] > im_end_coords[i] ) + { + FT_TRACE6(( " intermediate tuple range [%.5f;%.5f] is exceeded," + " stop\n", + im_start_coords[i] / 65536.0, + im_end_coords[i] / 65536.0 )); + apply = 0; + break; + } + + else if ( blend->normalizedcoords[i] < tuple_coords[i] ) + { + FT_TRACE6(( " intermediate tuple range [%.5f;%.5f] fits\n", + im_start_coords[i] / 65536.0, + im_end_coords[i] / 65536.0 )); + apply = FT_MulDiv( apply, + blend->normalizedcoords[i] - im_start_coords[i], + tuple_coords[i] - im_start_coords[i] ); + } + + else + { + FT_TRACE6(( " intermediate tuple range [%.5f;%.5f] fits\n", + im_start_coords[i] / 65536.0, + im_end_coords[i] / 65536.0 )); + apply = FT_MulDiv( apply, + im_end_coords[i] - blend->normalizedcoords[i], + im_end_coords[i] - tuple_coords[i] ); + } } } - FT_TRACE6(( " apply factor is %.4f\n", apply / 65536.0 )); + FT_TRACE6(( " apply factor is %.5f\n", apply / 65536.0 )); return apply; } + /* convert from design coordinates to normalized coordinates */ + + static void + ft_var_to_normalized( TT_Face face, + FT_UInt num_coords, + FT_Fixed* coords, + FT_Fixed* normalized ) + { + GX_Blend blend; + FT_MM_Var* mmvar; + FT_UInt i, j; + FT_Var_Axis* a; + GX_AVarSegment av; + + + blend = face->blend; + mmvar = blend->mmvar; + + if ( num_coords > mmvar->num_axis ) + { + FT_TRACE2(( "ft_var_to_normalized:" + " only using first %d of %d coordinates\n", + mmvar->num_axis, num_coords )); + num_coords = mmvar->num_axis; + } + + /* Axis normalization is a two-stage process. First we normalize */ + /* based on the [min,def,max] values for the axis to be [-1,0,1]. */ + /* Then, if there's an `avar' table, we renormalize this range. */ + + a = mmvar->axis; + for ( i = 0; i < num_coords; i++, a++ ) + { + FT_Fixed coord = coords[i]; + + + FT_TRACE5(( " %d: %.5f\n", i, coord / 65536.0 )); + if ( coord > a->maximum || coord < a->minimum ) + { + FT_TRACE1(( + "ft_var_to_normalized: design coordinate %.5f\n" + " is out of range [%.5f;%.5f]; clamping\n", + coord / 65536.0, + a->minimum / 65536.0, + a->maximum / 65536.0 )); + + if ( coord > a->maximum ) + coord = a->maximum; + else + coord = a->minimum; + } + + if ( coord < a->def ) + normalized[i] = -FT_DivFix( coord - a->def, + a->minimum - a->def ); + else if ( coord > a->def ) + normalized[i] = FT_DivFix( coord - a->def, + a->maximum - a->def ); + else + normalized[i] = 0; + } + + FT_TRACE5(( "\n" )); + + for ( ; i < mmvar->num_axis; i++ ) + normalized[i] = 0; + + if ( blend->avar_segment ) + { + FT_TRACE5(( "normalized design coordinates" + " before applying `avar' data:\n" )); + + av = blend->avar_segment; + for ( i = 0; i < mmvar->num_axis; i++, av++ ) + { + for ( j = 1; j < (FT_UInt)av->pairCount; j++ ) + { + if ( normalized[i] < av->correspondence[j].fromCoord ) + { + FT_TRACE5(( " %.5f\n", normalized[i] / 65536.0 )); + + normalized[i] = + FT_MulDiv( normalized[i] - av->correspondence[j - 1].fromCoord, + av->correspondence[j].toCoord - + av->correspondence[j - 1].toCoord, + av->correspondence[j].fromCoord - + av->correspondence[j - 1].fromCoord ) + + av->correspondence[j - 1].toCoord; + break; + } + } + } + } + } + + + /* convert from normalized coordinates to design coordinates */ + + static void + ft_var_to_design( TT_Face face, + FT_UInt num_coords, + FT_Fixed* coords, + FT_Fixed* design ) + { + GX_Blend blend; + FT_MM_Var* mmvar; + FT_Var_Axis* a; + + FT_UInt i, j, nc; + + + blend = face->blend; + + nc = num_coords; + if ( num_coords > blend->num_axis ) + { + FT_TRACE2(( "ft_var_to_design:" + " only using first %d of %d coordinates\n", + blend->num_axis, num_coords )); + nc = blend->num_axis; + } + + for ( i = 0; i < nc; i++ ) + design[i] = coords[i]; + + for ( ; i < num_coords; i++ ) + design[i] = 0; + + if ( blend->avar_segment ) + { + GX_AVarSegment av = blend->avar_segment; + + + FT_TRACE5(( "design coordinates" + " after removing `avar' distortion:\n" )); + + for ( i = 0; i < nc; i++, av++ ) + { + for ( j = 1; j < (FT_UInt)av->pairCount; j++ ) + { + if ( design[i] < av->correspondence[j].toCoord ) + { + design[i] = + FT_MulDiv( design[i] - av->correspondence[j - 1].toCoord, + av->correspondence[j].fromCoord - + av->correspondence[j - 1].fromCoord, + av->correspondence[j].toCoord - + av->correspondence[j - 1].toCoord ) + + av->correspondence[j - 1].fromCoord; + + FT_TRACE5(( " %.5f\n", design[i] / 65536.0 )); + break; + } + } + } + } + + mmvar = blend->mmvar; + a = mmvar->axis; + + for ( i = 0; i < nc; i++, a++ ) + { + if ( design[i] < 0 ) + design[i] = a->def + FT_MulFix( design[i], + a->def - a->minimum ); + else if ( design[i] > 0 ) + design[i] = a->def + FT_MulFix( design[i], + a->maximum - a->def ); + else + design[i] = a->def; + } + } + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -663,7 +1890,6 @@ { FT_Long version; FT_UShort offsetToData; - FT_UShort countSizePairs; FT_UShort axisCount; FT_UShort axisSize; FT_UShort instanceCount; @@ -691,7 +1917,8 @@ /* */ /* <Description> */ /* Check that the font's `fvar' table is valid, parse it, and return */ - /* those data. */ + /* those data. It also loads (and parses) the `MVAR' table, if */ + /* possible. */ /* */ /* <InOut> */ /* face :: The font face. */ @@ -708,18 +1935,33 @@ TT_Get_MM_Var( TT_Face face, FT_MM_Var* *master ) { - FT_Stream stream = face->root.stream; - FT_Memory memory = face->root.memory; + FT_Stream stream = face->root.stream; + FT_Memory memory = face->root.memory; FT_ULong table_len; - FT_Error error = FT_Err_Ok; - FT_ULong fvar_start; - FT_Int i, j; + FT_Error error = FT_Err_Ok; + FT_ULong fvar_start = 0; + FT_UInt i, j; FT_MM_Var* mmvar = NULL; FT_Fixed* next_coords; + FT_Fixed* nsc; FT_String* next_name; FT_Var_Axis* a; + FT_Fixed* c; FT_Var_Named_Style* ns; GX_FVar_Head fvar_head; + FT_Bool usePsName = 0; + FT_UInt num_instances; + FT_UInt num_axes; + FT_UShort* axis_flags; + + FT_Offset mmvar_size; + FT_Offset axis_flags_size; + FT_Offset axis_size; + FT_Offset namedstyle_size; + FT_Offset next_coords_size; + FT_Offset next_name_size; + + FT_Bool need_init; static const FT_Frame_Field fvar_fields[] = { @@ -728,13 +1970,13 @@ #define FT_STRUCTURE GX_FVar_Head FT_FRAME_START( 16 ), - FT_FRAME_LONG ( version ), - FT_FRAME_USHORT( offsetToData ), - FT_FRAME_USHORT( countSizePairs ), - FT_FRAME_USHORT( axisCount ), - FT_FRAME_USHORT( axisSize ), - FT_FRAME_USHORT( instanceCount ), - FT_FRAME_USHORT( instanceSize ), + FT_FRAME_LONG ( version ), + FT_FRAME_USHORT ( offsetToData ), + FT_FRAME_SKIP_SHORT, + FT_FRAME_USHORT ( axisCount ), + FT_FRAME_USHORT ( axisSize ), + FT_FRAME_USHORT ( instanceCount ), + FT_FRAME_USHORT ( instanceSize ), FT_FRAME_END }; @@ -758,21 +2000,28 @@ /* read the font data and set up the internal representation */ /* if not already done */ - if ( face->blend == NULL ) + need_init = !face->blend; + + if ( need_init ) { FT_TRACE2(( "FVAR " )); /* both `fvar' and `gvar' must be present */ - if ( ( error = face->goto_table( face, TTAG_gvar, - stream, &table_len ) ) != 0 ) + if ( FT_SET_ERROR( face->goto_table( face, TTAG_gvar, + stream, &table_len ) ) ) { - FT_TRACE1(( "\n" - "TT_Get_MM_Var: `gvar' table is missing\n" )); - goto Exit; + /* CFF2 is an alternate to gvar here */ + if ( FT_SET_ERROR( face->goto_table( face, TTAG_CFF2, + stream, &table_len ) ) ) + { + FT_TRACE1(( "\n" + "TT_Get_MM_Var: `gvar' or `CFF2' table is missing\n" )); + goto Exit; + } } - if ( ( error = face->goto_table( face, TTAG_fvar, - stream, &table_len ) ) != 0 ) + if ( FT_SET_ERROR( face->goto_table( face, TTAG_fvar, + stream, &table_len ) ) ) { FT_TRACE1(( "is missing\n" )); goto Exit; @@ -780,45 +2029,67 @@ fvar_start = FT_STREAM_POS( ); + /* the validity of the `fvar' header data was already checked */ + /* in function `sfnt_init_face' */ if ( FT_STREAM_READ_FIELDS( fvar_fields, &fvar_head ) ) goto Exit; - if ( fvar_head.version != (FT_Long)0x00010000L || -#if 0 - /* fonts like `JamRegular.ttf' have an incorrect value for */ - /* `countSizePairs'; since value 2 is hard-coded in `fvar' */ - /* version 1.0, we simply ignore it */ - fvar_head.countSizePairs != 2 || -#endif - fvar_head.axisSize != 20 || - /* axisCount limit implied by 16-bit instanceSize */ - fvar_head.axisCount > 0x3FFE || - fvar_head.instanceSize != 4 + 4 * fvar_head.axisCount || - /* instanceCount limit implied by limited range of name IDs */ - fvar_head.instanceCount > 0x7EFF || - fvar_head.offsetToData + fvar_head.axisCount * 20U + - fvar_head.instanceCount * fvar_head.instanceSize > table_len ) - { - FT_TRACE1(( "\n" - "TT_Get_MM_Var: invalid `fvar' header\n" )); - error = FT_THROW( Invalid_Table ); - goto Exit; - } + usePsName = FT_BOOL( fvar_head.instanceSize == + 6 + 4 * fvar_head.axisCount ); FT_TRACE2(( "loaded\n" )); - FT_TRACE5(( "number of GX style axes: %d\n", fvar_head.axisCount )); + FT_TRACE5(( "%d variation ax%s\n", + fvar_head.axisCount, + fvar_head.axisCount == 1 ? "is" : "es" )); if ( FT_NEW( face->blend ) ) goto Exit; - /* cannot overflow 32-bit arithmetic because of limits above */ - face->blend->mmvar_len = - sizeof ( FT_MM_Var ) + - fvar_head.axisCount * sizeof ( FT_Var_Axis ) + - fvar_head.instanceCount * sizeof ( FT_Var_Named_Style ) + - fvar_head.instanceCount * fvar_head.axisCount * sizeof ( FT_Fixed ) + - 5 * fvar_head.axisCount; + num_axes = fvar_head.axisCount; + face->blend->num_axis = num_axes; + } + else + num_axes = face->blend->num_axis; + + /* `num_instances' holds the number of all named instances, */ + /* including the default instance which might be missing */ + /* in fvar's table of named instances */ + num_instances = (FT_UInt)face->root.style_flags >> 16; + + /* prepare storage area for MM data; this cannot overflow */ + /* 32-bit arithmetic because of the size limits used in the */ + /* `fvar' table validity check in `sfnt_init_face' */ + + /* the various `*_size' variables, which we also use as */ + /* offsets into the `mmlen' array, must be multiples of the */ + /* pointer size (except the last one); without such an */ + /* alignment there might be runtime errors due to */ + /* misaligned addresses */ +#undef ALIGN_SIZE +#define ALIGN_SIZE( n ) \ + ( ( (n) + sizeof (void*) - 1 ) & ~( sizeof (void*) - 1 ) ) + + mmvar_size = ALIGN_SIZE( sizeof ( FT_MM_Var ) ); + axis_flags_size = ALIGN_SIZE( num_axes * + sizeof ( FT_UShort ) ); + axis_size = ALIGN_SIZE( num_axes * + sizeof ( FT_Var_Axis ) ); + namedstyle_size = ALIGN_SIZE( num_instances * + sizeof ( FT_Var_Named_Style ) ); + next_coords_size = ALIGN_SIZE( num_instances * + num_axes * + sizeof ( FT_Fixed ) ); + next_name_size = num_axes * 5; + + if ( need_init ) + { + face->blend->mmvar_len = mmvar_size + + axis_flags_size + + axis_size + + namedstyle_size + + next_coords_size + + next_name_size; if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) ) goto Exit; @@ -828,28 +2099,33 @@ /* the data gets filled in later on */ mmvar->num_axis = - fvar_head.axisCount; + num_axes; mmvar->num_designs = ~0U; /* meaningless in this context; each glyph */ /* may have a different number of designs */ /* (or tuples, as called by Apple) */ mmvar->num_namedstyles = - fvar_head.instanceCount; - mmvar->axis = - (FT_Var_Axis*)&( mmvar[1] ); - mmvar->namedstyle = - (FT_Var_Named_Style*)&( mmvar->axis[fvar_head.axisCount] ); + num_instances; - next_coords = - (FT_Fixed*)&( mmvar->namedstyle[fvar_head.instanceCount] ); - for ( i = 0; i < fvar_head.instanceCount; i++ ) + /* alas, no public field in `FT_Var_Axis' for axis flags */ + axis_flags = + (FT_UShort*)( (char*)mmvar + mmvar_size ); + mmvar->axis = + (FT_Var_Axis*)( (char*)axis_flags + axis_flags_size ); + mmvar->namedstyle = + (FT_Var_Named_Style*)( (char*)mmvar->axis + axis_size ); + + next_coords = (FT_Fixed*)( (char*)mmvar->namedstyle + + namedstyle_size ); + for ( i = 0; i < num_instances; i++ ) { mmvar->namedstyle[i].coords = next_coords; - next_coords += fvar_head.axisCount; + next_coords += num_axes; } - next_name = (FT_String*)next_coords; - for ( i = 0; i < fvar_head.axisCount; i++ ) + next_name = (FT_String*)( (char*)mmvar->namedstyle + + namedstyle_size + next_coords_size ); + for ( i = 0; i < num_axes; i++ ) { mmvar->axis[i].name = next_name; next_name += 5; @@ -861,10 +2137,14 @@ goto Exit; a = mmvar->axis; - for ( i = 0; i < fvar_head.axisCount; i++ ) + for ( i = 0; i < num_axes; i++ ) { GX_FVar_Axis axis_rec; +#ifdef FT_DEBUG_LEVEL_TRACE + int invalid = 0; +#endif + if ( FT_STREAM_READ_FIELDS( fvaraxis_fields, &axis_rec ) ) goto Exit; @@ -880,36 +2160,194 @@ a->name[3] = (FT_String)( ( a->tag ) & 0xFF ); a->name[4] = '\0'; - FT_TRACE5(( " \"%s\": minimum=%.4f, default=%.4f, maximum=%.4f\n", + *axis_flags = axis_rec.flags; + + if ( a->minimum > a->def || + a->def > a->maximum ) + { + a->minimum = a->def; + a->maximum = a->def; + +#ifdef FT_DEBUG_LEVEL_TRACE + invalid = 1; +#endif + } + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( i == 0 ) + FT_TRACE5(( " idx tag " + /* " XXX `XXXX'" */ + " minimum default maximum flags\n" )); + /* " XXXX.XXXXX XXXX.XXXXX XXXX.XXXXX 0xXXXX" */ + + FT_TRACE5(( " %3d `%s'" + " %10.5f %10.5f %10.5f 0x%04X%s\n", + i, a->name, a->minimum / 65536.0, a->def / 65536.0, - a->maximum / 65536.0 )); + a->maximum / 65536.0, + *axis_flags, + invalid ? " (invalid, disabled)" : "" )); +#endif a++; + axis_flags++; } FT_TRACE5(( "\n" )); - ns = mmvar->namedstyle; + /* named instance coordinates are stored as design coordinates; */ + /* we have to convert them to normalized coordinates also */ + if ( FT_NEW_ARRAY( face->blend->normalized_stylecoords, + num_axes * num_instances ) ) + goto Exit; + + if ( fvar_head.instanceCount && !face->blend->avar_loaded ) + { + FT_ULong offset = FT_STREAM_POS(); + + + ft_var_load_avar( face ); + + if ( FT_STREAM_SEEK( offset ) ) + goto Exit; + } + + FT_TRACE5(( "%d instance%s\n", + fvar_head.instanceCount, + fvar_head.instanceCount == 1 ? "" : "s" )); + + ns = mmvar->namedstyle; + nsc = face->blend->normalized_stylecoords; for ( i = 0; i < fvar_head.instanceCount; i++, ns++ ) { - if ( FT_FRAME_ENTER( 4L + 4L * fvar_head.axisCount ) ) + /* PostScript names add 2 bytes to the instance record size */ + if ( FT_FRAME_ENTER( ( usePsName ? 6L : 4L ) + + 4L * num_axes ) ) goto Exit; ns->strid = FT_GET_USHORT(); (void) /* flags = */ FT_GET_USHORT(); - for ( j = 0; j < fvar_head.axisCount; j++ ) - ns->coords[j] = FT_GET_LONG(); + c = ns->coords; + for ( j = 0; j < num_axes; j++, c++ ) + *c = FT_GET_LONG(); + + /* valid psid values are 6, [256;32767], and 0xFFFF */ + if ( usePsName ) + ns->psid = FT_GET_USHORT(); + else + ns->psid = 0xFFFF; + +#ifdef FT_DEBUG_LEVEL_TRACE + { + SFNT_Service sfnt = (SFNT_Service)face->sfnt; + + FT_String* strname = NULL; + FT_String* psname = NULL; + + FT_ULong pos; + + + pos = FT_STREAM_POS(); + + if ( ns->strid != 0xFFFF ) + { + (void)sfnt->get_name( face, + (FT_UShort)ns->strid, + &strname ); + if ( strname && !ft_strcmp( strname, ".notdef" ) ) + strname = NULL; + } + + if ( ns->psid != 0xFFFF ) + { + (void)sfnt->get_name( face, + (FT_UShort)ns->psid, + &psname ); + if ( psname && !ft_strcmp( psname, ".notdef" ) ) + psname = NULL; + } + + (void)FT_STREAM_SEEK( pos ); + + FT_TRACE5(( " instance %d (%s%s%s, %s%s%s)\n", + i, + strname ? "name: `" : "", + strname ? strname : "unnamed", + strname ? "'" : "", + psname ? "PS name: `" : "", + psname ? psname : "no PS name", + psname ? "'" : "" )); + + FT_FREE( strname ); + FT_FREE( psname ); + } +#endif /* FT_DEBUG_LEVEL_TRACE */ + + ft_var_to_normalized( face, num_axes, ns->coords, nsc ); + nsc += num_axes; FT_FRAME_EXIT(); } + + if ( num_instances != fvar_head.instanceCount ) + { + SFNT_Service sfnt = (SFNT_Service)face->sfnt; + + FT_Int found, dummy1, dummy2; + FT_UInt strid = ~0U; + + + /* the default instance is missing in array the */ + /* of named instances; try to synthesize an entry */ + found = sfnt->get_name_id( face, + TT_NAME_ID_TYPOGRAPHIC_SUBFAMILY, + &dummy1, + &dummy2 ); + if ( found ) + strid = TT_NAME_ID_TYPOGRAPHIC_SUBFAMILY; + else + { + found = sfnt->get_name_id( face, + TT_NAME_ID_FONT_SUBFAMILY, + &dummy1, + &dummy2 ); + if ( found ) + strid = TT_NAME_ID_FONT_SUBFAMILY; + } + + if ( found ) + { + found = sfnt->get_name_id( face, + TT_NAME_ID_PS_NAME, + &dummy1, + &dummy2 ); + if ( found ) + { + FT_TRACE5(( "TT_Get_MM_Var:" + " Adding default instance to named instances\n" )); + + ns = &mmvar->namedstyle[fvar_head.instanceCount]; + + ns->strid = strid; + ns->psid = TT_NAME_ID_PS_NAME; + + a = mmvar->axis; + c = ns->coords; + for ( j = 0; j < num_axes; j++, a++, c++ ) + *c = a->def; + } + } + } + + ft_var_load_mvar( face ); } /* fill the output array if requested */ - if ( master != NULL ) + if ( master ) { FT_UInt n; @@ -918,22 +2356,25 @@ goto Exit; FT_MEM_COPY( mmvar, face->blend->mmvar, face->blend->mmvar_len ); + axis_flags = + (FT_UShort*)( (char*)mmvar + mmvar_size ); mmvar->axis = - (FT_Var_Axis*)&( mmvar[1] ); + (FT_Var_Axis*)( (char*)axis_flags + axis_flags_size ); mmvar->namedstyle = - (FT_Var_Named_Style*)&( mmvar->axis[mmvar->num_axis] ); - next_coords = - (FT_Fixed*)&( mmvar->namedstyle[mmvar->num_namedstyles] ); + (FT_Var_Named_Style*)( (char*)mmvar->axis+ axis_size ); + next_coords = (FT_Fixed*)( (char*)mmvar->namedstyle + + namedstyle_size ); for ( n = 0; n < mmvar->num_namedstyles; n++ ) { mmvar->namedstyle[n].coords = next_coords; - next_coords += mmvar->num_axis; + next_coords += num_axes; } a = mmvar->axis; - next_name = (FT_String*)next_coords; - for ( n = 0; n < mmvar->num_axis; n++ ) + next_name = (FT_String*)( (char*)mmvar->namedstyle + + namedstyle_size + next_coords_size ); + for ( n = 0; n < num_axes; n++ ) { a->name = next_name; @@ -959,6 +2400,196 @@ } + static FT_Error + tt_set_mm_blend( TT_Face face, + FT_UInt num_coords, + FT_Fixed* coords, + FT_Bool set_design_coords ) + { + FT_Error error = FT_Err_Ok; + GX_Blend blend; + FT_MM_Var* mmvar; + FT_UInt i; + + FT_Bool all_design_coords = FALSE; + + FT_Memory memory = face->root.memory; + + enum + { + mcvt_retain, + mcvt_modify, + mcvt_load + + } manageCvt; + + + face->doblend = FALSE; + + if ( !face->blend ) + { + if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) ) + goto Exit; + } + + blend = face->blend; + mmvar = blend->mmvar; + + if ( num_coords > mmvar->num_axis ) + { + FT_TRACE2(( "TT_Set_MM_Blend:" + " only using first %d of %d coordinates\n", + mmvar->num_axis, num_coords )); + num_coords = mmvar->num_axis; + } + + FT_TRACE5(( "TT_Set_MM_Blend:\n" + " normalized design coordinates:\n" )); + + for ( i = 0; i < num_coords; i++ ) + { + FT_TRACE5(( " %.5f\n", coords[i] / 65536.0 )); + if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L ) + { + FT_TRACE1(( "TT_Set_MM_Blend: normalized design coordinate %.5f\n" + " is out of range [-1;1]\n", + coords[i] / 65536.0 )); + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + } + + FT_TRACE5(( "\n" )); + + if ( !face->is_cff2 && !blend->glyphoffsets ) + if ( FT_SET_ERROR( ft_var_load_gvar( face ) ) ) + goto Exit; + + if ( !blend->coords ) + { + if ( FT_NEW_ARRAY( blend->coords, mmvar->num_axis ) ) + goto Exit; + + /* the first time we have to compute all design coordinates */ + all_design_coords = TRUE; + } + + if ( !blend->normalizedcoords ) + { + if ( FT_NEW_ARRAY( blend->normalizedcoords, mmvar->num_axis ) ) + goto Exit; + + manageCvt = mcvt_modify; + + /* If we have not set the blend coordinates before this, then the */ + /* cvt table will still be what we read from the `cvt ' table and */ + /* we don't need to reload it. We may need to change it though... */ + } + else + { + FT_Bool have_diff = 0; + FT_UInt j; + FT_Fixed* c; + FT_Fixed* n; + + + manageCvt = mcvt_retain; + + for ( i = 0; i < num_coords; i++ ) + { + if ( blend->normalizedcoords[i] != coords[i] ) + { + manageCvt = mcvt_load; + have_diff = 1; + break; + } + } + + if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ) + { + FT_UInt idx = (FT_UInt)face->root.face_index >> 16; + + + c = blend->normalizedcoords + i; + n = blend->normalized_stylecoords + idx * mmvar->num_axis + i; + for ( j = i; j < mmvar->num_axis; j++, n++, c++ ) + if ( *c != *n ) + have_diff = 1; + } + else + { + c = blend->normalizedcoords + i; + for ( j = i; j < mmvar->num_axis; j++, c++ ) + if ( *c != 0 ) + have_diff = 1; + } + + /* return value -1 indicates `no change' */ + if ( !have_diff ) + return -1; + + for ( ; i < mmvar->num_axis; i++ ) + { + if ( blend->normalizedcoords[i] != 0 ) + { + manageCvt = mcvt_load; + break; + } + } + + /* If we don't change the blend coords then we don't need to do */ + /* anything to the cvt table. It will be correct. Otherwise we */ + /* no longer have the original cvt (it was modified when we set */ + /* the blend last time), so we must reload and then modify it. */ + } + + blend->num_axis = mmvar->num_axis; + FT_MEM_COPY( blend->normalizedcoords, + coords, + num_coords * sizeof ( FT_Fixed ) ); + + if ( set_design_coords ) + ft_var_to_design( face, + all_design_coords ? blend->num_axis : num_coords, + blend->normalizedcoords, + blend->coords ); + + face->doblend = TRUE; + + if ( face->cvt ) + { + switch ( manageCvt ) + { + case mcvt_load: + /* The cvt table has been loaded already; every time we change the */ + /* blend we may need to reload and remodify the cvt table. */ + FT_FREE( face->cvt ); + face->cvt = NULL; + + error = tt_face_load_cvt( face, face->root.stream ); + break; + + case mcvt_modify: + /* The original cvt table is in memory. All we need to do is */ + /* apply the `cvar' table (if any). */ + error = tt_face_vary_cvt( face, face->root.stream ); + break; + + case mcvt_retain: + /* The cvt table is correct for this set of coordinates. */ + break; + } + } + + /* enforce recomputation of the PostScript name; */ + FT_FREE( face->postscript_name ); + face->postscript_name = NULL; + + Exit: + return error; + } + + /*************************************************************************/ /* */ /* <Function> */ @@ -989,133 +2620,95 @@ FT_UInt num_coords, FT_Fixed* coords ) { - FT_Error error = FT_Err_Ok; - GX_Blend blend; - FT_MM_Var* mmvar; - FT_UInt i; - FT_Memory memory = face->root.memory; + FT_Error error; - enum + + error = tt_set_mm_blend( face, num_coords, coords, 1 ); + if ( error ) + return error; + + if ( num_coords ) + face->root.face_flags |= FT_FACE_FLAG_VARIATION; + else + face->root.face_flags &= ~FT_FACE_FLAG_VARIATION; + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Get_MM_Blend */ + /* */ + /* <Description> */ + /* Get the blend (normalized) coordinates for this instance of the */ + /* font. */ + /* */ + /* <InOut> */ + /* face :: The font. */ + /* Initialize the blend structure with `gvar' data. */ + /* */ + /* <Input> */ + /* num_coords :: The number of available coordinates. If it is */ + /* larger than the number of axes, set the excess */ + /* values to 0. */ + /* */ + /* coords :: An array of `num_coords', each between [-1,1]. */ + /* */ + /* <Return> */ + /* FreeType error code. 0 means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Get_MM_Blend( TT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Error error = FT_Err_Ok; + GX_Blend blend; + FT_UInt i, nc; + + + if ( !face->blend ) { - mcvt_retain, - mcvt_modify, - mcvt_load - - } manageCvt; - - - face->doblend = FALSE; - - if ( face->blend == NULL ) - { - if ( ( error = TT_Get_MM_Var( face, NULL ) ) != 0 ) - goto Exit; + if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) ) + return error; } blend = face->blend; - mmvar = blend->mmvar; - if ( num_coords > mmvar->num_axis ) + if ( !blend->coords ) { - FT_TRACE2(( "TT_Set_MM_Blend: only using first %d of %d coordinates\n", - mmvar->num_axis, num_coords )); - num_coords = mmvar->num_axis; + /* select default instance coordinates */ + /* if no instance is selected yet */ + if ( FT_SET_ERROR( tt_set_mm_blend( face, 0, NULL, 1 ) ) ) + return error; } - FT_TRACE5(( "normalized design coordinates:\n" )); - - for ( i = 0; i < num_coords; i++ ) + nc = num_coords; + if ( num_coords > blend->num_axis ) { - FT_TRACE5(( " %.4f\n", coords[i] / 65536.0 )); - if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L ) - { - FT_TRACE1(( "TT_Set_MM_Blend: normalized design coordinate %.4f\n" - " is out of range [-1;1]\n", - coords[i] / 65536.0 )); - error = FT_THROW( Invalid_Argument ); - goto Exit; - } + FT_TRACE2(( "TT_Get_MM_Blend:" + " only using first %d of %d coordinates\n", + blend->num_axis, num_coords )); + nc = blend->num_axis; } - FT_TRACE5(( "\n" )); - - if ( blend->glyphoffsets == NULL ) - if ( ( error = ft_var_load_gvar( face ) ) != 0 ) - goto Exit; - - if ( blend->normalizedcoords == NULL ) + if ( face->doblend ) { - if ( FT_NEW_ARRAY( blend->normalizedcoords, mmvar->num_axis ) ) - goto Exit; - - manageCvt = mcvt_modify; - - /* If we have not set the blend coordinates before this, then the */ - /* cvt table will still be what we read from the `cvt ' table and */ - /* we don't need to reload it. We may need to change it though... */ + for ( i = 0; i < nc; i++ ) + coords[i] = blend->normalizedcoords[i]; } else { - manageCvt = mcvt_retain; - - for ( i = 0; i < num_coords; i++ ) - { - if ( blend->normalizedcoords[i] != coords[i] ) - { - manageCvt = mcvt_load; - break; - } - } - - for ( ; i < mmvar->num_axis; i++ ) - { - if ( blend->normalizedcoords[i] != 0 ) - { - manageCvt = mcvt_load; - break; - } - } - - /* If we don't change the blend coords then we don't need to do */ - /* anything to the cvt table. It will be correct. Otherwise we */ - /* no longer have the original cvt (it was modified when we set */ - /* the blend last time), so we must reload and then modify it. */ + for ( i = 0; i < nc; i++ ) + coords[i] = 0; } - blend->num_axis = mmvar->num_axis; - FT_MEM_COPY( blend->normalizedcoords, - coords, - num_coords * sizeof ( FT_Fixed ) ); + for ( ; i < num_coords; i++ ) + coords[i] = 0; - face->doblend = TRUE; - - if ( face->cvt != NULL ) - { - switch ( manageCvt ) - { - case mcvt_load: - /* The cvt table has been loaded already; every time we change the */ - /* blend we may need to reload and remodify the cvt table. */ - FT_FREE( face->cvt ); - face->cvt = NULL; - - error = tt_face_load_cvt( face, face->root.stream ); - break; - - case mcvt_modify: - /* The original cvt table is in memory. All we need to do is */ - /* apply the `cvar' table (if any). */ - error = tt_face_vary_cvt( face, face->root.stream ); - break; - - case mcvt_retain: - /* The cvt table is correct for this set of coordinates. */ - break; - } - } - - Exit: - return error; + return FT_Err_Ok; } @@ -1149,19 +2742,22 @@ FT_UInt num_coords, FT_Fixed* coords ) { - FT_Error error = FT_Err_Ok; - FT_Fixed* normalized = NULL; - GX_Blend blend; - FT_MM_Var* mmvar; - FT_UInt i, j; - FT_Var_Axis* a; - GX_AVarSegment av; - FT_Memory memory = face->root.memory; + FT_Error error = FT_Err_Ok; + GX_Blend blend; + FT_MM_Var* mmvar; + FT_UInt i; + FT_Memory memory = face->root.memory; + + FT_Fixed* c; + FT_Fixed* n; + FT_Fixed* normalized = NULL; + + FT_Bool have_diff = 0; - if ( face->blend == NULL ) + if ( !face->blend ) { - if ( ( error = TT_Get_MM_Var( face, NULL ) ) != 0 ) + if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) ) goto Exit; } @@ -1176,75 +2772,81 @@ num_coords = mmvar->num_axis; } - /* Axis normalization is a two stage process. First we normalize */ - /* based on the [min,def,max] values for the axis to be [-1,0,1]. */ - /* Then, if there's an `avar' table, we renormalize this range. */ - - if ( FT_NEW_ARRAY( normalized, mmvar->num_axis ) ) - goto Exit; - - FT_TRACE5(( "design coordinates:\n" )); - - a = mmvar->axis; - for ( i = 0; i < num_coords; i++, a++ ) + if ( !blend->coords ) { - FT_TRACE5(( " %.4f\n", coords[i] / 65536.0 )); - if ( coords[i] > a->maximum || coords[i] < a->minimum ) - { - FT_TRACE1(( "TT_Set_Var_Design: normalized design coordinate %.4f\n" - " is out of range [%.4f;%.4f]\n", - coords[i] / 65536.0, - a->minimum / 65536.0, - a->maximum / 65536.0 )); - error = FT_THROW( Invalid_Argument ); + if ( FT_NEW_ARRAY( blend->coords, mmvar->num_axis ) ) goto Exit; - } - - if ( coords[i] < a->def ) - normalized[i] = -FT_DivFix( coords[i] - a->def, - a->minimum - a->def ); - else if ( a->maximum == a->def ) - normalized[i] = 0; - else - normalized[i] = FT_DivFix( coords[i] - a->def, - a->maximum - a->def ); } - FT_TRACE5(( "\n" )); - - for ( ; i < mmvar->num_axis; i++ ) - normalized[i] = 0; - - if ( !blend->avar_checked ) - ft_var_load_avar( face ); - - if ( blend->avar_segment != NULL ) + c = blend->coords; + n = coords; + for ( i = 0; i < num_coords; i++, n++, c++ ) { - FT_TRACE5(( "normalized design coordinates" - " before applying `avar' data:\n" )); - - av = blend->avar_segment; - for ( i = 0; i < mmvar->num_axis; i++, av++ ) + if ( *c != *n ) { - for ( j = 1; j < (FT_UInt)av->pairCount; j++ ) + *c = *n; + have_diff = 1; + } + } + + if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ) + { + FT_UInt instance_index; + FT_Var_Named_Style* named_style; + + + instance_index = (FT_UInt)face->root.face_index >> 16; + named_style = mmvar->namedstyle + instance_index - 1; + + n = named_style->coords + num_coords; + for ( ; i < mmvar->num_axis; i++, n++, c++ ) + { + if ( *c != *n ) { - FT_TRACE5(( " %.4f\n", normalized[i] / 65536.0 )); - if ( normalized[i] < av->correspondence[j].fromCoord ) - { - normalized[i] = - FT_MulDiv( normalized[i] - av->correspondence[j - 1].fromCoord, - av->correspondence[j].toCoord - - av->correspondence[j - 1].toCoord, - av->correspondence[j].fromCoord - - av->correspondence[j - 1].fromCoord ) + - av->correspondence[j - 1].toCoord; - break; - } + *c = *n; + have_diff = 1; + } + } + } + else + { + FT_Var_Axis* a; + + + a = mmvar->axis + num_coords; + for ( ; i < mmvar->num_axis; i++, a++, c++ ) + { + if ( *c != a->def ) + { + *c = a->def; + have_diff = 1; } } } - error = TT_Set_MM_Blend( face, mmvar->num_axis, normalized ); + /* return value -1 indicates `no change'; */ + /* we can exit early if `normalizedcoords' is already computed */ + if ( blend->normalizedcoords && !have_diff ) + return -1; + + if ( FT_NEW_ARRAY( normalized, mmvar->num_axis ) ) + goto Exit; + + if ( !face->blend->avar_loaded ) + ft_var_load_avar( face ); + + FT_TRACE5(( "TT_Set_Var_Design:\n" + " normalized design coordinates:\n" )); + ft_var_to_normalized( face, num_coords, blend->coords, normalized ); + + error = tt_set_mm_blend( face, mmvar->num_axis, normalized, 0 ); + if ( error ) + goto Exit; + + if ( num_coords ) + face->root.face_flags |= FT_FACE_FLAG_VARIATION; + else + face->root.face_flags &= ~FT_FACE_FLAG_VARIATION; Exit: FT_FREE( normalized ); @@ -1252,6 +2854,165 @@ } + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Get_Var_Design */ + /* */ + /* <Description> */ + /* Get the design coordinates of the currently selected interpolated */ + /* font. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* num_coords :: The number of design coordinates to retrieve. If it */ + /* is larger than the number of axes, set the excess */ + /* values to~0. */ + /* */ + /* <Output> */ + /* coords :: The design coordinates array. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Get_Var_Design( TT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Error error = FT_Err_Ok; + GX_Blend blend; + FT_UInt i, nc; + + + if ( !face->blend ) + { + if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) ) + return error; + } + + blend = face->blend; + + if ( !blend->coords ) + { + /* select default instance coordinates */ + /* if no instance is selected yet */ + if ( FT_SET_ERROR( tt_set_mm_blend( face, 0, NULL, 1 ) ) ) + return error; + } + + nc = num_coords; + if ( num_coords > blend->num_axis ) + { + FT_TRACE2(( "TT_Get_Var_Design:" + " only using first %d of %d coordinates\n", + blend->num_axis, num_coords )); + nc = blend->num_axis; + } + + if ( face->doblend ) + { + for ( i = 0; i < nc; i++ ) + coords[i] = blend->coords[i]; + } + else + { + for ( i = 0; i < nc; i++ ) + coords[i] = 0; + } + + for ( ; i < num_coords; i++ ) + coords[i] = 0; + + return FT_Err_Ok; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* TT_Set_Named_Instance */ + /* */ + /* <Description> */ + /* Set the given named instance, also resetting any further */ + /* variation. */ + /* */ + /* <Input> */ + /* face :: A handle to the source face. */ + /* */ + /* instance_index :: The instance index, starting with value 1. */ + /* Value 0 indicates to not use an instance. */ + /* */ + /* <Return> */ + /* FreeType error code. 0~means success. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + TT_Set_Named_Instance( TT_Face face, + FT_UInt instance_index ) + { + FT_Error error = FT_ERR( Invalid_Argument ); + GX_Blend blend; + FT_MM_Var* mmvar; + + FT_UInt num_instances; + + + if ( !face->blend ) + { + if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) ) + goto Exit; + } + + blend = face->blend; + mmvar = blend->mmvar; + + num_instances = (FT_UInt)face->root.style_flags >> 16; + + /* `instance_index' starts with value 1, thus `>' */ + if ( instance_index > num_instances ) + goto Exit; + + if ( instance_index > 0 && mmvar->namedstyle ) + { + FT_Memory memory = face->root.memory; + SFNT_Service sfnt = (SFNT_Service)face->sfnt; + + FT_Var_Named_Style* named_style; + FT_String* style_name; + + + named_style = mmvar->namedstyle + instance_index - 1; + + error = sfnt->get_name( face, + (FT_UShort)named_style->strid, + &style_name ); + if ( error ) + goto Exit; + + /* set (or replace) style name */ + FT_FREE( face->root.style_name ); + face->root.style_name = style_name; + + /* finally, select the named instance */ + error = TT_Set_Var_Design( face, + mmvar->num_axis, + named_style->coords ); + if ( error ) + goto Exit; + } + else + error = TT_Set_Var_Design( face, 0, NULL ); + + face->root.face_index = ( instance_index << 16 ) | + ( face->root.face_index & 0xFFFFL ); + face->root.face_flags &= ~FT_FACE_FLAG_VARIATION; + + Exit: + return error; + } + + /*************************************************************************/ /*************************************************************************/ /***** *****/ @@ -1298,14 +3059,16 @@ FT_Fixed* im_start_coords = NULL; FT_Fixed* im_end_coords = NULL; GX_Blend blend = face->blend; - FT_UInt point_count; - FT_UShort* localpoints; + FT_UInt point_count, spoint_count = 0; + FT_UShort* sharedpoints = NULL; + FT_UShort* localpoints = NULL; + FT_UShort* points; FT_Short* deltas; FT_TRACE2(( "CVAR " )); - if ( blend == NULL ) + if ( !blend ) { FT_TRACE2(( "\n" "tt_face_vary_cvt: no blend specified\n" )); @@ -1313,7 +3076,7 @@ goto Exit; } - if ( face->cvt == NULL ) + if ( !face->cvt ) { FT_TRACE2(( "\n" "tt_face_vary_cvt: no `cvt ' table\n" )); @@ -1353,13 +3116,39 @@ goto FExit; tupleCount = FT_GET_USHORT(); - offsetToData = table_start + FT_GET_USHORT(); + offsetToData = FT_GET_USHORT(); - /* The documentation implies there are flags packed into the */ - /* tuplecount, but John Jenkins says that shared points don't apply */ - /* to `cvar', and no other flags are defined. */ + /* rough sanity test */ + if ( offsetToData + ( tupleCount & GX_TC_TUPLE_COUNT_MASK ) * 4 > + table_len ) + { + FT_TRACE2(( "tt_face_vary_cvt:" + " invalid CVT variation array header\n" )); - FT_TRACE5(( "cvar: there are %d tuples:\n", tupleCount )); + error = FT_THROW( Invalid_Table ); + goto FExit; + } + + offsetToData += table_start; + + if ( tupleCount & GX_TC_TUPLES_SHARE_POINT_NUMBERS ) + { + here = FT_Stream_FTell( stream ); + + FT_Stream_SeekSet( stream, offsetToData ); + + sharedpoints = ft_var_readpackedpoints( stream, + table_len, + &spoint_count ); + offsetToData = FT_Stream_FTell( stream ); + + FT_Stream_SeekSet( stream, here ); + } + + FT_TRACE5(( "cvar: there %s %d tuple%s:\n", + ( tupleCount & 0xFFF ) == 1 ? "is" : "are", + tupleCount & 0xFFF, + ( tupleCount & 0xFFF ) == 1 ? "" : "s" )); for ( i = 0; i < ( tupleCount & 0xFFF ); i++ ) { @@ -1373,26 +3162,25 @@ tupleDataSize = FT_GET_USHORT(); tupleIndex = FT_GET_USHORT(); - /* There is no provision here for a global tuple coordinate section, */ - /* so John says. There are no tuple indices, just embedded tuples. */ - if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) { for ( j = 0; j < blend->num_axis; j++ ) tuple_coords[j] = FT_GET_SHORT() * 4; /* convert from */ /* short frac to fixed */ } - else + else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount ) { - /* skip this tuple; it makes no sense */ + FT_TRACE2(( "tt_face_vary_cvt:" + " invalid tuple index\n" )); - if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) - for ( j = 0; j < 2 * blend->num_axis; j++ ) - (void)FT_GET_SHORT(); - - offsetToData += tupleDataSize; - continue; + error = FT_THROW( Invalid_Table ); + goto Exit; } + else + FT_MEM_COPY( + tuple_coords, + &blend->tuplecoords[( tupleIndex & 0xFFF ) * blend->num_axis], + blend->num_axis * sizeof ( FT_Fixed ) ); if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) { @@ -1407,11 +3195,8 @@ tuple_coords, im_start_coords, im_end_coords ); - if ( /* tuple isn't active for our blend */ - apply == 0 || - /* global points not allowed, */ - /* if they aren't local, makes no sense */ - !( tupleIndex & GX_TI_PRIVATE_POINT_NUMBERS ) ) + + if ( apply == 0 ) /* tuple isn't active for our blend */ { offsetToData += tupleDataSize; continue; @@ -1421,11 +3206,27 @@ FT_Stream_SeekSet( stream, offsetToData ); - localpoints = ft_var_readpackedpoints( stream, &point_count ); - deltas = ft_var_readpackeddeltas( stream, - point_count == 0 ? face->cvt_size - : point_count ); - if ( localpoints == NULL || deltas == NULL ) + if ( tupleIndex & GX_TI_PRIVATE_POINT_NUMBERS ) + { + localpoints = ft_var_readpackedpoints( stream, + table_len, + &point_count ); + points = localpoints; + } + else + { + points = sharedpoints; + point_count = spoint_count; + } + + deltas = ft_var_readpackeddeltas( stream, + table_len, + point_count == 0 ? face->cvt_size + : point_count ); + + if ( !points || + !deltas || + ( localpoints == ALL_POINTS && point_count != face->cvt_size ) ) ; /* failure, ignore it */ else if ( localpoints == ALL_POINTS ) @@ -1473,10 +3274,15 @@ for ( j = 0; j < point_count; j++ ) { - int pindex = localpoints[j]; - FT_Long orig_cvt = face->cvt[pindex]; + int pindex; + FT_Long orig_cvt; + pindex = points[j]; + if ( (FT_ULong)pindex >= face->cvt_size ) + continue; + + orig_cvt = face->cvt[pindex]; face->cvt[pindex] = (FT_Short)( orig_cvt + FT_MulFix( deltas[j], apply ) ); @@ -1511,6 +3317,8 @@ FT_FRAME_EXIT(); Exit: + if ( sharedpoints != ALL_POINTS ) + FT_FREE( sharedpoints ); FT_FREE( tuple_coords ); FT_FREE( im_start_coords ); FT_FREE( im_end_coords ); @@ -1599,25 +3407,12 @@ d1 = out1 - in1; d2 = out2 - in2; - if ( out1 == out2 || in1 == in2 ) + /* If the reference points have the same coordinate but different */ + /* delta, inferred delta is zero. Otherwise interpolate. */ + if ( in1 != in2 || out1 == out2 ) { - for ( p = p1; p <= p2; p++ ) - { - out = in_points[p].x; - - if ( out <= in1 ) - out += d1; - else if ( out >= in2 ) - out += d2; - else - out = out1; - - out_points[p].x = out; - } - } - else - { - FT_Fixed scale = FT_DivFix( out2 - out1, in2 - in1 ); + FT_Fixed scale = in1 != in2 ? FT_DivFix( out2 - out1, in2 - in1 ) + : 0; for ( p = p1; p <= p2; p++ ) @@ -1644,12 +3439,11 @@ /* modeled after `Ins_IUP */ static void - tt_handle_deltas( FT_Outline* outline, - FT_Vector* in_points, - FT_Bool* has_delta ) + tt_interpolate_deltas( FT_Outline* outline, + FT_Vector* out_points, + FT_Vector* in_points, + FT_Bool* has_delta ) { - FT_Vector* out_points; - FT_Int first_point; FT_Int end_point; @@ -1664,8 +3458,6 @@ if ( !outline->n_contours ) return; - out_points = outline->points; - contour = 0; point = 0; @@ -1769,6 +3561,7 @@ GX_Blend blend = face->blend; FT_Vector* points_org = NULL; + FT_Vector* points_out = NULL; FT_Bool* has_delta = NULL; FT_Error error; @@ -1787,7 +3580,7 @@ FT_Short *deltas_x, *deltas_y; - if ( !face->doblend || blend == NULL ) + if ( !face->doblend || !blend ) return FT_THROW( Invalid_Argument ); if ( glyph_index >= blend->gv_glyphcnt || @@ -1800,6 +3593,7 @@ } if ( FT_NEW_ARRAY( points_org, n_points ) || + FT_NEW_ARRAY( points_out, n_points ) || FT_NEW_ARRAY( has_delta, n_points ) ) goto Fail1; @@ -1811,7 +3605,6 @@ glyph_start = FT_Stream_FTell( stream ); /* each set of glyph variation data is formatted similarly to `cvar' */ - /* (except we get shared points and global tuples) */ if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis ) || FT_NEW_ARRAY( im_start_coords, blend->num_axis ) || @@ -1819,7 +3612,20 @@ goto Fail2; tupleCount = FT_GET_USHORT(); - offsetToData = glyph_start + FT_GET_USHORT(); + offsetToData = FT_GET_USHORT(); + + /* rough sanity test */ + if ( offsetToData + ( tupleCount & GX_TC_TUPLE_COUNT_MASK ) * 4 > + blend->gvar_size ) + { + FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:" + " invalid glyph variation array header\n" )); + + error = FT_THROW( Invalid_Table ); + goto Fail2; + } + + offsetToData += glyph_start; if ( tupleCount & GX_TC_TUPLES_SHARE_POINT_NUMBERS ) { @@ -1827,13 +3633,21 @@ FT_Stream_SeekSet( stream, offsetToData ); - sharedpoints = ft_var_readpackedpoints( stream, &spoint_count ); + sharedpoints = ft_var_readpackedpoints( stream, + blend->gvar_size, + &spoint_count ); offsetToData = FT_Stream_FTell( stream ); FT_Stream_SeekSet( stream, here ); } - FT_TRACE5(( "gvar: there are %d tuples:\n", tupleCount )); + FT_TRACE5(( "gvar: there %s %d tuple%s:\n", + ( tupleCount & GX_TC_TUPLE_COUNT_MASK ) == 1 ? "is" : "are", + tupleCount & GX_TC_TUPLE_COUNT_MASK, + ( tupleCount & GX_TC_TUPLE_COUNT_MASK ) == 1 ? "" : "s" )); + + for ( j = 0; j < n_points; j++ ) + points_org[j] = outline->points[j]; for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); i++ ) { @@ -1855,6 +3669,9 @@ } else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount ) { + FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:" + " invalid tuple index\n" )); + error = FT_THROW( Invalid_Table ); goto Fail2; } @@ -1886,11 +3703,13 @@ here = FT_Stream_FTell( stream ); + FT_Stream_SeekSet( stream, offsetToData ); + if ( tupleIndex & GX_TI_PRIVATE_POINT_NUMBERS ) { - FT_Stream_SeekSet( stream, offsetToData ); - - localpoints = ft_var_readpackedpoints( stream, &point_count ); + localpoints = ft_var_readpackedpoints( stream, + blend->gvar_size, + &point_count ); points = localpoints; } else @@ -1900,13 +3719,15 @@ } deltas_x = ft_var_readpackeddeltas( stream, + blend->gvar_size, point_count == 0 ? n_points : point_count ); deltas_y = ft_var_readpackeddeltas( stream, + blend->gvar_size, point_count == 0 ? n_points : point_count ); - if ( points == NULL || deltas_y == NULL || deltas_x == NULL ) + if ( !points || !deltas_y || !deltas_x ) ; /* failure, ignore it */ else if ( points == ALL_POINTS ) @@ -1921,22 +3742,48 @@ /* this means that there are deltas for every point in the glyph */ for ( j = 0; j < n_points; j++ ) { -#ifdef FT_DEBUG_LEVEL_TRACE - FT_Vector point_org = outline->points[j]; -#endif + FT_Pos delta_x = FT_MulFix( deltas_x[j], apply ); + FT_Pos delta_y = FT_MulFix( deltas_y[j], apply ); - outline->points[j].x += FT_MulFix( deltas_x[j], apply ); - outline->points[j].y += FT_MulFix( deltas_y[j], apply ); + if ( j < n_points - 4 ) + { + outline->points[j].x += delta_x; + outline->points[j].y += delta_y; + } + else + { + /* To avoid double adjustment of advance width or height, */ + /* adjust phantom points only if there is no HVAR or VVAR */ + /* support, respectively. */ + if ( j == ( n_points - 4 ) && + !( face->variation_support & + TT_FACE_FLAG_VAR_LSB ) ) + outline->points[j].x += delta_x; + + else if ( j == ( n_points - 3 ) && + !( face->variation_support & + TT_FACE_FLAG_VAR_HADVANCE ) ) + outline->points[j].x += delta_x; + + else if ( j == ( n_points - 2 ) && + !( face->variation_support & + TT_FACE_FLAG_VAR_TSB ) ) + outline->points[j].y += delta_y; + + else if ( j == ( n_points - 1 ) && + !( face->variation_support & + TT_FACE_FLAG_VAR_VADVANCE ) ) + outline->points[j].y += delta_y; + } #ifdef FT_DEBUG_LEVEL_TRACE - if ( ( point_org.x != outline->points[j].x ) || - ( point_org.y != outline->points[j].y ) ) + if ( delta_x || delta_y ) { FT_TRACE7(( " %d: (%d, %d) -> (%d, %d)\n", j, - point_org.x, - point_org.y, + outline->points[j].x - delta_x, + outline->points[j].y - delta_y, outline->points[j].x, outline->points[j].y )); count++; @@ -1961,13 +3808,13 @@ /* IUP bytecode instruction */ for ( j = 0; j < n_points; j++ ) { - points_org[j] = outline->points[j]; has_delta[j] = FALSE; + points_out[j] = points_org[j]; } for ( j = 0; j < point_count; j++ ) { - FT_UShort idx = localpoints[j]; + FT_UShort idx = points[j]; if ( idx >= n_points ) @@ -1975,34 +3822,71 @@ has_delta[idx] = TRUE; - outline->points[idx].x += FT_MulFix( deltas_x[j], apply ); - outline->points[idx].y += FT_MulFix( deltas_y[j], apply ); + points_out[idx].x += FT_MulFix( deltas_x[j], apply ); + points_out[idx].y += FT_MulFix( deltas_y[j], apply ); } /* no need to handle phantom points here, */ /* since solitary points can't be interpolated */ - tt_handle_deltas( outline, - points_org, - has_delta ); + tt_interpolate_deltas( outline, + points_out, + points_org, + has_delta ); -#ifdef FT_DEBUG_LEVEL_TRACE FT_TRACE7(( " point deltas:\n" )); - for ( j = 0; j < n_points; j++) + for ( j = 0; j < n_points; j++ ) { - if ( ( points_org[j].x != outline->points[j].x ) || - ( points_org[j].y != outline->points[j].y ) ) + FT_Pos delta_x = points_out[j].x - points_org[j].x; + FT_Pos delta_y = points_out[j].y - points_org[j].y; + + + if ( j < n_points - 4 ) + { + outline->points[j].x += delta_x; + outline->points[j].y += delta_y; + } + else + { + /* To avoid double adjustment of advance width or height, */ + /* adjust phantom points only if there is no HVAR or VVAR */ + /* support, respectively. */ + if ( j == ( n_points - 4 ) && + !( face->variation_support & + TT_FACE_FLAG_VAR_LSB ) ) + outline->points[j].x += delta_x; + + else if ( j == ( n_points - 3 ) && + !( face->variation_support & + TT_FACE_FLAG_VAR_HADVANCE ) ) + outline->points[j].x += delta_x; + + else if ( j == ( n_points - 2 ) && + !( face->variation_support & + TT_FACE_FLAG_VAR_TSB ) ) + outline->points[j].y += delta_y; + + else if ( j == ( n_points - 1 ) && + !( face->variation_support & + TT_FACE_FLAG_VAR_VADVANCE ) ) + outline->points[j].y += delta_y; + } + +#ifdef FT_DEBUG_LEVEL_TRACE + if ( delta_x || delta_y ) { FT_TRACE7(( " %d: (%d, %d) -> (%d, %d)\n", j, - points_org[j].x, - points_org[j].y, + outline->points[j].x - delta_x, + outline->points[j].y - delta_y, outline->points[j].x, outline->points[j].y )); count++; } +#endif } +#ifdef FT_DEBUG_LEVEL_TRACE if ( !count ) FT_TRACE7(( " none\n" )); #endif @@ -2021,6 +3905,8 @@ FT_TRACE5(( "\n" )); Fail2: + if ( sharedpoints != ALL_POINTS ) + FT_FREE( sharedpoints ); FT_FREE( tuple_coords ); FT_FREE( im_start_coords ); FT_FREE( im_end_coords ); @@ -2029,12 +3915,84 @@ Fail1: FT_FREE( points_org ); + FT_FREE( points_out ); FT_FREE( has_delta ); return error; } + /*************************************************************************/ + /* */ + /* <Function> */ + /* tt_get_var_blend */ + /* */ + /* <Description> */ + /* An extended internal version of `TT_Get_MM_Blend' that returns */ + /* pointers instead of copying data, without any initialization of */ + /* the MM machinery in case it isn't loaded yet. */ + /* */ + FT_LOCAL_DEF( FT_Error ) + tt_get_var_blend( TT_Face face, + FT_UInt *num_coords, + FT_Fixed* *coords, + FT_Fixed* *normalizedcoords, + FT_MM_Var* *mm_var ) + { + if ( face->blend ) + { + if ( num_coords ) + *num_coords = face->blend->num_axis; + if ( coords ) + *coords = face->blend->coords; + if ( normalizedcoords ) + *normalizedcoords = face->blend->normalizedcoords; + if ( mm_var ) + *mm_var = face->blend->mmvar; + } + else + { + if ( num_coords ) + *num_coords = 0; + if ( coords ) + *coords = NULL; + if ( mm_var ) + *mm_var = NULL; + } + + return FT_Err_Ok; + } + + + static void + ft_var_done_item_variation_store( TT_Face face, + GX_ItemVarStore itemStore ) + { + FT_Memory memory = FT_FACE_MEMORY( face ); + FT_UInt i; + + + if ( itemStore->varData ) + { + for ( i = 0; i < itemStore->dataCount; i++ ) + { + FT_FREE( itemStore->varData[i].regionIndices ); + FT_FREE( itemStore->varData[i].deltaSet ); + } + + FT_FREE( itemStore->varData ); + } + + if ( itemStore->varRegionList ) + { + for ( i = 0; i < itemStore->regionCount; i++ ) + FT_FREE( itemStore->varRegionList[i].axisList ); + + FT_FREE( itemStore->varRegionList ); + } + } + + /*************************************************************************/ /* */ /* <Function> */ @@ -2044,31 +4002,73 @@ /* Free the blend internal data structure. */ /* */ FT_LOCAL_DEF( void ) - tt_done_blend( FT_Memory memory, - GX_Blend blend ) + tt_done_blend( TT_Face face ) { - if ( blend != NULL ) + FT_Memory memory = FT_FACE_MEMORY( face ); + GX_Blend blend = face->blend; + + + if ( blend ) { - FT_UInt i; + FT_UInt i, num_axes; + /* blend->num_axis might not be set up yet */ + num_axes = blend->mmvar->num_axis; + + FT_FREE( blend->coords ); FT_FREE( blend->normalizedcoords ); + FT_FREE( blend->normalized_stylecoords ); FT_FREE( blend->mmvar ); - if ( blend->avar_segment != NULL ) + if ( blend->avar_segment ) { - for ( i = 0; i < blend->num_axis; i++ ) + for ( i = 0; i < num_axes; i++ ) FT_FREE( blend->avar_segment[i].correspondence ); FT_FREE( blend->avar_segment ); } + if ( blend->hvar_table ) + { + ft_var_done_item_variation_store( face, + &blend->hvar_table->itemStore ); + + FT_FREE( blend->hvar_table->widthMap.innerIndex ); + FT_FREE( blend->hvar_table->widthMap.outerIndex ); + FT_FREE( blend->hvar_table ); + } + + if ( blend->vvar_table ) + { + ft_var_done_item_variation_store( face, + &blend->vvar_table->itemStore ); + + FT_FREE( blend->vvar_table->widthMap.innerIndex ); + FT_FREE( blend->vvar_table->widthMap.outerIndex ); + FT_FREE( blend->vvar_table ); + } + + if ( blend->mvar_table ) + { + ft_var_done_item_variation_store( face, + &blend->mvar_table->itemStore ); + + FT_FREE( blend->mvar_table->values ); + FT_FREE( blend->mvar_table ); + } + FT_FREE( blend->tuplecoords ); FT_FREE( blend->glyphoffsets ); FT_FREE( blend ); } } -#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ +#else /* !TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + + /* ANSI C doesn't like empty source files */ + typedef int _tt_gxvar_dummy; + +#endif /* !TT_CONFIG_OPTION_GX_VAR_SUPPORT */ /* END */ diff --git a/src/3rdparty/freetype/src/truetype/ttgxvar.h b/src/3rdparty/freetype/src/truetype/ttgxvar.h index 060d4d60ea..a37bb90266 100644 --- a/src/3rdparty/freetype/src/truetype/ttgxvar.h +++ b/src/3rdparty/freetype/src/truetype/ttgxvar.h @@ -4,7 +4,7 @@ /* */ /* TrueType GX Font Variation loader (specification) */ /* */ -/* Copyright 2004-2015 by */ +/* Copyright 2004-2018 by */ /* David Turner, Robert Wilhelm, Werner Lemberg and George Williams. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTGXVAR_H__ -#define __TTGXVAR_H__ +#ifndef TTGXVAR_H_ +#define TTGXVAR_H_ #include <ft2build.h> @@ -27,6 +27,8 @@ FT_BEGIN_HEADER +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + /*************************************************************************/ /* */ /* <Struct> */ @@ -61,6 +63,152 @@ FT_BEGIN_HEADER } GX_AVarSegmentRec, *GX_AVarSegment; + typedef struct GX_ItemVarDataRec_ + { + FT_UInt itemCount; /* number of delta sets per item */ + FT_UInt regionIdxCount; /* number of region indices in this data */ + FT_UInt* regionIndices; /* array of `regionCount' indices; */ + /* these index `varRegionList' */ + FT_Short* deltaSet; /* array of `itemCount' deltas */ + /* use `innerIndex' for this array */ + + } GX_ItemVarDataRec, *GX_ItemVarData; + + + /* contribution of one axis to a region */ + typedef struct GX_AxisCoordsRec_ + { + FT_Fixed startCoord; + FT_Fixed peakCoord; /* zero means no effect (factor = 1) */ + FT_Fixed endCoord; + + } GX_AxisCoordsRec, *GX_AxisCoords; + + + typedef struct GX_VarRegionRec_ + { + GX_AxisCoords axisList; /* array of axisCount records */ + + } GX_VarRegionRec, *GX_VarRegion; + + + /* item variation store */ + typedef struct GX_ItemVarStoreRec_ + { + FT_UInt dataCount; + GX_ItemVarData varData; /* array of dataCount records; */ + /* use `outerIndex' for this array */ + FT_UShort axisCount; + FT_UInt regionCount; /* total number of regions defined */ + GX_VarRegion varRegionList; + + } GX_ItemVarStoreRec, *GX_ItemVarStore; + + + typedef struct GX_DeltaSetIdxMapRec_ + { + FT_UInt mapCount; + FT_UInt* outerIndex; /* indices to item var data */ + FT_UInt* innerIndex; /* indices to delta set */ + + } GX_DeltaSetIdxMapRec, *GX_DeltaSetIdxMap; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* GX_HVVarTableRec */ + /* */ + /* <Description> */ + /* Data from either the `HVAR' or `VVAR' table. */ + /* */ + typedef struct GX_HVVarTableRec_ + { + GX_ItemVarStoreRec itemStore; /* Item Variation Store */ + GX_DeltaSetIdxMapRec widthMap; /* Advance Width Mapping */ + +#if 0 + GX_DeltaSetIdxMapRec lsbMap; /* not implemented */ + GX_DeltaSetIdxMapRec rsbMap; /* not implemented */ + + GX_DeltaSetIdxMapRec tsbMap; /* not implemented */ + GX_DeltaSetIdxMapRec bsbMap; /* not implemented */ + GX_DeltaSetIdxMapRec vorgMap; /* not implemented */ +#endif + + } GX_HVVarTableRec, *GX_HVVarTable; + + +#define MVAR_TAG_GASP_0 FT_MAKE_TAG( 'g', 's', 'p', '0' ) +#define MVAR_TAG_GASP_1 FT_MAKE_TAG( 'g', 's', 'p', '1' ) +#define MVAR_TAG_GASP_2 FT_MAKE_TAG( 'g', 's', 'p', '2' ) +#define MVAR_TAG_GASP_3 FT_MAKE_TAG( 'g', 's', 'p', '3' ) +#define MVAR_TAG_GASP_4 FT_MAKE_TAG( 'g', 's', 'p', '4' ) +#define MVAR_TAG_GASP_5 FT_MAKE_TAG( 'g', 's', 'p', '5' ) +#define MVAR_TAG_GASP_6 FT_MAKE_TAG( 'g', 's', 'p', '6' ) +#define MVAR_TAG_GASP_7 FT_MAKE_TAG( 'g', 's', 'p', '7' ) +#define MVAR_TAG_GASP_8 FT_MAKE_TAG( 'g', 's', 'p', '8' ) +#define MVAR_TAG_GASP_9 FT_MAKE_TAG( 'g', 's', 'p', '9' ) + +#define MVAR_TAG_CPHT FT_MAKE_TAG( 'c', 'p', 'h', 't' ) +#define MVAR_TAG_HASC FT_MAKE_TAG( 'h', 'a', 's', 'c' ) +#define MVAR_TAG_HCLA FT_MAKE_TAG( 'h', 'c', 'l', 'a' ) +#define MVAR_TAG_HCLD FT_MAKE_TAG( 'h', 'c', 'l', 'd' ) +#define MVAR_TAG_HCOF FT_MAKE_TAG( 'h', 'c', 'o', 'f' ) +#define MVAR_TAG_HCRN FT_MAKE_TAG( 'h', 'c', 'r', 'n' ) +#define MVAR_TAG_HCRS FT_MAKE_TAG( 'h', 'c', 'r', 's' ) +#define MVAR_TAG_HDSC FT_MAKE_TAG( 'h', 'd', 's', 'c' ) +#define MVAR_TAG_HLGP FT_MAKE_TAG( 'h', 'l', 'g', 'p' ) +#define MVAR_TAG_SBXO FT_MAKE_TAG( 's', 'b', 'x', 'o' ) +#define MVAR_TAG_SBXS FT_MAKE_TAG( 's', 'b', 'x', 's' ) +#define MVAR_TAG_SBYO FT_MAKE_TAG( 's', 'b', 'y', 'o' ) +#define MVAR_TAG_SBYS FT_MAKE_TAG( 's', 'b', 'y', 's' ) +#define MVAR_TAG_SPXO FT_MAKE_TAG( 's', 'p', 'x', 'o' ) +#define MVAR_TAG_SPXS FT_MAKE_TAG( 's', 'p', 'x', 's' ) +#define MVAR_TAG_SPYO FT_MAKE_TAG( 's', 'p', 'y', 'o' ) +#define MVAR_TAG_SPYS FT_MAKE_TAG( 's', 'p', 'y', 's' ) +#define MVAR_TAG_STRO FT_MAKE_TAG( 's', 't', 'r', 'o' ) +#define MVAR_TAG_STRS FT_MAKE_TAG( 's', 't', 'r', 's' ) +#define MVAR_TAG_UNDO FT_MAKE_TAG( 'u', 'n', 'd', 'o' ) +#define MVAR_TAG_UNDS FT_MAKE_TAG( 'u', 'n', 'd', 's' ) +#define MVAR_TAG_VASC FT_MAKE_TAG( 'v', 'a', 's', 'c' ) +#define MVAR_TAG_VCOF FT_MAKE_TAG( 'v', 'c', 'o', 'f' ) +#define MVAR_TAG_VCRN FT_MAKE_TAG( 'v', 'c', 'r', 'n' ) +#define MVAR_TAG_VCRS FT_MAKE_TAG( 'v', 'c', 'r', 's' ) +#define MVAR_TAG_VDSC FT_MAKE_TAG( 'v', 'd', 's', 'c' ) +#define MVAR_TAG_VLGP FT_MAKE_TAG( 'v', 'l', 'g', 'p' ) +#define MVAR_TAG_XHGT FT_MAKE_TAG( 'x', 'h', 'g', 't' ) + + + typedef struct GX_ValueRec_ + { + FT_ULong tag; + FT_UShort outerIndex; + FT_UShort innerIndex; + + FT_Short unmodified; /* values are either FT_Short or FT_UShort */ + + } GX_ValueRec, *GX_Value; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* GX_MVarTableRec */ + /* */ + /* <Description> */ + /* Data from the `MVAR' table. */ + /* */ + typedef struct GX_MVarTableRec_ + { + FT_UShort valueCount; + + GX_ItemVarStoreRec itemStore; /* Item Variation Store */ + GX_Value values; /* Value Records */ + + } GX_MVarTableRec, *GX_MVarTable; + + /*************************************************************************/ /* */ /* <Struct> */ @@ -68,32 +216,122 @@ FT_BEGIN_HEADER /* */ /* <Description> */ /* Data for interpolating a font from a distortable font specified */ - /* by the GX *var tables ([fgca]var). */ + /* by the GX *var tables ([fgcahvm]var). */ /* */ /* <Fields> */ - /* num_axis :: The number of axes along which interpolation */ - /* may happen */ + /* num_axis :: */ + /* The number of axes along which interpolation may happen. */ /* */ - /* normalizedcoords :: A normalized value (between [-1,1]) indicating */ - /* the contribution along each axis to the final */ - /* interpolated font. */ + /* coords :: */ + /* An array of design coordinates (in user space) indicating the */ + /* contribution along each axis to the final interpolated font. */ + /* `normalizedcoords' holds the same values. */ + /* */ + /* normalizedcoords :: */ + /* An array of normalized values (between [-1,1]) indicating the */ + /* contribution along each axis to the final interpolated font. */ + /* `coords' holds the same values. */ + /* */ + /* mmvar :: */ + /* Data from the `fvar' table. */ + /* */ + /* mmvar_len :: */ + /* The length of the `mmvar' structure. */ + /* */ + /* normalized_stylecoords :: */ + /* A two-dimensional array that holds the named instance data from */ + /* `mmvar' as normalized values. */ + /* */ + /* avar_loaded :: */ + /* A Boolean; if set, FreeType tried to load (and parse) the `avar' */ + /* table. */ + /* */ + /* avar_segment :: */ + /* Data from the `avar' table. */ + /* */ + /* hvar_loaded :: */ + /* A Boolean; if set, FreeType tried to load (and parse) the `hvar' */ + /* table. */ + /* */ + /* hvar_checked :: */ + /* A Boolean; if set, FreeType successfully loaded and parsed the */ + /* `hvar' table. */ + /* */ + /* hvar_error :: */ + /* If loading and parsing of the `hvar' table failed, this field */ + /* holds the corresponding error code. */ + /* */ + /* hvar_table :: */ + /* Data from the `hvar' table. */ + /* */ + /* vvar_loaded :: */ + /* A Boolean; if set, FreeType tried to load (and parse) the `vvar' */ + /* table. */ + /* */ + /* vvar_checked :: */ + /* A Boolean; if set, FreeType successfully loaded and parsed the */ + /* `vvar' table. */ + /* */ + /* vvar_error :: */ + /* If loading and parsing of the `vvar' table failed, this field */ + /* holds the corresponding error code. */ + /* */ + /* vvar_table :: */ + /* Data from the `vvar' table. */ + /* */ + /* mvar_table :: */ + /* Data from the `mvar' table. */ + /* */ + /* tuplecount :: */ + /* The number of shared tuples in the `gvar' table. */ + /* */ + /* tuplecoords :: */ + /* A two-dimensional array that holds the shared tuple coordinates */ + /* in the `gvar' table. */ + /* */ + /* gv_glyphcnt :: */ + /* The number of glyphs handled in the `gvar' table. */ + /* */ + /* glyphoffsets :: */ + /* Offsets into the glyph variation data array. */ + /* */ + /* gvar_size :: */ + /* The size of the `gvar' table. */ /* */ typedef struct GX_BlendRec_ { FT_UInt num_axis; + FT_Fixed* coords; FT_Fixed* normalizedcoords; FT_MM_Var* mmvar; FT_Offset mmvar_len; - FT_Bool avar_checked; - GX_AVarSegment avar_segment; + FT_Fixed* normalized_stylecoords; + /* normalized_stylecoords[num_namedstyles][num_axis] */ - FT_UInt tuplecount; /* shared tuples in `gvar' */ - FT_Fixed* tuplecoords; /* tuplecoords[tuplecount][num_axis] */ + FT_Bool avar_loaded; + GX_AVarSegment avar_segment; /* avar_segment[num_axis] */ + + FT_Bool hvar_loaded; + FT_Bool hvar_checked; + FT_Error hvar_error; + GX_HVVarTable hvar_table; + + FT_Bool vvar_loaded; + FT_Bool vvar_checked; + FT_Error vvar_error; + GX_HVVarTable vvar_table; + + GX_MVarTable mvar_table; + + FT_UInt tuplecount; + FT_Fixed* tuplecoords; /* tuplecoords[tuplecount][num_axis] */ FT_UInt gv_glyphcnt; - FT_ULong* glyphoffsets; + FT_ULong* glyphoffsets; /* glyphoffsets[gv_glyphcnt + 1] */ + + FT_ULong gvar_size; } GX_BlendRec; @@ -146,6 +384,11 @@ FT_BEGIN_HEADER FT_UInt num_coords, FT_Fixed* coords ); + FT_LOCAL( FT_Error ) + TT_Get_MM_Blend( TT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + FT_LOCAL( FT_Error ) TT_Set_Var_Design( TT_Face face, FT_UInt num_coords, @@ -155,6 +398,14 @@ FT_BEGIN_HEADER TT_Get_MM_Var( TT_Face face, FT_MM_Var* *master ); + FT_LOCAL( FT_Error ) + TT_Get_Var_Design( TT_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + FT_LOCAL( FT_Error ) + TT_Set_Named_Instance( TT_Face face, + FT_UInt instance_index ); FT_LOCAL( FT_Error ) tt_face_vary_cvt( TT_Face face, @@ -167,16 +418,36 @@ FT_BEGIN_HEADER FT_Outline* outline, FT_UInt n_points ); + FT_LOCAL( FT_Error ) + tt_hadvance_adjust( TT_Face face, + FT_UInt gindex, + FT_Int *adelta ); + + FT_LOCAL( FT_Error ) + tt_vadvance_adjust( TT_Face face, + FT_UInt gindex, + FT_Int *adelta ); FT_LOCAL( void ) - tt_done_blend( FT_Memory memory, - GX_Blend blend ); + tt_apply_mvar( TT_Face face ); + + FT_LOCAL( FT_Error ) + tt_get_var_blend( TT_Face face, + FT_UInt *num_coords, + FT_Fixed* *coords, + FT_Fixed* *normalizedcoords, + FT_MM_Var* *mm_var ); + + FT_LOCAL( void ) + tt_done_blend( TT_Face face ); + +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ FT_END_HEADER -#endif /* __TTGXVAR_H__ */ +#endif /* TTGXVAR_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/truetype/ttinterp.c b/src/3rdparty/freetype/src/truetype/ttinterp.c index ae2a82adc5..da9b595aba 100644 --- a/src/3rdparty/freetype/src/truetype/ttinterp.c +++ b/src/3rdparty/freetype/src/truetype/ttinterp.c @@ -4,7 +4,7 @@ /* */ /* TrueType bytecode interpreter (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -25,11 +25,15 @@ #include FT_INTERNAL_CALC_H #include FT_TRIGONOMETRY_H #include FT_SYSTEM_H -#include FT_TRUETYPE_DRIVER_H +#include FT_DRIVER_H +#include FT_MULTIPLE_MASTERS_H #include "ttinterp.h" #include "tterrors.h" #include "ttsubpix.h" +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#include "ttgxvar.h" +#endif #ifdef TT_USE_BYTECODE_INTERPRETER @@ -45,25 +49,31 @@ #define FT_COMPONENT trace_ttinterp - /*************************************************************************/ - /* */ - /* In order to detect infinite loops in the code, we set up a counter */ - /* within the run loop. A single stroke of interpretation is now */ - /* limited to a maximum number of opcodes defined below. */ - /* */ -#define MAX_RUNNABLE_OPCODES 1000000L +#define NO_SUBPIXEL_HINTING \ + ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \ + TT_INTERPRETER_VERSION_35 ) - -#define SUBPIXEL_HINTING \ +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY +#define SUBPIXEL_HINTING_INFINALITY \ ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \ TT_INTERPRETER_VERSION_38 ) +#endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL +#define SUBPIXEL_HINTING_MINIMAL \ + ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \ + TT_INTERPRETER_VERSION_40 ) +#endif -#define PROJECT( v1, v2 ) \ - exc->func_project( exc, (v1)->x - (v2)->x, (v1)->y - (v2)->y ) +#define PROJECT( v1, v2 ) \ + exc->func_project( exc, \ + SUB_LONG( (v1)->x, (v2)->x ), \ + SUB_LONG( (v1)->y, (v2)->y ) ) -#define DUALPROJ( v1, v2 ) \ - exc->func_dualproj( exc, (v1)->x - (v2)->x, (v1)->y - (v2)->y ) +#define DUALPROJ( v1, v2 ) \ + exc->func_dualproj( exc, \ + SUB_LONG( (v1)->x, (v2)->x ), \ + SUB_LONG( (v1)->y, (v2)->y ) ) #define FAST_PROJECT( v ) \ exc->func_project( exc, (v)->x, (v)->y ) @@ -72,14 +82,6 @@ exc->func_dualproj( exc, (v)->x, (v)->y ) - /*************************************************************************/ - /* */ - /* Instruction dispatch function, as used by the interpreter. */ - /* */ - typedef void (*TInstruction_Function)( TT_ExecContext exc, - FT_Long* args ); - - /*************************************************************************/ /* */ /* Two simple bounds-checking macros. */ @@ -94,20 +96,6 @@ #undef FAILURE #define FAILURE 1 -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING -#define GUESS_VECTOR( V ) \ - do \ - { \ - if ( exc->face->unpatented_hinting ) \ - { \ - exc->GS.V.x = (FT_F2Dot14)( exc->GS.both_x_axis ? 0x4000 : 0 ); \ - exc->GS.V.y = (FT_F2Dot14)( exc->GS.both_x_axis ? 0 : 0x4000 ); \ - } \ - } while (0) -#else -#define GUESS_VECTOR( V ) do { } while (0) -#endif - /*************************************************************************/ /* */ @@ -145,7 +133,7 @@ coderange = &exec->codeRangeTable[range - 1]; - FT_ASSERT( coderange->base != NULL ); + FT_ASSERT( coderange->base ); /* NOTE: Because the last instruction of a program may be a CALL */ /* which will return to the first byte *after* the code */ @@ -309,8 +297,8 @@ exec->stackSize = 0; exec->glyphSize = 0; - exec->stack = NULL; - exec->glyphIns = NULL; + exec->stack = NULL; + exec->glyphIns = NULL; exec->face = NULL; exec->size = NULL; @@ -416,8 +404,9 @@ exec->maxIDefs = size->max_instruction_defs; exec->FDefs = size->function_defs; exec->IDefs = size->instruction_defs; + exec->pointSize = size->point_size; exec->tt_metrics = size->ttmetrics; - exec->metrics = size->metrics; + exec->metrics = *size->metrics; exec->maxFunc = size->max_func; exec->maxIns = size->max_ins; @@ -438,7 +427,7 @@ /* In case of multi-threading it can happen that the old size object */ /* no longer exists, thus we must clear all glyph zone references. */ - ft_memset( &exec->zp0, 0, sizeof ( exec->zp0 ) ); + FT_ZERO( &exec->zp0 ); exec->zp1 = exec->zp0; exec->zp2 = exec->zp0; } @@ -556,10 +545,6 @@ exec->GS.freeVector = exec->GS.projVector; exec->GS.dualVector = exec->GS.projVector; -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - exec->GS.both_x_axis = TRUE; -#endif - exec->GS.round_state = 1; exec->GS.loop = 1; @@ -586,10 +571,6 @@ { 0x4000, 0 }, { 0x4000, 0 }, -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - TRUE, -#endif - 1, 64, 1, TRUE, 68, 0, 0, 9, 3, 0, FALSE, 0, 1, 1, 1 @@ -709,17 +690,17 @@ /* IUP[0] */ PACK( 0, 0 ), /* IUP[1] */ PACK( 0, 0 ), - /* SHP[0] */ PACK( 0, 0 ), - /* SHP[1] */ PACK( 0, 0 ), + /* SHP[0] */ PACK( 0, 0 ), /* loops */ + /* SHP[1] */ PACK( 0, 0 ), /* loops */ /* SHC[0] */ PACK( 1, 0 ), /* SHC[1] */ PACK( 1, 0 ), /* SHZ[0] */ PACK( 1, 0 ), /* SHZ[1] */ PACK( 1, 0 ), - /* SHPIX */ PACK( 1, 0 ), - /* IP */ PACK( 0, 0 ), + /* SHPIX */ PACK( 1, 0 ), /* loops */ + /* IP */ PACK( 0, 0 ), /* loops */ /* MSIRP[0] */ PACK( 2, 0 ), /* MSIRP[1] */ PACK( 2, 0 ), - /* AlignRP */ PACK( 0, 0 ), + /* AlignRP */ PACK( 0, 0 ), /* loops */ /* RTDG */ PACK( 0, 0 ), /* MIAP[0] */ PACK( 2, 0 ), /* MIAP[1] */ PACK( 2, 0 ), @@ -792,7 +773,7 @@ /* SANGW */ PACK( 1, 0 ), /* AA */ PACK( 1, 0 ), - /* FlipPT */ PACK( 0, 0 ), + /* FlipPT */ PACK( 0, 0 ), /* loops */ /* FlipRgON */ PACK( 2, 0 ), /* FlipRgOFF */ PACK( 2, 0 ), /* INS_$83 */ PACK( 0, 0 ), @@ -810,8 +791,8 @@ /* INS_$8F */ PACK( 0, 0 ), /* INS_$90 */ PACK( 0, 0 ), - /* INS_$91 */ PACK( 0, 0 ), - /* INS_$92 */ PACK( 0, 0 ), + /* GETVAR */ PACK( 0, 0 ), /* will be handled specially */ + /* GETDATA */ PACK( 0, 1 ), /* INS_$93 */ PACK( 0, 0 ), /* INS_$94 */ PACK( 0, 0 ), /* INS_$95 */ PACK( 0, 0 ), @@ -1093,8 +1074,13 @@ "7 INS_$8F", "7 INS_$90", +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + "6 GETVAR", + "7 GETDATA", +#else "7 INS_$91", "7 INS_$92", +#endif "7 INS_$93", "7 INS_$94", "7 INS_$95", @@ -1479,34 +1465,22 @@ { if ( !exc->tt_metrics.ratio ) { -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( exc->face->unpatented_hinting ) - { - if ( exc->GS.both_x_axis ) - exc->tt_metrics.ratio = exc->tt_metrics.x_ratio; - else - exc->tt_metrics.ratio = exc->tt_metrics.y_ratio; - } + if ( exc->GS.projVector.y == 0 ) + exc->tt_metrics.ratio = exc->tt_metrics.x_ratio; + + else if ( exc->GS.projVector.x == 0 ) + exc->tt_metrics.ratio = exc->tt_metrics.y_ratio; + else -#endif { - if ( exc->GS.projVector.y == 0 ) - exc->tt_metrics.ratio = exc->tt_metrics.x_ratio; - - else if ( exc->GS.projVector.x == 0 ) - exc->tt_metrics.ratio = exc->tt_metrics.y_ratio; - - else - { - FT_F26Dot6 x, y; + FT_F26Dot6 x, y; - x = TT_MulFix14( exc->tt_metrics.x_ratio, - exc->GS.projVector.x ); - y = TT_MulFix14( exc->tt_metrics.y_ratio, - exc->GS.projVector.y ); - exc->tt_metrics.ratio = FT_Hypot( x, y ); - } + x = TT_MulFix14( exc->tt_metrics.x_ratio, + exc->GS.projVector.x ); + y = TT_MulFix14( exc->tt_metrics.y_ratio, + exc->GS.projVector.y ); + exc->tt_metrics.ratio = FT_Hypot( x, y ); } } return exc->tt_metrics.ratio; @@ -1604,7 +1578,7 @@ static FT_Short GetShortIns( TT_ExecContext exc ) { - /* Reading a byte stream so there is no endianess (DaveP) */ + /* Reading a byte stream so there is no endianness (DaveP) */ exc->IP += 2; return (FT_Short)( ( exc->code[exc->IP - 2] << 8 ) + exc->code[exc->IP - 1] ); @@ -1643,7 +1617,7 @@ range = &exc->codeRangeTable[aRange - 1]; - if ( range->base == NULL ) /* invalid coderange */ + if ( !range->base ) /* invalid coderange */ { exc->error = FT_THROW( Invalid_CodeRange ); return FAILURE; @@ -1685,6 +1659,10 @@ /* <InOut> */ /* zone :: The affected glyph zone. */ /* */ + /* <Note> */ + /* See `ttinterp.h' for details on backward compatibility mode. */ + /* `Touches' the point. */ + /* */ static void Direct_Move( TT_ExecContext exc, TT_GlyphZone zone, @@ -1694,20 +1672,38 @@ FT_F26Dot6 v; -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - FT_ASSERT( !exc->face->unpatented_hinting ); -#endif - v = exc->GS.freeVector.x; if ( v != 0 ) { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( !SUBPIXEL_HINTING || +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && ( !exc->ignore_x_mode || ( exc->sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) ) -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - zone->cur[point].x += FT_MulDiv( distance, v, exc->F_dot_P ); + zone->cur[point].x = ADD_LONG( zone->cur[point].x, + FT_MulDiv( distance, + v, + exc->F_dot_P ) ); + else +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* Exception to the post-IUP curfew: Allow the x component of */ + /* diagonal moves, but only post-IUP. DejaVu tries to adjust */ + /* diagonal stems like on `Z' and `z' post-IUP. */ + if ( SUBPIXEL_HINTING_MINIMAL && !exc->backward_compatibility ) + zone->cur[point].x = ADD_LONG( zone->cur[point].x, + FT_MulDiv( distance, + v, + exc->F_dot_P ) ); + else +#endif + + if ( NO_SUBPIXEL_HINTING ) + zone->cur[point].x = ADD_LONG( zone->cur[point].x, + FT_MulDiv( distance, + v, + exc->F_dot_P ) ); zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; } @@ -1716,7 +1712,16 @@ if ( v != 0 ) { - zone->cur[point].y += FT_MulDiv( distance, v, exc->F_dot_P ); +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( !( SUBPIXEL_HINTING_MINIMAL && + exc->backward_compatibility && + exc->iupx_called && + exc->iupy_called ) ) +#endif + zone->cur[point].y = ADD_LONG( zone->cur[point].y, + FT_MulDiv( distance, + v, + exc->F_dot_P ) ); zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; } @@ -1749,19 +1754,21 @@ FT_F26Dot6 v; -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - FT_ASSERT( !exc->face->unpatented_hinting ); -#endif - v = exc->GS.freeVector.x; if ( v != 0 ) - zone->org[point].x += FT_MulDiv( distance, v, exc->F_dot_P ); + zone->org[point].x = ADD_LONG( zone->org[point].x, + FT_MulDiv( distance, + v, + exc->F_dot_P ) ); v = exc->GS.freeVector.y; if ( v != 0 ) - zone->org[point].y += FT_MulDiv( distance, v, exc->F_dot_P ); + zone->org[point].y = ADD_LONG( zone->org[point].y, + FT_MulDiv( distance, + v, + exc->F_dot_P ) ); } @@ -1771,6 +1778,7 @@ /* */ /* The following versions are used whenever both vectors are both */ /* along one of the coordinate unit vectors, i.e. in 90% of the cases. */ + /* See `ttinterp.h' for details on backward compatibility mode. */ /* */ /*************************************************************************/ @@ -1781,13 +1789,20 @@ FT_UShort point, FT_F26Dot6 distance ) { - FT_UNUSED( exc ); +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && !exc->ignore_x_mode ) + zone->cur[point].x = ADD_LONG( zone->cur[point].x, distance ); + else +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( !SUBPIXEL_HINTING || - !exc->ignore_x_mode ) -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - zone->cur[point].x += distance; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( SUBPIXEL_HINTING_MINIMAL && !exc->backward_compatibility ) + zone->cur[point].x = ADD_LONG( zone->cur[point].x, distance ); + else +#endif + + if ( NO_SUBPIXEL_HINTING ) + zone->cur[point].x = ADD_LONG( zone->cur[point].x, distance ); zone->tags[point] |= FT_CURVE_TAG_TOUCH_X; } @@ -1801,8 +1816,14 @@ { FT_UNUSED( exc ); - zone->cur[point].y += distance; - zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( !( SUBPIXEL_HINTING_MINIMAL && + exc->backward_compatibility && + exc->iupx_called && exc->iupy_called ) ) +#endif + zone->cur[point].y = ADD_LONG( zone->cur[point].y, distance ); + + zone->tags[point] |= FT_CURVE_TAG_TOUCH_Y; } @@ -1824,7 +1845,7 @@ { FT_UNUSED( exc ); - zone->org[point].x += distance; + zone->org[point].x = ADD_LONG( zone->org[point].x, distance ); } @@ -1836,7 +1857,7 @@ { FT_UNUSED( exc ); - zone->org[point].y += distance; + zone->org[point].y = ADD_LONG( zone->org[point].y, distance ); } @@ -1874,13 +1895,13 @@ if ( distance >= 0 ) { - val = distance + compensation; + val = ADD_LONG( distance, compensation ); if ( val < 0 ) val = 0; } else { - val = distance - compensation; + val = SUB_LONG( distance, compensation ); if ( val > 0 ) val = 0; } @@ -1916,13 +1937,14 @@ if ( distance >= 0 ) { - val = FT_PIX_ROUND( distance + compensation ); + val = FT_PIX_ROUND_LONG( ADD_LONG( distance, compensation ) ); if ( val < 0 ) val = 0; } else { - val = -FT_PIX_ROUND( compensation - distance ); + val = NEG_LONG( FT_PIX_ROUND_LONG( SUB_LONG( compensation, + distance ) ) ); if ( val > 0 ) val = 0; } @@ -1959,13 +1981,16 @@ if ( distance >= 0 ) { - val = FT_PIX_FLOOR( distance + compensation ) + 32; + val = ADD_LONG( FT_PIX_FLOOR( ADD_LONG( distance, compensation ) ), + 32 ); if ( val < 0 ) val = 32; } else { - val = -( FT_PIX_FLOOR( compensation - distance ) + 32 ); + val = NEG_LONG( ADD_LONG( FT_PIX_FLOOR( SUB_LONG( compensation, + distance ) ), + 32 ) ); if ( val > 0 ) val = -32; } @@ -2002,13 +2027,13 @@ if ( distance >= 0 ) { - val = FT_PIX_FLOOR( distance + compensation ); + val = FT_PIX_FLOOR( ADD_LONG( distance, compensation ) ); if ( val < 0 ) val = 0; } else { - val = -FT_PIX_FLOOR( compensation - distance ); + val = NEG_LONG( FT_PIX_FLOOR( SUB_LONG( compensation, distance ) ) ); if ( val > 0 ) val = 0; } @@ -2045,13 +2070,14 @@ if ( distance >= 0 ) { - val = FT_PIX_CEIL( distance + compensation ); + val = FT_PIX_CEIL_LONG( ADD_LONG( distance, compensation ) ); if ( val < 0 ) val = 0; } else { - val = -FT_PIX_CEIL( compensation - distance ); + val = NEG_LONG( FT_PIX_CEIL_LONG( SUB_LONG( compensation, + distance ) ) ); if ( val > 0 ) val = 0; } @@ -2081,20 +2107,21 @@ FT_F26Dot6 distance, FT_F26Dot6 compensation ) { - FT_F26Dot6 val; + FT_F26Dot6 val; FT_UNUSED( exc ); if ( distance >= 0 ) { - val = FT_PAD_ROUND( distance + compensation, 32 ); + val = FT_PAD_ROUND_LONG( ADD_LONG( distance, compensation ), 32 ); if ( val < 0 ) val = 0; } else { - val = -FT_PAD_ROUND( compensation - distance, 32 ); + val = NEG_LONG( FT_PAD_ROUND_LONG( SUB_LONG( compensation, distance ), + 32 ) ); if ( val > 0 ) val = 0; } @@ -2120,7 +2147,7 @@ /* Rounded distance. */ /* */ /* <Note> */ - /* The TrueType specification says very few about the relationship */ + /* The TrueType specification says very little about the relationship */ /* between rounding and engine compensation. However, it seems from */ /* the description of super round that we should add the compensation */ /* before rounding. */ @@ -2135,17 +2162,19 @@ if ( distance >= 0 ) { - val = ( distance - exc->phase + exc->threshold + compensation ) & + val = ADD_LONG( distance, + exc->threshold - exc->phase + compensation ) & -exc->period; - val += exc->phase; + val = ADD_LONG( val, exc->phase ); if ( val < 0 ) val = exc->phase; } else { - val = -( ( exc->threshold - exc->phase - distance + compensation ) & - -exc->period ); - val -= exc->phase; + val = NEG_LONG( SUB_LONG( exc->threshold - exc->phase + compensation, + distance ) & + -exc->period ); + val = SUB_LONG( val, exc->phase ); if ( val > 0 ) val = -exc->phase; } @@ -2184,17 +2213,19 @@ if ( distance >= 0 ) { - val = ( ( distance - exc->phase + exc->threshold + compensation ) / + val = ( ADD_LONG( distance, + exc->threshold - exc->phase + compensation ) / exc->period ) * exc->period; - val += exc->phase; + val = ADD_LONG( val, exc->phase ); if ( val < 0 ) val = exc->phase; } else { - val = -( ( ( exc->threshold - exc->phase - distance + compensation ) / - exc->period ) * exc->period ); - val -= exc->phase; + val = NEG_LONG( ( SUB_LONG( exc->threshold - exc->phase + compensation, + distance ) / + exc->period ) * exc->period ); + val = SUB_LONG( val, exc->phase ); if ( val > 0 ) val = -exc->phase; } @@ -2345,10 +2376,6 @@ FT_Pos dx, FT_Pos dy ) { -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - FT_ASSERT( !exc->face->unpatented_hinting ); -#endif - return TT_DotFix14( dx, dy, exc->GS.projVector.x, exc->GS.projVector.y ); @@ -2450,51 +2477,6 @@ static void Compute_Funcs( TT_ExecContext exc ) { -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( exc->face->unpatented_hinting ) - { - /* If both vectors point rightwards along the x axis, set */ - /* `both-x-axis' true, otherwise set it false. The x values only */ - /* need be tested because the vector has been normalised to a unit */ - /* vector of length 0x4000 = unity. */ - exc->GS.both_x_axis = (FT_Bool)( exc->GS.projVector.x == 0x4000 && - exc->GS.freeVector.x == 0x4000 ); - - /* Throw away projection and freedom vector information */ - /* because the patents don't allow them to be stored. */ - /* The relevant US Patents are 5155805 and 5325479. */ - exc->GS.projVector.x = 0; - exc->GS.projVector.y = 0; - exc->GS.freeVector.x = 0; - exc->GS.freeVector.y = 0; - - if ( exc->GS.both_x_axis ) - { - exc->func_project = Project_x; - exc->func_move = Direct_Move_X; - exc->func_move_orig = Direct_Move_Orig_X; - } - else - { - exc->func_project = Project_y; - exc->func_move = Direct_Move_Y; - exc->func_move_orig = Direct_Move_Orig_Y; - } - - if ( exc->GS.dualVector.x == 0x4000 ) - exc->func_dualproj = Project_x; - else if ( exc->GS.dualVector.y == 0x4000 ) - exc->func_dualproj = Project_y; - else - exc->func_dualproj = Dual_Project; - - /* Force recalculation of cached aspect ratio */ - exc->tt_metrics.ratio = 0; - - return; - } -#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING */ - if ( exc->GS.freeVector.x == 0x4000 ) exc->F_dot_P = exc->GS.projVector.x; else if ( exc->GS.freeVector.y == 0x4000 ) @@ -2634,13 +2616,20 @@ Ins_MPS( TT_ExecContext exc, FT_Long* args ) { - /* Note: The point size should be irrelevant in a given font program; */ - /* we thus decide to return only the PPEM value. */ -#if 0 - args[0] = exc->metrics.pointSize; -#else - args[0] = exc->func_cur_ppem( exc ); -#endif + if ( NO_SUBPIXEL_HINTING ) + { + /* Microsoft's GDI bytecode interpreter always returns value 12; */ + /* we return the current PPEM value instead. */ + args[0] = exc->func_cur_ppem( exc ); + } + else + { + /* A possible practical application of the MPS instruction is to */ + /* implement optical scaling and similar features, which should be */ + /* based on perceptual attributes, thus independent of the */ + /* resolution. */ + args[0] = exc->pointSize; + } } @@ -2869,7 +2858,7 @@ static void Ins_ADD( FT_Long* args ) { - args[0] += args[1]; + args[0] = ADD_LONG( args[0], args[1] ); } @@ -2882,7 +2871,7 @@ static void Ins_SUB( FT_Long* args ) { - args[0] -= args[1]; + args[0] = SUB_LONG( args[0], args[1] ); } @@ -2925,7 +2914,8 @@ static void Ins_ABS( FT_Long* args ) { - args[0] = FT_ABS( args[0] ); + if ( args[0] < 0 ) + args[0] = NEG_LONG( args[0] ); } @@ -2933,12 +2923,12 @@ /* */ /* NEG[]: NEGate */ /* Opcode range: 0x65 */ - /* Stack: f26.6 --> f26.6 */ + /* Stack: f26.6 --> f26.6 */ /* */ static void Ins_NEG( FT_Long* args ) { - args[0] = -args[0]; + args[0] = NEG_LONG( args[0] ); } @@ -2964,7 +2954,7 @@ static void Ins_CEILING( FT_Long* args ) { - args[0] = FT_PIX_CEIL( args[0] ); + args[0] = FT_PIX_CEIL_LONG( args[0] ); } @@ -2978,8 +2968,6 @@ Ins_RS( TT_ExecContext exc, FT_Long* args ) { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - FT_ULong I = (FT_ULong)args[0]; @@ -2992,9 +2980,10 @@ } else { +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* subpixel hinting - avoid Typeman Dstroke and */ /* IStroke and Vacuform rounds */ - if ( SUBPIXEL_HINTING && + if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode && ( ( I == 24 && ( exc->face->sph_found_func_flags & @@ -3009,25 +2998,9 @@ exc->iup_called ) ) ) args[0] = 0; else +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ args[0] = exc->storage[I]; } - -#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - FT_ULong I = (FT_ULong)args[0]; - - - if ( BOUNDSL( I, exc->storeSize ) ) - { - if ( exc->pedantic_hinting ) - ARRAY_BOUND_ERROR; - else - args[0] = 0; - } - else - args[0] = exc->storage[I]; - -#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ } @@ -3190,7 +3163,7 @@ /*************************************************************************/ /* */ /* MAX[]: MAXimum */ - /* Opcode range: 0x68 */ + /* Opcode range: 0x8B */ /* Stack: int32? int32? --> int32 */ /* */ static void @@ -3204,7 +3177,7 @@ /*************************************************************************/ /* */ /* MIN[]: MINimum */ - /* Opcode range: 0x69 */ + /* Opcode range: 0x8C */ /* Stack: int32? int32? --> int32 */ /* */ static void @@ -3316,7 +3289,10 @@ if ( args[0] < 0 ) exc->error = FT_THROW( Bad_Argument ); else - exc->GS.loop = args[0]; + { + /* we heuristically limit the number of loops to 16 bits */ + exc->GS.loop = args[0] > 0xFFFFL ? 0xFFFFL : args[0]; + } } @@ -3448,13 +3424,27 @@ FT_Long* args ) { if ( args[0] == 0 && exc->args == 0 ) + { exc->error = FT_THROW( Bad_Argument ); + return; + } + exc->IP += args[0]; if ( exc->IP < 0 || ( exc->callTop > 0 && exc->IP > exc->callStack[exc->callTop - 1].Def->end ) ) + { exc->error = FT_THROW( Bad_Argument ); + return; + } + exc->step_ins = FALSE; + + if ( args[0] < 0 ) + { + if ( ++exc->neg_jump_counter > exc->neg_jump_counter_max ) + exc->error = FT_THROW( Execution_Too_Long ); + } } @@ -3509,7 +3499,7 @@ TT_DefRecord* rec; TT_DefRecord* limit; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* arguments to opcodes are skipped by `SKIP_Code' */ FT_Byte opcode_pattern[9][12] = { /* #0 inline delta function 1 */ @@ -3607,9 +3597,16 @@ FT_UShort opcode_pointer[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; FT_UShort opcode_size[9] = { 12, 8, 8, 6, 7, 4, 5, 4, 2 }; FT_UShort i; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + /* FDEF is only allowed in `prep' or `fpgm' */ + if ( exc->curRange == tt_coderange_glyph ) + { + exc->error = FT_THROW( DEF_In_Glyf_Bytecode ); + return; + } + /* some font programs are broken enough to redefine functions! */ /* We will then parse the current table. */ @@ -3652,7 +3649,7 @@ if ( n > exc->maxFunc ) exc->maxFunc = (FT_UInt16)n; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* We don't know for sure these are typeman functions, */ /* however they are only active when RS 22 is called */ if ( n >= 64 && n <= 66 ) @@ -3665,9 +3662,9 @@ while ( SkipCode( exc ) == SUCCESS ) { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING ) + if ( SUBPIXEL_HINTING_INFINALITY ) { for ( i = 0; i < opcode_patterns; i++ ) { @@ -3774,7 +3771,7 @@ ( exc->face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ); } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ switch ( exc->opcode ) { @@ -3803,9 +3800,9 @@ TT_CallRec* pRec; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY exc->sph_in_func_flags = 0x0000; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ if ( exc->callTop <= 0 ) /* We encountered an ENDF without a call */ { @@ -3891,8 +3888,8 @@ if ( !def->active ) goto Fail; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode && ( ( exc->iup_called && ( exc->sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) || @@ -3900,7 +3897,7 @@ goto Fail; else exc->sph_in_func_flags = def->sph_fdef_flags; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ /* check the call stack */ if ( exc->callTop >= exc->callSize ) @@ -3979,14 +3976,14 @@ if ( !def->active ) goto Fail; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode && ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) ) goto Fail; else exc->sph_in_func_flags = def->sph_fdef_flags; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ /* check stack */ if ( exc->callTop >= exc->callSize ) @@ -4009,6 +4006,10 @@ Ins_Goto_CodeRange( exc, def->range, def->start ); exc->step_ins = FALSE; + + exc->loopcall_counter += (FT_ULong)args[0]; + if ( exc->loopcall_counter > exc->loopcall_counter_max ) + exc->error = FT_THROW( Execution_Too_Long ); } return; @@ -4032,6 +4033,13 @@ TT_DefRecord* limit; + /* we enable IDEF only in `prep' or `fpgm' */ + if ( exc->curRange == tt_coderange_glyph ) + { + exc->error = FT_THROW( DEF_In_Glyf_Bytecode ); + return; + } + /* First of all, look for the same function in our table */ def = exc->IDefs; @@ -4079,6 +4087,7 @@ exc->error = FT_THROW( Nested_DEFS ); return; case 0x2D: /* ENDF */ + def->end = exc->IP; return; } } @@ -4238,8 +4247,8 @@ p1 = exc->zp1.cur + aIdx2; p2 = exc->zp2.cur + aIdx1; - A = p1->x - p2->x; - B = p1->y - p2->y; + A = SUB_LONG( p1->x, p2->x ); + B = SUB_LONG( p1->y, p2->y ); /* If p1 == p2, SPvTL and SFvTL behave the same as */ /* SPvTCA[X] and SFvTCA[X], respectively. */ @@ -4254,9 +4263,9 @@ if ( ( opcode & 1 ) != 0 ) { - C = B; /* counter clockwise rotation */ - B = A; - A = -C; + C = B; /* counter clockwise rotation */ + B = A; + A = NEG_LONG( C ); } Normalize( A, B, Vec ); @@ -4298,16 +4307,12 @@ exc->GS.dualVector.x = AA; exc->GS.dualVector.y = BB; } - else - GUESS_VECTOR( projVector ); if ( ( opcode & 2 ) == 0 ) { exc->GS.freeVector.x = AA; exc->GS.freeVector.y = BB; } - else - GUESS_VECTOR( freeVector ); Compute_Funcs( exc ); } @@ -4329,7 +4334,6 @@ &exc->GS.projVector ) == SUCCESS ) { exc->GS.dualVector = exc->GS.projVector; - GUESS_VECTOR( freeVector ); Compute_Funcs( exc ); } } @@ -4350,7 +4354,6 @@ (FT_UShort)args[0], &exc->GS.freeVector ) == SUCCESS ) { - GUESS_VECTOR( projVector ); Compute_Funcs( exc ); } } @@ -4365,7 +4368,6 @@ static void Ins_SFVTPV( TT_ExecContext exc ) { - GUESS_VECTOR( projVector ); exc->GS.freeVector = exc->GS.projVector; Compute_Funcs( exc ); } @@ -4394,7 +4396,6 @@ Normalize( X, Y, &exc->GS.projVector ); exc->GS.dualVector = exc->GS.projVector; - GUESS_VECTOR( freeVector ); Compute_Funcs( exc ); } @@ -4420,7 +4421,6 @@ X = S; Normalize( X, Y, &exc->GS.freeVector ); - GUESS_VECTOR( projVector ); Compute_Funcs( exc ); } @@ -4435,21 +4435,8 @@ Ins_GPV( TT_ExecContext exc, FT_Long* args ) { -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( exc->face->unpatented_hinting ) - { - args[0] = exc->GS.both_x_axis ? 0x4000 : 0; - args[1] = exc->GS.both_x_axis ? 0 : 0x4000; - } - else - { - args[0] = exc->GS.projVector.x; - args[1] = exc->GS.projVector.y; - } -#else args[0] = exc->GS.projVector.x; args[1] = exc->GS.projVector.y; -#endif } @@ -4463,21 +4450,8 @@ Ins_GFV( TT_ExecContext exc, FT_Long* args ) { -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( exc->face->unpatented_hinting ) - { - args[0] = exc->GS.both_x_axis ? 0x4000 : 0; - args[1] = exc->GS.both_x_axis ? 0 : 0x4000; - } - else - { - args[0] = exc->GS.freeVector.x; - args[1] = exc->GS.freeVector.y; - } -#else args[0] = exc->GS.freeVector.x; args[1] = exc->GS.freeVector.y; -#endif } @@ -4597,7 +4571,7 @@ /* */ /* FLIPOFF[]: Set auto-FLIP to OFF */ /* Opcode range: 0x4E */ - /* Stack: --> */ + /* Stack: --> */ /* */ static void Ins_FLIPOFF( TT_ExecContext exc ) @@ -4832,7 +4806,7 @@ K = FAST_PROJECT( &exc->zp2.cur[L] ); - exc->func_move( exc, &exc->zp2, L, args[1] - K ); + exc->func_move( exc, &exc->zp2, L, SUB_LONG( args[1], K ) ); /* UNDOCUMENTED! The MS rasterizer does that with */ /* twilight points (confirmed by Greg Hitchcock) */ @@ -4916,13 +4890,13 @@ } } -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */ - if ( SUBPIXEL_HINTING && - exc->ignore_x_mode && - FT_ABS( D ) == 64 ) + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + FT_ABS( D ) == 64 ) D += 1; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ args[0] = D; } @@ -4956,12 +4930,12 @@ } { - FT_Vector* v1 = exc->zp1.org + p2; - FT_Vector* v2 = exc->zp2.org + p1; + FT_Vector* v1 = exc->zp1.org + p2; + FT_Vector* v2 = exc->zp2.org + p1; - A = v1->x - v2->x; - B = v1->y - v2->y; + A = SUB_LONG( v1->x, v2->x ); + B = SUB_LONG( v1->y, v2->y ); /* If v1 == v2, SDPvTL behaves the same as */ /* SVTCA[X], respectively. */ @@ -4977,9 +4951,9 @@ if ( ( opcode & 1 ) != 0 ) { - C = B; /* counter clockwise rotation */ - B = A; - A = -C; + C = B; /* counter clockwise rotation */ + B = A; + A = NEG_LONG( C ); } Normalize( A, B, &exc->GS.dualVector ); @@ -4989,8 +4963,8 @@ FT_Vector* v2 = exc->zp2.cur + p1; - A = v1->x - v2->x; - B = v1->y - v2->y; + A = SUB_LONG( v1->x, v2->x ); + B = SUB_LONG( v1->y, v2->y ); if ( A == 0 && B == 0 ) { @@ -5001,13 +4975,12 @@ if ( ( opcode & 1 ) != 0 ) { - C = B; /* counter clockwise rotation */ - B = A; - A = -C; + C = B; /* counter clockwise rotation */ + B = A; + A = NEG_LONG( C ); } Normalize( A, B, &exc->GS.projVector ); - GUESS_VECTOR( freeVector ); Compute_Funcs( exc ); } @@ -5179,12 +5152,23 @@ exc->GS.instruct_control &= ~(FT_Byte)Kf; exc->GS.instruct_control |= (FT_Byte)L; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - /* INSTCTRL modifying flag 3 also has an effect */ - /* outside of the CVT program */ if ( K == 3 ) - exc->ignore_x_mode = FT_BOOL( L == 4 ); + { +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + /* INSTCTRL modifying flag 3 also has an effect */ + /* outside of the CVT program */ + if ( SUBPIXEL_HINTING_INFINALITY ) + exc->ignore_x_mode = FT_BOOL( L == 4 ); #endif + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* Native ClearType fonts sign a waiver that turns off all backward */ + /* compatibility hacks and lets them program points to the grid like */ + /* it's 1996. They might sign a waiver for just one glyph, though. */ + if ( SUBPIXEL_HINTING_MINIMAL ) + exc->backward_compatibility = !FT_BOOL( L == 4 ); +#endif + } } @@ -5239,14 +5223,14 @@ /* */ /* SCANTYPE[]: SCAN TYPE */ /* Opcode range: 0x8D */ - /* Stack: uint32? --> */ + /* Stack: uint16 --> */ /* */ static void Ins_SCANTYPE( TT_ExecContext exc, FT_Long* args ) { if ( args[0] >= 0 ) - exc->GS.scan_type = (FT_Int)args[0]; + exc->GS.scan_type = (FT_Int)args[0] & 0xFFFF; } @@ -5269,6 +5253,15 @@ FT_UShort point; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* See `ttinterp.h' for details on backward compatibility mode. */ + if ( SUBPIXEL_HINTING_MINIMAL && + exc->backward_compatibility && + exc->iupx_called && + exc->iupy_called ) + goto Fail; +#endif + if ( exc->top < exc->GS.loop ) { if ( exc->pedantic_hinting ) @@ -5315,6 +5308,15 @@ FT_UShort I, K, L; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* See `ttinterp.h' for details on backward compatibility mode. */ + if ( SUBPIXEL_HINTING_MINIMAL && + exc->backward_compatibility && + exc->iupx_called && + exc->iupy_called ) + return; +#endif + K = (FT_UShort)args[1]; L = (FT_UShort)args[0]; @@ -5344,6 +5346,15 @@ FT_UShort I, K, L; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* See `ttinterp.h' for details on backward compatibility mode. */ + if ( SUBPIXEL_HINTING_MINIMAL && + exc->backward_compatibility && + exc->iupx_called && + exc->iupy_called ) + return; +#endif + K = (FT_UShort)args[1]; L = (FT_UShort)args[0]; @@ -5396,31 +5407,14 @@ d = PROJECT( zp.cur + p, zp.org + p ); -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( exc->face->unpatented_hinting ) - { - if ( exc->GS.both_x_axis ) - { - *x = d; - *y = 0; - } - else - { - *x = 0; - *y = d; - } - } - else -#endif - { - *x = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.x, exc->F_dot_P ); - *y = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.y, exc->F_dot_P ); - } + *x = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.x, exc->F_dot_P ); + *y = FT_MulDiv( d, (FT_Long)exc->GS.freeVector.y, exc->F_dot_P ); return SUCCESS; } + /* See `ttinterp.h' for details on backward compatibility mode. */ static void Move_Zp2_Point( TT_ExecContext exc, FT_UShort point, @@ -5428,35 +5422,28 @@ FT_F26Dot6 dy, FT_Bool touch ) { -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( exc->face->unpatented_hinting ) - { - if ( exc->GS.both_x_axis ) - { - exc->zp2.cur[point].x += dx; - if ( touch ) - exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; - } - else - { - exc->zp2.cur[point].y += dy; - if ( touch ) - exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; - } - return; - } -#endif - if ( exc->GS.freeVector.x != 0 ) { - exc->zp2.cur[point].x += dx; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( !( SUBPIXEL_HINTING_MINIMAL && + exc->backward_compatibility ) ) +#endif + exc->zp2.cur[point].x = ADD_LONG( exc->zp2.cur[point].x, dx ); + if ( touch ) exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_X; } if ( exc->GS.freeVector.y != 0 ) { - exc->zp2.cur[point].y += dy; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( !( SUBPIXEL_HINTING_MINIMAL && + exc->backward_compatibility && + exc->iupx_called && + exc->iupy_called ) ) +#endif + exc->zp2.cur[point].y = ADD_LONG( exc->zp2.cur[point].y, dy ); + if ( touch ) exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_Y; } @@ -5503,13 +5490,12 @@ } } else -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* doesn't follow Cleartype spec but produces better result */ - if ( SUBPIXEL_HINTING && - exc->ignore_x_mode ) + if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode ) Move_Zp2_Point( exc, point, 0, dy, TRUE ); else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ Move_Zp2_Point( exc, point, dx, dy, TRUE ); exc->GS.loop--; @@ -5637,9 +5623,15 @@ { FT_F26Dot6 dx, dy; FT_UShort point; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY FT_Int B1, B2; #endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + FT_Bool in_twilight = FT_BOOL( exc->GS.gep0 == 0 || + exc->GS.gep1 == 0 || + exc->GS.gep2 == 0 ); +#endif + if ( exc->top < exc->GS.loop + 1 ) @@ -5649,26 +5641,8 @@ goto Fail; } -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - if ( exc->face->unpatented_hinting ) - { - if ( exc->GS.both_x_axis ) - { - dx = (FT_UInt32)args[0]; - dy = 0; - } - else - { - dx = 0; - dy = (FT_UInt32)args[0]; - } - } - else -#endif - { - dx = TT_MulFix14( args[0], exc->GS.freeVector.x ); - dy = TT_MulFix14( args[0], exc->GS.freeVector.y ); - } + dx = TT_MulFix14( args[0], exc->GS.freeVector.x ); + dy = TT_MulFix14( args[0], exc->GS.freeVector.y ); while ( exc->GS.loop > 0 ) { @@ -5685,7 +5659,8 @@ } } else -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY ) { /* If not using ignore_x_mode rendering, allow ZP2 move. */ /* If inline deltas aren't allowed, skip ZP2 move. */ @@ -5695,8 +5670,7 @@ /* - the glyph is specifically set to allow SHPIX moves */ /* - the move is on a previously Y-touched point */ - if ( SUBPIXEL_HINTING && - exc->ignore_x_mode ) + if ( exc->ignore_x_mode ) { /* save point for later comparison */ if ( exc->GS.freeVector.y != 0 ) @@ -5719,7 +5693,11 @@ ( B1 & 63 ) != 0 && ( B2 & 63 ) != 0 && B1 != B2 ) - Move_Zp2_Point( exc, point, -dx, -dy, TRUE ); + Move_Zp2_Point( exc, + point, + NEG_LONG( dx ), + NEG_LONG( dy ), + TRUE ); } } else if ( exc->face->sph_compatibility_mode ) @@ -5751,7 +5729,7 @@ if ( ( B1 & 63 ) == 0 && ( B2 & 63 ) != 0 && B1 != B2 ) - Move_Zp2_Point( exc, point, 0, -dy, TRUE ); + Move_Zp2_Point( exc, point, 0, NEG_LONG( dy ), TRUE ); } } else if ( exc->sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL ) @@ -5760,15 +5738,30 @@ else Move_Zp2_Point( exc, point, dx, dy, TRUE ); } + else +#endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + if ( SUBPIXEL_HINTING_MINIMAL && + exc->backward_compatibility ) + { + /* Special case: allow SHPIX to move points in the twilight zone. */ + /* Otherwise, treat SHPIX the same as DELTAP. Unbreaks various */ + /* fonts such as older versions of Rokkitt and DTL Argo T Light */ + /* that would glitch severely after calling ALIGNRP after a */ + /* blocked SHPIX. */ + if ( in_twilight || + ( !( exc->iupx_called && exc->iupy_called ) && + ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) || + ( exc->zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y ) ) ) ) + Move_Zp2_Point( exc, point, 0, dy, TRUE ); + } + else +#endif + Move_Zp2_Point( exc, point, dx, dy, TRUE ); +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY Skip: - -#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - Move_Zp2_Point( exc, point, dx, dy, TRUE ); - -#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - +#endif exc->GS.loop--; } @@ -5788,14 +5781,14 @@ Ins_MSIRP( TT_ExecContext exc, FT_Long* args ) { - FT_UShort point; + FT_UShort point = 0; FT_F26Dot6 distance; - -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - FT_F26Dot6 control_value_cutin = 0; /* pacify compiler */ +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + FT_F26Dot6 control_value_cutin = 0; + FT_F26Dot6 delta; - if ( SUBPIXEL_HINTING ) + if ( SUBPIXEL_HINTING_INFINALITY ) { control_value_cutin = exc->GS.control_value_cutin; @@ -5804,8 +5797,7 @@ !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) control_value_cutin = 0; } - -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ point = (FT_UShort)args[0]; @@ -5828,16 +5820,23 @@ distance = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - /* subpixel hinting - make MSIRP respect CVT cut-in; */ - if ( SUBPIXEL_HINTING && - exc->ignore_x_mode && - exc->GS.freeVector.x != 0 && - FT_ABS( distance - args[1] ) >= control_value_cutin ) - distance = args[1]; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + delta = SUB_LONG( distance, args[1] ); + if ( delta < 0 ) + delta = NEG_LONG( delta ); - exc->func_move( exc, &exc->zp1, point, args[1] - distance ); + /* subpixel hinting - make MSIRP respect CVT cut-in; */ + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.freeVector.x != 0 && + delta >= control_value_cutin ) + distance = args[1]; +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + + exc->func_move( exc, + &exc->zp1, + point, + SUB_LONG( args[1], distance ) ); exc->GS.rp1 = exc->GS.rp0; exc->GS.rp2 = point; @@ -5874,20 +5873,22 @@ if ( ( exc->opcode & 1 ) != 0 ) { cur_dist = FAST_PROJECT( &exc->zp0.cur[point] ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - exc->ignore_x_mode && - exc->GS.freeVector.x != 0 ) - distance = Round_None( - exc, - cur_dist, - exc->tt_metrics.compensations[0] ) - cur_dist; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.freeVector.x != 0 ) + distance = SUB_LONG( + Round_None( exc, + cur_dist, + exc->tt_metrics.compensations[0] ), + cur_dist ); else #endif - distance = exc->func_round( - exc, - cur_dist, - exc->tt_metrics.compensations[0] ) - cur_dist; + distance = SUB_LONG( + exc->func_round( exc, + cur_dist, + exc->tt_metrics.compensations[0] ), + cur_dist ); } else distance = 0; @@ -5920,14 +5921,14 @@ cvtEntry = (FT_ULong)args[1]; point = (FT_UShort)args[0]; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode && exc->GS.freeVector.x != 0 && exc->GS.freeVector.y == 0 && !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) control_value_cutin = 0; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ if ( BOUNDS( point, exc->zp0.n_points ) || BOUNDSL( cvtEntry, exc->cvtSize ) ) @@ -5961,39 +5962,46 @@ if ( exc->GS.gep0 == 0 ) /* If in twilight zone */ { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* Only adjust if not in sph_compatibility_mode or ignore_x_mode. */ /* Determined via experimentation and may be incorrect... */ - if ( !SUBPIXEL_HINTING || - ( !exc->ignore_x_mode || - !exc->face->sph_compatibility_mode ) ) -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ + if ( !( SUBPIXEL_HINTING_INFINALITY && + ( exc->ignore_x_mode && + exc->face->sph_compatibility_mode ) ) ) +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ exc->zp0.org[point].x = TT_MulFix14( distance, exc->GS.freeVector.x ); exc->zp0.org[point].y = TT_MulFix14( distance, exc->GS.freeVector.y ), exc->zp0.cur[point] = exc->zp0.org[point]; } -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode && ( exc->sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) && distance > 0 && exc->GS.freeVector.y != 0 ) distance = 0; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ org_dist = FAST_PROJECT( &exc->zp0.cur[point] ); if ( ( exc->opcode & 1 ) != 0 ) /* rounding and control cut-in flag */ { - if ( FT_ABS( distance - org_dist ) > control_value_cutin ) + FT_F26Dot6 delta; + + + delta = SUB_LONG( distance, org_dist ); + if ( delta < 0 ) + delta = NEG_LONG( delta ); + + if ( delta > control_value_cutin ) distance = org_dist; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - exc->ignore_x_mode && - exc->GS.freeVector.x != 0 ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.freeVector.x != 0 ) distance = Round_None( exc, distance, exc->tt_metrics.compensations[0] ); @@ -6004,7 +6012,7 @@ exc->tt_metrics.compensations[0] ); } - exc->func_move( exc, &exc->zp0, point, distance - org_dist ); + exc->func_move( exc, &exc->zp0, point, SUB_LONG( distance, org_dist ) ); Fail: exc->GS.rp0 = point; @@ -6022,19 +6030,19 @@ Ins_MDRP( TT_ExecContext exc, FT_Long* args ) { - FT_UShort point; + FT_UShort point = 0; FT_F26Dot6 org_dist, distance, minimum_distance; minimum_distance = exc->GS.minimum_distance; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode && exc->GS.freeVector.x != 0 && !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) minimum_distance = 0; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ point = (FT_UShort)args[0]; @@ -6076,8 +6084,10 @@ FT_Vector vec; - vec.x = FT_MulFix( vec1->x - vec2->x, exc->metrics.x_scale ); - vec.y = FT_MulFix( vec1->y - vec2->y, exc->metrics.y_scale ); + vec.x = FT_MulFix( SUB_LONG( vec1->x, vec2->x ), + exc->metrics.x_scale ); + vec.y = FT_MulFix( SUB_LONG( vec1->y, vec2->y ), + exc->metrics.y_scale ); org_dist = FAST_DUALPROJ( &vec ); } @@ -6085,8 +6095,12 @@ /* single width cut-in test */ - if ( FT_ABS( org_dist - exc->GS.single_width_value ) < - exc->GS.single_width_cutin ) + /* |org_dist - single_width_value| < single_width_cutin */ + if ( exc->GS.single_width_cutin > 0 && + org_dist < exc->GS.single_width_value + + exc->GS.single_width_cutin && + org_dist > exc->GS.single_width_value - + exc->GS.single_width_cutin ) { if ( org_dist >= 0 ) org_dist = exc->GS.single_width_value; @@ -6098,10 +6112,10 @@ if ( ( exc->opcode & 4 ) != 0 ) { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - exc->ignore_x_mode && - exc->GS.freeVector.x != 0 ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode && + exc->GS.freeVector.x != 0 ) distance = Round_None( exc, org_dist, @@ -6130,8 +6144,8 @@ } else { - if ( distance > -minimum_distance ) - distance = -minimum_distance; + if ( distance > NEG_LONG( minimum_distance ) ) + distance = NEG_LONG( minimum_distance ); } } @@ -6139,7 +6153,7 @@ org_dist = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 ); - exc->func_move( exc, &exc->zp1, point, distance - org_dist ); + exc->func_move( exc, &exc->zp1, point, SUB_LONG( distance, org_dist ) ); Fail: exc->GS.rp1 = exc->GS.rp0; @@ -6169,25 +6183,25 @@ org_dist, control_value_cutin, minimum_distance; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY FT_Int B1 = 0; /* pacify compiler */ FT_Int B2 = 0; FT_Bool reverse_move = FALSE; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ minimum_distance = exc->GS.minimum_distance; control_value_cutin = exc->GS.control_value_cutin; point = (FT_UShort)args[0]; - cvtEntry = (FT_ULong)( args[1] + 1 ); + cvtEntry = (FT_ULong)( ADD_LONG( args[1], 1 ) ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode && exc->GS.freeVector.x != 0 && !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) ) control_value_cutin = minimum_distance = 0; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */ @@ -6240,8 +6254,8 @@ cvt_dist = -cvt_dist; } -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode && exc->GS.freeVector.y != 0 && ( exc->sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) ) @@ -6251,7 +6265,7 @@ else if ( cur_dist > 64 && cur_dist < 84 ) cvt_dist += 32; } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ /* control value cut-in and round */ @@ -6262,6 +6276,9 @@ if ( exc->GS.gep0 == exc->GS.gep1 ) { + FT_F26Dot6 delta; + + /* XXX: According to Greg Hitchcock, the following wording is */ /* the right one: */ /* */ @@ -6274,7 +6291,11 @@ /* `ttinst2.doc', version 1.66, is thus incorrect since */ /* it implies `>=' instead of `>'. */ - if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin ) + delta = SUB_LONG( cvt_dist, org_dist ); + if ( delta < 0 ) + delta = NEG_LONG( delta ); + + if ( delta > control_value_cutin ) cvt_dist = org_dist; } @@ -6286,16 +6307,23 @@ else { -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /* do cvt cut-in always in MIRP for sph */ - if ( SUBPIXEL_HINTING && + if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode && exc->GS.gep0 == exc->GS.gep1 ) { - if ( FT_ABS( cvt_dist - org_dist ) > control_value_cutin ) + FT_F26Dot6 delta; + + + delta = SUB_LONG( cvt_dist, org_dist ); + if ( delta < 0 ) + delta = NEG_LONG( delta ); + + if ( delta > control_value_cutin ) cvt_dist = org_dist; } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ distance = Round_None( exc, @@ -6314,13 +6342,13 @@ } else { - if ( distance > -minimum_distance ) - distance = -minimum_distance; + if ( distance > NEG_LONG( minimum_distance ) ) + distance = NEG_LONG( minimum_distance ); } } -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY ) { B1 = exc->zp1.cur[point].y; @@ -6337,12 +6365,15 @@ ( exc->sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) ) distance += 64; } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - exc->func_move( exc, &exc->zp1, point, distance - cur_dist ); + exc->func_move( exc, + &exc->zp1, + point, + SUB_LONG( distance, cur_dist ) ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY ) { B2 = exc->zp1.cur[point].y; @@ -6363,10 +6394,13 @@ } if ( reverse_move ) - exc->func_move( exc, &exc->zp1, point, -( distance - cur_dist ) ); + exc->func_move( exc, + &exc->zp1, + point, + SUB_LONG( cur_dist, distance ) ); } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ Fail: exc->GS.rp1 = exc->GS.rp0; @@ -6391,8 +6425,8 @@ FT_F26Dot6 distance; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode && exc->iup_called && ( exc->sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) ) @@ -6400,7 +6434,7 @@ exc->error = FT_THROW( Invalid_Reference ); goto Fail; } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ if ( exc->top < exc->GS.loop || BOUNDS( exc->GS.rp0, exc->zp0.n_points ) ) @@ -6429,7 +6463,7 @@ distance = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 ); - exc->func_move( exc, &exc->zp1, point, -distance ); + exc->func_move( exc, &exc->zp1, point, NEG_LONG( distance ) ); } exc->GS.loop--; @@ -6486,19 +6520,19 @@ /* Cramer's rule */ - dbx = exc->zp0.cur[b1].x - exc->zp0.cur[b0].x; - dby = exc->zp0.cur[b1].y - exc->zp0.cur[b0].y; + dbx = SUB_LONG( exc->zp0.cur[b1].x, exc->zp0.cur[b0].x ); + dby = SUB_LONG( exc->zp0.cur[b1].y, exc->zp0.cur[b0].y ); - dax = exc->zp1.cur[a1].x - exc->zp1.cur[a0].x; - day = exc->zp1.cur[a1].y - exc->zp1.cur[a0].y; + dax = SUB_LONG( exc->zp1.cur[a1].x, exc->zp1.cur[a0].x ); + day = SUB_LONG( exc->zp1.cur[a1].y, exc->zp1.cur[a0].y ); - dx = exc->zp0.cur[b0].x - exc->zp1.cur[a0].x; - dy = exc->zp0.cur[b0].y - exc->zp1.cur[a0].y; + dx = SUB_LONG( exc->zp0.cur[b0].x, exc->zp1.cur[a0].x ); + dy = SUB_LONG( exc->zp0.cur[b0].y, exc->zp1.cur[a0].y ); - discriminant = FT_MulDiv( dax, -dby, 0x40 ) + - FT_MulDiv( day, dbx, 0x40 ); - dotproduct = FT_MulDiv( dax, dbx, 0x40 ) + - FT_MulDiv( day, dby, 0x40 ); + discriminant = ADD_LONG( FT_MulDiv( dax, NEG_LONG( dby ), 0x40 ), + FT_MulDiv( day, dbx, 0x40 ) ); + dotproduct = ADD_LONG( FT_MulDiv( dax, dbx, 0x40 ), + FT_MulDiv( day, dby, 0x40 ) ); /* The discriminant above is actually a cross product of vectors */ /* da and db. Together with the dot product, they can be used as */ @@ -6508,28 +6542,29 @@ /* discriminant = |da||db|sin(angle) . */ /* We use these equations to reject grazing intersections by */ /* thresholding abs(tan(angle)) at 1/19, corresponding to 3 degrees. */ - if ( 19 * FT_ABS( discriminant ) > FT_ABS( dotproduct ) ) + if ( MUL_LONG( 19, FT_ABS( discriminant ) ) > FT_ABS( dotproduct ) ) { - val = FT_MulDiv( dx, -dby, 0x40 ) + FT_MulDiv( dy, dbx, 0x40 ); + val = ADD_LONG( FT_MulDiv( dx, NEG_LONG( dby ), 0x40 ), + FT_MulDiv( dy, dbx, 0x40 ) ); R.x = FT_MulDiv( val, dax, discriminant ); R.y = FT_MulDiv( val, day, discriminant ); - exc->zp2.cur[point].x = exc->zp1.cur[a0].x + R.x; - exc->zp2.cur[point].y = exc->zp1.cur[a0].y + R.y; + /* XXX: Block in backward_compatibility and/or post-IUP? */ + exc->zp2.cur[point].x = ADD_LONG( exc->zp1.cur[a0].x, R.x ); + exc->zp2.cur[point].y = ADD_LONG( exc->zp1.cur[a0].y, R.y ); } else { /* else, take the middle of the middles of A and B */ - exc->zp2.cur[point].x = ( exc->zp1.cur[a0].x + - exc->zp1.cur[a1].x + - exc->zp0.cur[b0].x + - exc->zp0.cur[b1].x ) / 4; - exc->zp2.cur[point].y = ( exc->zp1.cur[a0].y + - exc->zp1.cur[a1].y + - exc->zp0.cur[b0].y + - exc->zp0.cur[b1].y ) / 4; + /* XXX: Block in backward_compatibility and/or post-IUP? */ + exc->zp2.cur[point].x = + ADD_LONG( ADD_LONG( exc->zp1.cur[a0].x, exc->zp1.cur[a1].x ), + ADD_LONG( exc->zp0.cur[b0].x, exc->zp0.cur[b1].x ) ) / 4; + exc->zp2.cur[point].y = + ADD_LONG( ADD_LONG( exc->zp1.cur[a0].y, exc->zp1.cur[a1].y ), + ADD_LONG( exc->zp0.cur[b0].y, exc->zp0.cur[b1].y ) ) / 4; } exc->zp2.tags[point] |= FT_CURVE_TAG_TOUCH_BOTH; @@ -6564,7 +6599,7 @@ distance = PROJECT( exc->zp0.cur + p2, exc->zp1.cur + p1 ) / 2; exc->func_move( exc, &exc->zp1, p1, distance ); - exc->func_move( exc, &exc->zp0, p2, -distance ); + exc->func_move( exc, &exc->zp0, p2, NEG_LONG( distance ) ); } @@ -6598,7 +6633,9 @@ * Otherwise, by definition, the value of exc->twilight.orus[n] is (0,0), * for every n. */ - twilight = exc->GS.gep0 == 0 || exc->GS.gep1 == 0 || exc->GS.gep2 == 0; + twilight = ( exc->GS.gep0 == 0 || + exc->GS.gep1 == 0 || + exc->GS.gep2 == 0 ); if ( BOUNDS( exc->GS.rp1, exc->zp0.n_points ) ) { @@ -6635,9 +6672,11 @@ FT_Vector vec; - vec.x = FT_MulFix( exc->zp1.orus[exc->GS.rp2].x - orus_base->x, + vec.x = FT_MulFix( SUB_LONG( exc->zp1.orus[exc->GS.rp2].x, + orus_base->x ), exc->metrics.x_scale ); - vec.y = FT_MulFix( exc->zp1.orus[exc->GS.rp2].y - orus_base->y, + vec.y = FT_MulFix( SUB_LONG( exc->zp1.orus[exc->GS.rp2].y, + orus_base->y ), exc->metrics.y_scale ); old_range = FAST_DUALPROJ( &vec ); @@ -6646,7 +6685,7 @@ cur_range = PROJECT( &exc->zp1.cur[exc->GS.rp2], cur_base ); } - for ( ; exc->GS.loop > 0; --exc->GS.loop ) + for ( ; exc->GS.loop > 0; exc->GS.loop-- ) { FT_UInt point = (FT_UInt)exc->stack[--exc->args]; FT_F26Dot6 org_dist, cur_dist, new_dist; @@ -6672,9 +6711,11 @@ FT_Vector vec; - vec.x = FT_MulFix( exc->zp2.orus[point].x - orus_base->x, + vec.x = FT_MulFix( SUB_LONG( exc->zp2.orus[point].x, + orus_base->x ), exc->metrics.x_scale ); - vec.y = FT_MulFix( exc->zp2.orus[point].y - orus_base->y, + vec.y = FT_MulFix( SUB_LONG( exc->zp2.orus[point].y, + orus_base->y ), exc->metrics.y_scale ); org_dist = FAST_DUALPROJ( &vec ); @@ -6713,7 +6754,7 @@ exc->func_move( exc, &exc->zp2, (FT_UShort)point, - new_dist - cur_dist ); + SUB_LONG( new_dist, cur_dist ) ); } Fail: @@ -6778,14 +6819,14 @@ FT_F26Dot6 dx; - dx = worker->curs[p].x - worker->orgs[p].x; + dx = SUB_LONG( worker->curs[p].x, worker->orgs[p].x ); if ( dx != 0 ) { for ( i = p1; i < p; i++ ) - worker->curs[i].x += dx; + worker->curs[i].x = ADD_LONG( worker->curs[i].x, dx ); for ( i = p + 1; i <= p2; i++ ) - worker->curs[i].x += dx; + worker->curs[i].x = ADD_LONG( worker->curs[i].x, dx ); } } @@ -6830,8 +6871,8 @@ org2 = worker->orgs[ref2].x; cur1 = worker->curs[ref1].x; cur2 = worker->curs[ref2].x; - delta1 = cur1 - org1; - delta2 = cur2 - org2; + delta1 = SUB_LONG( cur1, org1 ); + delta2 = SUB_LONG( cur2, org2 ); if ( cur1 == cur2 || orus1 == orus2 ) { @@ -6843,10 +6884,10 @@ if ( x <= org1 ) - x += delta1; + x = ADD_LONG( x, delta1 ); else if ( x >= org2 ) - x += delta2; + x = ADD_LONG( x, delta2 ); else x = cur1; @@ -6867,20 +6908,23 @@ if ( x <= org1 ) - x += delta1; + x = ADD_LONG( x, delta1 ); else if ( x >= org2 ) - x += delta2; + x = ADD_LONG( x, delta2 ); else { if ( !scale_valid ) { scale_valid = 1; - scale = FT_DivFix( cur2 - cur1, orus2 - orus1 ); + scale = FT_DivFix( SUB_LONG( cur2, cur1 ), + SUB_LONG( orus2, orus1 ) ); } - x = cur1 + FT_MulFix( worker->orus[i].x - orus1, scale ); + x = ADD_LONG( cur1, + FT_MulFix( SUB_LONG( worker->orus[i].x, orus1 ), + scale ) ); } worker->curs[i].x = x; } @@ -6910,6 +6954,23 @@ FT_Short contour; /* current contour */ +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* See `ttinterp.h' for details on backward compatibility mode. */ + /* Allow IUP until it has been called on both axes. Immediately */ + /* return on subsequent ones. */ + if ( SUBPIXEL_HINTING_MINIMAL && + exc->backward_compatibility ) + { + if ( exc->iupx_called && exc->iupy_called ) + return; + + if ( exc->opcode & 1 ) + exc->iupx_called = TRUE; + else + exc->iupy_called = TRUE; + } +#endif + /* ignore empty outlines */ if ( exc->pts.n_contours == 0 ) return; @@ -6933,15 +6994,15 @@ contour = 0; point = 0; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - if ( SUBPIXEL_HINTING && - exc->ignore_x_mode ) +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + if ( SUBPIXEL_HINTING_INFINALITY && + exc->ignore_x_mode ) { exc->iup_called = TRUE; if ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_IUP ) return; } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ do { @@ -7013,37 +7074,16 @@ FT_UShort A; FT_ULong C, P; FT_Long B; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY FT_UShort B1, B2; - if ( SUBPIXEL_HINTING && + if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode && exc->iup_called && ( exc->sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) ) goto Fail; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ - - -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - /* Delta hinting is covered by US Patent 5159668. */ - if ( exc->face->unpatented_hinting ) - { - FT_Long n = args[0] * 2; - - - if ( exc->args < n ) - { - if ( exc->pedantic_hinting ) - exc->error = FT_THROW( Too_Few_Arguments ); - n = exc->args; - } - - exc->args -= n; - exc->new_top = exc->args; - return; - } -#endif +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ P = (FT_ULong)exc->func_cur_ppem( exc ); nump = (FT_ULong)args[0]; /* some points theoretically may occur more @@ -7097,9 +7137,9 @@ B++; B *= 1L << ( 6 - exc->GS.delta_shift ); -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING ) + if ( SUBPIXEL_HINTING_INFINALITY ) { /* * Allow delta move if @@ -7152,13 +7192,29 @@ SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP ) && ( B1 & 63 ) != 0 && ( B2 & 63 ) != 0 ) ) ) - exc->func_move( exc, &exc->zp0, A, -B ); + exc->func_move( exc, &exc->zp0, A, NEG_LONG( B ) ); } } else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ - exc->func_move( exc, &exc->zp0, A, B ); + { + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* See `ttinterp.h' for details on backward compatibility */ + /* mode. */ + if ( SUBPIXEL_HINTING_MINIMAL && + exc->backward_compatibility ) + { + if ( !( exc->iupx_called && exc->iupy_called ) && + ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) || + ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) ) ) + exc->func_move( exc, &exc->zp0, A, B ); + } + else +#endif + exc->func_move( exc, &exc->zp0, A, B ); + } } } else @@ -7186,26 +7242,6 @@ FT_Long B; -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - /* Delta hinting is covered by US Patent 5159668. */ - if ( exc->face->unpatented_hinting ) - { - FT_Long n = args[0] * 2; - - - if ( exc->args < n ) - { - if ( exc->pedantic_hinting ) - exc->error = FT_THROW( Too_Few_Arguments ); - n = exc->args; - } - - exc->args -= n; - exc->new_top = exc->args; - return; - } -#endif - P = (FT_ULong)exc->func_cur_ppem( exc ); nump = (FT_ULong)args[0]; @@ -7294,24 +7330,25 @@ Ins_GETINFO( TT_ExecContext exc, FT_Long* args ) { - FT_Long K; + FT_Long K; + TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( exc->face ); K = 0; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /********************************/ /* RASTERIZER VERSION */ /* Selector Bit: 0 */ /* Return Bit(s): 0-7 */ /* */ - if ( SUBPIXEL_HINTING && - ( args[0] & 1 ) != 0 && - exc->subpixel_hinting ) + if ( SUBPIXEL_HINTING_INFINALITY && + ( args[0] & 1 ) != 0 && + exc->subpixel_hinting ) { if ( exc->ignore_x_mode ) { - /* if in ClearType backwards compatibility mode, */ + /* if in ClearType backward compatibility mode, */ /* we sometimes change the TrueType version dynamically */ K = exc->rasterizer_version; FT_TRACE6(( "Setting rasterizer version %d\n", @@ -7321,9 +7358,9 @@ K = TT_INTERPRETER_VERSION_38; } else -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ if ( ( args[0] & 1 ) != 0 ) - K = TT_INTERPRETER_VERSION_35; + K = driver->interpreter_version; /********************************/ /* GLYPH ROTATED */ @@ -7331,7 +7368,7 @@ /* Return Bit(s): 8 */ /* */ if ( ( args[0] & 2 ) != 0 && exc->tt_metrics.rotated ) - K |= 0x80; + K |= 1 << 8; /********************************/ /* GLYPH STRETCHED */ @@ -7339,19 +7376,87 @@ /* Return Bit(s): 9 */ /* */ if ( ( args[0] & 4 ) != 0 && exc->tt_metrics.stretched ) - K |= 1 << 8; + K |= 1 << 9; + +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + /********************************/ + /* VARIATION GLYPH */ + /* Selector Bit: 3 */ + /* Return Bit(s): 10 */ + /* */ + /* XXX: UNDOCUMENTED! */ + if ( (args[0] & 8 ) != 0 && exc->face->blend ) + K |= 1 << 10; +#endif /********************************/ - /* HINTING FOR GRAYSCALE */ + /* BI-LEVEL HINTING AND */ + /* GRAYSCALE RENDERING */ /* Selector Bit: 5 */ /* Return Bit(s): 12 */ /* */ if ( ( args[0] & 32 ) != 0 && exc->grayscale ) K |= 1 << 12; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* Toggle the following flags only outside of monochrome mode. */ + /* Otherwise, instructions may behave weirdly and rendering results */ + /* may differ between v35 and v40 mode, e.g., in `Times New Roman */ + /* Bold Italic'. */ + if ( SUBPIXEL_HINTING_MINIMAL && exc->subpixel_hinting_lean ) + { + /********************************/ + /* HINTING FOR SUBPIXEL */ + /* Selector Bit: 6 */ + /* Return Bit(s): 13 */ + /* */ + /* v40 does subpixel hinting by default. */ + if ( ( args[0] & 64 ) != 0 ) + K |= 1 << 13; - if ( SUBPIXEL_HINTING && + /********************************/ + /* VERTICAL LCD SUBPIXELS? */ + /* Selector Bit: 8 */ + /* Return Bit(s): 15 */ + /* */ + if ( ( args[0] & 256 ) != 0 && exc->vertical_lcd_lean ) + K |= 1 << 15; + + /********************************/ + /* SUBPIXEL POSITIONED? */ + /* Selector Bit: 10 */ + /* Return Bit(s): 17 */ + /* */ + /* XXX: FreeType supports it, dependent on what client does? */ + if ( ( args[0] & 1024 ) != 0 ) + K |= 1 << 17; + + /********************************/ + /* SYMMETRICAL SMOOTHING */ + /* Selector Bit: 11 */ + /* Return Bit(s): 18 */ + /* */ + /* The only smoothing method FreeType supports unless someone sets */ + /* FT_LOAD_TARGET_MONO. */ + if ( ( args[0] & 2048 ) != 0 && exc->subpixel_hinting_lean ) + K |= 1 << 18; + + /********************************/ + /* CLEARTYPE HINTING AND */ + /* GRAYSCALE RENDERING */ + /* Selector Bit: 12 */ + /* Return Bit(s): 19 */ + /* */ + /* Grayscale rendering is what FreeType does anyway unless someone */ + /* sets FT_LOAD_TARGET_MONO or FT_LOAD_TARGET_LCD(_V) */ + if ( ( args[0] & 4096 ) != 0 && exc->grayscale_cleartype ) + K |= 1 << 19; + } +#endif + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + + if ( SUBPIXEL_HINTING_INFINALITY && exc->rasterizer_version >= TT_INTERPRETER_VERSION_35 ) { @@ -7424,12 +7529,71 @@ } } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ args[0] = K; } +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + + /*************************************************************************/ + /* */ + /* GETVARIATION[]: get normalized variation (blend) coordinates */ + /* Opcode range: 0x91 */ + /* Stack: --> f2.14... */ + /* */ + /* XXX: UNDOCUMENTED! There is no official documentation from Apple for */ + /* this bytecode instruction. Active only if a font has GX */ + /* variation axes. */ + /* */ + static void + Ins_GETVARIATION( TT_ExecContext exc, + FT_Long* args ) + { + FT_UInt num_axes = exc->face->blend->num_axis; + FT_Fixed* coords = exc->face->blend->normalizedcoords; + + FT_UInt i; + + + if ( BOUNDS( num_axes, exc->stackSize + 1 - exc->top ) ) + { + exc->error = FT_THROW( Stack_Overflow ); + return; + } + + if ( coords ) + { + for ( i = 0; i < num_axes; i++ ) + args[i] = coords[i] >> 2; /* convert 16.16 to 2.14 format */ + } + else + { + for ( i = 0; i < num_axes; i++ ) + args[i] = 0; + } + } + + + /*************************************************************************/ + /* */ + /* GETDATA[]: no idea what this is good for */ + /* Opcode range: 0x92 */ + /* Stack: --> 17 */ + /* */ + /* XXX: UNDOCUMENTED! There is no documentation from Apple for this */ + /* very weird bytecode instruction. */ + /* */ + static void + Ins_GETDATA( FT_Long* args ) + { + args[0] = 17; + } + +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + + static void Ins_UNKNOWN( TT_ExecContext exc ) { @@ -7503,10 +7667,11 @@ FT_EXPORT_DEF( FT_Error ) TT_RunIns( TT_ExecContext exc ) { - FT_Long ins_counter = 0; /* executed instructions counter */ + FT_ULong ins_counter = 0; /* executed instructions counter */ + FT_ULong num_twilight_points; FT_UShort i; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY FT_Byte opcode_pattern[1][2] = { /* #8 TypeMan Talk Align */ { @@ -7517,12 +7682,88 @@ FT_UShort opcode_patterns = 1; FT_UShort opcode_pointer[1] = { 0 }; FT_UShort opcode_size[1] = { 1 }; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY exc->iup_called = FALSE; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* + * Toggle backward compatibility according to what font wants, except + * when + * + * 1) we have a `tricky' font that heavily relies on the interpreter to + * render glyphs correctly, for example DFKai-SB, or + * 2) FT_RENDER_MODE_MONO (i.e, monochome rendering) is requested. + * + * In those cases, backward compatibility needs to be turned off to get + * correct rendering. The rendering is then completely up to the + * font's programming. + * + */ + if ( SUBPIXEL_HINTING_MINIMAL && + exc->subpixel_hinting_lean && + !FT_IS_TRICKY( &exc->face->root ) ) + exc->backward_compatibility = !( exc->GS.instruct_control & 4 ); + else + exc->backward_compatibility = FALSE; + + exc->iupx_called = FALSE; + exc->iupy_called = FALSE; +#endif + + /* We restrict the number of twilight points to a reasonable, */ + /* heuristic value to avoid slow execution of malformed bytecode. */ + num_twilight_points = FT_MAX( 30, + 2 * ( exc->pts.n_points + exc->cvtSize ) ); + if ( exc->twilight.n_points > num_twilight_points ) + { + if ( num_twilight_points > 0xFFFFU ) + num_twilight_points = 0xFFFFU; + + FT_TRACE5(( "TT_RunIns: Resetting number of twilight points\n" + " from %d to the more reasonable value %d\n", + exc->twilight.n_points, + num_twilight_points )); + exc->twilight.n_points = (FT_UShort)num_twilight_points; + } + + /* Set up loop detectors. We restrict the number of LOOPCALL loops */ + /* and the number of JMPR, JROT, and JROF calls with a negative */ + /* argument to values that depend on various parameters like the */ + /* size of the CVT table or the number of points in the current */ + /* glyph (if applicable). */ + /* */ + /* The idea is that in real-world bytecode you either iterate over */ + /* all CVT entries (in the `prep' table), or over all points (or */ + /* contours, in the `glyf' table) of a glyph, and such iterations */ + /* don't happen very often. */ + exc->loopcall_counter = 0; + exc->neg_jump_counter = 0; + + /* The maximum values are heuristic. */ + if ( exc->pts.n_points ) + exc->loopcall_counter_max = FT_MAX( 50, + 10 * exc->pts.n_points ) + + FT_MAX( 50, + exc->cvtSize / 10 ); + else + exc->loopcall_counter_max = 300 + 8 * exc->cvtSize; + + /* as a protection against an unreasonable number of CVT entries */ + /* we assume at most 100 control values per glyph for the counter */ + if ( exc->loopcall_counter_max > + 100 * (FT_ULong)exc->face->root.num_glyphs ) + exc->loopcall_counter_max = 100 * (FT_ULong)exc->face->root.num_glyphs; + + FT_TRACE5(( "TT_RunIns: Limiting total number of loops in LOOPCALL" + " to %d\n", exc->loopcall_counter_max )); + + exc->neg_jump_counter_max = exc->loopcall_counter_max; + FT_TRACE5(( "TT_RunIns: Limiting total number of backward jumps" + " to %d\n", exc->neg_jump_counter_max )); /* set PPEM and CVT functions */ exc->tt_metrics.ratio = 0; @@ -7565,7 +7806,7 @@ ? 2 : 12 - ( *opcode_name[exc->opcode] - '0' ), "#" )); - for ( n = 0; n < cnt; n++ ) + for ( n = 1; n <= cnt; n++ ) FT_TRACE7(( " %d", exc->stack[exc->top - n] )); FT_TRACE6(( "\n" )); } @@ -7601,7 +7842,21 @@ exc->args = 0; } - exc->new_top = exc->args + ( Pop_Push_Count[exc->opcode] & 15 ); +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + if ( exc->opcode == 0x91 ) + { + /* this is very special: GETVARIATION returns */ + /* a variable number of arguments */ + + /* it is the job of the application to `activate' GX handling, */ + /* this is, calling any of the GX API functions on the current */ + /* font to select a variation instance */ + if ( exc->face->blend ) + exc->new_top = exc->args + exc->face->blend->num_axis; + } + else +#endif + exc->new_top = exc->args + ( Pop_Push_Count[exc->opcode] & 15 ); /* `new_top' is the new top of the stack, after the instruction's */ /* execution. `top' will be set to `new_top' after the `switch' */ @@ -7615,9 +7870,9 @@ exc->step_ins = TRUE; exc->error = FT_Err_Ok; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - if ( SUBPIXEL_HINTING ) + if ( SUBPIXEL_HINTING_INFINALITY ) { for ( i = 0; i < opcode_patterns; i++ ) { @@ -7646,7 +7901,7 @@ } } -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ { FT_Long* args = exc->stack + exc->args; @@ -7794,7 +8049,7 @@ Ins_ALIGNPTS( exc, args ); break; - case 0x28: /* ???? */ + case 0x28: /* RAW */ Ins_UNKNOWN( exc ); break; @@ -8146,10 +8401,33 @@ Ins_INSTCTRL( exc, args ); break; - case 0x8F: + case 0x8F: /* ADJUST */ + case 0x90: /* ADJUST */ Ins_UNKNOWN( exc ); break; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + case 0x91: + /* it is the job of the application to `activate' GX handling, */ + /* this is, calling any of the GX API functions on the current */ + /* font to select a variation instance */ + if ( exc->face->blend ) + Ins_GETVARIATION( exc, args ); + else + Ins_UNKNOWN( exc ); + break; + + case 0x92: + /* there is at least one MS font (LaoUI.ttf version 5.01) that */ + /* uses IDEFs for 0x91 and 0x92; for this reason we activate */ + /* GETDATA for GX fonts only, similar to GETVARIATION */ + if ( exc->face->blend ) + Ins_GETDATA( args ); + else + Ins_UNKNOWN( exc ); + break; +#endif + default: if ( opcode >= 0xE0 ) Ins_MIRP( exc, args ); @@ -8230,7 +8508,7 @@ /* increment instruction counter and check if we didn't */ /* run this program for too long (e.g. infinite loops). */ - if ( ++ins_counter > MAX_RUNNABLE_OPCODES ) + if ( ++ins_counter > TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES ) return FT_THROW( Execution_Too_Long ); LSuiteLabel_: @@ -8247,29 +8525,27 @@ } while ( !exc->instruction_trap ); LNo_Error_: + FT_TRACE4(( " %d instruction%s executed\n", + ins_counter, + ins_counter == 1 ? "" : "s" )); return FT_Err_Ok; LErrorCodeOverflow_: exc->error = FT_THROW( Code_Overflow ); LErrorLabel_: - /* If any errors have occurred, function tables may be broken. */ - /* Force a re-execution of `prep' and `fpgm' tables if no */ - /* bytecode debugger is run. */ - if ( exc->error && - !exc->instruction_trap && - exc->curRange == tt_coderange_glyph ) - { + if ( exc->error && !exc->instruction_trap ) FT_TRACE1(( " The interpreter returned error 0x%x\n", exc->error )); - exc->size->bytecode_ready = -1; - exc->size->cvt_ready = -1; - } return exc->error; } +#else /* !TT_USE_BYTECODE_INTERPRETER */ -#endif /* TT_USE_BYTECODE_INTERPRETER */ + /* ANSI C doesn't like empty source files */ + typedef int _tt_interp_dummy; + +#endif /* !TT_USE_BYTECODE_INTERPRETER */ /* END */ diff --git a/src/3rdparty/freetype/src/truetype/ttinterp.h b/src/3rdparty/freetype/src/truetype/ttinterp.h index 32706d0760..2966439ea2 100644 --- a/src/3rdparty/freetype/src/truetype/ttinterp.h +++ b/src/3rdparty/freetype/src/truetype/ttinterp.h @@ -4,7 +4,7 @@ /* */ /* TrueType bytecode interpreter (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTINTERP_H__ -#define __TTINTERP_H__ +#ifndef TTINTERP_H_ +#define TTINTERP_H_ #include <ft2build.h> #include "ttobjs.h" @@ -99,7 +99,7 @@ FT_BEGIN_HEADER } TT_CallRec, *TT_CallStack; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /*************************************************************************/ /* */ @@ -138,7 +138,7 @@ FT_BEGIN_HEADER } SPH_Font_Class; -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ /*************************************************************************/ @@ -170,6 +170,7 @@ FT_BEGIN_HEADER pts, twilight; + FT_Long pointSize; /* in 26.6 format */ FT_Size_Metrics metrics; TT_Size_Metrics tt_metrics; /* size metrics */ @@ -247,9 +248,151 @@ FT_BEGIN_HEADER TT_Set_CVT_Func func_write_cvt; /* write a cvt entry (in pixels) */ TT_Set_CVT_Func func_move_cvt; /* incr a cvt entry (in pixels) */ - FT_Bool grayscale; /* are we hinting for grayscale? */ + FT_Bool grayscale; /* bi-level hinting and */ + /* grayscale rendering */ -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + /* + * FreeType supports ClearType-like hinting of TrueType fonts through + * the version 40 interpreter. This is achieved through several hacks + * in the base (v35) interpreter, as detailed below. + * + * ClearType is an umbrella term for several rendering techniques + * employed by Microsoft's various GUI and rendering toolkit + * implementations, most importantly: subpixel rendering for using the + * RGB subpixels of LCDs to approximately triple the perceived + * resolution on the x-axis and subpixel hinting for positioning stems + * on subpixel borders. TrueType programming is explicit, i.e., fonts + * must be programmed to take advantage of ClearType's possibilities. + * + * When ClearType was introduced, it seemed unlikely that all fonts + * would be reprogrammed, so Microsoft decided to implement a backward + * compatibility mode. It employs several simple to complicated + * assumptions and tricks, many of them font-dependent, that modify the + * interpretation of the bytecode contained in these fonts to retrofit + * them into a ClearType-y look. The quality of the results varies. + * Most (web)fonts that were released since then have come to rely on + * these hacks to render correctly, even some of Microsoft's flagship + * fonts (e.g., Calibri, Cambria, Segoe UI). + * + * FreeType's minimal subpixel hinting code (interpreter version 40) + * employs a small list of font-agnostic hacks loosely based on the + * public information available on Microsoft's compatibility mode[2]. + * The focus is on modern (web)fonts rather than legacy fonts that were + * made for monochrome rendering. It will not match ClearType rendering + * exactly. Unlike the `Infinality' code (interpreter version 38) that + * came before, it will not try to toggle hacks for specific fonts for + * performance and complexity reasons. It will fall back to version 35 + * behavior for tricky fonts[1] or when monochrome rendering is + * requested. + * + * Major hacks + * + * - Any point movement on the x axis is ignored (cf. `Direct_Move' and + * `Direct_Move_X'). This has the smallest code footprint and single + * biggest effect. The ClearType way to increase resolution is + * supersampling the x axis, the FreeType way is ignoring instructions + * on the x axis, which gives the same result in the majority of + * cases. + * + * - Points are not moved post-IUP (neither on the x nor on the y axis), + * except the x component of diagonal moves post-IUP (cf. + * `Direct_Move', `Direct_Move_Y', `Move_Zp2_Point'). Post-IUP + * changes are commonly used to `fix' pixel patterns which has little + * use outside monochrome rendering. + * + * - SHPIX and DELTAP don't execute unless moving a composite on the + * y axis or moving a previously y touched point. SHPIX additionally + * denies movement on the x axis (cf. `Ins_SHPIX' and `Ins_DELTAP'). + * Both instructions are commonly used to `fix' pixel patterns for + * monochrome or Windows's GDI rendering but make little sense for + * FreeType rendering. Both can distort the outline. See [2] for + * details. + * + * - The hdmx table and modifications to phantom points are ignored. + * Bearings and advance widths remain unchanged (except rounding them + * outside the interpreter!), cf. `compute_glyph_metrics' and + * `TT_Hint_Glyph'. Letting non-native-ClearType fonts modify spacing + * might mess up spacing. + * + * Minor hacks + * + * - FLIPRGON, FLIPRGOFF, and FLIPPT don't execute post-IUP. This + * prevents dents in e.g. Arial-Regular's `D' and `G' glyphs at + * various sizes. + * + * (Post-IUP is the state after both IUP[x] and IUP[y] have been + * executed.) + * + * The best results are achieved for fonts that were from the outset + * designed with ClearType in mind, meaning they leave the x axis mostly + * alone and don't mess with the `final' outline to produce more + * pleasing pixel patterns. The harder the designer tried to produce + * very specific patterns (`superhinting') for pre-ClearType-displays, + * the worse the results. + * + * Microsoft defines a way to turn off backward compatibility and + * interpret instructions as before (called `native ClearType')[2][3]. + * The font designer then regains full control and is responsible for + * making the font work correctly with ClearType without any + * hand-holding by the interpreter or rasterizer[4]. The v40 + * interpreter assumes backward compatibility by default, which can be + * turned off the same way by executing the following in the control + * program (cf. `Ins_INSTCTRL'). + * + * #PUSH 4,3 + * INSTCTRL[] + * + * [1] Tricky fonts as FreeType defines them rely on the bytecode + * interpreter to display correctly. Hacks can interfere with them, + * so they get treated like native ClearType fonts (v40 with + * backward compatibility turned off). Cf. `TT_RunIns'. + * + * [2] Proposed by Microsoft's Greg Hitchcock in + * https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx + * + * [3] Beat Stamm describes it in more detail: + * http://www.beatstamm.com/typography/RTRCh4.htm#Sec12 + * + * [4] The list of `native ClearType' fonts is small at the time of this + * writing; I found the following on a Windows 10 Update 1511 + * installation: Constantia, Corbel, Sitka, Malgun Gothic, Microsoft + * JhengHei (Bold and UI Bold), Microsoft YaHei (Bold and UI Bold), + * SimSun, NSimSun, and Yu Gothic. + * + */ + + /* Using v40 implies subpixel hinting, unless FT_RENDER_MODE_MONO has been + * requested. Used to detect interpreter */ + /* version switches. `_lean' to differentiate from the Infinality */ + /* `subpixel_hinting', which is managed differently. */ + FT_Bool subpixel_hinting_lean; + + /* Long side of a LCD subpixel is vertical (e.g., screen is rotated). */ + /* `_lean' to differentiate from the Infinality `vertical_lcd', which */ + /* is managed differently. */ + FT_Bool vertical_lcd_lean; + + /* Default to backward compatibility mode in v40 interpreter. If */ + /* this is false, it implies the interpreter is in v35 or in native */ + /* ClearType mode. */ + FT_Bool backward_compatibility; + + /* Useful for detecting and denying post-IUP trickery that is usually */ + /* used to fix pixel patterns (`superhinting'). */ + FT_Bool iupx_called; + FT_Bool iupy_called; + + /* ClearType hinting and grayscale rendering, as used by Universal */ + /* Windows Platform apps (Windows 8 and above). Like the standard */ + /* colorful ClearType mode, it utilizes a vastly increased virtual */ + /* resolution on the x axis. Different from bi-level hinting and */ + /* grayscale rendering, the old mode from Win9x days that roughly */ + /* adheres to the physical pixel grid on both axes. */ + FT_Bool grayscale_cleartype; +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL */ + +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY TT_Round_Func func_round_sphn; /* subpixel rounding function */ FT_Bool subpixel_hinting; /* Using subpixel hinting? */ @@ -279,7 +422,15 @@ FT_BEGIN_HEADER FT_ULong sph_in_func_flags; /* flags to indicate if in */ /* special functions */ -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ + + /* We maintain two counters (in addition to the instruction counter) */ + /* that act as loop detectors for LOOPCALL and jump opcodes with */ + /* negative arguments. */ + FT_ULong loopcall_counter; + FT_ULong loopcall_counter_max; + FT_ULong neg_jump_counter; + FT_ULong neg_jump_counter_max; } TT_ExecContextRec; @@ -382,7 +533,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTINTERP_H__ */ +#endif /* TTINTERP_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/truetype/ttobjs.c b/src/3rdparty/freetype/src/truetype/ttobjs.c index 6060d6f5d1..6685dc8196 100644 --- a/src/3rdparty/freetype/src/truetype/ttobjs.c +++ b/src/3rdparty/freetype/src/truetype/ttobjs.c @@ -4,7 +4,7 @@ /* */ /* Objects manager (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,7 +21,7 @@ #include FT_INTERNAL_STREAM_H #include FT_TRUETYPE_TAGS_H #include FT_INTERNAL_SFNT_H -#include FT_TRUETYPE_DRIVER_H +#include FT_DRIVER_H #include "ttgload.h" #include "ttpload.h" @@ -32,10 +32,6 @@ #include "ttinterp.h" #endif -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING -#include FT_TRUETYPE_UNPATENTED_H -#endif - #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT #include "ttgxvar.h" #endif @@ -121,7 +117,7 @@ FT_Error error; - FT_MEM_ZERO( zone, sizeof ( *zone ) ); + FT_ZERO( zone ); zone->memory = memory; if ( FT_NEW_ARRAY( zone->org, maxPoints ) || @@ -151,20 +147,51 @@ { #define TRICK_NAMES_MAX_CHARACTERS 19 -#define TRICK_NAMES_COUNT 9 +#define TRICK_NAMES_COUNT 26 static const char trick_names[TRICK_NAMES_COUNT] [TRICK_NAMES_MAX_CHARACTERS + 1] = { + /* + PostScript names are given in brackets if they differ from the + family name. The version numbers, together with the copyright or + release year data, are taken from fonts available to the + developers. + + Note that later versions of the fonts might be no longer tricky; + for example, `MingLiU' version 7.00 (file `mingliu.ttc' from + Windows 7) is an ordinary TTC with non-tricky subfonts. + */ + + "cpop", /* dftt-p7.ttf; version 1.00, 1992 [DLJGyShoMedium] */ + "DFGirl-W6-WIN-BF", /* dftt-h6.ttf; version 1.00, 1993 */ + "DFGothic-EB", /* DynaLab Inc. 1992-1995 */ + "DFGyoSho-Lt", /* DynaLab Inc. 1992-1995 */ + "DFHei-Md-HK-BF", /* maybe DynaLab Inc. */ + "DFHSGothic-W5", /* DynaLab Inc. 1992-1995 */ + "DFHSMincho-W3", /* DynaLab Inc. 1992-1995 */ + "DFHSMincho-W7", /* DynaLab Inc. 1992-1995 */ "DFKaiSho-SB", /* dfkaisb.ttf */ "DFKaiShu", - "DFKai-SB", /* kaiu.ttf */ + "DFKaiShu-Md-HK-BF", /* maybe DynaLab Inc. */ + "DFKai-SB", /* kaiu.ttf; version 3.00, 1998 [DFKaiShu-SB-Estd-BF] */ + "DFMing-Bd-HK-BF", /* maybe DynaLab Inc. */ + "DLC", /* dftt-m7.ttf; version 1.00, 1993 [DLCMingBold] */ + /* dftt-f5.ttf; version 1.00, 1993 [DLCFongSung] */ + "DLCHayMedium", /* dftt-b5.ttf; version 1.00, 1993 */ + "DLCHayBold", /* dftt-b7.ttf; version 1.00, 1993 */ + "DLCKaiMedium", /* dftt-k5.ttf; version 1.00, 1992 */ + "DLCLiShu", /* dftt-l5.ttf; version 1.00, 1992 */ + "DLCRoundBold", /* dftt-r7.ttf; version 1.00, 1993 */ "HuaTianKaiTi?", /* htkt2.ttf */ "HuaTianSongTi?", /* htst3.ttf */ - "Ming(for ISO10646)", /* hkscsiic.ttf & iicore.ttf */ - "MingLiU", /* mingliu.ttf & mingliu.ttc */ - "PMingLiU", /* mingliu.ttc */ - "MingLi43", /* mingli.ttf */ + "Ming(for ISO10646)", /* hkscsiic.ttf; version 0.12, 2007 [Ming] */ + /* iicore.ttf; version 0.07, 2007 [Ming] */ + "MingLiU", /* mingliu.ttf */ + /* mingliu.ttc; version 3.21, 2001 */ + "MingMedium", /* dftt-m5.ttf; version 1.00, 1993 [DLCMingMedium] */ + "PMingLiU", /* mingliu.ttc; version 3.21, 2001 */ + "MingLi43", /* mingli.ttf; version 1.00, 1992 */ }; int nn; @@ -246,7 +273,7 @@ tt_check_trickyness_sfnt_ids( TT_Face face ) { #define TRICK_SFNT_IDS_PER_FACE 3 -#define TRICK_SFNT_IDS_NUM_FACES 17 +#define TRICK_SFNT_IDS_NUM_FACES 29 static const tt_sfnt_id_rec sfnt_id[TRICK_SFNT_IDS_NUM_FACES] [TRICK_SFNT_IDS_PER_FACE] = { @@ -265,11 +292,66 @@ { 0x28233BF1UL, 0x000087C4UL }, /* fpgm */ { 0xA344A1EBUL, 0x000001E1UL } /* prep */ }, + { /* DFGothic-EB */ + { 0x12C3EBB2UL, 0x00000350UL }, /* cvt */ + { 0xB680EE64UL, 0x000087A7UL }, /* fpgm */ + { 0xCE939563UL, 0x00000758UL } /* prep */ + }, + { /* DFGyoSho-Lt */ + { 0x11E5EAD4UL, 0x00000350UL }, /* cvt */ + { 0xCE5956E9UL, 0x0000BC85UL }, /* fpgm */ + { 0x8272F416UL, 0x00000045UL } /* prep */ + }, + { /* DFHei-Md-HK-BF */ + { 0x1257EB46UL, 0x00000350UL }, /* cvt */ + { 0xF699D160UL, 0x0000715FUL }, /* fpgm */ + { 0xD222F568UL, 0x000003BCUL } /* prep */ + }, + { /* DFHSGothic-W5 */ + { 0x1262EB4EUL, 0x00000350UL }, /* cvt */ + { 0xE86A5D64UL, 0x00007940UL }, /* fpgm */ + { 0x7850F729UL, 0x000005FFUL } /* prep */ + }, + { /* DFHSMincho-W3 */ + { 0x122DEB0AUL, 0x00000350UL }, /* cvt */ + { 0x3D16328AUL, 0x0000859BUL }, /* fpgm */ + { 0xA93FC33BUL, 0x000002CBUL } /* prep */ + }, + { /* DFHSMincho-W7 */ + { 0x125FEB26UL, 0x00000350UL }, /* cvt */ + { 0xA5ACC982UL, 0x00007EE1UL }, /* fpgm */ + { 0x90999196UL, 0x0000041FUL } /* prep */ + }, { /* DFKaiShu */ { 0x11E5EAD4UL, 0x00000350UL }, /* cvt */ { 0x5A30CA3BUL, 0x00009063UL }, /* fpgm */ { 0x13A42602UL, 0x0000007EUL } /* prep */ }, + { /* DFKaiShu, variant */ + { 0x11E5EAD4UL, 0x00000350UL }, /* cvt */ + { 0xA6E78C01UL, 0x00008998UL }, /* fpgm */ + { 0x13A42602UL, 0x0000007EUL } /* prep */ + }, + { /* DFKaiShu-Md-HK-BF */ + { 0x11E5EAD4UL, 0x00000360UL }, /* cvt */ + { 0x9DB282B2UL, 0x0000C06EUL }, /* fpgm */ + { 0x53E6D7CAUL, 0x00000082UL } /* prep */ + }, + { /* DFMing-Bd-HK-BF */ + { 0x1243EB18UL, 0x00000350UL }, /* cvt */ + { 0xBA0A8C30UL, 0x000074ADUL }, /* fpgm */ + { 0xF3D83409UL, 0x0000037BUL } /* prep */ + }, + { /* DLCLiShu */ + { 0x07DCF546UL, 0x00000308UL }, /* cvt */ + { 0x40FE7C90UL, 0x00008E2AUL }, /* fpgm */ + { 0x608174B5UL, 0x0000007AUL } /* prep */ + }, + { /* DLCHayBold */ + { 0xEB891238UL, 0x00000308UL }, /* cvt */ + { 0xD2E4DCD4UL, 0x0000676FUL }, /* fpgm */ + { 0x8EA5F293UL, 0x000003B8UL } /* prep */ + }, { /* HuaTianKaiTi */ { 0xFFFBFFFCUL, 0x00000008UL }, /* cvt */ { 0x9C9E48B8UL, 0x0000BEA2UL }, /* fpgm */ @@ -339,6 +421,11 @@ { 0x00000000UL, 0x00000000UL }, /* cvt */ { 0xF055FC48UL, 0x000001C2UL }, /* fpgm */ { 0x3900DED3UL, 0x00001E18UL } /* prep */ + }, + { /* MINGLI.TTF, 1992 */ + { 0x00170003UL, 0x00000060UL }, /* cvt */ + { 0xDBB4306EUL, 0x000058AAUL }, /* fpgm */ + { 0xD643482AUL, 0x00000035UL } /* prep */ } }; @@ -397,11 +484,11 @@ for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ ) { if ( !has_cvt && !sfnt_id[j][TRICK_SFNT_ID_cvt].Length ) - num_matched_ids[j] ++; + num_matched_ids[j]++; if ( !has_fpgm && !sfnt_id[j][TRICK_SFNT_ID_fpgm].Length ) - num_matched_ids[j] ++; + num_matched_ids[j]++; if ( !has_prep && !sfnt_id[j][TRICK_SFNT_ID_prep].Length ) - num_matched_ids[j] ++; + num_matched_ids[j]++; if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE ) return TRUE; } @@ -535,6 +622,7 @@ goto Exit; /* check that we have a valid TrueType file */ + FT_TRACE2(( " " )); error = sfnt->init_face( stream, face, face_index, num_params, params ); /* Stream may have changed. */ @@ -546,9 +634,11 @@ /* We must also be able to accept Mac/GX fonts, as well as OT ones. */ /* The 0x00020000 tag is completely undocumented; some fonts from */ /* Arphic made for Chinese Windows 3.1 have this. */ - if ( face->format_tag != 0x00010000L && /* MS fonts */ - face->format_tag != 0x00020000L && /* CJK fonts for Win 3.1 */ - face->format_tag != TTAG_true ) /* Mac fonts */ + if ( face->format_tag != 0x00010000L && /* MS fonts */ + face->format_tag != 0x00020000L && /* CJK fonts for Win 3.1 */ + face->format_tag != TTAG_true && /* Mac fonts */ + face->format_tag != TTAG_0xA5kbd && /* `Keyboard.dfont' (legacy Mac OS X) */ + face->format_tag != TTAG_0xA5lst ) /* `LastResort.dfont' (legacy Mac OS X) */ { FT_TRACE2(( " not a TTF font\n" )); goto Bad_Format; @@ -576,129 +666,71 @@ if ( FT_IS_SCALABLE( ttface ) ) { - #ifdef FT_CONFIG_OPTION_INCREMENTAL - if ( !ttface->internal->incremental_interface ) - error = tt_face_load_loca( face, stream ); - if ( !error ) - error = tt_face_load_cvt( face, stream ); - if ( !error ) - error = tt_face_load_fpgm( face, stream ); - if ( !error ) - error = tt_face_load_prep( face, stream ); - - /* Check the scalable flag based on `loca'. */ - if ( !ttface->internal->incremental_interface && - ttface->num_fixed_sizes && - face->glyph_locations && - tt_check_single_notdef( ttface ) ) +#endif { - FT_TRACE5(( "tt_face_init:" - " Only the `.notdef' glyph has an outline.\n" - " " - " Resetting scalable flag to FALSE.\n" )); + error = tt_face_load_loca( face, stream ); - ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE; + /* having a (non-zero) `glyf' table without */ + /* a `loca' table is not valid */ + if ( face->glyf_len && FT_ERR_EQ( error, Table_Missing ) ) + goto Exit; + if ( error ) + goto Exit; } -#else /* !FT_CONFIG_OPTION_INCREMENTAL */ + /* `fpgm', `cvt', and `prep' are optional */ + error = tt_face_load_cvt( face, stream ); + if ( error && FT_ERR_NEQ( error, Table_Missing ) ) + goto Exit; - if ( !error ) - error = tt_face_load_loca( face, stream ); - if ( !error ) - error = tt_face_load_cvt( face, stream ); - if ( !error ) - error = tt_face_load_fpgm( face, stream ); - if ( !error ) - error = tt_face_load_prep( face, stream ); + error = tt_face_load_fpgm( face, stream ); + if ( error && FT_ERR_NEQ( error, Table_Missing ) ) + goto Exit; + + error = tt_face_load_prep( face, stream ); + if ( error && FT_ERR_NEQ( error, Table_Missing ) ) + goto Exit; /* Check the scalable flag based on `loca'. */ - if ( ttface->num_fixed_sizes && - face->glyph_locations && - tt_check_single_notdef( ttface ) ) +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( !ttface->internal->incremental_interface ) +#endif { - FT_TRACE5(( "tt_face_init:" - " Only the `.notdef' glyph has an outline.\n" - " " - " Resetting scalable flag to FALSE.\n" )); + if ( ttface->num_fixed_sizes && + face->glyph_locations && + tt_check_single_notdef( ttface ) ) + { + FT_TRACE5(( "tt_face_init:" + " Only the `.notdef' glyph has an outline.\n" + " " + " Resetting scalable flag to FALSE.\n" )); - ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE; + ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE; + } } - -#endif /* !FT_CONFIG_OPTION_INCREMENTAL */ - } #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT { - FT_Int instance_index = face_index >> 16; + FT_UInt instance_index = (FT_UInt)face_index >> 16; if ( FT_HAS_MULTIPLE_MASTERS( ttface ) && instance_index > 0 ) { - error = TT_Get_MM_Var( face, NULL ); + error = TT_Set_Named_Instance( face, instance_index ); if ( error ) goto Exit; - if ( face->blend->mmvar->namedstyle ) - { - FT_Memory memory = ttface->memory; - - FT_Var_Named_Style* named_style; - FT_String* style_name; - - - /* in `face_index', the instance index starts with value 1 */ - named_style = face->blend->mmvar->namedstyle + instance_index - 1; - error = sfnt->get_name( face, - (FT_UShort)named_style->strid, - &style_name ); - if ( error ) - goto Exit; - - /* set style name; if already set, replace it */ - if ( face->root.style_name ) - FT_FREE( face->root.style_name ); - face->root.style_name = style_name; - - /* finally, select the named instance */ - error = TT_Set_Var_Design( face, - face->blend->mmvar->num_axis, - named_style->coords ); - if ( error ) - goto Exit; - } + tt_apply_mvar( face ); } } #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ -#if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \ - !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER ) - - { - FT_Bool unpatented_hinting; - int i; - - - /* Determine whether unpatented hinting is to be used for this face. */ - unpatented_hinting = FT_BOOL - ( library->debug_hooks[FT_DEBUG_HOOK_UNPATENTED_HINTING] != NULL ); - - for ( i = 0; i < num_params && !face->unpatented_hinting; i++ ) - if ( params[i].tag == FT_PARAM_TAG_UNPATENTED_HINTING ) - unpatented_hinting = TRUE; - - if ( !unpatented_hinting ) - ttface->internal->ignore_unpatented_hinter = TRUE; - } - -#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING && - !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ - /* initialize standard glyph loading routines */ TT_Init_Glyph_Loading( face ); @@ -761,7 +793,7 @@ face->cvt_program_size = 0; #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - tt_done_blend( memory, face->blend ); + tt_done_blend( face ); face->blend = NULL; #endif } @@ -819,14 +851,14 @@ exec->pedantic_hinting = pedantic; { - FT_Size_Metrics* metrics = &exec->metrics; - TT_Size_Metrics* tt_metrics = &exec->tt_metrics; + FT_Size_Metrics* size_metrics = &exec->metrics; + TT_Size_Metrics* tt_metrics = &exec->tt_metrics; - metrics->x_ppem = 0; - metrics->y_ppem = 0; - metrics->x_scale = 0; - metrics->y_scale = 0; + size_metrics->x_ppem = 0; + size_metrics->y_ppem = 0; + size_metrics->x_scale = 0; + size_metrics->y_scale = 0; tt_metrics->ppem = 0; tt_metrics->scale = 0; @@ -849,6 +881,11 @@ FT_TRACE4(( "Executing `fpgm' table.\n" )); error = face->interpreter( exec ); +#ifdef FT_DEBUG_LEVEL_TRACE + if ( error ) + FT_TRACE4(( " interpretation failed with error code 0x%x\n", + error )); +#endif } else error = FT_Err_Ok; @@ -912,8 +949,12 @@ TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 ); FT_TRACE4(( "Executing `prep' table.\n" )); - error = face->interpreter( exec ); +#ifdef FT_DEBUG_LEVEL_TRACE + if ( error ) + FT_TRACE4(( " interpretation failed with error code 0x%x\n", + error )); +#endif } else error = FT_Err_Ok; @@ -1032,17 +1073,17 @@ /* Set default metrics */ { - TT_Size_Metrics* metrics = &size->ttmetrics; + TT_Size_Metrics* tt_metrics = &size->ttmetrics; - metrics->rotated = FALSE; - metrics->stretched = FALSE; + tt_metrics->rotated = FALSE; + tt_metrics->stretched = FALSE; /* set default engine compensation */ - metrics->compensations[0] = 0; /* gray */ - metrics->compensations[1] = 0; /* black */ - metrics->compensations[2] = 0; /* white */ - metrics->compensations[3] = 0; /* reserved */ + tt_metrics->compensations[0] = 0; /* gray */ + tt_metrics->compensations[1] = 0; /* black */ + tt_metrics->compensations[2] = 0; /* white */ + tt_metrics->compensations[3] = 0; /* reserved */ } /* allocate function defs, instruction defs, cvt, and storage area */ @@ -1078,7 +1119,15 @@ } /* Fine, now run the font program! */ + + /* In case of an error while executing `fpgm', we intentionally don't */ + /* clean up immediately – bugs in the `fpgm' are so fundamental that */ + /* all following hinting calls should fail. Additionally, `fpgm' is */ + /* to be executed just once; calling it again is completely useless */ + /* and might even lead to extremely slow behaviour if it is malformed */ + /* (containing an infinite loop, for example). */ error = tt_size_run_fpgm( size, pedantic ); + return error; Exit: if ( error ) @@ -1097,8 +1146,10 @@ if ( size->bytecode_ready < 0 ) error = tt_size_init_bytecode( (FT_Size)size, pedantic ); + else + error = size->bytecode_ready; - if ( error || size->bytecode_ready ) + if ( error ) goto Exit; /* rescale CVT when needed */ @@ -1130,6 +1181,8 @@ error = tt_size_run_prep( size, pedantic ); } + else + error = size->cvt_ready; Exit: return error; @@ -1206,26 +1259,34 @@ /* have been changed. */ /* */ /* <Input> */ - /* size :: A handle to the target size object. */ + /* size :: A handle to the target size object. */ + /* */ + /* only_height :: Only recompute ascender, descender, and height; */ + /* this flag is used for variation fonts where */ + /* `tt_size_reset' is used as an iterator function. */ /* */ FT_LOCAL_DEF( FT_Error ) - tt_size_reset( TT_Size size ) + tt_size_reset( TT_Size size, + FT_Bool only_height ) { TT_Face face; - FT_Error error = FT_Err_Ok; - FT_Size_Metrics* metrics; + FT_Size_Metrics* size_metrics; - size->ttmetrics.valid = FALSE; - face = (TT_Face)size->root.face; - metrics = &size->metrics; + /* nothing to do for CFF2 */ + if ( face->is_cff2 ) + return FT_Err_Ok; + + size->ttmetrics.valid = FALSE; + + size_metrics = &size->hinted_metrics; /* copy the result from base layer */ - *metrics = size->root.metrics; + *size_metrics = size->root.metrics; - if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 ) + if ( size_metrics->x_ppem < 1 || size_metrics->y_ppem < 1 ) return FT_THROW( Invalid_PPem ); /* This bit flag, if set, indicates that the ppems must be */ @@ -1234,48 +1295,66 @@ /* */ if ( face->header.Flags & 8 ) { - metrics->x_scale = FT_DivFix( metrics->x_ppem << 6, - face->root.units_per_EM ); - metrics->y_scale = FT_DivFix( metrics->y_ppem << 6, - face->root.units_per_EM ); + /* the TT spec always asks for ROUND, not FLOOR or CEIL */ + size_metrics->ascender = FT_PIX_ROUND( + FT_MulFix( face->root.ascender, + size_metrics->y_scale ) ); + size_metrics->descender = FT_PIX_ROUND( + FT_MulFix( face->root.descender, + size_metrics->y_scale ) ); + size_metrics->height = FT_PIX_ROUND( + FT_MulFix( face->root.height, + size_metrics->y_scale ) ); + } - metrics->ascender = - FT_PIX_ROUND( FT_MulFix( face->root.ascender, metrics->y_scale ) ); - metrics->descender = - FT_PIX_ROUND( FT_MulFix( face->root.descender, metrics->y_scale ) ); - metrics->height = - FT_PIX_ROUND( FT_MulFix( face->root.height, metrics->y_scale ) ); - metrics->max_advance = - FT_PIX_ROUND( FT_MulFix( face->root.max_advance_width, - metrics->x_scale ) ); + size->ttmetrics.valid = TRUE; + + if ( only_height ) + { + /* we must not recompute the scaling values here since */ + /* `tt_size_reset' was already called (with only_height = 0) */ + return FT_Err_Ok; + } + + if ( face->header.Flags & 8 ) + { + /* base scaling values on integer ppem values, */ + /* as mandated by the TrueType specification */ + size_metrics->x_scale = FT_DivFix( size_metrics->x_ppem << 6, + face->root.units_per_EM ); + size_metrics->y_scale = FT_DivFix( size_metrics->y_ppem << 6, + face->root.units_per_EM ); + + size_metrics->max_advance = FT_PIX_ROUND( + FT_MulFix( face->root.max_advance_width, + size_metrics->x_scale ) ); } /* compute new transformation */ - if ( metrics->x_ppem >= metrics->y_ppem ) + if ( size_metrics->x_ppem >= size_metrics->y_ppem ) { - size->ttmetrics.scale = metrics->x_scale; - size->ttmetrics.ppem = metrics->x_ppem; + size->ttmetrics.scale = size_metrics->x_scale; + size->ttmetrics.ppem = size_metrics->x_ppem; size->ttmetrics.x_ratio = 0x10000L; - size->ttmetrics.y_ratio = FT_DivFix( metrics->y_ppem, - metrics->x_ppem ); + size->ttmetrics.y_ratio = FT_DivFix( size_metrics->y_ppem, + size_metrics->x_ppem ); } else { - size->ttmetrics.scale = metrics->y_scale; - size->ttmetrics.ppem = metrics->y_ppem; - size->ttmetrics.x_ratio = FT_DivFix( metrics->x_ppem, - metrics->y_ppem ); + size->ttmetrics.scale = size_metrics->y_scale; + size->ttmetrics.ppem = size_metrics->y_ppem; + size->ttmetrics.x_ratio = FT_DivFix( size_metrics->x_ppem, + size_metrics->y_ppem ); size->ttmetrics.y_ratio = 0x10000L; } + size->metrics = size_metrics; + #ifdef TT_USE_BYTECODE_INTERPRETER size->cvt_ready = -1; #endif /* TT_USE_BYTECODE_INTERPRETER */ - if ( !error ) - size->ttmetrics.valid = TRUE; - - return error; + return FT_Err_Ok; } @@ -1301,10 +1380,12 @@ TT_Driver driver = (TT_Driver)ttdriver; -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING - driver->interpreter_version = TT_INTERPRETER_VERSION_38; -#else driver->interpreter_version = TT_INTERPRETER_VERSION_35; +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY + driver->interpreter_version = TT_INTERPRETER_VERSION_38; +#endif +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL + driver->interpreter_version = TT_INTERPRETER_VERSION_40; #endif #else /* !TT_USE_BYTECODE_INTERPRETER */ diff --git a/src/3rdparty/freetype/src/truetype/ttobjs.h b/src/3rdparty/freetype/src/truetype/ttobjs.h index 9396089a99..38fa30e4e9 100644 --- a/src/3rdparty/freetype/src/truetype/ttobjs.h +++ b/src/3rdparty/freetype/src/truetype/ttobjs.h @@ -4,7 +4,7 @@ /* */ /* Objects manager (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTOBJS_H__ -#define __TTOBJS_H__ +#ifndef TTOBJS_H_ +#define TTOBJS_H_ #include <ft2build.h> @@ -72,10 +72,6 @@ FT_BEGIN_HEADER FT_UnitVector projVector; FT_UnitVector freeVector; -#ifdef TT_CONFIG_OPTION_UNPATENTED_HINTING - FT_Bool both_x_axis; -#endif - FT_Long loop; FT_F26Dot6 minimum_distance; FT_Int round_state; @@ -282,7 +278,8 @@ FT_BEGIN_HEADER /* we have our own copy of metrics so that we can modify */ /* it without affecting auto-hinting (when used) */ - FT_Size_Metrics metrics; + FT_Size_Metrics* metrics; /* for the current rendering mode */ + FT_Size_Metrics hinted_metrics; /* for the hinted rendering mode */ TT_Size_Metrics ttmetrics; @@ -290,6 +287,8 @@ FT_BEGIN_HEADER #ifdef TT_USE_BYTECODE_INTERPRETER + FT_Long point_size; /* for the `MPS' bytecode instruction */ + FT_UInt num_function_defs; /* number of function definitions */ FT_UInt max_function_defs; TT_DefArray function_defs; /* table of function definitions */ @@ -391,7 +390,8 @@ FT_BEGIN_HEADER #endif /* TT_USE_BYTECODE_INTERPRETER */ FT_LOCAL( FT_Error ) - tt_size_reset( TT_Size size ); + tt_size_reset( TT_Size size, + FT_Bool only_height ); /*************************************************************************/ @@ -419,7 +419,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTOBJS_H__ */ +#endif /* TTOBJS_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/truetype/ttpic.c b/src/3rdparty/freetype/src/truetype/ttpic.c index 242a6b76dd..cdbb80639e 100644 --- a/src/3rdparty/freetype/src/truetype/ttpic.c +++ b/src/3rdparty/freetype/src/truetype/ttpic.c @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for truetype module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2018 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/src/truetype/ttpic.h b/src/3rdparty/freetype/src/truetype/ttpic.h index 076ae56efa..df878ae6f1 100644 --- a/src/3rdparty/freetype/src/truetype/ttpic.h +++ b/src/3rdparty/freetype/src/truetype/ttpic.h @@ -4,7 +4,7 @@ /* */ /* The FreeType position independent code services for truetype module. */ /* */ -/* Copyright 2009-2015 by */ +/* Copyright 2009-2018 by */ /* Oran Agra and Mickey Gabel. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTPIC_H__ -#define __TTPIC_H__ +#ifndef TTPIC_H_ +#define TTPIC_H_ #include FT_INTERNAL_PIC_H @@ -25,15 +25,17 @@ #ifndef FT_CONFIG_OPTION_PIC -#define TT_SERVICES_GET tt_services -#define TT_SERVICE_GX_MULTI_MASTERS_GET tt_service_gx_multi_masters -#define TT_SERVICE_TRUETYPE_GLYF_GET tt_service_truetype_glyf -#define TT_SERVICE_PROPERTIES_GET tt_service_properties +#define TT_SERVICES_GET tt_services +#define TT_SERVICE_GX_MULTI_MASTERS_GET tt_service_gx_multi_masters +#define TT_SERVICE_METRICS_VARIATIONS_GET tt_service_metrics_variations +#define TT_SERVICE_TRUETYPE_GLYF_GET tt_service_truetype_glyf +#define TT_SERVICE_PROPERTIES_GET tt_service_properties #else /* FT_CONFIG_OPTION_PIC */ #include FT_MULTIPLE_MASTERS_H #include FT_SERVICE_MULTIPLE_MASTERS_H +#include FT_SERVICE_METRICS_VARIATIONS_H #include FT_SERVICE_TRUETYPE_GLYF_H #include FT_SERVICE_PROPERTIES_H @@ -42,12 +44,13 @@ FT_BEGIN_HEADER typedef struct TTModulePIC_ { - FT_ServiceDescRec* tt_services; + FT_ServiceDescRec* tt_services; #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - FT_Service_MultiMastersRec tt_service_gx_multi_masters; + FT_Service_MultiMastersRec tt_service_gx_multi_masters; + FT_Service_MetricsVariationsRec tt_service_metrics_variations; #endif - FT_Service_TTGlyfRec tt_service_truetype_glyf; - FT_Service_PropertiesRec tt_service_properties; + FT_Service_TTGlyfRec tt_service_truetype_glyf; + FT_Service_PropertiesRec tt_service_properties; } TTModulePIC; @@ -56,6 +59,8 @@ FT_BEGIN_HEADER ( (TTModulePIC*)((lib)->pic_container.truetype) ) #define TT_SERVICES_GET \ ( GET_PIC( library )->tt_services ) +#define TT_SERVICE_METRICS_VARIATIONS_GET \ + ( GET_PIC( library )->tt_service_metrics_variations ) #define TT_SERVICE_GX_MULTI_MASTERS_GET \ ( GET_PIC( library )->tt_service_gx_multi_masters ) #define TT_SERVICE_TRUETYPE_GLYF_GET \ @@ -77,7 +82,7 @@ FT_END_HEADER /* */ -#endif /* __TTPIC_H__ */ +#endif /* TTPIC_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/truetype/ttpload.c b/src/3rdparty/freetype/src/truetype/ttpload.c index 4647c938ae..d9526ad082 100644 --- a/src/3rdparty/freetype/src/truetype/ttpload.c +++ b/src/3rdparty/freetype/src/truetype/ttpload.c @@ -4,7 +4,7 @@ /* */ /* TrueType-specific tables loader (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -73,9 +73,21 @@ /* it is possible that a font doesn't have a glyf table at all */ /* or its size is zero */ if ( FT_ERR_EQ( error, Table_Missing ) ) - face->glyf_len = 0; + { + face->glyf_len = 0; + face->glyf_offset = 0; + } else if ( error ) goto Exit; + else + { +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( face->root.internal->incremental_interface ) + face->glyf_offset = 0; + else +#endif + face->glyf_offset = FT_STREAM_POS(); + } FT_TRACE2(( "Locations " )); error = face->goto_table( face, TTAG_loca, stream, &table_len ); @@ -92,8 +104,7 @@ if ( table_len >= 0x40000L ) { FT_TRACE2(( "table too large\n" )); - error = FT_THROW( Invalid_Table ); - goto Exit; + table_len = 0x3FFFFL; } face->num_locations = table_len >> shift; } @@ -104,8 +115,7 @@ if ( table_len >= 0x20000L ) { FT_TRACE2(( "table too large\n" )); - error = FT_THROW( Invalid_Table ); - goto Exit; + table_len = 0x1FFFFL; } face->num_locations = table_len >> shift; } @@ -124,8 +134,9 @@ TT_Table entry = face->dir_tables; TT_Table limit = entry + face->num_tables; - FT_Long pos = (FT_Long)FT_STREAM_POS(); - FT_Long dist = 0x7FFFFFFFL; + FT_Long pos = (FT_Long)FT_STREAM_POS(); + FT_Long dist = 0x7FFFFFFFL; + FT_Bool found = 0; /* compute the distance to next table in font file */ @@ -135,10 +146,13 @@ if ( diff > 0 && diff < dist ) - dist = diff; + { + dist = diff; + found = 1; + } } - if ( entry == limit ) + if ( !found ) { /* `loca' is the last table */ dist = (FT_Long)stream->size - pos; @@ -218,12 +232,13 @@ } } - /* Check broken location data */ + /* Check broken location data. */ if ( pos1 > face->glyf_len ) { FT_TRACE1(( "tt_face_get_location:" - " too large offset=0x%08lx found for gid=0x%04lx," - " exceeding the end of glyf table (0x%08lx)\n", + " too large offset (0x%08lx) found for glyph index %ld,\n" + " " + " exceeding the end of `glyf' table (0x%08lx)\n", pos1, gindex, face->glyf_len )); *asize = 0; return 0; @@ -231,11 +246,26 @@ if ( pos2 > face->glyf_len ) { - FT_TRACE1(( "tt_face_get_location:" - " too large offset=0x%08lx found for gid=0x%04lx," - " truncate at the end of glyf table (0x%08lx)\n", - pos2, gindex + 1, face->glyf_len )); - pos2 = face->glyf_len; + /* We try to sanitize the last `loca' entry. */ + if ( gindex == face->num_locations - 2 ) + { + FT_TRACE1(( "tt_face_get_location:" + " too large size (%ld bytes) found for glyph index %ld,\n" + " " + " truncating at the end of `glyf' table to %ld bytes\n", + pos2 - pos1, gindex, face->glyf_len - pos1 )); + pos2 = face->glyf_len; + } + else + { + FT_TRACE1(( "tt_face_get_location:" + " too large offset (0x%08lx) found for glyph index %ld,\n" + " " + " exceeding the end of `glyf' table (0x%08lx)\n", + pos2, gindex + 1, face->glyf_len )); + *asize = 0; + return 0; + } } /* The `loca' table must be ordered; it refers to the length of */ @@ -494,7 +524,7 @@ { FT_Error error; FT_Memory memory = stream->memory; - FT_UInt version, nn, num_records; + FT_UInt nn, num_records; FT_ULong table_size, record_size; FT_Byte* p; FT_Byte* limit; @@ -511,7 +541,10 @@ p = face->hdmx_table; limit = p + table_size; - version = FT_NEXT_USHORT( p ); + /* Given that `hdmx' tables are losing its importance (for example, */ + /* variation fonts introduced in OpenType 1.8 must not have this */ + /* table) we no longer test for a correct `version' field. */ + p += 2; num_records = FT_NEXT_USHORT( p ); record_size = FT_NEXT_ULONG( p ); @@ -530,10 +563,10 @@ record_size &= 0xFFFFU; /* The limit for `num_records' is a heuristic value. */ - if ( version != 0 || - num_records > 255 || - record_size > 0x10001L || - record_size < 4 ) + if ( num_records > 255 || + ( num_records > 0 && + ( record_size > 0x10001L || + record_size < 4 ) ) ) { error = FT_THROW( Invalid_File_Format ); goto Fail; diff --git a/src/3rdparty/freetype/src/truetype/ttpload.h b/src/3rdparty/freetype/src/truetype/ttpload.h index bc92369827..fa12527247 100644 --- a/src/3rdparty/freetype/src/truetype/ttpload.h +++ b/src/3rdparty/freetype/src/truetype/ttpload.h @@ -4,7 +4,7 @@ /* */ /* TrueType-specific tables loader (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTPLOAD_H__ -#define __TTPLOAD_H__ +#ifndef TTPLOAD_H_ +#define TTPLOAD_H_ #include <ft2build.h> @@ -69,7 +69,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __TTPLOAD_H__ */ +#endif /* TTPLOAD_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/truetype/ttsubpix.c b/src/3rdparty/freetype/src/truetype/ttsubpix.c index 0d391e95a0..d94bcc8b50 100644 --- a/src/3rdparty/freetype/src/truetype/ttsubpix.c +++ b/src/3rdparty/freetype/src/truetype/ttsubpix.c @@ -4,7 +4,7 @@ /* */ /* TrueType Subpixel Hinting. */ /* */ -/* Copyright 2010-2015 by */ +/* Copyright 2010-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,12 +22,13 @@ #include FT_INTERNAL_SFNT_H #include FT_TRUETYPE_TAGS_H #include FT_OUTLINE_H -#include FT_TRUETYPE_DRIVER_H +#include FT_DRIVER_H #include "ttsubpix.h" -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#if defined( TT_USE_BYTECODE_INTERPRETER ) && \ + defined( TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY ) /*************************************************************************/ /* */ @@ -752,24 +753,24 @@ /* Does font name match rule family? */ - if ( strcmp( detected_font_name, rule_font_name ) == 0 ) + if ( ft_strcmp( detected_font_name, rule_font_name ) == 0 ) return TRUE; /* Is font name a wildcard ""? */ - if ( strcmp( rule_font_name, "" ) == 0 ) + if ( ft_strcmp( rule_font_name, "" ) == 0 ) return TRUE; /* Is font name contained in a class list? */ for ( i = 0; i < FAMILY_CLASS_RULES_SIZE; i++ ) { - if ( strcmp( FAMILY_CLASS_Rules[i].name, rule_font_name ) == 0 ) + if ( ft_strcmp( FAMILY_CLASS_Rules[i].name, rule_font_name ) == 0 ) { for ( j = 0; j < SPH_MAX_CLASS_MEMBERS; j++ ) { - if ( strcmp( FAMILY_CLASS_Rules[i].member[j], "" ) == 0 ) + if ( ft_strcmp( FAMILY_CLASS_Rules[i].member[j], "" ) == 0 ) continue; - if ( strcmp( FAMILY_CLASS_Rules[i].member[j], - detected_font_name ) == 0 ) + if ( ft_strcmp( FAMILY_CLASS_Rules[i].member[j], + detected_font_name ) == 0 ) return TRUE; } } @@ -787,24 +788,24 @@ /* Does font style match rule style? */ - if ( strcmp( detected_font_style, rule_font_style ) == 0 ) + if ( ft_strcmp( detected_font_style, rule_font_style ) == 0 ) return TRUE; /* Is font style a wildcard ""? */ - if ( strcmp( rule_font_style, "" ) == 0 ) + if ( ft_strcmp( rule_font_style, "" ) == 0 ) return TRUE; /* Is font style contained in a class list? */ for ( i = 0; i < STYLE_CLASS_RULES_SIZE; i++ ) { - if ( strcmp( STYLE_CLASS_Rules[i].name, rule_font_style ) == 0 ) + if ( ft_strcmp( STYLE_CLASS_Rules[i].name, rule_font_style ) == 0 ) { for ( j = 0; j < SPH_MAX_CLASS_MEMBERS; j++ ) { - if ( strcmp( STYLE_CLASS_Rules[i].member[j], "" ) == 0 ) + if ( ft_strcmp( STYLE_CLASS_Rules[i].member[j], "" ) == 0 ) continue; - if ( strcmp( STYLE_CLASS_Rules[i].member[j], - detected_font_style ) == 0 ) + if ( ft_strcmp( STYLE_CLASS_Rules[i].member[j], + detected_font_style ) == 0 ) return TRUE; } } @@ -905,7 +906,7 @@ { TT_Face face = loader->face; FT_String* family = face->root.family_name; - FT_UInt ppem = loader->size->metrics.x_ppem; + FT_UInt ppem = loader->size->metrics->x_ppem; FT_String* style = face->root.style_name; @@ -1000,12 +1001,14 @@ } } -#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#else /* !(TT_USE_BYTECODE_INTERPRETER && */ + /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY) */ /* ANSI C doesn't like empty source files */ typedef int _tt_subpix_dummy; -#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* !(TT_USE_BYTECODE_INTERPRETER && */ + /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY) */ /* END */ diff --git a/src/3rdparty/freetype/src/truetype/ttsubpix.h b/src/3rdparty/freetype/src/truetype/ttsubpix.h index 9151aa3250..1070bb016f 100644 --- a/src/3rdparty/freetype/src/truetype/ttsubpix.h +++ b/src/3rdparty/freetype/src/truetype/ttsubpix.h @@ -4,7 +4,7 @@ /* */ /* TrueType Subpixel Hinting. */ /* */ -/* Copyright 2010-2015 by */ +/* Copyright 2010-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __TTSUBPIX_H__ -#define __TTSUBPIX_H__ +#ifndef TTSUBPIX_H_ +#define TTSUBPIX_H_ #include <ft2build.h> #include "ttobjs.h" @@ -27,7 +27,7 @@ FT_BEGIN_HEADER -#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING +#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY /*************************************************************************/ /* */ @@ -100,11 +100,12 @@ FT_BEGIN_HEADER #define SPH_OPTION_SET_COMPATIBLE_WIDTHS FALSE #define SPH_OPTION_SET_RASTERIZER_VERSION 38 -#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */ +#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */ FT_END_HEADER -#endif /* __TTSUBPIX_H__ */ +#endif /* TTSUBPIX_H_ */ + /* END */ diff --git a/src/3rdparty/freetype/src/type1/Jamfile b/src/3rdparty/freetype/src/type1/Jamfile index d1a3af57e9..b94b7d0aae 100644 --- a/src/3rdparty/freetype/src/type1/Jamfile +++ b/src/3rdparty/freetype/src/type1/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/type1 Jamfile # -# Copyright 2001-2015 by +# Copyright 2001-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/type1/module.mk b/src/3rdparty/freetype/src/type1/module.mk index feb3459d87..3fea5cc16f 100644 --- a/src/3rdparty/freetype/src/type1/module.mk +++ b/src/3rdparty/freetype/src/type1/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2015 by +# Copyright 1996-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/type1/rules.mk b/src/3rdparty/freetype/src/type1/rules.mk index fbd0543531..cb1a142860 100644 --- a/src/3rdparty/freetype/src/type1/rules.mk +++ b/src/3rdparty/freetype/src/type1/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2015 by +# Copyright 1996-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/type1/t1afm.c b/src/3rdparty/freetype/src/type1/t1afm.c index 7f32059f85..61053d9a64 100644 --- a/src/3rdparty/freetype/src/type1/t1afm.c +++ b/src/3rdparty/freetype/src/type1/t1afm.c @@ -4,7 +4,7 @@ /* */ /* AFM support for Type 1 fonts (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -24,6 +24,8 @@ #include "t1errors.h" +#ifndef T1_CONFIG_OPTION_NO_AFM + /*************************************************************************/ /* */ /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ @@ -197,7 +199,7 @@ /* encoding of first glyph (1 byte) */ /* encoding of second glyph (1 byte) */ /* offset (little-endian short) */ - for ( ; p < limit ; p += 4 ) + for ( ; p < limit; p += 4 ) { kp->index1 = FT_Get_Char_Index( t1_face, p[0] ); kp->index2 = FT_Get_Char_Index( t1_face, p[1] ); @@ -208,7 +210,7 @@ kp++; } - if ( oldcharmap != NULL ) + if ( oldcharmap ) error = FT_Set_Charmap( t1_face, oldcharmap ); if ( error ) goto Exit; @@ -239,9 +241,19 @@ AFM_ParserRec parser; AFM_FontInfo fi = NULL; FT_Error error = FT_ERR( Unknown_File_Format ); - T1_Font t1_font = &( (T1_Face)t1_face )->type1; + T1_Face face = (T1_Face)t1_face; + T1_Font t1_font = &face->type1; + if ( face->afm_data ) + { + FT_TRACE1(( "T1_Read_Metrics:" + " Freeing previously attached metrics data.\n" )); + T1_Done_Metrics( memory, (AFM_FontInfo)face->afm_data ); + + face->afm_data = NULL; + } + if ( FT_NEW( fi ) || FT_FRAME_ENTER( stream->size ) ) goto Exit; @@ -250,7 +262,7 @@ fi->Ascender = t1_font->font_bbox.yMax; fi->Descender = t1_font->font_bbox.yMin; - psaux = (PSAux_Service)( (T1_Face)t1_face )->psaux; + psaux = (PSAux_Service)face->psaux; if ( psaux->afm_parser_funcs ) { error = psaux->afm_parser_funcs->init( &parser, @@ -298,15 +310,15 @@ if ( fi->NumKernPair ) { t1_face->face_flags |= FT_FACE_FLAG_KERNING; - ( (T1_Face)t1_face )->afm_data = fi; - fi = NULL; + face->afm_data = fi; + fi = NULL; } } FT_FRAME_EXIT(); Exit: - if ( fi != NULL ) + if ( fi ) T1_Done_Metrics( memory, fi ); return error; @@ -392,5 +404,12 @@ return FT_Err_Ok; } +#else /* T1_CONFIG_OPTION_NO_AFM */ + + /* ANSI C doesn't like empty source files */ + typedef int _t1_afm_dummy; + +#endif /* T1_CONFIG_OPTION_NO_AFM */ + /* END */ diff --git a/src/3rdparty/freetype/src/type1/t1afm.h b/src/3rdparty/freetype/src/type1/t1afm.h index 0f42f3e3a8..cb8d302b4d 100644 --- a/src/3rdparty/freetype/src/type1/t1afm.h +++ b/src/3rdparty/freetype/src/type1/t1afm.h @@ -4,7 +4,7 @@ /* */ /* AFM support for Type 1 fonts (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1AFM_H__ -#define __T1AFM_H__ +#ifndef T1AFM_H_ +#define T1AFM_H_ #include <ft2build.h> #include "t1objs.h" @@ -48,7 +48,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1AFM_H__ */ +#endif /* T1AFM_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/type1/t1driver.c b/src/3rdparty/freetype/src/type1/t1driver.c index 571f2d2f8c..029b410b47 100644 --- a/src/3rdparty/freetype/src/type1/t1driver.c +++ b/src/3rdparty/freetype/src/type1/t1driver.c @@ -4,7 +4,7 @@ /* */ /* Type 1 driver interface (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -29,6 +29,9 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_HASH_H +#include FT_INTERNAL_POSTSCRIPT_PROPS_H +#include FT_DRIVER_H #include FT_SERVICE_MULTIPLE_MASTERS_H #include FT_SERVICE_GLYPH_DICT_H @@ -36,6 +39,7 @@ #include FT_SERVICE_POSTSCRIPT_NAME_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H #include FT_SERVICE_POSTSCRIPT_INFO_H +#include FT_SERVICE_PROPERTIES_H #include FT_SERVICE_KERNING_H @@ -87,8 +91,8 @@ static const FT_Service_GlyphDictRec t1_service_glyph_dict = { - (FT_GlyphDict_GetNameFunc) t1_get_glyph_name, - (FT_GlyphDict_NameIndexFunc)t1_get_name_index + (FT_GlyphDict_GetNameFunc) t1_get_glyph_name, /* get_name */ + (FT_GlyphDict_NameIndexFunc)t1_get_name_index /* name_index */ }; @@ -106,7 +110,7 @@ static const FT_Service_PsFontNameRec t1_service_ps_name = { - (FT_PsName_GetFunc)t1_get_ps_name + (FT_PsName_GetFunc)t1_get_ps_name /* get_ps_font_name */ }; @@ -118,11 +122,17 @@ #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT static const FT_Service_MultiMastersRec t1_service_multi_masters = { - (FT_Get_MM_Func) T1_Get_Multi_Master, - (FT_Set_MM_Design_Func) T1_Set_MM_Design, - (FT_Set_MM_Blend_Func) T1_Set_MM_Blend, - (FT_Get_MM_Var_Func) T1_Get_MM_Var, - (FT_Set_Var_Design_Func)T1_Set_Var_Design + (FT_Get_MM_Func) T1_Get_Multi_Master, /* get_mm */ + (FT_Set_MM_Design_Func) T1_Set_MM_Design, /* set_mm_design */ + (FT_Set_MM_Blend_Func) T1_Set_MM_Blend, /* set_mm_blend */ + (FT_Get_MM_Blend_Func) T1_Get_MM_Blend, /* get_mm_blend */ + (FT_Get_MM_Var_Func) T1_Get_MM_Var, /* get_mm_var */ + (FT_Set_Var_Design_Func)T1_Set_Var_Design, /* set_var_design */ + (FT_Get_Var_Design_Func)T1_Get_Var_Design, /* get_var_design */ + (FT_Set_Instance_Func) T1_Reset_MM_Blend, /* set_instance */ + + (FT_Get_Var_Blend_Func) NULL, /* get_var_blend */ + (FT_Done_Blend_Func) T1_Done_Blend /* done_blend */ }; #endif @@ -329,13 +339,37 @@ break; case PS_DICT_SUBR: - if ( idx < (FT_UInt)type1->num_subrs ) { - retval = type1->subrs_len[idx] + 1; - if ( value && value_len >= retval ) + FT_Bool ok = 0; + + + if ( type1->subrs_hash ) { - ft_memcpy( value, (void *)( type1->subrs[idx] ), retval - 1 ); - ((FT_Char *)value)[retval - 1] = (FT_Char)'\0'; + /* convert subr index to array index */ + size_t* val = ft_hash_num_lookup( (FT_Int)idx, + type1->subrs_hash ); + + + if ( val ) + { + idx = *val; + ok = 1; + } + } + else + { + if ( idx < (FT_UInt)type1->num_subrs ) + ok = 1; + } + + if ( ok ) + { + retval = type1->subrs_len[idx] + 1; + if ( value && value_len >= retval ) + { + ft_memcpy( value, (void *)( type1->subrs[idx] ), retval - 1 ); + ((FT_Char *)value)[retval - 1] = (FT_Char)'\0'; + } } } break; @@ -567,22 +601,34 @@ static const FT_Service_PsInfoRec t1_service_ps_info = { - (PS_GetFontInfoFunc) t1_ps_get_font_info, - (PS_GetFontExtraFunc) t1_ps_get_font_extra, - (PS_HasGlyphNamesFunc) t1_ps_has_glyph_names, - (PS_GetFontPrivateFunc)t1_ps_get_font_private, - (PS_GetFontValueFunc) t1_ps_get_font_value, + (PS_GetFontInfoFunc) t1_ps_get_font_info, /* ps_get_font_info */ + (PS_GetFontExtraFunc) t1_ps_get_font_extra, /* ps_get_font_extra */ + (PS_HasGlyphNamesFunc) t1_ps_has_glyph_names, /* ps_has_glyph_names */ + (PS_GetFontPrivateFunc)t1_ps_get_font_private, /* ps_get_font_private */ + (PS_GetFontValueFunc) t1_ps_get_font_value, /* ps_get_font_value */ }; #ifndef T1_CONFIG_OPTION_NO_AFM static const FT_Service_KerningRec t1_service_kerning = { - T1_Get_Track_Kerning, + T1_Get_Track_Kerning, /* get_track */ }; #endif + /* + * PROPERTY SERVICE + * + */ + + FT_DEFINE_SERVICE_PROPERTIESREC( + t1_service_properties, + + (FT_Properties_SetFunc)ps_property_set, /* set_property */ + (FT_Properties_GetFunc)ps_property_get ) /* get_property */ + + /* * SERVICE LIST * @@ -594,6 +640,7 @@ { FT_SERVICE_ID_GLYPH_DICT, &t1_service_glyph_dict }, { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_TYPE_1 }, { FT_SERVICE_ID_POSTSCRIPT_INFO, &t1_service_ps_info }, + { FT_SERVICE_ID_PROPERTIES, &t1_service_properties }, #ifndef T1_CONFIG_OPTION_NO_AFM { FT_SERVICE_ID_KERNING, &t1_service_kerning }, @@ -683,42 +730,43 @@ FT_MODULE_DRIVER_SCALABLE | FT_MODULE_DRIVER_HAS_HINTER, - sizeof ( FT_DriverRec ), + sizeof ( PS_DriverRec ), "type1", 0x10000L, 0x20000L, - 0, /* format interface */ + NULL, /* module-specific interface */ - T1_Driver_Init, - T1_Driver_Done, - Get_Interface, + T1_Driver_Init, /* FT_Module_Constructor module_init */ + T1_Driver_Done, /* FT_Module_Destructor module_done */ + Get_Interface, /* FT_Module_Requester get_interface */ }, sizeof ( T1_FaceRec ), sizeof ( T1_SizeRec ), sizeof ( T1_GlyphSlotRec ), - T1_Face_Init, - T1_Face_Done, - T1_Size_Init, - T1_Size_Done, - T1_GlyphSlot_Init, - T1_GlyphSlot_Done, + T1_Face_Init, /* FT_Face_InitFunc init_face */ + T1_Face_Done, /* FT_Face_DoneFunc done_face */ + T1_Size_Init, /* FT_Size_InitFunc init_size */ + T1_Size_Done, /* FT_Size_DoneFunc done_size */ + T1_GlyphSlot_Init, /* FT_Slot_InitFunc init_slot */ + T1_GlyphSlot_Done, /* FT_Slot_DoneFunc done_slot */ - T1_Load_Glyph, + T1_Load_Glyph, /* FT_Slot_LoadFunc load_glyph */ #ifdef T1_CONFIG_OPTION_NO_AFM - 0, /* FT_Face_GetKerningFunc */ - 0, /* FT_Face_AttachFunc */ + NULL, /* FT_Face_GetKerningFunc get_kerning */ + NULL, /* FT_Face_AttachFunc attach_file */ #else - Get_Kerning, - T1_Read_Metrics, + Get_Kerning, /* FT_Face_GetKerningFunc get_kerning */ + T1_Read_Metrics, /* FT_Face_AttachFunc attach_file */ #endif - T1_Get_Advances, - T1_Size_Request, - 0 /* FT_Size_SelectFunc */ + T1_Get_Advances, /* FT_Face_GetAdvancesFunc get_advances */ + + T1_Size_Request, /* FT_Size_RequestFunc request_size */ + NULL /* FT_Size_SelectFunc select_size */ }; diff --git a/src/3rdparty/freetype/src/type1/t1driver.h b/src/3rdparty/freetype/src/type1/t1driver.h index 34bcf81ccf..2b1507233d 100644 --- a/src/3rdparty/freetype/src/type1/t1driver.h +++ b/src/3rdparty/freetype/src/type1/t1driver.h @@ -4,7 +4,7 @@ /* */ /* High-level Type 1 driver interface (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1DRIVER_H__ -#define __T1DRIVER_H__ +#ifndef T1DRIVER_H_ +#define T1DRIVER_H_ #include <ft2build.h> @@ -36,7 +36,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1DRIVER_H__ */ +#endif /* T1DRIVER_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/type1/t1errors.h b/src/3rdparty/freetype/src/type1/t1errors.h index fc7a9bd64e..9e0151b957 100644 --- a/src/3rdparty/freetype/src/type1/t1errors.h +++ b/src/3rdparty/freetype/src/type1/t1errors.h @@ -4,7 +4,7 @@ /* */ /* Type 1 error codes (specification only). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __T1ERRORS_H__ -#define __T1ERRORS_H__ +#ifndef T1ERRORS_H_ +#define T1ERRORS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX T1_Err_ @@ -35,7 +35,7 @@ #include FT_ERRORS_H -#endif /* __T1ERRORS_H__ */ +#endif /* T1ERRORS_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/type1/t1gload.c b/src/3rdparty/freetype/src/type1/t1gload.c index 85ada2ea6a..87d40e7566 100644 --- a/src/3rdparty/freetype/src/type1/t1gload.c +++ b/src/3rdparty/freetype/src/type1/t1gload.c @@ -4,7 +4,7 @@ /* */ /* Type 1 Glyph Loader (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,6 +23,8 @@ #include FT_INTERNAL_STREAM_H #include FT_OUTLINE_H #include FT_INTERNAL_POSTSCRIPT_AUX_H +#include FT_INTERNAL_CFF_TYPES_H +#include FT_DRIVER_H #include "t1errors.h" @@ -37,37 +39,28 @@ #define FT_COMPONENT trace_t1gload - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - /********** *********/ - /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ - /********** *********/ - /********** The following code is in charge of computing *********/ - /********** the maximum advance width of the font. It *********/ - /********** quickly processes each glyph charstring to *********/ - /********** extract the value from either a `sbw' or `seac' *********/ - /********** operator. *********/ - /********** *********/ - /*************************************************************************/ - /*************************************************************************/ - /*************************************************************************/ - - static FT_Error T1_Parse_Glyph_And_Get_Char_String( T1_Decoder decoder, FT_UInt glyph_index, - FT_Data* char_string ) + FT_Data* char_string, + FT_Bool* force_scaling ) { T1_Face face = (T1_Face)decoder->builder.face; T1_Font type1 = &face->type1; FT_Error error = FT_Err_Ok; + PSAux_Service psaux = (PSAux_Service)face->psaux; + const T1_Decoder_Funcs decoder_funcs = psaux->t1_decoder_funcs; + PS_Decoder psdecoder; + #ifdef FT_CONFIG_OPTION_INCREMENTAL FT_Incremental_InterfaceRec *inc = face->root.internal->incremental_interface; #endif +#ifdef T1_CONFIG_OPTION_OLD_ENGINE + PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( face ); +#endif decoder->font_matrix = type1->font_matrix; decoder->font_offset = type1->font_offset; @@ -90,9 +83,56 @@ } if ( !error ) - error = decoder->funcs.parse_charstrings( - decoder, (FT_Byte*)char_string->pointer, - (FT_UInt)char_string->length ); + { + /* choose which renderer to use */ +#ifdef T1_CONFIG_OPTION_OLD_ENGINE + if ( driver->hinting_engine == FT_HINTING_FREETYPE || + decoder->builder.metrics_only ) + error = decoder_funcs->parse_charstrings_old( + decoder, + (FT_Byte*)char_string->pointer, + (FT_UInt)char_string->length ); +#else + if ( decoder->builder.metrics_only ) + error = decoder_funcs->parse_metrics( + decoder, + (FT_Byte*)char_string->pointer, + (FT_UInt)char_string->length ); +#endif + else + { + CFF_SubFontRec subfont; + + + psaux->ps_decoder_init( &psdecoder, decoder, TRUE ); + + psaux->t1_make_subfont( FT_FACE( face ), + &face->type1.private_dict, &subfont ); + psdecoder.current_subfont = &subfont; + + error = decoder_funcs->parse_charstrings( + &psdecoder, + (FT_Byte*)char_string->pointer, + (FT_ULong)char_string->length ); + + /* Adobe's engine uses 16.16 numbers everywhere; */ + /* as a consequence, glyphs larger than 2000ppem get rejected */ + if ( FT_ERR_EQ( error, Glyph_Too_Big ) ) + { + /* this time, we retry unhinted and scale up the glyph later on */ + /* (the engine uses and sets the hardcoded value 0x10000 / 64 = */ + /* 0x400 for both `x_scale' and `y_scale' in this case) */ + ((T1_GlyphSlot)decoder->builder.glyph)->hint = FALSE; + + *force_scaling = TRUE; + + error = decoder_funcs->parse_charstrings( + &psdecoder, + (FT_Byte*)char_string->pointer, + (FT_ULong)char_string->length ); + } + } + } #ifdef FT_CONFIG_OPTION_INCREMENTAL @@ -126,8 +166,10 @@ FT_UInt glyph_index ) { FT_Data glyph_data; - FT_Error error = T1_Parse_Glyph_And_Get_Char_String( - decoder, glyph_index, &glyph_data ); + FT_Bool force_scaling = FALSE; + FT_Error error = T1_Parse_Glyph_And_Get_Char_String( + decoder, glyph_index, &glyph_data, + &force_scaling ); #ifdef FT_CONFIG_OPTION_INCREMENTAL @@ -149,6 +191,23 @@ } + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + /********** *********/ + /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/ + /********** *********/ + /********** The following code is in charge of computing *********/ + /********** the maximum advance width of the font. It *********/ + /********** quickly processes each glyph charstring to *********/ + /********** extract the value from either a `sbw' or `seac' *********/ + /********** operator. *********/ + /********** *********/ + /*************************************************************************/ + /*************************************************************************/ + /*************************************************************************/ + + FT_LOCAL_DEF( FT_Error ) T1_Compute_Max_Advance( T1_Face face, FT_Pos* max_advance ) @@ -183,6 +242,7 @@ decoder.num_subrs = type1->num_subrs; decoder.subrs = type1->subrs; decoder.subrs_len = type1->subrs_len; + decoder.subrs_hash = type1->subrs_hash; decoder.buildchar = face->buildchar; decoder.len_buildchar = face->len_buildchar; @@ -245,9 +305,10 @@ decoder.builder.metrics_only = 1; decoder.builder.load_points = 0; - decoder.num_subrs = type1->num_subrs; - decoder.subrs = type1->subrs; - decoder.subrs_len = type1->subrs_len; + decoder.num_subrs = type1->num_subrs; + decoder.subrs = type1->subrs; + decoder.subrs_len = type1->subrs_len; + decoder.subrs_hash = type1->subrs_hash; decoder.buildchar = face->buildchar; decoder.len_buildchar = face->len_buildchar; @@ -276,6 +337,8 @@ T1_DecoderRec decoder; T1_Face face = (T1_Face)t1glyph->face; FT_Bool hinting; + FT_Bool scaled; + FT_Bool force_scaling = FALSE; T1_Font type1 = &face->type1; PSAux_Service psaux = (PSAux_Service)face->psaux; const T1_Decoder_Funcs decoder_funcs = psaux->t1_decoder_funcs; @@ -323,7 +386,10 @@ hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 && ( load_flags & FT_LOAD_NO_HINTING ) == 0 ); + scaled = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ); + glyph->hint = hinting; + glyph->scaled = scaled; t1glyph->format = FT_GLYPH_FORMAT_OUTLINE; error = decoder_funcs->init( &decoder, @@ -346,19 +412,22 @@ decoder.num_subrs = type1->num_subrs; decoder.subrs = type1->subrs; decoder.subrs_len = type1->subrs_len; + decoder.subrs_hash = type1->subrs_hash; decoder.buildchar = face->buildchar; decoder.len_buildchar = face->len_buildchar; /* now load the unscaled outline */ error = T1_Parse_Glyph_And_Get_Char_String( &decoder, glyph_index, - &glyph_data ); + &glyph_data, + &force_scaling ); if ( error ) goto Exit; #ifdef FT_CONFIG_OPTION_INCREMENTAL glyph_data_loaded = 1; #endif + hinting = glyph->hint; font_matrix = decoder.font_matrix; font_offset = decoder.font_offset; @@ -448,7 +517,7 @@ } #endif - if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 ) + if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || force_scaling ) { /* scale the outline and the metrics */ FT_Int n; diff --git a/src/3rdparty/freetype/src/type1/t1gload.h b/src/3rdparty/freetype/src/type1/t1gload.h index 05f60d586a..72ef76f6ae 100644 --- a/src/3rdparty/freetype/src/type1/t1gload.h +++ b/src/3rdparty/freetype/src/type1/t1gload.h @@ -4,7 +4,7 @@ /* */ /* Type 1 Glyph Loader (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1GLOAD_H__ -#define __T1GLOAD_H__ +#ifndef T1GLOAD_H_ +#define T1GLOAD_H_ #include <ft2build.h> @@ -47,7 +47,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1GLOAD_H__ */ +#endif /* T1GLOAD_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/type1/t1load.c b/src/3rdparty/freetype/src/type1/t1load.c index dbf4eafd71..9dfa637a69 100644 --- a/src/3rdparty/freetype/src/type1/t1load.c +++ b/src/3rdparty/freetype/src/type1/t1load.c @@ -4,7 +4,7 @@ /* */ /* Type 1 font loader (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -66,6 +66,7 @@ #include FT_MULTIPLE_MASTERS_H #include FT_INTERNAL_TYPE1_TYPES_H #include FT_INTERNAL_CALC_H +#include FT_INTERNAL_HASH_H #include "t1load.h" #include "t1errors.h" @@ -236,7 +237,7 @@ if ( ncv <= axismap->blend_points[0] ) return INT_TO_FIXED( axismap->design_points[0] ); - for ( j = 1; j < axismap->num_points; ++j ) + for ( j = 1; j < axismap->num_points; j++ ) { if ( ncv <= axismap->blend_points[j] ) return INT_TO_FIXED( axismap->design_points[j - 1] ) + @@ -320,22 +321,25 @@ mmvar->num_axis = mmaster.num_axis; mmvar->num_designs = mmaster.num_designs; - mmvar->num_namedstyles = ~0U; /* Does not apply */ + mmvar->num_namedstyles = 0; /* Not supported */ mmvar->axis = (FT_Var_Axis*)&mmvar[1]; /* Point to axes after MM_Var struct */ mmvar->namedstyle = NULL; - for ( i = 0 ; i < mmaster.num_axis; ++i ) + for ( i = 0; i < mmaster.num_axis; i++ ) { mmvar->axis[i].name = mmaster.axis[i].name; - mmvar->axis[i].minimum = INT_TO_FIXED( mmaster.axis[i].minimum); - mmvar->axis[i].maximum = INT_TO_FIXED( mmaster.axis[i].maximum); + mmvar->axis[i].minimum = INT_TO_FIXED( mmaster.axis[i].minimum ); + mmvar->axis[i].maximum = INT_TO_FIXED( mmaster.axis[i].maximum ); mmvar->axis[i].def = ( mmvar->axis[i].minimum + mmvar->axis[i].maximum ) / 2; /* Does not apply. But this value is in range */ mmvar->axis[i].strid = ~0U; /* Does not apply */ mmvar->axis[i].tag = ~0U; /* Does not apply */ + if ( !mmvar->axis[i].name ) + continue; + if ( ft_strcmp( mmvar->axis[i].name, "Weight" ) == 0 ) mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'g', 'h', 't' ); else if ( ft_strcmp( mmvar->axis[i].name, "Width" ) == 0 ) @@ -350,7 +354,7 @@ axiscoords, blend->num_axis ); - for ( i = 0; i < mmaster.num_axis; ++i ) + for ( i = 0; i < mmaster.num_axis; i++ ) mmvar->axis[i].def = mm_axis_unmap( &blend->design_map[i], axiscoords[i] ); } @@ -362,14 +366,16 @@ } - FT_LOCAL_DEF( FT_Error ) - T1_Set_MM_Blend( T1_Face face, + static FT_Error + t1_set_mm_blend( T1_Face face, FT_UInt num_coords, FT_Fixed* coords ) { PS_Blend blend = face->blend; FT_UInt n, m; + FT_Bool have_diff = 0; + if ( !blend ) return FT_THROW( Invalid_Argument ); @@ -401,9 +407,71 @@ result = FT_MulFix( result, factor ); } - blend->weight_vector[n] = result; + + if ( blend->weight_vector[n] != result ) + { + blend->weight_vector[n] = result; + have_diff = 1; + } } + /* return value -1 indicates `no change' */ + return have_diff ? FT_Err_Ok : -1; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Set_MM_Blend( T1_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + FT_Error error; + + + error = t1_set_mm_blend( face, num_coords, coords ); + if ( error ) + return error; + + if ( num_coords ) + face->root.face_flags |= FT_FACE_FLAG_VARIATION; + else + face->root.face_flags &= ~FT_FACE_FLAG_VARIATION; + + return FT_Err_Ok; + } + + + FT_LOCAL_DEF( FT_Error ) + T1_Get_MM_Blend( T1_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + PS_Blend blend = face->blend; + + FT_Fixed axiscoords[4]; + FT_UInt i, nc; + + + if ( !blend ) + return FT_THROW( Invalid_Argument ); + + mm_weights_unmap( blend->weight_vector, + axiscoords, + blend->num_axis ); + + nc = num_coords; + if ( num_coords > blend->num_axis ) + { + FT_TRACE2(( "T1_Get_MM_Blend: only using first %d of %d coordinates\n", + blend->num_axis, num_coords )); + nc = blend->num_axis; + } + + for ( i = 0; i < nc; i++ ) + coords[i] = axiscoords[i]; + for ( ; i < num_coords; i++ ) + coords[i] = 0x8000; + return FT_Err_Ok; } @@ -413,6 +481,7 @@ FT_UInt num_coords, FT_Long* coords ) { + FT_Error error; PS_Blend blend = face->blend; FT_UInt n, p; FT_Fixed final_blends[T1_MAX_MM_DESIGNS]; @@ -479,7 +548,28 @@ final_blends[n] = the_blend; } - return T1_Set_MM_Blend( face, blend->num_axis, final_blends ); + error = t1_set_mm_blend( face, blend->num_axis, final_blends ); + if ( error ) + return error; + + if ( num_coords ) + face->root.face_flags |= FT_FACE_FLAG_VARIATION; + else + face->root.face_flags &= ~FT_FACE_FLAG_VARIATION; + + return FT_Err_Ok; + } + + + /* MM fonts don't have named instances, so only the design is reset */ + + FT_LOCAL_DEF( FT_Error ) + T1_Reset_MM_Blend( T1_Face face, + FT_UInt instance_index ) + { + FT_UNUSED( instance_index ); + + return T1_Set_MM_Blend( face, 0, NULL ); } @@ -500,13 +590,49 @@ if ( num_coords > T1_MAX_MM_AXIS ) num_coords = T1_MAX_MM_AXIS; - for ( i = 0; i < num_coords; ++i ) + for ( i = 0; i < num_coords; i++ ) lcoords[i] = FIXED_TO_INT( coords[i] ); return T1_Set_MM_Design( face, num_coords, lcoords ); } + FT_LOCAL_DEF( FT_Error ) + T1_Get_Var_Design( T1_Face face, + FT_UInt num_coords, + FT_Fixed* coords ) + { + PS_Blend blend = face->blend; + + FT_Fixed axiscoords[4]; + FT_UInt i, nc; + + + if ( !blend ) + return FT_THROW( Invalid_Argument ); + + mm_weights_unmap( blend->weight_vector, + axiscoords, + blend->num_axis ); + + nc = num_coords; + if ( num_coords > blend->num_axis ) + { + FT_TRACE2(( "T1_Get_Var_Design:" + " only using first %d of %d coordinates\n", + blend->num_axis, num_coords )); + nc = blend->num_axis; + } + + for ( i = 0; i < nc; i++ ) + coords[i] = mm_axis_unmap( &blend->design_map[i], axiscoords[i] ); + for ( ; i < num_coords; i++ ) + coords[i] = 0; + + return FT_Err_Ok; + } + + FT_LOCAL_DEF( void ) T1_Done_Blend( T1_Face face ) { @@ -1191,7 +1317,7 @@ if ( ft_isdigit( *cur ) || *cur == '[' ) { T1_Encoding encode = &face->type1.encoding; - FT_Int count, n; + FT_Int count, array_size, n; PS_Table char_table = &loader->encoding_table; FT_Memory memory = parser->root.memory; FT_Error error; @@ -1208,13 +1334,12 @@ else count = (FT_Int)T1_ToInt( parser ); - /* only composite fonts (which we don't support) */ - /* can have larger values */ + array_size = count; if ( count > 256 ) { - FT_ERROR(( "parse_encoding: invalid encoding array size\n" )); - parser->root.error = FT_THROW( Invalid_File_Format ); - return; + FT_TRACE2(( "parse_encoding:" + " only using first 256 encoding array entries\n" )); + array_size = 256; } T1_Skip_Spaces( parser ); @@ -1230,18 +1355,18 @@ } /* we use a T1_Table to store our charnames */ - loader->num_chars = encode->num_chars = count; - if ( FT_NEW_ARRAY( encode->char_index, count ) || - FT_NEW_ARRAY( encode->char_name, count ) || + loader->num_chars = encode->num_chars = array_size; + if ( FT_NEW_ARRAY( encode->char_index, array_size ) || + FT_NEW_ARRAY( encode->char_name, array_size ) || FT_SET_ERROR( psaux->ps_table_funcs->init( - char_table, count, memory ) ) ) + char_table, array_size, memory ) ) ) { parser->root.error = error; return; } /* We need to `zero' out encoding_table.elements */ - for ( n = 0; n < count; n++ ) + for ( n = 0; n < array_size; n++ ) { char* notdef = (char *)".notdef"; @@ -1334,11 +1459,14 @@ len = (FT_UInt)( parser->root.cursor - cur ); - parser->root.error = T1_Add_Table( char_table, charcode, - cur, len + 1 ); - if ( parser->root.error ) - return; - char_table->elements[charcode][len] = '\0'; + if ( n < array_size ) + { + parser->root.error = T1_Add_Table( char_table, charcode, + cur, len + 1 ); + if ( parser->root.error ) + return; + char_table->elements[charcode][len] = '\0'; + } n++; } @@ -1401,6 +1529,7 @@ FT_Memory memory = parser->root.memory; FT_Error error; FT_Int num_subrs; + FT_UInt count; PSAux_Service psaux = (PSAux_Service)face->psaux; @@ -1420,6 +1549,47 @@ } num_subrs = (FT_Int)T1_ToInt( parser ); + if ( num_subrs < 0 ) + { + parser->root.error = FT_THROW( Invalid_File_Format ); + return; + } + + /* we certainly need more than 8 bytes per subroutine */ + if ( parser->root.limit >= parser->root.cursor && + num_subrs > ( parser->root.limit - parser->root.cursor ) >> 3 ) + { + /* + * There are two possibilities. Either the font contains an invalid + * value for `num_subrs', or we have a subsetted font where the + * subroutine indices are not adjusted, e.g. + * + * /Subrs 812 array + * dup 0 { ... } NP + * dup 51 { ... } NP + * dup 681 { ... } NP + * ND + * + * In both cases, we use a number hash that maps from subr indices to + * actual array elements. + */ + + FT_TRACE0(( "parse_subrs: adjusting number of subroutines" + " (from %d to %d)\n", + num_subrs, + ( parser->root.limit - parser->root.cursor ) >> 3 )); + num_subrs = ( parser->root.limit - parser->root.cursor ) >> 3; + + if ( !loader->subrs_hash ) + { + if ( FT_NEW( loader->subrs_hash ) ) + goto Fail; + + error = ft_hash_num_init( loader->subrs_hash, memory ); + if ( error ) + goto Fail; + } + } /* position the parser right before the `dup' of the first subr */ T1_Skip_PS_Token( parser ); /* `array' */ @@ -1440,7 +1610,7 @@ /* */ /* `index' + binary data */ /* */ - for (;;) + for ( count = 0; ; count++ ) { FT_Long idx; FT_ULong size; @@ -1476,6 +1646,14 @@ T1_Skip_Spaces ( parser ); } + /* if we use a hash, the subrs index is the key, and a running */ + /* counter specified for `T1_Add_Table' acts as the value */ + if ( loader->subrs_hash ) + { + ft_hash_num_insert( idx, count, loader->subrs_hash, memory ); + idx = count; + } + /* with synthetic fonts it is possible we get here twice */ if ( loader->num_subrs ) continue; @@ -1487,7 +1665,7 @@ /* */ if ( face->type1.private_dict.lenIV >= 0 ) { - FT_Byte* temp; + FT_Byte* temp = NULL; /* some fonts define empty subr records -- this is not totally */ @@ -1691,7 +1869,7 @@ if ( face->type1.private_dict.lenIV >= 0 && n < num_glyphs + TABLE_EXTEND ) { - FT_Byte* temp; + FT_Byte* temp = NULL; if ( size <= (FT_ULong)face->type1.private_dict.lenIV ) @@ -1719,6 +1897,12 @@ } } + if ( !n ) + { + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + loader->num_glyphs = n; /* if /.notdef is found but does not occupy index 0, do our magic. */ @@ -2047,7 +2231,7 @@ parser->root.error = t1_load_keyword( face, loader, keyword ); - if ( parser->root.error != FT_Err_Ok ) + if ( parser->root.error ) { if ( FT_ERR_EQ( parser->root.error, Ignore ) ) parser->root.error = FT_Err_Ok; @@ -2086,18 +2270,7 @@ { FT_UNUSED( face ); - FT_MEM_ZERO( loader, sizeof ( *loader ) ); - loader->num_glyphs = 0; - loader->num_chars = 0; - - /* initialize the tables -- simply set their `init' field to 0 */ - loader->encoding_table.init = 0; - loader->charstrings.init = 0; - loader->glyph_names.init = 0; - loader->subrs.init = 0; - loader->swap_table.init = 0; - loader->fontdata = 0; - loader->keywords_encountered = 0; + FT_ZERO( loader ); } @@ -2105,6 +2278,7 @@ t1_done_loader( T1_Loader loader ) { T1_Parser parser = &loader->parser; + FT_Memory memory = parser->root.memory; /* finalize tables */ @@ -2114,6 +2288,10 @@ T1_Release_Table( &loader->swap_table ); T1_Release_Table( &loader->subrs ); + /* finalize hash */ + ft_hash_num_free( loader->subrs_hash, memory ); + FT_FREE( loader->subrs_hash ); + /* finalize parser */ T1_Finalize_Parser( parser ); } @@ -2230,11 +2408,15 @@ if ( loader.subrs.init ) { - loader.subrs.init = 0; type1->num_subrs = loader.num_subrs; type1->subrs_block = loader.subrs.block; type1->subrs = loader.subrs.elements; type1->subrs_len = loader.subrs.lengths; + type1->subrs_hash = loader.subrs_hash; + + /* prevent `t1_done_loader' from freeing the propagated data */ + loader.subrs.init = 0; + loader.subrs_hash = NULL; } if ( !IS_INCREMENTAL ) @@ -2311,6 +2493,24 @@ type1->encoding.num_chars = loader.num_chars; } + /* some sanitizing to avoid overflows later on; */ + /* the upper limits are ad-hoc values */ + if ( priv->blue_shift > 1000 || priv->blue_shift < 0 ) + { + FT_TRACE2(( "T1_Open_Face:" + " setting unlikely BlueShift value %d to default (7)\n", + priv->blue_shift )); + priv->blue_shift = 7; + } + + if ( priv->blue_fuzz > 1000 || priv->blue_fuzz < 0 ) + { + FT_TRACE2(( "T1_Open_Face:" + " setting unlikely BlueFuzz value %d to default (1)\n", + priv->blue_fuzz )); + priv->blue_fuzz = 1; + } + Exit: t1_done_loader( &loader ); return error; diff --git a/src/3rdparty/freetype/src/type1/t1load.h b/src/3rdparty/freetype/src/type1/t1load.h index de422e7ecd..03be3f7f93 100644 --- a/src/3rdparty/freetype/src/type1/t1load.h +++ b/src/3rdparty/freetype/src/type1/t1load.h @@ -4,7 +4,7 @@ /* */ /* Type 1 font loader (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1LOAD_H__ -#define __T1LOAD_H__ +#ifndef T1LOAD_H_ +#define T1LOAD_H_ #include <ft2build.h> @@ -46,6 +46,7 @@ FT_BEGIN_HEADER FT_Int num_subrs; PS_TableRec subrs; + FT_Hash subrs_hash; FT_Bool fontdata; FT_UInt keywords_encountered; /* T1_LOADER_ENCOUNTERED_XXX */ @@ -69,7 +70,7 @@ FT_BEGIN_HEADER T1_Get_Multi_Master( T1_Face face, FT_Multi_Master* master ); - FT_LOCAL_DEF( FT_Error ) + FT_LOCAL( FT_Error ) T1_Get_MM_Var( T1_Face face, FT_MM_Var* *master ); @@ -78,12 +79,26 @@ FT_BEGIN_HEADER FT_UInt num_coords, FT_Fixed* coords ); + FT_LOCAL( FT_Error ) + T1_Get_MM_Blend( T1_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + FT_LOCAL( FT_Error ) T1_Set_MM_Design( T1_Face face, FT_UInt num_coords, FT_Long* coords ); - FT_LOCAL_DEF( FT_Error ) + FT_LOCAL( FT_Error ) + T1_Reset_MM_Blend( T1_Face face, + FT_UInt instance_index ); + + FT_LOCAL( FT_Error ) + T1_Get_Var_Design( T1_Face face, + FT_UInt num_coords, + FT_Fixed* coords ); + + FT_LOCAL( FT_Error ) T1_Set_Var_Design( T1_Face face, FT_UInt num_coords, FT_Fixed* coords ); @@ -96,7 +111,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1LOAD_H__ */ +#endif /* T1LOAD_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/type1/t1objs.c b/src/3rdparty/freetype/src/type1/t1objs.c index d921063eaa..7333c4c958 100644 --- a/src/3rdparty/freetype/src/type1/t1objs.c +++ b/src/3rdparty/freetype/src/type1/t1objs.c @@ -4,7 +4,7 @@ /* */ /* Type 1 objects manager (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -21,6 +21,7 @@ #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_STREAM_H #include FT_TRUETYPE_IDS_H +#include FT_DRIVER_H #include "t1gload.h" #include "t1load.h" @@ -49,9 +50,6 @@ /* */ /* SIZE FUNCTIONS */ /* */ - /* note that we store the global hints in the size's "internal" root */ - /* field */ - /* */ /*************************************************************************/ @@ -67,7 +65,7 @@ "pshinter" ); return ( module && pshinter && pshinter->get_globals_funcs ) ? pshinter->get_globals_funcs( module ) - : 0 ; + : 0; } @@ -77,16 +75,16 @@ T1_Size size = (T1_Size)t1size; - if ( size->root.internal ) + if ( t1size->internal->module_data ) { PSH_Globals_Funcs funcs; funcs = T1_Size_Get_Globals_Funcs( size ); if ( funcs ) - funcs->destroy( (PSH_Globals)size->root.internal ); + funcs->destroy( (PSH_Globals)t1size->internal->module_data ); - size->root.internal = NULL; + t1size->internal->module_data = NULL; } } @@ -108,7 +106,7 @@ error = funcs->create( size->root.face->memory, &face->type1.private_dict, &globals ); if ( !error ) - size->root.internal = (FT_Size_Internal)(void*)globals; + t1size->internal->module_data = globals; } return error; @@ -126,7 +124,7 @@ FT_Request_Metrics( size->root.face, req ); if ( funcs ) - funcs->set_scale( (PSH_Globals)size->root.internal, + funcs->set_scale( (PSH_Globals)t1size->internal->module_data, size->root.metrics.x_scale, size->root.metrics.y_scale, 0, 0 ); @@ -247,6 +245,9 @@ FT_FREE( type1->subrs ); FT_FREE( type1->subrs_len ); + ft_hash_num_free( type1->subrs_hash, memory ); + FT_FREE( type1->subrs_hash ); + FT_FREE( type1->subrs_block ); FT_FREE( type1->charstrings_block ); FT_FREE( type1->glyph_names_block ); @@ -379,7 +380,7 @@ /* simplistic and might get some things wrong. For a full-featured */ /* algorithm you might have a look at the whitepaper given at */ /* */ - /* http://blogs.msdn.com/text/archive/2007/04/23/wpf-font-selection-model.aspx */ + /* https://blogs.msdn.com/text/archive/2007/04/23/wpf-font-selection-model.aspx */ /* get style name -- be careful, some broken fonts only */ /* have a `/FontName' dictionary entry! */ @@ -555,12 +556,6 @@ if ( clazz ) error = FT_CMap_New( clazz, NULL, &charmap, NULL ); - -#if 0 - /* Select default charmap */ - if (root->num_charmaps) - root->charmap = root->charmaps[0]; -#endif } } @@ -584,9 +579,42 @@ /* FreeType error code. 0 means success. */ /* */ FT_LOCAL_DEF( FT_Error ) - T1_Driver_Init( FT_Module driver ) + T1_Driver_Init( FT_Module module ) { - FT_UNUSED( driver ); + PS_Driver driver = (PS_Driver)module; + + FT_UInt32 seed; + + + /* set default property values, cf. `ftt1drv.h' */ +#ifdef T1_CONFIG_OPTION_OLD_ENGINE + driver->hinting_engine = FT_HINTING_FREETYPE; +#else + driver->hinting_engine = FT_HINTING_ADOBE; +#endif + + driver->no_stem_darkening = TRUE; + + driver->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1; + driver->darken_params[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1; + driver->darken_params[2] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2; + driver->darken_params[3] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2; + driver->darken_params[4] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3; + driver->darken_params[5] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3; + driver->darken_params[6] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4; + driver->darken_params[7] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4; + + /* compute random seed from some memory addresses */ + seed = (FT_UInt32)( (FT_Offset)(char*)&seed ^ + (FT_Offset)(char*)&module ^ + (FT_Offset)(char*)module->memory ); + seed = seed ^ ( seed >> 10 ) ^ ( seed >> 20 ); + + driver->random_seed = (FT_Int32)seed; + if ( driver->random_seed < 0 ) + driver->random_seed = -driver->random_seed; + else if ( driver->random_seed == 0 ) + driver->random_seed = 123456789; return FT_Err_Ok; } diff --git a/src/3rdparty/freetype/src/type1/t1objs.h b/src/3rdparty/freetype/src/type1/t1objs.h index 6b4f3cb56d..8298e036f4 100644 --- a/src/3rdparty/freetype/src/type1/t1objs.h +++ b/src/3rdparty/freetype/src/type1/t1objs.h @@ -4,7 +4,7 @@ /* */ /* Type 1 objects manager (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1OBJS_H__ -#define __T1OBJS_H__ +#ifndef T1OBJS_H_ +#define T1OBJS_H_ #include <ft2build.h> @@ -120,12 +120,12 @@ FT_BEGIN_HEADER FT_Bool hint; FT_Bool scaled; - FT_Int max_points; - FT_Int max_contours; - FT_Fixed x_scale; FT_Fixed y_scale; + FT_Int max_points; + FT_Int max_contours; + } T1_GlyphSlotRec; @@ -154,7 +154,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1OBJS_H__ */ +#endif /* T1OBJS_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/type1/t1parse.c b/src/3rdparty/freetype/src/type1/t1parse.c index 0b68502606..8e201e5ef5 100644 --- a/src/3rdparty/freetype/src/type1/t1parse.c +++ b/src/3rdparty/freetype/src/type1/t1parse.c @@ -4,7 +4,7 @@ /* */ /* Type 1 parser (body). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -437,7 +437,7 @@ *cur == '\t' || (test_cr && *cur == '\r' ) || *cur == '\n' ) ) - ++cur; + cur++; if ( cur >= limit ) { FT_ERROR(( "T1_Get_Private_Dict:" diff --git a/src/3rdparty/freetype/src/type1/t1parse.h b/src/3rdparty/freetype/src/type1/t1parse.h index 93b02e3d31..4ac82ae913 100644 --- a/src/3rdparty/freetype/src/type1/t1parse.h +++ b/src/3rdparty/freetype/src/type1/t1parse.h @@ -4,7 +4,7 @@ /* */ /* Type 1 parser (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T1PARSE_H__ -#define __T1PARSE_H__ +#ifndef T1PARSE_H_ +#define T1PARSE_H_ #include <ft2build.h> @@ -123,7 +123,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T1PARSE_H__ */ +#endif /* T1PARSE_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/type1/t1tokens.h b/src/3rdparty/freetype/src/type1/t1tokens.h index 3992652435..43a65d88ea 100644 --- a/src/3rdparty/freetype/src/type1/t1tokens.h +++ b/src/3rdparty/freetype/src/type1/t1tokens.h @@ -4,7 +4,7 @@ /* */ /* Type 1 tokenizer (specification). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ diff --git a/src/3rdparty/freetype/src/type1/type1.c b/src/3rdparty/freetype/src/type1/type1.c index 4c70ea7630..72eff59bfe 100644 --- a/src/3rdparty/freetype/src/type1/type1.c +++ b/src/3rdparty/freetype/src/type1/type1.c @@ -4,7 +4,7 @@ /* */ /* FreeType Type 1 driver component (body only). */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,17 +17,14 @@ #define FT_MAKE_OPTION_SINGLE_OBJECT - #include <ft2build.h> -#include "t1parse.c" -#include "t1load.c" -#include "t1objs.c" + +#include "t1afm.c" #include "t1driver.c" #include "t1gload.c" - -#ifndef T1_CONFIG_OPTION_NO_AFM -#include "t1afm.c" -#endif +#include "t1load.c" +#include "t1objs.c" +#include "t1parse.c" /* END */ diff --git a/src/3rdparty/freetype/src/type42/Jamfile b/src/3rdparty/freetype/src/type42/Jamfile index 722953d37f..b98de05a74 100644 --- a/src/3rdparty/freetype/src/type42/Jamfile +++ b/src/3rdparty/freetype/src/type42/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/type42 Jamfile # -# Copyright 2002-2015 by +# Copyright 2002-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/type42/module.mk b/src/3rdparty/freetype/src/type42/module.mk index af7e651d95..3d4732bb6f 100644 --- a/src/3rdparty/freetype/src/type42/module.mk +++ b/src/3rdparty/freetype/src/type42/module.mk @@ -3,7 +3,7 @@ # -# Copyright 2002-2015 by +# Copyright 2002-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/type42/rules.mk b/src/3rdparty/freetype/src/type42/rules.mk index 4a8efca507..9325d3898f 100644 --- a/src/3rdparty/freetype/src/type42/rules.mk +++ b/src/3rdparty/freetype/src/type42/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 2002-2015 by +# Copyright 2002-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/type42/t42drivr.c b/src/3rdparty/freetype/src/type42/t42drivr.c index 2907096c9f..f579b2708c 100644 --- a/src/3rdparty/freetype/src/type42/t42drivr.c +++ b/src/3rdparty/freetype/src/type42/t42drivr.c @@ -4,7 +4,7 @@ /* */ /* High-level Type 42 driver interface (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -81,7 +81,8 @@ if ( glyph_name[0] == gname[0] && !ft_strcmp( glyph_name, gname ) ) - return (FT_UInt)ft_atol( (const char *)face->type1.charstrings[i] ); + return (FT_UInt)ft_strtol( (const char *)face->type1.charstrings[i], + NULL, 10 ); } return 0; @@ -90,8 +91,8 @@ static const FT_Service_GlyphDictRec t42_service_glyph_dict = { - (FT_GlyphDict_GetNameFunc) t42_get_glyph_name, - (FT_GlyphDict_NameIndexFunc)t42_get_name_index + (FT_GlyphDict_GetNameFunc) t42_get_glyph_name, /* get_name */ + (FT_GlyphDict_NameIndexFunc)t42_get_name_index /* name_index */ }; @@ -110,7 +111,7 @@ static const FT_Service_PsFontNameRec t42_service_ps_font_name = { - (FT_PsName_GetFunc)t42_get_ps_font_name + (FT_PsName_GetFunc)t42_get_ps_font_name /* get_ps_font_name */ }; @@ -161,11 +162,12 @@ static const FT_Service_PsInfoRec t42_service_ps_info = { - (PS_GetFontInfoFunc) t42_ps_get_font_info, - (PS_GetFontExtraFunc) t42_ps_get_font_extra, - (PS_HasGlyphNamesFunc) t42_ps_has_glyph_names, - (PS_GetFontPrivateFunc)t42_ps_get_font_private, - (PS_GetFontValueFunc) NULL /* not implemented */ + (PS_GetFontInfoFunc) t42_ps_get_font_info, /* ps_get_font_info */ + (PS_GetFontExtraFunc) t42_ps_get_font_extra, /* ps_get_font_extra */ + (PS_HasGlyphNamesFunc) t42_ps_has_glyph_names, /* ps_has_glyph_names */ + (PS_GetFontPrivateFunc)t42_ps_get_font_private, /* ps_get_font_private */ + /* not implemented */ + (PS_GetFontValueFunc) NULL /* ps_get_font_value */ }; @@ -212,32 +214,32 @@ 0x10000L, 0x20000L, - 0, /* format interface */ + NULL, /* module-specific interface */ - T42_Driver_Init, - T42_Driver_Done, - T42_Get_Interface, + T42_Driver_Init, /* FT_Module_Constructor module_init */ + T42_Driver_Done, /* FT_Module_Destructor module_done */ + T42_Get_Interface, /* FT_Module_Requester get_interface */ }, sizeof ( T42_FaceRec ), sizeof ( T42_SizeRec ), sizeof ( T42_GlyphSlotRec ), - T42_Face_Init, - T42_Face_Done, - T42_Size_Init, - T42_Size_Done, - T42_GlyphSlot_Init, - T42_GlyphSlot_Done, + T42_Face_Init, /* FT_Face_InitFunc init_face */ + T42_Face_Done, /* FT_Face_DoneFunc done_face */ + T42_Size_Init, /* FT_Size_InitFunc init_size */ + T42_Size_Done, /* FT_Size_DoneFunc done_size */ + T42_GlyphSlot_Init, /* FT_Slot_InitFunc init_slot */ + T42_GlyphSlot_Done, /* FT_Slot_DoneFunc done_slot */ - T42_GlyphSlot_Load, + T42_GlyphSlot_Load, /* FT_Slot_LoadFunc load_glyph */ - 0, /* FT_Face_GetKerningFunc */ - 0, /* FT_Face_AttachFunc */ + NULL, /* FT_Face_GetKerningFunc get_kerning */ + NULL, /* FT_Face_AttachFunc attach_file */ + NULL, /* FT_Face_GetAdvancesFunc get_advances */ - 0, /* FT_Face_GetAdvancesFunc */ - T42_Size_Request, - T42_Size_Select + T42_Size_Request, /* FT_Size_RequestFunc request_size */ + T42_Size_Select /* FT_Size_SelectFunc select_size */ }; diff --git a/src/3rdparty/freetype/src/type42/t42drivr.h b/src/3rdparty/freetype/src/type42/t42drivr.h index b4d1753a23..3667f3e066 100644 --- a/src/3rdparty/freetype/src/type42/t42drivr.h +++ b/src/3rdparty/freetype/src/type42/t42drivr.h @@ -4,7 +4,7 @@ /* */ /* High-level Type 42 driver interface (specification). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T42DRIVR_H__ -#define __T42DRIVR_H__ +#ifndef T42DRIVR_H_ +#define T42DRIVR_H_ #include <ft2build.h> @@ -37,7 +37,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T42DRIVR_H__ */ +#endif /* T42DRIVR_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/type42/t42error.h b/src/3rdparty/freetype/src/type42/t42error.h index cddaf9e9ca..e3978a7607 100644 --- a/src/3rdparty/freetype/src/type42/t42error.h +++ b/src/3rdparty/freetype/src/type42/t42error.h @@ -4,7 +4,7 @@ /* */ /* Type 42 error codes (specification only). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -22,12 +22,12 @@ /* */ /*************************************************************************/ -#ifndef __T42ERROR_H__ -#define __T42ERROR_H__ +#ifndef T42ERROR_H_ +#define T42ERROR_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX T42_Err_ @@ -35,7 +35,7 @@ #include FT_ERRORS_H -#endif /* __T42ERROR_H__ */ +#endif /* T42ERROR_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/type42/t42objs.c b/src/3rdparty/freetype/src/type42/t42objs.c index 430871aced..66e5c40382 100644 --- a/src/3rdparty/freetype/src/type42/t42objs.c +++ b/src/3rdparty/freetype/src/type42/t42objs.c @@ -4,7 +4,7 @@ /* */ /* Type 42 objects manager (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -231,9 +231,6 @@ if ( info->is_fixed_pitch ) root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH; - /* We only set this flag if we have the patented bytecode interpreter. */ - /* There are no known `tricky' Type42 fonts that could be loaded with */ - /* the unpatented interpreter. */ #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER root->face_flags |= FT_FACE_FLAG_HINTER; #endif @@ -397,12 +394,6 @@ if ( clazz ) error = FT_CMap_New( clazz, NULL, &charmap, NULL ); - -#if 0 - /* Select default charmap */ - if ( root->num_charmaps ) - root->charmap = root->charmaps[0]; -#endif } } Exit: @@ -593,7 +584,7 @@ FT_Error error = FT_Err_Ok; - if ( face->glyph == NULL ) + if ( !face->glyph ) { /* First glyph slot for this face */ slot->ttslot = t42face->ttf_face->glyph; @@ -659,8 +650,9 @@ FT_TRACE1(( "T42_GlyphSlot_Load: glyph index %d\n", glyph_index )); /* map T42 glyph index to embedded TTF's glyph index */ - glyph_index = (FT_UInt)ft_atol( - (const char *)t42face->type1.charstrings[glyph_index] ); + glyph_index = (FT_UInt)ft_strtol( + (const char *)t42face->type1.charstrings[glyph_index], + NULL, 10 ); t42_glyphslot_clear( t42slot->ttslot ); error = ttclazz->load_glyph( t42slot->ttslot, diff --git a/src/3rdparty/freetype/src/type42/t42objs.h b/src/3rdparty/freetype/src/type42/t42objs.h index 3722c670f0..3bad5135e0 100644 --- a/src/3rdparty/freetype/src/type42/t42objs.h +++ b/src/3rdparty/freetype/src/type42/t42objs.h @@ -4,7 +4,7 @@ /* */ /* Type 42 objects manager (specification). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T42OBJS_H__ -#define __T42OBJS_H__ +#ifndef T42OBJS_H_ +#define T42OBJS_H_ #include <ft2build.h> #include FT_FREETYPE_H @@ -118,7 +118,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T42OBJS_H__ */ +#endif /* T42OBJS_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/type42/t42parse.c b/src/3rdparty/freetype/src/type42/t42parse.c index 003b63ed77..4813d1f3f9 100644 --- a/src/3rdparty/freetype/src/type42/t42parse.c +++ b/src/3rdparty/freetype/src/type42/t42parse.c @@ -4,7 +4,7 @@ /* */ /* Type 42 font parser (body). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -575,6 +575,9 @@ while ( parser->root.cursor < limit ) { + FT_ULong size; + + cur = parser->root.cursor; if ( *cur == ']' ) @@ -637,7 +640,7 @@ string_buf = parser->root.cursor + 1; /* one space after `RD' */ - if ( (FT_ULong)( limit - parser->root.cursor ) < string_size ) + if ( (FT_ULong)( limit - parser->root.cursor ) <= string_size ) { FT_ERROR(( "t42_parse_sfnts: too much binary data\n" )); error = FT_THROW( Invalid_File_Format ); @@ -666,6 +669,11 @@ goto Fail; } + /* The whole TTF is now loaded into `string_buf'. We are */ + /* checking its contents while copying it to `ttf_data'. */ + + size = (FT_ULong)( limit - parser->root.cursor ); + for ( n = 0; n < string_size; n++ ) { switch ( status ) @@ -683,7 +691,7 @@ status = BEFORE_TABLE_DIR; face->ttf_size = 12 + 16 * num_tables; - if ( (FT_Long)( limit - parser->root.cursor ) < face->ttf_size ) + if ( (FT_Long)size < face->ttf_size ) { FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array\n" )); error = FT_THROW( Invalid_File_Format ); @@ -714,6 +722,14 @@ len = FT_PEEK_ULONG( p ); + if ( len > size || + face->ttf_size > (FT_Long)( size - len ) ) + { + FT_ERROR(( "t42_parse_sfnts:" + " invalid data in sfnts array\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } /* Pad to a 4-byte boundary length */ face->ttf_size += (FT_Long)( ( len + 3 ) & ~3U ); @@ -721,7 +737,6 @@ status = OTHER_TABLES; - /* there are no more than 256 tables, so no size check here */ if ( FT_REALLOC( face->ttf_data, 12 + 16 * num_tables, face->ttf_size + 1 ) ) goto Fail; @@ -795,6 +810,17 @@ error = FT_THROW( Invalid_File_Format ); goto Fail; } + + /* we certainly need more than 4 bytes per glyph */ + if ( loader->num_glyphs > ( limit - parser->root.cursor ) >> 2 ) + { + FT_TRACE0(( "t42_parse_charstrings: adjusting number of glyphs" + " (from %d to %d)\n", + loader->num_glyphs, + ( limit - parser->root.cursor ) >> 2 )); + loader->num_glyphs = ( limit - parser->root.cursor ) >> 2; + } + } else if ( *parser->root.cursor == '<' ) { @@ -873,8 +899,13 @@ for (;;) { - /* The format is simple: */ - /* `/glyphname' + index [+ def] */ + /* We support two formats. */ + /* */ + /* `/glyphname' + index [+ `def'] */ + /* `(glyphname)' [+ `cvn'] + index [+ `def'] */ + /* */ + /* The latter format gets created by the */ + /* LilyPond typesetting program. */ T1_Skip_Spaces( parser ); @@ -902,12 +933,13 @@ if ( parser->root.error ) return; - if ( *cur == '/' ) + if ( *cur == '/' || *cur == '(' ) { FT_UInt len; + FT_Bool have_literal = FT_BOOL( *cur == '(' ); - if ( cur + 2 >= limit ) + if ( cur + ( have_literal ? 3 : 2 ) >= limit ) { FT_ERROR(( "t42_parse_charstrings: out of bounds\n" )); error = FT_THROW( Invalid_File_Format ); @@ -916,6 +948,8 @@ cur++; /* skip `/' */ len = (FT_UInt)( parser->root.cursor - cur ); + if ( have_literal ) + len--; error = T1_Add_Table( name_table, n, cur, len + 1 ); if ( error ) @@ -935,6 +969,9 @@ T1_Skip_Spaces( parser ); + if ( have_literal ) + T1_Skip_PS_Token( parser ); + cur = parser->root.cursor; (void)T1_ToInt( parser ); @@ -1231,7 +1268,7 @@ { FT_UNUSED( face ); - FT_MEM_ZERO( loader, sizeof ( *loader ) ); + FT_ZERO( loader ); loader->num_glyphs = 0; loader->num_chars = 0; diff --git a/src/3rdparty/freetype/src/type42/t42parse.h b/src/3rdparty/freetype/src/type42/t42parse.h index 8ed2fde65d..f35d23de63 100644 --- a/src/3rdparty/freetype/src/type42/t42parse.h +++ b/src/3rdparty/freetype/src/type42/t42parse.h @@ -4,7 +4,7 @@ /* */ /* Type 42 font parser (specification). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T42PARSE_H__ -#define __T42PARSE_H__ +#ifndef T42PARSE_H_ +#define T42PARSE_H_ #include "t42objs.h" @@ -85,7 +85,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T42PARSE_H__ */ +#endif /* T42PARSE_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/type42/t42types.h b/src/3rdparty/freetype/src/type42/t42types.h index 01286af827..d0aa2de570 100644 --- a/src/3rdparty/freetype/src/type42/t42types.h +++ b/src/3rdparty/freetype/src/type42/t42types.h @@ -4,7 +4,7 @@ /* */ /* Type 42 font data types (specification only). */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* Roberto Alameda. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -16,8 +16,8 @@ /***************************************************************************/ -#ifndef __T42TYPES_H__ -#define __T42TYPES_H__ +#ifndef T42TYPES_H_ +#define T42TYPES_H_ #include <ft2build.h> @@ -51,7 +51,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __T42TYPES_H__ */ +#endif /* T42TYPES_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/type42/type42.c b/src/3rdparty/freetype/src/type42/type42.c index 3332b7b7e6..6a89cfbed1 100644 --- a/src/3rdparty/freetype/src/type42/type42.c +++ b/src/3rdparty/freetype/src/type42/type42.c @@ -4,7 +4,7 @@ /* */ /* FreeType Type 42 driver component. */ /* */ -/* Copyright 2002-2015 by */ +/* Copyright 2002-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -15,11 +15,13 @@ /* */ /***************************************************************************/ -#define FT_MAKE_OPTION_SINGLE_OBJECT +#define FT_MAKE_OPTION_SINGLE_OBJECT #include <ft2build.h> + +#include "t42drivr.c" #include "t42objs.c" #include "t42parse.c" -#include "t42drivr.c" + /* END */ diff --git a/src/3rdparty/freetype/src/winfonts/Jamfile b/src/3rdparty/freetype/src/winfonts/Jamfile index 86ee668196..4385e3b39f 100644 --- a/src/3rdparty/freetype/src/winfonts/Jamfile +++ b/src/3rdparty/freetype/src/winfonts/Jamfile @@ -1,6 +1,6 @@ # FreeType 2 src/winfonts Jamfile # -# Copyright 2001-2015 by +# Copyright 2001-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/winfonts/fnterrs.h b/src/3rdparty/freetype/src/winfonts/fnterrs.h index 0bf4d0986d..3a86af5aac 100644 --- a/src/3rdparty/freetype/src/winfonts/fnterrs.h +++ b/src/3rdparty/freetype/src/winfonts/fnterrs.h @@ -4,7 +4,7 @@ /* */ /* Win FNT/FON error codes (specification only). */ /* */ -/* Copyright 2001-2015 by */ +/* Copyright 2001-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -23,12 +23,12 @@ /* */ /*************************************************************************/ -#ifndef __FNTERRS_H__ -#define __FNTERRS_H__ +#ifndef FNTERRS_H_ +#define FNTERRS_H_ #include FT_MODULE_ERRORS_H -#undef __FTERRORS_H__ +#undef FTERRORS_H_ #undef FT_ERR_PREFIX #define FT_ERR_PREFIX FNT_Err_ @@ -36,7 +36,7 @@ #include FT_ERRORS_H -#endif /* __FNTERRS_H__ */ +#endif /* FNTERRS_H_ */ /* END */ diff --git a/src/3rdparty/freetype/src/winfonts/module.mk b/src/3rdparty/freetype/src/winfonts/module.mk index 8ba6d7584f..13f9077cfc 100644 --- a/src/3rdparty/freetype/src/winfonts/module.mk +++ b/src/3rdparty/freetype/src/winfonts/module.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2015 by +# Copyright 1996-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/winfonts/rules.mk b/src/3rdparty/freetype/src/winfonts/rules.mk index 4535f54d42..d694d1a771 100644 --- a/src/3rdparty/freetype/src/winfonts/rules.mk +++ b/src/3rdparty/freetype/src/winfonts/rules.mk @@ -3,7 +3,7 @@ # -# Copyright 1996-2015 by +# Copyright 1996-2018 by # David Turner, Robert Wilhelm, and Werner Lemberg. # # This file is part of the FreeType project, and may only be used, modified, diff --git a/src/3rdparty/freetype/src/winfonts/winfnt.c b/src/3rdparty/freetype/src/winfonts/winfnt.c index 4bfa55a429..36bd3148d5 100644 --- a/src/3rdparty/freetype/src/winfonts/winfnt.c +++ b/src/3rdparty/freetype/src/winfonts/winfnt.c @@ -4,7 +4,7 @@ /* */ /* FreeType font driver for Windows FNT/FON files */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* Copyright 2003 Huw D M Davies for Codeweavers */ /* Copyright 2007 Dmitry Timoshkov for Codeweavers */ @@ -561,7 +561,7 @@ error = fnt_font_load( face->font, stream ); if ( error ) { - FT_TRACE2(( "font #%lu load error %d\n", + FT_TRACE2(( "font #%lu load error 0x%x\n", dir_entry2.name, error )); goto Fail; } @@ -759,6 +759,14 @@ if ( error ) goto Fail; + /* sanity check */ + if ( !face->font->header.pixel_height ) + { + FT_TRACE2(( "invalid pixel height\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } + /* we now need to fill the root FT_Face fields */ /* with relevant information */ { @@ -851,10 +859,6 @@ NULL ); if ( error ) goto Fail; - - /* Select default charmap */ - if ( root->num_charmaps ) - root->charmap = root->charmaps[0]; } /* set up remaining flags */ @@ -992,8 +996,6 @@ FT_ULong offset; FT_Bool new_format; - FT_UNUSED( load_flags ); - if ( !face ) { @@ -1047,46 +1049,9 @@ goto Exit; } - /* jump to glyph data */ - p = font->fnt_frame + /* font->header.bits_offset */ + offset; + bitmap->rows = font->header.pixel_height; + bitmap->pixel_mode = FT_PIXEL_MODE_MONO; - /* allocate and build bitmap */ - { - FT_Memory memory = FT_FACE_MEMORY( slot->face ); - FT_UInt pitch = ( bitmap->width + 7 ) >> 3; - FT_Byte* column; - FT_Byte* write; - - - bitmap->pitch = (int)pitch; - bitmap->rows = font->header.pixel_height; - bitmap->pixel_mode = FT_PIXEL_MODE_MONO; - - if ( offset + pitch * bitmap->rows > font->header.file_size ) - { - FT_TRACE2(( "invalid bitmap width\n" )); - error = FT_THROW( Invalid_File_Format ); - goto Exit; - } - - /* note: since glyphs are stored in columns and not in rows we */ - /* can't use ft_glyphslot_set_bitmap */ - if ( FT_ALLOC_MULT( bitmap->buffer, pitch, bitmap->rows ) ) - goto Exit; - - column = (FT_Byte*)bitmap->buffer; - - for ( ; pitch > 0; pitch--, column++ ) - { - FT_Byte* limit = p + bitmap->rows; - - - for ( write = column; p < limit; p++, write += bitmap->pitch ) - *write = *p; - } - } - - slot->internal->flags = FT_GLYPH_OWN_BITMAP; slot->bitmap_left = 0; slot->bitmap_top = font->header.ascent; slot->format = FT_GLYPH_FORMAT_BITMAP; @@ -1101,6 +1066,48 @@ ft_synthesize_vertical_metrics( &slot->metrics, (FT_Pos)( bitmap->rows << 6 ) ); + if ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY ) + goto Exit; + + /* jump to glyph data */ + p = font->fnt_frame + /* font->header.bits_offset */ + offset; + + /* allocate and build bitmap */ + { + FT_Memory memory = FT_FACE_MEMORY( slot->face ); + FT_UInt pitch = ( bitmap->width + 7 ) >> 3; + FT_Byte* column; + FT_Byte* write; + + + bitmap->pitch = (int)pitch; + if ( !pitch || + offset + pitch * bitmap->rows > font->header.file_size ) + { + FT_TRACE2(( "invalid bitmap width\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Exit; + } + + /* note: since glyphs are stored in columns and not in rows we */ + /* can't use ft_glyphslot_set_bitmap */ + if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, pitch ) ) + goto Exit; + + column = (FT_Byte*)bitmap->buffer; + + for ( ; pitch > 0; pitch--, column++ ) + { + FT_Byte* limit = p + bitmap->rows; + + + for ( write = column; p < limit; p++, write += bitmap->pitch ) + *write = *p; + } + + slot->internal->flags = FT_GLYPH_OWN_BITMAP; + } + Exit: return error; } @@ -1121,7 +1128,7 @@ static const FT_Service_WinFntRec winfnt_service_rec = { - winfnt_get_header + winfnt_get_header /* get_header */ }; /* @@ -1161,32 +1168,32 @@ 0x10000L, 0x20000L, - 0, + NULL, /* module-specific interface */ - 0, /* FT_Module_Constructor */ - 0, /* FT_Module_Destructor */ - winfnt_get_service + NULL, /* FT_Module_Constructor module_init */ + NULL, /* FT_Module_Destructor module_done */ + winfnt_get_service /* FT_Module_Requester get_interface */ }, sizeof ( FNT_FaceRec ), sizeof ( FT_SizeRec ), sizeof ( FT_GlyphSlotRec ), - FNT_Face_Init, - FNT_Face_Done, - 0, /* FT_Size_InitFunc */ - 0, /* FT_Size_DoneFunc */ - 0, /* FT_Slot_InitFunc */ - 0, /* FT_Slot_DoneFunc */ + FNT_Face_Init, /* FT_Face_InitFunc init_face */ + FNT_Face_Done, /* FT_Face_DoneFunc done_face */ + NULL, /* FT_Size_InitFunc init_size */ + NULL, /* FT_Size_DoneFunc done_size */ + NULL, /* FT_Slot_InitFunc init_slot */ + NULL, /* FT_Slot_DoneFunc done_slot */ - FNT_Load_Glyph, + FNT_Load_Glyph, /* FT_Slot_LoadFunc load_glyph */ - 0, /* FT_Face_GetKerningFunc */ - 0, /* FT_Face_AttachFunc */ - 0, /* FT_Face_GetAdvancesFunc */ + NULL, /* FT_Face_GetKerningFunc get_kerning */ + NULL, /* FT_Face_AttachFunc attach_file */ + NULL, /* FT_Face_GetAdvancesFunc get_advances */ - FNT_Size_Request, - FNT_Size_Select + FNT_Size_Request, /* FT_Size_RequestFunc request_size */ + FNT_Size_Select /* FT_Size_SelectFunc select_size */ }; diff --git a/src/3rdparty/freetype/src/winfonts/winfnt.h b/src/3rdparty/freetype/src/winfonts/winfnt.h index a39d26f449..4885c9d745 100644 --- a/src/3rdparty/freetype/src/winfonts/winfnt.h +++ b/src/3rdparty/freetype/src/winfonts/winfnt.h @@ -4,7 +4,7 @@ /* */ /* FreeType font driver for Windows FNT/FON files */ /* */ -/* Copyright 1996-2015 by */ +/* Copyright 1996-2018 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* Copyright 2007 Dmitry Timoshkov for Codeweavers */ /* */ @@ -17,8 +17,8 @@ /***************************************************************************/ -#ifndef __WINFNT_H__ -#define __WINFNT_H__ +#ifndef WINFNT_H_ +#define WINFNT_H_ #include <ft2build.h> @@ -165,7 +165,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* __WINFNT_H__ */ +#endif /* WINFNT_H_ */ /* END */ diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp index b6932d4892..f14adbcb6c 100644 --- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp +++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp @@ -1833,6 +1833,10 @@ void tst_QHeaderView::restoreBeforeSetModel() void tst_QHeaderView::defaultSectionSizeTest() { +#if defined Q_OS_WINRT + QSKIP("Fails on WinRT - QTBUG-73309"); +#endif + // Setup QTableView qtv; QHeaderView *hv = qtv.verticalHeader(); From fcba9fa861574f33e1d2e54d8c8d6da8062927cd Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen <allan.jensen@qt.io> Date: Wed, 23 Jan 2019 10:42:12 +0100 Subject: [PATCH 1005/1650] Fix regression in QPlainTextEdit updating It was incorrectly counting a block having more than one line as having changed visibility. Fixes: QTBUG-69310 Change-Id: I502cda1d3e8a4efb1c14122353cc0a4731d8581c Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> --- src/widgets/widgets/qplaintextedit.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp index d6f6a364a8..57f2dec8f7 100644 --- a/src/widgets/widgets/qplaintextedit.cpp +++ b/src/widgets/widgets/qplaintextedit.cpp @@ -312,10 +312,11 @@ void QPlainTextDocumentLayout::documentChanged(int from, int charsRemoved, int c QTextBlock block = changeStartBlock; do { block.clearLayout(); - const int lineCount = block.isVisible() ? 1 : 0; - if (block.lineCount() != lineCount) { + if (block.isVisible() + ? (block.lineCount() == 0) + : (block.lineCount() > 0)) { blockVisibilityChanged = true; - block.setLineCount(lineCount); + block.setLineCount(block.isVisible() ? 1 : 0); } if (block == changeEndBlock) break; From 7dd41b32678b8cedc6e03932ac4330d147f25f4a Mon Sep 17 00:00:00 2001 From: Edward Welbourne <edward.welbourne@qt.io> Date: Wed, 30 Jan 2019 12:02:27 +0100 Subject: [PATCH 1006/1650] generate_expected_output.py: placate FutureWarning from python Regexes have long specified that a [ as the first character inside a [...] is just a literal [, but apparently we need to escape it now, to avoid a "nested set" FutureWarning. Change-Id: I76a48c9aafb0684a1d6b0d5284fe9852c9ea0e43 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Samuel Gaist <samuel.gaist@idiap.ch> --- tests/auto/testlib/selftests/generate_expected_output.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/testlib/selftests/generate_expected_output.py b/tests/auto/testlib/selftests/generate_expected_output.py index 1996416e8c..111870b3fb 100755 --- a/tests/auto/testlib/selftests/generate_expected_output.py +++ b/tests/auto/testlib/selftests/generate_expected_output.py @@ -132,7 +132,7 @@ class Cleaner (object): # Add path to specific sources and to tst_*.cpp if missing (for in-source builds): patterns += ((r'(^|[^/])\b(qtestcase.cpp)\b', r'\1qtbase/src/testlib/\2'), # Add more special cases here, if they show up ! - (r'([[" ])\.\./(counting/tst_counting.cpp)\b', + (r'([\[" ])\.\./(counting/tst_counting.cpp)\b', r'\1' + os.path.sep.join(hereNames + (r'\2',))), # The common pattern: (r'(^|[^/])\b(tst_)?([a-z]+\d*)\.cpp\b', From e352ec4db4e6c6936bb406bb77776e1da89a2e84 Mon Sep 17 00:00:00 2001 From: Edward Welbourne <edward.welbourne@qt.io> Date: Wed, 7 Nov 2018 17:02:07 +0100 Subject: [PATCH 1007/1650] Q(Date|Time)+::toString: correct account of format specifiers Where non-format characters appear in the format string, they are not "ignored" as claimed; they are passed through verbatim. Formats without separators between fields are in fact supported, although results may be ambiguous. Cleaned up phrasing in the process. Fixes: QTBUG-51208 Change-Id: I7284a36c48aa0be29deaa16945ca0212e9e6f72c Reviewed-by: Paul Wicking <paul.wicking@qt.io> --- src/corelib/tools/qdatetime.cpp | 42 +++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 816bd974eb..3cba786865 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -908,10 +908,16 @@ QString QDate::toString(Qt::DateFormat format) const a minus sign is prepended in addition. \endtable - All other input characters will be ignored. Any sequence of characters that - are enclosed in single quotes will be treated as text and not be used as an - expression. Two consecutive single quotes ("''") are replaced by a singlequote - in the output. Formats without separators (e.g. "ddMM") are currently not supported. + Any sequence of characters enclosed in single quotes will be included + verbatim in the output string (stripped of the quotes), even if it contains + formatting characters. Two consecutive single quotes ("''") are replaced by + a single quote in the output. All other characters in the format string are + included verbatim in the output string. + + Formats without separators (e.g. "ddMM") are supported but must be used with + care, as the resulting strings aren't always reliably readable (e.g. if "dM" + produces "212" it could mean either the 2nd of December or the 21st of + February). Example format strings (assuming that the QDate is the 20 July 1969): @@ -1672,10 +1678,16 @@ QString QTime::toString(Qt::DateFormat format) const \row \li t \li the timezone (for example "CEST") \endtable - All other input characters will be ignored. Any sequence of characters that - are enclosed in single quotes will be treated as text and not be used as an - expression. Two consecutive single quotes ("''") are replaced by a singlequote - in the output. Formats without separators (e.g. "HHmm") are currently not supported. + Any sequence of characters enclosed in single quotes will be included + verbatim in the output string (stripped of the quotes), even if it contains + formatting characters. Two consecutive single quotes ("''") are replaced by + a single quote in the output. All other characters in the format string are + included verbatim in the output string. + + Formats without separators (e.g. "ddMM") are supported but must be used with + care, as the resulting strings aren't always reliably readable (e.g. if "dM" + produces "212" it could mean either the 2nd of December or the 21st of + February). Example format strings (assuming that the QTime is 14:13:09.042 and the system locale is \c{en_US}) @@ -3962,10 +3974,16 @@ QString QDateTime::toString(Qt::DateFormat format) const \row \li t \li the timezone (for example "CEST") \endtable - All other input characters will be ignored. Any sequence of characters that - are enclosed in single quotes will be treated as text and not be used as an - expression. Two consecutive single quotes ("''") are replaced by a singlequote - in the output. Formats without separators (e.g. "HHmm") are currently not supported. + Any sequence of characters enclosed in single quotes will be included + verbatim in the output string (stripped of the quotes), even if it contains + formatting characters. Two consecutive single quotes ("''") are replaced by + a single quote in the output. All other characters in the format string are + included verbatim in the output string. + + Formats without separators (e.g. "ddMM") are supported but must be used with + care, as the resulting strings aren't always reliably readable (e.g. if "dM" + produces "212" it could mean either the 2nd of December or the 21st of + February). Example format strings (assumed that the QDateTime is 21 May 2001 14:13:09.120): From 50447bb7a32dcdf5070f769cb9ef26112d2f4c04 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid <albert.astals.cid@kdab.com> Date: Thu, 31 Jan 2019 09:41:18 +0100 Subject: [PATCH 1008/1650] Initialize bit_depth ==12==WARNING: MemorySanitizer: use-of-uninitialized-value #0 0x6b90ea in setup_qt /src/qtbase/src/gui/image/qpnghandler.cpp:360:32 Change-Id: Idf04130e645dcf589dfb6260661be18a71b7bdc2 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io> --- src/gui/image/qpnghandler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index 110ee1670b..808037f434 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -233,7 +233,7 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scal png_uint_32 width; png_uint_32 height; - int bit_depth; + int bit_depth = 0; int color_type = 0; png_bytep trans_alpha = 0; png_color_16p trans_color_p = 0; @@ -678,7 +678,7 @@ QImage::Format QPngHandlerPrivate::readImageFormat() { QImage::Format format = QImage::Format_Invalid; png_uint_32 width, height; - int bit_depth, color_type = 0; + int bit_depth = 0, color_type = 0; png_colorp palette; int num_palette; png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0); From 4513cf47f14e63ae1c97fa53555ab9c63914cb7a Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen <allan.jensen@qt.io> Date: Thu, 31 Jan 2019 16:04:38 +0100 Subject: [PATCH 1009/1650] Fix merge mistake in 'Avoid picking worse formats when ...' When spliting the patch the edit become an addition instead. Task-number: QTBUG-72785 Change-Id: I92105d0e23e9b8426228f4202d46fa41f928fb94 Reviewed-by: Christian Andersen <csandersen3@gmail.com> Reviewed-by: Gatis Paeglis <gatis.paeglis@qt.io> --- src/platformsupport/glxconvenience/qglxconvenience.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/platformsupport/glxconvenience/qglxconvenience.cpp b/src/platformsupport/glxconvenience/qglxconvenience.cpp index 238f31994d..6bd73de8f3 100644 --- a/src/platformsupport/glxconvenience/qglxconvenience.cpp +++ b/src/platformsupport/glxconvenience/qglxconvenience.cpp @@ -240,7 +240,6 @@ GLXFBConfig qglx_findConfig(Display *display, int screen , QSurfaceFormat format continue; if (requestedAlpha && actualAlpha < requestedAlpha) continue; - compatibleCandidate = candidate; if (!compatibleCandidate) // Only pick up the first compatible one offered by the server compatibleCandidate = candidate; From 72b95742270afd30a7dda26344892d69fd8f8249 Mon Sep 17 00:00:00 2001 From: BogDan Vatra <bogdan@kdab.com> Date: Mon, 7 Jan 2019 16:06:16 +0200 Subject: [PATCH 1010/1650] Remove "/data/local/tmp/qt/" support Google removed this support long tima ago, also we removed it from QtCreator. Change-Id: I326da09e9e57f655eecfd1f25f39b4bd9c6784d1 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> --- .../qt5/android/bindings/QtLoader.java | 65 +++++++------------ 1 file changed, 23 insertions(+), 42 deletions(-) diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java index ae9ccc09db..9d5578ed6d 100644 --- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java +++ b/src/android/java/src/org/qtproject/qt5/android/bindings/QtLoader.java @@ -471,6 +471,7 @@ public abstract class QtLoader { } { + // why can't we load the plugins directly from libs ?!?! String key = BUNDLED_IN_LIB_RESOURCE_ID_KEY; if (m_contextInfo.metaData.containsKey(key)) { String[] list = m_context.getResources().getStringArray(m_contextInfo.metaData.getInt(key)); @@ -589,27 +590,6 @@ public abstract class QtLoader { if (apkDeployFromSystem && libsDir == null) throw new Exception(""); - String localPrefix = "/data/local/tmp/qt/"; - if (m_contextInfo.metaData.containsKey("android.app.libs_prefix")) - localPrefix = m_contextInfo.metaData.getString("android.app.libs_prefix"); - - String pluginsPrefix = localPrefix; - - boolean bundlingQtLibs = false; - if (m_contextInfo.metaData.containsKey("android.app.bundle_local_qt_libs") - && m_contextInfo.metaData.getInt("android.app.bundle_local_qt_libs") == 1) { - File dataDir = new File(m_context.getApplicationInfo().dataDir); - localPrefix = dataDir.getCanonicalPath() + "/"; - pluginsPrefix = localPrefix + "qt-reserved-files/"; - - if (libsDir == null) - throw new Exception(""); - - cleanOldCacheIfNecessary(localPrefix, pluginsPrefix); - extractBundledPluginsAndImports(pluginsPrefix, libsDir); - - bundlingQtLibs = true; - } if (m_qtLibs != null) { String libPrefix = libsDir + "lib"; @@ -617,30 +597,34 @@ public abstract class QtLoader { libraryList.add(libPrefix + m_qtLibs[i] + ".so"); } - if (m_contextInfo.metaData.containsKey("android.app.load_local_libs")) { - String[] extraLibs = m_contextInfo.metaData.getString("android.app.load_local_libs").split(":"); - for (String lib : extraLibs) { - if (lib.length() > 0) - libraryList.add((lib.startsWith("lib/") ? localPrefix : pluginsPrefix) + lib); - } - } + if (m_contextInfo.metaData.containsKey("android.app.bundle_local_qt_libs") + && m_contextInfo.metaData.getInt("android.app.bundle_local_qt_libs") == 1) { + File dataDir = new File(m_context.getApplicationInfo().dataDir); + String dataPath = dataDir.getCanonicalPath() + "/"; + String pluginsPrefix = dataPath + "qt-reserved-files/"; - String dexPaths = new String(); - String pathSeparator = System.getProperty("path.separator", ":"); - if (!bundlingQtLibs && m_contextInfo.metaData.containsKey("android.app.load_local_jars")) { - String[] jarFiles = m_contextInfo.metaData.getString("android.app.load_local_jars").split(":"); - for (String jar:jarFiles) { - if (jar.length() > 0) { - if (dexPaths.length() > 0) - dexPaths += pathSeparator; - dexPaths += localPrefix + jar; + if (libsDir == null) + throw new Exception(""); + + cleanOldCacheIfNecessary(dataPath, pluginsPrefix); + extractBundledPluginsAndImports(pluginsPrefix, libsDir); + + if (m_contextInfo.metaData.containsKey(BUNDLED_IN_LIB_RESOURCE_ID_KEY)) { + String[] extraLibs = m_contextInfo.metaData.getString("android.app.load_local_libs").split(":"); + for (String lib : extraLibs) { + if (!lib.isEmpty()) + libraryList.add(pluginsPrefix + lib); } } + + ENVIRONMENT_VARIABLES += "\tQML2_IMPORT_PATH=" + pluginsPrefix + "/qml" + + "\tQML_IMPORT_PATH=" + pluginsPrefix + "/imports" + + "\tQT_PLUGIN_PATH=" + pluginsPrefix + "/plugins"; } Bundle loaderParams = new Bundle(); loaderParams.putInt(ERROR_CODE_KEY, 0); - loaderParams.putString(DEX_PATH_KEY, dexPaths); + loaderParams.putString(DEX_PATH_KEY, new String()); loaderParams.putString(LOADER_CLASS_NAME_KEY, loaderClassName()); if (m_contextInfo.metaData.containsKey("android.app.static_init_classes")) { loaderParams.putStringArray(STATIC_INIT_CLASSES_KEY, @@ -683,10 +667,7 @@ public abstract class QtLoader { ENVIRONMENT_VARIABLES += "\tMINISTRO_ANDROID_STYLE_PATH=" + stylePath + "\tQT_ANDROID_THEMES_ROOT_PATH=" + themePath; - loaderParams.putString(ENVIRONMENT_VARIABLES_KEY, ENVIRONMENT_VARIABLES - + "\tQML2_IMPORT_PATH=" + pluginsPrefix + "/qml" - + "\tQML_IMPORT_PATH=" + pluginsPrefix + "/imports" - + "\tQT_PLUGIN_PATH=" + pluginsPrefix + "/plugins"); + loaderParams.putString(ENVIRONMENT_VARIABLES_KEY, ENVIRONMENT_VARIABLES); String appParams = null; if (APPLICATION_PARAMETERS != null) From 5de981d3bc3df874f9df35a6899345f4f61fa951 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint <Friedemann.Kleint@qt.io> Date: Tue, 29 Jan 2019 15:47:24 +0100 Subject: [PATCH 1011/1650] QtNetwork: Fix some messages in OCSP stapling Amends a8412dc020e82b45b54b0b6637b8b88b255c413a. Task-number: QTBUG-12812 Task-number: QTBUG-17158 Change-Id: Idcdf9ad39a43373097e2c3f31a62ce1b3cb46c22 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> --- src/network/ssl/qsslerror.cpp | 2 +- src/network/ssl/qsslsocket_schannel.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/network/ssl/qsslerror.cpp b/src/network/ssl/qsslerror.cpp index 74ff6987d2..02dd16a58d 100644 --- a/src/network/ssl/qsslerror.cpp +++ b/src/network/ssl/qsslerror.cpp @@ -326,7 +326,7 @@ QString QSslError::errorString() const errStr = QSslSocket::tr("The client is not authorized to request OCSP status from this server"); break; case OcspResponseCannotBeTrusted: - errStr = QSslSocket::tr("OCSP reponder's identity cannot be verified"); + errStr = QSslSocket::tr("OCSP responder's identity cannot be verified"); break; case OcspResponseCertIdUnknown: errStr = QSslSocket::tr("The identity of a certificate in an OCSP response cannot be established"); diff --git a/src/network/ssl/qsslsocket_schannel.cpp b/src/network/ssl/qsslsocket_schannel.cpp index e5f31a3fcf..06bbc86469 100644 --- a/src/network/ssl/qsslsocket_schannel.cpp +++ b/src/network/ssl/qsslsocket_schannel.cpp @@ -578,10 +578,10 @@ bool QSslSocketBackendPrivate::acquireCredentialsHandle() &findParam, nullptr); if (!chainContext) { - setErrorAndEmit(QAbstractSocket::SocketError::SslInvalidUserDataError, - QSslSocket::tr("The certificate provided can not be used for a %1.") - .arg(isClient ? QSslSocket::tr("client") - : QSslSocket::tr("server"))); + const QString message = isClient + ? QSslSocket::tr("The certificate provided can not be used for a client.") + : QSslSocket::tr("The certificate provided can not be used for a server."); + setErrorAndEmit(QAbstractSocket::SocketError::SslInvalidUserDataError, message); return false; } Q_ASSERT(chainContext->cChain == 1); From c306fdff7794d479945c4d7442c08998b7504c4d Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov <timur.pocheptsov@qt.io> Date: Thu, 31 Jan 2019 10:26:37 +0100 Subject: [PATCH 1012/1650] http2: skip content-length for content-encoding: gzip/deflate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The protocol handler now matches HTTP/1.1's protocol handler. Change-Id: Id55c10900e2bcd46e5dc65c63db77097eb4818b6 Fixes: QTBUG-73364 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> --- src/network/access/qhttp2protocolhandler.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp index df7f87efd4..d5221a4934 100644 --- a/src/network/access/qhttp2protocolhandler.cpp +++ b/src/network/access/qhttp2protocolhandler.cpp @@ -1056,6 +1056,7 @@ void QHttp2ProtocolHandler::updateStream(Stream &stream, const HPack::HttpHeader Qt::ConnectionType connectionType) { const auto httpReply = stream.reply(); + const auto &httpRequest = stream.request(); Q_ASSERT(httpReply || stream.state == Stream::remoteReserved); if (!httpReply) { @@ -1115,6 +1116,9 @@ void QHttp2ProtocolHandler::updateStream(Stream &stream, const HPack::HttpHeader if (QHttpNetworkReply::isHttpRedirect(statusCode) && redirectUrl.isValid()) httpReply->setRedirectUrl(redirectUrl); + if (httpReplyPrivate->isCompressed() && httpRequest.d->autoDecompress) + httpReplyPrivate->removeAutoDecompressHeader(); + if (QHttpNetworkReply::isHttpRedirect(statusCode) || statusCode == 401 || statusCode == 407) { // These are the status codes that can trigger uploadByteDevice->reset() From d84912838c1df383d2a9537aefa34e06a9780f08 Mon Sep 17 00:00:00 2001 From: Edward Welbourne <edward.welbourne@qt.io> Date: Wed, 16 Jan 2019 13:49:06 +0100 Subject: [PATCH 1013/1650] Add some missing expected_*.tap files for the testlib selftest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only for tests that have existing expected_*.* files for other formats, though. Change-Id: I34ca1900d88454f300e04d849a608c378009489b Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> --- .../selftests/expected_benchlibcallgrind.tap | 15 ++++++ .../selftests/expected_benchliboptions.tap | 27 ++++++++++ .../selftests/expected_blacklisted.tap | 44 +++++++++++++++ .../selftests/expected_differentexec.tap | 21 ++++++++ .../testlib/selftests/expected_multiexec.tap | 45 ++++++++++++++++ .../selftests/expected_qexecstringlist.tap | 54 +++++++++++++++++++ .../testlib/selftests/expected_silent.tap | 42 +++++++++++++++ 7 files changed, 248 insertions(+) create mode 100644 tests/auto/testlib/selftests/expected_benchlibcallgrind.tap create mode 100644 tests/auto/testlib/selftests/expected_benchliboptions.tap create mode 100644 tests/auto/testlib/selftests/expected_blacklisted.tap create mode 100644 tests/auto/testlib/selftests/expected_differentexec.tap create mode 100644 tests/auto/testlib/selftests/expected_multiexec.tap create mode 100644 tests/auto/testlib/selftests/expected_qexecstringlist.tap create mode 100644 tests/auto/testlib/selftests/expected_silent.tap diff --git a/tests/auto/testlib/selftests/expected_benchlibcallgrind.tap b/tests/auto/testlib/selftests/expected_benchlibcallgrind.tap new file mode 100644 index 0000000000..953756ac9e --- /dev/null +++ b/tests/auto/testlib/selftests/expected_benchlibcallgrind.tap @@ -0,0 +1,15 @@ +TAP version 13 +# tst_BenchlibCallgrind +TAP version 13 +# tst_BenchlibCallgrind +ok 1 - initTestCase() +ok 2 - twoHundredMillionInstructions() # SKIP This test is only defined for gcc and x86. +ok 3 - cleanupTestCase() +1..3 +# tests 3 +# pass 2 +# fail 0 +1..0 +# tests 0 +# pass 0 +# fail 0 diff --git a/tests/auto/testlib/selftests/expected_benchliboptions.tap b/tests/auto/testlib/selftests/expected_benchliboptions.tap new file mode 100644 index 0000000000..6a006ea881 --- /dev/null +++ b/tests/auto/testlib/selftests/expected_benchliboptions.tap @@ -0,0 +1,27 @@ +TAP version 13 +# tst_BenchlibOptions +ok 1 - initTestCase() +ok 2 - threeEvents() +ok 3 - cleanupTestCase() +1..3 +# tests 3 +# pass 3 +# fail 0 +TAP version 13 +# tst_BenchlibFifteenIterations +ok 1 - initTestCase() +ok 2 - threeEvents() +ok 3 - cleanupTestCase() +1..3 +# tests 3 +# pass 3 +# fail 0 +TAP version 13 +# tst_BenchlibOneHundredMinimum +ok 1 - initTestCase() +ok 2 - threeEvents() +ok 3 - cleanupTestCase() +1..3 +# tests 3 +# pass 3 +# fail 0 diff --git a/tests/auto/testlib/selftests/expected_blacklisted.tap b/tests/auto/testlib/selftests/expected_blacklisted.tap new file mode 100644 index 0000000000..7d3b2b0cc8 --- /dev/null +++ b/tests/auto/testlib/selftests/expected_blacklisted.tap @@ -0,0 +1,44 @@ +TAP version 13 +# tst_Blacklisted +ok 1 - initTestCase() +ok 2 - pass() # TODO +ok 3 - skip() # SKIP This test should SKIP +not ok 4 - fail() # TODO 'false' returned FALSE. (This test should BFAIL) + --- + type: QVERIFY + message: This test should BFAIL + wanted: true (false) + found: false (false) + expected: true (false) + actual: false (false) + at: tst_Blacklisted::fail() (qtbase/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp:62) + file: qtbase/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp + line: 62 + ... +not ok 4 - xfail() # TODO This test should BXFAIL then BPASS + --- + # This test should BXFAIL then BPASS + at: tst_Blacklisted::xfail() (qtbase/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp:68) + file: qtbase/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp + line: 68 + ... +ok 5 - xfail() # TODO +ok 6 - xpass() # TODO 'true' returned TRUE unexpectedly. (This test should BXPASS) +# This is a warning that should not appear in silent test output +# This is an internal testlib warning that should not appear in silent test output +# This is a debug message that should not appear in silent test output +# This is a critical message that should not appear in silent test output +# This is an info message that should not appear in silent test output +# This is an internal testlib info message that should not appear in silent test output +# This is a fatal error message that should still appear in silent test output +not ok 7 - messages() # TODO Received a fatal error. + --- + # Received a fatal error. + at: tst_Blacklisted::messages() (Unknown file:0) + file: Unknown file + line: 0 + ... +1..7 +# tests 7 +# pass 1 +# fail 0 diff --git a/tests/auto/testlib/selftests/expected_differentexec.tap b/tests/auto/testlib/selftests/expected_differentexec.tap new file mode 100644 index 0000000000..30ee50bc08 --- /dev/null +++ b/tests/auto/testlib/selftests/expected_differentexec.tap @@ -0,0 +1,21 @@ +********* Start testing of tst_TestA ********* +Config: Using QtTest library +PASS : tst_TestA::initTestCase() +PASS : tst_TestA::slotName() +PASS : tst_TestA::cleanupTestCase() +Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted, 0ms +********* Finished testing of tst_TestA ********* +********* Start testing of tst_TestA ********* +Config: Using QtTest library +PASS : tst_TestA::initTestCase() +PASS : tst_TestA::slotName() +PASS : tst_TestA::cleanupTestCase() +Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted, 0ms +********* Finished testing of tst_TestA ********* +********* Start testing of tst_TestB ********* +Config: Using QtTest library +PASS : tst_TestB::initTestCase() +PASS : tst_TestB::slotName() +PASS : tst_TestB::cleanupTestCase() +Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted, 0ms +********* Finished testing of tst_TestB ********* diff --git a/tests/auto/testlib/selftests/expected_multiexec.tap b/tests/auto/testlib/selftests/expected_multiexec.tap new file mode 100644 index 0000000000..ce6a7b37dd --- /dev/null +++ b/tests/auto/testlib/selftests/expected_multiexec.tap @@ -0,0 +1,45 @@ +TAP version 13 +# tst_Nothing +ok 1 - initTestCase() +ok 2 - nothing() +ok 3 - cleanupTestCase() +1..3 +# tests 3 +# pass 3 +# fail 0 +TAP version 13 +# tst_Nothing +ok 1 - initTestCase() +ok 2 - nothing() +ok 3 - cleanupTestCase() +1..3 +# tests 3 +# pass 3 +# fail 0 +TAP version 13 +# tst_Nothing +ok 1 - initTestCase() +ok 2 - nothing() +ok 3 - cleanupTestCase() +1..3 +# tests 3 +# pass 3 +# fail 0 +TAP version 13 +# tst_Nothing +ok 1 - initTestCase() +ok 2 - nothing() +ok 3 - cleanupTestCase() +1..3 +# tests 3 +# pass 3 +# fail 0 +TAP version 13 +# tst_Nothing +ok 1 - initTestCase() +ok 2 - nothing() +ok 3 - cleanupTestCase() +1..3 +# tests 3 +# pass 3 +# fail 0 diff --git a/tests/auto/testlib/selftests/expected_qexecstringlist.tap b/tests/auto/testlib/selftests/expected_qexecstringlist.tap new file mode 100644 index 0000000000..45aa7c4a3c --- /dev/null +++ b/tests/auto/testlib/selftests/expected_qexecstringlist.tap @@ -0,0 +1,54 @@ +TAP version 13 +# tst_QExecStringList +ok 1 - initTestCase() +ok 2 - testA() +ok 3 - testB(Data1) +ok 4 - testB(Data2) +ok 5 - testB(Data3) +ok 6 - testC() +ok 7 - cleanupTestCase() +1..7 +# tests 7 +# pass 7 +# fail 0 +********* Start testing of tst_QExecStringList ********* +Config: Using QtTest library +PASS : tst_QExecStringList::initTestCase() +PASS : tst_QExecStringList::testA() +PASS : tst_QExecStringList::testB(Data1) +PASS : tst_QExecStringList::testB(Data2) +PASS : tst_QExecStringList::testB(Data3) +PASS : tst_QExecStringList::testC() +PASS : tst_QExecStringList::cleanupTestCase() +Totals: 7 passed, 0 failed, 0 skipped, 0 blacklisted, 0ms +********* Finished testing of tst_QExecStringList ********* +********* Start testing of tst_QExecStringList ********* +Config: Using QtTest library +PASS : tst_QExecStringList::initTestCase() +PASS : tst_QExecStringList::testA() +PASS : tst_QExecStringList::cleanupTestCase() +Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted, 0ms +********* Finished testing of tst_QExecStringList ********* +********* Start testing of tst_QExecStringList ********* +Config: Using QtTest library +PASS : tst_QExecStringList::initTestCase() +PASS : tst_QExecStringList::testB(Data1) +PASS : tst_QExecStringList::testB(Data2) +PASS : tst_QExecStringList::testB(Data3) +PASS : tst_QExecStringList::cleanupTestCase() +Totals: 5 passed, 0 failed, 0 skipped, 0 blacklisted, 0ms +********* Finished testing of tst_QExecStringList ********* +********* Start testing of tst_QExecStringList ********* +Config: Using QtTest library +PASS : tst_QExecStringList::initTestCase() +PASS : tst_QExecStringList::testB(Data2) +PASS : tst_QExecStringList::cleanupTestCase() +Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted, 0ms +********* Finished testing of tst_QExecStringList ********* +********* Start testing of tst_QExecStringList ********* +Config: Using QtTest library +PASS : tst_QExecStringList::initTestCase() +PASS : tst_QExecStringList::testC() +PASS : tst_QExecStringList::cleanupTestCase() +Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted, 0ms +********* Finished testing of tst_QExecStringList ********* diff --git a/tests/auto/testlib/selftests/expected_silent.tap b/tests/auto/testlib/selftests/expected_silent.tap new file mode 100644 index 0000000000..c5f7716390 --- /dev/null +++ b/tests/auto/testlib/selftests/expected_silent.tap @@ -0,0 +1,42 @@ +TAP version 13 +# tst_Silent +ok 1 - initTestCase() +ok 2 - pass() +ok 3 - skip() # SKIP This test should skip +not ok 4 - fail() + --- + type: QVERIFY + message: This test should fail + wanted: true (false) + found: false (false) + expected: true (false) + actual: false (false) + at: tst_Silent::fail() (qtbase/tests/auto/testlib/selftests/silent/tst_silent.cpp:60) + file: qtbase/tests/auto/testlib/selftests/silent/tst_silent.cpp + line: 60 + ... +not ok 5 - xfail() # TODO This test should XFAIL + --- + at: tst_Silent::xfail() (qtbase/tests/auto/testlib/selftests/silent/tst_silent.cpp:66) + file: qtbase/tests/auto/testlib/selftests/silent/tst_silent.cpp + line: 66 + ... +ok 6 - xpass() # TODO 'true' returned TRUE unexpectedly. (This test should XPASS) +# This is a warning that should not appear in silent test output +# This is an internal testlib warning that should not appear in silent test output +# This is a debug message that should not appear in silent test output +# This is a critical message that should not appear in silent test output +# This is an info message that should not appear in silent test output +# This is an internal testlib info message that should not appear in silent test output +# This is a fatal error message that should still appear in silent test output +not ok 7 - messages() + --- + # Received a fatal error. + at: tst_Silent::messages() (Unknown file:0) + file: Unknown file + line: 0 + ... +1..7 +# tests 7 +# pass 3 +# fail 3 From 188eea0eb47c499f70a60f573948d529089d93b1 Mon Sep 17 00:00:00 2001 From: Thiago Macieira <thiago.macieira@intel.com> Date: Wed, 30 Jan 2019 21:13:51 -0800 Subject: [PATCH 1014/1650] Fix race condition in getting the system locale data QSharedDataPointer obeys the regular Qt container thread-safety rules: it's thread-safe in const methods but not in mutating ones. QSDP::data() is mutating, which causes a data race. For example, if the contained QLocalePrivate has a refcount of 2 and two threads see that, both threads will try to detach and then replace the pointer, but that pointer replacement is not atomic. Using QExplicitSharedDataPointer makes the race go away, since data() is now non-mutating. QESDP is used only to destroy the QLocalePrivate on program shutdown. Note that there are still race conditions relating to *updating* the locale private. Fixes: QTBUG-73403 Change-Id: Id98140e1c2f0426cabbefffd157ed6ec30a3e08f Reviewed-by: Thomas Sondergaard <thomas@sondergaard.cc> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> --- src/corelib/tools/qlocale.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 63499ab93f..df768fb875 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. +** Copyright (C) 2019 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -781,7 +781,7 @@ static const int locale_data_size = sizeof(locale_data)/sizeof(QLocaleData) - 1; Q_GLOBAL_STATIC_WITH_ARGS(QSharedDataPointer<QLocalePrivate>, defaultLocalePrivate, (QLocalePrivate::create(defaultData(), default_number_options))) -Q_GLOBAL_STATIC_WITH_ARGS(QSharedDataPointer<QLocalePrivate>, systemLocalePrivate, +Q_GLOBAL_STATIC_WITH_ARGS(QExplicitlySharedDataPointer<QLocalePrivate>, systemLocalePrivate, (QLocalePrivate::create(systemData()))) static QLocalePrivate *localePrivateByName(const QString &name) From 6666201a02817431f10c5a39c745fe31278bd612 Mon Sep 17 00:00:00 2001 From: Liang Qi <liang.qi@qt.io> Date: Thu, 31 Jan 2019 13:31:16 +0100 Subject: [PATCH 1015/1650] tests: require widgets explicitly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTQAINFRA-1975 Change-Id: I5ba4e230322dc0dbd063b48cadf9e4f96e0dc140 Reviewed-by: Tony Sarajärvi <tony.sarajarvi@qt.io> --- tests/auto/other/macgui/macgui.pro | 1 + tests/auto/other/macplist/macplist.pro | 2 ++ tests/auto/other/other.pro | 2 ++ 3 files changed, 5 insertions(+) diff --git a/tests/auto/other/macgui/macgui.pro b/tests/auto/other/macgui/macgui.pro index 75e0d595cb..6ee22bdaec 100644 --- a/tests/auto/other/macgui/macgui.pro +++ b/tests/auto/other/macgui/macgui.pro @@ -9,3 +9,4 @@ QT = core-private widgets-private testlib osx: LIBS += -framework ApplicationServices requires(mac) +requires(widgets) diff --git a/tests/auto/other/macplist/macplist.pro b/tests/auto/other/macplist/macplist.pro index 5820793cbc..df7143031a 100644 --- a/tests/auto/other/macplist/macplist.pro +++ b/tests/auto/other/macplist/macplist.pro @@ -1,3 +1,5 @@ +requires(widgets) + TEMPLATE = subdirs test.depends = app diff --git a/tests/auto/other/other.pro b/tests/auto/other/other.pro index d70c895dec..a720860288 100644 --- a/tests/auto/other/other.pro +++ b/tests/auto/other/other.pro @@ -30,6 +30,8 @@ SUBDIRS=\ gestures \ lancelot \ languagechange \ + macgui \ + macplist \ qaccessibility \ qfocusevent \ qnetworkaccessmanager_and_qprogressdialog \ From 7847e6bc02552fa7fc7f518e5cb3336f667b5a6d Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> Date: Tue, 29 Jan 2019 12:09:22 +0100 Subject: [PATCH 1016/1650] Enable deprecation warnings by default With Qt 6 in sight, people need to start moving away from their deprecated APIs, as we want to remove them all in 6.0. We are marking deprecated APIs with deprecation attributes, but by default we're disabling deprecation warnings, making them an opt-in by the user. We need to do the opposite: make deprecation warnings enabled by default, and have an opt-out define. [ChangeLog][QtCore][Important Behavior Changes] Qt now enables by default warnings when using APIs marked as deprecated. It is possible to disable such warnings by defining the QT_NO_DEPRECATED_WARNINGS macro. The old QT_DEPRECATED_WARNINGS macro which was used to enable this warning now has no effect (warnings are automatically enabled). Task-number: QTBUG-73048 Change-Id: Ie2b024fd667eb876b6ac9054cbbbc5a455cb9d5c Reviewed-by: Kai Koehne <kai.koehne@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> --- qmake/generators/projectgenerator.cpp | 10 +++------- src/corelib/global/qglobal.cpp | 26 +++++++++++++++++++------- src/corelib/global/qglobal.h | 2 +- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/qmake/generators/projectgenerator.cpp b/qmake/generators/projectgenerator.cpp index f45a90b851..ef34955eb1 100644 --- a/qmake/generators/projectgenerator.cpp +++ b/qmake/generators/projectgenerator.cpp @@ -345,14 +345,10 @@ ProjectGenerator::writeMakefile(QTextStream &t) << getWritableVar("CONFIG_REMOVE", false) << getWritableVar("INCLUDEPATH") << endl; - t << "# The following define makes your compiler warn you if you use any\n" - "# feature of Qt which has been marked as deprecated (the exact warnings\n" - "# depend on your compiler). Please consult the documentation of the\n" - "# deprecated API in order to know how to port your code away from it.\n" - "DEFINES += QT_DEPRECATED_WARNINGS\n" - "\n" - "# You can also make your code fail to compile if you use deprecated APIs.\n" + t << "# You can make your code fail to compile if you use deprecated APIs.\n" "# In order to do so, uncomment the following line.\n" + "# Please consult the documentation of the deprecated API in order to know\n" + "# how to port your code away from it.\n" "# You can also select to disable deprecated APIs only up to a certain version of Qt.\n" "#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0\n\n"; diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 3f0b78ec55..7879109930 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -1979,11 +1979,11 @@ bool qSharedBuild() Q_DECL_NOTHROW a specified version of Qt or any earlier version. The default version number is 5.0, meaning that functions deprecated in or before Qt 5.0 will not be included. - Examples: - When using a future release of Qt 5, set QT_DISABLE_DEPRECATED_BEFORE=0x050100 to - disable functions deprecated in Qt 5.1 and earlier. In any release, set - QT_DISABLE_DEPRECATED_BEFORE=0x000000 to enable any functions, including the ones - deprecated in Qt 5.0 + For instance, when using a future release of Qt 5, set + \c{QT_DISABLE_DEPRECATED_BEFORE=0x050100} to disable functions deprecated in + Qt 5.1 and earlier. In any release, set + \c{QT_DISABLE_DEPRECATED_BEFORE=0x000000} to enable all functions, including + the ones deprecated in Qt 5.0. \sa QT_DEPRECATED_WARNINGS */ @@ -1993,12 +1993,24 @@ bool qSharedBuild() Q_DECL_NOTHROW \macro QT_DEPRECATED_WARNINGS \relates <QtGlobal> - If this macro is defined, the compiler will generate warnings if API declared as + Since Qt 5.13, this macro has no effect. In Qt 5.12 and before, if this macro + is defined, the compiler will generate warnings if any API declared as deprecated by Qt is used. - \sa QT_DISABLE_DEPRECATED_BEFORE + \sa QT_DISABLE_DEPRECATED_BEFORE, QT_NO_DEPRECATED_WARNINGS */ +/*! + \macro QT_NO_DEPRECATED_WARNINGS + \relates <QtGlobal> + \since 5.13 + + This macro can be used to suppress deprecation warnings that would otherwise + be generated when using deprecated APIs. + + \sa QT_DISABLE_DEPRECATED_BEFORE +*/ + #if defined(QT_BUILD_QMAKE) // needed to bootstrap qmake static const unsigned int qt_one = 1; diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 1e4ccae65b..223ebbcabe 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -287,7 +287,7 @@ typedef double qreal; # undef QT_DEPRECATED_X # undef QT_DEPRECATED_VARIABLE # undef QT_DEPRECATED_CONSTRUCTOR -#elif defined(QT_DEPRECATED_WARNINGS) +#elif !defined(QT_NO_DEPRECATED_WARNINGS) # undef QT_DEPRECATED # define QT_DEPRECATED Q_DECL_DEPRECATED # undef QT_DEPRECATED_X From df39627fa33392a71ab79aadaa57e5c5e650e79e Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Tue, 1 Jan 2019 15:18:57 +0100 Subject: [PATCH 1017/1650] Examples: cleanup foreach usage Replace deprecated foreach macro with range-based for loop Change-Id: If919ba1d1d4acddfc1c5460ce7aebf8c49e3ac38 Reviewed-by: Paul Wicking <paul.wicking@qt.io> --- .../mimetypes/mimetypebrowser/mainwindow.cpp | 4 ++- .../corelib/serialization/savegame/game.cpp | 2 +- .../corelib/serialization/savegame/level.cpp | 2 +- .../threads/queuedcustomtype/window.cpp | 5 ++-- examples/dbus/listnames/listnames.cpp | 3 ++- examples/embedded/lightmaps/slippymap.cpp | 11 ++++---- examples/opengl/contextinfo/widget.cpp | 2 +- .../opengl/legacy/overpainting/glwidget.cpp | 2 +- examples/opengl/qopenglwidget/glwidget.cpp | 6 ++--- examples/opengl/qopenglwidget/mainwindow.cpp | 2 +- examples/qpa/windows/main.cpp | 4 +-- examples/xml/htmlinfo/main.cpp | 26 +++++++++---------- 12 files changed, 37 insertions(+), 32 deletions(-) diff --git a/examples/corelib/mimetypes/mimetypebrowser/mainwindow.cpp b/examples/corelib/mimetypes/mimetypebrowser/mainwindow.cpp index bc7ec17d1c..2e5c8069b8 100644 --- a/examples/corelib/mimetypes/mimetypebrowser/mainwindow.cpp +++ b/examples/corelib/mimetypes/mimetypebrowser/mainwindow.cpp @@ -185,7 +185,9 @@ void MainWindow::find() m_findMatches.clear(); m_findIndex = 0; - foreach (const QStandardItem *item, m_model->findItems(value, Qt::MatchContains | Qt::MatchFixedString | Qt::MatchRecursive)) + const QList<QStandardItem *> items = + m_model->findItems(value, Qt::MatchContains | Qt::MatchFixedString | Qt::MatchRecursive); + for (const QStandardItem *item : items) m_findMatches.append(m_model->indexFromItem(item)); statusBar()->showMessage(tr("%n mime types match \"%1\".", 0, m_findMatches.size()).arg(value)); updateFindActions(); diff --git a/examples/corelib/serialization/savegame/game.cpp b/examples/corelib/serialization/savegame/game.cpp index 4caec71a03..226f6fda11 100644 --- a/examples/corelib/serialization/savegame/game.cpp +++ b/examples/corelib/serialization/savegame/game.cpp @@ -185,7 +185,7 @@ void Game::write(QJsonObject &json) const json["player"] = playerObject; QJsonArray levelArray; - foreach (const Level level, mLevels) { + for (const Level level : mLevels) { QJsonObject levelObject; level.write(levelObject); levelArray.append(levelObject); diff --git a/examples/corelib/serialization/savegame/level.cpp b/examples/corelib/serialization/savegame/level.cpp index 8eda107f46..c7adc6c8ff 100644 --- a/examples/corelib/serialization/savegame/level.cpp +++ b/examples/corelib/serialization/savegame/level.cpp @@ -97,7 +97,7 @@ void Level::write(QJsonObject &json) const { json["name"] = mName; QJsonArray npcArray; - foreach (const Character npc, mNpcs) { + for (const Character npc : mNpcs) { QJsonObject npcObject; npc.write(npcObject); npcArray.append(npcObject); diff --git a/examples/corelib/threads/queuedcustomtype/window.cpp b/examples/corelib/threads/queuedcustomtype/window.cpp index 2cefba1e17..0d3f80aba4 100644 --- a/examples/corelib/threads/queuedcustomtype/window.cpp +++ b/examples/corelib/threads/queuedcustomtype/window.cpp @@ -89,9 +89,10 @@ Window::Window() void Window::loadImage() { QStringList formats; - foreach (QByteArray format, QImageReader::supportedImageFormats()) + const QList<QByteArray> supportedFormats = QImageReader::supportedImageFormats(); + for (const QByteArray &format : supportedFormats) if (format.toLower() == format) - formats.append("*." + format); + formats.append(QLatin1String("*.") + QString::fromLatin1(format)); QString newPath = QFileDialog::getOpenFileName(this, tr("Open Image"), path, tr("Image files (%1)").arg(formats.join(' '))); diff --git a/examples/dbus/listnames/listnames.cpp b/examples/dbus/listnames/listnames.cpp index c0afec062d..50203da73d 100644 --- a/examples/dbus/listnames/listnames.cpp +++ b/examples/dbus/listnames/listnames.cpp @@ -62,7 +62,8 @@ void method1() qDebug() << "Error:" << reply.error().message(); exit(1); } - foreach (QString name, reply.value()) + const QStringList values = reply.value(); + for (const QString &name : values) qDebug() << name; } diff --git a/examples/embedded/lightmaps/slippymap.cpp b/examples/embedded/lightmaps/slippymap.cpp index ff43261700..da003981ff 100644 --- a/examples/embedded/lightmaps/slippymap.cpp +++ b/examples/embedded/lightmaps/slippymap.cpp @@ -162,7 +162,6 @@ void SlippyMap::handleNetworkData(QNetworkReply *reply) { QImage img; QPoint tp = reply->request().attribute(QNetworkRequest::User).toPoint(); - QUrl url = reply->url(); if (!reply->error()) if (!img.load(reply, 0)) img = QImage(); @@ -173,10 +172,12 @@ void SlippyMap::handleNetworkData(QNetworkReply *reply) emit updated(tileRect(tp)); // purge unused spaces - QRect bound = m_tilesRect.adjusted(-2, -2, 2, 2); - foreach(QPoint tp, m_tilePixmaps.keys()) - if (!bound.contains(tp)) - m_tilePixmaps.remove(tp); + const QRect bound = m_tilesRect.adjusted(-2, -2, 2, 2); + for (auto it = m_tilePixmaps.keyBegin(); it != m_tilePixmaps.keyEnd(); ++it) { + const QPoint &tp = *it; + if (!bound.contains(tp)) + m_tilePixmaps.remove(tp); + } download(); } diff --git a/examples/opengl/contextinfo/widget.cpp b/examples/opengl/contextinfo/widget.cpp index a5d9e98bf8..b1b7076503 100644 --- a/examples/opengl/contextinfo/widget.cpp +++ b/examples/opengl/contextinfo/widget.cpp @@ -387,7 +387,7 @@ void Widget::renderWindowReady() QList<QByteArray> extensionList = context->extensions().toList(); std::sort(extensionList.begin(), extensionList.end()); m_extensions->append(tr("Found %1 extensions:").arg(extensionList.count())); - Q_FOREACH (const QByteArray &ext, extensionList) + for (const QByteArray &ext : qAsConst(extensionList)) m_extensions->append(QString::fromLatin1(ext)); m_output->moveCursor(QTextCursor::Start); diff --git a/examples/opengl/legacy/overpainting/glwidget.cpp b/examples/opengl/legacy/overpainting/glwidget.cpp index 1ec7bd731c..f98d043c5c 100644 --- a/examples/opengl/legacy/overpainting/glwidget.cpp +++ b/examples/opengl/legacy/overpainting/glwidget.cpp @@ -201,7 +201,7 @@ void GLWidget::paintEvent(QPaintEvent *event) //! [10] QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); - foreach (Bubble *bubble, bubbles) { + for (Bubble *bubble : qAsConst(bubbles)) { if (bubble->rect().intersects(event->rect())) bubble->drawBubble(&painter); } diff --git a/examples/opengl/qopenglwidget/glwidget.cpp b/examples/opengl/qopenglwidget/glwidget.cpp index 3fe919f94b..946b2bec67 100644 --- a/examples/opengl/qopenglwidget/glwidget.cpp +++ b/examples/opengl/qopenglwidget/glwidget.cpp @@ -385,10 +385,10 @@ void GLWidget::paintGL() painter.endNativePainting(); - if (m_showBubbles) - foreach (Bubble *bubble, m_bubbles) { + if (m_showBubbles) { + for (Bubble *bubble : qAsConst(m_bubbles)) bubble->drawBubble(&painter); - } + } if (const int elapsed = m_time.elapsed()) { QString framesPerSecond; diff --git a/examples/opengl/qopenglwidget/mainwindow.cpp b/examples/opengl/qopenglwidget/mainwindow.cpp index 4bd123628f..6fab3df79e 100644 --- a/examples/opengl/qopenglwidget/mainwindow.cpp +++ b/examples/opengl/qopenglwidget/mainwindow.cpp @@ -176,7 +176,7 @@ void MainWindow::timerUsageChanged(bool enabled) m_timer->start(); } else { m_timer->stop(); - foreach (QOpenGLWidget *w, m_glWidgets) + for (QOpenGLWidget *w : qAsConst(m_glWidgets)) w->update(); } } diff --git a/examples/qpa/windows/main.cpp b/examples/qpa/windows/main.cpp index 9d22d146d8..80f44ae0dc 100644 --- a/examples/qpa/windows/main.cpp +++ b/examples/qpa/windows/main.cpp @@ -79,9 +79,9 @@ int main(int argc, char **argv) // create one window on each additional screen as well - QList<QScreen *> screens = app.screens(); QList<WindowPtr> windows; - foreach (QScreen *screen, screens) { + const QList<QScreen *> screens = app.screens(); + for (QScreen *screen : screens) { if (screen == app.primaryScreen()) continue; WindowPtr window(new Window(screen)); diff --git a/examples/xml/htmlinfo/main.cpp b/examples/xml/htmlinfo/main.cpp index 6591c3ac91..22bf36f33c 100644 --- a/examples/xml/htmlinfo/main.cpp +++ b/examples/xml/htmlinfo/main.cpp @@ -50,7 +50,8 @@ #include <QtCore> -void parseHtmlFile(QTextStream &out, const QString &fileName) { +void parseHtmlFile(QTextStream &out, const QString &fileName) +{ QFile file(fileName); out << "Analysis of HTML file: " << fileName << endl; @@ -71,11 +72,11 @@ void parseHtmlFile(QTextStream &out, const QString &fileName) { while (!reader.atEnd()) { reader.readNext(); if (reader.isStartElement()) { - if (reader.name() == "title") + if (reader.name() == QLatin1String("title")) title = reader.readElementText(); - else if(reader.name() == "a") - links.append(reader.attributes().value("href").toString()); - else if(reader.name() == "p") + else if (reader.name() == QLatin1String("a")) + links.append(reader.attributes().value(QLatin1String("href")).toString()); + else if (reader.name() == QLatin1String("p")) ++paragraphCount; } } @@ -94,10 +95,10 @@ void parseHtmlFile(QTextStream &out, const QString &fileName) { << " Number of links: " << links.size() << endl << " Showing first few links:" << endl; - while(links.size() > 5) + while (links.size() > 5) links.removeLast(); - foreach(QString link, links) + for (const QString &link : qAsConst(links)) out << " " << link << endl; out << endl << endl; } @@ -108,11 +109,10 @@ int main(int argc, char **argv) QCoreApplication app(argc, argv); // get a list of all html files in the current directory - QStringList filter; - filter << "*.htm"; - filter << "*.html"; + const QStringList filter = { QStringLiteral("*.htm"), + QStringLiteral("*.html") }; - QStringList htmlFiles = QDir(":/").entryList(filter, QDir::Files); + const QStringList htmlFiles = QDir(QStringLiteral(":/")).entryList(filter, QDir::Files); QTextStream out(stdout); @@ -122,8 +122,8 @@ int main(int argc, char **argv) } // parse each html file and write the result to file/stream - foreach(QString file, htmlFiles) - parseHtmlFile(out, ":/" + file); + for (const QString &file : htmlFiles) + parseHtmlFile(out, QStringLiteral(":/") + file); return 0; } From daee9af969a04a2919a948ba1f5d314626925a9a Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Fri, 25 Jan 2019 21:15:43 +0100 Subject: [PATCH 1018/1650] QtGui: mark obsolete QPixmapCache::find() functions as deprecated QPixmapCache::find(QString) and QPixmapCache::find(QString, QPixmap&) are deprecated since Qt4 times. Explicit mark them as deprecated so they can be removed with Qt6. Change-Id: Iaf185f69afe02203559a1c812fbb4a95c9049a1d Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io> --- .../widgets/painting/shared/arthurstyle.cpp | 6 ++-- src/gui/image/qicon.cpp | 6 ++-- src/gui/image/qpixmapcache.cpp | 12 ++++--- src/gui/image/qpixmapcache.h | 4 +++ src/gui/painting/qbrush.cpp | 2 +- src/gui/painting/qpainter.cpp | 2 +- .../themes/qabstractfileiconengine.cpp | 2 +- .../xcb/nativepainting/qpaintengine_x11.cpp | 2 +- src/widgets/itemviews/qitemdelegate.cpp | 31 +++++++++++++------ src/widgets/itemviews/qitemdelegate.h | 5 +++ src/widgets/styles/qcommonstyle.cpp | 2 +- src/widgets/styles/qfusionstyle.cpp | 14 ++++----- src/widgets/styles/qstyle_p.h | 2 +- 13 files changed, 57 insertions(+), 33 deletions(-) diff --git a/examples/widgets/painting/shared/arthurstyle.cpp b/examples/widgets/painting/shared/arthurstyle.cpp index f4fc76bda6..3df9d9a6dc 100644 --- a/examples/widgets/painting/shared/arthurstyle.cpp +++ b/examples/widgets/painting/shared/arthurstyle.cpp @@ -61,10 +61,10 @@ QPixmap cached(const QString &img) { - if (QPixmap *p = QPixmapCache::find(img)) - return *p; - QPixmap pm; + if (QPixmapCache::find(img, &pm)) + return pm; + pm = QPixmap::fromImage(QImage(img), Qt::OrderedDither | Qt::OrderedAlphaDither); if (pm.isNull()) return QPixmap(); diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index 285cdf790a..c3c4b24678 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -315,9 +315,9 @@ QPixmap QPixmapIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::St % HexString<uint>(actualSize.height()); if (mode == QIcon::Active) { - if (QPixmapCache::find(key % HexString<uint>(mode), pm)) + if (QPixmapCache::find(key % HexString<uint>(mode), &pm)) return pm; // horray - if (QPixmapCache::find(key % HexString<uint>(QIcon::Normal), pm)) { + if (QPixmapCache::find(key % HexString<uint>(QIcon::Normal), &pm)) { QPixmap active = pm; if (QGuiApplication *guiApp = qobject_cast<QGuiApplication *>(qApp)) active = static_cast<QGuiApplicationPrivate*>(QObjectPrivate::get(guiApp))->applyQIconStyleHelper(QIcon::Active, pm); @@ -326,7 +326,7 @@ QPixmap QPixmapIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::St } } - if (!QPixmapCache::find(key % HexString<uint>(mode), pm)) { + if (!QPixmapCache::find(key % HexString<uint>(mode), &pm)) { if (pm.size() != actualSize) pm = pm.scaled(actualSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); if (pe->mode != mode && mode != QIcon::Normal) { diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp index 3d1652f68b..66907bebd7 100644 --- a/src/gui/image/qpixmapcache.cpp +++ b/src/gui/image/qpixmapcache.cpp @@ -469,10 +469,13 @@ QPixmapCacheEntry::~QPixmapCacheEntry() pm_cache()->releaseKey(key); } +#if QT_DEPRECATED_SINCE(5, 13) /*! \obsolete \overload + Use bool find(const QString &, QPixmap *) instead. + Returns the pixmap associated with the \a key in the cache, or null if there is no such pixmap. @@ -494,13 +497,14 @@ QPixmap *QPixmapCache::find(const QString &key) /*! \obsolete - Use bool find(const QString&, QPixmap*) instead. + Use bool find(const QString &, QPixmap *) instead. */ -bool QPixmapCache::find(const QString &key, QPixmap& pixmap) +bool QPixmapCache::find(const QString &key, QPixmap &pixmap) { return find(key, &pixmap); } +#endif /*! Looks for a cached pixmap associated with the given \a key in the cache. @@ -513,7 +517,7 @@ bool QPixmapCache::find(const QString &key, QPixmap& pixmap) \snippet code/src_gui_image_qpixmapcache.cpp 1 */ -bool QPixmapCache::find(const QString &key, QPixmap* pixmap) +bool QPixmapCache::find(const QString &key, QPixmap *pixmap) { QPixmap *ptr = pm_cache()->object(key); if (ptr && pixmap) @@ -530,7 +534,7 @@ bool QPixmapCache::find(const QString &key, QPixmap* pixmap) \since 4.6 */ -bool QPixmapCache::find(const Key &key, QPixmap* pixmap) +bool QPixmapCache::find(const Key &key, QPixmap *pixmap) { //The key is not valid anymore, a flush happened before probably if (!key.d || !key.d->isValid) diff --git a/src/gui/image/qpixmapcache.h b/src/gui/image/qpixmapcache.h index ea10ab1b76..12d05b00f3 100644 --- a/src/gui/image/qpixmapcache.h +++ b/src/gui/image/qpixmapcache.h @@ -76,8 +76,12 @@ public: static int cacheLimit(); static void setCacheLimit(int); +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X("Use bool find(const QString &, QPixmap *) instead") static QPixmap *find(const QString &key); + QT_DEPRECATED_X("Use bool find(const QString &, QPixmap *) instead") static bool find(const QString &key, QPixmap &pixmap); +#endif static bool find(const QString &key, QPixmap *pixmap); static bool find(const Key &key, QPixmap *pixmap); static bool insert(const QString &key, const QPixmap &pixmap); diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp index 860653cc4c..abfa8d41bb 100644 --- a/src/gui/painting/qbrush.cpp +++ b/src/gui/painting/qbrush.cpp @@ -111,7 +111,7 @@ Q_GUI_EXPORT QPixmap qt_pixmapForBrush(int brushStyle, bool invert) QString key = QLatin1String("$qt-brush$") % HexString<uint>(brushStyle) % QLatin1Char(invert ? '1' : '0'); - if (!QPixmapCache::find(key, pm)) { + if (!QPixmapCache::find(key, &pm)) { pm = QBitmap::fromData(QSize(8, 8), qt_patternForBrush(brushStyle, invert), QImage::Format_MonoLSB); QPixmapCache::insert(key, pm); diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index df2f5e11d3..6626768d51 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -6210,7 +6210,7 @@ static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen) % HexString<qreal>(pen.widthF()); QPixmap pixmap; - if (QPixmapCache::find(key, pixmap)) + if (QPixmapCache::find(key, &pixmap)) return pixmap; const qreal halfPeriod = qMax(qreal(2), qreal(radiusBase * 1.61803399)); // the golden ratio diff --git a/src/platformsupport/themes/qabstractfileiconengine.cpp b/src/platformsupport/themes/qabstractfileiconengine.cpp index 192ed00510..c5800d9119 100644 --- a/src/platformsupport/themes/qabstractfileiconengine.cpp +++ b/src/platformsupport/themes/qabstractfileiconengine.cpp @@ -76,7 +76,7 @@ QPixmap QAbstractFileIconEngine::pixmap(const QSize &size, QIcon::Mode mode, key += QLatin1Char('_') + QString::number(size.width()); QPixmap result; - if (!QPixmapCache::find(key, result)) { + if (!QPixmapCache::find(key, &result)) { result = filePixmap(size, mode, state); if (!result.isNull()) QPixmapCache::insert(key, result); diff --git a/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp b/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp index a3e6cedecd..2688d6e884 100644 --- a/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp +++ b/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp @@ -458,7 +458,7 @@ static QPixmap qt_patternForAlpha(uchar alpha, int screen) % HexString<uchar>(alpha) % HexString<int>(screen); - if (!QPixmapCache::find(key, pm)) { + if (!QPixmapCache::find(key, &pm)) { // #### why not use a mono image here???? QImage pattern(DITHER_SIZE, DITHER_SIZE, QImage::Format_ARGB32); pattern.fill(0xffffffff); diff --git a/src/widgets/itemviews/qitemdelegate.cpp b/src/widgets/itemviews/qitemdelegate.cpp index 16d4a21f50..f85004c49c 100644 --- a/src/widgets/itemviews/qitemdelegate.cpp +++ b/src/widgets/itemviews/qitemdelegate.cpp @@ -724,8 +724,8 @@ void QItemDelegate::drawDecoration(QPainter *painter, const QStyleOptionViewItem QPoint p = QStyle::alignedRect(option.direction, option.decorationAlignment, pixmap.size(), rect).topLeft(); if (option.state & QStyle::State_Selected) { - QPixmap *pm = selected(pixmap, option.palette, option.state & QStyle::State_Enabled); - painter->drawPixmap(p, *pm); + const QPixmap pm = selectedPixmap(pixmap, option.palette, option.state & QStyle::State_Enabled); + painter->drawPixmap(p, pm); } else { painter->drawPixmap(p, pixmap); } @@ -1001,17 +1001,29 @@ static QString qPixmapSerial(quint64 i, bool enabled) return QString((const QChar *)ptr, int(&arr[sizeof(arr) / sizeof(ushort)] - ptr)); } +#if QT_DEPRECATED_SINCE(5, 13) +QPixmap *QItemDelegate::selected(const QPixmap &pixmap, const QPalette &palette, bool enabled) const +{ + const QString key = qPixmapSerial(pixmap.cacheKey(), enabled); + QPixmap *pm = QPixmapCache::find(key); + if (pm) + return pm; + selectedPixmap(pixmap, palette, enabled); + return QPixmapCache::find(key); +} +#endif + /*! \internal Returns the selected version of the given \a pixmap using the given \a palette. The \a enabled argument decides whether the normal or disabled highlight color of the palette is used. */ -QPixmap *QItemDelegate::selected(const QPixmap &pixmap, const QPalette &palette, bool enabled) const +QPixmap QItemDelegate::selectedPixmap(const QPixmap &pixmap, const QPalette &palette, bool enabled) { - QString key = qPixmapSerial(pixmap.cacheKey(), enabled); - QPixmap *pm = QPixmapCache::find(key); - if (!pm) { + const QString key = qPixmapSerial(pixmap.cacheKey(), enabled); + QPixmap pm; + if (!QPixmapCache::find(key, &pm)) { QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied); QColor color = palette.color(enabled ? QPalette::Normal : QPalette::Disabled, @@ -1023,13 +1035,12 @@ QPixmap *QItemDelegate::selected(const QPixmap &pixmap, const QPalette &palette, painter.fillRect(0, 0, img.width(), img.height(), color); painter.end(); - QPixmap selected = QPixmap(QPixmap::fromImage(img)); - int n = (img.sizeInBytes() >> 10) + 1; + pm = QPixmap(QPixmap::fromImage(img)); + const int n = (img.sizeInBytes() >> 10) + 1; if (QPixmapCache::cacheLimit() < n) QPixmapCache::setCacheLimit(n); - QPixmapCache::insert(key, selected); - pm = QPixmapCache::find(key); + QPixmapCache::insert(key, pm); } return pm; } diff --git a/src/widgets/itemviews/qitemdelegate.h b/src/widgets/itemviews/qitemdelegate.h index 539dec4374..e504615fb2 100644 --- a/src/widgets/itemviews/qitemdelegate.h +++ b/src/widgets/itemviews/qitemdelegate.h @@ -113,7 +113,12 @@ protected: const QStyleOptionViewItem &option) const; QPixmap decoration(const QStyleOptionViewItem &option, const QVariant &variant) const; + +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X("Use selectedPixmap() instead") QPixmap *selected(const QPixmap &pixmap, const QPalette &palette, bool enabled) const; +#endif + static QPixmap selectedPixmap(const QPixmap &pixmap, const QPalette &palette, bool enabled); QRect doCheck(const QStyleOptionViewItem &option, const QRect &bounding, const QVariant &variant) const; diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 2bfc1acc26..1980dc47a9 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -751,7 +751,7 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q QString pixmapName = QStyleHelper::uniqueName(QLatin1String("$qt_ia-") % QLatin1String(metaObject()->className()), opt, QSize(size, size)) % HexString<uint>(pe); - if (!QPixmapCache::find(pixmapName, pixmap)) { + if (!QPixmapCache::find(pixmapName, &pixmap)) { qreal pixelRatio = p->device()->devicePixelRatioF(); int border = qRound(pixelRatio*(size/5)); int sqsize = qRound(pixelRatio*(2*(size/2))); diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp index 7c58adeb85..0e95d6efa4 100644 --- a/src/widgets/styles/qfusionstyle.cpp +++ b/src/widgets/styles/qfusionstyle.cpp @@ -261,7 +261,7 @@ static void qt_fusion_draw_arrow(Qt::ArrowType type, QPainter *painter, const QS QString cacheKey = QStyleHelper::uniqueName(QLatin1String("fusion-arrow"), option, rect.size()) % HexString<uint>(type) % HexString<uint>(color.rgba()); - if (!QPixmapCache::find(cacheKey, cachePixmap)) { + if (!QPixmapCache::find(cacheKey, &cachePixmap)) { cachePixmap = styleCachePixmap(rect.size()); cachePixmap.fill(Qt::transparent); QPainter cachePainter(&cachePixmap); @@ -1272,7 +1272,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio pixmapName += QString::number(- int(header->orientation)); QPixmap cache; - if (!QPixmapCache::find(pixmapName, cache)) { + if (!QPixmapCache::find(pixmapName, &cache)) { cache = styleCachePixmap(rect.size()); cache.fill(Qt::transparent); QRect pixmapRect(0, 0, rect.width(), rect.height()); @@ -2030,7 +2030,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption if (const QStyleOptionSpinBox *spinBox = qstyleoption_cast<const QStyleOptionSpinBox *>(option)) { QPixmap cache; QString pixmapName = QStyleHelper::uniqueName(QLatin1String("spinbox"), spinBox, spinBox->rect.size()); - if (!QPixmapCache::find(pixmapName, cache)) { + if (!QPixmapCache::find(pixmapName, &cache)) { cache = styleCachePixmap(spinBox->rect.size()); cache.fill(Qt::transparent); @@ -2745,7 +2745,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption if (!comboBox->frame) pixmapName += QLatin1String("-frameless"); - if (!QPixmapCache::find(pixmapName, cache)) { + if (!QPixmapCache::find(pixmapName, &cache)) { cache = styleCachePixmap(comboBox->rect.size()); cache.fill(Qt::transparent); QPainter cachePainter(&cache); @@ -2852,7 +2852,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption QRect pixmapRect(0, 0, groove.width(), groove.height()); // draw background groove - if (!QPixmapCache::find(groovePixmapName, cache)) { + if (!QPixmapCache::find(groovePixmapName, &cache)) { cache = styleCachePixmap(pixmapRect.size()); cache.fill(Qt::transparent); QPainter groovePainter(&cache); @@ -2880,7 +2880,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption // draw blue groove highlight QRect clipRect; groovePixmapName += QLatin1String("_blue"); - if (!QPixmapCache::find(groovePixmapName, cache)) { + if (!QPixmapCache::find(groovePixmapName, &cache)) { cache = styleCachePixmap(pixmapRect.size()); cache.fill(Qt::transparent); QPainter groovePainter(&cache); @@ -2987,7 +2987,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption // draw handle if ((option->subControls & SC_SliderHandle) ) { QString handlePixmapName = QStyleHelper::uniqueName(QLatin1String("slider_handle"), option, handle.size()); - if (!QPixmapCache::find(handlePixmapName, cache)) { + if (!QPixmapCache::find(handlePixmapName, &cache)) { cache = styleCachePixmap(handle.size()); cache.fill(Qt::transparent); QRect pixmapRect(0, 0, handle.width(), handle.height()); diff --git a/src/widgets/styles/qstyle_p.h b/src/widgets/styles/qstyle_p.h index 94e4540d0b..cdea29f944 100644 --- a/src/widgets/styles/qstyle_p.h +++ b/src/widgets/styles/qstyle_p.h @@ -96,7 +96,7 @@ inline QPixmap styleCachePixmap(const QSize &size) int txType = painter->deviceTransform().type() | painter->worldTransform().type(); \ bool doPixmapCache = (!option->rect.isEmpty()) \ && ((txType <= QTransform::TxTranslate) || (painter->deviceTransform().type() == QTransform::TxScale)); \ - if (doPixmapCache && QPixmapCache::find(unique, internalPixmapCache)) { \ + if (doPixmapCache && QPixmapCache::find(unique, &internalPixmapCache)) { \ painter->drawPixmap(option->rect.topLeft(), internalPixmapCache); \ } else { \ if (doPixmapCache) { \ From e56401818b1aae9856a5334f530c4eda33788429 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Sat, 26 Jan 2019 13:02:58 +0100 Subject: [PATCH 1019/1650] QtGui/QPainter: mark obsolete functions as deprecated Mark some long obsolete functions as deprecated so the can be removed with Qt6: - initFrom() - setMatrix()/matrix()/deviceMatrix()/resetMatrix() - setWorldMatrix()/worldMatrix()/combinedMatrix() - setMatrixEnabled()/matrixEnabled() - drawRoundRect() - setRedirected()/redirected()/restoreRedirected() Change-Id: I0daed72c0ef06c192309f02366a7201154e75ac9 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io> --- src/gui/image/qpicture.cpp | 2 +- src/gui/painting/qpainter.cpp | 22 ++++++++++++++-- src/gui/painting/qpainter.h | 47 ++++++++++++++++++++++------------ src/widgets/kernel/qwidget.cpp | 4 +-- 4 files changed, 53 insertions(+), 22 deletions(-) diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp index 7eede5ee26..51a9575fd0 100644 --- a/src/gui/image/qpicture.cpp +++ b/src/gui/image/qpicture.cpp @@ -858,7 +858,7 @@ bool QPicture::exec(QPainter *painter, QDataStream &s, int nrecords) break; case QPicturePrivate::PdcSetWXform: s >> i_8; - painter->setMatrixEnabled(i_8); + painter->setWorldMatrixEnabled(i_8); break; case QPicturePrivate::PdcSetWMatrix: if (d->formatMajor >= 8) { diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 6626768d51..36f0d1d5b9 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -1547,6 +1547,7 @@ bool QPainter::isActive() const return d->engine; } +#if QT_DEPRECATED_SINCE(5, 13) /*! Initializes the painters pen, background and font to the same as the given \a device. @@ -1574,7 +1575,7 @@ void QPainter::initFrom(const QPaintDevice *device) d->engine->setDirty(QPaintEngine::DirtyFont); } } - +#endif /*! Saves the current painter state (pushes the state onto a stack). A @@ -2885,6 +2886,7 @@ void QPainter::setClipRegion(const QRegion &r, Qt::ClipOperation op) d->updateState(d->state); } +#if QT_DEPRECATED_SINCE(5, 13) /*! \since 4.2 \obsolete @@ -3048,7 +3050,7 @@ void QPainter::resetMatrix() { resetTransform(); } - +#endif /*! \since 4.2 @@ -3099,6 +3101,7 @@ bool QPainter::worldMatrixEnabled() const return d->state->WxF; } +#if QT_DEPRECATED_SINCE(5, 13) /*! \obsolete @@ -3124,6 +3127,7 @@ bool QPainter::matrixEnabled() const { return worldMatrixEnabled(); } +#endif /*! Scales the coordinate system by (\a{sx}, \a{sy}). @@ -4182,6 +4186,7 @@ void QPainter::drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius, Draws the given rectangle \a x, \a y, \a w, \a h with rounded corners. */ +#if QT_DEPRECATED_SINCE(5, 13) /*! \obsolete @@ -4209,6 +4214,10 @@ void QPainter::drawRoundRect(const QRectF &r, int xRnd, int yRnd) Draws the rectangle \a r with rounded corners. */ +void QPainter::drawRoundRect(const QRect &rect, int xRnd, int yRnd) +{ + drawRoundRect(QRectF(rect), xRnd, yRnd); +} /*! \obsolete @@ -4219,6 +4228,11 @@ void QPainter::drawRoundRect(const QRectF &r, int xRnd, int yRnd) Draws the rectangle \a x, \a y, \a w, \a h with rounded corners. */ +void QPainter::drawRoundRect(int x, int y, int w, int h, int xRnd, int yRnd) +{ + drawRoundRect(QRectF(x, y, w, h), xRnd, yRnd); +} +#endif /*! \fn void QPainter::drawEllipse(const QRectF &rectangle) @@ -7378,6 +7392,7 @@ void QPainter::setViewTransformEnabled(bool enable) d->updateMatrix(); } +#if QT_DEPRECATED_SINCE(5, 13) /*! \threadsafe @@ -7458,6 +7473,7 @@ QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset) Q_UNUSED(offset) return 0; } +#endif void qt_format_text(const QFont &fnt, const QRectF &_r, int tf, const QString& str, QRectF *brect, @@ -8067,6 +8083,7 @@ QFont QPaintEngineState::font() const return static_cast<const QPainterState *>(this)->font; } +#if QT_DEPRECATED_SINCE(5, 13) /*! \since 4.2 \obsolete @@ -8089,6 +8106,7 @@ QMatrix QPaintEngineState::matrix() const return st->matrix.toAffine(); } +#endif /*! \since 4.3 diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h index 87c4899f0b..843f24e3e1 100644 --- a/src/gui/painting/qpainter.h +++ b/src/gui/painting/qpainter.h @@ -132,7 +132,10 @@ public: bool end(); bool isActive() const; +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X("Use begin(QPaintDevice*) instead") void initFrom(const QPaintDevice *device); +#endif enum CompositionMode { CompositionMode_SourceOver, @@ -232,28 +235,40 @@ public: void restore(); // XForm functions +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X("Use setTransform() instead") void setMatrix(const QMatrix &matrix, bool combine = false); + QT_DEPRECATED_X("Use transform() instead") const QMatrix &matrix() const; + QT_DEPRECATED_X("Use deviceTransform() instead") const QMatrix &deviceMatrix() const; + QT_DEPRECATED_X("Use resetTransform() instead") void resetMatrix(); +#endif void setTransform(const QTransform &transform, bool combine = false); const QTransform &transform() const; const QTransform &deviceTransform() const; void resetTransform(); +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X("Use setWorldTransform() instead") void setWorldMatrix(const QMatrix &matrix, bool combine = false); + QT_DEPRECATED_X("Use worldTransform() instead") const QMatrix &worldMatrix() const; + QT_DEPRECATED_X("Use combinedTransform() instead") + QMatrix combinedMatrix() const; + QT_DEPRECATED_X("Use setWorldMatrixEnabled() instead") + void setMatrixEnabled(bool enabled); + QT_DEPRECATED_X("Use worldMatrixEnabled() instead") + bool matrixEnabled() const; +#endif void setWorldTransform(const QTransform &matrix, bool combine = false); const QTransform &worldTransform() const; - QMatrix combinedMatrix() const; QTransform combinedTransform() const; - void setMatrixEnabled(bool enabled); - bool matrixEnabled() const; - void setWorldMatrixEnabled(bool enabled); bool worldMatrixEnabled() const; @@ -355,9 +370,14 @@ public: inline void drawRoundedRect(const QRect &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode = Qt::AbsoluteSize); +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X("Use drawRoundedRect(..., Qt::RelativeSize) instead") void drawRoundRect(const QRectF &r, int xround = 25, int yround = 25); - inline void drawRoundRect(int x, int y, int w, int h, int = 25, int = 25); - inline void drawRoundRect(const QRect &r, int xround = 25, int yround = 25); + QT_DEPRECATED_X("Use drawRoundedRect(..., Qt::RelativeSize) instead") + void drawRoundRect(int x, int y, int w, int h, int = 25, int = 25); + QT_DEPRECATED_X("Use drawRoundedRect(..., Qt::RelativeSize) instead") + void drawRoundRect(const QRect &r, int xround = 25, int yround = 25); +#endif void drawTiledPixmap(const QRectF &rect, const QPixmap &pm, const QPointF &offset = QPointF()); inline void drawTiledPixmap(int x, int y, int w, int h, const QPixmap &, int sx=0, int sy=0); @@ -464,10 +484,15 @@ public: QPaintEngine *paintEngine() const; +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X("Use QWidget::render() instead") static void setRedirected(const QPaintDevice *device, QPaintDevice *replacement, const QPoint& offset = QPoint()); + QT_DEPRECATED_X("Use QWidget::render() instead") static QPaintDevice *redirected(const QPaintDevice *device, QPoint *offset = nullptr); + QT_DEPRECATED_X("Use QWidget::render() instead") static void restoreRedirected(const QPaintDevice *device); +#endif void beginNativePainting(); void endNativePainting(); @@ -629,16 +654,6 @@ inline void QPainter::drawPoints(const QPolygon &points) drawPoints(points.constData(), points.size()); } -inline void QPainter::drawRoundRect(int x, int y, int w, int h, int xRnd, int yRnd) -{ - drawRoundRect(QRectF(x, y, w, h), xRnd, yRnd); -} - -inline void QPainter::drawRoundRect(const QRect &rect, int xRnd, int yRnd) -{ - drawRoundRect(QRectF(rect), xRnd, yRnd); -} - inline void QPainter::drawRoundedRect(int x, int y, int w, int h, qreal xRadius, qreal yRadius, Qt::SizeMode mode) { diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index c0430bec23..3b1d82df18 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -5737,12 +5737,10 @@ void QWidgetPrivate::render(QPaintDevice *target, const QPoint &targetOffset, QPoint offset = targetOffset; offset -= paintRegion.boundingRect().topLeft(); QPoint redirectionOffset; - QPaintDevice *redirected = 0; + QPaintDevice *redirected = nullptr; if (target->devType() == QInternal::Widget) redirected = static_cast<QWidget *>(target)->d_func()->redirected(&redirectionOffset); - if (!redirected) - redirected = QPainter::redirected(target, &redirectionOffset); if (redirected) { target = redirected; From 860bfc69e44c6b8d3cd0263c5afc729292aa639d Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Sat, 26 Jan 2019 13:11:41 +0100 Subject: [PATCH 1020/1650] QtGui/QPainterPath: mark obsolete functions as deprecated Mark some long obsolete functions as deprecated so the can be removed with Qt6: - addRoundRect() - subtractedInverted() Change-Id: I4707c07e983a4ac65ec3706d25b09ec01a9de62c Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io> --- src/gui/painting/qpainterpath.cpp | 25 ++++++++++++++++++ src/gui/painting/qpainterpath.h | 43 ++++++++++--------------------- 2 files changed, 39 insertions(+), 29 deletions(-) diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp index 3687bcf7d0..cb8bb9dfcf 100644 --- a/src/gui/painting/qpainterpath.cpp +++ b/src/gui/painting/qpainterpath.cpp @@ -3242,6 +3242,7 @@ void QPainterPath::addRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadi Adds the given rectangle \a x, \a y, \a w, \a h with rounded corners to the path. */ +#if QT_DEPRECATED_SINCE(5, 13) /*! \obsolete @@ -3308,6 +3309,17 @@ void QPainterPath::addRoundRect(const QRectF &r, int xRnd, int yRnd) \sa addRoundedRect() */ +void QPainterPath::addRoundRect(const QRectF &rect, + int roundness) +{ + int xRnd = roundness; + int yRnd = roundness; + if (rect.width() > rect.height()) + xRnd = int(roundness * rect.height()/rect.width()); + else + yRnd = int(roundness * rect.width()/rect.height()); + addRoundRect(rect, xRnd, yRnd); +} /*! \obsolete @@ -3324,6 +3336,11 @@ void QPainterPath::addRoundRect(const QRectF &r, int xRnd, int yRnd) \sa addRoundedRect() */ +void QPainterPath::addRoundRect(qreal x, qreal y, qreal w, qreal h, + int xRnd, int yRnd) +{ + addRoundRect(QRectF(x, y, w, h), xRnd, yRnd); +} /*! \obsolete @@ -3343,6 +3360,12 @@ void QPainterPath::addRoundRect(const QRectF &r, int xRnd, int yRnd) \sa addRoundedRect() */ +void QPainterPath::addRoundRect(qreal x, qreal y, qreal w, qreal h, + int roundness) +{ + addRoundRect(QRectF(x, y, w, h), roundness); +} +#endif /*! \since 4.3 @@ -3397,6 +3420,7 @@ QPainterPath QPainterPath::subtracted(const QPainterPath &p) const return clipper.clip(QPathClipper::BoolSub); } +#if QT_DEPRECATED_SINCE(5, 13) /*! \since 4.3 \obsolete @@ -3409,6 +3433,7 @@ QPainterPath QPainterPath::subtractedInverted(const QPainterPath &p) const { return p.subtracted(*this); } +#endif /*! \since 4.4 diff --git a/src/gui/painting/qpainterpath.h b/src/gui/painting/qpainterpath.h index 770b8f48d0..a69a192767 100644 --- a/src/gui/painting/qpainterpath.h +++ b/src/gui/painting/qpainterpath.h @@ -143,12 +143,18 @@ public: qreal xRadius, qreal yRadius, Qt::SizeMode mode = Qt::AbsoluteSize); +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X("Use addRoundedRect(..., Qt::RelativeSize) instead") void addRoundRect(const QRectF &rect, int xRnd, int yRnd); - inline void addRoundRect(qreal x, qreal y, qreal w, qreal h, - int xRnd, int yRnd); - inline void addRoundRect(const QRectF &rect, int roundness); - inline void addRoundRect(qreal x, qreal y, qreal w, qreal h, - int roundness); + QT_DEPRECATED_X("Use addRoundedRect(..., Qt::RelativeSize) instead") + void addRoundRect(qreal x, qreal y, qreal w, qreal h, + int xRnd, int yRnd); + QT_DEPRECATED_X("Use addRoundedRect(..., Qt::RelativeSize) instead") + void addRoundRect(const QRectF &rect, int roundness); + QT_DEPRECATED_X("Use addRoundedRect(..., Qt::RelativeSize) instead") + void addRoundRect(qreal x, qreal y, qreal w, qreal h, + int roundness); +#endif void connectPath(const QPainterPath &path); @@ -193,7 +199,10 @@ public: Q_REQUIRED_RESULT QPainterPath united(const QPainterPath &r) const; Q_REQUIRED_RESULT QPainterPath intersected(const QPainterPath &r) const; Q_REQUIRED_RESULT QPainterPath subtracted(const QPainterPath &r) const; +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X("Use r.subtracted() instead") Q_REQUIRED_RESULT QPainterPath subtractedInverted(const QPainterPath &r) const; +#endif Q_REQUIRED_RESULT QPainterPath simplified() const; @@ -338,30 +347,6 @@ inline void QPainterPath::addRoundedRect(qreal x, qreal y, qreal w, qreal h, addRoundedRect(QRectF(x, y, w, h), xRadius, yRadius, mode); } -inline void QPainterPath::addRoundRect(qreal x, qreal y, qreal w, qreal h, - int xRnd, int yRnd) -{ - addRoundRect(QRectF(x, y, w, h), xRnd, yRnd); -} - -inline void QPainterPath::addRoundRect(const QRectF &rect, - int roundness) -{ - int xRnd = roundness; - int yRnd = roundness; - if (rect.width() > rect.height()) - xRnd = int(roundness * rect.height()/rect.width()); - else - yRnd = int(roundness * rect.width()/rect.height()); - addRoundRect(rect, xRnd, yRnd); -} - -inline void QPainterPath::addRoundRect(qreal x, qreal y, qreal w, qreal h, - int roundness) -{ - addRoundRect(QRectF(x, y, w, h), roundness); -} - inline void QPainterPath::addText(qreal x, qreal y, const QFont &f, const QString &text) { addText(QPointF(x, y), f, text); From 2bfb89e133b8dcb138e046700ef4fbecb9da8fa0 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Sun, 27 Jan 2019 17:48:33 +0100 Subject: [PATCH 1021/1650] QtWidgets: replace 0 with \nullptr in documentation Replace 0 with \nullptr in the documentation. As a drive-by also replace some 0 with nullptr in the corresponding code. Change-Id: Id8056dc2364a372e40bc04e8cb9fcc443e49fb18 Reviewed-by: Paul Wicking <paul.wicking@qt.io> --- .../graphicsview/qgraphicsgridlayout.cpp | 11 +-- src/widgets/graphicsview/qgraphicsitem.cpp | 96 ++++++++++--------- .../graphicsview/qgraphicslayoutitem.cpp | 14 +-- .../graphicsview/qgraphicsproxywidget.cpp | 4 +- src/widgets/graphicsview/qgraphicsscene.cpp | 43 +++++---- .../graphicsview/qgraphicssceneevent.cpp | 4 +- src/widgets/graphicsview/qgraphicsview.cpp | 2 +- src/widgets/graphicsview/qgraphicswidget.cpp | 32 +++---- src/widgets/itemviews/qabstractitemview.cpp | 4 +- src/widgets/itemviews/qcolumnview.cpp | 2 +- src/widgets/itemviews/qtableview.cpp | 9 +- src/widgets/itemviews/qtreewidget.cpp | 16 ++-- 12 files changed, 120 insertions(+), 117 deletions(-) diff --git a/src/widgets/graphicsview/qgraphicsgridlayout.cpp b/src/widgets/graphicsview/qgraphicsgridlayout.cpp index d9005afbef..6b7052a0ab 100644 --- a/src/widgets/graphicsview/qgraphicsgridlayout.cpp +++ b/src/widgets/graphicsview/qgraphicsgridlayout.cpp @@ -552,20 +552,19 @@ int QGraphicsGridLayout::count() const } /*! - Returns the layout item at \a index, or 0 if there is no layout item at - this index. + Returns the layout item at \a index, or \nullptr if there is no + layout item at this index. */ QGraphicsLayoutItem *QGraphicsGridLayout::itemAt(int index) const { Q_D(const QGraphicsGridLayout); if (index < 0 || index >= d->engine.itemCount()) { qWarning("QGraphicsGridLayout::itemAt: invalid index %d", index); - return 0; + return nullptr; } - QGraphicsLayoutItem *item = 0; if (QGraphicsGridLayoutEngineItem *engineItem = static_cast<QGraphicsGridLayoutEngineItem*>(d->engine.itemAt(index))) - item = engineItem->layoutItem(); - return item; + return engineItem->layoutItem(); + return nullptr; } /*! diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp index 86f3d6a2f0..4476ecded3 100644 --- a/src/widgets/graphicsview/qgraphicsitem.cpp +++ b/src/widgets/graphicsview/qgraphicsitem.cpp @@ -661,9 +661,9 @@ \value ItemSceneChange The item is moved to a new scene. This notification is also sent when the item is added to its initial scene, and when it is removed. - The item's scene() is the old scene (or 0 if the item has not been added to a - scene yet). The value argument is the new scene (i.e., a QGraphicsScene - pointer), or a null pointer if the item is removed from a scene. Do not + The item's scene() is the old scene, or \nullptr if the item has not been added + to a scene yet. The value argument is the new scene (i.e., a QGraphicsScene + pointer), or \nullptr if the item is removed from a scene. Do not override this change by passing this item to QGraphicsScene::addItem() as this notification is delivered; instead, you can return the new scene from itemChange(). Use this feature with caution; objecting to a scene change can @@ -1542,7 +1542,7 @@ void QGraphicsItemCache::purge() Constructs a QGraphicsItem with the given \a parent item. It does not modify the parent object returned by QObject::parent(). - If \a parent is 0, you can add the item to a scene by calling + If \a parent is \nullptr, you can add the item to a scene by calling QGraphicsScene::addItem(). The item will then become a top-level item. \sa QGraphicsScene::addItem(), setParentItem() @@ -1650,8 +1650,8 @@ QGraphicsItem::~QGraphicsItem() } /*! - Returns the current scene for the item, or 0 if the item is not stored in - a scene. + Returns the current scene for the item, or \nullptr if the item is + not stored in a scene. To add or move an item to a scene, call QGraphicsScene::addItem(). */ @@ -1661,15 +1661,15 @@ QGraphicsScene *QGraphicsItem::scene() const } /*! - Returns a pointer to this item's item group, or 0 if this item is not - member of a group. + Returns a pointer to this item's item group, or \nullptr if this + item is not member of a group. \sa QGraphicsItemGroup, QGraphicsScene::createItemGroup() */ QGraphicsItemGroup *QGraphicsItem::group() const { if (!d_ptr->isMemberOfGroup) - return 0; + return nullptr; QGraphicsItem *parent = const_cast<QGraphicsItem *>(this); while ((parent = parent->d_ptr->parent)) { if (QGraphicsItemGroup *group = qgraphicsitem_cast<QGraphicsItemGroup *>(parent)) @@ -1677,11 +1677,11 @@ QGraphicsItemGroup *QGraphicsItem::group() const } // Unreachable; if d_ptr->isMemberOfGroup is != 0, then one parent of this // item is a group item. - return 0; + return nullptr; } /*! - Adds this item to the item group \a group. If \a group is 0, this item is + Adds this item to the item group \a group. If \a group is \nullptr, this item is removed from any current group and added as a child of the previous group's parent. @@ -1699,7 +1699,7 @@ void QGraphicsItem::setGroup(QGraphicsItemGroup *group) /*! Returns a pointer to this item's parent item. If this item does not have a - parent, 0 is returned. + parent, \nullptr is returned. \sa setParentItem(), childItems() */ @@ -1710,8 +1710,9 @@ QGraphicsItem *QGraphicsItem::parentItem() const /*! Returns this item's top-level item. The top-level item is the item's - topmost ancestor item whose parent is 0. If an item has no parent, its own - pointer is returned (i.e., a top-level item is its own top-level item). + topmost ancestor item whose parent is \nullptr. If an item has no + parent, its own pointer is returned (i.e., a top-level item is its + own top-level item). \sa parentItem() */ @@ -1734,7 +1735,7 @@ QGraphicsItem *QGraphicsItem::topLevelItem() const QGraphicsObject *QGraphicsItem::parentObject() const { QGraphicsItem *p = d_ptr->parent; - return (p && p->d_ptr->isObject) ? static_cast<QGraphicsObject *>(p) : 0; + return (p && p->d_ptr->isObject) ? static_cast<QGraphicsObject *>(p) : nullptr; } /*! @@ -1757,23 +1758,24 @@ QGraphicsWidget *QGraphicsItem::parentWidget() const \since 4.4 Returns a pointer to the item's top level widget (i.e., the item's - ancestor whose parent is 0, or whose parent is not a widget), or 0 if this - item does not have a top level widget. If the item is its own top level - widget, this function returns a pointer to the item itself. + ancestor whose parent is \nullptr, or whose parent is not a widget), or + \nullptr if this item does not have a top level widget. If the item + is its own top level widget, this function returns a pointer to the + item itself. */ QGraphicsWidget *QGraphicsItem::topLevelWidget() const { if (const QGraphicsWidget *p = parentWidget()) return p->topLevelWidget(); - return isWidget() ? static_cast<QGraphicsWidget *>(const_cast<QGraphicsItem *>(this)) : 0; + return isWidget() ? static_cast<QGraphicsWidget *>(const_cast<QGraphicsItem *>(this)) : nullptr; } /*! \since 4.4 - Returns the item's window, or 0 if this item does not have a window. If - the item is a window, it will return itself. Otherwise it will return the - closest ancestor that is a window. + Returns the item's window, or \nullptr if this item does not have a + window. If the item is a window, it will return itself. Otherwise + it will return the closest ancestor that is a window. \sa QGraphicsWidget::isWindow() */ @@ -1782,15 +1784,15 @@ QGraphicsWidget *QGraphicsItem::window() const QGraphicsItem *p = panel(); if (p && p->isWindow()) return static_cast<QGraphicsWidget *>(p); - return 0; + return nullptr; } /*! \since 4.6 - Returns the item's panel, or 0 if this item does not have a panel. If the - item is a panel, it will return itself. Otherwise it will return the - closest ancestor that is a panel. + Returns the item's panel, or \nullptr if this item does not have a + panel. If the item is a panel, it will return itself. Otherwise it + will return the closest ancestor that is a panel. \sa isPanel(), ItemIsPanel */ @@ -1798,7 +1800,7 @@ QGraphicsItem *QGraphicsItem::panel() const { if (d_ptr->flags & ItemIsPanel) return const_cast<QGraphicsItem *>(this); - return d_ptr->parent ? d_ptr->parent->panel() : 0; + return d_ptr->parent ? d_ptr->parent->panel() : nullptr; } /*! @@ -2397,7 +2399,7 @@ bool QGraphicsItem::isVisible() const /*! \since 4.4 Returns \c true if the item is visible to \a parent; otherwise, false is - returned. \a parent can be 0, in which case this function will return + returned. \a parent can be \nullptr, in which case this function will return whether the item is visible to the scene or not. An item may not be visible to its ancestors even if isVisible() is true. It @@ -2925,7 +2927,7 @@ void QGraphicsItem::setOpacity(qreal opacity) } /*! - Returns a pointer to this item's effect if it has one; otherwise 0. + Returns a pointer to this item's effect if it has one; otherwise \nullptr. \since 4.6 */ @@ -2939,7 +2941,7 @@ QGraphicsEffect *QGraphicsItem::graphicsEffect() const Sets \a effect as the item's effect. If there already is an effect installed on this item, QGraphicsItem will delete the existing effect before installing the new \a effect. You can delete an existing effect by calling - setGraphicsEffect(0). + setGraphicsEffect(\nullptr). If \a effect is the installed effect on a different item, setGraphicsEffect() will remove the effect from the item and install it on this item. @@ -3577,7 +3579,7 @@ void QGraphicsItemPrivate::clearFocusHelper(bool giveFocusToParent, bool hiddenB /*! \since 4.6 - Returns this item's focus proxy, or 0 if this item has no + Returns this item's focus proxy, or \nullptr if this item has no focus proxy. \sa setFocusProxy(), setFocus(), hasFocus() @@ -3640,7 +3642,7 @@ void QGraphicsItem::setFocusProxy(QGraphicsItem *item) If this item, a child or descendant of this item currently has input focus, this function will return a pointer to that item. If - no descendant has input focus, 0 is returned. + no descendant has input focus, \nullptr is returned. \sa hasFocus(), setFocus(), QWidget::focusWidget() */ @@ -5790,7 +5792,7 @@ void QGraphicsItemPrivate::clearSubFocus(QGraphicsItem *rootItem, QGraphicsItem /*! \internal - Sets the focusProxy pointer to 0 for all items that have this item as their + Sets the focusProxy pointer to \nullptr for all items that have this item as their focusProxy. */ void QGraphicsItemPrivate::resetFocusProxy() @@ -6001,7 +6003,7 @@ void QGraphicsItem::scroll(qreal dx, qreal dy, const QRectF &rect) Maps the point \a point, which is in this item's coordinate system, to \a item's coordinate system, and returns the mapped coordinate. - If \a item is 0, this function returns the same as mapToScene(). + If \a item is \nullptr, this function returns the same as mapToScene(). \sa itemTransform(), mapToParent(), mapToScene(), transform(), mapFromItem(), {The Graphics View Coordinate System} @@ -6071,7 +6073,7 @@ QPointF QGraphicsItem::mapToScene(const QPointF &point) const Maps the rectangle \a rect, which is in this item's coordinate system, to \a item's coordinate system, and returns the mapped rectangle as a polygon. - If \a item is 0, this function returns the same as mapToScene(). + If \a item is \nullptr, this function returns the same as mapToScene(). \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The Graphics View Coordinate System} @@ -6142,7 +6144,7 @@ QPolygonF QGraphicsItem::mapToScene(const QRectF &rect) const \a item's coordinate system, and returns the mapped rectangle as a new rectangle (i.e., the bounding rectangle of the resulting polygon). - If \a item is 0, this function returns the same as mapRectToScene(). + If \a item is \nullptr, this function returns the same as mapRectToScene(). \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The Graphics View Coordinate System} @@ -6217,7 +6219,7 @@ QRectF QGraphicsItem::mapRectToScene(const QRectF &rect) const this item's coordinate system, and returns the mapped rectangle as a new rectangle (i.e., the bounding rectangle of the resulting polygon). - If \a item is 0, this function returns the same as mapRectFromScene(). + If \a item is \nullptr, this function returns the same as mapRectFromScene(). \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The Graphics View Coordinate System} @@ -6290,7 +6292,7 @@ QRectF QGraphicsItem::mapRectFromScene(const QRectF &rect) const Maps the polygon \a polygon, which is in this item's coordinate system, to \a item's coordinate system, and returns the mapped polygon. - If \a item is 0, this function returns the same as mapToScene(). + If \a item is \nullptr, this function returns the same as mapToScene(). \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The Graphics View Coordinate System} @@ -6337,7 +6339,7 @@ QPolygonF QGraphicsItem::mapToScene(const QPolygonF &polygon) const Maps the path \a path, which is in this item's coordinate system, to \a item's coordinate system, and returns the mapped path. - If \a item is 0, this function returns the same as mapToScene(). + If \a item is \nullptr, this function returns the same as mapToScene(). \sa itemTransform(), mapToParent(), mapToScene(), mapFromItem(), {The Graphics View Coordinate System} @@ -6384,7 +6386,7 @@ QPainterPath QGraphicsItem::mapToScene(const QPainterPath &path) const Maps the point \a point, which is in \a item's coordinate system, to this item's coordinate system, and returns the mapped coordinate. - If \a item is 0, this function returns the same as mapFromScene(). + If \a item is \nullptr, this function returns the same as mapFromScene(). \sa itemTransform(), mapFromParent(), mapFromScene(), transform(), mapToItem(), {The Graphics View Coordinate System} @@ -6456,7 +6458,7 @@ QPointF QGraphicsItem::mapFromScene(const QPointF &point) const this item's coordinate system, and returns the mapped rectangle as a polygon. - If \a item is 0, this function returns the same as mapFromScene() + If \a item is \nullptr, this function returns the same as mapFromScene() \sa itemTransform(), mapToItem(), mapFromParent(), transform(), {The Graphics View Coordinate System} @@ -6524,7 +6526,7 @@ QPolygonF QGraphicsItem::mapFromScene(const QRectF &rect) const Maps the polygon \a polygon, which is in \a item's coordinate system, to this item's coordinate system, and returns the mapped polygon. - If \a item is 0, this function returns the same as mapFromScene(). + If \a item is \nullptr, this function returns the same as mapFromScene(). \sa itemTransform(), mapToItem(), mapFromParent(), transform(), {The Graphics View Coordinate System} @@ -6569,7 +6571,7 @@ QPolygonF QGraphicsItem::mapFromScene(const QPolygonF &polygon) const Maps the path \a path, which is in \a item's coordinate system, to this item's coordinate system, and returns the mapped path. - If \a item is 0, this function returns the same as mapFromScene(). + If \a item is \nullptr, this function returns the same as mapFromScene(). \sa itemTransform(), mapFromParent(), mapFromScene(), mapToItem(), {The Graphics View Coordinate System} @@ -6633,15 +6635,15 @@ bool QGraphicsItem::isAncestorOf(const QGraphicsItem *child) const /*! \since 4.4 - Returns the closest common ancestor item of this item and \a other, or 0 - if either \a other is 0, or there is no common ancestor. + Returns the closest common ancestor item of this item and \a other, + or \nullptr if either \a other is \nullptr, or there is no common ancestor. \sa isAncestorOf() */ QGraphicsItem *QGraphicsItem::commonAncestorItem(const QGraphicsItem *other) const { if (!other) - return 0; + return nullptr; if (other == this) return const_cast<QGraphicsItem *>(this); const QGraphicsItem *thisw = this; @@ -6726,7 +6728,7 @@ void QGraphicsItem::setData(int key, const QVariant &value) \since 4.2 Returns the given \a item cast to type T if \a item is of type T; - otherwise, 0 is returned. + otherwise, \nullptr is returned. \note To make this function work correctly with custom items, reimplement the \l{QGraphicsItem::}{type()} function for each custom QGraphicsItem diff --git a/src/widgets/graphicsview/qgraphicslayoutitem.cpp b/src/widgets/graphicsview/qgraphicslayoutitem.cpp index aed154a95f..1192bad51e 100644 --- a/src/widgets/graphicsview/qgraphicslayoutitem.cpp +++ b/src/widgets/graphicsview/qgraphicslayoutitem.cpp @@ -193,7 +193,7 @@ QSizeF *QGraphicsLayoutItemPrivate::effectiveSizeHints(const QSizeF &constraint) /*! \internal - Returns the parent item of this layout, or 0 if this layout is + Returns the parent item of this layout, or \nullptr if this layout is not installed on any widget. If this is the item that the layout is installed on, it will return "itself". @@ -214,7 +214,7 @@ QGraphicsItem *QGraphicsLayoutItemPrivate::parentItem() const while (parent && parent->isLayout()) { parent = parent->parentLayoutItem(); } - return parent ? parent->graphicsItem() : 0; + return parent ? parent->graphicsItem() : nullptr; } /*! @@ -368,7 +368,7 @@ bool QGraphicsLayoutItemPrivate::hasWidthForHeight() const passing a QGraphicsLayoutItem pointer to QGraphicsLayoutItem's protected constructor, or by calling setParentLayoutItem(). The parentLayoutItem() function returns a pointer to the item's layoutItem - parent. If the item's parent is 0 or if the parent does not inherit + parent. If the item's parent is \nullptr or if the parent does not inherit from QGraphicsItem, the parentLayoutItem() function then returns \nullptr. isLayout() returns \c true if the QGraphicsLayoutItem subclass is itself a layout, or false otherwise. @@ -737,7 +737,7 @@ QRectF QGraphicsLayoutItem::geometry() const This virtual function provides the \a left, \a top, \a right and \a bottom contents margins for this QGraphicsLayoutItem. The default implementation assumes all contents margins are 0. The parameters point to values stored - in qreals. If any of the pointers is 0, that value will not be updated. + in qreals. If any of the pointers is \nullptr, that value will not be updated. \sa QGraphicsWidget::setContentsMargins() */ @@ -826,8 +826,8 @@ void QGraphicsLayoutItem::updateGeometry() } /*! - Returns the parent of this QGraphicsLayoutItem, or 0 if there is no parent, - or if the parent does not inherit from QGraphicsLayoutItem + Returns the parent of this QGraphicsLayoutItem, or \nullptr if there is + no parent, or if the parent does not inherit from QGraphicsLayoutItem (QGraphicsLayoutItem is often used through multiple inheritance with QObject-derived classes). @@ -917,7 +917,7 @@ QGraphicsItem *QGraphicsLayoutItem::graphicsItem() const * advantage of the automatic reparenting capabilities of QGraphicsLayout it * should set this value. * Note that if you delete \a item and not delete the layout item, you are - * responsible of calling setGraphicsItem(0) in order to avoid having a + * responsible of calling setGraphicsItem(\nullptr) in order to avoid having a * dangling pointer. * * \sa graphicsItem() diff --git a/src/widgets/graphicsview/qgraphicsproxywidget.cpp b/src/widgets/graphicsview/qgraphicsproxywidget.cpp index 513cf9d361..e9f092020f 100644 --- a/src/widgets/graphicsview/qgraphicsproxywidget.cpp +++ b/src/widgets/graphicsview/qgraphicsproxywidget.cpp @@ -556,7 +556,7 @@ QGraphicsProxyWidget::~QGraphicsProxyWidget() exclusively either inside or outside of Graphics View. You cannot embed a widget as long as it is is visible elsewhere in the UI, at the same time. - \a widget must be a top-level widget whose parent is 0. + \a widget must be a top-level widget whose parent is \nullptr. When the widget is embedded, its state (e.g., visible, enabled, geometry, size hints) is copied into the proxy widget. If the embedded widget is @@ -739,7 +739,7 @@ QWidget *QGraphicsProxyWidget::widget() const Returns the rectangle for \a widget, which must be a descendant of widget(), or widget() itself, in this proxy item's local coordinates. - If no widget is embedded, \a widget is 0, or \a widget is not a + If no widget is embedded, \a widget is \nullptr, or \a widget is not a descendant of the embedded widget, this function returns an empty QRectF. \sa widget() diff --git a/src/widgets/graphicsview/qgraphicsscene.cpp b/src/widgets/graphicsview/qgraphicsscene.cpp index bba992144d..db7ce5251a 100644 --- a/src/widgets/graphicsview/qgraphicsscene.cpp +++ b/src/widgets/graphicsview/qgraphicsscene.cpp @@ -2144,8 +2144,8 @@ QList<QGraphicsItem *> QGraphicsScene::collidingItems(const QGraphicsItem *item, \overload \obsolete - Returns the topmost visible item at the specified \a position, or 0 if - there are no items at this position. + Returns the topmost visible item at the specified \a position, or + \nullptr if there are no items at this position. This function is deprecated and returns incorrect results if the scene contains items that ignore transformations. Use the overload that takes @@ -2159,7 +2159,7 @@ QList<QGraphicsItem *> QGraphicsScene::collidingItems(const QGraphicsItem *item, /*! \since 4.6 - Returns the topmost visible item at the specified \a position, or 0 + Returns the topmost visible item at the specified \a position, or \nullptr if there are no items at this position. \a deviceTransform is the transformation that applies to the view, and needs to @@ -2173,7 +2173,7 @@ QGraphicsItem *QGraphicsScene::itemAt(const QPointF &position, const QTransform { const QList<QGraphicsItem *> itemsAtPoint = items(position, Qt::IntersectsItemShape, Qt::DescendingOrder, deviceTransform); - return itemsAtPoint.isEmpty() ? 0 : itemsAtPoint.first(); + return itemsAtPoint.isEmpty() ? nullptr : itemsAtPoint.first(); } /*! @@ -2182,7 +2182,7 @@ QGraphicsItem *QGraphicsScene::itemAt(const QPointF &position, const QTransform \since 4.6 Returns the topmost visible item at the position specified by (\a x, \a - y), or 0 if there are no items at this position. + y), or \nullptr if there are no items at this position. \a deviceTransform is the transformation that applies to the view, and needs to be provided if the scene contains items that ignore transformations. @@ -2199,7 +2199,7 @@ QGraphicsItem *QGraphicsScene::itemAt(const QPointF &position, const QTransform \obsolete Returns the topmost visible item at the position specified by (\a x, \a - y), or 0 if there are no items at this position. + y), or \nullptr if there are no items at this position. This convenience function is equivalent to calling \c {itemAt(QPointF(x, y))}. @@ -2941,9 +2941,9 @@ void QGraphicsScene::removeItem(QGraphicsItem *item) /*! When the scene is active, this functions returns the scene's current focus - item, or 0 if no item currently has focus. When the scene is inactive, this - functions returns the item that will gain input focus when the scene becomes - active. + item, or \nullptr if no item currently has focus. When the scene is inactive, + this functions returns the item that will gain input focus when the scene + becomes active. The focus item receives keyboard input when the scene receives a key event. @@ -2961,12 +2961,12 @@ QGraphicsItem *QGraphicsScene::focusItem() const focusReason, after removing focus from any previous item that may have had focus. - If \a item is 0, or if it either does not accept focus (i.e., it does not + If \a item is \nullptr, or if it either does not accept focus (i.e., it does not have the QGraphicsItem::ItemIsFocusable flag enabled), or is not visible or not enabled, this function only removes focus from any previous focusitem. - If item is not 0, and the scene does not currently have focus (i.e., + If item is not \nullptr, and the scene does not currently have focus (i.e., hasFocus() returns \c false), this function will call setFocus() automatically. @@ -3062,9 +3062,9 @@ bool QGraphicsScene::stickyFocus() const } /*! - Returns the current mouse grabber item, or 0 if no item is currently - grabbing the mouse. The mouse grabber item is the item that receives all - mouse events sent to the scene. + Returns the current mouse grabber item, or \nullptr if no item is + currently grabbing the mouse. The mouse grabber item is the item + that receives all mouse events sent to the scene. An item becomes a mouse grabber when it receives and accepts a mouse press event, and it stays the mouse grabber until either of @@ -5547,7 +5547,7 @@ bool QGraphicsScene::focusNextPrevChild(bool next) \a oldFocusItem is a pointer to the item that previously had focus, or 0 if no item had focus before the signal was emitted. \a newFocusItem - is a pointer to the item that gained input focus, or 0 if focus was lost. + is a pointer to the item that gained input focus, or \nullptr if focus was lost. \a reason is the reason for the focus change (e.g., if the scene was deactivated while an input field had focus, \a oldFocusItem would point to the input field item, \a newFocusItem would be 0, and \a reason would be @@ -5582,7 +5582,7 @@ QStyle *QGraphicsScene::style() const the style for all widgets in the scene that do not have a style explicitly assigned to them. - If \a style is 0, QGraphicsScene will revert to QApplication::style(). + If \a style is \nullptr, QGraphicsScene will revert to QApplication::style(). \sa style() */ @@ -5703,7 +5703,8 @@ bool QGraphicsScene::isActive() const /*! \since 4.6 - Returns the current active panel, or 0 if no panel is currently active. + Returns the current active panel, or \nullptr if no panel is + currently active. \sa QGraphicsScene::setActivePanel() */ @@ -5720,7 +5721,7 @@ QGraphicsItem *QGraphicsScene::activePanel() const deactivate any currently active panel. If the scene is currently inactive, \a item remains inactive until the - scene becomes active (or, ir \a item is 0, no item will be activated). + scene becomes active (or, ir \a item is \nullptr, no item will be activated). \sa activePanel(), isActive(), QGraphicsItem::isActive() */ @@ -5733,8 +5734,8 @@ void QGraphicsScene::setActivePanel(QGraphicsItem *item) /*! \since 4.4 - Returns the current active window, or 0 if no window is currently - active. + Returns the current active window, or \nullptr if no window is + currently active. \sa QGraphicsScene::setActiveWindow() */ @@ -5743,7 +5744,7 @@ QGraphicsWidget *QGraphicsScene::activeWindow() const Q_D(const QGraphicsScene); if (d->activePanel && d->activePanel->isWindow()) return static_cast<QGraphicsWidget *>(d->activePanel); - return 0; + return nullptr; } /*! diff --git a/src/widgets/graphicsview/qgraphicssceneevent.cpp b/src/widgets/graphicsview/qgraphicssceneevent.cpp index 398ef1aaf5..5077a39d67 100644 --- a/src/widgets/graphicsview/qgraphicssceneevent.cpp +++ b/src/widgets/graphicsview/qgraphicssceneevent.cpp @@ -319,8 +319,8 @@ QGraphicsSceneEvent::~QGraphicsSceneEvent() } /*! - Returns the widget where the event originated, or 0 if the event - originates from another application. + Returns the widget where the event originated, or \nullptr if the + event originates from another application. */ QWidget *QGraphicsSceneEvent::widget() const { diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp index 24647dd74c..5fe520132f 100644 --- a/src/widgets/graphicsview/qgraphicsview.cpp +++ b/src/widgets/graphicsview/qgraphicsview.cpp @@ -1676,7 +1676,7 @@ void QGraphicsView::setInteractive(bool allowed) /*! Returns a pointer to the scene that is currently visualized in the - view. If no scene is currently visualized, 0 is returned. + view. If no scene is currently visualized, \nullptr is returned. \sa setScene() */ diff --git a/src/widgets/graphicsview/qgraphicswidget.cpp b/src/widgets/graphicsview/qgraphicswidget.cpp index a4534c73dd..c994136091 100644 --- a/src/widgets/graphicsview/qgraphicswidget.cpp +++ b/src/widgets/graphicsview/qgraphicswidget.cpp @@ -159,7 +159,7 @@ QT_BEGIN_NAMESPACE manage the relationships between parent and child items. These functions control the stacking order of items as well as their ownership. - \note The QObject::parent() should always return 0 for QGraphicsWidgets, + \note The QObject::parent() should always return \nullptr for QGraphicsWidgets, but this policy is not strictly defined. \sa QGraphicsProxyWidget, QGraphicsItem, {Widgets and Layouts} @@ -518,7 +518,7 @@ void QGraphicsWidget::setContentsMargins(qreal left, qreal top, qreal right, qre /*! Gets the widget's contents margins. The margins are stored in \a left, \a top, \a right and \a bottom, as pointers to qreals. Each argument can - be \e {omitted} by passing 0. + be \e {omitted} by passing \nullptr. \sa setContentsMargins() */ @@ -573,7 +573,7 @@ void QGraphicsWidget::setWindowFrameMargins(qreal left, qreal top, qreal right, /*! Gets the widget's window frame margins. The margins are stored in \a left, \a top, \a right and \a bottom as pointers to qreals. Each argument can - be \e {omitted} by passing 0. + be \e {omitted} by passing \nullptr. \sa setWindowFrameMargins(), windowFrameRect() */ @@ -780,7 +780,7 @@ QSizeF QGraphicsWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) c \brief The layout of the widget Any existing layout manager is deleted before the new layout is assigned. If - \a layout is 0, the widget is left without a layout. Existing subwidgets' + \a layout is \nullptr, the widget is left without a layout. Existing subwidgets' geometries will remain unaffected. QGraphicsWidget takes ownership of \a layout. @@ -792,7 +792,7 @@ QSizeF QGraphicsWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) c explicitly managed by \a layout remain unaffected by the layout after it has been assigned to this widget. - If no layout is currently managing this widget, layout() will return 0. + If no layout is currently managing this widget, layout() will return \nullptr. */ @@ -803,8 +803,8 @@ QSizeF QGraphicsWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) c */ /*! - Returns this widget's layout, or 0 if no layout is currently managing this - widget. + Returns this widget's layout, or \nullptr if no layout is currently + managing this widget. \sa setLayout() */ @@ -818,7 +818,7 @@ QGraphicsLayout *QGraphicsWidget::layout() const \fn void QGraphicsWidget::setLayout(QGraphicsLayout *layout) Sets the layout for this widget to \a layout. Any existing layout manager - is deleted before the new layout is assigned. If \a layout is 0, the + is deleted before the new layout is assigned. If \a layout is \nullptr, the widget is left without a layout. Existing subwidgets' geometries will remain unaffected. @@ -937,11 +937,11 @@ QStyle *QGraphicsWidget::style() const Sets the widget's style to \a style. QGraphicsWidget does \e not take ownership of \a style. - If no style is assigned, or \a style is 0, the widget will use + If no style is assigned, or \a style is \nullptr, the widget will use QGraphicsScene::style() (if this has been set). Otherwise the widget will use QApplication::style(). - This function sets the Qt::WA_SetStyle attribute if \a style is not 0; + This function sets the Qt::WA_SetStyle attribute if \a style is not \nullptr; otherwise it clears the attribute. \sa style() @@ -1871,7 +1871,7 @@ void QGraphicsWidget::setFocusPolicy(Qt::FocusPolicy policy) /*! If this widget, a child or descendant of this widget currently has input focus, this function will return a pointer to that widget. If - no descendant widget has input focus, 0 is returned. + no descendant widget has input focus, \nullptr is returned. \sa QGraphicsItem::focusItem(), QWidget::focusWidget() */ @@ -1880,7 +1880,7 @@ QGraphicsWidget *QGraphicsWidget::focusWidget() const Q_D(const QGraphicsWidget); if (d->subFocusItem && d->subFocusItem->d_ptr->isWidget) return static_cast<QGraphicsWidget *>(d->subFocusItem); - return 0; + return nullptr; } #ifndef QT_NO_SHORTCUT @@ -2022,7 +2022,7 @@ void QGraphicsWidget::addActions(QList<QAction *> actions) \since 4.5 Inserts the action \a action to this widget's list of actions, - before the action \a before. It appends the action if \a before is 0 or + before the action \a before. It appends the action if \a before is \nullptr or \a before is not a valid action for this widget. A QGraphicsWidget should only have one of each action. @@ -2062,7 +2062,7 @@ void QGraphicsWidget::insertAction(QAction *before, QAction *action) \since 4.5 Inserts the actions \a actions to this widget's list of actions, - before the action \a before. It appends the action if \a before is 0 or + before the action \a before. It appends the action if \a before is \nullptr or \a before is not a valid action for this widget. A QGraphicsWidget can have at most one of each action. @@ -2131,9 +2131,9 @@ QList<QAction *> QGraphicsWidget::actions() const \snippet code/src_gui_graphicsview_qgraphicswidget.cpp 2 - If \a first is 0, this indicates that \a second should be the first widget + If \a first is \nullptr, this indicates that \a second should be the first widget to receive input focus should the scene gain Tab focus (i.e., the user - hits Tab so that focus passes into the scene). If \a second is 0, this + hits Tab so that focus passes into the scene). If \a second is \nullptr, this indicates that \a first should be the first widget to gain focus if the scene gained BackTab focus. diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 1151379e17..7441161e13 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -940,8 +940,8 @@ void QAbstractItemView::setItemDelegateForRow(int row, QAbstractItemDelegate *de \since 4.2 Returns the item delegate used by this view and model for the given \a row, - or 0 if no delegate has been assigned. You can call itemDelegate() to get a - pointer to the current delegate for a given index. + or \nullptr if no delegate has been assigned. You can call itemDelegate() + to get a pointer to the current delegate for a given index. \sa setItemDelegateForRow(), itemDelegateForColumn(), setItemDelegate() */ diff --git a/src/widgets/itemviews/qcolumnview.cpp b/src/widgets/itemviews/qcolumnview.cpp index 1fe17721ba..a4eed2d885 100644 --- a/src/widgets/itemviews/qcolumnview.cpp +++ b/src/widgets/itemviews/qcolumnview.cpp @@ -801,7 +801,7 @@ void QColumnView::initializeColumn(QAbstractItemView *column) const } /*! - Returns the preview widget, or 0 if there is none. + Returns the preview widget, or \nullptr if there is none. \sa setPreviewWidget(), updatePreviewWidget() */ diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp index a7d144672c..dd43c6d3e4 100644 --- a/src/widgets/itemviews/qtableview.cpp +++ b/src/widgets/itemviews/qtableview.cpp @@ -138,20 +138,21 @@ void QSpanCollection::updateSpan(QSpanCollection::Span *span, int old_height) } /** \internal - * \return a spans that spans over cell x,y (column,row) or 0 if there is none. + * \return a spans that spans over cell x,y (column,row) + * or \nullptr if there is none. */ QSpanCollection::Span *QSpanCollection::spanAt(int x, int y) const { Index::const_iterator it_y = index.lowerBound(-y); if (it_y == index.end()) - return 0; + return nullptr; SubIndex::const_iterator it_x = (*it_y).lowerBound(-x); if (it_x == (*it_y).end()) - return 0; + return nullptr; Span *span = *it_x; if (span->right() >= x && span->bottom() >= y) return span; - return 0; + return nullptr; } diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp index 6050bcd616..29cc199526 100644 --- a/src/widgets/itemviews/qtreewidget.cpp +++ b/src/widgets/itemviews/qtreewidget.cpp @@ -2539,8 +2539,8 @@ void QTreeWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft, QStyle::SH_ItemView_ActivateItemOnSingleClick style hint) or pressing a special key (e.g., \uicontrol Enter). - The specified \a item is the item that was clicked, or 0 if no - item was clicked. The \a column is the item's column that was + The specified \a item is the item that was clicked, or \nullptr if + no item was clicked. The \a column is the item's column that was clicked, or -1 if no item was clicked. */ @@ -2550,8 +2550,8 @@ void QTreeWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft, This signal is emitted when the user presses a mouse button inside the widget. - The specified \a item is the item that was clicked, or 0 if no - item was clicked. The \a column is the item's column that was + The specified \a item is the item that was clicked, or \nullptr if + no item was clicked. The \a column is the item's column that was clicked, or -1 if no item was clicked. */ @@ -2571,8 +2571,8 @@ void QTreeWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft, This signal is emitted when the user double clicks inside the widget. - The specified \a item is the item that was clicked, or 0 if no - item was clicked. The \a column is the item's column that was + The specified \a item is the item that was clicked, or \nullptr if + no item was clicked. The \a column is the item's column that was clicked. If no item was double clicked, no signal will be emitted. */ @@ -2724,8 +2724,8 @@ QTreeWidgetItem *QTreeWidget::invisibleRootItem() const } /*! - Returns the top level item at the given \a index, or 0 if the item does - not exist. + Returns the top level item at the given \a index, or \nullptr if the + item does not exist. \sa topLevelItemCount(), insertTopLevelItem() */ From ae44da62ef30503a5380e5d1ee8b0cadd5960994 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Sun, 27 Jan 2019 17:49:29 +0100 Subject: [PATCH 1022/1650] QtGui: replace 0 with \nullptr in documentation Replace 0 with \nullptr in the documentation. As a drive-by also replace some 0 with nullptr in the corresponding code. Change-Id: Ieffbfffa76e3018257b667a3e8ad6e3b88486cde Reviewed-by: Paul Wicking <paul.wicking@qt.io> --- src/gui/image/qimageiohandler.cpp | 2 +- src/gui/image/qimagereader.cpp | 6 +++--- src/gui/image/qimagewriter.cpp | 4 ++-- src/gui/image/qmovie.cpp | 2 +- src/gui/image/qpicture.cpp | 6 +++--- src/gui/kernel/qcursor.cpp | 8 ++++---- src/gui/kernel/qopenglcontext.cpp | 7 +++---- src/gui/kernel/qplatformwindow.cpp | 4 ++-- src/gui/painting/qpainter.cpp | 2 +- src/gui/text/qtextdocumentwriter.cpp | 4 ++-- src/gui/text/qtextobject.cpp | 12 ++++++------ 11 files changed, 28 insertions(+), 29 deletions(-) diff --git a/src/gui/image/qimageiohandler.cpp b/src/gui/image/qimageiohandler.cpp index 9fe3b863b3..0e7b541cf2 100644 --- a/src/gui/image/qimageiohandler.cpp +++ b/src/gui/image/qimageiohandler.cpp @@ -340,7 +340,7 @@ void QImageIOHandler::setDevice(QIODevice *device) /*! Returns the device currently assigned to the QImageIOHandler. If - not device has been assigned, 0 is returned. + not device has been assigned, \nullptr is returned. */ QIODevice *QImageIOHandler::device() const { diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index 3f1297c81a..61f20e0c65 100644 --- a/src/gui/image/qimagereader.cpp +++ b/src/gui/image/qimagereader.cpp @@ -756,13 +756,13 @@ void QImageReader::setDevice(QIODevice *device) d->device = device; d->deleteDevice = false; delete d->handler; - d->handler = 0; + d->handler = nullptr; d->text.clear(); } /*! - Returns the device currently assigned to QImageReader, or 0 if no - device has been assigned. + Returns the device currently assigned to QImageReader, or \nullptr + if no device has been assigned. */ QIODevice *QImageReader::device() const { diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp index 41048fa681..ec66588ddf 100644 --- a/src/gui/image/qimagewriter.cpp +++ b/src/gui/image/qimagewriter.cpp @@ -407,8 +407,8 @@ void QImageWriter::setDevice(QIODevice *device) } /*! - Returns the device currently assigned to QImageWriter, or 0 if no - device has been assigned. + Returns the device currently assigned to QImageWriter, or \nullptr + if no device has been assigned. */ QIODevice *QImageWriter::device() const { diff --git a/src/gui/image/qmovie.cpp b/src/gui/image/qmovie.cpp index 7d17b7d5ef..79203c7b98 100644 --- a/src/gui/image/qmovie.cpp +++ b/src/gui/image/qmovie.cpp @@ -659,7 +659,7 @@ void QMovie::setDevice(QIODevice *device) /*! Returns the device QMovie reads image data from. If no device has - currently been assigned, 0 is returned. + currently been assigned, \nullptr is returned. \sa setDevice(), fileName() */ diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp index 51a9575fd0..6e57f679d8 100644 --- a/src/gui/image/qpicture.cpp +++ b/src/gui/image/qpicture.cpp @@ -1200,8 +1200,8 @@ QT_END_INCLUDE_NAMESPACE \obsolete Returns a string that specifies the picture format of the file \a - fileName, or 0 if the file cannot be read or if the format is not - recognized. + fileName, or \nullptr if the file cannot be read or if the format + is not recognized. \sa load(), save() */ @@ -1543,7 +1543,7 @@ const QPicture &QPictureIO::picture() const { return d->pi; } int QPictureIO::status() const { return d->iostat; } /*! - Returns the picture format string or 0 if no format has been + Returns the picture format string or \nullptr if no format has been explicitly set. */ const char *QPictureIO::format() const { return d->frmt; } diff --git a/src/gui/kernel/qcursor.cpp b/src/gui/kernel/qcursor.cpp index bb81ca109a..9e4787589f 100644 --- a/src/gui/kernel/qcursor.cpp +++ b/src/gui/kernel/qcursor.cpp @@ -564,8 +564,8 @@ void QCursor::setShape(Qt::CursorShape shape) } /*! - Returns the cursor bitmap, or 0 if it is one of the standard - cursors. + Returns the cursor bitmap, or \nullptr if it is one of the + standard cursors. */ const QBitmap *QCursor::bitmap() const { @@ -575,8 +575,8 @@ const QBitmap *QCursor::bitmap() const } /*! - Returns the cursor bitmap mask, or 0 if it is one of the standard - cursors. + Returns the cursor bitmap mask, or \nullptr if it is one of the + standard cursors. */ const QBitmap *QCursor::mask() const diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index be04513de6..4847a62b0f 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -414,15 +414,14 @@ int QOpenGLContextPrivate::maxTextureSize() /*! Returns the last context which called makeCurrent in the current thread, - or 0, if no context is current. + or \nullptr, if no context is current. */ QOpenGLContext* QOpenGLContext::currentContext() { QGuiGLThreadContext *threadContext = qwindow_context_storage()->localData(); - if (threadContext) { + if (threadContext) return threadContext->context; - } - return 0; + return nullptr; } /*! diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp index 50f05721f7..d6f90c9254 100644 --- a/src/gui/kernel/qplatformwindow.cpp +++ b/src/gui/kernel/qplatformwindow.cpp @@ -90,11 +90,11 @@ QWindow *QPlatformWindow::window() const } /*! - Returns the parent platform window (or 0 if orphan). + Returns the parent platform window (or \nullptr if orphan). */ QPlatformWindow *QPlatformWindow::parent() const { - return window()->parent() ? window()->parent()->handle() : 0; + return window()->parent() ? window()->parent()->handle() : nullptr; } /*! diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 36f0d1d5b9..c746df9dd6 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -1521,7 +1521,7 @@ QPainter::~QPainter() /*! Returns the paint device on which this painter is currently - painting, or 0 if the painter is not active. + painting, or \nullptr if the painter is not active. \sa isActive() */ diff --git a/src/gui/text/qtextdocumentwriter.cpp b/src/gui/text/qtextdocumentwriter.cpp index 5ea04fe9e9..ee72300bc7 100644 --- a/src/gui/text/qtextdocumentwriter.cpp +++ b/src/gui/text/qtextdocumentwriter.cpp @@ -206,8 +206,8 @@ void QTextDocumentWriter::setDevice (QIODevice *device) } /*! - Returns the device currently assigned, or 0 if no device has been - assigned. + Returns the device currently assigned, or \nullptr if no device + has been assigned. */ QIODevice *QTextDocumentWriter::device () const { diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp index 0ed8be8530..18c5a4f3dd 100644 --- a/src/gui/text/qtextobject.cpp +++ b/src/gui/text/qtextobject.cpp @@ -704,8 +704,8 @@ QTextFrame::iterator &QTextFrame::iterator::operator=(const iterator &other) Q_D #endif /*! - Returns the current frame pointed to by the iterator, or 0 if the - iterator currently points to a block. + Returns the current frame pointed to by the iterator, or \nullptr + if the iterator currently points to a block. \sa currentBlock() */ @@ -1291,12 +1291,12 @@ QVector<QTextLayout::FormatRange> QTextBlock::textFormats() const } /*! - Returns the text document this text block belongs to, or 0 if the - text block does not belong to any document. + Returns the text document this text block belongs to, or \nullptr + if the text block does not belong to any document. */ const QTextDocument *QTextBlock::document() const { - return p ? p->document() : 0; + return p ? p->document() : nullptr; } /*! @@ -1306,7 +1306,7 @@ const QTextDocument *QTextBlock::document() const QTextList *QTextBlock::textList() const { if (!isValid()) - return 0; + return nullptr; const QTextBlockFormat fmt = blockFormat(); QTextObject *obj = p->document()->objectForFormat(fmt); From fd1ebef13e9d0ebb82f1994eed264b849e3be9e9 Mon Sep 17 00:00:00 2001 From: Yuhang Zhao <2546789017@qq.com> Date: Fri, 1 Feb 2019 20:09:35 +0800 Subject: [PATCH 1023/1650] qtmain_win.cpp: Replace NULL with nullptr Change-Id: I727a07a3c56c97cf6f18929b2440f49f0cbb860d Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> --- src/winmain/qtmain_win.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/winmain/qtmain_win.cpp b/src/winmain/qtmain_win.cpp index 3dc1ac0fba..752fba1d5a 100644 --- a/src/winmain/qtmain_win.cpp +++ b/src/winmain/qtmain_win.cpp @@ -84,9 +84,9 @@ extern "C" int main(int, char **); // when passed CP_ACP. static inline char *wideToMulti(int codePage, const wchar_t *aw) { - const int required = WideCharToMultiByte(codePage, 0, aw, -1, NULL, 0, NULL, NULL); + const int required = WideCharToMultiByte(codePage, 0, aw, -1, nullptr, 0, nullptr, nullptr); char *result = new char[required]; - WideCharToMultiByte(codePage, 0, aw, -1, result, required, NULL, NULL); + WideCharToMultiByte(codePage, 0, aw, -1, result, required, nullptr, nullptr); return result; } From aea357c6bd28fd460a92980c47efbc9a6f418572 Mon Sep 17 00:00:00 2001 From: Yuhang Zhao <2546789017@qq.com> Date: Fri, 1 Feb 2019 20:15:50 +0800 Subject: [PATCH 1024/1650] qtmain_win.cpp: Improve coding style Change-Id: I08c722f4ff8a088d13af5b7d9cfbc88258d533ad Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> --- src/winmain/qtmain_win.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/winmain/qtmain_win.cpp b/src/winmain/qtmain_win.cpp index 752fba1d5a..0f29c6ac95 100644 --- a/src/winmain/qtmain_win.cpp +++ b/src/winmain/qtmain_win.cpp @@ -82,7 +82,7 @@ extern "C" int main(int, char **); // Convert a wchar_t to char string, equivalent to QString::toLocal8Bit() // when passed CP_ACP. -static inline char *wideToMulti(int codePage, const wchar_t *aw) +static inline char *wideToMulti(unsigned int codePage, const wchar_t *aw) { const int required = WideCharToMultiByte(codePage, 0, aw, -1, nullptr, 0, nullptr, nullptr); char *result = new char[required]; @@ -92,17 +92,17 @@ static inline char *wideToMulti(int codePage, const wchar_t *aw) extern "C" int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR /*cmdParamarg*/, int /* cmdShow */) { - int argc; + int argc = 0; wchar_t **argvW = CommandLineToArgvW(GetCommandLineW(), &argc); - if (!argvW) + if (argvW == nullptr) return -1; char **argv = new char *[argc + 1]; - for (int i = 0; i < argc; ++i) + for (int i = 0; i != argc; ++i) argv[i] = wideToMulti(CP_ACP, argvW[i]); argv[argc] = nullptr; LocalFree(argvW); const int exitCode = main(argc, argv); - for (int i = 0; i < argc && argv[i]; ++i) + for (int i = 0; (i != argc) && (argv[i] != nullptr); ++i) delete [] argv[i]; delete [] argv; return exitCode; From 3bf895c8d52a4172cd29ab8a8121e37ec790c47d Mon Sep 17 00:00:00 2001 From: Yuhang Zhao <2546789017@qq.com> Date: Thu, 31 Jan 2019 20:36:17 +0800 Subject: [PATCH 1025/1650] qtmain_win.cpp: Remove unused header files 1. Removed all Qt header files and make it a pure win32 project because it doesn't use any Qt features. 2. According to MSDN, CommandLineToArgvW is in shellapi.h, so replace ShlObj.h with it. Change-Id: I3daacb97f34664ac36f8e887a2c31d38f611b16e Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> --- src/winmain/qtmain_win.cpp | 13 +++---------- src/winmain/winmain.pro | 2 +- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/winmain/qtmain_win.cpp b/src/winmain/qtmain_win.cpp index 0f29c6ac95..5520a447a9 100644 --- a/src/winmain/qtmain_win.cpp +++ b/src/winmain/qtmain_win.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Windows main function of the Qt Toolkit. @@ -48,12 +48,8 @@ ** ****************************************************************************/ -#include "qt_windows.h" -#include "qbytearray.h" -#include "qstring.h" -#include "qvector.h" - -#include <shlobj.h> +#include <windows.h> +#include <shellapi.h> /* This file contains the code in the qtmain library for Windows. @@ -64,9 +60,6 @@ invoked. */ -QT_USE_NAMESPACE - - #if defined(QT_NEEDS_QMAIN) int qMain(int, char **); #define main qMain diff --git a/src/winmain/winmain.pro b/src/winmain/winmain.pro index 61e9f29d23..9cb6ab0c59 100644 --- a/src/winmain/winmain.pro +++ b/src/winmain/winmain.pro @@ -21,8 +21,8 @@ mingw: DEFINES += QT_NEEDS_QMAIN winrt { SOURCES = qtmain_winrt.cpp } else { + CONFIG -= qt SOURCES = qtmain_win.cpp - LIBS += -lshell32 } From 29d5a287abc3d3c9b75619db18042dea66236cb3 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann <joerg.bornemann@qt.io> Date: Fri, 1 Feb 2019 10:54:30 +0100 Subject: [PATCH 1026/1650] Make the Makefile a dependency of default targets for nmake If the user changes the .pro file, the Makefile is supposed to be re-generated by calling qmake again. NMake however lacks a "Makefile remake feature" like GNU make has. The generated Makefiles for nmake however have already a proper Makefile target that can be used to re-generate the Makefile. What was missing is the dependency from an entry-target in the meta-Makefile. Now changes in the .pro file trigger a re-generation of Makefile.Debug/Makefile.Release when calling nmake without target arguments or with "debug" or "release". Fixes: QTBUG-29193 Change-Id: I9f2dd5deba4a043ab6c9502bb0b0ba83dc843612 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> --- qmake/generators/makefile.cpp | 3 +++ qmake/generators/makefile.h | 1 + qmake/generators/win32/msvc_nmake.cpp | 5 +++++ qmake/generators/win32/msvc_nmake.h | 1 + 4 files changed, 10 insertions(+) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index f824f12bce..6a46df1af6 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -2585,6 +2585,9 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT { //actually compile t << subtarget->target << ":"; + auto extraDeps = extraSubTargetDependencies(); + if (!extraDeps.isEmpty()) + t << " " << valList(extraDeps); if(!subtarget->depends.isEmpty()) t << " " << valList(subtarget->depends); t << " FORCE"; diff --git a/qmake/generators/makefile.h b/qmake/generators/makefile.h index 0535017ff6..350ebd377a 100644 --- a/qmake/generators/makefile.h +++ b/qmake/generators/makefile.h @@ -119,6 +119,7 @@ protected: virtual void writeSubMakeCall(QTextStream &t, const QString &outDirectory_cdin, const QString &makeFileIn); virtual void writeSubTargets(QTextStream &t, QList<SubTarget*> subtargets, int flags); + virtual ProStringList extraSubTargetDependencies() { return {}; } //extra compiler interface bool verifyExtraCompiler(const ProString &c, const QString &f); diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index aa3d389b67..a6e850a036 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -76,6 +76,11 @@ void NmakeMakefileGenerator::writeSubMakeCall(QTextStream &t, const QString &cal Win32MakefileGenerator::writeSubMakeCall(t, callPrefix, makeArguments); } +ProStringList NmakeMakefileGenerator::extraSubTargetDependencies() +{ + return { "$(MAKEFILE)" }; +} + QString NmakeMakefileGenerator::defaultInstall(const QString &t) { QString ret = Win32MakefileGenerator::defaultInstall(t); diff --git a/qmake/generators/win32/msvc_nmake.h b/qmake/generators/win32/msvc_nmake.h index 67a56c7813..5bfdba2bbc 100644 --- a/qmake/generators/win32/msvc_nmake.h +++ b/qmake/generators/win32/msvc_nmake.h @@ -48,6 +48,7 @@ class NmakeMakefileGenerator : public Win32MakefileGenerator protected: void writeSubMakeCall(QTextStream &t, const QString &callPrefix, const QString &makeArguments) override; + ProStringList extraSubTargetDependencies() override; QString defaultInstall(const QString &t) override; QStringList &findDependencies(const QString &file) override; QString var(const ProKey &value) const override; From 9435526d507611b8b54f7c65df9febdde193c7bf Mon Sep 17 00:00:00 2001 From: Andy Shaw <andy.shaw@qt.io> Date: Mon, 15 Oct 2018 09:23:26 +0200 Subject: [PATCH 1027/1650] qmake: Add variables for setting the version number and name in Android This makes it much easier to have the version information set for an Android APK without having to manually modify the AndroidManifest.xml each time. [ChangeLog][Android][qmake] Can now set the version name and code for Android using ANDROID_VERSION_NAME and ANDROID_VERSION_CODE respectively in the pro file. Change-Id: Ie6813bc3a7444f7baa5e772b93bc2695d9b81e57 Done-with: Markus Maier <markus.maier@rosenberger.de> Reviewed-by: Markus Maier <markus.maier@rosenberger.de> Reviewed-by: BogDan Vatra <bogdan@kdab.com> --- .../android/android_deployment_settings.prf | 8 +++++++ src/android/templates/AndroidManifest.xml | 2 +- src/tools/androiddeployqt/main.cpp | 22 +++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/mkspecs/features/android/android_deployment_settings.prf b/mkspecs/features/android/android_deployment_settings.prf index 0db3230ce7..ad826bdad3 100644 --- a/mkspecs/features/android/android_deployment_settings.prf +++ b/mkspecs/features/android/android_deployment_settings.prf @@ -58,6 +58,14 @@ contains(TEMPLATE, ".*app"):!build_pass:!android-embedded { !isEmpty(ANDROID_PACKAGE_SOURCE_DIR): \ FILE_CONTENT += " \"android-package-source-directory\": $$emitString($$ANDROID_PACKAGE_SOURCE_DIR)," + # Android-specific version string + !isEmpty(ANDROID_VERSION_NAME): \ + FILE_CONTENT += " \"android-version-name\": $$emitString($$ANDROID_VERSION_NAME)," + + # Android-specific version number + !isEmpty(ANDROID_VERSION_CODE): \ + FILE_CONTENT += " \"android-version-code\": $$emitString($$ANDROID_VERSION_CODE)," + !isEmpty(ANDROID_EXTRA_LIBS): \ FILE_CONTENT += " \"android-extra-libs\": $$emitString($$join(ANDROID_EXTRA_LIBS, ","))," diff --git a/src/android/templates/AndroidManifest.xml b/src/android/templates/AndroidManifest.xml index 100fc99e80..cb97002560 100644 --- a/src/android/templates/AndroidManifest.xml +++ b/src/android/templates/AndroidManifest.xml @@ -1,5 +1,5 @@ <?xml version='1.0' encoding='utf-8'?> -<manifest package="org.qtproject.example" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto"> +<manifest package="org.qtproject.example" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="-- %%INSERT_VERSION_NAME%% --" android:versionCode="-- %%INSERT_VERSION_CODE%% --" android:installLocation="auto"> <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="28"/> <!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application. diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp index af3a3ae39a..9402a1a881 100644 --- a/src/tools/androiddeployqt/main.cpp +++ b/src/tools/androiddeployqt/main.cpp @@ -148,6 +148,10 @@ struct Options QString rootPath; QStringList qmlImportPaths; + // Versioning + QString versionName; + QString versionCode; + // lib c++ path QString stdCppPath; QString stdCppName = QStringLiteral("gnustl_shared"); @@ -756,6 +760,22 @@ bool readInputFile(Options *options) options->androidSourceDirectory = androidSourcesDirectory.toString(); } + { + const QJsonValue androidVersionName = jsonObject.value(QStringLiteral("android-version-name")); + if (!androidVersionName.isUndefined()) + options->versionName = androidVersionName.toString(); + else + options->versionName = QStringLiteral("1.0"); + } + + { + const QJsonValue androidVersionCode = jsonObject.value(QStringLiteral("android-version-code")); + if (!androidVersionCode.isUndefined()) + options->versionCode = androidVersionCode.toString(); + else + options->versionCode = QStringLiteral("1"); + } + { const QJsonValue applicationBinary = jsonObject.value(QStringLiteral("application-binary")); if (applicationBinary.isUndefined()) { @@ -1324,6 +1344,8 @@ bool updateAndroidManifest(Options &options) replacements[QLatin1String("-- %%INSERT_LOCAL_LIBS%% --")] = localLibs.join(QLatin1Char(':')); replacements[QLatin1String("-- %%INSERT_LOCAL_JARS%% --")] = options.localJars.join(QLatin1Char(':')); replacements[QLatin1String("-- %%INSERT_INIT_CLASSES%% --")] = options.initClasses.join(QLatin1Char(':')); + replacements[QLatin1String("-- %%INSERT_VERSION_NAME%% --")] = options.versionName; + replacements[QLatin1String("-- %%INSERT_VERSION_CODE%% --")] = options.versionCode; replacements[QLatin1String("package=\"org.qtproject.example\"")] = QString::fromLatin1("package=\"%1\"").arg(options.packageName); replacements[QLatin1String("-- %%BUNDLE_LOCAL_QT_LIBS%% --")] = (options.deploymentMechanism == Options::Bundled) ? QString::fromLatin1("1") : QString::fromLatin1("0"); From 850c922036b7eebc24cdb74a43a4b31319d924c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= <tor.arne.vestbo@qt.io> Date: Wed, 30 Jan 2019 18:03:00 +0100 Subject: [PATCH 1028/1650] macOS: Don't deliver update requests for windows that need display MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a window needs display due to e.g. being resized, we need to wait until the corresponding expose event has been delivered before we resume update requests, otherwise the update requests may result in partial paints that do not fully cover the area needing display. Change-Id: Ibfb54bfe3c2e85b606ef67d34a6a5fdb85456edd Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io> --- src/plugins/platforms/cocoa/qcocoawindow.mm | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index b0f0d51ecb..a1bed3db45 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1487,6 +1487,17 @@ void QCocoaWindow::requestUpdate() void QCocoaWindow::deliverUpdateRequest() { + // Don't send update requests for views that need display, as the update + // request doesn't carry any information about dirty rects, so the app + // may end up painting a smaller region than required. (For some reason + // the layer and view's needsDisplay status isn't always in sync, even if + // the view is layer-backed, not layer-hosted, so we check both). + if (m_view.layer.needsDisplay || m_view.needsDisplay) { + qCDebug(lcQpaDrawing) << "View needs display, deferring update request for" << window(); + requestUpdate(); + return; + } + qCDebug(lcQpaDrawing) << "Delivering update request to" << window(); QPlatformWindow::deliverUpdateRequest(); } From d726ccb83c14f829042fcb1019adba1cb7bf6fea Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Wed, 30 Jan 2019 17:35:48 +0100 Subject: [PATCH 1029/1650] tst_QHeaderView: fix defaultSectionSizeTest() on High-DPI screens tst_QHeaderView::defaultSectionSizeTest() fails on High-DPI screens because the default minimum section size is greater than the values used for testing the header sizes. Therefore the test will fail. Fix it by explicitly setting the minimum header size to something smaller than the test values. Also add a debug line to output the default minimum section sizes so other failures due to this problem can be debugged better. Fixes: QTBUG-73309 Change-Id: I257f341cef9381f140aa4d4f68376c5edadc39cc Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> --- .../widgets/itemviews/qheaderview/tst_qheaderview.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp index f14adbcb6c..12e458c669 100644 --- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp +++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp @@ -442,7 +442,13 @@ tst_QHeaderView::tst_QHeaderView() void tst_QHeaderView::initTestCase() { - m_tableview = new QTableView(); + m_tableview = new QTableView; + qDebug().noquote().nospace() + << "default min section size is " + << QString::number(m_tableview->verticalHeader()->minimumSectionSize()) + << QLatin1Char('/') + << m_tableview->horizontalHeader()->minimumSectionSize() + << " (v/h)"; } void tst_QHeaderView::cleanupTestCase() @@ -1840,6 +1846,7 @@ void tst_QHeaderView::defaultSectionSizeTest() // Setup QTableView qtv; QHeaderView *hv = qtv.verticalHeader(); + hv->setMinimumSectionSize(10); hv->setDefaultSectionSize(99); // Set it to a value different from defaultSize. QStandardItemModel amodel(4, 4); qtv.setModel(&amodel); From 0736e050cb0f82ca445e954e1db631f1dd1de473 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Tue, 8 Jan 2019 20:58:26 +0100 Subject: [PATCH 1030/1650] QMenuItem: fix rendering with css styling The rendering of a css styled menu item with icons or checkmark was partially fixed with aa1bc47942e2062dc7fad3e139bb4ceecc74f947 but introduced some other painting regressions, especially in RTL mode. Fix it by syncing the code with fusion and windows style. With this patch a menu text with a check mark but no icon is now aligned exactly the same as a menu text with a icon. Fixes: QTBUG-66380 Fixes: QTBUG-70491 Fixes: QTBUG-72817 Change-Id: I83a95d15eb130e7f72471820b53c3cd5554d9334 Reviewed-by: Nick D'Ademo <nickdademo@gmail.com> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> --- src/widgets/styles/qstylesheetstyle.cpp | 36 +++++++++++++++---------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 7c1c0ca3d8..79fa20851f 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -3705,21 +3705,17 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q QRenderRule subSubRule = renderRule(w, opt, PseudoElement_MenuCheckMark); QStyleOptionMenuItem newMi = mi; newMi.rect = positionRect(w, subRule, subSubRule, PseudoElement_MenuCheckMark, opt->rect, opt->direction); - checkableOffset = newMi.rect.width(); + // align with icons if there are some + checkableOffset = std::max(m->maxIconWidth, newMi.rect.width()); if (subSubRule.hasDrawable() || checked) drawPrimitive(PE_IndicatorMenuCheckMark, &newMi, p, w); } - int iconOffset = 0; if (!mi.icon.isNull()) { QIcon::Mode mode = dis ? QIcon::Disabled : QIcon::Normal; if (act && !dis) mode = QIcon::Active; - QPixmap pixmap; - if (checked) - pixmap = mi.icon.pixmap(pixelMetric(PM_SmallIconSize), mode, QIcon::On); - else - pixmap = mi.icon.pixmap(pixelMetric(PM_SmallIconSize), mode); + const QPixmap pixmap(mi.icon.pixmap(pixelMetric(PM_SmallIconSize), mode, checked ? QIcon::On : QIcon::Off)); const int pixw = pixmap.width() / pixmap.devicePixelRatio(); const int pixh = pixmap.height() / pixmap.devicePixelRatio(); QRenderRule iconRule = renderRule(w, opt, PseudoElement_MenuIcon); @@ -3738,15 +3734,20 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q QRect pmr(0, 0, pixw, pixh); pmr.moveCenter(iconRect.center()); p->drawPixmap(pmr.topLeft(), pixmap); - iconOffset = iconRule.geo->width; } + int textOffset = 0; + // padding overrules it all + if (!subRule.hasBox() || subRule.box()->paddings[LeftEdge] == 0) { + textOffset = checkableOffset; + if (!m->icon.isNull() || !checkable) + textOffset += m->maxIconWidth; + } QRect textRect = subRule.contentsRect(opt->rect); - if (opt->direction == Qt::LeftToRight) - textRect.setLeft(textRect.left() + checkableOffset + iconOffset); - else - textRect.setRight(textRect.right() - checkableOffset - iconOffset); + textRect.setLeft(textRect.left() + textOffset); textRect.setWidth(textRect.width() - mi.tabWidth); + const QRect vTextRect = visualRect(opt->direction, m->rect, textRect); + QStringRef s(&mi.text); p->setPen(mi.palette.buttonText().color()); if (!s.isEmpty()) { @@ -3760,7 +3761,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q p->drawText(vShortcutRect, text_flags, s.mid(t + 1).toString()); s = s.left(t); } - p->drawText(textRect, text_flags, s.left(t).toString()); + p->drawText(vTextRect, text_flags, s.left(t).toString()); } if (mi.menuItemType == QStyleOptionMenuItem::SubMenu) {// draw sub menu arrow @@ -5084,15 +5085,22 @@ QSize QStyleSheetStyle::sizeFromContents(ContentsType ct, const QStyleOption *op if (mi->text.contains(QLatin1Char('\t'))) width += 12; //as in QCommonStyle bool checkable = mi->checkType != QStyleOptionMenuItem::NotCheckable; + int checkableWidth = 0; if (checkable) { QRenderRule subSubRule = renderRule(w, opt, PseudoElement_MenuCheckMark); QRect checkmarkRect = positionRect(w, subRule, subSubRule, PseudoElement_MenuCheckMark, opt->rect, opt->direction); - width += checkmarkRect.width(); + checkableWidth = std::max(mi->maxIconWidth, checkmarkRect.width()); } if (!mi->icon.isNull()) { QPixmap pixmap = mi->icon.pixmap(pixelMetric(PM_SmallIconSize)); width += pixmap.width(); } + // padding overrules it all + if (!subRule.hasBox() || subRule.box()->paddings[LeftEdge] == 0) { + width += checkableWidth; + if (!mi->icon.isNull() || !checkable) + width += mi->maxIconWidth; + } return subRule.boxSize(subRule.adjustSize(QSize(width, csz.height()))); } } From b76a923a8e81f5fabe6e48ed467e5326275fae4e Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Sat, 2 Feb 2019 14:50:19 +0100 Subject: [PATCH 1031/1650] QAnimationDriver: mark obsolete functions as deprecated Mark the two long obsolete (and empty) functions as deprecated so they can be removed with Qt6: - setStartTime()/startTime() Change-Id: I7ee1d99ff194860e41723909f81adc181a71ec7c Reviewed-by: Lars Knoll <lars.knoll@qt.io> --- src/corelib/animation/qabstractanimation.cpp | 2 ++ src/corelib/animation/qabstractanimation.h | 7 ++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index 9dd81b2ecd..9d7a256191 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -773,6 +773,7 @@ QAnimationDriver::~QAnimationDriver() } +#if QT_DEPRECATED_SINCE(5, 13) /*! Sets the time at which an animation driver should start at. @@ -799,6 +800,7 @@ qint64 QAnimationDriver::startTime() const { return 0; } +#endif /*! diff --git a/src/corelib/animation/qabstractanimation.h b/src/corelib/animation/qabstractanimation.h index 25b5726d56..7f2577d7f7 100644 --- a/src/corelib/animation/qabstractanimation.h +++ b/src/corelib/animation/qabstractanimation.h @@ -147,9 +147,10 @@ public: virtual qint64 elapsed() const; - // ### Qt6: Remove these two functions - void setStartTime(qint64 startTime); - qint64 startTime() const; +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED void setStartTime(qint64 startTime); + QT_DEPRECATED qint64 startTime() const; +#endif Q_SIGNALS: void started(); From 3514aedbf36b96f6e03f88c9c7814b6ba50aac8f Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Sun, 3 Feb 2019 19:55:51 +0100 Subject: [PATCH 1032/1650] QtWidgets documentation: cleanup Cleanup the QtWidgets documentation: - use new signal/slot syntax - use range-based for loop instead foreach Change-Id: I621b1ddac108d3df676209241d93d9b4f04a25fe Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> --- .../src_gui_itemviews_qdatawidgetmapper.cpp | 8 ++--- .../code/src_gui_kernel_qapplication.cpp | 12 ++++--- .../snippets/code/src_gui_widgets_qmenu.cpp | 2 +- src/widgets/doc/snippets/dialogs/dialogs.cpp | 9 +++--- .../doc/snippets/dockwidgets/mainwindow.cpp | 8 ++--- src/widgets/doc/snippets/mdiareasnippets.cpp | 4 +-- .../doc/snippets/qlistview-dnd/mainwindow.cpp | 3 +- .../doc/snippets/qlistview-dnd/model.cpp | 8 ++--- .../snippets/qlistwidget-dnd/mainwindow.cpp | 4 +-- .../snippets/qlistwidget-using/mainwindow.cpp | 17 +++++----- .../snippets/qsortfilterproxymodel/main.cpp | 7 ++--- .../doc/snippets/qstackedlayout/main.cpp | 9 +++--- .../doc/snippets/qstackedwidget/main.cpp | 7 ++--- .../qtablewidget-resizing/mainwindow.cpp | 8 ++--- .../qtablewidget-using/mainwindow.cpp | 20 ++++++------ .../snippets/qtreewidget-using/mainwindow.cpp | 31 +++++++++---------- .../mainwindow.cpp | 21 ++++++------- .../snippets/reading-selections/window.cpp | 18 +++++------ .../snippets/updating-selections/window.cpp | 17 +++++----- .../doc/src/model-view-programming.qdoc | 5 ++- 20 files changed, 104 insertions(+), 114 deletions(-) diff --git a/src/widgets/doc/snippets/code/src_gui_itemviews_qdatawidgetmapper.cpp b/src/widgets/doc/snippets/code/src_gui_itemviews_qdatawidgetmapper.cpp index 4dad563660..cc1568cb9d 100644 --- a/src/widgets/doc/snippets/code/src_gui_itemviews_qdatawidgetmapper.cpp +++ b/src/widgets/doc/snippets/code/src_gui_itemviews_qdatawidgetmapper.cpp @@ -59,7 +59,7 @@ mapper->toFirst(); //! [1] -QDataWidgetMapper *mapper = new QDataWidgetMapper(); +QDataWidgetMapper *mapper = new QDataWidgetMapper; mapper->setModel(myModel); mapper->addMapping(nameLineEdit, 0); mapper->addMapping(ageSpinBox, 1); @@ -67,7 +67,7 @@ mapper->addMapping(ageSpinBox, 1); //! [2] -QDataWidgetMapper *mapper = new QDataWidgetMapper(); -connect(myTableView->selectionModel(), SIGNAL(currentRowChanged(QModelIndex,QModelIndex)), - mapper, SLOT(setCurrentModelIndex(QModelIndex))); +QDataWidgetMapper *mapper = new QDataWidgetMapper; +connect(myTableView->selectionModel(), &QItemSelectionModel::currentRowChanged, + mapper, &QDataWidgetMapper::setCurrentModelIndex); //! [2] diff --git a/src/widgets/doc/snippets/code/src_gui_kernel_qapplication.cpp b/src/widgets/doc/snippets/code/src_gui_kernel_qapplication.cpp index a907a0421f..0a70c1d32a 100644 --- a/src/widgets/doc/snippets/code/src_gui_kernel_qapplication.cpp +++ b/src/widgets/doc/snippets/code/src_gui_kernel_qapplication.cpp @@ -100,7 +100,8 @@ QSize MyWidget::sizeHint() const //! [4] void showAllHiddenTopLevelWidgets() { - foreach (QWidget *widget, QApplication::topLevelWidgets()) { + const QWidgetList topLevelWidgets = QApplication::topLevelWidgets(); + for (QWidget *widget : topLevelWidgets) { if (widget->isHidden()) widget->show(); } @@ -111,7 +112,8 @@ void showAllHiddenTopLevelWidgets() //! [5] void updateAllWidgets() { - foreach (QWidget *widget, QApplication::allWidgets()) + const QWidgetList allWidgets = QApplication::allWidgets(); + for (QWidget *widget : allWidgets) widget->update(); } //! [5] @@ -171,13 +173,15 @@ appname -session id //! [10] -foreach (const QString &command, mySession.restartCommand()) +const QStringList commands = mySession.restartCommand(); +for (const QString &command : commands) do_something(command); //! [10] //! [11] -foreach (const QString &command, mySession.discardCommand()) +const QStringList commands = mySession.discardCommand(); +for (const QString &command : commands) do_something(command); //! [11] diff --git a/src/widgets/doc/snippets/code/src_gui_widgets_qmenu.cpp b/src/widgets/doc/snippets/code/src_gui_widgets_qmenu.cpp index 4b1c4cd645..da3fd28056 100644 --- a/src/widgets/doc/snippets/code/src_gui_widgets_qmenu.cpp +++ b/src/widgets/doc/snippets/code/src_gui_widgets_qmenu.cpp @@ -81,7 +81,7 @@ exec(e->globalPos()); //! [6] QMenu menu; QAction *at = actions[0]; // Assumes actions is not empty -foreach (QAction *a, actions) +for (QAction *a : qAsConst(actions)) menu.addAction(a); menu.exec(pos, at); //! [6] diff --git a/src/widgets/doc/snippets/dialogs/dialogs.cpp b/src/widgets/doc/snippets/dialogs/dialogs.cpp index cca3ac8d75..7fa793c70f 100644 --- a/src/widgets/doc/snippets/dialogs/dialogs.cpp +++ b/src/widgets/doc/snippets/dialogs/dialogs.cpp @@ -48,7 +48,7 @@ ** ****************************************************************************/ -#include <QtGui> +#include <QtWidgets> typedef QDialog WordCountDialog; typedef QDialog FindDialog; @@ -76,7 +76,8 @@ void EditorWindow::find() { if (!findDialog) { findDialog = new FindDialog(this); - connect(findDialog, SIGNAL(findNext()), this, SLOT(findNext())); + connect(findDialog, &FindDialog::findNext, + this, &EditorWindow::findNext); } findDialog->show(); @@ -249,9 +250,9 @@ Operation::Operation(QObject *parent) : QObject(parent), steps(0) { pd = new QProgressDialog("Operation in progress.", "Cancel", 0, 100); - connect(pd, SIGNAL(canceled()), this, SLOT(cancel())); + connect(pd, &QProgressDialog::canceled, this, &Operation::cancel); t = new QTimer(this); - connect(t, SIGNAL(timeout()), this, SLOT(perform())); + connect(t, &QTimer::timeout, this, &Operation::perform); t->start(0); } //! [4] //! [5] diff --git a/src/widgets/doc/snippets/dockwidgets/mainwindow.cpp b/src/widgets/doc/snippets/dockwidgets/mainwindow.cpp index f6959cc12b..53f91589bf 100644 --- a/src/widgets/doc/snippets/dockwidgets/mainwindow.cpp +++ b/src/widgets/doc/snippets/dockwidgets/mainwindow.cpp @@ -48,7 +48,7 @@ ** ****************************************************************************/ -#include <QtGui> +#include <QtWidgets> #include "mainwindow.h" @@ -63,8 +63,8 @@ MainWindow::MainWindow(QWidget *parent) textBrowser = new QTextBrowser(this); - connect(headingList, SIGNAL(itemClicked(QListWidgetItem*)), - this, SLOT(updateText(QListWidgetItem*))); + connect(headingList, &QListWidget::itemClicked, + this, &MainWindow::updateText); updateText(headingList->item(0)); headingList->setCurrentRow(0); @@ -119,7 +119,7 @@ void MainWindow::setupMenus() QAction *exitAct = new QAction(tr("E&xit"), this); exitAct->setShortcut(tr("Ctrl+Q")); exitAct->setStatusTip(tr("Exit the application")); - connect(exitAct, SIGNAL(triggered()), qApp, SLOT(closeAllWindows())); + connect(exitAct, &QAction::triggered, qApp, &QApplication::closeAllWindows); QMenu *fileMenu = menuBar()->addMenu(tr("&File")); fileMenu->addAction(exitAct); diff --git a/src/widgets/doc/snippets/mdiareasnippets.cpp b/src/widgets/doc/snippets/mdiareasnippets.cpp index b9d6f05daf..dec7aaa1e7 100644 --- a/src/widgets/doc/snippets/mdiareasnippets.cpp +++ b/src/widgets/doc/snippets/mdiareasnippets.cpp @@ -48,7 +48,7 @@ ** ****************************************************************************/ -#include <QtGui> +#include <QtWidgets> void mainWindowExample() { @@ -95,7 +95,7 @@ int main(int argv, char **args) QAction *act = new QAction(qApp); act->setShortcut(Qt::ALT + Qt::Key_S); act->setShortcutContext( Qt::ApplicationShortcut ); - QObject::connect(act, SIGNAL(triggered()), qApp, SLOT(aboutQt())); + QObject::connect(act, &QAction::triggered, qApp, &QApplication::aboutQt); QWidget widget5; widget5.show(); diff --git a/src/widgets/doc/snippets/qlistview-dnd/mainwindow.cpp b/src/widgets/doc/snippets/qlistview-dnd/mainwindow.cpp index c2af9c4cf1..45f1eb7aa3 100644 --- a/src/widgets/doc/snippets/qlistview-dnd/mainwindow.cpp +++ b/src/widgets/doc/snippets/qlistview-dnd/mainwindow.cpp @@ -73,7 +73,8 @@ listView->setDropIndicatorShown(true); this->listView = listView; - connect(quitAction, SIGNAL(triggered()), this, SLOT(close())); + connect(quitAction, &QAction::triggered, + this, &QWidget::close); setupListItems(); diff --git a/src/widgets/doc/snippets/qlistview-dnd/model.cpp b/src/widgets/doc/snippets/qlistview-dnd/model.cpp index 710bbb2964..6835479e7a 100644 --- a/src/widgets/doc/snippets/qlistview-dnd/model.cpp +++ b/src/widgets/doc/snippets/qlistview-dnd/model.cpp @@ -54,7 +54,7 @@ A simple model that uses a QStringList as its data source. */ -#include <QtGui> +#include <QtWidgets> #include "model.h" @@ -121,7 +121,7 @@ bool DragDropListModel::dropMimeData(const QMimeData *data, //! [6] insertRows(beginRow, rows, QModelIndex()); - foreach (const QString &text, newItems) { + for (const QString &text : qAsConst(newItems)) { QModelIndex idx = index(beginRow, 0, QModelIndex()); setData(idx, text); beginRow++; @@ -146,12 +146,12 @@ Qt::ItemFlags DragDropListModel::flags(const QModelIndex &index) const //! [8] QMimeData *DragDropListModel::mimeData(const QModelIndexList &indexes) const { - QMimeData *mimeData = new QMimeData(); + QMimeData *mimeData = new QMimeData; QByteArray encodedData; QDataStream stream(&encodedData, QIODevice::WriteOnly); - foreach (const QModelIndex &index, indexes) { + for (const QModelIndex &index : indexes) { if (index.isValid()) { QString text = data(index, Qt::DisplayRole).toString(); stream << text; diff --git a/src/widgets/doc/snippets/qlistwidget-dnd/mainwindow.cpp b/src/widgets/doc/snippets/qlistwidget-dnd/mainwindow.cpp index 1153250b17..70df2b112e 100644 --- a/src/widgets/doc/snippets/qlistwidget-dnd/mainwindow.cpp +++ b/src/widgets/doc/snippets/qlistwidget-dnd/mainwindow.cpp @@ -48,7 +48,7 @@ ** ****************************************************************************/ -#include <QtGui> +#include <QtWidgets> #include "mainwindow.h" @@ -74,7 +74,7 @@ listWidget->setDragDropMode(QAbstractItemView::InternalMove); this->listWidget = listWidget; - connect(quitAction, SIGNAL(triggered()), this, SLOT(close())); + connect(quitAction, &QAction::triggered, this, &QWidget::close); setupListItems(); diff --git a/src/widgets/doc/snippets/qlistwidget-using/mainwindow.cpp b/src/widgets/doc/snippets/qlistwidget-using/mainwindow.cpp index ff69fd2efd..13b20bb856 100644 --- a/src/widgets/doc/snippets/qlistwidget-using/mainwindow.cpp +++ b/src/widgets/doc/snippets/qlistwidget-using/mainwindow.cpp @@ -48,7 +48,7 @@ ** ****************************************************************************/ -#include <QtGui> +#include <QtWidgets> #include "mainwindow.h" @@ -77,14 +77,13 @@ MainWindow::MainWindow() listWidget = new QListWidget(this); listWidget->setSelectionMode(QAbstractItemView::SingleSelection); - connect(quitAction, SIGNAL(triggered()), this, SLOT(close())); - connect(ascendingAction, SIGNAL(triggered()), this, SLOT(sortAscending())); - connect(descendingAction, SIGNAL(triggered()), this, SLOT(sortDescending())); - connect(insertAction, SIGNAL(triggered()), this, SLOT(insertItem())); - connect(removeAction, SIGNAL(triggered()), this, SLOT(removeItem())); - connect(listWidget, - SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), - this, SLOT(updateMenus(QListWidgetItem*))); + connect(quitAction, &QAction::triggered, this, &QWidget::close); + connect(ascendingAction, &QAction::triggered, this, &MainWindow::sortAscending); + connect(descendingAction, &QAction::triggered, this, &MainWindow::sortDescending); + connect(insertAction, &QAction::triggered, this, &MainWindow::insertItem); + connect(removeAction, &QAction::triggered, this, &MainWindow::removeItem); + connect(listWidget, &QListWidget::currentItemChanged, + this, &MainWindow::updateMenus); setupListItems(); updateMenus(listWidget->currentItem()); diff --git a/src/widgets/doc/snippets/qsortfilterproxymodel/main.cpp b/src/widgets/doc/snippets/qsortfilterproxymodel/main.cpp index a6284bd578..2d4b1023f1 100644 --- a/src/widgets/doc/snippets/qsortfilterproxymodel/main.cpp +++ b/src/widgets/doc/snippets/qsortfilterproxymodel/main.cpp @@ -48,7 +48,7 @@ ** ****************************************************************************/ -#include <QtGui> +#include <QtWidgets> int main(int argc, char *argv[]) { @@ -74,9 +74,8 @@ int main(int argc, char *argv[]) filteredView->setWindowTitle("Filtered view onto a string list model"); QLineEdit *patternEditor = new QLineEdit; - QObject:: - connect(patternEditor, SIGNAL(textChanged(QString)), - filterModel, SLOT(setFilterRegExp(QString))); + QObject::connect(patternEditor, &QLineEdit::textChanged, + filterModel, &QSortFilterProxyModel::setFilterWildcard); QVBoxLayout *layout = new QVBoxLayout(window); layout->addWidget(filteredView); diff --git a/src/widgets/doc/snippets/qstackedlayout/main.cpp b/src/widgets/doc/snippets/qstackedlayout/main.cpp index 765608848c..9c61939dee 100644 --- a/src/widgets/doc/snippets/qstackedlayout/main.cpp +++ b/src/widgets/doc/snippets/qstackedlayout/main.cpp @@ -48,13 +48,12 @@ ** ****************************************************************************/ -#include <QtGui> -#include <QApplication> +#include <QtWidgets> class Widget : public QWidget { public: - Widget(QWidget *parent = 0); + Widget(QWidget *parent = nullptr); }; Widget::Widget(QWidget *parent) @@ -75,8 +74,8 @@ Widget::Widget(QWidget *parent) pageComboBox->addItem(tr("Page 1")); pageComboBox->addItem(tr("Page 2")); pageComboBox->addItem(tr("Page 3")); - connect(pageComboBox, SIGNAL(activated(int)), - stackedLayout, SLOT(setCurrentIndex(int))); + connect(pageComboBox, QOverload<int>::of(&QComboBox::activated), + stackedLayout, &QStackedLayout::setCurrentIndex); //! [1] //! [2] diff --git a/src/widgets/doc/snippets/qstackedwidget/main.cpp b/src/widgets/doc/snippets/qstackedwidget/main.cpp index a6c9c7afe3..077c281830 100644 --- a/src/widgets/doc/snippets/qstackedwidget/main.cpp +++ b/src/widgets/doc/snippets/qstackedwidget/main.cpp @@ -48,8 +48,7 @@ ** ****************************************************************************/ -#include <QtGui> -#include <QApplication> +#include <QtWidgets> class Widget : public QWidget { @@ -75,8 +74,8 @@ Widget::Widget(QWidget *parent) pageComboBox->addItem(tr("Page 1")); pageComboBox->addItem(tr("Page 2")); pageComboBox->addItem(tr("Page 3")); - connect(pageComboBox, SIGNAL(activated(int)), - stackedWidget, SLOT(setCurrentIndex(int))); + connect(pageComboBox, QOverload<int>::of(&QComboBox::activated), + stackedWidget, &QStackedWidget::setCurrentIndex); //! [1] //! [2] QVBoxLayout *layout = new QVBoxLayout; diff --git a/src/widgets/doc/snippets/qtablewidget-resizing/mainwindow.cpp b/src/widgets/doc/snippets/qtablewidget-resizing/mainwindow.cpp index 95113153e1..d2c50336f6 100644 --- a/src/widgets/doc/snippets/qtablewidget-resizing/mainwindow.cpp +++ b/src/widgets/doc/snippets/qtablewidget-resizing/mainwindow.cpp @@ -48,7 +48,7 @@ ** ****************************************************************************/ -#include <QtGui> +#include <QtWidgets> #include "mainwindow.h" @@ -72,9 +72,9 @@ MainWindow::MainWindow() //! [0] tableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); - connect(quitAction, SIGNAL(triggered()), this, SLOT(close())); - connect(tableWidthAction, SIGNAL(triggered()), this, SLOT(changeWidth())); - connect(tableHeightAction, SIGNAL(triggered()), this, SLOT(changeHeight())); + connect(quitAction, &QAction::triggered, this, &QWidget::close); + connect(tableWidthAction, &QAction::triggered, this, &MainWindow::changeWidth); + connect(tableHeightAction, &QAction::triggered, this, &MainWindow::changeHeight); setupTableItems(); diff --git a/src/widgets/doc/snippets/qtablewidget-using/mainwindow.cpp b/src/widgets/doc/snippets/qtablewidget-using/mainwindow.cpp index 15b9457dd5..47b63b2b3f 100644 --- a/src/widgets/doc/snippets/qtablewidget-using/mainwindow.cpp +++ b/src/widgets/doc/snippets/qtablewidget-using/mainwindow.cpp @@ -48,8 +48,8 @@ ** ****************************************************************************/ -#include <QtGui> -#include "math.h" +#include <QtWidgets> +#include <math.h> #include "mainwindow.h" @@ -89,9 +89,9 @@ MainWindow::MainWindow() tableWidget->setHorizontalHeaderItem(1, squaresHeaderItem); tableWidget->setHorizontalHeaderItem(2, cubesHeaderItem); - connect(quitAction, SIGNAL(triggered()), this, SLOT(close())); - connect(sumItemsAction, SIGNAL(triggered()), this, SLOT(sumItems())); - connect(averageItemsAction, SIGNAL(triggered()), this, SLOT(averageItems())); + connect(quitAction, &QAction::triggered, this, &QWidget::close); + connect(sumItemsAction, &QAction::triggered, this, &MainWindow::sumItems); + connect(averageItemsAction, &QAction::triggered, this, &MainWindow::averageItems); setupTableItems(); @@ -119,12 +119,11 @@ void MainWindow::setupTableItems() void MainWindow::averageItems() { - QList<QTableWidgetItem *> selected = tableWidget->selectedItems(); - QTableWidgetItem *item; + const QList<QTableWidgetItem *> selected = tableWidget->selectedItems(); int number = 0; double total = 0; - foreach (item, selected) { + for (QTableWidgetItem *item : selected) { bool ok; double value = item->text().toDouble(&ok); @@ -140,12 +139,11 @@ void MainWindow::averageItems() void MainWindow::sumItems() { //! [4] - QList<QTableWidgetItem *> selected = tableWidget->selectedItems(); - QTableWidgetItem *item; + const QList<QTableWidgetItem *> selected = tableWidget->selectedItems(); int number = 0; double total = 0; - foreach (item, selected) { + for (QTableWidgetItem *item : selected) { bool ok; double value = item->text().toDouble(&ok); diff --git a/src/widgets/doc/snippets/qtreewidget-using/mainwindow.cpp b/src/widgets/doc/snippets/qtreewidget-using/mainwindow.cpp index 7c8d3f936e..b9e258cb03 100644 --- a/src/widgets/doc/snippets/qtreewidget-using/mainwindow.cpp +++ b/src/widgets/doc/snippets/qtreewidget-using/mainwindow.cpp @@ -48,7 +48,7 @@ ** ****************************************************************************/ -#include <QtGui> +#include <QtWidgets> #include "mainwindow.h" @@ -90,16 +90,15 @@ MainWindow::MainWindow() treeWidget->setHeaderLabels(headers); //! [2] - connect(quitAction, SIGNAL(triggered()), this, SLOT(close())); - connect(ascendingAction, SIGNAL(triggered()), this, SLOT(sortAscending())); - connect(autoSortAction, SIGNAL(triggered()), this, SLOT(updateSortItems())); - connect(descendingAction, SIGNAL(triggered()), this, SLOT(sortDescending())); - connect(findItemsAction, SIGNAL(triggered()), this, SLOT(findItems())); - connect(insertAction, SIGNAL(triggered()), this, SLOT(insertItem())); - connect(removeAction, SIGNAL(triggered()), this, SLOT(removeItem())); - connect(treeWidget, - SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), - this, SLOT(updateMenus(QTreeWidgetItem*))); + connect(quitAction, &QAction::triggered, this, &QWidget::close); + connect(ascendingAction, &QAction::triggered, this, &MainWindow::sortAscending); + connect(autoSortAction, &QAction::triggered, this, &MainWindow::updateSortItems); + connect(descendingAction, &QAction::triggered, this, &MainWindow::sortDescending); + connect(findItemsAction, &QAction::triggered, this, &MainWindow::findItems); + connect(insertAction, &QAction::triggered, this, &MainWindow::insertItem); + connect(removeAction, &QAction::triggered, this, &MainWindow::removeItem); + connect(treeWidget, &QTreeWidget::currentItemChanged, + this, &MainWindow::updateMenus); setupTreeItems(); updateMenus(treeWidget->currentItem()); @@ -150,17 +149,15 @@ void MainWindow::findItems() if (itemText.isEmpty()) return; -//! [6] - QTreeWidgetItem *item; -//! [6] - foreach (item, treeWidget->selectedItems()) + const QList<QTreeWidgetItem *> items = treeWidget->selectedItems(); + for (QTreeWidgetItem *item : items) item->setSelected(false); //! [7] - QList<QTreeWidgetItem *> found = treeWidget->findItems( + const QList<QTreeWidgetItem *> found = treeWidget->findItems( itemText, Qt::MatchWildcard); - foreach (item, found) { + for (QTreeWidgetItem *item : found) { item->setSelected(true); // Show the item->text(0) for each item. } diff --git a/src/widgets/doc/snippets/qtreewidgetitemiterator-using/mainwindow.cpp b/src/widgets/doc/snippets/qtreewidgetitemiterator-using/mainwindow.cpp index 5f1f606185..bfe099bbb4 100644 --- a/src/widgets/doc/snippets/qtreewidgetitemiterator-using/mainwindow.cpp +++ b/src/widgets/doc/snippets/qtreewidgetitemiterator-using/mainwindow.cpp @@ -48,7 +48,7 @@ ** ****************************************************************************/ -#include <QtGui> +#include <QtWidgets> #include "mainwindow.h" @@ -85,16 +85,15 @@ MainWindow::MainWindow() headers << tr("Subject") << tr("Default"); treeWidget->setHeaderLabels(headers); - connect(quitAction, SIGNAL(triggered()), this, SLOT(close())); - connect(ascendingAction, SIGNAL(triggered()), this, SLOT(sortAscending())); - connect(autoSortAction, SIGNAL(triggered()), this, SLOT(updateSortItems())); - connect(descendingAction, SIGNAL(triggered()), this, SLOT(sortDescending())); - connect(findItemsAction, SIGNAL(triggered()), this, SLOT(findItems())); - connect(insertAction, SIGNAL(triggered()), this, SLOT(insertItem())); - connect(removeAction, SIGNAL(triggered()), this, SLOT(removeItem())); - connect(treeWidget, - SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), - this, SLOT(updateMenus(QTreeWidgetItem*))); + connect(quitAction, &QAction::triggered, this, &QWidget::close); + connect(ascendingAction, &QAction::triggered, this, &MainWindow::sortAscending); + connect(autoSortAction, &QAction::triggered, this, &MainWindow::updateSortItems); + connect(descendingAction, &QAction::triggered, this, &MainWindow::sortDescending); + connect(findItemsAction, &QAction::triggered, this, &MainWindow::findItems); + connect(insertAction, &QAction::triggered, this, &MainWindow::insertItem); + connect(removeAction, &QAction::triggered, this, &MainWindow::removeItem); + connect(treeWidget, &QTreeWidget::currentItemChanged, + this, &MainWindow::updateMenus); setupTreeItems(); updateMenus(treeWidget->currentItem()); diff --git a/src/widgets/doc/snippets/reading-selections/window.cpp b/src/widgets/doc/snippets/reading-selections/window.cpp index 08805fe4b3..045d66a199 100644 --- a/src/widgets/doc/snippets/reading-selections/window.cpp +++ b/src/widgets/doc/snippets/reading-selections/window.cpp @@ -81,9 +81,9 @@ MainWindow::MainWindow(QWidget *parent) QAction *selectAllAction = actionMenu->addAction(tr("&Select All")); menuBar()->addMenu(actionMenu); - connect(fillAction, SIGNAL(triggered()), this, SLOT(fillSelection())); - connect(clearAction, SIGNAL(triggered()), this, SLOT(clearSelection())); - connect(selectAllAction, SIGNAL(triggered()), this, SLOT(selectAll())); + connect(fillAction, &QAction::triggered, this, &MainWindow::fillSelection); + connect(clearAction, &QAction::triggered, this, &MainWindow::clearSelection); + connect(selectAllAction, &QAction::triggered, this, &MainWindow::selectAll); selectionModel = table->selectionModel(); @@ -94,10 +94,9 @@ MainWindow::MainWindow(QWidget *parent) void MainWindow::fillSelection() { //! [0] - QModelIndexList indexes = selectionModel->selectedIndexes(); - QModelIndex index; + const QModelIndexList indexes = selectionModel->selectedIndexes(); - foreach(index, indexes) { + for (const QModelIndex &index : indexes) { QString text = QString("(%1,%2)").arg(index.row()).arg(index.column()); model->setData(index, text); } @@ -106,11 +105,10 @@ void MainWindow::fillSelection() void MainWindow::clearSelection() { - QModelIndexList indexes = selectionModel->selectedIndexes(); - QModelIndex index; + const QModelIndexList indexes = selectionModel->selectedIndexes(); - foreach(index, indexes) - model->setData(index, ""); + for (const QModelIndex &index : indexes) + model->setData(index, QString()); } void MainWindow::selectAll() diff --git a/src/widgets/doc/snippets/updating-selections/window.cpp b/src/widgets/doc/snippets/updating-selections/window.cpp index 0bdcf8a64d..26e9b56ae4 100644 --- a/src/widgets/doc/snippets/updating-selections/window.cpp +++ b/src/widgets/doc/snippets/updating-selections/window.cpp @@ -74,12 +74,10 @@ MainWindow::MainWindow(QWidget *parent) table->setModel(model); selectionModel = table->selectionModel(); - connect(selectionModel, - SIGNAL(selectionChanged(QItemSelection,QItemSelection)), - this, SLOT(updateSelection(QItemSelection,QItemSelection))); - connect(selectionModel, - SIGNAL(currentChanged(QModelIndex,QModelIndex)), - this, SLOT(changeCurrent(QModelIndex,QModelIndex))); + connect(selectionModel, &QItemSelectionModel::selectionChanged, + this, &MainWindow::updateSelection); + connect(selectionModel, &QItemSelectionModel::currentChanged, + this, &MainWindow::changeCurrent); statusBar(); setCentralWidget(table); @@ -89,10 +87,9 @@ MainWindow::MainWindow(QWidget *parent) void MainWindow::updateSelection(const QItemSelection &selected, const QItemSelection &deselected) { - QModelIndex index; QModelIndexList items = selected.indexes(); - foreach (index, items) { + for (const QModelIndex &index : qAsConst(items)) { QString text = QString("(%1,%2)").arg(index.row()).arg(index.column()); model->setData(index, text); //! [0] //! [1] @@ -102,8 +99,8 @@ void MainWindow::updateSelection(const QItemSelection &selected, //! [2] items = deselected.indexes(); - foreach (index, items) - model->setData(index, ""); + for (const QModelIndex &index : qAsConst(items)) { + model->setData(index, QString()); } //! [2] diff --git a/src/widgets/doc/src/model-view-programming.qdoc b/src/widgets/doc/src/model-view-programming.qdoc index 83397c90b6..9335ff78c9 100644 --- a/src/widgets/doc/src/model-view-programming.qdoc +++ b/src/widgets/doc/src/model-view-programming.qdoc @@ -1003,8 +1003,8 @@ \snippet reading-selections/window.cpp 0 - The above code uses Qt's convenient \l{Container Classes}{foreach - keyword} to iterate over, and modify, the items corresponding to the + The above code uses a range-based for-loop to iterate over, + and modify, the items corresponding to the indexes returned by the selection model. The selection model emits signals to indicate changes in the @@ -1611,7 +1611,6 @@ We can obtain a list of matching items with the \c findItems() function: - \snippet qtreewidget-using/mainwindow.cpp 6 \snippet qtreewidget-using/mainwindow.cpp 7 The above code causes items in a tree widget to be selected if they From 0059de2d1b4f9a063af7e81788aaec22a3ac7739 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Sun, 3 Feb 2019 20:29:34 +0100 Subject: [PATCH 1033/1650] QtGui documentation: cleanup Cleanup the QtGui documentation: - use new signal/slot syntax - use range-based for loop instead foreach Change-Id: Id49ff2cbe78f28a06ca0fb63e6ca6f7dc2736f7b Reviewed-by: Frederik Gladhorn <frederik.gladhorn@qt.io> Reviewed-by: Paul Wicking <paul.wicking@qt.io> --- src/gui/doc/snippets/clipboard/clipwindow.cpp | 9 +++++---- .../src_gui_itemviews_qstandarditemmodel.cpp | 4 ++-- .../code/src_gui_kernel_qguiapplication.cpp | 9 ++++++--- .../doc/snippets/draganddrop/mainwindow.cpp | 10 +++++----- src/gui/doc/snippets/picture/picture.cpp | 10 +++++----- src/gui/doc/snippets/qfontdatabase/main.cpp | 11 +++++++---- .../doc/snippets/separations/screenwidget.cpp | 4 ++-- src/gui/doc/snippets/separations/viewer.cpp | 18 +++++++++--------- .../textblock-fragments/mainwindow.cpp | 8 ++++---- .../textdocument-blocks/mainwindow.cpp | 8 ++++---- .../textdocument-frames/mainwindow.cpp | 8 ++++---- .../snippets/textdocument-lists/mainwindow.cpp | 5 +++-- .../textdocument-printing/mainwindow.cpp | 2 +- .../textdocument-selections/mainwindow.cpp | 5 +++-- .../textdocument-tables/mainwindow.cpp | 8 ++++---- 15 files changed, 64 insertions(+), 55 deletions(-) diff --git a/src/gui/doc/snippets/clipboard/clipwindow.cpp b/src/gui/doc/snippets/clipboard/clipwindow.cpp index bf1b2d904b..d1b39070fa 100644 --- a/src/gui/doc/snippets/clipboard/clipwindow.cpp +++ b/src/gui/doc/snippets/clipboard/clipwindow.cpp @@ -48,7 +48,7 @@ ** ****************************************************************************/ -#include <QtGui> +#include <QtWidgets> #include "clipwindow.h" @@ -67,10 +67,11 @@ ClipWindow::ClipWindow(QWidget *parent) previousItems = new QListWidget(centralWidget); //! [0] - connect(clipboard, SIGNAL(dataChanged()), this, SLOT(updateClipboard())); + connect(clipboard, &QClipboard::dataChanged, + this, &ClipWindow::updateClipboard); //! [0] - connect(mimeTypeCombo, SIGNAL(activated(QString)), - this, SLOT(updateData(QString))); + connect(mimeTypeCombo, QOverload<QString>::of(&QComboBox::activated), + this, &ClipWindow::updateData); QVBoxLayout *currentLayout = new QVBoxLayout(currentItem); currentLayout->addWidget(mimeTypeLabel); diff --git a/src/gui/doc/snippets/code/src_gui_itemviews_qstandarditemmodel.cpp b/src/gui/doc/snippets/code/src_gui_itemviews_qstandarditemmodel.cpp index 40893fae87..4266da0a11 100644 --- a/src/gui/doc/snippets/code/src_gui_itemviews_qstandarditemmodel.cpp +++ b/src/gui/doc/snippets/code/src_gui_itemviews_qstandarditemmodel.cpp @@ -73,8 +73,8 @@ for (int i = 0; i < 4; ++i) { //! [2] QTreeView *treeView = new QTreeView(this); treeView->setModel(myStandardItemModel); -connect(treeView, SIGNAL(clicked(QModelIndex)), - this, SLOT(clicked(QModelIndex))); +connect(treeView, &QTreeView::clicked, + this, &MyWidget::clicked); //! [2] diff --git a/src/gui/doc/snippets/code/src_gui_kernel_qguiapplication.cpp b/src/gui/doc/snippets/code/src_gui_kernel_qguiapplication.cpp index 7c5c387a5a..a399d444e1 100644 --- a/src/gui/doc/snippets/code/src_gui_kernel_qguiapplication.cpp +++ b/src/gui/doc/snippets/code/src_gui_kernel_qguiapplication.cpp @@ -64,7 +64,8 @@ MyMainWidget::MyMainWidget(QWidget *parent) :QWidget(parent) { QGuiApplication::setFallbackSessionManagementEnabled(false); - connect(qApp, SIGNAL(commitDataRequest(QSessionManager)), SLOT(commitData(QSessionManager))); + connect(qApp, &QGuiApplication::commitDataRequest, + this, &MyMainWidget::commitData); } void MyMainWidget::commitData(QSessionManager& manager) @@ -102,12 +103,14 @@ appname -session id //! [3] -foreach (const QString &command, mySession.restartCommand()) +const QStringList commands = mySession.restartCommand(); +for (const QString &command : commands) do_something(command); //! [3] //! [4] -foreach (const QString &command, mySession.discardCommand()) +const QStringList commands = mySession.discardCommand(); +for (const QString &command : mySession.discardCommand()) do_something(command); //! [4] diff --git a/src/gui/doc/snippets/draganddrop/mainwindow.cpp b/src/gui/doc/snippets/draganddrop/mainwindow.cpp index 551114856e..11311a0b57 100644 --- a/src/gui/doc/snippets/draganddrop/mainwindow.cpp +++ b/src/gui/doc/snippets/draganddrop/mainwindow.cpp @@ -48,7 +48,7 @@ ** ****************************************************************************/ -#include <QtGui> +#include <QtWidgets> #include "dragwidget.h" #include "mainwindow.h" @@ -64,10 +64,10 @@ MainWindow::MainWindow(QWidget *parent) QLabel *dataLabel = new QLabel(tr("Amount of data (bytes):"), centralWidget); dragWidget = new DragWidget(centralWidget); - connect(dragWidget, SIGNAL(mimeTypes(QStringList)), - this, SLOT(setMimeTypes(QStringList))); - connect(dragWidget, SIGNAL(dragResult(QString)), - this, SLOT(setDragResult(QString))); + connect(dragWidget, &DragWidget::mimeTypes, + this, &MainWindow::setMimeTypes); + connect(dragWidget, &DragWidget:dragResult, + this, &MainWindow::setDragResult); QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget); mainLayout->addWidget(mimeTypeLabel); diff --git a/src/gui/doc/snippets/picture/picture.cpp b/src/gui/doc/snippets/picture/picture.cpp index 3a7676f60a..863476fdbf 100644 --- a/src/gui/doc/snippets/picture/picture.cpp +++ b/src/gui/doc/snippets/picture/picture.cpp @@ -48,7 +48,7 @@ ** ****************************************************************************/ -#include <QtGui> +#include <QtWidgets> void myProcessing(const QString &) { @@ -85,8 +85,8 @@ int main() { // FORMATS //! [2] - QStringList list = QPicture::inputFormatList(); - foreach (const QString &string, list) + const QStringList list = QPicture::inputFormatList(); + for (const QString &string : list) myProcessing(string); //! [2] } @@ -94,8 +94,8 @@ int main() { // OUTPUT //! [3] - QStringList list = QPicture::outputFormatList(); - foreach (const QString &string, list) + const QStringList list = QPicture::outputFormatList(); + for (const QString &string : list) myProcessing(string); //! [3] } diff --git a/src/gui/doc/snippets/qfontdatabase/main.cpp b/src/gui/doc/snippets/qfontdatabase/main.cpp index ae078f374d..5a5aa7b485 100644 --- a/src/gui/doc/snippets/qfontdatabase/main.cpp +++ b/src/gui/doc/snippets/qfontdatabase/main.cpp @@ -48,7 +48,7 @@ ** ****************************************************************************/ -#include <QtGui> +#include <QtWidgets> int main(int argc, char **argv) { @@ -60,16 +60,19 @@ int main(int argc, char **argv) fontTree.setColumnCount(2); fontTree.setHeaderLabels(QStringList() << "Font" << "Smooth Sizes"); - foreach (const QString &family, database.families()) { + const QStringList fontFamilies = database.families(); + for (const QString &family : fontFamilies) { QTreeWidgetItem *familyItem = new QTreeWidgetItem(&fontTree); familyItem->setText(0, family); - foreach (const QString &style, database.styles(family)) { + const QStringList fontStyles = database.styles(family); + for (const QString &style : fontStyles) { QTreeWidgetItem *styleItem = new QTreeWidgetItem(familyItem); styleItem->setText(0, style); QString sizes; - foreach (int points, database.smoothSizes(family, style)) + const QList<int> smoothSizes = database.smoothSizes(family, style) + for (int points : smoothSizes) sizes += QString::number(points) + ' '; styleItem->setText(1, sizes.trimmed()); diff --git a/src/gui/doc/snippets/separations/screenwidget.cpp b/src/gui/doc/snippets/separations/screenwidget.cpp index 6f8be49bfa..d562991d26 100644 --- a/src/gui/doc/snippets/separations/screenwidget.cpp +++ b/src/gui/doc/snippets/separations/screenwidget.cpp @@ -105,8 +105,8 @@ ScreenWidget::ScreenWidget(QWidget *parent, QColor initialColor, //invertButton->setOn(inverted); invertButton->setEnabled(false); - connect(colorButton, SIGNAL(clicked()), this, SLOT(setColor())); - connect(invertButton, SIGNAL(clicked()), this, SLOT(invertImage())); + connect(colorButton, &QPushButton::clicked, this, &ScreenWidget::setColor); + connect(invertButton, &QPushButton::clicked, this, &ScreenWidget::invertImage); QGridLayout *gridLayout = new QGridLayout; gridLayout->addWidget(imageLabel, 0, 0, 1, 2); diff --git a/src/gui/doc/snippets/separations/viewer.cpp b/src/gui/doc/snippets/separations/viewer.cpp index 641294ea35..018b397f1a 100644 --- a/src/gui/doc/snippets/separations/viewer.cpp +++ b/src/gui/doc/snippets/separations/viewer.cpp @@ -58,7 +58,7 @@ A main menu provides entries for selecting files, and adjusting the brightness of the separations. */ -#include <QtGui> +#include <QtWidgets> #include "finalwidget.h" #include "screenwidget.h" @@ -126,11 +126,11 @@ void Viewer::createMenus() menuBar()->addMenu(fileMenu); menuBar()->addMenu(brightnessMenu); - connect(openAction, SIGNAL(triggered()), this, SLOT(chooseFile())); - connect(saveAction, SIGNAL(triggered()), this, SLOT(saveImage())); - connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); - connect(brightnessMenu, SIGNAL(triggered(QAction*)), this, - SLOT(setBrightness(QAction*))); + connect(openAction, &QAction::triggered, this, &Viewer::chooseFile); + connect(saveAction, &QAction::triggered, this, &Viewer::saveImage); + connect(quitAction, &QAction::triggered, qApp, QApplication::quit); + connect(brightnessMenu, &QMenu::triggered, + this, &Viewer::setBrightness); } /* @@ -160,9 +160,9 @@ QFrame* Viewer::createCentralWidget() yellowWidget = new ScreenWidget(frame, Qt::yellow, tr("Yellow"), ScreenWidget::Yellow, labelSize); - connect(cyanWidget, SIGNAL(imageChanged()), this, SLOT(createImage())); - connect(magentaWidget, SIGNAL(imageChanged()), this, SLOT(createImage())); - connect(yellowWidget, SIGNAL(imageChanged()), this, SLOT(createImage())); + connect(cyanWidget, &ScreenWidget::imageChanged, this, &Viewer::createImage); + connect(magentaWidget, &ScreenWidget::imageChanged, this, &Viewer::createImage); + connect(yellowWidget, &ScreenWidget::imageChanged, this, &Viewer::createImage); grid->addWidget(finalWidget, 0, 0, Qt::AlignTop | Qt::AlignHCenter); grid->addWidget(cyanWidget, 0, 1, Qt::AlignTop | Qt::AlignHCenter); diff --git a/src/gui/doc/snippets/textblock-fragments/mainwindow.cpp b/src/gui/doc/snippets/textblock-fragments/mainwindow.cpp index bcc5c7dc30..bf864ce48d 100644 --- a/src/gui/doc/snippets/textblock-fragments/mainwindow.cpp +++ b/src/gui/doc/snippets/textblock-fragments/mainwindow.cpp @@ -48,7 +48,7 @@ ** ****************************************************************************/ -#include <QtGui> +#include <QtWidgets> #include "mainwindow.h" #include "xmlwriter.h" @@ -73,9 +73,9 @@ MainWindow::MainWindow() editor = new QTextEdit(this); - connect(saveAction, SIGNAL(triggered()), this, SLOT(saveFile())); - connect(quitAction, SIGNAL(triggered()), this, SLOT(close())); - connect(calendarAction, SIGNAL(triggered()), this, SLOT(insertCalendar())); + connect(saveAction, &QAction::triggered, this, &MainWindow::saveFile); + connect(quitAction, &QAction::triggered, this, &MainWindow::close); + connect(calendarAction, &QAction::triggered, this, &MainWindow::insertCalendar); setCentralWidget(editor); setWindowTitle(tr("Text Document Writer")); diff --git a/src/gui/doc/snippets/textdocument-blocks/mainwindow.cpp b/src/gui/doc/snippets/textdocument-blocks/mainwindow.cpp index f512cf0dc6..a5801da67e 100644 --- a/src/gui/doc/snippets/textdocument-blocks/mainwindow.cpp +++ b/src/gui/doc/snippets/textdocument-blocks/mainwindow.cpp @@ -48,7 +48,7 @@ ** ****************************************************************************/ -#include <QtGui> +#include <QtWidgets> #include "mainwindow.h" #include "xmlwriter.h" @@ -75,9 +75,9 @@ MainWindow::MainWindow() editor = new QTextEdit(this); //! [0] - connect(saveAction, SIGNAL(triggered()), this, SLOT(saveFile())); - connect(quitAction, SIGNAL(triggered()), this, SLOT(close())); - connect(calendarAction, SIGNAL(triggered()), this, SLOT(insertCalendar())); + connect(saveAction, &QAction::triggered, this, &MainWindow::saveFile); + connect(quitAction, &QAction::triggered, this, &MainWindow::close); + connect(calendarAction, &QAction::triggered, this, &MainWindow::insertCalendar); setCentralWidget(editor); setWindowTitle(tr("Text Document Writer")); diff --git a/src/gui/doc/snippets/textdocument-frames/mainwindow.cpp b/src/gui/doc/snippets/textdocument-frames/mainwindow.cpp index f15ad45f2e..edfadb4c77 100644 --- a/src/gui/doc/snippets/textdocument-frames/mainwindow.cpp +++ b/src/gui/doc/snippets/textdocument-frames/mainwindow.cpp @@ -48,7 +48,7 @@ ** ****************************************************************************/ -#include <QtGui> +#include <QtWidgets> #include "mainwindow.h" #include "xmlwriter.h" @@ -64,7 +64,7 @@ MainWindow::MainWindow() quitAction->setShortcut(tr("Ctrl+Q")); menuBar()->addMenu(fileMenu); - editor = new QTextEdit(); + editor = new QTextEdit; QTextCursor cursor(editor->textCursor()); cursor.movePosition(QTextCursor::Start); @@ -130,8 +130,8 @@ MainWindow::MainWindow() plainCharFormat); - connect(saveAction, SIGNAL(triggered()), this, SLOT(saveFile())); - connect(quitAction, SIGNAL(triggered()), this, SLOT(close())); + connect(saveAction, &QAction::triggered, this, &MainWindow::saveFile); + connect(quitAction, &QAction::triggered, this, &MainWindow::close); setCentralWidget(editor); setWindowTitle(tr("Text Document Frames")); diff --git a/src/gui/doc/snippets/textdocument-lists/mainwindow.cpp b/src/gui/doc/snippets/textdocument-lists/mainwindow.cpp index 15a2752c8b..785f7ebcc9 100644 --- a/src/gui/doc/snippets/textdocument-lists/mainwindow.cpp +++ b/src/gui/doc/snippets/textdocument-lists/mainwindow.cpp @@ -48,7 +48,7 @@ ** ****************************************************************************/ -#include <QtGui> +#include <QtWidgets> #include "mainwindow.h" @@ -88,7 +88,8 @@ MainWindow::MainWindow() document = new QTextDocument(this); editor->setDocument(document); - connect(editor, SIGNAL(selectionChanged()), this, SLOT(updateMenus())); + connect(editor, &QTextEdit::selectionChanged, + this, &MainWindow::updateMenus); updateMenus(); diff --git a/src/gui/doc/snippets/textdocument-printing/mainwindow.cpp b/src/gui/doc/snippets/textdocument-printing/mainwindow.cpp index 40459b49da..a7bd90a9f1 100644 --- a/src/gui/doc/snippets/textdocument-printing/mainwindow.cpp +++ b/src/gui/doc/snippets/textdocument-printing/mainwindow.cpp @@ -74,7 +74,7 @@ MainWindow::MainWindow() document = new QTextDocument(this); editor->setDocument(document); - connect(editor, SIGNAL(selectionChanged()), this, SLOT(updateMenus())); + connect(editor, &QTextEdit::selectionChanged, this, &MainWindow::updateMenus); setCentralWidget(editor); setWindowTitle(tr("Text Document Writer")); diff --git a/src/gui/doc/snippets/textdocument-selections/mainwindow.cpp b/src/gui/doc/snippets/textdocument-selections/mainwindow.cpp index 8ac3913f3c..9253e87670 100644 --- a/src/gui/doc/snippets/textdocument-selections/mainwindow.cpp +++ b/src/gui/doc/snippets/textdocument-selections/mainwindow.cpp @@ -48,7 +48,7 @@ ** ****************************************************************************/ -#include <QtGui> +#include <QtWidgets> #include "mainwindow.h" @@ -90,7 +90,8 @@ MainWindow::MainWindow() document = new QTextDocument(this); editor->setDocument(document); - connect(editor, SIGNAL(selectionChanged()), this, SLOT(updateMenus())); + connect(editor, &QTextEdit::selectionChanged, + this, &MainWindow::updateMenus); setCentralWidget(editor); setWindowTitle(tr("Text Document Writer")); diff --git a/src/gui/doc/snippets/textdocument-tables/mainwindow.cpp b/src/gui/doc/snippets/textdocument-tables/mainwindow.cpp index 061c191f1c..bd976a8ce4 100644 --- a/src/gui/doc/snippets/textdocument-tables/mainwindow.cpp +++ b/src/gui/doc/snippets/textdocument-tables/mainwindow.cpp @@ -48,7 +48,7 @@ ** ****************************************************************************/ -#include <QtGui> +#include <QtWidgets> #include "mainwindow.h" #include "xmlwriter.h" @@ -132,9 +132,9 @@ MainWindow::MainWindow() } //! [8] - connect(saveAction, SIGNAL(triggered()), this, SLOT(saveFile())); - connect(quitAction, SIGNAL(triggered()), this, SLOT(close())); - connect(showTableAction, SIGNAL(triggered()), this, SLOT(showTable())); + connect(saveAction, &QAction:triggered, this, &MainWindow::saveFile); + connect(quitAction, &QAction:triggered, this, &MainWindow::close); + connect(showTableAction, &QAction:triggered, this, &MainWindow::showTable); setCentralWidget(editor); setWindowTitle(tr("Text Document Tables")); From 1b90684948df45977515ab5e9a3fb4aafb72c6fd Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Sun, 27 Jan 2019 17:49:07 +0100 Subject: [PATCH 1034/1650] QtWidgets: replace 0 with \nullptr in documentation Replace 0 with \nullptr in the documentation. As a drive-by also replace some 0 with nullptr in the corresponding code. Change-Id: I5e5bc1ae892f270d7c3419db1c179053561f1b26 Reviewed-by: Paul Wicking <paul.wicking@qt.io> --- src/widgets/dialogs/qdialog.cpp | 4 +- src/widgets/dialogs/qmessagebox.cpp | 14 +++---- src/widgets/dialogs/qwizard.cpp | 16 ++++---- src/widgets/kernel/qactiongroup.cpp | 4 +- src/widgets/kernel/qapplication.cpp | 20 +++++----- src/widgets/kernel/qgridlayout.cpp | 6 +-- src/widgets/kernel/qlayout.cpp | 17 +++++---- src/widgets/kernel/qlayoutitem.cpp | 18 ++++----- src/widgets/kernel/qopenglwidget.cpp | 4 +- src/widgets/kernel/qstackedlayout.cpp | 12 +++--- src/widgets/kernel/qwidget.cpp | 55 ++++++++++++++------------- src/widgets/styles/qstyleoption.cpp | 8 ++-- 12 files changed, 90 insertions(+), 88 deletions(-) diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp index ebbd2fa9ea..cc04110a30 100644 --- a/src/widgets/dialogs/qdialog.cpp +++ b/src/widgets/dialogs/qdialog.cpp @@ -422,7 +422,7 @@ QDialog::~QDialog() /*! \internal This function is called by the push button \a pushButton when it - becomes the default button. If \a pushButton is 0, the dialogs + becomes the default button. If \a pushButton is \nullptr, the dialogs default default button becomes the default button. This is what a push button calls when it loses focus. */ @@ -1014,7 +1014,7 @@ void QDialog::setExtension(QWidget* extension) /*! \obsolete - Returns the dialog's extension or 0 if no extension has been + Returns the dialog's extension or \nullptr if no extension has been defined. Instead of using this functionality, we recommend that you simply call diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index ac1952a642..c9818624fb 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -834,7 +834,7 @@ QMessageBox::QMessageBox(QWidget *parent) The message box is an \l{Qt::ApplicationModal} {application modal} dialog box. - On \macos, if \a parent is not 0 and you want your message box + On \macos, if \a parent is not \nullptr and you want your message box to appear as a Qt::Sheet of that parent, set the message box's \l{setWindowModality()} {window modality} to Qt::WindowModal (default). Otherwise, the message box will be a standard dialog. @@ -983,7 +983,7 @@ QMessageBox::StandardButton QMessageBox::standardButton(QAbstractButton *button) \since 4.2 Returns a pointer corresponding to the standard button \a which, - or 0 if the standard button doesn't exist in this message box. + or \nullptr if the standard button doesn't exist in this message box. \sa standardButtons, standardButton() */ @@ -1106,7 +1106,7 @@ void QMessageBoxPrivate::detectEscapeButton() \since 4.2 Returns the button that was clicked by the user, - or 0 if the user hit the \uicontrol Esc key and + or \nullptr if the user hit the \uicontrol Esc key and no \l{setEscapeButton()}{escape button} was set. If exec() hasn't been called yet, returns nullptr. @@ -1173,7 +1173,7 @@ void QMessageBox::setDefaultButton(QMessageBox::StandardButton button) /*! \since 5.2 Sets the checkbox \a cb on the message dialog. The message box takes ownership of the checkbox. - The argument \a cb can be 0 to remove an existing checkbox from the message box. + The argument \a cb can be \nullptr to remove an existing checkbox from the message box. \sa checkBox() */ @@ -1205,7 +1205,7 @@ void QMessageBox::setCheckBox(QCheckBox *cb) /*! \since 5.2 - Returns the checkbox shown on the dialog. This is 0 if no checkbox is set. + Returns the checkbox shown on the dialog. This is \nullptr if no checkbox is set. \sa setCheckBox() */ @@ -1570,7 +1570,7 @@ QList<QAbstractButton *> QMessageBox::buttons() const \since 4.5 Returns the button role for the specified \a button. This function returns - \l InvalidRole if \a button is 0 or has not been added to the message box. + \l InvalidRole if \a button is \nullptr or has not been added to the message box. \sa buttons(), addButton() */ @@ -1835,7 +1835,7 @@ void QMessageBox::about(QWidget *parent, const QString &title, const QString &te /*! Displays a simple message box about Qt, with the given \a title - and centered over \a parent (if \a parent is not 0). The message + and centered over \a parent (if \a parent is not \nullptr). The message includes the version number of Qt being used by the application. This is useful for inclusion in the \uicontrol Help menu of an application, diff --git a/src/widgets/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp index 59168ba14d..9345a4b583 100644 --- a/src/widgets/dialogs/qwizard.cpp +++ b/src/widgets/dialogs/qwizard.cpp @@ -2374,8 +2374,8 @@ void QWizard::removePage(int id) /*! \fn QWizardPage *QWizard::page(int id) const - Returns the page with the given \a id, or 0 if there is no such - page. + Returns the page with the given \a id, or \nullptr if there is no + such page. \sa addPage(), setPage() */ @@ -2462,8 +2462,8 @@ int QWizard::startId() const } /*! - Returns a pointer to the current page, or 0 if there is no current - page (e.g., before the wizard is shown). + Returns a pointer to the current page, or \nullptr if there is no + current page (e.g., before the wizard is shown). This is equivalent to calling page(currentId()). @@ -2954,7 +2954,7 @@ void QWizard::setDefaultProperty(const char *className, const char *property, Passing 0 shows no side widget. - When the \a widget is not 0 the wizard reparents it. + When the \a widget is not \nullptr the wizard reparents it. Any previous side widget is hidden. @@ -2963,7 +2963,7 @@ void QWizard::setDefaultProperty(const char *className, const char *property, All widgets set here will be deleted by the wizard when it is destroyed unless you separately reparent the widget after setting - some other side widget (or 0). + some other side widget (or \nullptr). By default, no side widget is present. */ @@ -2981,7 +2981,7 @@ void QWizard::setSideWidget(QWidget *widget) /*! \since 4.7 - Returns the widget on the left side of the wizard or 0. + Returns the widget on the left side of the wizard or \nullptr. By default, no side widget is present. */ @@ -3969,7 +3969,7 @@ void QWizardPage::registerField(const QString &name, QWidget *widget, const char } /*! - Returns the wizard associated with this page, or 0 if this page + Returns the wizard associated with this page, or \nullptr if this page hasn't been inserted into a QWizard yet. \sa QWizard::addPage(), QWizard::setPage() diff --git a/src/widgets/kernel/qactiongroup.cpp b/src/widgets/kernel/qactiongroup.cpp index 7934ae1d90..4786437d7e 100644 --- a/src/widgets/kernel/qactiongroup.cpp +++ b/src/widgets/kernel/qactiongroup.cpp @@ -316,8 +316,8 @@ bool QActionGroup::isEnabled() const } /*! - Returns the currently checked action in the group, or 0 if none - are checked. + Returns the currently checked action in the group, or \nullptr if + none are checked. */ QAction *QActionGroup::checkedAction() const { diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 53e1d13455..3594b5c902 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -784,7 +784,7 @@ QWidget *QApplication::activeModalWidget() /*! Cleans up any window system resources that were allocated by this - application. Sets the global variable \c qApp to 0. + application. Sets the global variable \c qApp to \nullptr. */ QApplication::~QApplication() @@ -893,8 +893,8 @@ void qt_cleanup() /*! \fn QWidget *QApplication::widgetAt(const QPoint &point) - Returns the widget at global screen position \a point, or 0 if there is no - Qt widget there. + Returns the widget at global screen position \a point, or \nullptr + if there is no Qt widget there. This function can be slow. @@ -904,9 +904,9 @@ QWidget *QApplication::widgetAt(const QPoint &p) { QWidget *window = QApplication::topLevelAt(p); if (!window) - return 0; + return nullptr; - QWidget *child = 0; + QWidget *child = nullptr; if (!window->testAttribute(Qt::WA_TransparentForMouseEvents)) child = window->childAt(window->mapFromGlobal(p)); @@ -942,8 +942,8 @@ QWidget *QApplication::widgetAt(const QPoint &p) \overload - Returns the widget at global screen position (\a x, \a y), or 0 if there is - no Qt widget there. + Returns the widget at global screen position (\a x, \a y), or + \nullptr if there is no Qt widget there. */ /*! @@ -1728,8 +1728,8 @@ QWidgetList QApplication::allWidgets() } /*! - Returns the application widget that has the keyboard input focus, or 0 if - no widget in this application has the focus. + Returns the application widget that has the keyboard input focus, + or \nullptr if no widget in this application has the focus. \sa QWidget::setFocus(), QWidget::hasFocus(), activeWindow(), focusChanged() */ @@ -1797,7 +1797,7 @@ void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason) /*! Returns the application top-level window that has the keyboard input focus, - or 0 if no application window has the focus. There might be an + or \nullptr if no application window has the focus. There might be an activeWindow() even if there is no focusWidget(), for example if no widget in that window accepts key events. diff --git a/src/widgets/kernel/qgridlayout.cpp b/src/widgets/kernel/qgridlayout.cpp index f1c6c96a6d..4f2b505e32 100644 --- a/src/widgets/kernel/qgridlayout.cpp +++ b/src/widgets/kernel/qgridlayout.cpp @@ -1330,8 +1330,8 @@ QLayoutItem *QGridLayout::itemAt(int index) const /*! \since 4.4 - Returns the layout item that occupies cell (\a row, \a column), or 0 if - the cell is empty. + Returns the layout item that occupies cell (\a row, \a column), or + \nullptr if the cell is empty. \sa getItemPosition(), indexOf() */ @@ -1346,7 +1346,7 @@ QLayoutItem *QGridLayout::itemAtPosition(int row, int column) const return box->item(); } } - return 0; + return nullptr; } /*! diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp index eac5674161..090abc883d 100644 --- a/src/widgets/kernel/qlayout.cpp +++ b/src/widgets/kernel/qlayout.cpp @@ -474,8 +474,8 @@ QRect QLayout::contentsRect() const /*! - Returns the parent widget of this layout, or 0 if this layout is - not installed on any widget. + Returns the parent widget of this layout, or \nullptr if this + layout is not installed on any widget. If the layout is a sub-layout, this function returns the parent widget of the parent layout. @@ -490,11 +490,11 @@ QWidget *QLayout::parentWidget() const QLayout *parentLayout = qobject_cast<QLayout*>(parent()); if (Q_UNLIKELY(!parentLayout)) { qWarning("QLayout::parentWidget: A layout can only have another layout as a parent."); - return 0; + return nullptr; } return parentLayout->parentWidget(); } else { - return 0; + return nullptr; } } else { Q_ASSERT(parent() && parent()->isWidgetType()); @@ -950,8 +950,8 @@ void QLayout::setMenuBar(QWidget *widget) } /*! - Returns the menu bar set for this layout, or 0 if no menu bar is - set. + Returns the menu bar set for this layout, or \nullptr if no + menu bar is set. */ QWidget *QLayout::menuBar() const @@ -1130,8 +1130,9 @@ bool QLayout::activate() Searches for widget \a from and replaces it with widget \a to if found. Returns the layout item that contains the widget \a from on success. - Otherwise \c 0 is returned. If \a options contains \c Qt::FindChildrenRecursively - (the default), sub-layouts are searched for doing the replacement. + Otherwise \nullptr is returned. + If \a options contains \c Qt::FindChildrenRecursively (the default), + sub-layouts are searched for doing the replacement. Any other flag in \a options is ignored. Notice that the returned item therefore might not belong to this layout, diff --git a/src/widgets/kernel/qlayoutitem.cpp b/src/widgets/kernel/qlayoutitem.cpp index 25890e888b..9e6d1c5eac 100644 --- a/src/widgets/kernel/qlayoutitem.cpp +++ b/src/widgets/kernel/qlayoutitem.cpp @@ -309,24 +309,24 @@ void QLayoutItem::invalidate() /*! If this item is a QLayout, it is returned as a QLayout; otherwise - 0 is returned. This function provides type-safe casting. + \nullptr is returned. This function provides type-safe casting. \sa spacerItem(), widget() */ -QLayout * QLayoutItem::layout() +QLayout *QLayoutItem::layout() { - return 0; + return nullptr; } /*! If this item is a QSpacerItem, it is returned as a QSpacerItem; - otherwise 0 is returned. This function provides type-safe casting. + otherwise \nullptr is returned. This function provides type-safe casting. \sa layout(), widget() */ -QSpacerItem * QLayoutItem::spacerItem() +QSpacerItem *QLayoutItem::spacerItem() { - return 0; + return nullptr; } /*! @@ -354,7 +354,7 @@ QSpacerItem * QSpacerItem::spacerItem() /*! If this item manages a QWidget, returns that widget. Otherwise, - \c nullptr is returned. + \nullptr is returned. \note While the functions layout() and spacerItem() perform casts, this function returns another object: QLayout and QSpacerItem inherit QLayoutItem, @@ -362,9 +362,9 @@ QSpacerItem * QSpacerItem::spacerItem() \sa layout(), spacerItem() */ -QWidget * QLayoutItem::widget() +QWidget *QLayoutItem::widget() { - return 0; + return nullptr; } /*! diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index 89f860150f..cf15614680 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -1118,8 +1118,8 @@ void QOpenGLWidget::setTextureFormat(GLenum texFormat) /*! \return the active internal texture format if the widget has already initialized, the requested format if one was set but the widget has not yet - been made visible, or 0 if setTextureFormat() was not called and the widget - has not yet been made visible. + been made visible, or \nullptr if setTextureFormat() was not called and the + widget has not yet been made visible. \since 5.10 */ diff --git a/src/widgets/kernel/qstackedlayout.cpp b/src/widgets/kernel/qstackedlayout.cpp index 7430d833db..0412dc188d 100644 --- a/src/widgets/kernel/qstackedlayout.cpp +++ b/src/widgets/kernel/qstackedlayout.cpp @@ -378,20 +378,20 @@ void QStackedLayout::setCurrentWidget(QWidget *widget) /*! - Returns the current widget, or 0 if there are no widgets in this - layout. + Returns the current widget, or \nullptr if there are no widgets + in this layout. \sa currentIndex(), setCurrentWidget() */ QWidget *QStackedLayout::currentWidget() const { Q_D(const QStackedLayout); - return d->index >= 0 ? d->list.at(d->index)->widget() : 0; + return d->index >= 0 ? d->list.at(d->index)->widget() : nullptr; } /*! - Returns the widget at the given \a index, or 0 if there is no - widget at the given position. + Returns the widget at the given \a index, or \nullptr if there is + no widget at the given position. \sa currentWidget(), indexOf() */ @@ -399,7 +399,7 @@ QWidget *QStackedLayout::widget(int index) const { Q_D(const QStackedLayout); if (index < 0 || index >= d->list.size()) - return 0; + return nullptr; return d->list.at(index)->widget(); } diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 3b1d82df18..87cc150530 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -511,10 +511,10 @@ void QWidget::setAutoFillBackground(bool enabled) Every widget's constructor accepts one or two standard arguments: \list 1 - \li \c{QWidget *parent = 0} is the parent of the new widget. If it is 0 - (the default), the new widget will be a window. If not, it will be - a child of \e parent, and be constrained by \e parent's geometry - (unless you specify Qt::Window as window flag). + \li \c{QWidget *parent = \nullptr} is the parent of the new widget. + If it is \nullptr (the default), the new widget will be a window. + If not, it will be a child of \e parent, and be constrained by + \e parent's geometry (unless you specify Qt::Window as window flag). \li \c{Qt::WindowFlags f = 0} (where available) sets the window flags; the default is suitable for almost all widgets, but to get, for example, a window without a window system frame, you must use @@ -1003,7 +1003,7 @@ struct QWidgetExceptionCleaner Constructs a widget which is a child of \a parent, with widget flags set to \a f. - If \a parent is 0, the new widget becomes a window. If + If \a parent is \nullptr, the new widget becomes a window. If \a parent is another widget, this widget becomes a child window inside \a parent. The new widget is deleted when its \a parent is deleted. @@ -2497,12 +2497,12 @@ void QWidgetPrivate::deactivateWidgetCleanup() The window identifier type depends on the underlying window system, see \c qwindowdefs.h for the actual definition. If there - is no widget with this identifier, 0 is returned. + is no widget with this identifier, \nullptr is returned. */ QWidget *QWidget::find(WId id) { - return QWidgetPrivate::mapper ? QWidgetPrivate::mapper->value(id, 0) : 0; + return QWidgetPrivate::mapper ? QWidgetPrivate::mapper->value(id, 0) : nullptr; } @@ -3279,7 +3279,7 @@ void QWidget::addActions(QList<QAction*> actions) /*! Inserts the action \a action to this widget's list of actions, - before the action \a before. It appends the action if \a before is 0 or + before the action \a before. It appends the action if \a before is \nullptr or \a before is not a valid action for this widget. A QWidget should only have one of each action. @@ -3313,7 +3313,7 @@ void QWidget::insertAction(QAction *before, QAction *action) /*! Inserts the actions \a actions to this widget's list of actions, - before the action \a before. It appends the action if \a before is 0 or + before the action \a before. It appends the action if \a before is \nullptr or \a before is not a valid action for this widget. A QWidget can have at most one of each action. @@ -4336,7 +4336,8 @@ QWidget *QWidget::window() const \since 4.4 Returns the native parent for this widget, i.e. the next ancestor widget - that has a system identifier, or 0 if it does not have any native parent. + that has a system identifier, or \nullptr if it does not have any native + parent. \sa effectiveWinId() */ @@ -5273,7 +5274,7 @@ QPixmap QWidget::grab(const QRect &rectangle) \brief The graphicsEffect function returns a pointer to the widget's graphics effect. - If the widget has no graphics effect, 0 is returned. + If the widget has no graphics effect, \nullptr is returned. \since 4.6 @@ -5917,10 +5918,10 @@ QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint * Finds the nearest widget embedded in a graphics proxy widget along the chain formed by this widget and its ancestors. The search starts at \a origin (inclusive). - If successful, the function returns the proxy that embeds the widget, or 0 if no embedded - widget was found. + If successful, the function returns the proxy that embeds the widget, or \nullptr if no + embedded widget was found. */ -QGraphicsProxyWidget * QWidgetPrivate::nearestGraphicsProxyWidget(const QWidget *origin) +QGraphicsProxyWidget *QWidgetPrivate::nearestGraphicsProxyWidget(const QWidget *origin) { if (origin) { QWExtra *extra = origin->d_func()->extra; @@ -5928,7 +5929,7 @@ QGraphicsProxyWidget * QWidgetPrivate::nearestGraphicsProxyWidget(const QWidget return extra->proxyWidget; return nearestGraphicsProxyWidget(origin->parentWidget()); } - return 0; + return nullptr; } #endif @@ -6400,7 +6401,7 @@ void QWidget::setWindowRole(const QString &role) /*! - Sets the widget's focus proxy to widget \a w. If \a w is 0, the + Sets the widget's focus proxy to widget \a w. If \a w is \nullptr, the function resets this widget to have no focus proxy. Some widgets can "have focus", but create a child widget, such as @@ -6433,15 +6434,15 @@ void QWidget::setFocusProxy(QWidget * w) /*! - Returns the focus proxy, or 0 if there is no focus proxy. + Returns the focus proxy, or \nullptr if there is no focus proxy. \sa setFocusProxy() */ -QWidget * QWidget::focusProxy() const +QWidget *QWidget::focusProxy() const { Q_D(const QWidget); - return d->extra ? (QWidget *)d->extra->focus_proxy : 0; + return d->extra ? (QWidget *)d->extra->focus_proxy : nullptr; } @@ -8819,7 +8820,7 @@ QSize QWidget::minimumSizeHint() const /*! \fn QWidget *QWidget::parentWidget() const - Returns the parent of this widget, or 0 if it does not have any + Returns the parent of this widget, or \nullptr if it does not have any parent widget. */ @@ -10229,7 +10230,7 @@ QRegion QWidget::mask() const } /*! - Returns the layout manager that is installed on this widget, or 0 + Returns the layout manager that is installed on this widget, or \nullptr if no layout manager is installed. The layout manager sets the geometry of the widget's children @@ -12117,14 +12118,14 @@ bool QWidgetPrivate::navigateToDirection(Direction direction) Searches for a widget that is positioned in the \a direction, starting from the current focusWidget. - Returns the pointer to a found widget or 0, if there was no widget in - that direction. + Returns the pointer to a found widget or \nullptr, if there was no widget + in that direction. */ QWidget *QWidgetPrivate::widgetInNavigationDirection(Direction direction) { const QWidget *sourceWidget = QApplication::focusWidget(); if (!sourceWidget) - return 0; + return nullptr; const QRect sourceRect = sourceWidget->rect().translated(sourceWidget->mapToGlobal(QPoint())); const int sourceX = (direction == DirectionNorth || direction == DirectionSouth) ? @@ -12138,7 +12139,7 @@ QWidget *QWidgetPrivate::widgetInNavigationDirection(Direction direction) const QPoint sourceCenter = sourceRect.center(); const QWidget *sourceWindow = sourceWidget->window(); - QWidget *targetWidget = 0; + QWidget *targetWidget = nullptr; int shortestDistance = INT_MAX; const auto targetCandidates = QApplication::allWidgets(); @@ -12805,7 +12806,7 @@ void QWidget::releaseKeyboard() Returns the widget that is currently grabbing the mouse input. If no widget in this application is currently grabbing the mouse, - 0 is returned. + \nullptr is returned. \sa grabMouse(), keyboardGrabber() */ @@ -12822,7 +12823,7 @@ QWidget *QWidget::mouseGrabber() Returns the widget that is currently grabbing the keyboard input. If no widget in this application is currently grabbing the - keyboard, 0 is returned. + keyboard, \nullptr is returned. \sa grabMouse(), mouseGrabber() */ diff --git a/src/widgets/styles/qstyleoption.cpp b/src/widgets/styles/qstyleoption.cpp index 97631a5841..88031a9f1e 100644 --- a/src/widgets/styles/qstyleoption.cpp +++ b/src/widgets/styles/qstyleoption.cpp @@ -3270,7 +3270,7 @@ QStyleOptionViewItem::QStyleOptionViewItem(int version) \fn template <typename T> T qstyleoption_cast<T>(const QStyleOption *option) \relates QStyleOption - Returns a T or 0 depending on the \l{QStyleOption::type}{type} and + Returns a T or \nullptr depending on the \l{QStyleOption::type}{type} and \l{QStyleOption::version}{version} of the given \a option. Example: @@ -3285,7 +3285,7 @@ QStyleOptionViewItem::QStyleOptionViewItem(int version) \overload \relates QStyleOption - Returns a T or 0 depending on the type of the given \a option. + Returns a T or \nullptr depending on the type of the given \a option. */ #if QT_CONFIG(tabwidget) @@ -4006,7 +4006,7 @@ QStyleHintReturnVariant::~QStyleHintReturnVariant() \fn template <typename T> T qstyleoption_cast<T>(const QStyleHintReturn *hint) \relates QStyleHintReturn - Returns a T or 0 depending on the \l{QStyleHintReturn::type}{type} + Returns a T or \nullptr depending on the \l{QStyleHintReturn::type}{type} and \l{QStyleHintReturn::version}{version} of \a hint. Example: @@ -4021,7 +4021,7 @@ QStyleHintReturnVariant::~QStyleHintReturnVariant() \overload \relates QStyleHintReturn - Returns a T or 0 depending on the type of \a hint. + Returns a T or \nullptr depending on the type of \a hint. */ #if !defined(QT_NO_DEBUG_STREAM) From 93cebb3837e341718dfc0cc44cb74d963e8e2c6c Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Sat, 26 Jan 2019 20:06:14 +0100 Subject: [PATCH 1035/1650] QtWidgets/Graphics-/ItemViews: mark obsolete functions as deprecated Mark some long obsolete functions as deprecated so the can be removed with Qt6: - QGraphicsItem::matrix()/setMatrix()/resetMatrix()/sceneMatrix() - QGraphicsItemAnimation::reset() - QGraphicsScene::isSortCacheEnabled()/setSortCacheEnabled() - QAbstractItemDelegate::elidedText() - QAbstractItemView::setHorizontalStepsPerItem()/horizontalStepsPerItem() - QAbstractItemView::setVerticalStepsPerItem()/verticalStepsPerItem() Change-Id: I7244078552ebeac9dfbcf3291b3ae0c44cc2c1d9 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> --- src/widgets/graphicsview/qgraphicsitem.cpp | 9 ++++++++- src/widgets/graphicsview/qgraphicsitem.h | 6 ++++++ src/widgets/graphicsview/qgraphicsitemanimation.cpp | 2 ++ src/widgets/graphicsview/qgraphicsitemanimation.h | 3 +++ src/widgets/graphicsview/qgraphicsscene.cpp | 2 ++ src/widgets/graphicsview/qgraphicsscene.h | 6 ++++-- src/widgets/itemviews/qabstractitemdelegate.cpp | 2 ++ src/widgets/itemviews/qabstractitemdelegate.h | 3 +++ src/widgets/itemviews/qabstractitemview.cpp | 2 ++ src/widgets/itemviews/qabstractitemview.h | 10 ++++++---- 10 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp index 4476ecded3..6e53ea94f3 100644 --- a/src/widgets/graphicsview/qgraphicsitem.cpp +++ b/src/widgets/graphicsview/qgraphicsitem.cpp @@ -3997,6 +3997,7 @@ void QGraphicsItem::ensureVisible(const QRectF &rect, int xmargin, int ymargin) ensureVisible(QRectF(\a x, \a y, \a w, \a h), \a xmargin, \a ymargin). */ +#if QT_DEPRECATED_SINCE(5, 13) /*! \obsolete @@ -4012,6 +4013,7 @@ QMatrix QGraphicsItem::matrix() const { return transform().toAffine(); } +#endif /*! \since 4.3 @@ -4322,6 +4324,7 @@ void QGraphicsItem::setTransformOriginPoint(const QPointF &origin) */ +#if QT_DEPRECATED_SINCE(5, 13) /*! \obsolete @@ -4334,7 +4337,7 @@ QMatrix QGraphicsItem::sceneMatrix() const d_ptr->ensureSceneTransform(); return d_ptr->sceneTransform.toAffine(); } - +#endif /*! \since 4.3 @@ -4546,6 +4549,7 @@ QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) co return x; } +#if QT_DEPRECATED_SINCE(5, 13) /*! \obsolete @@ -4584,6 +4588,7 @@ void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine) // Send post-notification. itemChange(ItemTransformHasChanged, QVariant::fromValue<QTransform>(newTransform)); } +#endif /*! \since 4.3 @@ -4638,6 +4643,7 @@ void QGraphicsItem::setTransform(const QTransform &matrix, bool combine) d_ptr->sendScenePosChange(); } +#if QT_DEPRECATED_SINCE(5, 13) /*! \obsolete @@ -4647,6 +4653,7 @@ void QGraphicsItem::resetMatrix() { resetTransform(); } +#endif /*! \since 4.3 diff --git a/src/widgets/graphicsview/qgraphicsitem.h b/src/widgets/graphicsview/qgraphicsitem.h index 729176530d..7dd4441ae9 100644 --- a/src/widgets/graphicsview/qgraphicsitem.h +++ b/src/widgets/graphicsview/qgraphicsitem.h @@ -283,10 +283,16 @@ public: inline void ensureVisible(qreal x, qreal y, qreal w, qreal h, int xmargin = 50, int ymargin = 50); // Local transformation +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X("Use transform() instead") QMatrix matrix() const; + QT_DEPRECATED_X("Use sceneTransform() instead") QMatrix sceneMatrix() const; + QT_DEPRECATED_X("Use setTransform() instead") void setMatrix(const QMatrix &matrix, bool combine = false); + QT_DEPRECATED_X("Use resetTransform() instead") void resetMatrix(); +#endif QTransform transform() const; QTransform sceneTransform() const; QTransform deviceTransform(const QTransform &viewportTransform) const; diff --git a/src/widgets/graphicsview/qgraphicsitemanimation.cpp b/src/widgets/graphicsview/qgraphicsitemanimation.cpp index 572ec141bc..78b91d5c39 100644 --- a/src/widgets/graphicsview/qgraphicsitemanimation.cpp +++ b/src/widgets/graphicsview/qgraphicsitemanimation.cpp @@ -549,6 +549,7 @@ void QGraphicsItemAnimation::setStep(qreal step) afterAnimationStep(step); } +#if QT_DEPRECATED_SINCE(5, 13) /*! Resets the item to its starting position and transformation. @@ -563,6 +564,7 @@ void QGraphicsItemAnimation::reset() d->startPos = d->item->pos(); d->startMatrix = d->item->matrix(); } +#endif /*! \fn void QGraphicsItemAnimation::beforeAnimationStep(qreal step) diff --git a/src/widgets/graphicsview/qgraphicsitemanimation.h b/src/widgets/graphicsview/qgraphicsitemanimation.h index 7417d7729c..f983bd8026 100644 --- a/src/widgets/graphicsview/qgraphicsitemanimation.h +++ b/src/widgets/graphicsview/qgraphicsitemanimation.h @@ -96,7 +96,10 @@ public: public Q_SLOTS: void setStep(qreal x); +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X("Use setStep(0) instead") void reset(); +#endif protected: virtual void beforeAnimationStep(qreal step); diff --git a/src/widgets/graphicsview/qgraphicsscene.cpp b/src/widgets/graphicsview/qgraphicsscene.cpp index db7ce5251a..a60c2872ae 100644 --- a/src/widgets/graphicsview/qgraphicsscene.cpp +++ b/src/widgets/graphicsview/qgraphicsscene.cpp @@ -1929,6 +1929,7 @@ void QGraphicsScene::setBspTreeDepth(int depth) bspTree->setBspTreeDepth(depth); } +#if QT_DEPRECATED_SINCE(5, 13) /*! \property QGraphicsScene::sortCacheEnabled \brief whether sort caching is enabled @@ -1949,6 +1950,7 @@ void QGraphicsScene::setSortCacheEnabled(bool enabled) return; d->sortCacheEnabled = enabled; } +#endif /*! Calculates and returns the bounding rect of all items on the scene. This diff --git a/src/widgets/graphicsview/qgraphicsscene.h b/src/widgets/graphicsview/qgraphicsscene.h index 287e551db7..71b8fc3013 100644 --- a/src/widgets/graphicsview/qgraphicsscene.h +++ b/src/widgets/graphicsview/qgraphicsscene.h @@ -141,8 +141,10 @@ public: ItemIndexMethod itemIndexMethod() const; void setItemIndexMethod(ItemIndexMethod method); - bool isSortCacheEnabled() const; - void setSortCacheEnabled(bool enabled); +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED bool isSortCacheEnabled() const; + QT_DEPRECATED void setSortCacheEnabled(bool enabled); +#endif int bspTreeDepth() const; void setBspTreeDepth(int depth); diff --git a/src/widgets/itemviews/qabstractitemdelegate.cpp b/src/widgets/itemviews/qabstractitemdelegate.cpp index 4bdc318566..448e775a71 100644 --- a/src/widgets/itemviews/qabstractitemdelegate.cpp +++ b/src/widgets/itemviews/qabstractitemdelegate.cpp @@ -345,6 +345,7 @@ bool QAbstractItemDelegate::editorEvent(QEvent *, return false; } +#if QT_DEPRECATED_SINCE(5, 13) /*! \obsolete @@ -364,6 +365,7 @@ QString QAbstractItemDelegate::elidedText(const QFontMetrics &fontMetrics, int w { return fontMetrics.elidedText(text, mode, width); } +#endif /*! \since 4.3 diff --git a/src/widgets/itemviews/qabstractitemdelegate.h b/src/widgets/itemviews/qabstractitemdelegate.h index 575728e806..5696e55691 100644 --- a/src/widgets/itemviews/qabstractitemdelegate.h +++ b/src/widgets/itemviews/qabstractitemdelegate.h @@ -103,8 +103,11 @@ public: const QStyleOptionViewItem &option, const QModelIndex &index); +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X("Use QFontMetrics::elidedText() instead") static QString elidedText(const QFontMetrics &fontMetrics, int width, Qt::TextElideMode mode, const QString &text); +#endif virtual bool helpEvent(QHelpEvent *event, QAbstractItemView *view, diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 7441161e13..63803767c8 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -2921,6 +2921,7 @@ void QAbstractItemView::editorDestroyed(QObject *editor) setState(NoState); } +#if QT_DEPRECATED_SINCE(5, 13) /*! \obsolete Sets the horizontal scroll bar's steps per item to \a steps. @@ -2978,6 +2979,7 @@ int QAbstractItemView::verticalStepsPerItem() const { return 1; } +#endif /*! Moves to and selects the item best matching the string \a search. diff --git a/src/widgets/itemviews/qabstractitemview.h b/src/widgets/itemviews/qabstractitemview.h index 981582c166..be8fa07c94 100644 --- a/src/widgets/itemviews/qabstractitemview.h +++ b/src/widgets/itemviews/qabstractitemview.h @@ -272,10 +272,12 @@ Q_SIGNALS: protected: QAbstractItemView(QAbstractItemViewPrivate &, QWidget *parent = nullptr); - void setHorizontalStepsPerItem(int steps); - int horizontalStepsPerItem() const; - void setVerticalStepsPerItem(int steps); - int verticalStepsPerItem() const; +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED void setHorizontalStepsPerItem(int steps); + QT_DEPRECATED int horizontalStepsPerItem() const; + QT_DEPRECATED void setVerticalStepsPerItem(int steps); + QT_DEPRECATED int verticalStepsPerItem() const; +#endif enum CursorAction { MoveUp, MoveDown, MoveLeft, MoveRight, MoveHome, MoveEnd, MovePageUp, MovePageDown, From a6aacdd5607437f13866aff7e0869a7c5f508f00 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen <allan.jensen@qt.io> Date: Thu, 31 Jan 2019 11:27:04 +0100 Subject: [PATCH 1036/1650] Fix convertARGBToARGB32PM_avx2 and convertARGBToRGBA64PM_avx2 The tails was off since f370410097f8cb8d8fdf6174b799497fe7fe0adf Fixes: QTBUG-73440 Change-Id: If86178c6cad3f87d9b5f0f89e90354d49cd386a4 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> --- src/gui/painting/qdrawhelper_avx2.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/painting/qdrawhelper_avx2.cpp b/src/gui/painting/qdrawhelper_avx2.cpp index 8c69e21569..4a3e24d6d5 100644 --- a/src/gui/painting/qdrawhelper_avx2.cpp +++ b/src/gui/painting/qdrawhelper_avx2.cpp @@ -1054,7 +1054,7 @@ static void convertARGBToARGB32PM_avx2(uint *buffer, const uint *src, qsizetype __m128i maskedAlphaMask = _mm256_castsi256_si128(alphaMask); __m128i mask = maskFromCount((count - i) * sizeof(*src)); maskedAlphaMask = _mm_and_si128(mask, maskedAlphaMask); - __m128i srcVector = _mm_maskload_epi32(reinterpret_cast<const int *>(src), mask); + __m128i srcVector = _mm_maskload_epi32(reinterpret_cast<const int *>(src + i), mask); if (!_mm_testz_si128(srcVector, maskedAlphaMask)) { // keep the two _mm_test[zc]_siXXX next to each other @@ -1166,7 +1166,7 @@ static void convertARGBToRGBA64PM_avx2(QRgba64 *buffer, const uint *src, qsizety __m128i maskedAlphaMask = _mm256_castsi256_si128(alphaMask); __m128i mask = maskFromCount((count - i) * sizeof(*src)); maskedAlphaMask = _mm_and_si128(mask, maskedAlphaMask); - __m128i srcVector = _mm_maskload_epi32(reinterpret_cast<const int *>(src), mask); + __m128i srcVector = _mm_maskload_epi32(reinterpret_cast<const int *>(src + i), mask); __m256i src; if (!_mm_testz_si128(srcVector, maskedAlphaMask)) { From e96641d881f2106151995c812fabb9d6c58beccb Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland <eirik.aavitsland@qt.io> Date: Mon, 14 Jan 2019 11:30:36 +0100 Subject: [PATCH 1037/1650] Fix xbm image format handler: properly reject invalid files The read_xbm_header() function is used to check for valid file header, containing valid width and height values. But in case of an invalid file, the check could depend on uninitialized variables. Change-Id: I9f933ed6e38d86109e5b5a8d55fe763ab928d749 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io> --- src/gui/image/qxbmhandler.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/image/qxbmhandler.cpp b/src/gui/image/qxbmhandler.cpp index 24d86e116d..7ba44049b4 100644 --- a/src/gui/image/qxbmhandler.cpp +++ b/src/gui/image/qxbmhandler.cpp @@ -97,6 +97,8 @@ static bool read_xbm_header(QIODevice *device, int& w, int& h) if (r1.indexIn(sbuf) == 0 && r2.indexIn(sbuf, r1.matchedLength()) == r1.matchedLength()) w = QByteArray(&buf[r1.matchedLength()]).trimmed().toInt(); + else + return false; // "#define .._height <num>" readBytes = device->readLine(buf, buflen); @@ -109,6 +111,8 @@ static bool read_xbm_header(QIODevice *device, int& w, int& h) if (r1.indexIn(sbuf) == 0 && r2.indexIn(sbuf, r1.matchedLength()) == r1.matchedLength()) h = QByteArray(&buf[r1.matchedLength()]).trimmed().toInt(); + else + return false; // format error if (w <= 0 || w > 32767 || h <= 0 || h > 32767) From 66c3a71e91edefdf5bc5c8efb009fb5f0f330cd1 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland <eirik.aavitsland@qt.io> Date: Thu, 17 Jan 2019 15:50:37 +0100 Subject: [PATCH 1038/1650] Painter path stroking: fix capping of beziers ending in tight turns For some overly tight beziers where the start or end point and the next control point are closer than the pen width, the stroker's shifting algorithm will produce a start/end tangent pointing in the opposite direction from what is expected, for one of the sides. This would break the square and round capping logic. Fix by detecting the situation in the capping function and reversing the tangent when necessary. Change-Id: I48f4f017403d7b289b0483dd2b3a7ff1bbd0cf2a Reviewed-by: Lars Knoll <lars.knoll@qt.io> --- src/gui/painting/qstroker.cpp | 27 +++++++++--------- .../lancelot/scripts/degeneratebeziers.qps | 28 ++++++++++++++++++- 2 files changed, 41 insertions(+), 14 deletions(-) diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp index 4776545be6..292952b7c0 100644 --- a/src/gui/painting/qstroker.cpp +++ b/src/gui/painting/qstroker.cpp @@ -455,12 +455,12 @@ void QStroker::joinPoints(qfixed focal_x, qfixed focal_y, const QLineF &nextLine return; } #endif + QLineF prevLine(qt_fixed_to_real(m_back2X), qt_fixed_to_real(m_back2Y), + qt_fixed_to_real(m_back1X), qt_fixed_to_real(m_back1Y)); + QPointF isect; + QLineF::IntersectType type = prevLine.intersect(nextLine, &isect); if (join == FlatJoin) { - QLineF prevLine(qt_fixed_to_real(m_back2X), qt_fixed_to_real(m_back2Y), - qt_fixed_to_real(m_back1X), qt_fixed_to_real(m_back1Y)); - QPointF isect; - QLineF::IntersectType type = prevLine.intersect(nextLine, &isect); QLineF shortCut(prevLine.p2(), nextLine.p1()); qreal angle = shortCut.angleTo(prevLine); if (type == QLineF::BoundedIntersection || (angle > 90 && !qFuzzyCompare(angle, (qreal)90))) { @@ -472,12 +472,6 @@ void QStroker::joinPoints(qfixed focal_x, qfixed focal_y, const QLineF &nextLine qt_real_to_fixed(nextLine.y1())); } else { - QLineF prevLine(qt_fixed_to_real(m_back2X), qt_fixed_to_real(m_back2Y), - qt_fixed_to_real(m_back1X), qt_fixed_to_real(m_back1Y)); - - QPointF isect; - QLineF::IntersectType type = prevLine.intersect(nextLine, &isect); - if (join == MiterJoin) { qreal appliedMiterLimit = qt_fixed_to_real(m_strokeWidth * m_miterLimit); @@ -512,7 +506,11 @@ void QStroker::joinPoints(qfixed focal_x, qfixed focal_y, const QLineF &nextLine qfixed offset = m_strokeWidth / 2; QLineF l1(prevLine); - l1.translate(l1.dx(), l1.dy()); + qreal dp = QPointF::dotProduct(QPointF(prevLine.dx(), prevLine.dy()), QPointF(nextLine.dx(), nextLine.dy())); + if (dp > 0) // same direction, means that prevLine is from a bezier that has been "reversed" by shifting + l1 = QLineF(prevLine.p2(), prevLine.p1()); + else + l1.translate(l1.dx(), l1.dy()); l1.setLength(qt_fixed_to_real(offset)); QLineF l2(nextLine.p2(), nextLine.p1()); l2.translate(l2.dx(), l2.dy()); @@ -570,7 +568,11 @@ void QStroker::joinPoints(qfixed focal_x, qfixed focal_y, const QLineF &nextLine // first control line QLineF l1 = prevLine; - l1.translate(l1.dx(), l1.dy()); + qreal dp = QPointF::dotProduct(QPointF(prevLine.dx(), prevLine.dy()), QPointF(nextLine.dx(), nextLine.dy())); + if (dp > 0) // same direction, means that prevLine is from a bezier that has been "reversed" by shifting + l1 = QLineF(prevLine.p2(), prevLine.p1()); + else + l1.translate(l1.dx(), l1.dy()); l1.setLength(QT_PATH_KAPPA * offset); // second control line, find through normal between prevLine and focal. @@ -705,7 +707,6 @@ template <class Iterator> bool qt_stroke_side(Iterator *it, QPointF(qt_fixed_to_real(e.x), qt_fixed_to_real(e.y)), QPointF(qt_fixed_to_real(cp2.x), qt_fixed_to_real(cp2.y)), QPointF(qt_fixed_to_real(ep.x), qt_fixed_to_real(ep.y))); - int count = bezier.shifted(offsetCurves, MAX_OFFSET, offset, diff --git a/tests/auto/other/lancelot/scripts/degeneratebeziers.qps b/tests/auto/other/lancelot/scripts/degeneratebeziers.qps index fb223d5b1f..6c069fd82f 100644 --- a/tests/auto/other/lancelot/scripts/degeneratebeziers.qps +++ b/tests/auto/other/lancelot/scripts/degeneratebeziers.qps @@ -7,4 +7,30 @@ path_cubicTo degenerate 3427.0918499999997948 3872.1318999999994048 4729.4590867 scale 0.05 0.05 translate -2500 -3000 setPen black 800 -drawPath degenerate \ No newline at end of file +drawPath degenerate + +resetMatrix +path_moveTo revbez 0 20 +path_cubicTo revbez 0 0 120 0 120 -20 + +path_moveTo revbez 0 80 +path_cubicTo revbez 0 100 120 100 120 120 + +translate 50 250 + +setPen blue 40 solidline flatcap +drawPath revbez +setPen red 0 +drawPath revbez + +translate 200 0 +setPen blue 40 solidline squarecap +drawPath revbez +setPen red 0 +drawPath revbez + +translate 200 0 +setPen blue 40 solidline roundcap +drawPath revbez +setPen red 0 +drawPath revbez From 01f090e9e45399f72b8bc73793797d44a69b2a2e Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland <eirik.aavitsland@qt.io> Date: Tue, 22 Jan 2019 13:26:02 +0100 Subject: [PATCH 1039/1650] Fix QColor::toCmyk() for rgb(0, 0, 0) We translate all pure gray colors into cmyk having c,m,y=0 and only the k value expressing the darkness. But a fix introduced to avoid division by 0 caused rgb(0, 0, 0) to be an exception to this; it ended up being translated as c,m,y,k=1 instead. Fix by catching the potential div-by-0 situation earlier and directly set the orthodox cmyk translation: c,m,y=0,k=1. Fixes: QTBUG-73171 Change-Id: I3774eaf9d96e096ac5c47c55d28881bea2bd1309 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io> --- src/gui/painting/qcolor.cpp | 37 +++++++++++-------- tests/auto/gui/painting/qcolor/tst_qcolor.cpp | 2 +- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index 318d55c4c3..1f1835d5da 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -2193,27 +2193,32 @@ QColor QColor::toCmyk() const Q_DECL_NOTHROW color.cspec = Cmyk; color.ct.acmyk.alpha = ct.argb.alpha; - // rgb -> cmy - const qreal r = ct.argb.red / qreal(USHRT_MAX); - const qreal g = ct.argb.green / qreal(USHRT_MAX); - const qreal b = ct.argb.blue / qreal(USHRT_MAX); - qreal c = qreal(1.0) - r; - qreal m = qreal(1.0) - g; - qreal y = qreal(1.0) - b; + if (!ct.argb.red && !ct.argb.green && !ct.argb.blue) { + // Avoid div-by-0 below + color.ct.acmyk.cyan = 0; + color.ct.acmyk.magenta = 0; + color.ct.acmyk.yellow = 0; + color.ct.acmyk.black = USHRT_MAX; + } else { + // rgb -> cmy + const qreal r = ct.argb.red / qreal(USHRT_MAX); + const qreal g = ct.argb.green / qreal(USHRT_MAX); + const qreal b = ct.argb.blue / qreal(USHRT_MAX); + qreal c = qreal(1.0) - r; + qreal m = qreal(1.0) - g; + qreal y = qreal(1.0) - b; - // cmy -> cmyk - const qreal k = qMin(c, qMin(m, y)); - - if (!qFuzzyIsNull(k - 1)) { + // cmy -> cmyk + const qreal k = qMin(c, qMin(m, y)); c = (c - k) / (qreal(1.0) - k); m = (m - k) / (qreal(1.0) - k); y = (y - k) / (qreal(1.0) - k); - } - color.ct.acmyk.cyan = qRound(c * USHRT_MAX); - color.ct.acmyk.magenta = qRound(m * USHRT_MAX); - color.ct.acmyk.yellow = qRound(y * USHRT_MAX); - color.ct.acmyk.black = qRound(k * USHRT_MAX); + color.ct.acmyk.cyan = qRound(c * USHRT_MAX); + color.ct.acmyk.magenta = qRound(m * USHRT_MAX); + color.ct.acmyk.yellow = qRound(y * USHRT_MAX); + color.ct.acmyk.black = qRound(k * USHRT_MAX); + } return color; } diff --git a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp index 72bad03a6a..17289e0b85 100644 --- a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp +++ b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp @@ -1291,7 +1291,7 @@ void tst_QColor::toCmyk_data() << QColor::fromHslF(180./360., 1., 0.5, 1.0); QTest::newRow("data1") - << QColor::fromCmyk(255, 255, 255, 255) + << QColor::fromCmyk(0, 0, 0, 255) << QColor::fromRgb(0, 0, 0) << QColor::fromRgb(0, 0, 0).toHsv() << QColor::fromRgb(0, 0, 0).toHsl(); From a2b8f891fa9a93229a8645d18617d6906aa88b88 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland <eirik.aavitsland@qt.io> Date: Mon, 21 Jan 2019 10:55:50 +0100 Subject: [PATCH 1040/1650] Doc: decrease confusion about HSV vs HSL in QColor The non-qualified hue() and saturation() etc. refers to those values in the HSV, not HSL, color model. Make this more explicit in the documentation to avoid confusion. Task-number: QTBUG-73129 Change-Id: Ief337672966ac72d0d0c3606d8d68acf01ffe7ee Reviewed-by: Venugopal Shivashankar <Venugopal.Shivashankar@qt.io> --- src/gui/painting/qcolor.cpp | 66 +++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index 1f1835d5da..e5bac84df9 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -541,7 +541,15 @@ static QStringList get_colornames() \section1 The HSL Color Model HSL is similar to HSV, however instead of the Value parameter, HSL - specifies a Lightness parameter. + specifies a Lightness parameter which maps somewhat differently to the + brightness of the color. + + Similarly, the HSL saturation value is not in general the same as the HSV + saturation value for the same color. hslSaturation() provides the color's + HSL saturation value, while saturation() and hsvSaturation() provides the + HSV saturation value. + + The hue value is defined to be the same in HSL and HSV. \section1 The CMYK Color Model @@ -1098,7 +1106,7 @@ void QColor::setHsv(int h, int s, int v, int a) These components can be retrieved individually using the hslHueF(), hslSaturationF(), lightnessF() and alphaF() functions. - \sa setHsl() + \sa getHsl(), setHslF(), {QColor#The HSL Color Model}{The HSL Color Model} */ void QColor::getHslF(qreal *h, qreal *s, qreal *l, qreal *a) const { @@ -1128,7 +1136,7 @@ void QColor::getHslF(qreal *h, qreal *s, qreal *l, qreal *a) const These components can be retrieved individually using the hslHue(), hslSaturation(), lightness() and alpha() functions. - \sa setHsl() + \sa getHslF(), setHsl(), {QColor#The HSL Color Model}{The HSL Color Model} */ void QColor::getHsl(int *h, int *s, int *l, int *a) const { @@ -1619,11 +1627,11 @@ void QColor::setBlueF(qreal blue) } /*! - Returns the hue color component of this color. + Returns the HSV hue color component of this color. The color is implicitly converted to HSV. - \sa hsvHue(), hueF(), getHsv(), {QColor#The HSV Color Model}{The HSV Color Model} + \sa hsvHue(), hslHue(), hueF(), getHsv(), {QColor#The HSV Color Model}{The HSV Color Model} */ int QColor::hue() const Q_DECL_NOTHROW @@ -1632,9 +1640,9 @@ int QColor::hue() const Q_DECL_NOTHROW } /*! - Returns the hue color component of this color. + Returns the HSV hue color component of this color. - \sa hueF(), getHsv(), {QColor#The HSV Color Model}{The HSV Color Model} + \sa hueF(), hslHue(), getHsv(), {QColor#The HSV Color Model}{The HSV Color Model} */ int QColor::hsvHue() const Q_DECL_NOTHROW { @@ -1644,11 +1652,11 @@ int QColor::hsvHue() const Q_DECL_NOTHROW } /*! - Returns the saturation color component of this color. + Returns the HSV saturation color component of this color. The color is implicitly converted to HSV. - \sa hsvSaturation(), saturationF(), getHsv(), {QColor#The HSV Color Model}{The HSV Color + \sa hsvSaturation(), hslSaturation(), saturationF(), getHsv(), {QColor#The HSV Color Model}{The HSV Color Model} */ @@ -1658,9 +1666,9 @@ int QColor::saturation() const Q_DECL_NOTHROW } /*! - Returns the saturation color component of this color. + Returns the HSV saturation color component of this color. - \sa saturationF(), getHsv(), {QColor#The HSV Color Model}{The HSV Color Model} + \sa saturationF(), hslSaturation(), getHsv(), {QColor#The HSV Color Model}{The HSV Color Model} */ int QColor::hsvSaturation() const Q_DECL_NOTHROW { @@ -1682,11 +1690,11 @@ int QColor::value() const Q_DECL_NOTHROW } /*! - Returns the hue color component of this color. + Returns the HSV hue color component of this color. The color is implicitly converted to HSV. - \sa hsvHueF(), hue(), getHsvF(), {QColor#The HSV Color Model}{The HSV Color Model} + \sa hsvHueF(), hslHueF(), hue(), getHsvF(), {QColor#The HSV Color Model}{The HSV Color Model} */ qreal QColor::hueF() const Q_DECL_NOTHROW { @@ -1696,7 +1704,7 @@ qreal QColor::hueF() const Q_DECL_NOTHROW /*! Returns the hue color component of this color. - \sa hue(), getHsvF(), {QColor#The HSV Color Model}{The HSV Color + \sa hue(), hslHueF(), getHsvF(), {QColor#The HSV Color Model}{The HSV Color Model} */ qreal QColor::hsvHueF() const Q_DECL_NOTHROW @@ -1707,11 +1715,11 @@ qreal QColor::hsvHueF() const Q_DECL_NOTHROW } /*! - Returns the saturation color component of this color. + Returns the HSV saturation color component of this color. The color is implicitly converted to HSV. - \sa hsvSaturationF(), saturation(), getHsvF(), {QColor#The HSV Color Model}{The HSV Color + \sa hsvSaturationF(), hslSaturationF(), saturation(), getHsvF(), {QColor#The HSV Color Model}{The HSV Color Model} */ qreal QColor::saturationF() const Q_DECL_NOTHROW @@ -1720,9 +1728,9 @@ qreal QColor::saturationF() const Q_DECL_NOTHROW } /*! - Returns the saturation color component of this color. + Returns the HSV saturation color component of this color. - \sa saturation(), getHsvF(), {QColor#The HSV Color Model}{The HSV Color Model} + \sa saturation(), hslSaturationF(), getHsvF(), {QColor#The HSV Color Model}{The HSV Color Model} */ qreal QColor::hsvSaturationF() const Q_DECL_NOTHROW { @@ -1746,9 +1754,9 @@ qreal QColor::valueF() const Q_DECL_NOTHROW /*! \since 4.6 - Returns the hue color component of this color. + Returns the HSL hue color component of this color. - \sa getHslF(), getHsl() + \sa hslHueF(), hsvHue(), getHsl(), {QColor#The HSL Color Model}{The HSL Color Model} */ int QColor::hslHue() const Q_DECL_NOTHROW { @@ -1760,9 +1768,9 @@ int QColor::hslHue() const Q_DECL_NOTHROW /*! \since 4.6 - Returns the saturation color component of this color. + Returns the HSL saturation color component of this color. - \sa saturationF(), getHsv(), {QColor#The HSV Color Model}{The HSV Color Model} + \sa hslSaturationF(), hsvSaturation(), getHsl(), {QColor#The HSL Color Model}{The HSL Color Model} */ int QColor::hslSaturation() const Q_DECL_NOTHROW { @@ -1788,9 +1796,9 @@ int QColor::lightness() const Q_DECL_NOTHROW /*! \since 4.6 - Returns the hue color component of this color. + Returns the HSL hue color component of this color. - \sa hue(), getHslF() + \sa hslHue(), hsvHueF(), getHslF() */ qreal QColor::hslHueF() const Q_DECL_NOTHROW { @@ -1802,9 +1810,9 @@ qreal QColor::hslHueF() const Q_DECL_NOTHROW /*! \since 4.6 - Returns the saturation color component of this color. + Returns the HSL saturation color component of this color. - \sa saturationF(), getHslF() + \sa hslSaturation(), hsvSaturationF(), getHslF(), {QColor#The HSL Color Model}{The HSL Color Model} */ qreal QColor::hslSaturationF() const Q_DECL_NOTHROW { @@ -2124,7 +2132,7 @@ QColor QColor::toHsv() const Q_DECL_NOTHROW /*! Creates and returns an HSL QColor based on this color. - \sa fromHsl(), convertTo(), isValid() + \sa fromHsl(), convertTo(), isValid(), {QColor#The HSL Color Model}{The HSL Color Model} */ QColor QColor::toHsl() const Q_DECL_NOTHROW { @@ -2436,7 +2444,7 @@ QColor QColor::fromHsvF(qreal h, qreal s, qreal v, qreal a) The value of \a s, \a l, and \a a must all be in the range 0-255; the value of \a h must be in the range 0-359. - \sa toHsl(), fromHslF(), isValid() + \sa toHsl(), fromHslF(), isValid(), {QColor#The HSL Color Model}{The HSL Color Model} */ QColor QColor::fromHsl(int h, int s, int l, int a) { @@ -2468,7 +2476,7 @@ QColor QColor::fromHsl(int h, int s, int l, int a) All the values must be in the range 0.0-1.0. - \sa toHsl(), fromHsl(), isValid() + \sa toHsl(), fromHsl(), isValid(), {QColor#The HSL Color Model}{The HSL Color Model} */ QColor QColor::fromHslF(qreal h, qreal s, qreal l, qreal a) { From c66ddd7aba11672336fcbda0b5ee61d568aa1c7a Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer <volker.hilsheimer@qt.io> Date: Thu, 8 Nov 2018 19:06:13 +0100 Subject: [PATCH 1041/1650] Include relevant example code in documentation of setUrlHandler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By only looking at the function prototype, it's tempting to assume that the handler needs to be registered with the usual SLOT macro. That is not the case. The code snippet is already included in the class description, but it doesn't hurt to repeat it here. Change-Id: If24fdca41a4bd976ebd1156c9e1106469388265c Fixes: QTBUG-50484 Reviewed-by: Paul Wicking <paul.wicking@qt.io> Reviewed-by: Topi Reiniö <topi.reinio@qt.io> --- src/gui/util/qdesktopservices.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/util/qdesktopservices.cpp b/src/gui/util/qdesktopservices.cpp index b6eac91478..8c7cf8682c 100644 --- a/src/gui/util/qdesktopservices.cpp +++ b/src/gui/util/qdesktopservices.cpp @@ -244,6 +244,8 @@ bool QDesktopServices::openUrl(const QUrl &url) The provided method must be implemented as a slot that only accepts a single QUrl argument. + \snippet code/src_gui_util_qdesktopservices.cpp 0 + To use this function for receiving data from other apps on iOS you also need to add the custom scheme to the \c CFBundleURLSchemes list in your Info.plist file: From 05bcfb901115eb92820478746cae359d4dc84fbf Mon Sep 17 00:00:00 2001 From: Joerg Bornemann <joerg.bornemann@qt.io> Date: Wed, 30 Jan 2019 17:18:04 +0100 Subject: [PATCH 1042/1650] Normalize some SIGNAL/SLOT signatures ...for a minor performance gain. Change-Id: I4bef867055e069926fdc24fa98a6f94b6a0630e2 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> --- src/network/access/qnetworkaccessmanager.cpp | 4 ++-- src/network/access/qnetworkreplyhttpimpl.cpp | 2 +- src/network/ssl/qsslsocket.cpp | 4 ++-- src/plugins/bearer/connman/qconnmanservice_linux.cpp | 2 +- src/plugins/bearer/linux_common/qofonoservice_linux.cpp | 2 +- .../platforminputcontexts/ibus/qibusplatforminputcontext.cpp | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 1f0d2f92e2..85e2c492e4 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -494,8 +494,8 @@ QNetworkAccessManager::QNetworkAccessManager(QObject *parent) // connect(&d->networkConfigurationManager, SIGNAL(onlineStateChanged(bool)), SLOT(_q_onlineStateChanged(bool))); - connect(&d->networkConfigurationManager, SIGNAL(configurationChanged(const QNetworkConfiguration &)), - SLOT(_q_configurationChanged(const QNetworkConfiguration &))); + connect(&d->networkConfigurationManager, SIGNAL(configurationChanged(QNetworkConfiguration)), + SLOT(_q_configurationChanged(QNetworkConfiguration))); #endif } diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index ef54c198ba..d4d3a21a7a 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -917,7 +917,7 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq // From http thread to user thread: QObject::connect(forwardUploadDevice, SIGNAL(wantData(qint64)), q, SLOT(wantUploadDataSlot(qint64))); - QObject::connect(forwardUploadDevice,SIGNAL(processedData(qint64, qint64)), + QObject::connect(forwardUploadDevice,SIGNAL(processedData(qint64,qint64)), q, SLOT(sentUploadDataSlot(qint64,qint64))); QObject::connect(forwardUploadDevice, SIGNAL(resetData(bool*)), q, SLOT(resetUploadDataSlot(bool*)), diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 4a9d054c0d..4f49a71e8a 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -2394,8 +2394,8 @@ void QSslSocketPrivate::createPlainSocket(QIODevice::OpenMode openMode) q->connect(plainSocket, SIGNAL(bytesWritten(qint64)), q, SLOT(_q_bytesWrittenSlot(qint64)), Qt::DirectConnection); - q->connect(plainSocket, SIGNAL(channelBytesWritten(int, qint64)), - q, SLOT(_q_channelBytesWrittenSlot(int, qint64)), + q->connect(plainSocket, SIGNAL(channelBytesWritten(int,qint64)), + q, SLOT(_q_channelBytesWrittenSlot(int,qint64)), Qt::DirectConnection); q->connect(plainSocket, SIGNAL(readChannelFinished()), q, SLOT(_q_readChannelFinishedSlot()), diff --git a/src/plugins/bearer/connman/qconnmanservice_linux.cpp b/src/plugins/bearer/connman/qconnmanservice_linux.cpp index 7c9db4640b..3659eb7740 100644 --- a/src/plugins/bearer/connman/qconnmanservice_linux.cpp +++ b/src/plugins/bearer/connman/qconnmanservice_linux.cpp @@ -171,7 +171,7 @@ void QConnmanManagerInterface::connectNotify(const QMetaMethod &signal) QLatin1String(CONNMAN_MANAGER_PATH), QLatin1String(CONNMAN_MANAGER_INTERFACE), QLatin1String("ServicesChanged"), - this,SLOT(onServicesChanged(ConnmanMapList, QList<QDBusObjectPath>)))) { + this,SLOT(onServicesChanged(ConnmanMapList,QList<QDBusObjectPath>)))) { qWarning("servicesChanged not connected"); } } diff --git a/src/plugins/bearer/linux_common/qofonoservice_linux.cpp b/src/plugins/bearer/linux_common/qofonoservice_linux.cpp index 897ee953c0..5d72731bc4 100644 --- a/src/plugins/bearer/linux_common/qofonoservice_linux.cpp +++ b/src/plugins/bearer/linux_common/qofonoservice_linux.cpp @@ -84,7 +84,7 @@ QOfonoManagerInterface::QOfonoManagerInterface( QObject *parent) QLatin1String(OFONO_MANAGER_PATH), QLatin1String(OFONO_MANAGER_INTERFACE), QLatin1String("ModemAdded"), - this,SLOT(modemAdded(QDBusObjectPath, QVariantMap))); + this,SLOT(modemAdded(QDBusObjectPath,QVariantMap))); QDBusConnection::systemBus().connect(QLatin1String(OFONO_SERVICE), QLatin1String(OFONO_MANAGER_PATH), QLatin1String(OFONO_MANAGER_INTERFACE), diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp index 3a54f33832..ca315840e2 100644 --- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp +++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp @@ -593,7 +593,7 @@ void QIBusPlatformInputContext::connectToContextSignals() if (d->context) { connect(d->context, SIGNAL(CommitText(QDBusVariant)), SLOT(commitText(QDBusVariant))); connect(d->context, SIGNAL(UpdatePreeditText(QDBusVariant,uint,bool)), this, SLOT(updatePreeditText(QDBusVariant,uint,bool))); - connect(d->context, SIGNAL(ForwardKeyEvent(uint, uint, uint)), this, SLOT(forwardKeyEvent(uint, uint, uint))); + connect(d->context, SIGNAL(ForwardKeyEvent(uint,uint,uint)), this, SLOT(forwardKeyEvent(uint,uint,uint))); connect(d->context, SIGNAL(DeleteSurroundingText(int,uint)), this, SLOT(deleteSurroundingText(int,uint))); connect(d->context, SIGNAL(RequireSurroundingText()), this, SLOT(surroundingTextRequired())); connect(d->context, SIGNAL(HidePreeditText()), this, SLOT(hidePreeditText())); From 8e6231f4ebd0957920b740fb0cc96af0ac66e6cf Mon Sep 17 00:00:00 2001 From: Joerg Bornemann <joerg.bornemann@qt.io> Date: Wed, 30 Jan 2019 16:16:58 +0100 Subject: [PATCH 1043/1650] Fix install targets for generated private headers Header files of modules that specify generated_privates are usually not yet available at qmake-time. Thus, the installation rule must not check for the file's existence. Change-Id: Ifc7ff95422912d255744c9006382ff181176ae77 Fixes: QTBUG-71340 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> --- mkspecs/features/qt_installs.prf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mkspecs/features/qt_installs.prf b/mkspecs/features/qt_installs.prf index 8f98987b99..1ebca17366 100644 --- a/mkspecs/features/qt_installs.prf +++ b/mkspecs/features/qt_installs.prf @@ -38,6 +38,8 @@ qt_install_headers { private_headers.files = $$SYNCQT.PRIVATE_HEADER_FILES $$SYNCQT.INJECTED_PRIVATE_HEADER_FILES private_headers.path = $$[QT_INSTALL_HEADERS]/$$MODULE_INCNAME/$$VERSION/$$MODULE_INCNAME/private + generated_privates: \ + private_headers.CONFIG += no_check_exist INSTALLS += private_headers qpa_headers.files = $$SYNCQT.QPA_HEADER_FILES From 54bcb9d42f5ceaafcca426dc2a5cc25d299d5a3d Mon Sep 17 00:00:00 2001 From: Kari Oikarinen <kari.oikarinen@qt.io> Date: Tue, 5 Feb 2019 15:26:17 +0200 Subject: [PATCH 1044/1650] Blacklist tst_QGraphicsItem::cursor on WinRT It is the flaky test causing most failures in qtbase at the moment. Task-number: QTBUG-73545 Change-Id: Id9c5db27ebd08a4cf3c119d2fada12fdf1a5d2a0 Reviewed-by: Ville Voutilainen <ville.voutilainen@qt.io> Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de> --- tests/auto/widgets/graphicsview/qgraphicsitem/BLACKLIST | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 tests/auto/widgets/graphicsview/qgraphicsitem/BLACKLIST diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/BLACKLIST b/tests/auto/widgets/graphicsview/qgraphicsitem/BLACKLIST new file mode 100644 index 0000000000..071ccaaff4 --- /dev/null +++ b/tests/auto/widgets/graphicsview/qgraphicsitem/BLACKLIST @@ -0,0 +1,3 @@ +[cursor] +# QTBUG-73545 +winrt From eb60877fe96d82d9d6e1a834857744799e6de4db Mon Sep 17 00:00:00 2001 From: Kari Oikarinen <kari.oikarinen@qt.io> Date: Wed, 30 Jan 2019 15:25:34 +0200 Subject: [PATCH 1045/1650] QWizard: Correctly calculate watermark size hint If we have have AA_EnableHighDpiScaling on and have loaded a @2x image, layout calculations can't use the real pixels of the QPixmap directly. Fixes: QTBUG-73401 Change-Id: I1891411a0e359e0148476f73b6cc3a128893a374 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> --- src/widgets/dialogs/qwizard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp index 3876cf16c6..21e1ff2778 100644 --- a/src/widgets/dialogs/qwizard.cpp +++ b/src/widgets/dialogs/qwizard.cpp @@ -456,7 +456,7 @@ public: QSize minimumSizeHint() const override { if (pixmap() && !pixmap()->isNull()) - return pixmap()->size(); + return pixmap()->size() / pixmap()->devicePixelRatio(); return QFrame::minimumSizeHint(); } From b319d141105044f612ada1efe62685b2c5dd4514 Mon Sep 17 00:00:00 2001 From: Boubacar DIENE <boubacar.diene@gmail.com> Date: Thu, 31 Jan 2019 00:12:16 +0100 Subject: [PATCH 1046/1650] Fix "error: too many arguments to function media_get_entity_by_name()" Since the official v4l-utils-1.12.0 release, media_get_entity_by_name() function expects only two arguments instead of three as in older versions thus breaking build of eglfs_kms_vsp2 backend. Cf. https://git.linuxtv.org/v4l-utils.git/tree/utils/media-ctl/mediactl.h#n253 Fixes it by creating an overloaded wrapper function that will choose the right version based on the signature of the media_get_entity_by_name function pointer argument. Fixes: QTBUG-73427 Change-Id: Idab52558b6f2f23137456c21e33ece1ef0e9aa4e Reviewed-by: Johan Helsing <johan.helsing@qt.io> --- .../eglfs_kms_vsp2/qlinuxmediadevice.cpp | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qlinuxmediadevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qlinuxmediadevice.cpp index 25b0c39050..f77430d7a0 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qlinuxmediadevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qlinuxmediadevice.cpp @@ -273,9 +273,30 @@ bool QLinuxMediaDevice::disableLink(struct media_link *link) return true; } -media_entity *QLinuxMediaDevice::getEntity(const QString &name) +// Between the v4l-utils 1.10 and 1.12 releases, media_get_entity_by_name changed signature, +// i.e. breaking source compatibility. Unfortunately the v4l-utils version is not exposed +// through anything we can use through a regular ifdef so here we do a hack and create two +// overloads for a function based on the signature of the function pointer argument. This +// means that by calling safeGetEntity with media_get_entity_by_name as an argument, the +// compiler will pick the correct version. +// +// v4l-utils v1.12 and later +static struct media_entity *safeGetEntity(struct media_entity *(get_entity_by_name_fn)(struct media_device *, const char *), + struct media_device *device, const QString &name) { - struct media_entity *entity = media_get_entity_by_name(m_mediaDevice, name.toStdString().c_str(), name.length()); + return get_entity_by_name_fn(device, name.toStdString().c_str()); +} +// v4l-utils v1.10 and earlier +static struct media_entity *safeGetEntity(struct media_entity *(get_entity_by_name_fn)(struct media_device *, const char *, size_t), + struct media_device *device, + const QString &name) +{ + return get_entity_by_name_fn(device, name.toStdString().c_str(), name.length()); +} + +struct media_entity *QLinuxMediaDevice::getEntity(const QString &name) +{ + struct media_entity *entity = safeGetEntity(media_get_entity_by_name, m_mediaDevice, name); if (!entity) qWarning() << "Failed to get media entity:" << name; From 37352b23a90e9b4550b5a5cef175f2a77598faa0 Mon Sep 17 00:00:00 2001 From: Thiago Macieira <thiago.macieira@intel.com> Date: Tue, 5 Feb 2019 13:55:14 -0800 Subject: [PATCH 1047/1650] x86: Disable AVX support on 64-bit MinGW GCC for 64-bit Windows has a bug that it fails to properly re-align the stack pointer for use with 256-bit memory addresses (AVX). Therefore, there's about a 50/50 chance that any function using AVX will have an improperly-aligned stack. In release mode, stack accesses should be rare, but in debug mode they happen frequently. Either way, this is a ticking time bomb, so we disable. Clang is not affected. 32-bit MinGW is not affected. 64-bit in other OSes with GCC are not affected. Fixes: QTBUG-73539 Change-Id: Id061f35c088044b69a15fffd1580967808f31671 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io> --- config.tests/x86_simd/main.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config.tests/x86_simd/main.cpp b/config.tests/x86_simd/main.cpp index 8120cb9d3f..4fac13973a 100644 --- a/config.tests/x86_simd/main.cpp +++ b/config.tests/x86_simd/main.cpp @@ -144,6 +144,9 @@ attribute_target("sha") void test_shani() #endif #if T(AVX) +# if defined(__WIN64__) && defined(__GNUC__) && !defined(__clang__) +# error "AVX support is broken in 64-bit MinGW - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49001" +# endif attribute_target("avx") void test_avx() { __m256d a = _mm256_setzero_pd(); From f6edb0ef721c5c3734c2c05352febf0f9003ef6a Mon Sep 17 00:00:00 2001 From: Alexander Volkov <a.volkov@rusbitech.ru> Date: Fri, 1 Feb 2019 15:34:49 +0300 Subject: [PATCH 1048/1650] Improve keyboard navigation in QListView when isWrapping is enabled Search the previous item or the next item in a model instead of searching them on visual layout. This way the cursor will not stop at the beginning or at the end of a row or a column. Fixes: QTBUG-14444 Change-Id: I0ef203a4dcd876e4c50559fb87e61585f07434d1 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> --- src/widgets/itemviews/qlistview.cpp | 34 ++++++++++++++++--- .../itemviews/qlistview/tst_qlistview.cpp | 25 +++++++++++--- 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index 1248e91c8c..6b5857f1ca 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -1100,19 +1100,45 @@ QModelIndex QListView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie Q_D(QListView); Q_UNUSED(modifiers); - QModelIndex current = currentIndex(); - if (!current.isValid()) { + auto findAvailableRowBackward = [d](int row) { + while (row >= 0 && d->isHiddenOrDisabled(row)) + --row; + return row; + }; + + auto findAvailableRowForward = [d](int row) { int rowCount = d->model->rowCount(d->root); if (!rowCount) - return QModelIndex(); - int row = 0; + return -1; while (row < rowCount && d->isHiddenOrDisabled(row)) ++row; if (row >= rowCount) + return -1; + return row; + }; + + QModelIndex current = currentIndex(); + if (!current.isValid()) { + int row = findAvailableRowForward(0); + if (row == -1) return QModelIndex(); return d->model->index(row, d->column, d->root); } + if ((d->flow == LeftToRight && cursorAction == MoveLeft) || + (d->flow == TopToBottom && (cursorAction == MoveUp || cursorAction == MovePrevious))) { + const int row = findAvailableRowBackward(current.row() - 1); + if (row == -1) + return current; + return d->model->index(row, d->column, d->root); + } else if ((d->flow == LeftToRight && cursorAction == MoveRight) || + (d->flow == TopToBottom && (cursorAction == MoveDown || cursorAction == MoveNext))) { + const int row = findAvailableRowForward(current.row() + 1); + if (row == -1) + return current; + return d->model->index(row, d->column, d->root); + } + const QRect initialRect = rectForIndex(current); QRect rect = initialRect; if (rect.isEmpty()) { diff --git a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp index 5227db64ec..9175c0bff4 100644 --- a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp +++ b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp @@ -380,8 +380,11 @@ void tst_QListView::cursorMove() << Qt::Key_Up << Qt::Key_Up << Qt::Key_Up << Qt::Key_Up << Qt::Key_Up << Qt::Key_Left << Qt::Key_Left << Qt::Key_Up << Qt::Key_Down; - int displayRow = rows / displayColumns - 1; - int displayColumn = displayColumns - (rows % displayColumns) - 1; + int lastRow = rows / displayColumns - 1; + int lastColumn = displayColumns - 1; + + int displayRow = lastRow; + int displayColumn = lastColumn - (rows % displayColumns); QApplication::instance()->processEvents(); for (int i = 0; i < keymoves.size(); ++i) { @@ -395,10 +398,24 @@ void tst_QListView::cursorMove() displayRow = qMin(rows / displayColumns - 1, displayRow + 1); break; case Qt::Key_Left: - displayColumn = qMax(0, displayColumn - 1); + if (displayColumn > 0) { + displayColumn--; + } else { + if (displayRow > 0) { + displayRow--; + displayColumn = lastColumn; + } + } break; case Qt::Key_Right: - displayColumn = qMin(displayColumns-1, displayColumn + 1); + if (displayColumn < lastColumn) { + displayColumn++; + } else { + if (displayRow < lastRow) { + displayRow++; + displayColumn = 0; + } + } break; default: QVERIFY(false); From 150c6fb74bb7bc702d1d319a1e9acba6b644944b Mon Sep 17 00:00:00 2001 From: Edward Welbourne <edward.welbourne@qt.io> Date: Mon, 14 Jan 2019 20:50:41 +0100 Subject: [PATCH 1049/1650] Add testlib selftests for double and for non-finite float and double Tidied up the existing float tests in the process. (In particular, s/SUCCESS/PASS/ since that matches real test output.) These verify that QCOMPARE() handles floats and doubles as intended. Extended the existing qFuzzyCompare tests to probe the boundaries of the ranges of values of both types, in the process. Revised the toString<double> that qCompare() uses to give enough precision to actually show some of the differences being tested there (12 digits, to match what qFuzzyCompare tests, so as to show different values rather than, e.g. 1e12 for both expected and actual) and to give consistent results for infinities and NaN (MinGW had eccentric versions for these, leading to different output from tests, which thus failed); did the latter also for toString<float> and fixed stray zeros in MinGW's exponents (which made a kludge in tst_selftest.cpp redundant, so I removed that, too). That's further complicated handling of floating-point types, so let's just keep an eye on how expensive that's getting by adding a benchmark test for QTest::toString(). Unfortunately, default settings only get runs that take modest numbers of milliseconds (some as low as 40) while increasing this with -minumumvalue 100 or more gets the process killed - and I'm unable to find out who's doing the killing (it's not QProcess::kill, ::kill or the QtTest WatchDog, as far as I can tell). So results are rather noisy; the integral tests exhibit speed-ups by factors up to 5, and slow-downs by factors up to 100, between runs with and without this change, which does not affec the integral tests. The relatively modest slow-downs and speed-ups in the floating point tests thus seem likely to be happenstance rather than signal. Change-Id: I4a6bbbab6a43bf14a4089e96238a7c8da2c3127e Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> --- src/testlib/qtestcase.cpp | 55 +- .../testlib/selftests/expected_float.lightxml | 403 ++++++++- .../auto/testlib/selftests/expected_float.tap | 778 +++++++++++++++++- .../testlib/selftests/expected_float.teamcity | 211 ++++- .../auto/testlib/selftests/expected_float.txt | 258 +++++- .../auto/testlib/selftests/expected_float.xml | 403 ++++++++- .../testlib/selftests/expected_float.xunitxml | 185 ++++- .../testlib/selftests/float/tst_float.cpp | 148 +++- .../auto/testlib/selftests/tst_selftests.cpp | 9 - tests/benchmarks/benchmarks.pro | 5 +- tests/benchmarks/testlib/testlib.pro | 3 + .../benchmarks/testlib/tostring/tostring.pro | 4 + .../testlib/tostring/tst_tostring.cpp | 103 +++ 13 files changed, 2480 insertions(+), 85 deletions(-) create mode 100644 tests/benchmarks/testlib/testlib.pro create mode 100644 tests/benchmarks/testlib/tostring/tostring.pro create mode 100644 tests/benchmarks/testlib/tostring/tst_tostring.cpp diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 2b0ad52b2d..22e8ac49bc 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -2525,7 +2525,7 @@ bool QTest::qCompare(double const &t1, double const &t2, const char *actual, con */ #define TO_STRING_IMPL(TYPE, FORMAT) \ -template <> Q_TESTLIB_EXPORT char *QTest::toString<TYPE >(const TYPE &t) \ +template <> Q_TESTLIB_EXPORT char *QTest::toString<TYPE>(const TYPE &t) \ { \ char *msg = new char[128]; \ qsnprintf(msg, 128, #FORMAT, t); \ @@ -2548,8 +2548,57 @@ TO_STRING_IMPL(quint64, %llu) TO_STRING_IMPL(bool, %d) TO_STRING_IMPL(signed char, %hhd) TO_STRING_IMPL(unsigned char, %hhu) -TO_STRING_IMPL(float, %g) -TO_STRING_IMPL(double, %lg) + +/*! + \internal + + Be consistent about leading 0 in exponent. + + POSIX specifies that %e (hence %g when using it) uses at least two digits in + the exponent, requiring a leading 0 on single-digit exponents; (at least) + MinGW includes a leading zero also on an already-two-digit exponent, + e.g. 9e-040, which differs from more usual platforms. So massage that away. + */ +static void massageExponent(char *text) +{ + char *p = strchr(text, 'e'); + if (!p) + return; + const char *const end = p + strlen(p); // *end is '\0' + p += (p[1] == '-' || p[1] == '+') ? 2 : 1; + if (p[0] != '0' || end - 2 <= p) + return; + // We have a leading 0 on an exponent of at least two more digits + const char *n = p + 1; + while (end - 2 > n && n[0] == '0') + ++n; + memmove(p, n, end + 1 - n); +} + +// Be consistent about display of infinities and NaNs (snprintf()'s varies, +// notably on MinGW, despite POSIX documenting "[-]inf" or "[-]infinity" for %f, +// %e and %g, uppercasing for their capital versions; similar for "nan"): +#define TO_STRING_FLOAT(TYPE, FORMAT) \ +template <> Q_TESTLIB_EXPORT char *QTest::toString<TYPE>(const TYPE &t) \ +{ \ + char *msg = new char[128]; \ + switch (std::fpclassify(t)) { \ + case FP_INFINITE: \ + qstrncpy(msg, (t < 0 ? "-inf" : "inf"), 128); \ + break; \ + case FP_NAN: \ + qstrncpy(msg, "nan", 128); \ + break; \ + default: \ + qsnprintf(msg, 128, #FORMAT, t); \ + massageExponent(msg); \ + break; \ + } \ + return msg; \ +} + +TO_STRING_FLOAT(float, %g) +TO_STRING_FLOAT(double, %.12lg) template <> Q_TESTLIB_EXPORT char *QTest::toString<char>(const char &t) { diff --git a/tests/auto/testlib/selftests/expected_float.lightxml b/tests/auto/testlib/selftests/expected_float.lightxml index 0dbc5dd8c8..79ce33627d 100644 --- a/tests/auto/testlib/selftests/expected_float.lightxml +++ b/tests/auto/testlib/selftests/expected_float.lightxml @@ -7,30 +7,423 @@ <Incident type="pass" file="" line="0" /> <Duration msecs="0"/> </TestFunction> -<TestFunction name="floatComparisons"> +<TestFunction name="doubleComparisons"> <Incident type="pass" file="" line="0"> - <DataTag><![CDATA[should SUCCEED 1]]></DataTag> + <DataTag><![CDATA[should PASS 1]]></DataTag> </Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL 1]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): 3]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL 2]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1e-07 + Expected (operandRight): 3e-07]]></Description> +</Incident> +<Incident type="pass" file="" line="0"> + <DataTag><![CDATA[should PASS 2]]></DataTag> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL 3]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 999999999999 + Expected (operandRight): 999999999998]]></Description> +</Incident> +<Incident type="pass" file="" line="0"> + <DataTag><![CDATA[should PASS 3]]></DataTag> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL 4]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 9.99999999999e-311 + Expected (operandRight): 9.99999999997e-311]]></Description> +</Incident> +<Incident type="pass" file="" line="0"> + <DataTag><![CDATA[should PASS 4]]></DataTag> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL 5]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 9.99999999999e+306 + Expected (operandRight): 9.99999999997e+306]]></Description> +</Incident> +<Incident type="pass" file="" line="0"> + <DataTag><![CDATA[should PASS: NaN == NaN]]></DataTag> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: NaN != 0]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): 0]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: 0 != NaN]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 0 + Expected (operandRight): nan]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: NaN != 1]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): 1]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: 1 != NaN]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): nan]]></Description> +</Incident> +<Incident type="pass" file="" line="0"> + <DataTag><![CDATA[should PASS: inf == inf]]></DataTag> +</Incident> +<Incident type="pass" file="" line="0"> + <DataTag><![CDATA[should PASS: -inf == -inf]]></DataTag> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: inf != -inf]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): -inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -inf != inf]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: inf != nan]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): nan]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: nan != inf]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -inf != nan]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): nan]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: nan != -inf]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): -inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: inf != 0]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): 0]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: 0 != inf]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 0 + Expected (operandRight): inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -inf != 0]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): 0]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: 0 != -inf]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 0 + Expected (operandRight): -inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: inf != 1]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): 1]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: 1 != inf]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -inf != 1]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): 1]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: 1 != -inf]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): -inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: inf != max]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): 1.79769313486e+308]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: inf != -max]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): -1.79769313486e+308]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: max != inf]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1.79769313486e+308 + Expected (operandRight): inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -max != inf]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -1.79769313486e+308 + Expected (operandRight): inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -inf != max]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): 1.79769313486e+308]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -inf != -max]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): -1.79769313486e+308]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: max != -inf]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1.79769313486e+308 + Expected (operandRight): -inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -max != -inf]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -1.79769313486e+308 + Expected (operandRight): -inf]]></Description> +</Incident> + <Duration msecs="0"/> +</TestFunction> +<TestFunction name="floatComparisons"> <Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> <DataTag><![CDATA[should FAIL 1]]></DataTag> <Description><![CDATA[Compared floats are not the same (fuzzy compare) Actual (operandLeft) : 1 Expected (operandRight): 3]]></Description> </Incident> +<Incident type="pass" file="" line="0"> + <DataTag><![CDATA[should PASS 1]]></DataTag> +</Incident> <Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> <DataTag><![CDATA[should FAIL 2]]></DataTag> <Description><![CDATA[Compared floats are not the same (fuzzy compare) Actual (operandLeft) : 1e-07 Expected (operandRight): 3e-07]]></Description> </Incident> +<Incident type="pass" file="" line="0"> + <DataTag><![CDATA[should PASS 2]]></DataTag> +</Incident> <Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> <DataTag><![CDATA[should FAIL 3]]></DataTag> <Description><![CDATA[Compared floats are not the same (fuzzy compare) - Actual (operandLeft) : 99998 - Expected (operandRight): 99999]]></Description> + Actual (operandLeft) : 99999 + Expected (operandRight): 99998]]></Description> </Incident> <Incident type="pass" file="" line="0"> - <DataTag><![CDATA[should SUCCEED 2]]></DataTag> + <DataTag><![CDATA[should PASS 3]]></DataTag> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL 4]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 9.9999e-40 + Expected (operandRight): 9.99971e-40]]></Description> +</Incident> +<Incident type="pass" file="" line="0"> + <DataTag><![CDATA[should PASS 4]]></DataTag> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL 5]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 9.9999e+37 + Expected (operandRight): 9.9997e+37]]></Description> +</Incident> +<Incident type="pass" file="" line="0"> + <DataTag><![CDATA[should PASS: NaN == NaN]]></DataTag> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: NaN != 0]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): 0]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: 0 != NaN]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 0 + Expected (operandRight): nan]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: NaN != 1]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): 1]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: 1 != NaN]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): nan]]></Description> +</Incident> +<Incident type="pass" file="" line="0"> + <DataTag><![CDATA[should PASS: inf == inf]]></DataTag> +</Incident> +<Incident type="pass" file="" line="0"> + <DataTag><![CDATA[should PASS: -inf == -inf]]></DataTag> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: inf != -inf]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): -inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -inf != inf]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: inf != nan]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): nan]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: nan != inf]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -inf != nan]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): nan]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: nan != -inf]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): -inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: inf != 0]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): 0]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: 0 != inf]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 0 + Expected (operandRight): inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -inf != 0]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): 0]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: 0 != -inf]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 0 + Expected (operandRight): -inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: inf != 1]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): 1]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: 1 != inf]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -inf != 1]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): 1]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: 1 != -inf]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): -inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: inf != max]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): 3.40282e+38]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: inf != -max]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): -3.40282e+38]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: max != inf]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 3.40282e+38 + Expected (operandRight): inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -max != inf]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -3.40282e+38 + Expected (operandRight): inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -inf != max]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): 3.40282e+38]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -inf != -max]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): -3.40282e+38]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: max != -inf]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 3.40282e+38 + Expected (operandRight): -inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -max != -inf]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -3.40282e+38 + Expected (operandRight): -inf]]></Description> </Incident> <Duration msecs="0"/> </TestFunction> diff --git a/tests/auto/testlib/selftests/expected_float.tap b/tests/auto/testlib/selftests/expected_float.tap index fae2dc9796..1896bb2fb3 100644 --- a/tests/auto/testlib/selftests/expected_float.tap +++ b/tests/auto/testlib/selftests/expected_float.tap @@ -1,8 +1,386 @@ TAP version 13 # tst_float ok 1 - initTestCase() -ok 2 - floatComparisons(should SUCCEED 1) -not ok 3 - floatComparisons(should FAIL 1) +ok 2 - doubleComparisons(should PASS 1) +not ok 3 - doubleComparisons(should FAIL 1) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: 3 (operandRight) + found: 1 (operandLeft) + expected: 3 (operandRight) + actual: 1 (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +not ok 4 - doubleComparisons(should FAIL 2) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: 3e-07 (operandRight) + found: 1e-07 (operandLeft) + expected: 3e-07 (operandRight) + actual: 1e-07 (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +ok 5 - doubleComparisons(should PASS 2) +not ok 6 - doubleComparisons(should FAIL 3) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: 999999999998 (operandRight) + found: 999999999999 (operandLeft) + expected: 999999999998 (operandRight) + actual: 999999999999 (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +ok 7 - doubleComparisons(should PASS 3) +not ok 8 - doubleComparisons(should FAIL 4) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: 9.99999999997e-311 (operandRight) + found: 9.99999999999e-311 (operandLeft) + expected: 9.99999999997e-311 (operandRight) + actual: 9.99999999999e-311 (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +ok 9 - doubleComparisons(should PASS 4) +not ok 10 - doubleComparisons(should FAIL 5) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: 9.99999999997e+306 (operandRight) + found: 9.99999999999e+306 (operandLeft) + expected: 9.99999999997e+306 (operandRight) + actual: 9.99999999999e+306 (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +ok 11 - doubleComparisons(should PASS: NaN == NaN) +not ok 12 - doubleComparisons(should FAIL: NaN != 0) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: 0 (operandRight) + found: nan (operandLeft) + expected: 0 (operandRight) + actual: nan (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +not ok 13 - doubleComparisons(should FAIL: 0 != NaN) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: nan (operandRight) + found: 0 (operandLeft) + expected: nan (operandRight) + actual: 0 (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +not ok 14 - doubleComparisons(should FAIL: NaN != 1) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: 1 (operandRight) + found: nan (operandLeft) + expected: 1 (operandRight) + actual: nan (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +not ok 15 - doubleComparisons(should FAIL: 1 != NaN) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: nan (operandRight) + found: 1 (operandLeft) + expected: nan (operandRight) + actual: 1 (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +ok 16 - doubleComparisons(should PASS: inf == inf) +ok 17 - doubleComparisons(should PASS: -inf == -inf) +not ok 18 - doubleComparisons(should FAIL: inf != -inf) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: -inf (operandRight) + found: inf (operandLeft) + expected: -inf (operandRight) + actual: inf (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +not ok 19 - doubleComparisons(should FAIL: -inf != inf) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: inf (operandRight) + found: -inf (operandLeft) + expected: inf (operandRight) + actual: -inf (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +not ok 20 - doubleComparisons(should FAIL: inf != nan) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: nan (operandRight) + found: inf (operandLeft) + expected: nan (operandRight) + actual: inf (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +not ok 21 - doubleComparisons(should FAIL: nan != inf) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: inf (operandRight) + found: nan (operandLeft) + expected: inf (operandRight) + actual: nan (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +not ok 22 - doubleComparisons(should FAIL: -inf != nan) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: nan (operandRight) + found: -inf (operandLeft) + expected: nan (operandRight) + actual: -inf (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +not ok 23 - doubleComparisons(should FAIL: nan != -inf) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: -inf (operandRight) + found: nan (operandLeft) + expected: -inf (operandRight) + actual: nan (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +not ok 24 - doubleComparisons(should FAIL: inf != 0) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: 0 (operandRight) + found: inf (operandLeft) + expected: 0 (operandRight) + actual: inf (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +not ok 25 - doubleComparisons(should FAIL: 0 != inf) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: inf (operandRight) + found: 0 (operandLeft) + expected: inf (operandRight) + actual: 0 (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +not ok 26 - doubleComparisons(should FAIL: -inf != 0) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: 0 (operandRight) + found: -inf (operandLeft) + expected: 0 (operandRight) + actual: -inf (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +not ok 27 - doubleComparisons(should FAIL: 0 != -inf) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: -inf (operandRight) + found: 0 (operandLeft) + expected: -inf (operandRight) + actual: 0 (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +not ok 28 - doubleComparisons(should FAIL: inf != 1) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: 1 (operandRight) + found: inf (operandLeft) + expected: 1 (operandRight) + actual: inf (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +not ok 29 - doubleComparisons(should FAIL: 1 != inf) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: inf (operandRight) + found: 1 (operandLeft) + expected: inf (operandRight) + actual: 1 (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +not ok 30 - doubleComparisons(should FAIL: -inf != 1) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: 1 (operandRight) + found: -inf (operandLeft) + expected: 1 (operandRight) + actual: -inf (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +not ok 31 - doubleComparisons(should FAIL: 1 != -inf) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: -inf (operandRight) + found: 1 (operandLeft) + expected: -inf (operandRight) + actual: 1 (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +not ok 32 - doubleComparisons(should FAIL: inf != max) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: 1.79769313486e+308 (operandRight) + found: inf (operandLeft) + expected: 1.79769313486e+308 (operandRight) + actual: inf (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +not ok 33 - doubleComparisons(should FAIL: inf != -max) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: -1.79769313486e+308 (operandRight) + found: inf (operandLeft) + expected: -1.79769313486e+308 (operandRight) + actual: inf (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +not ok 34 - doubleComparisons(should FAIL: max != inf) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: inf (operandRight) + found: 1.79769313486e+308 (operandLeft) + expected: inf (operandRight) + actual: 1.79769313486e+308 (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +not ok 35 - doubleComparisons(should FAIL: -max != inf) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: inf (operandRight) + found: -1.79769313486e+308 (operandLeft) + expected: inf (operandRight) + actual: -1.79769313486e+308 (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +not ok 36 - doubleComparisons(should FAIL: -inf != max) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: 1.79769313486e+308 (operandRight) + found: -inf (operandLeft) + expected: 1.79769313486e+308 (operandRight) + actual: -inf (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +not ok 37 - doubleComparisons(should FAIL: -inf != -max) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: -1.79769313486e+308 (operandRight) + found: -inf (operandLeft) + expected: -1.79769313486e+308 (operandRight) + actual: -inf (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +not ok 38 - doubleComparisons(should FAIL: max != -inf) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: -inf (operandRight) + found: 1.79769313486e+308 (operandLeft) + expected: -inf (operandRight) + actual: 1.79769313486e+308 (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +not ok 39 - doubleComparisons(should FAIL: -max != -inf) + --- + type: QCOMPARE + message: Compared doubles are not the same (fuzzy compare) + wanted: -inf (operandRight) + found: -1.79769313486e+308 (operandLeft) + expected: -inf (operandRight) + actual: -1.79769313486e+308 (operandLeft) + at: tst_float::doubleComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:51) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 51 + ... +not ok 40 - floatComparisons(should FAIL 1) --- type: QCOMPARE message: Compared floats are not the same (fuzzy compare) @@ -10,11 +388,12 @@ not ok 3 - floatComparisons(should FAIL 1) found: 1 (operandLeft) expected: 3 (operandRight) actual: 1 (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:48) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 48 + line: 124 ... -not ok 4 - floatComparisons(should FAIL 2) +ok 41 - floatComparisons(should PASS 1) +not ok 42 - floatComparisons(should FAIL 2) --- type: QCOMPARE message: Compared floats are not the same (fuzzy compare) @@ -22,24 +401,365 @@ not ok 4 - floatComparisons(should FAIL 2) found: 1e-07 (operandLeft) expected: 3e-07 (operandRight) actual: 1e-07 (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:48) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 48 + line: 124 ... -not ok 5 - floatComparisons(should FAIL 3) +ok 43 - floatComparisons(should PASS 2) +not ok 44 - floatComparisons(should FAIL 3) --- type: QCOMPARE message: Compared floats are not the same (fuzzy compare) - wanted: 99999 (operandRight) - found: 99998 (operandLeft) - expected: 99999 (operandRight) - actual: 99998 (operandLeft) - at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:48) + wanted: 99998 (operandRight) + found: 99999 (operandLeft) + expected: 99998 (operandRight) + actual: 99999 (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 48 + line: 124 ... -ok 6 - floatComparisons(should SUCCEED 2) -not ok 7 - compareFloatTests(1e0) +ok 45 - floatComparisons(should PASS 3) +not ok 46 - floatComparisons(should FAIL 4) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: 9.99971e-40 (operandRight) + found: 9.9999e-40 (operandLeft) + expected: 9.99971e-40 (operandRight) + actual: 9.9999e-40 (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +ok 47 - floatComparisons(should PASS 4) +not ok 48 - floatComparisons(should FAIL 5) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: 9.9997e+37 (operandRight) + found: 9.9999e+37 (operandLeft) + expected: 9.9997e+37 (operandRight) + actual: 9.9999e+37 (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +ok 49 - floatComparisons(should PASS: NaN == NaN) +not ok 50 - floatComparisons(should FAIL: NaN != 0) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: 0 (operandRight) + found: nan (operandLeft) + expected: 0 (operandRight) + actual: nan (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +not ok 51 - floatComparisons(should FAIL: 0 != NaN) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: nan (operandRight) + found: 0 (operandLeft) + expected: nan (operandRight) + actual: 0 (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +not ok 52 - floatComparisons(should FAIL: NaN != 1) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: 1 (operandRight) + found: nan (operandLeft) + expected: 1 (operandRight) + actual: nan (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +not ok 53 - floatComparisons(should FAIL: 1 != NaN) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: nan (operandRight) + found: 1 (operandLeft) + expected: nan (operandRight) + actual: 1 (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +ok 54 - floatComparisons(should PASS: inf == inf) +ok 55 - floatComparisons(should PASS: -inf == -inf) +not ok 56 - floatComparisons(should FAIL: inf != -inf) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: -inf (operandRight) + found: inf (operandLeft) + expected: -inf (operandRight) + actual: inf (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +not ok 57 - floatComparisons(should FAIL: -inf != inf) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: inf (operandRight) + found: -inf (operandLeft) + expected: inf (operandRight) + actual: -inf (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +not ok 58 - floatComparisons(should FAIL: inf != nan) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: nan (operandRight) + found: inf (operandLeft) + expected: nan (operandRight) + actual: inf (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +not ok 59 - floatComparisons(should FAIL: nan != inf) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: inf (operandRight) + found: nan (operandLeft) + expected: inf (operandRight) + actual: nan (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +not ok 60 - floatComparisons(should FAIL: -inf != nan) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: nan (operandRight) + found: -inf (operandLeft) + expected: nan (operandRight) + actual: -inf (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +not ok 61 - floatComparisons(should FAIL: nan != -inf) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: -inf (operandRight) + found: nan (operandLeft) + expected: -inf (operandRight) + actual: nan (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +not ok 62 - floatComparisons(should FAIL: inf != 0) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: 0 (operandRight) + found: inf (operandLeft) + expected: 0 (operandRight) + actual: inf (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +not ok 63 - floatComparisons(should FAIL: 0 != inf) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: inf (operandRight) + found: 0 (operandLeft) + expected: inf (operandRight) + actual: 0 (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +not ok 64 - floatComparisons(should FAIL: -inf != 0) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: 0 (operandRight) + found: -inf (operandLeft) + expected: 0 (operandRight) + actual: -inf (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +not ok 65 - floatComparisons(should FAIL: 0 != -inf) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: -inf (operandRight) + found: 0 (operandLeft) + expected: -inf (operandRight) + actual: 0 (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +not ok 66 - floatComparisons(should FAIL: inf != 1) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: 1 (operandRight) + found: inf (operandLeft) + expected: 1 (operandRight) + actual: inf (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +not ok 67 - floatComparisons(should FAIL: 1 != inf) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: inf (operandRight) + found: 1 (operandLeft) + expected: inf (operandRight) + actual: 1 (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +not ok 68 - floatComparisons(should FAIL: -inf != 1) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: 1 (operandRight) + found: -inf (operandLeft) + expected: 1 (operandRight) + actual: -inf (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +not ok 69 - floatComparisons(should FAIL: 1 != -inf) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: -inf (operandRight) + found: 1 (operandLeft) + expected: -inf (operandRight) + actual: 1 (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +not ok 70 - floatComparisons(should FAIL: inf != max) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: 3.40282e+38 (operandRight) + found: inf (operandLeft) + expected: 3.40282e+38 (operandRight) + actual: inf (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +not ok 71 - floatComparisons(should FAIL: inf != -max) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: -3.40282e+38 (operandRight) + found: inf (operandLeft) + expected: -3.40282e+38 (operandRight) + actual: inf (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +not ok 72 - floatComparisons(should FAIL: max != inf) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: inf (operandRight) + found: 3.40282e+38 (operandLeft) + expected: inf (operandRight) + actual: 3.40282e+38 (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +not ok 73 - floatComparisons(should FAIL: -max != inf) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: inf (operandRight) + found: -3.40282e+38 (operandLeft) + expected: inf (operandRight) + actual: -3.40282e+38 (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +not ok 74 - floatComparisons(should FAIL: -inf != max) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: 3.40282e+38 (operandRight) + found: -inf (operandLeft) + expected: 3.40282e+38 (operandRight) + actual: -inf (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +not ok 75 - floatComparisons(should FAIL: -inf != -max) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: -3.40282e+38 (operandRight) + found: -inf (operandLeft) + expected: -3.40282e+38 (operandRight) + actual: -inf (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +not ok 76 - floatComparisons(should FAIL: max != -inf) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: -inf (operandRight) + found: 3.40282e+38 (operandLeft) + expected: -inf (operandRight) + actual: 3.40282e+38 (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +not ok 77 - floatComparisons(should FAIL: -max != -inf) + --- + type: QCOMPARE + message: Compared floats are not the same (fuzzy compare) + wanted: -inf (operandRight) + found: -3.40282e+38 (operandLeft) + expected: -inf (operandRight) + actual: -3.40282e+38 (operandLeft) + at: tst_float::floatComparisons() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:124) + file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp + line: 124 + ... +not ok 78 - compareFloatTests(1e0) --- type: QCOMPARE message: Compared floats are not the same (fuzzy compare) @@ -47,11 +767,11 @@ not ok 7 - compareFloatTests(1e0) found: 1 (t1) expected: 3 (t3) actual: 1 (t1) - at: tst_float::compareFloatTests() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:96) + at: tst_float::compareFloatTests() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:206) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 96 + line: 206 ... -not ok 8 - compareFloatTests(1e-7) +not ok 79 - compareFloatTests(1e-7) --- type: QCOMPARE message: Compared floats are not the same (fuzzy compare) @@ -59,11 +779,11 @@ not ok 8 - compareFloatTests(1e-7) found: 1e-07 (t1) expected: 3e-07 (t3) actual: 1e-07 (t1) - at: tst_float::compareFloatTests() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:96) + at: tst_float::compareFloatTests() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:206) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 96 + line: 206 ... -not ok 9 - compareFloatTests(1e+7) +not ok 80 - compareFloatTests(1e+7) --- type: QCOMPARE message: Compared floats are not the same (fuzzy compare) @@ -71,12 +791,12 @@ not ok 9 - compareFloatTests(1e+7) found: 1e+07 (t1) expected: 3e+07 (t3) actual: 1e+07 (t1) - at: tst_float::compareFloatTests() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:96) + at: tst_float::compareFloatTests() (qtbase/tests/auto/testlib/selftests/float/tst_float.cpp:206) file: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp - line: 96 + line: 206 ... -ok 10 - cleanupTestCase() -1..10 -# tests 10 -# pass 4 -# fail 6 +ok 81 - cleanupTestCase() +1..81 +# tests 81 +# pass 16 +# fail 65 diff --git a/tests/auto/testlib/selftests/expected_float.teamcity b/tests/auto/testlib/selftests/expected_float.teamcity index d5b81593d8..9166f644af 100644 --- a/tests/auto/testlib/selftests/expected_float.teamcity +++ b/tests/auto/testlib/selftests/expected_float.teamcity @@ -1,19 +1,220 @@ ##teamcity[testSuiteStarted name='tst_float' flowId='tst_float'] ##teamcity[testStarted name='initTestCase()' flowId='tst_float'] ##teamcity[testFinished name='initTestCase()' flowId='tst_float'] -##teamcity[testStarted name='floatComparisons(should SUCCEED 1)' flowId='tst_float'] -##teamcity[testFinished name='floatComparisons(should SUCCEED 1)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should PASS 1)' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should PASS 1)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL 1)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL 1)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : 1|n Expected (operandRight): 3' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL 1)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL 2)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL 2)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : 1e-07|n Expected (operandRight): 3e-07' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL 2)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should PASS 2)' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should PASS 2)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL 3)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL 3)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : 999999999999|n Expected (operandRight): 999999999998' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL 3)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should PASS 3)' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should PASS 3)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL 4)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL 4)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : 9.99999999999e-311|n Expected (operandRight): 9.99999999997e-311' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL 4)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should PASS 4)' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should PASS 4)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL 5)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL 5)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : 9.99999999999e+306|n Expected (operandRight): 9.99999999997e+306' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL 5)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should PASS: NaN == NaN)' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should PASS: NaN == NaN)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL: NaN != 0)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL: NaN != 0)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : nan|n Expected (operandRight): 0' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL: NaN != 0)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL: 0 != NaN)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL: 0 != NaN)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : 0|n Expected (operandRight): nan' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL: 0 != NaN)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL: NaN != 1)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL: NaN != 1)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : nan|n Expected (operandRight): 1' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL: NaN != 1)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL: 1 != NaN)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL: 1 != NaN)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : 1|n Expected (operandRight): nan' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL: 1 != NaN)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should PASS: inf == inf)' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should PASS: inf == inf)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should PASS: -inf == -inf)' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should PASS: -inf == -inf)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL: inf != -inf)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL: inf != -inf)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : inf|n Expected (operandRight): -inf' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL: inf != -inf)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL: -inf != inf)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL: -inf != inf)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : -inf|n Expected (operandRight): inf' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL: -inf != inf)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL: inf != nan)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL: inf != nan)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : inf|n Expected (operandRight): nan' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL: inf != nan)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL: nan != inf)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL: nan != inf)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : nan|n Expected (operandRight): inf' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL: nan != inf)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL: -inf != nan)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL: -inf != nan)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : -inf|n Expected (operandRight): nan' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL: -inf != nan)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL: nan != -inf)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL: nan != -inf)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : nan|n Expected (operandRight): -inf' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL: nan != -inf)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL: inf != 0)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL: inf != 0)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : inf|n Expected (operandRight): 0' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL: inf != 0)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL: 0 != inf)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL: 0 != inf)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : 0|n Expected (operandRight): inf' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL: 0 != inf)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL: -inf != 0)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL: -inf != 0)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : -inf|n Expected (operandRight): 0' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL: -inf != 0)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL: 0 != -inf)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL: 0 != -inf)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : 0|n Expected (operandRight): -inf' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL: 0 != -inf)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL: inf != 1)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL: inf != 1)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : inf|n Expected (operandRight): 1' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL: inf != 1)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL: 1 != inf)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL: 1 != inf)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : 1|n Expected (operandRight): inf' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL: 1 != inf)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL: -inf != 1)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL: -inf != 1)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : -inf|n Expected (operandRight): 1' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL: -inf != 1)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL: 1 != -inf)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL: 1 != -inf)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : 1|n Expected (operandRight): -inf' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL: 1 != -inf)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL: inf != max)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL: inf != max)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : inf|n Expected (operandRight): 1.79769313486e+308' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL: inf != max)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL: inf != -max)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL: inf != -max)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : inf|n Expected (operandRight): -1.79769313486e+308' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL: inf != -max)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL: max != inf)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL: max != inf)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : 1.79769313486e+308|n Expected (operandRight): inf' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL: max != inf)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL: -max != inf)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL: -max != inf)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : -1.79769313486e+308|n Expected (operandRight): inf' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL: -max != inf)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL: -inf != max)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL: -inf != max)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : -inf|n Expected (operandRight): 1.79769313486e+308' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL: -inf != max)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL: -inf != -max)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL: -inf != -max)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : -inf|n Expected (operandRight): -1.79769313486e+308' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL: -inf != -max)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL: max != -inf)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL: max != -inf)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : 1.79769313486e+308|n Expected (operandRight): -inf' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL: max != -inf)' flowId='tst_float'] +##teamcity[testStarted name='doubleComparisons(should FAIL: -max != -inf)' flowId='tst_float'] +##teamcity[testFailed name='doubleComparisons(should FAIL: -max != -inf)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared doubles are not the same (fuzzy compare)|n Actual (operandLeft) : -1.79769313486e+308|n Expected (operandRight): -inf' flowId='tst_float'] +##teamcity[testFinished name='doubleComparisons(should FAIL: -max != -inf)' flowId='tst_float'] ##teamcity[testStarted name='floatComparisons(should FAIL 1)' flowId='tst_float'] ##teamcity[testFailed name='floatComparisons(should FAIL 1)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : 1|n Expected (operandRight): 3' flowId='tst_float'] ##teamcity[testFinished name='floatComparisons(should FAIL 1)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should PASS 1)' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should PASS 1)' flowId='tst_float'] ##teamcity[testStarted name='floatComparisons(should FAIL 2)' flowId='tst_float'] ##teamcity[testFailed name='floatComparisons(should FAIL 2)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : 1e-07|n Expected (operandRight): 3e-07' flowId='tst_float'] ##teamcity[testFinished name='floatComparisons(should FAIL 2)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should PASS 2)' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should PASS 2)' flowId='tst_float'] ##teamcity[testStarted name='floatComparisons(should FAIL 3)' flowId='tst_float'] -##teamcity[testFailed name='floatComparisons(should FAIL 3)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : 99998|n Expected (operandRight): 99999' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL 3)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : 99999|n Expected (operandRight): 99998' flowId='tst_float'] ##teamcity[testFinished name='floatComparisons(should FAIL 3)' flowId='tst_float'] -##teamcity[testStarted name='floatComparisons(should SUCCEED 2)' flowId='tst_float'] -##teamcity[testFinished name='floatComparisons(should SUCCEED 2)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should PASS 3)' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should PASS 3)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL 4)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL 4)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : 9.9999e-40|n Expected (operandRight): 9.99971e-40' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL 4)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should PASS 4)' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should PASS 4)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL 5)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL 5)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : 9.9999e+37|n Expected (operandRight): 9.9997e+37' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL 5)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should PASS: NaN == NaN)' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should PASS: NaN == NaN)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL: NaN != 0)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL: NaN != 0)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : nan|n Expected (operandRight): 0' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL: NaN != 0)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL: 0 != NaN)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL: 0 != NaN)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : 0|n Expected (operandRight): nan' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL: 0 != NaN)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL: NaN != 1)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL: NaN != 1)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : nan|n Expected (operandRight): 1' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL: NaN != 1)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL: 1 != NaN)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL: 1 != NaN)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : 1|n Expected (operandRight): nan' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL: 1 != NaN)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should PASS: inf == inf)' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should PASS: inf == inf)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should PASS: -inf == -inf)' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should PASS: -inf == -inf)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL: inf != -inf)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL: inf != -inf)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : inf|n Expected (operandRight): -inf' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL: inf != -inf)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL: -inf != inf)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL: -inf != inf)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : -inf|n Expected (operandRight): inf' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL: -inf != inf)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL: inf != nan)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL: inf != nan)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : inf|n Expected (operandRight): nan' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL: inf != nan)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL: nan != inf)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL: nan != inf)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : nan|n Expected (operandRight): inf' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL: nan != inf)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL: -inf != nan)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL: -inf != nan)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : -inf|n Expected (operandRight): nan' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL: -inf != nan)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL: nan != -inf)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL: nan != -inf)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : nan|n Expected (operandRight): -inf' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL: nan != -inf)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL: inf != 0)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL: inf != 0)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : inf|n Expected (operandRight): 0' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL: inf != 0)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL: 0 != inf)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL: 0 != inf)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : 0|n Expected (operandRight): inf' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL: 0 != inf)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL: -inf != 0)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL: -inf != 0)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : -inf|n Expected (operandRight): 0' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL: -inf != 0)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL: 0 != -inf)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL: 0 != -inf)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : 0|n Expected (operandRight): -inf' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL: 0 != -inf)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL: inf != 1)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL: inf != 1)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : inf|n Expected (operandRight): 1' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL: inf != 1)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL: 1 != inf)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL: 1 != inf)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : 1|n Expected (operandRight): inf' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL: 1 != inf)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL: -inf != 1)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL: -inf != 1)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : -inf|n Expected (operandRight): 1' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL: -inf != 1)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL: 1 != -inf)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL: 1 != -inf)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : 1|n Expected (operandRight): -inf' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL: 1 != -inf)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL: inf != max)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL: inf != max)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : inf|n Expected (operandRight): 3.40282e+38' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL: inf != max)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL: inf != -max)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL: inf != -max)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : inf|n Expected (operandRight): -3.40282e+38' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL: inf != -max)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL: max != inf)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL: max != inf)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : 3.40282e+38|n Expected (operandRight): inf' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL: max != inf)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL: -max != inf)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL: -max != inf)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : -3.40282e+38|n Expected (operandRight): inf' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL: -max != inf)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL: -inf != max)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL: -inf != max)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : -inf|n Expected (operandRight): 3.40282e+38' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL: -inf != max)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL: -inf != -max)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL: -inf != -max)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : -inf|n Expected (operandRight): -3.40282e+38' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL: -inf != -max)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL: max != -inf)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL: max != -inf)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : 3.40282e+38|n Expected (operandRight): -inf' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL: max != -inf)' flowId='tst_float'] +##teamcity[testStarted name='floatComparisons(should FAIL: -max != -inf)' flowId='tst_float'] +##teamcity[testFailed name='floatComparisons(should FAIL: -max != -inf)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (operandLeft) : -3.40282e+38|n Expected (operandRight): -inf' flowId='tst_float'] +##teamcity[testFinished name='floatComparisons(should FAIL: -max != -inf)' flowId='tst_float'] ##teamcity[testStarted name='compareFloatTests(1e0)' flowId='tst_float'] ##teamcity[testFailed name='compareFloatTests(1e0)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)|]' details='Compared floats are not the same (fuzzy compare)|n Actual (t1): 1|n Expected (t3): 3' flowId='tst_float'] ##teamcity[testFinished name='compareFloatTests(1e0)' flowId='tst_float'] diff --git a/tests/auto/testlib/selftests/expected_float.txt b/tests/auto/testlib/selftests/expected_float.txt index 8abea6a67e..3134196a9c 100644 --- a/tests/auto/testlib/selftests/expected_float.txt +++ b/tests/auto/testlib/selftests/expected_float.txt @@ -1,20 +1,268 @@ ********* Start testing of tst_float ********* Config: Using QtTest library PASS : tst_float::initTestCase() -PASS : tst_float::floatComparisons(should SUCCEED 1) +PASS : tst_float::doubleComparisons(should PASS 1) +FAIL! : tst_float::doubleComparisons(should FAIL 1) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): 3 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::doubleComparisons(should FAIL 2) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1e-07 + Expected (operandRight): 3e-07 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +PASS : tst_float::doubleComparisons(should PASS 2) +FAIL! : tst_float::doubleComparisons(should FAIL 3) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 999999999999 + Expected (operandRight): 999999999998 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +PASS : tst_float::doubleComparisons(should PASS 3) +FAIL! : tst_float::doubleComparisons(should FAIL 4) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 9.99999999999e-311 + Expected (operandRight): 9.99999999997e-311 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +PASS : tst_float::doubleComparisons(should PASS 4) +FAIL! : tst_float::doubleComparisons(should FAIL 5) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 9.99999999999e+306 + Expected (operandRight): 9.99999999997e+306 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +PASS : tst_float::doubleComparisons(should PASS: NaN == NaN) +FAIL! : tst_float::doubleComparisons(should FAIL: NaN != 0) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): 0 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::doubleComparisons(should FAIL: 0 != NaN) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 0 + Expected (operandRight): nan + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::doubleComparisons(should FAIL: NaN != 1) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): 1 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::doubleComparisons(should FAIL: 1 != NaN) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): nan + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +PASS : tst_float::doubleComparisons(should PASS: inf == inf) +PASS : tst_float::doubleComparisons(should PASS: -inf == -inf) +FAIL! : tst_float::doubleComparisons(should FAIL: inf != -inf) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): -inf + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::doubleComparisons(should FAIL: -inf != inf) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): inf + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::doubleComparisons(should FAIL: inf != nan) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): nan + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::doubleComparisons(should FAIL: nan != inf) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): inf + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::doubleComparisons(should FAIL: -inf != nan) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): nan + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::doubleComparisons(should FAIL: nan != -inf) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): -inf + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::doubleComparisons(should FAIL: inf != 0) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): 0 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::doubleComparisons(should FAIL: 0 != inf) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 0 + Expected (operandRight): inf + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::doubleComparisons(should FAIL: -inf != 0) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): 0 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::doubleComparisons(should FAIL: 0 != -inf) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 0 + Expected (operandRight): -inf + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::doubleComparisons(should FAIL: inf != 1) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): 1 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::doubleComparisons(should FAIL: 1 != inf) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): inf + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::doubleComparisons(should FAIL: -inf != 1) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): 1 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::doubleComparisons(should FAIL: 1 != -inf) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): -inf + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::doubleComparisons(should FAIL: inf != max) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): 1.79769313486e+308 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::doubleComparisons(should FAIL: inf != -max) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): -1.79769313486e+308 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::doubleComparisons(should FAIL: max != inf) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1.79769313486e+308 + Expected (operandRight): inf + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::doubleComparisons(should FAIL: -max != inf) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -1.79769313486e+308 + Expected (operandRight): inf + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::doubleComparisons(should FAIL: -inf != max) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): 1.79769313486e+308 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::doubleComparisons(should FAIL: -inf != -max) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): -1.79769313486e+308 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::doubleComparisons(should FAIL: max != -inf) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1.79769313486e+308 + Expected (operandRight): -inf + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::doubleComparisons(should FAIL: -max != -inf) Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -1.79769313486e+308 + Expected (operandRight): -inf + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] FAIL! : tst_float::floatComparisons(should FAIL 1) Compared floats are not the same (fuzzy compare) Actual (operandLeft) : 1 Expected (operandRight): 3 Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +PASS : tst_float::floatComparisons(should PASS 1) FAIL! : tst_float::floatComparisons(should FAIL 2) Compared floats are not the same (fuzzy compare) Actual (operandLeft) : 1e-07 Expected (operandRight): 3e-07 Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +PASS : tst_float::floatComparisons(should PASS 2) FAIL! : tst_float::floatComparisons(should FAIL 3) Compared floats are not the same (fuzzy compare) - Actual (operandLeft) : 99998 - Expected (operandRight): 99999 + Actual (operandLeft) : 99999 + Expected (operandRight): 99998 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +PASS : tst_float::floatComparisons(should PASS 3) +FAIL! : tst_float::floatComparisons(should FAIL 4) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 9.9999e-40 + Expected (operandRight): 9.99971e-40 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +PASS : tst_float::floatComparisons(should PASS 4) +FAIL! : tst_float::floatComparisons(should FAIL 5) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 9.9999e+37 + Expected (operandRight): 9.9997e+37 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +PASS : tst_float::floatComparisons(should PASS: NaN == NaN) +FAIL! : tst_float::floatComparisons(should FAIL: NaN != 0) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): 0 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::floatComparisons(should FAIL: 0 != NaN) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 0 + Expected (operandRight): nan + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::floatComparisons(should FAIL: NaN != 1) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): 1 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::floatComparisons(should FAIL: 1 != NaN) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): nan + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +PASS : tst_float::floatComparisons(should PASS: inf == inf) +PASS : tst_float::floatComparisons(should PASS: -inf == -inf) +FAIL! : tst_float::floatComparisons(should FAIL: inf != -inf) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): -inf + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::floatComparisons(should FAIL: -inf != inf) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): inf + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::floatComparisons(should FAIL: inf != nan) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): nan + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::floatComparisons(should FAIL: nan != inf) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): inf + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::floatComparisons(should FAIL: -inf != nan) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): nan + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::floatComparisons(should FAIL: nan != -inf) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): -inf + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::floatComparisons(should FAIL: inf != 0) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): 0 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::floatComparisons(should FAIL: 0 != inf) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 0 + Expected (operandRight): inf + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::floatComparisons(should FAIL: -inf != 0) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): 0 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::floatComparisons(should FAIL: 0 != -inf) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 0 + Expected (operandRight): -inf + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::floatComparisons(should FAIL: inf != 1) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): 1 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::floatComparisons(should FAIL: 1 != inf) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): inf + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::floatComparisons(should FAIL: -inf != 1) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): 1 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::floatComparisons(should FAIL: 1 != -inf) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): -inf + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::floatComparisons(should FAIL: inf != max) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): 3.40282e+38 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::floatComparisons(should FAIL: inf != -max) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): -3.40282e+38 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::floatComparisons(should FAIL: max != inf) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 3.40282e+38 + Expected (operandRight): inf + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::floatComparisons(should FAIL: -max != inf) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -3.40282e+38 + Expected (operandRight): inf + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::floatComparisons(should FAIL: -inf != max) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): 3.40282e+38 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::floatComparisons(should FAIL: -inf != -max) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): -3.40282e+38 + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::floatComparisons(should FAIL: max != -inf) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 3.40282e+38 + Expected (operandRight): -inf + Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] +FAIL! : tst_float::floatComparisons(should FAIL: -max != -inf) Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -3.40282e+38 + Expected (operandRight): -inf Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] -PASS : tst_float::floatComparisons(should SUCCEED 2) FAIL! : tst_float::compareFloatTests(1e0) Compared floats are not the same (fuzzy compare) Actual (t1): 1 Expected (t3): 3 @@ -28,5 +276,5 @@ FAIL! : tst_float::compareFloatTests(1e+7) Compared floats are not the same (fu Expected (t3): 3e+07 Loc: [qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(0)] PASS : tst_float::cleanupTestCase() -Totals: 4 passed, 6 failed, 0 skipped, 0 blacklisted, 0ms +Totals: 16 passed, 65 failed, 0 skipped, 0 blacklisted, 0ms ********* Finished testing of tst_float ********* diff --git a/tests/auto/testlib/selftests/expected_float.xml b/tests/auto/testlib/selftests/expected_float.xml index 096e1a5b54..da934eead3 100644 --- a/tests/auto/testlib/selftests/expected_float.xml +++ b/tests/auto/testlib/selftests/expected_float.xml @@ -9,30 +9,423 @@ <Incident type="pass" file="" line="0" /> <Duration msecs="0"/> </TestFunction> -<TestFunction name="floatComparisons"> +<TestFunction name="doubleComparisons"> <Incident type="pass" file="" line="0"> - <DataTag><![CDATA[should SUCCEED 1]]></DataTag> + <DataTag><![CDATA[should PASS 1]]></DataTag> </Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL 1]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): 3]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL 2]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1e-07 + Expected (operandRight): 3e-07]]></Description> +</Incident> +<Incident type="pass" file="" line="0"> + <DataTag><![CDATA[should PASS 2]]></DataTag> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL 3]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 999999999999 + Expected (operandRight): 999999999998]]></Description> +</Incident> +<Incident type="pass" file="" line="0"> + <DataTag><![CDATA[should PASS 3]]></DataTag> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL 4]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 9.99999999999e-311 + Expected (operandRight): 9.99999999997e-311]]></Description> +</Incident> +<Incident type="pass" file="" line="0"> + <DataTag><![CDATA[should PASS 4]]></DataTag> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL 5]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 9.99999999999e+306 + Expected (operandRight): 9.99999999997e+306]]></Description> +</Incident> +<Incident type="pass" file="" line="0"> + <DataTag><![CDATA[should PASS: NaN == NaN]]></DataTag> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: NaN != 0]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): 0]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: 0 != NaN]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 0 + Expected (operandRight): nan]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: NaN != 1]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): 1]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: 1 != NaN]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): nan]]></Description> +</Incident> +<Incident type="pass" file="" line="0"> + <DataTag><![CDATA[should PASS: inf == inf]]></DataTag> +</Incident> +<Incident type="pass" file="" line="0"> + <DataTag><![CDATA[should PASS: -inf == -inf]]></DataTag> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: inf != -inf]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): -inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -inf != inf]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: inf != nan]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): nan]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: nan != inf]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -inf != nan]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): nan]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: nan != -inf]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): -inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: inf != 0]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): 0]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: 0 != inf]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 0 + Expected (operandRight): inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -inf != 0]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): 0]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: 0 != -inf]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 0 + Expected (operandRight): -inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: inf != 1]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): 1]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: 1 != inf]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -inf != 1]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): 1]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: 1 != -inf]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): -inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: inf != max]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): 1.79769313486e+308]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: inf != -max]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): -1.79769313486e+308]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: max != inf]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1.79769313486e+308 + Expected (operandRight): inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -max != inf]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -1.79769313486e+308 + Expected (operandRight): inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -inf != max]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): 1.79769313486e+308]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -inf != -max]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): -1.79769313486e+308]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: max != -inf]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1.79769313486e+308 + Expected (operandRight): -inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -max != -inf]]></DataTag> + <Description><![CDATA[Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -1.79769313486e+308 + Expected (operandRight): -inf]]></Description> +</Incident> + <Duration msecs="0"/> +</TestFunction> +<TestFunction name="floatComparisons"> <Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> <DataTag><![CDATA[should FAIL 1]]></DataTag> <Description><![CDATA[Compared floats are not the same (fuzzy compare) Actual (operandLeft) : 1 Expected (operandRight): 3]]></Description> </Incident> +<Incident type="pass" file="" line="0"> + <DataTag><![CDATA[should PASS 1]]></DataTag> +</Incident> <Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> <DataTag><![CDATA[should FAIL 2]]></DataTag> <Description><![CDATA[Compared floats are not the same (fuzzy compare) Actual (operandLeft) : 1e-07 Expected (operandRight): 3e-07]]></Description> </Incident> +<Incident type="pass" file="" line="0"> + <DataTag><![CDATA[should PASS 2]]></DataTag> +</Incident> <Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> <DataTag><![CDATA[should FAIL 3]]></DataTag> <Description><![CDATA[Compared floats are not the same (fuzzy compare) - Actual (operandLeft) : 99998 - Expected (operandRight): 99999]]></Description> + Actual (operandLeft) : 99999 + Expected (operandRight): 99998]]></Description> </Incident> <Incident type="pass" file="" line="0"> - <DataTag><![CDATA[should SUCCEED 2]]></DataTag> + <DataTag><![CDATA[should PASS 3]]></DataTag> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL 4]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 9.9999e-40 + Expected (operandRight): 9.99971e-40]]></Description> +</Incident> +<Incident type="pass" file="" line="0"> + <DataTag><![CDATA[should PASS 4]]></DataTag> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL 5]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 9.9999e+37 + Expected (operandRight): 9.9997e+37]]></Description> +</Incident> +<Incident type="pass" file="" line="0"> + <DataTag><![CDATA[should PASS: NaN == NaN]]></DataTag> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: NaN != 0]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): 0]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: 0 != NaN]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 0 + Expected (operandRight): nan]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: NaN != 1]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): 1]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: 1 != NaN]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): nan]]></Description> +</Incident> +<Incident type="pass" file="" line="0"> + <DataTag><![CDATA[should PASS: inf == inf]]></DataTag> +</Incident> +<Incident type="pass" file="" line="0"> + <DataTag><![CDATA[should PASS: -inf == -inf]]></DataTag> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: inf != -inf]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): -inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -inf != inf]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: inf != nan]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): nan]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: nan != inf]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -inf != nan]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): nan]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: nan != -inf]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): -inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: inf != 0]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): 0]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: 0 != inf]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 0 + Expected (operandRight): inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -inf != 0]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): 0]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: 0 != -inf]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 0 + Expected (operandRight): -inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: inf != 1]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): 1]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: 1 != inf]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -inf != 1]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): 1]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: 1 != -inf]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): -inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: inf != max]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): 3.40282e+38]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: inf != -max]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): -3.40282e+38]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: max != inf]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 3.40282e+38 + Expected (operandRight): inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -max != inf]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -3.40282e+38 + Expected (operandRight): inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -inf != max]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): 3.40282e+38]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -inf != -max]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): -3.40282e+38]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: max != -inf]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 3.40282e+38 + Expected (operandRight): -inf]]></Description> +</Incident> +<Incident type="fail" file="qtbase/tests/auto/testlib/selftests/float/tst_float.cpp" line="0"> + <DataTag><![CDATA[should FAIL: -max != -inf]]></DataTag> + <Description><![CDATA[Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -3.40282e+38 + Expected (operandRight): -inf]]></Description> </Incident> <Duration msecs="0"/> </TestFunction> diff --git a/tests/auto/testlib/selftests/expected_float.xunitxml b/tests/auto/testlib/selftests/expected_float.xunitxml index 5de14e8d9b..ba96b16fe6 100644 --- a/tests/auto/testlib/selftests/expected_float.xunitxml +++ b/tests/auto/testlib/selftests/expected_float.xunitxml @@ -1,11 +1,106 @@ <?xml version="1.0" encoding="UTF-8" ?> -<testsuite errors="0" failures="6" tests="4" name="tst_float"> +<testsuite errors="0" failures="65" tests="5" name="tst_float"> <properties> <property value="@INSERT_QT_VERSION_HERE@" name="QTestVersion"/> <property value="@INSERT_QT_VERSION_HERE@" name="QtVersion"/> <property value="" name="QtBuild"/> </properties> <testcase result="pass" name="initTestCase"/> + <testcase result="fail" name="doubleComparisons"> + <failure tag="should FAIL 1" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): 3" result="fail"/> + <failure tag="should FAIL 2" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1e-07 + Expected (operandRight): 3e-07" result="fail"/> + <failure tag="should FAIL 3" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 999999999999 + Expected (operandRight): 999999999998" result="fail"/> + <failure tag="should FAIL 4" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 9.99999999999e-311 + Expected (operandRight): 9.99999999997e-311" result="fail"/> + <failure tag="should FAIL 5" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 9.99999999999e+306 + Expected (operandRight): 9.99999999997e+306" result="fail"/> + <failure tag="should FAIL: NaN != 0" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): 0" result="fail"/> + <failure tag="should FAIL: 0 != NaN" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 0 + Expected (operandRight): nan" result="fail"/> + <failure tag="should FAIL: NaN != 1" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): 1" result="fail"/> + <failure tag="should FAIL: 1 != NaN" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): nan" result="fail"/> + <failure tag="should FAIL: inf != -inf" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): -inf" result="fail"/> + <failure tag="should FAIL: -inf != inf" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): inf" result="fail"/> + <failure tag="should FAIL: inf != nan" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): nan" result="fail"/> + <failure tag="should FAIL: nan != inf" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): inf" result="fail"/> + <failure tag="should FAIL: -inf != nan" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): nan" result="fail"/> + <failure tag="should FAIL: nan != -inf" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): -inf" result="fail"/> + <failure tag="should FAIL: inf != 0" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): 0" result="fail"/> + <failure tag="should FAIL: 0 != inf" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 0 + Expected (operandRight): inf" result="fail"/> + <failure tag="should FAIL: -inf != 0" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): 0" result="fail"/> + <failure tag="should FAIL: 0 != -inf" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 0 + Expected (operandRight): -inf" result="fail"/> + <failure tag="should FAIL: inf != 1" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): 1" result="fail"/> + <failure tag="should FAIL: 1 != inf" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): inf" result="fail"/> + <failure tag="should FAIL: -inf != 1" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): 1" result="fail"/> + <failure tag="should FAIL: 1 != -inf" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): -inf" result="fail"/> + <failure tag="should FAIL: inf != max" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): 1.79769313486e+308" result="fail"/> + <failure tag="should FAIL: inf != -max" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): -1.79769313486e+308" result="fail"/> + <failure tag="should FAIL: max != inf" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1.79769313486e+308 + Expected (operandRight): inf" result="fail"/> + <failure tag="should FAIL: -max != inf" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -1.79769313486e+308 + Expected (operandRight): inf" result="fail"/> + <failure tag="should FAIL: -inf != max" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): 1.79769313486e+308" result="fail"/> + <failure tag="should FAIL: -inf != -max" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): -1.79769313486e+308" result="fail"/> + <failure tag="should FAIL: max != -inf" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : 1.79769313486e+308 + Expected (operandRight): -inf" result="fail"/> + <failure tag="should FAIL: -max != -inf" message="Compared doubles are not the same (fuzzy compare) + Actual (operandLeft) : -1.79769313486e+308 + Expected (operandRight): -inf" result="fail"/> + </testcase> <testcase result="fail" name="floatComparisons"> <failure tag="should FAIL 1" message="Compared floats are not the same (fuzzy compare) Actual (operandLeft) : 1 @@ -14,8 +109,92 @@ Actual (operandLeft) : 1e-07 Expected (operandRight): 3e-07" result="fail"/> <failure tag="should FAIL 3" message="Compared floats are not the same (fuzzy compare) - Actual (operandLeft) : 99998 - Expected (operandRight): 99999" result="fail"/> + Actual (operandLeft) : 99999 + Expected (operandRight): 99998" result="fail"/> + <failure tag="should FAIL 4" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 9.9999e-40 + Expected (operandRight): 9.99971e-40" result="fail"/> + <failure tag="should FAIL 5" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 9.9999e+37 + Expected (operandRight): 9.9997e+37" result="fail"/> + <failure tag="should FAIL: NaN != 0" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): 0" result="fail"/> + <failure tag="should FAIL: 0 != NaN" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 0 + Expected (operandRight): nan" result="fail"/> + <failure tag="should FAIL: NaN != 1" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): 1" result="fail"/> + <failure tag="should FAIL: 1 != NaN" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): nan" result="fail"/> + <failure tag="should FAIL: inf != -inf" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): -inf" result="fail"/> + <failure tag="should FAIL: -inf != inf" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): inf" result="fail"/> + <failure tag="should FAIL: inf != nan" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): nan" result="fail"/> + <failure tag="should FAIL: nan != inf" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): inf" result="fail"/> + <failure tag="should FAIL: -inf != nan" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): nan" result="fail"/> + <failure tag="should FAIL: nan != -inf" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : nan + Expected (operandRight): -inf" result="fail"/> + <failure tag="should FAIL: inf != 0" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): 0" result="fail"/> + <failure tag="should FAIL: 0 != inf" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 0 + Expected (operandRight): inf" result="fail"/> + <failure tag="should FAIL: -inf != 0" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): 0" result="fail"/> + <failure tag="should FAIL: 0 != -inf" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 0 + Expected (operandRight): -inf" result="fail"/> + <failure tag="should FAIL: inf != 1" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): 1" result="fail"/> + <failure tag="should FAIL: 1 != inf" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): inf" result="fail"/> + <failure tag="should FAIL: -inf != 1" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): 1" result="fail"/> + <failure tag="should FAIL: 1 != -inf" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 1 + Expected (operandRight): -inf" result="fail"/> + <failure tag="should FAIL: inf != max" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): 3.40282e+38" result="fail"/> + <failure tag="should FAIL: inf != -max" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : inf + Expected (operandRight): -3.40282e+38" result="fail"/> + <failure tag="should FAIL: max != inf" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 3.40282e+38 + Expected (operandRight): inf" result="fail"/> + <failure tag="should FAIL: -max != inf" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -3.40282e+38 + Expected (operandRight): inf" result="fail"/> + <failure tag="should FAIL: -inf != max" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): 3.40282e+38" result="fail"/> + <failure tag="should FAIL: -inf != -max" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -inf + Expected (operandRight): -3.40282e+38" result="fail"/> + <failure tag="should FAIL: max != -inf" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : 3.40282e+38 + Expected (operandRight): -inf" result="fail"/> + <failure tag="should FAIL: -max != -inf" message="Compared floats are not the same (fuzzy compare) + Actual (operandLeft) : -3.40282e+38 + Expected (operandRight): -inf" result="fail"/> </testcase> <testcase result="fail" name="compareFloatTests"> <failure tag="1e0" message="Compared floats are not the same (fuzzy compare) diff --git a/tests/auto/testlib/selftests/float/tst_float.cpp b/tests/auto/testlib/selftests/float/tst_float.cpp index 2fffcc7803..babb588f4b 100644 --- a/tests/auto/testlib/selftests/float/tst_float.cpp +++ b/tests/auto/testlib/selftests/float/tst_float.cpp @@ -30,16 +30,92 @@ #include <QtTest/QtTest> #include <QDebug> +// Test proper handling of floating-point types class tst_float: public QObject { Q_OBJECT private slots: + void doubleComparisons() const; + void doubleComparisons_data() const; void floatComparisons() const; void floatComparisons_data() const; void compareFloatTests() const; void compareFloatTests_data() const; }; +void tst_float::doubleComparisons() const +{ + QFETCH(double, operandLeft); + QFETCH(double, operandRight); + + QCOMPARE(operandLeft, operandRight); +} + +void tst_float::doubleComparisons_data() const +{ + QTest::addColumn<double>("operandLeft"); + QTest::addColumn<double>("operandRight"); + + QTest::newRow("should PASS 1") << 0. << 0.; + QTest::newRow("should FAIL 1") << 1.00000 << 3.00000; + QTest::newRow("should FAIL 2") << 1.00000e-7 << 3.00000e-7; + + // QCOMPARE for doubles uses qFuzzyCompare(), which succeeds if the numbers + // differ by no more than 1e-12 times the smaller value. Thus + // QCOMPARE(1e12-2, 1e12-1) should fail, while QCOMPARE(1e12+1, 1e12+2) + // should pass. + + QTest::newRow("should PASS 2") << 1e12 + 1. << 1e12 + 2.; + QTest::newRow("should FAIL 3") << 1e12 - 1. << 1e12 - 2.; + // ... but rounding makes that a bit unrelaible when scaled close to the bounds. + QTest::newRow("should PASS 3") << 1e-310 + 1e-322 << 1e-310 + 2e-322; + QTest::newRow("should FAIL 4") << 1e-310 - 1e-322 << 1e-310 - 3e-322; + QTest::newRow("should PASS 4") << 1e307 + 1e295 << 1e307 + 2e295; + QTest::newRow("should FAIL 5") << 1e307 - 1e295 << 1e307 - 3e295; + + // QCOMPARE special-cases non-finite values + if (std::numeric_limits<double>::has_quiet_NaN) { + const double nan = std::numeric_limits<double>::quiet_NaN(); + QTest::newRow("should PASS: NaN == NaN") << nan << nan; + QTest::newRow("should FAIL: NaN != 0") << nan << 0.; + QTest::newRow("should FAIL: 0 != NaN") << 0. << nan; + QTest::newRow("should FAIL: NaN != 1") << nan << 1.; + QTest::newRow("should FAIL: 1 != NaN") << 1. << nan; + } + if (std::numeric_limits<double>::has_infinity) { + const double uge = std::numeric_limits<double>::infinity(); + QTest::newRow("should PASS: inf == inf") << uge << uge; + QTest::newRow("should PASS: -inf == -inf") << -uge << -uge; + QTest::newRow("should FAIL: inf != -inf") << uge << -uge; + QTest::newRow("should FAIL: -inf != inf") << -uge << uge; + if (std::numeric_limits<double>::has_quiet_NaN) { + const double nan = std::numeric_limits<double>::quiet_NaN(); + QTest::newRow("should FAIL: inf != nan") << uge << nan; + QTest::newRow("should FAIL: nan != inf") << nan << uge; + QTest::newRow("should FAIL: -inf != nan") << -uge << nan; + QTest::newRow("should FAIL: nan != -inf") << nan << -uge; + } + QTest::newRow("should FAIL: inf != 0") << uge << 0.; + QTest::newRow("should FAIL: 0 != inf") << 0. << uge; + QTest::newRow("should FAIL: -inf != 0") << -uge << 0.; + QTest::newRow("should FAIL: 0 != -inf") << 0. << -uge; + QTest::newRow("should FAIL: inf != 1") << uge << 1.; + QTest::newRow("should FAIL: 1 != inf") << 1. << uge; + QTest::newRow("should FAIL: -inf != 1") << -uge << 1.; + QTest::newRow("should FAIL: 1 != -inf") << 1. << -uge; + + const double big = std::numeric_limits<double>::max(); + QTest::newRow("should FAIL: inf != max") << uge << big; + QTest::newRow("should FAIL: inf != -max") << uge << -big; + QTest::newRow("should FAIL: max != inf") << big << uge; + QTest::newRow("should FAIL: -max != inf") << -big << uge; + QTest::newRow("should FAIL: -inf != max") << -uge << big; + QTest::newRow("should FAIL: -inf != -max") << -uge << -big; + QTest::newRow("should FAIL: max != -inf") << big << -uge; + QTest::newRow("should FAIL: -max != -inf") << -big << -uge; + } +} + void tst_float::floatComparisons() const { QFETCH(float, operandLeft); @@ -53,30 +129,64 @@ void tst_float::floatComparisons_data() const QTest::addColumn<float>("operandLeft"); QTest::addColumn<float>("operandRight"); - QTest::newRow("should SUCCEED 1") - << float(0) - << float(0); - - QTest::newRow("should FAIL 1") - << float(1.00000) - << float(3.00000); - - QTest::newRow("should FAIL 2") - << float(1.00000e-7f) - << float(3.00000e-7f); + QTest::newRow("should FAIL 1") << 1.00000f << 3.00000f; + QTest::newRow("should PASS 1") << 0.f << 0.f; + QTest::newRow("should FAIL 2") << 1.00000e-7f << 3.00000e-7f; // QCOMPARE for floats uses qFuzzyCompare(), which succeeds if the numbers - // differ by no more than 1/100,000th of the smaller value. Thus - // QCOMPARE(99998, 99999) should fail, while QCOMPARE(100001, 100002) + // differ by no more than 1e-5 times the smaller value. Thus + // QCOMPARE(1e5-2, 1e5-1) should fail, while QCOMPARE(1e5+1, 1e5+2) // should pass. - QTest::newRow("should FAIL 3") - << float(99998) - << float(99999); + QTest::newRow("should PASS 2") << 1e5f + 1.f << 1e5f + 2.f; + QTest::newRow("should FAIL 3") << 1e5f - 1.f << 1e5f - 2.f; + // ... but rounding makes that a bit unrelaible when scaled close to the bounds. + QTest::newRow("should PASS 3") << 1e-39f + 1e-44f << 1e-39f + 2e-44f; + QTest::newRow("should FAIL 4") << 1e-39f - 1e-44f << 1e-39f - 3e-44f; + QTest::newRow("should PASS 4") << 1e38f + 1e33f << 1e38f + 2e33f; + QTest::newRow("should FAIL 5") << 1e38f - 1e33f << 1e38f - 3e33f; - QTest::newRow("should SUCCEED 2") - << float(100001) - << float(100002); + // QCOMPARE special-cases non-finite values + if (std::numeric_limits<float>::has_quiet_NaN) { + const float nan = std::numeric_limits<float>::quiet_NaN(); + QTest::newRow("should PASS: NaN == NaN") << nan << nan; + QTest::newRow("should FAIL: NaN != 0") << nan << 0.f; + QTest::newRow("should FAIL: 0 != NaN") << 0.f << nan; + QTest::newRow("should FAIL: NaN != 1") << nan << 1.f; + QTest::newRow("should FAIL: 1 != NaN") << 1.f << nan; + } + if (std::numeric_limits<float>::has_infinity) { + const float uge = std::numeric_limits<float>::infinity(); + QTest::newRow("should PASS: inf == inf") << uge << uge; + QTest::newRow("should PASS: -inf == -inf") << -uge << -uge; + QTest::newRow("should FAIL: inf != -inf") << uge << -uge; + QTest::newRow("should FAIL: -inf != inf") << -uge << uge; + if (std::numeric_limits<float>::has_quiet_NaN) { + const float nan = std::numeric_limits<float>::quiet_NaN(); + QTest::newRow("should FAIL: inf != nan") << uge << nan; + QTest::newRow("should FAIL: nan != inf") << nan << uge; + QTest::newRow("should FAIL: -inf != nan") << -uge << nan; + QTest::newRow("should FAIL: nan != -inf") << nan << -uge; + } + QTest::newRow("should FAIL: inf != 0") << uge << 0.f; + QTest::newRow("should FAIL: 0 != inf") << 0.f << uge; + QTest::newRow("should FAIL: -inf != 0") << -uge << 0.f; + QTest::newRow("should FAIL: 0 != -inf") << 0.f << -uge; + QTest::newRow("should FAIL: inf != 1") << uge << 1.f; + QTest::newRow("should FAIL: 1 != inf") << 1.f << uge; + QTest::newRow("should FAIL: -inf != 1") << -uge << 1.f; + QTest::newRow("should FAIL: 1 != -inf") << 1.f << -uge; + + const float big = std::numeric_limits<float>::max(); + QTest::newRow("should FAIL: inf != max") << uge << big; + QTest::newRow("should FAIL: inf != -max") << uge << -big; + QTest::newRow("should FAIL: max != inf") << big << uge; + QTest::newRow("should FAIL: -max != inf") << -big << uge; + QTest::newRow("should FAIL: -inf != max") << -uge << big; + QTest::newRow("should FAIL: -inf != -max") << -uge << -big; + QTest::newRow("should FAIL: max != -inf") << big << -uge; + QTest::newRow("should FAIL: -max != -inf") << -big << -uge; + } } void tst_float::compareFloatTests() const diff --git a/tests/auto/testlib/selftests/tst_selftests.cpp b/tests/auto/testlib/selftests/tst_selftests.cpp index 08c6dec191..8baca5bdad 100644 --- a/tests/auto/testlib/selftests/tst_selftests.cpp +++ b/tests/auto/testlib/selftests/tst_selftests.cpp @@ -782,15 +782,6 @@ void tst_Selftests::doRunSubTest(QString const& subdir, QStringList const& logge QString expectedFileName = expectedFileNameFromTest(subdir, logger); QByteArrayList exp = expectedResult(expectedFileName); if (!exp.isEmpty()) { -#ifdef Q_CC_MINGW - // MinGW formats double numbers differently (last verified with 7.1) - if (n == 0 && subdir == QStringLiteral("float")) { - for (int i = 0; i < exp.size(); ++i) { - exp[i].replace("e-07", "e-007"); - exp[i].replace("e+07", "e+007"); - } - } -#endif if (!compareOutput(logger, subdir, actualOutputs[n], res, exp, &errorMessage)) { errorMessage.prepend(QLatin1Char('"') + logger + QLatin1String("\", ") + expectedFileName + QLatin1Char(' ')); diff --git a/tests/benchmarks/benchmarks.pro b/tests/benchmarks/benchmarks.pro index 9e288f7aa2..a98b9a62c6 100644 --- a/tests/benchmarks/benchmarks.pro +++ b/tests/benchmarks/benchmarks.pro @@ -3,10 +3,11 @@ SUBDIRS = \ corelib \ sql \ -# removed-by-refactor qtHaveModule(opengl): SUBDIRS += opengl qtHaveModule(dbus): SUBDIRS += dbus -qtHaveModule(network): SUBDIRS += network qtHaveModule(gui): SUBDIRS += gui +qtHaveModule(network): SUBDIRS += network +# removed-by-refactor qtHaveModule(opengl): SUBDIRS += opengl +qtHaveModule(testlib): SUBDIRS += testlib qtHaveModule(widgets): SUBDIRS += widgets check-trusted.CONFIG += recursive diff --git a/tests/benchmarks/testlib/testlib.pro b/tests/benchmarks/testlib/testlib.pro new file mode 100644 index 0000000000..c325f3de9a --- /dev/null +++ b/tests/benchmarks/testlib/testlib.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs +SUBDIRS = \ + tostring \ diff --git a/tests/benchmarks/testlib/tostring/tostring.pro b/tests/benchmarks/testlib/tostring/tostring.pro new file mode 100644 index 0000000000..a5aebe1c81 --- /dev/null +++ b/tests/benchmarks/testlib/tostring/tostring.pro @@ -0,0 +1,4 @@ +TARGET = tst_bench_tostring +QT = core testlib + +SOURCES += tst_tostring.cpp diff --git a/tests/benchmarks/testlib/tostring/tst_tostring.cpp b/tests/benchmarks/testlib/tostring/tst_tostring.cpp new file mode 100644 index 0000000000..1731929f98 --- /dev/null +++ b/tests/benchmarks/testlib/tostring/tst_tostring.cpp @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> +#include <QtCore/qmath.h> // pi, e + +// Tests for QTest::toString +class tst_toString : public QObject +{ + Q_OBJECT + + template <typename T> void numeric_data(); + template <typename T> void numeric(); + +private slots: + void floatTst_data() { numeric_data<float>(); } + void floatTst() { numeric<float>(); } + void doubleTst_data() { numeric_data<double>(); } + void doubleTst() { numeric<double>(); } + void intTst_data() { numeric_data<int>(); } + void intTst() { numeric<int>(); } + void unsignedTst_data() { numeric_data<unsigned>(); } + void unsignedTst() { numeric<unsigned>(); } + void quint64Tst_data() { numeric_data<quint64>(); } + void quint64Tst() { numeric<quint64>(); } + void qint64Tst_data() { numeric_data<qint64>(); } + void qint64Tst() { numeric<qint64>(); } +}; + +template <typename T> +void tst_toString::numeric_data() +{ + QTest::addColumn<T>("datum"); + const bool floaty = std::is_floating_point<T>::value; + + QTest::newRow("zero") << T(0); + QTest::newRow("one") << T(1); + if (floaty) { + QTest::newRow("pi") << T(M_PI); + QTest::newRow("e") << T(M_E); + + // Stress canonicalisation of leading zeros on exponents: + QTest::newRow("milli") << T(1e-3); + QTest::newRow("micro") << T(1e-6); + QTest::newRow("mu0") << T(.4e-6 * M_PI); // Henry/metre + QTest::newRow("Planck") << T(662.606876e-36); // Joule.second/turn + } + QTest::newRow("2e9") << T(2000000000); + QTest::newRow("c.s/m") << T(299792458); + QTest::newRow("Avogadro") << T(6.022045e+23); // things/mol (.996 << 79, so ints overflow to max) + + QTest::newRow("lowest") << std::numeric_limits<T>::lowest(); + QTest::newRow("max") << std::numeric_limits<T>::max(); + if (floaty) { + QTest::newRow("min") << std::numeric_limits<T>::min(); + + if (std::numeric_limits<T>::has_infinity) { + const T uge = std::numeric_limits<T>::infinity(); + QTest::newRow("inf") << uge; + QTest::newRow("-inf") << -uge; + } + if (std::numeric_limits<T>::has_quiet_NaN) + QTest::newRow("nan") << std::numeric_limits<T>::quiet_NaN(); + } +} + +template <typename T> +void tst_toString::numeric() +{ + QFETCH(T, datum); + + QBENCHMARK { + QTest::toString<T>(datum); + } +} + +QTEST_MAIN(tst_toString) +#include "tst_tostring.moc" From ddb5d390450de25e510c72b17ed8124b9186a736 Mon Sep 17 00:00:00 2001 From: Andreas Hartmetz <andreas@ixgreen.de> Date: Tue, 5 Feb 2019 14:39:41 +0100 Subject: [PATCH 1050/1650] QMetaObject::Connection overview documentation improvements Try to better describe what it is and what it does. Also mention its strongest use case. Change-Id: Ib5c3e8a3c9b96169c139c5d7e8995a6a49d7d5e1 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io> Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com> --- src/corelib/kernel/qobject.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 42c39f18e3..b4e885e407 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -5070,11 +5070,14 @@ bool QObjectPrivate::disconnect(const QObject *sender, int signal_index, void ** /*! \class QMetaObject::Connection \inmodule QtCore - Represents a handle to a signal-slot connection. - It can be used to disconnect that connection, or check if - the connection was successful + Represents a handle to a signal-slot (or signal-functor) connection. - \sa QObject::disconnect() + It can be used to check if the connection is valid and to disconnect it using + QObject::disconnect(). For a signal-functor connection without a context object, + it is the only way to selectively disconnect that connection. + + As Connection is just a handle, the underlying signal-slot connection is unaffected + when Connection is destroyed or reassigned. */ /*! From 4c165e68342b7de32bbbb49fe103c1eb7f575696 Mon Sep 17 00:00:00 2001 From: Liang Qi <liang.qi@qt.io> Date: Tue, 5 Feb 2019 11:16:58 +0100 Subject: [PATCH 1051/1650] Disable Docker-based test servers on macOS temporarily The coin agent starts to crash after the docker-compose call. Need to have qt5 5.13 integrated first, then fix the real issue later. Task-number: QTQAINFRA-2717 Task-number: QTQAINFRA-2750 Change-Id: I3dcd963b1c5cea0b2197f1589398d8a9ed18f46f Reviewed-by: Aapo Keskimolo <aapo.keskimolo@qt.io> --- tests/auto/testserver.pri | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/auto/testserver.pri b/tests/auto/testserver.pri index 73008ea8b3..26e7f6ab8a 100644 --- a/tests/auto/testserver.pri +++ b/tests/auto/testserver.pri @@ -56,7 +56,18 @@ # Makefile.Debug and Makefile.Release. debug_and_release:!build_pass: return() -TESTSERVER_VERSION = $$system(docker-compose --version) +DOCKER_ENABLED = 1 + +equals(QMAKE_HOST.os, Darwin) { + DOCKER_ENABLED = 0 + message("Not using docker network test server on macOS, see QTQAINFRA-2717 and QTQAINFRA-2750") +} + +TESTSERVER_VERSION = "" + +equals(DOCKER_ENABLED, 1) { + TESTSERVER_VERSION = $$system(docker-compose --version) +} isEmpty(TESTSERVER_VERSION) { # Make check with server "qt-test-server.qt-test-net" as a fallback From 8a7c373f8e745427d5fe7afc08d698837b7b8f2b Mon Sep 17 00:00:00 2001 From: Karim Pinter <karim.pinter@qt.io> Date: Tue, 29 Jan 2019 16:05:06 +0200 Subject: [PATCH 1052/1650] QNX QPA: Add support for Qt Virtual Keyboard If the QT_IM_MODULE environment variable is set, then it loads the IM module accordingly, otherwise it is using the PPS one, if it is available. Task-number: QTBUG-54576 Change-Id: Icb8b474805053d8297029096365783c2cabc2cbc Reviewed-by: Samuli Piippo <samuli.piippo@qt.io> Reviewed-by: James McDonnell <jmcdonnell@blackberry.com> --- src/plugins/platforms/qnx/qqnxintegration.cpp | 25 +++++++++++++------ src/plugins/platforms/qnx/qqnxintegration.h | 1 + 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp index db79780407..a996e765c4 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.cpp +++ b/src/plugins/platforms/qnx/qqnxintegration.cpp @@ -72,6 +72,9 @@ # endif #endif +#include <qpa/qplatforminputcontextfactory_p.h> +#include <qpa/qplatforminputcontext.h> + #include "private/qgenericunixfontdatabase_p.h" #include "private/qgenericunixeventdispatcher_p.h" @@ -152,6 +155,7 @@ QQnxIntegration::QQnxIntegration(const QStringList ¶mList) , m_inputContext(0) , m_buttonsNotifier(new QQnxButtonEventNotifier()) #endif + , m_qpaInputContext(0) , m_services(0) , m_fontDatabase(new QGenericUnixFontDatabase()) , m_eventDispatcher(createUnixEventDispatcher()) @@ -194,13 +198,17 @@ QQnxIntegration::QQnxIntegration(const QStringList ¶mList) m_screenEventHandler->setScreenEventThread(m_screenEventThread); m_screenEventThread->start(); -#if QT_CONFIG(qqnx_pps) - // Create/start the keyboard class. - m_virtualKeyboard = new QQnxVirtualKeyboardPps(); + m_qpaInputContext = QPlatformInputContextFactory::create(); - // delay invocation of start() to the time the event loop is up and running - // needed to have the QThread internals of the main thread properly initialized - QMetaObject::invokeMethod(m_virtualKeyboard, "start", Qt::QueuedConnection); +#if QT_CONFIG(qqnx_pps) + if (!m_qpaInputContext) { + // Create/start the keyboard class. + m_virtualKeyboard = new QQnxVirtualKeyboardPps(); + + // delay invocation of start() to the time the event loop is up and running + // needed to have the QThread internals of the main thread properly initialized + QMetaObject::invokeMethod(m_virtualKeyboard, "start", Qt::QueuedConnection); + } #endif #if QT_CONFIG(qqnx_pps) @@ -281,6 +289,7 @@ QQnxIntegration::~QQnxIntegration() // Destroy input context delete m_inputContext; #endif + delete m_qpaInputContext; // Destroy the keyboard class. delete m_virtualKeyboard; @@ -397,13 +406,13 @@ QPlatformOpenGLContext *QQnxIntegration::createPlatformOpenGLContext(QOpenGLCont } #endif -#if QT_CONFIG(qqnx_pps) QPlatformInputContext *QQnxIntegration::inputContext() const { qIntegrationDebug(); + if (m_qpaInputContext) + return m_qpaInputContext; return m_inputContext; } -#endif void QQnxIntegration::moveToScreen(QWindow *window, int screen) { diff --git a/src/plugins/platforms/qnx/qqnxintegration.h b/src/plugins/platforms/qnx/qqnxintegration.h index 4a6f15fc08..366556dc4b 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.h +++ b/src/plugins/platforms/qnx/qqnxintegration.h @@ -153,6 +153,7 @@ private: QQnxInputContext *m_inputContext; QQnxButtonEventNotifier *m_buttonsNotifier; #endif + QPlatformInputContext *m_qpaInputContext; QQnxServices *m_services; QPlatformFontDatabase *m_fontDatabase; mutable QAbstractEventDispatcher *m_eventDispatcher; From 5133e22ae200eb3c5169340a16b419c9fce747cb Mon Sep 17 00:00:00 2001 From: Andy Shaw <andy.shaw@qt.io> Date: Wed, 30 Jan 2019 12:05:31 +0100 Subject: [PATCH 1053/1650] Add support for setting the peer verify name via the QNetwork* classes This adds functions to QNetworkRequest to be able to set the peerVerifyName. An overload of connectToHostEncrypted is also added to have an extra argument to allow setting it directly in this manner too. Fixes: QTBUG-73125 Change-Id: I371e90035b53a74c9eb3cef64f367e307dce073e Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> --- src/network/access/qhttpnetworkconnection.cpp | 12 +++++++ src/network/access/qhttpnetworkconnection_p.h | 4 +++ .../access/qhttpnetworkconnectionchannel.cpp | 1 + src/network/access/qhttpnetworkrequest.cpp | 15 +++++++-- src/network/access/qhttpnetworkrequest_p.h | 3 ++ src/network/access/qhttpthreaddelegate.cpp | 13 ++++---- src/network/access/qnetworkaccessmanager.cpp | 29 +++++++++++++++++ src/network/access/qnetworkaccessmanager.h | 3 ++ src/network/access/qnetworkreplyhttpimpl.cpp | 1 + src/network/access/qnetworkrequest.cpp | 31 ++++++++++++++++++- src/network/access/qnetworkrequest.h | 2 ++ 11 files changed, 105 insertions(+), 9 deletions(-) diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 9fd6acb26c..681d84fee8 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -1518,6 +1518,18 @@ void QHttpNetworkConnection::preConnectFinished() d_func()->preConnectRequests--; } +QString QHttpNetworkConnection::peerVerifyName() const +{ + Q_D(const QHttpNetworkConnection); + return d->peerVerifyName; +} + +void QHttpNetworkConnection::setPeerVerifyName(const QString &peerName) +{ + Q_D(QHttpNetworkConnection); + d->peerVerifyName = peerName; +} + #ifndef QT_NO_NETWORKPROXY // only called from QHttpNetworkConnectionChannel::_q_proxyAuthenticationRequired, not // from QHttpNetworkConnectionChannel::handleAuthenticationChallenge diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h index da54fbac2c..2bd727e0af 100644 --- a/src/network/access/qhttpnetworkconnection_p.h +++ b/src/network/access/qhttpnetworkconnection_p.h @@ -154,6 +154,8 @@ public: void preConnectFinished(); + QString peerVerifyName() const; + void setPeerVerifyName(const QString &peerName); private: Q_DECLARE_PRIVATE(QHttpNetworkConnection) Q_DISABLE_COPY_MOVE(QHttpNetworkConnection) @@ -289,6 +291,8 @@ public: Http2::ProtocolParameters http2Parameters; + QString peerVerifyName; + friend class QHttpNetworkConnectionChannel; }; diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 5726925cb0..9df3d73dd7 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -392,6 +392,7 @@ bool QHttpNetworkConnectionChannel::ensureConnection() if (!connection->sslContext().isNull()) QSslSocketPrivate::checkSettingSslContext(sslSocket, connection->sslContext()); + sslSocket->setPeerVerifyName(connection->d_func()->peerVerifyName); sslSocket->connectToHostEncrypted(connectHost, connectPort, QIODevice::ReadWrite, networkLayerPreference); if (ignoreAllSslErrors) sslSocket->ignoreSslErrors(); diff --git a/src/network/access/qhttpnetworkrequest.cpp b/src/network/access/qhttpnetworkrequest.cpp index 8de9760710..a3f71b8d2f 100644 --- a/src/network/access/qhttpnetworkrequest.cpp +++ b/src/network/access/qhttpnetworkrequest.cpp @@ -66,7 +66,8 @@ QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(const QHttpNetworkRequest ssl(other.ssl), preConnect(other.preConnect), redirectCount(other.redirectCount), - redirectPolicy(other.redirectPolicy) + redirectPolicy(other.redirectPolicy), + peerVerifyName(other.peerVerifyName) { } @@ -90,7 +91,8 @@ bool QHttpNetworkRequestPrivate::operator==(const QHttpNetworkRequestPrivate &ot && (withCredentials == other.withCredentials) && (ssl == other.ssl) && (preConnect == other.preConnect) - && (redirectPolicy == other.redirectPolicy); + && (redirectPolicy == other.redirectPolicy) + && (peerVerifyName == other.peerVerifyName); } QByteArray QHttpNetworkRequest::methodName() const @@ -397,6 +399,15 @@ int QHttpNetworkRequest::minorVersion() const return 1; } +QString QHttpNetworkRequest::peerVerifyName() const +{ + return d->peerVerifyName; +} + +void QHttpNetworkRequest::setPeerVerifyName(const QString &peerName) +{ + d->peerVerifyName = peerName; +} QT_END_NAMESPACE diff --git a/src/network/access/qhttpnetworkrequest_p.h b/src/network/access/qhttpnetworkrequest_p.h index bc797537ae..fb4896195b 100644 --- a/src/network/access/qhttpnetworkrequest_p.h +++ b/src/network/access/qhttpnetworkrequest_p.h @@ -147,6 +147,8 @@ public: QByteArray methodName() const; QByteArray uri(bool throughProxy) const; + QString peerVerifyName() const; + void setPeerVerifyName(const QString &peerName); private: QSharedDataPointer<QHttpNetworkRequestPrivate> d; friend class QHttpNetworkRequestPrivate; @@ -182,6 +184,7 @@ public: bool preConnect; int redirectCount; QNetworkRequest::RedirectPolicy redirectPolicy; + QString peerVerifyName; }; diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp index 0e97acdd9d..1fdf28df9d 100644 --- a/src/network/access/qhttpthreaddelegate.cpp +++ b/src/network/access/qhttpthreaddelegate.cpp @@ -123,7 +123,7 @@ static QNetworkReply::NetworkError statusCodeFromHttp(int httpStatusCode, const } -static QByteArray makeCacheKey(QUrl &url, QNetworkProxy *proxy) +static QByteArray makeCacheKey(QUrl &url, QNetworkProxy *proxy, const QString &peerVerifyName) { QString result; QUrl copy = url; @@ -170,7 +170,8 @@ static QByteArray makeCacheKey(QUrl &url, QNetworkProxy *proxy) #else Q_UNUSED(proxy) #endif - + if (!peerVerifyName.isEmpty()) + result += QLatin1Char(':') + peerVerifyName; return "http-connection:" + std::move(result).toLatin1(); } @@ -317,12 +318,12 @@ void QHttpThreadDelegate::startRequest() #ifndef QT_NO_NETWORKPROXY if (transparentProxy.type() != QNetworkProxy::NoProxy) - cacheKey = makeCacheKey(urlCopy, &transparentProxy); + cacheKey = makeCacheKey(urlCopy, &transparentProxy, httpRequest.peerVerifyName()); else if (cacheProxy.type() != QNetworkProxy::NoProxy) - cacheKey = makeCacheKey(urlCopy, &cacheProxy); + cacheKey = makeCacheKey(urlCopy, &cacheProxy, httpRequest.peerVerifyName()); else #endif - cacheKey = makeCacheKey(urlCopy, 0); + cacheKey = makeCacheKey(urlCopy, 0, httpRequest.peerVerifyName()); // the http object is actually a QHttpNetworkConnection @@ -352,7 +353,7 @@ void QHttpThreadDelegate::startRequest() httpConnection->setTransparentProxy(transparentProxy); httpConnection->setCacheProxy(cacheProxy); #endif - + httpConnection->setPeerVerifyName(httpRequest.peerVerifyName()); // cache the QHttpNetworkConnection corresponding to this cache key connections.localData()->addEntry(cacheKey, httpConnection); } else { diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 1f0d2f92e2..8e78857259 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -1181,8 +1181,36 @@ QSharedPointer<QNetworkSession> QNetworkAccessManagerPrivate::getNetworkSession( \sa connectToHost(), get(), post(), put(), deleteResource() */ + void QNetworkAccessManager::connectToHostEncrypted(const QString &hostName, quint16 port, const QSslConfiguration &sslConfiguration) +{ + connectToHostEncrypted(hostName, port, sslConfiguration, QString()); +} + +/*! + \since 5.13 + \overload + + Initiates a connection to the host given by \a hostName at port \a port, using + \a sslConfiguration with \a peerName set to be the hostName used for certificate + validation. This function is useful to complete the TCP and SSL handshake + to a host before the HTTPS request is made, resulting in a lower network latency. + + \note Preconnecting a SPDY connection can be done by calling setAllowedNextProtocols() + on \a sslConfiguration with QSslConfiguration::NextProtocolSpdy3_0 contained in + the list of allowed protocols. When using SPDY, one single connection per host is + enough, i.e. calling this method multiple times per host will not result in faster + network transactions. + + \note This function has no possibility to report errors. + + \sa connectToHost(), get(), post(), put(), deleteResource() +*/ + +void QNetworkAccessManager::connectToHostEncrypted(const QString &hostName, quint16 port, + const QSslConfiguration &sslConfiguration, + const QString &peerName) { QUrl url; url.setHost(hostName); @@ -1198,6 +1226,7 @@ void QNetworkAccessManager::connectToHostEncrypted(const QString &hostName, quin QSslConfiguration::NextProtocolSpdy3_0)) request.setAttribute(QNetworkRequest::SpdyAllowedAttribute, true); + request.setPeerVerifyName(peerName); get(request); } #endif diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h index 67b3a8b71b..7e2f7683d0 100644 --- a/src/network/access/qnetworkaccessmanager.h +++ b/src/network/access/qnetworkaccessmanager.h @@ -158,6 +158,9 @@ public: #ifndef QT_NO_SSL void connectToHostEncrypted(const QString &hostName, quint16 port = 443, const QSslConfiguration &sslConfiguration = QSslConfiguration::defaultConfiguration()); + void connectToHostEncrypted(const QString &hostName, quint16 port, + const QSslConfiguration &sslConfiguration, + const QString &peerName); #endif void connectToHost(const QString &hostName, quint16 port = 80); diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index ef54c198ba..9378e058b1 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -785,6 +785,7 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq if (request.attribute(QNetworkRequest::EmitAllUploadProgressSignalsAttribute).toBool()) emitAllUploadProgressSignals = true; + httpRequest.setPeerVerifyName(newHttpRequest.peerVerifyName()); // Create the HTTP thread delegate QHttpThreadDelegate *delegate = new QHttpThreadDelegate; diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index e4c46c3183..f15c43cdd8 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -438,6 +438,7 @@ public: if (other.sslConfiguration) sslConfiguration = new QSslConfiguration(*other.sslConfiguration); #endif + peerVerifyName = other.peerVerifyName; } inline bool operator==(const QNetworkRequestPrivate &other) const @@ -446,7 +447,8 @@ public: priority == other.priority && rawHeaders == other.rawHeaders && attributes == other.attributes && - maxRedirectsAllowed == other.maxRedirectsAllowed; + maxRedirectsAllowed == other.maxRedirectsAllowed && + peerVerifyName == other.peerVerifyName; // don't compare cookedHeaders } @@ -456,6 +458,7 @@ public: mutable QSslConfiguration *sslConfiguration; #endif int maxRedirectsAllowed; + QString peerVerifyName; }; /*! @@ -789,6 +792,32 @@ void QNetworkRequest::setMaximumRedirectsAllowed(int maxRedirectsAllowed) d->maxRedirectsAllowed = maxRedirectsAllowed; } +/*! + \since 5.13 + + Returns the host name set for the certificate validation, as set by + setPeerVerifyName. By default this returns a null string. + + \sa setPeerVerifyName +*/ +QString QNetworkRequest::peerVerifyName() const +{ + return d->peerVerifyName; +} + +/*! + \since 5.13 + + Sets \a peerName as host name for the certificate validation, instead of the one used for the + TCP connection. + + \sa peerVerifyName +*/ +void QNetworkRequest::setPeerVerifyName(const QString &peerName) +{ + d->peerVerifyName = peerName; +} + static QByteArray headerName(QNetworkRequest::KnownHeaders header) { switch (header) { diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h index 8462eae8c8..efb9cbecba 100644 --- a/src/network/access/qnetworkrequest.h +++ b/src/network/access/qnetworkrequest.h @@ -173,6 +173,8 @@ public: int maximumRedirectsAllowed() const; void setMaximumRedirectsAllowed(int maximumRedirectsAllowed); + QString peerVerifyName() const; + void setPeerVerifyName(const QString &peerName); private: QSharedDataPointer<QNetworkRequestPrivate> d; friend class QNetworkRequestPrivate; From 7910dd0a548cdd9e7c5716d4f6704b3185fa34fb Mon Sep 17 00:00:00 2001 From: Michal Klocek <michal.klocek@qt.io> Date: Thu, 17 Jan 2019 15:39:32 +0100 Subject: [PATCH 1054/1650] Add llvm linker detection to configure https://gcc.gnu.org/ml/gcc-patches/2018-10/msg01240.html This is currently only used for webengine, where link time really matters. New configure options: * force 'lld' '-linker lld' or' --linker=lld' * force 'gold' '-linker gold' or '--linker=gold' * force 'bfd' '-linker bfd' or '--linker=bfd' Note before by default gold was always forced (if supported) now default linker is system default one. [ChangeLog][Tools][configure & build system] Added --linker=[bfg,lld,gold] configure flag. Change-Id: Idaa13510da70243c6176b96db846d629cd65c7af Reviewed-by: Kai Koehne <kai.koehne@qt.io> --- config_help.txt | 3 +- configure.json | 49 +++++++++++++++++++++++++++---- configure.pri | 16 ++++++++++ mkspecs/common/gcc-base-unix.conf | 2 ++ mkspecs/features/default_post.prf | 2 ++ mkspecs/features/qt_configure.prf | 8 +++++ 6 files changed, 74 insertions(+), 6 deletions(-) diff --git a/config_help.txt b/config_help.txt index 223adf61d7..8eea64e03a 100644 --- a/config_help.txt +++ b/config_help.txt @@ -167,7 +167,8 @@ Build options: -pch ................. Use precompiled headers [auto] -ltcg ................ Use Link Time Code Generation [no] - -use-gold-linker ..... Use the GNU gold linker [auto] + -linker [bfd,gold,lld] Force use of the GNU ld, GNU gold or LLVM/LLD linker + instead of default one (GCC only) -incredibuild-xge .... Use the IncrediBuild XGE [no] (Windows only) -ccache .............. Use the ccache compiler cache [no] (Unix only) -make-tool <tool> .... Use <tool> to build qmake [nmake] (Windows only) diff --git a/configure.json b/configure.json index f1a414fbf9..4a9e1fc24e 100644 --- a/configure.json +++ b/configure.json @@ -90,6 +90,7 @@ "headersclean": "boolean", "incredibuild-xge": { "type": "boolean", "name": "incredibuild_xge" }, "libudev": "boolean", + "linker": { "type": "optionalString", "values": [ "bfd", "gold", "lld" ] }, "ltcg": "boolean", "make": { "type": "addString", "values": [ "examples", "libs", "tests", "tools" ] }, "make-tool": "string", @@ -131,7 +132,7 @@ "syncqt": "boolean", "sysroot": "string", "testcocoon": "boolean", - "use-gold-linker": { "type": "boolean", "name": "use_gold_linker" }, + "use-gold-linker": { "type": "boolean", "name": "use_gold_linker_alias" }, "warnings-are-errors": { "type": "boolean", "name": "warnings_are_errors" }, "Werror": { "type": "boolean", "name": "warnings_are_errors" }, "widgets": "boolean", @@ -224,8 +225,8 @@ }, "testTypeDependencies": { - "linkerSupportsFlag": [ "use_gold_linker" ], - "verifySpec": [ "shared", "use_gold_linker", "compiler-flags", "qmakeargs", "commit" ], + "linkerSupportsFlag": [ "use_bfd_linker", "use_gold_linker", "use_lld_linker" ], + "verifySpec": [ "shared", "use_bfd_linker", "use_gold_linker", "use_lld_linker", "compiler-flags", "qmakeargs", "commit" ], "compile": [ "verifyspec" ], "detectPkgConfig": [ "cross_compile", "machineTuple" ], "library": [ "pkg-config", "compiler-flags" ], @@ -357,11 +358,21 @@ ] } }, + "use_bfd_linker": { + "label": "bfd linker", + "type": "compilerSupportsFlag", + "flag": "-fuse-ld=bfd" + }, "use_gold_linker": { "label": "gold linker", "type": "compilerSupportsFlag", "flag": "-fuse-ld=gold" }, + "use_lld_linker" : { + "label": "lld linker", + "type": "compilerSupportsFlag", + "flag": "-fuse-ld=lld" + }, "optimize_debug": { "label": "-Og support", "type": "compilerSupportsFlag", @@ -649,11 +660,34 @@ "output": [ "qmakeArgs" ], "condition": "input.qmakeArgs != ''" }, + "use_bfd_linker": { + "label": "bfd", + "autoDetect": "false", + "enable" : "input.linker == 'bfd'", + "disable" : "input.linker == 'gold' || input.linker == 'lld'", + "condition": "!config.win32 && !config.integrity && !config.wasm && tests.use_bfd_linker", + "output": [ "privateConfig", "useBFDLinker" ] + }, + "use_gold_linker_alias": { + "autoDetect": "false", + "condition": "!config.win32 && !config.integrity && !config.wasm && tests.use_gold_linker" + }, "use_gold_linker": { - "label": "Using gold linker", + "label": "gold", + "autoDetect": "false", + "enable" : "input.linker == 'gold' || features.use_gold_linker_alias" , + "disable" : "input.linker == 'bfd' || input.linker == 'lld'", "condition": "!config.win32 && !config.integrity && !config.wasm && tests.use_gold_linker", "output": [ "privateConfig", "useGoldLinker" ] }, + "use_lld_linker": { + "label": "lld", + "autoDetect": "false", + "enable" : "input.linker == 'lld'", + "disable" : "input.linker == 'bfd' || input.linker == 'gold'", + "condition": "!config.win32 && !config.integrity && !config.wasm && tests.use_lld_linker", + "output": [ "privateConfig", "useLLDLinker" ] + }, "optimize_debug": { "label": "Optimize debug build", "condition": "!config.msvc && !config.clang && (features.debug || features.debug_and_release) && tests.optimize_debug", @@ -1386,7 +1420,12 @@ Configure with '-qreal float' to create a build that is binary-compatible with 5 "args": "ccache", "condition": "config.unix" }, - "use_gold_linker", + { + "message": "Linker", + "type": "firstAvailableFeature", + "args": "use_bfd_linker use_gold_linker use_lld_linker", + "condition": "features.use_bfd_linker || features.use_gold_linker || features.use_lld_linker" + }, { "type": "feature", "args": "enable_new_dtags", diff --git a/configure.pri b/configure.pri index df890a7c49..d92653885f 100644 --- a/configure.pri +++ b/configure.pri @@ -1026,6 +1026,14 @@ defineTest(qtConfOutput_crossCompile) { export(CONFIG) } +defineTest(qtConfOutput_useBFDLinker) { + !$${2}: return() + + # We need to preempt the output here, so that qtConfTest_linkerSupportsFlag can work properly in qtbase + CONFIG += use_bfd_linker + export(CONFIG) +} + defineTest(qtConfOutput_useGoldLinker) { !$${2}: return() @@ -1034,6 +1042,14 @@ defineTest(qtConfOutput_useGoldLinker) { export(CONFIG) } +defineTest(qtConfOutput_useLLDLinker) { + !$${2}: return() + + # We need to preempt the output here, so that qtConfTest_linkerSupportsFlag can work properly in qtbase + CONFIG += use_lld_linker + export(CONFIG) +} + defineTest(qtConfOutput_debugAndRelease) { $$qtConfEvaluate("features.debug") { qtConfOutputVar(append, "publicPro", "CONFIG", "debug") diff --git a/mkspecs/common/gcc-base-unix.conf b/mkspecs/common/gcc-base-unix.conf index 700f228c36..a456c8f3eb 100644 --- a/mkspecs/common/gcc-base-unix.conf +++ b/mkspecs/common/gcc-base-unix.conf @@ -20,7 +20,9 @@ QMAKE_LFLAGS_RPATH = -Wl,-rpath, QMAKE_LFLAGS_RPATHLINK = -Wl,-rpath-link, QMAKE_LFLAGS_NEW_DTAGS = -Wl,--enable-new-dtags QMAKE_LFLAGS_GDB_INDEX = -Wl,--gdb-index +QMAKE_LFLAGS_USE_BFD = -fuse-ld=bfd QMAKE_LFLAGS_USE_GOLD = -fuse-ld=gold +QMAKE_LFLAGS_USE_LLD = -fuse-ld=lld # -Bsymbolic-functions (ld) support QMAKE_LFLAGS_BSYMBOLIC_FUNC = -Wl,-Bsymbolic-functions diff --git a/mkspecs/features/default_post.prf b/mkspecs/features/default_post.prf index d90da49781..69da78c5b7 100644 --- a/mkspecs/features/default_post.prf +++ b/mkspecs/features/default_post.prf @@ -78,7 +78,9 @@ stack_protector_strong { # disable special linker flags for host builds (no proper test for host support yet) !host_build|!cross_compile { + use_bfd_linker: QMAKE_LFLAGS += $$QMAKE_LFLAGS_USE_BFD use_gold_linker: QMAKE_LFLAGS += $$QMAKE_LFLAGS_USE_GOLD + use_lld_linker: QMAKE_LFLAGS += $$QMAKE_LFLAGS_USE_LLD enable_new_dtags: QMAKE_LFLAGS += $$QMAKE_LFLAGS_NEW_DTAGS enable_gdb_index: QMAKE_LFLAGS += $$QMAKE_LFLAGS_GDB_INDEX } diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index c45439c3ef..f682892abe 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -368,8 +368,12 @@ defineTest(qtConfTest_compilerSupportsFlag) { defineTest(qtConfTest_linkerSupportsFlag) { flag = $$eval($${1}.flag) + use_bfd_linker: \ + LFLAGS = -fuse-ld=bfd use_gold_linker: \ LFLAGS = -fuse-ld=gold + use_lld_linker: \ + LFLAGS = -fuse-ld=lld return($$qtConfToolchainSupportsFlag($$LFLAGS "-Wl,$$flag")) } @@ -1220,8 +1224,12 @@ defineTest(qtConfTest_compile) { else: \ qmake_configs = "static" + use_bfd_linker: \ + qmake_configs += "use_bfd_linker" use_gold_linker: \ qmake_configs += "use_gold_linker" + use_lld_linker: \ + qmake_configs += "use_lld_linker" # disable warnings from the builds, since they're just noise at this point. qmake_configs += "warn_off" From 4715ca7bc54fc1f30dd7e603a396c876d667c92c Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Sun, 3 Feb 2019 17:09:10 +0100 Subject: [PATCH 1055/1650] Cleanup QtCore examples Cleanup QtCore examples: - use new signal/slot syntax - use 0 instead nullptr - remove unneeded includes - use initializer lists - replace foreach with range-based-for loop Change-Id: I5581f485fa0e9ccf3f4ce6f643908832bc6959bb Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> --- .../corelib/ipc/localfortuneclient/client.h | 4 +-- .../corelib/ipc/localfortuneserver/main.cpp | 3 --- .../corelib/ipc/localfortuneserver/server.cpp | 8 ++---- examples/corelib/ipc/sharedmemory/dialog.cpp | 9 +++---- examples/corelib/ipc/sharedmemory/dialog.h | 6 ++--- .../mimetypes/mimetypebrowser/main.cpp | 3 --- .../mimetypebrowser/mimetypemodel.cpp | 3 +-- .../serialization/convert/cborconverter.cpp | 1 - .../corelib/serialization/savegame/game.cpp | 2 +- .../corelib/serialization/savegame/level.cpp | 2 +- .../threads/mandelbrot/mandelbrotwidget.cpp | 8 +++--- .../threads/mandelbrot/mandelbrotwidget.h | 2 +- .../threads/mandelbrot/renderthread.cpp | 2 +- .../corelib/threads/mandelbrot/renderthread.h | 2 +- .../threads/queuedcustomtype/block.cpp | 8 ++---- .../corelib/threads/queuedcustomtype/block.h | 1 - .../threads/queuedcustomtype/renderthread.h | 2 +- .../threads/queuedcustomtype/window.cpp | 26 +++++++++++-------- .../corelib/threads/queuedcustomtype/window.h | 2 +- .../tools/contiguouscache/randomlistmodel.cpp | 1 - .../tools/contiguouscache/randomlistmodel.h | 2 +- examples/corelib/tools/customtype/main.cpp | 1 + examples/corelib/tools/customtype/message.cpp | 8 +++--- examples/corelib/tools/customtype/message.h | 1 - .../corelib/tools/customtypesending/main.cpp | 11 ++++---- .../tools/customtypesending/message.cpp | 6 ++--- .../corelib/tools/customtypesending/message.h | 1 - .../tools/customtypesending/window.cpp | 9 ++++--- .../corelib/tools/customtypesending/window.h | 2 +- 29 files changed, 59 insertions(+), 77 deletions(-) diff --git a/examples/corelib/ipc/localfortuneclient/client.h b/examples/corelib/ipc/localfortuneclient/client.h index 0c1ede94c9..7248428440 100644 --- a/examples/corelib/ipc/localfortuneclient/client.h +++ b/examples/corelib/ipc/localfortuneclient/client.h @@ -53,14 +53,12 @@ #include <QDialog> #include <QDataStream> - -#include <qlocalsocket.h> +#include <QLocalSocket> QT_BEGIN_NAMESPACE class QLabel; class QLineEdit; class QPushButton; -class QLocalSocket; QT_END_NAMESPACE class Client : public QDialog diff --git a/examples/corelib/ipc/localfortuneserver/main.cpp b/examples/corelib/ipc/localfortuneserver/main.cpp index 6f8ec539fe..430005a1d3 100644 --- a/examples/corelib/ipc/localfortuneserver/main.cpp +++ b/examples/corelib/ipc/localfortuneserver/main.cpp @@ -49,9 +49,6 @@ ****************************************************************************/ #include <QApplication> -#include <QtCore> - -#include <stdlib.h> #include "server.h" diff --git a/examples/corelib/ipc/localfortuneserver/server.cpp b/examples/corelib/ipc/localfortuneserver/server.cpp index be8d4750d6..9be5ed5051 100644 --- a/examples/corelib/ipc/localfortuneserver/server.cpp +++ b/examples/corelib/ipc/localfortuneserver/server.cpp @@ -48,15 +48,11 @@ ** ****************************************************************************/ +#include "server.h" + #include <QtWidgets> #include <QtNetwork> -#include <stdlib.h> - -#include "server.h" -#include <qlocalserver.h> -#include <qlocalsocket.h> - Server::Server(QWidget *parent) : QDialog(parent) { diff --git a/examples/corelib/ipc/sharedmemory/dialog.cpp b/examples/corelib/ipc/sharedmemory/dialog.cpp index ce5a4547bb..4e999d1bcf 100644 --- a/examples/corelib/ipc/sharedmemory/dialog.cpp +++ b/examples/corelib/ipc/sharedmemory/dialog.cpp @@ -51,7 +51,6 @@ #include "dialog.h" #include <QFileDialog> #include <QBuffer> -#include <QtCore/QDebug> /*! \class Dialog @@ -81,10 +80,10 @@ Dialog::Dialog(QWidget *parent) : QDialog(parent), sharedMemory("QSharedMemoryExample") { ui.setupUi(this); - connect(ui.loadFromFileButton, SIGNAL(clicked()), SLOT(loadFromFile())); - connect(ui.loadFromSharedMemoryButton, - SIGNAL(clicked()), - SLOT(loadFromMemory())); + connect(ui.loadFromFileButton, &QPushButton::clicked, + this, &Dialog::loadFromFile); + connect(ui.loadFromSharedMemoryButton, &QPushButton::clicked, + this, &Dialog::loadFromMemory); setWindowTitle(tr("SharedMemory Example")); } //! [0] diff --git a/examples/corelib/ipc/sharedmemory/dialog.h b/examples/corelib/ipc/sharedmemory/dialog.h index 1662654441..693333256c 100644 --- a/examples/corelib/ipc/sharedmemory/dialog.h +++ b/examples/corelib/ipc/sharedmemory/dialog.h @@ -51,8 +51,8 @@ #ifndef DIALOG_H #define DIALOG_H -#include <qdialog.h> -#include <qsharedmemory.h> +#include <QDialog> +#include <QSharedMemory> #include "ui_dialog.h" //! [0] @@ -61,7 +61,7 @@ class Dialog : public QDialog Q_OBJECT public: - Dialog(QWidget *parent = 0); + Dialog(QWidget *parent = nullptr); public slots: void loadFromFile(); diff --git a/examples/corelib/mimetypes/mimetypebrowser/main.cpp b/examples/corelib/mimetypes/mimetypebrowser/main.cpp index f4462df411..cf87004a01 100644 --- a/examples/corelib/mimetypes/mimetypebrowser/main.cpp +++ b/examples/corelib/mimetypes/mimetypebrowser/main.cpp @@ -55,9 +55,6 @@ #include <QCommandLineParser> #include <QCommandLineOption> -#include <QDebug> -#include <QMimeDatabase> -#include <QMimeType> int main(int argc, char *argv[]) { diff --git a/examples/corelib/mimetypes/mimetypebrowser/mimetypemodel.cpp b/examples/corelib/mimetypes/mimetypebrowser/mimetypemodel.cpp index ee83de092d..f755e060c6 100644 --- a/examples/corelib/mimetypes/mimetypebrowser/mimetypemodel.cpp +++ b/examples/corelib/mimetypes/mimetypebrowser/mimetypemodel.cpp @@ -50,9 +50,8 @@ #include "mimetypemodel.h" -#include <QIcon> - #include <QDebug> +#include <QIcon> #include <QMimeDatabase> #include <QTextStream> #include <QVariant> diff --git a/examples/corelib/serialization/convert/cborconverter.cpp b/examples/corelib/serialization/convert/cborconverter.cpp index f906c81062..ad69983eb1 100644 --- a/examples/corelib/serialization/convert/cborconverter.cpp +++ b/examples/corelib/serialization/convert/cborconverter.cpp @@ -56,7 +56,6 @@ #include <QCborArray> #include <QCborValue> #include <QDataStream> -#include <QDebug> #include <QFloat16> #include <QFile> #include <QMetaType> diff --git a/examples/corelib/serialization/savegame/game.cpp b/examples/corelib/serialization/savegame/game.cpp index 226f6fda11..c39362bc68 100644 --- a/examples/corelib/serialization/savegame/game.cpp +++ b/examples/corelib/serialization/savegame/game.cpp @@ -185,7 +185,7 @@ void Game::write(QJsonObject &json) const json["player"] = playerObject; QJsonArray levelArray; - for (const Level level : mLevels) { + for (const Level &level : mLevels) { QJsonObject levelObject; level.write(levelObject); levelArray.append(levelObject); diff --git a/examples/corelib/serialization/savegame/level.cpp b/examples/corelib/serialization/savegame/level.cpp index c7adc6c8ff..6fe46e8938 100644 --- a/examples/corelib/serialization/savegame/level.cpp +++ b/examples/corelib/serialization/savegame/level.cpp @@ -97,7 +97,7 @@ void Level::write(QJsonObject &json) const { json["name"] = mName; QJsonArray npcArray; - for (const Character npc : mNpcs) { + for (const Character &npc : mNpcs) { QJsonObject npcObject; npc.write(npcObject); npcArray.append(npcObject); diff --git a/examples/corelib/threads/mandelbrot/mandelbrotwidget.cpp b/examples/corelib/threads/mandelbrot/mandelbrotwidget.cpp index b3e4af5dc8..2603f041b2 100644 --- a/examples/corelib/threads/mandelbrot/mandelbrotwidget.cpp +++ b/examples/corelib/threads/mandelbrot/mandelbrotwidget.cpp @@ -48,14 +48,13 @@ ** ****************************************************************************/ +#include "mandelbrotwidget.h" + #include <QPainter> #include <QKeyEvent> #include <math.h> -#include "mandelbrotwidget.h" - - //! [0] const double DefaultCenterX = -0.637011f; const double DefaultCenterY = -0.0395159f; @@ -75,7 +74,8 @@ MandelbrotWidget::MandelbrotWidget(QWidget *parent) pixmapScale = DefaultScale; curScale = DefaultScale; - connect(&thread, SIGNAL(renderedImage(QImage,double)), this, SLOT(updatePixmap(QImage,double))); + connect(&thread, &RenderThread::renderedImage, + this, &MandelbrotWidget::updatePixmap); setWindowTitle(tr("Mandelbrot")); #ifndef QT_NO_CURSOR diff --git a/examples/corelib/threads/mandelbrot/mandelbrotwidget.h b/examples/corelib/threads/mandelbrot/mandelbrotwidget.h index a04bfa6e81..cb40962535 100644 --- a/examples/corelib/threads/mandelbrot/mandelbrotwidget.h +++ b/examples/corelib/threads/mandelbrot/mandelbrotwidget.h @@ -62,7 +62,7 @@ class MandelbrotWidget : public QWidget Q_OBJECT public: - MandelbrotWidget(QWidget *parent = 0); + MandelbrotWidget(QWidget *parent = nullptr); protected: void paintEvent(QPaintEvent *event) override; diff --git a/examples/corelib/threads/mandelbrot/renderthread.cpp b/examples/corelib/threads/mandelbrot/renderthread.cpp index c57b696e25..eee44c7242 100644 --- a/examples/corelib/threads/mandelbrot/renderthread.cpp +++ b/examples/corelib/threads/mandelbrot/renderthread.cpp @@ -50,7 +50,7 @@ #include "renderthread.h" -#include <QtWidgets> +#include <QImage> #include <cmath> //! [0] diff --git a/examples/corelib/threads/mandelbrot/renderthread.h b/examples/corelib/threads/mandelbrot/renderthread.h index b5e9226fb8..4f0394d554 100644 --- a/examples/corelib/threads/mandelbrot/renderthread.h +++ b/examples/corelib/threads/mandelbrot/renderthread.h @@ -66,7 +66,7 @@ class RenderThread : public QThread Q_OBJECT public: - RenderThread(QObject *parent = 0); + RenderThread(QObject *parent = nullptr); ~RenderThread(); void render(double centerX, double centerY, double scaleFactor, QSize resultSize); diff --git a/examples/corelib/threads/queuedcustomtype/block.cpp b/examples/corelib/threads/queuedcustomtype/block.cpp index a5058cc5ae..9cfad8673c 100644 --- a/examples/corelib/threads/queuedcustomtype/block.cpp +++ b/examples/corelib/threads/queuedcustomtype/block.cpp @@ -48,8 +48,6 @@ ** ****************************************************************************/ -#include <QColor> -#include <QRect> #include "block.h" Block::Block() @@ -57,9 +55,8 @@ Block::Block() } Block::Block(const Block &other) + : m_rect(other.m_rect), m_color(other.m_color) { - m_rect = other.m_rect; - m_color = other.m_color; } Block::~Block() @@ -67,9 +64,8 @@ Block::~Block() } Block::Block(const QRect &rect, const QColor &color) + : m_rect(rect), m_color(color) { - m_rect = rect; - m_color = color; } QColor Block::color() const diff --git a/examples/corelib/threads/queuedcustomtype/block.h b/examples/corelib/threads/queuedcustomtype/block.h index 547cc10f0a..eef48b25c2 100644 --- a/examples/corelib/threads/queuedcustomtype/block.h +++ b/examples/corelib/threads/queuedcustomtype/block.h @@ -52,7 +52,6 @@ #define BLOCK_H #include <QColor> -#include <QDebug> #include <QMetaType> #include <QRect> diff --git a/examples/corelib/threads/queuedcustomtype/renderthread.h b/examples/corelib/threads/queuedcustomtype/renderthread.h index 318ef293b4..9375b60e74 100644 --- a/examples/corelib/threads/queuedcustomtype/renderthread.h +++ b/examples/corelib/threads/queuedcustomtype/renderthread.h @@ -62,7 +62,7 @@ class RenderThread : public QThread Q_OBJECT public: - RenderThread(QObject *parent = 0); + RenderThread(QObject *parent = nullptr); ~RenderThread(); void processImage(const QImage &image); diff --git a/examples/corelib/threads/queuedcustomtype/window.cpp b/examples/corelib/threads/queuedcustomtype/window.cpp index 0d3f80aba4..183d9824cb 100644 --- a/examples/corelib/threads/queuedcustomtype/window.cpp +++ b/examples/corelib/threads/queuedcustomtype/window.cpp @@ -48,30 +48,34 @@ ** ****************************************************************************/ -#include <QtWidgets> #include "window.h" +#include <QtWidgets> //! [Window constructor start] -Window::Window() +Window::Window(QWidget *parent) + : QWidget(parent), thread(new RenderThread(this)) { - thread = new RenderThread(); //! [Window constructor start] //! [set up widgets and connections] - label = new QLabel(); + label = new QLabel(this); label->setAlignment(Qt::AlignCenter); - loadButton = new QPushButton(tr("&Load image...")); - resetButton = new QPushButton(tr("&Stop")); + loadButton = new QPushButton(tr("&Load image..."), this); + resetButton = new QPushButton(tr("&Stop"), this); resetButton->setEnabled(false); - connect(loadButton, SIGNAL(clicked()), this, SLOT(loadImage())); - connect(resetButton, SIGNAL(clicked()), thread, SLOT(stopProcess())); - connect(thread, SIGNAL(finished()), this, SLOT(resetUi())); + connect(loadButton, &QPushButton::clicked, + this, QOverload<>::of(&Window::loadImage)); + connect(resetButton, &QPushButton::clicked, + thread, &RenderThread::stopProcess); + connect(thread, &RenderThread::finished, + this, &Window::resetUi); //! [set up widgets and connections] //! [connecting signal with custom type] - connect(thread, SIGNAL(sendBlock(Block)), this, SLOT(addBlock(Block))); + connect(thread, &RenderThread::sendBlock, + this, &Window::addBlock); //! [connecting signal with custom type] - QHBoxLayout *buttonLayout = new QHBoxLayout(); + QHBoxLayout *buttonLayout = new QHBoxLayout; buttonLayout->addStretch(); buttonLayout->addWidget(loadButton); buttonLayout->addWidget(resetButton); diff --git a/examples/corelib/threads/queuedcustomtype/window.h b/examples/corelib/threads/queuedcustomtype/window.h index c472c0fea7..4215dfd5a7 100644 --- a/examples/corelib/threads/queuedcustomtype/window.h +++ b/examples/corelib/threads/queuedcustomtype/window.h @@ -65,7 +65,7 @@ class Window : public QWidget Q_OBJECT public: - Window(); + Window(QWidget *parent = nullptr); void loadImage(const QImage &image); public slots: diff --git a/examples/corelib/tools/contiguouscache/randomlistmodel.cpp b/examples/corelib/tools/contiguouscache/randomlistmodel.cpp index ccaa45a28b..d028b896f2 100644 --- a/examples/corelib/tools/contiguouscache/randomlistmodel.cpp +++ b/examples/corelib/tools/contiguouscache/randomlistmodel.cpp @@ -49,7 +49,6 @@ ****************************************************************************/ #include "randomlistmodel.h" #include <QRandomGenerator> -#include <stdlib.h> static const int bufferSize(500); static const int lookAhead(100); diff --git a/examples/corelib/tools/contiguouscache/randomlistmodel.h b/examples/corelib/tools/contiguouscache/randomlistmodel.h index e6192b434f..1fabb0d9f5 100644 --- a/examples/corelib/tools/contiguouscache/randomlistmodel.h +++ b/examples/corelib/tools/contiguouscache/randomlistmodel.h @@ -59,7 +59,7 @@ class RandomListModel : public QAbstractListModel { Q_OBJECT public: - RandomListModel(QObject *parent = 0); + RandomListModel(QObject *parent = nullptr); ~RandomListModel(); int rowCount(const QModelIndex & = QModelIndex()) const override; diff --git a/examples/corelib/tools/customtype/main.cpp b/examples/corelib/tools/customtype/main.cpp index ced317e208..d50bf9efea 100644 --- a/examples/corelib/tools/customtype/main.cpp +++ b/examples/corelib/tools/customtype/main.cpp @@ -49,6 +49,7 @@ ****************************************************************************/ #include <QCoreApplication> +#include <QDebug> #include <QVariant> #include "message.h" diff --git a/examples/corelib/tools/customtype/message.cpp b/examples/corelib/tools/customtype/message.cpp index 8b2c295e46..cc96aee978 100644 --- a/examples/corelib/tools/customtype/message.cpp +++ b/examples/corelib/tools/customtype/message.cpp @@ -50,15 +50,16 @@ #include "message.h" +#include <QDebug> + //! [Message class implementation] Message::Message() { } Message::Message(const Message &other) + : m_body(other.m_body), m_headers(other.m_headers) { - m_body = other.m_body; - m_headers = other.m_headers; } Message::~Message() @@ -67,9 +68,8 @@ Message::~Message() //! [Message class implementation] Message::Message(const QString &body, const QStringList &headers) + : m_body(body), m_headers(headers) { - m_body = body; - m_headers = headers; } //! [custom type streaming operator] diff --git a/examples/corelib/tools/customtype/message.h b/examples/corelib/tools/customtype/message.h index 9871a7d52d..c1b8243237 100644 --- a/examples/corelib/tools/customtype/message.h +++ b/examples/corelib/tools/customtype/message.h @@ -51,7 +51,6 @@ #ifndef MESSAGE_H #define MESSAGE_H -#include <QDebug> #include <QMetaType> #include <QStringList> diff --git a/examples/corelib/tools/customtypesending/main.cpp b/examples/corelib/tools/customtypesending/main.cpp index 966c284d9a..c5d643b9d1 100644 --- a/examples/corelib/tools/customtypesending/main.cpp +++ b/examples/corelib/tools/customtypesending/main.cpp @@ -57,19 +57,20 @@ int main(int argc, char *argv[]) { QApplication app(argc, argv); - Window window1; QStringList headers; headers << "Subject: Hello World" << "From: address@example.com"; QString body = "This is a test.\r\n"; Message message(body, headers); + + Window window1; window1.setMessage(message); Window window2; - QObject::connect(&window1, SIGNAL(messageSent(Message)), - &window2, SLOT(setMessage(Message))); - QObject::connect(&window2, SIGNAL(messageSent(Message)), - &window1, SLOT(setMessage(Message))); + QObject::connect(&window1, &Window::messageSent, + &window2, &Window::setMessage); + QObject::connect(&window2, &Window::messageSent, + &window1, &Window::setMessage); window1.show(); window2.show(); return app.exec(); diff --git a/examples/corelib/tools/customtypesending/message.cpp b/examples/corelib/tools/customtypesending/message.cpp index c990768079..9386b93898 100644 --- a/examples/corelib/tools/customtypesending/message.cpp +++ b/examples/corelib/tools/customtypesending/message.cpp @@ -55,9 +55,8 @@ Message::Message() } Message::Message(const Message &other) + : m_body(other.m_body), m_headers(other.m_headers) { - m_body = other.m_body; - m_headers = other.m_headers; } Message::~Message() @@ -65,9 +64,8 @@ Message::~Message() } Message::Message(const QString &body, const QStringList &headers) + : m_body(body), m_headers(headers) { - m_body = body; - m_headers = headers; } QString Message::body() const diff --git a/examples/corelib/tools/customtypesending/message.h b/examples/corelib/tools/customtypesending/message.h index a8d6d6be05..a93f111e45 100644 --- a/examples/corelib/tools/customtypesending/message.h +++ b/examples/corelib/tools/customtypesending/message.h @@ -51,7 +51,6 @@ #ifndef MESSAGE_H #define MESSAGE_H -#include <QDebug> #include <QMetaType> #include <QStringList> diff --git a/examples/corelib/tools/customtypesending/window.cpp b/examples/corelib/tools/customtypesending/window.cpp index 224656f94c..db4b52a985 100644 --- a/examples/corelib/tools/customtypesending/window.cpp +++ b/examples/corelib/tools/customtypesending/window.cpp @@ -52,14 +52,15 @@ #include "window.h" //! [Window constructor] -Window::Window() +Window::Window(QWidget *parent) + : QWidget(parent), editor(new QTextEdit(this)) { - editor = new QTextEdit(); QPushButton *sendButton = new QPushButton(tr("&Send message")); - connect(sendButton, SIGNAL(clicked()), this, SLOT(sendMessage())); + connect(sendButton, &QPushButton::clicked, + this, &Window::sendMessage); - QHBoxLayout *buttonLayout = new QHBoxLayout(); + QHBoxLayout *buttonLayout = new QHBoxLayout; buttonLayout->addStretch(); buttonLayout->addWidget(sendButton); buttonLayout->addStretch(); diff --git a/examples/corelib/tools/customtypesending/window.h b/examples/corelib/tools/customtypesending/window.h index d050931b74..048fecef67 100644 --- a/examples/corelib/tools/customtypesending/window.h +++ b/examples/corelib/tools/customtypesending/window.h @@ -62,7 +62,7 @@ class Window : public QWidget Q_OBJECT public: - Window(); + Window(QWidget *parent = nullptr); signals: void messageSent(const Message &message); From d6d33f0b80dd85043c71f71a3ed5485d6014e6c4 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Sat, 26 Jan 2019 20:02:53 +0100 Subject: [PATCH 1056/1650] QtWidgets: mark obsolete functions as deprecated Mark some long obsolete functions as deprecated so the can be removed with Qt6: - QLayout::margin()/setMargin() - QComboBox::autoCompletion()/setAutoCompletion() - QComboBox::autoCompletionCaseSensitivity() - QComboBox::setAutoCompletionCaseSensitivity() - QTextStream& operator<<(QTextStream&, const QSplitter&) - QTextStream& operator>>(QTextStream&, QSplitter&); Change-Id: Ic16b36bf647413b5b3ea2d9105981b95370b3178 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> --- src/widgets/kernel/qlayout.cpp | 18 ++++++++++-------- src/widgets/kernel/qlayout.h | 8 ++++++-- src/widgets/widgets/qcombobox.cpp | 2 ++ src/widgets/widgets/qcombobox.h | 4 ++++ src/widgets/widgets/qsplitter.cpp | 2 ++ src/widgets/widgets/qsplitter.h | 4 ++++ 6 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp index 090abc883d..f27851c7bb 100644 --- a/src/widgets/kernel/qlayout.cpp +++ b/src/widgets/kernel/qlayout.cpp @@ -282,6 +282,7 @@ bool QLayout::setAlignment(QLayout *l, Qt::Alignment alignment) return false; } +#if QT_DEPRECATED_SINCE(5, 13) /*! \property QLayout::margin \brief the width of the outside border of the layout @@ -306,6 +307,15 @@ int QLayout::margin() const } } +/*! + \obsolete +*/ +void QLayout::setMargin(int margin) +{ + setContentsMargins(margin, margin, margin, margin); +} + +#endif /*! \property QLayout::spacing \brief the spacing between widgets inside the layout @@ -344,14 +354,6 @@ int QLayout::spacing() const } } -/*! - \obsolete -*/ -void QLayout::setMargin(int margin) -{ - setContentsMargins(margin, margin, margin, margin); -} - void QLayout::setSpacing(int spacing) { if (QBoxLayout* boxlayout = qobject_cast<QBoxLayout*>(this)) { diff --git a/src/widgets/kernel/qlayout.h b/src/widgets/kernel/qlayout.h index 616f4e7164..35a04a35b2 100644 --- a/src/widgets/kernel/qlayout.h +++ b/src/widgets/kernel/qlayout.h @@ -63,7 +63,9 @@ class Q_WIDGETS_EXPORT QLayout : public QObject, public QLayoutItem Q_OBJECT Q_DECLARE_PRIVATE(QLayout) +#if QT_DEPRECATED_SINCE(5, 13) Q_PROPERTY(int margin READ margin WRITE setMargin) +#endif Q_PROPERTY(int spacing READ spacing WRITE setSpacing) Q_PROPERTY(SizeConstraint sizeConstraint READ sizeConstraint WRITE setSizeConstraint) public: @@ -81,10 +83,12 @@ public: QLayout(); ~QLayout(); +#if QT_DEPRECATED_SINCE(5, 13) int margin() const; - int spacing() const; - void setMargin(int); +#endif + + int spacing() const; void setSpacing(int); void setContentsMargins(int left, int top, int right, int bottom); diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 2f67a9202c..2c478f364d 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -1483,6 +1483,7 @@ int QComboBox::maxCount() const } #if QT_CONFIG(completer) +#if QT_DEPRECATED_SINCE(5, 13) /*! \property QComboBox::autoCompletion @@ -1576,6 +1577,7 @@ void QComboBox::setAutoCompletionCaseSensitivity(Qt::CaseSensitivity sensitivity if (d->lineEdit && d->lineEdit->completer()) d->lineEdit->completer()->setCaseSensitivity(sensitivity); } +#endif // QT_DEPRECATED_SINCE(5, 13) #endif // QT_CONFIG(completer) diff --git a/src/widgets/widgets/qcombobox.h b/src/widgets/widgets/qcombobox.h index 671c883584..542a3bd3b9 100644 --- a/src/widgets/widgets/qcombobox.h +++ b/src/widgets/widgets/qcombobox.h @@ -73,8 +73,10 @@ class Q_WIDGETS_EXPORT QComboBox : public QWidget Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize) #if QT_CONFIG(completer) +#if QT_DEPRECATED_SINCE(5, 13) Q_PROPERTY(bool autoCompletion READ autoCompletion WRITE setAutoCompletion DESIGNABLE false) Q_PROPERTY(Qt::CaseSensitivity autoCompletionCaseSensitivity READ autoCompletionCaseSensitivity WRITE setAutoCompletionCaseSensitivity DESIGNABLE false) +#endif #endif // QT_CONFIG(completer) Q_PROPERTY(bool duplicatesEnabled READ duplicatesEnabled WRITE setDuplicatesEnabled) @@ -93,11 +95,13 @@ public: int maxCount() const; #if QT_CONFIG(completer) +#if QT_DEPRECATED_SINCE(5, 13) bool autoCompletion() const; void setAutoCompletion(bool enable); Qt::CaseSensitivity autoCompletionCaseSensitivity() const; void setAutoCompletionCaseSensitivity(Qt::CaseSensitivity sensitivity); +#endif #endif bool duplicatesEnabled() const; diff --git a/src/widgets/widgets/qsplitter.cpp b/src/widgets/widgets/qsplitter.cpp index 9e38c8f18a..0b90714363 100644 --- a/src/widgets/widgets/qsplitter.cpp +++ b/src/widgets/widgets/qsplitter.cpp @@ -1783,6 +1783,7 @@ void QSplitter::setStretchFactor(int index, int stretch) } +#if QT_DEPRECATED_SINCE(5, 13) /*! \relates QSplitter \obsolete @@ -1813,6 +1814,7 @@ QTextStream& operator>>(QTextStream& ts, QSplitter& splitter) splitter.restoreState(std::move(line).toLatin1()); return ts; } +#endif QT_END_NAMESPACE diff --git a/src/widgets/widgets/qsplitter.h b/src/widgets/widgets/qsplitter.h index 16fac48d1c..ec980d9ee3 100644 --- a/src/widgets/widgets/qsplitter.h +++ b/src/widgets/widgets/qsplitter.h @@ -129,8 +129,12 @@ private: friend class QSplitterHandle; }; +#if QT_DEPRECATED_SINCE(5, 13) +QT_DEPRECATED_X("Use QSplitter::saveState() instead") Q_WIDGETS_EXPORT QTextStream& operator<<(QTextStream&, const QSplitter&); +QT_DEPRECATED_X("Use QSplitter::restoreState() instead") Q_WIDGETS_EXPORT QTextStream& operator>>(QTextStream&, QSplitter&); +#endif class QSplitterHandlePrivate; class Q_WIDGETS_EXPORT QSplitterHandle : public QWidget From edc455c69b7a938f7a7ce98b5b0ffd1398f239c6 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Sat, 26 Jan 2019 11:50:33 +0100 Subject: [PATCH 1057/1650] QtWidgets: mark QDialog/QFileDialog functions as deprecated Mark some long obsolete functions as deprecated so the can be removed with Qt6: - QDialog::setOrientation()/orientation() - QDialog::setExtension()/extension()/showExtension() - QFileDialog::setNameFilterDetailsVisible()/isNameFilterDetailsVisible() - QFileDialog::setResolveSymlinks()/resolveSymlinks() Change-Id: Ibbd5b4192ea8ab483d6b2a8dbf9879f29f9ee86d Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> --- src/widgets/dialogs/qdialog.cpp | 3 ++- src/widgets/dialogs/qdialog.h | 15 +++++++++------ src/widgets/dialogs/qfiledialog.cpp | 4 ++++ src/widgets/dialogs/qfiledialog.h | 12 +++++++++++- .../dialogs/qfiledialog/tst_qfiledialog.cpp | 6 +++--- .../dialogs/qfiledialog2/tst_qfiledialog2.cpp | 6 +++--- tests/manual/dialogs/filedialogpanel.cpp | 2 +- 7 files changed, 33 insertions(+), 15 deletions(-) diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp index cc04110a30..efd2c2ffea 100644 --- a/src/widgets/dialogs/qdialog.cpp +++ b/src/widgets/dialogs/qdialog.cpp @@ -946,6 +946,7 @@ void QDialog::adjustPosition(QWidget* w) move(p); } +#if QT_DEPRECATED_SINCE(5, 13) /*! \obsolete @@ -1090,7 +1091,7 @@ void QDialog::showExtension(bool showIt) #endif } } - +#endif /*! \reimp */ QSize QDialog::sizeHint() const diff --git a/src/widgets/dialogs/qdialog.h b/src/widgets/dialogs/qdialog.h index 7f267dd939..ce57ce5de7 100644 --- a/src/widgets/dialogs/qdialog.h +++ b/src/widgets/dialogs/qdialog.h @@ -69,11 +69,12 @@ public: void setVisible(bool visible) override; - void setOrientation(Qt::Orientation orientation); - Qt::Orientation orientation() const; - - void setExtension(QWidget* extension); - QWidget* extension() const; +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED void setOrientation(Qt::Orientation orientation); + QT_DEPRECATED Qt::Orientation orientation() const; + QT_DEPRECATED void setExtension(QWidget* extension); + QT_DEPRECATED QWidget* extension() const; +#endif QSize sizeHint() const override; QSize minimumSizeHint() const override; @@ -96,7 +97,9 @@ public Q_SLOTS: virtual void accept(); virtual void reject(); - void showExtension(bool); +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED void showExtension(bool); +#endif protected: QDialog(QDialogPrivate &, QWidget *parent, Qt::WindowFlags f = Qt::WindowFlags()); diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index edaa7854ba..f42cf89708 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -1359,6 +1359,7 @@ void QFileDialog::setNameFilter(const QString &filter) } +#if QT_DEPRECATED_SINCE(5, 13) /*! \property QFileDialog::nameFilterDetailsVisible \obsolete @@ -1380,6 +1381,7 @@ bool QFileDialog::isNameFilterDetailsVisible() const { return !testOption(HideNameFilterDetails); } +#endif /* @@ -1879,6 +1881,7 @@ bool QFileDialog::isReadOnly() const return testOption(ReadOnly); } +#if QT_DEPRECATED_SINCE(5, 13) /*! \property QFileDialog::resolveSymlinks \obsolete @@ -1899,6 +1902,7 @@ bool QFileDialog::resolveSymlinks() const { return !testOption(DontResolveSymlinks); } +#endif /*! \property QFileDialog::confirmOverwrite diff --git a/src/widgets/dialogs/qfiledialog.h b/src/widgets/dialogs/qfiledialog.h index a4d289a77a..8a99112081 100644 --- a/src/widgets/dialogs/qfiledialog.h +++ b/src/widgets/dialogs/qfiledialog.h @@ -65,11 +65,13 @@ class Q_WIDGETS_EXPORT QFileDialog : public QDialog Q_PROPERTY(FileMode fileMode READ fileMode WRITE setFileMode) Q_PROPERTY(AcceptMode acceptMode READ acceptMode WRITE setAcceptMode) Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly DESIGNABLE false) - Q_PROPERTY(bool resolveSymlinks READ resolveSymlinks WRITE setResolveSymlinks DESIGNABLE false) Q_PROPERTY(bool confirmOverwrite READ confirmOverwrite WRITE setConfirmOverwrite DESIGNABLE false) Q_PROPERTY(QString defaultSuffix READ defaultSuffix WRITE setDefaultSuffix) +#if QT_DEPRECATED_SINCE(5, 13) + Q_PROPERTY(bool resolveSymlinks READ resolveSymlinks WRITE setResolveSymlinks DESIGNABLE false) Q_PROPERTY(bool nameFilterDetailsVisible READ isNameFilterDetailsVisible WRITE setNameFilterDetailsVisible DESIGNABLE false) +#endif Q_PROPERTY(Options options READ options WRITE setOptions) Q_PROPERTY(QStringList supportedSchemes READ supportedSchemes WRITE setSupportedSchemes) @@ -117,8 +119,12 @@ public: void selectUrl(const QUrl &url); QList<QUrl> selectedUrls() const; +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X("Use setOption(HideNameFilterDetails, !enabled) instead") void setNameFilterDetailsVisible(bool enabled); + QT_DEPRECATED_X("Use !testOption(HideNameFilterDetails) instead") bool isNameFilterDetailsVisible() const; +#endif void setNameFilter(const QString &filter); void setNameFilters(const QStringList &filters); @@ -148,8 +154,12 @@ public: void setReadOnly(bool enabled); bool isReadOnly() const; +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X("Use setOption(DontResolveSymlinks, !enabled) instead") void setResolveSymlinks(bool enabled); + QT_DEPRECATED_X("Use !testOption(DontResolveSymlinks) instead") bool resolveSymlinks() const; +#endif void setSidebarUrls(const QList<QUrl> &urls); QList<QUrl> sidebarUrls() const; diff --git a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp index ae8e4f7e04..9668c82ef2 100644 --- a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp @@ -854,9 +854,9 @@ void tst_QFiledialog::resolveSymlinks() // default QCOMPARE(fd.resolveSymlinks(), true); - fd.setResolveSymlinks(false); + fd.setOption(QFileDialog::DontResolveSymlinks, true); QCOMPARE(fd.resolveSymlinks(), false); - fd.setResolveSymlinks(true); + fd.setOption(QFileDialog::DontResolveSymlinks, false); QCOMPARE(fd.resolveSymlinks(), true); // the file dialog doesn't do anything based upon this, just passes it to the model @@ -1119,7 +1119,7 @@ void tst_QFiledialog::setNameFilter() QFileDialog fd; fd.setNameFilters(filters); - fd.setNameFilterDetailsVisible(nameFilterDetailsVisible); + fd.setOption(QFileDialog::HideNameFilterDetails, !nameFilterDetailsVisible); fd.selectNameFilter(selectFilter); QCOMPARE(fd.selectedNameFilter(), expectedSelectedFilter); } diff --git a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp index 24ce598279..20fc7c9a6c 100644 --- a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp +++ b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp @@ -252,7 +252,7 @@ void tst_QFileDialog2::showNameFilterDetails() QFileDialog fd; QComboBox *filters = fd.findChild<QComboBox*>("fileTypeCombo"); QVERIFY(filters); - QVERIFY(fd.isNameFilterDetailsVisible()); + QVERIFY(!fd.testOption(QFileDialog::HideNameFilterDetails)); QStringList filterChoices; @@ -261,12 +261,12 @@ void tst_QFileDialog2::showNameFilterDetails() << "Any files (*.*)"; fd.setNameFilters(filterChoices); - fd.setNameFilterDetailsVisible(false); + fd.setOption(QFileDialog::HideNameFilterDetails, true); QCOMPARE(filters->itemText(0), QString("Image files")); QCOMPARE(filters->itemText(1), QString("Text files")); QCOMPARE(filters->itemText(2), QString("Any files")); - fd.setNameFilterDetailsVisible(true); + fd.setOption(QFileDialog::HideNameFilterDetails, false); QCOMPARE(filters->itemText(0), filterChoices.at(0)); QCOMPARE(filters->itemText(1), filterChoices.at(1)); QCOMPARE(filters->itemText(2), filterChoices.at(2)); diff --git a/tests/manual/dialogs/filedialogpanel.cpp b/tests/manual/dialogs/filedialogpanel.cpp index 9e3c761cff..e628dd2265 100644 --- a/tests/manual/dialogs/filedialogpanel.cpp +++ b/tests/manual/dialogs/filedialogpanel.cpp @@ -439,7 +439,7 @@ void FileDialogPanel::restoreDefaults() m_showDirsOnly->setChecked(d.testOption(QFileDialog::ShowDirsOnly)); m_allowedSchemes->setText(QString()); m_confirmOverWrite->setChecked(d.confirmOverwrite()); - m_nameFilterDetailsVisible->setChecked(d.isNameFilterDetailsVisible()); + m_nameFilterDetailsVisible->setChecked(!d.testOption(QFileDialog::HideNameFilterDetails)); m_resolveSymLinks->setChecked(d.resolveSymlinks()); m_readOnly->setChecked(d.isReadOnly()); m_native->setChecked(true); From c0ebec51e3dd1b52767878fe7fd56ce6e8f95461 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis <gatis.paeglis@qt.io> Date: Wed, 16 Jan 2019 15:12:16 +0800 Subject: [PATCH 1058/1650] xcb: respect big-request encoding in max request size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From big-request specification: "This extension defines a mechanism for extending the length field beyond 16 bits. If the normal 16-bit length field of the protocol request is zero, then an additional 32-bit field containing the actual length (in 4-byte units) is inserted into the request, immediately following the 16-bit length field." Meaning that the request requires 4 additional bytes. This patch provides a convenience API for calculating maximum request data size. Besides fixing QTBUG-73044, it was also discovered that calculations for xcb_image_put (in QXcbBackingStoreImage::flushPixmap) were wrong. The code assumed that xcb_get_maximum_request_length() returns bytes, but what it actually returns is length which is measured in four-byte units. This means that we were sending 4x less bytes than allowed by the protocol. Furthermore, use the actual 'stride' (bytes per line) value when calculating rows_per_put. The new stride value was introduced by 760b2929a3b268e2edf14a561329bdb78fbdc26e, but was not updated in rows_per_put calculations. Fixes: QTBUG-73044 Done-with: JiDe Zhang <zccrs@live.com> Done-with: Mikhail Svetkin <mikhail.svetkin@qt.io> Change-Id: I06beb6082da3e8bc78225a87603914e796fe5878 Reviewed-by: Błażej Szczygieł <spaz16@wp.pl> Reviewed-by: JiDe Zhang <zccrs@live.com> Reviewed-by: Mikhail Svetkin <mikhail.svetkin@qt.io> Reviewed-by: Uli Schlachter <psychon@znc.in> Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io> --- .../platforms/xcb/qxcbbackingstore.cpp | 17 +++++++------- src/plugins/platforms/xcb/qxcbclipboard.cpp | 23 +++++++------------ src/plugins/platforms/xcb/qxcbclipboard.h | 4 ++-- src/plugins/platforms/xcb/qxcbconnection.h | 2 +- .../platforms/xcb/qxcbconnection_basic.cpp | 14 +++++++++++ .../platforms/xcb/qxcbconnection_basic.h | 5 ++++ 6 files changed, 39 insertions(+), 26 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index f9240a45cc..741317d766 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -641,17 +641,17 @@ void QXcbBackingStoreImage::flushPixmap(const QRegion ®ion, bool fullRegion) xcb_subimage.bit_order = m_xcb_image->bit_order; const bool needsByteSwap = xcb_subimage.byte_order != m_xcb_image->byte_order; + // Ensure that we don't send more than maxPutImageRequestDataBytes per request. + const auto maxPutImageRequestDataBytes = connection()->maxRequestDataBytes(sizeof(xcb_put_image_request_t)); for (const QRect &rect : region) { - // We must make sure that each request is not larger than max_req_size. - // Each request takes req_size + m_xcb_image->stride * height bytes. - static const uint32_t req_size = sizeof(xcb_put_image_request_t); - const uint32_t max_req_size = xcb_get_maximum_request_length(xcb_connection()); - const int rows_per_put = (max_req_size - req_size) / m_xcb_image->stride; + const quint32 stride = round_up_scanline(rect.width() * m_qimage.depth(), xcb_subimage.scanline_pad) >> 3; + const int rows_per_put = maxPutImageRequestDataBytes / stride; // This assert could trigger if a single row has more pixels than fit in - // a single PutImage request. However, max_req_size is guaranteed to be - // at least 16384 bytes. That should be enough for quite large images. + // a single PutImage request. In the absence of the BIG-REQUESTS extension + // the theoretical maximum lengths of maxPutImageRequestDataBytes can be + // roughly 256kB. Q_ASSERT(rows_per_put > 0); // If we upload the whole image in a single chunk, the result might be @@ -666,9 +666,10 @@ void QXcbBackingStoreImage::flushPixmap(const QRegion ®ion, bool fullRegion) while (height > 0) { const int rows = std::min(height, rows_per_put); const QRect subRect(x, y, width, rows); - const quint32 stride = round_up_scanline(width * m_qimage.depth(), xcb_subimage.scanline_pad) >> 3; const QImage subImage = native_sub_image(&m_flushBuffer, stride, m_qimage, subRect, needsByteSwap); + Q_ASSERT(static_cast<size_t>(subImage.sizeInBytes()) <= maxPutImageRequestDataBytes); + xcb_subimage.width = width; xcb_subimage.height = rows; xcb_subimage.data = const_cast<uint8_t *>(subImage.constBits()); diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp index ac8b029916..2cb6720d40 100644 --- a/src/plugins/platforms/xcb/qxcbclipboard.cpp +++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp @@ -240,8 +240,8 @@ QXcbClipboard::QXcbClipboard(QXcbConnection *c) xcb_xfixes_select_selection_input_checked(xcb_connection(), m_owner, atom(QXcbAtom::CLIPBOARD), mask); } - // change property protocol request is 24 bytes - m_increment = (xcb_get_maximum_request_length(xcb_connection()) * 4) - 24; + // xcb_change_property_request_t and xcb_get_property_request_t are the same size + m_maxPropertyRequestDataBytes = connection()->maxRequestDataBytes(sizeof(xcb_change_property_request_t)); } QXcbClipboard::~QXcbClipboard() @@ -486,7 +486,7 @@ xcb_atom_t QXcbClipboard::sendSelection(QMimeData *d, xcb_atom_t target, xcb_win if (m_clipboard_closing) allow_incr = false; - if (data.size() > m_increment && allow_incr) { + if (data.size() > m_maxPropertyRequestDataBytes && allow_incr) { long bytes = data.size(); xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, window, property, atom(QXcbAtom::INCR), 32, 1, (const void *)&bytes); @@ -496,7 +496,7 @@ xcb_atom_t QXcbClipboard::sendSelection(QMimeData *d, xcb_atom_t target, xcb_win } // make sure we can perform the XChangeProperty in a single request - if (data.size() > m_increment) + if (data.size() > m_maxPropertyRequestDataBytes) return XCB_NONE; // ### perhaps use several XChangeProperty calls w/ PropModeAppend? int dataSize = data.size() / (dataFormat / 8); // use a single request to transfer data @@ -678,17 +678,8 @@ void QXcbClipboard::handleXFixesSelectionRequest(xcb_xfixes_selection_notify_eve emitChanged(mode); } - -static inline int maxSelectionIncr(xcb_connection_t *c) -{ - int l = xcb_get_maximum_request_length(c); - return (l > 65536 ? 65536*4 : l*4) - 100; -} - bool QXcbClipboard::clipboardReadProperty(xcb_window_t win, xcb_atom_t property, bool deleteProperty, QByteArray *buffer, int *size, xcb_atom_t *type, int *format) { - int maxsize = maxSelectionIncr(xcb_connection()); - ulong bytes_left; // bytes_after xcb_atom_t dummy_type; int dummy_format; @@ -705,7 +696,8 @@ bool QXcbClipboard::clipboardReadProperty(xcb_window_t win, xcb_atom_t property, } *type = reply->type; *format = reply->format; - bytes_left = reply->bytes_after; + + auto bytes_left = reply->bytes_after; int offset = 0, buffer_offset = 0; @@ -720,7 +712,8 @@ bool QXcbClipboard::clipboardReadProperty(xcb_window_t win, xcb_atom_t property, while (bytes_left) { // more to read... - reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(), false, win, property, XCB_GET_PROPERTY_TYPE_ANY, offset, maxsize/4); + reply = Q_XCB_REPLY(xcb_get_property, xcb_connection(), false, win, property, + XCB_GET_PROPERTY_TYPE_ANY, offset, m_maxPropertyRequestDataBytes / 4); if (!reply || reply->type == XCB_NONE) break; diff --git a/src/plugins/platforms/xcb/qxcbclipboard.h b/src/plugins/platforms/xcb/qxcbclipboard.h index 26d3b3b395..51ae0dc1ee 100644 --- a/src/plugins/platforms/xcb/qxcbclipboard.h +++ b/src/plugins/platforms/xcb/qxcbclipboard.h @@ -113,7 +113,7 @@ public: xcb_window_t getSelectionOwner(xcb_atom_t atom) const; QByteArray getSelection(xcb_atom_t selection, xcb_atom_t target, xcb_atom_t property, xcb_timestamp_t t = 0); - int increment() const { return m_increment; } + int increment() const { return m_maxPropertyRequestDataBytes; } int clipboardTimeout() const { return clipboard_timeout; } void removeTransaction(xcb_window_t window) { m_transactions.remove(window); } @@ -137,7 +137,7 @@ private: static const int clipboard_timeout; - int m_increment = 0; + int m_maxPropertyRequestDataBytes = 0; bool m_clipboard_closing = false; xcb_timestamp_t m_incr_receive_time = 0; diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index d63888b48f..0e3ecd135b 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -245,7 +245,7 @@ public: void flush() { xcb_flush(xcb_connection()); } void processXcbEvents(QEventLoop::ProcessEventsFlags flags); - QTimer &focusInTimer() { return m_focusInTimer; }; + QTimer &focusInTimer() { return m_focusInTimer; } protected: bool event(QEvent *e) override; diff --git a/src/plugins/platforms/xcb/qxcbconnection_basic.cpp b/src/plugins/platforms/xcb/qxcbconnection_basic.cpp index af72285135..9a028e5a7e 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_basic.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_basic.cpp @@ -134,6 +134,7 @@ QXcbBasicConnection::QXcbBasicConnection(const char *displayName) m_setup = xcb_get_setup(m_xcbConnection); m_xcbAtom.initialize(m_xcbConnection); + m_maximumRequestLength = xcb_get_maximum_request_length(m_xcbConnection); xcb_extension_t *extensions[] = { &xcb_shm_id, &xcb_xfixes_id, &xcb_randr_id, &xcb_shape_id, &xcb_sync_id, @@ -178,6 +179,14 @@ QXcbBasicConnection::~QXcbBasicConnection() } } +size_t QXcbBasicConnection::maxRequestDataBytes(size_t requestSize) const +{ + if (hasBigRequest()) + requestSize += 4; // big-request encoding adds 4 bytes + + return m_maximumRequestLength * 4 - requestSize; +} + xcb_atom_t QXcbBasicConnection::internAtom(const char *name) { if (!name || *name == 0) @@ -199,6 +208,11 @@ QByteArray QXcbBasicConnection::atomName(xcb_atom_t atom) return QByteArray(); } +bool QXcbBasicConnection::hasBigRequest() const +{ + return m_maximumRequestLength > m_setup->maximum_request_length; +} + #if QT_CONFIG(xcb_xinput) // Starting from the xcb version 1.9.3 struct xcb_ge_event_t has changed: // - "pad0" became "extension" diff --git a/src/plugins/platforms/xcb/qxcbconnection_basic.h b/src/plugins/platforms/xcb/qxcbconnection_basic.h index ca91f7fa45..3691763398 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_basic.h +++ b/src/plugins/platforms/xcb/qxcbconnection_basic.h @@ -73,6 +73,8 @@ public: } const xcb_setup_t *setup() const { return m_setup; } + size_t maxRequestDataBytes(size_t requestSize) const; + inline xcb_atom_t atom(QXcbAtom::Atom qatom) const { return m_xcbAtom.atom(qatom); } QXcbAtom::Atom qatom(xcb_atom_t atom) const { return m_xcbAtom.qatom(atom); } xcb_atom_t internAtom(const char *name); @@ -94,6 +96,7 @@ public: bool hasShmFd() const { return m_hasShmFd; } bool hasXSync() const { return m_hasXSync; } bool hasXinerama() const { return m_hasXinerama; } + bool hasBigRequest() const; #if QT_CONFIG(xcb_xinput) bool isAtLeastXI21() const { return m_xi2Enabled && m_xi2Minor >= 1; } @@ -152,6 +155,8 @@ private: uint32_t m_xfixesFirstEvent = 0; uint32_t m_xrandrFirstEvent = 0; uint32_t m_xkbFirstEvent = 0; + + uint32_t m_maximumRequestLength = 0; }; #define Q_XCB_REPLY_CONNECTION_ARG(connection, ...) connection From 27065bdc50fb3163f41d65ff70653aac8ca19094 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis <gatis.paeglis@qt.io> Date: Wed, 23 Jan 2019 14:02:38 +0100 Subject: [PATCH 1059/1650] ibus: allow filterEvent() from QWindowSystemEventHandler::sendEvent() The async mode, which is also default mode will recurs if QIBusPlatformInputContext::filterEvent() is called from QWindowSystemEventHandler::sendEvent() callback. The sync mode works fine without this patch. Modes can be toggled via IBUS_ENABLE_SYNC_MODE envvar. Removed redundant #ifndef and renamed one variable to something more meaningful. Change-Id: I8773445cef10212464cff09e3a70487fb38ac3fd Reviewed-by: Takao Fujiwara <takao.fujiwara1@gmail.com> Reviewed-by: Lars Knoll <lars.knoll@qt.io> --- .../ibus/qibusplatforminputcontext.cpp | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp index c0979e7864..98362f2116 100644 --- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp +++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp @@ -47,7 +47,9 @@ #include <qpa/qplatformcursor.h> #include <qpa/qplatformscreen.h> -#include <qpa/qwindowsysteminterface.h> +#include <qpa/qwindowsysteminterface_p.h> + +#include <QtGui/private/qguiapplication_p.h> #include "qibusproxy.h" #include "qibusproxyportal.h" @@ -419,9 +421,9 @@ bool QIBusPlatformInputContext::filterEvent(const QEvent *event) QDBusPendingReply<bool> reply = d->context->ProcessKeyEvent(sym, code - 8, ibusState); if (m_eventFilterUseSynchronousMode || reply.isFinished()) { - bool retval = reply.value(); - qCDebug(qtQpaInputMethods) << "filterEvent return" << code << sym << state << retval; - return retval; + bool filtered = reply.value(); + qCDebug(qtQpaInputMethods) << "filterEvent return" << code << sym << state << filtered; + return filtered; } Qt::KeyboardModifiers modifiers = keyEvent->modifiers(); @@ -491,23 +493,22 @@ void QIBusPlatformInputContext::filterEventFinished(QDBusPendingCallWatcher *cal const bool isAutoRepeat = args.at(7).toBool(); // copied from QXcbKeyboard::handleKeyEvent() - bool retval = reply.value(); - qCDebug(qtQpaInputMethods) << "filterEventFinished return" << code << sym << state << retval; - if (!retval) { + bool filtered = reply.value(); + qCDebug(qtQpaInputMethods) << "filterEventFinished return" << code << sym << state << filtered; + if (!filtered) { #ifndef QT_NO_CONTEXTMENU if (type == QEvent::KeyPress && qtcode == Qt::Key_Menu && window != NULL) { const QPoint globalPos = window->screen()->handle()->cursor()->pos(); const QPoint pos = window->mapFromGlobal(globalPos); -#ifndef QT_NO_CONTEXTMENU - QWindowSystemInterface::handleContextMenuEvent(window, false, pos, - globalPos, modifiers); -#endif + QWindowSystemInterfacePrivate::ContextMenuEvent contextMenuEvent(window, false, pos, + globalPos, modifiers); + QGuiApplicationPrivate::processWindowSystemEvent(&contextMenuEvent); } -#endif // QT_NO_CONTEXTMENU - QWindowSystemInterface::handleExtendedKeyEvent(window, time, type, qtcode, modifiers, - code, sym, state, string, isAutoRepeat); - +#endif + QWindowSystemInterfacePrivate::KeyEvent keyEvent(window, time, type, qtcode, modifiers, + code, sym, state, string, isAutoRepeat); + QGuiApplicationPrivate::processWindowSystemEvent(&keyEvent); } call->deleteLater(); } From a6f25dedd8fc7fa6053a6a1b98dc0548f3559db6 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint <Friedemann.Kleint@qt.io> Date: Tue, 5 Feb 2019 16:29:01 +0100 Subject: [PATCH 1060/1650] Windows style, themes: Fix deprecation warnings Fix: qwindowstheme.cpp:287:77: warning: 'const QBrush& QPalette::background() const' is deprecated: Use QPalette::window() instead [-Wdeprecated-declarations] qwindowstheme.cpp:336:37: warning: 'const QBrush& QPalette::foreground() const' is deprecated: Use QPalette::windowText() instead [-Wdeprecated-declarations] qwindowstheme.cpp:861:102: warning: 'static bool QPixmapCache::find(const QString&, QPixmap&)' is deprecated: Use bool find(const QString &, QPixmap *) instead [-Wdeprecated-declarations] qwindowsvistastyle.cpp:635:56: warning: 'const QBrush& QPalette::background() const' is deprecated: Use QPalette::window() instead [-Wdeprecated-declarations] qwindowsvistastyle.cpp:707:60: warning: 'static bool QPixmapCache::find(const QString&, QPixmap&)' is deprecated: Use bool find(const QString &, QPixmap *) instead [-Wdeprecated-declarations] qwindowsxpstyle.cpp:743:58: warning: 'const QMatrix& QPainter::deviceMatrix() const' is deprecated: Use deviceTransform() instead [-Wdeprecated-declarations] qwindowsinputcontext.cpp:448:49: warning: 'const QBrush& QPalette::background() const' is deprecated: Use QPalette::window() instead [-Wdeprecated-declarations] Change-Id: I00a52a27b066caeb135ad4124f71ef3e09beafbf Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de> --- .../windows/qwindowsinputcontext.cpp | 2 +- .../platforms/windows/qwindowstheme.cpp | 19 ++++++++++--------- .../windowsvista/qwindowsvistastyle.cpp | 12 ++++++------ .../styles/windowsvista/qwindowsxpstyle.cpp | 5 +++-- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp index d1e99c037b..2353afdd6a 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp @@ -445,7 +445,7 @@ static inline QTextFormat standardFormat(StandardFormat format) const QPalette palette = QGuiApplication::palette(); const QColor background = palette.text().color(); result.setBackground(QBrush(background)); - result.setForeground(palette.background()); + result.setForeground(palette.window()); break; } } diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index 4b70e915a8..137ac98899 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -284,24 +284,24 @@ static inline QPalette systemPalette() result.setColor(QPalette::Link, Qt::blue); result.setColor(QPalette::LinkVisited, Qt::magenta); result.setColor(QPalette::Inactive, QPalette::Button, result.button().color()); - result.setColor(QPalette::Inactive, QPalette::Window, result.background().color()); + result.setColor(QPalette::Inactive, QPalette::Window, result.window().color()); result.setColor(QPalette::Inactive, QPalette::Light, result.light().color()); result.setColor(QPalette::Inactive, QPalette::Dark, result.dark().color()); if (result.midlight() == result.button()) result.setColor(QPalette::Midlight, result.button().color().lighter(110)); - if (result.background() != result.base()) { + if (result.window() != result.base()) { result.setColor(QPalette::Inactive, QPalette::Highlight, result.color(QPalette::Inactive, QPalette::Window)); result.setColor(QPalette::Inactive, QPalette::HighlightedText, result.color(QPalette::Inactive, QPalette::Text)); } const QColor disabled = - mixColors(result.foreground().color(), result.button().color()); + mixColors(result.windowText().color(), result.button().color()); - result.setColorGroup(QPalette::Disabled, result.foreground(), result.button(), + result.setColorGroup(QPalette::Disabled, result.windowText(), result.button(), result.light(), result.dark(), result.mid(), result.text(), result.brightText(), result.base(), - result.background()); + result.window()); result.setColor(QPalette::Disabled, QPalette::WindowText, disabled); result.setColor(QPalette::Disabled, QPalette::Text, disabled); result.setColor(QPalette::Disabled, QPalette::ButtonText, disabled); @@ -310,7 +310,7 @@ static inline QPalette systemPalette() result.setColor(QPalette::Disabled, QPalette::HighlightedText, getSysColor(COLOR_HIGHLIGHTTEXT)); result.setColor(QPalette::Disabled, QPalette::Base, - result.background().color()); + result.window().color()); return result; } @@ -333,7 +333,7 @@ static inline QPalette toolTipPalette(const QPalette &systemPalette) result.setColor(QPalette::All, QPalette::ToolTipBase, tipBgColor); result.setColor(QPalette::All, QPalette::ToolTipText, tipTextColor); const QColor disabled = - mixColors(result.foreground().color(), result.button().color()); + mixColors(result.windowText().color(), result.button().color()); result.setColor(QPalette::Disabled, QPalette::WindowText, disabled); result.setColor(QPalette::Disabled, QPalette::Text, disabled); result.setColor(QPalette::Disabled, QPalette::ToolTipText, disabled); @@ -858,7 +858,8 @@ QPixmap QWindowsFileIconEngine::filePixmap(const QSize &size, QIcon::Mode, QIcon int iIcon = (useDefaultFolderIcon && defaultFolderIIcon >= 0) ? defaultFolderIIcon : **dirIconEntryCache.object(filePath); if (iIcon) { - QPixmapCache::find(dirIconPixmapCacheKey(iIcon, iconSize, requestedImageListSize), pixmap); + QPixmapCache::find(dirIconPixmapCacheKey(iIcon, iconSize, requestedImageListSize), + &pixmap); if (pixmap.isNull()) // Let's keep both caches in sync dirIconEntryCache.remove(filePath); else @@ -889,7 +890,7 @@ QPixmap QWindowsFileIconEngine::filePixmap(const QSize &size, QIcon::Mode, QIcon //using the unique icon index provided by windows save us from duplicate keys key = dirIconPixmapCacheKey(info.iIcon, iconSize, requestedImageListSize); - QPixmapCache::find(key, pixmap); + QPixmapCache::find(key, &pixmap); if (!pixmap.isNull()) { QMutexLocker locker(&mx); dirIconEntryCache.insert(filePath, FakePointer<int>::create(info.iIcon)); diff --git a/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp b/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp index 771552a121..8a3ae17b1d 100644 --- a/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp +++ b/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp @@ -632,7 +632,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt { QPen pen = painter->pen(); int margin = 3; - painter->setPen(option->palette.background().color().darker(114)); + painter->setPen(option->palette.window().color().darker(114)); if (option->state & State_Horizontal) { int x1 = option->rect.center().x(); painter->drawLine(QPoint(x1, option->rect.top() + margin), QPoint(x1, option->rect.bottom() - margin)); @@ -704,7 +704,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt if (sectionSize.width() > 0 && sectionSize.height() > 0) { QString key = QString::fromLatin1("qvdelegate-%1-%2-%3-%4-%5").arg(sectionSize.width()) .arg(sectionSize.height()).arg(selected).arg(active).arg(hover); - if (!QPixmapCache::find(key, pixmap)) { + if (!QPixmapCache::find(key, &pixmap)) { pixmap = QPixmap(sectionSize); pixmap.fill(Qt::transparent); @@ -1053,7 +1053,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption } QString name = QString::fromLatin1("qiprogress-%1-%2").arg(pixmapSize.width()).arg(pixmapSize.height()); QPixmap pixmap; - if (!QPixmapCache::find(name, pixmap)) { + if (!QPixmapCache::find(name, &pixmap)) { QImage image(pixmapSize, QImage::Format_ARGB32); image.fill(Qt::transparent); QPainter imagePainter(&image); @@ -1363,7 +1363,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption case CE_ToolBar: if (const QStyleOptionToolBar *toolbar = qstyleoption_cast<const QStyleOptionToolBar *>(option)) { QPalette pal = option->palette; - pal.setColor(QPalette::Dark, option->palette.background().color().darker(130)); + pal.setColor(QPalette::Dark, option->palette.window().color().darker(130)); QStyleOptionToolBar copyOpt = *toolbar; copyOpt.palette = pal; QWindowsStyle::drawControl(element, ©Opt, painter, widget); @@ -1388,8 +1388,8 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption painter->translate(-rect.left() + 1, -rect.top()); } - painter->setBrush(option->palette.background().color().darker(110)); - painter->setPen(option->palette.background().color().darker(130)); + painter->setBrush(option->palette.window().color().darker(110)); + painter->setPen(option->palette.window().color().darker(130)); painter->drawRect(rect.adjusted(0, 1, -1, -3)); int buttonMargin = 4; diff --git a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp index 43e8b37f71..90026e5bf0 100644 --- a/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp +++ b/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp @@ -740,7 +740,8 @@ bool QWindowsXPStylePrivate::drawBackgroundDirectly(HDC dc, XPThemeData &themeDa { QPainter *painter = themeData.painter; - const QPointF redirectionDelta(painter->deviceMatrix().dx(), painter->deviceMatrix().dy()); + const auto deviceTransform = painter->deviceTransform(); + const QPointF redirectionDelta(deviceTransform.dx(), deviceTransform.dy()); const QRect area = scaleRect(QRectF(themeData.rect), additionalDevicePixelRatio).translated(redirectionDelta).toRect(); QRegion sysRgn = painter->paintEngine()->systemClip(); @@ -835,7 +836,7 @@ bool QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeDa alphaType = data.alphaType; potentialInvalidAlpha = data.hadInvalidAlpha; - haveCachedPixmap = QPixmapCache::find(pixmapCacheKey, cachedPixmap); + haveCachedPixmap = QPixmapCache::find(pixmapCacheKey, &cachedPixmap); #ifdef DEBUG_XP_STYLE char buf[25]; From 0d3b913da78ce3e0b5905759f958a91eba030c4f Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen <allan.jensen@qt.io> Date: Thu, 31 Jan 2019 11:58:26 +0100 Subject: [PATCH 1061/1650] Switch epilogues of AVX2 conversions to single step Not only is it fewer instructions but all the logic except for load and store can be identical to the main loop. Change-Id: I2caac0c7504d94e404bd8cfe5080aff07ba2d465 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> --- src/gui/painting/qdrawhelper_avx2.cpp | 158 +++++++++++++------------- 1 file changed, 79 insertions(+), 79 deletions(-) diff --git a/src/gui/painting/qdrawhelper_avx2.cpp b/src/gui/painting/qdrawhelper_avx2.cpp index 4a3e24d6d5..f05cc0926e 100644 --- a/src/gui/painting/qdrawhelper_avx2.cpp +++ b/src/gui/painting/qdrawhelper_avx2.cpp @@ -995,16 +995,11 @@ void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper_avx2(uint * } } -static inline __m128i maskFromCount(qsizetype count) +static inline __m256i epilogueMaskFromCount(qsizetype count) { Q_ASSERT(count > 0); - static const qint64 data[] = { -1, -1, 0, 0 }; - auto ptr = reinterpret_cast<const quint8 *>(data) + sizeof(__m128i); - - if (count > int(sizeof(__m128i))) - return _mm_set1_epi8(-1); - - return _mm_loadu_si128(reinterpret_cast<const __m128i *>(ptr - count)); + static const __m256i offsetMask = _mm256_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7); + return _mm256_add_epi32(offsetMask, _mm256_set1_epi32(-count)); } template<bool RGBA> @@ -1050,40 +1045,39 @@ static void convertARGBToARGB32PM_avx2(uint *buffer, const uint *src, qsizetype } } - for ( ; i < count; i += 4) { - __m128i maskedAlphaMask = _mm256_castsi256_si128(alphaMask); - __m128i mask = maskFromCount((count - i) * sizeof(*src)); - maskedAlphaMask = _mm_and_si128(mask, maskedAlphaMask); - __m128i srcVector = _mm_maskload_epi32(reinterpret_cast<const int *>(src + i), mask); + if (i < count) { + const __m256i epilogueMask = epilogueMaskFromCount(count - i); + __m256i srcVector = _mm256_maskload_epi32(reinterpret_cast<const int *>(src + i), epilogueMask); + const __m256i epilogueAlphaMask = _mm256_blendv_epi8(_mm256_setzero_si256(), alphaMask, epilogueMask); - if (!_mm_testz_si128(srcVector, maskedAlphaMask)) { + if (!_mm256_testz_si256(srcVector, epilogueAlphaMask)) { // keep the two _mm_test[zc]_siXXX next to each other - bool cf = _mm_testc_si128(srcVector, maskedAlphaMask); + bool cf = _mm256_testc_si256(srcVector, epilogueAlphaMask); if (RGBA) - srcVector = _mm_shuffle_epi8(srcVector, _mm256_castsi256_si128(rgbaMask)); + srcVector = _mm256_shuffle_epi8(srcVector, rgbaMask); if (!cf) { - __m128i src1 = _mm_unpacklo_epi8(srcVector, _mm256_castsi256_si128(zero)); - __m128i src2 = _mm_unpackhi_epi8(srcVector, _mm256_castsi256_si128(zero)); - __m128i alpha1 = _mm_shuffle_epi8(src1, _mm256_castsi256_si128(shuffleMask)); - __m128i alpha2 = _mm_shuffle_epi8(src2, _mm256_castsi256_si128(shuffleMask)); - src1 = _mm_mullo_epi16(src1, alpha1); - src2 = _mm_mullo_epi16(src2, alpha2); - src1 = _mm_add_epi16(src1, _mm_srli_epi16(src1, 8)); - src2 = _mm_add_epi16(src2, _mm_srli_epi16(src2, 8)); - src1 = _mm_add_epi16(src1, _mm256_castsi256_si128(half)); - src2 = _mm_add_epi16(src2, _mm256_castsi256_si128(half)); - src1 = _mm_srli_epi16(src1, 8); - src2 = _mm_srli_epi16(src2, 8); - src1 = _mm_blend_epi16(src1, alpha1, 0x88); - src2 = _mm_blend_epi16(src2, alpha2, 0x88); - srcVector = _mm_packus_epi16(src1, src2); - _mm_maskstore_epi32(reinterpret_cast<int *>(buffer + i), mask, srcVector); + __m256i src1 = _mm256_unpacklo_epi8(srcVector, zero); + __m256i src2 = _mm256_unpackhi_epi8(srcVector, zero); + __m256i alpha1 = _mm256_shuffle_epi8(src1, shuffleMask); + __m256i alpha2 = _mm256_shuffle_epi8(src2, shuffleMask); + src1 = _mm256_mullo_epi16(src1, alpha1); + src2 = _mm256_mullo_epi16(src2, alpha2); + src1 = _mm256_add_epi16(src1, _mm256_srli_epi16(src1, 8)); + src2 = _mm256_add_epi16(src2, _mm256_srli_epi16(src2, 8)); + src1 = _mm256_add_epi16(src1, half); + src2 = _mm256_add_epi16(src2, half); + src1 = _mm256_srli_epi16(src1, 8); + src2 = _mm256_srli_epi16(src2, 8); + src1 = _mm256_blend_epi16(src1, alpha1, 0x88); + src2 = _mm256_blend_epi16(src2, alpha2, 0x88); + srcVector = _mm256_packus_epi16(src1, src2); + _mm256_maskstore_epi32(reinterpret_cast<int *>(buffer + i), epilogueMask, srcVector); } else { if (buffer != src || RGBA) - _mm_maskstore_epi32(reinterpret_cast<int *>(buffer + i), mask, srcVector); + _mm256_maskstore_epi32(reinterpret_cast<int *>(buffer + i), epilogueMask, srcVector); } } else { - _mm_maskstore_epi32(reinterpret_cast<int *>(buffer + i), mask, _mm256_castsi256_si128(zero)); + _mm256_maskstore_epi32(reinterpret_cast<int *>(buffer + i), epilogueMask, zero); } } } @@ -1116,13 +1110,13 @@ template<bool RGBA> static void convertARGBToRGBA64PM_avx2(QRgba64 *buffer, const uint *src, qsizetype count) { qsizetype i = 0; - const __m256i alphaMask = _mm256_broadcastsi128_si256(_mm_set1_epi32(0xff000000)); + const __m256i alphaMask = _mm256_set1_epi32(0xff000000); const __m256i rgbaMask = _mm256_broadcastsi128_si256(_mm_setr_epi8(2, 1, 0, 3, 6, 5, 4, 7, 10, 9, 8, 11, 14, 13, 12, 15)); const __m256i shuffleMask = _mm256_broadcastsi128_si256(_mm_setr_epi8(6, 7, 6, 7, 6, 7, 6, 7, 14, 15, 14, 15, 14, 15, 14, 15)); const __m256i zero = _mm256_setzero_si256(); for (; i < count - 7; i += 8) { - __m256i src1, src2; + __m256i dst1, dst2; __m256i srcVector = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(src + i)); if (!_mm256_testz_si256(srcVector, alphaMask)) { // keep the two _mm_test[zc]_siXXX next to each other @@ -1138,64 +1132,70 @@ static void convertARGBToRGBA64PM_avx2(QRgba64 *buffer, const uint *src, qsizety // after unpacklo/hi [ P1, P2; P3, P4 ] [ P5, P6; P7, P8 ] srcVector = _mm256_permute4x64_epi64(srcVector, _MM_SHUFFLE(3, 1, 2, 0)); + const __m256i src1 = _mm256_unpacklo_epi8(srcVector, srcVector); + const __m256i src2 = _mm256_unpackhi_epi8(srcVector, srcVector); if (!cf) { - src1 = _mm256_unpacklo_epi8(srcVector, zero); - src2 = _mm256_unpackhi_epi8(srcVector, zero); - __m256i alpha1 = _mm256_shuffle_epi8(src1, shuffleMask); - __m256i alpha2 = _mm256_shuffle_epi8(src2, shuffleMask); - src1 = _mm256_mullo_epi16(src1, alpha1); - src2 = _mm256_mullo_epi16(src2, alpha2); - alpha1 = _mm256_unpacklo_epi8(srcVector, srcVector); - alpha2 = _mm256_unpackhi_epi8(srcVector, srcVector); - src1 = _mm256_add_epi16(src1, _mm256_srli_epi16(src1, 7)); - src2 = _mm256_add_epi16(src2, _mm256_srli_epi16(src2, 7)); - src1 = _mm256_blend_epi16(src1, alpha1, 0x88); - src2 = _mm256_blend_epi16(src2, alpha2, 0x88); + dst1 = _mm256_unpacklo_epi8(srcVector, zero); + dst2 = _mm256_unpackhi_epi8(srcVector, zero); + const __m256i alpha1 = _mm256_shuffle_epi8(dst1, shuffleMask); + const __m256i alpha2 = _mm256_shuffle_epi8(dst2, shuffleMask); + dst1 = _mm256_mullo_epi16(dst1, alpha1); + dst2 = _mm256_mullo_epi16(dst2, alpha2); + dst1 = _mm256_add_epi16(dst1, _mm256_srli_epi16(dst1, 7)); + dst2 = _mm256_add_epi16(dst2, _mm256_srli_epi16(dst2, 7)); + dst1 = _mm256_blend_epi16(dst1, src1, 0x88); + dst2 = _mm256_blend_epi16(dst2, src2, 0x88); } else { - src1 = _mm256_unpacklo_epi8(srcVector, srcVector); - src2 = _mm256_unpackhi_epi8(srcVector, srcVector); + dst1 = src1; + dst2 = src2; } } else { - src1 = src2 = zero; + dst1 = dst2 = zero; } - _mm256_storeu_si256(reinterpret_cast<__m256i *>(buffer + i), src1); - _mm256_storeu_si256(reinterpret_cast<__m256i *>(buffer + i) + 1, src2); + _mm256_storeu_si256(reinterpret_cast<__m256i *>(buffer + i), dst1); + _mm256_storeu_si256(reinterpret_cast<__m256i *>(buffer + i) + 1, dst2); } - for ( ; i < count; i += 4) { - __m128i maskedAlphaMask = _mm256_castsi256_si128(alphaMask); - __m128i mask = maskFromCount((count - i) * sizeof(*src)); - maskedAlphaMask = _mm_and_si128(mask, maskedAlphaMask); - __m128i srcVector = _mm_maskload_epi32(reinterpret_cast<const int *>(src + i), mask); - __m256i src; + if (i < count) { + __m256i epilogueMask = epilogueMaskFromCount(count - i); + const __m256i epilogueAlphaMask = _mm256_blendv_epi8(_mm256_setzero_si256(), alphaMask, epilogueMask); + __m256i dst1, dst2; + __m256i srcVector = _mm256_maskload_epi32(reinterpret_cast<const int *>(src + i), epilogueMask); - if (!_mm_testz_si128(srcVector, maskedAlphaMask)) { + if (!_mm256_testz_si256(srcVector, epilogueAlphaMask)) { // keep the two _mm_test[zc]_siXXX next to each other - bool cf = _mm_testc_si128(srcVector, maskedAlphaMask); + bool cf = _mm256_testc_si256(srcVector, epilogueAlphaMask); if (!RGBA) - srcVector = _mm_shuffle_epi8(srcVector, _mm256_castsi256_si128(rgbaMask)); + srcVector = _mm256_shuffle_epi8(srcVector, rgbaMask); + srcVector = _mm256_permute4x64_epi64(srcVector, _MM_SHUFFLE(3, 1, 2, 0)); + const __m256i src1 = _mm256_unpacklo_epi8(srcVector, srcVector); + const __m256i src2 = _mm256_unpackhi_epi8(srcVector, srcVector); if (!cf) { - src = _mm256_cvtepu8_epi16(srcVector); - __m256i alpha = _mm256_shuffle_epi8(src, shuffleMask); - src = _mm256_mullo_epi16(src, alpha); - - __m128i alpha1 = _mm_unpacklo_epi8(srcVector, srcVector); - __m128i alpha2 = _mm_unpackhi_epi8(srcVector, srcVector); - alpha = _mm256_inserti128_si256(_mm256_castsi128_si256(alpha1), alpha2, 1); - src = _mm256_add_epi16(src, _mm256_srli_epi16(src, 7)); - src = _mm256_blend_epi16(src, alpha, 0x88); + dst1 = _mm256_unpacklo_epi8(srcVector, zero); + dst2 = _mm256_unpackhi_epi8(srcVector, zero); + const __m256i alpha1 = _mm256_shuffle_epi8(dst1, shuffleMask); + const __m256i alpha2 = _mm256_shuffle_epi8(dst2, shuffleMask); + dst1 = _mm256_mullo_epi16(dst1, alpha1); + dst2 = _mm256_mullo_epi16(dst2, alpha2); + dst1 = _mm256_add_epi16(dst1, _mm256_srli_epi16(dst1, 7)); + dst2 = _mm256_add_epi16(dst2, _mm256_srli_epi16(dst2, 7)); + dst1 = _mm256_blend_epi16(dst1, src1, 0x88); + dst2 = _mm256_blend_epi16(dst2, src2, 0x88); } else { - const __m128i src1 = _mm_unpacklo_epi8(srcVector, srcVector); - const __m128i src2 = _mm_unpackhi_epi8(srcVector, srcVector); - src = _mm256_castsi128_si256(src1); - src = _mm256_inserti128_si256(src, src2, 1); + dst1 = src1; + dst2 = src2; } } else { - src = zero; + dst1 = dst2 = zero; } - __m256i xmask = _mm256_cvtepi32_epi64(mask); - _mm256_maskstore_epi64(reinterpret_cast<qint64 *>(buffer + i), xmask, src); - }; + epilogueMask = _mm256_permute4x64_epi64(epilogueMask, _MM_SHUFFLE(3, 1, 2, 0)); + _mm256_maskstore_epi64(reinterpret_cast<qint64 *>(buffer + i), + _mm256_unpacklo_epi32(epilogueMask, epilogueMask), + dst1); + _mm256_maskstore_epi64(reinterpret_cast<qint64 *>(buffer + i + 4), + _mm256_unpackhi_epi32(epilogueMask, epilogueMask), + dst2); + } } const QRgba64 * QT_FASTCALL convertARGB32ToRGBA64PM_avx2(QRgba64 *buffer, const uint *src, int count, From 71a1c66ab9ae48f575b80290e1d5e3624fd81704 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov <timur.pocheptsov@qt.io> Date: Tue, 29 Jan 2019 10:34:26 +0100 Subject: [PATCH 1062/1650] Feature 'ocsp' - fix a broken win-64 build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Alas, we have to do the job ossl_typ.h failed to - undef macros coming from wincrypt.h (?) and clashing with identifiers/naming conventions not exactly very wisely chosen by OpenSSL. Change-Id: I1725c4f769be64dbb391d040b2c1574b20b65151 Fixes: QTBUG-73322 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> --- src/network/ssl/qocsp_p.h | 74 +++++++++++++++++++ src/network/ssl/qsslsocket_openssl.cpp | 2 +- .../ssl/qsslsocket_openssl_symbols_p.h | 2 +- src/network/ssl/ssl.pri | 2 + 4 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 src/network/ssl/qocsp_p.h diff --git a/src/network/ssl/qocsp_p.h b/src/network/ssl/qocsp_p.h new file mode 100644 index 0000000000..94c1c9b445 --- /dev/null +++ b/src/network/ssl/qocsp_p.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QOCSP_P_H +#define QOCSP_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +// Note, this file is a workaround: on 64-bit Windows one of OpenSSL +// includes combined with openssl/ocsp.h results in macros from +// wincrypt.h exposed. OpenSSL's own very "unique" and "inventive" +// names like OCSP_RESPONSE or X509_NAME were asking to clash with +// other entities (presumably macros) with the same names. Normally, +// ossl_typ.h un-defines them, but due to a bug in OpenSSL, fails +// to do this on Win 64. Thus we have to do it here. We only undef +// 3 names, ossl_typ.h has more, but apparently we don't need them +// (no name clash so far). + +QT_REQUIRE_CONFIG(ocsp); + +#ifdef Q_OS_WIN64 +#undef X509_NAME +#undef OCSP_REQUEST +#undef OCSP_RESPONSE +#endif // Q_OS_WIN64 + +#include <openssl/ocsp.h> + +#endif // QOCSP_P_H diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 15b2b4c2cf..038f21b099 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -85,7 +85,7 @@ #include <QtCore/qscopedvaluerollback.h> #if QT_CONFIG(ocsp) -#include <openssl/ocsp.h> +#include "qocsp_p.h" #endif #include <algorithm> diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h index cf426e2ed2..e09820b2f2 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols_p.h +++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h @@ -73,7 +73,7 @@ #include <QtCore/qglobal.h> #if QT_CONFIG(ocsp) -#include <openssl/ocsp.h> +#include "qocsp_p.h" #endif QT_BEGIN_NAMESPACE diff --git a/src/network/ssl/ssl.pri b/src/network/ssl/ssl.pri index 5712a26fd8..8bb70a2aed 100644 --- a/src/network/ssl/ssl.pri +++ b/src/network/ssl/ssl.pri @@ -100,6 +100,8 @@ qtConfig(ssl) { SOURCES += ssl/qdtls_openssl.cpp } + qtConfig(ocsp): HEADERS += ssl/qocsp_p.h + qtConfig(opensslv11) { HEADERS += ssl/qsslsocket_openssl11_symbols_p.h SOURCES += ssl/qsslsocket_openssl11.cpp \ From ca65efb0ccad566eed89e7b81896299ca00fd2da Mon Sep 17 00:00:00 2001 From: Friedemann Kleint <Friedemann.Kleint@qt.io> Date: Wed, 6 Feb 2019 10:12:48 +0100 Subject: [PATCH 1063/1650] Add deprecation exclusion around deprecated calls in deprecated code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix: io/qdir.cpp:1087:16: warning: ‘static void QResource::addSearchPath(const QString&)’ is deprecated: Use QDir::addSearchPath() instead [-Wdeprecated-declarations] io/qprocess.cpp:1178:34: warning: ‘void QProcess::finished(int)’ is deprecated: Use QProcess::finished(int, QProcess::ExitStatus) instead [-Wdeprecated-declarations] image/qpixmap.cpp:997:48: warning: ‘static QPixmap QPixmap::grabWidget(QObject*, const QRect&)’ is deprecated: Use QWidget::grab() instead [-Wdeprecated-declarations] text/qfont.cpp:2218:29: warning: ‘QString QFont::lastResortFamily() const’ is deprecated [-Wdeprecated-declarations] itemviews/qitemdelegate.cpp:1008:41: warning: ‘static QPixmap* QPixmapCache::find(const QString&)’ is deprecated: Use bool find(const QString &, QPixmap *) instead [-Wdeprecated-declarations] Change-Id: I51259edc175b1f55f61ded3af50ebfffd8c304a8 Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de> --- src/corelib/io/qdir.cpp | 3 +++ src/corelib/io/qprocess.cpp | 3 +++ src/gui/image/qpixmap.cpp | 3 +++ src/gui/painting/qpainter.cpp | 3 +++ src/gui/text/qfont.cpp | 3 +++ src/widgets/itemviews/qitemdelegate.cpp | 3 +++ 6 files changed, 18 insertions(+) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 9c4ae5a1c0..671913e92f 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -1084,7 +1084,10 @@ void QDir::setNameFilters(const QStringList &nameFilters) void QDir::addResourceSearchPath(const QString &path) { #ifdef QT_BUILD_CORE_LIB +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED QResource::addSearchPath(path); +QT_WARNING_POP #else Q_UNUSED(path) #endif diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 83849980ae..d5d67d86f3 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -1175,7 +1175,10 @@ bool QProcessPrivate::_q_processDied() //emit q->standardErrorClosed(); #if QT_DEPRECATED_SINCE(5, 13) +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED emit q->finished(exitCode); +QT_WARNING_POP #endif emit q->finished(exitCode, exitStatus); } diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 091095f3fc..1ec4e3488a 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -994,7 +994,10 @@ QPixmap QPixmap::grabWidget(QObject *widget, const QRect &rectangle) */ QPixmap QPixmap::grabWidget(QObject *widget, int x, int y, int w, int h) { +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED return grabWidget(widget, QRect(x, y, w, h)); +QT_WARNING_POP } #endif diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index c746df9dd6..570f750645 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -2981,7 +2981,10 @@ void QPainter::setMatrix(const QMatrix &matrix, bool combine) const QMatrix &QPainter::matrix() const { +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED return worldMatrix(); +QT_WARNING_POP } diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index d879836572..a51e98ce85 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -2215,7 +2215,10 @@ QString QFont::defaultFamily() const */ QString QFont::lastResortFont() const { +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED return lastResortFamily(); +QT_WARNING_POP } #endif diff --git a/src/widgets/itemviews/qitemdelegate.cpp b/src/widgets/itemviews/qitemdelegate.cpp index f85004c49c..6e57e0c32b 100644 --- a/src/widgets/itemviews/qitemdelegate.cpp +++ b/src/widgets/itemviews/qitemdelegate.cpp @@ -1005,11 +1005,14 @@ static QString qPixmapSerial(quint64 i, bool enabled) QPixmap *QItemDelegate::selected(const QPixmap &pixmap, const QPalette &palette, bool enabled) const { const QString key = qPixmapSerial(pixmap.cacheKey(), enabled); +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED QPixmap *pm = QPixmapCache::find(key); if (pm) return pm; selectedPixmap(pixmap, palette, enabled); return QPixmapCache::find(key); +QT_WARNING_POP } #endif From 5c98d15a45da1d63614b2e7181536e12d2bcb02d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint <Friedemann.Kleint@qt.io> Date: Wed, 6 Feb 2019 10:52:23 +0100 Subject: [PATCH 1064/1650] Fix some deprecation warnings in examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit googlesuggest.cpp:163:36: warning: ‘void QTreeWidgetItem::setTextColor(int, const QColor&)’ is deprecated: Use QTreeWidgetItem::setForeground() instead [-Wdeprecated-declarations] xbeltree.cpp:187:34: warning: ‘void QTreeWidget::setItemExpanded(const QTreeWidgetItem*, bool)’ is deprecated: Use QTreeWidgetItem::setExpanded() instead [-Wdeprecated-declarations] imageitem.cpp:114:21: warning: ‘void QGraphicsItem::setMatrix(const QMatrix&, bool)’ is deprecated: Use setTransform() instead [-Wdeprecated-declarations] xbelreader.cpp:143:48: warning: ‘void QTreeWidget::setItemExpanded(const QTreeWidgetItem*, bool)’ is deprecated: Use QTreeWidgetItem::setExpanded() instead [-Wdeprecated-declarations] xbelgenerator.cpp:103:55: warning: ‘bool QTreeWidget::isItemExpanded(const QTreeWidgetItem*) const’ is deprecated: Use QTreeWidgetItem::isExpanded() instead [-Wdeprecated-declarations] xbelwriter.cpp:90:55: warning: ‘bool QTreeWidget::isItemExpanded(const QTreeWidgetItem*) const’ is deprecated: Use QTreeWidgetItem::isExpanded() instead [-Wdeprecated-declarations] xbelhandler.cpp:97:50: warning: ‘void QTreeWidget::setItemExpanded(const QTreeWidgetItem*, bool)’ is deprecated: Use QTreeWidgetItem::setExpanded() instead [-Wdeprecated-declarations] node.cpp:180:60: warning: ‘QColor QColor::light(int) const’ is deprecated: Use QColor::lighter() instead [-Wdeprecated-declarations] node.cpp:181:64: warning: ‘QColor QColor::light(int) const’ is deprecated: Use QColor::lighter() instead [-Wdeprecated-declarations] chip.cpp:82:81: warning: ‘QColor QColor::dark(int) const’ is deprecated: Use QColor::darker() instead [-Wdeprecated-declarations] chip.cpp:84:40: warning: ‘QColor QColor::light(int) const’ is deprecated: Use QColor::lighter() instead [-Wdeprecated-declarations] chip.cpp:108:93: warning: ‘QColor QColor::dark(int) const’ is deprecated: Use QColor::darker() instead [-Wdeprecated-declarations] roundrectitem.cpp:65:42: warning: ‘QColor QColor::dark(int) const’ is deprecated: Use QColor::darker() instead [-Wdeprecated-declarations] roundrectitem.cpp:97:51: warning: ‘void QPainter::drawRoundRect(const QRectF&, int, int)’ is deprecated: Use drawRoundedRect(..., Qt::RelativeSize) instead [-Wdeprecated-declarations] roundrectitem.cpp:105:34: warning: ‘void QPainter::drawRoundRect(const QRectF&, int, int)’ is deprecated: Use drawRoundedRect(..., Qt::RelativeSize) instead [-Wdeprecated-declarations] splashitem.cpp:82:57: warning: ‘void QPainter::drawRoundRect(int, int, int, int, int, int)’ is deprecated: Use drawRoundedRect(..., Qt::RelativeSize) instead [-Wdeprecated-declarations] robot.cpp:116:53: warning: ‘QColor QColor::light(int) const’ is deprecated: Use QColor::lighter() instead [-Wdeprecated-declarations] robot.cpp:176:49: warning: ‘QColor QColor::light(int) const’ is deprecated: Use QColor::lighter() instead [-Wdeprecated-declarations] robot.cpp:200:49: warning: ‘QColor QColor::light(int) const’ is deprecated: Use QColor::lighter() instead [-Wdeprecated-declarations] mandelbrotwidget.cpp:120:41: warning: ‘const QMatrix& QPainter::matrix() const’ is deprecated: Use transform() instead [-Wdeprecated-declarations] composition.cpp:344:47: warning: ‘QColor QColor::light(int) const’ is deprecated: Use QColor::lighter() instead [-Wdeprecated-declarations] composition.cpp:346:46: warning: ‘QColor QColor::dark(int) const’ is deprecated: Use QColor::darker() instead [-Wdeprecated-declarations] colorswatch.cpp:89:34: warning: ‘QColor QColor::light(int) const’ is deprecated: Use QColor::lighter() instead [-Wdeprecated-declarations] mainwindow.cpp:81:62: warning: ‘void QTreeWidget::setItemSelected(const QTreeWidgetItem*, bool)’ is deprecated: Use QTreeWidgetItem::setSelected() instead [-Wdeprecated-declarations] puzzlewidget.cpp:172:35: warning: ‘Qt::DropAction QDrag::start(Qt::DropActions)’ is deprecated: Use QDrag::exec() instead [-Wdeprecated-declarations] spreadsheet.cpp:191:37: warning: ‘QColor QTableWidgetItem::backgroundColor() const’ is deprecated: Use QTableWidgetItem::background() instead [-Wdeprecated-declarations] spreadsheet.cpp:198:32: warning: ‘QColor QColor::light(int) const’ is deprecated: Use QColor::lighter() instead [-Wdeprecated-declarations] spreadsheet.cpp:203:24: warning: ‘QColor QColor::dark(int) const’ is deprecated: Use QColor::darker() instead [-Wdeprecated-declarations] spreadsheet.cpp:238:47: warning: ‘QColor QTableWidgetItem::backgroundColor() const’ is deprecated: Use QTableWidgetItem::background() instead [-Wdeprecated-declarations] spreadsheet.cpp:249:38: warning: ‘void QTableWidgetItem::setBackgroundColor(const QColor&)’ is deprecated: Use QTableWidgetItem::setBackground() instead [-Wdeprecated-declarations] spreadsheet.cpp:494:58: warning: ‘void QTableWidgetItem::setBackgroundColor(const QColor&)’ is deprecated: Use QTableWidgetItem::setBackground() instead [-Wdeprecated-declarations] spreadsheet.cpp:509:56: warning: ‘void QTableWidgetItem::setBackgroundColor(const QColor&)’ is deprecated: Use QTableWidgetItem::setBackground() instead [-Wdeprecated-declarations] spreadsheet.cpp:513:58: warning: ‘void QTableWidgetItem::setBackgroundColor(const QColor&)’ is deprecated: Use QTableWidgetItem::setBackground() instead [-Wdeprecated-declarations] spreadsheet.cpp:527:56: warning: ‘void QTableWidgetItem::setBackgroundColor(const QColor&)’ is deprecated: Use QTableWidgetItem::setBackground() instead [-Wdeprecated-declarations] spreadsheet.cpp:531:58: warning: ‘void QTableWidgetItem::setBackgroundColor(const QColor&)’ is deprecated: Use QTableWidgetItem::setBackground() instead [-Wdeprecated-declarations] spreadsheet.cpp:545:56: warning: ‘void QTableWidgetItem::setBackgroundColor(const QColor&)’ is deprecated: Use QTableWidgetItem::setBackground() instead [-Wdeprecated-declarations] spreadsheet.cpp:549:58: warning: ‘void QTableWidgetItem::setBackgroundColor(const QColor&)’ is deprecated: Use QTableWidgetItem::setBackground() instead [-Wdeprecated-declarations] spreadsheet.cpp:563:55: warning: ‘void QTableWidgetItem::setBackgroundColor(const QColor&)’ is deprecated: Use QTableWidgetItem::setBackground() instead [-Wdeprecated-declarations] spreadsheet.cpp:567:58: warning: ‘void QTableWidgetItem::setBackgroundColor(const QColor&)’ is deprecated: Use QTableWidgetItem::setBackground() instead [-Wdeprecated-declarations] spreadsheet.cpp:581:55: warning: ‘void QTableWidgetItem::setBackgroundColor(const QColor&)’ is deprecated: Use QTableWidgetItem::setBackground() instead [-Wdeprecated-declarations] spreadsheet.cpp:585:58: warning: ‘void QTableWidgetItem::setBackgroundColor(const QColor&)’ is deprecated: Use QTableWidgetItem::setBackground() instead [-Wdeprecated-declarations] spreadsheet.cpp:599:55: warning: ‘void QTableWidgetItem::setBackgroundColor(const QColor&)’ is deprecated: Use QTableWidgetItem::setBackground() instead [-Wdeprecated-declarations] starrating.cpp:91:46: warning: ‘const QBrush& QPalette::foreground() const’ is deprecated: Use QPalette::windowText() instead [-Wdeprecated-declarations] document.cpp:341:36: warning: ‘QColor QColor::dark(int) const’ is deprecated: Use QColor::darker() instead [-Wdeprecated-declarations] document.cpp:342:39: warning: ‘QColor QColor::light(int) const’ is deprecated: Use QColor::lighter() instead [-Wdeprecated-declarations] document.cpp:343:36: warning: ‘QColor QColor::dark(int) const’ is deprecated: Use QColor::darker() instead [-Wdeprecated-declarations] norwegianwoodstyle.cpp:88:39: warning: ‘const QBrush& QPalette::background() const’ is deprecated: Use QPalette::window() instead [-Wdeprecated-declarations] norwegianwoodstyle.cpp:89:39: warning: ‘QColor QColor::dark(int) const’ is deprecated: Use QColor::darker() instead [-Wdeprecated-declarations] norwegianwoodstyle.cpp:188:52: warning: ‘const QBrush& QPalette::background() const’ is deprecated: Use QPalette::window() instead [-Wdeprecated-declarations] norwegianwoodstyle.cpp:264:56: warning: ‘const QBrush& QPalette::foreground() const’ is deprecated: Use QPalette::windowText() instead [-Wdeprecated-declarations] plugindialog.cpp:128:49: warning: ‘void QTreeWidget::setItemExpanded(const QTreeWidgetItem*, bool)’ is deprecated: Use QTreeWidgetItem::setExpanded() instead [-Wdeprecated-declarations] tetrixboard.cpp:361:74: warning: ‘const QBrush& QPalette::background() const’ is deprecated: Use QPalette::window() instead [-Wdeprecated-declarations] tetrixboard.cpp:408:32: warning: ‘QColor QColor::light(int) const’ is deprecated: Use QColor::lighter() instead [-Wdeprecated-declarations] tetrixboard.cpp:412:31: warning: ‘QColor QColor::dark(int) const’ is deprecated: Use QColor::darker() instead [-Wdeprecated-declarations] mandelbrotwidget.cpp:120:41: warning: ‘const QMatrix& QPainter::matrix() const’ is deprecated: Use transform() instead [-Wdeprecated-declarations] Change-Id: If0afabbc35ef25f127f211c11699011d4ae4ae65 Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de> --- .../threads/mandelbrot/mandelbrotwidget.cpp | 3 +- .../network/googlesuggest/googlesuggest.cpp | 2 +- examples/sql/drilldown/imageitem.cpp | 5 ++- examples/widgets/graphicsview/chip/chip.cpp | 6 ++-- .../graphicsview/dragdroprobot/robot.cpp | 6 ++-- .../graphicsview/elasticnodes/node.cpp | 4 +-- .../padnavigator/roundrectitem.cpp | 6 ++-- .../graphicsview/padnavigator/splashitem.cpp | 2 +- .../widgets/itemviews/puzzle/puzzlewidget.cpp | 2 +- .../itemviews/spreadsheet/spreadsheet.cpp | 36 +++++++++---------- .../itemviews/stardelegate/starrating.cpp | 2 +- .../mainwindows/mainwindow/colorswatch.cpp | 2 +- .../painting/composition/composition.cpp | 4 +-- .../tools/plugandpaint/app/plugindialog.cpp | 2 +- examples/widgets/tools/undo/document.cpp | 6 ++-- .../widgets/styles/norwegianwoodstyle.cpp | 8 ++--- .../widgets/widgets/tetrix/tetrixboard.cpp | 6 ++-- examples/xml/dombookmarks/xbeltree.cpp | 2 +- examples/xml/saxbookmarks/xbelgenerator.cpp | 2 +- examples/xml/saxbookmarks/xbelhandler.cpp | 2 +- examples/xml/streambookmarks/xbelreader.cpp | 2 +- examples/xml/streambookmarks/xbelwriter.cpp | 2 +- 22 files changed, 56 insertions(+), 56 deletions(-) diff --git a/examples/corelib/threads/mandelbrot/mandelbrotwidget.cpp b/examples/corelib/threads/mandelbrot/mandelbrotwidget.cpp index 2603f041b2..71d0abb09f 100644 --- a/examples/corelib/threads/mandelbrot/mandelbrotwidget.cpp +++ b/examples/corelib/threads/mandelbrot/mandelbrotwidget.cpp @@ -117,7 +117,8 @@ void MandelbrotWidget::paintEvent(QPaintEvent * /* event */) painter.save(); painter.translate(newX, newY); painter.scale(scaleFactor, scaleFactor); - QRectF exposed = painter.matrix().inverted().mapRect(rect()).adjusted(-1, -1, 1, 1); + + QRectF exposed = painter.transform().inverted().mapRect(rect()).adjusted(-1, -1, 1, 1); painter.drawPixmap(exposed, pixmap, exposed); painter.restore(); } diff --git a/examples/network/googlesuggest/googlesuggest.cpp b/examples/network/googlesuggest/googlesuggest.cpp index 24fdde0a5c..d27beafd1e 100644 --- a/examples/network/googlesuggest/googlesuggest.cpp +++ b/examples/network/googlesuggest/googlesuggest.cpp @@ -160,7 +160,7 @@ void GSuggestCompletion::showCompletion(const QVector<QString> &choices) for (const auto &choice : choices) { auto item = new QTreeWidgetItem(popup); item->setText(0, choice); - item->setTextColor(0, color); + item->setForeground(0, color); } popup->setCurrentItem(popup->topLevelItem(0)); diff --git a/examples/sql/drilldown/imageitem.cpp b/examples/sql/drilldown/imageitem.cpp index 04ec614755..72de623373 100644 --- a/examples/sql/drilldown/imageitem.cpp +++ b/examples/sql/drilldown/imageitem.cpp @@ -109,9 +109,8 @@ void ImageItem::setFrame(int frame) //! [4] void ImageItem::adjust() { - QMatrix matrix; - matrix.scale(120/ boundingRect().width(), 120/ boundingRect().height()); - setMatrix(matrix); + setTransform(QTransform::fromScale(120 / boundingRect().width(), + 120 / boundingRect().height())); } //! [4] diff --git a/examples/widgets/graphicsview/chip/chip.cpp b/examples/widgets/graphicsview/chip/chip.cpp index 443994e121..3d2bbdfcef 100644 --- a/examples/widgets/graphicsview/chip/chip.cpp +++ b/examples/widgets/graphicsview/chip/chip.cpp @@ -79,9 +79,9 @@ void Chip::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWid { Q_UNUSED(widget); - QColor fillColor = (option->state & QStyle::State_Selected) ? color.dark(150) : color; + QColor fillColor = (option->state & QStyle::State_Selected) ? color.darker(150) : color; if (option->state & QStyle::State_MouseOver) - fillColor = fillColor.light(125); + fillColor = fillColor.lighter(125); const qreal lod = option->levelOfDetailFromTransform(painter->worldTransform()); if (lod < 0.2) { @@ -105,7 +105,7 @@ void Chip::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWid pen.setWidth(width); QBrush b = painter->brush(); - painter->setBrush(QBrush(fillColor.dark(option->state & QStyle::State_Sunken ? 120 : 100))); + painter->setBrush(QBrush(fillColor.darker(option->state & QStyle::State_Sunken ? 120 : 100))); painter->drawRect(QRect(14, 14, 79, 39)); painter->setBrush(b); diff --git a/examples/widgets/graphicsview/dragdroprobot/robot.cpp b/examples/widgets/graphicsview/dragdroprobot/robot.cpp index 38552747af..cc70366872 100644 --- a/examples/widgets/graphicsview/dragdroprobot/robot.cpp +++ b/examples/widgets/graphicsview/dragdroprobot/robot.cpp @@ -113,7 +113,7 @@ void RobotHead::paint(QPainter *painter, Q_UNUSED(option); Q_UNUSED(widget); if (pixmap.isNull()) { - painter->setBrush(dragOver ? color.light(130) : color); + painter->setBrush(dragOver ? color.lighter(130) : color); painter->drawRoundedRect(-10, -30, 20, 30, 25, 25, Qt::RelativeSize); painter->setBrush(Qt::white); painter->drawEllipse(-7, -3 - 20, 7, 7); @@ -173,7 +173,7 @@ void RobotTorso::paint(QPainter *painter, Q_UNUSED(option); Q_UNUSED(widget); - painter->setBrush(dragOver ? color.light(130) : color); + painter->setBrush(dragOver ? color.lighter(130) : color); painter->drawRoundedRect(-20, -20, 40, 60, 25, 25, Qt::RelativeSize); painter->drawEllipse(-25, -20, 20, 20); painter->drawEllipse(5, -20, 20, 20); @@ -197,7 +197,7 @@ void RobotLimb::paint(QPainter *painter, Q_UNUSED(option); Q_UNUSED(widget); - painter->setBrush(dragOver ? color.light(130) : color); + painter->setBrush(dragOver ? color.lighter(130) : color); painter->drawRoundedRect(boundingRect(), 50, 50, Qt::RelativeSize); painter->drawEllipse(-5, -5, 10, 10); } diff --git a/examples/widgets/graphicsview/elasticnodes/node.cpp b/examples/widgets/graphicsview/elasticnodes/node.cpp index d4fa3d2b4f..8d44a167fa 100644 --- a/examples/widgets/graphicsview/elasticnodes/node.cpp +++ b/examples/widgets/graphicsview/elasticnodes/node.cpp @@ -177,8 +177,8 @@ void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWid if (option->state & QStyle::State_Sunken) { gradient.setCenter(3, 3); gradient.setFocalPoint(3, 3); - gradient.setColorAt(1, QColor(Qt::yellow).light(120)); - gradient.setColorAt(0, QColor(Qt::darkYellow).light(120)); + gradient.setColorAt(1, QColor(Qt::yellow).lighter(120)); + gradient.setColorAt(0, QColor(Qt::darkYellow).lighter(120)); } else { gradient.setColorAt(0, Qt::yellow); gradient.setColorAt(1, Qt::darkYellow); diff --git a/examples/widgets/graphicsview/padnavigator/roundrectitem.cpp b/examples/widgets/graphicsview/padnavigator/roundrectitem.cpp index f629400a76..82205050ec 100644 --- a/examples/widgets/graphicsview/padnavigator/roundrectitem.cpp +++ b/examples/widgets/graphicsview/padnavigator/roundrectitem.cpp @@ -62,7 +62,7 @@ RoundRectItem::RoundRectItem(const QRectF &bounds, const QColor &color, gradient.setStart(bounds.topLeft()); gradient.setFinalStop(bounds.bottomRight()); gradient.setColorAt(0, color); - gradient.setColorAt(1, color.dark(200)); + gradient.setColorAt(1, color.darker(200)); setCacheMode(ItemCoordinateCache); } //! [0] @@ -94,7 +94,7 @@ void RoundRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt Q_UNUSED(widget); painter->setPen(Qt::NoPen); painter->setBrush(QColor(0, 0, 0, 64)); - painter->drawRoundRect(bounds.translated(2, 2)); + painter->drawRoundedRect(bounds.translated(2, 2), 25, 25, Qt::RelativeSize); //! [3] //! [4] if (fillRect) @@ -102,7 +102,7 @@ void RoundRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opt else painter->setBrush(gradient); painter->setPen(QPen(Qt::black, 1)); - painter->drawRoundRect(bounds); + painter->drawRoundedRect(bounds, 25,25, Qt::RelativeSize); //! [4] //! [5] if (!pix.isNull()) { diff --git a/examples/widgets/graphicsview/padnavigator/splashitem.cpp b/examples/widgets/graphicsview/padnavigator/splashitem.cpp index 0c3a05dd9a..7c3dfba588 100644 --- a/examples/widgets/graphicsview/padnavigator/splashitem.cpp +++ b/examples/widgets/graphicsview/padnavigator/splashitem.cpp @@ -79,7 +79,7 @@ void SplashItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option painter->setPen(QPen(Qt::black, 2)); painter->setBrush(QColor(245, 245, 255, 220)); painter->setClipRect(boundingRect()); - painter->drawRoundRect(3, -100 + 3, 400 - 6, 250 - 6); + painter->drawRoundedRect(3, -100 + 3, 400 - 6, 250 - 6, 25, 25, Qt::RelativeSize); QRectF textRect = boundingRect().adjusted(10, 10, -10, -10); int flags = Qt::AlignTop | Qt::AlignLeft | Qt::TextWordWrap; diff --git a/examples/widgets/itemviews/puzzle/puzzlewidget.cpp b/examples/widgets/itemviews/puzzle/puzzlewidget.cpp index 06968da80f..974a972306 100644 --- a/examples/widgets/itemviews/puzzle/puzzlewidget.cpp +++ b/examples/widgets/itemviews/puzzle/puzzlewidget.cpp @@ -169,7 +169,7 @@ void PuzzleWidget::mousePressEvent(QMouseEvent *event) drag->setHotSpot(event->pos() - square.topLeft()); drag->setPixmap(piece.pixmap); - if (drag->start(Qt::MoveAction) == Qt::IgnoreAction) { + if (drag->exec(Qt::MoveAction) == Qt::IgnoreAction) { pieces.insert(found, piece); update(targetSquare(event->pos())); diff --git a/examples/widgets/itemviews/spreadsheet/spreadsheet.cpp b/examples/widgets/itemviews/spreadsheet/spreadsheet.cpp index 421b4a240c..fc7fbb872c 100644 --- a/examples/widgets/itemviews/spreadsheet/spreadsheet.cpp +++ b/examples/widgets/itemviews/spreadsheet/spreadsheet.cpp @@ -188,19 +188,19 @@ void SpreadSheet::updateColor(QTableWidgetItem *item) QPixmap pix(16, 16); QColor col; if (item) - col = item->backgroundColor(); + col = item->background().color(); if (!col.isValid()) col = palette().base().color(); QPainter pt(&pix); pt.fillRect(0, 0, 16, 16, col); - QColor lighter = col.light(); + QColor lighter = col.lighter(); pt.setPen(lighter); QPoint lightFrame[] = { QPoint(0, 15), QPoint(0, 0), QPoint(15, 0) }; pt.drawPolyline(lightFrame, 3); - pt.setPen(col.dark()); + pt.setPen(col.darker()); QPoint darkFrame[] = { QPoint(1, 15), QPoint(15, 15), QPoint(15, 1) }; pt.drawPolyline(darkFrame, 3); @@ -235,7 +235,7 @@ void SpreadSheet::returnPressed() void SpreadSheet::selectColor() { QTableWidgetItem *item = table->currentItem(); - QColor col = item ? item->backgroundColor() : table->palette().base().color(); + QColor col = item ? item->background().color() : table->palette().base().color(); col = QColorDialog::getColor(col, this); if (!col.isValid()) return; @@ -246,7 +246,7 @@ void SpreadSheet::selectColor() for (QTableWidgetItem *i : selected) { if (i) - i->setBackgroundColor(col); + i->setBackground(col); } updateColor(table->currentItem()); @@ -485,13 +485,13 @@ void SpreadSheet::setupContextMenu() void SpreadSheet::setupContents() { - QColor titleBackground(Qt::lightGray); + QBrush titleBackground(Qt::lightGray); QFont titleFont = table->font(); titleFont.setBold(true); // column 0 table->setItem(0, 0, new SpreadSheetItem("Item")); - table->item(0, 0)->setBackgroundColor(titleBackground); + table->item(0, 0)->setBackground(titleBackground); table->item(0, 0)->setToolTip("This column shows the purchased item/service"); table->item(0, 0)->setFont(titleFont); @@ -506,11 +506,11 @@ void SpreadSheet::setupContents() table->setItem(9, 0, new SpreadSheetItem("Total:")); table->item(9, 0)->setFont(titleFont); - table->item(9, 0)->setBackgroundColor(Qt::lightGray); + table->item(9, 0)->setBackground(titleBackground); // column 1 table->setItem(0, 1, new SpreadSheetItem("Date")); - table->item(0, 1)->setBackgroundColor(titleBackground); + table->item(0, 1)->setBackground(titleBackground); table->item(0, 1)->setToolTip("This column shows the purchase date, double click to change"); table->item(0, 1)->setFont(titleFont); @@ -524,11 +524,11 @@ void SpreadSheet::setupContents() table->setItem(8, 1, new SpreadSheetItem("18/6/2006")); table->setItem(9, 1, new SpreadSheetItem()); - table->item(9, 1)->setBackgroundColor(Qt::lightGray); + table->item(9, 1)->setBackground(titleBackground); // column 2 table->setItem(0, 2, new SpreadSheetItem("Price")); - table->item(0, 2)->setBackgroundColor(titleBackground); + table->item(0, 2)->setBackground(titleBackground); table->item(0, 2)->setToolTip("This column shows the price of the purchase"); table->item(0, 2)->setFont(titleFont); @@ -542,11 +542,11 @@ void SpreadSheet::setupContents() table->setItem(8, 2, new SpreadSheetItem("1240")); table->setItem(9, 2, new SpreadSheetItem()); - table->item(9, 2)->setBackgroundColor(Qt::lightGray); + table->item(9, 2)->setBackground(Qt::lightGray); // column 3 table->setItem(0, 3, new SpreadSheetItem("Currency")); - table->item(0, 3)->setBackgroundColor(titleBackground); + table->item(0, 3)->setBackground(titleBackground); table->item(0, 3)->setToolTip("This column shows the currency"); table->item(0, 3)->setFont(titleFont); @@ -560,11 +560,11 @@ void SpreadSheet::setupContents() table->setItem(8, 3, new SpreadSheetItem("USD")); table->setItem(9, 3, new SpreadSheetItem()); - table->item(9,3)->setBackgroundColor(Qt::lightGray); + table->item(9, 3)->setBackground(Qt::lightGray); // column 4 table->setItem(0, 4, new SpreadSheetItem("Ex. Rate")); - table->item(0, 4)->setBackgroundColor(titleBackground); + table->item(0, 4)->setBackground(titleBackground); table->item(0, 4)->setToolTip("This column shows the exchange rate to NOK"); table->item(0, 4)->setFont(titleFont); @@ -578,11 +578,11 @@ void SpreadSheet::setupContents() table->setItem(8, 4, new SpreadSheetItem("7")); table->setItem(9, 4, new SpreadSheetItem()); - table->item(9,4)->setBackgroundColor(Qt::lightGray); + table->item(9, 4)->setBackground(titleBackground); // column 5 table->setItem(0, 5, new SpreadSheetItem("NOK")); - table->item(0, 5)->setBackgroundColor(titleBackground); + table->item(0, 5)->setBackground(titleBackground); table->item(0, 5)->setToolTip("This column shows the expenses in NOK"); table->item(0, 5)->setFont(titleFont); @@ -596,7 +596,7 @@ void SpreadSheet::setupContents() table->setItem(8, 5, new SpreadSheetItem("* C9 E9")); table->setItem(9, 5, new SpreadSheetItem("sum F2 F9")); - table->item(9,5)->setBackgroundColor(Qt::lightGray); + table->item(9, 5)->setBackground(titleBackground); } const char *htmlText = diff --git a/examples/widgets/itemviews/stardelegate/starrating.cpp b/examples/widgets/itemviews/stardelegate/starrating.cpp index 15e14965e3..75f0bd9cf7 100644 --- a/examples/widgets/itemviews/stardelegate/starrating.cpp +++ b/examples/widgets/itemviews/stardelegate/starrating.cpp @@ -88,7 +88,7 @@ void StarRating::paint(QPainter *painter, const QRect &rect, painter->setPen(Qt::NoPen); painter->setBrush(mode == EditMode::Editable ? palette.highlight() : - palette.foreground()); + palette.windowText()); const int yOffset = (rect.height() - PaintingScaleFactor) / 2; painter->translate(rect.x(), rect.y() + yOffset); diff --git a/examples/widgets/mainwindows/mainwindow/colorswatch.cpp b/examples/widgets/mainwindows/mainwindow/colorswatch.cpp index 4e4c15ccaf..5662518ddc 100644 --- a/examples/widgets/mainwindows/mainwindow/colorswatch.cpp +++ b/examples/widgets/mainwindows/mainwindow/colorswatch.cpp @@ -86,7 +86,7 @@ QColor bgColorForName(const QString &name) return QColor("#D8D8F1"); if (name == "Yellow") return QColor("#F1F0D8"); - return QColor(name).light(110); + return QColor(name).lighter(110); } QColor fgColorForName(const QString &name) diff --git a/examples/widgets/painting/composition/composition.cpp b/examples/widgets/painting/composition/composition.cpp index 96088cca4a..9bd71735a0 100644 --- a/examples/widgets/painting/composition/composition.cpp +++ b/examples/widgets/painting/composition/composition.cpp @@ -341,9 +341,9 @@ void CompositionRenderer::drawSource(QPainter &p) QRectF circle_rect = rectangle_around(m_circle_pos); QColor color = QColor::fromHsvF(m_circle_hue / 360.0, 1, 1, m_circle_alpha / 255.0); QLinearGradient circle_gradient(circle_rect.topLeft(), circle_rect.bottomRight()); - circle_gradient.setColorAt(0, color.light()); + circle_gradient.setColorAt(0, color.lighter()); circle_gradient.setColorAt(0.5, color); - circle_gradient.setColorAt(1, color.dark()); + circle_gradient.setColorAt(1, color.darker()); p.setBrush(circle_gradient); p.drawEllipse(circle_rect); diff --git a/examples/widgets/tools/plugandpaint/app/plugindialog.cpp b/examples/widgets/tools/plugandpaint/app/plugindialog.cpp index af5828f67e..84bd364b41 100644 --- a/examples/widgets/tools/plugandpaint/app/plugindialog.cpp +++ b/examples/widgets/tools/plugandpaint/app/plugindialog.cpp @@ -125,7 +125,7 @@ void PluginDialog::populateTreeWidget(QObject *plugin, const QString &text) { auto pluginItem = new QTreeWidgetItem(treeWidget); pluginItem->setText(0, text); - treeWidget->setItemExpanded(pluginItem, true); + pluginItem->setExpanded(true); QFont boldFont = pluginItem->font(0); boldFont.setBold(true); diff --git a/examples/widgets/tools/undo/document.cpp b/examples/widgets/tools/undo/document.cpp index 212656721e..8935f98a7a 100644 --- a/examples/widgets/tools/undo/document.cpp +++ b/examples/widgets/tools/undo/document.cpp @@ -338,9 +338,9 @@ static QGradient gradient(const QColor &color, const QRect &rect) QColor c = color; c.setAlpha(160); QLinearGradient result(rect.topLeft(), rect.bottomRight()); - result.setColorAt(0, c.dark(150)); - result.setColorAt(0.5, c.light(200)); - result.setColorAt(1, c.dark(150)); + result.setColorAt(0, c.darker(150)); + result.setColorAt(0.5, c.lighter(200)); + result.setColorAt(1, c.darker(150)); return result; } diff --git a/examples/widgets/widgets/styles/norwegianwoodstyle.cpp b/examples/widgets/widgets/styles/norwegianwoodstyle.cpp index b334ca97cb..1d7ef2637b 100644 --- a/examples/widgets/widgets/styles/norwegianwoodstyle.cpp +++ b/examples/widgets/widgets/styles/norwegianwoodstyle.cpp @@ -85,8 +85,8 @@ void NorwegianWoodStyle::polish(QPalette &palette) setTexture(palette, QPalette::Mid, midImage); setTexture(palette, QPalette::Window, backgroundImage); - QBrush brush = palette.background(); - brush.setColor(brush.color().dark()); + QBrush brush = palette.window(); + brush.setColor(brush.color().darker()); palette.setBrush(QPalette::Disabled, QPalette::WindowText, brush); palette.setBrush(QPalette::Disabled, QPalette::Text, brush); @@ -185,7 +185,7 @@ void NorwegianWoodStyle::drawPrimitive(PrimitiveElement element, qstyleoption_cast<const QStyleOptionButton *>(option); if (buttonOption && (buttonOption->features & QStyleOptionButton::Flat)) { - brush = option->palette.background(); + brush = option->palette.window(); darker = (option->state & (State_Sunken | State_On)); } else { if (option->state & (State_Sunken | State_On)) { @@ -261,7 +261,7 @@ void NorwegianWoodStyle::drawPrimitive(PrimitiveElement element, painter->setPen(bottomPen); painter->drawPath(roundRect); - painter->setPen(option->palette.foreground().color()); + painter->setPen(option->palette.windowText().color()); painter->setClipping(false); painter->drawPath(roundRect); diff --git a/examples/widgets/widgets/tetrix/tetrixboard.cpp b/examples/widgets/widgets/tetrix/tetrixboard.cpp index b1139ca8a6..ef3ac4fc38 100644 --- a/examples/widgets/widgets/tetrix/tetrixboard.cpp +++ b/examples/widgets/widgets/tetrix/tetrixboard.cpp @@ -358,7 +358,7 @@ void TetrixBoard::showNextPiece() QPixmap pixmap(dx * squareWidth(), dy * squareHeight()); QPainter painter(&pixmap); - painter.fillRect(pixmap.rect(), nextPieceLabel->palette().background()); + painter.fillRect(pixmap.rect(), nextPieceLabel->palette().window()); for (int i = 0; i < 4; ++i) { int x = nextPiece.x(i) - nextPiece.minX(); @@ -405,11 +405,11 @@ void TetrixBoard::drawSquare(QPainter &painter, int x, int y, TetrixShape shape) painter.fillRect(x + 1, y + 1, squareWidth() - 2, squareHeight() - 2, color); - painter.setPen(color.light()); + painter.setPen(color.lighter()); painter.drawLine(x, y + squareHeight() - 1, x, y); painter.drawLine(x, y, x + squareWidth() - 1, y); - painter.setPen(color.dark()); + painter.setPen(color.darker()); painter.drawLine(x + 1, y + squareHeight() - 1, x + squareWidth() - 1, y + squareHeight() - 1); painter.drawLine(x + squareWidth() - 1, y + squareHeight() - 1, diff --git a/examples/xml/dombookmarks/xbeltree.cpp b/examples/xml/dombookmarks/xbeltree.cpp index f7ff1de638..d90cdc03b4 100644 --- a/examples/xml/dombookmarks/xbeltree.cpp +++ b/examples/xml/dombookmarks/xbeltree.cpp @@ -184,7 +184,7 @@ void XbelTree::parseFolderElement(const QDomElement &element, item->setText(0, title); bool folded = (element.attribute(foldedAttribute()) != QLatin1String("no")); - setItemExpanded(item, !folded); + item->setExpanded(!folded); QDomElement child = element.firstChildElement(); while (!child.isNull()) { diff --git a/examples/xml/saxbookmarks/xbelgenerator.cpp b/examples/xml/saxbookmarks/xbelgenerator.cpp index ee6f113f9c..77cb6748fe 100644 --- a/examples/xml/saxbookmarks/xbelgenerator.cpp +++ b/examples/xml/saxbookmarks/xbelgenerator.cpp @@ -100,7 +100,7 @@ void XbelGenerator::generateItem(const QTreeWidgetItem *item, int depth) { QString tagName = item->data(0, Qt::UserRole).toString(); if (tagName == QLatin1String("folder")) { - bool folded = !treeWidget->isItemExpanded(item); + bool folded = !item->isExpanded(); out << indent(depth) << "<folder folded=\"" << (folded ? "yes" : "no") << "\">\n" << indent(depth + 1) << "<title>" << escapedText(item->text(0)) diff --git a/examples/xml/saxbookmarks/xbelhandler.cpp b/examples/xml/saxbookmarks/xbelhandler.cpp index 7e2a9db3c2..62dfbf9482 100644 --- a/examples/xml/saxbookmarks/xbelhandler.cpp +++ b/examples/xml/saxbookmarks/xbelhandler.cpp @@ -94,7 +94,7 @@ bool XbelHandler::startElement(const QString & /* namespaceURI */, item->setIcon(0, folderIcon); item->setText(0, QObject::tr("Folder")); bool folded = (attributes.value(foldedAttribute()) != QLatin1String("no")); - treeWidget->setItemExpanded(item, !folded); + item->setExpanded(!folded); } else if (qName == QLatin1String("bookmark")) { item = createChildItem(qName); item->setFlags(item->flags() | Qt::ItemIsEditable); diff --git a/examples/xml/streambookmarks/xbelreader.cpp b/examples/xml/streambookmarks/xbelreader.cpp index 099985d91e..bd187038bc 100644 --- a/examples/xml/streambookmarks/xbelreader.cpp +++ b/examples/xml/streambookmarks/xbelreader.cpp @@ -140,7 +140,7 @@ void XbelReader::readFolder(QTreeWidgetItem *item) QTreeWidgetItem *folder = createChildItem(item); bool folded = (xml.attributes().value(foldedAttribute()) != QLatin1String("no")); - treeWidget->setItemExpanded(folder, !folded); + folder->setExpanded(!folded); while (xml.readNextStartElement()) { if (xml.name() == QLatin1String("title")) diff --git a/examples/xml/streambookmarks/xbelwriter.cpp b/examples/xml/streambookmarks/xbelwriter.cpp index 2959680678..7cc16494e2 100644 --- a/examples/xml/streambookmarks/xbelwriter.cpp +++ b/examples/xml/streambookmarks/xbelwriter.cpp @@ -87,7 +87,7 @@ void XbelWriter::writeItem(const QTreeWidgetItem *item) { QString tagName = item->data(0, Qt::UserRole).toString(); if (tagName == QLatin1String("folder")) { - bool folded = !treeWidget->isItemExpanded(item); + bool folded = !item->isExpanded(); xml.writeStartElement(tagName); xml.writeAttribute(XbelReader::foldedAttribute(), folded ? yesValue() : noValue()); xml.writeTextElement(titleElement(), item->text(0)); From a7ba79553c364df9ab55c5c177b15606191cd568 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Sun, 27 Jan 2019 21:04:25 +0100 Subject: [PATCH 1065/1650] QCommonStyle: factor out elided text calculation Factor out the calculation of the elided text from QCommonStylePrivate::viewItemDrawText() so it can be used by other painting functions. Change-Id: I28e6bfd2fe4d7c552848446fa9913df78589d15b Reviewed-by: Christian Andersen <csandersen3@gmail.com> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> --- src/widgets/styles/qcommonstyle.cpp | 144 ++++++++++++++++------------ src/widgets/styles/qcommonstyle_p.h | 5 + 2 files changed, 87 insertions(+), 62 deletions(-) diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 3d626a57fa..867e91ab3e 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -843,8 +843,6 @@ static void drawArrow(const QStyle *style, const QStyleOptionToolButton *toolbut } #endif // QT_CONFIG(toolbutton) -#if QT_CONFIG(itemviews) - static QSizeF viewItemTextLayout(QTextLayout &textLayout, int lineWidth) { qreal height = 0; @@ -863,6 +861,80 @@ static QSizeF viewItemTextLayout(QTextLayout &textLayout, int lineWidth) return QSizeF(widthUsed, height); } +QString QCommonStylePrivate::calculateElidedText(const QString &text, const QTextOption &textOption, + const QFont &font, const QRect &textRect, const Qt::Alignment valign, + Qt::TextElideMode textElideMode, int flags, + bool lastVisibleLineShouldBeElided, QPointF *paintStartPosition) const +{ + QTextLayout textLayout(text, font); + textLayout.setTextOption(textOption); + + viewItemTextLayout(textLayout, textRect.width()); + + const QRectF boundingRect = textLayout.boundingRect(); + // don't care about LTR/RTL here, only need the height + const QRect layoutRect = QStyle::alignedRect(Qt::LayoutDirectionAuto, valign, + boundingRect.size().toSize(), textRect); + + if (paintStartPosition) + *paintStartPosition = QPointF(textRect.x(), layoutRect.top()); + + QString ret; + qreal height = 0; + const int lineCount = textLayout.lineCount(); + for (int i = 0; i < lineCount; ++i) { + const QTextLine line = textLayout.lineAt(i); + height += line.height(); + + // above visible rect + if (height + layoutRect.top() <= textRect.top()) { + if (paintStartPosition) + paintStartPosition->ry() += line.height(); + continue; + } + + const int start = line.textStart(); + const int length = line.textLength(); + const bool drawElided = line.naturalTextWidth() > textRect.width(); + bool elideLastVisibleLine = false; + if (!drawElided && i + 1 < lineCount && lastVisibleLineShouldBeElided) { + const QTextLine nextLine = textLayout.lineAt(i + 1); + const int nextHeight = height + nextLine.height() / 2; + // elide when less than the next half line is visible + if (nextHeight + layoutRect.top() > textRect.height() + textRect.top()) + elideLastVisibleLine = true; + } + + QString text = textLayout.text().mid(start, length); + if (drawElided || elideLastVisibleLine) { + if (elideLastVisibleLine) { + if (text.endsWith(QChar::LineSeparator)) + text.chop(1); + text += QChar(0x2026); + } + const QStackTextEngine engine(text, font); + ret += engine.elidedText(textElideMode, textRect.width(), flags); + + // no newline for the last line (last visible or real) + // sometimes drawElided is true but no eliding is done so the text ends + // with QChar::LineSeparator - don't add another one. This happened with + // arabic text in the testcase for QTBUG-72805 + if (i < lineCount - 1 && + !ret.endsWith(QChar::LineSeparator)) + ret += QChar::LineSeparator; + } else { + ret += text; + } + + // below visible text, can stop + if (height + layoutRect.top() >= textRect.bottom()) + break; + } + return ret; +} + +#if QT_CONFIG(itemviews) + QSize QCommonStylePrivate::viewItemSize(const QStyleOptionViewItem *option, int role) const { const QWidget *widget = option->widget; @@ -935,67 +1007,15 @@ void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewIt textOption.setWrapMode(wrapText ? QTextOption::WordWrap : QTextOption::ManualWrap); textOption.setTextDirection(option->direction); textOption.setAlignment(QStyle::visualAlignment(option->direction, option->displayAlignment)); - QTextLayout textLayout(option->text, option->font); + + QPointF paintPosition; + const QString newText = calculateElidedText(option->text, textOption, + option->font, textRect, option->displayAlignment, + option->textElideMode, 0, + true, &paintPosition); + + QTextLayout textLayout(newText, option->font); textLayout.setTextOption(textOption); - - viewItemTextLayout(textLayout, textRect.width()); - - const QRectF boundingRect = textLayout.boundingRect(); - const QRect layoutRect = QStyle::alignedRect(option->direction, option->displayAlignment, - boundingRect.size().toSize(), textRect); - QPointF paintPosition = QPointF(textRect.x(), layoutRect.top()); - - QString newText; - qreal height = 0; - const int lineCount = textLayout.lineCount(); - for (int i = 0; i < lineCount; ++i) { - const QTextLine line = textLayout.lineAt(i); - height += line.height(); - - // above visible rect - if (height + layoutRect.top() <= textRect.top()) { - paintPosition.ry() += line.height(); - continue; - } - - const int start = line.textStart(); - const int length = line.textLength(); - - const bool drawElided = line.naturalTextWidth() > textRect.width(); - bool elideLastVisibleLine = false; - if (!drawElided && i + 1 < lineCount) { - const QTextLine nextLine = textLayout.lineAt(i + 1); - const int nextHeight = height + nextLine.height() / 2; - // elide when less than the next half line is visible - if (nextHeight + layoutRect.top() > textRect.height() + textRect.top()) - elideLastVisibleLine = true; - } - - QString text = textLayout.text().mid(start, length); - if (drawElided || elideLastVisibleLine) { - if (elideLastVisibleLine) { - if (text.endsWith(QChar::LineSeparator)) - text.chop(1); - text += QChar(0x2026); - } - const QStackTextEngine engine(text, option->font); - newText += engine.elidedText(option->textElideMode, textRect.width()); - // sometimes drawElided is true but no eliding is done so the text ends - // with QChar::LineSeparator - don't add another one. This happened with - // arabic text in the testcase for QTBUG-72805 - if (i < lineCount - 1 && - !newText.endsWith(QChar::LineSeparator)) - newText += QChar::LineSeparator; - } else { - newText += text; - } - - // below visible text, can stop - if (height + layoutRect.top() >= textRect.bottom()) - break; - } - - textLayout.setText(newText); viewItemTextLayout(textLayout, textRect.width()); textLayout.draw(p, paintPosition); } diff --git a/src/widgets/styles/qcommonstyle_p.h b/src/widgets/styles/qcommonstyle_p.h index b347c8563a..f0131b7a58 100644 --- a/src/widgets/styles/qcommonstyle_p.h +++ b/src/widgets/styles/qcommonstyle_p.h @@ -62,6 +62,7 @@ QT_BEGIN_NAMESPACE // class QStringList; +class QTextOption; // Private class class Q_WIDGETS_EXPORT QCommonStylePrivate : public QStylePrivate @@ -85,6 +86,10 @@ public: #endif } + QString calculateElidedText(const QString &text, const QTextOption &textOption, + const QFont &font, const QRect &textRect, const Qt::Alignment valign, + Qt::TextElideMode textElideMode, int flags, + bool lastVisibleLineShouldBeElided, QPointF *paintStartPosition) const; #if QT_CONFIG(itemviews) void viewItemDrawText(QPainter *p, const QStyleOptionViewItem *option, const QRect &rect) const; void viewItemLayout(const QStyleOptionViewItem *opt, QRect *checkRect, From 7024090e1dc7043e7a2a692ede105bcb7952781d Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Sun, 27 Jan 2019 21:15:52 +0100 Subject: [PATCH 1066/1650] QToolButton: fix handling multi-line texts The patch to elide the QToolButton text when there is not enough space introduced a regression with multi-line text. Fix it by using the newly introduced common function to elide multi-line text. Fixes: QTBUG-72226 Change-Id: I066ebbd2f360add93406cc29bb4bbbebf599ba42 Reviewed-by: Samuel Gaist <samuel.gaist@idiap.ch> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> --- src/widgets/styles/qcommonstyle.cpp | 22 ++++++++++++++++++++-- src/widgets/styles/qcommonstyle_p.h | 5 +++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 867e91ab3e..79e338a6e7 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -1157,6 +1157,25 @@ void QCommonStylePrivate::viewItemLayout(const QStyleOptionViewItem *opt, QRect } #endif // QT_CONFIG(itemviews) +#if QT_CONFIG(toolbutton) +QString QCommonStylePrivate::toolButtonElideText(const QStyleOptionToolButton *option, + const QRect &textRect, int flags) const +{ + if (option->fontMetrics.horizontalAdvance(option->text) <= textRect.width()) + return option->text; + + QString text = option->text; + text.replace('\n', QChar::LineSeparator); + QTextOption textOption; + textOption.setWrapMode(QTextOption::ManualWrap); + textOption.setTextDirection(option->direction); + + return calculateElidedText(text, textOption, + option->font, textRect, Qt::AlignTop, + Qt::ElideMiddle, flags, + false, nullptr); +} +#endif // QT_CONFIG(toolbutton) #if QT_CONFIG(tabbar) /*! \internal @@ -1705,8 +1724,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, alignment |= Qt::AlignLeft | Qt::AlignVCenter; } tr.translate(shiftX, shiftY); - const QString text = toolbutton->fontMetrics.elidedText(toolbutton->text, Qt::ElideMiddle, - tr.width(), alignment); + const QString text = d->toolButtonElideText(toolbutton, tr, alignment); proxy()->drawItemText(p, QStyle::visualRect(opt->direction, rect, tr), alignment, toolbutton->palette, toolbutton->state & State_Enabled, text, QPalette::ButtonText); diff --git a/src/widgets/styles/qcommonstyle_p.h b/src/widgets/styles/qcommonstyle_p.h index f0131b7a58..296f89ce5f 100644 --- a/src/widgets/styles/qcommonstyle_p.h +++ b/src/widgets/styles/qcommonstyle_p.h @@ -115,6 +115,11 @@ public: && option.viewItemPosition == cachedOption->viewItemPosition); } #endif +#if QT_CONFIG(toolbutton) + QString toolButtonElideText(const QStyleOptionToolButton *toolbutton, + const QRect &textRect, int flags) const; +#endif + mutable QIcon tabBarcloseButtonIcon; #if QT_CONFIG(tabbar) void tabLayout(const QStyleOptionTab *opt, const QWidget *widget, QRect *textRect, QRect *pixmapRect) const; From c58df2d12e6087c4b880a0210062ca77b6aed046 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= <morten.sorvig@qt.io> Date: Fri, 18 Jan 2019 14:05:33 +0100 Subject: [PATCH 1067/1650] wasm: add qstdweb private API qstdweb provides a C++ API covering parts of the DOM API useful for implementing Qt. This currently includes ArrayBuffer, Blob, File, FileReader, and Uint8Array. The implementation uses emscripten::val, which currently proxies via JavaScript, but should at some point be able to acccess the DOM directly, once WebAssembly gains such access. This API should be easier to use than the string-and-casting emscripten::val API. It is currently private, and can be changed and extended as needed. Change-Id: I95a2ad735e511c8da61f3cc21357fbffe3b05d8e Reviewed-by: Lorn Potter <lorn.potter@gmail.com> --- src/corelib/corelib.pro | 1 + src/corelib/platform/platform.pri | 1 + src/corelib/platform/wasm/qstdweb.cpp | 236 ++++++++++++++++++++++++++ src/corelib/platform/wasm/qstdweb_p.h | 169 ++++++++++++++++++ src/corelib/platform/wasm/wasm.pri | 3 + 5 files changed, 410 insertions(+) create mode 100644 src/corelib/platform/platform.pri create mode 100644 src/corelib/platform/wasm/qstdweb.cpp create mode 100644 src/corelib/platform/wasm/qstdweb_p.h create mode 100644 src/corelib/platform/wasm/wasm.pri diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro index 181780c475..4b758532e6 100644 --- a/src/corelib/corelib.pro +++ b/src/corelib/corelib.pro @@ -44,6 +44,7 @@ include(codecs/codecs.pri) include(serialization/serialization.pri) include(statemachine/statemachine.pri) include(mimetypes/mimetypes.pri) +include(platform/platform.pri) win32 { LIBS_PRIVATE += -lws2_32 diff --git a/src/corelib/platform/platform.pri b/src/corelib/platform/platform.pri new file mode 100644 index 0000000000..1fe2db81b0 --- /dev/null +++ b/src/corelib/platform/platform.pri @@ -0,0 +1 @@ +wasm:include(wasm/wasm.pri) diff --git a/src/corelib/platform/wasm/qstdweb.cpp b/src/corelib/platform/wasm/qstdweb.cpp new file mode 100644 index 0000000000..1afd91d860 --- /dev/null +++ b/src/corelib/platform/wasm/qstdweb.cpp @@ -0,0 +1,236 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qstdweb_p.h" + +#include <emscripten/bind.h> +#include <cstdint> +#include <iostream> + +QT_BEGIN_NAMESPACE + +namespace qstdweb { + +typedef double uint53_t; // see Number.MAX_SAFE_INTEGER + +ArrayBuffer::ArrayBuffer(const emscripten::val &arrayBuffer) + :m_arrayBuffer(arrayBuffer) +{ + +} + +uint32_t ArrayBuffer::byteLength() const +{ + if (m_arrayBuffer.isUndefined() || m_arrayBuffer.isNull()) + return 0; + + return m_arrayBuffer["byteLength"].as<uint32_t>(); +} + +Blob::Blob(const emscripten::val &blob) + :m_blob(blob) +{ + +} + +uint32_t Blob::size() const +{ + return m_blob["size"].as<uint32_t>(); +} + +File::File(const emscripten::val &file) +:m_file(file) +{ + +} + +Blob File::slice(uint64_t begin, uint64_t end) const +{ + return Blob(m_file.call<emscripten::val>("slice", uint53_t(begin), uint53_t(end))); +} + +std::string File::name() const +{ + return m_file["name"].as<std::string>(); +} + +uint64_t File::size() const +{ + return uint64_t(m_file["size"].as<uint53_t>()); +} + +FileList::FileList(const emscripten::val &fileList) + :m_fileList(fileList) +{ + +} + +int FileList::length() const +{ + return m_fileList["length"].as<int>(); +} + +File FileList::item(int index) const +{ + return File(m_fileList[index]); +} + +File FileList::operator[](int index) const +{ + return item(index); +} + +ArrayBuffer FileReader::result() const +{ + return ArrayBuffer(m_fileReader["result"]); +} + +void FileReader::readAsArrayBuffer(const Blob &blob) const +{ + m_fileReader.call<void>("readAsArrayBuffer", blob.m_blob); +} + +void FileReader::onLoad(const std::function<void ()> &onLoad) +{ + m_onLoad.reset(new EventCallback(m_fileReader, "load", onLoad)); +} + +void FileReader::onError(const std::function<void ()> &onError) +{ + m_onError.reset(new EventCallback(m_fileReader, "error", onError)); +} + +void FileReader::onAbort(const std::function<void ()> &onAbort) +{ + m_onAbort.reset(new EventCallback(m_fileReader, "abort", onAbort)); +} + +Uint8Array Uint8Array::heap() +{ + return Uint8Array(heap_()); +} + +Uint8Array::Uint8Array(const emscripten::val &uint8Array) +: m_uint8Array(uint8Array) +{ + +} + +Uint8Array::Uint8Array(const ArrayBuffer &buffer) +: m_uint8Array(Uint8Array::constructor_().new_(buffer.m_arrayBuffer)) +{ + +} + +Uint8Array::Uint8Array(const ArrayBuffer &buffer, uint32_t offset, uint32_t length) +: m_uint8Array(Uint8Array::constructor_().new_(buffer.m_arrayBuffer, offset, length)) +{ + +} + +Uint8Array::Uint8Array(char *buffer, uint32_t size) +:m_uint8Array(Uint8Array::constructor_().new_(Uint8Array::heap().buffer().m_arrayBuffer, uint32_t(buffer), size)) +{ + +} + +ArrayBuffer Uint8Array::buffer() const +{ + return ArrayBuffer(m_uint8Array["buffer"]); +} + +uint32_t Uint8Array::length() const +{ + return m_uint8Array["length"].as<uint32_t>(); +} + +void Uint8Array::set(const Uint8Array &source) +{ + m_uint8Array.call<void>("set", source.m_uint8Array); // copies source content +} + +void Uint8Array::copyTo(char *destination) const +{ + Uint8Array(destination, length()).set(*this); +} + +void Uint8Array::copy(char *destination, const Uint8Array &source) +{ + Uint8Array(destination, source.length()).set(source); +} + +emscripten::val Uint8Array::heap_() +{ + return emscripten::val::module_property("HEAPU8"); +} + +emscripten::val Uint8Array::constructor_() +{ + return emscripten::val::global("Uint8Array"); +} + +// Registers a callback function for a named event on the given element. The event +// name must be the name as returned by the Event.type property: e.g. "load", "error". +EventCallback::EventCallback(emscripten::val element, const std::string &name, const std::function<void ()> &fn) +:m_fn(fn) +{ + element.set(contextPropertyName(name).c_str(), emscripten::val(intptr_t(this))); + element.set((std::string("on") + name).c_str(), emscripten::val::module_property("qtStdWebEventCallbackActivate")); +} + +void EventCallback::activate(emscripten::val event) +{ + emscripten::val target = event["target"]; + std::string eventName = event["type"].as<std::string>(); + EventCallback *that = reinterpret_cast<EventCallback *>(target[contextPropertyName(eventName).c_str()].as<intptr_t>()); + that->m_fn(); +} + +std::string EventCallback::contextPropertyName(const std::string &eventName) +{ + return std::string("data-qtEventCallbackContext") + eventName; +} + +EMSCRIPTEN_BINDINGS(QtStdwebCalback) { + emscripten::function("qtStdWebEventCallbackActivate", &EventCallback::activate); +} + +} // namespace qstdweb + +QT_END_NAMESPACE diff --git a/src/corelib/platform/wasm/qstdweb_p.h b/src/corelib/platform/wasm/qstdweb_p.h new file mode 100644 index 0000000000..75c2ec34b1 --- /dev/null +++ b/src/corelib/platform/wasm/qstdweb_p.h @@ -0,0 +1,169 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSTDWEB_P_H +#define QSTDWEB_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <qglobal.h> +#include <emscripten/val.h> +#include <cstdint> +#include <functional> + +QT_BEGIN_NAMESPACE + +namespace qstdweb { + + // DOM API in C++, implemented using emscripten val.h and bind.h. + // This is private API and can be extened and changed as needed. + + class ArrayBuffer; + class Blob; + class File; + class FileList; + class FileReader; + class Uint8Array; + class EventCallback; + + class ArrayBuffer { + public: + explicit ArrayBuffer(const emscripten::val &arrayBuffer); + uint32_t byteLength() const; + + private: + friend class Uint8Array; + emscripten::val m_arrayBuffer = emscripten::val::undefined(); + }; + + class Blob { + public: + explicit Blob(const emscripten::val &blob); + uint32_t size() const; + + private: + friend class FileReader; + emscripten::val m_blob = emscripten::val::undefined(); + }; + + class File { + public: + File() = default; + explicit File(const emscripten::val &file); + + Blob slice(uint64_t begin, uint64_t end) const; + std::string name() const; + uint64_t size() const; + + private: + emscripten::val m_file = emscripten::val::undefined(); + }; + + class FileList { + public: + FileList() = default; + explicit FileList(const emscripten::val &fileList); + + int length() const; + File item(int index) const; + File operator[](int index) const; + + private: + emscripten::val m_fileList = emscripten::val::undefined(); + }; + + class FileReader { + public: + ArrayBuffer result() const; + void readAsArrayBuffer(const Blob &blob) const; + + void onLoad(const std::function<void ()> &onLoad); + void onError(const std::function<void ()> &onError); + void onAbort(const std::function<void ()> &onAbort); + + private: + emscripten::val m_fileReader = emscripten::val::global("FileReader").new_(); + std::unique_ptr<EventCallback> m_onLoad; + std::unique_ptr<EventCallback> m_onError; + std::unique_ptr<EventCallback> m_onAbort; + }; + + class Uint8Array { + public: + static Uint8Array heap(); + explicit Uint8Array(const emscripten::val &uint8Array); + explicit Uint8Array(const ArrayBuffer &buffer); + Uint8Array(const ArrayBuffer &buffer, uint32_t offset, uint32_t length); + Uint8Array(char *buffer, uint32_t size); + + ArrayBuffer buffer() const; + uint32_t length() const; + void set(const Uint8Array &source); + + void copyTo(char *destination) const; + static void copy(char *destination, const Uint8Array &source); + private: + static emscripten::val heap_(); + static emscripten::val constructor_(); + emscripten::val m_uint8Array = emscripten::val::undefined(); + }; + + class EventCallback + { + public: + EventCallback(emscripten::val element, const std::string &name, const std::function<void ()> &fn); + static void activate(emscripten::val event); + private: + static std::string contextPropertyName(const std::string &eventName); + std::function<void ()> m_fn; + }; +} + +QT_END_NAMESPACE + +#endif diff --git a/src/corelib/platform/wasm/wasm.pri b/src/corelib/platform/wasm/wasm.pri new file mode 100644 index 0000000000..73447030fb --- /dev/null +++ b/src/corelib/platform/wasm/wasm.pri @@ -0,0 +1,3 @@ +INCLUDEDIR += $$PWD +HEADERS += $$PWD/qstdweb_p.h +SOURCES += $$PWD/qstdweb.cpp From 790cf25f9d811f2cda7e252b4f1844e8fce27e2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= <morten.sorvig@qt.io> Date: Fri, 18 Jan 2019 14:21:50 +0100 Subject: [PATCH 1068/1650] wasm: add local file access private API Access to the local file system is restricted by the Web sandbox, and a separate API an implementation is needed to facilitate this for Qt applications. This adds a private asynchronous callback-based C++ API for opening a file dialog and reading file content. The implementation uses a file input html element to show a file dialog, and then the uses the native File and FileReader APIs to read the selected file(s). Change-Id: I4e28baa032d7c3cd63241465f0ae55efd219a05b Reviewed-by: Lorn Potter <lorn.potter@gmail.com> --- src/gui/gui.pro | 1 + src/gui/platform/platform.pri | 1 + .../platform/wasm/qwasmlocalfileaccess.cpp | 169 ++++++++++++++++++ .../platform/wasm/qwasmlocalfileaccess_p.h | 78 ++++++++ src/gui/platform/wasm/wasm.pri | 3 + 5 files changed, 252 insertions(+) create mode 100644 src/gui/platform/platform.pri create mode 100644 src/gui/platform/wasm/qwasmlocalfileaccess.cpp create mode 100644 src/gui/platform/wasm/qwasmlocalfileaccess_p.h create mode 100644 src/gui/platform/wasm/wasm.pri diff --git a/src/gui/gui.pro b/src/gui/gui.pro index 06c9cd3939..edf8124081 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -48,6 +48,7 @@ include(opengl/opengl.pri) qtConfig(animation): include(animation/animation.pri) include(itemmodels/itemmodels.pri) include(vulkan/vulkan.pri) +include(platform/platform.pri) QMAKE_LIBS += $$QMAKE_LIBS_GUI diff --git a/src/gui/platform/platform.pri b/src/gui/platform/platform.pri new file mode 100644 index 0000000000..1fe2db81b0 --- /dev/null +++ b/src/gui/platform/platform.pri @@ -0,0 +1 @@ +wasm:include(wasm/wasm.pri) diff --git a/src/gui/platform/wasm/qwasmlocalfileaccess.cpp b/src/gui/platform/wasm/qwasmlocalfileaccess.cpp new file mode 100644 index 0000000000..83f9415c69 --- /dev/null +++ b/src/gui/platform/wasm/qwasmlocalfileaccess.cpp @@ -0,0 +1,169 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwasmlocalfileaccess_p.h" +#include <private/qstdweb_p.h> +#include <emscripten.h> +#include <emscripten/bind.h> +#include <emscripten/html5.h> +#include <emscripten/val.h> + +QT_BEGIN_NAMESPACE + +namespace QWasmLocalFileAccess { + +void streamFile(const qstdweb::File &file, uint32_t offset, uint32_t length, char *buffer, const std::function<void ()> &completed) +{ + // Read file in chunks in order to avoid holding two copies in memory at the same time + const uint32_t chunkSize = 256 * 1024; + const uint32_t end = offset + length; + // assert end < file.size + auto fileReader = std::make_shared<qstdweb::FileReader>(); + + auto chunkCompleted = std::make_shared<std::function<void (uint32_t, char *buffer)>>(); + *chunkCompleted = [=](uint32_t chunkBegin, char *chunkBuffer) mutable { + + // Copy current chunk from JS memory to Wasm memory + qstdweb::ArrayBuffer result = fileReader->result(); + qstdweb::Uint8Array(result).copyTo(chunkBuffer); + + // Read next chunk if not at buffer end + uint32_t nextChunkBegin = std::min(chunkBegin + result.byteLength(), end); + uint32_t nextChunkEnd = std::min(nextChunkBegin + chunkSize, end); + if (nextChunkBegin == end) { + completed(); + chunkCompleted.reset(); + return; + } + char *nextChunkBuffer = chunkBuffer + result.byteLength(); + fileReader->onLoad([=]() { (*chunkCompleted)(nextChunkBegin, nextChunkBuffer); }); + qstdweb::Blob blob = file.slice(nextChunkBegin, nextChunkEnd); + fileReader->readAsArrayBuffer(blob); + }; + + // Read first chunk. First iteration is a dummy iteration with no available data. + (*chunkCompleted)(offset, buffer); +} + +void streamFile(const qstdweb::File &file, char *buffer, const std::function<void ()> &completed) +{ + streamFile(file, 0, file.size(), buffer, completed); +} + +void readFiles(const qstdweb::FileList &fileList, + const std::function<char *(uint64_t size, const std::string name)> &acceptFile, + const std::function<void ()> &fileDataReady) +{ + auto readFile = std::make_shared<std::function<void(int)>>(); + + *readFile = [=](int fileIndex) mutable { + // Stop when all files have been processed + if (fileIndex >= fileList.length()) { + readFile.reset(); + return; + } + + const qstdweb::File file = fileList[fileIndex]; + + // Ask caller if the file should be accepted + char *buffer = acceptFile(file.size(), file.name()); + if (buffer == nullptr) { + (*readFile)(fileIndex + 1); + return; + } + + // Read file data into caller-provided buffer + streamFile(file, buffer, [=]() { + fileDataReady(); + (*readFile)(fileIndex + 1); + }); + }; + + (*readFile)(0); +} + +typedef std::function<void (const qstdweb::FileList &fileList)> OpenFileDialogCallback; +void openFileDialog(const std::string &accept, FileSelectMode fileSelectMode, + const OpenFileDialogCallback &filesSelected) +{ + // Create file input html element which will display a native file dialog + // and call back to our onchange handler once the user has selected + // one or more files. + emscripten::val document = emscripten::val::global("document"); + emscripten::val input = document.call<emscripten::val>("createElement", std::string("input")); + input.set("type", "file"); + input.set("style", "display:none"); + input.set("accept", emscripten::val(accept)); + input.set("multiple", emscripten::val(fileSelectMode == MultipleFiles)); + + // Note: there is no event in case the user cancels the file dialog. + static std::unique_ptr<qstdweb::EventCallback> changeEvent; + auto callback = [=]() { filesSelected(qstdweb::FileList(input["files"])); }; + changeEvent.reset(new qstdweb::EventCallback(input, "change", callback)); + + // Activate file input + emscripten::val body = document["body"]; + body.call<void>("appendChild", input); + input.call<void>("click"); + body.call<void>("removeChild", input); +} + +void openFiles(const std::string &accept, FileSelectMode fileSelectMode, + const std::function<void (int fileCount)> &fileDialogClosed, + const std::function<char *(uint64_t size, const std::string name)> &acceptFile, + const std::function<void()> &fileDataReady) +{ + openFileDialog(accept, fileSelectMode, [=](const qstdweb::FileList &files) { + fileDialogClosed(files.length()); + readFiles(files, acceptFile, fileDataReady); + }); +} + +void openFile(const std::string &accept, + const std::function<void (bool fileSelected)> &fileDialogClosed, + const std::function<char *(uint64_t size, const std::string name)> &acceptFile, + const std::function<void()> &fileDataReady) +{ + auto fileDialogClosedWithInt = [=](int fileCount) { fileDialogClosed(fileCount != 0); }; + openFiles(accept, FileSelectMode::SingleFile, fileDialogClosedWithInt, acceptFile, fileDataReady); +} + +} // namespace QWasmLocalFileAccess + +QT_END_NAMESPACE diff --git a/src/gui/platform/wasm/qwasmlocalfileaccess_p.h b/src/gui/platform/wasm/qwasmlocalfileaccess_p.h new file mode 100644 index 0000000000..794db8d9b2 --- /dev/null +++ b/src/gui/platform/wasm/qwasmlocalfileaccess_p.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWASMLOCALFILEACCESS_P_H +#define QWASMLOCALFILEACCESS_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <qglobal.h> +#include <cstdint> +#include <functional> + +QT_BEGIN_NAMESPACE + +namespace QWasmLocalFileAccess { + +enum FileSelectMode { SingleFile, MultipleFiles }; + +void openFiles(const std::string &accept, FileSelectMode fileSelectMode, + const std::function<void (int fileCount)> &fileDialogClosed, + const std::function<char *(uint64_t size, const std::string name)> &acceptFile, + const std::function<void()> &fileDataReady); + +void openFile(const std::string &accept, + const std::function<void (bool fileSelected)> &fileDialogClosed, + const std::function<char *(uint64_t size, const std::string name)> &acceptFile, + const std::function<void()> &fileDataReady); + +} // namespace QWasmLocalFileAccess + +QT_END_NAMESPACE + +#endif // QWASMLOCALFILEACCESS_P_H diff --git a/src/gui/platform/wasm/wasm.pri b/src/gui/platform/wasm/wasm.pri new file mode 100644 index 0000000000..1b5d7eadb5 --- /dev/null +++ b/src/gui/platform/wasm/wasm.pri @@ -0,0 +1,3 @@ +INCLUDEDIR += $$PWD +HEADERS += $$PWD/qwasmlocalfileaccess_p.h +SOURCES += $$PWD/qwasmlocalfileaccess.cpp From 928cab5ff1d931d00074d8930c41537109814371 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= <morten.sorvig@qt.io> Date: Fri, 18 Jan 2019 15:02:32 +0100 Subject: [PATCH 1069/1650] wasm: add public API for local file access The web sandbox restricts access to the local file system, which means Qt needs new public API to provide such access to applications. This adds a new static, asynchornous getOpenFileContent() function to QFileDialog, which will show a file dialog, read the file contents once a file has been selected, and finally call the user-provided callback with the selected file name and file data. auto fileReady = [](const QString &fileName, const QByteArray &fileContents) { // Process file } QFileDialog::getOpenFileContent("*.*", fileReady); This API can be expanded in at least two ways in the future: allow reading multiple files, and allow file streaming by returning a QOIDevice. Change-Id: I011b92fbcf21f0696604e66b7f9eb265c1a07aaa Reviewed-by: Lorn Potter <lorn.potter@gmail.com> --- src/widgets/dialogs/qfiledialog.cpp | 82 +++++++++++++++++++ src/widgets/dialogs/qfiledialog.h | 4 + .../code/src_gui_dialogs_qfiledialog.cpp | 11 +++ 3 files changed, 97 insertions(+) diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index f42cf89708..3e756da505 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -73,6 +73,9 @@ #elif defined(Q_OS_WIN) # include <QtCore/qt_windows.h> #endif +#if defined(Q_OS_WASM) +#include <private/qwasmlocalfileaccess_p.h> +#endif QT_BEGIN_NAMESPACE @@ -2347,6 +2350,85 @@ QList<QUrl> QFileDialog::getOpenFileUrls(QWidget *parent, return QList<QUrl>(); } +/*! + This is a convenience static function that will return the content of a file + selected by the user. + + This function is used to access local files on Qt for WebAssembly, where the web + sandbox places restrictions on how such access may happen. Its implementation will + make the browser display a native file dialog, where the user makes the file selection. + + It can also be used on other platforms, where it will fall back to using QFileDialog. + + The function is asynchronous and returns immediately. The \a fileOpenCompleted + callback will be called when a file has been selected and its contents has been + read into memory. + + \snippet code/src_gui_dialogs_qfiledialog.cpp 14 + \since 5.13 +*/ +void QFileDialog::getOpenFileContent(const QString &nameFilter, const std::function<void(const QString &, const QByteArray &)> &fileOpenCompleted) +{ +#ifdef Q_OS_WASM + auto openFileImpl = std::make_shared<std::function<void(void)>>(); + QString fileName; + QByteArray fileContent; + *openFileImpl = [=]() mutable { + auto fileDialogClosed = [&](bool fileSelected) { + if (!fileSelected) { + fileOpenCompleted(fileName, fileContent); + openFileImpl.reset(); + } + }; + auto acceptFile = [&](uint64_t size, const std::string name) -> char * { + const uint64_t twoGB = 1ULL << 31; // QByteArray limit + if (size > twoGB) + return nullptr; + + fileName = QString::fromStdString(name); + fileContent.resize(size); + return fileContent.data(); + }; + auto fileContentReady = [&]() mutable { + fileOpenCompleted(fileName, fileContent); + openFileImpl.reset(); + }; + + auto qtFilterStringToWebAcceptString = [](const QString &qtString) { + // The Qt and Web name filter string formats are similar, but + // not identical. + return qtString.toStdString(); // ### TODO + }; + + QWasmLocalFileAccess::openFile(qtFilterStringToWebAcceptString(nameFilter), fileDialogClosed, acceptFile, fileContentReady); + }; + + (*openFileImpl)(); +#else + QFileDialog *dialog = new QFileDialog(); + dialog->selectNameFilter(nameFilter); + + auto fileSelected = [=](const QString &fileName) { + QByteArray fileContent; + if (!fileName.isNull()) { + QFile selectedFile(fileName); + selectedFile.open(QIODevice::ReadOnly); + fileContent = selectedFile.readAll(); + } + fileOpenCompleted(fileName, fileContent); + }; + + auto dialogClosed = [=](int code) { + Q_UNUSED(code); + delete dialog; + }; + + connect(dialog, &QFileDialog::fileSelected, fileSelected); + connect(dialog, &QFileDialog::finished, dialogClosed); + dialog->show(); +#endif +} + /*! This is a convenience static function that will return a file name selected by the user. The file does not have to exist. diff --git a/src/widgets/dialogs/qfiledialog.h b/src/widgets/dialogs/qfiledialog.h index 8a99112081..c75795fd77 100644 --- a/src/widgets/dialogs/qfiledialog.h +++ b/src/widgets/dialogs/qfiledialog.h @@ -46,6 +46,8 @@ #include <QtCore/qurl.h> #include <QtWidgets/qdialog.h> +#include <functional> + QT_REQUIRE_CONFIG(filedialog); QT_BEGIN_NAMESPACE @@ -273,6 +275,8 @@ public: Options options = Options(), const QStringList &supportedSchemes = QStringList()); + static void getOpenFileContent(const QString &nameFilter, + const std::function<void(const QString &, const QByteArray &)> &fileContentsReady); protected: QFileDialog(const QFileDialogArgs &args); diff --git a/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp b/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp index 06cca37111..1e9daf824b 100644 --- a/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp +++ b/src/widgets/doc/snippets/code/src_gui_dialogs_qfiledialog.cpp @@ -144,3 +144,14 @@ dialog.exec(); //! [14] "Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)" //! [14] + +//! [14] +auto fileOpenCompleted = [](const QSting &fileName, const QByteArray &fileContent) { + if (fileName.isEmpty()) { + // No file was selected + } else { + // Use fileName and fileContent + } +} +QFileDialog::getOpenFileContent("Images (*.png *.xpm *.jpg)", fileContentReady); +//! [14] From 74e04d6ace7aa949db97ae2e46c38a4dc0d4d36a Mon Sep 17 00:00:00 2001 From: BogDan Vatra <bogdan@kdab.com> Date: Mon, 28 Jan 2019 17:04:21 +0200 Subject: [PATCH 1070/1650] Android: follow official android flags for cmake Update our cflags and lflags with the ones found in android.toolchain.cmake Fixes: QTBUG-73274 Change-Id: Id9fd9bf04df959239abd3100090a1485e872b2f0 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> --- mkspecs/android-clang/qmake.conf | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mkspecs/android-clang/qmake.conf b/mkspecs/android-clang/qmake.conf index a0a369bb44..a077c70cba 100644 --- a/mkspecs/android-clang/qmake.conf +++ b/mkspecs/android-clang/qmake.conf @@ -29,8 +29,11 @@ else: equals(ANDROID_TARGET_ARCH, mips): \ else: equals(ANDROID_TARGET_ARCH, mips64): \ QMAKE_CFLAGS += -target mips64el-none-linux-android -QMAKE_CFLAGS += -gcc-toolchain $$NDK_TOOLCHAIN_PATH -QMAKE_LINK = $$QMAKE_CXX $$QMAKE_CFLAGS -Wl,--exclude-libs,libgcc.a +QMAKE_CFLAGS += -gcc-toolchain $$NDK_TOOLCHAIN_PATH -fno-limit-debug-info + +QMAKE_LINK = $$QMAKE_CXX $$QMAKE_CFLAGS -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a +equals(ANDROID_TARGET_ARCH, armeabi-v7a): QMAKE_LINK += -Wl,--exclude-libs,libunwind.a + QMAKE_CFLAGS += -DANDROID_HAS_WSTRING --sysroot=$$NDK_ROOT/sysroot \ -isystem $$NDK_ROOT/sysroot/usr/include/$$NDK_TOOLS_PREFIX \ -isystem $$NDK_ROOT/sources/cxx-stl/llvm-libc++/include \ From 17512d497d7eaf01aefe8140f5010818c0103a95 Mon Sep 17 00:00:00 2001 From: Liang Qi <liang.qi@qt.io> Date: Thu, 7 Feb 2019 09:13:18 +0100 Subject: [PATCH 1071/1650] Disable Docker-based test servers on Windows temporarily The coin agent starts to crash after the docker-compose call. Need to have qt5 dev integrated first, then fix the real issue later. Task-number: QTQAINFRA-2717 Task-number: QTQAINFRA-2750 Change-Id: I255c0c10466cc9413ca41c756ebdb7c049511507 Reviewed-by: Aapo Keskimolo <aapo.keskimolo@qt.io> --- tests/auto/testserver.pri | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/testserver.pri b/tests/auto/testserver.pri index 26e7f6ab8a..eb83c6c2cc 100644 --- a/tests/auto/testserver.pri +++ b/tests/auto/testserver.pri @@ -58,9 +58,9 @@ debug_and_release:!build_pass: return() DOCKER_ENABLED = 1 -equals(QMAKE_HOST.os, Darwin) { +equals(QMAKE_HOST.os, Darwin) | equals(QMAKE_HOST.os, Windows) { DOCKER_ENABLED = 0 - message("Not using docker network test server on macOS, see QTQAINFRA-2717 and QTQAINFRA-2750") + message("Not using docker network test server on macOS and Windows, see QTQAINFRA-2717 and QTQAINFRA-2750") } TESTSERVER_VERSION = "" From 60addee9384cb8c589f7abf9020f7d6d7a6f4d63 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen <allan.jensen@qt.io> Date: Thu, 31 Jan 2019 16:13:16 +0100 Subject: [PATCH 1072/1650] Improve ARGB32ToRGBA64 conversions Improves the precision so 255 values map to 65535 exactly. Change-Id: I366f408e8c6047d52acbed35e9d665249bbaba2b Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> --- src/gui/painting/qdrawhelper_avx2.cpp | 28 +++++++++------------ src/gui/painting/qdrawhelper_sse4.cpp | 36 +++++++++++++-------------- 2 files changed, 29 insertions(+), 35 deletions(-) diff --git a/src/gui/painting/qdrawhelper_avx2.cpp b/src/gui/painting/qdrawhelper_avx2.cpp index f05cc0926e..2b3cc9b226 100644 --- a/src/gui/painting/qdrawhelper_avx2.cpp +++ b/src/gui/painting/qdrawhelper_avx2.cpp @@ -1135,14 +1135,12 @@ static void convertARGBToRGBA64PM_avx2(QRgba64 *buffer, const uint *src, qsizety const __m256i src1 = _mm256_unpacklo_epi8(srcVector, srcVector); const __m256i src2 = _mm256_unpackhi_epi8(srcVector, srcVector); if (!cf) { - dst1 = _mm256_unpacklo_epi8(srcVector, zero); - dst2 = _mm256_unpackhi_epi8(srcVector, zero); - const __m256i alpha1 = _mm256_shuffle_epi8(dst1, shuffleMask); - const __m256i alpha2 = _mm256_shuffle_epi8(dst2, shuffleMask); - dst1 = _mm256_mullo_epi16(dst1, alpha1); - dst2 = _mm256_mullo_epi16(dst2, alpha2); - dst1 = _mm256_add_epi16(dst1, _mm256_srli_epi16(dst1, 7)); - dst2 = _mm256_add_epi16(dst2, _mm256_srli_epi16(dst2, 7)); + const __m256i alpha1 = _mm256_shuffle_epi8(src1, shuffleMask); + const __m256i alpha2 = _mm256_shuffle_epi8(src2, shuffleMask); + dst1 = _mm256_mulhi_epu16(src1, alpha1); + dst2 = _mm256_mulhi_epu16(src2, alpha2); + dst1 = _mm256_add_epi16(dst1, _mm256_srli_epi16(dst1, 15)); + dst2 = _mm256_add_epi16(dst2, _mm256_srli_epi16(dst2, 15)); dst1 = _mm256_blend_epi16(dst1, src1, 0x88); dst2 = _mm256_blend_epi16(dst2, src2, 0x88); } else { @@ -1171,14 +1169,12 @@ static void convertARGBToRGBA64PM_avx2(QRgba64 *buffer, const uint *src, qsizety const __m256i src1 = _mm256_unpacklo_epi8(srcVector, srcVector); const __m256i src2 = _mm256_unpackhi_epi8(srcVector, srcVector); if (!cf) { - dst1 = _mm256_unpacklo_epi8(srcVector, zero); - dst2 = _mm256_unpackhi_epi8(srcVector, zero); - const __m256i alpha1 = _mm256_shuffle_epi8(dst1, shuffleMask); - const __m256i alpha2 = _mm256_shuffle_epi8(dst2, shuffleMask); - dst1 = _mm256_mullo_epi16(dst1, alpha1); - dst2 = _mm256_mullo_epi16(dst2, alpha2); - dst1 = _mm256_add_epi16(dst1, _mm256_srli_epi16(dst1, 7)); - dst2 = _mm256_add_epi16(dst2, _mm256_srli_epi16(dst2, 7)); + const __m256i alpha1 = _mm256_shuffle_epi8(src1, shuffleMask); + const __m256i alpha2 = _mm256_shuffle_epi8(src2, shuffleMask); + dst1 = _mm256_mulhi_epu16(src1, alpha1); + dst2 = _mm256_mulhi_epu16(src2, alpha2); + dst1 = _mm256_add_epi16(dst1, _mm256_srli_epi16(dst1, 15)); + dst2 = _mm256_add_epi16(dst2, _mm256_srli_epi16(dst2, 15)); dst1 = _mm256_blend_epi16(dst1, src1, 0x88); dst2 = _mm256_blend_epi16(dst2, src2, 0x88); } else { diff --git a/src/gui/painting/qdrawhelper_sse4.cpp b/src/gui/painting/qdrawhelper_sse4.cpp index 1da3b75ade..d9a687b1b4 100644 --- a/src/gui/painting/qdrawhelper_sse4.cpp +++ b/src/gui/painting/qdrawhelper_sse4.cpp @@ -107,28 +107,26 @@ static void convertARGBToRGBA64PM_sse4(QRgba64 *buffer, const uint *src, int cou for (; i < count - 3; i += 4) { __m128i srcVector = _mm_loadu_si128((const __m128i *)&src[i]); if (!_mm_testz_si128(srcVector, alphaMask)) { - if (!_mm_testc_si128(srcVector, alphaMask)) { - if (!RGBA) - srcVector = _mm_shuffle_epi8(srcVector, rgbaMask); - __m128i src1 = _mm_unpacklo_epi8(srcVector, zero); - __m128i src2 = _mm_unpackhi_epi8(srcVector, zero); + bool cf = _mm_testc_si128(srcVector, alphaMask); + + if (!RGBA) + srcVector = _mm_shuffle_epi8(srcVector, rgbaMask); + const __m128i src1 = _mm_unpacklo_epi8(srcVector, srcVector); + const __m128i src2 = _mm_unpackhi_epi8(srcVector, srcVector); + if (!cf) { __m128i alpha1 = _mm_shuffle_epi8(src1, shuffleMask); __m128i alpha2 = _mm_shuffle_epi8(src2, shuffleMask); - src1 = _mm_mullo_epi16(src1, alpha1); - src2 = _mm_mullo_epi16(src2, alpha2); - alpha1 = _mm_unpacklo_epi8(srcVector, srcVector); - alpha2 = _mm_unpackhi_epi8(srcVector, srcVector); - src1 = _mm_add_epi16(src1, _mm_srli_epi16(src1, 7)); - src2 = _mm_add_epi16(src2, _mm_srli_epi16(src2, 7)); - src1 = _mm_blend_epi16(src1, alpha1, 0x88); - src2 = _mm_blend_epi16(src2, alpha2, 0x88); - _mm_storeu_si128((__m128i *)&buffer[i], src1); - _mm_storeu_si128((__m128i *)&buffer[i + 2], src2); + __m128i dst1 = _mm_mulhi_epu16(src1, alpha1); + __m128i dst2 = _mm_mulhi_epu16(src2, alpha2); + // Map 0->0xfffe to 0->0xffff + dst1 = _mm_add_epi16(dst1, _mm_srli_epi16(dst1, 15)); + dst2 = _mm_add_epi16(dst2, _mm_srli_epi16(dst2, 15)); + // correct alpha value: + dst1 = _mm_blend_epi16(dst1, src1, 0x88); + dst2 = _mm_blend_epi16(dst2, src2, 0x88); + _mm_storeu_si128((__m128i *)&buffer[i], dst1); + _mm_storeu_si128((__m128i *)&buffer[i + 2], dst2); } else { - if (!RGBA) - srcVector = _mm_shuffle_epi8(srcVector, rgbaMask); - const __m128i src1 = _mm_unpacklo_epi8(srcVector, srcVector); - const __m128i src2 = _mm_unpackhi_epi8(srcVector, srcVector); _mm_storeu_si128((__m128i *)&buffer[i], src1); _mm_storeu_si128((__m128i *)&buffer[i + 2], src2); } From 6e7a7d5fb917b9099788a5917507dbfa56d5495c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= <morten.sorvig@qt.io> Date: Tue, 27 Nov 2018 22:02:07 +0100 Subject: [PATCH 1073/1650] Wasm: enable source map support for debug builds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The source map location can be configured by setting QMAKE_WASM_SOURCE_MAP_BASE in the .pro file. Fall back to “http://localhost:8000” if not set. Task-number: QTBUG-72002 Change-Id: I9da80dacdefc272f267e5db4caac274d93ba4479 Reviewed-by: Lorn Potter <lorn.potter@gmail.com> --- mkspecs/features/wasm/wasm.prf | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mkspecs/features/wasm/wasm.prf b/mkspecs/features/wasm/wasm.prf index 13ac43443d..c885b166ce 100644 --- a/mkspecs/features/wasm/wasm.prf +++ b/mkspecs/features/wasm/wasm.prf @@ -72,6 +72,13 @@ contains(TEMPLATE, .*app) { } } +# Pass --source-map-base on the linker line. This informs the +# browser where to find the source files when debugging. +WASM_SOURCE_MAP_BASE = http://localhost:8000/ +!isEmpty(QMAKE_WASM_SOURCE_MAP_BASE):\ + WASM_SOURCE_MAP_BASE = $$QMAKE_WASM_SOURCE_MAP_BASE +CONFIG(debug): QMAKE_LFLAGS += --source-map-base $$WASM_SOURCE_MAP_BASE + # Creates the stand-alone version of the library from bitcode !static:contains(TEMPLATE, .*lib): { load(resolve_target) From de4f256d48145778ed56389f5e883c5994b34dd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= <morten.sorvig@qt.io> Date: Tue, 20 Mar 2018 13:30:53 +0100 Subject: [PATCH 1074/1650] Wasm: enable thread support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit configure.json: Make the “thread” feature be allowed for wasm but disabled by default. Change qmake.conf and wasm.prf to enable Emscripten pthreads mode: - Add USE_PTHREADS=1 linker flag - Add PTHREAD_POOL_SIZE linker flag with a default pool size (4). - Add TOTAL_MEMORY linker flag to set available memory (1GB) It is possible to override options such as PTHREAD_POOL_SIZE from the application .pro file using QMAKE_WASM_PTHREAD_POOL_SIZE To change TOTAL_MEMORY, use QMAKE_WASM_TOTAL_MEMORY Make qtloader.js work in pthreads mode: - The Module.instantiateWasm callback must provide the module in addition to the instance to Emscripten. - Set Module.mainScriptUrlOrBlob so that the pthreads web workers can access the main script Task-number: QTBUG-64625 Change-Id: I1ab5a559ec97c27c5fc24500ba5f863bcd275141 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io> Reviewed-by: Lorn Potter <lorn.potter@gmail.com> --- configure.json | 2 +- mkspecs/features/qt.prf | 2 +- mkspecs/features/wasm/wasm.prf | 33 ++++++++++++++++++++++++++ mkspecs/wasm-emscripten/qmake.conf | 1 - src/plugins/platforms/wasm/qtloader.js | 8 ++++--- 5 files changed, 40 insertions(+), 6 deletions(-) diff --git a/configure.json b/configure.json index 4a9e1fc24e..f7449ec068 100644 --- a/configure.json +++ b/configure.json @@ -1199,7 +1199,7 @@ "label": "Thread support", "purpose": "Provides QThread and related classes.", "section": "Kernel", - "condition": "!config.wasm", + "autoDetect": "!config.wasm", "output": [ "publicFeature" ] }, "future": { diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index d8d5acaafd..5ac640190a 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -2,7 +2,7 @@ # due to required Qt modules being missing. !isEmpty(QMAKE_FAILED_REQUIREMENTS): return() -CONFIG *= thread +qtConfig(thread): CONFIG *= thread #handle defines win32 { diff --git a/mkspecs/features/wasm/wasm.prf b/mkspecs/features/wasm/wasm.prf index c885b166ce..de726c674c 100644 --- a/mkspecs/features/wasm/wasm.prf +++ b/mkspecs/features/wasm/wasm.prf @@ -2,6 +2,39 @@ # DESTDIR will be empty if not set in the app .pro file; make sure it has a value isEmpty(DESTDIR): DESTDIR = $$OUT_PWD +exists($$QMAKE_QT_CONFIG) { + qtConfig(thread) { + + EMCC_THREAD_LFLAGS += -s USE_PTHREADS=1 + # Hardcode wasm memory size. Emscripten does not currently support memory growth + # (ALLOW_MEMORY_GROWTH) in pthreads mode, and requires specifying the memory size + # at build time. Further, browsers limit the maximum initial memory size to 1GB. + TOTAL_MEMORY = 1GB + !isEmpty(QMAKE_WASM_TOTAL_MEMORY) { + TOTAL_MEMORY = $$QMAKE_WASM_TOTAL_MEMORY + } + + message("Setting TOTAL_MEMORY to" $$TOTAL_MEMORY) + EMCC_THREAD_LFLAGS += -s TOTAL_MEMORY=$$TOTAL_MEMORY + + # Create worker threads at startup. This is supposed to be an optimization, + # however exceeding the pool size has been obesverved to hang the application. + POOL_SIZE = 4 + !isEmpty(QMAKE_WASM_PTHREAD_POOL_SIZE) { + POOL_SIZE = $$QMAKE_WASM_PTHREAD_POOL_SIZE + } + + message("Setting PTHREAD_POOL_SIZE to" $$POOL_SIZE) + EMCC_THREAD_LFLAGS += -s PTHREAD_POOL_SIZE=$$POOL_SIZE + } else { + EMCC_THREAD_LFLAGS += -s ALLOW_MEMORY_GROWTH=1 + } + QMAKE_LFLAGS += $$EMCC_THREAD_LFLAGS + QMAKE_LFLAGS_DEBUG += $$EMCC_THREAD_LFLAGS + QMAKE_CFLAGS += $$EMCC_THREAD_LFLAGS + QMAKE_CXXFLAGS += $$EMCC_THREAD_LFLAGS +} + # Create js and wasm files for applications contains(TEMPLATE, .*app) { TARGET_BASE = $${TARGET} diff --git a/mkspecs/wasm-emscripten/qmake.conf b/mkspecs/wasm-emscripten/qmake.conf index e7b45d312d..6c4e62aff2 100644 --- a/mkspecs/wasm-emscripten/qmake.conf +++ b/mkspecs/wasm-emscripten/qmake.conf @@ -15,7 +15,6 @@ EMTERP_FLAGS = \ EMCC_COMMON_LFLAGS = \ -s WASM=1 \ -s FULL_ES2=1 \ - -s ALLOW_MEMORY_GROWTH=1 \ -s USE_WEBGL2=1 \ -s NO_EXIT_RUNTIME=0 \ -s ERROR_ON_UNDEFINED_SYMBOLS=1 \ diff --git a/src/plugins/platforms/wasm/qtloader.js b/src/plugins/platforms/wasm/qtloader.js index 37a5308034..84694c7b9f 100644 --- a/src/plugins/platforms/wasm/qtloader.js +++ b/src/plugins/platforms/wasm/qtloader.js @@ -312,13 +312,13 @@ function QtLoader(config) // and is ready to be instantiated. Define the instantiateWasm callback which // emscripten will call to create the instance. Module.instantiateWasm = function(imports, successCallback) { - return WebAssembly.instantiate(wasmModule, imports).then(function(instance) { - successCallback(instance); - return instance; + WebAssembly.instantiate(wasmModule, imports).then(function(instance) { + successCallback(instance, wasmModule); }, function(error) { self.error = error; setStatus("Error"); }); + return {}; }; Module.locateFile = Module.locateFile || function(filename) { @@ -382,6 +382,8 @@ function QtLoader(config) } }); + Module.mainScriptUrlOrBlob = new Blob([emscriptenModuleSource], {type: 'text/javascript'}); + config.restart = function() { // Restart by reloading the page. This will wipe all state which means From c1f4286a5cbc1794fe7be5bdbbd6a0bf29ef84d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= <morten.sorvig@qt.io> Date: Wed, 12 Dec 2018 10:00:05 +0100 Subject: [PATCH 1075/1650] Wasm: Implement QThread::idealThreadCount() Read the navigator.hardwareConcurrency property. Task-number: QTBUG-64625 Change-Id: I2ad582b67e4b0ddac3e3c21febab55543b2e1d6d Reviewed-by: Lorn Potter <lorn.potter@gmail.com> --- src/corelib/thread/qthread_unix.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index 329caa02ba..a13f8ca215 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -100,6 +100,9 @@ #include <sys/neutrino.h> #endif +#if defined(Q_OS_WASM) +#include <emscripten/val.h> +#endif QT_BEGIN_NAMESPACE @@ -499,6 +502,8 @@ int QThread::idealThreadCount() Q_DECL_NOTHROW // as of aug 2008 VxWorks < 6.6 only supports one single core CPU cores = 1; # endif +#elif defined(Q_OS_WASM) + cores = emscripten::val::global("navigator")["hardwareConcurrency"].as<int>(); #else // the rest: Linux, Solaris, AIX, Tru64 cores = (int)sysconf(_SC_NPROCESSORS_ONLN); From 86cf366a30c178006ee23f0fbf5bee1748a26b57 Mon Sep 17 00:00:00 2001 From: Oliver Wolff <oliver.wolff@qt.io> Date: Thu, 31 Jan 2019 13:10:50 +0100 Subject: [PATCH 1076/1650] winrt: Use ES3 ANGLE code path when blitting widgets We run into validation issues when using the ES2 code path when blitting widgets on winrt. By using ES3 we not only avoid this issue, but there might also be performance gains. We now call window()->format() instead of window()->requestedFormat as the latter will not respect the values that were set on initialization of the native window (which is done in QWinRTWindow's constructor). Change-Id: I5ed7a9326691375f9c9cb5d8d22ee8d1b643fbd0 Reviewed-by: Andre de la Rocha <andre.rocha@qt.io> Reviewed-by: Miguel Costa <miguel.costa@qt.io> --- src/plugins/platforms/winrt/qwinrtbackingstore.cpp | 7 +++---- src/plugins/platforms/winrt/qwinrtwindow.cpp | 2 ++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp index c23d48b2dd..fbf611d7f7 100644 --- a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp +++ b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp @@ -45,8 +45,7 @@ #include <QtGui/QOpenGLContext> #include <QtGui/QOpenGLFramebufferObject> -#include <GLES2/gl2.h> -#include <GLES2/gl2ext.h> +#include <GLES3/gl3.h> QT_BEGIN_NAMESPACE @@ -83,7 +82,7 @@ bool QWinRTBackingStore::initialize() return true; d->context.reset(new QOpenGLContext); - QSurfaceFormat format = window()->requestedFormat(); + QSurfaceFormat format = window()->format(); d->context->setFormat(format); d->context->setScreen(window()->screen()); if (!d->context->create()) @@ -138,7 +137,7 @@ void QWinRTBackingStore::flush(QWindow *window, const QRegion ®ion, const QPo const int y2 = y1 + bounds.height(); const int x1 = bounds.x(); const int x2 = x1 + bounds.width(); - glBlitFramebufferANGLE(x1, y1, x2, y2, + glBlitFramebuffer(x1, y1, x2, y2, x1, d->size.height() - y1, x2, d->size.height() - y2, GL_COLOR_BUFFER_BIT, GL_NEAREST); diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp index 29d234d276..83c3715bfd 100644 --- a/src/plugins/platforms/winrt/qwinrtwindow.cpp +++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp @@ -112,6 +112,8 @@ QWinRTWindow::QWinRTWindow(QWindow *window) d->screen = static_cast<QWinRTScreen *>(screen()); handleContentOrientationChange(window->contentOrientation()); + d->surfaceFormat.setMajorVersion(3); + d->surfaceFormat.setMinorVersion(0); d->surfaceFormat.setAlphaBufferSize(0); d->surfaceFormat.setRedBufferSize(8); d->surfaceFormat.setGreenBufferSize(8); From 1036c450860fcc6eb1b5fd702f8ca83972170bb7 Mon Sep 17 00:00:00 2001 From: Oliver Wolff <oliver.wolff@qt.io> Date: Wed, 30 Jan 2019 10:05:31 +0100 Subject: [PATCH 1077/1650] Revert "winrt: Skip context validation in ANGLE" Our current ANGLE version (chromium/3280) relies on validation to be done when doing the rendering, as the validation at the same time completes the caching. Skipping the validation caused asserts and rendering issues. The part of the validation that failed before is now deactivated in Qt's copy of ANGLE as it is not relevant for our use case, so that validation can be re-enabled now. This reverts commit a1dec825f9aa9d7f86d740fd420f1c084463f507. Fixes: QTBUG-73317 Change-Id: I5fd176eaa0bc28d93ca93019b7092211fe5bcce5 Reviewed-by: Miguel Costa <miguel.costa@qt.io> Reviewed-by: Andre de la Rocha <andre.rocha@qt.io> --- src/plugins/platforms/winrt/qwinrteglcontext.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.cpp b/src/plugins/platforms/winrt/qwinrteglcontext.cpp index eeb79be2e6..5ce2671bf1 100644 --- a/src/plugins/platforms/winrt/qwinrteglcontext.cpp +++ b/src/plugins/platforms/winrt/qwinrteglcontext.cpp @@ -138,7 +138,6 @@ void QWinRTEGLContext::initialize() EGL_CONTEXT_CLIENT_VERSION, d->format.majorVersion(), EGL_CONTEXT_MINOR_VERSION_KHR, d->format.minorVersion(), EGL_CONTEXT_FLAGS_KHR, flags, - EGL_CONTEXT_OPENGL_NO_ERROR_KHR, true, EGL_NONE }; d->eglContext = eglCreateContext(g->eglDisplay, d->eglConfig, d->eglShareContext, attributes); From 932b13d3ec76eedfc0e76e81c05b2d54552c0715 Mon Sep 17 00:00:00 2001 From: Oliver Wolff <oliver.wolff@qt.io> Date: Mon, 4 Feb 2019 11:23:16 +0100 Subject: [PATCH 1078/1650] windows: Support OpenGL ES versions > 3.0 with ANGLE Even though our ANGLE versions only partially supports OpenGL ES > 3.0, there are users who want to use functionality that is available. By setting major and minor version we can support this use case. Fixes: QTBUG-72762 Change-Id: I9a1d3009355693baa971deb3c4bbf14c595edf0b Reviewed-by: Andre de la Rocha <andre.rocha@qt.io> Reviewed-by: Miguel Costa <miguel.costa@qt.io> --- src/plugins/platforms/windows/qwindowseglcontext.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp index 70ba2784e9..063e81150e 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp @@ -393,8 +393,14 @@ QWindowsEGLContext::QWindowsEGLContext(QWindowsEGLStaticContext *staticContext, m_shareContext = share ? static_cast<QWindowsEGLContext *>(share)->m_eglContext : nullptr; QVector<EGLint> contextAttrs; - contextAttrs.append(EGL_CONTEXT_CLIENT_VERSION); - contextAttrs.append(m_format.majorVersion()); + const int major = m_format.majorVersion(); + const int minor = m_format.minorVersion(); + if (major > 3 || (major == 3 && minor > 0)) + qWarning("QWindowsEGLContext: ANGLE only partially supports OpenGL ES > 3.0"); + contextAttrs.append(EGL_CONTEXT_MAJOR_VERSION); + contextAttrs.append(major); + contextAttrs.append(EGL_CONTEXT_MINOR_VERSION); + contextAttrs.append(minor); contextAttrs.append(EGL_NONE); QWindowsEGLStaticContext::libEGL.eglBindAPI(m_api); From 5f384bd39c54b6bd60e71af1e3ac1b8168a33ed9 Mon Sep 17 00:00:00 2001 From: Oliver Wolff <oliver.wolff@qt.io> Date: Mon, 4 Feb 2019 12:15:54 +0100 Subject: [PATCH 1079/1650] winrt: Warn if OpenGL ES version is set to a value > 3.0 Our bundled ANGLE library only partially supports OpenGL ES > 3.0 so warn users that there might be dragons. Change-Id: I16711fe9f449e85dd8b2369e1fcec6c9f81d5ae0 Reviewed-by: Andre de la Rocha <andre.rocha@qt.io> Reviewed-by: Miguel Costa <miguel.costa@qt.io> --- src/plugins/platforms/winrt/qwinrteglcontext.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.cpp b/src/plugins/platforms/winrt/qwinrteglcontext.cpp index 5ce2671bf1..aa64ac1f99 100644 --- a/src/plugins/platforms/winrt/qwinrteglcontext.cpp +++ b/src/plugins/platforms/winrt/qwinrteglcontext.cpp @@ -134,6 +134,10 @@ void QWinRTEGLContext::initialize() const EGLint flags = d->format.testOption(QSurfaceFormat::DebugContext) ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0; + const int major = d->format.majorVersion(); + const int minor = d->format.minorVersion(); + if (major > 3 || (major == 3 && minor > 0)) + qWarning("QWinRTEGLContext: ANGLE only partially supports OpenGL ES > 3.0"); const EGLint attributes[] = { EGL_CONTEXT_CLIENT_VERSION, d->format.majorVersion(), EGL_CONTEXT_MINOR_VERSION_KHR, d->format.minorVersion(), From bf7458c76fcf821637368d05938823e42fbb28d5 Mon Sep 17 00:00:00 2001 From: Oliver Wolff <oliver.wolff@qt.io> Date: Wed, 6 Feb 2019 11:16:32 +0100 Subject: [PATCH 1080/1650] winrt qpa: Remove last windows phone leftovers WINAPI_PARTITION_PHONE_APP is defined for all our winrt mkspecs nowadays so the code can be used unconditionally. Change-Id: I4f2b60a0b9bba5b407ebbc213c44a0e5b4057855 Reviewed-by: Maurice Kalinowski <maurice.kalinowski@qt.io> --- .../platforms/winrt/qwinrtinputcontext.cpp | 4 --- .../platforms/winrt/qwinrtinputcontext.h | 2 -- src/plugins/platforms/winrt/qwinrtscreen.cpp | 29 ------------------- src/plugins/platforms/winrt/qwinrtscreen.h | 5 ---- 4 files changed, 40 deletions(-) diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp index f7e91bb047..5ae94ba613 100644 --- a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp +++ b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp @@ -158,8 +158,6 @@ HRESULT QWinRTInputContext::handleVisibilityChange(IInputPane *pane) return S_OK; } -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) - static HRESULT getInputPane(ComPtr<IInputPane2> *inputPane2) { ComPtr<IInputPaneStatics> factory; @@ -221,6 +219,4 @@ void QWinRTInputContext::hideInputPanel() }); } -#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) - QT_END_NAMESPACE diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.h b/src/plugins/platforms/winrt/qwinrtinputcontext.h index 13a0088ddc..59db90231f 100644 --- a/src/plugins/platforms/winrt/qwinrtinputcontext.h +++ b/src/plugins/platforms/winrt/qwinrtinputcontext.h @@ -74,10 +74,8 @@ public: bool isInputPanelVisible() const override; -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) void showInputPanel() override; void hideInputPanel() override; -#endif private slots: void updateScreenCursorRect(); diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index bd2bbcb81c..7f1854c601 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -91,13 +91,10 @@ typedef ITypedEventHandler<CoreWindow*, CharacterReceivedEventArgs*> CharacterRe typedef ITypedEventHandler<CoreWindow*, InputEnabledEventArgs*> InputEnabledHandler; typedef ITypedEventHandler<CoreWindow*, KeyEventArgs*> KeyHandler; typedef ITypedEventHandler<CoreWindow*, PointerEventArgs*> PointerHandler; -typedef ITypedEventHandler<CoreWindow*, WindowSizeChangedEventArgs*> SizeChangedHandler; typedef ITypedEventHandler<CoreWindow*, VisibilityChangedEventArgs*> VisibilityChangedHandler; typedef ITypedEventHandler<DisplayInformation*, IInspectable*> DisplayInformationHandler; typedef ITypedEventHandler<ICorePointerRedirector*, PointerEventArgs*> RedirectHandler; -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) typedef ITypedEventHandler<ApplicationView*, IInspectable*> VisibleBoundsChangedHandler; -#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) QT_BEGIN_NAMESPACE @@ -479,10 +476,8 @@ typedef HRESULT (__stdcall IDisplayInformation::*DisplayCallbackRemover)(EventRe uint qHash(DisplayCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); } typedef HRESULT (__stdcall ICorePointerRedirector::*RedirectorCallbackRemover)(EventRegistrationToken); uint qHash(RedirectorCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); } -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) typedef HRESULT (__stdcall IApplicationView2::*ApplicationView2CallbackRemover)(EventRegistrationToken); uint qHash(ApplicationView2CallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); } -#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) class QWinRTScreenPrivate { @@ -509,10 +504,8 @@ public: QHash<CoreWindowCallbackRemover, EventRegistrationToken> windowTokens; QHash<DisplayCallbackRemover, EventRegistrationToken> displayTokens; QHash<RedirectorCallbackRemover, EventRegistrationToken> redirectTokens; -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) QHash<ApplicationView2CallbackRemover, EventRegistrationToken> view2Tokens; ComPtr<IApplicationView2> view2; -#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) QAtomicPointer<QWinRTWindow> mouseGrabWindow; QAtomicPointer<QWinRTWindow> keyboardGrabWindow; QWindow *currentPressWindow = nullptr; @@ -603,10 +596,8 @@ QWinRTScreen::QWinRTScreen() d->cursor.reset(new QWinRTCursor); -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) hr = d->view.As(&d->view2); Q_ASSERT_SUCCEEDED(hr); -#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) } QWinRTScreen::~QWinRTScreen() @@ -630,12 +621,10 @@ QWinRTScreen::~QWinRTScreen() hr = (d->redirect.Get()->*i.key())(i.value()); Q_ASSERT_SUCCEEDED(hr); } -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) for (QHash<ApplicationView2CallbackRemover, EventRegistrationToken>::const_iterator i = d->view2Tokens.begin(); i != d->view2Tokens.end(); ++i) { hr = (d->view2.Get()->*i.key())(i.value()); Q_ASSERT_SUCCEEDED(hr); } -#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) return hr; }); RETURN_VOID_IF_FAILED("Failed to unregister screen event callbacks"); @@ -777,14 +766,8 @@ void QWinRTScreen::initialize() Q_ASSERT_SUCCEEDED(hr); hr = d->coreWindow->add_PointerWheelChanged(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &d->windowTokens[&ICoreWindow::remove_PointerWheelChanged]); Q_ASSERT_SUCCEEDED(hr); -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) hr = d->view2->add_VisibleBoundsChanged(Callback<VisibleBoundsChangedHandler>(this, &QWinRTScreen::onWindowSizeChanged).Get(), &d->view2Tokens[&IApplicationView2::remove_VisibleBoundsChanged]); Q_ASSERT_SUCCEEDED(hr); -#else - hr = d->coreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &QWinRTScreen::onWindowSizeChanged).Get(), &d->windowTokens[&ICoreWindow::remove_SizeChanged]); - Q_ASSERT_SUCCEEDED(hr) -#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) - hr = d->coreWindow->add_Activated(Callback<ActivatedHandler>(this, &QWinRTScreen::onActivated).Get(), &d->windowTokens[&ICoreWindow::remove_Activated]); Q_ASSERT_SUCCEEDED(hr); hr = d->coreWindow->add_Closed(Callback<ClosedHandler>(this, &QWinRTScreen::onClosed).Get(), &d->windowTokens[&ICoreWindow::remove_Closed]); @@ -820,7 +803,6 @@ void QWinRTScreen::setKeyboardRect(const QRectF &keyboardRect) return; } d->logicalRect = QRectF(windowSize.X, windowSize.Y, windowSize.Width, windowSize.Height); -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) Rect visibleRect; hr = d->view2->get_VisibleBounds(&visibleRect); if (FAILED(hr)) { @@ -828,9 +810,6 @@ void QWinRTScreen::setKeyboardRect(const QRectF &keyboardRect) return; } visibleRectF = QRectF(visibleRect.X, visibleRect.Y, visibleRect.Width, visibleRect.Height); -#else - visibleRectF = d->logicalRect; -#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) // if keyboard is snapped to the bottom of the screen and would cover the cursor the content is // moved up to make it visible if (keyboardRect.intersects(mCursorRect) @@ -1528,11 +1507,7 @@ HRESULT QWinRTScreen::onRedirectReleased(ICorePointerRedirector *, IPointerEvent return onPointerUpdated(nullptr, args); } -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) HRESULT QWinRTScreen::onWindowSizeChanged(IApplicationView *, IInspectable *) -#else -HRESULT QWinRTScreen::onWindowSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *) -#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) { Q_D(QWinRTScreen); @@ -1543,14 +1518,10 @@ HRESULT QWinRTScreen::onWindowSizeChanged(ICoreWindow *, IWindowSizeChangedEvent RETURN_OK_IF_FAILED("Failed to get window bounds"); d->logicalRect = QRectF(windowSize.X, windowSize.Y, windowSize.Width, windowSize.Height); -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) Rect visibleRect; hr = d->view2->get_VisibleBounds(&visibleRect); RETURN_OK_IF_FAILED("Failed to get window visible bounds"); d->visibleRect = QRectF(visibleRect.X, visibleRect.Y, visibleRect.Width, visibleRect.Height); -#else - d->visibleRect = QRectF(windowSize.X, windowSize.Y, windowSize.Width, windowSize.Height); -#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) qCDebug(lcQpaWindows) << __FUNCTION__ << d->logicalRect; QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), availableGeometry()); diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h index cde148a638..e28cfd8cc8 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.h +++ b/src/plugins/platforms/winrt/qwinrtscreen.h @@ -59,7 +59,6 @@ namespace ABI { struct IPointerEventArgs; struct IVisibilityChangedEventArgs; struct IWindowActivatedEventArgs; - struct IWindowSizeChangedEventArgs; } namespace Xaml { struct IDependencyObject; @@ -154,11 +153,7 @@ private: HRESULT onOrientationChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *); HRESULT onDpiChanged(ABI::Windows::Graphics::Display::IDisplayInformation *, IInspectable *); -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) HRESULT onWindowSizeChanged(ABI::Windows::UI::ViewManagement::IApplicationView *, IInspectable *); -#else - HRESULT onWindowSizeChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *); -#endif HRESULT onRedirectReleased(ABI::Windows::UI::Core::ICorePointerRedirector *, ABI::Windows::UI::Core::IPointerEventArgs *); QScopedPointer<QWinRTScreenPrivate> d_ptr; From 90a8de656fe689b6aa856e70e2d22de6630ea855 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen <allan.jensen@qt.io> Date: Tue, 26 Jun 2018 17:12:02 +0200 Subject: [PATCH 1081/1650] Long live QColorSpace and friends Adds QColorSpace and QColorTransform classes, and parsing of a common subset of ICC profiles found in images, and also parses the ICC profiles in PNG and JPEGs. For backwards compatibility no automatic color handling is done by this patch. [ChangeLog][QtGui] A QColorSpace class has been added, and color spaces are now parsed from PNG and JPEG images. No automatic color space conversion is done however, and applications must request it. Change-Id: Ic09935f84640a716467fa3a9ed1e73c02daf3675 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io> --- .../widgets/imageviewer/imageviewer.cpp | 2 + src/gui/image/qimage.cpp | 134 +++- src/gui/image/qimage.h | 10 +- src/gui/image/qimage_conversions.cpp | 4 +- src/gui/image/qimage_p.h | 4 + src/gui/image/qpnghandler.cpp | 72 +- src/gui/kernel/qguiapplication.cpp | 30 +- src/gui/kernel/qguiapplication_p.h | 11 +- src/gui/painting/painting.pri | 16 +- src/gui/painting/qcolormatrix_p.h | 214 ++++++ src/gui/painting/qcolorspace.cpp | 633 ++++++++++++++++ src/gui/painting/qcolorspace.h | 136 ++++ src/gui/painting/qcolorspace_p.h | 96 +++ src/gui/painting/qcolortransferfunction_p.h | 207 ++++++ src/gui/painting/qcolortransfertable_p.h | 245 +++++++ src/gui/painting/qcolortransform.cpp | 679 ++++++++++++++++++ src/gui/painting/qcolortransform.h | 93 +++ src/gui/painting/qcolortransform_p.h | 89 +++ src/gui/painting/qcolortrc_p.h | 129 ++++ .../{qcolorprofile.cpp => qcolortrclut.cpp} | 49 +- .../{qcolorprofile_p.h => qcolortrclut_p.h} | 72 +- src/gui/painting/qdrawhelper.cpp | 22 +- src/gui/painting/qicc.cpp | 669 +++++++++++++++++ src/gui/painting/qicc_p.h | 70 ++ src/gui/painting/qpainter_p.h | 2 + .../imageformats/jpeg/qjpeghandler.cpp | 14 +- tests/auto/gui/painting/painting.pro | 1 + tests/auto/gui/painting/qcolor/tst_qcolor.cpp | 5 +- .../gui/painting/qcolorspace/qcolorspace.pro | 9 + .../qcolorspace/resources/ProPhoto.jpg | Bin 0 -> 30900 bytes .../qcolorspace/resources/sRGB2014.icc | Bin 0 -> 3024 bytes .../painting/qcolorspace/tst_qcolorspace.cpp | 238 ++++++ 32 files changed, 3863 insertions(+), 92 deletions(-) create mode 100644 src/gui/painting/qcolormatrix_p.h create mode 100644 src/gui/painting/qcolorspace.cpp create mode 100644 src/gui/painting/qcolorspace.h create mode 100644 src/gui/painting/qcolorspace_p.h create mode 100644 src/gui/painting/qcolortransferfunction_p.h create mode 100644 src/gui/painting/qcolortransfertable_p.h create mode 100644 src/gui/painting/qcolortransform.cpp create mode 100644 src/gui/painting/qcolortransform.h create mode 100644 src/gui/painting/qcolortransform_p.h create mode 100644 src/gui/painting/qcolortrc_p.h rename src/gui/painting/{qcolorprofile.cpp => qcolortrclut.cpp} (69%) rename src/gui/painting/{qcolorprofile_p.h => qcolortrclut_p.h} (87%) create mode 100644 src/gui/painting/qicc.cpp create mode 100644 src/gui/painting/qicc_p.h create mode 100644 tests/auto/gui/painting/qcolorspace/qcolorspace.pro create mode 100644 tests/auto/gui/painting/qcolorspace/resources/ProPhoto.jpg create mode 100644 tests/auto/gui/painting/qcolorspace/resources/sRGB2014.icc create mode 100644 tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp diff --git a/examples/widgets/widgets/imageviewer/imageviewer.cpp b/examples/widgets/widgets/imageviewer/imageviewer.cpp index fed551dade..2fc8ff63de 100644 --- a/examples/widgets/widgets/imageviewer/imageviewer.cpp +++ b/examples/widgets/widgets/imageviewer/imageviewer.cpp @@ -106,6 +106,8 @@ bool ImageViewer::loadFile(const QString &fileName) void ImageViewer::setImage(const QImage &newImage) { image = newImage; + if (image.colorSpace().isValid()) + image.convertToColorSpace(QColorSpace::SRgb); imageLabel->setPixmap(QPixmap::fromImage(image)); //! [4] scaleFactor = 1.0; diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 16de045cf0..204729b551 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2018 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -38,8 +38,10 @@ ****************************************************************************/ #include "qimage.h" -#include "qdatastream.h" + #include "qbuffer.h" +#include "qdatastream.h" +#include "qcolortransform.h" #include "qmap.h" #include "qmatrix.h" #include "qtransform.h" @@ -54,6 +56,7 @@ #include <stdlib.h> #include <limits.h> #include <qpa/qplatformpixmap.h> +#include <private/qcolortransform_p.h> #include <private/qdrawhelper_p.h> #include <private/qmemrotate_p.h> #include <private/qimagescale_p.h> @@ -1098,6 +1101,7 @@ static void copyMetadata(QImageData *dst, const QImageData *src) dst->dpmy = src->dpmy; dst->devicePixelRatio = src->devicePixelRatio; dst->text = src->text; + dst->colorSpace = src->colorSpace; } /*! @@ -4920,6 +4924,132 @@ QTransform QImage::trueMatrix(const QTransform &matrix, int w, int h) return matrix * QTransform().translate(-delta.x(), -delta.y()); } +/*! + \since 5.14 + + Sets the image color space to \a colorSpace without performing any conversions on image data. + + \sa colorSpace() +*/ +void QImage::setColorSpace(const QColorSpace &colorSpace) +{ + if (!d) + return; + if (d->colorSpace == colorSpace) + return; + if (!isDetached()) // Detach only if shared, not for read-only data. + detach(); + d->colorSpace = colorSpace; +} + +/*! + \since 5.14 + + Converts the image to \a colorSpace. + + If the image has no valid color space, the method does nothing. + + \sa convertedToColorSpace(), setColorSpace() +*/ +void QImage::convertToColorSpace(const QColorSpace &colorSpace) +{ + if (!d) + return; + if (!d->colorSpace.isValid()) + return; + if (!colorSpace.isValid()) { + qWarning() << "QImage::convertToColorSpace: Output colorspace is not valid"; + return; + } + detach(); + applyColorTransform(d->colorSpace.transformationToColorSpace(colorSpace)); + d->colorSpace = colorSpace; +} + +/*! + \since 5.14 + + Returns the image converted to \a colorSpace. + + If the image has no valid color space, a null QImage is returned. + + \sa convertToColorSpace() +*/ +QImage QImage::convertedToColorSpace(const QColorSpace &colorSpace) const +{ + if (!d || !d->colorSpace.isValid() || !colorSpace.isValid()) + return QImage(); + QImage image = copy(); + image.convertToColorSpace(colorSpace); + return image; +} + +/*! + \since 5.14 + + Returns the color space of the image if a color space is defined. +*/ +QColorSpace QImage::colorSpace() const +{ + if (!d) + return QColorSpace::Undefined; + return d->colorSpace; +} + +/*! + \since 5.14 + + Applies the color transformation \a transform to all pixels in the image. +*/ +void QImage::applyColorTransform(const QColorTransform &transform) +{ + QImage::Format oldFormat = format(); + if (depth() > 32) { + if (format() != QImage::Format_RGBX64 && format() != QImage::Format_RGBA64 + && format() != QImage::Format_RGBA64_Premultiplied) + *this = std::move(*this).convertToFormat(QImage::Format_RGBA64); + } else if (format() != QImage::Format_ARGB32 && format() != QImage::Format_RGB32 + && format() != QImage::Format_ARGB32_Premultiplied) { + if (hasAlphaChannel()) + *this = std::move(*this).convertToFormat(QImage::Format_ARGB32); + else + *this = std::move(*this).convertToFormat(QImage::Format_RGB32); + } + + QColorTransformPrivate::TransformFlags flags = QColorTransformPrivate::Unpremultiplied; + switch (format()) { + case Format_ARGB32_Premultiplied: + case Format_RGBA64_Premultiplied: + flags = QColorTransformPrivate::Premultiplied; + break; + case Format_RGB32: + case Format_RGBX64: + flags = QColorTransformPrivate::InputOpaque; + break; + case Format_ARGB32: + case Format_RGBA64: + break; + default: + Q_UNREACHABLE(); + } + + if (depth() > 32) { + for (int i = 0; i < height(); ++i) { + QRgba64 *scanline = reinterpret_cast<QRgba64 *>(scanLine(i)); + transform.d_func()->apply(scanline, scanline, width(), flags); + } + } else { + for (int i = 0; i < height(); ++i) { + QRgb *scanline = reinterpret_cast<QRgb *>(scanLine(i)); + transform.d_func()->apply(scanline, scanline, width(), flags); + } + } + + if (oldFormat != format()) + *this = std::move(*this).convertToFormat(oldFormat); +} + + bool QImageData::convertInPlace(QImage::Format newFormat, Qt::ImageConversionFlags flags) { if (format == newFormat) diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h index 45f571807c..b09e69c839 100644 --- a/src/gui/image/qimage.h +++ b/src/gui/image/qimage.h @@ -61,9 +61,11 @@ Q_FORWARD_DECLARE_MUTABLE_CG_TYPE(CGImage); QT_BEGIN_NAMESPACE +class QColorSpace; +class QColorTransform; class QIODevice; -class QStringList; class QMatrix; +class QStringList; class QTransform; class QVariant; template <class T> class QList; @@ -296,6 +298,12 @@ public: #endif void invertPixels(InvertMode = InvertRgb); + QColorSpace colorSpace() const; + QImage convertedToColorSpace(const QColorSpace &) const; + void convertToColorSpace(const QColorSpace &); + void setColorSpace(const QColorSpace &); + + void applyColorTransform(const QColorTransform &transform); bool load(QIODevice *device, const char* format); bool load(const QString &fileName, const char *format = nullptr); diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index 82ffb8af8b..837ac88470 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -39,7 +39,7 @@ #include <private/qdrawhelper_p.h> #include <private/qguiapplication_p.h> -#include <private/qcolorprofile_p.h> +#include <private/qcolortrclut_p.h> #include <private/qendian_p.h> #include <private/qsimd_p.h> #include <private/qimage_p.h> @@ -100,7 +100,7 @@ const uchar *qt_get_bitflip_array() void qGamma_correct_back_to_linear_cs(QImage *image) { - const QColorProfile *cp = QGuiApplicationPrivate::instance()->colorProfileForA32Text(); + const QColorTrcLut *cp = QGuiApplicationPrivate::instance()->colorProfileForA32Text(); if (!cp) return; // gamma correct the pixels back to linear color space... diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h index de12a313e8..a599fc17c9 100644 --- a/src/gui/image/qimage_p.h +++ b/src/gui/image/qimage_p.h @@ -51,7 +51,9 @@ // We mean it. // +#include <QtGui/qcolorspace.h> #include <QtGui/private/qtguiglobal_p.h> +#include <QtGui/qimage.h> #include <QtCore/private/qnumeric_p.h> #include <QMap> @@ -106,6 +108,8 @@ struct Q_GUI_EXPORT QImageData { // internal image data QPaintEngine *paintEngine; + QColorSpace colorSpace; + struct ImageSizeParameters { qsizetype bytesPerLine; qsizetype totalSize; diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index 3655c39326..066261620b 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -42,6 +42,7 @@ #ifndef QT_NO_IMAGEFORMAT_PNG #include <qcoreapplication.h> +#include <qdebug.h> #include <qiodevice.h> #include <qimage.h> #include <qlist.h> @@ -50,6 +51,10 @@ #include <private/qimage_p.h> // for qt_getImageText +#include <qcolorspace.h> +#include <private/qcolorspace_p.h> +#include <private/qicc_p.h> + #include <png.h> #include <pngconf.h> @@ -96,9 +101,16 @@ public: ReadingEnd, Error }; + // Defines the order of how the various ways of setting colorspace overrides eachother: + enum ColorSpaceState { + Undefined = 0, + GammaChrm = 1, // gAMA+cHRM chunks + Srgb = 2, // sRGB chunk + Icc = 3 // iCCP chunk + }; QPngHandlerPrivate(QPngHandler *qq) - : gamma(0.0), fileGamma(0.0), quality(50), compression(50), png_ptr(0), info_ptr(0), end_info(0), state(Ready), q(qq) + : gamma(0.0), fileGamma(0.0), quality(50), compression(50), colorSpaceState(Undefined), png_ptr(0), info_ptr(0), end_info(0), state(Ready), q(qq) { } float gamma; @@ -108,6 +120,8 @@ public: QString description; QSize scaledSize; QStringList readTexts; + QColorSpace colorSpace; + ColorSpaceState colorSpaceState; png_struct *png_ptr; png_info *info_ptr; @@ -226,11 +240,8 @@ void qpiw_flush_fn(png_structp /* png_ptr */) } static -void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scaledSize, bool *doScaledRead, float screen_gamma=0.0, float file_gamma=0.0) +void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scaledSize, bool *doScaledRead) { - if (screen_gamma != 0.0 && file_gamma != 0.0) - png_set_gamma(png_ptr, 1.0f / screen_gamma, file_gamma); - png_uint_32 width; png_uint_32 height; int bit_depth; @@ -585,10 +596,45 @@ bool QPngHandlerPrivate::readPngHeader() readPngTexts(info_ptr); +#ifdef PNG_iCCP_SUPPORTED + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_iCCP)) { + png_charp name = nullptr; + int compressionType = 0; +#if (PNG_LIBPNG_VER < 10500) + png_charp profileData = nullptr; +#else + png_bytep profileData = nullptr; +#endif + png_uint_32 profLen; + png_get_iCCP(png_ptr, info_ptr, &name, &compressionType, &profileData, &profLen); + if (!QIcc::fromIccProfile(QByteArray::fromRawData((const char *)profileData, profLen), &colorSpace)) { + qWarning() << "QPngHandler: Failed to parse ICC profile"; + } else { + colorSpaceState = Icc; + } + } +#endif + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sRGB)) { + int rendering_intent = -1; + png_get_sRGB(png_ptr, info_ptr, &rendering_intent); + // We don't actually care about the rendering_intent, just that it is valid + if (rendering_intent >= 0 && rendering_intent <= 3 && colorSpaceState <= Srgb) { + colorSpace = QColorSpace::SRgb; + colorSpaceState = Srgb; + } + } if (png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA)) { double file_gamma = 0.0; png_get_gAMA(png_ptr, info_ptr, &file_gamma); fileGamma = file_gamma; + if (fileGamma > 0.0f && colorSpaceState <= GammaChrm) { + QColorSpacePrivate *csPrivate = colorSpace.d_func(); + csPrivate->gamut = QColorSpace::Gamut::SRgb; + csPrivate->transferFunction = QColorSpace::TransferFunction::Gamma; + csPrivate->gamma = fileGamma; + csPrivate->initialize(); + colorSpaceState = GammaChrm; + } } state = ReadHeader; @@ -613,8 +659,19 @@ bool QPngHandlerPrivate::readPngImage(QImage *outImage) return false; } + if (gamma != 0.0 && fileGamma != 0.0) { + // This configuration forces gamma correction and + // thus changes the output colorspace + png_set_gamma(png_ptr, 1.0f / gamma, fileGamma); + QColorSpacePrivate *csPrivate = colorSpace.d_func(); + csPrivate->transferFunction = QColorSpace::TransferFunction::Gamma; + csPrivate->gamma = gamma; + csPrivate->initialize(); + colorSpaceState = GammaChrm; + } + bool doScaledRead = false; - setup_qt(*outImage, png_ptr, info_ptr, scaledSize, &doScaledRead, gamma, fileGamma); + setup_qt(*outImage, png_ptr, info_ptr, scaledSize, &doScaledRead); if (outImage->isNull()) { png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); @@ -683,6 +740,9 @@ bool QPngHandlerPrivate::readPngImage(QImage *outImage) if (scaledSize.isValid() && outImage->size() != scaledSize) *outImage = outImage->scaled(scaledSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + if (colorSpaceState > Undefined && colorSpace.isValid()) + outImage->setColorSpace(colorSpace); + return true; } diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 4a0febc615..6753bf64bc 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -68,7 +68,7 @@ #include <qpalette.h> #include <qscreen.h> #include "qsessionmanager.h" -#include <private/qcolorprofile_p.h> +#include <private/qcolortrclut_p.h> #include <private/qscreen_p.h> #include <QtGui/qgenericpluginfactory.h> @@ -1643,8 +1643,6 @@ QGuiApplicationPrivate::~QGuiApplicationPrivate() platform_theme = 0; delete platform_integration; platform_integration = 0; - delete m_a8ColorProfile.load(); - delete m_a32ColorProfile.load(); window_list.clear(); screen_list.clear(); @@ -4019,32 +4017,26 @@ void QGuiApplicationPrivate::notifyDragStarted(const QDrag *drag) } #endif -const QColorProfile *QGuiApplicationPrivate::colorProfileForA8Text() +const QColorTrcLut *QGuiApplicationPrivate::colorProfileForA8Text() { #ifdef Q_OS_WIN - QColorProfile *result = m_a8ColorProfile.load(); - if (!result){ - QColorProfile *cs = QColorProfile::fromGamma(2.31); // This is a hard-coded thing for Windows text rendering - if (!m_a8ColorProfile.testAndSetRelease(0, cs)) - delete cs; - result = m_a8ColorProfile.load(); + if (!m_a8ColorProfile){ + QColorTrcLut *cs = QColorTrcLut::fromGamma(2.31); // This is a hard-coded thing for Windows text rendering + m_a8ColorProfile.reset(cs); } - return result; + return m_a8ColorProfile.get(); #else return colorProfileForA32Text(); #endif } -const QColorProfile *QGuiApplicationPrivate::colorProfileForA32Text() +const QColorTrcLut *QGuiApplicationPrivate::colorProfileForA32Text() { - QColorProfile *result = m_a32ColorProfile.load(); - if (!result){ - QColorProfile *cs = QColorProfile::fromGamma(fontSmoothingGamma); - if (!m_a32ColorProfile.testAndSetRelease(0, cs)) - delete cs; - result = m_a32ColorProfile.load(); + if (!m_a32ColorProfile) { + QColorTrcLut *cs = QColorTrcLut::fromGamma(fontSmoothingGamma); + m_a32ColorProfile.reset(cs); } - return result; + return m_a32ColorProfile.get(); } void QGuiApplicationPrivate::_q_updateFocusObject(QObject *object) diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h index 63646dcd50..61d9661286 100644 --- a/src/gui/kernel/qguiapplication_p.h +++ b/src/gui/kernel/qguiapplication_p.h @@ -55,6 +55,7 @@ #include <QtGui/qguiapplication.h> #include <QtCore/QPointF> +#include <QtCore/QSharedPointer> #include <QtCore/private/qcoreapplication_p.h> #include <QtCore/private/qthread_p.h> @@ -66,7 +67,7 @@ QT_BEGIN_NAMESPACE -class QColorProfile; +class QColorTrcLut; class QPlatformIntegration; class QPlatformTheme; class QPlatformDragQtResponse; @@ -299,8 +300,8 @@ public: static QInputDeviceManager *inputDeviceManager(); - const QColorProfile *colorProfileForA8Text(); - const QColorProfile *colorProfileForA32Text(); + const QColorTrcLut *colorProfileForA8Text(); + const QColorTrcLut *colorProfileForA32Text(); // hook reimplemented in QApplication to apply the QStyle function on the QIcon virtual QPixmap applyQIconStyleHelper(QIcon::Mode, const QPixmap &basePixmap) const { return basePixmap; } @@ -327,8 +328,8 @@ private: static QGuiApplicationPrivate *self; static QTouchDevice *m_fakeTouchDevice; static int m_fakeMouseSourcePointId; - QAtomicPointer<QColorProfile> m_a8ColorProfile; - QAtomicPointer<QColorProfile> m_a32ColorProfile; + QSharedPointer<QColorTrcLut> m_a8ColorProfile; + QSharedPointer<QColorTrcLut> m_a32ColorProfile; bool ownGlobalShareContext; diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index c3585a4647..0e2dfed9ab 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -8,7 +8,15 @@ HEADERS += \ painting/qbrush.h \ painting/qcolor.h \ painting/qcolor_p.h \ - painting/qcolorprofile_p.h \ + painting/qcolormatrix_p.h \ + painting/qcolorspace.h \ + painting/qcolorspace_p.h \ + painting/qcolortransferfunction_p.h \ + painting/qcolortransfertable_p.h \ + painting/qcolortransform.h \ + painting/qcolortransform_p.h \ + painting/qcolortrc_p.h \ + painting/qcolortrclut_p.h \ painting/qcosmeticstroker_p.h \ painting/qdatabuffer_p.h \ painting/qdrawhelper_p.h \ @@ -17,6 +25,7 @@ HEADERS += \ painting/qemulationpaintengine_p.h \ painting/qfixed_p.h \ painting/qgrayraster_p.h \ + painting/qicc_p.h \ painting/qmatrix.h \ painting/qmemrotate_p.h \ painting/qoutlinemapper_p.h \ @@ -64,12 +73,15 @@ SOURCES += \ painting/qblittable.cpp \ painting/qbrush.cpp \ painting/qcolor.cpp \ - painting/qcolorprofile.cpp \ + painting/qcolorspace.cpp \ + painting/qcolortransform.cpp \ + painting/qcolortrclut.cpp \ painting/qcompositionfunctions.cpp \ painting/qcosmeticstroker.cpp \ painting/qdrawhelper.cpp \ painting/qemulationpaintengine.cpp \ painting/qgrayraster.c \ + painting/qicc.cpp \ painting/qimagescale.cpp \ painting/qmatrix.cpp \ painting/qmemrotate.cpp \ diff --git a/src/gui/painting/qcolormatrix_p.h b/src/gui/painting/qcolormatrix_p.h new file mode 100644 index 0000000000..3d1dca6222 --- /dev/null +++ b/src/gui/painting/qcolormatrix_p.h @@ -0,0 +1,214 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QCOLORMATRIX_H +#define QCOLORMATRIX_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qtguiglobal.h> +#include <cmath> + +QT_BEGIN_NAMESPACE + +// An abstract 3 value color +class QColorVector +{ +public: + QColorVector() = default; + constexpr QColorVector(float x, float y, float z) : x(x), y(y), z(z), _unused(0.0f) { } + float x; // X, x or red + float y; // Y, y or green + float z; // Z, Y or blue + float _unused; + + friend inline bool operator==(const QColorVector &v1, const QColorVector &v2); + friend inline bool operator!=(const QColorVector &v1, const QColorVector &v2); + + static constexpr QColorVector null() { return QColorVector(0.0f, 0.0f, 0.0f); } + // Common whitepoints on normalized XYZ form: + static constexpr QColorVector D50() { return QColorVector(0.96421f, 1.0f, 0.82519f); } + static constexpr QColorVector D65() { return QColorVector(0.95043f, 1.0f, 1.08890f); } +}; + +inline bool operator==(const QColorVector &v1, const QColorVector &v2) +{ + return (std::abs(v1.x - v2.x) < (1.0f / 2048.0f)) + && (std::abs(v1.y - v2.y) < (1.0f / 2048.0f)) + && (std::abs(v1.z - v2.z) < (1.0f / 2048.0f)); +} + +inline bool operator!=(const QColorVector &v1, const QColorVector &v2) +{ + return !(v1 == v2); +} + + +// A matrix mapping 3 value colors. +// Not using QMatrix because only floats are needed and performance is critical. +class QColorMatrix +{ +public: + // We are storing the matrix transposed as that is more convenient: + QColorVector r; + QColorVector g; + QColorVector b; + + friend inline bool operator==(const QColorMatrix &m1, const QColorMatrix &m2); + friend inline bool operator!=(const QColorMatrix &m1, const QColorMatrix &m2); + + bool isValid() const + { + // A color matrix must be invertible + float det = r.x * (b.z * g.y - g.z * b.y) - + r.y * (b.z * g.x - g.z * b.x) + + r.z * (b.y * g.x - g.y * b.x); + return !qFuzzyIsNull(det); + } + + QColorMatrix inverted() const + { + float det = r.x * (b.z * g.y - g.z * b.y) - + r.y * (b.z * g.x - g.z * b.x) + + r.z * (b.y * g.x - g.y * b.x); + det = 1.0f / det; + QColorMatrix inv; + inv.r.x = (g.y * b.z - b.y * g.z) * det; + inv.r.y = (b.y * r.z - r.y * b.z) * det; + inv.r.z = (r.y * g.z - g.y * r.z) * det; + inv.g.x = (b.x * g.z - g.x * b.z) * det; + inv.g.y = (r.x * b.z - b.x * r.z) * det; + inv.g.z = (g.x * r.z - r.x * g.z) * det; + inv.b.x = (g.x * b.y - b.x * g.y) * det; + inv.b.y = (b.x * r.y - r.x * b.y) * det; + inv.b.z = (r.x * g.y - g.x * r.y) * det; + return inv; + } + QColorMatrix operator*(const QColorMatrix &o) const + { + QColorMatrix comb; + comb.r.x = r.x * o.r.x + g.x * o.r.y + b.x * o.r.z; + comb.g.x = r.x * o.g.x + g.x * o.g.y + b.x * o.g.z; + comb.b.x = r.x * o.b.x + g.x * o.b.y + b.x * o.b.z; + + comb.r.y = r.y * o.r.x + g.y * o.r.y + b.y * o.r.z; + comb.g.y = r.y * o.g.x + g.y * o.g.y + b.y * o.g.z; + comb.b.y = r.y * o.b.x + g.y * o.b.y + b.y * o.b.z; + + comb.r.z = r.z * o.r.x + g.z * o.r.y + b.z * o.r.z; + comb.g.z = r.z * o.g.x + g.z * o.g.y + b.z * o.g.z; + comb.b.z = r.z * o.b.x + g.z * o.b.y + b.z * o.b.z; + return comb; + + } + QColorVector map(const QColorVector &c) const + { + return QColorVector { c.x * r.x + c.y * g.x + c.z * b.x, + c.x * r.y + c.y * g.y + c.z * b.y, + c.x * r.z + c.y * g.z + c.z * b.z }; + } + QColorMatrix transposed() const + { + return QColorMatrix { { r.x, g.x, b.x }, + { r.y, g.y, b.y }, + { r.z, g.z, b.z } }; + } + + static QColorMatrix null() + { + return { QColorVector::null(), QColorVector::null(), QColorVector::null() }; + } + static QColorMatrix identity() + { + return { { 1.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } }; + } + static QColorMatrix toXyzFromSRgb() + { + return QColorMatrix { { 0.4360217452f, 0.2224751115f, 0.0139281144f }, + { 0.3851087987f, 0.7169067264f, 0.0971015394f }, + { 0.1430812478f, 0.0606181994f, 0.7141585946f } }; + } + static QColorMatrix toXyzFromAdobeRgb() + { + return QColorMatrix { { 0.6097189188f, 0.3111021519f, 0.0194766335f }, + { 0.2052682191f, 0.6256770492f, 0.0608891509f }, + { 0.1492247432f, 0.0632209629f, 0.7448224425f } }; + } + static QColorMatrix toXyzFromDciP3D65() + { + return QColorMatrix { { 0.5150973201f, 0.2411795557f, -0.0010491034f }, + { 0.2919696569f, 0.6922441125f, 0.0418830328f }, + { 0.1571449190f, 0.0665764511f, 0.7843542695f } }; + } + static QColorMatrix toXyzFromProPhotoRgb() + { + return QColorMatrix { { 0.7976672649f, 0.2880374491f, 0.0000000000f }, + { 0.1351922452f, 0.7118769884f, 0.0000000000f }, + { 0.0313525312f, 0.0000856627f, 0.8251883388f } }; + } + static QColorMatrix toXyzFromBt2020() + { + return QColorMatrix { { 0.6506130099f, 0.2695676684f, -0.0018652577f }, + { 0.1865101457f, 0.6840794086f, 0.0172256753f }, + { 0.1270887405f, 0.0463530831f, 0.8098278046f } }; + } +}; + +inline bool operator==(const QColorMatrix &m1, const QColorMatrix &m2) +{ + return (m1.r == m2.r) && (m1.g == m2.g) && (m1.b == m2.b); +} + +inline bool operator!=(const QColorMatrix &m1, const QColorMatrix &m2) +{ + return !(m1 == m2); +} + +QT_END_NAMESPACE + +#endif // QCOLORMATRIX_P_H diff --git a/src/gui/painting/qcolorspace.cpp b/src/gui/painting/qcolorspace.cpp new file mode 100644 index 0000000000..24785f7b61 --- /dev/null +++ b/src/gui/painting/qcolorspace.cpp @@ -0,0 +1,633 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qcolorspace.h" +#include "qcolorspace_p.h" + +#include "qcolortransform.h" +#include "qcolormatrix_p.h" +#include "qcolortransferfunction_p.h" +#include "qcolortransform_p.h" +#include "qicc_p.h" + +#include <qmath.h> +#include <qtransform.h> + +#include <qdebug.h> + +QT_BEGIN_NAMESPACE + +QColorSpacePrivate::QColorSpacePrivate() + : id(QColorSpace::Unknown) + , gamut(QColorSpace::Gamut::Custom) + , transferFunction(QColorSpace::TransferFunction::Custom) + , gamma(0.0f) + , whitePoint(QColorVector::null()) + , toXyz(QColorMatrix::null()) +{ +} + +QColorSpacePrivate::QColorSpacePrivate(QColorSpace::ColorSpaceId colorSpaceId) + : id(colorSpaceId) +{ + switch (colorSpaceId) { + case QColorSpace::Undefined: + gamut = QColorSpace::Gamut::Custom; + transferFunction = QColorSpace::TransferFunction::Custom; + gamma = 0.0f; + description = QStringLiteral("Undefined"); + break; + case QColorSpace::SRgb: + gamut = QColorSpace::Gamut::SRgb; + transferFunction = QColorSpace::TransferFunction::SRgb; + gamma = 2.31f; // ? + description = QStringLiteral("sRGB"); + break; + case QColorSpace::SRgbLinear: + gamut = QColorSpace::Gamut::SRgb; + transferFunction = QColorSpace::TransferFunction::Linear; + gamma = 1.0f; + description = QStringLiteral("Linear sRGB"); + break; + case QColorSpace::AdobeRgb: + gamut = QColorSpace::Gamut::AdobeRgb; + transferFunction = QColorSpace::TransferFunction::Gamma; + gamma = 2.19921875f; // Not quite 2.2, see https://www.adobe.com/digitalimag/pdfs/AdobeRGB1998.pdf + description = QStringLiteral("Adobe RGB"); + break; + case QColorSpace::DisplayP3: + gamut = QColorSpace::Gamut::DciP3D65; + transferFunction = QColorSpace::TransferFunction::SRgb; + gamma = 2.31f; // ? + description = QStringLiteral("Display P3"); + break; + case QColorSpace::ProPhotoRgb: + gamut = QColorSpace::Gamut::ProPhotoRgb; + transferFunction = QColorSpace::TransferFunction::ProPhotoRgb; + gamma = 1.8f; + description = QStringLiteral("ProPhoto RGB"); + break; + case QColorSpace::Bt2020: + gamut = QColorSpace::Gamut::Bt2020; + transferFunction = QColorSpace::TransferFunction::Bt2020; + gamma = 2.1f; // ? + description = QStringLiteral("BT.2020"); + break; + case QColorSpace::Unknown: + qWarning("Can not create an unknown color space"); + Q_FALLTHROUGH(); + default: + Q_UNREACHABLE(); + } + initialize(); +} + +QColorSpacePrivate::QColorSpacePrivate(QColorSpace::Gamut gamut, QColorSpace::TransferFunction fun, float gamma) + : gamut(gamut) + , transferFunction(fun) + , gamma(gamma) +{ + if (!identifyColorSpace()) + id = QColorSpace::Unknown; + initialize(); +} + +bool QColorSpacePrivate::identifyColorSpace() +{ + switch (gamut) { + case QColorSpace::Gamut::SRgb: + if (transferFunction == QColorSpace::TransferFunction::SRgb) { + id = QColorSpace::SRgb; + description = QStringLiteral("sRGB"); + return true; + } + if (transferFunction == QColorSpace::TransferFunction::Linear) { + id = QColorSpace::SRgbLinear; + description = QStringLiteral("Linear sRGB"); + return true; + } + break; + case QColorSpace::Gamut::AdobeRgb: + if (transferFunction == QColorSpace::TransferFunction::Gamma) { + if (qAbs(gamma - 2.19921875f) < (1/1024.0f)) { + id = QColorSpace::AdobeRgb; + description = QStringLiteral("Adobe RGB"); + return true; + } + } + break; + case QColorSpace::Gamut::DciP3D65: + if (transferFunction == QColorSpace::TransferFunction::SRgb) { + id = QColorSpace::DisplayP3; + description = QStringLiteral("Display P3"); + return true; + } + break; + case QColorSpace::Gamut::ProPhotoRgb: + if (transferFunction == QColorSpace::TransferFunction::ProPhotoRgb) { + id = QColorSpace::ProPhotoRgb; + description = QStringLiteral("ProPhoto RGB"); + return true; + } + if (transferFunction == QColorSpace::TransferFunction::Gamma) { + // ProPhoto RGB's curve is effectively gamma 1.8 for 8bit precision. + if (qAbs(gamma - 1.8f) < (1/1024.0f)) { + id = QColorSpace::ProPhotoRgb; + description = QStringLiteral("ProPhoto RGB"); + return true; + } + } + break; + case QColorSpace::Gamut::Bt2020: + if (transferFunction == QColorSpace::TransferFunction::Bt2020) { + id = QColorSpace::Bt2020; + description = QStringLiteral("BT.2020"); + return true; + } + break; + default: + break; + } + return false; +} + +void QColorSpacePrivate::initialize() +{ + setToXyzMatrix(); + setTransferFunction(); +} + +void QColorSpacePrivate::setToXyzMatrix() +{ + switch (gamut) { + case QColorSpace::Gamut::SRgb: + toXyz = QColorMatrix::toXyzFromSRgb(); + whitePoint = QColorVector::D65(); + return; + case QColorSpace::Gamut::AdobeRgb: + toXyz = QColorMatrix::toXyzFromAdobeRgb(); + whitePoint = QColorVector::D65(); + return; + case QColorSpace::Gamut::DciP3D65: + toXyz = QColorMatrix::toXyzFromDciP3D65(); + whitePoint = QColorVector::D65(); + return; + case QColorSpace::Gamut::ProPhotoRgb: + toXyz = QColorMatrix::toXyzFromProPhotoRgb(); + whitePoint = QColorVector::D50(); + return; + case QColorSpace::Gamut::Bt2020: + toXyz = QColorMatrix::toXyzFromBt2020(); + whitePoint = QColorVector::D65(); + return; + case QColorSpace::Gamut::Custom: + toXyz = QColorMatrix::null(); + whitePoint = QColorVector::D50(); + return; + } + Q_UNREACHABLE(); +} + +void QColorSpacePrivate::setTransferFunction() +{ + switch (transferFunction) { + case QColorSpace::TransferFunction::Linear: + trc[0].m_type = QColorTrc::Type::Function; + trc[0].m_fun = QColorTransferFunction(); + break; + case QColorSpace::TransferFunction::Gamma: + trc[0].m_type = QColorTrc::Type::Function; + trc[0].m_fun = QColorTransferFunction::fromGamma(gamma); + break; + case QColorSpace::TransferFunction::SRgb: + trc[0].m_type = QColorTrc::Type::Function; + trc[0].m_fun = QColorTransferFunction::fromSRgb(); + break; + case QColorSpace::TransferFunction::ProPhotoRgb: + trc[0].m_type = QColorTrc::Type::Function; + trc[0].m_fun = QColorTransferFunction::fromProPhotoRgb(); + break; + case QColorSpace::TransferFunction::Bt2020: + trc[0].m_type = QColorTrc::Type::Function; + trc[0].m_fun = QColorTransferFunction::fromBt2020(); + break; + case QColorSpace::TransferFunction::Custom: + break; + default: + Q_UNREACHABLE(); + break; + } + trc[1] = trc[0]; + trc[2] = trc[0]; +} + +QColorTransform QColorSpacePrivate::transformationToColorSpace(const QColorSpacePrivate *out) const +{ + Q_ASSERT(out); + QColorTransform combined; + combined.d_ptr.reset(new QColorTransformPrivate); + combined.d_ptr->colorSpaceIn = this; + combined.d_ptr->colorSpaceOut = out; + combined.d_ptr->colorMatrix = out->toXyz.inverted() * toXyz; + return combined; +} + +/*! + \class QColorSpace + \brief The QColorSpace class provides a color space abstraction. + \since 5.14 + + \ingroup painting + \ingroup appearance + \inmodule QtGui + + Color values can be interpreted in different ways, and based on the interpretation + can live in different spaces. We call this \e {color spaces}. + + QColorSpace provides access to creating several predefined color spaces and + can generate QColorTransforms for converting colors from one color space to + another. + + QColorSpace can also represent color spaces defined by ICC profiles or embedded + in images, that do not otherwise fit the predefined color spaces. + + A color space can generally speaking be conceived as a combination of a transfer + function and a gamut. The gamut defines which colors the color space can represent. + A color space that can represent a wider range of colors is also known as a + wide-gamut color space. The gamut is defined by three primary colors that represent + exactly how red, green, and blue look in this particular color space, and a white + color that represents where and how bright pure white is. + + The transfer function or gamma curve determines how each component in the + color space is encoded. These are used because human perception does not operate + linearly, and the transfer functions try to ensure that colors will seem evenly + spaced to human eyes. +*/ + + +/*! + \enum QColorSpace::ColorSpaceId + + Predefined color spaces. + + \value Undefined An empty, invalid or unsupported color space. + \value Unknown A valid color space that doesn't match any of the predefined color spaces. + \value SRgb The sRGB color space, which Qt operates in by default. It is a close approximation + of how most classic monitors operate, and a mode most software and hardware support. + \l{http://www.color.org/chardata/rgb/srgb.xalter}{ICC registration of sRGB}. + \value SRgbLinear The sRGB color space with linear gamma. Useful for gamma-corrected blending. + \value AdobeRgb The Adobe RGB color space is a classic wide-gamut color space, using a gamma of 2.2. + \l{http://www.color.org/chardata/rgb/adobergb.xalter}{ICC registration of Adobe RGB (1998)} + \value DisplayP3 A color-space using the primaries of DCI-P3, but with the whitepoint and transfer + function of sRGB. Common in modern wide-gamut screens. + \l{http://www.color.org/chardata/rgb/DCIP3.xalter}{ICC registration of DCI-P3} + \value ProPhotoRgb The Pro Photo RGB color space, also known as ROMM RGB is a very wide gamut color space. + \l{http://www.color.org/chardata/rgb/rommrgb.xalter}{ICC registration of ROMM RGB} + \value Bt2020 BT.2020 also known as Rec.2020 is the color space of HDR TVs. + \l{http://www.color.org/chardata/rgb/BT2020.xalter}{ICC registration of BT.2020} +*/ + +/*! + \enum QColorSpace::Gamut + + Predefined gamuts, or sets of primary colors. + + \value Custom The gamut is undefined or does not match any predefined sets. + \value SRgb The sRGB gamut + \value AdobeRgb The Adobe RGB gamut + \value DciP3D65 The DCI-P3 gamut with the D65 whitepoint + \value ProPhotoRgb The ProPhoto RGB gamut with the D50 whitepoint + \value Bt2020 The BT.2020 gamut +*/ + +/*! + \enum QColorSpace::TransferFunction + + Predefined transfer functions or gamma curves. + + \value Custom The custom or null transfer function + \value Linear The linear transfer functions + \value Gamma A transfer function that is a real gamma curve based on the value of gamma() + \value SRgb The sRGB transfer function, composed of linear and gamma parts + \value ProPhotoRgb The ProPhoto RGB transfer function, composed of linear and gamma parts + \value Bt2020 The BT.2020 transfer function, composed of linear and gamma parts +*/ + +/*! + Creates a new colorspace object that represents \a colorSpaceId. + */ +QColorSpace::QColorSpace(QColorSpace::ColorSpaceId colorSpaceId) +{ + static QExplicitlySharedDataPointer<QColorSpacePrivate> predefinedColorspacePrivates[QColorSpace::Bt2020]; + if (colorSpaceId <= QColorSpace::Unknown) { + if (!predefinedColorspacePrivates[0]) + predefinedColorspacePrivates[0] = new QColorSpacePrivate(QColorSpace::Undefined); + d_ptr = predefinedColorspacePrivates[0]; // unknown and undefined both returns the static undefined colorspace. + } else { + if (!predefinedColorspacePrivates[colorSpaceId - 1]) + predefinedColorspacePrivates[colorSpaceId - 1] = new QColorSpacePrivate(colorSpaceId); + d_ptr = predefinedColorspacePrivates[colorSpaceId - 1]; + } + + Q_ASSERT(colorSpaceId == QColorSpace::Undefined || isValid()); +} + +/*! + Creates a custom color space with the gamut \a gamut, using the transfer function \a fun and + optionally \a gamma. + */ +QColorSpace::QColorSpace(QColorSpace::Gamut gamut, QColorSpace::TransferFunction fun, float gamma) + : d_ptr(new QColorSpacePrivate(gamut, fun, gamma)) +{ +} + +/*! + Creates a custom color space with the gamut \a gamut, using a gamma transfer function of + \a gamma. + */ +QColorSpace::QColorSpace(QColorSpace::Gamut gamut, float gamma) + : d_ptr(new QColorSpacePrivate(gamut, TransferFunction::Gamma, gamma)) +{ +} + +QColorSpace::~QColorSpace() +{ +} + +QColorSpace::QColorSpace(QColorSpace &&colorSpace) + : d_ptr(std::move(colorSpace.d_ptr)) +{ +} + +QColorSpace::QColorSpace(const QColorSpace &colorSpace) + : d_ptr(colorSpace.d_ptr) +{ +} + +QColorSpace &QColorSpace::operator=(QColorSpace &&colorSpace) +{ + d_ptr = std::move(colorSpace.d_ptr); + return *this; +} + +QColorSpace &QColorSpace::operator=(const QColorSpace &colorSpace) +{ + d_ptr = colorSpace.d_ptr; + return *this; +} + +/*! + Returns the id of the predefined color space this object + represents or \c Unknown if it doesn't match any of them. +*/ +QColorSpace::ColorSpaceId QColorSpace::colorSpaceId() const noexcept +{ + return d_ptr->id; +} + +/*! + Returns the predefined gamut of the color space + or \c Gamut::Custom if it doesn't match any of them. +*/ +QColorSpace::Gamut QColorSpace::gamut() const noexcept +{ + return d_ptr->gamut; +} + +/*! + Returns the predefined transfer function of the color space + or \c TransferFunction::Custom if it doesn't match any of them. + + \sa gamma() +*/ +QColorSpace::TransferFunction QColorSpace::transferFunction() const noexcept +{ + return d_ptr->transferFunction; +} + +/*! + Returns the gamma value of color spaces with \c TransferFunction::Gamma, + an approximate gamma value for other predefined color spaces, or + 0.0 if no approximate gamma is known. + + \sa transferFunction() +*/ +float QColorSpace::gamma() const noexcept +{ + return d_ptr->gamma; +} + +/*! + Returns an ICC profile representing the color space. + + If the color space was generated from an ICC profile, that profile + is returned, otherwise one is generated. + + \note Even invalid color spaces may return the ICC profile if they + were generated from one, to allow applications to implement wider + support themselves. + + \sa fromIccProfile() +*/ +QByteArray QColorSpace::iccProfile() const +{ + if (!d_ptr->iccProfile.isEmpty()) + return d_ptr->iccProfile; + if (!isValid()) + return QByteArray(); + return QIcc::toIccProfile(*this); +} + +/*! + Creates a QColorSpace from ICC profile \a iccProfile. + + \note Not all ICC profiles are supported. QColorSpace only supports + RGB-XYZ ICC profiles that are three-component matrix-based. + + If the ICC profile is not supported an invalid QColorSpace is returned + where you can still read the original ICC profile using iccProfile(). + + \sa iccProfile() +*/ +QColorSpace QColorSpace::fromIccProfile(const QByteArray &iccProfile) +{ + QColorSpace colorSpace; + if (QIcc::fromIccProfile(iccProfile, &colorSpace)) + return colorSpace; + colorSpace.d_ptr->id = QColorSpace::Undefined; + colorSpace.d_ptr->iccProfile = iccProfile; + return colorSpace; +} + +/*! + Returns \c true if the color space is valid. +*/ +bool QColorSpace::isValid() const noexcept +{ + return d_ptr->id != QColorSpace::Undefined && d_ptr->toXyz.isValid() + && d_ptr->trc[0].isValid() && d_ptr->trc[1].isValid() && d_ptr->trc[2].isValid(); +} + +/*! + \relates QColorSpace + Returns \c true if colorspace \a colorSpace1 is equal to colorspace \a colorSpace2; + otherwise returns \c false +*/ +bool operator==(const QColorSpace &colorSpace1, const QColorSpace &colorSpace2) +{ + if (colorSpace1.d_ptr == colorSpace2.d_ptr) + return true; + + if (colorSpace1.colorSpaceId() == QColorSpace::Undefined && colorSpace2.colorSpaceId() == QColorSpace::Undefined) + return colorSpace1.d_ptr->iccProfile == colorSpace2.d_ptr->iccProfile; + + if (colorSpace1.colorSpaceId() != QColorSpace::Unknown && colorSpace2.colorSpaceId() != QColorSpace::Unknown) + return colorSpace1.colorSpaceId() == colorSpace2.colorSpaceId(); + + if (colorSpace1.gamut() != QColorSpace::Gamut::Custom && colorSpace2.gamut() != QColorSpace::Gamut::Custom) { + if (colorSpace1.gamut() != colorSpace2.gamut()) + return false; + } else { + if (colorSpace1.d_ptr->toXyz != colorSpace2.d_ptr->toXyz) + return false; + } + + if (colorSpace1.transferFunction() != QColorSpace::TransferFunction::Custom && + colorSpace2.transferFunction() != QColorSpace::TransferFunction::Custom) { + if (colorSpace1.transferFunction() != colorSpace2.transferFunction()) + return false; + if (colorSpace1.transferFunction() == QColorSpace::TransferFunction::Gamma) + return colorSpace1.gamma() == colorSpace2.gamma(); + return true; + } + + if (colorSpace1.d_ptr->trc[0] != colorSpace2.d_ptr->trc[0] || + colorSpace1.d_ptr->trc[1] != colorSpace2.d_ptr->trc[1] || + colorSpace1.d_ptr->trc[2] != colorSpace2.d_ptr->trc[2]) + return false; + + return true; +} + +/*! + \fn bool operator!=(const QColorSpace &colorSpace1, const QColorSpace &colorSpace2) + \relates QColorSpace + + Returns \c true if colorspace \a colorspace1 is not equal to colorspace \a colorspace2; + otherwise returns \c false +*/ + +/*! + Generates and returns a color space transformation from this color space to + \a colorspace. +*/ +QColorTransform QColorSpace::transformationToColorSpace(const QColorSpace &colorspace) const +{ + if (!isValid() || !colorspace.isValid()) + return QColorTransform(); + + return d_ptr->transformationToColorSpace(colorspace.d_ptr.constData()); +} + +/*! + \internal +*/ +QColorSpacePrivate *QColorSpace::d_func() +{ + d_ptr.detach(); + return d_ptr.data(); +} + +/*! + \fn const QColorSpacePrivate* QColorSpacePrivate::d_func() const + \internal +*/ + +/***************************************************************************** + QColorSpace stream functions + *****************************************************************************/ +#if !defined(QT_NO_DATASTREAM) +/*! + \fn QDataStream &operator<<(QDataStream &stream, const QColorSpace &colorSpace) + \relates QColorSpace + + Writes the given \a colorSpace to the given \a stream as an ICC profile. + + \sa QColorSpace::iccProfile(), {Serializing Qt Data Types} +*/ + +QDataStream &operator<<(QDataStream &s, const QColorSpace &image) +{ + s << image.iccProfile(); + return s; +} + +/*! + \fn QDataStream &operator>>(QDataStream &stream, QColorSpace &colorSpace) + \relates QColorSpace + + Reads a color space from the given \a stream and stores it in the given + \a colorSpace. + + \sa QColorSpace::fromIccProfile(), {Serializing Qt Data Types} +*/ + +QDataStream &operator>>(QDataStream &s, QColorSpace &colorSpace) +{ + QByteArray iccProfile; + s >> iccProfile; + colorSpace = QColorSpace::fromIccProfile(iccProfile); + return s; +} +#endif // QT_NO_DATASTREAM + +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug dbg, const QColorSpace &colorSpace) +{ + QDebugStateSaver saver(dbg); + dbg.nospace(); + dbg << "QColorSpace("; + dbg << colorSpace.colorSpaceId() << ", " << colorSpace.gamut() << ", " << colorSpace.transferFunction(); + dbg << ", gamma=" << colorSpace.gamma(); + dbg << ')'; + return dbg; +} +#endif + +QT_END_NAMESPACE diff --git a/src/gui/painting/qcolorspace.h b/src/gui/painting/qcolorspace.h new file mode 100644 index 0000000000..923546ec6f --- /dev/null +++ b/src/gui/painting/qcolorspace.h @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QCOLORSPACE_H +#define QCOLORSPACE_H + +#include <QtGui/qtguiglobal.h> +#include <QtGui/qcolortransform.h> +#include <QtCore/qshareddata.h> + +QT_BEGIN_NAMESPACE + +class QColorSpacePrivate; + +class Q_GUI_EXPORT QColorSpace +{ + Q_GADGET +public: + enum ColorSpaceId { + Undefined = 0, + Unknown = 1, + SRgb, + SRgbLinear, + AdobeRgb, + DisplayP3, + ProPhotoRgb, + Bt2020, + }; + Q_ENUM(ColorSpaceId) + enum class Gamut { + Custom = 0, + SRgb, + AdobeRgb, + DciP3D65, + ProPhotoRgb, + Bt2020, + }; + Q_ENUM(Gamut) + enum class TransferFunction { + Custom = 0, + Linear, + Gamma, + SRgb, + ProPhotoRgb, + Bt2020, + }; + Q_ENUM(TransferFunction) + + QColorSpace(ColorSpaceId colorSpaceId = Undefined); + QColorSpace(Gamut gamut, TransferFunction fun, float gamma = 0.0f); + QColorSpace(Gamut gamut, float gamma); + ~QColorSpace(); + + QColorSpace(QColorSpace &&colorSpace); + QColorSpace(const QColorSpace &colorSpace); + QColorSpace &operator=(QColorSpace &&colorSpace); + QColorSpace &operator=(const QColorSpace &colorSpace); + + ColorSpaceId colorSpaceId() const noexcept; + Gamut gamut() const noexcept; + TransferFunction transferFunction() const noexcept; + float gamma() const noexcept; + + bool isValid() const noexcept; + + friend Q_GUI_EXPORT bool operator==(const QColorSpace &colorSpace1, const QColorSpace &colorSpace2); + friend inline bool operator!=(const QColorSpace &colorSpace1, const QColorSpace &colorSpace2); + + static QColorSpace fromIccProfile(const QByteArray &iccProfile); + QByteArray iccProfile() const; + + QColorTransform transformationToColorSpace(const QColorSpace &colorspace) const; + + QColorSpacePrivate *d_func(); + inline const QColorSpacePrivate *d_func() const { return d_ptr.constData(); } + +private: + friend class QColorSpacePrivate; + QExplicitlySharedDataPointer<QColorSpacePrivate> d_ptr; +}; + +bool Q_GUI_EXPORT operator==(const QColorSpace &colorSpace1, const QColorSpace &colorSpace2); +inline bool operator!=(const QColorSpace &colorSpace1, const QColorSpace &colorSpace2) +{ + return !(colorSpace1 == colorSpace2); +} + +// QColorSpace stream functions +#if !defined(QT_NO_DATASTREAM) +Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QColorSpace &); +Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QColorSpace &); +#endif + +#ifndef QT_NO_DEBUG_STREAM +Q_GUI_EXPORT QDebug operator<<(QDebug, const QColorSpace &); +#endif + +QT_END_NAMESPACE + +#endif // QCOLORSPACE_P_H diff --git a/src/gui/painting/qcolorspace_p.h b/src/gui/painting/qcolorspace_p.h new file mode 100644 index 0000000000..91107a9a89 --- /dev/null +++ b/src/gui/painting/qcolorspace_p.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QCOLORSPACE_P_H +#define QCOLORSPACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qcolorspace.h" +#include "qcolormatrix_p.h" +#include "qcolortrc_p.h" +#include "qcolortrclut_p.h" + +#include <QtCore/qshareddata.h> + +QT_BEGIN_NAMESPACE + +class QColorSpacePrivate : public QSharedData +{ +public: + QColorSpacePrivate(); + QColorSpacePrivate(QColorSpace::ColorSpaceId colorSpaceId); + QColorSpacePrivate(QColorSpace::Gamut gamut, QColorSpace::TransferFunction fun, float gamma); + QColorSpacePrivate(const QColorSpacePrivate &other) = default; + QColorSpacePrivate &operator=(const QColorSpacePrivate &other) = default; + + void initialize(); + void setToXyzMatrix(); + void setTransferFunction(); + bool identifyColorSpace(); + QColorTransform transformationToColorSpace(const QColorSpacePrivate *out) const; + + QColorSpace::ColorSpaceId id; + QColorSpace::Gamut gamut; + QColorSpace::TransferFunction transferFunction; + float gamma; + QColorVector whitePoint; + + QColorTrc trc[3]; + QColorMatrix toXyz; + + QString description; + QByteArray iccProfile; + + mutable QSharedPointer<QColorTrcLut> lut[3]; + mutable QAtomicInt lutsGenerated; +}; + +QT_END_NAMESPACE + +#endif // QCOLORSPACE_P_H diff --git a/src/gui/painting/qcolortransferfunction_p.h b/src/gui/painting/qcolortransferfunction_p.h new file mode 100644 index 0000000000..fd7cfa2b2b --- /dev/null +++ b/src/gui/painting/qcolortransferfunction_p.h @@ -0,0 +1,207 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QCOLORTRANSFERFUNCTION_P_H +#define QCOLORTRANSFERFUNCTION_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/private/qtguiglobal_p.h> + +#include <cmath> + +QT_BEGIN_NAMESPACE + +// Defines a ICC parametric curve type 4 +class Q_GUI_EXPORT QColorTransferFunction +{ +public: + QColorTransferFunction() noexcept + : m_a(1.0f), m_b(0.0f), m_c(1.0f), m_d(0.0f), m_e(0.0f), m_f(0.0f), m_g(1.0f), m_flags(0) + { } + QColorTransferFunction(float a, float b, float c, float d, float e, float f, float g) noexcept + : m_a(a), m_b(b), m_c(c), m_d(d), m_e(e), m_f(f), m_g(g), m_flags(0) + { } + + bool isGamma() const + { + updateHints(); + return m_flags & quint32(Hints::IsGamma); + } + bool isLinear() const + { + updateHints(); + return m_flags & quint32(Hints::IsLinear); + } + bool isSRgb() const + { + updateHints(); + return m_flags & quint32(Hints::IsSRgb); + } + + float apply(float x) const + { + if (x < m_d) + return m_c * x + m_f; + else + return std::pow(m_a * x + m_b, m_g) + m_e; + } + + QColorTransferFunction inverted() const + { + float a, b, c, d, e, f, g; + + d = m_c * m_d + m_f; + + if (!qFuzzyIsNull(m_c)) { + c = 1.0f / m_c; + f = -m_f / m_c; + } else { + c = 0.0f; + f = 0.0f; + } + + if (!qFuzzyIsNull(m_a) && !qFuzzyIsNull(m_g)) { + a = std::pow(1.0f / m_a, m_g); + b = -a * m_e; + e = -m_b / m_a; + g = 1.0f / m_g; + } else { + a = 0.0f; + b = 0.0f; + e = 1.0f; + g = 1.0f; + } + + return QColorTransferFunction(a, b, c, d, e, f, g); + } + + // A few predefined curves: + static QColorTransferFunction fromGamma(float gamma) + { + return QColorTransferFunction(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, gamma); + } + static QColorTransferFunction fromSRgb() + { + return QColorTransferFunction(1.0f / 1.055f, 0.055f / 1.055f, 1.0f / 12.92f, 0.04045f, 0.0f, 0.0f, 2.4f); + } + static QColorTransferFunction fromBt2020() + { + return QColorTransferFunction(1.0f / 1.0993f, 0.0993f / 1.0993f, 1.0f / 4.5f, 0.08145f, 0.0f, 0.0f, 2.2f); + } + static QColorTransferFunction fromProPhotoRgb() + { + return QColorTransferFunction(1.0f, 0.0f, 1.0f / 16.0f, 16.0f / 512.0f, 0.0f, 0.0f, 1.8f); + } + bool matches(const QColorTransferFunction &o) const + { + return paramCompare(m_a, o.m_a) && paramCompare(m_b, o.m_b) + && paramCompare(m_c, o.m_c) && paramCompare(m_d, o.m_d) + && paramCompare(m_e, o.m_e) && paramCompare(m_f, o.m_f) + && paramCompare(m_g, o.m_g); + } + friend inline bool operator==(const QColorTransferFunction &f1, const QColorTransferFunction &f2); + friend inline bool operator!=(const QColorTransferFunction &f1, const QColorTransferFunction &f2); + + float m_a; + float m_b; + float m_c; + float m_d; + float m_e; + float m_f; + float m_g; + +private: + static inline bool paramCompare(float p1, float p2) + { + // Much fuzzier than fuzzy compare. + // It tries match parameters that has been passed through a 8.8 + // fixed point form. + return (qAbs(p1 - p2) <= (1.0f / 512.0f)); + } + + void updateHints() const + { + if (m_flags & quint32(Hints::Calculated)) + return; + // We do not consider the case with m_d = 1.0f linear or simple, + // since it wouldn't be linear for applyExtended(). + bool simple = paramCompare(m_a, 1.0f) && paramCompare(m_b, 0.0f) + && paramCompare(m_d, 0.0f) + && paramCompare(m_e, 0.0f); + if (simple) { + m_flags |= quint32(Hints::IsGamma); + if (qFuzzyCompare(m_g, 1.0f)) + m_flags |= quint32(Hints::IsLinear); + } else { + if (*this == fromSRgb()) + m_flags |= quint32(Hints::IsSRgb); + } + m_flags |= quint32(Hints::Calculated); + } + enum class Hints : quint32 { + Calculated = 1, + IsGamma = 2, + IsLinear = 4, + IsSRgb = 8 + }; + mutable quint32 m_flags; +}; + +inline bool operator==(const QColorTransferFunction &f1, const QColorTransferFunction &f2) +{ + return f1.matches(f2); +} +inline bool operator!=(const QColorTransferFunction &f1, const QColorTransferFunction &f2) +{ + return !f1.matches(f2); +} + +QT_END_NAMESPACE + +#endif // QCOLORTRANSFERFUNCTION_P_H diff --git a/src/gui/painting/qcolortransfertable_p.h b/src/gui/painting/qcolortransfertable_p.h new file mode 100644 index 0000000000..c8b2f7bd92 --- /dev/null +++ b/src/gui/painting/qcolortransfertable_p.h @@ -0,0 +1,245 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QCOLORTRANSFERTABLE_P_H +#define QCOLORTRANSFERTABLE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/private/qtguiglobal_p.h> +#include "qcolortransferfunction_p.h" + +#include <QVector> +#include <cmath> + +QT_BEGIN_NAMESPACE + +// Defines either an ICC TRC 'curve' or a lut8/lut16 A or B table +class Q_GUI_EXPORT QColorTransferTable +{ +public: + QColorTransferTable() noexcept + : m_tableSize(0) + { } + QColorTransferTable(uint32_t size, const QVector<uint8_t> &table) noexcept + : m_tableSize(size) + , m_table8(table) + { } + QColorTransferTable(uint32_t size, const QVector<uint16_t> &table) noexcept + : m_tableSize(size) + , m_table16(table) + { } + + bool isValid() const + { + if (m_tableSize < 2) + return false; + +#if !defined(QT_NO_DEBUG) + // The table must describe an injective curve: + if (!m_table8.isEmpty()) { + uint8_t val = 0; + for (uint i = 0; i < m_tableSize; ++i) { + Q_ASSERT(m_table8[i] >= val); + val = m_table8[i]; + } + } + if (!m_table16.isEmpty()) { + uint16_t val = 0; + for (uint i = 0; i < m_tableSize; ++i) { + Q_ASSERT(m_table16[i] >= val); + val = m_table16[i]; + } + } +#endif + return !m_table8.isEmpty() || !m_table16.isEmpty(); + } + + float apply(float x) const + { + x = std::min(std::max(x, 0.0f), 1.0f); + x *= m_tableSize - 1; + uint32_t lo = (int)std::floor(x); + uint32_t hi = std::min(lo + 1, m_tableSize); + float frac = x - lo; + if (!m_table16.isEmpty()) + return (m_table16[lo] * (1.0f - frac) + m_table16[hi] * frac) * (1.0f/65535.0f); + if (!m_table8.isEmpty()) + return (m_table8[lo] * (1.0f - frac) + m_table8[hi] * frac) * (1.0f/255.0f); + return x; + } + + // Apply inverse, optimized by giving a previous result a value < x. + float applyInverse(float x, float resultLargerThan = 0.0f) const + { + Q_ASSERT(resultLargerThan >= 0.0f && resultLargerThan <= 1.0f); + if (x <= 0.0f) + return 0.0f; + if (x >= 1.0f) + return 1.0f; + if (!m_table16.isEmpty()) { + float v = x * 65535.0f; + uint i = std::floor(resultLargerThan * (m_tableSize - 1)) + 1; + for ( ; i < m_tableSize; ++i) { + if (m_table16[i] > v) + break; + } + if (i >= m_tableSize - 1) + return 1.0f; + float y1 = m_table16[i - 1]; + float y2 = m_table16[i]; + Q_ASSERT(x >= y1 && x < y2); + float fr = (v - y1) / (y2 - y1); + return (i + fr) * (1.0f / (m_tableSize - 1)); + + } + if (!m_table8.isEmpty()) { + float v = x * 255.0f; + uint i = std::floor(resultLargerThan * (m_tableSize - 1)) + 1; + for ( ; i < m_tableSize; ++i) { + if (m_table8[i] > v) + break; + } + if (i >= m_tableSize - 1) + return 1.0f; + float y1 = m_table8[i - 1]; + float y2 = m_table8[i]; + Q_ASSERT(x >= y1 && x < y2); + float fr = (v - y1) / (y2 - y1); + return (i + fr) * (1.0f / (m_tableSize - 1)); + } + return x; + } + + bool asColorTransferFunction(QColorTransferFunction *transferFn) + { + Q_ASSERT(isValid()); + Q_ASSERT(transferFn); + if (!m_table8.isEmpty() && (m_table8[0] != 0 || m_table8[m_tableSize - 1] != 255)) + return false; + if (!m_table16.isEmpty() && (m_table16[0] != 0 || m_table16[m_tableSize - 1] != 65535)) + return false; + if (m_tableSize == 2) { + *transferFn = QColorTransferFunction(); // Linear + return true; + } + // The following heuristics are based on those from Skia: + if (m_tableSize == 26 && !m_table16.isEmpty()) { + // code.facebook.com/posts/411525055626587/under-the-hood-improving-facebook-photos + if (m_table16[6] != 3062) + return false; + if (m_table16[12] != 12824) + return false; + if (m_table16[18] != 31237) + return false; + *transferFn = QColorTransferFunction::fromSRgb(); + return true; + } + if (m_tableSize == 1024 && !m_table16.isEmpty()) { + // HP and Canon sRGB gamma tables: + if (m_table16[257] != 3366) + return false; + if (m_table16[513] != 14116) + return false; + if (m_table16[768] != 34318) + return false; + *transferFn = QColorTransferFunction::fromSRgb(); + return true; + } + if (m_tableSize == 4096 && !m_table16.isEmpty()) { + // Nikon, Epson, and lcms2 sRGB gamma tables: + if (m_table16[515] != 960) + return false; + if (m_table16[1025] != 3342) + return false; + if (m_table16[2051] != 14079) + return false; + *transferFn = QColorTransferFunction::fromSRgb(); + return true; + } + return false; + } + friend inline bool operator!=(const QColorTransferTable &t1, const QColorTransferTable &t2); + friend inline bool operator==(const QColorTransferTable &t1, const QColorTransferTable &t2); + + uint32_t m_tableSize; + QVector<uint8_t> m_table8; + QVector<uint16_t> m_table16; +}; + +inline bool operator!=(const QColorTransferTable &t1, const QColorTransferTable &t2) +{ + if (t1.m_tableSize != t2.m_tableSize) + return true; + if (t1.m_table8.isEmpty() != t2.m_table8.isEmpty()) + return true; + if (t1.m_table16.isEmpty() != t2.m_table16.isEmpty()) + return true; + if (!t1.m_table8.isEmpty()) { + for (quint32 i = 0; i < t1.m_tableSize; ++i) { + if (t1.m_table8[i] != t2.m_table8[i]) + return true; + } + } + if (!t1.m_table16.isEmpty()) { + for (quint32 i = 0; i < t1.m_tableSize; ++i) { + if (t1.m_table16[i] != t2.m_table16[i]) + return true; + } + } + return false; +} + +inline bool operator==(const QColorTransferTable &t1, const QColorTransferTable &t2) +{ + return !(t1 != t2); +} + +QT_END_NAMESPACE + +#endif // QCOLORTRANSFERTABLE_P_H diff --git a/src/gui/painting/qcolortransform.cpp b/src/gui/painting/qcolortransform.cpp new file mode 100644 index 0000000000..b677c4b36b --- /dev/null +++ b/src/gui/painting/qcolortransform.cpp @@ -0,0 +1,679 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include "qcolortransform.h" +#include "qcolortransform_p.h" + +#include "qcolormatrix_p.h" +#include "qcolorspace_p.h" +#include "qcolortrc_p.h" +#include "qcolortrclut_p.h" + +#include <QtCore/qatomic.h> +#include <QtCore/qmath.h> +#include <QtGui/qcolor.h> +#include <QtGui/qtransform.h> +#include <QtCore/private/qsimd_p.h> + +#include <qdebug.h> + +QT_BEGIN_NAMESPACE + +QColorTrcLut *lutFromTrc(const QColorTrc &trc) +{ + if (trc.m_type == QColorTrc::Type::Table) + return QColorTrcLut::fromTransferTable(trc.m_table); + if (trc.m_type == QColorTrc::Type::Function) + return QColorTrcLut::fromTransferFunction(trc.m_fun); + qWarning() << "TRC uninitialized"; + return nullptr; +} + +void QColorTransformPrivate::updateLutsIn() const +{ + if (colorSpaceIn->lutsGenerated.loadAcquire()) + return; + for (int i = 0; i < 3; ++i) { + if (!colorSpaceIn->trc[i].isValid()) + return; + } + + if (colorSpaceIn->trc[0] == colorSpaceIn->trc[1] && colorSpaceIn->trc[0] == colorSpaceIn->trc[2]) { + colorSpaceIn->lut[0].reset(lutFromTrc(colorSpaceIn->trc[0])); + colorSpaceIn->lut[1] = colorSpaceIn->lut[0]; + colorSpaceIn->lut[2] = colorSpaceIn->lut[0]; + } else { + for (int i = 0; i < 3; ++i) + colorSpaceIn->lut[i].reset(lutFromTrc(colorSpaceIn->trc[i])); + } + + colorSpaceIn->lutsGenerated.storeRelease(1); +} + +void QColorTransformPrivate::updateLutsOut() const +{ + if (colorSpaceOut->lutsGenerated.loadAcquire()) + return; + for (int i = 0; i < 3; ++i) { + if (!colorSpaceOut->trc[i].isValid()) + return; + } + + if (colorSpaceOut->trc[0] == colorSpaceOut->trc[1] && colorSpaceOut->trc[0] == colorSpaceOut->trc[2]) { + colorSpaceOut->lut[0].reset(lutFromTrc(colorSpaceOut->trc[0])); + colorSpaceOut->lut[1] = colorSpaceOut->lut[0]; + colorSpaceOut->lut[2] = colorSpaceOut->lut[0]; + } else { + for (int i = 0; i < 3; ++i) + colorSpaceOut->lut[i].reset(lutFromTrc(colorSpaceOut->trc[i])); + } + + colorSpaceOut->lutsGenerated.storeRelease(1); +} + +/*! + \class QColorTransform + \brief The QColorTransform class is a transformation between color spaces. + \since 5.14 + + \ingroup painting + \ingroup appearance + \inmodule QtGui + + QColorTransform is an instantiation of a transformation between color spaces. + It can be applied on color and pixels to convert them from one color space to + another. + + Setting up a QColorTransform takes some preprocessing, so keeping around + QColorTransforms that you need often is recommended, instead of generating + them on the fly. +*/ + + +QColorTransform::~QColorTransform() noexcept +{ +} + +/*! + Applies the color transformation on the QRgb value \a argb. + + The input should be opaque or unpremultiplied. +*/ +QRgb QColorTransform::map(const QRgb &argb) const +{ + if (!d_ptr) + return argb; + Q_D(const QColorTransform); + constexpr float f = 1.0f / 255.0f; + QColorVector c = { qRed(argb) * f, qGreen(argb) * f, qBlue(argb) * f }; + c.x = d->colorSpaceIn->trc[0].apply(c.x); + c.y = d->colorSpaceIn->trc[1].apply(c.y); + c.z = d->colorSpaceIn->trc[2].apply(c.z); + c = d->colorMatrix.map(c); + c.x = std::max(0.0f, std::min(1.0f, c.x)); + c.y = std::max(0.0f, std::min(1.0f, c.y)); + c.z = std::max(0.0f, std::min(1.0f, c.z)); + if (d->colorSpaceOut->lutsGenerated.loadAcquire()) { + c.x = d->colorSpaceOut->lut[0]->fromLinear(c.x); + c.y = d->colorSpaceOut->lut[1]->fromLinear(c.y); + c.z = d->colorSpaceOut->lut[2]->fromLinear(c.z); + } else { + c.x = d->colorSpaceOut->trc[0].applyInverse(c.x); + c.y = d->colorSpaceOut->trc[1].applyInverse(c.y); + c.z = d->colorSpaceOut->trc[2].applyInverse(c.z); + } + + return qRgba(c.x * 255 + 0.5f, c.y * 255 + 0.5f, c.z * 255 + 0.5f, qAlpha(argb)); +} + +/*! + Applies the color transformation on the QRgba64 value \a rgba64. + + The input should be opaque or unpremultiplied. +*/ +QRgba64 QColorTransform::map(const QRgba64 &rgba64) const +{ + if (!d_ptr) + return rgba64; + Q_D(const QColorTransform); + constexpr float f = 1.0f / 65535.0f; + QColorVector c = { rgba64.red() * f, rgba64.green() * f, rgba64.blue() * f }; + c.x = d->colorSpaceIn->trc[0].apply(c.x); + c.y = d->colorSpaceIn->trc[1].apply(c.y); + c.z = d->colorSpaceIn->trc[2].apply(c.z); + c = d->colorMatrix.map(c); + c.x = std::max(0.0f, std::min(1.0f, c.x)); + c.y = std::max(0.0f, std::min(1.0f, c.y)); + c.z = std::max(0.0f, std::min(1.0f, c.z)); + if (d->colorSpaceOut->lutsGenerated.loadAcquire()) { + c.x = d->colorSpaceOut->lut[0]->fromLinear(c.x); + c.y = d->colorSpaceOut->lut[1]->fromLinear(c.y); + c.z = d->colorSpaceOut->lut[2]->fromLinear(c.z); + } else { + c.x = d->colorSpaceOut->trc[0].applyInverse(c.x); + c.y = d->colorSpaceOut->trc[1].applyInverse(c.y); + c.z = d->colorSpaceOut->trc[2].applyInverse(c.z); + } + + return QRgba64::fromRgba64(c.x * 65535, c.y * 65535, c.z * 65535, rgba64.alpha()); +} + +/*! + Applies the color transformation on the QColor value \a color. + +*/ +QColor QColorTransform::map(const QColor &color) const +{ + if (!d_ptr) + return color; + Q_D(const QColorTransform); + QColorVector c = { (float)color.redF(), (float)color.greenF(), (float)color.blueF() }; + c.x = d->colorSpaceIn->trc[0].apply(c.x); + c.y = d->colorSpaceIn->trc[1].apply(c.y); + c.z = d->colorSpaceIn->trc[2].apply(c.z); + c = d->colorMatrix.map(c); + if (d_ptr->colorSpaceOut->lutsGenerated.loadAcquire()) { + c.x = d->colorSpaceOut->lut[0]->fromLinear(c.x); + c.y = d->colorSpaceOut->lut[1]->fromLinear(c.y); + c.z = d->colorSpaceOut->lut[2]->fromLinear(c.z); + } else { + c.x = d->colorSpaceOut->trc[0].applyInverse(c.x); + c.y = d->colorSpaceOut->trc[1].applyInverse(c.y); + c.z = d->colorSpaceOut->trc[2].applyInverse(c.z); + } + QColor out; + out.setRgbF(c.x, c.y, c.z, color.alphaF()); + return out; +} + +// Optimized sub-routines for fast block based conversion: + +static void applyMatrix(QColorVector *buffer, const qsizetype len, const QColorMatrix &colorMatrix) +{ +#if defined(__SSE2__) + const __m128 minV = _mm_set1_ps(0.0f); + const __m128 maxV = _mm_set1_ps(1.0f); + const __m128 xMat = _mm_loadu_ps(&colorMatrix.r.x); + const __m128 yMat = _mm_loadu_ps(&colorMatrix.g.x); + const __m128 zMat = _mm_loadu_ps(&colorMatrix.b.x); + for (qsizetype j = 0; j < len; ++j) { + __m128 c = _mm_loadu_ps(&buffer[j].x); + __m128 cx = _mm_shuffle_ps(c, c, _MM_SHUFFLE(0, 0, 0, 0)); + __m128 cy = _mm_shuffle_ps(c, c, _MM_SHUFFLE(1, 1, 1, 1)); + __m128 cz = _mm_shuffle_ps(c, c, _MM_SHUFFLE(2, 2, 2, 2)); + cx = _mm_mul_ps(cx, xMat); + cy = _mm_mul_ps(cy, yMat); + cz = _mm_mul_ps(cz, zMat); + cx = _mm_add_ps(cx, cy); + cx = _mm_add_ps(cx, cz); + // Clamp: + cx = _mm_min_ps(cx, maxV); + cx = _mm_max_ps(cx, minV); + _mm_storeu_ps(&buffer[j].x, cx); + } +#else + for (int j = 0; j < len; ++j) { + const QColorVector cv = colorMatrix.map(buffer[j]); + buffer[j].x = std::max(0.0f, std::min(1.0f, cv.x)); + buffer[j].y = std::max(0.0f, std::min(1.0f, cv.y)); + buffer[j].z = std::max(0.0f, std::min(1.0f, cv.z)); + } +#endif +} + +template<typename T> +static void loadPremultiplied(QColorVector *buffer, const T *src, const qsizetype len, const QColorTransformPrivate *d_ptr); +template<typename T> +static void loadUnpremultiplied(QColorVector *buffer, const T *src, const qsizetype len, const QColorTransformPrivate *d_ptr); + +#if defined(__SSE2__) +// Load to [0-alpha] in 4x32 SIMD +template<typename T> +static inline void loadP(const T &p, __m128i &v); + +template<> +inline void loadP<QRgb>(const QRgb &p, __m128i &v) +{ + v = _mm_cvtsi32_si128(p); +#if defined(__SSE4_1__) + v = _mm_cvtepu8_epi32(v); +#else + v = _mm_unpacklo_epi8(v, _mm_setzero_si128()); + v = _mm_unpacklo_epi16(v, _mm_setzero_si128()); +#endif +} + +template<> +inline void loadP<QRgba64>(const QRgba64 &p, __m128i &v) +{ + v = _mm_loadl_epi64((const __m128i *)&p); +#if defined(__SSE4_1__) + v = _mm_cvtepu16_epi32(v); +#else + v = _mm_unpacklo_epi16(v, _mm_setzero_si128()); +#endif + // Shuffle to ARGB as the template below expects it + v = _mm_shuffle_epi32(v, _MM_SHUFFLE(3, 0, 1, 2)); +} + +template<typename T> +static void loadPremultiplied(QColorVector *buffer, const T *src, const qsizetype len, const QColorTransformPrivate *d_ptr) +{ + const __m128 v4080 = _mm_set1_ps(4080.f); + const __m128 iFF00 = _mm_set1_ps(1.0f / (255 * 256)); + for (qsizetype i = 0; i < len; ++i) { + __m128i v; + loadP<T>(src[i], v); + __m128 vf = _mm_cvtepi32_ps(v); + // Approximate 1/a: + __m128 va = _mm_shuffle_ps(vf, vf, _MM_SHUFFLE(3, 3, 3, 3)); + __m128 via = _mm_rcp_ps(va); + via = _mm_sub_ps(_mm_add_ps(via, via), _mm_mul_ps(via, _mm_mul_ps(via, va))); + // v * (1/a) + vf = _mm_mul_ps(vf, via); + + // Handle zero alpha + __m128 vAlphaMask = _mm_cmpeq_ps(va, _mm_set1_ps(0.0f)); + vf = _mm_andnot_ps(vAlphaMask, vf); + + // LUT + v = _mm_cvtps_epi32(_mm_mul_ps(vf, v4080)); + const int ridx = _mm_extract_epi16(v, 4); + const int gidx = _mm_extract_epi16(v, 2); + const int bidx = _mm_extract_epi16(v, 0); + v = _mm_insert_epi16(v, d_ptr->colorSpaceIn->lut[0]->m_toLinear[ridx], 0); + v = _mm_insert_epi16(v, d_ptr->colorSpaceIn->lut[1]->m_toLinear[gidx], 2); + v = _mm_insert_epi16(v, d_ptr->colorSpaceIn->lut[2]->m_toLinear[bidx], 4); + vf = _mm_mul_ps(_mm_cvtepi32_ps(v), iFF00); + + _mm_storeu_ps(&buffer[i].x, vf); + } +} + +// Load to [0-4080] in 4x32 SIMD +template<typename T> +static inline void loadPU(const T &p, __m128i &v); + +template<> +inline void loadPU<QRgb>(const QRgb &p, __m128i &v) +{ + v = _mm_cvtsi32_si128(p); +#if defined(__SSE4_1__) + v = _mm_cvtepu8_epi32(v); +#else + v = _mm_unpacklo_epi8(v, _mm_setzero_si128()); + v = _mm_unpacklo_epi16(v, _mm_setzero_si128()); +#endif + v = _mm_slli_epi32(v, 4); +} + +template<> +inline void loadPU<QRgba64>(const QRgba64 &p, __m128i &v) +{ + v = _mm_loadl_epi64((const __m128i *)&p); + v = _mm_sub_epi16(v, _mm_srli_epi16(v, 8)); +#if defined(__SSE4_1__) + v = _mm_cvtepu16_epi32(v); +#else + v = _mm_unpacklo_epi16(v, _mm_setzero_si128()); +#endif + v = _mm_srli_epi32(v, 4); + // Shuffle to ARGB as the template below expects it + v = _mm_shuffle_epi32(v, _MM_SHUFFLE(3, 0, 1, 2)); +} + +template<typename T> +void loadUnpremultiplied(QColorVector *buffer, const T *src, const qsizetype len, const QColorTransformPrivate *d_ptr) +{ + const __m128 iFF00 = _mm_set1_ps(1.0f / (255 * 256)); + for (qsizetype i = 0; i < len; ++i) { + __m128i v; + loadPU<T>(src[i], v); + const int ridx = _mm_extract_epi16(v, 4); + const int gidx = _mm_extract_epi16(v, 2); + const int bidx = _mm_extract_epi16(v, 0); + v = _mm_insert_epi16(v, d_ptr->colorSpaceIn->lut[0]->m_toLinear[ridx], 0); + v = _mm_insert_epi16(v, d_ptr->colorSpaceIn->lut[1]->m_toLinear[gidx], 2); + v = _mm_insert_epi16(v, d_ptr->colorSpaceIn->lut[2]->m_toLinear[bidx], 4); + __m128 vf = _mm_mul_ps(_mm_cvtepi32_ps(v), iFF00); + _mm_storeu_ps(&buffer[i].x, vf); + } +} + +#else +template<> +void loadPremultiplied<QRgb>(QColorVector *buffer, const QRgb *src, const qsizetype len, const QColorTransformPrivate *d_ptr) +{ + for (qsizetype i = 0; i < len; ++i) { + const uint p = src[i]; + const int a = qAlpha(p); + if (a) { + const float ia = 4080.0f / a; + const int ridx = int(qRed(p) * ia + 0.5f); + const int gidx = int(qGreen(p) * ia + 0.5f); + const int bidx = int(qBlue(p) * ia + 0.5f); + buffer[i].x = d_ptr->colorSpaceIn->lut[0]->m_toLinear[ridx] * (1.0f / (255 * 256)); + buffer[i].y = d_ptr->colorSpaceIn->lut[1]->m_toLinear[gidx] * (1.0f / (255 * 256)); + buffer[i].z = d_ptr->colorSpaceIn->lut[2]->m_toLinear[bidx] * (1.0f / (255 * 256)); + } else { + buffer[i].x = buffer[i].y = buffer[i].z = 0.0f; + } + } +} + +template<> +void loadPremultiplied<QRgba64>(QColorVector *buffer, const QRgba64 *src, const qsizetype len, const QColorTransformPrivate *d_ptr) +{ + for (qsizetype i = 0; i < len; ++i) { + const QRgba64 &p = src[i]; + const int a = p.alpha(); + if (a) { + const float ia = 4080.0f / a; + const int ridx = int(p.red() * ia + 0.5f); + const int gidx = int(p.green() * ia + 0.5f); + const int bidx = int(p.blue() * ia + 0.5f); + buffer[i].x = d_ptr->colorSpaceIn->lut[0]->m_toLinear[ridx] * (1.0f / (255 * 256)); + buffer[i].y = d_ptr->colorSpaceIn->lut[1]->m_toLinear[gidx] * (1.0f / (255 * 256)); + buffer[i].z = d_ptr->colorSpaceIn->lut[2]->m_toLinear[bidx] * (1.0f / (255 * 256)); + } else { + buffer[i].x = buffer[i].y = buffer[i].z = 0.0f; + } + } +} + +template<> +void loadUnpremultiplied<QRgb>(QColorVector *buffer, const QRgb *src, const qsizetype len, const QColorTransformPrivate *d_ptr) +{ + for (qsizetype i = 0; i < len; ++i) { + const uint p = src[i]; + buffer[i].x = d_ptr->colorSpaceIn->lut[0]->u8ToLinearF32(qRed(p)); + buffer[i].y = d_ptr->colorSpaceIn->lut[1]->u8ToLinearF32(qGreen(p)); + buffer[i].z = d_ptr->colorSpaceIn->lut[2]->u8ToLinearF32(qBlue(p)); + } +} + +template<> +void loadUnpremultiplied<QRgba64>(QColorVector *buffer, const QRgba64 *src, const qsizetype len, const QColorTransformPrivate *d_ptr) +{ + for (qsizetype i = 0; i < len; ++i) { + const QRgba64 &p = src[i]; + buffer[i].x = d_ptr->colorSpaceIn->lut[0]->u16ToLinearF32(p.red()); + buffer[i].y = d_ptr->colorSpaceIn->lut[1]->u16ToLinearF32(p.green()); + buffer[i].z = d_ptr->colorSpaceIn->lut[2]->u16ToLinearF32(p.blue()); + } +} +#endif + +static void storePremultiplied(QRgb *dst, const QRgb *src, const QColorVector *buffer, const qsizetype len, + const QColorTransformPrivate *d_ptr) +{ +#if defined(__SSE2__) + const __m128 v4080 = _mm_set1_ps(4080.f); + const __m128 iFF00 = _mm_set1_ps(1.0f / (255 * 256)); + for (qsizetype i = 0; i < len; ++i) { + const int a = qAlpha(src[i]); + __m128 vf = _mm_loadu_ps(&buffer[i].x); + __m128i v = _mm_cvtps_epi32(_mm_mul_ps(vf, v4080)); + __m128 va = _mm_set1_ps(a); + va = _mm_mul_ps(va, iFF00); + const int ridx = _mm_extract_epi16(v, 0); + const int gidx = _mm_extract_epi16(v, 2); + const int bidx = _mm_extract_epi16(v, 4); + v = _mm_insert_epi16(v, d_ptr->colorSpaceOut->lut[0]->m_fromLinear[ridx], 4); + v = _mm_insert_epi16(v, d_ptr->colorSpaceOut->lut[1]->m_fromLinear[gidx], 2); + v = _mm_insert_epi16(v, d_ptr->colorSpaceOut->lut[2]->m_fromLinear[bidx], 0); + vf = _mm_cvtepi32_ps(v); + vf = _mm_mul_ps(vf, va); + v = _mm_cvtps_epi32(vf); + v = _mm_packs_epi32(v, v); + v = _mm_insert_epi16(v, a, 3); + v = _mm_packus_epi16(v, v); + dst[i] = _mm_cvtsi128_si32(v); + } +#else + for (qsizetype i = 0; i < len; ++i) { + const int a = qAlpha(src[i]); + const float fa = a / (255.0f * 256.0f); + const float r = d_ptr->colorSpaceOut->lut[0]->m_fromLinear[int(buffer[i].x * 4080.0f + 0.5f)]; + const float g = d_ptr->colorSpaceOut->lut[1]->m_fromLinear[int(buffer[i].y * 4080.0f + 0.5f)]; + const float b = d_ptr->colorSpaceOut->lut[2]->m_fromLinear[int(buffer[i].z * 4080.0f + 0.5f)]; + dst[i] = qRgba(r * fa + 0.5f, g * fa + 0.5f, b * fa + 0.5f, a); + } +#endif +} + +static void storeUnpremultiplied(QRgb *dst, const QRgb *src, const QColorVector *buffer, const qsizetype len, + const QColorTransformPrivate *d_ptr) +{ +#if defined(__SSE2__) + const __m128 v4080 = _mm_set1_ps(4080.f); + for (qsizetype i = 0; i < len; ++i) { + const int a = qAlpha(src[i]); + __m128 vf = _mm_loadu_ps(&buffer[i].x); + __m128i v = _mm_cvtps_epi32(_mm_mul_ps(vf, v4080)); + const int ridx = _mm_extract_epi16(v, 0); + const int gidx = _mm_extract_epi16(v, 2); + const int bidx = _mm_extract_epi16(v, 4); + v = _mm_setzero_si128(); + v = _mm_insert_epi16(v, d_ptr->colorSpaceOut->lut[0]->m_fromLinear[ridx], 2); + v = _mm_insert_epi16(v, d_ptr->colorSpaceOut->lut[1]->m_fromLinear[gidx], 1); + v = _mm_insert_epi16(v, d_ptr->colorSpaceOut->lut[2]->m_fromLinear[bidx], 0); + v = _mm_add_epi16(v, _mm_set1_epi16(0x80)); + v = _mm_srli_epi16(v, 8); + v = _mm_insert_epi16(v, a, 3); + v = _mm_packus_epi16(v, v); + dst[i] = _mm_cvtsi128_si32(v); + } +#else + for (qsizetype i = 0; i < len; ++i) { + const int r = d_ptr->colorSpaceOut->lut[0]->u8FromLinearF32(buffer[i].x); + const int g = d_ptr->colorSpaceOut->lut[1]->u8FromLinearF32(buffer[i].y); + const int b = d_ptr->colorSpaceOut->lut[2]->u8FromLinearF32(buffer[i].z); + dst[i] = (src[i] & 0xff000000) | (r << 16) | (g << 8) | (b << 0); + } +#endif +} + +static void storeOpaque(QRgb *dst, const QRgb *src, const QColorVector *buffer, const qsizetype len, + const QColorTransformPrivate *d_ptr) +{ + Q_UNUSED(src); +#if defined(__SSE2__) + const __m128 v4080 = _mm_set1_ps(4080.f); + for (qsizetype i = 0; i < len; ++i) { + __m128 vf = _mm_loadu_ps(&buffer[i].x); + __m128i v = _mm_cvtps_epi32(_mm_mul_ps(vf, v4080)); + const int ridx = _mm_extract_epi16(v, 0); + const int gidx = _mm_extract_epi16(v, 2); + const int bidx = _mm_extract_epi16(v, 4); + v = _mm_setzero_si128(); + v = _mm_insert_epi16(v, d_ptr->colorSpaceOut->lut[0]->m_fromLinear[ridx], 2); + v = _mm_insert_epi16(v, d_ptr->colorSpaceOut->lut[1]->m_fromLinear[gidx], 1); + v = _mm_insert_epi16(v, d_ptr->colorSpaceOut->lut[2]->m_fromLinear[bidx], 0); + v = _mm_add_epi16(v, _mm_set1_epi16(0x80)); + v = _mm_srli_epi16(v, 8); + v = _mm_insert_epi16(v, 255, 3); + v = _mm_packus_epi16(v, v); + dst[i] = _mm_cvtsi128_si32(v); + } +#else + for (qsizetype i = 0; i < len; ++i) { + const int r = d_ptr->colorSpaceOut->lut[0]->u8FromLinearF32(buffer[i].x); + const int g = d_ptr->colorSpaceOut->lut[1]->u8FromLinearF32(buffer[i].y); + const int b = d_ptr->colorSpaceOut->lut[2]->u8FromLinearF32(buffer[i].z); + dst[i] = 0xff000000 | (r << 16) | (g << 8) | (b << 0); + } +#endif +} + +static void storePremultiplied(QRgba64 *dst, const QRgba64 *src, const QColorVector *buffer, const qsizetype len, + const QColorTransformPrivate *d_ptr) +{ + for (qsizetype i = 0; i < len; ++i) { + const int a = src[i].alpha(); + const float fa = a / (255.0f * 256.0f); + const float r = d_ptr->colorSpaceOut->lut[0]->m_fromLinear[int(buffer[i].x * 4080.0f + 0.5f)]; + const float g = d_ptr->colorSpaceOut->lut[1]->m_fromLinear[int(buffer[i].y * 4080.0f + 0.5f)]; + const float b = d_ptr->colorSpaceOut->lut[2]->m_fromLinear[int(buffer[i].z * 4080.0f + 0.5f)]; + dst[i] = qRgba64(r * fa + 0.5f, g * fa + 0.5f, b * fa + 0.5f, a); + } +} + +static void storeUnpremultiplied(QRgba64 *dst, const QRgba64 *src, const QColorVector *buffer, const qsizetype len, + const QColorTransformPrivate *d_ptr) +{ + for (qsizetype i = 0; i < len; ++i) { + const int r = d_ptr->colorSpaceOut->lut[0]->u16FromLinearF32(buffer[i].x); + const int g = d_ptr->colorSpaceOut->lut[1]->u16FromLinearF32(buffer[i].y); + const int b = d_ptr->colorSpaceOut->lut[2]->u16FromLinearF32(buffer[i].z); + dst[i] = qRgba64(r, g, b, src[i].alpha()); + } +} + +static void storeOpaque(QRgba64 *dst, const QRgba64 *src, const QColorVector *buffer, const qsizetype len, + const QColorTransformPrivate *d_ptr) +{ + Q_UNUSED(src); + for (qsizetype i = 0; i < len; ++i) { + const int r = d_ptr->colorSpaceOut->lut[0]->u16FromLinearF32(buffer[i].x); + const int g = d_ptr->colorSpaceOut->lut[1]->u16FromLinearF32(buffer[i].y); + const int b = d_ptr->colorSpaceOut->lut[2]->u16FromLinearF32(buffer[i].z); + dst[i] = qRgba64(r, g, b, 0xFFFF); + } +} + +static constexpr qsizetype WorkBlockSize = 256; + +template<typename T> +void QColorTransformPrivate::apply(T *dst, const T *src, qsizetype count, TransformFlags flags) const +{ + if (!colorMatrix.isValid()) + return; + + updateLutsIn(); + updateLutsOut(); + + bool doApplyMatrix = (colorMatrix != QColorMatrix::identity()); + + QColorVector buffer[WorkBlockSize]; + qsizetype i = 0; + while (i < count) { + const qsizetype len = qMin(count - i, WorkBlockSize); + if (flags & InputPremultiplied) + loadPremultiplied(buffer, src + i, len, this); + else + loadUnpremultiplied(buffer, src + i, len, this); + + if (doApplyMatrix) + applyMatrix(buffer, len, colorMatrix); + + if (flags & InputOpaque) + storeOpaque(dst + i, src + i, buffer, len, this); + else if (flags & OutputPremultiplied) + storePremultiplied(dst + i, src + i, buffer, len, this); + else + storeUnpremultiplied(dst + i, src + i, buffer, len, this); + + i += len; + } +} + +/*! + \internal + \enum QColorTransformPrivate::TransformFlag + + Defines how the transform is to be applied. + + \value Unpremultiplied The input and output should both be unpremultiplied. + \value InputOpaque The input is guaranteed to be opaque. + \value InputPremultiplied The input is premultiplied. + \value OutputPremultiplied The output should be premultiplied. + \value Premultiplied Both input and output should both be premultiplied. +*/ + +/*! + \internal + Prepares a color transformation for fast application. You do not need to + call this explicitly as it will be called implicitly on the first transforms, but + if you want predictable performance on the first transforms, you can perform it + in advance. + + \sa QColorTransform::map(), apply() +*/ +void QColorTransformPrivate::prepare() +{ + updateLutsIn(); + updateLutsOut(); +} + +/*! + \internal + Applies the color transformation on \a count QRgb pixels starting from + \a src and stores the result in \a dst. + + Thread-safe if prepare() has been called first. + + Assumes unpremultiplied data by default. Set \a flags to change defaults. + + \sa prepare() +*/ +void QColorTransformPrivate::apply(QRgb *dst, const QRgb *src, qsizetype count, TransformFlags flags) const +{ + apply<QRgb>(dst, src, count, flags); +} + +/*! + \internal + Applies the color transformation on \a count QRgba64 pixels starting from + \a src and stores the result in \a dst. + + Thread-safe if prepare() has been called first. + + Assumes unpremultiplied data by default. Set \a flags to change defaults. + + \sa prepare() +*/ +void QColorTransformPrivate::apply(QRgba64 *dst, const QRgba64 *src, qsizetype count, TransformFlags flags) const +{ + apply<QRgba64>(dst, src, count, flags); +} + + +QT_END_NAMESPACE diff --git a/src/gui/painting/qcolortransform.h b/src/gui/painting/qcolortransform.h new file mode 100644 index 0000000000..9274387b97 --- /dev/null +++ b/src/gui/painting/qcolortransform.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QCOLORTRANSFORM_H +#define QCOLORTRANSFORM_H + +#include <QtGui/qtguiglobal.h> +#include <QtCore/qsharedpointer.h> +#include <QtGui/qrgb.h> + +QT_BEGIN_NAMESPACE + +class QColor; +class QRgba64; +class QColorSpacePrivate; +class QColorTransformPrivate; + +class Q_GUI_EXPORT QColorTransform +{ +public: + QColorTransform() noexcept : d_ptr(nullptr) { } + ~QColorTransform() noexcept; + QColorTransform(const QColorTransform &colorTransform) noexcept + : d_ptr(colorTransform.d_ptr) + { } + QColorTransform(QColorTransform &&colorTransform) noexcept + : d_ptr(std::move(colorTransform.d_ptr)) + { } + QColorTransform &operator=(const QColorTransform &other) noexcept + { + d_ptr = other.d_ptr; + return *this; + } + QColorTransform &operator=(QColorTransform &&other) noexcept + { + d_ptr = std::move(other.d_ptr); + return *this; + } + + bool isNull() const { return d_ptr.isNull(); } + + QRgb map(const QRgb &argb) const; + QRgba64 map(const QRgba64 &rgba64) const; + QColor map(const QColor &color) const; + +private: + friend class QColorSpace; + friend class QColorSpacePrivate; + friend class QImage; + + Q_DECLARE_PRIVATE(QColorTransform) + QSharedPointer<QColorTransformPrivate> d_ptr; +}; + +QT_END_NAMESPACE + +#endif // QCOLORTRANSFORM_H diff --git a/src/gui/painting/qcolortransform_p.h b/src/gui/painting/qcolortransform_p.h new file mode 100644 index 0000000000..74a1e7fe0a --- /dev/null +++ b/src/gui/painting/qcolortransform_p.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QCOLORTRANSFORM_P_H +#define QCOLORTRANSFORM_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qcolormatrix_p.h" +#include "qcolorspace_p.h" + +QT_BEGIN_NAMESPACE + +class QColorTransformPrivate +{ +public: + QColorMatrix colorMatrix; + QExplicitlySharedDataPointer<const QColorSpacePrivate> colorSpaceIn; + QExplicitlySharedDataPointer<const QColorSpacePrivate> colorSpaceOut; + + void updateLutsIn() const; + void updateLutsOut() const; + bool simpleGammaCorrection() const; + + void prepare(); + enum TransformFlag { + Unpremultiplied = 0, + InputOpaque = 1, + InputPremultiplied = 2, + OutputPremultiplied = 4, + Premultiplied = (InputPremultiplied | OutputPremultiplied) + }; + Q_DECLARE_FLAGS(TransformFlags, TransformFlag) + + void apply(QRgb *dst, const QRgb *src, qsizetype count, TransformFlags flags = Unpremultiplied) const; + void apply(QRgba64 *dst, const QRgba64 *src, qsizetype count, TransformFlags flags = Unpremultiplied) const; + + template<typename T> + void apply(T *dst, const T *src, qsizetype count, TransformFlags flags) const; +}; + +QT_END_NAMESPACE + +#endif // QCOLORTRANSFORM_P_H diff --git a/src/gui/painting/qcolortrc_p.h b/src/gui/painting/qcolortrc_p.h new file mode 100644 index 0000000000..3a649f3756 --- /dev/null +++ b/src/gui/painting/qcolortrc_p.h @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QCOLORTRC_P_H +#define QCOLORTRC_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/private/qtguiglobal_p.h> +#include "qcolortransferfunction_p.h" +#include "qcolortransfertable_p.h" + +QT_BEGIN_NAMESPACE + + +// Defines an ICC TRC (Tone Reproduction Curve) +class Q_GUI_EXPORT QColorTrc +{ +public: + QColorTrc() noexcept : m_type(Type::Uninitialized) + { } + QColorTrc(const QColorTransferFunction &fun) : m_type(Type::Function), m_fun(fun) + { } + QColorTrc(const QColorTransferTable &table) : m_type(Type::Table), m_table(table) + { } + + enum class Type { + Uninitialized, + Function, + Table + }; + + bool isLinear() const + { + return m_type == Type::Uninitialized || (m_type == Type::Function && m_fun.isLinear()); + } + bool isValid() const + { + return m_type != Type::Uninitialized; + } + float apply(float x) const + { + if (m_type == Type::Table) + return m_table.apply(x); + if (m_type == Type::Function) + return m_fun.apply(x); + return x; + } + + float applyInverse(float x) const + { + if (m_type == Type::Table) + return m_table.applyInverse(x); + if (m_type == Type::Function) + return m_fun.inverted().apply(x); + return x; + } + + friend inline bool operator!=(const QColorTrc &o1, const QColorTrc &o2); + friend inline bool operator==(const QColorTrc &o1, const QColorTrc &o2); + + Type m_type; + QColorTransferFunction m_fun; + QColorTransferTable m_table; +}; + +inline bool operator!=(const QColorTrc &o1, const QColorTrc &o2) +{ + if (o1.m_type != o2.m_type) + return true; + if (o1.m_type == QColorTrc::Type::Function) + return o1.m_fun != o2.m_fun; + if (o1.m_type == QColorTrc::Type::Table) + return o1.m_table != o2.m_table; + return false; +} +inline bool operator==(const QColorTrc &o1, const QColorTrc &o2) +{ + return !(o1 != o2); +} + +QT_END_NAMESPACE + +#endif // QCOLORTRC diff --git a/src/gui/painting/qcolorprofile.cpp b/src/gui/painting/qcolortrclut.cpp similarity index 69% rename from src/gui/painting/qcolorprofile.cpp rename to src/gui/painting/qcolortrclut.cpp index 3b7b0a248b..268d7252b4 100644 --- a/src/gui/painting/qcolorprofile.cpp +++ b/src/gui/painting/qcolortrclut.cpp @@ -37,14 +37,16 @@ ** ****************************************************************************/ -#include "qcolorprofile_p.h" +#include "qcolortrclut_p.h" +#include "qcolortransferfunction_p.h" +#include "qcolortransfertable_p.h" #include <qmath.h> QT_BEGIN_NAMESPACE -QColorProfile *QColorProfile::fromGamma(qreal gamma) +QColorTrcLut *QColorTrcLut::fromGamma(qreal gamma) { - QColorProfile *cp = new QColorProfile; + QColorTrcLut *cp = new QColorTrcLut; for (int i = 0; i <= (255 * 16); ++i) { cp->m_toLinear[i] = ushort(qRound(qPow(i / qreal(255 * 16), gamma) * (255 * 256))); @@ -54,31 +56,28 @@ QColorProfile *QColorProfile::fromGamma(qreal gamma) return cp; } -static qreal srgbToLinear(qreal v) +QColorTrcLut *QColorTrcLut::fromTransferFunction(const QColorTransferFunction &fun) { - const qreal a = 0.055; - if (v <= qreal(0.04045)) - return v / qreal(12.92); - else - return qPow((v + a) / (qreal(1) + a), qreal(2.4)); -} - -static qreal linearToSrgb(qreal v) -{ - const qreal a = 0.055; - if (v <= qreal(0.0031308)) - return v * qreal(12.92); - else - return (qreal(1) + a) * qPow(v, qreal(1.0 / 2.4)) - a; -} - -QColorProfile *QColorProfile::fromSRgb() -{ - QColorProfile *cp = new QColorProfile; + QColorTrcLut *cp = new QColorTrcLut; + QColorTransferFunction inv = fun.inverted(); for (int i = 0; i <= (255 * 16); ++i) { - cp->m_toLinear[i] = ushort(qRound(srgbToLinear(i / qreal(255 * 16)) * (255 * 256))); - cp->m_fromLinear[i] = ushort(qRound(linearToSrgb(i / qreal(255 * 16)) * (255 * 256))); + cp->m_toLinear[i] = ushort(qRound(fun.apply(i / qreal(255 * 16)) * (255 * 256))); + cp->m_fromLinear[i] = ushort(qRound(inv.apply(i / qreal(255 * 16)) * (255 * 256))); + } + + return cp; +} + +QColorTrcLut *QColorTrcLut::fromTransferTable(const QColorTransferTable &table) +{ + QColorTrcLut *cp = new QColorTrcLut; + + float minInverse = 0.0f; + for (int i = 0; i <= (255 * 16); ++i) { + cp->m_toLinear[i] = ushort(qBound(0, qRound(table.apply(i / qreal(255 * 16)) * (255 * 256)), 65280)); + minInverse = table.applyInverse(i / qreal(255 * 16), minInverse); + cp->m_fromLinear[i] = ushort(qBound(0, qRound(minInverse * (255 * 256)), 65280)); } return cp; diff --git a/src/gui/painting/qcolorprofile_p.h b/src/gui/painting/qcolortrclut_p.h similarity index 87% rename from src/gui/painting/qcolorprofile_p.h rename to src/gui/painting/qcolortrclut_p.h index 425e9abace..76a6a60803 100644 --- a/src/gui/painting/qcolorprofile_p.h +++ b/src/gui/painting/qcolortrclut_p.h @@ -37,8 +37,8 @@ ** ****************************************************************************/ -#ifndef QCOLORPROFILE_P_H -#define QCOLORPROFILE_P_H +#ifndef QCOLORTRCLUT_P_H +#define QCOLORTRCLUT_P_H // // W A R N I N G @@ -52,21 +52,29 @@ // #include <QtGui/private/qtguiglobal_p.h> +#include <QtCore/qsharedpointer.h> #include <QtGui/qrgb.h> #include <QtGui/qrgba64.h> +#include <cmath> + #if defined(__SSE2__) #include <emmintrin.h> #elif defined(__ARM_NEON__) || defined(__ARM_NEON) #include <arm_neon.h> #endif + QT_BEGIN_NAMESPACE -class Q_GUI_EXPORT QColorProfile +class QColorTransferFunction; +class QColorTransferTable; + +class Q_GUI_EXPORT QColorTrcLut : public QEnableSharedFromThis<QColorTrcLut> { public: - static QColorProfile *fromGamma(qreal gamma); - static QColorProfile *fromSRgb(); + static QColorTrcLut *fromGamma(qreal gamma); + static QColorTrcLut *fromTransferFunction(const QColorTransferFunction &transfn); + static QColorTrcLut *fromTransferTable(const QColorTransferTable &transTable); // The following methods all convert opaque or unpremultiplied colors: @@ -121,6 +129,25 @@ public: return convertWithTable(rgb64, m_toLinear); } + float u8ToLinearF32(int c) const + { + ushort v = m_toLinear[c << 4]; + return v * (1.0f / (255*256)); + } + + float u16ToLinearF32(int c) const + { + c -= (c >> 8); + ushort v = m_toLinear[c >> 4]; + return v * (1.0f / (255*256)); + } + + float toLinear(float f) const + { + ushort v = m_toLinear[(int)(f * (255 * 16) + 0.5f)]; + return v * (1.0f / (255*256)); + } + QRgb fromLinear64(QRgba64 rgb64) const { #if defined(__SSE2__) @@ -176,8 +203,31 @@ public: return convertWithTable(rgb64, m_fromLinear); } + int u8FromLinearF32(float f) const + { + ushort v = m_fromLinear[(int)(f * (255 * 16) + 0.5f)]; + return (v + 0x80) >> 8; + } + int u16FromLinearF32(float f) const + { + ushort v = m_fromLinear[(int)(f * (255 * 16) + 0.5f)]; + return v + (v >> 8); + } + float fromLinear(float f) const + { + ushort v = m_fromLinear[(int)(f * (255 * 16) + 0.5f)]; + return v * (1.0f / (255*256)); + } + + // We translate to 0-65280 (255*256) instead to 0-65535 to make simple + // shifting an accurate conversion. + // We translate from 0-4080 (255*16) for the same speed up, and to keep + // the tables small enough to fit in most inner caches. + ushort m_toLinear[(255 * 16) + 1]; // [0-4080] -> [0-65280] + ushort m_fromLinear[(255 * 16) + 1]; // [0-4080] -> [0-65280] + private: - QColorProfile() { } + QColorTrcLut() { } Q_ALWAYS_INLINE static QRgb convertWithTable(QRgb rgb32, const ushort *table) { @@ -230,16 +280,8 @@ private: return QRgba64::fromRgba64(r, g, b, rgb64.alpha()); #endif } - - // We translate to 0-65280 (255*256) instead to 0-65535 to make simple - // shifting an accurate conversion. - // We translate from 0-4080 (255*16) for the same speed up, and to keep - // the tables small enough to fit in most inner caches. - ushort m_toLinear[(255 * 16) + 1]; // [0-4080] -> [0-65280] - ushort m_fromLinear[(255 * 16) + 1]; // [0-4080] -> [0-65280] - }; QT_END_NAMESPACE -#endif // QCOLORPROFILE_P_H +#endif // QCOLORTRCLUT_P_H diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 2dd18f6dfc..1ed51d26a2 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -43,7 +43,7 @@ #include <qstylehints.h> #include <qguiapplication.h> #include <qatomic.h> -#include <private/qcolorprofile_p.h> +#include <private/qcolortrclut_p.h> #include <private/qdrawhelper_p.h> #include <private/qpaintengine_raster_p.h> #include <private/qpainter_p.h> @@ -5523,7 +5523,7 @@ inline static void qt_bitmapblit_quint16(QRasterBuffer *rasterBuffer, map, mapWidth, mapHeight, mapStride); } -static inline void alphamapblend_generic(int coverage, QRgba64 *dest, int x, const QRgba64 &srcLinear, const QRgba64 &src, const QColorProfile *colorProfile) +static inline void alphamapblend_generic(int coverage, QRgba64 *dest, int x, const QRgba64 &srcLinear, const QRgba64 &src, const QColorTrcLut *colorProfile) { if (coverage == 0) { // nothing @@ -5558,7 +5558,7 @@ static void qt_alphamapblit_generic(QRasterBuffer *rasterBuffer, if (color.isTransparent()) return; - const QColorProfile *colorProfile = nullptr; + const QColorTrcLut *colorProfile = nullptr; if (useGammaCorrection) colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text(); @@ -5684,7 +5684,7 @@ void qt_alphamapblit_quint16(QRasterBuffer *rasterBuffer, } } -static inline void rgbBlendPixel(quint32 *dst, int coverage, QRgba64 slinear, const QColorProfile *colorProfile) +static inline void rgbBlendPixel(quint32 *dst, int coverage, QRgba64 slinear, const QColorTrcLut *colorProfile) { // Do a gammacorrected RGB alphablend... const QRgba64 dlinear = colorProfile ? colorProfile->toLinear64(*dst) : QRgba64::fromArgb32(*dst); @@ -5694,7 +5694,7 @@ static inline void rgbBlendPixel(quint32 *dst, int coverage, QRgba64 slinear, co *dst = colorProfile ? colorProfile->fromLinear64(blend) : toArgb32(blend); } -static inline void grayBlendPixel(quint32 *dst, int coverage, QRgba64 srcLinear, const QColorProfile *colorProfile) +static inline void grayBlendPixel(quint32 *dst, int coverage, QRgba64 srcLinear, const QColorTrcLut *colorProfile) { // Do a gammacorrected gray alphablend... const QRgba64 dstLinear = colorProfile ? colorProfile->toLinear64(*dst) : QRgba64::fromArgb32(*dst); @@ -5704,7 +5704,7 @@ static inline void grayBlendPixel(quint32 *dst, int coverage, QRgba64 srcLinear, *dst = colorProfile ? colorProfile->fromLinear64(blend) : toArgb32(blend); } -static inline void alphamapblend_argb32(quint32 *dst, int coverage, QRgba64 srcLinear, quint32 src, const QColorProfile *colorProfile) +static inline void alphamapblend_argb32(quint32 *dst, int coverage, QRgba64 srcLinear, quint32 src, const QColorTrcLut *colorProfile) { if (coverage == 0) { // nothing @@ -5734,7 +5734,7 @@ static void qt_alphamapblit_argb32(QRasterBuffer *rasterBuffer, if (color.isTransparent()) return; - const QColorProfile *colorProfile = nullptr; + const QColorTrcLut *colorProfile = nullptr; if (useGammaCorrection) colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text(); @@ -5830,7 +5830,7 @@ static inline QRgb rgbBlend(QRgb d, QRgb s, uint rgbAlpha) #endif } -static inline void alphargbblend_generic(uint coverage, QRgba64 *dest, int x, const QRgba64 &srcLinear, const QRgba64 &src, const QColorProfile *colorProfile) +static inline void alphargbblend_generic(uint coverage, QRgba64 *dest, int x, const QRgba64 &srcLinear, const QRgba64 &src, const QColorTrcLut *colorProfile) { if (coverage == 0xff000000) { // nothing @@ -5852,7 +5852,7 @@ static inline void alphargbblend_generic(uint coverage, QRgba64 *dest, int x, co } } -static inline void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba64 &srcLinear, quint32 src, const QColorProfile *colorProfile) +static inline void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba64 &srcLinear, quint32 src, const QColorTrcLut *colorProfile) { if (coverage == 0xff000000) { // nothing @@ -5877,7 +5877,7 @@ static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer, if (color.isTransparent()) return; - const QColorProfile *colorProfile = nullptr; + const QColorTrcLut *colorProfile = nullptr; if (useGammaCorrection) colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text(); @@ -5954,7 +5954,7 @@ static void qt_alphargbblit_argb32(QRasterBuffer *rasterBuffer, const quint32 c = color.toArgb32(); - const QColorProfile *colorProfile = nullptr; + const QColorTrcLut *colorProfile = nullptr; if (useGammaCorrection) colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text(); diff --git a/src/gui/painting/qicc.cpp b/src/gui/painting/qicc.cpp new file mode 100644 index 0000000000..d88b005782 --- /dev/null +++ b/src/gui/painting/qicc.cpp @@ -0,0 +1,669 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qicc_p.h" + +#include <qbuffer.h> +#include <qbytearray.h> +#include <qdatastream.h> +#include <qloggingcategory.h> +#include <qendian.h> + +#include "qcolorspace_p.h" +#include "qcolortrc_p.h" + +QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcIcc, "qt.gui.icc") + +struct ICCProfileHeader +{ + quint32_be profileSize; + + quint32_be preferredCmmType; + + quint32_be profileVersion; + quint32_be profileClass; + quint32_be inputColorSpace; + quint32_be pcs; + quint32_be datetime[3]; + quint32_be signature; + quint32_be platformSignature; + quint32_be flags; + quint32_be deviceManufacturer; + quint32_be deviceModel; + quint32_be deviceAttributes[2]; + + quint32_be renderingIntent; + qint32_be illuminantXyz[3]; + + quint32_be creatorSignature; + quint32_be profileId[4]; + + quint32_be reserved[7]; + +// Technically after the header, but easier to include here: + quint32_be tagCount; +}; + +constexpr quint32 IccTag(uchar a, uchar b, uchar c, uchar d) +{ + return (a << 24) | (b << 16) | (c << 8) | d; +} + +enum class ProfileClass : quint32 { + Input = IccTag('s', 'c', 'r', 'n'), + Display = IccTag('m', 'n', 't', 'r'), + // Not supported: + Output = IccTag('p', 'r', 't', 'r'), + ColorSpace = IccTag('s', 'p', 'a', 'c'), +}; + +enum class Tag : quint32 { + acsp = IccTag('a', 'c', 's', 'p'), + RGB_ = IccTag('R', 'G', 'B', ' '), + XYZ_ = IccTag('X', 'Y', 'Z', ' '), + rXYZ = IccTag('r', 'X', 'Y', 'Z'), + gXYZ = IccTag('g', 'X', 'Y', 'Z'), + bXYZ = IccTag('b', 'X', 'Y', 'Z'), + rTRC = IccTag('r', 'T', 'R', 'C'), + gTRC = IccTag('g', 'T', 'R', 'C'), + bTRC = IccTag('b', 'T', 'R', 'C'), + A2B0 = IccTag('A', '2', 'B', '0'), + A2B1 = IccTag('A', '2', 'B', '1'), + B2A0 = IccTag('B', '2', 'A', '0'), + B2A1 = IccTag('B', '2', 'A', '1'), + desc = IccTag('d', 'e', 's', 'c'), + text = IccTag('t', 'e', 'x', 't'), + cprt = IccTag('c', 'p', 'r', 't'), + curv = IccTag('c', 'u', 'r', 'v'), + para = IccTag('p', 'a', 'r', 'a'), + wtpt = IccTag('w', 't', 'p', 't'), + bkpt = IccTag('b', 'k', 'p', 't'), + mft1 = IccTag('m', 'f', 't', '1'), + mft2 = IccTag('m', 'f', 't', '2'), + mAB_ = IccTag('m', 'A', 'B', ' '), + mBA_ = IccTag('m', 'B', 'A', ' '), + chad = IccTag('c', 'h', 'a', 'd'), + sf32 = IccTag('s', 'f', '3', '2'), + + // Apple extensions for ICCv2: + aarg = IccTag('a', 'a', 'r', 'g'), + aagg = IccTag('a', 'a', 'g', 'g'), + aabg = IccTag('a', 'a', 'b', 'g'), +}; + +inline uint qHash(const Tag &key, uint seed = 0) +{ + return qHash(quint32(key), seed); +} + +namespace QIcc { + +struct TagTableEntry +{ + quint32_be signature; + quint32_be offset; + quint32_be size; +}; + +struct GenericTagData { + quint32_be type; + quint32_be null; +}; + +struct XYZTagData : GenericTagData { + qint32_be fixedX; + qint32_be fixedY; + qint32_be fixedZ; +}; + +struct CurvTagData : GenericTagData { + quint32_be valueCount; + quint16_be value[1]; +}; + +struct ParaTagData : GenericTagData { + quint16_be curveType; + quint16_be null2; + quint32_be parameter[1]; +}; + +// For both mAB and mBA +struct mABTagData : GenericTagData { + quint8 inputChannels; + quint8 outputChannels; + quint8 padding[2]; + quint32_be bCurvesOffset; + quint32_be matrixOffset; + quint32_be mCurvesOffset; + quint32_be clutOffset; + quint32_be aCurvesOffset; +}; + +struct Sf32TagData : GenericTagData { + quint32_be value[1]; +}; + +static int toFixedS1516(float x) +{ + return int(x * 65536.0f + 0.5f); +} + +static float fromFixedS1516(int x) +{ + return x * (1.0f / 65536.0f); +} + +QColorVector fromXyzData(const XYZTagData *xyz) +{ + const float x = fromFixedS1516(xyz->fixedX); + const float y = fromFixedS1516(xyz->fixedY); + const float z = fromFixedS1516(xyz->fixedZ); + qCDebug(lcIcc) << "XYZ_ " << x << y << z; + + return QColorVector(x, y, z); +} + +static bool isValidIccProfile(const ICCProfileHeader &header) +{ + if (header.signature != uint(Tag::acsp)) { + qCWarning(lcIcc, "Failed ICC signature test"); + return false; + } + if (header.profileSize < (sizeof(ICCProfileHeader) + header.tagCount * sizeof(TagTableEntry))) { + qCWarning(lcIcc, "Failed basic size sanity"); + return false; + } + + if (header.profileClass != uint(ProfileClass::Input) + && header.profileClass != uint(ProfileClass::Display)) { + qCWarning(lcIcc, "Unsupported ICC profile class %x", quint32(header.profileClass)); + return false; + } + if (header.inputColorSpace != 0x52474220 /* 'RGB '*/) { + qCWarning(lcIcc, "Unsupported ICC input color space %x", quint32(header.inputColorSpace)); + return false; + } + if (header.pcs != 0x58595a20 /* 'XYZ '*/) { + // ### support PCSLAB + qCWarning(lcIcc, "Unsupported ICC profile connection space %x", quint32(header.pcs)); + return false; + } + + QColorVector illuminant; + illuminant.x = fromFixedS1516(header.illuminantXyz[0]); + illuminant.y = fromFixedS1516(header.illuminantXyz[1]); + illuminant.z = fromFixedS1516(header.illuminantXyz[2]); + if (illuminant != QColorVector::D50()) { + qCWarning(lcIcc, "Invalid ICC illuminant"); + return false; + } + + return true; +} + +static int writeColorTrc(QDataStream &stream, const QColorTrc &trc) +{ + if (trc.isLinear()) { + stream << uint(Tag::curv) << uint(0); + stream << uint(0); + return 12; + } + + if (trc.m_type == QColorTrc::Type::Function) { + const QColorTransferFunction &fun = trc.m_fun; + stream << uint(Tag::para) << uint(0); + if (fun.isGamma()) { + stream << ushort(0) << ushort(0); + stream << toFixedS1516(fun.m_g); + return 12 + 4; + } + bool type3 = qFuzzyIsNull(fun.m_e) && qFuzzyIsNull(fun.m_f); + stream << ushort(type3 ? 3 : 4) << ushort(0); + stream << toFixedS1516(fun.m_g); + stream << toFixedS1516(fun.m_a); + stream << toFixedS1516(fun.m_b); + stream << toFixedS1516(fun.m_c); + stream << toFixedS1516(fun.m_d); + if (type3) + return 12 + 5 * 4; + stream << toFixedS1516(fun.m_e); + stream << toFixedS1516(fun.m_f); + return 12 + 7 * 4; + } + + Q_ASSERT(trc.m_type == QColorTrc::Type::Table); + stream << uint(Tag::curv) << uint(0); + stream << uint(trc.m_table.m_tableSize); + if (!trc.m_table.m_table16.isEmpty()) { + for (uint i = 0; i < trc.m_table.m_tableSize; ++i) { + stream << ushort(trc.m_table.m_table16[i]); + } + } else { + for (uint i = 0; i < trc.m_table.m_tableSize; ++i) { + stream << ushort(trc.m_table.m_table8[i] * 257U); + } + } + return 12 + 2 * trc.m_table.m_tableSize; +} + +QByteArray toIccProfile(const QColorSpace &space) +{ + if (!space.isValid()) + return QByteArray(); + + const QColorSpacePrivate *spaceDPtr = space.d_func(); + + constexpr int tagCount = 9; + constexpr uint profileDataOffset = 128 + 4 + 12 * tagCount; + constexpr uint variableTagTableOffsets = 128 + 4 + 12 * 5; + uint currentOffset = 0; + uint rTrcOffset, gTrcOffset, bTrcOffset; + uint rTrcSize, gTrcSize, bTrcSize; + uint descOffset, descSize; + + QBuffer buffer; + buffer.open(QIODevice::WriteOnly); + QDataStream stream(&buffer); + + // Profile header: + stream << uint(0); // Size, we will update this later + stream << uint(0); + stream << uint(0x02400000); // Version 2.4 (note we use 'para' from version 4) + stream << uint(ProfileClass::Display); + stream << uint(Tag::RGB_); + stream << uint(Tag::XYZ_); + stream << uint(0) << uint(0) << uint(0); + stream << uint(Tag::acsp); + stream << uint(0) << uint(0) << uint(0); + stream << uint(0) << uint(0) << uint(0); + stream << uint(1); // Rendering intent + stream << uint(0x0000f6d6); // D50 X + stream << uint(0x00010000); // D50 Y + stream << uint(0x0000d32d); // D50 Z + stream << IccTag('Q','t', QT_VERSION_MAJOR, QT_VERSION_MINOR); + stream << uint(0) << uint(0) << uint(0) << uint(0); + stream << uint(0) << uint(0) << uint(0) << uint(0) << uint(0) << uint(0) << uint(0); + + // Tag table: + stream << uint(tagCount); + stream << uint(Tag::rXYZ) << uint(profileDataOffset + 00) << uint(20); + stream << uint(Tag::gXYZ) << uint(profileDataOffset + 20) << uint(20); + stream << uint(Tag::bXYZ) << uint(profileDataOffset + 40) << uint(20); + stream << uint(Tag::wtpt) << uint(profileDataOffset + 60) << uint(20); + stream << uint(Tag::cprt) << uint(profileDataOffset + 80) << uint(12); + // From here the offset and size will be updated later: + stream << uint(Tag::rTRC) << uint(0) << uint(0); + stream << uint(Tag::gTRC) << uint(0) << uint(0); + stream << uint(Tag::bTRC) << uint(0) << uint(0); + stream << uint(Tag::desc) << uint(0) << uint(0); + // TODO: consider adding 'chad' tag (required in ICC >=4 when we have non-D50 whitepoint) + currentOffset = profileDataOffset; + + // Tag data: + stream << uint(Tag::XYZ_) << uint(0); + stream << toFixedS1516(spaceDPtr->toXyz.r.x); + stream << toFixedS1516(spaceDPtr->toXyz.r.y); + stream << toFixedS1516(spaceDPtr->toXyz.r.z); + stream << uint(Tag::XYZ_) << uint(0); + stream << toFixedS1516(spaceDPtr->toXyz.g.x); + stream << toFixedS1516(spaceDPtr->toXyz.g.y); + stream << toFixedS1516(spaceDPtr->toXyz.g.z); + stream << uint(Tag::XYZ_) << uint(0); + stream << toFixedS1516(spaceDPtr->toXyz.b.x); + stream << toFixedS1516(spaceDPtr->toXyz.b.y); + stream << toFixedS1516(spaceDPtr->toXyz.b.z); + stream << uint(Tag::XYZ_) << uint(0); + stream << toFixedS1516(spaceDPtr->whitePoint.x); + stream << toFixedS1516(spaceDPtr->whitePoint.y); + stream << toFixedS1516(spaceDPtr->whitePoint.z); + stream << uint(Tag::text) << uint(0); + stream << uint(IccTag('N', '/', 'A', '\0')); + currentOffset += 92; + + // From now on the data is variable sized: + rTrcOffset = currentOffset; + rTrcSize = writeColorTrc(stream, spaceDPtr->trc[0]); + currentOffset += rTrcSize; + if (spaceDPtr->trc[0] == spaceDPtr->trc[1]) { + gTrcOffset = rTrcOffset; + gTrcSize = rTrcSize; + } else { + gTrcOffset = currentOffset; + gTrcSize = writeColorTrc(stream, spaceDPtr->trc[1]); + currentOffset += gTrcSize; + } + if (spaceDPtr->trc[0] == spaceDPtr->trc[2]) { + bTrcOffset = rTrcOffset; + bTrcSize = rTrcSize; + } else { + bTrcOffset = currentOffset; + bTrcSize = writeColorTrc(stream, spaceDPtr->trc[2]); + currentOffset += bTrcSize; + } + + descOffset = currentOffset; + QByteArray description = spaceDPtr->description.toUtf8(); + stream << uint(Tag::desc) << uint(0); + stream << uint(description.size() + 1); + stream.writeRawData(description.constData(), description.size() + 1); + stream << uint(0) << uint(0); + stream << ushort(0) << uchar(0); + QByteArray macdesc(67, '\0'); + stream.writeRawData(macdesc.constData(), 67); + descSize = 90 + description.size() + 1; + currentOffset += descSize; + + buffer.close(); + QByteArray iccProfile = buffer.buffer(); + // Now write final size + *(quint32_be *)iccProfile.data() = iccProfile.size(); + // And the final indices and sizes of variable size tags: + *(quint32_be *)(iccProfile.data() + variableTagTableOffsets + 4) = rTrcOffset; + *(quint32_be *)(iccProfile.data() + variableTagTableOffsets + 8) = rTrcSize; + *(quint32_be *)(iccProfile.data() + variableTagTableOffsets + 12 + 4) = gTrcOffset; + *(quint32_be *)(iccProfile.data() + variableTagTableOffsets + 12 + 8) = gTrcSize; + *(quint32_be *)(iccProfile.data() + variableTagTableOffsets + 2 * 12 + 4) = bTrcOffset; + *(quint32_be *)(iccProfile.data() + variableTagTableOffsets + 2 * 12 + 8) = bTrcSize; + *(quint32_be *)(iccProfile.data() + variableTagTableOffsets + 3 * 12 + 4) = descOffset; + *(quint32_be *)(iccProfile.data() + variableTagTableOffsets + 3 * 12 + 8) = descSize; + +#if !defined(QT_NO_DEBUG) || defined(QT_FORCE_ASSERTS) + const ICCProfileHeader *iccHeader = (const ICCProfileHeader *)iccProfile.constData(); + Q_ASSERT(qsizetype(iccHeader->profileSize) == qsizetype(iccProfile.size())); + Q_ASSERT(isValidIccProfile(*iccHeader)); +#endif + + return iccProfile; +} + +bool parseTRC(const GenericTagData *trcData, QColorTrc &gamma) +{ + if (trcData->type == quint32(Tag::curv)) { + const CurvTagData *curv = reinterpret_cast<const CurvTagData *>(trcData); + qCDebug(lcIcc) << "curv" << uint(curv->valueCount); + if (curv->valueCount == 0) { + gamma.m_type = QColorTrc::Type::Function; + gamma.m_fun = QColorTransferFunction(); // Linear + } else if (curv->valueCount == 1) { + float g = curv->value[0] * (1.0f / 256.0f); + qCDebug(lcIcc) << g; + gamma.m_type = QColorTrc::Type::Function; + gamma.m_fun = QColorTransferFunction::fromGamma(g); + } else { + QVector<quint16> tabl; + tabl.resize(curv->valueCount); + for (uint i = 0; i < curv->valueCount; ++i) + tabl[i] = curv->value[i]; + QColorTransferTable table = QColorTransferTable(curv->valueCount, std::move(tabl)); + QColorTransferFunction curve; + if (!table.asColorTransferFunction(&curve)) { + gamma.m_type = QColorTrc::Type::Table; + gamma.m_table = table; + } else { + qCDebug(lcIcc) << "Detected curv table as function"; + gamma.m_type = QColorTrc::Type::Function; + gamma.m_fun = curve; + } + } + return true; + } + if (trcData->type == quint32(Tag::para)) { + const ParaTagData *para = reinterpret_cast<const ParaTagData *>(trcData); + qCDebug(lcIcc) << "para" << uint(para->curveType); + switch (para->curveType) { + case 0: { + float g = fromFixedS1516(para->parameter[0]); + qCDebug(lcIcc) << g; + gamma.m_type = QColorTrc::Type::Function; + gamma.m_fun = QColorTransferFunction::fromGamma(g); + break; + } + case 1: { + float g = fromFixedS1516(para->parameter[0]); + float a = fromFixedS1516(para->parameter[1]); + float b = fromFixedS1516(para->parameter[2]); + float d = -b / a; + qCDebug(lcIcc) << g << a << b; + gamma.m_type = QColorTrc::Type::Function; + gamma.m_fun = QColorTransferFunction(a, b, 0.0f, d, 0.0f, 0.0f, g); + break; + } + case 2: { + float g = fromFixedS1516(para->parameter[0]); + float a = fromFixedS1516(para->parameter[1]); + float b = fromFixedS1516(para->parameter[2]); + float c = fromFixedS1516(para->parameter[3]); + float d = -b / a; + qCDebug(lcIcc) << g << a << b << c; + gamma.m_type = QColorTrc::Type::Function; + gamma.m_fun = QColorTransferFunction(a, b, 0.0f, d, c, c, g); + break; + } + case 3: { + float g = fromFixedS1516(para->parameter[0]); + float a = fromFixedS1516(para->parameter[1]); + float b = fromFixedS1516(para->parameter[2]); + float c = fromFixedS1516(para->parameter[3]); + float d = fromFixedS1516(para->parameter[4]); + qCDebug(lcIcc) << g << a << b << c << d; + gamma.m_type = QColorTrc::Type::Function; + gamma.m_fun = QColorTransferFunction(a, b, c, d, 0.0f, 0.0f, g); + break; + } + case 4: { + float g = fromFixedS1516(para->parameter[0]); + float a = fromFixedS1516(para->parameter[1]); + float b = fromFixedS1516(para->parameter[2]); + float c = fromFixedS1516(para->parameter[3]); + float d = fromFixedS1516(para->parameter[4]); + float e = fromFixedS1516(para->parameter[5]); + float f = fromFixedS1516(para->parameter[6]); + qCDebug(lcIcc) << g << a << b << c << d << e << f; + gamma.m_type = QColorTrc::Type::Function; + gamma.m_fun = QColorTransferFunction(a, b, c, d, e, f, g); + break; + } + default: + qCWarning(lcIcc) << "Unknown para type" << uint(para->curveType); + return false; + } + return true; + } + qCWarning(lcIcc) << "Invalid TRC data type"; + return false; +} + +bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace) +{ + if (data.size() < qsizetype(sizeof(ICCProfileHeader))) { + qCWarning(lcIcc) << "fromIccProfile: failed size sanity 1"; + return false; + } + const ICCProfileHeader *header = (const ICCProfileHeader *)data.constData(); + if (!isValidIccProfile(*header)) { + qCWarning(lcIcc) << "fromIccProfile: failed general sanity check"; + return false; + } + if (qsizetype(header->profileSize) > data.size()) { + qCWarning(lcIcc) << "fromIccProfile: failed size sanity 2"; + return false; + } + + // Read tag index + const TagTableEntry *tagTable = (const TagTableEntry *)(data.constData() + sizeof(ICCProfileHeader)); + const qsizetype offsetToData = sizeof(ICCProfileHeader) + header->tagCount * sizeof(TagTableEntry); + + QHash<Tag, quint32> tagIndex; + for (uint i = 0; i < header->tagCount; ++i) { + // Sanity check tag sizes and offsets: + if (qsizetype(tagTable[i].offset) < offsetToData) { + qCWarning(lcIcc) << "fromIccProfile: failed tag offset sanity 1"; + return false; + } + // Checked separately from (+ size) to handle overflow. + if (tagTable[i].offset > header->profileSize) { + qCWarning(lcIcc) << "fromIccProfile: failed tag offset sanity 2"; + return false; + } + if ((tagTable[i].offset + tagTable[i].size) > header->profileSize) { + qCWarning(lcIcc) << "fromIccProfile: failed tag offset + size sanity"; + return false; + } +// printf("'%4s' %d %d\n", (const char *)&tagTable[i].signature, +// quint32(tagTable[i].offset), +// quint32(tagTable[i].size)); + tagIndex.insert(Tag(quint32(tagTable[i].signature)), tagTable[i].offset); + } + // Check the profile is three-component matrix based (what we currently support): + if (!tagIndex.contains(Tag::rXYZ) || !tagIndex.contains(Tag::gXYZ) || !tagIndex.contains(Tag::bXYZ) || + !tagIndex.contains(Tag::rTRC) || !tagIndex.contains(Tag::gTRC) || !tagIndex.contains(Tag::bTRC) || + !tagIndex.contains(Tag::wtpt)) { + qCWarning(lcIcc) << "fromIccProfile: Unsupported ICC profile - not three component matrix based"; + return false; + } + + // Parse XYZ tags + const XYZTagData *rXyz = (const XYZTagData *)(data.constData() + tagIndex[Tag::rXYZ]); + const XYZTagData *gXyz = (const XYZTagData *)(data.constData() + tagIndex[Tag::gXYZ]); + const XYZTagData *bXyz = (const XYZTagData *)(data.constData() + tagIndex[Tag::bXYZ]); + const XYZTagData *wXyz = (const XYZTagData *)(data.constData() + tagIndex[Tag::wtpt]); + if (rXyz->type != quint32(Tag::XYZ_) || gXyz->type != quint32(Tag::XYZ_) || + wXyz->type != quint32(Tag::XYZ_) || wXyz->type != quint32(Tag::XYZ_)) { + qCWarning(lcIcc) << "fromIccProfile: Bad XYZ data type"; + return false; + } + QColorSpacePrivate *colorspaceDPtr = colorSpace->d_func(); + + colorspaceDPtr->toXyz.r = fromXyzData(rXyz); + colorspaceDPtr->toXyz.g = fromXyzData(gXyz); + colorspaceDPtr->toXyz.b = fromXyzData(bXyz); + QColorVector whitePoint = fromXyzData(wXyz); + colorspaceDPtr->whitePoint = whitePoint; + + colorspaceDPtr->gamut = QColorSpace::Gamut::Custom; + if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromSRgb()) { + qCDebug(lcIcc) << "fromIccProfile: sRGB gamut detected"; + colorspaceDPtr->gamut = QColorSpace::Gamut::SRgb; + } else if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromAdobeRgb()) { + qCDebug(lcIcc) << "fromIccProfile: Adobe RGB gamut detected"; + colorspaceDPtr->gamut = QColorSpace::Gamut::AdobeRgb; + } else if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromDciP3D65()) { + qCDebug(lcIcc) << "fromIccProfile: DCI-P3 D65 gamut detected"; + colorspaceDPtr->gamut = QColorSpace::Gamut::DciP3D65; + } else if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromBt2020()) { + qCDebug(lcIcc) << "fromIccProfile: BT.2020 gamut detected"; + colorspaceDPtr->gamut = QColorSpace::Gamut::Bt2020; + } + if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromProPhotoRgb()) { + qCDebug(lcIcc) << "fromIccProfile: ProPhoto RGB gamut detected"; + colorspaceDPtr->gamut = QColorSpace::Gamut::ProPhotoRgb; + } + // Reset the matrix to our canonical values: + if (colorspaceDPtr->gamut != QColorSpace::Gamut::Custom) + colorspaceDPtr->setToXyzMatrix(); + + // Parse TRC tags + const GenericTagData *rTrc; + const GenericTagData *gTrc; + const GenericTagData *bTrc; + if (tagIndex.contains(Tag::aarg) && tagIndex.contains(Tag::aagg) && tagIndex.contains(Tag::aabg)) { + // Apple extension for parametric version of TRCs in ICCv2: + rTrc = (const GenericTagData *)(data.constData() + tagIndex[Tag::aarg]); + gTrc = (const GenericTagData *)(data.constData() + tagIndex[Tag::aagg]); + bTrc = (const GenericTagData *)(data.constData() + tagIndex[Tag::aabg]); + } else { + rTrc = (const GenericTagData *)(data.constData() + tagIndex[Tag::rTRC]); + gTrc = (const GenericTagData *)(data.constData() + tagIndex[Tag::gTRC]); + bTrc = (const GenericTagData *)(data.constData() + tagIndex[Tag::bTRC]); + } + + QColorTrc rCurve; + QColorTrc gCurve; + QColorTrc bCurve; + if (!parseTRC(rTrc, rCurve)) + return false; + if (!parseTRC(gTrc, gCurve)) + return false; + if (!parseTRC(bTrc, bCurve)) + return false; + if (rCurve == gCurve && gCurve == bCurve && rCurve.m_type == QColorTrc::Type::Function) { + if (rCurve.m_fun.isLinear()) { + qCDebug(lcIcc) << "fromIccProfile: Linear gamma detected"; + colorspaceDPtr->trc[0] = QColorTransferFunction(); + colorspaceDPtr->transferFunction = QColorSpace::TransferFunction::Linear; + colorspaceDPtr->gamma = 1.0f; + } else if (rCurve.m_fun.isGamma()) { + qCDebug(lcIcc) << "fromIccProfile: Simple gamma detected"; + colorspaceDPtr->trc[0] = QColorTransferFunction::fromGamma(rCurve.m_fun.m_g); + colorspaceDPtr->transferFunction = QColorSpace::TransferFunction::Gamma; + colorspaceDPtr->gamma = rCurve.m_fun.m_g; + } else if (rCurve.m_fun.isSRgb()) { + qCDebug(lcIcc) << "fromIccProfile: sRGB gamma detected"; + colorspaceDPtr->trc[0] = QColorTransferFunction::fromSRgb(); + colorspaceDPtr->transferFunction = QColorSpace::TransferFunction::SRgb; + } else { + colorspaceDPtr->trc[0] = rCurve; + colorspaceDPtr->transferFunction = QColorSpace::TransferFunction::Custom; + } + + colorspaceDPtr->trc[1] = colorspaceDPtr->trc[0]; + colorspaceDPtr->trc[2] = colorspaceDPtr->trc[0]; + } else { + colorspaceDPtr->trc[0] = rCurve; + colorspaceDPtr->trc[1] = gCurve; + colorspaceDPtr->trc[2] = bCurve; + colorspaceDPtr->transferFunction = QColorSpace::TransferFunction::Custom; + } + + // FIXME: try to parse the description.. + + if (!colorspaceDPtr->identifyColorSpace()) + colorspaceDPtr->id = QColorSpace::Unknown; + else + qCDebug(lcIcc) << "fromIccProfile: Named colorspace detected: " << colorSpace->colorSpaceId(); + + colorspaceDPtr->iccProfile = data; + + return true; +} + +} // namespace QIcc + +QT_END_NAMESPACE diff --git a/src/gui/painting/qicc_p.h b/src/gui/painting/qicc_p.h new file mode 100644 index 0000000000..c3220391f4 --- /dev/null +++ b/src/gui/painting/qicc_p.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QICC_P_H +#define QICC_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qbytearray.h> +#include <QtGui/qtguiglobal.h> + +QT_BEGIN_NAMESPACE + +class QColorSpace; + +namespace QIcc { + +Q_GUI_EXPORT bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace); +Q_GUI_EXPORT QByteArray toIccProfile(const QColorSpace &space); + +} + +QT_END_NAMESPACE + +#endif // QICC_P_H diff --git a/src/gui/painting/qpainter_p.h b/src/gui/painting/qpainter_p.h index 930180e9fa..9857a59070 100644 --- a/src/gui/painting/qpainter_p.h +++ b/src/gui/painting/qpainter_p.h @@ -54,6 +54,8 @@ #include <QtCore/qvarlengtharray.h> #include <QtGui/private/qtguiglobal_p.h> #include "QtGui/qbrush.h" +#include "QtGui/qcolorspace.h" +#include "QtGui/qcolortransform.h" #include "QtGui/qfont.h" #include "QtGui/qpen.h" #include "QtGui/qregion.h" diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp index 54fe857908..9d5ccc8a3d 100644 --- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp +++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp @@ -40,10 +40,14 @@ #include "qjpeghandler_p.h" #include <qimage.h> +#include <qcolorspace.h> +#include <qcolortransform.h> +#include <qdebug.h> #include <qvariant.h> #include <qvector.h> #include <qbuffer.h> #include <qmath.h> +#include <private/qicc_p.h> #include <private/qsimd_p.h> #include <private/qimage_p.h> // for qt_getImageText @@ -725,6 +729,7 @@ public: QRect clipRect; QString description; QStringList readTexts; + QByteArray iccProfile; struct jpeg_decompress_struct info; struct my_jpeg_source_mgr * iod_src; @@ -887,6 +892,7 @@ bool QJpegHandlerPrivate::readJpegHeader(QIODevice *device) if (!setjmp(err.setjmp_buffer)) { jpeg_save_markers(&info, JPEG_COM, 0xFFFF); jpeg_save_markers(&info, JPEG_APP0 + 1, 0xFFFF); // Exif uses APP1 marker + jpeg_save_markers(&info, JPEG_APP0 + 2, 0xFFFF); // ICC uses APP2 marker (void) jpeg_read_header(&info, TRUE); @@ -919,6 +925,10 @@ bool QJpegHandlerPrivate::readJpegHeader(QIODevice *device) readTexts.append(value); } else if (marker->marker == JPEG_APP0 + 1) { exifData.append((const char*)marker->data, marker->data_length); + } else if (marker->marker == JPEG_APP0 + 2) { + if (marker->data_length > 128 + 4 + 14 && strcmp((const char *)marker->data, "ICC_PROFILE") == 0) { + iccProfile.append((const char*)marker->data + 14, marker->data_length - 14); + } } } @@ -954,6 +964,9 @@ bool QJpegHandlerPrivate::read(QImage *image) for (int i = 0; i < readTexts.size()-1; i+=2) image->setText(readTexts.at(i), readTexts.at(i+1)); + if (!iccProfile.isEmpty()) + image->setColorSpace(QColorSpace::fromIccProfile(iccProfile)); + state = ReadingEnd; return true; } @@ -962,7 +975,6 @@ bool QJpegHandlerPrivate::read(QImage *image) } return false; - } Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_neon(quint32 *dst, const uchar *src, int len); diff --git a/tests/auto/gui/painting/painting.pro b/tests/auto/gui/painting/painting.pro index 831fffab30..26e84c1b15 100644 --- a/tests/auto/gui/painting/painting.pro +++ b/tests/auto/gui/painting/painting.pro @@ -3,6 +3,7 @@ SUBDIRS=\ qpainterpath \ qpainterpathstroker \ qcolor \ + qcolorspace \ qbrush \ qregion \ qpagelayout \ diff --git a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp index 72bad03a6a..46a2d73ece 100644 --- a/tests/auto/gui/painting/qcolor/tst_qcolor.cpp +++ b/tests/auto/gui/painting/qcolor/tst_qcolor.cpp @@ -33,7 +33,7 @@ #include <qcolor.h> #include <qdebug.h> -#include <private/qcolorprofile_p.h> +#include <private/qcolortrclut_p.h> #include <private/qdrawingprimitive_sse2_p.h> #include <qrgba64.h> @@ -1632,14 +1632,13 @@ void tst_QColor::qcolorprofile_data() QTest::newRow("gamma=1.7") << qreal(1.7) << 2; QTest::newRow("gamma=2.0") << qreal(2.0) << 8; QTest::newRow("gamma=2.31") << qreal(2.31) << 33; - QTest::newRow("SRgb") << qreal(0.0) << 7; } void tst_QColor::qcolorprofile() { QFETCH(qreal, gammaC); QFETCH(int, tolerance); - QColorProfile *cp = (gammaC == 0) ? QColorProfile::fromSRgb(): QColorProfile::fromGamma(gammaC); + QColorTrcLut *cp = QColorTrcLut::fromGamma(gammaC); // Test we are accurate for most values after converting through gamma-correction. int error = 0; diff --git a/tests/auto/gui/painting/qcolorspace/qcolorspace.pro b/tests/auto/gui/painting/qcolorspace/qcolorspace.pro new file mode 100644 index 0000000000..14bd699bf7 --- /dev/null +++ b/tests/auto/gui/painting/qcolorspace/qcolorspace.pro @@ -0,0 +1,9 @@ +CONFIG += testcase +QT += testlib gui-private core-private + +TARGET = tst_qcolorspace +SOURCES += tst_qcolorspace.cpp + +RESOURCES += $$files(resources/*) + +TESTDATA += resources/* diff --git a/tests/auto/gui/painting/qcolorspace/resources/ProPhoto.jpg b/tests/auto/gui/painting/qcolorspace/resources/ProPhoto.jpg new file mode 100644 index 0000000000000000000000000000000000000000..481d35ca8ec02d94537ab16c585ccee339d8d249 GIT binary patch literal 30900 zcmeFZcU%+Q(f}NK5evN|ReB4A9+2KadRIddAe01>&_x9)(mT=w=}46hc160N^r|8q zDGDNrKI*ptEYI_L?|a|x_x<<Xh0V^MnKS3ioS8Xg_w4tH@3Wv220HpWAR;0n&^zD{ z^!+v0Y3%@%3kamIF9M<jfk0HC<3z+DIsgg+&JzGk16<>PlZ}WBL<C$jfs_3Zz5&2O zL?rv^!~iUPNM8=XU;t(Su8qK{48TW#Yd3JBqDc4YM*vuZ1OzhCH#9Zj)-*LgV`{E$ zsc&j>n4%>wB_&0u<UaL}tFFHB8E&wIw3LJt2rMP7pd=-)Bqhr&Eu$m@R+5nhS)#nS z^)OgG1`PrUfU?65>YM>o?)o8|2f(~nf7My=5KaPwllm<kltcj{1xl9!%Se$V9mrA& z<Rv|XZv!w<3iW>N1^}2i<)ExF0?lFiO8_Q2OkV<Eij;$L$pF5ThcEzws1D&108D*I zzX{MMrx1ex6@dUnfKq;giEbS5`TiXQVlMn83#f=<zdnRKM29e;&4>Y*(7L+-Pom-j zdf*mB{2NU28%$b!Aj>yG{SVVo06qC{G!%z0fj{MM=~TbL)W5+rzroVQ#QXIj2Pz5% z$|C6b7y!!x>GS|BK@b2q2)r)?bx;GY)W8X}xQvn%L`hnP8)$b~StTijKc;m<6F{dm zj)UG&n(beKtRQmW<N{6tpSu80!j%~K1H6HlP!8dgk&>1N%S!KC-S2c90FH3~;|i9Q zkP?>%Y>?Z_i`zvKETI7C0AO)o*#uTZhj0s!ix}__f<WcK56Pjo5NbpI8_akJ6X=MD z5BSsoH^hf<G#h{b4$A$%@4x#pq3S@1-={&EAWCv_3UV?^3JMA;DoSb^hNCn`j?l2u z(I02vWIM^l$;QFK%`YLy%`3*o!676sEG8u_D=T|aP!XyCR*{gA1rwMMQBhIR9HC)3 zdXxps!@&doKOf&8f@mp0EkuB@ydYv)A`)7n?@vG{fqIewk%tg`4i6$?5>hg93Q8*K zBLG3u34*3bh)GGv$VdT;APNESAW~W~Iv#0ta(Xiu1+NbSI5fF{l24=V5u^FwJAN5w zY#0?a6Eh1do4_eSAz=|&h@8BFqLQYTwvMizzJZ0Mm9>qnojn|Zba8b<x#RG@e*OW0 zL07^fBBQQG$E2jDrDt5r%*rk-DlRE4E5BJ$-_Y39+|t^1`*Hh|j?S*`p5CG1k<qd7 ziOH$gbMp&}OUo;(Z??AI?|j((_-XGmK`w%vKaK;z{vj7FAQv$yDG4bBK`tU<f8Zpc zB_-pLCZ|(3qk#F)^MXSu88ng$>K;+?$(X-mbjA)+Gx5v57T6+)wlCR#CRo`2E6IKe z_DilQ5Df_t(0C-Yfb%79jzitmnrec^B|hf`4;?jB>o|K!ICL~N9l9caWX-YH{p5z_ zD-6Y_3VYW2k0Q#WiXRl_pYhg9NWQxZIsfu(Lmg<S?w-goSG~`lMd7}tn3|&edycF# zUHsW8tXzB}qe9oQk44>rG~D&(6-zuuIhJGQZajcpHg*W!ws>pS>(d*aszl|BF!{jd z-n(4wV{@&>VbMM0`Y@byu-oIqCBJ1)OxnltsU26vDu%ZCYUK^Sv3#E1(X6K3*K5We zuP4TY+Z=t%rxtMis%Ey69&dxnd;(awJfv$bL*0cXh~C<;xXVU4>fg<dwuLh~Etf_I z)}+_L%edpLak=!?t~k4G#TUlX2`+P$-R`FY%1c%)!E_U{IXC0SQZDl!?Kdfksk-hy z6Cy0dXmhG$@`~|U79t00B|{Su{f9eMWoGJ5*G$shC~LC}<XXARj-&CmS^-m{%x4B4 zpG>m$?$9vlvV6x_z}~3xLakcXNkOsSdInXTeTU08p6ouxJ{>*tv8qE5qTo#C3W1j$ z*EfFSn6jAVlU*B^n+*#x1>YL^z(d*LCVJc;=$K-$qx4NmkW~i*dx$WXMrGWvrUinv zT1>O<2<L`*$M$<OktEc*w?eUj&CD${B`46V(r?euXA^JPYdgN*I-$Q}gy#5I%9@uX zpo}~x{0x>e@v+FK%RaU5Mj4|4k2CqHB<Y*1?qJ1=TiwOZ?nNPQ?r_iDY+Z__Q6I_@ zH1L)FY(d=MTU^G-zh&)--+NnQ&61R2DmWBc{PGE{F#KUPOVzS(cl_1QHmK51ChU0g z)zq2nm8!-{7ay+C8vD$2W<;V!#@R(Kl*|CWU&79HW-F;8IA)EO>@K{-FTTj(stE&# z!hH#YpXARB7bI@;VJ;6+P;!sX8)vP+*5AQ7h!!y<il-P`<`^O`Ha%mpTk-2@Zc-${ z2!2GVWN>Qxf+x#4MO8h{A2-+)yATrR!^-frjM4iE(T(;lhLR)MLpQshz8@z~qsdDb ztDD^^<*xB(ml=%POXj69Z*YzA=CEMlIO86fZL}0)@<Gq&qC)vpDXDXzPmD$|t!wsm zGHb!5N?M!~!{DQ<0!IvEq)mvM>$+vB%@xYbrecZgI<#~l$|Fbh;QXtW$TjN)v`DM* zQmUV@=!#B^?a1SiTb0t&m)kmwD6KjWZ~T-{&+jkVR)s=lK3N#Xu*CJp_Ybu(pgl^5 zeAP~YqMBezahnA?%t~J7t6qh)ojS%YlP`Lf5gcqW0wLyGy2>6Ejqg%>SdbcJV{L4{ z0=S{OsLrPqzWQ3W-1#L+qfaj15hC4%l-}psZcV>=O^((<YdUB+?wpx{kNcqFhV{qZ zRCk}4r%Fk%NRA=*-VJFHea5&iBkwihGxv7t9!MwVrC;+tGkn$+`Ap$MhqcSIpbwrG z%Evn0lr@H_7#V6qjaQ-={hgcIkIq;MO{|$X1a6idp=08opSrEAMy*#~KfoI0NaSec zl2KNzlN!Xw#Dd5~o=9G^=z_^Ut2?t<^Z1!z>)m88PtO@YF&mKe_3^MKW2NJb{K<Fx z&1`jwU#uszn9$Z^Ec!QhrgPAUs~aB}wG%||DMh!WpC75tQdfA<Ty@S(iL1bC$)UIW z)4Gp?j*Wem36r004y#{wovVjjfqXjk!bjEgI^Wr9Es0O8{N_Qf6pRh<^Vy7%$7mLC z1~@aV;WFXgXK?y&wEC9l6mQB6yZ81v`giX=y0_-;5xwl!<6b_79cZV<<u$I@To_BL zvvq4dd&K-Q>%+<;NEwOQrUulF?qX%!hP})1c@p%+^lDGX^E-;~_V5*=eVQp>#Ag1A zEDE@;x}Ck&-~7^G)+(@SNL!IH*Qe)>jNPKKIBVBEbpf=~>KZ$pDA)t7P?K&?^E!{N zSY8KFZKi!{?53c3@f9noN0mWEWC0CG0dl1n-KFv_X%5RsqjBZ<tZBAu+O1R7(*`fy z3&RXKK%&z8)vt~e8dp6zM=CrZ!rv%YCK<>dBpHcs31i5Bz4xto_$h2?K)haIz6tL5 zs@<b3r5MfIdep)k#jgPMVA}J8a%n@}awb&Illk+~IJfoXpKvtoeD65eDu&Cpy7sc5 zxi=<eko{fHZrG7L{hJc_ZYM0oe0FE#!j0MYrm0qG5-++K=BmprQ4<@r_}Bm@c0Nk# z8)$wjhwCRzGs(2f65UrWcquxB2c(g9QZe?FyfX1nF*ZofzunyqTQ#{p#oan6&a7bn z6my*ay@<w>6rV=_nxcV72lJ?Fye%qxCE6JFR|E1Ke`T!;o7Y<1v#o@!l)un5H$DD| zdWw=S<1HwTvuW7Loedh!Wv&%o-bLK@)#6;hi?G~dmu;AXD^yaHnU__YOdjZ^a)^I@ zlc+f&+qZ_gkr6O>hI*-1<s7leV8bSRoumI>{M+qiO?M^3Jg%kqyGlIO7ldGQ>Tlf~ zj$gzF`Cq-%0D&^xx9Ep$&yUsP6Qf#WroNWGS?}Ni-{A6y2+=U_CCL>Yka41UDLMjC zcB?8%Pe1)=%EunpIiAdsV)EQoFG;tQPjLFe6N@-{Tcx|VW*%(j<NPbmO*Z7;lYtLI zO5kOh#4-kx{Qfoi)>r&=J%t8Dw!ziT4;2}!Vbsiu#6^(~3P`x9D@CZjM4Jak{_TW9 z5yzRQgWKB^D|Wnw7jj8ro(9g_sKjM=w2hSB_F1emTeZ>}TFlVEtyz9-6=#g!<9Ecm zH>mZxhZ~uIQOJA_*BIl{u6mKPn=W$=e_g|ciF_G|dtw!9OOoVce=gmzLn6?2sTRLH z<-mA_m(dw2I$Tpt-=lIY{gL~bDu0t3{xvh=XkU2GQ}5nXa~<r>4%J)*h9PZV2yP&} zN<NUWtnh4(mpY4o)isDfah}y<wSuZ#lT6FTROoTDQT~*X^SRbXo+94h%yXKur`<<Y zIJO*9puTcr;aMf5yJa0z=q9B2!!^4$e#i3@6KQ#ktIpjw!$1n94~QF<{N)y{>sGR% zy=&eo{@aPyF57;n`tpTSq}RItP4WbZBLmn8d?B^|$~bvrbv1nY-bC9+NL59rbc2n{ znKH$JEkB*syDfCz7Gt^JI^DZp>vmg1o8gMz%k-u7(`T->GNMP)NyuAgK3_Mv21#8( zx%&%b=8ntY*PjML>bzgNO(~6ORcM|-J;9CI7WSg*Pcc<DlIlKy*gbkX)NHim<3wFf zFX&VK_1GXS%@b^pwZP*duL;$r!O7&KDZ6uJ^nyLekpP7+8}}okYtq@XOQ37FxaAq` z=P+QSgmikgs}^RuT4jFPGEDpnOT|qs?<rl%5tT|8^6yT#7r&AS*Ou@yR;V7eQK<MR zJsU>mmcUdJ_UxH?R|!tTWZ7{pjYj&^bN9RTOtV&NYcQH9PLX8CahGTgr8=>VkKOv! zt$eh#e2fmJEdq917QF^itc5099DFFAk13&4pKbEqfTM0FE#LFI_V!EUa+5c+=Y@~U z_b`|3Wu6TPRA?b9<lHq-;p3$Nrya6MEQ}el*<8(v_b})(?yY`%>PlhGh7KH4>Rs_i z+}1nvR3|vzJ6g?tgkIo8jEl~UfV{fP3d(QvQD^dy-~Cvy)@9}M#a)q)-^bbvXMXj) zMZfbN8fMq?o+$6AJD(RjZtND1IQ#hzjMW^E_1cf$6)kLpv^~=(&5#t{!&x}Y=$xeE z5=qWMXvdp>v2`W2ro9rB(_3iJrA^P1mK3m|)x0LUK;75eI@6v#-NJ`<7Z9Y^>(FQY z$mE$zvOR|1@+80QP;APrpolS8MnB`XP7cZ%5PACS$h9+2547v{24nDCJ>SEui%lic zHZ1Ts>YJ54tV5_%7RR$4m+xtHc?6qBmca__W34-ezM_uHCN)ovd>L+zyLMaY%tbSs z^`%KP?qvf*#?_$F%xKF;j9r|plU6Tm%WkHMz7Dd2gh#MeE1r-ZP%I6}nmJFs;>-Sg zDPCDLqgqavxZ3rck?LTVdxm8;*`t%`NRzH5_*kVcti{V9sQCt8cugR08`ZgBCg_@` zb@IZsf(|6d(mfRjgfd?_q3Vt04nwv<-pkQtGzH_}>Nlp~@^%GouJmyhIc#TINxkCf zrphumf95B0)MYhF<5tJ7%r*J&NBQ5VMr?~c7YWT*cl_|?3#4E?@=;sg%ZcTUyF9FX z!A*{sV_lx$h^srNYUOV9?vYx8-xz&04tz^1%r~AuoyIxD8$)&lv{Pwt^{cd9>J0M& zTLOF56;SRN_)11;uR9z2s^@V{Q@1C+)-N`-g0EkquJkVl%dy8S@8Z&`!b*9xSw2c_ zgd)C4eBf;SaxyQn>FvC>S1!)hyzCkeXXQwI8GVZWW1X~`vwT-N%t;tlT=*8DLYTWD zq7W{pqa0~X5|eU{HtOhCl8^!0R=V?J>&6ee3>IpdlyAL#A$$2))4;1ZgZ7s#1(%Y> zjum_doupVZGsLd_B_IY1tu&`Q-EVa=sMa9A)q1yj;e)O?q)1p##)yK$r8p>x#l7iP z-a=cUO5o+s7V4E5yVG;C$ed6^Sc#w8>Nl@xq;7XpNT2YO_Ssu4F})p@adL_k@)m+Q z+u2!<g&m6*1#h}grp2|$&Z|h}vh}5WC~_38&{?^&?ID5g%)Qs2Q+c)cTt?k;%X<!= zM-cR=R&7c^<vQ<4QKAhe%klxAWgRQF#M`~MJ_WI!=NZ)J8)^%2XgBK;7P_McdG$!a z_Lfpi`)EmD>bR_V#a`SR?EE~6FRQ-JHj|uFw5I-kB;{r9^VCaIChgTa-vYiAkKa_P zPlL9nTZGHXHyyPq-Gj4hBTq`#2lkY2Slc-)RU<+*;>MHZPkr4Oxb0&cT&k~c>Nz~$ zm|@Y~fu5c!E@OE%RGRm6y7Yr)2Zl!6PPEw2$D}`VwZtEu-A0xxjrHlUX?=h<O*=ov z*;y2@4Z2HW^+9Q9COiG+u&&FHM$&nBi4WVtWGjzp&}2lh6bX-F2hKh%w1$1n;Y_;@ zy~^#0o0fi1USl<roTY$-w{XXA4Fym7mh9yyztO*JS@ddqG;57qe{hEnGG|_GW{6vH z)i|b<>th|?dy6N^JxkTMa8r@VR66SD^I@Kl#C4BR^j6!FV4vvm9-a9s_ERA*U)S9p z3weArv_l&soq*&XqmRioel2g}YRAwD^*DLvJo=bOcP{CRywS{U*`Yd)F@||Blk5+& zw*<vRk#pZc>J(EIwzev9oSkIuFBu}AUKwV*Zdb;iEQ^ozT+U&LslXa*^0)I}>9A%# zr%L9hBVLr}ODD^HwNL1XlTNz(edlW@MaEpx+14!*vnnf_n~xlWde{dTq+2A{Hia|Z zNrMRM$aMx(fjKijKt`J51s?T=QB;HHjSUrclgKFq$4Xh)hWwIEX^lN`7d2Z~&p>ku zx~nzXm-uc}L~dzrK!&!vSXR1yhXv{)wG;W-BKL}|$!z1SbD3!~J1Hv~I#U$IJnkIT zf1EE0zRCaM@xbDOdR*>^zqdZmm(r?f<D<7{&l6c2@6cU&p8a0*d>O0a>D5SHuw%Vq zU^OSZe~DgwVHqEJQ;ofxiWRFk$uZ`b7|07n?9-S=iMB$Q<{P*4{1T2rA=a7eCNgHK zsba(4s`i7!_=x7)HrH}(JgpcdTyVNmQ(c;ckNEZY(@j;IT+Q0zv~;vhIGMPPk&6<C z49!TZ`K#CzQP;V5_n&%MdZF%ZPx<Rxb}kf*g>X)hjfiI3W`%-#6bf!G=d>3b=qTK0 z-y&YfxQ^YUcj8rcrm#5cUmihsWzA7IxIfP*JqMa^*nF$4E<@LjKkJ&>z4I|qtCq#@ zB4);T16c$!C$3)Ugc`f92uL=8##5z3O+VK?!c_bBc%H(@T&VA${5k?<2p*>k7pT;& zcw@qLPP6X=rxK^s5#_eO#-WZ9pqh&zs%|YRZbMp%GertDWu4@P_w=`DDT_FciOLw= zxmVYm!eVEjCuKDbp{-BG-Aw`CNK>JS3naN`A>LG3%*EMuKVsSTu_vp-Tif?28|gZB zoQ97n7EwAjO)D_JK4FY!W4zs4EJfb7vhyV}O{B9U(bIb7q{q<QD-lNfm=UCcnu~&! zw|~}1EFwYmh7GjVq&Uz$prXq@PxqlBMTy0|_xVfc50S?uZwlk|*KNi|wcWDTtNFsu z7SGz~mVPplz3BTivrENBsU+oedpYC*rt;~anCBkjx=xg+VsVbYyzH8m&3s|@OeB&n zVqNrl%Y7<litLQu*GpLwd1OJ!C{eyZ@niiTM1u`4bn7;Ge|~k9>CJNQ)vYz7@mkIk z#3rJNDL9~m4eBl4sJkYTP-e|>1bwfPXEfU!<+a(;6}NknT*k5lkJmp{qj)OdT1<jr z)`F*m?!B{-jJ~9Exz8(F+|85o#e3g9-UcC@Jv7)6oFa@o+NKOwpzabF7Jlf4M%*aY z@7+;jNROIG?nuU1q<V^Id)Jgq+oaBhZNkW6*t{ZScp|`cqvu`^*W>zXPZlE%N#Z;G z)NmFnzFPNJB-&PvLyB8C{AfYjGsggARVeo9+KLDGi(%4bXU(%YA?_}Tr9>5LFjDJD zZ<(045sa+w@hTspKl;vW-6=0?_U1TG@4$vT&L>#SCDs~>j`KPC^td)_Ri9y2%B!!2 zJ3H0xD>YF{FBd11=lX^cXpef=cMmDLK%NIA=$EwdcYgY8qoDpwk+FyLnQ-&u+HHxV z5>!2V&ZjAJn+VQ+w^tXmldGp*88_%zMIO1e)LJX-pCZ%JjQXPM{(jNkx*odnJa$Yc zbZj|;IOXzyi6L8QN+17PYHqHjgW}C=p&jsxWtukDN*)X;y^G@mF>V=RZ5G4ON+oab zQwq{8OD~S%PZW_X5SNWfxUx>bhTX`8A${JJt`za+Q#rDtew&}>OO&73_$_rgOG$)? zrnKG75H_`v?MCEn!&r{;wNT$cWPf-!xDb&DzPq>3<CVaFt{PAOI1ybob&Cc(-BWLg z@EMV+PS0$r|0?Rq*Wk9?t}K_8>_g5nSD;VLVYNr;tiEPhoVYaCoUv@7bG<m8d#%F@ zwXsNSS`9<>#kn+(?g}#&+Zjl7`rQ*wu5%o@lKo<2`l;ubvX1R#a{X1ik(mLv?7{91 zuhm_7`?x|;+iV>bA4~jowl|-@i6YHQp7HN8ZYr6imVI*7o1|V^h`R>Wuew)ZsNU9E z$#F4fHn@A@JIJjy!V>)ul6nb+K)+<SV_Ba~JsS)8wiYsO+*UH5Z?K5jS);r#<QRpv z!5A!7n%AtRYq+1IZ9f-X&4ECg`WQPD)*%+G*S+~$s2jlb$L;Tg6x%vI3U{hbpsXrN zG#he-mx#~T_1QXx6t0oJ6Ri#{N>JHyRLOYn_OZkCY4|%2!!H^xr-@rsNBiPq%SVdp zN|_4vZ=(H`@PpkfG_H`5)f3<Ljw#fzKYrdLal{qJwzH;eMoN_EXj2^;)li(g40kV+ zckbVK+(q=Tr^fxW#}%TzHuName3Vyr!WN`7E?@a6h0<$6H*BKj)06pdRysTNB^mw3 zx`os;GmzXs_LSDx2ebo2s{9J7A5tYMW$Fa_<%NpQT8*qrY^-lmeJKS-9y%?8B3EkN zORqIFfQpxz#b&c@-}4AU<4tAHhV6=I2CPk8|5o>|GAxK%s5WOCiUH3k8PBu}pWyrY z+J?S8`wIM{yUe$V!kE=~N?GSO-RXZRLo28x1QP^4EIvp_%ow}UgT<$N=f9Mn{_0kk zTW(>n%Qy9`weR@xnNKmZ{0@w2_q$5`>|LW|pHUWHV^%NCyl~%*bt<I1u;SRrj`X#A z78dFEA2g<($<}v%S^QTUM|PNy&H6GQY0Bvx1~dEF{QD?t(d;Ei-+FGSUUjxmO&eN6 zTwN-fsNe(Lv(Rjzf}SFs7m)@potJLJ5rOHSvk8?!oh8ZwXFu3MS{E^Q*p?Zm&&})& zH&cm_G1%m2YCHSXOyxd^hRDTfMR$@pAGL+l#XoXU>(FMXXz_VX=MCPh>Hcz;Z3VC3 zItnAR6%pFY9Mr~|2yfzhiwhg+_QY;D$K@d^f|BhtW&^*(NDNLhm|1Y*={Eh&GLKfV zLF=DbTS8CQ)XzJ%$kjN*lb}Z#YzlN53rEbltkWFYmaet5$hXvTD2k_!%(Y#2!obD& zNfKJ!g=%$5>^xl;aJ@z;MA<{JrpL$_%o9q6VuG{%vfX(oNFaAS=yVhdW5xunQtVHD zp9G#DpA>b&<Gqz6CDAwu7y{#rlz?NrBm-dHlF|}Vk{}he0B;!F1BvH$M!KTVP~Nw9 z9`JIb5Kvwlh_RHhw<gjJr5A)nS_GL`!h<~EiU?jcRc@64r2sE)FC-qu9pL4O#wi6r zdH0zs0Wcw1l9zj*1n&XmwFMptYhtiSZdnP!b2;FFwjY=m;DJTBD4A>N9C85epuC4w z_4oIe@RyOmU|l7p6%`dFrNEM4usA>=jtfNNVFBW39N!NPT1Xrmi}J>!FlcT9N0>9l z7Z2qH%HOXTfPrfV011bz3HSSqad?EJK5!!o2m%mDf~BMs#HGOEU`0aR4}|jaHa7m5 z^N;%T^7=`Q!)yEfD(8>XILkn9q@+0#hw;V2k=lMpG@kEAVK}@w@|OnwgX{qL&&=MQ zzPR5j>Wf1XlJ*7lM7T%-GVV9`kHQF#>3`A_wC#%W^4_N=Q2wBT`2x-QC+k51?<DN= z11Nq{!?Ay>!Y^Bc!@Q7Km^c>ZFOEav@hG$_?r)Vrz<-wF?Thu?uLc4xiS$Hz0SY3} zO8+dx+YN)q;M_3YKePNzQ$NvvD*%w`&*VS6fFLl?)Jj?yxG$kheJv<2kRpLVA(Z5t zA@a`B5Tv*>9O)u1i%^sihe;t7#T8|oT@Z>=5C}wC>PLQkG!73#!;wGoqk#M}a9OYv zOi@8x0S1u~msNzwiz~<>A>v3mX(>e+gp{1TG~`EqQ!EPbL73<7_0ZJTkdc<tk<pfw zQ<T<HkktfBYir6$%gcjx6y;<T<aoIWjj5!5Mjy%xmH?`<e|yFghIheWy`a2CD70_D zVJh(U1=0c!Bd9|fA|oX)C8H=WBclNP{m5sH#Nq%?BCsO7!@<i9w6K!8w>K6OfbxRj zkvf2ea9XGXF##$mDM@LmLo$6Ym@Cr6*UK4+1uzP7(lQ6xjgV--GXCc?`CnLqzNBU4 ze@j5SU<g?V+_`}lO$ZmT!q49WLJK4o1@rt-;NiOgyxf2tDye&7kuXFcP;pNb5{PA% zSYPBJ#utw<0tCUrJT=v!yg=3W>48)mHxwTEQ+{a~Ss7Uc1%hk@0u4_fNaBF^8^AyF zXn6V}^?Z?kySISheX%e?Ec%(Oxo`bvuoxGVCqS%D2*KPyBcKs5EaHH<rY8)G!Uz71 zyC%jHgEhgRa7c3`!WVwP5)4=hp*DX&Y5_qP<q74599H-bBo<y64Bicm!~w1Giwup& z!f^P1l#TX7V)2$3T`VjR2Zs^rtpoGK9jZ_Z>4F8E7^#azBGKwz7+*9H_702v8xGKp z9tz4U_b+fpKoiUU19!$3>+OmB7fcV3hg{|Vm=iz}*b?lSpeQY*8!YHo6KMx{V{pD$ z<e{_@KUx=%6ZKC?_NDv1efJao(7<{yoF<kKkbYAUkY;fh>V7vqJ(R1PCvf8bZb?8X z>IipV9G(z+)O~zmKh^m+48h?3jM=Z+pHaquPXb-$pOL0m7|@P?#vLg8&p5y&|BSFh zdU|5~f8q$9Zwy2G0uc=e8Nh2_fMfilZ3!fY&Y_KlITK9nu<d@s0J`)A6ii3~3=HP$ ziN_tZuaU185HEp<`!DqO2mIf(_y_#ob@>N^e`@p(B>&LsA1MBz-9J$LuH!$T|EcL8 zia2m`z&(HJ@eB+LgdjW?1=oUMJpkW7)bFqKpJr(RgiFAe<qyNmA1MBm-DuyU|G?K6 zg#cdkLmqPd5psTUwQvIl3I2!ZAF=J9=-)~N`X+BA5DNW}>ifX2B7b3kmkUur7{KCz zSolNGUs!Vt9*F$_hS0SU0>qhLIE#Zox8I%p17+n6bj)tQqTFw}fDQwX0&@N;4THlI z;(;~F6%B-df5tMv*5N<|{@KsSNdVm*p*Wzue~&i6?H^*zzfJlVKJY8gFM_{0!Ji2J z?gf9M_@^8EiRK@E@F$XgIKrPue)ohw;s4<Z2UcZ?`mI+wNcwxw1=6tINc4|>^N0Bz zCTk;Hk;X8b$M24Gh%$#EP=wL8C@_CIXu5sGLBINw4Z)KvF=!ya2F#NXp?(_3zP%ry zemdUoE&nI{FR}l`1}Go!qkqBU0Qm<7mPjveU>F1pSb)08D*osT4-_XV4L*<!s3=m? z7wbo;zZf_04~9VYfBu0!w5Wea^24V79gPVPs`kgMNEr4XB@j>t9XBwf{h#PF)`z|N zzhi$u^dHpqfbc)5@d4$5jsCl$|1E_v%-aHwMWS8tZa*9NXNXXgfJjImD8m}%40PGQ z8PmUrGW%oMpN6N7<F)|iO$RLYQNLUP0awxi<_Rz$xB&xvSEQu7H`0}t`{zVTNec*= zn!sopPw4Xj70ZZALByqHEPuS<yFZ8mCQC{OL<I8xfDVJT#9)A+`SX48{V9-=F))fn z!0@o2T;#;1fPb*1w5$?D0eFF2obWz5;C6%pjWGz6OW^-T3M@1nt^p_+Vc`2?^FwhC zmmoA?u95&K`LC(|i2;=9kN#hB|DgGiR~?J@$6!57v8K-MKp*xma{o`NANkFJ)fpTf z8>o-?7g_&Ca4?<K+aGiV9%isW`W!-@DDM5m3MJU#yaEUFLjrS=gG9I+VNeJ(wj^O8 zhtL{7FsMIFZ>8jsaxfVgxVRi#K~@}iTUkn6K~WYi4nYDFV?|jh8F?3Aih95qhjGFC z!>~wo!jSaGROrl)89n#GOo`hZ=Fh!v^4vnkFgOs#f%(4h4;KDzNW$b)O8Pg$kc9wS z3=R#0(2|5zp#LEv0+=lRCZzYlpa|&wp}cU+{&WY4;C8`cytohC09a!}d0^1uXrv1_ z9&?yT@C`BUeQgmE(MW%8&qJHy{g);G3+4Wh=ub-h&(<9NBc<*S&afCjE;&LN`A>EF zyR-d&DH&Ww9xN{>3l>Kp6cxo~;YeA+x{9p099UivB88Naad81c-5({>1(vAxx0Y}V z?XPM4!zM(fz=X)K@5%%VI52m@$``P(^UD(s?zIlAL5I-Z`wMSMh~Jie{`V!9gFJs~ zy8qN4fYm!CV5s_kU+y6YNLbrb+Fx$5@ZDeH!2a^_eFglH;8)^)0L1+3Ouz8^c{DNJ zf%^ksQ-3t_kGcK_#eO~`6dahb{kfdqa6lIXCv-5s6aI8#)n7Y?R3r~P8^G;Dhb{cK z?E8q{mV|%M0_)5K@aM9%D))bn|7zgB8u+gU{;PriYT&;b`2U{<em(d`qJhbdKk!)l z`vwUAYdRtWY++W=&^IRRbp#Gu4kCLH3A=zU2k{vY^{-J02eCYe5}1%E0FTpTIfzyF zZ)Bt((lQ*xYM>)h^1zfxK@`|4EyV$BW+euZauBP4j!4VMfPvX8;qrZs<gUJ^=D9QG zraJmY+Q8OSU>j<cp{B6~F|gm*3wS<buB*Wf?2_cB7yx#A69K!wl|YOzIL_PHLdTL& zHA7P^b#qf=V*>o^*c~HmI|YG;MG5#{>HiT#1NX+_fjyoK0JR<hc*G9CjsSecAMZ^_ zp9NqBtfjdo0Pg_sG1uQ<=igu~P;o$Pf({v64`3Do?0f)=5nzND8UfIp24FP83qgQy z0q~%g7Y2Yy!U0$aj|>3H1%ZB!G`WS~!ra=xqbn~Mn%fYAfO!Bf8F+ca(1BvygqH@y zxM7~2-21~;95)t;Ljr492no=EECf!Vqrh71esgmJ3f@lvevW<n4mtzEf-u0Z8}N$< zPHvDnNEftE^2a<s^8Tk+LR%it{%j*LIIzZcn4gHKA27F{G*4xL?f>@(xL;|!xgb!p z>fh5S_xCIV?JfSBjO2v2H#}qvq5y<51et=gK<dC1IR1|QLH2*W{#KqKFt0%Z3t4a^ zx2Z4Q+ZWGmj0BcTy?_hh34{>AOoh3*f0Q5uRLC5J1i1hw7C6x$IPl92RM8jEy!ZYu zH^>-BLx51gofm*3+~EOg6hJEk<TeFTj6uQxW}of<u?9bC^3Usm?GaMR0WZA1zlHeL zGv&+wq}$)tP5kp90U#1m;1}3AO-eY($jSB(VB<Fhu<x6kii(;V*uVYvV}DyW2?+@q zDH#<xIn_~WD(a)hj{(Q=<NJh%7n*~+zvumV_x&+pTX#9=4G9sjqxr|SZeUA1@qXoh zR-B9+*y&76Ndy8mN3#QahzZ!ANDv7r5iuEvoZ|c84&xIffcQjjkJ<+Dug={9i`Df% zuVWK1yvvg=&f0X7>|%n~=n`tm+Wz)?`2<Bos>Y03@deX?&H0)!F`Kf@64XuTN?gYS z)3arU`t~*1(54##@!L_a8E?8M+f~+md94ez4!XV&`1W+__T4+d)(_N&MDHX3yGc<U zVV&1w-*8{ydE;y^nV%3edc@bsO}pSEbJ);eQ9^kuXI^7Te~r<D)EU!@c}wrfs=H2S zWtKW`GQa5ZdCmFcs2WdGFyC`??o|%f&W{6odAVLwrns0_l|IDw_vROG+BdyvzTES4 zK&8QC`F386OTLlQV<mTg+zacLOGOt$yFM5jGQ^S?Qmu^4QPZ?zmPcF^<}REw$mD2x zl8vF+@vr)j{h`F7Tze*#>7>&Of9)C728Uu@BTJqe_fUQx-=Riz4K~Csjx|5FW3jth z2yL1j^)j>Gbhmo)VLjqzbx^~J{@{cJ52Ids+^H8GulxsA=A$~Iv=U05l~rz+ele7* zExH}uzg6|*Vbe9s$sIlR_$!zvL@j1{g-qkgqke{3@9ad}sr{9OlkSQP+kbXbK5Lsc zcugLAB;IGHq^Okq(edZTu8Zv8jy$dL>WH%B&~WOml?Ir$^&`cC<tQ=Vc}wV>q29(R zrYQrO-r?AhM9A%JbWwOU1$~nd2hH=VG_d8W<yz&0^r8p`<D|CT@FC5D^4hx0V@-3- z&L2O|FQ_)Z;eNfTci#QB?X8HX_h;(QSM)dP44%`}eX}veipdVGCPs~W_$*MSgufYB z$h*=Z)Rz9aq?|94T}er~KzKaTS;J+e$9iX{sJrZH)B6|Wvn=9V8YniK6T?+LE<06T zkL;<+Ws5J1Dg_Zun-*SXCGHP!>z(d^N`{{vY_EP{E&hV4V)-+>;^z|3XhrJ!NTAK@ z^n`*EgaD%Cajs$U*({3Fs}NU@zCae(^EaG!rB8MQJfvAaD9}3g*#~}Bz?8ickyvPl zGW)M&AoBvccb-zM+Lv_GTz^u$x+KF_<dVSyqYblcvgw92o4IT1$(;Ub7dhI(v6of< zcuCdoIb~=O*#c~wY3Dwre#TPp4zBRC=^NAw8=Y-7($VvmdAW`$uWn_(Z$gwrW||1O zwH<pSM#l5BlW~T|?61{5X%*ZzmjdD<!&sgtZ2`|@y&Is3l8EM!$&h;_Y45*Xb*_2d z`uMs9EM<*IO;;|}_<8l!no+u=)ADvb@;WT6-x8!j@@LX3)D0bs<p$@gsx)4>Lm&1r zQ{Ec3fbQ5$(ZwBq>~?13$w=HxlYzmS*qw;Dx6A8XHsi}vieslSgMMkUxn_gml{fCC z1?p<ni$pN{3^==LNu@MQ(aX)v%&&o~&Z8_STy9Uk$}{g2HMR;Y8gw0o$^>1$1mB4X zydN48^4_#?`L;gdOJ?yn`dHD@*=PQRIf{vaK{r1eSP9WYS38bV<aKXAF3RhT&*c?J z>Csj`eIq({dAFW1_e_J$%SQ6+&X+ke>HE9S^!3}lMSOY|oI9N=TOV~c^=gKQ;T+#Z zSc1fW;>y-ab6!XJZe3LaF}&Br$|BSJgOc72=_I=>X?z8&>70XN!uFGGgP`!p?b!s= z9Fp|>6ROX9ckBZz7e~&rJoa!-CU=UqZaywIl&~msZ&40Ry8ANJFkGQXz<Qmg!68&! z*gZ<Qi$6<q?<jG2zCo~>KyQoP5Eqs8=KOphdgY8{u(Hgs8=VTX^4aQ#n{CfKZB80T zCDbMi*4C7rS^?g%86b<>3*r}JT9O4KB=v<HvD1e5k{wC<#_5LZRbNb{76fEGQdvYv z(oI=!J&zPO?F)MQ5MDkvBnNRc_VMP51u3nlsNH}>*_=M5=`=Gw@Q^X0{pO>4;e~qL zD+^aqj~_NLrv<&g7<GEb_I~<~YJj4vFi%}?x>3l-+x^wdQIng^ZD>JA-H9?Erpay> z^_>@ZW=EHl1u651Oj_Q2;Y1rD;sN;l8!rigf<O`$5&e?;ud8#aJr?&OKGt=(-4<4K z;fm?YS_8TQp%cLOQHY6w6X+23`vYPS5zvd#($VvfpJ3qSlV;>r=LZA*0wsVaA|n>% zy>BS7Wva~A$XnV+$=!c!zK5tbqu1za3`Z*6UR>VLo@d^asC(d^_#W6x|BJs)b92sw zwvW!#Zg5X6&+VQ~aFZ7+?H%eEEQ8!%_P0zbjf}D{o#aWKK<u(!h}0EX*SaVmDKz|r z7->zHJKL$n=X#PpcK%#Q!X5ooBmENo#lFd$UjHHg>BR7DrFDVsj2D3)#fx_Nzl~Oy zf;j{pyW7^6Q%K}#hIrlU@WL9cJ}_B*;bXe~w6#VwhQ}oTgJ45VnLxy2#!34)M)FV_ zfgpt#=?<M<gXeUglFM$a=iR?%&b`ZI`nK5c>q)O*dO?$7jbke?FH+~eV`iH6i(z$8 z?=)t|h27$S0%eJg?H+yVY=K8C0g@BdUdkTR*}PM8CR^V@x?0g=-v+O)<m+)-H_j=r z9TmQGQV*WDsKEH;)`Yn^?>ROrf$E~<7hZ;fk;^<59mXOT0+iS?d$PMqHl=JM1CAVx zN3l70$7Hqj*k|dzO^h{7NVFJ~(xn9_EAJ&BbQ}3^S=n#Q2W)+)S+1tP-jF<hZG-VS zQShxzqvI#?iG)-#b3lbprW)WRE0OVbJ1=>PdAjC!??iSj5*IDQGemY<7rLr=BjPO! zSQV`(qb~EoT<dDU9)7^cnQU@;GCs&}THQl99f#sy`YS1A_>Paj8{U}ex`rlCH7=$& zOHo8a*Ep9$MDAvg$8dXQleLOXMRugBW5(G*>zgXijt1<Gx!Z^;+8IyHBxGy&^5-~` zcB5h=%^S2u<?F;Q#4(Apvot^N+zjIke*E?grAt?nYnhmUtDv`1&45WUui)_QQ(w#~ zh6b>d!V*j+X)j(!^wZFY89&T3rBkFIyJG0cmj&(J%uT&bH#{C6BNTCM6+ATeM%3n0 zI7#iUB2{Fcq69~7R>z6hNa5Blm$O=%@#d=fK&u$~u=sE%CVK~TJX=kZ{LJ|sRAP9F z@;EBTQ!LZQzUr*qUl=2LovlRX<FRvk_;~Bj){8Au0><A#GPi{<(OlLRIPa1&b7d5g z5u+^QufI`ZcodROQ95TD%fg`mW{DWqcsh+>kBc<%l6?W=_~xGXTtTVrbw8E7{<png zn-JqK=a$cocO=^`)pJIk;um3|wkf!bdJ>{$UHP$#{z5y0Uw1OA@)*0$?lCvb<w{z2 z1?1fJ*Q~oD`Q<$b_BSj3BWI`09x$3TCemM89Z=|621^HyvT+-VMqf^oeau{Y;XJ!M z;@0ix>3O}vqQ=pJcx~raRr_`Z2VXR+VmBw2=#$kcB&+D#))yKo1p>8V6_y(o6O^DT zuf@zXtk;w}<!qzG$AyJcCeOBJrtT_*bc&lWWz}lDtCW-$fh;Visq#$ZJ(5B4hWUI| zXpwgH5gEoE!G2TQt+J0aB?Z1<VH0SOi=ni4PP)$%vqHwHgR47vqMG4)l-X0);-?Sz zy~MWbp0jTBoq*U@+rIUW)^vyqEWH?fj_v8Y7lLmZ%$~qfqiwyQ4oBH|gXzXPSJ&0F z=nOWubXArU!$(dJWXF5cL}Y#uKS>leDRcdik4N>bCfHzFcx&t}vq+7wx+m!OM&z85 ztW;^)2^`mx_@+8%^7?jc1k&@)+=Dt^NHU)4Upym6rIs2d-F<eGdH5cC<Lj`-LUH?L zzCM>zjAUhjrK+7QgVz3L8r-3SEK&_BiT2DJ9X6K>A81i-%xc!CQ}1reJ#n9q(7C5( zw}-%Gx~Ff*sf?P@D?V<@wy>z_r9qwv!_ezG71zqDa0zo*T2n^GHjvw!SRA>-pxYdk znl&$ZG*It`*@WvkzIuaO4M*Mh1Y#54dd)}IUn@~~5K1E2deubv;`Q^U30cfCj<Q*4 z;2y`K+@)9^c-Vy}o9vU8sqYL6am=oT5uf5;H72NrKqKn1>KF}JO8ZAd7qP??95f*m z93v8P`mHdUWh<W5BYx`7B-3jhT|aQ#HI+Y~gmArn0a<FlFmK+&)A>^NgV-3mihw1Q z6WhLY<B3L5B$wYM)`o_18o2B2f%hTlr?_4jNsV_xBS|M+admF;@lBA3i{bn;BGI1% zw(g=A&Qp(pnaac>vU=u-)91U|paz<3Z=x>&-HHe>7Xc37!%?Kb2aEO(!snN0fsaO! zouKFDRcDX_o5{d@PVaXtK-Z&2^qIlWCcfUbD&32X?`)4nL2b#U*KvOE`Sl2Ujw3$J zh9@fGnQaCUvR`-H&NU^*Z3gM66?RDU-8;p$axwGcTdNB(b+ptepOtp!8&0Lkx((J& z)^g$AMXfgT2O&?=t^4y#HpG1F<Q~xFIX<1(^o^?KJIGbziu9IazKghr_Gr@0!e(Q) z$yztVXsfxrCzuuF%Ofh^o_I_;kqYZogtflYXh4(=viceH=iZOWM{1eXhNK{)8}09W zUfZ@ID|(m}?}NN|Qmk3qK+6M}Jd6D-y~abAi!$u-IuW(d!s&L+C|~E4nqaTy>spGN zW;ZujGLMZ<d}Wk198A&vmL>FwOYHf40mBrQA@1U&{WJ%6f=06cjF0F}k1<|NEB|%M zj$yL3*z5<M1(ENdP?|frel}DKUhC-@R>O*#eFBtrv$1R1R_nbTv2KMWbk@}U8QNfc zM^?b4L7~-^@J0<+KI(z)9$xdwdP#V#E6LE()OwJrj+5Ypofs)guE})qF1>b>Vuzc7 z0txvkae_4wn$>>7OoqwdL8N<BZgoi;DV-*Q6=y2*8(oB1hDQ3ogEX9L5$<z*+R@It zF}U3CAd<XU=fPV39&4eMJEi9bw+)f0^Rwv*XZ243yJ-0g^qPEJ!A|Kr-QPj<V<mT> zBM~xm4$+oo)xkcp&l0R9cPwHlb>T6XqJ*TL9gmP}x}G~LTcKX@b%uyI6sG7=Dlcd5 zu~XmLM<4X<%pqFAIe|wS`E(hapT3%X8Es&G?XyDj1yiSl`?0i%qZg<6;g^z9hrqOs zY`hnZaw8mRD(~C9U3s#z=cqfFvTYT$^+`1O`C`!r${G_=*S`9`)<R}K^IgXrd#$4K zRQeI-dbrRVWWC@ton}Z1)CB7@B*1hx>E=^gZ3ROY0e8x@q;;(Y9h_vn-d-QPFejki z17UQDSn{1w)D|m~XYBmsd%2Eg@qAYKnh0GN9ezQs!Lw|aZyMFK7Ti2W&u92oKAZNQ zbT#wx_9{nK(8M^CjapZ;c;CaUq|dAdGZgF5x@LN3c;yR>nfuq<N9GWtg&tZt(qFcf z84R&@G?C}<`C%L1v==5SbgaeLCTGJI!gqSb7wJ!huuG3mnP^@^N}cP;S8;jP#P@+R zL$5en%qjDux9c<3)B>aXQFL+!f<2NweTef)Ps?+S(}U76hV9^bzFL716gDv|2jBNO zSh`*TZ*obj@v7OR;=5?&#N?iow$?30h2y6@E3y2IqHLUDUP%ja!RHq0MYQUI#lz_~ z@~OA^<5@kI2kU*tJ>zn=O?tFLimIFKgguNVwP)<q%;NMB@3k^IDC#7l=)<(>_@lLE zHHft+#jm;3%ADF`Y1y*pGW4`q>1(;TYx`HAaABADH!{kL`o#}kUrj5XUu2rI`pVRE z%Hgj#tJb45anJa>?|~)Vk|`#;%_kk3cQllA%T1$`C1R%exVlc+>GI5<q!+FH0;xq= zmMnCH^Kix8X;k#eQZ*9(dVffZTVW-uVEPf0@q^aR9y6!HHc{A=n%?~E72oN}BV&o? zcRX`<bx6;nIH{FYX+O*wo;C6L*5!GrUePQ@te%PIk+55Wis0Gen2Jv?A5esz2oexa z(c$3hYXB=X)RHwULwU0UHQmA+uPz91^&z*DR(iv8RxJB29!nNx>`JQZI7hEb7<v<8 zBw_FkEF1lbk+h^I=y=Ga>3O-;`M?Z}X0ZJTNlb{4kFJo*J?ipgQOGqpb&NOE(f?eA zQ5OAl=o25dX<k?QtI1cQpUes6>Q#>~^sQUf^j)~(S?M4aYkB?=zkb$~ke)|Cu8AN$ z@$|{G^|+8&8zv8dr=PC2Q;09g`Y^~jKyL^U&?i&jb!=@6-Dy3%&|JBP^C`ZWoolX5 z&N?(Ke>p}QrH5BZpgmuQ3CH7g6kf3KM`wZglzGJxmx0id@i6?DD9K}v?)y447&+q% zce))b{DMs&*Vy=rgk)B|A&2zI@{#hB>)HzjP42qA;oD%J$wIdj8S!k<1e(;*@?gHj z^BoJ7$n2|4&#$SuKC(xYu-&7k&3BFi!VNa6{>)o}=JP`@-#N(hSVmigH9xOHvW2R| z(?y3(BzkfsrY!`rd<V79^ImPT7bwSRA2}{|+p%|A;|^tuZ9P;Yhtp0Zk-p%*7>>KM z!;iJNA<fUtM{p%|@@d-BjpIwJ87m|Dnsnj~{CeFzBsTt(Nmr7cL{4EHF!YOF$zM1q ztLQe4f8m0L_&=O;;$V_FWt63=O)=<Kh;y-*$>5>90(k}&uB1$g*V0S7-;*1+qqgpL zschcYPLKxZPr;uuzh?Gy#eh>()%9Y<H~R;JJ}0ja@7SG>OCKK4hP+FBjV?GH^fbdM zr8~ivGshT77e#lwzGuXNgHc8G$uL6u<eh1D`vzKxn9p2#4|S6Hff=w4E2GcZe&ZO` zc<tP)3$v3fOr1hC>2i`By(KBV+v?|$?LsGBO<WxtvRlcxets@#qKbz?qDuvD;i1j6 z$ac>m+NBT|EX<d~QLJew{6+S*378Sd<Rg=E=Icgz?XIkObKRVlfB2p54Y6HqgcWjj z2*pg&WBytqUZoc;U|z>|)jL32$<7va*U@}EKfcPIg?DO%SsT-k)w3|<&Y!iO+RoN1 z9?5DMJhk`rY7m=1ma0&Lw$hwX{{!udauym}wp#f5@P6>;?5}Fw(I|oATIe)rwv)M= zuTDssjuhYd1;i-0{A1%?r|1tWMW(!Wg6F<wv<p=>I$0ZeCm1&67uGIhIXPFJy3(a{ zJayO32yrQz>@yE(Grm*9Kq!M%Tm=z$l+LiQP2t37V+^|9D51LJb-G;-V!@r?su3~q zN;AxJk&EBl)XNxcwi0yY)U%VXmon@)1?g_T>;0_D+cO*YMUgVMxu@DryOw6CYcb1; zgKy9;bs@tbCFYU)BYeH}?I|g-W?HS%?;tJg__yr1PT}+yawwj0m%=7iyxaIz>eZ`H zV<m!hw93Mvj+AeBzjE{=GowTD;qAJTr!E!;^U-!luR3>?Ca!#96{ToV36jh${UY0h zO#5nV+Mp?U6I#$zB!Hna?!KL%!)d;nv^^1k*s#BfcPL%olJ!pL<+bIEKDK4=>iVka zb^c#!ops-$Zq(I7Ov={dADFLkg=CXEH6kt)-%*JYYL}MXMnk`-X|1=5*&%OVsx!KN zHd>xfzx>mDq(%7^;HzbV7mYG`n}NtA3oHr%pZp{vAts?DeEJkv3MPDXl1KUk9VtDp zx*0bZ#^)n-T7!XK#ym7ExqysO^KgNHT#a~V5eXcw+gWzNVKXk$ac-O4;j2MwN}>rN zX)Gl0FVz^tUo{y$&}*Y7Hs6qE{?++8qsa7Yni$39TKY*%=L^*f4nlFAYT#~?zKkg> zoXA(U@kY?qch`AogvngD#D*@>BMQuKG}K#@-AQw3y`<e#Vo1Cj1gn-%C4S+sD&@CX zm@YqZ^dnQWV_As&-eX9BD|OYna^Y0t%wrjzi{l-M#joH7;w9?0TFAfLAsgcs(@B{L z;<J{1+4-WIY2sU&tw`p(;x>aQKBRi?vzI4>@+rx!@<nH;y^dzRYuPf>f3N|`{iu+- zF_Wcnoe7duX<0OE10LBt5)N;Tk8*1ae{*SD<p|<S%+X>J)OV1ORyzOr8>h|DzK@d_ zf@nTcRi~>a_j2tnA}K7uZz+B58h?t4y}&zmn;L15u$!d`o9a9w7~@O%Ds8Db)1T?> z*o87n+;`B`*vk8Z=Mz3g%JMZ=6|(!0wQ}6_u~CBQy<I^G*S+yqh_ozu!G&SyJ0(3T zkQ1IZHjKZlEa>D|S)OSD6*s%gAUjFlhE`3AA?dmywwq<Mvr+a$DaUDZ3Wl!uXr-!u zTJ|*crc?`!5M{XQOzt9jY6IFhgSF&Vd4pM{5iB8wN-uhyE>yD*cN8mLWc;W*#QrXN zy>{|K8dC9P{J@I)8(exck51O`MmUGei{sZ}6S`eq><Z@6<?0%@973J+n&KtC2ziT( zzD8eUmillqy*axfy|<n->~^o$?MRy!CRcPmw{$WqE^Rv5>x`Ti4rpD!SNKL*XzOyJ z*R02=uP-reL^^S7(R!?L#tXUJ8=-?!k4wAvurzVJ8oeaFTSssPO13pc5$Sx?_Ey)a zp7{unuVPzNyaL)Et5NqYaGzmg)xJ>OMa29hr4Cy%_Q^)`;q!-)duLaN$o>*VlIOp% z(eJdRK}n}wl&yYZQMhR=db{9OVzl-Gm-SJTZktl7($}K1H@9zmG%g)RwvC(kf6_|d znQ+?99Fk6BVU~KeP-CnnKekpT%4F+g=g^(fVpgd4ma@@8?7dJ}f$8N6?VjOp528xG zsK<`f7+H|K249yTYgD+%dh7G3#F1y)5$E7-RWFXA9+y}|Reg3eT+UJNUp?u3<?PJG zYBtBq+c(%nUlW;RdUS`M4KAadC^Al%qLl=jhG444P3YCT@a)XS6B7>*?#d!Wjb-ZV z3F%w`rQVIU^4Fj}BdBo|4E^-^B*8@-YirwA6HvJqpSjxmo(T1gQX-7HrzCQ`5j`z| zEq@-QUVm(iaWI^k(hKE3iL0<!yfyD<<Dj=^euW`zE@xJ}>n}c&9KUN3{S_afOYeo6 z6rcJG!}G<_5Xl?w^%vBGFEI2k0YjhR49+wI9!4*x8>P?6v>$X-zKbGj_g)XqQ>y%E z87ms1<U;w7YDYxd?DA~sb>k*JN?gPpMcbPSr}}*A&N#Ug+WSK_jU<C6H`BvaBrcmi zZlaF*Vi5Xx<U5G+{Yit%Z|@iBes)0K)#sh27xhuQ{Vx1FDDVqV!i>bQLFUxi!DD+f zRwnAF;_#`9I+qKH(>5MD_f{K1MyV!uO)KU@O6fB{YSSSf(G8>f(w@6p=8&}{T(WIv z%N`qAp`^7)H;ddE?pKQUt@gD@8y|_=ICn<zL5NO15E=PT0FiM2_&H<)(E=YrHah|H z0ltCEUH544$5JWqD5^eqc4lB5YAtZt(nqnK@|@YF@QVyf$2NltK8n*VX?a{a(fzoK zE#MB)`K;#9xskSur33G0ovG|mK?&)tSK#_2;69Hr-e@W6#X#xx>uoP%?XchAD8DTh z)*|_>#$j-@Ga1(w(oMqFEH+L@{rHnJk#=yatIInYB`QWLOOaB2im}+d2@M&3%bZ8q zss`yaT&rdcrySX<wUJ9BitlV_H@V~DNONY!N*9aOF4LS4e#bDvcyqm#$H&?Esw}xk zd`?Wlp!Z|l8(rZ!Xs3#>SPNs-<7sVA#nf%Eb5+Nw-?5ZuDI|K(PU_s`_BcMto-}tN z+oLiRK62tUzh2HelU%wC49y)XrGV=?piqj}mtE4{*1oQdBq!>1ak<`yJ5D|FB$P4D zeWX>@_8p7`b5;aYx5-;l$2R)(MTg_f6O+%>J$r+#ry#wa-%=vC5=HlN&O&APM$FXe zzIHO|>~YO@?c9#3JMuYy6P*A51Zx?T=48>Ia_b~)h!Vu9RilNO*p<a6_cEkNp$JP_ zM3$CN6LN{-e4{w$oPg&LARcK7X-6821YWNz^h8_ORnq?Wi3)<h@f6_MGmdUAAq}dg z8L8-^4=aLhy0}w4ldfkfp}z(p(2jskA%{mqWpgfG2nyCJURzR_vZ=ujO)F7W`+|zJ zMk{9KEzrI=>Mjn@TidY>!uY&i5B52*b&9BpRbu&;b4dzR6fPocXf0E=EGKHJqoQKm z$Zi<cTZa^X*e395RQm#6T!(A~#1!1h^x{_vAV}0%m<>CYPScpQ+z4kPRS`18Oc7jX zvR8|VgZ+jftaOHD6P6Z;4pR7yYGf+lrBU3vt(EzP7J%xv23d}FMa?lQTbHy^Dy_jl z;$+g-a0L&fOs|V9v<+7<8r{Y17wrJnWMVBNYluV3F|=jr<ucB_>SqI@z#OrCLmcU! zRIu3E?hQ{HMy>dJlno`Htd|XxHz@SfL{o8<%fPXOu^xoDjqW)yj7w#Dhf8CGuP2N) zuG*dd0MtvE8e@e$m}%`D%MaX3JkC<0O%>cRSx83g;v0R%!zxHQsseR|;xB^88+8va zeHE5bw^5-X&Y^5MX=Kcdu{NIsb+0e*oJ3+f!w5ff5BEJoni8-0O_or8Nm0Z@6(@Bm zWZu#%n2J)UYCSLptwi>&5Wl7pp$a}w+2w$S!}Lht>kOn&t(mYJmkV9-2nFqTEm$4I z+njfMX!W{*SZt2NFAFGyNEx|c=$gw0j|&b?66=ja)V3=S3y9F<JD1zXQp$r;p-cD@ zf-r=QR0!I<C5#=*d8iq?Ow9_G9U-~59Y)vMU3WJ17=xCaN3v{YrEx2Sq07XaC&r-J z)aaW+Eejv~loSSlorsNguA!mIUAQG!XAHs|_Z$yA#6=6{UGLeIcoA6?<$;y^34LIc zBOUl6ktx9t99TK~niqDfnN6jOP{^4fH*+rNW;Hb_9e23%-ViAOc!F;GFhu58Fwy;^ zP@5pqX84uFY}y#Y#z|{tVl1dbt0zeHDaoQ{OGrmN9J2RExLR$XYu4nnG!h^6i=LZB z!;68eRIKNjM}GvPI+qv3e54YeUqr$cj3)S&V#GNHAn}H&hl9)1r6bz_I#*`mojIPb z05!P$DmWv2BOd*uvJk`;>6PyGGmT-Tf=?t0b8J0y9MzPm@|Ijo(<9MiVbtmQVEbjO zqdOzf5M_M`q6URxQw(X7GYvGu4OrX&`q+n-Stdi|ByF;;a4TdH5GsiGU3P|C+$RJU z?M&7XgeMU(cV;F?=PiI&6Ck55(u0^<MFcd>=Gt4mPLsXNyevxY%f_P2;A+oDqY zV0HIEU>R}LV4j+maOZPU1n~sZ<Qd%CD0Dzri&B*7j0+Lys?Lt<!p!rCz(wF(JZ!?L zeL}3C!f#lKExTaKAwfzr9l;CKrlAQ^3&q1}0H|NY$r^FEK<=+F3R#Ast4f1V7zF%r z@db)`2xFiXP!UZgV<Z5jI)@~=@t+j1z*@L3!b__5;w36&yB28l_W`$V2ids9H?6MN zQ70v2%G9;ngBhB%!vYugX`%)|lwruQfzL_4qFHg0l-a0-UT_B3<x?=|DQu}vbzkz1 zWjbs9&ae?r+TgJ1VPC9fTQ#z|4W|Yn2giWdBWws$8*9p{EvZ9&TvTC<)+R_bg7Gsp zY8sAbv?a8H?TBxdGlAe8L<8Bi`IU-ezFEkr+M+AKcv?6Cd<$QQwv}syL>hrFQv@rv z1Q%C7|Jncy0|5X600RI301%HplWpE$=iek>P4E@2s{=+wX$c>%rG{nmw;~&z0tH^f zVXUzrgYPY&?_A`TV3x7wOYaD<jhNTYdUyqwSj~0SW=kdHCwo5(FjP==f08l={{Tna z7Ma@otrb*qS_G<1s{~WTqSfIp0p6+D&l`B1pI@MZTyj*h%E@pF+U1T#CKg$8M$&J^ zH7VTBb=sMwDru6tG<+0>YYkr0T|EWQvA=+_)5QEGR0oBLVzOf8-UOgijoXJg`<eI> zh-6+odvZvL(zZ4CP2DBF-`NU!ZAx70avNS#fxm?R0P0~>2<o3j`y$jUj{}`qKmWu4 zBM|`s0RaI30{{X80RaI3000315g{=UK~W%Kfsvtc!Qubf00;pC0RcY{*!bDGB%&uJ zPh06=*<=t#&)^@yZ1~Kw%Pf(3COHWRn0%5Am#{ILmRTPF&zyt!Fnm<j4Pm?lMcXX2 zL<b^#kh8NQ`kdZLJ-rrh!yg0W{wd{Z7=Ggr!ecG<Wso)uE-f#>$scKOj?6!Up9jvS zeOez8@CBy>mtqCR!*Ah}t9u0YBFP2K)E~fn1REqY)c7DmKJX~Ua>I6D`LQR6sC)%U zxxTxQ84j%ZBj12HemKvMhZ+1|P8(bAT%GtY!2{dsI@s?efH1*4j|sl+0n01`$RBP0 z03;KVPECF<V4K|Wmoc3m7Sa5@FE03Y2ZfWf)rbzd`~5@ABXn$|f%hZEzwX-%CslG_ zZch(cfnGy`WG}ZMydxwzd2e3gT=YoFRcd$OTOYeqFJvirm`a%ydW_ZFFQXPb7@F9J ztiwlcn&;)`lF>m9TpR4DDA>;ABE~h@T+iL*g}Df8%L%bIdy@P~fI93>o+fNMlQj@C zBUay%#D`ae2M3Y4G%>o5!~yW+x0cj1knj4qlM)h-wpOw@*!n@F;GO)DwHPrG0AYPA zZNo{!;Tw(pA`gH%S%@|S1d+I%J)eTukogV~iVwi}z`69;P5nk%c>>3YOWsWcLDnDU zx46bUoY(qWk~c}0GRUE3Pwi!vT_=Q*rM+GV!x#|^PGdhTc=Yzizu2*SU1Hy7)^QT2 zeix+hY<XrfL&e8rLahG)2{2??**-o{MQrIa$X>javtd2B8|{!uV{{?6H&&B*koJBu zYBK2sFJKyCbz_770J3;_dXPN!SB>@?+^<`Gdh?dQai9s%lr=6`H2l}L*!U<i?m_m9 zyW{}N@lHECne=-i=f%~?`cP6HUv3Ml^=mnqXJlB$-Dl(+KBeU5SnB~@whjS-iu_3Y zS$&c(AbB{;(S6ha80RMVNTthTw`TU*19=N{_yoG2z8~g#F(CF|^7}qOFQW%fC(z_( z))WcNVp3t@{{Up1_TX&at&`&s_Cp8<v7DZn6R@+OFs>aSa>Pc!7sT1>eotcEdH(>P z+!^thpHKL<2M@_)JpTYT{-e>Fy2p|~ZZ_O@&tM9|ISN4=j6M<Gd^C^QN$je;urr&y zk>$5$I{yH01SBB!C$B%Wn#@1!F<5{MEsz4n;ke7KhDo==yydPl$N|4m_=edtV6;=V z^iDF@vYt)oYzGC4c@6&n@^qY6Sk6bLeZw|h7SXk~_{MbnNaJ(9e$4tTjKzcX>3%x> z%nsgH)w4c7-p>C3&EqV|AFD3A52Sykg!Xx*oHGnh>FmlkUT@?tt1JQ^7Lqb_kAsVM z!T|Ixb3J~r5zHl=pFIqIm$4}&+3X`eKmWu49}xio0RaI40RaI40RaF2000315g{=U zK~Z5Kk)i+E00;pB0RcY{J}hEGVOe5aD^R2EVQH4n;{9eg`PleIrHlr^AW78XKiU5P zm<g4fvH9QlVQ3~$;eNz8b_AFLIlWoFfP4dD#0a9#fd2rVs+P{*nl`KPiVGvj_Ugh6 zowN8h(kb-imVFW-C%czUuqH-#B1}hP<6|^g@J=BXf51ujuu3yBmMpesI|CJOz=y$P zdthL)_<I<Ov*vtf<K%;C!u^XLwzEV5eovBxmUr)IYShAg$Jlm{;qV$YZ(Zagj4^vE z!*<>e5YqkZ&wzf|9KR)zZA%TCbNIJ6lbN=W>nP4i{-uBn*uFde0N74YkQ*kOeiqp_ zVt0RjZw-g*eo%phu(2j`=6mqxQI1)G25j;@2GPFRgOU<k5A*J!dTh}n)(w&;7EC04 zwz4JS&+^t{9a?Pi64#QLi}^D4n9D5~d2wJ)rOlf&)@Qw$*dCzZn7_4{p@WwV{K=ZY zr98CG7@(FsHUNNX_92<d%0eR9_8Ie+NMqTN3=3QG8$4s_5m~rq46JSc0A$V1l4nl9 zeS)*t3x(R@f8w7xF2X7`5km5M?c#VK2tIpr3CAF;>P;DP>^pyL*!&>Ov_kCNmx3i5 z1;TR2FJ@keA_=fIPoEqgi+nE4<Hf1Zh>f{p1lZHt1O*tv+j2Tbu**w+AQkTYEbr0< zIS0hN9G9e#k0BlQR}RUyg`w8`7w{(CkioMCLb}L0MdHp$xU{fgvv2c0T=vnYk>r+Q z_CX)BfS;C(a@_2O7Ll0(cfLc>1EGEtqy&^P`x_0qTao$2+xO$795&SB9Uttn$m-k7 z@9l!r5qWm95&YRXpHQ1;_(*X3J}b`8hVwNtT{h01$NFq{Q!?w~F3~p+<o%Wz7N$8I z2yhQ9m{|{Cy$f#!$@w{+Om0~M0ozMSIwq`+_TvR0fsB^zv}R-T$nlGS2{!tEz=OMK z1_724PJC1&t%yt+*O3`sqeQddKik#+0GA6)N9MvnAP+egF%2bIVeo6afhav@y0Uo5 z?js}v3Vm<0aB>C^^5v5*7kE**McKci^+b2`SyxH@oW$zY?Z8R>$VC4DNk1(;VaRF~ z8i$r+mk93dvwNO5n0b2mBZJ%Cc-Xk*jH3<*l3n(1cVUN2vLPM3KZd^}-r9IJANL*) z{o4fymTuQc(n-!3-9JfVZngv+xNN^ku@&l+0d0-gw%H;2yJxV3=(LU%A$TyJ>?h@g z|HJ?!5CH%K00II700RL50RR910096IAu&NwVR3<xp|Qc?(eVG;00;pA00BP`G6MH- zR?y!YGr@0$SJC?lzDAasp_C=BFp&lKaEk<{^o`=Laj8@vFf|H%%TA-wGH#QvLK2v6 za4nCR2;04gZE|hG+)HL5)3Fg*X^B4NIKwLOj0+QdOpv#)F{oL7r6cZyZ<t)J?7ks5 zr<KM0tHUY&fQgkgULaTSAghNyA{~NJ*={Af5wf0d+#nZ#Ccm#R#*(>@G?nghf!g?j ztjBv5^Olt^6277ht7D@T{84I|Z<rK3_>}-SASE2rfP%ih-o7INX_N;Of|gP0<y>X+ zu?r{Md=9%{1-s^5+4+RGkp@{sgv3gFgoEZYE=DSxUYV#woW-8~#9rvDN`1>6Zlh1` zCdW)guNYlC!Unq|zlw9ION1K;Du{ltZ-fP!!`6e>UZ)t!itbs%u6vjBzUI8KO}vo} zb=AcbFA(i%^&YOym_ccL_?knKhhH!Y;=Okr5uRYF7S9l{IP*T34bO-iLzzXvFR5>& zH1P+=i2AJ_Q>fsq3L0D=QT?z03h|xHL;<;8rTlHEFU00pQ>yP{rVCL|vQw0m)yIO9 z)e`6|;^8ies2fvt)TIKO%7;huEEG}k8#T|k*-MRoaTf(ZmG>%Hz(DQ@;DzYC@e5y5 zcO{GaH;UEb8oPWTbOjzE(Y;iD!1g?!{D9;%Qr=i$AY3E$2UFV=x4O*R<u{q;9<XZ~ z`IqaborD9kasy#3RIYfBIXVe+3s=M-6KujXVQ&=_BlOEv@ZQ1!OwM5n7QEMT>T#;7 z{2;0nIb5Gox9aX0iM>w8&r!b$=6Bn^WkV>uVVF;u$0~Z3E#@{8(0XON2#a>Og4^D$ zMER9mGz4;ceUTokVvo7bXrG^Oep97HR|5rSo5=RH;sSYUe27jbpMZAV1hSyRfaOxu z7E&<K6@s?<U=_vfdf0!osUWBVz7-#hAt!wgo}ng97f(4`29WNoAIZ(_QdTBQr%YL8 zeT5d-Xlv>5%mFwpmteb!G)m>1Og>=JtodcbX*r6xsE(yk_K_SY4B*JJUD~3)qf%!! z{{XQpg_mu|my)d;9EKHH?ls)9H326I96sRp<3#>bHytXDJaaSEvA+0A+ULX@6q3a? zTp^|h1h>TrutkF1lGSgPA6|?W*p%1FS2%=H30pr#9dRsFy<A6(MlEZrh8$HD#47Di zOb$$qtKwGoR3VdcOO^oz6qsyB(Aj~^R_L|rBwrRG)C_E%VYQc#ac>+%wY6SlYS?$q z%f=Wb<jKhjx7@c&LEJc!@3&aX4fEy^F|VZs{(Z{pEeCwernh6qh-g#3io$qaSJX$V zMd%kv&5<>?OV)DuxtMgvTjj|5;l)##?of1;NUtSa<Q6~`Fb*o`Ylt1ayuvbbP*7%- zO98tabr3lZHf6nc1Z;U)jL!kJ$58eN)o~1r?aZ?R4v|iSM7SOfp%>~=h>5NtZXQUU zE^*<Aac7E@qOa7*>h=z!2pk==5UI$Hjl1qv?_%UZ@Q><THlkcu_jMTlfF8Gxs0w#I zIEy?-5DdQIB(m+)GP?c*L>*NXms}CskwWc4t*?=&%-<^a371VjkPl167)q{gexo20 zp#;25_4O@pQ2LFEe6TQb=OsPF)1*t7h_b|N-O}njAf_=u83Ax(U*deOj~tu~u0 zRW(oAtXl%DjrGJX88r`3f>o=WIYrYuptdB3$1Zq9uLM!Dq;0Z@aFJ)S60(yCP(L4V zGeLe)+LYtsI4eXyVH&}z$2T#z=4X<qi@P1$;x*%#8#yn2VO$s^g~H;YLNNx;>M$cA zfl2=W$d0qGAyCycuM^5B74BM@D;;&Q*dj`LUzmdKVR97(F`~=r1FAxm<+de;n>8L~ zt0KM~MHx#KBN}Z#ZVeoubk3Im@JjxpN0rMHR0Zzm^*VyL)KyAr>2V$(sY-CiAgBVh zej)Z1@xLhX0J`K`13`1K1I#aSt$B%q7lKhHIEbluY5-`k-p5egfpWzST&#*^-ifxh zDX777(s_WnBHum{7QDyw^AWrvc!frYoX29k))OTc`5=)I1-_0JFT(j!P)QfTe+&Vs zd2GpbN{AODaEDd>pmj=%9m{d%v+f;(r2dR4c7-4-tcPXTj4Q+3HuhoLbD9WAvFa$z z%asdtw%jGV!_VcG<IH%MI8E1yLUZCfS}iaiClMGb%}Cy>bGTFG>H(uvnnS+Hqv|1v za-L%SKzaqBM72XrenlX>c^K-Uz<=0MHZc~>YU|F!v(ZWdFwhm-^vmM~a97MS9tF^S z^BY0v9mhT%5(j3E3?(t=z9BnAwPbSI=@>^nwLQk&u^;?VAf>5QKAM8)LgKFcZ@Bt` z)x1Dust++iG>G&I(nJ*HSL9n@s&N{#&jhhr7A&E%F}WenPz_e7f8^F9csVk`0T>v( zjL+sDpu^#dbWPVrb0Ew4K@K0=D_RtfiK#Jxda;VSD}@X#8l&amsJBrh6K>QCExkSn z+T+Z!r6!&FwlmNs2h|NBX7opN)H33fhy8|%w;S;t%jC+)vH>ny8Uk$zrTjy~Q-`)V z3jnp3rYsx9uJH0)M{7{WmOBDfCZ93ln_Q*c#|RCxs&fIn6`^ruWdr7+fIW$9R@vsK zTM0Q3<VMXNrF0r>0->|N${zhhJ41mV(zdSPMvo4bF``Ml?rB&W9F$VBMwDAwS1i<a zfNKpqDt#M+uh(bXNP|${aCL9J>kUdbRzfI|p5CL&Zhv4NPSOtcWr`OyPcacwJxEAw zXfD{SEzsbL%mY)*wJU<wBxrQ9(A$<({P6>*TmjvQD9ws-2Z@|?>8W}+XqEFR%oYaD z=#(5?Q+6YQ0X}k8)Gq%3B@_U+)U?~!4u`H)TL9*x?7tvwR_=8Iu8B*4&Vxc%RAxU> zrG$|}VKr~RQqsPXpzLE^QQTV4DQEW;f&f#*zLMJE`y7p*O5nS%Ff~hL1_L=;y2N_4 zAB571&2JHAEhYC62Aw5P(gYayoH%~sIF-W#m~|)yj!=$xu(8Y)Fb18<WaDF>QxO0{ zi)PeA!e}~`ynx<;%mOx(PMK2o)l2s&^ZbRo(WO9!{4sglSFYE)L{&X6<iBAoOSDFf z@f+=~G8zid)#@_OoC9s->0r$S4jSa(g{Yz|FQ|vsfp&A$4kB&J1!eK#ZVi<YlcGhJ zV6Sq*=(NDG?ygpq_C8|EN)+vDp@-fA_fDwQ#vwsS;O-_xX>wT0AOJ!43xFWE@vsmA zU-J%%fN1dyw1l-$;#BaBz;h8ltpK^kOhyY+-_|$=?#fGl-D`SkFJb)`^8R7fgxfg& zetC;~meTo%0N5y1#)3N($x(_|9COX9uzvS%s1oq4Dae)@4f5{n5iL1R&1Ff(^5Kjv zZU8$vFzM2Tcw^9uBMffttB-NyvmMo;YS-}(iD9ZK5VobpQM3@g2gxX^#**_sAOcjV zH$pNSkWF`Y>Rs(X#wNeE_8WC?93CRTTGn$C6evvyn))6aer^z7&SV-Kjlg-@A|+c_ z9^nP;JeA#h`GOZ#$y4PEZgXY{qkb3}Xrjj=_Z5e5Ec;_S4nzJD>7hiM-8T4z(7$eh z*OLM#Es<3<-^=+e2g)gNSV8U?4F;F|M%cPqk3nMnOVF-PqDzqI$E=9AygbK80va4I z+b^A=FBre%<#KKp8BpanaCH;&2b(y)4{XY9a_z`GqQLWOW#xUu@J1ofPnZMTM2zrD j*$9d3q8=b|LY$Vw;YJ=9gwa*_BLHd3+$zKa^FRODaj~Kt literal 0 HcmV?d00001 diff --git a/tests/auto/gui/painting/qcolorspace/resources/sRGB2014.icc b/tests/auto/gui/painting/qcolorspace/resources/sRGB2014.icc new file mode 100644 index 0000000000000000000000000000000000000000..49afbfef10f22a1832590b68369d2f248ea553b9 GIT binary patch literal 3024 zcmb`Jc{r5o8^@pboqe;-klom~#=Z=)?<7n1RL0C;EQ4W?v`H$Qlq6e;oU(N2=!6`p zq_j9fq0&N*O8IqkN}I~>9j@P{b6vkb&vRYx^M3C8x$pP6pZoda{Q^K51jvAqCy}2f z2yl0zhlYjIaZeGKxM&3c7CSY0nf@_DE7pfmuw>n3h<vtUtxuW{AMLJ;(HbZuIuESG z{a=#ca8ua;KrYBCI||tx;d+E=QGo%@2zLR1C&&E2f*+WZ$l(A$xPip)i&@Gg`iXKA zgo!)=h{zhCC30D*2xlU!5fz`DhH#b0FIbL0E8;XRI~MWxB1}#fa*;fus4sgn(nRs3 zP*Ds!Ss>yBge}>zEF^|hhw$p<`Vm43NktlHVq|Q#Wc`bi=uVbDr*Q%R@mv7f?y!Y| z^kpAf^uhola$__g2b6(2&;bl!0xW?IZ~(5r3;2RS5C%2@Hi!j@Kmam8HrNI7Kmj-i zj(`eK4eCGxXa=pI9dv;!;5xVs2Ehmz2NPf#yasdN16Y6{2nSIhDkKM~K$?&~WCAfE zJIEDU3k5)7P$U!s@gX6U4ef>spkk;3s(~7yU!e=o73d~31U-Nzp&96J=nIU3$uJF8 zg0)~nm<c<=-f$qi5sraV;4C;7J^+`&weT6Z4ZZ^3hDYED_%%F_0w@wn2BnH(pqMCU zlrJhA6^#<0wxjY<rKnm|GpZBShq{ZJK+U2)qp@fznvQ0mZO|U*AT%4Dg5HiUL|35e z(QW8n^j-8MdJg>^L%}Fw^fA^LPfRE#29trw!<1r9Va{W&VMZ|1m=9PiRtBq$wZwX0 z!?1DKt=K~BF>DL=GIj_%g`LOYaB?_(oGs25$HJxI@^Iz2Gq_8*VcazC6P|=u!JFXS z@ZoqqJ_lclZ^U=whw(4)3j_&*Cc&EEOW+W;5Q+$OgigX8!ZcxlC`r^N+7bhaal~E3 zGGa6F8u1bF9f?FzBUzFBNj%a{QW@zi=>}<%^qDM0)+0NUBgjJX0rF|`W%2{^I|_xO zMRA~nQ_?60C=HaWlqZx=VpK5$F;6j$*bcEuu{N<`u{YubaZPbY@lE1c;-%u}#P5jD zN)RNpB%CE!65AyzB`!#eNz6-9C5<J0B@-nJB^xDgO1_lBNoh&BN^zuerA|s+m71cW zsOnT_Dx12ST1UM`ou*-F+B8pE9Ib%%3vGZlCoLsyCLJuDDP1XjQF=lKC8H(dDU%>m zB-1K0D)VKP(kjPQ+*SKmHLn_8^-)$q)<Kpln=jiUJ0kl<jxOga7cX~6u3hf2JX&5) z-d{dL{<!=#`B?>;f{g-OAzz_Y;h`d|sHYg9xK;6_V!z_NlCqM!QnFIH(p9BdWf^4$ z<v8UM<!<E}6{?Dz3Qwg(<&w%Px-{L9o<J|7_tNK76;(Y{g{n2G1F8#Z+G;^+IchCx zkJX9lO!a8>67?SSISmyJAB}8{CXI)h1Wl%9tmaY8KFyC>+FBu6d$roNUTVu~dunHC zH)%i8q3GD_r0CS@+|$MCGIis1kLeET!FuL;v3iwycl2R>3w@scG5w*{nAKLR`KxPJ zk1@y$M@BlMi7{y)W3bjB$DrNdjiH8NxZxqgKEv-u=0*udbw=aHQpR4!ImVsFf1Bu; zuuUpW?wL|d-As3wc9_03(>LRq9XGpgPBr&2-)r7u{>{SDLSWHsF=MG=8EIK%ImV<h z{g{Q!8&()AC#xM+T~?p1Ev(b5Tdn`HVc5jmG}^peqrHZ^rf$uYt(q;%w#IhCj&2ue zcfxMMUe%suUu*x&LEVAlaLVC@qpo9|;~B>{PDV}wr}Iu9ovod>IbU``xwyOJy9~HW zxdypbxIS@HbBl3na+`BEci-xM*#qO@?QzIs%u~se?b+Zt=Vj@&&8yd&?7iN*!u#1; zy|se1oj$OSm(O9JN9#1#@z=Hc0$)$x!@iIGwEa^2e)q@v`}tS;KMybt$PVaRPhG!x zedGEMflh%%f#X3sLBgP(VDaFH;D+FjAub`sArqm7q1!@lhslTW!aBln;lbgj!sj=* zZaA`GI>J06FJg3~_QuSOH#f;|O4xL9v-oD#=5vvl$dJg!$geD4RxN8j$}_4eYL4y9 zKFWU0ap072X1KQ8V(yD*+vwuxmoc_6hht`9?PE)0XL-)N3f|i|kGSf%kMX|or{fnB zLK0dM@rjX%7x+^Acz$n^a#Ci}P_lk<Uh+hWb;^;HIf1v}R4SCZF|{L&hWtqSg*w7L z!pU^I^vd*48NnInG9@$lnf+Vzw(Q^XBFio7=dI|i?5#c7s@c1;C$~9ntJw~1kJ{d| zLw!f?j_IB5JL`85cg64eBgZJGIOqNDklmfRO1V38r}nt-Y04AJ6XcEUwb@&}5514K zZ(zUa{__3b^Evsq3XBR$3%(Yz3vc~o{8QOaiwB|)3=~-u9Y2UY$UiuG$o^1$v1D;p z@zi0T!)+z>lKhhQM>Ze1S!z~VeUx}qcyyv{ZCOXTM)|?=uNAQsBb82-EmewD`>Q@4 z;~X14?r^-hTB*9A`pXI4iTgF~HEp$8wWTMqC(}<puM4j0`<eN3!zuYw1*g89=AWLZ z52){Luxw~(RBSA2f}4a*GiM^s4F2NsOGh)Kxu!*?rQj?$D?Iz^*T`Q-TfJL*&N0t5 z|EBp{)p_dq{5Gg<OWRy~Z2Lq<SjW%>uM0h$Hl62xH~9T@mugq#Md^!0-Nf$P?!`-4 zm*y`gU!J`Zb7iV$bI<tI(5v@){d)(ld0)G6-R=6-KF7XGH*9Zo-L$@W;TH2&`)!Nc zZT;r`=l?MO<NScdK-(S5I~{{ogPlWbhPsFChp*gqxqJPd=e^q_>qdq~gGTR<MT||{ z=iGn!AmPE=hv^R&#&<r#Jj#D8@woJf;*;8^x=&jsEG8~ax=i*zTmNi)iaquE&(uG^ zPUk+SJTHBr@}l9T$;+-8x0%6L8(vMnPJX>GoA)2d|5UxvdGp&}4uAE}h0aaC6}(;i zyYQXdyVLK@-uKM=%|H2&_+jB={wKLl^`Dua`@V#Hd9jf375BC5o9?&H@7~`ZEha85 z{-8k&JYAjX7RFW<77P=HG2Mk5%@QW0(M8J6IVmAYD4?%TX0f?+23;gpmIcJWHm~TE zsB!?>_W&UKaK(pgBT{F`Sk`1q_=ApIvi~>1Kja-poFc8Ycg2@f3jlK-0Mx-$UJPB7 z<Qx!4|Dg|z0B$r_z~v)H4d!t(c>EaT{Co~CjhDoy^Z4|Cv`LizZ;q8ZSF~{&Hxtp1 zNS#T^TLiqA*fhE)KaDHkvqTlK5|(a9AgVDnNsz`9Ca$I<O41yF)M!(arP?5}3nKHL eE-t>)0svP6z_+5s#f6&1#cxP2P~!kx7XBBF2+<<| literal 0 HcmV?d00001 diff --git a/tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp b/tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp new file mode 100644 index 0000000000..9bd4b75443 --- /dev/null +++ b/tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp @@ -0,0 +1,238 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> + +#include <qcolorspace.h> +#include <qimage.h> +#include <qimagereader.h> + +Q_DECLARE_METATYPE(QColorSpace::ColorSpaceId) +Q_DECLARE_METATYPE(QColorSpace::Gamut) +Q_DECLARE_METATYPE(QColorSpace::TransferFunction) + +class tst_QColorSpace : public QObject +{ + Q_OBJECT + +public: + tst_QColorSpace(); + +private slots: + void namedColorSpaces_data(); + void namedColorSpaces(); + + void toIccProfile_data(); + void toIccProfile(); + + void fromIccProfile(); + + void imageConversion_data(); + void imageConversion(); + + void loadImage(); +}; + +tst_QColorSpace::tst_QColorSpace() +{ } + + +void tst_QColorSpace::namedColorSpaces_data() +{ + QTest::addColumn<QColorSpace::ColorSpaceId>("colorSpaceId"); + QTest::addColumn<QColorSpace::Gamut>("gamutId"); + QTest::addColumn<QColorSpace::TransferFunction>("transferFunctionId"); + + QTest::newRow("sRGB") << QColorSpace::SRgb + << QColorSpace::Gamut::SRgb + << QColorSpace::TransferFunction::SRgb; + QTest::newRow("sRGB Linear") << QColorSpace::SRgbLinear + << QColorSpace::Gamut::SRgb + << QColorSpace::TransferFunction::Linear; + QTest::newRow("Adobe RGB") << QColorSpace::AdobeRgb + << QColorSpace::Gamut::AdobeRgb + << QColorSpace::TransferFunction::Gamma; + QTest::newRow("Display-P3") << QColorSpace::DisplayP3 + << QColorSpace::Gamut::DciP3D65 + << QColorSpace::TransferFunction::SRgb; + QTest::newRow("ProPhoto RGB") << QColorSpace::ProPhotoRgb + << QColorSpace::Gamut::ProPhotoRgb + << QColorSpace::TransferFunction::ProPhotoRgb; + QTest::newRow("BT.2020") << QColorSpace::Bt2020 + << QColorSpace::Gamut::Bt2020 + << QColorSpace::TransferFunction::Bt2020; +} + +void tst_QColorSpace::namedColorSpaces() +{ + QFETCH(QColorSpace::ColorSpaceId, colorSpaceId); + QFETCH(QColorSpace::Gamut, gamutId); + QFETCH(QColorSpace::TransferFunction, transferFunctionId); + + QColorSpace colorSpace = colorSpaceId; + + QVERIFY(colorSpace.isValid()); + + QCOMPARE(colorSpace.colorSpaceId(), colorSpaceId); + QCOMPARE(colorSpace.gamut(), gamutId); + QCOMPARE(colorSpace.transferFunction(), transferFunctionId); +} + + +void tst_QColorSpace::toIccProfile_data() +{ + namedColorSpaces_data(); +} + +void tst_QColorSpace::toIccProfile() +{ + QFETCH(QColorSpace::ColorSpaceId, colorSpaceId); + QFETCH(QColorSpace::Gamut, gamutId); + QFETCH(QColorSpace::TransferFunction, transferFunctionId); + + Q_UNUSED(gamutId); + Q_UNUSED(transferFunctionId); + + QColorSpace colorSpace = colorSpaceId; + QByteArray iccProfile = colorSpace.iccProfile(); + QVERIFY(!iccProfile.isEmpty()); + + QColorSpace colorSpace2 = QColorSpace::fromIccProfile(iccProfile); + QVERIFY(colorSpace2.isValid()); + + QCOMPARE(colorSpace2, colorSpace); + + QByteArray iccProfile2 = colorSpace2.iccProfile(); + QVERIFY(!iccProfile2.isEmpty()); + + QCOMPARE(iccProfile2, iccProfile); +} + +void tst_QColorSpace::fromIccProfile() +{ + // Read the official sRGB ICCv2 profile: + QString prefix = QFINDTESTDATA("resources/"); + QFile file(prefix + "sRGB2014.icc"); + file.open(QIODevice::ReadOnly); + QByteArray iccProfile = file.readAll(); + QColorSpace stdSRgb = QColorSpace::fromIccProfile(iccProfile); + QVERIFY(stdSRgb.isValid()); + + QCOMPARE(stdSRgb.gamut(), QColorSpace::Gamut::SRgb); + QCOMPARE(stdSRgb.transferFunction(), QColorSpace::TransferFunction::SRgb); + QCOMPARE(stdSRgb.colorSpaceId(), QColorSpace::SRgb); + + QCOMPARE(stdSRgb, QColorSpace(QColorSpace::SRgb)); +} + +void tst_QColorSpace::imageConversion_data() +{ + QTest::addColumn<QColorSpace::ColorSpaceId>("fromColorSpace"); + QTest::addColumn<QColorSpace::ColorSpaceId>("toColorSpace"); + QTest::addColumn<int>("tolerance"); + + QTest::newRow("sRGB -> Display-P3") << QColorSpace::SRgb << QColorSpace::DisplayP3 << 0; + QTest::newRow("sRGB -> Adobe RGB") << QColorSpace::SRgb << QColorSpace::AdobeRgb << 2; + QTest::newRow("Display-P3 -> sRGB") << QColorSpace::DisplayP3 << QColorSpace::SRgb << 0; + QTest::newRow("Adobe RGB -> sRGB") << QColorSpace::AdobeRgb << QColorSpace::SRgb << 2; + QTest::newRow("Display-P3 -> Adobe RGB") << QColorSpace::DisplayP3 << QColorSpace::AdobeRgb << 2; + QTest::newRow("Display-P3 -> BT.2020") << QColorSpace::DisplayP3 << QColorSpace::Bt2020 << 4; + QTest::newRow("sRGB -> sRGB Linear") << QColorSpace::SRgb << QColorSpace::SRgbLinear << 0; +} + +void tst_QColorSpace::imageConversion() +{ + QFETCH(QColorSpace::ColorSpaceId, fromColorSpace); + QFETCH(QColorSpace::ColorSpaceId, toColorSpace); + QFETCH(int, tolerance); + + QImage testImage(256, 1, QImage::Format_RGB32); + + for (int i = 0; i < 256; ++i) + testImage.setPixel(i, 0, qRgb(i, i, i)); + + testImage.setColorSpace(fromColorSpace); + QCOMPARE(testImage.colorSpace(), QColorSpace(fromColorSpace)); + + testImage.convertToColorSpace(toColorSpace); + QCOMPARE(testImage.colorSpace(), QColorSpace(toColorSpace)); + + int lastRed = 0; + int lastGreen = 0; + int lastBlue = 0; + for (int i = 0; i < 256; ++i) { + QRgb p = testImage.pixel(i, 0); + QVERIFY(qRed(p) >= lastRed); + QVERIFY(qGreen(p) >= lastGreen); + QVERIFY(qBlue(p) >= lastBlue); + lastRed = qRed(p); + lastGreen = qGreen(p); + lastBlue = qBlue(p); + } + + lastRed = 0; + lastGreen = 0; + lastBlue = 0; + testImage.convertToColorSpace(fromColorSpace); + QCOMPARE(testImage.colorSpace(), QColorSpace(fromColorSpace)); + for (int i = 0; i < 256; ++i) { + QRgb p = testImage.pixel(i, 0); + QVERIFY(qAbs(qRed(p) - qGreen(p)) <= tolerance); + QVERIFY(qAbs(qRed(p) - qBlue(p)) <= tolerance); + QVERIFY((lastRed - qRed(p)) <= (tolerance / 2)); + QVERIFY((lastGreen - qGreen(p)) <= (tolerance / 2)); + QVERIFY((lastBlue - qBlue(p)) <= (tolerance / 2)); + lastRed = qRed(p); + lastGreen = qGreen(p); + lastBlue = qBlue(p); + } +} + + +void tst_QColorSpace::loadImage() +{ + QString prefix = QFINDTESTDATA("resources/"); + QImageReader reader(prefix + "ProPhoto.jpg"); + QImage image = reader.read(); + + QVERIFY(!image.isNull()); + QVERIFY(image.colorSpace().isValid()); + QCOMPARE(image.colorSpace().colorSpaceId(), QColorSpace::ProPhotoRgb); + QVERIFY(!image.colorSpace().iccProfile().isEmpty()); + + QColorSpace defaultProPhotoRgb = QColorSpace::ProPhotoRgb; + QVERIFY(!defaultProPhotoRgb.iccProfile().isEmpty()); + + // Test the iccProfile getter returns the ICC profile from the image + // which since we didn't write it, isn't identical to our defaults. + QVERIFY(defaultProPhotoRgb.iccProfile() != image.colorSpace().iccProfile()); +} + +QTEST_MAIN(tst_QColorSpace) +#include "tst_qcolorspace.moc" From 756c64c539952334546c08741066546cc43e104c Mon Sep 17 00:00:00 2001 From: Tobias Hunger <tobias.hunger@qt.io> Date: Fri, 21 Dec 2018 12:17:25 +0100 Subject: [PATCH 1082/1650] qmake.pro: Fix missing headers and add missing line continuation Change-Id: I308cff86f1af2c24eee13ec0531d967a3770ed04 Reviewed-by: Frederik Gladhorn <frederik.gladhorn@qt.io> Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> --- qmake/qmake.pro | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/qmake/qmake.pro b/qmake/qmake.pro index ebd61751b7..d704fdb6dc 100644 --- a/qmake/qmake.pro +++ b/qmake/qmake.pro @@ -96,7 +96,7 @@ HEADERS += \ bp = $$shadowed(..) INCLUDEPATH += \ $$bp/include $$bp/include/QtCore \ - $$bp/include/QtCore/$$QT_VERSION $$bp/include/QtCore/$$QT_VERSION/QtCore + $$bp/include/QtCore/$$QT_VERSION $$bp/include/QtCore/$$QT_VERSION/QtCore \ $$bp/src/corelib/global VPATH += \ @@ -182,18 +182,17 @@ HEADERS += \ qglobal.h \ qhash.h \ qiodevice.h \ - qjson.h \ + qjson_p.h \ qjsonarray.h \ qjsondocument.h \ qjsonobject.h \ - qjsonparser.h \ + qjsonparser_p.h \ qjsonvalue.h \ - qjsonwriter.h \ + qjsonwriter_p.h \ qlinkedlist.h \ qlist.h \ qlocale.h \ qlocale_tools_p.h \ - qmalloc.h \ qmap.h \ qmetatype.h \ qnumeric.h \ @@ -204,12 +203,12 @@ HEADERS += \ qsystemerror_p.h \ qtemporaryfile.h \ qtextstream.h \ - qutfcodec.h \ + qutfcodec_p.h \ quuid.h \ qvector.h \ qversionnumber.h \ qxmlstream.h \ - qxmlutils.h + qxmlutils_p.h unix { SOURCES += \ From e990d4d27f6ca2044808a91f88c39d2ac1c690e2 Mon Sep 17 00:00:00 2001 From: Tobias Hunger <tobias.hunger@qt.io> Date: Tue, 29 Jan 2019 10:38:23 +0100 Subject: [PATCH 1083/1650] corelib: typo fix in .pro-file Consistently use space before line continuation marker. Change-Id: Ib87d45f76b6fd174c78a04335f06b4dbed1bed13 Reviewed-by: Frederik Gladhorn <frederik.gladhorn@qt.io> --- src/corelib/kernel/kernel.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri index 3f7bf3cd47..789bcb7927 100644 --- a/src/corelib/kernel/kernel.pri +++ b/src/corelib/kernel/kernel.pri @@ -7,7 +7,7 @@ HEADERS += \ kernel/qdeadlinetimer.h \ kernel/qdeadlinetimer_p.h \ kernel/qelapsedtimer.h \ - kernel/qeventloop.h\ + kernel/qeventloop.h \ kernel/qpointer.h \ kernel/qcorecmdlineargs_p.h \ kernel/qcoreapplication.h \ From 1d1e801cba01c88e75e73aa19e07d7588aa9e89b Mon Sep 17 00:00:00 2001 From: Tobias Hunger <tobias.hunger@qt.io> Date: Tue, 29 Jan 2019 14:13:41 +0100 Subject: [PATCH 1084/1650] gui: Fix typo in qmake build system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I170125fb7ed2355b3b322ef287c795f40c37fe6b Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> --- src/gui/kernel/kernel.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri index 1f137fc46f..9c80f1e2cc 100644 --- a/src/gui/kernel/kernel.pri +++ b/src/gui/kernel/kernel.pri @@ -21,7 +21,7 @@ HEADERS += \ kernel/qplatforminputcontextplugin_p.h \ kernel/qplatformintegrationfactory_p.h \ kernel/qplatformintegrationplugin.h \ - kernel/qplatformtheme.h\ + kernel/qplatformtheme.h \ kernel/qplatformtheme_p.h \ kernel/qplatformthemefactory_p.h \ kernel/qplatformthemeplugin.h \ From 30178a22ffde5d216a350910668df0d906aced3b Mon Sep 17 00:00:00 2001 From: Oliver Wolff <oliver.wolff@qt.io> Date: Fri, 25 Jan 2019 10:39:16 +0100 Subject: [PATCH 1085/1650] Windows configure: Make dynamic opengl the default option Most people expect dynamic opengl the default, when configuring Qt on Windows and are not too happy if they have to reconfigure and rebuild when they they find out, that the default is ANGLE. Dynamic OpenGL is the way to go as the user can easily decide what to use by setting the QT_OPENGL environment variable. Besides that, our packages are built using dynamic OpenGL on Windows [ChangeLog][configure] The default OpenGL configuration changed from ANGLE to dynamic OpenGL. Change-Id: Ia5688249e6d0a4d3ebe8cbe22e02fe290d9f0a4c Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io> --- src/gui/configure.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/gui/configure.json b/src/gui/configure.json index 70d0817791..51d89973ed 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -1105,7 +1105,7 @@ "angle": { "label": "ANGLE", "autoDetect": "features.opengles2 || features.opengl-dynamic", - "condition": "features.dxguid && tests.fxc && (features.direct3d9 || (config.winrt && features.direct3d11 && libs.d3dcompiler))", + "condition": "!features.opengl-desktop && features.dxguid && tests.fxc && (features.direct3d9 || (config.winrt && features.direct3d11 && libs.d3dcompiler))", "output": [ "publicFeature", { "type": "define", "name": "QT_OPENGL_ES_2_ANGLE" }, @@ -1308,9 +1308,9 @@ }, "opengles2": { "label": "OpenGL ES 2.0", - "enable": "input.opengl == 'es2'", + "enable": "input.opengl == 'es2' || input.angle == 'yes'", "disable": "input.opengl == 'desktop' || input.opengl == 'dynamic' || input.opengl == 'no'", - "condition": "config.win32 || (!config.watchos && !features.opengl-desktop && libs.opengl_es2)", + "condition": "(config.win32 && !features.opengl-dynamic) || (!config.watchos && !features.opengl-desktop && libs.opengl_es2)", "output": [ "publicFeature", "publicQtConfig", @@ -1344,6 +1344,7 @@ }, "opengl-desktop": { "label": "Desktop OpenGL", + "autoDetect": "!config.win32", "enable": "input.opengl == 'desktop'", "disable": "input.opengl == 'es2' || input.opengl == 'dynamic' || input.opengl == 'no'", "condition": "(config.win32 && !config.winrt && !features.opengles2 && (config.msvc || libs.opengl)) @@ -1351,8 +1352,7 @@ }, "opengl-dynamic": { "label": "Dynamic OpenGL", - "enable": "input.opengl == 'dynamic'", - "autoDetect": false, + "disable": "input.angle == 'yes' || input.opengl == 'no' || input.opengl == 'desktop'", "condition": "config.win32 && !config.winrt", "output": [ { "type": "publicFeature", "name": "dynamicgl" }, From b611eb81c822ed2bcd3107ba098b56952ae0685c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= <morten.sorvig@qt.io> Date: Tue, 5 Feb 2019 11:43:04 +0100 Subject: [PATCH 1086/1650] Fix QDeadlineTimer::Forever case in QWaitCondition The timeout will never be larger than numeric_limits<quint64>::max(), especially on platforms with 32-bit longs. Instead, test if the timeout is exactly numeric_limits<unsigned long>::max(), which matches the ULONG_MAX value which is documented to indicate no timeout. Change-Id: Ib663eddb5703797c50c04fd4eae60bd64f379d1c Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> --- src/corelib/thread/qwaitcondition_unix.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/corelib/thread/qwaitcondition_unix.cpp b/src/corelib/thread/qwaitcondition_unix.cpp index c93328b4bc..0ba90763cf 100644 --- a/src/corelib/thread/qwaitcondition_unix.cpp +++ b/src/corelib/thread/qwaitcondition_unix.cpp @@ -204,7 +204,7 @@ void QWaitCondition::wakeAll() bool QWaitCondition::wait(QMutex *mutex, unsigned long time) { - if (quint64(time) > quint64(std::numeric_limits<qint64>::max())) + if (time == std::numeric_limits<unsigned long>::max()) return wait(mutex, QDeadlineTimer(QDeadlineTimer::Forever)); return wait(mutex, QDeadlineTimer(time)); } @@ -231,6 +231,8 @@ bool QWaitCondition::wait(QMutex *mutex, QDeadlineTimer deadline) bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time) { + if (time == std::numeric_limits<unsigned long>::max()) + return wait(readWriteLock, QDeadlineTimer(QDeadlineTimer::Forever)); return wait(readWriteLock, QDeadlineTimer(time)); } From c066656aff4841f9095e77754fa7533f7bbbb66a Mon Sep 17 00:00:00 2001 From: Edward Welbourne <edward.welbourne@qt.io> Date: Thu, 7 Feb 2019 17:04:49 +0100 Subject: [PATCH 1087/1650] Avoid read-outside-array error by QStringRef over-reach Constructing a QStringRef directly from the string, offset and a length is UB if the offset + length exceeds the string's length. Thanks to Robert Loehning and libFuzzer for finding this. QString::midRef (as correctly used in both changed uses of QStringRef, since 432d3b69629) takes care of that for us. Changed one UB case and a matching but correct case, for consistency. In the process, deduplicate a QStringList look-up. Added tests to exercise the code (but the one that exercises the formerly UB case doesn't crash before the fix, so isn't very useful; the invalid read is only outside the array it's scanning, not outside allocated memory). Change-Id: I7051bbbc0267dd7ec0a8f75eee2034d0b7eb75a2 Reviewed-by: Anton Kudryavtsev <antkudr@mail.ru> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> --- src/corelib/tools/qdatetimeparser.cpp | 11 ++++++----- .../auto/corelib/tools/qdatetime/tst_qdatetime.cpp | 13 +++++++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index e6afd510fd..e8470f6cde 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -1125,13 +1125,14 @@ QDateTimeParser::scanString(const QDateTime &defaultValue, for (int index = 0; index < sectionNodesCount; ++index) { Q_ASSERT(state != Invalid); - if (QStringRef(input, pos, separators.at(index).size()) != separators.at(index)) { - QDTPDEBUG << "invalid because" << input->midRef(pos, separators.at(index).size()) - << "!=" << separators.at(index) + const QString &separator = separators.at(index); + if (input->midRef(pos, separator.size()) != separator) { + QDTPDEBUG << "invalid because" << input->midRef(pos, separator.size()) + << "!=" << separator << index << pos << currentSectionIndex; return StateNode(); } - pos += separators.at(index).size(); + pos += separator.size(); sectionNodes[index].pos = pos; int *current = 0; const SectionNode sn = sectionNodes.at(index); @@ -1227,7 +1228,7 @@ QDateTimeParser::scanString(const QDateTime &defaultValue, isSet |= sn.type; } - if (QStringRef(input, pos, input->size() - pos) != separators.last()) { + if (input->midRef(pos) != separators.last()) { QDTPDEBUG << "invalid because" << input->midRef(pos) << "!=" << separators.last() << pos; return StateNode(); diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp index 943805e228..b128ccebc5 100644 --- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp @@ -2401,6 +2401,19 @@ void tst_QDateTime::fromStringStringFormat_data() QTest::newRow("late") << QString("9999-12-31T23:59:59.999Z") << QString("yyyy-MM-ddThh:mm:ss.zZ") << QDateTime(QDate(9999, 12, 31), QTime(23, 59, 59, 999)); + // Separators match /([^aAdhHMmstyz]*)/ + QTest::newRow("oddly-separated") // To show broken-separator's format is valid. + << QStringLiteral("2018 wilful long working block relief 12-19T21:09 cruel blurb encore flux") + << QStringLiteral("yyyy wilful long working block relief MM-ddThh:mm cruel blurb encore flux") + << QDateTime(QDate(2018, 12, 19), QTime(21, 9)); + QTest::newRow("broken-separator") + << QStringLiteral("2018 wilful") + << QStringLiteral("yyyy wilful long working block relief MM-ddThh:mm cruel blurb encore flux") + << invalidDateTime(); + QTest::newRow("broken-terminator") + << QStringLiteral("2018 wilful long working block relief 12-19T21:09 cruel") + << QStringLiteral("yyyy wilful long working block relief MM-ddThh:mm cruel blurb encore flux") + << invalidDateTime(); } void tst_QDateTime::fromStringStringFormat() From c41efe7373ef207913cd27111aae8d3c48890efe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= <marten.nordheim@qt.io> Date: Mon, 28 Jan 2019 15:57:44 +0100 Subject: [PATCH 1088/1650] Schannel: slightly optimize memory-usage for encryption Change-Id: I0f4b372ad3a0cd5e6730ed2e23e738fb06b2aad5 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> --- src/network/ssl/qsslsocket_schannel.cpp | 37 ++++++++++--------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/src/network/ssl/qsslsocket_schannel.cpp b/src/network/ssl/qsslsocket_schannel.cpp index 965e9bf2f3..e75f81bd36 100644 --- a/src/network/ssl/qsslsocket_schannel.cpp +++ b/src/network/ssl/qsslsocket_schannel.cpp @@ -142,12 +142,9 @@ Medium priority: - Setting cipher-suites (or ALG_ID) - People have survived without it in WinRT - - ALPN: - For HTTP2. Note: Windows 8.1 and up ONLY. Low priority: - Possibly make RAII wrappers for SecBuffer (which I commonly create QScopeGuards for) - - Perform the '@future' optimization in "transmit()" */ @@ -1188,23 +1185,21 @@ void QSslSocketBackendPrivate::transmit() qint64 totalBytesWritten = 0; qint64 writeBufferSize; while ((writeBufferSize = writeBuffer.size()) > 0) { - QByteArray plaintext; + const int headerSize = int(streamSizes.cbHeader); + const int trailerSize = int(streamSizes.cbTrailer); + // Try to read 'cbMaximumMessage' bytes from buffer before encrypting. + const int size = int(std::min(writeBufferSize, qint64(streamSizes.cbMaximumMessage))); + QByteArray fullMessage(headerSize + trailerSize + size, Qt::Uninitialized); { - // Try to read 'cbMaximumMessage' bytes from buffer before encrypting. - int size = int(std::min(writeBufferSize, qint64(streamSizes.cbMaximumMessage))); - plaintext.resize(size); // Use peek() here instead of read() so we don't lose data if encryption fails. - qint64 copied = writeBuffer.peek(plaintext.data(), size); + qint64 copied = writeBuffer.peek(fullMessage.data() + headerSize, size); Q_ASSERT(copied == size); } - QByteArray header(int(streamSizes.cbHeader), '\0'); - QByteArray trailer(int(streamSizes.cbTrailer), '\0'); SecBuffer inputBuffers[4]{ - // @future[0/1]: optimize by using one container for all fields... - createSecBuffer(header, SECBUFFER_STREAM_HEADER), - createSecBuffer(plaintext, SECBUFFER_DATA), - createSecBuffer(trailer, SECBUFFER_STREAM_TRAILER), + createSecBuffer(fullMessage.data(), headerSize, SECBUFFER_STREAM_HEADER), + createSecBuffer(fullMessage.data() + headerSize, size, SECBUFFER_DATA), + createSecBuffer(fullMessage.data() + headerSize + size, trailerSize, SECBUFFER_STREAM_TRAILER), createSecBuffer(nullptr, 0, SECBUFFER_EMPTY) }; SecBufferDesc message{ @@ -1220,18 +1215,14 @@ void QSslSocketBackendPrivate::transmit() return; } // Data was encrypted successfully, so we free() what we peek()ed earlier - writeBuffer.free(plaintext.length()); + writeBuffer.free(size); - // trailer has been observed to change size, so resize them all (when needed) to be safe - header = header.left(int(inputBuffers[0].cbBuffer)); - plaintext = plaintext.left(int(inputBuffers[1].cbBuffer)); - trailer = trailer.left(int(inputBuffers[2].cbBuffer)); - const qint64 bytesWritten = plainSocket->write(header // @future[1/1]: ...because they need to be merged - + plaintext - + trailer); + // The trailer's size is not final, so resize fullMessage to not send trailing junk + fullMessage.resize(inputBuffers[0].cbBuffer + inputBuffers[1].cbBuffer + inputBuffers[2].cbBuffer); + const qint64 bytesWritten = plainSocket->write(fullMessage); #ifdef QSSLSOCKET_DEBUG qCDebug(lcSsl) << "Wrote" << bytesWritten << "of total" - << header.length() + plaintext.length() + trailer.length() << "bytes"; + << fullMessage.length() << "bytes"; #endif if (bytesWritten >= 0) { totalBytesWritten += bytesWritten; From 4ce485a2eba40cc6d1edcf4baa794276432e1bea Mon Sep 17 00:00:00 2001 From: Friedemann Kleint <Friedemann.Kleint@qt.io> Date: Wed, 6 Feb 2019 10:23:20 +0100 Subject: [PATCH 1089/1650] Fix some QPainter-related deprecation warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit text/qtextdocument.cpp:2666:48: warning: ‘QString QTextCharFormat::anchorName() const’ is deprecated: Use anchorNames() instead [-Wdeprecated-declarations] text/qtextdocumentfragment.cpp:545:87: warning: ‘QString QTextCharFormat::anchorName() const’ is deprecated: Use anchorNames() instead [-Wdeprecated-declarations] text/qtextdocumentfragment.cpp:546:68: warning: ‘QString QTextCharFormat::anchorName() const’ is deprecated: Use anchorNames() instead [-Wdeprecated-declarations] painting/qpainterpath.cpp:3321:34: warning: ‘void QPainterPath::addRoundRect(const QRectF&, int, int)’ is deprecated: Use addRoundedRect(..., Qt::RelativeSize) instead [-Wdeprecated-declarations] painting/qpainterpath.cpp:3342:48: warning: ‘void QPainterPath::addRoundRect(const QRectF&, int, int)’ is deprecated: Use addRoundedRect(..., Qt::RelativeSize) instead [-Wdeprecated-declarations] painting/qpainterpath.cpp:3366:47: warning: ‘void QPainterPath::addRoundRect(const QRectF&, int)’ is deprecated: Use addRoundedRect(..., Qt::RelativeSize) instead [-Wdeprecated-declarations] painting/qpainter.cpp:4233:49: warning: ‘void QPainter::drawRoundRect(const QRectF&, int, int)’ is deprecated: Use drawRoundedRect(..., Qt::RelativeSize) instead [-Wdeprecated-declarations] painting/qpainter.cpp:8349:27: warning: ‘void QPainter::setMatrixEnabled(bool)’ is deprecated: Use setWorldMatrixEnabled() instead [-Wdeprecated-declarations] painting/qpdf.cpp:1545:28: warning: ‘void QDataStream::unsetDevice()’ is deprecated: Use QDataStream::setDevice(nullptr) instead [-Wdeprecated-declarations] widgets/qtabbar.cpp:2096:17: warning: ‘void QPainter::initFrom(const QPaintDevice*)’ is deprecated: Use begin(QPaintDevice*) instead [-Wdeprecated-declarations] Change-Id: I76d98ea8146e7586d3763a5610781c7736d37204 Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de> --- src/gui/painting/qpainter.cpp | 6 +++--- src/gui/painting/qpainterpath.cpp | 6 +++--- src/gui/painting/qpdf.cpp | 2 +- src/gui/text/qtextdocument.cpp | 6 +++--- src/gui/text/qtextdocumentfragment.cpp | 6 ++++-- src/widgets/widgets/qtabbar.cpp | 1 - 6 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 570f750645..95e6bda78b 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -4219,7 +4219,7 @@ void QPainter::drawRoundRect(const QRectF &r, int xRnd, int yRnd) */ void QPainter::drawRoundRect(const QRect &rect, int xRnd, int yRnd) { - drawRoundRect(QRectF(rect), xRnd, yRnd); + drawRoundedRect(QRectF(rect), xRnd, yRnd, Qt::RelativeSize); } /*! @@ -4233,7 +4233,7 @@ void QPainter::drawRoundRect(const QRect &rect, int xRnd, int yRnd) */ void QPainter::drawRoundRect(int x, int y, int w, int h, int xRnd, int yRnd) { - drawRoundRect(QRectF(x, y, w, h), xRnd, yRnd); + drawRoundedRect(QRectF(x, y, w, h), xRnd, yRnd, Qt::RelativeSize); } #endif @@ -8349,7 +8349,7 @@ void QPainter::resetTransform() d->state->ww = d->state->vw = d->device->metric(QPaintDevice::PdmWidth); d->state->wh = d->state->vh = d->device->metric(QPaintDevice::PdmHeight); d->state->worldMatrix = QTransform(); - setMatrixEnabled(false); + setWorldMatrixEnabled(false); setViewTransformEnabled(false); if (d->extended) d->extended->transformChanged(); diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp index cb8bb9dfcf..42f94d038f 100644 --- a/src/gui/painting/qpainterpath.cpp +++ b/src/gui/painting/qpainterpath.cpp @@ -3318,7 +3318,7 @@ void QPainterPath::addRoundRect(const QRectF &rect, xRnd = int(roundness * rect.height()/rect.width()); else yRnd = int(roundness * rect.width()/rect.height()); - addRoundRect(rect, xRnd, yRnd); + addRoundedRect(rect, xRnd, yRnd, Qt::RelativeSize); } /*! @@ -3339,7 +3339,7 @@ void QPainterPath::addRoundRect(const QRectF &rect, void QPainterPath::addRoundRect(qreal x, qreal y, qreal w, qreal h, int xRnd, int yRnd) { - addRoundRect(QRectF(x, y, w, h), xRnd, yRnd); + addRoundedRect(QRectF(x, y, w, h), xRnd, yRnd, Qt::RelativeSize); } /*! @@ -3363,7 +3363,7 @@ void QPainterPath::addRoundRect(qreal x, qreal y, qreal w, qreal h, void QPainterPath::addRoundRect(qreal x, qreal y, qreal w, qreal h, int roundness) { - addRoundRect(QRectF(x, y, w, h), roundness); + addRoundedRect(QRectF(x, y, w, h), roundness, Qt::RelativeSize); } #endif diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index b23cc903b1..6bdc82a8e9 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -1542,7 +1542,7 @@ bool QPdfEngine::end() Q_D(QPdfEngine); d->writeTail(); - d->stream->unsetDevice(); + d->stream->setDevice(nullptr); qDeleteAll(d->fonts); d->fonts.clear(); diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 4f187c6701..fd3473b32e 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -2663,10 +2663,10 @@ void QTextHtmlExporter::emitFragment(const QTextFragment &fragment) bool closeAnchor = false; if (format.isAnchor()) { - const QString name = format.anchorName(); - if (!name.isEmpty()) { + const auto names = format.anchorNames(); + if (!names.isEmpty()) { html += QLatin1String("<a name=\""); - html += name.toHtmlEscaped(); + html += names.constFirst().toHtmlEscaped(); html += QLatin1String("\"></a>"); } const QString href = format.anchorHref(); diff --git a/src/gui/text/qtextdocumentfragment.cpp b/src/gui/text/qtextdocumentfragment.cpp index e7eaa54a45..d2fe87d560 100644 --- a/src/gui/text/qtextdocumentfragment.cpp +++ b/src/gui/text/qtextdocumentfragment.cpp @@ -542,8 +542,10 @@ void QTextHtmlImporter::import() } } - if (currentNode->charFormat.isAnchor() && !currentNode->charFormat.anchorName().isEmpty()) { - namedAnchors.append(currentNode->charFormat.anchorName()); + if (currentNode->charFormat.isAnchor()) { + const auto names = currentNode->charFormat.anchorNames(); + if (!names.isEmpty()) + namedAnchors.append(names.constFirst()); } if (appendNodeText()) diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp index 05a98fc1a5..b13f4da9d2 100644 --- a/src/widgets/widgets/qtabbar.cpp +++ b/src/widgets/widgets/qtabbar.cpp @@ -2093,7 +2093,6 @@ void QTabBarPrivate::setupMovableTab() grabImage.setDevicePixelRatio(q->devicePixelRatioF()); grabImage.fill(Qt::transparent); QStylePainter p(&grabImage, q); - p.initFrom(q); QStyleOptionTab tab; q->initStyleOption(&tab, pressedIndex); From 1b5a17632efbaf6c1d0eacdda72fad3bc9d5fe13 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Wed, 6 Feb 2019 22:09:33 +0100 Subject: [PATCH 1090/1650] Fix deprecation warnings in widget autotests Fix all deprecation warnings within tests/auto/widgets Change-Id: I854f54c0a1dc0a0086f626b93cd39f63cb1b6033 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> --- .../dialogs/qcolordialog/tst_qcolordialog.cpp | 8 +- .../dialogs/qfiledialog2/tst_qfiledialog2.cpp | 2 +- .../tst_qgraphicsanchorlayout.cpp | 2 +- .../tst_qgraphicsgridlayout.cpp | 2 +- .../qgraphicsitem/tst_qgraphicsitem.cpp | 154 +++++++++--------- .../tst_qgraphicslinearlayout.cpp | 2 +- .../qgraphicsscene/tst_qgraphicsscene.cpp | 112 ++++++------- .../tst_qabstractitemview.cpp | 5 - .../itemviews/qheaderview/tst_qheaderview.cpp | 6 +- .../itemviews/qlistwidget/tst_qlistwidget.cpp | 11 +- .../itemviews/qtableview/tst_qtableview.cpp | 2 +- .../qtablewidget/tst_qtablewidget.cpp | 2 +- .../itemviews/qtreeview/tst_qtreeview.cpp | 2 +- .../itemviews/qtreewidget/tst_qtreewidget.cpp | 19 ++- .../kernel/qapplication/tst_qapplication.cpp | 2 - .../qdesktopwidget/tst_qdesktopwidget.cpp | 5 +- .../auto/widgets/styles/qstyle/tst_qstyle.cpp | 2 +- .../util/qcompleter/tst_qcompleter.cpp | 27 +-- .../qdatetimeedit/tst_qdatetimeedit.cpp | 20 ++- .../auto/widgets/widgets/qmenu/tst_qmenu.cpp | 20 ++- .../widgets/widgets/qmenubar/tst_qmenubar.cpp | 2 +- .../qplaintextedit/tst_qplaintextedit.cpp | 12 +- .../widgets/qtextedit/tst_qtextedit.cpp | 12 +- 23 files changed, 212 insertions(+), 219 deletions(-) diff --git a/tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp b/tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp index 6a0ad4b3a4..413b865f04 100644 --- a/tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp +++ b/tests/auto/widgets/dialogs/qcolordialog/tst_qcolordialog.cpp @@ -116,10 +116,10 @@ void tst_QColorDialog::testGetRgba() #ifdef Q_OS_MAC QEXPECT_FAIL("", "Sending QTest::keyClick to OSX color dialog helper fails, see QTBUG-24320", Continue); #endif - bool ok = false; - QTimer::singleShot(500, this, SLOT(postKeyReturn())); - QColorDialog::getRgba(0xffffffff, &ok); - QVERIFY(ok); + QTimer::singleShot(500, this, &tst_QColorDialog::postKeyReturn); + const QColor color = QColorDialog::getColor(QColor::fromRgba(0xffffffff), nullptr, QString(), + QColorDialog::ShowAlphaChannel); + QVERIFY(color.isValid()); } void tst_QColorDialog::defaultOkButton() diff --git a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp index 20fc7c9a6c..869418371c 100644 --- a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp +++ b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp @@ -486,7 +486,7 @@ protected: parentIndex = source_parent; QString path; - path = parentIndex.child(source_row,0).data(Qt::DisplayRole).toString(); + path = sourceModel()->index(source_row, 0, parentIndex).data(Qt::DisplayRole).toString(); do { path = parentIndex.data(Qt::DisplayRole).toString() + QLatin1Char('/') + path; diff --git a/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index 67e1f9ce30..2f5fc597dc 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -91,7 +91,7 @@ public: { Q_UNUSED(option); Q_UNUSED(widget); - painter->drawRoundRect(rect()); + painter->drawRoundedRect(rect(), 25, 25, Qt::RelativeSize); painter->drawLine(rect().topLeft(), rect().bottomRight()); painter->drawLine(rect().bottomLeft(), rect().topRight()); } diff --git a/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp b/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp index 34646a9074..2f0c43552f 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp @@ -125,7 +125,7 @@ public: { Q_UNUSED(option); Q_UNUSED(widget); - painter->drawRoundRect(rect()); + painter->drawRoundedRect(rect(), 25, 25, Qt::RelativeSize); painter->drawLine(rect().topLeft(), rect().bottomRight()); painter->drawLine(rect().bottomLeft(), rect().topRight()); } diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp index 9a75774927..bca664c05b 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp @@ -301,8 +301,8 @@ private slots: void pos(); void scenePos(); void matrix(); - void sceneMatrix(); - void setMatrix(); + void sceneTransform(); + void setTransform(); void zValue(); void shape(); void contains(); @@ -552,8 +552,8 @@ void tst_QGraphicsItem::construction() QVERIFY(!item->acceptHoverEvents()); QVERIFY(!item->hasFocus()); QCOMPARE(item->pos(), QPointF()); - QCOMPARE(item->matrix(), QMatrix()); - QCOMPARE(item->sceneMatrix(), QMatrix()); + QCOMPARE(item->transform(), QTransform()); + QCOMPARE(item->sceneTransform(), QTransform()); QCOMPARE(item->zValue(), qreal(0)); QCOMPARE(item->sceneBoundingRect(), QRectF()); QCOMPARE(item->shape(), QPainterPath()); @@ -2116,68 +2116,68 @@ void tst_QGraphicsItem::scenePos() void tst_QGraphicsItem::matrix() { QGraphicsLineItem line; - QCOMPARE(line.matrix(), QMatrix()); - line.setMatrix(QMatrix().rotate(90)); - QCOMPARE(line.matrix(), QMatrix().rotate(90)); - line.setMatrix(QMatrix().rotate(90)); - QCOMPARE(line.matrix(), QMatrix().rotate(90)); - line.setMatrix(QMatrix().rotate(90), true); - QCOMPARE(line.matrix(), QMatrix().rotate(180)); - line.setMatrix(QMatrix().rotate(-90), true); - QCOMPARE(line.matrix(), QMatrix().rotate(90)); - line.resetMatrix(); - QCOMPARE(line.matrix(), QMatrix()); + QCOMPARE(line.transform(), QTransform()); + line.setTransform(QTransform().rotate(90)); + QCOMPARE(line.transform(), QTransform().rotate(90)); + line.setTransform(QTransform().rotate(90)); + QCOMPARE(line.transform(), QTransform().rotate(90)); + line.setTransform(QTransform().rotate(90), true); + QCOMPARE(line.transform(), QTransform().rotate(180)); + line.setTransform(QTransform().rotate(-90), true); + QCOMPARE(line.transform(), QTransform().rotate(90)); + line.resetTransform(); + QCOMPARE(line.transform(), QTransform()); line.setTransform(QTransform().rotate(90), true); - QCOMPARE(line.matrix(), QMatrix().rotate(90)); + QCOMPARE(line.transform(), QTransform().rotate(90)); line.setTransform(QTransform().rotate(90), true); - QCOMPARE(line.matrix(), QMatrix().rotate(90).rotate(90)); - line.resetMatrix(); + QCOMPARE(line.transform(), QTransform().rotate(90).rotate(90)); + line.resetTransform(); line.setTransform(QTransform::fromScale(2, 4), true); - QCOMPARE(line.matrix(), QMatrix().scale(2, 4)); + QCOMPARE(line.transform(), QTransform::fromScale(2, 4)); line.setTransform(QTransform::fromScale(2, 4), true); - QCOMPARE(line.matrix(), QMatrix().scale(2, 4).scale(2, 4)); - line.resetMatrix(); + QCOMPARE(line.transform(), QTransform::fromScale(2, 4).scale(2, 4)); + line.resetTransform(); line.setTransform(QTransform().shear(2, 4), true); - QCOMPARE(line.matrix(), QMatrix().shear(2, 4)); + QCOMPARE(line.transform(), QTransform().shear(2, 4)); line.setTransform(QTransform().shear(2, 4), true); - QCOMPARE(line.matrix(), QMatrix().shear(2, 4).shear(2, 4)); - line.resetMatrix(); + QCOMPARE(line.transform(), QTransform().shear(2, 4).shear(2, 4)); + line.resetTransform(); line.setTransform(QTransform::fromTranslate(10, 10), true); - QCOMPARE(line.matrix(), QMatrix().translate(10, 10)); + QCOMPARE(line.transform(), QTransform::fromTranslate(10, 10)); line.setTransform(QTransform::fromTranslate(10, 10), true); - QCOMPARE(line.matrix(), QMatrix().translate(10, 10).translate(10, 10)); - line.resetMatrix(); + QCOMPARE(line.transform(), QTransform::fromTranslate(10, 10).translate(10, 10)); + line.resetTransform(); } -void tst_QGraphicsItem::sceneMatrix() +void tst_QGraphicsItem::sceneTransform() { QGraphicsLineItem *parent = new QGraphicsLineItem; QGraphicsLineItem *child = new QGraphicsLineItem(QLineF(), parent); - QCOMPARE(parent->sceneMatrix(), QMatrix()); - QCOMPARE(child->sceneMatrix(), QMatrix()); + QCOMPARE(parent->sceneTransform(), QTransform()); + QCOMPARE(child->sceneTransform(), QTransform()); parent->setTransform(QTransform::fromTranslate(10, 10), true); - QCOMPARE(parent->sceneMatrix(), QMatrix().translate(10, 10)); - QCOMPARE(child->sceneMatrix(), QMatrix().translate(10, 10)); + QCOMPARE(parent->sceneTransform(), QTransform().translate(10, 10)); + QCOMPARE(child->sceneTransform(), QTransform().translate(10, 10)); child->setTransform(QTransform::fromTranslate(10, 10), true); - QCOMPARE(parent->sceneMatrix(), QMatrix().translate(10, 10)); - QCOMPARE(child->sceneMatrix(), QMatrix().translate(20, 20)); + QCOMPARE(parent->sceneTransform(), QTransform().translate(10, 10)); + QCOMPARE(child->sceneTransform(), QTransform().translate(20, 20)); parent->setTransform(QTransform().rotate(90), true); - QCOMPARE(parent->sceneMatrix(), QMatrix().translate(10, 10).rotate(90)); - QCOMPARE(child->sceneMatrix(), QMatrix().translate(10, 10).rotate(90).translate(10, 10)); + QCOMPARE(parent->sceneTransform(), QTransform().translate(10, 10).rotate(90)); + QCOMPARE(child->sceneTransform(), QTransform().translate(10, 10).rotate(90).translate(10, 10)); delete child; delete parent; } -void tst_QGraphicsItem::setMatrix() +void tst_QGraphicsItem::setTransform() { QGraphicsScene scene; QSignalSpy spy(&scene, SIGNAL(changed(QList<QRectF>))); @@ -2190,7 +2190,7 @@ void tst_QGraphicsItem::setMatrix() QCOMPARE(spy.count(), 1); - item.setMatrix(QMatrix().rotate(qreal(12.34))); + item.setTransform(QTransform().rotate(qreal(12.34))); QRectF rotatedRect = scene.sceneRect(); QVERIFY(unrotatedRect != rotatedRect); scene.update(scene.sceneRect()); @@ -2198,7 +2198,7 @@ void tst_QGraphicsItem::setMatrix() QCOMPARE(spy.count(), 2); - item.setMatrix(QMatrix()); + item.setTransform(QTransform()); scene.update(scene.sceneRect()); QApplication::instance()->processEvents(); @@ -2485,25 +2485,25 @@ void tst_QGraphicsItem::collidesWith_item() void tst_QGraphicsItem::collidesWith_path_data() { QTest::addColumn<QPointF>("pos"); - QTest::addColumn<QMatrix>("matrix"); + QTest::addColumn<QTransform>("transform"); QTest::addColumn<QPainterPath>("shape"); QTest::addColumn<bool>("rectCollides"); QTest::addColumn<bool>("ellipseCollides"); - QTest::newRow("nothing") << QPointF(0, 0) << QMatrix() << QPainterPath() << false << false; + QTest::newRow("nothing") << QPointF(0, 0) << QTransform() << QPainterPath() << false << false; QPainterPath rect; rect.addRect(0, 0, 20, 20); - QTest::newRow("rect1") << QPointF(0, 0) << QMatrix() << rect << true << true; - QTest::newRow("rect2") << QPointF(0, 0) << QMatrix().translate(21, 21) << rect << false << false; - QTest::newRow("rect3") << QPointF(21, 21) << QMatrix() << rect << false << false; + QTest::newRow("rect1") << QPointF(0, 0) << QTransform() << rect << true << true; + QTest::newRow("rect2") << QPointF(0, 0) << QTransform::fromTranslate(21, 21) << rect << false << false; + QTest::newRow("rect3") << QPointF(21, 21) << QTransform() << rect << false << false; } void tst_QGraphicsItem::collidesWith_path() { QFETCH(QPointF, pos); - QFETCH(QMatrix, matrix); + QFETCH(QTransform, transform); QFETCH(QPainterPath, shape); QFETCH(bool, rectCollides); QFETCH(bool, ellipseCollides); @@ -2512,12 +2512,12 @@ void tst_QGraphicsItem::collidesWith_path() QGraphicsEllipseItem ellipse(QRectF(0, 0, 20, 20)); rect.setPos(pos); - rect.setMatrix(matrix); + rect.setTransform(transform); ellipse.setPos(pos); - ellipse.setMatrix(matrix); + ellipse.setTransform(transform); - QPainterPath mappedShape = rect.sceneMatrix().inverted().map(shape); + QPainterPath mappedShape = rect.sceneTransform().inverted().map(shape); if (rectCollides) QVERIFY(rect.collidesWithPath(mappedShape)); @@ -2742,35 +2742,35 @@ void tst_QGraphicsItem::mapFromToParent() item4->setPos(10, 10); for (int i = 0; i < 4; ++i) { - QMatrix matrix; - matrix.rotate(i * 90); - matrix.translate(i * 100, -i * 100); - matrix.scale(2, 4); - item1->setMatrix(matrix); + QTransform transform; + transform.rotate(i * 90); + transform.translate(i * 100, -i * 100); + transform.scale(2, 4); + item1->setTransform(transform); - QCOMPARE(item1->mapToParent(QPointF(0, 0)), item1->pos() + matrix.map(QPointF(0, 0))); + QCOMPARE(item1->mapToParent(QPointF(0, 0)), item1->pos() + transform.map(QPointF(0, 0))); QCOMPARE(item2->mapToParent(QPointF(0, 0)), item2->pos()); QCOMPARE(item3->mapToParent(QPointF(0, 0)), item3->pos()); QCOMPARE(item4->mapToParent(QPointF(0, 0)), item4->pos()); - QCOMPARE(item1->mapToParent(QPointF(10, -10)), item1->pos() + matrix.map(QPointF(10, -10))); + QCOMPARE(item1->mapToParent(QPointF(10, -10)), item1->pos() + transform.map(QPointF(10, -10))); QCOMPARE(item2->mapToParent(QPointF(10, -10)), item2->pos() + QPointF(10, -10)); QCOMPARE(item3->mapToParent(QPointF(10, -10)), item3->pos() + QPointF(10, -10)); QCOMPARE(item4->mapToParent(QPointF(10, -10)), item4->pos() + QPointF(10, -10)); - QCOMPARE(item1->mapToParent(QPointF(-10, 10)), item1->pos() + matrix.map(QPointF(-10, 10))); + QCOMPARE(item1->mapToParent(QPointF(-10, 10)), item1->pos() + transform.map(QPointF(-10, 10))); QCOMPARE(item2->mapToParent(QPointF(-10, 10)), item2->pos() + QPointF(-10, 10)); QCOMPARE(item3->mapToParent(QPointF(-10, 10)), item3->pos() + QPointF(-10, 10)); QCOMPARE(item4->mapToParent(QPointF(-10, 10)), item4->pos() + QPointF(-10, 10)); - QCOMPARE(item1->mapFromParent(item1->pos()), matrix.inverted().map(QPointF(0, 0))); + QCOMPARE(item1->mapFromParent(item1->pos()), transform.inverted().map(QPointF(0, 0))); QCOMPARE(item2->mapFromParent(item2->pos()), QPointF(0, 0)); QCOMPARE(item3->mapFromParent(item3->pos()), QPointF(0, 0)); QCOMPARE(item4->mapFromParent(item4->pos()), QPointF(0, 0)); QCOMPARE(item1->mapFromParent(item1->pos() + QPointF(10, -10)), - matrix.inverted().map(QPointF(10, -10))); + transform.inverted().map(QPointF(10, -10))); QCOMPARE(item2->mapFromParent(item2->pos() + QPointF(10, -10)), QPointF(10, -10)); QCOMPARE(item3->mapFromParent(item3->pos() + QPointF(10, -10)), QPointF(10, -10)); QCOMPARE(item4->mapFromParent(item4->pos() + QPointF(10, -10)), QPointF(10, -10)); QCOMPARE(item1->mapFromParent(item1->pos() + QPointF(-10, 10)), - matrix.inverted().map(QPointF(-10, 10))); + transform.inverted().map(QPointF(-10, 10))); QCOMPARE(item2->mapFromParent(item2->pos() + QPointF(-10, 10)), QPointF(-10, 10)); QCOMPARE(item3->mapFromParent(item3->pos() + QPointF(-10, 10)), QPointF(-10, 10)); QCOMPARE(item4->mapFromParent(item4->pos() + QPointF(-10, 10)), QPointF(-10, 10)); @@ -2820,8 +2820,8 @@ void tst_QGraphicsItem::mapFromToScene() QCOMPARE(item4->mapFromScene(410, 400), QPointF(10, 0)); // Rotate item1 90 degrees clockwise - QMatrix matrix; matrix.rotate(90); - item1->setMatrix(matrix); + QTransform transform; transform.rotate(90); + item1->setTransform(transform); QCOMPARE(item1->pos(), item1->mapToParent(0, 0)); QCOMPARE(item2->pos(), item2->mapToParent(0, 0)); QCOMPARE(item3->pos(), item3->mapToParent(0, 0)); @@ -2848,7 +2848,7 @@ void tst_QGraphicsItem::mapFromToScene() QCOMPARE(item4->mapFromScene(-200, 410), QPointF(10, 0)); // Rotate item2 90 degrees clockwise - item2->setMatrix(matrix); + item2->setTransform(transform); QCOMPARE(item1->pos(), item1->mapToParent(0, 0)); QCOMPARE(item2->pos(), item2->mapToParent(0, 0)); QCOMPARE(item3->pos(), item3->mapToParent(0, 0)); @@ -2875,10 +2875,10 @@ void tst_QGraphicsItem::mapFromToScene() QCOMPARE(item4->mapFromScene(-210, 0), QPointF(10, 0)); // Translate item3 50 points, then rotate 90 degrees counterclockwise - QMatrix matrix2; - matrix2.translate(50, 0); - matrix2.rotate(-90); - item3->setMatrix(matrix2); + QTransform transform2; + transform2.translate(50, 0); + transform2.rotate(-90); + item3->setTransform(transform2); QCOMPARE(item1->pos(), item1->mapToParent(0, 0)); QCOMPARE(item2->pos(), item2->mapToParent(0, 0)); QCOMPARE(item3->pos(), item3->mapToParent(0, 0) - QPointF(50, 0)); @@ -2928,9 +2928,9 @@ void tst_QGraphicsItem::mapFromToItem() QCOMPARE(item3->mapFromItem(item2, 0, 0), QPointF(0, -200)); QCOMPARE(item4->mapFromItem(item3, 0, 0), QPointF(200, 0)); - QMatrix matrix; - matrix.translate(100, 100); - item1->setMatrix(matrix); + QTransform transform; + transform.translate(100, 100); + item1->setTransform(transform); QCOMPARE(item1->mapFromItem(item2, 0, 0), QPointF(100, -100)); QCOMPARE(item2->mapFromItem(item3, 0, 0), QPointF(0, 200)); @@ -2941,11 +2941,11 @@ void tst_QGraphicsItem::mapFromToItem() QCOMPARE(item3->mapFromItem(item2, 0, 0), QPointF(0, -200)); QCOMPARE(item4->mapFromItem(item3, 0, 0), QPointF(200, 0)); - matrix.rotate(90); - item1->setMatrix(matrix); - item2->setMatrix(matrix); - item3->setMatrix(matrix); - item4->setMatrix(matrix); + transform.rotate(90); + item1->setTransform(transform); + item2->setTransform(transform); + item3->setTransform(transform); + item4->setTransform(transform); QCOMPARE(item1->mapFromItem(item2, 0, 0), QPointF(0, -200)); QCOMPARE(item2->mapFromItem(item3, 0, 0), QPointF(200, 0)); @@ -4433,9 +4433,12 @@ protected: case QGraphicsItem::ItemPositionHasChanged: break; case QGraphicsItem::ItemMatrixChange: { +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED QVariant variant; variant.setValue<QMatrix>(matrix()); oldValues << variant; +QT_WARNING_POP } break; case QGraphicsItem::ItemTransformChange: { @@ -4556,6 +4559,8 @@ void tst_QGraphicsItem::itemChange() QCOMPARE(tester.isEnabled(), true); } { +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED // QDesktopWidget::screen() // ItemMatrixChange / ItemTransformHasChanged tester.itemChangeReturnValue.setValue<QMatrix>(QMatrix().rotate(90)); tester.setMatrix(QMatrix().translate(50, 0), true); @@ -4570,6 +4575,7 @@ void tst_QGraphicsItem::itemChange() variant.setValue<QMatrix>(QMatrix()); QCOMPARE(tester.oldValues.last(), variant); QCOMPARE(tester.matrix(), QMatrix().rotate(90)); +QT_WARNING_POP } { tester.resetTransform(); diff --git a/tests/auto/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp b/tests/auto/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp index f9b6fe3ebd..9369470ce5 100644 --- a/tests/auto/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp @@ -150,7 +150,7 @@ public: Q_UNUSED(option); Q_UNUSED(widget); painter->setBrush(m_brush); - painter->drawRoundRect(rect()); + painter->drawRoundedRect(rect(), 25, 25, Qt::RelativeSize); } void setSizeHint(Qt::SizeHint which, const QSizeF &size) { diff --git a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp index 48488abfb8..46f1d5df5c 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp @@ -112,14 +112,14 @@ protected: painter->setOpacity(0.75); painter->setPen(Qt::NoPen); painter->setBrush(Qt::darkGray); - painter->drawRoundRect(boundingRect().adjusted(3, 3, -3, -3), Qt::darkGray); + painter->drawRoundedRect(boundingRect().adjusted(3, 3, -3, -3), 25, 25, Qt::RelativeSize); painter->setPen(Qt::black); if (isHovered) { - painter->setBrush(QColor(Qt::blue).light(120)); + painter->setBrush(QColor(Qt::blue).lighter(120)); } else { painter->setBrush(Qt::gray); } - painter->drawRoundRect(boundingRect().adjusted(0, 0, -5, -5)); + painter->drawRoundedRect(boundingRect().adjusted(0, 0, -5, -5), 25, 25, Qt::RelativeSize); } }; @@ -233,7 +233,6 @@ private slots: void tabFocus_sceneWithFocusWidgets(); void tabFocus_sceneWithNestedFocusWidgets(); void style(); - void sorting_data(); void sorting(); void insertionOrder(); void changedSignal_data(); @@ -459,41 +458,41 @@ void tst_QGraphicsScene::items() void tst_QGraphicsScene::itemsBoundingRect_data() { QTest::addColumn<QList<QRectF> >("rects"); - QTest::addColumn<QMatrix>("matrix"); + QTest::addColumn<QTransform>("transform"); QTest::addColumn<QRectF>("boundingRect"); - QMatrix transformationMatrix; - transformationMatrix.translate(50, -50); - transformationMatrix.scale(2, 2); - transformationMatrix.rotate(90); + QTransform transformation; + transformation.translate(50, -50); + transformation.scale(2, 2); + transformation.rotate(90); QTest::newRow("none") << QList<QRectF>() - << QMatrix() + << QTransform() << QRectF(); QTest::newRow("{{0, 0, 10, 10}}") << (QList<QRectF>() << QRectF(0, 0, 10, 10)) - << QMatrix() + << QTransform() << QRectF(0, 0, 10, 10); QTest::newRow("{{-10, -10, 10, 10}}") << (QList<QRectF>() << QRectF(-10, -10, 10, 10)) - << QMatrix() + << QTransform() << QRectF(-10, -10, 10, 10); QTest::newRow("{{-1000, -1000, 1, 1}, {-10, -10, 10, 10}}") << (QList<QRectF>() << QRectF(-1000, -1000, 1, 1) << QRectF(-10, -10, 10, 10)) - << QMatrix() + << QTransform() << QRectF(-1000, -1000, 1000, 1000); QTest::newRow("transformed {{0, 0, 10, 10}}") << (QList<QRectF>() << QRectF(0, 0, 10, 10)) - << transformationMatrix + << transformation << QRectF(30, -50, 20, 20); QTest::newRow("transformed {{-10, -10, 10, 10}}") << (QList<QRectF>() << QRectF(-10, -10, 10, 10)) - << transformationMatrix + << transformation << QRectF(50, -70, 20, 20); QTest::newRow("transformed {{-1000, -1000, 1, 1}, {-10, -10, 10, 10}}") << (QList<QRectF>() << QRectF(-1000, -1000, 1, 1) << QRectF(-10, -10, 10, 10)) - << transformationMatrix + << transformation << QRectF(50, -2050, 2000, 2000); QList<QRectF> all; @@ -501,18 +500,18 @@ void tst_QGraphicsScene::itemsBoundingRect_data() all << QRectF(randomX[i], randomY[i], 10, 10); QTest::newRow("all") << all - << QMatrix() + << QTransform() << QRectF(-980, -994, 1988, 1983); QTest::newRow("transformed all") << all - << transformationMatrix + << transformation << QRectF(-1928, -2010, 3966, 3976); } void tst_QGraphicsScene::itemsBoundingRect() { QFETCH(QList<QRectF>, rects); - QFETCH(QMatrix, matrix); + QFETCH(QTransform, transform); QFETCH(QRectF, boundingRect); QGraphicsScene scene; @@ -522,7 +521,7 @@ void tst_QGraphicsScene::itemsBoundingRect() path.addRect(rect); QGraphicsPathItem *item = scene.addPath(path); item->setPen(QPen(Qt::black, 0)); - item->setMatrix(matrix); + item->setTransform(transform); } QCOMPARE(scene.itemsBoundingRect(), boundingRect); @@ -2502,7 +2501,7 @@ void tst_QGraphicsScene::render_data() QTest::addColumn<QRectF>("targetRect"); QTest::addColumn<QRectF>("sourceRect"); QTest::addColumn<Qt::AspectRatioMode>("aspectRatioMode"); - QTest::addColumn<QMatrix>("matrix"); + QTest::addColumn<QTransform>("transform"); QTest::addColumn<QPainterPath>("clip"); QPainterPath clip_rect; @@ -2512,61 +2511,61 @@ void tst_QGraphicsScene::render_data() clip_ellipse.addEllipse(100,50,150,200); QTest::newRow("all-all-untransformed") << QRectF() << QRectF() - << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); + << Qt::IgnoreAspectRatio << QTransform() << QPainterPath(); QTest::newRow("all-topleft-untransformed") << QRectF(0, 0, 150, 150) - << QRectF() << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); + << QRectF() << Qt::IgnoreAspectRatio << QTransform() << QPainterPath(); QTest::newRow("all-topright-untransformed") << QRectF(150, 0, 150, 150) - << QRectF() << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); + << QRectF() << Qt::IgnoreAspectRatio << QTransform() << QPainterPath(); QTest::newRow("all-bottomleft-untransformed") << QRectF(0, 150, 150, 150) - << QRectF() << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); + << QRectF() << Qt::IgnoreAspectRatio << QTransform() << QPainterPath(); QTest::newRow("all-bottomright-untransformed") << QRectF(150, 150, 150, 150) - << QRectF() << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); + << QRectF() << Qt::IgnoreAspectRatio << QTransform() << QPainterPath(); QTest::newRow("topleft-all-untransformed") << QRectF() << QRectF(-10, -10, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); + << Qt::IgnoreAspectRatio << QTransform() << QPainterPath(); QTest::newRow("topright-all-untransformed") << QRectF() << QRectF(0, -10, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); + << Qt::IgnoreAspectRatio << QTransform() << QPainterPath(); QTest::newRow("bottomleft-all-untransformed") << QRectF() << QRectF(-10, 0, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); + << Qt::IgnoreAspectRatio << QTransform() << QPainterPath(); QTest::newRow("bottomright-all-untransformed") << QRectF() << QRectF(0, 0, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); + << Qt::IgnoreAspectRatio << QTransform() << QPainterPath(); QTest::newRow("topleft-topleft-untransformed") << QRectF(0, 0, 150, 150) << QRectF(-10, -10, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); + << Qt::IgnoreAspectRatio << QTransform() << QPainterPath(); QTest::newRow("topright-topleft-untransformed") << QRectF(150, 0, 150, 150) << QRectF(-10, -10, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); + << Qt::IgnoreAspectRatio << QTransform() << QPainterPath(); QTest::newRow("bottomleft-topleft-untransformed") << QRectF(0, 150, 150, 150) << QRectF(-10, -10, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); + << Qt::IgnoreAspectRatio << QTransform() << QPainterPath(); QTest::newRow("bottomright-topleft-untransformed") << QRectF(150, 150, 150, 150) << QRectF(-10, -10, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); + << Qt::IgnoreAspectRatio << QTransform() << QPainterPath(); QTest::newRow("top-topleft-untransformed") << QRectF(0, 0, 300, 150) << QRectF(-10, -10, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); + << Qt::IgnoreAspectRatio << QTransform() << QPainterPath(); QTest::newRow("bottom-topleft-untransformed") << QRectF(0, 150, 300, 150) << QRectF(-10, -10, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); + << Qt::IgnoreAspectRatio << QTransform() << QPainterPath(); QTest::newRow("left-topleft-untransformed") << QRectF(0, 0, 150, 300) << QRectF(-10, -10, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); + << Qt::IgnoreAspectRatio << QTransform() << QPainterPath(); QTest::newRow("right-topleft-untransformed") << QRectF(150, 0, 150, 300) << QRectF(-10, -10, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); + << Qt::IgnoreAspectRatio << QTransform() << QPainterPath(); QTest::newRow("top-bottomright-untransformed") << QRectF(0, 0, 300, 150) << QRectF(0, 0, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); + << Qt::IgnoreAspectRatio << QTransform() << QPainterPath(); QTest::newRow("bottom-bottomright-untransformed") << QRectF(0, 150, 300, 150) << QRectF(0, 0, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); + << Qt::IgnoreAspectRatio << QTransform() << QPainterPath(); QTest::newRow("left-bottomright-untransformed") << QRectF(0, 0, 150, 300) << QRectF(0, 0, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); + << Qt::IgnoreAspectRatio << QTransform() << QPainterPath(); QTest::newRow("right-bottomright-untransformed") << QRectF(150, 0, 150, 300) << QRectF(0, 0, 10, 10) - << Qt::IgnoreAspectRatio << QMatrix() << QPainterPath(); + << Qt::IgnoreAspectRatio << QTransform() << QPainterPath(); QTest::newRow("all-all-45-deg-right") << QRectF() << QRectF() - << Qt::IgnoreAspectRatio << QMatrix().rotate(-45) << QPainterPath(); + << Qt::IgnoreAspectRatio << QTransform().rotate(-45) << QPainterPath(); QTest::newRow("all-all-45-deg-left") << QRectF() << QRectF() - << Qt::IgnoreAspectRatio << QMatrix().rotate(45) << QPainterPath(); + << Qt::IgnoreAspectRatio << QTransform().rotate(45) << QPainterPath(); QTest::newRow("all-all-scale-2x") << QRectF() << QRectF() - << Qt::IgnoreAspectRatio << QMatrix().scale(2, 2) << QPainterPath(); + << Qt::IgnoreAspectRatio << QTransform::fromScale(2, 2) << QPainterPath(); QTest::newRow("all-all-translate-50-0") << QRectF() << QRectF() - << Qt::IgnoreAspectRatio << QMatrix().translate(50, 0) << QPainterPath(); + << Qt::IgnoreAspectRatio << QTransform::fromTranslate(50, 0) << QPainterPath(); QTest::newRow("all-all-translate-0-50") << QRectF() << QRectF() - << Qt::IgnoreAspectRatio << QMatrix().translate(0, 50) << QPainterPath(); + << Qt::IgnoreAspectRatio << QTransform::fromTranslate(0, 50) << QPainterPath(); QTest::newRow("all-all-untransformed-clip-rect") << QRectF() << QRectF() - << Qt::IgnoreAspectRatio << QMatrix() << clip_rect; + << Qt::IgnoreAspectRatio << QTransform() << clip_rect; QTest::newRow("all-all-untransformed-clip-ellipse") << QRectF() << QRectF() - << Qt::IgnoreAspectRatio << QMatrix() << clip_ellipse; + << Qt::IgnoreAspectRatio << QTransform() << clip_ellipse; } void tst_QGraphicsScene::render() @@ -2574,7 +2573,7 @@ void tst_QGraphicsScene::render() QFETCH(QRectF, targetRect); QFETCH(QRectF, sourceRect); QFETCH(Qt::AspectRatioMode, aspectRatioMode); - QFETCH(QMatrix, matrix); + QFETCH(QTransform, transform); QFETCH(QPainterPath, clip); QPixmap pix(30, 30); @@ -2602,7 +2601,7 @@ void tst_QGraphicsScene::render() painter.setPen(QPen(Qt::darkGray, 2)); painter.drawLine(0, 150, 300, 150); painter.drawLine(150, 0, 150, 300); - painter.setMatrix(matrix); + painter.setTransform(transform); if (!clip.isEmpty()) painter.setClipPath(clip); scene.render(&painter, targetRect, sourceRect, aspectRatioMode); painter.end(); @@ -3519,20 +3518,9 @@ void tst_QGraphicsScene::task250680_childClip() QCOMPARE(scene.items(QRectF(320, 240, 5, 5)).size(), 2); } -void tst_QGraphicsScene::sorting_data() -{ - QTest::addColumn<bool>("cache"); - - QTest::newRow("Normal sorting") << false; - QTest::newRow("Cached sorting") << true; -} - void tst_QGraphicsScene::sorting() { - QFETCH(bool, cache); - QGraphicsScene scene; - scene.setSortCacheEnabled(cache); QGraphicsRectItem *t_1 = new QGraphicsRectItem(0, 0, 50, 50); QGraphicsRectItem *c_1 = new QGraphicsRectItem(0, 0, 40, 40, t_1); diff --git a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp index 45c86800d6..6f7dca86eb 100644 --- a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp +++ b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp @@ -502,11 +502,6 @@ void tst_QAbstractItemView::basic_tests(QAbstractItemView *view) view->commitData(0); view->editorDestroyed(0); - view->setHorizontalStepsPerItem(2); - view->horizontalStepsPerItem(); - view->setVerticalStepsPerItem(2); - view->verticalStepsPerItem(); - // Will assert as it should // view->setIndexWidget(QModelIndex(), 0); diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp index 4841ceb116..eaf75e7494 100644 --- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp +++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp @@ -85,7 +85,8 @@ class XResetModel : public QStandardItemModel blockSignals(true); bool r = QStandardItemModel::removeRows(row, count, parent); blockSignals(false); - emit reset(); + emit beginResetModel(); + emit endResetModel(); return r; } virtual bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) @@ -93,7 +94,8 @@ class XResetModel : public QStandardItemModel blockSignals(true); bool r = QStandardItemModel::insertRows(row, count, parent); blockSignals(false); - emit reset(); + emit beginResetModel(); + emit endResetModel(); return r; } }; diff --git a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp index 0c1b20d61a..30afa69c31 100644 --- a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp +++ b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp @@ -403,14 +403,17 @@ void tst_QListWidget::closePersistentEditor() void tst_QListWidget::setItemHidden() { #if QT_DEPRECATED_SINCE(5, 13) +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED // Boundary checking - testWidget->setItemHidden(0, true); - testWidget->setItemHidden(0, false); + testWidget->setItemHidden(nullptr, true); + testWidget->setItemHidden(nullptr, false); +QT_WARNING_POP #endif int totalHidden = 0; for (int i = 0; i < testWidget->model()->rowCount(); ++i) - if (testWidget->isItemHidden(testWidget->item(i))) + if (testWidget->item(i)->isHidden()) totalHidden++; QListWidgetItem *item = new QListWidgetItem(QString::number(testWidget->count())); @@ -419,7 +422,7 @@ void tst_QListWidget::setItemHidden() // Check that nothing else changed int newTotal = 0; for (int i = 0; i < testWidget->model()->rowCount(); ++i) - if (testWidget->isItemHidden(testWidget->item(i))) + if (testWidget->item(i)->isHidden()) newTotal++; QCOMPARE(newTotal, totalHidden); diff --git a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp index e8ee735915..b1ddc6e7a2 100644 --- a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp +++ b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp @@ -4253,7 +4253,7 @@ void tst_QTableView::task234926_setHeaderSorting() QStringList sortedDataA = data; QStringList sortedDataD = data; std::sort(sortedDataA.begin(), sortedDataA.end()); - std::sort(sortedDataD.begin(), sortedDataD.end(), qGreater<QString>()); + std::sort(sortedDataD.begin(), sortedDataD.end(), std::greater<QString>()); model.setStringList(data); QTableView view; view.setModel(&model); diff --git a/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp b/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp index f97c43e347..c2de5c2761 100644 --- a/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp +++ b/tests/auto/widgets/itemviews/qtablewidget/tst_qtablewidget.cpp @@ -1567,7 +1567,7 @@ void tst_QTableWidget::task262056_sortDuplicate() } testWidget->sortItems(0, Qt::AscendingOrder); QSignalSpy layoutChangedSpy(testWidget->model(), SIGNAL(layoutChanged())); - testWidget->item(3,0)->setBackgroundColor(Qt::red); + testWidget->item(3,0)->setBackground(Qt::red); QCOMPARE(layoutChangedSpy.count(),0); diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index ece2e9a220..ae968d34dd 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -1796,7 +1796,7 @@ void tst_QTreeView::keyboardNavigation() case Qt::Key_Down: if (view.isExpanded(index)) { row = 0; - index = index.child(row, column); + index = model.index(row, column, index); } else { row = qMin(rows - 1, row + 1); index = index.sibling(row, column); diff --git a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp index f2ed72be52..33d4f3bf91 100644 --- a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp +++ b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp @@ -874,9 +874,12 @@ void tst_QTreeWidget::selectedItems() } #if QT_DEPRECATED_SINCE(5, 13) +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED // Possible to select null without crashing? - testWidget->setItemSelected(0, true); - QVERIFY(!testWidget->isItemSelected(0)); + testWidget->setItemSelected(nullptr, true); + QVERIFY(!testWidget->isItemSelected(nullptr)); +QT_WARNING_POP #endif // unselect @@ -1876,14 +1879,14 @@ void tst_QTreeWidget::setData() item->setBackground(j, backgroundColor); QCOMPARE(itemChangedSpy.count(), 0); - QColor textColor((i == 1) ? Qt::green : Qt::cyan); - item->setTextColor(j, textColor); - QCOMPARE(item->textColor(j), textColor); + const QColor foregroundColor((i == 1) ? Qt::green : Qt::cyan); + item->setForeground(j, foregroundColor); + QCOMPARE(item->foreground(j), foregroundColor); QCOMPARE(itemChangedSpy.count(), 1); args = itemChangedSpy.takeFirst(); QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item); QCOMPARE(qvariant_cast<int>(args.at(1)), j); - item->setTextColor(j, textColor); + item->setForeground(j, foregroundColor); QCOMPARE(itemChangedSpy.count(), 0); Qt::CheckState checkState((i == 1) ? Qt::PartiallyChecked : Qt::Checked); @@ -1905,7 +1908,7 @@ void tst_QTreeWidget::setData() QCOMPARE(item->font(j), font); QCOMPARE(item->textAlignment(j), int(textAlignment)); QCOMPARE(item->background(j).color(), backgroundColor); - QCOMPARE(item->textColor(j), textColor); + QCOMPARE(item->foreground(j), foregroundColor); QCOMPARE(item->checkState(j), checkState); QCOMPARE(qvariant_cast<QString>(item->data(j, Qt::DisplayRole)), text); @@ -1917,7 +1920,7 @@ void tst_QTreeWidget::setData() QCOMPARE(qvariant_cast<QFont>(item->data(j, Qt::FontRole)), font); QCOMPARE(qvariant_cast<int>(item->data(j, Qt::TextAlignmentRole)), int(textAlignment)); QCOMPARE(qvariant_cast<QBrush>(item->data(j, Qt::BackgroundRole)), QBrush(backgroundColor)); - QCOMPARE(qvariant_cast<QColor>(item->data(j, Qt::ForegroundRole)), textColor); + QCOMPARE(qvariant_cast<QColor>(item->data(j, Qt::ForegroundRole)), foregroundColor); QCOMPARE(qvariant_cast<int>(item->data(j, Qt::CheckStateRole)), int(checkState)); item->setBackground(j, pixmap); diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp index e2ef5635c2..e57ac77c39 100644 --- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp +++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp @@ -2200,8 +2200,6 @@ void tst_QApplication::abortQuitOnShow() void tst_QApplication::staticFunctions() { QApplication::setStyle(QStringLiteral("blub")); - QApplication::colorSpec(); - QApplication::setColorSpec(42); QApplication::allWidgets(); QApplication::topLevelWidgets(); QApplication::desktop(); diff --git a/tests/auto/widgets/kernel/qdesktopwidget/tst_qdesktopwidget.cpp b/tests/auto/widgets/kernel/qdesktopwidget/tst_qdesktopwidget.cpp index 6f2847974f..90776dfcb2 100644 --- a/tests/auto/widgets/kernel/qdesktopwidget/tst_qdesktopwidget.cpp +++ b/tests/auto/widgets/kernel/qdesktopwidget/tst_qdesktopwidget.cpp @@ -32,6 +32,9 @@ #include <QtGui/QWindow> #include <QDebug> +// the complete class is deprecated +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED class tst_QDesktopWidget : public QObject { Q_OBJECT @@ -163,7 +166,7 @@ void tst_QDesktopWidget::topLevels() QCOMPARE(topLevelDesktopWidgets, 0); QCOMPARE(topLevelDesktopWindows, 0); } +QT_WARNING_POP QTEST_MAIN(tst_QDesktopWidget) #include "tst_qdesktopwidget.moc" - diff --git a/tests/auto/widgets/styles/qstyle/tst_qstyle.cpp b/tests/auto/widgets/styles/qstyle/tst_qstyle.cpp index 587e8a080d..a552c91928 100644 --- a/tests/auto/widgets/styles/qstyle/tst_qstyle.cpp +++ b/tests/auto/widgets/styles/qstyle/tst_qstyle.cpp @@ -197,7 +197,7 @@ void tst_QStyle::drawItemPixmap() const QRgb green = QColor(Qt::green).rgb(); QVERIFY(image.reinterpretAsFormat(QImage::Format_RGB32)); const QRgb *bits = reinterpret_cast<const QRgb *>(image.constBits()); - const QRgb *end = bits + image.byteCount() / sizeof(QRgb); + const QRgb *end = bits + image.sizeInBytes() / sizeof(QRgb); #ifdef Q_OS_WINRT QEXPECT_FAIL("", "QWidget::resize does not work on WinRT", Continue); #endif diff --git a/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp b/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp index ad64f1aef7..8bb16cc9d1 100644 --- a/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp +++ b/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp @@ -1595,27 +1595,16 @@ void tst_QCompleter::task247560_keyboardNavigation() } // Helpers for QTBUG_14292_filesystem: Recursion helper for below recurseTreeModel -template <class Function> -bool recurseTreeModelIndex(const QModelIndex &idx, Function f, int depth = 0) -{ - if (f(idx, depth)) - return true; - const int rowCount = idx.model()->rowCount(idx); - for (int row = 0; row < rowCount; ++row) - if (recurseTreeModelIndex(idx.child(row, 0), f, depth + 1)) - return true; - return false; -} - // Function to recurse over a tree model applying a function // taking index and depth, returning true to terminate recursion. - template <class Function> -bool recurseTreeModel(const QAbstractItemModel &m, Function f) +bool recurseTreeModel(const QAbstractItemModel &m, const QModelIndex &idx, Function f, int depth = 0) { - const int rowCount = m.rowCount(QModelIndex()); + if (idx.isValid() && f(idx, depth)) + return true; + const int rowCount = m.rowCount(idx); for (int row = 0; row < rowCount; ++row) - if (recurseTreeModelIndex(m.index(row, 0, QModelIndex()), f)) + if (recurseTreeModel(m, m.index(row, 0, idx), f, depth + 1)) return true; return false; } @@ -1658,7 +1647,7 @@ QDebug operator<<(QDebug d, const QAbstractItemModel &m) { QDebug dns = d.nospace(); dns << '\n'; - recurseTreeModel(m, DebugFunction(dns)); + recurseTreeModel(m, QModelIndex(), DebugFunction(dns)); return d; } @@ -1671,8 +1660,8 @@ static const char testDir2[] = "holla"; static inline bool testFileSystemReady(const QAbstractItemModel &model) { - return recurseTreeModel(model, SearchFunction(QLatin1String(testDir1), QFileSystemModel::FileNameRole)) - && recurseTreeModel(model, SearchFunction(QLatin1String(testDir2), QFileSystemModel::FileNameRole)); + return recurseTreeModel(model, QModelIndex(), SearchFunction(QLatin1String(testDir1), QFileSystemModel::FileNameRole)) + && recurseTreeModel(model, QModelIndex(), SearchFunction(QLatin1String(testDir2), QFileSystemModel::FileNameRole)); } void tst_QCompleter::QTBUG_14292_filesystem() diff --git a/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp b/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp index 20aad6ba97..b5ef454b14 100644 --- a/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp +++ b/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp @@ -823,7 +823,7 @@ void tst_QDateTimeEdit::displayFormat_data() << QString("31 12 2999::59:59:03") << dt; QTest::newRow("valid-2") << QString("hh-dd-mm-MM-yy") << true << QString("03-31-59-12-99") << dt; QTest::newRow("valid-3") << QString("ddd MM d yyyy::ss:mm:hh") << true - << QDate::shortDayName(2) + " 12 31 2999::59:59:03" << dt; + << QLocale::system().dayName(2, QLocale::ShortFormat) + " 12 31 2999::59:59:03" << dt; QTest::newRow("valid-4") << QString("hh-dd-mm-MM-yyyy") << true << QString("03-31-59-12-2999") << dt; QTest::newRow("invalid-0") << QString("yyyy.MM.yy") << true << QString("2999.12.99") << dt; QTest::newRow("invalid-1") << QString("y") << false << QString() << dt; @@ -2611,9 +2611,13 @@ void tst_QDateTimeEdit::weirdCase() void tst_QDateTimeEdit::newCase() { - if (QDate::shortMonthName(6) != "Jun" || QDate::shortMonthName(7) != "Jul" || - QDate::longMonthName(6) != "June" || QDate::longMonthName(7) != "July") + const auto locale = QLocale::system(); + if (locale.monthName(6, QLocale::ShortFormat) != "Jun" || + locale.monthName(7, QLocale::ShortFormat) != "Jul" || + locale.monthName(6, QLocale::LongFormat) != "June" || + locale.monthName(7, QLocale::LongFormat) != "July") { QSKIP("This test only works in English"); + } testWidget->setDisplayFormat("MMMM'a'MbMMMcMM"); testWidget->setDate(QDate(2005, 6, 1)); @@ -2656,12 +2660,12 @@ void tst_QDateTimeEdit::newCase2() testWidget->setDate(QDate(2005, 8, 8)); QTest::keyClick(testWidget, Qt::Key_Return); QTest::keyClick(testWidget, Qt::Key_Backspace); - QCOMPARE(testWidget->text(), QString(" 2005-08-08 ") + QDate::longMonthName(8)); + QCOMPARE(testWidget->text(), QString(" 2005-08-08 ") + QLocale::system().monthName(8, QLocale::LongFormat)); } void tst_QDateTimeEdit::newCase3() { - if (!QDate::longMonthName(1).startsWith("Januar")) + if (!QLocale::system().monthName(1, QLocale::LongFormat).startsWith("Januar")) QSKIP("This test does not work in this locale"); testWidget->setDisplayFormat("dd MMMM yyyy"); @@ -2681,7 +2685,7 @@ void tst_QDateTimeEdit::newCase3() void tst_QDateTimeEdit::cursorPos() { - if (QDate::longMonthName(1) != "January") + if (QLocale::system().monthName(1, QLocale::LongFormat) != "January") QSKIP("This test only works in English"); testWidget->setDisplayFormat("dd MMMM yyyy"); @@ -3017,7 +3021,7 @@ void tst_QDateTimeEdit::yyTest() testWidget->setDate(testWidget->minimumDate()); testWidget->setCurrentSection(QDateTimeEdit::YearSection); - QString jan = QDate::shortMonthName(1); + QString jan = QLocale::system().monthName(1, QLocale::ShortFormat); QCOMPARE(testWidget->lineEdit()->displayText(), "01-" + jan + "-05"); QTest::keyClick(testWidget, Qt::Key_Up); QCOMPARE(testWidget->lineEdit()->displayText(), "01-" + jan + "-06"); @@ -3130,7 +3134,7 @@ void tst_QDateTimeEdit::ddMMMMyyyy() #ifdef Q_OS_MAC QEXPECT_FAIL("", "QTBUG-23674", Abort); #endif - QCOMPARE(testWidget->lineEdit()->text(), "01." + QDate::longMonthName(1) + ".200"); + QCOMPARE(testWidget->lineEdit()->text(), "01." + QLocale::system().monthName(1, QLocale::LongFormat) + ".200"); } void tst_QDateTimeEdit::wheelEvent_data() diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp index 634e258250..a3e8ac44e6 100644 --- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp +++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp @@ -1001,7 +1001,7 @@ void tst_QMenu::task258920_mouseBorder() menu.setMouseTracking(true); QAction *action = menu.addAction("test"); - const QPoint center = QApplication::desktop()->availableGeometry().center(); + const QPoint center = QGuiApplication::primaryScreen()->availableGeometry().center(); menu.popup(center); QVERIFY(QTest::qWaitForWindowExposed(&menu)); QRect actionRect = menu.actionGeometry(action); @@ -1073,9 +1073,9 @@ void tst_QMenu::pushButtonPopulateOnAboutToShow() QMenu *buttonMenu= new PopulateOnAboutToShowTestMenu(&b); b.setMenu(buttonMenu); - const int scrNumber = QApplication::desktop()->screenNumber(&b); + const QScreen *scr = QGuiApplication::screenAt(b.pos()); b.show(); - const QRect screen = QApplication::desktop()->screenGeometry(scrNumber); + const QRect screen = scr->geometry(); QRect desiredGeometry = b.geometry(); desiredGeometry.moveTopLeft(QPoint(screen.x() + 10, screen.bottom() - b.height() - 5)); @@ -1450,13 +1450,14 @@ void tst_QMenu::QTBUG_56917_wideMenuScreenNumber() QString longString; longString.fill(QLatin1Char('Q'), 3000); - for (int i = 0; i < QApplication::desktop()->screenCount(); i++) { + const QList<QScreen *> screens = QGuiApplication::screens(); + for (QScreen *screen : screens) { QMenu menu; menu.addAction(longString); - menu.popup(QApplication::desktop()->screen(i)->geometry().center()); + menu.popup(screen->geometry().center()); QVERIFY(QTest::qWaitForWindowExposed(&menu)); QVERIFY(menu.isVisible()); - QCOMPARE(QApplication::desktop()->screenNumber(&menu), i); + QCOMPARE(QGuiApplication::screenAt(menu.pos()), screen); } } @@ -1468,19 +1469,20 @@ void tst_QMenu::QTBUG_56917_wideSubmenuScreenNumber() QString longString; longString.fill(QLatin1Char('Q'), 3000); - for (int i = 0; i < QApplication::desktop()->screenCount(); i++) { + const QList<QScreen *> screens = QGuiApplication::screens(); + for (QScreen *screen : screens) { QMenu menu; QMenu submenu("Submenu"); submenu.addAction(longString); QAction *action = menu.addMenu(&submenu); - menu.popup(QApplication::desktop()->screen(i)->geometry().center()); + menu.popup(screen->geometry().center()); QVERIFY(QTest::qWaitForWindowExposed(&menu)); QVERIFY(menu.isVisible()); QTest::mouseClick(&menu, Qt::LeftButton, 0, menu.actionGeometry(action).center()); QTest::qWait(100); QVERIFY(QTest::qWaitForWindowExposed(&submenu)); QVERIFY(submenu.isVisible()); - QCOMPARE(QApplication::desktop()->screenNumber(&submenu), i); + QCOMPARE(QGuiApplication::screenAt(submenu.pos()), screen); } } diff --git a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp index 3063d43aa6..cb829c81a6 100644 --- a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp +++ b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp @@ -326,7 +326,7 @@ TestMenu tst_QMenuBar::initComplexMenuBar(QMenuBar *mb) connect(action, SIGNAL(triggered()), this, SLOT(onComplexActionTriggered())); result.actions << action; - qFill(m_complexTriggerCount, m_complexTriggerCount + sizeof(m_complexTriggerCount) / sizeof(int), 0); + std::fill(m_complexTriggerCount, m_complexTriggerCount + sizeof(m_complexTriggerCount) / sizeof(int), 0); return result; } diff --git a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp index be19cbc9d1..2ce75620cf 100644 --- a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp +++ b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp @@ -209,12 +209,12 @@ void tst_QPlainTextEdit::getSetCheck() // int QPlainTextEdit::tabStopWidth() // void QPlainTextEdit::setTabStopWidth(int) - obj1.setTabStopWidth(0); - QCOMPARE(0, obj1.tabStopWidth()); - obj1.setTabStopWidth(INT_MIN); - QCOMPARE(0, obj1.tabStopWidth()); // Makes no sense to set a negative tabstop value - obj1.setTabStopWidth(INT_MAX); - QCOMPARE(INT_MAX, obj1.tabStopWidth()); + obj1.setTabStopDistance(0); + QCOMPARE(0, obj1.tabStopDistance()); + obj1.setTabStopDistance(-1); + QCOMPARE(0, obj1.tabStopDistance()); // Makes no sense to set a negative tabstop value + obj1.setTabStopDistance(std::numeric_limits<qreal>::max()); + QCOMPARE(std::numeric_limits<qreal>::max(), obj1.tabStopDistance()); } class QtTestDocumentLayout : public QAbstractTextDocumentLayout diff --git a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp index 5f5cd78215..3669935823 100644 --- a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp +++ b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp @@ -282,12 +282,12 @@ void tst_QTextEdit::getSetCheck() // int QTextEdit::tabStopWidth() // void QTextEdit::setTabStopWidth(int) - obj1.setTabStopWidth(0); - QCOMPARE(0, obj1.tabStopWidth()); - obj1.setTabStopWidth(INT_MIN); - QCOMPARE(0, obj1.tabStopWidth()); // Makes no sense to set a negative tabstop value - obj1.setTabStopWidth(INT_MAX); - QCOMPARE(INT_MAX, obj1.tabStopWidth()); + obj1.setTabStopDistance(0); + QCOMPARE(0, obj1.tabStopDistance()); + obj1.setTabStopDistance(-1); + QCOMPARE(0, obj1.tabStopDistance()); // Makes no sense to set a negative tabstop value + obj1.setTabStopDistance(std::numeric_limits<qreal>::max()); + QCOMPARE(std::numeric_limits<qreal>::max(), obj1.tabStopDistance()); // bool QTextEdit::acceptRichText() // void QTextEdit::setAcceptRichText(bool) From 88a2a746b7ed49f4ac4861bbf8e3a55db691fa43 Mon Sep 17 00:00:00 2001 From: Lars Knoll <lars.knoll@qt.io> Date: Fri, 4 Jan 2019 14:55:28 +0100 Subject: [PATCH 1091/1650] Always return early if no signal is connected And simply emit the signal spy and tracing callbacks in that code path as well. Change-Id: I17f65055c7044caf1be58fac94bb7fe3487f3060 Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com> --- src/corelib/kernel/qobject.cpp | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index c0c009f254..8a03fe2a86 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -3668,12 +3668,14 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i Q_TRACE(QMetaObject_activate_end_declarative_signal, sender, signal_index); } - if (!sender->d_func()->isSignalConnected(signal_index, /*checkDeclarative =*/ false) - && !qt_signal_spy_callback_set.signal_begin_callback - && !qt_signal_spy_callback_set.signal_end_callback - && !Q_TRACE_ENABLED(QMetaObject_activate_begin_signal) - && !Q_TRACE_ENABLED(QMetaObject_activate_end_signal)) { - // The possible declarative connection is done, and nothing else is connected, so: + if (!sender->d_func()->isSignalConnected(signal_index, /*checkDeclarative =*/ false)) { + // The possible declarative connection is done, and nothing else is connected + if (qt_signal_spy_callback_set.signal_begin_callback != nullptr) + qt_signal_spy_callback_set.signal_begin_callback(sender, signal_index, argv); + Q_TRACE(QMetaObject_activate_begin_signal, sender, signal_index); + Q_TRACE(QMetaObject_activate_end_signal, sender, signal_index); + if (qt_signal_spy_callback_set.signal_end_callback != nullptr) + qt_signal_spy_callback_set.signal_end_callback(sender, signal_index); return; } @@ -3711,13 +3713,6 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i QObjectConnectionListVector *operator->() const { return connectionLists; } }; ConnectionListsRef connectionLists = sender->d_func()->connectionLists; - if (!connectionLists.connectionLists) { - locker.unlock(); - if (qt_signal_spy_callback_set.signal_end_callback != 0) - qt_signal_spy_callback_set.signal_end_callback(sender, signal_index); - Q_TRACE(QMetaObject_activate_end_signal, sender, signal_index); - return; - } const QObjectPrivate::ConnectionList *list; if (signal_index < connectionLists->count()) From a5a859e721e7a1d0c5a3ec6abe2db55d9144bb36 Mon Sep 17 00:00:00 2001 From: Lars Knoll <lars.knoll@qt.io> Date: Thu, 3 Jan 2019 16:02:09 +0100 Subject: [PATCH 1092/1650] Get rid of the connectedSignals bitflags Measurements show that it's just almost as fast to simply query the connectionlist directly and avoid both the memory overhead of the bitfield and the associated bookkeeping. For connected signals, the difference is not relevant at all. With a signal that was never connected, removing the bitfield will cause signal emission to be ~2.5% faster. And if you ever disconnect from a signal, the bitfields might not be accurate and this can cause a major slowdown. Here are some numbers to validate this. All times are measured in ms for 100M signal emissions: without change with change string based connect: 3817 3836 pointer based connect: 4552 4571 not connected: 493 479 disconnected: 2113 559 Change-Id: Ia2c85036afaa7f991b883c8ff812f69cf4580f7e Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com> Reviewed-by: hjk <hjk@qt.io> --- src/corelib/global/qhooks.cpp | 2 +- src/corelib/kernel/qobject.cpp | 65 +++++++++---------- src/corelib/kernel/qobject_p.h | 18 +---- .../other/toolsupport/tst_toolsupport.cpp | 4 +- 4 files changed, 35 insertions(+), 54 deletions(-) diff --git a/src/corelib/global/qhooks.cpp b/src/corelib/global/qhooks.cpp index bbddb1cbf1..020dee3710 100644 --- a/src/corelib/global/qhooks.cpp +++ b/src/corelib/global/qhooks.cpp @@ -67,7 +67,7 @@ quintptr Q_CORE_EXPORT qtHookData[] = { // The required sizes and offsets are tested in tests/auto/other/toolsupport. // When this fails and the change was intentional, adjust the test and // adjust this value here. - 16 + 17 }; Q_STATIC_ASSERT(QHooks::LastHookIndex == sizeof(qtHookData) / sizeof(qtHookData[0])); diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 8a03fe2a86..c158cf9452 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -232,7 +232,6 @@ QObjectPrivate::QObjectPrivate(int version) receiveChildEvents = true; postedEvents = 0; extraData = 0; - connectedSignals[0] = connectedSignals[1] = 0; metaObject = 0; isWindow = false; deleteLaterCalled = false; @@ -409,19 +408,12 @@ void QObjectPrivate::addConnection(int signal, Connection *c) *c->prev = c; if (c->next) c->next->prev = &c->next; - - if (signal < 0) { - connectedSignals[0] = connectedSignals[1] = ~0; - } else if (signal < (int)sizeof(connectedSignals) * 8) { - connectedSignals[signal >> 5] |= (1 << (signal & 0x1f)); - } } void QObjectPrivate::cleanConnectionLists() { if (connectionLists->dirty && !connectionLists->inUse) { // remove broken connections - bool allConnected = false; for (int signal = -1; signal < connectionLists->count(); ++signal) { QObjectPrivate::ConnectionList &connectionList = (*connectionLists)[signal]; @@ -433,13 +425,11 @@ void QObjectPrivate::cleanConnectionLists() QObjectPrivate::Connection **prev = &connectionList.first; QObjectPrivate::Connection *c = *prev; - bool connected = false; // whether the signal is still connected somewhere while (c) { if (c->receiver) { last = c; prev = &c->nextConnectionList; c = *prev; - connected = true; } else { QObjectPrivate::Connection *next = c->nextConnectionList; *prev = next; @@ -451,19 +441,40 @@ void QObjectPrivate::cleanConnectionLists() // Correct the connection list's last pointer. // As conectionList.last could equal last, this could be a noop connectionList.last = last; - - if (!allConnected && !connected && signal >= 0 - && size_t(signal) < sizeof(connectedSignals) * 8) { - // This signal is no longer connected - connectedSignals[signal >> 5] &= ~(1 << (signal & 0x1f)); - } else if (signal == -1) { - allConnected = connected; - } } connectionLists->dirty = false; } } +/*! \internal + + Returns \c true if the signal with index \a signal_index from object \a sender is connected. + + \a signal_index must be the index returned by QObjectPrivate::signalIndex; +*/ +bool QObjectPrivate::isSignalConnected(uint signalIndex, bool checkDeclarative) const +{ + if (checkDeclarative && isDeclarativeSignalConnected(signalIndex)) + return true; + + if (!connectionLists) + return false; + + if (connectionLists->allsignals.first) + return true; + + if (signalIndex < uint(connectionLists->count())) { + const QObjectPrivate::Connection *c = connectionLists->at(signalIndex).first; + while (c) { + if (c->receiver) + return true; + c = c->nextConnectionList; + } + } + return false; +} + + /*! \internal */ @@ -2521,21 +2532,7 @@ bool QObject::isSignalConnected(const QMetaMethod &signal) const signalIndex += QMetaObjectPrivate::signalOffset(signal.mobj); QMutexLocker locker(signalSlotLock(this)); - if (d->connectionLists) { - if (signalIndex < sizeof(d->connectedSignals) * 8 && !d->connectionLists->dirty) - return d->isSignalConnected(signalIndex); - - if (signalIndex < uint(d->connectionLists->count())) { - const QObjectPrivate::Connection *c = - d->connectionLists->at(signalIndex).first; - while (c) { - if (c->receiver) - return true; - c = c->nextConnectionList; - } - } - } - return d->isDeclarativeSignalConnected(signalIndex); + return d->isSignalConnected(signalIndex, true); } /*! @@ -3668,7 +3665,7 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i Q_TRACE(QMetaObject_activate_end_declarative_signal, sender, signal_index); } - if (!sender->d_func()->isSignalConnected(signal_index, /*checkDeclarative =*/ false)) { + if (!sender->d_func()->isSignalConnected(signal_index, false)) { // The possible declarative connection is done, and nothing else is connected if (qt_signal_spy_callback_set.signal_begin_callback != nullptr) qt_signal_spy_callback_set.signal_begin_callback(sender, signal_index, argv); diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index a762e6f529..7cc82d4f71 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -201,7 +201,7 @@ public: static const QObjectPrivate *get(const QObject *o) { return o->d_func(); } int signalIndex(const char *signalName, const QMetaObject **meta = nullptr) const; - inline bool isSignalConnected(uint signalIdx, bool checkDeclarative = true) const; + bool isSignalConnected(uint signalIdx, bool checkDeclarative = true) const; inline bool isDeclarativeSignalConnected(uint signalIdx) const; // To allow abitrary objects to call connectNotify()/disconnectNotify() without making @@ -232,7 +232,6 @@ public: Connection *senders; // linked list of connections connected to this object Sender *currentSender; // object currently activating the object - mutable quint32 connectedSignals[2]; union { QObject *currentChildBeingDeleted; // should only be used when QObjectData::isDeletingChildren is set @@ -246,21 +245,6 @@ public: Q_DECLARE_TYPEINFO(QObjectPrivate::ConnectionList, Q_MOVABLE_TYPE); -/*! \internal - - Returns \c true if the signal with index \a signal_index from object \a sender is connected. - Signals with indices above a certain range are always considered connected (see connectedSignals - in QObjectPrivate). - - \a signal_index must be the index returned by QObjectPrivate::signalIndex; -*/ -inline bool QObjectPrivate::isSignalConnected(uint signal_index, bool checkDeclarative) const -{ - return signal_index >= sizeof(connectedSignals) * 8 - || (connectedSignals[signal_index >> 5] & (1 << (signal_index & 0x1f)) - || (checkDeclarative && isDeclarativeSignalConnected(signal_index))); -} - inline bool QObjectPrivate::isDeclarativeSignalConnected(uint signal_index) const { return declarativeData && QAbstractDeclarativeData::isSignalConnected diff --git a/tests/auto/other/toolsupport/tst_toolsupport.cpp b/tests/auto/other/toolsupport/tst_toolsupport.cpp index f31a755f9e..27bc6ba646 100644 --- a/tests/auto/other/toolsupport/tst_toolsupport.cpp +++ b/tests/auto/other/toolsupport/tst_toolsupport.cpp @@ -126,9 +126,9 @@ void tst_toolsupport::offsets_data() #ifdef Q_PROCESSOR_X86 // x86 32-bit has weird alignment rules. Refer to QtPrivate::AlignOf in // qglobal.h for more details. - data << 168 << 248; + data << 160 << 240; #else - data << 172 << 248; + data << 164 << 240; #endif } #endif From a65752c71bd25bbb66bf33d3a82f7901419c5d95 Mon Sep 17 00:00:00 2001 From: Lars Knoll <lars.knoll@qt.io> Date: Thu, 3 Jan 2019 22:57:28 +0100 Subject: [PATCH 1093/1650] Shave ~5% off from signal emission time Refactor activate(), so that we eliminate almost all checks for signal hooks in the common case. Here are the benchmark numbers showing the improvement for 100M signal emissions without change with change string based connect: 3836 3693 pointer based connect: 4571 4510 not connected: 479 433 disconnected: 559 522 Change-Id: I394e6ea5d5bc96e298e8cc0c763eed78c8041876 Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com> --- src/corelib/global/qtrace_p.h | 2 + src/corelib/kernel/qcoreapplication.cpp | 9 --- src/corelib/kernel/qobject.cpp | 102 +++++++++++++++--------- src/corelib/kernel/qobject_p.h | 4 +- src/testlib/qsignaldumper.cpp | 5 +- 5 files changed, 69 insertions(+), 53 deletions(-) diff --git a/src/corelib/global/qtrace_p.h b/src/corelib/global/qtrace_p.h index 3d04a7311d..56d1f9a318 100644 --- a/src/corelib/global/qtrace_p.h +++ b/src/corelib/global/qtrace_p.h @@ -114,10 +114,12 @@ QT_BEGIN_NAMESPACE #if defined(Q_TRACEPOINT) && !defined(QT_BOOTSTRAPPED) +# define Q_HAS_TRACEPOINTS 1 # define Q_TRACE(x, ...) QtPrivate::trace_ ## x(__VA_ARGS__) # define Q_UNCONDITIONAL_TRACE(x, ...) QtPrivate::do_trace_ ## x(__VA_ARGS__) # define Q_TRACE_ENABLED(x) QtPrivate::trace_ ## x ## _enabled() #else +# define Q_HAS_TRACEPOINTS 0 # define Q_TRACE(x, ...) # define Q_UNCONDITIONAL_TRACE(x, ...) # define Q_TRACE_ENABLED(x) false diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index e5098b8415..e6d1d26f3c 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -256,15 +256,6 @@ void QCoreApplicationPrivate::processCommandLineArguments() // Support for introspection -#ifndef QT_NO_QOBJECT -QSignalSpyCallbackSet Q_CORE_EXPORT qt_signal_spy_callback_set = { 0, 0, 0, 0 }; - -void qt_register_signal_spy_callbacks(const QSignalSpyCallbackSet &callback_set) -{ - qt_signal_spy_callback_set = callback_set; -} -#endif - extern "C" void Q_CORE_EXPORT qt_startup_hook() { } diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index c158cf9452..0c81e416da 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -77,6 +77,12 @@ QT_BEGIN_NAMESPACE static int DIRECT_CONNECTION_ONLY = 0; +Q_CORE_EXPORT QBasicAtomicPointer<QSignalSpyCallbackSet> qt_signal_spy_callback_set = Q_BASIC_ATOMIC_INITIALIZER(nullptr); + +void qt_register_signal_spy_callbacks(QSignalSpyCallbackSet *callback_set) +{ + qt_signal_spy_callback_set.store(callback_set); +} QDynamicMetaObjectData::~QDynamicMetaObjectData() { @@ -3638,41 +3644,32 @@ static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connect QCoreApplication::postEvent(c->receiver, ev); } -/*! - \internal - */ -void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_signal_index, - void **argv) +template <bool callbacks_enabled> +void doActivate(QObject *sender, int signal_index, void **argv) { - activate(sender, QMetaObjectPrivate::signalOffset(m), local_signal_index, argv); -} + QObjectPrivate *sp = QObjectPrivate::get(sender); -/*! - \internal - */ -void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_index, void **argv) -{ - int signal_index = signalOffset + local_signal_index; - - if (sender->d_func()->blockSig) + if (sp->blockSig) return; - if (sender->d_func()->isDeclarativeSignalConnected(signal_index) + if (sp->isDeclarativeSignalConnected(signal_index) && QAbstractDeclarativeData::signalEmitted) { Q_TRACE(QMetaObject_activate_begin_declarative_signal, sender, signal_index); - QAbstractDeclarativeData::signalEmitted(sender->d_func()->declarativeData, sender, + QAbstractDeclarativeData::signalEmitted(sp->declarativeData, sender, signal_index, argv); Q_TRACE(QMetaObject_activate_end_declarative_signal, sender, signal_index); } - if (!sender->d_func()->isSignalConnected(signal_index, false)) { + const QSignalSpyCallbackSet *signal_spy_set = callbacks_enabled ? qt_signal_spy_callback_set.load() : nullptr; + + if (!sp->isSignalConnected(signal_index, false)) { // The possible declarative connection is done, and nothing else is connected - if (qt_signal_spy_callback_set.signal_begin_callback != nullptr) - qt_signal_spy_callback_set.signal_begin_callback(sender, signal_index, argv); + if (callbacks_enabled && signal_spy_set->signal_begin_callback != nullptr) + signal_spy_set->signal_begin_callback(sender, signal_index, argv); Q_TRACE(QMetaObject_activate_begin_signal, sender, signal_index); Q_TRACE(QMetaObject_activate_end_signal, sender, signal_index); - if (qt_signal_spy_callback_set.signal_end_callback != nullptr) - qt_signal_spy_callback_set.signal_end_callback(sender, signal_index); + if (callbacks_enabled && signal_spy_set->signal_end_callback != nullptr) + signal_spy_set->signal_end_callback(sender, signal_index); return; } @@ -3680,9 +3677,8 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i if (!argv) argv = empty_argv; - if (qt_signal_spy_callback_set.signal_begin_callback != 0) { - qt_signal_spy_callback_set.signal_begin_callback(sender, signal_index, argv); - } + if (callbacks_enabled && signal_spy_set->signal_begin_callback != nullptr) + signal_spy_set->signal_begin_callback(sender, signal_index, argv); Q_TRACE(QMetaObject_activate_begin_signal, sender, signal_index); { @@ -3709,7 +3705,7 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i QObjectConnectionListVector *operator->() const { return connectionLists; } }; - ConnectionListsRef connectionLists = sender->d_func()->connectionLists; + ConnectionListsRef connectionLists = sp->connectionLists; const QObjectPrivate::ConnectionList *list; if (signal_index < connectionLists->count()) @@ -3731,7 +3727,7 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i continue; QObject * const receiver = c->receiver; - const bool receiverInSameThread = currentThreadId == receiver->d_func()->threadData->threadId.load(); + const bool receiverInSameThread = currentThreadId == QObjectPrivate::get(receiver)->threadData->threadId.load(); // determine if this connection should be sent immediately or // put into the event queue @@ -3780,34 +3776,34 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i locker.relock(); } else if (c->callFunction && c->method_offset <= receiver->metaObject()->methodOffset()) { //we compare the vtable to make sure we are not in the destructor of the object. - const int methodIndex = c->method(); const int method_relative = c->method_relative; const auto callFunction = c->callFunction; locker.unlock(); - if (qt_signal_spy_callback_set.slot_begin_callback != 0) - qt_signal_spy_callback_set.slot_begin_callback(receiver, methodIndex, argv); + const int methodIndex = (Q_HAS_TRACEPOINTS || callbacks_enabled) ? c->method() : 0; + if (callbacks_enabled && signal_spy_set->slot_begin_callback != nullptr) + signal_spy_set->slot_begin_callback(receiver, methodIndex, argv); Q_TRACE(QMetaObject_activate_begin_slot, receiver, methodIndex); callFunction(receiver, QMetaObject::InvokeMetaMethod, method_relative, argv); Q_TRACE(QMetaObject_activate_end_slot, receiver, methodIndex); - if (qt_signal_spy_callback_set.slot_end_callback != 0) - qt_signal_spy_callback_set.slot_end_callback(receiver, methodIndex); + if (callbacks_enabled && signal_spy_set->slot_end_callback != nullptr) + signal_spy_set->slot_end_callback(receiver, methodIndex); locker.relock(); } else { const int method = c->method_relative + c->method_offset; locker.unlock(); - if (qt_signal_spy_callback_set.slot_begin_callback != 0) { - qt_signal_spy_callback_set.slot_begin_callback(receiver, method, argv); + if (callbacks_enabled && signal_spy_set->slot_begin_callback != nullptr) { + signal_spy_set->slot_begin_callback(receiver, method, argv); } Q_TRACE(QMetaObject_activate_begin_slot, receiver, method); - metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv); + QMetaObject::metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv); Q_TRACE(QMetaObject_activate_end_slot, receiver, method); - if (qt_signal_spy_callback_set.slot_end_callback != 0) - qt_signal_spy_callback_set.slot_end_callback(receiver, method); + if (callbacks_enabled && signal_spy_set->slot_end_callback != nullptr) + signal_spy_set->slot_end_callback(receiver, method); locker.relock(); } @@ -3824,11 +3820,39 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i } - if (qt_signal_spy_callback_set.signal_end_callback != 0) - qt_signal_spy_callback_set.signal_end_callback(sender, signal_index); + if (callbacks_enabled && signal_spy_set->signal_end_callback != nullptr) + signal_spy_set->signal_end_callback(sender, signal_index); Q_TRACE(QMetaObject_activate_end_signal, sender, signal_index); + } +/*! + \internal + */ +void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_signal_index, + void **argv) +{ + int signal_index = local_signal_index + QMetaObjectPrivate::signalOffset(m); + + if (Q_UNLIKELY(qt_signal_spy_callback_set.load())) + doActivate<true>(sender, signal_index, argv); + else + doActivate<false>(sender, signal_index, argv); +} + +/*! + \internal + */ +void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_index, void **argv) +{ + int signal_index = signalOffset + local_signal_index; + + if (Q_UNLIKELY(qt_signal_spy_callback_set.load())) + doActivate<true>(sender, signal_index, argv); + else + doActivate<false>(sender, signal_index, argv); + } + /*! \internal signal_index comes from indexOfMethod() diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 7cc82d4f71..a260ed680e 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -79,9 +79,9 @@ struct QSignalSpyCallbackSet EndCallback signal_end_callback, slot_end_callback; }; -void Q_CORE_EXPORT qt_register_signal_spy_callbacks(const QSignalSpyCallbackSet &callback_set); +void Q_CORE_EXPORT qt_register_signal_spy_callbacks(QSignalSpyCallbackSet *callback_set); -extern QSignalSpyCallbackSet Q_CORE_EXPORT qt_signal_spy_callback_set; +extern Q_CORE_EXPORT QBasicAtomicPointer<QSignalSpyCallbackSet> qt_signal_spy_callback_set; enum { QObjectPrivateVersion = QT_VERSION }; diff --git a/src/testlib/qsignaldumper.cpp b/src/testlib/qsignaldumper.cpp index 8305c5d424..b3360b4e6c 100644 --- a/src/testlib/qsignaldumper.cpp +++ b/src/testlib/qsignaldumper.cpp @@ -170,13 +170,12 @@ void QSignalDumper::startDump() { static QSignalSpyCallbackSet set = { QTest::qSignalDumperCallback, QTest::qSignalDumperCallbackSlot, QTest::qSignalDumperCallbackEndSignal, 0 }; - qt_register_signal_spy_callbacks(set); + qt_register_signal_spy_callbacks(&set); } void QSignalDumper::endDump() { - static QSignalSpyCallbackSet nset = { 0, 0, 0 ,0 }; - qt_register_signal_spy_callbacks(nset); + qt_register_signal_spy_callbacks(nullptr); } void QSignalDumper::ignoreClass(const QByteArray &klass) From ab92b9e40025dcf08c14232de762a268201a78b4 Mon Sep 17 00:00:00 2001 From: Lars Knoll <lars.knoll@qt.io> Date: Fri, 4 Jan 2019 08:55:40 +0100 Subject: [PATCH 1094/1650] Simplify the code required for switching the current sender Squeezes another percent of performance out of QMetaObject::activate(). Change-Id: I620b8c578681280efcc9bec50cfb1020d2afc928 Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com> --- src/corelib/kernel/qobject.cpp | 55 +++++++--------------------------- src/corelib/kernel/qobject_p.h | 50 ++++++++++++++----------------- 2 files changed, 33 insertions(+), 72 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 0c81e416da..f7983f3251 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -166,39 +166,6 @@ extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *) {} #endif -struct QConnectionSenderSwitcher { - QObject *receiver; - QObjectPrivate::Sender *previousSender; - QObjectPrivate::Sender currentSender; - bool switched; - - inline QConnectionSenderSwitcher() : switched(false) {} - - inline QConnectionSenderSwitcher(QObject *receiver, QObject *sender, int signal_absolute_id) - { - switchSender(receiver, sender, signal_absolute_id); - } - - inline void switchSender(QObject *receiver, QObject *sender, int signal_absolute_id) - { - this->receiver = receiver; - currentSender.sender = sender; - currentSender.signal = signal_absolute_id; - currentSender.ref = 1; - previousSender = QObjectPrivate::setCurrentSender(receiver, ¤tSender); - switched = true; - } - - inline ~QConnectionSenderSwitcher() - { - if (switched) - QObjectPrivate::resetCurrentSender(receiver, ¤tSender, previousSender); - } -private: - Q_DISABLE_COPY(QConnectionSenderSwitcher) -}; - - void (*QAbstractDeclarativeData::destroyed)(QAbstractDeclarativeData *, QObject *) = 0; void (*QAbstractDeclarativeData::destroyed_qml1)(QAbstractDeclarativeData *, QObject *) = 0; void (*QAbstractDeclarativeData::parentChanged)(QAbstractDeclarativeData *, QObject *, QObject *) = 0; @@ -938,10 +905,10 @@ QObject::~QObject() } } - // set ref to zero to indicate that this object has been deleted - if (d->currentSender != 0) - d->currentSender->ref = 0; - d->currentSender = 0; + if (d->currentSender) { + d->currentSender->receiverDeleted(); + d->currentSender = nullptr; + } if (d->connectionLists || d->senders) { QMutex *signalSlotMutex = signalSlotLock(this); @@ -1272,7 +1239,7 @@ bool QObject::event(QEvent *e) { QMetaCallEvent *mce = static_cast<QMetaCallEvent*>(e); - QConnectionSenderSwitcher sw(this, const_cast<QObject*>(mce->sender()), mce->signalId()); + QObjectPrivate::Sender sender(this, const_cast<QObject*>(mce->sender()), mce->signalId()); mce->placeMetaCall(this); break; @@ -1576,9 +1543,10 @@ void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData } // the current emitting thread shouldn't restore currentSender after calling moveToThread() - if (currentSender) - currentSender->ref = 0; - currentSender = 0; + if (currentSender) { + currentSender->receiverDeleted(); + currentSender = nullptr; + } // set new thread data targetData->ref(); @@ -3755,11 +3723,8 @@ void doActivate(QObject *sender, int signal_index, void **argv) #endif } - QConnectionSenderSwitcher sw; + QObjectPrivate::Sender senderData(receiverInSameThread ? receiver : nullptr, sender, signal_index); - if (receiverInSameThread) { - sw.switchSender(receiver, sender, signal_index); - } if (c->isSlotObject) { c->slotObj->ref(); QScopedPointer<QtPrivate::QSlotObjectBase, QSlotObjectBaseDeleter> obj(c->slotObj); diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index a260ed680e..ab20064c65 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -167,9 +167,31 @@ public: struct Sender { + Sender(QObject *receiver, QObject *sender, int signal) + : receiver(receiver), sender(sender), signal(signal) + { + if (receiver) { + previous = receiver->d_func()->currentSender; + receiver->d_func()->currentSender = this; + } + } + ~Sender() + { + if (receiver) + receiver->d_func()->currentSender = previous; + } + void receiverDeleted() + { + Sender *s = this; + while (s) { + s->receiver = nullptr; + s = s->previous; + } + } + Sender *previous; + QObject *receiver; QObject *sender; int signal; - int ref; }; @@ -189,12 +211,6 @@ public: void addConnection(int signal, Connection *c); void cleanConnectionLists(); - static inline Sender *setCurrentSender(QObject *receiver, - Sender *sender); - static inline void resetCurrentSender(QObject *receiver, - Sender *currentSender, - Sender *previousSender); - static QObjectPrivate *get(QObject *o) { return o->d_func(); } @@ -251,26 +267,6 @@ inline bool QObjectPrivate::isDeclarativeSignalConnected(uint signal_index) cons && QAbstractDeclarativeData::isSignalConnected(declarativeData, q_func(), signal_index); } -inline QObjectPrivate::Sender *QObjectPrivate::setCurrentSender(QObject *receiver, - Sender *sender) -{ - Sender *previousSender = receiver->d_func()->currentSender; - receiver->d_func()->currentSender = sender; - return previousSender; -} - -inline void QObjectPrivate::resetCurrentSender(QObject *receiver, - Sender *currentSender, - Sender *previousSender) -{ - // ref is set to zero when this object is deleted during the metacall - if (currentSender->ref == 1) - receiver->d_func()->currentSender = previousSender; - // if we've recursed, we need to tell the caller about the objects deletion - if (previousSender) - previousSender->ref = currentSender->ref; -} - inline void QObjectPrivate::connectNotify(const QMetaMethod &signal) { q_ptr->connectNotify(signal); From 5cc6f90910082f35e3f5340493facbc8c175f65f Mon Sep 17 00:00:00 2001 From: Lars Knoll <lars.knoll@qt.io> Date: Mon, 7 Jan 2019 15:05:06 +0100 Subject: [PATCH 1095/1650] Move all connection related data into one data structure Adn create that data structure on demand on the heap. This reduces the size of QObjectPrivate if there are no connections. If we have connections, it'll use the same amount of allocations and memory as before. Change-Id: I900f6980a2cd8a5f72c3ad18697b5dd49100217d Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com> --- src/corelib/kernel/qobject.cpp | 376 ++++++++---------- src/corelib/kernel/qobject_p.h | 47 ++- .../other/toolsupport/tst_toolsupport.cpp | 4 +- 3 files changed, 215 insertions(+), 212 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index f7983f3251..b8e973a0a3 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -182,7 +182,7 @@ QMetaObject *QObjectData::dynamicMetaObject() const } QObjectPrivate::QObjectPrivate(int version) - : threadData(0), connectionLists(0), senders(0), currentSender(0), currentChildBeingDeleted(0) + : threadData(0), currentChildBeingDeleted(0) { #ifdef QT_BUILD_INTERNAL // Don't check the version parameter in internal builds. @@ -257,59 +257,22 @@ static void computeOffsets(const QMetaObject *metaobject, int *signalOffset, int } } -/* - This vector contains the all connections from an object. - - Each object may have one vector containing the lists of - connections for a given signal. The index in the vector correspond - to the signal index. The signal index is the one returned by - QObjectPrivate::signalIndex (not QMetaObject::indexOfSignal). - Negative index means connections to all signals. - - This vector is protected by the object mutex (signalSlotMutexes()) - - Each Connection is also part of a 'senders' linked list. The mutex - of the receiver must be locked when touching the pointers of this - linked list. -*/ -class QObjectConnectionListVector : public QVector<QObjectPrivate::ConnectionList> -{ -public: - bool orphaned; //the QObject owner of this vector has been destroyed while the vector was inUse - bool dirty; //some Connection have been disconnected (their receiver is 0) but not removed from the list yet - int inUse; //number of functions that are currently accessing this object or its connections - QObjectPrivate::ConnectionList allsignals; - - QObjectConnectionListVector() - : QVector<QObjectPrivate::ConnectionList>(), orphaned(false), dirty(false), inUse(0) - { } - - QObjectPrivate::ConnectionList &operator[](int at) - { - if (at < 0) - return allsignals; - return QVector<QObjectPrivate::ConnectionList>::operator[](at); - } -}; - // Used by QAccessibleWidget bool QObjectPrivate::isSender(const QObject *receiver, const char *signal) const { Q_Q(const QObject); int signal_index = signalIndex(signal); - if (signal_index < 0) + ConnectionData *cd = connections.load(); + if (signal_index < 0 || !cd) return false; QMutexLocker locker(signalSlotLock(q)); - if (connectionLists) { - if (signal_index < connectionLists->count()) { - const QObjectPrivate::Connection *c = - connectionLists->at(signal_index).first; + if (signal_index < cd->signalVector.count()) { + const QObjectPrivate::Connection *c = cd->signalVector.at(signal_index).first; - while (c) { - if (c->receiver == receiver) - return true; - c = c->nextConnectionList; - } + while (c) { + if (c->receiver == receiver) + return true; + c = c->nextConnectionList; } } return false; @@ -321,18 +284,17 @@ QObjectList QObjectPrivate::receiverList(const char *signal) const Q_Q(const QObject); QObjectList returnValue; int signal_index = signalIndex(signal); - if (signal_index < 0) + ConnectionData *cd = connections.load(); + if (signal_index < 0 || !cd) return returnValue; QMutexLocker locker(signalSlotLock(q)); - if (connectionLists) { - if (signal_index < connectionLists->count()) { - const QObjectPrivate::Connection *c = connectionLists->at(signal_index).first; + if (signal_index < cd->signalVector.count()) { + const QObjectPrivate::Connection *c = cd->signalVector.at(signal_index).first; - while (c) { - if (c->receiver) - returnValue << c->receiver; - c = c->nextConnectionList; - } + while (c) { + if (c->receiver) + returnValue << c->receiver; + c = c->nextConnectionList; } } return returnValue; @@ -342,9 +304,12 @@ QObjectList QObjectPrivate::receiverList(const char *signal) const QObjectList QObjectPrivate::senderList() const { QObjectList returnValue; - QMutexLocker locker(signalSlotLock(q_func())); - for (Connection *c = senders; c; c = c->next) - returnValue << c->sender; + ConnectionData *cd = connections.load(); + if (cd) { + QMutexLocker locker(signalSlotLock(q_func())); + for (Connection *c = cd->senders; c; c = c->next) + returnValue << c->sender; + } return returnValue; } @@ -361,12 +326,12 @@ QObjectList QObjectPrivate::senderList() const void QObjectPrivate::addConnection(int signal, Connection *c) { Q_ASSERT(c->sender == q_ptr); - if (!connectionLists) - connectionLists = new QObjectConnectionListVector(); - if (signal >= connectionLists->count()) - connectionLists->resize(signal + 1); + ensureConnectionData(); + ConnectionData *cd = connections.load(); + if (signal >= cd->signalVector.count()) + cd->signalVector.resize(signal + 1); - ConnectionList &connectionList = (*connectionLists)[signal]; + ConnectionList &connectionList = cd->connectionsForSignal(signal); if (connectionList.last) { connectionList.last->nextConnectionList = c; } else { @@ -376,7 +341,10 @@ void QObjectPrivate::addConnection(int signal, Connection *c) cleanConnectionLists(); - c->prev = &(QObjectPrivate::get(c->receiver)->senders); + QObjectPrivate *rd = QObjectPrivate::get(c->receiver); + rd->ensureConnectionData(); + + c->prev = &(rd->connections.load()->senders); c->next = *c->prev; *c->prev = c; if (c->next) @@ -385,11 +353,11 @@ void QObjectPrivate::addConnection(int signal, Connection *c) void QObjectPrivate::cleanConnectionLists() { - if (connectionLists->dirty && !connectionLists->inUse) { + ConnectionData *cd = connections.load(); + if (cd->dirty && !cd->inUse) { // remove broken connections - for (int signal = -1; signal < connectionLists->count(); ++signal) { - QObjectPrivate::ConnectionList &connectionList = - (*connectionLists)[signal]; + for (int signal = -1; signal < cd->signalVector.count(); ++signal) { + ConnectionList &connectionList = cd->connectionsForSignal(signal); // Set to the last entry in the connection list that was *not* // deleted. This is needed to update the list's last pointer @@ -415,7 +383,7 @@ void QObjectPrivate::cleanConnectionLists() // As conectionList.last could equal last, this could be a noop connectionList.last = last; } - connectionLists->dirty = false; + cd->dirty = false; } } @@ -430,14 +398,15 @@ bool QObjectPrivate::isSignalConnected(uint signalIndex, bool checkDeclarative) if (checkDeclarative && isDeclarativeSignalConnected(signalIndex)) return true; - if (!connectionLists) + ConnectionData *cd = connections.load(); + if (!cd) return false; - if (connectionLists->allsignals.first) + if (cd->allsignals.first) return true; - if (signalIndex < uint(connectionLists->count())) { - const QObjectPrivate::Connection *c = connectionLists->at(signalIndex).first; + if (signalIndex < uint(cd->signalVector.count())) { + const QObjectPrivate::Connection *c = cd->signalVector.at(signalIndex).first; while (c) { if (c->receiver) return true; @@ -905,60 +874,51 @@ QObject::~QObject() } } - if (d->currentSender) { - d->currentSender->receiverDeleted(); - d->currentSender = nullptr; - } + QObjectPrivate::ConnectionData *cd = d->connections.load(); + if (cd) { + if (cd->currentSender) { + cd->currentSender->receiverDeleted(); + cd->currentSender = nullptr; + } - if (d->connectionLists || d->senders) { QMutex *signalSlotMutex = signalSlotLock(this); QMutexLocker locker(signalSlotMutex); + ++cd->inUse; // disconnect all receivers - if (d->connectionLists) { - ++d->connectionLists->inUse; - int connectionListsCount = d->connectionLists->count(); - for (int signal = -1; signal < connectionListsCount; ++signal) { - QObjectPrivate::ConnectionList &connectionList = - (*d->connectionLists)[signal]; - - while (QObjectPrivate::Connection *c = connectionList.first) { - if (!c->receiver) { - connectionList.first = c->nextConnectionList; - c->deref(); - continue; - } - - QMutex *m = signalSlotLock(c->receiver); - bool needToUnlock = QOrderedMutexLocker::relock(signalSlotMutex, m); - - if (c->receiver) { - *c->prev = c->next; - if (c->next) c->next->prev = c->prev; - } - c->receiver = 0; - if (needToUnlock) - m->unlock(); + int receiverCount = cd->signalVector.count(); + for (int signal = -1; signal < receiverCount; ++signal) { + QObjectPrivate::ConnectionList &connectionList = cd->connectionsForSignal(signal); + while (QObjectPrivate::Connection *c = connectionList.first) { + if (!c->receiver) { connectionList.first = c->nextConnectionList; - - // The destroy operation must happen outside the lock - if (c->isSlotObject) { - c->isSlotObject = false; - locker.unlock(); - c->slotObj->destroyIfLastRef(); - locker.relock(); - } c->deref(); + continue; } - } - if (!--d->connectionLists->inUse) { - delete d->connectionLists; - } else { - d->connectionLists->orphaned = true; + QMutex *m = signalSlotLock(c->receiver); + bool needToUnlock = QOrderedMutexLocker::relock(signalSlotMutex, m); + + if (c->receiver) { + *c->prev = c->next; + if (c->next) c->next->prev = c->prev; + } + c->receiver = 0; + if (needToUnlock) + m->unlock(); + + connectionList.first = c->nextConnectionList; + + // The destroy operation must happen outside the lock + if (c->isSlotObject) { + c->isSlotObject = false; + locker.unlock(); + c->slotObj->destroyIfLastRef(); + locker.relock(); + } + c->deref(); } - d->connectionLists = 0; } /* Disconnect all senders: @@ -970,8 +930,9 @@ QObject::~QObject() * thread. That's why we set node->prev to &node, that way, if node is destroyed, node will * be updated. */ - QObjectPrivate::Connection *node = d->senders; + QObjectPrivate::Connection *node = cd->senders; while (node) { + Q_ASSERT(node->receiver); QObject *sender = node->sender; // Send disconnectNotify before removing the connection from sender's connection list. // This ensures any eventual destructor of sender will block on getting receiver's lock @@ -988,9 +949,9 @@ QObject::~QObject() continue; } node->receiver = 0; - QObjectConnectionListVector *senderLists = sender->d_func()->connectionLists; - if (senderLists) - senderLists->dirty = true; + QObjectPrivate::ConnectionData *senderData = sender->d_func()->connections; + if (senderData) + senderData->dirty = true; QtPrivate::QSlotObjectBase *slotObj = nullptr; if (node->isSlotObject) { @@ -1010,6 +971,13 @@ QObject::~QObject() locker.relock(); } } + + if (!--cd->inUse) { + delete cd; + } else { + cd->orphaned = true; + } + d->connections.store(nullptr); } if (!d->children.isEmpty()) @@ -1239,6 +1207,10 @@ bool QObject::event(QEvent *e) { QMetaCallEvent *mce = static_cast<QMetaCallEvent*>(e); + if (!d_func()->connections.load()) { + QMutexLocker locker(signalSlotLock(this)); + d_func()->ensureConnectionData(); + } QObjectPrivate::Sender sender(this, const_cast<QObject*>(mce->sender()), mce->signalId()); mce->placeMetaCall(this); @@ -1543,9 +1515,10 @@ void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData } // the current emitting thread shouldn't restore currentSender after calling moveToThread() - if (currentSender) { - currentSender->receiverDeleted(); - currentSender = nullptr; + ConnectionData *cd = connections.load(); + if (cd && cd->currentSender) { + cd->currentSender->receiverDeleted(); + cd->currentSender = nullptr; } // set new thread data @@ -2354,12 +2327,13 @@ QObject *QObject::sender() const Q_D(const QObject); QMutexLocker locker(signalSlotLock(this)); - if (!d->currentSender) - return 0; + QObjectPrivate::ConnectionData *cd = d->connections.load(); + if (!cd || !cd->currentSender) + return nullptr; - for (QObjectPrivate::Connection *c = d->senders; c; c = c->next) { - if (c->sender == d->currentSender->sender) - return d->currentSender->sender; + for (QObjectPrivate::Connection *c = cd->senders; c; c = c->next) { + if (c->sender == cd->currentSender->sender) + return cd->currentSender->sender; } return 0; @@ -2395,13 +2369,14 @@ int QObject::senderSignalIndex() const Q_D(const QObject); QMutexLocker locker(signalSlotLock(this)); - if (!d->currentSender) + QObjectPrivate::ConnectionData *cd = d->connections.load(); + if (!cd || !cd->currentSender) return -1; - for (QObjectPrivate::Connection *c = d->senders; c; c = c->next) { - if (c->sender == d->currentSender->sender) { + for (QObjectPrivate::Connection *c = cd->senders; c; c = c->next) { + if (c->sender == cd->currentSender->sender) { // Convert from signal range to method range - return QMetaObjectPrivate::signal(c->sender->metaObject(), d->currentSender->signal).methodIndex(); + return QMetaObjectPrivate::signal(c->sender->metaObject(), cd->currentSender->signal).methodIndex(); } } @@ -2433,7 +2408,8 @@ int QObject::receivers(const char *signal) const { Q_D(const QObject); int receivers = 0; - if (signal) { + QObjectPrivate::ConnectionData *cd = d->connections.load(); + if (signal && cd) { QByteArray signal_name = QMetaObject::normalizedSignature(signal); signal = signal_name; #ifndef QT_NO_DEBUG @@ -2458,14 +2434,12 @@ int QObject::receivers(const char *signal) const } QMutexLocker locker(signalSlotLock(this)); - if (d->connectionLists) { - if (signal_index < d->connectionLists->count()) { - const QObjectPrivate::Connection *c = - d->connectionLists->at(signal_index).first; - while (c) { - receivers += c->receiver ? 1 : 0; - c = c->nextConnectionList; - } + if (signal_index < cd->signalVector.count()) { + const QObjectPrivate::Connection *c = + cd->signalVector.at(signal_index).first; + while (c) { + receivers += c->receiver ? 1 : 0; + c = c->nextConnectionList; } } } @@ -3269,23 +3243,21 @@ QObjectPrivate::Connection *QMetaObjectPrivate::connect(const QObject *sender, int method_offset = rmeta ? rmeta->methodOffset() : 0; Q_ASSERT(!rmeta || QMetaObjectPrivate::get(rmeta)->revision >= 6); - QObjectPrivate::StaticMetaCallFunction callFunction = - rmeta ? rmeta->d.static_metacall : 0; + QObjectPrivate::StaticMetaCallFunction callFunction = rmeta ? rmeta->d.static_metacall : nullptr; QOrderedMutexLocker locker(signalSlotLock(sender), signalSlotLock(receiver)); - if (type & Qt::UniqueConnection) { - QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists; - if (connectionLists && connectionLists->count() > signal_index) { - const QObjectPrivate::Connection *c2 = - (*connectionLists)[signal_index].first; + QObjectPrivate::ConnectionData *scd = QObjectPrivate::get(s)->connections.load(); + if (type & Qt::UniqueConnection && scd) { + if (scd->signalVector.count() > signal_index) { + const QObjectPrivate::Connection *c2 = scd->signalVector.at(signal_index).first; int method_index_absolute = method_index + method_offset; while (c2) { if (!c2->isSlotObject && c2->receiver == receiver && c2->method() == method_index_absolute) - return 0; + return nullptr; c2 = c2->nextConnectionList; } } @@ -3409,37 +3381,35 @@ bool QMetaObjectPrivate::disconnect(const QObject *sender, QMutex *senderMutex = signalSlotLock(sender); QMutexLocker locker(senderMutex); - QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists; - if (!connectionLists) + QObjectPrivate::ConnectionData *scd = QObjectPrivate::get(s)->connections.load(); + if (!scd) return false; - // prevent incoming connections changing the connectionLists while unlocked - ++connectionLists->inUse; + // prevent incoming connections changing the connections->receivers while unlocked + ++scd->inUse; bool success = false; if (signal_index < 0) { // remove from all connection lists - for (int sig_index = -1; sig_index < connectionLists->count(); ++sig_index) { - QObjectPrivate::Connection *c = - (*connectionLists)[sig_index].first; + for (int sig_index = -1; sig_index < scd->signalVector.count(); ++sig_index) { + QObjectPrivate::Connection *c = scd->connectionsForSignal(sig_index).first; if (disconnectHelper(c, receiver, method_index, slot, senderMutex, disconnectType)) { success = true; - connectionLists->dirty = true; + scd->dirty = true; } } - } else if (signal_index < connectionLists->count()) { - QObjectPrivate::Connection *c = - (*connectionLists)[signal_index].first; + } else if (signal_index < scd->signalVector.count()) { + QObjectPrivate::Connection *c = scd->signalVector.at(signal_index).first; if (disconnectHelper(c, receiver, method_index, slot, senderMutex, disconnectType)) { success = true; - connectionLists->dirty = true; + scd->dirty = true; } } - --connectionLists->inUse; - Q_ASSERT(connectionLists->inUse >= 0); - if (connectionLists->orphaned && !connectionLists->inUse) - delete connectionLists; + --scd->inUse; + Q_ASSERT(scd->inUse >= 0); + if (scd->orphaned && !scd->inUse) + delete scd; locker.unlock(); if (success) { @@ -3651,35 +3621,36 @@ void doActivate(QObject *sender, int signal_index, void **argv) { QMutexLocker locker(signalSlotLock(sender)); - struct ConnectionListsRef { - QObjectConnectionListVector *connectionLists; - ConnectionListsRef(QObjectConnectionListVector *connectionLists) : connectionLists(connectionLists) + struct ConnectionDataRef { + QObjectPrivate::ConnectionData *connections; + ConnectionDataRef(QObjectPrivate::ConnectionData *connections) : connections(connections) { - if (connectionLists) - ++connectionLists->inUse; + if (connections) + ++connections->inUse; } - ~ConnectionListsRef() + ~ConnectionDataRef() { - if (!connectionLists) + if (!connections) return; - --connectionLists->inUse; - Q_ASSERT(connectionLists->inUse >= 0); - if (connectionLists->orphaned) { - if (!connectionLists->inUse) - delete connectionLists; + --connections->inUse; + Q_ASSERT(connections->inUse >= 0); + if (connections->orphaned) { + if (!connections->inUse) + delete connections; } } - QObjectConnectionListVector *operator->() const { return connectionLists; } + QObjectPrivate::ConnectionData *operator->() const { return connections; } }; - ConnectionListsRef connectionLists = sp->connectionLists; + Q_ASSERT(sp->connections.load()); + ConnectionDataRef connections = sp->connections.load(); const QObjectPrivate::ConnectionList *list; - if (signal_index < connectionLists->count()) - list = &connectionLists->at(signal_index); + if (signal_index < connections->signalVector.count()) + list = &connections->signalVector.at(signal_index); else - list = &connectionLists->allsignals; + list = &connections->allsignals; Qt::HANDLE currentThreadId = QThread::currentThreadId(); @@ -3773,15 +3744,15 @@ void doActivate(QObject *sender, int signal_index, void **argv) locker.relock(); } - if (connectionLists->orphaned) + if (connections->orphaned) break; } while (c != last && (c = c->nextConnectionList) != 0); - if (connectionLists->orphaned) + if (connections->orphaned) break; - } while (list != &connectionLists->allsignals && + } while (list != &connections->allsignals && //start over for all signals; - ((list = &connectionLists->allsignals), true)); + ((list = &connections->allsignals), true)); } @@ -3832,7 +3803,7 @@ void QMetaObject::activate(QObject *sender, int signal_index, void **argv) /*! \internal - Returns the signal index used in the internal connectionLists vector. + Returns the signal index used in the internal connections->receivers vector. It is different from QMetaObject::indexOfSignal(): indexOfSignal is the same as indexOfMethod while QObjectPrivate::signalIndex is smaller because it doesn't give index to slots. @@ -4077,14 +4048,14 @@ void QObject::dumpObjectInfo() const // first, look for connections where this object is the sender qDebug(" SIGNALS OUT"); - if (d->connectionLists) { - for (int signal_index = 0; signal_index < d->connectionLists->count(); ++signal_index) { + QObjectPrivate::ConnectionData *cd = d->connections.load(); + if (cd && cd->signalVector.count()) { + for (int signal_index = 0; signal_index < cd->signalVector.count(); ++signal_index) { const QMetaMethod signal = QMetaObjectPrivate::signal(metaObject(), signal_index); qDebug(" signal: %s", signal.methodSignature().constData()); // receivers - const QObjectPrivate::Connection *c = - d->connectionLists->at(signal_index).first; + const QObjectPrivate::Connection *c = cd->signalVector.at(signal_index).first; while (c) { if (!c->receiver) { qDebug(" <Disconnected receiver>"); @@ -4112,8 +4083,8 @@ void QObject::dumpObjectInfo() const // now look for connections where this object is the receiver qDebug(" SIGNALS IN"); - if (d->senders) { - for (QObjectPrivate::Connection *s = d->senders; s; s = s->next) { + if (cd && cd->senders) { + for (QObjectPrivate::Connection *s = cd->senders; s; s = s->next) { QByteArray slotName = QByteArrayLiteral("<unknown>"); if (!s->isSlotObject) { const QMetaMethod slot = metaObject()->method(s->method()); @@ -4848,11 +4819,10 @@ QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int s QOrderedMutexLocker locker(signalSlotLock(sender), signalSlotLock(receiver)); - if (type & Qt::UniqueConnection && slot) { - QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists; - if (connectionLists && connectionLists->count() > signal_index) { - const QObjectPrivate::Connection *c2 = - (*connectionLists)[signal_index].first; + if (type & Qt::UniqueConnection && slot && QObjectPrivate::get(s)->connections.load()) { + QObjectPrivate::ConnectionData *connections = QObjectPrivate::get(s)->connections.load(); + if (connections->signalVector.count() > signal_index) { + const QObjectPrivate::Connection *c2 = connections->signalVector.at(signal_index).first; while (c2) { if (c2->receiver == receiver && c2->isSlotObject && c2->slotObj->compare(slot)) { @@ -4909,14 +4879,14 @@ bool QObject::disconnect(const QMetaObject::Connection &connection) { QOrderedMutexLocker locker(senderMutex, receiverMutex); - QObjectConnectionListVector *connectionLists = QObjectPrivate::get(c->sender)->connectionLists; - Q_ASSERT(connectionLists); - connectionLists->dirty = true; + QObjectPrivate::ConnectionData *connections = QObjectPrivate::get(c->sender)->connections.load(); + Q_ASSERT(connections); + connections->dirty = true; *c->prev = c->next; if (c->next) c->next->prev = c->prev; - c->receiver = 0; + c->receiver = nullptr; } // destroy the QSlotObject, if possible @@ -4928,7 +4898,7 @@ bool QObject::disconnect(const QMetaObject::Connection &connection) c->sender->disconnectNotify(QMetaObjectPrivate::signal(c->sender->metaObject(), c->signal_index)); - const_cast<QMetaObject::Connection &>(connection).d_ptr = 0; + const_cast<QMetaObject::Connection &>(connection).d_ptr = nullptr; c->deref(); // has been removed from the QMetaObject::Connection object return true; diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index ab20064c65..64998797ac 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -171,14 +171,15 @@ public: : receiver(receiver), sender(sender), signal(signal) { if (receiver) { - previous = receiver->d_func()->currentSender; - receiver->d_func()->currentSender = this; + ConnectionData *cd = receiver->d_func()->connections.load(); + previous = cd->currentSender; + cd->currentSender = this; } } ~Sender() { if (receiver) - receiver->d_func()->currentSender = previous; + receiver->d_func()->connections.load()->currentSender = previous; } void receiverDeleted() { @@ -194,6 +195,34 @@ public: int signal; }; + /* + This contains the all connections from and to an object. + + The signalVector contains the lists of connections for a given signal. The index in the vector correspond + to the signal index. The signal index is the one returned by QObjectPrivate::signalIndex (not + QMetaObject::indexOfSignal). allsignals contains a list of special connections that will get invoked on + any signal emission. This is done by connecting to signal index -1. + + This vector is protected by the object mutex (signalSlotLock()) + + Each Connection is also part of a 'senders' linked list. This one contains all connections connected + to a slot in this object. The mutex of the receiver must be locked when touching the pointers of this + linked list. + */ + struct ConnectionData { + bool orphaned = false; //the QObject owner of this vector has been destroyed while the vector was inUse + bool dirty = false; //some Connection have been disconnected (their receiver is 0) but not removed from the list yet + int inUse = 0; //number of functions that are currently accessing this object or its connections + ConnectionList allsignals; + QVector<ConnectionList> signalVector; + Connection *senders = nullptr; + Sender *currentSender = nullptr; // object currently activating the object + + ConnectionList &connectionsForSignal(int signal) + { + return signal < 0 ? allsignals : signalVector[signal]; + } + }; QObjectPrivate(int version = QObjectPrivateVersion); virtual ~QObjectPrivate(); @@ -240,14 +269,18 @@ public: const int *types, const QMetaObject *senderMetaObject); static QMetaObject::Connection connect(const QObject *sender, int signal_index, QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type); static bool disconnect(const QObject *sender, int signal_index, void **slot); + + void ensureConnectionData() + { + if (connections.load()) + return; + connections.store(new ConnectionData); + } public: ExtraData *extraData; // extra data set by the user QThreadData *threadData; // id of the thread that owns the object - QObjectConnectionListVector *connectionLists; - - Connection *senders; // linked list of connections connected to this object - Sender *currentSender; // object currently activating the object + QAtomicPointer<ConnectionData> connections; union { QObject *currentChildBeingDeleted; // should only be used when QObjectData::isDeletingChildren is set diff --git a/tests/auto/other/toolsupport/tst_toolsupport.cpp b/tests/auto/other/toolsupport/tst_toolsupport.cpp index 27bc6ba646..8c129adaf3 100644 --- a/tests/auto/other/toolsupport/tst_toolsupport.cpp +++ b/tests/auto/other/toolsupport/tst_toolsupport.cpp @@ -126,9 +126,9 @@ void tst_toolsupport::offsets_data() #ifdef Q_PROCESSOR_X86 // x86 32-bit has weird alignment rules. Refer to QtPrivate::AlignOf in // qglobal.h for more details. - data << 160 << 240; + data << 152 << 224; #else - data << 164 << 240; + data << 156 << 224; #endif } #endif From 0e534bf8b704b8ae24b87a9b1dcb5cd829c9dd2f Mon Sep 17 00:00:00 2001 From: Lars Knoll <lars.knoll@qt.io> Date: Wed, 9 Jan 2019 09:48:59 +0100 Subject: [PATCH 1096/1650] Replace the ConnectionData::inUse int with a proper refcount The main difference is that QObject itself also holds on reference on the structure. Also rename the orphaned flag to objectDeleted for clarity. Change-Id: Ief9b9ff9c8b9cc3630dcfd29806ed24cd07150e4 Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com> --- src/corelib/kernel/qobject.cpp | 78 +++++++++++----------------------- src/corelib/kernel/qobject_p.h | 16 +++++-- 2 files changed, 38 insertions(+), 56 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index b8e973a0a3..c3271b2c35 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -354,7 +354,7 @@ void QObjectPrivate::addConnection(int signal, Connection *c) void QObjectPrivate::cleanConnectionLists() { ConnectionData *cd = connections.load(); - if (cd->dirty && !cd->inUse) { + if (cd->dirty && cd->ref == 1) { // remove broken connections for (int signal = -1; signal < cd->signalVector.count(); ++signal) { ConnectionList &connectionList = cd->connectionsForSignal(signal); @@ -883,7 +883,6 @@ QObject::~QObject() QMutex *signalSlotMutex = signalSlotLock(this); QMutexLocker locker(signalSlotMutex); - ++cd->inUse; // disconnect all receivers int receiverCount = cd->signalVector.count(); @@ -949,7 +948,7 @@ QObject::~QObject() continue; } node->receiver = 0; - QObjectPrivate::ConnectionData *senderData = sender->d_func()->connections; + QObjectPrivate::ConnectionData *senderData = sender->d_func()->connections.load(); if (senderData) senderData->dirty = true; @@ -972,13 +971,11 @@ QObject::~QObject() } } - if (!--cd->inUse) { - delete cd; - } else { - cd->orphaned = true; - } - d->connections.store(nullptr); + cd->objectDeleted = true; } + if (cd && !cd->ref.deref()) + delete cd; + d->connections.store(nullptr); if (!d->children.isEmpty()) d->deleteChildren(); @@ -3385,32 +3382,29 @@ bool QMetaObjectPrivate::disconnect(const QObject *sender, if (!scd) return false; - // prevent incoming connections changing the connections->receivers while unlocked - ++scd->inUse; - bool success = false; - if (signal_index < 0) { - // remove from all connection lists - for (int sig_index = -1; sig_index < scd->signalVector.count(); ++sig_index) { - QObjectPrivate::Connection *c = scd->connectionsForSignal(sig_index).first; + { + // prevent incoming connections changing the connections->receivers while unlocked + QObjectPrivate::ConnectionDataPointer connections(scd); + + if (signal_index < 0) { + // remove from all connection lists + for (int sig_index = -1; sig_index < scd->signalVector.count(); ++sig_index) { + QObjectPrivate::Connection *c = scd->connectionsForSignal(sig_index).first; + if (disconnectHelper(c, receiver, method_index, slot, senderMutex, disconnectType)) { + success = true; + scd->dirty = true; + } + } + } else if (signal_index < scd->signalVector.count()) { + QObjectPrivate::Connection *c = scd->signalVector.at(signal_index).first; if (disconnectHelper(c, receiver, method_index, slot, senderMutex, disconnectType)) { success = true; scd->dirty = true; } } - } else if (signal_index < scd->signalVector.count()) { - QObjectPrivate::Connection *c = scd->signalVector.at(signal_index).first; - if (disconnectHelper(c, receiver, method_index, slot, senderMutex, disconnectType)) { - success = true; - scd->dirty = true; - } } - --scd->inUse; - Q_ASSERT(scd->inUse >= 0); - if (scd->orphaned && !scd->inUse) - delete scd; - locker.unlock(); if (success) { QMetaMethod smethod = QMetaObjectPrivate::signal(smeta, signal_index); @@ -3621,30 +3615,8 @@ void doActivate(QObject *sender, int signal_index, void **argv) { QMutexLocker locker(signalSlotLock(sender)); - struct ConnectionDataRef { - QObjectPrivate::ConnectionData *connections; - ConnectionDataRef(QObjectPrivate::ConnectionData *connections) : connections(connections) - { - if (connections) - ++connections->inUse; - } - ~ConnectionDataRef() - { - if (!connections) - return; - - --connections->inUse; - Q_ASSERT(connections->inUse >= 0); - if (connections->orphaned) { - if (!connections->inUse) - delete connections; - } - } - - QObjectPrivate::ConnectionData *operator->() const { return connections; } - }; - Q_ASSERT(sp->connections.load()); - ConnectionDataRef connections = sp->connections.load(); + Q_ASSERT(sp->connections); + QObjectPrivate::ConnectionDataPointer connections(sp->connections.load()); const QObjectPrivate::ConnectionList *list; if (signal_index < connections->signalVector.count()) @@ -3744,11 +3716,11 @@ void doActivate(QObject *sender, int signal_index, void **argv) locker.relock(); } - if (connections->orphaned) + if (connections->objectDeleted) break; } while (c != last && (c = c->nextConnectionList) != 0); - if (connections->orphaned) + if (connections->objectDeleted) break; } while (list != &connections->allsignals && //start over for all signals; diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 64998797ac..823c7a195a 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -210,9 +210,16 @@ public: linked list. */ struct ConnectionData { - bool orphaned = false; //the QObject owner of this vector has been destroyed while the vector was inUse + bool objectDeleted = false; //the QObject owner of this vector has been destroyed while the vector was inUse + struct Ref { + int _ref = 0; + void ref() { ++_ref; } + int deref() { return --_ref; } + operator int() const { return _ref; } + }; + + Ref ref; bool dirty = false; //some Connection have been disconnected (their receiver is 0) but not removed from the list yet - int inUse = 0; //number of functions that are currently accessing this object or its connections ConnectionList allsignals; QVector<ConnectionList> signalVector; Connection *senders = nullptr; @@ -274,12 +281,15 @@ public: { if (connections.load()) return; - connections.store(new ConnectionData); + ConnectionData *cd = new ConnectionData; + cd->ref.ref(); + connections.store(cd); } public: ExtraData *extraData; // extra data set by the user QThreadData *threadData; // id of the thread that owns the object + using ConnectionDataPointer = QExplicitlySharedDataPointer<ConnectionData>; QAtomicPointer<ConnectionData> connections; union { From aea500d5d76864bb1a3918e338ca6806e1766e41 Mon Sep 17 00:00:00 2001 From: Lars Knoll <lars.knoll@qt.io> Date: Wed, 9 Jan 2019 11:00:01 +0100 Subject: [PATCH 1097/1650] Use QBasicMutex instead of QMutex in the signalSlockLock() Add a simple private QBasicMutexLocker class, and let the QOrderedMutexLocker operate on a QBasicMutex. This allows the compiler to inline more things when handling connections and speeds up activate() a bit more. without change with change string based connect: 3621 3368 pointer based connect: 4341 3919 not connected: 433 437 disconnected: 551 538 Change-Id: If979337891178aaeb0b3340b6d4f68b6f86b0260 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com> --- src/corelib/kernel/qmetaobject_p.h | 4 +- src/corelib/kernel/qobject.cpp | 47 ++++++++-------- src/corelib/thread/qorderedmutexlocker_p.h | 62 +++++++++++++++++++--- 3 files changed, 81 insertions(+), 32 deletions(-) diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h index 522bd78e42..5b412b5140 100644 --- a/src/corelib/kernel/qmetaobject_p.h +++ b/src/corelib/kernel/qmetaobject_p.h @@ -54,6 +54,7 @@ #include <QtCore/qglobal.h> #include <QtCore/qobjectdefs.h> +#include <QtCore/qmutex.h> #ifndef QT_NO_QOBJECT #include <private/qobject_p.h> // For QObjectPrivate::Connection #endif @@ -168,7 +169,6 @@ Q_DECLARE_TYPEINFO(QArgumentType, Q_MOVABLE_TYPE); typedef QVarLengthArray<QArgumentType, 10> QArgumentTypeArray; class QMetaMethodPrivate; -class QMutex; struct QMetaObjectPrivate { @@ -234,7 +234,7 @@ struct QMetaObjectPrivate DisconnectType = DisconnectAll); static inline bool disconnectHelper(QObjectPrivate::Connection *c, const QObject *receiver, int method_index, void **slot, - QMutex *senderMutex, DisconnectType = DisconnectAll); + QBasicMutex *senderMutex, DisconnectType = DisconnectAll); #endif }; diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index c3271b2c35..3db43ba1c4 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -152,10 +152,9 @@ static QBasicMutex _q_ObjectMutexPool[131]; * \internal * mutex to be locked when accessing the connectionlists or the senders list */ -static inline QMutex *signalSlotLock(const QObject *o) +static inline QBasicMutex *signalSlotLock(const QObject *o) { - return static_cast<QMutex *>(&_q_ObjectMutexPool[ - uint(quintptr(o)) % sizeof(_q_ObjectMutexPool)/sizeof(QBasicMutex)]); + return &_q_ObjectMutexPool[uint(quintptr(o)) % sizeof(_q_ObjectMutexPool)/sizeof(QBasicMutex)]; } #if QT_VERSION < 0x60000 @@ -265,7 +264,7 @@ bool QObjectPrivate::isSender(const QObject *receiver, const char *signal) const ConnectionData *cd = connections.load(); if (signal_index < 0 || !cd) return false; - QMutexLocker locker(signalSlotLock(q)); + QBasicMutexLocker locker(signalSlotLock(q)); if (signal_index < cd->signalVector.count()) { const QObjectPrivate::Connection *c = cd->signalVector.at(signal_index).first; @@ -287,7 +286,7 @@ QObjectList QObjectPrivate::receiverList(const char *signal) const ConnectionData *cd = connections.load(); if (signal_index < 0 || !cd) return returnValue; - QMutexLocker locker(signalSlotLock(q)); + QBasicMutexLocker locker(signalSlotLock(q)); if (signal_index < cd->signalVector.count()) { const QObjectPrivate::Connection *c = cd->signalVector.at(signal_index).first; @@ -306,7 +305,7 @@ QObjectList QObjectPrivate::senderList() const QObjectList returnValue; ConnectionData *cd = connections.load(); if (cd) { - QMutexLocker locker(signalSlotLock(q_func())); + QBasicMutexLocker locker(signalSlotLock(q_func())); for (Connection *c = cd->senders; c; c = c->next) returnValue << c->sender; } @@ -881,8 +880,8 @@ QObject::~QObject() cd->currentSender = nullptr; } - QMutex *signalSlotMutex = signalSlotLock(this); - QMutexLocker locker(signalSlotMutex); + QBasicMutex *signalSlotMutex = signalSlotLock(this); + QBasicMutexLocker locker(signalSlotMutex); // disconnect all receivers int receiverCount = cd->signalVector.count(); @@ -896,7 +895,7 @@ QObject::~QObject() continue; } - QMutex *m = signalSlotLock(c->receiver); + QBasicMutex *m = signalSlotLock(c->receiver); bool needToUnlock = QOrderedMutexLocker::relock(signalSlotMutex, m); if (c->receiver) { @@ -937,7 +936,7 @@ QObject::~QObject() // This ensures any eventual destructor of sender will block on getting receiver's lock // and not finish until we release it. sender->disconnectNotify(QMetaObjectPrivate::signal(sender->metaObject(), node->signal_index)); - QMutex *m = signalSlotLock(sender); + QBasicMutex *m = signalSlotLock(sender); node->prev = &node; bool needToUnlock = QOrderedMutexLocker::relock(signalSlotMutex, m); //the node has maybe been removed while the mutex was unlocked in relock? @@ -1205,7 +1204,7 @@ bool QObject::event(QEvent *e) QMetaCallEvent *mce = static_cast<QMetaCallEvent*>(e); if (!d_func()->connections.load()) { - QMutexLocker locker(signalSlotLock(this)); + QBasicMutexLocker locker(signalSlotLock(this)); d_func()->ensureConnectionData(); } QObjectPrivate::Sender sender(this, const_cast<QObject*>(mce->sender()), mce->signalId()); @@ -2323,7 +2322,7 @@ QObject *QObject::sender() const { Q_D(const QObject); - QMutexLocker locker(signalSlotLock(this)); + QBasicMutexLocker locker(signalSlotLock(this)); QObjectPrivate::ConnectionData *cd = d->connections.load(); if (!cd || !cd->currentSender) return nullptr; @@ -2365,7 +2364,7 @@ int QObject::senderSignalIndex() const { Q_D(const QObject); - QMutexLocker locker(signalSlotLock(this)); + QBasicMutexLocker locker(signalSlotLock(this)); QObjectPrivate::ConnectionData *cd = d->connections.load(); if (!cd || !cd->currentSender) return -1; @@ -2430,7 +2429,7 @@ int QObject::receivers(const char *signal) const signal_index); } - QMutexLocker locker(signalSlotLock(this)); + QBasicMutexLocker locker(signalSlotLock(this)); if (signal_index < cd->signalVector.count()) { const QObjectPrivate::Connection *c = cd->signalVector.at(signal_index).first; @@ -2476,7 +2475,7 @@ bool QObject::isSignalConnected(const QMetaMethod &signal) const signalIndex += QMetaObjectPrivate::signalOffset(signal.mobj); - QMutexLocker locker(signalSlotLock(this)); + QBasicMutexLocker locker(signalSlotLock(this)); return d->isSignalConnected(signalIndex, true); } @@ -3318,7 +3317,7 @@ bool QMetaObject::disconnectOne(const QObject *sender, int signal_index, */ bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::Connection *c, const QObject *receiver, int method_index, void **slot, - QMutex *senderMutex, DisconnectType disconnectType) + QBasicMutex *senderMutex, DisconnectType disconnectType) { bool success = false; while (c) { @@ -3327,7 +3326,7 @@ bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::Connection *c, && (method_index < 0 || (!c->isSlotObject && c->method() == method_index)) && (slot == 0 || (c->isSlotObject && c->slotObj->compare(slot)))))) { bool needToUnlock = false; - QMutex *receiverMutex = 0; + QBasicMutex *receiverMutex = nullptr; if (c->receiver) { receiverMutex = signalSlotLock(c->receiver); // need to relock this receiver and sender in the correct order @@ -3375,8 +3374,8 @@ bool QMetaObjectPrivate::disconnect(const QObject *sender, QObject *s = const_cast<QObject *>(sender); - QMutex *senderMutex = signalSlotLock(sender); - QMutexLocker locker(senderMutex); + QBasicMutex *senderMutex = signalSlotLock(sender); + QBasicMutexLocker locker(senderMutex); QObjectPrivate::ConnectionData *scd = QObjectPrivate::get(s)->connections.load(); if (!scd) @@ -3523,7 +3522,7 @@ void QMetaObject::connectSlotsByName(QObject *o) \a signal must be in the signal index range (see QObjectPrivate::signalIndex()). */ static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connection *c, void **argv, - QMutexLocker &locker) + QBasicMutexLocker &locker) { const int *argumentTypes = c->argumentTypes.load(); if (!argumentTypes) { @@ -3614,7 +3613,7 @@ void doActivate(QObject *sender, int signal_index, void **argv) Q_TRACE(QMetaObject_activate_begin_signal, sender, signal_index); { - QMutexLocker locker(signalSlotLock(sender)); + QBasicMutexLocker locker(signalSlotLock(sender)); Q_ASSERT(sp->connections); QObjectPrivate::ConnectionDataPointer connections(sp->connections.load()); @@ -4015,7 +4014,7 @@ void QObject::dumpObjectInfo() const objectName().isEmpty() ? "unnamed" : objectName().toLocal8Bit().data()); Q_D(const QObject); - QMutexLocker locker(signalSlotLock(this)); + QBasicMutexLocker locker(signalSlotLock(this)); // first, look for connections where this object is the sender qDebug(" SIGNALS OUT"); @@ -4845,8 +4844,8 @@ bool QObject::disconnect(const QMetaObject::Connection &connection) if (!c || !c->receiver) return false; - QMutex *senderMutex = signalSlotLock(c->sender); - QMutex *receiverMutex = signalSlotLock(c->receiver); + QBasicMutex *senderMutex = signalSlotLock(c->sender); + QBasicMutex *receiverMutex = signalSlotLock(c->receiver); { QOrderedMutexLocker locker(senderMutex, receiverMutex); diff --git a/src/corelib/thread/qorderedmutexlocker_p.h b/src/corelib/thread/qorderedmutexlocker_p.h index ded102d32d..5b2c7ab112 100644 --- a/src/corelib/thread/qorderedmutexlocker_p.h +++ b/src/corelib/thread/qorderedmutexlocker_p.h @@ -58,6 +58,8 @@ QT_BEGIN_NAMESPACE +#if QT_CONFIG(thread) + /* Locks 2 mutexes in a defined order, avoiding a recursive lock if we're trying to lock the same mutex twice. @@ -65,9 +67,9 @@ QT_BEGIN_NAMESPACE class QOrderedMutexLocker { public: - QOrderedMutexLocker(QMutex *m1, QMutex *m2) - : mtx1((m1 == m2) ? m1 : (std::less<QMutex *>()(m1, m2) ? m1 : m2)), - mtx2((m1 == m2) ? 0 : (std::less<QMutex *>()(m1, m2) ? m2 : m1)), + QOrderedMutexLocker(QBasicMutex *m1, QBasicMutex *m2) + : mtx1((m1 == m2) ? m1 : (std::less<QBasicMutex *>()(m1, m2) ? m1 : m2)), + mtx2((m1 == m2) ? 0 : (std::less<QBasicMutex *>()(m1, m2) ? m2 : m1)), locked(false) { relock(); @@ -95,12 +97,12 @@ public: } } - static bool relock(QMutex *mtx1, QMutex *mtx2) + static bool relock(QBasicMutex *mtx1, QBasicMutex *mtx2) { // mtx1 is already locked, mtx2 not... do we need to unlock and relock? if (mtx1 == mtx2) return false; - if (std::less<QMutex *>()(mtx1, mtx2)) { + if (std::less<QBasicMutex *>()(mtx1, mtx2)) { mtx2->lock(); return true; } @@ -113,10 +115,58 @@ public: } private: - QMutex *mtx1, *mtx2; + QBasicMutex *mtx1, *mtx2; bool locked; }; +class QBasicMutexLocker +{ +public: + inline explicit QBasicMutexLocker(QBasicMutex *m) QT_MUTEX_LOCK_NOEXCEPT + : m(m), isLocked(true) + { + m->lock(); + } + inline ~QBasicMutexLocker() { if (isLocked) unlock(); } + + inline void unlock() Q_DECL_NOTHROW + { + isLocked = false; + m->unlock(); + } + + inline void relock() QT_MUTEX_LOCK_NOEXCEPT + { + isLocked = true; + m->lock(); + } + +private: + Q_DISABLE_COPY(QBasicMutexLocker) + + QBasicMutex *m; + bool isLocked; +}; + +#else + +class QOrderedMutexLocker +{ +public: + QOrderedMutexLocker(QBasicMutex *, QBasicMutex *) {} + ~QOrderedMutexLocker() {} + + void relock() {} + void unlock() {} + + static bool relock(QBasicMutex *, QBasicMutex *) {} +}; + +using QBasicMutexLocker = QMutexLocker; + +#endif + + QT_END_NAMESPACE #endif From 484eec96f9b2235780119526faeb6d69536f509c Mon Sep 17 00:00:00 2001 From: Olivier Goffart <ogoffart@woboq.com> Date: Sat, 19 Jan 2019 15:32:07 +0100 Subject: [PATCH 1098/1650] Add a couple of tests in QObject::tst_qobject For destructors of functor connected to signals Change-Id: I3f8b18fee7507f3cb72e36a2f9e6ef7f37dbeea1 Reviewed-by: Lars Knoll <lars.knoll@qt.io> --- .../corelib/kernel/qobject/tst_qobject.cpp | 165 ++++++++++++++++++ 1 file changed, 165 insertions(+) diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 31268c5cf3..b823ca2aab 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -154,6 +154,8 @@ private slots: void mutableFunctor(); void checkArgumentsForNarrowing(); void nullReceiver(); + void functorReferencesConnection(); + void disconnectDisconnects(); }; struct QObjectCreatedOnShutdown @@ -7487,6 +7489,169 @@ void tst_QObject::nullReceiver() QVERIFY(!connect(&o, SIGNAL(destroyed()), nullObj, SLOT(deleteLater()))); } +void tst_QObject::functorReferencesConnection() +{ + countedStructObjectsCount = 0; + QMetaObject::Connection globalCon; + { + GetSenderObject obj; + CountedStruct counted(&obj); + QCOMPARE(countedStructObjectsCount, 1); + auto c = QSharedPointer<QMetaObject::Connection>::create(); + int slotCalled = 0; + *c = connect(&obj, &GetSenderObject::aSignal, &obj, [&slotCalled, c, counted] { + QObject::disconnect(*c); + slotCalled++; + }); + globalCon = *c; // keep a handle to the connection somewhere; + QVERIFY(globalCon); + QCOMPARE(countedStructObjectsCount, 2); + obj.triggerSignal(); + QCOMPARE(slotCalled, 1); + QCOMPARE(countedStructObjectsCount, 1); + QVERIFY(!globalCon); + obj.triggerSignal(); + QCOMPARE(slotCalled, 1); + QCOMPARE(countedStructObjectsCount, 1); + } + QCOMPARE(countedStructObjectsCount, 0); + + { + GetSenderObject obj; + CountedStruct counted(&obj); + QCOMPARE(countedStructObjectsCount, 1); + auto *rec = new QObject; + int slotCalled = 0; + globalCon = connect(&obj, &GetSenderObject::aSignal, rec, [&slotCalled, rec, counted] { + delete rec; + slotCalled++; + }); + QCOMPARE(countedStructObjectsCount, 2); + obj.triggerSignal(); + QCOMPARE(slotCalled, 1); + QCOMPARE(countedStructObjectsCount, 1); + QVERIFY(!globalCon); + obj.triggerSignal(); + QCOMPARE(slotCalled, 1); + QCOMPARE(countedStructObjectsCount, 1); + } + QCOMPARE(countedStructObjectsCount, 0); + { + int slotCalled = 0; + QEventLoop eventLoop; + { + // Sender will be destroyed when the labda goes out of scope lambda, so it will exit the event loop + auto sender = QSharedPointer<GetSenderObject>::create(); + connect(sender.data(), &QObject::destroyed, &eventLoop, &QEventLoop::quit, Qt::QueuedConnection); + globalCon = connect(sender.data(), &GetSenderObject::aSignal, this, [&slotCalled, sender, &globalCon, this] { + ++slotCalled; + // This signal will be connected, but should never be called as the sender will be destroyed before + auto c2 = connect(sender.data(), &GetSenderObject::aSignal, [] { QFAIL("Should not be called"); }); + QVERIFY(c2); + QVERIFY(QObject::disconnect(sender.data(), nullptr, this, nullptr)); + QVERIFY(!globalCon); // this connection has been disconnected + QVERIFY(c2); // sender should not have been deleted yet, only after the emission is done + }); + QMetaObject::invokeMethod(sender.data(), &GetSenderObject::triggerSignal, Qt::QueuedConnection); + QMetaObject::invokeMethod(sender.data(), &GetSenderObject::triggerSignal, Qt::QueuedConnection); + QMetaObject::invokeMethod(sender.data(), &GetSenderObject::triggerSignal, Qt::QueuedConnection); + } + eventLoop.exec(); + QCOMPARE(slotCalled, 1); + } + + { + GetSenderObject obj; + CountedStruct counted(&obj); + QCOMPARE(countedStructObjectsCount, 1); + auto c1 = QSharedPointer<QMetaObject::Connection>::create(); + auto c2 = QSharedPointer<QMetaObject::Connection>::create(); + int slot1Called = 0; + int slot3Called = 0; + *c1 = connect(&obj, &GetSenderObject::aSignal, &obj, [&slot1Called, &slot3Called, &obj, c1, c2, counted] { + auto c3 = connect(&obj, &GetSenderObject::aSignal, [counted, &slot3Called] { + slot3Called++; + }); + // top-level + the one in the 3 others lambdas + QCOMPARE(countedStructObjectsCount, 4); + QObject::disconnect(*c2); + // the one in the c2's lambda is gone + QCOMPARE(countedStructObjectsCount, 3); + slot1Called++; + }); + connect(&obj, &GetSenderObject::aSignal, [] {}); // just a dummy signal to fill the connection list + *c2 = connect(&obj, &GetSenderObject::aSignal, [counted, c2] { QFAIL("should not be called"); }); + QVERIFY(c1 && c2); + QCOMPARE(countedStructObjectsCount, 3); // top-level + c1 + c2 + obj.triggerSignal(); + QCOMPARE(slot1Called, 1); + QCOMPARE(slot3Called, 0); + QCOMPARE(countedStructObjectsCount, 3); // top-level + c1 + c3 + QObject::disconnect(*c1); + QCOMPARE(countedStructObjectsCount, 2); // top-level + c3 + obj.triggerSignal(); + QCOMPARE(slot1Called, 1); + QCOMPARE(slot3Called, 1); + } + { + struct DestroyEmit { + Q_DISABLE_COPY(DestroyEmit); + explicit DestroyEmit(SenderObject *obj) : obj(obj) {} + SenderObject *obj; + ~DestroyEmit() { + obj->emitSignal1(); + } + }; + SenderObject obj; + int slot1Called = 0; + int slot2Called = 0; + int slot3Called = 0; + auto c1 = QSharedPointer<QMetaObject::Connection>::create(); + auto de = QSharedPointer<DestroyEmit>::create(&obj); + *c1 = connect(&obj, &SenderObject::signal1, [&slot1Called, &slot3Called, de, c1, &obj] { + connect(&obj, &SenderObject::signal1, [&slot3Called] { slot3Called++; }); + slot1Called++; + QObject::disconnect(*c1); + }); + de.clear(); + connect(&obj, &SenderObject::signal1, [&slot2Called] { slot2Called++; }); + obj.emitSignal1(); + QCOMPARE(slot1Called, 1); + QCOMPARE(slot2Called, 2); // because also called from ~DestroyEmit + QCOMPARE(slot3Called, 1); + } +} + +void tst_QObject::disconnectDisconnects() +{ + // Test what happens if the destructor of an functor slot also disconnects more slot; + + SenderObject s1; + QScopedPointer<QObject> receiver(new QObject); + + auto s2 = QSharedPointer<SenderObject>::create(); + QPointer<QObject> s2_tracker = s2.data(); + int count = 0; + connect(&s1, &SenderObject::signal1, [&count] { count++; }); // α + connect(&s1, &SenderObject::signal1, receiver.data(), [s2] { QFAIL("!!"); }); // β + connect(s2.data(), &SenderObject::signal1, receiver.data(), [] { QFAIL("!!"); }); + connect(&s1, &SenderObject::signal2, receiver.data(), [] { QFAIL("!!"); }); + connect(s2.data(), &SenderObject::signal2, receiver.data(), [] { QFAIL("!!"); }); + connect(&s1, &SenderObject::signal1, [&count] { count++; }); // γ + connect(&s1, &SenderObject::signal2, [&count] { count++; }); // δ + s2.clear(); + + QVERIFY(s2_tracker); + receiver + .reset(); // this will delete the receiver which must also delete s2 as β is disconnected + QVERIFY(!s2_tracker); + // test that the data structures are still in order + s1.emitSignal1(); + QCOMPARE(count, 2); // α + γ + s1.emitSignal2(); + QCOMPARE(count, 3); // + δ +} + // Test for QtPrivate::HasQ_OBJECT_Macro Q_STATIC_ASSERT(QtPrivate::HasQ_OBJECT_Macro<tst_QObject>::Value); Q_STATIC_ASSERT(!QtPrivate::HasQ_OBJECT_Macro<SiblingDeleter>::Value); From b179abc33b7111e889ca45f48f0ddd5c0182fa2e Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen <allan.jensen@qt.io> Date: Thu, 29 Nov 2018 11:01:09 +0100 Subject: [PATCH 1099/1650] Remove old dead code Nothing references this, not even commented out debug code, and some functions doesn't even have implementations. Change-Id: I344de26a650b1180f0da78eaece5bd5688fdcd95 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io> --- src/gui/painting/qpaintengine_raster.cpp | 76 ---------------------- src/gui/painting/qpaintengine_raster_p.h | 20 ------ src/widgets/kernel/qwidgetbackingstore.cpp | 6 -- src/widgets/kernel/qwidgetbackingstore_p.h | 1 - 4 files changed, 103 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 0f5c7756ad..66af6e3de3 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -552,35 +552,6 @@ bool QRasterPaintEngine::end() return true; } -/*! - \internal -*/ -void QRasterPaintEngine::releaseBuffer() -{ - Q_D(QRasterPaintEngine); - d->rasterBuffer.reset(new QRasterBuffer); -} - -/*! - \internal -*/ -QSize QRasterPaintEngine::size() const -{ - Q_D(const QRasterPaintEngine); - return QSize(d->rasterBuffer->width(), d->rasterBuffer->height()); -} - -/*! - \internal -*/ -#ifndef QT_NO_DEBUG -void QRasterPaintEngine::saveBuffer(const QString &s) const -{ - Q_D(const QRasterPaintEngine); - d->rasterBuffer->bufferImage().save(s, "PNG"); -} -#endif - /*! \internal */ @@ -3845,11 +3816,6 @@ QImage::Format QRasterBuffer::prepare(QImage *image) return format; } -void QRasterBuffer::resetBuffer(int val) -{ - memset(m_buffer, val, m_height*bytes_per_line); -} - QClipData::QClipData(int height) { clipSpanHeight = height; @@ -4272,48 +4238,6 @@ static void qt_span_clip(int count, const QSpan *spans, void *userData) } } -#ifndef QT_NO_DEBUG -QImage QRasterBuffer::bufferImage() const -{ - QImage image(m_width, m_height, QImage::Format_ARGB32_Premultiplied); - - for (int y = 0; y < m_height; ++y) { - uint *span = (uint *)const_cast<QRasterBuffer *>(this)->scanLine(y); - - for (int x=0; x<m_width; ++x) { - uint argb = span[x]; - image.setPixel(x, y, argb); - } - } - return image; -} -#endif - - -void QRasterBuffer::flushToARGBImage(QImage *target) const -{ - int w = qMin(m_width, target->width()); - int h = qMin(m_height, target->height()); - - for (int y=0; y<h; ++y) { - uint *sourceLine = (uint *)const_cast<QRasterBuffer *>(this)->scanLine(y); - QRgb *dest = (QRgb *) target->scanLine(y); - for (int x=0; x<w; ++x) { - QRgb pixel = sourceLine[x]; - int alpha = qAlpha(pixel); - if (!alpha) { - dest[x] = 0; - } else { - dest[x] = (alpha << 24) - | ((255*qRed(pixel)/alpha) << 16) - | ((255*qGreen(pixel)/alpha) << 8) - | ((255*qBlue(pixel)/alpha) << 0); - } - } - } -} - - class QGradientCache { public: diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h index 881144d1c2..c3734f1c62 100644 --- a/src/gui/painting/qpaintengine_raster_p.h +++ b/src/gui/painting/qpaintengine_raster_p.h @@ -208,15 +208,6 @@ public: ClipType clipType() const; QRect clipBoundingRect() const; - void releaseBuffer(); - - QSize size() const; - -#ifndef QT_NO_DEBUG - void saveBuffer(const QString &s) const; -#endif - - #ifdef Q_OS_WIN void setDC(HDC hdc); HDC getDC() const; @@ -442,20 +433,9 @@ public: void init(); QImage::Format prepare(QImage *image); - QImage::Format prepare(QPixmap *pix); - void prepare(int w, int h); - void prepareBuffer(int w, int h); - - void resetBuffer(int val=0); uchar *scanLine(int y) { Q_ASSERT(y>=0); Q_ASSERT(y<m_height); return m_buffer + y * bytes_per_line; } -#ifndef QT_NO_DEBUG - QImage bufferImage() const; -#endif - - void flushToARGBImage(QImage *image) const; - int width() const { return m_width; } int height() const { return m_height; } int bytesPerLine() const { return bytes_per_line; } diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index a32eb2a03b..69460bcd54 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -310,12 +310,6 @@ bool QWidgetBackingStore::bltRect(const QRect &rect, int dx, int dy, QWidget *wi return store->scroll(tlwRect, dx, dy); } -void QWidgetBackingStore::releaseBuffer() -{ - if (store) - store->resize(QSize()); -} - /*! Prepares the window surface to paint a\ toClean region of the \a widget and updates the BeginPaintInfo struct accordingly. diff --git a/src/widgets/kernel/qwidgetbackingstore_p.h b/src/widgets/kernel/qwidgetbackingstore_p.h index 41469a04bb..a1846da44e 100644 --- a/src/widgets/kernel/qwidgetbackingstore_p.h +++ b/src/widgets/kernel/qwidgetbackingstore_p.h @@ -151,7 +151,6 @@ private: void doSync(); bool bltRect(const QRect &rect, int dx, int dy, QWidget *widget); - void releaseBuffer(); void beginPaint(QRegion &toClean, QWidget *widget, QBackingStore *backingStore, BeginPaintInfo *returnInfo, bool toCleanIsInTopLevelCoordinates = true); From 4247d7c5a0c9a5133245b935eef017149f49de87 Mon Sep 17 00:00:00 2001 From: Lars Knoll <lars.knoll@qt.io> Date: Wed, 23 Jan 2019 14:12:47 +0100 Subject: [PATCH 1100/1650] Fix QTextTable:insertRows() for tables with spanning cells Don't resize the height of cells spanning several columns multiple times. Fixes: QTBUG-36713 Change-Id: I5eb45892f2008e6a4f85745b56efd04323e25673 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> --- src/gui/text/qtexttable.cpp | 12 ++++++++---- tests/auto/gui/text/qtexttable/tst_qtexttable.cpp | 6 ++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/gui/text/qtexttable.cpp b/src/gui/text/qtexttable.cpp index 9639c18d2b..39f26d5d42 100644 --- a/src/gui/text/qtexttable.cpp +++ b/src/gui/text/qtexttable.cpp @@ -696,18 +696,22 @@ void QTextTable::insertRows(int pos, int num) int extended = 0; int insert_before = 0; if (pos > 0 && pos < d->nRows) { + int lastCell = -1; for (int i = 0; i < d->nCols; ++i) { int cell = d->grid[pos*d->nCols + i]; if (cell == d->grid[(pos-1)*d->nCols+i]) { // cell spans the insertion place, extend it - QTextDocumentPrivate::FragmentIterator it(&p->fragmentMap(), cell); - QTextCharFormat fmt = c->charFormat(it->format); - fmt.setTableCellRowSpan(fmt.tableCellRowSpan() + num); - p->setCharFormat(it.position(), 1, fmt); + if (cell != lastCell) { + QTextDocumentPrivate::FragmentIterator it(&p->fragmentMap(), cell); + QTextCharFormat fmt = c->charFormat(it->format); + fmt.setTableCellRowSpan(fmt.tableCellRowSpan() + num); + p->setCharFormat(it.position(), 1, fmt); + } extended++; } else if (!insert_before) { insert_before = cell; } + lastCell = cell; } } else { insert_before = (pos == 0 ? d->grid[0] : d->fragment_end); diff --git a/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp b/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp index 29eef506bf..22f00c677d 100644 --- a/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp +++ b/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp @@ -431,6 +431,12 @@ void tst_QTextTable::insertRows() table->insertRows(5, 2); QCOMPARE(table->rows(), 7); + table = cursor.insertTable(5,5); + table->mergeCells(0,0,3,3); + table->insertRows(2,1); + + QCOMPARE(table->rows(), 6); + } void tst_QTextTable::deleteInTable() From 79f2a9e666a241c5baba1b9bf35c12be4cefcc26 Mon Sep 17 00:00:00 2001 From: Lars Knoll <lars.knoll@qt.io> Date: Fri, 25 Jan 2019 10:17:18 +0100 Subject: [PATCH 1101/1650] Fix an assertion in the BiDi algorithm The algorithm has been treating DirB inconsistently so far. initScriptAnalysisAndIsolatePairs was treating it differently than generateDireationalRuns leading to assertions. It wasn't visible in our test data, as DirB is in almost all cases the paragraph separator, where we split strings anyway. Change-Id: I7dc0e7bbcf30ee84d8781ea06097da023e371f05 Fixes: QTBUG-73238 Reviewed-by: Robert Loehning <robert.loehning@qt.io> Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> --- src/gui/text/qtextengine.cpp | 42 ++++++++++++------- .../other/qcomplextext/tst_qcomplextext.cpp | 6 +++ 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 9ed497839c..f305b9b7dc 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -252,8 +252,6 @@ struct QBidiAlgorithm { void initScriptAnalysisAndIsolatePairs(Vector<IsolatePair> &isolatePairs) { - isolatePairs.append({ -1, length }); // treat the whole string as one isolate - int isolateStack[128]; int isolateLevel = 0; // load directions of string, and determine isolate pairs @@ -304,6 +302,14 @@ struct QBidiAlgorithm { case QChar::DirS: case QChar::DirB: analysis[pos].bidiFlags = QScriptAnalysis::BidiResetToParagraphLevel; + if (uc == QChar::ParagraphSeparator) { + // close all open isolates as we start a new paragraph + while (isolateLevel > 0) { + --isolateLevel; + if (isolateLevel < 128) + isolatePairs[isolateStack[isolateLevel]].end = pos; + } + } break; default: break; @@ -434,21 +440,21 @@ struct QBidiAlgorithm { doEmbed(true, true, false); break; case QChar::DirLRI: - ++isolatePairPosition; Q_ASSERT(isolatePairs.at(isolatePairPosition).start == i); doEmbed(false, false, true); + ++isolatePairPosition; break; case QChar::DirRLI: - ++isolatePairPosition; Q_ASSERT(isolatePairs.at(isolatePairPosition).start == i); doEmbed(true, false, true); + ++isolatePairPosition; break; case QChar::DirFSI: { - ++isolatePairPosition; const auto &pair = isolatePairs.at(isolatePairPosition); Q_ASSERT(pair.start == i); bool isRtl = QStringView(text + pair.start + 1, pair.end - pair.start - 1).isRightToLeft(); doEmbed(isRtl, false, true); + ++isolatePairPosition; break; } @@ -492,16 +498,24 @@ struct QBidiAlgorithm { analysis[i].bidiDirection = (level & 1) ? QChar::DirR : QChar::DirL; break; case QChar::DirB: - // paragraph separator, go down to base direction - appendRun(i - 1); - while (stack.counter > 1) { - // there might be remaining isolates on the stack that are missing a PDI. Those need to get - // a continuation indicating to take the eos from the end of the string (ie. the paragraph level) - const auto &t = stack.top(); - if (t.isIsolate) { - runs[t.runBeforeIsolate].continuation = -2; + // paragraph separator, go down to base direction, reset all state + if (text[i].unicode() == QChar::ParagraphSeparator) { + appendRun(i - 1); + while (stack.counter > 1) { + // there might be remaining isolates on the stack that are missing a PDI. Those need to get + // a continuation indicating to take the eos from the end of the string (ie. the paragraph level) + const auto &t = stack.top(); + if (t.isIsolate) { + runs[t.runBeforeIsolate].continuation = -2; + } + --stack.counter; } - --stack.counter; + continuationFrom = -1; + lastRunWithContent = -1; + validIsolateCount = 0; + overflowIsolateCount = 0; + overflowEmbeddingCount = 0; + level = baseLevel; } break; default: diff --git a/tests/auto/other/qcomplextext/tst_qcomplextext.cpp b/tests/auto/other/qcomplextext/tst_qcomplextext.cpp index 0116e546a0..c328776089 100644 --- a/tests/auto/other/qcomplextext/tst_qcomplextext.cpp +++ b/tests/auto/other/qcomplextext/tst_qcomplextext.cpp @@ -68,6 +68,12 @@ void tst_QComplexText::bidiReorderString_data() << (int) data->basicDir; data++; } + + QString isolateAndBoundary = QString(QChar(0x2068 /* DirFSI */)) + QChar(0x1c /* DirB */) + QChar(0x2069 /* DirPDI */); + QTest::newRow( "isolateAndBoundary" ) + << QString::fromUtf8( data->logical ) + << QString::fromUtf8( data->visual ) + << (int) QChar::DirL; } void tst_QComplexText::bidiReorderString() From 035d80407b693662c209cd4f156085d583ad428c Mon Sep 17 00:00:00 2001 From: Lars Knoll <lars.knoll@qt.io> Date: Fri, 25 Jan 2019 10:49:34 +0100 Subject: [PATCH 1102/1650] Fix two smaller bugs in the BiDi engine Remove wrong code changing the Bido level of line separators. This lead to wrong ordering of the string in case the line separator was meant to be ignored and the string should be rendered in one line. Line breaks are anyways already reset to the paragraph level by the algorithm and reordering is done on a line by line basis, so this will work correctly when doing proper line breaking. Secondly fix a small bug found while testing the above change, where we wouldn't set the correct levels for boundary neutrals and explicit embedding chars because we did that processing before we were fully done with the BiDi algorithm. Change-Id: Id88f91cd58d2ab29be864aef34ca1727c1586611 Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com> Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> --- src/gui/text/qtextengine.cpp | 34 +++++++++---------- .../other/qcomplextext/bidireorderstring.h | 2 +- .../other/qcomplextext/tst_qcomplextext.cpp | 7 +++- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index f305b9b7dc..a83ef95c79 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1108,6 +1108,22 @@ struct QBidiAlgorithm { resolveImplicitLevels(runs); } + BIDI_DEBUG() << "Rule L1:"; + // Rule L1: + bool resetLevel = true; + for (int i = length - 1; i >= 0; --i) { + if (analysis[i].bidiFlags & QScriptAnalysis::BidiResetToParagraphLevel) { + BIDI_DEBUG() << "resetting pos" << i << "to baselevel"; + analysis[i].bidiLevel = baseLevel; + resetLevel = true; + } else if (resetLevel && analysis[i].bidiFlags & QScriptAnalysis::BidiMaybeResetToParagraphLevel) { + BIDI_DEBUG() << "resetting pos" << i << "to baselevel (maybereset flag)"; + analysis[i].bidiLevel = baseLevel; + } else { + resetLevel = false; + } + } + // set directions for BN to the minimum of adjacent chars // This makes is possible to be conformant with the Bidi algorithm even though we don't // remove BN and explicit embedding chars from the stream of characters to reorder @@ -1139,22 +1155,6 @@ struct QBidiAlgorithm { } } - BIDI_DEBUG() << "Rule L1:"; - // Rule L1: - bool resetLevel = true; - for (int i = length - 1; i >= 0; --i) { - if (analysis[i].bidiFlags & QScriptAnalysis::BidiResetToParagraphLevel) { - BIDI_DEBUG() << "resetting pos" << i << "to baselevel"; - analysis[i].bidiLevel = baseLevel; - resetLevel = true; - } else if (resetLevel && analysis[i].bidiFlags & QScriptAnalysis::BidiMaybeResetToParagraphLevel) { - BIDI_DEBUG() << "resetting pos" << i << "to baselevel (maybereset flag)"; - analysis[i].bidiLevel = baseLevel; - } else { - resetLevel = false; - } - } - if (BidiDebugEnabled) { BIDI_DEBUG() << "final resolved levels:"; for (int i = 0; i < length; ++i) @@ -2087,8 +2087,6 @@ void QTextEngine::itemize() const analysis->flags = QScriptAnalysis::Object; break; case QChar::LineSeparator: - if (analysis->bidiLevel % 2) - --analysis->bidiLevel; analysis->flags = QScriptAnalysis::LineOrParagraphSeparator; if (option.flags() & QTextOption::ShowLineAndParagraphSeparators) { const int offset = uc - string; diff --git a/tests/auto/other/qcomplextext/bidireorderstring.h b/tests/auto/other/qcomplextext/bidireorderstring.h index a7401d2c18..b537bf45e4 100644 --- a/tests/auto/other/qcomplextext/bidireorderstring.h +++ b/tests/auto/other/qcomplextext/bidireorderstring.h @@ -78,7 +78,7 @@ const LV logical_visual[] = { { "data42", "foo\nfoo", "foo\nfoo", QChar::DirL }, { "data43", "\327\251\327\234\327\225\327\235\n\327\251\327\234\327\225\327\235", "\327\235\327\225\327\234\327\251\n\327\235\327\225\327\234\327\251", QChar::DirR }, { "data44", "foo\n\327\251\327\234\327\225\327\235", "foo\n\327\235\327\225\327\234\327\251", QChar::DirL }, - { "data45", "\327\251\327\234\327\225\327\235\nfoo", "\327\235\327\225\327\234\327\251\nfoo", QChar::DirR }, + { "data45", "\327\251\327\234\327\225\327\235\nfoo", "foo\n\327\235\327\225\327\234\327\251", QChar::DirR }, { "data46", "\330\250 1.23 \330\250", "\330\250 1.23 \330\250", QChar::DirR }, { "data47", "\331\204\330\250 1.23 \331\202\330\250", "\330\250\331\202 1.23 \330\250\331\204", QChar::DirR }, { "data48", "\330\250 1.2 \330\250", "\330\250 1.2 \330\250", QChar::DirR }, diff --git a/tests/auto/other/qcomplextext/tst_qcomplextext.cpp b/tests/auto/other/qcomplextext/tst_qcomplextext.cpp index c328776089..9ca61a69b4 100644 --- a/tests/auto/other/qcomplextext/tst_qcomplextext.cpp +++ b/tests/auto/other/qcomplextext/tst_qcomplextext.cpp @@ -66,6 +66,11 @@ void tst_QComplexText::bidiReorderString_data() << QString::fromUtf8( data->logical ) << QString::fromUtf8( data->visual ) << (int) data->basicDir; + + QTest::newRow( QByteArray(data->name) + " (doubled)" ) + << (QString::fromUtf8( data->logical ) + QChar(QChar::ParagraphSeparator) + QString::fromUtf8( data->logical )) + << (QString::fromUtf8( data->visual ) + QChar(QChar::ParagraphSeparator) + QString::fromUtf8( data->visual )) + << (int) data->basicDir; data++; } @@ -432,7 +437,7 @@ ushort unicodeForDirection(const QByteArray &direction) { "ET", 0x24 }, { "AN", 0x660 }, { "CS", 0x2c }, - { "B", QChar::ParagraphSeparator }, + { "B", '\n' }, { "S", 0x9 }, { "WS", 0x20 }, { "ON", 0x2a }, From 7472415f3f331ccd415cc644cc210d2457ef690c Mon Sep 17 00:00:00 2001 From: Samuli Piippo <samuli.piippo@qt.io> Date: Tue, 5 Feb 2019 10:52:47 +0200 Subject: [PATCH 1103/1650] tst_QMenu: skip part of menuSize_Scrolling test Test fails on minimal and offscreen platforms. Task-number: QTBUG-73522 Task-number: QTQAINFRA-2630 Change-Id: I6260454be35a8bbac1ab683d89fb7b262d3b69ab Reviewed-by: Sami Nurmenniemi <sami.nurmenniemi@qt.io> Reviewed-by: Ville Voutilainen <ville.voutilainen@qt.io> --- tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp index a3e8ac44e6..3bfbe754ef 100644 --- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp +++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp @@ -1579,6 +1579,13 @@ void tst_QMenu::menuSize_Scrolling() #ifdef Q_OS_WINRT QEXPECT_FAIL("", "Broken on WinRT - QTBUG-68297", Abort); #endif + if (!QGuiApplication::platformName().compare(QLatin1String("minimal"), Qt::CaseInsensitive) + || !QGuiApplication::platformName().compare(QLatin1String("offscreen"), Qt::CaseInsensitive)) { + QWARN("Skipping test on minimal/offscreen platforms - QTBUG-73522"); + QMenu::showEvent(e); + return; + } + QCOMPARE( s.width(), lastItem.right() + fw + hmargin + rightMargin + 1); QMenu::showEvent(e); } From e48b85408752725bd9e90f303354bcdd380b3448 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen <allan.jensen@qt.io> Date: Fri, 22 Sep 2017 14:54:39 +0200 Subject: [PATCH 1104/1650] Simplify freetype rendering Switch to always using FT_Render_Glyph for all glyph types. Change-Id: I9427bbffd30a8d1ca92d7ab9a92df8761f6b89c3 Reviewed-by: Lars Knoll <lars.knoll@qt.io> --- .../fontdatabases/freetype/qfontengine_ft.cpp | 326 ++++-------------- 1 file changed, 75 insertions(+), 251 deletions(-) diff --git a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp index 381db1ed12..40db7dbac7 100644 --- a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp +++ b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp @@ -121,13 +121,12 @@ class QtFreetypeData { public: QtFreetypeData() - : library(0), hasPatentFreeLcdRendering(false) + : library(0) { } ~QtFreetypeData(); FT_Library library; QHash<QFontEngine::FaceId, QFreetypeFace *> faces; - bool hasPatentFreeLcdRendering; }; QtFreetypeData::~QtFreetypeData() @@ -153,11 +152,6 @@ QtFreetypeData *qt_getFreetypeData() FT_Bool no_darkening = false; FT_Property_Set(freetypeData->library, "cff", "no-stem-darkening", &no_darkening); #endif - // FreeType has since 2.8.1 a patent free alternative to LCD-filtering. - FT_Int amajor, aminor = 0, apatch = 0; - FT_Library_Version(freetypeData->library, &amajor, &aminor, &apatch); - if (QT_VERSION_CHECK(amajor, aminor, apatch) >= QT_VERSION_CHECK(2, 8, 1)) - freetypeData->hasPatentFreeLcdRendering = true; } return freetypeData; } @@ -561,26 +555,7 @@ QFontEngineFT::Glyph::~Glyph() delete [] data; } -struct LcdFilterDummy -{ - static inline void filterPixel(uchar &, uchar &, uchar &) - {} -}; - -struct LcdFilterLegacy -{ - static inline void filterPixel(uchar &red, uchar &green, uchar &blue) - { - uint r = red, g = green, b = blue; - // intra-pixel filter used by the legacy filter (adopted from _ft_lcd_filter_legacy) - red = (r * uint(65538 * 9/13) + g * uint(65538 * 1/6) + b * uint(65538 * 1/13)) / 65536; - green = (r * uint(65538 * 3/13) + g * uint(65538 * 4/6) + b * uint(65538 * 3/13)) / 65536; - blue = (r * uint(65538 * 1/13) + g * uint(65538 * 1/6) + b * uint(65538 * 9/13)) / 65536; - } -}; - -template <typename LcdFilter> -static void convertRGBToARGB_helper(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr) +static inline void convertRGBToARGB(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr) { const int offs = bgr ? -1 : 1; const int w = width * 3; @@ -590,7 +565,6 @@ static void convertRGBToARGB_helper(const uchar *src, uint *dst, int width, int uchar red = src[x + 1 - offs]; uchar green = src[x + 1]; uchar blue = src[x + 1 + offs]; - LcdFilter::filterPixel(red, green, blue); *dd++ = (0xFFU << 24) | (red << 16) | (green << 8) | blue; } dst += width; @@ -598,16 +572,7 @@ static void convertRGBToARGB_helper(const uchar *src, uint *dst, int width, int } } -static inline void convertRGBToARGB(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr, bool legacyFilter) -{ - if (!legacyFilter) - convertRGBToARGB_helper<LcdFilterDummy>(src, dst, width, height, src_pitch, bgr); - else - convertRGBToARGB_helper<LcdFilterLegacy>(src, dst, width, height, src_pitch, bgr); -} - -template <typename LcdFilter> -static void convertRGBToARGB_V_helper(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr) +static inline void convertRGBToARGB_V(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr) { const int offs = bgr ? -src_pitch : src_pitch; while (height--) { @@ -615,54 +580,12 @@ static void convertRGBToARGB_V_helper(const uchar *src, uint *dst, int width, in uchar red = src[x + src_pitch - offs]; uchar green = src[x + src_pitch]; uchar blue = src[x + src_pitch + offs]; - LcdFilter::filterPixel(red, green, blue); *dst++ = (0XFFU << 24) | (red << 16) | (green << 8) | blue; } src += 3*src_pitch; } } -static inline void convertRGBToARGB_V(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr, bool legacyFilter) -{ - if (!legacyFilter) - convertRGBToARGB_V_helper<LcdFilterDummy>(src, dst, width, height, src_pitch, bgr); - else - convertRGBToARGB_V_helper<LcdFilterLegacy>(src, dst, width, height, src_pitch, bgr); -} - -static inline void convertGRAYToARGB(const uchar *src, uint *dst, int width, int height, int src_pitch) -{ - while (height--) { - const uchar *p = src; - const uchar * const e = p + width; - while (p < e) { - uchar gray = *p++; - *dst++ = (0xFFU << 24) | (gray << 16) | (gray << 8) | gray; - } - src += src_pitch; - } -} - -static void convoluteBitmap(const uchar *src, uchar *dst, int width, int height, int pitch) -{ - // convolute the bitmap with a triangle filter to get rid of color fringes - // If we take account for a gamma value of 2, we end up with - // weights of 1, 4, 9, 4, 1. We use an approximation of 1, 3, 8, 3, 1 here, - // as this nicely sums up to 16 :) - int h = height; - while (h--) { - dst[0] = dst[1] = 0; - // - for (int x = 2; x < width - 2; ++x) { - uint sum = src[x-2] + 3*src[x-1] + 8*src[x] + 3*src[x+1] + src[x+2]; - dst[x] = (uchar) (sum >> 4); - } - dst[width - 2] = dst[width - 1] = 0; - src += pitch; - dst += pitch; - } -} - static QFontEngine::SubpixelAntialiasingType subpixelAntialiasingTypeHint() { static int type = -1; @@ -1153,196 +1076,97 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, int glyph_buffer_size = 0; QScopedArrayPointer<uchar> glyph_buffer; - bool useFreetypeRenderGlyph = false; - if (slot->format == FT_GLYPH_FORMAT_OUTLINE && (hsubpixel || vfactor != 1)) { - err = FT_Library_SetLcdFilter(slot->library, (FT_LcdFilter)lcdFilterType); - // We use FT_Render_Glyph if freetype has support for lcd-filtering - // or is version 2.8.1 or higher and can do without. - if (err == FT_Err_Ok || qt_getFreetypeData()->hasPatentFreeLcdRendering) - useFreetypeRenderGlyph = true; + FT_Render_Mode renderMode = (default_hint_style == HintLight) ? FT_RENDER_MODE_LIGHT : FT_RENDER_MODE_NORMAL; + switch (format) { + case Format_Mono: + renderMode = FT_RENDER_MODE_MONO; + break; + case Format_A32: + Q_ASSERT(hsubpixel || vfactor != 1); + renderMode = hsubpixel ? FT_RENDER_MODE_LCD : FT_RENDER_MODE_LCD_V; + break; + case Format_A8: + case Format_ARGB: + break; + default: + Q_UNREACHABLE(); } - if (useFreetypeRenderGlyph) { - err = FT_Render_Glyph(slot, hsubpixel ? FT_RENDER_MODE_LCD : FT_RENDER_MODE_LCD_V); + FT_Library_SetLcdFilter(slot->library, (FT_LcdFilter)lcdFilterType); - if (err != FT_Err_Ok) - qWarning("render glyph failed err=%x face=%p, glyph=%d", err, face, glyph); + err = FT_Render_Glyph(slot, renderMode); + if (err != FT_Err_Ok) + qWarning("render glyph failed err=%x face=%p, glyph=%d", err, face, glyph); - FT_Library_SetLcdFilter(slot->library, FT_LCD_FILTER_NONE); + FT_Library_SetLcdFilter(slot->library, FT_LCD_FILTER_NONE); - info.height = slot->bitmap.rows / vfactor; - info.width = hsubpixel ? slot->bitmap.width / 3 : slot->bitmap.width; - info.x = slot->bitmap_left; - info.y = slot->bitmap_top; - - glyph_buffer_size = info.width * info.height * 4; - glyph_buffer.reset(new uchar[glyph_buffer_size]); - - if (hsubpixel) - convertRGBToARGB(slot->bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_RGB, false); - else if (vfactor != 1) - convertRGBToARGB_V(slot->bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_VRGB, false); - } else { - int left = slot->metrics.horiBearingX; - int right = slot->metrics.horiBearingX + slot->metrics.width; - int top = slot->metrics.horiBearingY; - int bottom = slot->metrics.horiBearingY - slot->metrics.height; - if (transform && slot->format != FT_GLYPH_FORMAT_BITMAP) - transformBoundingBox(&left, &top, &right, &bottom, &matrix); - left = FLOOR(left); - right = CEIL(right); - bottom = FLOOR(bottom); - top = CEIL(top); - - int hpixels = TRUNC(right - left); - // subpixel position requires one more pixel - if (subPixelPosition > 0 && format != Format_Mono) - hpixels++; - - if (hsubpixel) - hpixels = hpixels*3 + 8; - info.width = hpixels; - info.height = TRUNC(top - bottom); - info.x = TRUNC(left); - info.y = TRUNC(top); - if (hsubpixel) { - info.width /= 3; - info.x -= 1; - } - - // If any of the metrics are too large to fit, don't cache them - if (areMetricsTooLarge(info)) - return 0; + info.height = slot->bitmap.rows; + info.width = slot->bitmap.width; + info.x = slot->bitmap_left; + info.y = slot->bitmap_top; + if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_LCD) + info.width = info.width / 3; + if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_LCD_V) + info.height = info.height / vfactor; int pitch = (format == Format_Mono ? ((info.width + 31) & ~31) >> 3 : (format == Format_A8 ? (info.width + 3) & ~3 : info.width * 4)); - if (glyph_buffer_size < pitch * info.height) { - glyph_buffer_size = pitch * info.height; - glyph_buffer.reset(new uchar[glyph_buffer_size]); - memset(glyph_buffer.data(), 0, glyph_buffer_size); - } - if (slot->format == FT_GLYPH_FORMAT_OUTLINE) { - FT_Bitmap bitmap; - bitmap.rows = info.height*vfactor; - bitmap.width = hpixels; - bitmap.pitch = format == Format_Mono ? (((info.width + 31) & ~31) >> 3) : ((bitmap.width + 3) & ~3); - int bitmap_buffer_size = bitmap.rows * bitmap.pitch; - if (!hsubpixel && vfactor == 1 && format != Format_A32) { - Q_ASSERT(glyph_buffer_size <= bitmap_buffer_size); - bitmap.buffer = glyph_buffer.data(); - } else { - bitmap.buffer = new uchar[bitmap_buffer_size]; - memset(bitmap.buffer, 0, bitmap_buffer_size); - } - bitmap.pixel_mode = format == Format_Mono ? FT_PIXEL_MODE_MONO : FT_PIXEL_MODE_GRAY; - FT_Matrix matrix; - matrix.xx = (hsubpixel ? 3 : 1) << 16; - matrix.yy = vfactor << 16; - matrix.yx = matrix.xy = 0; + glyph_buffer_size = info.height * pitch; + glyph_buffer.reset(new uchar[glyph_buffer_size]); - FT_Outline_Transform(&slot->outline, &matrix); - FT_Outline_Translate (&slot->outline, (hsubpixel ? -3*left +(4<<6) : -left), -bottom*vfactor); - FT_Outline_Get_Bitmap(slot->library, &slot->outline, &bitmap); - if (hsubpixel) { - Q_ASSERT (bitmap.pixel_mode == FT_PIXEL_MODE_GRAY); - Q_ASSERT(antialias); - uchar *convoluted = new uchar[bitmap_buffer_size]; - bool useLegacyLcdFilter = false; - useLegacyLcdFilter = (lcdFilterType == FT_LCD_FILTER_LEGACY); - uchar *buffer = bitmap.buffer; - if (!useLegacyLcdFilter) { - convoluteBitmap(bitmap.buffer, convoluted, bitmap.width, info.height, bitmap.pitch); - buffer = convoluted; - } - convertRGBToARGB(buffer + 1, (uint *)glyph_buffer.data(), info.width, info.height, bitmap.pitch, subpixelType != Subpixel_RGB, useLegacyLcdFilter); - delete [] convoluted; - } else if (vfactor != 1) { - convertRGBToARGB_V(bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, bitmap.pitch, subpixelType != Subpixel_VRGB, true); - } else if (format == Format_A32 && bitmap.pixel_mode == FT_PIXEL_MODE_GRAY) { - convertGRAYToARGB(bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, bitmap.pitch); - } - - if (bitmap.buffer != glyph_buffer.data()) - delete [] bitmap.buffer; - } else if (slot->format == FT_GLYPH_FORMAT_BITMAP) { -#if ((FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100) >= 20500) - Q_ASSERT(slot->bitmap.pixel_mode == FT_PIXEL_MODE_MONO || slot->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA); -#else - Q_ASSERT(slot->bitmap.pixel_mode == FT_PIXEL_MODE_MONO); -#endif + if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) { + Q_ASSERT(format == Format_Mono); uchar *src = slot->bitmap.buffer; uchar *dst = glyph_buffer.data(); int h = slot->bitmap.rows; - if (format == Format_Mono) { - int bytes = ((info.width + 7) & ~7) >> 3; - while (h--) { - memcpy (dst, src, bytes); - dst += pitch; - src += slot->bitmap.pitch; - } - } else if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) { - if (hsubpixel) { - while (h--) { - uint *dd = (uint *)dst; - *dd++ = 0; - for (int x = 0; x < static_cast<int>(slot->bitmap.width); x++) { - uint a = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xffffff : 0x000000); - *dd++ = a; - } - *dd++ = 0; - dst += pitch; - src += slot->bitmap.pitch; - } - } else if (vfactor != 1) { - while (h--) { - uint *dd = (uint *)dst; - for (int x = 0; x < static_cast<int>(slot->bitmap.width); x++) { - uint a = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xffffff : 0x000000); - *dd++ = a; - } - dst += pitch; - src += slot->bitmap.pitch; - } - } else { - while (h--) { - for (int x = 0; x < static_cast<int>(slot->bitmap.width); x++) { - unsigned char a = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xff : 0x00); - dst[x] = a; - } - dst += pitch; - src += slot->bitmap.pitch; - } - } + + int bytes = ((info.width + 7) & ~7) >> 3; + while (h--) { + memcpy (dst, src, bytes); + dst += pitch; + src += slot->bitmap.pitch; } -#if ((FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100) >= 20500) - else if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) - { - while (h--) { + } else if (slot->bitmap.pixel_mode == 7 /*FT_PIXEL_MODE_BGRA*/) { + Q_ASSERT(format == Format_ARGB); + uchar *src = slot->bitmap.buffer; + uchar *dst = glyph_buffer.data(); + int h = slot->bitmap.rows; + while (h--) { #if Q_BYTE_ORDER == Q_BIG_ENDIAN - const quint32 *srcPixel = (const quint32 *)src; - quint32 *dstPixel = (quint32 *)dst; - for (int x = 0; x < static_cast<int>(slot->bitmap.width); x++, srcPixel++, dstPixel++) { - const quint32 pixel = *srcPixel; - *dstPixel = qbswap(pixel); - } -#else - memcpy(dst, src, slot->bitmap.width * 4); -#endif - dst += slot->bitmap.pitch; - src += slot->bitmap.pitch; + const quint32 *srcPixel = (const quint32 *)src; + quint32 *dstPixel = (quint32 *)dst; + for (int x = 0; x < static_cast<int>(slot->bitmap.width); x++, srcPixel++, dstPixel++) { + const quint32 pixel = *srcPixel; + *dstPixel = qbswap(pixel); } - info.width = info.linearAdvance = info.xOff = slot->bitmap.width; - info.height = slot->bitmap.rows; - info.x = slot->bitmap_left; - info.y = slot->bitmap_top; - } +#else + memcpy(dst, src, slot->bitmap.width * 4); #endif + dst += slot->bitmap.pitch; + src += slot->bitmap.pitch; + } + info.linearAdvance = info.xOff = slot->bitmap.width; + } else if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY) { + Q_ASSERT(format == Format_A8); + uchar *src = slot->bitmap.buffer; + uchar *dst = glyph_buffer.data(); + int h = slot->bitmap.rows; + int bytes = info.width; + while (h--) { + memcpy (dst, src, bytes); + dst += pitch; + src += slot->bitmap.pitch; + } + } else if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_LCD) { + Q_ASSERT(format == Format_A32); + convertRGBToARGB(slot->bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_RGB); + } else if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_LCD_V) { + Q_ASSERT(format == Format_A32); + convertRGBToARGB_V(slot->bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_VRGB); } else { - qWarning("QFontEngine: Glyph neither outline nor bitmap format=%d", slot->format); + qWarning("QFontEngine: Glyph rendered in unknown pixel_mode=%d", slot->bitmap.pixel_mode); return 0; } - } - if (!g) { g = new Glyph; From 6f9e444c28c0095595b1b61cb0f399ac2790716b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= <tor.arne.vestbo@qt.io> Date: Sun, 16 Dec 2018 19:54:26 +0100 Subject: [PATCH 1105/1650] harbuzzng: Remove assumption about Core Text working in 96 DPI Core Text doesn't actually have a concept of DPI internally, as it doesn't rasterize anything by itself, it just generates vector paths that get passed along to Core Graphics. In practice this means Core Text operates in the classical macOS logical DPI of 72, with one typographic point corresponding to one point in the Core Graphics coordinate system, which for a normal bitmap context then corresponds to one pixel -- or two pixels for a "retina" context with a 2x scale transform. Scaling the font point sizes given to HarfBuzz to an assumed DPI of 96 is problematic with this in mind, as fonts with optical features such as 'trak' tables for tracking, or color glyphs, will then base the metrics off of the wrong point size compared to what the client asked for. This in turn causes mismatches between the metrics of the shaped text and the actual rasterization, which doesn't include the 72 to 96 DPI scaling. If a 96 DPI is needed, such as on the Web, the scaling should be done outside of HarfBuzz, allowing the client to keep the DPI of the shaping in sync with the rasterization. The recommended way to do that is by scaling the font point size, not by applying a transform to the target Core Graphics context, to let Core Text choose the right optical features of the target point size, as described in WWDC 2015 session 804: https://developer.apple.com/videos/play/wwdc2015/804/ GitHub-PR: https://github.com/harfbuzz/harfbuzz/pull/1484 Change-Id: I830f0cd7a82552422bbe09226e2d571e246fe3f4 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io> --- src/3rdparty/harfbuzz-ng/src/hb-coretext.cc | 25 ++++----------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc index 9431ba5fe1..d64cb7edbd 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc @@ -52,24 +52,6 @@ struct CoreTextFontEngineData { /* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */ #define HB_CORETEXT_DEFAULT_FONT_SIZE 12.f -static CGFloat -coretext_font_size_from_ptem (float ptem) -{ - /* CoreText points are CSS pixels (96 per inch), - * NOT typographic points (72 per inch). - * - * https://developer.apple.com/library/content/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html - */ - ptem *= 96.f / 72.f; - return ptem <= 0.f ? HB_CORETEXT_DEFAULT_FONT_SIZE : ptem; -} -static float -coretext_font_size_to_ptem (CGFloat size) -{ - size *= 72.f / 96.f; - return size <= 0.f ? 0 : size; -} - static void release_table_data (void *user_data) { @@ -104,7 +86,7 @@ _hb_cg_font_release (void *data) HB_SHAPER_DATA_ENSURE_DEFINE(coretext, face) HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(coretext, font, - fabs (CTFontGetSize((CTFontRef) data) - coretext_font_size_from_ptem (font->ptem)) <= .5 + fabs (CTFontGetSize ((CTFontRef) data) - font->ptem) <= .5 ) static CTFontDescriptorRef @@ -308,7 +290,8 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font) if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return nullptr; CGFontRef cg_font = (CGFontRef) HB_SHAPER_DATA_GET (face); - CTFontRef ct_font = create_ct_font (cg_font, coretext_font_size_from_ptem (font->ptem)); + CGFloat font_size = font->ptem <= 0.f ? HB_CORETEXT_DEFAULT_FONT_SIZE : font->ptem; + CTFontRef ct_font = create_ct_font (cg_font, font_size); if (unlikely (!ct_font)) { @@ -340,7 +323,7 @@ hb_coretext_font_create (CTFontRef ct_font) if (unlikely (hb_object_is_inert (font))) return font; - hb_font_set_ptem (font, coretext_font_size_to_ptem (CTFontGetSize(ct_font))); + hb_font_set_ptem (font, CTFontGetSize (ct_font)); /* Let there be dragons here... */ HB_SHAPER_DATA_GET (font) = (hb_coretext_shaper_font_data_t *) CFRetain (ct_font); From 4697467e9888d7631841af6be436ed58e41f4759 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= <tor.arne.vestbo@qt.io> Date: Fri, 8 Feb 2019 15:01:28 +0100 Subject: [PATCH 1106/1650] macOS: Explain QNSViewMouseMoveHelper for future generations Change-Id: I61f38ee38d5afb657cd8b76b2b9dba1dac7167b4 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> --- src/plugins/platforms/cocoa/qnsview_mouse.mm | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/plugins/platforms/cocoa/qnsview_mouse.mm b/src/plugins/platforms/cocoa/qnsview_mouse.mm index 3d6471005d..563a66515a 100644 --- a/src/plugins/platforms/cocoa/qnsview_mouse.mm +++ b/src/plugins/platforms/cocoa/qnsview_mouse.mm @@ -39,6 +39,22 @@ // This file is included from qnsview.mm, and only used to organize the code +/* + The reason for using this helper is to ensure that QNSView doesn't implement + the NSResponder callbacks for mouseEntered, mouseExited, and mouseMoved. + + If it did, we would get mouse events though the responder chain as well, + for example if a subview has a tracking area of its own and calls super + in the handler, which results in forwarding the event though the responder + chain. The same applies if NSWindow.acceptsMouseMovedEvents is YES. + + By having a helper as the target for our tracking areas, we know for sure + that the events we are getting stem from our own tracking areas. + + FIXME: Ideally we wouldn't need this workaround, and would correctly + interact with the responder chain by e.g. calling super if Qt does not + accept the mouse event +*/ @implementation QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) { QNSView *view; } From 21e25ff38babc6dad57a56c758d05997c16eb111 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= <tor.arne.vestbo@qt.io> Date: Mon, 4 Feb 2019 23:39:42 +0100 Subject: [PATCH 1107/1650] macOS: Simplify mouse tracking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't need to react to updateTrackingAreas, as we only have a single tracking area that we can add once and forget. By asking AppKit to track all events in the visible rect, we can also pass a zero-rect for the tracking area. Change-Id: I2545712adc49b51904d5adc11f1faca36901b49d Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> --- src/plugins/platforms/cocoa/qnsview.mm | 8 +--- src/plugins/platforms/cocoa/qnsview_mouse.mm | 50 +++++++++----------- 2 files changed, 25 insertions(+), 33 deletions(-) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 7f826942f3..17063f6e92 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -85,6 +85,7 @@ @end @interface QT_MANGLE_NAMESPACE(QNSView) (Mouse) +- (void)initMouse; - (NSPoint)screenMousePoint:(NSEvent *)theEvent; - (void)mouseMovedImpl:(NSEvent *)theEvent; - (void)mouseEnteredImpl:(NSEvent *)theEvent; @@ -114,7 +115,6 @@ @implementation QT_MANGLE_NAMESPACE(QNSView) { QPointer<QCocoaWindow> m_platformWindow; - NSTrackingArea *m_trackingArea; Qt::MouseButtons m_buttons; Qt::MouseButtons m_acceptedMouseDowns; Qt::MouseButtons m_frameStrutButtons; @@ -150,7 +150,6 @@ m_currentlyInterpretedKeyEvent = nil; m_dontOverrideCtrlLMB = qt_mac_resolveOption(false, platformWindow->window(), "_q_platform_MacDontOverrideCtrlLMB", "QT_MAC_DONT_OVERRIDE_CTRL_LMB"); - m_trackingArea = nil; self.focusRingType = NSFocusRingTypeNone; self.cursor = nil; @@ -159,6 +158,7 @@ self.previousWindow = nil; [self initDrawing]; + [self initMouse]; [self registerDragTypes]; [[NSNotificationCenter defaultCenter] addObserver:self @@ -173,10 +173,6 @@ { qCDebug(lcQpaWindow) << "Deallocating" << self; - if (m_trackingArea) { - [self removeTrackingArea:m_trackingArea]; - [m_trackingArea release]; - } [m_inputSource release]; [[NSNotificationCenter defaultCenter] removeObserver:self]; [m_mouseMoveHelper release]; diff --git a/src/plugins/platforms/cocoa/qnsview_mouse.mm b/src/plugins/platforms/cocoa/qnsview_mouse.mm index 563a66515a..49c94f18db 100644 --- a/src/plugins/platforms/cocoa/qnsview_mouse.mm +++ b/src/plugins/platforms/cocoa/qnsview_mouse.mm @@ -151,6 +151,28 @@ @implementation QT_MANGLE_NAMESPACE(QNSView) (Mouse) +- (void)initMouse +{ + NSUInteger trackingOptions = NSTrackingActiveInActiveApp + | NSTrackingMouseEnteredAndExited | NSTrackingCursorUpdate; + + // Ideally, NSTrackingMouseMoved should be turned on only if QWidget::mouseTracking + // is enabled, hover is on, or a tool tip is set. Unfortunately, Qt will send "tooltip" + // events on mouse moves, so we need to turn it on in ALL case. That means EVERY QWindow + // gets to pay the cost of mouse moves delivered to it (Apple recommends keeping it OFF + // because there is a performance hit). + trackingOptions |= NSTrackingMouseMoved; + + // Using NSTrackingInVisibleRect means AppKit will automatically synchronize the + // tracking rect with changes in the view's visible area, so leave it undefined. + trackingOptions |= NSTrackingInVisibleRect; + static const NSRect trackingRect = NSZeroRect; + + QMacAutoReleasePool pool; + [self addTrackingArea:[[[NSTrackingArea alloc] initWithRect:trackingRect + options:trackingOptions owner:m_mouseMoveHelper userInfo:nil] autorelease]]; +} + - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent { Q_UNUSED(theEvent) @@ -422,35 +444,9 @@ [super otherMouseUp:theEvent]; } -- (void)updateTrackingAreas -{ - [super updateTrackingAreas]; - - QMacAutoReleasePool pool; - - // NSTrackingInVisibleRect keeps care of updating once the tracking is set up, so bail out early - if (m_trackingArea && [[self trackingAreas] containsObject:m_trackingArea]) - return; - - // Ideally, we shouldn't have NSTrackingMouseMoved events included below, it should - // only be turned on if mouseTracking, hover is on or a tool tip is set. - // Unfortunately, Qt will send "tooltip" events on mouse moves, so we need to - // turn it on in ALL case. That means EVERY QWindow gets to pay the cost of - // mouse moves delivered to it (Apple recommends keeping it OFF because there - // is a performance hit). So it goes. - NSUInteger trackingOptions = NSTrackingMouseEnteredAndExited | NSTrackingActiveInActiveApp - | NSTrackingInVisibleRect | NSTrackingMouseMoved | NSTrackingCursorUpdate; - [m_trackingArea release]; - m_trackingArea = [[NSTrackingArea alloc] initWithRect:[self frame] - options:trackingOptions - owner:m_mouseMoveHelper - userInfo:nil]; - [self addTrackingArea:m_trackingArea]; -} - - (void)cursorUpdate:(NSEvent *)theEvent { - qCDebug(lcQpaMouse) << "[QNSView cursorUpdate:]" << self.cursor; + qCDebug(lcQpaMouse) << "Updating cursor for" << self << "to" << self.cursor; // Note: We do not get this callback when moving from a subview that // uses the legacy cursorRect API, so the cursor is reset to the arrow From 17e51585702b51c4b854ec32a0cb9339ab34528f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= <tor.arne.vestbo@qt.io> Date: Mon, 4 Feb 2019 15:53:01 +0100 Subject: [PATCH 1108/1650] macOS: Treat default swapInterval (-1) as vsync-enabled display-link MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I6d3d241d3813bfac36155ad219d4a338cb1ef6f7 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> --- src/plugins/platforms/cocoa/qcocoascreen.mm | 4 ++-- src/plugins/platforms/cocoa/qcocoawindow.h | 1 + src/plugins/platforms/cocoa/qcocoawindow.mm | 13 +++++++++---- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoascreen.mm b/src/plugins/platforms/cocoa/qcocoascreen.mm index afe14e623c..36c11ba8af 100644 --- a/src/plugins/platforms/cocoa/qcocoascreen.mm +++ b/src/plugins/platforms/cocoa/qcocoascreen.mm @@ -330,7 +330,7 @@ void QCocoaScreen::deliverUpdateRequests() auto windows = QGuiApplication::allWindows(); for (int i = 0; i < windows.size(); ++i) { QWindow *window = windows.at(i); - QPlatformWindow *platformWindow = window->handle(); + auto *platformWindow = static_cast<QCocoaWindow*>(window->handle()); if (!platformWindow) continue; @@ -341,7 +341,7 @@ void QCocoaScreen::deliverUpdateRequests() continue; // Skip windows that are not doing update requests via display link - if (!(window->format().swapInterval() > 0)) + if (!platformWindow->updatesWithDisplayLink()) continue; platformWindow->deliverUpdateRequest(); diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 8f1bdb8af0..0a913ef66e 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -129,6 +129,7 @@ public: bool isForeignWindow() const override; void requestUpdate() override; + bool updatesWithDisplayLink() const; void deliverUpdateRequest() override; void requestActivateWindow() override; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index a1bed3db45..792993afbf 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1473,11 +1473,10 @@ void QCocoaWindow::recreateWindowIfNeeded() void QCocoaWindow::requestUpdate() { - const int swapInterval = format().swapInterval(); - qCDebug(lcQpaDrawing) << "QCocoaWindow::requestUpdate" << window() << "swapInterval" << swapInterval; + qCDebug(lcQpaDrawing) << "QCocoaWindow::requestUpdate" << window() + << "using" << (updatesWithDisplayLink() ? "display-link" : "timer"); - if (swapInterval > 0) { - // Vsync is enabled, deliver via CVDisplayLink + if (updatesWithDisplayLink()) { static_cast<QCocoaScreen *>(screen())->requestUpdate(); } else { // Fall back to the un-throttled timer-based callback @@ -1485,6 +1484,12 @@ void QCocoaWindow::requestUpdate() } } +bool QCocoaWindow::updatesWithDisplayLink() const +{ + // Update via CVDisplayLink if Vsync is enabled + return format().swapInterval() != 0; +} + void QCocoaWindow::deliverUpdateRequest() { // Don't send update requests for views that need display, as the update From 9f22ac0aa0254f20f9b26aec7b124d74141fdfcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= <tor.arne.vestbo@qt.io> Date: Wed, 30 Jan 2019 16:29:59 +0100 Subject: [PATCH 1109/1650] macOS: Don't send redundant geometry change events for top level windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Top level windows already get their geometry changes via windowDidMove and windowDidResize. Change-Id: Ie6370aa290ef48c8b3ac770e77adb57ce43cbb47 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> --- src/plugins/platforms/cocoa/qcocoawindow.mm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 792993afbf..724c9485bd 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1101,6 +1101,9 @@ void QCocoaWindow::setEmbeddedInForeignView() void QCocoaWindow::viewDidChangeFrame() { + if (isContentView()) + return; // Handled below + handleGeometryChange(); } From 8c73ddd8e3fb43cc22fa111b855ab1f9f5b83405 Mon Sep 17 00:00:00 2001 From: Gerry Boland <gerboland@gmail.com> Date: Wed, 18 Jul 2018 15:28:02 +0100 Subject: [PATCH 1110/1650] qpa: remove mirclient MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Mir display server is now Wayland compatible, so a dedicated Mir client library is no longer necessary. [ChangeLog][Platform Specific Changes][Mir] The Mir platform plugin has been removed: use the Wayland plugin when connecting to a Mir display server. Change-Id: Ibc77698dd45a1afaf29f0d57b5e5cf7bd91735f5 Reviewed-by: Gatis Paeglis <gatis.paeglis@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io> Reviewed-by: Johan Helsing <johan.helsing@qt.io> --- config_help.txt | 1 - src/gui/configure.json | 26 +- .../platforms/mirclient/mirclient.json | 3 - src/plugins/platforms/mirclient/mirclient.pro | 61 -- .../qmirclientappstatecontroller.cpp | 102 -- .../mirclient/qmirclientappstatecontroller.h | 62 -- .../mirclient/qmirclientbackingstore.cpp | 157 --- .../mirclient/qmirclientbackingstore.h | 74 -- .../mirclient/qmirclientclipboard.cpp | 181 ---- .../platforms/mirclient/qmirclientclipboard.h | 92 -- .../platforms/mirclient/qmirclientcursor.cpp | 209 ---- .../platforms/mirclient/qmirclientcursor.h | 64 -- .../mirclient/qmirclientdebugextension.cpp | 79 -- .../mirclient/qmirclientdebugextension.h | 63 -- .../mirclient/qmirclientdesktopwindow.cpp | 50 - .../mirclient/qmirclientdesktopwindow.h | 53 - .../mirclient/qmirclientglcontext.cpp | 132 --- .../platforms/mirclient/qmirclientglcontext.h | 63 -- .../platforms/mirclient/qmirclientinput.cpp | 708 ------------- .../platforms/mirclient/qmirclientinput.h | 86 -- .../mirclient/qmirclientintegration.cpp | 411 -------- .../mirclient/qmirclientintegration.h | 131 --- .../platforms/mirclient/qmirclientlogging.h | 55 - .../mirclient/qmirclientnativeinterface.cpp | 217 ---- .../mirclient/qmirclientnativeinterface.h | 83 -- .../qmirclientorientationchangeevent_p.h | 61 -- .../mirclient/qmirclientplatformservices.cpp | 75 -- .../mirclient/qmirclientplatformservices.h | 57 -- .../platforms/mirclient/qmirclientplugin.cpp | 56 - .../platforms/mirclient/qmirclientplugin.h | 56 - .../platforms/mirclient/qmirclientscreen.cpp | 262 ----- .../platforms/mirclient/qmirclientscreen.h | 106 -- .../mirclient/qmirclientscreenobserver.cpp | 161 --- .../mirclient/qmirclientscreenobserver.h | 78 -- .../platforms/mirclient/qmirclienttheme.cpp | 67 -- .../platforms/mirclient/qmirclienttheme.h | 57 -- .../platforms/mirclient/qmirclientwindow.cpp | 968 ------------------ .../platforms/mirclient/qmirclientwindow.h | 118 --- src/plugins/platforms/platforms.pro | 2 - 39 files changed, 2 insertions(+), 5285 deletions(-) delete mode 100644 src/plugins/platforms/mirclient/mirclient.json delete mode 100644 src/plugins/platforms/mirclient/mirclient.pro delete mode 100644 src/plugins/platforms/mirclient/qmirclientappstatecontroller.cpp delete mode 100644 src/plugins/platforms/mirclient/qmirclientappstatecontroller.h delete mode 100644 src/plugins/platforms/mirclient/qmirclientbackingstore.cpp delete mode 100644 src/plugins/platforms/mirclient/qmirclientbackingstore.h delete mode 100644 src/plugins/platforms/mirclient/qmirclientclipboard.cpp delete mode 100644 src/plugins/platforms/mirclient/qmirclientclipboard.h delete mode 100644 src/plugins/platforms/mirclient/qmirclientcursor.cpp delete mode 100644 src/plugins/platforms/mirclient/qmirclientcursor.h delete mode 100644 src/plugins/platforms/mirclient/qmirclientdebugextension.cpp delete mode 100644 src/plugins/platforms/mirclient/qmirclientdebugextension.h delete mode 100644 src/plugins/platforms/mirclient/qmirclientdesktopwindow.cpp delete mode 100644 src/plugins/platforms/mirclient/qmirclientdesktopwindow.h delete mode 100644 src/plugins/platforms/mirclient/qmirclientglcontext.cpp delete mode 100644 src/plugins/platforms/mirclient/qmirclientglcontext.h delete mode 100644 src/plugins/platforms/mirclient/qmirclientinput.cpp delete mode 100644 src/plugins/platforms/mirclient/qmirclientinput.h delete mode 100644 src/plugins/platforms/mirclient/qmirclientintegration.cpp delete mode 100644 src/plugins/platforms/mirclient/qmirclientintegration.h delete mode 100644 src/plugins/platforms/mirclient/qmirclientlogging.h delete mode 100644 src/plugins/platforms/mirclient/qmirclientnativeinterface.cpp delete mode 100644 src/plugins/platforms/mirclient/qmirclientnativeinterface.h delete mode 100644 src/plugins/platforms/mirclient/qmirclientorientationchangeevent_p.h delete mode 100644 src/plugins/platforms/mirclient/qmirclientplatformservices.cpp delete mode 100644 src/plugins/platforms/mirclient/qmirclientplatformservices.h delete mode 100644 src/plugins/platforms/mirclient/qmirclientplugin.cpp delete mode 100644 src/plugins/platforms/mirclient/qmirclientplugin.h delete mode 100644 src/plugins/platforms/mirclient/qmirclientscreen.cpp delete mode 100644 src/plugins/platforms/mirclient/qmirclientscreen.h delete mode 100644 src/plugins/platforms/mirclient/qmirclientscreenobserver.cpp delete mode 100644 src/plugins/platforms/mirclient/qmirclientscreenobserver.h delete mode 100644 src/plugins/platforms/mirclient/qmirclienttheme.cpp delete mode 100644 src/plugins/platforms/mirclient/qmirclienttheme.h delete mode 100644 src/plugins/platforms/mirclient/qmirclientwindow.cpp delete mode 100644 src/plugins/platforms/mirclient/qmirclientwindow.h diff --git a/config_help.txt b/config_help.txt index 223adf61d7..606f40385e 100644 --- a/config_help.txt +++ b/config_help.txt @@ -295,7 +295,6 @@ Gui, printing, widget options: -gbm ............... Enable backends for GBM [auto] (Linux only) -kms ............... Enable backends for KMS [auto] (Linux only) -linuxfb ........... Enable Linux Framebuffer support [auto] (Linux only) - -mirclient ......... Enable Mir client support [no] (Linux only) -xcb ............... Enable X11 support. Select used xcb-* libraries [system/qt/no] (-qt-xcb still uses system version of libxcb itself) diff --git a/src/gui/configure.json b/src/gui/configure.json index 70d0817791..1a7afb9c38 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -30,7 +30,6 @@ "libjpeg": { "type": "enum", "values": [ "no", "qt", "system" ] }, "libpng": { "type": "enum", "values": [ "no", "qt", "system" ] }, "linuxfb": "boolean", - "mirclient": "boolean", "mtdev": "boolean", "opengl": { "type": "optionalString", "values": [ "no", "yes", "desktop", "es2", "dynamic" ] }, "opengl-es-2": { "type": "void", "name": "opengl", "value": "es2" }, @@ -394,20 +393,6 @@ { "lib": "zlib", "condition": "features.system-zlib" } ] }, - "mirclient": { - "label": "Mir client libraries", - "test": { - "tail": "static void surfaceCreateCallback(MirSurface*, void*) {}", - "main": [ - "u_application_lifecycle_delegate_new();", - "mir_surface_create(0, surfaceCreateCallback, 0);" - ] - }, - "headers": [ "mir_toolkit/mir_client_library.h", "ubuntu/application/lifecycle_delegate.h", "EGL/egl.h" ], - "sources": [ - { "type": "pkgConfig", "args": "egl mirclient ubuntu-platform-api libcontent-hub >= 0.2.0" } - ] - }, "mtdev": { "label": "mtdev", "test": { @@ -1294,13 +1279,6 @@ ], "output": [ "privateFeature" ] }, - "mirclient": { - "label": "Mir client", - "section": "Platform plugins", - "autoDetect": false, - "condition": "libs.mirclient && features.xkbcommon", - "output": [ "privateFeature" ] - }, "mtdev": { "label": "mtdev", "condition": "libs.mtdev", @@ -1827,7 +1805,7 @@ or may depend on your system and XQuartz setup." }, { "type": "warning", - "condition": "features.gui && config.linux && !config.android && !features.xcb && !features.eglfs && !features.directfb && !features.linuxfb && !features.mirclient", + "condition": "features.gui && config.linux && !config.android && !features.xcb && !features.eglfs && !features.directfb && !features.linuxfb", "message": "No QPA platform plugin enabled! This will produce a Qt that cannot run GUI applications. See \"Platform backends\" in the output of --help." @@ -1935,7 +1913,7 @@ QMAKE_LIBDIR_OPENGL[_ES2] and QMAKE_LIBS_OPENGL[_ES2] in the mkspec for your pla "eglfs_openwfd", "eglfs_viv", "eglfs_viv_wl", "eglfs_rcar", "eglfs_egldevice", "eglfs_gbm", "eglfs_vsp2", "eglfs_mali", "eglfs_brcm", "eglfs_x11" ] }, - "linuxfb", "vnc", "mirclient", + "linuxfb", "vnc", { "type": "feature", "condition": "config.integrity", diff --git a/src/plugins/platforms/mirclient/mirclient.json b/src/plugins/platforms/mirclient/mirclient.json deleted file mode 100644 index c31558a2f1..0000000000 --- a/src/plugins/platforms/mirclient/mirclient.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "Keys": [ "mirclient" ] -} diff --git a/src/plugins/platforms/mirclient/mirclient.pro b/src/plugins/platforms/mirclient/mirclient.pro deleted file mode 100644 index d9eb069200..0000000000 --- a/src/plugins/platforms/mirclient/mirclient.pro +++ /dev/null @@ -1,61 +0,0 @@ -TARGET = qmirclient - -QT += \ - core-private gui-private dbus \ - theme_support-private eventdispatcher_support-private \ - fontdatabase_support-private egl_support-private - -qtHaveModule(linuxaccessibility_support-private): \ - QT += linuxaccessibility_support-private - -DEFINES += MESA_EGL_NO_X11_HEADERS -# CONFIG += c++11 # only enables C++0x -QMAKE_CXXFLAGS += -fvisibility=hidden -fvisibility-inlines-hidden -std=c++11 -Werror -Wall -QMAKE_LFLAGS += -std=c++11 -Wl,-no-undefined - -QMAKE_USE_PRIVATE += mirclient - -SOURCES = \ - qmirclientappstatecontroller.cpp \ - qmirclientbackingstore.cpp \ - qmirclientclipboard.cpp \ - qmirclientcursor.cpp \ - qmirclientdebugextension.cpp \ - qmirclientdesktopwindow.cpp \ - qmirclientglcontext.cpp \ - qmirclientinput.cpp \ - qmirclientintegration.cpp \ - qmirclientnativeinterface.cpp \ - qmirclientplatformservices.cpp \ - qmirclientplugin.cpp \ - qmirclientscreen.cpp \ - qmirclientscreenobserver.cpp \ - qmirclienttheme.cpp \ - qmirclientwindow.cpp - -HEADERS = \ - qmirclientappstatecontroller.h \ - qmirclientbackingstore.h \ - qmirclientclipboard.h \ - qmirclientcursor.h \ - qmirclientdebugextension.h \ - qmirclientdesktopwindow.h \ - qmirclientglcontext.h \ - qmirclientinput.h \ - qmirclientintegration.h \ - qmirclientlogging.h \ - qmirclientnativeinterface.h \ - qmirclientorientationchangeevent_p.h \ - qmirclientplatformservices.h \ - qmirclientplugin.h \ - qmirclientscreen.h \ - qmirclientscreenobserver.h \ - qmirclienttheme.h \ - qmirclientwindow.h - -QMAKE_USE_PRIVATE += xkbcommon - -PLUGIN_TYPE = platforms -PLUGIN_CLASS_NAME = MirServerIntegrationPlugin -!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - -load(qt_plugin) diff --git a/src/plugins/platforms/mirclient/qmirclientappstatecontroller.cpp b/src/plugins/platforms/mirclient/qmirclientappstatecontroller.cpp deleted file mode 100644 index 69fc9b7aa7..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientappstatecontroller.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "qmirclientappstatecontroller.h" - -#include <qpa/qwindowsysteminterface.h> - -/* - * QMirClientAppStateController - updates Qt's QApplication::applicationState property. - * - * Tries to avoid active-inactive-active invocations using a timer. The rapid state - * change can confuse some applications. - */ - -QMirClientAppStateController::QMirClientAppStateController() - : m_suspended(false) - , m_lastActive(true) -{ - m_inactiveTimer.setSingleShot(true); - m_inactiveTimer.setInterval(10); - QObject::connect(&m_inactiveTimer, &QTimer::timeout, []() - { - QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive); - }); -} - -void QMirClientAppStateController::setSuspended() -{ - m_inactiveTimer.stop(); - if (!m_suspended) { - m_suspended = true; - - QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationSuspended); - } -} - -void QMirClientAppStateController::setResumed() -{ - m_inactiveTimer.stop(); - if (m_suspended) { - m_suspended = false; - - if (m_lastActive) { - QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive); - } else { - QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive); - } - } -} - -void QMirClientAppStateController::setWindowFocused(bool focused) -{ - if (m_suspended) { - return; - } - - if (focused) { - m_inactiveTimer.stop(); - QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive); - } else { - m_inactiveTimer.start(); - } - - m_lastActive = focused; -} diff --git a/src/plugins/platforms/mirclient/qmirclientappstatecontroller.h b/src/plugins/platforms/mirclient/qmirclientappstatecontroller.h deleted file mode 100644 index b3aa0022d9..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientappstatecontroller.h +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTAPPSTATECONTROLLER_H -#define QMIRCLIENTAPPSTATECONTROLLER_H - -#include <QTimer> - -class QMirClientAppStateController -{ -public: - QMirClientAppStateController(); - - void setSuspended(); - void setResumed(); - - void setWindowFocused(bool focused); - -private: - bool m_suspended; - bool m_lastActive; - QTimer m_inactiveTimer; -}; - -#endif // QMIRCLIENTAPPSTATECONTROLLER_H diff --git a/src/plugins/platforms/mirclient/qmirclientbackingstore.cpp b/src/plugins/platforms/mirclient/qmirclientbackingstore.cpp deleted file mode 100644 index 51363619d9..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientbackingstore.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "qmirclientbackingstore.h" -#include "qmirclientlogging.h" -#include <QtGui/QOpenGLContext> -#include <QtGui/QOpenGLTexture> -#include <QtGui/QMatrix4x4> -#include <QtGui/qopengltextureblitter.h> -#include <QtGui/qopenglfunctions.h> - -QMirClientBackingStore::QMirClientBackingStore(QWindow* window) - : QPlatformBackingStore(window) - , mContext(new QOpenGLContext) - , mTexture(new QOpenGLTexture(QOpenGLTexture::Target2D)) - , mBlitter(new QOpenGLTextureBlitter) -{ - mContext->setFormat(window->requestedFormat()); - mContext->setScreen(window->screen()); - mContext->create(); - - window->setSurfaceType(QSurface::OpenGLSurface); -} - -QMirClientBackingStore::~QMirClientBackingStore() -{ - mContext->makeCurrent(window()); // needed as QOpenGLTexture destructor assumes current context -} - -void QMirClientBackingStore::flush(QWindow* window, const QRegion& region, const QPoint& offset) -{ - Q_UNUSED(region); - Q_UNUSED(offset); - mContext->makeCurrent(window); - glViewport(0, 0, window->width(), window->height()); - - updateTexture(); - - if (!mBlitter->isCreated()) - mBlitter->create(); - - mBlitter->bind(); - mBlitter->blit(mTexture->textureId(), QMatrix4x4(), QOpenGLTextureBlitter::OriginTopLeft); - mBlitter->release(); - - mContext->swapBuffers(window); -} - -void QMirClientBackingStore::updateTexture() -{ - if (mDirty.isNull()) - return; - - if (!mTexture->isCreated()) { - mTexture->setMinificationFilter(QOpenGLTexture::Nearest); - mTexture->setMagnificationFilter(QOpenGLTexture::Nearest); - mTexture->setWrapMode(QOpenGLTexture::ClampToEdge); - mTexture->setData(mImage, QOpenGLTexture::DontGenerateMipMaps); - mTexture->create(); - } - mTexture->bind(); - - QRegion fixed; - QRect imageRect = mImage.rect(); - - for (const QRect &rect : mDirty) { - // intersect with image rect to be sure - QRect r = imageRect & rect; - - // if the rect is wide enough it is cheaper to just extend it instead of doing an image copy - if (r.width() >= imageRect.width() / 2) { - r.setX(0); - r.setWidth(imageRect.width()); - } - - fixed |= r; - } - - for (const QRect &rect : fixed) { - // if the sub-rect is full-width we can pass the image data directly to - // OpenGL instead of copying, since there is no gap between scanlines - if (rect.width() == imageRect.width()) { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, - mImage.constScanLine(rect.y())); - } else { - glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE, - mImage.copy(rect).constBits()); - } - } - /* End of code taken from QEGLPlatformBackingStore */ - - mDirty = QRegion(); -} - - -void QMirClientBackingStore::beginPaint(const QRegion& region) -{ - mDirty |= region; -} - -void QMirClientBackingStore::resize(const QSize& size, const QRegion& /*staticContents*/) -{ - mImage = QImage(size, QImage::Format_RGBA8888); - - mContext->makeCurrent(window()); - - if (mTexture->isCreated()) - mTexture->destroy(); -} - -QPaintDevice* QMirClientBackingStore::paintDevice() -{ - return &mImage; -} - -QImage QMirClientBackingStore::toImage() const -{ - // used by QPlatformBackingStore::composeAndFlush - return mImage; -} diff --git a/src/plugins/platforms/mirclient/qmirclientbackingstore.h b/src/plugins/platforms/mirclient/qmirclientbackingstore.h deleted file mode 100644 index 7644c77df2..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientbackingstore.h +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTBACKINGSTORE_H -#define QMIRCLIENTBACKINGSTORE_H - -#include <qpa/qplatformbackingstore.h> - -class QOpenGLContext; -class QOpenGLTexture; -class QOpenGLTextureBlitter; - -class QMirClientBackingStore : public QPlatformBackingStore -{ -public: - QMirClientBackingStore(QWindow* window); - virtual ~QMirClientBackingStore(); - - // QPlatformBackingStore methods. - void beginPaint(const QRegion&) override; - void flush(QWindow* window, const QRegion& region, const QPoint& offset) override; - void resize(const QSize& size, const QRegion& staticContents) override; - QPaintDevice* paintDevice() override; - QImage toImage() const override; - -protected: - void updateTexture(); - -private: - QScopedPointer<QOpenGLContext> mContext; - QScopedPointer<QOpenGLTexture> mTexture; - QScopedPointer<QOpenGLTextureBlitter> mBlitter; - QImage mImage; - QRegion mDirty; -}; - -#endif // QMIRCLIENTBACKINGSTORE_H diff --git a/src/plugins/platforms/mirclient/qmirclientclipboard.cpp b/src/plugins/platforms/mirclient/qmirclientclipboard.cpp deleted file mode 100644 index b9fc9b3b42..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientclipboard.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "qmirclientclipboard.h" -#include "qmirclientlogging.h" -#include "qmirclientwindow.h" - -#include <QDBusPendingCallWatcher> -#include <QGuiApplication> -#include <QSignalBlocker> -#include <QtCore/QMimeData> -#include <QtCore/QStringList> - -// content-hub -#include <com/ubuntu/content/hub.h> - -// get this cumbersome nested namespace out of the way -using namespace com::ubuntu::content; - -QMirClientClipboard::QMirClientClipboard() - : mMimeData(new QMimeData) - , mContentHub(Hub::Client::instance()) -{ - connect(mContentHub, &Hub::pasteboardChanged, this, [this]() { - if (mClipboardState == QMirClientClipboard::SyncedClipboard) { - mClipboardState = QMirClientClipboard::OutdatedClipboard; - emitChanged(QClipboard::Clipboard); - } - }); - - connect(qGuiApp, &QGuiApplication::applicationStateChanged, - this, &QMirClientClipboard::onApplicationStateChanged); - - requestMimeData(); -} - -QMirClientClipboard::~QMirClientClipboard() -{ - delete mMimeData; -} - -QMimeData* QMirClientClipboard::mimeData(QClipboard::Mode mode) -{ - if (mode != QClipboard::Clipboard) - return nullptr; - - // Blocks dataChanged() signal from being emitted. Makes no sense to emit it from - // inside the data getter. - const QSignalBlocker blocker(this); - - if (mClipboardState == OutdatedClipboard) { - updateMimeData(); - } else if (mClipboardState == SyncingClipboard) { - mPasteReply->waitForFinished(); - } - - return mMimeData; -} - -void QMirClientClipboard::setMimeData(QMimeData* mimeData, QClipboard::Mode mode) -{ - QWindow *focusWindow = QGuiApplication::focusWindow(); - if (focusWindow && mode == QClipboard::Clipboard && mimeData != nullptr) { - QString surfaceId = static_cast<QMirClientWindow*>(focusWindow->handle())->persistentSurfaceId(); - - QDBusPendingCall reply = mContentHub->createPaste(surfaceId, *mimeData); - - // Don't care whether it succeeded - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); - connect(watcher, &QDBusPendingCallWatcher::finished, - watcher, &QObject::deleteLater); - - mMimeData = mimeData; - mClipboardState = SyncedClipboard; - emitChanged(QClipboard::Clipboard); - } -} - -bool QMirClientClipboard::supportsMode(QClipboard::Mode mode) const -{ - return mode == QClipboard::Clipboard; -} - -bool QMirClientClipboard::ownsMode(QClipboard::Mode mode) const -{ - Q_UNUSED(mode); - return false; -} - -void QMirClientClipboard::onApplicationStateChanged(Qt::ApplicationState state) -{ - if (state == Qt::ApplicationActive) { - // Only focused or active applications might be allowed to paste, so we probably - // missed changes in the clipboard while we were hidden, inactive or, more importantly, - // suspended. - requestMimeData(); - } -} - -void QMirClientClipboard::updateMimeData() -{ - if (qGuiApp->applicationState() != Qt::ApplicationActive) { - // Don't even bother asking as content-hub would probably ignore our request (and should). - return; - } - - delete mMimeData; - - QWindow *focusWindow = QGuiApplication::focusWindow(); - if (focusWindow) { - QString surfaceId = static_cast<QMirClientWindow*>(focusWindow->handle())->persistentSurfaceId(); - mMimeData = mContentHub->latestPaste(surfaceId); - mClipboardState = SyncedClipboard; - emitChanged(QClipboard::Clipboard); - } -} - -void QMirClientClipboard::requestMimeData() -{ - if (qGuiApp->applicationState() != Qt::ApplicationActive) { - // Don't even bother asking as content-hub would probably ignore our request (and should). - return; - } - - QWindow *focusWindow = QGuiApplication::focusWindow(); - if (!focusWindow) { - return; - } - - QString surfaceId = static_cast<QMirClientWindow*>(focusWindow->handle())->persistentSurfaceId(); - QDBusPendingCall reply = mContentHub->requestLatestPaste(surfaceId); - mClipboardState = SyncingClipboard; - - mPasteReply = new QDBusPendingCallWatcher(reply, this); - connect(mPasteReply, &QDBusPendingCallWatcher::finished, - this, [this]() { - delete mMimeData; - mMimeData = mContentHub->paste(*mPasteReply); - mClipboardState = SyncedClipboard; - mPasteReply->deleteLater(); - mPasteReply = nullptr; - emitChanged(QClipboard::Clipboard); - }); -} diff --git a/src/plugins/platforms/mirclient/qmirclientclipboard.h b/src/plugins/platforms/mirclient/qmirclientclipboard.h deleted file mode 100644 index 09e9bcdf38..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientclipboard.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTCLIPBOARD_H -#define QMIRCLIENTCLIPBOARD_H - -#include <qpa/qplatformclipboard.h> - -#include <QMimeData> -#include <QPointer> - -namespace com { - namespace ubuntu { - namespace content { - class Hub; - } - } -} - -class QDBusPendingCallWatcher; - -class QMirClientClipboard : public QObject, public QPlatformClipboard -{ - Q_OBJECT -public: - QMirClientClipboard(); - virtual ~QMirClientClipboard(); - - // QPlatformClipboard methods. - QMimeData* mimeData(QClipboard::Mode mode = QClipboard::Clipboard) override; - void setMimeData(QMimeData* data, QClipboard::Mode mode = QClipboard::Clipboard) override; - bool supportsMode(QClipboard::Mode mode) const override; - bool ownsMode(QClipboard::Mode mode) const override; - -private Q_SLOTS: - void onApplicationStateChanged(Qt::ApplicationState state); - -private: - void updateMimeData(); - void requestMimeData(); - - QMimeData *mMimeData; - - enum { - OutdatedClipboard, // Our mimeData is outdated, need to fetch latest from ContentHub - SyncingClipboard, // Our mimeData is outdated and we are waiting for ContentHub to reply with the latest paste - SyncedClipboard // Our mimeData is in sync with what ContentHub has - } mClipboardState{OutdatedClipboard}; - - com::ubuntu::content::Hub *mContentHub; - - QDBusPendingCallWatcher *mPasteReply{nullptr}; -}; - -#endif // QMIRCLIENTCLIPBOARD_H diff --git a/src/plugins/platforms/mirclient/qmirclientcursor.cpp b/src/plugins/platforms/mirclient/qmirclientcursor.cpp deleted file mode 100644 index 812cde95c6..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientcursor.cpp +++ /dev/null @@ -1,209 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015-2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "qmirclientcursor.h" - -#include "qmirclientlogging.h" -#include "qmirclientwindow.h" - -#include <mir_toolkit/mir_client_library.h> - -Q_LOGGING_CATEGORY(mirclientCursor, "qt.qpa.mirclient.cursor", QtWarningMsg) - -QMirClientCursor::QMirClientCursor(MirConnection *connection) - : mConnection(connection) -{ - /* - * TODO: Add the missing cursors to Mir (LP: #1388987) - * Those are the ones without a mir_ prefix, which are X11 cursors - * and won't be understood by any shell other than Unity8. - */ - mShapeToCursorName[Qt::ArrowCursor] = mir_arrow_cursor_name; - mShapeToCursorName[Qt::UpArrowCursor] = "up_arrow"; - mShapeToCursorName[Qt::CrossCursor] = mir_crosshair_cursor_name; - mShapeToCursorName[Qt::WaitCursor] = mir_busy_cursor_name; - mShapeToCursorName[Qt::IBeamCursor] = mir_caret_cursor_name; - mShapeToCursorName[Qt::SizeVerCursor] = mir_vertical_resize_cursor_name; - mShapeToCursorName[Qt::SizeHorCursor] = mir_horizontal_resize_cursor_name; - mShapeToCursorName[Qt::SizeBDiagCursor] = mir_diagonal_resize_bottom_to_top_cursor_name; - mShapeToCursorName[Qt::SizeFDiagCursor] = mir_diagonal_resize_top_to_bottom_cursor_name; - mShapeToCursorName[Qt::SizeAllCursor] = mir_omnidirectional_resize_cursor_name; - mShapeToCursorName[Qt::BlankCursor] = mir_disabled_cursor_name; - mShapeToCursorName[Qt::SplitVCursor] = mir_vsplit_resize_cursor_name; - mShapeToCursorName[Qt::SplitHCursor] = mir_hsplit_resize_cursor_name; - mShapeToCursorName[Qt::PointingHandCursor] = mir_pointing_hand_cursor_name; - mShapeToCursorName[Qt::ForbiddenCursor] = "forbidden"; - mShapeToCursorName[Qt::WhatsThisCursor] = "whats_this"; - mShapeToCursorName[Qt::BusyCursor] = "left_ptr_watch"; - mShapeToCursorName[Qt::OpenHandCursor] = mir_open_hand_cursor_name; - mShapeToCursorName[Qt::ClosedHandCursor] = mir_closed_hand_cursor_name; - mShapeToCursorName[Qt::DragCopyCursor] = "dnd-copy"; - mShapeToCursorName[Qt::DragMoveCursor] = "dnd-move"; - mShapeToCursorName[Qt::DragLinkCursor] = "dnd-link"; -} - -namespace { -const char *qtCursorShapeToStr(Qt::CursorShape shape) -{ - switch (shape) { - case Qt::ArrowCursor: - return "Arrow"; - case Qt::UpArrowCursor: - return "UpArrow"; - case Qt::CrossCursor: - return "Cross"; - case Qt::WaitCursor: - return "Wait"; - case Qt::IBeamCursor: - return "IBeam"; - case Qt::SizeVerCursor: - return "SizeVer"; - case Qt::SizeHorCursor: - return "SizeHor"; - case Qt::SizeBDiagCursor: - return "SizeBDiag"; - case Qt::SizeFDiagCursor: - return "SizeFDiag"; - case Qt::SizeAllCursor: - return "SizeAll"; - case Qt::BlankCursor: - return "Blank"; - case Qt::SplitVCursor: - return "SplitV"; - case Qt::SplitHCursor: - return "SplitH"; - case Qt::PointingHandCursor: - return "PointingHand"; - case Qt::ForbiddenCursor: - return "Forbidden"; - case Qt::WhatsThisCursor: - return "WhatsThis"; - case Qt::BusyCursor: - return "Busy"; - case Qt::OpenHandCursor: - return "OpenHand"; - case Qt::ClosedHandCursor: - return "ClosedHand"; - case Qt::DragCopyCursor: - return "DragCopy"; - case Qt::DragMoveCursor: - return "DragMove"; - case Qt::DragLinkCursor: - return "DragLink"; - case Qt::BitmapCursor: - return "Bitmap"; - default: - return "???"; - } -} -} // anonymous namespace - -void QMirClientCursor::changeCursor(QCursor *windowCursor, QWindow *window) -{ - if (!window) { - return; - } - - MirSurface *surface = static_cast<QMirClientWindow*>(window->handle())->mirSurface(); - - if (!surface) { - return; - } - - - if (windowCursor) { - qCDebug(mirclientCursor, "changeCursor shape=%s, window=%p", qtCursorShapeToStr(windowCursor->shape()), window); - if (!windowCursor->pixmap().isNull()) { - configureMirCursorWithPixmapQCursor(surface, *windowCursor); - } else if (windowCursor->shape() == Qt::BitmapCursor) { - // TODO: Implement bitmap cursor support - applyDefaultCursorConfiguration(surface); - } else { - const auto &cursorName = mShapeToCursorName.value(windowCursor->shape(), QByteArray("left_ptr")); - auto cursorConfiguration = mir_cursor_configuration_from_name(cursorName.data()); - mir_surface_configure_cursor(surface, cursorConfiguration); - mir_cursor_configuration_destroy(cursorConfiguration); - } - } else { - applyDefaultCursorConfiguration(surface); - } - -} - -void QMirClientCursor::configureMirCursorWithPixmapQCursor(MirSurface *surface, QCursor &cursor) -{ - QImage image = cursor.pixmap().toImage(); - - if (image.format() != QImage::Format_ARGB32) { - image = image.convertToFormat(QImage::Format_ARGB32); - } - - MirBufferStream *bufferStream = mir_connection_create_buffer_stream_sync(mConnection, - image.width(), image.height(), mir_pixel_format_argb_8888, mir_buffer_usage_software); - - { - MirGraphicsRegion region; - mir_buffer_stream_get_graphics_region(bufferStream, ®ion); - - char *regionLine = region.vaddr; - Q_ASSERT(image.bytesPerLine() <= region.stride); - for (int i = 0; i < image.height(); ++i) { - memcpy(regionLine, image.scanLine(i), image.bytesPerLine()); - regionLine += region.stride; - } - } - - mir_buffer_stream_swap_buffers_sync(bufferStream); - - { - auto configuration = mir_cursor_configuration_from_buffer_stream(bufferStream, cursor.hotSpot().x(), cursor.hotSpot().y()); - mir_surface_configure_cursor(surface, configuration); - mir_cursor_configuration_destroy(configuration); - } - - mir_buffer_stream_release_sync(bufferStream); -} - -void QMirClientCursor::applyDefaultCursorConfiguration(MirSurface *surface) -{ - auto cursorConfiguration = mir_cursor_configuration_from_name("left_ptr"); - mir_surface_configure_cursor(surface, cursorConfiguration); - mir_cursor_configuration_destroy(cursorConfiguration); -} diff --git a/src/plugins/platforms/mirclient/qmirclientcursor.h b/src/plugins/platforms/mirclient/qmirclientcursor.h deleted file mode 100644 index c5de23b272..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientcursor.h +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015-2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTCURSOR_H -#define QMIRCLIENTCURSOR_H - -#include <qpa/qplatformcursor.h> - -#include <QMap> -#include <QByteArray> - -struct MirConnection; -struct MirSurface; - -class QMirClientCursor : public QPlatformCursor -{ -public: - QMirClientCursor(MirConnection *connection); - void changeCursor(QCursor *windowCursor, QWindow *window) override; -private: - void configureMirCursorWithPixmapQCursor(MirSurface *surface, QCursor &cursor); - void applyDefaultCursorConfiguration(MirSurface *surface); - QMap<int, QByteArray> mShapeToCursorName; - MirConnection *mConnection; -}; - -#endif // QMIRCLIENTCURSOR_H diff --git a/src/plugins/platforms/mirclient/qmirclientdebugextension.cpp b/src/plugins/platforms/mirclient/qmirclientdebugextension.cpp deleted file mode 100644 index 9aa934083d..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientdebugextension.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "qmirclientdebugextension.h" - -#include "qmirclientlogging.h" - -// mir client debug -#include <mir_toolkit/debug/surface.h> - -Q_LOGGING_CATEGORY(mirclientDebug, "qt.qpa.mirclient.debug") - -QMirClientDebugExtension::QMirClientDebugExtension() - : m_mirclientDebug(QStringLiteral("mirclient-debug-extension"), 1) - , m_mapper(nullptr) -{ - qCDebug(mirclientDebug) << "NOTICE: Loading mirclient-debug-extension"; - m_mapper = (MapperPrototype) m_mirclientDebug.resolve("mir_debug_surface_coords_to_screen"); - - if (!m_mirclientDebug.isLoaded()) { - qCWarning(mirclientDebug) << "ERROR: mirclient-debug-extension failed to load:" - << m_mirclientDebug.errorString(); - } else if (!m_mapper) { - qCWarning(mirclientDebug) << "ERROR: unable to find required symbols in mirclient-debug-extension:" - << m_mirclientDebug.errorString(); - } -} - -QPoint QMirClientDebugExtension::mapSurfacePointToScreen(MirSurface *surface, const QPoint &point) -{ - if (!m_mapper) { - return point; - } - - QPoint mappedPoint; - bool status = m_mapper(surface, point.x(), point.y(), &mappedPoint.rx(), &mappedPoint.ry()); - if (status) { - return mappedPoint; - } else { - return point; - } -} diff --git a/src/plugins/platforms/mirclient/qmirclientdebugextension.h b/src/plugins/platforms/mirclient/qmirclientdebugextension.h deleted file mode 100644 index 0596561d77..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientdebugextension.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTDEBUGEXTENSION_H -#define QMIRCLIENTDEBUGEXTENSION_H - -#include <QPoint> -#include <QLibrary> -struct MirSurface; - -typedef bool (*MapperPrototype)(MirSurface* surface, int x, int y, int* screenX, int* screenY); - - -class QMirClientDebugExtension -{ -public: - QMirClientDebugExtension(); - - QPoint mapSurfacePointToScreen(MirSurface *, const QPoint &point); - -private: - QLibrary m_mirclientDebug; - MapperPrototype m_mapper; -}; - -#endif // QMIRCLIENTDEBUGEXTENSION_H diff --git a/src/plugins/platforms/mirclient/qmirclientdesktopwindow.cpp b/src/plugins/platforms/mirclient/qmirclientdesktopwindow.cpp deleted file mode 100644 index 123f805c25..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientdesktopwindow.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "qmirclientdesktopwindow.h" - -// local -#include "qmirclientlogging.h" - -QMirClientDesktopWindow::QMirClientDesktopWindow(QWindow *window) - : QPlatformWindow(window) -{ - qCDebug(mirclient, "QMirClientDesktopWindow(window=%p)", window); -} diff --git a/src/plugins/platforms/mirclient/qmirclientdesktopwindow.h b/src/plugins/platforms/mirclient/qmirclientdesktopwindow.h deleted file mode 100644 index 3ba54db826..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientdesktopwindow.h +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTDESKTOPWINDOW_H -#define QMIRCLIENTDESKTOPWINDOW_H - -#include <qpa/qplatformwindow.h> - -// TODO Implement it. For now it's just an empty, dummy class. -class QMirClientDesktopWindow : public QPlatformWindow -{ -public: - QMirClientDesktopWindow(QWindow*); -}; - -#endif // QMIRCLIENTDESKTOPWINDOW_H diff --git a/src/plugins/platforms/mirclient/qmirclientglcontext.cpp b/src/plugins/platforms/mirclient/qmirclientglcontext.cpp deleted file mode 100644 index fc7d90d5ec..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientglcontext.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "qmirclientglcontext.h" -#include "qmirclientlogging.h" -#include "qmirclientwindow.h" - -#include <QOpenGLFramebufferObject> -#include <QtEglSupport/private/qeglconvenience_p.h> -#include <QtEglSupport/private/qeglpbuffer_p.h> -#include <QtGui/private/qopenglcontext_p.h> - -Q_LOGGING_CATEGORY(mirclientGraphics, "qt.qpa.mirclient.graphics", QtWarningMsg) - -namespace { - -void printEglConfig(EGLDisplay display, EGLConfig config) -{ - Q_ASSERT(display != EGL_NO_DISPLAY); - Q_ASSERT(config != nullptr); - - const char *string = eglQueryString(display, EGL_VENDOR); - qCDebug(mirclientGraphics, "EGL vendor: %s", string); - - string = eglQueryString(display, EGL_VERSION); - qCDebug(mirclientGraphics, "EGL version: %s", string); - - string = eglQueryString(display, EGL_EXTENSIONS); - qCDebug(mirclientGraphics, "EGL extensions: %s", string); - - qCDebug(mirclientGraphics, "EGL configuration attributes:"); - q_printEglConfig(display, config); -} - -} // anonymous namespace - -QMirClientOpenGLContext::QMirClientOpenGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, - EGLDisplay display) - : QEGLPlatformContext(format, share, display, 0) -{ - if (mirclientGraphics().isDebugEnabled()) { - printEglConfig(display, eglConfig()); - } -} - -static bool needsFBOReadBackWorkaround() -{ - static bool set = false; - static bool needsWorkaround = false; - - if (Q_UNLIKELY(!set)) { - const char *rendererString = reinterpret_cast<const char *>(glGetString(GL_RENDERER)); - needsWorkaround = qstrncmp(rendererString, "Mali-400", 8) == 0 - || qstrncmp(rendererString, "Mali-T7", 7) == 0 - || qstrncmp(rendererString, "PowerVR Rogue G6200", 19) == 0; - set = true; - } - - return needsWorkaround; -} - -bool QMirClientOpenGLContext::makeCurrent(QPlatformSurface* surface) -{ - const bool ret = QEGLPlatformContext::makeCurrent(surface); - - if (Q_LIKELY(ret)) { - QOpenGLContextPrivate *ctx_d = QOpenGLContextPrivate::get(context()); - if (!ctx_d->workaround_brokenFBOReadBack && needsFBOReadBackWorkaround()) { - ctx_d->workaround_brokenFBOReadBack = true; - } - } - return ret; -} - -// Following method used internally in the base class QEGLPlatformContext to access -// the egl surface of a QPlatformSurface/QMirClientWindow -EGLSurface QMirClientOpenGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface) -{ - if (surface->surface()->surfaceClass() == QSurface::Window) { - return static_cast<QMirClientWindow *>(surface)->eglSurface(); - } else { - return static_cast<QEGLPbuffer *>(surface)->pbuffer(); - } -} - -void QMirClientOpenGLContext::swapBuffers(QPlatformSurface* surface) -{ - QEGLPlatformContext::swapBuffers(surface); - - if (surface->surface()->surfaceClass() == QSurface::Window) { - // notify window on swap completion - auto platformWindow = static_cast<QMirClientWindow *>(surface); - platformWindow->onSwapBuffersDone(); - } -} diff --git a/src/plugins/platforms/mirclient/qmirclientglcontext.h b/src/plugins/platforms/mirclient/qmirclientglcontext.h deleted file mode 100644 index 92331a6fb1..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientglcontext.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTGLCONTEXT_H -#define QMIRCLIENTGLCONTEXT_H - -#include <qpa/qplatformopenglcontext.h> -#include <QtEglSupport/private/qeglplatformcontext_p.h> - -#include <EGL/egl.h> - -class QMirClientOpenGLContext : public QEGLPlatformContext -{ -public: - QMirClientOpenGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, - EGLDisplay display); - - // QEGLPlatformContext methods. - void swapBuffers(QPlatformSurface *surface) final; - bool makeCurrent(QPlatformSurface *surface) final; - -protected: - EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) final; -}; - -#endif // QMIRCLIENTGLCONTEXT_H diff --git a/src/plugins/platforms/mirclient/qmirclientinput.cpp b/src/plugins/platforms/mirclient/qmirclientinput.cpp deleted file mode 100644 index e5319b0435..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientinput.cpp +++ /dev/null @@ -1,708 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -// Local -#include "qmirclientinput.h" -#include "qmirclientintegration.h" -#include "qmirclientnativeinterface.h" -#include "qmirclientscreen.h" -#include "qmirclientwindow.h" -#include "qmirclientlogging.h" -#include "qmirclientorientationchangeevent_p.h" - -// Qt -#include <QtCore/QThread> -#include <QtCore/qglobal.h> -#include <QtCore/QCoreApplication> -#include <QtGui/private/qguiapplication_p.h> -#include <qpa/qplatforminputcontext.h> -#include <qpa/qwindowsysteminterface.h> -#include <QTextCodec> - -#include <xkbcommon/xkbcommon.h> -#include <xkbcommon/xkbcommon-keysyms.h> - -#include <mir_toolkit/mir_client_library.h> - -Q_LOGGING_CATEGORY(mirclientInput, "qt.qpa.mirclient.input", QtWarningMsg) - -namespace -{ - -// XKB Keysyms which do not map directly to Qt types (i.e. Unicode points) -static const uint32_t KeyTable[] = { - XKB_KEY_Escape, Qt::Key_Escape, - XKB_KEY_Tab, Qt::Key_Tab, - XKB_KEY_ISO_Left_Tab, Qt::Key_Backtab, - XKB_KEY_BackSpace, Qt::Key_Backspace, - XKB_KEY_Return, Qt::Key_Return, - XKB_KEY_Insert, Qt::Key_Insert, - XKB_KEY_Delete, Qt::Key_Delete, - XKB_KEY_Clear, Qt::Key_Delete, - XKB_KEY_Pause, Qt::Key_Pause, - XKB_KEY_Print, Qt::Key_Print, - - XKB_KEY_Home, Qt::Key_Home, - XKB_KEY_End, Qt::Key_End, - XKB_KEY_Left, Qt::Key_Left, - XKB_KEY_Up, Qt::Key_Up, - XKB_KEY_Right, Qt::Key_Right, - XKB_KEY_Down, Qt::Key_Down, - XKB_KEY_Prior, Qt::Key_PageUp, - XKB_KEY_Next, Qt::Key_PageDown, - - XKB_KEY_Shift_L, Qt::Key_Shift, - XKB_KEY_Shift_R, Qt::Key_Shift, - XKB_KEY_Shift_Lock, Qt::Key_Shift, - XKB_KEY_Control_L, Qt::Key_Control, - XKB_KEY_Control_R, Qt::Key_Control, - XKB_KEY_Meta_L, Qt::Key_Meta, - XKB_KEY_Meta_R, Qt::Key_Meta, - XKB_KEY_Alt_L, Qt::Key_Alt, - XKB_KEY_Alt_R, Qt::Key_Alt, - XKB_KEY_Caps_Lock, Qt::Key_CapsLock, - XKB_KEY_Num_Lock, Qt::Key_NumLock, - XKB_KEY_Scroll_Lock, Qt::Key_ScrollLock, - XKB_KEY_Super_L, Qt::Key_Super_L, - XKB_KEY_Super_R, Qt::Key_Super_R, - XKB_KEY_Menu, Qt::Key_Menu, - XKB_KEY_Hyper_L, Qt::Key_Hyper_L, - XKB_KEY_Hyper_R, Qt::Key_Hyper_R, - XKB_KEY_Help, Qt::Key_Help, - - XKB_KEY_KP_Space, Qt::Key_Space, - XKB_KEY_KP_Tab, Qt::Key_Tab, - XKB_KEY_KP_Enter, Qt::Key_Enter, - XKB_KEY_KP_Home, Qt::Key_Home, - XKB_KEY_KP_Left, Qt::Key_Left, - XKB_KEY_KP_Up, Qt::Key_Up, - XKB_KEY_KP_Right, Qt::Key_Right, - XKB_KEY_KP_Down, Qt::Key_Down, - XKB_KEY_KP_Prior, Qt::Key_PageUp, - XKB_KEY_KP_Next, Qt::Key_PageDown, - XKB_KEY_KP_End, Qt::Key_End, - XKB_KEY_KP_Begin, Qt::Key_Clear, - XKB_KEY_KP_Insert, Qt::Key_Insert, - XKB_KEY_KP_Delete, Qt::Key_Delete, - XKB_KEY_KP_Equal, Qt::Key_Equal, - XKB_KEY_KP_Multiply, Qt::Key_Asterisk, - XKB_KEY_KP_Add, Qt::Key_Plus, - XKB_KEY_KP_Separator, Qt::Key_Comma, - XKB_KEY_KP_Subtract, Qt::Key_Minus, - XKB_KEY_KP_Decimal, Qt::Key_Period, - XKB_KEY_KP_Divide, Qt::Key_Slash, - - XKB_KEY_ISO_Level3_Shift, Qt::Key_AltGr, - XKB_KEY_Multi_key, Qt::Key_Multi_key, - XKB_KEY_Codeinput, Qt::Key_Codeinput, - XKB_KEY_SingleCandidate, Qt::Key_SingleCandidate, - XKB_KEY_MultipleCandidate, Qt::Key_MultipleCandidate, - XKB_KEY_PreviousCandidate, Qt::Key_PreviousCandidate, - - // dead keys - XKB_KEY_dead_grave, Qt::Key_Dead_Grave, - XKB_KEY_dead_acute, Qt::Key_Dead_Acute, - XKB_KEY_dead_circumflex, Qt::Key_Dead_Circumflex, - XKB_KEY_dead_tilde, Qt::Key_Dead_Tilde, - XKB_KEY_dead_macron, Qt::Key_Dead_Macron, - XKB_KEY_dead_breve, Qt::Key_Dead_Breve, - XKB_KEY_dead_abovedot, Qt::Key_Dead_Abovedot, - XKB_KEY_dead_diaeresis, Qt::Key_Dead_Diaeresis, - XKB_KEY_dead_abovering, Qt::Key_Dead_Abovering, - XKB_KEY_dead_doubleacute, Qt::Key_Dead_Doubleacute, - XKB_KEY_dead_caron, Qt::Key_Dead_Caron, - XKB_KEY_dead_cedilla, Qt::Key_Dead_Cedilla, - XKB_KEY_dead_ogonek, Qt::Key_Dead_Ogonek, - XKB_KEY_dead_iota, Qt::Key_Dead_Iota, - XKB_KEY_dead_voiced_sound, Qt::Key_Dead_Voiced_Sound, - XKB_KEY_dead_semivoiced_sound, Qt::Key_Dead_Semivoiced_Sound, - XKB_KEY_dead_belowdot, Qt::Key_Dead_Belowdot, - XKB_KEY_dead_hook, Qt::Key_Dead_Hook, - XKB_KEY_dead_horn, Qt::Key_Dead_Horn, - XKB_KEY_dead_stroke, Qt::Key_Dead_Stroke, - XKB_KEY_dead_abovecomma, Qt::Key_Dead_Abovecomma, - XKB_KEY_dead_abovereversedcomma, Qt::Key_Dead_Abovereversedcomma, - XKB_KEY_dead_doublegrave, Qt::Key_Dead_Doublegrave, - XKB_KEY_dead_belowring, Qt::Key_Dead_Belowring, - XKB_KEY_dead_belowmacron, Qt::Key_Dead_Belowmacron, - XKB_KEY_dead_belowcircumflex, Qt::Key_Dead_Belowcircumflex, - XKB_KEY_dead_belowtilde, Qt::Key_Dead_Belowtilde, - XKB_KEY_dead_belowbreve, Qt::Key_Dead_Belowbreve, - XKB_KEY_dead_belowdiaeresis, Qt::Key_Dead_Belowdiaeresis, - XKB_KEY_dead_invertedbreve, Qt::Key_Dead_Invertedbreve, - XKB_KEY_dead_belowcomma, Qt::Key_Dead_Belowcomma, - XKB_KEY_dead_currency, Qt::Key_Dead_Currency, - XKB_KEY_dead_a, Qt::Key_Dead_a, - XKB_KEY_dead_A, Qt::Key_Dead_A, - XKB_KEY_dead_e, Qt::Key_Dead_e, - XKB_KEY_dead_E, Qt::Key_Dead_E, - XKB_KEY_dead_i, Qt::Key_Dead_i, - XKB_KEY_dead_I, Qt::Key_Dead_I, - XKB_KEY_dead_o, Qt::Key_Dead_o, - XKB_KEY_dead_O, Qt::Key_Dead_O, - XKB_KEY_dead_u, Qt::Key_Dead_u, - XKB_KEY_dead_U, Qt::Key_Dead_U, - XKB_KEY_dead_small_schwa, Qt::Key_Dead_Small_Schwa, - XKB_KEY_dead_capital_schwa, Qt::Key_Dead_Capital_Schwa, - XKB_KEY_dead_greek, Qt::Key_Dead_Greek, - XKB_KEY_dead_lowline, Qt::Key_Dead_Lowline, - XKB_KEY_dead_aboveverticalline, Qt::Key_Dead_Aboveverticalline, - XKB_KEY_dead_belowverticalline, Qt::Key_Dead_Belowverticalline, - XKB_KEY_dead_longsolidusoverlay, Qt::Key_Dead_Longsolidusoverlay, - - XKB_KEY_Mode_switch, Qt::Key_Mode_switch, - XKB_KEY_script_switch, Qt::Key_Mode_switch, - XKB_KEY_XF86AudioRaiseVolume, Qt::Key_VolumeUp, - XKB_KEY_XF86AudioLowerVolume, Qt::Key_VolumeDown, - XKB_KEY_XF86PowerOff, Qt::Key_PowerOff, - XKB_KEY_XF86PowerDown, Qt::Key_PowerDown, - - 0, 0 -}; - -Qt::WindowState mirSurfaceStateToWindowState(MirSurfaceState state) -{ - switch (state) { - case mir_surface_state_fullscreen: - return Qt::WindowFullScreen; - case mir_surface_state_maximized: - case mir_surface_state_vertmaximized: - case mir_surface_state_horizmaximized: - return Qt::WindowMaximized; - case mir_surface_state_minimized: - return Qt::WindowMinimized; - case mir_surface_state_hidden: - // We should be handling this state separately. - Q_ASSERT(false); - case mir_surface_state_restored: - case mir_surface_state_unknown: - default: - return Qt::WindowNoState; - } -} - -} // namespace - -class UbuntuEvent : public QEvent -{ -public: - UbuntuEvent(QMirClientWindow* window, const MirEvent *event, QEvent::Type type) - : QEvent(type), window(window) { - nativeEvent = mir_event_ref(event); - } - ~UbuntuEvent() - { - mir_event_unref(nativeEvent); - } - - QPointer<QMirClientWindow> window; - const MirEvent *nativeEvent; -}; - -QMirClientInput::QMirClientInput(QMirClientClientIntegration* integration) - : QObject(nullptr) - , mIntegration(integration) - , mEventFilterType(static_cast<QMirClientNativeInterface*>( - integration->nativeInterface())->genericEventFilterType()) - , mEventType(static_cast<QEvent::Type>(QEvent::registerEventType())) - , mLastInputWindow(nullptr) -{ - // Initialize touch device. - mTouchDevice = new QTouchDevice; - mTouchDevice->setType(QTouchDevice::TouchScreen); - mTouchDevice->setCapabilities( - QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure | - QTouchDevice::NormalizedPosition); - QWindowSystemInterface::registerTouchDevice(mTouchDevice); -} - -QMirClientInput::~QMirClientInput() -{ - // Qt will take care of deleting mTouchDevice. -} - -static const char* nativeEventTypeToStr(MirEventType t) -{ - switch (t) - { - case mir_event_type_key: - return "key"; - case mir_event_type_motion: - return "motion"; - case mir_event_type_surface: - return "surface"; - case mir_event_type_resize: - return "resize"; - case mir_event_type_prompt_session_state_change: - return "prompt_session_state_change"; - case mir_event_type_orientation: - return "orientation"; - case mir_event_type_close_surface: - return "close_surface"; - case mir_event_type_input: - return "input"; - case mir_event_type_keymap: - return "keymap"; - case mir_event_type_input_configuration: - return "input_configuration"; - case mir_event_type_surface_output: - return "surface_output"; - case mir_event_type_input_device_state: - return "input_device_state"; - default: - return "unknown"; - } -} - -void QMirClientInput::customEvent(QEvent* event) -{ - Q_ASSERT(QThread::currentThread() == thread()); - UbuntuEvent* ubuntuEvent = static_cast<UbuntuEvent*>(event); - const MirEvent *nativeEvent = ubuntuEvent->nativeEvent; - - if ((ubuntuEvent->window == nullptr) || (ubuntuEvent->window->window() == nullptr)) { - qCWarning(mirclient) << "Attempted to deliver an event to a non-existent window, ignoring."; - return; - } - - // Event filtering. - long result; - if (QWindowSystemInterface::handleNativeEvent( - ubuntuEvent->window->window(), mEventFilterType, - const_cast<void *>(static_cast<const void *>(nativeEvent)), &result) == true) { - qCDebug(mirclient, "event filtered out by native interface"); - return; - } - - qCDebug(mirclientInput, "customEvent(type=%s)", nativeEventTypeToStr(mir_event_get_type(nativeEvent))); - - // Event dispatching. - switch (mir_event_get_type(nativeEvent)) - { - case mir_event_type_input: - dispatchInputEvent(ubuntuEvent->window, mir_event_get_input_event(nativeEvent)); - break; - case mir_event_type_resize: - { - auto resizeEvent = mir_event_get_resize_event(nativeEvent); - - // Enable workaround for Screen rotation - auto const targetWindow = ubuntuEvent->window; - if (targetWindow) { - auto const screen = static_cast<QMirClientScreen*>(targetWindow->screen()); - if (screen) { - screen->handleWindowSurfaceResize( - mir_resize_event_get_width(resizeEvent), - mir_resize_event_get_height(resizeEvent)); - } - - targetWindow->handleSurfaceResized( - mir_resize_event_get_width(resizeEvent), - mir_resize_event_get_height(resizeEvent)); - } - break; - } - case mir_event_type_surface: - handleSurfaceEvent(ubuntuEvent->window, mir_event_get_surface_event(nativeEvent)); - break; - case mir_event_type_surface_output: - handleSurfaceOutputEvent(ubuntuEvent->window, mir_event_get_surface_output_event(nativeEvent)); - break; - case mir_event_type_orientation: - dispatchOrientationEvent(ubuntuEvent->window->window(), mir_event_get_orientation_event(nativeEvent)); - break; - case mir_event_type_close_surface: - QWindowSystemInterface::handleCloseEvent(ubuntuEvent->window->window()); - break; - default: - qCDebug(mirclient, "unhandled event type: %d", static_cast<int>(mir_event_get_type(nativeEvent))); - } -} - -void QMirClientInput::postEvent(QMirClientWindow *platformWindow, const MirEvent *event) -{ - QWindow *window = platformWindow->window(); - - QCoreApplication::postEvent(this, new UbuntuEvent( - platformWindow, event, mEventType)); - - if ((window->flags().testFlag(Qt::WindowTransparentForInput)) && window->parent()) { - QCoreApplication::postEvent(this, new UbuntuEvent( - static_cast<QMirClientWindow*>(platformWindow->QPlatformWindow::parent()), - event, mEventType)); - } -} - -void QMirClientInput::dispatchInputEvent(QMirClientWindow *window, const MirInputEvent *ev) -{ - switch (mir_input_event_get_type(ev)) - { - case mir_input_event_type_key: - dispatchKeyEvent(window, ev); - break; - case mir_input_event_type_touch: - dispatchTouchEvent(window, ev); - break; - case mir_input_event_type_pointer: - dispatchPointerEvent(window, ev); - break; - default: - break; - } -} - -void QMirClientInput::dispatchTouchEvent(QMirClientWindow *window, const MirInputEvent *ev) -{ - const MirTouchEvent *tev = mir_input_event_get_touch_event(ev); - - // FIXME(loicm) Max pressure is device specific. That one is for the Samsung Galaxy Nexus. That - // needs to be fixed as soon as the compat input lib adds query support. - const float kMaxPressure = 1.28; - const QRect kWindowGeometry = window->geometry(); - QList<QWindowSystemInterface::TouchPoint> touchPoints; - - - // TODO: Is it worth setting the Qt::TouchPointStationary ones? Currently they are left - // as Qt::TouchPointMoved - const unsigned int kPointerCount = mir_touch_event_point_count(tev); - touchPoints.reserve(int(kPointerCount)); - for (unsigned int i = 0; i < kPointerCount; ++i) { - QWindowSystemInterface::TouchPoint touchPoint; - - const float kX = mir_touch_event_axis_value(tev, i, mir_touch_axis_x) + kWindowGeometry.x(); - const float kY = mir_touch_event_axis_value(tev, i, mir_touch_axis_y) + kWindowGeometry.y(); // see bug lp:1346633 workaround comments elsewhere - const float kW = mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_major); - const float kH = mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_minor); - const float kP = mir_touch_event_axis_value(tev, i, mir_touch_axis_pressure); - touchPoint.id = mir_touch_event_id(tev, i); - touchPoint.normalPosition = QPointF(kX / kWindowGeometry.width(), kY / kWindowGeometry.height()); - touchPoint.area = QRectF(kX - (kW / 2.0), kY - (kH / 2.0), kW, kH); - touchPoint.pressure = kP / kMaxPressure; - - MirTouchAction touch_action = mir_touch_event_action(tev, i); - switch (touch_action) - { - case mir_touch_action_down: - mLastInputWindow = window; - touchPoint.state = Qt::TouchPointPressed; - break; - case mir_touch_action_up: - touchPoint.state = Qt::TouchPointReleased; - break; - case mir_touch_action_change: - touchPoint.state = Qt::TouchPointMoved; - break; - default: - Q_UNREACHABLE(); - } - - touchPoints.append(touchPoint); - } - - ulong timestamp = mir_input_event_get_event_time(ev) / 1000000; - QWindowSystemInterface::handleTouchEvent(window->window(), timestamp, - mTouchDevice, touchPoints); -} - -static uint32_t translateKeysym(uint32_t sym, const QString &text) { - int code = 0; - - QTextCodec *systemCodec = QTextCodec::codecForLocale(); - if (sym < 128 || (sym < 256 && systemCodec->mibEnum() == 4)) { - // upper-case key, if known - code = isprint((int)sym) ? toupper((int)sym) : 0; - } else if (sym >= XKB_KEY_F1 && sym <= XKB_KEY_F35) { - return Qt::Key_F1 + (int(sym) - XKB_KEY_F1); - } else if (text.length() == 1 && text.unicode()->unicode() > 0x1f - && text.unicode()->unicode() != 0x7f - && !(sym >= XKB_KEY_dead_grave && sym <= XKB_KEY_dead_currency)) { - code = text.unicode()->toUpper().unicode(); - } else { - for (int i = 0; KeyTable[i]; i += 2) - if (sym == KeyTable[i]) - code = KeyTable[i + 1]; - } - - return code; -} - -namespace -{ -Qt::KeyboardModifiers qt_modifiers_from_mir(MirInputEventModifiers modifiers) -{ - Qt::KeyboardModifiers q_modifiers = Qt::NoModifier; - if (modifiers & mir_input_event_modifier_shift) { - q_modifiers |= Qt::ShiftModifier; - } - if (modifiers & mir_input_event_modifier_ctrl) { - q_modifiers |= Qt::ControlModifier; - } - if (modifiers & mir_input_event_modifier_alt_left) { - q_modifiers |= Qt::AltModifier; - } - if (modifiers & mir_input_event_modifier_meta) { - q_modifiers |= Qt::MetaModifier; - } - if (modifiers & mir_input_event_modifier_alt_right) { - q_modifiers |= Qt::GroupSwitchModifier; - } - return q_modifiers; -} -} - -void QMirClientInput::dispatchKeyEvent(QMirClientWindow *window, const MirInputEvent *event) -{ - const MirKeyboardEvent *key_event = mir_input_event_get_keyboard_event(event); - - ulong timestamp = mir_input_event_get_event_time(event) / 1000000; - xkb_keysym_t xk_sym = mir_keyboard_event_key_code(key_event); - quint32 scan_code = mir_keyboard_event_scan_code(key_event); - quint32 native_modifiers = mir_keyboard_event_modifiers(key_event); - - // Key modifier and unicode index mapping. - auto modifiers = qt_modifiers_from_mir(native_modifiers); - - MirKeyboardAction action = mir_keyboard_event_action(key_event); - QEvent::Type keyType = action == mir_keyboard_action_up - ? QEvent::KeyRelease : QEvent::KeyPress; - - if (action == mir_keyboard_action_down) - mLastInputWindow = window; - - QString text; - QVarLengthArray<char, 32> chars(32); - { - int result = xkb_keysym_to_utf8(xk_sym, chars.data(), chars.size()); - - if (result > 0) { - text = QString::fromUtf8(chars.constData()); - } - } - int sym = translateKeysym(xk_sym, text); - - bool is_auto_rep = action == mir_keyboard_action_repeat; - - QPlatformInputContext *context = QGuiApplicationPrivate::platformIntegration()->inputContext(); - if (context) { - QKeyEvent qKeyEvent(keyType, sym, modifiers, scan_code, xk_sym, native_modifiers, text, is_auto_rep); - qKeyEvent.setTimestamp(timestamp); - if (context->filterEvent(&qKeyEvent)) { - qCDebug(mirclient, "key event filtered out by input context"); - return; - } - } - - QWindowSystemInterface::handleExtendedKeyEvent(window->window(), timestamp, keyType, sym, modifiers, scan_code, xk_sym, native_modifiers, text, is_auto_rep); -} - -namespace -{ -Qt::MouseButtons extract_buttons(const MirPointerEvent *pev) -{ - Qt::MouseButtons buttons = Qt::NoButton; - if (mir_pointer_event_button_state(pev, mir_pointer_button_primary)) - buttons |= Qt::LeftButton; - if (mir_pointer_event_button_state(pev, mir_pointer_button_secondary)) - buttons |= Qt::RightButton; - if (mir_pointer_event_button_state(pev, mir_pointer_button_tertiary)) - buttons |= Qt::MiddleButton; - if (mir_pointer_event_button_state(pev, mir_pointer_button_back)) - buttons |= Qt::BackButton; - if (mir_pointer_event_button_state(pev, mir_pointer_button_forward)) - buttons |= Qt::ForwardButton; - - return buttons; -} -} - -void QMirClientInput::dispatchPointerEvent(QMirClientWindow *platformWindow, const MirInputEvent *ev) -{ - const auto window = platformWindow->window(); - const auto timestamp = mir_input_event_get_event_time(ev) / 1000000; - - const auto pev = mir_input_event_get_pointer_event(ev); - const auto action = mir_pointer_event_action(pev); - - const auto modifiers = qt_modifiers_from_mir(mir_pointer_event_modifiers(pev)); - const auto localPoint = QPointF(mir_pointer_event_axis_value(pev, mir_pointer_axis_x), - mir_pointer_event_axis_value(pev, mir_pointer_axis_y)); - - mLastInputWindow = platformWindow; - - switch (action) { - case mir_pointer_action_button_up: - case mir_pointer_action_button_down: - case mir_pointer_action_motion: - { - const float hDelta = mir_pointer_event_axis_value(pev, mir_pointer_axis_hscroll); - const float vDelta = mir_pointer_event_axis_value(pev, mir_pointer_axis_vscroll); - - if (hDelta != 0 || vDelta != 0) { - // QWheelEvent::DefaultDeltasPerStep = 120 but doesn't exist on vivid - const QPoint angleDelta(120 * hDelta, 120 * vDelta); - QWindowSystemInterface::handleWheelEvent(window, timestamp, localPoint, window->position() + localPoint, - QPoint(), angleDelta, modifiers, Qt::ScrollUpdate); - } - auto buttons = extract_buttons(pev); - QWindowSystemInterface::handleMouseEvent(window, timestamp, localPoint, window->position() + localPoint /* Should we omit global point instead? */, - buttons, modifiers); - break; - } - case mir_pointer_action_enter: - QWindowSystemInterface::handleEnterEvent(window, localPoint, window->position() + localPoint); - break; - case mir_pointer_action_leave: - QWindowSystemInterface::handleLeaveEvent(window); - break; - default: - Q_UNREACHABLE(); - } -} - -static const char* nativeOrientationDirectionToStr(MirOrientation orientation) -{ - switch (orientation) { - case mir_orientation_normal: - return "Normal"; - case mir_orientation_left: - return "Left"; - case mir_orientation_inverted: - return "Inverted"; - case mir_orientation_right: - return "Right"; - } - Q_UNREACHABLE(); -} - -void QMirClientInput::dispatchOrientationEvent(QWindow *window, const MirOrientationEvent *event) -{ - MirOrientation mir_orientation = mir_orientation_event_get_direction(event); - qCDebug(mirclientInput, "orientation direction: %s", nativeOrientationDirectionToStr(mir_orientation)); - - if (!window->screen()) { - qCDebug(mirclient, "Window has no associated screen, dropping orientation event"); - return; - } - - OrientationChangeEvent::Orientation orientation; - switch (mir_orientation) { - case mir_orientation_normal: - orientation = OrientationChangeEvent::TopUp; - break; - case mir_orientation_left: - orientation = OrientationChangeEvent::LeftUp; - break; - case mir_orientation_inverted: - orientation = OrientationChangeEvent::TopDown; - break; - case mir_orientation_right: - orientation = OrientationChangeEvent::RightUp; - break; - default: - qCDebug(mirclient, "No such orientation %d", mir_orientation); - return; - } - - // Dispatch orientation event to [Platform]Screen, as that is where Qt reads it. Screen will handle - // notifying Qt of the actual orientation change - done to prevent multiple Windows each creating - // an identical orientation change event and passing it directly to Qt. - // [Platform]Screen can also factor in the native orientation. - QCoreApplication::postEvent(static_cast<QMirClientScreen*>(window->screen()->handle()), - new OrientationChangeEvent(OrientationChangeEvent::mType, orientation)); -} - -void QMirClientInput::handleSurfaceEvent(const QPointer<QMirClientWindow> &window, const MirSurfaceEvent *event) -{ - auto surfaceEventAttribute = mir_surface_event_get_attribute(event); - - switch (surfaceEventAttribute) { - case mir_surface_attrib_focus: { - window->handleSurfaceFocusChanged( - mir_surface_event_get_attribute_value(event) == mir_surface_focused); - break; - } - case mir_surface_attrib_visibility: { - window->handleSurfaceExposeChange( - mir_surface_event_get_attribute_value(event) == mir_surface_visibility_exposed); - break; - } - // Remaining attributes are ones client sets for server, and server should not override them - case mir_surface_attrib_state: { - MirSurfaceState state = static_cast<MirSurfaceState>(mir_surface_event_get_attribute_value(event)); - - if (state == mir_surface_state_hidden) { - window->handleSurfaceVisibilityChanged(false); - } else { - // it's visible! - window->handleSurfaceVisibilityChanged(true); - window->handleSurfaceStateChanged(mirSurfaceStateToWindowState(state)); - } - break; - } - case mir_surface_attrib_type: - case mir_surface_attrib_swapinterval: - case mir_surface_attrib_dpi: - case mir_surface_attrib_preferred_orientation: - case mir_surface_attribs: - break; - } -} - -void QMirClientInput::handleSurfaceOutputEvent(const QPointer<QMirClientWindow> &window, const MirSurfaceOutputEvent *event) -{ - const uint32_t outputId = mir_surface_output_event_get_output_id(event); - const int dpi = mir_surface_output_event_get_dpi(event); - const MirFormFactor formFactor = mir_surface_output_event_get_form_factor(event); - const float scale = mir_surface_output_event_get_scale(event); - - const auto screenObserver = mIntegration->screenObserver(); - QMirClientScreen *screen = screenObserver->findScreenWithId(outputId); - if (!screen) { - qCWarning(mirclient) << "Mir notified window" << window->window() << "on an unknown screen with id" << outputId; - return; - } - - screenObserver->handleScreenPropertiesChange(screen, dpi, formFactor, scale); - window->handleScreenPropertiesChange(formFactor, scale); - - if (window->screen() != screen) { - QWindowSystemInterface::handleWindowScreenChanged(window->window(), screen->screen()); - } -} diff --git a/src/plugins/platforms/mirclient/qmirclientinput.h b/src/plugins/platforms/mirclient/qmirclientinput.h deleted file mode 100644 index 263cb5e54e..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientinput.h +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTINPUT_H -#define QMIRCLIENTINPUT_H - -// Qt -#include <qpa/qwindowsysteminterface.h> - -#include <mir_toolkit/mir_client_library.h> - -class QMirClientClientIntegration; -class QMirClientWindow; - -class QMirClientInput : public QObject -{ - Q_OBJECT - -public: - QMirClientInput(QMirClientClientIntegration* integration); - virtual ~QMirClientInput(); - - // QObject methods. - void customEvent(QEvent* event) override; - - void postEvent(QMirClientWindow* window, const MirEvent *event); - QMirClientClientIntegration* integration() const { return mIntegration; } - QMirClientWindow *lastInputWindow() const {return mLastInputWindow; } - -protected: - void dispatchKeyEvent(QMirClientWindow *window, const MirInputEvent *event); - void dispatchPointerEvent(QMirClientWindow *window, const MirInputEvent *event); - void dispatchTouchEvent(QMirClientWindow *window, const MirInputEvent *event); - void dispatchInputEvent(QMirClientWindow *window, const MirInputEvent *event); - - void dispatchOrientationEvent(QWindow* window, const MirOrientationEvent *event); - void handleSurfaceEvent(const QPointer<QMirClientWindow> &window, const MirSurfaceEvent *event); - void handleSurfaceOutputEvent(const QPointer<QMirClientWindow> &window, const MirSurfaceOutputEvent *event); - -private: - QMirClientClientIntegration* mIntegration; - QTouchDevice* mTouchDevice; - const QByteArray mEventFilterType; - const QEvent::Type mEventType; - - QMirClientWindow *mLastInputWindow; -}; - -#endif // QMIRCLIENTINPUT_H diff --git a/src/plugins/platforms/mirclient/qmirclientintegration.cpp b/src/plugins/platforms/mirclient/qmirclientintegration.cpp deleted file mode 100644 index eef96ee3de..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientintegration.cpp +++ /dev/null @@ -1,411 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -// Local -#include "qmirclientintegration.h" -#include "qmirclientbackingstore.h" -#include "qmirclientclipboard.h" -#include "qmirclientdebugextension.h" -#include "qmirclientdesktopwindow.h" -#include "qmirclientglcontext.h" -#include "qmirclientinput.h" -#include "qmirclientlogging.h" -#include "qmirclientnativeinterface.h" -#include "qmirclientscreen.h" -#include "qmirclienttheme.h" -#include "qmirclientwindow.h" - -// Qt -#include <QFileInfo> -#include <QGuiApplication> -#include <qpa/qplatformnativeinterface.h> -#include <qpa/qplatforminputcontextfactory_p.h> -#include <qpa/qplatforminputcontext.h> -#include <QtEglSupport/private/qeglconvenience_p.h> -#include <QtEglSupport/private/qeglpbuffer_p.h> -#include <QtFontDatabaseSupport/private/qgenericunixfontdatabase_p.h> -#include <QtEventDispatcherSupport/private/qgenericunixeventdispatcher_p.h> -#ifndef QT_NO_ACCESSIBILITY -#include <qpa/qplatformaccessibility.h> -#ifndef QT_NO_ACCESSIBILITY_ATSPI_BRIDGE -#include <QtLinuxAccessibilitySupport/private/bridge_p.h> -#endif -#endif - -#include <QOpenGLContext> -#include <QOffscreenSurface> - -// platform-api -#include <ubuntu/application/lifecycle_delegate.h> -#include <ubuntu/application/id.h> -#include <ubuntu/application/options.h> - -static void resumedCallback(const UApplicationOptions */*options*/, void* context) -{ - auto integration = static_cast<QMirClientClientIntegration*>(context); - integration->appStateController()->setResumed(); -} - -static void aboutToStopCallback(UApplicationArchive */*archive*/, void* context) -{ - auto integration = static_cast<QMirClientClientIntegration*>(context); - auto inputContext = integration->inputContext(); - if (inputContext) { - inputContext->hideInputPanel(); - } else { - qCWarning(mirclient) << "aboutToStopCallback(): no input context"; - } - integration->appStateController()->setSuspended(); -} - -QMirClientClientIntegration::QMirClientClientIntegration(int argc, char **argv) - : QPlatformIntegration() - , mNativeInterface(new QMirClientNativeInterface(this)) - , mFontDb(new QGenericUnixFontDatabase) - , mServices(new QMirClientPlatformServices) - , mAppStateController(new QMirClientAppStateController) - , mScaleFactor(1.0) -{ - { - QStringList args = QCoreApplication::arguments(); - setupOptions(args); - QByteArray sessionName = generateSessionName(args); - setupDescription(sessionName); - } - - // Create new application instance - mInstance = u_application_instance_new_from_description_with_options(mDesc, mOptions); - - if (Q_UNLIKELY(!mInstance)) - qFatal("QMirClientClientIntegration: connection to Mir server failed. Check that a Mir server is\n" - "running, and the correct socket is being used and is accessible. The shell may have\n" - "rejected the incoming connection, so check its log file"); - - mMirConnection = u_application_instance_get_mir_connection(mInstance); - - // Choose the default surface format suited to the Mir platform - QSurfaceFormat defaultFormat; - defaultFormat.setRedBufferSize(8); - defaultFormat.setGreenBufferSize(8); - defaultFormat.setBlueBufferSize(8); - QSurfaceFormat::setDefaultFormat(defaultFormat); - - // Initialize EGL. - mEglNativeDisplay = mir_connection_get_egl_native_display(mMirConnection); - ASSERT((mEglDisplay = eglGetDisplay(mEglNativeDisplay)) != EGL_NO_DISPLAY); - ASSERT(eglInitialize(mEglDisplay, nullptr, nullptr) == EGL_TRUE); - - // Has debug mode been requsted, either with "-testability" switch or QT_LOAD_TESTABILITY env var - bool testability = qEnvironmentVariableIsSet("QT_LOAD_TESTABILITY"); - for (int i=1; !testability && i<argc; i++) { - if (strcmp(argv[i], "-testability") == 0) { - testability = true; - } - } - if (testability) { - mDebugExtension.reset(new QMirClientDebugExtension); - } -} - -void QMirClientClientIntegration::initialize() -{ - // Init the ScreenObserver - mScreenObserver.reset(new QMirClientScreenObserver(mMirConnection)); - connect(mScreenObserver.data(), &QMirClientScreenObserver::screenAdded, - [this](QMirClientScreen *screen) { this->screenAdded(screen); }); - connect(mScreenObserver.data(), &QMirClientScreenObserver::screenRemoved, - this, &QMirClientClientIntegration::destroyScreen); - - Q_FOREACH (auto screen, mScreenObserver->screens()) { - screenAdded(screen); - } - - // Initialize input. - mInput = new QMirClientInput(this); - mInputContext = QPlatformInputContextFactory::create(); - - // compute the scale factor - const int defaultGridUnit = 8; - int gridUnit = defaultGridUnit; - QByteArray gridUnitString = qgetenv("GRID_UNIT_PX"); - if (!gridUnitString.isEmpty()) { - bool ok; - gridUnit = gridUnitString.toInt(&ok); - if (!ok) { - gridUnit = defaultGridUnit; - } - } - mScaleFactor = static_cast<qreal>(gridUnit) / defaultGridUnit; -} - -QMirClientClientIntegration::~QMirClientClientIntegration() -{ - eglTerminate(mEglDisplay); - delete mInput; - delete mInputContext; - delete mServices; -} - -QPlatformServices *QMirClientClientIntegration::services() const -{ - return mServices; -} - -void QMirClientClientIntegration::setupOptions(QStringList &args) -{ - int argc = args.size() + 1; - char **argv = new char*[argc]; - for (int i = 0; i < argc - 1; i++) - argv[i] = qstrdup(args.at(i).toLocal8Bit()); - argv[argc - 1] = nullptr; - - mOptions = u_application_options_new_from_cmd_line(argc - 1, argv); - - for (int i = 0; i < argc; i++) - delete [] argv[i]; - delete [] argv; -} - -void QMirClientClientIntegration::setupDescription(QByteArray &sessionName) -{ - mDesc = u_application_description_new(); - - UApplicationId* id = u_application_id_new_from_stringn(sessionName.data(), sessionName.count()); - u_application_description_set_application_id(mDesc, id); - - UApplicationLifecycleDelegate* delegate = u_application_lifecycle_delegate_new(); - u_application_lifecycle_delegate_set_application_resumed_cb(delegate, &resumedCallback); - u_application_lifecycle_delegate_set_application_about_to_stop_cb(delegate, &aboutToStopCallback); - u_application_lifecycle_delegate_set_context(delegate, this); - u_application_description_set_application_lifecycle_delegate(mDesc, delegate); -} - -QByteArray QMirClientClientIntegration::generateSessionName(QStringList &args) -{ - // Try to come up with some meaningful session name to uniquely identify this session, - // helping with shell debugging - - if (args.count() == 0) { - return QByteArray("QtUbuntu"); - } if (args[0].contains("qmlscene")) { - return generateSessionNameFromQmlFile(args); - } else { - // use the executable name - QFileInfo fileInfo(args[0]); - return fileInfo.fileName().toLocal8Bit(); - } -} - -QByteArray QMirClientClientIntegration::generateSessionNameFromQmlFile(QStringList &args) -{ - Q_FOREACH (QString arg, args) { - if (arg.endsWith(".qml")) { - QFileInfo fileInfo(arg); - return fileInfo.fileName().toLocal8Bit(); - } - } - - // give up - return "qmlscene"; -} - -QPlatformWindow* QMirClientClientIntegration::createPlatformWindow(QWindow* window) const -{ - if (window->type() == Qt::Desktop) { - // Desktop windows should not be backed up by a mir surface as they don't draw anything (nor should). - return new QMirClientDesktopWindow(window); - } else { - return new QMirClientWindow(window, mInput, mNativeInterface, mAppStateController.data(), - mEglDisplay, mMirConnection, mDebugExtension.data()); - } -} - -bool QMirClientClientIntegration::hasCapability(QPlatformIntegration::Capability cap) const -{ - switch (cap) { - case ThreadedOpenGL: - if (qEnvironmentVariableIsEmpty("QTUBUNTU_NO_THREADED_OPENGL")) { - return true; - } else { - qCDebug(mirclient, "disabled threaded OpenGL"); - return false; - } - - case ThreadedPixmaps: - case OpenGL: - case ApplicationState: - case MultipleWindows: - case NonFullScreenWindows: -#if QT_VERSION > QT_VERSION_CHECK(5, 5, 0) - case SwitchableWidgetComposition: -#endif - case RasterGLSurface: // needed for QQuickWidget - return true; - default: - return QPlatformIntegration::hasCapability(cap); - } -} - -QAbstractEventDispatcher *QMirClientClientIntegration::createEventDispatcher() const -{ - return createUnixEventDispatcher(); -} - -QPlatformBackingStore* QMirClientClientIntegration::createPlatformBackingStore(QWindow* window) const -{ - return new QMirClientBackingStore(window); -} - -QPlatformOpenGLContext* QMirClientClientIntegration::createPlatformOpenGLContext( - QOpenGLContext* context) const -{ - QSurfaceFormat format(context->format()); - - auto platformContext = new QMirClientOpenGLContext(format, context->shareHandle(), mEglDisplay); - if (!platformContext->isValid()) { - // Older Intel Atom-based devices only support OpenGL 1.4 compatibility profile but by default - // QML asks for at least OpenGL 2.0. The XCB GLX backend ignores this request and returns a - // 1.4 context, but the XCB EGL backend tries to honor it, and fails. The 1.4 context appears to - // have sufficient capabilities on MESA (i915) to render correctly however. So reduce the default - // requested OpenGL version to 1.0 to ensure EGL will give us a working context (lp:1549455). - static const bool isMesa = QString(eglQueryString(mEglDisplay, EGL_VENDOR)).contains(QStringLiteral("Mesa")); - if (isMesa) { - qCDebug(mirclientGraphics, "Attempting to choose OpenGL 1.4 context which may suit Mesa"); - format.setMajorVersion(1); - format.setMinorVersion(4); - delete platformContext; - platformContext = new QMirClientOpenGLContext(format, context->shareHandle(), mEglDisplay); - } - } - return platformContext; -} - -QStringList QMirClientClientIntegration::themeNames() const -{ - return QStringList(QMirClientTheme::name); -} - -QPlatformTheme* QMirClientClientIntegration::createPlatformTheme(const QString& name) const -{ - Q_UNUSED(name); - return new QMirClientTheme; -} - -QVariant QMirClientClientIntegration::styleHint(StyleHint hint) const -{ - switch (hint) { - case QPlatformIntegration::StartDragDistance: { - // default is 10 pixels (see QPlatformTheme::defaultThemeHint) - return 10.0 * mScaleFactor; - } - case QPlatformIntegration::PasswordMaskDelay: { - // return time in milliseconds - 1 second - return QVariant(1000); - } - default: - break; - } - return QPlatformIntegration::styleHint(hint); -} - -QPlatformClipboard* QMirClientClientIntegration::clipboard() const -{ - static QPlatformClipboard *clipboard = nullptr; - if (!clipboard) { - clipboard = new QMirClientClipboard; - } - return clipboard; -} - -QPlatformNativeInterface* QMirClientClientIntegration::nativeInterface() const -{ - return mNativeInterface; -} - -QPlatformOffscreenSurface *QMirClientClientIntegration::createPlatformOffscreenSurface( - QOffscreenSurface *surface) const -{ - return new QEGLPbuffer(mEglDisplay, surface->requestedFormat(), surface); -} - -void QMirClientClientIntegration::destroyScreen(QMirClientScreen *screen) -{ - // FIXME: on deleting a screen while a Window is on it, Qt will automatically - // move the window to the primaryScreen(). This will trigger a screenChanged - // signal, causing things like QQuickScreenAttached to re-fetch screen properties - // like DPI and physical size. However this is crashing, as Qt is calling virtual - // functions on QPlatformScreen, for reasons unclear. As workaround, move window - // to primaryScreen() before deleting the screen. Might be QTBUG-38650 - - QScreen *primaryScreen = QGuiApplication::primaryScreen(); - if (screen != primaryScreen->handle()) { - uint32_t movedWindowCount = 0; - Q_FOREACH (QWindow *w, QGuiApplication::topLevelWindows()) { - if (w->screen()->handle() == screen) { - QWindowSystemInterface::handleWindowScreenChanged(w, primaryScreen); - ++movedWindowCount; - } - } - if (movedWindowCount > 0) { - QWindowSystemInterface::flushWindowSystemEvents(); - } - } - - qCDebug(mirclient) << "Removing Screen with id" << screen->mirOutputId() << "and geometry" << screen->geometry(); -#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0) - delete screen; -#else - QPlatformIntegration::destroyScreen(screen); -#endif -} - -#ifndef QT_NO_ACCESSIBILITY -QPlatformAccessibility *QMirClientClientIntegration::accessibility() const -{ -#if !defined(QT_NO_ACCESSIBILITY_ATSPI_BRIDGE) - if (!mAccessibility) { - Q_ASSERT_X(QCoreApplication::eventDispatcher(), "QMirClientIntegration", - "Initializing accessibility without event-dispatcher!"); - mAccessibility.reset(new QSpiAccessibleBridge()); - } -#endif - return mAccessibility.data(); -} -#endif diff --git a/src/plugins/platforms/mirclient/qmirclientintegration.h b/src/plugins/platforms/mirclient/qmirclientintegration.h deleted file mode 100644 index 035117f4da..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientintegration.h +++ /dev/null @@ -1,131 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTINTEGRATION_H -#define QMIRCLIENTINTEGRATION_H - -#include <qpa/qplatformintegration.h> -#include <QSharedPointer> - -#include "qmirclientappstatecontroller.h" -#include "qmirclientplatformservices.h" -#include "qmirclientscreenobserver.h" - -// platform-api -#include <ubuntu/application/description.h> -#include <ubuntu/application/instance.h> - -#include <EGL/egl.h> - -class QMirClientDebugExtension; -class QMirClientInput; -class QMirClientNativeInterface; -class QMirClientScreen; -class MirConnection; - -class QMirClientClientIntegration : public QObject, public QPlatformIntegration -{ - Q_OBJECT - -public: - QMirClientClientIntegration(int argc, char **argv); - virtual ~QMirClientClientIntegration(); - - // QPlatformIntegration methods. - bool hasCapability(QPlatformIntegration::Capability cap) const override; - QAbstractEventDispatcher *createEventDispatcher() const override; - QPlatformNativeInterface* nativeInterface() const override; - QPlatformBackingStore* createPlatformBackingStore(QWindow* window) const override; - QPlatformOpenGLContext* createPlatformOpenGLContext(QOpenGLContext* context) const override; - QPlatformFontDatabase* fontDatabase() const override { return mFontDb; } - QStringList themeNames() const override; - QPlatformTheme* createPlatformTheme(const QString& name) const override; - QVariant styleHint(StyleHint hint) const override; - QPlatformServices *services() const override; - QPlatformWindow* createPlatformWindow(QWindow* window) const override; - QPlatformInputContext* inputContext() const override { return mInputContext; } - QPlatformClipboard* clipboard() const override; - void initialize() override; - QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const override; - QPlatformAccessibility *accessibility() const override; - - // New methods. - MirConnection *mirConnection() const { return mMirConnection; } - EGLDisplay eglDisplay() const { return mEglDisplay; } - EGLNativeDisplayType eglNativeDisplay() const { return mEglNativeDisplay; } - QMirClientAppStateController *appStateController() const { return mAppStateController.data(); } - QMirClientScreenObserver *screenObserver() const { return mScreenObserver.data(); } - QMirClientDebugExtension *debugExtension() const { return mDebugExtension.data(); } - -private Q_SLOTS: - void destroyScreen(QMirClientScreen *screen); - -private: - void setupOptions(QStringList &args); - void setupDescription(QByteArray &sessionName); - static QByteArray generateSessionName(QStringList &args); - static QByteArray generateSessionNameFromQmlFile(QStringList &args); - - QMirClientNativeInterface* mNativeInterface; - QPlatformFontDatabase* mFontDb; - - QMirClientPlatformServices* mServices; - - QMirClientInput* mInput; - QPlatformInputContext* mInputContext; - mutable QScopedPointer<QPlatformAccessibility> mAccessibility; - QScopedPointer<QMirClientDebugExtension> mDebugExtension; - QScopedPointer<QMirClientScreenObserver> mScreenObserver; - QScopedPointer<QMirClientAppStateController> mAppStateController; - qreal mScaleFactor; - - MirConnection *mMirConnection; - - // Platform API stuff - UApplicationOptions* mOptions; - UApplicationDescription* mDesc; - UApplicationInstance* mInstance; - - // EGL related - EGLDisplay mEglDisplay{EGL_NO_DISPLAY}; - EGLNativeDisplayType mEglNativeDisplay; -}; - -#endif // QMIRCLIENTINTEGRATION_H diff --git a/src/plugins/platforms/mirclient/qmirclientlogging.h b/src/plugins/platforms/mirclient/qmirclientlogging.h deleted file mode 100644 index 4921864ced..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientlogging.h +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTLOGGING_H -#define QMIRCLIENTLOGGING_H - -#include <QLoggingCategory> - -#define ASSERT(cond) ((!(cond)) ? qt_assert(#cond,__FILE__,__LINE__) : qt_noop()) - -Q_DECLARE_LOGGING_CATEGORY(mirclient) -Q_DECLARE_LOGGING_CATEGORY(mirclientBufferSwap) -Q_DECLARE_LOGGING_CATEGORY(mirclientInput) -Q_DECLARE_LOGGING_CATEGORY(mirclientGraphics) -Q_DECLARE_LOGGING_CATEGORY(mirclientCursor) -Q_DECLARE_LOGGING_CATEGORY(mirclientDebug) - -#endif // QMIRCLIENTLOGGING_H diff --git a/src/plugins/platforms/mirclient/qmirclientnativeinterface.cpp b/src/plugins/platforms/mirclient/qmirclientnativeinterface.cpp deleted file mode 100644 index b85e6fedfa..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientnativeinterface.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -// Local -#include "qmirclientnativeinterface.h" -#include "qmirclientscreen.h" -#include "qmirclientglcontext.h" -#include "qmirclientwindow.h" - -// Qt -#include <QtGui/private/qguiapplication_p.h> -#include <QtGui/qopenglcontext.h> -#include <QtGui/qscreen.h> -#include <QtCore/QMap> - -class UbuntuResourceMap : public QMap<QByteArray, QMirClientNativeInterface::ResourceType> -{ -public: - UbuntuResourceMap() - : QMap<QByteArray, QMirClientNativeInterface::ResourceType>() { - insert("egldisplay", QMirClientNativeInterface::EglDisplay); - insert("eglcontext", QMirClientNativeInterface::EglContext); - insert("nativeorientation", QMirClientNativeInterface::NativeOrientation); - insert("display", QMirClientNativeInterface::Display); - insert("mirconnection", QMirClientNativeInterface::MirConnection); - insert("mirsurface", QMirClientNativeInterface::MirSurface); - insert("scale", QMirClientNativeInterface::Scale); - insert("formfactor", QMirClientNativeInterface::FormFactor); - } -}; - -Q_GLOBAL_STATIC(UbuntuResourceMap, ubuntuResourceMap) - -QMirClientNativeInterface::QMirClientNativeInterface(const QMirClientClientIntegration *integration) - : mIntegration(integration) - , mGenericEventFilterType(QByteArrayLiteral("Event")) - , mNativeOrientation(nullptr) -{ -} - -QMirClientNativeInterface::~QMirClientNativeInterface() -{ - delete mNativeOrientation; - mNativeOrientation = nullptr; -} - -void* QMirClientNativeInterface::nativeResourceForIntegration(const QByteArray &resourceString) -{ - const QByteArray lowerCaseResource = resourceString.toLower(); - - if (!ubuntuResourceMap()->contains(lowerCaseResource)) { - return nullptr; - } - - const ResourceType resourceType = ubuntuResourceMap()->value(lowerCaseResource); - - if (resourceType == QMirClientNativeInterface::MirConnection) { - return mIntegration->mirConnection(); - } else { - return nullptr; - } -} - -void* QMirClientNativeInterface::nativeResourceForContext( - const QByteArray& resourceString, QOpenGLContext* context) -{ - if (!context) - return nullptr; - - const QByteArray kLowerCaseResource = resourceString.toLower(); - - if (!ubuntuResourceMap()->contains(kLowerCaseResource)) - return nullptr; - - const ResourceType kResourceType = ubuntuResourceMap()->value(kLowerCaseResource); - - if (kResourceType == QMirClientNativeInterface::EglContext) - return static_cast<QMirClientOpenGLContext*>(context->handle())->eglContext(); - else - return nullptr; -} - -void* QMirClientNativeInterface::nativeResourceForWindow(const QByteArray& resourceString, QWindow* window) -{ - const QByteArray kLowerCaseResource = resourceString.toLower(); - if (!ubuntuResourceMap()->contains(kLowerCaseResource)) - return NULL; - const ResourceType kResourceType = ubuntuResourceMap()->value(kLowerCaseResource); - - switch (kResourceType) { - case EglDisplay: - return mIntegration->eglDisplay(); - case NativeOrientation: - // Return the device's native screen orientation. - if (window) { - QMirClientScreen *ubuntuScreen = static_cast<QMirClientScreen*>(window->screen()->handle()); - mNativeOrientation = new Qt::ScreenOrientation(ubuntuScreen->nativeOrientation()); - } else { - QPlatformScreen *platformScreen = QGuiApplication::primaryScreen()->handle(); - mNativeOrientation = new Qt::ScreenOrientation(platformScreen->nativeOrientation()); - } - return mNativeOrientation; - case MirSurface: - if (window) { - auto ubuntuWindow = static_cast<QMirClientWindow*>(window->handle()); - if (ubuntuWindow) { - return ubuntuWindow->mirSurface(); - } else { - return nullptr; - } - } else { - return nullptr; - } - default: - return nullptr; - } -} - -void* QMirClientNativeInterface::nativeResourceForScreen(const QByteArray& resourceString, QScreen* screen) -{ - const QByteArray kLowerCaseResource = resourceString.toLower(); - if (!ubuntuResourceMap()->contains(kLowerCaseResource)) - return NULL; - const ResourceType kResourceType = ubuntuResourceMap()->value(kLowerCaseResource); - if (!screen) - screen = QGuiApplication::primaryScreen(); - auto ubuntuScreen = static_cast<QMirClientScreen*>(screen->handle()); - if (kResourceType == QMirClientNativeInterface::Display) { - return mIntegration->eglNativeDisplay(); - // Changes to the following properties are emitted via the QMirClientNativeInterface::screenPropertyChanged - // signal fired by QMirClientScreen. Connect to this signal for these properties updates. - // WARNING: code highly thread unsafe! - } else if (kResourceType == QMirClientNativeInterface::Scale) { - // In application code, read with: - // float scale = *reinterpret_cast<float*>(nativeResourceForScreen("scale", screen())); - return &ubuntuScreen->mScale; - } else if (kResourceType == QMirClientNativeInterface::FormFactor) { - return &ubuntuScreen->mFormFactor; - } else - return NULL; -} - -// Changes to these properties are emitted via the QMirClientNativeInterface::windowPropertyChanged -// signal fired by QMirClientWindow. Connect to this signal for these properties updates. -QVariantMap QMirClientNativeInterface::windowProperties(QPlatformWindow *window) const -{ - QVariantMap propertyMap; - auto w = static_cast<QMirClientWindow*>(window); - if (w) { - propertyMap.insert("scale", w->scale()); - propertyMap.insert("formFactor", w->formFactor()); - } - return propertyMap; -} - -QVariant QMirClientNativeInterface::windowProperty(QPlatformWindow *window, const QString &name) const -{ - auto w = static_cast<QMirClientWindow*>(window); - if (!w) { - return QVariant(); - } - - if (name == QStringLiteral("scale")) { - return w->scale(); - } else if (name == QStringLiteral("formFactor")) { - return w->formFactor(); - } else { - return QVariant(); - } -} - -QVariant QMirClientNativeInterface::windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const -{ - QVariant returnVal = windowProperty(window, name); - if (!returnVal.isValid()) { - return defaultValue; - } else { - return returnVal; - } -} diff --git a/src/plugins/platforms/mirclient/qmirclientnativeinterface.h b/src/plugins/platforms/mirclient/qmirclientnativeinterface.h deleted file mode 100644 index eb601de301..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientnativeinterface.h +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTNATIVEINTERFACE_H -#define QMIRCLIENTNATIVEINTERFACE_H - -#include <qpa/qplatformnativeinterface.h> - -#include "qmirclientintegration.h" - -class QPlatformScreen; - -class QMirClientNativeInterface : public QPlatformNativeInterface { - Q_OBJECT -public: - enum ResourceType { EglDisplay, EglContext, NativeOrientation, Display, MirConnection, MirSurface, Scale, FormFactor }; - - QMirClientNativeInterface(const QMirClientClientIntegration *integration); - ~QMirClientNativeInterface(); - - // QPlatformNativeInterface methods. - void* nativeResourceForIntegration(const QByteArray &resource) override; - void* nativeResourceForContext(const QByteArray& resourceString, - QOpenGLContext* context) override; - void* nativeResourceForWindow(const QByteArray& resourceString, - QWindow* window) override; - void* nativeResourceForScreen(const QByteArray& resourceString, - QScreen* screen) override; - - QVariantMap windowProperties(QPlatformWindow *window) const override; - QVariant windowProperty(QPlatformWindow *window, const QString &name) const override; - QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const override; - - // New methods. - const QByteArray& genericEventFilterType() const { return mGenericEventFilterType; } - -Q_SIGNALS: // New signals - void screenPropertyChanged(QPlatformScreen *screen, const QString &propertyName); - -private: - const QMirClientClientIntegration *mIntegration; - const QByteArray mGenericEventFilterType; - Qt::ScreenOrientation* mNativeOrientation; -}; - -#endif // QMIRCLIENTNATIVEINTERFACE_H diff --git a/src/plugins/platforms/mirclient/qmirclientorientationchangeevent_p.h b/src/plugins/platforms/mirclient/qmirclientorientationchangeevent_p.h deleted file mode 100644 index 5abd3262dc..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientorientationchangeevent_p.h +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTORIENTATIONCHANGEEVENT_P_H -#define QMIRCLIENTORIENTATIONCHANGEEVENT_P_H - -#include <QEvent> -#include "qmirclientlogging.h" - -class OrientationChangeEvent : public QEvent { -public: - enum Orientation { TopUp, LeftUp, TopDown, RightUp }; - - OrientationChangeEvent(QEvent::Type type, Orientation orientation) - : QEvent(type) - , mOrientation(orientation) - { - } - - static const QEvent::Type mType; - Orientation mOrientation; -}; - -#endif // QMIRCLIENTORIENTATIONCHANGEEVENT_P_H diff --git a/src/plugins/platforms/mirclient/qmirclientplatformservices.cpp b/src/plugins/platforms/mirclient/qmirclientplatformservices.cpp deleted file mode 100644 index 1ccd57fc28..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientplatformservices.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "qmirclientplatformservices.h" - -#include <QUrl> - -#include <ubuntu/application/url_dispatcher/service.h> -#include <ubuntu/application/url_dispatcher/session.h> - -bool QMirClientPlatformServices::openUrl(const QUrl &url) -{ - return callDispatcher(url); -} - -bool QMirClientPlatformServices::openDocument(const QUrl &url) -{ - return callDispatcher(url); -} - -bool QMirClientPlatformServices::callDispatcher(const QUrl &url) -{ - UAUrlDispatcherSession* session = ua_url_dispatcher_session(); - if (!session) - return false; - - ua_url_dispatcher_session_open(session, url.toEncoded().constData(), NULL, NULL); - - free(session); - - // We are returning true here because the other option - // is spawning a nested event loop and wait for the - // callback. But there is no guarantee on how fast - // the callback is going to be so we prefer to avoid the - // nested event loop. Long term plan is improve Qt API - // to support an async openUrl - return true; -} diff --git a/src/plugins/platforms/mirclient/qmirclientplatformservices.h b/src/plugins/platforms/mirclient/qmirclientplatformservices.h deleted file mode 100644 index a1cd5758ca..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientplatformservices.h +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTPLATFORMSERVICES_H -#define QMIRCLIENTPLATFORMSERVICES_H - -#include <qpa/qplatformservices.h> -#include <QtFontDatabaseSupport/private/qgenericunixfontdatabase_p.h> -#include <QtEventDispatcherSupport/private/qgenericunixeventdispatcher_p.h> - -class QMirClientPlatformServices : public QPlatformServices { -public: - bool openUrl(const QUrl &url) override; - bool openDocument(const QUrl &url) override; - -private: - bool callDispatcher(const QUrl &url); -}; - -#endif // QMIRCLIENTPLATFORMSERVICES_H diff --git a/src/plugins/platforms/mirclient/qmirclientplugin.cpp b/src/plugins/platforms/mirclient/qmirclientplugin.cpp deleted file mode 100644 index fc44edfe40..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientplugin.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "qmirclientplugin.h" -#include "qmirclientintegration.h" -#include "qmirclientlogging.h" - -Q_LOGGING_CATEGORY(mirclient, "qt.qpa.mirclient", QtWarningMsg) - -QPlatformIntegration *QMirClientIntegrationPlugin::create(const QString &system, - const QStringList &/*paramList*/, - int &argc, char **argv) -{ - if (system.toLower() == QLatin1String("mirclient")) { - return new QMirClientClientIntegration(argc, argv); - } else { - return 0; - } -} diff --git a/src/plugins/platforms/mirclient/qmirclientplugin.h b/src/plugins/platforms/mirclient/qmirclientplugin.h deleted file mode 100644 index 207d97b5af..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientplugin.h +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTPLUGIN_H -#define QMIRCLIENTPLUGIN_H - -#include <qpa/qplatformintegrationplugin.h> - -class QMirClientIntegrationPlugin : public QPlatformIntegrationPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "mirclient.json") - -public: - QPlatformIntegration *create(const QString &system, const QStringList ¶mList, - int &argc, char **argv) override; -}; - -#endif // QMIRCLIENTPLUGIN_H diff --git a/src/plugins/platforms/mirclient/qmirclientscreen.cpp b/src/plugins/platforms/mirclient/qmirclientscreen.cpp deleted file mode 100644 index cc8db830aa..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientscreen.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -// local -#include "qmirclientscreen.h" -#include "qmirclientlogging.h" -#include "qmirclientorientationchangeevent_p.h" -#include "qmirclientnativeinterface.h" - -#include <mir_toolkit/mir_client_library.h> - -// Qt -#include <QGuiApplication> -#include <QtCore/qmath.h> -#include <QScreen> -#include <QThread> -#include <qpa/qwindowsysteminterface.h> -#include <QtEglSupport/private/qeglconvenience_p.h> - -#include <memory> - -static const int overrideDevicePixelRatio = qgetenv("QT_DEVICE_PIXEL_RATIO").toInt(); - -static const char *orientationToStr(Qt::ScreenOrientation orientation) { - switch (orientation) { - case Qt::PrimaryOrientation: - return "primary"; - case Qt::PortraitOrientation: - return "portrait"; - case Qt::LandscapeOrientation: - return "landscape"; - case Qt::InvertedPortraitOrientation: - return "inverted portrait"; - case Qt::InvertedLandscapeOrientation: - return "inverted landscape"; - } - Q_UNREACHABLE(); -} - -const QEvent::Type OrientationChangeEvent::mType = - static_cast<QEvent::Type>(QEvent::registerEventType()); - - -QMirClientScreen::QMirClientScreen(const MirOutput *output, MirConnection *connection) - : mDevicePixelRatio(1.0) - , mFormat(QImage::Format_RGB32) - , mDepth(32) - , mDpi{0} - , mFormFactor{mir_form_factor_unknown} - , mScale{1.0} - , mOutputId(0) - , mCursor(connection) -{ - setMirOutput(output); -} - -QMirClientScreen::~QMirClientScreen() -{ -} - -void QMirClientScreen::customEvent(QEvent* event) { - Q_ASSERT(QThread::currentThread() == thread()); - - OrientationChangeEvent* oReadingEvent = static_cast<OrientationChangeEvent*>(event); - switch (oReadingEvent->mOrientation) { - case OrientationChangeEvent::LeftUp: { - mCurrentOrientation = (screen()->primaryOrientation() == Qt::LandscapeOrientation) ? - Qt::InvertedPortraitOrientation : Qt::LandscapeOrientation; - break; - } - case OrientationChangeEvent::TopUp: { - mCurrentOrientation = (screen()->primaryOrientation() == Qt::LandscapeOrientation) ? - Qt::LandscapeOrientation : Qt::PortraitOrientation; - break; - } - case OrientationChangeEvent::RightUp: { - mCurrentOrientation = (screen()->primaryOrientation() == Qt::LandscapeOrientation) ? - Qt::PortraitOrientation : Qt::InvertedLandscapeOrientation; - break; - } - case OrientationChangeEvent::TopDown: { - mCurrentOrientation = (screen()->primaryOrientation() == Qt::LandscapeOrientation) ? - Qt::InvertedLandscapeOrientation : Qt::InvertedPortraitOrientation; - break; - } - } - - // Raise the event signal so that client apps know the orientation changed - qCDebug(mirclient, "QMirClientScreen::customEvent - handling orientation change to %s", orientationToStr(mCurrentOrientation)); - QWindowSystemInterface::handleScreenOrientationChange(screen(), mCurrentOrientation); -} - -void QMirClientScreen::handleWindowSurfaceResize(int windowWidth, int windowHeight) -{ - if ((windowWidth > windowHeight && mGeometry.width() < mGeometry.height()) - || (windowWidth < windowHeight && mGeometry.width() > mGeometry.height())) { - - // The window aspect ratio differ's from the screen one. This means that - // unity8 has rotated the window in its scene. - // As there's no way to express window rotation in Qt's API, we have - // Flip QScreen's dimensions so that orientation properties match - // (primaryOrientation particularly). - // FIXME: This assumes a phone scenario. Won't work, or make sense, - // on the desktop - - QRect currGeometry = mGeometry; - mGeometry.setWidth(currGeometry.height()); - mGeometry.setHeight(currGeometry.width()); - - qCDebug(mirclient, "QMirClientScreen::handleWindowSurfaceResize - new screen geometry (w=%d, h=%d)", - mGeometry.width(), mGeometry.height()); - QWindowSystemInterface::handleScreenGeometryChange(screen(), - mGeometry /* newGeometry */, - mGeometry /* newAvailableGeometry */); - - if (mGeometry.width() < mGeometry.height()) { - mCurrentOrientation = Qt::PortraitOrientation; - } else { - mCurrentOrientation = Qt::LandscapeOrientation; - } - qCDebug(mirclient, "QMirClientScreen::handleWindowSurfaceResize - new orientation %s",orientationToStr(mCurrentOrientation)); - QWindowSystemInterface::handleScreenOrientationChange(screen(), mCurrentOrientation); - } -} - -void QMirClientScreen::setMirOutput(const MirOutput *output) -{ - // Physical screen size (in mm) - mPhysicalSize.setWidth(mir_output_get_physical_width_mm(output)); - mPhysicalSize.setHeight(mir_output_get_physical_height_mm(output)); - - // Pixel Format -// mFormat = qImageFormatFromMirPixelFormat(mir_output_get_current_pixel_format(output)); // GERRY: TODO - - // Pixel depth - mDepth = 8 * MIR_BYTES_PER_PIXEL(mir_output_get_current_pixel_format(output)); - - // Mode = Resolution & refresh rate - const MirOutputMode *mode = mir_output_get_current_mode(output); - mNativeGeometry.setX(mir_output_get_position_x(output)); - mNativeGeometry.setY(mir_output_get_position_y(output)); - mNativeGeometry.setWidth(mir_output_mode_get_width(mode)); - mNativeGeometry.setHeight(mir_output_mode_get_height(mode)); - - mRefreshRate = mir_output_mode_get_refresh_rate(mode); - - // UI scale & DPR - mScale = mir_output_get_scale_factor(output); - if (overrideDevicePixelRatio > 0) { - mDevicePixelRatio = overrideDevicePixelRatio; - } else { - mDevicePixelRatio = 1.0; // FIXME - need to determine suitable DPR for the specified scale - } - - mFormFactor = mir_output_get_form_factor(output); - - mOutputId = mir_output_get_id(output); - - mGeometry.setX(mNativeGeometry.x()); - mGeometry.setY(mNativeGeometry.y()); - mGeometry.setWidth(mNativeGeometry.width()); - mGeometry.setHeight(mNativeGeometry.height()); - - // Set the default orientation based on the initial screen dimensions. - mNativeOrientation = (mGeometry.width() >= mGeometry.height()) ? Qt::LandscapeOrientation : Qt::PortraitOrientation; - - // If it's a landscape device (i.e. some tablets), start in landscape, otherwise portrait - mCurrentOrientation = (mNativeOrientation == Qt::LandscapeOrientation) ? Qt::LandscapeOrientation : Qt::PortraitOrientation; -} - -void QMirClientScreen::updateMirOutput(const MirOutput *output) -{ - auto oldRefreshRate = mRefreshRate; - auto oldScale = mScale; - auto oldFormFactor = mFormFactor; - auto oldGeometry = mGeometry; - - setMirOutput(output); - - // Emit change signals in particular order - if (oldGeometry != mGeometry) { - QWindowSystemInterface::handleScreenGeometryChange(screen(), - mGeometry /* newGeometry */, - mGeometry /* newAvailableGeometry */); - } - - if (!qFuzzyCompare(mRefreshRate, oldRefreshRate)) { - QWindowSystemInterface::handleScreenRefreshRateChange(screen(), mRefreshRate); - } - - auto nativeInterface = static_cast<QMirClientNativeInterface *>(qGuiApp->platformNativeInterface()); - if (!qFuzzyCompare(mScale, oldScale)) { - nativeInterface->screenPropertyChanged(this, QStringLiteral("scale")); - } - if (mFormFactor != oldFormFactor) { - nativeInterface->screenPropertyChanged(this, QStringLiteral("formFactor")); - } -} - -void QMirClientScreen::setAdditionalMirDisplayProperties(float scale, MirFormFactor formFactor, int dpi) -{ - if (mDpi != dpi) { - mDpi = dpi; - QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen(), dpi, dpi); - } - - auto nativeInterface = static_cast<QMirClientNativeInterface *>(qGuiApp->platformNativeInterface()); - if (!qFuzzyCompare(mScale, scale)) { - mScale = scale; - nativeInterface->screenPropertyChanged(this, QStringLiteral("scale")); - } - if (mFormFactor != formFactor) { - mFormFactor = formFactor; - nativeInterface->screenPropertyChanged(this, QStringLiteral("formFactor")); - } -} - -QDpi QMirClientScreen::logicalDpi() const -{ - if (mDpi > 0) { - return QDpi(mDpi, mDpi); - } else { - return QPlatformScreen::logicalDpi(); - } -} diff --git a/src/plugins/platforms/mirclient/qmirclientscreen.h b/src/plugins/platforms/mirclient/qmirclientscreen.h deleted file mode 100644 index b31cba1964..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientscreen.h +++ /dev/null @@ -1,106 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTSCREEN_H -#define QMIRCLIENTSCREEN_H - -#include <qpa/qplatformscreen.h> -#include <QSurfaceFormat> - -#include <mir_toolkit/common.h> // just for MirFormFactor enum - -#include "qmirclientcursor.h" - -struct MirConnection; -struct MirOutput; - -class QMirClientScreen : public QObject, public QPlatformScreen -{ - Q_OBJECT -public: - QMirClientScreen(const MirOutput *output, MirConnection *connection); - virtual ~QMirClientScreen(); - - // QPlatformScreen methods. - QImage::Format format() const override { return mFormat; } - int depth() const override { return mDepth; } - QRect geometry() const override { return mGeometry; } - QRect availableGeometry() const override { return mGeometry; } - QSizeF physicalSize() const override { return mPhysicalSize; } - qreal devicePixelRatio() const override { return mDevicePixelRatio; } - QDpi logicalDpi() const override; - Qt::ScreenOrientation nativeOrientation() const override { return mNativeOrientation; } - Qt::ScreenOrientation orientation() const override { return mNativeOrientation; } - QPlatformCursor *cursor() const override { return const_cast<QMirClientCursor*>(&mCursor); } - - // Additional Screen properties from Mir - int mirOutputId() const { return mOutputId; } - MirFormFactor formFactor() const { return mFormFactor; } - float scale() const { return mScale; } - - // Internally used methods - void updateMirOutput(const MirOutput *output); - void setAdditionalMirDisplayProperties(float scale, MirFormFactor formFactor, int dpi); - void handleWindowSurfaceResize(int width, int height); - - // QObject methods. - void customEvent(QEvent* event) override; - -private: - void setMirOutput(const MirOutput *output); - - QRect mGeometry, mNativeGeometry; - QSizeF mPhysicalSize; - qreal mDevicePixelRatio; - Qt::ScreenOrientation mNativeOrientation; - Qt::ScreenOrientation mCurrentOrientation; - QImage::Format mFormat; - int mDepth; - int mDpi; - qreal mRefreshRate; - MirFormFactor mFormFactor; - float mScale; - int mOutputId; - QMirClientCursor mCursor; - - friend class QMirClientNativeInterface; -}; - -#endif // QMIRCLIENTSCREEN_H diff --git a/src/plugins/platforms/mirclient/qmirclientscreenobserver.cpp b/src/plugins/platforms/mirclient/qmirclientscreenobserver.cpp deleted file mode 100644 index 792aeca351..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientscreenobserver.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "qmirclientscreenobserver.h" -#include "qmirclientscreen.h" -#include "qmirclientwindow.h" -#include "qmirclientlogging.h" - -// Qt -#include <QMetaObject> -#include <QPointer> - -// Mir -#include <mirclient/mir_toolkit/mir_connection.h> -#include <mirclient/mir_toolkit/mir_display_configuration.h> - -#include <memory> - -namespace { - static void displayConfigurationChangedCallback(MirConnection */*connection*/, void* context) - { - ASSERT(context != NULL); - QMirClientScreenObserver *observer = static_cast<QMirClientScreenObserver *>(context); - QMetaObject::invokeMethod(observer, "update"); - } - - const char *mirFormFactorToStr(MirFormFactor formFactor) - { - switch (formFactor) { - case mir_form_factor_unknown: return "unknown"; - case mir_form_factor_phone: return "phone"; - case mir_form_factor_tablet: return "tablet"; - case mir_form_factor_monitor: return "monitor"; - case mir_form_factor_tv: return "tv"; - case mir_form_factor_projector: return "projector"; - } - Q_UNREACHABLE(); - } -} // anonymous namespace - -QMirClientScreenObserver::QMirClientScreenObserver(MirConnection *mirConnection) - : mMirConnection(mirConnection) -{ - mir_connection_set_display_config_change_callback(mirConnection, ::displayConfigurationChangedCallback, this); - update(); -} - -void QMirClientScreenObserver::update() -{ - // Wrap MirDisplayConfiguration to always delete when out of scope - auto configDeleter = [](MirDisplayConfig *config) { mir_display_config_release(config); }; - using configUp = std::unique_ptr<MirDisplayConfig, decltype(configDeleter)>; - configUp displayConfig(mir_connection_create_display_configuration(mMirConnection), configDeleter); - - // Mir only tells us something changed, it is up to us to figure out what. - QList<QMirClientScreen*> newScreenList; - QList<QMirClientScreen*> oldScreenList = mScreenList; - mScreenList.clear(); - - for (int i = 0; i < mir_display_config_get_num_outputs(displayConfig.get()); i++) { - const MirOutput *output = mir_display_config_get_output(displayConfig.get(), i); - if (mir_output_is_enabled(output)) { - QMirClientScreen *screen = findScreenWithId(oldScreenList, mir_output_get_id(output)); - if (screen) { // we've already set up this display before - screen->updateMirOutput(output); - oldScreenList.removeAll(screen); - } else { - // new display, so create QMirClientScreen for it - screen = new QMirClientScreen(output, mMirConnection); - newScreenList.append(screen); - qCDebug(mirclient) << "Added Screen with id" << mir_output_get_id(output) - << "and geometry" << screen->geometry(); - } - mScreenList.append(screen); - } - } - - // Announce old & unused Screens, should be deleted by the slot - Q_FOREACH (const auto screen, oldScreenList) { - Q_EMIT screenRemoved(screen); - } - - /* - * Mir's MirDisplayOutput does not include formFactor or scale for some reason, but Qt - * will want that information on creating the QScreen. Only way we get that info is when - * Mir positions a Window on that Screen. See "handleScreenPropertiesChange" method - */ - - // Announce new Screens - Q_FOREACH (const auto screen, newScreenList) { - Q_EMIT screenAdded(screen); - } - - qCDebug(mirclient) << "======================================="; - for (auto screen: mScreenList) { - qCDebug(mirclient) << screen << "- id:" << screen->mirOutputId() - << "geometry:" << screen->geometry() - << "form factor:" << mirFormFactorToStr(screen->formFactor()) - << "scale:" << screen->scale(); - } - qCDebug(mirclient) << "======================================="; -} - -QMirClientScreen *QMirClientScreenObserver::findScreenWithId(int id) -{ - return findScreenWithId(mScreenList, id); -} - -QMirClientScreen *QMirClientScreenObserver::findScreenWithId(const QList<QMirClientScreen *> &list, int id) -{ - Q_FOREACH (const auto screen, list) { - if (screen->mirOutputId() == id) { - return screen; - } - } - return nullptr; -} - -void QMirClientScreenObserver::handleScreenPropertiesChange(QMirClientScreen *screen, int dpi, - MirFormFactor formFactor, float scale) -{ - screen->setAdditionalMirDisplayProperties(scale, formFactor, dpi); -} - diff --git a/src/plugins/platforms/mirclient/qmirclientscreenobserver.h b/src/plugins/platforms/mirclient/qmirclientscreenobserver.h deleted file mode 100644 index ad927319c1..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientscreenobserver.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTSCREENOBSERVER_H -#define QMIRCLIENTSCREENOBSERVER_H - -#include <QObject> - -#include <mir_toolkit/mir_connection.h> - -class QMirClientScreen; - -class QMirClientScreenObserver : public QObject -{ - Q_OBJECT - -public: - QMirClientScreenObserver(MirConnection *connection); - - QList<QMirClientScreen*> screens() const { return mScreenList; } - QMirClientScreen *findScreenWithId(int id); - - void handleScreenPropertiesChange(QMirClientScreen *screen, int dpi, - MirFormFactor formFactor, float scale); - -Q_SIGNALS: - void screenAdded(QMirClientScreen *screen); - void screenRemoved(QMirClientScreen *screen); - -private Q_SLOTS: - void update(); - -private: - QMirClientScreen *findScreenWithId(const QList<QMirClientScreen *> &list, int id); - void removeScreen(QMirClientScreen *screen); - - MirConnection *mMirConnection; - QList<QMirClientScreen*> mScreenList; -}; - -#endif // QMIRCLIENTSCREENOBSERVER_H diff --git a/src/plugins/platforms/mirclient/qmirclienttheme.cpp b/src/plugins/platforms/mirclient/qmirclienttheme.cpp deleted file mode 100644 index dcfef7ca67..0000000000 --- a/src/plugins/platforms/mirclient/qmirclienttheme.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "qmirclienttheme.h" - -#include <QtCore/QVariant> - -const char *QMirClientTheme::name = "ubuntu"; - -QMirClientTheme::QMirClientTheme() -{ -} - -QMirClientTheme::~QMirClientTheme() -{ -} - -QVariant QMirClientTheme::themeHint(ThemeHint hint) const -{ - if (hint == QPlatformTheme::SystemIconThemeName) { - QByteArray iconTheme = qgetenv("QTUBUNTU_ICON_THEME"); - if (iconTheme.isEmpty()) { - return QVariant(QStringLiteral("ubuntu-mobile")); - } else { - return QVariant(QString(iconTheme)); - } - } else { - return QGenericUnixTheme::themeHint(hint); - } -} diff --git a/src/plugins/platforms/mirclient/qmirclienttheme.h b/src/plugins/platforms/mirclient/qmirclienttheme.h deleted file mode 100644 index 4bab1d0ee0..0000000000 --- a/src/plugins/platforms/mirclient/qmirclienttheme.h +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTTHEME_H -#define QMIRCLIENTTHEME_H - -#include <QtThemeSupport/private/qgenericunixthemes_p.h> - -class QMirClientTheme : public QGenericUnixTheme -{ -public: - static const char* name; - QMirClientTheme(); - virtual ~QMirClientTheme(); - - // From QPlatformTheme - QVariant themeHint(ThemeHint hint) const override; -}; - -#endif // QMIRCLIENTTHEME_H diff --git a/src/plugins/platforms/mirclient/qmirclientwindow.cpp b/src/plugins/platforms/mirclient/qmirclientwindow.cpp deleted file mode 100644 index decd21516e..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientwindow.cpp +++ /dev/null @@ -1,968 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -// Local -#include "qmirclientwindow.h" -#include "qmirclientdebugextension.h" -#include "qmirclientnativeinterface.h" -#include "qmirclientinput.h" -#include "qmirclientintegration.h" -#include "qmirclientscreen.h" -#include "qmirclientlogging.h" - -#include <mir_toolkit/mir_client_library.h> -#include <mir_toolkit/version.h> - -// Qt -#include <qpa/qwindowsysteminterface.h> -#include <QMutexLocker> -#include <QSize> -#include <QtMath> -#include <QtEglSupport/private/qeglconvenience_p.h> - -// Platform API -#include <ubuntu/application/instance.h> - -#include <EGL/egl.h> - -Q_LOGGING_CATEGORY(mirclientBufferSwap, "qt.qpa.mirclient.bufferSwap", QtWarningMsg) - -namespace -{ -const Qt::WindowType LowChromeWindowHint = (Qt::WindowType)0x00800000; - -// FIXME: this used to be defined by platform-api, but it's been removed in v3. Change ubuntu-keyboard to use -// a different enum for window roles. -enum UAUiWindowRole { - U_MAIN_ROLE = 1, - U_DASH_ROLE, - U_INDICATOR_ROLE, - U_NOTIFICATIONS_ROLE, - U_GREETER_ROLE, - U_LAUNCHER_ROLE, - U_ON_SCREEN_KEYBOARD_ROLE, - U_SHUTDOWN_DIALOG_ROLE, -}; - -struct MirSpecDeleter -{ - void operator()(MirSurfaceSpec *spec) { mir_surface_spec_release(spec); } -}; - -using Spec = std::unique_ptr<MirSurfaceSpec, MirSpecDeleter>; - -EGLNativeWindowType nativeWindowFor(MirSurface *surf) -{ - auto stream = mir_surface_get_buffer_stream(surf); - return reinterpret_cast<EGLNativeWindowType>(mir_buffer_stream_get_egl_native_window(stream)); -} - -const char *qtWindowStateToStr(Qt::WindowState state) -{ - switch (state) { - case Qt::WindowNoState: - return "NoState"; - case Qt::WindowFullScreen: - return "FullScreen"; - case Qt::WindowMaximized: - return "Maximized"; - case Qt::WindowMinimized: - return "Minimized"; - case Qt::WindowActive: - return "Active"; - } - Q_UNREACHABLE(); -} - -const char *mirSurfaceStateToStr(MirSurfaceState surfaceState) -{ - switch (surfaceState) { - case mir_surface_state_unknown: return "unknown"; - case mir_surface_state_restored: return "restored"; - case mir_surface_state_minimized: return "minimized"; - case mir_surface_state_maximized: return "vertmaximized"; - case mir_surface_state_vertmaximized: return "vertmaximized"; - case mir_surface_state_fullscreen: return "fullscreen"; - case mir_surface_state_horizmaximized: return "horizmaximized"; - case mir_surface_state_hidden: return "hidden"; - case mir_surface_states: Q_UNREACHABLE(); - } - Q_UNREACHABLE(); -} - -const char *mirPixelFormatToStr(MirPixelFormat pixelFormat) -{ - switch (pixelFormat) { - case mir_pixel_format_invalid: return "invalid"; - case mir_pixel_format_abgr_8888: return "ABGR8888"; - case mir_pixel_format_xbgr_8888: return "XBGR8888"; - case mir_pixel_format_argb_8888: return "ARGB8888"; - case mir_pixel_format_xrgb_8888: return "XRGB8888"; - case mir_pixel_format_bgr_888: return "BGR888"; - case mir_pixel_format_rgb_888: return "RGB888"; - case mir_pixel_format_rgb_565: return "RGB565"; - case mir_pixel_format_rgba_5551: return "RGBA5551"; - case mir_pixel_format_rgba_4444: return "RGBA4444"; - case mir_pixel_formats: Q_UNREACHABLE(); - } - Q_UNREACHABLE(); -} - -const char *mirSurfaceTypeToStr(MirSurfaceType type) -{ - switch (type) { - case mir_surface_type_normal: return "Normal"; /**< AKA "regular" */ - case mir_surface_type_utility: return "Utility"; /**< AKA "floating regular" */ - case mir_surface_type_dialog: return "Dialog"; - case mir_surface_type_gloss: return "Gloss"; - case mir_surface_type_freestyle: return "Freestyle"; - case mir_surface_type_menu: return "Menu"; - case mir_surface_type_inputmethod: return "Input Method"; /**< AKA "OSK" or handwriting etc. */ - case mir_surface_type_satellite: return "Satellite"; /**< AKA "toolbox"/"toolbar" */ - case mir_surface_type_tip: return "Tip"; /**< AKA "tooltip" */ - case mir_surface_types: Q_UNREACHABLE(); - } - return ""; -} - -MirSurfaceState qtWindowStateToMirSurfaceState(Qt::WindowState state) -{ - switch (state) { - case Qt::WindowNoState: - case Qt::WindowActive: - return mir_surface_state_restored; - case Qt::WindowFullScreen: - return mir_surface_state_fullscreen; - case Qt::WindowMaximized: - return mir_surface_state_maximized; - case Qt::WindowMinimized: - return mir_surface_state_minimized; - } - return mir_surface_state_unknown; // should never be reached -} - -MirSurfaceType qtWindowTypeToMirSurfaceType(Qt::WindowType type) -{ - switch (type & Qt::WindowType_Mask) { - case Qt::Dialog: - return mir_surface_type_dialog; - case Qt::Sheet: - case Qt::Drawer: - return mir_surface_type_utility; - case Qt::Popup: - case Qt::Tool: - return mir_surface_type_menu; - case Qt::ToolTip: - return mir_surface_type_tip; - case Qt::SplashScreen: - return mir_surface_type_freestyle; - case Qt::Window: - default: - return mir_surface_type_normal; - } -} - -WId makeId() -{ - static int id = 1; - return id++; -} - -UAUiWindowRole roleFor(QWindow *window) -{ - QVariant roleVariant = window->property("role"); - if (!roleVariant.isValid()) - return U_MAIN_ROLE; - - uint role = roleVariant.toUInt(); - if (role < U_MAIN_ROLE || role > U_SHUTDOWN_DIALOG_ROLE) - return U_MAIN_ROLE; - - return static_cast<UAUiWindowRole>(role); -} - -QMirClientWindow *transientParentFor(QWindow *window) -{ - QWindow *parent = window->transientParent(); - return parent ? static_cast<QMirClientWindow *>(parent->handle()) : nullptr; -} - -bool requiresParent(const MirSurfaceType type) -{ - switch (type) { - case mir_surface_type_dialog: //FIXME - not quite what the specification dictates, but is what Mir's api dictates - case mir_surface_type_utility: - case mir_surface_type_gloss: - case mir_surface_type_menu: - case mir_surface_type_satellite: - case mir_surface_type_tip: - return true; - default: - return false; - } -} - -bool requiresParent(const Qt::WindowType type) -{ - return requiresParent(qtWindowTypeToMirSurfaceType(type)); -} - -bool isMovable(const Qt::WindowType type) -{ - auto mirType = qtWindowTypeToMirSurfaceType(type); - switch (mirType) { - case mir_surface_type_menu: - case mir_surface_type_tip: - return true; - default: - return false; - } -} - -Spec makeSurfaceSpec(QWindow *window, MirPixelFormat pixelFormat, QMirClientWindow *parentWindowHandle, - MirConnection *connection) -{ - const auto geometry = window->geometry(); - const int width = geometry.width() > 0 ? geometry.width() : 1; - const int height = geometry.height() > 0 ? geometry.height() : 1; - auto type = qtWindowTypeToMirSurfaceType(window->type()); - - if (U_ON_SCREEN_KEYBOARD_ROLE == roleFor(window)) { - type = mir_surface_type_inputmethod; - } - - MirRectangle location{geometry.x(), geometry.y(), 0, 0}; - MirSurface *parent = nullptr; - if (parentWindowHandle) { - parent = parentWindowHandle->mirSurface(); - // Qt uses absolute positioning, but Mir positions surfaces relative to parent. - location.top -= parentWindowHandle->geometry().top(); - location.left -= parentWindowHandle->geometry().left(); - } - - Spec spec; - - switch (type) { - case mir_surface_type_menu: - spec = Spec{mir_connection_create_spec_for_menu(connection, width, height, pixelFormat, parent, - &location, mir_edge_attachment_any)}; - break; - case mir_surface_type_dialog: - spec = Spec{mir_connection_create_spec_for_modal_dialog(connection, width, height, pixelFormat, parent)}; - break; - case mir_surface_type_utility: - spec = Spec{mir_connection_create_spec_for_dialog(connection, width, height, pixelFormat)}; - break; - case mir_surface_type_tip: -#if MIR_CLIENT_VERSION < MIR_VERSION_NUMBER(3, 4, 0) - spec = Spec{mir_connection_create_spec_for_tooltip(connection, width, height, pixelFormat, parent, - &location)}; -#else - spec = Spec{mir_connection_create_spec_for_tip(connection, width, height, pixelFormat, parent, - &location, mir_edge_attachment_any)}; -#endif - break; - case mir_surface_type_inputmethod: - spec = Spec{mir_connection_create_spec_for_input_method(connection, width, height, pixelFormat)}; - break; - default: - spec = Spec{mir_connection_create_spec_for_normal_surface(connection, width, height, pixelFormat)}; - break; - } - - qCDebug(mirclient, "makeSurfaceSpec(window=%p): %s spec (type=0x%x, position=(%d, %d)px, size=(%dx%d)px)", - window, mirSurfaceTypeToStr(type), window->type(), location.left, location.top, width, height); - - return std::move(spec); -} - -void setSizingConstraints(MirSurfaceSpec *spec, const QSize& minSize, const QSize& maxSize, const QSize& increment) -{ - mir_surface_spec_set_min_width(spec, minSize.width()); - mir_surface_spec_set_min_height(spec, minSize.height()); - if (maxSize.width() >= minSize.width()) { - mir_surface_spec_set_max_width(spec, maxSize.width()); - } - if (maxSize.height() >= minSize.height()) { - mir_surface_spec_set_max_height(spec, maxSize.height()); - } - if (increment.width() > 0) { - mir_surface_spec_set_width_increment(spec, increment.width()); - } - if (increment.height() > 0) { - mir_surface_spec_set_height_increment(spec, increment.height()); - } -} - -MirSurface *createMirSurface(QWindow *window, int mirOutputId, QMirClientWindow *parentWindowHandle, - MirPixelFormat pixelFormat, MirConnection *connection, - mir_surface_event_callback inputCallback, void *inputContext) -{ - auto spec = makeSurfaceSpec(window, pixelFormat, parentWindowHandle, connection); - - // Install event handler as early as possible - mir_surface_spec_set_event_handler(spec.get(), inputCallback, inputContext); - - const auto title = window->title().toUtf8(); - mir_surface_spec_set_name(spec.get(), title.constData()); - - setSizingConstraints(spec.get(), window->minimumSize(), window->maximumSize(), window->sizeIncrement()); - - if (window->windowState() == Qt::WindowFullScreen) { - mir_surface_spec_set_fullscreen_on_output(spec.get(), mirOutputId); - } - - if (window->flags() & LowChromeWindowHint) { - mir_surface_spec_set_shell_chrome(spec.get(), mir_shell_chrome_low); - } - - if (!window->isVisible()) { - mir_surface_spec_set_state(spec.get(), mir_surface_state_hidden); - } - - auto surface = mir_surface_create_sync(spec.get()); - Q_ASSERT(mir_surface_is_valid(surface)); - return surface; -} - -QMirClientWindow *getParentIfNecessary(QWindow *window, QMirClientInput *input) -{ - QMirClientWindow *parentWindowHandle = nullptr; - if (requiresParent(window->type())) { - parentWindowHandle = transientParentFor(window); - if (parentWindowHandle == nullptr) { - // NOTE: Mir requires this surface have a parent. Try using the last surface to receive input as that will - // most likely be the one that caused this surface to be created - parentWindowHandle = input->lastInputWindow(); - } - } - return parentWindowHandle; -} - -MirPixelFormat disableAlphaBufferIfPossible(MirPixelFormat pixelFormat) -{ - switch (pixelFormat) { - case mir_pixel_format_abgr_8888: - return mir_pixel_format_xbgr_8888; - case mir_pixel_format_argb_8888: - return mir_pixel_format_xrgb_8888; - default: // can do nothing, leave it alone - return pixelFormat; - } -} -} //namespace - - - -class UbuntuSurface -{ -public: - UbuntuSurface(QMirClientWindow *platformWindow, EGLDisplay display, QMirClientInput *input, MirConnection *connection); - ~UbuntuSurface(); - - UbuntuSurface(const UbuntuSurface &) = delete; - UbuntuSurface& operator=(const UbuntuSurface &) = delete; - - void updateGeometry(const QRect &newGeometry); - void updateTitle(const QString& title); - void setSizingConstraints(const QSize& minSize, const QSize& maxSize, const QSize& increment); - - void onSwapBuffersDone(); - void handleSurfaceResized(int width, int height); - int needsRepaint() const; - - MirSurfaceState state() const { return mir_surface_get_state(mMirSurface); } - void setState(MirSurfaceState state); - - MirSurfaceType type() const { return mir_surface_get_type(mMirSurface); } - - void setShellChrome(MirShellChrome shellChrome); - - EGLSurface eglSurface() const { return mEglSurface; } - MirSurface *mirSurface() const { return mMirSurface; } - - void setSurfaceParent(MirSurface*); - bool hasParent() const { return mParented; } - - QSurfaceFormat format() const { return mFormat; } - - bool mNeedsExposeCatchup; - - QString persistentSurfaceId(); - -private: - static void surfaceEventCallback(MirSurface* surface, const MirEvent *event, void* context); - void postEvent(const MirEvent *event); - - QWindow * const mWindow; - QMirClientWindow * const mPlatformWindow; - QMirClientInput * const mInput; - MirConnection * const mConnection; - QMirClientWindow * mParentWindowHandle{nullptr}; - - MirSurface* mMirSurface; - const EGLDisplay mEglDisplay; - EGLSurface mEglSurface; - - bool mNeedsRepaint; - bool mParented; - QSize mBufferSize; - QSurfaceFormat mFormat; - MirPixelFormat mPixelFormat; - - QMutex mTargetSizeMutex; - QSize mTargetSize; - MirShellChrome mShellChrome; - QString mPersistentIdStr; -}; - -UbuntuSurface::UbuntuSurface(QMirClientWindow *platformWindow, EGLDisplay display, QMirClientInput *input, MirConnection *connection) - : mWindow(platformWindow->window()) - , mPlatformWindow(platformWindow) - , mInput(input) - , mConnection(connection) - , mEglDisplay(display) - , mNeedsRepaint(false) - , mParented(mWindow->transientParent() || mWindow->parent()) - , mFormat(mWindow->requestedFormat()) - , mShellChrome(mWindow->flags() & LowChromeWindowHint ? mir_shell_chrome_low : mir_shell_chrome_normal) -{ - // Have Qt choose most suitable EGLConfig for the requested surface format, and update format to reflect it - EGLConfig config = q_configFromGLFormat(display, mFormat, true); - if (config == 0) { - // Older Intel Atom-based devices only support OpenGL 1.4 compatibility profile but by default - // QML asks for at least OpenGL 2.0. The XCB GLX backend ignores this request and returns a - // 1.4 context, but the XCB EGL backend tries to honor it, and fails. The 1.4 context appears to - // have sufficient capabilities on MESA (i915) to render correctly however. So reduce the default - // requested OpenGL version to 1.0 to ensure EGL will give us a working context (lp:1549455). - static const bool isMesa = QString(eglQueryString(display, EGL_VENDOR)).contains(QStringLiteral("Mesa")); - if (isMesa) { - qCDebug(mirclientGraphics, "Attempting to choose OpenGL 1.4 context which may suit Mesa"); - mFormat.setMajorVersion(1); - mFormat.setMinorVersion(4); - config = q_configFromGLFormat(display, mFormat, true); - } - } - if (config == 0) { - qCritical() << "Qt failed to choose a suitable EGLConfig to suit the surface format" << mFormat; - } - - mFormat = q_glFormatFromConfig(display, config, mFormat); - - // Have Mir decide the pixel format most suited to the chosen EGLConfig. This is the only way - // Mir will know what EGLConfig has been chosen - it cannot deduce it from the buffers. - mPixelFormat = mir_connection_get_egl_pixel_format(connection, display, config); - // But the chosen EGLConfig might have an alpha buffer enabled, even if not requested by the client. - // If that's the case, try to edit the chosen pixel format in order to disable the alpha buffer. - // This is an optimization for the compositor, as it can avoid blending this surface. - if (mWindow->requestedFormat().alphaBufferSize() < 0) { - mPixelFormat = disableAlphaBufferIfPossible(mPixelFormat); - } - - const auto outputId = static_cast<QMirClientScreen *>(mWindow->screen()->handle())->mirOutputId(); - - mParentWindowHandle = getParentIfNecessary(mWindow, input); - - mMirSurface = createMirSurface(mWindow, outputId, mParentWindowHandle, mPixelFormat, connection, surfaceEventCallback, this); - mEglSurface = eglCreateWindowSurface(mEglDisplay, config, nativeWindowFor(mMirSurface), nullptr); - - mNeedsExposeCatchup = mir_surface_get_visibility(mMirSurface) == mir_surface_visibility_occluded; - - // Window manager can give us a final size different from what we asked for - // so let's check what we ended up getting - MirSurfaceParameters parameters; - mir_surface_get_parameters(mMirSurface, ¶meters); - - auto geom = mWindow->geometry(); - geom.setWidth(parameters.width); - geom.setHeight(parameters.height); - - // Assume that the buffer size matches the surface size at creation time - mBufferSize = geom.size(); - QWindowSystemInterface::handleGeometryChange(mWindow, geom); - - qCDebug(mirclient) << "Created surface with geometry:" << geom << "title:" << mWindow->title() - << "role:" << roleFor(mWindow); - qCDebug(mirclientGraphics) - << "Requested format:" << mWindow->requestedFormat() - << "\nActual format:" << mFormat - << "with associated Mir pixel format:" << mirPixelFormatToStr(mPixelFormat); -} - -UbuntuSurface::~UbuntuSurface() -{ - if (mEglSurface != EGL_NO_SURFACE) - eglDestroySurface(mEglDisplay, mEglSurface); - if (mMirSurface) { - mir_surface_release_sync(mMirSurface); - } -} - -void UbuntuSurface::updateGeometry(const QRect &newGeometry) -{ - qCDebug(mirclient,"updateGeometry(window=%p, width=%d, height=%d)", mWindow, - newGeometry.width(), newGeometry.height()); - - Spec spec; - if (isMovable(mWindow->type())) { - spec = Spec{makeSurfaceSpec(mWindow, mPixelFormat, mParentWindowHandle, mConnection)}; - } else { - spec = Spec{mir_connection_create_spec_for_changes(mConnection)}; - mir_surface_spec_set_width(spec.get(), newGeometry.width()); - mir_surface_spec_set_height(spec.get(), newGeometry.height()); - } - mir_surface_apply_spec(mMirSurface, spec.get()); -} - -void UbuntuSurface::updateTitle(const QString& newTitle) -{ - const auto title = newTitle.toUtf8(); - Spec spec{mir_connection_create_spec_for_changes(mConnection)}; - mir_surface_spec_set_name(spec.get(), title.constData()); - mir_surface_apply_spec(mMirSurface, spec.get()); -} - -void UbuntuSurface::setSizingConstraints(const QSize& minSize, const QSize& maxSize, const QSize& increment) -{ - Spec spec{mir_connection_create_spec_for_changes(mConnection)}; - ::setSizingConstraints(spec.get(), minSize, maxSize, increment); - mir_surface_apply_spec(mMirSurface, spec.get()); -} - -void UbuntuSurface::handleSurfaceResized(int width, int height) -{ - QMutexLocker lock(&mTargetSizeMutex); - - // mir's resize event is mainly a signal that we need to redraw our content. We use the - // width/height as identifiers to figure out if this is the latest surface resize event - // that has posted, discarding any old ones. This avoids issuing too many redraw events. - // see TODO in postEvent as the ideal way we should handle this. - // The actual buffer size may or may have not changed at this point, so let the rendering - // thread drive the window geometry updates. - mNeedsRepaint = mTargetSize.width() == width && mTargetSize.height() == height; -} - -int UbuntuSurface::needsRepaint() const -{ - if (mNeedsRepaint) { - if (mTargetSize != mBufferSize) { - //If the buffer hasn't changed yet, we need at least two redraws, - //once to get the new buffer size and propagate the geometry changes - //and the second to redraw the content at the new size - return 2; - } else { - // The buffer size has already been updated so we only need one redraw - // to render at the new size - return 1; - } - } - return 0; -} - -void UbuntuSurface::setState(MirSurfaceState state) -{ - mir_wait_for(mir_surface_set_state(mMirSurface, state)); -} - -void UbuntuSurface::setShellChrome(MirShellChrome chrome) -{ - if (chrome != mShellChrome) { - auto spec = Spec{mir_connection_create_spec_for_changes(mConnection)}; - mir_surface_spec_set_shell_chrome(spec.get(), chrome); - mir_surface_apply_spec(mMirSurface, spec.get()); - - mShellChrome = chrome; - } -} - -void UbuntuSurface::onSwapBuffersDone() -{ - static int sFrameNumber = 0; - ++sFrameNumber; - - EGLint eglSurfaceWidth = -1; - EGLint eglSurfaceHeight = -1; - eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &eglSurfaceWidth); - eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &eglSurfaceHeight); - - const bool validSize = eglSurfaceWidth > 0 && eglSurfaceHeight > 0; - - if (validSize && (mBufferSize.width() != eglSurfaceWidth || mBufferSize.height() != eglSurfaceHeight)) { - - qCDebug(mirclientBufferSwap, "onSwapBuffersDone(window=%p) [%d] - size changed (%d, %d) => (%d, %d)", - mWindow, sFrameNumber, mBufferSize.width(), mBufferSize.height(), eglSurfaceWidth, eglSurfaceHeight); - - mBufferSize.rwidth() = eglSurfaceWidth; - mBufferSize.rheight() = eglSurfaceHeight; - - QRect newGeometry = mPlatformWindow->geometry(); - newGeometry.setSize(mBufferSize); - - QWindowSystemInterface::handleGeometryChange(mWindow, newGeometry); - } else { - qCDebug(mirclientBufferSwap, "onSwapBuffersDone(window=%p) [%d] - buffer size (%d,%d)", - mWindow, sFrameNumber, mBufferSize.width(), mBufferSize.height()); - } -} - -void UbuntuSurface::surfaceEventCallback(MirSurface *surface, const MirEvent *event, void* context) -{ - Q_UNUSED(surface); - Q_ASSERT(context != nullptr); - - auto s = static_cast<UbuntuSurface *>(context); - s->postEvent(event); -} - -void UbuntuSurface::postEvent(const MirEvent *event) -{ - if (mir_event_type_resize == mir_event_get_type(event)) { - // TODO: The current event queue just accumulates all resize events; - // It would be nicer if we could update just one event if that event has not been dispatched. - // As a workaround, we use the width/height as an identifier of this latest event - // so the event handler (handleSurfaceResized) can discard/ignore old ones. - const auto resizeEvent = mir_event_get_resize_event(event); - const auto width = mir_resize_event_get_width(resizeEvent); - const auto height = mir_resize_event_get_height(resizeEvent); - qCDebug(mirclient, "resizeEvent(window=%p, width=%d, height=%d)", mWindow, width, height); - - QMutexLocker lock(&mTargetSizeMutex); - mTargetSize.rwidth() = width; - mTargetSize.rheight() = height; - } - - mInput->postEvent(mPlatformWindow, event); -} - -void UbuntuSurface::setSurfaceParent(MirSurface* parent) -{ - qCDebug(mirclient, "setSurfaceParent(window=%p)", mWindow); - - mParented = true; - Spec spec{mir_connection_create_spec_for_changes(mConnection)}; - mir_surface_spec_set_parent(spec.get(), parent); - mir_surface_apply_spec(mMirSurface, spec.get()); -} - -QString UbuntuSurface::persistentSurfaceId() -{ - if (mPersistentIdStr.isEmpty()) { - MirPersistentId* mirPermaId = mir_surface_request_persistent_id_sync(mMirSurface); - mPersistentIdStr = mir_persistent_id_as_string(mirPermaId); - mir_persistent_id_release(mirPermaId); - } - return mPersistentIdStr; -} - -QMirClientWindow::QMirClientWindow(QWindow *w, QMirClientInput *input, QMirClientNativeInterface *native, - QMirClientAppStateController *appState, EGLDisplay eglDisplay, - MirConnection *mirConnection, QMirClientDebugExtension *debugExt) - : QObject(nullptr) - , QPlatformWindow(w) - , mId(makeId()) - , mWindowState(w->windowState()) - , mWindowFlags(w->flags()) - , mWindowVisible(false) - , mAppStateController(appState) - , mDebugExtention(debugExt) - , mNativeInterface(native) - , mSurface(new UbuntuSurface{this, eglDisplay, input, mirConnection}) - , mScale(1.0) - , mFormFactor(mir_form_factor_unknown) -{ - mWindowExposed = mSurface->mNeedsExposeCatchup == false; - - qCDebug(mirclient, "QMirClientWindow(window=%p, screen=%p, input=%p, surf=%p) with title '%s', role: '%d'", - w, w->screen()->handle(), input, mSurface.get(), qPrintable(window()->title()), roleFor(window())); -} - -QMirClientWindow::~QMirClientWindow() -{ - qCDebug(mirclient, "~QMirClientWindow(window=%p)", this); -} - -void QMirClientWindow::handleSurfaceResized(int width, int height) -{ - QMutexLocker lock(&mMutex); - qCDebug(mirclient, "handleSurfaceResize(window=%p, size=(%dx%d)px", window(), width, height); - - mSurface->handleSurfaceResized(width, height); - - // This resize event could have occurred just after the last buffer swap for this window. - // This means the client may still be holding a buffer with the older size. The first redraw call - // will then render at the old size. After swapping the client now will get a new buffer with the - // updated size but it still needs re-rendering so another redraw may be needed. - // A mir API to drop the currently held buffer would help here, so that we wouldn't have to redraw twice - auto const numRepaints = mSurface->needsRepaint(); - lock.unlock(); - qCDebug(mirclient, "handleSurfaceResize(window=%p) redraw %d times", window(), numRepaints); - for (int i = 0; i < numRepaints; i++) { - qCDebug(mirclient, "handleSurfaceResize(window=%p) repainting size=(%dx%d)dp", window(), geometry().size().width(), geometry().size().height()); - QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); - } -} - -void QMirClientWindow::handleSurfaceExposeChange(bool exposed) -{ - QMutexLocker lock(&mMutex); - qCDebug(mirclient, "handleSurfaceExposeChange(window=%p, exposed=%s)", window(), exposed ? "true" : "false"); - - mSurface->mNeedsExposeCatchup = false; - if (mWindowExposed == exposed) return; - mWindowExposed = exposed; - - lock.unlock(); - QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); -} - -void QMirClientWindow::handleSurfaceFocusChanged(bool focused) -{ - qCDebug(mirclient, "handleSurfaceFocusChanged(window=%p, focused=%d)", window(), focused); - if (focused) { - mAppStateController->setWindowFocused(true); - QWindowSystemInterface::handleWindowActivated(window(), Qt::ActiveWindowFocusReason); - } else { - mAppStateController->setWindowFocused(false); - } -} - -void QMirClientWindow::handleSurfaceVisibilityChanged(bool visible) -{ - qCDebug(mirclient, "handleSurfaceVisibilityChanged(window=%p, visible=%d)", window(), visible); - - if (mWindowVisible == visible) return; - mWindowVisible = visible; - - QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); -} - -void QMirClientWindow::handleSurfaceStateChanged(Qt::WindowState state) -{ - qCDebug(mirclient, "handleSurfaceStateChanged(window=%p, %s)", window(), qtWindowStateToStr(state)); - - if (mWindowState == state) return; - mWindowState = state; - - QWindowSystemInterface::handleWindowStateChanged(window(), state); -} - -void QMirClientWindow::setWindowState(Qt::WindowStates states) -{ - Qt::WindowState state = Qt::WindowNoState; - if (states & Qt::WindowMinimized) - state = Qt::WindowMinimized; - else if (states & Qt::WindowFullScreen) - state = Qt::WindowFullScreen; - else if (states & Qt::WindowMaximized) - state = Qt::WindowMaximized; - - QMutexLocker lock(&mMutex); - qCDebug(mirclient, "setWindowState(window=%p, %s)", this, qtWindowStateToStr(state)); - - if (mWindowState == state) return; - mWindowState = state; - - lock.unlock(); - updateSurfaceState(); -} - -void QMirClientWindow::setWindowFlags(Qt::WindowFlags flags) -{ - QMutexLocker lock(&mMutex); - qCDebug(mirclient, "setWindowFlags(window=%p, 0x%x)", this, (int)flags); - - if (mWindowFlags == flags) return; - mWindowFlags = flags; - - mSurface->setShellChrome(mWindowFlags & LowChromeWindowHint ? mir_shell_chrome_low : mir_shell_chrome_normal); -} - -QRect QMirClientWindow::geometry() const -{ - if (mDebugExtention) { - auto geom = QPlatformWindow::geometry(); - geom.moveTopLeft(mDebugExtention->mapSurfacePointToScreen(mSurface->mirSurface(), QPoint(0,0))); - return geom; - } else { - return QPlatformWindow::geometry(); - } -} - -void QMirClientWindow::setGeometry(const QRect& rect) -{ - QMutexLocker lock(&mMutex); - - if (window()->windowState() == Qt::WindowFullScreen || window()->windowState() == Qt::WindowMaximized) { - qCDebug(mirclient, "setGeometry(window=%p) - not resizing, window is maximized or fullscreen", window()); - return; - } - - qCDebug(mirclient, "setGeometry (window=%p, position=(%d, %d)dp, size=(%dx%d)dp)", - window(), rect.x(), rect.y(), rect.width(), rect.height()); - // Immediately update internal geometry so Qt believes position updated - QRect newPosition(geometry()); - newPosition.moveTo(rect.topLeft()); - QPlatformWindow::setGeometry(newPosition); - - mSurface->updateGeometry(rect); - // Note: don't call handleGeometryChange here, wait to see what Mir replies with. -} - -void QMirClientWindow::setVisible(bool visible) -{ - QMutexLocker lock(&mMutex); - qCDebug(mirclient, "setVisible (window=%p, visible=%s)", window(), visible ? "true" : "false"); - - if (mWindowVisible == visible) return; - mWindowVisible = visible; - - if (visible) { - if (!mSurface->hasParent() && window()->type() == Qt::Dialog) { - // The dialog may have been parented after creation time - // so morph it into a modal dialog - auto parent = transientParentFor(window()); - if (parent) { - mSurface->setSurfaceParent(parent->mirSurface()); - } - } - } - - lock.unlock(); - updateSurfaceState(); - QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); -} - -void QMirClientWindow::setWindowTitle(const QString& title) -{ - QMutexLocker lock(&mMutex); - qCDebug(mirclient, "setWindowTitle(window=%p) title=%s)", window(), title.toUtf8().constData()); - mSurface->updateTitle(title); -} - -void QMirClientWindow::propagateSizeHints() -{ - QMutexLocker lock(&mMutex); - const auto win = window(); - qCDebug(mirclient, "propagateSizeHints(window=%p) min(%d,%d), max(%d,%d) increment(%d, %d)", - win, win->minimumSize().width(), win->minimumSize().height(), - win->maximumSize().width(), win->maximumSize().height(), - win->sizeIncrement().width(), win->sizeIncrement().height()); - mSurface->setSizingConstraints(win->minimumSize(), win->maximumSize(), win->sizeIncrement()); -} - -bool QMirClientWindow::isExposed() const -{ - // mNeedsExposeCatchup because we need to render a frame to get the expose surface event from mir. - return mWindowVisible && (mWindowExposed || (mSurface && mSurface->mNeedsExposeCatchup)); -} - -QSurfaceFormat QMirClientWindow::format() const -{ - return mSurface->format(); -} - -QPoint QMirClientWindow::mapToGlobal(const QPoint &pos) const -{ - if (mDebugExtention) { - return mDebugExtention->mapSurfacePointToScreen(mSurface->mirSurface(), pos); - } else { - return pos; - } -} - -void* QMirClientWindow::eglSurface() const -{ - return mSurface->eglSurface(); -} - -MirSurface *QMirClientWindow::mirSurface() const -{ - return mSurface->mirSurface(); -} - -WId QMirClientWindow::winId() const -{ - return mId; -} - -void QMirClientWindow::onSwapBuffersDone() -{ - QMutexLocker lock(&mMutex); - mSurface->onSwapBuffersDone(); - - if (mSurface->mNeedsExposeCatchup) { - mSurface->mNeedsExposeCatchup = false; - mWindowExposed = false; - - lock.unlock(); - QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size())); - } -} - -void QMirClientWindow::handleScreenPropertiesChange(MirFormFactor formFactor, float scale) -{ - // Update the scale & form factor native-interface properties for the windows affected - // as there is no convenient way to emit signals for those custom properties on a QScreen - if (formFactor != mFormFactor) { - mFormFactor = formFactor; - Q_EMIT mNativeInterface->windowPropertyChanged(this, QStringLiteral("formFactor")); - } - - if (!qFuzzyCompare(scale, mScale)) { - mScale = scale; - Q_EMIT mNativeInterface->windowPropertyChanged(this, QStringLiteral("scale")); - } -} - -void QMirClientWindow::updateSurfaceState() -{ - QMutexLocker lock(&mMutex); - MirSurfaceState newState = mWindowVisible ? qtWindowStateToMirSurfaceState(mWindowState) : - mir_surface_state_hidden; - qCDebug(mirclient, "updateSurfaceState (window=%p, surfaceState=%s)", window(), mirSurfaceStateToStr(newState)); - if (newState != mSurface->state()) { - mSurface->setState(newState); - } -} - -QString QMirClientWindow::persistentSurfaceId() -{ - return mSurface->persistentSurfaceId(); -} diff --git a/src/plugins/platforms/mirclient/qmirclientwindow.h b/src/plugins/platforms/mirclient/qmirclientwindow.h deleted file mode 100644 index 6c5695d62f..0000000000 --- a/src/plugins/platforms/mirclient/qmirclientwindow.h +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014-2016 Canonical, Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QMIRCLIENTWINDOW_H -#define QMIRCLIENTWINDOW_H - -#include <qpa/qplatformwindow.h> -#include <QSharedPointer> -#include <QMutex> - -#include <mir_toolkit/common.h> // needed only for MirFormFactor enum - -#include <memory> - -#include <EGL/egl.h> - -class QMirClientAppStateController; -class QMirClientDebugExtension; -class QMirClientNativeInterface; -class QMirClientInput; -class QMirClientScreen; -class UbuntuSurface; -struct MirSurface; -class MirConnection; - -class QMirClientWindow : public QObject, public QPlatformWindow -{ - Q_OBJECT -public: - QMirClientWindow(QWindow *w, QMirClientInput *input, QMirClientNativeInterface* native, - QMirClientAppStateController *appState, EGLDisplay eglDisplay, - MirConnection *mirConnection, QMirClientDebugExtension *debugExt); - virtual ~QMirClientWindow(); - - // QPlatformWindow methods. - WId winId() const override; - QRect geometry() const override; - void setGeometry(const QRect&) override; - void setWindowState(Qt::WindowStates state) override; - void setWindowFlags(Qt::WindowFlags flags) override; - void setVisible(bool visible) override; - void setWindowTitle(const QString &title) override; - void propagateSizeHints() override; - bool isExposed() const override; - - QPoint mapToGlobal(const QPoint &pos) const override; - QSurfaceFormat format() const override; - - // Additional Window properties exposed by NativeInterface - MirFormFactor formFactor() const { return mFormFactor; } - float scale() const { return mScale; } - - // New methods. - void *eglSurface() const; - MirSurface *mirSurface() const; - void handleSurfaceResized(int width, int height); - void handleSurfaceExposeChange(bool exposed); - void handleSurfaceFocusChanged(bool focused); - void handleSurfaceVisibilityChanged(bool visible); - void handleSurfaceStateChanged(Qt::WindowState state); - void onSwapBuffersDone(); - void handleScreenPropertiesChange(MirFormFactor formFactor, float scale); - QString persistentSurfaceId(); - -private: - void updateSurfaceState(); - mutable QMutex mMutex; - const WId mId; - Qt::WindowState mWindowState; - Qt::WindowFlags mWindowFlags; - bool mWindowVisible; - bool mWindowExposed; - QMirClientAppStateController *mAppStateController; - QMirClientDebugExtension *mDebugExtention; - QMirClientNativeInterface *mNativeInterface; - std::unique_ptr<UbuntuSurface> mSurface; - float mScale; - MirFormFactor mFormFactor; -}; - -#endif // QMIRCLIENTWINDOW_H diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro index acc55adf6f..c4f2b30965 100644 --- a/src/plugins/platforms/platforms.pro +++ b/src/plugins/platforms/platforms.pro @@ -48,6 +48,4 @@ haiku { wasm: SUBDIRS += wasm -qtConfig(mirclient): SUBDIRS += mirclient - qtConfig(integrityfb): SUBDIRS += integrity From e3f16e7a42893447631321b02a2468c3b1fa35fb Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov <timur.pocheptsov@qt.io> Date: Fri, 1 Feb 2019 13:37:33 +0100 Subject: [PATCH 1111/1650] Convert tst_qabstractnetwork auto-test to make it work with our new docker-based test server. Change-Id: I76345a2d3d768b8a571f2c85e69f6a21e9a96d7e Reviewed-by: Ryan Chu <ryan.chu@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> --- .../qabstractnetworkcache/qabstractnetworkcache.pro | 2 ++ .../tst_qabstractnetworkcache.cpp | 7 ++++++- .../cgi-bin/httpcachetest_cachecontrol-expire.cgi | 7 +++++++ .../www/cgi-bin/httpcachetest_cachecontrol.cgi | 13 +++++++++++++ .../www/cgi-bin/httpcachetest_cachecontrol200.cgi | 9 +++++++++ .../testdata/www/cgi-bin/httpcachetest_etag200.cgi | 5 +++++ .../testdata/www/cgi-bin/httpcachetest_etag304.cgi | 11 +++++++++++ .../www/cgi-bin/httpcachetest_expires200.cgi | 5 +++++ .../www/cgi-bin/httpcachetest_expires304.cgi | 11 +++++++++++ .../www/cgi-bin/httpcachetest_lastModified200.cgi | 5 +++++ .../www/cgi-bin/httpcachetest_lastModified304.cgi | 11 +++++++++++ 11 files changed, 85 insertions(+), 1 deletion(-) create mode 100755 tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_cachecontrol-expire.cgi create mode 100755 tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_cachecontrol.cgi create mode 100755 tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_cachecontrol200.cgi create mode 100755 tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_etag200.cgi create mode 100755 tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_etag304.cgi create mode 100755 tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_expires200.cgi create mode 100755 tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_expires304.cgi create mode 100755 tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_lastModified200.cgi create mode 100755 tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_lastModified304.cgi diff --git a/tests/auto/network/access/qabstractnetworkcache/qabstractnetworkcache.pro b/tests/auto/network/access/qabstractnetworkcache/qabstractnetworkcache.pro index 1874f001ab..bdd9d4eb7e 100644 --- a/tests/auto/network/access/qabstractnetworkcache/qabstractnetworkcache.pro +++ b/tests/auto/network/access/qabstractnetworkcache/qabstractnetworkcache.pro @@ -5,3 +5,5 @@ SOURCES += tst_qabstractnetworkcache.cpp TESTDATA += tests/* +QT_TEST_SERVER_LIST = apache2 +include($$dirname(_QMAKE_CONF_)/tests/auto/testserver.pri) diff --git a/tests/auto/network/access/qabstractnetworkcache/tst_qabstractnetworkcache.cpp b/tests/auto/network/access/qabstractnetworkcache/tst_qabstractnetworkcache.cpp index 0da42b8b87..92384e85bc 100644 --- a/tests/auto/network/access/qabstractnetworkcache/tst_qabstractnetworkcache.cpp +++ b/tests/auto/network/access/qabstractnetworkcache/tst_qabstractnetworkcache.cpp @@ -39,7 +39,7 @@ #include <algorithm> -#define TESTFILE QLatin1String("http://") + QtNetworkSettings::serverName() + QLatin1String("/qtest/cgi-bin/") +#define TESTFILE QLatin1String("http://") + QtNetworkSettings::httpServerName() + QLatin1String("/qtest/cgi-bin/") class tst_QAbstractNetworkCache : public QObject { @@ -127,8 +127,13 @@ Q_DECLARE_METATYPE(QNetworkRequest::CacheLoadControl) void tst_QAbstractNetworkCache::initTestCase() { +#if defined(QT_TEST_SERVER) + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::httpServerName(), 80)); +#else if (!QtNetworkSettings::verifyTestNetworkSettings()) QSKIP("No network test server available"); +#endif + #ifndef QT_NO_BEARERMANAGEMENT netConfMan = new QNetworkConfigurationManager(this); networkConfiguration = netConfMan->defaultConfiguration(); diff --git a/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_cachecontrol-expire.cgi b/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_cachecontrol-expire.cgi new file mode 100755 index 0000000000..7dc506fc1e --- /dev/null +++ b/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_cachecontrol-expire.cgi @@ -0,0 +1,7 @@ +#!/bin/bash +# cache control takes precedence over expires +echo "Cache-Control: max-age=-1" +echo "Expires: Mon, 30 Oct 2028 14:19:41 GMT" +echo "Content-type: text/html"; +echo "" +echo "Hello World!" diff --git a/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_cachecontrol.cgi b/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_cachecontrol.cgi new file mode 100755 index 0000000000..f2edfc161f --- /dev/null +++ b/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_cachecontrol.cgi @@ -0,0 +1,13 @@ +#!/bin/bash +if [ ! -z ${HTTP_IF_MODIFIED_SINCE} ] ; then + echo "Status: 304" + echo "" + exit; +fi + +cc=`echo "${QUERY_STRING}" | sed -e s/%20/\ /g` +echo "Cache-Control: $cc" +echo "Last-Modified: Sat, 31 Oct 1981 06:00:00 GMT" +echo "Content-type: text/html"; +echo "" +echo "Hello World!" diff --git a/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_cachecontrol200.cgi b/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_cachecontrol200.cgi new file mode 100755 index 0000000000..e44d5ed570 --- /dev/null +++ b/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_cachecontrol200.cgi @@ -0,0 +1,9 @@ +#!/bin/bash +cc=`echo "${QUERY_STRING}" | sed -e s/%20/\ /g` +echo "Status: 200" +echo "Cache-Control: $cc" +echo "Last-Modified: Sat, 31 Oct 1981 06:00:00 GMT" +echo "Content-type: text/html"; +echo "X-Script: $0" +echo "" +echo "Hello World!" diff --git a/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_etag200.cgi b/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_etag200.cgi new file mode 100755 index 0000000000..0966abfdd1 --- /dev/null +++ b/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_etag200.cgi @@ -0,0 +1,5 @@ +#!/bin/bash +echo "ETag: foo" +echo "Content-type: text/html"; +echo "" +echo "Hello World!" diff --git a/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_etag304.cgi b/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_etag304.cgi new file mode 100755 index 0000000000..91a4b922bd --- /dev/null +++ b/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_etag304.cgi @@ -0,0 +1,11 @@ +#!/bin/bash +if [ ! -z ${HTTP_IF_NONE_MATCH} ] ; then + echo "Status: 304" + echo "" + exit; +fi + +echo "ETag: foo" +echo "Content-type: text/html"; +echo "" +echo "Hello World!" diff --git a/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_expires200.cgi b/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_expires200.cgi new file mode 100755 index 0000000000..e18ebc86ad --- /dev/null +++ b/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_expires200.cgi @@ -0,0 +1,5 @@ +#!/bin/bash +echo "Expires: Sat, 31 Oct 1981 6:00:00 GMT" +echo "Content-type: text/html"; +echo "" +echo "Hello World!" diff --git a/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_expires304.cgi b/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_expires304.cgi new file mode 100755 index 0000000000..1c7de1cd77 --- /dev/null +++ b/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_expires304.cgi @@ -0,0 +1,11 @@ +#!/bin/bash +if [ ${HTTP_IF_MODIFIED_SINCE} == "Mon, 30 Oct 2028 14:19:41 GMT" ] ; then + echo "Status: 304" + echo "" + exit; +fi + +echo "Expires: Mon, 30 Oct 2028 14:19:41 GMT" +echo "Content-type: text/html"; +echo "" +echo "Hello World!" diff --git a/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_lastModified200.cgi b/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_lastModified200.cgi new file mode 100755 index 0000000000..5dc219b1e7 --- /dev/null +++ b/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_lastModified200.cgi @@ -0,0 +1,5 @@ +#!/bin/bash +echo "Last-Modified: Sat, 31 Oct 1981 6:00:00 GMT" +echo "Content-type: text/html"; +echo "" +echo "Hello World!" diff --git a/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_lastModified304.cgi b/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_lastModified304.cgi new file mode 100755 index 0000000000..bdf23bed2f --- /dev/null +++ b/tests/testserver/apache2/testdata/www/cgi-bin/httpcachetest_lastModified304.cgi @@ -0,0 +1,11 @@ +#!/bin/bash +if [ ${HTTP_IF_MODIFIED_SINCE} == "Sat, 31 Oct 1981 06:00:00 GMT" ] ; then + echo "Status: 304" + echo "" + exit; +fi + +echo "Last-Modified: Sat, 31 Oct 1981 06:00:00 GMT" +echo "Content-type: text/html"; +echo "" +echo "Hello World!" From ece341e2f3ef90204b209012b2099b8e599eee08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= <tor.arne.vestbo@qt.io> Date: Wed, 19 Dec 2018 18:14:59 +0100 Subject: [PATCH 1112/1650] Allow more fine grained control over QFont debug output With verbosity level 0, only the resolved properties are included in the debug output, which is useful when debugging font resolving. With verbosity level 1, the family, size, and weights are included, plus any resolved property that is different from the default value. Verbosity level 2, the QDebug default, has been kept unchanged, except removing quotes and spaces by adding nospace() and qPrintable. Verbosity level 3 includes all properties, regardless of whether or not they have been resolved. Levels 1 and 3 also include the resolve mask, to aid debugging. This gives the following results for a QFont set to 100pt: QFont(100pt) QFont(".SF NS Text", 100pt, Weight::Normal, resolveMask=SizeResolved) QFont(.SF NS Text,100,-1,5,50,0,0,0,0,0) QFont(".SF NS Text", 100pt, StyleHint::AnyStyle, StyleStrategy::PreferDefault, Weight::Normal, StyleNormal, underline=false, overline=false, strikeOut=false, fixedPitch=false, AnyStretch, kerning=true, MixedCase, letterSpacing=0 (PercentageSpacing), PreferDefaultHinting, styleName="", resolveMask=SizeResolved) Change-Id: Ib4aebd7346ef4a2946cc4450c12730cf7844c3bc Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com> Reviewed-by: Lars Knoll <lars.knoll@qt.io> --- src/gui/text/qfont.cpp | 99 +++++++++++++++++++++++++++++++++++++++++- src/gui/text/qfont.h | 6 +++ 2 files changed, 104 insertions(+), 1 deletion(-) diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index d879836572..82e03b6df9 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -3161,7 +3161,104 @@ void QFontCache::decreaseCache() #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug stream, const QFont &font) { - return stream << "QFont(" << font.toString() << ')'; + QDebugStateSaver saver(stream); + stream.nospace().noquote(); + stream << "QFont("; + + if (stream.verbosity() == QDebug::DefaultVerbosity) { + stream << font.toString() << ")"; + return stream; + } + + QString fontDescription; + QDebug debug(&fontDescription); + debug.nospace(); + + QFontPrivate priv; + const QFont defaultFont(&priv); + + for (int property = QFont::FamilyResolved; property < QFont::AllPropertiesResolved; property <<= 1) { + const bool resolved = (font.resolve_mask & property) != 0; + if (!resolved && stream.verbosity() == QDebug::MinimumVerbosity) + continue; + + #define QFONT_DEBUG_SKIP_DEFAULT(prop) \ + if ((font.prop() == defaultFont.prop()) && stream.verbosity() == 1) \ + continue; + + QDebugStateSaver saver(debug); + + switch (property) { + case QFont::FamilyResolved: + debug << font.family(); break; + case QFont::SizeResolved: + if (font.pointSizeF() >= 0) + debug << font.pointSizeF() << "pt"; + else if (font.pixelSize() >= 0) + debug << font.pixelSize() << "px"; + else + Q_UNREACHABLE(); + break; + case QFont::StyleHintResolved: + QFONT_DEBUG_SKIP_DEFAULT(styleHint); + debug.verbosity(1) << font.styleHint(); break; + case QFont::StyleStrategyResolved: + QFONT_DEBUG_SKIP_DEFAULT(styleStrategy); + debug.verbosity(1) << font.styleStrategy(); break; + case QFont::WeightResolved: + debug.verbosity(1) << QFont::Weight(font.weight()); break; + case QFont::StyleResolved: + QFONT_DEBUG_SKIP_DEFAULT(style); + debug.verbosity(0) << font.style(); break; + case QFont::UnderlineResolved: + QFONT_DEBUG_SKIP_DEFAULT(underline); + debug << "underline=" << font.underline(); break; + case QFont::OverlineResolved: + QFONT_DEBUG_SKIP_DEFAULT(overline); + debug << "overline=" << font.overline(); break; + case QFont::StrikeOutResolved: + QFONT_DEBUG_SKIP_DEFAULT(strikeOut); + debug << "strikeOut=" << font.strikeOut(); break; + case QFont::FixedPitchResolved: + QFONT_DEBUG_SKIP_DEFAULT(fixedPitch); + debug << "fixedPitch=" << font.fixedPitch(); break; + case QFont::StretchResolved: + QFONT_DEBUG_SKIP_DEFAULT(stretch); + debug.verbosity(0) << QFont::Stretch(font.stretch()); break; + case QFont::KerningResolved: + QFONT_DEBUG_SKIP_DEFAULT(kerning); + debug << "kerning=" << font.kerning(); break; + case QFont::CapitalizationResolved: + QFONT_DEBUG_SKIP_DEFAULT(capitalization); + debug.verbosity(0) << font.capitalization(); break; + case QFont::LetterSpacingResolved: + QFONT_DEBUG_SKIP_DEFAULT(letterSpacing); + debug << "letterSpacing=" << font.letterSpacing(); + debug.verbosity(0) << " (" << font.letterSpacingType() << ")"; + break; + case QFont::HintingPreferenceResolved: + QFONT_DEBUG_SKIP_DEFAULT(hintingPreference); + debug.verbosity(0) << font.hintingPreference(); break; + case QFont::StyleNameResolved: + QFONT_DEBUG_SKIP_DEFAULT(styleName); + debug << "styleName=" << font.styleName(); break; + default: + continue; + }; + + #undef QFONT_DEBUG_SKIP_DEFAULT + + debug << ", "; + } + + if (stream.verbosity() > QDebug::MinimumVerbosity) + debug.verbosity(0) << "resolveMask=" << QFlags<QFont::ResolveProperties>(font.resolve_mask); + else + fontDescription.chop(2); // Last ', ' + + stream << fontDescription << ')'; + + return stream; } #endif diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h index e86f06353a..35ef798275 100644 --- a/src/gui/text/qfont.h +++ b/src/gui/text/qfont.h @@ -147,6 +147,7 @@ public: Q_ENUM(SpacingType) enum ResolveProperties { + NoPropertiesResolved = 0x0000, FamilyResolved = 0x0001, SizeResolved = 0x0002, StyleHintResolved = 0x0004, @@ -167,6 +168,7 @@ public: FamiliesResolved = 0x20000, AllPropertiesResolved = 0x3ffff }; + Q_ENUM(ResolveProperties) QFont(); QFont(const QString &family, int pointSize = -1, int weight = -1, bool italic = false); @@ -335,6 +337,10 @@ private: friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QFont &); #endif +#ifndef QT_NO_DEBUG_STREAM + friend Q_GUI_EXPORT QDebug operator<<(QDebug, const QFont &); +#endif + QExplicitlySharedDataPointer<QFontPrivate> d; uint resolve_mask; }; From 9332f8cb723f63761e60b6cf6b12276aa2cc6721 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid <albert.astals.cid@kdab.com> Date: Thu, 31 Jan 2019 09:30:20 +0100 Subject: [PATCH 1113/1650] tst_qheaderview: Do not use the deprecated QAbstractItemModel::reset() Still do a begin/end reset model in place, which is probably not the best code but since it's a test and it works it should be enough Change-Id: Iffaf8d69d5be64ef5e1e359e3d90a1e8174fc13b Reviewed-by: David Faure <david.faure@kdab.com> Reviewed-by: Frederik Gladhorn <frederik.gladhorn@qt.io> --- .../auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp index 9d3770064f..21ff6c4a1b 100644 --- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp +++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp @@ -85,7 +85,8 @@ class XResetModel : public QStandardItemModel blockSignals(true); bool r = QStandardItemModel::removeRows(row, count, parent); blockSignals(false); - emit reset(); + beginResetModel(); + endResetModel(); return r; } virtual bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) @@ -93,7 +94,8 @@ class XResetModel : public QStandardItemModel blockSignals(true); bool r = QStandardItemModel::insertRows(row, count, parent); blockSignals(false); - emit reset(); + beginResetModel(); + endResetModel(); return r; } }; From f20adcde3079227b063b747e6bd91f8fd94c4866 Mon Sep 17 00:00:00 2001 From: Edward Welbourne <edward.welbourne@qt.io> Date: Tue, 20 Nov 2018 19:57:25 +0100 Subject: [PATCH 1114/1650] Dodge qFatal() so as to get coverage results despite it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The silent and blacklisted selftests of testlib end in a qFatal(), to test its messaging is handled correctly. However, this prevents hooks in main() from saving coverage data when we're gathering that. So use a transient signal handler that longjmp()s back to a setjmp() just before the qFatal() to let the test complete normally (but, since qFatal() does something different on MS-Win, don't apply this to it). Note that testlib's internal FatalSignalHandler handles all fatal signals *except* SIGABRT, so this isn't over-riding it. (In any case, this restores the prior signal handler in setjmp()'s catch branch.) Added missing expected_silent.tap test output while checking that this change doesn't affect (the rest of) the test output. Change-Id: I7e460581ad93e26639c066b3229438a66fd299de Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> --- .../selftests/blacklisted/tst_blacklisted.cpp | 21 +++++++++- .../testlib/selftests/expected_silent.tap | 42 +++++++++++++++++++ .../testlib/selftests/silent/tst_silent.cpp | 21 +++++++++- 3 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 tests/auto/testlib/selftests/expected_silent.tap diff --git a/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp b/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp index 90520385ec..9c08af382a 100644 --- a/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp +++ b/tests/auto/testlib/selftests/blacklisted/tst_blacklisted.cpp @@ -75,6 +75,17 @@ void tst_Blacklisted::xpass() QVERIFY2(true, "This test should XPASS, blacklist ignored for XPASS"); } +#ifndef Q_OS_WIN +#include <signal.h> +#include <setjmp.h> + +static jmp_buf state; +static void abort_handler(int signal) +{ + longjmp(state, 1); +} +#endif + void tst_Blacklisted::messages() { qWarning("This is a warning that should not appear in silent test output"); @@ -83,7 +94,15 @@ void tst_Blacklisted::messages() qCritical("This is a critical message that should not appear in silent test output"); qInfo("This is an info message that should not appear in silent test output"); QTestLog::info("This is an internal testlib info message that should not appear in silent test output", __FILE__, __LINE__); - qFatal("This is a fatal error message that should still appear in silent test output"); + +#ifndef Q_OS_WIN + // We're testing qFatal, but we don't want to actually std::abort() ! + auto prior = signal(SIGABRT, abort_handler); + if (setjmp(state)) + signal(SIGABRT, prior); + else +#endif + qFatal("This is a fatal error message that should still appear in silent test output"); } QTEST_MAIN(tst_Blacklisted) diff --git a/tests/auto/testlib/selftests/expected_silent.tap b/tests/auto/testlib/selftests/expected_silent.tap new file mode 100644 index 0000000000..c5f7716390 --- /dev/null +++ b/tests/auto/testlib/selftests/expected_silent.tap @@ -0,0 +1,42 @@ +TAP version 13 +# tst_Silent +ok 1 - initTestCase() +ok 2 - pass() +ok 3 - skip() # SKIP This test should skip +not ok 4 - fail() + --- + type: QVERIFY + message: This test should fail + wanted: true (false) + found: false (false) + expected: true (false) + actual: false (false) + at: tst_Silent::fail() (qtbase/tests/auto/testlib/selftests/silent/tst_silent.cpp:60) + file: qtbase/tests/auto/testlib/selftests/silent/tst_silent.cpp + line: 60 + ... +not ok 5 - xfail() # TODO This test should XFAIL + --- + at: tst_Silent::xfail() (qtbase/tests/auto/testlib/selftests/silent/tst_silent.cpp:66) + file: qtbase/tests/auto/testlib/selftests/silent/tst_silent.cpp + line: 66 + ... +ok 6 - xpass() # TODO 'true' returned TRUE unexpectedly. (This test should XPASS) +# This is a warning that should not appear in silent test output +# This is an internal testlib warning that should not appear in silent test output +# This is a debug message that should not appear in silent test output +# This is a critical message that should not appear in silent test output +# This is an info message that should not appear in silent test output +# This is an internal testlib info message that should not appear in silent test output +# This is a fatal error message that should still appear in silent test output +not ok 7 - messages() + --- + # Received a fatal error. + at: tst_Silent::messages() (Unknown file:0) + file: Unknown file + line: 0 + ... +1..7 +# tests 7 +# pass 3 +# fail 3 diff --git a/tests/auto/testlib/selftests/silent/tst_silent.cpp b/tests/auto/testlib/selftests/silent/tst_silent.cpp index 97fbbfd30a..cf3c35dec4 100644 --- a/tests/auto/testlib/selftests/silent/tst_silent.cpp +++ b/tests/auto/testlib/selftests/silent/tst_silent.cpp @@ -72,6 +72,17 @@ void tst_Silent::xpass() QVERIFY2(true, "This test should XPASS"); } +#ifndef Q_OS_WIN +#include <signal.h> +#include <setjmp.h> + +static jmp_buf state; +static void abort_handler(int signal) +{ + longjmp(state, 1); +} +#endif + void tst_Silent::messages() { qWarning("This is a warning that should not appear in silent test output"); @@ -80,7 +91,15 @@ void tst_Silent::messages() qCritical("This is a critical message that should not appear in silent test output"); qInfo("This is an info message that should not appear in silent test output"); QTestLog::info("This is an internal testlib info message that should not appear in silent test output", __FILE__, __LINE__); - qFatal("This is a fatal error message that should still appear in silent test output"); + +#ifndef Q_OS_WIN + // We're testing qFatal, but we don't want to actually std::abort() ! + auto prior = signal(SIGABRT, abort_handler); + if (setjmp(state)) + signal(SIGABRT, prior); + else +#endif + qFatal("This is a fatal error message that should still appear in silent test output"); } QTEST_MAIN(tst_Silent) From 3b87ecc06a4056de48ce7fa4d69ca71422cc1170 Mon Sep 17 00:00:00 2001 From: Yuhang Zhao <2546789017@qq.com> Date: Mon, 11 Feb 2019 20:39:36 +0800 Subject: [PATCH 1115/1650] Win32 makefile for qmake: Use proper linker Use xilink for ICC and lld-link for Clang. Change-Id: I13c74339ae9e3e5c97210afd20a53c7e474b873b Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> --- qmake/Makefile.win32 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index ed738e0c02..3f13df884a 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -12,11 +12,11 @@ QMKSRC = $(SOURCE_PATH)\qmake # !if "$(QMAKESPEC)" == "win32-icc" CXX = icl -LINKER = link +LINKER = xilink CFLAGS_EXTRA = /Zc:forScope /Qstd=c++11 !elseif "$(QMAKESPEC)" == "win32-clang-msvc" CXX = clang-cl -LINKER = link +LINKER = lld-link CFLAGS_EXTRA = -fms-compatibility-version=19.00.23506 -Wno-microsoft-enum-value !else CXX = cl From fd88c152db0949e47613858a914a6ae4a825781d Mon Sep 17 00:00:00 2001 From: Eric Lemanissier <eric.lemanissier@gmail.com> Date: Sun, 3 Feb 2019 14:42:27 +0100 Subject: [PATCH 1116/1650] configure: use proper separator for mingw libraries Change-Id: Ic328691fe2f08e918c1bb67910521d85b274a8fd Fixes: QTBUG-73466 Reviewed-by: Kai Koehne <kai.koehne@qt.io> Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> --- mkspecs/features/toolchain.prf | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mkspecs/features/toolchain.prf b/mkspecs/features/toolchain.prf index 2a7cbabc54..9c3a64aa8b 100644 --- a/mkspecs/features/toolchain.prf +++ b/mkspecs/features/toolchain.prf @@ -229,7 +229,10 @@ isEmpty($${target_prefix}.INCDIRS) { line ~= s/^[ \\t]*// # remove leading spaces contains(line, "LIBRARY_PATH=.*") { line ~= s/^LIBRARY_PATH=// # remove leading LIBRARY_PATH= - paths = $$split(line, $$QMAKE_DIRLIST_SEP) + equals(QMAKE_HOST.os, Windows): \ + paths = $$split(line, ;) + else: \ + paths = $$split(line, $$QMAKE_DIRLIST_SEP) for (path, paths): \ QMAKE_DEFAULT_LIBDIRS += $$clean_path($$path) } else: contains(line, "Library search paths:") { From 2e12bfdc1e537bb3cc027eed14500fe5724ab30f Mon Sep 17 00:00:00 2001 From: Laszlo Agocs <laszlo.agocs@qt.io> Date: Fri, 14 Dec 2018 10:48:43 +0100 Subject: [PATCH 1117/1650] eglfs: avoid breaking builds without EGL_EXT_platform_base Change-Id: I9183e17b42c00435f20c00a414e1f20aa3972351 Fixes: QTBUG-72559 Reviewed-by: Johan Helsing <johan.helsing@qt.io> --- .../deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp | 1 - .../eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp index 1e4f4e72c8..f154520669 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp @@ -63,7 +63,6 @@ QEglFSKmsGbmIntegration::QEglFSKmsGbmIntegration() #ifndef EGL_EXT_platform_base typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void *native_display, const EGLint *attrib_list); -typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list); #endif #ifndef EGL_PLATFORM_GBM_KHR diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp index 65a7c4f38a..a93762e5b4 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmwindow.cpp @@ -45,6 +45,10 @@ QT_BEGIN_NAMESPACE +#ifndef EGL_EXT_platform_base +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list); +#endif + void QEglFSKmsGbmWindow::resetSurface() { QEglFSKmsGbmScreen *gbmScreen = static_cast<QEglFSKmsGbmScreen *>(screen()); From 7faec58d5cccf7e7a5f92116f70cc504821711af Mon Sep 17 00:00:00 2001 From: Mitch Curtis <mitch.curtis@qt.io> Date: Wed, 9 Jan 2019 15:01:16 +0100 Subject: [PATCH 1118/1650] Fix crash when using Qt Virtual Keyboard with QCalendarWidget For some reason, QCalendarWidget gets filtered press events that were intended for Qt Virtual Keyboard's input panel (QQuickView), so we have to make sure that the window is indeed a QWidget - no static_cast. Change-Id: Ibc9dce956918ac50d1fed8231a445b7338aef09c Fixes: QTBUG-72925 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> --- src/widgets/widgets/qcalendarwidget.cpp | 27 ++++++++++++++----------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/widgets/widgets/qcalendarwidget.cpp b/src/widgets/widgets/qcalendarwidget.cpp index 4946969360..2ff383d9c7 100644 --- a/src/widgets/widgets/qcalendarwidget.cpp +++ b/src/widgets/widgets/qcalendarwidget.cpp @@ -3063,19 +3063,22 @@ bool QCalendarWidget::eventFilter(QObject *watched, QEvent *event) { Q_D(QCalendarWidget); if (event->type() == QEvent::MouseButtonPress && d->yearEdit->hasFocus()) { + // We can get filtered press events that were intended for Qt Virtual Keyboard's + // input panel (QQuickView), so we have to make sure that the window is indeed a QWidget - no static_cast. + // In addition, as we have a event filter on the whole application we first make sure that the top level widget + // of both this and the watched widget are the same to decide if we should finish the year edition. QWidget *tlw = window(); - QWidget *widget = static_cast<QWidget*>(watched); - //as we have a event filter on the whole application we first make sure that the top level widget - //of both this and the watched widget are the same to decide if we should finish the year edition. - if (widget->window() == tlw) { - QPoint mousePos = widget->mapTo(tlw, static_cast<QMouseEvent *>(event)->pos()); - QRect geom = QRect(d->yearEdit->mapTo(tlw, QPoint(0, 0)), d->yearEdit->size()); - if (!geom.contains(mousePos)) { - event->accept(); - d->_q_yearEditingFinished(); - setFocus(); - return true; - } + QWidget *widget = qobject_cast<QWidget *>(watched); + if (!widget || widget->window() != tlw) + return QWidget::eventFilter(watched, event); + + QPoint mousePos = widget->mapTo(tlw, static_cast<QMouseEvent *>(event)->pos()); + QRect geom = QRect(d->yearEdit->mapTo(tlw, QPoint(0, 0)), d->yearEdit->size()); + if (!geom.contains(mousePos)) { + event->accept(); + d->_q_yearEditingFinished(); + setFocus(); + return true; } } return QWidget::eventFilter(watched, event); From da55a1b04121abd44d9c72e0c7cba7d72f16d4f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= <tor.arne.vestbo@qt.io> Date: Fri, 1 Feb 2019 11:19:32 +0100 Subject: [PATCH 1119/1650] Widgets: Only set WA_WState_ExplicitShowHide via public API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Calling QWindow::setVisible doesn't have the same semantics, so we split off QWidget::setVisible into QWidgetPrivate::setVisible and call that instead from QWidgetWindow. Task-number QTBUG-67504 Change-Id: Ie50938d4a1d33ad4b59c742e75e3ca30f1b19399 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> --- src/widgets/kernel/qwidget.cpp | 111 ++++++++++++++------------- src/widgets/kernel/qwidget_p.h | 1 + src/widgets/kernel/qwidgetwindow.cpp | 2 +- 3 files changed, 59 insertions(+), 55 deletions(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 19599cc008..332eee9c03 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -8296,49 +8296,57 @@ void QWidgetPrivate::hide_sys() \endlist */ - void QWidget::setVisible(bool visible) { + if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden) == !visible) + return; + + // Remember that setVisible was called explicitly + setAttribute(Qt::WA_WState_ExplicitShowHide); + + Q_D(QWidget); + d->setVisible(visible); +} + +// This method is called from QWidgetWindow in response to QWindow::setVisible, +// and should match the semantics of QWindow::setVisible. QWidget::setVisible on +// the other hand keeps track of WA_WState_ExplicitShowHide in addition. +void QWidgetPrivate::setVisible(bool visible) +{ + Q_Q(QWidget); if (visible) { // show - if (testAttribute(Qt::WA_WState_ExplicitShowHide) && !testAttribute(Qt::WA_WState_Hidden)) - return; - - Q_D(QWidget); - // Designer uses a trick to make grabWidget work without showing - if (!isWindow() && parentWidget() && parentWidget()->isVisible() - && !parentWidget()->testAttribute(Qt::WA_WState_Created)) - parentWidget()->window()->d_func()->createRecursively(); + if (!q->isWindow() && q->parentWidget() && q->parentWidget()->isVisible() + && !q->parentWidget()->testAttribute(Qt::WA_WState_Created)) + q->parentWidget()->window()->d_func()->createRecursively(); //create toplevels but not children of non-visible parents - QWidget *pw = parentWidget(); - if (!testAttribute(Qt::WA_WState_Created) - && (isWindow() || pw->testAttribute(Qt::WA_WState_Created))) { - create(); + QWidget *pw = q->parentWidget(); + if (!q->testAttribute(Qt::WA_WState_Created) + && (q->isWindow() || pw->testAttribute(Qt::WA_WState_Created))) { + q->create(); } - bool wasResized = testAttribute(Qt::WA_Resized); - Qt::WindowStates initialWindowState = windowState(); + bool wasResized = q->testAttribute(Qt::WA_Resized); + Qt::WindowStates initialWindowState = q->windowState(); // polish if necessary - ensurePolished(); + q->ensurePolished(); - // remember that show was called explicitly - setAttribute(Qt::WA_WState_ExplicitShowHide); // whether we need to inform the parent widget immediately - bool needUpdateGeometry = !isWindow() && testAttribute(Qt::WA_WState_Hidden); + bool needUpdateGeometry = !q->isWindow() && q->testAttribute(Qt::WA_WState_Hidden); // we are no longer hidden - setAttribute(Qt::WA_WState_Hidden, false); + q->setAttribute(Qt::WA_WState_Hidden, false); if (needUpdateGeometry) - d->updateGeometry_helper(true); + updateGeometry_helper(true); // activate our layout before we and our children become visible - if (d->layout) - d->layout->activate(); + if (layout) + layout->activate(); - if (!isWindow()) { - QWidget *parent = parentWidget(); + if (!q->isWindow()) { + QWidget *parent = q->parentWidget(); while (parent && parent->isVisible() && parent->d_func()->layout && !parent->data->in_show) { parent->d_func()->layout->activate(); if (parent->isWindow()) @@ -8351,30 +8359,28 @@ void QWidget::setVisible(bool visible) // adjust size if necessary if (!wasResized - && (isWindow() || !parentWidget()->d_func()->layout)) { - if (isWindow()) { - adjustSize(); - if (windowState() != initialWindowState) - setWindowState(initialWindowState); + && (q->isWindow() || !q->parentWidget()->d_func()->layout)) { + if (q->isWindow()) { + q->adjustSize(); + if (q->windowState() != initialWindowState) + q->setWindowState(initialWindowState); } else { - adjustSize(); + q->adjustSize(); } - setAttribute(Qt::WA_Resized, false); + q->setAttribute(Qt::WA_Resized, false); } - setAttribute(Qt::WA_KeyboardFocusChange, false); + q->setAttribute(Qt::WA_KeyboardFocusChange, false); - if (isWindow() || parentWidget()->isVisible()) { - d->show_helper(); + if (q->isWindow() || q->parentWidget()->isVisible()) { + show_helper(); - qApp->d_func()->sendSyntheticEnterLeave(this); + qApp->d_func()->sendSyntheticEnterLeave(q); } QEvent showToParentEvent(QEvent::ShowToParent); - QApplication::sendEvent(this, &showToParentEvent); + QApplication::sendEvent(q, &showToParentEvent); } else { // hide - if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden)) - return; #if 0 // Used to be included in Qt4 for Q_WS_WIN // reset WS_DISABLED style in a Blocked window if(isWindow() && testAttribute(Qt::WA_WState_Created) @@ -8385,33 +8391,30 @@ void QWidget::setVisible(bool visible) SetWindowLong(winId(), GWL_STYLE, dwStyle); } #endif - if (QApplicationPrivate::hidden_focus_widget == this) + if (QApplicationPrivate::hidden_focus_widget == q) QApplicationPrivate::hidden_focus_widget = 0; - Q_D(QWidget); - // hw: The test on getOpaqueRegion() needs to be more intelligent // currently it doesn't work if the widget is hidden (the region will // be clipped). The real check should be testing the cached region // (and dirty flag) directly. - if (!isWindow() && parentWidget()) // && !d->getOpaqueRegion().isEmpty()) - parentWidget()->d_func()->setDirtyOpaqueRegion(); + if (!q->isWindow() && q->parentWidget()) // && !d->getOpaqueRegion().isEmpty()) + q->parentWidget()->d_func()->setDirtyOpaqueRegion(); - setAttribute(Qt::WA_WState_Hidden); - setAttribute(Qt::WA_WState_ExplicitShowHide); - if (testAttribute(Qt::WA_WState_Created)) - d->hide_helper(); + q->setAttribute(Qt::WA_WState_Hidden); + if (q->testAttribute(Qt::WA_WState_Created)) + hide_helper(); // invalidate layout similar to updateGeometry() - if (!isWindow() && parentWidget()) { - if (parentWidget()->d_func()->layout) - parentWidget()->d_func()->layout->invalidate(); - else if (parentWidget()->isVisible()) - QApplication::postEvent(parentWidget(), new QEvent(QEvent::LayoutRequest)); + if (!q->isWindow() && q->parentWidget()) { + if (q->parentWidget()->d_func()->layout) + q->parentWidget()->d_func()->layout->invalidate(); + else if (q->parentWidget()->isVisible()) + QApplication::postEvent(q->parentWidget(), new QEvent(QEvent::LayoutRequest)); } QEvent hideToParentEvent(QEvent::HideToParent); - QApplication::sendEvent(this, &hideToParentEvent); + QApplication::sendEvent(q, &hideToParentEvent); } } diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 0d7e9e26ba..7e4ea2cc0c 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -483,6 +483,7 @@ public: void hide_sys(); void hide_helper(); void _q_showIfNotHidden(); + void setVisible(bool); void setEnabled_helper(bool); static void adjustFlags(Qt::WindowFlags &flags, QWidget *w = 0); diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 991a05fa02..e9b749d7c2 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -73,7 +73,7 @@ public: { Q_Q(QWidgetWindow); if (QWidget *widget = q->widget()) - widget->setVisible(visible); + QWidgetPrivate::get(widget)->setVisible(visible); else QWindowPrivate::setVisible(visible); } From 3fe9f245e8fb5fa9a2336fecaabd8d677f55c5db Mon Sep 17 00:00:00 2001 From: Michal Klocek <michal.klocek@qt.io> Date: Thu, 13 Sep 2018 10:54:18 +0200 Subject: [PATCH 1120/1650] Add platform native interface to offscreen plugin Adds trival support for querying "display" and "glxconfig" in case offscreen plugin is compiled with xlib support. This is required so this plugin could work with webengine. Taks-number: QTBUG-63346 Change-Id: Ie0f29385cb44429ddf383ad459e0c9f3263ccffe Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io> --- .../offscreen/qoffscreenintegration.h | 1 + .../offscreen/qoffscreenintegration_x11.cpp | 77 +++++++++++++------ .../offscreen/qoffscreenintegration_x11.h | 9 ++- 3 files changed, 62 insertions(+), 25 deletions(-) diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration.h b/src/plugins/platforms/offscreen/qoffscreenintegration.h index fc988126bb..098e726550 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration.h +++ b/src/plugins/platforms/offscreen/qoffscreenintegration.h @@ -41,6 +41,7 @@ #define QOFFSCREENINTEGRATION_H #include <qpa/qplatformintegration.h> +#include <qpa/qplatformnativeinterface.h> #include <qscopedpointer.h> diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp index 93566220e8..06a9bd2a4c 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp +++ b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp @@ -52,6 +52,30 @@ QT_BEGIN_NAMESPACE +class QOffscreenX11Info +{ +public: + QOffscreenX11Info(QOffscreenX11Connection *connection) + : m_connection(connection) + { + } + + Display *display() const { + return (Display *)m_connection->display(); + } + + Window root() const { + return DefaultRootWindow(display()); + } + + int screenNumber() const { + return m_connection->screenNumber(); + } + +private: + QOffscreenX11Connection *m_connection; +}; + QOffscreenIntegration *QOffscreenIntegration::createOffscreenIntegration() { return new QOffscreenX11Integration; @@ -77,6 +101,35 @@ QPlatformOpenGLContext *QOffscreenX11Integration::createPlatformOpenGLContext(QO return new QOffscreenX11GLXContext(m_connection->x11Info(), context); } +QPlatformNativeInterface *QOffscreenX11Integration::nativeInterface() const +{ + return const_cast<QOffscreenX11Integration *>(this); +} + +void *QOffscreenX11Integration::nativeResourceForScreen(const QByteArray &resource, QScreen *screen) +{ + Q_UNUSED(screen) + if (resource.toLower() == QByteArrayLiteral("display") ) { + if (!m_connection) + m_connection.reset(new QOffscreenX11Connection); + return m_connection->display(); + } + return nullptr; +} + +#ifndef QT_NO_OPENGL +void *QOffscreenX11Integration::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) { + if (resource.toLower() == QByteArrayLiteral("glxconfig") ) { + if (!m_connection) + m_connection.reset(new QOffscreenX11Connection); + QOffscreenX11Info *x11 = m_connection->x11Info(); + GLXFBConfig config = qglx_findConfig(x11->display(), x11->screenNumber(), context->format()); + return config; + } + return nullptr; +} +#endif + QOffscreenX11Connection::QOffscreenX11Connection() { XInitThreads(); @@ -93,30 +146,6 @@ QOffscreenX11Connection::~QOffscreenX11Connection() XCloseDisplay((Display *)m_display); } -class QOffscreenX11Info -{ -public: - QOffscreenX11Info(QOffscreenX11Connection *connection) - : m_connection(connection) - { - } - - Display *display() const { - return (Display *)m_connection->display(); - } - - Window root() const { - return DefaultRootWindow(display()); - } - - int screenNumber() const { - return m_connection->screenNumber(); - } - -private: - QOffscreenX11Connection *m_connection; -}; - QOffscreenX11Info *QOffscreenX11Connection::x11Info() { if (!m_x11Info) diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h index 5e1c6b799b..a1986fdc94 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h +++ b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h @@ -52,12 +52,19 @@ QT_BEGIN_NAMESPACE class QOffscreenX11Connection; class QOffscreenX11Info; -class QOffscreenX11Integration : public QOffscreenIntegration +class QOffscreenX11Integration : public QOffscreenIntegration, public QPlatformNativeInterface { public: bool hasCapability(QPlatformIntegration::Capability cap) const override; QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override; + QPlatformNativeInterface *nativeInterface()const override; + + // QPlatformNativeInterface + void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen) override; +#ifndef QT_NO_OPENGL + void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) override; +#endif private: mutable QScopedPointer<QOffscreenX11Connection> m_connection; From 37970d7b3e6fff92dca98db974ada865c1bfd730 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann <joerg.bornemann@qt.io> Date: Tue, 12 Feb 2019 13:21:39 +0100 Subject: [PATCH 1121/1650] Fix determination of OpenGL include paths on macOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since include paths are fully resolved, we must remove the code that prepends the SDK path to the OpenGL include paths. Change-Id: I80d74629c7fc989a89c3f1d95d6de43b4c1de17a Fixes: QTBUG-73736 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> --- mkspecs/common/mac.conf | 2 +- mkspecs/features/mac/sdk.prf | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/mkspecs/common/mac.conf b/mkspecs/common/mac.conf index b77494ec9b..e000d1026b 100644 --- a/mkspecs/common/mac.conf +++ b/mkspecs/common/mac.conf @@ -17,7 +17,7 @@ QMAKE_EXTENSION_SHLIB = dylib QMAKE_EXTENSIONS_AUX_SHLIB = tbd QMAKE_LIBDIR = -# sdk.prf will prefix the proper SDK sysroot +# The proper SDK sysroot will be automatically prepended QMAKE_INCDIR_OPENGL = \ /System/Library/Frameworks/OpenGL.framework/Headers \ /System/Library/Frameworks/AGL.framework/Headers/ diff --git a/mkspecs/features/mac/sdk.prf b/mkspecs/features/mac/sdk.prf index 8360dd8b38..50a41657d8 100644 --- a/mkspecs/features/mac/sdk.prf +++ b/mkspecs/features/mac/sdk.prf @@ -33,10 +33,6 @@ QMAKE_MAC_SDK_PATH = $$xcodeSDKInfo(Path) QMAKE_MAC_SDK_PLATFORM_PATH = $$xcodeSDKInfo(PlatformPath) QMAKE_MAC_SDK_VERSION = $$xcodeSDKInfo(SDKVersion) -sysrootified = -for(val, QMAKE_INCDIR_OPENGL): sysrootified += $${QMAKE_MAC_SDK_PATH}$$val -QMAKE_INCDIR_OPENGL = $$sysrootified - QMAKESPEC_NAME = $$basename(QMAKESPEC) # Resolve SDK version of various tools From 2c60844badd8fb07dd4844926345c924679f20fb Mon Sep 17 00:00:00 2001 From: Nicolas Fella <nicolas.fella@kdab.com> Date: Wed, 30 Jan 2019 14:13:12 +0100 Subject: [PATCH 1122/1650] [platform/android] Add native file dialog Add basic native file open dialog on Android. Not all features of QFileDialog can be mapped to the Android file dialog. Most notably there is no "Save" dialog. The dialog returns a content:// URL. Patch 251038 adds support for those to QFile. Change-Id: I13d02103edcd9a089afcce8193432f24b2e0fe43 Reviewed-by: BogDan Vatra <bogdan@kdab.com> --- src/plugins/platforms/android/android.pro | 6 +- .../qandroidplatformfiledialoghelper.cpp | 149 ++++++++++++++++++ .../qandroidplatformfiledialoghelper.h | 81 ++++++++++ .../android/qandroidplatformtheme.cpp | 5 + 4 files changed, 239 insertions(+), 2 deletions(-) create mode 100644 src/plugins/platforms/android/qandroidplatformfiledialoghelper.cpp create mode 100644 src/plugins/platforms/android/qandroidplatformfiledialoghelper.h diff --git a/src/plugins/platforms/android/android.pro b/src/plugins/platforms/android/android.pro index 73db9e93a3..f91db1ab5f 100644 --- a/src/plugins/platforms/android/android.pro +++ b/src/plugins/platforms/android/android.pro @@ -46,7 +46,8 @@ SOURCES += $$PWD/androidplatformplugin.cpp \ $$PWD/qandroidplatformopenglcontext.cpp \ $$PWD/qandroidplatformforeignwindow.cpp \ $$PWD/qandroideventdispatcher.cpp \ - $$PWD/qandroidplatformoffscreensurface.cpp + $$PWD/qandroidplatformoffscreensurface.cpp \ + $$PWD/qandroidplatformfiledialoghelper.cpp HEADERS += $$PWD/qandroidplatformintegration.h \ $$PWD/androiddeadlockprotector.h \ @@ -75,7 +76,8 @@ HEADERS += $$PWD/qandroidplatformintegration.h \ $$PWD/qandroidplatformopenglcontext.h \ $$PWD/qandroidplatformforeignwindow.h \ $$PWD/qandroideventdispatcher.h \ - $$PWD/qandroidplatformoffscreensurface.h + $$PWD/qandroidplatformoffscreensurface.h \ + $$PWD/qandroidplatformfiledialoghelper.h qtConfig(android-style-assets): SOURCES += $$PWD/extract.cpp else: SOURCES += $$PWD/extract-dummy.cpp diff --git a/src/plugins/platforms/android/qandroidplatformfiledialoghelper.cpp b/src/plugins/platforms/android/qandroidplatformfiledialoghelper.cpp new file mode 100644 index 0000000000..4fb271a75c --- /dev/null +++ b/src/plugins/platforms/android/qandroidplatformfiledialoghelper.cpp @@ -0,0 +1,149 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB) +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qandroidplatformfiledialoghelper.h" + +#include <androidjnimain.h> +#include <private/qjni_p.h> +#include <jni.h> + +QT_BEGIN_NAMESPACE + +namespace QtAndroidFileDialogHelper { + +#define RESULT_OK -1 +#define REQUEST_CODE 1305 // Arbitrary + +QAndroidPlatformFileDialogHelper::QAndroidPlatformFileDialogHelper() + : QPlatformFileDialogHelper() + , m_selectedFile() +{ +} + +bool QAndroidPlatformFileDialogHelper::handleActivityResult(jint requestCode, jint resultCode, jobject data) +{ + if (requestCode != REQUEST_CODE) + return false; + + if (resultCode == RESULT_OK) { + const QJNIObjectPrivate intent = QJNIObjectPrivate::fromLocalRef(data); + const QJNIObjectPrivate uri = intent.callObjectMethod("getData", "()Landroid/net/Uri;"); + const QString uriStr = uri.callObjectMethod("toString", "()Ljava/lang/String;").toString(); + m_selectedFile = QUrl(uriStr); + Q_EMIT fileSelected(m_selectedFile); + Q_EMIT accept(); + } else { + Q_EMIT reject(); + } + + return true; +} + +bool QAndroidPlatformFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) +{ + Q_UNUSED(windowFlags) + Q_UNUSED(windowModality) + Q_UNUSED(parent) + + if (options()->fileMode() != QFileDialogOptions::FileMode::ExistingFile) + return false; + + QtAndroidPrivate::registerActivityResultListener(this); + + const QJNIObjectPrivate ACTION_OPEN_DOCUMENT = QJNIObjectPrivate::getStaticObjectField("android/content/Intent", "ACTION_OPEN_DOCUMENT", "Ljava/lang/String;"); + QJNIObjectPrivate intent("android/content/Intent", "(Ljava/lang/String;)V", ACTION_OPEN_DOCUMENT.object()); + const QJNIObjectPrivate CATEGORY_OPENABLE = QJNIObjectPrivate::getStaticObjectField("android/content/Intent", "CATEGORY_OPENABLE", "Ljava/lang/String;"); + intent.callObjectMethod("addCategory", "(Ljava/lang/String;)Landroid/content/Intent;", CATEGORY_OPENABLE.object()); + intent.callObjectMethod("setType", "(Ljava/lang/String;)Landroid/content/Intent;", QJNIObjectPrivate::fromString(QStringLiteral("*/*")).object()); + + const QJNIObjectPrivate activity(QtAndroid::activity()); + activity.callMethod<void>("startActivityForResult", "(Landroid/content/Intent;I)V", intent.object(), REQUEST_CODE); + + return true; +} + +void QAndroidPlatformFileDialogHelper::exec() +{ +} + +void QAndroidPlatformFileDialogHelper::hide() +{ +} + +QString QAndroidPlatformFileDialogHelper::selectedNameFilter() const +{ + return QString(); +} + +void QAndroidPlatformFileDialogHelper::selectNameFilter(const QString &filter) +{ + Q_UNUSED(filter) +} + +void QAndroidPlatformFileDialogHelper::setFilter() +{ +} + +QList<QUrl> QAndroidPlatformFileDialogHelper::selectedFiles() const +{ + return {m_selectedFile}; +} + +void QAndroidPlatformFileDialogHelper::selectFile(const QUrl &file) +{ + Q_UNUSED(file) +} + +QUrl QAndroidPlatformFileDialogHelper::directory() const +{ + return QUrl(); +} + +void QAndroidPlatformFileDialogHelper::setDirectory(const QUrl &directory) +{ + Q_UNUSED(directory) +} + +bool QAndroidPlatformFileDialogHelper::defaultNameFilterDisables() const +{ + return false; +} +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/android/qandroidplatformfiledialoghelper.h b/src/plugins/platforms/android/qandroidplatformfiledialoghelper.h new file mode 100644 index 0000000000..e445aa2fef --- /dev/null +++ b/src/plugins/platforms/android/qandroidplatformfiledialoghelper.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB) +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QANDROIDPLATFORMFILEDIALOGHELPER_H +#define QANDROIDPLATFORMFILEDIALOGHELPER_H + +#include <jni.h> +#include <qpa/qplatformdialoghelper.h> +#include <QtCore/private/qjnihelpers_p.h> + +QT_BEGIN_NAMESPACE + +namespace QtAndroidFileDialogHelper { + +class QAndroidPlatformFileDialogHelper: public QPlatformFileDialogHelper, public QtAndroidPrivate::ActivityResultListener +{ + Q_OBJECT + +public: + QAndroidPlatformFileDialogHelper(); + void exec() override; + + bool show(Qt::WindowFlags windowFlags, + Qt::WindowModality windowModality, + QWindow *parent) override; + void hide() override; + + QString selectedNameFilter() const override; + void selectNameFilter(const QString &filter) override; + void setFilter() override; + QList<QUrl> selectedFiles() const override; + void selectFile(const QUrl &file) override; + QUrl directory() const override; + void setDirectory(const QUrl &directory) override; + bool defaultNameFilterDisables() const override; + bool handleActivityResult(jint requestCode, jint resultCode, jobject data) override; + +private: + QUrl m_selectedFile; +}; + +} +QT_END_NAMESPACE + +#endif // QANDROIDPLATFORMFILEDIALOGHELPER_H diff --git a/src/plugins/platforms/android/qandroidplatformtheme.cpp b/src/plugins/platforms/android/qandroidplatformtheme.cpp index b891407c44..a78a62337f 100644 --- a/src/plugins/platforms/android/qandroidplatformtheme.cpp +++ b/src/plugins/platforms/android/qandroidplatformtheme.cpp @@ -44,6 +44,7 @@ #include "qandroidplatformmenu.h" #include "qandroidplatformmenuitem.h" #include "qandroidplatformdialoghelpers.h" +#include "qandroidplatformfiledialoghelper.h" #include <QCoreApplication> #include <QDebug> @@ -512,6 +513,8 @@ bool QAndroidPlatformTheme::usePlatformNativeDialog(QPlatformTheme::DialogType t { if (type == MessageDialog) return qEnvironmentVariableIntValue("QT_USE_ANDROID_NATIVE_DIALOGS") == 1; + if (type == FileDialog) + return true; return false; } @@ -520,6 +523,8 @@ QPlatformDialogHelper *QAndroidPlatformTheme::createPlatformDialogHelper(QPlatfo switch (type) { case MessageDialog: return new QtAndroidDialogHelpers::QAndroidPlatformMessageDialogHelper; + case FileDialog: + return new QtAndroidFileDialogHelper::QAndroidPlatformFileDialogHelper; default: return 0; } From cbbf7ddd3dcacc99908218abb45c7d8d5496562e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Micha=C3=ABl=20Celerier?= <jeanmichael.celerier@gmail.com> Date: Fri, 28 Dec 2018 01:35:16 +0100 Subject: [PATCH 1123/1650] Fix detection of libraries when linking against static builds with CMake This patch is a follow-up to eda28621f6c1a68774719f382be53ec109123b18. It adds a translation of the $$[QT_INSTALL_LIBS] variable into a path that CMake understands. Without this, CMake finds the system libraries if there are any instead. It also handles the case where the .prl file contains absolute paths to libraries, as it happens for instance on Debian systems. Task-number: QTBUG-38913 Change-Id: If68373efee22bc00172e8fead3e2c12ea440787f Reviewed-by: Kyle Edwards <kyle.edwards@kitware.com> Reviewed-by: Kevin Funk <kevin.funk@kdab.com> --- mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in b/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in index acd302d4b2..d6773d6e98 100644 --- a/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in +++ b/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in @@ -52,13 +52,18 @@ endmacro() function(_qt5_$${CMAKE_MODULE_NAME}_process_prl_file prl_file_location Configuration lib_deps link_flags) set(_lib_deps) set(_link_flags) + + get_filename_component(_qt5_install_libs \"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}/lib\" ABSOLUTE) + if(EXISTS \"${prl_file_location}\") file(STRINGS \"${prl_file_location}\" _prl_strings REGEX \"QMAKE_PRL_LIBS[ \\t]*=\") string(REGEX REPLACE \"QMAKE_PRL_LIBS[ \\t]*=[ \\t]*([^\\n]*)\" \"\\\\1\" _static_depends ${_prl_strings}) string(REGEX REPLACE \"[ \\t]+\" \";\" _static_depends ${_static_depends}) set(_search_paths) + string(REPLACE \"\\$\\$[QT_INSTALL_LIBS]\" \"${_qt5_install_libs}\" _static_depends \"${_static_depends}\") foreach(_flag ${_static_depends}) if(_flag MATCHES \"^-l(.*)$\") + # Handle normal libraries passed as -lfoo set(_lib \"${CMAKE_MATCH_1}\") if(_lib MATCHES \"^pthread$\") find_package(Threads REQUIRED) @@ -77,9 +82,14 @@ function(_qt5_$${CMAKE_MODULE_NAME}_process_prl_file prl_file_location Configura message(FATAL_ERROR \"Library not found: ${_lib}\") endif() endif() + elseif(EXISTS \"${_flag}\") + # The flag is an absolute path to an existing library + list(APPEND _lib_deps \"${_flag}\") elseif(_flag MATCHES \"^-L(.*)$\") + # Handle -Lfoo flags by putting their paths in the search path used by find_library above list(APPEND _search_paths \"${CMAKE_MATCH_1}\") else() + # Handle all remaining flags by simply passing them to the linker list(APPEND _link_flags ${_flag}) endif() endforeach() From a3c3330b6fa2a7599a86dd1475987e73856f481b Mon Sep 17 00:00:00 2001 From: Andy Shaw <andy.shaw@qt.io> Date: Fri, 8 Feb 2019 15:06:43 +0100 Subject: [PATCH 1124/1650] Update SQLite to 3.27.1 [ChangeLog][Third-Party Code] Updated bundled SQLite to version 3.27.1. Change-Id: I816a78bff07e5cde52fb7ff60b528924f22b1b80 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Jani Heikkinen <jani.heikkinen@qt.io> --- src/3rdparty/sqlite/qt_attribution.json | 4 +- src/3rdparty/sqlite/sqlite3.c | 8876 +++++++++++++---------- src/3rdparty/sqlite/sqlite3.h | 79 +- 3 files changed, 5150 insertions(+), 3809 deletions(-) diff --git a/src/3rdparty/sqlite/qt_attribution.json b/src/3rdparty/sqlite/qt_attribution.json index 542fa9efb9..30f266ee23 100644 --- a/src/3rdparty/sqlite/qt_attribution.json +++ b/src/3rdparty/sqlite/qt_attribution.json @@ -6,8 +6,8 @@ "Description": "SQLite is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine.", "Homepage": "https://www.sqlite.org/", - "Version": "3.26.0", - "DownloadLocation": "https://www.sqlite.org/2018/sqlite-amalgamation-3260000.zip", + "Version": "3.27.1", + "DownloadLocation": "https://www.sqlite.org/2018/sqlite-amalgamation-3270100.zip", "License": "Public Domain", "Copyright": "The authors disclaim copyright to the source code. However, a license can be obtained if needed." } diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c index d015df2c31..70e84b589c 100644 --- a/src/3rdparty/sqlite/sqlite3.c +++ b/src/3rdparty/sqlite/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.26.0. By combining all the individual C code files into this +** version 3.27.1. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -1162,9 +1162,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.26.0" -#define SQLITE_VERSION_NUMBER 3026000 -#define SQLITE_SOURCE_ID "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9" +#define SQLITE_VERSION "3.27.1" +#define SQLITE_VERSION_NUMBER 3027001 +#define SQLITE_SOURCE_ID "2019-02-08 13:17:39 0eca3dd3d38b31c92b49ca2d311128b74584714d9e7de895b1a6286ef959a1dd" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -1862,6 +1862,15 @@ struct sqlite3_io_methods { ** file space based on this hint in order to help writes to the database ** file run faster. ** +** <li>[[SQLITE_FCNTL_SIZE_LIMIT]] +** The [SQLITE_FCNTL_SIZE_LIMIT] opcode is used by in-memory VFS that +** implements [sqlite3_deserialize()] to set an upper bound on the size +** of the in-memory database. The argument is a pointer to a [sqlite3_int64]. +** If the integer pointed to is negative, then it is filled in with the +** current limit. Otherwise the limit is set to the larger of the value +** of the integer pointed to and the current database size. The integer +** pointed to is set to the new limit. +** ** <li>[[SQLITE_FCNTL_CHUNK_SIZE]] ** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS ** extends and truncates the database file in chunks of a size specified @@ -2170,6 +2179,7 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33 #define SQLITE_FCNTL_LOCK_TIMEOUT 34 #define SQLITE_FCNTL_DATA_VERSION 35 +#define SQLITE_FCNTL_SIZE_LIMIT 36 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE @@ -3011,6 +3021,17 @@ struct sqlite3_mem_methods { ** negative value for this option restores the default behaviour. ** This option is only available if SQLite is compiled with the ** [SQLITE_ENABLE_SORTER_REFERENCES] compile-time option. +** +** [[SQLITE_CONFIG_MEMDB_MAXSIZE]] +** <dt>SQLITE_CONFIG_MEMDB_MAXSIZE +** <dd>The SQLITE_CONFIG_MEMDB_MAXSIZE option accepts a single parameter +** [sqlite3_int64] parameter which is the default maximum size for an in-memory +** database created using [sqlite3_deserialize()]. This default maximum +** size can be adjusted up or down for individual databases using the +** [SQLITE_FCNTL_SIZE_LIMIT] [sqlite3_file_control|file-control]. If this +** configuration setting is never used, then the default maximum is determined +** by the [SQLITE_MEMDB_DEFAULT_MAXSIZE] compile-time option. If that +** compile-time option is not set, then the default maximum is 1073741824. ** </dl> */ #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ @@ -3041,6 +3062,7 @@ struct sqlite3_mem_methods { #define SQLITE_CONFIG_STMTJRNL_SPILL 26 /* int nByte */ #define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */ #define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */ +#define SQLITE_CONFIG_MEMDB_MAXSIZE 29 /* sqlite3_int64 */ /* ** CAPI3REF: Database Connection Configuration Options @@ -4030,9 +4052,9 @@ SQLITE_API int sqlite3_set_authorizer( ** time is in units of nanoseconds, however the current implementation ** is only capable of millisecond resolution so the six least significant ** digits in the time are meaningless. Future versions of SQLite -** might provide greater resolution on the profiler callback. The -** sqlite3_profile() function is considered experimental and is -** subject to change in future versions of SQLite. +** might provide greater resolution on the profiler callback. Invoking +** either [sqlite3_trace()] or [sqlite3_trace_v2()] will cancel the +** profile callback. */ SQLITE_API SQLITE_DEPRECATED void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); @@ -4446,6 +4468,8 @@ SQLITE_API int sqlite3_open_v2( ** is not a database file pathname pointer that SQLite passed into the xOpen ** VFS method, then the behavior of this routine is undefined and probably ** undesirable. +** +** See the [URI filename] documentation for additional information. */ SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam); SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault); @@ -4668,18 +4692,23 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** deplete the limited store of lookaside memory. Future versions of ** SQLite may act on this hint differently. ** -** [[SQLITE_PREPARE_NORMALIZE]] ^(<dt>SQLITE_PREPARE_NORMALIZE</dt> -** <dd>The SQLITE_PREPARE_NORMALIZE flag indicates that a normalized -** representation of the SQL statement should be calculated and then -** associated with the prepared statement, which can be obtained via -** the [sqlite3_normalized_sql()] interface.)^ The semantics used to -** normalize a SQL statement are unspecified and subject to change. -** At a minimum, literal values will be replaced with suitable -** placeholders. +** [[SQLITE_PREPARE_NORMALIZE]] <dt>SQLITE_PREPARE_NORMALIZE</dt> +** <dd>The SQLITE_PREPARE_NORMALIZE flag is a no-op. This flag used +** to be required for any prepared statement that wanted to use the +** [sqlite3_normalized_sql()] interface. However, the +** [sqlite3_normalized_sql()] interface is now available to all +** prepared statements, regardless of whether or not they use this +** flag. +** +** [[SQLITE_PREPARE_NO_VTAB]] <dt>SQLITE_PREPARE_NO_VTAB</dt> +** <dd>The SQLITE_PREPARE_NO_VTAB flag causes the SQL compiler +** to return an error (error code SQLITE_ERROR) if the statement uses +** any virtual tables. ** </dl> */ #define SQLITE_PREPARE_PERSISTENT 0x01 #define SQLITE_PREPARE_NORMALIZE 0x02 +#define SQLITE_PREPARE_NO_VTAB 0x04 /* ** CAPI3REF: Compiling An SQL Statement @@ -11035,7 +11064,7 @@ SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter); ** sqlite3changeset_next() is called on the iterator or until the ** conflict-handler function returns. If pnCol is not NULL, then *pnCol is ** set to the number of columns in the table affected by the change. If -** pbIncorrect is not NULL, then *pbIndirect is set to true (1) if the change +** pbIndirect is not NULL, then *pbIndirect is set to true (1) if the change ** is an indirect change, or false (0) otherwise. See the documentation for ** [sqlite3session_indirect()] for a description of direct and indirect ** changes. Finally, if pOp is not NULL, then *pOp is set to one of @@ -12269,12 +12298,8 @@ struct Fts5PhraseIter { ** ** Usually, output parameter *piPhrase is set to the phrase number, *piCol ** to the column in which it occurs and *piOff the token offset of the -** first token of the phrase. The exception is if the table was created -** with the offsets=0 option specified. In this case *piOff is always -** set to -1. -** -** Returns SQLITE_OK if successful, or an error code (i.e. SQLITE_NOMEM) -** if an error occurs. +** first token of the phrase. Returns SQLITE_OK if successful, or an error +** code (i.e. SQLITE_NOMEM) if an error occurs. ** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. @@ -12563,11 +12588,11 @@ struct Fts5ExtensionApi { ** the tokenizer substitutes "first" for "1st" and the query works ** as expected. ** -** <li> By adding multiple synonyms for a single term to the FTS index. -** In this case, when tokenizing query text, the tokenizer may -** provide multiple synonyms for a single term within the document. -** FTS5 then queries the index for each synonym individually. For -** example, faced with the query: +** <li> By querying the index for all synonyms of each query term +** separately. In this case, when tokenizing query text, the +** tokenizer may provide multiple synonyms for a single term +** within the document. FTS5 then queries the index for each +** synonym individually. For example, faced with the query: ** ** <codeblock> ** ... MATCH 'first place'</codeblock> @@ -12591,7 +12616,7 @@ struct Fts5ExtensionApi { ** "place". ** ** This way, even if the tokenizer does not provide synonyms -** when tokenizing query text (it should not - to do would be +** when tokenizing query text (it should not - to do so would be ** inefficient), it doesn't matter if the user queries for ** 'first + place' or '1st + place', as there are entries in the ** FTS index corresponding to both forms of the first token. @@ -14535,6 +14560,7 @@ SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor*); SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*); SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt); SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor*); +SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor*); SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*); SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*); @@ -14774,12 +14800,11 @@ typedef struct VdbeOpList VdbeOpList; #endif /* -** The following macro converts a relative address in the p2 field -** of a VdbeOp structure into a negative number so that -** sqlite3VdbeAddOpList() knows that the address is relative. Calling -** the macro again restores the address. +** The following macro converts a label returned by sqlite3VdbeMakeLabel() +** into an index into the Parse.aLabel[] array that contains the resolved +** address of that label. */ -#define ADDR(X) (-1-(X)) +#define ADDR(X) (~(X)) /* ** The makefile scans the vdbe.c source file and creates the "opcodes.h" @@ -15055,6 +15080,12 @@ SQLITE_PRIVATE int sqlite3VdbeExplainParent(Parse*); # define ExplainQueryPlan(P) # define ExplainQueryPlanPop(P) # define ExplainQueryPlanParent(P) 0 +# define sqlite3ExplainBreakpoint(A,B) /*no-op*/ +#endif +#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_EXPLAIN) +SQLITE_PRIVATE void sqlite3ExplainBreakpoint(const char*,const char*); +#else +# define sqlite3ExplainBreakpoint(A,B) /*no-op*/ #endif SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*); SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe*, u32 addr, u8); @@ -15070,7 +15101,7 @@ SQLITE_PRIVATE void sqlite3VdbeAppendP4(Vdbe*, void *pP4, int p4type); SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse*, Index*); SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int); SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); -SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe*); +SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Parse*); SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*); @@ -15091,6 +15122,10 @@ SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*); SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*); SQLITE_PRIVATE u8 sqlite3VdbePrepareFlags(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, u8); +#ifdef SQLITE_ENABLE_NORMALIZE +SQLITE_PRIVATE void sqlite3VdbeAddDblquoteStr(sqlite3*,Vdbe*,const char*); +SQLITE_PRIVATE int sqlite3VdbeUsesDoubleQuotedString(Vdbe*,const char*); +#endif SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*); SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*); SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8); @@ -16216,10 +16251,13 @@ SQLITE_PRIVATE void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**); /* This is an extra SQLITE_TRACE macro that indicates "legacy" tracing ** in the style of sqlite3_trace() */ -#define SQLITE_TRACE_LEGACY 0x80 +#define SQLITE_TRACE_LEGACY 0x40 /* Use the legacy xTrace */ +#define SQLITE_TRACE_XPROFILE 0x80 /* Use the legacy xProfile */ #else -#define SQLITE_TRACE_LEGACY 0 +#define SQLITE_TRACE_LEGACY 0 +#define SQLITE_TRACE_XPROFILE 0 #endif /* SQLITE_OMIT_DEPRECATED */ +#define SQLITE_TRACE_NONLEGACY_MASK 0x0f /* Normal flags */ /* @@ -16278,8 +16316,10 @@ struct sqlite3 { void **aExtension; /* Array of shared library handles */ int (*xTrace)(u32,void*,void*,void*); /* Trace function */ void *pTraceArg; /* Argument to the trace function */ +#ifndef SQLITE_OMIT_DEPRECATED void (*xProfile)(void*,const char*,u64); /* Profiling function */ void *pProfileArg; /* Argument to profile function */ +#endif void *pCommitArg; /* Argument to xCommitCallback() */ int (*xCommitCallback)(void*); /* Invoked at every commit. */ void *pRollbackArg; /* Argument to xRollbackCallback() */ @@ -16410,6 +16450,7 @@ struct sqlite3 { #define SQLITE_VdbeTrace HI(0x0004) /* True to trace VDBE execution */ #define SQLITE_VdbeAddopTrace HI(0x0008) /* Trace sqlite3VdbeAddOp() calls */ #define SQLITE_VdbeEQP HI(0x0010) /* Debug EXPLAIN QUERY PLAN */ +#define SQLITE_ParserTrace HI(0x0020) /* PRAGMA parser_trace=ON */ #endif /* @@ -16812,9 +16853,6 @@ struct VTable { struct Table { char *zName; /* Name of the table or view */ Column *aCol; /* Information about each column */ -#ifdef SQLITE_ENABLE_NORMALIZE - Hash *pColHash; /* All columns indexed by name */ -#endif Index *pIndex; /* List of SQL indexes on this table. */ Select *pSelect; /* NULL for tables. Points to definition if a view. */ FKey *pFKey; /* Linked list of all foreign keys in this table */ @@ -17101,7 +17139,7 @@ struct Index { u16 nKeyCol; /* Number of columns forming the key */ u16 nColumn; /* Number of columns stored in the index */ u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ - unsigned idxType:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */ + unsigned idxType:2; /* 0:Normal 1:UNIQUE, 2:PRIMARY KEY, 3:IPK */ unsigned bUnordered:1; /* Use this index for == or IN queries only */ unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */ unsigned isResized:1; /* True if resizeIndexObject() has been called */ @@ -17126,6 +17164,7 @@ struct Index { #define SQLITE_IDXTYPE_APPDEF 0 /* Created using CREATE INDEX */ #define SQLITE_IDXTYPE_UNIQUE 1 /* Implements a UNIQUE constraint */ #define SQLITE_IDXTYPE_PRIMARYKEY 2 /* Is the PRIMARY KEY for the table */ +#define SQLITE_IDXTYPE_IPK 3 /* INTEGER PRIMARY KEY index */ /* Return true if index X is a PRIMARY KEY index */ #define IsPrimaryKeyIndex(X) ((X)->idxType==SQLITE_IDXTYPE_PRIMARYKEY) @@ -17343,6 +17382,10 @@ struct Expr { Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL ** for a column of an index on an expression */ Window *pWin; /* TK_FUNCTION: Window definition for the func */ + struct { /* TK_IN, TK_SELECT, and TK_EXISTS */ + int iAddr; /* Subroutine entry address */ + int regReturn; /* Register used to hold return address */ + } sub; } y; }; @@ -17374,6 +17417,8 @@ struct Expr { #define EP_Alias 0x400000 /* Is an alias for a result set column */ #define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */ #define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */ +#define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */ +#define EP_Quoted 0x4000000 /* TK_ID was originally quoted */ /* ** The EP_Propagate mask is a set of properties that automatically propagate @@ -17917,16 +17962,17 @@ struct Parse { u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */ u8 okConstFactor; /* OK to factor out constants */ u8 disableLookaside; /* Number of times lookaside has been disabled */ + u8 disableVtab; /* Disable all virtual tables for this parse */ int nRangeReg; /* Size of the temporary register block */ int iRangeReg; /* First register in temporary register block */ int nErr; /* Number of errors seen */ int nTab; /* Number of previously allocated VDBE cursors */ int nMem; /* Number of memory cells used so far */ - int nOpAlloc; /* Number of slots allocated for Vdbe.aOp[] */ int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */ int iSelfTab; /* Table associated with an index on expr, or negative ** of the base register during check-constraint eval */ - int nLabel; /* Number of labels used */ + int nLabel; /* The *negative* of the number of labels used */ + int nLabelAlloc; /* Number of slots in aLabel */ int *aLabel; /* Space to hold the labels */ ExprList *pConstExpr;/* Constant expressions */ Token constraintName;/* Name of the constraint currently being parsed */ @@ -17986,7 +18032,9 @@ struct Parse { Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */ const char *zTail; /* All SQL text past the last semicolon parsed */ Table *pNewTable; /* A table being constructed by CREATE TABLE */ - Index *pNewIndex; /* An index being constructed by CREATE INDEX */ + Index *pNewIndex; /* An index being constructed by CREATE INDEX. + ** Also used to hold redundant UNIQUE constraints + ** during a RENAME COLUMN */ Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */ const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */ #ifndef SQLITE_OMIT_VIRTUALTABLE @@ -18214,6 +18262,7 @@ typedef struct { int iDb; /* 0 for main database. 1 for TEMP, 2.. for ATTACHed */ int rc; /* Result code stored here */ u32 mInitFlags; /* Flags controlling error messages */ + u32 nInitRow; /* Number of rows processed */ } InitData; /* @@ -18274,6 +18323,9 @@ struct Sqlite3Config { void (*xVdbeBranch)(void*,unsigned iSrcLine,u8 eThis,u8 eMx); /* Callback */ void *pVdbeBranchArg; /* 1st argument */ #endif +#ifdef SQLITE_ENABLE_DESERIALIZE + sqlite3_int64 mxMemdbSize; /* Default max memdb size */ +#endif #ifndef SQLITE_UNTESTABLE int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */ #endif @@ -18662,6 +18714,7 @@ SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8); SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*); SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...); SQLITE_PRIVATE void sqlite3Dequote(char*); +SQLITE_PRIVATE void sqlite3DequoteExpr(Expr*); SQLITE_PRIVATE void sqlite3TokenInit(Token*,char*); SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int); SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*, char **); @@ -18690,6 +18743,7 @@ SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int); SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*); SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*); SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*); +SQLITE_PRIVATE int sqlite3IndexHasDuplicateRootPage(Index*); SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**); SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**); SQLITE_PRIVATE int sqlite3InitOne(sqlite3*, int, char**, u32); @@ -18723,6 +18777,11 @@ SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*); SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*); SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*, sqlite3_vfs**,char**,char **); +#ifdef SQLITE_HAS_CODEC +SQLITE_PRIVATE int sqlite3CodecQueryParameters(sqlite3*,const char*,const char*); +#else +# define sqlite3CodecQueryParameters(A,B,C) 0 +#endif SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3*,const char*); #ifdef SQLITE_UNTESTABLE @@ -18775,8 +18834,8 @@ SQLITE_PRIVATE void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int, Upser SQLITE_PRIVATE void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*); SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse*, IdList*, Token*); SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*); -SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(sqlite3*, SrcList*, int, int); -SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(sqlite3*, SrcList*, Token*, Token*); +SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(Parse*, SrcList*, int, int); +SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*); SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*, Token*, Select*, Expr*, IdList*); SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *); @@ -18843,8 +18902,8 @@ SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,u32 flags,struct SrcList_ite SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*); SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*); SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); -SQLITE_PRIVATE void sqlite3Vacuum(Parse*,Token*); -SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*, int); +SQLITE_PRIVATE void sqlite3Vacuum(Parse*,Token*,Expr*); +SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*, int, sqlite3_value*); SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*); SQLITE_PRIVATE int sqlite3ExprCompare(Parse*,Expr*, Expr*, int); SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr*, Expr*, int); @@ -18882,9 +18941,6 @@ SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*); SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*); SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); SQLITE_PRIVATE int sqlite3IsRowid(const char*); -#ifdef SQLITE_ENABLE_NORMALIZE -SQLITE_PRIVATE int sqlite3IsRowidN(const char*, int); -#endif SQLITE_PRIVATE void sqlite3GenerateRowDelete( Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int); SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int); @@ -18911,9 +18967,7 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int); SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int); SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*); SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int); -#ifdef SQLITE_ENABLE_NORMALIZE -SQLITE_PRIVATE FuncDef *sqlite3FunctionSearchN(int,const char*,int); -#endif +SQLITE_PRIVATE FuncDef *sqlite3FunctionSearch(int,const char*); SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(FuncDef*,int); SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8); SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void); @@ -19118,19 +19172,17 @@ SQLITE_PRIVATE void sqlite3AlterFunctions(void); SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*); SQLITE_PRIVATE void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*); SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *); -#ifdef SQLITE_ENABLE_NORMALIZE -SQLITE_PRIVATE int sqlite3GetTokenNormalized(const unsigned char *, int *, int *); -#endif SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...); SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*, int); -SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr *, int, int); +SQLITE_PRIVATE void sqlite3CodeRhsOfIN(Parse*, Expr*, int, int); +SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr*); SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*); SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p); SQLITE_PRIVATE int sqlite3MatchSpanName(const char*, const char*, const char*, const char*); SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*); SQLITE_PRIVATE int sqlite3ResolveExprListNames(NameContext*, ExprList*); SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*); -SQLITE_PRIVATE void sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*); +SQLITE_PRIVATE int sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*); SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*); SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int); SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *); @@ -19279,7 +19331,7 @@ SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int); SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); SQLITE_PRIVATE void sqlite3ParserReset(Parse*); #ifdef SQLITE_ENABLE_NORMALIZE -SQLITE_PRIVATE void sqlite3Normalize(Vdbe*, const char*, int, u8); +SQLITE_PRIVATE char *sqlite3Normalize(Vdbe*, const char*); #endif SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*); SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*); @@ -19375,7 +19427,7 @@ SQLITE_PRIVATE void sqlite3EndBenignMalloc(void); #define IN_INDEX_NOOP_OK 0x0001 /* OK to return IN_INDEX_NOOP */ #define IN_INDEX_MEMBERSHIP 0x0002 /* IN operator used for membership test */ #define IN_INDEX_LOOP 0x0004 /* IN operator used as a loop */ -SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*, int*); +SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*, int*, int*); SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int); SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *); @@ -19691,6 +19743,13 @@ SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = { #endif +/* The default maximum size of an in-memory database created using +** sqlite3_deserialize() +*/ +#ifndef SQLITE_MEMDB_DEFAULT_MAXSIZE +# define SQLITE_MEMDB_DEFAULT_MAXSIZE 1073741824 +#endif + /* ** The following singleton contains the global configuration for ** the SQLite library. @@ -19738,13 +19797,16 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { 0, /* xVdbeBranch */ 0, /* pVbeBranchArg */ #endif +#ifdef SQLITE_ENABLE_DESERIALIZE + SQLITE_MEMDB_DEFAULT_MAXSIZE, /* mxMemdbSize */ +#endif #ifndef SQLITE_UNTESTABLE 0, /* xTestCallback */ #endif 0, /* bLocaltimeFault */ 0, /* bInternalFunctions */ 0x7ffffffe, /* iOnceResetThreshold */ - SQLITE_DEFAULT_SORTERREF_SIZE /* szSorterRef */ + SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */ }; /* @@ -20163,6 +20225,9 @@ struct sqlite3_context { */ typedef unsigned bft; /* Bit Field Type */ +/* The ScanStatus object holds a single value for the +** sqlite3_stmt_scanstatus() interface. +*/ typedef struct ScanStatus ScanStatus; struct ScanStatus { int addrExplain; /* OP_Explain for loop */ @@ -20173,6 +20238,19 @@ struct ScanStatus { char *zName; /* Name of table or index */ }; +/* The DblquoteStr object holds the text of a double-quoted +** string for a prepared statement. A linked list of these objects +** is constructed during statement parsing and is held on Vdbe.pDblStr. +** When computing a normalized SQL statement for an SQL statement, that +** list is consulted for each double-quoted identifier to see if the +** identifier should really be a string literal. +*/ +typedef struct DblquoteStr DblquoteStr; +struct DblquoteStr { + DblquoteStr *pNextStr; /* Next string literal in the list */ + char z[8]; /* Dequoted value for the string */ +}; + /* ** An instance of the virtual machine. This structure contains the complete ** state of the virtual machine. @@ -20192,28 +20270,29 @@ struct Vdbe { int pc; /* The program counter */ int rc; /* Value to return */ int nChange; /* Number of db changes made since last reset */ - int iStatement; /* Statement number (or 0 if has not opened stmt) */ + int iStatement; /* Statement number (or 0 if has no opened stmt) */ i64 iCurrentTime; /* Value of julianday('now') for this statement */ i64 nFkConstraint; /* Number of imm. FK constraints this VM */ i64 nStmtDefCons; /* Number of def. constraints when stmt started */ i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */ + Mem *aMem; /* The memory locations */ + Mem **apArg; /* Arguments to currently executing user function */ + VdbeCursor **apCsr; /* One element of this array for each open cursor */ + Mem *aVar; /* Values for the OP_Variable opcode. */ /* When allocating a new Vdbe object, all of the fields below should be ** initialized to zero or NULL */ Op *aOp; /* Space to hold the virtual machine's program */ - Mem *aMem; /* The memory locations */ - Mem **apArg; /* Arguments to currently executing user function */ + int nOp; /* Number of instructions in the program */ + int nOpAlloc; /* Slots allocated for aOp[] */ Mem *aColName; /* Column names to return */ Mem *pResultSet; /* Pointer to an array of results */ char *zErrMsg; /* Error message written here */ - VdbeCursor **apCsr; /* One element of this array for each open cursor */ - Mem *aVar; /* Values for the OP_Variable opcode. */ VList *pVList; /* Name of variables */ #ifndef SQLITE_OMIT_TRACE i64 startTime; /* Time when query started - used for profiling */ #endif - int nOp; /* Number of instructions in the program */ #ifdef SQLITE_DEBUG int rcApp; /* errcode set by sqlite3_result_error_code() */ u32 nWrite; /* Number of write operations that have occurred */ @@ -20236,6 +20315,7 @@ struct Vdbe { char *zSql; /* Text of the SQL statement that generated this */ #ifdef SQLITE_ENABLE_NORMALIZE char *zNormSql; /* Normalization of the associated SQL statement */ + DblquoteStr *pDblStr; /* List of double-quoted string literals */ #endif void *pFree; /* Free this when deleting the vdbe */ VdbeFrame *pFrame; /* Parent frame */ @@ -27253,6 +27333,27 @@ static char *getTextArg(PrintfArguments *p){ return (char*)sqlite3_value_text(p->apArg[p->nUsed++]); } +/* +** Allocate memory for a temporary buffer needed for printf rendering. +** +** If the requested size of the temp buffer is larger than the size +** of the output buffer in pAccum, then cause an SQLITE_TOOBIG error. +** Do the size check before the memory allocation to prevent rogue +** SQL from requesting large allocations using the precision or width +** field of the printf() function. +*/ +static char *printfTempBuf(sqlite3_str *pAccum, sqlite3_int64 n){ + char *z; + if( n>pAccum->nAlloc && n>pAccum->mxAlloc ){ + setStrAccumError(pAccum, SQLITE_TOOBIG); + return 0; + } + z = sqlite3DbMallocRaw(pAccum->db, n); + if( z==0 ){ + setStrAccumError(pAccum, SQLITE_NOMEM); + } + return z; +} /* ** On machines with a small stack size, you can redefine the @@ -27335,6 +27436,9 @@ SQLITE_API void sqlite3_str_vappendf( flag_leftjustify = flag_prefix = cThousand = flag_alternateform = flag_altform2 = flag_zeropad = 0; done = 0; + width = 0; + flag_long = 0; + precision = -1; do{ switch( c ){ case '-': flag_leftjustify = 1; break; @@ -27345,80 +27449,93 @@ SQLITE_API void sqlite3_str_vappendf( case '0': flag_zeropad = 1; break; case ',': cThousand = ','; break; default: done = 1; break; + case 'l': { + flag_long = 1; + c = *++fmt; + if( c=='l' ){ + c = *++fmt; + flag_long = 2; + } + done = 1; + break; + } + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': { + unsigned wx = c - '0'; + while( (c = *++fmt)>='0' && c<='9' ){ + wx = wx*10 + c - '0'; + } + testcase( wx>0x7fffffff ); + width = wx & 0x7fffffff; +#ifdef SQLITE_PRINTF_PRECISION_LIMIT + if( width>SQLITE_PRINTF_PRECISION_LIMIT ){ + width = SQLITE_PRINTF_PRECISION_LIMIT; + } +#endif + if( c!='.' && c!='l' ){ + done = 1; + }else{ + fmt--; + } + break; + } + case '*': { + if( bArgList ){ + width = (int)getIntArg(pArgList); + }else{ + width = va_arg(ap,int); + } + if( width<0 ){ + flag_leftjustify = 1; + width = width >= -2147483647 ? -width : 0; + } +#ifdef SQLITE_PRINTF_PRECISION_LIMIT + if( width>SQLITE_PRINTF_PRECISION_LIMIT ){ + width = SQLITE_PRINTF_PRECISION_LIMIT; + } +#endif + if( (c = fmt[1])!='.' && c!='l' ){ + c = *++fmt; + done = 1; + } + break; + } + case '.': { + c = *++fmt; + if( c=='*' ){ + if( bArgList ){ + precision = (int)getIntArg(pArgList); + }else{ + precision = va_arg(ap,int); + } + if( precision<0 ){ + precision = precision >= -2147483647 ? -precision : -1; + } + c = *++fmt; + }else{ + unsigned px = 0; + while( c>='0' && c<='9' ){ + px = px*10 + c - '0'; + c = *++fmt; + } + testcase( px>0x7fffffff ); + precision = px & 0x7fffffff; + } +#ifdef SQLITE_PRINTF_PRECISION_LIMIT + if( precision>SQLITE_PRINTF_PRECISION_LIMIT ){ + precision = SQLITE_PRINTF_PRECISION_LIMIT; + } +#endif + if( c=='l' ){ + --fmt; + }else{ + done = 1; + } + break; + } } }while( !done && (c=(*++fmt))!=0 ); - /* Get the field width */ - if( c=='*' ){ - if( bArgList ){ - width = (int)getIntArg(pArgList); - }else{ - width = va_arg(ap,int); - } - if( width<0 ){ - flag_leftjustify = 1; - width = width >= -2147483647 ? -width : 0; - } - c = *++fmt; - }else{ - unsigned wx = 0; - while( c>='0' && c<='9' ){ - wx = wx*10 + c - '0'; - c = *++fmt; - } - testcase( wx>0x7fffffff ); - width = wx & 0x7fffffff; - } - assert( width>=0 ); -#ifdef SQLITE_PRINTF_PRECISION_LIMIT - if( width>SQLITE_PRINTF_PRECISION_LIMIT ){ - width = SQLITE_PRINTF_PRECISION_LIMIT; - } -#endif - /* Get the precision */ - if( c=='.' ){ - c = *++fmt; - if( c=='*' ){ - if( bArgList ){ - precision = (int)getIntArg(pArgList); - }else{ - precision = va_arg(ap,int); - } - c = *++fmt; - if( precision<0 ){ - precision = precision >= -2147483647 ? -precision : -1; - } - }else{ - unsigned px = 0; - while( c>='0' && c<='9' ){ - px = px*10 + c - '0'; - c = *++fmt; - } - testcase( px>0x7fffffff ); - precision = px & 0x7fffffff; - } - }else{ - precision = -1; - } - assert( precision>=(-1) ); -#ifdef SQLITE_PRINTF_PRECISION_LIMIT - if( precision>SQLITE_PRINTF_PRECISION_LIMIT ){ - precision = SQLITE_PRINTF_PRECISION_LIMIT; - } -#endif - - - /* Get the conversion type modifier */ - if( c=='l' ){ - flag_long = 1; - c = *++fmt; - if( c=='l' ){ - flag_long = 2; - c = *++fmt; - } - }else{ - flag_long = 0; - } /* Fetch the info entry for the field */ infop = &fmtinfo[0]; xtype = etINVALID; @@ -27503,12 +27620,11 @@ SQLITE_API void sqlite3_str_vappendf( nOut = etBUFSIZE; zOut = buf; }else{ - u64 n = (u64)precision + 10 + precision/3; - zOut = zExtra = sqlite3Malloc( n ); - if( zOut==0 ){ - setStrAccumError(pAccum, SQLITE_NOMEM); - return; - } + u64 n; + n = (u64)precision + 10; + if( cThousand ) n += precision/3; + zOut = zExtra = printfTempBuf(pAccum, n); + if( zOut==0 ) return; nOut = (int)n; } bufpt = &zOut[nOut-1]; @@ -27627,12 +27743,12 @@ SQLITE_API void sqlite3_str_vappendf( }else{ e2 = exp; } - if( MAX(e2,0)+(i64)precision+(i64)width > etBUFSIZE - 15 ){ - bufpt = zExtra - = sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 ); - if( bufpt==0 ){ - setStrAccumError(pAccum, SQLITE_NOMEM); - return; + { + i64 szBufNeeded; /* Size of a temporary buffer needed */ + szBufNeeded = MAX(e2,0)+(i64)precision+(i64)width+15; + if( szBufNeeded > etBUFSIZE ){ + bufpt = zExtra = printfTempBuf(pAccum, szBufNeeded); + if( bufpt==0 ) return; } } zOut = bufpt; @@ -27856,11 +27972,8 @@ SQLITE_API void sqlite3_str_vappendf( needQuote = !isnull && xtype==etSQLESCAPE2; n += i + 3; if( n>etBUFSIZE ){ - bufpt = zExtra = sqlite3Malloc( n ); - if( bufpt==0 ){ - setStrAccumError(pAccum, SQLITE_NOMEM); - return; - } + bufpt = zExtra = printfTempBuf(pAccum, n); + if( bufpt==0 ) return; }else{ bufpt = buf; } @@ -28486,7 +28599,8 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc) sqlite3_str_appendf(&x, " %s", pItem->zName); } if( pItem->pTab ){ - sqlite3_str_appendf(&x, " tabname=%Q", pItem->pTab->zName); + sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p", + pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab); } if( pItem->zAlias ){ sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias); @@ -30226,7 +30340,7 @@ SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){ ** dequoted string, exclusive of the zero terminator, if dequoting does ** occur. ** -** 2002-Feb-14: This routine is extended to remove MS-Access style +** 2002-02-14: This routine is extended to remove MS-Access style ** brackets from around identifiers. For example: "[a-b-c]" becomes ** "a-b-c". */ @@ -30252,6 +30366,11 @@ SQLITE_PRIVATE void sqlite3Dequote(char *z){ } z[j] = 0; } +SQLITE_PRIVATE void sqlite3DequoteExpr(Expr *p){ + assert( sqlite3Isquote(p->u.zToken[0]) ); + p->flags |= p->u.zToken[0]=='"' ? EP_Quoted|EP_DblQuoted : EP_Quoted; + sqlite3Dequote(p->u.zToken); +} /* ** Generate a Token object from a string @@ -31679,20 +31798,6 @@ static unsigned int strHash(const char *z){ } return h; } -#ifdef SQLITE_ENABLE_NORMALIZE -static unsigned int strHashN(const char *z, int n){ - unsigned int h = 0; - int i; - for(i=0; i<n; i++){ - /* Knuth multiplicative hashing. (Sorting & Searching, p. 510). - ** 0x9e3779b1 is 2654435761 which is the closest prime number to - ** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. */ - h += sqlite3UpperToLower[z[i]]; - h *= 0x9e3779b1; - } - return h; -} -#endif /* SQLITE_ENABLE_NORMALIZE */ /* Link pNew element into the hash table pH. If pEntry!=0 then also @@ -31804,40 +31909,6 @@ static HashElem *findElementWithHash( } return &nullElement; } -#ifdef SQLITE_ENABLE_NORMALIZE -static HashElem *findElementWithHashN( - const Hash *pH, /* The pH to be searched */ - const char *pKey, /* The key we are searching for */ - int nKey, /* Number of key bytes to use */ - unsigned int *pHash /* Write the hash value here */ -){ - HashElem *elem; /* Used to loop thru the element list */ - int count; /* Number of elements left to test */ - unsigned int h; /* The computed hash */ - static HashElem nullElement = { 0, 0, 0, 0 }; - - if( pH->ht ){ /*OPTIMIZATION-IF-TRUE*/ - struct _ht *pEntry; - h = strHashN(pKey, nKey) % pH->htsize; - pEntry = &pH->ht[h]; - elem = pEntry->chain; - count = pEntry->count; - }else{ - h = 0; - elem = pH->first; - count = pH->count; - } - if( pHash ) *pHash = h; - while( count-- ){ - assert( elem!=0 ); - if( sqlite3StrNICmp(elem->pKey,pKey,nKey)==0 ){ - return elem; - } - elem = elem->next; - } - return &nullElement; -} -#endif /* SQLITE_ENABLE_NORMALIZE */ /* Remove a single entry from the hash table given a pointer to that ** element and a hash on the element's key. @@ -31882,14 +31953,6 @@ SQLITE_PRIVATE void *sqlite3HashFind(const Hash *pH, const char *pKey){ assert( pKey!=0 ); return findElementWithHash(pH, pKey, 0)->data; } -#ifdef SQLITE_ENABLE_NORMALIZE -SQLITE_PRIVATE void *sqlite3HashFindN(const Hash *pH, const char *pKey, int nKey){ - assert( pH!=0 ); - assert( pKey!=0 ); - assert( nKey>=0 ); - return findElementWithHashN(pH, pKey, nKey, 0)->data; -} -#endif /* SQLITE_ENABLE_NORMALIZE */ /* Insert an element into the hash table pH. The key is pKey ** and the data is "data". @@ -46577,7 +46640,8 @@ typedef struct MemFile MemFile; struct MemFile { sqlite3_file base; /* IO methods */ sqlite3_int64 sz; /* Size of the file */ - sqlite3_int64 szMax; /* Space allocated to aData */ + sqlite3_int64 szAlloc; /* Space allocated to aData */ + sqlite3_int64 szMax; /* Maximum allowed size of the file */ unsigned char *aData; /* content of the file */ int nMmap; /* Number of memory mapped pages */ unsigned mFlags; /* Flags */ @@ -46703,10 +46767,15 @@ static int memdbEnlarge(MemFile *p, sqlite3_int64 newSz){ if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || p->nMmap>0 ){ return SQLITE_FULL; } + if( newSz>p->szMax ){ + return SQLITE_FULL; + } + newSz *= 2; + if( newSz>p->szMax ) newSz = p->szMax; pNew = sqlite3_realloc64(p->aData, newSz); if( pNew==0 ) return SQLITE_NOMEM; p->aData = pNew; - p->szMax = newSz; + p->szAlloc = newSz; return SQLITE_OK; } @@ -46720,10 +46789,11 @@ static int memdbWrite( sqlite_int64 iOfst ){ MemFile *p = (MemFile *)pFile; + if( NEVER(p->mFlags & SQLITE_DESERIALIZE_READONLY) ) return SQLITE_READONLY; if( iOfst+iAmt>p->sz ){ int rc; - if( iOfst+iAmt>p->szMax - && (rc = memdbEnlarge(p, (iOfst+iAmt)*2))!=SQLITE_OK + if( iOfst+iAmt>p->szAlloc + && (rc = memdbEnlarge(p, iOfst+iAmt))!=SQLITE_OK ){ return rc; } @@ -46769,6 +46839,11 @@ static int memdbFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ */ static int memdbLock(sqlite3_file *pFile, int eLock){ MemFile *p = (MemFile *)pFile; + if( eLock>SQLITE_LOCK_SHARED + && (p->mFlags & SQLITE_DESERIALIZE_READONLY)!=0 + ){ + return SQLITE_READONLY; + } p->eLock = eLock; return SQLITE_OK; } @@ -46793,6 +46868,19 @@ static int memdbFileControl(sqlite3_file *pFile, int op, void *pArg){ *(char**)pArg = sqlite3_mprintf("memdb(%p,%lld)", p->aData, p->sz); rc = SQLITE_OK; } + if( op==SQLITE_FCNTL_SIZE_LIMIT ){ + sqlite3_int64 iLimit = *(sqlite3_int64*)pArg; + if( iLimit<p->sz ){ + if( iLimit<0 ){ + iLimit = p->szMax; + }else{ + iLimit = p->sz; + } + } + p->szMax = iLimit; + *(sqlite3_int64*)pArg = iLimit; + rc = SQLITE_OK; + } return rc; } @@ -46823,8 +46911,12 @@ static int memdbFetch( void **pp ){ MemFile *p = (MemFile *)pFile; - p->nMmap++; - *pp = (void*)(p->aData + iOfst); + if( iOfst+iAmt>p->sz ){ + *pp = 0; + }else{ + p->nMmap++; + *pp = (void*)(p->aData + iOfst); + } return SQLITE_OK; } @@ -46854,6 +46946,7 @@ static int memdbOpen( assert( pOutFlags!=0 ); /* True because flags==SQLITE_OPEN_MAIN_DB */ *pOutFlags = flags | SQLITE_OPEN_MEMORY; p->base.pMethods = &memdb_io_methods; + p->szMax = sqlite3GlobalConfig.mxMemdbSize; return SQLITE_OK; } @@ -47103,7 +47196,11 @@ SQLITE_API int sqlite3_deserialize( }else{ p->aData = pData; p->sz = szDb; + p->szAlloc = szBuf; p->szMax = szBuf; + if( p->szMax<sqlite3GlobalConfig.mxMemdbSize ){ + p->szMax = sqlite3GlobalConfig.mxMemdbSize; + } p->mFlags = mFlags; rc = SQLITE_OK; } @@ -48524,16 +48621,27 @@ typedef struct PGroup PGroup; ** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of ** PgHdr1.pCache->szPage bytes is allocated directly before this structure ** in memory. +** +** Note: Variables isBulkLocal and isAnchor were once type "u8". That works, +** but causes a 2-byte gap in the structure for most architectures (since +** pointers must be either 4 or 8-byte aligned). As this structure is located +** in memory directly after the associated page data, if the database is +** corrupt, code at the b-tree layer may overread the page buffer and +** read part of this structure before the corruption is detected. This +** can cause a valgrind error if the unitialized gap is accessed. Using u16 +** ensures there is no such gap, and therefore no bytes of unitialized memory +** in the structure. */ struct PgHdr1 { sqlite3_pcache_page page; /* Base class. Must be first. pBuf & pExtra */ unsigned int iKey; /* Key value (page number) */ - u8 isBulkLocal; /* This page from bulk local storage */ - u8 isAnchor; /* This is the PGroup.lru element */ + u16 isBulkLocal; /* This page from bulk local storage */ + u16 isAnchor; /* This is the PGroup.lru element */ PgHdr1 *pNext; /* Next in hash table chain */ PCache1 *pCache; /* Cache that currently owns this page */ PgHdr1 *pLruNext; /* Next in LRU list of unpinned pages */ PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */ + /* NB: pLruPrev is only valid if pLruNext!=0 */ }; /* @@ -48599,6 +48707,7 @@ struct PCache1 { unsigned int nMax; /* Configured "cache_size" value */ unsigned int n90pct; /* nMax*9/10 */ unsigned int iMaxKey; /* Largest key seen since xTruncate() */ + unsigned int nPurgeableDummy; /* pnPurgeable points here when not used*/ /* Hash table of all pages. The following variables may only be accessed ** when the accessor is holding the PGroup mutex. @@ -48733,6 +48842,7 @@ static int pcache1InitBulk(PCache1 *pCache){ pX->isBulkLocal = 1; pX->isAnchor = 0; pX->pNext = pCache->pFree; + pX->pLruPrev = 0; /* Initializing this saves a valgrind error */ pCache->pFree = pX; zBulk += pCache->szAlloc; }while( --nBulk ); @@ -48908,6 +49018,9 @@ static void pcache1FreePage(PgHdr1 *p){ ** exists, this function falls back to sqlite3Malloc(). */ SQLITE_PRIVATE void *sqlite3PageMalloc(int sz){ + /* During rebalance operations on a corrupt database file, it is sometimes + ** (rarely) possible to overread the temporary page buffer by a few bytes. + ** Enlarge the allocation slightly so that this does not cause problems. */ return pcache1Alloc(sz); } @@ -49002,7 +49115,8 @@ static PgHdr1 *pcache1PinPage(PgHdr1 *pPage){ pPage->pLruPrev->pLruNext = pPage->pLruNext; pPage->pLruNext->pLruPrev = pPage->pLruPrev; pPage->pLruNext = 0; - pPage->pLruPrev = 0; + /* pPage->pLruPrev = 0; + ** No need to clear pLruPrev as it is never accessed if pLruNext is 0 */ assert( pPage->isAnchor==0 ); assert( pPage->pCache->pGroup->lru.isAnchor==1 ); pPage->pCache->nRecyclable--; @@ -49212,8 +49326,7 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){ pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; pCache->pnPurgeable = &pGroup->nPurgeable; }else{ - static unsigned int dummyCurrentPage; - pCache->pnPurgeable = &dummyCurrentPage; + pCache->pnPurgeable = &pCache->nPurgeableDummy; } pcache1LeaveMutex(pGroup); if( pCache->nHash==0 ){ @@ -49340,8 +49453,9 @@ static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2( pPage->iKey = iKey; pPage->pNext = pCache->apHash[h]; pPage->pCache = pCache; - pPage->pLruPrev = 0; pPage->pLruNext = 0; + /* pPage->pLruPrev = 0; + ** No need to clear pLruPrev since it is not accessed when pLruNext==0 */ *(void **)pPage->page.pExtra = 0; pCache->apHash[h] = pPage; if( iKey>pCache->iMaxKey ){ @@ -49501,7 +49615,7 @@ static void pcache1Unpin( /* It is an error to call this function if the page is already ** part of the PGroup LRU list. */ - assert( pPage->pLruPrev==0 && pPage->pLruNext==0 ); + assert( pPage->pLruNext==0 ); assert( PAGE_IS_PINNED(pPage) ); if( reuseUnlikely || pGroup->nPurgeable>pGroup->nMaxPage ){ @@ -54192,7 +54306,10 @@ SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager *pPager, int mxPage){ pPager->mxPgno = mxPage; } assert( pPager->eState!=PAGER_OPEN ); /* Called only by OP_MaxPgcnt */ - assert( pPager->mxPgno>=pPager->dbSize ); /* OP_MaxPgcnt enforces this */ + /* assert( pPager->mxPgno>=pPager->dbSize ); */ + /* OP_MaxPgcnt ensures that the parameter passed to this function is not + ** less than the total number of valid pages in the database. But this + ** may be less than Pager.dbSize, and so the assert() above is not valid */ return pPager->mxPgno; } @@ -62431,9 +62548,16 @@ struct CellInfo { ** found at self->pBt->mutex. ** ** skipNext meaning: -** eState==SKIPNEXT && skipNext>0: Next sqlite3BtreeNext() is no-op. -** eState==SKIPNEXT && skipNext<0: Next sqlite3BtreePrevious() is no-op. -** eState==FAULT: Cursor fault with skipNext as error code. +** The meaning of skipNext depends on the value of eState: +** +** eState Meaning of skipNext +** VALID skipNext is meaningless and is ignored +** INVALID skipNext is meaningless and is ignored +** SKIPNEXT sqlite3BtreeNext() is a no-op if skipNext>0 and +** sqlite3BtreePrevious() is no-op if skipNext<0. +** REQUIRESEEK restoreCursorPosition() restores the cursor to +** eState=SKIPNEXT if skipNext!=0 +** FAULT skipNext holds the cursor fault error code. */ struct BtCursor { u8 eState; /* One of the CURSOR_XXX constants (see below) */ @@ -63597,13 +63721,19 @@ static int saveCursorKey(BtCursor *pCur){ /* Only the rowid is required for a table btree */ pCur->nKey = sqlite3BtreeIntegerKey(pCur); }else{ - /* For an index btree, save the complete key content */ + /* For an index btree, save the complete key content. It is possible + ** that the current key is corrupt. In that case, it is possible that + ** the sqlite3VdbeRecordUnpack() function may overread the buffer by + ** up to the size of 1 varint plus 1 8-byte value when the cursor + ** position is restored. Hence the 17 bytes of padding allocated + ** below. */ void *pKey; pCur->nKey = sqlite3BtreePayloadSize(pCur); - pKey = sqlite3Malloc( pCur->nKey ); + pKey = sqlite3Malloc( pCur->nKey + 9 + 8 ); if( pKey ){ rc = sqlite3BtreePayload(pCur, 0, (int)pCur->nKey, pKey); if( rc==SQLITE_OK ){ + memset(((u8*)pKey)+pCur->nKey, 0, 9+8); pCur->pKey = pKey; }else{ sqlite3_free(pKey); @@ -63735,11 +63865,12 @@ static int btreeMoveto( UnpackedRecord *pIdxKey; /* Unpacked index key */ if( pKey ){ + KeyInfo *pKeyInfo = pCur->pKeyInfo; assert( nKey==(i64)(int)nKey ); - pIdxKey = sqlite3VdbeAllocUnpackedRecord(pCur->pKeyInfo); + pIdxKey = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT; - sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey); - if( pIdxKey->nField==0 ){ + sqlite3VdbeRecordUnpack(pKeyInfo, (int)nKey, pKey, pIdxKey); + if( pIdxKey->nField==0 || pIdxKey->nField>pKeyInfo->nAllField ){ rc = SQLITE_CORRUPT_BKPT; goto moveto_done; } @@ -63775,7 +63906,7 @@ static int btreeRestoreCursorPosition(BtCursor *pCur){ sqlite3_free(pCur->pKey); pCur->pKey = 0; assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID ); - pCur->skipNext |= skipNext; + if( skipNext ) pCur->skipNext = skipNext; if( pCur->skipNext && pCur->eState==CURSOR_VALID ){ pCur->eState = CURSOR_SKIPNEXT; } @@ -63845,7 +63976,6 @@ SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow) if( pCur->eState!=CURSOR_VALID ){ *pDifferentRow = 1; }else{ - assert( pCur->skipNext==0 ); *pDifferentRow = 0; } return SQLITE_OK; @@ -63929,6 +64059,13 @@ static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){ *pRC = rc; return; } + if( ((char*)sqlite3PagerGetExtra(pDbPage))[0]!=0 ){ + /* The first byte of the extra data is the MemPage.isInit byte. + ** If that byte is set, it means this page is also being used + ** as a btree page. */ + *pRC = SQLITE_CORRUPT_BKPT; + goto ptrmap_exit; + } offset = PTRMAP_PTROFFSET(iPtrmap, key); if( offset<0 ){ *pRC = SQLITE_CORRUPT_BKPT; @@ -63991,7 +64128,7 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){ #else /* if defined SQLITE_OMIT_AUTOVACUUM */ #define ptrmapPut(w,x,y,z,rc) #define ptrmapGet(w,x,y,z) SQLITE_OK - #define ptrmapPutOvflPtr(x, y, rc) + #define ptrmapPutOvflPtr(x, y, z, rc) #endif /* @@ -64284,17 +64421,24 @@ static u16 cellSize(MemPage *pPage, int iCell){ #ifndef SQLITE_OMIT_AUTOVACUUM /* -** If the cell pCell, part of page pPage contains a pointer -** to an overflow page, insert an entry into the pointer-map -** for the overflow page. +** The cell pCell is currently part of page pSrc but will ultimately be part +** of pPage. (pSrc and pPager are often the same.) If pCell contains a +** pointer to an overflow page, insert an entry into the pointer-map for +** the overflow page that will be valid after pCell has been moved to pPage. */ -static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){ +static void ptrmapPutOvflPtr(MemPage *pPage, MemPage *pSrc, u8 *pCell,int *pRC){ CellInfo info; if( *pRC ) return; assert( pCell!=0 ); pPage->xParseCell(pPage, pCell, &info); if( info.nLocal<info.nPayload ){ - Pgno ovfl = get4byte(&pCell[info.nSize-4]); + Pgno ovfl; + if( SQLITE_WITHIN(pSrc->aDataEnd, pCell, pCell+info.nLocal) ){ + testcase( pSrc!=pPage ); + *pRC = SQLITE_CORRUPT_BKPT; + return; + } + ovfl = get4byte(&pCell[info.nSize-4]); ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC); } } @@ -64349,19 +64493,14 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){ ** reconstruct the entire page. */ if( (int)data[hdr+7]<=nMaxFrag ){ int iFree = get2byte(&data[hdr+1]); + + /* If the initial freeblock offset were out of bounds, that would + ** have been detected by btreeInitPage() when it was computing the + ** number of free bytes on the page. */ + assert( iFree<=usableSize-4 ); if( iFree ){ int iFree2 = get2byte(&data[iFree]); - - /* pageFindSlot() has already verified that free blocks are sorted - ** in order of offset within the page, and that no block extends - ** past the end of the page. Provided the two free slots do not - ** overlap, this guarantees that the memmove() calls below will not - ** overwrite the usableSize byte buffer, even if the database page - ** is corrupt. */ - assert( iFree2==0 || iFree2>iFree ); - assert( iFree+get2byte(&data[iFree+2]) <= usableSize ); - assert( iFree2==0 || iFree2+get2byte(&data[iFree2+2]) <= usableSize ); - + if( iFree2>usableSize-4 ) return SQLITE_CORRUPT_PAGE(pPage); if( 0==iFree2 || (data[iFree2]==0 && data[iFree2+1]==0) ){ u8 *pEnd = &data[cellOffset + nCell*2]; u8 *pAddr; @@ -64372,9 +64511,9 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){ return SQLITE_CORRUPT_PAGE(pPage); } if( iFree2 ){ - assert( iFree+sz<=iFree2 ); /* Verified by pageFindSlot() */ + if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PAGE(pPage); sz2 = get2byte(&data[iFree2+2]); - assert( iFree+sz+sz2+iFree2-(iFree+sz) <= usableSize ); + if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage); memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz)); sz += sz2; } @@ -65929,9 +66068,9 @@ static int newDatabase(BtShared*); static int lockBtree(BtShared *pBt){ int rc; /* Result code from subfunctions */ MemPage *pPage1; /* Page 1 of the database file */ - int nPage; /* Number of pages in the database */ - int nPageFile = 0; /* Number of pages in the database file */ - int nPageHeader; /* Number of pages in the database according to hdr */ + u32 nPage; /* Number of pages in the database */ + u32 nPageFile = 0; /* Number of pages in the database file */ + u32 nPageHeader; /* Number of pages in the database according to hdr */ assert( sqlite3_mutex_held(pBt->mutex) ); assert( pBt->pPage1==0 ); @@ -65944,7 +66083,7 @@ static int lockBtree(BtShared *pBt){ ** a valid database file. */ nPage = nPageHeader = get4byte(28+(u8*)pPage1->aData); - sqlite3PagerPagecount(pBt->pPager, &nPageFile); + sqlite3PagerPagecount(pBt->pPager, (int*)&nPageFile); if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){ nPage = nPageFile; } @@ -66025,6 +66164,7 @@ static int lockBtree(BtShared *pBt){ ){ goto page1_init_failed; } + pBt->btsFlags |= BTS_PAGESIZE_FIXED; assert( (pageSize & 7)==0 ); /* EVIDENCE-OF: R-59310-51205 The "reserved space" size in the 1-byte ** integer at offset 20 is the number of bytes of space at the end of @@ -66415,7 +66555,7 @@ static int setChildPtrmaps(MemPage *pPage){ for(i=0; i<nCell; i++){ u8 *pCell = findCell(pPage, i); - ptrmapPutOvflPtr(pPage, pCell, &rc); + ptrmapPutOvflPtr(pPage, pPage, pCell, &rc); if( !pPage->leaf ){ Pgno childPgno = get4byte(pCell); @@ -67341,6 +67481,7 @@ SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){ sqlite3_free(pCur->aOverflow); sqlite3_free(pCur->pKey); sqlite3BtreeLeave(pBtree); + pCur->pBtree = 0; } return SQLITE_OK; } @@ -67439,6 +67580,25 @@ SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor *pCur){ return pCur->info.nPayload; } +/* +** Return an upper bound on the size of any record for the table +** that the cursor is pointing into. +** +** This is an optimization. Everything will still work if this +** routine always returns 2147483647 (which is the largest record +** that SQLite can handle) or more. But returning a smaller value might +** prevent large memory allocations when trying to interpret a +** corrupt datrabase. +** +** The current implementation merely returns the size of the underlying +** database file. +*/ +SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor *pCur){ + assert( cursorHoldsMutex(pCur) ); + assert( pCur->eState==CURSOR_VALID ); + return pCur->pBt->pageSize * (sqlite3_int64)pCur->pBt->nPage; +} + /* ** Given the page number of an overflow page in the database (parameter ** ovfl), this function finds the page number of the next page in the @@ -68253,7 +68413,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( ** try to get there using sqlite3BtreeNext() rather than a full ** binary search. This is an optimization only. The correct answer ** is still obtained without this case, only a little more slowely */ - if( pCur->info.nKey+1==intKey && !pCur->skipNext ){ + if( pCur->info.nKey+1==intKey ){ *pRes = 0; rc = sqlite3BtreeNext(pCur, 0); if( rc==SQLITE_OK ){ @@ -68395,7 +68555,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( testcase( nCell==0 ); /* Invalid key size: 0x80 0x80 0x00 */ testcase( nCell==1 ); /* Invalid key size: 0x80 0x80 0x01 */ testcase( nCell==2 ); /* Minimum legal index key size */ - if( nCell<2 ){ + if( nCell<2 || nCell/pCur->pBt->usableSize>pCur->pBt->nPage ){ rc = SQLITE_CORRUPT_PAGE(pPage); goto moveto_finish; } @@ -68527,7 +68687,6 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){ MemPage *pPage; assert( cursorOwnsBtShared(pCur) ); - assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); if( pCur->eState!=CURSOR_VALID ){ assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); rc = restoreCursorPosition(pCur); @@ -68537,14 +68696,9 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){ if( CURSOR_INVALID==pCur->eState ){ return SQLITE_DONE; } - if( pCur->skipNext ){ - assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT ); + if( pCur->eState==CURSOR_SKIPNEXT ){ pCur->eState = CURSOR_VALID; - if( pCur->skipNext>0 ){ - pCur->skipNext = 0; - return SQLITE_OK; - } - pCur->skipNext = 0; + if( pCur->skipNext>0 ) return SQLITE_OK; } } @@ -68599,7 +68753,6 @@ SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int flags){ UNUSED_PARAMETER( flags ); /* Used in COMDB2 but not native SQLite */ assert( cursorOwnsBtShared(pCur) ); assert( flags==0 || flags==1 ); - assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); pCur->info.nSize = 0; pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur); @@ -68640,7 +68793,6 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){ MemPage *pPage; assert( cursorOwnsBtShared(pCur) ); - assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); assert( (pCur->curFlags & (BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey))==0 ); assert( pCur->info.nSize==0 ); if( pCur->eState!=CURSOR_VALID ){ @@ -68651,14 +68803,9 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){ if( CURSOR_INVALID==pCur->eState ){ return SQLITE_DONE; } - if( pCur->skipNext ){ - assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT ); + if( CURSOR_SKIPNEXT==pCur->eState ){ pCur->eState = CURSOR_VALID; - if( pCur->skipNext<0 ){ - pCur->skipNext = 0; - return SQLITE_OK; - } - pCur->skipNext = 0; + if( pCur->skipNext<0 ) return SQLITE_OK; } } @@ -68693,7 +68840,6 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){ SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int flags){ assert( cursorOwnsBtShared(pCur) ); assert( flags==0 || flags==1 ); - assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID ); UNUSED_PARAMETER( flags ); /* Used in COMDB2 but not native SQLite */ pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey); pCur->info.nSize = 0; @@ -69029,7 +69175,7 @@ static int allocateBtreePage( TRACE(("ALLOCATE: %d from end of file\n", *pPgno)); } - assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); + assert( CORRUPT_DB || *pPgno!=PENDING_BYTE_PAGE(pBt) ); end_allocate_page: releasePage(pTrunk); @@ -69584,9 +69730,16 @@ static void insertCell( assert( idx >= pPage->cellOffset+2*pPage->nCell+2 || CORRUPT_DB ); assert( idx+sz <= (int)pPage->pBt->usableSize ); pPage->nFree -= (u16)(2 + sz); - memcpy(&data[idx], pCell, sz); if( iChild ){ + /* In a corrupt database where an entry in the cell index section of + ** a btree page has a value of 3 or less, the pCell value might point + ** as many as 4 bytes in front of the start of the aData buffer for + ** the source page. Make sure this does not cause problems by not + ** reading the first 4 bytes */ + memcpy(&data[idx+4], pCell+4, sz-4); put4byte(&data[idx], iChild); + }else{ + memcpy(&data[idx], pCell, sz); } pIns = pPage->aCellIdx + i*2; memmove(pIns+2, pIns, 2*(pPage->nCell - i)); @@ -69600,15 +69753,89 @@ static void insertCell( /* The cell may contain a pointer to an overflow page. If so, write ** the entry for the overflow page into the pointer map. */ - ptrmapPutOvflPtr(pPage, pCell, pRC); + ptrmapPutOvflPtr(pPage, pPage, pCell, pRC); } #endif } } +/* +** The following parameters determine how many adjacent pages get involved +** in a balancing operation. NN is the number of neighbors on either side +** of the page that participate in the balancing operation. NB is the +** total number of pages that participate, including the target page and +** NN neighbors on either side. +** +** The minimum value of NN is 1 (of course). Increasing NN above 1 +** (to 2 or 3) gives a modest improvement in SELECT and DELETE performance +** in exchange for a larger degradation in INSERT and UPDATE performance. +** The value of NN appears to give the best results overall. +** +** (Later:) The description above makes it seem as if these values are +** tunable - as if you could change them and recompile and it would all work. +** But that is unlikely. NB has been 3 since the inception of SQLite and +** we have never tested any other value. +*/ +#define NN 1 /* Number of neighbors on either side of pPage */ +#define NB 3 /* (NN*2+1): Total pages involved in the balance */ + /* ** A CellArray object contains a cache of pointers and sizes for a ** consecutive sequence of cells that might be held on multiple pages. +** +** The cells in this array are the divider cell or cells from the pParent +** page plus up to three child pages. There are a total of nCell cells. +** +** pRef is a pointer to one of the pages that contributes cells. This is +** used to access information such as MemPage.intKey and MemPage.pBt->pageSize +** which should be common to all pages that contribute cells to this array. +** +** apCell[] and szCell[] hold, respectively, pointers to the start of each +** cell and the size of each cell. Some of the apCell[] pointers might refer +** to overflow cells. In other words, some apCel[] pointers might not point +** to content area of the pages. +** +** A szCell[] of zero means the size of that cell has not yet been computed. +** +** The cells come from as many as four different pages: +** +** ----------- +** | Parent | +** ----------- +** / | \ +** / | \ +** --------- --------- --------- +** |Child-1| |Child-2| |Child-3| +** --------- --------- --------- +** +** The order of cells is in the array is for an index btree is: +** +** 1. All cells from Child-1 in order +** 2. The first divider cell from Parent +** 3. All cells from Child-2 in order +** 4. The second divider cell from Parent +** 5. All cells from Child-3 in order +** +** For a table-btree (with rowids) the items 2 and 4 are empty because +** content exists only in leaves and there are no divider cells. +** +** For an index btree, the apEnd[] array holds pointer to the end of page +** for Child-1, the Parent, Child-2, the Parent (again), and Child-3, +** respectively. The ixNx[] array holds the number of cells contained in +** each of these 5 stages, and all stages to the left. Hence: +** +** ixNx[0] = Number of cells in Child-1. +** ixNx[1] = Number of cells in Child-1 plus 1 for first divider. +** ixNx[2] = Number of cells in Child-1 and Child-2 + 1 for 1st divider. +** ixNx[3] = Number of cells in Child-1 and Child-2 + both divider cells +** ixNx[4] = Total number of cells. +** +** For a table-btree, the concept is similar, except only apEnd[0]..apEnd[2] +** are used and they point to the leaf pages only, and the ixNx value are: +** +** ixNx[0] = Number of cells in Child-1. +** ixNx[1] = Number of cells in Child-1 and Child-2 + 1 for 1st divider. +** ixNx[2] = Number of cells in Child-1 and Child-2 + both divider cells */ typedef struct CellArray CellArray; struct CellArray { @@ -69616,6 +69843,8 @@ struct CellArray { MemPage *pRef; /* Reference page */ u8 **apCell; /* All cells begin balanced */ u16 *szCell; /* Local size of all cells in apCell[] */ + u8 *apEnd[NB*2]; /* MemPage.aDataEnd values */ + int ixNx[NB*2]; /* Index of at which we move to the next apEnd[] */ }; /* @@ -69666,36 +69895,59 @@ static u16 cachedCellSize(CellArray *p, int N){ ** responsibility of the caller to set it correctly. */ static int rebuildPage( - MemPage *pPg, /* Edit this page */ + CellArray *pCArray, /* Content to be added to page pPg */ + int iFirst, /* First cell in pCArray to use */ int nCell, /* Final number of cells on page */ - u8 **apCell, /* Array of cells */ - u16 *szCell /* Array of cell sizes */ + MemPage *pPg /* The page to be reconstructed */ ){ const int hdr = pPg->hdrOffset; /* Offset of header on pPg */ u8 * const aData = pPg->aData; /* Pointer to data for pPg */ const int usableSize = pPg->pBt->usableSize; u8 * const pEnd = &aData[usableSize]; - int i; + int i = iFirst; /* Which cell to copy from pCArray*/ + u32 j; /* Start of cell content area */ + int iEnd = i+nCell; /* Loop terminator */ u8 *pCellptr = pPg->aCellIdx; u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager); u8 *pData; + int k; /* Current slot in pCArray->apEnd[] */ + u8 *pSrcEnd; /* Current pCArray->apEnd[k] value */ - i = get2byte(&aData[hdr+5]); - memcpy(&pTmp[i], &aData[i], usableSize - i); + assert( i<iEnd ); + j = get2byte(&aData[hdr+5]); + if( NEVER(j>(u32)usableSize) ){ j = 0; } + memcpy(&pTmp[j], &aData[j], usableSize - j); + + for(k=0; pCArray->ixNx[k]<=i && ALWAYS(k<NB*2); k++){} + pSrcEnd = pCArray->apEnd[k]; pData = pEnd; - for(i=0; i<nCell; i++){ - u8 *pCell = apCell[i]; + while( 1/*exit by break*/ ){ + u8 *pCell = pCArray->apCell[i]; + u16 sz = pCArray->szCell[i]; + assert( sz>0 ); if( SQLITE_WITHIN(pCell,aData,pEnd) ){ + if( ((uptr)(pCell+sz))>(uptr)pEnd ) return SQLITE_CORRUPT_BKPT; pCell = &pTmp[pCell - aData]; + }else if( (uptr)(pCell+sz)>(uptr)pSrcEnd + && (uptr)(pCell)<(uptr)pSrcEnd + ){ + return SQLITE_CORRUPT_BKPT; } - pData -= szCell[i]; + + pData -= sz; put2byte(pCellptr, (pData - aData)); pCellptr += 2; if( pData < pCellptr ) return SQLITE_CORRUPT_BKPT; - memcpy(pData, pCell, szCell[i]); - assert( szCell[i]==pPg->xCellSize(pPg, pCell) || CORRUPT_DB ); - testcase( szCell[i]!=pPg->xCellSize(pPg,pCell) ); + memcpy(pData, pCell, sz); + assert( sz==pPg->xCellSize(pPg, pCell) || CORRUPT_DB ); + testcase( sz!=pPg->xCellSize(pPg,pCell) ); + i++; + if( i>=iEnd ) break; + if( pCArray->ixNx[k]<=i ){ + k++; + pSrcEnd = pCArray->apEnd[k]; + } } /* The pPg->nFree field is now set incorrectly. The caller will fix it. */ @@ -69710,12 +69962,11 @@ static int rebuildPage( } /* -** Array apCell[] contains nCell pointers to b-tree cells. Array szCell -** contains the size in bytes of each such cell. This function attempts to -** add the cells stored in the array to page pPg. If it cannot (because -** the page needs to be defragmented before the cells will fit), non-zero -** is returned. Otherwise, if the cells are added successfully, zero is -** returned. +** The pCArray objects contains pointers to b-tree cells and the cell sizes. +** This function attempts to add the cells stored in the array to page pPg. +** If it cannot (because the page needs to be defragmented before the cells +** will fit), non-zero is returned. Otherwise, if the cells are added +** successfully, zero is returned. ** ** Argument pCellptr points to the first entry in the cell-pointer array ** (part of page pPg) to populate. After cell apCell[0] is written to the @@ -69737,18 +69988,23 @@ static int rebuildPage( static int pageInsertArray( MemPage *pPg, /* Page to add cells to */ u8 *pBegin, /* End of cell-pointer array */ - u8 **ppData, /* IN/OUT: Page content -area pointer */ + u8 **ppData, /* IN/OUT: Page content-area pointer */ u8 *pCellptr, /* Pointer to cell-pointer area */ int iFirst, /* Index of first cell to add */ int nCell, /* Number of cells to add to pPg */ CellArray *pCArray /* Array of cells */ ){ - int i; - u8 *aData = pPg->aData; - u8 *pData = *ppData; - int iEnd = iFirst + nCell; + int i = iFirst; /* Loop counter - cell index to insert */ + u8 *aData = pPg->aData; /* Complete page */ + u8 *pData = *ppData; /* Content area. A subset of aData[] */ + int iEnd = iFirst + nCell; /* End of loop. One past last cell to ins */ + int k; /* Current slot in pCArray->apEnd[] */ + u8 *pEnd; /* Maximum extent of cell data */ assert( CORRUPT_DB || pPg->hdrOffset==0 ); /* Never called on page 1 */ - for(i=iFirst; i<iEnd; i++){ + if( iEnd<=iFirst ) return 0; + for(k=0; pCArray->ixNx[k]<=i && ALWAYS(k<NB*2); k++){} + pEnd = pCArray->apEnd[k]; + while( 1 /*Exit by break*/ ){ int sz, rc; u8 *pSlot; sz = cachedCellSize(pCArray, i); @@ -69763,20 +70019,33 @@ static int pageInsertArray( assert( (pSlot+sz)<=pCArray->apCell[i] || pSlot>=(pCArray->apCell[i]+sz) || CORRUPT_DB ); + if( (uptr)(pCArray->apCell[i]+sz)>(uptr)pEnd + && (uptr)(pCArray->apCell[i])<(uptr)pEnd + ){ + assert( CORRUPT_DB ); + (void)SQLITE_CORRUPT_BKPT; + return 1; + } memmove(pSlot, pCArray->apCell[i], sz); put2byte(pCellptr, (pSlot - aData)); pCellptr += 2; + i++; + if( i>=iEnd ) break; + if( pCArray->ixNx[k]<=i ){ + k++; + pEnd = pCArray->apEnd[k]; + } } *ppData = pData; return 0; } /* -** Array apCell[] contains nCell pointers to b-tree cells. Array szCell -** contains the size in bytes of each such cell. This function adds the -** space associated with each cell in the array that is currently stored -** within the body of pPg to the pPg free-list. The cell-pointers and other -** fields of the page are not updated. +** The pCArray object contains pointers to b-tree cells and their sizes. +** +** This function adds the space associated with each cell in the array +** that is currently stored within the body of pPg to the pPg free-list. +** The cell-pointers and other fields of the page are not updated. ** ** This function returns the total number of cells added to the free-list. */ @@ -69826,9 +70095,9 @@ static int pageFreeArray( } /* -** apCell[] and szCell[] contains pointers to and sizes of all cells in the -** pages being balanced. The current page, pPg, has pPg->nCell cells starting -** with apCell[iOld]. After balancing, this page should hold nNew cells +** pCArray contains pointers to and sizes of all cells in the page being +** balanced. The current page, pPg, has pPg->nCell cells starting with +** pCArray->apCell[iOld]. After balancing, this page should hold nNew cells ** starting at apCell[iNew]. ** ** This routine makes the necessary adjustments to pPg so that it contains @@ -69860,13 +70129,17 @@ static int editPage( #endif /* Remove cells from the start and end of the page */ + assert( nCell>=0 ); if( iOld<iNew ){ int nShift = pageFreeArray(pPg, iOld, iNew-iOld, pCArray); + if( nShift>nCell ) return SQLITE_CORRUPT_BKPT; memmove(pPg->aCellIdx, &pPg->aCellIdx[nShift*2], nCell*2); nCell -= nShift; } if( iNewEnd < iOldEnd ){ - nCell -= pageFreeArray(pPg, iNewEnd, iOldEnd - iNewEnd, pCArray); + int nTail = pageFreeArray(pPg, iNewEnd, iOldEnd - iNewEnd, pCArray); + assert( nCell>=nTail ); + nCell -= nTail; } pData = &aData[get2byteNotZero(&aData[hdr+5])]; @@ -69876,6 +70149,7 @@ static int editPage( if( iNew<iOld ){ int nAdd = MIN(nNew,iOld-iNew); assert( (iOld-iNew)<nNew || nCell==0 || CORRUPT_DB ); + assert( nAdd>=0 ); pCellptr = pPg->aCellIdx; memmove(&pCellptr[nAdd*2], pCellptr, nCell*2); if( pageInsertArray( @@ -69890,6 +70164,7 @@ static int editPage( int iCell = (iOld + pPg->aiOvfl[i]) - iNew; if( iCell>=0 && iCell<nNew ){ pCellptr = &pPg->aCellIdx[iCell * 2]; + assert( nCell>=iCell ); memmove(&pCellptr[2], pCellptr, (nCell - iCell) * 2); nCell++; if( pageInsertArray( @@ -69900,6 +70175,7 @@ static int editPage( } /* Append cells to the end of the page */ + assert( nCell>=0 ); pCellptr = &pPg->aCellIdx[nCell*2]; if( pageInsertArray( pPg, pBegin, &pData, pCellptr, @@ -69928,24 +70204,9 @@ static int editPage( editpage_fail: /* Unable to edit this page. Rebuild it from scratch instead. */ populateCellCache(pCArray, iNew, nNew); - return rebuildPage(pPg, nNew, &pCArray->apCell[iNew], &pCArray->szCell[iNew]); + return rebuildPage(pCArray, iNew, nNew, pPg); } -/* -** The following parameters determine how many adjacent pages get involved -** in a balancing operation. NN is the number of neighbors on either side -** of the page that participate in the balancing operation. NB is the -** total number of pages that participate, including the target page and -** NN neighbors on either side. -** -** The minimum value of NN is 1 (of course). Increasing NN above 1 -** (to 2 or 3) gives a modest improvement in SELECT and DELETE performance -** in exchange for a larger degradation in INSERT and UPDATE performance. -** The value of NN appears to give the best results overall. -*/ -#define NN 1 /* Number of neighbors on either side of pPage */ -#define NB (NN*2+1) /* Total pages involved in the balance */ - #ifndef SQLITE_OMIT_QUICKBALANCE /* @@ -69981,8 +70242,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ assert( sqlite3PagerIswriteable(pParent->pDbPage) ); assert( pPage->nOverflow==1 ); - /* This error condition is now caught prior to reaching this function */ - if( NEVER(pPage->nCell==0) ) return SQLITE_CORRUPT_BKPT; + if( pPage->nCell==0 ) return SQLITE_CORRUPT_BKPT; /* dbfuzz001.test */ /* Allocate a new page. This page will become the right-sibling of ** pPage. Make the parent page writable, so that the new divider cell @@ -69996,12 +70256,22 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ u8 *pCell = pPage->apOvfl[0]; u16 szCell = pPage->xCellSize(pPage, pCell); u8 *pStop; + CellArray b; assert( sqlite3PagerIswriteable(pNew->pDbPage) ); - assert( pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) ); + assert( CORRUPT_DB || pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) ); zeroPage(pNew, PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF); - rc = rebuildPage(pNew, 1, &pCell, &szCell); - if( NEVER(rc) ) return rc; + b.nCell = 1; + b.pRef = pPage; + b.apCell = &pCell; + b.szCell = &szCell; + b.apEnd[0] = pPage->aDataEnd; + b.ixNx[0] = 2; + rc = rebuildPage(&b, 0, 1, pNew); + if( NEVER(rc) ){ + releasePage(pNew); + return rc; + } pNew->nFree = pBt->usableSize - pNew->cellOffset - 2 - szCell; /* If this is an auto-vacuum database, update the pointer map @@ -70016,7 +70286,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ if( ISAUTOVACUUM ){ ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno, &rc); if( szCell>pNew->minLocal ){ - ptrmapPutOvflPtr(pNew, pCell, &rc); + ptrmapPutOvflPtr(pNew, pNew, pCell, &rc); } } @@ -70239,10 +70509,6 @@ static int balance_nonroot( assert( sqlite3_mutex_held(pBt->mutex) ); assert( sqlite3PagerIswriteable(pParent->pDbPage) ); -#if 0 - TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno)); -#endif - /* At this point pParent may have at most one overflow cell. And if ** this overflow cell is present, it must be the cell with ** index iParentIdx. This scenario comes about when this function @@ -70483,8 +70749,15 @@ static int balance_nonroot( ** */ usableSpace = pBt->usableSize - 12 + leafCorrection; - for(i=0; i<nOld; i++){ + for(i=k=0; i<nOld; i++, k++){ MemPage *p = apOld[i]; + b.apEnd[k] = p->aDataEnd; + b.ixNx[k] = cntOld[i]; + if( !leafData ){ + k++; + b.apEnd[k] = pParent->aDataEnd; + b.ixNx[k] = cntOld[i]+1; + } szNew[i] = usableSpace - p->nFree; for(j=0; j<p->nOverflow; j++){ szNew[i] += 2 + p->xCellSize(p, p->apOvfl[j]); @@ -70708,7 +70981,8 @@ static int balance_nonroot( ** populated, not here. */ if( ISAUTOVACUUM ){ - MemPage *pNew = apNew[0]; + MemPage *pOld; + MemPage *pNew = pOld = apNew[0]; u8 *aOld = pNew->aData; int cntOldNext = pNew->nCell + pNew->nOverflow; int usableSize = pBt->usableSize; @@ -70718,7 +70992,7 @@ static int balance_nonroot( for(i=0; i<b.nCell; i++){ u8 *pCell = b.apCell[i]; if( i==cntOldNext ){ - MemPage *pOld = (++iOld)<nNew ? apNew[iOld] : apOld[iOld]; + pOld = (++iOld)<nNew ? apNew[iOld] : apOld[iOld]; cntOldNext += pOld->nCell + pOld->nOverflow + !leafData; aOld = pOld->aData; } @@ -70741,7 +71015,7 @@ static int balance_nonroot( ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno, &rc); } if( cachedCellSize(&b,i)>pNew->minLocal ){ - ptrmapPutOvflPtr(pNew, pCell, &rc); + ptrmapPutOvflPtr(pNew, pOld, pCell, &rc); } if( rc ) goto balance_cleanup; } @@ -71165,7 +71439,11 @@ static int btreeOverwriteContent( if( memcmp(pDest, ((u8*)pX->pData) + iOffset, iAmt)!=0 ){ int rc = sqlite3PagerWrite(pPage->pDbPage); if( rc ) return rc; - memcpy(pDest, ((u8*)pX->pData) + iOffset, iAmt); + /* In a corrupt database, it is possible for the source and destination + ** buffers to overlap. This is harmless since the database is already + ** corrupt but it does cause valgrind and ASAN warnings. So use + ** memmove(). */ + memmove(pDest, ((u8*)pX->pData) + iOffset, iAmt); } } return SQLITE_OK; @@ -71560,6 +71838,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ if( bPreserve ){ if( !pPage->leaf || (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3) + || pPage->nCell==1 /* See dbfuzz001.test for a test case */ ){ /* A b-tree rebalance will be required after deleting this entry. ** Save the cursor key. */ @@ -72338,18 +72617,18 @@ static void checkList( } pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage); if( isFreeList ){ - int n = get4byte(&pOvflData[4]); + u32 n = (u32)get4byte(&pOvflData[4]); #ifndef SQLITE_OMIT_AUTOVACUUM if( pCheck->pBt->autoVacuum ){ checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0); } #endif - if( n>(int)pCheck->pBt->usableSize/4-2 ){ + if( n>pCheck->pBt->usableSize/4-2 ){ checkAppendMsg(pCheck, "freelist leaf count too big on page %d", iPage); N--; }else{ - for(i=0; i<n; i++){ + for(i=0; i<(int)n; i++){ Pgno iFreePage = get4byte(&pOvflData[8+i*4]); #ifndef SQLITE_OMIT_AUTOVACUUM if( pCheck->pBt->autoVacuum ){ @@ -72726,7 +73005,7 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck( Pgno i; IntegrityCk sCheck; BtShared *pBt = p->pBt; - int savedDbFlags = pBt->db->flags; + u64 savedDbFlags = pBt->db->flags; char zErr[100]; VVA_ONLY( int nRef ); @@ -72793,7 +73072,7 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck( } #endif testcase( pBt->db->flags & SQLITE_CellSizeCk ); - pBt->db->flags &= ~SQLITE_CellSizeCk; + pBt->db->flags &= ~(u64)SQLITE_CellSizeCk; for(i=0; (int)i<nRoot && sCheck.mxErr; i++){ i64 notUsed; if( aRoot[i]==0 ) continue; @@ -74181,7 +74460,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPre ** if unable to complete the resizing. */ SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){ - assert( szNew>0 ); + assert( CORRUPT_DB || szNew>0 ); assert( (pMem->flags & MEM_Dyn)==0 || pMem->szMalloc==0 ); if( pMem->szMalloc<szNew ){ return sqlite3VdbeMemGrow(pMem, szNew, 0); @@ -75062,6 +75341,9 @@ static SQLITE_NOINLINE int vdbeMemFromBtreeResize( ){ int rc; pMem->flags = MEM_Null; + if( sqlite3BtreeMaxRecordSize(pCur)<offset+amt ){ + return SQLITE_CORRUPT_BKPT; + } if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+1)) ){ rc = sqlite3BtreePayload(pCur, offset, amt, pMem->z); if( rc==SQLITE_OK ){ @@ -75468,9 +75750,11 @@ static int valueFromExpr( } #endif else if( op==TK_TRUEFALSE ){ - pVal = valueNew(db, pCtx); - pVal->flags = MEM_Int; - pVal->u.i = pExpr->u.zToken[4]==0; + pVal = valueNew(db, pCtx); + if( pVal ){ + pVal->flags = MEM_Int; + pVal->u.i = pExpr->u.zToken[4]==0; + } } *ppVal = pVal; @@ -75863,7 +76147,7 @@ SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){ pParse->pVdbe = p; assert( pParse->aLabel==0 ); assert( pParse->nLabel==0 ); - assert( pParse->nOpAlloc==0 ); + assert( p->nOpAlloc==0 ); assert( pParse->szOpAlloc==0 ); sqlite3VdbeAddOp2(p, OP_Init, 0, 1); return p; @@ -75891,15 +76175,45 @@ SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, u8 prepFlag } assert( p->zSql==0 ); p->zSql = sqlite3DbStrNDup(p->db, z, n); -#ifdef SQLITE_ENABLE_NORMALIZE - assert( p->zNormSql==0 ); - if( p->zSql && (prepFlags & SQLITE_PREPARE_NORMALIZE)!=0 ){ - sqlite3Normalize(p, p->zSql, n, prepFlags); - assert( p->zNormSql!=0 || p->db->mallocFailed ); - } -#endif } +#ifdef SQLITE_ENABLE_NORMALIZE +/* +** Add a new element to the Vdbe->pDblStr list. +*/ +SQLITE_PRIVATE void sqlite3VdbeAddDblquoteStr(sqlite3 *db, Vdbe *p, const char *z){ + if( p ){ + int n = sqlite3Strlen30(z); + DblquoteStr *pStr = sqlite3DbMallocRawNN(db, + sizeof(*pStr)+n+1-sizeof(pStr->z)); + if( pStr ){ + pStr->pNextStr = p->pDblStr; + p->pDblStr = pStr; + memcpy(pStr->z, z, n+1); + } + } +} +#endif + +#ifdef SQLITE_ENABLE_NORMALIZE +/* +** zId of length nId is a double-quoted identifier. Check to see if +** that identifier is really used as a string literal. +*/ +SQLITE_PRIVATE int sqlite3VdbeUsesDoubleQuotedString( + Vdbe *pVdbe, /* The prepared statement */ + const char *zId /* The double-quoted identifier, already dequoted */ +){ + DblquoteStr *pStr; + assert( zId!=0 ); + if( pVdbe->pDblStr==0 ) return 0; + for(pStr=pVdbe->pDblStr; pStr; pStr=pStr->pNextStr){ + if( strcmp(zId, pStr->z)==0 ) return 1; + } + return 0; +} +#endif + /* ** Swap all content between two VDBE structures. */ @@ -75919,7 +76233,7 @@ SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){ zTmp = pA->zSql; pA->zSql = pB->zSql; pB->zSql = zTmp; -#ifdef SQLITE_ENABLE_NORMALIZE +#if 0 zTmp = pA->zNormSql; pA->zNormSql = pB->zNormSql; pB->zNormSql = zTmp; @@ -75936,7 +76250,7 @@ SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){ ** to 1024/sizeof(Op). ** ** If an out-of-memory error occurs while resizing the array, return -** SQLITE_NOMEM. In this case Vdbe.aOp and Parse.nOpAlloc remain +** SQLITE_NOMEM. In this case Vdbe.aOp and Vdbe.nOpAlloc remain ** unchanged (this is so that any opcodes already allocated can be ** correctly deallocated along with the rest of the Vdbe). */ @@ -75952,9 +76266,9 @@ static int growOpArray(Vdbe *v, int nOp){ ** operation (without SQLITE_TEST_REALLOC_STRESS) is to double the current ** size of the op array or add 1KB of space, whichever is smaller. */ #ifdef SQLITE_TEST_REALLOC_STRESS - int nNew = (p->nOpAlloc>=512 ? p->nOpAlloc*2 : p->nOpAlloc+nOp); + int nNew = (v->nOpAlloc>=512 ? v->nOpAlloc*2 : v->nOpAlloc+nOp); #else - int nNew = (p->nOpAlloc ? p->nOpAlloc*2 : (int)(1024/sizeof(Op))); + int nNew = (v->nOpAlloc ? v->nOpAlloc*2 : (int)(1024/sizeof(Op))); UNUSED_PARAMETER(nOp); #endif @@ -75965,11 +76279,11 @@ static int growOpArray(Vdbe *v, int nOp){ } assert( nOp<=(1024/sizeof(Op)) ); - assert( nNew>=(p->nOpAlloc+nOp) ); + assert( nNew>=(v->nOpAlloc+nOp) ); pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op)); if( pNew ){ p->szOpAlloc = sqlite3DbMallocSize(p->db, pNew); - p->nOpAlloc = p->szOpAlloc/sizeof(Op); + v->nOpAlloc = p->szOpAlloc/sizeof(Op); v->aOp = pNew; } return (pNew ? SQLITE_OK : SQLITE_NOMEM_BKPT); @@ -76003,9 +76317,9 @@ static void test_addop_breakpoint(void){ ** operand. */ static SQLITE_NOINLINE int growOp3(Vdbe *p, int op, int p1, int p2, int p3){ - assert( p->pParse->nOpAlloc<=p->nOp ); + assert( p->nOpAlloc<=p->nOp ); if( growOpArray(p, 1) ) return 1; - assert( p->pParse->nOpAlloc>p->nOp ); + assert( p->nOpAlloc>p->nOp ); return sqlite3VdbeAddOp3(p, op, p1, p2, p3); } SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ @@ -76015,7 +76329,7 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ i = p->nOp; assert( p->magic==VDBE_MAGIC_INIT ); assert( op>=0 && op<0xff ); - if( p->pParse->nOpAlloc<=i ){ + if( p->nOpAlloc<=i ){ return growOp3(p, op, p1, p2, p3); } p->nOp++; @@ -76147,13 +76461,29 @@ SQLITE_PRIVATE int sqlite3VdbeExplainParent(Parse *pParse){ } /* -** Add a new OP_Explain opcode. +** Set a debugger breakpoint on the following routine in order to +** monitor the EXPLAIN QUERY PLAN code generation. +*/ +#if defined(SQLITE_DEBUG) +SQLITE_PRIVATE void sqlite3ExplainBreakpoint(const char *z1, const char *z2){ + (void)z1; + (void)z2; +} +#endif + +/* +** Add a new OP_ opcode. ** ** If the bPush flag is true, then make this opcode the parent for ** subsequent Explains until sqlite3VdbeExplainPop() is called. */ SQLITE_PRIVATE void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){ - if( pParse->explain==2 ){ +#ifndef SQLITE_DEBUG + /* Always include the OP_Explain opcodes if SQLITE_DEBUG is defined. + ** But omit them (for performance) during production builds */ + if( pParse->explain==2 ) +#endif + { char *zMsg; Vdbe *v; va_list ap; @@ -76165,7 +76495,10 @@ SQLITE_PRIVATE void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt iThis = v->nOp; sqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0, zMsg, P4_DYNAMIC); - if( bPush) pParse->addrExplain = iThis; + sqlite3ExplainBreakpoint(bPush?"PUSH":"", sqlite3VdbeGetOp(v,-1)->p4.z); + if( bPush){ + pParse->addrExplain = iThis; + } } } @@ -76173,6 +76506,7 @@ SQLITE_PRIVATE void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt ** Pop the EXPLAIN QUERY PLAN stack one level. */ SQLITE_PRIVATE void sqlite3VdbeExplainPop(Parse *pParse){ + sqlite3ExplainBreakpoint("POP", 0); pParse->addrExplain = sqlite3VdbeExplainParent(pParse); } #endif /* SQLITE_OMIT_EXPLAIN */ @@ -76237,21 +76571,22 @@ SQLITE_PRIVATE void sqlite3VdbeEndCoroutine(Vdbe *v, int regYield){ ** The VDBE knows that a P2 value is a label because labels are ** always negative and P2 values are suppose to be non-negative. ** Hence, a negative P2 value is a label that has yet to be resolved. +** (Later:) This is only true for opcodes that have the OPFLG_JUMP +** property. ** -** Zero is returned if a malloc() fails. +** Variable usage notes: +** +** Parse.aLabel[x] Stores the address that the x-th label resolves +** into. For testing (SQLITE_DEBUG), unresolved +** labels stores -1, but that is not required. +** Parse.nLabelAlloc Number of slots allocated to Parse.aLabel[] +** Parse.nLabel The *negative* of the number of labels that have +** been issued. The negative is stored because +** that gives a performance improvement over storing +** the equivalent positive value. */ -SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe *v){ - Parse *p = v->pParse; - int i = p->nLabel++; - assert( v->magic==VDBE_MAGIC_INIT ); - if( (i & (i-1))==0 ){ - p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel, - (i*2+1)*sizeof(p->aLabel[0])); - } - if( p->aLabel ){ - p->aLabel[i] = -1; - } - return ADDR(i); +SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Parse *pParse){ + return --pParse->nLabel; } /* @@ -76259,18 +76594,35 @@ SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe *v){ ** be inserted. The parameter "x" must have been obtained from ** a prior call to sqlite3VdbeMakeLabel(). */ +static SQLITE_NOINLINE void resizeResolveLabel(Parse *p, Vdbe *v, int j){ + int nNewSize = 10 - p->nLabel; + p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel, + nNewSize*sizeof(p->aLabel[0])); + if( p->aLabel==0 ){ + p->nLabelAlloc = 0; + }else{ +#ifdef SQLITE_DEBUG + int i; + for(i=p->nLabelAlloc; i<nNewSize; i++) p->aLabel[i] = -1; +#endif + p->nLabelAlloc = nNewSize; + p->aLabel[j] = v->nOp; + } +} SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){ Parse *p = v->pParse; int j = ADDR(x); assert( v->magic==VDBE_MAGIC_INIT ); - assert( j<p->nLabel ); + assert( j<-p->nLabel ); assert( j>=0 ); - if( p->aLabel ){ #ifdef SQLITE_DEBUG - if( p->db->flags & SQLITE_VdbeAddopTrace ){ - printf("RESOLVE LABEL %d to %d\n", x, v->nOp); - } + if( p->db->flags & SQLITE_VdbeAddopTrace ){ + printf("RESOLVE LABEL %d to %d\n", x, v->nOp); + } #endif + if( p->nLabelAlloc + p->nLabel < 0 ){ + resizeResolveLabel(p,v,j); + }else{ assert( p->aLabel[j]==(-1) ); /* Labels may only be resolved once */ p->aLabel[j] = v->nOp; } @@ -76395,8 +76747,9 @@ SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){ while( (pOp = opIterNext(&sIter))!=0 ){ int opcode = pOp->opcode; if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename + || opcode==OP_VDestroy || ((opcode==OP_Halt || opcode==OP_HaltIfNull) - && ((pOp->p1&0xff)==SQLITE_CONSTRAINT && pOp->p2==OE_Abort)) + && ((pOp->p1)!=SQLITE_OK && pOp->p2==OE_Abort)) ){ hasAbort = 1; break; @@ -76545,7 +76898,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to ** have non-negative values for P2. */ assert( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 ); - assert( ADDR(pOp->p2)<pParse->nLabel ); + assert( ADDR(pOp->p2)<-pParse->nLabel ); pOp->p2 = aLabel[ADDR(pOp->p2)]; } break; @@ -76584,7 +76937,7 @@ SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe *p){ */ #if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS) SQLITE_PRIVATE void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N){ - assert( p->nOp + N <= p->pParse->nOpAlloc ); + assert( p->nOp + N <= p->nOpAlloc ); } #endif @@ -76656,7 +77009,7 @@ SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList( VdbeOp *pOut, *pFirst; assert( nOp>0 ); assert( p->magic==VDBE_MAGIC_INIT ); - if( p->nOp + nOp > p->pParse->nOpAlloc && growOpArray(p, nOp) ){ + if( p->nOp + nOp > p->nOpAlloc && growOpArray(p, nOp) ){ return 0; } pFirst = pOut = &p->aOp[p->nOp]; @@ -77978,19 +78331,27 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( ** the leftover memory at the end of the opcode array. This can significantly ** reduce the amount of memory held by a prepared statement. */ - do { - x.nNeeded = 0; - p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem)); - p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem)); - p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*)); - p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*)); + x.nNeeded = 0; + p->aMem = allocSpace(&x, 0, nMem*sizeof(Mem)); + p->aVar = allocSpace(&x, 0, nVar*sizeof(Mem)); + p->apArg = allocSpace(&x, 0, nArg*sizeof(Mem*)); + p->apCsr = allocSpace(&x, 0, nCursor*sizeof(VdbeCursor*)); #ifdef SQLITE_ENABLE_STMT_SCANSTATUS - p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64)); + p->anExec = allocSpace(&x, 0, p->nOp*sizeof(i64)); #endif - if( x.nNeeded==0 ) break; + if( x.nNeeded ){ x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded); x.nFree = x.nNeeded; - }while( !db->mallocFailed ); + if( !db->mallocFailed ){ + p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem)); + p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem)); + p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*)); + p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*)); +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64)); +#endif + } + } p->pVList = pParse->pVList; pParse->pVList = 0; @@ -78682,7 +79043,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ }else{ db->nDeferredCons = 0; db->nDeferredImmCons = 0; - db->flags &= ~SQLITE_DeferFKs; + db->flags &= ~(u64)SQLITE_DeferFKs; sqlite3CommitInternalChanges(db); } }else{ @@ -78997,6 +79358,13 @@ SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ sqlite3DbFree(db, p->zSql); #ifdef SQLITE_ENABLE_NORMALIZE sqlite3DbFree(db, p->zNormSql); + { + DblquoteStr *pThis, *pNext; + for(pThis=p->pDblStr; pThis; pThis=pNext){ + pNext = pThis->pNextStr; + sqlite3DbFree(db, pThis); + } + } #endif #ifdef SQLITE_ENABLE_STMT_SCANSTATUS { @@ -79537,7 +79905,7 @@ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack( UnpackedRecord *p /* Populate this structure before returning. */ ){ const unsigned char *aKey = (const unsigned char *)pKey; - int d; + u32 d; u32 idx; /* Offset in aKey[] to read from */ u16 u; /* Unsigned loop counter */ u32 szHdr; @@ -79548,7 +79916,7 @@ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack( idx = getVarint32(aKey, szHdr); d = szHdr; u = 0; - while( idx<szHdr && d<=nKey ){ + while( idx<szHdr && d<=(u32)nKey ){ u32 serial_type; idx += getVarint32(&aKey[idx], serial_type); @@ -79561,6 +79929,13 @@ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack( pMem++; if( (++u)>=p->nField ) break; } + if( d>(u32)nKey && u ){ + assert( CORRUPT_DB ); + /* In a corrupt record entry, the last pMem might have been set up using + ** uninitialized memory. Overwrite its value with NULL, to prevent + ** warnings from MSAN. */ + sqlite3VdbeMemSetNull(pMem-1); + } assert( u<=pKeyInfo->nKeyField + 1 ); p->nField = u; } @@ -79626,8 +80001,8 @@ static int vdbeRecordCompareDebug( ** Use that approximation to avoid the more expensive call to ** sqlite3VdbeSerialTypeLen() in the common case. */ - if( d1+serial_type1+2>(u32)nKey1 - && d1+sqlite3VdbeSerialTypeLen(serial_type1)>(u32)nKey1 + if( d1+(u64)serial_type1+2>(u64)nKey1 + && d1+(u64)sqlite3VdbeSerialTypeLen(serial_type1)>(u64)nKey1 ){ break; } @@ -79638,7 +80013,8 @@ static int vdbeRecordCompareDebug( /* Do the comparison */ - rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], pKeyInfo->aColl[i]); + rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], + pKeyInfo->nAllField>i ? pKeyInfo->aColl[i] : 0); if( rc!=0 ){ assert( mem1.szMalloc==0 ); /* See comment below */ if( pKeyInfo->aSortOrder[i] ){ @@ -79994,12 +80370,12 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( }else{ idx1 = getVarint32(aKey1, szHdr1); d1 = szHdr1; - if( d1>(unsigned)nKey1 ){ - pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; - return 0; /* Corruption */ - } i = 0; } + if( d1>(unsigned)nKey1 ){ + pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; + return 0; /* Corruption */ + } VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */ assert( pPKey2->pKeyInfo->nAllField>=pPKey2->nField @@ -80069,10 +80445,12 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( mem1.n = (serial_type - 12) / 2; testcase( (d1+mem1.n)==(unsigned)nKey1 ); testcase( (d1+mem1.n+1)==(unsigned)nKey1 ); - if( (d1+mem1.n) > (unsigned)nKey1 ){ + if( (d1+mem1.n) > (unsigned)nKey1 + || (pKeyInfo = pPKey2->pKeyInfo)->nAllField<=i + ){ pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; return 0; /* Corruption */ - }else if( (pKeyInfo = pPKey2->pKeyInfo)->aColl[i] ){ + }else if( pKeyInfo->aColl[i] ){ mem1.enc = pKeyInfo->enc; mem1.db = pKeyInfo->db; mem1.flags = MEM_Str; @@ -80772,14 +81150,16 @@ static SQLITE_NOINLINE void invokeProfileCallback(sqlite3 *db, Vdbe *p){ sqlite3_int64 iNow; sqlite3_int64 iElapse; assert( p->startTime>0 ); - assert( db->xProfile!=0 || (db->mTrace & SQLITE_TRACE_PROFILE)!=0 ); + assert( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0 ); assert( db->init.busy==0 ); assert( p->zSql!=0 ); sqlite3OsCurrentTimeInt64(db->pVfs, &iNow); iElapse = (iNow - p->startTime)*1000000; +#ifndef SQLITE_OMIT_DEPRECATED if( db->xProfile ){ db->xProfile(db->pProfileArg, p->zSql, iElapse); } +#endif if( db->mTrace & SQLITE_TRACE_PROFILE ){ db->xTrace(SQLITE_TRACE_PROFILE, db->pTraceArg, p, (void*)&iElapse); } @@ -81293,7 +81673,7 @@ static int sqlite3Step(Vdbe *p){ return SQLITE_NOMEM_BKPT; } - if( p->pc<=0 && p->expired ){ + if( p->pc<0 && p->expired ){ p->rc = SQLITE_SCHEMA; rc = SQLITE_ERROR; goto end_of_step; @@ -81312,7 +81692,7 @@ static int sqlite3Step(Vdbe *p){ ); #ifndef SQLITE_OMIT_TRACE - if( (db->xProfile || (db->mTrace & SQLITE_TRACE_PROFILE)!=0) + if( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0 && !db->init.busy && p->zSql ){ sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime); }else{ @@ -81339,16 +81719,18 @@ static int sqlite3Step(Vdbe *p){ db->nVdbeExec--; } + if( rc!=SQLITE_ROW ){ #ifndef SQLITE_OMIT_TRACE - /* If the statement completed successfully, invoke the profile callback */ - if( rc!=SQLITE_ROW ) checkProfileCallback(db, p); + /* If the statement completed successfully, invoke the profile callback */ + checkProfileCallback(db, p); #endif - if( rc==SQLITE_DONE && db->autoCommit ){ - assert( p->rc==SQLITE_OK ); - p->rc = doWalCallbacks(db); - if( p->rc!=SQLITE_OK ){ - rc = SQLITE_ERROR; + if( rc==SQLITE_DONE && db->autoCommit ){ + assert( p->rc==SQLITE_OK ); + p->rc = doWalCallbacks(db); + if( p->rc!=SQLITE_OK ){ + rc = SQLITE_ERROR; + } } } @@ -81368,9 +81750,9 @@ end_of_step: || (rc&0xff)==SQLITE_BUSY || rc==SQLITE_MISUSE ); assert( (p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE) || p->rc==p->rcApp ); - if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 - && rc!=SQLITE_ROW - && rc!=SQLITE_DONE + if( rc!=SQLITE_ROW + && rc!=SQLITE_DONE + && (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 ){ /* If this statement was prepared using saved SQL and an ** error has occurred, then return the error code in p->rc to the @@ -81992,7 +82374,7 @@ static int vdbeUnbind(Vdbe *p, int i){ pVar = &p->aVar[i]; sqlite3VdbeMemRelease(pVar); pVar->flags = MEM_Null; - sqlite3Error(p->db, SQLITE_OK); + p->db->errCode = SQLITE_OK; /* If the bit corresponding to this variable in Vdbe.expmask is set, then ** binding a new value to this variable invalidates the current query plan. @@ -82418,7 +82800,13 @@ SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt){ */ SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt){ Vdbe *p = (Vdbe *)pStmt; - return p ? p->zNormSql : 0; + if( p==0 ) return 0; + if( p->zNormSql==0 && ALWAYS(p->zSql!=0) ){ + sqlite3_mutex_enter(p->db->mutex); + p->zNormSql = sqlite3Normalize(p, p->zSql); + sqlite3_mutex_leave(p->db->mutex); + } + return p->zNormSql; } #endif /* SQLITE_ENABLE_NORMALIZE */ @@ -83118,6 +83506,11 @@ static VdbeCursor *allocateCursor( assert( iCur>=0 && iCur<p->nCursor ); if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/ + /* Before calling sqlite3VdbeFreeCursor(), ensure the isEphemeral flag + ** is clear. Otherwise, if this is an ephemeral cursor created by + ** OP_OpenDup, the cursor will not be closed and will still be part + ** of a BtShared.pCursor list. */ + p->apCsr[iCur]->isEphemeral = 0; sqlite3VdbeFreeCursor(p, p->apCsr[iCur]); p->apCsr[iCur] = 0; } @@ -83258,6 +83651,7 @@ SQLITE_PRIVATE void sqlite3ValueApplyAffinity( static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){ assert( (pMem->flags & (MEM_Int|MEM_Real))==0 ); assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ); + ExpandBlob(pMem); if( sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc)==0 ){ return 0; } @@ -84545,8 +84939,8 @@ fp_math: break; } default: { - iA = (i64)rA; - iB = (i64)rB; + iA = sqlite3VdbeIntValue(pIn1); + iB = sqlite3VdbeIntValue(pIn2); if( iA==0 ) goto arithmetic_result_is_null; if( iA==-1 ) iA = 1; rB = (double)(iB % iA); @@ -84892,7 +85286,8 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ */ assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne ); assert( (flags1 & MEM_Cleared)==0 ); - assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 ); + assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 || CORRUPT_DB ); + testcase( (pOp->p5 & SQLITE_JUMPIFNULL)!=0 ); if( (flags1&flags3&MEM_Null)!=0 && (flags3&MEM_Cleared)==0 ){ @@ -86576,7 +86971,8 @@ case OP_OpenDup: { pCx->isEphemeral = 1; pCx->pKeyInfo = pOrig->pKeyInfo; pCx->isTable = pOrig->isTable; - rc = sqlite3BtreeCursor(pOrig->pBtx, MASTER_ROOT, BTREE_WRCSR, + pCx->pgnoRoot = pOrig->pgnoRoot; + rc = sqlite3BtreeCursor(pOrig->pBtx, pCx->pgnoRoot, BTREE_WRCSR, pCx->pKeyInfo, pCx->uc.pCursor); /* The sqlite3BtreeCursor() routine can only fail for the first cursor ** opened for a database. Since there is already an open cursor when this @@ -86594,6 +86990,9 @@ case OP_OpenDup: { ** the main database is read-only. The ephemeral ** table is deleted automatically when the cursor is closed. ** +** If the cursor P1 is already opened on an ephemeral table, the table +** is cleared (all content is erased). +** ** P2 is the number of columns in the ephemeral table. ** The cursor points to a BTree table if P4==0 and to a BTree index ** if P4 is not 0. If P4 is not NULL, it points to a KeyInfo structure @@ -86625,41 +87024,50 @@ case OP_OpenEphemeral: { SQLITE_OPEN_TRANSIENT_DB; assert( pOp->p1>=0 ); assert( pOp->p2>=0 ); - pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE); - if( pCx==0 ) goto no_mem; - pCx->nullRow = 1; - pCx->isEphemeral = 1; - rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx, - BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags); - if( rc==SQLITE_OK ){ - rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1, 0); - } - if( rc==SQLITE_OK ){ - /* If a transient index is required, create it by calling - ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before - ** opening it. If a transient table is required, just use the - ** automatically created table with root-page 1 (an BLOB_INTKEY table). - */ - if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){ - int pgno; - assert( pOp->p4type==P4_KEYINFO ); - rc = sqlite3BtreeCreateTable(pCx->pBtx, &pgno, BTREE_BLOBKEY | pOp->p5); - if( rc==SQLITE_OK ){ - assert( pgno==MASTER_ROOT+1 ); - assert( pKeyInfo->db==db ); - assert( pKeyInfo->enc==ENC(db) ); - rc = sqlite3BtreeCursor(pCx->pBtx, pgno, BTREE_WRCSR, - pKeyInfo, pCx->uc.pCursor); - } - pCx->isTable = 0; - }else{ - rc = sqlite3BtreeCursor(pCx->pBtx, MASTER_ROOT, BTREE_WRCSR, - 0, pCx->uc.pCursor); - pCx->isTable = 1; + pCx = p->apCsr[pOp->p1]; + if( pCx ){ + /* If the ephermeral table is already open, erase all existing content + ** so that the table is empty again, rather than creating a new table. */ + rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0); + }else{ + pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE); + if( pCx==0 ) goto no_mem; + pCx->nullRow = 1; + pCx->isEphemeral = 1; + rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx, + BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, + vfsFlags); + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1, 0); } + if( rc==SQLITE_OK ){ + /* If a transient index is required, create it by calling + ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before + ** opening it. If a transient table is required, just use the + ** automatically created table with root-page 1 (an BLOB_INTKEY table). + */ + if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){ + assert( pOp->p4type==P4_KEYINFO ); + rc = sqlite3BtreeCreateTable(pCx->pBtx, (int*)&pCx->pgnoRoot, + BTREE_BLOBKEY | pOp->p5); + if( rc==SQLITE_OK ){ + assert( pCx->pgnoRoot==MASTER_ROOT+1 ); + assert( pKeyInfo->db==db ); + assert( pKeyInfo->enc==ENC(db) ); + rc = sqlite3BtreeCursor(pCx->pBtx, pCx->pgnoRoot, BTREE_WRCSR, + pKeyInfo, pCx->uc.pCursor); + } + pCx->isTable = 0; + }else{ + pCx->pgnoRoot = MASTER_ROOT; + rc = sqlite3BtreeCursor(pCx->pBtx, MASTER_ROOT, BTREE_WRCSR, + 0, pCx->uc.pCursor); + pCx->isTable = 1; + } + } + pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); } if( rc ) goto abort_due_to_error; - pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); break; } @@ -87309,7 +87717,7 @@ case OP_NotExists: /* jump, in3 */ pC = p->apCsr[pOp->p1]; assert( pC!=0 ); #ifdef SQLITE_DEBUG - pC->seekOp = OP_SeekRowid; + if( pOp->opcode==OP_SeekRowid ) pC->seekOp = OP_SeekRowid; #endif assert( pC->isTable ); assert( pC->eCurType==CURTYPE_BTREE ); @@ -88217,7 +88625,7 @@ case OP_Next: /* jump */ assert( pOp->opcode!=OP_Next || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found - || pC->seekOp==OP_NullRow); + || pC->seekOp==OP_NullRow|| pC->seekOp==OP_SeekRowid); assert( pOp->opcode!=OP_Prev || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE || pC->seekOp==OP_Last @@ -88747,9 +89155,16 @@ case OP_ParseSchema: { assert( db->init.busy==0 ); db->init.busy = 1; initData.rc = SQLITE_OK; + initData.nInitRow = 0; assert( !db->mallocFailed ); rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); if( rc==SQLITE_OK ) rc = initData.rc; + if( rc==SQLITE_OK && initData.nInitRow==0 ){ + /* The OP_ParseSchema opcode with a non-NULL P4 argument should parse + ** at least one SQL statement. Any less than that indicates that + ** the sqlite_master table is corrupt. */ + rc = SQLITE_CORRUPT_BKPT; + } sqlite3DbFreeNN(db, zSql); db->init.busy = 0; } @@ -89112,6 +89527,17 @@ case OP_Program: { /* jump */ p->nOp = pProgram->nOp; #ifdef SQLITE_ENABLE_STMT_SCANSTATUS p->anExec = 0; +#endif +#ifdef SQLITE_DEBUG + /* Verify that second and subsequent executions of the same trigger do not + ** try to reuse register values from the first use. */ + { + int i; + for(i=0; i<p->nMem; i++){ + aMem[i].pScopyFrom = 0; /* Prevent false-positive AboutToChange() errs */ + aMem[i].flags |= MEM_Undefined; /* Cause a fault if this reg is reused */ + } + } #endif pOp = &aOp[-1]; @@ -89651,14 +90077,19 @@ case OP_JournalMode: { /* out2 */ #endif /* SQLITE_OMIT_PRAGMA */ #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) -/* Opcode: Vacuum P1 * * * * +/* Opcode: Vacuum P1 P2 * * * ** ** Vacuum the entire database P1. P1 is 0 for "main", and 2 or more ** for an attached database. The "temp" database may not be vacuumed. +** +** If P2 is not zero, then it is a register holding a string which is +** the file into which the result of vacuum should be written. When +** P2 is zero, the vacuum overwrites the original database. */ case OP_Vacuum: { assert( p->readOnly==0 ); - rc = sqlite3RunVacuum(&p->zErrMsg, db, pOp->p1); + rc = sqlite3RunVacuum(&p->zErrMsg, db, pOp->p1, + pOp->p2 ? &aMem[pOp->p2] : 0); if( rc ) goto abort_due_to_error; break; } @@ -89810,6 +90241,7 @@ case OP_VDestroy: { db->nVDestroy++; rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z); db->nVDestroy--; + assert( p->errorAction==OE_Abort && p->usesStmtJournal ); if( rc ) goto abort_due_to_error; break; } @@ -90053,7 +90485,7 @@ case OP_VRename: { rc = sqlite3VdbeChangeEncoding(pName, SQLITE_UTF8); if( rc ) goto abort_due_to_error; rc = pVtab->pModule->xRename(pVtab, pName->z); - if( isLegacy==0 ) db->flags &= ~SQLITE_LegacyAlter; + if( isLegacy==0 ) db->flags &= ~(u64)SQLITE_LegacyAlter; sqlite3VtabImportErrmsg(p, pVtab); p->expired = 0; if( rc ) goto abort_due_to_error; @@ -94280,6 +94712,22 @@ SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){ /* #include <string.h> */ +#if !defined(SQLITE_OMIT_WINDOWFUNC) +/* +** Walk all expressions linked into the list of Window objects passed +** as the second argument. +*/ +static int walkWindowList(Walker *pWalker, Window *pList){ + Window *pWin; + for(pWin=pList; pWin; pWin=pWin->pNextWin){ + if( sqlite3WalkExprList(pWalker, pWin->pOrderBy) ) return WRC_Abort; + if( sqlite3WalkExprList(pWalker, pWin->pPartition) ) return WRC_Abort; + if( sqlite3WalkExpr(pWalker, pWin->pFilter) ) return WRC_Abort; + } + return WRC_Continue; +} +#endif + /* ** Walk an expression tree. Invoke the callback once for each node ** of the expression, while descending. (In other words, the callback @@ -94319,10 +94767,7 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){ } #ifndef SQLITE_OMIT_WINDOWFUNC if( ExprHasProperty(pExpr, EP_WinFunc) ){ - Window *pWin = pExpr->y.pWin; - if( sqlite3WalkExprList(pWalker, pWin->pPartition) ) return WRC_Abort; - if( sqlite3WalkExprList(pWalker, pWin->pOrderBy) ) return WRC_Abort; - if( sqlite3WalkExpr(pWalker, pWin->pFilter) ) return WRC_Abort; + if( walkWindowList(pWalker, pExpr->y.pWin) ) return WRC_Abort; } #endif } @@ -94362,6 +94807,16 @@ SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){ if( sqlite3WalkExpr(pWalker, p->pHaving) ) return WRC_Abort; if( sqlite3WalkExprList(pWalker, p->pOrderBy) ) return WRC_Abort; if( sqlite3WalkExpr(pWalker, p->pLimit) ) return WRC_Abort; +#if !defined(SQLITE_OMIT_WINDOWFUNC) && !defined(SQLITE_OMIT_ALTERTABLE) + { + Parse *pParse = pWalker->pParse; + if( pParse && IN_RENAME_OBJECT ){ + int rc = walkWindowList(pWalker, p->pWinDefn); + assert( rc==WRC_Continue ); + return rc; + } + } +#endif return WRC_Continue; } @@ -94513,7 +94968,6 @@ static void resolveAlias( if( pExpr->op==TK_COLLATE ){ pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); } - ExprSetProperty(pDup, EP_Alias); /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This ** prevents ExprDelete() from deleting the Expr structure itself, @@ -94907,6 +95361,25 @@ static int lookupName( if( cnt==0 && zTab==0 ){ assert( pExpr->op==TK_ID ); if( ExprHasProperty(pExpr,EP_DblQuoted) ){ + /* If a double-quoted identifier does not match any known column name, + ** then treat it as a string. + ** + ** This hack was added in the early days of SQLite in a misguided attempt + ** to be compatible with MySQL 3.x, which used double-quotes for strings. + ** I now sorely regret putting in this hack. The effect of this hack is + ** that misspelled identifier names are silently converted into strings + ** rather than causing an error, to the frustration of countless + ** programmers. To all those frustrated programmers, my apologies. + ** + ** Someday, I hope to get rid of this hack. Unfortunately there is + ** a huge amount of legacy SQL that uses it. So for now, we just + ** issue a warning. + */ + sqlite3_log(SQLITE_WARNING, + "double-quoted string literal: \"%w\"", zCol); +#ifdef SQLITE_ENABLE_NORMALIZE + sqlite3VdbeAddDblquoteStr(db, pParse->pVdbe, zCol); +#endif pExpr->op = TK_STRING; pExpr->y.pTab = 0; return WRC_Prune; @@ -95273,10 +95746,10 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ #ifndef SQLITE_OMIT_WINDOWFUNC if( pExpr->y.pWin ){ Select *pSel = pNC->pWinSelect; + sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef); sqlite3WalkExprList(pWalker, pExpr->y.pWin->pPartition); sqlite3WalkExprList(pWalker, pExpr->y.pWin->pOrderBy); sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter); - sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef); if( 0==pSel->pWin || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->y.pWin) ){ @@ -95553,32 +96026,53 @@ static int resolveCompoundOrderBy( }else{ iCol = resolveAsName(pParse, pEList, pE); if( iCol==0 ){ - pDup = sqlite3ExprDup(db, pE, 0); + /* Now test if expression pE matches one of the values returned + ** by pSelect. In the usual case this is done by duplicating the + ** expression, resolving any symbols in it, and then comparing + ** it against each expression returned by the SELECT statement. + ** Once the comparisons are finished, the duplicate expression + ** is deleted. + ** + ** Or, if this is running as part of an ALTER TABLE operation, + ** resolve the symbols in the actual expression, not a duplicate. + ** And, if one of the comparisons is successful, leave the expression + ** as is instead of transforming it to an integer as in the usual + ** case. This allows the code in alter.c to modify column + ** refererences within the ORDER BY expression as required. */ + if( IN_RENAME_OBJECT ){ + pDup = pE; + }else{ + pDup = sqlite3ExprDup(db, pE, 0); + } if( !db->mallocFailed ){ assert(pDup); iCol = resolveOrderByTermToExprList(pParse, pSelect, pDup); } - sqlite3ExprDelete(db, pDup); + if( !IN_RENAME_OBJECT ){ + sqlite3ExprDelete(db, pDup); + } } } if( iCol>0 ){ /* Convert the ORDER BY term into an integer column number iCol, ** taking care to preserve the COLLATE clause if it exists */ - Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0); - if( pNew==0 ) return 1; - pNew->flags |= EP_IntValue; - pNew->u.iValue = iCol; - if( pItem->pExpr==pE ){ - pItem->pExpr = pNew; - }else{ - Expr *pParent = pItem->pExpr; - assert( pParent->op==TK_COLLATE ); - while( pParent->pLeft->op==TK_COLLATE ) pParent = pParent->pLeft; - assert( pParent->pLeft==pE ); - pParent->pLeft = pNew; + if( !IN_RENAME_OBJECT ){ + Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0); + if( pNew==0 ) return 1; + pNew->flags |= EP_IntValue; + pNew->u.iValue = iCol; + if( pItem->pExpr==pE ){ + pItem->pExpr = pNew; + }else{ + Expr *pParent = pItem->pExpr; + assert( pParent->op==TK_COLLATE ); + while( pParent->pLeft->op==TK_COLLATE ) pParent = pParent->pLeft; + assert( pParent->pLeft==pE ); + pParent->pLeft = pNew; + } + sqlite3ExprDelete(db, pE); + pItem->u.x.iOrderByCol = (u16)iCol; } - sqlite3ExprDelete(db, pE); - pItem->u.x.iOrderByCol = (u16)iCol; pItem->done = 1; }else{ moreToDo = 1; @@ -95927,6 +96421,17 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ } } + if( IN_RENAME_OBJECT ){ + Window *pWin; + for(pWin=p->pWinDefn; pWin; pWin=pWin->pNextWin){ + if( sqlite3ResolveExprListNames(&sNC, pWin->pOrderBy) + || sqlite3ResolveExprListNames(&sNC, pWin->pPartition) + ){ + return WRC_Abort; + } + } + } + /* If this is part of a compound SELECT, check that it has the right ** number of expressions in the select list. */ if( p->pNext && p->pEList->nExpr!=p->pNext->pEList->nExpr ){ @@ -96077,38 +96582,47 @@ SQLITE_PRIVATE void sqlite3ResolveSelectNames( } /* -** Resolve names in expressions that can only reference a single table: +** Resolve names in expressions that can only reference a single table +** or which cannot reference any tables at all. Examples: ** -** * CHECK constraints -** * WHERE clauses on partial indices +** (1) CHECK constraints +** (2) WHERE clauses on partial indices +** (3) Expressions in indexes on expressions +** (4) Expression arguments to VACUUM INTO. ** -** The Expr.iTable value for Expr.op==TK_COLUMN nodes of the expression -** is set to -1 and the Expr.iColumn value is set to the column number. +** In all cases except (4), the Expr.iTable value for Expr.op==TK_COLUMN +** nodes of the expression is set to -1 and the Expr.iColumn value is +** set to the column number. In case (4), TK_COLUMN nodes cause an error. ** ** Any errors cause an error message to be set in pParse. */ -SQLITE_PRIVATE void sqlite3ResolveSelfReference( +SQLITE_PRIVATE int sqlite3ResolveSelfReference( Parse *pParse, /* Parsing context */ - Table *pTab, /* The table being referenced */ - int type, /* NC_IsCheck or NC_PartIdx or NC_IdxExpr */ + Table *pTab, /* The table being referenced, or NULL */ + int type, /* NC_IsCheck or NC_PartIdx or NC_IdxExpr, or 0 */ Expr *pExpr, /* Expression to resolve. May be NULL. */ ExprList *pList /* Expression list to resolve. May be NULL. */ ){ SrcList sSrc; /* Fake SrcList for pParse->pNewTable */ NameContext sNC; /* Name context for pParse->pNewTable */ + int rc; - assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr ); + assert( type==0 || pTab!=0 ); + assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr || pTab==0 ); memset(&sNC, 0, sizeof(sNC)); memset(&sSrc, 0, sizeof(sSrc)); - sSrc.nSrc = 1; - sSrc.a[0].zName = pTab->zName; - sSrc.a[0].pTab = pTab; - sSrc.a[0].iCursor = -1; + if( pTab ){ + sSrc.nSrc = 1; + sSrc.a[0].zName = pTab->zName; + sSrc.a[0].pTab = pTab; + sSrc.a[0].iCursor = -1; + } sNC.pParse = pParse; sNC.pSrcList = &sSrc; sNC.ncFlags = type; - if( sqlite3ResolveExprNames(&sNC, pExpr) ) return; - if( pList ) sqlite3ResolveExprListNames(&sNC, pList); + if( (rc = sqlite3ResolveExprNames(&sNC, pExpr))!=SQLITE_OK ) return rc; + if( pList ) rc = sqlite3ResolveExprListNames(&sNC, pList); + return rc; } /************** End of resolve.c *********************************************/ @@ -96256,8 +96770,8 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ while( p ){ int op = p->op; if( p->flags & EP_Generic ) break; - if( (op==TK_AGG_COLUMN || op==TK_COLUMN - || op==TK_REGISTER || op==TK_TRIGGER) + if( op==TK_REGISTER ) op = p->op2; + if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_TRIGGER) && p->y.pTab!=0 ){ /* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally @@ -96273,7 +96787,7 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ p = p->pLeft; continue; } - if( op==TK_COLLATE || (op==TK_REGISTER && p->op2==TK_COLLATE) ){ + if( op==TK_COLLATE ){ pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken); break; } @@ -96580,6 +97094,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprForVectorField( }else{ if( pVector->op==TK_VECTOR ) pVector = pVector->x.pList->a[iField].pExpr; pRet = sqlite3ExprDup(pParse->db, pVector, 0); + sqlite3RenameTokenRemap(pParse, pRet, pVector); } return pRet; } @@ -96596,7 +97111,7 @@ static int exprCodeSubselect(Parse *pParse, Expr *pExpr){ int reg = 0; #ifndef SQLITE_OMIT_SUBQUERY if( pExpr->op==TK_SELECT ){ - reg = sqlite3CodeSubselect(pParse, pExpr, 0, 0); + reg = sqlite3CodeSubselect(pParse, pExpr); } #endif return reg; @@ -96668,7 +97183,7 @@ static void codeVectorCompare( int regLeft = 0; int regRight = 0; u8 opx = op; - int addrDone = sqlite3VdbeMakeLabel(v); + int addrDone = sqlite3VdbeMakeLabel(pParse); if( nLeft!=sqlite3ExprVectorSize(pRight) ){ sqlite3ErrorMsg(pParse, "row value misused"); @@ -96895,8 +97410,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAlloc( if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n); pNew->u.zToken[pToken->n] = 0; if( dequote && sqlite3Isquote(pNew->u.zToken[0]) ){ - if( pNew->u.zToken[0]=='"' ) pNew->flags |= EP_DblQuoted; - sqlite3Dequote(pNew->u.zToken); + sqlite3DequoteExpr(pNew); } } } @@ -96965,7 +97479,7 @@ SQLITE_PRIVATE Expr *sqlite3PExpr( Expr *pRight /* Right operand */ ){ Expr *p; - if( op==TK_AND && pParse->nErr==0 ){ + if( op==TK_AND && pParse->nErr==0 && !IN_RENAME_OBJECT ){ /* Take advantage of short-circuit false optimization for AND */ p = sqlite3ExprAnd(pParse->db, pLeft, pRight); }else{ @@ -97214,6 +97728,16 @@ static int exprStructSize(Expr *p){ return EXPR_FULLSIZE; } +/* +** Copy the complete content of an Expr node, taking care not to read +** past the end of the structure for a reduced-size version of the source +** Expr. +*/ +static void exprNodeCopy(Expr *pDest, Expr *pSrc){ + memset(pDest, 0, sizeof(Expr)); + memcpy(pDest, pSrc, exprStructSize(pSrc)); +} + /* ** The dupedExpr*Size() routines each return the number of bytes required ** to store a copy of an expression or expression tree. They differ in @@ -97445,6 +97969,36 @@ static With *withDup(sqlite3 *db, With *p){ # define withDup(x,y) 0 #endif +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** The gatherSelectWindows() procedure and its helper routine +** gatherSelectWindowsCallback() are used to scan all the expressions +** an a newly duplicated SELECT statement and gather all of the Window +** objects found there, assembling them onto the linked list at Select->pWin. +*/ +static int gatherSelectWindowsCallback(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_FUNCTION && pExpr->y.pWin!=0 ){ + assert( ExprHasProperty(pExpr, EP_WinFunc) ); + pExpr->y.pWin->pNextWin = pWalker->u.pSelect->pWin; + pWalker->u.pSelect->pWin = pExpr->y.pWin; + } + return WRC_Continue; +} +static int gatherSelectWindowsSelectCallback(Walker *pWalker, Select *p){ + return p==pWalker->u.pSelect ? WRC_Continue : WRC_Prune; +} +static void gatherSelectWindows(Select *p){ + Walker w; + w.xExprCallback = gatherSelectWindowsCallback; + w.xSelectCallback = gatherSelectWindowsSelectCallback; + w.xSelectCallback2 = 0; + w.pParse = 0; + w.u.pSelect = p; + sqlite3WalkSelect(&w, p); +} +#endif + + /* ** The following group of routines make deep copies of expressions, ** expression lists, ID lists, and select statements. The copies can @@ -97612,6 +98166,7 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){ #ifndef SQLITE_OMIT_WINDOWFUNC pNew->pWin = 0; pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn); + if( p->pWin ) gatherSelectWindows(pNew); #endif pNew->selId = p->selId; *pp = pNew; @@ -97744,6 +98299,9 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector( } vector_append_error: + if( IN_RENAME_OBJECT ){ + sqlite3RenameExprUnmap(pParse, pExpr); + } sqlite3ExprDelete(db, pExpr); sqlite3IdListDelete(db, pColumns); return pList; @@ -97887,8 +98445,9 @@ SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){ */ SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr *pExpr){ assert( pExpr->op==TK_ID || pExpr->op==TK_STRING ); - if( sqlite3StrICmp(pExpr->u.zToken, "true")==0 - || sqlite3StrICmp(pExpr->u.zToken, "false")==0 + if( !ExprHasProperty(pExpr, EP_Quoted) + && (sqlite3StrICmp(pExpr->u.zToken, "true")==0 + || sqlite3StrICmp(pExpr->u.zToken, "false")==0) ){ pExpr->op = TK_TRUEFALSE; return 1; @@ -98197,7 +98756,9 @@ SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){ */ SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){ u8 op; - while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ p = p->pLeft; } + while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ + p = p->pLeft; + } op = p->op; if( op==TK_REGISTER ) op = p->op2; switch( op ){ @@ -98264,14 +98825,6 @@ SQLITE_PRIVATE int sqlite3IsRowid(const char *z){ if( sqlite3StrICmp(z, "OID")==0 ) return 1; return 0; } -#ifdef SQLITE_ENABLE_NORMALIZE -SQLITE_PRIVATE int sqlite3IsRowidN(const char *z, int n){ - if( sqlite3StrNICmp(z, "_ROWID_", n)==0 ) return 1; - if( sqlite3StrNICmp(z, "ROWID", n)==0 ) return 1; - if( sqlite3StrNICmp(z, "OID", n)==0 ) return 1; - return 0; -} -#endif /* ** pX is the RHS of an IN operator. If pX is a SELECT statement @@ -98441,7 +98994,8 @@ SQLITE_PRIVATE int sqlite3FindInIndex( Expr *pX, /* The right-hand side (RHS) of the IN operator */ u32 inFlags, /* IN_INDEX_LOOP, _MEMBERSHIP, and/or _NOOP_OK */ int *prRhsHasNull, /* Register holding NULL status. See notes */ - int *aiMap /* Mapping from Index fields to RHS fields */ + int *aiMap, /* Mapping from Index fields to RHS fields */ + int *piTab /* OUT: index to use */ ){ Select *p; /* SELECT to the right of IN operator */ int eType = 0; /* Type of RHS table. IN_INDEX_* */ @@ -98536,6 +99090,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex( Bitmask colUsed; /* Columns of the index used */ Bitmask mCol; /* Mask for the current column */ if( pIdx->nColumn<nExpr ) continue; + if( pIdx->pPartIdxWhere!=0 ) continue; /* Maximum nColumn is BMS-2, not BMS-1, so that we can compute ** BITMASK(nExpr) without overflowing */ testcase( pIdx->nColumn==BMS-2 ); @@ -98632,10 +99187,12 @@ SQLITE_PRIVATE int sqlite3FindInIndex( }else if( prRhsHasNull ){ *prRhsHasNull = rMayHaveNull = ++pParse->nMem; } - sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID); + assert( pX->op==TK_IN ); + sqlite3CodeRhsOfIN(pParse, pX, iTab, eType==IN_INDEX_ROWID); + if( rMayHaveNull ){ + sqlite3SetHasNullFlag(v, iTab, rMayHaveNull); + } pParse->nQueryLoop = savedNQueryLoop; - }else{ - pX->iTable = iTab; } if( aiMap && eType!=IN_INDEX_INDEX_ASC && eType!=IN_INDEX_INDEX_DESC ){ @@ -98643,6 +99200,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex( n = sqlite3ExprVectorSize(pX->pLeft); for(i=0; i<n; i++) aiMap[i] = i; } + *piTab = iTab; return eType; } #endif @@ -98716,48 +99274,252 @@ SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){ } } +#ifndef SQLITE_OMIT_SUBQUERY /* -** Generate code for scalar subqueries used as a subquery expression, EXISTS, -** or IN operators. Examples: +** Generate code that will construct an ephemeral table containing all terms +** in the RHS of an IN operator. The IN operator can be in either of two +** forms: ** -** (SELECT a FROM b) -- subquery -** EXISTS (SELECT a FROM b) -- EXISTS subquery ** x IN (4,5,11) -- IN operator with list on right-hand side ** x IN (SELECT a FROM b) -- IN operator with subquery on the right ** -** The pExpr parameter describes the expression that contains the IN -** operator or subquery. +** The pExpr parameter is the IN operator. The cursor number for the +** constructed ephermeral table is returned. The first time the ephemeral +** table is computed, the cursor number is also stored in pExpr->iTable, +** however the cursor number returned might not be the same, as it might +** have been duplicated using OP_OpenDup. ** -** If parameter isRowid is non-zero, then expression pExpr is guaranteed -** to be of the form "<rowid> IN (?, ?, ?)", where <rowid> is a reference -** to some integer key column of a table B-Tree. In this case, use an -** intkey B-Tree to store the set of IN(...) values instead of the usual -** (slower) variable length keys B-Tree. +** If parameter isRowid is non-zero, then LHS of the IN operator is guaranteed +** to be a non-null integer. In this case, the ephemeral table can be an +** table B-Tree that keyed by only integers. The more general cases uses +** an index B-Tree which can have arbitrary keys, but is slower to both +** read and write. ** -** If rMayHaveNull is non-zero, that means that the operation is an IN -** (not a SELECT or EXISTS) and that the RHS might contains NULLs. -** All this routine does is initialize the register given by rMayHaveNull -** to NULL. Calling routines will take care of changing this register -** value to non-NULL if the RHS is NULL-free. +** If the LHS expression ("x" in the examples) is a column value, or +** the SELECT statement returns a column value, then the affinity of that +** column is used to build the index keys. If both 'x' and the +** SELECT... statement are columns, then numeric affinity is used +** if either column has NUMERIC or INTEGER affinity. If neither +** 'x' nor the SELECT... statement are columns, then numeric affinity +** is used. +*/ +SQLITE_PRIVATE void sqlite3CodeRhsOfIN( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* The IN operator */ + int iTab, /* Use this cursor number */ + int isRowid /* If true, LHS is a rowid */ +){ + int addrOnce = 0; /* Address of the OP_Once instruction at top */ + int addr; /* Address of OP_OpenEphemeral instruction */ + Expr *pLeft; /* the LHS of the IN operator */ + KeyInfo *pKeyInfo = 0; /* Key information */ + int nVal; /* Size of vector pLeft */ + Vdbe *v; /* The prepared statement under construction */ + + v = pParse->pVdbe; + assert( v!=0 ); + + /* The evaluation of the IN must be repeated every time it + ** is encountered if any of the following is true: + ** + ** * The right-hand side is a correlated subquery + ** * The right-hand side is an expression list containing variables + ** * We are inside a trigger + ** + ** If all of the above are false, then we can compute the RHS just once + ** and reuse it many names. + */ + if( !ExprHasProperty(pExpr, EP_VarSelect) && pParse->iSelfTab==0 ){ + /* Reuse of the RHS is allowed */ + /* If this routine has already been coded, but the previous code + ** might not have been invoked yet, so invoke it now as a subroutine. + */ + if( ExprHasProperty(pExpr, EP_Subrtn) ){ + addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + ExplainQueryPlan((pParse, 0, "REUSE LIST SUBQUERY %d", + pExpr->x.pSelect->selId)); + } + sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, + pExpr->y.sub.iAddr); + sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable); + sqlite3VdbeJumpHere(v, addrOnce); + return; + } + + /* Begin coding the subroutine */ + ExprSetProperty(pExpr, EP_Subrtn); + pExpr->y.sub.regReturn = ++pParse->nMem; + pExpr->y.sub.iAddr = + sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1; + VdbeComment((v, "return address")); + + addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + } + + /* Check to see if this is a vector IN operator */ + pLeft = pExpr->pLeft; + nVal = sqlite3ExprVectorSize(pLeft); + assert( !isRowid || nVal==1 ); + + /* Construct the ephemeral table that will contain the content of + ** RHS of the IN operator. + */ + pExpr->iTable = iTab; + addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, + pExpr->iTable, (isRowid?0:nVal)); +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + VdbeComment((v, "Result of SELECT %u", pExpr->x.pSelect->selId)); + }else{ + VdbeComment((v, "RHS of IN operator")); + } +#endif + pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, nVal, 1); + + if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + /* Case 1: expr IN (SELECT ...) + ** + ** Generate code to write the results of the select into the temporary + ** table allocated and opened above. + */ + Select *pSelect = pExpr->x.pSelect; + ExprList *pEList = pSelect->pEList; + + ExplainQueryPlan((pParse, 1, "%sLIST SUBQUERY %d", + addrOnce?"":"CORRELATED ", pSelect->selId + )); + assert( !isRowid ); + /* If the LHS and RHS of the IN operator do not match, that + ** error will have been caught long before we reach this point. */ + if( ALWAYS(pEList->nExpr==nVal) ){ + SelectDest dest; + int i; + sqlite3SelectDestInit(&dest, SRT_Set, iTab); + dest.zAffSdst = exprINAffinity(pParse, pExpr); + pSelect->iLimit = 0; + testcase( pSelect->selFlags & SF_Distinct ); + testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ + if( sqlite3Select(pParse, pSelect, &dest) ){ + sqlite3DbFree(pParse->db, dest.zAffSdst); + sqlite3KeyInfoUnref(pKeyInfo); + return; + } + sqlite3DbFree(pParse->db, dest.zAffSdst); + assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */ + assert( pEList!=0 ); + assert( pEList->nExpr>0 ); + assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); + for(i=0; i<nVal; i++){ + Expr *p = sqlite3VectorFieldSubexpr(pLeft, i); + pKeyInfo->aColl[i] = sqlite3BinaryCompareCollSeq( + pParse, p, pEList->a[i].pExpr + ); + } + } + }else if( ALWAYS(pExpr->x.pList!=0) ){ + /* Case 2: expr IN (exprlist) + ** + ** For each expression, build an index key from the evaluation and + ** store it in the temporary table. If <expr> is a column, then use + ** that columns affinity when building index keys. If <expr> is not + ** a column, use numeric affinity. + */ + char affinity; /* Affinity of the LHS of the IN */ + int i; + ExprList *pList = pExpr->x.pList; + struct ExprList_item *pItem; + int r1, r2, r3; + affinity = sqlite3ExprAffinity(pLeft); + if( !affinity ){ + affinity = SQLITE_AFF_BLOB; + } + if( pKeyInfo ){ + assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); + pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft); + } + + /* Loop through each expression in <exprlist>. */ + r1 = sqlite3GetTempReg(pParse); + r2 = sqlite3GetTempReg(pParse); + if( isRowid ) sqlite3VdbeAddOp4(v, OP_Blob, 0, r2, 0, "", P4_STATIC); + for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){ + Expr *pE2 = pItem->pExpr; + int iValToIns; + + /* If the expression is not constant then we will need to + ** disable the test that was generated above that makes sure + ** this code only executes once. Because for a non-constant + ** expression we need to rerun this code each time. + */ + if( addrOnce && !sqlite3ExprIsConstant(pE2) ){ + sqlite3VdbeChangeToNoop(v, addrOnce); + addrOnce = 0; + } + + /* Evaluate the expression and insert it into the temp table */ + if( isRowid && sqlite3ExprIsInteger(pE2, &iValToIns) ){ + sqlite3VdbeAddOp3(v, OP_InsertInt, iTab, r2, iValToIns); + }else{ + r3 = sqlite3ExprCodeTarget(pParse, pE2, r1); + if( isRowid ){ + sqlite3VdbeAddOp2(v, OP_MustBeInt, r3, + sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_Insert, iTab, r2, r3); + }else{ + sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r3, 1); + } + } + } + sqlite3ReleaseTempReg(pParse, r1); + sqlite3ReleaseTempReg(pParse, r2); + } + if( pKeyInfo ){ + sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO); + } + if( addrOnce ){ + sqlite3VdbeJumpHere(v, addrOnce); + /* Subroutine return */ + sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn); + sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1); + } +} +#endif /* SQLITE_OMIT_SUBQUERY */ + +/* +** Generate code for scalar subqueries used as a subquery expression +** or EXISTS operator: ** -** For a SELECT or EXISTS operator, return the register that holds the -** result. For a multi-column SELECT, the result is stored in a contiguous -** array of registers and the return value is the register of the left-most -** result column. Return 0 for IN operators or if an error occurs. +** (SELECT a FROM b) -- subquery +** EXISTS (SELECT a FROM b) -- EXISTS subquery +** +** The pExpr parameter is the SELECT or EXISTS operator to be coded. +** +** The register that holds the result. For a multi-column SELECT, +** the result is stored in a contiguous array of registers and the +** return value is the register of the left-most result column. +** Return 0 if an error occurs. */ #ifndef SQLITE_OMIT_SUBQUERY -SQLITE_PRIVATE int sqlite3CodeSubselect( - Parse *pParse, /* Parsing context */ - Expr *pExpr, /* The IN, SELECT, or EXISTS operator */ - int rHasNullFlag, /* Register that records whether NULLs exist in RHS */ - int isRowid /* If true, LHS of IN operator is a rowid */ -){ - int jmpIfDynamic = -1; /* One-time test address */ - int rReg = 0; /* Register storing resulting */ - Vdbe *v = sqlite3GetVdbe(pParse); - if( NEVER(v==0) ) return 0; +SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ + int addrOnce = 0; /* Address of OP_Once at top of subroutine */ + int rReg = 0; /* Register storing resulting */ + Select *pSel; /* SELECT statement to encode */ + SelectDest dest; /* How to deal with SELECT result */ + int nReg; /* Registers to allocate */ + Expr *pLimit; /* New limit expression */ - /* The evaluation of the IN/EXISTS/SELECT must be repeated every time it + Vdbe *v = pParse->pVdbe; + assert( v!=0 ); + testcase( pExpr->op==TK_EXISTS ); + testcase( pExpr->op==TK_SELECT ); + assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT ); + assert( ExprHasProperty(pExpr, EP_xIsSelect) ); + pSel = pExpr->x.pSelect; + + /* The evaluation of the EXISTS/SELECT must be repeated every time it ** is encountered if any of the following is true: ** ** * The right-hand side is a correlated subquery @@ -98768,208 +99530,70 @@ SQLITE_PRIVATE int sqlite3CodeSubselect( ** save the results, and reuse the same result on subsequent invocations. */ if( !ExprHasProperty(pExpr, EP_VarSelect) ){ - jmpIfDynamic = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); - } - - switch( pExpr->op ){ - case TK_IN: { - int addr; /* Address of OP_OpenEphemeral instruction */ - Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */ - KeyInfo *pKeyInfo = 0; /* Key information */ - int nVal; /* Size of vector pLeft */ - - nVal = sqlite3ExprVectorSize(pLeft); - assert( !isRowid || nVal==1 ); - - /* Whether this is an 'x IN(SELECT...)' or an 'x IN(<exprlist>)' - ** expression it is handled the same way. An ephemeral table is - ** filled with index keys representing the results from the - ** SELECT or the <exprlist>. - ** - ** If the 'x' expression is a column value, or the SELECT... - ** statement returns a column value, then the affinity of that - ** column is used to build the index keys. If both 'x' and the - ** SELECT... statement are columns, then numeric affinity is used - ** if either column has NUMERIC or INTEGER affinity. If neither - ** 'x' nor the SELECT... statement are columns, then numeric affinity - ** is used. - */ - pExpr->iTable = pParse->nTab++; - addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, - pExpr->iTable, (isRowid?0:nVal)); - pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, nVal, 1); - - if( ExprHasProperty(pExpr, EP_xIsSelect) ){ - /* Case 1: expr IN (SELECT ...) - ** - ** Generate code to write the results of the select into the temporary - ** table allocated and opened above. - */ - Select *pSelect = pExpr->x.pSelect; - ExprList *pEList = pSelect->pEList; - - ExplainQueryPlan((pParse, 1, "%sLIST SUBQUERY", - jmpIfDynamic>=0?"":"CORRELATED " - )); - assert( !isRowid ); - /* If the LHS and RHS of the IN operator do not match, that - ** error will have been caught long before we reach this point. */ - if( ALWAYS(pEList->nExpr==nVal) ){ - SelectDest dest; - int i; - sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable); - dest.zAffSdst = exprINAffinity(pParse, pExpr); - pSelect->iLimit = 0; - testcase( pSelect->selFlags & SF_Distinct ); - testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ - if( sqlite3Select(pParse, pSelect, &dest) ){ - sqlite3DbFree(pParse->db, dest.zAffSdst); - sqlite3KeyInfoUnref(pKeyInfo); - return 0; - } - sqlite3DbFree(pParse->db, dest.zAffSdst); - assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */ - assert( pEList!=0 ); - assert( pEList->nExpr>0 ); - assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); - for(i=0; i<nVal; i++){ - Expr *p = sqlite3VectorFieldSubexpr(pLeft, i); - pKeyInfo->aColl[i] = sqlite3BinaryCompareCollSeq( - pParse, p, pEList->a[i].pExpr - ); - } - } - }else if( ALWAYS(pExpr->x.pList!=0) ){ - /* Case 2: expr IN (exprlist) - ** - ** For each expression, build an index key from the evaluation and - ** store it in the temporary table. If <expr> is a column, then use - ** that columns affinity when building index keys. If <expr> is not - ** a column, use numeric affinity. - */ - char affinity; /* Affinity of the LHS of the IN */ - int i; - ExprList *pList = pExpr->x.pList; - struct ExprList_item *pItem; - int r1, r2, r3; - affinity = sqlite3ExprAffinity(pLeft); - if( !affinity ){ - affinity = SQLITE_AFF_BLOB; - } - if( pKeyInfo ){ - assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); - pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft); - } - - /* Loop through each expression in <exprlist>. */ - r1 = sqlite3GetTempReg(pParse); - r2 = sqlite3GetTempReg(pParse); - if( isRowid ) sqlite3VdbeAddOp4(v, OP_Blob, 0, r2, 0, "", P4_STATIC); - for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){ - Expr *pE2 = pItem->pExpr; - int iValToIns; - - /* If the expression is not constant then we will need to - ** disable the test that was generated above that makes sure - ** this code only executes once. Because for a non-constant - ** expression we need to rerun this code each time. - */ - if( jmpIfDynamic>=0 && !sqlite3ExprIsConstant(pE2) ){ - sqlite3VdbeChangeToNoop(v, jmpIfDynamic); - jmpIfDynamic = -1; - } - - /* Evaluate the expression and insert it into the temp table */ - if( isRowid && sqlite3ExprIsInteger(pE2, &iValToIns) ){ - sqlite3VdbeAddOp3(v, OP_InsertInt, pExpr->iTable, r2, iValToIns); - }else{ - r3 = sqlite3ExprCodeTarget(pParse, pE2, r1); - if( isRowid ){ - sqlite3VdbeAddOp2(v, OP_MustBeInt, r3, - sqlite3VdbeCurrentAddr(v)+2); - VdbeCoverage(v); - sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3); - }else{ - sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1); - sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pExpr->iTable, r2, r3, 1); - } - } - } - sqlite3ReleaseTempReg(pParse, r1); - sqlite3ReleaseTempReg(pParse, r2); - } - if( pKeyInfo ){ - sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO); - } - break; + /* If this routine has already been coded, then invoke it as a + ** subroutine. */ + if( ExprHasProperty(pExpr, EP_Subrtn) ){ + ExplainQueryPlan((pParse, 0, "REUSE SUBQUERY %d", pSel->selId)); + sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, + pExpr->y.sub.iAddr); + return pExpr->iTable; } - case TK_EXISTS: - case TK_SELECT: - default: { - /* Case 3: (SELECT ... FROM ...) - ** or: EXISTS(SELECT ... FROM ...) - ** - ** For a SELECT, generate code to put the values for all columns of - ** the first row into an array of registers and return the index of - ** the first register. - ** - ** If this is an EXISTS, write an integer 0 (not exists) or 1 (exists) - ** into a register and return that register number. - ** - ** In both cases, the query is augmented with "LIMIT 1". Any - ** preexisting limit is discarded in place of the new LIMIT 1. - */ - Select *pSel; /* SELECT statement to encode */ - SelectDest dest; /* How to deal with SELECT result */ - int nReg; /* Registers to allocate */ - Expr *pLimit; /* New limit expression */ + /* Begin coding the subroutine */ + ExprSetProperty(pExpr, EP_Subrtn); + pExpr->y.sub.regReturn = ++pParse->nMem; + pExpr->y.sub.iAddr = + sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1; + VdbeComment((v, "return address")); - testcase( pExpr->op==TK_EXISTS ); - testcase( pExpr->op==TK_SELECT ); - assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT ); - assert( ExprHasProperty(pExpr, EP_xIsSelect) ); - - pSel = pExpr->x.pSelect; - ExplainQueryPlan((pParse, 1, "%sSCALAR SUBQUERY", - jmpIfDynamic>=0?"":"CORRELATED ")); - nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1; - sqlite3SelectDestInit(&dest, 0, pParse->nMem+1); - pParse->nMem += nReg; - if( pExpr->op==TK_SELECT ){ - dest.eDest = SRT_Mem; - dest.iSdst = dest.iSDParm; - dest.nSdst = nReg; - sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1); - VdbeComment((v, "Init subquery result")); - }else{ - dest.eDest = SRT_Exists; - sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm); - VdbeComment((v, "Init EXISTS result")); - } - pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[1], 0); - if( pSel->pLimit ){ - sqlite3ExprDelete(pParse->db, pSel->pLimit->pLeft); - pSel->pLimit->pLeft = pLimit; - }else{ - pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0); - } - pSel->iLimit = 0; - if( sqlite3Select(pParse, pSel, &dest) ){ - return 0; - } - rReg = dest.iSDParm; - ExprSetVVAProperty(pExpr, EP_NoReduce); - break; - } + addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); } - - if( rHasNullFlag ){ - sqlite3SetHasNullFlag(v, pExpr->iTable, rHasNullFlag); + + /* For a SELECT, generate code to put the values for all columns of + ** the first row into an array of registers and return the index of + ** the first register. + ** + ** If this is an EXISTS, write an integer 0 (not exists) or 1 (exists) + ** into a register and return that register number. + ** + ** In both cases, the query is augmented with "LIMIT 1". Any + ** preexisting limit is discarded in place of the new LIMIT 1. + */ + ExplainQueryPlan((pParse, 1, "%sSCALAR SUBQUERY %d", + addrOnce?"":"CORRELATED ", pSel->selId)); + nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1; + sqlite3SelectDestInit(&dest, 0, pParse->nMem+1); + pParse->nMem += nReg; + if( pExpr->op==TK_SELECT ){ + dest.eDest = SRT_Mem; + dest.iSdst = dest.iSDParm; + dest.nSdst = nReg; + sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1); + VdbeComment((v, "Init subquery result")); + }else{ + dest.eDest = SRT_Exists; + sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm); + VdbeComment((v, "Init EXISTS result")); } + pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[1], 0); + if( pSel->pLimit ){ + sqlite3ExprDelete(pParse->db, pSel->pLimit->pLeft); + pSel->pLimit->pLeft = pLimit; + }else{ + pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0); + } + pSel->iLimit = 0; + if( sqlite3Select(pParse, pSel, &dest) ){ + return 0; + } + pExpr->iTable = rReg = dest.iSDParm; + ExprSetVVAProperty(pExpr, EP_NoReduce); + if( addrOnce ){ + sqlite3VdbeJumpHere(v, addrOnce); - if( jmpIfDynamic>=0 ){ - sqlite3VdbeJumpHere(v, jmpIfDynamic); + /* Subroutine return */ + sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn); + sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1); } return rReg; @@ -99046,6 +99670,7 @@ static void sqlite3ExprCodeIN( int addrTruthOp; /* Address of opcode that determines the IN is true */ int destNotNull; /* Jump here if a comparison is not true in step 6 */ int addrTop; /* Top of the step-6 loop */ + int iTab = 0; /* Index to use */ pLeft = pExpr->pLeft; if( sqlite3ExprCheckIN(pParse, pExpr) ) return; @@ -99057,7 +99682,7 @@ static void sqlite3ExprCodeIN( if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error; /* Attempt to compute the RHS. After this step, if anything other than - ** IN_INDEX_NOOP is returned, the table opened ith cursor pExpr->iTable + ** IN_INDEX_NOOP is returned, the table opened with cursor iTab ** contains the values that make up the RHS. If IN_INDEX_NOOP is returned, ** the RHS has not yet been coded. */ v = pParse->pVdbe; @@ -99065,7 +99690,8 @@ static void sqlite3ExprCodeIN( VdbeNoopComment((v, "begin IN expr")); eType = sqlite3FindInIndex(pParse, pExpr, IN_INDEX_MEMBERSHIP | IN_INDEX_NOOP_OK, - destIfFalse==destIfNull ? 0 : &rRhsHasNull, aiMap); + destIfFalse==destIfNull ? 0 : &rRhsHasNull, + aiMap, &iTab); assert( pParse->nErr || nVector==1 || eType==IN_INDEX_EPH || eType==IN_INDEX_INDEX_ASC || eType==IN_INDEX_INDEX_DESC @@ -99111,7 +99737,7 @@ static void sqlite3ExprCodeIN( if( eType==IN_INDEX_NOOP ){ ExprList *pList = pExpr->x.pList; CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft); - int labelOk = sqlite3VdbeMakeLabel(v); + int labelOk = sqlite3VdbeMakeLabel(pParse); int r2, regToFree; int regCkNull = 0; int ii; @@ -99155,7 +99781,7 @@ static void sqlite3ExprCodeIN( if( destIfNull==destIfFalse ){ destStep2 = destIfFalse; }else{ - destStep2 = destStep6 = sqlite3VdbeMakeLabel(v); + destStep2 = destStep6 = sqlite3VdbeMakeLabel(pParse); } for(i=0; i<nVector; i++){ Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i); @@ -99173,19 +99799,19 @@ static void sqlite3ExprCodeIN( /* In this case, the RHS is the ROWID of table b-tree and so we also ** know that the RHS is non-NULL. Hence, we combine steps 3 and 4 ** into a single opcode. */ - sqlite3VdbeAddOp3(v, OP_SeekRowid, pExpr->iTable, destIfFalse, rLhs); + sqlite3VdbeAddOp3(v, OP_SeekRowid, iTab, destIfFalse, rLhs); VdbeCoverage(v); addrTruthOp = sqlite3VdbeAddOp0(v, OP_Goto); /* Return True */ }else{ sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector); if( destIfFalse==destIfNull ){ /* Combine Step 3 and Step 5 into a single opcode */ - sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse, + sqlite3VdbeAddOp4Int(v, OP_NotFound, iTab, destIfFalse, rLhs, nVector); VdbeCoverage(v); goto sqlite3ExprCodeIN_finished; } /* Ordinary Step 3, for the case where FALSE and NULL are distinct */ - addrTruthOp = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, + addrTruthOp = sqlite3VdbeAddOp4Int(v, OP_Found, iTab, 0, rLhs, nVector); VdbeCoverage(v); } @@ -99210,10 +99836,10 @@ static void sqlite3ExprCodeIN( ** of the RHS. */ if( destStep6 ) sqlite3VdbeResolveLabel(v, destStep6); - addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse); + addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, destIfFalse); VdbeCoverage(v); if( nVector>1 ){ - destNotNull = sqlite3VdbeMakeLabel(v); + destNotNull = sqlite3VdbeMakeLabel(pParse); }else{ /* For nVector==1, combine steps 6 and 7 by immediately returning ** FALSE if the first comparison is not NULL */ @@ -99225,7 +99851,7 @@ static void sqlite3ExprCodeIN( int r3 = sqlite3GetTempReg(pParse); p = sqlite3VectorFieldSubexpr(pLeft, i); pColl = sqlite3ExprCollSeq(pParse, p); - sqlite3VdbeAddOp3(v, OP_Column, pExpr->iTable, i, r3); + sqlite3VdbeAddOp3(v, OP_Column, iTab, i, r3); sqlite3VdbeAddOp4(v, OP_Ne, rLhs+i, destNotNull, r3, (void*)pColl, P4_COLLSEQ); VdbeCoverage(v); @@ -99234,7 +99860,7 @@ static void sqlite3ExprCodeIN( sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull); if( nVector>1 ){ sqlite3VdbeResolveLabel(v, destNotNull); - sqlite3VdbeAddOp2(v, OP_Next, pExpr->iTable, addrTop+1); + sqlite3VdbeAddOp2(v, OP_Next, iTab, addrTop+1); VdbeCoverage(v); /* Step 7: If we reach this point, we know that the result must @@ -99433,7 +100059,7 @@ static int exprCodeVector(Parse *pParse, Expr *p, int *piFreeable){ #if SQLITE_OMIT_SUBQUERY iResult = 0; #else - iResult = sqlite3CodeSubselect(pParse, p, 0, 0); + iResult = sqlite3CodeSubselect(pParse, p); #endif }else{ int i; @@ -99778,7 +100404,7 @@ expr_code_doover: ** arguments past the first non-NULL argument. */ if( pDef->funcFlags & SQLITE_FUNC_COALESCE ){ - int endCoalesce = sqlite3VdbeMakeLabel(v); + int endCoalesce = sqlite3VdbeMakeLabel(pParse); assert( nFarg>=2 ); sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target); for(i=1; i<nFarg; i++){ @@ -99907,14 +100533,14 @@ expr_code_doover: if( op==TK_SELECT && (nCol = pExpr->x.pSelect->pEList->nExpr)!=1 ){ sqlite3SubselectError(pParse, nCol, 1); }else{ - return sqlite3CodeSubselect(pParse, pExpr, 0, 0); + return sqlite3CodeSubselect(pParse, pExpr); } break; } case TK_SELECT_COLUMN: { int n; if( pExpr->pLeft->iTable==0 ){ - pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft, 0, 0); + pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft); } assert( pExpr->iTable==0 || pExpr->pLeft->op==TK_SELECT ); if( pExpr->iTable @@ -99926,8 +100552,8 @@ expr_code_doover: return pExpr->pLeft->iTable + pExpr->iColumn; } case TK_IN: { - int destIfFalse = sqlite3VdbeMakeLabel(v); - int destIfNull = sqlite3VdbeMakeLabel(v); + int destIfFalse = sqlite3VdbeMakeLabel(pParse); + int destIfNull = sqlite3VdbeMakeLabel(pParse); sqlite3VdbeAddOp2(v, OP_Null, 0, target); sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull); sqlite3VdbeAddOp2(v, OP_Integer, 1, target); @@ -100067,9 +100693,9 @@ expr_code_doover: pEList = pExpr->x.pList; aListelem = pEList->a; nExpr = pEList->nExpr; - endLabel = sqlite3VdbeMakeLabel(v); + endLabel = sqlite3VdbeMakeLabel(pParse); if( (pX = pExpr->pLeft)!=0 ){ - tempX = *pX; + exprNodeCopy(&tempX, pX); testcase( pX->op==TK_COLUMN ); exprToRegister(&tempX, exprCodeVector(pParse, &tempX, ®Free1)); testcase( regFree1==0 ); @@ -100090,7 +100716,7 @@ expr_code_doover: }else{ pTest = aListelem[i].pExpr; } - nextCase = sqlite3VdbeMakeLabel(v); + nextCase = sqlite3VdbeMakeLabel(pParse); testcase( pTest->op==TK_COLUMN ); sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL); testcase( aListelem[i+1].pExpr->op==TK_COLUMN ); @@ -100390,13 +101016,12 @@ static void exprCodeBetween( Expr exprX; /* The x subexpression */ int regFree1 = 0; /* Temporary use register */ - memset(&compLeft, 0, sizeof(Expr)); memset(&compRight, 0, sizeof(Expr)); memset(&exprAnd, 0, sizeof(Expr)); assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); - exprX = *pExpr->pLeft; + exprNodeCopy(&exprX, pExpr->pLeft); exprAnd.op = TK_AND; exprAnd.pLeft = &compLeft; exprAnd.pRight = &compRight; @@ -100459,7 +101084,7 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int op = pExpr->op; switch( op ){ case TK_AND: { - int d2 = sqlite3VdbeMakeLabel(v); + int d2 = sqlite3VdbeMakeLabel(pParse); testcase( jumpIfNull==0 ); sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL); sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); @@ -100545,7 +101170,7 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int } #ifndef SQLITE_OMIT_SUBQUERY case TK_IN: { - int destIfFalse = sqlite3VdbeMakeLabel(v); + int destIfFalse = sqlite3VdbeMakeLabel(pParse); int destIfNull = jumpIfNull ? dest : destIfFalse; sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull); sqlite3VdbeGoto(v, dest); @@ -100632,7 +101257,7 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int break; } case TK_OR: { - int d2 = sqlite3VdbeMakeLabel(v); + int d2 = sqlite3VdbeMakeLabel(pParse); testcase( jumpIfNull==0 ); sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL); sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); @@ -100716,7 +101341,7 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int if( jumpIfNull ){ sqlite3ExprCodeIN(pParse, pExpr, dest, dest); }else{ - int destIfNull = sqlite3VdbeMakeLabel(v); + int destIfNull = sqlite3VdbeMakeLabel(pParse); sqlite3ExprCodeIN(pParse, pExpr, dest, destIfNull); sqlite3VdbeResolveLabel(v, destIfNull); } @@ -100837,7 +101462,7 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTa } return 2; } - if( pA->op!=pB->op ){ + if( pA->op!=pB->op || pA->op==TK_RAISE ){ if( pA->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA->pLeft,pB,iTab)<2 ){ return 1; } @@ -100863,21 +101488,25 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTa if( sqlite3WindowCompare(pParse,pA->y.pWin,pB->y.pWin)!=0 ) return 2; } #endif + }else if( pA->op==TK_NULL ){ + return 0; }else if( pA->op==TK_COLLATE ){ if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2; - }else if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){ + }else if( ALWAYS(pB->u.zToken!=0) && strcmp(pA->u.zToken,pB->u.zToken)!=0 ){ return 2; } } if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2; - if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){ + if( (combinedFlags & EP_TokenOnly)==0 ){ if( combinedFlags & EP_xIsSelect ) return 2; if( (combinedFlags & EP_FixedCol)==0 && sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2; if( sqlite3ExprCompare(pParse, pA->pRight, pB->pRight, iTab) ) return 2; if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2; - assert( (combinedFlags & EP_Reduced)==0 ); - if( pA->op!=TK_STRING && pA->op!=TK_TRUEFALSE ){ + if( pA->op!=TK_STRING + && pA->op!=TK_TRUEFALSE + && (combinedFlags & EP_Reduced)==0 + ){ if( pA->iColumn!=pB->iColumn ) return 2; if( pA->iTable!=pB->iTable && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2; @@ -100986,6 +101615,7 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ case TK_ISNOT: case TK_NOT: case TK_ISNULL: + case TK_NOTNULL: case TK_IS: case TK_OR: case TK_CASE: @@ -100994,6 +101624,7 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ testcase( pExpr->op==TK_ISNOT ); testcase( pExpr->op==TK_NOT ); testcase( pExpr->op==TK_ISNULL ); + testcase( pExpr->op==TK_NOTNULL ); testcase( pExpr->op==TK_IS ); testcase( pExpr->op==TK_OR ); testcase( pExpr->op==TK_CASE ); @@ -101367,6 +101998,7 @@ SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){ w.xSelectCallback2 = analyzeAggregatesInSelectEnd; w.walkerDepth = 0; w.u.pNC = pNC; + w.pParse = 0; assert( pNC->pSrcList!=0 ); sqlite3WalkExpr(&w, pExpr); } @@ -101498,9 +102130,16 @@ SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse *pParse, int iFirst, int iLast){ ** ** Or, if zName is not a system table, zero is returned. */ -static int isSystemTable(Parse *pParse, const char *zName){ - if( 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){ - sqlite3ErrorMsg(pParse, "table %s may not be altered", zName); +static int isAlterableTable(Parse *pParse, Table *pTab){ + if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) +#ifndef SQLITE_OMIT_VIRTUALTABLE + || ( (pTab->tabFlags & TF_Shadow) + && (pParse->db->flags & SQLITE_Defensive) + && pParse->db->nVdbeExec==0 + ) +#endif + ){ + sqlite3ErrorMsg(pParse, "table %s may not be altered", pTab->zName); return 1; } return 0; @@ -101596,7 +102235,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( /* Make sure it is not a system table being altered, or a reserved name ** that the table is being renamed to. */ - if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ){ + if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){ goto exit_rename_table; } if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto @@ -101894,7 +102533,7 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ sqlite3ErrorMsg(pParse, "Cannot add a column to a view"); goto exit_begin_add_column; } - if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ){ + if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){ goto exit_begin_add_column; } @@ -101996,7 +102635,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameColumn( if( !pTab ) goto exit_rename_column; /* Cannot alter a system table */ - if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ) goto exit_rename_column; + if( SQLITE_OK!=isAlterableTable(pParse, pTab) ) goto exit_rename_column; if( SQLITE_OK!=isRealTable(pParse, pTab) ) goto exit_rename_column; /* Which schema holds the table to be altered */ @@ -102250,14 +102889,31 @@ static void renameTokenFind(Parse *pParse, struct RenameCtx *pCtx, void *pPtr){ } } +/* +** Iterate through the Select objects that are part of WITH clauses attached +** to select statement pSelect. +*/ +static void renameWalkWith(Walker *pWalker, Select *pSelect){ + if( pSelect->pWith ){ + int i; + for(i=0; i<pSelect->pWith->nCte; i++){ + Select *p = pSelect->pWith->a[i].pSelect; + NameContext sNC; + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pWalker->pParse; + sqlite3SelectPrep(sNC.pParse, p, &sNC); + sqlite3WalkSelect(pWalker, p); + } + } +} + /* ** This is a Walker select callback. It does nothing. It is only required ** because without a dummy callback, sqlite3WalkExpr() and similar do not ** descend into sub-select statements. */ static int renameColumnSelectCb(Walker *pWalker, Select *p){ - UNUSED_PARAMETER(pWalker); - UNUSED_PARAMETER(p); + renameWalkWith(pWalker, p); return WRC_Continue; } @@ -102407,7 +103063,6 @@ static int renameParseSql( rc = sqlite3RunParser(p, zSql, &zErr); assert( p->zErrMsg==0 ); assert( rc!=SQLITE_OK || zErr==0 ); - assert( (0!=p->pNewTable) + (0!=p->pNewIndex) + (0!=p->pNewTrigger)<2 ); p->zErrMsg = zErr; if( db->mallocFailed ) rc = SQLITE_NOMEM; if( rc==SQLITE_OK @@ -102590,6 +103245,7 @@ static int renameResolveTrigger(Parse *pParse, const char *zDb){ } sNC.ncFlags = 0; } + sNC.pSrcList = 0; } } } @@ -102627,11 +103283,15 @@ static void renameWalkTrigger(Walker *pWalker, Trigger *pTrigger){ */ static void renameParseCleanup(Parse *pParse){ sqlite3 *db = pParse->db; + Index *pIdx; if( pParse->pVdbe ){ sqlite3VdbeFinalize(pParse->pVdbe); } sqlite3DeleteTable(db, pParse->pNewTable); - if( pParse->pNewIndex ) sqlite3FreeIndex(db, pParse->pNewIndex); + while( (pIdx = pParse->pNewIndex)!=0 ){ + pParse->pNewIndex = pIdx->pNext; + sqlite3FreeIndex(db, pIdx); + } sqlite3DeleteTrigger(db, pParse->pNewTrigger); sqlite3DbFree(db, pParse->zErrMsg); renameTokenFree(db, pParse->pRename); @@ -102742,6 +103402,9 @@ static void renameColumnFunc( for(pIdx=sParse.pNewTable->pIndex; pIdx; pIdx=pIdx->pNext){ sqlite3WalkExprList(&sWalker, pIdx->aColExpr); } + for(pIdx=sParse.pNewIndex; pIdx; pIdx=pIdx->pNext){ + sqlite3WalkExprList(&sWalker, pIdx->aColExpr); + } } for(pFKey=sParse.pNewTable->pFKey; pFKey; pFKey=pFKey->pNextFrom){ @@ -102828,12 +103491,17 @@ static int renameTableSelectCb(Walker *pWalker, Select *pSelect){ int i; RenameCtx *p = pWalker->u.pRename; SrcList *pSrc = pSelect->pSrc; + if( pSrc==0 ){ + assert( pWalker->pParse->db->mallocFailed ); + return WRC_Abort; + } for(i=0; i<pSrc->nSrc; i++){ struct SrcList_item *pItem = &pSrc->a[i]; if( pItem->pTab==p->pTab ){ renameTokenFind(pWalker->pParse, p, pItem->zName); } } + renameWalkWith(pWalker, pSelect); return WRC_Continue; } @@ -104235,7 +104903,7 @@ static void analyzeOneTable( addrNextRow = sqlite3VdbeCurrentAddr(v); if( nColTest>0 ){ - int endDistinctTest = sqlite3VdbeMakeLabel(v); + int endDistinctTest = sqlite3VdbeMakeLabel(pParse); int *aGotoChng; /* Array of jump instruction addresses */ aGotoChng = sqlite3DbMallocRawNN(db, sizeof(int)*nColTest); if( aGotoChng==0 ) continue; @@ -105173,8 +105841,8 @@ static void attachFunc( assert( pVfs ); flags |= SQLITE_OPEN_MAIN_DB; rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags); - sqlite3_free( zPath ); db->nDb++; + pNew->zDbSName = sqlite3DbStrDup(db, zName); } db->noSharedCache = 0; if( rc==SQLITE_CONSTRAINT ){ @@ -105202,7 +105870,6 @@ static void attachFunc( sqlite3BtreeLeave(pNew->pBt); } pNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1; - if( !REOPEN_AS_MEMDB(db) ) pNew->zDbSName = sqlite3DbStrDup(db, zName); if( rc==SQLITE_OK && pNew->zDbSName==0 ){ rc = SQLITE_NOMEM_BKPT; } @@ -105230,15 +105897,19 @@ static void attachFunc( break; case SQLITE_NULL: - /* No key specified. Use the key from the main database */ - sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey); - if( nKey || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){ - rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); + /* No key specified. Use the key from URI filename, or if none, + ** use the key from the main database. */ + if( sqlite3CodecQueryParameters(db, zName, zPath)==0 ){ + sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey); + if( nKey || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){ + rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); + } } break; } } #endif + sqlite3_free( zPath ); /* If the file was opened successfully, read the schema for the new database. ** If this fails, or if opening the file failed, then close the file and @@ -106150,7 +106821,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ if( v && pParse->nErr==0 && !db->mallocFailed ){ /* A minimum of one cursor is required if autoincrement is used * See ticket [a696379c1f08866] */ - if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1; + assert( pParse->pAinc==0 || pParse->nTab>0 ); sqlite3VdbeMakeReady(v, pParse); pParse->rc = SQLITE_DONE; }else{ @@ -106277,26 +106948,32 @@ SQLITE_PRIVATE Table *sqlite3LocateTable( p = sqlite3FindTable(db, zName, zDbase); if( p==0 ){ - const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table"; #ifndef SQLITE_OMIT_VIRTUALTABLE /* If zName is the not the name of a table in the schema created using ** CREATE, then check to see if it is the name of an virtual table that ** can be an eponymous virtual table. */ - Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName); - if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){ - pMod = sqlite3PragmaVtabRegister(db, zName); - } - if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){ - return pMod->pEpoTab; + if( pParse->disableVtab==0 ){ + Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName); + if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){ + pMod = sqlite3PragmaVtabRegister(db, zName); + } + if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){ + return pMod->pEpoTab; + } } #endif - if( (flags & LOCATE_NOERR)==0 ){ - if( zDbase ){ - sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName); - }else{ - sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName); - } - pParse->checkSchema = 1; + if( flags & LOCATE_NOERR ) return 0; + pParse->checkSchema = 1; + }else if( IsVirtual(p) && pParse->disableVtab ){ + p = 0; + } + + if( p==0 ){ + const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table"; + if( zDbase ){ + sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName); + }else{ + sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName); } } @@ -106559,12 +107236,6 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){ /* Delete the Table structure itself. */ -#ifdef SQLITE_ENABLE_NORMALIZE - if( pTable->pColHash ){ - sqlite3HashClear(pTable->pColHash); - sqlite3_free(pTable->pColHash); - } -#endif sqlite3DeleteColumnNames(db, pTable); sqlite3DbFree(db, pTable->zName); sqlite3DbFree(db, pTable->zColAff); @@ -108561,6 +109232,7 @@ SQLITE_PRIVATE void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, in */ if( IsVirtual(pTab) ){ sqlite3VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0); + sqlite3MayAbort(pParse); } sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0); sqlite3ChangeCookie(pParse, iDb); @@ -109389,6 +110061,11 @@ SQLITE_PRIVATE void sqlite3CreateIndex( } } if( idxType==SQLITE_IDXTYPE_PRIMARYKEY ) pIdx->idxType = idxType; + if( IN_RENAME_OBJECT ){ + pIndex->pNext = pParse->pNewIndex; + pParse->pNewIndex = pIndex; + pIndex = 0; + } goto exit_create_index; } } @@ -109404,6 +110081,14 @@ SQLITE_PRIVATE void sqlite3CreateIndex( Index *p; assert( !IN_SPECIAL_PARSE ); assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); + if( pTblName!=0 ){ + pIndex->tnum = db->init.newTnum; + if( sqlite3IndexHasDuplicateRootPage(pIndex) ){ + sqlite3ErrorMsg(pParse, "invalid rootpage"); + pParse->rc = SQLITE_CORRUPT_BKPT; + goto exit_create_index; + } + } p = sqlite3HashInsert(&pIndex->pSchema->idxHash, pIndex->zName, pIndex); if( p ){ @@ -109412,9 +110097,6 @@ SQLITE_PRIVATE void sqlite3CreateIndex( goto exit_create_index; } db->mDbFlags |= DBFLAG_SchemaChange; - if( pTblName!=0 ){ - pIndex->tnum = db->init.newTnum; - } } /* If this is the initial CREATE INDEX statement (or CREATE TABLE if the @@ -109740,6 +110422,18 @@ SQLITE_PRIVATE int sqlite3IdListIndex(IdList *pList, const char *zName){ return -1; } +/* +** Maximum size of a SrcList object. +** The SrcList object is used to represent the FROM clause of a +** SELECT statement, and the query planner cannot deal with more +** than 64 tables in a join. So any value larger than 64 here +** is sufficient for most uses. Smaller values, like say 10, are +** appropriate for small and memory-limited applications. +*/ +#ifndef SQLITE_MAX_SRCLIST +# define SQLITE_MAX_SRCLIST 200 +#endif + /* ** Expand the space allocated for the given SrcList object by ** creating nExtra new slots beginning at iStart. iStart is zero based. @@ -109756,11 +110450,12 @@ SQLITE_PRIVATE int sqlite3IdListIndex(IdList *pList, const char *zName){ ** the iStart value would be 0. The result then would ** be: nil, nil, nil, A, B. ** -** If a memory allocation fails the SrcList is unchanged. The -** db->mallocFailed flag will be set to true. +** If a memory allocation fails or the SrcList becomes too large, leave +** the original SrcList unchanged, return NULL, and leave an error message +** in pParse. */ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge( - sqlite3 *db, /* Database connection to notify of OOM errors */ + Parse *pParse, /* Parsing context into which errors are reported */ SrcList *pSrc, /* The SrcList to be enlarged */ int nExtra, /* Number of new slots to add to pSrc->a[] */ int iStart /* Index in pSrc->a[] of first new slot */ @@ -109777,16 +110472,22 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge( if( (u32)pSrc->nSrc+nExtra>pSrc->nAlloc ){ SrcList *pNew; int nAlloc = pSrc->nSrc*2+nExtra; - int nGot; + sqlite3 *db = pParse->db; + + if( pSrc->nSrc+nExtra>=SQLITE_MAX_SRCLIST ){ + sqlite3ErrorMsg(pParse, "too many FROM clause terms, max: %d", + SQLITE_MAX_SRCLIST); + return 0; + } + if( nAlloc>SQLITE_MAX_SRCLIST ) nAlloc = SQLITE_MAX_SRCLIST; pNew = sqlite3DbRealloc(db, pSrc, sizeof(*pSrc) + (nAlloc-1)*sizeof(pSrc->a[0]) ); if( pNew==0 ){ assert( db->mallocFailed ); - return pSrc; + return 0; } pSrc = pNew; - nGot = (sqlite3DbMallocSize(db, pNew) - sizeof(*pSrc))/sizeof(pSrc->a[0])+1; - pSrc->nAlloc = nGot; + pSrc->nAlloc = nAlloc; } /* Move existing slots that come after the newly inserted slots @@ -109811,7 +110512,8 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge( ** Append a new table name to the given SrcList. Create a new SrcList if ** need be. A new entry is created in the SrcList even if pTable is NULL. ** -** A SrcList is returned, or NULL if there is an OOM error. The returned +** A SrcList is returned, or NULL if there is an OOM error or if the +** SrcList grows to large. The returned ** SrcList might be the same as the SrcList that was input or it might be ** a new one. If an OOM error does occurs, then the prior value of pList ** that is input to this routine is automatically freed. @@ -109842,27 +110544,32 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge( ** before being added to the SrcList. */ SQLITE_PRIVATE SrcList *sqlite3SrcListAppend( - sqlite3 *db, /* Connection to notify of malloc failures */ + Parse *pParse, /* Parsing context, in which errors are reported */ SrcList *pList, /* Append to this SrcList. NULL creates a new SrcList */ Token *pTable, /* Table to append */ Token *pDatabase /* Database of the table */ ){ struct SrcList_item *pItem; + sqlite3 *db; assert( pDatabase==0 || pTable!=0 ); /* Cannot have C without B */ - assert( db!=0 ); + assert( pParse!=0 ); + assert( pParse->db!=0 ); + db = pParse->db; if( pList==0 ){ - pList = sqlite3DbMallocRawNN(db, sizeof(SrcList) ); + pList = sqlite3DbMallocRawNN(pParse->db, sizeof(SrcList) ); if( pList==0 ) return 0; pList->nAlloc = 1; pList->nSrc = 1; memset(&pList->a[0], 0, sizeof(pList->a[0])); pList->a[0].iCursor = -1; }else{ - pList = sqlite3SrcListEnlarge(db, pList, 1, pList->nSrc); - } - if( db->mallocFailed ){ - sqlite3SrcListDelete(db, pList); - return 0; + SrcList *pNew = sqlite3SrcListEnlarge(pParse, pList, 1, pList->nSrc); + if( pNew==0 ){ + sqlite3SrcListDelete(db, pList); + return 0; + }else{ + pList = pNew; + } } pItem = &pList->a[pList->nSrc-1]; if( pDatabase && pDatabase->z==0 ){ @@ -109951,7 +110658,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm( ); goto append_from_error; } - p = sqlite3SrcListAppend(db, p, pTable, pDatabase); + p = sqlite3SrcListAppend(pParse, p, pTable, pDatabase); if( p==0 ){ goto append_from_error; } @@ -110340,13 +111047,15 @@ static int collationMatch(const char *zColl, Index *pIndex){ */ #ifndef SQLITE_OMIT_REINDEX static void reindexTable(Parse *pParse, Table *pTab, char const *zColl){ - Index *pIndex; /* An index associated with pTab */ + if( !IsVirtual(pTab) ){ + Index *pIndex; /* An index associated with pTab */ - for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){ - if( zColl==0 || collationMatch(zColl, pIndex) ){ - int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); - sqlite3BeginWriteOperation(pParse, 0, iDb); - sqlite3RefillIndex(pParse, pIndex, -1); + for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){ + if( zColl==0 || collationMatch(zColl, pIndex) ){ + int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + sqlite3BeginWriteOperation(pParse, 0, iDb); + sqlite3RefillIndex(pParse, pIndex, -1); + } } } } @@ -110845,7 +111554,7 @@ static int matchQuality( ** Search a FuncDefHash for a function with the given name. Return ** a pointer to the matching FuncDef if found, or 0 if there is no match. */ -static FuncDef *functionSearch( +SQLITE_PRIVATE FuncDef *sqlite3FunctionSearch( int h, /* Hash of the name */ const char *zFunc /* Name of function */ ){ @@ -110857,21 +111566,6 @@ static FuncDef *functionSearch( } return 0; } -#ifdef SQLITE_ENABLE_NORMALIZE -SQLITE_PRIVATE FuncDef *sqlite3FunctionSearchN( - int h, /* Hash of the name */ - const char *zFunc, /* Name of function */ - int nFunc /* Length of the name */ -){ - FuncDef *p; - for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){ - if( sqlite3StrNICmp(p->zName, zFunc, nFunc)==0 ){ - return p; - } - } - return 0; -} -#endif /* SQLITE_ENABLE_NORMALIZE */ /* ** Insert a new FuncDef into a FuncDefHash hash table. @@ -110887,7 +111581,7 @@ SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs( int nName = sqlite3Strlen30(zName); int h = SQLITE_FUNC_HASH(zName[0], nName); assert( zName[0]>='a' && zName[0]<='z' ); - pOther = functionSearch(h, zName); + pOther = sqlite3FunctionSearch(h, zName); if( pOther ){ assert( pOther!=&aDef[i] && pOther->pNext!=&aDef[i] ); aDef[i].pNext = pOther->pNext; @@ -110965,7 +111659,7 @@ SQLITE_PRIVATE FuncDef *sqlite3FindFunction( if( !createFlag && (pBest==0 || (db->mDbFlags & DBFLAG_PreferBuiltin)!=0) ){ bestScore = 0; h = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zName[0]], nName); - p = functionSearch(h, zName); + p = sqlite3FunctionSearch(h, zName); while( p ){ int score = matchQuality(p, nArg, enc); if( score>bestScore ){ @@ -111185,7 +111879,7 @@ SQLITE_PRIVATE void sqlite3MaterializeView( sqlite3 *db = pParse->db; int iDb = sqlite3SchemaToIndex(db, pView->pSchema); pWhere = sqlite3ExprDup(db, pWhere, 0); - pFrom = sqlite3SrcListAppend(db, 0, 0, 0); + pFrom = sqlite3SrcListAppend(pParse, 0, 0, 0); if( pFrom ){ assert( pFrom->nSrc==1 ); pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName); @@ -111585,7 +112279,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( /* If this DELETE cannot use the ONEPASS strategy, this is the ** end of the WHERE loop */ if( eOnePass!=ONEPASS_OFF ){ - addrBypass = sqlite3VdbeMakeLabel(v); + addrBypass = sqlite3VdbeMakeLabel(pParse); }else{ sqlite3WhereEnd(pWInfo); } @@ -111774,7 +112468,7 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete( /* Seek cursor iCur to the row to delete. If this row no longer exists ** (this can happen if a trigger program has already deleted it), do ** not attempt to delete it or fire any DELETE triggers. */ - iLabel = sqlite3VdbeMakeLabel(v); + iLabel = sqlite3VdbeMakeLabel(pParse); opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound; if( eMode==ONEPASS_OFF ){ sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk); @@ -111980,7 +112674,7 @@ SQLITE_PRIVATE int sqlite3GenerateIndexKey( if( piPartIdxLabel ){ if( pIdx->pPartIdxWhere ){ - *piPartIdxLabel = sqlite3VdbeMakeLabel(v); + *piPartIdxLabel = sqlite3VdbeMakeLabel(pParse); pParse->iSelfTab = iDataCur + 1; sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, SQLITE_JUMPIFNULL); @@ -112236,6 +112930,7 @@ static void instrFunc( int typeHaystack, typeNeedle; int N = 1; int isText; + unsigned char firstChar; UNUSED_PARAMETER(argc); typeHaystack = sqlite3_value_type(argv[0]); @@ -112254,7 +112949,10 @@ static void instrFunc( isText = 1; } if( zNeedle==0 || (nHaystack && zHaystack==0) ) return; - while( nNeedle<=nHaystack && memcmp(zHaystack, zNeedle, nNeedle)!=0 ){ + firstChar = zNeedle[0]; + while( nNeedle<=nHaystack + && (zHaystack[0]!=firstChar || memcmp(zHaystack, zNeedle, nNeedle)!=0) + ){ N++; do{ nHaystack--; @@ -112545,11 +113243,11 @@ static void randomBlob( int argc, sqlite3_value **argv ){ - int n; + sqlite3_int64 n; unsigned char *p; assert( argc==1 ); UNUSED_PARAMETER(argc); - n = sqlite3_value_int(argv[0]); + n = sqlite3_value_int64(argv[0]); if( n<1 ){ n = 1; } @@ -114385,7 +115083,7 @@ static void fkLookupParent( int i; /* Iterator variable */ Vdbe *v = sqlite3GetVdbe(pParse); /* Vdbe to add code to */ int iCur = pParse->nTab - 1; /* Cursor number to use */ - int iOk = sqlite3VdbeMakeLabel(v); /* jump here if parent key found */ + int iOk = sqlite3VdbeMakeLabel(pParse); /* jump here if parent key found */ sqlite3VdbeVerifyAbortable(v, (!pFKey->isDeferred @@ -114658,8 +115356,11 @@ static void fkScanChildren( ** NOT( $current_a==a AND $current_b==b AND ... ) ** ** The first form is used for rowid tables. The second form is used - ** for WITHOUT ROWID tables. In the second form, the primary key is - ** (a,b,...) + ** for WITHOUT ROWID tables. In the second form, the *parent* key is + ** (a,b,...). Either the parent or primary key could be used to + ** uniquely identify the current row, but the parent key is more convenient + ** as the required values have already been loaded into registers + ** by the caller. */ if( pTab==pFKey->pFrom && nIncr>0 ){ Expr *pNe; /* Expression (pLeft != pRight) */ @@ -114671,14 +115372,13 @@ static void fkScanChildren( pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight); }else{ Expr *pEq, *pAll = 0; - Index *pPk = sqlite3PrimaryKeyIndex(pTab); assert( pIdx!=0 ); - for(i=0; i<pPk->nKeyCol; i++){ + for(i=0; i<pIdx->nKeyCol; i++){ i16 iCol = pIdx->aiColumn[i]; assert( iCol>=0 ); pLeft = exprTableRegister(pParse, pTab, regData, iCol); - pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, iCol); - pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight); + pRight = sqlite3Expr(db, TK_ID, pTab->aCol[iCol].zName); + pEq = sqlite3PExpr(pParse, TK_IS, pLeft, pRight); pAll = sqlite3ExprAnd(db, pAll, pEq); } pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0); @@ -114783,7 +115483,7 @@ SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTa if( p->isDeferred || (db->flags & SQLITE_DeferFKs) ) break; } if( !p ) return; - iSkip = sqlite3VdbeMakeLabel(v); + iSkip = sqlite3VdbeMakeLabel(pParse); sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip); VdbeCoverage(v); } @@ -115068,7 +115768,7 @@ SQLITE_PRIVATE void sqlite3FkCheck( /* Create a SrcList structure containing the child table. We need the ** child table as a SrcList for sqlite3WhereBegin() */ - pSrc = sqlite3SrcListAppend(db, 0, 0, 0); + pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); if( pSrc ){ struct SrcList_item *pItem = pSrc->a; pItem->pTab = pFKey->pFrom; @@ -115345,7 +116045,7 @@ static Trigger *fkActionTrigger( } pSelect = sqlite3SelectNew(pParse, sqlite3ExprListAppend(pParse, 0, pRaise), - sqlite3SrcListAppend(db, 0, &tFrom, 0), + sqlite3SrcListAppend(pParse, 0, &tFrom, 0), pWhere, 0, 0, 0, 0, 0 ); @@ -115807,6 +116507,7 @@ SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse){ aOp[7].p2 = memId+2; aOp[7].p1 = memId; aOp[10].p2 = memId; + if( pParse->nTab==0 ) pParse->nTab = 1; } } @@ -116313,6 +117014,11 @@ SQLITE_PRIVATE void sqlite3Insert( } #ifndef SQLITE_OMIT_UPSERT if( pUpsert ){ + if( IsVirtual(pTab) ){ + sqlite3ErrorMsg(pParse, "UPSERT not implemented for virtual table \"%s\"", + pTab->zName); + goto insert_cleanup; + } pTabList->a[0].iCursor = iDataCur; pUpsert->pUpsertSrc = pTabList; pUpsert->regData = regData; @@ -116353,7 +117059,7 @@ SQLITE_PRIVATE void sqlite3Insert( /* Run the BEFORE and INSTEAD OF triggers, if there are any */ - endOfLoop = sqlite3VdbeMakeLabel(v); + endOfLoop = sqlite3VdbeMakeLabel(pParse); if( tmask & TRIGGER_BEFORE ){ int regCols = sqlite3GetTempRange(pParse, pTab->nCol+1); @@ -116435,16 +117141,12 @@ SQLITE_PRIVATE void sqlite3Insert( }else if( pSelect ){ sqlite3VdbeAddOp2(v, OP_Copy, regFromSelect+ipkColumn, regRowid); }else{ - VdbeOp *pOp; - sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid); - pOp = sqlite3VdbeGetOp(v, -1); - assert( pOp!=0 ); - if( pOp->opcode==OP_Null && !IsVirtual(pTab) ){ + Expr *pIpk = pList->a[ipkColumn].pExpr; + if( pIpk->op==TK_NULL && !IsVirtual(pTab) ){ + sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc); appendFlag = 1; - pOp->opcode = OP_NewRowid; - pOp->p1 = iDataCur; - pOp->p2 = regRowid; - pOp->p3 = regAutoinc; + }else{ + sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid); } } /* If the PRIMARY KEY expression is NULL, then use OP_NewRowid @@ -116839,7 +117541,20 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( } assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail || onError==OE_Ignore || onError==OE_Replace ); + addr1 = 0; switch( onError ){ + case OE_Replace: { + assert( onError==OE_Replace ); + addr1 = sqlite3VdbeMakeLabel(pParse); + sqlite3VdbeAddOp2(v, OP_NotNull, regNewData+1+i, addr1); + VdbeCoverage(v); + sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i); + sqlite3VdbeAddOp2(v, OP_NotNull, regNewData+1+i, addr1); + VdbeCoverage(v); + onError = OE_Abort; + /* Fall through into the OE_Abort case to generate code that runs + ** if both the input and the default value are NULL */ + } case OE_Abort: sqlite3MayAbort(pParse); /* Fall through */ @@ -116852,19 +117567,13 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC); sqlite3VdbeChangeP5(v, P5_ConstraintNotNull); VdbeCoverage(v); - break; - } - case OE_Ignore: { - sqlite3VdbeAddOp2(v, OP_IsNull, regNewData+1+i, ignoreDest); - VdbeCoverage(v); + if( addr1 ) sqlite3VdbeResolveLabel(v, addr1); break; } default: { - assert( onError==OE_Replace ); - addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regNewData+1+i); - VdbeCoverage(v); - sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i); - sqlite3VdbeJumpHere(v, addr1); + assert( onError==OE_Ignore ); + sqlite3VdbeAddOp2(v, OP_IsNull, regNewData+1+i, ignoreDest); + VdbeCoverage(v); break; } } @@ -116887,7 +117596,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( ** updated so there is no point it verifying the check constraint */ continue; } - allOk = sqlite3VdbeMakeLabel(v); + allOk = sqlite3VdbeMakeLabel(pParse); sqlite3VdbeVerifyAbortable(v, onError); sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL); if( onError==OE_Ignore ){ @@ -116954,7 +117663,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( ** exist in the table. */ if( pkChng && pPk==0 ){ - int addrRowidOk = sqlite3VdbeMakeLabel(v); + int addrRowidOk = sqlite3VdbeMakeLabel(pParse); /* Figure out what action to take in case of a rowid collision */ onError = pTab->keyConf; @@ -117104,7 +117813,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( VdbeComment((v, "Skip upsert subroutine")); sqlite3VdbeJumpHere(v, upsertJump); }else{ - addrUniqueOk = sqlite3VdbeMakeLabel(v); + addrUniqueOk = sqlite3VdbeMakeLabel(pParse); } if( bAffinityDone==0 && (pUpIdx==0 || pUpIdx==pIdx) ){ sqlite3TableAffinity(v, pTab, regNewData+1); @@ -117187,7 +117896,11 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( ** (3) There are no secondary indexes on the table ** (4) No delete triggers need to be fired if there is a conflict ** (5) No FK constraint counters need to be updated if a conflict occurs. - */ + ** + ** This is not possible for ENABLE_PREUPDATE_HOOK builds, as the row + ** must be explicitly deleted in order to ensure any pre-update hook + ** is invoked. */ +#ifndef SQLITE_ENABLE_PREUPDATE_HOOK if( (ix==0 && pIdx->pNext==0) /* Condition 3 */ && pPk==pIdx /* Condition 2 */ && onError==OE_Replace /* Condition 1 */ @@ -117199,6 +117912,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( sqlite3VdbeResolveLabel(v, addrUniqueOk); continue; } +#endif /* ifndef SQLITE_ENABLE_PREUPDATE_HOOK */ /* Check to see if the new index entry will be unique */ sqlite3VdbeVerifyAbortable(v, onError); @@ -117312,7 +118026,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( /* If the IPK constraint is a REPLACE, run it last */ if( ipkTop ){ - sqlite3VdbeGoto(v, ipkTop+1); + sqlite3VdbeGoto(v, ipkTop); VdbeComment((v, "Do IPK REPLACE")); sqlite3VdbeJumpHere(v, ipkBottom); } @@ -117682,7 +118396,8 @@ static int xferOptimization( if( pSrc==0 ){ return 0; /* FROM clause does not contain a real table */ } - if( pSrc==pDest ){ + if( pSrc->tnum==pDest->tnum && pSrc->pSchema==pDest->pSchema ){ + testcase( pSrc!=pDest ); /* Possible due to bad sqlite_master.rootpage */ return 0; /* tab1 and tab2 may not be the same table */ } if( HasRowid(pDest)!=HasRowid(pSrc) ){ @@ -117958,7 +118673,7 @@ SQLITE_API int sqlite3_exec( sqlite3_mutex_enter(db->mutex); sqlite3Error(db, SQLITE_OK); while( rc==SQLITE_OK && zSql[0] ){ - int nCol; + int nCol = 0; char **azVals = 0; pStmt = 0; @@ -117972,9 +118687,7 @@ SQLITE_API int sqlite3_exec( zSql = zLeftover; continue; } - callbackIsInit = 0; - nCol = sqlite3_column_count(pStmt); while( 1 ){ int i; @@ -117985,6 +118698,7 @@ SQLITE_API int sqlite3_exec( (SQLITE_DONE==rc && !callbackIsInit && db->flags&SQLITE_NullCallback)) ){ if( !callbackIsInit ){ + nCol = sqlite3_column_count(pStmt); azCols = sqlite3DbMallocRaw(db, (2*nCol+1)*sizeof(const char*)); if( azCols==0 ){ goto exec_out; @@ -119339,7 +120053,7 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff){ if( onoff ){ db->flags |= SQLITE_LoadExtension|SQLITE_LoadExtFunc; }else{ - db->flags &= ~(SQLITE_LoadExtension|SQLITE_LoadExtFunc); + db->flags &= ~(u64)(SQLITE_LoadExtension|SQLITE_LoadExtFunc); } sqlite3_mutex_leave(db->mutex); return SQLITE_OK; @@ -119598,8 +120312,7 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){ #define PragTyp_HEXKEY 41 #define PragTyp_KEY 42 #define PragTyp_LOCK_STATUS 43 -#define PragTyp_PARSER_TRACE 44 -#define PragTyp_STATS 45 +#define PragTyp_STATS 44 /* Property flags associated with various pragma. */ #define PragFlg_NeedSchema 0x01 /* Force schema load before running */ @@ -120010,12 +120723,14 @@ static const PragmaName aPragmaName[] = { /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif -#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_PARSER_TRACE) +#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) +#if defined(SQLITE_DEBUG) {/* zName: */ "parser_trace", - /* ePragTyp: */ PragTyp_PARSER_TRACE, - /* ePragFlg: */ 0, + /* ePragTyp: */ PragTyp_FLAG, + /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, - /* iArg: */ 0 }, + /* iArg: */ SQLITE_ParserTrace }, +#endif #endif #if defined(SQLITE_INTROSPECTION_PRAGMAS) {/* zName: */ "pragma_list", @@ -121006,7 +121721,7 @@ SQLITE_PRIVATE void sqlite3Pragma( if( sqlite3GetBoolean(zRight, size!=0) ){ db->flags |= SQLITE_CacheSpill; }else{ - db->flags &= ~SQLITE_CacheSpill; + db->flags &= ~(u64)SQLITE_CacheSpill; } setAllPagerFlags(db); } @@ -121566,7 +122281,7 @@ SQLITE_PRIVATE void sqlite3Pragma( x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols); assert( x==0 ); } - addrOk = sqlite3VdbeMakeLabel(v); + addrOk = sqlite3VdbeMakeLabel(pParse); /* Generate code to read the child key values into registers ** regRow..regRow+n. If any of the child key values are NULL, this @@ -121611,19 +122326,6 @@ SQLITE_PRIVATE void sqlite3Pragma( #endif /* !defined(SQLITE_OMIT_TRIGGER) */ #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ -#ifndef NDEBUG - case PragTyp_PARSER_TRACE: { - if( zRight ){ - if( sqlite3GetBoolean(zRight, 0) ){ - sqlite3ParserTrace(stdout, "parser: "); - }else{ - sqlite3ParserTrace(0, 0); - } - } - } - break; -#endif - /* Reinstall the LIKE and GLOB functions. The variant of LIKE ** used will be case sensitive or not depending on the RHS. */ @@ -121786,8 +122488,8 @@ SQLITE_PRIVATE void sqlite3Pragma( if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){ ExprList *pCheck = sqlite3ExprListDup(db, pTab->pCheck, 0); if( db->mallocFailed==0 ){ - int addrCkFault = sqlite3VdbeMakeLabel(v); - int addrCkOk = sqlite3VdbeMakeLabel(v); + int addrCkFault = sqlite3VdbeMakeLabel(pParse); + int addrCkOk = sqlite3VdbeMakeLabel(pParse); char *zErr; int k; pParse->iSelfTab = iDataCur + 1; @@ -121810,7 +122512,7 @@ SQLITE_PRIVATE void sqlite3Pragma( /* Validate index entries for the current row */ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ int jmp2, jmp3, jmp4, jmp5; - int ckUniq = sqlite3VdbeMakeLabel(v); + int ckUniq = sqlite3VdbeMakeLabel(pParse); if( pPk==pIdx ) continue; r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3, pPrior, r1); @@ -121831,7 +122533,7 @@ SQLITE_PRIVATE void sqlite3Pragma( ** current key. The entry is unique if (1) any column is NULL ** or (2) the next entry has a different key */ if( IsUniqueIndex(pIdx) ){ - int uniqOk = sqlite3VdbeMakeLabel(v); + int uniqOk = sqlite3VdbeMakeLabel(pParse); int jmp6; int kk; for(kk=0; kk<pIdx->nKeyCol; kk++){ @@ -122745,6 +123447,19 @@ static void corruptSchema( } } +/* +** Check to see if any sibling index (another index on the same table) +** of pIndex has the same root page number, and if it does, return true. +** This would indicate a corrupt schema. +*/ +SQLITE_PRIVATE int sqlite3IndexHasDuplicateRootPage(Index *pIndex){ + Index *p; + for(p=pIndex->pTable->pIndex; p; p=p->pNext){ + if( p->tnum==pIndex->tnum && p!=pIndex ) return 1; + } + return 0; +} + /* ** This is the callback routine for the code that initializes the ** database. See sqlite3Init() below for additional information. @@ -122766,6 +123481,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char UNUSED_PARAMETER2(NotUsed, argc); assert( sqlite3_mutex_held(db->mutex) ); DbClearProperty(db, iDb, DB_Empty); + pData->nInitRow++; if( db->mallocFailed ){ corruptSchema(pData, argv[0], 0); return 1; @@ -122819,15 +123535,12 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char */ Index *pIndex; pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zDbSName); - if( pIndex==0 ){ - /* This can occur if there exists an index on a TEMP table which - ** has the same name as another index on a permanent index. Since - ** the permanent table is hidden by the TEMP table, we can also - ** safely ignore the index on the permanent table. - */ - /* Do Nothing */; - }else if( sqlite3GetInt32(argv[1], &pIndex->tnum)==0 ){ - corruptSchema(pData, argv[0], "invalid rootpage"); + if( pIndex==0 + || sqlite3GetInt32(argv[1],&pIndex->tnum)==0 + || pIndex->tnum<2 + || sqlite3IndexHasDuplicateRootPage(pIndex) + ){ + corruptSchema(pData, argv[0], pIndex?"invalid rootpage":"orphan index"); } } return 0; @@ -122877,6 +123590,7 @@ SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFl initData.rc = SQLITE_OK; initData.pzErrMsg = pzErrMsg; initData.mInitFlags = mFlags; + initData.nInitRow = 0; sqlite3InitCallback(&initData, 3, (char **)azArg, 0); if( initData.rc ){ rc = initData.rc; @@ -122994,7 +123708,7 @@ SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFl ** indices that the user might have created. */ if( iDb==0 && meta[BTREE_FILE_FORMAT-1]>=4 ){ - db->flags &= ~SQLITE_LegacyFileFmt; + db->flags &= ~(u64)SQLITE_LegacyFileFmt; } /* Read the schema information out of the schema tables @@ -123246,6 +123960,7 @@ static int sqlite3Prepare( sParse.disableLookaside++; db->lookaside.bDisable++; } + sParse.disableVtab = (prepFlags & SQLITE_PREPARE_NO_VTAB)!=0; /* Check to verify that it is possible to get a read lock on all ** database schemas. The inability to get a read lock indicates that @@ -123410,293 +124125,6 @@ static int sqlite3LockAndPrepare( return rc; } -#ifdef SQLITE_ENABLE_NORMALIZE -/* -** Checks if the specified token is a table, column, or function name, -** based on the databases associated with the statement being prepared. -** If the function fails, zero is returned and pRc is filled with the -** error code. -*/ -static int shouldTreatAsIdentifier( - sqlite3 *db, /* Database handle. */ - const char *zToken, /* Pointer to start of token to be checked */ - int nToken, /* Length of token to be checked */ - int *pRc /* Pointer to error code upon failure */ -){ - int bFound = 0; /* Non-zero if token is an identifier name. */ - int i, j; /* Database and column loop indexes. */ - Schema *pSchema; /* Schema for current database. */ - Hash *pHash; /* Hash table of tables for current database. */ - HashElem *e; /* Hash element for hash table iteration. */ - Table *pTab; /* Database table for columns being checked. */ - - if( sqlite3IsRowidN(zToken, nToken) ){ - return 1; - } - if( nToken>0 ){ - int hash = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zToken[0]], nToken); - if( sqlite3FunctionSearchN(hash, zToken, nToken) ) return 1; - } - assert( db!=0 ); - sqlite3_mutex_enter(db->mutex); - sqlite3BtreeEnterAll(db); - for(i=0; i<db->nDb; i++){ - pHash = &db->aFunc; - if( sqlite3HashFindN(pHash, zToken, nToken) ){ - bFound = 1; - break; - } - pSchema = db->aDb[i].pSchema; - if( pSchema==0 ) continue; - pHash = &pSchema->tblHash; - if( sqlite3HashFindN(pHash, zToken, nToken) ){ - bFound = 1; - break; - } - for(e=sqliteHashFirst(pHash); e; e=sqliteHashNext(e)){ - pTab = sqliteHashData(e); - if( pTab==0 ) continue; - pHash = pTab->pColHash; - if( pHash==0 ){ - pTab->pColHash = pHash = sqlite3_malloc(sizeof(Hash)); - if( pHash ){ - sqlite3HashInit(pHash); - for(j=0; j<pTab->nCol; j++){ - Column *pCol = &pTab->aCol[j]; - sqlite3HashInsert(pHash, pCol->zName, pCol); - } - }else{ - *pRc = SQLITE_NOMEM_BKPT; - bFound = 0; - goto done; - } - } - if( pHash && sqlite3HashFindN(pHash, zToken, nToken) ){ - bFound = 1; - goto done; - } - } - } -done: - sqlite3BtreeLeaveAll(db); - sqlite3_mutex_leave(db->mutex); - return bFound; -} - -/* -** Attempt to estimate the final output buffer size needed for the fully -** normalized version of the specified SQL string. This should take into -** account any potential expansion that could occur (e.g. via IN clauses -** being expanded, etc). This size returned is the total number of bytes -** including the NUL terminator. -*/ -static int estimateNormalizedSize( - const char *zSql, /* The original SQL string */ - int nSql, /* Length of original SQL string */ - u8 prepFlags /* The flags passed to sqlite3_prepare_v3() */ -){ - int nOut = nSql + 4; - const char *z = zSql; - while( nOut<nSql*5 ){ - while( z[0]!=0 && z[0]!='I' && z[0]!='i' ){ z++; } - if( z[0]==0 ) break; - z++; - if( z[0]!='N' && z[0]!='n' ) break; - z++; - while( sqlite3Isspace(z[0]) ){ z++; } - if( z[0]!='(' ) break; - z++; - nOut += 5; /* ?,?,? */ - } - return nOut; -} - -/* -** Copy the current token into the output buffer while dealing with quoted -** identifiers. By default, all letters will be converted into lowercase. -** If the bUpper flag is set, uppercase will be used. The piOut argument -** will be used to update the target index into the output string. -*/ -static void copyNormalizedToken( - const char *zSql, /* The original SQL string */ - int iIn, /* Current index into the original SQL string */ - int nToken, /* Number of bytes in the current token */ - int tokenFlags, /* Flags returned by the tokenizer */ - char *zOut, /* The output string */ - int *piOut /* Pointer to target index into the output string */ -){ - int bQuoted = tokenFlags & SQLITE_TOKEN_QUOTED; - int bKeyword = tokenFlags & SQLITE_TOKEN_KEYWORD; - int j = *piOut, k = 0; - for(; k<nToken; k++){ - if( bQuoted ){ - if( k==0 && iIn>0 ){ - zOut[j++] = '"'; - continue; - }else if( k==nToken-1 ){ - zOut[j++] = '"'; - continue; - } - } - if( bKeyword ){ - zOut[j++] = sqlite3Toupper(zSql[iIn+k]); - }else{ - zOut[j++] = sqlite3Tolower(zSql[iIn+k]); - } - } - *piOut = j; -} - -/* -** Perform normalization of the SQL contained in the prepared statement and -** store the result in the zNormSql field. The schema for the associated -** databases are consulted while performing the normalization in order to -** determine if a token appears to be an identifier. All identifiers are -** left intact in the normalized SQL and all literals are replaced with a -** single '?'. -*/ -SQLITE_PRIVATE void sqlite3Normalize( - Vdbe *pVdbe, /* VM being reprepared */ - const char *zSql, /* The original SQL string */ - int nSql, /* Size of the input string in bytes */ - u8 prepFlags /* The flags passed to sqlite3_prepare_v3() */ -){ - sqlite3 *db; /* Database handle. */ - char *z; /* The output string */ - int nZ; /* Size of the output string in bytes */ - int i; /* Next character to read from zSql[] */ - int j; /* Next character to fill in on z[] */ - int tokenType = 0; /* Type of the next token */ - int prevTokenType = 0; /* Type of the previous token, except spaces */ - int n; /* Size of the next token */ - int nParen = 0; /* Nesting level of parenthesis */ - Hash inHash; /* Table of parenthesis levels to output index. */ - - db = sqlite3VdbeDb(pVdbe); - assert( db!=0 ); - assert( pVdbe->zNormSql==0 ); - if( zSql==0 ) return; - nZ = estimateNormalizedSize(zSql, nSql, prepFlags); - z = sqlite3DbMallocRawNN(db, nZ); - if( z==0 ) return; - sqlite3HashInit(&inHash); - for(i=j=0; i<nSql && zSql[i]; i+=n){ - int flags = 0; - if( tokenType!=TK_SPACE ) prevTokenType = tokenType; - n = sqlite3GetTokenNormalized((unsigned char*)zSql+i, &tokenType, &flags); - switch( tokenType ){ - case TK_SPACE: { - break; - } - case TK_ILLEGAL: { - sqlite3DbFree(db, z); - sqlite3HashClear(&inHash); - return; - } - case TK_STRING: - case TK_INTEGER: - case TK_FLOAT: - case TK_VARIABLE: - case TK_BLOB: { - z[j++] = '?'; - break; - } - case TK_LP: - case TK_RP: { - if( tokenType==TK_LP ){ - nParen++; - if( prevTokenType==TK_IN ){ - assert( nParen<nSql ); - sqlite3HashInsert(&inHash, zSql+nParen, SQLITE_INT_TO_PTR(j)); - } - }else{ - int jj; - assert( nParen<nSql ); - jj = SQLITE_PTR_TO_INT(sqlite3HashFind(&inHash, zSql+nParen)); - if( jj>0 ){ - sqlite3HashInsert(&inHash, zSql+nParen, 0); - assert( jj+6<nZ ); - memcpy(z+jj+1, "?,?,?", 5); - j = jj+6; - assert( nZ-1-j>=0 ); - assert( nZ-1-j<nZ ); - memset(z+j, 0, nZ-1-j); - } - nParen--; - } - assert( nParen>=0 ); - /* Fall through */ - } - case TK_MINUS: - case TK_SEMI: - case TK_PLUS: - case TK_STAR: - case TK_SLASH: - case TK_REM: - case TK_EQ: - case TK_LE: - case TK_NE: - case TK_LSHIFT: - case TK_LT: - case TK_RSHIFT: - case TK_GT: - case TK_GE: - case TK_BITOR: - case TK_CONCAT: - case TK_COMMA: - case TK_BITAND: - case TK_BITNOT: - case TK_DOT: - case TK_IN: - case TK_IS: - case TK_NOT: - case TK_NULL: - case TK_ID: { - if( tokenType==TK_NULL ){ - if( prevTokenType==TK_IS || prevTokenType==TK_NOT ){ - /* NULL is a keyword in this case, not a literal value */ - }else{ - /* Here the NULL is a literal value */ - z[j++] = '?'; - break; - } - } - if( j>0 && sqlite3IsIdChar(z[j-1]) && sqlite3IsIdChar(zSql[i]) ){ - z[j++] = ' '; - } - if( tokenType==TK_ID ){ - int i2 = i, n2 = n, rc = SQLITE_OK; - if( nParen>0 ){ - assert( nParen<nSql ); - sqlite3HashInsert(&inHash, zSql+nParen, 0); - } - if( flags&SQLITE_TOKEN_QUOTED ){ i2++; n2-=2; } - if( shouldTreatAsIdentifier(db, zSql+i2, n2, &rc)==0 ){ - if( rc!=SQLITE_OK ){ - sqlite3DbFree(db, z); - sqlite3HashClear(&inHash); - return; - } - if( sqlite3_keyword_check(zSql+i2, n2)==0 ){ - z[j++] = '?'; - break; - } - } - } - copyNormalizedToken(zSql, i, n, flags, z, &j); - break; - } - } - } - assert( j<nZ && "one" ); - while( j>0 && z[j-1]==' ' ){ j--; } - if( j>0 && z[j-1]!=';' ){ z[j++] = ';'; } - z[j] = 0; - assert( j<nZ && "two" ); - pVdbe->zNormSql = z; - sqlite3HashClear(&inHash); -} -#endif /* SQLITE_ENABLE_NORMALIZE */ /* ** Rerun the compilation of a statement after a schema change. @@ -124538,7 +124966,7 @@ static void pushOntoSorter( } assert( pSelect->iOffset==0 || pSelect->iLimit!=0 ); iLimit = pSelect->iOffset ? pSelect->iOffset+1 : pSelect->iLimit; - pSort->labelDone = sqlite3VdbeMakeLabel(v); + pSort->labelDone = sqlite3VdbeMakeLabel(pParse); sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, regOrigData, SQLITE_ECEL_DUP | (regOrigData? SQLITE_ECEL_REF : 0)); if( bSeq ){ @@ -124577,7 +125005,7 @@ static void pushOntoSorter( pKI->nAllField-pKI->nKeyField-1); addrJmp = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v); - pSort->labelBkOut = sqlite3VdbeMakeLabel(v); + pSort->labelBkOut = sqlite3VdbeMakeLabel(pParse); pSort->regReturn = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut); sqlite3VdbeAddOp1(v, OP_ResetSorter, pSort->iECursor); @@ -125324,7 +125752,7 @@ static void generateSortTail( ){ Vdbe *v = pParse->pVdbe; /* The prepared statement */ int addrBreak = pSort->labelDone; /* Jump here to exit loop */ - int addrContinue = sqlite3VdbeMakeLabel(v); /* Jump here for next cycle */ + int addrContinue = sqlite3VdbeMakeLabel(pParse);/* Jump here for next cycle */ int addr; /* Top of output loop. Jump for Next. */ int addrOnce = 0; int iTab; @@ -125364,7 +125792,12 @@ static void generateSortTail( regRow = pDest->iSdst; }else{ regRowid = sqlite3GetTempReg(pParse); - regRow = sqlite3GetTempRange(pParse, nColumn); + if( eDest==SRT_EphemTab || eDest==SRT_Table ){ + regRow = sqlite3GetTempReg(pParse); + nColumn = 0; + }else{ + regRow = sqlite3GetTempRange(pParse, nColumn); + } } nKey = pOrderBy->nExpr - pSort->nOBSat; if( pSort->sortFlags & SORTFLAG_UseSorter ){ @@ -125444,6 +125877,7 @@ static void generateSortTail( switch( eDest ){ case SRT_Table: case SRT_EphemTab: { + sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq, regRow); sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid); sqlite3VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid); sqlite3VdbeChangeP5(v, OPFLAG_APPEND); @@ -125984,15 +126418,15 @@ SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation( SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){ Table *pTab; sqlite3 *db = pParse->db; - int savedFlags; + u64 savedFlags; savedFlags = db->flags; - db->flags &= ~SQLITE_FullColNames; + db->flags &= ~(u64)SQLITE_FullColNames; db->flags |= SQLITE_ShortColNames; sqlite3SelectPrep(pParse, pSelect, 0); + db->flags = savedFlags; if( pParse->nErr ) return 0; while( pSelect->pPrior ) pSelect = pSelect->pPrior; - db->flags = savedFlags; pTab = sqlite3DbMallocZero(db, sizeof(Table) ); if( pTab==0 ){ return 0; @@ -126236,7 +126670,7 @@ static void generateWithRecursiveQuery( if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return; /* Process the LIMIT and OFFSET clauses, if they exist */ - addrBreak = sqlite3VdbeMakeLabel(v); + addrBreak = sqlite3VdbeMakeLabel(pParse); p->nSelectRow = 320; /* 4 billion rows */ computeLimitRegisters(pParse, p, addrBreak); pLimit = p->pLimit; @@ -126306,7 +126740,7 @@ static void generateWithRecursiveQuery( sqlite3VdbeAddOp1(v, OP_Delete, iQueue); /* Output the single row in Current */ - addrCont = sqlite3VdbeMakeLabel(v); + addrCont = sqlite3VdbeMakeLabel(pParse); codeOffset(v, regOffset, addrCont); selectInnerLoop(pParse, p, iCurrent, 0, 0, pDest, addrCont, addrBreak); @@ -126614,8 +127048,8 @@ static int multiSelect( if( dest.eDest!=priorOp ){ int iCont, iBreak, iStart; assert( p->pEList ); - iBreak = sqlite3VdbeMakeLabel(v); - iCont = sqlite3VdbeMakeLabel(v); + iBreak = sqlite3VdbeMakeLabel(pParse); + iCont = sqlite3VdbeMakeLabel(pParse); computeLimitRegisters(pParse, p, iBreak); sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v); iStart = sqlite3VdbeCurrentAddr(v); @@ -126683,8 +127117,8 @@ static int multiSelect( ** tables. */ assert( p->pEList ); - iBreak = sqlite3VdbeMakeLabel(v); - iCont = sqlite3VdbeMakeLabel(v); + iBreak = sqlite3VdbeMakeLabel(pParse); + iCont = sqlite3VdbeMakeLabel(pParse); computeLimitRegisters(pParse, p, iBreak); sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v); r1 = sqlite3GetTempReg(pParse); @@ -126814,7 +127248,7 @@ static int generateOutputSubroutine( int addr; addr = sqlite3VdbeCurrentAddr(v); - iContinue = sqlite3VdbeMakeLabel(v); + iContinue = sqlite3VdbeMakeLabel(pParse); /* Suppress duplicates for UNION, EXCEPT, and INTERSECT */ @@ -127051,8 +127485,8 @@ static int multiSelectOrderBy( db = pParse->db; v = pParse->pVdbe; assert( v!=0 ); /* Already thrown the error if VDBE alloc failed */ - labelEnd = sqlite3VdbeMakeLabel(v); - labelCmpr = sqlite3VdbeMakeLabel(v); + labelEnd = sqlite3VdbeMakeLabel(pParse); + labelCmpr = sqlite3VdbeMakeLabel(pParse); /* Patch up the ORDER BY clause @@ -127368,6 +127802,7 @@ static Expr *substExpr( ifNullRow.iTable = pSubst->iNewTable; pCopy = &ifNullRow; } + testcase( ExprHasProperty(pCopy, EP_Subquery) ); pNew = sqlite3ExprDup(db, pCopy, 0); if( pNew && pSubst->isLeftJoin ){ ExprSetProperty(pNew, EP_CanBeNull); @@ -127860,11 +128295,9 @@ static int flattenSubquery( jointype = pSubitem->fg.jointype; }else{ assert( pParent!=p ); /* 2nd and subsequent times through the loop */ - pSrc = pParent->pSrc = sqlite3SrcListAppend(db, 0, 0, 0); - if( pSrc==0 ){ - assert( db->mallocFailed ); - break; - } + pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); + if( pSrc==0 ) break; + pParent->pSrc = pSrc; } /* The subquery uses a single slot of the FROM clause of the outer @@ -127883,10 +128316,9 @@ static int flattenSubquery( ** for the two elements in the FROM clause of the subquery. */ if( nSubSrc>1 ){ - pParent->pSrc = pSrc = sqlite3SrcListEnlarge(db, pSrc, nSubSrc-1,iFrom+1); - if( db->mallocFailed ){ - break; - } + pSrc = sqlite3SrcListEnlarge(pParse, pSrc, nSubSrc-1,iFrom+1); + if( pSrc==0 ) break; + pParent->pSrc = pSrc; } /* Transfer the FROM clause terms from the subquery into the @@ -127932,7 +128364,8 @@ static int flattenSubquery( pParent->pOrderBy = pOrderBy; pSub->pOrderBy = 0; } - pWhere = sqlite3ExprDup(db, pSub->pWhere, 0); + pWhere = pSub->pWhere; + pSub->pWhere = 0; if( isLeftJoin>0 ){ setJoinExpr(pWhere, iNewParent); } @@ -129235,7 +129668,7 @@ static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){ regAgg = 0; } if( pF->iDistinct>=0 ){ - addrNext = sqlite3VdbeMakeLabel(v); + addrNext = sqlite3VdbeMakeLabel(pParse); testcase( nArg==0 ); /* Error condition */ testcase( nArg>1 ); /* Also an error */ codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg); @@ -129371,14 +129804,19 @@ static struct SrcList_item *isSelfJoinView( ){ struct SrcList_item *pItem; for(pItem = pTabList->a; pItem<pThis; pItem++){ + Select *pS1; if( pItem->pSelect==0 ) continue; if( pItem->fg.viaCoroutine ) continue; if( pItem->zName==0 ) continue; if( sqlite3_stricmp(pItem->zDatabase, pThis->zDatabase)!=0 ) continue; if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue; - if( sqlite3ExprCompare(0, - pThis->pSelect->pWhere, pItem->pSelect->pWhere, -1) - ){ + pS1 = pItem->pSelect; + if( pThis->pSelect->selId!=pS1->selId ){ + /* The query flattener left two different CTE tables with identical + ** names in the same FROM clause. */ + continue; + } + if( sqlite3ExprCompare(0, pThis->pSelect->pWhere, pS1->pWhere, -1) ){ /* The view was modified by some other optimization such as ** pushDownWhereTerms() */ continue; @@ -129640,6 +130078,7 @@ SQLITE_PRIVATE int sqlite3Select( } if( flattenSubquery(pParse, p, i, isAgg) ){ + if( pParse->nErr ) goto select_end; /* This subquery can be absorbed into its parent. */ i = -1; } @@ -129735,22 +130174,12 @@ SQLITE_PRIVATE int sqlite3Select( pSub = pItem->pSelect; if( pSub==0 ) continue; - /* Sometimes the code for a subquery will be generated more than - ** once, if the subquery is part of the WHERE clause in a LEFT JOIN, - ** for example. In that case, do not regenerate the code to manifest - ** a view or the co-routine to implement a view. The first instance - ** is sufficient, though the subroutine to manifest the view does need - ** to be invoked again. */ - if( pItem->addrFillSub ){ - if( pItem->fg.viaCoroutine==0 ){ - /* The subroutine that manifests the view might be a one-time routine, - ** or it might need to be rerun on each iteration because it - ** encodes a correlated subquery. */ - testcase( sqlite3VdbeGetOp(v, pItem->addrFillSub)->opcode==OP_Once ); - sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub); - } - continue; - } + /* The code for a subquery should only be generated once, though it is + ** technically harmless for it to be generated multiple times. The + ** following assert() will detect if something changes to cause + ** the same subquery to be coded multiple times, as a signal to the + ** developers to try to optimize the situation. */ + assert( pItem->addrFillSub==0 ); /* Increment Parse.nHeight by the height of the largest expression ** tree referred to by this, the parent select. The child select @@ -129938,7 +130367,7 @@ SQLITE_PRIVATE int sqlite3Select( /* Set the limiter. */ - iEnd = sqlite3VdbeMakeLabel(v); + iEnd = sqlite3VdbeMakeLabel(pParse); if( (p->selFlags & SF_FixedLimit)==0 ){ p->nSelectRow = 320; /* 4 billion rows */ } @@ -130005,9 +130434,9 @@ SQLITE_PRIVATE int sqlite3Select( assert( p->pEList==pEList ); #ifndef SQLITE_OMIT_WINDOWFUNC if( pWin ){ - int addrGosub = sqlite3VdbeMakeLabel(v); - int iCont = sqlite3VdbeMakeLabel(v); - int iBreak = sqlite3VdbeMakeLabel(v); + int addrGosub = sqlite3VdbeMakeLabel(pParse); + int iCont = sqlite3VdbeMakeLabel(pParse); + int iBreak = sqlite3VdbeMakeLabel(pParse); int regGosub = ++pParse->nMem; sqlite3WindowCodeStep(pParse, p, pWInfo, regGosub, addrGosub); @@ -130082,7 +130511,7 @@ SQLITE_PRIVATE int sqlite3Select( } /* Create a label to jump to when we want to abort the query */ - addrEnd = sqlite3VdbeMakeLabel(v); + addrEnd = sqlite3VdbeMakeLabel(pParse); /* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in ** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the @@ -130171,9 +130600,9 @@ SQLITE_PRIVATE int sqlite3Select( iUseFlag = ++pParse->nMem; iAbortFlag = ++pParse->nMem; regOutputRow = ++pParse->nMem; - addrOutputRow = sqlite3VdbeMakeLabel(v); + addrOutputRow = sqlite3VdbeMakeLabel(pParse); regReset = ++pParse->nMem; - addrReset = sqlite3VdbeMakeLabel(v); + addrReset = sqlite3VdbeMakeLabel(pParse); iAMem = pParse->nMem + 1; pParse->nMem += pGroupBy->nExpr; iBMem = pParse->nMem + 1; @@ -131460,7 +131889,7 @@ static SrcList *targetSrcList( int iDb; /* Index of the database to use */ SrcList *pSrc; /* SrcList to be returned */ - pSrc = sqlite3SrcListAppend(db, 0, 0, 0); + pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); if( pSrc ){ assert( pSrc->nSrc>0 ); pSrc->a[pSrc->nSrc-1].zName = sqlite3DbStrDup(db, pStep->zTarget); @@ -131645,6 +132074,7 @@ static TriggerPrg *codeRowTrigger( pSubParse->zAuthContext = pTrigger->zName; pSubParse->eTriggerOp = pTrigger->op; pSubParse->nQueryLoop = pParse->nQueryLoop; + pSubParse->disableVtab = pParse->disableVtab; v = sqlite3GetVdbe(pSubParse); if( v ){ @@ -131672,7 +132102,7 @@ static TriggerPrg *codeRowTrigger( if( SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen) && db->mallocFailed==0 ){ - iEndTrigger = sqlite3VdbeMakeLabel(v); + iEndTrigger = sqlite3VdbeMakeLabel(pSubParse); sqlite3ExprIfFalse(pSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL); } sqlite3ExprDelete(db, pWhen); @@ -132271,6 +132701,7 @@ SQLITE_PRIVATE void sqlite3Update( ** being updated. Fill in aRegIdx[] with a register number that will hold ** the key for accessing each index. */ + if( onError==OE_Replace ) bReplace = 1; for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ int reg; if( chngKey || hasFK>1 || pIdx==pPk @@ -132284,9 +132715,7 @@ SQLITE_PRIVATE void sqlite3Update( if( indexColumnIsBeingUpdated(pIdx, i, aXRef, chngRowid) ){ reg = ++pParse->nMem; pParse->nMem += pIdx->nColumn; - if( (onError==OE_Replace) - || (onError==OE_Default && pIdx->onError==OE_Replace) - ){ + if( onError==OE_Default && pIdx->onError==OE_Replace ){ bReplace = 1; } break; @@ -132358,7 +132787,7 @@ SQLITE_PRIVATE void sqlite3Update( #endif /* Jump to labelBreak to abandon further processing of this UPDATE */ - labelContinue = labelBreak = sqlite3VdbeMakeLabel(v); + labelContinue = labelBreak = sqlite3VdbeMakeLabel(pParse); /* Not an UPSERT. Normal processing. Begin by ** initialize the count of updated rows */ @@ -132493,13 +132922,13 @@ SQLITE_PRIVATE void sqlite3Update( VdbeCoverage(v); } if( eOnePass!=ONEPASS_SINGLE ){ - labelContinue = sqlite3VdbeMakeLabel(v); + labelContinue = sqlite3VdbeMakeLabel(pParse); } sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak); VdbeCoverageIf(v, pPk==0); VdbeCoverageIf(v, pPk!=0); }else if( pPk ){ - labelContinue = sqlite3VdbeMakeLabel(v); + labelContinue = sqlite3VdbeMakeLabel(pParse); sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v); addrTop = sqlite3VdbeAddOp2(v, OP_RowData, iEph, regKey); sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0); @@ -133267,16 +133696,16 @@ static int execSqlF(sqlite3 *db, char **pzErrMsg, const char *zSql, ...){ ** transient would cause the database file to appear to be deleted ** following reboot. */ -SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm){ +SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm, Expr *pInto){ Vdbe *v = sqlite3GetVdbe(pParse); int iDb = 0; - if( v==0 ) return; + if( v==0 ) goto build_vacuum_end; if( pNm ){ #ifndef SQLITE_BUG_COMPATIBLE_20160819 /* Default behavior: Report an error if the argument to VACUUM is ** not recognized */ iDb = sqlite3TwoPartName(pParse, pNm, pNm, &pNm); - if( iDb<0 ) return; + if( iDb<0 ) goto build_vacuum_end; #else /* When SQLITE_BUG_COMPATIBLE_20160819 is defined, unrecognized arguments ** to VACUUM are silently ignored. This is a back-out of a bug fix that @@ -133288,21 +133717,33 @@ SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm){ #endif } if( iDb!=1 ){ - sqlite3VdbeAddOp1(v, OP_Vacuum, iDb); + int iIntoReg = 0; + if( pInto && sqlite3ResolveSelfReference(pParse,0,0,pInto,0)==0 ){ + iIntoReg = ++pParse->nMem; + sqlite3ExprCode(pParse, pInto, iIntoReg); + } + sqlite3VdbeAddOp2(v, OP_Vacuum, iDb, iIntoReg); sqlite3VdbeUsesBtree(v, iDb); } +build_vacuum_end: + sqlite3ExprDelete(pParse->db, pInto); return; } /* ** This routine implements the OP_Vacuum opcode of the VDBE. */ -SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){ +SQLITE_PRIVATE int sqlite3RunVacuum( + char **pzErrMsg, /* Write error message here */ + sqlite3 *db, /* Database connection */ + int iDb, /* Which attached DB to vacuum */ + sqlite3_value *pOut /* Write results here, if not NULL */ +){ int rc = SQLITE_OK; /* Return code from service routines */ Btree *pMain; /* The database being vacuumed */ Btree *pTemp; /* The temporary database we vacuum into */ - u16 saved_mDbFlags; /* Saved value of db->mDbFlags */ - u32 saved_flags; /* Saved value of db->flags */ + u32 saved_mDbFlags; /* Saved value of db->mDbFlags */ + u64 saved_flags; /* Saved value of db->flags */ int saved_nChange; /* Saved value of db->nChange */ int saved_nTotalChange; /* Saved value of db->nTotalChange */ u8 saved_mTrace; /* Saved trace settings */ @@ -133311,6 +133752,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){ int nRes; /* Bytes of reserved space at the end of each page */ int nDb; /* Number of attached databases */ const char *zDbMain; /* Schema name of database to vacuum */ + const char *zOut; /* Name of output file */ if( !db->autoCommit ){ sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction"); @@ -133320,6 +133762,15 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){ sqlite3SetString(pzErrMsg, db,"cannot VACUUM - SQL statements in progress"); return SQLITE_ERROR; } + if( pOut ){ + if( sqlite3_value_type(pOut)!=SQLITE_TEXT ){ + sqlite3SetString(pzErrMsg, db, "non-text filename"); + return SQLITE_ERROR; + } + zOut = (const char*)sqlite3_value_text(pOut); + }else{ + zOut = ""; + } /* Save the current value of the database flags so that it can be ** restored before returning. Then set the writable-schema flag, and @@ -133331,7 +133782,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){ saved_mTrace = db->mTrace; db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks; db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum; - db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder + db->flags &= ~(u64)(SQLITE_ForeignKeys | SQLITE_ReverseOrder | SQLITE_Defensive | SQLITE_CountRows); db->mTrace = 0; @@ -133354,19 +133805,21 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){ ** to write the journal header file. */ nDb = db->nDb; - rc = execSql(db, pzErrMsg, "ATTACH''AS vacuum_db"); + rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS vacuum_db", zOut); if( rc!=SQLITE_OK ) goto end_of_vacuum; assert( (db->nDb-1)==nDb ); pDb = &db->aDb[nDb]; assert( strcmp(pDb->zDbSName,"vacuum_db")==0 ); pTemp = pDb->pBt; - - /* The call to execSql() to attach the temp database has left the file - ** locked (as there was more than one active statement when the transaction - ** to read the schema was concluded. Unlock it here so that this doesn't - ** cause problems for the call to BtreeSetPageSize() below. */ - sqlite3BtreeCommit(pTemp); - + if( pOut ){ + sqlite3_file *id = sqlite3PagerFile(sqlite3BtreePager(pTemp)); + i64 sz = 0; + if( id->pMethods!=0 && (sqlite3OsFileSize(id, &sz)!=SQLITE_OK || sz>0) ){ + rc = SQLITE_ERROR; + sqlite3SetString(pzErrMsg, db, "output file already exists"); + goto end_of_vacuum; + } + } nRes = sqlite3BtreeGetOptimalReserve(pMain); /* A VACUUM cannot change the pagesize of an encrypted database. */ @@ -133390,7 +133843,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){ */ rc = execSql(db, pzErrMsg, "BEGIN"); if( rc!=SQLITE_OK ) goto end_of_vacuum; - rc = sqlite3BtreeBeginTrans(pMain, 2, 0); + rc = sqlite3BtreeBeginTrans(pMain, pOut==0 ? 2 : 0, 0); if( rc!=SQLITE_OK ) goto end_of_vacuum; /* Do not attempt to change the page size for a WAL database */ @@ -133485,7 +133938,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){ }; assert( 1==sqlite3BtreeIsInTrans(pTemp) ); - assert( 1==sqlite3BtreeIsInTrans(pMain) ); + assert( pOut!=0 || 1==sqlite3BtreeIsInTrans(pMain) ); /* Copy Btree meta values */ for(i=0; i<ArraySize(aCopy); i+=2){ @@ -133496,17 +133949,23 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){ if( NEVER(rc!=SQLITE_OK) ) goto end_of_vacuum; } - rc = sqlite3BtreeCopyFile(pMain, pTemp); + if( pOut==0 ){ + rc = sqlite3BtreeCopyFile(pMain, pTemp); + } if( rc!=SQLITE_OK ) goto end_of_vacuum; rc = sqlite3BtreeCommit(pTemp); if( rc!=SQLITE_OK ) goto end_of_vacuum; #ifndef SQLITE_OMIT_AUTOVACUUM - sqlite3BtreeSetAutoVacuum(pMain, sqlite3BtreeGetAutoVacuum(pTemp)); + if( pOut==0 ){ + sqlite3BtreeSetAutoVacuum(pMain, sqlite3BtreeGetAutoVacuum(pTemp)); + } #endif } assert( rc==SQLITE_OK ); - rc = sqlite3BtreeSetPageSize(pMain, sqlite3BtreeGetPageSize(pTemp), nRes,1); + if( pOut==0 ){ + rc = sqlite3BtreeSetPageSize(pMain, sqlite3BtreeGetPageSize(pTemp), nRes,1); + } end_of_vacuum: /* Restore the original value of db->flags */ @@ -134547,6 +135006,7 @@ SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){ const sqlite3_module *pMod = pVTab->pMod->pModule; if( pVTab->pVtab && pMod->iVersion>=2 ){ int (*xMethod)(sqlite3_vtab *, int); + sqlite3VtabLock(pVTab); switch( op ){ case SAVEPOINT_BEGIN: xMethod = pMod->xSavepoint; @@ -134562,6 +135022,7 @@ SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){ if( xMethod && pVTab->iSavepoint>iSavepoint ){ rc = xMethod(pVTab->pVtab, iSavepoint); } + sqlite3VtabUnlock(pVTab); } } } @@ -135323,8 +135784,11 @@ SQLITE_PRIVATE void sqlite3WhereAddScanStatus( # define sqlite3WhereAddScanStatus(a, b, c, d) ((void)d) #endif SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( + Parse *pParse, /* Parsing context */ + Vdbe *v, /* Prepared statement under construction */ WhereInfo *pWInfo, /* Complete information about the WHERE clause */ int iLevel, /* Which level of pWInfo->a[] should be coded */ + WhereLevel *pLevel, /* The current level pointer */ Bitmask notReady /* Which tables are currently available */ ); @@ -135594,6 +136058,7 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( } #endif zMsg = sqlite3StrAccumFinish(&str); + sqlite3ExplainBreakpoint("",zMsg); ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v), pParse->addrExplain, 0, zMsg,P4_DYNAMIC); } @@ -135919,16 +136384,17 @@ static int codeEqualityTerm( if( pLoop->aLTerm[i]->pExpr==pX ) nEq++; } + iTab = 0; if( (pX->flags & EP_xIsSelect)==0 || pX->x.pSelect->pEList->nExpr==1 ){ - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0); + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); }else{ sqlite3 *db = pParse->db; pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); if( !db->mallocFailed ){ aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap); - pTerm->pExpr->iTable = pX->iTable; + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab); + pTerm->pExpr->iTable = iTab; } sqlite3ExprDelete(db, pX); pX = pTerm->pExpr; @@ -135938,7 +136404,6 @@ static int codeEqualityTerm( testcase( bRev ); bRev = !bRev; } - iTab = pX->iTable; sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0); VdbeCoverageIf(v, bRev); VdbeCoverageIf(v, !bRev); @@ -135946,7 +136411,7 @@ static int codeEqualityTerm( pLoop->wsFlags |= WHERE_IN_ABLE; if( pLevel->u.in.nIn==0 ){ - pLevel->addrNxt = sqlite3VdbeMakeLabel(v); + pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse); } i = pLevel->u.in.nIn; @@ -136457,7 +136922,9 @@ static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){ #ifndef SQLITE_OMIT_SUBQUERY if( (p->flags & EP_xIsSelect) ){ Vdbe *v = pParse->pVdbe; - int iSelect = sqlite3CodeSubselect(pParse, p, 0, 0); + int iSelect; + assert( p->op==TK_SELECT ); + iSelect = sqlite3CodeSubselect(pParse, p); sqlite3VdbeAddOp3(v, OP_Copy, iSelect, iReg, nReg-1); }else #endif @@ -136543,22 +137010,21 @@ static void whereIndexExprTrans( ** implementation described by pWInfo. */ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( + Parse *pParse, /* Parsing context */ + Vdbe *v, /* Prepared statement under construction */ WhereInfo *pWInfo, /* Complete information about the WHERE clause */ int iLevel, /* Which level of pWInfo->a[] should be coded */ + WhereLevel *pLevel, /* The current level pointer */ Bitmask notReady /* Which tables are currently available */ ){ int j, k; /* Loop counters */ int iCur; /* The VDBE cursor for the table */ int addrNxt; /* Where to jump to continue with the next IN case */ - int omitTable; /* True if we use the index only */ int bRev; /* True if we need to scan in reverse order */ - WhereLevel *pLevel; /* The where level to be coded */ WhereLoop *pLoop; /* The WhereLoop object being coded */ WhereClause *pWC; /* Decomposition of the entire WHERE clause */ WhereTerm *pTerm; /* A WHERE clause term */ - Parse *pParse; /* Parsing context */ sqlite3 *db; /* Database connection */ - Vdbe *v; /* The prepared stmt under constructions */ struct SrcList_item *pTabItem; /* FROM clause term being coded */ int addrBrk; /* Jump here to break out of the loop */ int addrHalt; /* addrBrk for the outermost loop */ @@ -136568,18 +137034,13 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( Index *pIdx = 0; /* Index used by loop (if any) */ int iLoop; /* Iteration of constraint generator loop */ - pParse = pWInfo->pParse; - v = pParse->pVdbe; pWC = &pWInfo->sWC; db = pParse->db; - pLevel = &pWInfo->a[iLevel]; pLoop = pLevel->pWLoop; pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; iCur = pTabItem->iCursor; pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); bRev = (pWInfo->revMask>>iLevel)&1; - omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0 - && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0; VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName)); /* Create labels for the "break" and "continue" instructions @@ -136592,8 +137053,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( ** there are no IN operators in the constraints, the "addrNxt" label ** is the same as "addrBrk". */ - addrBrk = pLevel->addrBrk = pLevel->addrNxt = sqlite3VdbeMakeLabel(v); - addrCont = pLevel->addrCont = sqlite3VdbeMakeLabel(v); + addrBrk = pLevel->addrBrk = pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse); + addrCont = pLevel->addrCont = sqlite3VdbeMakeLabel(pParse); /* If this is the right table of a LEFT OUTER JOIN, allocate and ** initialize a memory cell that records if this table matches any @@ -136720,7 +137181,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( pTerm = pLoop->aLTerm[0]; assert( pTerm!=0 ); assert( pTerm->pExpr!=0 ); - assert( omitTable==0 ); testcase( pTerm->wtFlags & TERM_VIRTUAL ); iReleaseReg = ++pParse->nMem; iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg); @@ -136739,7 +137199,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( int memEndValue = 0; WhereTerm *pStart, *pEnd; - assert( omitTable==0 ); j = 0; pStart = pEnd = 0; if( pLoop->wsFlags & WHERE_BTM_LIMIT ) pStart = pLoop->aLTerm[j++]; @@ -136903,6 +137362,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( char *zEndAff = 0; /* Affinity for end of range constraint */ u8 bSeekPastNull = 0; /* True to seek past initial nulls */ u8 bStopAtNull = 0; /* Add condition to terminate at NULLs */ + int omitTable; /* True if we use the index only */ + pIdx = pLoop->u.btree.pIndex; iIdxCur = pLevel->iIdxCur; @@ -137104,6 +137565,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( } /* Seek the table cursor, if required */ + omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0 + && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0; if( omitTable ){ /* pIdx is a covering index. No need to access the main table. */ }else if( HasRowid(pIdx->pTable) ){ @@ -137138,8 +137601,13 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( ** the cursor. In this case it is important to do the full evaluation, ** as the result of the expression may not be NULL, even if all table ** column values are. https://www.sqlite.org/src/info/7fa8049685b50b5a + ** + ** Also, do not do this when processing one index an a multi-index + ** OR clause, since the transformation will become invalid once we + ** move forward to the next index. + ** https://sqlite.org/src/info/4e8e4857d32d401f */ - if( pLevel->iLeftJoin==0 ){ + if( pLevel->iLeftJoin==0 && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){ whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo); } @@ -137214,7 +137682,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( int regReturn = ++pParse->nMem; /* Register used with OP_Gosub */ int regRowset = 0; /* Register for RowSet object */ int regRowid = 0; /* Register holding rowid */ - int iLoopBody = sqlite3VdbeMakeLabel(v); /* Start of loop body */ + int iLoopBody = sqlite3VdbeMakeLabel(pParse);/* Start of loop body */ int iRetInit; /* Address of regReturn init */ int untestedTerms = 0; /* Some terms not completely tested */ int ii; /* Loop counter */ @@ -137330,6 +137798,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( pOrExpr = pAndExpr; } /* Loop through table entries that match term pOrTerm. */ + ExplainQueryPlan((pParse, 1, "INDEX %d", ii+1)); WHERETRACE(0xffff, ("Subplan for OR-clause:\n")); pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, wctrlFlags, iCovCur); @@ -137433,6 +137902,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( /* Finish the loop through table entries that match term pOrTerm. */ sqlite3WhereEnd(pSubWInfo); + ExplainQueryPlanPop(pParse); } } } @@ -138394,6 +138864,7 @@ static void exprAnalyzeOrTerm( ** and column is found but leave okToChngToIN false if not found. */ for(j=0; j<2 && !okToChngToIN; j++){ + Expr *pLeft = 0; pOrTerm = pOrWc->a; for(i=pOrWc->nTerm-1; i>=0; i--, pOrTerm++){ assert( pOrTerm->eOperator & WO_EQ ); @@ -138417,6 +138888,7 @@ static void exprAnalyzeOrTerm( } iColumn = pOrTerm->u.leftColumn; iCursor = pOrTerm->leftCursor; + pLeft = pOrTerm->pExpr->pLeft; break; } if( i<0 ){ @@ -138436,7 +138908,9 @@ static void exprAnalyzeOrTerm( assert( pOrTerm->eOperator & WO_EQ ); if( pOrTerm->leftCursor!=iCursor ){ pOrTerm->wtFlags &= ~TERM_OR_OK; - }else if( pOrTerm->u.leftColumn!=iColumn ){ + }else if( pOrTerm->u.leftColumn!=iColumn || (iColumn==XN_EXPR + && sqlite3ExprCompare(pParse, pOrTerm->pExpr->pLeft, pLeft, -1) + )){ okToChngToIN = 0; }else{ int affLeft, affRight; @@ -139524,6 +139998,17 @@ static WhereTerm *whereScanNext(WhereScan *pScan){ return 0; } +/* +** This is whereScanInit() for the case of an index on an expression. +** It is factored out into a separate tail-recursion subroutine so that +** the normal whereScanInit() routine, which is a high-runner, does not +** need to push registers onto the stack as part of its prologue. +*/ +static SQLITE_NOINLINE WhereTerm *whereScanInitIndexExpr(WhereScan *pScan){ + pScan->idxaff = sqlite3ExprAffinity(pScan->pIdxExpr); + return whereScanNext(pScan); +} + /* ** Initialize a WHERE clause scanner object. Return a pointer to the ** first match. Return NULL if there are no matches. @@ -139556,12 +140041,19 @@ static WhereTerm *whereScanInit( pScan->pIdxExpr = 0; pScan->idxaff = 0; pScan->zCollName = 0; + pScan->opMask = opMask; + pScan->k = 0; + pScan->aiCur[0] = iCur; + pScan->nEquiv = 1; + pScan->iEquiv = 1; if( pIdx ){ int j = iColumn; iColumn = pIdx->aiColumn[j]; if( iColumn==XN_EXPR ){ pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr; pScan->zCollName = pIdx->azColl[j]; + pScan->aiColumn[0] = XN_EXPR; + return whereScanInitIndexExpr(pScan); }else if( iColumn==pIdx->pTable->iPKey ){ iColumn = XN_ROWID; }else if( iColumn>=0 ){ @@ -139571,12 +140063,7 @@ static WhereTerm *whereScanInit( }else if( iColumn==XN_EXPR ){ return 0; } - pScan->opMask = opMask; - pScan->k = 0; - pScan->aiCur[0] = iCur; pScan->aiColumn[0] = iColumn; - pScan->nEquiv = 1; - pScan->iEquiv = 1; return whereScanNext(pScan); } @@ -140051,7 +140538,7 @@ static void constructAutomaticIndex( addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v); } if( pPartial ){ - iContinue = sqlite3VdbeMakeLabel(v); + iContinue = sqlite3VdbeMakeLabel(pParse); sqlite3ExprIfFalse(pParse, pPartial, iContinue, SQLITE_JUMPIFNULL); pLoop->wsFlags |= WHERE_PARTIALIDX; } @@ -140068,6 +140555,7 @@ static void constructAutomaticIndex( translateColumnToCopy(pParse, addrTop, pLevel->iTabCur, pTabItem->regResult, 1); sqlite3VdbeGoto(v, addrTop); + pTabItem->fg.viaCoroutine = 0; }else{ sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v); } @@ -141423,7 +141911,7 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ rc = whereLoopXfer(db, p, pTemplate); if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){ Index *pIndex = p->u.btree.pIndex; - if( pIndex && pIndex->tnum==0 ){ + if( pIndex && pIndex->idxType==SQLITE_IDXTYPE_IPK ){ p->u.btree.pIndex = 0; } } @@ -141590,8 +142078,8 @@ static int whereRangeVectorLen( ** terms only. If it is modified, this value is restored before this ** function returns. ** -** If pProbe->tnum==0, that means pIndex is a fake index used for the -** INTEGER PRIMARY KEY. +** If pProbe->idxType==SQLITE_IDXTYPE_IPK, that means pIndex is +** a fake index used for the INTEGER PRIMARY KEY. */ static int whereLoopAddBtreeIndex( WhereLoopBuilder *pBuilder, /* The WhereLoop factory */ @@ -142091,6 +142579,7 @@ static int whereLoopAddBtree( sPk.onError = OE_Replace; sPk.pTable = pTab; sPk.szIdxRow = pTab->szTabRow; + sPk.idxType = SQLITE_IDXTYPE_IPK; aiRowEstPk[0] = pTab->nRowLogEst; aiRowEstPk[1] = 0; pFirst = pSrc->pTab->pIndex; @@ -142181,7 +142670,7 @@ static int whereLoopAddBtree( b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor); /* The ONEPASS_DESIRED flags never occurs together with ORDER BY */ assert( (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || b==0 ); - if( pProbe->tnum<=0 ){ + if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){ /* Integer primary key index */ pNew->wsFlags = WHERE_IPK; @@ -143857,7 +144346,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( pWInfo->pResultSet = pResultSet; pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1; pWInfo->nLevel = nTabList; - pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v); + pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(pParse); pWInfo->wctrlFlags = wctrlFlags; pWInfo->iLimit = iAuxArg; pWInfo->savedNQueryLoop = pParse->nQueryLoop; @@ -144131,9 +144620,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){ int wsFlags = pWInfo->a[0].pWLoop->wsFlags; int bOnerow = (wsFlags & WHERE_ONEROW)!=0; + assert( !(wsFlags & WHERE_VIRTUALTABLE) || IsVirtual(pTabList->a[0].pTab) ); if( bOnerow || ( 0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW) - && 0==(wsFlags & WHERE_VIRTUALTABLE) + && !IsVirtual(pTabList->a[0].pTab) && (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK)) )){ pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI; @@ -144288,7 +144778,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( pParse, pTabList, pLevel, wctrlFlags ); pLevel->addrBody = sqlite3VdbeCurrentAddr(v); - notReady = sqlite3WhereCodeOneLoopStart(pWInfo, ii, notReady); + notReady = sqlite3WhereCodeOneLoopStart(pParse,v,pWInfo,ii,pLevel,notReady); pWInfo->iContinue = pLevel->addrCont; if( (wsFlags&WHERE_MULTI_OR)==0 && (wctrlFlags&WHERE_OR_SUBCLAUSE)==0 ){ sqlite3WhereAddScanStatus(v, pTabList, pLevel, addrExplain); @@ -144473,6 +144963,29 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ continue; } +#ifdef SQLITE_ENABLE_EARLY_CURSOR_CLOSE + /* Close all of the cursors that were opened by sqlite3WhereBegin. + ** Except, do not close cursors that will be reused by the OR optimization + ** (WHERE_OR_SUBCLAUSE). And do not close the OP_OpenWrite cursors + ** created for the ONEPASS optimization. + */ + if( (pTab->tabFlags & TF_Ephemeral)==0 + && pTab->pSelect==0 + && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 + ){ + int ws = pLoop->wsFlags; + if( pWInfo->eOnePass==ONEPASS_OFF && (ws & WHERE_IDX_ONLY)==0 ){ + sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor); + } + if( (ws & WHERE_INDEXED)!=0 + && (ws & (WHERE_IPK|WHERE_AUTO_INDEX))==0 + && pLevel->iIdxCur!=pWInfo->aiCurOnePass[1] + ){ + sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur); + } + } +#endif + /* If this scan uses an index, make VDBE code substitutions to read data ** from the index instead of from the table where possible. In some cases ** this optimization prevents the table from ever being read, which can @@ -145372,8 +145885,7 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ pSub = sqlite3SelectNew( pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0 ); - p->pSrc = sqlite3SrcListAppend(db, 0, 0, 0); - assert( p->pSrc || db->mallocFailed ); + p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); if( p->pSrc ){ p->pSrc->a[0].pSelect = pSub; sqlite3SrcListAssignCursors(pParse, p->pSrc); @@ -145430,6 +145942,7 @@ SQLITE_PRIVATE void sqlite3WindowListDelete(sqlite3 *db, Window *p){ */ static Expr *sqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){ if( 0==sqlite3ExprIsConstant(pExpr) ){ + if( IN_RENAME_OBJECT ) sqlite3RenameExprUnmap(pParse, pExpr); sqlite3ExprDelete(pParse->db, pExpr); pExpr = sqlite3ExprAlloc(pParse->db, TK_NULL, 0, 0); } @@ -145624,6 +146137,7 @@ static void windowCheckIntValue(Parse *pParse, int reg, int eCond){ VdbeCoverageNeverNullIf(v, eCond==0); VdbeCoverageNeverNullIf(v, eCond==1); VdbeCoverageNeverNullIf(v, eCond==2); + sqlite3MayAbort(pParse); sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_ERROR, OE_Abort); sqlite3VdbeAppendP4(v, (void*)azErr[eCond], P4_STATIC); sqlite3ReleaseTempReg(pParse, regZero); @@ -145879,7 +146393,7 @@ static void windowReturnOneRow( || pFunc->zName==first_valueName ){ int csr = pWin->csrApp; - int lbl = sqlite3VdbeMakeLabel(v); + int lbl = sqlite3VdbeMakeLabel(pParse); int tmpReg = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult); @@ -145902,7 +146416,7 @@ static void windowReturnOneRow( int nArg = pWin->pOwner->x.pList->nExpr; int iEph = pMWin->iEphCsr; int csr = pWin->csrApp; - int lbl = sqlite3VdbeMakeLabel(v); + int lbl = sqlite3VdbeMakeLabel(pParse); int tmpReg = sqlite3GetTempReg(pParse); if( nArg<3 ){ @@ -146163,8 +146677,8 @@ static void windowCodeRowExprStep( /* Allocate register and label for the "flush_partition" sub-routine. */ regFlushPart = ++pParse->nMem; - lblFlushPart = sqlite3VdbeMakeLabel(v); - lblFlushDone = sqlite3VdbeMakeLabel(v); + lblFlushPart = sqlite3VdbeMakeLabel(pParse); + lblFlushDone = sqlite3VdbeMakeLabel(pParse); regStart = ++pParse->nMem; regEnd = ++pParse->nMem; @@ -146274,7 +146788,7 @@ static void windowCodeRowExprStep( || pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_FOLLOWING ){ - int lblSkipInverse = sqlite3VdbeMakeLabel(v);; + int lblSkipInverse = sqlite3VdbeMakeLabel(pParse);; if( pMWin->eStart==TK_PRECEDING ){ sqlite3VdbeAddOp3(v, OP_IfPos, regStart, lblSkipInverse, 1); VdbeCoverage(v); @@ -146439,13 +146953,13 @@ static void windowCodeCacheStep( || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED) ); - lblEmpty = sqlite3VdbeMakeLabel(v); + lblEmpty = sqlite3VdbeMakeLabel(pParse); regNewPeer = pParse->nMem+1; pParse->nMem += nPeer; /* Allocate register and label for the "flush_partition" sub-routine. */ regFlushPart = ++pParse->nMem; - lblFlushPart = sqlite3VdbeMakeLabel(v); + lblFlushPart = sqlite3VdbeMakeLabel(pParse); csrLead = pParse->nTab++; regCtr = ++pParse->nMem; @@ -146682,6 +147196,7 @@ SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){ if( pNew ){ pNew->zName = sqlite3DbStrDup(db, p->zName); pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0); + pNew->pFunc = p->pFunc; pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0); pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0); pNew->eType = p->eType; @@ -146939,8 +147454,7 @@ static void disableLookaside(Parse *pParse){ memcpy(p->u.zToken, t.z, t.n); p->u.zToken[t.n] = 0; if( sqlite3Isquote(p->u.zToken[0]) ){ - if( p->u.zToken[0]=='"' ) p->flags |= EP_DblQuoted; - sqlite3Dequote(p->u.zToken); + sqlite3DequoteExpr(p); } #if SQLITE_MAX_EXPR_DEPTH>0 p->nHeight = 1; @@ -147049,27 +147563,27 @@ static void disableLookaside(Parse *pParse){ #endif /************* Begin control #defines *****************************************/ #define YYCODETYPE unsigned short int -#define YYNOCODE 277 +#define YYNOCODE 278 #define YYACTIONTYPE unsigned short int #define YYWILDCARD 91 #define sqlite3ParserTOKENTYPE Token typedef union { int yyinit; sqlite3ParserTOKENTYPE yy0; - Expr* yy18; - struct TrigEvent yy34; - IdList* yy48; - int yy70; - struct {int value; int mask;} yy111; - struct FrameBound yy119; - SrcList* yy135; - TriggerStep* yy207; - Window* yy327; - Upsert* yy340; - const char* yy392; - ExprList* yy420; - With* yy449; - Select* yy489; + ExprList* yy42; + int yy96; + TriggerStep* yy119; + Window* yy147; + SrcList* yy167; + Upsert* yy266; + struct FrameBound yy317; + IdList* yy336; + struct TrigEvent yy350; + struct {int value; int mask;} yy367; + Select* yy423; + const char* yy464; + Expr* yy490; + With* yy499; } YYMINORTYPE; #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 @@ -147085,17 +147599,17 @@ typedef union { #define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse; #define sqlite3ParserCTX_STORE yypParser->pParse=pParse; #define YYFALLBACK 1 -#define YYNSTATE 521 -#define YYNRULE 367 +#define YYNSTATE 524 +#define YYNRULE 369 #define YYNTOKEN 155 -#define YY_MAX_SHIFT 520 -#define YY_MIN_SHIFTREDUCE 756 -#define YY_MAX_SHIFTREDUCE 1122 -#define YY_ERROR_ACTION 1123 -#define YY_ACCEPT_ACTION 1124 -#define YY_NO_ACTION 1125 -#define YY_MIN_REDUCE 1126 -#define YY_MAX_REDUCE 1492 +#define YY_MAX_SHIFT 523 +#define YY_MIN_SHIFTREDUCE 760 +#define YY_MAX_SHIFTREDUCE 1128 +#define YY_ERROR_ACTION 1129 +#define YY_ACCEPT_ACTION 1130 +#define YY_NO_ACTION 1131 +#define YY_MIN_REDUCE 1132 +#define YY_MAX_REDUCE 1500 /************* End control #defines *******************************************/ #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) @@ -147164,566 +147678,567 @@ typedef union { *********** Begin parsing tables **********************************************/ #define YY_ACTTAB_COUNT (2009) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 368, 105, 102, 197, 105, 102, 197, 515, 1124, 1, - /* 10 */ 1, 520, 2, 1128, 515, 1192, 1171, 1456, 275, 370, - /* 20 */ 127, 1389, 1197, 1197, 1192, 1166, 178, 1205, 64, 64, - /* 30 */ 477, 887, 322, 428, 348, 37, 37, 808, 362, 888, - /* 40 */ 509, 509, 509, 112, 113, 103, 1100, 1100, 953, 956, - /* 50 */ 946, 946, 110, 110, 111, 111, 111, 111, 365, 252, - /* 60 */ 252, 515, 252, 252, 497, 515, 309, 515, 459, 515, - /* 70 */ 1079, 491, 512, 478, 6, 512, 809, 134, 498, 228, - /* 80 */ 194, 428, 37, 37, 515, 208, 64, 64, 64, 64, - /* 90 */ 13, 13, 109, 109, 109, 109, 108, 108, 107, 107, - /* 100 */ 107, 106, 401, 258, 381, 13, 13, 398, 397, 428, - /* 110 */ 252, 252, 370, 476, 405, 1104, 1079, 1080, 1081, 386, - /* 120 */ 1106, 390, 497, 512, 497, 1423, 1419, 304, 1105, 307, - /* 130 */ 1256, 496, 370, 499, 16, 16, 112, 113, 103, 1100, - /* 140 */ 1100, 953, 956, 946, 946, 110, 110, 111, 111, 111, - /* 150 */ 111, 262, 1107, 495, 1107, 401, 112, 113, 103, 1100, - /* 160 */ 1100, 953, 956, 946, 946, 110, 110, 111, 111, 111, - /* 170 */ 111, 129, 1425, 343, 1420, 339, 1059, 492, 1057, 263, - /* 180 */ 73, 105, 102, 197, 994, 109, 109, 109, 109, 108, - /* 190 */ 108, 107, 107, 107, 106, 401, 370, 111, 111, 111, - /* 200 */ 111, 104, 492, 89, 1432, 109, 109, 109, 109, 108, - /* 210 */ 108, 107, 107, 107, 106, 401, 111, 111, 111, 111, - /* 220 */ 112, 113, 103, 1100, 1100, 953, 956, 946, 946, 110, - /* 230 */ 110, 111, 111, 111, 111, 109, 109, 109, 109, 108, - /* 240 */ 108, 107, 107, 107, 106, 401, 114, 108, 108, 107, - /* 250 */ 107, 107, 106, 401, 109, 109, 109, 109, 108, 108, - /* 260 */ 107, 107, 107, 106, 401, 152, 399, 399, 399, 109, - /* 270 */ 109, 109, 109, 108, 108, 107, 107, 107, 106, 401, - /* 280 */ 178, 493, 1412, 434, 1037, 1486, 1079, 515, 1486, 370, - /* 290 */ 421, 297, 357, 412, 74, 1079, 109, 109, 109, 109, - /* 300 */ 108, 108, 107, 107, 107, 106, 401, 1413, 37, 37, - /* 310 */ 1431, 274, 506, 112, 113, 103, 1100, 1100, 953, 956, - /* 320 */ 946, 946, 110, 110, 111, 111, 111, 111, 1436, 520, - /* 330 */ 2, 1128, 1079, 1080, 1081, 430, 275, 1079, 127, 366, - /* 340 */ 933, 1079, 1080, 1081, 220, 1205, 913, 458, 455, 454, - /* 350 */ 392, 167, 515, 1035, 152, 445, 924, 453, 152, 874, - /* 360 */ 923, 289, 109, 109, 109, 109, 108, 108, 107, 107, - /* 370 */ 107, 106, 401, 13, 13, 261, 853, 252, 252, 227, - /* 380 */ 106, 401, 370, 1079, 1080, 1081, 311, 388, 1079, 296, - /* 390 */ 512, 923, 923, 925, 231, 323, 1255, 1388, 1423, 490, - /* 400 */ 274, 506, 12, 208, 274, 506, 112, 113, 103, 1100, - /* 410 */ 1100, 953, 956, 946, 946, 110, 110, 111, 111, 111, - /* 420 */ 111, 1440, 286, 1128, 288, 1079, 1097, 247, 275, 1098, - /* 430 */ 127, 387, 405, 389, 1079, 1080, 1081, 1205, 159, 238, - /* 440 */ 255, 321, 461, 316, 460, 225, 790, 105, 102, 197, - /* 450 */ 513, 314, 842, 842, 445, 109, 109, 109, 109, 108, - /* 460 */ 108, 107, 107, 107, 106, 401, 515, 514, 515, 252, - /* 470 */ 252, 1079, 1080, 1081, 435, 370, 1098, 933, 1460, 794, - /* 480 */ 274, 506, 512, 105, 102, 197, 336, 63, 63, 64, - /* 490 */ 64, 27, 790, 924, 287, 208, 1354, 923, 515, 112, - /* 500 */ 113, 103, 1100, 1100, 953, 956, 946, 946, 110, 110, - /* 510 */ 111, 111, 111, 111, 107, 107, 107, 106, 401, 49, - /* 520 */ 49, 515, 28, 1079, 405, 497, 421, 297, 923, 923, - /* 530 */ 925, 186, 468, 1079, 467, 999, 999, 442, 515, 1079, - /* 540 */ 334, 515, 45, 45, 1083, 342, 173, 168, 109, 109, - /* 550 */ 109, 109, 108, 108, 107, 107, 107, 106, 401, 13, - /* 560 */ 13, 205, 13, 13, 252, 252, 1195, 1195, 370, 1079, - /* 570 */ 1080, 1081, 787, 265, 5, 359, 494, 512, 469, 1079, - /* 580 */ 1080, 1081, 398, 397, 1079, 1079, 1080, 1081, 3, 282, - /* 590 */ 1079, 1083, 112, 113, 103, 1100, 1100, 953, 956, 946, - /* 600 */ 946, 110, 110, 111, 111, 111, 111, 252, 252, 1015, - /* 610 */ 220, 1079, 873, 458, 455, 454, 943, 943, 954, 957, - /* 620 */ 512, 252, 252, 453, 1016, 1079, 445, 1107, 1209, 1107, - /* 630 */ 1079, 1080, 1081, 515, 512, 426, 1079, 1080, 1081, 1017, - /* 640 */ 512, 109, 109, 109, 109, 108, 108, 107, 107, 107, - /* 650 */ 106, 401, 1052, 515, 50, 50, 515, 1079, 1080, 1081, - /* 660 */ 828, 370, 1051, 379, 411, 1064, 1358, 207, 408, 773, - /* 670 */ 829, 1079, 1080, 1081, 64, 64, 322, 64, 64, 1302, - /* 680 */ 947, 411, 410, 1358, 1360, 112, 113, 103, 1100, 1100, - /* 690 */ 953, 956, 946, 946, 110, 110, 111, 111, 111, 111, - /* 700 */ 294, 482, 515, 1037, 1487, 515, 434, 1487, 354, 1120, - /* 710 */ 483, 996, 913, 485, 466, 996, 132, 178, 33, 450, - /* 720 */ 1203, 136, 406, 64, 64, 479, 64, 64, 419, 369, - /* 730 */ 283, 1146, 252, 252, 109, 109, 109, 109, 108, 108, - /* 740 */ 107, 107, 107, 106, 401, 512, 224, 440, 411, 266, - /* 750 */ 1358, 266, 252, 252, 370, 296, 416, 284, 934, 396, - /* 760 */ 976, 470, 400, 252, 252, 512, 9, 473, 231, 500, - /* 770 */ 354, 1036, 1035, 1488, 355, 374, 512, 1121, 112, 113, - /* 780 */ 103, 1100, 1100, 953, 956, 946, 946, 110, 110, 111, - /* 790 */ 111, 111, 111, 252, 252, 1015, 515, 1347, 295, 252, - /* 800 */ 252, 252, 252, 1098, 375, 249, 512, 445, 872, 322, - /* 810 */ 1016, 480, 512, 195, 512, 434, 273, 15, 15, 515, - /* 820 */ 314, 515, 95, 515, 93, 1017, 367, 109, 109, 109, - /* 830 */ 109, 108, 108, 107, 107, 107, 106, 401, 515, 1121, - /* 840 */ 39, 39, 51, 51, 52, 52, 503, 370, 515, 1204, - /* 850 */ 1098, 918, 439, 341, 133, 436, 223, 222, 221, 53, - /* 860 */ 53, 322, 1400, 761, 762, 763, 515, 370, 88, 54, - /* 870 */ 54, 112, 113, 103, 1100, 1100, 953, 956, 946, 946, - /* 880 */ 110, 110, 111, 111, 111, 111, 407, 55, 55, 196, - /* 890 */ 515, 112, 113, 103, 1100, 1100, 953, 956, 946, 946, - /* 900 */ 110, 110, 111, 111, 111, 111, 135, 264, 1149, 376, - /* 910 */ 515, 40, 40, 515, 872, 515, 993, 515, 993, 116, - /* 920 */ 109, 109, 109, 109, 108, 108, 107, 107, 107, 106, - /* 930 */ 401, 41, 41, 515, 43, 43, 44, 44, 56, 56, - /* 940 */ 109, 109, 109, 109, 108, 108, 107, 107, 107, 106, - /* 950 */ 401, 515, 379, 515, 57, 57, 515, 799, 515, 379, - /* 960 */ 515, 445, 200, 515, 323, 515, 1397, 515, 1459, 515, - /* 970 */ 1287, 817, 58, 58, 14, 14, 515, 59, 59, 118, - /* 980 */ 118, 60, 60, 515, 46, 46, 61, 61, 62, 62, - /* 990 */ 47, 47, 515, 190, 189, 91, 515, 140, 140, 515, - /* 1000 */ 394, 515, 277, 1200, 141, 141, 515, 1115, 515, 992, - /* 1010 */ 515, 992, 515, 69, 69, 370, 278, 48, 48, 259, - /* 1020 */ 65, 65, 119, 119, 246, 246, 260, 66, 66, 120, - /* 1030 */ 120, 121, 121, 117, 117, 370, 515, 512, 383, 112, - /* 1040 */ 113, 103, 1100, 1100, 953, 956, 946, 946, 110, 110, - /* 1050 */ 111, 111, 111, 111, 515, 872, 515, 139, 139, 112, - /* 1060 */ 113, 103, 1100, 1100, 953, 956, 946, 946, 110, 110, - /* 1070 */ 111, 111, 111, 111, 1287, 138, 138, 125, 125, 515, - /* 1080 */ 12, 515, 281, 1287, 515, 445, 131, 1287, 109, 109, - /* 1090 */ 109, 109, 108, 108, 107, 107, 107, 106, 401, 515, - /* 1100 */ 124, 124, 122, 122, 515, 123, 123, 515, 109, 109, - /* 1110 */ 109, 109, 108, 108, 107, 107, 107, 106, 401, 515, - /* 1120 */ 68, 68, 463, 783, 515, 70, 70, 302, 67, 67, - /* 1130 */ 1032, 253, 253, 356, 1287, 191, 196, 1433, 465, 1301, - /* 1140 */ 38, 38, 384, 94, 512, 42, 42, 177, 848, 274, - /* 1150 */ 506, 385, 420, 847, 1356, 441, 508, 376, 377, 153, - /* 1160 */ 423, 872, 432, 370, 224, 251, 194, 887, 182, 293, - /* 1170 */ 783, 848, 88, 254, 466, 888, 847, 915, 807, 806, - /* 1180 */ 230, 1241, 910, 370, 17, 413, 797, 112, 113, 103, - /* 1190 */ 1100, 1100, 953, 956, 946, 946, 110, 110, 111, 111, - /* 1200 */ 111, 111, 395, 814, 815, 1175, 983, 112, 101, 103, - /* 1210 */ 1100, 1100, 953, 956, 946, 946, 110, 110, 111, 111, - /* 1220 */ 111, 111, 375, 422, 427, 429, 298, 230, 230, 88, - /* 1230 */ 1240, 451, 312, 797, 226, 88, 109, 109, 109, 109, - /* 1240 */ 108, 108, 107, 107, 107, 106, 401, 86, 433, 979, - /* 1250 */ 927, 881, 226, 983, 230, 415, 109, 109, 109, 109, - /* 1260 */ 108, 108, 107, 107, 107, 106, 401, 320, 845, 781, - /* 1270 */ 846, 100, 130, 100, 1403, 290, 370, 319, 1377, 1376, - /* 1280 */ 437, 1449, 299, 1237, 303, 306, 308, 310, 1188, 1174, - /* 1290 */ 1173, 1172, 315, 324, 325, 1228, 370, 927, 1249, 271, - /* 1300 */ 1286, 113, 103, 1100, 1100, 953, 956, 946, 946, 110, - /* 1310 */ 110, 111, 111, 111, 111, 1224, 1235, 502, 501, 1292, - /* 1320 */ 1221, 1155, 103, 1100, 1100, 953, 956, 946, 946, 110, - /* 1330 */ 110, 111, 111, 111, 111, 1148, 1137, 1136, 1138, 1443, - /* 1340 */ 446, 244, 184, 98, 507, 188, 4, 353, 327, 109, - /* 1350 */ 109, 109, 109, 108, 108, 107, 107, 107, 106, 401, - /* 1360 */ 510, 329, 331, 199, 414, 456, 292, 285, 318, 109, - /* 1370 */ 109, 109, 109, 108, 108, 107, 107, 107, 106, 401, - /* 1380 */ 11, 1271, 1279, 402, 361, 192, 1171, 1351, 431, 505, - /* 1390 */ 346, 1350, 333, 98, 507, 504, 4, 187, 1446, 1115, - /* 1400 */ 233, 1396, 155, 1394, 1112, 152, 72, 75, 378, 425, - /* 1410 */ 510, 165, 149, 157, 933, 1276, 86, 30, 1268, 417, - /* 1420 */ 96, 96, 8, 160, 161, 162, 163, 97, 418, 402, - /* 1430 */ 517, 516, 449, 402, 923, 210, 358, 424, 1282, 438, - /* 1440 */ 169, 214, 360, 1345, 80, 504, 31, 444, 1365, 301, - /* 1450 */ 245, 274, 506, 216, 174, 305, 488, 447, 217, 462, - /* 1460 */ 1139, 487, 218, 363, 933, 923, 923, 925, 926, 24, - /* 1470 */ 96, 96, 1191, 1190, 1189, 391, 1182, 97, 1163, 402, - /* 1480 */ 517, 516, 799, 364, 923, 1162, 317, 1161, 98, 507, - /* 1490 */ 1181, 4, 1458, 472, 393, 269, 270, 475, 481, 1232, - /* 1500 */ 85, 1233, 326, 328, 232, 510, 495, 1231, 330, 98, - /* 1510 */ 507, 1230, 4, 486, 335, 923, 923, 925, 926, 24, - /* 1520 */ 1435, 1068, 404, 181, 336, 256, 510, 115, 402, 332, - /* 1530 */ 352, 352, 351, 241, 349, 1214, 1414, 770, 338, 10, - /* 1540 */ 504, 340, 272, 92, 1331, 1213, 87, 183, 484, 402, - /* 1550 */ 201, 488, 280, 239, 344, 345, 489, 1145, 29, 933, - /* 1560 */ 279, 504, 1074, 518, 240, 96, 96, 242, 243, 519, - /* 1570 */ 1134, 1129, 97, 154, 402, 517, 516, 372, 373, 923, - /* 1580 */ 933, 142, 143, 128, 1381, 267, 96, 96, 852, 757, - /* 1590 */ 203, 144, 403, 97, 1382, 402, 517, 516, 204, 1380, - /* 1600 */ 923, 146, 1379, 1159, 1158, 71, 1156, 276, 202, 185, - /* 1610 */ 923, 923, 925, 926, 24, 198, 257, 126, 991, 989, - /* 1620 */ 907, 98, 507, 156, 4, 145, 158, 206, 831, 209, - /* 1630 */ 291, 923, 923, 925, 926, 24, 1005, 911, 510, 164, - /* 1640 */ 147, 380, 371, 382, 166, 76, 77, 274, 506, 148, - /* 1650 */ 78, 79, 1008, 211, 212, 1004, 137, 213, 18, 300, - /* 1660 */ 230, 402, 997, 1109, 443, 215, 32, 170, 171, 772, - /* 1670 */ 409, 448, 319, 504, 219, 172, 452, 81, 19, 457, - /* 1680 */ 313, 20, 82, 268, 488, 150, 810, 179, 83, 487, - /* 1690 */ 464, 151, 933, 180, 959, 84, 1040, 34, 96, 96, - /* 1700 */ 471, 1041, 35, 474, 193, 97, 248, 402, 517, 516, - /* 1710 */ 1068, 404, 923, 250, 256, 880, 229, 175, 875, 352, - /* 1720 */ 352, 351, 241, 349, 100, 21, 770, 22, 1054, 1056, - /* 1730 */ 7, 98, 507, 1045, 4, 337, 1058, 23, 974, 201, - /* 1740 */ 176, 280, 88, 923, 923, 925, 926, 24, 510, 279, - /* 1750 */ 960, 958, 962, 1014, 963, 1013, 235, 234, 25, 36, - /* 1760 */ 99, 90, 507, 928, 4, 511, 350, 782, 26, 841, - /* 1770 */ 236, 402, 347, 1069, 237, 1125, 1125, 1451, 510, 203, - /* 1780 */ 1450, 1125, 1125, 504, 1125, 1125, 1125, 204, 1125, 1125, - /* 1790 */ 146, 1125, 1125, 1125, 1125, 1125, 1125, 202, 1125, 1125, - /* 1800 */ 1125, 402, 933, 1125, 1125, 1125, 1125, 1125, 96, 96, - /* 1810 */ 1125, 1125, 1125, 504, 1125, 97, 1125, 402, 517, 516, - /* 1820 */ 1125, 1125, 923, 1125, 1125, 1125, 1125, 1125, 1125, 1125, - /* 1830 */ 1125, 371, 933, 1125, 1125, 1125, 274, 506, 96, 96, - /* 1840 */ 1125, 1125, 1125, 1125, 1125, 97, 1125, 402, 517, 516, - /* 1850 */ 1125, 1125, 923, 923, 923, 925, 926, 24, 1125, 409, - /* 1860 */ 1125, 1125, 1125, 256, 1125, 1125, 1125, 1125, 352, 352, - /* 1870 */ 351, 241, 349, 1125, 1125, 770, 1125, 1125, 1125, 1125, - /* 1880 */ 1125, 1125, 1125, 923, 923, 925, 926, 24, 201, 1125, - /* 1890 */ 280, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 279, 1125, - /* 1900 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, - /* 1910 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, - /* 1920 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 203, 1125, - /* 1930 */ 1125, 1125, 1125, 1125, 1125, 1125, 204, 1125, 1125, 146, - /* 1940 */ 1125, 1125, 1125, 1125, 1125, 1125, 202, 1125, 1125, 1125, - /* 1950 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, - /* 1960 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, - /* 1970 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, - /* 1980 */ 371, 1125, 1125, 1125, 1125, 274, 506, 1125, 1125, 1125, - /* 1990 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, - /* 2000 */ 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 409, + /* 0 */ 377, 518, 371, 107, 104, 200, 1293, 518, 1130, 1, + /* 10 */ 1, 523, 2, 1134, 518, 1203, 1203, 1262, 277, 373, + /* 20 */ 129, 495, 37, 37, 1397, 1201, 1201, 1211, 65, 65, + /* 30 */ 480, 891, 107, 104, 200, 37, 37, 1043, 1494, 892, + /* 40 */ 346, 1494, 342, 114, 115, 105, 1106, 1106, 957, 960, + /* 50 */ 950, 950, 112, 112, 113, 113, 113, 113, 285, 254, + /* 60 */ 254, 518, 254, 254, 500, 518, 495, 518, 107, 104, + /* 70 */ 200, 1085, 515, 481, 386, 515, 1464, 442, 501, 230, + /* 80 */ 197, 439, 37, 37, 1172, 210, 65, 65, 65, 65, + /* 90 */ 254, 254, 111, 111, 111, 111, 110, 110, 109, 109, + /* 100 */ 109, 108, 404, 515, 404, 155, 1041, 431, 401, 400, + /* 110 */ 254, 254, 373, 1431, 1427, 408, 1110, 1085, 1086, 1087, + /* 120 */ 284, 1112, 500, 515, 500, 368, 1433, 1421, 1428, 1111, + /* 130 */ 1261, 499, 373, 502, 108, 404, 114, 115, 105, 1106, + /* 140 */ 1106, 957, 960, 950, 950, 112, 112, 113, 113, 113, + /* 150 */ 113, 276, 509, 1113, 369, 1113, 114, 115, 105, 1106, + /* 160 */ 1106, 957, 960, 950, 950, 112, 112, 113, 113, 113, + /* 170 */ 113, 496, 1420, 1431, 493, 1468, 1065, 260, 1063, 433, + /* 180 */ 74, 107, 104, 200, 498, 111, 111, 111, 111, 110, + /* 190 */ 110, 109, 109, 109, 108, 404, 373, 113, 113, 113, + /* 200 */ 113, 106, 131, 91, 1361, 111, 111, 111, 111, 110, + /* 210 */ 110, 109, 109, 109, 108, 404, 113, 113, 113, 113, + /* 220 */ 114, 115, 105, 1106, 1106, 957, 960, 950, 950, 112, + /* 230 */ 112, 113, 113, 113, 113, 111, 111, 111, 111, 110, + /* 240 */ 110, 109, 109, 109, 108, 404, 116, 110, 110, 109, + /* 250 */ 109, 109, 108, 404, 111, 111, 111, 111, 110, 110, + /* 260 */ 109, 109, 109, 108, 404, 917, 512, 512, 512, 111, + /* 270 */ 111, 111, 111, 110, 110, 109, 109, 109, 108, 404, + /* 280 */ 517, 1198, 1177, 181, 109, 109, 109, 108, 404, 373, + /* 290 */ 1198, 402, 402, 402, 75, 360, 111, 111, 111, 111, + /* 300 */ 110, 110, 109, 109, 109, 108, 404, 382, 299, 419, + /* 310 */ 287, 170, 518, 114, 115, 105, 1106, 1106, 957, 960, + /* 320 */ 950, 950, 112, 112, 113, 113, 113, 113, 1444, 523, + /* 330 */ 2, 1134, 518, 13, 13, 337, 277, 1085, 129, 226, + /* 340 */ 937, 1058, 1000, 471, 917, 1211, 453, 384, 1085, 395, + /* 350 */ 162, 1057, 155, 45, 45, 416, 928, 401, 400, 479, + /* 360 */ 927, 12, 111, 111, 111, 111, 110, 110, 109, 109, + /* 370 */ 109, 108, 404, 226, 286, 254, 254, 254, 254, 518, + /* 380 */ 16, 16, 373, 1085, 1086, 1087, 314, 299, 515, 472, + /* 390 */ 515, 927, 927, 929, 1085, 1086, 1087, 378, 276, 509, + /* 400 */ 65, 65, 1113, 210, 1113, 1085, 114, 115, 105, 1106, + /* 410 */ 1106, 957, 960, 950, 950, 112, 112, 113, 113, 113, + /* 420 */ 113, 1448, 222, 1134, 1089, 461, 458, 457, 277, 180, + /* 430 */ 129, 378, 392, 408, 423, 456, 500, 1211, 240, 257, + /* 440 */ 324, 464, 319, 463, 227, 470, 12, 317, 424, 300, + /* 450 */ 317, 1085, 1086, 1087, 485, 111, 111, 111, 111, 110, + /* 460 */ 110, 109, 109, 109, 108, 404, 181, 118, 1085, 254, + /* 470 */ 254, 1089, 518, 90, 351, 373, 518, 1181, 365, 798, + /* 480 */ 1440, 339, 515, 248, 248, 77, 325, 133, 1085, 249, + /* 490 */ 424, 300, 794, 49, 49, 210, 515, 65, 65, 114, + /* 500 */ 115, 105, 1106, 1106, 957, 960, 950, 950, 112, 112, + /* 510 */ 113, 113, 113, 113, 1085, 1086, 1087, 222, 1085, 438, + /* 520 */ 461, 458, 457, 937, 787, 408, 171, 857, 362, 1021, + /* 530 */ 456, 136, 198, 486, 1085, 1086, 1087, 448, 794, 928, + /* 540 */ 5, 193, 192, 927, 1022, 107, 104, 200, 111, 111, + /* 550 */ 111, 111, 110, 110, 109, 109, 109, 108, 404, 1023, + /* 560 */ 254, 254, 803, 1085, 1085, 1086, 1087, 437, 373, 1085, + /* 570 */ 344, 787, 791, 515, 927, 927, 929, 1085, 1408, 1396, + /* 580 */ 832, 1085, 176, 3, 852, 1085, 518, 1439, 429, 851, + /* 590 */ 833, 518, 114, 115, 105, 1106, 1106, 957, 960, 950, + /* 600 */ 950, 112, 112, 113, 113, 113, 113, 13, 13, 1085, + /* 610 */ 1086, 1087, 13, 13, 518, 1085, 1086, 1087, 1496, 358, + /* 620 */ 1085, 389, 1234, 1085, 1086, 1087, 391, 1085, 1086, 1087, + /* 630 */ 448, 1085, 1086, 1087, 518, 65, 65, 947, 947, 958, + /* 640 */ 961, 111, 111, 111, 111, 110, 110, 109, 109, 109, + /* 650 */ 108, 404, 518, 382, 878, 13, 13, 518, 877, 518, + /* 660 */ 263, 373, 518, 431, 448, 1070, 1085, 1086, 1087, 267, + /* 670 */ 448, 488, 1360, 64, 64, 431, 812, 155, 50, 50, + /* 680 */ 65, 65, 518, 65, 65, 114, 115, 105, 1106, 1106, + /* 690 */ 957, 960, 950, 950, 112, 112, 113, 113, 113, 113, + /* 700 */ 518, 951, 382, 13, 13, 415, 411, 462, 414, 1085, + /* 710 */ 1366, 777, 1210, 292, 297, 813, 399, 497, 181, 403, + /* 720 */ 261, 15, 15, 276, 509, 414, 413, 1366, 1368, 410, + /* 730 */ 372, 345, 1209, 264, 111, 111, 111, 111, 110, 110, + /* 740 */ 109, 109, 109, 108, 404, 265, 254, 254, 229, 1405, + /* 750 */ 268, 1215, 268, 1103, 373, 1085, 1086, 1087, 938, 515, + /* 760 */ 393, 409, 876, 515, 254, 254, 1152, 482, 473, 262, + /* 770 */ 422, 476, 325, 503, 289, 518, 291, 515, 114, 115, + /* 780 */ 105, 1106, 1106, 957, 960, 950, 950, 112, 112, 113, + /* 790 */ 113, 113, 113, 414, 1021, 1366, 39, 39, 254, 254, + /* 800 */ 254, 254, 980, 254, 254, 254, 254, 255, 255, 1022, + /* 810 */ 279, 515, 516, 515, 846, 846, 515, 138, 515, 518, + /* 820 */ 515, 1043, 1495, 251, 1023, 1495, 876, 111, 111, 111, + /* 830 */ 111, 110, 110, 109, 109, 109, 108, 404, 518, 1353, + /* 840 */ 51, 51, 518, 199, 518, 506, 290, 373, 518, 276, + /* 850 */ 509, 922, 9, 483, 233, 1005, 1005, 445, 189, 52, + /* 860 */ 52, 325, 280, 53, 53, 54, 54, 373, 876, 55, + /* 870 */ 55, 114, 115, 105, 1106, 1106, 957, 960, 950, 950, + /* 880 */ 112, 112, 113, 113, 113, 113, 97, 518, 95, 1104, + /* 890 */ 1041, 114, 115, 105, 1106, 1106, 957, 960, 950, 950, + /* 900 */ 112, 112, 113, 113, 113, 113, 135, 199, 56, 56, + /* 910 */ 765, 766, 767, 225, 224, 223, 518, 283, 437, 233, + /* 920 */ 111, 111, 111, 111, 110, 110, 109, 109, 109, 108, + /* 930 */ 404, 1002, 876, 326, 518, 1002, 1104, 40, 40, 518, + /* 940 */ 111, 111, 111, 111, 110, 110, 109, 109, 109, 108, + /* 950 */ 404, 518, 448, 518, 1104, 41, 41, 518, 17, 518, + /* 960 */ 43, 43, 1155, 379, 518, 448, 518, 443, 518, 390, + /* 970 */ 518, 194, 44, 44, 57, 57, 1247, 518, 58, 58, + /* 980 */ 59, 59, 518, 466, 326, 14, 14, 60, 60, 120, + /* 990 */ 120, 61, 61, 449, 1206, 93, 518, 425, 46, 46, + /* 1000 */ 518, 1104, 518, 62, 62, 518, 437, 305, 518, 852, + /* 1010 */ 518, 298, 518, 1246, 851, 373, 518, 63, 63, 1293, + /* 1020 */ 397, 47, 47, 142, 142, 1467, 143, 143, 821, 70, + /* 1030 */ 70, 48, 48, 66, 66, 373, 518, 121, 121, 114, + /* 1040 */ 115, 105, 1106, 1106, 957, 960, 950, 950, 112, 112, + /* 1050 */ 113, 113, 113, 113, 518, 418, 518, 67, 67, 114, + /* 1060 */ 115, 105, 1106, 1106, 957, 960, 950, 950, 112, 112, + /* 1070 */ 113, 113, 113, 113, 312, 122, 122, 123, 123, 1293, + /* 1080 */ 518, 357, 1126, 88, 518, 435, 325, 387, 111, 111, + /* 1090 */ 111, 111, 110, 110, 109, 109, 109, 108, 404, 266, + /* 1100 */ 518, 119, 119, 518, 1293, 141, 141, 518, 111, 111, + /* 1110 */ 111, 111, 110, 110, 109, 109, 109, 108, 404, 518, + /* 1120 */ 801, 140, 140, 518, 127, 127, 511, 379, 126, 126, + /* 1130 */ 518, 137, 518, 1308, 518, 307, 518, 310, 518, 203, + /* 1140 */ 124, 124, 1307, 96, 125, 125, 207, 388, 1441, 468, + /* 1150 */ 1127, 69, 69, 71, 71, 68, 68, 38, 38, 42, + /* 1160 */ 42, 357, 1042, 373, 1293, 276, 509, 801, 185, 469, + /* 1170 */ 494, 436, 444, 6, 380, 156, 253, 197, 469, 134, + /* 1180 */ 426, 33, 1038, 373, 1121, 359, 1411, 114, 115, 105, + /* 1190 */ 1106, 1106, 957, 960, 950, 950, 112, 112, 113, 113, + /* 1200 */ 113, 113, 914, 296, 27, 293, 90, 114, 103, 105, + /* 1210 */ 1106, 1106, 957, 960, 950, 950, 112, 112, 113, 113, + /* 1220 */ 113, 113, 919, 275, 430, 232, 891, 232, 432, 256, + /* 1230 */ 1127, 232, 398, 370, 892, 28, 111, 111, 111, 111, + /* 1240 */ 110, 110, 109, 109, 109, 108, 404, 301, 454, 1385, + /* 1250 */ 90, 228, 209, 987, 811, 810, 111, 111, 111, 111, + /* 1260 */ 110, 110, 109, 109, 109, 108, 404, 315, 818, 819, + /* 1270 */ 90, 323, 983, 931, 885, 228, 373, 232, 999, 849, + /* 1280 */ 999, 322, 102, 998, 1384, 998, 785, 850, 440, 132, + /* 1290 */ 102, 302, 1243, 306, 309, 311, 373, 313, 1194, 1180, + /* 1300 */ 987, 115, 105, 1106, 1106, 957, 960, 950, 950, 112, + /* 1310 */ 112, 113, 113, 113, 113, 1178, 1179, 318, 327, 328, + /* 1320 */ 931, 1255, 105, 1106, 1106, 957, 960, 950, 950, 112, + /* 1330 */ 112, 113, 113, 113, 113, 1292, 1230, 1457, 273, 1241, + /* 1340 */ 504, 505, 1298, 100, 510, 246, 4, 1161, 1154, 111, + /* 1350 */ 111, 111, 111, 110, 110, 109, 109, 109, 108, 404, + /* 1360 */ 513, 1143, 187, 1142, 202, 1144, 1451, 356, 1227, 111, + /* 1370 */ 111, 111, 111, 110, 110, 109, 109, 109, 108, 404, + /* 1380 */ 11, 1277, 330, 405, 332, 334, 191, 1285, 364, 195, + /* 1390 */ 295, 417, 288, 100, 510, 507, 4, 434, 459, 321, + /* 1400 */ 1177, 349, 1357, 1356, 336, 155, 190, 1454, 1121, 158, + /* 1410 */ 513, 508, 235, 1404, 937, 1402, 1118, 381, 77, 428, + /* 1420 */ 98, 98, 8, 1282, 168, 30, 152, 99, 160, 405, + /* 1430 */ 520, 519, 88, 405, 927, 1362, 1274, 420, 163, 73, + /* 1440 */ 164, 76, 165, 166, 421, 507, 452, 212, 361, 363, + /* 1450 */ 427, 276, 509, 31, 1288, 172, 491, 441, 216, 1351, + /* 1460 */ 82, 490, 447, 1373, 937, 927, 927, 929, 930, 24, + /* 1470 */ 98, 98, 304, 247, 218, 177, 308, 99, 219, 405, + /* 1480 */ 520, 519, 450, 1145, 927, 220, 366, 1197, 100, 510, + /* 1490 */ 465, 4, 1188, 1196, 1195, 394, 803, 1169, 1187, 367, + /* 1500 */ 1168, 396, 484, 320, 1167, 513, 1466, 87, 475, 100, + /* 1510 */ 510, 271, 4, 272, 478, 927, 927, 929, 930, 24, + /* 1520 */ 1443, 1074, 407, 1238, 1239, 258, 513, 329, 405, 331, + /* 1530 */ 355, 355, 354, 243, 352, 234, 489, 774, 498, 184, + /* 1540 */ 507, 338, 1422, 339, 117, 1220, 10, 341, 333, 405, + /* 1550 */ 204, 491, 282, 1219, 1237, 1236, 492, 335, 343, 937, + /* 1560 */ 281, 507, 94, 1337, 186, 98, 98, 347, 89, 487, + /* 1570 */ 348, 241, 99, 29, 405, 520, 519, 274, 1151, 927, + /* 1580 */ 937, 521, 1080, 245, 242, 244, 98, 98, 856, 522, + /* 1590 */ 206, 1140, 1135, 99, 144, 405, 520, 519, 147, 375, + /* 1600 */ 927, 149, 376, 157, 1389, 1390, 1388, 1387, 205, 145, + /* 1610 */ 927, 927, 929, 930, 24, 146, 130, 761, 1165, 1164, + /* 1620 */ 72, 100, 510, 1162, 4, 269, 406, 188, 278, 201, + /* 1630 */ 259, 927, 927, 929, 930, 24, 128, 911, 513, 997, + /* 1640 */ 995, 159, 374, 208, 148, 161, 835, 276, 509, 211, + /* 1650 */ 294, 1011, 915, 167, 150, 383, 169, 78, 385, 79, + /* 1660 */ 80, 405, 81, 151, 1014, 213, 214, 1010, 139, 18, + /* 1670 */ 412, 215, 303, 507, 232, 1115, 1003, 446, 173, 217, + /* 1680 */ 174, 32, 776, 451, 491, 322, 221, 175, 814, 490, + /* 1690 */ 83, 455, 937, 19, 460, 316, 20, 84, 98, 98, + /* 1700 */ 270, 182, 85, 467, 153, 99, 154, 405, 520, 519, + /* 1710 */ 1074, 407, 927, 183, 258, 963, 1046, 86, 34, 355, + /* 1720 */ 355, 354, 243, 352, 474, 1047, 774, 35, 477, 196, + /* 1730 */ 250, 100, 510, 252, 4, 884, 178, 231, 1060, 204, + /* 1740 */ 21, 282, 102, 927, 927, 929, 930, 24, 513, 281, + /* 1750 */ 879, 22, 1064, 1062, 1051, 7, 340, 23, 978, 179, + /* 1760 */ 90, 92, 510, 964, 4, 236, 962, 966, 1020, 1019, + /* 1770 */ 237, 405, 967, 25, 36, 514, 932, 786, 513, 206, + /* 1780 */ 101, 26, 845, 507, 238, 239, 1459, 147, 350, 1458, + /* 1790 */ 149, 353, 1075, 1131, 1131, 1131, 1131, 205, 1131, 1131, + /* 1800 */ 1131, 405, 937, 1131, 1131, 1131, 1131, 1131, 98, 98, + /* 1810 */ 1131, 1131, 1131, 507, 1131, 99, 1131, 405, 520, 519, + /* 1820 */ 1131, 1131, 927, 1131, 1131, 1131, 1131, 1131, 1131, 1131, + /* 1830 */ 1131, 374, 937, 1131, 1131, 1131, 276, 509, 98, 98, + /* 1840 */ 1131, 1131, 1131, 1131, 1131, 99, 1131, 405, 520, 519, + /* 1850 */ 1131, 1131, 927, 927, 927, 929, 930, 24, 1131, 412, + /* 1860 */ 1131, 1131, 1131, 258, 1131, 1131, 1131, 1131, 355, 355, + /* 1870 */ 354, 243, 352, 1131, 1131, 774, 1131, 1131, 1131, 1131, + /* 1880 */ 1131, 1131, 1131, 927, 927, 929, 930, 24, 204, 1131, + /* 1890 */ 282, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 281, 1131, + /* 1900 */ 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, + /* 1910 */ 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, + /* 1920 */ 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 206, 1131, + /* 1930 */ 1131, 1131, 1131, 1131, 1131, 1131, 147, 1131, 1131, 149, + /* 1940 */ 1131, 1131, 1131, 1131, 1131, 1131, 205, 1131, 1131, 1131, + /* 1950 */ 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, + /* 1960 */ 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, + /* 1970 */ 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, + /* 1980 */ 374, 1131, 1131, 1131, 1131, 276, 509, 1131, 1131, 1131, + /* 1990 */ 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, + /* 2000 */ 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 412, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 184, 238, 239, 240, 238, 239, 240, 163, 155, 156, - /* 10 */ 157, 158, 159, 160, 163, 191, 192, 183, 165, 19, - /* 20 */ 167, 258, 202, 203, 200, 191, 163, 174, 184, 185, - /* 30 */ 174, 31, 163, 163, 171, 184, 185, 35, 175, 39, - /* 40 */ 179, 180, 181, 43, 44, 45, 46, 47, 48, 49, - /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 184, 206, - /* 60 */ 207, 163, 206, 207, 220, 163, 16, 163, 66, 163, - /* 70 */ 59, 270, 219, 229, 273, 219, 74, 208, 174, 223, - /* 80 */ 224, 163, 184, 185, 163, 232, 184, 185, 184, 185, - /* 90 */ 184, 185, 92, 93, 94, 95, 96, 97, 98, 99, - /* 100 */ 100, 101, 102, 233, 198, 184, 185, 96, 97, 163, - /* 110 */ 206, 207, 19, 163, 261, 104, 105, 106, 107, 198, - /* 120 */ 109, 119, 220, 219, 220, 274, 275, 77, 117, 79, - /* 130 */ 187, 229, 19, 229, 184, 185, 43, 44, 45, 46, + /* 0 */ 168, 163, 184, 238, 239, 240, 163, 163, 155, 156, + /* 10 */ 157, 158, 159, 160, 163, 202, 203, 187, 165, 19, + /* 20 */ 167, 163, 184, 185, 259, 202, 203, 174, 184, 185, + /* 30 */ 174, 31, 238, 239, 240, 184, 185, 22, 23, 39, + /* 40 */ 216, 26, 218, 43, 44, 45, 46, 47, 48, 49, + /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 174, 206, + /* 60 */ 207, 163, 206, 207, 220, 163, 163, 163, 238, 239, + /* 70 */ 240, 59, 219, 229, 231, 219, 183, 245, 174, 223, + /* 80 */ 224, 249, 184, 185, 191, 232, 184, 185, 184, 185, + /* 90 */ 206, 207, 92, 93, 94, 95, 96, 97, 98, 99, + /* 100 */ 100, 101, 102, 219, 102, 81, 91, 163, 96, 97, + /* 110 */ 206, 207, 19, 275, 276, 262, 104, 105, 106, 107, + /* 120 */ 163, 109, 220, 219, 220, 184, 275, 269, 277, 117, + /* 130 */ 187, 229, 19, 229, 101, 102, 43, 44, 45, 46, /* 140 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 150 */ 57, 233, 141, 134, 143, 102, 43, 44, 45, 46, + /* 150 */ 57, 127, 128, 141, 184, 143, 43, 44, 45, 46, /* 160 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 170 */ 57, 152, 274, 216, 276, 218, 83, 163, 85, 233, - /* 180 */ 67, 238, 239, 240, 11, 92, 93, 94, 95, 96, + /* 170 */ 57, 268, 269, 275, 276, 197, 83, 233, 85, 163, + /* 180 */ 67, 238, 239, 240, 134, 92, 93, 94, 95, 96, /* 190 */ 97, 98, 99, 100, 101, 102, 19, 54, 55, 56, - /* 200 */ 57, 58, 163, 26, 163, 92, 93, 94, 95, 96, + /* 200 */ 57, 58, 152, 26, 247, 92, 93, 94, 95, 96, /* 210 */ 97, 98, 99, 100, 101, 102, 54, 55, 56, 57, /* 220 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, /* 230 */ 53, 54, 55, 56, 57, 92, 93, 94, 95, 96, /* 240 */ 97, 98, 99, 100, 101, 102, 69, 96, 97, 98, /* 250 */ 99, 100, 101, 102, 92, 93, 94, 95, 96, 97, - /* 260 */ 98, 99, 100, 101, 102, 81, 179, 180, 181, 92, + /* 260 */ 98, 99, 100, 101, 102, 73, 179, 180, 181, 92, /* 270 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, - /* 280 */ 163, 267, 268, 163, 22, 23, 59, 163, 26, 19, - /* 290 */ 117, 118, 175, 109, 24, 59, 92, 93, 94, 95, - /* 300 */ 96, 97, 98, 99, 100, 101, 102, 268, 184, 185, - /* 310 */ 269, 127, 128, 43, 44, 45, 46, 47, 48, 49, + /* 280 */ 163, 191, 192, 163, 98, 99, 100, 101, 102, 19, + /* 290 */ 200, 179, 180, 181, 24, 175, 92, 93, 94, 95, + /* 300 */ 96, 97, 98, 99, 100, 101, 102, 163, 116, 117, + /* 310 */ 118, 22, 163, 43, 44, 45, 46, 47, 48, 49, /* 320 */ 50, 51, 52, 53, 54, 55, 56, 57, 157, 158, - /* 330 */ 159, 160, 105, 106, 107, 163, 165, 59, 167, 184, - /* 340 */ 90, 105, 106, 107, 108, 174, 73, 111, 112, 113, - /* 350 */ 19, 22, 163, 91, 81, 163, 106, 121, 81, 132, - /* 360 */ 110, 16, 92, 93, 94, 95, 96, 97, 98, 99, - /* 370 */ 100, 101, 102, 184, 185, 255, 98, 206, 207, 26, - /* 380 */ 101, 102, 19, 105, 106, 107, 23, 198, 59, 116, - /* 390 */ 219, 141, 142, 143, 24, 163, 187, 205, 274, 275, - /* 400 */ 127, 128, 182, 232, 127, 128, 43, 44, 45, 46, + /* 330 */ 159, 160, 163, 184, 185, 163, 165, 59, 167, 46, + /* 340 */ 90, 76, 11, 174, 73, 174, 19, 198, 59, 19, + /* 350 */ 72, 86, 81, 184, 185, 234, 106, 96, 97, 163, + /* 360 */ 110, 182, 92, 93, 94, 95, 96, 97, 98, 99, + /* 370 */ 100, 101, 102, 46, 230, 206, 207, 206, 207, 163, + /* 380 */ 184, 185, 19, 105, 106, 107, 23, 116, 219, 220, + /* 390 */ 219, 141, 142, 143, 105, 106, 107, 104, 127, 128, + /* 400 */ 184, 185, 141, 232, 143, 59, 43, 44, 45, 46, /* 410 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 420 */ 57, 158, 77, 160, 79, 59, 26, 182, 165, 59, - /* 430 */ 167, 199, 261, 102, 105, 106, 107, 174, 72, 108, - /* 440 */ 109, 110, 111, 112, 113, 114, 59, 238, 239, 240, - /* 450 */ 123, 120, 125, 126, 163, 92, 93, 94, 95, 96, - /* 460 */ 97, 98, 99, 100, 101, 102, 163, 163, 163, 206, - /* 470 */ 207, 105, 106, 107, 254, 19, 106, 90, 197, 23, - /* 480 */ 127, 128, 219, 238, 239, 240, 22, 184, 185, 184, - /* 490 */ 185, 22, 105, 106, 149, 232, 205, 110, 163, 43, + /* 420 */ 57, 158, 108, 160, 59, 111, 112, 113, 165, 250, + /* 430 */ 167, 104, 102, 262, 255, 121, 220, 174, 108, 109, + /* 440 */ 110, 111, 112, 113, 114, 229, 182, 120, 117, 118, + /* 450 */ 120, 105, 106, 107, 163, 92, 93, 94, 95, 96, + /* 460 */ 97, 98, 99, 100, 101, 102, 163, 22, 59, 206, + /* 470 */ 207, 106, 163, 26, 171, 19, 163, 193, 175, 23, + /* 480 */ 163, 22, 219, 206, 207, 139, 163, 22, 59, 182, + /* 490 */ 117, 118, 59, 184, 185, 232, 219, 184, 185, 43, /* 500 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - /* 510 */ 54, 55, 56, 57, 98, 99, 100, 101, 102, 184, - /* 520 */ 185, 163, 53, 59, 261, 220, 117, 118, 141, 142, - /* 530 */ 143, 131, 174, 59, 229, 116, 117, 118, 163, 59, - /* 540 */ 163, 163, 184, 185, 59, 242, 72, 22, 92, 93, - /* 550 */ 94, 95, 96, 97, 98, 99, 100, 101, 102, 184, - /* 560 */ 185, 24, 184, 185, 206, 207, 202, 203, 19, 105, - /* 570 */ 106, 107, 23, 198, 22, 174, 198, 219, 220, 105, - /* 580 */ 106, 107, 96, 97, 59, 105, 106, 107, 22, 174, - /* 590 */ 59, 106, 43, 44, 45, 46, 47, 48, 49, 50, - /* 600 */ 51, 52, 53, 54, 55, 56, 57, 206, 207, 12, - /* 610 */ 108, 59, 132, 111, 112, 113, 46, 47, 48, 49, - /* 620 */ 219, 206, 207, 121, 27, 59, 163, 141, 207, 143, - /* 630 */ 105, 106, 107, 163, 219, 234, 105, 106, 107, 42, - /* 640 */ 219, 92, 93, 94, 95, 96, 97, 98, 99, 100, - /* 650 */ 101, 102, 76, 163, 184, 185, 163, 105, 106, 107, - /* 660 */ 63, 19, 86, 163, 163, 23, 163, 130, 205, 21, - /* 670 */ 73, 105, 106, 107, 184, 185, 163, 184, 185, 237, - /* 680 */ 110, 180, 181, 180, 181, 43, 44, 45, 46, 47, + /* 510 */ 54, 55, 56, 57, 105, 106, 107, 108, 59, 255, + /* 520 */ 111, 112, 113, 90, 59, 262, 22, 98, 174, 12, + /* 530 */ 121, 208, 163, 220, 105, 106, 107, 163, 105, 106, + /* 540 */ 22, 96, 97, 110, 27, 238, 239, 240, 92, 93, + /* 550 */ 94, 95, 96, 97, 98, 99, 100, 101, 102, 42, + /* 560 */ 206, 207, 115, 59, 105, 106, 107, 163, 19, 59, + /* 570 */ 163, 106, 23, 219, 141, 142, 143, 59, 163, 205, + /* 580 */ 63, 59, 72, 22, 124, 59, 163, 270, 234, 129, + /* 590 */ 73, 163, 43, 44, 45, 46, 47, 48, 49, 50, + /* 600 */ 51, 52, 53, 54, 55, 56, 57, 184, 185, 105, + /* 610 */ 106, 107, 184, 185, 163, 105, 106, 107, 265, 266, + /* 620 */ 59, 198, 225, 105, 106, 107, 198, 105, 106, 107, + /* 630 */ 163, 105, 106, 107, 163, 184, 185, 46, 47, 48, + /* 640 */ 49, 92, 93, 94, 95, 96, 97, 98, 99, 100, + /* 650 */ 101, 102, 163, 163, 132, 184, 185, 163, 132, 163, + /* 660 */ 256, 19, 163, 163, 163, 23, 105, 106, 107, 198, + /* 670 */ 163, 220, 205, 184, 185, 163, 35, 81, 184, 185, + /* 680 */ 184, 185, 163, 184, 185, 43, 44, 45, 46, 47, /* 690 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 700 */ 174, 163, 163, 22, 23, 163, 163, 26, 22, 23, - /* 710 */ 220, 29, 73, 220, 272, 33, 22, 163, 24, 19, - /* 720 */ 174, 208, 259, 184, 185, 19, 184, 185, 80, 175, - /* 730 */ 230, 174, 206, 207, 92, 93, 94, 95, 96, 97, - /* 740 */ 98, 99, 100, 101, 102, 219, 46, 65, 247, 195, - /* 750 */ 247, 197, 206, 207, 19, 116, 117, 118, 23, 220, - /* 760 */ 112, 174, 220, 206, 207, 219, 22, 174, 24, 174, - /* 770 */ 22, 23, 91, 264, 265, 168, 219, 91, 43, 44, + /* 700 */ 163, 110, 163, 184, 185, 109, 205, 66, 163, 59, + /* 710 */ 163, 21, 205, 16, 174, 74, 220, 198, 163, 220, + /* 720 */ 230, 184, 185, 127, 128, 180, 181, 180, 181, 163, + /* 730 */ 175, 242, 174, 233, 92, 93, 94, 95, 96, 97, + /* 740 */ 98, 99, 100, 101, 102, 233, 206, 207, 26, 163, + /* 750 */ 195, 207, 197, 26, 19, 105, 106, 107, 23, 219, + /* 760 */ 119, 260, 26, 219, 206, 207, 174, 19, 174, 230, + /* 770 */ 80, 174, 163, 174, 77, 163, 79, 219, 43, 44, /* 780 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - /* 790 */ 55, 56, 57, 206, 207, 12, 163, 149, 255, 206, - /* 800 */ 207, 206, 207, 59, 104, 23, 219, 163, 26, 163, - /* 810 */ 27, 105, 219, 163, 219, 163, 211, 184, 185, 163, - /* 820 */ 120, 163, 146, 163, 148, 42, 221, 92, 93, 94, - /* 830 */ 95, 96, 97, 98, 99, 100, 101, 102, 163, 91, - /* 840 */ 184, 185, 184, 185, 184, 185, 63, 19, 163, 205, - /* 850 */ 106, 23, 245, 163, 208, 248, 116, 117, 118, 184, - /* 860 */ 185, 163, 163, 7, 8, 9, 163, 19, 26, 184, + /* 790 */ 55, 56, 57, 248, 12, 248, 184, 185, 206, 207, + /* 800 */ 206, 207, 112, 206, 207, 206, 207, 206, 207, 27, + /* 810 */ 163, 219, 123, 219, 125, 126, 219, 208, 219, 163, + /* 820 */ 219, 22, 23, 23, 42, 26, 26, 92, 93, 94, + /* 830 */ 95, 96, 97, 98, 99, 100, 101, 102, 163, 149, + /* 840 */ 184, 185, 163, 107, 163, 63, 149, 19, 163, 127, + /* 850 */ 128, 23, 22, 105, 24, 116, 117, 118, 131, 184, + /* 860 */ 185, 163, 163, 184, 185, 184, 185, 19, 132, 184, /* 870 */ 185, 43, 44, 45, 46, 47, 48, 49, 50, 51, - /* 880 */ 52, 53, 54, 55, 56, 57, 163, 184, 185, 107, - /* 890 */ 163, 43, 44, 45, 46, 47, 48, 49, 50, 51, - /* 900 */ 52, 53, 54, 55, 56, 57, 208, 255, 177, 178, - /* 910 */ 163, 184, 185, 163, 132, 163, 141, 163, 143, 22, + /* 880 */ 52, 53, 54, 55, 56, 57, 146, 163, 148, 59, + /* 890 */ 91, 43, 44, 45, 46, 47, 48, 49, 50, 51, + /* 900 */ 52, 53, 54, 55, 56, 57, 208, 107, 184, 185, + /* 910 */ 7, 8, 9, 116, 117, 118, 163, 163, 163, 24, /* 920 */ 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - /* 930 */ 102, 184, 185, 163, 184, 185, 184, 185, 184, 185, + /* 930 */ 102, 29, 132, 163, 163, 33, 106, 184, 185, 163, /* 940 */ 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - /* 950 */ 102, 163, 163, 163, 184, 185, 163, 115, 163, 163, - /* 960 */ 163, 163, 15, 163, 163, 163, 163, 163, 23, 163, - /* 970 */ 163, 26, 184, 185, 184, 185, 163, 184, 185, 184, - /* 980 */ 185, 184, 185, 163, 184, 185, 184, 185, 184, 185, - /* 990 */ 184, 185, 163, 96, 97, 147, 163, 184, 185, 163, - /* 1000 */ 199, 163, 163, 205, 184, 185, 163, 60, 163, 141, - /* 1010 */ 163, 143, 163, 184, 185, 19, 163, 184, 185, 230, - /* 1020 */ 184, 185, 184, 185, 206, 207, 230, 184, 185, 184, - /* 1030 */ 185, 184, 185, 184, 185, 19, 163, 219, 231, 43, + /* 950 */ 102, 163, 163, 163, 59, 184, 185, 163, 22, 163, + /* 960 */ 184, 185, 177, 178, 163, 163, 163, 65, 163, 199, + /* 970 */ 163, 26, 184, 185, 184, 185, 163, 163, 184, 185, + /* 980 */ 184, 185, 163, 98, 163, 184, 185, 184, 185, 184, + /* 990 */ 185, 184, 185, 252, 205, 147, 163, 61, 184, 185, + /* 1000 */ 163, 106, 163, 184, 185, 163, 163, 205, 163, 124, + /* 1010 */ 163, 256, 163, 163, 129, 19, 163, 184, 185, 163, + /* 1020 */ 199, 184, 185, 184, 185, 23, 184, 185, 26, 184, + /* 1030 */ 185, 184, 185, 184, 185, 19, 163, 184, 185, 43, /* 1040 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - /* 1050 */ 54, 55, 56, 57, 163, 26, 163, 184, 185, 43, + /* 1050 */ 54, 55, 56, 57, 163, 163, 163, 184, 185, 43, /* 1060 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - /* 1070 */ 54, 55, 56, 57, 163, 184, 185, 184, 185, 163, - /* 1080 */ 182, 163, 163, 163, 163, 163, 22, 163, 92, 93, - /* 1090 */ 94, 95, 96, 97, 98, 99, 100, 101, 102, 163, - /* 1100 */ 184, 185, 184, 185, 163, 184, 185, 163, 92, 93, + /* 1070 */ 54, 55, 56, 57, 16, 184, 185, 184, 185, 163, + /* 1080 */ 163, 22, 23, 138, 163, 19, 163, 231, 92, 93, + /* 1090 */ 94, 95, 96, 97, 98, 99, 100, 101, 102, 256, + /* 1100 */ 163, 184, 185, 163, 163, 184, 185, 163, 92, 93, /* 1110 */ 94, 95, 96, 97, 98, 99, 100, 101, 102, 163, - /* 1120 */ 184, 185, 98, 59, 163, 184, 185, 205, 184, 185, - /* 1130 */ 23, 206, 207, 26, 163, 26, 107, 153, 154, 237, - /* 1140 */ 184, 185, 231, 147, 219, 184, 185, 249, 124, 127, - /* 1150 */ 128, 231, 254, 129, 163, 231, 177, 178, 262, 263, - /* 1160 */ 118, 132, 19, 19, 46, 223, 224, 31, 24, 23, - /* 1170 */ 106, 124, 26, 22, 272, 39, 129, 23, 109, 110, - /* 1180 */ 26, 163, 140, 19, 22, 234, 59, 43, 44, 45, + /* 1120 */ 59, 184, 185, 163, 184, 185, 177, 178, 184, 185, + /* 1130 */ 163, 208, 163, 237, 163, 77, 163, 79, 163, 15, + /* 1140 */ 184, 185, 237, 147, 184, 185, 24, 231, 153, 154, + /* 1150 */ 91, 184, 185, 184, 185, 184, 185, 184, 185, 184, + /* 1160 */ 185, 22, 23, 19, 163, 127, 128, 106, 24, 273, + /* 1170 */ 271, 105, 231, 274, 263, 264, 223, 224, 273, 22, + /* 1180 */ 118, 24, 23, 19, 60, 26, 163, 43, 44, 45, /* 1190 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - /* 1200 */ 56, 57, 231, 7, 8, 193, 59, 43, 44, 45, + /* 1200 */ 56, 57, 140, 23, 22, 163, 26, 43, 44, 45, /* 1210 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - /* 1220 */ 56, 57, 104, 61, 23, 23, 23, 26, 26, 26, - /* 1230 */ 163, 23, 23, 106, 26, 26, 92, 93, 94, 95, - /* 1240 */ 96, 97, 98, 99, 100, 101, 102, 138, 105, 23, - /* 1250 */ 59, 23, 26, 106, 26, 163, 92, 93, 94, 95, - /* 1260 */ 96, 97, 98, 99, 100, 101, 102, 110, 23, 23, - /* 1270 */ 23, 26, 26, 26, 163, 163, 19, 120, 163, 163, - /* 1280 */ 163, 130, 163, 163, 163, 163, 163, 163, 163, 193, - /* 1290 */ 193, 163, 163, 163, 163, 225, 19, 106, 163, 222, - /* 1300 */ 163, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 1310 */ 53, 54, 55, 56, 57, 163, 163, 203, 163, 163, - /* 1320 */ 222, 163, 45, 46, 47, 48, 49, 50, 51, 52, - /* 1330 */ 53, 54, 55, 56, 57, 163, 163, 163, 163, 163, - /* 1340 */ 251, 250, 209, 19, 20, 182, 22, 161, 222, 92, + /* 1220 */ 56, 57, 23, 211, 23, 26, 31, 26, 23, 22, + /* 1230 */ 91, 26, 231, 221, 39, 53, 92, 93, 94, 95, + /* 1240 */ 96, 97, 98, 99, 100, 101, 102, 23, 23, 163, + /* 1250 */ 26, 26, 130, 59, 109, 110, 92, 93, 94, 95, + /* 1260 */ 96, 97, 98, 99, 100, 101, 102, 23, 7, 8, + /* 1270 */ 26, 110, 23, 59, 23, 26, 19, 26, 141, 23, + /* 1280 */ 143, 120, 26, 141, 163, 143, 23, 23, 163, 26, + /* 1290 */ 26, 163, 163, 163, 163, 163, 19, 163, 163, 193, + /* 1300 */ 106, 44, 45, 46, 47, 48, 49, 50, 51, 52, + /* 1310 */ 53, 54, 55, 56, 57, 163, 193, 163, 163, 163, + /* 1320 */ 106, 163, 45, 46, 47, 48, 49, 50, 51, 52, + /* 1330 */ 53, 54, 55, 56, 57, 163, 163, 130, 222, 163, + /* 1340 */ 163, 203, 163, 19, 20, 251, 22, 163, 163, 92, /* 1350 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, - /* 1360 */ 36, 222, 222, 260, 226, 188, 256, 226, 187, 92, + /* 1360 */ 36, 163, 209, 163, 261, 163, 163, 161, 222, 92, /* 1370 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, - /* 1380 */ 210, 213, 213, 59, 213, 196, 192, 187, 256, 244, - /* 1390 */ 212, 187, 226, 19, 20, 71, 22, 210, 166, 60, - /* 1400 */ 130, 170, 260, 170, 38, 81, 257, 257, 170, 104, - /* 1410 */ 36, 22, 43, 201, 90, 236, 138, 235, 213, 18, - /* 1420 */ 96, 97, 48, 204, 204, 204, 204, 103, 170, 105, - /* 1430 */ 106, 107, 18, 59, 110, 169, 213, 213, 201, 170, - /* 1440 */ 201, 169, 236, 213, 146, 71, 235, 62, 253, 252, - /* 1450 */ 170, 127, 128, 169, 22, 170, 82, 189, 169, 104, - /* 1460 */ 170, 87, 169, 189, 90, 141, 142, 143, 144, 145, - /* 1470 */ 96, 97, 186, 186, 186, 64, 194, 103, 186, 105, - /* 1480 */ 106, 107, 115, 189, 110, 188, 186, 186, 19, 20, - /* 1490 */ 194, 22, 186, 189, 102, 246, 246, 189, 133, 228, - /* 1500 */ 104, 228, 227, 227, 170, 36, 134, 228, 227, 19, - /* 1510 */ 20, 228, 22, 84, 271, 141, 142, 143, 144, 145, - /* 1520 */ 0, 1, 2, 216, 22, 5, 36, 137, 59, 227, - /* 1530 */ 10, 11, 12, 13, 14, 217, 269, 17, 216, 22, - /* 1540 */ 71, 170, 243, 146, 241, 217, 136, 215, 135, 59, - /* 1550 */ 30, 82, 32, 25, 214, 213, 87, 173, 26, 90, - /* 1560 */ 40, 71, 13, 172, 164, 96, 97, 164, 6, 162, - /* 1570 */ 162, 162, 103, 263, 105, 106, 107, 266, 266, 110, - /* 1580 */ 90, 176, 176, 190, 182, 190, 96, 97, 98, 4, - /* 1590 */ 70, 176, 3, 103, 182, 105, 106, 107, 78, 182, - /* 1600 */ 110, 81, 182, 182, 182, 182, 182, 151, 88, 22, - /* 1610 */ 141, 142, 143, 144, 145, 15, 89, 16, 23, 23, - /* 1620 */ 128, 19, 20, 139, 22, 119, 131, 24, 20, 133, - /* 1630 */ 16, 141, 142, 143, 144, 145, 1, 140, 36, 131, - /* 1640 */ 119, 61, 122, 37, 139, 53, 53, 127, 128, 119, - /* 1650 */ 53, 53, 105, 34, 130, 1, 5, 104, 22, 149, - /* 1660 */ 26, 59, 68, 75, 41, 130, 24, 68, 104, 20, - /* 1670 */ 150, 19, 120, 71, 114, 22, 67, 22, 22, 67, - /* 1680 */ 23, 22, 22, 67, 82, 37, 28, 23, 138, 87, - /* 1690 */ 22, 153, 90, 23, 23, 26, 23, 22, 96, 97, - /* 1700 */ 24, 23, 22, 24, 130, 103, 23, 105, 106, 107, - /* 1710 */ 1, 2, 110, 23, 5, 105, 34, 22, 132, 10, - /* 1720 */ 11, 12, 13, 14, 26, 34, 17, 34, 85, 83, - /* 1730 */ 44, 19, 20, 23, 22, 24, 75, 34, 23, 30, - /* 1740 */ 26, 32, 26, 141, 142, 143, 144, 145, 36, 40, - /* 1750 */ 23, 23, 23, 23, 11, 23, 22, 26, 22, 22, - /* 1760 */ 22, 19, 20, 23, 22, 26, 15, 23, 22, 124, - /* 1770 */ 130, 59, 23, 1, 130, 277, 277, 130, 36, 70, - /* 1780 */ 130, 277, 277, 71, 277, 277, 277, 78, 277, 277, - /* 1790 */ 81, 277, 277, 277, 277, 277, 277, 88, 277, 277, - /* 1800 */ 277, 59, 90, 277, 277, 277, 277, 277, 96, 97, - /* 1810 */ 277, 277, 277, 71, 277, 103, 277, 105, 106, 107, - /* 1820 */ 277, 277, 110, 277, 277, 277, 277, 277, 277, 277, - /* 1830 */ 277, 122, 90, 277, 277, 277, 127, 128, 96, 97, - /* 1840 */ 277, 277, 277, 277, 277, 103, 277, 105, 106, 107, - /* 1850 */ 277, 277, 110, 141, 142, 143, 144, 145, 277, 150, - /* 1860 */ 277, 277, 277, 5, 277, 277, 277, 277, 10, 11, - /* 1870 */ 12, 13, 14, 277, 277, 17, 277, 277, 277, 277, - /* 1880 */ 277, 277, 277, 141, 142, 143, 144, 145, 30, 277, - /* 1890 */ 32, 277, 277, 277, 277, 277, 277, 277, 40, 277, - /* 1900 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - /* 1910 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - /* 1920 */ 277, 277, 277, 277, 277, 277, 277, 277, 70, 277, - /* 1930 */ 277, 277, 277, 277, 277, 277, 78, 277, 277, 81, - /* 1940 */ 277, 277, 277, 277, 277, 277, 88, 277, 277, 277, - /* 1950 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - /* 1960 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - /* 1970 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - /* 1980 */ 122, 277, 277, 277, 277, 127, 128, 277, 277, 277, - /* 1990 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - /* 2000 */ 277, 277, 277, 277, 277, 277, 277, 277, 150, 277, - /* 2010 */ 277, 277, 277, 277, 277, 277, 277, 277, 277, + /* 1380 */ 210, 213, 222, 59, 222, 222, 182, 213, 213, 196, + /* 1390 */ 257, 226, 226, 19, 20, 71, 22, 257, 188, 187, + /* 1400 */ 192, 212, 187, 187, 226, 81, 210, 166, 60, 261, + /* 1410 */ 36, 244, 130, 170, 90, 170, 38, 170, 139, 104, + /* 1420 */ 96, 97, 48, 236, 22, 235, 43, 103, 201, 105, + /* 1430 */ 106, 107, 138, 59, 110, 247, 213, 18, 204, 258, + /* 1440 */ 204, 258, 204, 204, 170, 71, 18, 169, 213, 236, + /* 1450 */ 213, 127, 128, 235, 201, 201, 82, 170, 169, 213, + /* 1460 */ 146, 87, 62, 254, 90, 141, 142, 143, 144, 145, + /* 1470 */ 96, 97, 253, 170, 169, 22, 170, 103, 169, 105, + /* 1480 */ 106, 107, 189, 170, 110, 169, 189, 186, 19, 20, + /* 1490 */ 104, 22, 194, 186, 186, 64, 115, 186, 194, 189, + /* 1500 */ 188, 102, 133, 186, 186, 36, 186, 104, 189, 19, + /* 1510 */ 20, 246, 22, 246, 189, 141, 142, 143, 144, 145, + /* 1520 */ 0, 1, 2, 228, 228, 5, 36, 227, 59, 227, + /* 1530 */ 10, 11, 12, 13, 14, 170, 84, 17, 134, 216, + /* 1540 */ 71, 272, 270, 22, 137, 217, 22, 216, 227, 59, + /* 1550 */ 30, 82, 32, 217, 228, 228, 87, 227, 170, 90, + /* 1560 */ 40, 71, 146, 241, 215, 96, 97, 214, 136, 135, + /* 1570 */ 213, 25, 103, 26, 105, 106, 107, 243, 173, 110, + /* 1580 */ 90, 172, 13, 6, 164, 164, 96, 97, 98, 162, + /* 1590 */ 70, 162, 162, 103, 176, 105, 106, 107, 78, 267, + /* 1600 */ 110, 81, 267, 264, 182, 182, 182, 182, 88, 176, + /* 1610 */ 141, 142, 143, 144, 145, 176, 190, 4, 182, 182, + /* 1620 */ 182, 19, 20, 182, 22, 190, 3, 22, 151, 15, + /* 1630 */ 89, 141, 142, 143, 144, 145, 16, 128, 36, 23, + /* 1640 */ 23, 139, 122, 24, 119, 131, 20, 127, 128, 133, + /* 1650 */ 16, 1, 140, 131, 119, 61, 139, 53, 37, 53, + /* 1660 */ 53, 59, 53, 119, 105, 34, 130, 1, 5, 22, + /* 1670 */ 150, 104, 149, 71, 26, 75, 68, 41, 68, 130, + /* 1680 */ 104, 24, 20, 19, 82, 120, 114, 22, 28, 87, + /* 1690 */ 22, 67, 90, 22, 67, 23, 22, 22, 96, 97, + /* 1700 */ 67, 23, 138, 22, 37, 103, 153, 105, 106, 107, + /* 1710 */ 1, 2, 110, 23, 5, 23, 23, 26, 22, 10, + /* 1720 */ 11, 12, 13, 14, 24, 23, 17, 22, 24, 130, + /* 1730 */ 23, 19, 20, 23, 22, 105, 22, 34, 85, 30, + /* 1740 */ 34, 32, 26, 141, 142, 143, 144, 145, 36, 40, + /* 1750 */ 132, 34, 75, 83, 23, 44, 24, 34, 23, 26, + /* 1760 */ 26, 19, 20, 23, 22, 26, 23, 23, 23, 23, + /* 1770 */ 22, 59, 11, 22, 22, 26, 23, 23, 36, 70, + /* 1780 */ 22, 22, 124, 71, 130, 130, 130, 78, 23, 130, + /* 1790 */ 81, 15, 1, 278, 278, 278, 278, 88, 278, 278, + /* 1800 */ 278, 59, 90, 278, 278, 278, 278, 278, 96, 97, + /* 1810 */ 278, 278, 278, 71, 278, 103, 278, 105, 106, 107, + /* 1820 */ 278, 278, 110, 278, 278, 278, 278, 278, 278, 278, + /* 1830 */ 278, 122, 90, 278, 278, 278, 127, 128, 96, 97, + /* 1840 */ 278, 278, 278, 278, 278, 103, 278, 105, 106, 107, + /* 1850 */ 278, 278, 110, 141, 142, 143, 144, 145, 278, 150, + /* 1860 */ 278, 278, 278, 5, 278, 278, 278, 278, 10, 11, + /* 1870 */ 12, 13, 14, 278, 278, 17, 278, 278, 278, 278, + /* 1880 */ 278, 278, 278, 141, 142, 143, 144, 145, 30, 278, + /* 1890 */ 32, 278, 278, 278, 278, 278, 278, 278, 40, 278, + /* 1900 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + /* 1910 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + /* 1920 */ 278, 278, 278, 278, 278, 278, 278, 278, 70, 278, + /* 1930 */ 278, 278, 278, 278, 278, 278, 78, 278, 278, 81, + /* 1940 */ 278, 278, 278, 278, 278, 278, 88, 278, 278, 278, + /* 1950 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + /* 1960 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + /* 1970 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + /* 1980 */ 122, 278, 278, 278, 278, 127, 128, 278, 278, 278, + /* 1990 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + /* 2000 */ 278, 278, 278, 278, 278, 278, 278, 278, 150, 278, + /* 2010 */ 278, 278, 278, 278, 278, 278, 278, 278, 278, }; -#define YY_SHIFT_COUNT (520) +#define YY_SHIFT_COUNT (523) #define YY_SHIFT_MIN (0) #define YY_SHIFT_MAX (1858) static const unsigned short int yy_shift_ofst[] = { - /* 0 */ 1709, 1520, 1858, 1324, 1324, 277, 1374, 1469, 1602, 1712, - /* 10 */ 1712, 1712, 273, 0, 0, 113, 1016, 1712, 1712, 1712, - /* 20 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 11, 11, 236, - /* 30 */ 184, 277, 277, 277, 277, 277, 277, 93, 177, 270, + /* 0 */ 1709, 1520, 1858, 1324, 1324, 24, 1374, 1469, 1602, 1712, + /* 10 */ 1712, 1712, 271, 0, 0, 113, 1016, 1712, 1712, 1712, + /* 20 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 12, 12, 409, + /* 30 */ 596, 24, 24, 24, 24, 24, 24, 93, 177, 270, /* 40 */ 363, 456, 549, 642, 735, 828, 848, 996, 1144, 1016, /* 50 */ 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, - /* 60 */ 1016, 1016, 1016, 1016, 1016, 1016, 1164, 1016, 1257, 1277, - /* 70 */ 1277, 1490, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, + /* 60 */ 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1164, 1016, 1257, + /* 70 */ 1277, 1277, 1490, 1712, 1712, 1712, 1712, 1712, 1712, 1712, /* 80 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, /* 90 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, - /* 100 */ 1712, 1712, 1712, 1742, 1712, 1712, 1712, 1712, 1712, 1712, - /* 110 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 143, 162, 162, - /* 120 */ 162, 162, 162, 204, 151, 416, 531, 648, 700, 531, - /* 130 */ 486, 486, 531, 353, 353, 353, 353, 409, 279, 53, - /* 140 */ 2009, 2009, 331, 331, 331, 329, 366, 329, 329, 597, - /* 150 */ 597, 464, 474, 262, 681, 531, 531, 531, 531, 531, - /* 160 */ 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, - /* 170 */ 531, 531, 531, 531, 531, 531, 531, 173, 485, 984, - /* 180 */ 984, 576, 485, 19, 1022, 2009, 2009, 2009, 387, 250, - /* 190 */ 250, 525, 502, 278, 552, 227, 480, 566, 531, 531, - /* 200 */ 531, 531, 531, 531, 531, 531, 531, 531, 639, 531, - /* 210 */ 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, - /* 220 */ 531, 2, 2, 2, 531, 531, 531, 531, 782, 531, - /* 230 */ 531, 531, 744, 531, 531, 783, 531, 531, 531, 531, - /* 240 */ 531, 531, 531, 531, 419, 682, 327, 370, 370, 370, - /* 250 */ 370, 1029, 327, 327, 1024, 897, 856, 947, 1109, 706, - /* 260 */ 706, 1143, 1109, 1109, 1143, 842, 945, 1118, 1136, 1136, - /* 270 */ 1136, 706, 676, 400, 1047, 694, 1339, 1270, 1270, 1366, - /* 280 */ 1366, 1270, 1305, 1389, 1369, 1278, 1401, 1401, 1401, 1401, - /* 290 */ 1270, 1414, 1278, 1278, 1305, 1389, 1369, 1369, 1278, 1270, - /* 300 */ 1414, 1298, 1385, 1270, 1414, 1432, 1270, 1414, 1270, 1414, - /* 310 */ 1432, 1355, 1355, 1355, 1411, 1432, 1355, 1367, 1355, 1411, - /* 320 */ 1355, 1355, 1432, 1392, 1392, 1432, 1365, 1396, 1365, 1396, - /* 330 */ 1365, 1396, 1365, 1396, 1270, 1372, 1429, 1502, 1390, 1372, - /* 340 */ 1517, 1270, 1397, 1390, 1410, 1413, 1278, 1528, 1532, 1549, - /* 350 */ 1549, 1562, 1562, 1562, 2009, 2009, 2009, 2009, 2009, 2009, + /* 100 */ 1712, 1712, 1712, 1712, 1712, 1742, 1712, 1712, 1712, 1712, + /* 110 */ 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 1712, 143, + /* 120 */ 162, 162, 162, 162, 162, 204, 151, 186, 650, 690, + /* 130 */ 327, 650, 261, 261, 650, 722, 722, 722, 722, 373, + /* 140 */ 33, 2, 2009, 2009, 330, 330, 330, 346, 289, 278, + /* 150 */ 289, 289, 517, 517, 459, 510, 15, 799, 650, 650, + /* 160 */ 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, + /* 170 */ 650, 650, 650, 650, 650, 650, 650, 650, 650, 650, + /* 180 */ 331, 365, 995, 995, 265, 365, 50, 1038, 2009, 2009, + /* 190 */ 2009, 433, 250, 250, 504, 314, 429, 518, 522, 526, + /* 200 */ 561, 650, 650, 650, 650, 650, 650, 650, 650, 650, + /* 210 */ 192, 650, 650, 650, 650, 650, 650, 650, 650, 650, + /* 220 */ 650, 650, 650, 641, 641, 641, 650, 650, 650, 650, + /* 230 */ 800, 650, 650, 650, 830, 650, 650, 782, 650, 650, + /* 240 */ 650, 650, 650, 650, 650, 650, 739, 902, 689, 895, + /* 250 */ 895, 895, 895, 736, 689, 689, 885, 445, 903, 1124, + /* 260 */ 945, 748, 748, 1066, 945, 945, 1066, 447, 1002, 293, + /* 270 */ 1195, 1195, 1195, 748, 740, 727, 460, 1157, 1348, 1282, + /* 280 */ 1282, 1378, 1378, 1282, 1279, 1315, 1402, 1383, 1294, 1419, + /* 290 */ 1419, 1419, 1419, 1282, 1428, 1294, 1294, 1315, 1402, 1383, + /* 300 */ 1383, 1294, 1282, 1428, 1314, 1400, 1282, 1428, 1453, 1282, + /* 310 */ 1428, 1282, 1428, 1453, 1386, 1386, 1386, 1431, 1453, 1386, + /* 320 */ 1381, 1386, 1431, 1386, 1386, 1453, 1399, 1399, 1453, 1369, + /* 330 */ 1403, 1369, 1403, 1369, 1403, 1369, 1403, 1282, 1404, 1452, + /* 340 */ 1521, 1407, 1404, 1524, 1282, 1416, 1407, 1432, 1434, 1294, + /* 350 */ 1546, 1547, 1569, 1569, 1577, 1577, 1577, 2009, 2009, 2009, /* 360 */ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, - /* 370 */ 570, 345, 686, 748, 50, 740, 1064, 1107, 469, 537, - /* 380 */ 1042, 1146, 1162, 1154, 1201, 1202, 1203, 1208, 1209, 1127, - /* 390 */ 1069, 1196, 1157, 1147, 1226, 1228, 1245, 775, 868, 1246, - /* 400 */ 1247, 1191, 1151, 1585, 1589, 1587, 1456, 1600, 1527, 1601, - /* 410 */ 1595, 1596, 1492, 1484, 1506, 1603, 1495, 1608, 1496, 1614, - /* 420 */ 1635, 1508, 1497, 1521, 1580, 1606, 1505, 1592, 1593, 1597, - /* 430 */ 1598, 1530, 1547, 1619, 1524, 1654, 1651, 1636, 1553, 1510, - /* 440 */ 1594, 1634, 1599, 1588, 1623, 1535, 1564, 1642, 1649, 1652, - /* 450 */ 1552, 1560, 1653, 1609, 1655, 1656, 1657, 1659, 1612, 1658, - /* 460 */ 1660, 1616, 1648, 1664, 1550, 1668, 1538, 1670, 1671, 1669, - /* 470 */ 1673, 1675, 1676, 1678, 1680, 1679, 1574, 1683, 1690, 1610, - /* 480 */ 1682, 1695, 1586, 1698, 1691, 1698, 1693, 1643, 1661, 1646, - /* 490 */ 1686, 1710, 1711, 1714, 1716, 1703, 1715, 1698, 1727, 1728, - /* 500 */ 1729, 1730, 1731, 1732, 1734, 1743, 1736, 1737, 1740, 1744, - /* 510 */ 1738, 1746, 1739, 1645, 1640, 1644, 1647, 1650, 1749, 1751, - /* 520 */ 1772, + /* 370 */ 2009, 2009, 2009, 591, 697, 1059, 1139, 1058, 797, 465, + /* 380 */ 1159, 1182, 1122, 1062, 1180, 936, 1199, 1201, 1205, 1224, + /* 390 */ 1225, 1244, 1061, 1145, 1261, 1161, 1194, 1249, 1251, 1256, + /* 400 */ 1137, 1142, 1263, 1264, 1214, 1207, 1613, 1623, 1605, 1477, + /* 410 */ 1614, 1541, 1620, 1616, 1617, 1509, 1502, 1525, 1619, 1514, + /* 420 */ 1626, 1516, 1634, 1650, 1522, 1512, 1535, 1594, 1621, 1517, + /* 430 */ 1604, 1606, 1607, 1609, 1544, 1559, 1631, 1536, 1666, 1663, + /* 440 */ 1647, 1567, 1523, 1608, 1648, 1610, 1600, 1636, 1549, 1576, + /* 450 */ 1657, 1662, 1664, 1565, 1572, 1665, 1624, 1668, 1671, 1672, + /* 460 */ 1674, 1627, 1660, 1675, 1633, 1667, 1678, 1564, 1681, 1553, + /* 470 */ 1690, 1692, 1691, 1693, 1696, 1700, 1702, 1705, 1704, 1599, + /* 480 */ 1707, 1710, 1630, 1703, 1714, 1618, 1716, 1706, 1716, 1717, + /* 490 */ 1653, 1677, 1670, 1711, 1731, 1732, 1733, 1734, 1723, 1735, + /* 500 */ 1716, 1740, 1743, 1744, 1745, 1739, 1746, 1748, 1761, 1751, + /* 510 */ 1752, 1753, 1754, 1758, 1759, 1749, 1658, 1654, 1655, 1656, + /* 520 */ 1659, 1765, 1776, 1791, }; -#define YY_REDUCE_COUNT (369) -#define YY_REDUCE_MIN (-237) -#define YY_REDUCE_MAX (1424) +#define YY_REDUCE_COUNT (372) +#define YY_REDUCE_MIN (-235) +#define YY_REDUCE_MAX (1441) static const short yy_reduce_ofst[] = { - /* 0 */ -147, 171, 263, -96, 358, -144, -149, -102, 124, -156, - /* 10 */ -98, 305, 401, -57, 209, -237, 245, -94, -79, 189, - /* 20 */ 375, 490, 493, 378, 303, 539, 542, 501, 503, 554, - /* 30 */ 415, 526, 546, 557, 587, 593, 595, -234, -234, -234, - /* 40 */ -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, - /* 50 */ -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, - /* 60 */ -234, -234, -234, -234, -234, -234, -234, -234, -234, -234, - /* 70 */ -234, -50, 335, 470, 633, 656, 658, 660, 675, 685, - /* 80 */ 703, 727, 747, 750, 752, 754, 770, 788, 790, 793, - /* 90 */ 795, 797, 800, 802, 804, 806, 813, 820, 829, 833, - /* 100 */ 836, 838, 843, 845, 847, 849, 873, 891, 893, 916, - /* 110 */ 918, 921, 936, 941, 944, 956, 961, -234, -234, -234, - /* 120 */ -234, -234, -234, -234, -234, -234, 463, 607, -176, 14, - /* 130 */ -139, 87, -137, 818, 925, 818, 925, 898, -234, -234, - /* 140 */ -234, -234, -166, -166, -166, -130, -131, -82, -54, -180, - /* 150 */ 364, 41, 513, 509, 509, 117, 500, 789, 796, 646, - /* 160 */ 192, 291, 644, 798, 120, 807, 543, 911, 920, 652, - /* 170 */ 924, 922, 232, 698, 801, 971, 39, 220, 731, 442, - /* 180 */ 902, -199, 979, -43, 421, 896, 942, 605, -184, -126, - /* 190 */ 155, 172, 281, 304, 377, 538, 650, 690, 699, 723, - /* 200 */ 803, 839, 853, 919, 991, 1018, 1067, 1092, 951, 1111, - /* 210 */ 1112, 1115, 1116, 1117, 1119, 1120, 1121, 1122, 1123, 1124, - /* 220 */ 1125, 1012, 1096, 1097, 1128, 1129, 1130, 1131, 1070, 1135, - /* 230 */ 1137, 1152, 1077, 1153, 1155, 1114, 1156, 304, 1158, 1172, - /* 240 */ 1173, 1174, 1175, 1176, 1089, 1091, 1133, 1098, 1126, 1139, - /* 250 */ 1140, 1070, 1133, 1133, 1170, 1163, 1186, 1103, 1168, 1138, - /* 260 */ 1141, 1110, 1169, 1171, 1132, 1177, 1189, 1194, 1181, 1200, - /* 270 */ 1204, 1166, 1145, 1178, 1187, 1232, 1142, 1231, 1233, 1149, - /* 280 */ 1150, 1238, 1179, 1182, 1212, 1205, 1219, 1220, 1221, 1222, - /* 290 */ 1258, 1266, 1223, 1224, 1206, 1211, 1237, 1239, 1230, 1269, - /* 300 */ 1272, 1195, 1197, 1280, 1284, 1268, 1285, 1289, 1290, 1293, - /* 310 */ 1274, 1286, 1287, 1288, 1282, 1294, 1292, 1297, 1300, 1296, - /* 320 */ 1301, 1306, 1304, 1249, 1250, 1308, 1271, 1275, 1273, 1276, - /* 330 */ 1279, 1281, 1283, 1302, 1334, 1307, 1243, 1267, 1318, 1322, - /* 340 */ 1303, 1371, 1299, 1328, 1332, 1340, 1342, 1384, 1391, 1400, - /* 350 */ 1403, 1407, 1408, 1409, 1311, 1312, 1310, 1405, 1402, 1412, - /* 360 */ 1417, 1420, 1406, 1393, 1395, 1421, 1422, 1423, 1424, 1415, + /* 0 */ -147, 171, 263, -96, 169, -144, -162, -149, -102, -156, + /* 10 */ -98, 216, 354, -170, -57, -235, 307, 149, 423, 428, + /* 20 */ 471, 313, 451, 519, 489, 496, 499, 545, 547, 555, + /* 30 */ -116, 540, 558, 592, 594, 597, 599, -206, -206, -206, + /* 40 */ -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, + /* 50 */ -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, + /* 60 */ -206, -206, -206, -206, -206, -206, -206, -206, -206, -206, + /* 70 */ -206, -206, 196, 309, 494, 537, 612, 656, 675, 679, + /* 80 */ 681, 685, 724, 753, 771, 776, 788, 790, 794, 796, + /* 90 */ 801, 803, 805, 807, 814, 819, 833, 837, 839, 842, + /* 100 */ 845, 847, 849, 853, 873, 891, 893, 917, 921, 937, + /* 110 */ 940, 944, 956, 960, 967, 969, 971, 973, 975, -206, + /* 120 */ -206, -206, -206, -206, -206, -206, -206, -206, 501, -168, + /* 130 */ 90, -97, 87, 112, 303, 277, 601, 277, 601, 179, + /* 140 */ -206, -206, -206, -206, -107, -107, -107, -43, -56, 323, + /* 150 */ 500, 512, -187, -177, 317, 609, 353, 353, 120, 144, + /* 160 */ 490, 539, 698, 374, 467, 507, 789, 404, -157, 755, + /* 170 */ 856, 916, 843, 941, 802, 770, 923, 821, 1001, -142, + /* 180 */ 264, 785, 896, 905, 899, 949, -176, 544, 911, 953, + /* 190 */ 1012, -182, -59, -30, 16, -22, 117, 172, 291, 369, + /* 200 */ 407, 415, 566, 586, 647, 699, 754, 813, 850, 892, + /* 210 */ 121, 1023, 1042, 1086, 1121, 1125, 1128, 1129, 1130, 1131, + /* 220 */ 1132, 1134, 1135, 284, 1106, 1123, 1152, 1154, 1155, 1156, + /* 230 */ 397, 1158, 1172, 1173, 1116, 1176, 1177, 1138, 1179, 117, + /* 240 */ 1184, 1185, 1198, 1200, 1202, 1203, 741, 1094, 1153, 1146, + /* 250 */ 1160, 1162, 1163, 397, 1153, 1153, 1170, 1204, 1206, 1103, + /* 260 */ 1168, 1165, 1166, 1133, 1174, 1175, 1140, 1210, 1193, 1208, + /* 270 */ 1212, 1215, 1216, 1178, 1167, 1189, 1196, 1241, 1148, 1243, + /* 280 */ 1245, 1181, 1183, 1247, 1188, 1187, 1190, 1227, 1223, 1234, + /* 290 */ 1236, 1238, 1239, 1274, 1278, 1235, 1237, 1213, 1218, 1253, + /* 300 */ 1254, 1246, 1287, 1289, 1209, 1219, 1303, 1305, 1293, 1306, + /* 310 */ 1309, 1313, 1316, 1297, 1301, 1307, 1308, 1298, 1310, 1311, + /* 320 */ 1312, 1317, 1304, 1318, 1320, 1319, 1265, 1267, 1325, 1295, + /* 330 */ 1300, 1296, 1302, 1326, 1321, 1327, 1330, 1365, 1323, 1269, + /* 340 */ 1272, 1328, 1331, 1322, 1388, 1334, 1336, 1349, 1353, 1357, + /* 350 */ 1405, 1409, 1420, 1421, 1427, 1429, 1430, 1332, 1335, 1339, + /* 360 */ 1418, 1422, 1423, 1424, 1425, 1433, 1426, 1435, 1436, 1437, + /* 370 */ 1438, 1441, 1439, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 1492, 1492, 1492, 1340, 1123, 1229, 1123, 1123, 1123, 1340, - /* 10 */ 1340, 1340, 1123, 1259, 1259, 1391, 1154, 1123, 1123, 1123, - /* 20 */ 1123, 1123, 1123, 1123, 1339, 1123, 1123, 1123, 1123, 1123, - /* 30 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1265, 1123, - /* 40 */ 1123, 1123, 1123, 1123, 1341, 1342, 1123, 1123, 1123, 1390, - /* 50 */ 1392, 1275, 1274, 1273, 1272, 1373, 1246, 1270, 1263, 1267, - /* 60 */ 1335, 1336, 1334, 1338, 1342, 1341, 1123, 1266, 1306, 1320, - /* 70 */ 1305, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, - /* 80 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, - /* 90 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, - /* 100 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, - /* 110 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1314, 1319, 1325, - /* 120 */ 1318, 1315, 1308, 1307, 1309, 1310, 1123, 1144, 1193, 1123, - /* 130 */ 1123, 1123, 1123, 1409, 1408, 1123, 1123, 1154, 1311, 1312, - /* 140 */ 1322, 1321, 1398, 1448, 1447, 1123, 1123, 1123, 1123, 1123, - /* 150 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, - /* 160 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, - /* 170 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1154, 1150, 1300, - /* 180 */ 1299, 1418, 1150, 1253, 1123, 1404, 1229, 1220, 1123, 1123, - /* 190 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, - /* 200 */ 1123, 1395, 1393, 1123, 1355, 1123, 1123, 1123, 1123, 1123, - /* 210 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, - /* 220 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, - /* 230 */ 1123, 1123, 1225, 1123, 1123, 1123, 1123, 1123, 1123, 1123, - /* 240 */ 1123, 1123, 1123, 1442, 1123, 1368, 1207, 1225, 1225, 1225, - /* 250 */ 1225, 1227, 1208, 1206, 1219, 1154, 1130, 1484, 1269, 1248, - /* 260 */ 1248, 1481, 1269, 1269, 1481, 1168, 1462, 1165, 1259, 1259, - /* 270 */ 1259, 1248, 1337, 1226, 1219, 1123, 1484, 1234, 1234, 1483, - /* 280 */ 1483, 1234, 1278, 1284, 1196, 1269, 1202, 1202, 1202, 1202, - /* 290 */ 1234, 1141, 1269, 1269, 1278, 1284, 1196, 1196, 1269, 1234, - /* 300 */ 1141, 1372, 1478, 1234, 1141, 1348, 1234, 1141, 1234, 1141, - /* 310 */ 1348, 1194, 1194, 1194, 1183, 1348, 1194, 1168, 1194, 1183, - /* 320 */ 1194, 1194, 1348, 1352, 1352, 1348, 1252, 1247, 1252, 1247, - /* 330 */ 1252, 1247, 1252, 1247, 1234, 1253, 1417, 1123, 1264, 1253, - /* 340 */ 1343, 1234, 1123, 1264, 1262, 1260, 1269, 1147, 1186, 1445, - /* 350 */ 1445, 1441, 1441, 1441, 1489, 1489, 1404, 1457, 1154, 1154, - /* 360 */ 1154, 1154, 1457, 1170, 1170, 1154, 1154, 1154, 1154, 1457, - /* 370 */ 1123, 1123, 1123, 1123, 1123, 1123, 1452, 1123, 1357, 1238, - /* 380 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, - /* 390 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, - /* 400 */ 1123, 1123, 1289, 1123, 1126, 1401, 1123, 1123, 1399, 1123, - /* 410 */ 1123, 1123, 1123, 1123, 1123, 1239, 1123, 1123, 1123, 1123, - /* 420 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, - /* 430 */ 1123, 1123, 1123, 1123, 1480, 1123, 1123, 1123, 1123, 1123, - /* 440 */ 1123, 1371, 1370, 1123, 1123, 1236, 1123, 1123, 1123, 1123, - /* 450 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, - /* 460 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, - /* 470 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, - /* 480 */ 1123, 1123, 1123, 1261, 1123, 1416, 1123, 1123, 1123, 1123, - /* 490 */ 1123, 1123, 1123, 1430, 1254, 1123, 1123, 1471, 1123, 1123, - /* 500 */ 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, - /* 510 */ 1123, 1123, 1466, 1210, 1291, 1123, 1290, 1294, 1123, 1135, - /* 520 */ 1123, + /* 0 */ 1500, 1500, 1500, 1346, 1129, 1235, 1129, 1129, 1129, 1346, + /* 10 */ 1346, 1346, 1129, 1265, 1265, 1399, 1160, 1129, 1129, 1129, + /* 20 */ 1129, 1129, 1129, 1129, 1345, 1129, 1129, 1129, 1129, 1129, + /* 30 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1271, 1129, + /* 40 */ 1129, 1129, 1129, 1129, 1347, 1348, 1129, 1129, 1129, 1398, + /* 50 */ 1400, 1363, 1281, 1280, 1279, 1278, 1381, 1252, 1276, 1269, + /* 60 */ 1273, 1341, 1342, 1340, 1344, 1348, 1347, 1129, 1272, 1312, + /* 70 */ 1326, 1311, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, + /* 80 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, + /* 90 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, + /* 100 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, + /* 110 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1320, + /* 120 */ 1325, 1331, 1324, 1321, 1314, 1313, 1315, 1316, 1129, 1150, + /* 130 */ 1199, 1129, 1129, 1129, 1129, 1417, 1416, 1129, 1129, 1160, + /* 140 */ 1317, 1318, 1328, 1327, 1406, 1456, 1455, 1364, 1129, 1129, + /* 150 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, + /* 160 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, + /* 170 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, + /* 180 */ 1160, 1156, 1306, 1305, 1426, 1156, 1259, 1129, 1412, 1235, + /* 190 */ 1226, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, + /* 200 */ 1129, 1129, 1129, 1129, 1403, 1401, 1129, 1129, 1129, 1129, + /* 210 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, + /* 220 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, + /* 230 */ 1129, 1129, 1129, 1129, 1231, 1129, 1129, 1129, 1129, 1129, + /* 240 */ 1129, 1129, 1129, 1129, 1129, 1450, 1129, 1376, 1213, 1231, + /* 250 */ 1231, 1231, 1231, 1233, 1214, 1212, 1225, 1160, 1136, 1492, + /* 260 */ 1275, 1254, 1254, 1489, 1275, 1275, 1489, 1174, 1470, 1171, + /* 270 */ 1265, 1265, 1265, 1254, 1343, 1232, 1225, 1129, 1492, 1240, + /* 280 */ 1240, 1491, 1491, 1240, 1364, 1284, 1290, 1202, 1275, 1208, + /* 290 */ 1208, 1208, 1208, 1240, 1147, 1275, 1275, 1284, 1290, 1202, + /* 300 */ 1202, 1275, 1240, 1147, 1380, 1486, 1240, 1147, 1354, 1240, + /* 310 */ 1147, 1240, 1147, 1354, 1200, 1200, 1200, 1189, 1354, 1200, + /* 320 */ 1174, 1200, 1189, 1200, 1200, 1354, 1358, 1358, 1354, 1258, + /* 330 */ 1253, 1258, 1253, 1258, 1253, 1258, 1253, 1240, 1259, 1425, + /* 340 */ 1129, 1270, 1259, 1349, 1240, 1129, 1270, 1268, 1266, 1275, + /* 350 */ 1153, 1192, 1453, 1453, 1449, 1449, 1449, 1497, 1497, 1412, + /* 360 */ 1465, 1160, 1160, 1160, 1160, 1465, 1176, 1176, 1160, 1160, + /* 370 */ 1160, 1160, 1465, 1129, 1129, 1129, 1129, 1129, 1129, 1460, + /* 380 */ 1129, 1365, 1244, 1129, 1129, 1129, 1129, 1129, 1129, 1129, + /* 390 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, + /* 400 */ 1129, 1129, 1129, 1129, 1129, 1295, 1129, 1132, 1409, 1129, + /* 410 */ 1129, 1407, 1129, 1129, 1129, 1129, 1129, 1129, 1245, 1129, + /* 420 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, + /* 430 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1488, 1129, 1129, + /* 440 */ 1129, 1129, 1129, 1129, 1379, 1378, 1129, 1129, 1242, 1129, + /* 450 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, + /* 460 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, + /* 470 */ 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, + /* 480 */ 1129, 1129, 1129, 1129, 1129, 1129, 1267, 1129, 1424, 1129, + /* 490 */ 1129, 1129, 1129, 1129, 1129, 1129, 1438, 1260, 1129, 1129, + /* 500 */ 1479, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, + /* 510 */ 1129, 1129, 1129, 1129, 1129, 1474, 1216, 1297, 1129, 1296, + /* 520 */ 1300, 1129, 1141, 1129, }; /********** End of lemon-generated parsing tables *****************************/ @@ -148168,36 +148683,37 @@ static const char *const yyTokenName[] = { /* 244 */ "case_else", /* 245 */ "uniqueflag", /* 246 */ "collate", - /* 247 */ "nmnum", - /* 248 */ "trigger_decl", - /* 249 */ "trigger_cmd_list", - /* 250 */ "trigger_time", - /* 251 */ "trigger_event", - /* 252 */ "foreach_clause", - /* 253 */ "when_clause", - /* 254 */ "trigger_cmd", - /* 255 */ "trnm", - /* 256 */ "tridxby", - /* 257 */ "database_kw_opt", - /* 258 */ "key_opt", - /* 259 */ "add_column_fullname", - /* 260 */ "kwcolumn_opt", - /* 261 */ "create_vtab", - /* 262 */ "vtabarglist", - /* 263 */ "vtabarg", - /* 264 */ "vtabargtoken", - /* 265 */ "lp", - /* 266 */ "anylist", - /* 267 */ "windowdefn_list", - /* 268 */ "windowdefn", - /* 269 */ "window", - /* 270 */ "frame_opt", - /* 271 */ "part_opt", - /* 272 */ "filter_opt", - /* 273 */ "range_or_rows", - /* 274 */ "frame_bound", - /* 275 */ "frame_bound_s", - /* 276 */ "frame_bound_e", + /* 247 */ "vinto", + /* 248 */ "nmnum", + /* 249 */ "trigger_decl", + /* 250 */ "trigger_cmd_list", + /* 251 */ "trigger_time", + /* 252 */ "trigger_event", + /* 253 */ "foreach_clause", + /* 254 */ "when_clause", + /* 255 */ "trigger_cmd", + /* 256 */ "trnm", + /* 257 */ "tridxby", + /* 258 */ "database_kw_opt", + /* 259 */ "key_opt", + /* 260 */ "add_column_fullname", + /* 261 */ "kwcolumn_opt", + /* 262 */ "create_vtab", + /* 263 */ "vtabarglist", + /* 264 */ "vtabarg", + /* 265 */ "vtabargtoken", + /* 266 */ "lp", + /* 267 */ "anylist", + /* 268 */ "windowdefn_list", + /* 269 */ "windowdefn", + /* 270 */ "window", + /* 271 */ "frame_opt", + /* 272 */ "part_opt", + /* 273 */ "filter_opt", + /* 274 */ "range_or_rows", + /* 275 */ "frame_bound", + /* 276 */ "frame_bound_s", + /* 277 */ "frame_bound_e", }; #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ @@ -148434,144 +148950,146 @@ static const char *const yyRuleName[] = { /* 226 */ "collate ::=", /* 227 */ "collate ::= COLLATE ID|STRING", /* 228 */ "cmd ::= DROP INDEX ifexists fullname", - /* 229 */ "cmd ::= VACUUM", - /* 230 */ "cmd ::= VACUUM nm", - /* 231 */ "cmd ::= PRAGMA nm dbnm", - /* 232 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", - /* 233 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", - /* 234 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", - /* 235 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", - /* 236 */ "plus_num ::= PLUS INTEGER|FLOAT", - /* 237 */ "minus_num ::= MINUS INTEGER|FLOAT", - /* 238 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", - /* 239 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", - /* 240 */ "trigger_time ::= BEFORE|AFTER", - /* 241 */ "trigger_time ::= INSTEAD OF", - /* 242 */ "trigger_time ::=", - /* 243 */ "trigger_event ::= DELETE|INSERT", - /* 244 */ "trigger_event ::= UPDATE", - /* 245 */ "trigger_event ::= UPDATE OF idlist", - /* 246 */ "when_clause ::=", - /* 247 */ "when_clause ::= WHEN expr", - /* 248 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", - /* 249 */ "trigger_cmd_list ::= trigger_cmd SEMI", - /* 250 */ "trnm ::= nm DOT nm", - /* 251 */ "tridxby ::= INDEXED BY nm", - /* 252 */ "tridxby ::= NOT INDEXED", - /* 253 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt", - /* 254 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", - /* 255 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", - /* 256 */ "trigger_cmd ::= scanpt select scanpt", - /* 257 */ "expr ::= RAISE LP IGNORE RP", - /* 258 */ "expr ::= RAISE LP raisetype COMMA nm RP", - /* 259 */ "raisetype ::= ROLLBACK", - /* 260 */ "raisetype ::= ABORT", - /* 261 */ "raisetype ::= FAIL", - /* 262 */ "cmd ::= DROP TRIGGER ifexists fullname", - /* 263 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", - /* 264 */ "cmd ::= DETACH database_kw_opt expr", - /* 265 */ "key_opt ::=", - /* 266 */ "key_opt ::= KEY expr", - /* 267 */ "cmd ::= REINDEX", - /* 268 */ "cmd ::= REINDEX nm dbnm", - /* 269 */ "cmd ::= ANALYZE", - /* 270 */ "cmd ::= ANALYZE nm dbnm", - /* 271 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", - /* 272 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", - /* 273 */ "add_column_fullname ::= fullname", - /* 274 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", - /* 275 */ "cmd ::= create_vtab", - /* 276 */ "cmd ::= create_vtab LP vtabarglist RP", - /* 277 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", - /* 278 */ "vtabarg ::=", - /* 279 */ "vtabargtoken ::= ANY", - /* 280 */ "vtabargtoken ::= lp anylist RP", - /* 281 */ "lp ::= LP", - /* 282 */ "with ::= WITH wqlist", - /* 283 */ "with ::= WITH RECURSIVE wqlist", - /* 284 */ "wqlist ::= nm eidlist_opt AS LP select RP", - /* 285 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP", - /* 286 */ "windowdefn_list ::= windowdefn", - /* 287 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", - /* 288 */ "windowdefn ::= nm AS window", - /* 289 */ "window ::= LP part_opt orderby_opt frame_opt RP", - /* 290 */ "part_opt ::= PARTITION BY nexprlist", - /* 291 */ "part_opt ::=", - /* 292 */ "frame_opt ::=", - /* 293 */ "frame_opt ::= range_or_rows frame_bound_s", - /* 294 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e", - /* 295 */ "range_or_rows ::= RANGE", - /* 296 */ "range_or_rows ::= ROWS", - /* 297 */ "frame_bound_s ::= frame_bound", - /* 298 */ "frame_bound_s ::= UNBOUNDED PRECEDING", - /* 299 */ "frame_bound_e ::= frame_bound", - /* 300 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", - /* 301 */ "frame_bound ::= expr PRECEDING", - /* 302 */ "frame_bound ::= CURRENT ROW", - /* 303 */ "frame_bound ::= expr FOLLOWING", - /* 304 */ "window_clause ::= WINDOW windowdefn_list", - /* 305 */ "over_clause ::= filter_opt OVER window", - /* 306 */ "over_clause ::= filter_opt OVER nm", - /* 307 */ "filter_opt ::=", - /* 308 */ "filter_opt ::= FILTER LP WHERE expr RP", - /* 309 */ "input ::= cmdlist", - /* 310 */ "cmdlist ::= cmdlist ecmd", - /* 311 */ "cmdlist ::= ecmd", - /* 312 */ "ecmd ::= SEMI", - /* 313 */ "ecmd ::= cmdx SEMI", - /* 314 */ "ecmd ::= explain cmdx", - /* 315 */ "trans_opt ::=", - /* 316 */ "trans_opt ::= TRANSACTION", - /* 317 */ "trans_opt ::= TRANSACTION nm", - /* 318 */ "savepoint_opt ::= SAVEPOINT", - /* 319 */ "savepoint_opt ::=", - /* 320 */ "cmd ::= create_table create_table_args", - /* 321 */ "columnlist ::= columnlist COMMA columnname carglist", - /* 322 */ "columnlist ::= columnname carglist", - /* 323 */ "nm ::= ID|INDEXED", - /* 324 */ "nm ::= STRING", - /* 325 */ "nm ::= JOIN_KW", - /* 326 */ "typetoken ::= typename", - /* 327 */ "typename ::= ID|STRING", - /* 328 */ "signed ::= plus_num", - /* 329 */ "signed ::= minus_num", - /* 330 */ "carglist ::= carglist ccons", - /* 331 */ "carglist ::=", - /* 332 */ "ccons ::= NULL onconf", - /* 333 */ "conslist_opt ::= COMMA conslist", - /* 334 */ "conslist ::= conslist tconscomma tcons", - /* 335 */ "conslist ::= tcons", - /* 336 */ "tconscomma ::=", - /* 337 */ "defer_subclause_opt ::= defer_subclause", - /* 338 */ "resolvetype ::= raisetype", - /* 339 */ "selectnowith ::= oneselect", - /* 340 */ "oneselect ::= values", - /* 341 */ "sclp ::= selcollist COMMA", - /* 342 */ "as ::= ID|STRING", - /* 343 */ "expr ::= term", - /* 344 */ "likeop ::= LIKE_KW|MATCH", - /* 345 */ "exprlist ::= nexprlist", - /* 346 */ "nmnum ::= plus_num", - /* 347 */ "nmnum ::= nm", - /* 348 */ "nmnum ::= ON", - /* 349 */ "nmnum ::= DELETE", - /* 350 */ "nmnum ::= DEFAULT", - /* 351 */ "plus_num ::= INTEGER|FLOAT", - /* 352 */ "foreach_clause ::=", - /* 353 */ "foreach_clause ::= FOR EACH ROW", - /* 354 */ "trnm ::= nm", - /* 355 */ "tridxby ::=", - /* 356 */ "database_kw_opt ::= DATABASE", - /* 357 */ "database_kw_opt ::=", - /* 358 */ "kwcolumn_opt ::=", - /* 359 */ "kwcolumn_opt ::= COLUMNKW", - /* 360 */ "vtabarglist ::= vtabarg", - /* 361 */ "vtabarglist ::= vtabarglist COMMA vtabarg", - /* 362 */ "vtabarg ::= vtabarg vtabargtoken", - /* 363 */ "anylist ::=", - /* 364 */ "anylist ::= anylist LP anylist RP", - /* 365 */ "anylist ::= anylist ANY", - /* 366 */ "with ::=", + /* 229 */ "cmd ::= VACUUM vinto", + /* 230 */ "cmd ::= VACUUM nm vinto", + /* 231 */ "vinto ::= INTO expr", + /* 232 */ "vinto ::=", + /* 233 */ "cmd ::= PRAGMA nm dbnm", + /* 234 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", + /* 235 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", + /* 236 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", + /* 237 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", + /* 238 */ "plus_num ::= PLUS INTEGER|FLOAT", + /* 239 */ "minus_num ::= MINUS INTEGER|FLOAT", + /* 240 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", + /* 241 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", + /* 242 */ "trigger_time ::= BEFORE|AFTER", + /* 243 */ "trigger_time ::= INSTEAD OF", + /* 244 */ "trigger_time ::=", + /* 245 */ "trigger_event ::= DELETE|INSERT", + /* 246 */ "trigger_event ::= UPDATE", + /* 247 */ "trigger_event ::= UPDATE OF idlist", + /* 248 */ "when_clause ::=", + /* 249 */ "when_clause ::= WHEN expr", + /* 250 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", + /* 251 */ "trigger_cmd_list ::= trigger_cmd SEMI", + /* 252 */ "trnm ::= nm DOT nm", + /* 253 */ "tridxby ::= INDEXED BY nm", + /* 254 */ "tridxby ::= NOT INDEXED", + /* 255 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt", + /* 256 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", + /* 257 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", + /* 258 */ "trigger_cmd ::= scanpt select scanpt", + /* 259 */ "expr ::= RAISE LP IGNORE RP", + /* 260 */ "expr ::= RAISE LP raisetype COMMA nm RP", + /* 261 */ "raisetype ::= ROLLBACK", + /* 262 */ "raisetype ::= ABORT", + /* 263 */ "raisetype ::= FAIL", + /* 264 */ "cmd ::= DROP TRIGGER ifexists fullname", + /* 265 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", + /* 266 */ "cmd ::= DETACH database_kw_opt expr", + /* 267 */ "key_opt ::=", + /* 268 */ "key_opt ::= KEY expr", + /* 269 */ "cmd ::= REINDEX", + /* 270 */ "cmd ::= REINDEX nm dbnm", + /* 271 */ "cmd ::= ANALYZE", + /* 272 */ "cmd ::= ANALYZE nm dbnm", + /* 273 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", + /* 274 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", + /* 275 */ "add_column_fullname ::= fullname", + /* 276 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", + /* 277 */ "cmd ::= create_vtab", + /* 278 */ "cmd ::= create_vtab LP vtabarglist RP", + /* 279 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", + /* 280 */ "vtabarg ::=", + /* 281 */ "vtabargtoken ::= ANY", + /* 282 */ "vtabargtoken ::= lp anylist RP", + /* 283 */ "lp ::= LP", + /* 284 */ "with ::= WITH wqlist", + /* 285 */ "with ::= WITH RECURSIVE wqlist", + /* 286 */ "wqlist ::= nm eidlist_opt AS LP select RP", + /* 287 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP", + /* 288 */ "windowdefn_list ::= windowdefn", + /* 289 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", + /* 290 */ "windowdefn ::= nm AS window", + /* 291 */ "window ::= LP part_opt orderby_opt frame_opt RP", + /* 292 */ "part_opt ::= PARTITION BY nexprlist", + /* 293 */ "part_opt ::=", + /* 294 */ "frame_opt ::=", + /* 295 */ "frame_opt ::= range_or_rows frame_bound_s", + /* 296 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e", + /* 297 */ "range_or_rows ::= RANGE", + /* 298 */ "range_or_rows ::= ROWS", + /* 299 */ "frame_bound_s ::= frame_bound", + /* 300 */ "frame_bound_s ::= UNBOUNDED PRECEDING", + /* 301 */ "frame_bound_e ::= frame_bound", + /* 302 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", + /* 303 */ "frame_bound ::= expr PRECEDING", + /* 304 */ "frame_bound ::= CURRENT ROW", + /* 305 */ "frame_bound ::= expr FOLLOWING", + /* 306 */ "window_clause ::= WINDOW windowdefn_list", + /* 307 */ "over_clause ::= filter_opt OVER window", + /* 308 */ "over_clause ::= filter_opt OVER nm", + /* 309 */ "filter_opt ::=", + /* 310 */ "filter_opt ::= FILTER LP WHERE expr RP", + /* 311 */ "input ::= cmdlist", + /* 312 */ "cmdlist ::= cmdlist ecmd", + /* 313 */ "cmdlist ::= ecmd", + /* 314 */ "ecmd ::= SEMI", + /* 315 */ "ecmd ::= cmdx SEMI", + /* 316 */ "ecmd ::= explain cmdx", + /* 317 */ "trans_opt ::=", + /* 318 */ "trans_opt ::= TRANSACTION", + /* 319 */ "trans_opt ::= TRANSACTION nm", + /* 320 */ "savepoint_opt ::= SAVEPOINT", + /* 321 */ "savepoint_opt ::=", + /* 322 */ "cmd ::= create_table create_table_args", + /* 323 */ "columnlist ::= columnlist COMMA columnname carglist", + /* 324 */ "columnlist ::= columnname carglist", + /* 325 */ "nm ::= ID|INDEXED", + /* 326 */ "nm ::= STRING", + /* 327 */ "nm ::= JOIN_KW", + /* 328 */ "typetoken ::= typename", + /* 329 */ "typename ::= ID|STRING", + /* 330 */ "signed ::= plus_num", + /* 331 */ "signed ::= minus_num", + /* 332 */ "carglist ::= carglist ccons", + /* 333 */ "carglist ::=", + /* 334 */ "ccons ::= NULL onconf", + /* 335 */ "conslist_opt ::= COMMA conslist", + /* 336 */ "conslist ::= conslist tconscomma tcons", + /* 337 */ "conslist ::= tcons", + /* 338 */ "tconscomma ::=", + /* 339 */ "defer_subclause_opt ::= defer_subclause", + /* 340 */ "resolvetype ::= raisetype", + /* 341 */ "selectnowith ::= oneselect", + /* 342 */ "oneselect ::= values", + /* 343 */ "sclp ::= selcollist COMMA", + /* 344 */ "as ::= ID|STRING", + /* 345 */ "expr ::= term", + /* 346 */ "likeop ::= LIKE_KW|MATCH", + /* 347 */ "exprlist ::= nexprlist", + /* 348 */ "nmnum ::= plus_num", + /* 349 */ "nmnum ::= nm", + /* 350 */ "nmnum ::= ON", + /* 351 */ "nmnum ::= DELETE", + /* 352 */ "nmnum ::= DEFAULT", + /* 353 */ "plus_num ::= INTEGER|FLOAT", + /* 354 */ "foreach_clause ::=", + /* 355 */ "foreach_clause ::= FOR EACH ROW", + /* 356 */ "trnm ::= nm", + /* 357 */ "tridxby ::=", + /* 358 */ "database_kw_opt ::= DATABASE", + /* 359 */ "database_kw_opt ::=", + /* 360 */ "kwcolumn_opt ::=", + /* 361 */ "kwcolumn_opt ::= COLUMNKW", + /* 362 */ "vtabarglist ::= vtabarg", + /* 363 */ "vtabarglist ::= vtabarglist COMMA vtabarg", + /* 364 */ "vtabarg ::= vtabarg vtabargtoken", + /* 365 */ "anylist ::=", + /* 366 */ "anylist ::= anylist LP anylist RP", + /* 367 */ "anylist ::= anylist ANY", + /* 368 */ "with ::=", }; #endif /* NDEBUG */ @@ -148702,7 +149220,7 @@ static void yy_destructor( case 207: /* oneselect */ case 219: /* values */ { -sqlite3SelectDelete(pParse->db, (yypminor->yy489)); +sqlite3SelectDelete(pParse->db, (yypminor->yy423)); } break; case 184: /* term */ @@ -148712,11 +149230,12 @@ sqlite3SelectDelete(pParse->db, (yypminor->yy489)); case 227: /* on_opt */ case 242: /* case_operand */ case 244: /* case_else */ - case 253: /* when_clause */ - case 258: /* key_opt */ - case 272: /* filter_opt */ + case 247: /* vinto */ + case 254: /* when_clause */ + case 259: /* key_opt */ + case 273: /* filter_opt */ { -sqlite3ExprDelete(pParse->db, (yypminor->yy18)); +sqlite3ExprDelete(pParse->db, (yypminor->yy490)); } break; case 189: /* eidlist_opt */ @@ -148731,9 +149250,9 @@ sqlite3ExprDelete(pParse->db, (yypminor->yy18)); case 233: /* setlist */ case 241: /* paren_exprlist */ case 243: /* case_exprlist */ - case 271: /* part_opt */ + case 272: /* part_opt */ { -sqlite3ExprListDelete(pParse->db, (yypminor->yy420)); +sqlite3ExprListDelete(pParse->db, (yypminor->yy42)); } break; case 205: /* fullname */ @@ -148742,51 +149261,51 @@ sqlite3ExprListDelete(pParse->db, (yypminor->yy420)); case 224: /* stl_prefix */ case 230: /* xfullname */ { -sqlite3SrcListDelete(pParse->db, (yypminor->yy135)); +sqlite3SrcListDelete(pParse->db, (yypminor->yy167)); } break; case 208: /* wqlist */ { -sqlite3WithDelete(pParse->db, (yypminor->yy449)); +sqlite3WithDelete(pParse->db, (yypminor->yy499)); } break; case 218: /* window_clause */ - case 267: /* windowdefn_list */ + case 268: /* windowdefn_list */ { -sqlite3WindowListDelete(pParse->db, (yypminor->yy327)); +sqlite3WindowListDelete(pParse->db, (yypminor->yy147)); } break; case 228: /* using_opt */ case 231: /* idlist */ case 235: /* idlist_opt */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy48)); +sqlite3IdListDelete(pParse->db, (yypminor->yy336)); } break; case 237: /* over_clause */ - case 268: /* windowdefn */ - case 269: /* window */ - case 270: /* frame_opt */ + case 269: /* windowdefn */ + case 270: /* window */ + case 271: /* frame_opt */ { -sqlite3WindowDelete(pParse->db, (yypminor->yy327)); +sqlite3WindowDelete(pParse->db, (yypminor->yy147)); } break; - case 249: /* trigger_cmd_list */ - case 254: /* trigger_cmd */ + case 250: /* trigger_cmd_list */ + case 255: /* trigger_cmd */ { -sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy207)); +sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy119)); } break; - case 251: /* trigger_event */ + case 252: /* trigger_event */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy34).b); +sqlite3IdListDelete(pParse->db, (yypminor->yy350).b); } break; - case 274: /* frame_bound */ - case 275: /* frame_bound_s */ - case 276: /* frame_bound_e */ + case 275: /* frame_bound */ + case 276: /* frame_bound_s */ + case 277: /* frame_bound_e */ { -sqlite3ExprDelete(pParse->db, (yypminor->yy119).pExpr); +sqlite3ExprDelete(pParse->db, (yypminor->yy317).pExpr); } break; /********* End destructor definitions *****************************************/ @@ -149078,380 +149597,752 @@ static void yy_shift( yyTraceShift(yypParser, yyNewState, "Shift"); } -/* The following table contains information about every rule that -** is used during the reduce. -*/ -static const struct { - YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ - signed char nrhs; /* Negative of the number of RHS symbols in the rule */ -} yyRuleInfo[] = { - { 159, -1 }, /* (0) explain ::= EXPLAIN */ - { 159, -3 }, /* (1) explain ::= EXPLAIN QUERY PLAN */ - { 158, -1 }, /* (2) cmdx ::= cmd */ - { 160, -3 }, /* (3) cmd ::= BEGIN transtype trans_opt */ - { 161, 0 }, /* (4) transtype ::= */ - { 161, -1 }, /* (5) transtype ::= DEFERRED */ - { 161, -1 }, /* (6) transtype ::= IMMEDIATE */ - { 161, -1 }, /* (7) transtype ::= EXCLUSIVE */ - { 160, -2 }, /* (8) cmd ::= COMMIT|END trans_opt */ - { 160, -2 }, /* (9) cmd ::= ROLLBACK trans_opt */ - { 160, -2 }, /* (10) cmd ::= SAVEPOINT nm */ - { 160, -3 }, /* (11) cmd ::= RELEASE savepoint_opt nm */ - { 160, -5 }, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ - { 165, -6 }, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */ - { 167, -1 }, /* (14) createkw ::= CREATE */ - { 169, 0 }, /* (15) ifnotexists ::= */ - { 169, -3 }, /* (16) ifnotexists ::= IF NOT EXISTS */ - { 168, -1 }, /* (17) temp ::= TEMP */ - { 168, 0 }, /* (18) temp ::= */ - { 166, -5 }, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_options */ - { 166, -2 }, /* (20) create_table_args ::= AS select */ - { 173, 0 }, /* (21) table_options ::= */ - { 173, -2 }, /* (22) table_options ::= WITHOUT nm */ - { 175, -2 }, /* (23) columnname ::= nm typetoken */ - { 177, 0 }, /* (24) typetoken ::= */ - { 177, -4 }, /* (25) typetoken ::= typename LP signed RP */ - { 177, -6 }, /* (26) typetoken ::= typename LP signed COMMA signed RP */ - { 178, -2 }, /* (27) typename ::= typename ID|STRING */ - { 182, 0 }, /* (28) scanpt ::= */ - { 183, -2 }, /* (29) ccons ::= CONSTRAINT nm */ - { 183, -4 }, /* (30) ccons ::= DEFAULT scanpt term scanpt */ - { 183, -4 }, /* (31) ccons ::= DEFAULT LP expr RP */ - { 183, -4 }, /* (32) ccons ::= DEFAULT PLUS term scanpt */ - { 183, -4 }, /* (33) ccons ::= DEFAULT MINUS term scanpt */ - { 183, -3 }, /* (34) ccons ::= DEFAULT scanpt ID|INDEXED */ - { 183, -3 }, /* (35) ccons ::= NOT NULL onconf */ - { 183, -5 }, /* (36) ccons ::= PRIMARY KEY sortorder onconf autoinc */ - { 183, -2 }, /* (37) ccons ::= UNIQUE onconf */ - { 183, -4 }, /* (38) ccons ::= CHECK LP expr RP */ - { 183, -4 }, /* (39) ccons ::= REFERENCES nm eidlist_opt refargs */ - { 183, -1 }, /* (40) ccons ::= defer_subclause */ - { 183, -2 }, /* (41) ccons ::= COLLATE ID|STRING */ - { 188, 0 }, /* (42) autoinc ::= */ - { 188, -1 }, /* (43) autoinc ::= AUTOINCR */ - { 190, 0 }, /* (44) refargs ::= */ - { 190, -2 }, /* (45) refargs ::= refargs refarg */ - { 192, -2 }, /* (46) refarg ::= MATCH nm */ - { 192, -3 }, /* (47) refarg ::= ON INSERT refact */ - { 192, -3 }, /* (48) refarg ::= ON DELETE refact */ - { 192, -3 }, /* (49) refarg ::= ON UPDATE refact */ - { 193, -2 }, /* (50) refact ::= SET NULL */ - { 193, -2 }, /* (51) refact ::= SET DEFAULT */ - { 193, -1 }, /* (52) refact ::= CASCADE */ - { 193, -1 }, /* (53) refact ::= RESTRICT */ - { 193, -2 }, /* (54) refact ::= NO ACTION */ - { 191, -3 }, /* (55) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ - { 191, -2 }, /* (56) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ - { 194, 0 }, /* (57) init_deferred_pred_opt ::= */ - { 194, -2 }, /* (58) init_deferred_pred_opt ::= INITIALLY DEFERRED */ - { 194, -2 }, /* (59) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ - { 172, 0 }, /* (60) conslist_opt ::= */ - { 196, -1 }, /* (61) tconscomma ::= COMMA */ - { 197, -2 }, /* (62) tcons ::= CONSTRAINT nm */ - { 197, -7 }, /* (63) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ - { 197, -5 }, /* (64) tcons ::= UNIQUE LP sortlist RP onconf */ - { 197, -5 }, /* (65) tcons ::= CHECK LP expr RP onconf */ - { 197, -10 }, /* (66) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ - { 200, 0 }, /* (67) defer_subclause_opt ::= */ - { 186, 0 }, /* (68) onconf ::= */ - { 186, -3 }, /* (69) onconf ::= ON CONFLICT resolvetype */ - { 201, 0 }, /* (70) orconf ::= */ - { 201, -2 }, /* (71) orconf ::= OR resolvetype */ - { 202, -1 }, /* (72) resolvetype ::= IGNORE */ - { 202, -1 }, /* (73) resolvetype ::= REPLACE */ - { 160, -4 }, /* (74) cmd ::= DROP TABLE ifexists fullname */ - { 204, -2 }, /* (75) ifexists ::= IF EXISTS */ - { 204, 0 }, /* (76) ifexists ::= */ - { 160, -9 }, /* (77) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ - { 160, -4 }, /* (78) cmd ::= DROP VIEW ifexists fullname */ - { 160, -1 }, /* (79) cmd ::= select */ - { 174, -3 }, /* (80) select ::= WITH wqlist selectnowith */ - { 174, -4 }, /* (81) select ::= WITH RECURSIVE wqlist selectnowith */ - { 174, -1 }, /* (82) select ::= selectnowith */ - { 206, -3 }, /* (83) selectnowith ::= selectnowith multiselect_op oneselect */ - { 209, -1 }, /* (84) multiselect_op ::= UNION */ - { 209, -2 }, /* (85) multiselect_op ::= UNION ALL */ - { 209, -1 }, /* (86) multiselect_op ::= EXCEPT|INTERSECT */ - { 207, -9 }, /* (87) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ - { 207, -10 }, /* (88) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ - { 219, -4 }, /* (89) values ::= VALUES LP nexprlist RP */ - { 219, -5 }, /* (90) values ::= values COMMA LP nexprlist RP */ - { 210, -1 }, /* (91) distinct ::= DISTINCT */ - { 210, -1 }, /* (92) distinct ::= ALL */ - { 210, 0 }, /* (93) distinct ::= */ - { 221, 0 }, /* (94) sclp ::= */ - { 211, -5 }, /* (95) selcollist ::= sclp scanpt expr scanpt as */ - { 211, -3 }, /* (96) selcollist ::= sclp scanpt STAR */ - { 211, -5 }, /* (97) selcollist ::= sclp scanpt nm DOT STAR */ - { 222, -2 }, /* (98) as ::= AS nm */ - { 222, 0 }, /* (99) as ::= */ - { 212, 0 }, /* (100) from ::= */ - { 212, -2 }, /* (101) from ::= FROM seltablist */ - { 224, -2 }, /* (102) stl_prefix ::= seltablist joinop */ - { 224, 0 }, /* (103) stl_prefix ::= */ - { 223, -7 }, /* (104) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ - { 223, -9 }, /* (105) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ - { 223, -7 }, /* (106) seltablist ::= stl_prefix LP select RP as on_opt using_opt */ - { 223, -7 }, /* (107) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ - { 170, 0 }, /* (108) dbnm ::= */ - { 170, -2 }, /* (109) dbnm ::= DOT nm */ - { 205, -1 }, /* (110) fullname ::= nm */ - { 205, -3 }, /* (111) fullname ::= nm DOT nm */ - { 230, -1 }, /* (112) xfullname ::= nm */ - { 230, -3 }, /* (113) xfullname ::= nm DOT nm */ - { 230, -5 }, /* (114) xfullname ::= nm DOT nm AS nm */ - { 230, -3 }, /* (115) xfullname ::= nm AS nm */ - { 225, -1 }, /* (116) joinop ::= COMMA|JOIN */ - { 225, -2 }, /* (117) joinop ::= JOIN_KW JOIN */ - { 225, -3 }, /* (118) joinop ::= JOIN_KW nm JOIN */ - { 225, -4 }, /* (119) joinop ::= JOIN_KW nm nm JOIN */ - { 227, -2 }, /* (120) on_opt ::= ON expr */ - { 227, 0 }, /* (121) on_opt ::= */ - { 226, 0 }, /* (122) indexed_opt ::= */ - { 226, -3 }, /* (123) indexed_opt ::= INDEXED BY nm */ - { 226, -2 }, /* (124) indexed_opt ::= NOT INDEXED */ - { 228, -4 }, /* (125) using_opt ::= USING LP idlist RP */ - { 228, 0 }, /* (126) using_opt ::= */ - { 216, 0 }, /* (127) orderby_opt ::= */ - { 216, -3 }, /* (128) orderby_opt ::= ORDER BY sortlist */ - { 198, -4 }, /* (129) sortlist ::= sortlist COMMA expr sortorder */ - { 198, -2 }, /* (130) sortlist ::= expr sortorder */ - { 187, -1 }, /* (131) sortorder ::= ASC */ - { 187, -1 }, /* (132) sortorder ::= DESC */ - { 187, 0 }, /* (133) sortorder ::= */ - { 214, 0 }, /* (134) groupby_opt ::= */ - { 214, -3 }, /* (135) groupby_opt ::= GROUP BY nexprlist */ - { 215, 0 }, /* (136) having_opt ::= */ - { 215, -2 }, /* (137) having_opt ::= HAVING expr */ - { 217, 0 }, /* (138) limit_opt ::= */ - { 217, -2 }, /* (139) limit_opt ::= LIMIT expr */ - { 217, -4 }, /* (140) limit_opt ::= LIMIT expr OFFSET expr */ - { 217, -4 }, /* (141) limit_opt ::= LIMIT expr COMMA expr */ - { 160, -6 }, /* (142) cmd ::= with DELETE FROM xfullname indexed_opt where_opt */ - { 213, 0 }, /* (143) where_opt ::= */ - { 213, -2 }, /* (144) where_opt ::= WHERE expr */ - { 160, -8 }, /* (145) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */ - { 233, -5 }, /* (146) setlist ::= setlist COMMA nm EQ expr */ - { 233, -7 }, /* (147) setlist ::= setlist COMMA LP idlist RP EQ expr */ - { 233, -3 }, /* (148) setlist ::= nm EQ expr */ - { 233, -5 }, /* (149) setlist ::= LP idlist RP EQ expr */ - { 160, -7 }, /* (150) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ - { 160, -7 }, /* (151) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */ - { 236, 0 }, /* (152) upsert ::= */ - { 236, -11 }, /* (153) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */ - { 236, -8 }, /* (154) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */ - { 236, -4 }, /* (155) upsert ::= ON CONFLICT DO NOTHING */ - { 234, -2 }, /* (156) insert_cmd ::= INSERT orconf */ - { 234, -1 }, /* (157) insert_cmd ::= REPLACE */ - { 235, 0 }, /* (158) idlist_opt ::= */ - { 235, -3 }, /* (159) idlist_opt ::= LP idlist RP */ - { 231, -3 }, /* (160) idlist ::= idlist COMMA nm */ - { 231, -1 }, /* (161) idlist ::= nm */ - { 185, -3 }, /* (162) expr ::= LP expr RP */ - { 185, -1 }, /* (163) expr ::= ID|INDEXED */ - { 185, -1 }, /* (164) expr ::= JOIN_KW */ - { 185, -3 }, /* (165) expr ::= nm DOT nm */ - { 185, -5 }, /* (166) expr ::= nm DOT nm DOT nm */ - { 184, -1 }, /* (167) term ::= NULL|FLOAT|BLOB */ - { 184, -1 }, /* (168) term ::= STRING */ - { 184, -1 }, /* (169) term ::= INTEGER */ - { 185, -1 }, /* (170) expr ::= VARIABLE */ - { 185, -3 }, /* (171) expr ::= expr COLLATE ID|STRING */ - { 185, -6 }, /* (172) expr ::= CAST LP expr AS typetoken RP */ - { 185, -5 }, /* (173) expr ::= ID|INDEXED LP distinct exprlist RP */ - { 185, -4 }, /* (174) expr ::= ID|INDEXED LP STAR RP */ - { 185, -6 }, /* (175) expr ::= ID|INDEXED LP distinct exprlist RP over_clause */ - { 185, -5 }, /* (176) expr ::= ID|INDEXED LP STAR RP over_clause */ - { 184, -1 }, /* (177) term ::= CTIME_KW */ - { 185, -5 }, /* (178) expr ::= LP nexprlist COMMA expr RP */ - { 185, -3 }, /* (179) expr ::= expr AND expr */ - { 185, -3 }, /* (180) expr ::= expr OR expr */ - { 185, -3 }, /* (181) expr ::= expr LT|GT|GE|LE expr */ - { 185, -3 }, /* (182) expr ::= expr EQ|NE expr */ - { 185, -3 }, /* (183) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ - { 185, -3 }, /* (184) expr ::= expr PLUS|MINUS expr */ - { 185, -3 }, /* (185) expr ::= expr STAR|SLASH|REM expr */ - { 185, -3 }, /* (186) expr ::= expr CONCAT expr */ - { 238, -2 }, /* (187) likeop ::= NOT LIKE_KW|MATCH */ - { 185, -3 }, /* (188) expr ::= expr likeop expr */ - { 185, -5 }, /* (189) expr ::= expr likeop expr ESCAPE expr */ - { 185, -2 }, /* (190) expr ::= expr ISNULL|NOTNULL */ - { 185, -3 }, /* (191) expr ::= expr NOT NULL */ - { 185, -3 }, /* (192) expr ::= expr IS expr */ - { 185, -4 }, /* (193) expr ::= expr IS NOT expr */ - { 185, -2 }, /* (194) expr ::= NOT expr */ - { 185, -2 }, /* (195) expr ::= BITNOT expr */ - { 185, -2 }, /* (196) expr ::= PLUS|MINUS expr */ - { 239, -1 }, /* (197) between_op ::= BETWEEN */ - { 239, -2 }, /* (198) between_op ::= NOT BETWEEN */ - { 185, -5 }, /* (199) expr ::= expr between_op expr AND expr */ - { 240, -1 }, /* (200) in_op ::= IN */ - { 240, -2 }, /* (201) in_op ::= NOT IN */ - { 185, -5 }, /* (202) expr ::= expr in_op LP exprlist RP */ - { 185, -3 }, /* (203) expr ::= LP select RP */ - { 185, -5 }, /* (204) expr ::= expr in_op LP select RP */ - { 185, -5 }, /* (205) expr ::= expr in_op nm dbnm paren_exprlist */ - { 185, -4 }, /* (206) expr ::= EXISTS LP select RP */ - { 185, -5 }, /* (207) expr ::= CASE case_operand case_exprlist case_else END */ - { 243, -5 }, /* (208) case_exprlist ::= case_exprlist WHEN expr THEN expr */ - { 243, -4 }, /* (209) case_exprlist ::= WHEN expr THEN expr */ - { 244, -2 }, /* (210) case_else ::= ELSE expr */ - { 244, 0 }, /* (211) case_else ::= */ - { 242, -1 }, /* (212) case_operand ::= expr */ - { 242, 0 }, /* (213) case_operand ::= */ - { 229, 0 }, /* (214) exprlist ::= */ - { 220, -3 }, /* (215) nexprlist ::= nexprlist COMMA expr */ - { 220, -1 }, /* (216) nexprlist ::= expr */ - { 241, 0 }, /* (217) paren_exprlist ::= */ - { 241, -3 }, /* (218) paren_exprlist ::= LP exprlist RP */ - { 160, -12 }, /* (219) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ - { 245, -1 }, /* (220) uniqueflag ::= UNIQUE */ - { 245, 0 }, /* (221) uniqueflag ::= */ - { 189, 0 }, /* (222) eidlist_opt ::= */ - { 189, -3 }, /* (223) eidlist_opt ::= LP eidlist RP */ - { 199, -5 }, /* (224) eidlist ::= eidlist COMMA nm collate sortorder */ - { 199, -3 }, /* (225) eidlist ::= nm collate sortorder */ - { 246, 0 }, /* (226) collate ::= */ - { 246, -2 }, /* (227) collate ::= COLLATE ID|STRING */ - { 160, -4 }, /* (228) cmd ::= DROP INDEX ifexists fullname */ - { 160, -1 }, /* (229) cmd ::= VACUUM */ - { 160, -2 }, /* (230) cmd ::= VACUUM nm */ - { 160, -3 }, /* (231) cmd ::= PRAGMA nm dbnm */ - { 160, -5 }, /* (232) cmd ::= PRAGMA nm dbnm EQ nmnum */ - { 160, -6 }, /* (233) cmd ::= PRAGMA nm dbnm LP nmnum RP */ - { 160, -5 }, /* (234) cmd ::= PRAGMA nm dbnm EQ minus_num */ - { 160, -6 }, /* (235) cmd ::= PRAGMA nm dbnm LP minus_num RP */ - { 180, -2 }, /* (236) plus_num ::= PLUS INTEGER|FLOAT */ - { 181, -2 }, /* (237) minus_num ::= MINUS INTEGER|FLOAT */ - { 160, -5 }, /* (238) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ - { 248, -11 }, /* (239) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ - { 250, -1 }, /* (240) trigger_time ::= BEFORE|AFTER */ - { 250, -2 }, /* (241) trigger_time ::= INSTEAD OF */ - { 250, 0 }, /* (242) trigger_time ::= */ - { 251, -1 }, /* (243) trigger_event ::= DELETE|INSERT */ - { 251, -1 }, /* (244) trigger_event ::= UPDATE */ - { 251, -3 }, /* (245) trigger_event ::= UPDATE OF idlist */ - { 253, 0 }, /* (246) when_clause ::= */ - { 253, -2 }, /* (247) when_clause ::= WHEN expr */ - { 249, -3 }, /* (248) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ - { 249, -2 }, /* (249) trigger_cmd_list ::= trigger_cmd SEMI */ - { 255, -3 }, /* (250) trnm ::= nm DOT nm */ - { 256, -3 }, /* (251) tridxby ::= INDEXED BY nm */ - { 256, -2 }, /* (252) tridxby ::= NOT INDEXED */ - { 254, -8 }, /* (253) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */ - { 254, -8 }, /* (254) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ - { 254, -6 }, /* (255) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ - { 254, -3 }, /* (256) trigger_cmd ::= scanpt select scanpt */ - { 185, -4 }, /* (257) expr ::= RAISE LP IGNORE RP */ - { 185, -6 }, /* (258) expr ::= RAISE LP raisetype COMMA nm RP */ - { 203, -1 }, /* (259) raisetype ::= ROLLBACK */ - { 203, -1 }, /* (260) raisetype ::= ABORT */ - { 203, -1 }, /* (261) raisetype ::= FAIL */ - { 160, -4 }, /* (262) cmd ::= DROP TRIGGER ifexists fullname */ - { 160, -6 }, /* (263) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ - { 160, -3 }, /* (264) cmd ::= DETACH database_kw_opt expr */ - { 258, 0 }, /* (265) key_opt ::= */ - { 258, -2 }, /* (266) key_opt ::= KEY expr */ - { 160, -1 }, /* (267) cmd ::= REINDEX */ - { 160, -3 }, /* (268) cmd ::= REINDEX nm dbnm */ - { 160, -1 }, /* (269) cmd ::= ANALYZE */ - { 160, -3 }, /* (270) cmd ::= ANALYZE nm dbnm */ - { 160, -6 }, /* (271) cmd ::= ALTER TABLE fullname RENAME TO nm */ - { 160, -7 }, /* (272) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ - { 259, -1 }, /* (273) add_column_fullname ::= fullname */ - { 160, -8 }, /* (274) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ - { 160, -1 }, /* (275) cmd ::= create_vtab */ - { 160, -4 }, /* (276) cmd ::= create_vtab LP vtabarglist RP */ - { 261, -8 }, /* (277) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ - { 263, 0 }, /* (278) vtabarg ::= */ - { 264, -1 }, /* (279) vtabargtoken ::= ANY */ - { 264, -3 }, /* (280) vtabargtoken ::= lp anylist RP */ - { 265, -1 }, /* (281) lp ::= LP */ - { 232, -2 }, /* (282) with ::= WITH wqlist */ - { 232, -3 }, /* (283) with ::= WITH RECURSIVE wqlist */ - { 208, -6 }, /* (284) wqlist ::= nm eidlist_opt AS LP select RP */ - { 208, -8 }, /* (285) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */ - { 267, -1 }, /* (286) windowdefn_list ::= windowdefn */ - { 267, -3 }, /* (287) windowdefn_list ::= windowdefn_list COMMA windowdefn */ - { 268, -3 }, /* (288) windowdefn ::= nm AS window */ - { 269, -5 }, /* (289) window ::= LP part_opt orderby_opt frame_opt RP */ - { 271, -3 }, /* (290) part_opt ::= PARTITION BY nexprlist */ - { 271, 0 }, /* (291) part_opt ::= */ - { 270, 0 }, /* (292) frame_opt ::= */ - { 270, -2 }, /* (293) frame_opt ::= range_or_rows frame_bound_s */ - { 270, -5 }, /* (294) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e */ - { 273, -1 }, /* (295) range_or_rows ::= RANGE */ - { 273, -1 }, /* (296) range_or_rows ::= ROWS */ - { 275, -1 }, /* (297) frame_bound_s ::= frame_bound */ - { 275, -2 }, /* (298) frame_bound_s ::= UNBOUNDED PRECEDING */ - { 276, -1 }, /* (299) frame_bound_e ::= frame_bound */ - { 276, -2 }, /* (300) frame_bound_e ::= UNBOUNDED FOLLOWING */ - { 274, -2 }, /* (301) frame_bound ::= expr PRECEDING */ - { 274, -2 }, /* (302) frame_bound ::= CURRENT ROW */ - { 274, -2 }, /* (303) frame_bound ::= expr FOLLOWING */ - { 218, -2 }, /* (304) window_clause ::= WINDOW windowdefn_list */ - { 237, -3 }, /* (305) over_clause ::= filter_opt OVER window */ - { 237, -3 }, /* (306) over_clause ::= filter_opt OVER nm */ - { 272, 0 }, /* (307) filter_opt ::= */ - { 272, -5 }, /* (308) filter_opt ::= FILTER LP WHERE expr RP */ - { 155, -1 }, /* (309) input ::= cmdlist */ - { 156, -2 }, /* (310) cmdlist ::= cmdlist ecmd */ - { 156, -1 }, /* (311) cmdlist ::= ecmd */ - { 157, -1 }, /* (312) ecmd ::= SEMI */ - { 157, -2 }, /* (313) ecmd ::= cmdx SEMI */ - { 157, -2 }, /* (314) ecmd ::= explain cmdx */ - { 162, 0 }, /* (315) trans_opt ::= */ - { 162, -1 }, /* (316) trans_opt ::= TRANSACTION */ - { 162, -2 }, /* (317) trans_opt ::= TRANSACTION nm */ - { 164, -1 }, /* (318) savepoint_opt ::= SAVEPOINT */ - { 164, 0 }, /* (319) savepoint_opt ::= */ - { 160, -2 }, /* (320) cmd ::= create_table create_table_args */ - { 171, -4 }, /* (321) columnlist ::= columnlist COMMA columnname carglist */ - { 171, -2 }, /* (322) columnlist ::= columnname carglist */ - { 163, -1 }, /* (323) nm ::= ID|INDEXED */ - { 163, -1 }, /* (324) nm ::= STRING */ - { 163, -1 }, /* (325) nm ::= JOIN_KW */ - { 177, -1 }, /* (326) typetoken ::= typename */ - { 178, -1 }, /* (327) typename ::= ID|STRING */ - { 179, -1 }, /* (328) signed ::= plus_num */ - { 179, -1 }, /* (329) signed ::= minus_num */ - { 176, -2 }, /* (330) carglist ::= carglist ccons */ - { 176, 0 }, /* (331) carglist ::= */ - { 183, -2 }, /* (332) ccons ::= NULL onconf */ - { 172, -2 }, /* (333) conslist_opt ::= COMMA conslist */ - { 195, -3 }, /* (334) conslist ::= conslist tconscomma tcons */ - { 195, -1 }, /* (335) conslist ::= tcons */ - { 196, 0 }, /* (336) tconscomma ::= */ - { 200, -1 }, /* (337) defer_subclause_opt ::= defer_subclause */ - { 202, -1 }, /* (338) resolvetype ::= raisetype */ - { 206, -1 }, /* (339) selectnowith ::= oneselect */ - { 207, -1 }, /* (340) oneselect ::= values */ - { 221, -2 }, /* (341) sclp ::= selcollist COMMA */ - { 222, -1 }, /* (342) as ::= ID|STRING */ - { 185, -1 }, /* (343) expr ::= term */ - { 238, -1 }, /* (344) likeop ::= LIKE_KW|MATCH */ - { 229, -1 }, /* (345) exprlist ::= nexprlist */ - { 247, -1 }, /* (346) nmnum ::= plus_num */ - { 247, -1 }, /* (347) nmnum ::= nm */ - { 247, -1 }, /* (348) nmnum ::= ON */ - { 247, -1 }, /* (349) nmnum ::= DELETE */ - { 247, -1 }, /* (350) nmnum ::= DEFAULT */ - { 180, -1 }, /* (351) plus_num ::= INTEGER|FLOAT */ - { 252, 0 }, /* (352) foreach_clause ::= */ - { 252, -3 }, /* (353) foreach_clause ::= FOR EACH ROW */ - { 255, -1 }, /* (354) trnm ::= nm */ - { 256, 0 }, /* (355) tridxby ::= */ - { 257, -1 }, /* (356) database_kw_opt ::= DATABASE */ - { 257, 0 }, /* (357) database_kw_opt ::= */ - { 260, 0 }, /* (358) kwcolumn_opt ::= */ - { 260, -1 }, /* (359) kwcolumn_opt ::= COLUMNKW */ - { 262, -1 }, /* (360) vtabarglist ::= vtabarg */ - { 262, -3 }, /* (361) vtabarglist ::= vtabarglist COMMA vtabarg */ - { 263, -2 }, /* (362) vtabarg ::= vtabarg vtabargtoken */ - { 266, 0 }, /* (363) anylist ::= */ - { 266, -4 }, /* (364) anylist ::= anylist LP anylist RP */ - { 266, -2 }, /* (365) anylist ::= anylist ANY */ - { 232, 0 }, /* (366) with ::= */ +/* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side +** of that rule */ +static const YYCODETYPE yyRuleInfoLhs[] = { + 159, /* (0) explain ::= EXPLAIN */ + 159, /* (1) explain ::= EXPLAIN QUERY PLAN */ + 158, /* (2) cmdx ::= cmd */ + 160, /* (3) cmd ::= BEGIN transtype trans_opt */ + 161, /* (4) transtype ::= */ + 161, /* (5) transtype ::= DEFERRED */ + 161, /* (6) transtype ::= IMMEDIATE */ + 161, /* (7) transtype ::= EXCLUSIVE */ + 160, /* (8) cmd ::= COMMIT|END trans_opt */ + 160, /* (9) cmd ::= ROLLBACK trans_opt */ + 160, /* (10) cmd ::= SAVEPOINT nm */ + 160, /* (11) cmd ::= RELEASE savepoint_opt nm */ + 160, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ + 165, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */ + 167, /* (14) createkw ::= CREATE */ + 169, /* (15) ifnotexists ::= */ + 169, /* (16) ifnotexists ::= IF NOT EXISTS */ + 168, /* (17) temp ::= TEMP */ + 168, /* (18) temp ::= */ + 166, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_options */ + 166, /* (20) create_table_args ::= AS select */ + 173, /* (21) table_options ::= */ + 173, /* (22) table_options ::= WITHOUT nm */ + 175, /* (23) columnname ::= nm typetoken */ + 177, /* (24) typetoken ::= */ + 177, /* (25) typetoken ::= typename LP signed RP */ + 177, /* (26) typetoken ::= typename LP signed COMMA signed RP */ + 178, /* (27) typename ::= typename ID|STRING */ + 182, /* (28) scanpt ::= */ + 183, /* (29) ccons ::= CONSTRAINT nm */ + 183, /* (30) ccons ::= DEFAULT scanpt term scanpt */ + 183, /* (31) ccons ::= DEFAULT LP expr RP */ + 183, /* (32) ccons ::= DEFAULT PLUS term scanpt */ + 183, /* (33) ccons ::= DEFAULT MINUS term scanpt */ + 183, /* (34) ccons ::= DEFAULT scanpt ID|INDEXED */ + 183, /* (35) ccons ::= NOT NULL onconf */ + 183, /* (36) ccons ::= PRIMARY KEY sortorder onconf autoinc */ + 183, /* (37) ccons ::= UNIQUE onconf */ + 183, /* (38) ccons ::= CHECK LP expr RP */ + 183, /* (39) ccons ::= REFERENCES nm eidlist_opt refargs */ + 183, /* (40) ccons ::= defer_subclause */ + 183, /* (41) ccons ::= COLLATE ID|STRING */ + 188, /* (42) autoinc ::= */ + 188, /* (43) autoinc ::= AUTOINCR */ + 190, /* (44) refargs ::= */ + 190, /* (45) refargs ::= refargs refarg */ + 192, /* (46) refarg ::= MATCH nm */ + 192, /* (47) refarg ::= ON INSERT refact */ + 192, /* (48) refarg ::= ON DELETE refact */ + 192, /* (49) refarg ::= ON UPDATE refact */ + 193, /* (50) refact ::= SET NULL */ + 193, /* (51) refact ::= SET DEFAULT */ + 193, /* (52) refact ::= CASCADE */ + 193, /* (53) refact ::= RESTRICT */ + 193, /* (54) refact ::= NO ACTION */ + 191, /* (55) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ + 191, /* (56) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ + 194, /* (57) init_deferred_pred_opt ::= */ + 194, /* (58) init_deferred_pred_opt ::= INITIALLY DEFERRED */ + 194, /* (59) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ + 172, /* (60) conslist_opt ::= */ + 196, /* (61) tconscomma ::= COMMA */ + 197, /* (62) tcons ::= CONSTRAINT nm */ + 197, /* (63) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ + 197, /* (64) tcons ::= UNIQUE LP sortlist RP onconf */ + 197, /* (65) tcons ::= CHECK LP expr RP onconf */ + 197, /* (66) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ + 200, /* (67) defer_subclause_opt ::= */ + 186, /* (68) onconf ::= */ + 186, /* (69) onconf ::= ON CONFLICT resolvetype */ + 201, /* (70) orconf ::= */ + 201, /* (71) orconf ::= OR resolvetype */ + 202, /* (72) resolvetype ::= IGNORE */ + 202, /* (73) resolvetype ::= REPLACE */ + 160, /* (74) cmd ::= DROP TABLE ifexists fullname */ + 204, /* (75) ifexists ::= IF EXISTS */ + 204, /* (76) ifexists ::= */ + 160, /* (77) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ + 160, /* (78) cmd ::= DROP VIEW ifexists fullname */ + 160, /* (79) cmd ::= select */ + 174, /* (80) select ::= WITH wqlist selectnowith */ + 174, /* (81) select ::= WITH RECURSIVE wqlist selectnowith */ + 174, /* (82) select ::= selectnowith */ + 206, /* (83) selectnowith ::= selectnowith multiselect_op oneselect */ + 209, /* (84) multiselect_op ::= UNION */ + 209, /* (85) multiselect_op ::= UNION ALL */ + 209, /* (86) multiselect_op ::= EXCEPT|INTERSECT */ + 207, /* (87) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ + 207, /* (88) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ + 219, /* (89) values ::= VALUES LP nexprlist RP */ + 219, /* (90) values ::= values COMMA LP nexprlist RP */ + 210, /* (91) distinct ::= DISTINCT */ + 210, /* (92) distinct ::= ALL */ + 210, /* (93) distinct ::= */ + 221, /* (94) sclp ::= */ + 211, /* (95) selcollist ::= sclp scanpt expr scanpt as */ + 211, /* (96) selcollist ::= sclp scanpt STAR */ + 211, /* (97) selcollist ::= sclp scanpt nm DOT STAR */ + 222, /* (98) as ::= AS nm */ + 222, /* (99) as ::= */ + 212, /* (100) from ::= */ + 212, /* (101) from ::= FROM seltablist */ + 224, /* (102) stl_prefix ::= seltablist joinop */ + 224, /* (103) stl_prefix ::= */ + 223, /* (104) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ + 223, /* (105) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ + 223, /* (106) seltablist ::= stl_prefix LP select RP as on_opt using_opt */ + 223, /* (107) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ + 170, /* (108) dbnm ::= */ + 170, /* (109) dbnm ::= DOT nm */ + 205, /* (110) fullname ::= nm */ + 205, /* (111) fullname ::= nm DOT nm */ + 230, /* (112) xfullname ::= nm */ + 230, /* (113) xfullname ::= nm DOT nm */ + 230, /* (114) xfullname ::= nm DOT nm AS nm */ + 230, /* (115) xfullname ::= nm AS nm */ + 225, /* (116) joinop ::= COMMA|JOIN */ + 225, /* (117) joinop ::= JOIN_KW JOIN */ + 225, /* (118) joinop ::= JOIN_KW nm JOIN */ + 225, /* (119) joinop ::= JOIN_KW nm nm JOIN */ + 227, /* (120) on_opt ::= ON expr */ + 227, /* (121) on_opt ::= */ + 226, /* (122) indexed_opt ::= */ + 226, /* (123) indexed_opt ::= INDEXED BY nm */ + 226, /* (124) indexed_opt ::= NOT INDEXED */ + 228, /* (125) using_opt ::= USING LP idlist RP */ + 228, /* (126) using_opt ::= */ + 216, /* (127) orderby_opt ::= */ + 216, /* (128) orderby_opt ::= ORDER BY sortlist */ + 198, /* (129) sortlist ::= sortlist COMMA expr sortorder */ + 198, /* (130) sortlist ::= expr sortorder */ + 187, /* (131) sortorder ::= ASC */ + 187, /* (132) sortorder ::= DESC */ + 187, /* (133) sortorder ::= */ + 214, /* (134) groupby_opt ::= */ + 214, /* (135) groupby_opt ::= GROUP BY nexprlist */ + 215, /* (136) having_opt ::= */ + 215, /* (137) having_opt ::= HAVING expr */ + 217, /* (138) limit_opt ::= */ + 217, /* (139) limit_opt ::= LIMIT expr */ + 217, /* (140) limit_opt ::= LIMIT expr OFFSET expr */ + 217, /* (141) limit_opt ::= LIMIT expr COMMA expr */ + 160, /* (142) cmd ::= with DELETE FROM xfullname indexed_opt where_opt */ + 213, /* (143) where_opt ::= */ + 213, /* (144) where_opt ::= WHERE expr */ + 160, /* (145) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */ + 233, /* (146) setlist ::= setlist COMMA nm EQ expr */ + 233, /* (147) setlist ::= setlist COMMA LP idlist RP EQ expr */ + 233, /* (148) setlist ::= nm EQ expr */ + 233, /* (149) setlist ::= LP idlist RP EQ expr */ + 160, /* (150) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + 160, /* (151) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */ + 236, /* (152) upsert ::= */ + 236, /* (153) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */ + 236, /* (154) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */ + 236, /* (155) upsert ::= ON CONFLICT DO NOTHING */ + 234, /* (156) insert_cmd ::= INSERT orconf */ + 234, /* (157) insert_cmd ::= REPLACE */ + 235, /* (158) idlist_opt ::= */ + 235, /* (159) idlist_opt ::= LP idlist RP */ + 231, /* (160) idlist ::= idlist COMMA nm */ + 231, /* (161) idlist ::= nm */ + 185, /* (162) expr ::= LP expr RP */ + 185, /* (163) expr ::= ID|INDEXED */ + 185, /* (164) expr ::= JOIN_KW */ + 185, /* (165) expr ::= nm DOT nm */ + 185, /* (166) expr ::= nm DOT nm DOT nm */ + 184, /* (167) term ::= NULL|FLOAT|BLOB */ + 184, /* (168) term ::= STRING */ + 184, /* (169) term ::= INTEGER */ + 185, /* (170) expr ::= VARIABLE */ + 185, /* (171) expr ::= expr COLLATE ID|STRING */ + 185, /* (172) expr ::= CAST LP expr AS typetoken RP */ + 185, /* (173) expr ::= ID|INDEXED LP distinct exprlist RP */ + 185, /* (174) expr ::= ID|INDEXED LP STAR RP */ + 185, /* (175) expr ::= ID|INDEXED LP distinct exprlist RP over_clause */ + 185, /* (176) expr ::= ID|INDEXED LP STAR RP over_clause */ + 184, /* (177) term ::= CTIME_KW */ + 185, /* (178) expr ::= LP nexprlist COMMA expr RP */ + 185, /* (179) expr ::= expr AND expr */ + 185, /* (180) expr ::= expr OR expr */ + 185, /* (181) expr ::= expr LT|GT|GE|LE expr */ + 185, /* (182) expr ::= expr EQ|NE expr */ + 185, /* (183) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ + 185, /* (184) expr ::= expr PLUS|MINUS expr */ + 185, /* (185) expr ::= expr STAR|SLASH|REM expr */ + 185, /* (186) expr ::= expr CONCAT expr */ + 238, /* (187) likeop ::= NOT LIKE_KW|MATCH */ + 185, /* (188) expr ::= expr likeop expr */ + 185, /* (189) expr ::= expr likeop expr ESCAPE expr */ + 185, /* (190) expr ::= expr ISNULL|NOTNULL */ + 185, /* (191) expr ::= expr NOT NULL */ + 185, /* (192) expr ::= expr IS expr */ + 185, /* (193) expr ::= expr IS NOT expr */ + 185, /* (194) expr ::= NOT expr */ + 185, /* (195) expr ::= BITNOT expr */ + 185, /* (196) expr ::= PLUS|MINUS expr */ + 239, /* (197) between_op ::= BETWEEN */ + 239, /* (198) between_op ::= NOT BETWEEN */ + 185, /* (199) expr ::= expr between_op expr AND expr */ + 240, /* (200) in_op ::= IN */ + 240, /* (201) in_op ::= NOT IN */ + 185, /* (202) expr ::= expr in_op LP exprlist RP */ + 185, /* (203) expr ::= LP select RP */ + 185, /* (204) expr ::= expr in_op LP select RP */ + 185, /* (205) expr ::= expr in_op nm dbnm paren_exprlist */ + 185, /* (206) expr ::= EXISTS LP select RP */ + 185, /* (207) expr ::= CASE case_operand case_exprlist case_else END */ + 243, /* (208) case_exprlist ::= case_exprlist WHEN expr THEN expr */ + 243, /* (209) case_exprlist ::= WHEN expr THEN expr */ + 244, /* (210) case_else ::= ELSE expr */ + 244, /* (211) case_else ::= */ + 242, /* (212) case_operand ::= expr */ + 242, /* (213) case_operand ::= */ + 229, /* (214) exprlist ::= */ + 220, /* (215) nexprlist ::= nexprlist COMMA expr */ + 220, /* (216) nexprlist ::= expr */ + 241, /* (217) paren_exprlist ::= */ + 241, /* (218) paren_exprlist ::= LP exprlist RP */ + 160, /* (219) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + 245, /* (220) uniqueflag ::= UNIQUE */ + 245, /* (221) uniqueflag ::= */ + 189, /* (222) eidlist_opt ::= */ + 189, /* (223) eidlist_opt ::= LP eidlist RP */ + 199, /* (224) eidlist ::= eidlist COMMA nm collate sortorder */ + 199, /* (225) eidlist ::= nm collate sortorder */ + 246, /* (226) collate ::= */ + 246, /* (227) collate ::= COLLATE ID|STRING */ + 160, /* (228) cmd ::= DROP INDEX ifexists fullname */ + 160, /* (229) cmd ::= VACUUM vinto */ + 160, /* (230) cmd ::= VACUUM nm vinto */ + 247, /* (231) vinto ::= INTO expr */ + 247, /* (232) vinto ::= */ + 160, /* (233) cmd ::= PRAGMA nm dbnm */ + 160, /* (234) cmd ::= PRAGMA nm dbnm EQ nmnum */ + 160, /* (235) cmd ::= PRAGMA nm dbnm LP nmnum RP */ + 160, /* (236) cmd ::= PRAGMA nm dbnm EQ minus_num */ + 160, /* (237) cmd ::= PRAGMA nm dbnm LP minus_num RP */ + 180, /* (238) plus_num ::= PLUS INTEGER|FLOAT */ + 181, /* (239) minus_num ::= MINUS INTEGER|FLOAT */ + 160, /* (240) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + 249, /* (241) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + 251, /* (242) trigger_time ::= BEFORE|AFTER */ + 251, /* (243) trigger_time ::= INSTEAD OF */ + 251, /* (244) trigger_time ::= */ + 252, /* (245) trigger_event ::= DELETE|INSERT */ + 252, /* (246) trigger_event ::= UPDATE */ + 252, /* (247) trigger_event ::= UPDATE OF idlist */ + 254, /* (248) when_clause ::= */ + 254, /* (249) when_clause ::= WHEN expr */ + 250, /* (250) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + 250, /* (251) trigger_cmd_list ::= trigger_cmd SEMI */ + 256, /* (252) trnm ::= nm DOT nm */ + 257, /* (253) tridxby ::= INDEXED BY nm */ + 257, /* (254) tridxby ::= NOT INDEXED */ + 255, /* (255) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */ + 255, /* (256) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + 255, /* (257) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + 255, /* (258) trigger_cmd ::= scanpt select scanpt */ + 185, /* (259) expr ::= RAISE LP IGNORE RP */ + 185, /* (260) expr ::= RAISE LP raisetype COMMA nm RP */ + 203, /* (261) raisetype ::= ROLLBACK */ + 203, /* (262) raisetype ::= ABORT */ + 203, /* (263) raisetype ::= FAIL */ + 160, /* (264) cmd ::= DROP TRIGGER ifexists fullname */ + 160, /* (265) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + 160, /* (266) cmd ::= DETACH database_kw_opt expr */ + 259, /* (267) key_opt ::= */ + 259, /* (268) key_opt ::= KEY expr */ + 160, /* (269) cmd ::= REINDEX */ + 160, /* (270) cmd ::= REINDEX nm dbnm */ + 160, /* (271) cmd ::= ANALYZE */ + 160, /* (272) cmd ::= ANALYZE nm dbnm */ + 160, /* (273) cmd ::= ALTER TABLE fullname RENAME TO nm */ + 160, /* (274) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + 260, /* (275) add_column_fullname ::= fullname */ + 160, /* (276) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + 160, /* (277) cmd ::= create_vtab */ + 160, /* (278) cmd ::= create_vtab LP vtabarglist RP */ + 262, /* (279) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 264, /* (280) vtabarg ::= */ + 265, /* (281) vtabargtoken ::= ANY */ + 265, /* (282) vtabargtoken ::= lp anylist RP */ + 266, /* (283) lp ::= LP */ + 232, /* (284) with ::= WITH wqlist */ + 232, /* (285) with ::= WITH RECURSIVE wqlist */ + 208, /* (286) wqlist ::= nm eidlist_opt AS LP select RP */ + 208, /* (287) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */ + 268, /* (288) windowdefn_list ::= windowdefn */ + 268, /* (289) windowdefn_list ::= windowdefn_list COMMA windowdefn */ + 269, /* (290) windowdefn ::= nm AS window */ + 270, /* (291) window ::= LP part_opt orderby_opt frame_opt RP */ + 272, /* (292) part_opt ::= PARTITION BY nexprlist */ + 272, /* (293) part_opt ::= */ + 271, /* (294) frame_opt ::= */ + 271, /* (295) frame_opt ::= range_or_rows frame_bound_s */ + 271, /* (296) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e */ + 274, /* (297) range_or_rows ::= RANGE */ + 274, /* (298) range_or_rows ::= ROWS */ + 276, /* (299) frame_bound_s ::= frame_bound */ + 276, /* (300) frame_bound_s ::= UNBOUNDED PRECEDING */ + 277, /* (301) frame_bound_e ::= frame_bound */ + 277, /* (302) frame_bound_e ::= UNBOUNDED FOLLOWING */ + 275, /* (303) frame_bound ::= expr PRECEDING */ + 275, /* (304) frame_bound ::= CURRENT ROW */ + 275, /* (305) frame_bound ::= expr FOLLOWING */ + 218, /* (306) window_clause ::= WINDOW windowdefn_list */ + 237, /* (307) over_clause ::= filter_opt OVER window */ + 237, /* (308) over_clause ::= filter_opt OVER nm */ + 273, /* (309) filter_opt ::= */ + 273, /* (310) filter_opt ::= FILTER LP WHERE expr RP */ + 155, /* (311) input ::= cmdlist */ + 156, /* (312) cmdlist ::= cmdlist ecmd */ + 156, /* (313) cmdlist ::= ecmd */ + 157, /* (314) ecmd ::= SEMI */ + 157, /* (315) ecmd ::= cmdx SEMI */ + 157, /* (316) ecmd ::= explain cmdx */ + 162, /* (317) trans_opt ::= */ + 162, /* (318) trans_opt ::= TRANSACTION */ + 162, /* (319) trans_opt ::= TRANSACTION nm */ + 164, /* (320) savepoint_opt ::= SAVEPOINT */ + 164, /* (321) savepoint_opt ::= */ + 160, /* (322) cmd ::= create_table create_table_args */ + 171, /* (323) columnlist ::= columnlist COMMA columnname carglist */ + 171, /* (324) columnlist ::= columnname carglist */ + 163, /* (325) nm ::= ID|INDEXED */ + 163, /* (326) nm ::= STRING */ + 163, /* (327) nm ::= JOIN_KW */ + 177, /* (328) typetoken ::= typename */ + 178, /* (329) typename ::= ID|STRING */ + 179, /* (330) signed ::= plus_num */ + 179, /* (331) signed ::= minus_num */ + 176, /* (332) carglist ::= carglist ccons */ + 176, /* (333) carglist ::= */ + 183, /* (334) ccons ::= NULL onconf */ + 172, /* (335) conslist_opt ::= COMMA conslist */ + 195, /* (336) conslist ::= conslist tconscomma tcons */ + 195, /* (337) conslist ::= tcons */ + 196, /* (338) tconscomma ::= */ + 200, /* (339) defer_subclause_opt ::= defer_subclause */ + 202, /* (340) resolvetype ::= raisetype */ + 206, /* (341) selectnowith ::= oneselect */ + 207, /* (342) oneselect ::= values */ + 221, /* (343) sclp ::= selcollist COMMA */ + 222, /* (344) as ::= ID|STRING */ + 185, /* (345) expr ::= term */ + 238, /* (346) likeop ::= LIKE_KW|MATCH */ + 229, /* (347) exprlist ::= nexprlist */ + 248, /* (348) nmnum ::= plus_num */ + 248, /* (349) nmnum ::= nm */ + 248, /* (350) nmnum ::= ON */ + 248, /* (351) nmnum ::= DELETE */ + 248, /* (352) nmnum ::= DEFAULT */ + 180, /* (353) plus_num ::= INTEGER|FLOAT */ + 253, /* (354) foreach_clause ::= */ + 253, /* (355) foreach_clause ::= FOR EACH ROW */ + 256, /* (356) trnm ::= nm */ + 257, /* (357) tridxby ::= */ + 258, /* (358) database_kw_opt ::= DATABASE */ + 258, /* (359) database_kw_opt ::= */ + 261, /* (360) kwcolumn_opt ::= */ + 261, /* (361) kwcolumn_opt ::= COLUMNKW */ + 263, /* (362) vtabarglist ::= vtabarg */ + 263, /* (363) vtabarglist ::= vtabarglist COMMA vtabarg */ + 264, /* (364) vtabarg ::= vtabarg vtabargtoken */ + 267, /* (365) anylist ::= */ + 267, /* (366) anylist ::= anylist LP anylist RP */ + 267, /* (367) anylist ::= anylist ANY */ + 232, /* (368) with ::= */ +}; + +/* For rule J, yyRuleInfoNRhs[J] contains the negative of the number +** of symbols on the right-hand side of that rule. */ +static const signed char yyRuleInfoNRhs[] = { + -1, /* (0) explain ::= EXPLAIN */ + -3, /* (1) explain ::= EXPLAIN QUERY PLAN */ + -1, /* (2) cmdx ::= cmd */ + -3, /* (3) cmd ::= BEGIN transtype trans_opt */ + 0, /* (4) transtype ::= */ + -1, /* (5) transtype ::= DEFERRED */ + -1, /* (6) transtype ::= IMMEDIATE */ + -1, /* (7) transtype ::= EXCLUSIVE */ + -2, /* (8) cmd ::= COMMIT|END trans_opt */ + -2, /* (9) cmd ::= ROLLBACK trans_opt */ + -2, /* (10) cmd ::= SAVEPOINT nm */ + -3, /* (11) cmd ::= RELEASE savepoint_opt nm */ + -5, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ + -6, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */ + -1, /* (14) createkw ::= CREATE */ + 0, /* (15) ifnotexists ::= */ + -3, /* (16) ifnotexists ::= IF NOT EXISTS */ + -1, /* (17) temp ::= TEMP */ + 0, /* (18) temp ::= */ + -5, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_options */ + -2, /* (20) create_table_args ::= AS select */ + 0, /* (21) table_options ::= */ + -2, /* (22) table_options ::= WITHOUT nm */ + -2, /* (23) columnname ::= nm typetoken */ + 0, /* (24) typetoken ::= */ + -4, /* (25) typetoken ::= typename LP signed RP */ + -6, /* (26) typetoken ::= typename LP signed COMMA signed RP */ + -2, /* (27) typename ::= typename ID|STRING */ + 0, /* (28) scanpt ::= */ + -2, /* (29) ccons ::= CONSTRAINT nm */ + -4, /* (30) ccons ::= DEFAULT scanpt term scanpt */ + -4, /* (31) ccons ::= DEFAULT LP expr RP */ + -4, /* (32) ccons ::= DEFAULT PLUS term scanpt */ + -4, /* (33) ccons ::= DEFAULT MINUS term scanpt */ + -3, /* (34) ccons ::= DEFAULT scanpt ID|INDEXED */ + -3, /* (35) ccons ::= NOT NULL onconf */ + -5, /* (36) ccons ::= PRIMARY KEY sortorder onconf autoinc */ + -2, /* (37) ccons ::= UNIQUE onconf */ + -4, /* (38) ccons ::= CHECK LP expr RP */ + -4, /* (39) ccons ::= REFERENCES nm eidlist_opt refargs */ + -1, /* (40) ccons ::= defer_subclause */ + -2, /* (41) ccons ::= COLLATE ID|STRING */ + 0, /* (42) autoinc ::= */ + -1, /* (43) autoinc ::= AUTOINCR */ + 0, /* (44) refargs ::= */ + -2, /* (45) refargs ::= refargs refarg */ + -2, /* (46) refarg ::= MATCH nm */ + -3, /* (47) refarg ::= ON INSERT refact */ + -3, /* (48) refarg ::= ON DELETE refact */ + -3, /* (49) refarg ::= ON UPDATE refact */ + -2, /* (50) refact ::= SET NULL */ + -2, /* (51) refact ::= SET DEFAULT */ + -1, /* (52) refact ::= CASCADE */ + -1, /* (53) refact ::= RESTRICT */ + -2, /* (54) refact ::= NO ACTION */ + -3, /* (55) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ + -2, /* (56) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ + 0, /* (57) init_deferred_pred_opt ::= */ + -2, /* (58) init_deferred_pred_opt ::= INITIALLY DEFERRED */ + -2, /* (59) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ + 0, /* (60) conslist_opt ::= */ + -1, /* (61) tconscomma ::= COMMA */ + -2, /* (62) tcons ::= CONSTRAINT nm */ + -7, /* (63) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ + -5, /* (64) tcons ::= UNIQUE LP sortlist RP onconf */ + -5, /* (65) tcons ::= CHECK LP expr RP onconf */ + -10, /* (66) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ + 0, /* (67) defer_subclause_opt ::= */ + 0, /* (68) onconf ::= */ + -3, /* (69) onconf ::= ON CONFLICT resolvetype */ + 0, /* (70) orconf ::= */ + -2, /* (71) orconf ::= OR resolvetype */ + -1, /* (72) resolvetype ::= IGNORE */ + -1, /* (73) resolvetype ::= REPLACE */ + -4, /* (74) cmd ::= DROP TABLE ifexists fullname */ + -2, /* (75) ifexists ::= IF EXISTS */ + 0, /* (76) ifexists ::= */ + -9, /* (77) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ + -4, /* (78) cmd ::= DROP VIEW ifexists fullname */ + -1, /* (79) cmd ::= select */ + -3, /* (80) select ::= WITH wqlist selectnowith */ + -4, /* (81) select ::= WITH RECURSIVE wqlist selectnowith */ + -1, /* (82) select ::= selectnowith */ + -3, /* (83) selectnowith ::= selectnowith multiselect_op oneselect */ + -1, /* (84) multiselect_op ::= UNION */ + -2, /* (85) multiselect_op ::= UNION ALL */ + -1, /* (86) multiselect_op ::= EXCEPT|INTERSECT */ + -9, /* (87) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ + -10, /* (88) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ + -4, /* (89) values ::= VALUES LP nexprlist RP */ + -5, /* (90) values ::= values COMMA LP nexprlist RP */ + -1, /* (91) distinct ::= DISTINCT */ + -1, /* (92) distinct ::= ALL */ + 0, /* (93) distinct ::= */ + 0, /* (94) sclp ::= */ + -5, /* (95) selcollist ::= sclp scanpt expr scanpt as */ + -3, /* (96) selcollist ::= sclp scanpt STAR */ + -5, /* (97) selcollist ::= sclp scanpt nm DOT STAR */ + -2, /* (98) as ::= AS nm */ + 0, /* (99) as ::= */ + 0, /* (100) from ::= */ + -2, /* (101) from ::= FROM seltablist */ + -2, /* (102) stl_prefix ::= seltablist joinop */ + 0, /* (103) stl_prefix ::= */ + -7, /* (104) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ + -9, /* (105) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ + -7, /* (106) seltablist ::= stl_prefix LP select RP as on_opt using_opt */ + -7, /* (107) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ + 0, /* (108) dbnm ::= */ + -2, /* (109) dbnm ::= DOT nm */ + -1, /* (110) fullname ::= nm */ + -3, /* (111) fullname ::= nm DOT nm */ + -1, /* (112) xfullname ::= nm */ + -3, /* (113) xfullname ::= nm DOT nm */ + -5, /* (114) xfullname ::= nm DOT nm AS nm */ + -3, /* (115) xfullname ::= nm AS nm */ + -1, /* (116) joinop ::= COMMA|JOIN */ + -2, /* (117) joinop ::= JOIN_KW JOIN */ + -3, /* (118) joinop ::= JOIN_KW nm JOIN */ + -4, /* (119) joinop ::= JOIN_KW nm nm JOIN */ + -2, /* (120) on_opt ::= ON expr */ + 0, /* (121) on_opt ::= */ + 0, /* (122) indexed_opt ::= */ + -3, /* (123) indexed_opt ::= INDEXED BY nm */ + -2, /* (124) indexed_opt ::= NOT INDEXED */ + -4, /* (125) using_opt ::= USING LP idlist RP */ + 0, /* (126) using_opt ::= */ + 0, /* (127) orderby_opt ::= */ + -3, /* (128) orderby_opt ::= ORDER BY sortlist */ + -4, /* (129) sortlist ::= sortlist COMMA expr sortorder */ + -2, /* (130) sortlist ::= expr sortorder */ + -1, /* (131) sortorder ::= ASC */ + -1, /* (132) sortorder ::= DESC */ + 0, /* (133) sortorder ::= */ + 0, /* (134) groupby_opt ::= */ + -3, /* (135) groupby_opt ::= GROUP BY nexprlist */ + 0, /* (136) having_opt ::= */ + -2, /* (137) having_opt ::= HAVING expr */ + 0, /* (138) limit_opt ::= */ + -2, /* (139) limit_opt ::= LIMIT expr */ + -4, /* (140) limit_opt ::= LIMIT expr OFFSET expr */ + -4, /* (141) limit_opt ::= LIMIT expr COMMA expr */ + -6, /* (142) cmd ::= with DELETE FROM xfullname indexed_opt where_opt */ + 0, /* (143) where_opt ::= */ + -2, /* (144) where_opt ::= WHERE expr */ + -8, /* (145) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */ + -5, /* (146) setlist ::= setlist COMMA nm EQ expr */ + -7, /* (147) setlist ::= setlist COMMA LP idlist RP EQ expr */ + -3, /* (148) setlist ::= nm EQ expr */ + -5, /* (149) setlist ::= LP idlist RP EQ expr */ + -7, /* (150) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + -7, /* (151) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */ + 0, /* (152) upsert ::= */ + -11, /* (153) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */ + -8, /* (154) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */ + -4, /* (155) upsert ::= ON CONFLICT DO NOTHING */ + -2, /* (156) insert_cmd ::= INSERT orconf */ + -1, /* (157) insert_cmd ::= REPLACE */ + 0, /* (158) idlist_opt ::= */ + -3, /* (159) idlist_opt ::= LP idlist RP */ + -3, /* (160) idlist ::= idlist COMMA nm */ + -1, /* (161) idlist ::= nm */ + -3, /* (162) expr ::= LP expr RP */ + -1, /* (163) expr ::= ID|INDEXED */ + -1, /* (164) expr ::= JOIN_KW */ + -3, /* (165) expr ::= nm DOT nm */ + -5, /* (166) expr ::= nm DOT nm DOT nm */ + -1, /* (167) term ::= NULL|FLOAT|BLOB */ + -1, /* (168) term ::= STRING */ + -1, /* (169) term ::= INTEGER */ + -1, /* (170) expr ::= VARIABLE */ + -3, /* (171) expr ::= expr COLLATE ID|STRING */ + -6, /* (172) expr ::= CAST LP expr AS typetoken RP */ + -5, /* (173) expr ::= ID|INDEXED LP distinct exprlist RP */ + -4, /* (174) expr ::= ID|INDEXED LP STAR RP */ + -6, /* (175) expr ::= ID|INDEXED LP distinct exprlist RP over_clause */ + -5, /* (176) expr ::= ID|INDEXED LP STAR RP over_clause */ + -1, /* (177) term ::= CTIME_KW */ + -5, /* (178) expr ::= LP nexprlist COMMA expr RP */ + -3, /* (179) expr ::= expr AND expr */ + -3, /* (180) expr ::= expr OR expr */ + -3, /* (181) expr ::= expr LT|GT|GE|LE expr */ + -3, /* (182) expr ::= expr EQ|NE expr */ + -3, /* (183) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ + -3, /* (184) expr ::= expr PLUS|MINUS expr */ + -3, /* (185) expr ::= expr STAR|SLASH|REM expr */ + -3, /* (186) expr ::= expr CONCAT expr */ + -2, /* (187) likeop ::= NOT LIKE_KW|MATCH */ + -3, /* (188) expr ::= expr likeop expr */ + -5, /* (189) expr ::= expr likeop expr ESCAPE expr */ + -2, /* (190) expr ::= expr ISNULL|NOTNULL */ + -3, /* (191) expr ::= expr NOT NULL */ + -3, /* (192) expr ::= expr IS expr */ + -4, /* (193) expr ::= expr IS NOT expr */ + -2, /* (194) expr ::= NOT expr */ + -2, /* (195) expr ::= BITNOT expr */ + -2, /* (196) expr ::= PLUS|MINUS expr */ + -1, /* (197) between_op ::= BETWEEN */ + -2, /* (198) between_op ::= NOT BETWEEN */ + -5, /* (199) expr ::= expr between_op expr AND expr */ + -1, /* (200) in_op ::= IN */ + -2, /* (201) in_op ::= NOT IN */ + -5, /* (202) expr ::= expr in_op LP exprlist RP */ + -3, /* (203) expr ::= LP select RP */ + -5, /* (204) expr ::= expr in_op LP select RP */ + -5, /* (205) expr ::= expr in_op nm dbnm paren_exprlist */ + -4, /* (206) expr ::= EXISTS LP select RP */ + -5, /* (207) expr ::= CASE case_operand case_exprlist case_else END */ + -5, /* (208) case_exprlist ::= case_exprlist WHEN expr THEN expr */ + -4, /* (209) case_exprlist ::= WHEN expr THEN expr */ + -2, /* (210) case_else ::= ELSE expr */ + 0, /* (211) case_else ::= */ + -1, /* (212) case_operand ::= expr */ + 0, /* (213) case_operand ::= */ + 0, /* (214) exprlist ::= */ + -3, /* (215) nexprlist ::= nexprlist COMMA expr */ + -1, /* (216) nexprlist ::= expr */ + 0, /* (217) paren_exprlist ::= */ + -3, /* (218) paren_exprlist ::= LP exprlist RP */ + -12, /* (219) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + -1, /* (220) uniqueflag ::= UNIQUE */ + 0, /* (221) uniqueflag ::= */ + 0, /* (222) eidlist_opt ::= */ + -3, /* (223) eidlist_opt ::= LP eidlist RP */ + -5, /* (224) eidlist ::= eidlist COMMA nm collate sortorder */ + -3, /* (225) eidlist ::= nm collate sortorder */ + 0, /* (226) collate ::= */ + -2, /* (227) collate ::= COLLATE ID|STRING */ + -4, /* (228) cmd ::= DROP INDEX ifexists fullname */ + -2, /* (229) cmd ::= VACUUM vinto */ + -3, /* (230) cmd ::= VACUUM nm vinto */ + -2, /* (231) vinto ::= INTO expr */ + 0, /* (232) vinto ::= */ + -3, /* (233) cmd ::= PRAGMA nm dbnm */ + -5, /* (234) cmd ::= PRAGMA nm dbnm EQ nmnum */ + -6, /* (235) cmd ::= PRAGMA nm dbnm LP nmnum RP */ + -5, /* (236) cmd ::= PRAGMA nm dbnm EQ minus_num */ + -6, /* (237) cmd ::= PRAGMA nm dbnm LP minus_num RP */ + -2, /* (238) plus_num ::= PLUS INTEGER|FLOAT */ + -2, /* (239) minus_num ::= MINUS INTEGER|FLOAT */ + -5, /* (240) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + -11, /* (241) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + -1, /* (242) trigger_time ::= BEFORE|AFTER */ + -2, /* (243) trigger_time ::= INSTEAD OF */ + 0, /* (244) trigger_time ::= */ + -1, /* (245) trigger_event ::= DELETE|INSERT */ + -1, /* (246) trigger_event ::= UPDATE */ + -3, /* (247) trigger_event ::= UPDATE OF idlist */ + 0, /* (248) when_clause ::= */ + -2, /* (249) when_clause ::= WHEN expr */ + -3, /* (250) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + -2, /* (251) trigger_cmd_list ::= trigger_cmd SEMI */ + -3, /* (252) trnm ::= nm DOT nm */ + -3, /* (253) tridxby ::= INDEXED BY nm */ + -2, /* (254) tridxby ::= NOT INDEXED */ + -8, /* (255) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */ + -8, /* (256) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + -6, /* (257) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + -3, /* (258) trigger_cmd ::= scanpt select scanpt */ + -4, /* (259) expr ::= RAISE LP IGNORE RP */ + -6, /* (260) expr ::= RAISE LP raisetype COMMA nm RP */ + -1, /* (261) raisetype ::= ROLLBACK */ + -1, /* (262) raisetype ::= ABORT */ + -1, /* (263) raisetype ::= FAIL */ + -4, /* (264) cmd ::= DROP TRIGGER ifexists fullname */ + -6, /* (265) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + -3, /* (266) cmd ::= DETACH database_kw_opt expr */ + 0, /* (267) key_opt ::= */ + -2, /* (268) key_opt ::= KEY expr */ + -1, /* (269) cmd ::= REINDEX */ + -3, /* (270) cmd ::= REINDEX nm dbnm */ + -1, /* (271) cmd ::= ANALYZE */ + -3, /* (272) cmd ::= ANALYZE nm dbnm */ + -6, /* (273) cmd ::= ALTER TABLE fullname RENAME TO nm */ + -7, /* (274) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + -1, /* (275) add_column_fullname ::= fullname */ + -8, /* (276) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + -1, /* (277) cmd ::= create_vtab */ + -4, /* (278) cmd ::= create_vtab LP vtabarglist RP */ + -8, /* (279) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 0, /* (280) vtabarg ::= */ + -1, /* (281) vtabargtoken ::= ANY */ + -3, /* (282) vtabargtoken ::= lp anylist RP */ + -1, /* (283) lp ::= LP */ + -2, /* (284) with ::= WITH wqlist */ + -3, /* (285) with ::= WITH RECURSIVE wqlist */ + -6, /* (286) wqlist ::= nm eidlist_opt AS LP select RP */ + -8, /* (287) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */ + -1, /* (288) windowdefn_list ::= windowdefn */ + -3, /* (289) windowdefn_list ::= windowdefn_list COMMA windowdefn */ + -3, /* (290) windowdefn ::= nm AS window */ + -5, /* (291) window ::= LP part_opt orderby_opt frame_opt RP */ + -3, /* (292) part_opt ::= PARTITION BY nexprlist */ + 0, /* (293) part_opt ::= */ + 0, /* (294) frame_opt ::= */ + -2, /* (295) frame_opt ::= range_or_rows frame_bound_s */ + -5, /* (296) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e */ + -1, /* (297) range_or_rows ::= RANGE */ + -1, /* (298) range_or_rows ::= ROWS */ + -1, /* (299) frame_bound_s ::= frame_bound */ + -2, /* (300) frame_bound_s ::= UNBOUNDED PRECEDING */ + -1, /* (301) frame_bound_e ::= frame_bound */ + -2, /* (302) frame_bound_e ::= UNBOUNDED FOLLOWING */ + -2, /* (303) frame_bound ::= expr PRECEDING */ + -2, /* (304) frame_bound ::= CURRENT ROW */ + -2, /* (305) frame_bound ::= expr FOLLOWING */ + -2, /* (306) window_clause ::= WINDOW windowdefn_list */ + -3, /* (307) over_clause ::= filter_opt OVER window */ + -3, /* (308) over_clause ::= filter_opt OVER nm */ + 0, /* (309) filter_opt ::= */ + -5, /* (310) filter_opt ::= FILTER LP WHERE expr RP */ + -1, /* (311) input ::= cmdlist */ + -2, /* (312) cmdlist ::= cmdlist ecmd */ + -1, /* (313) cmdlist ::= ecmd */ + -1, /* (314) ecmd ::= SEMI */ + -2, /* (315) ecmd ::= cmdx SEMI */ + -2, /* (316) ecmd ::= explain cmdx */ + 0, /* (317) trans_opt ::= */ + -1, /* (318) trans_opt ::= TRANSACTION */ + -2, /* (319) trans_opt ::= TRANSACTION nm */ + -1, /* (320) savepoint_opt ::= SAVEPOINT */ + 0, /* (321) savepoint_opt ::= */ + -2, /* (322) cmd ::= create_table create_table_args */ + -4, /* (323) columnlist ::= columnlist COMMA columnname carglist */ + -2, /* (324) columnlist ::= columnname carglist */ + -1, /* (325) nm ::= ID|INDEXED */ + -1, /* (326) nm ::= STRING */ + -1, /* (327) nm ::= JOIN_KW */ + -1, /* (328) typetoken ::= typename */ + -1, /* (329) typename ::= ID|STRING */ + -1, /* (330) signed ::= plus_num */ + -1, /* (331) signed ::= minus_num */ + -2, /* (332) carglist ::= carglist ccons */ + 0, /* (333) carglist ::= */ + -2, /* (334) ccons ::= NULL onconf */ + -2, /* (335) conslist_opt ::= COMMA conslist */ + -3, /* (336) conslist ::= conslist tconscomma tcons */ + -1, /* (337) conslist ::= tcons */ + 0, /* (338) tconscomma ::= */ + -1, /* (339) defer_subclause_opt ::= defer_subclause */ + -1, /* (340) resolvetype ::= raisetype */ + -1, /* (341) selectnowith ::= oneselect */ + -1, /* (342) oneselect ::= values */ + -2, /* (343) sclp ::= selcollist COMMA */ + -1, /* (344) as ::= ID|STRING */ + -1, /* (345) expr ::= term */ + -1, /* (346) likeop ::= LIKE_KW|MATCH */ + -1, /* (347) exprlist ::= nexprlist */ + -1, /* (348) nmnum ::= plus_num */ + -1, /* (349) nmnum ::= nm */ + -1, /* (350) nmnum ::= ON */ + -1, /* (351) nmnum ::= DELETE */ + -1, /* (352) nmnum ::= DEFAULT */ + -1, /* (353) plus_num ::= INTEGER|FLOAT */ + 0, /* (354) foreach_clause ::= */ + -3, /* (355) foreach_clause ::= FOR EACH ROW */ + -1, /* (356) trnm ::= nm */ + 0, /* (357) tridxby ::= */ + -1, /* (358) database_kw_opt ::= DATABASE */ + 0, /* (359) database_kw_opt ::= */ + 0, /* (360) kwcolumn_opt ::= */ + -1, /* (361) kwcolumn_opt ::= COLUMNKW */ + -1, /* (362) vtabarglist ::= vtabarg */ + -3, /* (363) vtabarglist ::= vtabarglist COMMA vtabarg */ + -2, /* (364) vtabarg ::= vtabarg vtabargtoken */ + 0, /* (365) anylist ::= */ + -4, /* (366) anylist ::= anylist LP anylist RP */ + -2, /* (367) anylist ::= anylist ANY */ + 0, /* (368) with ::= */ }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -149483,7 +150374,7 @@ static YYACTIONTYPE yy_reduce( yymsp = yypParser->yytos; #ifndef NDEBUG if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ - yysize = yyRuleInfo[yyruleno].nrhs; + yysize = yyRuleInfoNRhs[yyruleno]; if( yysize ){ fprintf(yyTraceFILE, "%sReduce %d [%s], go to state %d.\n", yyTracePrompt, @@ -149498,7 +150389,7 @@ static YYACTIONTYPE yy_reduce( /* Check that the stack is large enough to grow by a single entry ** if the RHS of the rule is empty. This ensures that there is room ** enough on the stack to push the LHS value */ - if( yyRuleInfo[yyruleno].nrhs==0 ){ + if( yyRuleInfoNRhs[yyruleno]==0 ){ #ifdef YYTRACKMAXSTACKDEPTH if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){ yypParser->yyhwm++; @@ -149548,15 +150439,15 @@ static YYACTIONTYPE yy_reduce( { sqlite3FinishCoding(pParse); } break; case 3: /* cmd ::= BEGIN transtype trans_opt */ -{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy70);} +{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy96);} break; case 4: /* transtype ::= */ -{yymsp[1].minor.yy70 = TK_DEFERRED;} +{yymsp[1].minor.yy96 = TK_DEFERRED;} break; case 5: /* transtype ::= DEFERRED */ case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6); case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7); -{yymsp[0].minor.yy70 = yymsp[0].major; /*A-overwrites-X*/} +{yymsp[0].minor.yy96 = yymsp[0].major; /*A-overwrites-X*/} break; case 8: /* cmd ::= COMMIT|END trans_opt */ case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9); @@ -149579,7 +150470,7 @@ static YYACTIONTYPE yy_reduce( break; case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */ { - sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy70,0,0,yymsp[-2].minor.yy70); + sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy96,0,0,yymsp[-2].minor.yy96); } break; case 14: /* createkw ::= CREATE */ @@ -149594,32 +150485,32 @@ static YYACTIONTYPE yy_reduce( case 76: /* ifexists ::= */ yytestcase(yyruleno==76); case 93: /* distinct ::= */ yytestcase(yyruleno==93); case 226: /* collate ::= */ yytestcase(yyruleno==226); -{yymsp[1].minor.yy70 = 0;} +{yymsp[1].minor.yy96 = 0;} break; case 16: /* ifnotexists ::= IF NOT EXISTS */ -{yymsp[-2].minor.yy70 = 1;} +{yymsp[-2].minor.yy96 = 1;} break; case 17: /* temp ::= TEMP */ case 43: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==43); -{yymsp[0].minor.yy70 = 1;} +{yymsp[0].minor.yy96 = 1;} break; case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_options */ { - sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy70,0); + sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy96,0); } break; case 20: /* create_table_args ::= AS select */ { - sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy489); - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy489); + sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy423); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy423); } break; case 22: /* table_options ::= WITHOUT nm */ { if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){ - yymsp[-1].minor.yy70 = TF_WithoutRowid | TF_NoVisibleRowid; + yymsp[-1].minor.yy96 = TF_WithoutRowid | TF_NoVisibleRowid; }else{ - yymsp[-1].minor.yy70 = 0; + yymsp[-1].minor.yy96 = 0; sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); } } @@ -149648,7 +150539,7 @@ static YYACTIONTYPE yy_reduce( case 28: /* scanpt ::= */ { assert( yyLookahead!=YYNOCODE ); - yymsp[1].minor.yy392 = yyLookaheadToken.z; + yymsp[1].minor.yy464 = yyLookaheadToken.z; } break; case 29: /* ccons ::= CONSTRAINT nm */ @@ -149656,18 +150547,18 @@ static YYACTIONTYPE yy_reduce( {pParse->constraintName = yymsp[0].minor.yy0;} break; case 30: /* ccons ::= DEFAULT scanpt term scanpt */ -{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy18,yymsp[-2].minor.yy392,yymsp[0].minor.yy392);} +{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy490,yymsp[-2].minor.yy464,yymsp[0].minor.yy464);} break; case 31: /* ccons ::= DEFAULT LP expr RP */ -{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy18,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);} +{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy490,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);} break; case 32: /* ccons ::= DEFAULT PLUS term scanpt */ -{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy18,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy392);} +{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy490,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy464);} break; case 33: /* ccons ::= DEFAULT MINUS term scanpt */ { - Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[-1].minor.yy18, 0); - sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy392); + Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[-1].minor.yy490, 0); + sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy464); } break; case 34: /* ccons ::= DEFAULT scanpt ID|INDEXED */ @@ -149681,170 +150572,170 @@ static YYACTIONTYPE yy_reduce( } break; case 35: /* ccons ::= NOT NULL onconf */ -{sqlite3AddNotNull(pParse, yymsp[0].minor.yy70);} +{sqlite3AddNotNull(pParse, yymsp[0].minor.yy96);} break; case 36: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */ -{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy70,yymsp[0].minor.yy70,yymsp[-2].minor.yy70);} +{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy96,yymsp[0].minor.yy96,yymsp[-2].minor.yy96);} break; case 37: /* ccons ::= UNIQUE onconf */ -{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy70,0,0,0,0, +{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy96,0,0,0,0, SQLITE_IDXTYPE_UNIQUE);} break; case 38: /* ccons ::= CHECK LP expr RP */ -{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy18);} +{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy490);} break; case 39: /* ccons ::= REFERENCES nm eidlist_opt refargs */ -{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy420,yymsp[0].minor.yy70);} +{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy42,yymsp[0].minor.yy96);} break; case 40: /* ccons ::= defer_subclause */ -{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy70);} +{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy96);} break; case 41: /* ccons ::= COLLATE ID|STRING */ {sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);} break; case 44: /* refargs ::= */ -{ yymsp[1].minor.yy70 = OE_None*0x0101; /* EV: R-19803-45884 */} +{ yymsp[1].minor.yy96 = OE_None*0x0101; /* EV: R-19803-45884 */} break; case 45: /* refargs ::= refargs refarg */ -{ yymsp[-1].minor.yy70 = (yymsp[-1].minor.yy70 & ~yymsp[0].minor.yy111.mask) | yymsp[0].minor.yy111.value; } +{ yymsp[-1].minor.yy96 = (yymsp[-1].minor.yy96 & ~yymsp[0].minor.yy367.mask) | yymsp[0].minor.yy367.value; } break; case 46: /* refarg ::= MATCH nm */ -{ yymsp[-1].minor.yy111.value = 0; yymsp[-1].minor.yy111.mask = 0x000000; } +{ yymsp[-1].minor.yy367.value = 0; yymsp[-1].minor.yy367.mask = 0x000000; } break; case 47: /* refarg ::= ON INSERT refact */ -{ yymsp[-2].minor.yy111.value = 0; yymsp[-2].minor.yy111.mask = 0x000000; } +{ yymsp[-2].minor.yy367.value = 0; yymsp[-2].minor.yy367.mask = 0x000000; } break; case 48: /* refarg ::= ON DELETE refact */ -{ yymsp[-2].minor.yy111.value = yymsp[0].minor.yy70; yymsp[-2].minor.yy111.mask = 0x0000ff; } +{ yymsp[-2].minor.yy367.value = yymsp[0].minor.yy96; yymsp[-2].minor.yy367.mask = 0x0000ff; } break; case 49: /* refarg ::= ON UPDATE refact */ -{ yymsp[-2].minor.yy111.value = yymsp[0].minor.yy70<<8; yymsp[-2].minor.yy111.mask = 0x00ff00; } +{ yymsp[-2].minor.yy367.value = yymsp[0].minor.yy96<<8; yymsp[-2].minor.yy367.mask = 0x00ff00; } break; case 50: /* refact ::= SET NULL */ -{ yymsp[-1].minor.yy70 = OE_SetNull; /* EV: R-33326-45252 */} +{ yymsp[-1].minor.yy96 = OE_SetNull; /* EV: R-33326-45252 */} break; case 51: /* refact ::= SET DEFAULT */ -{ yymsp[-1].minor.yy70 = OE_SetDflt; /* EV: R-33326-45252 */} +{ yymsp[-1].minor.yy96 = OE_SetDflt; /* EV: R-33326-45252 */} break; case 52: /* refact ::= CASCADE */ -{ yymsp[0].minor.yy70 = OE_Cascade; /* EV: R-33326-45252 */} +{ yymsp[0].minor.yy96 = OE_Cascade; /* EV: R-33326-45252 */} break; case 53: /* refact ::= RESTRICT */ -{ yymsp[0].minor.yy70 = OE_Restrict; /* EV: R-33326-45252 */} +{ yymsp[0].minor.yy96 = OE_Restrict; /* EV: R-33326-45252 */} break; case 54: /* refact ::= NO ACTION */ -{ yymsp[-1].minor.yy70 = OE_None; /* EV: R-33326-45252 */} +{ yymsp[-1].minor.yy96 = OE_None; /* EV: R-33326-45252 */} break; case 55: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ -{yymsp[-2].minor.yy70 = 0;} +{yymsp[-2].minor.yy96 = 0;} break; case 56: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ case 71: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==71); case 156: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==156); -{yymsp[-1].minor.yy70 = yymsp[0].minor.yy70;} +{yymsp[-1].minor.yy96 = yymsp[0].minor.yy96;} break; case 58: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ case 75: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==75); case 198: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==198); case 201: /* in_op ::= NOT IN */ yytestcase(yyruleno==201); case 227: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==227); -{yymsp[-1].minor.yy70 = 1;} +{yymsp[-1].minor.yy96 = 1;} break; case 59: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ -{yymsp[-1].minor.yy70 = 0;} +{yymsp[-1].minor.yy96 = 0;} break; case 61: /* tconscomma ::= COMMA */ {pParse->constraintName.n = 0;} break; case 63: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ -{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy420,yymsp[0].minor.yy70,yymsp[-2].minor.yy70,0);} +{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy42,yymsp[0].minor.yy96,yymsp[-2].minor.yy96,0);} break; case 64: /* tcons ::= UNIQUE LP sortlist RP onconf */ -{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy420,yymsp[0].minor.yy70,0,0,0,0, +{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy42,yymsp[0].minor.yy96,0,0,0,0, SQLITE_IDXTYPE_UNIQUE);} break; case 65: /* tcons ::= CHECK LP expr RP onconf */ -{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy18);} +{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy490);} break; case 66: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ { - sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy420, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy420, yymsp[-1].minor.yy70); - sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy70); + sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy42, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy42, yymsp[-1].minor.yy96); + sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy96); } break; case 68: /* onconf ::= */ case 70: /* orconf ::= */ yytestcase(yyruleno==70); -{yymsp[1].minor.yy70 = OE_Default;} +{yymsp[1].minor.yy96 = OE_Default;} break; case 69: /* onconf ::= ON CONFLICT resolvetype */ -{yymsp[-2].minor.yy70 = yymsp[0].minor.yy70;} +{yymsp[-2].minor.yy96 = yymsp[0].minor.yy96;} break; case 72: /* resolvetype ::= IGNORE */ -{yymsp[0].minor.yy70 = OE_Ignore;} +{yymsp[0].minor.yy96 = OE_Ignore;} break; case 73: /* resolvetype ::= REPLACE */ case 157: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==157); -{yymsp[0].minor.yy70 = OE_Replace;} +{yymsp[0].minor.yy96 = OE_Replace;} break; case 74: /* cmd ::= DROP TABLE ifexists fullname */ { - sqlite3DropTable(pParse, yymsp[0].minor.yy135, 0, yymsp[-1].minor.yy70); + sqlite3DropTable(pParse, yymsp[0].minor.yy167, 0, yymsp[-1].minor.yy96); } break; case 77: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ { - sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy420, yymsp[0].minor.yy489, yymsp[-7].minor.yy70, yymsp[-5].minor.yy70); + sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy42, yymsp[0].minor.yy423, yymsp[-7].minor.yy96, yymsp[-5].minor.yy96); } break; case 78: /* cmd ::= DROP VIEW ifexists fullname */ { - sqlite3DropTable(pParse, yymsp[0].minor.yy135, 1, yymsp[-1].minor.yy70); + sqlite3DropTable(pParse, yymsp[0].minor.yy167, 1, yymsp[-1].minor.yy96); } break; case 79: /* cmd ::= select */ { SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0}; - sqlite3Select(pParse, yymsp[0].minor.yy489, &dest); - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy489); + sqlite3Select(pParse, yymsp[0].minor.yy423, &dest); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy423); } break; case 80: /* select ::= WITH wqlist selectnowith */ { - Select *p = yymsp[0].minor.yy489; + Select *p = yymsp[0].minor.yy423; if( p ){ - p->pWith = yymsp[-1].minor.yy449; + p->pWith = yymsp[-1].minor.yy499; parserDoubleLinkSelect(pParse, p); }else{ - sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy449); + sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy499); } - yymsp[-2].minor.yy489 = p; + yymsp[-2].minor.yy423 = p; } break; case 81: /* select ::= WITH RECURSIVE wqlist selectnowith */ { - Select *p = yymsp[0].minor.yy489; + Select *p = yymsp[0].minor.yy423; if( p ){ - p->pWith = yymsp[-1].minor.yy449; + p->pWith = yymsp[-1].minor.yy499; parserDoubleLinkSelect(pParse, p); }else{ - sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy449); + sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy499); } - yymsp[-3].minor.yy489 = p; + yymsp[-3].minor.yy423 = p; } break; case 82: /* select ::= selectnowith */ { - Select *p = yymsp[0].minor.yy489; + Select *p = yymsp[0].minor.yy423; if( p ){ parserDoubleLinkSelect(pParse, p); } - yymsp[0].minor.yy489 = p; /*A-overwrites-X*/ + yymsp[0].minor.yy423 = p; /*A-overwrites-X*/ } break; case 83: /* selectnowith ::= selectnowith multiselect_op oneselect */ { - Select *pRhs = yymsp[0].minor.yy489; - Select *pLhs = yymsp[-2].minor.yy489; + Select *pRhs = yymsp[0].minor.yy423; + Select *pLhs = yymsp[-2].minor.yy423; if( pRhs && pRhs->pPrior ){ SrcList *pFrom; Token x; @@ -149854,63 +150745,63 @@ static YYACTIONTYPE yy_reduce( pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0); } if( pRhs ){ - pRhs->op = (u8)yymsp[-1].minor.yy70; + pRhs->op = (u8)yymsp[-1].minor.yy96; pRhs->pPrior = pLhs; if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue; pRhs->selFlags &= ~SF_MultiValue; - if( yymsp[-1].minor.yy70!=TK_ALL ) pParse->hasCompound = 1; + if( yymsp[-1].minor.yy96!=TK_ALL ) pParse->hasCompound = 1; }else{ sqlite3SelectDelete(pParse->db, pLhs); } - yymsp[-2].minor.yy489 = pRhs; + yymsp[-2].minor.yy423 = pRhs; } break; case 84: /* multiselect_op ::= UNION */ case 86: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==86); -{yymsp[0].minor.yy70 = yymsp[0].major; /*A-overwrites-OP*/} +{yymsp[0].minor.yy96 = yymsp[0].major; /*A-overwrites-OP*/} break; case 85: /* multiselect_op ::= UNION ALL */ -{yymsp[-1].minor.yy70 = TK_ALL;} +{yymsp[-1].minor.yy96 = TK_ALL;} break; case 87: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ { - yymsp[-8].minor.yy489 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy420,yymsp[-5].minor.yy135,yymsp[-4].minor.yy18,yymsp[-3].minor.yy420,yymsp[-2].minor.yy18,yymsp[-1].minor.yy420,yymsp[-7].minor.yy70,yymsp[0].minor.yy18); + yymsp[-8].minor.yy423 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy42,yymsp[-5].minor.yy167,yymsp[-4].minor.yy490,yymsp[-3].minor.yy42,yymsp[-2].minor.yy490,yymsp[-1].minor.yy42,yymsp[-7].minor.yy96,yymsp[0].minor.yy490); } break; case 88: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ { - yymsp[-9].minor.yy489 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy420,yymsp[-6].minor.yy135,yymsp[-5].minor.yy18,yymsp[-4].minor.yy420,yymsp[-3].minor.yy18,yymsp[-1].minor.yy420,yymsp[-8].minor.yy70,yymsp[0].minor.yy18); - if( yymsp[-9].minor.yy489 ){ - yymsp[-9].minor.yy489->pWinDefn = yymsp[-2].minor.yy327; + yymsp[-9].minor.yy423 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy42,yymsp[-6].minor.yy167,yymsp[-5].minor.yy490,yymsp[-4].minor.yy42,yymsp[-3].minor.yy490,yymsp[-1].minor.yy42,yymsp[-8].minor.yy96,yymsp[0].minor.yy490); + if( yymsp[-9].minor.yy423 ){ + yymsp[-9].minor.yy423->pWinDefn = yymsp[-2].minor.yy147; }else{ - sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy327); + sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy147); } } break; case 89: /* values ::= VALUES LP nexprlist RP */ { - yymsp[-3].minor.yy489 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy420,0,0,0,0,0,SF_Values,0); + yymsp[-3].minor.yy423 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy42,0,0,0,0,0,SF_Values,0); } break; case 90: /* values ::= values COMMA LP nexprlist RP */ { - Select *pRight, *pLeft = yymsp[-4].minor.yy489; - pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy420,0,0,0,0,0,SF_Values|SF_MultiValue,0); + Select *pRight, *pLeft = yymsp[-4].minor.yy423; + pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy42,0,0,0,0,0,SF_Values|SF_MultiValue,0); if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue; if( pRight ){ pRight->op = TK_ALL; pRight->pPrior = pLeft; - yymsp[-4].minor.yy489 = pRight; + yymsp[-4].minor.yy423 = pRight; }else{ - yymsp[-4].minor.yy489 = pLeft; + yymsp[-4].minor.yy423 = pLeft; } } break; case 91: /* distinct ::= DISTINCT */ -{yymsp[0].minor.yy70 = SF_Distinct;} +{yymsp[0].minor.yy96 = SF_Distinct;} break; case 92: /* distinct ::= ALL */ -{yymsp[0].minor.yy70 = SF_All;} +{yymsp[0].minor.yy96 = SF_All;} break; case 94: /* sclp ::= */ case 127: /* orderby_opt ::= */ yytestcase(yyruleno==127); @@ -149918,19 +150809,19 @@ static YYACTIONTYPE yy_reduce( case 214: /* exprlist ::= */ yytestcase(yyruleno==214); case 217: /* paren_exprlist ::= */ yytestcase(yyruleno==217); case 222: /* eidlist_opt ::= */ yytestcase(yyruleno==222); -{yymsp[1].minor.yy420 = 0;} +{yymsp[1].minor.yy42 = 0;} break; case 95: /* selcollist ::= sclp scanpt expr scanpt as */ { - yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy420, yymsp[-2].minor.yy18); - if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy420, &yymsp[0].minor.yy0, 1); - sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy420,yymsp[-3].minor.yy392,yymsp[-1].minor.yy392); + yymsp[-4].minor.yy42 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy42, yymsp[-2].minor.yy490); + if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy42, &yymsp[0].minor.yy0, 1); + sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy42,yymsp[-3].minor.yy464,yymsp[-1].minor.yy464); } break; case 96: /* selcollist ::= sclp scanpt STAR */ { Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0); - yymsp[-2].minor.yy420 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy420, p); + yymsp[-2].minor.yy42 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy42, p); } break; case 97: /* selcollist ::= sclp scanpt nm DOT STAR */ @@ -149938,70 +150829,76 @@ static YYACTIONTYPE yy_reduce( Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0); Expr *pLeft = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); - yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy420, pDot); + yymsp[-4].minor.yy42 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy42, pDot); } break; case 98: /* as ::= AS nm */ case 109: /* dbnm ::= DOT nm */ yytestcase(yyruleno==109); - case 236: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==236); - case 237: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==237); + case 238: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==238); + case 239: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==239); {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;} break; case 100: /* from ::= */ -{yymsp[1].minor.yy135 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy135));} +{yymsp[1].minor.yy167 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy167));} break; case 101: /* from ::= FROM seltablist */ { - yymsp[-1].minor.yy135 = yymsp[0].minor.yy135; - sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy135); + yymsp[-1].minor.yy167 = yymsp[0].minor.yy167; + sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy167); } break; case 102: /* stl_prefix ::= seltablist joinop */ { - if( ALWAYS(yymsp[-1].minor.yy135 && yymsp[-1].minor.yy135->nSrc>0) ) yymsp[-1].minor.yy135->a[yymsp[-1].minor.yy135->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy70; + if( ALWAYS(yymsp[-1].minor.yy167 && yymsp[-1].minor.yy167->nSrc>0) ) yymsp[-1].minor.yy167->a[yymsp[-1].minor.yy167->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy96; } break; case 103: /* stl_prefix ::= */ -{yymsp[1].minor.yy135 = 0;} +{yymsp[1].minor.yy167 = 0;} break; case 104: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ { - yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy18,yymsp[0].minor.yy48); - sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy135, &yymsp[-2].minor.yy0); + yymsp[-6].minor.yy167 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy167,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy490,yymsp[0].minor.yy336); + sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy167, &yymsp[-2].minor.yy0); } break; case 105: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ { - yymsp[-8].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy135,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy18,yymsp[0].minor.yy48); - sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy135, yymsp[-4].minor.yy420); + yymsp[-8].minor.yy167 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy167,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy490,yymsp[0].minor.yy336); + sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy167, yymsp[-4].minor.yy42); } break; case 106: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */ { - yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy489,yymsp[-1].minor.yy18,yymsp[0].minor.yy48); + yymsp[-6].minor.yy167 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy167,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy423,yymsp[-1].minor.yy490,yymsp[0].minor.yy336); } break; case 107: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ { - if( yymsp[-6].minor.yy135==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy18==0 && yymsp[0].minor.yy48==0 ){ - yymsp[-6].minor.yy135 = yymsp[-4].minor.yy135; - }else if( yymsp[-4].minor.yy135->nSrc==1 ){ - yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy18,yymsp[0].minor.yy48); - if( yymsp[-6].minor.yy135 ){ - struct SrcList_item *pNew = &yymsp[-6].minor.yy135->a[yymsp[-6].minor.yy135->nSrc-1]; - struct SrcList_item *pOld = yymsp[-4].minor.yy135->a; + if( yymsp[-6].minor.yy167==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy490==0 && yymsp[0].minor.yy336==0 ){ + yymsp[-6].minor.yy167 = yymsp[-4].minor.yy167; + }else if( yymsp[-4].minor.yy167->nSrc==1 ){ + yymsp[-6].minor.yy167 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy167,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy490,yymsp[0].minor.yy336); + if( yymsp[-6].minor.yy167 ){ + struct SrcList_item *pNew = &yymsp[-6].minor.yy167->a[yymsp[-6].minor.yy167->nSrc-1]; + struct SrcList_item *pOld = yymsp[-4].minor.yy167->a; pNew->zName = pOld->zName; pNew->zDatabase = pOld->zDatabase; pNew->pSelect = pOld->pSelect; + if( pOld->fg.isTabFunc ){ + pNew->u1.pFuncArg = pOld->u1.pFuncArg; + pOld->u1.pFuncArg = 0; + pOld->fg.isTabFunc = 0; + pNew->fg.isTabFunc = 1; + } pOld->zName = pOld->zDatabase = 0; pOld->pSelect = 0; } - sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy135); + sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy167); }else{ Select *pSubquery; - sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy135); - pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy135,0,0,0,0,SF_NestedFrom,0); - yymsp[-6].minor.yy135 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy135,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy18,yymsp[0].minor.yy48); + sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy167); + pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy167,0,0,0,0,SF_NestedFrom,0); + yymsp[-6].minor.yy167 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy167,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy490,yymsp[0].minor.yy336); } } break; @@ -150011,53 +150908,54 @@ static YYACTIONTYPE yy_reduce( break; case 110: /* fullname ::= nm */ { - yylhsminor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[0].minor.yy0,0); - if( IN_RENAME_OBJECT && yylhsminor.yy135 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy135->a[0].zName, &yymsp[0].minor.yy0); + yylhsminor.yy167 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); + if( IN_RENAME_OBJECT && yylhsminor.yy167 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy167->a[0].zName, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy135 = yylhsminor.yy135; + yymsp[0].minor.yy167 = yylhsminor.yy167; break; case 111: /* fullname ::= nm DOT nm */ { - yylhsminor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); - if( IN_RENAME_OBJECT && yylhsminor.yy135 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy135->a[0].zName, &yymsp[0].minor.yy0); + yylhsminor.yy167 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); + if( IN_RENAME_OBJECT && yylhsminor.yy167 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy167->a[0].zName, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy135 = yylhsminor.yy135; + yymsp[-2].minor.yy167 = yylhsminor.yy167; break; case 112: /* xfullname ::= nm */ -{yymsp[0].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/} +{yymsp[0].minor.yy167 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/} break; case 113: /* xfullname ::= nm DOT nm */ -{yymsp[-2].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} +{yymsp[-2].minor.yy167 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} break; case 114: /* xfullname ::= nm DOT nm AS nm */ { - yymsp[-4].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/ - if( yymsp[-4].minor.yy135 ) yymsp[-4].minor.yy135->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); + yymsp[-4].minor.yy167 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/ + if( yymsp[-4].minor.yy167 ) yymsp[-4].minor.yy167->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); } break; case 115: /* xfullname ::= nm AS nm */ { - yymsp[-2].minor.yy135 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/ - if( yymsp[-2].minor.yy135 ) yymsp[-2].minor.yy135->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); + yymsp[-2].minor.yy167 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/ + if( yymsp[-2].minor.yy167 ) yymsp[-2].minor.yy167->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); } break; case 116: /* joinop ::= COMMA|JOIN */ -{ yymsp[0].minor.yy70 = JT_INNER; } +{ yymsp[0].minor.yy96 = JT_INNER; } break; case 117: /* joinop ::= JOIN_KW JOIN */ -{yymsp[-1].minor.yy70 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} +{yymsp[-1].minor.yy96 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} break; case 118: /* joinop ::= JOIN_KW nm JOIN */ -{yymsp[-2].minor.yy70 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} +{yymsp[-2].minor.yy96 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} break; case 119: /* joinop ::= JOIN_KW nm nm JOIN */ -{yymsp[-3].minor.yy70 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} +{yymsp[-3].minor.yy96 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} break; case 120: /* on_opt ::= ON expr */ case 137: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==137); case 144: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==144); case 210: /* case_else ::= ELSE expr */ yytestcase(yyruleno==210); -{yymsp[-1].minor.yy18 = yymsp[0].minor.yy18;} + case 231: /* vinto ::= INTO expr */ yytestcase(yyruleno==231); +{yymsp[-1].minor.yy490 = yymsp[0].minor.yy490;} break; case 121: /* on_opt ::= */ case 136: /* having_opt ::= */ yytestcase(yyruleno==136); @@ -150065,7 +150963,8 @@ static YYACTIONTYPE yy_reduce( case 143: /* where_opt ::= */ yytestcase(yyruleno==143); case 211: /* case_else ::= */ yytestcase(yyruleno==211); case 213: /* case_operand ::= */ yytestcase(yyruleno==213); -{yymsp[1].minor.yy18 = 0;} + case 232: /* vinto ::= */ yytestcase(yyruleno==232); +{yymsp[1].minor.yy490 = 0;} break; case 123: /* indexed_opt ::= INDEXED BY nm */ {yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;} @@ -150074,119 +150973,119 @@ static YYACTIONTYPE yy_reduce( {yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;} break; case 125: /* using_opt ::= USING LP idlist RP */ -{yymsp[-3].minor.yy48 = yymsp[-1].minor.yy48;} +{yymsp[-3].minor.yy336 = yymsp[-1].minor.yy336;} break; case 126: /* using_opt ::= */ case 158: /* idlist_opt ::= */ yytestcase(yyruleno==158); -{yymsp[1].minor.yy48 = 0;} +{yymsp[1].minor.yy336 = 0;} break; case 128: /* orderby_opt ::= ORDER BY sortlist */ case 135: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==135); -{yymsp[-2].minor.yy420 = yymsp[0].minor.yy420;} +{yymsp[-2].minor.yy42 = yymsp[0].minor.yy42;} break; case 129: /* sortlist ::= sortlist COMMA expr sortorder */ { - yymsp[-3].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy420,yymsp[-1].minor.yy18); - sqlite3ExprListSetSortOrder(yymsp[-3].minor.yy420,yymsp[0].minor.yy70); + yymsp[-3].minor.yy42 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy42,yymsp[-1].minor.yy490); + sqlite3ExprListSetSortOrder(yymsp[-3].minor.yy42,yymsp[0].minor.yy96); } break; case 130: /* sortlist ::= expr sortorder */ { - yymsp[-1].minor.yy420 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy18); /*A-overwrites-Y*/ - sqlite3ExprListSetSortOrder(yymsp[-1].minor.yy420,yymsp[0].minor.yy70); + yymsp[-1].minor.yy42 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy490); /*A-overwrites-Y*/ + sqlite3ExprListSetSortOrder(yymsp[-1].minor.yy42,yymsp[0].minor.yy96); } break; case 131: /* sortorder ::= ASC */ -{yymsp[0].minor.yy70 = SQLITE_SO_ASC;} +{yymsp[0].minor.yy96 = SQLITE_SO_ASC;} break; case 132: /* sortorder ::= DESC */ -{yymsp[0].minor.yy70 = SQLITE_SO_DESC;} +{yymsp[0].minor.yy96 = SQLITE_SO_DESC;} break; case 133: /* sortorder ::= */ -{yymsp[1].minor.yy70 = SQLITE_SO_UNDEFINED;} +{yymsp[1].minor.yy96 = SQLITE_SO_UNDEFINED;} break; case 139: /* limit_opt ::= LIMIT expr */ -{yymsp[-1].minor.yy18 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy18,0);} +{yymsp[-1].minor.yy490 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy490,0);} break; case 140: /* limit_opt ::= LIMIT expr OFFSET expr */ -{yymsp[-3].minor.yy18 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy18,yymsp[0].minor.yy18);} +{yymsp[-3].minor.yy490 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy490,yymsp[0].minor.yy490);} break; case 141: /* limit_opt ::= LIMIT expr COMMA expr */ -{yymsp[-3].minor.yy18 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy18,yymsp[-2].minor.yy18);} +{yymsp[-3].minor.yy490 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy490,yymsp[-2].minor.yy490);} break; case 142: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt */ { - sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy135, &yymsp[-1].minor.yy0); - sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy135,yymsp[0].minor.yy18,0,0); + sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy167, &yymsp[-1].minor.yy0); + sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy167,yymsp[0].minor.yy490,0,0); } break; case 145: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */ { - sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy135, &yymsp[-3].minor.yy0); - sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy420,"set list"); - sqlite3Update(pParse,yymsp[-4].minor.yy135,yymsp[-1].minor.yy420,yymsp[0].minor.yy18,yymsp[-5].minor.yy70,0,0,0); + sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy167, &yymsp[-3].minor.yy0); + sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy42,"set list"); + sqlite3Update(pParse,yymsp[-4].minor.yy167,yymsp[-1].minor.yy42,yymsp[0].minor.yy490,yymsp[-5].minor.yy96,0,0,0); } break; case 146: /* setlist ::= setlist COMMA nm EQ expr */ { - yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy420, yymsp[0].minor.yy18); - sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy420, &yymsp[-2].minor.yy0, 1); + yymsp[-4].minor.yy42 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy42, yymsp[0].minor.yy490); + sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy42, &yymsp[-2].minor.yy0, 1); } break; case 147: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ { - yymsp[-6].minor.yy420 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy420, yymsp[-3].minor.yy48, yymsp[0].minor.yy18); + yymsp[-6].minor.yy42 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy42, yymsp[-3].minor.yy336, yymsp[0].minor.yy490); } break; case 148: /* setlist ::= nm EQ expr */ { - yylhsminor.yy420 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy18); - sqlite3ExprListSetName(pParse, yylhsminor.yy420, &yymsp[-2].minor.yy0, 1); + yylhsminor.yy42 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy490); + sqlite3ExprListSetName(pParse, yylhsminor.yy42, &yymsp[-2].minor.yy0, 1); } - yymsp[-2].minor.yy420 = yylhsminor.yy420; + yymsp[-2].minor.yy42 = yylhsminor.yy42; break; case 149: /* setlist ::= LP idlist RP EQ expr */ { - yymsp[-4].minor.yy420 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy48, yymsp[0].minor.yy18); + yymsp[-4].minor.yy42 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy336, yymsp[0].minor.yy490); } break; case 150: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ { - sqlite3Insert(pParse, yymsp[-3].minor.yy135, yymsp[-1].minor.yy489, yymsp[-2].minor.yy48, yymsp[-5].minor.yy70, yymsp[0].minor.yy340); + sqlite3Insert(pParse, yymsp[-3].minor.yy167, yymsp[-1].minor.yy423, yymsp[-2].minor.yy336, yymsp[-5].minor.yy96, yymsp[0].minor.yy266); } break; case 151: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */ { - sqlite3Insert(pParse, yymsp[-3].minor.yy135, 0, yymsp[-2].minor.yy48, yymsp[-5].minor.yy70, 0); + sqlite3Insert(pParse, yymsp[-3].minor.yy167, 0, yymsp[-2].minor.yy336, yymsp[-5].minor.yy96, 0); } break; case 152: /* upsert ::= */ -{ yymsp[1].minor.yy340 = 0; } +{ yymsp[1].minor.yy266 = 0; } break; case 153: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */ -{ yymsp[-10].minor.yy340 = sqlite3UpsertNew(pParse->db,yymsp[-7].minor.yy420,yymsp[-5].minor.yy18,yymsp[-1].minor.yy420,yymsp[0].minor.yy18);} +{ yymsp[-10].minor.yy266 = sqlite3UpsertNew(pParse->db,yymsp[-7].minor.yy42,yymsp[-5].minor.yy490,yymsp[-1].minor.yy42,yymsp[0].minor.yy490);} break; case 154: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */ -{ yymsp[-7].minor.yy340 = sqlite3UpsertNew(pParse->db,yymsp[-4].minor.yy420,yymsp[-2].minor.yy18,0,0); } +{ yymsp[-7].minor.yy266 = sqlite3UpsertNew(pParse->db,yymsp[-4].minor.yy42,yymsp[-2].minor.yy490,0,0); } break; case 155: /* upsert ::= ON CONFLICT DO NOTHING */ -{ yymsp[-3].minor.yy340 = sqlite3UpsertNew(pParse->db,0,0,0,0); } +{ yymsp[-3].minor.yy266 = sqlite3UpsertNew(pParse->db,0,0,0,0); } break; case 159: /* idlist_opt ::= LP idlist RP */ -{yymsp[-2].minor.yy48 = yymsp[-1].minor.yy48;} +{yymsp[-2].minor.yy336 = yymsp[-1].minor.yy336;} break; case 160: /* idlist ::= idlist COMMA nm */ -{yymsp[-2].minor.yy48 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy48,&yymsp[0].minor.yy0);} +{yymsp[-2].minor.yy336 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy336,&yymsp[0].minor.yy0);} break; case 161: /* idlist ::= nm */ -{yymsp[0].minor.yy48 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} +{yymsp[0].minor.yy336 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} break; case 162: /* expr ::= LP expr RP */ -{yymsp[-2].minor.yy18 = yymsp[-1].minor.yy18;} +{yymsp[-2].minor.yy490 = yymsp[-1].minor.yy490;} break; case 163: /* expr ::= ID|INDEXED */ case 164: /* expr ::= JOIN_KW */ yytestcase(yyruleno==164); -{yymsp[0].minor.yy18=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} +{yymsp[0].minor.yy490=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} break; case 165: /* expr ::= nm DOT nm */ { @@ -150196,9 +151095,9 @@ static YYACTIONTYPE yy_reduce( sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[0].minor.yy0); sqlite3RenameTokenMap(pParse, (void*)temp1, &yymsp[-2].minor.yy0); } - yylhsminor.yy18 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); + yylhsminor.yy490 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); } - yymsp[-2].minor.yy18 = yylhsminor.yy18; + yymsp[-2].minor.yy490 = yylhsminor.yy490; break; case 166: /* expr ::= nm DOT nm DOT nm */ { @@ -150210,26 +151109,26 @@ static YYACTIONTYPE yy_reduce( sqlite3RenameTokenMap(pParse, (void*)temp3, &yymsp[0].minor.yy0); sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[-2].minor.yy0); } - yylhsminor.yy18 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); + yylhsminor.yy490 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); } - yymsp[-4].minor.yy18 = yylhsminor.yy18; + yymsp[-4].minor.yy490 = yylhsminor.yy490; break; case 167: /* term ::= NULL|FLOAT|BLOB */ case 168: /* term ::= STRING */ yytestcase(yyruleno==168); -{yymsp[0].minor.yy18=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} +{yymsp[0].minor.yy490=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} break; case 169: /* term ::= INTEGER */ { - yylhsminor.yy18 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); + yylhsminor.yy490 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); } - yymsp[0].minor.yy18 = yylhsminor.yy18; + yymsp[0].minor.yy490 = yylhsminor.yy490; break; case 170: /* expr ::= VARIABLE */ { if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){ u32 n = yymsp[0].minor.yy0.n; - yymsp[0].minor.yy18 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); - sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy18, n); + yymsp[0].minor.yy490 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); + sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy490, n); }else{ /* When doing a nested parse, one can include terms in an expression ** that look like this: #1 #2 ... These terms refer to registers @@ -150238,63 +151137,63 @@ static YYACTIONTYPE yy_reduce( assert( t.n>=2 ); if( pParse->nested==0 ){ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t); - yymsp[0].minor.yy18 = 0; + yymsp[0].minor.yy490 = 0; }else{ - yymsp[0].minor.yy18 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); - if( yymsp[0].minor.yy18 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy18->iTable); + yymsp[0].minor.yy490 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); + if( yymsp[0].minor.yy490 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy490->iTable); } } } break; case 171: /* expr ::= expr COLLATE ID|STRING */ { - yymsp[-2].minor.yy18 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy18, &yymsp[0].minor.yy0, 1); + yymsp[-2].minor.yy490 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy490, &yymsp[0].minor.yy0, 1); } break; case 172: /* expr ::= CAST LP expr AS typetoken RP */ { - yymsp[-5].minor.yy18 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); - sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy18, yymsp[-3].minor.yy18, 0); + yymsp[-5].minor.yy490 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); + sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy490, yymsp[-3].minor.yy490, 0); } break; case 173: /* expr ::= ID|INDEXED LP distinct exprlist RP */ { - yylhsminor.yy18 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy420, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy70); + yylhsminor.yy490 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy42, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy96); } - yymsp[-4].minor.yy18 = yylhsminor.yy18; + yymsp[-4].minor.yy490 = yylhsminor.yy490; break; case 174: /* expr ::= ID|INDEXED LP STAR RP */ { - yylhsminor.yy18 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); + yylhsminor.yy490 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); } - yymsp[-3].minor.yy18 = yylhsminor.yy18; + yymsp[-3].minor.yy490 = yylhsminor.yy490; break; case 175: /* expr ::= ID|INDEXED LP distinct exprlist RP over_clause */ { - yylhsminor.yy18 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy420, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy70); - sqlite3WindowAttach(pParse, yylhsminor.yy18, yymsp[0].minor.yy327); + yylhsminor.yy490 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy42, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy96); + sqlite3WindowAttach(pParse, yylhsminor.yy490, yymsp[0].minor.yy147); } - yymsp[-5].minor.yy18 = yylhsminor.yy18; + yymsp[-5].minor.yy490 = yylhsminor.yy490; break; case 176: /* expr ::= ID|INDEXED LP STAR RP over_clause */ { - yylhsminor.yy18 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); - sqlite3WindowAttach(pParse, yylhsminor.yy18, yymsp[0].minor.yy327); + yylhsminor.yy490 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); + sqlite3WindowAttach(pParse, yylhsminor.yy490, yymsp[0].minor.yy147); } - yymsp[-4].minor.yy18 = yylhsminor.yy18; + yymsp[-4].minor.yy490 = yylhsminor.yy490; break; case 177: /* term ::= CTIME_KW */ { - yylhsminor.yy18 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); + yylhsminor.yy490 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); } - yymsp[0].minor.yy18 = yylhsminor.yy18; + yymsp[0].minor.yy490 = yylhsminor.yy490; break; case 178: /* expr ::= LP nexprlist COMMA expr RP */ { - ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy420, yymsp[-1].minor.yy18); - yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); - if( yymsp[-4].minor.yy18 ){ - yymsp[-4].minor.yy18->x.pList = pList; + ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy42, yymsp[-1].minor.yy490); + yymsp[-4].minor.yy490 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); + if( yymsp[-4].minor.yy490 ){ + yymsp[-4].minor.yy490->x.pList = pList; }else{ sqlite3ExprListDelete(pParse->db, pList); } @@ -150308,7 +151207,7 @@ static YYACTIONTYPE yy_reduce( case 184: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==184); case 185: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==185); case 186: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==186); -{yymsp[-2].minor.yy18=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy18,yymsp[0].minor.yy18);} +{yymsp[-2].minor.yy490=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy490,yymsp[0].minor.yy490);} break; case 187: /* likeop ::= NOT LIKE_KW|MATCH */ {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/} @@ -150318,11 +151217,11 @@ static YYACTIONTYPE yy_reduce( ExprList *pList; int bNot = yymsp[-1].minor.yy0.n & 0x80000000; yymsp[-1].minor.yy0.n &= 0x7fffffff; - pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy18); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy18); - yymsp[-2].minor.yy18 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); - if( bNot ) yymsp[-2].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy18, 0); - if( yymsp[-2].minor.yy18 ) yymsp[-2].minor.yy18->flags |= EP_InfixFunc; + pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy490); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy490); + yymsp[-2].minor.yy490 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); + if( bNot ) yymsp[-2].minor.yy490 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy490, 0); + if( yymsp[-2].minor.yy490 ) yymsp[-2].minor.yy490->flags |= EP_InfixFunc; } break; case 189: /* expr ::= expr likeop expr ESCAPE expr */ @@ -150330,62 +151229,62 @@ static YYACTIONTYPE yy_reduce( ExprList *pList; int bNot = yymsp[-3].minor.yy0.n & 0x80000000; yymsp[-3].minor.yy0.n &= 0x7fffffff; - pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy18); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy18); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy18); - yymsp[-4].minor.yy18 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); - if( bNot ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0); - if( yymsp[-4].minor.yy18 ) yymsp[-4].minor.yy18->flags |= EP_InfixFunc; + pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy490); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy490); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy490); + yymsp[-4].minor.yy490 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); + if( bNot ) yymsp[-4].minor.yy490 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy490, 0); + if( yymsp[-4].minor.yy490 ) yymsp[-4].minor.yy490->flags |= EP_InfixFunc; } break; case 190: /* expr ::= expr ISNULL|NOTNULL */ -{yymsp[-1].minor.yy18 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy18,0);} +{yymsp[-1].minor.yy490 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy490,0);} break; case 191: /* expr ::= expr NOT NULL */ -{yymsp[-2].minor.yy18 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy18,0);} +{yymsp[-2].minor.yy490 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy490,0);} break; case 192: /* expr ::= expr IS expr */ { - yymsp[-2].minor.yy18 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy18,yymsp[0].minor.yy18); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy18, yymsp[-2].minor.yy18, TK_ISNULL); + yymsp[-2].minor.yy490 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy490,yymsp[0].minor.yy490); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy490, yymsp[-2].minor.yy490, TK_ISNULL); } break; case 193: /* expr ::= expr IS NOT expr */ { - yymsp[-3].minor.yy18 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy18,yymsp[0].minor.yy18); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy18, yymsp[-3].minor.yy18, TK_NOTNULL); + yymsp[-3].minor.yy490 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy490,yymsp[0].minor.yy490); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy490, yymsp[-3].minor.yy490, TK_NOTNULL); } break; case 194: /* expr ::= NOT expr */ case 195: /* expr ::= BITNOT expr */ yytestcase(yyruleno==195); -{yymsp[-1].minor.yy18 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy18, 0);/*A-overwrites-B*/} +{yymsp[-1].minor.yy490 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy490, 0);/*A-overwrites-B*/} break; case 196: /* expr ::= PLUS|MINUS expr */ { - yymsp[-1].minor.yy18 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy18, 0); + yymsp[-1].minor.yy490 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy490, 0); /*A-overwrites-B*/ } break; case 197: /* between_op ::= BETWEEN */ case 200: /* in_op ::= IN */ yytestcase(yyruleno==200); -{yymsp[0].minor.yy70 = 0;} +{yymsp[0].minor.yy96 = 0;} break; case 199: /* expr ::= expr between_op expr AND expr */ { - ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy18); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy18); - yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy18, 0); - if( yymsp[-4].minor.yy18 ){ - yymsp[-4].minor.yy18->x.pList = pList; + ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy490); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy490); + yymsp[-4].minor.yy490 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy490, 0); + if( yymsp[-4].minor.yy490 ){ + yymsp[-4].minor.yy490->x.pList = pList; }else{ sqlite3ExprListDelete(pParse->db, pList); } - if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0); + if( yymsp[-3].minor.yy96 ) yymsp[-4].minor.yy490 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy490, 0); } break; case 202: /* expr ::= expr in_op LP exprlist RP */ { - if( yymsp[-1].minor.yy420==0 ){ + if( yymsp[-1].minor.yy42==0 ){ /* Expressions of the form ** ** expr1 IN () @@ -150394,9 +151293,11 @@ static YYACTIONTYPE yy_reduce( ** simplify to constants 0 (false) and 1 (true), respectively, ** regardless of the value of expr1. */ - sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy18); - yymsp[-4].minor.yy18 = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[yymsp[-3].minor.yy70],1); - }else if( yymsp[-1].minor.yy420->nExpr==1 ){ + if( IN_RENAME_OBJECT==0 ){ + sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy490); + yymsp[-4].minor.yy490 = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[yymsp[-3].minor.yy96],1); + } + }else if( yymsp[-1].minor.yy42->nExpr==1 ){ /* Expressions of the form: ** ** expr1 IN (?1) @@ -150413,199 +151314,199 @@ static YYACTIONTYPE yy_reduce( ** affinity or the collating sequence to use for comparison. Otherwise, ** the semantics would be subtly different from IN or NOT IN. */ - Expr *pRHS = yymsp[-1].minor.yy420->a[0].pExpr; - yymsp[-1].minor.yy420->a[0].pExpr = 0; - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy420); + Expr *pRHS = yymsp[-1].minor.yy42->a[0].pExpr; + yymsp[-1].minor.yy42->a[0].pExpr = 0; + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy42); /* pRHS cannot be NULL because a malloc error would have been detected ** before now and control would have never reached this point */ if( ALWAYS(pRHS) ){ pRHS->flags &= ~EP_Collate; pRHS->flags |= EP_Generic; } - yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, yymsp[-3].minor.yy70 ? TK_NE : TK_EQ, yymsp[-4].minor.yy18, pRHS); + yymsp[-4].minor.yy490 = sqlite3PExpr(pParse, yymsp[-3].minor.yy96 ? TK_NE : TK_EQ, yymsp[-4].minor.yy490, pRHS); }else{ - yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy18, 0); - if( yymsp[-4].minor.yy18 ){ - yymsp[-4].minor.yy18->x.pList = yymsp[-1].minor.yy420; - sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy18); + yymsp[-4].minor.yy490 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy490, 0); + if( yymsp[-4].minor.yy490 ){ + yymsp[-4].minor.yy490->x.pList = yymsp[-1].minor.yy42; + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy490); }else{ - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy420); + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy42); } - if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0); + if( yymsp[-3].minor.yy96 ) yymsp[-4].minor.yy490 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy490, 0); } } break; case 203: /* expr ::= LP select RP */ { - yymsp[-2].minor.yy18 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); - sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy18, yymsp[-1].minor.yy489); + yymsp[-2].minor.yy490 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); + sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy490, yymsp[-1].minor.yy423); } break; case 204: /* expr ::= expr in_op LP select RP */ { - yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy18, 0); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy18, yymsp[-1].minor.yy489); - if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0); + yymsp[-4].minor.yy490 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy490, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy490, yymsp[-1].minor.yy423); + if( yymsp[-3].minor.yy96 ) yymsp[-4].minor.yy490 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy490, 0); } break; case 205: /* expr ::= expr in_op nm dbnm paren_exprlist */ { - SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); + SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0); - if( yymsp[0].minor.yy420 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy420); - yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy18, 0); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy18, pSelect); - if( yymsp[-3].minor.yy70 ) yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy18, 0); + if( yymsp[0].minor.yy42 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy42); + yymsp[-4].minor.yy490 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy490, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy490, pSelect); + if( yymsp[-3].minor.yy96 ) yymsp[-4].minor.yy490 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy490, 0); } break; case 206: /* expr ::= EXISTS LP select RP */ { Expr *p; - p = yymsp[-3].minor.yy18 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); - sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy489); + p = yymsp[-3].minor.yy490 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); + sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy423); } break; case 207: /* expr ::= CASE case_operand case_exprlist case_else END */ { - yymsp[-4].minor.yy18 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy18, 0); - if( yymsp[-4].minor.yy18 ){ - yymsp[-4].minor.yy18->x.pList = yymsp[-1].minor.yy18 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy420,yymsp[-1].minor.yy18) : yymsp[-2].minor.yy420; - sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy18); + yymsp[-4].minor.yy490 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy490, 0); + if( yymsp[-4].minor.yy490 ){ + yymsp[-4].minor.yy490->x.pList = yymsp[-1].minor.yy490 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy42,yymsp[-1].minor.yy490) : yymsp[-2].minor.yy42; + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy490); }else{ - sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy420); - sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy18); + sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy42); + sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy490); } } break; case 208: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ { - yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy420, yymsp[-2].minor.yy18); - yymsp[-4].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy420, yymsp[0].minor.yy18); + yymsp[-4].minor.yy42 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy42, yymsp[-2].minor.yy490); + yymsp[-4].minor.yy42 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy42, yymsp[0].minor.yy490); } break; case 209: /* case_exprlist ::= WHEN expr THEN expr */ { - yymsp[-3].minor.yy420 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy18); - yymsp[-3].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy420, yymsp[0].minor.yy18); + yymsp[-3].minor.yy42 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy490); + yymsp[-3].minor.yy42 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy42, yymsp[0].minor.yy490); } break; case 212: /* case_operand ::= expr */ -{yymsp[0].minor.yy18 = yymsp[0].minor.yy18; /*A-overwrites-X*/} +{yymsp[0].minor.yy490 = yymsp[0].minor.yy490; /*A-overwrites-X*/} break; case 215: /* nexprlist ::= nexprlist COMMA expr */ -{yymsp[-2].minor.yy420 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy420,yymsp[0].minor.yy18);} +{yymsp[-2].minor.yy42 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy42,yymsp[0].minor.yy490);} break; case 216: /* nexprlist ::= expr */ -{yymsp[0].minor.yy420 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy18); /*A-overwrites-Y*/} +{yymsp[0].minor.yy42 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy490); /*A-overwrites-Y*/} break; case 218: /* paren_exprlist ::= LP exprlist RP */ case 223: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==223); -{yymsp[-2].minor.yy420 = yymsp[-1].minor.yy420;} +{yymsp[-2].minor.yy42 = yymsp[-1].minor.yy42;} break; case 219: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ { sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, - sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy420, yymsp[-10].minor.yy70, - &yymsp[-11].minor.yy0, yymsp[0].minor.yy18, SQLITE_SO_ASC, yymsp[-8].minor.yy70, SQLITE_IDXTYPE_APPDEF); + sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy42, yymsp[-10].minor.yy96, + &yymsp[-11].minor.yy0, yymsp[0].minor.yy490, SQLITE_SO_ASC, yymsp[-8].minor.yy96, SQLITE_IDXTYPE_APPDEF); if( IN_RENAME_OBJECT && pParse->pNewIndex ){ sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0); } } break; case 220: /* uniqueflag ::= UNIQUE */ - case 260: /* raisetype ::= ABORT */ yytestcase(yyruleno==260); -{yymsp[0].minor.yy70 = OE_Abort;} + case 262: /* raisetype ::= ABORT */ yytestcase(yyruleno==262); +{yymsp[0].minor.yy96 = OE_Abort;} break; case 221: /* uniqueflag ::= */ -{yymsp[1].minor.yy70 = OE_None;} +{yymsp[1].minor.yy96 = OE_None;} break; case 224: /* eidlist ::= eidlist COMMA nm collate sortorder */ { - yymsp[-4].minor.yy420 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy420, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy70, yymsp[0].minor.yy70); + yymsp[-4].minor.yy42 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy42, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy96, yymsp[0].minor.yy96); } break; case 225: /* eidlist ::= nm collate sortorder */ { - yymsp[-2].minor.yy420 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy70, yymsp[0].minor.yy70); /*A-overwrites-Y*/ + yymsp[-2].minor.yy42 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy96, yymsp[0].minor.yy96); /*A-overwrites-Y*/ } break; case 228: /* cmd ::= DROP INDEX ifexists fullname */ -{sqlite3DropIndex(pParse, yymsp[0].minor.yy135, yymsp[-1].minor.yy70);} +{sqlite3DropIndex(pParse, yymsp[0].minor.yy167, yymsp[-1].minor.yy96);} break; - case 229: /* cmd ::= VACUUM */ -{sqlite3Vacuum(pParse,0);} + case 229: /* cmd ::= VACUUM vinto */ +{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy490);} break; - case 230: /* cmd ::= VACUUM nm */ -{sqlite3Vacuum(pParse,&yymsp[0].minor.yy0);} + case 230: /* cmd ::= VACUUM nm vinto */ +{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy490);} break; - case 231: /* cmd ::= PRAGMA nm dbnm */ + case 233: /* cmd ::= PRAGMA nm dbnm */ {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} break; - case 232: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ + case 234: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);} break; - case 233: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ + case 235: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);} break; - case 234: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ + case 236: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);} break; - case 235: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ + case 237: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);} break; - case 238: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + case 240: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ { Token all; all.z = yymsp[-3].minor.yy0.z; all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n; - sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy207, &all); + sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy119, &all); } break; - case 239: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + case 241: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ { - sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy70, yymsp[-4].minor.yy34.a, yymsp[-4].minor.yy34.b, yymsp[-2].minor.yy135, yymsp[0].minor.yy18, yymsp[-10].minor.yy70, yymsp[-8].minor.yy70); + sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy96, yymsp[-4].minor.yy350.a, yymsp[-4].minor.yy350.b, yymsp[-2].minor.yy167, yymsp[0].minor.yy490, yymsp[-10].minor.yy96, yymsp[-8].minor.yy96); yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/ } break; - case 240: /* trigger_time ::= BEFORE|AFTER */ -{ yymsp[0].minor.yy70 = yymsp[0].major; /*A-overwrites-X*/ } + case 242: /* trigger_time ::= BEFORE|AFTER */ +{ yymsp[0].minor.yy96 = yymsp[0].major; /*A-overwrites-X*/ } break; - case 241: /* trigger_time ::= INSTEAD OF */ -{ yymsp[-1].minor.yy70 = TK_INSTEAD;} + case 243: /* trigger_time ::= INSTEAD OF */ +{ yymsp[-1].minor.yy96 = TK_INSTEAD;} break; - case 242: /* trigger_time ::= */ -{ yymsp[1].minor.yy70 = TK_BEFORE; } + case 244: /* trigger_time ::= */ +{ yymsp[1].minor.yy96 = TK_BEFORE; } break; - case 243: /* trigger_event ::= DELETE|INSERT */ - case 244: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==244); -{yymsp[0].minor.yy34.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy34.b = 0;} + case 245: /* trigger_event ::= DELETE|INSERT */ + case 246: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==246); +{yymsp[0].minor.yy350.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy350.b = 0;} break; - case 245: /* trigger_event ::= UPDATE OF idlist */ -{yymsp[-2].minor.yy34.a = TK_UPDATE; yymsp[-2].minor.yy34.b = yymsp[0].minor.yy48;} + case 247: /* trigger_event ::= UPDATE OF idlist */ +{yymsp[-2].minor.yy350.a = TK_UPDATE; yymsp[-2].minor.yy350.b = yymsp[0].minor.yy336;} break; - case 246: /* when_clause ::= */ - case 265: /* key_opt ::= */ yytestcase(yyruleno==265); - case 307: /* filter_opt ::= */ yytestcase(yyruleno==307); -{ yymsp[1].minor.yy18 = 0; } + case 248: /* when_clause ::= */ + case 267: /* key_opt ::= */ yytestcase(yyruleno==267); + case 309: /* filter_opt ::= */ yytestcase(yyruleno==309); +{ yymsp[1].minor.yy490 = 0; } break; - case 247: /* when_clause ::= WHEN expr */ - case 266: /* key_opt ::= KEY expr */ yytestcase(yyruleno==266); -{ yymsp[-1].minor.yy18 = yymsp[0].minor.yy18; } + case 249: /* when_clause ::= WHEN expr */ + case 268: /* key_opt ::= KEY expr */ yytestcase(yyruleno==268); +{ yymsp[-1].minor.yy490 = yymsp[0].minor.yy490; } break; - case 248: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + case 250: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ { - assert( yymsp[-2].minor.yy207!=0 ); - yymsp[-2].minor.yy207->pLast->pNext = yymsp[-1].minor.yy207; - yymsp[-2].minor.yy207->pLast = yymsp[-1].minor.yy207; + assert( yymsp[-2].minor.yy119!=0 ); + yymsp[-2].minor.yy119->pLast->pNext = yymsp[-1].minor.yy119; + yymsp[-2].minor.yy119->pLast = yymsp[-1].minor.yy119; } break; - case 249: /* trigger_cmd_list ::= trigger_cmd SEMI */ + case 251: /* trigger_cmd_list ::= trigger_cmd SEMI */ { - assert( yymsp[-1].minor.yy207!=0 ); - yymsp[-1].minor.yy207->pLast = yymsp[-1].minor.yy207; + assert( yymsp[-1].minor.yy119!=0 ); + yymsp[-1].minor.yy119->pLast = yymsp[-1].minor.yy119; } break; - case 250: /* trnm ::= nm DOT nm */ + case 252: /* trnm ::= nm DOT nm */ { yymsp[-2].minor.yy0 = yymsp[0].minor.yy0; sqlite3ErrorMsg(pParse, @@ -150613,312 +151514,312 @@ static YYACTIONTYPE yy_reduce( "statements within triggers"); } break; - case 251: /* tridxby ::= INDEXED BY nm */ + case 253: /* tridxby ::= INDEXED BY nm */ { sqlite3ErrorMsg(pParse, "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 252: /* tridxby ::= NOT INDEXED */ + case 254: /* tridxby ::= NOT INDEXED */ { sqlite3ErrorMsg(pParse, "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 253: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */ -{yylhsminor.yy207 = sqlite3TriggerUpdateStep(pParse, &yymsp[-5].minor.yy0, yymsp[-2].minor.yy420, yymsp[-1].minor.yy18, yymsp[-6].minor.yy70, yymsp[-7].minor.yy0.z, yymsp[0].minor.yy392);} - yymsp[-7].minor.yy207 = yylhsminor.yy207; + case 255: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */ +{yylhsminor.yy119 = sqlite3TriggerUpdateStep(pParse, &yymsp[-5].minor.yy0, yymsp[-2].minor.yy42, yymsp[-1].minor.yy490, yymsp[-6].minor.yy96, yymsp[-7].minor.yy0.z, yymsp[0].minor.yy464);} + yymsp[-7].minor.yy119 = yylhsminor.yy119; break; - case 254: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + case 256: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ { - yylhsminor.yy207 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy48,yymsp[-2].minor.yy489,yymsp[-6].minor.yy70,yymsp[-1].minor.yy340,yymsp[-7].minor.yy392,yymsp[0].minor.yy392);/*yylhsminor.yy207-overwrites-yymsp[-6].minor.yy70*/ + yylhsminor.yy119 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy336,yymsp[-2].minor.yy423,yymsp[-6].minor.yy96,yymsp[-1].minor.yy266,yymsp[-7].minor.yy464,yymsp[0].minor.yy464);/*yylhsminor.yy119-overwrites-yymsp[-6].minor.yy96*/ } - yymsp[-7].minor.yy207 = yylhsminor.yy207; + yymsp[-7].minor.yy119 = yylhsminor.yy119; break; - case 255: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ -{yylhsminor.yy207 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy18, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy392);} - yymsp[-5].minor.yy207 = yylhsminor.yy207; + case 257: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ +{yylhsminor.yy119 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy490, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy464);} + yymsp[-5].minor.yy119 = yylhsminor.yy119; break; - case 256: /* trigger_cmd ::= scanpt select scanpt */ -{yylhsminor.yy207 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy489, yymsp[-2].minor.yy392, yymsp[0].minor.yy392); /*yylhsminor.yy207-overwrites-yymsp[-1].minor.yy489*/} - yymsp[-2].minor.yy207 = yylhsminor.yy207; + case 258: /* trigger_cmd ::= scanpt select scanpt */ +{yylhsminor.yy119 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy423, yymsp[-2].minor.yy464, yymsp[0].minor.yy464); /*yylhsminor.yy119-overwrites-yymsp[-1].minor.yy423*/} + yymsp[-2].minor.yy119 = yylhsminor.yy119; break; - case 257: /* expr ::= RAISE LP IGNORE RP */ + case 259: /* expr ::= RAISE LP IGNORE RP */ { - yymsp[-3].minor.yy18 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); - if( yymsp[-3].minor.yy18 ){ - yymsp[-3].minor.yy18->affinity = OE_Ignore; + yymsp[-3].minor.yy490 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); + if( yymsp[-3].minor.yy490 ){ + yymsp[-3].minor.yy490->affinity = OE_Ignore; } } break; - case 258: /* expr ::= RAISE LP raisetype COMMA nm RP */ + case 260: /* expr ::= RAISE LP raisetype COMMA nm RP */ { - yymsp[-5].minor.yy18 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); - if( yymsp[-5].minor.yy18 ) { - yymsp[-5].minor.yy18->affinity = (char)yymsp[-3].minor.yy70; + yymsp[-5].minor.yy490 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); + if( yymsp[-5].minor.yy490 ) { + yymsp[-5].minor.yy490->affinity = (char)yymsp[-3].minor.yy96; } } break; - case 259: /* raisetype ::= ROLLBACK */ -{yymsp[0].minor.yy70 = OE_Rollback;} + case 261: /* raisetype ::= ROLLBACK */ +{yymsp[0].minor.yy96 = OE_Rollback;} break; - case 261: /* raisetype ::= FAIL */ -{yymsp[0].minor.yy70 = OE_Fail;} + case 263: /* raisetype ::= FAIL */ +{yymsp[0].minor.yy96 = OE_Fail;} break; - case 262: /* cmd ::= DROP TRIGGER ifexists fullname */ + case 264: /* cmd ::= DROP TRIGGER ifexists fullname */ { - sqlite3DropTrigger(pParse,yymsp[0].minor.yy135,yymsp[-1].minor.yy70); + sqlite3DropTrigger(pParse,yymsp[0].minor.yy167,yymsp[-1].minor.yy96); } break; - case 263: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + case 265: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ { - sqlite3Attach(pParse, yymsp[-3].minor.yy18, yymsp[-1].minor.yy18, yymsp[0].minor.yy18); + sqlite3Attach(pParse, yymsp[-3].minor.yy490, yymsp[-1].minor.yy490, yymsp[0].minor.yy490); } break; - case 264: /* cmd ::= DETACH database_kw_opt expr */ + case 266: /* cmd ::= DETACH database_kw_opt expr */ { - sqlite3Detach(pParse, yymsp[0].minor.yy18); + sqlite3Detach(pParse, yymsp[0].minor.yy490); } break; - case 267: /* cmd ::= REINDEX */ + case 269: /* cmd ::= REINDEX */ {sqlite3Reindex(pParse, 0, 0);} break; - case 268: /* cmd ::= REINDEX nm dbnm */ + case 270: /* cmd ::= REINDEX nm dbnm */ {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 269: /* cmd ::= ANALYZE */ + case 271: /* cmd ::= ANALYZE */ {sqlite3Analyze(pParse, 0, 0);} break; - case 270: /* cmd ::= ANALYZE nm dbnm */ + case 272: /* cmd ::= ANALYZE nm dbnm */ {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 271: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ + case 273: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ { - sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy135,&yymsp[0].minor.yy0); + sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy167,&yymsp[0].minor.yy0); } break; - case 272: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + case 274: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ { yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n; sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0); } break; - case 273: /* add_column_fullname ::= fullname */ + case 275: /* add_column_fullname ::= fullname */ { disableLookaside(pParse); - sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy135); + sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy167); } break; - case 274: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + case 276: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ { - sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy135, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); + sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy167, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } break; - case 275: /* cmd ::= create_vtab */ + case 277: /* cmd ::= create_vtab */ {sqlite3VtabFinishParse(pParse,0);} break; - case 276: /* cmd ::= create_vtab LP vtabarglist RP */ + case 278: /* cmd ::= create_vtab LP vtabarglist RP */ {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} break; - case 277: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + case 279: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ { - sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy70); + sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy96); } break; - case 278: /* vtabarg ::= */ + case 280: /* vtabarg ::= */ {sqlite3VtabArgInit(pParse);} break; - case 279: /* vtabargtoken ::= ANY */ - case 280: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==280); - case 281: /* lp ::= LP */ yytestcase(yyruleno==281); + case 281: /* vtabargtoken ::= ANY */ + case 282: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==282); + case 283: /* lp ::= LP */ yytestcase(yyruleno==283); {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} break; - case 282: /* with ::= WITH wqlist */ - case 283: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==283); -{ sqlite3WithPush(pParse, yymsp[0].minor.yy449, 1); } + case 284: /* with ::= WITH wqlist */ + case 285: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==285); +{ sqlite3WithPush(pParse, yymsp[0].minor.yy499, 1); } break; - case 284: /* wqlist ::= nm eidlist_opt AS LP select RP */ + case 286: /* wqlist ::= nm eidlist_opt AS LP select RP */ { - yymsp[-5].minor.yy449 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy420, yymsp[-1].minor.yy489); /*A-overwrites-X*/ + yymsp[-5].minor.yy499 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy42, yymsp[-1].minor.yy423); /*A-overwrites-X*/ } break; - case 285: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */ + case 287: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */ { - yymsp[-7].minor.yy449 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy449, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy420, yymsp[-1].minor.yy489); + yymsp[-7].minor.yy499 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy499, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy42, yymsp[-1].minor.yy423); } break; - case 286: /* windowdefn_list ::= windowdefn */ -{ yylhsminor.yy327 = yymsp[0].minor.yy327; } - yymsp[0].minor.yy327 = yylhsminor.yy327; + case 288: /* windowdefn_list ::= windowdefn */ +{ yylhsminor.yy147 = yymsp[0].minor.yy147; } + yymsp[0].minor.yy147 = yylhsminor.yy147; break; - case 287: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ + case 289: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ { - assert( yymsp[0].minor.yy327!=0 ); - yymsp[0].minor.yy327->pNextWin = yymsp[-2].minor.yy327; - yylhsminor.yy327 = yymsp[0].minor.yy327; + assert( yymsp[0].minor.yy147!=0 ); + yymsp[0].minor.yy147->pNextWin = yymsp[-2].minor.yy147; + yylhsminor.yy147 = yymsp[0].minor.yy147; } - yymsp[-2].minor.yy327 = yylhsminor.yy327; + yymsp[-2].minor.yy147 = yylhsminor.yy147; break; - case 288: /* windowdefn ::= nm AS window */ + case 290: /* windowdefn ::= nm AS window */ { - if( ALWAYS(yymsp[0].minor.yy327) ){ - yymsp[0].minor.yy327->zName = sqlite3DbStrNDup(pParse->db, yymsp[-2].minor.yy0.z, yymsp[-2].minor.yy0.n); + if( ALWAYS(yymsp[0].minor.yy147) ){ + yymsp[0].minor.yy147->zName = sqlite3DbStrNDup(pParse->db, yymsp[-2].minor.yy0.z, yymsp[-2].minor.yy0.n); } - yylhsminor.yy327 = yymsp[0].minor.yy327; + yylhsminor.yy147 = yymsp[0].minor.yy147; } - yymsp[-2].minor.yy327 = yylhsminor.yy327; + yymsp[-2].minor.yy147 = yylhsminor.yy147; break; - case 289: /* window ::= LP part_opt orderby_opt frame_opt RP */ + case 291: /* window ::= LP part_opt orderby_opt frame_opt RP */ { - yymsp[-4].minor.yy327 = yymsp[-1].minor.yy327; - if( ALWAYS(yymsp[-4].minor.yy327) ){ - yymsp[-4].minor.yy327->pPartition = yymsp[-3].minor.yy420; - yymsp[-4].minor.yy327->pOrderBy = yymsp[-2].minor.yy420; + yymsp[-4].minor.yy147 = yymsp[-1].minor.yy147; + if( ALWAYS(yymsp[-4].minor.yy147) ){ + yymsp[-4].minor.yy147->pPartition = yymsp[-3].minor.yy42; + yymsp[-4].minor.yy147->pOrderBy = yymsp[-2].minor.yy42; } } break; - case 290: /* part_opt ::= PARTITION BY nexprlist */ -{ yymsp[-2].minor.yy420 = yymsp[0].minor.yy420; } + case 292: /* part_opt ::= PARTITION BY nexprlist */ +{ yymsp[-2].minor.yy42 = yymsp[0].minor.yy42; } break; - case 291: /* part_opt ::= */ -{ yymsp[1].minor.yy420 = 0; } + case 293: /* part_opt ::= */ +{ yymsp[1].minor.yy42 = 0; } break; - case 292: /* frame_opt ::= */ + case 294: /* frame_opt ::= */ { - yymsp[1].minor.yy327 = sqlite3WindowAlloc(pParse, TK_RANGE, TK_UNBOUNDED, 0, TK_CURRENT, 0); + yymsp[1].minor.yy147 = sqlite3WindowAlloc(pParse, TK_RANGE, TK_UNBOUNDED, 0, TK_CURRENT, 0); } break; - case 293: /* frame_opt ::= range_or_rows frame_bound_s */ + case 295: /* frame_opt ::= range_or_rows frame_bound_s */ { - yylhsminor.yy327 = sqlite3WindowAlloc(pParse, yymsp[-1].minor.yy70, yymsp[0].minor.yy119.eType, yymsp[0].minor.yy119.pExpr, TK_CURRENT, 0); + yylhsminor.yy147 = sqlite3WindowAlloc(pParse, yymsp[-1].minor.yy96, yymsp[0].minor.yy317.eType, yymsp[0].minor.yy317.pExpr, TK_CURRENT, 0); } - yymsp[-1].minor.yy327 = yylhsminor.yy327; + yymsp[-1].minor.yy147 = yylhsminor.yy147; break; - case 294: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e */ + case 296: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e */ { - yylhsminor.yy327 = sqlite3WindowAlloc(pParse, yymsp[-4].minor.yy70, yymsp[-2].minor.yy119.eType, yymsp[-2].minor.yy119.pExpr, yymsp[0].minor.yy119.eType, yymsp[0].minor.yy119.pExpr); + yylhsminor.yy147 = sqlite3WindowAlloc(pParse, yymsp[-4].minor.yy96, yymsp[-2].minor.yy317.eType, yymsp[-2].minor.yy317.pExpr, yymsp[0].minor.yy317.eType, yymsp[0].minor.yy317.pExpr); } - yymsp[-4].minor.yy327 = yylhsminor.yy327; + yymsp[-4].minor.yy147 = yylhsminor.yy147; break; - case 295: /* range_or_rows ::= RANGE */ -{ yymsp[0].minor.yy70 = TK_RANGE; } + case 297: /* range_or_rows ::= RANGE */ +{ yymsp[0].minor.yy96 = TK_RANGE; } break; - case 296: /* range_or_rows ::= ROWS */ -{ yymsp[0].minor.yy70 = TK_ROWS; } + case 298: /* range_or_rows ::= ROWS */ +{ yymsp[0].minor.yy96 = TK_ROWS; } break; - case 297: /* frame_bound_s ::= frame_bound */ - case 299: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==299); -{ yylhsminor.yy119 = yymsp[0].minor.yy119; } - yymsp[0].minor.yy119 = yylhsminor.yy119; + case 299: /* frame_bound_s ::= frame_bound */ + case 301: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==301); +{ yylhsminor.yy317 = yymsp[0].minor.yy317; } + yymsp[0].minor.yy317 = yylhsminor.yy317; break; - case 298: /* frame_bound_s ::= UNBOUNDED PRECEDING */ - case 300: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==300); -{yymsp[-1].minor.yy119.eType = TK_UNBOUNDED; yymsp[-1].minor.yy119.pExpr = 0;} + case 300: /* frame_bound_s ::= UNBOUNDED PRECEDING */ + case 302: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==302); +{yymsp[-1].minor.yy317.eType = TK_UNBOUNDED; yymsp[-1].minor.yy317.pExpr = 0;} break; - case 301: /* frame_bound ::= expr PRECEDING */ -{ yylhsminor.yy119.eType = TK_PRECEDING; yylhsminor.yy119.pExpr = yymsp[-1].minor.yy18; } - yymsp[-1].minor.yy119 = yylhsminor.yy119; + case 303: /* frame_bound ::= expr PRECEDING */ +{ yylhsminor.yy317.eType = TK_PRECEDING; yylhsminor.yy317.pExpr = yymsp[-1].minor.yy490; } + yymsp[-1].minor.yy317 = yylhsminor.yy317; break; - case 302: /* frame_bound ::= CURRENT ROW */ -{ yymsp[-1].minor.yy119.eType = TK_CURRENT ; yymsp[-1].minor.yy119.pExpr = 0; } + case 304: /* frame_bound ::= CURRENT ROW */ +{ yymsp[-1].minor.yy317.eType = TK_CURRENT ; yymsp[-1].minor.yy317.pExpr = 0; } break; - case 303: /* frame_bound ::= expr FOLLOWING */ -{ yylhsminor.yy119.eType = TK_FOLLOWING; yylhsminor.yy119.pExpr = yymsp[-1].minor.yy18; } - yymsp[-1].minor.yy119 = yylhsminor.yy119; + case 305: /* frame_bound ::= expr FOLLOWING */ +{ yylhsminor.yy317.eType = TK_FOLLOWING; yylhsminor.yy317.pExpr = yymsp[-1].minor.yy490; } + yymsp[-1].minor.yy317 = yylhsminor.yy317; break; - case 304: /* window_clause ::= WINDOW windowdefn_list */ -{ yymsp[-1].minor.yy327 = yymsp[0].minor.yy327; } + case 306: /* window_clause ::= WINDOW windowdefn_list */ +{ yymsp[-1].minor.yy147 = yymsp[0].minor.yy147; } break; - case 305: /* over_clause ::= filter_opt OVER window */ + case 307: /* over_clause ::= filter_opt OVER window */ { - yylhsminor.yy327 = yymsp[0].minor.yy327; - assert( yylhsminor.yy327!=0 ); - yylhsminor.yy327->pFilter = yymsp[-2].minor.yy18; + yylhsminor.yy147 = yymsp[0].minor.yy147; + assert( yylhsminor.yy147!=0 ); + yylhsminor.yy147->pFilter = yymsp[-2].minor.yy490; } - yymsp[-2].minor.yy327 = yylhsminor.yy327; + yymsp[-2].minor.yy147 = yylhsminor.yy147; break; - case 306: /* over_clause ::= filter_opt OVER nm */ + case 308: /* over_clause ::= filter_opt OVER nm */ { - yylhsminor.yy327 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); - if( yylhsminor.yy327 ){ - yylhsminor.yy327->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n); - yylhsminor.yy327->pFilter = yymsp[-2].minor.yy18; + yylhsminor.yy147 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); + if( yylhsminor.yy147 ){ + yylhsminor.yy147->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n); + yylhsminor.yy147->pFilter = yymsp[-2].minor.yy490; }else{ - sqlite3ExprDelete(pParse->db, yymsp[-2].minor.yy18); + sqlite3ExprDelete(pParse->db, yymsp[-2].minor.yy490); } } - yymsp[-2].minor.yy327 = yylhsminor.yy327; + yymsp[-2].minor.yy147 = yylhsminor.yy147; break; - case 308: /* filter_opt ::= FILTER LP WHERE expr RP */ -{ yymsp[-4].minor.yy18 = yymsp[-1].minor.yy18; } + case 310: /* filter_opt ::= FILTER LP WHERE expr RP */ +{ yymsp[-4].minor.yy490 = yymsp[-1].minor.yy490; } break; default: - /* (309) input ::= cmdlist */ yytestcase(yyruleno==309); - /* (310) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==310); - /* (311) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=311); - /* (312) ecmd ::= SEMI */ yytestcase(yyruleno==312); - /* (313) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==313); - /* (314) ecmd ::= explain cmdx */ yytestcase(yyruleno==314); - /* (315) trans_opt ::= */ yytestcase(yyruleno==315); - /* (316) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==316); - /* (317) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==317); - /* (318) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==318); - /* (319) savepoint_opt ::= */ yytestcase(yyruleno==319); - /* (320) cmd ::= create_table create_table_args */ yytestcase(yyruleno==320); - /* (321) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==321); - /* (322) columnlist ::= columnname carglist */ yytestcase(yyruleno==322); - /* (323) nm ::= ID|INDEXED */ yytestcase(yyruleno==323); - /* (324) nm ::= STRING */ yytestcase(yyruleno==324); - /* (325) nm ::= JOIN_KW */ yytestcase(yyruleno==325); - /* (326) typetoken ::= typename */ yytestcase(yyruleno==326); - /* (327) typename ::= ID|STRING */ yytestcase(yyruleno==327); - /* (328) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=328); - /* (329) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=329); - /* (330) carglist ::= carglist ccons */ yytestcase(yyruleno==330); - /* (331) carglist ::= */ yytestcase(yyruleno==331); - /* (332) ccons ::= NULL onconf */ yytestcase(yyruleno==332); - /* (333) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==333); - /* (334) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==334); - /* (335) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=335); - /* (336) tconscomma ::= */ yytestcase(yyruleno==336); - /* (337) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=337); - /* (338) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=338); - /* (339) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=339); - /* (340) oneselect ::= values */ yytestcase(yyruleno==340); - /* (341) sclp ::= selcollist COMMA */ yytestcase(yyruleno==341); - /* (342) as ::= ID|STRING */ yytestcase(yyruleno==342); - /* (343) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=343); - /* (344) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==344); - /* (345) exprlist ::= nexprlist */ yytestcase(yyruleno==345); - /* (346) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=346); - /* (347) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=347); - /* (348) nmnum ::= ON */ yytestcase(yyruleno==348); - /* (349) nmnum ::= DELETE */ yytestcase(yyruleno==349); - /* (350) nmnum ::= DEFAULT */ yytestcase(yyruleno==350); - /* (351) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==351); - /* (352) foreach_clause ::= */ yytestcase(yyruleno==352); - /* (353) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==353); - /* (354) trnm ::= nm */ yytestcase(yyruleno==354); - /* (355) tridxby ::= */ yytestcase(yyruleno==355); - /* (356) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==356); - /* (357) database_kw_opt ::= */ yytestcase(yyruleno==357); - /* (358) kwcolumn_opt ::= */ yytestcase(yyruleno==358); - /* (359) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==359); - /* (360) vtabarglist ::= vtabarg */ yytestcase(yyruleno==360); - /* (361) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==361); - /* (362) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==362); - /* (363) anylist ::= */ yytestcase(yyruleno==363); - /* (364) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==364); - /* (365) anylist ::= anylist ANY */ yytestcase(yyruleno==365); - /* (366) with ::= */ yytestcase(yyruleno==366); + /* (311) input ::= cmdlist */ yytestcase(yyruleno==311); + /* (312) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==312); + /* (313) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=313); + /* (314) ecmd ::= SEMI */ yytestcase(yyruleno==314); + /* (315) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==315); + /* (316) ecmd ::= explain cmdx */ yytestcase(yyruleno==316); + /* (317) trans_opt ::= */ yytestcase(yyruleno==317); + /* (318) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==318); + /* (319) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==319); + /* (320) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==320); + /* (321) savepoint_opt ::= */ yytestcase(yyruleno==321); + /* (322) cmd ::= create_table create_table_args */ yytestcase(yyruleno==322); + /* (323) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==323); + /* (324) columnlist ::= columnname carglist */ yytestcase(yyruleno==324); + /* (325) nm ::= ID|INDEXED */ yytestcase(yyruleno==325); + /* (326) nm ::= STRING */ yytestcase(yyruleno==326); + /* (327) nm ::= JOIN_KW */ yytestcase(yyruleno==327); + /* (328) typetoken ::= typename */ yytestcase(yyruleno==328); + /* (329) typename ::= ID|STRING */ yytestcase(yyruleno==329); + /* (330) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=330); + /* (331) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=331); + /* (332) carglist ::= carglist ccons */ yytestcase(yyruleno==332); + /* (333) carglist ::= */ yytestcase(yyruleno==333); + /* (334) ccons ::= NULL onconf */ yytestcase(yyruleno==334); + /* (335) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==335); + /* (336) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==336); + /* (337) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=337); + /* (338) tconscomma ::= */ yytestcase(yyruleno==338); + /* (339) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=339); + /* (340) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=340); + /* (341) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=341); + /* (342) oneselect ::= values */ yytestcase(yyruleno==342); + /* (343) sclp ::= selcollist COMMA */ yytestcase(yyruleno==343); + /* (344) as ::= ID|STRING */ yytestcase(yyruleno==344); + /* (345) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=345); + /* (346) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==346); + /* (347) exprlist ::= nexprlist */ yytestcase(yyruleno==347); + /* (348) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=348); + /* (349) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=349); + /* (350) nmnum ::= ON */ yytestcase(yyruleno==350); + /* (351) nmnum ::= DELETE */ yytestcase(yyruleno==351); + /* (352) nmnum ::= DEFAULT */ yytestcase(yyruleno==352); + /* (353) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==353); + /* (354) foreach_clause ::= */ yytestcase(yyruleno==354); + /* (355) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==355); + /* (356) trnm ::= nm */ yytestcase(yyruleno==356); + /* (357) tridxby ::= */ yytestcase(yyruleno==357); + /* (358) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==358); + /* (359) database_kw_opt ::= */ yytestcase(yyruleno==359); + /* (360) kwcolumn_opt ::= */ yytestcase(yyruleno==360); + /* (361) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==361); + /* (362) vtabarglist ::= vtabarg */ yytestcase(yyruleno==362); + /* (363) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==363); + /* (364) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==364); + /* (365) anylist ::= */ yytestcase(yyruleno==365); + /* (366) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==366); + /* (367) anylist ::= anylist ANY */ yytestcase(yyruleno==367); + /* (368) with ::= */ yytestcase(yyruleno==368); break; /********** End reduce actions ************************************************/ }; - assert( yyruleno<sizeof(yyRuleInfo)/sizeof(yyRuleInfo[0]) ); - yygoto = yyRuleInfo[yyruleno].lhs; - yysize = yyRuleInfo[yyruleno].nrhs; + assert( yyruleno<sizeof(yyRuleInfoLhs)/sizeof(yyRuleInfoLhs[0]) ); + yygoto = yyRuleInfoLhs[yyruleno]; + yysize = yyRuleInfoNRhs[yyruleno]; yyact = yy_find_reduce_action(yymsp[yysize].stateno,(YYCODETYPE)yygoto); /* There are no SHIFTREDUCE actions on nonterminals because the table @@ -152095,73 +152996,6 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ return i; } -#ifdef SQLITE_ENABLE_NORMALIZE -/* -** Return the length (in bytes) of the token that begins at z[0]. -** Store the token type in *tokenType before returning. If flags has -** SQLITE_TOKEN_NORMALIZE flag enabled, use the identifier token type -** for keywords. Add SQLITE_TOKEN_QUOTED to flags if the token was -** actually a quoted identifier. Add SQLITE_TOKEN_KEYWORD to flags -** if the token was recognized as a keyword; this is useful when the -** SQLITE_TOKEN_NORMALIZE flag is used, because it enables the caller -** to differentiate between a keyword being treated as an identifier -** (for normalization purposes) and an actual identifier. -*/ -SQLITE_PRIVATE int sqlite3GetTokenNormalized( - const unsigned char *z, - int *tokenType, - int *flags -){ - int n; - unsigned char iClass = aiClass[*z]; - if( iClass==CC_KYWD ){ - int i; - for(i=1; aiClass[z[i]]<=CC_KYWD; i++){} - if( IdChar(z[i]) ){ - /* This token started out using characters that can appear in keywords, - ** but z[i] is a character not allowed within keywords, so this must - ** be an identifier instead */ - i++; - while( IdChar(z[i]) ){ i++; } - *tokenType = TK_ID; - return i; - } - *tokenType = TK_ID; - n = keywordCode((char*)z, i, tokenType); - /* If the token is no longer considered to be an identifier, then it is a - ** keyword of some kind. Make the token back into an identifier and then - ** set the SQLITE_TOKEN_KEYWORD flag. Several non-identifier tokens are - ** used verbatim, including IN, IS, NOT, and NULL. */ - switch( *tokenType ){ - case TK_ID: { - /* do nothing, handled by caller */ - break; - } - case TK_IN: - case TK_IS: - case TK_NOT: - case TK_NULL: { - *flags |= SQLITE_TOKEN_KEYWORD; - break; - } - default: { - *tokenType = TK_ID; - *flags |= SQLITE_TOKEN_KEYWORD; - break; - } - } - }else{ - n = sqlite3GetToken(z, tokenType); - /* If the token is considered to be an identifier and the character class - ** of the first character is a quote, set the SQLITE_TOKEN_QUOTED flag. */ - if( *tokenType==TK_ID && (iClass==CC_QUOTE || iClass==CC_QUOTE2) ){ - *flags |= SQLITE_TOKEN_QUOTED; - } - } - return n; -} -#endif /* SQLITE_ENABLE_NORMALIZE */ - /* ** Run the parser on the given SQL string. The parser structure is ** passed in. An SQLITE_ status code is returned. If an error occurs @@ -152189,7 +153023,14 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr pParse->rc = SQLITE_OK; pParse->zTail = zSql; assert( pzErrMsg!=0 ); - /* sqlite3ParserTrace(stdout, "parser: "); */ +#ifdef SQLITE_DEBUG + if( db->flags & SQLITE_ParserTrace ){ + printf("parser: [[[%s]]]\n", zSql); + sqlite3ParserTrace(stdout, "parser: "); + }else{ + sqlite3ParserTrace(0, 0); + } +#endif #ifdef sqlite3Parser_ENGINEALWAYSONSTACK pEngine = &sEngine; sqlite3ParserInit(pEngine, pParse); @@ -152332,6 +153173,141 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr return nErr; } + +#ifdef SQLITE_ENABLE_NORMALIZE +/* +** Insert a single space character into pStr if the current string +** ends with an identifier +*/ +static void addSpaceSeparator(sqlite3_str *pStr){ + if( pStr->nChar && sqlite3IsIdChar(pStr->zText[pStr->nChar-1]) ){ + sqlite3_str_append(pStr, " ", 1); + } +} + +/* +** Compute a normalization of the SQL given by zSql[0..nSql-1]. Return +** the normalization in space obtained from sqlite3DbMalloc(). Or return +** NULL if anything goes wrong or if zSql is NULL. +*/ +SQLITE_PRIVATE char *sqlite3Normalize( + Vdbe *pVdbe, /* VM being reprepared */ + const char *zSql /* The original SQL string */ +){ + sqlite3 *db; /* The database connection */ + int i; /* Next unread byte of zSql[] */ + int n; /* length of current token */ + int tokenType; /* type of current token */ + int prevType = 0; /* Previous non-whitespace token */ + int nParen; /* Number of nested levels of parentheses */ + int iStartIN; /* Start of RHS of IN operator in z[] */ + int nParenAtIN; /* Value of nParent at start of RHS of IN operator */ + int j; /* Bytes of normalized SQL generated so far */ + sqlite3_str *pStr; /* The normalized SQL string under construction */ + + db = sqlite3VdbeDb(pVdbe); + tokenType = -1; + nParen = iStartIN = nParenAtIN = 0; + pStr = sqlite3_str_new(db); + assert( pStr!=0 ); /* sqlite3_str_new() never returns NULL */ + for(i=0; zSql[i] && pStr->accError==0; i+=n){ + if( tokenType!=TK_SPACE ){ + prevType = tokenType; + } + n = sqlite3GetToken((unsigned char*)zSql+i, &tokenType); + if( NEVER(n<=0) ) break; + switch( tokenType ){ + case TK_SPACE: { + break; + } + case TK_NULL: { + if( prevType==TK_IS || prevType==TK_NOT ){ + sqlite3_str_append(pStr, " NULL", 5); + break; + } + /* Fall through */ + } + case TK_STRING: + case TK_INTEGER: + case TK_FLOAT: + case TK_VARIABLE: + case TK_BLOB: { + sqlite3_str_append(pStr, "?", 1); + break; + } + case TK_LP: { + nParen++; + if( prevType==TK_IN ){ + iStartIN = pStr->nChar; + nParenAtIN = nParen; + } + sqlite3_str_append(pStr, "(", 1); + break; + } + case TK_RP: { + if( iStartIN>0 && nParen==nParenAtIN ){ + assert( pStr->nChar>=iStartIN ); + pStr->nChar = iStartIN+1; + sqlite3_str_append(pStr, "?,?,?", 5); + iStartIN = 0; + } + nParen--; + sqlite3_str_append(pStr, ")", 1); + break; + } + case TK_ID: { + iStartIN = 0; + j = pStr->nChar; + if( sqlite3Isquote(zSql[i]) ){ + char *zId = sqlite3DbStrNDup(db, zSql+i, n); + int nId; + int eType = 0; + if( zId==0 ) break; + sqlite3Dequote(zId); + if( zSql[i]=='"' && sqlite3VdbeUsesDoubleQuotedString(pVdbe, zId) ){ + sqlite3_str_append(pStr, "?", 1); + sqlite3DbFree(db, zId); + break; + } + nId = sqlite3Strlen30(zId); + if( sqlite3GetToken((u8*)zId, &eType)==nId && eType==TK_ID ){ + addSpaceSeparator(pStr); + sqlite3_str_append(pStr, zId, nId); + }else{ + sqlite3_str_appendf(pStr, "\"%w\"", zId); + } + sqlite3DbFree(db, zId); + }else{ + addSpaceSeparator(pStr); + sqlite3_str_append(pStr, zSql+i, n); + } + while( j<pStr->nChar ){ + pStr->zText[j] = sqlite3Tolower(pStr->zText[j]); + j++; + } + break; + } + case TK_SELECT: { + iStartIN = 0; + /* fall through */ + } + default: { + if( sqlite3IsIdChar(zSql[i]) ) addSpaceSeparator(pStr); + j = pStr->nChar; + sqlite3_str_append(pStr, zSql+i, n); + while( j<pStr->nChar ){ + pStr->zText[j] = sqlite3Toupper(pStr->zText[j]); + j++; + } + break; + } + } + } + if( tokenType!=TK_SEMI ) sqlite3_str_append(pStr, ";", 1); + return sqlite3_str_finish(pStr); +} +#endif /* SQLITE_ENABLE_NORMALIZE */ + /************** End of tokenize.c ********************************************/ /************** Begin file complete.c ****************************************/ /* @@ -153377,6 +154353,13 @@ SQLITE_API int sqlite3_config(int op, ...){ } #endif /* SQLITE_ENABLE_SORTER_REFERENCES */ +#ifdef SQLITE_ENABLE_DESERIALIZE + case SQLITE_CONFIG_MEMDB_MAXSIZE: { + sqlite3GlobalConfig.mxMemdbSize = va_arg(ap, sqlite3_int64); + break; + } +#endif /* SQLITE_ENABLE_DESERIALIZE */ + default: { rc = SQLITE_ERROR; break; @@ -153567,11 +154550,11 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){ if( aFlagOp[i].op==op ){ int onoff = va_arg(ap, int); int *pRes = va_arg(ap, int*); - u32 oldFlags = db->flags; + u64 oldFlags = db->flags; if( onoff>0 ){ db->flags |= aFlagOp[i].mask; }else if( onoff==0 ){ - db->flags &= ~aFlagOp[i].mask; + db->flags &= ~(u64)aFlagOp[i].mask; } if( oldFlags!=db->flags ){ sqlite3ExpirePreparedStatements(db, 0); @@ -154034,7 +155017,7 @@ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){ /* Any deferred constraint violations have now been resolved. */ db->nDeferredCons = 0; db->nDeferredImmCons = 0; - db->flags &= ~SQLITE_DeferFKs; + db->flags &= ~(u64)SQLITE_DeferFKs; /* If one has been configured, invoke the rollback-hook callback */ if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){ @@ -154776,6 +155759,8 @@ SQLITE_API void *sqlite3_profile( pOld = db->pProfileArg; db->xProfile = xProfile; db->pProfileArg = pArg; + db->mTrace &= SQLITE_TRACE_NONLEGACY_MASK; + if( db->xProfile ) db->mTrace |= SQLITE_TRACE_XPROFILE; sqlite3_mutex_leave(db->mutex); return pOld; } @@ -155127,7 +156112,7 @@ SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){ z = sqlite3ErrStr(SQLITE_NOMEM_BKPT); }else{ testcase( db->pErr==0 ); - z = (char*)sqlite3_value_text(db->pErr); + z = db->errCode ? (char*)sqlite3_value_text(db->pErr) : 0; assert( !db->mallocFailed ); if( z==0 ){ z = sqlite3ErrStr(db->errCode); @@ -155657,6 +156642,40 @@ SQLITE_PRIVATE int sqlite3ParseUri( return rc; } +#if defined(SQLITE_HAS_CODEC) +/* +** Process URI filename query parameters relevant to the SQLite Encryption +** Extension. Return true if any of the relevant query parameters are +** seen and return false if not. +*/ +SQLITE_PRIVATE int sqlite3CodecQueryParameters( + sqlite3 *db, /* Database connection */ + const char *zDb, /* Which schema is being created/attached */ + const char *zUri /* URI filename */ +){ + const char *zKey; + if( (zKey = sqlite3_uri_parameter(zUri, "hexkey"))!=0 && zKey[0] ){ + u8 iByte; + int i; + char zDecoded[40]; + for(i=0, iByte=0; i<sizeof(zDecoded)*2 && sqlite3Isxdigit(zKey[i]); i++){ + iByte = (iByte<<4) + sqlite3HexToInt(zKey[i]); + if( (i&1)!=0 ) zDecoded[i/2] = iByte; + } + sqlite3_key_v2(db, zDb, zDecoded, i/2); + return 1; + }else if( (zKey = sqlite3_uri_parameter(zUri, "key"))!=0 ){ + sqlite3_key_v2(db, zDb, zKey, sqlite3Strlen30(zKey)); + return 1; + }else if( (zKey = sqlite3_uri_parameter(zUri, "textkey"))!=0 ){ + sqlite3_key_v2(db, zDb, zKey, -1); + return 1; + }else{ + return 0; + } +} +#endif + /* ** This routine does the work of opening a database on behalf of @@ -156002,26 +157021,13 @@ opendb_out: } #endif #if defined(SQLITE_HAS_CODEC) - if( rc==SQLITE_OK ){ - const char *zKey; - if( (zKey = sqlite3_uri_parameter(zOpen, "hexkey"))!=0 && zKey[0] ){ - u8 iByte; - int i; - char zDecoded[40]; - for(i=0, iByte=0; i<sizeof(zDecoded)*2 && sqlite3Isxdigit(zKey[i]); i++){ - iByte = (iByte<<4) + sqlite3HexToInt(zKey[i]); - if( (i&1)!=0 ) zDecoded[i/2] = iByte; - } - sqlite3_key_v2(db, 0, zDecoded, i/2); - }else if( (zKey = sqlite3_uri_parameter(zOpen, "key"))!=0 ){ - sqlite3_key_v2(db, 0, zKey, sqlite3Strlen30(zKey)); - } - } + if( rc==SQLITE_OK ) sqlite3CodecQueryParameters(db, 0, zOpen); #endif sqlite3_free(zOpen); return rc & 0xff; } + /* ** Open a new database handle. */ @@ -158082,6 +159088,8 @@ SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem(const Fts3Hash *, const voi */ #define FTS3_VARINT_MAX 10 +#define FTS3_BUFFER_PADDING 8 + /* ** FTS4 virtual tables may maintain multiple indexes - one index of all terms ** in the document set and zero or more prefix indexes. All indexes are stored @@ -158114,6 +159122,18 @@ SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem(const Fts3Hash *, const voi #define POS_COLUMN (1) /* Column-list terminator */ #define POS_END (0) /* Position-list terminator */ +/* +** The assert_fts3_nc() macro is similar to the assert() macro, except that it +** is used for assert() conditions that are true only if it can be +** guranteed that the database is not corrupt. +*/ +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) +SQLITE_API extern int sqlite3_fts3_may_be_corrupt; +# define assert_fts3_nc(x) assert(sqlite3_fts3_may_be_corrupt || (x)) +#else +# define assert_fts3_nc(x) assert(x) +#endif + /* ** This section provides definitions to allow the ** FTS3 extension to be compiled outside of the @@ -158638,6 +159658,14 @@ SQLITE_PRIVATE int sqlite3Fts3Never(int b) { assert( !b ); return b; } # endif #endif +/* +** This variable is set to false when running tests for which the on disk +** structures should not be corrupt. Otherwise, true. If it is false, extra +** assert() conditions in the fts3 code are activated - conditions that are +** only true if it is guaranteed that the fts3 database is not corrupt. +*/ +SQLITE_API int sqlite3_fts3_may_be_corrupt = 1; + /* ** Write a 64-bit variable-length integer to memory starting at p[0]. ** The length of data written will be between 1 and FTS3_VARINT_MAX bytes. @@ -158656,7 +159684,7 @@ SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *p, sqlite_int64 v){ } #define GETVARINT_STEP(v, ptr, shift, mask1, mask2, var, ret) \ - v = (v & mask1) | ( (*ptr++) << shift ); \ + v = (v & mask1) | ( (*(const unsigned char*)(ptr++)) << shift ); \ if( (v & mask2)==0 ){ var = v; return ret; } #define GETVARINT_INIT(v, ptr, shift, mask1, mask2, var, ret) \ v = (*ptr++); \ @@ -158694,20 +159722,21 @@ SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *pBuf, sqlite_int64 *v){ ** a non-negative 32-bit integer before it is returned. */ SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *p, int *pi){ + const unsigned char *ptr = (const unsigned char*)p; u32 a; #ifndef fts3GetVarint32 - GETVARINT_INIT(a, p, 0, 0x00, 0x80, *pi, 1); + GETVARINT_INIT(a, ptr, 0, 0x00, 0x80, *pi, 1); #else - a = (*p++); + a = (*ptr++); assert( a & 0x80 ); #endif - GETVARINT_STEP(a, p, 7, 0x7F, 0x4000, *pi, 2); - GETVARINT_STEP(a, p, 14, 0x3FFF, 0x200000, *pi, 3); - GETVARINT_STEP(a, p, 21, 0x1FFFFF, 0x10000000, *pi, 4); + GETVARINT_STEP(a, ptr, 7, 0x7F, 0x4000, *pi, 2); + GETVARINT_STEP(a, ptr, 14, 0x3FFF, 0x200000, *pi, 3); + GETVARINT_STEP(a, ptr, 21, 0x1FFFFF, 0x10000000, *pi, 4); a = (a & 0x0FFFFFFF ); - *pi = (int)(a | ((u32)(*p & 0x07) << 28)); + *pi = (int)(a | ((u32)(*ptr & 0x07) << 28)); assert( 0==(a & 0x80000000) ); assert( *pi>=0 ); return 5; @@ -158878,13 +159907,18 @@ static int fts3DestroyMethod(sqlite3_vtab *pVtab){ sqlite3 *db = p->db; /* Database handle */ /* Drop the shadow tables */ - if( p->zContentTbl==0 ){ - fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_content'", zDb, p->zName); - } - fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segments'", zDb,p->zName); - fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segdir'", zDb, p->zName); - fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_docsize'", zDb, p->zName); - fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_stat'", zDb, p->zName); + fts3DbExec(&rc, db, + "DROP TABLE IF EXISTS %Q.'%q_segments';" + "DROP TABLE IF EXISTS %Q.'%q_segdir';" + "DROP TABLE IF EXISTS %Q.'%q_docsize';" + "DROP TABLE IF EXISTS %Q.'%q_stat';" + "%s DROP TABLE IF EXISTS %Q.'%q_content';", + zDb, p->zName, + zDb, p->zName, + zDb, p->zName, + zDb, p->zName, + (p->zContentTbl ? "--" : ""), zDb,p->zName + ); /* If everything has worked, invoke fts3DisconnectMethod() to free the ** memory associated with the Fts3Table structure and return SQLITE_OK. @@ -159116,10 +160150,10 @@ static void fts3Appendf( ** memory. */ static char *fts3QuoteId(char const *zInput){ - int nRet; + sqlite3_int64 nRet; char *zRet; nRet = 2 + (int)strlen(zInput)*2 + 1; - zRet = sqlite3_malloc(nRet); + zRet = sqlite3_malloc64(nRet); if( zRet ){ int i; char *z = zRet; @@ -159300,7 +160334,7 @@ static int fts3PrefixParameter( } } - aIndex = sqlite3_malloc(sizeof(struct Fts3Index) * nIndex); + aIndex = sqlite3_malloc64(sizeof(struct Fts3Index) * nIndex); *apIndex = aIndex; if( !aIndex ){ return SQLITE_NOMEM; @@ -159379,7 +160413,7 @@ static int fts3ContentColumns( if( rc==SQLITE_OK ){ const char **azCol; /* Output array */ - int nStr = 0; /* Size of all column names (incl. 0x00) */ + sqlite3_int64 nStr = 0; /* Size of all column names (incl. 0x00) */ int nCol; /* Number of table columns */ int i; /* Used to iterate through columns */ @@ -159389,11 +160423,11 @@ static int fts3ContentColumns( nCol = sqlite3_column_count(pStmt); for(i=0; i<nCol; i++){ const char *zCol = sqlite3_column_name(pStmt, i); - nStr += (int)strlen(zCol) + 1; + nStr += strlen(zCol) + 1; } /* Allocate and populate the array to return. */ - azCol = (const char **)sqlite3_malloc(sizeof(char *) * nCol + nStr); + azCol = (const char **)sqlite3_malloc64(sizeof(char *) * nCol + nStr); if( azCol==0 ){ rc = SQLITE_NOMEM; }else{ @@ -159441,7 +160475,7 @@ static int fts3InitVtab( Fts3Table *p = 0; /* Pointer to allocated vtab */ int rc = SQLITE_OK; /* Return code */ int i; /* Iterator variable */ - int nByte; /* Size of allocation used for *p */ + sqlite3_int64 nByte; /* Size of allocation used for *p */ int iCol; /* Column index */ int nString = 0; /* Bytes required to hold all column names */ int nCol = 0; /* Number of columns in the FTS table */ @@ -159475,10 +160509,10 @@ static int fts3InitVtab( nName = (int)strlen(argv[2]) + 1; nByte = sizeof(const char *) * (argc-2); - aCol = (const char **)sqlite3_malloc(nByte); + aCol = (const char **)sqlite3_malloc64(nByte); if( aCol ){ memset((void*)aCol, 0, nByte); - azNotindexed = (char **)sqlite3_malloc(nByte); + azNotindexed = (char **)sqlite3_malloc64(nByte); } if( azNotindexed ){ memset(azNotindexed, 0, nByte); @@ -159673,7 +160707,7 @@ static int fts3InitVtab( nName + /* zName */ nDb + /* zDb */ nString; /* Space for azColumn strings */ - p = (Fts3Table*)sqlite3_malloc(nByte); + p = (Fts3Table*)sqlite3_malloc64(nByte); if( p==0 ){ rc = SQLITE_NOMEM; goto fts3_init_out; @@ -160452,7 +161486,7 @@ static int fts3PutColNumber(char **pp, int iCol){ ** updated appropriately. The caller is responsible for insuring ** that there is enough space in *pp to hold the complete output. */ -static void fts3PoslistMerge( +static int fts3PoslistMerge( char **pp, /* Output buffer */ char **pp1, /* Left input list */ char **pp2 /* Right input list */ @@ -160465,11 +161499,17 @@ static void fts3PoslistMerge( int iCol1; /* The current column index in pp1 */ int iCol2; /* The current column index in pp2 */ - if( *p1==POS_COLUMN ) fts3GetVarint32(&p1[1], &iCol1); + if( *p1==POS_COLUMN ){ + fts3GetVarint32(&p1[1], &iCol1); + if( iCol1==0 ) return FTS_CORRUPT_VTAB; + } else if( *p1==POS_END ) iCol1 = POSITION_LIST_END; else iCol1 = 0; - if( *p2==POS_COLUMN ) fts3GetVarint32(&p2[1], &iCol2); + if( *p2==POS_COLUMN ){ + fts3GetVarint32(&p2[1], &iCol2); + if( iCol2==0 ) return FTS_CORRUPT_VTAB; + } else if( *p2==POS_END ) iCol2 = POSITION_LIST_END; else iCol2 = 0; @@ -160517,6 +161557,7 @@ static void fts3PoslistMerge( *pp = p; *pp1 = p1 + 1; *pp2 = p2 + 1; + return SQLITE_OK; } /* @@ -160581,10 +161622,9 @@ static int fts3PoslistPhraseMerge( p += sqlite3Fts3PutVarint(p, iCol1); } - assert( *p1!=POS_END && *p1!=POS_COLUMN ); - assert( *p2!=POS_END && *p2!=POS_COLUMN ); fts3GetDeltaVarint(&p1, &iPos1); iPos1 -= 2; fts3GetDeltaVarint(&p2, &iPos2); iPos2 -= 2; + if( iPos1<0 || iPos2<0 ) break; while( 1 ){ if( iPos2==iPos1+nToken @@ -160810,6 +161850,7 @@ static int fts3DoclistOrMerge( char *a2, int n2, /* Second doclist */ char **paOut, int *pnOut /* OUT: Malloc'd doclist */ ){ + int rc = SQLITE_OK; sqlite3_int64 i1 = 0; sqlite3_int64 i2 = 0; sqlite3_int64 iPrev = 0; @@ -160853,7 +161894,7 @@ static int fts3DoclistOrMerge( ** A symetric argument may be made if the doclists are in descending ** order. */ - aOut = sqlite3_malloc(n1+n2+FTS3_VARINT_MAX-1); + aOut = sqlite3_malloc64((i64)n1+n2+FTS3_VARINT_MAX-1+FTS3_BUFFER_PADDING); if( !aOut ) return SQLITE_NOMEM; p = aOut; @@ -160864,7 +161905,8 @@ static int fts3DoclistOrMerge( if( p2 && p1 && iDiff==0 ){ fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i1); - fts3PoslistMerge(&p, &p1, &p2); + rc = fts3PoslistMerge(&p, &p1, &p2); + if( rc ) break; fts3GetDeltaVarint3(&p1, pEnd1, bDescDoclist, &i1); fts3GetDeltaVarint3(&p2, pEnd2, bDescDoclist, &i2); }else if( !p2 || (p1 && iDiff<0) ){ @@ -160878,10 +161920,16 @@ static int fts3DoclistOrMerge( } } + if( rc!=SQLITE_OK ){ + sqlite3_free(aOut); + p = aOut = 0; + }else{ + assert( (p-aOut)<=n1+n2+FTS3_VARINT_MAX-1 ); + memset(&aOut[(p-aOut)], 0, FTS3_BUFFER_PADDING); + } *paOut = aOut; *pnOut = (int)(p-aOut); - assert( *pnOut<=n1+n2+FTS3_VARINT_MAX-1 ); - return SQLITE_OK; + return rc; } /* @@ -160916,7 +161964,7 @@ static int fts3DoclistPhraseMerge( assert( nDist>0 ); if( bDescDoclist ){ - aOut = sqlite3_malloc(*pnRight + FTS3_VARINT_MAX); + aOut = sqlite3_malloc64((sqlite3_int64)*pnRight + FTS3_VARINT_MAX); if( aOut==0 ) return SQLITE_NOMEM; }else{ aOut = aRight; @@ -161100,6 +162148,7 @@ static int fts3TermSelectMerge( pTS->anOutput[0] = nDoclist; if( pTS->aaOutput[0] ){ memcpy(pTS->aaOutput[0], aDoclist, nDoclist); + memset(&pTS->aaOutput[0][nDoclist], 0, FTS3_VARINT_MAX); }else{ return SQLITE_NOMEM; } @@ -161151,8 +162200,8 @@ static int fts3SegReaderCursorAppend( ){ if( (pCsr->nSegment%16)==0 ){ Fts3SegReader **apNew; - int nByte = (pCsr->nSegment + 16)*sizeof(Fts3SegReader*); - apNew = (Fts3SegReader **)sqlite3_realloc(pCsr->apSegment, nByte); + sqlite3_int64 nByte = (pCsr->nSegment + 16)*sizeof(Fts3SegReader*); + apNew = (Fts3SegReader **)sqlite3_realloc64(pCsr->apSegment, nByte); if( !apNew ){ sqlite3Fts3SegReaderFree(pNew); return SQLITE_NOMEM; @@ -161216,7 +162265,7 @@ static int fts3SegReaderCursor( /* If zTerm is not NULL, and this segment is not stored entirely on its ** root node, the range of leaves scanned can be reduced. Do this. */ - if( iStartBlock && zTerm ){ + if( iStartBlock && zTerm && zRoot ){ sqlite3_int64 *pi = (isPrefix ? &iLeavesEndBlock : 0); rc = fts3SelectLeaf(p, zTerm, nTerm, zRoot, nRoot, &iStartBlock, pi); if( rc!=SQLITE_OK ) goto finished; @@ -162158,7 +163207,6 @@ static int fts3RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ Fts3Table *p = (Fts3Table*)pVtab; UNUSED_PARAMETER(iSavepoint); assert( p->inTransaction ); - assert( p->mxSavepoint >= iSavepoint ); TESTONLY( p->mxSavepoint = iSavepoint ); sqlite3Fts3PendingTermsClear(p); return SQLITE_OK; @@ -162933,9 +163981,10 @@ static int fts3EvalIncrPhraseNext( if( bEof==0 ){ int nList = 0; int nByte = a[p->nToken-1].nList; - char *aDoclist = sqlite3_malloc(nByte+1); + char *aDoclist = sqlite3_malloc(nByte+FTS3_BUFFER_PADDING); if( !aDoclist ) return SQLITE_NOMEM; memcpy(aDoclist, a[p->nToken-1].pList, nByte+1); + memset(&aDoclist[nByte], 0, FTS3_BUFFER_PADDING); for(i=0; i<(p->nToken-1); i++){ if( a[i].bIgnore==0 ){ @@ -163326,7 +164375,7 @@ static int fts3EvalStart(Fts3Cursor *pCsr){ if( rc==SQLITE_OK && nToken>1 && pTab->bFts4 ){ Fts3TokenAndCost *aTC; Fts3Expr **apOr; - aTC = (Fts3TokenAndCost *)sqlite3_malloc( + aTC = (Fts3TokenAndCost *)sqlite3_malloc64( sizeof(Fts3TokenAndCost) * nToken + sizeof(Fts3Expr *) * nOr * 2 ); @@ -163637,7 +164686,7 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){ && (pExpr->pParent==0 || pExpr->pParent->eType!=FTSQUERY_NEAR) ){ Fts3Expr *p; - int nTmp = 0; /* Bytes of temp space */ + sqlite3_int64 nTmp = 0; /* Bytes of temp space */ char *aTmp; /* Temp space for PoslistNearMerge() */ /* Allocate temporary working space. */ @@ -163646,7 +164695,7 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){ nTmp += p->pRight->pPhrase->doclist.nList; } nTmp += p->pPhrase->doclist.nList; - aTmp = sqlite3_malloc(nTmp*2); + aTmp = sqlite3_malloc64(nTmp*2); if( !aTmp ){ *pRc = SQLITE_NOMEM; res = 0; @@ -163916,15 +164965,14 @@ static void fts3EvalRestart( ** found in Fts3Expr.pPhrase->doclist.pList for each of the phrase ** expression nodes. */ -static void fts3EvalUpdateCounts(Fts3Expr *pExpr){ +static void fts3EvalUpdateCounts(Fts3Expr *pExpr, int nCol){ if( pExpr ){ Fts3Phrase *pPhrase = pExpr->pPhrase; if( pPhrase && pPhrase->doclist.pList ){ int iCol = 0; char *p = pPhrase->doclist.pList; - assert( *p ); - while( 1 ){ + do{ u8 c = 0; int iCnt = 0; while( 0xFE & (*p | c) ){ @@ -163940,11 +164988,11 @@ static void fts3EvalUpdateCounts(Fts3Expr *pExpr){ if( *p==0x00 ) break; p++; p += fts3GetVarint32(p, &iCol); - } + }while( iCol<nCol ); } - fts3EvalUpdateCounts(pExpr->pLeft); - fts3EvalUpdateCounts(pExpr->pRight); + fts3EvalUpdateCounts(pExpr->pLeft, nCol); + fts3EvalUpdateCounts(pExpr->pRight, nCol); } } @@ -163988,7 +165036,7 @@ static int fts3EvalGatherStats( for(p=pRoot; p; p=p->pLeft){ Fts3Expr *pE = (p->eType==FTSQUERY_PHRASE?p:p->pRight); assert( pE->aMI==0 ); - pE->aMI = (u32 *)sqlite3_malloc(pTab->nColumn * 3 * sizeof(u32)); + pE->aMI = (u32 *)sqlite3_malloc64(pTab->nColumn * 3 * sizeof(u32)); if( !pE->aMI ) return SQLITE_NOMEM; memset(pE->aMI, 0, pTab->nColumn * 3 * sizeof(u32)); } @@ -164014,7 +165062,7 @@ static int fts3EvalGatherStats( ); if( rc==SQLITE_OK && pCsr->isEof==0 ){ - fts3EvalUpdateCounts(pRoot); + fts3EvalUpdateCounts(pRoot, pTab->nColumn); } } @@ -164364,7 +165412,7 @@ static int fts3auxConnectMethod( char const *zFts3; /* Name of fts3 table */ int nDb; /* Result of strlen(zDb) */ int nFts3; /* Result of strlen(zFts3) */ - int nByte; /* Bytes of space to allocate here */ + sqlite3_int64 nByte; /* Bytes of space to allocate here */ int rc; /* value returned by declare_vtab() */ Fts3auxTable *p; /* Virtual table object to return */ @@ -164396,7 +165444,7 @@ static int fts3auxConnectMethod( if( rc!=SQLITE_OK ) return rc; nByte = sizeof(Fts3auxTable) + sizeof(Fts3Table) + nDb + nFts3 + 2; - p = (Fts3auxTable *)sqlite3_malloc(nByte); + p = (Fts3auxTable *)sqlite3_malloc64(nByte); if( !p ) return SQLITE_NOMEM; memset(p, 0, nByte); @@ -164546,7 +165594,7 @@ static int fts3auxCloseMethod(sqlite3_vtab_cursor *pCursor){ static int fts3auxGrowStatArray(Fts3auxCursor *pCsr, int nSize){ if( nSize>pCsr->nStat ){ struct Fts3auxColstats *aNew; - aNew = (struct Fts3auxColstats *)sqlite3_realloc(pCsr->aStat, + aNew = (struct Fts3auxColstats *)sqlite3_realloc64(pCsr->aStat, sizeof(struct Fts3auxColstats) * nSize ); if( aNew==0 ) return SQLITE_NOMEM; @@ -164714,15 +165762,15 @@ static int fts3auxFilterMethod( assert( (iEq==0 && iGe==-1) || (iEq==-1 && iGe==0) ); if( zStr ){ pCsr->filter.zTerm = sqlite3_mprintf("%s", zStr); - pCsr->filter.nTerm = sqlite3_value_bytes(apVal[0]); if( pCsr->filter.zTerm==0 ) return SQLITE_NOMEM; + pCsr->filter.nTerm = (int)strlen(pCsr->filter.zTerm); } } if( iLe>=0 ){ pCsr->zStop = sqlite3_mprintf("%s", sqlite3_value_text(apVal[iLe])); - pCsr->nStop = sqlite3_value_bytes(apVal[iLe]); if( pCsr->zStop==0 ) return SQLITE_NOMEM; + pCsr->nStop = (int)strlen(pCsr->zStop); } if( iLangid>=0 ){ @@ -164974,8 +166022,8 @@ static int fts3isspace(char c){ ** zero the memory before returning a pointer to it. If unsuccessful, ** return NULL. */ -static void *fts3MallocZero(int nByte){ - void *pRet = sqlite3_malloc(nByte); +static void *fts3MallocZero(sqlite3_int64 nByte){ + void *pRet = sqlite3_malloc64(nByte); if( pRet ) memset(pRet, 0, nByte); return pRet; } @@ -165050,7 +166098,7 @@ static int getNextToken( if( rc==SQLITE_OK ){ const char *zToken; int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0; - int nByte; /* total space to allocate */ + sqlite3_int64 nByte; /* total space to allocate */ rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition); if( rc==SQLITE_OK ){ @@ -165104,8 +166152,8 @@ static int getNextToken( ** Enlarge a memory allocation. If an out-of-memory allocation occurs, ** then free the old allocation. */ -static void *fts3ReallocOrFree(void *pOrig, int nNew){ - void *pRet = sqlite3_realloc(pOrig, nNew); +static void *fts3ReallocOrFree(void *pOrig, sqlite3_int64 nNew){ + void *pRet = sqlite3_realloc64(pOrig, nNew); if( !pRet ){ sqlite3_free(pOrig); } @@ -165349,7 +166397,6 @@ static int getNextNode( int nConsumed = 0; pParse->nNest++; rc = fts3ExprParse(pParse, zInput+1, nInput-1, ppExpr, &nConsumed); - if( rc==SQLITE_OK && !*ppExpr ){ rc = SQLITE_DONE; } *pnConsumed = (int)(zInput - z) + 1 + nConsumed; return rc; }else if( *zInput==')' ){ @@ -165648,7 +166695,7 @@ static int fts3ExprBalance(Fts3Expr **pp, int nMaxDepth){ if( rc==SQLITE_OK ){ if( (eType==FTSQUERY_AND || eType==FTSQUERY_OR) ){ Fts3Expr **apLeaf; - apLeaf = (Fts3Expr **)sqlite3_malloc(sizeof(Fts3Expr *) * nMaxDepth); + apLeaf = (Fts3Expr **)sqlite3_malloc64(sizeof(Fts3Expr *) * nMaxDepth); if( 0==apLeaf ){ rc = SQLITE_NOMEM; }else{ @@ -166068,7 +167115,7 @@ static void fts3ExprTestCommon( zExpr = (const char *)sqlite3_value_text(argv[1]); nExpr = sqlite3_value_bytes(argv[1]); nCol = argc-2; - azCol = (char **)sqlite3_malloc(nCol*sizeof(char *)); + azCol = (char **)sqlite3_malloc64(nCol*sizeof(char *)); if( !azCol ){ sqlite3_result_error_nomem(context); goto exprtest_out; @@ -166182,8 +167229,8 @@ SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash *pHash /* ** Malloc and Free functions */ -static void *fts3HashMalloc(int n){ - void *p = sqlite3_malloc(n); +static void *fts3HashMalloc(sqlite3_int64 n){ + void *p = sqlite3_malloc64(n); if( p ){ memset(p, 0, n); } @@ -168076,7 +169123,7 @@ static int fts3tokDequoteArray( nByte += (int)(strlen(argv[i]) + 1); } - *pazDequote = azDequote = sqlite3_malloc(sizeof(char *)*argc + nByte); + *pazDequote = azDequote = sqlite3_malloc64(sizeof(char *)*argc + nByte); if( azDequote==0 ){ rc = SQLITE_NOMEM; }else{ @@ -168808,10 +169855,12 @@ static int fts3SqlStmt( pStmt = p->aStmt[eStmt]; if( !pStmt ){ + int f = SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB; char *zSql; if( eStmt==SQL_CONTENT_INSERT ){ zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName, p->zWriteExprlist); }else if( eStmt==SQL_SELECT_CONTENT_BY_ROWID ){ + f &= ~SQLITE_PREPARE_NO_VTAB; zSql = sqlite3_mprintf(azSql[eStmt], p->zReadExprlist); }else{ zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName); @@ -168819,8 +169868,7 @@ static int fts3SqlStmt( if( !zSql ){ rc = SQLITE_NOMEM; }else{ - rc = sqlite3_prepare_v3(p->db, zSql, -1, SQLITE_PREPARE_PERSISTENT, - &pStmt, NULL); + rc = sqlite3_prepare_v3(p->db, zSql, -1, f, &pStmt, NULL); sqlite3_free(zSql); assert( rc==SQLITE_OK || pStmt==0 ); p->aStmt[eStmt] = pStmt; @@ -168978,7 +170026,7 @@ static sqlite3_int64 getAbsoluteLevel( int iLevel /* Level of segments */ ){ sqlite3_int64 iBase; /* First absolute level for iLangid/iIndex */ - assert( iLangid>=0 ); + assert_fts3_nc( iLangid>=0 ); assert( p->nIndex>0 ); assert( iIndex>=0 && iIndex<p->nIndex ); @@ -169820,7 +170868,7 @@ static int fts3SegReaderNext( ** b-tree node. And that the final byte of the doclist is 0x00. If either ** of these statements is untrue, then the data structure is corrupt. */ - if( (&pReader->aNode[pReader->nNode] - pReader->aDoclist)<pReader->nDoclist + if( pReader->nDoclist > pReader->nNode-(pReader->aDoclist-pReader->aNode) || (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1]) ){ return FTS_CORRUPT_VTAB; @@ -170020,8 +171068,13 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderNew( Fts3SegReader *pReader; /* Newly allocated SegReader object */ int nExtra = 0; /* Bytes to allocate segment root node */ - assert( iStartLeaf<=iEndLeaf ); + assert( zRoot!=0 || nRoot==0 ); +#ifdef CORRUPT_DB + assert( zRoot!=0 || CORRUPT_DB ); +#endif + if( iStartLeaf==0 ){ + if( iEndLeaf!=0 ) return FTS_CORRUPT_VTAB; nExtra = nRoot + FTS3_NODE_PADDING; } @@ -170041,7 +171094,7 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderNew( pReader->aNode = (char *)&pReader[1]; pReader->rootOnly = 1; pReader->nNode = nRoot; - memcpy(pReader->aNode, zRoot, nRoot); + if( nRoot ) memcpy(pReader->aNode, zRoot, nRoot); memset(&pReader->aNode[nRoot], 0, FTS3_NODE_PADDING); }else{ pReader->iCurrentBlock = iStartLeaf-1; @@ -170661,6 +171714,11 @@ static int fts3SegWriterAdd( nPrefix = fts3PrefixCompress(pWriter->zTerm, pWriter->nTerm, zTerm, nTerm); nSuffix = nTerm-nPrefix; + /* If nSuffix is zero or less, then zTerm/nTerm must be a prefix of + ** pWriter->zTerm/pWriter->nTerm. i.e. must be equal to or less than when + ** compared with BINARY collation. This indicates corruption. */ + if( nSuffix<=0 ) return FTS_CORRUPT_VTAB; + /* Figure out how many bytes are required by this new entry */ nReq = sqlite3Fts3VarintLen(nPrefix) + /* varint containing prefix size */ sqlite3Fts3VarintLen(nSuffix) + /* varint containing suffix size */ @@ -171368,7 +172426,9 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderStep( }else{ iDelta = iDocid - iPrev; } - assert( iDelta>0 || (nDoclist==0 && iDelta==iDocid) ); + if( iDelta<=0 && (nDoclist>0 || iDelta!=iDocid) ){ + return FTS_CORRUPT_VTAB; + } assert( nDoclist>0 || iDelta==iDocid ); nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0); @@ -171734,14 +172794,16 @@ static void fts3DecodeIntArray( const char *zBuf, /* The BLOB containing the varints */ int nBuf /* size of the BLOB */ ){ - int i, j; - UNUSED_PARAMETER(nBuf); - for(i=j=0; i<N; i++){ - sqlite3_int64 x; - j += sqlite3Fts3GetVarint(&zBuf[j], &x); - assert(j<=nBuf); - a[i] = (u32)(x & 0xffffffff); + int i = 0; + if( nBuf && (zBuf[nBuf-1]&0x80)==0 ){ + int j; + for(i=j=0; i<N && j<nBuf; i++){ + sqlite3_int64 x; + j += sqlite3Fts3GetVarint(&zBuf[j], &x); + a[i] = (u32)(x & 0xffffffff); + } } + while( i<N ) a[i++] = 0; } /* @@ -172147,7 +173209,7 @@ static int nodeReaderNext(NodeReader *p){ p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix); if( nPrefix>p->iOff || nSuffix>p->nNode-p->iOff ){ - return SQLITE_CORRUPT_VTAB; + return FTS_CORRUPT_VTAB; } blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc); if( rc==SQLITE_OK ){ @@ -172157,7 +173219,7 @@ static int nodeReaderNext(NodeReader *p){ if( p->iChild==0 ){ p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist); if( (p->nNode-p->iOff)<p->nDoclist ){ - return SQLITE_CORRUPT_VTAB; + return FTS_CORRUPT_VTAB; } p->aDoclist = &p->aNode[p->iOff]; p->iOff += p->nDoclist; @@ -174287,7 +175349,7 @@ static void (*fts3MIBufferAlloc(MatchinfoBuffer *p, u32 **paOut))(void*){ aOut = &p->aMatchinfo[p->nElem+2]; xRet = fts3MIBufferFree; }else{ - aOut = (u32*)sqlite3_malloc(p->nElem * sizeof(u32)); + aOut = (u32*)sqlite3_malloc64(p->nElem * sizeof(u32)); if( aOut ){ xRet = sqlite3_free; if( p->bGlobal ) memcpy(aOut, &p->aMatchinfo[1], p->nElem*sizeof(u32)); @@ -174542,7 +175604,8 @@ static void fts3SnippetDetails( int j; u64 mPhrase = (u64)1 << i; u64 mPos = (u64)1 << (iCsr - iStart); - assert( iCsr>=iStart ); + assert( iCsr>=iStart && (iCsr - iStart)<=64 ); + assert( i>=0 && i<=64 ); if( (mCover|mCovered)&mPhrase ){ iScore++; }else{ @@ -174584,11 +175647,14 @@ static int fts3SnippetFindPositions(Fts3Expr *pExpr, int iPhrase, void *ctx){ int iFirst = 0; pPhrase->pList = pCsr; fts3GetDeltaPosition(&pCsr, &iFirst); - assert( iFirst>=0 ); - pPhrase->pHead = pCsr; - pPhrase->pTail = pCsr; - pPhrase->iHead = iFirst; - pPhrase->iTail = iFirst; + if( iFirst<0 ){ + rc = FTS_CORRUPT_VTAB; + }else{ + pPhrase->pHead = pCsr; + pPhrase->pTail = pCsr; + pPhrase->iHead = iFirst; + pPhrase->iTail = iFirst; + } }else{ assert( rc!=SQLITE_OK || ( pPhrase->pList==0 && pPhrase->pHead==0 && pPhrase->pTail==0 @@ -174625,7 +175691,7 @@ static int fts3BestSnippet( int rc; /* Return Code */ int nList; /* Number of phrases in expression */ SnippetIter sIter; /* Iterates through snippet candidates */ - int nByte; /* Number of bytes of space to allocate */ + sqlite3_int64 nByte; /* Number of bytes of space to allocate */ int iBestScore = -1; /* Best snippet score found so far */ int i; /* Loop counter */ @@ -174643,7 +175709,7 @@ static int fts3BestSnippet( ** the required space using malloc(). */ nByte = sizeof(SnippetPhrase) * nList; - sIter.aPhrase = (SnippetPhrase *)sqlite3_malloc(nByte); + sIter.aPhrase = (SnippetPhrase *)sqlite3_malloc64(nByte); if( !sIter.aPhrase ){ return SQLITE_NOMEM; } @@ -174713,8 +175779,8 @@ static int fts3StringAppend( ** appended data. */ if( pStr->n+nAppend+1>=pStr->nAlloc ){ - int nAlloc = pStr->nAlloc+nAppend+100; - char *zNew = sqlite3_realloc(pStr->z, nAlloc); + sqlite3_int64 nAlloc = pStr->nAlloc+(sqlite3_int64)nAppend+100; + char *zNew = sqlite3_realloc64(pStr->z, nAlloc); if( !zNew ){ return SQLITE_NOMEM; } @@ -174769,6 +175835,7 @@ static int fts3SnippetShift( for(nLeft=0; !(hlmask & ((u64)1 << nLeft)); nLeft++); for(nRight=0; !(hlmask & ((u64)1 << (nSnippet-1-nRight))); nRight++); + assert( (nSnippet-1-nRight)<=63 && (nSnippet-1-nRight)>=0 ); nDesired = (nLeft-nRight)/2; /* Ideally, the start of the snippet should be pushed forward in the @@ -174961,7 +176028,7 @@ static int fts3ColumnlistCount(char **ppCollist){ /* ** This function gathers 'y' or 'b' data for a single phrase. */ -static void fts3ExprLHits( +static int fts3ExprLHits( Fts3Expr *pExpr, /* Phrase expression node */ MatchInfo *p /* Matchinfo context */ ){ @@ -174991,25 +176058,29 @@ static void fts3ExprLHits( if( *pIter!=0x01 ) break; pIter++; pIter += fts3GetVarint32(pIter, &iCol); + if( iCol>=p->nCol ) return FTS_CORRUPT_VTAB; } + return SQLITE_OK; } /* ** Gather the results for matchinfo directives 'y' and 'b'. */ -static void fts3ExprLHitGather( +static int fts3ExprLHitGather( Fts3Expr *pExpr, MatchInfo *p ){ + int rc = SQLITE_OK; assert( (pExpr->pLeft==0)==(pExpr->pRight==0) ); if( pExpr->bEof==0 && pExpr->iDocid==p->pCursor->iPrevId ){ if( pExpr->pLeft ){ - fts3ExprLHitGather(pExpr->pLeft, p); - fts3ExprLHitGather(pExpr->pRight, p); + rc = fts3ExprLHitGather(pExpr->pLeft, p); + if( rc==SQLITE_OK ) rc = fts3ExprLHitGather(pExpr->pRight, p); }else{ - fts3ExprLHits(pExpr, p); + rc = fts3ExprLHits(pExpr, p); } } + return rc; } /* @@ -175226,11 +176297,12 @@ static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){ int i; int iCol; int nToken = 0; + int rc = SQLITE_OK; /* Allocate and populate the array of LcsIterator objects. The array ** contains one element for each matchable phrase in the query. **/ - aIter = sqlite3_malloc(sizeof(LcsIterator) * pCsr->nPhrase); + aIter = sqlite3_malloc64(sizeof(LcsIterator) * pCsr->nPhrase); if( !aIter ) return SQLITE_NOMEM; memset(aIter, 0, sizeof(LcsIterator) * pCsr->nPhrase); (void)fts3ExprIterate(pCsr->pExpr, fts3MatchinfoLcsCb, (void*)aIter); @@ -175246,13 +176318,16 @@ static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){ int nLive = 0; /* Number of iterators in aIter not at EOF */ for(i=0; i<pInfo->nPhrase; i++){ - int rc; LcsIterator *pIt = &aIter[i]; rc = sqlite3Fts3EvalPhrasePoslist(pCsr, pIt->pExpr, iCol, &pIt->pRead); - if( rc!=SQLITE_OK ) return rc; + if( rc!=SQLITE_OK ) goto matchinfo_lcs_out; if( pIt->pRead ){ pIt->iPos = pIt->iPosOffset; - fts3LcsIteratorAdvance(&aIter[i]); + fts3LcsIteratorAdvance(pIt); + if( pIt->pRead==0 ){ + rc = FTS_CORRUPT_VTAB; + goto matchinfo_lcs_out; + } nLive++; } } @@ -175284,8 +176359,9 @@ static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){ pInfo->aMatchinfo[iCol] = nLcs; } + matchinfo_lcs_out: sqlite3_free(aIter); - return SQLITE_OK; + return rc; } /* @@ -175381,7 +176457,7 @@ static int fts3MatchinfoValues( case FTS3_MATCHINFO_LHITS: { int nZero = fts3MatchinfoSize(pInfo, zArg[i]) * sizeof(u32); memset(pInfo->aMatchinfo, 0, nZero); - fts3ExprLHitGather(pCsr->pExpr, pInfo); + rc = fts3ExprLHitGather(pCsr->pExpr, pInfo); break; } @@ -175533,6 +176609,10 @@ SQLITE_PRIVATE void sqlite3Fts3Snippet( return; } + /* Limit the snippet length to 64 tokens. */ + if( nToken<-64 ) nToken = -64; + if( nToken>+64 ) nToken = +64; + for(nSnippet=1; 1; nSnippet++){ int iSnip; /* Loop counter 0..nSnippet-1 */ @@ -175675,7 +176755,7 @@ SQLITE_PRIVATE void sqlite3Fts3Offsets( if( rc!=SQLITE_OK ) goto offsets_out; /* Allocate the array of TermOffset iterators. */ - sCtx.aTerm = (TermOffset *)sqlite3_malloc(sizeof(TermOffset)*nToken); + sCtx.aTerm = (TermOffset *)sqlite3_malloc64(sizeof(TermOffset)*nToken); if( 0==sCtx.aTerm ){ rc = SQLITE_NOMEM; goto offsets_out; @@ -175900,7 +176980,7 @@ typedef struct unicode_cursor unicode_cursor; struct unicode_tokenizer { sqlite3_tokenizer base; - int bRemoveDiacritic; + int eRemoveDiacritic; int nException; int *aiException; }; @@ -175973,7 +177053,7 @@ static int unicodeAddExceptions( int *aNew; /* New aiException[] array */ int nNew; /* Number of valid entries in array aNew[] */ - aNew = sqlite3_realloc(p->aiException, (p->nException+nEntry)*sizeof(int)); + aNew = sqlite3_realloc64(p->aiException,(p->nException+nEntry)*sizeof(int)); if( aNew==0 ) return SQLITE_NOMEM; nNew = p->nException; @@ -176045,17 +177125,20 @@ static int unicodeCreate( pNew = (unicode_tokenizer *) sqlite3_malloc(sizeof(unicode_tokenizer)); if( pNew==NULL ) return SQLITE_NOMEM; memset(pNew, 0, sizeof(unicode_tokenizer)); - pNew->bRemoveDiacritic = 1; + pNew->eRemoveDiacritic = 1; for(i=0; rc==SQLITE_OK && i<nArg; i++){ const char *z = azArg[i]; int n = (int)strlen(z); if( n==19 && memcmp("remove_diacritics=1", z, 19)==0 ){ - pNew->bRemoveDiacritic = 1; + pNew->eRemoveDiacritic = 1; } else if( n==19 && memcmp("remove_diacritics=0", z, 19)==0 ){ - pNew->bRemoveDiacritic = 0; + pNew->eRemoveDiacritic = 0; + } + else if( n==19 && memcmp("remove_diacritics=2", z, 19)==0 ){ + pNew->eRemoveDiacritic = 2; } else if( n>=11 && memcmp("tokenchars=", z, 11)==0 ){ rc = unicodeAddExceptions(pNew, 1, &z[11], n-11); @@ -176159,7 +177242,7 @@ static int unicodeNext( /* Grow the output buffer if required. */ if( (zOut-pCsr->zToken)>=(pCsr->nAlloc-4) ){ - char *zNew = sqlite3_realloc(pCsr->zToken, pCsr->nAlloc+64); + char *zNew = sqlite3_realloc64(pCsr->zToken, pCsr->nAlloc+64); if( !zNew ) return SQLITE_NOMEM; zOut = &zNew[zOut - pCsr->zToken]; pCsr->zToken = zNew; @@ -176168,7 +177251,7 @@ static int unicodeNext( /* Write the folded case of the last character read to the output */ zEnd = z; - iOut = sqlite3FtsUnicodeFold((int)iCode, p->bRemoveDiacritic); + iOut = sqlite3FtsUnicodeFold((int)iCode, p->eRemoveDiacritic); if( iOut ){ WRITE_UTF8(zOut, iOut); } @@ -176213,7 +177296,7 @@ SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const * /************** End of fts3_unicode.c ****************************************/ /************** Begin file fts3_unicode2.c ***********************************/ /* -** 2012 May 25 +** 2012-05-25 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: @@ -176373,32 +177456,48 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int c){ ** E"). The resuls of passing a codepoint that corresponds to an ** uppercase letter are undefined. */ -static int remove_diacritic(int c){ +static int remove_diacritic(int c, int bComplex){ unsigned short aDia[] = { 0, 1797, 1848, 1859, 1891, 1928, 1940, 1995, 2024, 2040, 2060, 2110, 2168, 2206, 2264, 2286, 2344, 2383, 2472, 2488, 2516, 2596, 2668, 2732, 2782, 2842, 2894, 2954, 2984, 3000, 3028, 3336, - 3456, 3696, 3712, 3728, 3744, 3896, 3912, 3928, - 3968, 4008, 4040, 4106, 4138, 4170, 4202, 4234, - 4266, 4296, 4312, 4344, 4408, 4424, 4472, 4504, - 6148, 6198, 6264, 6280, 6360, 6429, 6505, 6529, - 61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726, - 61784, 61800, 61836, 61880, 61914, 61948, 61998, 62122, - 62154, 62200, 62218, 62302, 62364, 62442, 62478, 62536, - 62554, 62584, 62604, 62640, 62648, 62656, 62664, 62730, - 62924, 63050, 63082, 63274, 63390, + 3456, 3696, 3712, 3728, 3744, 3766, 3832, 3896, + 3912, 3928, 3944, 3968, 4008, 4040, 4056, 4106, + 4138, 4170, 4202, 4234, 4266, 4296, 4312, 4344, + 4408, 4424, 4442, 4472, 4488, 4504, 6148, 6198, + 6264, 6280, 6360, 6429, 6505, 6529, 61448, 61468, + 61512, 61534, 61592, 61610, 61642, 61672, 61688, 61704, + 61726, 61784, 61800, 61816, 61836, 61880, 61896, 61914, + 61948, 61998, 62062, 62122, 62154, 62184, 62200, 62218, + 62252, 62302, 62364, 62410, 62442, 62478, 62536, 62554, + 62584, 62604, 62640, 62648, 62656, 62664, 62730, 62766, + 62830, 62890, 62924, 62974, 63032, 63050, 63082, 63118, + 63182, 63242, 63274, 63310, 63368, 63390, }; - char aChar[] = { - '\0', 'a', 'c', 'e', 'i', 'n', 'o', 'u', 'y', 'y', 'a', 'c', - 'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r', - 's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o', - 'u', 'g', 'k', 'o', 'j', 'g', 'n', 'a', 'e', 'i', 'o', 'r', - 'u', 's', 't', 'h', 'a', 'e', 'o', 'y', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', 'a', 'b', 'd', 'd', 'e', 'f', 'g', 'h', - 'h', 'i', 'k', 'l', 'l', 'm', 'n', 'p', 'r', 'r', 's', 't', - 'u', 'v', 'w', 'w', 'x', 'y', 'z', 'h', 't', 'w', 'y', 'a', - 'e', 'i', 'o', 'u', 'y', +#define HIBIT ((unsigned char)0x80) + unsigned char aChar[] = { + '\0', 'a', 'c', 'e', 'i', 'n', + 'o', 'u', 'y', 'y', 'a', 'c', + 'd', 'e', 'e', 'g', 'h', 'i', + 'j', 'k', 'l', 'n', 'o', 'r', + 's', 't', 'u', 'u', 'w', 'y', + 'z', 'o', 'u', 'a', 'i', 'o', + 'u', 'u'|HIBIT, 'a'|HIBIT, 'g', 'k', 'o', + 'o'|HIBIT, 'j', 'g', 'n', 'a'|HIBIT, 'a', + 'e', 'i', 'o', 'r', 'u', 's', + 't', 'h', 'a', 'e', 'o'|HIBIT, 'o', + 'o'|HIBIT, 'y', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', 'a', 'b', + 'c'|HIBIT, 'd', 'd', 'e'|HIBIT, 'e', 'e'|HIBIT, + 'f', 'g', 'h', 'h', 'i', 'i'|HIBIT, + 'k', 'l', 'l'|HIBIT, 'l', 'm', 'n', + 'o'|HIBIT, 'p', 'r', 'r'|HIBIT, 'r', 's', + 's'|HIBIT, 't', 'u', 'u'|HIBIT, 'v', 'w', + 'w', 'x', 'y', 'z', 'h', 't', + 'w', 'y', 'a', 'a'|HIBIT, 'a'|HIBIT, 'a'|HIBIT, + 'e', 'e'|HIBIT, 'e'|HIBIT, 'i', 'o', 'o'|HIBIT, + 'o'|HIBIT, 'o'|HIBIT, 'u', 'u'|HIBIT, 'u'|HIBIT, 'y', }; unsigned int key = (((unsigned int)c)<<3) | 0x00000007; @@ -176415,7 +177514,8 @@ static int remove_diacritic(int c){ } } assert( key>=aDia[iRes] ); - return ((c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : (int)aChar[iRes]); + if( bComplex==0 && (aChar[iRes] & 0x80) ) return c; + return (c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : ((int)aChar[iRes] & 0x7F); } @@ -176428,8 +177528,8 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int c){ unsigned int mask1 = 0x000361F8; if( c<768 || c>817 ) return 0; return (c < 768+32) ? - (mask0 & (1 << (c-768))) : - (mask1 & (1 << (c-768-32))); + (mask0 & ((unsigned int)1 << (c-768))) : + (mask1 & ((unsigned int)1 << (c-768-32))); } @@ -176442,7 +177542,7 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int c){ ** The results are undefined if the value passed to this function ** is less than zero. */ -SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){ +SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){ /* Each entry in the following array defines a rule for folding a range ** of codepoints to lower case. The rule applies to a range of nRange ** codepoints starting at codepoint iCode. @@ -176565,7 +177665,9 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){ assert( ret>0 ); } - if( bRemoveDiacritic ) ret = remove_diacritic(ret); + if( eRemoveDiacritic ){ + ret = remove_diacritic(ret, eRemoveDiacritic==2); + } } else if( c>=66560 && c<66600 ){ @@ -177272,7 +178374,7 @@ static JSON_NOINLINE int jsonParseAddNodeExpand( assert( pParse->nNode>=pParse->nAlloc ); if( pParse->oom ) return -1; nNew = pParse->nAlloc*2 + 10; - pNew = sqlite3_realloc(pParse->aNode, sizeof(JsonNode)*nNew); + pNew = sqlite3_realloc64(pParse->aNode, sizeof(JsonNode)*nNew); if( pNew==0 ){ pParse->oom = 1; return -1; @@ -177546,7 +178648,7 @@ static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){ static int jsonParseFindParents(JsonParse *pParse){ u32 *aUp; assert( pParse->aUp==0 ); - aUp = pParse->aUp = sqlite3_malloc( sizeof(u32)*pParse->nNode ); + aUp = pParse->aUp = sqlite3_malloc64( sizeof(u32)*pParse->nNode ); if( aUp==0 ){ pParse->oom = 1; return SQLITE_NOMEM; @@ -177608,7 +178710,7 @@ static JsonParse *jsonParseCached( pMatch->iHold = iMaxHold+1; return pMatch; } - p = sqlite3_malloc( sizeof(*p) + nJson + 1 ); + p = sqlite3_malloc64( sizeof(*p) + nJson + 1 ); if( p==0 ){ sqlite3_result_error_nomem(pCtx); return 0; @@ -179253,6 +180355,9 @@ struct Rtree { u8 inWrTrans; /* True if inside write transaction */ u8 nAux; /* # of auxiliary columns in %_rowid */ u8 nAuxNotNull; /* Number of initial not-null aux columns */ +#ifdef SQLITE_DEBUG + u8 bCorrupt; /* Shadow table corruption detected */ +#endif int iDepth; /* Current depth of the r-tree structure */ char *zDb; /* Name of database containing r-tree table */ char *zName; /* Name of r-tree table */ @@ -179312,6 +180417,15 @@ struct Rtree { # define RTREE_ZERO 0.0 #endif +/* +** Set the Rtree.bCorrupt flag +*/ +#ifdef SQLITE_DEBUG +# define RTREE_IS_CORRUPT(X) ((X)->bCorrupt = 1) +#else +# define RTREE_IS_CORRUPT(X) +#endif + /* ** When doing a search of an r-tree, instances of the following structure ** record intermediate results from the tree walk. @@ -179678,8 +180792,8 @@ static void nodeZero(Rtree *pRtree, RtreeNode *p){ ** Given a node number iNode, return the corresponding key to use ** in the Rtree.aHash table. */ -static int nodeHash(i64 iNode){ - return iNode % HASHSIZE; +static unsigned int nodeHash(i64 iNode){ + return ((unsigned)iNode) % HASHSIZE; } /* @@ -179724,7 +180838,7 @@ static void nodeHashDelete(Rtree *pRtree, RtreeNode *pNode){ */ static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){ RtreeNode *pNode; - pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode) + pRtree->iNodeSize); + pNode = (RtreeNode *)sqlite3_malloc64(sizeof(RtreeNode) + pRtree->iNodeSize); if( pNode ){ memset(pNode, 0, sizeof(RtreeNode) + pRtree->iNodeSize); pNode->zData = (u8 *)&pNode[1]; @@ -179748,6 +180862,18 @@ static void nodeBlobReset(Rtree *pRtree){ } } +/* +** Check to see if pNode is the same as pParent or any of the parents +** of pParent. +*/ +static int nodeInParentChain(const RtreeNode *pNode, const RtreeNode *pParent){ + do{ + if( pNode==pParent ) return 1; + pParent = pParent->pParent; + }while( pParent ); + return 0; +} + /* ** Obtain a reference to an r-tree node. */ @@ -179766,6 +180892,10 @@ static int nodeAcquire( if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){ assert( !pParent || !pNode->pParent || pNode->pParent==pParent ); if( pParent && !pNode->pParent ){ + if( nodeInParentChain(pNode, pParent) ){ + RTREE_IS_CORRUPT(pRtree); + return SQLITE_CORRUPT_VTAB; + } pParent->nRef++; pNode->pParent = pParent; } @@ -179796,9 +180926,12 @@ static int nodeAcquire( *ppNode = 0; /* If unable to open an sqlite3_blob on the desired row, that can only ** be because the shadow tables hold erroneous data. */ - if( rc==SQLITE_ERROR ) rc = SQLITE_CORRUPT_VTAB; + if( rc==SQLITE_ERROR ){ + rc = SQLITE_CORRUPT_VTAB; + RTREE_IS_CORRUPT(pRtree); + } }else if( pRtree->iNodeSize==sqlite3_blob_bytes(pRtree->pNodeBlob) ){ - pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode)+pRtree->iNodeSize); + pNode = (RtreeNode *)sqlite3_malloc64(sizeof(RtreeNode)+pRtree->iNodeSize); if( !pNode ){ rc = SQLITE_NOMEM; }else{ @@ -179811,7 +180944,6 @@ static int nodeAcquire( pNode->pNext = 0; rc = sqlite3_blob_read(pRtree->pNodeBlob, pNode->zData, pRtree->iNodeSize, 0); - nodeReference(pParent); } } @@ -179825,6 +180957,7 @@ static int nodeAcquire( pRtree->iDepth = readInt16(pNode->zData); if( pRtree->iDepth>RTREE_MAX_DEPTH ){ rc = SQLITE_CORRUPT_VTAB; + RTREE_IS_CORRUPT(pRtree); } } @@ -179835,14 +180968,17 @@ static int nodeAcquire( if( pNode && rc==SQLITE_OK ){ if( NCELL(pNode)>((pRtree->iNodeSize-4)/pRtree->nBytesPerCell) ){ rc = SQLITE_CORRUPT_VTAB; + RTREE_IS_CORRUPT(pRtree); } } if( rc==SQLITE_OK ){ if( pNode!=0 ){ + nodeReference(pParent); nodeHashInsert(pRtree, pNode); }else{ rc = SQLITE_CORRUPT_VTAB; + RTREE_IS_CORRUPT(pRtree); } *ppNode = pNode; }else{ @@ -180068,7 +181204,7 @@ static void rtreeRelease(Rtree *pRtree){ pRtree->inWrTrans = 0; assert( pRtree->nCursor==0 ); nodeBlobReset(pRtree); - assert( pRtree->nNodeRef==0 ); + assert( pRtree->nNodeRef==0 || pRtree->bCorrupt ); sqlite3_finalize(pRtree->pWriteNode); sqlite3_finalize(pRtree->pDeleteNode); sqlite3_finalize(pRtree->pReadRowid); @@ -180127,7 +181263,7 @@ static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ Rtree *pRtree = (Rtree *)pVTab; RtreeCursor *pCsr; - pCsr = (RtreeCursor *)sqlite3_malloc(sizeof(RtreeCursor)); + pCsr = (RtreeCursor *)sqlite3_malloc64(sizeof(RtreeCursor)); if( pCsr ){ memset(pCsr, 0, sizeof(RtreeCursor)); pCsr->base.pVtab = pVTab; @@ -180400,6 +181536,7 @@ static int nodeRowidIndex( return SQLITE_OK; } } + RTREE_IS_CORRUPT(pRtree); return SQLITE_CORRUPT_VTAB; } @@ -180493,7 +181630,7 @@ static RtreeSearchPoint *rtreeEnqueue( RtreeSearchPoint *pNew; if( pCur->nPoint>=pCur->nPointAlloc ){ int nNew = pCur->nPointAlloc*2 + 8; - pNew = sqlite3_realloc(pCur->aPoint, nNew*sizeof(pCur->aPoint[0])); + pNew = sqlite3_realloc64(pCur->aPoint, nNew*sizeof(pCur->aPoint[0])); if( pNew==0 ) return 0; pCur->aPoint = pNew; pCur->nPointAlloc = nNew; @@ -180895,7 +182032,7 @@ static int rtreeFilter( */ rc = nodeAcquire(pRtree, 1, 0, &pRoot); if( rc==SQLITE_OK && argc>0 ){ - pCsr->aConstraint = sqlite3_malloc(sizeof(RtreeConstraint)*argc); + pCsr->aConstraint = sqlite3_malloc64(sizeof(RtreeConstraint)*argc); pCsr->nConstraint = argc; if( !pCsr->aConstraint ){ rc = SQLITE_NOMEM; @@ -181040,20 +182177,20 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ ){ u8 op; switch( p->op ){ - case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break; - case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; break; - case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break; - case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break; - case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break; - default: - assert( p->op==SQLITE_INDEX_CONSTRAINT_MATCH ); - op = RTREE_MATCH; - break; + case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break; + case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; break; + case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break; + case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break; + case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break; + case SQLITE_INDEX_CONSTRAINT_MATCH: op = RTREE_MATCH; break; + default: op = 0; break; + } + if( op ){ + zIdxStr[iIdx++] = op; + zIdxStr[iIdx++] = (char)(p->iColumn - 1 + '0'); + pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2); + pIdxInfo->aConstraintUsage[ii].omit = 1; } - zIdxStr[iIdx++] = op; - zIdxStr[iIdx++] = (char)(p->iColumn - 1 + '0'); - pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2); - pIdxInfo->aConstraintUsage[ii].omit = 1; } } @@ -181089,11 +182226,11 @@ static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){ #endif { switch( pRtree->nDim ){ - case 5: area = p->aCoord[9].i - p->aCoord[8].i; - case 4: area *= p->aCoord[7].i - p->aCoord[6].i; - case 3: area *= p->aCoord[5].i - p->aCoord[4].i; - case 2: area *= p->aCoord[3].i - p->aCoord[2].i; - default: area *= p->aCoord[1].i - p->aCoord[0].i; + case 5: area = (i64)p->aCoord[9].i - (i64)p->aCoord[8].i; + case 4: area *= (i64)p->aCoord[7].i - (i64)p->aCoord[6].i; + case 3: area *= (i64)p->aCoord[5].i - (i64)p->aCoord[4].i; + case 2: area *= (i64)p->aCoord[3].i - (i64)p->aCoord[2].i; + default: area *= (i64)p->aCoord[1].i - (i64)p->aCoord[0].i; } } return area; @@ -181262,12 +182399,14 @@ static int AdjustTree( RtreeCell *pCell /* This cell was just inserted */ ){ RtreeNode *p = pNode; + int cnt = 0; while( p->pParent ){ RtreeNode *pParent = p->pParent; RtreeCell cell; int iCell; - if( nodeParentIndex(pRtree, p, &iCell) ){ + if( (++cnt)>1000 || nodeParentIndex(pRtree, p, &iCell) ){ + RTREE_IS_CORRUPT(pRtree); return SQLITE_CORRUPT_VTAB; } @@ -181464,9 +182603,9 @@ static int splitNodeStartree( int iBestSplit = 0; RtreeDValue fBestMargin = RTREE_ZERO; - int nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int)); + sqlite3_int64 nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int)); - aaSorted = (int **)sqlite3_malloc(nByte); + aaSorted = (int **)sqlite3_malloc64(nByte); if( !aaSorted ){ return SQLITE_NOMEM; } @@ -181587,7 +182726,7 @@ static int SplitNode( /* Allocate an array and populate it with a copy of pCell and ** all cells from node pLeft. Then zero the original node. */ - aCell = sqlite3_malloc((sizeof(RtreeCell)+sizeof(int))*(nCell+1)); + aCell = sqlite3_malloc64((sizeof(RtreeCell)+sizeof(int))*(nCell+1)); if( !aCell ){ rc = SQLITE_NOMEM; goto splitnode_out; @@ -181735,7 +182874,10 @@ static int fixLeafParent(Rtree *pRtree, RtreeNode *pLeaf){ } rc = sqlite3_reset(pRtree->pReadParent); if( rc==SQLITE_OK ) rc = rc2; - if( rc==SQLITE_OK && !pChild->pParent ) rc = SQLITE_CORRUPT_VTAB; + if( rc==SQLITE_OK && !pChild->pParent ){ + RTREE_IS_CORRUPT(pRtree); + rc = SQLITE_CORRUPT_VTAB; + } pChild = pChild->pParent; } return rc; @@ -181875,7 +183017,7 @@ static int Reinsert( /* Allocate the buffers used by this operation. The allocation is ** relinquished before this function returns. */ - aCell = (RtreeCell *)sqlite3_malloc(n * ( + aCell = (RtreeCell *)sqlite3_malloc64(n * ( sizeof(RtreeCell) + /* aCell array */ sizeof(int) + /* aOrder array */ sizeof(int) + /* aSpare array */ @@ -182049,8 +183191,12 @@ static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){ rc = findLeafNode(pRtree, iDelete, &pLeaf, 0); } +#ifdef CORRUPT_DB + assert( pLeaf!=0 || rc!=SQLITE_OK || CORRUPT_DB ); +#endif + /* Delete the cell in question from the leaf node. */ - if( rc==SQLITE_OK ){ + if( rc==SQLITE_OK && pLeaf ){ int rc2; rc = nodeRowidIndex(pRtree, pLeaf, iDelete, &iCell); if( rc==SQLITE_OK ){ @@ -182322,7 +183468,7 @@ static int rtreeUpdate( rc = rc2; } } - if( pRtree->nAux ){ + if( rc==SQLITE_OK && pRtree->nAux ){ sqlite3_stmt *pUp = pRtree->pWriteAux; int jj; sqlite3_bind_int64(pUp, 1, *pRowid); @@ -182520,6 +183666,7 @@ static int rtreeSqlInit( }; sqlite3_stmt **appStmt[N_STATEMENT]; int i; + const int f = SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB; pRtree->db = db; @@ -182576,8 +183723,7 @@ static int rtreeSqlInit( } zSql = sqlite3_mprintf(zFormat, zDb, zPrefix); if( zSql ){ - rc = sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_PERSISTENT, - appStmt[i], 0); + rc = sqlite3_prepare_v3(db, zSql, -1, f, appStmt[i], 0); }else{ rc = SQLITE_NOMEM; } @@ -182607,8 +183753,7 @@ static int rtreeSqlInit( if( zSql==0 ){ rc = SQLITE_NOMEM; }else{ - rc = sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_PERSISTENT, - &pRtree->pWriteAux, 0); + rc = sqlite3_prepare_v3(db, zSql, -1, f, &pRtree->pWriteAux, 0); sqlite3_free(zSql); } } @@ -182684,6 +183829,7 @@ static int getNodeSize( *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); }else if( pRtree->iNodeSize<(512-64) ){ rc = SQLITE_CORRUPT_VTAB; + RTREE_IS_CORRUPT(pRtree); *pzErr = sqlite3_mprintf("undersize RTree blobs in \"%q_node\"", pRtree->zName); } @@ -182739,7 +183885,7 @@ static int rtreeInit( /* Allocate the sqlite3_vtab structure */ nDb = (int)strlen(argv[1]); nName = (int)strlen(argv[2]); - pRtree = (Rtree *)sqlite3_malloc(sizeof(Rtree)+nDb+nName+2); + pRtree = (Rtree *)sqlite3_malloc64(sizeof(Rtree)+nDb+nName+2); if( !pRtree ){ return SQLITE_NOMEM; } @@ -183007,8 +184153,7 @@ static void rtreeCheckAppendMsg(RtreeCheck *pCheck, const char *zFmt, ...){ static u8 *rtreeCheckGetNode(RtreeCheck *pCheck, i64 iNode, int *pnNode){ u8 *pRet = 0; /* Return value */ - assert( pCheck->rc==SQLITE_OK ); - if( pCheck->pGetNode==0 ){ + if( pCheck->rc==SQLITE_OK && pCheck->pGetNode==0 ){ pCheck->pGetNode = rtreeCheckPrepare(pCheck, "SELECT data FROM %Q.'%q_node' WHERE nodeno=?", pCheck->zDb, pCheck->zTab @@ -183020,7 +184165,7 @@ static u8 *rtreeCheckGetNode(RtreeCheck *pCheck, i64 iNode, int *pnNode){ if( sqlite3_step(pCheck->pGetNode)==SQLITE_ROW ){ int nNode = sqlite3_column_bytes(pCheck->pGetNode, 0); const u8 *pNode = (const u8*)sqlite3_column_blob(pCheck->pGetNode, 0); - pRet = sqlite3_malloc(nNode); + pRet = sqlite3_malloc64(nNode); if( pRet==0 ){ pCheck->rc = SQLITE_NOMEM; }else{ @@ -183499,6 +184644,14 @@ struct GeoPoly { */ #define GEOPOLY_SZ(N) (sizeof(GeoPoly) + sizeof(GeoCoord)*2*((N)-4)) +/* Macros to access coordinates of a GeoPoly. +** We have to use these macros, rather than just say p->a[i] in order +** to silence (incorrect) UBSAN warnings if the array index is too large. +*/ +#define GeoX(P,I) (((GeoCoord*)(P)->a)[(I)*2]) +#define GeoY(P,I) (((GeoCoord*)(P)->a)[(I)*2+1]) + + /* ** State of a parse of a GeoJSON input. */ @@ -183691,8 +184844,9 @@ static GeoPoly *geopolyFuncParam( memcpy(p->hdr, a, nByte); if( a[0] != *(unsigned char*)&x ){ int ii; - for(ii=0; ii<nVertex*2; ii++){ - geopolySwab32((unsigned char*)&p->a[ii]); + for(ii=0; ii<nVertex; ii++){ + geopolySwab32((unsigned char*)&GeoX(p,ii)); + geopolySwab32((unsigned char*)&GeoY(p,ii)); } p->hdr[0] ^= 1; } @@ -183751,9 +184905,9 @@ static void geopolyJsonFunc( int i; sqlite3_str_append(x, "[", 1); for(i=0; i<p->nVertex; i++){ - sqlite3_str_appendf(x, "[%!g,%!g],", p->a[i*2], p->a[i*2+1]); + sqlite3_str_appendf(x, "[%!g,%!g],", GeoX(p,i), GeoY(p,i)); } - sqlite3_str_appendf(x, "[%!g,%!g]]", p->a[0], p->a[1]); + sqlite3_str_appendf(x, "[%!g,%!g]]", GeoX(p,0), GeoY(p,0)); sqlite3_result_text(context, sqlite3_str_finish(x), -1, sqlite3_free); sqlite3_free(p); } @@ -183770,7 +184924,9 @@ static void geopolySvgFunc( int argc, sqlite3_value **argv ){ - GeoPoly *p = geopolyFuncParam(context, argv[0], 0); + GeoPoly *p; + if( argc<1 ) return; + p = geopolyFuncParam(context, argv[0], 0); if( p ){ sqlite3 *db = sqlite3_context_db_handle(context); sqlite3_str *x = sqlite3_str_new(db); @@ -183778,10 +184934,10 @@ static void geopolySvgFunc( char cSep = '\''; sqlite3_str_appendf(x, "<polyline points="); for(i=0; i<p->nVertex; i++){ - sqlite3_str_appendf(x, "%c%g,%g", cSep, p->a[i*2], p->a[i*2+1]); + sqlite3_str_appendf(x, "%c%g,%g", cSep, GeoX(p,i), GeoY(p,i)); cSep = ' '; } - sqlite3_str_appendf(x, " %g,%g'", p->a[0], p->a[1]); + sqlite3_str_appendf(x, " %g,%g'", GeoX(p,0), GeoY(p,0)); for(i=1; i<argc; i++){ const char *z = (const char*)sqlite3_value_text(argv[i]); if( z && z[0] ){ @@ -183826,12 +184982,12 @@ static void geopolyXformFunc( int ii; if( p ){ for(ii=0; ii<p->nVertex; ii++){ - x0 = p->a[ii*2]; - y0 = p->a[ii*2+1]; + x0 = GeoX(p,ii); + y0 = GeoY(p,ii); x1 = (GeoCoord)(A*x0 + B*y0 + E); y1 = (GeoCoord)(C*x0 + D*y0 + F); - p->a[ii*2] = x1; - p->a[ii*2+1] = y1; + GeoX(p,ii) = x1; + GeoY(p,ii) = y1; } sqlite3_result_blob(context, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT); @@ -183850,12 +185006,12 @@ static double geopolyArea(GeoPoly *p){ double rArea = 0.0; int ii; for(ii=0; ii<p->nVertex-1; ii++){ - rArea += (p->a[ii*2] - p->a[ii*2+2]) /* (x0 - x1) */ - * (p->a[ii*2+1] + p->a[ii*2+3]) /* (y0 + y1) */ + rArea += (GeoX(p,ii) - GeoX(p,ii+1)) /* (x0 - x1) */ + * (GeoY(p,ii) + GeoY(p,ii+1)) /* (y0 + y1) */ * 0.5; } - rArea += (p->a[ii*2] - p->a[0]) /* (xN - x0) */ - * (p->a[ii*2+1] + p->a[1]) /* (yN + y0) */ + rArea += (GeoX(p,ii) - GeoX(p,0)) /* (xN - x0) */ + * (GeoY(p,ii) + GeoY(p,0)) /* (yN + y0) */ * 0.5; return rArea; } @@ -183902,13 +185058,13 @@ static void geopolyCcwFunc( if( p ){ if( geopolyArea(p)<0.0 ){ int ii, jj; - for(ii=2, jj=p->nVertex*2 - 2; ii<jj; ii+=2, jj-=2){ - GeoCoord t = p->a[ii]; - p->a[ii] = p->a[jj]; - p->a[jj] = t; - t = p->a[ii+1]; - p->a[ii+1] = p->a[jj+1]; - p->a[jj+1] = t; + for(ii=1, jj=p->nVertex-1; ii<jj; ii++, jj--){ + GeoCoord t = GeoX(p,ii); + GeoX(p,ii) = GeoX(p,jj); + GeoX(p,jj) = t; + t = GeoY(p,ii); + GeoY(p,ii) = GeoY(p,jj); + GeoY(p,jj) = t; } } sqlite3_result_blob(context, p->hdr, @@ -183968,8 +185124,8 @@ static void geopolyRegularFunc( p->hdr[3] = n&0xff; for(i=0; i<n; i++){ double rAngle = 2.0*GEOPOLY_PI*i/n; - p->a[i*2] = x - r*geopolySine(rAngle-0.5*GEOPOLY_PI); - p->a[i*2+1] = y + r*geopolySine(rAngle); + GeoX(p,i) = x - r*geopolySine(rAngle-0.5*GEOPOLY_PI); + GeoY(p,i) = y + r*geopolySine(rAngle); } sqlite3_result_blob(context, p->hdr, 4+8*n, SQLITE_TRANSIENT); sqlite3_free(p); @@ -184006,13 +185162,13 @@ static GeoPoly *geopolyBBox( } if( p ){ int ii; - mnX = mxX = p->a[0]; - mnY = mxY = p->a[1]; + mnX = mxX = GeoX(p,0); + mnY = mxY = GeoY(p,0); for(ii=1; ii<p->nVertex; ii++){ - double r = p->a[ii*2]; + double r = GeoX(p,ii); if( r<mnX ) mnX = (float)r; else if( r>mxX ) mxX = (float)r; - r = p->a[ii*2+1]; + r = GeoY(p,ii); if( r<mnY ) mnY = (float)r; else if( r>mxY ) mxY = (float)r; } @@ -184032,14 +185188,14 @@ static GeoPoly *geopolyBBox( pOut->hdr[1] = 0; pOut->hdr[2] = 0; pOut->hdr[3] = 4; - pOut->a[0] = mnX; - pOut->a[1] = mnY; - pOut->a[2] = mxX; - pOut->a[3] = mnY; - pOut->a[4] = mxX; - pOut->a[5] = mxY; - pOut->a[6] = mnX; - pOut->a[7] = mxY; + GeoX(pOut,0) = mnX; + GeoY(pOut,0) = mnY; + GeoX(pOut,1) = mxX; + GeoY(pOut,1) = mnY; + GeoX(pOut,2) = mxX; + GeoY(pOut,2) = mxY; + GeoX(pOut,3) = mnX; + GeoY(pOut,3) = mxY; }else{ sqlite3_free(p); aCoord[0].f = mnX; @@ -184177,14 +185333,14 @@ static void geopolyContainsPointFunc( int ii; if( p1==0 ) return; for(ii=0; ii<p1->nVertex-1; ii++){ - v = pointBeneathLine(x0,y0,p1->a[ii*2],p1->a[ii*2+1], - p1->a[ii*2+2],p1->a[ii*2+3]); + v = pointBeneathLine(x0,y0,GeoX(p1,ii), GeoY(p1,ii), + GeoX(p1,ii+1),GeoY(p1,ii+1)); if( v==2 ) break; cnt += v; } if( v!=2 ){ - v = pointBeneathLine(x0,y0,p1->a[ii*2],p1->a[ii*2+1], - p1->a[0],p1->a[1]); + v = pointBeneathLine(x0,y0,GeoX(p1,ii), GeoY(p1,ii), + GeoX(p1,0), GeoY(p1,0)); } if( v==2 ){ sqlite3_result_int(context, 1); @@ -184306,10 +185462,10 @@ static void geopolyAddSegments( unsigned int i; GeoCoord *x; for(i=0; i<(unsigned)pPoly->nVertex-1; i++){ - x = pPoly->a + (i*2); + x = &GeoX(pPoly,i); geopolyAddOneSegment(p, x[0], x[1], x[2], x[3], side, i); } - x = pPoly->a + (i*2); + x = &GeoX(pPoly,i); geopolyAddOneSegment(p, x[0], x[1], pPoly->a[0], pPoly->a[1], side, i); } @@ -185254,12 +186410,12 @@ static void rtreeMatchArgFree(void *pArg){ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){ RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx); RtreeMatchArg *pBlob; - int nBlob; + sqlite3_int64 nBlob; int memErr = 0; nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue) + nArg*sizeof(sqlite3_value*); - pBlob = (RtreeMatchArg *)sqlite3_malloc(nBlob); + pBlob = (RtreeMatchArg *)sqlite3_malloc64(nBlob); if( !pBlob ){ sqlite3_result_error_nomem(ctx); }else{ @@ -185970,7 +187126,7 @@ static int icuCreate( if( argc>0 ){ n = strlen(argv[0])+1; } - p = (IcuTokenizer *)sqlite3_malloc(sizeof(IcuTokenizer)+n); + p = (IcuTokenizer *)sqlite3_malloc64(sizeof(IcuTokenizer)+n); if( !p ){ return SQLITE_NOMEM; } @@ -186027,7 +187183,7 @@ static int icuOpen( nInput = strlen(zInput); } nChar = nInput+1; - pCsr = (IcuCursor *)sqlite3_malloc( + pCsr = (IcuCursor *)sqlite3_malloc64( sizeof(IcuCursor) + /* IcuCursor */ ((nChar+3)&~3) * sizeof(UChar) + /* IcuCursor.aChar[] */ (nChar+1) * sizeof(int) /* IcuCursor.aOffset[] */ @@ -186599,7 +187755,11 @@ SQLITE_API sqlite3rbu *sqlite3rbu_open( ** name of the state database is "<database>-vacuum", where <database> ** is the name of the target database file. In this case, on UNIX, if the ** state database is not already present in the file-system, it is created -** with the same permissions as the target db is made. +** with the same permissions as the target db is made. +** +** With an RBU vacuum, it is an SQLITE_MISUSE error if the name of the +** state database ends with "-vactmp". This name is reserved for internal +** use. ** ** This function does not delete the state database after an RBU vacuum ** is completed, even if it created it. However, if the call to @@ -189257,7 +190417,7 @@ static void rbuOpenDatabase(sqlite3rbu *p, int *pbRetry){ if( *zExtra=='\0' ) zExtra = 0; } - zTarget = sqlite3_mprintf("file:%s-vacuum?rbu_memory=1%s%s", + zTarget = sqlite3_mprintf("file:%s-vactmp?rbu_memory=1%s%s", sqlite3_db_filename(p->dbRbu, "main"), (zExtra==0 ? "" : "&"), (zExtra==0 ? "" : zExtra) ); @@ -190523,6 +191683,12 @@ SQLITE_API sqlite3rbu *sqlite3rbu_vacuum( const char *zState ){ if( zTarget==0 ){ return rbuMisuseError(); } + if( zState ){ + int n = strlen(zState); + if( n>=7 && 0==memcmp("-vactmp", &zState[n-7], 7) ){ + return rbuMisuseError(); + } + } /* TODO: Check that both arguments are non-NULL */ return openRbuHandle(0, zTarget, zState); } @@ -190719,7 +191885,10 @@ SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *p){ if( p->eStage==RBU_STAGE_OAL ){ assert( rc!=SQLITE_DONE ); if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, 0); - if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbRbu, "BEGIN IMMEDIATE", 0, 0, 0); + if( rc==SQLITE_OK ){ + const char *zBegin = rbuIsVacuum(p) ? "BEGIN" : "BEGIN IMMEDIATE"; + rc = sqlite3_exec(p->dbRbu, zBegin, 0, 0, 0); + } if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbMain, "BEGIN IMMEDIATE", 0, 0,0); } @@ -192250,6 +193419,10 @@ statNextRestart: goto statNextRestart; /* Tail recursion */ } pCsr->iPage++; + if( pCsr->iPage>=ArraySize(pCsr->aPage) ){ + statResetCsr(pCsr); + return SQLITE_CORRUPT_BKPT; + } assert( p==&pCsr->aPage[pCsr->iPage-1] ); if( p->iCell==p->nCell ){ @@ -192321,7 +193494,6 @@ static int statFilter( StatTable *pTab = (StatTable*)(pCursor->pVtab); char *zSql; int rc = SQLITE_OK; - char *zMaster; if( idxNum==1 ){ const char *zDbase = (const char*)sqlite3_value_text(argv[0]); @@ -192337,13 +193509,12 @@ static int statFilter( statResetCsr(pCsr); sqlite3_finalize(pCsr->pStmt); pCsr->pStmt = 0; - zMaster = pCsr->iDb==1 ? "sqlite_temp_master" : "sqlite_master"; zSql = sqlite3_mprintf( "SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type" " UNION ALL " "SELECT name, rootpage, type" - " FROM \"%w\".%s WHERE rootpage!=0" - " ORDER BY name", pTab->db->aDb[pCsr->iDb].zDbSName, zMaster); + " FROM \"%w\".sqlite_master WHERE rootpage!=0" + " ORDER BY name", pTab->db->aDb[pCsr->iDb].zDbSName); if( zSql==0 ){ return SQLITE_NOMEM_BKPT; }else{ @@ -193231,7 +194402,7 @@ static void sessionPutI64(u8 *aBuf, sqlite3_int64 i){ static int sessionSerializeValue( u8 *aBuf, /* If non-NULL, write serialized value here */ sqlite3_value *pValue, /* Value to serialize */ - int *pnWrite /* IN/OUT: Increment by bytes written */ + sqlite3_int64 *pnWrite /* IN/OUT: Increment by bytes written */ ){ int nByte; /* Size of serialized value in bytes */ @@ -193772,7 +194943,7 @@ static int sessionGrowHash(int bPatchset, SessionTable *pTab){ SessionChange **apNew; int nNew = (pTab->nChange ? pTab->nChange : 128) * 2; - apNew = (SessionChange **)sqlite3_malloc(sizeof(SessionChange *) * nNew); + apNew = (SessionChange **)sqlite3_malloc64(sizeof(SessionChange *) * nNew); if( apNew==0 ){ if( pTab->nChange==0 ){ return SQLITE_ERROR; @@ -193838,7 +195009,7 @@ static int sessionTableInfo( char *zPragma; sqlite3_stmt *pStmt; int rc; - int nByte; + sqlite3_int64 nByte; int nDbCol = 0; int nThis; int i; @@ -193881,7 +195052,7 @@ static int sessionTableInfo( if( rc==SQLITE_OK ){ nByte += nDbCol * (sizeof(const char *) + sizeof(u8) + 1); - pAlloc = sqlite3_malloc(nByte); + pAlloc = sqlite3_malloc64(nByte); if( pAlloc==0 ){ rc = SQLITE_NOMEM; } @@ -194022,7 +195193,7 @@ static void sessionPreupdateOneChange( int iHash; int bNull = 0; int rc = SQLITE_OK; - SessionStat1Ctx stat1 = {0}; + SessionStat1Ctx stat1 = {{0,0,0,0,0},0}; if( pSession->rc ) return; @@ -194079,7 +195250,7 @@ static void sessionPreupdateOneChange( ** this is an SQLITE_UPDATE or SQLITE_DELETE), or just the PK ** values (if this is an INSERT). */ SessionChange *pChange; /* New change object */ - int nByte; /* Number of bytes to allocate */ + sqlite3_int64 nByte; /* Number of bytes to allocate */ int i; /* Used to iterate through columns */ assert( rc==SQLITE_OK ); @@ -194104,7 +195275,7 @@ static void sessionPreupdateOneChange( } /* Allocate the change object */ - pChange = (SessionChange *)sqlite3_malloc(nByte); + pChange = (SessionChange *)sqlite3_malloc64(nByte); if( !pChange ){ rc = SQLITE_NOMEM; goto error_out; @@ -194548,7 +195719,7 @@ SQLITE_API int sqlite3session_create( *ppSession = 0; /* Allocate and populate the new session object. */ - pNew = (sqlite3_session *)sqlite3_malloc(sizeof(sqlite3_session) + nDb + 1); + pNew = (sqlite3_session *)sqlite3_malloc64(sizeof(sqlite3_session) + nDb + 1); if( !pNew ) return SQLITE_NOMEM; memset(pNew, 0, sizeof(sqlite3_session)); pNew->db = db; @@ -194667,7 +195838,7 @@ SQLITE_API int sqlite3session_attach( if( !pTab ){ /* Allocate new SessionTable object. */ - pTab = (SessionTable *)sqlite3_malloc(sizeof(SessionTable) + nName + 1); + pTab = (SessionTable *)sqlite3_malloc64(sizeof(SessionTable) + nName + 1); if( !pTab ){ rc = SQLITE_NOMEM; }else{ @@ -194727,7 +195898,7 @@ static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){ static void sessionAppendValue(SessionBuffer *p, sqlite3_value *pVal, int *pRc){ int rc = *pRc; if( rc==SQLITE_OK ){ - int nByte = 0; + sqlite3_int64 nByte = 0; rc = sessionSerializeValue(0, pVal, &nByte); sessionBufferGrow(p, nByte, &rc); if( rc==SQLITE_OK ){ @@ -195603,7 +196774,7 @@ static int sessionValueSetStr( ** argument to sqlite3ValueSetStr() and have the copy created ** automatically. But doing so makes it difficult to detect any OOM ** error. Hence the code to create the copy externally. */ - u8 *aCopy = sqlite3_malloc(nData+1); + u8 *aCopy = sqlite3_malloc64((sqlite3_int64)nData+1); if( aCopy==0 ) return SQLITE_NOMEM; memcpy(aCopy, aData, nData); sqlite3ValueSetStr(pVal, nData, (char*)aCopy, enc, sqlite3_free); @@ -196216,7 +197387,7 @@ static int sessionChangesetInvert( int iCol; if( 0==apVal ){ - apVal = (sqlite3_value **)sqlite3_malloc(sizeof(apVal[0])*nCol*2); + apVal = (sqlite3_value **)sqlite3_malloc64(sizeof(apVal[0])*nCol*2); if( 0==apVal ){ rc = SQLITE_NOMEM; goto finished_invert; @@ -197489,7 +198660,7 @@ static int sessionChangeMerge( int rc = SQLITE_OK; if( !pExist ){ - pNew = (SessionChange *)sqlite3_malloc(sizeof(SessionChange) + nRec); + pNew = (SessionChange *)sqlite3_malloc64(sizeof(SessionChange) + nRec); if( !pNew ){ return SQLITE_NOMEM; } @@ -197522,8 +198693,8 @@ static int sessionChangeMerge( if( pExist->op==SQLITE_DELETE && pExist->bIndirect ){ *ppNew = pExist; }else{ - int nByte = nRec + pExist->nRecord + sizeof(SessionChange); - pNew = (SessionChange*)sqlite3_malloc(nByte); + sqlite3_int64 nByte = nRec + pExist->nRecord + sizeof(SessionChange); + pNew = (SessionChange*)sqlite3_malloc64(nByte); if( pNew==0 ){ rc = SQLITE_NOMEM; }else{ @@ -197583,14 +198754,14 @@ static int sessionChangeMerge( assert( pNew==0 ); }else{ u8 *aExist = pExist->aRecord; - int nByte; + sqlite3_int64 nByte; u8 *aCsr; /* Allocate a new SessionChange object. Ensure that the aRecord[] ** buffer of the new object is large enough to hold any record that ** may be generated by combining the input records. */ nByte = sizeof(SessionChange) + pExist->nRecord + nRec; - pNew = (SessionChange *)sqlite3_malloc(nByte); + pNew = (SessionChange *)sqlite3_malloc64(nByte); if( !pNew ){ sqlite3_free(pExist); return SQLITE_NOMEM; @@ -197696,7 +198867,7 @@ static int sessionChangesetToHash( if( !pTab ){ SessionTable **ppTab; - pTab = sqlite3_malloc(sizeof(SessionTable) + nCol + nNew+1); + pTab = sqlite3_malloc64(sizeof(SessionTable) + nCol + nNew+1); if( !pTab ){ rc = SQLITE_NOMEM; break; @@ -198470,12 +199641,8 @@ struct Fts5PhraseIter { ** ** Usually, output parameter *piPhrase is set to the phrase number, *piCol ** to the column in which it occurs and *piOff the token offset of the -** first token of the phrase. The exception is if the table was created -** with the offsets=0 option specified. In this case *piOff is always -** set to -1. -** -** Returns SQLITE_OK if successful, or an error code (i.e. SQLITE_NOMEM) -** if an error occurs. +** first token of the phrase. Returns SQLITE_OK if successful, or an error +** code (i.e. SQLITE_NOMEM) if an error occurs. ** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. @@ -198764,11 +199931,11 @@ struct Fts5ExtensionApi { ** the tokenizer substitutes "first" for "1st" and the query works ** as expected. ** -** <li> By adding multiple synonyms for a single term to the FTS index. -** In this case, when tokenizing query text, the tokenizer may -** provide multiple synonyms for a single term within the document. -** FTS5 then queries the index for each synonym individually. For -** example, faced with the query: +** <li> By querying the index for all synonyms of each query term +** separately. In this case, when tokenizing query text, the +** tokenizer may provide multiple synonyms for a single term +** within the document. FTS5 then queries the index for each +** synonym individually. For example, faced with the query: ** ** <codeblock> ** ... MATCH 'first place'</codeblock> @@ -198792,7 +199959,7 @@ struct Fts5ExtensionApi { ** "place". ** ** This way, even if the tokenizer does not provide synonyms -** when tokenizing query text (it should not - to do would be +** when tokenizing query text (it should not - to do so would be ** inefficient), it doesn't matter if the user queries for ** 'first + place' or '1st + place', as there are entries in the ** FTS index corresponding to both forms of the first token. @@ -199017,6 +200184,12 @@ SQLITE_API extern int sqlite3_fts5_may_be_corrupt; # define assert_nc(x) assert(x) #endif +/* +** A version of memcmp() that does not cause asan errors if one of the pointer +** parameters is NULL and the number of bytes to compare is zero. +*/ +#define fts5Memcmp(s1, s2, n) ((n)==0 ? 0 : memcmp((s1), (s2), (n))) + /* Mark a function parameter as unused, to suppress nuisance compiler ** warnings. */ #ifndef UNUSED_PARAM @@ -199204,7 +200377,7 @@ static void sqlite3Fts5Put32(u8*, int); static int sqlite3Fts5Get32(const u8*); #define FTS5_POS2COLUMN(iPos) (int)(iPos >> 32) -#define FTS5_POS2OFFSET(iPos) (int)(iPos & 0xFFFFFFFF) +#define FTS5_POS2OFFSET(iPos) (int)(iPos & 0x7FFFFFFF) typedef struct Fts5PoslistReader Fts5PoslistReader; struct Fts5PoslistReader { @@ -199239,7 +200412,7 @@ static int sqlite3Fts5PoslistNext64( ); /* Malloc utility */ -static void *sqlite3Fts5MallocZero(int *pRc, int nByte); +static void *sqlite3Fts5MallocZero(int *pRc, sqlite3_int64 nByte); static char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn); /* Character set tests (like isspace(), isalpha() etc.) */ @@ -199450,9 +200623,19 @@ static int sqlite3Fts5PutVarint(unsigned char *p, u64 v); /************************************************************************** -** Interface to code in fts5.c. +** Interface to code in fts5_main.c. */ +/* +** Virtual-table object. +*/ +typedef struct Fts5Table Fts5Table; +struct Fts5Table { + sqlite3_vtab base; /* Base class used by SQLite core */ + Fts5Config *pConfig; /* Virtual table configuration */ + Fts5Index *pIndex; /* Full-text index */ +}; + static int sqlite3Fts5GetTokenizer( Fts5Global*, const char **azArg, @@ -199462,7 +200645,9 @@ static int sqlite3Fts5GetTokenizer( char **pzErr ); -static Fts5Index *sqlite3Fts5IndexFromCsrid(Fts5Global*, i64, Fts5Config **); +static Fts5Table *sqlite3Fts5TableFromCsrid(Fts5Global*, i64); + +static int sqlite3Fts5FlushToDisk(Fts5Table*); /* ** End of interface to code in fts5.c. @@ -199718,7 +200903,7 @@ static int sqlite3Fts5UnicodeIsdiacritic(int c); static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic); static int sqlite3Fts5UnicodeCatParse(const char*, u8*); -static int sqlite3Fts5UnicodeCategory(int iCode); +static int sqlite3Fts5UnicodeCategory(u32 iCode); static void sqlite3Fts5UnicodeAscii(u8*, u8*); /* ** End of interface to code in fts5_unicode2.c. @@ -200622,41 +201807,70 @@ static void fts5yy_shift( fts5yyTraceShift(fts5yypParser, fts5yyNewState, "Shift"); } -/* The following table contains information about every rule that -** is used during the reduce. -*/ -static const struct { - fts5YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ - signed char nrhs; /* Negative of the number of RHS symbols in the rule */ -} fts5yyRuleInfo[] = { - { 16, -1 }, /* (0) input ::= expr */ - { 20, -4 }, /* (1) colset ::= MINUS LCP colsetlist RCP */ - { 20, -3 }, /* (2) colset ::= LCP colsetlist RCP */ - { 20, -1 }, /* (3) colset ::= STRING */ - { 20, -2 }, /* (4) colset ::= MINUS STRING */ - { 21, -2 }, /* (5) colsetlist ::= colsetlist STRING */ - { 21, -1 }, /* (6) colsetlist ::= STRING */ - { 17, -3 }, /* (7) expr ::= expr AND expr */ - { 17, -3 }, /* (8) expr ::= expr OR expr */ - { 17, -3 }, /* (9) expr ::= expr NOT expr */ - { 17, -5 }, /* (10) expr ::= colset COLON LP expr RP */ - { 17, -3 }, /* (11) expr ::= LP expr RP */ - { 17, -1 }, /* (12) expr ::= exprlist */ - { 19, -1 }, /* (13) exprlist ::= cnearset */ - { 19, -2 }, /* (14) exprlist ::= exprlist cnearset */ - { 18, -1 }, /* (15) cnearset ::= nearset */ - { 18, -3 }, /* (16) cnearset ::= colset COLON nearset */ - { 22, -1 }, /* (17) nearset ::= phrase */ - { 22, -2 }, /* (18) nearset ::= CARET phrase */ - { 22, -5 }, /* (19) nearset ::= STRING LP nearphrases neardist_opt RP */ - { 23, -1 }, /* (20) nearphrases ::= phrase */ - { 23, -2 }, /* (21) nearphrases ::= nearphrases phrase */ - { 25, 0 }, /* (22) neardist_opt ::= */ - { 25, -2 }, /* (23) neardist_opt ::= COMMA STRING */ - { 24, -4 }, /* (24) phrase ::= phrase PLUS STRING star_opt */ - { 24, -2 }, /* (25) phrase ::= STRING star_opt */ - { 26, -1 }, /* (26) star_opt ::= STAR */ - { 26, 0 }, /* (27) star_opt ::= */ +/* For rule J, fts5yyRuleInfoLhs[J] contains the symbol on the left-hand side +** of that rule */ +static const fts5YYCODETYPE fts5yyRuleInfoLhs[] = { + 16, /* (0) input ::= expr */ + 20, /* (1) colset ::= MINUS LCP colsetlist RCP */ + 20, /* (2) colset ::= LCP colsetlist RCP */ + 20, /* (3) colset ::= STRING */ + 20, /* (4) colset ::= MINUS STRING */ + 21, /* (5) colsetlist ::= colsetlist STRING */ + 21, /* (6) colsetlist ::= STRING */ + 17, /* (7) expr ::= expr AND expr */ + 17, /* (8) expr ::= expr OR expr */ + 17, /* (9) expr ::= expr NOT expr */ + 17, /* (10) expr ::= colset COLON LP expr RP */ + 17, /* (11) expr ::= LP expr RP */ + 17, /* (12) expr ::= exprlist */ + 19, /* (13) exprlist ::= cnearset */ + 19, /* (14) exprlist ::= exprlist cnearset */ + 18, /* (15) cnearset ::= nearset */ + 18, /* (16) cnearset ::= colset COLON nearset */ + 22, /* (17) nearset ::= phrase */ + 22, /* (18) nearset ::= CARET phrase */ + 22, /* (19) nearset ::= STRING LP nearphrases neardist_opt RP */ + 23, /* (20) nearphrases ::= phrase */ + 23, /* (21) nearphrases ::= nearphrases phrase */ + 25, /* (22) neardist_opt ::= */ + 25, /* (23) neardist_opt ::= COMMA STRING */ + 24, /* (24) phrase ::= phrase PLUS STRING star_opt */ + 24, /* (25) phrase ::= STRING star_opt */ + 26, /* (26) star_opt ::= STAR */ + 26, /* (27) star_opt ::= */ +}; + +/* For rule J, fts5yyRuleInfoNRhs[J] contains the negative of the number +** of symbols on the right-hand side of that rule. */ +static const signed char fts5yyRuleInfoNRhs[] = { + -1, /* (0) input ::= expr */ + -4, /* (1) colset ::= MINUS LCP colsetlist RCP */ + -3, /* (2) colset ::= LCP colsetlist RCP */ + -1, /* (3) colset ::= STRING */ + -2, /* (4) colset ::= MINUS STRING */ + -2, /* (5) colsetlist ::= colsetlist STRING */ + -1, /* (6) colsetlist ::= STRING */ + -3, /* (7) expr ::= expr AND expr */ + -3, /* (8) expr ::= expr OR expr */ + -3, /* (9) expr ::= expr NOT expr */ + -5, /* (10) expr ::= colset COLON LP expr RP */ + -3, /* (11) expr ::= LP expr RP */ + -1, /* (12) expr ::= exprlist */ + -1, /* (13) exprlist ::= cnearset */ + -2, /* (14) exprlist ::= exprlist cnearset */ + -1, /* (15) cnearset ::= nearset */ + -3, /* (16) cnearset ::= colset COLON nearset */ + -1, /* (17) nearset ::= phrase */ + -2, /* (18) nearset ::= CARET phrase */ + -5, /* (19) nearset ::= STRING LP nearphrases neardist_opt RP */ + -1, /* (20) nearphrases ::= phrase */ + -2, /* (21) nearphrases ::= nearphrases phrase */ + 0, /* (22) neardist_opt ::= */ + -2, /* (23) neardist_opt ::= COMMA STRING */ + -4, /* (24) phrase ::= phrase PLUS STRING star_opt */ + -2, /* (25) phrase ::= STRING star_opt */ + -1, /* (26) star_opt ::= STAR */ + 0, /* (27) star_opt ::= */ }; static void fts5yy_accept(fts5yyParser*); /* Forward Declaration */ @@ -200688,7 +201902,7 @@ static fts5YYACTIONTYPE fts5yy_reduce( fts5yymsp = fts5yypParser->fts5yytos; #ifndef NDEBUG if( fts5yyTraceFILE && fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) ){ - fts5yysize = fts5yyRuleInfo[fts5yyruleno].nrhs; + fts5yysize = fts5yyRuleInfoNRhs[fts5yyruleno]; if( fts5yysize ){ fprintf(fts5yyTraceFILE, "%sReduce %d [%s], go to state %d.\n", fts5yyTracePrompt, @@ -200703,7 +201917,7 @@ static fts5YYACTIONTYPE fts5yy_reduce( /* Check that the stack is large enough to grow by a single entry ** if the RHS of the rule is empty. This ensures that there is room ** enough on the stack to push the LHS value */ - if( fts5yyRuleInfo[fts5yyruleno].nrhs==0 ){ + if( fts5yyRuleInfoNRhs[fts5yyruleno]==0 ){ #ifdef fts5YYTRACKMAXSTACKDEPTH if( (int)(fts5yypParser->fts5yytos - fts5yypParser->fts5yystack)>fts5yypParser->fts5yyhwm ){ fts5yypParser->fts5yyhwm++; @@ -200887,9 +202101,9 @@ static fts5YYACTIONTYPE fts5yy_reduce( break; /********** End reduce actions ************************************************/ }; - assert( fts5yyruleno<sizeof(fts5yyRuleInfo)/sizeof(fts5yyRuleInfo[0]) ); - fts5yygoto = fts5yyRuleInfo[fts5yyruleno].lhs; - fts5yysize = fts5yyRuleInfo[fts5yyruleno].nrhs; + assert( fts5yyruleno<sizeof(fts5yyRuleInfoLhs)/sizeof(fts5yyRuleInfoLhs[0]) ); + fts5yygoto = fts5yyRuleInfoLhs[fts5yyruleno]; + fts5yysize = fts5yyRuleInfoNRhs[fts5yyruleno]; fts5yyact = fts5yy_find_reduce_action(fts5yymsp[fts5yysize].stateno,(fts5YYCODETYPE)fts5yygoto); /* There are no SHIFTREDUCE actions on nonterminals because the table @@ -201320,7 +202534,7 @@ static void fts5HighlightAppend( HighlightContext *p, const char *z, int n ){ - if( *pRc==SQLITE_OK ){ + if( *pRc==SQLITE_OK && z ){ if( n<0 ) n = (int)strlen(z); p->zOut = sqlite3_mprintf("%z%.*s", p->zOut, n, z); if( p->zOut==0 ) *pRc = SQLITE_NOMEM; @@ -201452,7 +202666,7 @@ static int fts5SentenceFinderAdd(Fts5SFinder *p, int iAdd){ int nNew = p->nFirstAlloc ? p->nFirstAlloc*2 : 64; int *aNew; - aNew = (int*)sqlite3_realloc(p->aFirst, nNew*sizeof(int)); + aNew = (int*)sqlite3_realloc64(p->aFirst, nNew*sizeof(int)); if( aNew==0 ) return SQLITE_NOMEM; p->aFirst = aNew; p->nFirstAlloc = nNew; @@ -201519,11 +202733,12 @@ static int fts5SnippetScore( int nInst; int nScore = 0; int iLast = 0; + sqlite3_int64 iEnd = (sqlite3_int64)iPos + nToken; rc = pApi->xInstCount(pFts, &nInst); for(i=0; i<nInst && rc==SQLITE_OK; i++){ rc = pApi->xInst(pFts, i, &ip, &ic, &iOff); - if( rc==SQLITE_OK && ic==iCol && iOff>=iPos && iOff<(iPos+nToken) ){ + if( rc==SQLITE_OK && ic==iCol && iOff>=iPos && iOff<iEnd ){ nScore += (aSeen[ip] ? 1 : 1000); aSeen[ip] = 1; if( iFirst<0 ) iFirst = iOff; @@ -201533,7 +202748,7 @@ static int fts5SnippetScore( *pnScore = nScore; if( piPos ){ - int iAdj = iFirst - (nToken - (iLast-iFirst)) / 2; + sqlite3_int64 iAdj = iFirst - (nToken - (iLast-iFirst)) / 2; if( (iAdj+nToken)>nDocsize ) iAdj = nDocsize - nToken; if( iAdj<0 ) iAdj = 0; *piPos = iAdj; @@ -201626,7 +202841,9 @@ static void fts5SnippetFunction( int jj; rc = pApi->xInst(pFts, ii, &ip, &ic, &io); - if( ic!=i || rc!=SQLITE_OK ) continue; + if( ic!=i ) continue; + if( io>nDocsize ) rc = FTS5_CORRUPT; + if( rc!=SQLITE_OK ) continue; memset(aSeen, 0, nPhrase); rc = fts5SnippetScore(pApi, pFts, nDocsize, aSeen, i, io, nToken, &nScore, &iAdj @@ -201752,13 +202969,13 @@ static int fts5Bm25GetData( int nPhrase; /* Number of phrases in query */ sqlite3_int64 nRow = 0; /* Number of rows in table */ sqlite3_int64 nToken = 0; /* Number of tokens in table */ - int nByte; /* Bytes of space to allocate */ + sqlite3_int64 nByte; /* Bytes of space to allocate */ int i; /* Allocate the Fts5Bm25Data object */ nPhrase = pApi->xPhraseCount(pFts); nByte = sizeof(Fts5Bm25Data) + nPhrase*2*sizeof(double); - p = (Fts5Bm25Data*)sqlite3_malloc(nByte); + p = (Fts5Bm25Data*)sqlite3_malloc64(nByte); if( p==0 ){ rc = SQLITE_NOMEM; }else{ @@ -201770,6 +202987,7 @@ static int fts5Bm25GetData( /* Calculate the average document length for this FTS5 table */ if( rc==SQLITE_OK ) rc = pApi->xRowCount(pFts, &nRow); + assert( rc!=SQLITE_OK || nRow>0 ); if( rc==SQLITE_OK ) rc = pApi->xColumnTotalSize(pFts, -1, &nToken); if( rc==SQLITE_OK ) p->avgdl = (double)nToken / (double)nRow; @@ -201895,8 +203113,6 @@ static int sqlite3Fts5AuxInit(fts5_api *pApi){ return rc; } - - /* ** 2014 May 31 ** @@ -201916,12 +203132,12 @@ static int sqlite3Fts5AuxInit(fts5_api *pApi){ static int sqlite3Fts5BufferSize(int *pRc, Fts5Buffer *pBuf, u32 nByte){ if( (u32)pBuf->nSpace<nByte ){ - u32 nNew = pBuf->nSpace ? pBuf->nSpace : 64; + u64 nNew = pBuf->nSpace ? pBuf->nSpace : 64; u8 *pNew; while( nNew<nByte ){ nNew = nNew * 2; } - pNew = sqlite3_realloc(pBuf->p, nNew); + pNew = sqlite3_realloc64(pBuf->p, nNew); if( pNew==0 ){ *pRc = SQLITE_NOMEM; return 1; @@ -201951,7 +203167,7 @@ static void sqlite3Fts5Put32(u8 *aBuf, int iVal){ } static int sqlite3Fts5Get32(const u8 *aBuf){ - return (aBuf[0] << 24) + (aBuf[1] << 16) + (aBuf[2] << 8) + aBuf[3]; + return (int)((((u32)aBuf[0])<<24) + (aBuf[1]<<16) + (aBuf[2]<<8) + aBuf[3]); } /* @@ -202082,7 +203298,7 @@ static int sqlite3Fts5PoslistNext64( iOff = ((i64)iVal) << 32; fts5FastGetVarint32(a, i, iVal); } - *piOff = iOff + (iVal-2); + *piOff = iOff + ((iVal-2) & 0x7FFFFFFF); *pi = i; return 0; } @@ -202143,10 +203359,10 @@ static int sqlite3Fts5PoslistWriterAppend( return SQLITE_OK; } -static void *sqlite3Fts5MallocZero(int *pRc, int nByte){ +static void *sqlite3Fts5MallocZero(int *pRc, sqlite3_int64 nByte){ void *pRet = 0; if( *pRc==SQLITE_OK ){ - pRet = sqlite3_malloc(nByte); + pRet = sqlite3_malloc64(nByte); if( pRet==0 ){ if( nByte>0 ) *pRc = SQLITE_NOMEM; }else{ @@ -202589,7 +203805,7 @@ static int fts5ConfigParseSpecial( if( sqlite3_strnicmp("tokenize", zCmd, nCmd)==0 ){ const char *p = (const char*)zArg; - int nArg = (int)strlen(zArg) + 1; + sqlite3_int64 nArg = strlen(zArg) + 1; char **azArg = sqlite3Fts5MallocZero(&rc, sizeof(char*) * nArg); char *pDel = sqlite3Fts5MallocZero(&rc, nArg * 2); char *pSpace = pDel; @@ -202719,8 +203935,8 @@ static const char *fts5ConfigGobbleWord( ){ const char *zRet = 0; - int nIn = (int)strlen(zIn); - char *zOut = sqlite3_malloc(nIn+1); + sqlite3_int64 nIn = strlen(zIn); + char *zOut = sqlite3_malloc64(nIn+1); assert( *pRc==SQLITE_OK ); *pbQuoted = 0; @@ -202823,7 +204039,7 @@ static int sqlite3Fts5ConfigParse( int rc = SQLITE_OK; /* Return code */ Fts5Config *pRet; /* New object to return */ int i; - int nByte; + sqlite3_int64 nByte; *ppOut = pRet = (Fts5Config*)sqlite3_malloc(sizeof(Fts5Config)); if( pRet==0 ) return SQLITE_NOMEM; @@ -203467,7 +204683,7 @@ static int fts5ExprGetToken( return tok; } -static void *fts5ParseAlloc(u64 t){ return sqlite3_malloc((int)t); } +static void *fts5ParseAlloc(u64 t){ return sqlite3_malloc64((sqlite3_int64)t);} static void fts5ParseFree(void *p){ sqlite3_free(p); } static int sqlite3Fts5ExprNew( @@ -203612,8 +204828,8 @@ static int fts5ExprSynonymList( if( sqlite3Fts5IterEof(pIter)==0 && pIter->iRowid==iRowid ){ if( pIter->nData==0 ) continue; if( nIter==nAlloc ){ - int nByte = sizeof(Fts5PoslistReader) * nAlloc * 2; - Fts5PoslistReader *aNew = (Fts5PoslistReader*)sqlite3_malloc(nByte); + sqlite3_int64 nByte = sizeof(Fts5PoslistReader) * nAlloc * 2; + Fts5PoslistReader *aNew = (Fts5PoslistReader*)sqlite3_malloc64(nByte); if( aNew==0 ){ rc = SQLITE_NOMEM; goto synonym_poslist_out; @@ -203693,8 +204909,8 @@ static int fts5ExprPhraseIsMatch( /* If the aStatic[] array is not large enough, allocate a large array ** using sqlite3_malloc(). This approach could be improved upon. */ if( pPhrase->nTerm>ArraySize(aStatic) ){ - int nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm; - aIter = (Fts5PoslistReader*)sqlite3_malloc(nByte); + sqlite3_int64 nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm; + aIter = (Fts5PoslistReader*)sqlite3_malloc64(nByte); if( !aIter ) return SQLITE_NOMEM; } memset(aIter, 0, sizeof(Fts5PoslistReader) * pPhrase->nTerm); @@ -203828,7 +205044,7 @@ static int fts5ExprNearIsMatch(int *pRc, Fts5ExprNearset *pNear){ /* If the aStatic[] array is not large enough, allocate a large array ** using sqlite3_malloc(). This approach could be improved upon. */ if( pNear->nPhrase>ArraySize(aStatic) ){ - int nByte = sizeof(Fts5NearTrimmer) * pNear->nPhrase; + sqlite3_int64 nByte = sizeof(Fts5NearTrimmer) * pNear->nPhrase; a = (Fts5NearTrimmer*)sqlite3Fts5MallocZero(&rc, nByte); }else{ memset(aStatic, 0, sizeof(aStatic)); @@ -204737,8 +205953,9 @@ static Fts5ExprNearset *sqlite3Fts5ParseNearset( return pNear; } if( pNear==0 ){ - int nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*); - pRet = sqlite3_malloc(nByte); + sqlite3_int64 nByte; + nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*); + pRet = sqlite3_malloc64(nByte); if( pRet==0 ){ pParse->rc = SQLITE_NOMEM; }else{ @@ -204746,9 +205963,10 @@ static Fts5ExprNearset *sqlite3Fts5ParseNearset( } }else if( (pNear->nPhrase % SZALLOC)==0 ){ int nNew = pNear->nPhrase + SZALLOC; - int nByte = sizeof(Fts5ExprNearset) + nNew * sizeof(Fts5ExprPhrase*); + sqlite3_int64 nByte; - pRet = (Fts5ExprNearset*)sqlite3_realloc(pNear, nByte); + nByte = sizeof(Fts5ExprNearset) + nNew * sizeof(Fts5ExprPhrase*); + pRet = (Fts5ExprNearset*)sqlite3_realloc64(pNear, nByte); if( pRet==0 ){ pParse->rc = SQLITE_NOMEM; } @@ -204812,8 +206030,8 @@ static int fts5ParseTokenize( if( pPhrase && pPhrase->nTerm>0 && (tflags & FTS5_TOKEN_COLOCATED) ){ Fts5ExprTerm *pSyn; - int nByte = sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer) + nToken+1; - pSyn = (Fts5ExprTerm*)sqlite3_malloc(nByte); + sqlite3_int64 nByte = sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer) + nToken+1; + pSyn = (Fts5ExprTerm*)sqlite3_malloc64(nByte); if( pSyn==0 ){ rc = SQLITE_NOMEM; }else{ @@ -204829,7 +206047,7 @@ static int fts5ParseTokenize( Fts5ExprPhrase *pNew; int nNew = SZALLOC + (pPhrase ? pPhrase->nTerm : 0); - pNew = (Fts5ExprPhrase*)sqlite3_realloc(pPhrase, + pNew = (Fts5ExprPhrase*)sqlite3_realloc64(pPhrase, sizeof(Fts5ExprPhrase) + sizeof(Fts5ExprTerm) * nNew ); if( pNew==0 ){ @@ -204915,9 +206133,9 @@ static Fts5ExprPhrase *sqlite3Fts5ParseTerm( if( pAppend==0 ){ if( (pParse->nPhrase % 8)==0 ){ - int nByte = sizeof(Fts5ExprPhrase*) * (pParse->nPhrase + 8); + sqlite3_int64 nByte = sizeof(Fts5ExprPhrase*) * (pParse->nPhrase + 8); Fts5ExprPhrase **apNew; - apNew = (Fts5ExprPhrase**)sqlite3_realloc(pParse->apPhrase, nByte); + apNew = (Fts5ExprPhrase**)sqlite3_realloc64(pParse->apPhrase, nByte); if( apNew==0 ){ pParse->rc = SQLITE_NOMEM; fts5ExprPhraseFree(sCtx.pPhrase); @@ -204972,8 +206190,10 @@ static int sqlite3Fts5ExprClonePhrase( if( rc==SQLITE_OK ){ Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset; if( pColsetOrig ){ - int nByte = sizeof(Fts5Colset) + (pColsetOrig->nCol-1) * sizeof(int); - Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&rc, nByte); + sqlite3_int64 nByte; + Fts5Colset *pColset; + nByte = sizeof(Fts5Colset) + (pColsetOrig->nCol-1) * sizeof(int); + pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&rc, nByte); if( pColset ){ memcpy(pColset, pColsetOrig, nByte); } @@ -205093,7 +206313,7 @@ static Fts5Colset *fts5ParseColset( assert( pParse->rc==SQLITE_OK ); assert( iCol>=0 && iCol<pParse->pConfig->nCol ); - pNew = sqlite3_realloc(p, sizeof(Fts5Colset) + sizeof(int)*nCol); + pNew = sqlite3_realloc64(p, sizeof(Fts5Colset) + sizeof(int)*nCol); if( pNew==0 ){ pParse->rc = SQLITE_NOMEM; }else{ @@ -205189,7 +206409,7 @@ static Fts5Colset *sqlite3Fts5ParseColset( static Fts5Colset *fts5CloneColset(int *pRc, Fts5Colset *pOrig){ Fts5Colset *pRet; if( pOrig ){ - int nByte = sizeof(Fts5Colset) + (pOrig->nCol-1) * sizeof(int); + sqlite3_int64 nByte = sizeof(Fts5Colset) + (pOrig->nCol-1) * sizeof(int); pRet = (Fts5Colset*)sqlite3Fts5MallocZero(pRc, nByte); if( pRet ){ memcpy(pRet, pOrig, nByte); @@ -205343,7 +206563,7 @@ static Fts5ExprNode *sqlite3Fts5ParseNode( if( pParse->rc==SQLITE_OK ){ int nChild = 0; /* Number of children of returned node */ - int nByte; /* Bytes of space to allocate for this node */ + sqlite3_int64 nByte; /* Bytes of space to allocate for this node */ assert( (eType!=FTS5_STRING && !pNear) || (eType==FTS5_STRING && !pLeft && !pRight) @@ -205475,7 +206695,7 @@ static Fts5ExprNode *sqlite3Fts5ParseImplicitAnd( } static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){ - int nByte = 0; + sqlite3_int64 nByte = 0; Fts5ExprTerm *p; char *zQuoted; @@ -205483,7 +206703,7 @@ static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){ for(p=pTerm; p; p=p->pSynonym){ nByte += (int)strlen(pTerm->zTerm) * 2 + 3 + 2; } - zQuoted = sqlite3_malloc(nByte); + zQuoted = sqlite3_malloc64(nByte); if( zQuoted ){ int i = 0; @@ -205723,7 +206943,7 @@ static void fts5ExprFunction( } nConfig = 3 + (nArg-iArg); - azConfig = (const char**)sqlite3_malloc(sizeof(char*) * nConfig); + azConfig = (const char**)sqlite3_malloc64(sizeof(char*) * nConfig); if( azConfig==0 ){ sqlite3_result_error_nomem(pCtx); return; @@ -205809,7 +207029,7 @@ static void fts5ExprIsAlnum( sqlite3Fts5UnicodeCatParse("N*", aArr); sqlite3Fts5UnicodeCatParse("Co", aArr); iCode = sqlite3_value_int(apVal[0]); - sqlite3_result_int(pCtx, aArr[sqlite3Fts5UnicodeCategory(iCode)]); + sqlite3_result_int(pCtx, aArr[sqlite3Fts5UnicodeCategory((u32)iCode)]); } static void fts5ExprFold( @@ -205904,7 +207124,7 @@ struct Fts5PoslistPopulator { static Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr *pExpr, int bLive){ Fts5PoslistPopulator *pRet; - pRet = sqlite3_malloc(sizeof(Fts5PoslistPopulator)*pExpr->nPhrase); + pRet = sqlite3_malloc64(sizeof(Fts5PoslistPopulator)*pExpr->nPhrase); if( pRet ){ int i; memset(pRet, 0, sizeof(Fts5PoslistPopulator)*pExpr->nPhrase); @@ -206104,7 +207324,6 @@ static int sqlite3Fts5ExprPhraseCollist( return rc; } - /* ** 2014 August 11 ** @@ -206197,14 +207416,14 @@ static int sqlite3Fts5HashNew(Fts5Config *pConfig, Fts5Hash **ppNew, int *pnByte if( pNew==0 ){ rc = SQLITE_NOMEM; }else{ - int nByte; + sqlite3_int64 nByte; memset(pNew, 0, sizeof(Fts5Hash)); pNew->pnByte = pnByte; pNew->eDetail = pConfig->eDetail; pNew->nSlot = 1024; nByte = sizeof(Fts5HashEntry*) * pNew->nSlot; - pNew->aSlot = (Fts5HashEntry**)sqlite3_malloc(nByte); + pNew->aSlot = (Fts5HashEntry**)sqlite3_malloc64(nByte); if( pNew->aSlot==0 ){ sqlite3_free(pNew); *ppNew = 0; @@ -206272,7 +207491,7 @@ static int fts5HashResize(Fts5Hash *pHash){ Fts5HashEntry **apNew; Fts5HashEntry **apOld = pHash->aSlot; - apNew = (Fts5HashEntry**)sqlite3_malloc(nNew*sizeof(Fts5HashEntry*)); + apNew = (Fts5HashEntry**)sqlite3_malloc64(nNew*sizeof(Fts5HashEntry*)); if( !apNew ) return SQLITE_NOMEM; memset(apNew, 0, nNew*sizeof(Fts5HashEntry*)); @@ -206366,7 +207585,7 @@ static int sqlite3Fts5HashWrite( if( p==0 ){ /* Figure out how much space to allocate */ char *zKey; - int nByte = sizeof(Fts5HashEntry) + (nToken+1) + 1 + 64; + sqlite3_int64 nByte = sizeof(Fts5HashEntry) + (nToken+1) + 1 + 64; if( nByte<128 ) nByte = 128; /* Grow the Fts5Hash.aSlot[] array if necessary. */ @@ -206377,7 +207596,7 @@ static int sqlite3Fts5HashWrite( } /* Allocate new Fts5HashEntry and add it to the hash table. */ - p = (Fts5HashEntry*)sqlite3_malloc(nByte); + p = (Fts5HashEntry*)sqlite3_malloc64(nByte); if( !p ) return SQLITE_NOMEM; memset(p, 0, sizeof(Fts5HashEntry)); p->nAlloc = nByte; @@ -206416,12 +207635,12 @@ static int sqlite3Fts5HashWrite( ** + 5 bytes for the new position offset (32-bit max). */ if( (p->nAlloc - p->nData) < (9 + 4 + 1 + 3 + 5) ){ - int nNew = p->nAlloc * 2; + sqlite3_int64 nNew = p->nAlloc * 2; Fts5HashEntry *pNew; Fts5HashEntry **pp; - pNew = (Fts5HashEntry*)sqlite3_realloc(p, nNew); + pNew = (Fts5HashEntry*)sqlite3_realloc64(p, nNew); if( pNew==0 ) return SQLITE_NOMEM; - pNew->nAlloc = nNew; + pNew->nAlloc = (int)nNew; for(pp=&pHash->aSlot[iHash]; *pp!=p; pp=&(*pp)->pHashNext); *pp = pNew; p = pNew; @@ -206545,7 +207764,7 @@ static int fts5HashEntrySort( int i; *ppSorted = 0; - ap = sqlite3_malloc(sizeof(Fts5HashEntry*) * nMergeSlot); + ap = sqlite3_malloc64(sizeof(Fts5HashEntry*) * nMergeSlot); if( !ap ) return SQLITE_NOMEM; memset(ap, 0, sizeof(Fts5HashEntry*) * nMergeSlot); @@ -206590,7 +207809,8 @@ static int sqlite3Fts5HashQuery( for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){ zKey = fts5EntryKey(p); - if( memcmp(zKey, pTerm, nTerm)==0 && zKey[nTerm]==0 ) break; + assert( p->nKey+1==(int)strlen(zKey) ); + if( nTerm==p->nKey+1 && memcmp(zKey, pTerm, nTerm)==0 ) break; } if( p ){ @@ -206642,7 +207862,6 @@ static void sqlite3Fts5HashScanEntry( } } - /* ** 2014 May 31 ** @@ -207157,7 +208376,6 @@ struct Fts5Iter { Fts5IndexIter base; /* Base class containing output vars */ Fts5Index *pIndex; /* Index that owns this iterator */ - Fts5Structure *pStruct; /* Database structure for this iterator */ Fts5Buffer poslist; /* Buffer containing current poslist */ Fts5Colset *pColset; /* Restrict matches to these columns */ @@ -207218,7 +208436,7 @@ static u16 fts5GetU16(const u8 *aIn){ ** If an OOM error is encountered, return NULL and set the error code in ** the Fts5Index handle passed as the first argument. */ -static void *fts5IdxMalloc(Fts5Index *p, int nByte){ +static void *fts5IdxMalloc(Fts5Index *p, sqlite3_int64 nByte){ return sqlite3Fts5MallocZero(&p->rc, nByte); } @@ -207252,7 +208470,7 @@ static int fts5BufferCompareBlob( */ static int fts5BufferCompare(Fts5Buffer *pLeft, Fts5Buffer *pRight){ int nCmp = MIN(pLeft->n, pRight->n); - int res = memcmp(pLeft->p, pRight->p, nCmp); + int res = fts5Memcmp(pLeft->p, pRight->p, nCmp); return (res==0 ? (pLeft->n - pRight->n) : res); } @@ -207318,8 +208536,8 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){ if( rc==SQLITE_OK ){ u8 *aOut = 0; /* Read blob data into this buffer */ int nByte = sqlite3_blob_bytes(p->pReader); - int nAlloc = sizeof(Fts5Data) + nByte + FTS5_DATA_PADDING; - pRet = (Fts5Data*)sqlite3_malloc(nAlloc); + sqlite3_int64 nAlloc = sizeof(Fts5Data) + nByte + FTS5_DATA_PADDING; + pRet = (Fts5Data*)sqlite3_malloc64(nAlloc); if( pRet ){ pRet->nn = nByte; aOut = pRet->p = (u8*)&pRet[1]; @@ -207335,6 +208553,7 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){ pRet = 0; }else{ /* TODO1: Fix this */ + pRet->p[nByte] = 0x00; pRet->szLeaf = fts5GetU16(&pRet->p[2]); } } @@ -207374,7 +208593,8 @@ static int fts5IndexPrepareStmt( if( p->rc==SQLITE_OK ){ if( zSql ){ p->rc = sqlite3_prepare_v3(p->pConfig->db, zSql, -1, - SQLITE_PREPARE_PERSISTENT, ppStmt, 0); + SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB, + ppStmt, 0); }else{ p->rc = SQLITE_NOMEM; } @@ -207415,23 +208635,12 @@ static void fts5DataDelete(Fts5Index *p, i64 iFirst, i64 iLast){ if( p->rc!=SQLITE_OK ) return; if( p->pDeleter==0 ){ - int rc; Fts5Config *pConfig = p->pConfig; char *zSql = sqlite3_mprintf( "DELETE FROM '%q'.'%q_data' WHERE id>=? AND id<=?", pConfig->zDb, pConfig->zName ); - if( zSql==0 ){ - rc = SQLITE_NOMEM; - }else{ - rc = sqlite3_prepare_v3(pConfig->db, zSql, -1, - SQLITE_PREPARE_PERSISTENT, &p->pDeleter, 0); - sqlite3_free(zSql); - } - if( rc!=SQLITE_OK ){ - p->rc = rc; - return; - } + if( fts5IndexPrepareStmt(p, &p->pDeleter, zSql) ) return; } sqlite3_bind_int64(p->pDeleter, 1, iFirst); @@ -207503,7 +208712,7 @@ static int fts5StructureDecode( int iLvl; int nLevel = 0; int nSegment = 0; - int nByte; /* Bytes of space to allocate at pRet */ + sqlite3_int64 nByte; /* Bytes of space to allocate at pRet */ Fts5Structure *pRet = 0; /* Structure object to return */ /* Grab the cookie value */ @@ -207514,6 +208723,11 @@ static int fts5StructureDecode( ** structure record. */ i += fts5GetVarint32(&pData[i], nLevel); i += fts5GetVarint32(&pData[i], nSegment); + if( nLevel>FTS5_MAX_SEGMENT || nLevel<0 + || nSegment>FTS5_MAX_SEGMENT || nSegment<0 + ){ + return FTS5_CORRUPT; + } nByte = ( sizeof(Fts5Structure) + /* Main structure */ sizeof(Fts5StructureLevel) * (nLevel-1) /* aLevel[] array */ @@ -207536,25 +208750,35 @@ static int fts5StructureDecode( }else{ i += fts5GetVarint32(&pData[i], pLvl->nMerge); i += fts5GetVarint32(&pData[i], nTotal); - assert( nTotal>=pLvl->nMerge ); + if( nTotal<pLvl->nMerge ) rc = FTS5_CORRUPT; pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&rc, nTotal * sizeof(Fts5StructureSegment) ); + nSegment -= nTotal; } if( rc==SQLITE_OK ){ pLvl->nSeg = nTotal; for(iSeg=0; iSeg<nTotal; iSeg++){ + Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg]; if( i>=nData ){ rc = FTS5_CORRUPT; break; } - i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].iSegid); - i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].pgnoFirst); - i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].pgnoLast); + i += fts5GetVarint32(&pData[i], pSeg->iSegid); + i += fts5GetVarint32(&pData[i], pSeg->pgnoFirst); + i += fts5GetVarint32(&pData[i], pSeg->pgnoLast); + if( pSeg->pgnoLast<pSeg->pgnoFirst ){ + rc = FTS5_CORRUPT; + break; + } } + if( iLvl>0 && pLvl[-1].nMerge && nTotal==0 ) rc = FTS5_CORRUPT; + if( iLvl==nLevel-1 && pLvl->nMerge ) rc = FTS5_CORRUPT; } } + if( nSegment!=0 && rc==SQLITE_OK ) rc = FTS5_CORRUPT; + if( rc!=SQLITE_OK ){ fts5StructureRelease(pRet); pRet = 0; @@ -207572,12 +208796,12 @@ static void fts5StructureAddLevel(int *pRc, Fts5Structure **ppStruct){ if( *pRc==SQLITE_OK ){ Fts5Structure *pStruct = *ppStruct; int nLevel = pStruct->nLevel; - int nByte = ( + sqlite3_int64 nByte = ( sizeof(Fts5Structure) + /* Main structure */ sizeof(Fts5StructureLevel) * (nLevel+1) /* aLevel[] array */ ); - pStruct = sqlite3_realloc(pStruct, nByte); + pStruct = sqlite3_realloc64(pStruct, nByte); if( pStruct ){ memset(&pStruct->aLevel[nLevel], 0, sizeof(Fts5StructureLevel)); pStruct->nLevel++; @@ -207602,10 +208826,10 @@ static void fts5StructureExtendLevel( if( *pRc==SQLITE_OK ){ Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl]; Fts5StructureSegment *aNew; - int nByte; + sqlite3_int64 nByte; nByte = (pLvl->nSeg + nExtra) * sizeof(Fts5StructureSegment); - aNew = sqlite3_realloc(pLvl->aSeg, nByte); + aNew = sqlite3_realloc64(pLvl->aSeg, nByte); if( aNew ){ if( bInsert==0 ){ memset(&aNew[pLvl->nSeg], 0, sizeof(Fts5StructureSegment) * nExtra); @@ -208119,10 +209343,10 @@ static Fts5DlidxIter *fts5DlidxIterInit( int bDone = 0; for(i=0; p->rc==SQLITE_OK && bDone==0; i++){ - int nByte = sizeof(Fts5DlidxIter) + i * sizeof(Fts5DlidxLvl); + sqlite3_int64 nByte = sizeof(Fts5DlidxIter) + i * sizeof(Fts5DlidxLvl); Fts5DlidxIter *pNew; - pNew = (Fts5DlidxIter*)sqlite3_realloc(pIter, nByte); + pNew = (Fts5DlidxIter*)sqlite3_realloc64(pIter, nByte); if( pNew==0 ){ p->rc = SQLITE_NOMEM; }else{ @@ -208292,12 +209516,13 @@ static void fts5SegIterLoadTerm(Fts5Index *p, Fts5SegIter *pIter, int nKeep){ int nNew; /* Bytes of new data */ iOff += fts5GetVarint32(&a[iOff], nNew); - if( iOff+nNew>pIter->pLeaf->nn ){ + if( iOff+nNew>pIter->pLeaf->szLeaf || nKeep>pIter->term.n || nNew==0 ){ p->rc = FTS5_CORRUPT; return; } pIter->term.n = nKeep; fts5BufferAppendBlob(&p->rc, &pIter->term, nNew, &a[iOff]); + assert( pIter->term.n<=pIter->term.nSpace ); iOff += nNew; pIter->iTermLeafOffset = iOff; pIter->iTermLeafPgno = pIter->iLeafPgno; @@ -208362,7 +209587,7 @@ static void fts5SegIterInit( if( p->rc==SQLITE_OK ){ pIter->iLeafOffset = 4; assert_nc( pIter->pLeaf->nn>4 ); - assert( fts5LeafFirstTermOff(pIter->pLeaf)==4 ); + assert_nc( fts5LeafFirstTermOff(pIter->pLeaf)==4 ); pIter->iPgidxOff = pIter->pLeaf->szLeaf+1; fts5SegIterLoadTerm(p, pIter, 0); fts5SegIterLoadNPos(p, pIter); @@ -208418,7 +209643,7 @@ static void fts5SegIterReverseInitPage(Fts5Index *p, Fts5SegIter *pIter){ /* If necessary, grow the pIter->aRowidOffset[] array. */ if( iRowidOffset>=pIter->nRowidOffset ){ int nNew = pIter->nRowidOffset + 8; - int *aNew = (int*)sqlite3_realloc(pIter->aRowidOffset, nNew*sizeof(int)); + int *aNew = (int*)sqlite3_realloc64(pIter->aRowidOffset,nNew*sizeof(int)); if( aNew==0 ){ p->rc = SQLITE_NOMEM; break; @@ -208872,10 +210097,10 @@ static void fts5LeafSeek( int szLeaf = pIter->pLeaf->szLeaf; int n = pIter->pLeaf->nn; - int nMatch = 0; - int nKeep = 0; - int nNew = 0; - int iTermOff; + u32 nMatch = 0; + u32 nKeep = 0; + u32 nNew = 0; + u32 iTermOff; int iPgidx; /* Current offset in pgidx */ int bEndOfPage = 0; @@ -208899,15 +210124,15 @@ static void fts5LeafSeek( assert( nKeep>=nMatch ); if( nKeep==nMatch ){ - int nCmp; - int i; - nCmp = MIN(nNew, nTerm-nMatch); + u32 nCmp; + u32 i; + nCmp = (u32)MIN(nNew, nTerm-nMatch); for(i=0; i<nCmp; i++){ if( a[iOff+i]!=pTerm[nMatch+i] ) break; } nMatch += i; - if( nTerm==nMatch ){ + if( (u32)nTerm==nMatch ){ if( i==nNew ){ goto search_success; }else{ @@ -208951,6 +210176,7 @@ static void fts5LeafSeek( iPgidx += fts5GetVarint32(&pIter->pLeaf->p[iPgidx], iOff); if( iOff<4 || iOff>=pIter->pLeaf->szLeaf ){ p->rc = FTS5_CORRUPT; + return; }else{ nKeep = 0; iTermOff = iOff; @@ -208963,8 +210189,11 @@ static void fts5LeafSeek( } search_success: - pIter->iLeafOffset = iOff + nNew; + if( pIter->iLeafOffset>n || nNew<1 ){ + p->rc = FTS5_CORRUPT; + return; + } pIter->iTermLeafOffset = pIter->iLeafOffset; pIter->iTermLeafPgno = pIter->iLeafPgno; @@ -209071,7 +210300,7 @@ static void fts5SegIterSeekInit( ** 4) the FTS5INDEX_QUERY_SCAN flag was set and the iterator points ** to an entry with a term greater than or equal to (pTerm/nTerm). */ - assert( p->rc!=SQLITE_OK /* 1 */ + assert_nc( p->rc!=SQLITE_OK /* 1 */ || pIter->pLeaf==0 /* 2 */ || fts5BufferCompareBlob(&pIter->term, pTerm, nTerm)==0 /* 3 */ || (bGe && fts5BufferCompareBlob(&pIter->term, pTerm, nTerm)>0) /* 4 */ @@ -209169,7 +210398,7 @@ static void fts5AssertComparisonResult( assert( pRes->iFirst==i1 ); }else{ int nMin = MIN(p1->term.n, p2->term.n); - int res = memcmp(p1->term.p, p2->term.p, nMin); + int res = fts5Memcmp(p1->term.p, p2->term.p, nMin); if( res==0 ) res = p1->term.n - p2->term.n; if( res==0 ){ @@ -209392,7 +210621,6 @@ static void fts5MultiIterFree(Fts5Iter *pIter){ for(i=0; i<pIter->nSeg; i++){ fts5SegIterClear(&pIter->aSeg[i]); } - fts5StructureRelease(pIter->pStruct); fts5BufferFree(&pIter->poslist); sqlite3_free(pIter); } @@ -209740,7 +210968,8 @@ static void fts5SegiterPoslist( Fts5Colset *pColset, Fts5Buffer *pBuf ){ - if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos) ){ + if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos+FTS5_DATA_ZERO_PADDING) ){ + memset(&pBuf->p[pBuf->n+pSeg->nPos], 0, FTS5_DATA_ZERO_PADDING); if( pColset==0 ){ fts5ChunkIterate(p, pSeg, (void*)pBuf, fts5PoslistCallback); }else{ @@ -210038,9 +211267,7 @@ static void fts5MultiIterNew( if( pNew==0 ) return; pNew->bRev = (0!=(flags & FTS5INDEX_QUERY_DESC)); pNew->bSkipEmpty = (0!=(flags & FTS5INDEX_QUERY_SKIPEMPTY)); - pNew->pStruct = pStruct; pNew->pColset = pColset; - fts5StructureRef(pStruct); if( (flags & FTS5INDEX_QUERY_NOOUTPUT)==0 ){ fts5IterSetOutputCb(&p->rc, pNew); } @@ -210218,24 +211445,24 @@ static int fts5AllocateSegid(Fts5Index *p, Fts5Structure *pStruct){ for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){ for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){ int iId = pStruct->aLevel[iLvl].aSeg[iSeg].iSegid; - if( iId<=FTS5_MAX_SEGMENT ){ - aUsed[(iId-1) / 32] |= 1 << ((iId-1) % 32); + if( iId<=FTS5_MAX_SEGMENT && iId>0 ){ + aUsed[(iId-1) / 32] |= (u32)1 << ((iId-1) % 32); } } } for(i=0; aUsed[i]==0xFFFFFFFF; i++); mask = aUsed[i]; - for(iSegid=0; mask & (1 << iSegid); iSegid++); + for(iSegid=0; mask & ((u32)1 << iSegid); iSegid++); iSegid += 1 + i*32; #ifdef SQLITE_DEBUG for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){ for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){ - assert( iSegid!=pStruct->aLevel[iLvl].aSeg[iSeg].iSegid ); + assert_nc( iSegid!=pStruct->aLevel[iLvl].aSeg[iSeg].iSegid ); } } - assert( iSegid>0 && iSegid<=FTS5_MAX_SEGMENT ); + assert_nc( iSegid>0 && iSegid<=FTS5_MAX_SEGMENT ); { sqlite3_stmt *pIdxSelect = fts5IdxSelectStmt(p); @@ -210243,7 +211470,7 @@ static int fts5AllocateSegid(Fts5Index *p, Fts5Structure *pStruct){ u8 aBlob[2] = {0xff, 0xff}; sqlite3_bind_int(pIdxSelect, 1, iSegid); sqlite3_bind_blob(pIdxSelect, 2, aBlob, 2, SQLITE_STATIC); - assert( sqlite3_step(pIdxSelect)!=SQLITE_ROW ); + assert_nc( sqlite3_step(pIdxSelect)!=SQLITE_ROW ); p->rc = sqlite3_reset(pIdxSelect); sqlite3_bind_null(pIdxSelect, 2); } @@ -210313,7 +211540,7 @@ static int fts5WriteDlidxGrow( int nLvl ){ if( p->rc==SQLITE_OK && nLvl>=pWriter->nDlidx ){ - Fts5DlidxWriter *aDlidx = (Fts5DlidxWriter*)sqlite3_realloc( + Fts5DlidxWriter *aDlidx = (Fts5DlidxWriter*)sqlite3_realloc64( pWriter->aDlidx, sizeof(Fts5DlidxWriter) * nLvl ); if( aDlidx==0 ){ @@ -210392,8 +211619,10 @@ static void fts5WriteBtreeTerm( int nTerm, const u8 *pTerm /* First term on new page */ ){ fts5WriteFlushBtree(p, pWriter); - fts5BufferSet(&p->rc, &pWriter->btterm, nTerm, pTerm); - pWriter->iBtPage = pWriter->writer.pgno; + if( p->rc==SQLITE_OK ){ + fts5BufferSet(&p->rc, &pWriter->btterm, nTerm, pTerm); + pWriter->iBtPage = pWriter->writer.pgno; + } } /* @@ -210544,6 +211773,7 @@ static void fts5WriteAppendTerm( int nPrefix; /* Bytes of prefix compression for term */ Fts5PageWriter *pPage = &pWriter->writer; Fts5Buffer *pPgidx = &pWriter->writer.pgidx; + int nMin = MIN(pPage->term.n, nTerm); assert( p->rc==SQLITE_OK ); assert( pPage->buf.n>=4 ); @@ -210553,6 +211783,7 @@ static void fts5WriteAppendTerm( if( (pPage->buf.n + pPgidx->n + nTerm + 2)>=p->pConfig->pgsz ){ if( pPage->buf.n>4 ){ fts5WriteFlushLeaf(p, pWriter); + if( p->rc!=SQLITE_OK ) return; } fts5BufferGrow(&p->rc, &pPage->buf, nTerm+FTS5_DATA_PADDING); } @@ -210585,13 +211816,14 @@ static void fts5WriteAppendTerm( ** inefficient, but still correct. */ int n = nTerm; if( pPage->term.n ){ - n = 1 + fts5PrefixCompress(pPage->term.n, pPage->term.p, pTerm); + n = 1 + fts5PrefixCompress(nMin, pPage->term.p, pTerm); } fts5WriteBtreeTerm(p, pWriter, n, pTerm); + if( p->rc!=SQLITE_OK ) return; pPage = &pWriter->writer; } }else{ - nPrefix = fts5PrefixCompress(pPage->term.n, pPage->term.p, pTerm); + nPrefix = fts5PrefixCompress(nMin, pPage->term.p, pTerm); fts5BufferAppendVarint(&p->rc, &pPage->buf, nPrefix); } @@ -210638,7 +211870,7 @@ static void fts5WriteAppendRowid( if( pWriter->bFirstRowidInDoclist || pWriter->bFirstRowidInPage ){ fts5BufferAppendVarint(&p->rc, &pPage->buf, iRowid); }else{ - assert( p->rc || iRowid>pWriter->iPrevRowid ); + assert_nc( p->rc || iRowid>pWriter->iPrevRowid ); fts5BufferAppendVarint(&p->rc, &pPage->buf, iRowid - pWriter->iPrevRowid); } pWriter->iPrevRowid = iRowid; @@ -210760,7 +211992,7 @@ static void fts5TrimSegments(Fts5Index *p, Fts5Iter *pIter){ int i; Fts5Buffer buf; memset(&buf, 0, sizeof(Fts5Buffer)); - for(i=0; i<pIter->nSeg; i++){ + for(i=0; i<pIter->nSeg && p->rc==SQLITE_OK; i++){ Fts5SegIter *pSeg = &pIter->aSeg[i]; if( pSeg->pSeg==0 ){ /* no-op */ @@ -210778,35 +212010,43 @@ static void fts5TrimSegments(Fts5Index *p, Fts5Iter *pIter){ u8 aHdr[4] = {0x00, 0x00, 0x00, 0x00}; iLeafRowid = FTS5_SEGMENT_ROWID(iId, pSeg->iTermLeafPgno); - pData = fts5DataRead(p, iLeafRowid); + pData = fts5LeafRead(p, iLeafRowid); if( pData ){ - fts5BufferZero(&buf); - fts5BufferGrow(&p->rc, &buf, pData->nn); - fts5BufferAppendBlob(&p->rc, &buf, sizeof(aHdr), aHdr); - fts5BufferAppendVarint(&p->rc, &buf, pSeg->term.n); - fts5BufferAppendBlob(&p->rc, &buf, pSeg->term.n, pSeg->term.p); - fts5BufferAppendBlob(&p->rc, &buf, pData->szLeaf-iOff, &pData->p[iOff]); - if( p->rc==SQLITE_OK ){ - /* Set the szLeaf field */ - fts5PutU16(&buf.p[2], (u16)buf.n); - } + if( iOff>pData->szLeaf ){ + /* This can occur if the pages that the segments occupy overlap - if + ** a single page has been assigned to more than one segment. In + ** this case a prior iteration of this loop may have corrupted the + ** segment currently being trimmed. */ + p->rc = FTS5_CORRUPT; + }else{ + fts5BufferZero(&buf); + fts5BufferGrow(&p->rc, &buf, pData->nn); + fts5BufferAppendBlob(&p->rc, &buf, sizeof(aHdr), aHdr); + fts5BufferAppendVarint(&p->rc, &buf, pSeg->term.n); + fts5BufferAppendBlob(&p->rc, &buf, pSeg->term.n, pSeg->term.p); + fts5BufferAppendBlob(&p->rc, &buf, pData->szLeaf-iOff,&pData->p[iOff]); + if( p->rc==SQLITE_OK ){ + /* Set the szLeaf field */ + fts5PutU16(&buf.p[2], (u16)buf.n); + } - /* Set up the new page-index array */ - fts5BufferAppendVarint(&p->rc, &buf, 4); - if( pSeg->iLeafPgno==pSeg->iTermLeafPgno - && pSeg->iEndofDoclist<pData->szLeaf - ){ - int nDiff = pData->szLeaf - pSeg->iEndofDoclist; - fts5BufferAppendVarint(&p->rc, &buf, buf.n - 1 - nDiff - 4); - fts5BufferAppendBlob(&p->rc, &buf, - pData->nn - pSeg->iPgidxOff, &pData->p[pSeg->iPgidxOff] - ); - } + /* Set up the new page-index array */ + fts5BufferAppendVarint(&p->rc, &buf, 4); + if( pSeg->iLeafPgno==pSeg->iTermLeafPgno + && pSeg->iEndofDoclist<pData->szLeaf + ){ + int nDiff = pData->szLeaf - pSeg->iEndofDoclist; + fts5BufferAppendVarint(&p->rc, &buf, buf.n - 1 - nDiff - 4); + fts5BufferAppendBlob(&p->rc, &buf, + pData->nn - pSeg->iPgidxOff, &pData->p[pSeg->iPgidxOff] + ); + } + pSeg->pSeg->pgnoFirst = pSeg->iTermLeafPgno; + fts5DataDelete(p, FTS5_SEGMENT_ROWID(iId, 1), iLeafRowid); + fts5DataWrite(p, iLeafRowid, buf.p, buf.n); + } fts5DataRelease(pData); - pSeg->pSeg->pgnoFirst = pSeg->iTermLeafPgno; - fts5DataDelete(p, FTS5_SEGMENT_ROWID(iId, 1), iLeafRowid); - fts5DataWrite(p, iLeafRowid, buf.p, buf.n); } } } @@ -210898,7 +212138,7 @@ static void fts5IndexMergeLevel( const u8 *pTerm; pTerm = fts5MultiIterTerm(pIter, &nTerm); - if( nTerm!=term.n || memcmp(pTerm, term.p, nTerm) ){ + if( nTerm!=term.n || fts5Memcmp(pTerm, term.p, nTerm) ){ if( pnRem && writer.nLeafWritten>nRem ){ break; } @@ -211153,6 +212393,7 @@ static void fts5FlushOneHash(Fts5Index *p){ /* Write the term for this entry to disk. */ sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist); fts5WriteAppendTerm(p, &writer, (int)strlen(zTerm), (const u8*)zTerm); + if( p->rc!=SQLITE_OK ) break; assert( writer.bFirstRowidInPage==0 ); if( pgsz>=(pBuf->n + pPgidx->n + nDoclist + 1) ){ @@ -211175,6 +212416,7 @@ static void fts5FlushOneHash(Fts5Index *p){ pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid); writer.bFirstRowidInPage = 0; fts5WriteDlidxAppend(p, &writer, iRowid); + if( p->rc!=SQLITE_OK ) break; }else{ pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iDelta); } @@ -211232,7 +212474,7 @@ static void fts5FlushOneHash(Fts5Index *p){ /* TODO2: Doclist terminator written here. */ /* pBuf->p[pBuf->n++] = '\0'; */ assert( pBuf->n<=pBuf->nSpace ); - sqlite3Fts5HashScanNext(pHash); + if( p->rc==SQLITE_OK ) sqlite3Fts5HashScanNext(pHash); } sqlite3Fts5HashClear(pHash); fts5WriteFinish(p, &writer, &pgnoLast); @@ -211276,7 +212518,7 @@ static Fts5Structure *fts5IndexOptimizeStruct( Fts5Structure *pStruct ){ Fts5Structure *pNew = 0; - int nByte = sizeof(Fts5Structure); + sqlite3_int64 nByte = sizeof(Fts5Structure); int nSeg = pStruct->nSegment; int i; @@ -211406,11 +212648,13 @@ static void fts5AppendPoslist( Fts5Buffer *pBuf ){ int nData = pMulti->base.nData; + int nByte = nData + 9 + 9 + FTS5_DATA_ZERO_PADDING; assert( nData>0 ); - if( p->rc==SQLITE_OK && 0==fts5BufferGrow(&p->rc, pBuf, nData+9+9) ){ + if( p->rc==SQLITE_OK && 0==fts5BufferGrow(&p->rc, pBuf, nByte) ){ fts5BufferSafeAppendVarint(pBuf, iDelta); fts5BufferSafeAppendVarint(pBuf, nData*2); fts5BufferSafeAppendBlob(pBuf, pMulti->base.pData, nData); + memset(&pBuf->p[pBuf->n], 0, FTS5_DATA_ZERO_PADDING); } } @@ -211591,6 +212835,8 @@ static void fts5MergePrefixLists( int iOff2 = 0; u8 *a1 = &i1.aPoslist[i1.nSize]; u8 *a2 = &i2.aPoslist[i2.nSize]; + int nCopy; + u8 *aCopy; i64 iPrev = 0; Fts5PoslistWriter writer; @@ -211622,7 +212868,7 @@ static void fts5MergePrefixLists( sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1); if( iPos1<0 ) break; }else{ - assert( iPos2!=iPrev ); + assert_nc( iPos2!=iPrev ); sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2); sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2); if( iPos2<0 ) break; @@ -211634,11 +212880,16 @@ static void fts5MergePrefixLists( if( iPos1!=iPrev ){ sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1); } - fts5BufferSafeAppendBlob(&tmp, &a1[iOff1], i1.nPoslist-iOff1); + aCopy = &a1[iOff1]; + nCopy = i1.nPoslist - iOff1; }else{ assert( iPos2>=0 && iPos2!=iPrev ); sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2); - fts5BufferSafeAppendBlob(&tmp, &a2[iOff2], i2.nPoslist-iOff2); + aCopy = &a2[iOff2]; + nCopy = i2.nPoslist - iOff2; + } + if( nCopy>0 ){ + fts5BufferSafeAppendBlob(&tmp, aCopy, nCopy); } /* WRITEPOSLISTSIZE */ @@ -211646,6 +212897,7 @@ static void fts5MergePrefixLists( fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n); fts5DoclistIterNext(&i1); fts5DoclistIterNext(&i2); + assert( out.n<=(p1->n+p2->n+9) ); if( i1.aPoslist==0 || i2.aPoslist==0 ) break; } } @@ -211747,7 +212999,7 @@ static void fts5SetupPrefixIter( } fts5MultiIterFree(p1); - pData = fts5IdxMalloc(p, sizeof(Fts5Data) + doclist.n); + pData = fts5IdxMalloc(p, sizeof(Fts5Data)+doclist.n+FTS5_DATA_ZERO_PADDING); if( pData ){ pData->p = (u8*)&pData[1]; pData->nn = pData->szLeaf = doclist.n; @@ -212509,11 +213761,11 @@ static void fts5IndexIntegrityCheckSegment( iOff = fts5LeafFirstTermOff(pLeaf); iRowidOff = fts5LeafFirstRowidOff(pLeaf); - if( iRowidOff>=iOff ){ + if( iRowidOff>=iOff || iOff>=pLeaf->szLeaf ){ p->rc = FTS5_CORRUPT; }else{ iOff += fts5GetVarint32(&pLeaf->p[iOff], nTerm); - res = memcmp(&pLeaf->p[iOff], zIdxTerm, MIN(nTerm, nIdxTerm)); + res = fts5Memcmp(&pLeaf->p[iOff], zIdxTerm, MIN(nTerm, nIdxTerm)); if( res==0 ) res = nTerm - nIdxTerm; if( res<0 ) p->rc = FTS5_CORRUPT; } @@ -212908,7 +214160,7 @@ static void fts5DecodeFunction( u8 *a = 0; Fts5Buffer s; /* Build up text to return here */ int rc = SQLITE_OK; /* Return code */ - int nSpace = 0; + sqlite3_int64 nSpace = 0; int eDetailNone = (sqlite3_user_data(pCtx)!=0); assert( nArg==2 ); @@ -212924,8 +214176,7 @@ static void fts5DecodeFunction( nSpace = n + FTS5_DATA_ZERO_PADDING; a = (u8*)sqlite3Fts5MallocZero(&rc, nSpace); if( a==0 ) goto decode_out; - memcpy(a, aBlob, n); - + if( n>0 ) memcpy(a, aBlob, n); fts5DecodeRowid(iRowid, &iSegid, &bDlidx, &iHeight, &iPgno); @@ -213020,6 +214271,9 @@ static void fts5DecodeFunction( iPgidxOff = szLeaf = fts5GetU16(&a[2]); if( iPgidxOff<n ){ fts5GetVarint32(&a[iPgidxOff], iTermOff); + }else if( iPgidxOff>n ){ + rc = FTS5_CORRUPT; + goto decode_out; } } @@ -213031,14 +214285,22 @@ static void fts5DecodeFunction( }else{ iOff = szLeaf; } + if( iOff>n ){ + rc = FTS5_CORRUPT; + goto decode_out; + } fts5DecodePoslist(&rc, &s, &a[4], iOff-4); /* Decode any more doclist data that appears on the page before the ** first term. */ nDoclist = (iTermOff ? iTermOff : szLeaf) - iOff; + if( nDoclist+iOff>n ){ + rc = FTS5_CORRUPT; + goto decode_out; + } fts5DecodeDoclist(&rc, &s, &a[iOff], nDoclist); - while( iPgidxOff<n ){ + while( iPgidxOff<n && rc==SQLITE_OK ){ int bFirst = (iPgidxOff==szLeaf); /* True for first term on page */ int nByte; /* Bytes of data */ int iEnd; @@ -213053,12 +214315,24 @@ static void fts5DecodeFunction( }else{ iEnd = szLeaf; } + if( iEnd>szLeaf ){ + rc = FTS5_CORRUPT; + break; + } if( bFirst==0 ){ iOff += fts5GetVarint32(&a[iOff], nByte); + if( nByte>term.n ){ + rc = FTS5_CORRUPT; + break; + } term.n = nByte; } iOff += fts5GetVarint32(&a[iOff], nByte); + if( iOff+nByte>n ){ + rc = FTS5_CORRUPT; + break; + } fts5BufferAppendBlob(&rc, &term, nByte, &a[iOff]); iOff += nByte; @@ -213182,8 +214456,8 @@ SQLITE_API int sqlite3_fts5_may_be_corrupt = 1; typedef struct Fts5Auxdata Fts5Auxdata; typedef struct Fts5Auxiliary Fts5Auxiliary; typedef struct Fts5Cursor Fts5Cursor; +typedef struct Fts5FullTable Fts5FullTable; typedef struct Fts5Sorter Fts5Sorter; -typedef struct Fts5Table Fts5Table; typedef struct Fts5TokenizerModule Fts5TokenizerModule; /* @@ -213264,13 +214538,8 @@ struct Fts5TokenizerModule { Fts5TokenizerModule *pNext; /* Next registered tokenizer module */ }; -/* -** Virtual-table object. -*/ -struct Fts5Table { - sqlite3_vtab base; /* Base class used by SQLite core */ - Fts5Config *pConfig; /* Virtual table configuration */ - Fts5Index *pIndex; /* Full-text index */ +struct Fts5FullTable { + Fts5Table p; /* Public class members from fts5Int.h */ Fts5Storage *pStorage; /* Document store */ Fts5Global *pGlobal; /* Global (connection wide) data */ Fts5Cursor *pSortCsr; /* Sort data from this cursor */ @@ -213408,7 +214677,7 @@ struct Fts5Auxdata { #define FTS5_SAVEPOINT 5 #define FTS5_RELEASE 6 #define FTS5_ROLLBACKTO 7 -static void fts5CheckTransactionState(Fts5Table *p, int op, int iSavepoint){ +static void fts5CheckTransactionState(Fts5FullTable *p, int op, int iSavepoint){ switch( op ){ case FTS5_BEGIN: assert( p->ts.eState==0 ); @@ -213447,7 +214716,7 @@ static void fts5CheckTransactionState(Fts5Table *p, int op, int iSavepoint){ case FTS5_ROLLBACKTO: assert( p->ts.eState==1 ); - assert( iSavepoint>=0 ); + assert( iSavepoint>=-1 ); assert( iSavepoint<=p->ts.iSavepoint ); p->ts.iSavepoint = iSavepoint; break; @@ -213460,18 +214729,18 @@ static void fts5CheckTransactionState(Fts5Table *p, int op, int iSavepoint){ /* ** Return true if pTab is a contentless table. */ -static int fts5IsContentless(Fts5Table *pTab){ - return pTab->pConfig->eContent==FTS5_CONTENT_NONE; +static int fts5IsContentless(Fts5FullTable *pTab){ + return pTab->p.pConfig->eContent==FTS5_CONTENT_NONE; } /* ** Delete a virtual table handle allocated by fts5InitVtab(). */ -static void fts5FreeVtab(Fts5Table *pTab){ +static void fts5FreeVtab(Fts5FullTable *pTab){ if( pTab ){ - sqlite3Fts5IndexClose(pTab->pIndex); + sqlite3Fts5IndexClose(pTab->p.pIndex); sqlite3Fts5StorageClose(pTab->pStorage); - sqlite3Fts5ConfigFree(pTab->pConfig); + sqlite3Fts5ConfigFree(pTab->p.pConfig); sqlite3_free(pTab); } } @@ -213480,7 +214749,7 @@ static void fts5FreeVtab(Fts5Table *pTab){ ** The xDisconnect() virtual table method. */ static int fts5DisconnectMethod(sqlite3_vtab *pVtab){ - fts5FreeVtab((Fts5Table*)pVtab); + fts5FreeVtab((Fts5FullTable*)pVtab); return SQLITE_OK; } @@ -213491,7 +214760,7 @@ static int fts5DestroyMethod(sqlite3_vtab *pVtab){ Fts5Table *pTab = (Fts5Table*)pVtab; int rc = sqlite3Fts5DropAll(pTab->pConfig); if( rc==SQLITE_OK ){ - fts5FreeVtab((Fts5Table*)pVtab); + fts5FreeVtab((Fts5FullTable*)pVtab); } return rc; } @@ -213520,28 +214789,28 @@ static int fts5InitVtab( const char **azConfig = (const char**)argv; int rc = SQLITE_OK; /* Return code */ Fts5Config *pConfig = 0; /* Results of parsing argc/argv */ - Fts5Table *pTab = 0; /* New virtual table object */ + Fts5FullTable *pTab = 0; /* New virtual table object */ /* Allocate the new vtab object and parse the configuration */ - pTab = (Fts5Table*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Table)); + pTab = (Fts5FullTable*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5FullTable)); if( rc==SQLITE_OK ){ rc = sqlite3Fts5ConfigParse(pGlobal, db, argc, azConfig, &pConfig, pzErr); assert( (rc==SQLITE_OK && *pzErr==0) || pConfig==0 ); } if( rc==SQLITE_OK ){ - pTab->pConfig = pConfig; + pTab->p.pConfig = pConfig; pTab->pGlobal = pGlobal; } /* Open the index sub-system */ if( rc==SQLITE_OK ){ - rc = sqlite3Fts5IndexOpen(pConfig, bCreate, &pTab->pIndex, pzErr); + rc = sqlite3Fts5IndexOpen(pConfig, bCreate, &pTab->p.pIndex, pzErr); } /* Open the storage sub-system */ if( rc==SQLITE_OK ){ rc = sqlite3Fts5StorageOpen( - pConfig, pTab->pIndex, bCreate, &pTab->pStorage, pzErr + pConfig, pTab->p.pIndex, bCreate, &pTab->pStorage, pzErr ); } @@ -213554,8 +214823,8 @@ static int fts5InitVtab( if( rc==SQLITE_OK ){ assert( pConfig->pzErrmsg==0 ); pConfig->pzErrmsg = pzErr; - rc = sqlite3Fts5IndexLoadConfig(pTab->pIndex); - sqlite3Fts5IndexRollback(pTab->pIndex); + rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); + sqlite3Fts5IndexRollback(pTab->p.pIndex); pConfig->pzErrmsg = 0; } @@ -213768,7 +215037,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ return SQLITE_OK; } -static int fts5NewTransaction(Fts5Table *pTab){ +static int fts5NewTransaction(Fts5FullTable *pTab){ Fts5Cursor *pCsr; for(pCsr=pTab->pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){ if( pCsr->base.pVtab==(sqlite3_vtab*)pTab ) return SQLITE_OK; @@ -213780,16 +215049,16 @@ static int fts5NewTransaction(Fts5Table *pTab){ ** Implementation of xOpen method. */ static int fts5OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ - Fts5Table *pTab = (Fts5Table*)pVTab; - Fts5Config *pConfig = pTab->pConfig; + Fts5FullTable *pTab = (Fts5FullTable*)pVTab; + Fts5Config *pConfig = pTab->p.pConfig; Fts5Cursor *pCsr = 0; /* New cursor object */ - int nByte; /* Bytes of space to allocate */ + sqlite3_int64 nByte; /* Bytes of space to allocate */ int rc; /* Return code */ rc = fts5NewTransaction(pTab); if( rc==SQLITE_OK ){ nByte = sizeof(Fts5Cursor) + pConfig->nCol * sizeof(int); - pCsr = (Fts5Cursor*)sqlite3_malloc(nByte); + pCsr = (Fts5Cursor*)sqlite3_malloc64(nByte); if( pCsr ){ Fts5Global *pGlobal = pTab->pGlobal; memset(pCsr, 0, nByte); @@ -213827,7 +215096,7 @@ static void fts5CsrNewrow(Fts5Cursor *pCsr){ } static void fts5FreeCursorComponents(Fts5Cursor *pCsr){ - Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); + Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab); Fts5Auxdata *pData; Fts5Auxdata *pNext; @@ -213871,7 +215140,7 @@ static void fts5FreeCursorComponents(Fts5Cursor *pCsr){ */ static int fts5CloseMethod(sqlite3_vtab_cursor *pCursor){ if( pCursor ){ - Fts5Table *pTab = (Fts5Table*)(pCursor->pVtab); + Fts5FullTable *pTab = (Fts5FullTable*)(pCursor->pVtab); Fts5Cursor *pCsr = (Fts5Cursor*)pCursor; Fts5Cursor **pp; @@ -213928,7 +215197,7 @@ static int fts5SorterNext(Fts5Cursor *pCsr){ ** Set the FTS5CSR_REQUIRE_RESEEK flag on all FTS5_PLAN_MATCH cursors ** open on table pTab. */ -static void fts5TripCursors(Fts5Table *pTab){ +static void fts5TripCursors(Fts5FullTable *pTab){ Fts5Cursor *pCsr; for(pCsr=pTab->pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){ if( pCsr->ePlan==FTS5_PLAN_MATCH @@ -213955,11 +215224,11 @@ static int fts5CursorReseek(Fts5Cursor *pCsr, int *pbSkip){ int rc = SQLITE_OK; assert( *pbSkip==0 ); if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_RESEEK) ){ - Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); + Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab); int bDesc = pCsr->bDesc; i64 iRowid = sqlite3Fts5ExprRowid(pCsr->pExpr); - rc = sqlite3Fts5ExprFirst(pCsr->pExpr, pTab->pIndex, iRowid, bDesc); + rc = sqlite3Fts5ExprFirst(pCsr->pExpr, pTab->p.pIndex, iRowid, bDesc); if( rc==SQLITE_OK && iRowid!=sqlite3Fts5ExprRowid(pCsr->pExpr) ){ *pbSkip = 1; } @@ -214056,18 +215325,22 @@ static int fts5PrepareStatement( return rc; } -static int fts5CursorFirstSorted(Fts5Table *pTab, Fts5Cursor *pCsr, int bDesc){ - Fts5Config *pConfig = pTab->pConfig; +static int fts5CursorFirstSorted( + Fts5FullTable *pTab, + Fts5Cursor *pCsr, + int bDesc +){ + Fts5Config *pConfig = pTab->p.pConfig; Fts5Sorter *pSorter; int nPhrase; - int nByte; + sqlite3_int64 nByte; int rc; const char *zRank = pCsr->zRank; const char *zRankArgs = pCsr->zRankArgs; nPhrase = sqlite3Fts5ExprPhraseCount(pCsr->pExpr); nByte = sizeof(Fts5Sorter) + sizeof(int) * (nPhrase-1); - pSorter = (Fts5Sorter*)sqlite3_malloc(nByte); + pSorter = (Fts5Sorter*)sqlite3_malloc64(nByte); if( pSorter==0 ) return SQLITE_NOMEM; memset(pSorter, 0, nByte); pSorter->nIdx = nPhrase; @@ -214104,10 +215377,10 @@ static int fts5CursorFirstSorted(Fts5Table *pTab, Fts5Cursor *pCsr, int bDesc){ return rc; } -static int fts5CursorFirst(Fts5Table *pTab, Fts5Cursor *pCsr, int bDesc){ +static int fts5CursorFirst(Fts5FullTable *pTab, Fts5Cursor *pCsr, int bDesc){ int rc; Fts5Expr *pExpr = pCsr->pExpr; - rc = sqlite3Fts5ExprFirst(pExpr, pTab->pIndex, pCsr->iFirstRowid, bDesc); + rc = sqlite3Fts5ExprFirst(pExpr, pTab->p.pIndex, pCsr->iFirstRowid, bDesc); if( sqlite3Fts5ExprEof(pExpr) ){ CsrFlagSet(pCsr, FTS5CSR_EOF); } @@ -214122,7 +215395,7 @@ static int fts5CursorFirst(Fts5Table *pTab, Fts5Cursor *pCsr, int bDesc){ ** parameters. */ static int fts5SpecialMatch( - Fts5Table *pTab, + Fts5FullTable *pTab, Fts5Cursor *pCsr, const char *zQuery ){ @@ -214133,18 +215406,18 @@ static int fts5SpecialMatch( while( z[0]==' ' ) z++; for(n=0; z[n] && z[n]!=' '; n++); - assert( pTab->base.zErrMsg==0 ); + assert( pTab->p.base.zErrMsg==0 ); pCsr->ePlan = FTS5_PLAN_SPECIAL; if( 0==sqlite3_strnicmp("reads", z, n) ){ - pCsr->iSpecial = sqlite3Fts5IndexReads(pTab->pIndex); + pCsr->iSpecial = sqlite3Fts5IndexReads(pTab->p.pIndex); } else if( 0==sqlite3_strnicmp("id", z, n) ){ pCsr->iSpecial = pCsr->iCsrId; } else{ /* An unrecognized directive. Return an error message. */ - pTab->base.zErrMsg = sqlite3_mprintf("unknown special query: %.*s", n, z); + pTab->p.base.zErrMsg = sqlite3_mprintf("unknown special query: %.*s", n, z); rc = SQLITE_ERROR; } @@ -214156,7 +215429,7 @@ static int fts5SpecialMatch( ** pTab. If one is found, return a pointer to the corresponding Fts5Auxiliary ** structure. Otherwise, if no such function exists, return NULL. */ -static Fts5Auxiliary *fts5FindAuxiliary(Fts5Table *pTab, const char *zName){ +static Fts5Auxiliary *fts5FindAuxiliary(Fts5FullTable *pTab, const char *zName){ Fts5Auxiliary *pAux; for(pAux=pTab->pGlobal->pAux; pAux; pAux=pAux->pNext){ @@ -214169,8 +215442,8 @@ static Fts5Auxiliary *fts5FindAuxiliary(Fts5Table *pTab, const char *zName){ static int fts5FindRankFunction(Fts5Cursor *pCsr){ - Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); - Fts5Config *pConfig = pTab->pConfig; + Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab); + Fts5Config *pConfig = pTab->p.pConfig; int rc = SQLITE_OK; Fts5Auxiliary *pAux = 0; const char *zRank = pCsr->zRank; @@ -214186,7 +215459,7 @@ static int fts5FindRankFunction(Fts5Cursor *pCsr){ assert( rc==SQLITE_OK || pCsr->pRankArgStmt==0 ); if( rc==SQLITE_OK ){ if( SQLITE_ROW==sqlite3_step(pStmt) ){ - int nByte; + sqlite3_int64 nByte; pCsr->nRankArg = sqlite3_column_count(pStmt); nByte = sizeof(sqlite3_value*)*pCsr->nRankArg; pCsr->apRankArg = (sqlite3_value**)sqlite3Fts5MallocZero(&rc, nByte); @@ -214208,8 +215481,8 @@ static int fts5FindRankFunction(Fts5Cursor *pCsr){ if( rc==SQLITE_OK ){ pAux = fts5FindAuxiliary(pTab, zRank); if( pAux==0 ){ - assert( pTab->base.zErrMsg==0 ); - pTab->base.zErrMsg = sqlite3_mprintf("no such function: %s", zRank); + assert( pTab->p.base.zErrMsg==0 ); + pTab->p.base.zErrMsg = sqlite3_mprintf("no such function: %s", zRank); rc = SQLITE_ERROR; } } @@ -214284,8 +215557,8 @@ static int fts5FilterMethod( int nVal, /* Number of elements in apVal */ sqlite3_value **apVal /* Arguments for the indexing scheme */ ){ - Fts5Table *pTab = (Fts5Table*)(pCursor->pVtab); - Fts5Config *pConfig = pTab->pConfig; + Fts5FullTable *pTab = (Fts5FullTable*)(pCursor->pVtab); + Fts5Config *pConfig = pTab->p.pConfig; Fts5Cursor *pCsr = (Fts5Cursor*)pCursor; int rc = SQLITE_OK; /* Error code */ int iVal = 0; /* Counter for apVal[] */ @@ -214314,8 +215587,8 @@ static int fts5FilterMethod( assert( pCsr->zRank==0 ); assert( pCsr->zRankArgs==0 ); - assert( pzErrmsg==0 || pzErrmsg==&pTab->base.zErrMsg ); - pConfig->pzErrmsg = &pTab->base.zErrMsg; + assert( pzErrmsg==0 || pzErrmsg==&pTab->p.base.zErrMsg ); + pConfig->pzErrmsg = &pTab->p.base.zErrMsg; /* Decode the arguments passed through to this function. ** @@ -214381,7 +215654,7 @@ static int fts5FilterMethod( ** but a request for an internal parameter. */ rc = fts5SpecialMatch(pTab, pCsr, &zExpr[1]); }else{ - char **pzErr = &pTab->base.zErrMsg; + char **pzErr = &pTab->p.base.zErrMsg; rc = sqlite3Fts5ExprNew(pConfig, iCol, zExpr, &pCsr->pExpr, pzErr); if( rc==SQLITE_OK ){ if( bOrderByRank ){ @@ -214404,7 +215677,7 @@ static int fts5FilterMethod( ** by rowid (ePlan==FTS5_PLAN_ROWID). */ pCsr->ePlan = (pRowidEq ? FTS5_PLAN_ROWID : FTS5_PLAN_SCAN); rc = sqlite3Fts5StorageStmt( - pTab->pStorage, fts5StmtType(pCsr), &pCsr->pStmt, &pTab->base.zErrMsg + pTab->pStorage, fts5StmtType(pCsr), &pCsr->pStmt, &pTab->p.base.zErrMsg ); if( rc==SQLITE_OK ){ if( pCsr->ePlan==FTS5_PLAN_ROWID ){ @@ -214487,12 +215760,12 @@ static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){ /* If the cursor does not yet have a statement handle, obtain one now. */ if( pCsr->pStmt==0 ){ - Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); + Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab); int eStmt = fts5StmtType(pCsr); rc = sqlite3Fts5StorageStmt( - pTab->pStorage, eStmt, &pCsr->pStmt, (bErrormsg?&pTab->base.zErrMsg:0) + pTab->pStorage, eStmt, &pCsr->pStmt, (bErrormsg?&pTab->p.base.zErrMsg:0) ); - assert( rc!=SQLITE_OK || pTab->base.zErrMsg==0 ); + assert( rc!=SQLITE_OK || pTab->p.base.zErrMsg==0 ); assert( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_CONTENT) ); } @@ -214514,11 +215787,11 @@ static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){ return rc; } -static void fts5SetVtabError(Fts5Table *p, const char *zFormat, ...){ +static void fts5SetVtabError(Fts5FullTable *p, const char *zFormat, ...){ va_list ap; /* ... printf arguments */ va_start(ap, zFormat); - assert( p->base.zErrMsg==0 ); - p->base.zErrMsg = sqlite3_vmprintf(zFormat, ap); + assert( p->p.base.zErrMsg==0 ); + p->p.base.zErrMsg = sqlite3_vmprintf(zFormat, ap); va_end(ap); } @@ -214538,11 +215811,11 @@ static void fts5SetVtabError(Fts5Table *p, const char *zFormat, ...){ ** more commands are added to this function. */ static int fts5SpecialInsert( - Fts5Table *pTab, /* Fts5 table object */ + Fts5FullTable *pTab, /* Fts5 table object */ const char *zCmd, /* Text inserted into table-name column */ sqlite3_value *pVal /* Value inserted into rank column */ ){ - Fts5Config *pConfig = pTab->pConfig; + Fts5Config *pConfig = pTab->p.pConfig; int rc = SQLITE_OK; int bError = 0; @@ -214577,9 +215850,9 @@ static int fts5SpecialInsert( pConfig->bPrefixIndex = sqlite3_value_int(pVal); #endif }else{ - rc = sqlite3Fts5IndexLoadConfig(pTab->pIndex); + rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); if( rc==SQLITE_OK ){ - rc = sqlite3Fts5ConfigSetValue(pTab->pConfig, zCmd, pVal, &bError); + rc = sqlite3Fts5ConfigSetValue(pTab->p.pConfig, zCmd, pVal, &bError); } if( rc==SQLITE_OK ){ if( bError ){ @@ -214593,7 +215866,7 @@ static int fts5SpecialInsert( } static int fts5SpecialDelete( - Fts5Table *pTab, + Fts5FullTable *pTab, sqlite3_value **apVal ){ int rc = SQLITE_OK; @@ -214607,7 +215880,7 @@ static int fts5SpecialDelete( static void fts5StorageInsert( int *pRc, - Fts5Table *pTab, + Fts5FullTable *pTab, sqlite3_value **apVal, i64 *piRowid ){ @@ -214641,8 +215914,8 @@ static int fts5UpdateMethod( sqlite3_value **apVal, /* Array of arguments */ sqlite_int64 *pRowid /* OUT: The affected (or effected) rowid */ ){ - Fts5Table *pTab = (Fts5Table*)pVtab; - Fts5Config *pConfig = pTab->pConfig; + Fts5FullTable *pTab = (Fts5FullTable*)pVtab; + Fts5Config *pConfig = pTab->p.pConfig; int eType0; /* value_type() of apVal[0] */ int rc = SQLITE_OK; /* Return code */ @@ -214651,12 +215924,11 @@ static int fts5UpdateMethod( assert( pVtab->zErrMsg==0 ); assert( nArg==1 || nArg==(2+pConfig->nCol+2) ); - assert( nArg==1 - || sqlite3_value_type(apVal[1])==SQLITE_INTEGER - || sqlite3_value_type(apVal[1])==SQLITE_NULL + assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER + || sqlite3_value_type(apVal[0])==SQLITE_NULL ); - assert( pTab->pConfig->pzErrmsg==0 ); - pTab->pConfig->pzErrmsg = &pTab->base.zErrMsg; + assert( pTab->p.pConfig->pzErrmsg==0 ); + pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg; /* Put any active cursors into REQUIRE_SEEK state. */ fts5TripCursors(pTab); @@ -214697,7 +215969,7 @@ static int fts5UpdateMethod( /* Filter out attempts to run UPDATE or DELETE on contentless tables. ** This is not suported. */ if( eType0==SQLITE_INTEGER && fts5IsContentless(pTab) ){ - pTab->base.zErrMsg = sqlite3_mprintf( + pTab->p.base.zErrMsg = sqlite3_mprintf( "cannot %s contentless fts5 table: %s", (nArg>1 ? "UPDATE" : "DELETE from"), pConfig->zName ); @@ -214710,46 +215982,52 @@ static int fts5UpdateMethod( rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0); } - /* INSERT */ - else if( eType0!=SQLITE_INTEGER ){ - /* If this is a REPLACE, first remove the current entry (if any) */ - if( eConflict==SQLITE_REPLACE - && sqlite3_value_type(apVal[1])==SQLITE_INTEGER - ){ - i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0); - } - fts5StorageInsert(&rc, pTab, apVal, pRowid); - } - - /* UPDATE */ + /* INSERT or UPDATE */ else{ - i64 iOld = sqlite3_value_int64(apVal[0]); /* Old rowid */ - i64 iNew = sqlite3_value_int64(apVal[1]); /* New rowid */ - if( iOld!=iNew ){ - if( eConflict==SQLITE_REPLACE ){ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); - if( rc==SQLITE_OK ){ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0); - } - fts5StorageInsert(&rc, pTab, apVal, pRowid); - }else{ - rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, pRowid); - if( rc==SQLITE_OK ){ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); - } - if( rc==SQLITE_OK ){ - rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal, *pRowid); - } + int eType1 = sqlite3_value_numeric_type(apVal[1]); + + if( eType1!=SQLITE_INTEGER && eType1!=SQLITE_NULL ){ + rc = SQLITE_MISMATCH; + } + + else if( eType0!=SQLITE_INTEGER ){ + /* If this is a REPLACE, first remove the current entry (if any) */ + if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){ + i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */ + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0); } - }else{ - rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); fts5StorageInsert(&rc, pTab, apVal, pRowid); } + + /* UPDATE */ + else{ + i64 iOld = sqlite3_value_int64(apVal[0]); /* Old rowid */ + i64 iNew = sqlite3_value_int64(apVal[1]); /* New rowid */ + if( eType1==SQLITE_INTEGER && iOld!=iNew ){ + if( eConflict==SQLITE_REPLACE ){ + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0); + } + fts5StorageInsert(&rc, pTab, apVal, pRowid); + }else{ + rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, pRowid); + if( rc==SQLITE_OK ){ + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); + } + if( rc==SQLITE_OK ){ + rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal,*pRowid); + } + } + }else{ + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); + fts5StorageInsert(&rc, pTab, apVal, pRowid); + } + } } } - pTab->pConfig->pzErrmsg = 0; + pTab->p.pConfig->pzErrmsg = 0; return rc; } @@ -214758,12 +216036,12 @@ static int fts5UpdateMethod( */ static int fts5SyncMethod(sqlite3_vtab *pVtab){ int rc; - Fts5Table *pTab = (Fts5Table*)pVtab; + Fts5FullTable *pTab = (Fts5FullTable*)pVtab; fts5CheckTransactionState(pTab, FTS5_SYNC, 0); - pTab->pConfig->pzErrmsg = &pTab->base.zErrMsg; + pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg; fts5TripCursors(pTab); rc = sqlite3Fts5StorageSync(pTab->pStorage); - pTab->pConfig->pzErrmsg = 0; + pTab->p.pConfig->pzErrmsg = 0; return rc; } @@ -214771,8 +216049,8 @@ static int fts5SyncMethod(sqlite3_vtab *pVtab){ ** Implementation of xBegin() method. */ static int fts5BeginMethod(sqlite3_vtab *pVtab){ - fts5CheckTransactionState((Fts5Table*)pVtab, FTS5_BEGIN, 0); - fts5NewTransaction((Fts5Table*)pVtab); + fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_BEGIN, 0); + fts5NewTransaction((Fts5FullTable*)pVtab); return SQLITE_OK; } @@ -214783,7 +216061,7 @@ static int fts5BeginMethod(sqlite3_vtab *pVtab){ */ static int fts5CommitMethod(sqlite3_vtab *pVtab){ UNUSED_PARAM(pVtab); /* Call below is a no-op for NDEBUG builds */ - fts5CheckTransactionState((Fts5Table*)pVtab, FTS5_COMMIT, 0); + fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_COMMIT, 0); return SQLITE_OK; } @@ -214793,7 +216071,7 @@ static int fts5CommitMethod(sqlite3_vtab *pVtab){ */ static int fts5RollbackMethod(sqlite3_vtab *pVtab){ int rc; - Fts5Table *pTab = (Fts5Table*)pVtab; + Fts5FullTable *pTab = (Fts5FullTable*)pVtab; fts5CheckTransactionState(pTab, FTS5_ROLLBACK, 0); rc = sqlite3Fts5StorageRollback(pTab->pStorage); return rc; @@ -214817,13 +216095,13 @@ static int fts5ApiColumnTotalSize( sqlite3_int64 *pnToken ){ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; - Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); + Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab); return sqlite3Fts5StorageSize(pTab->pStorage, iCol, pnToken); } static int fts5ApiRowCount(Fts5Context *pCtx, i64 *pnRow){ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; - Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); + Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab); return sqlite3Fts5StorageRowCount(pTab->pStorage, pnRow); } @@ -214858,7 +216136,9 @@ static int fts5ApiColumnText( ){ int rc = SQLITE_OK; Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; - if( fts5IsContentless((Fts5Table*)(pCsr->base.pVtab)) ){ + if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab)) + || pCsr->ePlan==FTS5_PLAN_SPECIAL + ){ *pz = 0; *pn = 0; }else{ @@ -214927,10 +216207,11 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){ int rc = SQLITE_OK; Fts5PoslistReader *aIter; /* One iterator for each phrase */ int nIter; /* Number of iterators/phrases */ + int nCol = ((Fts5Table*)pCsr->base.pVtab)->pConfig->nCol; nIter = sqlite3Fts5ExprPhraseCount(pCsr->pExpr); if( pCsr->aInstIter==0 ){ - int nByte = sizeof(Fts5PoslistReader) * nIter; + sqlite3_int64 nByte = sizeof(Fts5PoslistReader) * nIter; pCsr->aInstIter = (Fts5PoslistReader*)sqlite3Fts5MallocZero(&rc, nByte); } aIter = pCsr->aInstIter; @@ -214965,7 +216246,7 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){ nInst++; if( nInst>=pCsr->nInstAlloc ){ pCsr->nInstAlloc = pCsr->nInstAlloc ? pCsr->nInstAlloc*2 : 32; - aInst = (int*)sqlite3_realloc( + aInst = (int*)sqlite3_realloc64( pCsr->aInst, pCsr->nInstAlloc*sizeof(int)*3 ); if( aInst ){ @@ -214980,6 +216261,10 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){ aInst[0] = iBest; aInst[1] = FTS5_POS2COLUMN(aIter[iBest].iPos); aInst[2] = FTS5_POS2OFFSET(aIter[iBest].iPos); + if( aInst[1]<0 || aInst[1]>=nCol ){ + rc = FTS5_CORRUPT; + break; + } sqlite3Fts5PoslistReaderNext(&aIter[iBest]); } } @@ -215052,8 +216337,8 @@ static int fts5ColumnSizeCb( static int fts5ApiColumnSize(Fts5Context *pCtx, int iCol, int *pnToken){ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; - Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); - Fts5Config *pConfig = pTab->pConfig; + Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab); + Fts5Config *pConfig = pTab->p.pConfig; int rc = SQLITE_OK; if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_DOCSIZE) ){ @@ -215309,7 +216594,7 @@ static int fts5ApiQueryPhrase( int(*xCallback)(const Fts5ExtensionApi*, Fts5Context*, void*) ){ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; - Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); + Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab); int rc; Fts5Cursor *pNew = 0; @@ -215386,25 +216671,19 @@ static void fts5ApiCallback( /* -** Given cursor id iId, return a pointer to the corresponding Fts5Index +** Given cursor id iId, return a pointer to the corresponding Fts5Table ** object. Or NULL If the cursor id does not exist. -** -** If successful, set *ppConfig to point to the associated config object -** before returning. */ -static Fts5Index *sqlite3Fts5IndexFromCsrid( +static Fts5Table *sqlite3Fts5TableFromCsrid( Fts5Global *pGlobal, /* FTS5 global context for db handle */ - i64 iCsrId, /* Id of cursor to find */ - Fts5Config **ppConfig /* OUT: Configuration object */ + i64 iCsrId /* Id of cursor to find */ ){ Fts5Cursor *pCsr; - Fts5Table *pTab; - pCsr = fts5CursorFromCsrid(pGlobal, iCsrId); - pTab = (Fts5Table*)pCsr->base.pVtab; - *ppConfig = pTab->pConfig; - - return pTab->pIndex; + if( pCsr ){ + return (Fts5Table*)pCsr->base.pVtab; + } + return 0; } /* @@ -215484,8 +216763,8 @@ static int fts5ColumnMethod( sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */ int iCol /* Index of column to read value from */ ){ - Fts5Table *pTab = (Fts5Table*)(pCursor->pVtab); - Fts5Config *pConfig = pTab->pConfig; + Fts5FullTable *pTab = (Fts5FullTable*)(pCursor->pVtab); + Fts5Config *pConfig = pTab->p.pConfig; Fts5Cursor *pCsr = (Fts5Cursor*)pCursor; int rc = SQLITE_OK; @@ -215537,7 +216816,7 @@ static int fts5FindFunctionMethod( void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */ void **ppArg /* OUT: User data for *pxFunc */ ){ - Fts5Table *pTab = (Fts5Table*)pVtab; + Fts5FullTable *pTab = (Fts5FullTable*)pVtab; Fts5Auxiliary *pAux; UNUSED_PARAM(nUnused); @@ -215559,21 +216838,24 @@ static int fts5RenameMethod( sqlite3_vtab *pVtab, /* Virtual table handle */ const char *zName /* New name of table */ ){ - Fts5Table *pTab = (Fts5Table*)pVtab; + Fts5FullTable *pTab = (Fts5FullTable*)pVtab; return sqlite3Fts5StorageRename(pTab->pStorage, zName); } +static int sqlite3Fts5FlushToDisk(Fts5Table *pTab){ + fts5TripCursors((Fts5FullTable*)pTab); + return sqlite3Fts5StorageSync(((Fts5FullTable*)pTab)->pStorage); +} + /* ** The xSavepoint() method. ** ** Flush the contents of the pending-terms table to disk. */ static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ - Fts5Table *pTab = (Fts5Table*)pVtab; UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ - fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint); - fts5TripCursors(pTab); - return sqlite3Fts5StorageSync(pTab->pStorage); + fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_SAVEPOINT, iSavepoint); + return sqlite3Fts5FlushToDisk((Fts5Table*)pVtab); } /* @@ -215582,11 +216864,9 @@ static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ ** This is a no-op. */ static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ - Fts5Table *pTab = (Fts5Table*)pVtab; UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ - fts5CheckTransactionState(pTab, FTS5_RELEASE, iSavepoint); - fts5TripCursors(pTab); - return sqlite3Fts5StorageSync(pTab->pStorage); + fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_RELEASE, iSavepoint); + return sqlite3Fts5FlushToDisk((Fts5Table*)pVtab); } /* @@ -215595,7 +216875,7 @@ static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ ** Discard the contents of the pending terms table. */ static int fts5RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ - Fts5Table *pTab = (Fts5Table*)pVtab; + Fts5FullTable *pTab = (Fts5FullTable*)pVtab; UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint); fts5TripCursors(pTab); @@ -215796,7 +217076,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2019-02-08 13:17:39 0eca3dd3d38b31c92b49ca2d311128b74584714d9e7de895b1a6286ef959a1dd", -1, SQLITE_TRANSIENT); } /* @@ -216045,7 +217325,7 @@ static int fts5StorageGetStmt( char *zBind; int i; - zBind = sqlite3_malloc(1 + nCol*2); + zBind = sqlite3_malloc64(1 + nCol*2); if( zBind ){ for(i=0; i<nCol; i++){ zBind[i*2] = '?'; @@ -216066,8 +217346,9 @@ static int fts5StorageGetStmt( if( zSql==0 ){ rc = SQLITE_NOMEM; }else{ - rc = sqlite3_prepare_v3(pC->db, zSql, -1, - SQLITE_PREPARE_PERSISTENT, &p->aStmt[eStmt], 0); + int f = SQLITE_PREPARE_PERSISTENT; + if( eStmt>FTS5_STMT_LOOKUP ) f |= SQLITE_PREPARE_NO_VTAB; + rc = sqlite3_prepare_v3(pC->db, zSql, -1, f, &p->aStmt[eStmt], 0); sqlite3_free(zSql); if( rc!=SQLITE_OK && pzErrMsg ){ *pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db)); @@ -216211,11 +217492,11 @@ static int sqlite3Fts5StorageOpen( ){ int rc = SQLITE_OK; Fts5Storage *p; /* New object */ - int nByte; /* Bytes of space to allocate */ + sqlite3_int64 nByte; /* Bytes of space to allocate */ nByte = sizeof(Fts5Storage) /* Fts5Storage object */ + pConfig->nCol * sizeof(i64); /* Fts5Storage.aTotalSize[] */ - *pp = p = (Fts5Storage*)sqlite3_malloc(nByte); + *pp = p = (Fts5Storage*)sqlite3_malloc64(nByte); if( !p ) return SQLITE_NOMEM; memset(p, 0, nByte); @@ -216226,7 +217507,7 @@ static int sqlite3Fts5StorageOpen( if( bCreate ){ if( pConfig->eContent==FTS5_CONTENT_NORMAL ){ int nDefn = 32 + pConfig->nCol*10; - char *zDefn = sqlite3_malloc(32 + pConfig->nCol * 10); + char *zDefn = sqlite3_malloc64(32 + (sqlite3_int64)pConfig->nCol * 10); if( zDefn==0 ){ rc = SQLITE_NOMEM; }else{ @@ -216517,7 +217798,7 @@ static int sqlite3Fts5StorageRebuild(Fts5Storage *p){ Fts5Config *pConfig = p->pConfig; sqlite3_stmt *pScan = 0; Fts5InsertCtx ctx; - int rc; + int rc, rc2; memset(&ctx, 0, sizeof(Fts5InsertCtx)); ctx.pStorage = p; @@ -216556,6 +217837,8 @@ static int sqlite3Fts5StorageRebuild(Fts5Storage *p){ } } sqlite3_free(buf.p); + rc2 = sqlite3_reset(pScan); + if( rc==SQLITE_OK ) rc = rc2; /* Write the averages record */ if( rc==SQLITE_OK ){ @@ -216805,7 +218088,7 @@ static int sqlite3Fts5StorageIntegrity(Fts5Storage *p){ memset(&ctx, 0, sizeof(Fts5IntegrityCtx)); ctx.pConfig = p->pConfig; - aTotalSize = (i64*)sqlite3_malloc(pConfig->nCol * (sizeof(int)+sizeof(i64))); + aTotalSize = (i64*)sqlite3_malloc64(pConfig->nCol*(sizeof(int)+sizeof(i64))); if( !aTotalSize ) return SQLITE_NOMEM; aColSize = (int*)&aTotalSize[pConfig->nCol]; memset(aTotalSize, 0, sizeof(i64) * pConfig->nCol); @@ -217005,7 +218288,13 @@ static int sqlite3Fts5StorageSize(Fts5Storage *p, int iCol, i64 *pnToken){ static int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow){ int rc = fts5StorageLoadTotals(p, 0); if( rc==SQLITE_OK ){ + /* nTotalRow being zero does not necessarily indicate a corrupt + ** database - it might be that the FTS5 table really does contain zero + ** rows. However this function is only called from the xRowCount() API, + ** and there is no way for that API to be invoked if the table contains + ** no rows. Hence the FTS5_CORRUPT return. */ *pnRow = p->nTotalRow; + if( p->nTotalRow<=0 ) rc = FTS5_CORRUPT; } return rc; } @@ -217215,7 +218504,7 @@ static int fts5AsciiTokenize( nByte = ie-is; if( nByte>nFold ){ if( pFold!=aFold ) sqlite3_free(pFold); - pFold = sqlite3_malloc(nByte*2); + pFold = sqlite3_malloc64((sqlite3_int64)nByte*2); if( pFold==0 ){ rc = SQLITE_NOMEM; break; @@ -217297,13 +218586,18 @@ struct Unicode61Tokenizer { unsigned char aTokenChar[128]; /* ASCII range token characters */ char *aFold; /* Buffer to fold text into */ int nFold; /* Size of aFold[] in bytes */ - int bRemoveDiacritic; /* True if remove_diacritics=1 is set */ + int eRemoveDiacritic; /* True if remove_diacritics=1 is set */ int nException; int *aiException; unsigned char aCategory[32]; /* True for token char categories */ }; +/* Values for eRemoveDiacritic (must match internals of fts5_unicode2.c) */ +#define FTS5_REMOVE_DIACRITICS_NONE 0 +#define FTS5_REMOVE_DIACRITICS_SIMPLE 1 +#define FTS5_REMOVE_DIACRITICS_COMPLEX 2 + static int fts5UnicodeAddExceptions( Unicode61Tokenizer *p, /* Tokenizer object */ const char *z, /* Characters to treat as exceptions */ @@ -217314,13 +218608,14 @@ static int fts5UnicodeAddExceptions( int *aNew; if( n>0 ){ - aNew = (int*)sqlite3_realloc(p->aiException, (n+p->nException)*sizeof(int)); + aNew = (int*)sqlite3_realloc64(p->aiException, + (n+p->nException)*sizeof(int)); if( aNew ){ int nNew = p->nException; const unsigned char *zCsr = (const unsigned char*)z; const unsigned char *zTerm = (const unsigned char*)&z[n]; while( zCsr<zTerm ){ - int iCode; + u32 iCode; int bToken; READ_UTF8(zCsr, zTerm, iCode); if( iCode<128 ){ @@ -217332,7 +218627,7 @@ static int fts5UnicodeAddExceptions( if( bToken!=bTokenChars && sqlite3Fts5UnicodeIsdiacritic(iCode)==0 ){ int i; for(i=0; i<nNew; i++){ - if( aNew[i]>iCode ) break; + if( (u32)aNew[i]>iCode ) break; } memmove(&aNew[i+1], &aNew[i], (nNew-i)*sizeof(int)); aNew[i] = iCode; @@ -217424,7 +218719,7 @@ static int fts5UnicodeCreate( int i; memset(p, 0, sizeof(Unicode61Tokenizer)); - p->bRemoveDiacritic = 1; + p->eRemoveDiacritic = FTS5_REMOVE_DIACRITICS_SIMPLE; p->nFold = 64; p->aFold = sqlite3_malloc(p->nFold * sizeof(char)); if( p->aFold==0 ){ @@ -217445,10 +218740,15 @@ static int fts5UnicodeCreate( for(i=0; rc==SQLITE_OK && i<nArg; i+=2){ const char *zArg = azArg[i+1]; if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){ - if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){ + if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){ rc = SQLITE_ERROR; + }else{ + p->eRemoveDiacritic = (zArg[0] - '0'); + assert( p->eRemoveDiacritic==FTS5_REMOVE_DIACRITICS_NONE + || p->eRemoveDiacritic==FTS5_REMOVE_DIACRITICS_SIMPLE + || p->eRemoveDiacritic==FTS5_REMOVE_DIACRITICS_COMPLEX + ); } - p->bRemoveDiacritic = (zArg[0]=='1'); }else if( 0==sqlite3_stricmp(azArg[i], "tokenchars") ){ rc = fts5UnicodeAddExceptions(p, zArg, 1); @@ -217482,7 +218782,7 @@ static int fts5UnicodeCreate( */ static int fts5UnicodeIsAlnum(Unicode61Tokenizer *p, int iCode){ return ( - p->aCategory[sqlite3Fts5UnicodeCategory(iCode)] + p->aCategory[sqlite3Fts5UnicodeCategory((u32)iCode)] ^ fts5UnicodeIsException(p, iCode) ); } @@ -217511,7 +218811,7 @@ static int fts5UnicodeTokenize( /* Each iteration of this loop gobbles up a contiguous run of separators, ** then the next token. */ while( rc==SQLITE_OK ){ - int iCode; /* non-ASCII codepoint read from input */ + u32 iCode; /* non-ASCII codepoint read from input */ char *zOut = aFold; int is; int ie; @@ -217543,7 +218843,7 @@ static int fts5UnicodeTokenize( /* Grow the output buffer so that there is sufficient space to fit the ** largest possible utf-8 character. */ if( zOut>pEnd ){ - aFold = sqlite3_malloc(nFold*2); + aFold = sqlite3_malloc64((sqlite3_int64)nFold*2); if( aFold==0 ){ rc = SQLITE_NOMEM; goto tokenize_done; @@ -217562,7 +218862,7 @@ static int fts5UnicodeTokenize( READ_UTF8(zCsr, zTerm, iCode); if( fts5UnicodeIsAlnum(p,iCode)||sqlite3Fts5UnicodeIsdiacritic(iCode) ){ non_ascii_tokenchar: - iCode = sqlite3Fts5UnicodeFold(iCode, p->bRemoveDiacritic); + iCode = sqlite3Fts5UnicodeFold(iCode, p->eRemoveDiacritic); if( iCode ) WRITE_UTF8(zOut, iCode); }else{ break; @@ -218338,10 +219638,8 @@ static int sqlite3Fts5TokenizerInit(fts5_api *pApi){ return rc; } - - /* -** 2012 May 25 +** 2012-05-25 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: @@ -218370,32 +219668,48 @@ static int sqlite3Fts5TokenizerInit(fts5_api *pApi){ ** E"). The resuls of passing a codepoint that corresponds to an ** uppercase letter are undefined. */ -static int fts5_remove_diacritic(int c){ +static int fts5_remove_diacritic(int c, int bComplex){ unsigned short aDia[] = { 0, 1797, 1848, 1859, 1891, 1928, 1940, 1995, 2024, 2040, 2060, 2110, 2168, 2206, 2264, 2286, 2344, 2383, 2472, 2488, 2516, 2596, 2668, 2732, 2782, 2842, 2894, 2954, 2984, 3000, 3028, 3336, - 3456, 3696, 3712, 3728, 3744, 3896, 3912, 3928, - 3968, 4008, 4040, 4106, 4138, 4170, 4202, 4234, - 4266, 4296, 4312, 4344, 4408, 4424, 4472, 4504, - 6148, 6198, 6264, 6280, 6360, 6429, 6505, 6529, - 61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726, - 61784, 61800, 61836, 61880, 61914, 61948, 61998, 62122, - 62154, 62200, 62218, 62302, 62364, 62442, 62478, 62536, - 62554, 62584, 62604, 62640, 62648, 62656, 62664, 62730, - 62924, 63050, 63082, 63274, 63390, + 3456, 3696, 3712, 3728, 3744, 3766, 3832, 3896, + 3912, 3928, 3944, 3968, 4008, 4040, 4056, 4106, + 4138, 4170, 4202, 4234, 4266, 4296, 4312, 4344, + 4408, 4424, 4442, 4472, 4488, 4504, 6148, 6198, + 6264, 6280, 6360, 6429, 6505, 6529, 61448, 61468, + 61512, 61534, 61592, 61610, 61642, 61672, 61688, 61704, + 61726, 61784, 61800, 61816, 61836, 61880, 61896, 61914, + 61948, 61998, 62062, 62122, 62154, 62184, 62200, 62218, + 62252, 62302, 62364, 62410, 62442, 62478, 62536, 62554, + 62584, 62604, 62640, 62648, 62656, 62664, 62730, 62766, + 62830, 62890, 62924, 62974, 63032, 63050, 63082, 63118, + 63182, 63242, 63274, 63310, 63368, 63390, }; - char aChar[] = { - '\0', 'a', 'c', 'e', 'i', 'n', 'o', 'u', 'y', 'y', 'a', 'c', - 'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r', - 's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o', - 'u', 'g', 'k', 'o', 'j', 'g', 'n', 'a', 'e', 'i', 'o', 'r', - 'u', 's', 't', 'h', 'a', 'e', 'o', 'y', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', 'a', 'b', 'd', 'd', 'e', 'f', 'g', 'h', - 'h', 'i', 'k', 'l', 'l', 'm', 'n', 'p', 'r', 'r', 's', 't', - 'u', 'v', 'w', 'w', 'x', 'y', 'z', 'h', 't', 'w', 'y', 'a', - 'e', 'i', 'o', 'u', 'y', +#define HIBIT ((unsigned char)0x80) + unsigned char aChar[] = { + '\0', 'a', 'c', 'e', 'i', 'n', + 'o', 'u', 'y', 'y', 'a', 'c', + 'd', 'e', 'e', 'g', 'h', 'i', + 'j', 'k', 'l', 'n', 'o', 'r', + 's', 't', 'u', 'u', 'w', 'y', + 'z', 'o', 'u', 'a', 'i', 'o', + 'u', 'u'|HIBIT, 'a'|HIBIT, 'g', 'k', 'o', + 'o'|HIBIT, 'j', 'g', 'n', 'a'|HIBIT, 'a', + 'e', 'i', 'o', 'r', 'u', 's', + 't', 'h', 'a', 'e', 'o'|HIBIT, 'o', + 'o'|HIBIT, 'y', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', 'a', 'b', + 'c'|HIBIT, 'd', 'd', 'e'|HIBIT, 'e', 'e'|HIBIT, + 'f', 'g', 'h', 'h', 'i', 'i'|HIBIT, + 'k', 'l', 'l'|HIBIT, 'l', 'm', 'n', + 'o'|HIBIT, 'p', 'r', 'r'|HIBIT, 'r', 's', + 's'|HIBIT, 't', 'u', 'u'|HIBIT, 'v', 'w', + 'w', 'x', 'y', 'z', 'h', 't', + 'w', 'y', 'a', 'a'|HIBIT, 'a'|HIBIT, 'a'|HIBIT, + 'e', 'e'|HIBIT, 'e'|HIBIT, 'i', 'o', 'o'|HIBIT, + 'o'|HIBIT, 'o'|HIBIT, 'u', 'u'|HIBIT, 'u'|HIBIT, 'y', }; unsigned int key = (((unsigned int)c)<<3) | 0x00000007; @@ -218412,7 +219726,8 @@ static int fts5_remove_diacritic(int c){ } } assert( key>=aDia[iRes] ); - return ((c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : (int)aChar[iRes]); + if( bComplex==0 && (aChar[iRes] & 0x80) ) return c; + return (c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : ((int)aChar[iRes] & 0x7F); } @@ -218425,8 +219740,8 @@ static int sqlite3Fts5UnicodeIsdiacritic(int c){ unsigned int mask1 = 0x000361F8; if( c<768 || c>817 ) return 0; return (c < 768+32) ? - (mask0 & (1 << (c-768))) : - (mask1 & (1 << (c-768-32))); + (mask0 & ((unsigned int)1 << (c-768))) : + (mask1 & ((unsigned int)1 << (c-768-32))); } @@ -218439,7 +219754,7 @@ static int sqlite3Fts5UnicodeIsdiacritic(int c){ ** The results are undefined if the value passed to this function ** is less than zero. */ -static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic){ +static int sqlite3Fts5UnicodeFold(int c, int eRemoveDiacritic){ /* Each entry in the following array defines a rule for folding a range ** of codepoints to lower case. The rule applies to a range of nRange ** codepoints starting at codepoint iCode. @@ -218562,7 +219877,9 @@ static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic){ assert( ret>0 ); } - if( bRemoveDiacritic ) ret = fts5_remove_diacritic(ret); + if( eRemoveDiacritic ){ + ret = fts5_remove_diacritic(ret, eRemoveDiacritic==2); + } } else if( c>=66560 && c<66600 ){ @@ -218573,12 +219890,6 @@ static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic){ } -#if 0 -static int sqlite3Fts5UnicodeNCat(void) { - return 32; -} -#endif - static int sqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){ aArray[0] = 1; switch( zCat[0] ){ @@ -219060,7 +220371,7 @@ static u16 aFts5UnicodeData[] = { 34, 3074, 7692, 63, 63, }; -static int sqlite3Fts5UnicodeCategory(int iCode) { +static int sqlite3Fts5UnicodeCategory(u32 iCode) { int iRes = -1; int iHi; int iLo; @@ -219098,13 +220409,12 @@ static void sqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){ int bToken = aArray[ aFts5UnicodeData[iTbl] & 0x1F ]; int n = (aFts5UnicodeData[iTbl] >> 5) + i; for(; i<128 && i<n; i++){ - aAscii[i] = (u8)bToken; + aAscii[i] = bToken; } iTbl++; } } - /* ** 2015 May 30 ** @@ -219183,7 +220493,7 @@ static int sqlite3Fts5GetVarint32(const unsigned char *p, u32 *v){ u8 n; p -= 2; n = sqlite3Fts5GetVarint(p, &v64); - *v = (u32)v64; + *v = ((u32)v64) & 0x7FFFFFFF; assert( n>3 && n<=9 ); return n; } @@ -219450,7 +220760,6 @@ static int sqlite3Fts5GetVarintLen(u32 iVal){ return 5; } - /* ** 2015 May 08 ** @@ -219508,7 +220817,7 @@ struct Fts5VocabTable { struct Fts5VocabCursor { sqlite3_vtab_cursor base; sqlite3_stmt *pStmt; /* Statement holding lock on pIndex */ - Fts5Index *pIndex; /* Associated FTS5 index */ + Fts5Table *pFts5; /* Associated FTS5 table */ int bEof; /* True if this cursor is at EOF */ Fts5IndexIter *pIter; /* Term/rowid iterator object */ @@ -219517,7 +220826,6 @@ struct Fts5VocabCursor { char *zLeTerm; /* (term <= $zLeTerm) paramater, or NULL */ /* These are used by 'col' tables only */ - Fts5Config *pConfig; /* Fts5 table configuration */ int iCol; i64 *aCnt; i64 *aDoc; @@ -219780,8 +221088,7 @@ static int fts5VocabOpenMethod( sqlite3_vtab_cursor **ppCsr ){ Fts5VocabTable *pTab = (Fts5VocabTable*)pVTab; - Fts5Index *pIndex = 0; - Fts5Config *pConfig = 0; + Fts5Table *pFts5 = 0; Fts5VocabCursor *pCsr = 0; int rc = SQLITE_OK; sqlite3_stmt *pStmt = 0; @@ -219800,31 +221107,34 @@ static int fts5VocabOpenMethod( if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){ i64 iId = sqlite3_column_int64(pStmt, 0); - pIndex = sqlite3Fts5IndexFromCsrid(pTab->pGlobal, iId, &pConfig); + pFts5 = sqlite3Fts5TableFromCsrid(pTab->pGlobal, iId); } - if( rc==SQLITE_OK && pIndex==0 ){ - rc = sqlite3_finalize(pStmt); - pStmt = 0; - if( rc==SQLITE_OK ){ - pVTab->zErrMsg = sqlite3_mprintf( - "no such fts5 table: %s.%s", pTab->zFts5Db, pTab->zFts5Tbl - ); - rc = SQLITE_ERROR; + if( rc==SQLITE_OK ){ + if( pFts5==0 ){ + rc = sqlite3_finalize(pStmt); + pStmt = 0; + if( rc==SQLITE_OK ){ + pVTab->zErrMsg = sqlite3_mprintf( + "no such fts5 table: %s.%s", pTab->zFts5Db, pTab->zFts5Tbl + ); + rc = SQLITE_ERROR; + } + }else{ + rc = sqlite3Fts5FlushToDisk(pFts5); } } if( rc==SQLITE_OK ){ - int nByte = pConfig->nCol * sizeof(i64) * 2 + sizeof(Fts5VocabCursor); + int nByte = pFts5->pConfig->nCol * sizeof(i64)*2 + sizeof(Fts5VocabCursor); pCsr = (Fts5VocabCursor*)sqlite3Fts5MallocZero(&rc, nByte); } if( pCsr ){ - pCsr->pIndex = pIndex; + pCsr->pFts5 = pFts5; pCsr->pStmt = pStmt; - pCsr->pConfig = pConfig; pCsr->aCnt = (i64*)&pCsr[1]; - pCsr->aDoc = &pCsr->aCnt[pConfig->nCol]; + pCsr->aDoc = &pCsr->aCnt[pFts5->pConfig->nCol]; }else{ sqlite3_finalize(pStmt); } @@ -219840,6 +221150,7 @@ static void fts5VocabResetCursor(Fts5VocabCursor *pCsr){ sqlite3_free(pCsr->zLeTerm); pCsr->nLeTerm = -1; pCsr->zLeTerm = 0; + pCsr->bEof = 0; } /* @@ -219878,7 +221189,7 @@ static int fts5VocabInstanceNewTerm(Fts5VocabCursor *pCsr){ } static int fts5VocabInstanceNext(Fts5VocabCursor *pCsr){ - int eDetail = pCsr->pConfig->eDetail; + int eDetail = pCsr->pFts5->pConfig->eDetail; int rc = SQLITE_OK; Fts5IndexIter *pIter = pCsr->pIter; i64 *pp = &pCsr->iInstPos; @@ -219913,7 +221224,7 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor; Fts5VocabTable *pTab = (Fts5VocabTable*)pCursor->pVtab; int rc = SQLITE_OK; - int nCol = pCsr->pConfig->nCol; + int nCol = pCsr->pFts5->pConfig->nCol; pCsr->rowid++; @@ -219935,6 +221246,7 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ int nTerm; zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm); + assert( nTerm>=0 ); if( pCsr->nLeTerm>=0 ){ int nCmp = MIN(nTerm, pCsr->nLeTerm); int bCmp = memcmp(pCsr->zLeTerm, zTerm, nCmp); @@ -219951,7 +221263,7 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ assert( pTab->eType==FTS5_VOCAB_COL || pTab->eType==FTS5_VOCAB_ROW ); while( rc==SQLITE_OK ){ - int eDetail = pCsr->pConfig->eDetail; + int eDetail = pCsr->pFts5->pConfig->eDetail; const u8 *pPos; int nPos; /* Position list */ i64 iPos = 0; /* 64-bit position read from poslist */ int iOff = 0; /* Current offset within position list */ @@ -219974,7 +221286,6 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ int iCol = -1; while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){ int ii = FTS5_POS2COLUMN(iPos); - pCsr->aCnt[ii]++; if( iCol!=ii ){ if( ii>=nCol ){ rc = FTS5_CORRUPT; @@ -219983,6 +221294,7 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ pCsr->aDoc[ii]++; iCol = ii; } + pCsr->aCnt[ii]++; } }else if( eDetail==FTS5_DETAIL_COLUMNS ){ while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff,&iPos) ){ @@ -220011,7 +221323,9 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ if( rc==SQLITE_OK ){ zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm); - if( nTerm!=pCsr->term.n || memcmp(zTerm, pCsr->term.p, nTerm) ){ + if( nTerm!=pCsr->term.n + || (nTerm>0 && memcmp(zTerm, pCsr->term.p, nTerm)) + ){ break; } if( sqlite3Fts5IterEof(pCsr->pIter) ) break; @@ -220022,7 +221336,7 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ if( rc==SQLITE_OK && pCsr->bEof==0 && pTab->eType==FTS5_VOCAB_COL ){ while( pCsr->aDoc[pCsr->iCol]==0 ) pCsr->iCol++; - assert( pCsr->iCol<pCsr->pConfig->nCol ); + assert( pCsr->iCol<pCsr->pFts5->pConfig->nCol ); } return rc; } @@ -220069,6 +221383,7 @@ static int fts5VocabFilterMethod( } if( pLe ){ const char *zCopy = (const char *)sqlite3_value_text(pLe); + if( zCopy==0 ) zCopy = ""; pCsr->nLeTerm = sqlite3_value_bytes(pLe); pCsr->zLeTerm = sqlite3_malloc(pCsr->nLeTerm+1); if( pCsr->zLeTerm==0 ){ @@ -220080,14 +221395,15 @@ static int fts5VocabFilterMethod( } if( rc==SQLITE_OK ){ - rc = sqlite3Fts5IndexQuery(pCsr->pIndex, zTerm, nTerm, f, 0, &pCsr->pIter); + Fts5Index *pIndex = pCsr->pFts5->pIndex; + rc = sqlite3Fts5IndexQuery(pIndex, zTerm, nTerm, f, 0, &pCsr->pIter); } if( rc==SQLITE_OK && eType==FTS5_VOCAB_INSTANCE ){ rc = fts5VocabInstanceNewTerm(pCsr); } - if( rc==SQLITE_OK - && !pCsr->bEof - && (eType!=FTS5_VOCAB_INSTANCE || pCsr->pConfig->eDetail!=FTS5_DETAIL_NONE) + if( rc==SQLITE_OK && !pCsr->bEof + && (eType!=FTS5_VOCAB_INSTANCE + || pCsr->pFts5->pConfig->eDetail!=FTS5_DETAIL_NONE) ){ rc = fts5VocabNextMethod(pCursor); } @@ -220110,7 +221426,7 @@ static int fts5VocabColumnMethod( int iCol /* Index of column to read value from */ ){ Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor; - int eDetail = pCsr->pConfig->eDetail; + int eDetail = pCsr->pFts5->pConfig->eDetail; int eType = ((Fts5VocabTable*)(pCursor->pVtab))->eType; i64 iVal = 0; @@ -220122,7 +221438,7 @@ static int fts5VocabColumnMethod( assert( iCol==1 || iCol==2 || iCol==3 ); if( iCol==1 ){ if( eDetail!=FTS5_DETAIL_NONE ){ - const char *z = pCsr->pConfig->azCol[pCsr->iCol]; + const char *z = pCsr->pFts5->pConfig->azCol[pCsr->iCol]; sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC); } }else if( iCol==2 ){ @@ -220150,8 +221466,8 @@ static int fts5VocabColumnMethod( }else if( eDetail==FTS5_DETAIL_COLUMNS ){ ii = (int)pCsr->iInstPos; } - if( ii>=0 && ii<pCsr->pConfig->nCol ){ - const char *z = pCsr->pConfig->azCol[ii]; + if( ii>=0 && ii<pCsr->pFts5->pConfig->nCol ){ + const char *z = pCsr->pFts5->pConfig->azCol[ii]; sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC); } break; @@ -220524,9 +221840,9 @@ SQLITE_API int sqlite3_stmt_init( #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */ /************** End of stmt.c ************************************************/ -#if __LINE__!=220527 +#if __LINE__!=221843 #undef SQLITE_SOURCE_ID -#define SQLITE_SOURCE_ID "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238alt2" +#define SQLITE_SOURCE_ID "2019-02-08 13:17:39 0eca3dd3d38b31c92b49ca2d311128b74584714d9e7de895b1a6286ef959alt2" #endif /* Return the source-id for this library */ SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } diff --git a/src/3rdparty/sqlite/sqlite3.h b/src/3rdparty/sqlite/sqlite3.h index f36ae57a64..686aa8b739 100644 --- a/src/3rdparty/sqlite/sqlite3.h +++ b/src/3rdparty/sqlite/sqlite3.h @@ -123,9 +123,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.26.0" -#define SQLITE_VERSION_NUMBER 3026000 -#define SQLITE_SOURCE_ID "2018-12-01 12:34:55 bf8c1b2b7a5960c282e543b9c293686dccff272512d08865f4600fb58238b4f9" +#define SQLITE_VERSION "3.27.1" +#define SQLITE_VERSION_NUMBER 3027001 +#define SQLITE_SOURCE_ID "2019-02-08 13:17:39 0eca3dd3d38b31c92b49ca2d311128b74584714d9e7de895b1a6286ef959a1dd" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -823,6 +823,15 @@ struct sqlite3_io_methods { ** file space based on this hint in order to help writes to the database ** file run faster. ** +** <li>[[SQLITE_FCNTL_SIZE_LIMIT]] +** The [SQLITE_FCNTL_SIZE_LIMIT] opcode is used by in-memory VFS that +** implements [sqlite3_deserialize()] to set an upper bound on the size +** of the in-memory database. The argument is a pointer to a [sqlite3_int64]. +** If the integer pointed to is negative, then it is filled in with the +** current limit. Otherwise the limit is set to the larger of the value +** of the integer pointed to and the current database size. The integer +** pointed to is set to the new limit. +** ** <li>[[SQLITE_FCNTL_CHUNK_SIZE]] ** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS ** extends and truncates the database file in chunks of a size specified @@ -1131,6 +1140,7 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33 #define SQLITE_FCNTL_LOCK_TIMEOUT 34 #define SQLITE_FCNTL_DATA_VERSION 35 +#define SQLITE_FCNTL_SIZE_LIMIT 36 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE @@ -1972,6 +1982,17 @@ struct sqlite3_mem_methods { ** negative value for this option restores the default behaviour. ** This option is only available if SQLite is compiled with the ** [SQLITE_ENABLE_SORTER_REFERENCES] compile-time option. +** +** [[SQLITE_CONFIG_MEMDB_MAXSIZE]] +** <dt>SQLITE_CONFIG_MEMDB_MAXSIZE +** <dd>The SQLITE_CONFIG_MEMDB_MAXSIZE option accepts a single parameter +** [sqlite3_int64] parameter which is the default maximum size for an in-memory +** database created using [sqlite3_deserialize()]. This default maximum +** size can be adjusted up or down for individual databases using the +** [SQLITE_FCNTL_SIZE_LIMIT] [sqlite3_file_control|file-control]. If this +** configuration setting is never used, then the default maximum is determined +** by the [SQLITE_MEMDB_DEFAULT_MAXSIZE] compile-time option. If that +** compile-time option is not set, then the default maximum is 1073741824. ** </dl> */ #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ @@ -2002,6 +2023,7 @@ struct sqlite3_mem_methods { #define SQLITE_CONFIG_STMTJRNL_SPILL 26 /* int nByte */ #define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */ #define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */ +#define SQLITE_CONFIG_MEMDB_MAXSIZE 29 /* sqlite3_int64 */ /* ** CAPI3REF: Database Connection Configuration Options @@ -2991,9 +3013,9 @@ SQLITE_API int sqlite3_set_authorizer( ** time is in units of nanoseconds, however the current implementation ** is only capable of millisecond resolution so the six least significant ** digits in the time are meaningless. Future versions of SQLite -** might provide greater resolution on the profiler callback. The -** sqlite3_profile() function is considered experimental and is -** subject to change in future versions of SQLite. +** might provide greater resolution on the profiler callback. Invoking +** either [sqlite3_trace()] or [sqlite3_trace_v2()] will cancel the +** profile callback. */ SQLITE_API SQLITE_DEPRECATED void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); @@ -3407,6 +3429,8 @@ SQLITE_API int sqlite3_open_v2( ** is not a database file pathname pointer that SQLite passed into the xOpen ** VFS method, then the behavior of this routine is undefined and probably ** undesirable. +** +** See the [URI filename] documentation for additional information. */ SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam); SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault); @@ -3629,18 +3653,23 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); ** deplete the limited store of lookaside memory. Future versions of ** SQLite may act on this hint differently. ** -** [[SQLITE_PREPARE_NORMALIZE]] ^(<dt>SQLITE_PREPARE_NORMALIZE</dt> -** <dd>The SQLITE_PREPARE_NORMALIZE flag indicates that a normalized -** representation of the SQL statement should be calculated and then -** associated with the prepared statement, which can be obtained via -** the [sqlite3_normalized_sql()] interface.)^ The semantics used to -** normalize a SQL statement are unspecified and subject to change. -** At a minimum, literal values will be replaced with suitable -** placeholders. +** [[SQLITE_PREPARE_NORMALIZE]] <dt>SQLITE_PREPARE_NORMALIZE</dt> +** <dd>The SQLITE_PREPARE_NORMALIZE flag is a no-op. This flag used +** to be required for any prepared statement that wanted to use the +** [sqlite3_normalized_sql()] interface. However, the +** [sqlite3_normalized_sql()] interface is now available to all +** prepared statements, regardless of whether or not they use this +** flag. +** +** [[SQLITE_PREPARE_NO_VTAB]] <dt>SQLITE_PREPARE_NO_VTAB</dt> +** <dd>The SQLITE_PREPARE_NO_VTAB flag causes the SQL compiler +** to return an error (error code SQLITE_ERROR) if the statement uses +** any virtual tables. ** </dl> */ #define SQLITE_PREPARE_PERSISTENT 0x01 #define SQLITE_PREPARE_NORMALIZE 0x02 +#define SQLITE_PREPARE_NO_VTAB 0x04 /* ** CAPI3REF: Compiling An SQL Statement @@ -9996,7 +10025,7 @@ SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter); ** sqlite3changeset_next() is called on the iterator or until the ** conflict-handler function returns. If pnCol is not NULL, then *pnCol is ** set to the number of columns in the table affected by the change. If -** pbIncorrect is not NULL, then *pbIndirect is set to true (1) if the change +** pbIndirect is not NULL, then *pbIndirect is set to true (1) if the change ** is an indirect change, or false (0) otherwise. See the documentation for ** [sqlite3session_indirect()] for a description of direct and indirect ** changes. Finally, if pOp is not NULL, then *pOp is set to one of @@ -11230,12 +11259,8 @@ struct Fts5PhraseIter { ** ** Usually, output parameter *piPhrase is set to the phrase number, *piCol ** to the column in which it occurs and *piOff the token offset of the -** first token of the phrase. The exception is if the table was created -** with the offsets=0 option specified. In this case *piOff is always -** set to -1. -** -** Returns SQLITE_OK if successful, or an error code (i.e. SQLITE_NOMEM) -** if an error occurs. +** first token of the phrase. Returns SQLITE_OK if successful, or an error +** code (i.e. SQLITE_NOMEM) if an error occurs. ** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. @@ -11524,11 +11549,11 @@ struct Fts5ExtensionApi { ** the tokenizer substitutes "first" for "1st" and the query works ** as expected. ** -** <li> By adding multiple synonyms for a single term to the FTS index. -** In this case, when tokenizing query text, the tokenizer may -** provide multiple synonyms for a single term within the document. -** FTS5 then queries the index for each synonym individually. For -** example, faced with the query: +** <li> By querying the index for all synonyms of each query term +** separately. In this case, when tokenizing query text, the +** tokenizer may provide multiple synonyms for a single term +** within the document. FTS5 then queries the index for each +** synonym individually. For example, faced with the query: ** ** <codeblock> ** ... MATCH 'first place'</codeblock> @@ -11552,7 +11577,7 @@ struct Fts5ExtensionApi { ** "place". ** ** This way, even if the tokenizer does not provide synonyms -** when tokenizing query text (it should not - to do would be +** when tokenizing query text (it should not - to do so would be ** inefficient), it doesn't matter if the user queries for ** 'first + place' or '1st + place', as there are entries in the ** FTS index corresponding to both forms of the first token. From aed1e2c49f0a9ad06732d39f70b513ad2fcfdaa3 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann <joerg.bornemann@qt.io> Date: Tue, 12 Feb 2019 14:21:03 +0100 Subject: [PATCH 1125/1650] Fix warning in tst_qopengl.cpp MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes warning: unused parameter ‘glFormat’ Change-Id: I4865300fb99ea5392b96f8e9f4f594f15f18625c Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> --- tests/auto/gui/qopengl/tst_qopengl.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/gui/qopengl/tst_qopengl.cpp b/tests/auto/gui/qopengl/tst_qopengl.cpp index f1360b9efe..ede1e58a53 100644 --- a/tests/auto/gui/qopengl/tst_qopengl.cpp +++ b/tests/auto/gui/qopengl/tst_qopengl.cpp @@ -642,6 +642,8 @@ static bool supportsInternalFboFormat(QOpenGLContext *ctx, int glFormat) return false; } } +#else + Q_UNUSED(glFormat); #endif return true; } From 1a36cf5ea1a8ab10658919892f29bbc3d337d1d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= <tor.arne.vestbo@qt.io> Date: Fri, 4 Jan 2019 15:18:39 +0100 Subject: [PATCH 1126/1650] Deduplicate QWidgetPrivate::invalidateBuffer Now that MSVC (presumably) supports templates, we can merge the QRect and QRegion versions of the functions into one. The function has been renamed to invalidateBackingStore to better reflect what it's doing. Change-Id: I0e94a0cabd286cf97f2ba718a42ee0425f59d3ec Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> --- src/widgets/kernel/qwidget.cpp | 26 ++-- src/widgets/kernel/qwidget_p.h | 9 +- src/widgets/kernel/qwidgetbackingstore.cpp | 125 +++++++----------- .../widgets/kernel/qwidget/tst_qwidget.cpp | 14 +- 4 files changed, 73 insertions(+), 101 deletions(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index b4ae994375..b91d637766 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -5317,7 +5317,7 @@ void QWidget::setGraphicsEffect(QGraphicsEffect *effect) return; if (d->graphicsEffect) { - d->invalidateBuffer(rect()); + d->invalidateBackingStore(rect()); delete d->graphicsEffect; d->graphicsEffect = 0; } @@ -7340,11 +7340,11 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) if (renderToTexture) { QRegion updateRegion(q->geometry()); updateRegion += QRect(oldPos, olds); - q->parentWidget()->d_func()->invalidateBuffer(updateRegion); + q->parentWidget()->d_func()->invalidateBackingStore(updateRegion); } else if (isMove && !isResize) { moveRect(QRect(oldPos, olds), x - oldPos.x(), y - oldPos.y()); } else { - invalidateBuffer_resizeHelper(oldPos, olds); + invalidateBackingStore_resizeHelper(oldPos, olds); } } } @@ -8106,7 +8106,7 @@ void QWidgetPrivate::show_sys() QWidgetWindow *window = windowHandle(); if (q->testAttribute(Qt::WA_DontShowOnScreen)) { - invalidateBuffer(q->rect()); + invalidateBackingStore(q->rect()); q->setAttribute(Qt::WA_Mapped); // add our window the modal window list (native dialogs) if (window && q->isWindow() @@ -8149,7 +8149,7 @@ void QWidgetPrivate::show_sys() #ifndef QT_NO_CURSOR qt_qpa_set_cursor(q, false); // Needed in case cursor was set before show #endif - invalidateBuffer(q->rect()); + invalidateBackingStore(q->rect()); window->setNativeWindowVisibility(true); // Was the window moved by the Window system or QPlatformWindow::initialGeometry() ? if (window->isTopLevel()) { @@ -8263,12 +8263,12 @@ void QWidgetPrivate::hide_sys() QWidget *p = q->parentWidget(); if (p &&p->isVisible()) { if (renderToTexture) - p->d_func()->invalidateBuffer(q->geometry()); + p->d_func()->invalidateBackingStore(q->geometry()); else - invalidateBuffer(q->rect()); + invalidateBackingStore(q->rect()); } } else { - invalidateBuffer(q->rect()); + invalidateBackingStore(q->rect()); } if (window) @@ -11901,7 +11901,7 @@ void QWidget::raise() QRegion region(rect()); d->subtractOpaqueSiblings(region); - d->invalidateBuffer(region); + d->invalidateBackingStore(region); } if (testAttribute(Qt::WA_WState_Created)) d->raise_sys(); @@ -11921,7 +11921,7 @@ void QWidgetPrivate::raise_sys() } else if (renderToTexture) { if (QWidget *p = q->parentWidget()) { setDirtyOpaqueRegion(); - p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry())); + p->d_func()->invalidateBackingStore(effectiveRectFor(q->geometry())); } } } @@ -11971,7 +11971,7 @@ void QWidgetPrivate::lower_sys() q->windowHandle()->lower(); } else if (QWidget *p = q->parentWidget()) { setDirtyOpaqueRegion(); - p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry())); + p->d_func()->invalidateBackingStore(effectiveRectFor(q->geometry())); } } @@ -12015,7 +12015,7 @@ void QWidgetPrivate::stackUnder_sys(QWidget*) Q_Q(QWidget); if (QWidget *p = q->parentWidget()) { setDirtyOpaqueRegion(); - p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry())); + p->d_func()->invalidateBackingStore(effectiveRectFor(q->geometry())); } } @@ -12457,7 +12457,7 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows) d->aboutToDestroy(); if (!isWindow() && parentWidget()) - parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry())); + parentWidget()->d_func()->invalidateBackingStore(d->effectiveRectFor(geometry())); d->deactivateWidgetCleanup(); if ((windowType() == Qt::Popup) && qApp) diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index ab5dc6bfba..60612e9b52 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -452,10 +452,11 @@ public: void scrollChildren(int dx, int dy); void moveRect(const QRect &, int dx, int dy); void scrollRect(const QRect &, int dx, int dy); - void invalidateBuffer_resizeHelper(const QPoint &oldPos, const QSize &oldSize); - // ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore). - void invalidateBuffer(const QRegion &); - void invalidateBuffer(const QRect &); + void invalidateBackingStore_resizeHelper(const QPoint &oldPos, const QSize &oldSize); + + template <class T> + void invalidateBackingStore(const T &); + QRegion overlappedRegion(const QRect &rect, bool breakAfterFirst = false) const; void syncBackingStore(); void syncBackingStore(const QRegion ®ion); diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index a32eb2a03b..f4d1dab84e 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -859,11 +859,11 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy) if (!extra || !extra->hasMask) { parentR -= newRect; } else { - // invalidateBuffer() excludes anything outside the mask + // invalidateBackingStore() excludes anything outside the mask parentR += newRect & clipR; } - pd->invalidateBuffer(parentR); - invalidateBuffer((newRect & clipR).translated(-data.crect.topLeft())); + pd->invalidateBackingStore(parentR); + invalidateBackingStore((newRect & clipR).translated(-data.crect.topLeft())); } else { QWidgetBackingStore *wbs = x->backingStoreTracker.data(); @@ -894,7 +894,7 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy) if (childUpdatesEnabled) { if (!overlappedExpose.isEmpty()) { overlappedExpose.translate(-data.crect.topLeft()); - invalidateBuffer(overlappedExpose); + invalidateBackingStore(overlappedExpose); } if (!childExpose.isEmpty()) { childExpose.translate(-data.crect.topLeft()); @@ -944,9 +944,9 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy) if (!overlappedRegion(scrollRect.translated(data.crect.topLeft()), true).isEmpty()) { QRegion region(scrollRect); subtractOpaqueSiblings(region); - invalidateBuffer(region); + invalidateBackingStore(region); }else { - invalidateBuffer(scrollRect); + invalidateBackingStore(scrollRect); } } else { const QPoint toplevelOffset = q->mapTo(tlw, QPoint()); @@ -987,7 +987,7 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy) return; if (!overlappedExpose.isEmpty()) - invalidateBuffer(overlappedExpose); + invalidateBackingStore(overlappedExpose); if (!childExpose.isEmpty()) { wbs->markDirty(childExpose, q); isScrolled = true; @@ -1471,26 +1471,11 @@ void QWidgetBackingStore::flush(QWidget *widget) dirtyOnScreenWidgets->clear(); } -static inline bool discardInvalidateBufferRequest(QWidget *widget, QTLWExtra *tlwExtra) -{ - Q_ASSERT(widget); - if (QApplication::closingDown()) - return true; - - if (!tlwExtra || tlwExtra->inTopLevelResize || !tlwExtra->backingStore) - return true; - - if (!widget->isVisible() || !widget->updatesEnabled()) - return true; - - return false; -} - /*! - Invalidates the buffer when the widget is resized. + Invalidates the backing store when the widget is resized. Static areas are never invalidated unless absolutely needed. */ -void QWidgetPrivate::invalidateBuffer_resizeHelper(const QPoint &oldPos, const QSize &oldSize) +void QWidgetPrivate::invalidateBackingStore_resizeHelper(const QPoint &oldPos, const QSize &oldSize) { Q_Q(QWidget); Q_ASSERT(!q->isWindow()); @@ -1515,10 +1500,10 @@ void QWidgetPrivate::invalidateBuffer_resizeHelper(const QPoint &oldPos, const Q if (hasStaticChildren) { QRegion dirty(newWidgetRect); dirty -= staticChildren; - invalidateBuffer(dirty); + invalidateBackingStore(dirty); } else { // Entire widget needs repaint. - invalidateBuffer(newWidgetRect); + invalidateBackingStore(newWidgetRect); } if (!parentAreaExposed) @@ -1530,14 +1515,14 @@ void QWidgetPrivate::invalidateBuffer_resizeHelper(const QPoint &oldPos, const Q parentExpose &= QRect(oldPos, oldSize); if (hasStaticChildren) parentExpose -= data.crect; // Offset is unchanged, safe to do this. - q->parentWidget()->d_func()->invalidateBuffer(parentExpose); + q->parentWidget()->d_func()->invalidateBackingStore(parentExpose); } else { if (hasStaticChildren && !graphicsEffect) { QRegion parentExpose(QRect(oldPos, oldSize)); parentExpose -= data.crect; // Offset is unchanged, safe to do this. - q->parentWidget()->d_func()->invalidateBuffer(parentExpose); + q->parentWidget()->d_func()->invalidateBackingStore(parentExpose); } else { - q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(QRect(oldPos, oldSize))); + q->parentWidget()->d_func()->invalidateBackingStore(effectiveRectFor(QRect(oldPos, oldSize))); } } return; @@ -1558,7 +1543,7 @@ void QWidgetPrivate::invalidateBuffer_resizeHelper(const QPoint &oldPos, const Q if (!sizeDecreased || !oldWidgetRect.contains(newWidgetRect)) { QRegion newVisible(newWidgetRect); newVisible -= oldWidgetRect; - invalidateBuffer(newVisible); + invalidateBackingStore(newVisible); } if (!parentAreaExposed) @@ -1570,74 +1555,56 @@ void QWidgetPrivate::invalidateBuffer_resizeHelper(const QPoint &oldPos, const Q QRegion parentExpose(oldRect); parentExpose &= extra->mask.translated(oldPos); parentExpose -= (extra->mask.translated(data.crect.topLeft()) & data.crect); - q->parentWidget()->d_func()->invalidateBuffer(parentExpose); + q->parentWidget()->d_func()->invalidateBackingStore(parentExpose); } else { QRegion parentExpose(oldRect); parentExpose -= data.crect; - q->parentWidget()->d_func()->invalidateBuffer(parentExpose); + q->parentWidget()->d_func()->invalidateBackingStore(parentExpose); } } /*! - Invalidates the \a rgn (in widget's coordinates) of the backing store, i.e. - all widgets intersecting with the region will be repainted when the backing store - is synced. - - ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore). + Invalidates the \a r (in widget's coordinates) of the backing store, i.e. + all widgets intersecting with the region will be repainted when the backing + store is synced. */ -void QWidgetPrivate::invalidateBuffer(const QRegion &rgn) +template <class T> +void QWidgetPrivate::invalidateBackingStore(const T &r) { + if (r.isEmpty()) + return; + + if (QApplication::closingDown()) + return; + Q_Q(QWidget); + if (!q->isVisible() || !q->updatesEnabled()) + return; QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData(); - if (discardInvalidateBufferRequest(q, tlwExtra) || rgn.isEmpty()) + if (!tlwExtra || tlwExtra->inTopLevelResize || !tlwExtra->backingStore) return; - QRegion wrgn(rgn); - wrgn &= clipRect(); - if (!graphicsEffect && extra && extra->hasMask) - wrgn &= extra->mask; - if (wrgn.isEmpty()) + T clipped(r); + clipped &= clipRect(); + if (clipped.isEmpty()) return; - tlwExtra->backingStoreTracker->markDirty(wrgn, q, + if (!graphicsEffect && extra && extra->hasMask) { + QRegion masked(extra->mask); + masked &= clipped; + if (masked.isEmpty()) + return; + + tlwExtra->backingStoreTracker->markDirty(masked, q, + QWidgetBackingStore::UpdateLater, QWidgetBackingStore::BufferInvalid); + } else { + tlwExtra->backingStoreTracker->markDirty(clipped, q, QWidgetBackingStore::UpdateLater, QWidgetBackingStore::BufferInvalid); -} - -/*! - This function is equivalent to calling invalidateBuffer(QRegion(rect), ...), but - is more efficient as it eliminates QRegion operations/allocations and can - use the rect more precisely for additional cut-offs. - - ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore). -*/ -void QWidgetPrivate::invalidateBuffer(const QRect &rect) -{ - Q_Q(QWidget); - - QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData(); - if (discardInvalidateBufferRequest(q, tlwExtra) || rect.isEmpty()) - return; - - QRect wRect(rect); - wRect &= clipRect(); - if (wRect.isEmpty()) - return; - - if (graphicsEffect || !extra || !extra->hasMask) { - tlwExtra->backingStoreTracker->markDirty(wRect, q, - QWidgetBackingStore::UpdateLater, QWidgetBackingStore::BufferInvalid); - return; } - - QRegion wRgn(extra->mask); - wRgn &= wRect; - if (wRgn.isEmpty()) - return; - - tlwExtra->backingStoreTracker->markDirty(wRgn, q, - QWidgetBackingStore::UpdateLater, QWidgetBackingStore::BufferInvalid); } +// Needed by tst_QWidget +template Q_AUTOTEST_EXPORT void QWidgetPrivate::invalidateBackingStore<QRect>(const QRect &r); void QWidgetPrivate::repaint_sys(const QRegion &rgn) { diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 93c8b095e0..2d4d5249d2 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -321,7 +321,9 @@ private slots: void setMaskInResizeEvent(); void moveInResizeEvent(); - void immediateRepaintAfterInvalidateBuffer(); +#ifdef QT_BUILD_INTERNAL + void immediateRepaintAfterInvalidateBackingStore(); +#endif void effectiveWinId(); void effectiveWinId2(); @@ -8215,7 +8217,7 @@ void tst_QWidget::resizeInPaintEvent() widget.resizeInPaintEvent = true; // This will call resize in the paintEvent, which in turn will call - // invalidateBuffer() and a new update request should be posted. + // invalidateBackingStore() and a new update request should be posted. widget.repaint(); QCOMPARE(widget.numPaintEvents, 1); widget.numPaintEvents = 0; @@ -8370,7 +8372,8 @@ void tst_QWidget::moveInResizeEvent() QTRY_COMPARE(testWidget.geometry(), expectedGeometry); } -void tst_QWidget::immediateRepaintAfterInvalidateBuffer() +#ifdef QT_BUILD_INTERNAL +void tst_QWidget::immediateRepaintAfterInvalidateBackingStore() { if (m_platform != QStringLiteral("xcb") && m_platform != QStringLiteral("windows")) QSKIP("We don't support immediate repaint right after show on other platforms."); @@ -8384,7 +8387,7 @@ void tst_QWidget::immediateRepaintAfterInvalidateBuffer() // Marks the area covered by the widget as dirty in the backing store and // posts an UpdateRequest event. - qt_widget_private(widget.data())->invalidateBuffer(widget->rect()); + qt_widget_private(widget.data())->invalidateBackingStore(widget->rect()); QCOMPARE(widget->numPaintEvents, 0); // The entire widget is already dirty, but this time we want to update immediately @@ -8393,6 +8396,7 @@ void tst_QWidget::immediateRepaintAfterInvalidateBuffer() widget->repaint(); QCOMPARE(widget->numPaintEvents, 1); } +#endif void tst_QWidget::effectiveWinId() { @@ -9628,7 +9632,7 @@ public: { if (!static_cast<QWidgetPrivate*>(d_ptr.data())->maybeBackingStore()) { static_cast<QWidgetPrivate*>(d_ptr.data())->topData()->backingStoreTracker.create(this); - static_cast<QWidgetPrivate*>(d_ptr.data())->invalidateBuffer(this->rect()); + static_cast<QWidgetPrivate*>(d_ptr.data())->invalidateBackingStore(this->rect()); repaint(); } } From c4e9eabc309a275efc222f4127f31ba4677259b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= <tor.arne.vestbo@qt.io> Date: Sun, 10 Feb 2019 22:53:02 +0100 Subject: [PATCH 1127/1650] Don't allow backingstore flush to non-raster surfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I8e85706727a8c5f7585e34e3864c8a9f48481b92 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> --- src/gui/painting/qbackingstore.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index 8d71d1c3a9..0dfb52e7c3 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -192,6 +192,17 @@ void QBackingStore::endPaint() d_ptr->platformBackingStore->endPaint(); } +static bool isRasterSurface(QWindow *window) +{ + switch (window->surfaceType()) { + case QSurface::RasterSurface: + case QSurface::RasterGLSurface: + return true; + default: + return false; + }; +} + /*! Flushes the given \a region from the specified \a window onto the screen. @@ -220,6 +231,13 @@ void QBackingStore::flush(const QRegion ®ion, QWindow *window, const QPoint & return; } + if (!isRasterSurface(window)) { + qWarning() << "Attempted flush to non-raster surface" << window << "of type" << window->surfaceType() + << (window->inherits("QWidgetWindow") ? "(consider using Qt::WA_PaintOnScreen to exclude " + "from backingstore sync)" : ""); + return; + } + #ifdef QBACKINGSTORE_DEBUG if (window && window->isTopLevel() && !qt_window_private(window)->receivedExpose) { qWarning().nospace() << "QBackingStore::flush() called with non-exposed window " From df2b76046de4af7a47fa8303d5f261e3c5d120fe Mon Sep 17 00:00:00 2001 From: Dominik Holland <dominik.holland@pelagicore.com> Date: Wed, 7 Nov 2018 10:18:14 +0100 Subject: [PATCH 1128/1650] eglfs: Add vsync support when using NVIDIA eglstreams Similar to the kms backend a flip event handler can be retrieved using the drmEvent API to implement vsync. For this to work the acquire calls need to be done manuallly and the automatic acquiring needs to be disabled. Change-Id: I670d288ef68eb49846108db2a31993c6167d9313 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io> --- .../eglconvenience/qeglstreamconvenience_p.h | 11 ++++ .../qeglfskmsegldeviceintegration.cpp | 50 +++++++++++++++++++ .../qeglfskmsegldeviceintegration.h | 2 + 3 files changed, 63 insertions(+) diff --git a/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h b/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h index c3d3070210..31a79dbc6c 100644 --- a/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h +++ b/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h @@ -131,6 +131,12 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEKHRPROC) (EGLDisplay typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMEROUTPUTEXTPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer); #endif +#ifndef EGL_EXT_stream_acquire_mode +#define EGL_EXT_stream_acquire_mode 1 +#define EGL_CONSUMER_AUTO_ACQUIRE_EXT 0x332B +#define EGL_RESOURCE_BUSY_EXT 0x3353 +#endif + #ifndef EGL_EXT_platform_device #define EGL_PLATFORM_DEVICE_EXT 0x313F #endif @@ -156,6 +162,11 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREATTRIBNVPROC) (EGLDi typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEATTRIBNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); #endif +#ifndef EGL_NV_output_drm_flip_event +#define EGL_NV_output_drm_flip_event 1 +#define EGL_DRM_FLIP_EVENT_DATA_NV 0x333E +#endif + QT_BEGIN_NAMESPACE class QEGLStreamConvenience diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp index ab39af6b80..9f4c9f5703 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp @@ -114,14 +114,18 @@ public: : QEglFSWindow(w) , m_integration(integration) , m_egl_stream(EGL_NO_STREAM_KHR) + , m_framePending(false) { } void invalidateSurface() override; void resetSurface() override; + void flip(); + static void pageFlipHandler(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data); const QEglFSKmsEglDeviceIntegration *m_integration; EGLStreamKHR m_egl_stream; EGLint m_latency; + bool m_framePending; }; void QEglFSKmsEglDeviceWindow::invalidateSurface() @@ -142,6 +146,9 @@ void QEglFSKmsEglDeviceWindow::resetSurface() streamAttribs[streamAttribCount++] = EGL_STREAM_FIFO_LENGTH_KHR; streamAttribs[streamAttribCount++] = fifoLength; } + + streamAttribs[streamAttribCount++] = EGL_CONSUMER_AUTO_ACQUIRE_EXT; + streamAttribs[streamAttribCount++] = EGL_FALSE; streamAttribs[streamAttribCount++] = EGL_NONE; m_egl_stream = m_integration->m_funcs->create_stream(display, streamAttribs); @@ -239,6 +246,49 @@ void QEglFSKmsEglDeviceWindow::resetSurface() qCDebug(qLcEglfsKmsDebug, "Created stream producer surface %p", m_surface); } +void QEglFSKmsEglDeviceWindow::flip() +{ + EGLDisplay display = screen()->display(); + + EGLAttrib acquire_attribs[3] = { EGL_NONE }; + + acquire_attribs[0] = EGL_DRM_FLIP_EVENT_DATA_NV; + acquire_attribs[1] = (EGLAttrib)this; + acquire_attribs[2] = EGL_NONE; + + if (m_egl_stream != EGL_NO_STREAM_KHR) + if (!m_integration->m_funcs->acquire_stream_attrib_nv(display, m_egl_stream, acquire_attribs)) + qWarning("eglStreamConsumerAcquireAttribNV failed: eglError: %x", eglGetError()); + + m_framePending = true; + + while (m_framePending) { + drmEventContext drmEvent; + memset(&drmEvent, 0, sizeof(drmEvent)); + drmEvent.version = 3; + drmEvent.vblank_handler = nullptr; + drmEvent.page_flip_handler = pageFlipHandler; + drmHandleEvent(m_integration->m_device->fd(), &drmEvent); + } +} + +void QEglFSKmsEglDeviceWindow::pageFlipHandler(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data) +{ + Q_UNUSED(fd); + Q_UNUSED(sequence); + Q_UNUSED(tv_sec); + Q_UNUSED(tv_usec); + + QEglFSKmsEglDeviceWindow *window = static_cast<QEglFSKmsEglDeviceWindow*>(user_data); + window->m_framePending = false; +} + +void QEglFSKmsEglDeviceIntegration::presentBuffer(QPlatformSurface *surface) +{ + QEglFSKmsEglDeviceWindow *eglWindow = static_cast<QEglFSKmsEglDeviceWindow*>(surface); + eglWindow->flip(); +} + QEglFSWindow *QEglFSKmsEglDeviceIntegration::createWindow(QWindow *window) const { QEglFSKmsEglDeviceWindow *eglWindow = new QEglFSKmsEglDeviceWindow(window, this); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h index 5819d82ebf..0c64d83b12 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h @@ -62,6 +62,8 @@ public: bool supportsPBuffers() const override; QEglFSWindow *createWindow(QWindow *window) const override; + void presentBuffer(QPlatformSurface *surface); + EGLDeviceEXT eglDevice() const { return m_egl_device; } protected: From dd1a6308719929b0798447244b401376d983cfbf Mon Sep 17 00:00:00 2001 From: Samuel Gaist <samuel.gaist@idiap.ch> Date: Sun, 25 Nov 2018 21:58:47 +0100 Subject: [PATCH 1129/1650] QLineEdit: don't emit editingFinished if nothing was done When a modal dialog is called from a slot connected to the editingFinished signal, the chain of events resulting from the focus returning to this widget will make the editingFinished signal emitted again. This patch uses a new variable to keep track of the fact that there was a modification. Once editingFinished was emitted, that flag is cleared so next time the signal will be emitted again only if a modification was made to the line edit content. [ChangeLog][QtWidget][QLineEdit] Behavior change: now the editingFinished signal is emitted only once after the line edit content was edited. Fixes: QTBUG-40 Change-Id: Ia4760bad8717f1758c3939132c446b4b4c6cd498 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> --- src/widgets/widgets/qlineedit.cpp | 12 ++++++++---- src/widgets/widgets/qlineedit_p.cpp | 7 +++++++ src/widgets/widgets/qlineedit_p.h | 4 +++- .../auto/widgets/widgets/qlineedit/tst_qlineedit.cpp | 10 ++++++++++ 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp index ad3d372bd3..02aa703289 100644 --- a/src/widgets/widgets/qlineedit.cpp +++ b/src/widgets/widgets/qlineedit.cpp @@ -315,7 +315,7 @@ QString QLineEdit::text() const void QLineEdit::setText(const QString& text) { Q_D(QLineEdit); - d->control->setText(text); + d->setText(text); } /*! @@ -1483,8 +1483,11 @@ bool QLineEdit::event(QEvent * e) } else if (e->type() == QEvent::LeaveEditFocus) { d->setCursorVisible(false); d->control->setCursorBlinkEnabled(false); - if (d->control->hasAcceptableInput() || d->control->fixup()) + if (d->edited && (d->control->hasAcceptableInput() + || d->control->fixup())) { emit editingFinished(); + d->edited = false; + } } } #endif @@ -1891,7 +1894,6 @@ void QLineEdit::focusInEvent(QFocusEvent *e) /*!\reimp */ - void QLineEdit::focusOutEvent(QFocusEvent *e) { Q_D(QLineEdit); @@ -1914,8 +1916,10 @@ void QLineEdit::focusOutEvent(QFocusEvent *e) #endif if (reason != Qt::PopupFocusReason || !(QApplication::activePopupWidget() && QApplication::activePopupWidget()->parentWidget() == this)) { - if (hasAcceptableInput() || d->control->fixup()) + if (d->edited && (hasAcceptableInput() || d->control->fixup())) { emit editingFinished(); + d->edited = false; + } } #ifdef QT_KEYPAD_NAVIGATION d->control->setCancelText(QString()); diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp index 2a5a0c34dc..21e70db0ac 100644 --- a/src/widgets/widgets/qlineedit_p.cpp +++ b/src/widgets/widgets/qlineedit_p.cpp @@ -127,6 +127,7 @@ void QLineEditPrivate::_q_handleWindowActivate() void QLineEditPrivate::_q_textEdited(const QString &text) { Q_Q(QLineEdit); + edited = true; emit q->textEdited(text); #if QT_CONFIG(completer) if (control->completer() @@ -272,6 +273,12 @@ void QLineEditPrivate::setCursorVisible(bool visible) q->update(); } +void QLineEditPrivate::setText(const QString& text) +{ + edited = true; + control->setText(text); +} + void QLineEditPrivate::updatePasswordEchoEditing(bool editing) { Q_Q(QLineEdit); diff --git a/src/widgets/widgets/qlineedit_p.h b/src/widgets/widgets/qlineedit_p.h index 12a2f1ddfd..dce5bf605a 100644 --- a/src/widgets/widgets/qlineedit_p.h +++ b/src/widgets/widgets/qlineedit_p.h @@ -151,7 +151,7 @@ public: QLineEditPrivate() : control(0), frame(1), contextMenuEnabled(1), cursorVisible(0), - dragEnabled(0), clickCausedFocus(0), hscroll(0), vscroll(0), + dragEnabled(0), clickCausedFocus(0), edited(0), hscroll(0), vscroll(0), alignment(Qt::AlignLeading | Qt::AlignVCenter), leftTextMargin(0), topTextMargin(0), rightTextMargin(0), bottomTextMargin(0), lastTextSize(0), mouseYThreshold(0) @@ -176,6 +176,7 @@ public: bool inSelection(int x) const; QRect cursorRect() const; void setCursorVisible(bool visible); + void setText(const QString& text); void updatePasswordEchoEditing(bool); @@ -202,6 +203,7 @@ public: uint cursorVisible : 1; uint dragEnabled : 1; uint clickCausedFocus : 1; + uint edited : 1; int hscroll; int vscroll; uint alignment; diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp index 95799905de..7861065de9 100644 --- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp @@ -3613,6 +3613,14 @@ void tst_QLineEdit::task174640_editingFinished() QTRY_VERIFY(le1->hasFocus()); QCOMPARE(editingFinishedSpy.count(), 0); + le2->setFocus(); + QTRY_VERIFY(le2->hasFocus()); + // editingFinished will not be emitted anew because no editing happened + QCOMPARE(editingFinishedSpy.count(), 0); + + le1->setFocus(); + QTRY_VERIFY(le1->hasFocus()); + QTest::keyPress(le1, Qt::Key_Plus); le2->setFocus(); QTRY_VERIFY(le2->hasFocus()); QCOMPARE(editingFinishedSpy.count(), 1); @@ -3632,6 +3640,8 @@ void tst_QLineEdit::task174640_editingFinished() delete testMenu1; QCOMPARE(editingFinishedSpy.count(), 0); QTRY_VERIFY(le1->hasFocus()); + // Ensure le1 has been edited + QTest::keyPress(le1, Qt::Key_Plus); QMenu *testMenu2 = new QMenu(le2); testMenu2->addAction("foo2"); From 568bc974d7d89f8d12bc4877c59e4291fe582e8b Mon Sep 17 00:00:00 2001 From: Kai Koehne <kai.koehne@qt.io> Date: Mon, 11 Feb 2019 12:18:35 +0100 Subject: [PATCH 1130/1650] Remove eval mode The evaluation mode of Qt hasn't been used since quite some time. Let's just remove the remaining logic from the code base. Change-Id: I61a2c432cbae78bf973f882848b3732e27431351 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> Reviewed-by: Iikka Eklund <iikka.eklund@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> --- src/corelib/corelib.pro | 2 - src/corelib/eval.pri | 4 - src/corelib/global/qlibraryinfo.cpp | 5 - src/corelib/kernel/qcoreapplication.cpp | 5 - src/corelib/kernel/qtcore_eval.cpp | 560 ------------------------ src/tools/bootstrap/bootstrap.pro | 2 - src/widgets/kernel/qapplication.cpp | 4 - src/widgets/kernel/qwidget.cpp | 11 - src/widgets/widgets.pro | 2 - 9 files changed, 595 deletions(-) delete mode 100644 src/corelib/eval.pri delete mode 100644 src/corelib/kernel/qtcore_eval.cpp diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro index 181780c475..2323512a30 100644 --- a/src/corelib/corelib.pro +++ b/src/corelib/corelib.pro @@ -67,8 +67,6 @@ integrity { QMAKE_DYNAMIC_LIST_FILE = $$PWD/QtCore.dynlist -contains(DEFINES,QT_EVAL):include(eval.pri) - HOST_BINS = $$[QT_HOST_BINS] host_bins.name = host_bins host_bins.variable = HOST_BINS diff --git a/src/corelib/eval.pri b/src/corelib/eval.pri deleted file mode 100644 index efda56b16a..0000000000 --- a/src/corelib/eval.pri +++ /dev/null @@ -1,4 +0,0 @@ -SOURCES += \ - $$QT_SOURCE_TREE/src/corelib/kernel/qtcore_eval.cpp -INCLUDEPATH += \ - $$QT_BUILD_TREE/src/corelib/global diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index 4119012d85..88cc5b0b01 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -717,11 +717,6 @@ void qt_core_boilerplate() QT_PREPEND_NAMESPACE(qDumpCPUFeatures)(); -#ifdef QT_EVAL - extern void qt_core_eval_init(QCoreApplicationPrivate::Type); - qt_core_eval_init(QCoreApplicationPrivate::Tty); -#endif - exit(0); } diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index e6d1d26f3c..7524d2e6c4 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -857,11 +857,6 @@ void QCoreApplicationPrivate::init() eventDispatcherReady(); #endif -#ifdef QT_EVAL - extern void qt_core_eval_init(QCoreApplicationPrivate::Type); - qt_core_eval_init(application_type); -#endif - processCommandLineArguments(); qt_call_pre_routines(); diff --git a/src/corelib/kernel/qtcore_eval.cpp b/src/corelib/kernel/qtcore_eval.cpp deleted file mode 100644 index 5437210699..0000000000 --- a/src/corelib/kernel/qtcore_eval.cpp +++ /dev/null @@ -1,560 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <qcoreevent.h> -#include <qdatetime.h> -#include <qlibraryinfo.h> -#include <qobject.h> -#include <qcoreapplication.h> -#include <private/qcoreapplication_p.h> - -#include "stdio.h" -#include "stdlib.h" - -QT_BEGIN_NAMESPACE - -#include "qconfig_eval.cpp" - -static const char boilerplate_supported_but_time_limited[] = - "\nQt %1 Evaluation License\n" - "Copyright (C) 2016 The Qt Company Ltd.\n" - "This trial version may only be used for evaluation purposes\n" - "and will shut down after 120 minutes.\n" - "Registered to:\n" - " Licensee: %2\n\n" - "The evaluation expires in %4 days\n\n" - "Contact http://www.qt.io/contact-us for pricing and purchasing information.\n"; - -static const char boilerplate_supported[] = - "\nQt %1 Evaluation License\n" - "Copyright (C) 2016 The Qt Company Ltd.\n" - "This trial version may only be used for evaluation purposes\n" - "Registered to:\n" - " Licensee: %2\n\n" - "The evaluation expires in %4 days\n\n" - "Contact http://www.qt.io/contact-us for pricing and purchasing information.\n"; - -static const char boilerplate_expired[] = - "This software is using the trial version of the Qt GUI toolkit.\n" - "The trial period has expired. If you need more time to\n" - "evaluate Qt, or if you have any questions about Qt, contact us\n" - "at: http://www.qt.io/contact-us.\n\n"; - -static const char will_shutdown_1min[] = - "\nThe evaluation of Qt will SHUT DOWN in 1 minute.\n" - "Contact http://www.qt.io/contact-us for pricing and purchasing information.\n"; - -static const char will_shutdown_now[] = - "\nThe evaluation of Qt has now reached its automatic\n" - "timeout and will shut down.\n" - "Contact http://www.qt.io/contact-us for pricing and purchasing information.\n"; - -enum EvaluationStatus { - EvaluationNotSupported = 0, - EvaluationSupportedButTimeLimited, - EvaluationSupported -}; - -static EvaluationStatus qt_eval_is_supported() -{ - const volatile char *const license_key = qt_eval_key_data + 12; - - // fast fail - if (!qt_eval_key_data[0] || !*license_key) - return EvaluationNotSupported; - - // is this an unsupported evaluation? - const volatile char *typecode = license_key; - int field = 2; - for ( ; field && *typecode; ++typecode) - if (*typecode == '-') - --field; - - if (!field && typecode[1] == '4' && typecode[2] == 'M') { - if (typecode[0] == 'Q') - return EvaluationSupportedButTimeLimited; - else if (typecode[0] == 'R' || typecode[0] == 'Z') - return EvaluationSupported; - } - return EvaluationNotSupported; -} - -static int qt_eval_days_left() -{ - const volatile char *const expiry_date = qt_eval_expiry_date + 12; - - QDate today = QDate::currentDate(); - QDate lastday = QDate::fromString( - QString::fromLatin1(const_cast<const char*>(expiry_date)), Qt::ISODate); - return today.daysTo(lastday); -} - -static bool qt_eval_is_expired() -{ - return qt_eval_days_left() < 0; -} - -static QString qt_eval_string() -{ - const char *msg; - switch (qt_eval_is_supported()) { - case EvaluationSupportedButTimeLimited: - msg = boilerplate_supported_but_time_limited; - break; - case EvaluationSupported: - msg = boilerplate_supported; - break; - default: - return QString(); - } - - return QString::fromLatin1(msg) - .arg(QLatin1String(QT_VERSION_STR)) - .arg(QLibraryInfo::licensee()) - .arg(qt_eval_days_left()); -} - -#define WARN_TIMEOUT 60 * 1000 * 119 -#define KILL_DELAY 60 * 1000 * 1 - -class QCoreFuriCuri : public QObject -{ -public: - - int warn; - int kill; - - QCoreFuriCuri() : QObject(), warn(-1), kill(-1) - { - if (qt_eval_is_supported() == EvaluationSupportedButTimeLimited) { - warn = startTimer(WARN_TIMEOUT); - kill = 0; - } - } - - void timerEvent(QTimerEvent *e) override { - if (e->timerId() == warn) { - killTimer(warn); - fprintf(stderr, "%s\n", will_shutdown_1min); - kill = startTimer(KILL_DELAY); - } else if (e->timerId() == kill) { - fprintf(stderr, "%s\n", will_shutdown_now); - QCoreApplication::instance()->quit(); - } - } -}; - -#if defined(QT_BUILD_CORE_LIB) || defined (QT_BOOTSTRAPPED) - -void qt_core_eval_init(QCoreApplicationPrivate::Type type) -{ - if (type != QCoreApplicationPrivate::Tty) - return; - - if (!qt_eval_is_supported()) - return; - - if (qt_eval_is_expired()) { - fprintf(stderr, "%s\n", boilerplate_expired); - exit(0); - } else { - fprintf(stderr, "%s\n", qPrintable(qt_eval_string())); - Q_UNUSED(new QCoreFuriCuri()); - } -} -#endif - -#ifdef QT_BUILD_WIDGETS_LIB - -QT_BEGIN_INCLUDE_NAMESPACE -#include <qdialog.h> -#include <qlabel.h> -#include <qlayout.h> -#include <qmessagebox.h> -#if QT_CONFIG(pushbutton) -#include <qpushbutton.h> -#endif -#include <qtimer.h> -#include <qapplication.h> -QT_END_INCLUDE_NAMESPACE - - -static const char * const qtlogo_eval_xpm[] = { -/* columns rows colors chars-per-pixel */ -"46 55 174 2", -" c #002E02", -". c #00370D", -"X c #003A0E", -"o c #003710", -"O c #013C13", -"+ c #043E1A", -"@ c #084F0A", -"# c #0B520C", -"$ c #054413", -"% c #0C4C17", -"& c #07421D", -"* c #09451D", -"= c #0D491E", -"- c #125515", -"; c #13541A", -": c #17591B", -"> c #1B5C1D", -", c #1F611F", -"< c #20621E", -"1 c #337B1E", -"2 c #0B4521", -"3 c #0F4923", -"4 c #114B24", -"5 c #154D2A", -"6 c #175323", -"7 c #1C5924", -"8 c #1C532F", -"9 c #1E5432", -"0 c #245936", -"q c #265938", -"w c #295C3B", -"e c #246324", -"r c #266823", -"t c #2A6C24", -"y c #276628", -"u c #2D7026", -"i c #327427", -"p c #367927", -"a c #37782A", -"s c #397C2A", -"d c #2E613E", -"f c #336C37", -"g c #2F6040", -"h c #356545", -"j c #3C6B4E", -"k c #3F6C51", -"l c #406E4F", -"z c #406D52", -"x c #477457", -"c c #497557", -"v c #4B7857", -"b c #517B5E", -"n c #3C8423", -"m c #3E812C", -"M c #53A61D", -"N c #41862C", -"B c #458A2D", -"V c #498F2D", -"C c #479324", -"Z c #489226", -"A c #4D952C", -"S c #478B30", -"D c #488C30", -"F c #4D9232", -"G c #509632", -"H c #549A33", -"J c #589F35", -"K c #56A526", -"L c #57A821", -"P c #5BAA27", -"I c #57A32A", -"U c #5CA72E", -"Y c #5DAB2A", -"T c #5CA336", -"R c #60AD2E", -"E c #63B12D", -"W c #65AF35", -"Q c #62A53F", -"! c #65AE39", -"~ c #66B036", -"^ c #6AB437", -"/ c #67B138", -"( c #6AB339", -") c #6DB838", -"_ c #70BA3C", -"` c #4D8545", -"' c #4E8942", -"] c #548851", -"[ c #6FAF4A", -"{ c #6DB243", -"} c #71B546", -"| c #70B840", -" . c #73B648", -".. c #79BA4E", -"X. c #7CBB53", -"o. c #598266", -"O. c #62886D", -"+. c #6A8F75", -"@. c #6B9173", -"#. c #70937A", -"$. c #799F79", -"%. c #7BAF66", -"&. c #81BD5B", -"*. c #85BF60", -"=. c #85AC7F", -"-. c #8DBA7B", -";. c #87C061", -":. c #8AC364", -">. c #8DC46A", -",. c #90C56E", -"<. c #93C771", -"1. c #96CA73", -"2. c #9ACB7C", -"3. c #9FD07D", -"4. c #779981", -"5. c #7F9F89", -"6. c #809F88", -"7. c #82A18B", -"8. c #86A192", -"9. c #8DA994", -"0. c #8FA998", -"q. c #94AF9B", -"w. c #97B991", -"e. c #97B19E", -"r. c #9DB6A3", -"t. c #A3BCA7", -"y. c #A6BCAB", -"u. c #A9BEB1", -"i. c #9ECD81", -"p. c #A2CF85", -"a. c #A5D284", -"s. c #A6D189", -"d. c #A9D28E", -"f. c #ABD491", -"g. c #B1D797", -"h. c #B1D699", -"j. c #B5D89E", -"k. c #ADC5AC", -"l. c #B1CAAE", -"z. c #B9DAA3", -"x. c #BDDDA8", -"c. c #ADC1B4", -"v. c #B2C6B6", -"b. c #B5C6BC", -"n. c #B6C9BA", -"m. c #BCD1BA", -"M. c #C6E1B4", -"N. c #CDE5BD", -"B. c #C2D2C6", -"V. c #CADEC2", -"C. c #C6D3CC", -"Z. c #C8D7CB", -"A. c #CEDAD2", -"S. c #D2DDD4", -"D. c #D3E9C6", -"F. c #D7EBC9", -"G. c #D9EBCD", -"H. c #DEEED4", -"J. c #D6E0D9", -"K. c #DAE4DC", -"L. c #E0EFD7", -"P. c #E5F2DD", -"I. c #DFE8E0", -"U. c #E4EBE5", -"Y. c #E9EFEA", -"T. c #EDF4EB", -"R. c #F0FAE6", -"E. c #F1F8EC", -"W. c #EDF0F0", -"Q. c #F4F7F3", -"!. c #F6F9F4", -"~. c #F8FAF7", -"^. c #FEFEFE", -"/. c None", -/* pixels */ -"/././././.c h ' Q / W _ &.p././././././././././././././././././././././././././././././././.", -"/././.4 O % Z ~ ~ W ~ W R U R R ( X.>.p././././././././././././././././././././././././././.", -"/./.. * = J _ ~ ~ ~ ~ ~ / / / / W W U P P U W .;.2././././././././././././././././././././.", -"/.= = & a ) W ~ ~ ~ ~ ~ / W / ~ ~ ~ ^ ( ( ^ ~ R R U P Y ~ .;.2././././././././././././././.", -"O.O = = T ^ W ~ ~ ~ ~ ~ ~ W W / W ~ ~ ~ ~ ~ ~ ~ ( ( ( ( ~ W Y Y Y Y W { &.1././././././././.", -"0 = * 7 ~ ~ ~ ~ ~ ~ ~ ~ ~ / / W ~ ~ ~ ~ ~ ~ ~ ~ W W W ~ ~ ~ ~ ( ( ( W W R U P U W { X.1.f./.", -"= = & e ^ W ~ ~ ~ ~ ~ ~ ~ ~ / / ~ ~ ~ ~ ~ ~ ~ ~ W ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ^ ( ( / ~ W R U U Y ", -"= = & e ^ W ~ ~ ~ ~ ~ ~ ~ ~ W W ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ( W ~ ~ ~ ^ ^ ( ", -"= = * e ^ W ~ ~ ~ ~ ~ ~ / W / W ! ( / ~ W ^ ( ( ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ~ W W ~ ~ ~ ~ ~ ~ ", -"= = & e ^ ! ~ ~ ~ ~ ~ ~ W W ^ _ ~ K Y W W R P Y W ( ~ ~ ~ ~ ~ ~ ~ W / ~ ~ ~ ^ W ~ ~ ~ ~ ~ ~ ", -"= = & e ^ W ~ ~ ~ ~ ~ ~ W ) W 1 ` w.V.L.H.D.z.,.~ Y ^ ~ ~ ~ ~ ~ W ~ ~ ~ ( ~ W W ~ ~ ~ ~ ~ ~ ", -"= = & e ^ W ~ ~ ~ ~ ~ W ) V = 8.~.^.^.^.^.^.^.^.U.<.Y ~ ~ ~ ~ ~ W W ! ~ Y W ^ W ~ ~ ~ ~ ~ ~ ", -"= = & e ^ W ~ ~ ~ ~ W ^ B O u.^.~.^.^.^.^.~.~.^.^.^.h.Y ^ ~ ~ ^ F $ k.R.G.1.Y / ~ ~ ~ ~ ~ ~ ", -"= = & e ^ ~ ~ ~ / W ( J X 7.^.~.^.^.^.^.^.^.^.^.^.^.^.s.Y / W ) a 2 U.^.^.d.U ( ~ ~ ~ ~ ~ ~ ", -"= = & e ^ W / ~ ~ ~ ^ > w ~.^.^.^.^.^.F.%.v c.^.^.^.^.~.X.W ~ ^ > h ^.^.^.d.P ( ~ ~ ~ ~ ~ ~ ", -"= = & e ^ W ~ ~ W ^ H o e.^.^.^.^.^.G.Y E n . y.^.^.^.^.M.Y ( ! $ @.^.~.^.f.U ( / ~ ~ W ~ ~ ", -"= = & e ^ W ~ W ! ) t 4 U.^.^.^.^.^.>.U ( _ , 9 ~.^.^.^.~...^ A y.^.~.^.s.M W Y ~ ~ ~ ~ ~ ", -"= 3 & e ^ W ~ ( ^ ( $ c ^.^.^.^.^.E.) ~ ~ ^ S o n.^.^.^.^.=.- l.v.Y.^.^.^.M.:.:.X.~ ~ ~ ~ ~ ", -"= = & e ^ ! W W ( J X 7.^.^.^.^.^.F.Y ( W ^ T X 6.^.^.~.^.c.. J.^.^.^.^.^.^.^.^.P.~ ~ ~ ~ ~ ", -"= = & r ^ W / W ) B o v.^.~.^.^.^.M.U / ~ ~ ! $ o.^.^.^.^.K.* S.^.^.^.^.^.^.^.^.P.~ ~ ~ ~ ~ ", -"= = & e ^ ! ~ W ) a + S.^.^.^.^.^.z.P ( W ~ ( % z ^.^.^.^.~.f t.U.^.^.^.^.~.^.^.P.~ ~ ~ ~ ~ ", -"* = & e ^ W ~ W ) t 3 Y.^.^.^.^.^.f.P ( ~ ~ ^ ; h ^.^.^.^.^.:.@ j ^.^.^.^.h.{ X.&.~ ~ ~ ~ ~ ", -"3 = & e ^ W ~ ~ ^ e 8 Q.^.^.^.^.^.s.P ~ ~ W ^ > 0 ~.^.^.^.^.1.# z ^.^.^.^.d.L W R ~ ~ ~ ~ ~ ", -"= = & e ^ W ~ ~ ^ > q ~.^.^.^.^.^.p.U ^ ~ W ) e 9 ~.^.^.^.^.3.# k ^.^.^.^.f.Y ( / ~ ~ ~ ~ ~ ", -"= = & e ^ W / W ^ > w ~.^.^.^.^.^.i.Y / ~ W ^ e 8 Q.^.^.^.^.a.# z ^.^.^.^.f.Y / ~ ~ ~ ~ ~ ~ ", -"= = & e ^ W / W ^ > w ^.^.^.^.^.^.2.Y / ~ ~ ) e 8 Q.^.^.^.^.s.# z ^.^.^.^.d.P ( ~ ~ ~ ~ ~ ~ ", -"= = & e ^ W W W ^ > q ^.^.^.^.^.^.p.Y / ~ ~ ^ e 9 Q.^.^.^.^.a.@ z ^.^.^.^.f.U / ~ ~ ~ ~ ~ ~ ", -"= = & e ^ W / W ) 7 9 Q.^.^.^.^.^.a.P / ~ W ) , 9 Q.^.^.^.^.3.# z ^.^.~.^.f.P ^ ~ ~ ~ ~ ~ ~ ", -"= = & e ^ W / W ) r 5 T.^.^.^.^.^.d.Y / ~ W ) > q ~.^.^.^.^.1.# k ^.^.^.^.f.Y ( ~ ~ ~ ~ ~ ~ ", -"= = & e ^ / / W ) i 2 I.^.^.^.^.^.h.P ( ~ W ( > g ^.^.^.^.^.:.# z ^.^.^.^.f.P / ~ ~ ~ ~ ~ ~ ", -"= = & e ( W / W ) m O Z.^.^.^.^.^.x.P / ~ ~ ( ; j ^.^.^.^.~.&.- k ^.^.~.^.f.P / ~ ~ ~ ~ ~ ~ ", -"= = & e ( W / W ) F o y.^.~.^.^.^.N.U ( ~ ~ W $ b ^.^.^.^.R._ - k ^.^.^.^.f.Y ( ~ ~ ~ ~ ~ ~ ", -"= = & e ^ W ~ ~ ^ J X 4.^.^.^.^.^.L.~ ~ W ^ T X #.^.^.^.^.F.~ ; j ^.^.^.^.f.U ( ~ ~ ~ ~ ~ ~ ", -"= = & e ^ ~ ~ ~ / ^ % l ^.^.^.^.^.!. .R ^ ^ G . r.^.~.^.^.j.E : j ^.^.^.^.f.P ) ( ~ ~ ~ ~ ~ ", -"= = & e ^ W ~ ~ W ) u = U.^.^.^.^.^.1.Y ! ) a & K.^.^.^.^.;.~ : j ^.^.~.^.z.M I I / ~ ~ W ~ ", -"= = & e ( W ~ ~ W ( G . q.^.^.^.^.^.D.U ^ ! X o.^.^.^.^.P.~ ^ > g ^.^.^.^.E.-.$.m.X.W ~ ~ ~ ", -"= = & e ^ / ~ ~ ^ ! ( > w ~.^.^.^.^.^.h.T > j T.^.^.~.^.a.Y _ i 3 U.^.^.^.^.^.^.^.X.R ~ ~ ~ ", -"= = & e ^ / ~ ~ W W ^ H . 9.^.~.^.^.^.^.K.C.~.^.^.^.^.H.W W ^ T . q.^.~.^.^.^.^.^.X.R ~ ~ ~ ", -"= = + e ^ W / ~ W W W ) m + B.^.~.^.^.^.^.^.^.^.^.^.E.X.Y ( W ^ B 6 y.^.^.^.E.D.2.( ~ ~ ~ ~ ", -"= = * e ^ ! / ! W ^ W W ) a 4 b.^.^.^.^.^.^.^.^.^.P...Y ( ! W ! ^ W Z [ *.X.{ Y U ~ ~ ~ ~ ~ ", -"= = & e ( W ~ ~ W / W / W ) A < +.A.~.^.^.^.^.!.p.W R ~ ~ ~ ~ ~ W / ) E U W W / ^ ~ ~ ~ ~ ~ ", -"= = & e ^ W ~ ~ / W / / / W ( _ Z X 6.^.^.^.^.E.W ~ ^ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ / ~ ~ ~ ~ ~ ~ ~ ~ ", -"= = & e ^ ~ ~ ~ W W / W ~ ~ ~ ~ ) ; h ^.^.^.^.^.d.M U ~ / ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ", -"= = & e ^ W ~ ~ ^ W W / ~ ~ ~ W ) p + S.^.^.^.^.~.M.f. .W ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ .", -"= = & e ^ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ( T O +.^.~.^.^.^.^.^.&.Y ( ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ( Y 2.", -"= = & e ( W ~ ~ ~ ~ ~ ~ ~ ~ ~ / W ) N + b.^.^.^.^.^.^.&.R ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W /.", -"= = & e ^ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ^ N 7 r.W.^.^.^.!.X.W ~ ~ W ~ W ~ ~ ~ ~ ~ ~ / ( ( K p./.", -"= = & e ( W ~ ~ W ~ ~ ~ ~ ~ ~ ~ ~ ~ W ( W C Q &.:.X.| ~ ~ ~ ~ W ~ / ~ ( / ( ~ W E U P 1././.", -"= = + e ^ / / / ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W / ) ^ R Y W W ~ ~ ( / ( / W R Y Y U R ( X.,././././.", -"= = * e ( / ~ / ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W W W ! ( ( ( W W E U P Y W ( X.,.d./././././././././.", -"= = * e ( W ~ ~ ~ ~ W ! ~ W ~ W ~ ( ( / ^ W W U Y P W ( X.,.d./././././././././././././././.", -"8 $ * e ( W ~ ~ ~ ! ( ( ( / ( W R Y Y Y R ( X.>.d./././././././././././././././././././././.", -"/.d . y ^ / / / ( W Y Y P P W ( X.>.d./././././././././././././././././././././././././././.", -"/./.h : ^ R R R W ( X.<.f./././././././././././././././././././././././././././././././././.", -"/././.] _ *.3./././././././././././././././././././././././././././././././././././././././." -}; - -class EvalMessageBox : public QDialog -{ -public: - EvalMessageBox(bool expired) - { - setWindowTitle(QLatin1String(" ")); - - QString str = expired ? QLatin1String(boilerplate_expired) : qt_eval_string(); - str = str.trimmed(); - - QFrame *border = new QFrame(this); - - QLabel *pixmap_label = new QLabel(border); - pixmap_label->setPixmap(QPixmap(qtlogo_eval_xpm)); - pixmap_label->setAlignment(Qt::AlignTop); - - QLabel *text_label = new QLabel(str, border); - - QHBoxLayout *pm_and_text_layout = new QHBoxLayout(); - pm_and_text_layout->addWidget(pixmap_label); - pm_and_text_layout->addWidget(text_label); - - QVBoxLayout *master_layout = new QVBoxLayout(border); - master_layout->addLayout(pm_and_text_layout); - - QVBoxLayout *border_layout = new QVBoxLayout(this); - border_layout->setMargin(0); - border_layout->addWidget(border); - - if (expired) { - QPushButton *cmd = new QPushButton(QLatin1String("OK"), border); - cmd->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - cmd->setDefault(true); - - QHBoxLayout *button_layout = new QHBoxLayout(); - master_layout->addLayout(button_layout); - button_layout->addWidget(cmd); - - connect(cmd, SIGNAL(clicked()), this, SLOT(close())); - } else { - border->setFrameShape(QFrame::WinPanel); - border->setFrameShadow(QFrame::Raised); - setParent(parentWidget(), Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); - QTimer::singleShot(7000, this, SLOT(close())); - setAttribute(Qt::WA_DeleteOnClose); - setAttribute(Qt::WA_QuitOnClose, false); - } - - setFixedSize(sizeHint()); - } -}; - -class QGuiFuriCuri : public QCoreFuriCuri -{ -public: - void timerEvent(QTimerEvent *e) { - if (e->timerId() == warn) { - killTimer(warn); - QMessageBox::information(0, QLatin1String("Automatic Timeout"), QLatin1String(will_shutdown_1min)); - kill = startTimer(KILL_DELAY); - } else if (e->timerId() == kill) { - killTimer(kill); - QMessageBox::information(0, QLatin1String("Automatic Timeout"), QLatin1String(will_shutdown_now)); - qApp->quit(); - } - } -}; - - -void qt_gui_eval_init(QCoreApplicationPrivate::Type type) -{ - Q_UNUSED(type); - - if (!qt_eval_is_supported()) - return; - - if (qt_eval_is_expired()) { - EvalMessageBox box(true); - box.exec(); - ::exit(0); - } else { - Q_UNUSED(new QGuiFuriCuri()); - } -} - -static QString qt_eval_title_prefix() -{ - return QLatin1String("[Qt Evaluation] "); -} - -QString qt_eval_adapt_window_title(const QString &title) -{ - if (!qt_eval_is_supported()) - return title; - return qt_eval_title_prefix() + title; -} - -void qt_eval_init_widget(QWidget *w) -{ - if (!qt_eval_is_supported()) - return; - if (w->isTopLevel() && w->windowTitle().isEmpty() && w->windowType() != Qt::Desktop ) { - w->setWindowTitle(QLatin1String(" ")); - } -} -#endif - -QT_END_NAMESPACE diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro index 83e44ff9a4..3a1a186e8e 100644 --- a/src/tools/bootstrap/bootstrap.pro +++ b/src/tools/bootstrap/bootstrap.pro @@ -19,8 +19,6 @@ DEFINES += \ QT_NO_FOREACH \ QT_NO_CAST_FROM_ASCII -DEFINES -= QT_EVAL - SOURCES += \ ../../corelib/codecs/qlatincodec.cpp \ ../../corelib/codecs/qtextcodec.cpp \ diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 3594b5c902..e189e5ba50 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -575,10 +575,6 @@ void QApplicationPrivate::init() initialize(); eventDispatcher->startingUp(); -#ifdef QT_EVAL - extern void qt_gui_eval_init(QCoreApplicationPrivate::Type); - qt_gui_eval_init(application_type); -#endif #ifndef QT_NO_ACCESSIBILITY // factory for accessible interfaces for widgets shipped with Qt QAccessible::installFactory(&qAccessibleFactory); diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 87cc150530..e1ce731418 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1348,11 +1348,6 @@ void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow) if (!isWindow() && parentWidget() && parentWidget()->testAttribute(Qt::WA_DropSiteRegistered)) setAttribute(Qt::WA_DropSiteRegistered, true); -#ifdef QT_EVAL - extern void qt_eval_init_widget(QWidget *w); - qt_eval_init_widget(this); -#endif - // need to force the resting of the icon after changing parents if (testAttribute(Qt::WA_SetWindowIcon)) d->setWindowIcon_sys(); @@ -6055,13 +6050,7 @@ QString qt_setWindowTitle_helperHelper(const QString &title, const QWidget *widg { Q_ASSERT(widget); -#ifdef QT_EVAL - extern QString qt_eval_adapt_window_title(const QString &title); - QString cap = qt_eval_adapt_window_title(title); -#else QString cap = title; -#endif - if (cap.isEmpty()) return cap; diff --git a/src/widgets/widgets.pro b/src/widgets/widgets.pro index e556cb8b10..6f807e1696 100644 --- a/src/widgets/widgets.pro +++ b/src/widgets/widgets.pro @@ -32,8 +32,6 @@ qtConfig(graphicseffect) { QMAKE_LIBS += $$QMAKE_LIBS_GUI -contains(DEFINES,QT_EVAL):include($$QT_SOURCE_TREE/src/corelib/eval.pri) - QMAKE_DYNAMIC_LIST_FILE = $$PWD/QtWidgets.dynlist # Code coverage with TestCocoon From 652075d1e09c8dc1cfaa8d273d136d27e3d141f2 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint <Friedemann.Kleint@qt.io> Date: Mon, 11 Feb 2019 13:39:45 +0100 Subject: [PATCH 1131/1650] Add missing \since to QList<T>::swapItemsAt() Amends 7f4d0405b409b1d3aa9d91e31972669576ec698c. Change-Id: I4de38428ea4a0e448e2930d19d94821884f7331e Reviewed-by: Lars Knoll <lars.knoll@qt.io> --- src/corelib/tools/qlist.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp index 1de93ff9e1..6f8084c676 100644 --- a/src/corelib/tools/qlist.cpp +++ b/src/corelib/tools/qlist.cpp @@ -971,6 +971,7 @@ void **QListData::erase(void **xi) */ /*! \fn template <class T> void QList<T>::swapItemsAt(int i, int j) + \since 5.13 Exchange the item at index position \a i with the item at index position \a j. This function assumes that both \a i and \a j are From afc7b26313e0d6c43bdc62b021751f30e6fa27a5 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Sun, 10 Feb 2019 19:37:03 +0100 Subject: [PATCH 1132/1650] QtWidgets: mark QFileDialog functions as deprecated Mark some long obsolete functions as deprecated so the can be removed with Qt6: - QFileDialog::setConfirmOverwrite()/confirmOverwrite() - QFileDialog::setReadOnly()/isReadOnly() Change-Id: I3cc1df76c8e40e95b8e9893ae06ef488fad26fb6 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> --- src/widgets/dialogs/qfiledialog.cpp | 4 ++-- src/widgets/dialogs/qfiledialog.h | 13 ++++++---- .../dialogs/qfiledialog/tst_qfiledialog.cpp | 24 +++++++++---------- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 3e756da505..d8a4ad5f24 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -1864,6 +1864,7 @@ QFileDialog::AcceptMode QFileDialog::acceptMode() const return static_cast<AcceptMode>(d->options->acceptMode()); } +#if QT_DEPRECATED_SINCE(5, 13) /*! \property QFileDialog::readOnly \obsolete @@ -1884,7 +1885,6 @@ bool QFileDialog::isReadOnly() const return testOption(ReadOnly); } -#if QT_DEPRECATED_SINCE(5, 13) /*! \property QFileDialog::resolveSymlinks \obsolete @@ -1905,7 +1905,6 @@ bool QFileDialog::resolveSymlinks() const { return !testOption(DontResolveSymlinks); } -#endif /*! \property QFileDialog::confirmOverwrite @@ -1925,6 +1924,7 @@ bool QFileDialog::confirmOverwrite() const { return !testOption(DontConfirmOverwrite); } +#endif /*! \property QFileDialog::defaultSuffix diff --git a/src/widgets/dialogs/qfiledialog.h b/src/widgets/dialogs/qfiledialog.h index c75795fd77..95e03618ac 100644 --- a/src/widgets/dialogs/qfiledialog.h +++ b/src/widgets/dialogs/qfiledialog.h @@ -66,10 +66,10 @@ class Q_WIDGETS_EXPORT QFileDialog : public QDialog Q_PROPERTY(ViewMode viewMode READ viewMode WRITE setViewMode) Q_PROPERTY(FileMode fileMode READ fileMode WRITE setFileMode) Q_PROPERTY(AcceptMode acceptMode READ acceptMode WRITE setAcceptMode) - Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly DESIGNABLE false) - Q_PROPERTY(bool confirmOverwrite READ confirmOverwrite WRITE setConfirmOverwrite DESIGNABLE false) Q_PROPERTY(QString defaultSuffix READ defaultSuffix WRITE setDefaultSuffix) #if QT_DEPRECATED_SINCE(5, 13) + Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly DESIGNABLE false) + Q_PROPERTY(bool confirmOverwrite READ confirmOverwrite WRITE setConfirmOverwrite DESIGNABLE false) Q_PROPERTY(bool resolveSymlinks READ resolveSymlinks WRITE setResolveSymlinks DESIGNABLE false) Q_PROPERTY(bool nameFilterDetailsVisible READ isNameFilterDetailsVisible WRITE setNameFilterDetailsVisible DESIGNABLE false) @@ -80,7 +80,8 @@ class Q_WIDGETS_EXPORT QFileDialog : public QDialog public: enum ViewMode { Detail, List }; Q_ENUM(ViewMode) - enum FileMode { AnyFile, ExistingFile, Directory, ExistingFiles, DirectoryOnly }; + enum FileMode { AnyFile, ExistingFile, Directory, ExistingFiles, + DirectoryOnly Q_DECL_ENUMERATOR_DEPRECATED_X("Use setOption(ShowDirsOnly, true) instead")}; Q_ENUM(FileMode) enum AcceptMode { AcceptOpen, AcceptSave }; Q_ENUM(AcceptMode) @@ -153,10 +154,10 @@ public: void setAcceptMode(AcceptMode mode); AcceptMode acceptMode() const; +#if QT_DEPRECATED_SINCE(5, 13) void setReadOnly(bool enabled); bool isReadOnly() const; -#if QT_DEPRECATED_SINCE(5, 13) QT_DEPRECATED_X("Use setOption(DontResolveSymlinks, !enabled) instead") void setResolveSymlinks(bool enabled); QT_DEPRECATED_X("Use !testOption(DontResolveSymlinks) instead") @@ -169,8 +170,12 @@ public: QByteArray saveState() const; bool restoreState(const QByteArray &state); +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X("Use setOption(DontConfirmOverwrite, !enabled) instead") void setConfirmOverwrite(bool enabled); + QT_DEPRECATED_X("Use !testOption(DontConfirmOverwrite) instead") bool confirmOverwrite() const; +#endif void setDefaultSuffix(const QString &suffix); QString defaultSuffix() const; diff --git a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp index 9668c82ef2..748c8aaa84 100644 --- a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp @@ -620,13 +620,13 @@ void tst_QFiledialog::acceptMode() void tst_QFiledialog::confirmOverwrite() { QFileDialog fd; - QCOMPARE(fd.confirmOverwrite(), true); - fd.setConfirmOverwrite(true); - QCOMPARE(fd.confirmOverwrite(), true); - fd.setConfirmOverwrite(false); - QCOMPARE(fd.confirmOverwrite(), false); - fd.setConfirmOverwrite(true); - QCOMPARE(fd.confirmOverwrite(), true); + QCOMPARE(fd.testOption(QFileDialog::DontConfirmOverwrite), false); + fd.setOption(QFileDialog::DontConfirmOverwrite, false); + QCOMPARE(fd.testOption(QFileDialog::DontConfirmOverwrite), false); + fd.setOption(QFileDialog::DontConfirmOverwrite, true); + QCOMPARE(fd.testOption(QFileDialog::DontConfirmOverwrite), true); + fd.setOption(QFileDialog::DontConfirmOverwrite, false); + QCOMPARE(fd.testOption(QFileDialog::DontConfirmOverwrite), false); } void tst_QFiledialog::defaultSuffix() @@ -808,8 +808,8 @@ void tst_QFiledialog::isReadOnly() //QCOMPARE(renameAction && renameAction->isEnabled(), true); //QCOMPARE(deleteAction && deleteAction->isEnabled(), true); - fd.setReadOnly(true); - QCOMPARE(fd.isReadOnly(), true); + fd.setOption(QFileDialog::ReadOnly, true); + QCOMPARE(fd.testOption(QFileDialog::ReadOnly), true); QCOMPARE(newButton && newButton->isEnabled(), false); QCOMPARE(renameAction && renameAction->isEnabled(), false); @@ -853,11 +853,11 @@ void tst_QFiledialog::resolveSymlinks() QFileDialog fd; // default - QCOMPARE(fd.resolveSymlinks(), true); + QCOMPARE(fd.testOption(QFileDialog::DontResolveSymlinks), false); fd.setOption(QFileDialog::DontResolveSymlinks, true); - QCOMPARE(fd.resolveSymlinks(), false); + QCOMPARE(fd.testOption(QFileDialog::DontResolveSymlinks), true); fd.setOption(QFileDialog::DontResolveSymlinks, false); - QCOMPARE(fd.resolveSymlinks(), true); + QCOMPARE(fd.testOption(QFileDialog::DontResolveSymlinks), false); // the file dialog doesn't do anything based upon this, just passes it to the model // the model should fully test it, don't test it here From a7123de6c99b4949fb1b3affffcba3bf9a9d372f Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Fri, 1 Feb 2019 20:06:24 +0100 Subject: [PATCH 1133/1650] QFontComboBox: fix layouting in RTL mode QFontComboBox did not work very well in RTL mode. The text was not aligned right and the icon was not painted on the right side as it is done for a normal combobox. Fix it by using QStyle::alignedRect() for the icon position calculation and passing the correct alignment when drawing text. Fixes: QTBUG-19722 Change-Id: I47c5864519e78e0833ef4c07a1385e45ce4479f8 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> --- src/widgets/widgets/qfontcombobox.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/widgets/widgets/qfontcombobox.cpp b/src/widgets/widgets/qfontcombobox.cpp index 957a464b71..4a99b0f962 100644 --- a/src/widgets/widgets/qfontcombobox.cpp +++ b/src/widgets/widgets/qfontcombobox.cpp @@ -236,9 +236,10 @@ void QFontFamilyDelegate::paint(QPainter *painter, if (QFontDatabase().isSmoothlyScalable(text)) { icon = &truetype; } - QSize actualSize = icon->actualSize(r.size()); - - icon->paint(painter, r, Qt::AlignLeft|Qt::AlignVCenter); + const QSize actualSize = icon->actualSize(r.size()); + const QRect iconRect = QStyle::alignedRect(option.direction, option.displayAlignment, + actualSize, r); + icon->paint(painter, iconRect, Qt::AlignLeft|Qt::AlignVCenter); if (option.direction == Qt::RightToLeft) r.setRight(r.right() - actualSize.width() - 4); else @@ -247,6 +248,7 @@ void QFontFamilyDelegate::paint(QPainter *painter, QFont old = painter->font(); painter->setFont(font); + const Qt::Alignment textAlign = QStyle::visualAlignment(option.direction, option.displayAlignment); // If the ascent of the font is larger than the height of the rect, // we will clip the text, so it's better to align the tight bounding rect in this case // This is specifically for fonts where the ascent is very large compared to @@ -254,9 +256,11 @@ void QFontFamilyDelegate::paint(QPainter *painter, QFontMetricsF fontMetrics(font); if (fontMetrics.ascent() > r.height()) { QRectF tbr = fontMetrics.tightBoundingRect(text); - painter->drawText(r.x(), r.y() + (r.height() + tbr.height()) / 2.0, text); + QRect textRect(r); + textRect.setHeight(textRect.height() + (r.height() - tbr.height())); + painter->drawText(textRect, Qt::AlignBottom|Qt::TextSingleLine|textAlign, text); } else { - painter->drawText(r, Qt::AlignVCenter|Qt::AlignLeading|Qt::TextSingleLine, text); + painter->drawText(r, Qt::AlignVCenter|Qt::TextSingleLine|textAlign, text); } if (writingSystem != QFontDatabase::Any) @@ -270,7 +274,7 @@ void QFontFamilyDelegate::paint(QPainter *painter, r.setRight(r.right() - w); else r.setLeft(r.left() + w); - painter->drawText(r, Qt::AlignVCenter|Qt::AlignLeading|Qt::TextSingleLine, sample); + painter->drawText(r, Qt::AlignVCenter|Qt::TextSingleLine|textAlign, sample); } painter->setFont(old); From 0e82e1bd237fe295e0e30ec3613afd95142f3941 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Fri, 1 Feb 2019 22:39:43 +0100 Subject: [PATCH 1134/1650] QComboBox: deprecate signal currentIndexChanged(const QString &) QComboBox has two overloaded signals currentIndexChanged(). This results in a need to use QOverload<>::of or similar when using the new signal/slot syntax. Since there is already a signal 'currentTextChanged()' which is emitted too, deprecate 'currentIndexChanged(const QString &)'. Change-Id: Iadac8930de1721b042fa1daea097c8ab5378738e Reviewed-by: Samuel Gaist <samuel.gaist@idiap.ch> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> --- src/widgets/widgets/qcombobox.cpp | 9 +++++++++ src/widgets/widgets/qcombobox.h | 3 +++ 2 files changed, 12 insertions(+) diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 2c478f364d..f3e6bd80f4 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -895,14 +895,21 @@ QStyleOptionComboBox QComboBoxPrivateContainer::comboStyleOption() const currentIndex was reset. */ +#if QT_DEPRECATED_SINCE(5, 13) /*! \fn void QComboBox::currentIndexChanged(const QString &text) \since 4.1 + \obsolete + + Use currentTextChanged(const QString &) or currentIndexChanged(int) + instead. + This signal is sent whenever the currentIndex in the combobox changes either through user interaction or programmatically. The item's \a text is passed. */ +#endif /*! \fn void QComboBox::currentTextChanged(const QString &text) @@ -1375,7 +1382,9 @@ void QComboBoxPrivate::_q_emitCurrentIndexChanged(const QModelIndex &index) Q_Q(QComboBox); const QString text = itemText(index); emit q->currentIndexChanged(index.row()); +#if QT_DEPRECATED_SINCE(5, 13) emit q->currentIndexChanged(text); +#endif // signal lineEdit.textChanged already connected to signal currentTextChanged, so don't emit double here if (!lineEdit) emit q->currentTextChanged(text); diff --git a/src/widgets/widgets/qcombobox.h b/src/widgets/widgets/qcombobox.h index 542a3bd3b9..64fbebb3c5 100644 --- a/src/widgets/widgets/qcombobox.h +++ b/src/widgets/widgets/qcombobox.h @@ -224,7 +224,10 @@ Q_SIGNALS: void highlighted(int index); void highlighted(const QString &); void currentIndexChanged(int index); +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X("Use currentTextChanged() instead") void currentIndexChanged(const QString &); +#endif void currentTextChanged(const QString &); protected: From 6b8610f4e8b72895bfa4228cca2230f31c259d80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= <tor.arne.vestbo@qt.io> Date: Tue, 12 Feb 2019 13:55:52 +0100 Subject: [PATCH 1135/1650] macOS: Add explicit auto-release pool for requestActivateWindow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The API is often called from main before entering the event loop, and the making the window first responder and key will autorelease both the window and view. Change-Id: Ie2a7dc14652015cbe802b57696e4a82d564e2dc0 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> --- src/plugins/platforms/cocoa/qcocoawindow.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 724c9485bd..ebdd51acb4 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1512,9 +1512,9 @@ void QCocoaWindow::deliverUpdateRequest() void QCocoaWindow::requestActivateWindow() { - NSWindow *window = [m_view window]; - [window makeFirstResponder:m_view]; - [window makeKeyWindow]; + QMacAutoReleasePool pool; + [m_view.window makeFirstResponder:m_view]; + [m_view.window makeKeyWindow]; } QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel) From ae94ab264ba29a41beac81a61fb39c0d4f669270 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= <tor.arne.vestbo@qt.io> Date: Tue, 12 Feb 2019 14:04:04 +0100 Subject: [PATCH 1136/1650] Add developer documentation on how to debug missing auto-release pools MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ie3942210ab5bafea22d65d6f7c9a099e40ee6b73 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io> --- src/corelib/kernel/qcore_mac_objc.mm | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm index bc23e821fd..140c60a080 100644 --- a/src/corelib/kernel/qcore_mac_objc.mm +++ b/src/corelib/kernel/qcore_mac_objc.mm @@ -129,6 +129,16 @@ QT_USE_NAMESPACE QT_NAMESPACE_ALIAS_OBJC_CLASS(QMacAutoReleasePoolTracker); QT_BEGIN_NAMESPACE + +/* + Manages a scoped auto-release pool. + + To track autoreleases without any pools in place, such as in main() + before the runloop has started, export OBJC_DEBUG_MISSING_POOLS=YES + and break in objc_autoreleaseNoPool, e.g.: + + br set -n objc_autoreleaseNoPool -c "[((NSObject*)$r14) class] == [QNSWindow class]" +*/ QMacAutoReleasePool::QMacAutoReleasePool() : pool([[NSAutoreleasePool alloc] init]) { From 0ad651579fe9055e52d4a6754a95de35f7b9bf52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= <tor.arne.vestbo@qt.io> Date: Thu, 7 Feb 2019 17:27:18 +0100 Subject: [PATCH 1137/1650] macOS: Don't rely on QGuiApplication::instance() during CVDisplayLink callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The display-link callback comes in on a secondary thread, so there's a possible race in using QGuiApplication::instance() to check whether or not we're on the main thread. Change-Id: Ic26bca8f5f54847a1e1b11dc92e786693c86e9de Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io> --- src/plugins/platforms/cocoa/qcocoascreen.mm | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoascreen.mm b/src/plugins/platforms/cocoa/qcocoascreen.mm index 36c11ba8af..80dd7e40d3 100644 --- a/src/plugins/platforms/cocoa/qcocoascreen.mm +++ b/src/plugins/platforms/cocoa/qcocoascreen.mm @@ -269,15 +269,12 @@ struct DeferredDebugHelper void QCocoaScreen::deliverUpdateRequests() { - if (!QGuiApplication::instance()) - return; - // The CVDisplayLink callback is a notification that it's a good time to produce a new frame. // Since the callback is delivered on a separate thread we have to marshal it over to the // main thread, as Qt requires update requests to be delivered there. This needs to happen // asynchronously, as otherwise we may end up deadlocking if the main thread calls back // into any of the CVDisplayLink APIs. - if (QThread::currentThread() != QGuiApplication::instance()->thread()) { + if (!NSThread.isMainThread) { // We're explicitly not using the data of the GCD source to track the pending updates, // as the data isn't reset to 0 until after the event handler, and also doesn't update // during the event handler, both of which we need to track late frames. From 77389ad8ff9fd3dc56f5a398fab11a993e7a621c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= <tor.arne.vestbo@qt.io> Date: Sun, 10 Feb 2019 17:39:06 +0100 Subject: [PATCH 1138/1650] macOS: Remove screen-update disable during resize MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was needed as a workaround for the window border and window content becoming out of sync when we were drawing and flushing to the layer from another thread using OpenGL. Since we've disabled ThreadedOpenGL we can remove this workaround for now. The workaround also had other problems, as windowWillResize: did not turn out to be a reliable signal to know when a window was about to resize. Since we override windowWillUseStandardFrame:, we would not get the callback when zooming windows. Conversely, if we removed the windowWillUseStandardFrame: override, we would get a single callback for windowWillResize:, and then multiple callbacks that the window had resized. In addition, windowWillResize: is not only used as a callback, but also as a way to let the window delegate restrict the size, so it's called when e.g. AppKit determines the standard frame of the window -- an operation that doesn't involve an actual resize operation. If we re-introduce a workaround using screen-update disabling we need a better hook than windowWillResize:, and we need to track when we disable screen updates so that we can pair them up with corresponding screen update enables, otherwise we'll get log messages in the console about "SLSReenableUpdate: unbalanced enable/disable update". Change-Id: Ifca8892083c8666976391a4ada8f8d1471493943 Fixes: QTBUG-73726 Task-number: QTBUG-69321 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> --- .../platforms/cocoa/qnswindowdelegate.mm | 34 ------------------- 1 file changed, 34 deletions(-) diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.mm b/src/plugins/platforms/cocoa/qnswindowdelegate.mm index 14f1ca0114..087cb3651f 100644 --- a/src/plugins/platforms/cocoa/qnswindowdelegate.mm +++ b/src/plugins/platforms/cocoa/qnswindowdelegate.mm @@ -102,40 +102,6 @@ static QCocoaWindow *toPlatformWindow(NSWindow *window) return QCocoaScreen::mapToNative(maximizedFrame); } -#pragma clang diagnostic push -// NSDisableScreenUpdates and NSEnableScreenUpdates are deprecated, but the -// NSAnimationContext API that replaces them doesn't handle the use-case of -// cross-thread screen update synchronization. -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -- (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)frameSize -{ - Q_ASSERT(toPlatformWindow(window)); - - qCDebug(lcQpaWindow) << window << "will resize to" << QSizeF::fromCGSize(frameSize) - << "- disabling screen updates temporarily"; - - // There may be separate threads rendering to CA layers in this window, - // and if any of them do a swap while the resize is still in progress, - // the visual bounds of that layer will be updated before the visual - // bounds of the window frame, resulting in flickering while resizing. - - // To prevent this we disable screen updates for the whole process until - // the resize is complete, which makes the whole thing visually atomic. - NSDisableScreenUpdates(); - - return frameSize; -} - -- (void)windowDidResize:(NSNotification *)notification -{ - NSWindow *window = notification.object; - Q_ASSERT(toPlatformWindow(window)); - - qCDebug(lcQpaWindow) << window << "was resized - re-enabling screen updates"; - NSEnableScreenUpdates(); -} -#pragma clang diagnostic pop - - (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu { Q_UNUSED(menu); From 6c9b17d446b8245472f5ece41a2f0d1ef866f5a1 Mon Sep 17 00:00:00 2001 From: Alessandro Portale <alessandro.portale@qt.io> Date: Wed, 6 Feb 2019 07:55:51 +0100 Subject: [PATCH 1139/1650] Fix: "Emit keyword being used with non-signal" [-Wclazy-incorrect-emit] Change-Id: I21f69d7f6b161d70a687ab17b2821a595c113ec7 Reviewed-by: Tim Jenssen <tim.jenssen@qt.io> --- src/network/access/qnetworkaccessftpbackend.cpp | 2 +- src/network/socket/qhttpsocketengine.cpp | 8 ++++---- src/network/socket/qsocks5socketengine.cpp | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/network/access/qnetworkaccessftpbackend.cpp b/src/network/access/qnetworkaccessftpbackend.cpp index fd6589b396..5ad820eba0 100644 --- a/src/network/access/qnetworkaccessftpbackend.cpp +++ b/src/network/access/qnetworkaccessftpbackend.cpp @@ -351,7 +351,7 @@ void QNetworkAccessFtpBackend::ftpDone() } } else if (state == Statting) { // statted successfully, send the actual request - emit metaDataChanged(); + metaDataChanged(); state = Transferring; QFtp::TransferType type = QFtp::Binary; diff --git a/src/network/socket/qhttpsocketengine.cpp b/src/network/socket/qhttpsocketengine.cpp index 9427c3b00d..49ea17f9f8 100644 --- a/src/network/socket/qhttpsocketengine.cpp +++ b/src/network/socket/qhttpsocketengine.cpp @@ -649,7 +649,7 @@ void QHttpSocketEngine::slotSocketReadNotification() } if (priv->phase == QAuthenticatorPrivate::Done) - emit proxyAuthenticationRequired(d->proxy, &d->authenticator); + proxyAuthenticationRequired(d->proxy, &d->authenticator); // priv->phase will get reset to QAuthenticatorPrivate::Start if the authenticator got modified in the signal above. if (priv->phase == QAuthenticatorPrivate::Done) { setError(QAbstractSocket::ProxyAuthenticationRequiredError, tr("Authentication required")); @@ -771,7 +771,7 @@ void QHttpSocketEngine::emitPendingReadNotification() Q_D(QHttpSocketEngine); d->readNotificationPending = false; if (d->readNotificationEnabled) - emit readNotification(); + readNotification(); } void QHttpSocketEngine::emitPendingWriteNotification() @@ -779,14 +779,14 @@ void QHttpSocketEngine::emitPendingWriteNotification() Q_D(QHttpSocketEngine); d->writeNotificationPending = false; if (d->writeNotificationEnabled) - emit writeNotification(); + writeNotification(); } void QHttpSocketEngine::emitPendingConnectionNotification() { Q_D(QHttpSocketEngine); d->connectionNotificationPending = false; - emit connectionNotification(); + connectionNotification(); } void QHttpSocketEngine::emitReadNotification() diff --git a/src/network/socket/qsocks5socketengine.cpp b/src/network/socket/qsocks5socketengine.cpp index dd2bc90855..3e4c35fcc5 100644 --- a/src/network/socket/qsocks5socketengine.cpp +++ b/src/network/socket/qsocks5socketengine.cpp @@ -706,7 +706,7 @@ void QSocks5SocketEnginePrivate::reauthenticate() // we require authentication QAuthenticator auth; - emit q->proxyAuthenticationRequired(proxyInfo, &auth); + q->proxyAuthenticationRequired(proxyInfo, &auth); if (!auth.user().isEmpty() || !auth.password().isEmpty()) { // we have new credentials, let's try again @@ -915,7 +915,7 @@ void QSocks5SocketEnginePrivate::_q_emitPendingReadNotification() if (readNotificationEnabled) { QSOCKS5_D_DEBUG << "emitting readNotification"; QPointer<QSocks5SocketEngine> qq = q; - emit q->readNotification(); + q->readNotification(); if (!qq) return; // check if there needs to be a new zero read notification @@ -944,7 +944,7 @@ void QSocks5SocketEnginePrivate::_q_emitPendingWriteNotification() Q_Q(QSocks5SocketEngine); if (writeNotificationEnabled) { QSOCKS5_D_DEBUG << "emitting writeNotification"; - emit q->writeNotification(); + q->writeNotification(); } } @@ -964,7 +964,7 @@ void QSocks5SocketEnginePrivate::_q_emitPendingConnectionNotification() connectionNotificationPending = false; Q_Q(QSocks5SocketEngine); QSOCKS5_D_DEBUG << "emitting connectionNotification"; - emit q->connectionNotification(); + q->connectionNotification(); } void QSocks5SocketEnginePrivate::emitConnectionNotification() From 80bcfa776f9243641484181a18090b34147e8e30 Mon Sep 17 00:00:00 2001 From: Andre de la Rocha <andre.rocha@qt.io> Date: Fri, 8 Feb 2019 22:33:15 +0100 Subject: [PATCH 1140/1650] Fix QSpinBox tests failing after change in the Windows QPA Some QSpinBox tests start failing after reverting to using legacy mouse messages to handle mouse input in the Windows QPA. It seems to be caused by a test that runs before it and moves the mouse cursor. Then when the QSpinBox tests run, they create widgets that appear below the mouse cursor, causing some mouse events to be generating and messing with the events synthesized by the test itself. With the pointer messages being used for mouse input, the legacy mouse messages that are generated under this condition were being ignored. But by reverting to the old implementation, the legacy messages are handled again, causing the test to fail. This change moves the mouse pointer to a safe position during the test initialization, so it does not depend on the state left by previous tests. This change needs to be integrated together or before the change in the windows QPA. Change-Id: I91f7e9376dc495ee61250e0a7d908c1c2b685bc8 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> --- tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp index 37bb28dec9..1d106f94f3 100644 --- a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp +++ b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp @@ -53,6 +53,8 @@ #include <QStyleOptionSpinBox> #include <QStyle> #include <QProxyStyle> +#include <QScreen> + class SpinBox : public QSpinBox { @@ -343,6 +345,14 @@ tst_QSpinBox::tst_QSpinBox() void tst_QSpinBox::init() { QLocale::setDefault(QLocale(QLocale::C)); + +#if QT_CONFIG(cursor) + // Ensure mouse cursor was not left by previous tests where widgets + // will appear, as it could cause events and interfere with the tests. + const QScreen *screen = QGuiApplication::primaryScreen(); + const QRect availableGeometry = screen->availableGeometry(); + QCursor::setPos(availableGeometry.topLeft()); +#endif } void tst_QSpinBox::setValue_data() From 38504041148f2d1cffea6520ea448dd4171adb0b Mon Sep 17 00:00:00 2001 From: Andre de la Rocha <andre.rocha@qt.io> Date: Mon, 4 Feb 2019 19:25:31 +0100 Subject: [PATCH 1141/1650] Windows QPA: Handle mouse input using legacy messages This change reverts to using legacy mouse messages when handling mouse and touchpad input, while using pointer messages to handle touchscreen and pen input. The use of pointer messages to handle everything, added in 5.12.0, caused issues in some particular cases, due mainly to differences in behavior or bugs in the pointer messages, which required workarounds in the Windows QPA, which didn't work well in all cases and led to additional issues. For instance, DoDragDrop() does not work when called by pointer (or touch/pen) handlers, but only after OS-synthesized legacy mouse messages are generated. Also, in some cases pointer messages for mouse movement are generated as non-client for client area events. Modal loops like the ones in window resize/move and menu handling caused some issues with pointer messages, as well. Also, we have to handle the OS-synthesized legacy mouse message generated for touch and pen. Ignoring them while letting the gui layer synthesize mouse events for touch/pen may break Drag and Drop by triggering DoDragDrop() before legacy messages, which can result in a hang inside the DoDragDrop() modal loop. This change should fix most regressions related to pointer messages, while keeping the enhancements in pen and touch input. Fixes: QTBUG-73389 Fixes: QTBUG-72624 Fixes: QTBUG-72801 Fixes: QTBUG-73290 Fixes: QTBUG-72458 Fixes: QTBUG-73358 Fixes: QTBUG-72992 Change-Id: I919f78930d3965270ef2094401e827ab87174979 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> --- .../platforms/windows/qwindowscontext.cpp | 20 +- .../windows/qwindowspointerhandler.cpp | 487 ++++++------------ .../windows/qwindowspointerhandler.h | 6 +- 3 files changed, 167 insertions(+), 346 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 2b96fb3a5e..41655dbd57 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -334,12 +334,8 @@ bool QWindowsContext::initTouch(unsigned integrationOptions) if (!touchDevice) return false; - if (d->m_systemInfo & QWindowsContext::SI_SupportsPointer) { - QWindowSystemInterfacePrivate::TabletEvent::setPlatformSynthesizesMouse(false); - } else { - if (!(integrationOptions & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch)) - touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation); - } + if (!(integrationOptions & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch)) + touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation); QWindowSystemInterface::registerTouchDevice(touchDevice); @@ -376,7 +372,6 @@ bool QWindowsContext::initPointer(unsigned integrationOptions) if (!QWindowsContext::user32dll.supportsPointerApi()) return false; - QWindowsContext::user32dll.enableMouseInPointer(TRUE); d->m_systemInfo |= QWindowsContext::SI_SupportsPointer; return true; } @@ -1218,9 +1213,10 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, case QtWindows::ExposeEvent: return platformWindow->handleWmPaint(hwnd, message, wParam, lParam); case QtWindows::NonClientMouseEvent: - if (!(d->m_systemInfo & QWindowsContext::SI_SupportsPointer) && platformWindow->frameStrutEventsEnabled()) + if ((d->m_systemInfo & QWindowsContext::SI_SupportsPointer) && platformWindow->frameStrutEventsEnabled()) + return sessionManagerInteractionBlocked() || d->m_pointerHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result); + else return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result); - break; case QtWindows::NonClientPointerEvent: if ((d->m_systemInfo & QWindowsContext::SI_SupportsPointer) && platformWindow->frameStrutEventsEnabled()) return sessionManagerInteractionBlocked() || d->m_pointerHandler.translatePointerEvent(platformWindow->window(), hwnd, et, msg, result); @@ -1246,10 +1242,10 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, window = window->parent(); if (!window) return false; - if (!(d->m_systemInfo & QWindowsContext::SI_SupportsPointer)) - return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateMouseEvent(window, hwnd, et, msg, result); - else + if (d->m_systemInfo & QWindowsContext::SI_SupportsPointer) return sessionManagerInteractionBlocked() || d->m_pointerHandler.translateMouseEvent(window, hwnd, et, msg, result); + else + return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateMouseEvent(window, hwnd, et, msg, result); } break; case QtWindows::TouchEvent: diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp index 203d803a1b..f1960f1585 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. @@ -50,9 +50,6 @@ #include "qwindowswindow.h" #include "qwindowsintegration.h" #include "qwindowsscreen.h" -#if QT_CONFIG(draganddrop) -# include "qwindowsdrag.h" -#endif #include <QtGui/qguiapplication.h> #include <QtGui/qscreen.h> @@ -78,111 +75,9 @@ enum { QT_PT_TOUCHPAD = 5, // MinGW is missing PT_TOUCHPAD }; -struct PointerTouchEventInfo { - QPointer<QWindow> window; - QList<QWindowSystemInterface::TouchPoint> points; - Qt::KeyboardModifiers modifiers; -}; - -struct PointerTabletEventInfo { - QPointer<QWindow> window; - QPointF local; - QPointF global; - int device; - int pointerType; - Qt::MouseButtons buttons; - qreal pressure; - int xTilt; - int yTilt; - qreal tangentialPressure; - qreal rotation; - int z; - qint64 uid; - Qt::KeyboardModifiers modifiers; -}; - -static QQueue<PointerTouchEventInfo> touchEventQueue; -static QQueue<PointerTabletEventInfo> tabletEventQueue; - -static void enqueueTouchEvent(QWindow *window, - const QList<QWindowSystemInterface::TouchPoint> &points, - Qt::KeyboardModifiers modifiers) -{ - PointerTouchEventInfo eventInfo; - eventInfo.window = window; - eventInfo.points = points; - eventInfo.modifiers = modifiers; - touchEventQueue.enqueue(eventInfo); -} - -static void enqueueTabletEvent(QWindow *window, const QPointF &local, const QPointF &global, - int device, int pointerType, Qt::MouseButtons buttons, qreal pressure, - int xTilt, int yTilt, qreal tangentialPressure, qreal rotation, - int z, qint64 uid, Qt::KeyboardModifiers modifiers) -{ - PointerTabletEventInfo eventInfo; - eventInfo.window = window; - eventInfo.local = local; - eventInfo.global = global; - eventInfo.device = device; - eventInfo.pointerType = pointerType; - eventInfo.buttons = buttons; - eventInfo.pressure = pressure; - eventInfo.xTilt = xTilt; - eventInfo.yTilt = yTilt; - eventInfo.tangentialPressure = tangentialPressure; - eventInfo.rotation = rotation; - eventInfo.z = z; - eventInfo.uid = uid; - eventInfo.modifiers = modifiers; - tabletEventQueue.enqueue(eventInfo); -} - -static void flushTouchEvents(QTouchDevice *touchDevice) -{ - while (!touchEventQueue.isEmpty()) { - PointerTouchEventInfo eventInfo = touchEventQueue.dequeue(); - if (eventInfo.window) { - QWindowSystemInterface::handleTouchEvent(eventInfo.window, - touchDevice, - eventInfo.points, - eventInfo.modifiers); - } - } -} - -static void flushTabletEvents() -{ - while (!tabletEventQueue.isEmpty()) { - PointerTabletEventInfo eventInfo = tabletEventQueue.dequeue(); - if (eventInfo.window) { - QWindowSystemInterface::handleTabletEvent(eventInfo.window, - eventInfo.local, - eventInfo.global, - eventInfo.device, - eventInfo.pointerType, - eventInfo.buttons, - eventInfo.pressure, - eventInfo.xTilt, - eventInfo.yTilt, - eventInfo.tangentialPressure, - eventInfo.rotation, - eventInfo.z, - eventInfo.uid, - eventInfo.modifiers); - } - } -} - bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result) { *result = 0; - - // If we are inside the move/resize modal loop, let DefWindowProc() handle it (but process NC button release). - QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window->handle()); - if (msg.message != WM_NCPOINTERUP && platformWindow->testFlag(QWindowsWindow::ResizeMoveActive)) - return false; - const quint32 pointerId = GET_POINTERID_WPARAM(msg.wParam); POINTER_INPUT_TYPE pointerType; @@ -191,30 +86,12 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q return false; } - m_lastPointerType = pointerType; - - // Handle non-client pen/touch as generic mouse events for compatibility with QDockWindow. - if ((pointerType == QT_PT_TOUCH || pointerType == QT_PT_PEN) && (et & QtWindows::NonClientEventFlag)) { - POINTER_INFO pointerInfo; - if (!QWindowsContext::user32dll.getPointerInfo(pointerId, &pointerInfo)) { - qWarning() << "GetPointerInfo() failed:" << qt_error_string(); - return false; - } - if (pointerInfo.pointerFlags & (POINTER_FLAG_UP | POINTER_FLAG_DOWN)) - return translateMouseTouchPadEvent(window, hwnd, et, msg, &pointerInfo); - return false; - } - switch (pointerType) { case QT_PT_POINTER: case QT_PT_MOUSE: case QT_PT_TOUCHPAD: { - POINTER_INFO pointerInfo; - if (!QWindowsContext::user32dll.getPointerInfo(pointerId, &pointerInfo)) { - qWarning() << "GetPointerInfo() failed:" << qt_error_string(); - return false; - } - return translateMouseTouchPadEvent(window, hwnd, et, msg, &pointerInfo); + // Let Mouse/TouchPad be handled using legacy messages. + return false; } case QT_PT_TOUCH: { quint32 pointerCount = 0; @@ -290,76 +167,71 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q return false; } -static void getMouseEventInfo(UINT message, POINTER_BUTTON_CHANGE_TYPE changeType, QEvent::Type *eventType, Qt::MouseButton *mouseButton) +namespace { +struct MouseEvent { + QEvent::Type type; + Qt::MouseButton button; +}; +} // namespace + +static inline Qt::MouseButton extraButton(WPARAM wParam) // for WM_XBUTTON... { - static const QHash<POINTER_BUTTON_CHANGE_TYPE, Qt::MouseButton> buttonMapping { - {POINTER_CHANGE_FIRSTBUTTON_DOWN, Qt::LeftButton}, - {POINTER_CHANGE_FIRSTBUTTON_UP, Qt::LeftButton}, - {POINTER_CHANGE_SECONDBUTTON_DOWN, Qt::RightButton}, - {POINTER_CHANGE_SECONDBUTTON_UP, Qt::RightButton}, - {POINTER_CHANGE_THIRDBUTTON_DOWN, Qt::MiddleButton}, - {POINTER_CHANGE_THIRDBUTTON_UP, Qt::MiddleButton}, - {POINTER_CHANGE_FOURTHBUTTON_DOWN, Qt::XButton1}, - {POINTER_CHANGE_FOURTHBUTTON_UP, Qt::XButton1}, - {POINTER_CHANGE_FIFTHBUTTON_DOWN, Qt::XButton2}, - {POINTER_CHANGE_FIFTHBUTTON_UP, Qt::XButton2}, - }; - - static const POINTER_BUTTON_CHANGE_TYPE downChanges[] = { - POINTER_CHANGE_FIRSTBUTTON_DOWN, - POINTER_CHANGE_SECONDBUTTON_DOWN, - POINTER_CHANGE_THIRDBUTTON_DOWN, - POINTER_CHANGE_FOURTHBUTTON_DOWN, - POINTER_CHANGE_FIFTHBUTTON_DOWN, - }; - - static const POINTER_BUTTON_CHANGE_TYPE upChanges[] = { - POINTER_CHANGE_FIRSTBUTTON_UP, - POINTER_CHANGE_SECONDBUTTON_UP, - POINTER_CHANGE_THIRDBUTTON_UP, - POINTER_CHANGE_FOURTHBUTTON_UP, - POINTER_CHANGE_FIFTHBUTTON_UP, - }; - - if (!eventType || !mouseButton) - return; - - const bool nonClient = message == WM_NCPOINTERUPDATE || - message == WM_NCPOINTERDOWN || - message == WM_NCPOINTERUP; - - if (std::find(std::begin(downChanges), - std::end(downChanges), changeType) < std::end(downChanges)) { - *eventType = nonClient ? QEvent::NonClientAreaMouseButtonPress : - QEvent::MouseButtonPress; - } else if (std::find(std::begin(upChanges), - std::end(upChanges), changeType) < std::end(upChanges)) { - *eventType = nonClient ? QEvent::NonClientAreaMouseButtonRelease : - QEvent::MouseButtonRelease; - } else if (message == WM_POINTERWHEEL || message == WM_POINTERHWHEEL) { - *eventType = QEvent::Wheel; - } else { - *eventType = nonClient ? QEvent::NonClientAreaMouseMove : - QEvent::MouseMove; - } - - *mouseButton = buttonMapping.value(changeType, Qt::NoButton); + return GET_XBUTTON_WPARAM(wParam) == XBUTTON1 ? Qt::BackButton : Qt::ForwardButton; } -static Qt::MouseButtons mouseButtonsFromPointerFlags(POINTER_FLAGS pointerFlags) +static inline MouseEvent eventFromMsg(const MSG &msg) { - Qt::MouseButtons result = Qt::NoButton; - if (pointerFlags & POINTER_FLAG_FIRSTBUTTON) - result |= Qt::LeftButton; - if (pointerFlags & POINTER_FLAG_SECONDBUTTON) - result |= Qt::RightButton; - if (pointerFlags & POINTER_FLAG_THIRDBUTTON) - result |= Qt::MiddleButton; - if (pointerFlags & POINTER_FLAG_FOURTHBUTTON) - result |= Qt::XButton1; - if (pointerFlags & POINTER_FLAG_FIFTHBUTTON) - result |= Qt::XButton2; - return result; + switch (msg.message) { + case WM_MOUSEMOVE: + return {QEvent::MouseMove, Qt::NoButton}; + case WM_LBUTTONDOWN: + return {QEvent::MouseButtonPress, Qt::LeftButton}; + case WM_LBUTTONUP: + return {QEvent::MouseButtonRelease, Qt::LeftButton}; + case WM_LBUTTONDBLCLK: // Qt QPA does not handle double clicks, send as press + return {QEvent::MouseButtonPress, Qt::LeftButton}; + case WM_MBUTTONDOWN: + return {QEvent::MouseButtonPress, Qt::MidButton}; + case WM_MBUTTONUP: + return {QEvent::MouseButtonRelease, Qt::MidButton}; + case WM_MBUTTONDBLCLK: + return {QEvent::MouseButtonPress, Qt::MidButton}; + case WM_RBUTTONDOWN: + return {QEvent::MouseButtonPress, Qt::RightButton}; + case WM_RBUTTONUP: + return {QEvent::MouseButtonRelease, Qt::RightButton}; + case WM_RBUTTONDBLCLK: + return {QEvent::MouseButtonPress, Qt::RightButton}; + case WM_XBUTTONDOWN: + return {QEvent::MouseButtonPress, extraButton(msg.wParam)}; + case WM_XBUTTONUP: + return {QEvent::MouseButtonRelease, extraButton(msg.wParam)}; + case WM_XBUTTONDBLCLK: + return {QEvent::MouseButtonPress, extraButton(msg.wParam)}; + case WM_NCMOUSEMOVE: + return {QEvent::NonClientAreaMouseMove, Qt::NoButton}; + case WM_NCLBUTTONDOWN: + return {QEvent::NonClientAreaMouseButtonPress, Qt::LeftButton}; + case WM_NCLBUTTONUP: + return {QEvent::NonClientAreaMouseButtonRelease, Qt::LeftButton}; + case WM_NCLBUTTONDBLCLK: + return {QEvent::NonClientAreaMouseButtonPress, Qt::LeftButton}; + case WM_NCMBUTTONDOWN: + return {QEvent::NonClientAreaMouseButtonPress, Qt::MidButton}; + case WM_NCMBUTTONUP: + return {QEvent::NonClientAreaMouseButtonRelease, Qt::MidButton}; + case WM_NCMBUTTONDBLCLK: + return {QEvent::NonClientAreaMouseButtonPress, Qt::MidButton}; + case WM_NCRBUTTONDOWN: + return {QEvent::NonClientAreaMouseButtonPress, Qt::RightButton}; + case WM_NCRBUTTONUP: + return {QEvent::NonClientAreaMouseButtonRelease, Qt::RightButton}; + case WM_NCRBUTTONDBLCLK: + return {QEvent::NonClientAreaMouseButtonPress, Qt::RightButton}; + default: // WM_MOUSELEAVE + break; + } + return {QEvent::None, Qt::NoButton}; } static Qt::MouseButtons mouseButtonsFromKeyState(WPARAM keyState) @@ -419,15 +291,6 @@ static bool isValidWheelReceiver(QWindow *candidate) return false; } -static bool isMenuWindow(QWindow *window) -{ - if (window) - if (QObject *fo = window->focusObject()) - if (fo->inherits("QMenu")) - return true; - return false; -} - static QTouchDevice *createTouchDevice() { const int digitizers = GetSystemMetrics(SM_DIGITIZER); @@ -553,71 +416,6 @@ void QWindowsPointerHandler::handleEnterLeave(QWindow *window, m_previousCaptureWindow = hasCapture ? window : nullptr; } -bool QWindowsPointerHandler::translateMouseTouchPadEvent(QWindow *window, HWND hwnd, - QtWindows::WindowsEventType et, - MSG msg, PVOID vPointerInfo) -{ - POINTER_INFO *pointerInfo = static_cast<POINTER_INFO *>(vPointerInfo); - const QPoint globalPos = QPoint(pointerInfo->ptPixelLocation.x, pointerInfo->ptPixelLocation.y); - const QPoint localPos = QWindowsGeometryHint::mapFromGlobal(hwnd, globalPos); - const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers(); - const Qt::MouseButtons mouseButtons = mouseButtonsFromPointerFlags(pointerInfo->pointerFlags); - QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos); - - switch (msg.message) { - case WM_NCPOINTERDOWN: - case WM_NCPOINTERUP: - case WM_NCPOINTERUPDATE: - case WM_POINTERDOWN: - case WM_POINTERUP: - case WM_POINTERUPDATE: { - - QEvent::Type eventType; - Qt::MouseButton button; - getMouseEventInfo(msg.message, pointerInfo->ButtonChangeType, &eventType, &button); - - if (et & QtWindows::NonClientEventFlag) { - QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, mouseButtons, button, eventType, - keyModifiers, Qt::MouseEventNotSynthesized); - return false; // To allow window dragging, etc. - } else { - - handleCaptureRelease(window, currentWindowUnderPointer, hwnd, eventType, mouseButtons); - handleEnterLeave(window, currentWindowUnderPointer, globalPos); - - QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos, mouseButtons, button, eventType, - keyModifiers, Qt::MouseEventNotSynthesized); - - // The initial down click over the QSizeGrip area, which posts a resize WM_SYSCOMMAND - // has go to through DefWindowProc() for resizing to work, so we return false here, - // unless the click was on a menu, as it would mess with menu processing. - return msg.message != WM_POINTERDOWN || isMenuWindow(window); - } - } - case WM_POINTERHWHEEL: - case WM_POINTERWHEEL: { - - if (!isValidWheelReceiver(window)) - return true; - - int delta = GET_WHEEL_DELTA_WPARAM(msg.wParam); - - // Qt horizontal wheel rotation orientation is opposite to the one in WM_POINTERHWHEEL - if (msg.message == WM_POINTERHWHEEL) - delta = -delta; - - const QPoint angleDelta = (msg.message == WM_POINTERHWHEEL || (keyModifiers & Qt::AltModifier)) ? - QPoint(delta, 0) : QPoint(0, delta); - - QWindowSystemInterface::handleWheelEvent(window, localPos, globalPos, QPoint(), angleDelta, keyModifiers); - return true; - } - case WM_POINTERLEAVE: - return true; - } - return false; -} - bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, PVOID vTouchInfo, quint32 count) @@ -653,15 +451,14 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd, QList<QWindowSystemInterface::TouchPoint> touchPoints; - bool primaryPointer = false; - bool pressRelease = false; - if (QWindowsContext::verbose > 1) qCDebug(lcQpaEvents).noquote().nospace() << showbase << __FUNCTION__ << " message=" << hex << msg.message << " count=" << dec << count; + Qt::TouchPointStates allStates = 0; + for (quint32 i = 0; i < count; ++i) { if (QWindowsContext::verbose > 1) qCDebug(lcQpaEvents).noquote().nospace() << showbase @@ -670,7 +467,13 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd, << " flags=" << hex << touchInfo[i].pointerInfo.pointerFlags; QWindowSystemInterface::TouchPoint touchPoint; - touchPoint.id = touchInfo[i].pointerInfo.pointerId; + const quint32 pointerId = touchInfo[i].pointerInfo.pointerId; + int id = m_touchInputIDToTouchPointID.value(pointerId, -1); + if (id == -1) { + id = m_touchInputIDToTouchPointID.size(); + m_touchInputIDToTouchPointID.insert(pointerId, id); + } + touchPoint.id = id; touchPoint.pressure = (touchInfo[i].touchMask & TOUCH_MASK_PRESSURE) ? touchInfo[i].pressure / 1024.0 : 1.0; if (m_lastTouchPositions.contains(touchPoint.id)) @@ -691,32 +494,27 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd, if (touchInfo[i].pointerInfo.pointerFlags & POINTER_FLAG_DOWN) { touchPoint.state = Qt::TouchPointPressed; m_lastTouchPositions.insert(touchPoint.id, touchPoint.normalPosition); - pressRelease = true; } else if (touchInfo[i].pointerInfo.pointerFlags & POINTER_FLAG_UP) { touchPoint.state = Qt::TouchPointReleased; m_lastTouchPositions.remove(touchPoint.id); - pressRelease = true; } else { touchPoint.state = stationaryTouchPoint ? Qt::TouchPointStationary : Qt::TouchPointMoved; m_lastTouchPositions.insert(touchPoint.id, touchPoint.normalPosition); } - if (touchInfo[i].pointerInfo.pointerFlags & POINTER_FLAG_PRIMARY) - primaryPointer = true; + allStates |= touchPoint.state; touchPoints.append(touchPoint); // Avoid getting repeated messages for this frame if there are multiple pointerIds QWindowsContext::user32dll.skipPointerFrameMessages(touchInfo[i].pointerInfo.pointerId); } - if (primaryPointer && !pressRelease) { - // Postpone event delivery to avoid hanging inside DoDragDrop(). - // Only the primary pointer will generate mouse messages. - enqueueTouchEvent(window, touchPoints, QWindowsKeyMapper::queryKeyboardModifiers()); - } else { - flushTouchEvents(m_touchDevice); - QWindowSystemInterface::handleTouchEvent(window, m_touchDevice, touchPoints, - QWindowsKeyMapper::queryKeyboardModifiers()); - } + + // all touch points released, forget the ids we've seen. + if (allStates == Qt::TouchPointReleased) + m_touchInputIDToTouchPointID.clear(); + + QWindowSystemInterface::handleTouchEvent(window, m_touchDevice, touchPoints, + QWindowsKeyMapper::queryKeyboardModifiers()); return false; // Allow mouse messages to be generated. } @@ -807,10 +605,9 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin } const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers(); - // Postpone event delivery to avoid hanging inside DoDragDrop(). - enqueueTabletEvent(target, localPos, hiResGlobalPos, device, type, mouseButtons, - pressure, xTilt, yTilt, tangentialPressure, rotation, z, - pointerId, keyModifiers); + QWindowSystemInterface::handleTabletEvent(target, localPos, hiResGlobalPos, device, type, mouseButtons, + pressure, xTilt, yTilt, tangentialPressure, rotation, z, + pointerId, keyModifiers); return false; // Allow mouse messages to be generated. } } @@ -835,18 +632,46 @@ static inline bool isMouseEventSynthesizedFromPenOrTouch() return ((::GetMessageExtraInfo() & SIGNATURE_MASK) == MI_WP_SIGNATURE); } -// Process old-style mouse messages here. -bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, LRESULT *result) +bool QWindowsPointerHandler::translateMouseWheelEvent(QWindow *window, + QWindow *currentWindowUnderPointer, + MSG msg, + QPoint globalPos, + Qt::KeyboardModifiers keyModifiers) { - // Generate enqueued events. - flushTouchEvents(m_touchDevice); - flushTabletEvents(); + QWindow *receiver = currentWindowUnderPointer; + if (!isValidWheelReceiver(receiver)) + receiver = window; + if (!isValidWheelReceiver(receiver)) + return true; + int delta = GET_WHEEL_DELTA_WPARAM(msg.wParam); + + // Qt horizontal wheel rotation orientation is opposite to the one in WM_MOUSEHWHEEL + if (msg.message == WM_MOUSEHWHEEL) + delta = -delta; + + const QPoint angleDelta = (msg.message == WM_MOUSEHWHEEL || (keyModifiers & Qt::AltModifier)) ? + QPoint(delta, 0) : QPoint(0, delta); + + QPoint localPos = QWindowsGeometryHint::mapFromGlobal(receiver, globalPos); + + QWindowSystemInterface::handleWheelEvent(window, localPos, globalPos, QPoint(), angleDelta, keyModifiers); + return true; +} + +// Process legacy mouse messages here. +bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, + HWND hwnd, + QtWindows::WindowsEventType et, + MSG msg, + LRESULT *result) +{ *result = 0; const QPoint eventPos(GET_X_LPARAM(msg.lParam), GET_Y_LPARAM(msg.lParam)); QPoint localPos; QPoint globalPos; + if ((et == QtWindows::MouseWheelEvent) || (et & QtWindows::NonClientEventFlag)) { globalPos = eventPos; localPos = QWindowsGeometryHint::mapFromGlobal(hwnd, eventPos); @@ -857,46 +682,39 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtW const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers(); const Qt::MouseButtons mouseButtons = mouseButtonsFromKeyState(msg.wParam); + QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos); - // Handle "press and hold for right-clicking". - // We have to synthesize it here as it only comes from Windows as a fake RMB. - // MS docs say we could use bit 7 from extraInfo to distinguish pen from touch, - // but on the Surface it is set for both. So we use the last pointer type. - if (isMouseEventSynthesizedFromPenOrTouch()) { - if ((msg.message == WM_RBUTTONDOWN || msg.message == WM_RBUTTONUP) - && (((m_lastPointerType == QT_PT_PEN) - && QCoreApplication::testAttribute(Qt::AA_SynthesizeMouseForUnhandledTabletEvents)) - || ((m_lastPointerType == QT_PT_TOUCH) - && QCoreApplication::testAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents)))) { - QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos, mouseButtons, Qt::RightButton, - (msg.message == WM_RBUTTONDOWN) ? QEvent::MouseButtonPress - : QEvent::MouseButtonRelease, - keyModifiers, Qt::MouseEventSynthesizedBySystem); - } - // Messages synthesized from touch/pen are only used for flushing queues and press&hold. - return false; + if (et == QtWindows::MouseWheelEvent) + return translateMouseWheelEvent(window, currentWindowUnderPointer, msg, globalPos, keyModifiers); + + // Windows sends a mouse move with no buttons pressed to signal "Enter" + // when a window is shown over the cursor. Discard the event and only use + // it for generating QEvent::Enter to be consistent with other platforms - + // X11 and macOS. + bool discardEvent = false; + if (msg.message == WM_MOUSEMOVE) { + static QPoint lastMouseMovePos; + if (msg.wParam == 0 && (m_windowUnderPointer.isNull() || globalPos == lastMouseMovePos)) + discardEvent = true; + lastMouseMovePos = globalPos; } - if (et == QtWindows::MouseWheelEvent) { + Qt::MouseEventSource source = Qt::MouseEventNotSynthesized; + if (isMouseEventSynthesizedFromPenOrTouch()) { + if (QWindowsIntegration::instance()->options() & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch) + return false; + source = Qt::MouseEventSynthesizedBySystem; + } - if (!isValidWheelReceiver(window)) - return true; + const MouseEvent mouseEvent = eventFromMsg(msg); - int delta = GET_WHEEL_DELTA_WPARAM(msg.wParam); - - // Qt horizontal wheel rotation orientation is opposite to the one in WM_MOUSEHWHEEL - if (msg.message == WM_MOUSEHWHEEL) - delta = -delta; - - const QPoint angleDelta = (msg.message == WM_MOUSEHWHEEL || (keyModifiers & Qt::AltModifier)) ? - QPoint(delta, 0) : QPoint(0, delta); - - QWindowSystemInterface::handleWheelEvent(window, localPos, globalPos, QPoint(), angleDelta, keyModifiers); - return true; + if (mouseEvent.type >= QEvent::NonClientAreaMouseMove && mouseEvent.type <= QEvent::NonClientAreaMouseButtonDblClick) { + QWindowSystemInterface::handleFrameStrutMouseEvent(window, localPos, globalPos, mouseButtons, + mouseEvent.button, mouseEvent.type, keyModifiers, source); + return false; // Allow further event processing } if (msg.message == WM_MOUSELEAVE) { - if (window == m_currentWindow) { QWindow *leaveTarget = m_windowUnderPointer ? m_windowUnderPointer : m_currentWindow; qCDebug(lcQpaEvents) << "Leaving window " << leaveTarget; @@ -904,14 +722,21 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, HWND hwnd, QtW m_windowUnderPointer = nullptr; m_currentWindow = nullptr; } - - } else if (msg.message == WM_MOUSEMOVE) { - - QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos); - handleCaptureRelease(window, currentWindowUnderPointer, hwnd, QEvent::MouseMove, mouseButtons); - handleEnterLeave(window, currentWindowUnderPointer, globalPos); + return true; } - return false; + + handleCaptureRelease(window, currentWindowUnderPointer, hwnd, mouseEvent.type, mouseButtons); + handleEnterLeave(window, currentWindowUnderPointer, globalPos); + + if (!discardEvent && mouseEvent.type != QEvent::None) { + QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos, mouseButtons, + mouseEvent.button, mouseEvent.type, keyModifiers, source); + } + + // QTBUG-48117, force synchronous handling for the extra buttons so that WM_APPCOMMAND + // is sent for unhandled WM_XBUTTONDOWN. + return (msg.message != WM_XBUTTONUP && msg.message != WM_XBUTTONDOWN && msg.message != WM_XBUTTONDBLCLK) + || QWindowSystemInterface::flushWindowSystemEvents(); } QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.h b/src/plugins/platforms/windows/qwindowspointerhandler.h index ec3179e821..aebef062bc 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.h +++ b/src/plugins/platforms/windows/qwindowspointerhandler.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. @@ -66,19 +66,19 @@ public: void clearWindowUnderMouse() { m_windowUnderPointer = nullptr; } private: - bool translateMouseTouchPadEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, PVOID vPointerInfo); bool translateTouchEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, PVOID vTouchInfo, unsigned int count); bool translatePenEvent(QWindow *window, HWND hwnd, QtWindows::WindowsEventType et, MSG msg, PVOID vPenInfo); + bool translateMouseWheelEvent(QWindow *window, QWindow *currentWindowUnderPointer, MSG msg, QPoint globalPos, Qt::KeyboardModifiers keyModifiers); void handleCaptureRelease(QWindow *window, QWindow *currentWindowUnderPointer, HWND hwnd, QEvent::Type eventType, Qt::MouseButtons mouseButtons); void handleEnterLeave(QWindow *window, QWindow *currentWindowUnderPointer, QPoint globalPos); QTouchDevice *m_touchDevice = nullptr; QHash<int, QPointF> m_lastTouchPositions; + QHash<DWORD, int> m_touchInputIDToTouchPointID; QPointer<QWindow> m_windowUnderPointer; QPointer<QWindow> m_currentWindow; QWindow *m_previousCaptureWindow = nullptr; bool m_needsEnterOnPointerUpdate = false; - DWORD m_lastPointerType = 0; }; QT_END_NAMESPACE From 81fd7f4c8af260d753a834480f790c82fb161889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= <tor.arne.vestbo@qt.io> Date: Tue, 12 Feb 2019 14:06:08 +0100 Subject: [PATCH 1142/1650] macOS: Add auto-release pool during QCocoaScreen::deliverUpdateRequests() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Checking the application's keyWindow will autorelease the window, and there's no root pool in place when called from the display-link thread. Change-Id: Ic43164ad6397c92b858fb549f7a00e28b6110849 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> --- src/plugins/platforms/cocoa/qcocoascreen.mm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoascreen.mm b/src/plugins/platforms/cocoa/qcocoascreen.mm index 80dd7e40d3..830a387fd1 100644 --- a/src/plugins/platforms/cocoa/qcocoascreen.mm +++ b/src/plugins/platforms/cocoa/qcocoascreen.mm @@ -269,6 +269,8 @@ struct DeferredDebugHelper void QCocoaScreen::deliverUpdateRequests() { + QMacAutoReleasePool pool; + // The CVDisplayLink callback is a notification that it's a good time to produce a new frame. // Since the callback is delivered on a separate thread we have to marshal it over to the // main thread, as Qt requires update requests to be delivered there. This needs to happen From 078cc302cb4f03ffdcee3696338385c33427c716 Mon Sep 17 00:00:00 2001 From: Lorn Potter <lorn.potter@gmail.com> Date: Thu, 7 Feb 2019 05:20:37 +1000 Subject: [PATCH 1143/1650] wasm: fix build with emsdk 1.38.26 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit emscripten removed their fake SSE support, which removed x86intrin.h Task-number: QTBUG-73657 Change-Id: I77094fc77be3e685adf9e16d8c3e6aebde9b0687 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io> --- src/corelib/global/qprocessordetection.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h index 77b3ba36b0..1f327c352e 100644 --- a/src/corelib/global/qprocessordetection.h +++ b/src/corelib/global/qprocessordetection.h @@ -324,7 +324,6 @@ // -- Web Assembly -- #elif defined(__EMSCRIPTEN__) # define Q_PROCESSOR_WASM -# define Q_PROCESSOR_X86 6 // enables SIMD support # define Q_BYTE_ORDER Q_LITTLE_ENDIAN # define Q_PROCESSOR_WORDSIZE 8 #endif From 960af0d64de576321db91ccbe426891465b24540 Mon Sep 17 00:00:00 2001 From: Lorn Potter <lorn.potter@gmail.com> Date: Wed, 30 Jan 2019 18:17:39 +1000 Subject: [PATCH 1144/1650] wasm: remove EM_ASM calls in wasm platform plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I8453836b6730d18eaaa4ffe1fb9cb3933079ebee Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io> --- src/plugins/platforms/wasm/qwasmcursor.cpp | 7 ++-- .../platforms/wasm/qwasmeventtranslator.cpp | 33 ++++++++++--------- .../platforms/wasm/qwasmintegration.cpp | 17 ++++------ src/plugins/platforms/wasm/qwasmscreen.cpp | 5 ++- 4 files changed, 27 insertions(+), 35 deletions(-) diff --git a/src/plugins/platforms/wasm/qwasmcursor.cpp b/src/plugins/platforms/wasm/qwasmcursor.cpp index 54804a55b3..90431ab6a5 100644 --- a/src/plugins/platforms/wasm/qwasmcursor.cpp +++ b/src/plugins/platforms/wasm/qwasmcursor.cpp @@ -32,6 +32,7 @@ #include <QtCore/qdebug.h> #include <emscripten/emscripten.h> +#include <emscripten/bind.h> void QWasmCursor::changeCursor(QCursor *windowCursor, QWindow *window) { @@ -52,11 +53,7 @@ void QWasmCursor::changeCursor(QCursor *windowCursor, QWindow *window) htmlCursorName = "auto"; // Set cursor on the main canvas - EM_ASM_ARGS({ - if (Module['canvas']) { - Module['canvas'].style['cursor'] = Pointer_stringify($0); - } - }, htmlCursorName.constData()); + emscripten::val::global("window").set("cursor", emscripten::val(htmlCursorName.constData())); } QByteArray QWasmCursor::cursorShapeToHtml(Qt::CursorShape shape) diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp index 8ab109f03c..ea88ef59a0 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp @@ -52,12 +52,17 @@ static bool g_usePlatformMacCtrlMetaSwitching = false; bool g_useNaturalScrolling = true; // natural scrolling is default on linux/windows -void setNaturalScrolling(bool use) { - g_useNaturalScrolling = use; +static void mouseWheelEvent(emscripten::val event) { + + emscripten::val wheelInterted = event["webkitDirectionInvertedFromDevice"]; + + if (wheelInterted.as<bool>()) { + g_useNaturalScrolling = true; + } } EMSCRIPTEN_BINDINGS(mouse_module) { - function("setNaturalScrolling", &setNaturalScrolling); + function("mouseWheelEvent", &mouseWheelEvent); } QWasmEventTranslator::QWasmEventTranslator(QObject *parent) @@ -93,23 +98,19 @@ QWasmEventTranslator::QWasmEventTranslator(QObject *parent) GenericPlatform, MacOSPlatform }; - Platform platform = - Platform(EM_ASM_INT("if (navigator.platform.includes(\"Mac\")) return 1; return 0;")); - + Platform platform = Platform(emscripten::val::global("navigator")["platform"] + .call<bool>("includes", emscripten::val("Mac"))); g_usePlatformMacCtrlMetaSwitching = (platform == MacOSPlatform); if (platform == MacOSPlatform) { g_useNaturalScrolling = false; // make this !default on macOS - EM_ASM( - if (window.safari !== undefined) {//this only works on safari - Module["canvas"].addEventListener('wheel', mouseWheelEvent); - function mouseWheelEvent(e) { - if (event.webkitDirectionInvertedFromDevice) { - Module.setNaturalScrolling(event.webkitDirectionInvertedFromDevice); - } - } - } - ); + + if (emscripten::val::global("window")["safari"].isUndefined()) { + + emscripten::val::global("canvas").call<void>("addEventListener", + std::string("wheel"), + val::module_property("mouseWheelEvent")); + } } } diff --git a/src/plugins/platforms/wasm/qwasmintegration.cpp b/src/plugins/platforms/wasm/qwasmintegration.cpp index 1be909f0a0..7a44c47893 100644 --- a/src/plugins/platforms/wasm/qwasmintegration.cpp +++ b/src/plugins/platforms/wasm/qwasmintegration.cpp @@ -55,7 +55,7 @@ using namespace emscripten; QT_BEGIN_NAMESPACE -void browserBeforeUnload() +void browserBeforeUnload(emscripten::val) { QWasmIntegration::QWasmBrowserExit(); } @@ -83,11 +83,8 @@ QWasmIntegration::QWasmIntegration() m_eventTranslator = new QWasmEventTranslator; - EM_ASM(// exit app if browser closes - window.onbeforeunload = function () { - Module.browserBeforeUnload(); - }; - ); + emscripten::val::global("window").set("onbeforeunload", val::module_property("browserBeforeUnload")); + } QWasmIntegration::~QWasmIntegration() @@ -187,11 +184,9 @@ int QWasmIntegration::uiEvent_cb(int eventType, const EmscriptenUiEvent *e, void static void set_canvas_size(double width, double height) { - EM_ASM_({ - var canvas = Module.canvas; - canvas.width = $0; - canvas.height = $1; - }, width, height); + emscripten::val canvas = emscripten::val::global("canvas"); + canvas.set("width", width); + canvas.set("height", height); } void QWasmIntegration::updateQScreenAndCanvasRenderSize() diff --git a/src/plugins/platforms/wasm/qwasmscreen.cpp b/src/plugins/platforms/wasm/qwasmscreen.cpp index 93e9906ffc..37f1efadc6 100644 --- a/src/plugins/platforms/wasm/qwasmscreen.cpp +++ b/src/plugins/platforms/wasm/qwasmscreen.cpp @@ -30,6 +30,7 @@ #include "qwasmscreen.h" #include "qwasmwindow.h" #include "qwasmcompositor.h" +#include <emscripten/bind.h> #include <QtEglSupport/private/qeglconvenience_p.h> #ifndef QT_NO_OPENGL @@ -77,9 +78,7 @@ qreal QWasmScreen::devicePixelRatio() const // HTML window dpr if the OpenGL driver/GPU allocates a less than // full resolution surface. Use emscripten_webgl_get_drawing_buffer_size() // and compute the dpr instead. - double htmlWindowDpr = EM_ASM_DOUBLE({ - return window.devicePixelRatio; - }); + double htmlWindowDpr = emscripten::val::global("window")["devicePixelRatio"].as<double>(); return qreal(htmlWindowDpr); } From 64fab8f7e2d225e37aa731db7501b5d5b82eab64 Mon Sep 17 00:00:00 2001 From: Joni Poikelin <joni.poikelin@qt.io> Date: Thu, 3 Jan 2019 11:52:15 +0200 Subject: [PATCH 1145/1650] Add faster path for scaling QRegion with multiple regions Fixes: QTBUG-72821 Change-Id: Ic4fa349087239337a77b0e280be551b46c75af71 Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> --- src/gui/painting/qtransform.cpp | 19 ++++++- .../auto/gui/painting/qregion/tst_qregion.cpp | 55 +++++++++++++++++++ 2 files changed, 72 insertions(+), 2 deletions(-) diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp index 5f9e037ff0..816514a695 100644 --- a/src/gui/painting/qtransform.cpp +++ b/src/gui/painting/qtransform.cpp @@ -1517,8 +1517,23 @@ QRegion QTransform::map(const QRegion &r) const return copy; } - if (t == TxScale && r.rectCount() == 1) - return QRegion(mapRect(r.boundingRect())); + if (t == TxScale) { + QRegion res; + if (m11() < 0 || m22() < 0) { + for (const QRect &rect : r) + res += mapRect(rect); + } else { + QVarLengthArray<QRect, 32> rects; + rects.reserve(r.rectCount()); + for (const QRect &rect : r) { + QRect nr = mapRect(rect); + if (!nr.isEmpty()) + rects.append(nr); + } + res.setRects(rects.constData(), rects.count()); + } + return res; + } QPainterPath p = map(qt_regionToPath(r)); return p.toFillPolygon(QTransform()).toPolygon(); diff --git a/tests/auto/gui/painting/qregion/tst_qregion.cpp b/tests/auto/gui/painting/qregion/tst_qregion.cpp index 5256fbd1dc..24c4583819 100644 --- a/tests/auto/gui/painting/qregion/tst_qregion.cpp +++ b/tests/auto/gui/painting/qregion/tst_qregion.cpp @@ -84,6 +84,8 @@ private slots: #endif void regionFromPath(); + void scaleRegions_data(); + void scaleRegions(); #ifdef QT_BUILD_INTERNAL void regionToPath_data(); @@ -973,6 +975,59 @@ void tst_QRegion::regionFromPath() } } +void tst_QRegion::scaleRegions_data() +{ + QTest::addColumn<qreal>("scale"); + QTest::addColumn<QVector<QRect>>("inputRects"); + QTest::addColumn<QVector<QRect>>("expectedRects"); + + QTest::newRow("1.0 single") << 1.0 + << QVector<QRect>{ QRect(10, 10, 20, 20) } + << QVector<QRect>{ QRect(10, 10, 20, 20) }; + QTest::newRow("1.0 multi") << 1.0 + << QVector<QRect>{ QRect(10, 10, 20, 20), QRect(40, 10, 20, 20) } + << QVector<QRect>{ QRect(10, 10, 20, 20), QRect(40, 10, 20, 20) }; + QTest::newRow("2.0 single") << 2.0 + << QVector<QRect>{ QRect(10, 10, 20, 20) } + << QVector<QRect>{ QRect(20, 20, 40, 40) }; + QTest::newRow("2.0 multi") << 2.0 + << QVector<QRect>{ QRect(10, 10, 20, 20), QRect(40, 10, 20, 20) } + << QVector<QRect>{ QRect(20, 20, 40, 40), QRect(80, 20, 40, 40) }; + QTest::newRow("-1.0 single") << -1.0 + << QVector<QRect>{ QRect(10, 10, 20, 20) } + << QVector<QRect>{ QRect(-30, -30, 20, 20) }; + QTest::newRow("-1.0 multi") << -1.0 + << QVector<QRect>{ QRect(10, 10, 20, 20), QRect(40, 10, 20, 20) } + << QVector<QRect>{ QRect(-60, -30, 20, 20), QRect(-30, -30, 20, 20) }; + QTest::newRow("-2.0 single") << -2.0 + << QVector<QRect>{ QRect(10, 10, 20, 20) } + << QVector<QRect>{ QRect(-60, -60, 40, 40) }; + QTest::newRow("-2.0 multi") << -2.0 + << QVector<QRect>{ QRect(10, 10, 20, 20), QRect(40, 10, 20, 20) } + << QVector<QRect>{ QRect(-120, -60, 40, 40), QRect(-60, -60, 40, 40) }; +} + +void tst_QRegion::scaleRegions() +{ + QFETCH(qreal, scale); + QFETCH(QVector<QRect>, inputRects); + QFETCH(QVector<QRect>, expectedRects); + + QRegion region; + region.setRects(inputRects.constData(), inputRects.size()); + + QRegion expected(expectedRects.first()); + expected.setRects(expectedRects.constData(), expectedRects.size()); + + QTransform t; + t.scale(scale, scale); + + auto result = t.map(region); + + QCOMPARE(result.rectCount(), expectedRects.size()); + QCOMPARE(result, expected); +} + Q_DECLARE_METATYPE(QPainterPath) #ifdef QT_BUILD_INTERNAL From d99162754f225ca98318e96184e80a57c33fa1ed Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Sat, 2 Feb 2019 22:03:42 +0100 Subject: [PATCH 1146/1650] QStyleSheet/QToolbox: don't overlap text and icon When an icon was specified with a style sheet, the content rect for the toolbox label was not adjusted which results in an overlapping of the text and the icon. Fix it by adjusting the rect used by drawing the label when an icon is specified with a style sheet. Fixes: QTBUG-40871 Change-Id: I088b319e6355d78066d0bc4472882a5d9a599091 Reviewed-by: Frederik Gladhorn <frederik.gladhorn@qt.io> Reviewed-by: Vitaly Fanaskov <vitaly.fanaskov@qt.io> --- src/widgets/styles/qstylesheetstyle.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index e73d019408..c0f0321fce 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -4089,6 +4089,11 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q if (subRule.hasFont) p->setFont(subRule.font); boxCopy.rect = subRule.contentsRect(opt->rect); + if (subRule.hasImage()) { + // the image is already drawn with CE_ToolBoxTabShape, adjust rect here + const int iconExtent = proxy()->pixelMetric(QStyle::PM_SmallIconSize, box, w); + boxCopy.rect.setLeft(boxCopy.rect.left() + iconExtent); + } QWindowsStyle::drawControl(ce, &boxCopy, p , w); if (subRule.hasFont) p->setFont(oldFont); From ee845dfc3907cde91ffe79d9c2372d92ae900813 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Sat, 9 Feb 2019 14:33:46 +0100 Subject: [PATCH 1147/1650] QtGui: compile with QT_DISABLE_DEPRECATED_BEFORE=0x050d00 Don't call or implement functions which are not available when compiling with QT_DISABLE_DEPRECATED_BEFORE=0x050d00 Change-Id: I763a1c60d7cc080677736447dc358299d8f7ab04 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> --- src/gui/image/qbmphandler.cpp | 2 ++ src/gui/image/qbmphandler_p.h | 3 ++- src/gui/image/qimage.cpp | 2 ++ src/gui/image/qpnghandler.cpp | 2 ++ src/gui/image/qpnghandler_p.h | 2 ++ src/gui/image/qppmhandler.cpp | 2 ++ src/gui/image/qppmhandler_p.h | 2 ++ src/gui/image/qxbmhandler.cpp | 2 ++ src/gui/image/qxbmhandler_p.h | 2 ++ src/gui/image/qxpmhandler.cpp | 2 ++ src/gui/image/qxpmhandler_p.h | 2 ++ src/gui/painting/qtransform.h | 2 ++ src/gui/text/qtextodfwriter.cpp | 2 ++ 13 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp index 7257853c3e..7f8e072322 100644 --- a/src/gui/image/qbmphandler.cpp +++ b/src/gui/image/qbmphandler.cpp @@ -866,10 +866,12 @@ void QBmpHandler::setOption(ImageOption option, const QVariant &value) Q_UNUSED(value); } +#if QT_DEPRECATED_SINCE(5, 13) QByteArray QBmpHandler::name() const { return formatName(); } +#endif QT_END_NAMESPACE diff --git a/src/gui/image/qbmphandler_p.h b/src/gui/image/qbmphandler_p.h index 56b39dd0f0..33b5b9c501 100644 --- a/src/gui/image/qbmphandler_p.h +++ b/src/gui/image/qbmphandler_p.h @@ -113,8 +113,9 @@ public: bool read(QImage *image) override; bool write(const QImage &image) override; +#if QT_DEPRECATED_SINCE(5, 13) QByteArray name() const override; - +#endif static bool canRead(QIODevice *device); QVariant option(ImageOption option) const override; diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 16de045cf0..97123bfec2 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -1450,6 +1450,7 @@ void QImage::setDevicePixelRatio(qreal scaleFactor) d->devicePixelRatio = scaleFactor; } +#if QT_DEPRECATED_SINCE(5, 10) /*! \since 4.6 \obsolete @@ -1466,6 +1467,7 @@ int QImage::byteCount() const Q_ASSERT(!d || d->nbytes < std::numeric_limits<int>::max()); return d ? int(d->nbytes) : 0; } +#endif /*! \since 5.10 diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index 1a5e7718eb..140196004b 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -1197,10 +1197,12 @@ void QPngHandler::setOption(ImageOption option, const QVariant &value) d->scaledSize = value.toSize(); } +#if QT_DEPRECATED_SINCE(5, 13) QByteArray QPngHandler::name() const { return "png"; } +#endif QT_END_NAMESPACE diff --git a/src/gui/image/qpnghandler_p.h b/src/gui/image/qpnghandler_p.h index 4ca716e7c2..5d4da97395 100644 --- a/src/gui/image/qpnghandler_p.h +++ b/src/gui/image/qpnghandler_p.h @@ -69,7 +69,9 @@ public: bool read(QImage *image) override; bool write(const QImage &image) override; +#if QT_DEPRECATED_SINCE(5, 13) QByteArray name() const override; +#endif QVariant option(ImageOption option) const override; void setOption(ImageOption option, const QVariant &value) override; diff --git a/src/gui/image/qppmhandler.cpp b/src/gui/image/qppmhandler.cpp index bfde0aa76e..13ee2eadd2 100644 --- a/src/gui/image/qppmhandler.cpp +++ b/src/gui/image/qppmhandler.cpp @@ -576,10 +576,12 @@ void QPpmHandler::setOption(ImageOption option, const QVariant &value) subType = value.toByteArray().toLower(); } +#if QT_DEPRECATED_SINCE(5, 13) QByteArray QPpmHandler::name() const { return subType.isEmpty() ? QByteArray("ppm") : subType; } +#endif QT_END_NAMESPACE diff --git a/src/gui/image/qppmhandler_p.h b/src/gui/image/qppmhandler_p.h index 1c6fbd6869..f3c9d0f139 100644 --- a/src/gui/image/qppmhandler_p.h +++ b/src/gui/image/qppmhandler_p.h @@ -67,7 +67,9 @@ public: bool read(QImage *image) override; bool write(const QImage &image) override; +#if QT_DEPRECATED_SINCE(5, 13) QByteArray name() const override; +#endif static bool canRead(QIODevice *device, QByteArray *subType = 0); diff --git a/src/gui/image/qxbmhandler.cpp b/src/gui/image/qxbmhandler.cpp index 7ba44049b4..65a5b63bc7 100644 --- a/src/gui/image/qxbmhandler.cpp +++ b/src/gui/image/qxbmhandler.cpp @@ -356,10 +356,12 @@ void QXbmHandler::setOption(ImageOption option, const QVariant &value) fileName = value.toString(); } +#if QT_DEPRECATED_SINCE(5, 13) QByteArray QXbmHandler::name() const { return "xbm"; } +#endif QT_END_NAMESPACE diff --git a/src/gui/image/qxbmhandler_p.h b/src/gui/image/qxbmhandler_p.h index 26439af527..ae590a1944 100644 --- a/src/gui/image/qxbmhandler_p.h +++ b/src/gui/image/qxbmhandler_p.h @@ -66,7 +66,9 @@ public: bool read(QImage *image) override; bool write(const QImage &image) override; +#if QT_DEPRECATED_SINCE(5, 13) QByteArray name() const override; +#endif static bool canRead(QIODevice *device); diff --git a/src/gui/image/qxpmhandler.cpp b/src/gui/image/qxpmhandler.cpp index 17272ffe69..a32dfda96d 100644 --- a/src/gui/image/qxpmhandler.cpp +++ b/src/gui/image/qxpmhandler.cpp @@ -1287,10 +1287,12 @@ void QXpmHandler::setOption(ImageOption option, const QVariant &value) fileName = value.toString(); } +#if QT_DEPRECATED_SINCE(5, 13) QByteArray QXpmHandler::name() const { return "xpm"; } +#endif QT_END_NAMESPACE diff --git a/src/gui/image/qxpmhandler_p.h b/src/gui/image/qxpmhandler_p.h index f118bf2309..a4dd88cd17 100644 --- a/src/gui/image/qxpmhandler_p.h +++ b/src/gui/image/qxpmhandler_p.h @@ -68,7 +68,9 @@ public: static bool canRead(QIODevice *device); +#if QT_DEPRECATED_SINCE(5, 13) QByteArray name() const override; +#endif QVariant option(ImageOption option) const override; void setOption(ImageOption option, const QVariant &value) override; diff --git a/src/gui/painting/qtransform.h b/src/gui/painting/qtransform.h index 7460a405be..1e322d435a 100644 --- a/src/gui/painting/qtransform.h +++ b/src/gui/painting/qtransform.h @@ -245,10 +245,12 @@ inline qreal QTransform::determinant() const return affine._m11*(m_33*affine._m22-affine._dy*m_23) - affine._m21*(m_33*affine._m12-affine._dy*m_13)+affine._dx*(m_23*affine._m12-affine._m22*m_13); } +#if QT_DEPRECATED_SINCE(5, 13) inline qreal QTransform::det() const { return determinant(); } +#endif inline qreal QTransform::m11() const { return affine._m11; diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp index 1a3f5309ae..c8fa5306c3 100644 --- a/src/gui/text/qtextodfwriter.cpp +++ b/src/gui/text/qtextodfwriter.cpp @@ -496,10 +496,12 @@ void QTextOdfWriter::writeFormats(QXmlStreamWriter &writer, const QSet<int> &for else writeFrameFormat(writer, textFormat.toFrameFormat(), formatIndex); break; +#if QT_DEPRECATED_SINCE(5, 3) case QTextFormat::TableFormat: // this case never happens, because TableFormat is a FrameFormat Q_UNREACHABLE(); break; +#endif } } From 7c254024f32ab783385718dea08829c5e0c82408 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Sat, 9 Feb 2019 14:44:43 +0100 Subject: [PATCH 1148/1650] QtWidgets: compile with QT_DISABLE_DEPRECATED_BEFORE=0x050d00 Don't call or implement functions which are not available when compiling with QT_DISABLE_DEPRECATED_BEFORE=0x050d00 Change-Id: If427e20774b358dc16fa1c7d7ba8c0feba3e144b Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> --- src/widgets/dialogs/qdialog.cpp | 2 ++ src/widgets/graphicsview/qgraphicsscene.h | 2 ++ src/widgets/kernel/qapplication.cpp | 2 ++ src/widgets/kernel/qdesktopwidget.cpp | 26 ++++++++++++++++++----- src/widgets/kernel/qdesktopwidget.h | 2 ++ 5 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp index efd2c2ffea..3c49016e2c 100644 --- a/src/widgets/dialogs/qdialog.cpp +++ b/src/widgets/dialogs/qdialog.cpp @@ -779,7 +779,9 @@ void QDialog::setVisible(bool visible) return; QWidget::setVisible(visible); +#if QT_DEPRECATED_SINCE(5, 13) showExtension(d->doShowExtension); +#endif QWidget *fw = window()->focusWidget(); if (!fw) fw = this; diff --git a/src/widgets/graphicsview/qgraphicsscene.h b/src/widgets/graphicsview/qgraphicsscene.h index 71b8fc3013..3cc00ead08 100644 --- a/src/widgets/graphicsview/qgraphicsscene.h +++ b/src/widgets/graphicsview/qgraphicsscene.h @@ -103,7 +103,9 @@ class Q_WIDGETS_EXPORT QGraphicsScene : public QObject Q_PROPERTY(int bspTreeDepth READ bspTreeDepth WRITE setBspTreeDepth) Q_PROPERTY(QPalette palette READ palette WRITE setPalette) Q_PROPERTY(QFont font READ font WRITE setFont) +#if QT_DEPRECATED_SINCE(5, 13) Q_PROPERTY(bool sortCacheEnabled READ isSortCacheEnabled WRITE setSortCacheEnabled) +#endif Q_PROPERTY(bool stickyFocus READ stickyFocus WRITE setStickyFocus) Q_PROPERTY(qreal minimumRenderSize READ minimumRenderSize WRITE setMinimumRenderSize) Q_PROPERTY(bool focusOnTouch READ focusOnTouch WRITE setFocusOnTouch) diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 3594b5c902..7c44bfe39d 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -1243,6 +1243,7 @@ QStyle* QApplication::setStyle(const QString& style) return s; } +#if QT_DEPRECATED_SINCE(5, 8) /*! Returns the color specification. \obsolete @@ -1317,6 +1318,7 @@ void QApplication::setColorSpec(int spec) { Q_UNUSED(spec) } +#endif /*! \property QApplication::globalStrut diff --git a/src/widgets/kernel/qdesktopwidget.cpp b/src/widgets/kernel/qdesktopwidget.cpp index 5fb7882932..d17c7eb36c 100644 --- a/src/widgets/kernel/qdesktopwidget.cpp +++ b/src/widgets/kernel/qdesktopwidget.cpp @@ -176,26 +176,32 @@ void QDesktopWidgetPrivate::_q_updateScreens() // Notice that we trigger screenCountChanged even if a screen was removed and another one added, // in which case the total number of screens did not change. This is the only way for applications // to notice that a screen was swapped out against another one. +#if QT_DEPRECATED_SINCE(5, 11) QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED emit q->screenCountChanged(targetLength); QT_WARNING_POP +#endif } +#if QT_DEPRECATED_SINCE(5, 11) foreach (int changedScreen, changedScreens) QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED emit q->resized(changedScreen); QT_WARNING_POP +#endif } void QDesktopWidgetPrivate::_q_availableGeometryChanged() { +#if QT_DEPRECATED_SINCE(5, 11) Q_Q(QDesktopWidget); if (QScreen *screen = qobject_cast<QScreen *>(q->sender())) QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED emit q->workAreaResized(QGuiApplication::screens().indexOf(screen)); QT_WARNING_POP +#endif } QDesktopWidget::QDesktopWidget() @@ -212,10 +218,12 @@ QDesktopWidget::~QDesktopWidget() { } +#if QT_DEPRECATED_SINCE(5, 11) bool QDesktopWidget::isVirtualDesktop() const { return QDesktopWidgetPrivate::isVirtualDesktop(); } +#endif bool QDesktopWidgetPrivate::isVirtualDesktop() { @@ -242,26 +250,29 @@ int QDesktopWidgetPrivate::height() return geometry().height(); } +#if QT_DEPRECATED_SINCE(5, 11) int QDesktopWidget::primaryScreen() const { return QDesktopWidgetPrivate::primaryScreen(); } +#endif int QDesktopWidgetPrivate::primaryScreen() { return 0; } -int QDesktopWidget::numScreens() const -{ - return QDesktopWidgetPrivate::numScreens(); -} - int QDesktopWidgetPrivate::numScreens() { return qMax(QGuiApplication::screens().size(), 1); } +#if QT_DEPRECATED_SINCE(5, 11) +int QDesktopWidget::numScreens() const +{ + return QDesktopWidgetPrivate::numScreens(); +} + QWidget *QDesktopWidget::screen(int screen) { Q_D(QDesktopWidget); @@ -274,6 +285,7 @@ const QRect QDesktopWidget::availableGeometry(int screenNo) const { return QDesktopWidgetPrivate::availableGeometry(screenNo); } +#endif const QRect QDesktopWidgetPrivate::availableGeometry(int screenNo) { @@ -281,10 +293,12 @@ const QRect QDesktopWidgetPrivate::availableGeometry(int screenNo) return screen ? screen->availableGeometry() : QRect(); } +#if QT_DEPRECATED_SINCE(5, 11) const QRect QDesktopWidget::screenGeometry(int screenNo) const { return QDesktopWidgetPrivate::screenGeometry(screenNo); } +#endif const QRect QDesktopWidgetPrivate::screenGeometry(int screenNo) { @@ -344,10 +358,12 @@ int QDesktopWidgetPrivate::screenNumber(const QWidget *w) return allScreens.indexOf(widgetScreen); } +#if QT_DEPRECATED_SINCE(5, 11) int QDesktopWidget::screenNumber(const QPoint &p) const { return QDesktopWidgetPrivate::screenNumber(p); } +#endif int QDesktopWidgetPrivate::screenNumber(const QPoint &p) { diff --git a/src/widgets/kernel/qdesktopwidget.h b/src/widgets/kernel/qdesktopwidget.h index f986f0db20..e5c587984f 100644 --- a/src/widgets/kernel/qdesktopwidget.h +++ b/src/widgets/kernel/qdesktopwidget.h @@ -52,9 +52,11 @@ class QDesktopWidgetPrivate; class Q_WIDGETS_EXPORT QDesktopWidget : public QWidget { Q_OBJECT +#if QT_DEPRECATED_SINCE(5, 11) Q_PROPERTY(bool virtualDesktop READ isVirtualDesktop) Q_PROPERTY(int screenCount READ screenCount NOTIFY screenCountChanged) Q_PROPERTY(int primaryScreen READ primaryScreen NOTIFY primaryScreenChanged) +#endif public: QDesktopWidget(); ~QDesktopWidget(); From 3c907d0f4a0bbd4f2d4116d9bb0929c51f7cc905 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Sat, 9 Feb 2019 14:41:46 +0100 Subject: [PATCH 1149/1650] Replace QWidget::margin() with QWidget::contentsMargins() Replace deprecated QWidget::margin/setMargin() calls with contentsMargin/setContentsMargins(). Change-Id: I7fe8056196d73d1be97446d40a438cd0b1a13817 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> --- src/printsupport/dialogs/qprintpreviewdialog.cpp | 2 +- src/widgets/dialogs/qcolordialog.cpp | 7 ++++--- src/widgets/dialogs/qmessagebox.cpp | 2 +- src/widgets/dialogs/qwizard.cpp | 8 ++++---- src/widgets/styles/qcommonstyle.cpp | 10 +++++++--- src/widgets/util/qsystemtrayicon.cpp | 2 +- src/widgets/widgets/qabstractscrollarea.cpp | 2 +- src/widgets/widgets/qcalendarwidget.cpp | 6 +++--- src/widgets/widgets/qcombobox.cpp | 2 +- src/widgets/widgets/qdatetimeedit.cpp | 2 +- src/widgets/widgets/qmdisubwindow.cpp | 2 +- src/widgets/widgets/qstatusbar.cpp | 4 ++-- src/widgets/widgets/qtoolbox.cpp | 4 ++-- 13 files changed, 29 insertions(+), 24 deletions(-) diff --git a/src/printsupport/dialogs/qprintpreviewdialog.cpp b/src/printsupport/dialogs/qprintpreviewdialog.cpp index 418bc47a59..e6b665f82c 100644 --- a/src/printsupport/dialogs/qprintpreviewdialog.cpp +++ b/src/printsupport/dialogs/qprintpreviewdialog.cpp @@ -331,7 +331,7 @@ void QPrintPreviewDialogPrivate::init(QPrinter *_printer) QVBoxLayout *topLayout = new QVBoxLayout; topLayout->addWidget(mw); - topLayout->setMargin(0); + topLayout->setContentsMargins(0, 0, 0, 0); q->setLayout(topLayout); QString caption = QCoreApplication::translate("QPrintPreviewDialog", "Print Preview"); diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp index 722aa3e278..c0bacd553d 100644 --- a/src/widgets/dialogs/qcolordialog.cpp +++ b/src/widgets/dialogs/qcolordialog.cpp @@ -1179,7 +1179,8 @@ QColorShower::QColorShower(QColorDialog *parent) curQColor = Qt::white; gl = new QGridLayout(this); - gl->setMargin(gl->spacing()); + const int s = gl->spacing(); + gl->setContentsMargins(s, s, s, s); lab = new QColorShowLabel(this); #ifdef QT_SMALL_COLORDIALOG @@ -1807,7 +1808,7 @@ void QColorDialogPrivate::initWidgets() rightLay->addStretch(); cs = new QColorShower(q); - pickLay->setMargin(cs->gl->margin()); + pickLay->setContentsMargins(cs->gl->contentsMargins()); QObject::connect(cs, SIGNAL(newCol(QRgb)), q, SLOT(_q_newColorTypedIn(QRgb))); QObject::connect(cs, SIGNAL(currentColorChanged(QColor)), q, SIGNAL(currentColorChanged(QColor))); @@ -1816,7 +1817,7 @@ void QColorDialogPrivate::initWidgets() #else rightLay->addWidget(cs); if (leftLay) - leftLay->addSpacing(cs->gl->margin()); + leftLay->addSpacing(cs->gl->contentsMargins().right()); #endif buttons = new QDialogButtonBox(q); diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index c9818624fb..f143e3b527 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -113,7 +113,7 @@ public: , copyAvailable(false) { QVBoxLayout *layout = new QVBoxLayout; - layout->setMargin(0); + layout->setContentsMargins(QMargins()); QFrame *line = new QFrame(this); line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); diff --git a/src/widgets/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp index 5eae70baf2..88b187cd7f 100644 --- a/src/widgets/dialogs/qwizard.cpp +++ b/src/widgets/dialogs/qwizard.cpp @@ -331,7 +331,7 @@ QWizardHeader::QWizardHeader(QWidget *parent) titleLabel->setFont(font); layout = new QGridLayout(this); - layout->setMargin(0); + layout->setContentsMargins(QMargins()); layout->setSpacing(0); layout->setRowMinimumHeight(3, 1); @@ -1032,13 +1032,13 @@ void QWizardPrivate::recreateLayout(const QWizardLayoutInfo &info) int pageColumn = qMin(1, numColumns - 1); if (mac) { - mainLayout->setMargin(0); + mainLayout->setContentsMargins(QMargins()); mainLayout->setSpacing(0); buttonLayout->setContentsMargins(MacLayoutLeftMargin, MacButtonTopMargin, MacLayoutRightMargin, MacLayoutBottomMargin); - pageVBoxLayout->setMargin(7); + pageVBoxLayout->setContentsMargins(7, 7, 7, 7); } else { if (modern) { - mainLayout->setMargin(0); + mainLayout->setContentsMargins(QMargins()); mainLayout->setSpacing(0); pageVBoxLayout->setContentsMargins(deltaMarginLeft, deltaMarginTop, deltaMarginRight, deltaMarginBottom); diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 01c400c5da..56bc329827 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -3140,13 +3140,17 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt, ///we need to access the widget here because the style option doesn't //have all the information we need (ie. the layout's margin) const QToolBar *tb = qobject_cast<const QToolBar*>(widget); - const int margin = tb && tb->layout() ? tb->layout()->margin() : 2; + const QMargins margins = tb && tb->layout() ? tb->layout()->contentsMargins() : QMargins(2, 2, 2, 2); const int handleExtent = proxy()->pixelMetric(QStyle::PM_ToolBarHandleExtent, opt, tb); if (tbopt->state & QStyle::State_Horizontal) { - r = QRect(margin, margin, handleExtent, tbopt->rect.height() - 2*margin); + r = QRect(margins.left(), margins.top(), + handleExtent, + tbopt->rect.height() - (margins.top() + margins.bottom())); r = QStyle::visualRect(tbopt->direction, tbopt->rect, r); } else { - r = QRect(margin, margin, tbopt->rect.width() - 2*margin, handleExtent); + r = QRect(margins.left(), margins.top(), + tbopt->rect.width() - (margins.left() + margins.right()), + handleExtent); } } } diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp index d15f5e5955..a38a50d3df 100644 --- a/src/widgets/util/qsystemtrayicon.cpp +++ b/src/widgets/util/qsystemtrayicon.cpp @@ -574,7 +574,7 @@ QBalloonTip::QBalloonTip(const QIcon &icon, const QString &title, layout->addWidget(msgLabel, 1, 0, 1, 3); #endif layout->setSizeConstraint(QLayout::SetFixedSize); - layout->setMargin(3); + layout->setContentsMargins(3, 3, 3, 3); setLayout(layout); QPalette pal = palette(); diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp index b378884275..5ea8330db2 100644 --- a/src/widgets/widgets/qabstractscrollarea.cpp +++ b/src/widgets/widgets/qabstractscrollarea.cpp @@ -185,7 +185,7 @@ QAbstractScrollAreaScrollBarContainer::QAbstractScrollAreaScrollBarContainer(Qt: orientation(orientation) { setLayout(layout); - layout->setMargin(0); + layout->setContentsMargins(QMargins()); layout->setSpacing(0); layout->addWidget(scrollBar); layout->setSizeConstraint(QLayout::SetMaximumSize); diff --git a/src/widgets/widgets/qcalendarwidget.cpp b/src/widgets/widgets/qcalendarwidget.cpp index 5649243d1d..7637877926 100644 --- a/src/widgets/widgets/qcalendarwidget.cpp +++ b/src/widgets/widgets/qcalendarwidget.cpp @@ -1778,7 +1778,7 @@ void QCalendarWidgetPrivate::createNavigationBar(QWidget *widget) spaceHolder = new QSpacerItem(0,0); QHBoxLayout *headerLayout = new QHBoxLayout; - headerLayout->setMargin(0); + headerLayout->setContentsMargins(QMargins()); headerLayout->setSpacing(0); headerLayout->addWidget(prevMonth); headerLayout->insertStretch(headerLayout->count()); @@ -2101,7 +2101,7 @@ QCalendarWidget::QCalendarWidget(QWidget *parent) setBackgroundRole(QPalette::Window); QVBoxLayout *layoutV = new QVBoxLayout(this); - layoutV->setMargin(0); + layoutV->setContentsMargins(QMargins()); d->m_model = new QCalendarModel(this); QTextCharFormat fmt; fmt.setForeground(QBrush(Qt::red)); @@ -2148,7 +2148,7 @@ QCalendarWidget::QCalendarWidget(QWidget *parent) connect(d->yearEdit, SIGNAL(editingFinished()), this, SLOT(_q_yearEditingFinished())); - layoutV->setMargin(0); + layoutV->setContentsMargins(QMargins()); layoutV->setSpacing(0); layoutV->addWidget(d->navBarBackground); layoutV->addWidget(d->m_view); diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index f3e6bd80f4..1ad43fffb4 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -472,7 +472,7 @@ QComboBoxPrivateContainer::QComboBoxPrivateContainer(QAbstractItemView *itemView // we need a vertical layout QBoxLayout *layout = new QBoxLayout(QBoxLayout::TopToBottom, this); layout->setSpacing(0); - layout->setMargin(0); + layout->setContentsMargins(QMargins()); // set item view setItemView(itemView); diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp index c66400f423..4dda01f0c7 100644 --- a/src/widgets/widgets/qdatetimeedit.cpp +++ b/src/widgets/widgets/qdatetimeedit.cpp @@ -2598,7 +2598,7 @@ void QCalendarPopup::setCalendarWidget(QCalendarWidget *cw) QVBoxLayout *widgetLayout = qobject_cast<QVBoxLayout*>(layout()); if (!widgetLayout) { widgetLayout = new QVBoxLayout(this); - widgetLayout->setMargin(0); + widgetLayout->setContentsMargins(QMargins()); widgetLayout->setSpacing(0); } delete calendar.data(); diff --git a/src/widgets/widgets/qmdisubwindow.cpp b/src/widgets/widgets/qmdisubwindow.cpp index c7e0603309..e25bc6de7a 100644 --- a/src/widgets/widgets/qmdisubwindow.cpp +++ b/src/widgets/widgets/qmdisubwindow.cpp @@ -2268,7 +2268,7 @@ QMdiSubWindow::QMdiSubWindow(QWidget *parent, Qt::WindowFlags flags) setMouseTracking(true); setLayout(new QVBoxLayout); setFocusPolicy(Qt::StrongFocus); - layout()->setMargin(0); + layout()->setContentsMargins(QMargins()); d->updateGeometryConstraints(); setAttribute(Qt::WA_Resized, false); d->titleBarPalette = d->desktopPalette(); diff --git a/src/widgets/widgets/qstatusbar.cpp b/src/widgets/widgets/qstatusbar.cpp index ae67cbd890..e9044e6cad 100644 --- a/src/widgets/widgets/qstatusbar.cpp +++ b/src/widgets/widgets/qstatusbar.cpp @@ -482,14 +482,14 @@ void QStatusBar::reformat() #if QT_CONFIG(sizegrip) if (d->resizer) { d->box = new QHBoxLayout(this); - d->box->setMargin(0); + d->box->setContentsMargins(QMargins()); vbox = new QVBoxLayout; d->box->addLayout(vbox); } else #endif { vbox = d->box = new QVBoxLayout(this); - d->box->setMargin(0); + d->box->setContentsMargins(QMargins()); } vbox->addSpacing(3); QBoxLayout* l = new QHBoxLayout; diff --git a/src/widgets/widgets/qtoolbox.cpp b/src/widgets/widgets/qtoolbox.cpp index eee112f02f..1c83485bff 100644 --- a/src/widgets/widgets/qtoolbox.cpp +++ b/src/widgets/widgets/qtoolbox.cpp @@ -294,7 +294,7 @@ QToolBox::QToolBox(QWidget *parent, Qt::WindowFlags f) { Q_D(QToolBox); d->layout = new QVBoxLayout(this); - d->layout->setMargin(0); + d->layout->setContentsMargins(QMargins()); setBackgroundRole(QPalette::Button); } @@ -437,7 +437,7 @@ void QToolBoxPrivate::relayout() Q_Q(QToolBox); delete layout; layout = new QVBoxLayout(q); - layout->setMargin(0); + layout->setContentsMargins(QMargins()); for (QToolBoxPrivate::PageList::ConstIterator i = pageList.constBegin(); i != pageList.constEnd(); ++i) { layout->addWidget((*i).button); layout->addWidget((*i).sv); From d493f676a38f000dd9c22dee6eea2b5ae4291e0a Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Sat, 9 Feb 2019 14:52:26 +0100 Subject: [PATCH 1150/1650] QToolBarLayout: replace deprecated calls to QLayout::margin() Replace QLayout::margin() with QLayout::contentsMargins() and add two new helper functions to get the correct margins. Change-Id: I3ad24747e7c6323eaf4386c00c47029009d64f8c Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> --- src/widgets/widgets/qmenu_p.h | 6 ++++ src/widgets/widgets/qtoolbarlayout.cpp | 45 ++++++++++++++------------ 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h index 3e1aa2f738..12521e7a36 100644 --- a/src/widgets/widgets/qmenu_p.h +++ b/src/widgets/widgets/qmenu_p.h @@ -95,6 +95,12 @@ static inline int &rperp(Qt::Orientation o, QPoint &pos) static inline int &rperp(Qt::Orientation o, QSize &size) { return o == Qt::Vertical ? size.rwidth() : size.rheight(); } +static inline int pick(Qt::Orientation o, const QMargins &m) +{ return o == Qt::Horizontal ? (m.left() + m.right()) : (m.top() + m.bottom()); } + +static inline int perp(Qt::Orientation o, const QMargins &m) +{ return o == Qt::Vertical ? (m.left() + m.right()) : (m.top() + m.bottom()); } + class QTornOffMenu; class QEventLoop; diff --git a/src/widgets/widgets/qtoolbarlayout.cpp b/src/widgets/widgets/qtoolbarlayout.cpp index f2d329d59d..d50e19a5ed 100644 --- a/src/widgets/widgets/qtoolbarlayout.cpp +++ b/src/widgets/widgets/qtoolbarlayout.cpp @@ -119,8 +119,9 @@ void QToolBarLayout::updateMarginAndSpacing() QStyle *style = tb->style(); QStyleOptionToolBar opt; tb->initStyleOption(&opt); - setMargin(style->pixelMetric(QStyle::PM_ToolBarItemMargin, &opt, tb) - + style->pixelMetric(QStyle::PM_ToolBarFrameWidth, &opt, tb)); + const int margin = style->pixelMetric(QStyle::PM_ToolBarItemMargin, &opt, tb) + + style->pixelMetric(QStyle::PM_ToolBarFrameWidth, &opt, tb); + setContentsMargins(margin, margin, margin, margin); setSpacing(style->pixelMetric(QStyle::PM_ToolBarItemSpacing, &opt, tb)); } @@ -268,7 +269,7 @@ void QToolBarLayout::updateGeomArray() const tb->initStyleOption(&opt); const int handleExtent = movable() ? style->pixelMetric(QStyle::PM_ToolBarHandleExtent, &opt, tb) : 0; - const int margin = this->margin(); + const QMargins margins = contentsMargins(); const int spacing = this->spacing(); const int extensionExtent = style->pixelMetric(QStyle::PM_ToolBarExtensionExtent, &opt, tb); Qt::Orientation o = tb->orientation(); @@ -330,12 +331,12 @@ void QToolBarLayout::updateGeomArray() const that->empty = count == 0; rpick(o, that->minSize) += handleExtent; - that->minSize += QSize(2*margin, 2*margin); + that->minSize += QSize(pick(Qt::Horizontal, margins), pick(Qt::Vertical, margins)); if (items.count() > 1) rpick(o, that->minSize) += spacing + extensionExtent; rpick(o, that->hint) += handleExtent; - that->hint += QSize(2*margin, 2*margin); + that->hint += QSize(pick(Qt::Horizontal, margins), pick(Qt::Vertical, margins)); that->dirty = false; } @@ -384,7 +385,7 @@ void QToolBarLayout::setGeometry(const QRect &rect) QStyle *style = tb->style(); QStyleOptionToolBar opt; tb->initStyleOption(&opt); - const int margin = this->margin(); + const QMargins margins = contentsMargins(); const int extensionExtent = style->pixelMetric(QStyle::PM_ToolBarExtensionExtent, &opt, tb); Qt::Orientation o = tb->orientation(); @@ -403,14 +404,18 @@ void QToolBarLayout::setGeometry(const QRect &rect) QSize hint = sizeHint(); QPoint pos; - rpick(o, pos) = pick(o, rect.bottomRight()) - margin - extensionExtent + 2; + rpick(o, pos) = pick(o, rect.bottomRight()) - + pick(o, QSize(margins.bottom(), margins.right())) - extensionExtent + 2; if (area == Qt::LeftToolBarArea || area == Qt::TopToolBarArea) - rperp(o, pos) = perp(o, rect.topLeft()) + margin; + rperp(o, pos) = perp(o, rect.topLeft()) + + perp(o, QSize(margins.top(), margins.left())); else - rperp(o, pos) = perp(o, rect.bottomRight()) - margin - (perp(o, hint) - 2*margin) + 1; + rperp(o, pos) = perp(o, rect.bottomRight()) - + perp(o, QSize(margins.bottom(), margins.right())) - + (perp(o, hint) - perp(o, margins)) + 1; QSize size; rpick(o, size) = extensionExtent; - rperp(o, size) = perp(o, hint) - 2*margin; + rperp(o, size) = perp(o, hint) - perp(o, margins); QRect r(pos, size); if (o == Qt::Horizontal) @@ -443,13 +448,13 @@ bool QToolBarLayout::layoutActions(const QSize &size) tb->initStyleOption(&opt); const int handleExtent = movable() ? style->pixelMetric(QStyle::PM_ToolBarHandleExtent, &opt, tb) : 0; - const int margin = this->margin(); + const QMargins margins = contentsMargins(); const int spacing = this->spacing(); const int extensionExtent = style->pixelMetric(QStyle::PM_ToolBarExtensionExtent, &opt, tb); Qt::Orientation o = tb->orientation(); bool extensionMenuContainsOnlyWidgetActions = true; - int space = pick(o, rect.size()) - 2*margin - handleExtent; + int space = pick(o, rect.size()) - pick(o, margins) - handleExtent; if (space <= 0) return false; // nothing to do. @@ -458,7 +463,7 @@ bool QToolBarLayout::layoutActions(const QSize &size) bool ranOutOfSpace = false; int rows = 0; - int rowPos = perp(o, rect.topLeft()) + margin; + int rowPos = perp(o, rect.topLeft()) + perp(o, QSize(margins.top(), margins.left())); int i = 0; while (i < items.count()) { QVector<QLayoutStruct> a = geomArray; @@ -521,14 +526,14 @@ bool QToolBarLayout::layoutActions(const QSize &size) } QPoint pos; - rpick(o, pos) = margin + handleExtent + a[j].pos; + rpick(o, pos) = pick(o, QSize(margins.top(), margins.left())) + handleExtent + a[j].pos; rperp(o, pos) = rowPos; QSize size; rpick(o, size) = a[j].size; if (expanded) rperp(o, size) = rowHeight; else - rperp(o, size) = perp(o, rect.size()) - 2*margin; + rperp(o, size) = perp(o, rect.size()) - perp(o, QSize(margins.top(), margins.left())); QRect r(pos, size); if (o == Qt::Horizontal) @@ -589,7 +594,7 @@ QSize QToolBarLayout::expandedSize(const QSize &size) const tb->initStyleOption(&opt); const int handleExtent = movable() ? style->pixelMetric(QStyle::PM_ToolBarHandleExtent, &opt, tb) : 0; - const int margin = this->margin(); + const QMargins margins = contentsMargins(); const int spacing = this->spacing(); const int extensionExtent = style->pixelMetric(QStyle::PM_ToolBarExtensionExtent, &opt, tb); @@ -609,9 +614,9 @@ QSize QToolBarLayout::expandedSize(const QSize &size) const if (rows == 1) ++rows; // we want to expand to at least two rows int space = total_w/rows + spacing + extensionExtent; - space = qMax(space, min_w - 2*margin - handleExtent); + space = qMax(space, min_w - pick(o, margins) - handleExtent); if (win != 0) - space = qMin(space, pick(o, win->size()) - 2*margin - handleExtent); + space = qMin(space, pick(o, win->size()) - pick(o, margins) - handleExtent); int w = 0; int h = 0; @@ -644,11 +649,11 @@ QSize QToolBarLayout::expandedSize(const QSize &size) const h += rowHeight + spacing; } - w += 2*margin + handleExtent + spacing + extensionExtent; + w += pick(Qt::Horizontal, margins) + handleExtent + spacing + extensionExtent; w = qMax(w, min_w); if (win != 0) w = qMin(w, pick(o, win->size())); - h += 2*margin - spacing; //there is no spacing before the first row + h += pick(Qt::Vertical, margins) - spacing; //there is no spacing before the first row QSize result; rpick(o, result) = w; From 8cba096c2aa181b93887fa6f6086dee689dbf5ca Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Sat, 9 Feb 2019 18:43:05 +0100 Subject: [PATCH 1151/1650] QtBase: compile examples with QT_DISABLE_DEPRECATED_BEFORE=0x050d00 Replace deprecated functions to be able to compile examples with QT_DISABLE_DEPRECATED_BEFORE=0x050d00 Change-Id: If6b8de31f526320d6a0e2a20bb5f8e26c77f2353 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> --- examples/network/securesocketclient/sslclient.cpp | 3 ++- examples/network/torrent/mainwindow.cpp | 2 +- examples/widgets/dialogs/extension/finddialog.cpp | 2 +- .../widgets/layouts/borderlayout/borderlayout.cpp | 4 ++-- .../widgets/layouts/borderlayout/borderlayout.h | 2 +- examples/widgets/layouts/flowlayout/flowlayout.cpp | 3 ++- examples/widgets/mainwindows/menus/mainwindow.cpp | 2 +- examples/widgets/painting/deform/pathdeform.cpp | 4 ++-- .../widgets/painting/fontsampler/mainwindow.cpp | 2 +- examples/widgets/painting/gradients/gradients.cpp | 2 +- .../widgets/painting/pathstroke/pathstroke.cpp | 14 +++++++------- examples/widgets/painting/shared/arthurstyle.cpp | 4 ++-- .../widgets/statemachine/trafficlight/main.cpp | 6 +++--- .../regularexpression/regularexpressiondialog.cpp | 4 ++-- examples/widgets/widgets/styles/widgetgallery.cpp | 4 ++-- 15 files changed, 30 insertions(+), 28 deletions(-) diff --git a/examples/network/securesocketclient/sslclient.cpp b/examples/network/securesocketclient/sslclient.cpp index afeec033ff..79ed7746d6 100644 --- a/examples/network/securesocketclient/sslclient.cpp +++ b/examples/network/securesocketclient/sslclient.cpp @@ -206,7 +206,8 @@ void SslClient::setupUi() padLock->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored); QHBoxLayout *layout = new QHBoxLayout(form->hostNameEdit); - layout->setMargin(form->hostNameEdit->style()->pixelMetric(QStyle::PM_DefaultFrameWidth)); + const int margin = form->hostNameEdit->style()->pixelMetric(QStyle::PM_DefaultFrameWidth); + layout->setContentsMargins(margin, margin, margin, margin); layout->setSpacing(0); layout->addStretch(); layout->addWidget(padLock); diff --git a/examples/network/torrent/mainwindow.cpp b/examples/network/torrent/mainwindow.cpp index 39b166101d..704012ef6d 100644 --- a/examples/network/torrent/mainwindow.cpp +++ b/examples/network/torrent/mainwindow.cpp @@ -630,7 +630,7 @@ void MainWindow::about() QPushButton *quitButton = new QPushButton("OK"); QHBoxLayout *topLayout = new QHBoxLayout; - topLayout->setMargin(10); + topLayout->setContentsMargins(10, 10, 10, 10); topLayout->setSpacing(10); topLayout->addWidget(icon); topLayout->addWidget(text); diff --git a/examples/widgets/dialogs/extension/finddialog.cpp b/examples/widgets/dialogs/extension/finddialog.cpp index 1321155f00..10a4ae1ac0 100644 --- a/examples/widgets/dialogs/extension/finddialog.cpp +++ b/examples/widgets/dialogs/extension/finddialog.cpp @@ -91,7 +91,7 @@ FindDialog::FindDialog(QWidget *parent) connect(moreButton, &QAbstractButton::toggled, extension, &QWidget::setVisible); QVBoxLayout *extensionLayout = new QVBoxLayout; - extensionLayout->setMargin(0); + extensionLayout->setContentsMargins(QMargins()); extensionLayout->addWidget(wholeWordsCheckBox); extensionLayout->addWidget(backwardCheckBox); extensionLayout->addWidget(searchSelectionCheckBox); diff --git a/examples/widgets/layouts/borderlayout/borderlayout.cpp b/examples/widgets/layouts/borderlayout/borderlayout.cpp index c929d3b2a4..b8ddd3af83 100644 --- a/examples/widgets/layouts/borderlayout/borderlayout.cpp +++ b/examples/widgets/layouts/borderlayout/borderlayout.cpp @@ -50,10 +50,10 @@ #include "borderlayout.h" -BorderLayout::BorderLayout(QWidget *parent, int margin, int spacing) +BorderLayout::BorderLayout(QWidget *parent, const QMargins &margins, int spacing) : QLayout(parent) { - setMargin(margin); + setContentsMargins(margins); setSpacing(spacing); } diff --git a/examples/widgets/layouts/borderlayout/borderlayout.h b/examples/widgets/layouts/borderlayout/borderlayout.h index 4c0c01f90b..58d1aa394d 100644 --- a/examples/widgets/layouts/borderlayout/borderlayout.h +++ b/examples/widgets/layouts/borderlayout/borderlayout.h @@ -59,7 +59,7 @@ class BorderLayout : public QLayout public: enum Position { West, North, South, East, Center }; - explicit BorderLayout(QWidget *parent, int margin = 0, int spacing = -1); + explicit BorderLayout(QWidget *parent, const QMargins &margins = QMargins(), int spacing = -1); BorderLayout(int spacing = -1); ~BorderLayout(); diff --git a/examples/widgets/layouts/flowlayout/flowlayout.cpp b/examples/widgets/layouts/flowlayout/flowlayout.cpp index 53613b8b20..5c59ae025c 100644 --- a/examples/widgets/layouts/flowlayout/flowlayout.cpp +++ b/examples/widgets/layouts/flowlayout/flowlayout.cpp @@ -158,7 +158,8 @@ QSize FlowLayout::minimumSize() const for (const QLayoutItem *item : qAsConst(itemList)) size = size.expandedTo(item->minimumSize()); - size += QSize(2*margin(), 2*margin()); + const QMargins margins = contentsMargins(); + size += QSize(margins.left() + margins.right(), margins.top() + margins.bottom()); return size; } //! [8] diff --git a/examples/widgets/mainwindows/menus/mainwindow.cpp b/examples/widgets/mainwindows/menus/mainwindow.cpp index 600b04fdb2..c6aba8be83 100644 --- a/examples/widgets/mainwindows/menus/mainwindow.cpp +++ b/examples/widgets/mainwindows/menus/mainwindow.cpp @@ -72,7 +72,7 @@ MainWindow::MainWindow() bottomFiller->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); QVBoxLayout *layout = new QVBoxLayout; - layout->setMargin(5); + layout->setContentsMargins(5, 5, 5, 5); layout->addWidget(topFiller); layout->addWidget(infoLabel); layout->addWidget(bottomFiller); diff --git a/examples/widgets/painting/deform/pathdeform.cpp b/examples/widgets/painting/deform/pathdeform.cpp index 0eda76a831..64e81f8cab 100644 --- a/examples/widgets/painting/deform/pathdeform.cpp +++ b/examples/widgets/painting/deform/pathdeform.cpp @@ -150,7 +150,7 @@ void PathDeformControls::layoutForDesktop() QVBoxLayout * mainLayout = new QVBoxLayout(this); mainLayout->addWidget(mainGroup); - mainLayout->setMargin(0); + mainLayout->setContentsMargins(QMargins()); connect(radiusSlider, &QAbstractSlider::valueChanged, m_renderer, &PathDeformRenderer::setRadius); connect(deformSlider, &QAbstractSlider::valueChanged, m_renderer, &PathDeformRenderer::setIntensity); @@ -211,7 +211,7 @@ void PathDeformControls::layoutForSmallScreen() QGridLayout *mainGroupLayout = new QGridLayout(mainGroup); - mainGroupLayout->setMargin(0); + mainGroupLayout->setContentsMargins(QMargins()); mainGroupLayout->addWidget(radiusLabel, 0, 0, Qt::AlignRight); mainGroupLayout->addWidget(radiusSlider, 0, 1); mainGroupLayout->addWidget(deformLabel, 1, 0, Qt::AlignRight); diff --git a/examples/widgets/painting/fontsampler/mainwindow.cpp b/examples/widgets/painting/fontsampler/mainwindow.cpp index a464eee3ff..b3304b4b6d 100644 --- a/examples/widgets/painting/fontsampler/mainwindow.cpp +++ b/examples/widgets/painting/fontsampler/mainwindow.cpp @@ -78,7 +78,7 @@ MainWindow::MainWindow(QWidget *parent) connect(fontTree, &QTreeWidget::itemChanged, this, &MainWindow::updateStyles); - fontTree->setItemSelected(fontTree->topLevelItem(0), true); + fontTree->topLevelItem(0)->setSelected(true); showFont(fontTree->topLevelItem(0)); } diff --git a/examples/widgets/painting/gradients/gradients.cpp b/examples/widgets/painting/gradients/gradients.cpp index fd6eaeb0d9..7abaef771b 100644 --- a/examples/widgets/painting/gradients/gradients.cpp +++ b/examples/widgets/painting/gradients/gradients.cpp @@ -180,7 +180,7 @@ GradientEditor::GradientEditor(QWidget *parent) { QVBoxLayout *vbox = new QVBoxLayout(this); vbox->setSpacing(1); - vbox->setMargin(1); + vbox->setContentsMargins(1, 1, 1, 1); m_red_shade = new ShadeWidget(ShadeWidget::RedShade, this); m_green_shade = new ShadeWidget(ShadeWidget::GreenShade, this); diff --git a/examples/widgets/painting/pathstroke/pathstroke.cpp b/examples/widgets/painting/pathstroke/pathstroke.cpp index cad0b8732c..03e55bb2a2 100644 --- a/examples/widgets/painting/pathstroke/pathstroke.cpp +++ b/examples/widgets/painting/pathstroke/pathstroke.cpp @@ -227,11 +227,11 @@ void PathStrokeControls::layoutForDesktop() penWidthLayout->addWidget(penWidth); QVBoxLayout * mainLayout = new QVBoxLayout(this); - mainLayout->setMargin(0); + mainLayout->setContentsMargins(QMargins()); mainLayout->addWidget(mainGroup); QVBoxLayout *mainGroupLayout = new QVBoxLayout(mainGroup); - mainGroupLayout->setMargin(3); + mainGroupLayout->setContentsMargins(3, 3, 3, 3); mainGroupLayout->addWidget(m_capGroup); mainGroupLayout->addWidget(m_joinGroup); mainGroupLayout->addWidget(m_styleGroup); @@ -270,10 +270,10 @@ void PathStrokeControls::layoutForSmallScreens() { createCommonControls(this); - m_capGroup->layout()->setMargin(0); - m_joinGroup->layout()->setMargin(0); - m_styleGroup->layout()->setMargin(0); - m_pathModeGroup->layout()->setMargin(0); + m_capGroup->layout()->setContentsMargins(QMargins()); + m_joinGroup->layout()->setContentsMargins(QMargins()); + m_styleGroup->layout()->setContentsMargins(QMargins()); + m_pathModeGroup->layout()->setContentsMargins(QMargins()); QPushButton* okBtn = new QPushButton(tr("OK"), this); okBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); @@ -313,7 +313,7 @@ void PathStrokeControls::layoutForSmallScreens() rightLayout->addWidget(m_pathModeGroup); QGridLayout *mainLayout = new QGridLayout(this); - mainLayout->setMargin(0); + mainLayout->setContentsMargins(QMargins()); // Add spacers around the form items so we don't look stupid at higher resolutions mainLayout->addItem(new QSpacerItem(0,0), 0, 0, 1, 4); diff --git a/examples/widgets/painting/shared/arthurstyle.cpp b/examples/widgets/painting/shared/arthurstyle.cpp index 3df9d9a6dc..3fc461bbd2 100644 --- a/examples/widgets/painting/shared/arthurstyle.cpp +++ b/examples/widgets/painting/shared/arthurstyle.cpp @@ -443,9 +443,9 @@ void ArthurStyle::polish(QWidget *widget) if (widget->layout() && qobject_cast<QGroupBox *>(widget)) { if (widget->findChildren<QGroupBox *>().size() == 0) { widget->layout()->setSpacing(0); - widget->layout()->setMargin(12); + widget->layout()->setContentsMargins(12, 12, 12, 12); } else { - widget->layout()->setMargin(13); + widget->layout()->setContentsMargins(13, 13, 13, 13); } } diff --git a/examples/widgets/statemachine/trafficlight/main.cpp b/examples/widgets/statemachine/trafficlight/main.cpp index b348d4f65d..1a7050c28d 100644 --- a/examples/widgets/statemachine/trafficlight/main.cpp +++ b/examples/widgets/statemachine/trafficlight/main.cpp @@ -146,13 +146,13 @@ QState *createLightState(LightWidget *light, int duration, QState *parent = 0) class TrafficLight : public QWidget { public: - TrafficLight(QWidget *parent = 0) + TrafficLight(QWidget *parent = nullptr) : QWidget(parent) { QVBoxLayout *vbox = new QVBoxLayout(this); - TrafficLightWidget *widget = new TrafficLightWidget(); + TrafficLightWidget *widget = new TrafficLightWidget; vbox->addWidget(widget); - vbox->setMargin(0); + vbox->setContentsMargins(QMargins()); QStateMachine *machine = new QStateMachine(this); QState *redGoingYellow = createLightState(widget->redLight(), 3000); diff --git a/examples/widgets/tools/regularexpression/regularexpressiondialog.cpp b/examples/widgets/tools/regularexpression/regularexpressiondialog.cpp index 8fbf143cbd..ea3cb00a02 100644 --- a/examples/widgets/tools/regularexpression/regularexpressiondialog.cpp +++ b/examples/widgets/tools/regularexpression/regularexpressiondialog.cpp @@ -376,7 +376,7 @@ QWidget *RegularExpressionDialog::setupLeftUi() QFormLayout *layout = new QFormLayout(container); layout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); - layout->setMargin(0); + layout->setContentsMargins(QMargins()); QLabel *regexpAndSubjectLabel = new QLabel(tr("<h3>Regular expression and text input</h3>")); layout->addRow(regexpAndSubjectLabel); @@ -448,7 +448,7 @@ QWidget *RegularExpressionDialog::setupRightUi() QFormLayout *layout = new QFormLayout(container); layout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); - layout->setMargin(0); + layout->setContentsMargins(QMargins()); QLabel *matchInfoLabel = new QLabel(tr("<h3>Match information</h3>")); layout->addRow(matchInfoLabel); diff --git a/examples/widgets/widgets/styles/widgetgallery.cpp b/examples/widgets/widgets/styles/widgetgallery.cpp index 7f4b7f39d4..f0a0336a94 100644 --- a/examples/widgets/widgets/styles/widgetgallery.cpp +++ b/examples/widgets/widgets/styles/widgetgallery.cpp @@ -212,7 +212,7 @@ void WidgetGallery::createBottomLeftTabWidget() tableWidget = new QTableWidget(10, 10); QHBoxLayout *tab1hbox = new QHBoxLayout; - tab1hbox->setMargin(5); + tab1hbox->setContentsMargins(5,5, 5, 5); tab1hbox->addWidget(tableWidget); tab1->setLayout(tab1hbox); @@ -227,7 +227,7 @@ void WidgetGallery::createBottomLeftTabWidget() "How I wonder what you are!\n")); QHBoxLayout *tab2hbox = new QHBoxLayout; - tab2hbox->setMargin(5); + tab2hbox->setContentsMargins(5, 5, 5, 5); tab2hbox->addWidget(textEdit); tab2->setLayout(tab2hbox); From d6c474b49b349dc6c30ea059040285221e712217 Mon Sep 17 00:00:00 2001 From: Kai Koehne <kai.koehne@qt.io> Date: Fri, 14 Dec 2018 12:36:22 +0100 Subject: [PATCH 1152/1650] QTextDocument: Do respect white-space:nowrap Prevent automatic insertion of line-breaks in blocks formatted with 'white-space:nowrap'. This follows the example of white-space:pre. Fixes: QTBUG-54787 Change-Id: If26f6a54106a02fe0e388947f6368ae4e86acf63 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> Reviewed-by: Simon Hausmann <simon.hausmann@qt.io> --- src/gui/text/qtextdocumentfragment.cpp | 3 ++- .../tst_qtextdocumentfragment.cpp | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/gui/text/qtextdocumentfragment.cpp b/src/gui/text/qtextdocumentfragment.cpp index e7eaa54a45..6b3604afb5 100644 --- a/src/gui/text/qtextdocumentfragment.cpp +++ b/src/gui/text/qtextdocumentfragment.cpp @@ -1139,7 +1139,8 @@ QTextHtmlImporter::ProcessNodeResult QTextHtmlImporter::processBlockNode() // #################### // block.setFloatPosition(node->cssFloat); - if (wsm == QTextHtmlParserNode::WhiteSpacePre) { + if (wsm == QTextHtmlParserNode::WhiteSpacePre + || wsm == QTextHtmlParserNode::WhiteSpaceNoWrap) { block.setNonBreakableLines(true); modifiedBlockFormat = true; } diff --git a/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp b/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp index 3e354b7523..d652bb066d 100644 --- a/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp +++ b/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp @@ -195,6 +195,8 @@ private slots: void css_linkPseudo(); void css_pageBreaks(); void css_cellPaddings(); + void css_whiteSpace_data(); + void css_whiteSpace(); void universalSelectors_data(); void universalSelectors(); void screenMedia(); @@ -1770,6 +1772,26 @@ void tst_QTextDocumentFragment::css_cellPaddings() QCOMPARE(cell.format().toTableCellFormat().bottomPadding(), qreal(15)); } +void tst_QTextDocumentFragment::css_whiteSpace_data() +{ + QTest::addColumn<QString>("htmlText"); + QTest::addColumn<bool>("nowrap"); + + QTest::newRow("default") << QString("<p>Normal Text</p>") << false; + QTest::newRow("white-space:nowrap") << QString("<p style=white-space:nowrap>Normal Text</p>") << true; + QTest::newRow("white-space:pre") << QString("<p style=white-space:pre>Normal Text</p>") << true; +} + +void tst_QTextDocumentFragment::css_whiteSpace() +{ + QFETCH(QString, htmlText); + QFETCH(bool, nowrap); + + doc->setHtml(htmlText); + QCOMPARE(doc->blockCount(), 1); + QCOMPARE(doc->begin().blockFormat().nonBreakableLines(), nowrap); +} + void tst_QTextDocumentFragment::html_blockLevelDiv() { const char html[] = "<div align=right><b>Hello World"; From 7d2d1eb9e051ad01dc5c5c3053c58364885bdc07 Mon Sep 17 00:00:00 2001 From: Volker Krause <vkrause@kde.org> Date: Sat, 26 Jan 2019 18:30:56 +0100 Subject: [PATCH 1153/1650] Add file engine for Android content URLs The "file dialog" on Android returns such URLs, which so far required special-casing this in application code. With this change QFile can consume those URLs directly. Change-Id: I489c0db112cf1dc7497e7a90f0e9a79ea8fa5237 Reviewed-by: Nicolas Fella <nicolas.fella@kdab.com> Reviewed-by: BogDan Vatra <bogdan@kdab.com> Reviewed-by: Aleix Pol Gonzalez <aleixpol@kde.org> --- .../org/qtproject/qt5/android/QtNative.java | 13 +++ src/plugins/platforms/android/android.pro | 2 + .../android/androidcontentfileengine.cpp | 92 +++++++++++++++++++ .../android/androidcontentfileengine.h | 60 ++++++++++++ .../platforms/android/androidjnimain.cpp | 5 + 5 files changed, 172 insertions(+) create mode 100644 src/plugins/platforms/android/androidcontentfileengine.cpp create mode 100644 src/plugins/platforms/android/androidcontentfileengine.h diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java index 5562c010aa..c5e8a5f794 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java @@ -41,6 +41,7 @@ package org.qtproject.qt5.android; import java.io.File; +import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.concurrent.Semaphore; @@ -59,6 +60,7 @@ import android.os.Looper; import android.content.ClipboardManager; import android.content.ClipboardManager.OnPrimaryClipChangedListener; import android.content.ClipData; +import android.os.ParcelFileDescriptor; import android.util.Log; import android.view.ContextMenu; import android.view.KeyEvent; @@ -168,6 +170,17 @@ public class QtNative return ok; } + public static int openFdForContentUrl(Context context, String contentUrl, String openMode) + { + try { + ContentResolver resolver = context.getContentResolver(); + ParcelFileDescriptor fdDesc = resolver.openFileDescriptor(Uri.parse(contentUrl), openMode); + return fdDesc.detachFd(); + } catch (FileNotFoundException e) { + return -1; + } + } + // this method loads full path libs public static void loadQtLibraries(final ArrayList<String> libraries) { diff --git a/src/plugins/platforms/android/android.pro b/src/plugins/platforms/android/android.pro index f91db1ab5f..78632a9bea 100644 --- a/src/plugins/platforms/android/android.pro +++ b/src/plugins/platforms/android/android.pro @@ -20,6 +20,7 @@ INCLUDEPATH += \ $$QT_SOURCE_TREE/src/3rdparty/android SOURCES += $$PWD/androidplatformplugin.cpp \ + $$PWD/androidcontentfileengine.cpp \ $$PWD/androiddeadlockprotector.cpp \ $$PWD/androidjnimain.cpp \ $$PWD/androidjniaccessibility.cpp \ @@ -50,6 +51,7 @@ SOURCES += $$PWD/androidplatformplugin.cpp \ $$PWD/qandroidplatformfiledialoghelper.cpp HEADERS += $$PWD/qandroidplatformintegration.h \ + $$PWD/androidcontentfileengine.h \ $$PWD/androiddeadlockprotector.h \ $$PWD/androidjnimain.h \ $$PWD/androidjniaccessibility.h \ diff --git a/src/plugins/platforms/android/androidcontentfileengine.cpp b/src/plugins/platforms/android/androidcontentfileengine.cpp new file mode 100644 index 0000000000..1444407195 --- /dev/null +++ b/src/plugins/platforms/android/androidcontentfileengine.cpp @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Volker Krause <vkrause@kde.org> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "androidcontentfileengine.h" + +#include <private/qjni_p.h> +#include <private/qjnihelpers_p.h> + +#include <QDebug> + +AndroidContentFileEngine::AndroidContentFileEngine(const QString &fileName) + : QFSFileEngine(fileName) +{ +} + +bool AndroidContentFileEngine::open(QIODevice::OpenMode openMode) +{ + QString openModeStr; + if (openMode & QFileDevice::ReadOnly) { + openModeStr += QLatin1Char('r'); + } + if (openMode & QFileDevice::WriteOnly) { + openModeStr += QLatin1Char('w'); + } + if (openMode & QFileDevice::Truncate) { + openModeStr += QLatin1Char('t'); + } else if (openMode & QFileDevice::Append) { + openModeStr += QLatin1Char('a'); + } + + const auto fd = QJNIObjectPrivate::callStaticMethod<jint>("org/qtproject/qt5/android/QtNative", + "openFdForContentUrl", + "(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)I", + QtAndroidPrivate::context(), + QJNIObjectPrivate::fromString(fileName(DefaultName)).object(), + QJNIObjectPrivate::fromString(openModeStr).object()); + + if (fd < 0) { + return false; + } + + return QFSFileEngine::open(openMode, fd, QFile::AutoCloseHandle); +} + + +AndroidContentFileEngineHandler::AndroidContentFileEngineHandler() = default; +AndroidContentFileEngineHandler::~AndroidContentFileEngineHandler() = default; + +QAbstractFileEngine* AndroidContentFileEngineHandler::create(const QString &fileName) const +{ + if (!fileName.startsWith(QLatin1String("content"))) { + return nullptr; + } + + return new AndroidContentFileEngine(fileName); +} diff --git a/src/plugins/platforms/android/androidcontentfileengine.h b/src/plugins/platforms/android/androidcontentfileengine.h new file mode 100644 index 0000000000..db3def03d6 --- /dev/null +++ b/src/plugins/platforms/android/androidcontentfileengine.h @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Volker Krause <vkrause@kde.org> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ANDROIDCONTENTFILEENGINE_H +#define ANDROIDCONTENTFILEENGINE_H + +#include <private/qfsfileengine_p.h> + +class AndroidContentFileEngine : public QFSFileEngine +{ +public: + AndroidContentFileEngine(const QString &fileName); + bool open(QIODevice::OpenMode openMode) override; +}; + +class AndroidContentFileEngineHandler : public QAbstractFileEngineHandler +{ +public: + AndroidContentFileEngineHandler(); + ~AndroidContentFileEngineHandler(); + QAbstractFileEngine *create(const QString &fileName) const override; +}; + +#endif // ANDROIDCONTENTFILEENGINE_H diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index 13d41bea99..37cfbc13ec 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -49,6 +49,7 @@ #include "androidjniinput.h" #include "androidjniclipboard.h" #include "androidjnimenu.h" +#include "androidcontentfileengine.h" #include "androiddeadlockprotector.h" #include "qandroidplatformdialoghelpers.h" #include "qandroidplatformintegration.h" @@ -116,6 +117,7 @@ static double m_scaledDensity = 0; static double m_density = 1.0; static AndroidAssetsFileEngineHandler *m_androidAssetsFileEngineHandler = nullptr; +static AndroidContentFileEngineHandler *m_androidContentFileEngineHandler = nullptr; @@ -445,6 +447,7 @@ static jboolean startQtAndroidPlugin(JNIEnv *env, jobject /*object*/, jstring pa { m_androidPlatformIntegration = nullptr; m_androidAssetsFileEngineHandler = new AndroidAssetsFileEngineHandler(); + m_androidContentFileEngineHandler = new AndroidContentFileEngineHandler(); m_mainLibraryHnd = nullptr; { // Set env. vars const char *nativeString = env->GetStringUTFChars(environmentString, 0); @@ -555,6 +558,8 @@ static void quitQtAndroidPlugin(JNIEnv *env, jclass /*clazz*/) m_androidPlatformIntegration = nullptr; delete m_androidAssetsFileEngineHandler; m_androidAssetsFileEngineHandler = nullptr; + delete m_androidContentFileEngineHandler; + m_androidContentFileEngineHandler = nullptr; } static void terminateQt(JNIEnv *env, jclass /*clazz*/) From 56a8c277546fba6ad45711e95db26c74178ef512 Mon Sep 17 00:00:00 2001 From: Lars Knoll <lars.knoll@qt.io> Date: Tue, 12 Feb 2019 09:53:11 +0100 Subject: [PATCH 1154/1650] Remove bogus assert MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The code was actually completely fine, but the assert was bogus. detach() can call realloc(d->alloc). Fixes: QTBUG-73756 Change-Id: I3485bc926dba3f2537e14c0c05d30ff982e6e714 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> --- src/corelib/tools/qvector.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index b51cd819c5..988d5a9e1b 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -672,7 +672,6 @@ void QVector<T>::realloc(int aalloc, QArrayData::AllocationOptions options) Data *x = d; const bool isShared = d->ref.isShared(); - Q_ASSERT(aalloc != int(d->alloc) || isShared); QT_TRY { // allocate memory From 48f5b671a3102df50115e566c01298f3e9106654 Mon Sep 17 00:00:00 2001 From: Michal Klocek <michal.klocek@qt.io> Date: Mon, 19 Nov 2018 15:49:48 +0100 Subject: [PATCH 1155/1650] Add native handle for context in offscreen plugin Offscreen plugin can be compiled with x11 support. In case of glx add missing native handle for context. This fixes crashes of running web engine with offscreenplugin (with glx support). Task-number: QTBUG-63346 Change-Id: Ia717ad2551536fbfdfb6633e506704a3ebe42a2b Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io> --- src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp index 06a9bd2a4c..38d06a4131 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp +++ b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp @@ -41,6 +41,7 @@ #include <QByteArray> #include <QOpenGLContext> +#include <QtPlatformHeaders/QGLXNativeContext> #include <X11/Xlib.h> #include <GL/glx.h> @@ -228,6 +229,9 @@ QOffscreenX11GLXContext::QOffscreenX11GLXContext(QOffscreenX11Info *x11, QOpenGL d->window = createDummyWindow(x11, visualInfo); XFree(visualInfo); } + if (d->context) + context->setNativeHandle(QVariant::fromValue<QGLXNativeContext>(QGLXNativeContext(d->context))); + } QOffscreenX11GLXContext::~QOffscreenX11GLXContext() From 652e9146ac3a28a166928f7e594dfa1c3514e912 Mon Sep 17 00:00:00 2001 From: Michal Klocek <michal.klocek@qt.io> Date: Fri, 8 Feb 2019 13:51:05 +0100 Subject: [PATCH 1156/1650] Fix incorrect surface type in offscreen plugin In case we use glx backend set correct surface. Task-number: QTBUG-63346 Change-Id: I5827bf5b8e4ed60b933c25ce234fdd4a3dd20c88 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io> --- .../platforms/offscreen/qoffscreenintegration_x11.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp index 38d06a4131..2e9f1eec2c 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp +++ b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp @@ -87,6 +87,7 @@ bool QOffscreenX11Integration::hasCapability(QPlatformIntegration::Capability ca switch (cap) { case OpenGL: return true; case ThreadedOpenGL: return true; + case RasterGLSurface: return true; default: return QOffscreenIntegration::hasCapability(cap); } } @@ -196,6 +197,12 @@ QOffscreenX11GLXContext::QOffscreenX11GLXContext(QOffscreenX11Info *x11, QOpenGL d->x11 = x11; d->format = context->format(); + if (d->format.renderableType() == QSurfaceFormat::DefaultRenderableType) + d->format.setRenderableType(QSurfaceFormat::OpenGL); + + if (d->format.renderableType() != QSurfaceFormat::OpenGL) + return; + d->shareContext = 0; if (context->shareHandle()) d->shareContext = static_cast<QOffscreenX11GLXContext *>(context->shareHandle())->d->context; From 6bad49308a9d943200fd48a8c9f732de20250bed Mon Sep 17 00:00:00 2001 From: Michal Klocek <michal.klocek@qt.io> Date: Fri, 8 Feb 2019 14:00:42 +0100 Subject: [PATCH 1157/1650] Fix handling of glxconfig and glxcontext in offscreen plugin Return glxconfig and glxcontext, it is needed by share context in chromium. Task-number: QTBUG-63346 Change-Id: Ief15bf7170af9cf61a71453043a2629a4bcbcdc2 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io> --- .../offscreen/qoffscreenintegration_x11.cpp | 38 ++++++++++++++----- .../offscreen/qoffscreenintegration_x11.h | 3 ++ 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp index 2e9f1eec2c..2532cedc70 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp +++ b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp @@ -122,11 +122,16 @@ void *QOffscreenX11Integration::nativeResourceForScreen(const QByteArray &resour #ifndef QT_NO_OPENGL void *QOffscreenX11Integration::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) { if (resource.toLower() == QByteArrayLiteral("glxconfig") ) { - if (!m_connection) - m_connection.reset(new QOffscreenX11Connection); - QOffscreenX11Info *x11 = m_connection->x11Info(); - GLXFBConfig config = qglx_findConfig(x11->display(), x11->screenNumber(), context->format()); - return config; + if (context) { + QOffscreenX11GLXContext *glxPlatformContext = static_cast<QOffscreenX11GLXContext *>(context->handle()); + return glxPlatformContext->glxConfig(); + } + } + if (resource.toLower() == QByteArrayLiteral("glxcontext") ) { + if (context) { + QOffscreenX11GLXContext *glxPlatformContext = static_cast<QOffscreenX11GLXContext *>(context->handle()); + return glxPlatformContext->glxContext(); + } } return nullptr; } @@ -158,11 +163,12 @@ QOffscreenX11Info *QOffscreenX11Connection::x11Info() class QOffscreenX11GLXContextData { public: - QOffscreenX11Info *x11; + QOffscreenX11Info *x11 = nullptr; QSurfaceFormat format; - GLXContext context; - GLXContext shareContext; - Window window; + GLXContext context = nullptr; + GLXContext shareContext = nullptr; + GLXFBConfig config = nullptr; + Window window = 0; }; static Window createDummyWindow(QOffscreenX11Info *x11, XVisualInfo *visualInfo) @@ -173,6 +179,7 @@ static Window createDummyWindow(QOffscreenX11Info *x11, XVisualInfo *visualInfo) a.border_pixel = BlackPixel(x11->display(), x11->screenNumber()); a.colormap = cmap; + Window window = XCreateWindow(x11->display(), x11->root(), 0, 0, 100, 100, 0, visualInfo->depth, InputOutput, visualInfo->visual, @@ -194,6 +201,7 @@ static Window createDummyWindow(QOffscreenX11Info *x11, GLXFBConfig config) QOffscreenX11GLXContext::QOffscreenX11GLXContext(QOffscreenX11Info *x11, QOpenGLContext *context) : d(new QOffscreenX11GLXContextData) { + d->x11 = x11; d->format = context->format(); @@ -208,6 +216,8 @@ QOffscreenX11GLXContext::QOffscreenX11GLXContext(QOffscreenX11Info *x11, QOpenGL d->shareContext = static_cast<QOffscreenX11GLXContext *>(context->shareHandle())->d->context; GLXFBConfig config = qglx_findConfig(x11->display(), x11->screenNumber(), d->format); + d->config = config; + if (config) { d->context = glXCreateNewContext(x11->display(), config, GLX_RGBA_TYPE, d->shareContext, true); if (!d->context && d->shareContext) { @@ -291,4 +301,14 @@ bool QOffscreenX11GLXContext::isValid() const return d->context && d->window; } +void *QOffscreenX11GLXContext::glxContext() const +{ + return d->context; +} + +void *QOffscreenX11GLXContext::glxConfig() const +{ + return d->config; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h index a1986fdc94..5ef51a15a8 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h +++ b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h @@ -104,6 +104,9 @@ public: bool isSharing() const override; bool isValid() const override; + void *glxConfig() const; + void *glxContext() const; + private: QScopedPointer<QOffscreenX11GLXContextData> d; }; From e1d42a40a2fabefdc57c40e25dbf7b923332ba5d Mon Sep 17 00:00:00 2001 From: Alessandro Portale <alessandro.portale@qt.io> Date: Mon, 11 Feb 2019 00:02:37 +0100 Subject: [PATCH 1158/1650] Add missing "override" specifiers Annotate this function with 'override' or (rarely) 'final' [modernize-use-override] Change-Id: If31ab03b46f885e4984ba3aaaf1ad8d46aae9d9c Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> --- src/corelib/codecs/qbig5codec_p.h | 20 ++++++------ src/corelib/io/qfilesystemwatcher_win_p.h | 6 ++-- src/corelib/kernel/qeventdispatcher_win_p.h | 34 ++++++++++----------- src/widgets/itemviews/qitemeditorfactory.h | 4 +-- 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/corelib/codecs/qbig5codec_p.h b/src/corelib/codecs/qbig5codec_p.h index 2db8377ee3..c17afae1c4 100644 --- a/src/corelib/codecs/qbig5codec_p.h +++ b/src/corelib/codecs/qbig5codec_p.h @@ -69,12 +69,12 @@ public: static QList<QByteArray> _aliases(); static int _mibEnum(); - QByteArray name() const { return _name(); } - QList<QByteArray> aliases() const { return _aliases(); } - int mibEnum() const { return _mibEnum(); } + QByteArray name() const override { return _name(); } + QList<QByteArray> aliases() const override { return _aliases(); } + int mibEnum() const override { return _mibEnum(); } - QString convertToUnicode(const char *, int, ConverterState *) const; - QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const; + QString convertToUnicode(const char *, int, ConverterState *) const override; + QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const override; }; class QBig5hkscsCodec : public QTextCodec { @@ -83,12 +83,12 @@ public: static QList<QByteArray> _aliases() { return QList<QByteArray>(); } static int _mibEnum(); - QByteArray name() const { return _name(); } - QList<QByteArray> aliases() const { return _aliases(); } - int mibEnum() const { return _mibEnum(); } + QByteArray name() const override { return _name(); } + QList<QByteArray> aliases() const override { return _aliases(); } + int mibEnum() const override { return _mibEnum(); } - QString convertToUnicode(const char *, int, ConverterState *) const; - QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const; + QString convertToUnicode(const char *, int, ConverterState *) const override; + QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const override; }; QT_END_NAMESPACE diff --git a/src/corelib/io/qfilesystemwatcher_win_p.h b/src/corelib/io/qfilesystemwatcher_win_p.h index 1d3224614c..272591ce7a 100644 --- a/src/corelib/io/qfilesystemwatcher_win_p.h +++ b/src/corelib/io/qfilesystemwatcher_win_p.h @@ -77,8 +77,8 @@ public: explicit QWindowsFileSystemWatcherEngine(QObject *parent); ~QWindowsFileSystemWatcherEngine(); - QStringList addPaths(const QStringList &paths, QStringList *files, QStringList *directories); - QStringList removePaths(const QStringList &paths, QStringList *files, QStringList *directories); + QStringList addPaths(const QStringList &paths, QStringList *files, QStringList *directories) override; + QStringList removePaths(const QStringList &paths, QStringList *files, QStringList *directories) override; class Handle { @@ -154,7 +154,7 @@ public: QWindowsFileSystemWatcherEngineThread(); ~QWindowsFileSystemWatcherEngineThread(); - void run(); + void run() override; void stop(); void wakeup(); diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h index a7ed8dda8a..707bc79407 100644 --- a/src/corelib/kernel/qeventdispatcher_win_p.h +++ b/src/corelib/kernel/qeventdispatcher_win_p.h @@ -80,31 +80,31 @@ public: explicit QEventDispatcherWin32(QObject *parent = 0); ~QEventDispatcherWin32(); - bool QT_ENSURE_STACK_ALIGNED_FOR_SSE processEvents(QEventLoop::ProcessEventsFlags flags); - bool hasPendingEvents(); + bool QT_ENSURE_STACK_ALIGNED_FOR_SSE processEvents(QEventLoop::ProcessEventsFlags flags) override; + bool hasPendingEvents() override; - void registerSocketNotifier(QSocketNotifier *notifier); - void unregisterSocketNotifier(QSocketNotifier *notifier); + void registerSocketNotifier(QSocketNotifier *notifier) override; + void unregisterSocketNotifier(QSocketNotifier *notifier) override; - void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object); - bool unregisterTimer(int timerId); - bool unregisterTimers(QObject *object); - QList<TimerInfo> registeredTimers(QObject *object) const; + void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object) override; + bool unregisterTimer(int timerId) override; + bool unregisterTimers(QObject *object) override; + QList<TimerInfo> registeredTimers(QObject *object) const override; - bool registerEventNotifier(QWinEventNotifier *notifier); - void unregisterEventNotifier(QWinEventNotifier *notifier); + bool registerEventNotifier(QWinEventNotifier *notifier) override; + void unregisterEventNotifier(QWinEventNotifier *notifier) override; void activateEventNotifiers(); - int remainingTime(int timerId); + int remainingTime(int timerId) override; - void wakeUp(); - void interrupt(); - void flush(); + void wakeUp() override; + void interrupt() override; + void flush() override; - void startingUp(); - void closingDown(); + void startingUp() override; + void closingDown() override; - bool event(QEvent *e); + bool event(QEvent *e) override; HWND internalHwnd(); diff --git a/src/widgets/itemviews/qitemeditorfactory.h b/src/widgets/itemviews/qitemeditorfactory.h index f2610ad3de..118f6e45e8 100644 --- a/src/widgets/itemviews/qitemeditorfactory.h +++ b/src/widgets/itemviews/qitemeditorfactory.h @@ -66,8 +66,8 @@ class QItemEditorCreator : public QItemEditorCreatorBase { public: inline explicit QItemEditorCreator(const QByteArray &valuePropertyName); - inline QWidget *createWidget(QWidget *parent) const { return new T(parent); } - inline QByteArray valuePropertyName() const { return propertyName; } + inline QWidget *createWidget(QWidget *parent) const override { return new T(parent); } + inline QByteArray valuePropertyName() const override { return propertyName; } private: QByteArray propertyName; From 5993bea032936bd3c913290249eb5b60f819818d Mon Sep 17 00:00:00 2001 From: Alessandro Portale <alessandro.portale@qt.io> Date: Wed, 6 Feb 2019 07:54:33 +0100 Subject: [PATCH 1159/1650] Fix: "Missing emit keyword on signal call" [-Wclazy-incorrect-emit] Change-Id: I32cf5db522dcb14bbe5151914624979929eeb52e Reviewed-by: Tim Jenssen <tim.jenssen@qt.io> --- src/corelib/itemmodels/qidentityproxymodel.cpp | 8 ++++---- src/corelib/itemmodels/qtransposeproxymodel.cpp | 8 ++++---- src/corelib/thread/qfuturewatcher.cpp | 2 +- src/gui/kernel/qguiapplication.cpp | 8 ++++---- src/gui/text/qtextdocument_p.cpp | 2 +- src/network/access/qnetworkfile.cpp | 12 ++++++------ src/network/socket/qabstractsocket_p.h | 2 +- src/network/socket/qlocalsocket_win.cpp | 4 ++-- 8 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/corelib/itemmodels/qidentityproxymodel.cpp b/src/corelib/itemmodels/qidentityproxymodel.cpp index f869601d3f..bb92857786 100644 --- a/src/corelib/itemmodels/qidentityproxymodel.cpp +++ b/src/corelib/itemmodels/qidentityproxymodel.cpp @@ -480,13 +480,13 @@ void QIdentityProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &topLeft Q_ASSERT(topLeft.isValid() ? topLeft.model() == model : true); Q_ASSERT(bottomRight.isValid() ? bottomRight.model() == model : true); Q_Q(QIdentityProxyModel); - q->dataChanged(q->mapFromSource(topLeft), q->mapFromSource(bottomRight), roles); + emit q->dataChanged(q->mapFromSource(topLeft), q->mapFromSource(bottomRight), roles); } void QIdentityProxyModelPrivate::_q_sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last) { Q_Q(QIdentityProxyModel); - q->headerDataChanged(orientation, first, last); + emit q->headerDataChanged(orientation, first, last); } void QIdentityProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(const QList<QPersistentModelIndex> &sourceParents, QAbstractItemModel::LayoutChangeHint hint) @@ -505,7 +505,7 @@ void QIdentityProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(const QList<QPe parents << mappedParent; } - q->layoutAboutToBeChanged(parents, hint); + emit q->layoutAboutToBeChanged(parents, hint); const auto proxyPersistentIndexes = q->persistentIndexList(); for (const QPersistentModelIndex &proxyPersistentIndex : proxyPersistentIndexes) { @@ -540,7 +540,7 @@ void QIdentityProxyModelPrivate::_q_sourceLayoutChanged(const QList<QPersistentM parents << mappedParent; } - q->layoutChanged(parents, hint); + emit q->layoutChanged(parents, hint); } void QIdentityProxyModelPrivate::_q_sourceModelAboutToBeReset() diff --git a/src/corelib/itemmodels/qtransposeproxymodel.cpp b/src/corelib/itemmodels/qtransposeproxymodel.cpp index dd84b97118..f15435739c 100644 --- a/src/corelib/itemmodels/qtransposeproxymodel.cpp +++ b/src/corelib/itemmodels/qtransposeproxymodel.cpp @@ -81,7 +81,7 @@ void QTransposeProxyModelPrivate::onLayoutChanged(const QList<QPersistentModelIn proxyHint = QAbstractItemModel::HorizontalSortHint; else if (hint == QAbstractItemModel::HorizontalSortHint) proxyHint = QAbstractItemModel::VerticalSortHint; - q->layoutChanged(proxyParents, proxyHint); + emit q->layoutChanged(proxyParents, proxyHint); } void QTransposeProxyModelPrivate::onLayoutAboutToBeChanged(const QList<QPersistentModelIndex> &parents, QAbstractItemModel::LayoutChangeHint hint) @@ -108,19 +108,19 @@ void QTransposeProxyModelPrivate::onLayoutAboutToBeChanged(const QList<QPersiste proxyHint = QAbstractItemModel::HorizontalSortHint; else if (hint == QAbstractItemModel::HorizontalSortHint) proxyHint = QAbstractItemModel::VerticalSortHint; - q->layoutAboutToBeChanged(proxyParents, proxyHint); + emit q->layoutAboutToBeChanged(proxyParents, proxyHint); } void QTransposeProxyModelPrivate::onDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>& roles) { Q_Q(QTransposeProxyModel); - q->dataChanged(q->mapFromSource(topLeft), q->mapFromSource(bottomRight), roles); + emit q->dataChanged(q->mapFromSource(topLeft), q->mapFromSource(bottomRight), roles); } void QTransposeProxyModelPrivate::onHeaderDataChanged(Qt::Orientation orientation, int first, int last) { Q_Q(QTransposeProxyModel); - q->headerDataChanged(orientation == Qt::Horizontal ? Qt::Vertical : Qt::Horizontal, first, last); + emit q->headerDataChanged(orientation == Qt::Horizontal ? Qt::Vertical : Qt::Horizontal, first, last); } void QTransposeProxyModelPrivate::onColumnsAboutToBeInserted(const QModelIndex &parent, int first, int last) diff --git a/src/corelib/thread/qfuturewatcher.cpp b/src/corelib/thread/qfuturewatcher.cpp index faeb6b3a28..4ee7693ace 100644 --- a/src/corelib/thread/qfuturewatcher.cpp +++ b/src/corelib/thread/qfuturewatcher.cpp @@ -479,7 +479,7 @@ void QFutureWatcherBasePrivate::sendCallOutEvent(QFutureCallOutEvent *event) emit q->progressValueChanged(event->index1); if (!event->text.isNull()) // ### - q->progressTextChanged(event->text); + emit q->progressTextChanged(event->text); break; case QFutureCallOutEvent::ProgressRange: emit q->progressRangeChanged(event->index1, event->index2); diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 4a0febc615..e0b94676d5 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -2427,9 +2427,9 @@ void QGuiApplicationPrivate::processGeometryChangeEvent(QWindowSystemInterfacePr window->d_func()->resizeEventPending = false; if (actualGeometry.width() != lastReportedGeometry.width()) - window->widthChanged(actualGeometry.width()); + emit window->widthChanged(actualGeometry.width()); if (actualGeometry.height() != lastReportedGeometry.height()) - window->heightChanged(actualGeometry.height()); + emit window->heightChanged(actualGeometry.height()); } if (isMove) { @@ -2438,9 +2438,9 @@ void QGuiApplicationPrivate::processGeometryChangeEvent(QWindowSystemInterfacePr QGuiApplication::sendSpontaneousEvent(window, &e); if (actualGeometry.x() != lastReportedGeometry.x()) - window->xChanged(actualGeometry.x()); + emit window->xChanged(actualGeometry.x()); if (actualGeometry.y() != lastReportedGeometry.y()) - window->yChanged(actualGeometry.y()); + emit window->yChanged(actualGeometry.y()); } } diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp index 66e038122c..c0a0c1a177 100644 --- a/src/gui/text/qtextdocument_p.cpp +++ b/src/gui/text/qtextdocument_p.cpp @@ -275,7 +275,7 @@ void QTextDocumentPrivate::clear() init(); cursors = oldCursors; inContentsChange = true; - q->contentsChange(0, len, 0); + emit q->contentsChange(0, len, 0); inContentsChange = false; if (lout) lout->documentChanged(0, len, 0); diff --git a/src/network/access/qnetworkfile.cpp b/src/network/access/qnetworkfile.cpp index 374dd26e2e..b7c91f28d8 100644 --- a/src/network/access/qnetworkfile.cpp +++ b/src/network/access/qnetworkfile.cpp @@ -65,21 +65,21 @@ void QNetworkFile::open() if (fi.isDir()) { QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Cannot open %1: Path is a directory").arg(fileName()); - error(QNetworkReply::ContentOperationNotPermittedError, msg); + emit error(QNetworkReply::ContentOperationNotPermittedError, msg); } else { - headerRead(QNetworkRequest::LastModifiedHeader, QVariant::fromValue(fi.lastModified())); - headerRead(QNetworkRequest::ContentLengthHeader, QVariant::fromValue(fi.size())); + emit headerRead(QNetworkRequest::LastModifiedHeader, QVariant::fromValue(fi.lastModified())); + emit headerRead(QNetworkRequest::ContentLengthHeader, QVariant::fromValue(fi.size())); opened = QFile::open(QIODevice::ReadOnly | QIODevice::Unbuffered); if (!opened) { QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Error opening %1: %2").arg(fileName(), errorString()); if (exists()) - error(QNetworkReply::ContentAccessDenied, msg); + emit error(QNetworkReply::ContentAccessDenied, msg); else - error(QNetworkReply::ContentNotFoundError, msg); + emit error(QNetworkReply::ContentNotFoundError, msg); } } - finished(opened); + emit finished(opened); } void QNetworkFile::close() diff --git a/src/network/socket/qabstractsocket_p.h b/src/network/socket/qabstractsocket_p.h index 38c0caef49..5aa69d747e 100644 --- a/src/network/socket/qabstractsocket_p.h +++ b/src/network/socket/qabstractsocket_p.h @@ -83,7 +83,7 @@ public: #ifndef QT_NO_NETWORKPROXY inline void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator) override { Q_Q(QAbstractSocket); - q->proxyAuthenticationRequired(proxy, authenticator); + emit q->proxyAuthenticationRequired(proxy, authenticator); } #endif diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp index d6ee76043f..4decbd5ded 100644 --- a/src/network/socket/qlocalsocket_win.cpp +++ b/src/network/socket/qlocalsocket_win.cpp @@ -87,9 +87,9 @@ void QLocalSocketPrivate::_q_winError(ulong windowsError, const QString &functio } if (currentState != state) { - q->emit stateChanged(state); + emit q->stateChanged(state); if (state == QLocalSocket::UnconnectedState && currentState != QLocalSocket::ConnectingState) - q->emit disconnected(); + emit q->disconnected(); } emit q->error(error); } From 6c18f86af7affc60a571c65f0b335d7ee8947100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= <tor.arne.vestbo@qt.io> Date: Tue, 12 Feb 2019 13:02:48 +0100 Subject: [PATCH 1160/1650] Track call sites of QMacAutoReleasePools for debugging pool usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Printing pools by calling [NSAutoreleasePool showPools] will now give a more detailed view of where the various pools in the stack were created, eg: AUTORELEASE POOLS for thread 0x1000be5c0 17 releases pending. [0x107802000] ................ PAGE (hot) (cold) [0x107802038] ################ POOL 0x107802038 [0x107802040] 0x107791c70 ^-- allocated in function: main [0x107802048] ################ POOL 0x107802048 [0x107802050] 0x1073b2e80 ^-- allocated in function: QCocoaWindow::initialize() [0x107802058] 0x107111ed0 NSCompositeAppearance [0x107802060] 0x107111ed0 NSCompositeAppearance [0x107802068] 0x107111ed0 NSCompositeAppearance [0x107802070] 0x1073bbe10 __NSCFString [0x107802078] 0x1073bbde0 _NSViewBackingLayer [0x107802080] 0x1073bc100 NSWeakObjectValue [0x107802088] 0x1073bbe40 QNSView [0x107802090] 0x1073bbe40 QNSView [0x107802098] 0x107111ed0 NSCompositeAppearance [0x1078020a0] 0x107111ed0 NSCompositeAppearance [0x1078020a8] 0x1073bbe40 QNSView [0x1078020b0] ################ POOL 0x1078020b0 [0x1078020b8] 0x1073bbe30 ^-- allocated in function: QCocoaWindow::recreateWindowIfNeeded() Change-Id: I97faf30db5835fea2f05320435b1b8c334a478d1 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> --- src/corelib/kernel/qcore_mac_objc.mm | 59 ++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm index 140c60a080..4550891e2a 100644 --- a/src/corelib/kernel/qcore_mac_objc.mm +++ b/src/corelib/kernel/qcore_mac_objc.mm @@ -48,6 +48,11 @@ #include <UIKit/UIKit.h> #endif +#include <execinfo.h> +#include <dlfcn.h> +#include <cxxabi.h> +#include <objc/runtime.h> + #include <qdebug.h> QT_BEGIN_NAMESPACE @@ -127,22 +132,54 @@ QT_USE_NAMESPACE } @end QT_NAMESPACE_ALIAS_OBJC_CLASS(QMacAutoReleasePoolTracker); + QT_BEGIN_NAMESPACE - -/* - Manages a scoped auto-release pool. - - To track autoreleases without any pools in place, such as in main() - before the runloop has started, export OBJC_DEBUG_MISSING_POOLS=YES - and break in objc_autoreleaseNoPool, e.g.: - - br set -n objc_autoreleaseNoPool -c "[((NSObject*)$r14) class] == [QNSWindow class]" -*/ QMacAutoReleasePool::QMacAutoReleasePool() : pool([[NSAutoreleasePool alloc] init]) { - [[[QMacAutoReleasePoolTracker alloc] initWithPool: + Class trackerClass = [QMacAutoReleasePoolTracker class]; + +#ifdef QT_DEBUG + void *poolFrame = nullptr; + if (__builtin_available(macOS 10.14, iOS 12.0, tvOS 12.0, watchOS 5.0, *)) { + void *frame; + if (backtrace_from_fp(__builtin_frame_address(0), &frame, 1)) + poolFrame = frame; + } else { + static const int maxFrames = 3; + void *callstack[maxFrames]; + if (backtrace(callstack, maxFrames) == maxFrames) + poolFrame = callstack[maxFrames - 1]; + } + + if (poolFrame) { + Dl_info info; + if (dladdr(poolFrame, &info) && info.dli_sname) { + const char *symbolName = info.dli_sname; + if (symbolName[0] == '_') { + int status; + if (char *demangled = abi::__cxa_demangle(info.dli_sname, nullptr, 0, &status)) + symbolName = demangled; + } + + char *className = nullptr; + asprintf(&className, " ^-- allocated in function: %s", symbolName); + + if (Class existingClass = objc_getClass(className)) + trackerClass = existingClass; + else + trackerClass = objc_duplicateClass(trackerClass, className, 0); + + free(className); + + if (symbolName != info.dli_sname) + free((char*)symbolName); + } + } +#endif + + [[[trackerClass alloc] initWithPool: reinterpret_cast<NSAutoreleasePool **>(&pool)] autorelease]; } From 18f415e46d592f255495061618891ed18d356d7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= <tor.arne.vestbo@qt.io> Date: Tue, 22 Jan 2019 12:34:02 +0100 Subject: [PATCH 1161/1650] QBackingStore: Make QPlatformBackingStore creation lazy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some platform backing stores may require that the window has been created, so let's defer the platform backingstore creation until absolutely necessary. Change-Id: Ib93151c6473e3bbe77d994782d84289c2f63bcf2 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> --- src/gui/painting/qbackingstore.cpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index 0dfb52e7c3..d935deb4d6 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -62,7 +62,7 @@ public: } QWindow *window; - QPlatformBackingStore *platformBackingStore; + QPlatformBackingStore *platformBackingStore = nullptr; QScopedPointer<QImage> highDpiBackingstore; QRegion staticContents; QSize size; @@ -95,8 +95,6 @@ public: QBackingStore::QBackingStore(QWindow *window) : d_ptr(new QBackingStorePrivate(window)) { - d_ptr->platformBackingStore = QGuiApplicationPrivate::platformIntegration()->createPlatformBackingStore(window); - d_ptr->platformBackingStore->setBackingStore(this); } /*! @@ -131,7 +129,8 @@ void QBackingStore::beginPaint(const QRegion ®ion) d_ptr->highDpiBackingstore->devicePixelRatio() != d_ptr->window->devicePixelRatio()) resize(size()); - d_ptr->platformBackingStore->beginPaint(QHighDpi::toNativeLocalRegion(region, d_ptr->window)); + QPlatformBackingStore *platformBackingStore = handle(); + platformBackingStore->beginPaint(QHighDpi::toNativeLocalRegion(region, d_ptr->window)); // When QtGui is applying a high-dpi scale factor the backing store // creates a "large" backing store image. This image needs to be @@ -139,7 +138,7 @@ void QBackingStore::beginPaint(const QRegion ®ion) // devicePixelRatio. Do this on a separate image instance that shares // the image data to avoid having the new devicePixelRatio be propagated // back to the platform plugin. - QPaintDevice *device = d_ptr->platformBackingStore->paintDevice(); + QPaintDevice *device = platformBackingStore->paintDevice(); if (QHighDpiScaling::isActive() && device->devType() == QInternal::Image) { QImage *source = static_cast<QImage *>(device); const bool needsNewImage = d_ptr->highDpiBackingstore.isNull() @@ -168,7 +167,7 @@ void QBackingStore::beginPaint(const QRegion ®ion) */ QPaintDevice *QBackingStore::paintDevice() { - QPaintDevice *device = d_ptr->platformBackingStore->paintDevice(); + QPaintDevice *device = handle()->paintDevice(); if (QHighDpiScaling::isActive() && device->devType() == QInternal::Image) return d_ptr->highDpiBackingstore.data(); @@ -189,7 +188,7 @@ void QBackingStore::endPaint() if (paintDevice()->paintingActive()) qWarning() << "QBackingStore::endPaint() called with active painter on backingstore paint device"; - d_ptr->platformBackingStore->endPaint(); + handle()->endPaint(); } static bool isRasterSurface(QWindow *window) @@ -247,7 +246,7 @@ void QBackingStore::flush(const QRegion ®ion, QWindow *window, const QPoint & Q_ASSERT(window == topLevelWindow || topLevelWindow->isAncestorOf(window, QWindow::ExcludeTransients)); - d_ptr->platformBackingStore->flush(window, QHighDpi::toNativeLocalRegion(region, window), + handle()->flush(window, QHighDpi::toNativeLocalRegion(region, window), QHighDpi::toNativeLocalPosition(offset, window)); } @@ -259,7 +258,7 @@ void QBackingStore::flush(const QRegion ®ion, QWindow *window, const QPoint & void QBackingStore::resize(const QSize &size) { d_ptr->size = size; - d_ptr->platformBackingStore->resize(QHighDpi::toNativePixels(size, d_ptr->window), d_ptr->staticContents); + handle()->resize(QHighDpi::toNativePixels(size, d_ptr->window), d_ptr->staticContents); } /*! @@ -286,7 +285,7 @@ bool QBackingStore::scroll(const QRegion &area, int dx, int dy) if (qFloor(nativeDx) != nativeDx || qFloor(nativeDy) != nativeDy) return false; - return d_ptr->platformBackingStore->scroll(QHighDpi::toNativeLocalRegion(area, d_ptr->window), + return handle()->scroll(QHighDpi::toNativeLocalRegion(area, d_ptr->window), nativeDx, nativeDy); } @@ -367,6 +366,10 @@ void Q_GUI_EXPORT qt_scrollRectInImage(QImage &img, const QRect &rect, const QPo */ QPlatformBackingStore *QBackingStore::handle() const { + if (!d_ptr->platformBackingStore) { + d_ptr->platformBackingStore = QGuiApplicationPrivate::platformIntegration()->createPlatformBackingStore(d_ptr->window); + d_ptr->platformBackingStore->setBackingStore(const_cast<QBackingStore*>(this)); + } return d_ptr->platformBackingStore; } From 2dcfaf7bee9e74546b96481554ba06d5dcb29cfa Mon Sep 17 00:00:00 2001 From: Joerg Bornemann <joerg.bornemann@qt.io> Date: Wed, 30 Jan 2019 13:44:54 +0100 Subject: [PATCH 1162/1650] qmake/vcxproj generator: Fix bug in extra compiler initialization QMake ignored every extra compiler that sets variable_out and whose output does not have a builtin compiler (C++, C). What the code wants to achieve is to ignore extra compilers that put their output into variables that are handled "somewhere else already", e.g. are in the otherFilters list. Evidence for that is to be found in the addOnInput == true if branch. Task-number: QTBUG-71283 Change-Id: I8c1d76febccacb450cd14ad7a1f4b87726832312 Reviewed-by: Brett Stottlemyer <bstottle@ford.com> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> --- qmake/generators/win32/msvc_vcproj.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 95c16661e7..a81e540e1f 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -1541,14 +1541,14 @@ void VcprojGenerator::initExtraCompilerOutputs() extraCompile.Filter = ""; extraCompile.Guid = QString(_GUIDExtraCompilerFiles) + "-" + (*it); - // If the extra compiler has a variable_out set the output file - // is added to an other file list, and does not need its own.. bool addOnInput = hasBuiltinCompiler(firstExpandedOutputFileName(*it)); - const ProString &tmp_other_out = project->first(ProKey(*it + ".variable_out")); - if (!tmp_other_out.isEmpty() && !addOnInput) - continue; - if (!addOnInput) { + // If the extra compiler has a variable_out set that is already handled + // some other place, ignore it. + const ProString &outputVar = project->first(ProKey(*it + ".variable_out")); + if (!outputVar.isEmpty() && otherFilters.contains(outputVar)) + continue; + QString tmp_out = project->first(ProKey(*it + ".output")).toQString(); if (project->values(ProKey(*it + ".CONFIG")).indexOf("combine") != -1) { // Combined output, only one file result From 9f3cdf3d44cce757450f027684980538cb1263c5 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann <joerg.bornemann@qt.io> Date: Fri, 1 Feb 2019 15:06:56 +0100 Subject: [PATCH 1163/1650] INSTALL: Remove outdated reference to Windows CE Change-Id: Ie4960ab6632642094b97d8eeae5bfe17b0aad633 Reviewed-by: Maurice Kalinowski <maurice.kalinowski@qt.io> --- INSTALL | 1 - 1 file changed, 1 deletion(-) diff --git a/INSTALL b/INSTALL index 7c14b301f8..d0976a92ae 100644 --- a/INSTALL +++ b/INSTALL @@ -7,4 +7,3 @@ or follow one of these links: Mac OS X: http://doc.qt.io/qt-%SHORTVERSION%/osx-building.html Windows: http://doc.qt.io/qt-%SHORTVERSION%/windows-building.html X11 Platforms: http://doc.qt.io/qt-%SHORTVERSION%/linux-building.html -Windows CE: http://doc.qt.io/qt-%SHORTVERSION%/install-wince.html From 37e545e0f133ff6be9e9071e9419b0996e41fcdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= <tor.arne.vestbo@qt.io> Date: Fri, 4 Jan 2019 17:08:15 +0100 Subject: [PATCH 1164/1650] Deduplicate QWidgetBackingStore::markDirty Now that MSVC (presumably) supports templates, we can merge the QRect and QRegion versions of the functions into one. Change-Id: Ia4264096c4988d9043444e604ebb133e4ff2ace9 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> --- src/widgets/kernel/qwidget_p.h | 5 + src/widgets/kernel/qwidgetbackingstore.cpp | 179 +++++++-------------- src/widgets/kernel/qwidgetbackingstore_p.h | 6 +- 3 files changed, 66 insertions(+), 124 deletions(-) diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 60612e9b52..e50d828775 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -607,6 +607,11 @@ public: return extra ? extra->nativeChildrenForced : false; } + inline QRect effectiveRectFor(const QRegion ®ion) const + { + return effectiveRectFor(region.boundingRect()); + } + inline QRect effectiveRectFor(const QRect &rect) const { #if QT_CONFIG(graphicseffect) diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index f4d1dab84e..0481dffda8 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -507,6 +507,9 @@ void QWidgetBackingStore::sendUpdateRequest(QWidget *widget, UpdateTime updateTi } } +static inline QRect widgetRectFor(QWidget *, const QRect &r) { return r; } +static inline QRect widgetRectFor(QWidget *widget, const QRegion &) { return widget->rect(); } + /*! Marks the region of the widget as dirty (if not already marked as dirty) and posts an UpdateRequest event to the top-level widget (if not already posted). @@ -517,178 +520,114 @@ void QWidgetBackingStore::sendUpdateRequest(QWidget *widget, UpdateTime updateTi If the widget paints directly on screen, the event is sent to the widget instead of the top-level widget, and bufferState is completely ignored. - - ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore). */ -void QWidgetBackingStore::markDirty(const QRegion &rgn, QWidget *widget, - UpdateTime updateTime, BufferState bufferState) +template <class T> +void QWidgetBackingStore::markDirty(const T &r, QWidget *widget, UpdateTime updateTime, BufferState bufferState) { Q_ASSERT(tlw->d_func()->extra); Q_ASSERT(tlw->d_func()->extra->topextra); Q_ASSERT(!tlw->d_func()->extra->topextra->inTopLevelResize); Q_ASSERT(widget->isVisible() && widget->updatesEnabled()); Q_ASSERT(widget->window() == tlw); - Q_ASSERT(!rgn.isEmpty()); + Q_ASSERT(!r.isEmpty()); #if QT_CONFIG(graphicseffect) widget->d_func()->invalidateGraphicsEffectsRecursively(); -#endif // QT_CONFIG(graphicseffect) +#endif + + QRect widgetRect = widgetRectFor(widget, r); + + // --------------------------------------------------------------------------- if (widget->d_func()->paintOnScreen()) { if (widget->d_func()->dirty.isEmpty()) { - widget->d_func()->dirty = rgn; + widget->d_func()->dirty = r; sendUpdateRequest(widget, updateTime); return; - } else if (qt_region_strictContains(widget->d_func()->dirty, widget->rect())) { + } else if (qt_region_strictContains(widget->d_func()->dirty, widgetRect)) { if (updateTime == UpdateNow) sendUpdateRequest(widget, updateTime); - return; // Already dirty. + return; // Already dirty } const bool eventAlreadyPosted = !widget->d_func()->dirty.isEmpty(); - widget->d_func()->dirty += rgn; + widget->d_func()->dirty += r; if (!eventAlreadyPosted || updateTime == UpdateNow) sendUpdateRequest(widget, updateTime); return; } + // --------------------------------------------------------------------------- + + if (QWidgetPrivate::get(widget)->renderToTexture) { + if (!widget->d_func()->inDirtyList) + addDirtyRenderToTextureWidget(widget); + if (!updateRequestSent || updateTime == UpdateNow) + sendUpdateRequest(tlw, updateTime); + return; + } + + // --------------------------------------------------------------------------- + + QRect effectiveWidgetRect = widget->d_func()->effectiveRectFor(widgetRect); const QPoint offset = widget->mapTo(tlw, QPoint()); - - if (QWidgetPrivate::get(widget)->renderToTexture) { - if (!widget->d_func()->inDirtyList) - addDirtyRenderToTextureWidget(widget); - if (!updateRequestSent || updateTime == UpdateNow) - sendUpdateRequest(tlw, updateTime); - return; - } - - const QRect widgetRect = widget->d_func()->effectiveRectFor(widget->rect()); - if (qt_region_strictContains(dirty, widgetRect.translated(offset))) { - if (updateTime == UpdateNow) - sendUpdateRequest(tlw, updateTime); - return; // Already dirty. - } - - if (bufferState == BufferInvalid) { - const bool eventAlreadyPosted = !dirty.isEmpty() || updateRequestSent; + QRect translatedRect = effectiveWidgetRect.translated(offset); #if QT_CONFIG(graphicseffect) - if (widget->d_func()->graphicsEffect) - dirty += widget->d_func()->effectiveRectFor(rgn.boundingRect()).translated(offset); - else -#endif // QT_CONFIG(graphicseffect) - dirty += rgn.translated(offset); - if (!eventAlreadyPosted || updateTime == UpdateNow) - sendUpdateRequest(tlw, updateTime); - return; - } - - if (dirtyWidgets.isEmpty()) { - addDirtyWidget(widget, rgn); - sendUpdateRequest(tlw, updateTime); - return; - } - - if (widget->d_func()->inDirtyList) { - if (!qt_region_strictContains(widget->d_func()->dirty, widgetRect)) { -#if QT_CONFIG(graphicseffect) - if (widget->d_func()->graphicsEffect) - widget->d_func()->dirty += widget->d_func()->effectiveRectFor(rgn.boundingRect()); - else -#endif // QT_CONFIG(graphicseffect) - widget->d_func()->dirty += rgn; - } - } else { - addDirtyWidget(widget, rgn); - } - - if (updateTime == UpdateNow) - sendUpdateRequest(tlw, updateTime); -} - -/*! - This function is equivalent to calling markDirty(QRegion(rect), ...), but - is more efficient as it eliminates QRegion operations/allocations and can - use the rect more precisely for additional cut-offs. - - ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore). -*/ -void QWidgetBackingStore::markDirty(const QRect &rect, QWidget *widget, - UpdateTime updateTime, BufferState bufferState) -{ - Q_ASSERT(tlw->d_func()->extra); - Q_ASSERT(tlw->d_func()->extra->topextra); - Q_ASSERT(!tlw->d_func()->extra->topextra->inTopLevelResize); - Q_ASSERT(widget->isVisible() && widget->updatesEnabled()); - Q_ASSERT(widget->window() == tlw); - Q_ASSERT(!rect.isEmpty()); - -#if QT_CONFIG(graphicseffect) - widget->d_func()->invalidateGraphicsEffectsRecursively(); -#endif // QT_CONFIG(graphicseffect) - - if (widget->d_func()->paintOnScreen()) { - if (widget->d_func()->dirty.isEmpty()) { - widget->d_func()->dirty = QRegion(rect); - sendUpdateRequest(widget, updateTime); - return; - } else if (qt_region_strictContains(widget->d_func()->dirty, rect)) { - if (updateTime == UpdateNow) - sendUpdateRequest(widget, updateTime); - return; // Already dirty. - } - - const bool eventAlreadyPosted = !widget->d_func()->dirty.isEmpty(); - widget->d_func()->dirty += rect; - if (!eventAlreadyPosted || updateTime == UpdateNow) - sendUpdateRequest(widget, updateTime); - return; - } - - if (QWidgetPrivate::get(widget)->renderToTexture) { - if (!widget->d_func()->inDirtyList) - addDirtyRenderToTextureWidget(widget); - if (!updateRequestSent || updateTime == UpdateNow) - sendUpdateRequest(tlw, updateTime); - return; - } - - - const QRect widgetRect = widget->d_func()->effectiveRectFor(rect); - QRect translatedRect = widgetRect; - if (widget != tlw) - translatedRect.translate(widget->mapTo(tlw, QPoint())); - // Graphics effects may exceed window size, clamp. + // Graphics effects may exceed window size, clamp translatedRect = translatedRect.intersected(QRect(QPoint(), tlw->size())); +#endif if (qt_region_strictContains(dirty, translatedRect)) { if (updateTime == UpdateNow) sendUpdateRequest(tlw, updateTime); return; // Already dirty } + // --------------------------------------------------------------------------- + if (bufferState == BufferInvalid) { - const bool eventAlreadyPosted = !dirty.isEmpty(); - dirty += translatedRect; + const bool eventAlreadyPosted = !dirty.isEmpty() || updateRequestSent; +#if QT_CONFIG(graphicseffect) + if (widget->d_func()->graphicsEffect) + dirty += widget->d_func()->effectiveRectFor(r).translated(offset); + else +#endif + dirty += r.translated(offset); + if (!eventAlreadyPosted || updateTime == UpdateNow) sendUpdateRequest(tlw, updateTime); return; } + // --------------------------------------------------------------------------- + if (dirtyWidgets.isEmpty()) { - addDirtyWidget(widget, rect); + addDirtyWidget(widget, r); sendUpdateRequest(tlw, updateTime); return; } + // --------------------------------------------------------------------------- + if (widget->d_func()->inDirtyList) { - if (!qt_region_strictContains(widget->d_func()->dirty, widgetRect)) - widget->d_func()->dirty += widgetRect; + if (!qt_region_strictContains(widget->d_func()->dirty, effectiveWidgetRect)) { +#if QT_CONFIG(graphicseffect) + if (widget->d_func()->graphicsEffect) + widget->d_func()->dirty += widget->d_func()->effectiveRectFor(r); + else +#endif + widget->d_func()->dirty += r; + } } else { - addDirtyWidget(widget, rect); + addDirtyWidget(widget, r); } + // --------------------------------------------------------------------------- + if (updateTime == UpdateNow) sendUpdateRequest(tlw, updateTime); } +template void QWidgetBackingStore::markDirty<QRect>(const QRect &, QWidget *, UpdateTime, BufferState); +template void QWidgetBackingStore::markDirty<QRegion>(const QRegion &, QWidget *, UpdateTime, BufferState); /*! Marks the \a region of the \a widget as dirty on screen. The \a region will be copied from diff --git a/src/widgets/kernel/qwidgetbackingstore_p.h b/src/widgets/kernel/qwidgetbackingstore_p.h index 41469a04bb..4d15ab138e 100644 --- a/src/widgets/kernel/qwidgetbackingstore_p.h +++ b/src/widgets/kernel/qwidgetbackingstore_p.h @@ -118,10 +118,8 @@ public: return !(dirtyWidgets.isEmpty() && dirty.isEmpty() && dirtyRenderToTextureWidgets.isEmpty()); } - // ### Qt 4.6: Merge into a template function (after MSVC isn't supported anymore). - void markDirty(const QRegion &rgn, QWidget *widget, UpdateTime updateTime = UpdateLater, - BufferState bufferState = BufferValid); - void markDirty(const QRect &rect, QWidget *widget, UpdateTime updateTime = UpdateLater, + template <class T> + void markDirty(const T &r, QWidget *widget, UpdateTime updateTime = UpdateLater, BufferState bufferState = BufferValid); private: From 736cc1d564a204f66b2a3dd8e12a34b64a38d971 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> Date: Fri, 8 Feb 2019 12:43:26 +0100 Subject: [PATCH 1165/1650] Don't wrongly detect fonts as oblique We were interpreting bit #8 as the oblique bit, but this is the WWS-conformity bit. Bit #10 is the oblique bit. [ChangeLog][Windows] Fixed an issue where loading fonts from files or data would sometimes mistakenly classify them as oblique. Fixes: QTBUG-73660 Change-Id: Id9e5012d1b89d0bee0e966c5105657b38834e13a Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com> --- .../fontdatabases/windows/qwindowsfontdatabase.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp index 40ac46df85..bd4338feb8 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp @@ -1429,8 +1429,8 @@ QT_WARNING_POP reinterpret_cast<const OS2Table *>(fontData.constData() + qFromBigEndian<quint32>(os2TableEntry->offset)); - bool italic = qFromBigEndian<quint16>(os2Table->selection) & 1; - bool oblique = qFromBigEndian<quint16>(os2Table->selection) & 128; + bool italic = qFromBigEndian<quint16>(os2Table->selection) & (1 << 0); + bool oblique = qFromBigEndian<quint16>(os2Table->selection) & (1 << 9); if (italic) fontEngine->fontDef.style = QFont::StyleItalic; From 896b30767980f7033c34c2b90be99aac696d6432 Mon Sep 17 00:00:00 2001 From: Oliver Wolff <oliver.wolff@qt.io> Date: Tue, 12 Feb 2019 09:09:50 +0100 Subject: [PATCH 1166/1650] Add support for Visual Studio 2019 Change-Id: I963fc1c159edc644f081675c3dee248c25d7c9dc Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> Reviewed-by: Andre de la Rocha <andre.rocha@qt.io> --- mkspecs/common/msvc-version.conf | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mkspecs/common/msvc-version.conf b/mkspecs/common/msvc-version.conf index de8ba56b7b..06af6abf13 100644 --- a/mkspecs/common/msvc-version.conf +++ b/mkspecs/common/msvc-version.conf @@ -113,4 +113,9 @@ greaterThan(QMAKE_MSC_VER, 1910) { COMPAT_MKSPEC = } +greaterThan(QMAKE_MSC_VER, 1919) { + # Visual Studio 2019 (16.0) / Visual C++ 19.20 and up + MSVC_VER = 16.0 +} + !isEmpty(COMPAT_MKSPEC):!$$COMPAT_MKSPEC: CONFIG += $$COMPAT_MKSPEC From 4aafe68e1ac12ab0f897828f9f8c2930a68fac95 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann <joerg.bornemann@qt.io> Date: Tue, 12 Feb 2019 09:23:28 +0100 Subject: [PATCH 1167/1650] qmake vcxproj generator: Update platform toolset and solution header for VS 2019 Change-Id: Id01f28f2ef3e271fa48dddf5f8ccb6b057180aa0 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> --- qmake/generators/win32/msvc_objectmodel.cpp | 3 ++- qmake/generators/win32/msvc_objectmodel.h | 3 ++- qmake/generators/win32/msvc_vcproj.cpp | 10 ++++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp index 4f0cee65e1..7335211f30 100644 --- a/qmake/generators/win32/msvc_objectmodel.cpp +++ b/qmake/generators/win32/msvc_objectmodel.cpp @@ -55,7 +55,8 @@ static DotNET vsVersionFromString(const char *versionString) { "11.0", NET2012 }, { "12.0", NET2013 }, { "14.0", NET2015 }, - { "15.0", NET2017 } + { "15.0", NET2017 }, + { "16.0", NET2019 } }; DotNET result = NETUnknown; for (const auto entry : mapping) { diff --git a/qmake/generators/win32/msvc_objectmodel.h b/qmake/generators/win32/msvc_objectmodel.h index 9d1a170489..41a6ffafa7 100644 --- a/qmake/generators/win32/msvc_objectmodel.h +++ b/qmake/generators/win32/msvc_objectmodel.h @@ -52,7 +52,8 @@ enum DotNET { NET2012 = 0xb0, NET2013 = 0xc0, NET2015 = 0xd0, - NET2017 = 0xe0 + NET2017 = 0xe0, + NET2019 }; DotNET vsVersionFromString(const ProString &versionString); diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index a81e540e1f..669c8287ff 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -74,6 +74,8 @@ const char _slnHeader140[] = "Microsoft Visual Studio Solution File, Format "\n# Visual Studio 2015"; const char _slnHeader141[] = "Microsoft Visual Studio Solution File, Format Version 12.00" "\n# Visual Studio 2017"; +const char _slnHeader142[] = "Microsoft Visual Studio Solution File, Format Version 12.00" + "\n# Visual Studio Version 16"; // The following UUID _may_ change for later servicepacks... // If so we need to search through the registry at // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.0\Projects @@ -301,6 +303,8 @@ QString VcprojGenerator::retrievePlatformToolSet() const return QStringLiteral("v140"); case NET2017: return QStringLiteral("v141"); + case NET2019: + return QStringLiteral("v142"); default: return QString(); } @@ -527,6 +531,9 @@ void VcprojGenerator::writeSubDirs(QTextStream &t) } switch (vcProject.Configuration.CompilerVersion) { + case NET2019: + t << _slnHeader142; + break; case NET2017: t << _slnHeader141; break; @@ -874,6 +881,9 @@ void VcprojGenerator::initProject() // Own elements ----------------------------- vcProject.Name = project->first("QMAKE_ORIG_TARGET").toQString(); switch (vcProject.Configuration.CompilerVersion) { + case NET2019: + vcProject.Version = "16.00"; + break; case NET2017: vcProject.Version = "15.00"; break; From 083c03e22b40cda682043df1044e01e15df2ce4b Mon Sep 17 00:00:00 2001 From: Oliver Wolff <oliver.wolff@qt.io> Date: Tue, 12 Feb 2019 10:37:10 +0100 Subject: [PATCH 1168/1650] qmake vcxproj generator: Use correct version in solution header for 2017 Change-Id: I360202c88a8da84f3ecaf43304fcf6f5a992b953 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> --- qmake/generators/win32/msvc_vcproj.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 669c8287ff..713a55d16b 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -73,7 +73,7 @@ const char _slnHeader120[] = "Microsoft Visual Studio Solution File, Format const char _slnHeader140[] = "Microsoft Visual Studio Solution File, Format Version 12.00" "\n# Visual Studio 2015"; const char _slnHeader141[] = "Microsoft Visual Studio Solution File, Format Version 12.00" - "\n# Visual Studio 2017"; + "\n# Visual Studio 15"; const char _slnHeader142[] = "Microsoft Visual Studio Solution File, Format Version 12.00" "\n# Visual Studio Version 16"; // The following UUID _may_ change for later servicepacks... From a2c9f9433a772c03e6aaf820910487d794280c3a Mon Sep 17 00:00:00 2001 From: Oliver Wolff <oliver.wolff@qt.io> Date: Wed, 6 Feb 2019 11:24:17 +0100 Subject: [PATCH 1169/1650] winrt: Handle WaitForWindowExposed As winrt does not have native windows, exposure check was just done by checking, whether the window is the active window. If a window is shown fullscreen though, winrtscreen will be resized. This resize triggers a resize of every maximized or fullscreen window that is shown. If we enter or leave full screen mode, we have to wait until the screen resize and the subsequent window resizes are done and only then we can consider the windows properly exposed. This patch reverts 54bcb9d42f5ceaafcca426dc2a5cc25d299d5a3d and thus unblacklists tst_QGraphicsItem::cursor on WinRT. Fixes: QTBUG-73545 Change-Id: If469fce319ed6b3a5d56b7bf3cbc11929b72bb11 Reviewed-by: Andre de la Rocha <andre.rocha@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Maurice Kalinowski <maurice.kalinowski@qt.io> --- src/plugins/platforms/winrt/qwinrtscreen.cpp | 18 +++++++++++++++++- src/plugins/platforms/winrt/qwinrtscreen.h | 3 +++ src/plugins/platforms/winrt/qwinrtwindow.cpp | 5 ++++- .../graphicsview/qgraphicsitem/BLACKLIST | 3 --- 4 files changed, 24 insertions(+), 5 deletions(-) delete mode 100644 tests/auto/widgets/graphicsview/qgraphicsitem/BLACKLIST diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index 7f1854c601..e611c7be24 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -511,6 +511,7 @@ public: QWindow *currentPressWindow = nullptr; QWindow *currentTargetWindow = nullptr; bool firstMouseMove = true; + bool resizePending = false; }; // To be called from the XAML thread @@ -1402,6 +1403,18 @@ void QWinRTScreen::emulateMouseMove(const QPointF &point, MousePositionTransitio Qt::NoModifier); } +void QWinRTScreen::setResizePending() +{ + Q_D(QWinRTScreen); + d->resizePending = true; +} + +bool QWinRTScreen::resizePending() const +{ + Q_D(const QWinRTScreen); + return d->resizePending; +} + HRESULT QWinRTScreen::onActivated(ICoreWindow *, IWindowActivatedEventArgs *args) { Q_D(QWinRTScreen); @@ -1507,7 +1520,7 @@ HRESULT QWinRTScreen::onRedirectReleased(ICorePointerRedirector *, IPointerEvent return onPointerUpdated(nullptr, args); } -HRESULT QWinRTScreen::onWindowSizeChanged(IApplicationView *, IInspectable *) +HRESULT QWinRTScreen::onWindowSizeChanged(IApplicationView *w, IInspectable *) { Q_D(QWinRTScreen); @@ -1527,6 +1540,9 @@ HRESULT QWinRTScreen::onWindowSizeChanged(IApplicationView *, IInspectable *) QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), availableGeometry()); QPlatformScreen::resizeMaximizedWindows(); handleExpose(); + // If we "emulate" a resize, w will be nullptr.Checking w shows whether it's a real resize + if (w) + d->resizePending = false; return S_OK; } diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h index e28cfd8cc8..63c254940d 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.h +++ b/src/plugins/platforms/winrt/qwinrtscreen.h @@ -136,6 +136,9 @@ public: void emulateMouseMove(const QPointF &point, MousePositionTransition transition); + void setResizePending(); + bool resizePending() const; + private: void handleExpose(); diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp index 83c3715bfd..73816b6512 100644 --- a/src/plugins/platforms/winrt/qwinrtwindow.cpp +++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp @@ -225,7 +225,8 @@ bool QWinRTWindow::isActive() const bool QWinRTWindow::isExposed() const { - const bool exposed = isActive(); + Q_D(const QWinRTWindow); + const bool exposed = isActive() && !d->screen->resizePending(); return exposed; } @@ -360,6 +361,7 @@ void QWinRTWindow::setWindowState(Qt::WindowStates state) qCDebug(lcQpaWindows) << "Failed to enter full screen mode."; return; } + d->screen->setResizePending(); d->state = state; return; } @@ -384,6 +386,7 @@ void QWinRTWindow::setWindowState(Qt::WindowStates state) qCDebug(lcQpaWindows) << "Failed to exit full screen mode."; return; } + d->screen->setResizePending(); } if (d->state & Qt::WindowMinimized || state == Qt::WindowNoState || state == Qt::WindowActive) diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/BLACKLIST b/tests/auto/widgets/graphicsview/qgraphicsitem/BLACKLIST deleted file mode 100644 index 071ccaaff4..0000000000 --- a/tests/auto/widgets/graphicsview/qgraphicsitem/BLACKLIST +++ /dev/null @@ -1,3 +0,0 @@ -[cursor] -# QTBUG-73545 -winrt From 4b4a288f5f88077d647d47e9bdd911edf6cdca72 Mon Sep 17 00:00:00 2001 From: Edward Welbourne <edward.welbourne@qt.io> Date: Tue, 5 Feb 2019 10:45:38 +0100 Subject: [PATCH 1170/1650] Recognize UNC paths as absolute (i.e. not relative) IoUtils::isRelativePath() didn't attempt to consider UNC paths, due to a belief that qmake fails on them so badly that it wasn't worth the extra code. However, it turns out Qt Creator's copy of this code does need to take this into account, so start the change off in qmake's version so as to keep in sync. Task-number: QTCREATORBUG-21881 Change-Id: I3084b87c1d3ca6508255e94e04ac8db3ceaebb7e Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> --- qmake/library/ioutils.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/qmake/library/ioutils.cpp b/qmake/library/ioutils.cpp index 2b2c6d0078..3e49a99cd5 100644 --- a/qmake/library/ioutils.cpp +++ b/qmake/library/ioutils.cpp @@ -77,7 +77,12 @@ bool IoUtils::isRelativePath(const QString &path) && (path.at(2) == QLatin1Char('/') || path.at(2) == QLatin1Char('\\'))) { return false; } - // (... unless, of course, they're UNC, which qmake fails on anyway) + // ... unless, of course, they're UNC: + if (path.length() >= 2 + && (path.at(0).unicode() == '\\' || path.at(0).unicode() == '/') + && path.at(1) == path.at(0)) { + return false; + } #else if (path.startsWith(QLatin1Char('/'))) return false; From 797f686ea4c7ba4953242fc7755bf30e531644d0 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann <joerg.bornemann@qt.io> Date: Mon, 11 Feb 2019 15:00:09 +0100 Subject: [PATCH 1171/1650] Turn bcm_host library into makeSpec source The bcm_host library couldn't be detected anymore. Let the makespec provide LIBDIR, INCDIR and LIBS for bcm_host to fix this. Change-Id: I4bc268504dc48edaf2884f1c14b745260fd9112c Fixes: QTBUG-73727 Reviewed-by: Kai Koehne <kai.koehne@qt.io> --- mkspecs/devices/linux-rasp-pi-g++/qmake.conf | 4 ++++ mkspecs/devices/linux-rasp-pi2-g++/qmake.conf | 5 +++++ mkspecs/devices/linux-rasp-pi3-g++/qmake.conf | 4 ++++ src/gui/configure.json | 3 ++- 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/mkspecs/devices/linux-rasp-pi-g++/qmake.conf b/mkspecs/devices/linux-rasp-pi-g++/qmake.conf index b72091373d..6ec7817efb 100644 --- a/mkspecs/devices/linux-rasp-pi-g++/qmake.conf +++ b/mkspecs/devices/linux-rasp-pi-g++/qmake.conf @@ -20,6 +20,10 @@ QMAKE_INCDIR_OPENVG = $${QMAKE_INCDIR_EGL} QMAKE_LIBS_EGL = -lEGL -lGLESv2 QMAKE_LIBS_OPENVG = -lEGL -lOpenVG -lGLESv2 +QMAKE_INCDIR_BCM_HOST = $$[QT_SYSROOT]/opt/vc/include +QMAKE_LIBDIR_BCM_HOST = $$[QT_SYSROOT]/opt/vc/lib +QMAKE_LIBS_BCM_HOST = -lbcm_host + contains(DISTRO, squeeze) { #Debian Squeeze: Legacy everything QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 -lEGL diff --git a/mkspecs/devices/linux-rasp-pi2-g++/qmake.conf b/mkspecs/devices/linux-rasp-pi2-g++/qmake.conf index ffe8f5739a..3b49f19a5b 100644 --- a/mkspecs/devices/linux-rasp-pi2-g++/qmake.conf +++ b/mkspecs/devices/linux-rasp-pi2-g++/qmake.conf @@ -16,6 +16,11 @@ QMAKE_INCDIR_OPENVG = $${QMAKE_INCDIR_EGL} QMAKE_LIBS_EGL = -lEGL -lGLESv2 QMAKE_LIBS_OPENVG = -lEGL -lOpenVG -lGLESv2 + +QMAKE_INCDIR_BCM_HOST = $$[QT_SYSROOT]/opt/vc/include +QMAKE_LIBDIR_BCM_HOST = $$[QT_SYSROOT]/opt/vc/lib +QMAKE_LIBS_BCM_HOST = -lbcm_host + QMAKE_CFLAGS += -march=armv7-a -marm -mthumb-interwork -mfpu=neon-vfpv4 -mtune=cortex-a7 -mabi=aapcs-linux QMAKE_CXXFLAGS = $$QMAKE_CFLAGS diff --git a/mkspecs/devices/linux-rasp-pi3-g++/qmake.conf b/mkspecs/devices/linux-rasp-pi3-g++/qmake.conf index 2bb70ffb5a..b215833486 100644 --- a/mkspecs/devices/linux-rasp-pi3-g++/qmake.conf +++ b/mkspecs/devices/linux-rasp-pi3-g++/qmake.conf @@ -31,6 +31,10 @@ QMAKE_LIBS_OPENGL_ES2 = $${VC_LINK_LINE} -lGLESv2 # The official opt vc EGL references GLESv2 symbols: need to link it QMAKE_LIBS_EGL = $${VC_LINK_LINE} -lEGL -lGLESv2 +QMAKE_LIBDIR_BCM_HOST = $$VC_LIBRARY_PATH +QMAKE_INCDIR_BCM_HOST = $$VC_INCLUDE_PATH +QMAKE_LIBS_BCM_HOST = -lbcm_host + QMAKE_CFLAGS = -march=armv8-a -mtune=cortex-a53 -mfpu=crypto-neon-fp-armv8 QMAKE_CXXFLAGS = $$QMAKE_CFLAGS diff --git a/src/gui/configure.json b/src/gui/configure.json index 70d0817791..44140bc7b6 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -59,8 +59,9 @@ }, "bcm_host": { "export": "", + "headers": ["bcm_host.h"], "sources": [ - "-lbcm_host" + { "type": "makeSpec", "spec": "BCM_HOST" } ] }, "dxguid": { From a34077ceac6a3e436328fcfb444e20111455a885 Mon Sep 17 00:00:00 2001 From: Andy Shaw <andy.shaw@qt.io> Date: Wed, 13 Feb 2019 15:42:11 +0100 Subject: [PATCH 1172/1650] Windows: Freetype: Load fonts from the user locations Since Windows 10 update 1809 it is possible to install fonts as a user so they are only available for use by the user and not on the system. So this location in the registry needs to be checked as well when looking for available fonts. Fixes: QTBUG-73241 Change-Id: I5d808e38b80dde8189fe8c549a6524bd559e30c7 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> --- .../windows/qwindowsfontdatabase_ft.cpp | 45 ++++++++++--------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp index f68ea54dcf..db2186644b 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp @@ -115,30 +115,33 @@ static FontKeys &fontKeys() { static FontKeys result; if (result.isEmpty()) { - const QSettings fontRegistry(QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"), - QSettings::NativeFormat); - const QStringList allKeys = fontRegistry.allKeys(); - const QString trueType = QStringLiteral("(TrueType)"); + const QStringList keys = { QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"), + QStringLiteral("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts") }; + for (const auto key : keys) { + const QSettings fontRegistry(key, QSettings::NativeFormat); + const QStringList allKeys = fontRegistry.allKeys(); + const QString trueType = QStringLiteral("(TrueType)"); #if QT_CONFIG(regularexpression) - const QRegularExpression sizeListMatch(QStringLiteral("\\s(\\d+,)+\\d+")); + const QRegularExpression sizeListMatch(QStringLiteral("\\s(\\d+,)+\\d+")); #else - const QRegExp sizeListMatch(QLatin1String("\\s(\\d+,)+\\d+")); + const QRegExp sizeListMatch(QLatin1String("\\s(\\d+,)+\\d+")); #endif - Q_ASSERT(sizeListMatch.isValid()); - const int size = allKeys.size(); - result.reserve(size); - for (int i = 0; i < size; ++i) { - FontKey fontKey; - const QString ®istryFontKey = allKeys.at(i); - fontKey.fileName = fontRegistry.value(registryFontKey).toString(); - QString realKey = registryFontKey; - realKey.remove(trueType); - realKey.remove(sizeListMatch); - const auto fontNames = QStringRef(&realKey).trimmed().split(QLatin1Char('&')); - fontKey.fontNames.reserve(fontNames.size()); - for (const QStringRef &fontName : fontNames) - fontKey.fontNames.append(fontName.trimmed().toString()); - result.append(fontKey); + Q_ASSERT(sizeListMatch.isValid()); + const int size = allKeys.size(); + result.reserve(result.size() + size); + for (int i = 0; i < size; ++i) { + FontKey fontKey; + const QString ®istryFontKey = allKeys.at(i); + fontKey.fileName = fontRegistry.value(registryFontKey).toString(); + QString realKey = registryFontKey; + realKey.remove(trueType); + realKey.remove(sizeListMatch); + const auto fontNames = QStringRef(&realKey).trimmed().split(QLatin1Char('&')); + fontKey.fontNames.reserve(fontNames.size()); + for (const QStringRef &fontName : fontNames) + fontKey.fontNames.append(fontName.trimmed().toString()); + result.append(fontKey); + } } } return result; From a5cded843f495b4276a8289b1324778d97bed5ba Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen <allan.jensen@qt.io> Date: Mon, 11 Feb 2019 10:52:06 +0100 Subject: [PATCH 1173/1650] Avoid creating wide images with negative bytesPerLine The QImage API can not handle images with more bytes per line than what an integer can hold. Fixes: QTBUG-73731 Fixes: QTBUG-73732 Change-Id: Ieed6fec7645661fd58d8d25335f806faaa1bb3e9 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> --- src/gui/image/qimage.cpp | 11 +++++++++-- src/gui/image/qimage.h | 4 ++++ src/gui/image/qimage_p.h | 6 ++++++ tests/auto/gui/image/qimage/tst_qimage.cpp | 20 ++++++++++++++++++++ 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 9897c3aa6f..3e18ca6528 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -124,7 +124,7 @@ QImageData * QImageData::create(const QSize &size, QImage::Format format) int height = size.height(); int depth = qt_depthForFormat(format); auto params = calculateImageParameters(width, height, depth); - if (params.bytesPerLine < 0) + if (!params.isValid()) return nullptr; QScopedPointer<QImageData> d(new QImageData); @@ -781,7 +781,7 @@ QImageData *QImageData::create(uchar *data, int width, int height, int bpl, QIm const int depth = qt_depthForFormat(format); auto params = calculateImageParameters(width, height, depth); - if (params.totalSize < 0) + if (!params.isValid()) return nullptr; if (bpl > 0) { @@ -1484,10 +1484,17 @@ qsizetype QImage::sizeInBytes() const \sa scanLine() */ +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) +qsizetype QImage::bytesPerLine() const +{ + return d ? d->bytes_per_line : 0; +} +#else int QImage::bytesPerLine() const { return d ? d->bytes_per_line : 0; } +#endif /*! diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h index 4b7a3b1ead..6505fd5845 100644 --- a/src/gui/image/qimage.h +++ b/src/gui/image/qimage.h @@ -227,7 +227,11 @@ public: uchar *scanLine(int); const uchar *scanLine(int) const; const uchar *constScanLine(int) const; +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + qsizetype bytesPerLine() const; +#else int bytesPerLine() const; +#endif bool valid(int x, int y) const; bool valid(const QPoint &pt) const; diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h index e3a6c53833..a0a3b5406e 100644 --- a/src/gui/image/qimage_p.h +++ b/src/gui/image/qimage_p.h @@ -109,6 +109,7 @@ struct Q_GUI_EXPORT QImageData { // internal image data struct ImageSizeParameters { qsizetype bytesPerLine; qsizetype totalSize; + bool isValid() const { return bytesPerLine > 0 && totalSize > 0; } }; static ImageSizeParameters calculateImageParameters(qsizetype width, qsizetype height, qsizetype depth); }; @@ -135,6 +136,11 @@ QImageData::calculateImageParameters(qsizetype width, qsizetype height, qsizetyp qsizetype dummy; if (mul_overflow(height, qsizetype(sizeof(uchar *)), &dummy)) return invalid; // why is this here? +#if QT_VERSION < QT_VERSION_CHECK(6,0,0) + // Disallow images where width * depth calculations might overflow + if (width > (INT_MAX - 31) / depth) + return invalid; +#endif return { bytes_per_line, total_size }; } diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index eded206d37..6bc27a6e16 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -230,6 +230,8 @@ private slots: void convertColorTable(); + void wideImage(); + #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) void toWinHBITMAP_data(); void toWinHBITMAP(); @@ -3535,6 +3537,24 @@ void tst_QImage::convertColorTable() QCOMPARE(rgb32.pixel(0,0), 0xffffffff); } +void tst_QImage::wideImage() +{ + // QTBUG-73731 and QTBUG-73732 + QImage i(538994187, 2, QImage::Format_ARGB32); + QImage i2(32, 32, QImage::Format_ARGB32); + i2.fill(Qt::white); + + // Test that it doesn't crash: + QPainter painter(&i); + // With the composition mode is SourceOver out it's an invalid write + // With the composition mode is Source it's an invalid read + painter.drawImage(0, 0, i2); + painter.setCompositionMode(QPainter::CompositionMode_Source); + painter.drawImage(0, 0, i2); + + // Qt6: Test that it actually works on 64bit architectures. +} + #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) QT_BEGIN_NAMESPACE Q_GUI_EXPORT HBITMAP qt_imageToWinHBITMAP(const QImage &p, int hbitmapFormat = 0); From 793cfa20a3c5a44be5a67c31f6035fb4dc193edc Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> Date: Thu, 14 Feb 2019 08:10:03 +0100 Subject: [PATCH 1174/1650] [Windows] Fixed regression when creating fallback fonts In 3ccdeb4b58b681bb3a0a43f926f81fd94f527680, we removed the specialized multi font engine on Windows, causing us to go through the same code path when loading fallbacks as on other platforms. When combined with 97f73e957756753b09a778daf2ee8f0ddb97f746, this caused an error, because the code in QFontEngineMulti::loadEngine() only overrode the families list, but not the singular family in the request. In the QRawFont test, this would cause the requested fallback font to correctly have "MS Shell Dlg2" as the only font in the families list, but the request.family would still be "QtBidiTestFont", the name of the main font. The singular family in the request was preferred by the windows font database when creating the LOGFONT. We would therefore load the latter for the fallback as well and since it still does not support the characters in question, we would continue searching. Fixes: QTBUG-72836 Change-Id: I1787b57febcf6030d5c5b09bc2ef2c9558f05beb Reviewed-by: Andy Shaw <andy.shaw@qt.io> --- src/gui/text/qfontengine.cpp | 3 ++- tests/auto/gui/text/qrawfont/BLACKLIST | 3 --- 2 files changed, 2 insertions(+), 4 deletions(-) delete mode 100644 tests/auto/gui/text/qrawfont/BLACKLIST diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index cab4ca0047..c363807e5e 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -1842,7 +1842,8 @@ QFontEngine *QFontEngineMulti::loadEngine(int at) { QFontDef request(fontDef); request.styleStrategy |= QFont::NoFontMerging; - request.families = QStringList(fallbackFamilyAt(at - 1)); + request.family = fallbackFamilyAt(at - 1); + request.families = QStringList(request.family); // At this point, the main script of the text has already been considered // when fetching the list of fallback families from the database, and the diff --git a/tests/auto/gui/text/qrawfont/BLACKLIST b/tests/auto/gui/text/qrawfont/BLACKLIST deleted file mode 100644 index c076f11635..0000000000 --- a/tests/auto/gui/text/qrawfont/BLACKLIST +++ /dev/null @@ -1,3 +0,0 @@ -# QTBUG-72836 -[unsupportedWritingSystem] -windows From 501cca2c4b0851cea7133ba56c3a05d71c25ce6d Mon Sep 17 00:00:00 2001 From: Samuel Thibault <sthibault@debian.org> Date: Sun, 27 Jan 2019 13:54:06 +0100 Subject: [PATCH 1175/1650] Add <features.h> include to hurd-g++ mkspec Without this include, __REDIRECT does not get defined, and then open gets #defined to open64, leading to bogus MOC output. See https://bugs.debian.org/920613. Change-Id: I629d9dc6af05b9480c0c81a61d8890ab8bbefaae Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> --- mkspecs/hurd-g++/qplatformdefs.h | 1 + 1 file changed, 1 insertion(+) diff --git a/mkspecs/hurd-g++/qplatformdefs.h b/mkspecs/hurd-g++/qplatformdefs.h index 3c80cbdfad..b1887aae7f 100644 --- a/mkspecs/hurd-g++/qplatformdefs.h +++ b/mkspecs/hurd-g++/qplatformdefs.h @@ -59,6 +59,7 @@ // We are hot - unistd.h should have turned on the specific APIs we requested +#include <features.h> #include <pthread.h> #include <dirent.h> #include <fcntl.h> From e2cf6ade3535467bc2f21b54b82ed007d5ce279b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= <morten.sorvig@qt.io> Date: Thu, 7 Feb 2019 23:14:10 +0100 Subject: [PATCH 1176/1650] wasm: disable the eglfs platform plugin Emscripten has EGL headers, but we have no use for the eglfs platform plugin on this platform. Change-Id: I50bab4d1ef0b45bb5dd10e5ea9aa3bf9282652a7 Reviewed-by: Lorn Potter <lorn.potter@gmail.com> --- src/gui/configure.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/configure.json b/src/gui/configure.json index 51d89973ed..4420b81409 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -1387,7 +1387,7 @@ "eglfs": { "label": "EGLFS", "section": "Platform plugins", - "condition": "!config.android && !config.darwin && !config.win32 && features.egl", + "condition": "!config.android && !config.darwin && !config.win32 && !config.wasm && features.egl", "output": [ "privateFeature" ] }, "eglfs_brcm": { From 57953174549797d1e87543ff7f70571053caf370 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Sun, 23 Dec 2018 10:20:47 +0100 Subject: [PATCH 1177/1650] QFormLayout: honor vertical expanding size policy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QFormLayout did not honor the vertical expanding state for widgets. Therefore e.g. a QTextEdit was not expanded vertically when it was inside a QFormLayout but worked fine inside a QGridLayout. It was honored when a stretch factor was set though. Fix it by not adding a dummy stretch item when one item is expanding. [ChangeLog][QtWidgets][QFormLayout] Honor the vertical expanding state of a widget inside a QFormLayout. Fixes: QTBUG-72676 Change-Id: If4456145918afa5a10435063770cc93bb9315fbe Reviewed-by: Samuel Gaist <samuel.gaist@idiap.ch> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io> --- src/widgets/kernel/qformlayout.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/kernel/qformlayout.cpp b/src/widgets/kernel/qformlayout.cpp index bd0ea2598a..9146ba84c8 100644 --- a/src/widgets/kernel/qformlayout.cpp +++ b/src/widgets/kernel/qformlayout.cpp @@ -783,7 +783,7 @@ void QFormLayoutPrivate::setupVerticalLayoutData(int width) vLayouts[vidx].expansive = expanding || (vLayouts[vidx].stretch > 0); vLayouts[vidx].empty = false; - if (vLayouts[vidx].stretch > 0) + if (vLayouts[vidx].expansive) addTopBottomStretch = false; if (vidx > 1) From 2634ba5b4da5e315f4b0d396d8f8ab3cc48d9c8e Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen <oswald.buddenhagen@qt.io> Date: Wed, 19 Dec 2018 18:18:24 +0100 Subject: [PATCH 1178/1650] qmake: don't mess up linking order of frameworks make it "last one wins", consistently with regular libraries. this isn't really relevant in qmake, because the order matters only for static frameworks, which qmake defines out of existence. note that specifying frameworks by full path does not work, so we don't need to amend 9d76beee5 in that regard. Change-Id: Ib027109339e1b5973c577d69906b6daf83ba9611 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> --- qmake/generators/unix/unixmake.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp index 4cbe06d9dc..7f42fbe09e 100644 --- a/qmake/generators/unix/unixmake.cpp +++ b/qmake/generators/unix/unixmake.cpp @@ -506,17 +506,14 @@ UnixMakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags) if (opt.startsWith("-Xarch")) opt = l.at(++lit); // The user has done the right thing and prefixed each part } - bool found = false; for(int x = 0; x < lflags[arch].size(); ++x) { if (lflags[arch].at(x) == "-framework" && lflags[arch].at(++x) == opt) { - found = true; + lflags[arch].remove(x - 1, 2); break; } } - if(!found) { - lflags[arch].append("-framework"); - lflags[arch].append(opt); - } + lflags[arch].append("-framework"); + lflags[arch].append(opt); } else { lflags[arch].append(opt); } From 44b91a619d14932635e9a3fe155de4df9f98a25c Mon Sep 17 00:00:00 2001 From: Lorn Potter <lorn.potter@gmail.com> Date: Thu, 14 Feb 2019 04:06:27 +1000 Subject: [PATCH 1179/1650] wasm: fix building examples and applications MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a bug where app build would fail with AssertionError: SIMD is used, but not supported in WASM mode yet Change-Id: I27d5eb00b2c869b890dc519a7a793b7f87aeb9d2 Fixes: QTBUG-73795 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io> --- src/3rdparty/freetype/src/sfnt/pngshim.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/3rdparty/freetype/src/sfnt/pngshim.c b/src/3rdparty/freetype/src/sfnt/pngshim.c index 16020266af..cd110776c8 100644 --- a/src/3rdparty/freetype/src/sfnt/pngshim.c +++ b/src/3rdparty/freetype/src/sfnt/pngshim.c @@ -68,6 +68,7 @@ ( ( __clang_major__ >= 4 ) || \ ( ( __clang_major__ == 3 ) && ( __clang_minor__ >= 2 ) ) ) ) ) && \ defined( __OPTIMIZE__ ) && \ + !defined( __EMSCRIPTEN__ ) && \ __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #ifdef __clang__ From 2c6c724949374b17bd3da2938fe8747b480d575a Mon Sep 17 00:00:00 2001 From: Lorn Potter <lorn.potter@gmail.com> Date: Thu, 22 Feb 2018 04:35:25 +1000 Subject: [PATCH 1180/1650] wasm: add clipboard support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This feature uses the js Clipboard API and is supported only in Chrome, as Firefox only supports reading the clipboard in browser extensions. It also requires https or localhost access, otherwise access to the clipboard is blocked by chrome. Chrome users will be able to copy/paste text to and from the system clipbaord. Other browsers will be able to use the clipboard from within the same application. Currently only supports text and html. Task-number: QTBUG-64638 Change-Id: Ie6de9d10812b776519bd6115593b433fe77059fe Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io> --- src/plugins/platforms/wasm/qwasmclipboard.cpp | 204 ++++++++++++++++++ src/plugins/platforms/wasm/qwasmclipboard.h | 59 +++++ .../platforms/wasm/qwasmeventtranslator.cpp | 23 +- .../platforms/wasm/qwasmintegration.cpp | 18 +- src/plugins/platforms/wasm/qwasmintegration.h | 8 +- src/plugins/platforms/wasm/wasm.pro | 6 +- 6 files changed, 307 insertions(+), 11 deletions(-) create mode 100644 src/plugins/platforms/wasm/qwasmclipboard.cpp create mode 100644 src/plugins/platforms/wasm/qwasmclipboard.h diff --git a/src/plugins/platforms/wasm/qwasmclipboard.cpp b/src/plugins/platforms/wasm/qwasmclipboard.cpp new file mode 100644 index 0000000000..ec058f05dd --- /dev/null +++ b/src/plugins/platforms/wasm/qwasmclipboard.cpp @@ -0,0 +1,204 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwasmclipboard.h" +#include "qwasmwindow.h" + +#include <emscripten.h> +#include <emscripten/html5.h> +#include <emscripten/bind.h> + +#include <QCoreApplication> +#include <qpa/qwindowsysteminterface.h> + +using namespace emscripten; + +// there has got to be a better way... +static QByteArray g_clipboardArray; +static QByteArray g_clipboardFormat; + +static val getClipboardData() +{ + return val(g_clipboardArray.constData()); +} + +static val getClipboardFormat() +{ + return val(g_clipboardFormat.constData()); +} + +static void pasteClipboardData(emscripten::val format, emscripten::val dataPtr) +{ + QString formatString = QString::fromStdString(format.as<std::string>()); + QByteArray dataArray = QByteArray::fromStdString(dataPtr.as<std::string>()); + QMimeData *mMimeData = new QMimeData; + mMimeData->setData(formatString, dataArray); + QWasmClipboard::qWasmClipboardPaste(mMimeData); +} + +static void qClipboardPromiseResolve(emscripten::val something) +{ + pasteClipboardData(emscripten::val("text/plain"), something); +} + +static void qClipboardCopyTo(val event) +{ + val target = event["target"]; + val clipboard = event["clipboardData"]; + + val module = val::global("Module"); + val clipdata = module.call<val>("getClipboardData"); + val clipFormat = module.call<val>("getClipboardFormat"); + clipboard.call<void>("setData", clipFormat, clipdata); + target.call<void>("preventDefault"); +} + +static void qClipboardPasteTo(val event) +{ + val target = event["clipboardData"]; + val module = val::global("Module"); + val clipdata = module.call<val>("getClipboardData"); + + const std::string data = clipdata.as<std::string>(); + if (data.length() > 0) { + QString qstr = QString::fromStdString(data); + QMimeData *mMimeData = new QMimeData; + mMimeData->setText(qstr); + QWasmClipboard::qWasmClipboardPaste(mMimeData); + } +} + +EMSCRIPTEN_BINDINGS(clipboard_module) { + function("getClipboardData", &getClipboardData); + function("getClipboardFormat", &getClipboardFormat); + function("pasteClipboardData", &pasteClipboardData); + function("qClipboardPromiseResolve", &qClipboardPromiseResolve); + function("qClipboardCopyTo", &qClipboardCopyTo); + function("qClipboardPasteTo", &qClipboardPasteTo); +} + +QWasmClipboard::QWasmClipboard() : + hasClipboardApi(false) +{ + initClipboardEvents(); +} + +QWasmClipboard::~QWasmClipboard() +{ + g_clipboardArray.clear(); + g_clipboardFormat.clear(); +} + +QMimeData* QWasmClipboard::mimeData(QClipboard::Mode mode) +{ + if (mode != QClipboard::Clipboard) + return nullptr; + + return QPlatformClipboard::mimeData(mode); +} + +void QWasmClipboard::setMimeData(QMimeData* mimeData, QClipboard::Mode mode) +{ + if (mimeData->hasText()) { + g_clipboardFormat = mimeData->formats().at(0).toUtf8(); + g_clipboardArray = mimeData->text().toUtf8(); + } else if (mimeData->hasHtml()) { + g_clipboardFormat =mimeData->formats().at(0).toUtf8(); + g_clipboardArray = mimeData->html().toUtf8(); + } + + QPlatformClipboard::setMimeData(mimeData, mode); +} + +bool QWasmClipboard::supportsMode(QClipboard::Mode mode) const +{ + return mode == QClipboard::Clipboard; +} + +bool QWasmClipboard::ownsMode(QClipboard::Mode mode) const +{ + Q_UNUSED(mode); + return false; +} + +void QWasmClipboard::qWasmClipboardPaste(QMimeData *mData) +{ + QWasmIntegration::get()->clipboard()->setMimeData(mData, QClipboard::Clipboard); + + QWindowSystemInterface::handleKeyEvent<QWindowSystemInterface::SynchronousDelivery>( + 0, QEvent::KeyPress, Qt::Key_V, Qt::ControlModifier, "V"); +} + +void QWasmClipboard::initClipboardEvents() +{ + val navigator = val::global("navigator"); + val permissions = navigator["permissions"]; + val clipboard = navigator["clipboard"]; + + hasClipboardApi = (!clipboard.isUndefined()); + if (hasClipboardApi) { + val readPermissionsMap = val::object(); + readPermissionsMap.set("name", val("clipboard-read")); + permissions.call<val>("query", readPermissionsMap); + + val writePermissionsMap = val::object(); + writePermissionsMap.set("name", val("clipboard-write")); + permissions.call<val>("query", writePermissionsMap); + + } else { + + val window = val::global("window"); + window.call<void>("addEventListener", std::string("paste"), + val::module_property("qClipboardPasteTo")); + + window.call<void>("addEventListener", std::string("copy"), + val::module_property("qClipboardCopyTo")); + } +} + +void QWasmClipboard::readTextFromClipboard() +{ + if (QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi) { + val navigator = val::global("navigator"); + val textPromise = navigator["clipboard"].call<val>("readText"); + val readTextResolve = val::global("Module")["qClipboardPromiseResolve"]; + textPromise.call<val>("then", readTextResolve); + } +} + +void QWasmClipboard::writeTextToClipboard() +{ + if (QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi) { + val module = val::global("Module"); + val txt = module.call<val>("getClipboardData"); + val format = module.call<val>("getClipboardFormat"); + val navigator = val::global("navigator"); + navigator["clipboard"].call<void>("writeText", txt.as<std::string>()); + } +} diff --git a/src/plugins/platforms/wasm/qwasmclipboard.h b/src/plugins/platforms/wasm/qwasmclipboard.h new file mode 100644 index 0000000000..e64b2e5007 --- /dev/null +++ b/src/plugins/platforms/wasm/qwasmclipboard.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWasmClipboard_H +#define QWasmClipboard_H + +#include <QObject> + +#include <qpa/qplatformclipboard.h> +#include <QMimeData> + +#include <emscripten/bind.h> + +class QWasmClipboard : public QObject, public QPlatformClipboard +{ +public: + QWasmClipboard(); + virtual ~QWasmClipboard(); + + // QPlatformClipboard methods. + QMimeData* mimeData(QClipboard::Mode mode = QClipboard::Clipboard) override; + void setMimeData(QMimeData* data, QClipboard::Mode mode = QClipboard::Clipboard) override; + bool supportsMode(QClipboard::Mode mode) const override; + bool ownsMode(QClipboard::Mode mode) const override; + + static void qWasmClipboardPaste(QMimeData *mData); + void initClipboardEvents(); + bool hasClipboardApi; + void readTextFromClipboard(); + void writeTextToClipboard(); +}; + +#endif // QWASMCLIPBOARD_H diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp index ea88ef59a0..df81413d5c 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp @@ -31,6 +31,7 @@ #include "qwasmeventdispatcher.h" #include "qwasmcompositor.h" #include "qwasmintegration.h" +#include "qwasmclipboard.h" #include <QtGui/qevent.h> #include <qpa/qwindowsysteminterface.h> @@ -175,10 +176,26 @@ int QWasmEventTranslator::keyboard_cb(int eventType, const EmscriptenKeyboardEve if (keyType == QEvent::None) return 0; - QString keyText = alphanumeric ? QString(keyEvent->key) : QString(); - bool accepted = QWindowSystemInterface::handleKeyEvent<QWindowSystemInterface::SynchronousDelivery>( - 0, keyType, qtKey, translateKeyboardEventModifier(keyEvent), keyText); + QFlags<Qt::KeyboardModifier> mods = translateKeyboardEventModifier(keyEvent); + bool accepted = false; + + if (keyType == QEvent::KeyPress && + mods.testFlag(Qt::ControlModifier) + && qtKey == Qt::Key_V) { + QWasmIntegration::get()->getWasmClipboard()->readTextFromClipboard(); + } else { + QString keyText = alphanumeric ? QString(keyEvent->key) : QString(); + accepted = QWindowSystemInterface::handleKeyEvent<QWindowSystemInterface::SynchronousDelivery>( + 0, keyType, qtKey, translateKeyboardEventModifier(keyEvent), keyText); + } + + if (keyType == QEvent::KeyPress && + mods.testFlag(Qt::ControlModifier) + && qtKey == Qt::Key_C) { + QWasmIntegration::get()->getWasmClipboard()->writeTextToClipboard(); + } QWasmEventDispatcher::maintainTimers(); + return accepted ? 1 : 0; } diff --git a/src/plugins/platforms/wasm/qwasmintegration.cpp b/src/plugins/platforms/wasm/qwasmintegration.cpp index 7a44c47893..6f96ec69da 100644 --- a/src/plugins/platforms/wasm/qwasmintegration.cpp +++ b/src/plugins/platforms/wasm/qwasmintegration.cpp @@ -33,6 +33,7 @@ #include "qwasmcompositor.h" #include "qwasmopenglcontext.h" #include "qwasmtheme.h" +#include "qwasmclipboard.h" #include "qwasmwindow.h" #ifndef QT_NO_OPENGL @@ -65,17 +66,16 @@ EMSCRIPTEN_BINDINGS(my_module) function("browserBeforeUnload", &browserBeforeUnload); } -static QWasmIntegration *globalHtml5Integration; -QWasmIntegration *QWasmIntegration::get() { return globalHtml5Integration; } +QWasmIntegration *QWasmIntegration::s_instance; QWasmIntegration::QWasmIntegration() : m_fontDb(nullptr), m_compositor(new QWasmCompositor), m_screen(new QWasmScreen(m_compositor)), - m_eventDispatcher(nullptr) + m_eventDispatcher(nullptr), + m_clipboard(new QWasmClipboard) { - - globalHtml5Integration = this; + s_instance = this; updateQScreenAndCanvasRenderSize(); screenAdded(m_screen); @@ -93,6 +93,7 @@ QWasmIntegration::~QWasmIntegration() destroyScreen(m_screen); delete m_fontDb; delete m_eventTranslator; + s_instance = nullptr; } void QWasmIntegration::QWasmBrowserExit() @@ -211,4 +212,11 @@ void QWasmIntegration::updateQScreenAndCanvasRenderSize() QWasmIntegration::get()->m_compositor->redrawWindowContent(); } +QPlatformClipboard* QWasmIntegration::clipboard() const +{ + if (!m_clipboard) + m_clipboard = new QWasmClipboard; + return m_clipboard; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/qwasmintegration.h b/src/plugins/platforms/wasm/qwasmintegration.h index ebc3d9d431..4c5aeb4ebc 100644 --- a/src/plugins/platforms/wasm/qwasmintegration.h +++ b/src/plugins/platforms/wasm/qwasmintegration.h @@ -49,6 +49,7 @@ class QWasmEventDispatcher; class QWasmScreen; class QWasmCompositor; class QWasmBackingStore; +class QWasmClipboard; class QWasmIntegration : public QObject, public QPlatformIntegration { @@ -68,12 +69,14 @@ public: QVariant styleHint(QPlatformIntegration::StyleHint hint) const override; QStringList themeNames() const override; QPlatformTheme *createPlatformTheme(const QString &name) const override; + QPlatformClipboard *clipboard() const override; - static QWasmIntegration *get(); QWasmScreen *screen() { return m_screen; } QWasmCompositor *compositor() { return m_compositor; } QWasmEventTranslator *eventTranslator() { return m_eventTranslator; } + QWasmClipboard *getWasmClipboard() { return m_clipboard; } + static QWasmIntegration *get() { return s_instance; } static void QWasmBrowserExit(); static void updateQScreenAndCanvasRenderSize(); @@ -85,6 +88,9 @@ private: mutable QWasmEventDispatcher *m_eventDispatcher; static int uiEvent_cb(int eventType, const EmscriptenUiEvent *e, void *userData); mutable QHash<QWindow *, QWasmBackingStore *> m_backingStores; + + mutable QWasmClipboard *m_clipboard; + static QWasmIntegration *s_instance; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/wasm.pro b/src/plugins/platforms/wasm/wasm.pro index eaaba53aa2..5aa6dfccf3 100644 --- a/src/plugins/platforms/wasm/wasm.pro +++ b/src/plugins/platforms/wasm/wasm.pro @@ -18,7 +18,8 @@ SOURCES = \ qwasmcompositor.cpp \ qwasmcursor.cpp \ qwasmopenglcontext.cpp \ - qwasmtheme.cpp + qwasmtheme.cpp \ + qwasmclipboard.cpp HEADERS = \ qwasmintegration.h \ @@ -31,7 +32,8 @@ HEADERS = \ qwasmstylepixmaps_p.h \ qwasmcursor.h \ qwasmopenglcontext.h \ - qwasmtheme.h + qwasmtheme.h \ + qwasmclipboard.h wasmfonts.files = \ ../../../3rdparty/wasm/Vera.ttf \ From feb5fdd0cfe63252437b20296ccc2b982a85c6dc Mon Sep 17 00:00:00 2001 From: Joerg Bornemann <joerg.bornemann@qt.io> Date: Tue, 12 Feb 2019 14:14:16 +0100 Subject: [PATCH 1181/1650] Fix OpenGL ES2 build on Linux The feature detection in QOpenGL test project file needed adjustment. This amends commit dd988e20. Change-Id: I7efaaec9fbf564be4033e99a8554dbe51322f494 Fixes: QTBUG-73592 Reviewed-by: Gatis Paeglis <gatis.paeglis@qt.io> --- tests/auto/gui/qopengl/qopengl.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/gui/qopengl/qopengl.pro b/tests/auto/gui/qopengl/qopengl.pro index d744d37280..722c99ee0b 100644 --- a/tests/auto/gui/qopengl/qopengl.pro +++ b/tests/auto/gui/qopengl/qopengl.pro @@ -8,4 +8,4 @@ QT += gui-private core-private testlib SOURCES += tst_qopengl.cpp -linux:qtConfig(xcb):qtConfig(xcb-glx):qtConfig(xcb-xlib):!qtConfig(egl): DEFINES += USE_GLX +linux:qtConfig(xcb):qtConfig(xcb-glx-plugin): DEFINES += USE_GLX From e57fe14a04fa077786bbde90c089b4c494150430 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis <gatis.paeglis@qt.io> Date: Fri, 15 Feb 2019 15:24:00 +0100 Subject: [PATCH 1182/1650] remove obscure comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-73826 Change-Id: I2d15ab726ae3be85220bf96aef673d0037738d97 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> --- src/gui/kernel/qguiapplication.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index e0b94676d5..4b069b4f82 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -2187,8 +2187,6 @@ void QGuiApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::Wh #endif // QT_CONFIG(wheelevent) } -// Remember, Qt convention is: keyboard state is state *before* - void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent *e) { QWindow *window = e->window.data(); From 0c03316ec94361bd1d80b391d77a1dcd52f2a23a Mon Sep 17 00:00:00 2001 From: Joerg Bornemann <joerg.bornemann@qt.io> Date: Thu, 14 Feb 2019 17:03:19 +0100 Subject: [PATCH 1183/1650] Revert "Fix determination of OpenGL include paths on macOS" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 37970d7b3e6fff92dca98db974ada865c1bfd730. That commit broke the build on macOS, because the OpenGL headers aren't resolved anymore at configure time. Change-Id: Iec6ef009c9ea7e28b12eeca6b5eb06918bf49d98 Fixes: QTBUG-73827 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Reviewed-by: Mitch Curtis <mitch.curtis@qt.io> --- mkspecs/common/mac.conf | 2 +- mkspecs/features/mac/sdk.prf | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/mkspecs/common/mac.conf b/mkspecs/common/mac.conf index e000d1026b..b77494ec9b 100644 --- a/mkspecs/common/mac.conf +++ b/mkspecs/common/mac.conf @@ -17,7 +17,7 @@ QMAKE_EXTENSION_SHLIB = dylib QMAKE_EXTENSIONS_AUX_SHLIB = tbd QMAKE_LIBDIR = -# The proper SDK sysroot will be automatically prepended +# sdk.prf will prefix the proper SDK sysroot QMAKE_INCDIR_OPENGL = \ /System/Library/Frameworks/OpenGL.framework/Headers \ /System/Library/Frameworks/AGL.framework/Headers/ diff --git a/mkspecs/features/mac/sdk.prf b/mkspecs/features/mac/sdk.prf index 50a41657d8..8360dd8b38 100644 --- a/mkspecs/features/mac/sdk.prf +++ b/mkspecs/features/mac/sdk.prf @@ -33,6 +33,10 @@ QMAKE_MAC_SDK_PATH = $$xcodeSDKInfo(Path) QMAKE_MAC_SDK_PLATFORM_PATH = $$xcodeSDKInfo(PlatformPath) QMAKE_MAC_SDK_VERSION = $$xcodeSDKInfo(SDKVersion) +sysrootified = +for(val, QMAKE_INCDIR_OPENGL): sysrootified += $${QMAKE_MAC_SDK_PATH}$$val +QMAKE_INCDIR_OPENGL = $$sysrootified + QMAKESPEC_NAME = $$basename(QMAKESPEC) # Resolve SDK version of various tools From 8fe36801930872ef4a57e2ff7d7f935de12a33e9 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann <joerg.bornemann@qt.io> Date: Fri, 1 Feb 2019 15:16:00 +0100 Subject: [PATCH 1184/1650] Add cmdline feature to qmake [ChangeLog][qmake] A new feature "cmdline" was added that implies "CONFIG += console" and "CONFIG -= app_bundle". Task-number: QTBUG-27079 Change-Id: I6e52b07c9341c904bb1424fc717057432f9360e1 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de> --- examples/corelib/serialization/cbordump/cbordump.pro | 3 +-- examples/corelib/serialization/convert/convert.pro | 3 +-- examples/corelib/serialization/savegame/savegame.pro | 3 +-- examples/corelib/threads/semaphores/semaphores.pro | 3 +-- .../corelib/threads/waitconditions/waitconditions.pro | 4 ++-- examples/network/dnslookup/dnslookup.pro | 3 +-- examples/network/download/download.pro | 3 +-- examples/network/downloadmanager/downloadmanager.pro | 3 +-- examples/qmake/precompile/precompile.pro | 3 +-- examples/qtconcurrent/map/map.pro | 3 +-- examples/qtconcurrent/runfunction/runfunction.pro | 3 +-- examples/qtconcurrent/wordcount/wordcount.pro | 3 +-- examples/widgets/statemachine/factorial/factorial.pro | 3 +-- examples/widgets/statemachine/pingpong/pingpong.pro | 3 +-- examples/xml/htmlinfo/htmlinfo.pro | 3 +-- examples/xml/xmlstreamlint/xmlstreamlint.pro | 3 +-- mkspecs/features/cmdline.prf | 2 ++ mkspecs/features/qt_test_helper.prf | 3 +-- qmake/doc/src/qmake-manual.qdoc | 11 +++++++---- qmake/qmake.pro | 4 ++-- src/tools/moc/util/generate_keywords.pro | 2 +- tests/auto/corelib/global/qlogging/app/app.pro | 3 +-- .../qlockfiletesthelper/qlockfile_test_helper.pro | 3 +-- .../qprocess/fileWriterProcess/fileWriterProcess.pro | 3 +-- .../corelib/io/qprocess/testDetached/testDetached.pro | 3 +-- .../io/qprocess/testExitCodes/testExitCodes.pro | 4 ++-- .../io/qprocess/testForwarding/testForwarding.pro | 3 +-- .../testForwardingHelper/testForwardingHelper.pro | 4 ++-- .../io/qprocess/testGuiProcess/testGuiProcess.pro | 3 +-- .../io/qprocess/testProcessCrash/testProcessCrash.pro | 4 ++-- .../testProcessDeadWhileReading.pro | 4 ++-- .../io/qprocess/testProcessEOF/testProcessEOF.pro | 4 ++-- .../io/qprocess/testProcessEcho/testProcessEcho.pro | 4 ++-- .../io/qprocess/testProcessEcho2/testProcessEcho2.pro | 4 ++-- .../io/qprocess/testProcessEcho3/testProcessEcho3.pro | 4 ++-- .../testProcessEnvironment/testProcessEnvironment.pro | 6 +----- .../io/qprocess/testProcessHang/testProcessHang.pro | 4 ++-- .../qprocess/testProcessNormal/testProcessNormal.pro | 4 ++-- .../qprocess/testProcessOutput/testProcessOutput.pro | 4 ++-- .../io/qprocess/testProcessSpacesArgs/nospace.pro | 4 ++-- .../io/qprocess/testProcessSpacesArgs/onespace.pro | 4 ++-- .../io/qprocess/testProcessSpacesArgs/twospaces.pro | 4 ++-- .../testSetNamedPipeHandleState.pro | 4 ++-- .../testSetWorkingDirectory.pro | 3 +-- .../corelib/io/qprocess/testSoftExit/testSoftExit.pro | 4 ++-- .../io/qprocess/testSpaceInName/testSpaceInName.pro | 6 +----- .../readAllStdinProcess/readAllStdinProcess.pro | 3 +-- .../readLineStdinProcess/readLineStdinProcess.pro | 3 +-- .../qtextstream/stdinProcess/stdinProcess.pro | 3 +-- .../thread/qthreadstorage/crashonexit/crashonexit.pro | 3 +-- .../testhelper/qcommandlineparser_test_helper.pro | 3 +-- .../tools/qlocale/syslocaleapp/syslocaleapp.pro | 3 +-- .../corelib/tools/qsharedpointer/externaltests.cpp | 3 +-- .../dbus/qdbusabstractinterface/qpinger/qpinger.pro | 3 +-- tests/auto/dbus/qdbusmarshall/qpong/qpong.pro | 4 +--- tests/auto/network/access/qnetworkreply/echo/echo.pro | 4 ++-- .../network/bearer/qnetworksession/lackey/lackey.pro | 3 +-- .../qlocalsocket/socketprocess/socketprocess.pro | 3 +-- .../socket/qtcpsocket/stressTest/stressTest.pro | 3 +-- .../socket/qudpsocket/clientserver/clientserver.pro | 3 +-- .../network/socket/qudpsocket/udpServer/udpServer.pro | 4 +--- .../write-read-write/write-read-write.pro | 4 ++-- tests/baselineserver/src/baselineserver.pro | 3 +-- .../testProcessLoopback/testProcessLoopback.pro | 4 ++-- .../tools/qcryptographichash/qcryptographichash.pro | 4 ++-- .../embeddedintoforeignwindow.pro | 3 +-- tests/manual/filetest/filetest.pro | 3 +-- tests/manual/foreignwindows/foreignwindows.pro | 3 +-- tests/manual/highdpi/highdpi.pro | 3 +-- tests/manual/lance/lance.pro | 3 +-- tests/manual/qdesktopservices/qdesktopservices.pro | 3 +-- tests/manual/qmimedatabase/qmimedatabase.pro | 3 +-- tests/manual/qstorageinfo/qstorageinfo.pro | 3 +-- tests/manual/qsysinfo/qsysinfo.pro | 3 +-- tests/manual/widgets/styles/styles.pro | 3 +-- util/glgen/glgen.pro | 3 +-- util/gradientgen/tobinaryjson.pro | 3 +-- 77 files changed, 106 insertions(+), 161 deletions(-) create mode 100644 mkspecs/features/cmdline.prf diff --git a/examples/corelib/serialization/cbordump/cbordump.pro b/examples/corelib/serialization/cbordump/cbordump.pro index 7fb2ef69f0..8149cb1d4c 100644 --- a/examples/corelib/serialization/cbordump/cbordump.pro +++ b/examples/corelib/serialization/cbordump/cbordump.pro @@ -2,8 +2,7 @@ QT += core QT -= gui TARGET = cbordump -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline TEMPLATE = app diff --git a/examples/corelib/serialization/convert/convert.pro b/examples/corelib/serialization/convert/convert.pro index d9b1de41e3..4c6b0b557a 100644 --- a/examples/corelib/serialization/convert/convert.pro +++ b/examples/corelib/serialization/convert/convert.pro @@ -2,8 +2,7 @@ QT += core QT -= gui TARGET = convert -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline TEMPLATE = app diff --git a/examples/corelib/serialization/savegame/savegame.pro b/examples/corelib/serialization/savegame/savegame.pro index 15a38c32ef..69e6b216f2 100644 --- a/examples/corelib/serialization/savegame/savegame.pro +++ b/examples/corelib/serialization/savegame/savegame.pro @@ -2,8 +2,7 @@ QT += core QT -= gui TARGET = savegame -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline TEMPLATE = app diff --git a/examples/corelib/threads/semaphores/semaphores.pro b/examples/corelib/threads/semaphores/semaphores.pro index 69154e57eb..de909508c4 100644 --- a/examples/corelib/threads/semaphores/semaphores.pro +++ b/examples/corelib/threads/semaphores/semaphores.pro @@ -1,8 +1,7 @@ SOURCES += semaphores.cpp QT = core -CONFIG -= app_bundle -CONFIG += console +CONFIG += cmdline # install target.path = $$[QT_INSTALL_EXAMPLES]/corelib/threads/semaphores diff --git a/examples/corelib/threads/waitconditions/waitconditions.pro b/examples/corelib/threads/waitconditions/waitconditions.pro index 2dbe7df68a..19b56a246d 100644 --- a/examples/corelib/threads/waitconditions/waitconditions.pro +++ b/examples/corelib/threads/waitconditions/waitconditions.pro @@ -1,6 +1,6 @@ QT = core -CONFIG -= moc app_bundle -CONFIG += console +CONFIG -= moc +CONFIG += cmdline SOURCES += waitconditions.cpp diff --git a/examples/network/dnslookup/dnslookup.pro b/examples/network/dnslookup/dnslookup.pro index 0c6b512d3b..c72301420c 100644 --- a/examples/network/dnslookup/dnslookup.pro +++ b/examples/network/dnslookup/dnslookup.pro @@ -1,7 +1,6 @@ TEMPLATE = app QT = core network -mac:CONFIG -= app_bundle -win32:CONFIG += console +CONFIG += cmdline HEADERS += dnslookup.h SOURCES += dnslookup.cpp diff --git a/examples/network/download/download.pro b/examples/network/download/download.pro index 2c784c4197..63d80a0e7c 100644 --- a/examples/network/download/download.pro +++ b/examples/network/download/download.pro @@ -1,6 +1,5 @@ QT = core network -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline SOURCES += main.cpp diff --git a/examples/network/downloadmanager/downloadmanager.pro b/examples/network/downloadmanager/downloadmanager.pro index 68972610fa..cd1a977e5d 100644 --- a/examples/network/downloadmanager/downloadmanager.pro +++ b/examples/network/downloadmanager/downloadmanager.pro @@ -1,6 +1,5 @@ QT = core network -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline HEADERS += downloadmanager.h textprogressbar.h SOURCES += downloadmanager.cpp main.cpp textprogressbar.cpp diff --git a/examples/qmake/precompile/precompile.pro b/examples/qmake/precompile/precompile.pro index 6a23d82c32..27564cd390 100644 --- a/examples/qmake/precompile/precompile.pro +++ b/examples/qmake/precompile/precompile.pro @@ -6,8 +6,7 @@ #! [0] TEMPLATE = app LANGUAGE = C++ -CONFIG += console precompile_header -CONFIG -= app_bundle +CONFIG += cmdline precompile_header QT += widgets # Use Precompiled headers (PCH) diff --git a/examples/qtconcurrent/map/map.pro b/examples/qtconcurrent/map/map.pro index 166f596909..7f267beb22 100644 --- a/examples/qtconcurrent/map/map.pro +++ b/examples/qtconcurrent/map/map.pro @@ -1,8 +1,7 @@ TEMPLATE = app TARGET = mapdemo QT += concurrent -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline SOURCES += main.cpp diff --git a/examples/qtconcurrent/runfunction/runfunction.pro b/examples/qtconcurrent/runfunction/runfunction.pro index 5624c87df7..42c05551ba 100644 --- a/examples/qtconcurrent/runfunction/runfunction.pro +++ b/examples/qtconcurrent/runfunction/runfunction.pro @@ -1,6 +1,5 @@ QT += concurrent widgets -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline SOURCES += main.cpp diff --git a/examples/qtconcurrent/wordcount/wordcount.pro b/examples/qtconcurrent/wordcount/wordcount.pro index 771efadc4a..18545b1a65 100644 --- a/examples/qtconcurrent/wordcount/wordcount.pro +++ b/examples/qtconcurrent/wordcount/wordcount.pro @@ -1,6 +1,5 @@ QT += concurrent widgets -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline SOURCES += main.cpp diff --git a/examples/widgets/statemachine/factorial/factorial.pro b/examples/widgets/statemachine/factorial/factorial.pro index f200c738ba..bf285acf4d 100644 --- a/examples/widgets/statemachine/factorial/factorial.pro +++ b/examples/widgets/statemachine/factorial/factorial.pro @@ -1,6 +1,5 @@ QT = core -win32: CONFIG += console -mac:CONFIG -= app_bundle +CONFIG += cmdline SOURCES += main.cpp diff --git a/examples/widgets/statemachine/pingpong/pingpong.pro b/examples/widgets/statemachine/pingpong/pingpong.pro index 7cc27a13f5..18dee0400d 100644 --- a/examples/widgets/statemachine/pingpong/pingpong.pro +++ b/examples/widgets/statemachine/pingpong/pingpong.pro @@ -1,6 +1,5 @@ QT = core -win32: CONFIG += console -mac:CONFIG -= app_bundle +CONFIG += cmdline SOURCES = main.cpp diff --git a/examples/xml/htmlinfo/htmlinfo.pro b/examples/xml/htmlinfo/htmlinfo.pro index e106c69b52..8fea3b38dd 100644 --- a/examples/xml/htmlinfo/htmlinfo.pro +++ b/examples/xml/htmlinfo/htmlinfo.pro @@ -1,10 +1,9 @@ SOURCES += main.cpp QT -= gui -CONFIG -= app_bundle RESOURCES = resources.qrc -win32: CONFIG += console +CONFIG += cmdline # install target.path = $$[QT_INSTALL_EXAMPLES]/xml/htmlinfo diff --git a/examples/xml/xmlstreamlint/xmlstreamlint.pro b/examples/xml/xmlstreamlint/xmlstreamlint.pro index cf03c4817a..90a6387afe 100644 --- a/examples/xml/xmlstreamlint/xmlstreamlint.pro +++ b/examples/xml/xmlstreamlint/xmlstreamlint.pro @@ -1,5 +1,4 @@ -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline QT -= gui SOURCES += main.cpp diff --git a/mkspecs/features/cmdline.prf b/mkspecs/features/cmdline.prf new file mode 100644 index 0000000000..f9d90d3a50 --- /dev/null +++ b/mkspecs/features/cmdline.prf @@ -0,0 +1,2 @@ +win32: CONFIG *= console +macos: CONFIG -= app_bundle diff --git a/mkspecs/features/qt_test_helper.prf b/mkspecs/features/qt_test_helper.prf index 5daa14731d..86b65dd884 100644 --- a/mkspecs/features/qt_test_helper.prf +++ b/mkspecs/features/qt_test_helper.prf @@ -16,8 +16,7 @@ # Additionally the helper's executable is suffixed with "_helper" to # avoid name clashes with its folder. -CONFIG -= app_bundle -CONFIG += console +CONFIG += cmdline debug_and_release { CONFIG(debug, debug|release) { diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index fb8bad32a2..84e3fb6df4 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -1060,8 +1060,12 @@ proper include paths, compiler flags and libraries will automatically be added to the project. \row \li console \li The target is a Win32 console application (app only). The - proper include paths, compiler flags and libraries will - automatically be added to the project. + proper include paths, compiler flags and libraries will automatically be + added to the project. Consider using the option \c{cmdline} for + cross-platform applications. + \row \li cmdline \li The target is a cross-platform command line application. + On Windows, this implies \c{CONFIG += console}. + On macOS, this implies \c{CONFIG -= app_bundle}. \row \li shared \li{1,2} The target is a shared object/DLL. The proper include paths, compiler flags and libraries will automatically be added to the project. Note that \c dll can also be used on all platforms; @@ -4887,8 +4891,7 @@ \code TEMPLATE = app LANGUAGE = C++ - CONFIG += console precompile_header - CONFIG -= app_bundle + CONFIG += cmdline precompile_header # Use Precompiled headers (PCH) PRECOMPILED_HEADER = stable.h diff --git a/qmake/qmake.pro b/qmake/qmake.pro index ebd61751b7..5399e8c298 100644 --- a/qmake/qmake.pro +++ b/qmake/qmake.pro @@ -3,8 +3,8 @@ # and the configures. option(host_build) -CONFIG += console -CONFIG -= qt app_bundle +CONFIG += cmdline +CONFIG -= qt DEFINES += \ PROEVALUATOR_FULL \ diff --git a/src/tools/moc/util/generate_keywords.pro b/src/tools/moc/util/generate_keywords.pro index 88e5553f54..2bbc3ced61 100644 --- a/src/tools/moc/util/generate_keywords.pro +++ b/src/tools/moc/util/generate_keywords.pro @@ -1,4 +1,4 @@ CONFIG -= moc -mac:CONFIG -= app_bundle +CONFIG += cmdline SOURCES += generate_keywords.cpp diff --git a/tests/auto/corelib/global/qlogging/app/app.pro b/tests/auto/corelib/global/qlogging/app/app.pro index b90b685749..3ada382ff4 100644 --- a/tests/auto/corelib/global/qlogging/app/app.pro +++ b/tests/auto/corelib/global/qlogging/app/app.pro @@ -14,8 +14,7 @@ QT = core DESTDIR = ./ -CONFIG -= app_bundle -CONFIG += console +CONFIG += cmdline SOURCES += main.cpp DEFINES += QT_MESSAGELOGCONTEXT diff --git a/tests/auto/corelib/io/qlockfile/qlockfiletesthelper/qlockfile_test_helper.pro b/tests/auto/corelib/io/qlockfile/qlockfiletesthelper/qlockfile_test_helper.pro index 3ac3be9c9b..97135d279e 100644 --- a/tests/auto/corelib/io/qlockfile/qlockfiletesthelper/qlockfile_test_helper.pro +++ b/tests/auto/corelib/io/qlockfile/qlockfiletesthelper/qlockfile_test_helper.pro @@ -1,7 +1,6 @@ TARGET = qlockfile_test_helper SOURCES += qlockfile_test_helper.cpp -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline QT = core DESTDIR = ./ diff --git a/tests/auto/corelib/io/qprocess/fileWriterProcess/fileWriterProcess.pro b/tests/auto/corelib/io/qprocess/fileWriterProcess/fileWriterProcess.pro index 947dc916f2..2744491151 100644 --- a/tests/auto/corelib/io/qprocess/fileWriterProcess/fileWriterProcess.pro +++ b/tests/auto/corelib/io/qprocess/fileWriterProcess/fileWriterProcess.pro @@ -1,5 +1,4 @@ SOURCES = main.cpp -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline QT = core DESTDIR = ./ diff --git a/tests/auto/corelib/io/qprocess/testDetached/testDetached.pro b/tests/auto/corelib/io/qprocess/testDetached/testDetached.pro index 8d1fcba624..3d80b668df 100644 --- a/tests/auto/corelib/io/qprocess/testDetached/testDetached.pro +++ b/tests/auto/corelib/io/qprocess/testDetached/testDetached.pro @@ -1,6 +1,5 @@ SOURCES = main.cpp QT = core -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline INSTALLS = DESTDIR = ./ diff --git a/tests/auto/corelib/io/qprocess/testExitCodes/testExitCodes.pro b/tests/auto/corelib/io/qprocess/testExitCodes/testExitCodes.pro index b08371804f..5eaf8dc881 100644 --- a/tests/auto/corelib/io/qprocess/testExitCodes/testExitCodes.pro +++ b/tests/auto/corelib/io/qprocess/testExitCodes/testExitCodes.pro @@ -1,5 +1,5 @@ SOURCES += main.cpp -CONFIG -= qt app_bundle -CONFIG += console +CONFIG -= qt +CONFIG += cmdline DESTDIR = ./ diff --git a/tests/auto/corelib/io/qprocess/testForwarding/testForwarding.pro b/tests/auto/corelib/io/qprocess/testForwarding/testForwarding.pro index 45b498c32a..4d91e0cf36 100644 --- a/tests/auto/corelib/io/qprocess/testForwarding/testForwarding.pro +++ b/tests/auto/corelib/io/qprocess/testForwarding/testForwarding.pro @@ -1,5 +1,4 @@ SOURCES = main.cpp -CONFIG -= app_bundle -CONFIG += console +CONFIG += cmdline DESTDIR = ./ QT = core diff --git a/tests/auto/corelib/io/qprocess/testForwardingHelper/testForwardingHelper.pro b/tests/auto/corelib/io/qprocess/testForwardingHelper/testForwardingHelper.pro index e236e05c7d..6a23e52d95 100644 --- a/tests/auto/corelib/io/qprocess/testForwardingHelper/testForwardingHelper.pro +++ b/tests/auto/corelib/io/qprocess/testForwardingHelper/testForwardingHelper.pro @@ -1,4 +1,4 @@ SOURCES = main.cpp -CONFIG -= qt app_bundle -CONFIG += console +CONFIG -= qt +CONFIG += cmdline DESTDIR = ./ diff --git a/tests/auto/corelib/io/qprocess/testGuiProcess/testGuiProcess.pro b/tests/auto/corelib/io/qprocess/testGuiProcess/testGuiProcess.pro index 8778da7ffe..ef438d6399 100644 --- a/tests/auto/corelib/io/qprocess/testGuiProcess/testGuiProcess.pro +++ b/tests/auto/corelib/io/qprocess/testGuiProcess/testGuiProcess.pro @@ -1,5 +1,4 @@ SOURCES += main.cpp QT += widgets -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline DESTDIR = ./ diff --git a/tests/auto/corelib/io/qprocess/testProcessCrash/testProcessCrash.pro b/tests/auto/corelib/io/qprocess/testProcessCrash/testProcessCrash.pro index 7ccc976efc..640ce4cd09 100644 --- a/tests/auto/corelib/io/qprocess/testProcessCrash/testProcessCrash.pro +++ b/tests/auto/corelib/io/qprocess/testProcessCrash/testProcessCrash.pro @@ -1,5 +1,5 @@ SOURCES = main.cpp -CONFIG += console -CONFIG -= qt app_bundle +CONFIG += cmdline +CONFIG -= qt DESTDIR = ./ diff --git a/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/testProcessDeadWhileReading.pro b/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/testProcessDeadWhileReading.pro index fbb3411d47..c7be60a82d 100644 --- a/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/testProcessDeadWhileReading.pro +++ b/tests/auto/corelib/io/qprocess/testProcessDeadWhileReading/testProcessDeadWhileReading.pro @@ -1,5 +1,5 @@ SOURCES = main.cpp -CONFIG -= qt app_bundle -CONFIG += console +CONFIG -= qt +CONFIG += cmdline DESTDIR = ./ diff --git a/tests/auto/corelib/io/qprocess/testProcessEOF/testProcessEOF.pro b/tests/auto/corelib/io/qprocess/testProcessEOF/testProcessEOF.pro index 98fe78c8b9..ab1394a5c9 100644 --- a/tests/auto/corelib/io/qprocess/testProcessEOF/testProcessEOF.pro +++ b/tests/auto/corelib/io/qprocess/testProcessEOF/testProcessEOF.pro @@ -1,6 +1,6 @@ SOURCES = main.cpp -CONFIG -= qt app_bundle -CONFIG += console +CONFIG -= qt +CONFIG += cmdline win32:!mingw:!equals(TEMPLATE_PREFIX, "vc"):QMAKE_CXXFLAGS += /GS- DESTDIR = ./ diff --git a/tests/auto/corelib/io/qprocess/testProcessEcho/testProcessEcho.pro b/tests/auto/corelib/io/qprocess/testProcessEcho/testProcessEcho.pro index e236e05c7d..6a23e52d95 100644 --- a/tests/auto/corelib/io/qprocess/testProcessEcho/testProcessEcho.pro +++ b/tests/auto/corelib/io/qprocess/testProcessEcho/testProcessEcho.pro @@ -1,4 +1,4 @@ SOURCES = main.cpp -CONFIG -= qt app_bundle -CONFIG += console +CONFIG -= qt +CONFIG += cmdline DESTDIR = ./ diff --git a/tests/auto/corelib/io/qprocess/testProcessEcho2/testProcessEcho2.pro b/tests/auto/corelib/io/qprocess/testProcessEcho2/testProcessEcho2.pro index e236e05c7d..6a23e52d95 100644 --- a/tests/auto/corelib/io/qprocess/testProcessEcho2/testProcessEcho2.pro +++ b/tests/auto/corelib/io/qprocess/testProcessEcho2/testProcessEcho2.pro @@ -1,4 +1,4 @@ SOURCES = main.cpp -CONFIG -= qt app_bundle -CONFIG += console +CONFIG -= qt +CONFIG += cmdline DESTDIR = ./ diff --git a/tests/auto/corelib/io/qprocess/testProcessEcho3/testProcessEcho3.pro b/tests/auto/corelib/io/qprocess/testProcessEcho3/testProcessEcho3.pro index e236e05c7d..6a23e52d95 100644 --- a/tests/auto/corelib/io/qprocess/testProcessEcho3/testProcessEcho3.pro +++ b/tests/auto/corelib/io/qprocess/testProcessEcho3/testProcessEcho3.pro @@ -1,4 +1,4 @@ SOURCES = main.cpp -CONFIG -= qt app_bundle -CONFIG += console +CONFIG -= qt +CONFIG += cmdline DESTDIR = ./ diff --git a/tests/auto/corelib/io/qprocess/testProcessEnvironment/testProcessEnvironment.pro b/tests/auto/corelib/io/qprocess/testProcessEnvironment/testProcessEnvironment.pro index a07ae00605..6a23e52d95 100644 --- a/tests/auto/corelib/io/qprocess/testProcessEnvironment/testProcessEnvironment.pro +++ b/tests/auto/corelib/io/qprocess/testProcessEnvironment/testProcessEnvironment.pro @@ -1,8 +1,4 @@ SOURCES = main.cpp CONFIG -= qt -CONFIG += console +CONFIG += cmdline DESTDIR = ./ - -mac { - CONFIG -= app_bundle -} diff --git a/tests/auto/corelib/io/qprocess/testProcessHang/testProcessHang.pro b/tests/auto/corelib/io/qprocess/testProcessHang/testProcessHang.pro index e236e05c7d..6a23e52d95 100644 --- a/tests/auto/corelib/io/qprocess/testProcessHang/testProcessHang.pro +++ b/tests/auto/corelib/io/qprocess/testProcessHang/testProcessHang.pro @@ -1,4 +1,4 @@ SOURCES = main.cpp -CONFIG -= qt app_bundle -CONFIG += console +CONFIG -= qt +CONFIG += cmdline DESTDIR = ./ diff --git a/tests/auto/corelib/io/qprocess/testProcessNormal/testProcessNormal.pro b/tests/auto/corelib/io/qprocess/testProcessNormal/testProcessNormal.pro index c6db9d1bac..7e1119c117 100644 --- a/tests/auto/corelib/io/qprocess/testProcessNormal/testProcessNormal.pro +++ b/tests/auto/corelib/io/qprocess/testProcessNormal/testProcessNormal.pro @@ -1,6 +1,6 @@ SOURCES = main.cpp -CONFIG += console -CONFIG -= qt app_bundle +CONFIG += cmdline +CONFIG -= qt DESTDIR = ./ QT = core diff --git a/tests/auto/corelib/io/qprocess/testProcessOutput/testProcessOutput.pro b/tests/auto/corelib/io/qprocess/testProcessOutput/testProcessOutput.pro index 95191098bd..0bbb6b3c0e 100644 --- a/tests/auto/corelib/io/qprocess/testProcessOutput/testProcessOutput.pro +++ b/tests/auto/corelib/io/qprocess/testProcessOutput/testProcessOutput.pro @@ -1,5 +1,5 @@ SOURCES = main.cpp -CONFIG -= qt app_bundle -CONFIG += console +CONFIG -= qt +CONFIG += cmdline DESTDIR = ./ QT = core diff --git a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/nospace.pro b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/nospace.pro index dd7e8e4a85..7954a2f74b 100644 --- a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/nospace.pro +++ b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/nospace.pro @@ -1,6 +1,6 @@ SOURCES = main.cpp -CONFIG -= qt app_bundle -CONFIG += console +CONFIG -= qt +CONFIG += cmdline DESTDIR = ./ OBJECTS_DIR = $${OBJECTS_DIR}-nospace DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/onespace.pro b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/onespace.pro index d18a683e1c..44a365c9a5 100644 --- a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/onespace.pro +++ b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/onespace.pro @@ -1,6 +1,6 @@ SOURCES = main.cpp -CONFIG -= qt app_bundle -CONFIG += console +CONFIG -= qt +CONFIG += cmdline DESTDIR = ./ OBJECTS_DIR = $${OBJECTS_DIR}-onespace diff --git a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/twospaces.pro b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/twospaces.pro index 8b16f65e34..bd2db9fb6d 100644 --- a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/twospaces.pro +++ b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/twospaces.pro @@ -1,6 +1,6 @@ SOURCES = main.cpp -CONFIG -= qt app_bundle -CONFIG += console +CONFIG -= qt +CONFIG += cmdline DESTDIR = ./ OBJECTS_DIR = $${OBJECTS_DIR}-twospaces diff --git a/tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/testSetNamedPipeHandleState.pro b/tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/testSetNamedPipeHandleState.pro index e236e05c7d..6a23e52d95 100644 --- a/tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/testSetNamedPipeHandleState.pro +++ b/tests/auto/corelib/io/qprocess/testSetNamedPipeHandleState/testSetNamedPipeHandleState.pro @@ -1,4 +1,4 @@ SOURCES = main.cpp -CONFIG -= qt app_bundle -CONFIG += console +CONFIG -= qt +CONFIG += cmdline DESTDIR = ./ diff --git a/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/testSetWorkingDirectory.pro b/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/testSetWorkingDirectory.pro index 21a115b536..4d91e0cf36 100644 --- a/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/testSetWorkingDirectory.pro +++ b/tests/auto/corelib/io/qprocess/testSetWorkingDirectory/testSetWorkingDirectory.pro @@ -1,5 +1,4 @@ SOURCES = main.cpp -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline DESTDIR = ./ QT = core diff --git a/tests/auto/corelib/io/qprocess/testSoftExit/testSoftExit.pro b/tests/auto/corelib/io/qprocess/testSoftExit/testSoftExit.pro index 80e8bcad98..2cfcb4794e 100644 --- a/tests/auto/corelib/io/qprocess/testSoftExit/testSoftExit.pro +++ b/tests/auto/corelib/io/qprocess/testSoftExit/testSoftExit.pro @@ -6,7 +6,7 @@ unix { SOURCES = main_unix.cpp } -CONFIG -= qt app_bundle -CONFIG += console +CONFIG -= qt +CONFIG += cmdline DESTDIR = ./ QT = core diff --git a/tests/auto/corelib/io/qprocess/testSpaceInName/testSpaceInName.pro b/tests/auto/corelib/io/qprocess/testSpaceInName/testSpaceInName.pro index afa4f32a85..48f28c4c8b 100644 --- a/tests/auto/corelib/io/qprocess/testSpaceInName/testSpaceInName.pro +++ b/tests/auto/corelib/io/qprocess/testSpaceInName/testSpaceInName.pro @@ -1,9 +1,5 @@ SOURCES = main.cpp CONFIG -= qt -CONFIG += console +CONFIG += cmdline DESTDIR = "../test Space In Name" - -mac { - CONFIG -= app_bundle -} QT = core diff --git a/tests/auto/corelib/serialization/qtextstream/readAllStdinProcess/readAllStdinProcess.pro b/tests/auto/corelib/serialization/qtextstream/readAllStdinProcess/readAllStdinProcess.pro index 4a4c091dcb..f2b5aa619f 100644 --- a/tests/auto/corelib/serialization/qtextstream/readAllStdinProcess/readAllStdinProcess.pro +++ b/tests/auto/corelib/serialization/qtextstream/readAllStdinProcess/readAllStdinProcess.pro @@ -1,7 +1,6 @@ SOURCES += main.cpp QT = core -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline DESTDIR = ./ # This app is testdata for tst_qtextstream diff --git a/tests/auto/corelib/serialization/qtextstream/readLineStdinProcess/readLineStdinProcess.pro b/tests/auto/corelib/serialization/qtextstream/readLineStdinProcess/readLineStdinProcess.pro index 4a4c091dcb..f2b5aa619f 100644 --- a/tests/auto/corelib/serialization/qtextstream/readLineStdinProcess/readLineStdinProcess.pro +++ b/tests/auto/corelib/serialization/qtextstream/readLineStdinProcess/readLineStdinProcess.pro @@ -1,7 +1,6 @@ SOURCES += main.cpp QT = core -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline DESTDIR = ./ # This app is testdata for tst_qtextstream diff --git a/tests/auto/corelib/serialization/qtextstream/stdinProcess/stdinProcess.pro b/tests/auto/corelib/serialization/qtextstream/stdinProcess/stdinProcess.pro index 4a4c091dcb..f2b5aa619f 100644 --- a/tests/auto/corelib/serialization/qtextstream/stdinProcess/stdinProcess.pro +++ b/tests/auto/corelib/serialization/qtextstream/stdinProcess/stdinProcess.pro @@ -1,7 +1,6 @@ SOURCES += main.cpp QT = core -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline DESTDIR = ./ # This app is testdata for tst_qtextstream diff --git a/tests/auto/corelib/thread/qthreadstorage/crashonexit/crashonexit.pro b/tests/auto/corelib/thread/qthreadstorage/crashonexit/crashonexit.pro index d5c09ebc84..57bd78bcee 100644 --- a/tests/auto/corelib/thread/qthreadstorage/crashonexit/crashonexit.pro +++ b/tests/auto/corelib/thread/qthreadstorage/crashonexit/crashonexit.pro @@ -9,8 +9,7 @@ debug_and_release { TARGET = ../crashOnExit_helper } QT = core -CONFIG -= app_bundle -CONFIG += console +CONFIG += cmdline # This app is testdata for tst_qthreadstorage target.path = $$[QT_INSTALL_TESTS]/tst_qthreadstorage/$$TARGET diff --git a/tests/auto/corelib/tools/qcommandlineparser/testhelper/qcommandlineparser_test_helper.pro b/tests/auto/corelib/tools/qcommandlineparser/testhelper/qcommandlineparser_test_helper.pro index dce1ac0d37..5020658835 100644 --- a/tests/auto/corelib/tools/qcommandlineparser/testhelper/qcommandlineparser_test_helper.pro +++ b/tests/auto/corelib/tools/qcommandlineparser/testhelper/qcommandlineparser_test_helper.pro @@ -1,5 +1,4 @@ -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline QT = core DESTDIR = ./ diff --git a/tests/auto/corelib/tools/qlocale/syslocaleapp/syslocaleapp.pro b/tests/auto/corelib/tools/qlocale/syslocaleapp/syslocaleapp.pro index b61f51d53a..3e283c05a4 100644 --- a/tests/auto/corelib/tools/qlocale/syslocaleapp/syslocaleapp.pro +++ b/tests/auto/corelib/tools/qlocale/syslocaleapp/syslocaleapp.pro @@ -1,8 +1,7 @@ SOURCES += syslocaleapp.cpp DESTDIR = ./ -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline QT = core diff --git a/tests/auto/corelib/tools/qsharedpointer/externaltests.cpp b/tests/auto/corelib/tools/qsharedpointer/externaltests.cpp index 4dc620e6ab..d1bb89f549 100644 --- a/tests/auto/corelib/tools/qsharedpointer/externaltests.cpp +++ b/tests/auto/corelib/tools/qsharedpointer/externaltests.cpp @@ -470,9 +470,8 @@ namespace QTest { "TEMPLATE = app\n" "\n" "TARGET = externaltest\n" - "CONFIG -= app_bundle\n" // for the Mac "CONFIG -= debug_and_release\n" - "CONFIG += console\n" + "CONFIG += cmdline\n" "DESTDIR = .\n" "OBJECTS_DIR = .\n" "UI_DIR = .\n" diff --git a/tests/auto/dbus/qdbusabstractinterface/qpinger/qpinger.pro b/tests/auto/dbus/qdbusabstractinterface/qpinger/qpinger.pro index 206522b557..a876cbfa33 100644 --- a/tests/auto/dbus/qdbusabstractinterface/qpinger/qpinger.pro +++ b/tests/auto/dbus/qdbusabstractinterface/qpinger/qpinger.pro @@ -2,6 +2,5 @@ SOURCES = qpinger.cpp ../interface.cpp HEADERS = ../interface.h TARGET = qpinger DESTDIR = ./ -CONFIG -= app_bundle -CONFIG += console +CONFIG += cmdline QT = core dbus diff --git a/tests/auto/dbus/qdbusmarshall/qpong/qpong.pro b/tests/auto/dbus/qdbusmarshall/qpong/qpong.pro index 57f8b2a598..97a5e7e19d 100644 --- a/tests/auto/dbus/qdbusmarshall/qpong/qpong.pro +++ b/tests/auto/dbus/qdbusmarshall/qpong/qpong.pro @@ -2,6 +2,4 @@ SOURCES = qpong.cpp TARGET = qpong DESTDIR = ./ QT = core dbus -CONFIG -= app_bundle -CONFIG += console - +CONFIG += cmdline diff --git a/tests/auto/network/access/qnetworkreply/echo/echo.pro b/tests/auto/network/access/qnetworkreply/echo/echo.pro index 1f05fd9a54..3e304f4105 100644 --- a/tests/auto/network/access/qnetworkreply/echo/echo.pro +++ b/tests/auto/network/access/qnetworkreply/echo/echo.pro @@ -1,4 +1,4 @@ SOURCES += main.cpp QT = core -CONFIG -= app_bundle debug_and_release_target -CONFIG += console +CONFIG -= debug_and_release_target +CONFIG += cmdline diff --git a/tests/auto/network/bearer/qnetworksession/lackey/lackey.pro b/tests/auto/network/bearer/qnetworksession/lackey/lackey.pro index 1605b31d94..dd83d905e6 100644 --- a/tests/auto/network/bearer/qnetworksession/lackey/lackey.pro +++ b/tests/auto/network/bearer/qnetworksession/lackey/lackey.pro @@ -5,5 +5,4 @@ QT = core network DESTDIR = ./ -win32:CONFIG += console -mac:CONFIG -= app_bundle +CONFIG += cmdline diff --git a/tests/auto/network/socket/qlocalsocket/socketprocess/socketprocess.pro b/tests/auto/network/socket/qlocalsocket/socketprocess/socketprocess.pro index 643c4c5733..e11ed5644b 100644 --- a/tests/auto/network/socket/qlocalsocket/socketprocess/socketprocess.pro +++ b/tests/auto/network/socket/qlocalsocket/socketprocess/socketprocess.pro @@ -3,7 +3,6 @@ QT = core network testlib DESTDIR = ./ TARGET = socketprocess -win32:CONFIG += console -mac:CONFIG -= app_bundle +CONFIG += cmdline SOURCES += main.cpp diff --git a/tests/auto/network/socket/qtcpsocket/stressTest/stressTest.pro b/tests/auto/network/socket/qtcpsocket/stressTest/stressTest.pro index 2eb00593e0..6afc008e7d 100644 --- a/tests/auto/network/socket/qtcpsocket/stressTest/stressTest.pro +++ b/tests/auto/network/socket/qtcpsocket/stressTest/stressTest.pro @@ -2,8 +2,7 @@ HEADERS += Test.h SOURCES += main.cpp Test.cpp QT = core network testlib -CONFIG -= app_bundle -CONFIG += console +CONFIG += cmdline DESTDIR = ./ MOC_DIR = .moc/ TMP_DIR = .tmp/ diff --git a/tests/auto/network/socket/qudpsocket/clientserver/clientserver.pro b/tests/auto/network/socket/qudpsocket/clientserver/clientserver.pro index a1b0021232..83a31b11e9 100644 --- a/tests/auto/network/socket/qudpsocket/clientserver/clientserver.pro +++ b/tests/auto/network/socket/qudpsocket/clientserver/clientserver.pro @@ -1,6 +1,5 @@ QT = core network SOURCES += main.cpp -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline TARGET = clientserver DESTDIR = ./ diff --git a/tests/auto/network/socket/qudpsocket/udpServer/udpServer.pro b/tests/auto/network/socket/qudpsocket/udpServer/udpServer.pro index cf707aa14a..c8f9ebf648 100644 --- a/tests/auto/network/socket/qudpsocket/udpServer/udpServer.pro +++ b/tests/auto/network/socket/qudpsocket/udpServer/udpServer.pro @@ -1,5 +1,3 @@ SOURCES += main.cpp QT = core network -CONFIG -= app_bundle -CONFIG += console - +CONFIG += cmdline diff --git a/tests/auto/other/qprocess_and_guieventloop/write-read-write/write-read-write.pro b/tests/auto/other/qprocess_and_guieventloop/write-read-write/write-read-write.pro index e236e05c7d..6a23e52d95 100644 --- a/tests/auto/other/qprocess_and_guieventloop/write-read-write/write-read-write.pro +++ b/tests/auto/other/qprocess_and_guieventloop/write-read-write/write-read-write.pro @@ -1,4 +1,4 @@ SOURCES = main.cpp -CONFIG -= qt app_bundle -CONFIG += console +CONFIG -= qt +CONFIG += cmdline DESTDIR = ./ diff --git a/tests/baselineserver/src/baselineserver.pro b/tests/baselineserver/src/baselineserver.pro index a77014c1e6..2d8438cb51 100644 --- a/tests/baselineserver/src/baselineserver.pro +++ b/tests/baselineserver/src/baselineserver.pro @@ -5,8 +5,7 @@ QT += core network TARGET = baselineserver DESTDIR = ../bin -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline TEMPLATE = app diff --git a/tests/benchmarks/corelib/io/qprocess/testProcessLoopback/testProcessLoopback.pro b/tests/benchmarks/corelib/io/qprocess/testProcessLoopback/testProcessLoopback.pro index cb8dfdcdcb..a0230e1cb8 100644 --- a/tests/benchmarks/corelib/io/qprocess/testProcessLoopback/testProcessLoopback.pro +++ b/tests/benchmarks/corelib/io/qprocess/testProcessLoopback/testProcessLoopback.pro @@ -1,5 +1,5 @@ SOURCES = main.cpp -CONFIG -= qt app_bundle -CONFIG += console +CONFIG -= qt +CONFIG += cmdline winrt: QMAKE_LFLAGS += /ENTRY:mainCRTStartup DESTDIR = ./ diff --git a/tests/benchmarks/corelib/tools/qcryptographichash/qcryptographichash.pro b/tests/benchmarks/corelib/tools/qcryptographichash/qcryptographichash.pro index 9c55de8b47..cf9d640f7e 100644 --- a/tests/benchmarks/corelib/tools/qcryptographichash/qcryptographichash.pro +++ b/tests/benchmarks/corelib/tools/qcryptographichash/qcryptographichash.pro @@ -1,5 +1,5 @@ TARGET = tst_bench_qcryptographichash -CONFIG -= debug app_bundle -CONFIG += release console +CONFIG -= debug +CONFIG += release cmdline QT = core testlib SOURCES += main.cpp diff --git a/tests/manual/embeddedintoforeignwindow/embeddedintoforeignwindow.pro b/tests/manual/embeddedintoforeignwindow/embeddedintoforeignwindow.pro index 93da4b8c91..dba33a139e 100644 --- a/tests/manual/embeddedintoforeignwindow/embeddedintoforeignwindow.pro +++ b/tests/manual/embeddedintoforeignwindow/embeddedintoforeignwindow.pro @@ -1,7 +1,6 @@ TEMPLATE = app QT += gui-private -CONFIG += console c++11 -CONFIG -= app_bundle +CONFIG += cmdline c++11 SOURCES += main.cpp itemwindow.cpp HEADERS += itemwindow.h include(../diaglib/diaglib.pri) diff --git a/tests/manual/filetest/filetest.pro b/tests/manual/filetest/filetest.pro index 5d2ba9b82b..b91689e0ff 100644 --- a/tests/manual/filetest/filetest.pro +++ b/tests/manual/filetest/filetest.pro @@ -1,6 +1,5 @@ TEMPLATE = app QT = core -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline SOURCES += main.cpp diff --git a/tests/manual/foreignwindows/foreignwindows.pro b/tests/manual/foreignwindows/foreignwindows.pro index 6a370a6813..15bf2395f8 100644 --- a/tests/manual/foreignwindows/foreignwindows.pro +++ b/tests/manual/foreignwindows/foreignwindows.pro @@ -1,6 +1,5 @@ TEMPLATE = app QT += widgets -CONFIG += console c++11 -CONFIG -= app_bundle +CONFIG += cmdline c++11 SOURCES += main.cpp include(../diaglib/diaglib.pri) diff --git a/tests/manual/highdpi/highdpi.pro b/tests/manual/highdpi/highdpi.pro index 7d6b42535e..9db083cd82 100644 --- a/tests/manual/highdpi/highdpi.pro +++ b/tests/manual/highdpi/highdpi.pro @@ -2,8 +2,7 @@ TEMPLATE = app TARGET = highdpi INCLUDEPATH += . QT += widgets gui-private -CONFIG +=console -CONFIG -= app_bundle +CONFIG += cmdline CONFIG += c++11 # Input SOURCES += \ diff --git a/tests/manual/lance/lance.pro b/tests/manual/lance/lance.pro index 312106c2f0..78ca2f56e5 100644 --- a/tests/manual/lance/lance.pro +++ b/tests/manual/lance/lance.pro @@ -1,6 +1,5 @@ LANCELOT_DIR = $$PWD/../../auto/other/lancelot -CONFIG+=console moc -CONFIG -= app_bundle +CONFIG += cmdline moc TEMPLATE = app INCLUDEPATH += . $$LANCELOT_DIR QT += core-private gui-private widgets printsupport diff --git a/tests/manual/qdesktopservices/qdesktopservices.pro b/tests/manual/qdesktopservices/qdesktopservices.pro index c96287e159..baa3c325ff 100644 --- a/tests/manual/qdesktopservices/qdesktopservices.pro +++ b/tests/manual/qdesktopservices/qdesktopservices.pro @@ -1,8 +1,7 @@ QT += testlib TARGET = tst_qdesktopservices -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline TEMPLATE = app diff --git a/tests/manual/qmimedatabase/qmimedatabase.pro b/tests/manual/qmimedatabase/qmimedatabase.pro index 5473330edf..fd931d5eec 100644 --- a/tests/manual/qmimedatabase/qmimedatabase.pro +++ b/tests/manual/qmimedatabase/qmimedatabase.pro @@ -1,5 +1,4 @@ TEMPLATE = app QT = core -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline SOURCES += main.cpp diff --git a/tests/manual/qstorageinfo/qstorageinfo.pro b/tests/manual/qstorageinfo/qstorageinfo.pro index 25acd24c80..e47ecc5b3e 100644 --- a/tests/manual/qstorageinfo/qstorageinfo.pro +++ b/tests/manual/qstorageinfo/qstorageinfo.pro @@ -1,4 +1,3 @@ QT = core -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline SOURCES += main.cpp diff --git a/tests/manual/qsysinfo/qsysinfo.pro b/tests/manual/qsysinfo/qsysinfo.pro index c73d8282cb..ff0a09d42e 100644 --- a/tests/manual/qsysinfo/qsysinfo.pro +++ b/tests/manual/qsysinfo/qsysinfo.pro @@ -1,7 +1,6 @@ QT = core TARGET = qsysinfo TEMPLATE = app -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline SOURCES += main.cpp diff --git a/tests/manual/widgets/styles/styles.pro b/tests/manual/widgets/styles/styles.pro index ef8217a9a3..d302ae0691 100644 --- a/tests/manual/widgets/styles/styles.pro +++ b/tests/manual/widgets/styles/styles.pro @@ -1,7 +1,6 @@ TEMPLATE = app QT = widgets -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline CONFIG += c++11 SOURCES += main.cpp diff --git a/util/glgen/glgen.pro b/util/glgen/glgen.pro index 11018e942d..22c377e5f1 100644 --- a/util/glgen/glgen.pro +++ b/util/glgen/glgen.pro @@ -1,6 +1,5 @@ QT -= gui -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline # Uncomment following to enable debug output #DEFINES += SPECPARSER_DEBUG diff --git a/util/gradientgen/tobinaryjson.pro b/util/gradientgen/tobinaryjson.pro index 8ed3509278..8aa9d0d008 100644 --- a/util/gradientgen/tobinaryjson.pro +++ b/util/gradientgen/tobinaryjson.pro @@ -1,4 +1,3 @@ SOURCES += tobinaryjson.cpp QT = core -CONFIG += console -CONFIG -= app_bundle +CONFIG += cmdline From 1366c4f04645d74e83847687adcf61ecfa20b3d2 Mon Sep 17 00:00:00 2001 From: Christian Kandeler <christian.kandeler@qt.io> Date: Mon, 18 Feb 2019 10:44:21 +0100 Subject: [PATCH 1185/1650] androiddeployqt: Do not check for stdcpp-path in auxiliary mode Fixes: QBS-1429 Change-Id: I189bc42fdee5e63f55705084247fbfc4448a6b65 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> --- src/tools/androiddeployqt/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp index 712a8091fb..6f08238bcc 100644 --- a/src/tools/androiddeployqt/main.cpp +++ b/src/tools/androiddeployqt/main.cpp @@ -891,7 +891,7 @@ bool readInputFile(Options *options) options->extraPlugins = extraPlugins.toString().split(QLatin1Char(',')); } - { + if (!options->auxMode) { const QJsonValue stdcppPath = jsonObject.value(QStringLiteral("stdcpp-path")); if (stdcppPath.isUndefined()) { fprintf(stderr, "No stdcpp-path defined in json file.\n"); From 93a78799c3df7c8859b2d9addad45bb4a535dc97 Mon Sep 17 00:00:00 2001 From: Yuhang Zhao <2546789017@qq.com> Date: Wed, 13 Feb 2019 23:26:55 +0800 Subject: [PATCH 1186/1650] Fix compilation with icc, converting between egl's and gl's Error types Each has two constructors from the other, one copying the other moving; and this leads to an ambiguous overload when converting Texture::onDestroy()'s gl::error to the egl::Error that gl::Context::onDestroy() returns. Passing the value through a temporary prevents the move-constructor from being attempted and saves the day. Thanks to Ville Voutilainen for suggesting the fix. Fixes: QTBUG-73698 Change-Id: I628173399a73cee2e253201bc3e8d3e6477a2fbf Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> --- src/3rdparty/angle/src/libANGLE/Context.cpp | 3 +- src/3rdparty/angle/src/libANGLE/Stream.cpp | 8 +- src/3rdparty/angle/src/libANGLE/Texture.cpp | 3 +- .../libANGLE/renderer/d3d/d3d9/Renderer9.cpp | 3 +- ...with-icc-converting-between-egl-s-an.patch | 93 +++++++++++++++++++ 5 files changed, 104 insertions(+), 6 deletions(-) create mode 100644 src/angle/patches/0013-Fix-compilation-with-icc-converting-between-egl-s-an.patch diff --git a/src/3rdparty/angle/src/libANGLE/Context.cpp b/src/3rdparty/angle/src/libANGLE/Context.cpp index f638beda58..84f7936feb 100644 --- a/src/3rdparty/angle/src/libANGLE/Context.cpp +++ b/src/3rdparty/angle/src/libANGLE/Context.cpp @@ -451,7 +451,8 @@ egl::Error Context::onDestroy(const egl::Display *display) for (auto &zeroTexture : mZeroTextures) { - ANGLE_TRY(zeroTexture.second->onDestroy(this)); + auto result = zeroTexture.second->onDestroy(this); + ANGLE_TRY(egl::Error(result)); zeroTexture.second.set(this, nullptr); } mZeroTextures.clear(); diff --git a/src/3rdparty/angle/src/libANGLE/Stream.cpp b/src/3rdparty/angle/src/libANGLE/Stream.cpp index 68279976b7..e384c7d486 100644 --- a/src/3rdparty/angle/src/libANGLE/Stream.cpp +++ b/src/3rdparty/angle/src/libANGLE/Stream.cpp @@ -192,8 +192,9 @@ Error Stream::consumerAcquire(const gl::Context *context) { if (mPlanes[i].texture != nullptr) { - ANGLE_TRY(mPlanes[i].texture->acquireImageFromStream( - context, mProducerImplementation->getGLFrameDescription(i))); + auto result = mPlanes[i].texture->acquireImageFromStream( + context, mProducerImplementation->getGLFrameDescription(i)); + ANGLE_TRY(Error(result)); } } @@ -213,7 +214,8 @@ Error Stream::consumerRelease(const gl::Context *context) { if (mPlanes[i].texture != nullptr) { - ANGLE_TRY(mPlanes[i].texture->releaseImageFromStream(context)); + auto result = mPlanes[i].texture->releaseImageFromStream(context); + ANGLE_TRY(Error(result)); } } diff --git a/src/3rdparty/angle/src/libANGLE/Texture.cpp b/src/3rdparty/angle/src/libANGLE/Texture.cpp index da92e65916..7447604fe6 100644 --- a/src/3rdparty/angle/src/libANGLE/Texture.cpp +++ b/src/3rdparty/angle/src/libANGLE/Texture.cpp @@ -550,7 +550,8 @@ Error Texture::onDestroy(const Context *context) { if (mBoundSurface) { - ANGLE_TRY(mBoundSurface->releaseTexImage(context, EGL_BACK_BUFFER)); + auto result = mBoundSurface->releaseTexImage(context, EGL_BACK_BUFFER); + ANGLE_TRY(Error(result)); mBoundSurface = nullptr; } if (mBoundStream) diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp index 75c6298868..b583273641 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp @@ -376,7 +376,8 @@ egl::Error Renderer9::initializeDevice() ASSERT(!mBlit); mBlit = new Blit9(this); - ANGLE_TRY(mBlit->initialize()); + auto result = mBlit->initialize(); + ANGLE_TRY(egl::Error(result)); ASSERT(!mVertexDataManager && !mIndexDataManager); mVertexDataManager = new VertexDataManager(this); diff --git a/src/angle/patches/0013-Fix-compilation-with-icc-converting-between-egl-s-an.patch b/src/angle/patches/0013-Fix-compilation-with-icc-converting-between-egl-s-an.patch new file mode 100644 index 0000000000..6d3b1cac08 --- /dev/null +++ b/src/angle/patches/0013-Fix-compilation-with-icc-converting-between-egl-s-an.patch @@ -0,0 +1,93 @@ +From 2d8118620d4871f74a3ddca233529ff540384477 Mon Sep 17 00:00:00 2001 +From: Yuhang Zhao <2546789017@qq.com> +Date: Wed, 13 Feb 2019 23:26:55 +0800 +Subject: [PATCH] Fix compilation with icc, converting between egl's and gl's + Error types + +Each has two constructors from the other, one copying the other +moving; and this leads to an ambiguous overload when converting +Texture::onDestroy()'s gl::error to the egl::Error that +gl::Context::onDestroy() returns. Passing the value through a +temporary prevents the move-constructor from being attempted and saves +the day. Thanks to Ville Voutilainen for suggesting the fix. + +Fixes: QTBUG-73698 +Change-Id: I628173399a73cee2e253201bc3e8d3e6477a2fbf +--- + src/3rdparty/angle/src/libANGLE/Context.cpp | 3 ++- + src/3rdparty/angle/src/libANGLE/Stream.cpp | 8 +++++--- + src/3rdparty/angle/src/libANGLE/Texture.cpp | 3 ++- + .../angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp | 3 ++- + 4 files changed, 11 insertions(+), 6 deletions(-) + +diff --git a/src/3rdparty/angle/src/libANGLE/Context.cpp b/src/3rdparty/angle/src/libANGLE/Context.cpp +index f638beda58..84f7936feb 100644 +--- a/src/3rdparty/angle/src/libANGLE/Context.cpp ++++ b/src/3rdparty/angle/src/libANGLE/Context.cpp +@@ -451,7 +451,8 @@ egl::Error Context::onDestroy(const egl::Display *display) + + for (auto &zeroTexture : mZeroTextures) + { +- ANGLE_TRY(zeroTexture.second->onDestroy(this)); ++ auto result = zeroTexture.second->onDestroy(this); ++ ANGLE_TRY(egl::Error(result)); + zeroTexture.second.set(this, nullptr); + } + mZeroTextures.clear(); +diff --git a/src/3rdparty/angle/src/libANGLE/Stream.cpp b/src/3rdparty/angle/src/libANGLE/Stream.cpp +index 68279976b7..e384c7d486 100644 +--- a/src/3rdparty/angle/src/libANGLE/Stream.cpp ++++ b/src/3rdparty/angle/src/libANGLE/Stream.cpp +@@ -192,8 +192,9 @@ Error Stream::consumerAcquire(const gl::Context *context) + { + if (mPlanes[i].texture != nullptr) + { +- ANGLE_TRY(mPlanes[i].texture->acquireImageFromStream( +- context, mProducerImplementation->getGLFrameDescription(i))); ++ auto result = mPlanes[i].texture->acquireImageFromStream( ++ context, mProducerImplementation->getGLFrameDescription(i)); ++ ANGLE_TRY(Error(result)); + } + } + +@@ -213,7 +214,8 @@ Error Stream::consumerRelease(const gl::Context *context) + { + if (mPlanes[i].texture != nullptr) + { +- ANGLE_TRY(mPlanes[i].texture->releaseImageFromStream(context)); ++ auto result = mPlanes[i].texture->releaseImageFromStream(context); ++ ANGLE_TRY(Error(result)); + } + } + +diff --git a/src/3rdparty/angle/src/libANGLE/Texture.cpp b/src/3rdparty/angle/src/libANGLE/Texture.cpp +index da92e65916..7447604fe6 100644 +--- a/src/3rdparty/angle/src/libANGLE/Texture.cpp ++++ b/src/3rdparty/angle/src/libANGLE/Texture.cpp +@@ -550,7 +550,8 @@ Error Texture::onDestroy(const Context *context) + { + if (mBoundSurface) + { +- ANGLE_TRY(mBoundSurface->releaseTexImage(context, EGL_BACK_BUFFER)); ++ auto result = mBoundSurface->releaseTexImage(context, EGL_BACK_BUFFER); ++ ANGLE_TRY(Error(result)); + mBoundSurface = nullptr; + } + if (mBoundStream) +diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp +index 75c6298868..b583273641 100644 +--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp ++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp +@@ -376,7 +376,8 @@ egl::Error Renderer9::initializeDevice() + + ASSERT(!mBlit); + mBlit = new Blit9(this); +- ANGLE_TRY(mBlit->initialize()); ++ auto result = mBlit->initialize(); ++ ANGLE_TRY(egl::Error(result)); + + ASSERT(!mVertexDataManager && !mIndexDataManager); + mVertexDataManager = new VertexDataManager(this); +-- +2.20.1.windows.1 + From 94a4f06fb88ec6c7fa5e31dfd28af4e9b3cdbdd8 Mon Sep 17 00:00:00 2001 From: Michal Klocek <michal.klocek@qt.io> Date: Fri, 8 Feb 2019 15:31:15 +0100 Subject: [PATCH 1187/1650] Add run-time qpa offscreen glx support selection Introduce QT_QPA_OFFSCREEN_NO_GLX to run offscreen qpa without glx even if compiled with x11 support. Task-number: QTBUG-63346 Change-Id: I647bf5df27f095c3dd27a90415cc9c445df93fd1 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io> --- src/plugins/platforms/offscreen/offscreen.pro | 3 -- .../offscreen/qoffscreenintegration.cpp | 14 ++++++ .../offscreen/qoffscreenintegration_dummy.cpp | 45 ------------------- .../offscreen/qoffscreenintegration_x11.cpp | 5 --- 4 files changed, 14 insertions(+), 53 deletions(-) delete mode 100644 src/plugins/platforms/offscreen/qoffscreenintegration_dummy.cpp diff --git a/src/plugins/platforms/offscreen/offscreen.pro b/src/plugins/platforms/offscreen/offscreen.pro index 392ee8bed1..a8f230a7b1 100644 --- a/src/plugins/platforms/offscreen/offscreen.pro +++ b/src/plugins/platforms/offscreen/offscreen.pro @@ -21,9 +21,6 @@ qtConfig(system-xcb):qtConfig(xlib):qtConfig(opengl):!qtConfig(opengles2) { SOURCES += qoffscreenintegration_x11.cpp HEADERS += qoffscreenintegration_x11.h QT += glx_support-private - system(echo "Using X11 offscreen integration with GLX") -} else { - SOURCES += qoffscreenintegration_dummy.cpp } PLUGIN_TYPE = platforms diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp index 9815be16a3..efd8fdf3fa 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp +++ b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp @@ -66,6 +66,10 @@ #include <qpa/qplatformservices.h> +#if QT_CONFIG(system_xcb) && QT_CONFIG(xlib) && QT_CONFIG(opengl) && !QT_CONFIG(opengles2) +#include "qoffscreenintegration_x11.h" +#endif + QT_BEGIN_NAMESPACE class QCoreTextFontEngine; @@ -219,4 +223,14 @@ QPlatformServices *QOffscreenIntegration::services() const return m_services.data(); } +QOffscreenIntegration *QOffscreenIntegration::createOffscreenIntegration() +{ +#if QT_CONFIG(system_xcb) && QT_CONFIG(xlib) && QT_CONFIG(opengl) && !QT_CONFIG(opengles2) + QByteArray glx = qgetenv("QT_QPA_OFFSCREEN_NO_GLX"); + if (glx.isEmpty()) + return new QOffscreenX11Integration; +#endif + return new QOffscreenIntegration; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration_dummy.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration_dummy.cpp deleted file mode 100644 index 78b289ea49..0000000000 --- a/src/plugins/platforms/offscreen/qoffscreenintegration_dummy.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qoffscreenintegration.h" - -QOffscreenIntegration *QOffscreenIntegration::createOffscreenIntegration() -{ - return new QOffscreenIntegration; -} diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp index 2532cedc70..92fc8aa57a 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp +++ b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp @@ -77,11 +77,6 @@ private: QOffscreenX11Connection *m_connection; }; -QOffscreenIntegration *QOffscreenIntegration::createOffscreenIntegration() -{ - return new QOffscreenX11Integration; -} - bool QOffscreenX11Integration::hasCapability(QPlatformIntegration::Capability cap) const { switch (cap) { From 28a87f1f213a84781ef6a4ddfdd3ef1362d03743 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov <timur.pocheptsov@qt.io> Date: Mon, 11 Feb 2019 16:07:04 +0100 Subject: [PATCH 1188/1650] OCSP response - fix API as proposed in the API review. Change-Id: I607a38d24d533da59fc0d33dac886fa7693ed6c8 Fixes: QTBUG-73739 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> --- src/network/ssl/qocspresponse.cpp | 109 +++++++++++++++++-------- src/network/ssl/qocspresponse.h | 29 +++++-- src/network/ssl/qocspresponse_p.h | 17 +++- src/network/ssl/qsslsocket.h | 2 +- src/network/ssl/qsslsocket_openssl.cpp | 28 +++---- 5 files changed, 125 insertions(+), 60 deletions(-) diff --git a/src/network/ssl/qocspresponse.cpp b/src/network/ssl/qocspresponse.cpp index 1466364af2..496979913b 100644 --- a/src/network/ssl/qocspresponse.cpp +++ b/src/network/ssl/qocspresponse.cpp @@ -40,6 +40,8 @@ #include "qocspresponse_p.h" #include "qocspresponse.h" +#include "qhashfunctions.h" + QT_BEGIN_NAMESPACE /*! @@ -56,13 +58,13 @@ QT_BEGIN_NAMESPACE configured with OCSP stapling enabled. \sa QSslSocket, QSslSocket::ocspResponse(), certificateStatus(), - revocationReason(), responder(), subject(), OcspCertificateStatus, OcspRevocationReason, + revocationReason(), responder(), subject(), QOcspCertificateStatus, QOcspRevocationReason, QSslConfiguration::setOcspStaplingEnabled(), QSslConfiguration::ocspStaplingEnabled(), QSslConfiguration::peerCertificate() */ /*! - \enum OcspCertificateStatus + \enum QOcspCertificateStatus \brief Describes the Online Certificate Status \relates QOcspResponse \since 5.13 @@ -79,11 +81,11 @@ QT_BEGIN_NAMESPACE \value Unknown This state indicates that the responder doesn't know about the certificate being requested. - \sa OcspRevocationReason + \sa QOcspRevocationReason */ /*! - \enum OcspRevocationReason + \enum QOcspRevocationReason \brief Describes the reason for revocation \relates QOcspResponse \since 5.13 @@ -109,10 +111,10 @@ QT_BEGIN_NAMESPACE /*! \since 5.13 - Creates a new response with status OcspCertificateStatus::Unknown - and revocation reason OcspRevocationReason::None. + Creates a new response with status QOcspCertificateStatus::Unknown + and revocation reason QOcspRevocationReason::None. - \sa OcspCertificateStatus + \sa QOcspCertificateStatus */ QOcspResponse::QOcspResponse() : d(new QOcspResponsePrivate) @@ -124,64 +126,51 @@ QOcspResponse::QOcspResponse() Creates a new response, the copy of \a other. */ -QOcspResponse::QOcspResponse(const QOcspResponse &other) -{ - *d = *other.d; -} +QOcspResponse::QOcspResponse(const QOcspResponse &other) = default; /*! \since 5.13 Move-constructs a QOcspResponse instance from \a other. */ -QOcspResponse::QOcspResponse(QOcspResponse &&other) Q_DECL_NOTHROW -{ - d.swap(other.d); -} +QOcspResponse::QOcspResponse(QOcspResponse &&other) Q_DECL_NOTHROW = default; /*! \since 5.13 Destroys the response. */ -QOcspResponse::~QOcspResponse() -{ -} +QOcspResponse::~QOcspResponse() = default; /*! \since 5.13 - Assignes \a other to the response and returns a reference to this response. + Assigns \a other to the response and returns a reference to this response. */ -QOcspResponse &QOcspResponse::operator=(const QOcspResponse &other) -{ - if (this != &other) - *d = *other.d; - - return *this; -} +QOcspResponse &QOcspResponse::operator=(const QOcspResponse &other) = default; /*! \since 5.13 Move-assigns \a other to this QOcspResponse instance. */ -QOcspResponse &QOcspResponse::operator=(QOcspResponse &&other) Q_DECL_NOTHROW -{ - if (this != &other) - d.swap(other.d); +QOcspResponse &QOcspResponse::operator=(QOcspResponse &&other) Q_DECL_NOTHROW = default; - return *this; -} +/*! + \fn void QOcspResponse::swap(QOcspResponse &other) + \since 5.13 + + Swaps this response with \a other. +*/ /*! \since 5.13 Returns the certificate status. - \sa OcspCertificateStatus + \sa QOcspCertificateStatus */ -OcspCertificateStatus QOcspResponse::certificateStatus() const +QOcspCertificateStatus QOcspResponse::certificateStatus() const { return d->certificateStatus; } @@ -191,7 +180,7 @@ OcspCertificateStatus QOcspResponse::certificateStatus() const Returns the reason for revocation. */ -OcspRevocationReason QOcspResponse::revocationReason() const +QOcspRevocationReason QOcspResponse::revocationReason() const { return d->revocationReason; } @@ -216,4 +205,54 @@ QSslCertificate QOcspResponse::subject() const return d->subjectCert; } +/*! + \fn bool operator==(const QOcspResponse &lhs, const QOcspResponse &rhs) + + Returns \c true if \a lhs and \a rhs are the responses for the same + certificate, signed by the same responder, have the same + revocation reason and the same certificate status. + + \since 5.13 + \relates QOcspResponse + */ +Q_NETWORK_EXPORT bool operator==(const QOcspResponse &lhs, const QOcspResponse &rhs) +{ + return lhs.d == rhs.d || *lhs.d == *rhs.d; +} + +/*! + \fn bool operator != (const QOcspResponse &lhs, const QOcspResponse &rhs) + + Returns \c true if \a lhs and \a rhs are responses for different certificates, + or signed by different responders, or have different revocation reasons, or different + certificate statuses. + + \since 5.13 + \relates QOcspResponse +*/ + +/*! + \fn uint qHash(const QOcspResponse &response, uint seed) + + Returns the hash value for the \a response, using \a seed to seed the calculation. + + \since 5.13 + \relates QHash +*/ +uint qHash(const QOcspResponse &response, uint seed) +{ + const QOcspResponsePrivate *d = response.d.data(); + Q_ASSERT(d); + + QtPrivate::QHashCombine hasher; + uint hash = hasher(seed, int(d->certificateStatus)); + hash = hasher(hash, int(d->revocationReason)); + if (!d->signerCert.isNull()) + hash = hasher(hash, d->signerCert); + if (!d->subjectCert.isNull()) + hash = hasher(hash, d->subjectCert); + + return hash; +} + QT_END_NAMESPACE diff --git a/src/network/ssl/qocspresponse.h b/src/network/ssl/qocspresponse.h index 5cff625b84..552a088ba5 100644 --- a/src/network/ssl/qocspresponse.h +++ b/src/network/ssl/qocspresponse.h @@ -42,8 +42,9 @@ #include <QtNetwork/qtnetworkglobal.h> +#include <QtCore/qshareddata.h> +#include <QtCore/qmetatype.h> #include <QtCore/qobject.h> -#include <QtCore/qscopedpointer.h> #ifndef Q_CLANG_QDOC QT_REQUIRE_CONFIG(ssl); @@ -51,14 +52,14 @@ QT_REQUIRE_CONFIG(ssl); QT_BEGIN_NAMESPACE -enum class OcspCertificateStatus +enum class QOcspCertificateStatus { Good, Revoked, Unknown }; -enum class OcspRevocationReason +enum class QOcspRevocationReason { None = -1, Unspecified, @@ -71,8 +72,11 @@ enum class OcspRevocationReason RemoveFromCRL }; +class QOcspResponse; +Q_NETWORK_EXPORT uint qHash(const QOcspResponse &response, uint seed = 0); + class QOcspResponsePrivate; -class QOcspResponse +class Q_NETWORK_EXPORT QOcspResponse { public: @@ -84,18 +88,29 @@ public: QOcspResponse &operator = (const QOcspResponse &other); QOcspResponse &operator = (QOcspResponse &&other) Q_DECL_NOTHROW; - OcspCertificateStatus certificateStatus() const; - OcspRevocationReason revocationReason() const; + QOcspCertificateStatus certificateStatus() const; + QOcspRevocationReason revocationReason() const; class QSslCertificate responder() const; QSslCertificate subject() const; + void swap(QOcspResponse &other) Q_DECL_NOTHROW { d.swap(other.d); } + private: friend class QSslSocketBackendPrivate; - QScopedPointer<QOcspResponsePrivate> d; + friend Q_NETWORK_EXPORT bool operator==(const QOcspResponse &lhs, const QOcspResponse &rhs); + friend Q_NETWORK_EXPORT uint qHash(const QOcspResponse &response, uint seed); + + QSharedDataPointer<QOcspResponsePrivate> d; }; +inline bool operator!=(const QOcspResponse &lhs, const QOcspResponse &rhs) { return !(lhs == rhs); } + +Q_DECLARE_SHARED(QOcspResponse) + QT_END_NAMESPACE +Q_DECLARE_METATYPE(QOcspResponse) + #endif // QOCSPRESPONSE_H diff --git a/src/network/ssl/qocspresponse_p.h b/src/network/ssl/qocspresponse_p.h index 44480df633..e421b76899 100644 --- a/src/network/ssl/qocspresponse_p.h +++ b/src/network/ssl/qocspresponse_p.h @@ -44,6 +44,9 @@ #include <qsslcertificate.h> #include <qocspresponse.h> + +#include <qshareddata.h> + // // W A R N I N G // ------------- @@ -57,17 +60,25 @@ QT_BEGIN_NAMESPACE -class QOcspResponsePrivate +class QOcspResponsePrivate : public QSharedData { public: - OcspCertificateStatus certificateStatus = OcspCertificateStatus::Unknown; - OcspRevocationReason revocationReason = OcspRevocationReason::None; + QOcspCertificateStatus certificateStatus = QOcspCertificateStatus::Unknown; + QOcspRevocationReason revocationReason = QOcspRevocationReason::None; QSslCertificate signerCert; QSslCertificate subjectCert; }; +inline bool operator==(const QOcspResponsePrivate &lhs, const QOcspResponsePrivate &rhs) +{ + return lhs.certificateStatus == rhs.certificateStatus + && lhs.revocationReason == rhs.revocationReason + && lhs.signerCert == rhs.signerCert + && lhs.subjectCert == rhs.subjectCert; +} + QT_END_NAMESPACE #endif // QOCSPRESPONSE_P_H diff --git a/src/network/ssl/qsslsocket.h b/src/network/ssl/qsslsocket.h index 4a695a6b01..35943c7d7e 100644 --- a/src/network/ssl/qsslsocket.h +++ b/src/network/ssl/qsslsocket.h @@ -44,6 +44,7 @@ #include <QtNetwork/qtnetworkglobal.h> #include <QtCore/qlist.h> #include <QtCore/qregexp.h> +#include <QtCore/qvector.h> #ifndef QT_NO_SSL # include <QtNetwork/qtcpsocket.h> # include <QtNetwork/qsslerror.h> @@ -61,7 +62,6 @@ class QSslConfiguration; class QSslEllipticCurve; class QSslPreSharedKeyAuthenticator; class QOcspResponse; -template<class> class QVector; class QSslSocketPrivate; class Q_NETWORK_EXPORT QSslSocket : public QTcpSocket diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 9f5a11294d..c48cd42360 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -258,29 +258,29 @@ QSslError qt_OCSP_response_status_to_QSslError(long code) Q_UNREACHABLE(); } -OcspRevocationReason qt_OCSP_revocation_reason(int reason) +QOcspRevocationReason qt_OCSP_revocation_reason(int reason) { switch (reason) { case OCSP_REVOKED_STATUS_NOSTATUS: - return OcspRevocationReason::None; + return QOcspRevocationReason::None; case OCSP_REVOKED_STATUS_UNSPECIFIED: - return OcspRevocationReason::Unspecified; + return QOcspRevocationReason::Unspecified; case OCSP_REVOKED_STATUS_KEYCOMPROMISE: - return OcspRevocationReason::KeyCompromise; + return QOcspRevocationReason::KeyCompromise; case OCSP_REVOKED_STATUS_CACOMPROMISE: - return OcspRevocationReason::CACompromise; + return QOcspRevocationReason::CACompromise; case OCSP_REVOKED_STATUS_AFFILIATIONCHANGED: - return OcspRevocationReason::AffiliationChanged; + return QOcspRevocationReason::AffiliationChanged; case OCSP_REVOKED_STATUS_SUPERSEDED: - return OcspRevocationReason::Superseded; + return QOcspRevocationReason::Superseded; case OCSP_REVOKED_STATUS_CESSATIONOFOPERATION: - return OcspRevocationReason::CessationOfOperation; + return QOcspRevocationReason::CessationOfOperation; case OCSP_REVOKED_STATUS_CERTIFICATEHOLD: - return OcspRevocationReason::CertificateHold; + return QOcspRevocationReason::CertificateHold; case OCSP_REVOKED_STATUS_REMOVEFROMCRL: - return OcspRevocationReason::RemoveFromCRL; + return QOcspRevocationReason::RemoveFromCRL; default: - return OcspRevocationReason::None; + return QOcspRevocationReason::None; } Q_UNREACHABLE(); @@ -1624,15 +1624,15 @@ bool QSslSocketBackendPrivate::checkOcspStatus() switch (certStatus) { case V_OCSP_CERTSTATUS_GOOD: // This certificate was not found among the revoked ones. - dResponse->certificateStatus = OcspCertificateStatus::Good; + dResponse->certificateStatus = QOcspCertificateStatus::Good; break; case V_OCSP_CERTSTATUS_REVOKED: - dResponse->certificateStatus = OcspCertificateStatus::Revoked; + dResponse->certificateStatus = QOcspCertificateStatus::Revoked; dResponse->revocationReason = qt_OCSP_revocation_reason(reason); ocspErrors.push_back({QSslError::CertificateRevoked, configuration.peerCertificate}); break; case V_OCSP_CERTSTATUS_UNKNOWN: - dResponse->certificateStatus = OcspCertificateStatus::Unknown; + dResponse->certificateStatus = QOcspCertificateStatus::Unknown; ocspErrors.push_back({QSslError::OcspStatusUnknown, configuration.peerCertificate}); } From c7318e899ea00cf9f3979c8876b2402187000905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= <tor.arne.vestbo@qt.io> Date: Wed, 13 Feb 2019 15:28:44 +0100 Subject: [PATCH 1189/1650] macOS: Remove dead code in window activation handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I321ab68b51c4ba63204c0e15fec74164e2c93d34 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> --- .../cocoa/qcocoaapplicationdelegate.mm | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm index 44ab16d300..9e3c89b6a4 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm +++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm @@ -353,21 +353,6 @@ QT_USE_NAMESPACE [reflectionDelegate applicationDidBecomeActive:notification]; QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive); -/* - onApplicationChangedActivation(true); - - if (!QWidget::mouseGrabber()){ - // Update enter/leave immidiatly, don't wait for a move event. But only - // if no grab exists (even if the grab points to this widget, it seems, ref X11) - QPoint qlocal, qglobal; - QWidget *widgetUnderMouse = 0; - qt_mac_getTargetForMouseEvent(0, QEvent::Enter, qlocal, qglobal, 0, &widgetUnderMouse); - QApplicationPrivate::dispatchEnterLeave(widgetUnderMouse, 0); - qt_last_mouse_receiver = widgetUnderMouse; - qt_last_native_mouse_receiver = widgetUnderMouse ? - (widgetUnderMouse->internalWinId() ? widgetUnderMouse : widgetUnderMouse->nativeParentWidget()) : 0; - } -*/ } - (void)applicationDidResignActive:(NSNotification *)notification @@ -377,15 +362,6 @@ QT_USE_NAMESPACE [reflectionDelegate applicationDidResignActive:notification]; QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive); -/* - onApplicationChangedActivation(false); - - if (!QWidget::mouseGrabber()) - QApplicationPrivate::dispatchEnterLeave(0, qt_last_mouse_receiver); - qt_last_mouse_receiver = 0; - qt_last_native_mouse_receiver = 0; - qt_button_down = 0; -*/ } - (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag From 025128a7e0d7100da7e1705cd448012e0421e05b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= <tor.arne.vestbo@qt.io> Date: Tue, 12 Feb 2019 20:07:35 +0100 Subject: [PATCH 1190/1650] macOS: Simplify QCocoaWindow::setVisible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't need all the checks for the event dispatcher, it should always be there. Change-Id: Ib89a9c1c5524b49c2d85fae12425d19ced960597 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io> --- src/plugins/platforms/cocoa/qcocoawindow.mm | 50 ++++++++------------- 1 file changed, 18 insertions(+), 32 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index ebdd51acb4..ec7ad38be5 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -303,13 +303,17 @@ void QCocoaWindow::setVisible(bool visible) { qCDebug(lcQpaWindow) << "QCocoaWindow::setVisible" << window() << visible; - m_inSetVisible = true; + QScopedValueRollback<bool> rollback(m_inSetVisible, true); QMacAutoReleasePool pool; QCocoaWindow *parentCocoaWindow = nullptr; if (window()->transientParent()) parentCocoaWindow = static_cast<QCocoaWindow *>(window()->transientParent()->handle()); + auto eventDispatcher = [] { + return static_cast<QCocoaEventDispatcherPrivate *>(QObjectPrivate::get(qApp->eventDispatcher())); + }; + if (visible) { // We need to recreate if the modality has changed as the style mask will need updating recreateWindowIfNeeded(); @@ -350,28 +354,15 @@ void QCocoaWindow::setVisible(bool visible) applyWindowState(window()->windowStates()); if (window()->windowState() != Qt::WindowMinimized) { - if ((window()->modality() == Qt::WindowModal - || window()->type() == Qt::Sheet) - && parentCocoaWindow) { - // show the window as a sheet + if (parentCocoaWindow && (window()->modality() == Qt::WindowModal || window()->type() == Qt::Sheet)) { + // Show the window as a sheet [parentCocoaWindow->nativeWindow() beginSheet:m_view.window completionHandler:nil]; - } else if (window()->modality() != Qt::NonModal) { - // show the window as application modal - QCocoaEventDispatcher *cocoaEventDispatcher = qobject_cast<QCocoaEventDispatcher *>(QGuiApplication::instance()->eventDispatcher()); - Q_ASSERT(cocoaEventDispatcher); - QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate = static_cast<QCocoaEventDispatcherPrivate *>(QObjectPrivate::get(cocoaEventDispatcher)); - cocoaEventDispatcherPrivate->beginModalSession(window()); + } else if (window()->modality() == Qt::ApplicationModal) { + // Show the window as application modal + eventDispatcher()->beginModalSession(window()); m_hasModalSession = true; - } else if ([m_view.window canBecomeKeyWindow]) { - QCocoaEventDispatcher *cocoaEventDispatcher = qobject_cast<QCocoaEventDispatcher *>(QGuiApplication::instance()->eventDispatcher()); - QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate = nullptr; - if (cocoaEventDispatcher) - cocoaEventDispatcherPrivate = static_cast<QCocoaEventDispatcherPrivate *>(QObjectPrivate::get(cocoaEventDispatcher)); - - if (cocoaEventDispatcherPrivate && cocoaEventDispatcherPrivate->cocoaModalSessionStack.isEmpty()) - [m_view.window makeKeyAndOrderFront:nil]; - else - [m_view.window orderFront:nil]; + } else if (m_view.window.canBecomeKeyWindow && eventDispatcher()->cocoaModalSessionStack.isEmpty()) { + [m_view.window makeKeyAndOrderFront:nil]; } else { [m_view.window orderFront:nil]; } @@ -396,21 +387,18 @@ void QCocoaWindow::setVisible(bool visible) } } } + // In some cases, e.g. QDockWidget, the content view is hidden before moving to its own // Cocoa window, and then shown again. Therefore, we test for the view being hidden even // if it's attached to an NSWindow. if ([m_view isHidden]) [m_view setHidden:NO]; + } else { - // qDebug() << "close" << this; - QCocoaEventDispatcher *cocoaEventDispatcher = qobject_cast<QCocoaEventDispatcher *>(QGuiApplication::instance()->eventDispatcher()); - QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate = nullptr; - if (cocoaEventDispatcher) - cocoaEventDispatcherPrivate = static_cast<QCocoaEventDispatcherPrivate *>(QObjectPrivate::get(cocoaEventDispatcher)); + // Window not visible, hide it if (isContentView()) { if (m_hasModalSession) { - if (cocoaEventDispatcherPrivate) - cocoaEventDispatcherPrivate->endModalSession(window()); + eventDispatcher()->endModalSession(window()); m_hasModalSession = false; } else { if ([m_view.window isSheet]) { @@ -421,8 +409,7 @@ void QCocoaWindow::setVisible(bool visible) [m_view.window orderOut:nil]; - if (m_view.window == [NSApp keyWindow] - && !(cocoaEventDispatcherPrivate && cocoaEventDispatcherPrivate->currentModalSession())) { + if (m_view.window == [NSApp keyWindow] && !eventDispatcher()->currentModalSession()) { // Probably because we call runModalSession: outside [NSApp run] in QCocoaEventDispatcher // (e.g., when show()-ing a modal QDialog instead of exec()-ing it), it can happen that // the current NSWindow is still key after being ordered out. Then, after checking we @@ -434,6 +421,7 @@ void QCocoaWindow::setVisible(bool visible) } else { [m_view setHidden:YES]; } + removeMonitor(); if (window()->type() == Qt::Popup || window()->type() == Qt::ToolTip) @@ -447,8 +435,6 @@ void QCocoaWindow::setVisible(bool visible) nativeParentWindow.styleMask |= NSWindowStyleMaskResizable; } } - - m_inSetVisible = false; } NSInteger QCocoaWindow::windowLevel(Qt::WindowFlags flags) From c36c5e9b552f826c96bf066252b49de03921c03f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= <tor.arne.vestbo@qt.io> Date: Tue, 12 Feb 2019 20:33:13 +0100 Subject: [PATCH 1191/1650] macOS: Modernize worksWhenModal handling The code in QCocoaEventDispatcher was dead and could be removed. Change-Id: I0c57e64791045d65033376c096220983059028ba Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> --- .../platforms/cocoa/qcocoaeventdispatcher.h | 1 - .../platforms/cocoa/qcocoaeventdispatcher.mm | 41 ------------------- src/plugins/platforms/cocoa/qcocoawindow.mm | 30 ++++++-------- src/plugins/platforms/cocoa/qnswindow.h | 1 + src/plugins/platforms/cocoa/qnswindow.mm | 13 ++++++ 5 files changed, 27 insertions(+), 59 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h index ebf33cf4e2..44a9c52b7b 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h @@ -168,7 +168,6 @@ public: uint processEventsCalled; NSModalSession currentModalSessionCached; NSModalSession currentModalSession(); - void updateChildrenWorksWhenModal(); void temporarilyStopAllModalSessions(); void beginModalSession(QWindow *widget); void endModalSession(QWindow *widget); diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index b0f2b6d940..b944c3d28c 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -672,45 +672,6 @@ NSModalSession QCocoaEventDispatcherPrivate::currentModalSession() return currentModalSessionCached; } -static void setChildrenWorksWhenModal(QWindow *window, bool worksWhenModal) -{ - Q_UNUSED(window) - Q_UNUSED(worksWhenModal) - - // For NSPanels (but not NSWindows, sadly), we can set the flag - // worksWhenModal, so that they are active even when they are not modal. -/* - ### not ported - QList<QDialog *> dialogs = window->findChildren<QDialog *>(); - for (int i=0; i<dialogs.size(); ++i){ - NSWindow *window = qt_mac_window_for(dialogs[i]); - if (window && [window isKindOfClass:[NSPanel class]]) { - [static_cast<NSPanel *>(window) setWorksWhenModal:worksWhenModal]; - if (worksWhenModal && [window isVisible]){ - [window orderFront:window]; - } - } - } -*/ -} - -void QCocoaEventDispatcherPrivate::updateChildrenWorksWhenModal() -{ - // Make the dialog children of the window - // active. And make the dialog children of - // the previous modal dialog unactive again: - QMacAutoReleasePool pool; - int size = cocoaModalSessionStack.size(); - if (size > 0){ - if (QWindow *prevModal = cocoaModalSessionStack[size-1].window) - setChildrenWorksWhenModal(prevModal, true); - if (size > 1){ - if (QWindow *prevModal = cocoaModalSessionStack[size-2].window) - setChildrenWorksWhenModal(prevModal, false); - } - } -} - void QCocoaEventDispatcherPrivate::cleanupModalSessions() { // Go through the list of modal sessions, and end those @@ -743,7 +704,6 @@ void QCocoaEventDispatcherPrivate::cleanupModalSessions() cocoaModalSessionStack.remove(i); } - updateChildrenWorksWhenModal(); cleanupModalSessionsNeeded = false; } @@ -764,7 +724,6 @@ void QCocoaEventDispatcherPrivate::beginModalSession(QWindow *window) // stopped in cleanupModalSessions()). QCocoaModalSessionInfo info = {window, nullptr, nullptr}; cocoaModalSessionStack.push(info); - updateChildrenWorksWhenModal(); currentModalSessionCached = nullptr; } diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index ec7ad38be5..5a26f57c8c 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -367,23 +367,19 @@ void QCocoaWindow::setVisible(bool visible) [m_view.window orderFront:nil]; } - // We want the events to properly reach the popup, dialog, and tool - if ((window()->type() == Qt::Popup || window()->type() == Qt::Dialog || window()->type() == Qt::Tool) - && [m_view.window isKindOfClass:[NSPanel class]]) { - ((NSPanel *)m_view.window).worksWhenModal = YES; - if (!(parentCocoaWindow && window()->transientParent()->isActive()) && window()->type() == Qt::Popup) { - removeMonitor(); - NSEventMask eventMask = NSEventMaskLeftMouseDown | NSEventMaskRightMouseDown - | NSEventMaskOtherMouseDown | NSEventMaskMouseMoved; - monitor = [NSEvent addGlobalMonitorForEventsMatchingMask:eventMask handler:^(NSEvent *e) { - const auto button = cocoaButton2QtButton(e); - const auto buttons = currentlyPressedMouseButtons(); - const auto eventType = cocoaEvent2QtMouseEvent(e); - const auto globalPoint = QCocoaScreen::mapFromNative(NSEvent.mouseLocation); - const auto localPoint = window()->mapFromGlobal(globalPoint.toPoint()); - QWindowSystemInterface::handleMouseEvent(window(), localPoint, globalPoint, buttons, button, eventType); - }]; - } + // Close popup when clicking outside it + if (window()->type() == Qt::Popup && !(parentCocoaWindow && window()->transientParent()->isActive())) { + removeMonitor(); + NSEventMask eventMask = NSEventMaskLeftMouseDown | NSEventMaskRightMouseDown + | NSEventMaskOtherMouseDown | NSEventMaskMouseMoved; + monitor = [NSEvent addGlobalMonitorForEventsMatchingMask:eventMask handler:^(NSEvent *e) { + const auto button = cocoaButton2QtButton(e); + const auto buttons = currentlyPressedMouseButtons(); + const auto eventType = cocoaEvent2QtMouseEvent(e); + const auto globalPoint = QCocoaScreen::mapFromNative(NSEvent.mouseLocation); + const auto localPoint = window()->mapFromGlobal(globalPoint.toPoint()); + QWindowSystemInterface::handleMouseEvent(window(), localPoint, globalPoint, buttons, button, eventType); + }]; } } } diff --git a/src/plugins/platforms/cocoa/qnswindow.h b/src/plugins/platforms/cocoa/qnswindow.h index 64f1ed0802..dcbcd58901 100644 --- a/src/plugins/platforms/cocoa/qnswindow.h +++ b/src/plugins/platforms/cocoa/qnswindow.h @@ -62,6 +62,7 @@ QT_FORWARD_DECLARE_CLASS(QCocoaWindow) @protocol QNSWindowProtocol @optional - (BOOL)canBecomeKeyWindow; +- (BOOL)worksWhenModal; - (void)sendEvent:(NSEvent*)theEvent; - (void)closeAndRelease; - (void)dealloc; diff --git a/src/plugins/platforms/cocoa/qnswindow.mm b/src/plugins/platforms/cocoa/qnswindow.mm index c17ad47aba..28a9fa8607 100644 --- a/src/plugins/platforms/cocoa/qnswindow.mm +++ b/src/plugins/platforms/cocoa/qnswindow.mm @@ -177,6 +177,19 @@ static bool isMouseEvent(NSEvent *ev) return canBecomeMain; } +- (BOOL)worksWhenModal +{ + if ([self isKindOfClass:[QNSPanel class]]) { + if (QCocoaWindow *pw = self.platformWindow) { + Qt::WindowType type = pw->window()->type(); + if (type == Qt::Popup || type == Qt::Dialog || type == Qt::Tool) + return YES; + } + } + + return qt_objcDynamicSuper(); +} + - (BOOL)isOpaque { return self.platformWindow ? From 6273b484b35479eb5788425c8d90acacdf239623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= <tor.arne.vestbo@qt.io> Date: Tue, 12 Feb 2019 20:55:31 +0100 Subject: [PATCH 1192/1650] macOS: Remove redundant tracking of modal sessions in QCocoaWindow Change-Id: I43a40889b0731e4b480155256fc51eaa836e62a3 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> --- src/plugins/platforms/cocoa/qcocoaeventdispatcher.h | 1 + src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm | 5 +++++ src/plugins/platforms/cocoa/qcocoawindow.h | 1 - src/plugins/platforms/cocoa/qcocoawindow.mm | 9 +++------ 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h index 44a9c52b7b..9771cd0289 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h @@ -171,6 +171,7 @@ public: void temporarilyStopAllModalSessions(); void beginModalSession(QWindow *widget); void endModalSession(QWindow *widget); + bool hasModalSession() const; void cleanupModalSessions(); void cancelWaitForMoreEvents(); diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index b944c3d28c..84ffadea83 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -672,6 +672,11 @@ NSModalSession QCocoaEventDispatcherPrivate::currentModalSession() return currentModalSessionCached; } +bool QCocoaEventDispatcherPrivate::hasModalSession() const +{ + return !cocoaModalSessionStack.isEmpty(); +} + void QCocoaEventDispatcherPrivate::cleanupModalSessions() { // Go through the list of modal sessions, and end those diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index 0a913ef66e..fef72bc496 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -253,7 +253,6 @@ public: // for QNSView bool m_needsInvalidateShadow; - bool m_hasModalSession; bool m_frameStrutEventsEnabled; QRect m_exposedRect; int m_registerTouchCount; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 5a26f57c8c..2718dc9600 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -153,7 +153,6 @@ QCocoaWindow::QCocoaWindow(QWindow *win, WId nativeHandle) , m_inSetStyleMask(false) , m_menubar(nullptr) , m_needsInvalidateShadow(false) - , m_hasModalSession(false) , m_frameStrutEventsEnabled(false) , m_registerTouchCount(0) , m_resizableTransientParent(false) @@ -360,8 +359,7 @@ void QCocoaWindow::setVisible(bool visible) } else if (window()->modality() == Qt::ApplicationModal) { // Show the window as application modal eventDispatcher()->beginModalSession(window()); - m_hasModalSession = true; - } else if (m_view.window.canBecomeKeyWindow && eventDispatcher()->cocoaModalSessionStack.isEmpty()) { + } else if (m_view.window.canBecomeKeyWindow && !eventDispatcher()->hasModalSession()) { [m_view.window makeKeyAndOrderFront:nil]; } else { [m_view.window orderFront:nil]; @@ -393,9 +391,8 @@ void QCocoaWindow::setVisible(bool visible) } else { // Window not visible, hide it if (isContentView()) { - if (m_hasModalSession) { + if (eventDispatcher()->hasModalSession()) { eventDispatcher()->endModalSession(window()); - m_hasModalSession = false; } else { if ([m_view.window isSheet]) { Q_ASSERT_X(parentCocoaWindow, "QCocoaWindow", "Window modal dialog has no transient parent."); @@ -405,7 +402,7 @@ void QCocoaWindow::setVisible(bool visible) [m_view.window orderOut:nil]; - if (m_view.window == [NSApp keyWindow] && !eventDispatcher()->currentModalSession()) { + if (m_view.window == [NSApp keyWindow] && !eventDispatcher()->hasModalSession()) { // Probably because we call runModalSession: outside [NSApp run] in QCocoaEventDispatcher // (e.g., when show()-ing a modal QDialog instead of exec()-ing it), it can happen that // the current NSWindow is still key after being ordered out. Then, after checking we From 46278b77aa5827295ef04ec5b973b36071275249 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Sat, 9 Feb 2019 14:35:25 +0100 Subject: [PATCH 1193/1650] QtNetwork: compile with QT_DISABLE_DEPRECATED_BEFORE=0x050d00 Don't call or implement functions which are not available when compiling with QT_DISABLE_DEPRECATED_BEFORE=0x050d00 Change-Id: I9e059cfa6d5e70c5672d50d7d4dae7483314ad17 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> --- src/network/ssl/qsslsocket.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index fdd3e8efba..cf8a472606 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -1228,6 +1228,7 @@ QSslKey QSslSocket::privateKey() const return d->configuration.privateKey; } +#if QT_DEPRECATED_SINCE(5, 5) /*! \deprecated @@ -1371,6 +1372,7 @@ QList<QSslCipher> QSslSocket::supportedCiphers() { return QSslSocketPrivate::supportedCiphers(); } +#endif // #if QT_DEPRECATED_SINCE(5, 5) /*! Searches all files in the \a path for certificates encoded in the @@ -1430,6 +1432,7 @@ void QSslSocket::addCaCertificates(const QList<QSslCertificate> &certificates) d->configuration.caCertificates += certificates; } +#if QT_DEPRECATED_SINCE(5, 5) /*! \deprecated @@ -1474,6 +1477,7 @@ QList<QSslCertificate> QSslSocket::caCertificates() const Q_D(const QSslSocket); return d->configuration.caCertificates; } +#endif // #if QT_DEPRECATED_SINCE(5, 5) /*! Searches all files in the \a path for certificates with the @@ -1518,6 +1522,7 @@ void QSslSocket::addDefaultCaCertificates(const QList<QSslCertificate> &certific QSslSocketPrivate::addDefaultCaCertificates(certificates); } +#if QT_DEPRECATED_SINCE(5, 5) /*! \deprecated @@ -1585,6 +1590,7 @@ QList<QSslCertificate> QSslSocket::systemCaCertificates() // we are calling ensureInitialized() in the method below return QSslSocketPrivate::systemCaCertificates(); } +#endif // #if QT_DEPRECATED_SINCE(5, 5) /*! Waits until the socket is connected, or \a msecs milliseconds, From 91deac4a65a31141764cd2739066166475f024d8 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Fri, 15 Feb 2019 21:21:20 +0100 Subject: [PATCH 1194/1650] QtCore: replace null and nullptr with \nullptr in documentation Replace null and '\c nullptr' with \nullptr in the documentation. Change-Id: Ib9e0cfc2eb2830b213e6523773603d56180b0998 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> --- src/corelib/kernel/qcoreapplication.cpp | 19 +++++---- src/corelib/kernel/qmetaobject.cpp | 2 +- src/corelib/kernel/qmetatype.cpp | 2 +- src/corelib/kernel/qobject.cpp | 4 +- src/corelib/kernel/qvariant.cpp | 4 +- src/corelib/plugin/quuid.cpp | 2 +- src/corelib/serialization/qcborvalue.cpp | 4 +- src/corelib/thread/qsemaphore.cpp | 4 +- src/corelib/tools/qbytearray.cpp | 54 ++++++++++++------------ src/corelib/tools/qlocale.cpp | 48 ++++++++++----------- src/corelib/tools/qshareddata.cpp | 6 +-- src/corelib/tools/qsharedpointer.cpp | 8 ++-- src/corelib/tools/qstring.cpp | 44 +++++++++---------- src/corelib/tools/qstringview.cpp | 12 +++--- 14 files changed, 107 insertions(+), 106 deletions(-) diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index e5098b8415..db66157a0e 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -1636,14 +1636,15 @@ bool QCoreApplication::compressEvent(QEvent *event, QObject *receiver, QPostEven /*! Immediately dispatches all events which have been previously queued - with QCoreApplication::postEvent() and which are for the object \a receiver - and have the event type \a event_type. + with QCoreApplication::postEvent() and which are for the object \a + receiver and have the event type \a event_type. Events from the window system are \e not dispatched by this function, but by processEvents(). - If \a receiver is null, the events of \a event_type are sent for all - objects. If \a event_type is 0, all the events are sent for \a receiver. + If \a receiver is \nullptr, the events of \a event_type are sent for + all objects. If \a event_type is 0, all the events are sent for + \a receiver. \note This method must be called from the thread in which its QObject parameter, \a receiver, lives. @@ -1824,10 +1825,10 @@ void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type call it, be aware that killing events may cause \a receiver to break one or more invariants. - If \a receiver is null, the events of \a eventType are removed for - all objects. If \a eventType is 0, all the events are removed for - \a receiver. You should never call this function with \a eventType - of 0. + If \a receiver is \nullptr, the events of \a eventType are removed + for all objects. If \a eventType is 0, all the events are removed + for \a receiver. You should never call this function with \a + eventType of 0. \threadsafe */ @@ -2140,7 +2141,7 @@ static void replacePercentN(QString *result, int n) \a disambiguation is an identifying string, for when the same \a sourceText is used in different roles within the same context. By - default, it is null. + default, it is \nullptr. See the \l QTranslator and \l QObject::tr() documentation for more information about contexts, disambiguations and comments. diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 8082b7fe9b..c15a9f7b0f 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -3522,7 +3522,7 @@ bool QMetaProperty::isStored(const QObject *object) const false. e.g., the \c text property is the \c USER editable property of a QLineEdit. - If \a object is null, the function returns \c false if the \c + If \a object is \nullptr, the function returns \c false if the \c {Q_PROPERTY()}'s \c USER attribute is false. Otherwise it returns true. diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index a1d53be197..45d0b5df6c 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -432,7 +432,7 @@ struct DefinedTypesFilter { \since 5.0 Returns a copy of \a copy, assuming it is of the type that this - QMetaType instance was created for. If \a copy is null, creates + QMetaType instance was created for. If \a copy is \nullptr, creates a default constructed instance. \sa QMetaType::destroy() diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 2cdb9eaaa6..77f507ff3f 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -3284,7 +3284,7 @@ QMetaObject::Connection QMetaObject::connect(const QObject *sender, int signal_i \internal Same as the QMetaObject::connect, but \a signal_index must be the result of QObjectPrivate::signalIndex - method_index is relative to the rmeta metaobject, if rmeta is null, then it is absolute index + method_index is relative to the rmeta metaobject, if rmeta is \nullptr, then it is absolute index the QObjectPrivate::Connection* has a refcount of 2, so it must be passed to a QMetaObject::Connection */ @@ -3856,7 +3856,7 @@ void QMetaObject::activate(QObject *sender, int signal_index, void **argv) It is different from QMetaObject::indexOfSignal(): indexOfSignal is the same as indexOfMethod while QObjectPrivate::signalIndex is smaller because it doesn't give index to slots. - If \a meta is not 0, it is set to the meta-object where the signal was found. + If \a meta is not \nullptr, it is set to the meta-object where the signal was found. */ int QObjectPrivate::signalIndex(const char *signalName, const QMetaObject **meta) const diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 090436a3c7..18c7f7648d 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -1768,7 +1768,7 @@ Q_CORE_EXPORT void QVariantPrivate::registerHandler(const int /* Modules::Names \fn QVariant::QVariant(int typeId, const void *copy) Constructs variant of type \a typeId, and initializes with - \a copy if \a copy is not 0. + \a copy if \a copy is not \nullptr. Note that you have to pass the address of the variable you want stored. @@ -1797,7 +1797,7 @@ Q_CORE_EXPORT void QVariantPrivate::registerHandler(const int /* Modules::Names \internal Constructs a variant private of type \a type, and initializes with \a copy if - \a copy is not 0. + \a copy is not \nullptr. */ void QVariant::create(int type, const void *copy) diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp index b113ca13ce..8bb5e1463a 100644 --- a/src/corelib/plugin/quuid.cpp +++ b/src/corelib/plugin/quuid.cpp @@ -112,7 +112,7 @@ static char *_q_uuidToHex(const QUuid &uuid, char *dst, QUuid::StringFormat mode Parses the string representation of a UUID (with optional surrounding "{}") by reading at most MaxStringUuidLength (38) characters from \a src, which - may be \c nullptr. Stops at the first invalid character (which includes a + may be \nullptr. Stops at the first invalid character (which includes a premature NUL). Returns the successfully parsed QUuid, or a null QUuid in case of failure. diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp index c99782bb1e..288446878c 100644 --- a/src/corelib/serialization/qcborvalue.cpp +++ b/src/corelib/serialization/qcborvalue.cpp @@ -108,7 +108,7 @@ QT_BEGIN_NAMESPACE QCborValue can contain a value of "null", which is not of any specific type. It resembles the C++ \c {std::nullptr_t} type, whose only possible value is - \c nullptr. QCborValue has a constructor taking such a type and creates a + \nullptr. QCborValue has a constructor taking such a type and creates a null QCborValue. Null values are used to indicate that an optional value is not present. In @@ -417,7 +417,7 @@ QT_BEGIN_NAMESPACE using toSimpleType() as well as isSimpleType(st). CBOR simple types are types that do not have any associated value, like - C++'s \c{std::nullptr_t} type, whose only possible value is \c nullptr. + C++'s \c{std::nullptr_t} type, whose only possible value is \nullptr. If \a st is \c{QCborSimpleType::Null}, the resulting QCborValue will be of the \l{Type}{Null} type and similarly for \c{QCborSimpleType::Undefined}. diff --git a/src/corelib/thread/qsemaphore.cpp b/src/corelib/thread/qsemaphore.cpp index aa04fb10ff..2e0b6f2bc0 100644 --- a/src/corelib/thread/qsemaphore.cpp +++ b/src/corelib/thread/qsemaphore.cpp @@ -606,7 +606,7 @@ bool QSemaphore::tryAcquire(int n, int timeout) \fn QSemaphoreReleaser::semaphore() const Returns a pointer to the QSemaphore object provided to the constructor, - or by the last move assignment, if any. Otherwise, returns \c nullptr. + or by the last move assignment, if any. Otherwise, returns \nullptr. */ /*! @@ -614,7 +614,7 @@ bool QSemaphore::tryAcquire(int n, int timeout) Cancels this QSemaphoreReleaser such that the destructor will no longer call \c{semaphore()->release()}. Returns the value of semaphore() - before this call. After this call, semaphore() will return \c nullptr. + before this call. After this call, semaphore() will return \nullptr. To enable again, assign a new QSemaphoreReleaser: diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 70eae9e463..64674ddc00 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -239,8 +239,8 @@ qCalculateGrowingBlockSize(size_t elementCount, size_t elementSize, size_t heade Returns a duplicate string. Allocates space for a copy of \a src, copies it, and returns a - pointer to the copy. If \a src is nullptr, it immediately returns - nullptr. + pointer to the copy. If \a src is \nullptr, it immediately returns + \nullptr. Ownership is passed to the caller, so the returned string must be deleted using \c delete[]. @@ -258,7 +258,7 @@ char *qstrdup(const char *src) Copies all the characters up to and including the '\\0' from \a src into \a dst and returns a pointer to \a dst. If \a src is - nullptr, it immediately returns nullptr. + \nullptr, it immediately returns \nullptr. This function assumes that \a dst is large enough to hold the contents of \a src. @@ -291,7 +291,7 @@ char *qstrcpy(char *dst, const char *src) Copies at most \a len bytes from \a src (stopping at \a len or the terminating '\\0' whichever comes first) into \a dst and returns a pointer to \a dst. Guarantees that \a dst is '\\0'-terminated. If - \a src or \a dst is nullptr, returns nullptr immediately. + \a src or \a dst is \nullptr, returns \nullptr immediately. This function assumes that \a dst is at least \a len characters long. @@ -326,7 +326,7 @@ char *qstrncpy(char *dst, const char *src, uint len) A safe \c strlen() function. Returns the number of characters that precede the terminating '\\0', - or 0 if \a str is nullptr. + or 0 if \a str is \nullptr. \sa qstrnlen() */ @@ -338,7 +338,7 @@ char *qstrncpy(char *dst, const char *src, uint len) A safe \c strnlen() function. Returns the number of characters that precede the terminating '\\0', but - at most \a maxlen. If \a str is nullptr, returns 0. + at most \a maxlen. If \a str is \nullptr, returns 0. \sa qstrlen() */ @@ -352,10 +352,10 @@ char *qstrncpy(char *dst, const char *src, uint len) is less than \a str2, 0 if \a str1 is equal to \a str2 or a positive value if \a str1 is greater than \a str2. - Special case 1: Returns 0 if \a str1 and \a str2 are both nullptr. + Special case 1: Returns 0 if \a str1 and \a str2 are both \nullptr. Special case 2: Returns an arbitrary non-zero value if \a str1 is - nullptr or \a str2 is nullptr (but not both). + \nullptr or \a str2 is \nullptr (but not both). \sa qstrncmp(), qstricmp(), qstrnicmp(), {8-bit Character Comparisons}, QByteArray::compare() @@ -378,10 +378,10 @@ int qstrcmp(const char *str1, const char *str2) str1 is equal to \a str2 or a positive value if \a str1 is greater than \a str2. - Special case 1: Returns 0 if \a str1 and \a str2 are both nullptr. + Special case 1: Returns 0 if \a str1 and \a str2 are both \nullptr. - Special case 2: Returns a random non-zero value if \a str1 is nullptr - or \a str2 is nullptr (but not both). + Special case 2: Returns a random non-zero value if \a str1 is \nullptr + or \a str2 is \nullptr (but not both). \sa qstrcmp(), qstricmp(), qstrnicmp(), {8-bit Character Comparisons}, QByteArray::compare() @@ -398,10 +398,10 @@ int qstrcmp(const char *str1, const char *str2) str1 is equal to \a str2 or a positive value if \a str1 is greater than \a str2. - Special case 1: Returns 0 if \a str1 and \a str2 are both nullptr. + Special case 1: Returns 0 if \a str1 and \a str2 are both \nullptr. - Special case 2: Returns a random non-zero value if \a str1 is nullptr - or \a str2 is nullptr (but not both). + Special case 2: Returns a random non-zero value if \a str1 is \nullptr + or \a str2 is \nullptr (but not both). \sa qstrcmp(), qstrncmp(), qstrnicmp(), {8-bit Character Comparisons}, QByteArray::compare() @@ -491,10 +491,10 @@ int qstricmp(const char *str1, const char *str2) is equal to \a str2 or a positive value if \a str1 is greater than \a str2. - Special case 1: Returns 0 if \a str1 and \a str2 are both nullptr. + Special case 1: Returns 0 if \a str1 and \a str2 are both \nullptr. - Special case 2: Returns a random non-zero value if \a str1 is nullptr - or \a str2 is nullptr (but not both). + Special case 2: Returns a random non-zero value if \a str1 is \nullptr + or \a str2 is \nullptr (but not both). \sa qstrcmp(), qstrncmp(), qstricmp(), {8-bit Character Comparisons}, QByteArray::compare() @@ -3912,7 +3912,7 @@ T toIntegral_helper(const char *data, bool *ok, int base) Returns 0 if the conversion fails. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. \note The conversion of the number is performed in the default C locale, @@ -3938,7 +3938,7 @@ qlonglong QByteArray::toLongLong(bool *ok, int base) const Returns 0 if the conversion fails. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. \note The conversion of the number is performed in the default C locale, @@ -3963,7 +3963,7 @@ qulonglong QByteArray::toULongLong(bool *ok, int base) const Returns 0 if the conversion fails. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. \snippet code/src_corelib_tools_qbytearray.cpp 36 @@ -3990,7 +3990,7 @@ int QByteArray::toInt(bool *ok, int base) const Returns 0 if the conversion fails. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. \note The conversion of the number is performed in the default C locale, @@ -4017,7 +4017,7 @@ uint QByteArray::toUInt(bool *ok, int base) const Returns 0 if the conversion fails. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. \snippet code/src_corelib_tools_qbytearray.cpp 37 @@ -4045,7 +4045,7 @@ long QByteArray::toLong(bool *ok, int base) const Returns 0 if the conversion fails. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. \note The conversion of the number is performed in the default C locale, @@ -4069,7 +4069,7 @@ ulong QByteArray::toULong(bool *ok, int base) const Returns 0 if the conversion fails. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. \note The conversion of the number is performed in the default C locale, @@ -4094,7 +4094,7 @@ short QByteArray::toShort(bool *ok, int base) const Returns 0 if the conversion fails. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. \note The conversion of the number is performed in the default C locale, @@ -4115,7 +4115,7 @@ ushort QByteArray::toUShort(bool *ok, int base) const Returns an infinity if the conversion overflows or 0.0 if the conversion fails for other reasons (e.g. underflow). - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. \snippet code/src_corelib_tools_qbytearray.cpp 38 @@ -4151,7 +4151,7 @@ double QByteArray::toDouble(bool *ok) const Returns an infinity if the conversion overflows or 0.0 if the conversion fails for other reasons (e.g. underflow). - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. \snippet code/src_corelib_tools_qbytearray.cpp 38float diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 79ecdb0a54..b3fb079342 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -1265,7 +1265,7 @@ QString QLocale::scriptToString(QLocale::Script script) If the conversion fails the function returns 0. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function ignores leading and trailing whitespace. @@ -1283,7 +1283,7 @@ short QLocale::toShort(const QString &s, bool *ok) const If the conversion fails the function returns 0. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function ignores leading and trailing whitespace. @@ -1301,7 +1301,7 @@ ushort QLocale::toUShort(const QString &s, bool *ok) const If the conversion fails the function returns 0. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function ignores leading and trailing whitespace. @@ -1319,7 +1319,7 @@ int QLocale::toInt(const QString &s, bool *ok) const If the conversion fails the function returns 0. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function ignores leading and trailing whitespace. @@ -1337,7 +1337,7 @@ uint QLocale::toUInt(const QString &s, bool *ok) const If the conversion fails the function returns 0. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function ignores leading and trailing whitespace. @@ -1357,7 +1357,7 @@ qlonglong QLocale::toLongLong(const QString &s, bool *ok) const If the conversion fails the function returns 0. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function ignores leading and trailing whitespace. @@ -1376,7 +1376,7 @@ qulonglong QLocale::toULongLong(const QString &s, bool *ok) const Returns an infinity if the conversion overflows or 0.0 if the conversion fails for any other reason (e.g. underflow). - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function does not fall back to the 'C' locale if the string @@ -1398,7 +1398,7 @@ float QLocale::toFloat(const QString &s, bool *ok) const Returns an infinity if the conversion overflows or 0.0 if the conversion fails for any other reason (e.g. underflow). - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function does not fall back to the 'C' locale if the string @@ -1424,7 +1424,7 @@ double QLocale::toDouble(const QString &s, bool *ok) const If the conversion fails the function returns 0. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function ignores leading and trailing whitespace. @@ -1444,7 +1444,7 @@ short QLocale::toShort(const QStringRef &s, bool *ok) const If the conversion fails the function returns 0. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function ignores leading and trailing whitespace. @@ -1464,7 +1464,7 @@ ushort QLocale::toUShort(const QStringRef &s, bool *ok) const If the conversion fails the function returns 0. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function ignores leading and trailing whitespace. @@ -1484,7 +1484,7 @@ int QLocale::toInt(const QStringRef &s, bool *ok) const If the conversion fails the function returns 0. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function ignores leading and trailing whitespace. @@ -1504,7 +1504,7 @@ uint QLocale::toUInt(const QStringRef &s, bool *ok) const If the conversion fails the function returns 0. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function ignores leading and trailing whitespace. @@ -1526,7 +1526,7 @@ qlonglong QLocale::toLongLong(const QStringRef &s, bool *ok) const If the conversion fails the function returns 0. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function ignores leading and trailing whitespace. @@ -1547,7 +1547,7 @@ qulonglong QLocale::toULongLong(const QStringRef &s, bool *ok) const Returns an infinity if the conversion overflows or 0.0 if the conversion fails for any other reason (e.g. underflow). - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function does not fall back to the 'C' locale if the string @@ -1571,7 +1571,7 @@ float QLocale::toFloat(const QStringRef &s, bool *ok) const Returns an infinity if the conversion overflows or 0.0 if the conversion fails for any other reason (e.g. underflow). - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function does not fall back to the 'C' locale if the string @@ -1600,7 +1600,7 @@ double QLocale::toDouble(const QStringRef &s, bool *ok) const If the conversion fails, the function returns 0. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function ignores leading and trailing whitespace. @@ -1620,7 +1620,7 @@ short QLocale::toShort(QStringView s, bool *ok) const If the conversion fails, the function returns 0. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function ignores leading and trailing whitespace. @@ -1640,7 +1640,7 @@ ushort QLocale::toUShort(QStringView s, bool *ok) const If the conversion fails, the function returns 0. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function ignores leading and trailing whitespace. @@ -1660,7 +1660,7 @@ int QLocale::toInt(QStringView s, bool *ok) const If the conversion fails, the function returns 0. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function ignores leading and trailing whitespace. @@ -1680,7 +1680,7 @@ uint QLocale::toUInt(QStringView s, bool *ok) const If the conversion fails, the function returns 0. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function ignores leading and trailing whitespace. @@ -1702,7 +1702,7 @@ qlonglong QLocale::toLongLong(QStringView s, bool *ok) const If the conversion fails, the function returns 0. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function ignores leading and trailing whitespace. @@ -1723,7 +1723,7 @@ qulonglong QLocale::toULongLong(QStringView s, bool *ok) const Returns an infinity if the conversion overflows or 0.0 if the conversion fails for any other reason (e.g. underflow). - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. This function ignores leading and trailing whitespace. @@ -1744,7 +1744,7 @@ float QLocale::toFloat(QStringView s, bool *ok) const Returns an infinity if the conversion overflows or 0.0 if the conversion fails for any other reason (e.g. underflow). - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. Unlike QString::toDouble(), this function does not fall back to diff --git a/src/corelib/tools/qshareddata.cpp b/src/corelib/tools/qshareddata.cpp index c334f71fa0..dcfda40eda 100644 --- a/src/corelib/tools/qshareddata.cpp +++ b/src/corelib/tools/qshareddata.cpp @@ -368,7 +368,7 @@ QT_BEGIN_NAMESPACE */ /*! \fn template <class T> bool QSharedDataPointer<T>::operator!() const - Returns \c true if the \e{d pointer} of \e this is null. + Returns \c true if the \e{d pointer} of \e this is \nullptr. */ /*! \fn template <class T> void QSharedDataPointer<T>::detach() @@ -583,7 +583,7 @@ QT_BEGIN_NAMESPACE \since 5.12 Returns a pointer to the shared object, and resets \e this to be null. - That is, this function sets the \e{d pointer} of \e this to \c nullptr. + That is, this function sets the \e{d pointer} of \e this to \nullptr. */ /*! \fn template <class T> QExplicitlySharedDataPointer<T>::operator bool () const @@ -591,7 +591,7 @@ QT_BEGIN_NAMESPACE */ /*! \fn template <class T> bool QExplicitlySharedDataPointer<T>::operator!() const - Returns \c true if the \e{d pointer} of \e this is null. + Returns \c true if the \e{d pointer} of \e this is \nullptr. */ /*! \fn template <class T> void QExplicitlySharedDataPointer<T>::detach() diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index a1caeeb135..ce0a1ad9cb 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -579,8 +579,8 @@ /*! \fn template <class T> bool QSharedPointer<T>::operator !() const - Returns \c true if this object is null. This function is suitable - for use in \tt if-constructs, like: + Returns \c true if this object is \nullptr. This function is + suitable for use in \tt if-constructs, like: \snippet code/src_corelib_tools_qsharedpointer.cpp 5 @@ -854,8 +854,8 @@ /*! \fn template <class T> bool QWeakPointer<T>::operator !() const - Returns \c true if this object is null. This function is suitable - for use in \tt if-constructs, like: + Returns \c true if this object is \nullptr. This function is + suitable for use in \tt if-constructs, like: \snippet code/src_corelib_tools_qsharedpointer.cpp 9 diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index dc09c8e729..59c4884ff5 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -7231,7 +7231,7 @@ QString QString::vasprintf(const char *cformat, va_list ap) base, which is 10 by default and must be between 2 and 36, or 0. Returns 0 if the conversion fails. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. If \a base is 0, the C language convention is used: If the string @@ -7273,7 +7273,7 @@ qlonglong QString::toIntegral_helper(const QChar *data, int len, bool *ok, int b base, which is 10 by default and must be between 2 and 36, or 0. Returns 0 if the conversion fails. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. If \a base is 0, the C language convention is used: If the string @@ -7317,7 +7317,7 @@ qulonglong QString::toIntegral_helper(const QChar *data, uint len, bool *ok, int base, which is 10 by default and must be between 2 and 36, or 0. Returns 0 if the conversion fails. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. If \a base is 0, the C language convention is used: If the string @@ -7348,7 +7348,7 @@ long QString::toLong(bool *ok, int base) const base, which is 10 by default and must be between 2 and 36, or 0. Returns 0 if the conversion fails. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. If \a base is 0, the C language convention is used: If the string @@ -7378,7 +7378,7 @@ ulong QString::toULong(bool *ok, int base) const base, which is 10 by default and must be between 2 and 36, or 0. Returns 0 if the conversion fails. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. If \a base is 0, the C language convention is used: If the string @@ -7407,7 +7407,7 @@ int QString::toInt(bool *ok, int base) const base, which is 10 by default and must be between 2 and 36, or 0. Returns 0 if the conversion fails. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. If \a base is 0, the C language convention is used: If the string @@ -7436,7 +7436,7 @@ uint QString::toUInt(bool *ok, int base) const base, which is 10 by default and must be between 2 and 36, or 0. Returns 0 if the conversion fails. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. If \a base is 0, the C language convention is used: If the string @@ -7465,7 +7465,7 @@ short QString::toShort(bool *ok, int base) const base, which is 10 by default and must be between 2 and 36, or 0. Returns 0 if the conversion fails. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. If \a base is 0, the C language convention is used: If the string @@ -7496,7 +7496,7 @@ ushort QString::toUShort(bool *ok, int base) const Returns an infinity if the conversion overflows or 0.0 if the conversion fails for other reasons (e.g. underflow). - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. \snippet qstring/main.cpp 66 @@ -7535,7 +7535,7 @@ double QString::toDouble(bool *ok) const Returns an infinity if the conversion overflows or 0.0 if the conversion fails for other reasons (e.g. underflow). - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. \warning The QString content may only contain valid numerical characters @@ -9440,11 +9440,11 @@ QString &QString::setRawData(const QChar *unicode, int size) The range \c{[first,last)} must remain valid for the lifetime of this Latin-1 string object. - Passing \c nullptr as \a first is safe if \a last is \c nullptr, + Passing \nullptr as \a first is safe if \a last is \nullptr, too, and results in a null Latin-1 string. The behavior is undefined if \a last precedes \a first, \a first - is \c nullptr and \a last is not, or if \c{last - first > + is \nullptr and \a last is not, or if \c{last - first > INT_MAX}. */ @@ -11933,7 +11933,7 @@ QStringRef QStringRef::trimmed() const base, which is 10 by default and must be between 2 and 36, or 0. Returns 0 if the conversion fails. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. If \a base is 0, the C language convention is used: If the string @@ -11958,7 +11958,7 @@ qint64 QStringRef::toLongLong(bool *ok, int base) const base, which is 10 by default and must be between 2 and 36, or 0. Returns 0 if the conversion fails. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. If \a base is 0, the C language convention is used: If the string @@ -11985,7 +11985,7 @@ quint64 QStringRef::toULongLong(bool *ok, int base) const base, which is 10 by default and must be between 2 and 36, or 0. Returns 0 if the conversion fails. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. If \a base is 0, the C language convention is used: If the string @@ -12012,7 +12012,7 @@ long QStringRef::toLong(bool *ok, int base) const base, which is 10 by default and must be between 2 and 36, or 0. Returns 0 if the conversion fails. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. If \a base is 0, the C language convention is used: If the string @@ -12038,7 +12038,7 @@ ulong QStringRef::toULong(bool *ok, int base) const base, which is 10 by default and must be between 2 and 36, or 0. Returns 0 if the conversion fails. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. If \a base is 0, the C language convention is used: If the string @@ -12063,7 +12063,7 @@ int QStringRef::toInt(bool *ok, int base) const base, which is 10 by default and must be between 2 and 36, or 0. Returns 0 if the conversion fails. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. If \a base is 0, the C language convention is used: If the string @@ -12088,7 +12088,7 @@ uint QStringRef::toUInt(bool *ok, int base) const base, which is 10 by default and must be between 2 and 36, or 0. Returns 0 if the conversion fails. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. If \a base is 0, the C language convention is used: If the string @@ -12113,7 +12113,7 @@ short QStringRef::toShort(bool *ok, int base) const base, which is 10 by default and must be between 2 and 36, or 0. Returns 0 if the conversion fails. - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. If \a base is 0, the C language convention is used: If the string @@ -12140,7 +12140,7 @@ ushort QStringRef::toUShort(bool *ok, int base) const Returns an infinity if the conversion overflows or 0.0 if the conversion fails for other reasons (e.g. underflow). - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. The string conversion will always happen in the 'C' locale. For locale @@ -12166,7 +12166,7 @@ double QStringRef::toDouble(bool *ok) const Returns an infinity if the conversion overflows or 0.0 if the conversion fails for other reasons (e.g. underflow). - If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + If \a ok is not \nullptr, failure is reported by setting *\a{ok} to \c false, and success by setting *\a{ok} to \c true. The string conversion will always happen in the 'C' locale. For locale diff --git a/src/corelib/tools/qstringview.cpp b/src/corelib/tools/qstringview.cpp index a7d9426fa6..b97e989110 100644 --- a/src/corelib/tools/qstringview.cpp +++ b/src/corelib/tools/qstringview.cpp @@ -232,9 +232,9 @@ QT_BEGIN_NAMESPACE The range \c{[str,len)} must remain valid for the lifetime of this string view object. - Passing \c nullptr as \a str is safe if \a len is 0, too, and results in a null string view. + Passing \nullptr as \a str is safe if \a len is 0, too, and results in a null string view. - The behavior is undefined if \a len is negative or, when positive, if \a str is \c nullptr. + The behavior is undefined if \a len is negative or, when positive, if \a str is \nullptr. This constructor only participates in overload resolution if \c Char is a compatible character type. The compatible character types are: \c QChar, \c ushort, \c char16_t and @@ -249,11 +249,11 @@ QT_BEGIN_NAMESPACE The range \c{[first,last)} must remain valid for the lifetime of this string view object. - Passing \c nullptr as \a first is safe if \a last is nullptr, too, + Passing \c \nullptr as \a first is safe if \a last is \nullptr, too, and results in a null string view. The behavior is undefined if \a last precedes \a first, or \a first - is \c nullptr and \a last is not. + is \nullptr and \a last is not. This constructor only participates in overload resolution if \c Char is a compatible character type. The compatible character types @@ -269,7 +269,7 @@ QT_BEGIN_NAMESPACE \a str must remain valid for the lifetime of this string view object. - Passing \c nullptr as \a str is safe and results in a null string view. + Passing \nullptr as \a str is safe and results in a null string view. This constructor only participates in overload resolution if \a str is not an array and if \c Char is a compatible character @@ -332,7 +332,7 @@ QT_BEGIN_NAMESPACE The string view will be empty if and only if \c{str.empty()}. It is unspecified whether this constructor can result in a null string view (\c{str.data()} would - have to return \c nullptr for this). + have to return \nullptr for this). \sa isNull(), isEmpty() */ From 5242126a610ebe76513cee22ecd8b5354bbf96b7 Mon Sep 17 00:00:00 2001 From: Lorn Potter <lorn.potter@gmail.com> Date: Tue, 17 Jul 2018 14:58:41 +1000 Subject: [PATCH 1195/1650] wasm: improve key handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow for extended non English keys Task-number: QTBUG-68189 Task-number: QTBUG-69392 Change-Id: I12187ebc1250a5c29022cd2d3ad3a77eb45c06a8 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io> --- .../platforms/wasm/qwasmeventtranslator.cpp | 540 +++++++++++++----- .../platforms/wasm/qwasmeventtranslator.h | 178 ++---- 2 files changed, 450 insertions(+), 268 deletions(-) diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp index df81413d5c..ddf0ff61e5 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp @@ -40,6 +40,9 @@ #include <QtCore/qobject.h> #include <QtCore/qdeadlinetimer.h> +#include <private/qmakearray_p.h> +#include <QtCore/qnamespace.h> + #include <emscripten/bind.h> #include <iostream> @@ -47,6 +50,257 @@ QT_BEGIN_NAMESPACE using namespace emscripten; +typedef struct emkb2qt { + const char *em; + unsigned int qt; + + constexpr bool operator <=(const emkb2qt &that) const noexcept + { + return !(strcmp(that) > 0); + } + + bool operator <(const emkb2qt &that) const noexcept + { + return ::strcmp(em, that.em) < 0; + } + constexpr int strcmp(const emkb2qt &that, const int i = 0) const + { + return em[i] == 0 && that.em[i] == 0 ? 0 + : em[i] == 0 ? -1 + : that.em[i] == 0 ? 1 + : em[i] < that.em[i] ? -1 + : em[i] > that.em[i] ? 1 + : strcmp(that, i + 1); + } +} emkb2qt_t; + +template<unsigned int Qt, char ... EmChar> +struct Emkb2Qt +{ + static constexpr const char storage[sizeof ... (EmChar) + 1] = {EmChar..., '\0'}; + using Type = emkb2qt_t; + static constexpr Type data() noexcept { return Type{storage, Qt}; } +}; + +template<unsigned int Qt, char ... EmChar> constexpr char Emkb2Qt<Qt, EmChar...>::storage[]; + +static constexpr const auto KeyTbl = qMakeArray( + QSortedData< + Emkb2Qt< Qt::Key_Escape, 'E','s','c','a','p','e' >, + Emkb2Qt< Qt::Key_Tab, 'T','a','b' >, + Emkb2Qt< Qt::Key_Backspace, 'B','a','c','k','s','p','a','c','e' >, + Emkb2Qt< Qt::Key_Return, 'E','n','t','e','r' >, + Emkb2Qt< Qt::Key_Insert, 'I','n','s','e','r','t' >, + Emkb2Qt< Qt::Key_Delete, 'D','e','l','e','t','e' >, + Emkb2Qt< Qt::Key_Pause, 'P','a','u','s','e' >, + Emkb2Qt< Qt::Key_Pause, 'C','l','e','a','r' >, + Emkb2Qt< Qt::Key_Home, 'H','o','m','e' >, + Emkb2Qt< Qt::Key_End, 'E','n','d' >, + Emkb2Qt< Qt::Key_Left, 'A','r','r','o','w','L','e','f','t' >, + Emkb2Qt< Qt::Key_Up, 'A','r','r','o','w','U','p' >, + Emkb2Qt< Qt::Key_Right, 'A','r','r','o','w','R','i','g','h','t' >, + Emkb2Qt< Qt::Key_Down, 'A','r','r','o','w','D','o','w','n' >, + Emkb2Qt< Qt::Key_PageUp, 'P','a','g','e','U','p' >, + Emkb2Qt< Qt::Key_PageDown, 'P','a','g','e','D','o','w','n' >, + Emkb2Qt< Qt::Key_Shift, 'S','h','i','f','t' >, + Emkb2Qt< Qt::Key_Control, 'C','o','n','t','r','o','l' >, + Emkb2Qt< Qt::Key_Meta, 'O','S'>, + Emkb2Qt< Qt::Key_Alt, 'A','l','t','L','e','f','t' >, + Emkb2Qt< Qt::Key_Alt, 'A','l','t' >, + Emkb2Qt< Qt::Key_CapsLock, 'C','a','p','s','L','o','c','k' >, + Emkb2Qt< Qt::Key_NumLock, 'N','u','m','L','o','c','k' >, + Emkb2Qt< Qt::Key_ScrollLock, 'S','c','r','o','l','l','L','o','c','k' >, + Emkb2Qt< Qt::Key_F1, 'F','1' >, + Emkb2Qt< Qt::Key_F2, 'F','2' >, + Emkb2Qt< Qt::Key_F3, 'F','3' >, + Emkb2Qt< Qt::Key_F4, 'F','4' >, + Emkb2Qt< Qt::Key_F5, 'F','5' >, + Emkb2Qt< Qt::Key_F6, 'F','6' >, + Emkb2Qt< Qt::Key_F7, 'F','7' >, + Emkb2Qt< Qt::Key_F8, 'F','8' >, + Emkb2Qt< Qt::Key_F9, 'F','9' >, + Emkb2Qt< Qt::Key_F10, 'F','1','0' >, + Emkb2Qt< Qt::Key_F11, 'F','1','1' >, + Emkb2Qt< Qt::Key_F12, 'F','1','2' >, + Emkb2Qt< Qt::Key_F13, 'F','1','3' >, + Emkb2Qt< Qt::Key_F14, 'F','1','4' >, + Emkb2Qt< Qt::Key_F15, 'F','1','5' >, + Emkb2Qt< Qt::Key_F16, 'F','1','6' >, + Emkb2Qt< Qt::Key_F17, 'F','1','7' >, + Emkb2Qt< Qt::Key_F18, 'F','1','8' >, + Emkb2Qt< Qt::Key_F19, 'F','1','9' >, + Emkb2Qt< Qt::Key_F20, 'F','2','0' >, + Emkb2Qt< Qt::Key_F21, 'F','2','1' >, + Emkb2Qt< Qt::Key_F22, 'F','2','2' >, + Emkb2Qt< Qt::Key_F23, 'F','2','3' >, + Emkb2Qt< Qt::Key_Space, ' ' >, + Emkb2Qt< Qt::Key_Comma, ',' >, + Emkb2Qt< Qt::Key_Minus, '-' >, + Emkb2Qt< Qt::Key_Period, '.' >, + Emkb2Qt< Qt::Key_Slash, '/' >, + Emkb2Qt< Qt::Key_0, '0' >, + Emkb2Qt< Qt::Key_1, '1' >, + Emkb2Qt< Qt::Key_2, '2' >, + Emkb2Qt< Qt::Key_3, '3' >, + Emkb2Qt< Qt::Key_4, '4' >, + Emkb2Qt< Qt::Key_5, '5' >, + Emkb2Qt< Qt::Key_6, '6' >, + Emkb2Qt< Qt::Key_7, '7' >, + Emkb2Qt< Qt::Key_8, '8' >, + Emkb2Qt< Qt::Key_9, '9' >, + Emkb2Qt< Qt::Key_Semicolon, ';' >, + Emkb2Qt< Qt::Key_Equal, '=' >, + Emkb2Qt< Qt::Key_A, 'K','e','y','A' >, + Emkb2Qt< Qt::Key_B, 'K','e','y','B' >, + Emkb2Qt< Qt::Key_C, 'K','e','y','C' >, + Emkb2Qt< Qt::Key_D, 'K','e','y','D' >, + Emkb2Qt< Qt::Key_E, 'K','e','y','E' >, + Emkb2Qt< Qt::Key_F, 'K','e','y','F' >, + Emkb2Qt< Qt::Key_G, 'K','e','y','G' >, + Emkb2Qt< Qt::Key_H, 'K','e','y','H' >, + Emkb2Qt< Qt::Key_I, 'K','e','y','I' >, + Emkb2Qt< Qt::Key_J, 'K','e','y','J' >, + Emkb2Qt< Qt::Key_K, 'K','e','y','K' >, + Emkb2Qt< Qt::Key_L, 'K','e','y','L' >, + Emkb2Qt< Qt::Key_M, 'K','e','y','M' >, + Emkb2Qt< Qt::Key_N, 'K','e','y','N' >, + Emkb2Qt< Qt::Key_O, 'K','e','y','O' >, + Emkb2Qt< Qt::Key_P, 'K','e','y','P' >, + Emkb2Qt< Qt::Key_Q, 'K','e','y','Q' >, + Emkb2Qt< Qt::Key_R, 'K','e','y','R' >, + Emkb2Qt< Qt::Key_S, 'K','e','y','S' >, + Emkb2Qt< Qt::Key_T, 'K','e','y','T' >, + Emkb2Qt< Qt::Key_U, 'K','e','y','U' >, + Emkb2Qt< Qt::Key_V, 'K','e','y','V' >, + Emkb2Qt< Qt::Key_W, 'K','e','y','W' >, + Emkb2Qt< Qt::Key_X, 'K','e','y','X' >, + Emkb2Qt< Qt::Key_Y, 'K','e','y','Y' >, + Emkb2Qt< Qt::Key_Z, 'K','e','y','Z' >, + Emkb2Qt< Qt::Key_BracketLeft, '[' >, + Emkb2Qt< Qt::Key_Backslash, '\\' >, + Emkb2Qt< Qt::Key_BracketRight, ']' >, + Emkb2Qt< Qt::Key_Apostrophe, '\'' >, + Emkb2Qt< Qt::Key_QuoteLeft, 'B','a','c','k','q','u','o','t','e' >, + Emkb2Qt< Qt::Key_multiply, 'N','u','m','p','a','d','M','u','l','t','i','p','l','y' >, + Emkb2Qt< Qt::Key_Minus, 'N','u','m','p','a','d','S','u','b','t','r','a','c','t' >, + Emkb2Qt< Qt::Key_Period, 'N','u','m','p','a','d','D','e','c','i','m','a','l' >, + Emkb2Qt< Qt::Key_Plus, 'N','u','m','p','a','d','A','d','d' >, + Emkb2Qt< Qt::Key_division, 'N','u','m','p','a','d','D','i','v','i','d','e' >, + Emkb2Qt< Qt::Key_Equal, 'N','u','m','p','a','d','E','q','u','a','l' >, + Emkb2Qt< Qt::Key_0, 'N','u','m','p','a','d','0' >, + Emkb2Qt< Qt::Key_1, 'N','u','m','p','a','d','1' >, + Emkb2Qt< Qt::Key_2, 'N','u','m','p','a','d','2' >, + Emkb2Qt< Qt::Key_3, 'N','u','m','p','a','d','3' >, + Emkb2Qt< Qt::Key_4, 'N','u','m','p','a','d','4' >, + Emkb2Qt< Qt::Key_5, 'N','u','m','p','a','d','5' >, + Emkb2Qt< Qt::Key_6, 'N','u','m','p','a','d','6' >, + Emkb2Qt< Qt::Key_7, 'N','u','m','p','a','d','7' >, + Emkb2Qt< Qt::Key_8, 'N','u','m','p','a','d','8' >, + Emkb2Qt< Qt::Key_9, 'N','u','m','p','a','d','9' >, + Emkb2Qt< Qt::Key_Comma, 'N','u','m','p','a','d','C','o','m','m','a' >, + Emkb2Qt< Qt::Key_Enter, 'N','u','m','p','a','d','E','n','t','e','r' >, + Emkb2Qt< Qt::Key_Paste, 'P','a','s','t','e' >, + Emkb2Qt< Qt::Key_AltGr, 'A','l','t','R','i','g','h','t' >, + Emkb2Qt< Qt::Key_Help, 'H','e','l','p' >, + Emkb2Qt< Qt::Key_Equal, '=' >, + Emkb2Qt< Qt::Key_yen, 'I','n','t','l','Y','e','n' >, + + Emkb2Qt< Qt::Key_Exclam, '\x21' >, + Emkb2Qt< Qt::Key_QuoteDbl, '\x22' >, + Emkb2Qt< Qt::Key_NumberSign, '\x23' >, + Emkb2Qt< Qt::Key_Dollar, '\x24' >, + Emkb2Qt< Qt::Key_Percent, '\x25' >, + Emkb2Qt< Qt::Key_Ampersand, '\x26' >, + Emkb2Qt< Qt::Key_ParenLeft, '\x28' >, + Emkb2Qt< Qt::Key_ParenRight, '\x29' >, + Emkb2Qt< Qt::Key_Asterisk, '\x2a' >, + Emkb2Qt< Qt::Key_Plus, '\x2b' >, + Emkb2Qt< Qt::Key_Colon, '\x3a' >, + Emkb2Qt< Qt::Key_Semicolon, '\x3b' >, + Emkb2Qt< Qt::Key_Less, '\x3c' >, + Emkb2Qt< Qt::Key_Equal, '\x3d' >, + Emkb2Qt< Qt::Key_Greater, '\x3e' >, + Emkb2Qt< Qt::Key_Question, '\x3f' >, + Emkb2Qt< Qt::Key_At, '\x40' >, + Emkb2Qt< Qt::Key_BracketLeft, '\x5b' >, + Emkb2Qt< Qt::Key_Backslash, '\x5c' >, + Emkb2Qt< Qt::Key_BracketRight, '\x5d' >, + Emkb2Qt< Qt::Key_AsciiCircum, '\x5e' >, + Emkb2Qt< Qt::Key_Underscore, '\x5f' >, + Emkb2Qt< Qt::Key_QuoteLeft, '\x60'>, + Emkb2Qt< Qt::Key_BraceLeft, '\x7b'>, + Emkb2Qt< Qt::Key_Bar, '\x7c'>, + Emkb2Qt< Qt::Key_BraceRight, '\x7d'>, + Emkb2Qt< Qt::Key_AsciiTilde, '\x7e'>, + Emkb2Qt< Qt::Key_Space, '\x20' >, + Emkb2Qt< Qt::Key_Comma, '\x2c' >, + Emkb2Qt< Qt::Key_Minus, '\x2d' >, + Emkb2Qt< Qt::Key_Period, '\x2e' >, + Emkb2Qt< Qt::Key_Slash, '\x2f' >, + Emkb2Qt< Qt::Key_Apostrophe, '\x27' >, + Emkb2Qt< Qt::Key_Menu, 'C','o','n','t','e','x','t','M','e','n','u' >, + + Emkb2Qt< Qt::Key_Agrave, '\xc3','\xa0' >, + Emkb2Qt< Qt::Key_Aacute, '\xc3','\xa1' >, + Emkb2Qt< Qt::Key_Acircumflex, '\xc3','\xa2' >, + Emkb2Qt< Qt::Key_Adiaeresis, '\xc3','\xa4' >, + Emkb2Qt< Qt::Key_AE, '\xc3','\xa6' >, + Emkb2Qt< Qt::Key_Atilde, '\xc3','\xa3' >, + Emkb2Qt< Qt::Key_Aring, '\xc3','\xa5' >, + Emkb2Qt< Qt::Key_Ccedilla, '\xc3','\xa7' >, + Emkb2Qt< Qt::Key_Egrave, '\xc3','\xa8' >, + Emkb2Qt< Qt::Key_Eacute, '\xc3','\xa9' >, + Emkb2Qt< Qt::Key_Ecircumflex, '\xc3','\xaa' >, + Emkb2Qt< Qt::Key_Ediaeresis, '\xc3','\xab' >, + Emkb2Qt< Qt::Key_Icircumflex, '\xc3','\xae' >, + Emkb2Qt< Qt::Key_Idiaeresis, '\xc3','\xaf' >, + Emkb2Qt< Qt::Key_Ocircumflex, '\xc3','\xb4' >, + Emkb2Qt< Qt::Key_Odiaeresis, '\xc3','\xb6' >, + Emkb2Qt< Qt::Key_Ograve, '\xc3','\xb2' >, + Emkb2Qt< Qt::Key_Oacute, '\xc3','\xb3' >, + Emkb2Qt< Qt::Key_Ooblique, '\xc3','\xb8' >, + Emkb2Qt< Qt::Key_Otilde, '\xc3','\xb5' >, + Emkb2Qt< Qt::Key_Ucircumflex, '\xc3','\xbb' >, + Emkb2Qt< Qt::Key_Udiaeresis, '\xc3','\xbc' >, + Emkb2Qt< Qt::Key_Ugrave, '\xc3','\xb9' >, + Emkb2Qt< Qt::Key_Uacute, '\xc3','\xba' >, + Emkb2Qt< Qt::Key_Ntilde, '\xc3','\xb1' >, + Emkb2Qt< Qt::Key_ydiaeresis, '\xc3','\xbf' > + >::Data{} + ); + +static constexpr const auto DeadKeyShiftTbl = qMakeArray( + QSortedData< + // shifted + Emkb2Qt< Qt::Key_Agrave, '\xc3','\x80' >, + Emkb2Qt< Qt::Key_Aacute, '\xc3','\x81' >, + Emkb2Qt< Qt::Key_Acircumflex, '\xc3','\x82' >, + Emkb2Qt< Qt::Key_Adiaeresis, '\xc3','\x84' >, + Emkb2Qt< Qt::Key_AE, '\xc3','\x86' >, + Emkb2Qt< Qt::Key_Atilde, '\xc3','\x83' >, + Emkb2Qt< Qt::Key_Aring, '\xc3','\x85' >, + Emkb2Qt< Qt::Key_Egrave, '\xc3','\x88' >, + Emkb2Qt< Qt::Key_Eacute, '\xc3','\x89' >, + Emkb2Qt< Qt::Key_Ecircumflex, '\xc3','\x8a' >, + Emkb2Qt< Qt::Key_Ediaeresis, '\xc3','\x8b' >, + Emkb2Qt< Qt::Key_Icircumflex, '\xc3','\x8e' >, + Emkb2Qt< Qt::Key_Idiaeresis, '\xc3','\x8f' >, + Emkb2Qt< Qt::Key_Ocircumflex, '\xc3','\x94' >, + Emkb2Qt< Qt::Key_Odiaeresis, '\xc3','\x96' >, + Emkb2Qt< Qt::Key_Ograve, '\xc3','\x92' >, + Emkb2Qt< Qt::Key_Oacute, '\xc3','\x93' >, + Emkb2Qt< Qt::Key_Ooblique, '\xc3','\x98' >, + Emkb2Qt< Qt::Key_Otilde, '\xc3','\x95' >, + Emkb2Qt< Qt::Key_Ucircumflex, '\xc3','\x9b' >, + Emkb2Qt< Qt::Key_Udiaeresis, '\xc3','\x9c' >, + Emkb2Qt< Qt::Key_Ugrave, '\xc3','\x99' >, + Emkb2Qt< Qt::Key_Uacute, '\xc3','\x9a' >, + Emkb2Qt< Qt::Key_Ntilde, '\xc3','\x91' >, + Emkb2Qt< Qt::Key_Ccedilla, '\xc3','\x87' >, + Emkb2Qt< Qt::Key_ydiaeresis, '\xc3','\x8f' > + >::Data{} +); + // macOS CTRL <-> META switching. We most likely want to enable // the existing switching code in QtGui, but for now do it here. static bool g_usePlatformMacCtrlMetaSwitching = false; @@ -155,148 +409,44 @@ QFlags<Qt::KeyboardModifier> QWasmEventTranslator::translateMouseEventModifier(c int QWasmEventTranslator::keyboard_cb(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData) { - Q_UNUSED(userData) - - bool alphanumeric; - Qt::Key qtKey = translateEmscriptKey(keyEvent, &alphanumeric); - - QEvent::Type keyType = QEvent::None; - switch (eventType) { - case EMSCRIPTEN_EVENT_KEYPRESS: - case EMSCRIPTEN_EVENT_KEYDOWN: //down - keyType = QEvent::KeyPress; - break; - case EMSCRIPTEN_EVENT_KEYUP: //up - keyType = QEvent::KeyRelease; - break; - default: - break; - }; - - if (keyType == QEvent::None) - return 0; - - QFlags<Qt::KeyboardModifier> mods = translateKeyboardEventModifier(keyEvent); - bool accepted = false; - - if (keyType == QEvent::KeyPress && - mods.testFlag(Qt::ControlModifier) - && qtKey == Qt::Key_V) { - QWasmIntegration::get()->getWasmClipboard()->readTextFromClipboard(); - } else { - QString keyText = alphanumeric ? QString(keyEvent->key) : QString(); - accepted = QWindowSystemInterface::handleKeyEvent<QWindowSystemInterface::SynchronousDelivery>( - 0, keyType, qtKey, translateKeyboardEventModifier(keyEvent), keyText); - } - - if (keyType == QEvent::KeyPress && - mods.testFlag(Qt::ControlModifier) - && qtKey == Qt::Key_C) { - QWasmIntegration::get()->getWasmClipboard()->writeTextToClipboard(); - } - QWasmEventDispatcher::maintainTimers(); + QWasmEventTranslator *wasmTranslator = reinterpret_cast<QWasmEventTranslator *>(userData); + bool accepted = wasmTranslator->processKeyboard(eventType, keyEvent); return accepted ? 1 : 0; } -Qt::Key QWasmEventTranslator::translateEmscriptKey(const EmscriptenKeyboardEvent *emscriptKey, bool *outAlphanumeric) +Qt::Key QWasmEventTranslator::translateEmscriptKey(const EmscriptenKeyboardEvent *emscriptKey) { - Qt::Key qtKey; - if (outAlphanumeric) - *outAlphanumeric = false; + Qt::Key qtKey = Qt::Key_unknown; - switch (emscriptKey->keyCode) { - case KeyMultiply: qtKey = Qt::Key_Asterisk; *outAlphanumeric = true; break; - case KeyAdd: qtKey = Qt::Key_Plus; *outAlphanumeric = true; break; - case KeyMinus: qtKey = Qt::Key_Minus; *outAlphanumeric = true; break; - case KeySubtract: qtKey = Qt::Key_Minus; *outAlphanumeric = true; break; - case KeyDecimal: qtKey = Qt::Key_Period; *outAlphanumeric = true; break; - case KeyDivide: qtKey = Qt::Key_Slash; *outAlphanumeric = true; break; - case KeyNumPad0: qtKey = Qt::Key_0; *outAlphanumeric = true; break; - case KeyNumPad1: qtKey = Qt::Key_1; *outAlphanumeric = true; break; - case KeyNumPad2: qtKey = Qt::Key_2; *outAlphanumeric = true; break; - case KeyNumPad3: qtKey = Qt::Key_3; *outAlphanumeric = true; break; - case KeyNumPad4: qtKey = Qt::Key_4; *outAlphanumeric = true; break; - case KeyNumPad5: qtKey = Qt::Key_5; *outAlphanumeric = true; break; - case KeyNumPad6: qtKey = Qt::Key_6; *outAlphanumeric = true; break; - case KeyNumPad7: qtKey = Qt::Key_7; *outAlphanumeric = true; break; - case KeyNumPad8: qtKey = Qt::Key_8; *outAlphanumeric = true; break; - case KeyNumPad9: qtKey = Qt::Key_9; *outAlphanumeric = true; break; - case KeyComma: qtKey = Qt::Key_Comma; *outAlphanumeric = true; break; - case KeyPeriod: qtKey = Qt::Key_Period; *outAlphanumeric = true; break; - case KeySlash: qtKey = Qt::Key_Slash; *outAlphanumeric = true; break; - case KeySemiColon: qtKey = Qt::Key_Semicolon; *outAlphanumeric = true; break; - case KeyEquals: qtKey = Qt::Key_Equal; *outAlphanumeric = true; break; - case KeyOpenBracket: qtKey = Qt::Key_BracketLeft; *outAlphanumeric = true; break; - case KeyCloseBracket: qtKey = Qt::Key_BracketRight; *outAlphanumeric = true; break; - case KeyBackSlash: qtKey = Qt::Key_Backslash; *outAlphanumeric = true; break; - case KeyMeta: - Q_FALLTHROUGH(); - case KeyMetaRight: - qtKey = Qt::Key_Meta; - break; - case KeyTab: qtKey = Qt::Key_Tab; break; - case KeyClear: qtKey = Qt::Key_Clear; break; - case KeyBackSpace: qtKey = Qt::Key_Backspace; break; - case KeyEnter: qtKey = Qt::Key_Return; break; - case KeyShift: qtKey = Qt::Key_Shift; break; - case KeyControl: qtKey = Qt::Key_Control; break; - case KeyAlt: qtKey = Qt::Key_Alt; break; - case KeyCapsLock: qtKey = Qt::Key_CapsLock; break; - case KeyEscape: qtKey = Qt::Key_Escape; break; - case KeyPageUp: qtKey = Qt::Key_PageUp; break; - case KeyPageDown: qtKey = Qt::Key_PageDown; break; - case KeyEnd: qtKey = Qt::Key_End; break; - case KeyHome: qtKey = Qt::Key_Home; break; - case KeyLeft: qtKey = Qt::Key_Left; break; - case KeyUp: qtKey = Qt::Key_Up; break; - case KeyRight: qtKey = Qt::Key_Right; break; - case KeyDown: qtKey = Qt::Key_Down; break; - case KeyBrightnessDown: qtKey = Qt::Key_MonBrightnessDown; break; - case KeyBrightnessUp: qtKey = Qt::Key_MonBrightnessUp; break; - case KeyMediaTrackPrevious: qtKey = Qt::Key_MediaPrevious; break; - case KeyMediaPlayPause: qtKey = Qt::Key_MediaTogglePlayPause; break; - case KeyMediaTrackNext: qtKey = Qt::Key_MediaNext; break; - case KeyAudioVolumeMute: qtKey = Qt::Key_VolumeMute; break; - case KeyAudioVolumeDown: qtKey = Qt::Key_VolumeDown; break; - case KeyAudioVolumeUp: qtKey = Qt::Key_VolumeUp; break; - case KeyDelete: qtKey = Qt::Key_Delete; break; + if (qstrncmp(emscriptKey->code, "Key", 3) == 0 || qstrncmp(emscriptKey->code, "Numpad", 6) == 0) { - case KeyF1: qtKey = Qt::Key_F1; break; - case KeyF2: qtKey = Qt::Key_F2; break; - case KeyF3: qtKey = Qt::Key_F3; break; - case KeyF4: qtKey = Qt::Key_F4; break; - case KeyF5: qtKey = Qt::Key_F5; break; - case KeyF6: qtKey = Qt::Key_F6; break; - case KeyF7: qtKey = Qt::Key_F7; break; - case KeyF8: qtKey = Qt::Key_F8; break; - case KeyF9: qtKey = Qt::Key_F9; break; - case KeyF10: qtKey = Qt::Key_F10; break; - case KeyF11: qtKey = Qt::Key_F11; break; - case KeyF12: qtKey = Qt::Key_F12; break; - case 124: qtKey = Qt::Key_F13; break; - case 125: qtKey = Qt::Key_F14; break; - - case KeySpace: - default: - if (outAlphanumeric) - *outAlphanumeric = true; - qtKey = static_cast<Qt::Key>(emscriptKey->keyCode); - break; + emkb2qt_t searchKey{emscriptKey->code, 0}; // search emcsripten code + auto it1 = std::lower_bound(KeyTbl.cbegin(), KeyTbl.cend(), searchKey); + if (it1 != KeyTbl.end() && !(searchKey < *it1)) { + qtKey = static_cast<Qt::Key>(it1->qt); + } + } else if (qstrncmp(emscriptKey->key, "Dead", 4) == 0 ) { + emkb2qt_t searchKey1{emscriptKey->code, 0}; + for (auto it1 = KeyTbl.cbegin(); it1 != KeyTbl.end(); ++it1) + if (it1 != KeyTbl.end() && (qstrcmp(searchKey1.em, it1->em) == 0)) { + qtKey = static_cast<Qt::Key>(it1->qt); + } } - // Handle Mac command key. Using event->keyCode as above is - // no reliable since the codes differ between browsers. - if (qstrncmp(emscriptKey->key, "Meta", 4) == 0) { - qtKey = Qt::Key_Meta; - *outAlphanumeric = false; + if (qtKey == Qt::Key_unknown) { + emkb2qt_t searchKey{emscriptKey->key, 0}; // search unicode key + auto it1 = std::lower_bound(KeyTbl.cbegin(), KeyTbl.cend(), searchKey); + if (it1 != KeyTbl.end() && !(searchKey < *it1)) { + qtKey = static_cast<Qt::Key>(it1->qt); + } } - - if (g_usePlatformMacCtrlMetaSwitching) { - if (qtKey == Qt::Key_Meta) - qtKey = Qt::Key_Control; - else if (qtKey == Qt::Key_Control) - qtKey = Qt::Key_Meta; + if (qtKey == Qt::Key_unknown) {//try harder with shifted number keys + emkb2qt_t searchKey1{emscriptKey->key, 0}; + for (auto it1 = KeyTbl.cbegin(); it1 != KeyTbl.end(); ++it1) + if (it1 != KeyTbl.end() && (qstrcmp(searchKey1.em, it1->em) == 0)) { + qtKey = static_cast<Qt::Key>(it1->qt); + } } return qtKey; @@ -481,7 +631,6 @@ int QWasmEventTranslator::focus_cb(int /*eventType*/, const EmscriptenFocusEvent int QWasmEventTranslator::wheel_cb(int eventType, const EmscriptenWheelEvent *wheelEvent, void *userData) { Q_UNUSED(eventType) - Q_UNUSED(userData) EmscriptenMouseEvent mouseEvent = wheelEvent->mouse; @@ -501,7 +650,8 @@ int QWasmEventTranslator::wheel_cb(int eventType, const EmscriptenWheelEvent *wh if (g_useNaturalScrolling) //macOS platform has document oriented scrolling scrollFactor = -scrollFactor; - Qt::KeyboardModifiers modifiers = translateMouseEventModifier(&mouseEvent); + QWasmEventTranslator *translator = (QWasmEventTranslator*)userData; + Qt::KeyboardModifiers modifiers = translator->translateMouseEventModifier(&mouseEvent); auto timestamp = mouseEvent.timestamp; QPoint globalPoint(mouseEvent.canvasX, mouseEvent.canvasY); @@ -514,8 +664,8 @@ int QWasmEventTranslator::wheel_cb(int eventType, const EmscriptenWheelEvent *wh if (wheelEvent->deltaY != 0) pixelDelta.setY(wheelEvent->deltaY * scrollFactor); if (wheelEvent->deltaX != 0) pixelDelta.setX(wheelEvent->deltaX * scrollFactor); - QWindowSystemInterface::handleWheelEvent(window2, timestamp, localPoint, globalPoint, QPoint(), pixelDelta, modifiers); - + QWindowSystemInterface::handleWheelEvent(window2, timestamp, localPoint, + globalPoint, QPoint(), pixelDelta, modifiers); QWasmEventDispatcher::maintainTimers(); return 1; @@ -562,12 +712,16 @@ int QWasmEventTranslator::touchCallback(int eventType, const EmscriptenTouchEven } QWasmEventTranslator *wasmEventTranslator = (QWasmEventTranslator*)userData; - QFlags<Qt::KeyboardModifier> keyModifier = translatKeyModifier(touchEvent); + QFlags<Qt::KeyboardModifier> keyModifier = wasmEventTranslator->translatKeyModifier(touchEvent); if (eventType != EMSCRIPTEN_EVENT_TOUCHCANCEL) - QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::SynchronousDelivery>(window2, wasmEventTranslator->getTimestamp(), wasmEventTranslator->touchDevice, touchPointList, keyModifier); + QWindowSystemInterface::handleTouchEvent + <QWindowSystemInterface::SynchronousDelivery>(window2, wasmEventTranslator->getTimestamp(), + wasmEventTranslator->touchDevice, + touchPointList, keyModifier); else - QWindowSystemInterface::handleTouchCancelEvent(window2, wasmEventTranslator->getTimestamp(), wasmEventTranslator->touchDevice, keyModifier); + QWindowSystemInterface::handleTouchCancelEvent(window2, wasmEventTranslator->getTimestamp(), + wasmEventTranslator->touchDevice, keyModifier); QWasmEventDispatcher::maintainTimers(); return 1; @@ -578,4 +732,112 @@ quint64 QWasmEventTranslator::getTimestamp() return QDeadlineTimer::current().deadlineNSecs() / 1000; } +Qt::Key QWasmEventTranslator::translateDeadKey(Qt::Key deadKey, Qt::Key accentBaseKey) +{ + Qt::Key wasmKey = Qt::Key_unknown; + switch (deadKey) { +#ifdef Q_OS_MACOS + case Qt::Key_QuoteLeft: // ` macOS: Key_Dead_Grave +#else + case Qt::Key_O: // ´ Key_Dead_Grave +#endif + wasmKey = graveKeyTable.value(accentBaseKey); + break; + case Qt::Key_E: // ´ Key_Dead_Acute + wasmKey = acuteKeyTable.value(accentBaseKey); + break; + case Qt::Key_AsciiTilde: + case Qt::Key_N:// Key_Dead_Tilde + wasmKey = tildeKeyTable.value(accentBaseKey); + break; +#ifndef Q_OS_MACOS + case Qt::Key_QuoteLeft: +#endif + case Qt::Key_U:// ¨ Key_Dead_Diaeresis + wasmKey = diaeresisKeyTable.value(accentBaseKey); + break; + case Qt::Key_I:// macOS Key_Dead_Circumflex + case Qt::Key_6:// linux + case Qt::Key_Apostrophe:// linux + wasmKey = circumflexKeyTable.value(accentBaseKey); + break; + break; + default: + break; + }; + + return wasmKey; +} + +bool QWasmEventTranslator::processKeyboard(int eventType, const EmscriptenKeyboardEvent *keyEvent) +{ + Qt::Key qtKey = translateEmscriptKey(keyEvent); + + Qt::KeyboardModifiers modifiers = translateKeyboardEventModifier(keyEvent); + + QString keyText; + QEvent::Type keyType = QEvent::None; + switch (eventType) { + case EMSCRIPTEN_EVENT_KEYPRESS: + case EMSCRIPTEN_EVENT_KEYDOWN: // down + keyType = QEvent::KeyPress; + + if (m_emDeadKey != Qt::Key_unknown) { + + Qt::Key transformedKey = translateDeadKey(m_emDeadKey, qtKey); + + if (transformedKey != Qt::Key_unknown) + qtKey = transformedKey; + + if (keyEvent->shiftKey == 0) { + for (auto it = KeyTbl.cbegin(); it != KeyTbl.end(); ++it) { + if (it != KeyTbl.end() && (qtKey == static_cast<Qt::Key>(it->qt))) { + keyText = it->em; + m_emDeadKey = Qt::Key_unknown; + break; + } + } + } else { + for (auto it = DeadKeyShiftTbl.cbegin(); it != DeadKeyShiftTbl.end(); ++it) { + if (it != DeadKeyShiftTbl.end() && (qtKey == static_cast<Qt::Key>(it->qt))) { + keyText = it->em; + m_emDeadKey = Qt::Key_unknown; + break; + } + } + } + } + if (qstrncmp(keyEvent->key, "Dead", 4) == 0 || qtKey == Qt::Key_AltGr) { + qtKey = translateEmscriptKey(keyEvent); + m_emStickyDeadKey = true; + if (keyEvent->shiftKey == 1 && qtKey == Qt::Key_QuoteLeft) + qtKey = Qt::Key_AsciiTilde; + m_emDeadKey = qtKey; + } + break; + case EMSCRIPTEN_EVENT_KEYUP: // up + keyType = QEvent::KeyRelease; + if (m_emStickyDeadKey && qtKey != Qt::Key_Alt) { + m_emStickyDeadKey = false; + } + break; + default: + break; + }; + + if (keyType == QEvent::None) + return 0; + + bool accepted = false; + + if (keyText.isEmpty()) + keyText = QString(keyEvent->key); + if (keyText.size() > 1) + keyText.clear(); + accepted = QWindowSystemInterface::handleKeyEvent<QWindowSystemInterface::SynchronousDelivery>( + 0, keyType, qtKey, modifiers, keyText); + QWasmEventDispatcher::maintainTimers(); + return accepted ? 1 : 0; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.h b/src/plugins/platforms/wasm/qwasmeventtranslator.h index f3dff8e48c..25e2a630b6 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.h +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.h @@ -36,6 +36,7 @@ #include <emscripten/html5.h> #include "qwasmwindow.h" #include <QtGui/qtouchdevice.h> +#include <QHash> QT_BEGIN_NAMESPACE @@ -45,130 +46,6 @@ class QWasmEventTranslator : public QObject { Q_OBJECT - enum KeyCode { - // numpad - KeyNumPad0 = 0x60, - KeyNumPad1 = 0x61, - KeyNumPad2 = 0x62, - KeyNumPad3 = 0x63, - KeyNumPad4 = 0x64, - KeyNumPad5 = 0x65, - KeyNumPad6 = 0x66, - KeyNumPad7 = 0x67, - KeyNumPad8 = 0x68, - KeyNumPad9 = 0x69, - KeyMultiply = 0x6A, - KeyAdd = 0x6B, - KeySeparator = 0x6C, - KeySubtract = 0x6D, - KeyDecimal = 0x6E, - KeyDivide = 0x6F, - KeyMeta = 0x5B, - KeyMetaRight = 0x5C, - //////// - KeyClear = 0x90, - KeyEnter = 0xD, - KeyBackSpace = 0x08, - KeyCancel = 0x03, - KeyTab = 0x09, - KeyShift = 0x10, - KeyControl = 0x11, - KeyAlt = 0x12, - KeyPause = 0x13, - KeyCapsLock = 0x14, - KeyEscape = 0x1B, - KeySpace = 0x20, - KeyPageUp = 0x21, - KeyPageDown = 0x22, - KeyEnd = 0x23, - KeyHome = 0x24, - KeyLeft = 0x25, - KeyUp = 0x26, - KeyRight = 0x27, - KeyDown = 0x28, - KeyComma = 0xBC, - KeyPeriod = 0xBE, - KeySlash = 0xBF, - KeyZero = 0x30, - KeyOne = 0x31, - KeyTwo = 0x32, - KeyThree = 0x33, - KeyFour = 0x34, - KeyFive = 0x35, - KeySix = 0x36, - KeySeven = 0x37, - KeyEight = 0x38, - KeyNine = 0x39, - KeyBrightnessDown = 0xD8, - KeyBrightnessUp = 0xD9, - KeyMediaTrackPrevious = 0xB1, - KeyMediaPlayPause = 0xB3, - KeyMediaTrackNext = 0xB0, - KeyAudioVolumeMute = 0xAD, - KeyAudioVolumeDown = 0xAE, - KeyAudioVolumeUp = 0xAF, - KeySemiColon = 0xBA, - KeyEquals = 0xBB, - KeyMinus = 0xBD, - KeyA = 0x41, - KeyB = 0x42, - KeyC = 0x43, - KeyD = 0x44, - KeyE = 0x45, - KeyF = 0x46, - KeyG = 0x47, - KeyH = 0x48, - KeyI = 0x49, - KeyJ = 0x4A, - KeyK = 0x4B, - KeyL = 0x4C, - KeyM = 0x4D, - KeyN = 0x4E, - KeyO = 0x4F, - KeyP = 0x50, - KeyQ = 0x51, - KeyR = 0x52, - KeyS = 0x53, - KeyT = 0x54, - KeyU = 0x55, - KeyV = 0x56, - KeyW = 0x57, - KeyX = 0x58, - KeyY = 0x59, - KeyZ = 0x5A, - KeyOpenBracket = 0xDB, - KeyBackSlash = 0xDC, - KeyCloseBracket = 0xDD, - KeyF1 = 0x70, - KeyF2 = 0x71, - KeyF3 = 0x72, - KeyF4 = 0x73, - KeyF5 = 0x74, - KeyF6 = 0x75, - KeyF7 = 0x76, - KeyF8 = 0x77, - KeyF9 = 0x78, - KeyF10 = 0x79, - KeyF11 = 0x7A, - KeyF12 = 0x7B, - KeyDelete = 0x2E, - KeyNumLock = 0x90, - KeyScrollLock = 0x91, - KeyPrintScreen = 0x9A, - KeyInsert = 0x9B, - KeyHelp = 0x9C, - KeyBackQuote = 0xC0, - KeyQuote = 0xDE, - KeyFinal = 0x18, - KeyConvert = 0x1C, - KeyNonConvert = 0x1D, - KeyAccept = 0x1E, - KeyModeChange = 0x1F, - KeyKana = 0x15, - KeyKanji = 0x19, - KeyUndefined = 0x0 - }; - public: explicit QWasmEventTranslator(QObject *parent = 0); @@ -185,14 +62,54 @@ public: Q_SIGNALS: void getWindowAt(const QPoint &point, QWindow **window); private: - static Qt::Key translateEmscriptKey(const EmscriptenKeyboardEvent *emscriptKey, bool *outAlphanumretic); + + Qt::Key translateEmscriptKey(const EmscriptenKeyboardEvent *emscriptKey); template <typename Event> - static QFlags<Qt::KeyboardModifier> translatKeyModifier(const Event *event); - static QFlags<Qt::KeyboardModifier> translateKeyboardEventModifier(const EmscriptenKeyboardEvent *keyEvent); - static QFlags<Qt::KeyboardModifier> translateMouseEventModifier(const EmscriptenMouseEvent *mouseEvent); - static Qt::MouseButton translateMouseButton(unsigned short button); + QFlags<Qt::KeyboardModifier> translatKeyModifier(const Event *event); + QFlags<Qt::KeyboardModifier> translateKeyboardEventModifier(const EmscriptenKeyboardEvent *keyEvent); + QFlags<Qt::KeyboardModifier> translateMouseEventModifier(const EmscriptenMouseEvent *mouseEvent); + Qt::MouseButton translateMouseButton(unsigned short button); void processMouse(int eventType, const EmscriptenMouseEvent *mouseEvent); + bool processKeyboard(int eventType, const EmscriptenKeyboardEvent *keyEvent); + + Qt::Key translateDeadKey(Qt::Key deadKey, Qt::Key accentBaseKey); + + QHash<Qt::Key , Qt::Key> tildeKeyTable { // ~ + { Qt::Key_A, Qt::Key_Atilde}, + { Qt::Key_N, Qt::Key_Ntilde}, + { Qt::Key_O, Qt::Key_Otilde} + }; + QHash<Qt::Key , Qt::Key> graveKeyTable { // ` + { Qt::Key_A, Qt::Key_Agrave}, + { Qt::Key_E, Qt::Key_Egrave}, + { Qt::Key_I, Qt::Key_Igrave}, + { Qt::Key_O, Qt::Key_Ograve}, + { Qt::Key_U, Qt::Key_Ugrave} + }; + QHash<Qt::Key , Qt::Key> acuteKeyTable { // ' + { Qt::Key_A, Qt::Key_Aacute}, + { Qt::Key_E, Qt::Key_Eacute}, + { Qt::Key_I, Qt::Key_Iacute}, + { Qt::Key_O, Qt::Key_Oacute}, + { Qt::Key_U, Qt::Key_Uacute}, + { Qt::Key_Y, Qt::Key_Yacute} + }; + QHash<Qt::Key , Qt::Key> diaeresisKeyTable { // umlaut ¨ + { Qt::Key_A, Qt::Key_Adiaeresis}, + { Qt::Key_E, Qt::Key_Ediaeresis}, + { Qt::Key_I, Qt::Key_Idiaeresis}, + { Qt::Key_O, Qt::Key_Odiaeresis}, + { Qt::Key_U, Qt::Key_Udiaeresis}, + { Qt::Key_Y, Qt::Key_ydiaeresis} + }; + QHash<Qt::Key , Qt::Key> circumflexKeyTable { // ^ + { Qt::Key_A, Qt::Key_Acircumflex}, + { Qt::Key_E, Qt::Key_Ecircumflex}, + { Qt::Key_I, Qt::Key_Icircumflex}, + { Qt::Key_O, Qt::Key_Ocircumflex}, + { Qt::Key_U, Qt::Key_Ucircumflex} + }; private: QWindow *draggedWindow; @@ -205,6 +122,9 @@ private: QRect resizeStartRect; QTouchDevice *touchDevice; quint64 getTimestamp(); + + Qt::Key m_emDeadKey = Qt::Key_unknown; + bool m_emStickyDeadKey = false; }; QT_END_NAMESPACE From 7319c342c34f6bcc8f0322e9613c6296331f1487 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= <tor.arne.vestbo@qt.io> Date: Wed, 13 Feb 2019 12:52:33 +0100 Subject: [PATCH 1196/1650] macOS: Implement QNSWindow/QNSPanel mixin using preprocessor includes We want to share the implementation between the two classes, but Objective-C doesn't natively have a mixin-feature. Instead of using dynamic super-calls at runtime (which worked fine, but added complexity), we now do the mixin at compile time using the preprocessor. The dynamic-super feature is left in, in case we need it in other areas in the future. Change-Id: I95dfa7f18cba86cc518e963dd018944ef113ac06 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> --- src/plugins/platforms/cocoa/qnswindow.h | 8 - src/plugins/platforms/cocoa/qnswindow.mm | 336 +++++++++++------------ 2 files changed, 158 insertions(+), 186 deletions(-) diff --git a/src/plugins/platforms/cocoa/qnswindow.h b/src/plugins/platforms/cocoa/qnswindow.h index dcbcd58901..2827e41049 100644 --- a/src/plugins/platforms/cocoa/qnswindow.h +++ b/src/plugins/platforms/cocoa/qnswindow.h @@ -60,15 +60,7 @@ QT_FORWARD_DECLARE_CLASS(QCocoaWindow) #define QNSWindowProtocol QT_MANGLE_NAMESPACE(QNSWindowProtocol) @protocol QNSWindowProtocol -@optional -- (BOOL)canBecomeKeyWindow; -- (BOOL)worksWhenModal; -- (void)sendEvent:(NSEvent*)theEvent; - (void)closeAndRelease; -- (void)dealloc; -- (BOOL)isOpaque; -- (NSColor *)backgroundColor; -- (NSString *)description; @property (nonatomic, readonly) QCocoaWindow *platformWindow; @end diff --git a/src/plugins/platforms/cocoa/qnswindow.mm b/src/plugins/platforms/cocoa/qnswindow.mm index 28a9fa8607..3a1a04f887 100644 --- a/src/plugins/platforms/cocoa/qnswindow.mm +++ b/src/plugins/platforms/cocoa/qnswindow.mm @@ -37,6 +37,8 @@ ** ****************************************************************************/ +#if !defined(QNSWINDOW_PROTOCOL_IMPLMENTATION) + #include "qnswindow.h" #include "qcocoawindow.h" #include "qcocoahelpers.h" @@ -89,183 +91,10 @@ static bool isMouseEvent(NSEvent *ev) } @end -#define super USE_qt_objcDynamicSuper_INSTEAD - @implementation QNSWindow - -+ (void)load -{ - const Class windowClass = [self class]; - const Class panelClass = [QNSPanel class]; - - unsigned int protocolCount; - Protocol **protocols = class_copyProtocolList(windowClass, &protocolCount); - for (unsigned int i = 0; i < protocolCount; ++i) { - Protocol *protocol = protocols[i]; - - unsigned int methodDescriptionsCount; - objc_method_description *methods = protocol_copyMethodDescriptionList( - protocol, NO, YES, &methodDescriptionsCount); - - for (unsigned int j = 0; j < methodDescriptionsCount; ++j) { - objc_method_description method = methods[j]; - class_addMethod(panelClass, method.name, - class_getMethodImplementation(windowClass, method.name), - method.types); - } - free(methods); - } - - free(protocols); -} - -- (QCocoaWindow *)platformWindow -{ - return qnsview_cast(self.contentView).platformWindow; -} - -- (NSString *)description -{ - NSMutableString *description = [NSMutableString stringWithString:qt_objcDynamicSuper()]; - -#ifndef QT_NO_DEBUG_STREAM - QString contentViewDescription; - QDebug debug(&contentViewDescription); - debug.nospace() << "; contentView=" << qnsview_cast(self.contentView) << ">"; - - NSRange lastCharacter = [description rangeOfComposedCharacterSequenceAtIndex:description.length - 1]; - [description replaceCharactersInRange:lastCharacter withString:contentViewDescription.toNSString()]; -#endif - - return description; -} - -- (BOOL)canBecomeKeyWindow -{ - QCocoaWindow *pw = self.platformWindow; - if (!pw) - return NO; - - if (pw->shouldRefuseKeyWindowAndFirstResponder()) - return NO; - - if ([self isKindOfClass:[QNSPanel class]]) { - // Only tool or dialog windows should become key: - Qt::WindowType type = pw->window()->type(); - if (type == Qt::Tool || type == Qt::Dialog) - return YES; - - return NO; - } else { - // The default implementation returns NO for title-bar less windows, - // override and return yes here to make sure popup windows such as - // the combobox popup can become the key window. - return YES; - } -} - -- (BOOL)canBecomeMainWindow -{ - BOOL canBecomeMain = YES; // By default, windows can become the main window - - // Windows with a transient parent (such as combobox popup windows) - // cannot become the main window: - QCocoaWindow *pw = self.platformWindow; - if (!pw || pw->window()->transientParent()) - canBecomeMain = NO; - - return canBecomeMain; -} - -- (BOOL)worksWhenModal -{ - if ([self isKindOfClass:[QNSPanel class]]) { - if (QCocoaWindow *pw = self.platformWindow) { - Qt::WindowType type = pw->window()->type(); - if (type == Qt::Popup || type == Qt::Dialog || type == Qt::Tool) - return YES; - } - } - - return qt_objcDynamicSuper(); -} - -- (BOOL)isOpaque -{ - return self.platformWindow ? - self.platformWindow->isOpaque() : qt_objcDynamicSuper(); -} - -/*! - Borderless windows need a transparent background - - Technically windows with NSWindowStyleMaskTexturedBackground - (such as windows with unified toolbars) need to draw the textured - background of the NSWindow, and can't have a transparent - background, but as NSWindowStyleMaskBorderless is 0, you can't - have a window with NSWindowStyleMaskTexturedBackground that is - also borderless. -*/ -- (NSColor *)backgroundColor -{ - return self.styleMask == NSWindowStyleMaskBorderless - ? [NSColor clearColor] : qt_objcDynamicSuper(); -} - -- (void)sendEvent:(NSEvent*)theEvent -{ - qCDebug(lcQpaEvents) << "Sending" << theEvent << "to" << self; - - // We might get events for a NSWindow after the corresponding platform - // window has been deleted, as the NSWindow can outlive the QCocoaWindow - // e.g. if being retained by other parts of AppKit, or in an auto-release - // pool. We guard against this in QNSView as well, as not all callbacks - // come via events, but if they do there's no point in propagating them. - if (!self.platformWindow) - return; - - // Prevent deallocation of this NSWindow during event delivery, as we - // have logic further below that depends on the window being alive. - [[self retain] autorelease]; - - const char *eventType = object_getClassName(theEvent); - if (QWindowSystemInterface::handleNativeEvent(self.platformWindow->window(), - QByteArray::fromRawData(eventType, qstrlen(eventType)), theEvent, nullptr)) { - return; - } - - qt_objcDynamicSuper(theEvent); - - if (!self.platformWindow) - return; // Platform window went away while processing event - - QCocoaWindow *pw = self.platformWindow; - if (pw->frameStrutEventsEnabled() && isMouseEvent(theEvent)) { - NSPoint loc = [theEvent locationInWindow]; - NSRect windowFrame = [self convertRectFromScreen:self.frame]; - NSRect contentFrame = self.contentView.frame; - if (NSMouseInRect(loc, windowFrame, NO) && !NSMouseInRect(loc, contentFrame, NO)) - [qnsview_cast(pw->view()) handleFrameStrutMouseEvent:theEvent]; - } -} - -- (void)closeAndRelease -{ - qCDebug(lcQpaWindow) << "Closing and releasing" << self; - [self close]; - [self release]; -} - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wobjc-missing-super-calls" -- (void)dealloc -{ - qCDebug(lcQpaWindow) << "Deallocating" << self; - self.delegate = nil; - - qt_objcDynamicSuper(); -} -#pragma clang diagnostic pop +#define QNSWINDOW_PROTOCOL_IMPLMENTATION 1 +#include "qnswindow.mm" +#undef QNSWINDOW_PROTOCOL_IMPLMENTATION + (void)applicationActivationChanged:(NSNotification*)notification { @@ -326,7 +155,158 @@ static bool isMouseEvent(NSEvent *ev) @end @implementation QNSPanel -// Implementation shared with QNSWindow, see +[QNSWindow load] above +#define QNSWINDOW_PROTOCOL_IMPLMENTATION 1 +#include "qnswindow.mm" +#undef QNSWINDOW_PROTOCOL_IMPLMENTATION @end -#undef super +#else // QNSWINDOW_PROTOCOL_IMPLMENTATION + +// The following methods are mixed in to the QNSWindow and QNSPanel classes via includes + +- (QCocoaWindow *)platformWindow +{ + return qnsview_cast(self.contentView).platformWindow; +} + +- (NSString *)description +{ + NSMutableString *description = [NSMutableString stringWithString:[super description]]; + +#ifndef QT_NO_DEBUG_STREAM + QString contentViewDescription; + QDebug debug(&contentViewDescription); + debug.nospace() << "; contentView=" << qnsview_cast(self.contentView) << ">"; + + NSRange lastCharacter = [description rangeOfComposedCharacterSequenceAtIndex:description.length - 1]; + [description replaceCharactersInRange:lastCharacter withString:contentViewDescription.toNSString()]; +#endif + + return description; +} + +- (BOOL)canBecomeKeyWindow +{ + QCocoaWindow *pw = self.platformWindow; + if (!pw) + return NO; + + if (pw->shouldRefuseKeyWindowAndFirstResponder()) + return NO; + + if ([self isKindOfClass:[QNSPanel class]]) { + // Only tool or dialog windows should become key: + Qt::WindowType type = pw->window()->type(); + if (type == Qt::Tool || type == Qt::Dialog) + return YES; + + return NO; + } else { + // The default implementation returns NO for title-bar less windows, + // override and return yes here to make sure popup windows such as + // the combobox popup can become the key window. + return YES; + } +} + +- (BOOL)canBecomeMainWindow +{ + BOOL canBecomeMain = YES; // By default, windows can become the main window + + // Windows with a transient parent (such as combobox popup windows) + // cannot become the main window: + QCocoaWindow *pw = self.platformWindow; + if (!pw || pw->window()->transientParent()) + canBecomeMain = NO; + + return canBecomeMain; +} + +- (BOOL)worksWhenModal +{ + if ([self isKindOfClass:[QNSPanel class]]) { + if (QCocoaWindow *pw = self.platformWindow) { + Qt::WindowType type = pw->window()->type(); + if (type == Qt::Popup || type == Qt::Dialog || type == Qt::Tool) + return YES; + } + } + + return [super worksWhenModal]; +} + +- (BOOL)isOpaque +{ + return self.platformWindow ? + self.platformWindow->isOpaque() : [super isOpaque]; +} + +/*! + Borderless windows need a transparent background + + Technically windows with NSWindowStyleMaskTexturedBackground + (such as windows with unified toolbars) need to draw the textured + background of the NSWindow, and can't have a transparent + background, but as NSWindowStyleMaskBorderless is 0, you can't + have a window with NSWindowStyleMaskTexturedBackground that is + also borderless. +*/ +- (NSColor *)backgroundColor +{ + return self.styleMask == NSWindowStyleMaskBorderless + ? [NSColor clearColor] : [super backgroundColor]; +} + +- (void)sendEvent:(NSEvent*)theEvent +{ + qCDebug(lcQpaEvents) << "Sending" << theEvent << "to" << self; + + // We might get events for a NSWindow after the corresponding platform + // window has been deleted, as the NSWindow can outlive the QCocoaWindow + // e.g. if being retained by other parts of AppKit, or in an auto-release + // pool. We guard against this in QNSView as well, as not all callbacks + // come via events, but if they do there's no point in propagating them. + if (!self.platformWindow) + return; + + // Prevent deallocation of this NSWindow during event delivery, as we + // have logic further below that depends on the window being alive. + [[self retain] autorelease]; + + const char *eventType = object_getClassName(theEvent); + if (QWindowSystemInterface::handleNativeEvent(self.platformWindow->window(), + QByteArray::fromRawData(eventType, qstrlen(eventType)), theEvent, nullptr)) { + return; + } + + [super sendEvent:theEvent]; + + if (!self.platformWindow) + return; // Platform window went away while processing event + + QCocoaWindow *pw = self.platformWindow; + if (pw->frameStrutEventsEnabled() && isMouseEvent(theEvent)) { + NSPoint loc = [theEvent locationInWindow]; + NSRect windowFrame = [self convertRectFromScreen:self.frame]; + NSRect contentFrame = self.contentView.frame; + if (NSMouseInRect(loc, windowFrame, NO) && !NSMouseInRect(loc, contentFrame, NO)) + [qnsview_cast(pw->view()) handleFrameStrutMouseEvent:theEvent]; + } +} + +- (void)closeAndRelease +{ + qCDebug(lcQpaWindow) << "Closing and releasing" << self; + [self close]; + [self release]; +} + +- (void)dealloc +{ + qCDebug(lcQpaWindow) << "Deallocating" << self; + self.delegate = nil; + + [super dealloc]; +} + +#endif From 0a2e91328e6340b6ecfeb4ee202ab1527cefaeca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= <tor.arne.vestbo@qt.io> Date: Wed, 13 Feb 2019 13:50:02 +0100 Subject: [PATCH 1197/1650] macOS: Set up platform window reference before initializing QNSWindow/Panel Initializing the window will end up in [NSWindow _commonAwake], which calls many of the getters. We need to set up the platform window reference first, so we can properly reflect the window's state during initialization. Change-Id: I5349273b1930ee8a57dc518db74be90d2426f61c Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> --- src/plugins/platforms/cocoa/qcocoascreen.mm | 3 +- src/plugins/platforms/cocoa/qcocoawindow.mm | 3 +- src/plugins/platforms/cocoa/qnswindow.h | 3 ++ src/plugins/platforms/cocoa/qnswindow.mm | 55 ++++++++++++--------- 4 files changed, 39 insertions(+), 25 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoascreen.mm b/src/plugins/platforms/cocoa/qcocoascreen.mm index 830a387fd1..6a5b0e6e3e 100644 --- a/src/plugins/platforms/cocoa/qcocoascreen.mm +++ b/src/plugins/platforms/cocoa/qcocoascreen.mm @@ -410,8 +410,7 @@ QWindow *QCocoaScreen::topLevelAt(const QPoint &point) const if (![nsWindow conformsToProtocol:@protocol(QNSWindowProtocol)]) continue; - id<QNSWindowProtocol> proto = static_cast<id<QNSWindowProtocol> >(nsWindow); - QCocoaWindow *cocoaWindow = proto.platformWindow; + QCocoaWindow *cocoaWindow = qnsview_cast(nsWindow.contentView).platformWindow; if (!cocoaWindow) continue; window = cocoaWindow->window(); diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 2718dc9600..d1047e1965 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1539,7 +1539,8 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel) // Deferring window creation breaks OpenGL (the GL context is // set up before the window is shown and needs a proper window) backing:NSBackingStoreBuffered defer:NO - screen:cocoaScreen->nativeScreen()]; + screen:cocoaScreen->nativeScreen() + platformWindow:this]; Q_ASSERT_X(nsWindow.screen == cocoaScreen->nativeScreen(), "QCocoaWindow", "Resulting NSScreen should match the requested NSScreen"); diff --git a/src/plugins/platforms/cocoa/qnswindow.h b/src/plugins/platforms/cocoa/qnswindow.h index 2827e41049..5fc48d826f 100644 --- a/src/plugins/platforms/cocoa/qnswindow.h +++ b/src/plugins/platforms/cocoa/qnswindow.h @@ -60,6 +60,9 @@ QT_FORWARD_DECLARE_CLASS(QCocoaWindow) #define QNSWindowProtocol QT_MANGLE_NAMESPACE(QNSWindowProtocol) @protocol QNSWindowProtocol +- (instancetype)initWithContentRect:(NSRect)contentRect styleMask:(NSWindowStyleMask)style + backing:(NSBackingStoreType)backingStoreType defer:(BOOL)flag screen:(NSScreen *)screen + platformWindow:(QCocoaWindow*)window; - (void)closeAndRelease; @property (nonatomic, readonly) QCocoaWindow *platformWindow; @end diff --git a/src/plugins/platforms/cocoa/qnswindow.mm b/src/plugins/platforms/cocoa/qnswindow.mm index 3a1a04f887..52f765eb31 100644 --- a/src/plugins/platforms/cocoa/qnswindow.mm +++ b/src/plugins/platforms/cocoa/qnswindow.mm @@ -162,11 +162,28 @@ static bool isMouseEvent(NSEvent *ev) #else // QNSWINDOW_PROTOCOL_IMPLMENTATION -// The following methods are mixed in to the QNSWindow and QNSPanel classes via includes +// The following content is mixed in to the QNSWindow and QNSPanel classes via includes + +{ + // Member variables + QPointer<QCocoaWindow> m_platformWindow; +} + +- (instancetype)initWithContentRect:(NSRect)contentRect styleMask:(NSWindowStyleMask)style + backing:(NSBackingStoreType)backingStoreType defer:(BOOL)defer screen:(NSScreen *)screen + platformWindow:(QCocoaWindow*)window +{ + // Initializing the window will end up in [NSWindow _commonAwake], which calls many + // of the getters below. We need to set up the platform window reference first, so + // we can properly reflect the window's state during initialization. + m_platformWindow = window; + + return [super initWithContentRect:contentRect styleMask:style backing:backingStoreType defer:defer screen:screen]; +} - (QCocoaWindow *)platformWindow { - return qnsview_cast(self.contentView).platformWindow; + return m_platformWindow; } - (NSString *)description @@ -187,16 +204,15 @@ static bool isMouseEvent(NSEvent *ev) - (BOOL)canBecomeKeyWindow { - QCocoaWindow *pw = self.platformWindow; - if (!pw) + if (!m_platformWindow) return NO; - if (pw->shouldRefuseKeyWindowAndFirstResponder()) + if (m_platformWindow->shouldRefuseKeyWindowAndFirstResponder()) return NO; if ([self isKindOfClass:[QNSPanel class]]) { // Only tool or dialog windows should become key: - Qt::WindowType type = pw->window()->type(); + Qt::WindowType type = m_platformWindow->window()->type(); if (type == Qt::Tool || type == Qt::Dialog) return YES; @@ -215,8 +231,7 @@ static bool isMouseEvent(NSEvent *ev) // Windows with a transient parent (such as combobox popup windows) // cannot become the main window: - QCocoaWindow *pw = self.platformWindow; - if (!pw || pw->window()->transientParent()) + if (!m_platformWindow || m_platformWindow->window()->transientParent()) canBecomeMain = NO; return canBecomeMain; @@ -224,12 +239,10 @@ static bool isMouseEvent(NSEvent *ev) - (BOOL)worksWhenModal { - if ([self isKindOfClass:[QNSPanel class]]) { - if (QCocoaWindow *pw = self.platformWindow) { - Qt::WindowType type = pw->window()->type(); - if (type == Qt::Popup || type == Qt::Dialog || type == Qt::Tool) - return YES; - } + if (m_platformWindow && [self isKindOfClass:[QNSPanel class]]) { + Qt::WindowType type = m_platformWindow->window()->type(); + if (type == Qt::Popup || type == Qt::Dialog || type == Qt::Tool) + return YES; } return [super worksWhenModal]; @@ -237,8 +250,7 @@ static bool isMouseEvent(NSEvent *ev) - (BOOL)isOpaque { - return self.platformWindow ? - self.platformWindow->isOpaque() : [super isOpaque]; + return m_platformWindow ? m_platformWindow->isOpaque() : [super isOpaque]; } /*! @@ -266,7 +278,7 @@ static bool isMouseEvent(NSEvent *ev) // e.g. if being retained by other parts of AppKit, or in an auto-release // pool. We guard against this in QNSView as well, as not all callbacks // come via events, but if they do there's no point in propagating them. - if (!self.platformWindow) + if (!m_platformWindow) return; // Prevent deallocation of this NSWindow during event delivery, as we @@ -274,23 +286,22 @@ static bool isMouseEvent(NSEvent *ev) [[self retain] autorelease]; const char *eventType = object_getClassName(theEvent); - if (QWindowSystemInterface::handleNativeEvent(self.platformWindow->window(), + if (QWindowSystemInterface::handleNativeEvent(m_platformWindow->window(), QByteArray::fromRawData(eventType, qstrlen(eventType)), theEvent, nullptr)) { return; } [super sendEvent:theEvent]; - if (!self.platformWindow) + if (!m_platformWindow) return; // Platform window went away while processing event - QCocoaWindow *pw = self.platformWindow; - if (pw->frameStrutEventsEnabled() && isMouseEvent(theEvent)) { + if (m_platformWindow->frameStrutEventsEnabled() && isMouseEvent(theEvent)) { NSPoint loc = [theEvent locationInWindow]; NSRect windowFrame = [self convertRectFromScreen:self.frame]; NSRect contentFrame = self.contentView.frame; if (NSMouseInRect(loc, windowFrame, NO) && !NSMouseInRect(loc, contentFrame, NO)) - [qnsview_cast(pw->view()) handleFrameStrutMouseEvent:theEvent]; + [qnsview_cast(m_platformWindow->view()) handleFrameStrutMouseEvent:theEvent]; } } From 11111c5a7d71024f281322d9b310ce37210fc4c2 Mon Sep 17 00:00:00 2001 From: Yuhang Zhao <2546789017@qq.com> Date: Wed, 13 Feb 2019 20:18:39 +0800 Subject: [PATCH 1198/1650] qmake: Optimize for speed instead of size Change-Id: Ide06365f3ba0db673749a9938afc18fdf7480542 Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de> Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> --- qmake/Makefile.win32 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index 3f13df884a..506e9deb19 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -13,7 +13,7 @@ QMKSRC = $(SOURCE_PATH)\qmake !if "$(QMAKESPEC)" == "win32-icc" CXX = icl LINKER = xilink -CFLAGS_EXTRA = /Zc:forScope /Qstd=c++11 +CFLAGS_EXTRA = /Zc:forScope /Qstd=c++11 /O3 !elseif "$(QMAKESPEC)" == "win32-clang-msvc" CXX = clang-cl LINKER = lld-link @@ -30,7 +30,7 @@ PCH_OBJECT = qmake_pch.obj !endif CFLAGS_BARE = -c -Fo./ -Fdqmake.pdb \ - -W2 -nologo -O1 \ + -W2 -nologo -O2 \ $(CFLAGS_EXTRA) \ -I$(QMKSRC) -I$(QMKSRC)\library -I$(QMKSRC)\generators -I$(QMKSRC)\generators\unix -I$(QMKSRC)\generators\win32 -I$(QMKSRC)\generators\mac \ -I$(INC_PATH) -I$(INC_PATH)\QtCore -I$(INC_PATH)\QtCore\$(QT_VERSION) -I$(INC_PATH)\QtCore\$(QT_VERSION)\QtCore \ From 8796e3016fae1672e727e2fa4e48f671a0c667ba Mon Sep 17 00:00:00 2001 From: Andy Shaw <andy.shaw@qt.io> Date: Mon, 11 Feb 2019 12:50:03 +0100 Subject: [PATCH 1199/1650] Android: Add support for getting the UiLanguages From API 24 it is possible to get the UiLanguages correctly from Android so if API 24 or later is available we should use this. If it is not available, then it will fallback to the original behavior of using the system language. Fixes: QTBUG-68019 Change-Id: I4cfbc2b807b361c08da56a74100ba59abf5f2d0f Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> --- .../platforms/android/qandroidsystemlocale.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/plugins/platforms/android/qandroidsystemlocale.cpp b/src/plugins/platforms/android/qandroidsystemlocale.cpp index 7fe36aa9bc..f9d566ff1a 100644 --- a/src/plugins/platforms/android/qandroidsystemlocale.cpp +++ b/src/plugins/platforms/android/qandroidsystemlocale.cpp @@ -40,6 +40,7 @@ #include "qandroidsystemlocale.h" #include "androidjnimain.h" #include <QtCore/private/qjni_p.h> +#include <QtCore/private/qjnihelpers_p.h> #include "qdatetime.h" #include "qstringlist.h" #include "qvariant.h" @@ -162,6 +163,23 @@ QVariant QAndroidSystemLocale::query(QueryType type, QVariant in) const return m_locale.createSeparatedList(in.value<QStringList>()); case LocaleChanged: Q_ASSERT_X(false, Q_FUNC_INFO, "This can't happen."); + case UILanguages: { + if (QtAndroidPrivate::androidSdkVersion() >= 24) { + QJNIObjectPrivate localeListObject = + QJNIObjectPrivate::callStaticObjectMethod("android/os/LocaleList", "getDefault", + "()Landroid/os/LocaleList;"); + if (localeListObject.isValid()) { + QString lang = localeListObject.callObjectMethod("toLanguageTags", + "()Ljava/lang/String;").toString(); + // Some devices return with it enclosed in []'s so check if both exists before + // removing to ensure it is formatted correctly + if (lang.startsWith(QChar('[')) && lang.endsWith(QChar(']'))) + lang = lang.mid(1, lang.length() - 2); + return lang.split(QChar(',')); + } + } + return QVariant(); + } default: break; } From 99e9666492095e3b96ac16f03e28f20288cc0af6 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis <gatis.paeglis@qt.io> Date: Thu, 14 Feb 2019 16:57:22 +0100 Subject: [PATCH 1200/1650] qguiapplication: move long comment to JIRA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ... where it can be commented on. Change-Id: I627c7562be3a650e08ec7e7e76839797f07d5b2e Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> --- src/gui/kernel/qguiapplication.cpp | 37 ++---------------------------- 1 file changed, 2 insertions(+), 35 deletions(-) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 4b069b4f82..038b0857ae 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -3076,41 +3076,8 @@ void QGuiApplicationPrivate::processExposeEvent(QWindowSystemInterfacePrivate::E /*! \internal - This function updates an internal state to keep the source compatibility. Documentation of - QGuiApplication::mouseButtons() states - "The current state is updated synchronously as - the event queue is emptied of events that will spontaneously change the mouse state - (QEvent::MouseButtonPress and QEvent::MouseButtonRelease events)". But internally we have - been updating these state variables from various places to keep buttons returned by - mouseButtons() in sync with the systems state. This is not the documented behavior. - - ### Qt6 - Remove QGuiApplication::mouseButtons()/keyboardModifiers() API? And here - are the reasons: - - - It is an easy to misuse API by: - - a) Application developers: The only place where the values of this API can be trusted is - when using within mouse handling callbacks. In these callbacks we work with the state - that was provided directly by the windowing system. Anywhere else it might not reflect what - user wrongly expects. We might not always receive a matching mouse release for a press event - (e.g. When dismissing a popup window on X11. Or when dnd enter Qt application with mouse - button down, we update mouse_buttons and then dnd leaves Qt application and does a drop - somewhere else) and hence mouseButtons() will be out-of-sync from users perspective, see - for example QTBUG-33161. BUT THIS IS NOT HOW THE API IS SUPPOSED TO BE USED. Since the only - safe place to use this API is from mouse event handlers, we might as well deprecate it and - pass down the button state if we are not already doing that everywhere where it matters. - - b) Qt framework developers: - - We see users complaining, we start adding hacks everywhere just to keep buttons in sync ;) - There are corner cases that can not be solved and adding this kind of hacks is never ending - task. - - - Real mouse events, tablet mouse events, etc: all go through QGuiApplication::processMouseEvent, - and all share mouse_buttons. What if we want to support multiple mice in future? The API must - go. - - - Motivation why this API is public is not clear. Could the same be achieved by a user by - installing an event filter? + This function updates an internal state to keep the source compatibility. + ### Qt 6 - Won't need after QTBUG-73829 */ static void updateMouseAndModifierButtonState(Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers) { From 3c74042c3db8c68e47ed1f0c2ecd4d39a2d84912 Mon Sep 17 00:00:00 2001 From: BogDan Vatra <bogdan@kdab.com> Date: Mon, 11 Feb 2019 14:22:13 +0200 Subject: [PATCH 1201/1650] Load main library as soon as possible Delaying the main library load cause serious problems for people who want to access it's functions from java before the main method is called. Change-Id: I87f3a8282003395e003b06978048762eeabe6548 Fixes: QTBUG-68813 Reviewed-by: Andy Shaw <andy.shaw@qt.io> --- .../qt5/android/QtActivityDelegate.java | 17 +++-- .../org/qtproject/qt5/android/QtNative.java | 65 +++++++++++-------- .../qt5/android/QtServiceDelegate.java | 14 ++-- 3 files changed, 51 insertions(+), 45 deletions(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index 02033859e9..4b87c25787 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -606,11 +606,14 @@ public class QtActivityDelegate } QtNative.loadQtLibraries(loaderParams.getStringArrayList(NATIVE_LIBRARIES_KEY)); ArrayList<String> libraries = loaderParams.getStringArrayList(BUNDLED_LIBRARIES_KEY); - QtNative.loadBundledLibraries(libraries, QtNativeLibrariesDir.nativeLibrariesDir(m_activity)); + String nativeLibsDir = QtNativeLibrariesDir.nativeLibrariesDir(m_activity); + QtNative.loadBundledLibraries(libraries, nativeLibsDir); m_mainLib = loaderParams.getString(MAIN_LIBRARY_KEY); // older apps provide the main library as the last bundled library; look for this if the main library isn't provided - if (null == m_mainLib && libraries.size() > 0) + if (null == m_mainLib && libraries.size() > 0) { m_mainLib = libraries.get(libraries.size() - 1); + libraries.remove(libraries.size() - 1); + } if (loaderParams.containsKey(EXTRACT_STYLE_KEY)) { String path = loaderParams.getString(EXTRACT_STYLE_KEY); @@ -664,8 +667,8 @@ public class QtActivityDelegate } catch (Exception e) { e.printStackTrace(); } - - return true; + m_mainLib = QtNative.loadMainLibrary(m_mainLib, nativeLibsDir); + return m_mainLib != null; } public boolean startApplication() @@ -728,11 +731,7 @@ public class QtActivityDelegate @Override public void run() { try { - String nativeLibraryDir = QtNativeLibrariesDir.nativeLibrariesDir(m_activity); - QtNative.startApplication(m_applicationParameters, - m_environmentVariables, - m_mainLib, - nativeLibraryDir); + QtNative.startApplication(m_applicationParameters, m_environmentVariables, m_mainLib); m_started = true; } catch (Exception e) { e.printStackTrace(); diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java index 5562c010aa..1d2b70ab5f 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java @@ -231,6 +231,41 @@ public class QtNative }); } + public static String loadMainLibrary(final String mainLibrary, final String nativeLibraryDir) + { + final String[] res = new String[1]; + res[0] = null; + m_qtThread.run(new Runnable() { + @Override + public void run() { + try { + String mainLibNameTemplate = "lib" + mainLibrary + ".so"; + File f = new File(nativeLibraryDir + mainLibNameTemplate); + if (!f.exists()) { + try { + ActivityInfo info = m_activity.getPackageManager().getActivityInfo(m_activity.getComponentName(), + PackageManager.GET_META_DATA); + String systemLibraryDir = QtNativeLibrariesDir.systemLibrariesDir; + if (info.metaData.containsKey("android.app.system_libs_prefix")) + systemLibraryDir = info.metaData.getString("android.app.system_libs_prefix"); + f = new File(systemLibraryDir + mainLibNameTemplate); + } catch (Exception e) { + e.printStackTrace(); + return; + } + } + if (!f.exists()) + return; + System.load(f.getAbsolutePath()); + res[0] = f.getAbsolutePath(); + } catch (Exception e) { + Log.e(QtTAG, "Can't load '" + mainLibrary + "'", e); + } + } + }); + return res[0]; + } + public static void setActivity(Activity qtMainActivity, QtActivityDelegate qtActivityDelegate) { synchronized (m_mainActivityMutex) { @@ -308,46 +343,20 @@ public class QtNative }); } - public static boolean startApplication(String params, - final String environment, - String mainLibrary, - String nativeLibraryDir) throws Exception + public static boolean startApplication(String params, final String environment, String mainLib) throws Exception { - String mainLibNameTemplate = "lib" + mainLibrary + ".so"; - File f = new File(nativeLibraryDir + mainLibNameTemplate); - if (!f.exists()) { - try { - ActivityInfo info = m_activity.getPackageManager().getActivityInfo(m_activity.getComponentName(), - PackageManager.GET_META_DATA); - String systemLibraryDir = QtNativeLibrariesDir.systemLibrariesDir; - if (info.metaData.containsKey("android.app.system_libs_prefix")) - systemLibraryDir = info.metaData.getString("android.app.system_libs_prefix"); - f = new File(systemLibraryDir + mainLibNameTemplate); - } catch (Exception e) { - - } - } - if (!f.exists()) - throw new Exception("Can't find main library '" + mainLibrary + "'"); - if (params == null) params = "-platform\tandroid"; - final String mainLibraryPath = f.getAbsolutePath(); final boolean[] res = new boolean[1]; res[0] = false; synchronized (m_mainActivityMutex) { if (params.length() > 0 && !params.startsWith("\t")) params = "\t" + params; - final String qtParams = f.getAbsolutePath() + params; + final String qtParams = mainLib + params; m_qtThread.run(new Runnable() { @Override public void run() { - try { - System.load(mainLibraryPath); - } catch (Exception e) { - Log.i(QtTAG, "Can't load '" + mainLibraryPath + "'", e); - } res[0] = startQtAndroidPlugin(qtParams, environment); setDisplayMetrics(m_displayMetricsScreenWidthPixels, m_displayMetricsScreenHeightPixels, diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtServiceDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtServiceDelegate.java index ae06fa6268..33bcb364de 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtServiceDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtServiceDelegate.java @@ -98,8 +98,8 @@ public class QtServiceDelegate private static final String APP_DISPLAY_METRIC_SCREEN_YDPI_KEY = "display.screen.dpi.y"; private static final String APP_DISPLAY_METRIC_SCREEN_DENSITY_KEY = "display.screen.density"; + private String m_mainLib = null; private Service m_service = null; - private String m_mainLib; private static String m_environmentVariables = null; private static String m_applicationParameters = null; @@ -142,9 +142,9 @@ public class QtServiceDelegate } QtNative.loadQtLibraries(loaderParams.getStringArrayList(NATIVE_LIBRARIES_KEY)); ArrayList<String> libraries = loaderParams.getStringArrayList(BUNDLED_LIBRARIES_KEY); - QtNative.loadBundledLibraries(libraries, QtNativeLibrariesDir.nativeLibrariesDir(m_service)); + String nativeLibsDir = QtNativeLibrariesDir.nativeLibrariesDir(m_service); + QtNative.loadBundledLibraries(libraries, nativeLibsDir); m_mainLib = loaderParams.getString(MAIN_LIBRARY_KEY); - m_environmentVariables = loaderParams.getString(ENVIRONMENT_VARIABLES_KEY); String additionalEnvironmentVariables = "QT_ANDROID_FONTS_MONOSPACE=Droid Sans Mono;Droid Sans;Droid Sans Fallback" + "\tQT_ANDROID_FONTS_SERIF=Droid Serif" @@ -165,7 +165,8 @@ public class QtServiceDelegate else m_applicationParameters = ""; - return true; + m_mainLib = QtNative.loadMainLibrary(m_mainLib, nativeLibsDir); + return m_mainLib != null; } public boolean startApplication() @@ -173,10 +174,7 @@ public class QtServiceDelegate // start application try { String nativeLibraryDir = QtNativeLibrariesDir.nativeLibrariesDir(m_service); - QtNative.startApplication(m_applicationParameters, - m_environmentVariables, - m_mainLib, - nativeLibraryDir); + QtNative.startApplication(m_applicationParameters, m_environmentVariables, m_mainLib); return true; } catch (Exception e) { e.printStackTrace(); From 36a294d1aa18ba67989d505eadf4b9c2012c0c9e Mon Sep 17 00:00:00 2001 From: Kai Koehne <kai.koehne@qt.io> Date: Wed, 13 Feb 2019 14:06:31 +0100 Subject: [PATCH 1202/1650] Emit returnPressed() signal for the lineEdit embedded in QDateTimeEdit f78842abe429dc9b42fd15dc8e9e842ab72dcf2b added the emission of the signal in QAbstractLineEdit::keyPressEvent(). This patch also emits it for QDateTimeEdit. Fixes: QTBUG-73725 Change-Id: I66d577f5d4b60ad57987b26e7a1c1f20fad47782 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> --- src/widgets/widgets/qdatetimeedit.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp index c66400f423..41d9faa5c2 100644 --- a/src/widgets/widgets/qdatetimeedit.cpp +++ b/src/widgets/widgets/qdatetimeedit.cpp @@ -1092,6 +1092,7 @@ void QDateTimeEdit::keyPressEvent(QKeyEvent *event) d->setSelected(d->currentSectionIndex, true); event->ignore(); emit editingFinished(); + emit d->edit->returnPressed(); return; default: #ifdef QT_KEYPAD_NAVIGATION From 55e31e6389c78218f1f9039a4bf642db68a86975 Mon Sep 17 00:00:00 2001 From: Dmitry Sokolov <sokolov_d_s@mail.ru> Date: Thu, 14 Feb 2019 11:12:18 +0100 Subject: [PATCH 1203/1650] Kludge popen/pclose calls on MS-Win For MS Visual Studio we need to use _popen() and _pclose() instead of the POSIX functions; and the pipe needs to be opened in binary mode. Change-Id: Ide0fb26a1e5f121b384b0baaf8100f26c614ccc6 Fixes: QTBUG-73810 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> --- src/tools/androiddeployqt/main.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp index 712a8091fb..b0df833b87 100644 --- a/src/tools/androiddeployqt/main.cpp +++ b/src/tools/androiddeployqt/main.cpp @@ -43,6 +43,15 @@ #include <QRegExp> #include <algorithm> + +#ifdef Q_CC_MSVC +#define popen _popen +#define QT_POPEN_READ "rb" +#define pclose _pclose +#else +#define QT_POPEN_READ "r" +#endif + static const bool mustReadOutputAnyway = true; // pclose seems to return the wrong error code unless we read the output void deleteRecursively(const QString &dirName) @@ -70,7 +79,7 @@ FILE *openProcess(const QString &command) QString processedCommand = command; #endif - return popen(processedCommand.toLocal8Bit().constData(), "r"); + return popen(processedCommand.toLocal8Bit().constData(), QT_POPEN_READ); } struct QtDependency @@ -1721,7 +1730,7 @@ bool scanImports(Options *options, QSet<QString> *usedDependencies) .arg(shellQuote(rootPath)) .arg(importPaths.join(QLatin1Char(' '))); - FILE *qmlImportScannerCommand = popen(qmlImportScanner.toLocal8Bit().constData(), "r"); + FILE *qmlImportScannerCommand = popen(qmlImportScanner.toLocal8Bit().constData(), QT_POPEN_READ); if (qmlImportScannerCommand == 0) { fprintf(stderr, "Couldn't run qmlimportscanner.\n"); return false; @@ -2160,7 +2169,7 @@ bool createAndroidProject(const Options &options) if (options.verbose) fprintf(stdout, " -- Command: %s\n", qPrintable(androidTool)); - FILE *androidToolCommand = popen(androidTool.toLocal8Bit().constData(), "r"); + FILE *androidToolCommand = popen(androidTool.toLocal8Bit().constData(), QT_POPEN_READ); if (androidToolCommand == 0) { fprintf(stderr, "Cannot run command '%s'\n", qPrintable(androidTool)); return false; From 441520141ead6dec74f3bdbb4c1d1e48d3356435 Mon Sep 17 00:00:00 2001 From: Dmitry Sokolov <sokolov_d_s@mail.ru> Date: Thu, 14 Feb 2019 10:49:52 +0100 Subject: [PATCH 1204/1650] Inline expression to bypass compiler bug MSVC managed to trigger the this != &other assertion in QString(const QString &other); so just skip creation of the intermediate string in the function whose body tripped over this. Change-Id: I687003cfc588531018c6069863ce2a76078c8e3f Fixes: QTBUG-73802 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> --- qmake/generators/makefile.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 6a46df1af6..7762e47f41 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -81,8 +81,8 @@ bool MakefileGenerator::canExecute(const QStringList &cmdline, int *a) const QString MakefileGenerator::mkdir_p_asstring(const QString &dir, bool escape) const { - QString edir = escape ? escapeFilePath(Option::fixPathToTargetOS(dir, false, false)) : dir; - return "@" + makedir.arg(edir); + return "@" + makedir.arg( + escape ? escapeFilePath(Option::fixPathToTargetOS(dir, false, false)) : dir); } bool MakefileGenerator::mkdir(const QString &in_path) const From da4ab444ffac37514435364d4d3f0ad59d4f9bc3 Mon Sep 17 00:00:00 2001 From: Eric Lemanissier <eric.lemanissier@gmail.com> Date: Tue, 19 Feb 2019 10:32:55 +0100 Subject: [PATCH 1205/1650] Feature 'ocsp' - fix a broken win-32 build Change-Id: I0fcec3a555a8c5ff5b5faff3cff16b173e9b9950 Fixes: QTBUG-73322 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> --- src/network/ssl/qocsp_p.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/ssl/qocsp_p.h b/src/network/ssl/qocsp_p.h index 94c1c9b445..71f59da0b4 100644 --- a/src/network/ssl/qocsp_p.h +++ b/src/network/ssl/qocsp_p.h @@ -63,11 +63,11 @@ QT_REQUIRE_CONFIG(ocsp); -#ifdef Q_OS_WIN64 +#ifdef Q_OS_WIN #undef X509_NAME #undef OCSP_REQUEST #undef OCSP_RESPONSE -#endif // Q_OS_WIN64 +#endif // Q_OS_WIN #include <openssl/ocsp.h> From 4c759340081384e7b9fae5d2179d25016dc1dda6 Mon Sep 17 00:00:00 2001 From: Andy Shaw <andy.shaw@qt.io> Date: Mon, 7 Jan 2019 12:14:19 +0100 Subject: [PATCH 1206/1650] Fix a couple of SQL tests One of the tests was not added to the parent subdirectory pro so this is also rectified. Change-Id: I270f1c2882260e3e3fac83d074ed6444c5dece19 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> --- tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp | 2 +- tests/auto/sql/models/models.pro | 8 ++++---- .../qsqlrelationaldelegate/tst_qsqlrelationaldelegate.cpp | 3 ++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp index 8cf43e243b..af6b6ca881 100644 --- a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp @@ -909,7 +909,7 @@ void tst_QSqlDatabase::recordMySQL() FieldDef("date", QVariant::Date, QDate::currentDate()), FieldDef("datetime", QVariant::DateTime, dt), FieldDef("timestamp", QVariant::DateTime, dt, false), - FieldDef("time", QVariant::Time, dt.time()), + FieldDef("time", QVariant::String, dt.time()), FieldDef("year", QVariant::Int, 2003), FieldDef("char(20)", QVariant::String, "Blah"), FieldDef("varchar(20)", QVariant::String, "BlahBlah"), diff --git a/tests/auto/sql/models/models.pro b/tests/auto/sql/models/models.pro index 2c3ae4ef0a..da807f4351 100644 --- a/tests/auto/sql/models/models.pro +++ b/tests/auto/sql/models/models.pro @@ -1,8 +1,8 @@ TEMPLATE=subdirs -SUBDIRS=\ +qtHaveModule(widgets): SUBDIRS = \ qsqlquerymodel \ - qsqlrelationaltablemodel \ + qsqlrelationaldelegate + +SUBDIRS += qsqlrelationaltablemodel \ qsqltablemodel \ -!qtHaveModule(widgets): SUBDIRS -= \ - qsqlquerymodel diff --git a/tests/auto/sql/models/qsqlrelationaldelegate/tst_qsqlrelationaldelegate.cpp b/tests/auto/sql/models/qsqlrelationaldelegate/tst_qsqlrelationaldelegate.cpp index 36f592395e..a7089c06a1 100644 --- a/tests/auto/sql/models/qsqlrelationaldelegate/tst_qsqlrelationaldelegate.cpp +++ b/tests/auto/sql/models/qsqlrelationaldelegate/tst_qsqlrelationaldelegate.cpp @@ -158,12 +158,13 @@ void tst_QSqlRelationalDelegate::comboBoxEditor() QTest::keyClick(editor, Qt::Key_Down); QTest::keyClick(editor, Qt::Key_Enter); QCOMPARE(editor->currentText(), "mister"); + QTest::keyClick(tv.viewport(), Qt::Key_Tab); QVERIFY_SQL(model, submitAll()); QSqlQuery qry(db); QVERIFY_SQL(qry, exec("SELECT title_key FROM " + reltest1 + " WHERE id=1")); QVERIFY(qry.next()); - QCOMPARE(qry.value(0).toString(), "mister"); + QCOMPARE(qry.value(0).toString(), "2"); } QTEST_MAIN(tst_QSqlRelationalDelegate) From f4cc23cffbe3005f0a522cac938695e87ecd6407 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Mon, 18 Feb 2019 21:46:33 +0100 Subject: [PATCH 1207/1650] QPdfWriter: mark obsolete functions as deprecated Mark obsolete functions in QPdfWriter as deprecated so they can be removed with Qt6: - setPageSize(PageSize size) - setPageSizeMM(const QSizeF &size) - setMargins(const Margins &m) Change-Id: Iba88528742e67c09f5dc61aea69d27e26f484c16 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Andy Shaw <andy.shaw@qt.io> --- src/gui/painting/qpdfwriter.cpp | 10 ++++++++++ src/gui/painting/qpdfwriter.h | 6 +++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/gui/painting/qpdfwriter.cpp b/src/gui/painting/qpdfwriter.cpp index 258939a763..7f18ce42be 100644 --- a/src/gui/painting/qpdfwriter.cpp +++ b/src/gui/painting/qpdfwriter.cpp @@ -379,6 +379,9 @@ int QPdfWriter::resolution() const */ #endif +#if QT_DEPRECATED_SINCE(5, 14) +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED /*! \reimp @@ -404,6 +407,8 @@ void QPdfWriter::setPageSizeMM(const QSizeF &size) { setPageSize(QPageSize(size, QPageSize::Millimeter)); } +QT_WARNING_POP +#endif /*! \internal @@ -427,6 +432,9 @@ bool QPdfWriter::newPage() } +#if QT_DEPRECATED_SINCE(5, 14) +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED /*! \reimp @@ -438,6 +446,8 @@ void QPdfWriter::setMargins(const Margins &m) { setPageMargins(QMarginsF(m.left, m.top, m.right, m.bottom), QPageLayout::Millimeter); } +QT_WARNING_POP +#endif QT_END_NAMESPACE diff --git a/src/gui/painting/qpdfwriter.h b/src/gui/painting/qpdfwriter.h index b260805b2b..668081e008 100644 --- a/src/gui/painting/qpdfwriter.h +++ b/src/gui/painting/qpdfwriter.h @@ -86,10 +86,14 @@ public: using QPagedPaintDevice::setPageSize; #endif +#if QT_DEPRECATED_SINCE(5, 14) + QT_DEPRECATED_X("Use setPageSize(QPageSize(id)) instead") void setPageSize(PageSize size) override; + QT_DEPRECATED_X("Use setPageSize(QPageSize(size, QPageSize::Millimeter)) instead") void setPageSizeMM(const QSizeF &size) override; - + QT_DEPRECATED_X("Use setPageMargins(QMarginsF(l, t, r, b), QPageLayout::Millimeter) instead") void setMargins(const Margins &m) override; +#endif protected: QPaintEngine *paintEngine() const override; From 655e8623afed01de63ce43f55227fb019e800fe9 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint <Friedemann.Kleint@qt.io> Date: Thu, 14 Feb 2019 11:45:13 +0100 Subject: [PATCH 1208/1650] Fix QSplashscreen positioning on Android Android does not use QPlatformWindow::initialGeometry(), so the underlying assumption of 56e92dfdf255231aff0034d2e197fd096da7f0c0 was wrong. Try to explicitly find a screen and default to primary. Fixes: QTBUG-73794 Change-Id: Iba3e70657a60babfcedf751335ca55cb971a4f99 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> --- src/widgets/widgets/qsplashscreen.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/widgets/widgets/qsplashscreen.cpp b/src/widgets/widgets/qsplashscreen.cpp index 4af4f90119..bf6bf1c7c9 100644 --- a/src/widgets/widgets/qsplashscreen.cpp +++ b/src/widgets/widgets/qsplashscreen.cpp @@ -289,8 +289,7 @@ void QSplashScreen::setPixmap(const QPixmap &pixmap) // 1) If a QDesktopScreenWidget is found in the parent hierarchy, use that (see docs on // QSplashScreen(QWidget *, QPixmap). // 2) If a widget with associated QWindow is found, use that -// 3) When nothing can be found, do not position the widget, allowing for -// QPlatformWindow::initialGeometry() to center it over the cursor +// 3) When nothing can be found, try to center it over the cursor static inline int screenNumberOf(const QDesktopScreenWidget *dsw) { @@ -307,7 +306,15 @@ const QScreen *QSplashScreenPrivate::screenFor(const QWidget *w) if (QWindow *window = p->windowHandle()) return window->screen(); } - return nullptr; +#if QT_CONFIG(cursor) + // Note: We could rely on QPlatformWindow::initialGeometry() to center it + // over the cursor, but not all platforms (namely Android) use that. + if (QGuiApplication::screens().size() > 1) { + if (auto screenAtCursor = QGuiApplication::screenAt(QCursor::pos())) + return screenAtCursor; + } +#endif // cursor + return QGuiApplication::primaryScreen(); } void QSplashScreenPrivate::setPixmap(const QPixmap &p, const QScreen *screen) From 2fc4635e9889ade1ae79b787cc18aae654e65e3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= <tor.arne.vestbo@qt.io> Date: Tue, 19 Feb 2019 11:14:53 +0100 Subject: [PATCH 1209/1650] macOS: Remove special handling for hiding tool windows on application hide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The code was needed when we had QCocoaWindow::hide(), that guarded the ordering out by checking the visible state of the NSWindow. We no longer have that method, and setVisible doesn't have the same guard. Added a comment in setVisible to prevent future travelers from adding logic that introduces the same situation. Change-Id: I0514619a303daceb1cd7d334f0de4bfce6c3e96f Reviewed-by: Andy Shaw <andy.shaw@qt.io> Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> --- .../cocoa/qcocoaapplicationdelegate.mm | 36 ------------------- src/plugins/platforms/cocoa/qcocoawindow.mm | 5 +++ 2 files changed, 5 insertions(+), 36 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm index 9e3c89b6a4..e255719cc1 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm +++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm @@ -94,7 +94,6 @@ QT_USE_NAMESPACE bool startedQuit; NSObject <NSApplicationDelegate> *reflectionDelegate; bool inLaunch; - QWindowList hiddenWindows; } + (instancetype)sharedDelegate @@ -311,41 +310,6 @@ QT_USE_NAMESPACE return NO; // Someday qApp->quitOnLastWindowClosed(); when QApp and NSApp work closer together. } -- (void)applicationWillHide:(NSNotification *)notification -{ - if (reflectionDelegate - && [reflectionDelegate respondsToSelector:@selector(applicationWillHide:)]) { - [reflectionDelegate applicationWillHide:notification]; - } - - // When the application is hidden Qt will hide the popup windows associated with - // it when it has lost the activation for the application. However, when it gets - // to this point it believes the popup windows to be hidden already due to the - // fact that the application itself is hidden, which will cause a problem when - // the application is made visible again. - const QWindowList topLevelWindows = QGuiApplication::topLevelWindows(); - for (QWindow *topLevelWindow : topLevelWindows) { - if ((topLevelWindow->type() & Qt::Popup) == Qt::Popup && topLevelWindow->isVisible()) { - topLevelWindow->hide(); - - if ((topLevelWindow->type() & Qt::Tool) == Qt::Tool) - hiddenWindows << topLevelWindow; - } - } -} - -- (void)applicationDidUnhide:(NSNotification *)notification -{ - if (reflectionDelegate - && [reflectionDelegate respondsToSelector:@selector(applicationDidUnhide:)]) - [reflectionDelegate applicationDidUnhide:notification]; - - for (QWindow *window : qAsConst(hiddenWindows)) - window->show(); - - hiddenWindows.clear(); -} - - (void)applicationDidBecomeActive:(NSNotification *)notification { if (reflectionDelegate diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index d1047e1965..50adbad518 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -400,6 +400,11 @@ void QCocoaWindow::setVisible(bool visible) } } + // Note: We do not guard the order out by checking NSWindow.visible, as AppKit will + // in some cases, such as when hiding the application, order out and make a window + // invisible, but keep it in a list of "hidden windows", that it then restores again + // when the application is unhidden. We need to call orderOut explicitly, to bring + // the window out of this "hidden list". [m_view.window orderOut:nil]; if (m_view.window == [NSApp keyWindow] && !eventDispatcher()->hasModalSession()) { From 5c014a48dc9d831457184af1b4302cc4e61632a7 Mon Sep 17 00:00:00 2001 From: Lars Schmertmann <Lars.Schmertmann@governikus.de> Date: Mon, 28 Jan 2019 19:44:34 +0100 Subject: [PATCH 1210/1650] Add missing translations for Android Task-number: QTBUG-72895 Change-Id: Ia9f6d0809c1d8f408a0818367ceb96599c13cbca Reviewed-by: BogDan Vatra <bogdan@kdab.com> Reviewed-by: Sergey Belyashov <Sergey.Belyashov@gmail.com> Reviewed-by: Takumi ASAKI <takumi.asaki@gmail.com> Reviewed-by: Liang Qi <liang.qi@qt.io> Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> --- src/android/java/res/values-el/strings.xml | 1 + src/android/java/res/values-es/strings.xml | 1 + src/android/java/res/values-et/strings.xml | 1 + src/android/java/res/values-fa/strings.xml | 1 + src/android/java/res/values-id/strings.xml | 1 + src/android/java/res/values-it/strings.xml | 1 + src/android/java/res/values-ja/strings.xml | 1 + src/android/java/res/values-ms/strings.xml | 1 + src/android/java/res/values-nb/strings.xml | 1 + src/android/java/res/values-nl/strings.xml | 1 + src/android/java/res/values-pl/strings.xml | 1 + src/android/java/res/values-pt-rBR/strings.xml | 1 + src/android/java/res/values-ro/strings.xml | 2 +- src/android/java/res/values-rs/strings.xml | 1 + src/android/java/res/values-ru/strings.xml | 1 + src/android/java/res/values-zh-rCN/strings.xml | 1 + src/android/java/res/values-zh-rTW/strings.xml | 1 + src/android/java/res/values/strings.xml | 2 +- 18 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/android/java/res/values-el/strings.xml b/src/android/java/res/values-el/strings.xml index 3cab212f2b..42b2b3b49d 100644 --- a/src/android/java/res/values-el/strings.xml +++ b/src/android/java/res/values-el/strings.xml @@ -3,4 +3,5 @@ <string name="ministro_not_found_msg">Δεν ήταν δυνατή η εύρεση της υπηρεσίας Ministro. Δεν είναι δυνατή η εκκίνηση της εφαρμογής.</string> <string name="ministro_needed_msg">Η εφαρμογή απαιτεί την υπηρεσία Ministro. Να εγκατασταθεί η υπηρεσία?</string> <string name="fatal_error_msg">Παρουσιάστηκε ένα κρίσιμο σφάλμα και η εφαρμογή δεν μπορεί να συνεχίσει.</string> + <string name="unsupported_android_version">Αυτή η έκδοση του Android δεν υποστηρίζεται.</string> </resources> diff --git a/src/android/java/res/values-es/strings.xml b/src/android/java/res/values-es/strings.xml index cf0b54d0b0..1da33a6444 100644 --- a/src/android/java/res/values-es/strings.xml +++ b/src/android/java/res/values-es/strings.xml @@ -3,4 +3,5 @@ <string name="ministro_not_found_msg">Servicio Ministro inesistente. Imposible ejecutar la aplicación.</string> <string name="ministro_needed_msg">Esta aplicación requiere el servicio Ministro. Instalarlo?</string> <string name="fatal_error_msg">La aplicación ha causado un error grave y no es posible continuar.</string> + <string name="unsupported_android_version">Esta versión de Android no es compatible.</string> </resources> diff --git a/src/android/java/res/values-et/strings.xml b/src/android/java/res/values-et/strings.xml index d55a3c1471..9620fd2bc8 100644 --- a/src/android/java/res/values-et/strings.xml +++ b/src/android/java/res/values-et/strings.xml @@ -3,4 +3,5 @@ <string name="ministro_not_found_msg">Ei suuda leida Ministro teenust.\nProgrammi ei saa käivitada.</string> <string name="ministro_needed_msg">See programm vajab Ministro teenust.\nKas soovite paigaldada?</string> <string name="fatal_error_msg">Programmiga juhtus fataalne viga.\nKahjuks ei saa jätkata.</string> + <string name="unsupported_android_version">Seda Androidi versiooni ei toetata.</string> </resources> diff --git a/src/android/java/res/values-fa/strings.xml b/src/android/java/res/values-fa/strings.xml index a8d1b87444..d1ee06118a 100644 --- a/src/android/java/res/values-fa/strings.xml +++ b/src/android/java/res/values-fa/strings.xml @@ -3,4 +3,5 @@ <string name="ministro_not_found_msg">سرویس Ministro را پیدا نمی‌کند. برنامه نمی‌تواند آغاز شود.</string> <string name="ministro_needed_msg">این نرم‌افزار به سرویس Ministro احتیاج دارد. آیا دوست دارید آن را نصب کنید؟</string> <string name="fatal_error_msg">خطایی اساسی در برنامه‌تان رخ داد و اجرای برنامه نمی‌تواند ادامه یابد.</string> + <string name="unsupported_android_version">این نسخه از Android پشتیبانی نمی شود</string> </resources> diff --git a/src/android/java/res/values-id/strings.xml b/src/android/java/res/values-id/strings.xml index aaa5bda0de..b25f568ee9 100644 --- a/src/android/java/res/values-id/strings.xml +++ b/src/android/java/res/values-id/strings.xml @@ -3,4 +3,5 @@ <string name="ministro_not_found_msg">Layanan Ministro tidak bisa ditemukan.\nAplikasi tidak bisa dimulai.</string> <string name="ministro_needed_msg">Aplikasi ini membutuhkan layanan Ministro. Apakah Anda ingin menginstalnya?</string> <string name="fatal_error_msg">Aplikasi Anda mengalami kesalahan fatal dan tidak dapat melanjutkan.</string> + <string name="unsupported_android_version">Versi Android ini tidak didukung.</string> </resources> diff --git a/src/android/java/res/values-it/strings.xml b/src/android/java/res/values-it/strings.xml index 4773419c44..9ba5fe2b1c 100644 --- a/src/android/java/res/values-it/strings.xml +++ b/src/android/java/res/values-it/strings.xml @@ -3,4 +3,5 @@ <string name="ministro_not_found_msg">Servizio Ministro inesistente. Impossibile eseguire \nl\'applicazione.</string> <string name="ministro_needed_msg">Questa applicazione richiede il servizio Ministro.Installarlo?</string> <string name="fatal_error_msg">L\'applicazione ha provocato un errore grave e non puo\' continuare.</string> + <string name="unsupported_android_version">Questa versione di Android non è supportata.</string> </resources> diff --git a/src/android/java/res/values-ja/strings.xml b/src/android/java/res/values-ja/strings.xml index ba1cfda9ec..40da7dce48 100644 --- a/src/android/java/res/values-ja/strings.xml +++ b/src/android/java/res/values-ja/strings.xml @@ -3,4 +3,5 @@ <string name="ministro_not_found_msg">Ministroサービスが見つかりません。\nアプリケーションが起動できません。</string> <string name="ministro_needed_msg">このアプリケーションにはMinistroサービスが必要です。 インストールしてもよろしいですか?</string> <string name="fatal_error_msg">アプリケーションで致命的なエラーが発生したため続行できません。</string> + <string name="unsupported_android_version">このバージョンのAndroidはサポートされていません。</string> </resources> diff --git a/src/android/java/res/values-ms/strings.xml b/src/android/java/res/values-ms/strings.xml index 6e3952eaec..bd27890eb2 100644 --- a/src/android/java/res/values-ms/strings.xml +++ b/src/android/java/res/values-ms/strings.xml @@ -3,4 +3,5 @@ <string name="ministro_not_found_msg">Tidak jumpa servis Ministro.\nAplikasi tidak boleh dimulakan.</string> <string name="ministro_needed_msg">Aplikasi ini memerlukan servis Ministro. Adakah anda ingin pasang servis itu?</string> <string name="fatal_error_msg">Aplikasi anda menemui ralat muat dan tidak boleh diteruskan.</string> + <string name="unsupported_android_version">Versi Android ini tidak disokong.</string> </resources> diff --git a/src/android/java/res/values-nb/strings.xml b/src/android/java/res/values-nb/strings.xml index 8a550e99a2..53529b7f52 100644 --- a/src/android/java/res/values-nb/strings.xml +++ b/src/android/java/res/values-nb/strings.xml @@ -3,4 +3,5 @@ <string name="ministro_not_found_msg">Kan ikke finne tjenesten Ministro. Applikasjonen kan ikke starte.</string> <string name="ministro_needed_msg">Denne applikasjonen krever tjenesten Ministro. Vil du installere denne?</string> <string name="fatal_error_msg">Applikasjonen fikk en kritisk feil og kan ikke fortsette</string> + <string name="unsupported_android_version">Denne versjonen av Android støttes ikke.</string> </resources> diff --git a/src/android/java/res/values-nl/strings.xml b/src/android/java/res/values-nl/strings.xml index 8a45a724ff..7e54587f61 100644 --- a/src/android/java/res/values-nl/strings.xml +++ b/src/android/java/res/values-nl/strings.xml @@ -3,4 +3,5 @@ <string name="ministro_not_found_msg">De Ministro service is niet gevonden.\nDe applicatie kan niet starten.</string> <string name="ministro_needed_msg">Deze applicatie maakt gebruik van de Ministro service. Wilt u deze installeren?</string> <string name="fatal_error_msg">Er is een fatale fout in de applicatie opgetreden. De applicatie kan niet verder gaan.</string> + <string name="unsupported_android_version">Deze versie van Android wordt niet ondersteund.</string> </resources> diff --git a/src/android/java/res/values-pl/strings.xml b/src/android/java/res/values-pl/strings.xml index 9fefc92dcd..e7feb01392 100644 --- a/src/android/java/res/values-pl/strings.xml +++ b/src/android/java/res/values-pl/strings.xml @@ -3,4 +3,5 @@ <string name="ministro_not_found_msg">Usługa Ministro nie została znaleziona.\nAplikacja nie może zostać uruchomiona.</string> <string name="ministro_needed_msg">Aplikacja wymaga usługi Ministro. Czy chcesz ją zainstalować?</string> <string name="fatal_error_msg">Wystąpił błąd krytyczny. Aplikacja zostanie zamknięta.</string> + <string name="unsupported_android_version">Ta wersja Androida nie jest obsługiwana.</string> </resources> diff --git a/src/android/java/res/values-pt-rBR/strings.xml b/src/android/java/res/values-pt-rBR/strings.xml index 67ac3f9f98..4bac77c784 100644 --- a/src/android/java/res/values-pt-rBR/strings.xml +++ b/src/android/java/res/values-pt-rBR/strings.xml @@ -3,4 +3,5 @@ <string name="ministro_not_found_msg">Não foi possível encontrar o serviço Ministro.\nA aplicação não pode iniciar.</string> <string name="ministro_needed_msg">Essa aplicação requer o serviço Ministro. Gostaria de instalá-lo?</string> <string name="fatal_error_msg">Sua aplicação encontrou um erro fatal e não pode continuar.</string> + <string name="unsupported_android_version">Esta versão do Android não é suportada.</string> </resources> diff --git a/src/android/java/res/values-ro/strings.xml b/src/android/java/res/values-ro/strings.xml index fef52ad3bd..d55c5b5c38 100644 --- a/src/android/java/res/values-ro/strings.xml +++ b/src/android/java/res/values-ro/strings.xml @@ -3,5 +3,5 @@ <string name="ministro_not_found_msg">Serviciul Ministro nu poate fi găsit.\nAplicaţia nu poate porni.</string> <string name="ministro_needed_msg">Această aplicaţie necesită serviciul Ministro.\nDoriţi să-l instalaţi?</string> <string name="fatal_error_msg">Aplicaţia dumneavoastră a întâmpinat o eroare fatală şi nu poate continua.</string> - <string name="unsupported_android_version">Versiune Android nesuportată.</string> + <string name="unsupported_android_version">Această versiune de Android nu este suportată.</string> </resources> diff --git a/src/android/java/res/values-rs/strings.xml b/src/android/java/res/values-rs/strings.xml index 3194ce9022..2a1e8284ce 100644 --- a/src/android/java/res/values-rs/strings.xml +++ b/src/android/java/res/values-rs/strings.xml @@ -3,4 +3,5 @@ <string name="ministro_not_found_msg">Ministro servise nije pronađen. Aplikacija ne može biti pokrenuta.</string> <string name="ministro_needed_msg">Ova aplikacija zahteva Ministro servis. Želite li da ga instalirate?</string> <string name="fatal_error_msg">Vaša aplikacija je naišla na fatalnu grešku i ne može nastaviti sa radom.</string> + <string name="unsupported_android_version">Ova verzija Android-a nije podržana.</string> </resources> diff --git a/src/android/java/res/values-ru/strings.xml b/src/android/java/res/values-ru/strings.xml index d3cee80f9d..ec853d22f9 100644 --- a/src/android/java/res/values-ru/strings.xml +++ b/src/android/java/res/values-ru/strings.xml @@ -3,4 +3,5 @@ <string name="ministro_not_found_msg">Сервис Ministro не найден.\nПриложение нельзя запустить.</string> <string name="ministro_needed_msg">Этому приложению необходим сервис Ministro. Вы хотите его установить?</string> <string name="fatal_error_msg">Ваше приложение столкнулось с фатальной ошибкой и не может более работать.</string> + <string name="unsupported_android_version">Эта версия Android не поддерживается.</string> </resources> diff --git a/src/android/java/res/values-zh-rCN/strings.xml b/src/android/java/res/values-zh-rCN/strings.xml index 2eb1269880..58cdd89946 100644 --- a/src/android/java/res/values-zh-rCN/strings.xml +++ b/src/android/java/res/values-zh-rCN/strings.xml @@ -3,4 +3,5 @@ <string name="ministro_not_found_msg">无法找到Ministro服务。\n应用程序无法启动。</string> <string name="ministro_needed_msg">此应用程序需要Ministro服务。您想安装它吗?</string> <string name="fatal_error_msg">您的应用程序遇到一个致命错误导致它无法继续。</string> + <string name="unsupported_android_version">这个版本的安卓系统不被支持。</string> </resources> diff --git a/src/android/java/res/values-zh-rTW/strings.xml b/src/android/java/res/values-zh-rTW/strings.xml index f6e68efa52..81d2bebdee 100644 --- a/src/android/java/res/values-zh-rTW/strings.xml +++ b/src/android/java/res/values-zh-rTW/strings.xml @@ -3,4 +3,5 @@ <string name="ministro_not_found_msg">無法找到Ministro服務。\n應用程序無法啟動。</string> <string name="ministro_needed_msg">此應用程序需要Ministro服務。您想安裝它嗎?</string> <string name="fatal_error_msg">您的應用程序遇到一個致命錯誤導致它無法繼續。</string> + <string name="unsupported_android_version">這個版本的安卓系統不被支持。</string> </resources> diff --git a/src/android/java/res/values/strings.xml b/src/android/java/res/values/strings.xml index 95b3385924..0110948dcf 100644 --- a/src/android/java/res/values/strings.xml +++ b/src/android/java/res/values/strings.xml @@ -4,5 +4,5 @@ <string name="ministro_not_found_msg">Can\'t find Ministro service.\nThe application can\'t start.</string> <string name="ministro_needed_msg">This application requires Ministro service. Would you like to install it?</string> <string name="fatal_error_msg">Your application encountered a fatal error and cannot continue.</string> - <string name="unsupported_android_version">Unsupported Android version.</string> + <string name="unsupported_android_version">This version of Android is not supported.</string> </resources> From 10565c5ef32457443cc950c26e2d8fab6941dac1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= <tor.arne.vestbo@qt.io> Date: Wed, 13 Feb 2019 15:49:26 +0100 Subject: [PATCH 1211/1650] macOS: Decouple screen property updates from application delegate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I489c37131bf715d45f147964de4a8cd8c02adbcb Fixes: QTBUG-72966 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> --- .../platforms/cocoa/qcocoaapplicationdelegate.mm | 12 ------------ src/plugins/platforms/cocoa/qcocoaintegration.h | 1 + src/plugins/platforms/cocoa/qcocoaintegration.mm | 3 +++ 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm index e255719cc1..2cf6672da9 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm +++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm @@ -115,22 +115,10 @@ QT_USE_NAMESPACE self = [super init]; if (self) { inLaunch = true; - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(updateScreens:) - name:NSApplicationDidChangeScreenParametersNotification - object:NSApp]; } return self; } -- (void)updateScreens:(NSNotification *)notification -{ - Q_UNUSED(notification); - if (QCocoaIntegration *ci = QCocoaIntegration::instance()) - ci->updateScreens(); -} - - (void)dealloc { [_dockMenu release]; diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h index 7de7e073de..04cb4e1226 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.h +++ b/src/plugins/platforms/cocoa/qcocoaintegration.h @@ -144,6 +144,7 @@ private: #endif QScopedPointer<QPlatformTheme> mPlatformTheme; QList<QCocoaScreen *> mScreens; + QMacScopedObserver m_screensObserver; #ifndef QT_NO_CLIPBOARD QCocoaClipboard *mCocoaClipboard; #endif diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index f6a49dd74f..affbee35b7 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -206,6 +206,9 @@ QCocoaIntegration::QCocoaIntegration(const QStringList ¶mList) // by explicitly setting the presentation option to the magic 'default value', // which will resolve to an actual value and result in screen invalidation. cocoaApplication.presentationOptions = NSApplicationPresentationDefault; + + m_screensObserver = QMacScopedObserver([NSApplication sharedApplication], + NSApplicationDidChangeScreenParametersNotification, [&]() { updateScreens(); }); updateScreens(); QMacInternalPasteboardMime::initializeMimeTypes(); From 3a1a97dabe11238d1580c8afaf6fcd8ea74fea68 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov <timur.pocheptsov@qt.io> Date: Tue, 19 Feb 2019 15:41:21 +0100 Subject: [PATCH 1212/1650] tst_http2::earlyResponse - fix a flaky and somewhat broken test 1. Fix erroneous logic, which was triggered in 'h2' mode (non-TLS connection) - after the initial protocol upgrade/POST request was handled, the server (on Windows specifically) was erroneously handling upcoming DATA frames by replying with another redirect response. 2. Make the test less heavy by sending 1 MB of Qt::Uninitialize instead of 10 MB - theoretically this could cause a timeout before the redirected request finished successfully. Task-number: QTBUG-73873 Change-Id: I961e0a5f50252988edd46d0e73baf96ee22eef3f Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> --- tests/auto/network/access/http2/http2srv.cpp | 14 ++++++++++++++ tests/auto/network/access/http2/http2srv.h | 1 + tests/auto/network/access/http2/tst_http2.cpp | 2 +- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/auto/network/access/http2/http2srv.cpp b/tests/auto/network/access/http2/http2srv.cpp index 1f9ffb8985..6e2220fa67 100644 --- a/tests/auto/network/access/http2/http2srv.cpp +++ b/tests/auto/network/access/http2/http2srv.cpp @@ -431,6 +431,13 @@ void Http2Server::readReady() if (connectionError) return; + if (redirectSent) { + // We are a "single shot" server, working in 'h2' mode, + // responding with a redirect code. Don't bother to handle + // anything else now. + return; + } + if (upgradeProtocol) { handleProtocolUpgrade(); } else if (waitingClientPreface) { @@ -800,6 +807,13 @@ void Http2Server::sendResponse(quint32 streamID, bool emptyBody) HttpHeader header; if (redirectWhileReading) { + if (redirectSent) { + // This is a "single-shot" server responding with a redirect code. + return; + } + + redirectSent = true; + qDebug("server received HEADERS frame (followed by DATA frames), redirecting ..."); Q_ASSERT(targetPort); header.push_back({":status", "308"}); diff --git a/tests/auto/network/access/http2/http2srv.h b/tests/auto/network/access/http2/http2srv.h index 87a17ced8b..ae3f084fdc 100644 --- a/tests/auto/network/access/http2/http2srv.h +++ b/tests/auto/network/access/http2/http2srv.h @@ -193,6 +193,7 @@ private: // Redirect, with status code 308, as soon as we've seen headers, while client // may still be sending DATA frames. See tst_Http2::earlyResponse(). bool redirectWhileReading = false; + bool redirectSent = false; quint16 targetPort = 0; QAtomicInt interrupted; protected slots: diff --git a/tests/auto/network/access/http2/tst_http2.cpp b/tests/auto/network/access/http2/tst_http2.cpp index 235b78c34a..52e98c1fc1 100644 --- a/tests/auto/network/access/http2/tst_http2.cpp +++ b/tests/auto/network/access/http2/tst_http2.cpp @@ -473,7 +473,7 @@ void tst_Http2::earlyResponse() runEventLoop(); QVERIFY(serverPort); - sendRequest(1, QNetworkRequest::NormalPriority, {10000000, Qt::Uninitialized}); + sendRequest(1, QNetworkRequest::NormalPriority, {1000000, Qt::Uninitialized}); runEventLoop(); From ba58776a795b3ddeeb9587780122f0cdaaa22933 Mon Sep 17 00:00:00 2001 From: Oliver Wolff <oliver.wolff@qt.io> Date: Wed, 13 Feb 2019 13:48:21 +0100 Subject: [PATCH 1213/1650] winrt: Add support for Visual Studio 2019 Change-Id: I5a07a3d20425a8c7ce2b2477792c379afeff5680 Reviewed-by: Andre de la Rocha <andre.rocha@qt.io> --- mkspecs/winrt-arm-msvc2019/qmake.conf | 19 ++++++++++ mkspecs/winrt-arm-msvc2019/qplatformdefs.h | 40 ++++++++++++++++++++ mkspecs/winrt-arm64-msvc2019/qmake.conf | 19 ++++++++++ mkspecs/winrt-arm64-msvc2019/qplatformdefs.h | 40 ++++++++++++++++++++ mkspecs/winrt-x64-msvc2019/qmake.conf | 19 ++++++++++ mkspecs/winrt-x64-msvc2019/qplatformdefs.h | 40 ++++++++++++++++++++ mkspecs/winrt-x86-msvc2019/qmake.conf | 18 +++++++++ mkspecs/winrt-x86-msvc2019/qplatformdefs.h | 40 ++++++++++++++++++++ 8 files changed, 235 insertions(+) create mode 100644 mkspecs/winrt-arm-msvc2019/qmake.conf create mode 100644 mkspecs/winrt-arm-msvc2019/qplatformdefs.h create mode 100644 mkspecs/winrt-arm64-msvc2019/qmake.conf create mode 100644 mkspecs/winrt-arm64-msvc2019/qplatformdefs.h create mode 100644 mkspecs/winrt-x64-msvc2019/qmake.conf create mode 100644 mkspecs/winrt-x64-msvc2019/qplatformdefs.h create mode 100644 mkspecs/winrt-x86-msvc2019/qmake.conf create mode 100644 mkspecs/winrt-x86-msvc2019/qplatformdefs.h diff --git a/mkspecs/winrt-arm-msvc2019/qmake.conf b/mkspecs/winrt-arm-msvc2019/qmake.conf new file mode 100644 index 0000000000..fe30a843eb --- /dev/null +++ b/mkspecs/winrt-arm-msvc2019/qmake.conf @@ -0,0 +1,19 @@ +# +# qmake configuration for winrt-arm-msvc2019 +# +# Written for Microsoft Visual C++ 2019 +# + +include(../common/winrt_winphone/qmake.conf) +DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_PC_APP WINAPI_PARTITION_PHONE_APP=1 ARM __ARM__ __arm__ + +QMAKE_CFLAGS += -FS +QMAKE_CXXFLAGS += -FS +QMAKE_LFLAGS += /MACHINE:ARM /NODEFAULTLIB:kernel32.lib + +QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib OneCore.lib + +VCPROJ_ARCH = ARM +WINSDK_VER = 10.0 +WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in +WINRT_MANIFEST.architecture = arm diff --git a/mkspecs/winrt-arm-msvc2019/qplatformdefs.h b/mkspecs/winrt-arm-msvc2019/qplatformdefs.h new file mode 100644 index 0000000000..4222bca8e1 --- /dev/null +++ b/mkspecs/winrt-arm-msvc2019/qplatformdefs.h @@ -0,0 +1,40 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../common/winrt_winphone/qplatformdefs.h" diff --git a/mkspecs/winrt-arm64-msvc2019/qmake.conf b/mkspecs/winrt-arm64-msvc2019/qmake.conf new file mode 100644 index 0000000000..8c16e93d26 --- /dev/null +++ b/mkspecs/winrt-arm64-msvc2019/qmake.conf @@ -0,0 +1,19 @@ +# +# qmake configuration for winrt-arm64-msvc2019 +# +# Written for Microsoft Visual C++ 2019 +# + +include(../common/winrt_winphone/qmake.conf) +DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_PC_APP WINAPI_PARTITION_PHONE_APP=1 arm64 __arm64__ __arm64__ + +QMAKE_CFLAGS += -FS +QMAKE_CXXFLAGS += -FS +QMAKE_LFLAGS += /MACHINE:arm64 /NODEFAULTLIB:kernel32.lib + +QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib OneCore.lib + +VCPROJ_ARCH = arm64 +WINSDK_VER = 10.0 +WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in +WINRT_MANIFEST.architecture = arm64 diff --git a/mkspecs/winrt-arm64-msvc2019/qplatformdefs.h b/mkspecs/winrt-arm64-msvc2019/qplatformdefs.h new file mode 100644 index 0000000000..4222bca8e1 --- /dev/null +++ b/mkspecs/winrt-arm64-msvc2019/qplatformdefs.h @@ -0,0 +1,40 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../common/winrt_winphone/qplatformdefs.h" diff --git a/mkspecs/winrt-x64-msvc2019/qmake.conf b/mkspecs/winrt-x64-msvc2019/qmake.conf new file mode 100644 index 0000000000..0d3b6d2196 --- /dev/null +++ b/mkspecs/winrt-x64-msvc2019/qmake.conf @@ -0,0 +1,19 @@ +# +# qmake configuration for winrt-x64-msvc2019 +# +# Written for Microsoft Visual C++ 2019 +# + +include(../common/winrt_winphone/qmake.conf) +DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_PC_APP WINAPI_PARTITION_PHONE_APP=1 X64 __X64__ __x64__ + +QMAKE_CFLAGS += -FS +QMAKE_CXXFLAGS += -FS +QMAKE_LFLAGS += /MACHINE:X64 /NODEFAULTLIB:kernel32.lib + +QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib OneCore.lib + +VCPROJ_ARCH = x64 +WINSDK_VER = 10.0 +WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in +WINRT_MANIFEST.architecture = x64 diff --git a/mkspecs/winrt-x64-msvc2019/qplatformdefs.h b/mkspecs/winrt-x64-msvc2019/qplatformdefs.h new file mode 100644 index 0000000000..4222bca8e1 --- /dev/null +++ b/mkspecs/winrt-x64-msvc2019/qplatformdefs.h @@ -0,0 +1,40 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../common/winrt_winphone/qplatformdefs.h" diff --git a/mkspecs/winrt-x86-msvc2019/qmake.conf b/mkspecs/winrt-x86-msvc2019/qmake.conf new file mode 100644 index 0000000000..8948e20ab1 --- /dev/null +++ b/mkspecs/winrt-x86-msvc2019/qmake.conf @@ -0,0 +1,18 @@ +# +# qmake configuration for winrt-x86-msvc2019 +# +# Written for Microsoft Visual C++ 2019 +# + +include(../common/winrt_winphone/qmake.conf) +DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_PC_APP WINAPI_PARTITION_PHONE_APP=1 X86 __X86__ __x86__ + +QMAKE_CFLAGS += -FS +QMAKE_CXXFLAGS += -FS +QMAKE_LFLAGS += /SAFESEH /MACHINE:X86 /NODEFAULTLIB:kernel32.lib + +QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib OneCore.lib +VCPROJ_ARCH = Win32 +WINSDK_VER = 10.0 +WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in +WINRT_MANIFEST.architecture = x86 diff --git a/mkspecs/winrt-x86-msvc2019/qplatformdefs.h b/mkspecs/winrt-x86-msvc2019/qplatformdefs.h new file mode 100644 index 0000000000..4222bca8e1 --- /dev/null +++ b/mkspecs/winrt-x86-msvc2019/qplatformdefs.h @@ -0,0 +1,40 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../common/winrt_winphone/qplatformdefs.h" From 130bede6196ba32cc7fcbd7773c7732045f0d80c Mon Sep 17 00:00:00 2001 From: Lars Schmertmann <Lars.Schmertmann@governikus.de> Date: Thu, 10 Jan 2019 15:11:18 +0100 Subject: [PATCH 1214/1650] Add translatable attribute to the app_name string to fix a lint warning Incomplete translation ---------------------- If an application has more than one locale, then all the strings declared in one language should also be translated in all other languages. If the string should not be translated, you can add the attribute translatable="false" on the <string> element, or you can define all your non-translatable strings in a resource file called donottranslate.xml. Or, you can ignore the issue with a tools:ignore="MissingTranslation" attribute. Change-Id: I6f93f34fc36a06de9a0b687a93cf58df941dbbcb Reviewed-by: Andy Shaw <andy.shaw@qt.io> --- src/tools/androiddeployqt/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp index b0df833b87..f57c612244 100644 --- a/src/tools/androiddeployqt/main.cpp +++ b/src/tools/androiddeployqt/main.cpp @@ -1261,7 +1261,7 @@ bool updateStringsXml(const Options &options) fprintf(stderr, "Can't open %s for writing.\n", qPrintable(fileName)); return false; } - file.write(QByteArray("<?xml version='1.0' encoding='utf-8'?><resources><string name=\"app_name\">") + file.write(QByteArray("<?xml version='1.0' encoding='utf-8'?><resources><string name=\"app_name\" translatable=\"false\">") .append(QFileInfo(options.applicationBinary).baseName().mid(sizeof("lib") - 1).toLatin1()) .append("</string></resources>\n")); return true; From ee8a5f4917d98a26f8dedd6802eac754d748b227 Mon Sep 17 00:00:00 2001 From: Mitch Curtis <mitch.curtis@qt.io> Date: Wed, 20 Feb 2019 13:17:51 +0100 Subject: [PATCH 1215/1650] Document that type information is lost when reading QSettings from INI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is quite an important detail for an otherwise useful format. We should make the user aware that they currently have a tradeoff: - Either you can store settings in one place on all platforms that your application targets and have to manually manage conversion from strings, or - Use native formats which can be hard to find and edit, but retain type information. Change-Id: Ic648524c9ebff25246d7cdefb7628ff5ddf84964 Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@qt.io> --- src/corelib/io/qsettings.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 0d2bd72d75..ed61c4aca0 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -2167,6 +2167,9 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile, \snippet settings/settings.cpp 15 + Note that type information is not preserved when reading settings from INI + files; all values will be returned as QString. + The \l{tools/settingseditor}{Settings Editor} example lets you experiment with different settings location and with fallbacks turned on or off. @@ -2448,7 +2451,10 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile, On 32-bit Windows or from a 64-bit application on 64-bit Windows, this works the same as specifying NativeFormat. This enum value was added in Qt 5.7. - \value IniFormat Store the settings in INI files. + \value IniFormat Store the settings in INI files. Note that type information + is not preserved when reading settings from INI files; + all values will be returned as QString. + \value InvalidFormat Special value returned by registerFormat(). \omitvalue CustomFormat1 \omitvalue CustomFormat2 From 904617dfb83f39a6a379635b64fea6fcd00f241a Mon Sep 17 00:00:00 2001 From: Edward Welbourne <edward.welbourne@qt.io> Date: Tue, 19 Feb 2019 13:25:12 +0100 Subject: [PATCH 1216/1650] Add missing increment of blacklisted tests for BXFAIL case The counter is just how many tests were blacklisted, regardless of their success or otherwise. Skipping its increment for BXFAIL is apt to introduce noise in our tracking of how many tests are blacklisted. Change-Id: I1dd74e5f6619121c21d8741be7bc4e2d1cb43fa9 Reviewed-by: Christian Stenger <christian.stenger@qt.io> --- src/testlib/qtestlog.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/testlib/qtestlog.cpp b/src/testlib/qtestlog.cpp index 3285a6d8a7..c3e7385217 100644 --- a/src/testlib/qtestlog.cpp +++ b/src/testlib/qtestlog.cpp @@ -470,6 +470,8 @@ void QTestLog::addBXFail(const char *msg, const char *file, int line) QTEST_ASSERT(msg); QTEST_ASSERT(file); + ++QTest::blacklists; + QTest::TestLoggers::addIncident(QAbstractTestLogger::BlacklistedXFail, msg, file, line); } From a4b8e7141b3dd3bf3c2ac139b44ece0f74b054d8 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher <ch.ehrlicher@gmx.de> Date: Fri, 15 Feb 2019 21:27:58 +0100 Subject: [PATCH 1217/1650] QtGui/Network/OpenGl/Widgets/Xml: use \nullptr in documentation Replace null and '\c nullptr' with \nullptr in the documentation. Change-Id: I58934eea06943309ba895833f1991629870ab45b Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> --- src/gui/kernel/qclipboard.cpp | 2 +- src/gui/kernel/qguiapplication.cpp | 2 +- src/gui/kernel/qopenglcontext.cpp | 3 +- src/gui/kernel/qplatformintegration.cpp | 4 +-- src/gui/kernel/qshortcutmap.cpp | 6 ++-- src/gui/opengl/qopenglfunctions.cpp | 7 ++-- src/gui/opengl/qopenglshaderprogram.cpp | 6 ++-- src/gui/painting/qbackingstore.cpp | 2 +- src/gui/text/qfontengine.cpp | 4 +-- src/gui/vulkan/qvulkaninstance.cpp | 2 +- src/network/access/qftp.cpp | 4 +-- src/network/socket/qlocalserver.cpp | 4 +-- src/network/socket/qnativesocketengine.cpp | 8 ++--- src/network/socket/qtcpserver.cpp | 2 +- .../ssl/qssldiffiehellmanparameters.cpp | 2 +- src/opengl/qglfunctions.cpp | 5 +-- src/opengl/qglshaderprogram.cpp | 6 ++-- src/testlib/qsignalspy.qdoc | 4 +-- src/widgets/dialogs/qfiledialog.cpp | 34 +++++++++---------- src/widgets/kernel/qlayout.cpp | 2 +- src/widgets/util/qundostack.cpp | 12 +++---- src/widgets/widgets/qsplitter.cpp | 4 +-- src/xml/sax/qxml.cpp | 7 ++-- 23 files changed, 70 insertions(+), 62 deletions(-) diff --git a/src/gui/kernel/qclipboard.cpp b/src/gui/kernel/qclipboard.cpp index a76150d91d..267c079ad9 100644 --- a/src/gui/kernel/qclipboard.cpp +++ b/src/gui/kernel/qclipboard.cpp @@ -439,7 +439,7 @@ void QClipboard::setPixmap(const QPixmap &pixmap, Mode mode) \fn QMimeData *QClipboard::mimeData(Mode mode) const Returns a pointer to a QMimeData representation of the current - clipboard data (can be NULL if the given \a mode is not + clipboard data (can be \nullptr if the given \a mode is not supported by the platform). The \a mode argument is used to control which part of the system diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 038b0857ae..4e0c45d8ae 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1023,7 +1023,7 @@ QList<QScreen *> QGuiApplication::screens() } /*! - Returns the screen at \a point, or \c nullptr if outside of any screen. + Returns the screen at \a point, or \nullptr if outside of any screen. The \a point is in relation to the virtualGeometry() of each set of virtual siblings. If the point maps to more than one set of virtual siblings the first diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index 4847a62b0f..acb6c3fe94 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -1235,7 +1235,8 @@ void QOpenGLContext::deleteQGLContext() Returns the platform-specific handle for the OpenGL implementation that is currently in use. (for example, a HMODULE on Windows) - On platforms that do not use dynamic GL switch the return value is null. + On platforms that do not use dynamic GL switching, the return value + is \nullptr. The library might be GL-only, meaning that windowing system interface functions (for example EGL) may live in another, separate library. diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp index bb20a160db..199ef0de07 100644 --- a/src/gui/kernel/qplatformintegration.cpp +++ b/src/gui/kernel/qplatformintegration.cpp @@ -291,7 +291,7 @@ QPlatformPixmap *QPlatformIntegration::createPlatformPixmap(QPlatformPixmap::Pix platform implementation is responsible for querying the configuriation from the provided native context. - Returns a pointer to a QPlatformOpenGLContext instance or \c NULL if the context could + Returns a pointer to a QPlatformOpenGLContext instance or \nullptr if the context could not be created. \sa QOpenGLContext @@ -647,7 +647,7 @@ void QPlatformIntegration::setApplicationIcon(const QIcon &icon) const pointer to the instance for which a platform-specific backend needs to be created. - Returns a pointer to a QPlatformOpenGLContext instance or \c NULL if the context could + Returns a pointer to a QPlatformOpenGLContext instance or \nullptr if the context could not be created. \sa QVulkanInstance diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp index 3bb42c1c0b..0395c1db38 100644 --- a/src/gui/kernel/qshortcutmap.cpp +++ b/src/gui/kernel/qshortcutmap.cpp @@ -175,7 +175,7 @@ int QShortcutMap::addShortcut(QObject *owner, const QKeySequence &key, Qt::Short /*! \internal Removes a shortcut from the global map. - If \a owner is 0, all entries in the map with the key sequence specified + If \a owner is \nullptr, all entries in the map with the key sequence specified is removed. If \a key is null, all sequences for \a owner is removed from the map. If \a id is 0, any identical \a key sequences owned by \a owner are removed. @@ -222,7 +222,7 @@ int QShortcutMap::removeShortcut(int id, QObject *owner, const QKeySequence &key /*! \internal Changes the enable state of a shortcut to \a enable. - If \a owner is 0, all entries in the map with the key sequence specified + If \a owner is \nullptr, all entries in the map with the key sequence specified is removed. If \a key is null, all sequences for \a owner is removed from the map. If \a id is 0, any identical \a key sequences owned by \a owner are changed. @@ -260,7 +260,7 @@ int QShortcutMap::setShortcutEnabled(bool enable, int id, QObject *owner, const /*! \internal Changes the auto repeat state of a shortcut to \a enable. - If \a owner is 0, all entries in the map with the key sequence specified + If \a owner is \nullptr, all entries in the map with the key sequence specified is removed. If \a key is null, all sequences for \a owner is removed from the map. If \a id is 0, any identical \a key sequences owned by \a owner are changed. diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp index 92770cb55f..8ec814296a 100644 --- a/src/gui/opengl/qopenglfunctions.cpp +++ b/src/gui/opengl/qopenglfunctions.cpp @@ -206,7 +206,8 @@ QOpenGLFunctions::QOpenGLFunctions() /*! Constructs a function resolver for \a context. If \a context - is null, then the resolver will be created for the current QOpenGLContext. + is \nullptr, then the resolver will be created for the current + QOpenGLContext. The context or another context in the group must be current. @@ -5035,8 +5036,8 @@ QOpenGLExtraFunctions::QOpenGLExtraFunctions() } /*! - Constructs a function resolver for context. If \a context is null, then - the resolver will be created for the current QOpenGLContext. + Constructs a function resolver for context. If \a context is \nullptr, + then the resolver will be created for the current QOpenGLContext. The context or another context in the group must be current. diff --git a/src/gui/opengl/qopenglshaderprogram.cpp b/src/gui/opengl/qopenglshaderprogram.cpp index c39177080d..f225d5dc75 100644 --- a/src/gui/opengl/qopenglshaderprogram.cpp +++ b/src/gui/opengl/qopenglshaderprogram.cpp @@ -3667,7 +3667,8 @@ QVector<float> QOpenGLShaderProgram::defaultInnerTessellationLevels() const Language (GLSL) are supported on this system; false otherwise. The \a context is used to resolve the GLSL extensions. - If \a context is null, then QOpenGLContext::currentContext() is used. + If \a context is \nullptr, then QOpenGLContext::currentContext() + is used. */ bool QOpenGLShaderProgram::hasOpenGLShaderPrograms(QOpenGLContext *context) { @@ -3694,7 +3695,8 @@ void QOpenGLShaderProgram::shaderDestroyed() this system; false otherwise. The \a context is used to resolve the GLSL extensions. - If \a context is null, then QOpenGLContext::currentContext() is used. + If \a context is \nullptr, then QOpenGLContext::currentContext() + is used. */ bool QOpenGLShader::hasOpenGLShaders(ShaderType type, QOpenGLContext *context) { diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index d935deb4d6..3fab903c4d 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -208,7 +208,7 @@ static bool isRasterSurface(QWindow *window) The \a window must either be the top level window represented by this backingstore, or a non-transient child of that window. Passing - \c nullptr falls back to using the backingstore's top level window. + \nullptr falls back to using the backingstore's top level window. If the \a window is a child window, the \a region should be in child window coordinates, and the \a offset should be the child window's offset in relation diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index c363807e5e..1719855e68 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -1022,8 +1022,8 @@ void QFontEngine::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metr Returns \c true if the font table idetified by \a tag exists in the font; returns \c false otherwise. - If \a buffer is NULL, stores the size of the buffer required for the font table data, - in bytes, in \a length. If \a buffer is not NULL and the capacity + If \a buffer is \nullptr, stores the size of the buffer required for the font table data, + in bytes, in \a length. If \a buffer is not \nullptr and the capacity of the buffer, passed in \a length, is sufficient to store the font table data, also copies the font table data to \a buffer. diff --git a/src/gui/vulkan/qvulkaninstance.cpp b/src/gui/vulkan/qvulkaninstance.cpp index 000c2b8caa..9895fec2ca 100644 --- a/src/gui/vulkan/qvulkaninstance.cpp +++ b/src/gui/vulkan/qvulkaninstance.cpp @@ -306,7 +306,7 @@ QVulkanInstance::QVulkanInstance() /*! Destructor. - \note current() will return \c nullptr once the instance is destroyed. + \note current() will return \nullptr once the instance is destroyed. */ QVulkanInstance::~QVulkanInstance() { diff --git a/src/network/access/qftp.cpp b/src/network/access/qftp.cpp index d33355c470..4e399f018f 100644 --- a/src/network/access/qftp.cpp +++ b/src/network/access/qftp.cpp @@ -1826,8 +1826,8 @@ int QFtp::cd(const QString &dir) is data available to read. You can then read the data with the read() or readAll() functions. - If \a dev is not 0, the data is written directly to the device \a - dev. Make sure that the \a dev pointer is valid for the duration + If \a dev is not \nullptr, the data is written directly to the device + \a dev. Make sure that the \a dev pointer is valid for the duration of the operation (it is safe to delete it when the commandFinished() signal is emitted). In this case the readyRead() signal is \e not emitted and you cannot read data with the diff --git a/src/network/socket/qlocalserver.cpp b/src/network/socket/qlocalserver.cpp index a9789b7d04..c5bd599a51 100644 --- a/src/network/socket/qlocalserver.cpp +++ b/src/network/socket/qlocalserver.cpp @@ -506,8 +506,8 @@ void QLocalServer::setMaxPendingConnections(int numConnections) /*! Waits for at most \a msec milliseconds or until an incoming connection is available. Returns \c true if a connection is available; otherwise - returns \c false. If the operation timed out and \a timedOut is not 0, - *timedOut will be set to true. + returns \c false. If the operation timed out and \a timedOut is not + \nullptr, *timedOut will be set to true. This is a blocking function call. Its use is ill-advised in a single-threaded GUI application, since the whole application will stop diff --git a/src/network/socket/qnativesocketengine.cpp b/src/network/socket/qnativesocketengine.cpp index 8947a7ee8a..5126a5330f 100644 --- a/src/network/socket/qnativesocketengine.cpp +++ b/src/network/socket/qnativesocketengine.cpp @@ -999,8 +999,8 @@ void QNativeSocketEngine::close() /*! Waits for \a msecs milliseconds or until the socket is ready for - reading. If \a timedOut is not 0 and \a msecs milliseconds have - passed, the value of \a timedOut is set to true. + reading. If \a timedOut is not \nullptr and \a msecs milliseconds + have passed, the value of \a timedOut is set to true. Returns \c true if data is available for reading; otherwise returns false. @@ -1039,8 +1039,8 @@ bool QNativeSocketEngine::waitForRead(int msecs, bool *timedOut) /*! Waits for \a msecs milliseconds or until the socket is ready for - writing. If \a timedOut is not 0 and \a msecs milliseconds have - passed, the value of \a timedOut is set to true. + writing. If \a timedOut is not \nullptr and \a msecs milliseconds + have passed, the value of \a timedOut is set to true. Returns \c true if data is available for writing; otherwise returns false. diff --git a/src/network/socket/qtcpserver.cpp b/src/network/socket/qtcpserver.cpp index eddf789921..56c700ca8f 100644 --- a/src/network/socket/qtcpserver.cpp +++ b/src/network/socket/qtcpserver.cpp @@ -493,7 +493,7 @@ QHostAddress QTcpServer::serverAddress() const Waits for at most \a msec milliseconds or until an incoming connection is available. Returns \c true if a connection is available; otherwise returns \c false. If the operation timed out - and \a timedOut is not 0, *\a timedOut will be set to true. + and \a timedOut is not \nullptr, *\a timedOut will be set to true. This is a blocking function call. Its use is disadvised in a single-threaded GUI application, since the whole application will diff --git a/src/network/ssl/qssldiffiehellmanparameters.cpp b/src/network/ssl/qssldiffiehellmanparameters.cpp index 7fbcff2861..65041d4456 100644 --- a/src/network/ssl/qssldiffiehellmanparameters.cpp +++ b/src/network/ssl/qssldiffiehellmanparameters.cpp @@ -136,7 +136,7 @@ QSslDiffieHellmanParameters QSslDiffieHellmanParameters::fromEncoded(const QByte to check whether the Diffie-Hellman parameters were valid and loaded correctly. - In particular, if \a device is \c nullptr or not open for reading, an invalid + In particular, if \a device is \nullptr or not open for reading, an invalid object will be returned. \sa isValid() diff --git a/src/opengl/qglfunctions.cpp b/src/opengl/qglfunctions.cpp index 7fe7102510..f22f9f470b 100644 --- a/src/opengl/qglfunctions.cpp +++ b/src/opengl/qglfunctions.cpp @@ -170,7 +170,8 @@ QGLFunctions::QGLFunctions() /*! Constructs a function resolver for \a context. If \a context - is null, then the resolver will be created for the current QGLContext. + is \nullptr, then the resolver will be created for the current + QGLContext. An object constructed in this way can only be used with \a context and other contexts that share with it. Use initializeGLFunctions() @@ -305,7 +306,7 @@ bool QGLFunctions::hasOpenGLFeature(QGLFunctions::OpenGLFeature feature) const /*! Initializes GL function resolution for \a context. If \a context - is null, then the current QGLContext will be used. + is \nullptr, then the current QGLContext will be used. After calling this function, the QGLFunctions object can only be used with \a context and other contexts that share with it. diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp index 545df8fa44..35f60318be 100644 --- a/src/opengl/qglshaderprogram.cpp +++ b/src/opengl/qglshaderprogram.cpp @@ -3169,7 +3169,8 @@ GLenum QGLShaderProgram::geometryOutputType() const Language (GLSL) are supported on this system; false otherwise. The \a context is used to resolve the GLSL extensions. - If \a context is null, then QGLContext::currentContext() is used. + If \a context is \nullptr, then QGLContext::currentContext() is + used. */ bool QGLShaderProgram::hasOpenGLShaderPrograms(const QGLContext *context) { @@ -3207,7 +3208,8 @@ void QGLShaderProgram::shaderDestroyed() this system; false otherwise. The \a context is used to resolve the GLSL extensions. - If \a context is null, then QGLContext::currentContext() is used. + If \a context is \nullptr, then QGLContext::currentContext() is + used. \since 4.7 */ diff --git a/src/testlib/qsignalspy.qdoc b/src/testlib/qsignalspy.qdoc index 77affc9a4b..3352307d69 100644 --- a/src/testlib/qsignalspy.qdoc +++ b/src/testlib/qsignalspy.qdoc @@ -63,7 +63,7 @@ Constructs a new QSignalSpy that listens for emissions of the \a signal from the QObject \a object. If QSignalSpy is not able to listen for a - valid signal (for example, because \a object is null or \a signal does + valid signal (for example, because \a object is \nullptr or \a signal does not denote a valid signal of \a object), an explanatory warning message will be output using qWarning() and subsequent calls to \c isValid() will return false. @@ -77,7 +77,7 @@ Constructs a new QSignalSpy that listens for emissions of the \a signal from the QObject \a object. If QSignalSpy is not able to listen for a - valid signal (for example, because \a object is null or \a signal does + valid signal (for example, because \a object is \nullptr or \a signal does not denote a valid signal of \a object), an explanatory warning message will be output using qWarning() and subsequent calls to \c isValid() will return false. diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index d8a4ad5f24..625da78794 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -2129,8 +2129,8 @@ QString QFileDialog::labelText(DialogLabel label) const \snippet code/src_gui_dialogs_qfiledialog.cpp 8 The function creates a modal file dialog with the given \a parent widget. - If \a parent is not 0, the dialog will be shown centered over the parent - widget. + If \a parent is not \nullptr, the dialog will be shown centered over the + parent widget. The file dialog's working directory will be set to \a dir. If \a dir includes a file name, the file will be selected. Only files that match the @@ -2152,8 +2152,8 @@ QString QFileDialog::labelText(DialogLabel label) const native file dialog and not a QFileDialog. On Windows the dialog will spin a blocking modal event loop that will not - dispatch any QTimers, and if \a parent is not 0 then it will position the - dialog just below the parent's title bar. + dispatch any QTimers, and if \a parent is not \nullptr then it will position + the dialog just below the parent's title bar. On Unix/X11, the normal behavior of the file dialog is to resolve and follow symlinks. For example, if \c{/usr/tmp} is a symlink to \c{/var/tmp}, @@ -2242,8 +2242,8 @@ QUrl QFileDialog::getOpenFileUrl(QWidget *parent, \snippet code/src_gui_dialogs_qfiledialog.cpp 9 This function creates a modal file dialog with the given \a parent widget. - If \a parent is not 0, the dialog will be shown centered over the parent - widget. + If \a parent is not \nullptr, the dialog will be shown centered over the + parent widget. The file dialog's working directory will be set to \a dir. If \a dir includes a file name, the file will be selected. The filter is set to @@ -2261,8 +2261,8 @@ QUrl QFileDialog::getOpenFileUrl(QWidget *parent, native file dialog and not a QFileDialog. On Windows the dialog will spin a blocking modal event loop that will not - dispatch any QTimers, and if \a parent is not 0 then it will position the - dialog just below the parent's title bar. + dispatch any QTimers, and if \a parent is not \nullptr then it will position + the dialog just below the parent's title bar. On Unix/X11, the normal behavior of the file dialog is to resolve and follow symlinks. For example, if \c{/usr/tmp} is a symlink to \c{/var/tmp}, @@ -2434,8 +2434,8 @@ void QFileDialog::getOpenFileContent(const QString &nameFilter, const std::funct by the user. The file does not have to exist. It creates a modal file dialog with the given \a parent widget. If - \a parent is not 0, the dialog will be shown centered over the parent - widget. + \a parent is not \nullptr, the dialog will be shown centered over the + parent widget. \snippet code/src_gui_dialogs_qfiledialog.cpp 11 @@ -2461,9 +2461,9 @@ void QFileDialog::getOpenFileContent(const QString &nameFilter, const std::funct native file dialog and not a QFileDialog. On Windows the dialog will spin a blocking modal event loop that will not - dispatch any QTimers, and if \a parent is not 0 then it will position the - dialog just below the parent's title bar. On \macos, with its native file - dialog, the filter argument is ignored. + dispatch any QTimers, and if \a parent is not \nullptr then it will + position the dialog just below the parent's title bar. On \macos, with its + native file dialog, the filter argument is ignored. On Unix/X11, the normal behavior of the file dialog is to resolve and follow symlinks. For example, if \c{/usr/tmp} is a symlink to \c{/var/tmp}, @@ -2553,8 +2553,8 @@ QUrl QFileDialog::getSaveFileUrl(QWidget *parent, \snippet code/src_gui_dialogs_qfiledialog.cpp 12 This function creates a modal file dialog with the given \a parent widget. - If \a parent is not 0, the dialog will be shown centered over the parent - widget. + If \a parent is not \nullptr, the dialog will be shown centered over the + parent widget. The dialog's working directory is set to \a dir, and the caption is set to \a caption. Either of these may be an empty string in which case the @@ -2578,8 +2578,8 @@ QUrl QFileDialog::getSaveFileUrl(QWidget *parent, symlinks as regular directories. On Windows, the dialog will spin a blocking modal event loop that will not - dispatch any QTimers, and if \a parent is not 0 then it will position the - dialog just below the parent's title bar. + dispatch any QTimers, and if \a parent is not \nullptr then it will position + the dialog just below the parent's title bar. \warning Do not delete \a parent during the execution of the dialog. If you want to do this, you should create the dialog yourself using one of the diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp index f27851c7bb..e3f6a56875 100644 --- a/src/widgets/kernel/qlayout.cpp +++ b/src/widgets/kernel/qlayout.cpp @@ -109,7 +109,7 @@ static int menuBarHeightForWidth(QWidget *menubar, int w) /*! Constructs a new top-level QLayout, with parent \a parent. - \a parent may not be a \c nullptr. + \a parent may not be a \nullptr. The layout is set directly as the top-level layout for \a parent. There can be only one top-level layout for a diff --git a/src/widgets/util/qundostack.cpp b/src/widgets/util/qundostack.cpp index e928b9fe37..8788c42252 100644 --- a/src/widgets/util/qundostack.cpp +++ b/src/widgets/util/qundostack.cpp @@ -102,9 +102,9 @@ QT_BEGIN_NAMESPACE /*! Constructs a QUndoCommand object with the given \a parent and \a text. - If \a parent is not 0, this command is appended to parent's child list. - The parent command then owns this command and will delete it in its - destructor. + If \a parent is not \nullptr, this command is appended to parent's + child list. The parent command then owns this command and will delete + it in its destructor. \sa ~QUndoCommand() */ @@ -118,9 +118,9 @@ QUndoCommand::QUndoCommand(const QString &text, QUndoCommand *parent) /*! Constructs a QUndoCommand object with parent \a parent. - If \a parent is not 0, this command is appended to parent's child list. - The parent command then owns this command and will delete it in its - destructor. + If \a parent is not \nullptr, this command is appended to parent's + child list. The parent command then owns this command and will delete + it in its destructor. \sa ~QUndoCommand() */ diff --git a/src/widgets/widgets/qsplitter.cpp b/src/widgets/widgets/qsplitter.cpp index 0b90714363..98bb23caad 100644 --- a/src/widgets/widgets/qsplitter.cpp +++ b/src/widgets/widgets/qsplitter.cpp @@ -1232,7 +1232,7 @@ QSplitterHandle *QSplitter::createHandle() /*! Returns the handle to the left of (or above) the item in the - splitter's layout at the given \a index, or \c nullptr if there is no such item. + splitter's layout at the given \a index, or \nullptr if there is no such item. The handle at index 0 is always hidden. For right-to-left languages such as Arabic and Hebrew, the layout @@ -1251,7 +1251,7 @@ QSplitterHandle *QSplitter::handle(int index) const /*! Returns the widget at the given \a index in the splitter's layout, - or \c nullptr if there is no such widget. + or \nullptr if there is no such widget. \sa count(), handle(), indexOf(), insertWidget() */ diff --git a/src/xml/sax/qxml.cpp b/src/xml/sax/qxml.cpp index f4e6937146..0e3a87e883 100644 --- a/src/xml/sax/qxml.cpp +++ b/src/xml/sax/qxml.cpp @@ -2613,8 +2613,9 @@ void QXmlSimpleReaderPrivate::initIncrementalParsing() is returned. If no such feature exists the return value is undefined. - If \a ok is not 0: \c{*}\a{ok} is set to true if the reader has the - feature called \a name; otherwise \c{*}\a{ok} is set to false. + If \a ok is not \nullptr: \c{*}\a{ok} is set to true if the + reader has the feature called \a name; otherwise \c{*}\a{ok} is + set to false. \sa setFeature(), hasFeature() */ @@ -2643,7 +2644,7 @@ void QXmlSimpleReaderPrivate::initIncrementalParsing() If the reader has the property \a name, this function returns the value of the property; otherwise the return value is undefined. - If \a ok is not 0: if the reader has the \a name property + If \a ok is not \nullptr: if the reader has the \a name property \c{*}\a{ok} is set to true; otherwise \c{*}\a{ok} is set to false. \sa setProperty(), hasProperty() From ca32a373b31b087b602ca555151e01ed8ea601c1 Mon Sep 17 00:00:00 2001 From: Lorn Potter <lorn.potter@gmail.com> Date: Wed, 20 Feb 2019 11:46:07 +1000 Subject: [PATCH 1218/1650] wasm: fix crash on window close MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I07d6edfbfbf056240262b833ccb708dc15f830a3 Fixes: QTBUG-73678 Task-number: QTBUG-73678 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io> --- src/plugins/platforms/wasm/qwasmwindow.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/wasm/qwasmwindow.cpp b/src/plugins/platforms/wasm/qwasmwindow.cpp index 25a0190053..39797cb09d 100644 --- a/src/plugins/platforms/wasm/qwasmwindow.cpp +++ b/src/plugins/platforms/wasm/qwasmwindow.cpp @@ -198,8 +198,10 @@ void QWasmWindow::injectMouseReleased(const QPoint &local, const QPoint &global, if (!hasTitleBar() || button != Qt::LeftButton) return; - if (closeButtonRect().contains(global) && m_activeControl == QWasmCompositor::SC_TitleBarCloseButton) + if (closeButtonRect().contains(global) && m_activeControl == QWasmCompositor::SC_TitleBarCloseButton) { window()->close(); + return; + } if (maxButtonRect().contains(global) && m_activeControl == QWasmCompositor::SC_TitleBarMaxButton) { window()->setWindowState(Qt::WindowMaximized); From 70b558ad5b7972178b990b33cbd73694775b265f Mon Sep 17 00:00:00 2001 From: Lorn Potter <lorn.potter@gmail.com> Date: Tue, 19 Feb 2019 17:07:50 +1000 Subject: [PATCH 1219/1650] wasm: fix system lib detection and use MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a revert of eea08d376ac5cb35ff03be630923f21f7fa3aecd. We need these flags to be added to the compiler in order to find the emscripten ports to be able to use them. Task-number: QTBUG-73127 Change-Id: Icf70f456947aef04dc79b2328f2e95fb1e94fcf8 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io> --- mkspecs/wasm-emscripten/qmake.conf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mkspecs/wasm-emscripten/qmake.conf b/mkspecs/wasm-emscripten/qmake.conf index 6c4e62aff2..a9ded4be12 100644 --- a/mkspecs/wasm-emscripten/qmake.conf +++ b/mkspecs/wasm-emscripten/qmake.conf @@ -21,6 +21,11 @@ EMCC_COMMON_LFLAGS = \ --bind \ -s \"BINARYEN_TRAP_MODE=\'clamp\'\" +EMCC_USE_PORTS_FLAGS = \ + -s USE_LIBPNG=1 \ + -s USE_FREETYPE=1 \ + -s USE_ZLIB=1 + # The -s arguments can also be used with release builds, # but are here in debug for clarity. EMCC_COMMON_LFLAGS_DEBUG = \ @@ -38,6 +43,9 @@ QMAKE_COMPILER += emscripten QMAKE_CC = emcc QMAKE_CXX = em++ +QMAKE_CFLAGS += $$EMCC_USE_PORTS_FLAGS +QMAKE_CXXFLAGS += $$EMCC_USE_PORTS_FLAGS + # Practical debugging setup: # "-g4" preserves function names for stack traces # "-Os" produces reasonably sized binaries From 0f163887b526d00ccdcead907dde042aa370fc16 Mon Sep 17 00:00:00 2001 From: Juha Karjalainen <juha.karjalainen@qt.io> Date: Tue, 19 Feb 2019 13:57:47 +0200 Subject: [PATCH 1220/1650] Fix blacklisting tst_QTimer::basic_chrono() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Blacklisting did not work as blacklist should have contained osx instead macos Change-Id: Ifd76a38d371ccce545eb5df030aaa819b00a5b48 Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@qt.io> --- tests/auto/corelib/kernel/qtimer/BLACKLIST | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/corelib/kernel/qtimer/BLACKLIST b/tests/auto/corelib/kernel/qtimer/BLACKLIST index c31e15f171..16cbab4587 100644 --- a/tests/auto/corelib/kernel/qtimer/BLACKLIST +++ b/tests/auto/corelib/kernel/qtimer/BLACKLIST @@ -2,4 +2,4 @@ windows osx [basic_chrono] -macos +osx From 7227e54445021b8c2ce4f4ab638cc7d43e32a5a7 Mon Sep 17 00:00:00 2001 From: Oliver Wolff <oliver.wolff@qt.io> Date: Wed, 20 Feb 2019 14:05:36 +0100 Subject: [PATCH 1221/1650] qmake: Fix COPIES for Visual Studio projects QINSTALLS is not set when Visual Studio projects are used. Use its resolved value in case that Visual Studio projects are generated. Change-Id: I8c21d4335971f45e56b3549086cb803c2d464158 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io> --- mkspecs/features/file_copies.prf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mkspecs/features/file_copies.prf b/mkspecs/features/file_copies.prf index 58e07bd393..8a718d8a81 100644 --- a/mkspecs/features/file_copies.prf +++ b/mkspecs/features/file_copies.prf @@ -44,7 +44,9 @@ for (cp, COPIES) { $${pfx}.output = $$path/${QMAKE_FUNC_FILE_IN_qtStripSrcDir_$$cp} } $${pfx}.input = $${pfx}.files - $${pfx}.commands = $(QINSTALL) ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT} + contains(TEMPLATE, "vc.*"): copycommand = $$QMAKE_QMAKE -install qinstall + else: copycommand = $(QINSTALL) + $${pfx}.commands = $$copycommand ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT} $${pfx}.name = COPY ${QMAKE_FILE_IN} $${pfx}.CONFIG = no_link no_clean target_predeps QMAKE_EXTRA_COMPILERS += $${pfx} From 6a314669511fe7b36abc8da832c80de32fa567d9 Mon Sep 17 00:00:00 2001 From: Martin Koller <kollix@aon.at> Date: Fri, 4 Jan 2019 21:58:51 +0100 Subject: [PATCH 1222/1650] ensure signal subWindowActivated() triggers even when widget has focus A widget being added to QMdiArea which currently has focus did not trigger the subWindowActivated() signal since the connection to the method _q_processWindowStateChanged, which emits the signal (set up in appendChild()), was just done after the focus was set back again to the added widget. Setting the focus makes the widget active. This patch changes the order: first call appendChild(), then set focus Change-Id: I3aaf1728dc082d1323c7fbd62bfdbd2af87ab2ce Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> --- src/widgets/widgets/qmdiarea.cpp | 4 +++- tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/widgets/widgets/qmdiarea.cpp b/src/widgets/widgets/qmdiarea.cpp index feea7cd050..0ce561860e 100644 --- a/src/widgets/widgets/qmdiarea.cpp +++ b/src/widgets/widgets/qmdiarea.cpp @@ -1988,9 +1988,11 @@ QMdiSubWindow *QMdiArea::addSubWindow(QWidget *widget, Qt::WindowFlags windowFla Q_ASSERT(child->testAttribute(Qt::WA_DeleteOnClose)); } + d->appendChild(child); + if (childFocus) childFocus->setFocus(); - d->appendChild(child); + return child; } diff --git a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp index 67b79e3faf..046899ce05 100644 --- a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp +++ b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp @@ -333,6 +333,7 @@ void tst_QMdiArea::subWindowActivated() for ( i = 0; i < count; ++i ) { QWidget *widget = new QWidget(workspace, 0); widget->setAttribute(Qt::WA_DeleteOnClose); + widget->setFocus(); workspace->addSubWindow(widget)->show(); widget->show(); qApp->processEvents(); From c79b27dbcb885dc1bca69d4605993f7a096887b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tony=20Saraj=C3=A4rvi?= <tony.sarajarvi@qt.io> Date: Tue, 11 Sep 2018 14:18:50 +0300 Subject: [PATCH 1223/1650] Remove "insignificant" flag from qfilesystemmodel test Due to removal of insignificant flag in tst_qfilesystemmode.pro a bunch of tests will either fail or crash in different operating systems. Task-number: QTBUG-70572 Task-number: QTBUG-70573 Task-number: QTBUG-29403 Change-Id: I44925187acd72e600d2fec4f2604b67c66ecdd6b Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Heikki Halmet <heikki.halmet@qt.io> --- tests/auto/widgets/dialogs/qfilesystemmodel/BLACKLIST | 11 +++++++++++ .../dialogs/qfilesystemmodel/qfilesystemmodel.pro | 5 +++-- .../dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp | 4 ++++ 3 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 tests/auto/widgets/dialogs/qfilesystemmodel/BLACKLIST diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/BLACKLIST b/tests/auto/widgets/dialogs/qfilesystemmodel/BLACKLIST new file mode 100644 index 0000000000..01679eb6ee --- /dev/null +++ b/tests/auto/widgets/dialogs/qfilesystemmodel/BLACKLIST @@ -0,0 +1,11 @@ +winrt +[sort:QFileDialog usage] +ubuntu +b2qt +[specialFiles] +ubuntu +b2qt +[dirsBeforeFiles] +ubuntu +b2qt +windows diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/qfilesystemmodel.pro b/tests/auto/widgets/dialogs/qfilesystemmodel/qfilesystemmodel.pro index bc4671f60c..db8cf7de3f 100644 --- a/tests/auto/widgets/dialogs/qfilesystemmodel/qfilesystemmodel.pro +++ b/tests/auto/widgets/dialogs/qfilesystemmodel/qfilesystemmodel.pro @@ -1,3 +1,6 @@ +INCLUDEPATH += ../../../../shared +HEADERS += ../../../../shared/emulationdetector.h + CONFIG += testcase # This testcase can be slow on Windows and OS X, and may interfere with other file system tests. win32:testcase.timeout = 900 @@ -8,5 +11,3 @@ QT += core-private testlib SOURCES += tst_qfilesystemmodel.cpp TARGET = tst_qfilesystemmodel - -CONFIG += insignificant_test # QTBUG-29403 diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp index 9ee5292fcb..665a116a3a 100644 --- a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp +++ b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp @@ -27,6 +27,7 @@ ****************************************************************************/ +#include <emulationdetector.h> #include <QtTest/QtTest> #ifdef QT_BUILD_INTERNAL #include <private/qfilesystemmodel_p.h> @@ -788,6 +789,9 @@ void tst_QFileSystemModel::sort() MyFriendFileSystemModel *myModel = new MyFriendFileSystemModel(); QTreeView *tree = new QTreeView(); + if (fileDialogMode && EmulationDetector::isRunningArmOnX86()) + QSKIP("Crashes in QEMU. QTBUG-70572"); + #ifdef QT_BUILD_INTERNAL if (fileDialogMode) myModel->d_func()->disableRecursiveSort = true; From 06b29a62de60a631af77ee887ccf2d24d6871df2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tony=20Saraj=C3=A4rvi?= <tony.sarajarvi@qt.io> Date: Wed, 20 Feb 2019 11:07:59 +0200 Subject: [PATCH 1224/1650] Add keyword "macos" to testlib blacklisting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With "macos" keyword in place, we can blacklist using that keyword instead of the old "osx". Change-Id: Ib7a2f88265271df152320cce8594b8f788b47687 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Simon Hausmann <simon.hausmann@qt.io> Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@qt.io> --- src/testlib/qtestblacklist.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/testlib/qtestblacklist.cpp b/src/testlib/qtestblacklist.cpp index f430294142..ae2913da9a 100644 --- a/src/testlib/qtestblacklist.cpp +++ b/src/testlib/qtestblacklist.cpp @@ -104,6 +104,7 @@ static QSet<QByteArray> keywords() #endif #ifdef Q_OS_OSX << "osx" + << "macos" #endif #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) << "windows" From 1d3a162bfe38f8a3cd576ca17ea7e0f71a55e074 Mon Sep 17 00:00:00 2001 From: Jan Grulich <jgrulich@redhat.com> Date: Mon, 18 Feb 2019 13:15:31 +0100 Subject: [PATCH 1225/1650] Properly convert filename to bytearray when sending over portal We should be using QFile::encodeName() to properly convert filenames from string to bytearray. This takes user's locale into account. Change-Id: I090f73f21feb73af166e88baa0e7f4a595cdb25b Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> --- .../xdgdesktopportal/qxdgdesktopportalfiledialog.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp index 5e94d1558e..dcf52921aa 100644 --- a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp +++ b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp @@ -48,6 +48,7 @@ #include <QDBusPendingCallWatcher> #include <QDBusPendingReply> +#include <QFile> #include <QMetaType> #include <QMimeType> #include <QMimeDatabase> @@ -181,10 +182,10 @@ void QXdgDesktopPortalFileDialog::openPortal() if (d->saveFile) { if (!d->directory.isEmpty()) - options.insert(QLatin1String("current_folder"), d->directory.toLatin1().append('\0')); + options.insert(QLatin1String("current_folder"), QFile::encodeName(d->directory).append('\0')); if (!d->selectedFiles.isEmpty()) - options.insert(QLatin1String("current_file"), d->selectedFiles.first().toLatin1().append('\0')); + options.insert(QLatin1String("current_file"), QFile::encodeName(d->selectedFiles.first()).append('\0')); } // Insert filters From d3eb9e944ac73f238b8716bb25b8051377bba946 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov <timur.pocheptsov@qt.io> Date: Wed, 20 Feb 2019 13:30:52 +0100 Subject: [PATCH 1226/1650] Make tst_QUdpSocket::lincLocalIPv6 less sadistic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It fails on CI (Windows 10). Given our qabstractsocket disables read notifications/stops emitting readyRead if it already has pending data (unbuffered, aka UDP socket type) - make sure we do not suffer from this. The change does not affect the test's logic (unless the logic was to fail), it just makes it more fail-proof. Change-Id: I6c9b7ded20478f675260872a2a7032b4f356f197 Fixes: QTBUG-73884 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> --- tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp index 8ebb27e58c..707c1acf48 100644 --- a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp @@ -1640,15 +1640,14 @@ void tst_QUdpSocket::linkLocalIPv6() sockets << s; } - QUdpSocket neutral; - QVERIFY(neutral.bind(QHostAddress(QHostAddress::AnyIPv6))); - QSignalSpy neutralReadSpy(&neutral, SIGNAL(readyRead())); - QByteArray testData("hello"); foreach (QUdpSocket *s, sockets) { + QUdpSocket neutral; + QVERIFY(neutral.bind(QHostAddress(QHostAddress::AnyIPv6))); + QSignalSpy neutralReadSpy(&neutral, SIGNAL(readyRead())); + QSignalSpy spy(s, SIGNAL(readyRead())); - neutralReadSpy.clear(); QVERIFY(s->writeDatagram(testData, s->localAddress(), neutral.localPort())); QTRY_VERIFY(neutralReadSpy.count() > 0); //note may need to accept a firewall prompt From 1c55948ee84f7e8ce4ec6532d7e34f4a1f3c3dea Mon Sep 17 00:00:00 2001 From: Edward Welbourne <edward.welbourne@qt.io> Date: Wed, 20 Feb 2019 16:01:00 +0100 Subject: [PATCH 1227/1650] DBus: verify up to date with dbus-1.12.12 The attirubtion previously only sayd 1.12, so verified up to date at 1.12.12; and tweaked the header slightly to make it easier to verify (content is now in the same order as in the dbus sources). Updated the list of years in which Red Hat claims copyright on various parts. Fixes: QTBUG-72622 Change-Id: Idcec9edbf42860bca61d838e75889a55eb0859d5 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> --- src/dbus/dbus_minimal_p.h | 32 ++++++++++++++++---------------- src/dbus/qt_attribution.json | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/dbus/dbus_minimal_p.h b/src/dbus/dbus_minimal_p.h index 869c02b59d..243c8ceaba 100644 --- a/src/dbus/dbus_minimal_p.h +++ b/src/dbus/dbus_minimal_p.h @@ -53,7 +53,7 @@ extern "C" { -// Equivalent to dbus-arch-deps.h +// Equivalent to dbus-arch-deps.h (generated from dbus-arch-deps.h.in) typedef qint64 dbus_int64_t; typedef quint64 dbus_uint64_t; typedef qint32 dbus_int32_t; @@ -78,7 +78,7 @@ struct DBusWatch; // which carry the following copyright: /* * Copyright (C) 2002, 2003 CodeFactory AB - * Copyright (C) 2004, 2005 Red Hat, Inc. + * Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc. * * Licensed under the Academic Free License version 2.1 * @@ -103,6 +103,20 @@ typedef dbus_uint32_t dbus_unichar_t; typedef dbus_uint32_t dbus_bool_t; /* dbus-shared.h */ +typedef enum +{ + DBUS_BUS_SESSION, /**< The login session bus */ + DBUS_BUS_SYSTEM, /**< The systemwide bus */ + DBUS_BUS_STARTER /**< The bus that started us, if any */ +} DBusBusType; + +typedef enum +{ + DBUS_HANDLER_RESULT_HANDLED, /**< Message has had its effect - no need to run more handlers. */ + DBUS_HANDLER_RESULT_NOT_YET_HANDLED, /**< Message has not had any effect - see if other handlers want it. */ + DBUS_HANDLER_RESULT_NEED_MEMORY /**< Need more memory in order to return #DBUS_HANDLER_RESULT_HANDLED or #DBUS_HANDLER_RESULT_NOT_YET_HANDLED. Please try again later with more memory. */ +} DBusHandlerResult; + #define DBUS_SERVICE_DBUS "org.freedesktop.DBus" #define DBUS_PATH_DBUS "/org/freedesktop/DBus" #define DBUS_PATH_LOCAL "/org/freedesktop/DBus/Local" @@ -124,20 +138,6 @@ typedef dbus_uint32_t dbus_bool_t; #define DBUS_RELEASE_NAME_REPLY_NON_EXISTENT 2 /**< The given name does not exist on the bus */ #define DBUS_RELEASE_NAME_REPLY_NOT_OWNER 3 /**< Service is not an owner of the given name */ -typedef enum -{ - DBUS_BUS_SESSION, /**< The login session bus */ - DBUS_BUS_SYSTEM, /**< The systemwide bus */ - DBUS_BUS_STARTER /**< The bus that started us, if any */ -} DBusBusType; - -typedef enum -{ - DBUS_HANDLER_RESULT_HANDLED, /**< Message has had its effect - no need to run more handlers. */ - DBUS_HANDLER_RESULT_NOT_YET_HANDLED, /**< Message has not had any effect - see if other handlers want it. */ - DBUS_HANDLER_RESULT_NEED_MEMORY /**< Need more memory in order to return #DBUS_HANDLER_RESULT_HANDLED or #DBUS_HANDLER_RESULT_NOT_YET_HANDLED. Please try again later with more memory. */ -} DBusHandlerResult; - /* dbus-memory.h */ typedef void (* DBusFreeFunction) (void *memory); diff --git a/src/dbus/qt_attribution.json b/src/dbus/qt_attribution.json index 69d946ba5c..33eaee1ed1 100644 --- a/src/dbus/qt_attribution.json +++ b/src/dbus/qt_attribution.json @@ -7,7 +7,7 @@ "Description": "D-Bus is a message bus system, a simple way for applications to talk to one another.", "Homepage": "https://www.freedesktop.org/wiki/Software/dbus/", "Version": "Minimal supported is 1.2, compatible up to ...", - "Version": "1.12", + "Version": "dbus-1.12.12", "LicenseId": "AFL-2.1 OR GPL-2.0-or-later", "License": "Academic Free License v2.1, or GNU General Public License v2.0 or later", "LicenseFile": "LIBDBUS-1-LICENSE.txt", From 01f07fd2d1f4e9c6dfc755ffa1c30bb1281a0ff1 Mon Sep 17 00:00:00 2001 From: Lars Schmertmann <Lars.Schmertmann@governikus.de> Date: Tue, 15 Jan 2019 10:26:37 +0100 Subject: [PATCH 1228/1650] Rename the Indonesian Android translation folder to fix a lint warning Wrong locale name ----------------- From the java.util.Locale documentation: "Note that Java uses several deprecated two-letter codes. The Hebrew ("he") language code is rewritten as "iw", Indonesian ("id") as "in", and Yiddish ("yi") as "ji". This rewriting happens even if you construct your own Locale object, not just for instances returned by the various lookup methods. Because of this, if you add your localized resources in for example values-he they will not be used, since the system will look for values-iw instead. To work around this, place your resources in a values folder using the deprecated language code instead. See also: http://www.apps4android.org/?p=3695 https://issuetracker.google.com/issues/36908826 Change-Id: I726c43f282156b21e8d6b073029f3c3b8fd42a30 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: BogDan Vatra <bogdan@kdab.com> --- src/android/java/res/{values-id => values-in}/strings.xml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/android/java/res/{values-id => values-in}/strings.xml (100%) diff --git a/src/android/java/res/values-id/strings.xml b/src/android/java/res/values-in/strings.xml similarity index 100% rename from src/android/java/res/values-id/strings.xml rename to src/android/java/res/values-in/strings.xml From 46a20b90243149b0ecd1d44cab964e785648d214 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann <joerg.bornemann@qt.io> Date: Wed, 13 Feb 2019 10:09:54 +0100 Subject: [PATCH 1229/1650] QProcess: Fix crash when calling closeWriteChannel on Windows We must deleteLater the pipe writer in closeChannel, because if you call closeWriteChannel() from a slot that is connected to a signal emitted from QWindowsPipeWriter, we'd operate on a deleted object. For consistency, we're calling QWindowsPipeWriter::stop before deleteLater and deduplicate the code. Fixes: QTBUG-73778 Change-Id: I61d3dedf57e9fd02517a108d13ffc85e006330f6 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io> --- src/corelib/io/qprocess_win.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index cb4b2f9f91..3ba86063e3 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -362,16 +362,22 @@ void QProcessPrivate::destroyPipe(Q_PIPE pipe[2]) } } +template <class T> +void deleteWorker(T *&worker) +{ + if (!worker) + return; + worker->stop(); + worker->deleteLater(); + worker = nullptr; +} + void QProcessPrivate::closeChannel(Channel *channel) { - if (channel == &stdinChannel) { - delete stdinChannel.writer; - stdinChannel.writer = 0; - } else if (channel->reader) { - channel->reader->stop(); - channel->reader->deleteLater(); - channel->reader = 0; - } + if (channel == &stdinChannel) + deleteWorker(channel->writer); + else + deleteWorker(channel->reader); destroyPipe(channel->pipe); } From f6cf0442df52e8018f724a9234d2ae0267ecba85 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov <timur.pocheptsov@qt.io> Date: Fri, 1 Feb 2019 14:27:58 +0100 Subject: [PATCH 1230/1650] Convert tst_qhttpnetworkconnection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit and make it work with our new docker-based test server Change-Id: I98b5b5b1e2cdca46b7f15be72aa1483d9455403d Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> --- .../qhttpnetworkconnection.pro | 4 + .../tst_qhttpnetworkconnection.cpp | 76 +- tests/testserver/apache2/apache2.sh | 3 + .../testdata/www/htdocs/rfcs/.gitattributes | 1 + .../testdata/www/htdocs/rfcs/rfc2616.html | 8380 +++++++++++++++++ 5 files changed, 8428 insertions(+), 36 deletions(-) create mode 100644 tests/testserver/apache2/testdata/www/htdocs/rfcs/.gitattributes create mode 100644 tests/testserver/apache2/testdata/www/htdocs/rfcs/rfc2616.html diff --git a/tests/auto/network/access/qhttpnetworkconnection/qhttpnetworkconnection.pro b/tests/auto/network/access/qhttpnetworkconnection/qhttpnetworkconnection.pro index d32b651b86..69a4a50144 100644 --- a/tests/auto/network/access/qhttpnetworkconnection/qhttpnetworkconnection.pro +++ b/tests/auto/network/access/qhttpnetworkconnection/qhttpnetworkconnection.pro @@ -4,3 +4,7 @@ SOURCES += tst_qhttpnetworkconnection.cpp requires(qtConfig(private_tests)) QT = core-private network-private testlib + +QT_TEST_SERVER_LIST = apache2 +include($$dirname(_QMAKE_CONF_)/tests/auto/testserver.pri) + diff --git a/tests/auto/network/access/qhttpnetworkconnection/tst_qhttpnetworkconnection.cpp b/tests/auto/network/access/qhttpnetworkconnection/tst_qhttpnetworkconnection.cpp index 84766f5484..0a9320118d 100644 --- a/tests/auto/network/access/qhttpnetworkconnection/tst_qhttpnetworkconnection.cpp +++ b/tests/auto/network/access/qhttpnetworkconnection/tst_qhttpnetworkconnection.cpp @@ -50,6 +50,7 @@ private: bool finishedCalled; bool finishedWithErrorCalled; QNetworkReply::NetworkError netErrorCode; + QString (*httpServerName)() = QtNetworkSettings::httpServerName; private Q_SLOTS: void initTestCase(); @@ -101,7 +102,11 @@ private Q_SLOTS: void tst_QHttpNetworkConnection::initTestCase() { +#if defined(QT_TEST_SERVER) + QVERIFY(QtNetworkSettings::verifyConnection(httpServerName(), 80)); +#else QVERIFY(QtNetworkSettings::verifyTestNetworkSettings()); +#endif } void tst_QHttpNetworkConnection::options_data() @@ -126,10 +131,9 @@ void tst_QHttpNetworkConnection::head_data() QTest::addColumn<QString>("statusString"); QTest::addColumn<int>("contentLength"); - QTest::newRow("success-internal") << "http://" << QtNetworkSettings::serverName() << "/qtest/rfc3252.txt" << ushort(80) << false << 200 << "OK" << 25962; - - QTest::newRow("failure-path") << "http://" << QtNetworkSettings::serverName() << "/t" << ushort(80) << false << 404 << "Not Found" << -1; - QTest::newRow("failure-protocol") << "" << QtNetworkSettings::serverName() << "/qtest/rfc3252.txt" << ushort(80) << false << 400 << "Bad Request" << -1; + QTest::newRow("success-internal") << "http://" << httpServerName() << "/qtest/rfc3252.txt" << ushort(80) << false << 200 << "OK" << 25962; + QTest::newRow("failure-path") << "http://" << httpServerName() << "/t" << ushort(80) << false << 404 << "Not Found" << -1; + QTest::newRow("failure-protocol") << "" << httpServerName() << "/qtest/rfc3252.txt" << ushort(80) << false << 400 << "Bad Request" << -1; } void tst_QHttpNetworkConnection::head() @@ -175,10 +179,10 @@ void tst_QHttpNetworkConnection::get_data() QTest::addColumn<int>("contentLength"); QTest::addColumn<int>("downloadSize"); - QTest::newRow("success-internal") << "http://" << QtNetworkSettings::serverName() << "/qtest/rfc3252.txt" << ushort(80) << false << 200 << "OK" << 25962 << 25962; + QTest::newRow("success-internal") << "http://" << httpServerName() << "/qtest/rfc3252.txt" << ushort(80) << false << 200 << "OK" << 25962 << 25962; - QTest::newRow("failure-path") << "http://" << QtNetworkSettings::serverName() << "/t" << ushort(80) << false << 404 << "Not Found" << -1 << -1; - QTest::newRow("failure-protocol") << "" << QtNetworkSettings::serverName() << "/qtest/rfc3252.txt" << ushort(80) << false << 400 << "Bad Request" << -1 << -1; + QTest::newRow("failure-path") << "http://" << httpServerName() << "/t" << ushort(80) << false << 404 << "Not Found" << -1 << -1; + QTest::newRow("failure-protocol") << "" << httpServerName() << "/qtest/rfc3252.txt" << ushort(80) << false << 400 << "Bad Request" << -1 << -1; } void tst_QHttpNetworkConnection::get() @@ -244,8 +248,8 @@ void tst_QHttpNetworkConnection::put_data() QTest::addColumn<QString>("data"); QTest::addColumn<bool>("succeed"); - QTest::newRow("success-internal") << "http://" << QtNetworkSettings::serverName() << "/dav/file1.txt" << ushort(80) << false << "Hello World\nEnd of file\n"<<true; - QTest::newRow("fail-internal") << "http://" << QtNetworkSettings::serverName() << "/dav2/file1.txt" << ushort(80) << false << "Hello World\nEnd of file\n"<<false; + QTest::newRow("success-internal") << "http://" << httpServerName() << "/dav/file1.txt" << ushort(80) << false << "Hello World\nEnd of file\n"<<true; + QTest::newRow("fail-internal") << "http://" << httpServerName() << "/dav2/file1.txt" << ushort(80) << false << "Hello World\nEnd of file\n"<<false; QTest::newRow("fail-host") << "http://" << "invalid.test.qt-project.org" << "/dav2/file1.txt" << ushort(80) << false << "Hello World\nEnd of file\n"<<false; } @@ -324,8 +328,8 @@ void tst_QHttpNetworkConnection::post_data() QTest::addColumn<int>("contentLength"); QTest::addColumn<int>("downloadSize"); - QTest::newRow("success-internal") << "http://" << QtNetworkSettings::serverName() << "/qtest/cgi-bin/echo.cgi" << ushort(80) << false << "7 bytes" << 200 << "OK" << 7 << 7; - QTest::newRow("failure-internal") << "http://" << QtNetworkSettings::serverName() << "/t" << ushort(80) << false << "Hello World" << 404 << "Not Found" << -1 << -1; + QTest::newRow("success-internal") << "http://" << httpServerName() << "/qtest/cgi-bin/echo.cgi" << ushort(80) << false << "7 bytes" << 200 << "OK" << 7 << 7; + QTest::newRow("failure-internal") << "http://" << httpServerName() << "/t" << ushort(80) << false << "Hello World" << 404 << "Not Found" << -1 << -1; } void tst_QHttpNetworkConnection::post() @@ -449,11 +453,11 @@ void tst_QHttpNetworkConnection::get401_data() QTest::addColumn<QString>("password"); QTest::addColumn<int>("statusCode"); - QTest::newRow("no-credentials") << "http://" << QtNetworkSettings::serverName() << "/qtest/rfcs-auth/index.html" << ushort(80) << false << false << "" << ""<<401; - QTest::newRow("invalid-credentials") << "http://" << QtNetworkSettings::serverName() << "/qtest/rfcs-auth/index.html" << ushort(80) << false << true << "test" << "test"<<401; - QTest::newRow("valid-credentials") << "http://" << QtNetworkSettings::serverName() << "/qtest/rfcs-auth/index.html" << ushort(80) << false << true << "httptest" << "httptest"<<200; - QTest::newRow("digest-authentication-invalid") << "http://" << QtNetworkSettings::serverName() << "/qtest/auth-digest/index.html" << ushort(80) << false << true << "wrong" << "wrong"<<401; - QTest::newRow("digest-authentication-valid") << "http://" << QtNetworkSettings::serverName() << "/qtest/auth-digest/index.html" << ushort(80) << false << true << "httptest" << "httptest"<<200; + QTest::newRow("no-credentials") << "http://" << httpServerName() << "/qtest/rfcs-auth/index.html" << ushort(80) << false << false << "" << ""<<401; + QTest::newRow("invalid-credentials") << "http://" << httpServerName() << "/qtest/rfcs-auth/index.html" << ushort(80) << false << true << "test" << "test"<<401; + QTest::newRow("valid-credentials") << "http://" << httpServerName() << "/qtest/rfcs-auth/index.html" << ushort(80) << false << true << "httptest" << "httptest"<<200; + QTest::newRow("digest-authentication-invalid") << "http://" << httpServerName() << "/qtest/auth-digest/index.html" << ushort(80) << false << true << "wrong" << "wrong"<<401; + QTest::newRow("digest-authentication-valid") << "http://" << httpServerName() << "/qtest/auth-digest/index.html" << ushort(80) << false << true << "httptest" << "httptest"<<200; } void tst_QHttpNetworkConnection::get401() @@ -508,9 +512,9 @@ void tst_QHttpNetworkConnection::compression_data() QTest::addColumn<bool>("autoCompress"); QTest::addColumn<QString>("contentCoding"); - QTest::newRow("success-autogzip-temp") << "http://" << QtNetworkSettings::serverName() << "/qtest/rfcs/rfc2616.html" << ushort(80) << false << 200 << "OK" << -1 << 418321 << true << ""; - QTest::newRow("success-nogzip-temp") << "http://" << QtNetworkSettings::serverName() << "/qtest/rfcs/rfc2616.html" << ushort(80) << false << 200 << "OK" << 418321 << 418321 << false << "identity"; - QTest::newRow("success-manualgzip-temp") << "http://" << QtNetworkSettings::serverName() << "/qtest/deflate/rfc2616.html" << ushort(80) << false << 200 << "OK" << 119124 << 119124 << false << "gzip"; + QTest::newRow("success-autogzip-temp") << "http://" << httpServerName() << "/qtest/rfcs/rfc2616.html" << ushort(80) << false << 200 << "OK" << -1 << 418321 << true << ""; + QTest::newRow("success-nogzip-temp") << "http://" << httpServerName() << "/qtest/rfcs/rfc2616.html" << ushort(80) << false << 200 << "OK" << 418321 << 418321 << false << "identity"; + QTest::newRow("success-manualgzip-temp") << "http://" << httpServerName() << "/qtest/deflate/rfc2616.html" << ushort(80) << false << 200 << "OK" << 119124 << 119124 << false << "gzip"; } @@ -586,9 +590,9 @@ void tst_QHttpNetworkConnection::ignoresslerror_data() // fluke's certificate is signed by a non-standard authority. // Since we don't introduce that CA into the SSL verification chain, // connecting should fail. - QTest::newRow("success-init") << "https://" << QtNetworkSettings::serverName() << "/" << ushort(443) << true << true << false << 200; - QTest::newRow("success-fromSignal") << "https://" << QtNetworkSettings::serverName() << "/" << ushort(443) << true << false << true << 200; - QTest::newRow("failure") << "https://" << QtNetworkSettings::serverName() << "/" << ushort(443) << true << false << false << 100; + QTest::newRow("success-init") << "https://" << httpServerName() << "/" << ushort(443) << true << true << false << 200; + QTest::newRow("success-fromSignal") << "https://" << httpServerName() << "/" << ushort(443) << true << false << true << 200; + QTest::newRow("failure") << "https://" << httpServerName() << "/" << ushort(443) << true << false << false << 100; } void tst_QHttpNetworkConnection::ignoresslerror() @@ -635,7 +639,7 @@ void tst_QHttpNetworkConnection::nossl_data() QTest::addColumn<bool>("encrypt"); QTest::addColumn<QNetworkReply::NetworkError>("networkError"); - QTest::newRow("protocol-error") << "https://" << QtNetworkSettings::serverName() << "/" << ushort(443) << true <<QNetworkReply::ProtocolUnknownError; + QTest::newRow("protocol-error") << "https://" << httpServerName() << "/" << ushort(443) << true <<QNetworkReply::ProtocolUnknownError; } void tst_QHttpNetworkConnection::nossl() @@ -696,7 +700,7 @@ void tst_QHttpNetworkConnection::getMultiple() QFETCH(bool, pipeliningAllowed); QFETCH(int, requestCount); - QHttpNetworkConnection connection(connectionCount, QtNetworkSettings::serverName()); + QHttpNetworkConnection connection(connectionCount, httpServerName()); QList<QHttpNetworkRequest*> requests; QList<QHttpNetworkReply*> replies; @@ -705,7 +709,7 @@ void tst_QHttpNetworkConnection::getMultiple() // depending on what you use the results will vary. // for the "real" results, use a URL that has "internet latency" for you. Then (6 connections, pipelining) will win. // for LAN latency, you will possibly get that (1 connection, no pipelining) is the fastest - QHttpNetworkRequest *request = new QHttpNetworkRequest("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"); + QHttpNetworkRequest *request = new QHttpNetworkRequest("http://" + httpServerName() + "/qtest/rfc3252.txt"); if (pipeliningAllowed) request->setPipeliningAllowed(true); requests.append(request); @@ -723,7 +727,7 @@ void tst_QHttpNetworkConnection::getMultipleWithPipeliningAndMultiplePriorities( quint16 requestCount = 100; // use 2 connections. - QHttpNetworkConnection connection(2, QtNetworkSettings::serverName()); + QHttpNetworkConnection connection(2, httpServerName()); QList<QHttpNetworkRequest*> requests; QList<QHttpNetworkReply*> replies; @@ -731,9 +735,9 @@ void tst_QHttpNetworkConnection::getMultipleWithPipeliningAndMultiplePriorities( for (int i = 0; i < requestCount; i++) { QHttpNetworkRequest *request = 0; if (i % 3) - request = new QHttpNetworkRequest("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt", QHttpNetworkRequest::Get); + request = new QHttpNetworkRequest("http://" + httpServerName() + "/qtest/rfc3252.txt", QHttpNetworkRequest::Get); else - request = new QHttpNetworkRequest("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt", QHttpNetworkRequest::Head); + request = new QHttpNetworkRequest("http://" + httpServerName() + "/qtest/rfc3252.txt", QHttpNetworkRequest::Head); if (i % 2 || i % 3) request->setPipeliningAllowed(true); @@ -800,9 +804,9 @@ void tst_QHttpNetworkConnection::getMultipleWithPriorities() { quint16 requestCount = 100; // use 2 connections. - QHttpNetworkConnection connection(2, QtNetworkSettings::serverName()); + QHttpNetworkConnection connection(2, httpServerName()); GetMultipleWithPrioritiesReceiver receiver(requestCount); - QUrl url("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"); + QUrl url("http://" + httpServerName() + "/qtest/rfc3252.txt"); QList<QHttpNetworkRequest*> requests; QList<QHttpNetworkReply*> replies; @@ -854,10 +858,10 @@ void tst_QHttpNetworkConnection::getEmptyWithPipelining() { quint16 requestCount = 50; // use 2 connections. - QHttpNetworkConnection connection(2, QtNetworkSettings::serverName()); + QHttpNetworkConnection connection(2, httpServerName()); GetEmptyWithPipeliningReceiver receiver(requestCount); - QUrl url("http://" + QtNetworkSettings::serverName() + "/cgi-bin/echo.cgi"); // a get on this = getting an empty file + QUrl url("http://" + httpServerName() + "/cgi-bin/echo.cgi"); // a get on this = getting an empty file QList<QHttpNetworkRequest*> requests; QList<QHttpNetworkReply*> replies; @@ -901,8 +905,8 @@ void tst_QHttpNetworkConnection::getAndEverythingShouldBePipelined() { quint16 requestCount = 100; // use 1 connection. - QHttpNetworkConnection connection(1, QtNetworkSettings::serverName()); - QUrl url("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt"); + QHttpNetworkConnection connection(1, httpServerName()); + QUrl url("http://" + httpServerName() + "/qtest/rfc3252.txt"); QList<QHttpNetworkRequest*> requests; QList<QHttpNetworkReply*> replies; @@ -937,8 +941,8 @@ void tst_QHttpNetworkConnection::getAndThenDeleteObject_data() void tst_QHttpNetworkConnection::getAndThenDeleteObject() { // yes, this will leak if the testcase fails. I don't care. It must not fail then :P - QHttpNetworkConnection *connection = new QHttpNetworkConnection(QtNetworkSettings::serverName()); - QHttpNetworkRequest request("http://" + QtNetworkSettings::serverName() + "/qtest/bigfile"); + QHttpNetworkConnection *connection = new QHttpNetworkConnection(httpServerName()); + QHttpNetworkRequest request("http://" + httpServerName() + "/qtest/bigfile"); QHttpNetworkReply *reply = connection->sendRequest(request); reply->setDownstreamLimited(true); diff --git a/tests/testserver/apache2/apache2.sh b/tests/testserver/apache2/apache2.sh index 4b0c74e2c4..d5075c7096 100755 --- a/tests/testserver/apache2/apache2.sh +++ b/tests/testserver/apache2/apache2.sh @@ -73,5 +73,8 @@ touch -d "2007-05-22 12:04:57 GMT" /home/$USER/www/htdocs/fluke.gif # Create 10MB file for use by tst_Q*::downloadBigFile and interruption tests: su $USER -c "/bin/dd if=/dev/zero of=~/www/htdocs/mediumfile bs=1 count=0 seek=10000000" +# Emulate test server's hierarchy: +su $USER -c "ln -s ~/www/htdocs/rfcs/rfc2616.html ~/www/htdocs/deflate/" + # enable service with installed configurations service apache2 restart diff --git a/tests/testserver/apache2/testdata/www/htdocs/rfcs/.gitattributes b/tests/testserver/apache2/testdata/www/htdocs/rfcs/.gitattributes new file mode 100644 index 0000000000..1d09ee726e --- /dev/null +++ b/tests/testserver/apache2/testdata/www/htdocs/rfcs/.gitattributes @@ -0,0 +1 @@ +rfc2616.html binary diff --git a/tests/testserver/apache2/testdata/www/htdocs/rfcs/rfc2616.html b/tests/testserver/apache2/testdata/www/htdocs/rfcs/rfc2616.html new file mode 100644 index 0000000000..0e3282fb8d --- /dev/null +++ b/tests/testserver/apache2/testdata/www/htdocs/rfcs/rfc2616.html @@ -0,0 +1,8380 @@ +<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> +<html><head><title>RFC 2616 (rfc2616) - Hypertext Transfer Protocol -- HTTP/1.1 + + + + + + +

    +

    RFC 2616 (RFC2616)

    +

    Internet RFC/STD/FYI/BCP Archives

    + + +

    Comment on RFC 2616 +

    +

    RFC 2616 - Hypertext Transfer Protocol -- HTTP/1.1

    +
    +
    +Network Working Group                                      R. Fielding
    +Request for Comments: 2616                                   UC Irvine
    +Obsoletes: 2068                                              J. Gettys
    +Category: Standards Track                                   Compaq/W3C
    +                                                              J. Mogul
    +                                                                Compaq
    +                                                            H. Frystyk
    +                                                               W3C/MIT
    +                                                           L. Masinter
    +                                                                 Xerox
    +                                                              P. Leach
    +                                                             Microsoft
    +                                                        T. Berners-Lee
    +                                                               W3C/MIT
    +                                                             June 1999
    +
    +                Hypertext Transfer Protocol -- HTTP/1.1
    +
    +Status of this Memo
    +
    +   This document specifies an Internet standards track protocol for the
    +   Internet community, and requests discussion and suggestions for
    +   improvements.  Please refer to the current edition of the "Internet
    +   Official Protocol Standards" (STD 1) for the standardization state
    +   and status of this protocol.  Distribution of this memo is unlimited.
    +
    +Copyright Notice
    +
    +   Copyright (C) The Internet Society (1999).  All Rights Reserved.
    +
    +Abstract
    +
    +   The Hypertext Transfer Protocol (HTTP) is an application-level
    +   protocol for distributed, collaborative, hypermedia information
    +   systems. It is a generic, stateless, protocol which can be used for
    +   many tasks beyond its use for hypertext, such as name servers and
    +   distributed object management systems, through extension of its
    +   request methods, error codes and headers [47]. A feature of HTTP is
    +   the typing and negotiation of data representation, allowing systems
    +   to be built independently of the data being transferred.
    +
    +   HTTP has been in use by the World-Wide Web global information
    +   initiative since 1990. This specification defines the protocol
    +   referred to as "HTTP/1.1", and is an update to RFC 2068 [33].
    +
    +Table of Contents
    +
    +   1   Introduction ...................................................7
    +   1.1    Purpose......................................................7
    +   1.2   Requirements .................................................8
    +   1.3   Terminology ..................................................8
    +   1.4   Overall Operation ...........................................12
    +   2   Notational Conventions and Generic Grammar ....................14
    +   2.1   Augmented BNF ...............................................14
    +   2.2   Basic Rules .................................................15
    +   3   Protocol Parameters ...........................................17
    +   3.1   HTTP Version ................................................17
    +   3.2   Uniform Resource Identifiers ................................18
    +   3.2.1    General Syntax ...........................................19
    +   3.2.2    http URL .................................................19
    +   3.2.3    URI Comparison ...........................................20
    +   3.3   Date/Time Formats ...........................................20
    +   3.3.1    Full Date ................................................20
    +   3.3.2    Delta Seconds ............................................21
    +   3.4   Character Sets ..............................................21
    +   3.4.1    Missing Charset ..........................................22
    +   3.5   Content Codings .............................................23
    +   3.6   Transfer Codings ............................................24
    +   3.6.1    Chunked Transfer Coding ..................................25
    +   3.7   Media Types .................................................26
    +   3.7.1    Canonicalization and Text Defaults .......................27
    +   3.7.2    Multipart Types ..........................................27
    +   3.8   Product Tokens ..............................................28
    +   3.9   Quality Values ..............................................29
    +   3.10  Language Tags ...............................................29
    +   3.11  Entity Tags .................................................30
    +   3.12  Range Units .................................................30
    +   4   HTTP Message ..................................................31
    +   4.1   Message Types ...............................................31
    +   4.2   Message Headers .............................................31
    +   4.3   Message Body ................................................32
    +   4.4   Message Length ..............................................33
    +   4.5   General Header Fields .......................................34
    +   5   Request .......................................................35
    +   5.1   Request-Line ................................................35
    +   5.1.1    Method ...................................................36
    +   5.1.2    Request-URI ..............................................36
    +   5.2   The Resource Identified by a Request ........................38
    +   5.3   Request Header Fields .......................................38
    +   6   Response ......................................................39
    +   6.1   Status-Line .................................................39
    +   6.1.1    Status Code and Reason Phrase ............................39
    +   6.2   Response Header Fields ......................................41
    +
    +   7   Entity ........................................................42
    +   7.1   Entity Header Fields ........................................42
    +   7.2   Entity Body .................................................43
    +   7.2.1    Type .....................................................43
    +   7.2.2    Entity Length ............................................43
    +   8   Connections ...................................................44
    +   8.1   Persistent Connections ......................................44
    +   8.1.1    Purpose ..................................................44
    +   8.1.2    Overall Operation ........................................45
    +   8.1.3    Proxy Servers ............................................46
    +   8.1.4    Practical Considerations .................................46
    +   8.2   Message Transmission Requirements ...........................47
    +   8.2.1    Persistent Connections and Flow Control ..................47
    +   8.2.2    Monitoring Connections for Error Status Messages .........48
    +   8.2.3    Use of the 100 (Continue) Status .........................48
    +   8.2.4    Client Behavior if Server Prematurely Closes Connection ..50
    +   9   Method Definitions ............................................51
    +   9.1   Safe and Idempotent Methods .................................51
    +   9.1.1    Safe Methods .............................................51
    +   9.1.2    Idempotent Methods .......................................51
    +   9.2   OPTIONS .....................................................52
    +   9.3   GET .........................................................53
    +   9.4   HEAD ........................................................54
    +   9.5   POST ........................................................54
    +   9.6   PUT .........................................................55
    +   9.7   DELETE ......................................................56
    +   9.8   TRACE .......................................................56
    +   9.9   CONNECT .....................................................57
    +   10   Status Code Definitions ......................................57
    +   10.1  Informational 1xx ...........................................57
    +   10.1.1   100 Continue .............................................58
    +   10.1.2   101 Switching Protocols ..................................58
    +   10.2  Successful 2xx ..............................................58
    +   10.2.1   200 OK ...................................................58
    +   10.2.2   201 Created ..............................................59
    +   10.2.3   202 Accepted .............................................59
    +   10.2.4   203 Non-Authoritative Information ........................59
    +   10.2.5   204 No Content ...........................................60
    +   10.2.6   205 Reset Content ........................................60
    +   10.2.7   206 Partial Content ......................................60
    +   10.3  Redirection 3xx .............................................61
    +   10.3.1   300 Multiple Choices .....................................61
    +   10.3.2   301 Moved Permanently ....................................62
    +   10.3.3   302 Found ................................................62
    +   10.3.4   303 See Other ............................................63
    +   10.3.5   304 Not Modified .........................................63
    +   10.3.6   305 Use Proxy ............................................64
    +   10.3.7   306 (Unused) .............................................64
    +
    +   10.3.8   307 Temporary Redirect ...................................65
    +   10.4  Client Error 4xx ............................................65
    +   10.4.1    400 Bad Request .........................................65
    +   10.4.2    401 Unauthorized ........................................66
    +   10.4.3    402 Payment Required ....................................66
    +   10.4.4    403 Forbidden ...........................................66
    +   10.4.5    404 Not Found ...........................................66
    +   10.4.6    405 Method Not Allowed ..................................66
    +   10.4.7    406 Not Acceptable ......................................67
    +   10.4.8    407 Proxy Authentication Required .......................67
    +   10.4.9    408 Request Timeout .....................................67
    +   10.4.10   409 Conflict ............................................67
    +   10.4.11   410 Gone ................................................68
    +   10.4.12   411 Length Required .....................................68
    +   10.4.13   412 Precondition Failed .................................68
    +   10.4.14   413 Request Entity Too Large ............................69
    +   10.4.15   414 Request-URI Too Long ................................69
    +   10.4.16   415 Unsupported Media Type ..............................69
    +   10.4.17   416 Requested Range Not Satisfiable .....................69
    +   10.4.18   417 Expectation Failed ..................................70
    +   10.5  Server Error 5xx ............................................70
    +   10.5.1   500 Internal Server Error ................................70
    +   10.5.2   501 Not Implemented ......................................70
    +   10.5.3   502 Bad Gateway ..........................................70
    +   10.5.4   503 Service Unavailable ..................................70
    +   10.5.5   504 Gateway Timeout ......................................71
    +   10.5.6   505 HTTP Version Not Supported ...........................71
    +   11   Access Authentication ........................................71
    +   12   Content Negotiation ..........................................71
    +   12.1  Server-driven Negotiation ...................................72
    +   12.2  Agent-driven Negotiation ....................................73
    +   12.3  Transparent Negotiation .....................................74
    +   13   Caching in HTTP ..............................................74
    +   13.1.1   Cache Correctness ........................................75
    +   13.1.2   Warnings .................................................76
    +   13.1.3   Cache-control Mechanisms .................................77
    +   13.1.4   Explicit User Agent Warnings .............................78
    +   13.1.5   Exceptions to the Rules and Warnings .....................78
    +   13.1.6   Client-controlled Behavior ...............................79
    +   13.2  Expiration Model ............................................79
    +   13.2.1   Server-Specified Expiration ..............................79
    +   13.2.2   Heuristic Expiration .....................................80
    +   13.2.3   Age Calculations .........................................80
    +   13.2.4   Expiration Calculations ..................................83
    +   13.2.5   Disambiguating Expiration Values .........................84
    +   13.2.6   Disambiguating Multiple Responses ........................84
    +   13.3  Validation Model ............................................85
    +   13.3.1   Last-Modified Dates ......................................86
    +
    +   13.3.2   Entity Tag Cache Validators ..............................86
    +   13.3.3   Weak and Strong Validators ...............................86
    +   13.3.4   Rules for When to Use Entity Tags and Last-Modified Dates.89
    +   13.3.5   Non-validating Conditionals ..............................90
    +   13.4  Response Cacheability .......................................91
    +   13.5  Constructing Responses From Caches ..........................92
    +   13.5.1   End-to-end and Hop-by-hop Headers ........................92
    +   13.5.2   Non-modifiable Headers ...................................92
    +   13.5.3   Combining Headers ........................................94
    +   13.5.4   Combining Byte Ranges ....................................95
    +   13.6  Caching Negotiated Responses ................................95
    +   13.7  Shared and Non-Shared Caches ................................96
    +   13.8  Errors or Incomplete Response Cache Behavior ................97
    +   13.9  Side Effects of GET and HEAD ................................97
    +   13.10   Invalidation After Updates or Deletions ...................97
    +   13.11   Write-Through Mandatory ...................................98
    +   13.12   Cache Replacement .........................................99
    +   13.13   History Lists .............................................99
    +   14   Header Field Definitions ....................................100
    +   14.1  Accept .....................................................100
    +   14.2  Accept-Charset .............................................102
    +   14.3  Accept-Encoding ............................................102
    +   14.4  Accept-Language ............................................104
    +   14.5  Accept-Ranges ..............................................105
    +   14.6  Age ........................................................106
    +   14.7  Allow ......................................................106
    +   14.8  Authorization ..............................................107
    +   14.9  Cache-Control ..............................................108
    +   14.9.1   What is Cacheable .......................................109
    +   14.9.2   What May be Stored by Caches ............................110
    +   14.9.3   Modifications of the Basic Expiration Mechanism .........111
    +   14.9.4   Cache Revalidation and Reload Controls ..................113
    +   14.9.5   No-Transform Directive ..................................115
    +   14.9.6   Cache Control Extensions ................................116
    +   14.10   Connection ...............................................117
    +   14.11   Content-Encoding .........................................118
    +   14.12   Content-Language .........................................118
    +   14.13   Content-Length ...........................................119
    +   14.14   Content-Location .........................................120
    +   14.15   Content-MD5 ..............................................121
    +   14.16   Content-Range ............................................122
    +   14.17   Content-Type .............................................124
    +   14.18   Date .....................................................124
    +   14.18.1   Clockless Origin Server Operation ......................125
    +   14.19   ETag .....................................................126
    +   14.20   Expect ...................................................126
    +   14.21   Expires ..................................................127
    +   14.22   From .....................................................128
    +
    +   14.23   Host .....................................................128
    +   14.24   If-Match .................................................129
    +   14.25   If-Modified-Since ........................................130
    +   14.26   If-None-Match ............................................132
    +   14.27   If-Range .................................................133
    +   14.28   If-Unmodified-Since ......................................134
    +   14.29   Last-Modified ............................................134
    +   14.30   Location .................................................135
    +   14.31   Max-Forwards .............................................136
    +   14.32   Pragma ...................................................136
    +   14.33   Proxy-Authenticate .......................................137
    +   14.34   Proxy-Authorization ......................................137
    +   14.35   Range ....................................................138
    +   14.35.1    Byte Ranges ...........................................138
    +   14.35.2    Range Retrieval Requests ..............................139
    +   14.36   Referer ..................................................140
    +   14.37   Retry-After ..............................................141
    +   14.38   Server ...................................................141
    +   14.39   TE .......................................................142
    +   14.40   Trailer ..................................................143
    +   14.41  Transfer-Encoding..........................................143
    +   14.42   Upgrade ..................................................144
    +   14.43   User-Agent ...............................................145
    +   14.44   Vary .....................................................145
    +   14.45   Via ......................................................146
    +   14.46   Warning ..................................................148
    +   14.47   WWW-Authenticate .........................................150
    +   15 Security Considerations .......................................150
    +   15.1      Personal Information....................................151
    +   15.1.1   Abuse of Server Log Information .........................151
    +   15.1.2   Transfer of Sensitive Information .......................151
    +   15.1.3   Encoding Sensitive Information in URI's .................152
    +   15.1.4   Privacy Issues Connected to Accept Headers ..............152
    +   15.2  Attacks Based On File and Path Names .......................153
    +   15.3  DNS Spoofing ...............................................154
    +   15.4  Location Headers and Spoofing ..............................154
    +   15.5  Content-Disposition Issues .................................154
    +   15.6  Authentication Credentials and Idle Clients ................155
    +   15.7  Proxies and Caching ........................................155
    +   15.7.1    Denial of Service Attacks on Proxies....................156
    +   16   Acknowledgments .............................................156
    +   17   References ..................................................158
    +   18   Authors' Addresses ..........................................162
    +   19   Appendices ..................................................164
    +   19.1  Internet Media Type message/http and application/http ......164
    +   19.2  Internet Media Type multipart/byteranges ...................165
    +   19.3  Tolerant Applications ......................................166
    +   19.4  Differences Between HTTP Entities and RFC 2045 Entities ....167
    +
    +   19.4.1   MIME-Version ............................................167
    +   19.4.2   Conversion to Canonical Form ............................167
    +   19.4.3   Conversion of Date Formats ..............................168
    +   19.4.4   Introduction of Content-Encoding ........................168
    +   19.4.5   No Content-Transfer-Encoding ............................168
    +   19.4.6   Introduction of Transfer-Encoding .......................169
    +   19.4.7   MHTML and Line Length Limitations .......................169
    +   19.5  Additional Features ........................................169
    +   19.5.1   Content-Disposition .....................................170
    +   19.6  Compatibility with Previous Versions .......................170
    +   19.6.1   Changes from HTTP/1.0 ...................................171
    +   19.6.2   Compatibility with HTTP/1.0 Persistent Connections ......172
    +   19.6.3   Changes from RFC 2068 ...................................172
    +   20   Index .......................................................175
    +   21   Full Copyright Statement ....................................176
    +
    +1 Introduction
    +
    +1.1 Purpose
    +
    +   The Hypertext Transfer Protocol (HTTP) is an application-level
    +   protocol for distributed, collaborative, hypermedia information
    +   systems. HTTP has been in use by the World-Wide Web global
    +   information initiative since 1990. The first version of HTTP,
    +   referred to as HTTP/0.9, was a simple protocol for raw data transfer
    +   across the Internet. HTTP/1.0, as defined by RFC 1945 [6], improved
    +   the protocol by allowing messages to be in the format of MIME-like
    +   messages, containing metainformation about the data transferred and
    +   modifiers on the request/response semantics. However, HTTP/1.0 does
    +   not sufficiently take into consideration the effects of hierarchical
    +   proxies, caching, the need for persistent connections, or virtual
    +   hosts. In addition, the proliferation of incompletely-implemented
    +   applications calling themselves "HTTP/1.0" has necessitated a
    +   protocol version change in order for two communicating applications
    +   to determine each other's true capabilities.
    +
    +   This specification defines the protocol referred to as "HTTP/1.1".
    +   This protocol includes more stringent requirements than HTTP/1.0 in
    +   order to ensure reliable implementation of its features.
    +
    +   Practical information systems require more functionality than simple
    +   retrieval, including search, front-end update, and annotation. HTTP
    +   allows an open-ended set of methods and headers that indicate the
    +   purpose of a request [47]. It builds on the discipline of reference
    +   provided by the Uniform Resource Identifier (URI) [3], as a location
    +   (URL) [4] or name (URN) [20], for indicating the resource to which a
    +
    +   method is to be applied. Messages are passed in a format similar to
    +   that used by Internet mail [9] as defined by the Multipurpose
    +   Internet Mail Extensions (MIME) [7].
    +
    +   HTTP is also used as a generic protocol for communication between
    +   user agents and proxies/gateways to other Internet systems, including
    +   those supported by the SMTP [16], NNTP [13], FTP [18], Gopher [2],
    +   and WAIS [10] protocols. In this way, HTTP allows basic hypermedia
    +   access to resources available from diverse applications.
    +
    +1.2 Requirements
    +
    +   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
    +   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
    +   document are to be interpreted as described in RFC 2119 [34].
    +
    +   An implementation is not compliant if it fails to satisfy one or more
    +   of the MUST or REQUIRED level requirements for the protocols it
    +   implements. An implementation that satisfies all the MUST or REQUIRED
    +   level and all the SHOULD level requirements for its protocols is said
    +   to be "unconditionally compliant"; one that satisfies all the MUST
    +   level requirements but not all the SHOULD level requirements for its
    +   protocols is said to be "conditionally compliant."
    +
    +1.3 Terminology
    +
    +   This specification uses a number of terms to refer to the roles
    +   played by participants in, and objects of, the HTTP communication.
    +
    +   connection
    +      A transport layer virtual circuit established between two programs
    +      for the purpose of communication.
    +
    +   message
    +      The basic unit of HTTP communication, consisting of a structured
    +      sequence of octets matching the syntax defined in section 4 and
    +      transmitted via the connection.
    +
    +   request
    +      An HTTP request message, as defined in section 5.
    +
    +   response
    +      An HTTP response message, as defined in section 6.
    +
    +   resource
    +      A network data object or service that can be identified by a URI,
    +      as defined in section 3.2. Resources may be available in multiple
    +      representations (e.g. multiple languages, data formats, size, and
    +      resolutions) or vary in other ways.
    +
    +   entity
    +      The information transferred as the payload of a request or
    +      response. An entity consists of metainformation in the form of
    +      entity-header fields and content in the form of an entity-body, as
    +      described in section 7.
    +
    +   representation
    +      An entity included with a response that is subject to content
    +      negotiation, as described in section 12. There may exist multiple
    +      representations associated with a particular response status.
    +
    +   content negotiation
    +      The mechanism for selecting the appropriate representation when
    +      servicing a request, as described in section 12. The
    +      representation of entities in any response can be negotiated
    +      (including error responses).
    +
    +   variant
    +      A resource may have one, or more than one, representation(s)
    +      associated with it at any given instant. Each of these
    +      representations is termed a `varriant'.  Use of the term `variant'
    +      does not necessarily imply that the resource is subject to content
    +      negotiation.
    +
    +   client
    +      A program that establishes connections for the purpose of sending
    +      requests.
    +
    +   user agent
    +      The client which initiates a request. These are often browsers,
    +      editors, spiders (web-traversing robots), or other end user tools.
    +
    +   server
    +      An application program that accepts connections in order to
    +      service requests by sending back responses. Any given program may
    +      be capable of being both a client and a server; our use of these
    +      terms refers only to the role being performed by the program for a
    +      particular connection, rather than to the program's capabilities
    +      in general. Likewise, any server may act as an origin server,
    +      proxy, gateway, or tunnel, switching behavior based on the nature
    +      of each request.
    +
    +   origin server
    +      The server on which a given resource resides or is to be created.
    +
    +   proxy
    +      An intermediary program which acts as both a server and a client
    +      for the purpose of making requests on behalf of other clients.
    +      Requests are serviced internally or by passing them on, with
    +      possible translation, to other servers. A proxy MUST implement
    +      both the client and server requirements of this specification. A
    +      "transparent proxy" is a proxy that does not modify the request or
    +      response beyond what is required for proxy authentication and
    +      identification. A "non-transparent proxy" is a proxy that modifies
    +      the request or response in order to provide some added service to
    +      the user agent, such as group annotation services, media type
    +      transformation, protocol reduction, or anonymity filtering. Except
    +      where either transparent or non-transparent behavior is explicitly
    +      stated, the HTTP proxy requirements apply to both types of
    +      proxies.
    +
    +   gateway
    +      A server which acts as an intermediary for some other server.
    +      Unlike a proxy, a gateway receives requests as if it were the
    +      origin server for the requested resource; the requesting client
    +      may not be aware that it is communicating with a gateway.
    +
    +   tunnel
    +      An intermediary program which is acting as a blind relay between
    +      two connections. Once active, a tunnel is not considered a party
    +      to the HTTP communication, though the tunnel may have been
    +      initiated by an HTTP request. The tunnel ceases to exist when both
    +      ends of the relayed connections are closed.
    +
    +   cache
    +      A program's local store of response messages and the subsystem
    +      that controls its message storage, retrieval, and deletion. A
    +      cache stores cacheable responses in order to reduce the response
    +      time and network bandwidth consumption on future, equivalent
    +      requests. Any client or server may include a cache, though a cache
    +      cannot be used by a server that is acting as a tunnel.
    +
    +   cacheable
    +      A response is cacheable if a cache is allowed to store a copy of
    +      the response message for use in answering subsequent requests. The
    +      rules for determining the cacheability of HTTP responses are
    +      defined in section 13. Even if a resource is cacheable, there may
    +      be additional constraints on whether a cache can use the cached
    +      copy for a particular request.
    +
    +   first-hand
    +      A response is first-hand if it comes directly and without
    +      unnecessary delay from the origin server, perhaps via one or more
    +      proxies. A response is also first-hand if its validity has just
    +      been checked directly with the origin server.
    +
    +   explicit expiration time
    +      The time at which the origin server intends that an entity should
    +      no longer be returned by a cache without further validation.
    +
    +   heuristic expiration time
    +      An expiration time assigned by a cache when no explicit expiration
    +      time is available.
    +
    +   age
    +      The age of a response is the time since it was sent by, or
    +      successfully validated with, the origin server.
    +
    +   freshness lifetime
    +      The length of time between the generation of a response and its
    +      expiration time.
    +
    +   fresh
    +      A response is fresh if its age has not yet exceeded its freshness
    +      lifetime.
    +
    +   stale
    +      A response is stale if its age has passed its freshness lifetime.
    +
    +   semantically transparent
    +      A cache behaves in a "semantically transparent" manner, with
    +      respect to a particular response, when its use affects neither the
    +      requesting client nor the origin server, except to improve
    +      performance. When a cache is semantically transparent, the client
    +      receives exactly the same response (except for hop-by-hop headers)
    +      that it would have received had its request been handled directly
    +      by the origin server.
    +
    +   validator
    +      A protocol element (e.g., an entity tag or a Last-Modified time)
    +      that is used to find out whether a cache entry is an equivalent
    +      copy of an entity.
    +
    +   upstream/downstream
    +      Upstream and downstream describe the flow of a message: all
    +      messages flow from upstream to downstream.
    +
    +   inbound/outbound
    +      Inbound and outbound refer to the request and response paths for
    +      messages: "inbound" means "traveling toward the origin server",
    +      and "outbound" means "traveling toward the user agent"
    +
    +1.4 Overall Operation
    +
    +   The HTTP protocol is a request/response protocol. A client sends a
    +   request to the server in the form of a request method, URI, and
    +   protocol version, followed by a MIME-like message containing request
    +   modifiers, client information, and possible body content over a
    +   connection with a server. The server responds with a status line,
    +   including the message's protocol version and a success or error code,
    +   followed by a MIME-like message containing server information, entity
    +   metainformation, and possible entity-body content. The relationship
    +   between HTTP and MIME is described in appendix 19.4.
    +
    +   Most HTTP communication is initiated by a user agent and consists of
    +   a request to be applied to a resource on some origin server. In the
    +   simplest case, this may be accomplished via a single connection (v)
    +   between the user agent (UA) and the origin server (O).
    +
    +          request chain ------------------------>
    +       UA -------------------v------------------- O
    +          <----------------------- response chain
    +
    +   A more complicated situation occurs when one or more intermediaries
    +   are present in the request/response chain. There are three common
    +   forms of intermediary: proxy, gateway, and tunnel. A proxy is a
    +   forwarding agent, receiving requests for a URI in its absolute form,
    +   rewriting all or part of the message, and forwarding the reformatted
    +   request toward the server identified by the URI. A gateway is a
    +   receiving agent, acting as a layer above some other server(s) and, if
    +   necessary, translating the requests to the underlying server's
    +   protocol. A tunnel acts as a relay point between two connections
    +   without changing the messages; tunnels are used when the
    +   communication needs to pass through an intermediary (such as a
    +   firewall) even when the intermediary cannot understand the contents
    +   of the messages.
    +
    +          request chain -------------------------------------->
    +       UA -----v----- A -----v----- B -----v----- C -----v----- O
    +          <------------------------------------- response chain
    +
    +   The figure above shows three intermediaries (A, B, and C) between the
    +   user agent and origin server. A request or response message that
    +   travels the whole chain will pass through four separate connections.
    +   This distinction is important because some HTTP communication options
    +
    +   may apply only to the connection with the nearest, non-tunnel
    +   neighbor, only to the end-points of the chain, or to all connections
    +   along the chain. Although the diagram is linear, each participant may
    +   be engaged in multiple, simultaneous communications. For example, B
    +   may be receiving requests from many clients other than A, and/or
    +   forwarding requests to servers other than C, at the same time that it
    +   is handling A's request.
    +
    +   Any party to the communication which is not acting as a tunnel may
    +   employ an internal cache for handling requests. The effect of a cache
    +   is that the request/response chain is shortened if one of the
    +   participants along the chain has a cached response applicable to that
    +   request. The following illustrates the resulting chain if B has a
    +   cached copy of an earlier response from O (via C) for a request which
    +   has not been cached by UA or A.
    +
    +          request chain ---------->
    +       UA -----v----- A -----v----- B - - - - - - C - - - - - - O
    +          <--------- response chain
    +
    +   Not all responses are usefully cacheable, and some requests may
    +   contain modifiers which place special requirements on cache behavior.
    +   HTTP requirements for cache behavior and cacheable responses are
    +   defined in section 13.
    +
    +   In fact, there are a wide variety of architectures and configurations
    +   of caches and proxies currently being experimented with or deployed
    +   across the World Wide Web. These systems include national hierarchies
    +   of proxy caches to save transoceanic bandwidth, systems that
    +   broadcast or multicast cache entries, organizations that distribute
    +   subsets of cached data via CD-ROM, and so on. HTTP systems are used
    +   in corporate intranets over high-bandwidth links, and for access via
    +   PDAs with low-power radio links and intermittent connectivity. The
    +   goal of HTTP/1.1 is to support the wide diversity of configurations
    +   already deployed while introducing protocol constructs that meet the
    +   needs of those who build web applications that require high
    +   reliability and, failing that, at least reliable indications of
    +   failure.
    +
    +   HTTP communication usually takes place over TCP/IP connections. The
    +   default port is TCP 80 [19], but other ports can be used. This does
    +   not preclude HTTP from being implemented on top of any other protocol
    +   on the Internet, or on other networks. HTTP only presumes a reliable
    +   transport; any protocol that provides such guarantees can be used;
    +   the mapping of the HTTP/1.1 request and response structures onto the
    +   transport data units of the protocol in question is outside the scope
    +   of this specification.
    +
    +   In HTTP/1.0, most implementations used a new connection for each
    +   request/response exchange. In HTTP/1.1, a connection may be used for
    +   one or more request/response exchanges, although connections may be
    +   closed for a variety of reasons (see section 8.1).
    +
    +2 Notational Conventions and Generic Grammar
    +
    +2.1 Augmented BNF
    +
    +   All of the mechanisms specified in this document are described in
    +   both prose and an augmented Backus-Naur Form (BNF) similar to that
    +   used by RFC 822 [9]. Implementors will need to be familiar with the
    +   notation in order to understand this specification. The augmented BNF
    +   includes the following constructs:
    +
    +   name = definition
    +      The name of a rule is simply the name itself (without any
    +      enclosing "<" and ">") and is separated from its definition by the
    +      equal "=" character. White space is only significant in that
    +      indentation of continuation lines is used to indicate a rule
    +      definition that spans more than one line. Certain basic rules are
    +      in uppercase, such as SP, LWS, HT, CRLF, DIGIT, ALPHA, etc. Angle
    +      brackets are used within definitions whenever their presence will
    +      facilitate discerning the use of rule names.
    +
    +   "literal"
    +      Quotation marks surround literal text. Unless stated otherwise,
    +      the text is case-insensitive.
    +
    +   rule1 | rule2
    +      Elements separated by a bar ("|") are alternatives, e.g., "yes |
    +      no" will accept yes or no.
    +
    +   (rule1 rule2)
    +      Elements enclosed in parentheses are treated as a single element.
    +      Thus, "(elem (foo | bar) elem)" allows the token sequences "elem
    +      foo elem" and "elem bar elem".
    +
    +   *rule
    +      The character "*" preceding an element indicates repetition. The
    +      full form is "<n>*<m>element" indicating at least <n> and at most
    +      <m> occurrences of element. Default values are 0 and infinity so
    +      that "*(element)" allows any number, including zero; "1*element"
    +      requires at least one; and "1*2element" allows one or two.
    +
    +   [rule]
    +      Square brackets enclose optional elements; "[foo bar]" is
    +      equivalent to "*1(foo bar)".
    +
    +   N rule
    +      Specific repetition: "<n>(element)" is equivalent to
    +      "<n>*<n>(element)"; that is, exactly <n> occurrences of (element).
    +      Thus 2DIGIT is a 2-digit number, and 3ALPHA is a string of three
    +      alphabetic characters.
    +
    +   #rule
    +      A construct "#" is defined, similar to "*", for defining lists of
    +      elements. The full form is "<n>#<m>element" indicating at least
    +      <n> and at most <m> elements, each separated by one or more commas
    +      (",") and OPTIONAL linear white space (LWS). This makes the usual
    +      form of lists very easy; a rule such as
    +         ( *LWS element *( *LWS "," *LWS element ))
    +      can be shown as
    +         1#element
    +      Wherever this construct is used, null elements are allowed, but do
    +      not contribute to the count of elements present. That is,
    +      "(element), , (element) " is permitted, but counts as only two
    +      elements. Therefore, where at least one element is required, at
    +      least one non-null element MUST be present. Default values are 0
    +      and infinity so that "#element" allows any number, including zero;
    +      "1#element" requires at least one; and "1#2element" allows one or
    +      two.
    +
    +   ; comment
    +      A semi-colon, set off some distance to the right of rule text,
    +      starts a comment that continues to the end of line. This is a
    +      simple way of including useful notes in parallel with the
    +      specifications.
    +
    +   implied *LWS
    +      The grammar described by this specification is word-based. Except
    +      where noted otherwise, linear white space (LWS) can be included
    +      between any two adjacent words (token or quoted-string), and
    +      between adjacent words and separators, without changing the
    +      interpretation of a field. At least one delimiter (LWS and/or
    +
    +      separators) MUST exist between any two tokens (for the definition
    +      of "token" below), since they would otherwise be interpreted as a
    +      single token.
    +
    +2.2 Basic Rules
    +
    +   The following rules are used throughout this specification to
    +   describe basic parsing constructs. The US-ASCII coded character set
    +   is defined by ANSI X3.4-1986 [21].
    +
    +       OCTET          = <any 8-bit sequence of data>
    +       CHAR           = <any US-ASCII character (octets 0 - 127)>
    +       UPALPHA        = <any US-ASCII uppercase letter "A".."Z">
    +       LOALPHA        = <any US-ASCII lowercase letter "a".."z">
    +       ALPHA          = UPALPHA | LOALPHA
    +       DIGIT          = <any US-ASCII digit "0".."9">
    +       CTL            = <any US-ASCII control character
    +                        (octets 0 - 31) and DEL (127)>
    +       CR             = <US-ASCII CR, carriage return (13)>
    +       LF             = <US-ASCII LF, linefeed (10)>
    +       SP             = <US-ASCII SP, space (32)>
    +       HT             = <US-ASCII HT, horizontal-tab (9)>
    +       <">            = <US-ASCII double-quote mark (34)>
    +
    +   HTTP/1.1 defines the sequence CR LF as the end-of-line marker for all
    +   protocol elements except the entity-body (see appendix 19.3 for
    +   tolerant applications). The end-of-line marker within an entity-body
    +   is defined by its associated media type, as described in section 3.7.
    +
    +       CRLF           = CR LF
    +
    +   HTTP/1.1 header field values can be folded onto multiple lines if the
    +   continuation line begins with a space or horizontal tab. All linear
    +   white space, including folding, has the same semantics as SP. A
    +   recipient MAY replace any linear white space with a single SP before
    +   interpreting the field value or forwarding the message downstream.
    +
    +       LWS            = [CRLF] 1*( SP | HT )
    +
    +   The TEXT rule is only used for descriptive field contents and values
    +   that are not intended to be interpreted by the message parser. Words
    +   of *TEXT MAY contain characters from character sets other than ISO-
    +   8859-1 [22] only when encoded according to the rules of RFC 2047
    +   [14].
    +
    +       TEXT           = <any OCTET except CTLs,
    +                        but including LWS>
    +
    +   A CRLF is allowed in the definition of TEXT only as part of a header
    +   field continuation. It is expected that the folding LWS will be
    +   replaced with a single SP before interpretation of the TEXT value.
    +
    +   Hexadecimal numeric characters are used in several protocol elements.
    +
    +       HEX            = "A" | "B" | "C" | "D" | "E" | "F"
    +                      | "a" | "b" | "c" | "d" | "e" | "f" | DIGIT
    +
    +   Many HTTP/1.1 header field values consist of words separated by LWS
    +   or special characters. These special characters MUST be in a quoted
    +   string to be used within a parameter value (as defined in section
    +   3.6).
    +
    +       token          = 1*<any CHAR except CTLs or separators>
    +       separators     = "(" | ")" | "<" | ">" | "@"
    +                      | "," | ";" | ":" | "\" | <">
    +                      | "/" | "[" | "]" | "?" | "="
    +                      | "{" | "}" | SP | HT
    +
    +   Comments can be included in some HTTP header fields by surrounding
    +   the comment text with parentheses. Comments are only allowed in
    +   fields containing "comment" as part of their field value definition.
    +   In all other fields, parentheses are considered part of the field
    +   value.
    +
    +       comment        = "(" *( ctext | quoted-pair | comment ) ")"
    +       ctext          = <any TEXT excluding "(" and ")">
    +
    +   A string of text is parsed as a single word if it is quoted using
    +   double-quote marks.
    +
    +       quoted-string  = ( <"> *(qdtext | quoted-pair ) <"> )
    +       qdtext         = <any TEXT except <">>
    +
    +   The backslash character ("\") MAY be used as a single-character
    +   quoting mechanism only within quoted-string and comment constructs.
    +
    +       quoted-pair    = "\" CHAR
    +
    +3 Protocol Parameters
    +
    +3.1 HTTP Version
    +
    +   HTTP uses a "<major>.<minor>" numbering scheme to indicate versions
    +   of the protocol. The protocol versioning policy is intended to allow
    +   the sender to indicate the format of a message and its capacity for
    +   understanding further HTTP communication, rather than the features
    +   obtained via that communication. No change is made to the version
    +   number for the addition of message components which do not affect
    +   communication behavior or which only add to extensible field values.
    +   The <minor> number is incremented when the changes made to the
    +   protocol add features which do not change the general message parsing
    +   algorithm, but which may add to the message semantics and imply
    +   additional capabilities of the sender. The <major> number is
    +   incremented when the format of a message within the protocol is
    +   changed. See RFC 2145 [36] for a fuller explanation.
    +
    +   The version of an HTTP message is indicated by an HTTP-Version field
    +   in the first line of the message.
    +
    +       HTTP-Version   = "HTTP" "/" 1*DIGIT "." 1*DIGIT
    +
    +   Note that the major and minor numbers MUST be treated as separate
    +   integers and that each MAY be incremented higher than a single digit.
    +   Thus, HTTP/2.4 is a lower version than HTTP/2.13, which in turn is
    +   lower than HTTP/12.3. Leading zeros MUST be ignored by recipients and
    +   MUST NOT be sent.
    +
    +   An application that sends a request or response message that includes
    +   HTTP-Version of "HTTP/1.1" MUST be at least conditionally compliant
    +   with this specification. Applications that are at least conditionally
    +   compliant with this specification SHOULD use an HTTP-Version of
    +   "HTTP/1.1" in their messages, and MUST do so for any message that is
    +   not compatible with HTTP/1.0. For more details on when to send
    +   specific HTTP-Version values, see RFC 2145 [36].
    +
    +   The HTTP version of an application is the highest HTTP version for
    +   which the application is at least conditionally compliant.
    +
    +   Proxy and gateway applications need to be careful when forwarding
    +   messages in protocol versions different from that of the application.
    +   Since the protocol version indicates the protocol capability of the
    +   sender, a proxy/gateway MUST NOT send a message with a version
    +   indicator which is greater than its actual version. If a higher
    +   version request is received, the proxy/gateway MUST either downgrade
    +   the request version, or respond with an error, or switch to tunnel
    +   behavior.
    +
    +   Due to interoperability problems with HTTP/1.0 proxies discovered
    +   since the publication of RFC 2068[33], caching proxies MUST, gateways
    +   MAY, and tunnels MUST NOT upgrade the request to the highest version
    +   they support. The proxy/gateway's response to that request MUST be in
    +   the same major version as the request.
    +
    +      Note: Converting between versions of HTTP may involve modification
    +      of header fields required or forbidden by the versions involved.
    +
    +3.2 Uniform Resource Identifiers
    +
    +   URIs have been known by many names: WWW addresses, Universal Document
    +   Identifiers, Universal Resource Identifiers [3], and finally the
    +   combination of Uniform Resource Locators (URL) [4] and Names (URN)
    +   [20]. As far as HTTP is concerned, Uniform Resource Identifiers are
    +   simply formatted strings which identify--via name, location, or any
    +   other characteristic--a resource.
    +
    +3.2.1 General Syntax
    +
    +   URIs in HTTP can be represented in absolute form or relative to some
    +   known base URI [11], depending upon the context of their use. The two
    +   forms are differentiated by the fact that absolute URIs always begin
    +   with a scheme name followed by a colon. For definitive information on
    +   URL syntax and semantics, see "Uniform Resource Identifiers (URI):
    +   Generic Syntax and Semantics," RFC 2396 [42] (which replaces RFCs
    +   1738 [4] and RFC 1808 [11]). This specification adopts the
    +   definitions of "URI-reference", "absoluteURI", "relativeURI", "port",
    +   "host","abs_path", "rel_path", and "authority" from that
    +   specification.
    +
    +   The HTTP protocol does not place any a priori limit on the length of
    +   a URI. Servers MUST be able to handle the URI of any resource they
    +   serve, and SHOULD be able to handle URIs of unbounded length if they
    +   provide GET-based forms that could generate such URIs. A server
    +   SHOULD return 414 (Request-URI Too Long) status if a URI is longer
    +   than the server can handle (see section 10.4.15).
    +
    +      Note: Servers ought to be cautious about depending on URI lengths
    +      above 255 bytes, because some older client or proxy
    +      implementations might not properly support these lengths.
    +
    +3.2.2 http URL
    +
    +   The "http" scheme is used to locate network resources via the HTTP
    +   protocol. This section defines the scheme-specific syntax and
    +   semantics for http URLs.
    +
    +   http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]
    +
    +   If the port is empty or not given, port 80 is assumed. The semantics
    +   are that the identified resource is located at the server listening
    +   for TCP connections on that port of that host, and the Request-URI
    +   for the resource is abs_path (section 5.1.2). The use of IP addresses
    +   in URLs SHOULD be avoided whenever possible (see RFC 1900 [24]). If
    +   the abs_path is not present in the URL, it MUST be given as "/" when
    +   used as a Request-URI for a resource (section 5.1.2). If a proxy
    +   receives a host name which is not a fully qualified domain name, it
    +   MAY add its domain to the host name it received. If a proxy receives
    +   a fully qualified domain name, the proxy MUST NOT change the host
    +   name.
    +
    +3.2.3 URI Comparison
    +
    +   When comparing two URIs to decide if they match or not, a client
    +   SHOULD use a case-sensitive octet-by-octet comparison of the entire
    +   URIs, with these exceptions:
    +
    +      - A port that is empty or not given is equivalent to the default
    +        port for that URI-reference;
    +
    +        - Comparisons of host names MUST be case-insensitive;
    +
    +        - Comparisons of scheme names MUST be case-insensitive;
    +
    +        - An empty abs_path is equivalent to an abs_path of "/".
    +
    +   Characters other than those in the "reserved" and "unsafe" sets (see
    +   RFC 2396 [42]) are equivalent to their ""%" HEX HEX" encoding.
    +
    +   For example, the following three URIs are equivalent:
    +
    +      http://abc.com:80/~smith/home.html
    +      http://ABC.com/%7Esmith/home.html
    +      /ABC.com:/%7esmith/home.html">http://ABC.com:/%7esmith/home.html
    +
    +3.3 Date/Time Formats
    +
    +3.3.1 Full Date
    +
    +   HTTP applications have historically allowed three different formats
    +   for the representation of date/time stamps:
    +
    +      Sun, 06 Nov 1994 08:49:37 GMT  ; RFC 822, updated by RFC 1123
    +      Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
    +      Sun Nov  6 08:49:37 1994       ; ANSI C's asctime() format
    +
    +   The first format is preferred as an Internet standard and represents
    +   a fixed-length subset of that defined by RFC 1123 [8] (an update to
    +   RFC 822 [9]). The second format is in common use, but is based on the
    +   obsolete RFC 850 [12] date format and lacks a four-digit year.
    +   HTTP/1.1 clients and servers that parse the date value MUST accept
    +   all three formats (for compatibility with HTTP/1.0), though they MUST
    +   only generate the RFC 1123 format for representing HTTP-date values
    +   in header fields. See section 19.3 for further information.
    +
    +      Note: Recipients of date values are encouraged to be robust in
    +      accepting date values that may have been sent by non-HTTP
    +      applications, as is sometimes the case when retrieving or posting
    +      messages via proxies/gateways to SMTP or NNTP.
    +
    +   All HTTP date/time stamps MUST be represented in Greenwich Mean Time
    +   (GMT), without exception. For the purposes of HTTP, GMT is exactly
    +   equal to UTC (Coordinated Universal Time). This is indicated in the
    +   first two formats by the inclusion of "GMT" as the three-letter
    +   abbreviation for time zone, and MUST be assumed when reading the
    +   asctime format. HTTP-date is case sensitive and MUST NOT include
    +   additional LWS beyond that specifically included as SP in the
    +   grammar.
    +
    +       HTTP-date    = rfc1123-date | rfc850-date | asctime-date
    +       rfc1123-date = wkday "," SP date1 SP time SP "GMT"
    +       rfc850-date  = weekday "," SP date2 SP time SP "GMT"
    +       asctime-date = wkday SP date3 SP time SP 4DIGIT
    +       date1        = 2DIGIT SP month SP 4DIGIT
    +                      ; day month year (e.g., 02 Jun 1982)
    +       date2        = 2DIGIT "-" month "-" 2DIGIT
    +                      ; day-month-year (e.g., 02-Jun-82)
    +       date3        = month SP ( 2DIGIT | ( SP 1DIGIT ))
    +                      ; month day (e.g., Jun  2)
    +       time         = 2DIGIT ":" 2DIGIT ":" 2DIGIT
    +                      ; 00:00:00 - 23:59:59
    +       wkday        = "Mon" | "Tue" | "Wed"
    +                    | "Thu" | "Fri" | "Sat" | "Sun"
    +       weekday      = "Monday" | "Tuesday" | "Wednesday"
    +                    | "Thursday" | "Friday" | "Saturday" | "Sunday"
    +       month        = "Jan" | "Feb" | "Mar" | "Apr"
    +                    | "May" | "Jun" | "Jul" | "Aug"
    +                    | "Sep" | "Oct" | "Nov" | "Dec"
    +
    +      Note: HTTP requirements for the date/time stamp format apply only
    +      to their usage within the protocol stream. Clients and servers are
    +      not required to use these formats for user presentation, request
    +      logging, etc.
    +
    +3.3.2 Delta Seconds
    +
    +   Some HTTP header fields allow a time value to be specified as an
    +   integer number of seconds, represented in decimal, after the time
    +   that the message was received.
    +
    +       delta-seconds  = 1*DIGIT
    +
    +3.4 Character Sets
    +
    +   HTTP uses the same definition of the term "character set" as that
    +   described for MIME:
    +
    +   The term "character set" is used in this document to refer to a
    +   method used with one or more tables to convert a sequence of octets
    +   into a sequence of characters. Note that unconditional conversion in
    +   the other direction is not required, in that not all characters may
    +   be available in a given character set and a character set may provide
    +   more than one sequence of octets to represent a particular character.
    +   This definition is intended to allow various kinds of character
    +   encoding, from simple single-table mappings such as US-ASCII to
    +   complex table switching methods such as those that use ISO-2022's
    +   techniques. However, the definition associated with a MIME character
    +   set name MUST fully specify the mapping to be performed from octets
    +   to characters. In particular, use of external profiling information
    +   to determine the exact mapping is not permitted.
    +
    +      Note: This use of the term "character set" is more commonly
    +      referred to as a "character encoding." However, since HTTP and
    +      MIME share the same registry, it is important that the terminology
    +      also be shared.
    +
    +   HTTP character sets are identified by case-insensitive tokens. The
    +   complete set of tokens is defined by the IANA Character Set registry
    +   [19].
    +
    +       charset = token
    +
    +   Although HTTP allows an arbitrary token to be used as a charset
    +   value, any token that has a predefined value within the IANA
    +   Character Set registry [19] MUST represent the character set defined
    +   by that registry. Applications SHOULD limit their use of character
    +   sets to those defined by the IANA registry.
    +
    +   Implementors should be aware of IETF character set requirements [38]
    +   [41].
    +
    +3.4.1 Missing Charset
    +
    +   Some HTTP/1.0 software has interpreted a Content-Type header without
    +   charset parameter incorrectly to mean "recipient should guess."
    +   Senders wishing to defeat this behavior MAY include a charset
    +   parameter even when the charset is ISO-8859-1 and SHOULD do so when
    +   it is known that it will not confuse the recipient.
    +
    +   Unfortunately, some older HTTP/1.0 clients did not deal properly with
    +   an explicit charset parameter. HTTP/1.1 recipients MUST respect the
    +   charset label provided by the sender; and those user agents that have
    +   a provision to "guess" a charset MUST use the charset from the
    +
    +   content-type field if they support that charset, rather than the
    +   recipient's preference, when initially displaying a document. See
    +   section 3.7.1.
    +
    +3.5 Content Codings
    +
    +   Content coding values indicate an encoding transformation that has
    +   been or can be applied to an entity. Content codings are primarily
    +   used to allow a document to be compressed or otherwise usefully
    +   transformed without losing the identity of its underlying media type
    +   and without loss of information. Frequently, the entity is stored in
    +   coded form, transmitted directly, and only decoded by the recipient.
    +
    +       content-coding   = token
    +
    +   All content-coding values are case-insensitive. HTTP/1.1 uses
    +   content-coding values in the Accept-Encoding (section 14.3) and
    +   Content-Encoding (section 14.11) header fields. Although the value
    +   describes the content-coding, what is more important is that it
    +   indicates what decoding mechanism will be required to remove the
    +   encoding.
    +
    +   The Internet Assigned Numbers Authority (IANA) acts as a registry for
    +   content-coding value tokens. Initially, the registry contains the
    +   following tokens:
    +
    +   gzip An encoding format produced by the file compression program
    +        "gzip" (GNU zip) as described in RFC 1952 [25]. This format is a
    +        Lempel-Ziv coding (LZ77) with a 32 bit CRC.
    +
    +   compress
    +        The encoding format produced by the common UNIX file compression
    +        program "compress". This format is an adaptive Lempel-Ziv-Welch
    +        coding (LZW).
    +
    +        Use of program names for the identification of encoding formats
    +        is not desirable and is discouraged for future encodings. Their
    +        use here is representative of historical practice, not good
    +        design. For compatibility with previous implementations of HTTP,
    +        applications SHOULD consider "x-gzip" and "x-compress" to be
    +        equivalent to "gzip" and "compress" respectively.
    +
    +   deflate
    +        The "zlib" format defined in RFC 1950 [31] in combination with
    +        the "deflate" compression mechanism described in RFC 1951 [29].
    +
    +   identity
    +        The default (identity) encoding; the use of no transformation
    +        whatsoever. This content-coding is used only in the Accept-
    +        Encoding header, and SHOULD NOT be used in the Content-Encoding
    +        header.
    +
    +   New content-coding value tokens SHOULD be registered; to allow
    +   interoperability between clients and servers, specifications of the
    +   content coding algorithms needed to implement a new value SHOULD be
    +   publicly available and adequate for independent implementation, and
    +   conform to the purpose of content coding defined in this section.
    +
    +3.6 Transfer Codings
    +
    +   Transfer-coding values are used to indicate an encoding
    +   transformation that has been, can be, or may need to be applied to an
    +   entity-body in order to ensure "safe transport" through the network.
    +   This differs from a content coding in that the transfer-coding is a
    +   property of the message, not of the original entity.
    +
    +       transfer-coding         = "chunked" | transfer-extension
    +       transfer-extension      = token *( ";" parameter )
    +
    +   Parameters are in  the form of attribute/value pairs.
    +
    +       parameter               = attribute "=" value
    +       attribute               = token
    +       value                   = token | quoted-string
    +
    +   All transfer-coding values are case-insensitive. HTTP/1.1 uses
    +   transfer-coding values in the TE header field (section 14.39) and in
    +   the Transfer-Encoding header field (section 14.41).
    +
    +   Whenever a transfer-coding is applied to a message-body, the set of
    +   transfer-codings MUST include "chunked", unless the message is
    +   terminated by closing the connection. When the "chunked" transfer-
    +   coding is used, it MUST be the last transfer-coding applied to the
    +   message-body. The "chunked" transfer-coding MUST NOT be applied more
    +   than once to a message-body. These rules allow the recipient to
    +   determine the transfer-length of the message (section 4.4).
    +
    +   Transfer-codings are analogous to the Content-Transfer-Encoding
    +   values of MIME [7], which were designed to enable safe transport of
    +   binary data over a 7-bit transport service. However, safe transport
    +   has a different focus for an 8bit-clean transfer protocol. In HTTP,
    +   the only unsafe characteristic of message-bodies is the difficulty in
    +   determining the exact body length (section 7.2.2), or the desire to
    +   encrypt data over a shared transport.
    +
    +   The Internet Assigned Numbers Authority (IANA) acts as a registry for
    +   transfer-coding value tokens. Initially, the registry contains the
    +   following tokens: "chunked" (section 3.6.1), "identity" (section
    +   3.6.2), "gzip" (section 3.5), "compress" (section 3.5), and "deflate"
    +   (section 3.5).
    +
    +   New transfer-coding value tokens SHOULD be registered in the same way
    +   as new content-coding value tokens (section 3.5).
    +
    +   A server which receives an entity-body with a transfer-coding it does
    +   not understand SHOULD return 501 (Unimplemented), and close the
    +   connection. A server MUST NOT send transfer-codings to an HTTP/1.0
    +   client.
    +
    +3.6.1 Chunked Transfer Coding
    +
    +   The chunked encoding modifies the body of a message in order to
    +   transfer it as a series of chunks, each with its own size indicator,
    +   followed by an OPTIONAL trailer containing entity-header fields. This
    +   allows dynamically produced content to be transferred along with the
    +   information necessary for the recipient to verify that it has
    +   received the full message.
    +
    +       Chunked-Body   = *chunk
    +                        last-chunk
    +                        trailer
    +                        CRLF
    +
    +       chunk          = chunk-size [ chunk-extension ] CRLF
    +                        chunk-data CRLF
    +       chunk-size     = 1*HEX
    +       last-chunk     = 1*("0") [ chunk-extension ] CRLF
    +
    +       chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
    +       chunk-ext-name = token
    +       chunk-ext-val  = token | quoted-string
    +       chunk-data     = chunk-size(OCTET)
    +       trailer        = *(entity-header CRLF)
    +
    +   The chunk-size field is a string of hex digits indicating the size of
    +   the chunk. The chunked encoding is ended by any chunk whose size is
    +   zero, followed by the trailer, which is terminated by an empty line.
    +
    +   The trailer allows the sender to include additional HTTP header
    +   fields at the end of the message. The Trailer header field can be
    +   used to indicate which header fields are included in a trailer (see
    +   section 14.40).
    +
    +   A server using chunked transfer-coding in a response MUST NOT use the
    +   trailer for any header fields unless at least one of the following is
    +   true:
    +
    +   a)the request included a TE header field that indicates "trailers" is
    +     acceptable in the transfer-coding of the  response, as described in
    +     section 14.39; or,
    +
    +   b)the server is the origin server for the response, the trailer
    +     fields consist entirely of optional metadata, and the recipient
    +     could use the message (in a manner acceptable to the origin server)
    +     without receiving this metadata.  In other words, the origin server
    +     is willing to accept the possibility that the trailer fields might
    +     be silently discarded along the path to the client.
    +
    +   This requirement prevents an interoperability failure when the
    +   message is being received by an HTTP/1.1 (or later) proxy and
    +   forwarded to an HTTP/1.0 recipient. It avoids a situation where
    +   compliance with the protocol would have necessitated a possibly
    +   infinite buffer on the proxy.
    +
    +   An example process for decoding a Chunked-Body is presented in
    +   appendix 19.4.6.
    +
    +   All HTTP/1.1 applications MUST be able to receive and decode the
    +   "chunked" transfer-coding, and MUST ignore chunk-extension extensions
    +   they do not understand.
    +
    +3.7 Media Types
    +
    +   HTTP uses Internet Media Types [17] in the Content-Type (section
    +   14.17) and Accept (section 14.1) header fields in order to provide
    +   open and extensible data typing and type negotiation.
    +
    +       media-type     = type "/" subtype *( ";" parameter )
    +       type           = token
    +       subtype        = token
    +
    +   Parameters MAY follow the type/subtype in the form of attribute/value
    +   pairs (as defined in section 3.6).
    +
    +   The type, subtype, and parameter attribute names are case-
    +   insensitive. Parameter values might or might not be case-sensitive,
    +   depending on the semantics of the parameter name. Linear white space
    +   (LWS) MUST NOT be used between the type and subtype, nor between an
    +   attribute and its value. The presence or absence of a parameter might
    +   be significant to the processing of a media-type, depending on its
    +   definition within the media type registry.
    +
    +   Note that some older HTTP applications do not recognize media type
    +   parameters. When sending data to older HTTP applications,
    +   implementations SHOULD only use media type parameters when they are
    +   required by that type/subtype definition.
    +
    +   Media-type values are registered with the Internet Assigned Number
    +   Authority (IANA [19]). The media type registration process is
    +   outlined in RFC 1590 [17]. Use of non-registered media types is
    +   discouraged.
    +
    +3.7.1 Canonicalization and Text Defaults
    +
    +   Internet media types are registered with a canonical form. An
    +   entity-body transferred via HTTP messages MUST be represented in the
    +   appropriate canonical form prior to its transmission except for
    +   "text" types, as defined in the next paragraph.
    +
    +   When in canonical form, media subtypes of the "text" type use CRLF as
    +   the text line break. HTTP relaxes this requirement and allows the
    +   transport of text media with plain CR or LF alone representing a line
    +   break when it is done consistently for an entire entity-body. HTTP
    +   applications MUST accept CRLF, bare CR, and bare LF as being
    +   representative of a line break in text media received via HTTP. In
    +   addition, if the text is represented in a character set that does not
    +   use octets 13 and 10 for CR and LF respectively, as is the case for
    +   some multi-byte character sets, HTTP allows the use of whatever octet
    +   sequences are defined by that character set to represent the
    +   equivalent of CR and LF for line breaks. This flexibility regarding
    +   line breaks applies only to text media in the entity-body; a bare CR
    +   or LF MUST NOT be substituted for CRLF within any of the HTTP control
    +   structures (such as header fields and multipart boundaries).
    +
    +   If an entity-body is encoded with a content-coding, the underlying
    +   data MUST be in a form defined above prior to being encoded.
    +
    +   The "charset" parameter is used with some media types to define the
    +   character set (section 3.4) of the data. When no explicit charset
    +   parameter is provided by the sender, media subtypes of the "text"
    +   type are defined to have a default charset value of "ISO-8859-1" when
    +   received via HTTP. Data in character sets other than "ISO-8859-1" or
    +   its subsets MUST be labeled with an appropriate charset value. See
    +   section 3.4.1 for compatibility problems.
    +
    +3.7.2 Multipart Types
    +
    +   MIME provides for a number of "multipart" types -- encapsulations of
    +   one or more entities within a single message-body. All multipart
    +   types share a common syntax, as defined in section 5.1.1 of RFC 2046
    +
    +   [40], and MUST include a boundary parameter as part of the media type
    +   value. The message body is itself a protocol element and MUST
    +   therefore use only CRLF to represent line breaks between body-parts.
    +   Unlike in RFC 2046, the epilogue of any multipart message MUST be
    +   empty; HTTP applications MUST NOT transmit the epilogue (even if the
    +   original multipart contains an epilogue). These restrictions exist in
    +   order to preserve the self-delimiting nature of a multipart message-
    +   body, wherein the "end" of the message-body is indicated by the
    +   ending multipart boundary.
    +
    +   In general, HTTP treats a multipart message-body no differently than
    +   any other media type: strictly as payload. The one exception is the
    +   "multipart/byteranges" type (appendix 19.2) when it appears in a 206
    +   (Partial Content) response, which will be interpreted by some HTTP
    +   caching mechanisms as described in sections 13.5.4 and 14.16. In all
    +   other cases, an HTTP user agent SHOULD follow the same or similar
    +   behavior as a MIME user agent would upon receipt of a multipart type.
    +   The MIME header fields within each body-part of a multipart message-
    +   body do not have any significance to HTTP beyond that defined by
    +   their MIME semantics.
    +
    +   In general, an HTTP user agent SHOULD follow the same or similar
    +   behavior as a MIME user agent would upon receipt of a multipart type.
    +   If an application receives an unrecognized multipart subtype, the
    +   application MUST treat it as being equivalent to "multipart/mixed".
    +
    +      Note: The "multipart/form-data" type has been specifically defined
    +      for carrying form data suitable for processing via the POST
    +      request method, as described in RFC 1867 [15].
    +
    +3.8 Product Tokens
    +
    +   Product tokens are used to allow communicating applications to
    +   identify themselves by software name and version. Most fields using
    +   product tokens also allow sub-products which form a significant part
    +   of the application to be listed, separated by white space. By
    +   convention, the products are listed in order of their significance
    +   for identifying the application.
    +
    +       product         = token ["/" product-version]
    +       product-version = token
    +
    +   Examples:
    +
    +       User-Agent: CERN-LineMode/2.15 libwww/2.17b3
    +       Server: Apache/0.8.4
    +
    +   Product tokens SHOULD be short and to the point. They MUST NOT be
    +   used for advertising or other non-essential information. Although any
    +   token character MAY appear in a product-version, this token SHOULD
    +   only be used for a version identifier (i.e., successive versions of
    +   the same product SHOULD only differ in the product-version portion of
    +   the product value).
    +
    +3.9 Quality Values
    +
    +   HTTP content negotiation (section 12) uses short "floating point"
    +   numbers to indicate the relative importance ("weight") of various
    +   negotiable parameters.  A weight is normalized to a real number in
    +   the range 0 through 1, where 0 is the minimum and 1 the maximum
    +   value. If a parameter has a quality value of 0, then content with
    +   this parameter is `not acceptable' for the client. HTTP/1.1
    +   applications MUST NOT generate more than three digits after the
    +   decimal point. User configuration of these values SHOULD also be
    +   limited in this fashion.
    +
    +       qvalue         = ( "0" [ "." 0*3DIGIT ] )
    +                      | ( "1" [ "." 0*3("0") ] )
    +
    +   "Quality values" is a misnomer, since these values merely represent
    +   relative degradation in desired quality.
    +
    +3.10 Language Tags
    +
    +   A language tag identifies a natural language spoken, written, or
    +   otherwise conveyed by human beings for communication of information
    +   to other human beings. Computer languages are explicitly excluded.
    +   HTTP uses language tags within the Accept-Language and Content-
    +   Language fields.
    +
    +   The syntax and registry of HTTP language tags is the same as that
    +   defined by RFC 1766 [1]. In summary, a language tag is composed of 1
    +   or more parts: A primary language tag and a possibly empty series of
    +   subtags:
    +
    +        language-tag  = primary-tag *( "-" subtag )
    +        primary-tag   = 1*8ALPHA
    +        subtag        = 1*8ALPHA
    +
    +   White space is not allowed within the tag and all tags are case-
    +   insensitive. The name space of language tags is administered by the
    +   IANA. Example tags include:
    +
    +       en, en-US, en-cockney, i-cherokee, x-pig-latin
    +
    +   where any two-letter primary-tag is an ISO-639 language abbreviation
    +   and any two-letter initial subtag is an ISO-3166 country code. (The
    +   last three tags above are not registered tags; all but the last are
    +   examples of tags which could be registered in future.)
    +
    +3.11 Entity Tags
    +
    +   Entity tags are used for comparing two or more entities from the same
    +   requested resource. HTTP/1.1 uses entity tags in the ETag (section
    +   14.19), If-Match (section 14.24), If-None-Match (section 14.26), and
    +   If-Range (section 14.27) header fields. The definition of how they
    +   are used and compared as cache validators is in section 13.3.3. An
    +   entity tag consists of an opaque quoted string, possibly prefixed by
    +   a weakness indicator.
    +
    +      entity-tag = [ weak ] opaque-tag
    +      weak       = "W/"
    +      opaque-tag = quoted-string
    +
    +   A "strong entity tag" MAY be shared by two entities of a resource
    +   only if they are equivalent by octet equality.
    +
    +   A "weak entity tag," indicated by the "W/" prefix, MAY be shared by
    +   two entities of a resource only if the entities are equivalent and
    +   could be substituted for each other with no significant change in
    +   semantics. A weak entity tag can only be used for weak comparison.
    +
    +   An entity tag MUST be unique across all versions of all entities
    +   associated with a particular resource. A given entity tag value MAY
    +   be used for entities obtained by requests on different URIs. The use
    +   of the same entity tag value in conjunction with entities obtained by
    +   requests on different URIs does not imply the equivalence of those
    +   entities.
    +
    +3.12 Range Units
    +
    +   HTTP/1.1 allows a client to request that only part (a range of) the
    +   response entity be included within the response. HTTP/1.1 uses range
    +   units in the Range (section 14.35) and Content-Range (section 14.16)
    +   header fields. An entity can be broken down into subranges according
    +   to various structural units.
    +
    +      range-unit       = bytes-unit | other-range-unit
    +      bytes-unit       = "bytes"
    +      other-range-unit = token
    +
    +   The only range unit defined by HTTP/1.1 is "bytes". HTTP/1.1
    +   implementations MAY ignore ranges specified using other units.
    +
    +   HTTP/1.1 has been designed to allow implementations of applications
    +   that do not depend on knowledge of ranges.
    +
    +4 HTTP Message
    +
    +4.1 Message Types
    +
    +   HTTP messages consist of requests from client to server and responses
    +   from server to client.
    +
    +       HTTP-message   = Request | Response     ; HTTP/1.1 messages
    +
    +   Request (section 5) and Response (section 6) messages use the generic
    +   message format of RFC 822 [9] for transferring entities (the payload
    +   of the message). Both types of message consist of a start-line, zero
    +   or more header fields (also known as "headers"), an empty line (i.e.,
    +   a line with nothing preceding the CRLF) indicating the end of the
    +   header fields, and possibly a message-body.
    +
    +        generic-message = start-line
    +                          *(message-header CRLF)
    +                          CRLF
    +                          [ message-body ]
    +        start-line      = Request-Line | Status-Line
    +
    +   In the interest of robustness, servers SHOULD ignore any empty
    +   line(s) received where a Request-Line is expected. In other words, if
    +   the server is reading the protocol stream at the beginning of a
    +   message and receives a CRLF first, it should ignore the CRLF.
    +
    +   Certain buggy HTTP/1.0 client implementations generate extra CRLF's
    +   after a POST request. To restate what is explicitly forbidden by the
    +   BNF, an HTTP/1.1 client MUST NOT preface or follow a request with an
    +   extra CRLF.
    +
    +4.2 Message Headers
    +
    +   HTTP header fields, which include general-header (section 4.5),
    +   request-header (section 5.3), response-header (section 6.2), and
    +   entity-header (section 7.1) fields, follow the same generic format as
    +   that given in Section 3.1 of RFC 822 [9]. Each header field consists
    +   of a name followed by a colon (":") and the field value. Field names
    +   are case-insensitive. The field value MAY be preceded by any amount
    +   of LWS, though a single SP is preferred. Header fields can be
    +   extended over multiple lines by preceding each extra line with at
    +   least one SP or HT. Applications ought to follow "common form", where
    +   one is known or indicated, when generating HTTP constructs, since
    +   there might exist some implementations that fail to accept anything
    +
    +   beyond the common forms.
    +
    +       message-header = field-name ":" [ field-value ]
    +       field-name     = token
    +       field-value    = *( field-content | LWS )
    +       field-content  = <the OCTETs making up the field-value
    +                        and consisting of either *TEXT or combinations
    +                        of token, separators, and quoted-string>
    +
    +   The field-content does not include any leading or trailing LWS:
    +   linear white space occurring before the first non-whitespace
    +   character of the field-value or after the last non-whitespace
    +   character of the field-value. Such leading or trailing LWS MAY be
    +   removed without changing the semantics of the field value. Any LWS
    +   that occurs between field-content MAY be replaced with a single SP
    +   before interpreting the field value or forwarding the message
    +   downstream.
    +
    +   The order in which header fields with differing field names are
    +   received is not significant. However, it is "good practice" to send
    +   general-header fields first, followed by request-header or response-
    +   header fields, and ending with the entity-header fields.
    +
    +   Multiple message-header fields with the same field-name MAY be
    +   present in a message if and only if the entire field-value for that
    +   header field is defined as a comma-separated list [i.e., #(values)].
    +   It MUST be possible to combine the multiple header fields into one
    +   "field-name: field-value" pair, without changing the semantics of the
    +   message, by appending each subsequent field-value to the first, each
    +   separated by a comma. The order in which header fields with the same
    +   field-name are received is therefore significant to the
    +   interpretation of the combined field value, and thus a proxy MUST NOT
    +   change the order of these field values when a message is forwarded.
    +
    +4.3 Message Body
    +
    +   The message-body (if any) of an HTTP message is used to carry the
    +   entity-body associated with the request or response. The message-body
    +   differs from the entity-body only when a transfer-coding has been
    +   applied, as indicated by the Transfer-Encoding header field (section
    +   14.41).
    +
    +       message-body = entity-body
    +                    | <entity-body encoded as per Transfer-Encoding>
    +
    +   Transfer-Encoding MUST be used to indicate any transfer-codings
    +   applied by an application to ensure safe and proper transfer of the
    +   message. Transfer-Encoding is a property of the message, not of the
    +
    +   entity, and thus MAY be added or removed by any application along the
    +   request/response chain. (However, section 3.6 places restrictions on
    +   when certain transfer-codings may be used.)
    +
    +   The rules for when a message-body is allowed in a message differ for
    +   requests and responses.
    +
    +   The presence of a message-body in a request is signaled by the
    +   inclusion of a Content-Length or Transfer-Encoding header field in
    +   the request's message-headers. A message-body MUST NOT be included in
    +   a request if the specification of the request method (section 5.1.1)
    +   does not allow sending an entity-body in requests. A server SHOULD
    +   read and forward a message-body on any request; if the request method
    +   does not include defined semantics for an entity-body, then the
    +   message-body SHOULD be ignored when handling the request.
    +
    +   For response messages, whether or not a message-body is included with
    +   a message is dependent on both the request method and the response
    +   status code (section 6.1.1). All responses to the HEAD request method
    +   MUST NOT include a message-body, even though the presence of entity-
    +   header fields might lead one to believe they do. All 1xx
    +   (informational), 204 (no content), and 304 (not modified) responses
    +   MUST NOT include a message-body. All other responses do include a
    +   message-body, although it MAY be of zero length.
    +
    +4.4 Message Length
    +
    +   The transfer-length of a message is the length of the message-body as
    +   it appears in the message; that is, after any transfer-codings have
    +   been applied. When a message-body is included with a message, the
    +   transfer-length of that body is determined by one of the following
    +   (in order of precedence):
    +
    +   1.Any response message which "MUST NOT" include a message-body (such
    +     as the 1xx, 204, and 304 responses and any response to a HEAD
    +     request) is always terminated by the first empty line after the
    +     header fields, regardless of the entity-header fields present in
    +     the message.
    +
    +   2.If a Transfer-Encoding header field (section 14.41) is present and
    +     has any value other than "identity", then the transfer-length is
    +     defined by use of the "chunked" transfer-coding (section 3.6),
    +     unless the message is terminated by closing the connection.
    +
    +   3.If a Content-Length header field (section 14.13) is present, its
    +     decimal value in OCTETs represents both the entity-length and the
    +     transfer-length. The Content-Length header field MUST NOT be sent
    +     if these two lengths are different (i.e., if a Transfer-Encoding
    +
    +     header field is present). If a message is received with both a
    +     Transfer-Encoding header field and a Content-Length header field,
    +     the latter MUST be ignored.
    +
    +   4.If the message uses the media type "multipart/byteranges", and the
    +     ransfer-length is not otherwise specified, then this self-
    +     elimiting media type defines the transfer-length. This media type
    +     UST NOT be used unless the sender knows that the recipient can arse
    +     it; the presence in a request of a Range header with ultiple byte-
    +     range specifiers from a 1.1 client implies that the lient can parse
    +     multipart/byteranges responses.
    +
    +       A range header might be forwarded by a 1.0 proxy that does not
    +       understand multipart/byteranges; in this case the server MUST
    +       delimit the message using methods defined in items 1,3 or 5 of
    +       this section.
    +
    +   5.By the server closing the connection. (Closing the connection
    +     cannot be used to indicate the end of a request body, since that
    +     would leave no possibility for the server to send back a response.)
    +
    +   For compatibility with HTTP/1.0 applications, HTTP/1.1 requests
    +   containing a message-body MUST include a valid Content-Length header
    +   field unless the server is known to be HTTP/1.1 compliant. If a
    +   request contains a message-body and a Content-Length is not given,
    +   the server SHOULD respond with 400 (bad request) if it cannot
    +   determine the length of the message, or with 411 (length required) if
    +   it wishes to insist on receiving a valid Content-Length.
    +
    +   All HTTP/1.1 applications that receive entities MUST accept the
    +   "chunked" transfer-coding (section 3.6), thus allowing this mechanism
    +   to be used for messages when the message length cannot be determined
    +   in advance.
    +
    +   Messages MUST NOT include both a Content-Length header field and a
    +   non-identity transfer-coding. If the message does include a non-
    +   identity transfer-coding, the Content-Length MUST be ignored.
    +
    +   When a Content-Length is given in a message where a message-body is
    +   allowed, its field value MUST exactly match the number of OCTETs in
    +   the message-body. HTTP/1.1 user agents MUST notify the user when an
    +   invalid length is received and detected.
    +
    +4.5 General Header Fields
    +
    +   There are a few header fields which have general applicability for
    +   both request and response messages, but which do not apply to the
    +   entity being transferred. These header fields apply only to the
    +
    +   message being transmitted.
    +
    +       general-header = Cache-Control            ; Section 14.9
    +                      | Connection               ; Section 14.10
    +                      | Date                     ; Section 14.18
    +                      | Pragma                   ; Section 14.32
    +                      | Trailer                  ; Section 14.40
    +                      | Transfer-Encoding        ; Section 14.41
    +                      | Upgrade                  ; Section 14.42
    +                      | Via                      ; Section 14.45
    +                      | Warning                  ; Section 14.46
    +
    +   General-header field names can be extended reliably only in
    +   combination with a change in the protocol version. However, new or
    +   experimental header fields may be given the semantics of general
    +   header fields if all parties in the communication recognize them to
    +   be general-header fields. Unrecognized header fields are treated as
    +   entity-header fields.
    +
    +5 Request
    +
    +   A request message from a client to a server includes, within the
    +   first line of that message, the method to be applied to the resource,
    +   the identifier of the resource, and the protocol version in use.
    +
    +        Request       = Request-Line              ; Section 5.1
    +                        *(( general-header        ; Section 4.5
    +                         | request-header         ; Section 5.3
    +                         | entity-header ) CRLF)  ; Section 7.1
    +                        CRLF
    +                        [ message-body ]          ; Section 4.3
    +
    +5.1 Request-Line
    +
    +   The Request-Line begins with a method token, followed by the
    +   Request-URI and the protocol version, and ending with CRLF. The
    +   elements are separated by SP characters. No CR or LF is allowed
    +   except in the final CRLF sequence.
    +
    +        Request-Line   = Method SP Request-URI SP HTTP-Version CRLF
    +
    +5.1.1 Method
    +
    +   The Method  token indicates the method to be performed on the
    +   resource identified by the Request-URI. The method is case-sensitive.
    +
    +       Method         = "OPTIONS"                ; Section 9.2
    +                      | "GET"                    ; Section 9.3
    +                      | "HEAD"                   ; Section 9.4
    +                      | "POST"                   ; Section 9.5
    +                      | "PUT"                    ; Section 9.6
    +                      | "DELETE"                 ; Section 9.7
    +                      | "TRACE"                  ; Section 9.8
    +                      | "CONNECT"                ; Section 9.9
    +                      | extension-method
    +       extension-method = token
    +
    +   The list of methods allowed by a resource can be specified in an
    +   Allow header field (section 14.7). The return code of the response
    +   always notifies the client whether a method is currently allowed on a
    +   resource, since the set of allowed methods can change dynamically. An
    +   origin server SHOULD return the status code 405 (Method Not Allowed)
    +   if the method is known by the origin server but not allowed for the
    +   requested resource, and 501 (Not Implemented) if the method is
    +   unrecognized or not implemented by the origin server. The methods GET
    +   and HEAD MUST be supported by all general-purpose servers. All other
    +   methods are OPTIONAL; however, if the above methods are implemented,
    +   they MUST be implemented with the same semantics as those specified
    +   in section 9.
    +
    +5.1.2 Request-URI
    +
    +   The Request-URI is a Uniform Resource Identifier (section 3.2) and
    +   identifies the resource upon which to apply the request.
    +
    +       Request-URI    = "*" | absoluteURI | abs_path | authority
    +
    +   The four options for Request-URI are dependent on the nature of the
    +   request. The asterisk "*" means that the request does not apply to a
    +   particular resource, but to the server itself, and is only allowed
    +   when the method used does not necessarily apply to a resource. One
    +   example would be
    +
    +       OPTIONS * HTTP/1.1
    +
    +   The absoluteURI form is REQUIRED when the request is being made to a
    +   proxy. The proxy is requested to forward the request or service it
    +   from a valid cache, and return the response. Note that the proxy MAY
    +   forward the request on to another proxy or directly to the server
    +
    +   specified by the absoluteURI. In order to avoid request loops, a
    +   proxy MUST be able to recognize all of its server names, including
    +   any aliases, local variations, and the numeric IP address. An example
    +   Request-Line would be:
    +
    +       GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.1
    +
    +   To allow for transition to absoluteURIs in all requests in future
    +   versions of HTTP, all HTTP/1.1 servers MUST accept the absoluteURI
    +   form in requests, even though HTTP/1.1 clients will only generate
    +   them in requests to proxies.
    +
    +   The authority form is only used by the CONNECT method (section 9.9).
    +
    +   The most common form of Request-URI is that used to identify a
    +   resource on an origin server or gateway. In this case the absolute
    +   path of the URI MUST be transmitted (see section 3.2.1, abs_path) as
    +   the Request-URI, and the network location of the URI (authority) MUST
    +   be transmitted in a Host header field. For example, a client wishing
    +   to retrieve the resource above directly from the origin server would
    +   create a TCP connection to port 80 of the host "www.w3.org" and send
    +   the lines:
    +
    +       GET /pub/WWW/TheProject.html HTTP/1.1
    +       Host: www.w3.org
    +
    +   followed by the remainder of the Request. Note that the absolute path
    +   cannot be empty; if none is present in the original URI, it MUST be
    +   given as "/" (the server root).
    +
    +   The Request-URI is transmitted in the format specified in section
    +   3.2.1. If the Request-URI is encoded using the "% HEX HEX" encoding
    +   [42], the origin server MUST decode the Request-URI in order to
    +   properly interpret the request. Servers SHOULD respond to invalid
    +   Request-URIs with an appropriate status code.
    +
    +   A transparent proxy MUST NOT rewrite the "abs_path" part of the
    +   received Request-URI when forwarding it to the next inbound server,
    +   except as noted above to replace a null abs_path with "/".
    +
    +      Note: The "no rewrite" rule prevents the proxy from changing the
    +      meaning of the request when the origin server is improperly using
    +      a non-reserved URI character for a reserved purpose.  Implementors
    +      should be aware that some pre-HTTP/1.1 proxies have been known to
    +      rewrite the Request-URI.
    +
    +5.2 The Resource Identified by a Request
    +
    +   The exact resource identified by an Internet request is determined by
    +   examining both the Request-URI and the Host header field.
    +
    +   An origin server that does not allow resources to differ by the
    +   requested host MAY ignore the Host header field value when
    +   determining the resource identified by an HTTP/1.1 request. (But see
    +   section 19.6.1.1 for other requirements on Host support in HTTP/1.1.)
    +
    +   An origin server that does differentiate resources based on the host
    +   requested (sometimes referred to as virtual hosts or vanity host
    +   names) MUST use the following rules for determining the requested
    +   resource on an HTTP/1.1 request:
    +
    +   1. If Request-URI is an absoluteURI, the host is part of the
    +     Request-URI. Any Host header field value in the request MUST be
    +     ignored.
    +
    +   2. If the Request-URI is not an absoluteURI, and the request includes
    +     a Host header field, the host is determined by the Host header
    +     field value.
    +
    +   3. If the host as determined by rule 1 or 2 is not a valid host on
    +     the server, the response MUST be a 400 (Bad Request) error message.
    +
    +   Recipients of an HTTP/1.0 request that lacks a Host header field MAY
    +   attempt to use heuristics (e.g., examination of the URI path for
    +   something unique to a particular host) in order to determine what
    +   exact resource is being requested.
    +
    +5.3 Request Header Fields
    +
    +   The request-header fields allow the client to pass additional
    +   information about the request, and about the client itself, to the
    +   server. These fields act as request modifiers, with semantics
    +   equivalent to the parameters on a programming language method
    +   invocation.
    +
    +       request-header = Accept                   ; Section 14.1
    +                      | Accept-Charset           ; Section 14.2
    +                      | Accept-Encoding          ; Section 14.3
    +                      | Accept-Language          ; Section 14.4
    +                      | Authorization            ; Section 14.8
    +                      | Expect                   ; Section 14.20
    +                      | From                     ; Section 14.22
    +                      | Host                     ; Section 14.23
    +                      | If-Match                 ; Section 14.24
    +
    +                      | If-Modified-Since        ; Section 14.25
    +                      | If-None-Match            ; Section 14.26
    +                      | If-Range                 ; Section 14.27
    +                      | If-Unmodified-Since      ; Section 14.28
    +                      | Max-Forwards             ; Section 14.31
    +                      | Proxy-Authorization      ; Section 14.34
    +                      | Range                    ; Section 14.35
    +                      | Referer                  ; Section 14.36
    +                      | TE                       ; Section 14.39
    +                      | User-Agent               ; Section 14.43
    +
    +   Request-header field names can be extended reliably only in
    +   combination with a change in the protocol version. However, new or
    +   experimental header fields MAY be given the semantics of request-
    +   header fields if all parties in the communication recognize them to
    +   be request-header fields. Unrecognized header fields are treated as
    +   entity-header fields.
    +
    +6 Response
    +
    +   After receiving and interpreting a request message, a server responds
    +   with an HTTP response message.
    +
    +       Response      = Status-Line               ; Section 6.1
    +                       *(( general-header        ; Section 4.5
    +                        | response-header        ; Section 6.2
    +                        | entity-header ) CRLF)  ; Section 7.1
    +                       CRLF
    +                       [ message-body ]          ; Section 7.2
    +
    +6.1 Status-Line
    +
    +   The first line of a Response message is the Status-Line, consisting
    +   of the protocol version followed by a numeric status code and its
    +   associated textual phrase, with each element separated by SP
    +   characters. No CR or LF is allowed except in the final CRLF sequence.
    +
    +       Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
    +
    +6.1.1 Status Code and Reason Phrase
    +
    +   The Status-Code element is a 3-digit integer result code of the
    +   attempt to understand and satisfy the request. These codes are fully
    +   defined in section 10. The Reason-Phrase is intended to give a short
    +   textual description of the Status-Code. The Status-Code is intended
    +   for use by automata and the Reason-Phrase is intended for the human
    +   user. The client is not required to examine or display the Reason-
    +   Phrase.
    +
    +   The first digit of the Status-Code defines the class of response. The
    +   last two digits do not have any categorization role. There are 5
    +   values for the first digit:
    +
    +      - 1xx: Informational - Request received, continuing process
    +
    +      - 2xx: Success - The action was successfully received,
    +        understood, and accepted
    +
    +      - 3xx: Redirection - Further action must be taken in order to
    +        complete the request
    +
    +      - 4xx: Client Error - The request contains bad syntax or cannot
    +        be fulfilled
    +
    +      - 5xx: Server Error - The server failed to fulfill an apparently
    +        valid request
    +
    +   The individual values of the numeric status codes defined for
    +   HTTP/1.1, and an example set of corresponding Reason-Phrase's, are
    +   presented below. The reason phrases listed here are only
    +   recommendations -- they MAY be replaced by local equivalents without
    +   affecting the protocol.
    +
    +      Status-Code    =
    +            "100"  ; Section 10.1.1: Continue
    +          | "101"  ; Section 10.1.2: Switching Protocols
    +          | "200"  ; Section 10.2.1: OK
    +          | "201"  ; Section 10.2.2: Created
    +          | "202"  ; Section 10.2.3: Accepted
    +          | "203"  ; Section 10.2.4: Non-Authoritative Information
    +          | "204"  ; Section 10.2.5: No Content
    +          | "205"  ; Section 10.2.6: Reset Content
    +          | "206"  ; Section 10.2.7: Partial Content
    +          | "300"  ; Section 10.3.1: Multiple Choices
    +          | "301"  ; Section 10.3.2: Moved Permanently
    +          | "302"  ; Section 10.3.3: Found
    +          | "303"  ; Section 10.3.4: See Other
    +          | "304"  ; Section 10.3.5: Not Modified
    +          | "305"  ; Section 10.3.6: Use Proxy
    +          | "307"  ; Section 10.3.8: Temporary Redirect
    +          | "400"  ; Section 10.4.1: Bad Request
    +          | "401"  ; Section 10.4.2: Unauthorized
    +          | "402"  ; Section 10.4.3: Payment Required
    +          | "403"  ; Section 10.4.4: Forbidden
    +          | "404"  ; Section 10.4.5: Not Found
    +          | "405"  ; Section 10.4.6: Method Not Allowed
    +          | "406"  ; Section 10.4.7: Not Acceptable
    +
    +          | "407"  ; Section 10.4.8: Proxy Authentication Required
    +          | "408"  ; Section 10.4.9: Request Time-out
    +          | "409"  ; Section 10.4.10: Conflict
    +          | "410"  ; Section 10.4.11: Gone
    +          | "411"  ; Section 10.4.12: Length Required
    +          | "412"  ; Section 10.4.13: Precondition Failed
    +          | "413"  ; Section 10.4.14: Request Entity Too Large
    +          | "414"  ; Section 10.4.15: Request-URI Too Large
    +          | "415"  ; Section 10.4.16: Unsupported Media Type
    +          | "416"  ; Section 10.4.17: Requested range not satisfiable
    +          | "417"  ; Section 10.4.18: Expectation Failed
    +          | "500"  ; Section 10.5.1: Internal Server Error
    +          | "501"  ; Section 10.5.2: Not Implemented
    +          | "502"  ; Section 10.5.3: Bad Gateway
    +          | "503"  ; Section 10.5.4: Service Unavailable
    +          | "504"  ; Section 10.5.5: Gateway Time-out
    +          | "505"  ; Section 10.5.6: HTTP Version not supported
    +          | extension-code
    +
    +      extension-code = 3DIGIT
    +      Reason-Phrase  = *<TEXT, excluding CR, LF>
    +
    +   HTTP status codes are extensible. HTTP applications are not required
    +   to understand the meaning of all registered status codes, though such
    +   understanding is obviously desirable. However, applications MUST
    +   understand the class of any status code, as indicated by the first
    +   digit, and treat any unrecognized response as being equivalent to the
    +   x00 status code of that class, with the exception that an
    +   unrecognized response MUST NOT be cached. For example, if an
    +   unrecognized status code of 431 is received by the client, it can
    +   safely assume that there was something wrong with its request and
    +   treat the response as if it had received a 400 status code. In such
    +   cases, user agents SHOULD present to the user the entity returned
    +   with the response, since that entity is likely to include human-
    +   readable information which will explain the unusual status.
    +
    +6.2 Response Header Fields
    +
    +   The response-header fields allow the server to pass additional
    +   information about the response which cannot be placed in the Status-
    +   Line. These header fields give information about the server and about
    +   further access to the resource identified by the Request-URI.
    +
    +       response-header = Accept-Ranges           ; Section 14.5
    +                       | Age                     ; Section 14.6
    +                       | ETag                    ; Section 14.19
    +                       | Location                ; Section 14.30
    +                       | Proxy-Authenticate      ; Section 14.33
    +
    +                       | Retry-After             ; Section 14.37
    +                       | Server                  ; Section 14.38
    +                       | Vary                    ; Section 14.44
    +                       | WWW-Authenticate        ; Section 14.47
    +
    +   Response-header field names can be extended reliably only in
    +   combination with a change in the protocol version. However, new or
    +   experimental header fields MAY be given the semantics of response-
    +   header fields if all parties in the communication recognize them to
    +   be response-header fields. Unrecognized header fields are treated as
    +   entity-header fields.
    +
    +7 Entity
    +
    +   Request and Response messages MAY transfer an entity if not otherwise
    +   restricted by the request method or response status code. An entity
    +   consists of entity-header fields and an entity-body, although some
    +   responses will only include the entity-headers.
    +
    +   In this section, both sender and recipient refer to either the client
    +   or the server, depending on who sends and who receives the entity.
    +
    +7.1 Entity Header Fields
    +
    +   Entity-header fields define metainformation about the entity-body or,
    +   if no body is present, about the resource identified by the request.
    +   Some of this metainformation is OPTIONAL; some might be REQUIRED by
    +   portions of this specification.
    +
    +       entity-header  = Allow                    ; Section 14.7
    +                      | Content-Encoding         ; Section 14.11
    +                      | Content-Language         ; Section 14.12
    +                      | Content-Length           ; Section 14.13
    +                      | Content-Location         ; Section 14.14
    +                      | Content-MD5              ; Section 14.15
    +                      | Content-Range            ; Section 14.16
    +                      | Content-Type             ; Section 14.17
    +                      | Expires                  ; Section 14.21
    +                      | Last-Modified            ; Section 14.29
    +                      | extension-header
    +
    +       extension-header = message-header
    +
    +   The extension-header mechanism allows additional entity-header fields
    +   to be defined without changing the protocol, but these fields cannot
    +   be assumed to be recognizable by the recipient. Unrecognized header
    +   fields SHOULD be ignored by the recipient and MUST be forwarded by
    +   transparent proxies.
    +
    +7.2 Entity Body
    +
    +   The entity-body (if any) sent with an HTTP request or response is in
    +   a format and encoding defined by the entity-header fields.
    +
    +       entity-body    = *OCTET
    +
    +   An entity-body is only present in a message when a message-body is
    +   present, as described in section 4.3. The entity-body is obtained
    +   from the message-body by decoding any Transfer-Encoding that might
    +   have been applied to ensure safe and proper transfer of the message.
    +
    +7.2.1 Type
    +
    +   When an entity-body is included with a message, the data type of that
    +   body is determined via the header fields Content-Type and Content-
    +   Encoding. These define a two-layer, ordered encoding model:
    +
    +       entity-body := Content-Encoding( Content-Type( data ) )
    +
    +   Content-Type specifies the media type of the underlying data.
    +   Content-Encoding may be used to indicate any additional content
    +   codings applied to the data, usually for the purpose of data
    +   compression, that are a property of the requested resource. There is
    +   no default encoding.
    +
    +   Any HTTP/1.1 message containing an entity-body SHOULD include a
    +   Content-Type header field defining the media type of that body. If
    +   and only if the media type is not given by a Content-Type field, the
    +   recipient MAY attempt to guess the media type via inspection of its
    +   content and/or the name extension(s) of the URI used to identify the
    +   resource. If the media type remains unknown, the recipient SHOULD
    +   treat it as type "application/octet-stream".
    +
    +7.2.2 Entity Length
    +
    +   The entity-length of a message is the length of the message-body
    +   before any transfer-codings have been applied. Section 4.4 defines
    +   how the transfer-length of a message-body is determined.
    +
    +8 Connections
    +
    +8.1 Persistent Connections
    +
    +8.1.1 Purpose
    +
    +   Prior to persistent connections, a separate TCP connection was
    +   established to fetch each URL, increasing the load on HTTP servers
    +   and causing congestion on the Internet. The use of inline images and
    +   other associated data often require a client to make multiple
    +   requests of the same server in a short amount of time. Analysis of
    +   these performance problems and results from a prototype
    +   implementation are available [26] [30]. Implementation experience and
    +   measurements of actual HTTP/1.1 (RFC 2068) implementations show good
    +   results [39]. Alternatives have also been explored, for example,
    +   T/TCP [27].
    +
    +   Persistent HTTP connections have a number of advantages:
    +
    +      - By opening and closing fewer TCP connections, CPU time is saved
    +        in routers and hosts (clients, servers, proxies, gateways,
    +        tunnels, or caches), and memory used for TCP protocol control
    +        blocks can be saved in hosts.
    +
    +      - HTTP requests and responses can be pipelined on a connection.
    +        Pipelining allows a client to make multiple requests without
    +        waiting for each response, allowing a single TCP connection to
    +        be used much more efficiently, with much lower elapsed time.
    +
    +      - Network congestion is reduced by reducing the number of packets
    +        caused by TCP opens, and by allowing TCP sufficient time to
    +        determine the congestion state of the network.
    +
    +      - Latency on subsequent requests is reduced since there is no time
    +        spent in TCP's connection opening handshake.
    +
    +      - HTTP can evolve more gracefully, since errors can be reported
    +        without the penalty of closing the TCP connection. Clients using
    +        future versions of HTTP might optimistically try a new feature,
    +        but if communicating with an older server, retry with old
    +        semantics after an error is reported.
    +
    +   HTTP implementations SHOULD implement persistent connections.
    +
    +8.1.2 Overall Operation
    +
    +   A significant difference between HTTP/1.1 and earlier versions of
    +   HTTP is that persistent connections are the default behavior of any
    +   HTTP connection. That is, unless otherwise indicated, the client
    +   SHOULD assume that the server will maintain a persistent connection,
    +   even after error responses from the server.
    +
    +   Persistent connections provide a mechanism by which a client and a
    +   server can signal the close of a TCP connection. This signaling takes
    +   place using the Connection header field (section 14.10). Once a close
    +   has been signaled, the client MUST NOT send any more requests on that
    +   connection.
    +
    +8.1.2.1 Negotiation
    +
    +   An HTTP/1.1 server MAY assume that a HTTP/1.1 client intends to
    +   maintain a persistent connection unless a Connection header including
    +   the connection-token "close" was sent in the request. If the server
    +   chooses to close the connection immediately after sending the
    +   response, it SHOULD send a Connection header including the
    +   connection-token close.
    +
    +   An HTTP/1.1 client MAY expect a connection to remain open, but would
    +   decide to keep it open based on whether the response from a server
    +   contains a Connection header with the connection-token close. In case
    +   the client does not want to maintain a connection for more than that
    +   request, it SHOULD send a Connection header including the
    +   connection-token close.
    +
    +   If either the client or the server sends the close token in the
    +   Connection header, that request becomes the last one for the
    +   connection.
    +
    +   Clients and servers SHOULD NOT assume that a persistent connection is
    +   maintained for HTTP versions less than 1.1 unless it is explicitly
    +   signaled. See section 19.6.2 for more information on backward
    +   compatibility with HTTP/1.0 clients.
    +
    +   In order to remain persistent, all messages on the connection MUST
    +   have a self-defined message length (i.e., one not defined by closure
    +   of the connection), as described in section 4.4.
    +
    +8.1.2.2 Pipelining
    +
    +   A client that supports persistent connections MAY "pipeline" its
    +   requests (i.e., send multiple requests without waiting for each
    +   response). A server MUST send its responses to those requests in the
    +   same order that the requests were received.
    +
    +   Clients which assume persistent connections and pipeline immediately
    +   after connection establishment SHOULD be prepared to retry their
    +   connection if the first pipelined attempt fails. If a client does
    +   such a retry, it MUST NOT pipeline before it knows the connection is
    +   persistent. Clients MUST also be prepared to resend their requests if
    +   the server closes the connection before sending all of the
    +   corresponding responses.
    +
    +   Clients SHOULD NOT pipeline requests using non-idempotent methods or
    +   non-idempotent sequences of methods (see section 9.1.2). Otherwise, a
    +   premature termination of the transport connection could lead to
    +   indeterminate results. A client wishing to send a non-idempotent
    +   request SHOULD wait to send that request until it has received the
    +   response status for the previous request.
    +
    +8.1.3 Proxy Servers
    +
    +   It is especially important that proxies correctly implement the
    +   properties of the Connection header field as specified in section
    +   14.10.
    +
    +   The proxy server MUST signal persistent connections separately with
    +   its clients and the origin servers (or other proxy servers) that it
    +   connects to. Each persistent connection applies to only one transport
    +   link.
    +
    +   A proxy server MUST NOT establish a HTTP/1.1 persistent connection
    +   with an HTTP/1.0 client (but see RFC 2068 [33] for information and
    +   discussion of the problems with the Keep-Alive header implemented by
    +   many HTTP/1.0 clients).
    +
    +8.1.4 Practical Considerations
    +
    +   Servers will usually have some time-out value beyond which they will
    +   no longer maintain an inactive connection. Proxy servers might make
    +   this a higher value since it is likely that the client will be making
    +   more connections through the same server. The use of persistent
    +   connections places no requirements on the length (or existence) of
    +   this time-out for either the client or the server.
    +
    +   When a client or server wishes to time-out it SHOULD issue a graceful
    +   close on the transport connection. Clients and servers SHOULD both
    +   constantly watch for the other side of the transport close, and
    +   respond to it as appropriate. If a client or server does not detect
    +   the other side's close promptly it could cause unnecessary resource
    +   drain on the network.
    +
    +   A client, server, or proxy MAY close the transport connection at any
    +   time. For example, a client might have started to send a new request
    +   at the same time that the server has decided to close the "idle"
    +   connection. From the server's point of view, the connection is being
    +   closed while it was idle, but from the client's point of view, a
    +   request is in progress.
    +
    +   This means that clients, servers, and proxies MUST be able to recover
    +   from asynchronous close events. Client software SHOULD reopen the
    +   transport connection and retransmit the aborted sequence of requests
    +   without user interaction so long as the request sequence is
    +   idempotent (see section 9.1.2). Non-idempotent methods or sequences
    +   MUST NOT be automatically retried, although user agents MAY offer a
    +   human operator the choice of retrying the request(s). Confirmation by
    +   user-agent software with semantic understanding of the application
    +   MAY substitute for user confirmation. The automatic retry SHOULD NOT
    +   be repeated if the second sequence of requests fails.
    +
    +   Servers SHOULD always respond to at least one request per connection,
    +   if at all possible. Servers SHOULD NOT close a connection in the
    +   middle of transmitting a response, unless a network or client failure
    +   is suspected.
    +
    +   Clients that use persistent connections SHOULD limit the number of
    +   simultaneous connections that they maintain to a given server. A
    +   single-user client SHOULD NOT maintain more than 2 connections with
    +   any server or proxy. A proxy SHOULD use up to 2*N connections to
    +   another server or proxy, where N is the number of simultaneously
    +   active users. These guidelines are intended to improve HTTP response
    +   times and avoid congestion.
    +
    +8.2 Message Transmission Requirements
    +
    +8.2.1 Persistent Connections and Flow Control
    +
    +   HTTP/1.1 servers SHOULD maintain persistent connections and use TCP's
    +   flow control mechanisms to resolve temporary overloads, rather than
    +   terminating connections with the expectation that clients will retry.
    +   The latter technique can exacerbate network congestion.
    +
    +8.2.2 Monitoring Connections for Error Status Messages
    +
    +   An HTTP/1.1 (or later) client sending a message-body SHOULD monitor
    +   the network connection for an error status while it is transmitting
    +   the request. If the client sees an error status, it SHOULD
    +   immediately cease transmitting the body. If the body is being sent
    +   using a "chunked" encoding (section 3.6), a zero length chunk and
    +   empty trailer MAY be used to prematurely mark the end of the message.
    +   If the body was preceded by a Content-Length header, the client MUST
    +   close the connection.
    +
    +8.2.3 Use of the 100 (Continue) Status
    +
    +   The purpose of the 100 (Continue) status (see section 10.1.1) is to
    +   allow a client that is sending a request message with a request body
    +   to determine if the origin server is willing to accept the request
    +   (based on the request headers) before the client sends the request
    +   body. In some cases, it might either be inappropriate or highly
    +   inefficient for the client to send the body if the server will reject
    +   the message without looking at the body.
    +
    +   Requirements for HTTP/1.1 clients:
    +
    +      - If a client will wait for a 100 (Continue) response before
    +        sending the request body, it MUST send an Expect request-header
    +        field (section 14.20) with the "100-continue" expectation.
    +
    +      - A client MUST NOT send an Expect request-header field (section
    +        14.20) with the "100-continue" expectation if it does not intend
    +        to send a request body.
    +
    +   Because of the presence of older implementations, the protocol allows
    +   ambiguous situations in which a client may send "Expect: 100-
    +   continue" without receiving either a 417 (Expectation Failed) status
    +   or a 100 (Continue) status. Therefore, when a client sends this
    +   header field to an origin server (possibly via a proxy) from which it
    +   has never seen a 100 (Continue) status, the client SHOULD NOT wait
    +   for an indefinite period before sending the request body.
    +
    +   Requirements for HTTP/1.1 origin servers:
    +
    +      - Upon receiving a request which includes an Expect request-header
    +        field with the "100-continue" expectation, an origin server MUST
    +        either respond with 100 (Continue) status and continue to read
    +        from the input stream, or respond with a final status code. The
    +        origin server MUST NOT wait for the request body before sending
    +        the 100 (Continue) response. If it responds with a final status
    +        code, it MAY close the transport connection or it MAY continue
    +
    +        to read and discard the rest of the request.  It MUST NOT
    +        perform the requested method if it returns a final status code.
    +
    +      - An origin server SHOULD NOT send a 100 (Continue) response if
    +        the request message does not include an Expect request-header
    +        field with the "100-continue" expectation, and MUST NOT send a
    +        100 (Continue) response if such a request comes from an HTTP/1.0
    +        (or earlier) client. There is an exception to this rule: for
    +        compatibility with RFC 2068, a server MAY send a 100 (Continue)
    +        status in response to an HTTP/1.1 PUT or POST request that does
    +        not include an Expect request-header field with the "100-
    +        continue" expectation. This exception, the purpose of which is
    +        to minimize any client processing delays associated with an
    +        undeclared wait for 100 (Continue) status, applies only to
    +        HTTP/1.1 requests, and not to requests with any other HTTP-
    +        version value.
    +
    +      - An origin server MAY omit a 100 (Continue) response if it has
    +        already received some or all of the request body for the
    +        corresponding request.
    +
    +      - An origin server that sends a 100 (Continue) response MUST
    +        ultimately send a final status code, once the request body is
    +        received and processed, unless it terminates the transport
    +        connection prematurely.
    +
    +      - If an origin server receives a request that does not include an
    +        Expect request-header field with the "100-continue" expectation,
    +        the request includes a request body, and the server responds
    +        with a final status code before reading the entire request body
    +        from the transport connection, then the server SHOULD NOT close
    +        the transport connection until it has read the entire request,
    +        or until the client closes the connection. Otherwise, the client
    +        might not reliably receive the response message. However, this
    +        requirement is not be construed as preventing a server from
    +        defending itself against denial-of-service attacks, or from
    +        badly broken client implementations.
    +
    +   Requirements for HTTP/1.1 proxies:
    +
    +      - If a proxy receives a request that includes an Expect request-
    +        header field with the "100-continue" expectation, and the proxy
    +        either knows that the next-hop server complies with HTTP/1.1 or
    +        higher, or does not know the HTTP version of the next-hop
    +        server, it MUST forward the request, including the Expect header
    +        field.
    +
    +      - If the proxy knows that the version of the next-hop server is
    +        HTTP/1.0 or lower, it MUST NOT forward the request, and it MUST
    +        respond with a 417 (Expectation Failed) status.
    +
    +      - Proxies SHOULD maintain a cache recording the HTTP version
    +        numbers received from recently-referenced next-hop servers.
    +
    +      - A proxy MUST NOT forward a 100 (Continue) response if the
    +        request message was received from an HTTP/1.0 (or earlier)
    +        client and did not include an Expect request-header field with
    +        the "100-continue" expectation. This requirement overrides the
    +        general rule for forwarding of 1xx responses (see section 10.1).
    +
    +8.2.4 Client Behavior if Server Prematurely Closes Connection
    +
    +   If an HTTP/1.1 client sends a request which includes a request body,
    +   but which does not include an Expect request-header field with the
    +   "100-continue" expectation, and if the client is not directly
    +   connected to an HTTP/1.1 origin server, and if the client sees the
    +   connection close before receiving any status from the server, the
    +   client SHOULD retry the request.  If the client does retry this
    +   request, it MAY use the following "binary exponential backoff"
    +   algorithm to be assured of obtaining a reliable response:
    +
    +      1. Initiate a new connection to the server
    +
    +      2. Transmit the request-headers
    +
    +      3. Initialize a variable R to the estimated round-trip time to the
    +         server (e.g., based on the time it took to establish the
    +         connection), or to a constant value of 5 seconds if the round-
    +         trip time is not available.
    +
    +      4. Compute T = R * (2**N), where N is the number of previous
    +         retries of this request.
    +
    +      5. Wait either for an error response from the server, or for T
    +         seconds (whichever comes first)
    +
    +      6. If no error response is received, after T seconds transmit the
    +         body of the request.
    +
    +      7. If client sees that the connection is closed prematurely,
    +         repeat from step 1 until the request is accepted, an error
    +         response is received, or the user becomes impatient and
    +         terminates the retry process.
    +
    +   If at any point an error status is received, the client
    +
    +      - SHOULD NOT continue and
    +
    +      - SHOULD close the connection if it has not completed sending the
    +        request message.
    +
    +9 Method Definitions
    +
    +   The set of common methods for HTTP/1.1 is defined below. Although
    +   this set can be expanded, additional methods cannot be assumed to
    +   share the same semantics for separately extended clients and servers.
    +
    +   The Host request-header field (section 14.23) MUST accompany all
    +   HTTP/1.1 requests.
    +
    +9.1 Safe and Idempotent Methods
    +
    +9.1.1 Safe Methods
    +
    +   Implementors should be aware that the software represents the user in
    +   their interactions over the Internet, and should be careful to allow
    +   the user to be aware of any actions they might take which may have an
    +   unexpected significance to themselves or others.
    +
    +   In particular, the convention has been established that the GET and
    +   HEAD methods SHOULD NOT have the significance of taking an action
    +   other than retrieval. These methods ought to be considered "safe".
    +   This allows user agents to represent other methods, such as POST, PUT
    +   and DELETE, in a special way, so that the user is made aware of the
    +   fact that a possibly unsafe action is being requested.
    +
    +   Naturally, it is not possible to ensure that the server does not
    +   generate side-effects as a result of performing a GET request; in
    +   fact, some dynamic resources consider that a feature. The important
    +   distinction here is that the user did not request the side-effects,
    +   so therefore cannot be held accountable for them.
    +
    +9.1.2 Idempotent Methods
    +
    +   Methods can also have the property of "idempotence" in that (aside
    +   from error or expiration issues) the side-effects of N > 0 identical
    +   requests is the same as for a single request. The methods GET, HEAD,
    +   PUT and DELETE share this property. Also, the methods OPTIONS and
    +   TRACE SHOULD NOT have side effects, and so are inherently idempotent.
    +
    +   However, it is possible that a sequence of several requests is non-
    +   idempotent, even if all of the methods executed in that sequence are
    +   idempotent. (A sequence is idempotent if a single execution of the
    +   entire sequence always yields a result that is not changed by a
    +   reexecution of all, or part, of that sequence.) For example, a
    +   sequence is non-idempotent if its result depends on a value that is
    +   later modified in the same sequence.
    +
    +   A sequence that never has side effects is idempotent, by definition
    +   (provided that no concurrent operations are being executed on the
    +   same set of resources).
    +
    +9.2 OPTIONS
    +
    +   The OPTIONS method represents a request for information about the
    +   communication options available on the request/response chain
    +   identified by the Request-URI. This method allows the client to
    +   determine the options and/or requirements associated with a resource,
    +   or the capabilities of a server, without implying a resource action
    +   or initiating a resource retrieval.
    +
    +   Responses to this method are not cacheable.
    +
    +   If the OPTIONS request includes an entity-body (as indicated by the
    +   presence of Content-Length or Transfer-Encoding), then the media type
    +   MUST be indicated by a Content-Type field. Although this
    +   specification does not define any use for such a body, future
    +   extensions to HTTP might use the OPTIONS body to make more detailed
    +   queries on the server. A server that does not support such an
    +   extension MAY discard the request body.
    +
    +   If the Request-URI is an asterisk ("*"), the OPTIONS request is
    +   intended to apply to the server in general rather than to a specific
    +   resource. Since a server's communication options typically depend on
    +   the resource, the "*" request is only useful as a "ping" or "no-op"
    +   type of method; it does nothing beyond allowing the client to test
    +   the capabilities of the server. For example, this can be used to test
    +   a proxy for HTTP/1.1 compliance (or lack thereof).
    +
    +   If the Request-URI is not an asterisk, the OPTIONS request applies
    +   only to the options that are available when communicating with that
    +   resource.
    +
    +   A 200 response SHOULD include any header fields that indicate
    +   optional features implemented by the server and applicable to that
    +   resource (e.g., Allow), possibly including extensions not defined by
    +   this specification. The response body, if any, SHOULD also include
    +   information about the communication options. The format for such a
    +
    +   body is not defined by this specification, but might be defined by
    +   future extensions to HTTP. Content negotiation MAY be used to select
    +   the appropriate response format. If no response body is included, the
    +   response MUST include a Content-Length field with a field-value of
    +   "0".
    +
    +   The Max-Forwards request-header field MAY be used to target a
    +   specific proxy in the request chain. When a proxy receives an OPTIONS
    +   request on an absoluteURI for which request forwarding is permitted,
    +   the proxy MUST check for a Max-Forwards field. If the Max-Forwards
    +   field-value is zero ("0"), the proxy MUST NOT forward the message;
    +   instead, the proxy SHOULD respond with its own communication options.
    +   If the Max-Forwards field-value is an integer greater than zero, the
    +   proxy MUST decrement the field-value when it forwards the request. If
    +   no Max-Forwards field is present in the request, then the forwarded
    +   request MUST NOT include a Max-Forwards field.
    +
    +9.3 GET
    +
    +   The GET method means retrieve whatever information (in the form of an
    +   entity) is identified by the Request-URI. If the Request-URI refers
    +   to a data-producing process, it is the produced data which shall be
    +   returned as the entity in the response and not the source text of the
    +   process, unless that text happens to be the output of the process.
    +
    +   The semantics of the GET method change to a "conditional GET" if the
    +   request message includes an If-Modified-Since, If-Unmodified-Since,
    +   If-Match, If-None-Match, or If-Range header field. A conditional GET
    +   method requests that the entity be transferred only under the
    +   circumstances described by the conditional header field(s). The
    +   conditional GET method is intended to reduce unnecessary network
    +   usage by allowing cached entities to be refreshed without requiring
    +   multiple requests or transferring data already held by the client.
    +
    +   The semantics of the GET method change to a "partial GET" if the
    +   request message includes a Range header field. A partial GET requests
    +   that only part of the entity be transferred, as described in section
    +   14.35. The partial GET method is intended to reduce unnecessary
    +   network usage by allowing partially-retrieved entities to be
    +   completed without transferring data already held by the client.
    +
    +   The response to a GET request is cacheable if and only if it meets
    +   the requirements for HTTP caching described in section 13.
    +
    +   See section 15.1.3 for security considerations when used for forms.
    +
    +9.4 HEAD
    +
    +   The HEAD method is identical to GET except that the server MUST NOT
    +   return a message-body in the response. The metainformation contained
    +   in the HTTP headers in response to a HEAD request SHOULD be identical
    +   to the information sent in response to a GET request. This method can
    +   be used for obtaining metainformation about the entity implied by the
    +   request without transferring the entity-body itself. This method is
    +   often used for testing hypertext links for validity, accessibility,
    +   and recent modification.
    +
    +   The response to a HEAD request MAY be cacheable in the sense that the
    +   information contained in the response MAY be used to update a
    +   previously cached entity from that resource. If the new field values
    +   indicate that the cached entity differs from the current entity (as
    +   would be indicated by a change in Content-Length, Content-MD5, ETag
    +   or Last-Modified), then the cache MUST treat the cache entry as
    +   stale.
    +
    +9.5 POST
    +
    +   The POST method is used to request that the origin server accept the
    +   entity enclosed in the request as a new subordinate of the resource
    +   identified by the Request-URI in the Request-Line. POST is designed
    +   to allow a uniform method to cover the following functions:
    +
    +      - Annotation of existing resources;
    +
    +      - Posting a message to a bulletin board, newsgroup, mailing list,
    +        or similar group of articles;
    +
    +      - Providing a block of data, such as the result of submitting a
    +        form, to a data-handling process;
    +
    +      - Extending a database through an append operation.
    +
    +   The actual function performed by the POST method is determined by the
    +   server and is usually dependent on the Request-URI. The posted entity
    +   is subordinate to that URI in the same way that a file is subordinate
    +   to a directory containing it, a news article is subordinate to a
    +   newsgroup to which it is posted, or a record is subordinate to a
    +   database.
    +
    +   The action performed by the POST method might not result in a
    +   resource that can be identified by a URI. In this case, either 200
    +   (OK) or 204 (No Content) is the appropriate response status,
    +   depending on whether or not the response includes an entity that
    +   describes the result.
    +
    +   If a resource has been created on the origin server, the response
    +   SHOULD be 201 (Created) and contain an entity which describes the
    +   status of the request and refers to the new resource, and a Location
    +   header (see section 14.30).
    +
    +   Responses to this method are not cacheable, unless the response
    +   includes appropriate Cache-Control or Expires header fields. However,
    +   the 303 (See Other) response can be used to direct the user agent to
    +   retrieve a cacheable resource.
    +
    +   POST requests MUST obey the message transmission requirements set out
    +   in section 8.2.
    +
    +   See section 15.1.3 for security considerations.
    +
    +9.6 PUT
    +
    +   The PUT method requests that the enclosed entity be stored under the
    +   supplied Request-URI. If the Request-URI refers to an already
    +   existing resource, the enclosed entity SHOULD be considered as a
    +   modified version of the one residing on the origin server. If the
    +   Request-URI does not point to an existing resource, and that URI is
    +   capable of being defined as a new resource by the requesting user
    +   agent, the origin server can create the resource with that URI. If a
    +   new resource is created, the origin server MUST inform the user agent
    +   via the 201 (Created) response. If an existing resource is modified,
    +   either the 200 (OK) or 204 (No Content) response codes SHOULD be sent
    +   to indicate successful completion of the request. If the resource
    +   could not be created or modified with the Request-URI, an appropriate
    +   error response SHOULD be given that reflects the nature of the
    +   problem. The recipient of the entity MUST NOT ignore any Content-*
    +   (e.g. Content-Range) headers that it does not understand or implement
    +   and MUST return a 501 (Not Implemented) response in such cases.
    +
    +   If the request passes through a cache and the Request-URI identifies
    +   one or more currently cached entities, those entries SHOULD be
    +   treated as stale. Responses to this method are not cacheable.
    +
    +   The fundamental difference between the POST and PUT requests is
    +   reflected in the different meaning of the Request-URI. The URI in a
    +   POST request identifies the resource that will handle the enclosed
    +   entity. That resource might be a data-accepting process, a gateway to
    +   some other protocol, or a separate entity that accepts annotations.
    +   In contrast, the URI in a PUT request identifies the entity enclosed
    +   with the request -- the user agent knows what URI is intended and the
    +   server MUST NOT attempt to apply the request to some other resource.
    +   If the server desires that the request be applied to a different URI,
    +
    +   it MUST send a 301 (Moved Permanently) response; the user agent MAY
    +   then make its own decision regarding whether or not to redirect the
    +   request.
    +
    +   A single resource MAY be identified by many different URIs. For
    +   example, an article might have a URI for identifying "the current
    +   version" which is separate from the URI identifying each particular
    +   version. In this case, a PUT request on a general URI might result in
    +   several other URIs being defined by the origin server.
    +
    +   HTTP/1.1 does not define how a PUT method affects the state of an
    +   origin server.
    +
    +   PUT requests MUST obey the message transmission requirements set out
    +   in section 8.2.
    +
    +   Unless otherwise specified for a particular entity-header, the
    +   entity-headers in the PUT request SHOULD be applied to the resource
    +   created or modified by the PUT.
    +
    +9.7 DELETE
    +
    +   The DELETE method requests that the origin server delete the resource
    +   identified by the Request-URI. This method MAY be overridden by human
    +   intervention (or other means) on the origin server. The client cannot
    +   be guaranteed that the operation has been carried out, even if the
    +   status code returned from the origin server indicates that the action
    +   has been completed successfully. However, the server SHOULD NOT
    +   indicate success unless, at the time the response is given, it
    +   intends to delete the resource or move it to an inaccessible
    +   location.
    +
    +   A successful response SHOULD be 200 (OK) if the response includes an
    +   entity describing the status, 202 (Accepted) if the action has not
    +   yet been enacted, or 204 (No Content) if the action has been enacted
    +   but the response does not include an entity.
    +
    +   If the request passes through a cache and the Request-URI identifies
    +   one or more currently cached entities, those entries SHOULD be
    +   treated as stale. Responses to this method are not cacheable.
    +
    +9.8 TRACE
    +
    +   The TRACE method is used to invoke a remote, application-layer loop-
    +   back of the request message. The final recipient of the request
    +   SHOULD reflect the message received back to the client as the
    +   entity-body of a 200 (OK) response. The final recipient is either the
    +
    +   origin server or the first proxy or gateway to receive a Max-Forwards
    +   value of zero (0) in the request (see section 14.31). A TRACE request
    +   MUST NOT include an entity.
    +
    +   TRACE allows the client to see what is being received at the other
    +   end of the request chain and use that data for testing or diagnostic
    +   information. The value of the Via header field (section 14.45) is of
    +   particular interest, since it acts as a trace of the request chain.
    +   Use of the Max-Forwards header field allows the client to limit the
    +   length of the request chain, which is useful for testing a chain of
    +   proxies forwarding messages in an infinite loop.
    +
    +   If the request is valid, the response SHOULD contain the entire
    +   request message in the entity-body, with a Content-Type of
    +   "message/http". Responses to this method MUST NOT be cached.
    +
    +9.9 CONNECT
    +
    +   This specification reserves the method name CONNECT for use with a
    +   proxy that can dynamically switch to being a tunnel (e.g. SSL
    +   tunneling [44]).
    +
    +10 Status Code Definitions
    +
    +   Each Status-Code is described below, including a description of which
    +   method(s) it can follow and any metainformation required in the
    +   response.
    +
    +10.1 Informational 1xx
    +
    +   This class of status code indicates a provisional response,
    +   consisting only of the Status-Line and optional headers, and is
    +   terminated by an empty line. There are no required headers for this
    +   class of status code. Since HTTP/1.0 did not define any 1xx status
    +   codes, servers MUST NOT send a 1xx response to an HTTP/1.0 client
    +   except under experimental conditions.
    +
    +   A client MUST be prepared to accept one or more 1xx status responses
    +   prior to a regular response, even if the client does not expect a 100
    +   (Continue) status message. Unexpected 1xx status responses MAY be
    +   ignored by a user agent.
    +
    +   Proxies MUST forward 1xx responses, unless the connection between the
    +   proxy and its client has been closed, or unless the proxy itself
    +   requested the generation of the 1xx response. (For example, if a
    +
    +   proxy adds a "Expect: 100-continue" field when it forwards a request,
    +   then it need not forward the corresponding 100 (Continue)
    +   response(s).)
    +
    +10.1.1 100 Continue
    +
    +   The client SHOULD continue with its request. This interim response is
    +   used to inform the client that the initial part of the request has
    +   been received and has not yet been rejected by the server. The client
    +   SHOULD continue by sending the remainder of the request or, if the
    +   request has already been completed, ignore this response. The server
    +   MUST send a final response after the request has been completed. See
    +   section 8.2.3 for detailed discussion of the use and handling of this
    +   status code.
    +
    +10.1.2 101 Switching Protocols
    +
    +   The server understands and is willing to comply with the client's
    +   request, via the Upgrade message header field (section 14.42), for a
    +   change in the application protocol being used on this connection. The
    +   server will switch protocols to those defined by the response's
    +   Upgrade header field immediately after the empty line which
    +   terminates the 101 response.
    +
    +   The protocol SHOULD be switched only when it is advantageous to do
    +   so. For example, switching to a newer version of HTTP is advantageous
    +   over older versions, and switching to a real-time, synchronous
    +   protocol might be advantageous when delivering resources that use
    +   such features.
    +
    +10.2 Successful 2xx
    +
    +   This class of status code indicates that the client's request was
    +   successfully received, understood, and accepted.
    +
    +10.2.1 200 OK
    +
    +   The request has succeeded. The information returned with the response
    +   is dependent on the method used in the request, for example:
    +
    +   GET    an entity corresponding to the requested resource is sent in
    +          the response;
    +
    +   HEAD   the entity-header fields corresponding to the requested
    +          resource are sent in the response without any message-body;
    +
    +   POST   an entity describing or containing the result of the action;
    +
    +   TRACE  an entity containing the request message as received by the
    +          end server.
    +
    +10.2.2 201 Created
    +
    +   The request has been fulfilled and resulted in a new resource being
    +   created. The newly created resource can be referenced by the URI(s)
    +   returned in the entity of the response, with the most specific URI
    +   for the resource given by a Location header field. The response
    +   SHOULD include an entity containing a list of resource
    +   characteristics and location(s) from which the user or user agent can
    +   choose the one most appropriate. The entity format is specified by
    +   the media type given in the Content-Type header field. The origin
    +   server MUST create the resource before returning the 201 status code.
    +   If the action cannot be carried out immediately, the server SHOULD
    +   respond with 202 (Accepted) response instead.
    +
    +   A 201 response MAY contain an ETag response header field indicating
    +   the current value of the entity tag for the requested variant just
    +   created, see section 14.19.
    +
    +10.2.3 202 Accepted
    +
    +   The request has been accepted for processing, but the processing has
    +   not been completed.  The request might or might not eventually be
    +   acted upon, as it might be disallowed when processing actually takes
    +   place. There is no facility for re-sending a status code from an
    +   asynchronous operation such as this.
    +
    +   The 202 response is intentionally non-committal. Its purpose is to
    +   allow a server to accept a request for some other process (perhaps a
    +   batch-oriented process that is only run once per day) without
    +   requiring that the user agent's connection to the server persist
    +   until the process is completed. The entity returned with this
    +   response SHOULD include an indication of the request's current status
    +   and either a pointer to a status monitor or some estimate of when the
    +   user can expect the request to be fulfilled.
    +
    +10.2.4 203 Non-Authoritative Information
    +
    +   The returned metainformation in the entity-header is not the
    +   definitive set as available from the origin server, but is gathered
    +   from a local or a third-party copy. The set presented MAY be a subset
    +   or superset of the original version. For example, including local
    +   annotation information about the resource might result in a superset
    +   of the metainformation known by the origin server. Use of this
    +   response code is not required and is only appropriate when the
    +   response would otherwise be 200 (OK).
    +
    +10.2.5 204 No Content
    +
    +   The server has fulfilled the request but does not need to return an
    +   entity-body, and might want to return updated metainformation. The
    +   response MAY include new or updated metainformation in the form of
    +   entity-headers, which if present SHOULD be associated with the
    +   requested variant.
    +
    +   If the client is a user agent, it SHOULD NOT change its document view
    +   from that which caused the request to be sent. This response is
    +   primarily intended to allow input for actions to take place without
    +   causing a change to the user agent's active document view, although
    +   any new or updated metainformation SHOULD be applied to the document
    +   currently in the user agent's active view.
    +
    +   The 204 response MUST NOT include a message-body, and thus is always
    +   terminated by the first empty line after the header fields.
    +
    +10.2.6 205 Reset Content
    +
    +   The server has fulfilled the request and the user agent SHOULD reset
    +   the document view which caused the request to be sent. This response
    +   is primarily intended to allow input for actions to take place via
    +   user input, followed by a clearing of the form in which the input is
    +   given so that the user can easily initiate another input action. The
    +   response MUST NOT include an entity.
    +
    +10.2.7 206 Partial Content
    +
    +   The server has fulfilled the partial GET request for the resource.
    +   The request MUST have included a Range header field (section 14.35)
    +   indicating the desired range, and MAY have included an If-Range
    +   header field (section 14.27) to make the request conditional.
    +
    +   The response MUST include the following header fields:
    +
    +      - Either a Content-Range header field (section 14.16) indicating
    +        the range included with this response, or a multipart/byteranges
    +        Content-Type including Content-Range fields for each part. If a
    +        Content-Length header field is present in the response, its
    +        value MUST match the actual number of OCTETs transmitted in the
    +        message-body.
    +
    +      - Date
    +
    +      - ETag and/or Content-Location, if the header would have been sent
    +        in a 200 response to the same request
    +
    +      - Expires, Cache-Control, and/or Vary, if the field-value might
    +        differ from that sent in any previous response for the same
    +        variant
    +
    +   If the 206 response is the result of an If-Range request that used a
    +   strong cache validator (see section 13.3.3), the response SHOULD NOT
    +   include other entity-headers. If the response is the result of an
    +   If-Range request that used a weak validator, the response MUST NOT
    +   include other entity-headers; this prevents inconsistencies between
    +   cached entity-bodies and updated headers. Otherwise, the response
    +   MUST include all of the entity-headers that would have been returned
    +   with a 200 (OK) response to the same request.
    +
    +   A cache MUST NOT combine a 206 response with other previously cached
    +   content if the ETag or Last-Modified headers do not match exactly,
    +   see 13.5.4.
    +
    +   A cache that does not support the Range and Content-Range headers
    +   MUST NOT cache 206 (Partial) responses.
    +
    +10.3 Redirection 3xx
    +
    +   This class of status code indicates that further action needs to be
    +   taken by the user agent in order to fulfill the request.  The action
    +   required MAY be carried out by the user agent without interaction
    +   with the user if and only if the method used in the second request is
    +   GET or HEAD. A client SHOULD detect infinite redirection loops, since
    +   such loops generate network traffic for each redirection.
    +
    +      Note: previous versions of this specification recommended a
    +      maximum of five redirections. Content developers should be aware
    +      that there might be clients that implement such a fixed
    +      limitation.
    +
    +10.3.1 300 Multiple Choices
    +
    +   The requested resource corresponds to any one of a set of
    +   representations, each with its own specific location, and agent-
    +   driven negotiation information (section 12) is being provided so that
    +   the user (or user agent) can select a preferred representation and
    +   redirect its request to that location.
    +
    +   Unless it was a HEAD request, the response SHOULD include an entity
    +   containing a list of resource characteristics and location(s) from
    +   which the user or user agent can choose the one most appropriate. The
    +   entity format is specified by the media type given in the Content-
    +   Type header field. Depending upon the format and the capabilities of
    +
    +   the user agent, selection of the most appropriate choice MAY be
    +   performed automatically. However, this specification does not define
    +   any standard for such automatic selection.
    +
    +   If the server has a preferred choice of representation, it SHOULD
    +   include the specific URI for that representation in the Location
    +   field; user agents MAY use the Location field value for automatic
    +   redirection. This response is cacheable unless indicated otherwise.
    +
    +10.3.2 301 Moved Permanently
    +
    +   The requested resource has been assigned a new permanent URI and any
    +   future references to this resource SHOULD use one of the returned
    +   URIs.  Clients with link editing capabilities ought to automatically
    +   re-link references to the Request-URI to one or more of the new
    +   references returned by the server, where possible. This response is
    +   cacheable unless indicated otherwise.
    +
    +   The new permanent URI SHOULD be given by the Location field in the
    +   response. Unless the request method was HEAD, the entity of the
    +   response SHOULD contain a short hypertext note with a hyperlink to
    +   the new URI(s).
    +
    +   If the 301 status code is received in response to a request other
    +   than GET or HEAD, the user agent MUST NOT automatically redirect the
    +   request unless it can be confirmed by the user, since this might
    +   change the conditions under which the request was issued.
    +
    +      Note: When automatically redirecting a POST request after
    +      receiving a 301 status code, some existing HTTP/1.0 user agents
    +      will erroneously change it into a GET request.
    +
    +10.3.3 302 Found
    +
    +   The requested resource resides temporarily under a different URI.
    +   Since the redirection might be altered on occasion, the client SHOULD
    +   continue to use the Request-URI for future requests.  This response
    +   is only cacheable if indicated by a Cache-Control or Expires header
    +   field.
    +
    +   The temporary URI SHOULD be given by the Location field in the
    +   response. Unless the request method was HEAD, the entity of the
    +   response SHOULD contain a short hypertext note with a hyperlink to
    +   the new URI(s).
    +
    +   If the 302 status code is received in response to a request other
    +   than GET or HEAD, the user agent MUST NOT automatically redirect the
    +   request unless it can be confirmed by the user, since this might
    +   change the conditions under which the request was issued.
    +
    +      Note: RFC 1945 and RFC 2068 specify that the client is not allowed
    +      to change the method on the redirected request.  However, most
    +      existing user agent implementations treat 302 as if it were a 303
    +      response, performing a GET on the Location field-value regardless
    +      of the original request method. The status codes 303 and 307 have
    +      been added for servers that wish to make unambiguously clear which
    +      kind of reaction is expected of the client.
    +
    +10.3.4 303 See Other
    +
    +   The response to the request can be found under a different URI and
    +   SHOULD be retrieved using a GET method on that resource. This method
    +   exists primarily to allow the output of a POST-activated script to
    +   redirect the user agent to a selected resource. The new URI is not a
    +   substitute reference for the originally requested resource. The 303
    +   response MUST NOT be cached, but the response to the second
    +   (redirected) request might be cacheable.
    +
    +   The different URI SHOULD be given by the Location field in the
    +   response. Unless the request method was HEAD, the entity of the
    +   response SHOULD contain a short hypertext note with a hyperlink to
    +   the new URI(s).
    +
    +      Note: Many pre-HTTP/1.1 user agents do not understand the 303
    +      status. When interoperability with such clients is a concern, the
    +      302 status code may be used instead, since most user agents react
    +      to a 302 response as described here for 303.
    +
    +10.3.5 304 Not Modified
    +
    +   If the client has performed a conditional GET request and access is
    +   allowed, but the document has not been modified, the server SHOULD
    +   respond with this status code. The 304 response MUST NOT contain a
    +   message-body, and thus is always terminated by the first empty line
    +   after the header fields.
    +
    +   The response MUST include the following header fields:
    +
    +      - Date, unless its omission is required by section 14.18.1
    +
    +   If a clockless origin server obeys these rules, and proxies and
    +   clients add their own Date to any response received without one (as
    +   already specified by [RFC 2068], section 14.19), caches will operate
    +   correctly.
    +
    +      - ETag and/or Content-Location, if the header would have been sent
    +        in a 200 response to the same request
    +
    +      - Expires, Cache-Control, and/or Vary, if the field-value might
    +        differ from that sent in any previous response for the same
    +        variant
    +
    +   If the conditional GET used a strong cache validator (see section
    +   13.3.3), the response SHOULD NOT include other entity-headers.
    +   Otherwise (i.e., the conditional GET used a weak validator), the
    +   response MUST NOT include other entity-headers; this prevents
    +   inconsistencies between cached entity-bodies and updated headers.
    +
    +   If a 304 response indicates an entity not currently cached, then the
    +   cache MUST disregard the response and repeat the request without the
    +   conditional.
    +
    +   If a cache uses a received 304 response to update a cache entry, the
    +   cache MUST update the entry to reflect any new field values given in
    +   the response.
    +
    +10.3.6 305 Use Proxy
    +
    +   The requested resource MUST be accessed through the proxy given by
    +   the Location field. The Location field gives the URI of the proxy.
    +   The recipient is expected to repeat this single request via the
    +   proxy. 305 responses MUST only be generated by origin servers.
    +
    +      Note: RFC 2068 was not clear that 305 was intended to redirect a
    +      single request, and to be generated by origin servers only.  Not
    +      observing these limitations has significant security consequences.
    +
    +10.3.7 306 (Unused)
    +
    +   The 306 status code was used in a previous version of the
    +   specification, is no longer used, and the code is reserved.
    +
    +10.3.8 307 Temporary Redirect
    +
    +   The requested resource resides temporarily under a different URI.
    +   Since the redirection MAY be altered on occasion, the client SHOULD
    +   continue to use the Request-URI for future requests.  This response
    +   is only cacheable if indicated by a Cache-Control or Expires header
    +   field.
    +
    +   The temporary URI SHOULD be given by the Location field in the
    +   response. Unless the request method was HEAD, the entity of the
    +   response SHOULD contain a short hypertext note with a hyperlink to
    +   the new URI(s) , since many pre-HTTP/1.1 user agents do not
    +   understand the 307 status. Therefore, the note SHOULD contain the
    +   information necessary for a user to repeat the original request on
    +   the new URI.
    +
    +   If the 307 status code is received in response to a request other
    +   than GET or HEAD, the user agent MUST NOT automatically redirect the
    +   request unless it can be confirmed by the user, since this might
    +   change the conditions under which the request was issued.
    +
    +10.4 Client Error 4xx
    +
    +   The 4xx class of status code is intended for cases in which the
    +   client seems to have erred. Except when responding to a HEAD request,
    +   the server SHOULD include an entity containing an explanation of the
    +   error situation, and whether it is a temporary or permanent
    +   condition. These status codes are applicable to any request method.
    +   User agents SHOULD display any included entity to the user.
    +
    +   If the client is sending data, a server implementation using TCP
    +   SHOULD be careful to ensure that the client acknowledges receipt of
    +   the packet(s) containing the response, before the server closes the
    +   input connection. If the client continues sending data to the server
    +   after the close, the server's TCP stack will send a reset packet to
    +   the client, which may erase the client's unacknowledged input buffers
    +   before they can be read and interpreted by the HTTP application.
    +
    +10.4.1 400 Bad Request
    +
    +   The request could not be understood by the server due to malformed
    +   syntax. The client SHOULD NOT repeat the request without
    +   modifications.
    +
    +10.4.2 401 Unauthorized
    +
    +   The request requires user authentication. The response MUST include a
    +   WWW-Authenticate header field (section 14.47) containing a challenge
    +   applicable to the requested resource. The client MAY repeat the
    +   request with a suitable Authorization header field (section 14.8). If
    +   the request already included Authorization credentials, then the 401
    +   response indicates that authorization has been refused for those
    +   credentials. If the 401 response contains the same challenge as the
    +   prior response, and the user agent has already attempted
    +   authentication at least once, then the user SHOULD be presented the
    +   entity that was given in the response, since that entity might
    +   include relevant diagnostic information. HTTP access authentication
    +   is explained in "HTTP Authentication: Basic and Digest Access
    +   Authentication" [43].
    +
    +10.4.3 402 Payment Required
    +
    +   This code is reserved for future use.
    +
    +10.4.4 403 Forbidden
    +
    +   The server understood the request, but is refusing to fulfill it.
    +   Authorization will not help and the request SHOULD NOT be repeated.
    +   If the request method was not HEAD and the server wishes to make
    +   public why the request has not been fulfilled, it SHOULD describe the
    +   reason for the refusal in the entity.  If the server does not wish to
    +   make this information available to the client, the status code 404
    +   (Not Found) can be used instead.
    +
    +10.4.5 404 Not Found
    +
    +   The server has not found anything matching the Request-URI. No
    +   indication is given of whether the condition is temporary or
    +   permanent. The 410 (Gone) status code SHOULD be used if the server
    +   knows, through some internally configurable mechanism, that an old
    +   resource is permanently unavailable and has no forwarding address.
    +   This status code is commonly used when the server does not wish to
    +   reveal exactly why the request has been refused, or when no other
    +   response is applicable.
    +
    +10.4.6 405 Method Not Allowed
    +
    +   The method specified in the Request-Line is not allowed for the
    +   resource identified by the Request-URI. The response MUST include an
    +   Allow header containing a list of valid methods for the requested
    +   resource.
    +
    +10.4.7 406 Not Acceptable
    +
    +   The resource identified by the request is only capable of generating
    +   response entities which have content characteristics not acceptable
    +   according to the accept headers sent in the request.
    +
    +   Unless it was a HEAD request, the response SHOULD include an entity
    +   containing a list of available entity characteristics and location(s)
    +   from which the user or user agent can choose the one most
    +   appropriate. The entity format is specified by the media type given
    +   in the Content-Type header field. Depending upon the format and the
    +   capabilities of the user agent, selection of the most appropriate
    +   choice MAY be performed automatically. However, this specification
    +   does not define any standard for such automatic selection.
    +
    +      Note: HTTP/1.1 servers are allowed to return responses which are
    +      not acceptable according to the accept headers sent in the
    +      request. In some cases, this may even be preferable to sending a
    +      406 response. User agents are encouraged to inspect the headers of
    +      an incoming response to determine if it is acceptable.
    +
    +   If the response could be unacceptable, a user agent SHOULD
    +   temporarily stop receipt of more data and query the user for a
    +   decision on further actions.
    +
    +10.4.8 407 Proxy Authentication Required
    +
    +   This code is similar to 401 (Unauthorized), but indicates that the
    +   client must first authenticate itself with the proxy. The proxy MUST
    +   return a Proxy-Authenticate header field (section 14.33) containing a
    +   challenge applicable to the proxy for the requested resource. The
    +   client MAY repeat the request with a suitable Proxy-Authorization
    +   header field (section 14.34). HTTP access authentication is explained
    +   in "HTTP Authentication: Basic and Digest Access Authentication"
    +   [43].
    +
    +10.4.9 408 Request Timeout
    +
    +   The client did not produce a request within the time that the server
    +   was prepared to wait. The client MAY repeat the request without
    +   modifications at any later time.
    +
    +10.4.10 409 Conflict
    +
    +   The request could not be completed due to a conflict with the current
    +   state of the resource. This code is only allowed in situations where
    +   it is expected that the user might be able to resolve the conflict
    +   and resubmit the request. The response body SHOULD include enough
    +
    +   information for the user to recognize the source of the conflict.
    +   Ideally, the response entity would include enough information for the
    +   user or user agent to fix the problem; however, that might not be
    +   possible and is not required.
    +
    +   Conflicts are most likely to occur in response to a PUT request. For
    +   example, if versioning were being used and the entity being PUT
    +   included changes to a resource which conflict with those made by an
    +   earlier (third-party) request, the server might use the 409 response
    +   to indicate that it can't complete the request. In this case, the
    +   response entity would likely contain a list of the differences
    +   between the two versions in a format defined by the response
    +   Content-Type.
    +
    +10.4.11 410 Gone
    +
    +   The requested resource is no longer available at the server and no
    +   forwarding address is known. This condition is expected to be
    +   considered permanent. Clients with link editing capabilities SHOULD
    +   delete references to the Request-URI after user approval. If the
    +   server does not know, or has no facility to determine, whether or not
    +   the condition is permanent, the status code 404 (Not Found) SHOULD be
    +   used instead. This response is cacheable unless indicated otherwise.
    +
    +   The 410 response is primarily intended to assist the task of web
    +   maintenance by notifying the recipient that the resource is
    +   intentionally unavailable and that the server owners desire that
    +   remote links to that resource be removed. Such an event is common for
    +   limited-time, promotional services and for resources belonging to
    +   individuals no longer working at the server's site. It is not
    +   necessary to mark all permanently unavailable resources as "gone" or
    +   to keep the mark for any length of time -- that is left to the
    +   discretion of the server owner.
    +
    +10.4.12 411 Length Required
    +
    +   The server refuses to accept the request without a defined Content-
    +   Length. The client MAY repeat the request if it adds a valid
    +   Content-Length header field containing the length of the message-body
    +   in the request message.
    +
    +10.4.13 412 Precondition Failed
    +
    +   The precondition given in one or more of the request-header fields
    +   evaluated to false when it was tested on the server. This response
    +   code allows the client to place preconditions on the current resource
    +   metainformation (header field data) and thus prevent the requested
    +   method from being applied to a resource other than the one intended.
    +
    +10.4.14 413 Request Entity Too Large
    +
    +   The server is refusing to process a request because the request
    +   entity is larger than the server is willing or able to process. The
    +   server MAY close the connection to prevent the client from continuing
    +   the request.
    +
    +   If the condition is temporary, the server SHOULD include a Retry-
    +   After header field to indicate that it is temporary and after what
    +   time the client MAY try again.
    +
    +10.4.15 414 Request-URI Too Long
    +
    +   The server is refusing to service the request because the Request-URI
    +   is longer than the server is willing to interpret. This rare
    +   condition is only likely to occur when a client has improperly
    +   converted a POST request to a GET request with long query
    +   information, when the client has descended into a URI "black hole" of
    +   redirection (e.g., a redirected URI prefix that points to a suffix of
    +   itself), or when the server is under attack by a client attempting to
    +   exploit security holes present in some servers using fixed-length
    +   buffers for reading or manipulating the Request-URI.
    +
    +10.4.16 415 Unsupported Media Type
    +
    +   The server is refusing to service the request because the entity of
    +   the request is in a format not supported by the requested resource
    +   for the requested method.
    +
    +10.4.17 416 Requested Range Not Satisfiable
    +
    +   A server SHOULD return a response with this status code if a request
    +   included a Range request-header field (section 14.35), and none of
    +   the range-specifier values in this field overlap the current extent
    +   of the selected resource, and the request did not include an If-Range
    +   request-header field. (For byte-ranges, this means that the first-
    +   byte-pos of all of the byte-range-spec values were greater than the
    +   current length of the selected resource.)
    +
    +   When this status code is returned for a byte-range request, the
    +   response SHOULD include a Content-Range entity-header field
    +   specifying the current length of the selected resource (see section
    +   14.16). This response MUST NOT use the multipart/byteranges content-
    +   type.
    +
    +10.4.18 417 Expectation Failed
    +
    +   The expectation given in an Expect request-header field (see section
    +   14.20) could not be met by this server, or, if the server is a proxy,
    +   the server has unambiguous evidence that the request could not be met
    +   by the next-hop server.
    +
    +10.5 Server Error 5xx
    +
    +   Response status codes beginning with the digit "5" indicate cases in
    +   which the server is aware that it has erred or is incapable of
    +   performing the request. Except when responding to a HEAD request, the
    +   server SHOULD include an entity containing an explanation of the
    +   error situation, and whether it is a temporary or permanent
    +   condition. User agents SHOULD display any included entity to the
    +   user. These response codes are applicable to any request method.
    +
    +10.5.1 500 Internal Server Error
    +
    +   The server encountered an unexpected condition which prevented it
    +   from fulfilling the request.
    +
    +10.5.2 501 Not Implemented
    +
    +   The server does not support the functionality required to fulfill the
    +   request. This is the appropriate response when the server does not
    +   recognize the request method and is not capable of supporting it for
    +   any resource.
    +
    +10.5.3 502 Bad Gateway
    +
    +   The server, while acting as a gateway or proxy, received an invalid
    +   response from the upstream server it accessed in attempting to
    +   fulfill the request.
    +
    +10.5.4 503 Service Unavailable
    +
    +   The server is currently unable to handle the request due to a
    +   temporary overloading or maintenance of the server. The implication
    +   is that this is a temporary condition which will be alleviated after
    +   some delay. If known, the length of the delay MAY be indicated in a
    +   Retry-After header. If no Retry-After is given, the client SHOULD
    +   handle the response as it would for a 500 response.
    +
    +      Note: The existence of the 503 status code does not imply that a
    +      server must use it when becoming overloaded. Some servers may wish
    +      to simply refuse the connection.
    +
    +10.5.5 504 Gateway Timeout
    +
    +   The server, while acting as a gateway or proxy, did not receive a
    +   timely response from the upstream server specified by the URI (e.g.
    +   HTTP, FTP, LDAP) or some other auxiliary server (e.g. DNS) it needed
    +   to access in attempting to complete the request.
    +
    +      Note: Note to implementors: some deployed proxies are known to
    +      return 400 or 500 when DNS lookups time out.
    +
    +10.5.6 505 HTTP Version Not Supported
    +
    +   The server does not support, or refuses to support, the HTTP protocol
    +   version that was used in the request message. The server is
    +   indicating that it is unable or unwilling to complete the request
    +   using the same major version as the client, as described in section
    +   3.1, other than with this error message. The response SHOULD contain
    +   an entity describing why that version is not supported and what other
    +   protocols are supported by that server.
    +
    +11 Access Authentication
    +
    +   HTTP provides several OPTIONAL challenge-response authentication
    +   mechanisms which can be used by a server to challenge a client
    +   request and by a client to provide authentication information. The
    +   general framework for access authentication, and the specification of
    +   "basic" and "digest" authentication, are specified in "HTTP
    +   Authentication: Basic and Digest Access Authentication" [43]. This
    +   specification adopts the definitions of "challenge" and "credentials"
    +   from that specification.
    +
    +12 Content Negotiation
    +
    +   Most HTTP responses include an entity which contains information for
    +   interpretation by a human user. Naturally, it is desirable to supply
    +   the user with the "best available" entity corresponding to the
    +   request. Unfortunately for servers and caches, not all users have the
    +   same preferences for what is "best," and not all user agents are
    +   equally capable of rendering all entity types. For that reason, HTTP
    +   has provisions for several mechanisms for "content negotiation" --
    +   the process of selecting the best representation for a given response
    +   when there are multiple representations available.
    +
    +      Note: This is not called "format negotiation" because the
    +      alternate representations may be of the same media type, but use
    +      different capabilities of that type, be in different languages,
    +      etc.
    +
    +   Any response containing an entity-body MAY be subject to negotiation,
    +   including error responses.
    +
    +   There are two kinds of content negotiation which are possible in
    +   HTTP: server-driven and agent-driven negotiation. These two kinds of
    +   negotiation are orthogonal and thus may be used separately or in
    +   combination. One method of combination, referred to as transparent
    +   negotiation, occurs when a cache uses the agent-driven negotiation
    +   information provided by the origin server in order to provide
    +   server-driven negotiation for subsequent requests.
    +
    +12.1 Server-driven Negotiation
    +
    +   If the selection of the best representation for a response is made by
    +   an algorithm located at the server, it is called server-driven
    +   negotiation. Selection is based on the available representations of
    +   the response (the dimensions over which it can vary; e.g. language,
    +   content-coding, etc.) and the contents of particular header fields in
    +   the request message or on other information pertaining to the request
    +   (such as the network address of the client).
    +
    +   Server-driven negotiation is advantageous when the algorithm for
    +   selecting from among the available representations is difficult to
    +   describe to the user agent, or when the server desires to send its
    +   "best guess" to the client along with the first response (hoping to
    +   avoid the round-trip delay of a subsequent request if the "best
    +   guess" is good enough for the user). In order to improve the server's
    +   guess, the user agent MAY include request header fields (Accept,
    +   Accept-Language, Accept-Encoding, etc.) which describe its
    +   preferences for such a response.
    +
    +   Server-driven negotiation has disadvantages:
    +
    +      1. It is impossible for the server to accurately determine what
    +         might be "best" for any given user, since that would require
    +         complete knowledge of both the capabilities of the user agent
    +         and the intended use for the response (e.g., does the user want
    +         to view it on screen or print it on paper?).
    +
    +      2. Having the user agent describe its capabilities in every
    +         request can be both very inefficient (given that only a small
    +         percentage of responses have multiple representations) and a
    +         potential violation of the user's privacy.
    +
    +      3. It complicates the implementation of an origin server and the
    +         algorithms for generating responses to a request.
    +
    +      4. It may limit a public cache's ability to use the same response
    +         for multiple user's requests.
    +
    +   HTTP/1.1 includes the following request-header fields for enabling
    +   server-driven negotiation through description of user agent
    +   capabilities and user preferences: Accept (section 14.1), Accept-
    +   Charset (section 14.2), Accept-Encoding (section 14.3), Accept-
    +   Language (section 14.4), and User-Agent (section 14.43). However, an
    +   origin server is not limited to these dimensions and MAY vary the
    +   response based on any aspect of the request, including information
    +   outside the request-header fields or within extension header fields
    +   not defined by this specification.
    +
    +   The Vary  header field can be used to express the parameters the
    +   server uses to select a representation that is subject to server-
    +   driven negotiation. See section 13.6 for use of the Vary header field
    +   by caches and section 14.44 for use of the Vary header field by
    +   servers.
    +
    +12.2 Agent-driven Negotiation
    +
    +   With agent-driven negotiation, selection of the best representation
    +   for a response is performed by the user agent after receiving an
    +   initial response from the origin server. Selection is based on a list
    +   of the available representations of the response included within the
    +   header fields or entity-body of the initial response, with each
    +   representation identified by its own URI. Selection from among the
    +   representations may be performed automatically (if the user agent is
    +   capable of doing so) or manually by the user selecting from a
    +   generated (possibly hypertext) menu.
    +
    +   Agent-driven negotiation is advantageous when the response would vary
    +   over commonly-used dimensions (such as type, language, or encoding),
    +   when the origin server is unable to determine a user agent's
    +   capabilities from examining the request, and generally when public
    +   caches are used to distribute server load and reduce network usage.
    +
    +   Agent-driven negotiation suffers from the disadvantage of needing a
    +   second request to obtain the best alternate representation. This
    +   second request is only efficient when caching is used. In addition,
    +   this specification does not define any mechanism for supporting
    +   automatic selection, though it also does not prevent any such
    +   mechanism from being developed as an extension and used within
    +   HTTP/1.1.
    +
    +   HTTP/1.1 defines the 300 (Multiple Choices) and 406 (Not Acceptable)
    +   status codes for enabling agent-driven negotiation when the server is
    +   unwilling or unable to provide a varying response using server-driven
    +   negotiation.
    +
    +12.3 Transparent Negotiation
    +
    +   Transparent negotiation is a combination of both server-driven and
    +   agent-driven negotiation. When a cache is supplied with a form of the
    +   list of available representations of the response (as in agent-driven
    +   negotiation) and the dimensions of variance are completely understood
    +   by the cache, then the cache becomes capable of performing server-
    +   driven negotiation on behalf of the origin server for subsequent
    +   requests on that resource.
    +
    +   Transparent negotiation has the advantage of distributing the
    +   negotiation work that would otherwise be required of the origin
    +   server and also removing the second request delay of agent-driven
    +   negotiation when the cache is able to correctly guess the right
    +   response.
    +
    +   This specification does not define any mechanism for transparent
    +   negotiation, though it also does not prevent any such mechanism from
    +   being developed as an extension that could be used within HTTP/1.1.
    +
    +13 Caching in HTTP
    +
    +   HTTP is typically used for distributed information systems, where
    +   performance can be improved by the use of response caches. The
    +   HTTP/1.1 protocol includes a number of elements intended to make
    +   caching work as well as possible. Because these elements are
    +   inextricable from other aspects of the protocol, and because they
    +   interact with each other, it is useful to describe the basic caching
    +   design of HTTP separately from the detailed descriptions of methods,
    +   headers, response codes, etc.
    +
    +   Caching would be useless if it did not significantly improve
    +   performance. The goal of caching in HTTP/1.1 is to eliminate the need
    +   to send requests in many cases, and to eliminate the need to send
    +   full responses in many other cases. The former reduces the number of
    +   network round-trips required for many operations; we use an
    +   "expiration" mechanism for this purpose (see section 13.2). The
    +   latter reduces network bandwidth requirements; we use a "validation"
    +   mechanism for this purpose (see section 13.3).
    +
    +   Requirements for performance, availability, and disconnected
    +   operation require us to be able to relax the goal of semantic
    +   transparency. The HTTP/1.1 protocol allows origin servers, caches,
    +
    +   and clients to explicitly reduce transparency when necessary.
    +   However, because non-transparent operation may confuse non-expert
    +   users, and might be incompatible with certain server applications
    +   (such as those for ordering merchandise), the protocol requires that
    +   transparency be relaxed
    +
    +      - only by an explicit protocol-level request when relaxed by
    +        client or origin server
    +
    +      - only with an explicit warning to the end user when relaxed by
    +        cache or client
    +
    +   Therefore, the HTTP/1.1 protocol provides these important elements:
    +
    +      1. Protocol features that provide full semantic transparency when
    +         this is required by all parties.
    +
    +      2. Protocol features that allow an origin server or user agent to
    +         explicitly request and control non-transparent operation.
    +
    +      3. Protocol features that allow a cache to attach warnings to
    +         responses that do not preserve the requested approximation of
    +         semantic transparency.
    +
    +   A basic principle is that it must be possible for the clients to
    +   detect any potential relaxation of semantic transparency.
    +
    +      Note: The server, cache, or client implementor might be faced with
    +      design decisions not explicitly discussed in this specification.
    +      If a decision might affect semantic transparency, the implementor
    +      ought to err on the side of maintaining transparency unless a
    +      careful and complete analysis shows significant benefits in
    +      breaking transparency.
    +
    +13.1.1 Cache Correctness
    +
    +   A correct cache MUST respond to a request with the most up-to-date
    +   response held by the cache that is appropriate to the request (see
    +   sections 13.2.5, 13.2.6, and 13.12) which meets one of the following
    +   conditions:
    +
    +      1. It has been checked for equivalence with what the origin server
    +         would have returned by revalidating the response with the
    +         origin server (section 13.3);
    +
    +      2. It is "fresh enough" (see section 13.2). In the default case,
    +         this means it meets the least restrictive freshness requirement
    +         of the client, origin server, and cache (see section 14.9); if
    +         the origin server so specifies, it is the freshness requirement
    +         of the origin server alone.
    +
    +         If a stored response is not "fresh enough" by the most
    +         restrictive freshness requirement of both the client and the
    +         origin server, in carefully considered circumstances the cache
    +         MAY still return the response with the appropriate Warning
    +         header (see section 13.1.5 and 14.46), unless such a response
    +         is prohibited (e.g., by a "no-store" cache-directive, or by a
    +         "no-cache" cache-request-directive; see section 14.9).
    +
    +      3. It is an appropriate 304 (Not Modified), 305 (Proxy Redirect),
    +         or error (4xx or 5xx) response message.
    +
    +   If the cache can not communicate with the origin server, then a
    +   correct cache SHOULD respond as above if the response can be
    +   correctly served from the cache; if not it MUST return an error or
    +   warning indicating that there was a communication failure.
    +
    +   If a cache receives a response (either an entire response, or a 304
    +   (Not Modified) response) that it would normally forward to the
    +   requesting client, and the received response is no longer fresh, the
    +   cache SHOULD forward it to the requesting client without adding a new
    +   Warning (but without removing any existing Warning headers). A cache
    +   SHOULD NOT attempt to revalidate a response simply because that
    +   response became stale in transit; this might lead to an infinite
    +   loop. A user agent that receives a stale response without a Warning
    +   MAY display a warning indication to the user.
    +
    +13.1.2 Warnings
    +
    +   Whenever a cache returns a response that is neither first-hand nor
    +   "fresh enough" (in the sense of condition 2 in section 13.1.1), it
    +   MUST attach a warning to that effect, using a Warning general-header.
    +   The Warning header and the currently defined warnings are described
    +   in section 14.46. The warning allows clients to take appropriate
    +   action.
    +
    +   Warnings MAY be used for other purposes, both cache-related and
    +   otherwise. The use of a warning, rather than an error status code,
    +   distinguish these responses from true failures.
    +
    +   Warnings are assigned three digit warn-codes. The first digit
    +   indicates whether the Warning MUST or MUST NOT be deleted from a
    +   stored cache entry after a successful revalidation:
    +
    +   1xx  Warnings that describe the freshness or revalidation status of
    +     the response, and so MUST be deleted after a successful
    +     revalidation. 1XX warn-codes MAY be generated by a cache only when
    +     validating a cached entry. It MUST NOT be generated by clients.
    +
    +   2xx  Warnings that describe some aspect of the entity body or entity
    +     headers that is not rectified by a revalidation (for example, a
    +     lossy compression of the entity bodies) and which MUST NOT be
    +     deleted after a successful revalidation.
    +
    +   See section 14.46 for the definitions of the codes themselves.
    +
    +   HTTP/1.0 caches will cache all Warnings in responses, without
    +   deleting the ones in the first category. Warnings in responses that
    +   are passed to HTTP/1.0 caches carry an extra warning-date field,
    +   which prevents a future HTTP/1.1 recipient from believing an
    +   erroneously cached Warning.
    +
    +   Warnings also carry a warning text. The text MAY be in any
    +   appropriate natural language (perhaps based on the client's Accept
    +   headers), and include an OPTIONAL indication of what character set is
    +   used.
    +
    +   Multiple warnings MAY be attached to a response (either by the origin
    +   server or by a cache), including multiple warnings with the same code
    +   number. For example, a server might provide the same warning with
    +   texts in both English and Basque.
    +
    +   When multiple warnings are attached to a response, it might not be
    +   practical or reasonable to display all of them to the user. This
    +   version of HTTP does not specify strict priority rules for deciding
    +   which warnings to display and in what order, but does suggest some
    +   heuristics.
    +
    +13.1.3 Cache-control Mechanisms
    +
    +   The basic cache mechanisms in HTTP/1.1 (server-specified expiration
    +   times and validators) are implicit directives to caches. In some
    +   cases, a server or client might need to provide explicit directives
    +   to the HTTP caches. We use the Cache-Control header for this purpose.
    +
    +   The Cache-Control header allows a client or server to transmit a
    +   variety of directives in either requests or responses. These
    +   directives typically override the default caching algorithms. As a
    +   general rule, if there is any apparent conflict between header
    +   values, the most restrictive interpretation is applied (that is, the
    +   one that is most likely to preserve semantic transparency). However,
    +
    +   in some cases, cache-control directives are explicitly specified as
    +   weakening the approximation of semantic transparency (for example,
    +   "max-stale" or "public").
    +
    +   The cache-control directives are described in detail in section 14.9.
    +
    +13.1.4 Explicit User Agent Warnings
    +
    +   Many user agents make it possible for users to override the basic
    +   caching mechanisms. For example, the user agent might allow the user
    +   to specify that cached entities (even explicitly stale ones) are
    +   never validated. Or the user agent might habitually add "Cache-
    +   Control: max-stale=3600" to every request. The user agent SHOULD NOT
    +   default to either non-transparent behavior, or behavior that results
    +   in abnormally ineffective caching, but MAY be explicitly configured
    +   to do so by an explicit action of the user.
    +
    +   If the user has overridden the basic caching mechanisms, the user
    +   agent SHOULD explicitly indicate to the user whenever this results in
    +   the display of information that might not meet the server's
    +   transparency requirements (in particular, if the displayed entity is
    +   known to be stale). Since the protocol normally allows the user agent
    +   to determine if responses are stale or not, this indication need only
    +   be displayed when this actually happens. The indication need not be a
    +   dialog box; it could be an icon (for example, a picture of a rotting
    +   fish) or some other indicator.
    +
    +   If the user has overridden the caching mechanisms in a way that would
    +   abnormally reduce the effectiveness of caches, the user agent SHOULD
    +   continually indicate this state to the user (for example, by a
    +   display of a picture of currency in flames) so that the user does not
    +   inadvertently consume excess resources or suffer from excessive
    +   latency.
    +
    +13.1.5 Exceptions to the Rules and Warnings
    +
    +   In some cases, the operator of a cache MAY choose to configure it to
    +   return stale responses even when not requested by clients. This
    +   decision ought not be made lightly, but may be necessary for reasons
    +   of availability or performance, especially when the cache is poorly
    +   connected to the origin server. Whenever a cache returns a stale
    +   response, it MUST mark it as such (using a Warning header) enabling
    +   the client software to alert the user that there might be a potential
    +   problem.
    +
    +   It also allows the user agent to take steps to obtain a first-hand or
    +   fresh response. For this reason, a cache SHOULD NOT return a stale
    +   response if the client explicitly requests a first-hand or fresh one,
    +   unless it is impossible to comply for technical or policy reasons.
    +
    +13.1.6 Client-controlled Behavior
    +
    +   While the origin server (and to a lesser extent, intermediate caches,
    +   by their contribution to the age of a response) are the primary
    +   source of expiration information, in some cases the client might need
    +   to control a cache's decision about whether to return a cached
    +   response without validating it. Clients do this using several
    +   directives of the Cache-Control header.
    +
    +   A client's request MAY specify the maximum age it is willing to
    +   accept of an unvalidated response; specifying a value of zero forces
    +   the cache(s) to revalidate all responses. A client MAY also specify
    +   the minimum time remaining before a response expires. Both of these
    +   options increase constraints on the behavior of caches, and so cannot
    +   further relax the cache's approximation of semantic transparency.
    +
    +   A client MAY also specify that it will accept stale responses, up to
    +   some maximum amount of staleness. This loosens the constraints on the
    +   caches, and so might violate the origin server's specified
    +   constraints on semantic transparency, but might be necessary to
    +   support disconnected operation, or high availability in the face of
    +   poor connectivity.
    +
    +13.2 Expiration Model
    +
    +13.2.1 Server-Specified Expiration
    +
    +   HTTP caching works best when caches can entirely avoid making
    +   requests to the origin server. The primary mechanism for avoiding
    +   requests is for an origin server to provide an explicit expiration
    +   time in the future, indicating that a response MAY be used to satisfy
    +   subsequent requests. In other words, a cache can return a fresh
    +   response without first contacting the server.
    +
    +   Our expectation is that servers will assign future explicit
    +   expiration times to responses in the belief that the entity is not
    +   likely to change, in a semantically significant way, before the
    +   expiration time is reached. This normally preserves semantic
    +   transparency, as long as the server's expiration times are carefully
    +   chosen.
    +
    +   The expiration mechanism applies only to responses taken from a cache
    +   and not to first-hand responses forwarded immediately to the
    +   requesting client.
    +
    +   If an origin server wishes to force a semantically transparent cache
    +   to validate every request, it MAY assign an explicit expiration time
    +   in the past. This means that the response is always stale, and so the
    +   cache SHOULD validate it before using it for subsequent requests. See
    +   section 14.9.4 for a more restrictive way to force revalidation.
    +
    +   If an origin server wishes to force any HTTP/1.1 cache, no matter how
    +   it is configured, to validate every request, it SHOULD use the "must-
    +   revalidate" cache-control directive (see section 14.9).
    +
    +   Servers specify explicit expiration times using either the Expires
    +   header, or the max-age directive of the Cache-Control header.
    +
    +   An expiration time cannot be used to force a user agent to refresh
    +   its display or reload a resource; its semantics apply only to caching
    +   mechanisms, and such mechanisms need only check a resource's
    +   expiration status when a new request for that resource is initiated.
    +   See section 13.13 for an explanation of the difference between caches
    +   and history mechanisms.
    +
    +13.2.2 Heuristic Expiration
    +
    +   Since origin servers do not always provide explicit expiration times,
    +   HTTP caches typically assign heuristic expiration times, employing
    +   algorithms that use other header values (such as the Last-Modified
    +   time) to estimate a plausible expiration time. The HTTP/1.1
    +   specification does not provide specific algorithms, but does impose
    +   worst-case constraints on their results. Since heuristic expiration
    +   times might compromise semantic transparency, they ought to used
    +   cautiously, and we encourage origin servers to provide explicit
    +   expiration times as much as possible.
    +
    +13.2.3 Age Calculations
    +
    +   In order to know if a cached entry is fresh, a cache needs to know if
    +   its age exceeds its freshness lifetime. We discuss how to calculate
    +   the latter in section 13.2.4; this section describes how to calculate
    +   the age of a response or cache entry.
    +
    +   In this discussion, we use the term "now" to mean "the current value
    +   of the clock at the host performing the calculation." Hosts that use
    +   HTTP, but especially hosts running origin servers and caches, SHOULD
    +   use NTP [28] or some similar protocol to synchronize their clocks to
    +   a globally accurate time standard.
    +
    +   HTTP/1.1 requires origin servers to send a Date header, if possible,
    +   with every response, giving the time at which the response was
    +   generated (see section 14.18). We use the term "date_value" to denote
    +   the value of the Date header, in a form appropriate for arithmetic
    +   operations.
    +
    +   HTTP/1.1 uses the Age response-header to convey the estimated age of
    +   the response message when obtained from a cache. The Age field value
    +   is the cache's estimate of the amount of time since the response was
    +   generated or revalidated by the origin server.
    +
    +   In essence, the Age value is the sum of the time that the response
    +   has been resident in each of the caches along the path from the
    +   origin server, plus the amount of time it has been in transit along
    +   network paths.
    +
    +   We use the term "age_value" to denote the value of the Age header, in
    +   a form appropriate for arithmetic operations.
    +
    +   A response's age can be calculated in two entirely independent ways:
    +
    +      1. now minus date_value, if the local clock is reasonably well
    +         synchronized to the origin server's clock. If the result is
    +         negative, the result is replaced by zero.
    +
    +      2. age_value, if all of the caches along the response path
    +         implement HTTP/1.1.
    +
    +   Given that we have two independent ways to compute the age of a
    +   response when it is received, we can combine these as
    +
    +       corrected_received_age = max(now - date_value, age_value)
    +
    +   and as long as we have either nearly synchronized clocks or all-
    +   HTTP/1.1 paths, one gets a reliable (conservative) result.
    +
    +   Because of network-imposed delays, some significant interval might
    +   pass between the time that a server generates a response and the time
    +   it is received at the next outbound cache or client. If uncorrected,
    +   this delay could result in improperly low ages.
    +
    +   Because the request that resulted in the returned Age value must have
    +   been initiated prior to that Age value's generation, we can correct
    +   for delays imposed by the network by recording the time at which the
    +   request was initiated. Then, when an Age value is received, it MUST
    +   be interpreted relative to the time the request was initiated, not
    +
    +   the time that the response was received. This algorithm results in
    +   conservative behavior no matter how much delay is experienced. So, we
    +   compute:
    +
    +      corrected_initial_age = corrected_received_age
    +                            + (now - request_time)
    +
    +   where "request_time" is the time (according to the local clock) when
    +   the request that elicited this response was sent.
    +
    +   Summary of age calculation algorithm, when a cache receives a
    +   response:
    +
    +      /*
    +       * age_value
    +       *      is the value of Age: header received by the cache with
    +       *              this response.
    +       * date_value
    +       *      is the value of the origin server's Date: header
    +       * request_time
    +       *      is the (local) time when the cache made the request
    +       *              that resulted in this cached response
    +       * response_time
    +       *      is the (local) time when the cache received the
    +       *              response
    +       * now
    +       *      is the current (local) time
    +       */
    +
    +      apparent_age = max(0, response_time - date_value);
    +      corrected_received_age = max(apparent_age, age_value);
    +      response_delay = response_time - request_time;
    +      corrected_initial_age = corrected_received_age + response_delay;
    +      resident_time = now - response_time;
    +      current_age   = corrected_initial_age + resident_time;
    +
    +   The current_age of a cache entry is calculated by adding the amount
    +   of time (in seconds) since the cache entry was last validated by the
    +   origin server to the corrected_initial_age. When a response is
    +   generated from a cache entry, the cache MUST include a single Age
    +   header field in the response with a value equal to the cache entry's
    +   current_age.
    +
    +   The presence of an Age header field in a response implies that a
    +   response is not first-hand. However, the converse is not true, since
    +   the lack of an Age header field in a response does not imply that the
    +
    +   response is first-hand unless all caches along the request path are
    +   compliant with HTTP/1.1 (i.e., older HTTP caches did not implement
    +   the Age header field).
    +
    +13.2.4 Expiration Calculations
    +
    +   In order to decide whether a response is fresh or stale, we need to
    +   compare its freshness lifetime to its age. The age is calculated as
    +   described in section 13.2.3; this section describes how to calculate
    +   the freshness lifetime, and to determine if a response has expired.
    +   In the discussion below, the values can be represented in any form
    +   appropriate for arithmetic operations.
    +
    +   We use the term "expires_value" to denote the value of the Expires
    +   header. We use the term "max_age_value" to denote an appropriate
    +   value of the number of seconds carried by the "max-age" directive of
    +   the Cache-Control header in a response (see section 14.9.3).
    +
    +   The max-age directive takes priority over Expires, so if max-age is
    +   present in a response, the calculation is simply:
    +
    +      freshness_lifetime = max_age_value
    +
    +   Otherwise, if Expires is present in the response, the calculation is:
    +
    +      freshness_lifetime = expires_value - date_value
    +
    +   Note that neither of these calculations is vulnerable to clock skew,
    +   since all of the information comes from the origin server.
    +
    +   If none of Expires, Cache-Control: max-age, or Cache-Control: s-
    +   maxage (see section 14.9.3) appears in the response, and the response
    +   does not include other restrictions on caching, the cache MAY compute
    +   a freshness lifetime using a heuristic. The cache MUST attach Warning
    +   113 to any response whose age is more than 24 hours if such warning
    +   has not already been added.
    +
    +   Also, if the response does have a Last-Modified time, the heuristic
    +   expiration value SHOULD be no more than some fraction of the interval
    +   since that time. A typical setting of this fraction might be 10%.
    +
    +   The calculation to determine if a response has expired is quite
    +   simple:
    +
    +      response_is_fresh = (freshness_lifetime > current_age)
    +
    +13.2.5 Disambiguating Expiration Values
    +
    +   Because expiration values are assigned optimistically, it is possible
    +   for two caches to contain fresh values for the same resource that are
    +   different.
    +
    +   If a client performing a retrieval receives a non-first-hand response
    +   for a request that was already fresh in its own cache, and the Date
    +   header in its existing cache entry is newer than the Date on the new
    +   response, then the client MAY ignore the response. If so, it MAY
    +   retry the request with a "Cache-Control: max-age=0" directive (see
    +   section 14.9), to force a check with the origin server.
    +
    +   If a cache has two fresh responses for the same representation with
    +   different validators, it MUST use the one with the more recent Date
    +   header. This situation might arise because the cache is pooling
    +   responses from other caches, or because a client has asked for a
    +   reload or a revalidation of an apparently fresh cache entry.
    +
    +13.2.6 Disambiguating Multiple Responses
    +
    +   Because a client might be receiving responses via multiple paths, so
    +   that some responses flow through one set of caches and other
    +   responses flow through a different set of caches, a client might
    +   receive responses in an order different from that in which the origin
    +   server sent them. We would like the client to use the most recently
    +   generated response, even if older responses are still apparently
    +   fresh.
    +
    +   Neither the entity tag nor the expiration value can impose an
    +   ordering on responses, since it is possible that a later response
    +   intentionally carries an earlier expiration time. The Date values are
    +   ordered to a granularity of one second.
    +
    +   When a client tries to revalidate a cache entry, and the response it
    +   receives contains a Date header that appears to be older than the one
    +   for the existing entry, then the client SHOULD repeat the request
    +   unconditionally, and include
    +
    +       Cache-Control: max-age=0
    +
    +   to force any intermediate caches to validate their copies directly
    +   with the origin server, or
    +
    +       Cache-Control: no-cache
    +
    +   to force any intermediate caches to obtain a new copy from the origin
    +   server.
    +
    +   If the Date values are equal, then the client MAY use either response
    +   (or MAY, if it is being extremely prudent, request a new response).
    +   Servers MUST NOT depend on clients being able to choose
    +   deterministically between responses generated during the same second,
    +   if their expiration times overlap.
    +
    +13.3 Validation Model
    +
    +   When a cache has a stale entry that it would like to use as a
    +   response to a client's request, it first has to check with the origin
    +   server (or possibly an intermediate cache with a fresh response) to
    +   see if its cached entry is still usable. We call this "validating"
    +   the cache entry. Since we do not want to have to pay the overhead of
    +   retransmitting the full response if the cached entry is good, and we
    +   do not want to pay the overhead of an extra round trip if the cached
    +   entry is invalid, the HTTP/1.1 protocol supports the use of
    +   conditional methods.
    +
    +   The key protocol features for supporting conditional methods are
    +   those concerned with "cache validators." When an origin server
    +   generates a full response, it attaches some sort of validator to it,
    +   which is kept with the cache entry. When a client (user agent or
    +   proxy cache) makes a conditional request for a resource for which it
    +   has a cache entry, it includes the associated validator in the
    +   request.
    +
    +   The server then checks that validator against the current validator
    +   for the entity, and, if they match (see section 13.3.3), it responds
    +   with a special status code (usually, 304 (Not Modified)) and no
    +   entity-body. Otherwise, it returns a full response (including
    +   entity-body). Thus, we avoid transmitting the full response if the
    +   validator matches, and we avoid an extra round trip if it does not
    +   match.
    +
    +   In HTTP/1.1, a conditional request looks exactly the same as a normal
    +   request for the same resource, except that it carries a special
    +   header (which includes the validator) that implicitly turns the
    +   method (usually, GET) into a conditional.
    +
    +   The protocol includes both positive and negative senses of cache-
    +   validating conditions. That is, it is possible to request either that
    +   a method be performed if and only if a validator matches or if and
    +   only if no validators match.
    +
    +      Note: a response that lacks a validator may still be cached, and
    +      served from cache until it expires, unless this is explicitly
    +      prohibited by a cache-control directive. However, a cache cannot
    +      do a conditional retrieval if it does not have a validator for the
    +      entity, which means it will not be refreshable after it expires.
    +
    +13.3.1 Last-Modified Dates
    +
    +   The Last-Modified entity-header field value is often used as a cache
    +   validator. In simple terms, a cache entry is considered to be valid
    +   if the entity has not been modified since the Last-Modified value.
    +
    +13.3.2 Entity Tag Cache Validators
    +
    +   The ETag response-header field value, an entity tag, provides for an
    +   "opaque" cache validator. This might allow more reliable validation
    +   in situations where it is inconvenient to store modification dates,
    +   where the one-second resolution of HTTP date values is not
    +   sufficient, or where the origin server wishes to avoid certain
    +   paradoxes that might arise from the use of modification dates.
    +
    +   Entity Tags are described in section 3.11. The headers used with
    +   entity tags are described in sections 14.19, 14.24, 14.26 and 14.44.
    +
    +13.3.3 Weak and Strong Validators
    +
    +   Since both origin servers and caches will compare two validators to
    +   decide if they represent the same or different entities, one normally
    +   would expect that if the entity (the entity-body or any entity-
    +   headers) changes in any way, then the associated validator would
    +   change as well. If this is true, then we call this validator a
    +   "strong validator."
    +
    +   However, there might be cases when a server prefers to change the
    +   validator only on semantically significant changes, and not when
    +   insignificant aspects of the entity change. A validator that does not
    +   always change when the resource changes is a "weak validator."
    +
    +   Entity tags are normally "strong validators," but the protocol
    +   provides a mechanism to tag an entity tag as "weak." One can think of
    +   a strong validator as one that changes whenever the bits of an entity
    +   changes, while a weak value changes whenever the meaning of an entity
    +   changes. Alternatively, one can think of a strong validator as part
    +   of an identifier for a specific entity, while a weak validator is
    +   part of an identifier for a set of semantically equivalent entities.
    +
    +      Note: One example of a strong validator is an integer that is
    +      incremented in stable storage every time an entity is changed.
    +
    +      An entity's modification time, if represented with one-second
    +      resolution, could be a weak validator, since it is possible that
    +      the resource might be modified twice during a single second.
    +
    +      Support for weak validators is optional. However, weak validators
    +      allow for more efficient caching of equivalent objects; for
    +      example, a hit counter on a site is probably good enough if it is
    +      updated every few days or weeks, and any value during that period
    +      is likely "good enough" to be equivalent.
    +
    +   A "use" of a validator is either when a client generates a request
    +   and includes the validator in a validating header field, or when a
    +   server compares two validators.
    +
    +   Strong validators are usable in any context. Weak validators are only
    +   usable in contexts that do not depend on exact equality of an entity.
    +   For example, either kind is usable for a conditional GET of a full
    +   entity. However, only a strong validator is usable for a sub-range
    +   retrieval, since otherwise the client might end up with an internally
    +   inconsistent entity.
    +
    +   Clients MAY issue simple (non-subrange) GET requests with either weak
    +   validators or strong validators. Clients MUST NOT use weak validators
    +   in other forms of request.
    +
    +   The only function that the HTTP/1.1 protocol defines on validators is
    +   comparison. There are two validator comparison functions, depending
    +   on whether the comparison context allows the use of weak validators
    +   or not:
    +
    +      - The strong comparison function: in order to be considered equal,
    +        both validators MUST be identical in every way, and both MUST
    +        NOT be weak.
    +
    +      - The weak comparison function: in order to be considered equal,
    +        both validators MUST be identical in every way, but either or
    +        both of them MAY be tagged as "weak" without affecting the
    +        result.
    +
    +   An entity tag is strong unless it is explicitly tagged as weak.
    +   Section 3.11 gives the syntax for entity tags.
    +
    +   A Last-Modified time, when used as a validator in a request, is
    +   implicitly weak unless it is possible to deduce that it is strong,
    +   using the following rules:
    +
    +      - The validator is being compared by an origin server to the
    +        actual current validator for the entity and,
    +
    +      - That origin server reliably knows that the associated entity did
    +        not change twice during the second covered by the presented
    +        validator.
    +
    +   or
    +
    +      - The validator is about to be used by a client in an If-
    +        Modified-Since or If-Unmodified-Since header, because the client
    +        has a cache entry for the associated entity, and
    +
    +      - That cache entry includes a Date value, which gives the time
    +        when the origin server sent the original response, and
    +
    +      - The presented Last-Modified time is at least 60 seconds before
    +        the Date value.
    +
    +   or
    +
    +      - The validator is being compared by an intermediate cache to the
    +        validator stored in its cache entry for the entity, and
    +
    +      - That cache entry includes a Date value, which gives the time
    +        when the origin server sent the original response, and
    +
    +      - The presented Last-Modified time is at least 60 seconds before
    +        the Date value.
    +
    +   This method relies on the fact that if two different responses were
    +   sent by the origin server during the same second, but both had the
    +   same Last-Modified time, then at least one of those responses would
    +   have a Date value equal to its Last-Modified time. The arbitrary 60-
    +   second limit guards against the possibility that the Date and Last-
    +   Modified values are generated from different clocks, or at somewhat
    +   different times during the preparation of the response. An
    +   implementation MAY use a value larger than 60 seconds, if it is
    +   believed that 60 seconds is too short.
    +
    +   If a client wishes to perform a sub-range retrieval on a value for
    +   which it has only a Last-Modified time and no opaque validator, it
    +   MAY do this only if the Last-Modified time is strong in the sense
    +   described here.
    +
    +   A cache or origin server receiving a conditional request, other than
    +   a full-body GET request, MUST use the strong comparison function to
    +   evaluate the condition.
    +
    +   These rules allow HTTP/1.1 caches and clients to safely perform sub-
    +   range retrievals on values that have been obtained from HTTP/1.0
    +
    +   servers.
    +
    +13.3.4 Rules for When to Use Entity Tags and Last-Modified Dates
    +
    +   We adopt a set of rules and recommendations for origin servers,
    +   clients, and caches regarding when various validator types ought to
    +   be used, and for what purposes.
    +
    +   HTTP/1.1 origin servers:
    +
    +      - SHOULD send an entity tag validator unless it is not feasible to
    +        generate one.
    +
    +      - MAY send a weak entity tag instead of a strong entity tag, if
    +        performance considerations support the use of weak entity tags,
    +        or if it is unfeasible to send a strong entity tag.
    +
    +      - SHOULD send a Last-Modified value if it is feasible to send one,
    +        unless the risk of a breakdown in semantic transparency that
    +        could result from using this date in an If-Modified-Since header
    +        would lead to serious problems.
    +
    +   In other words, the preferred behavior for an HTTP/1.1 origin server
    +   is to send both a strong entity tag and a Last-Modified value.
    +
    +   In order to be legal, a strong entity tag MUST change whenever the
    +   associated entity value changes in any way. A weak entity tag SHOULD
    +   change whenever the associated entity changes in a semantically
    +   significant way.
    +
    +      Note: in order to provide semantically transparent caching, an
    +      origin server must avoid reusing a specific strong entity tag
    +      value for two different entities, or reusing a specific weak
    +      entity tag value for two semantically different entities. Cache
    +      entries might persist for arbitrarily long periods, regardless of
    +      expiration times, so it might be inappropriate to expect that a
    +      cache will never again attempt to validate an entry using a
    +      validator that it obtained at some point in the past.
    +
    +   HTTP/1.1 clients:
    +
    +      - If an entity tag has been provided by the origin server, MUST
    +        use that entity tag in any cache-conditional request (using If-
    +        Match or If-None-Match).
    +
    +      - If only a Last-Modified value has been provided by the origin
    +        server, SHOULD use that value in non-subrange cache-conditional
    +        requests (using If-Modified-Since).
    +
    +      - If only a Last-Modified value has been provided by an HTTP/1.0
    +        origin server, MAY use that value in subrange cache-conditional
    +        requests (using If-Unmodified-Since:). The user agent SHOULD
    +        provide a way to disable this, in case of difficulty.
    +
    +      - If both an entity tag and a Last-Modified value have been
    +        provided by the origin server, SHOULD use both validators in
    +        cache-conditional requests. This allows both HTTP/1.0 and
    +        HTTP/1.1 caches to respond appropriately.
    +
    +   An HTTP/1.1 origin server, upon receiving a conditional request that
    +   includes both a Last-Modified date (e.g., in an If-Modified-Since or
    +   If-Unmodified-Since header field) and one or more entity tags (e.g.,
    +   in an If-Match, If-None-Match, or If-Range header field) as cache
    +   validators, MUST NOT return a response status of 304 (Not Modified)
    +   unless doing so is consistent with all of the conditional header
    +   fields in the request.
    +
    +   An HTTP/1.1 caching proxy, upon receiving a conditional request that
    +   includes both a Last-Modified date and one or more entity tags as
    +   cache validators, MUST NOT return a locally cached response to the
    +   client unless that cached response is consistent with all of the
    +   conditional header fields in the request.
    +
    +      Note: The general principle behind these rules is that HTTP/1.1
    +      servers and clients should transmit as much non-redundant
    +      information as is available in their responses and requests.
    +      HTTP/1.1 systems receiving this information will make the most
    +      conservative assumptions about the validators they receive.
    +
    +      HTTP/1.0 clients and caches will ignore entity tags. Generally,
    +      last-modified values received or used by these systems will
    +      support transparent and efficient caching, and so HTTP/1.1 origin
    +      servers should provide Last-Modified values. In those rare cases
    +      where the use of a Last-Modified value as a validator by an
    +      HTTP/1.0 system could result in a serious problem, then HTTP/1.1
    +      origin servers should not provide one.
    +
    +13.3.5 Non-validating Conditionals
    +
    +   The principle behind entity tags is that only the service author
    +   knows the semantics of a resource well enough to select an
    +   appropriate cache validation mechanism, and the specification of any
    +   validator comparison function more complex than byte-equality would
    +   open up a can of worms. Thus, comparisons of any other headers
    +   (except Last-Modified, for compatibility with HTTP/1.0) are never
    +   used for purposes of validating a cache entry.
    +
    +13.4 Response Cacheability
    +
    +   Unless specifically constrained by a cache-control (section 14.9)
    +   directive, a caching system MAY always store a successful response
    +   (see section 13.8) as a cache entry, MAY return it without validation
    +   if it is fresh, and MAY return it after successful validation. If
    +   there is neither a cache validator nor an explicit expiration time
    +   associated with a response, we do not expect it to be cached, but
    +   certain caches MAY violate this expectation (for example, when little
    +   or no network connectivity is available). A client can usually detect
    +   that such a response was taken from a cache by comparing the Date
    +   header to the current time.
    +
    +      Note: some HTTP/1.0 caches are known to violate this expectation
    +      without providing any Warning.
    +
    +   However, in some cases it might be inappropriate for a cache to
    +   retain an entity, or to return it in response to a subsequent
    +   request. This might be because absolute semantic transparency is
    +   deemed necessary by the service author, or because of security or
    +   privacy considerations. Certain cache-control directives are
    +   therefore provided so that the server can indicate that certain
    +   resource entities, or portions thereof, are not to be cached
    +   regardless of other considerations.
    +
    +   Note that section 14.8 normally prevents a shared cache from saving
    +   and returning a response to a previous request if that request
    +   included an Authorization header.
    +
    +   A response received with a status code of 200, 203, 206, 300, 301 or
    +   410 MAY be stored by a cache and used in reply to a subsequent
    +   request, subject to the expiration mechanism, unless a cache-control
    +   directive prohibits caching. However, a cache that does not support
    +   the Range and Content-Range headers MUST NOT cache 206 (Partial
    +   Content) responses.
    +
    +   A response received with any other status code (e.g. status codes 302
    +   and 307) MUST NOT be returned in a reply to a subsequent request
    +   unless there are cache-control directives or another header(s) that
    +   explicitly allow it. For example, these include the following: an
    +   Expires header (section 14.21); a "max-age", "s-maxage",  "must-
    +   revalidate", "proxy-revalidate", "public" or "private" cache-control
    +   directive (section 14.9).
    +
    +13.5 Constructing Responses From Caches
    +
    +   The purpose of an HTTP cache is to store information received in
    +   response to requests for use in responding to future requests. In
    +   many cases, a cache simply returns the appropriate parts of a
    +   response to the requester. However, if the cache holds a cache entry
    +   based on a previous response, it might have to combine parts of a new
    +   response with what is held in the cache entry.
    +
    +13.5.1 End-to-end and Hop-by-hop Headers
    +
    +   For the purpose of defining the behavior of caches and non-caching
    +   proxies, we divide HTTP headers into two categories:
    +
    +      - End-to-end headers, which are  transmitted to the ultimate
    +        recipient of a request or response. End-to-end headers in
    +        responses MUST be stored as part of a cache entry and MUST be
    +        transmitted in any response formed from a cache entry.
    +
    +      - Hop-by-hop headers, which are meaningful only for a single
    +        transport-level connection, and are not stored by caches or
    +        forwarded by proxies.
    +
    +   The following HTTP/1.1 headers are hop-by-hop headers:
    +
    +      - Connection
    +      - Keep-Alive
    +      - Proxy-Authenticate
    +      - Proxy-Authorization
    +      - TE
    +      - Trailers
    +      - Transfer-Encoding
    +      - Upgrade
    +
    +   All other headers defined by HTTP/1.1 are end-to-end headers.
    +
    +   Other hop-by-hop headers MUST be listed in a Connection header,
    +   (section 14.10) to be introduced into HTTP/1.1 (or later).
    +
    +13.5.2 Non-modifiable Headers
    +
    +   Some features of the HTTP/1.1 protocol, such as Digest
    +   Authentication, depend on the value of certain end-to-end headers. A
    +   transparent proxy SHOULD NOT modify an end-to-end header unless the
    +   definition of that header requires or specifically allows that.
    +
    +   A transparent proxy MUST NOT modify any of the following fields in a
    +   request or response, and it MUST NOT add any of these fields if not
    +   already present:
    +
    +      - Content-Location
    +
    +      - Content-MD5
    +
    +      - ETag
    +
    +      - Last-Modified
    +
    +   A transparent proxy MUST NOT modify any of the following fields in a
    +   response:
    +
    +      - Expires
    +
    +   but it MAY add any of these fields if not already present. If an
    +   Expires header is added, it MUST be given a field-value identical to
    +   that of the Date header in that response.
    +
    +   A  proxy MUST NOT modify or add any of the following fields in a
    +   message that contains the no-transform cache-control directive, or in
    +   any request:
    +
    +      - Content-Encoding
    +
    +      - Content-Range
    +
    +      - Content-Type
    +
    +   A non-transparent proxy MAY modify or add these fields to a message
    +   that does not include no-transform, but if it does so, it MUST add a
    +   Warning 214 (Transformation applied) if one does not already appear
    +   in the message (see section 14.46).
    +
    +      Warning: unnecessary modification of end-to-end headers might
    +      cause authentication failures if stronger authentication
    +      mechanisms are introduced in later versions of HTTP. Such
    +      authentication mechanisms MAY rely on the values of header fields
    +      not listed here.
    +
    +   The Content-Length field of a request or response is added or deleted
    +   according to the rules in section 4.4. A transparent proxy MUST
    +   preserve the entity-length (section 7.2.2) of the entity-body,
    +   although it MAY change the transfer-length (section 4.4).
    +
    +13.5.3 Combining Headers
    +
    +   When a cache makes a validating request to a server, and the server
    +   provides a 304 (Not Modified) response or a 206 (Partial Content)
    +   response, the cache then constructs a response to send to the
    +   requesting client.
    +
    +   If the status code is 304 (Not Modified), the cache uses the entity-
    +   body stored in the cache entry as the entity-body of this outgoing
    +   response. If the status code is 206 (Partial Content) and the ETag or
    +   Last-Modified headers match exactly, the cache MAY combine the
    +   contents stored in the cache entry with the new contents received in
    +   the response and use the result as the entity-body of this outgoing
    +   response, (see 13.5.4).
    +
    +   The end-to-end headers stored in the cache entry are used for the
    +   constructed response, except that
    +
    +      - any stored Warning headers with warn-code 1xx (see section
    +        14.46) MUST be deleted from the cache entry and the forwarded
    +        response.
    +
    +      - any stored Warning headers with warn-code 2xx MUST be retained
    +        in the cache entry and the forwarded response.
    +
    +      - any end-to-end headers provided in the 304 or 206 response MUST
    +        replace the corresponding headers from the cache entry.
    +
    +   Unless the cache decides to remove the cache entry, it MUST also
    +   replace the end-to-end headers stored with the cache entry with
    +   corresponding headers received in the incoming response, except for
    +   Warning headers as described immediately above. If a header field-
    +   name in the incoming response matches more than one header in the
    +   cache entry, all such old headers MUST be replaced.
    +
    +   In other words, the set of end-to-end headers received in the
    +   incoming response overrides all corresponding end-to-end headers
    +   stored with the cache entry (except for stored Warning headers with
    +   warn-code 1xx, which are deleted even if not overridden).
    +
    +      Note: this rule allows an origin server to use a 304 (Not
    +      Modified) or a 206 (Partial Content) response to update any header
    +      associated with a previous response for the same entity or sub-
    +      ranges thereof, although it might not always be meaningful or
    +      correct to do so. This rule does not allow an origin server to use
    +      a 304 (Not Modified) or a 206 (Partial Content) response to
    +      entirely delete a header that it had provided with a previous
    +      response.
    +
    +13.5.4 Combining Byte Ranges
    +
    +   A response might transfer only a subrange of the bytes of an entity-
    +   body, either because the request included one or more Range
    +   specifications, or because a connection was broken prematurely. After
    +   several such transfers, a cache might have received several ranges of
    +   the same entity-body.
    +
    +   If a cache has a stored non-empty set of subranges for an entity, and
    +   an incoming response transfers another subrange, the cache MAY
    +   combine the new subrange with the existing set if both the following
    +   conditions are met:
    +
    +      - Both the incoming response and the cache entry have a cache
    +        validator.
    +
    +      - The two cache validators match using the strong comparison
    +        function (see section 13.3.3).
    +
    +   If either requirement is not met, the cache MUST use only the most
    +   recent partial response (based on the Date values transmitted with
    +   every response, and using the incoming response if these values are
    +   equal or missing), and MUST discard the other partial information.
    +
    +13.6 Caching Negotiated Responses
    +
    +   Use of server-driven content negotiation (section 12.1), as indicated
    +   by the presence of a Vary header field in a response, alters the
    +   conditions and procedure by which a cache can use the response for
    +   subsequent requests. See section 14.44 for use of the Vary header
    +   field by servers.
    +
    +   A server SHOULD use the Vary header field to inform a cache of what
    +   request-header fields were used to select among multiple
    +   representations of a cacheable response subject to server-driven
    +   negotiation. The set of header fields named by the Vary field value
    +   is known as the "selecting" request-headers.
    +
    +   When the cache receives a subsequent request whose Request-URI
    +   specifies one or more cache entries including a Vary header field,
    +   the cache MUST NOT use such a cache entry to construct a response to
    +   the new request unless all of the selecting request-headers present
    +   in the new request match the corresponding stored request-headers in
    +   the original request.
    +
    +   The selecting request-headers from two requests are defined to match
    +   if and only if the selecting request-headers in the first request can
    +   be transformed to the selecting request-headers in the second request
    +
    +   by adding or removing linear white space (LWS) at places where this
    +   is allowed by the corresponding BNF, and/or combining multiple
    +   message-header fields with the same field name following the rules
    +   about message headers in section 4.2.
    +
    +   A Vary header field-value of "*" always fails to match and subsequent
    +   requests on that resource can only be properly interpreted by the
    +   origin server.
    +
    +   If the selecting request header fields for the cached entry do not
    +   match the selecting request header fields of the new request, then
    +   the cache MUST NOT use a cached entry to satisfy the request unless
    +   it first relays the new request to the origin server in a conditional
    +   request and the server responds with 304 (Not Modified), including an
    +   entity tag or Content-Location that indicates the entity to be used.
    +
    +   If an entity tag was assigned to a cached representation, the
    +   forwarded request SHOULD be conditional and include the entity tags
    +   in an If-None-Match header field from all its cache entries for the
    +   resource. This conveys to the server the set of entities currently
    +   held by the cache, so that if any one of these entities matches the
    +   requested entity, the server can use the ETag header field in its 304
    +   (Not Modified) response to tell the cache which entry is appropriate.
    +   If the entity-tag of the new response matches that of an existing
    +   entry, the new response SHOULD be used to update the header fields of
    +   the existing entry, and the result MUST be returned to the client.
    +
    +   If any of the existing cache entries contains only partial content
    +   for the associated entity, its entity-tag SHOULD NOT be included in
    +   the If-None-Match header field unless the request is for a range that
    +   would be fully satisfied by that entry.
    +
    +   If a cache receives a successful response whose Content-Location
    +   field matches that of an existing cache entry for the same Request-
    +   ]URI, whose entity-tag differs from that of the existing entry, and
    +   whose Date is more recent than that of the existing entry, the
    +   existing entry SHOULD NOT be returned in response to future requests
    +   and SHOULD be deleted from the cache.
    +
    +13.7 Shared and Non-Shared Caches
    +
    +   For reasons of security and privacy, it is necessary to make a
    +   distinction between "shared" and "non-shared" caches. A non-shared
    +   cache is one that is accessible only to a single user. Accessibility
    +   in this case SHOULD be enforced by appropriate security mechanisms.
    +   All other caches are considered to be "shared." Other sections of
    +
    +   this specification place certain constraints on the operation of
    +   shared caches in order to prevent loss of privacy or failure of
    +   access controls.
    +
    +13.8 Errors or Incomplete Response Cache Behavior
    +
    +   A cache that receives an incomplete response (for example, with fewer
    +   bytes of data than specified in a Content-Length header) MAY store
    +   the response. However, the cache MUST treat this as a partial
    +   response. Partial responses MAY be combined as described in section
    +   13.5.4; the result might be a full response or might still be
    +   partial. A cache MUST NOT return a partial response to a client
    +   without explicitly marking it as such, using the 206 (Partial
    +   Content) status code. A cache MUST NOT return a partial response
    +   using a status code of 200 (OK).
    +
    +   If a cache receives a 5xx response while attempting to revalidate an
    +   entry, it MAY either forward this response to the requesting client,
    +   or act as if the server failed to respond. In the latter case, it MAY
    +   return a previously received response unless the cached entry
    +   includes the "must-revalidate" cache-control directive (see section
    +   14.9).
    +
    +13.9 Side Effects of GET and HEAD
    +
    +   Unless the origin server explicitly prohibits the caching of their
    +   responses, the application of GET and HEAD methods to any resources
    +   SHOULD NOT have side effects that would lead to erroneous behavior if
    +   these responses are taken from a cache. They MAY still have side
    +   effects, but a cache is not required to consider such side effects in
    +   its caching decisions. Caches are always expected to observe an
    +   origin server's explicit restrictions on caching.
    +
    +   We note one exception to this rule: since some applications have
    +   traditionally used GETs and HEADs with query URLs (those containing a
    +   "?" in the rel_path part) to perform operations with significant side
    +   effects, caches MUST NOT treat responses to such URIs as fresh unless
    +   the server provides an explicit expiration time. This specifically
    +   means that responses from HTTP/1.0 servers for such URIs SHOULD NOT
    +   be taken from a cache. See section 9.1.1 for related information.
    +
    +13.10 Invalidation After Updates or Deletions
    +
    +   The effect of certain methods performed on a resource at the origin
    +   server might cause one or more existing cache entries to become non-
    +   transparently invalid. That is, although they might continue to be
    +   "fresh," they do not accurately reflect what the origin server would
    +   return for a new request on that resource.
    +
    +   There is no way for the HTTP protocol to guarantee that all such
    +   cache entries are marked invalid. For example, the request that
    +   caused the change at the origin server might not have gone through
    +   the proxy where a cache entry is stored. However, several rules help
    +   reduce the likelihood of erroneous behavior.
    +
    +   In this section, the phrase "invalidate an entity" means that the
    +   cache will either remove all instances of that entity from its
    +   storage, or will mark these as "invalid" and in need of a mandatory
    +   revalidation before they can be returned in response to a subsequent
    +   request.
    +
    +   Some HTTP methods MUST cause a cache to invalidate an entity. This is
    +   either the entity referred to by the Request-URI, or by the Location
    +   or Content-Location headers (if present). These methods are:
    +
    +      - PUT
    +
    +      - DELETE
    +
    +      - POST
    +
    +   In order to prevent denial of service attacks, an invalidation based
    +   on the URI in a Location or Content-Location header MUST only be
    +   performed if the host part is the same as in the Request-URI.
    +
    +   A cache that passes through requests for methods it does not
    +   understand SHOULD invalidate any entities referred to by the
    +   Request-URI.
    +
    +13.11 Write-Through Mandatory
    +
    +   All methods that might be expected to cause modifications to the
    +   origin server's resources MUST be written through to the origin
    +   server. This currently includes all methods except for GET and HEAD.
    +   A cache MUST NOT reply to such a request from a client before having
    +   transmitted the request to the inbound server, and having received a
    +   corresponding response from the inbound server. This does not prevent
    +   a proxy cache from sending a 100 (Continue) response before the
    +   inbound server has sent its final reply.
    +
    +   The alternative (known as "write-back" or "copy-back" caching) is not
    +   allowed in HTTP/1.1, due to the difficulty of providing consistent
    +   updates and the problems arising from server, cache, or network
    +   failure prior to write-back.
    +
    +13.12 Cache Replacement
    +
    +   If a new cacheable (see sections 14.9.2, 13.2.5, 13.2.6 and 13.8)
    +   response is received from a resource while any existing responses for
    +   the same resource are cached, the cache SHOULD use the new response
    +   to reply to the current request. It MAY insert it into cache storage
    +   and MAY, if it meets all other requirements, use it to respond to any
    +   future requests that would previously have caused the old response to
    +   be returned. If it inserts the new response into cache storage  the
    +   rules in section 13.5.3 apply.
    +
    +      Note: a new response that has an older Date header value than
    +      existing cached responses is not cacheable.
    +
    +13.13 History Lists
    +
    +   User agents often have history mechanisms, such as "Back" buttons and
    +   history lists, which can be used to redisplay an entity retrieved
    +   earlier in a session.
    +
    +   History mechanisms and caches are different. In particular history
    +   mechanisms SHOULD NOT try to show a semantically transparent view of
    +   the current state of a resource. Rather, a history mechanism is meant
    +   to show exactly what the user saw at the time when the resource was
    +   retrieved.
    +
    +   By default, an expiration time does not apply to history mechanisms.
    +   If the entity is still in storage, a history mechanism SHOULD display
    +   it even if the entity has expired, unless the user has specifically
    +   configured the agent to refresh expired history documents.
    +
    +   This is not to be construed to prohibit the history mechanism from
    +   telling the user that a view might be stale.
    +
    +      Note: if history list mechanisms unnecessarily prevent users from
    +      viewing stale resources, this will tend to force service authors
    +      to avoid using HTTP expiration controls and cache controls when
    +      they would otherwise like to. Service authors may consider it
    +      important that users not be presented with error messages or
    +      warning messages when they use navigation controls (such as BACK)
    +      to view previously fetched resources. Even though sometimes such
    +      resources ought not to cached, or ought to expire quickly, user
    +      interface considerations may force service authors to resort to
    +      other means of preventing caching (e.g. "once-only" URLs) in order
    +      not to suffer the effects of improperly functioning history
    +      mechanisms.
    +
    +14 Header Field Definitions
    +
    +   This section defines the syntax and semantics of all standard
    +   HTTP/1.1 header fields. For entity-header fields, both sender and
    +   recipient refer to either the client or the server, depending on who
    +   sends and who receives the entity.
    +
    +14.1 Accept
    +
    +   The Accept request-header field can be used to specify certain media
    +   types which are acceptable for the response. Accept headers can be
    +   used to indicate that the request is specifically limited to a small
    +   set of desired types, as in the case of a request for an in-line
    +   image.
    +
    +       Accept         = "Accept" ":"
    +                        #( media-range [ accept-params ] )
    +
    +       media-range    = ( "*/*"
    +                        | ( type "/" "*" )
    +                        | ( type "/" subtype )
    +                        ) *( ";" parameter )
    +       accept-params  = ";" "q" "=" qvalue *( accept-extension )
    +       accept-extension = ";" token [ "=" ( token | quoted-string ) ]
    +
    +   The asterisk "*" character is used to group media types into ranges,
    +   with "*/*" indicating all media types and "type/*" indicating all
    +   subtypes of that type. The media-range MAY include media type
    +   parameters that are applicable to that range.
    +
    +   Each media-range MAY be followed by one or more accept-params,
    +   beginning with the "q" parameter for indicating a relative quality
    +   factor. The first "q" parameter (if any) separates the media-range
    +   parameter(s) from the accept-params. Quality factors allow the user
    +   or user agent to indicate the relative degree of preference for that
    +   media-range, using the qvalue scale from 0 to 1 (section 3.9). The
    +   default value is q=1.
    +
    +      Note: Use of the "q" parameter name to separate media type
    +      parameters from Accept extension parameters is due to historical
    +      practice. Although this prevents any media type parameter named
    +      "q" from being used with a media range, such an event is believed
    +      to be unlikely given the lack of any "q" parameters in the IANA
    +      media type registry and the rare usage of any media type
    +      parameters in Accept. Future media types are discouraged from
    +      registering any parameter named "q".
    +
    +   The example
    +
    +       Accept: audio/*; q=0.2, audio/basic
    +
    +   SHOULD be interpreted as "I prefer audio/basic, but send me any audio
    +   type if it is the best available after an 80% mark-down in quality."
    +
    +   If no Accept header field is present, then it is assumed that the
    +   client accepts all media types. If an Accept header field is present,
    +   and if the server cannot send a response which is acceptable
    +   according to the combined Accept field value, then the server SHOULD
    +   send a 406 (not acceptable) response.
    +
    +   A more elaborate example is
    +
    +       Accept: text/plain; q=0.5, text/html,
    +               text/x-dvi; q=0.8, text/x-c
    +
    +   Verbally, this would be interpreted as "text/html and text/x-c are
    +   the preferred media types, but if they do not exist, then send the
    +   text/x-dvi entity, and if that does not exist, send the text/plain
    +   entity."
    +
    +   Media ranges can be overridden by more specific media ranges or
    +   specific media types. If more than one media range applies to a given
    +   type, the most specific reference has precedence. For example,
    +
    +       Accept: text/*, text/html, text/html;level=1, */*
    +
    +   have the following precedence:
    +
    +       1) text/html;level=1
    +       2) text/html
    +       3) text/*
    +       4) */*
    +
    +   The media type quality factor associated with a given type is
    +   determined by finding the media range with the highest precedence
    +   which matches that type. For example,
    +
    +       Accept: text/*;q=0.3, text/html;q=0.7, text/html;level=1,
    +               text/html;level=2;q=0.4, */*;q=0.5
    +
    +   would cause the following values to be associated:
    +
    +       text/html;level=1         = 1
    +       text/html                 = 0.7
    +       text/plain                = 0.3
    +
    +       image/jpeg                = 0.5
    +       text/html;level=2         = 0.4
    +       text/html;level=3         = 0.7
    +
    +      Note: A user agent might be provided with a default set of quality
    +      values for certain media ranges. However, unless the user agent is
    +      a closed system which cannot interact with other rendering agents,
    +      this default set ought to be configurable by the user.
    +
    +14.2 Accept-Charset
    +
    +   The Accept-Charset request-header field can be used to indicate what
    +   character sets are acceptable for the response. This field allows
    +   clients capable of understanding more comprehensive or special-
    +   purpose character sets to signal that capability to a server which is
    +   capable of representing documents in those character sets.
    +
    +      Accept-Charset = "Accept-Charset" ":"
    +              1#( ( charset | "*" )[ ";" "q" "=" qvalue ] )
    +
    +   Character set values are described in section 3.4. Each charset MAY
    +   be given an associated quality value which represents the user's
    +   preference for that charset. The default value is q=1. An example is
    +
    +      Accept-Charset: iso-8859-5, unicode-1-1;q=0.8
    +
    +   The special value "*", if present in the Accept-Charset field,
    +   matches every character set (including ISO-8859-1) which is not
    +   mentioned elsewhere in the Accept-Charset field. If no "*" is present
    +   in an Accept-Charset field, then all character sets not explicitly
    +   mentioned get a quality value of 0, except for ISO-8859-1, which gets
    +   a quality value of 1 if not explicitly mentioned.
    +
    +   If no Accept-Charset header is present, the default is that any
    +   character set is acceptable. If an Accept-Charset header is present,
    +   and if the server cannot send a response which is acceptable
    +   according to the Accept-Charset header, then the server SHOULD send
    +   an error response with the 406 (not acceptable) status code, though
    +   the sending of an unacceptable response is also allowed.
    +
    +14.3 Accept-Encoding
    +
    +   The Accept-Encoding request-header field is similar to Accept, but
    +   restricts the content-codings (section 3.5) that are acceptable in
    +   the response.
    +
    +       Accept-Encoding  = "Accept-Encoding" ":"
    +
    +                          1#( codings [ ";" "q" "=" qvalue ] )
    +       codings          = ( content-coding | "*" )
    +
    +   Examples of its use are:
    +
    +       Accept-Encoding: compress, gzip
    +       Accept-Encoding:
    +       Accept-Encoding: *
    +       Accept-Encoding: compress;q=0.5, gzip;q=1.0
    +       Accept-Encoding: gzip;q=1.0, identity; q=0.5, *;q=0
    +
    +   A server tests whether a content-coding is acceptable, according to
    +   an Accept-Encoding field, using these rules:
    +
    +      1. If the content-coding is one of the content-codings listed in
    +         the Accept-Encoding field, then it is acceptable, unless it is
    +         accompanied by a qvalue of 0. (As defined in section 3.9, a
    +         qvalue of 0 means "not acceptable.")
    +
    +      2. The special "*" symbol in an Accept-Encoding field matches any
    +         available content-coding not explicitly listed in the header
    +         field.
    +
    +      3. If multiple content-codings are acceptable, then the acceptable
    +         content-coding with the highest non-zero qvalue is preferred.
    +
    +      4. The "identity" content-coding is always acceptable, unless
    +         specifically refused because the Accept-Encoding field includes
    +         "identity;q=0", or because the field includes "*;q=0" and does
    +         not explicitly include the "identity" content-coding. If the
    +         Accept-Encoding field-value is empty, then only the "identity"
    +         encoding is acceptable.
    +
    +   If an Accept-Encoding field is present in a request, and if the
    +   server cannot send a response which is acceptable according to the
    +   Accept-Encoding header, then the server SHOULD send an error response
    +   with the 406 (Not Acceptable) status code.
    +
    +   If no Accept-Encoding field is present in a request, the server MAY
    +   assume that the client will accept any content coding. In this case,
    +   if "identity" is one of the available content-codings, then the
    +   server SHOULD use the "identity" content-coding, unless it has
    +   additional information that a different content-coding is meaningful
    +   to the client.
    +
    +      Note: If the request does not include an Accept-Encoding field,
    +      and if the "identity" content-coding is unavailable, then
    +      content-codings commonly understood by HTTP/1.0 clients (i.e.,
    +
    +      "gzip" and "compress") are preferred; some older clients
    +      improperly display messages sent with other content-codings.  The
    +      server might also make this decision based on information about
    +      the particular user-agent or client.
    +
    +      Note: Most HTTP/1.0 applications do not recognize or obey qvalues
    +      associated with content-codings. This means that qvalues will not
    +      work and are not permitted with x-gzip or x-compress.
    +
    +14.4 Accept-Language
    +
    +   The Accept-Language request-header field is similar to Accept, but
    +   restricts the set of natural languages that are preferred as a
    +   response to the request. Language tags are defined in section 3.10.
    +
    +       Accept-Language = "Accept-Language" ":"
    +                         1#( language-range [ ";" "q" "=" qvalue ] )
    +       language-range  = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" )
    +
    +   Each language-range MAY be given an associated quality value which
    +   represents an estimate of the user's preference for the languages
    +   specified by that range. The quality value defaults to "q=1". For
    +   example,
    +
    +       Accept-Language: da, en-gb;q=0.8, en;q=0.7
    +
    +   would mean: "I prefer Danish, but will accept British English and
    +   other types of English." A language-range matches a language-tag if
    +   it exactly equals the tag, or if it exactly equals a prefix of the
    +   tag such that the first tag character following the prefix is "-".
    +   The special range "*", if present in the Accept-Language field,
    +   matches every tag not matched by any other range present in the
    +   Accept-Language field.
    +
    +      Note: This use of a prefix matching rule does not imply that
    +      language tags are assigned to languages in such a way that it is
    +      always true that if a user understands a language with a certain
    +      tag, then this user will also understand all languages with tags
    +      for which this tag is a prefix. The prefix rule simply allows the
    +      use of prefix tags if this is the case.
    +
    +   The language quality factor assigned to a language-tag by the
    +   Accept-Language field is the quality value of the longest language-
    +   range in the field that matches the language-tag. If no language-
    +   range in the field matches the tag, the language quality factor
    +   assigned is 0. If no Accept-Language header is present in the
    +   request, the server
    +
    +   SHOULD assume that all languages are equally acceptable. If an
    +   Accept-Language header is present, then all languages which are
    +   assigned a quality factor greater than 0 are acceptable.
    +
    +   It might be contrary to the privacy expectations of the user to send
    +   an Accept-Language header with the complete linguistic preferences of
    +   the user in every request. For a discussion of this issue, see
    +   section 15.1.4.
    +
    +   As intelligibility is highly dependent on the individual user, it is
    +   recommended that client applications make the choice of linguistic
    +   preference available to the user. If the choice is not made
    +   available, then the Accept-Language header field MUST NOT be given in
    +   the request.
    +
    +      Note: When making the choice of linguistic preference available to
    +      the user, we remind implementors of  the fact that users are not
    +      familiar with the details of language matching as described above,
    +      and should provide appropriate guidance. As an example, users
    +      might assume that on selecting "en-gb", they will be served any
    +      kind of English document if British English is not available. A
    +      user agent might suggest in such a case to add "en" to get the
    +      best matching behavior.
    +
    +14.5 Accept-Ranges
    +
    +      The Accept-Ranges response-header field allows the server to
    +      indicate its acceptance of range requests for a resource:
    +
    +          Accept-Ranges     = "Accept-Ranges" ":" acceptable-ranges
    +          acceptable-ranges = 1#range-unit | "none"
    +
    +      Origin servers that accept byte-range requests MAY send
    +
    +          Accept-Ranges: bytes
    +
    +      but are not required to do so. Clients MAY generate byte-range
    +      requests without having received this header for the resource
    +      involved. Range units are defined in section 3.12.
    +
    +      Servers that do not accept any kind of range request for a
    +      resource MAY send
    +
    +          Accept-Ranges: none
    +
    +      to advise the client not to attempt a range request.
    +
    +14.6 Age
    +
    +      The Age response-header field conveys the sender's estimate of the
    +      amount of time since the response (or its revalidation) was
    +      generated at the origin server. A cached response is "fresh" if
    +      its age does not exceed its freshness lifetime. Age values are
    +      calculated as specified in section 13.2.3.
    +
    +           Age = "Age" ":" age-value
    +           age-value = delta-seconds
    +
    +      Age values are non-negative decimal integers, representing time in
    +      seconds.
    +
    +      If a cache receives a value larger than the largest positive
    +      integer it can represent, or if any of its age calculations
    +      overflows, it MUST transmit an Age header with a value of
    +      2147483648 (2^31). An HTTP/1.1 server that includes a cache MUST
    +      include an Age header field in every response generated from its
    +      own cache. Caches SHOULD use an arithmetic type of at least 31
    +      bits of range.
    +
    +14.7 Allow
    +
    +      The Allow entity-header field lists the set of methods supported
    +      by the resource identified by the Request-URI. The purpose of this
    +      field is strictly to inform the recipient of valid methods
    +      associated with the resource. An Allow header field MUST be
    +      present in a 405 (Method Not Allowed) response.
    +
    +          Allow   = "Allow" ":" #Method
    +
    +      Example of use:
    +
    +          Allow: GET, HEAD, PUT
    +
    +      This field cannot prevent a client from trying other methods.
    +      However, the indications given by the Allow header field value
    +      SHOULD be followed. The actual set of allowed methods is defined
    +      by the origin server at the time of each request.
    +
    +      The Allow header field MAY be provided with a PUT request to
    +      recommend the methods to be supported by the new or modified
    +      resource. The server is not required to support these methods and
    +      SHOULD include an Allow header in the response giving the actual
    +      supported methods.
    +
    +      A proxy MUST NOT modify the Allow header field even if it does not
    +      understand all the methods specified, since the user agent might
    +      have other means of communicating with the origin server.
    +
    +14.8 Authorization
    +
    +      A user agent that wishes to authenticate itself with a server--
    +      usually, but not necessarily, after receiving a 401 response--does
    +      so by including an Authorization request-header field with the
    +      request.  The Authorization field value consists of credentials
    +      containing the authentication information of the user agent for
    +      the realm of the resource being requested.
    +
    +          Authorization  = "Authorization" ":" credentials
    +
    +      HTTP access authentication is described in "HTTP Authentication:
    +      Basic and Digest Access Authentication" [43]. If a request is
    +      authenticated and a realm specified, the same credentials SHOULD
    +      be valid for all other requests within this realm (assuming that
    +      the authentication scheme itself does not require otherwise, such
    +      as credentials that vary according to a challenge value or using
    +      synchronized clocks).
    +
    +      When a shared cache (see section 13.7) receives a request
    +      containing an Authorization field, it MUST NOT return the
    +      corresponding response as a reply to any other request, unless one
    +      of the following specific exceptions holds:
    +
    +      1. If the response includes the "s-maxage" cache-control
    +         directive, the cache MAY use that response in replying to a
    +         subsequent request. But (if the specified maximum age has
    +         passed) a proxy cache MUST first revalidate it with the origin
    +         server, using the request-headers from the new request to allow
    +         the origin server to authenticate the new request. (This is the
    +         defined behavior for s-maxage.) If the response includes "s-
    +         maxage=0", the proxy MUST always revalidate it before re-using
    +         it.
    +
    +      2. If the response includes the "must-revalidate" cache-control
    +         directive, the cache MAY use that response in replying to a
    +         subsequent request. But if the response is stale, all caches
    +         MUST first revalidate it with the origin server, using the
    +         request-headers from the new request to allow the origin server
    +         to authenticate the new request.
    +
    +      3. If the response includes the "public" cache-control directive,
    +         it MAY be returned in reply to any subsequent request.
    +
    +14.9 Cache-Control
    +
    +   The Cache-Control general-header field is used to specify directives
    +   that MUST be obeyed by all caching mechanisms along the
    +   request/response chain. The directives specify behavior intended to
    +   prevent caches from adversely interfering with the request or
    +   response. These directives typically override the default caching
    +   algorithms. Cache directives are unidirectional in that the presence
    +   of a directive in a request does not imply that the same directive is
    +   to be given in the response.
    +
    +      Note that HTTP/1.0 caches might not implement Cache-Control and
    +      might only implement Pragma: no-cache (see section 14.32).
    +
    +   Cache directives MUST be passed through by a proxy or gateway
    +   application, regardless of their significance to that application,
    +   since the directives might be applicable to all recipients along the
    +   request/response chain. It is not possible to specify a cache-
    +   directive for a specific cache.
    +
    +    Cache-Control   = "Cache-Control" ":" 1#cache-directive
    +
    +    cache-directive = cache-request-directive
    +         | cache-response-directive
    +
    +    cache-request-directive =
    +           "no-cache"                          ; Section 14.9.1
    +         | "no-store"                          ; Section 14.9.2
    +         | "max-age" "=" delta-seconds         ; Section 14.9.3, 14.9.4
    +         | "max-stale" [ "=" delta-seconds ]   ; Section 14.9.3
    +         | "min-fresh" "=" delta-seconds       ; Section 14.9.3
    +         | "no-transform"                      ; Section 14.9.5
    +         | "only-if-cached"                    ; Section 14.9.4
    +         | cache-extension                     ; Section 14.9.6
    +
    +     cache-response-directive =
    +           "public"                               ; Section 14.9.1
    +         | "private" [ "=" <"> 1#field-name <"> ] ; Section 14.9.1
    +         | "no-cache" [ "=" <"> 1#field-name <"> ]; Section 14.9.1
    +         | "no-store"                             ; Section 14.9.2
    +         | "no-transform"                         ; Section 14.9.5
    +         | "must-revalidate"                      ; Section 14.9.4
    +         | "proxy-revalidate"                     ; Section 14.9.4
    +         | "max-age" "=" delta-seconds            ; Section 14.9.3
    +         | "s-maxage" "=" delta-seconds           ; Section 14.9.3
    +         | cache-extension                        ; Section 14.9.6
    +
    +    cache-extension = token [ "=" ( token | quoted-string ) ]
    +
    +   When a directive appears without any 1#field-name parameter, the
    +   directive applies to the entire request or response. When such a
    +   directive appears with a 1#field-name parameter, it applies only to
    +   the named field or fields, and not to the rest of the request or
    +   response. This mechanism supports extensibility; implementations of
    +   future versions of the HTTP protocol might apply these directives to
    +   header fields not defined in HTTP/1.1.
    +
    +   The cache-control directives can be broken down into these general
    +   categories:
    +
    +      - Restrictions on what are cacheable; these may only be imposed by
    +        the origin server.
    +
    +      - Restrictions on what may be stored by a cache; these may be
    +        imposed by either the origin server or the user agent.
    +
    +      - Modifications of the basic expiration mechanism; these may be
    +        imposed by either the origin server or the user agent.
    +
    +      - Controls over cache revalidation and reload; these may only be
    +        imposed by a user agent.
    +
    +      - Control over transformation of entities.
    +
    +      - Extensions to the caching system.
    +
    +14.9.1 What is Cacheable
    +
    +   By default, a response is cacheable if the requirements of the
    +   request method, request header fields, and the response status
    +   indicate that it is cacheable. Section 13.4 summarizes these defaults
    +   for cacheability. The following Cache-Control response directives
    +   allow an origin server to override the default cacheability of a
    +   response:
    +
    +   public
    +      Indicates that the response MAY be cached by any cache, even if it
    +      would normally be non-cacheable or cacheable only within a non-
    +      shared cache. (See also Authorization, section 14.8, for
    +      additional details.)
    +
    +   private
    +      Indicates that all or part of the response message is intended for
    +      a single user and MUST NOT be cached by a shared cache. This
    +      allows an origin server to state that the specified parts of the
    +
    +      response are intended for only one user and are not a valid
    +      response for requests by other users. A private (non-shared) cache
    +      MAY cache the response.
    +
    +       Note: This usage of the word private only controls where the
    +       response may be cached, and cannot ensure the privacy of the
    +       message content.
    +
    +   no-cache
    +       If the no-cache directive does not specify a field-name, then a
    +      cache MUST NOT use the response to satisfy a subsequent request
    +      without successful revalidation with the origin server. This
    +      allows an origin server to prevent caching even by caches that
    +      have been configured to return stale responses to client requests.
    +
    +      If the no-cache directive does specify one or more field-names,
    +      then a cache MAY use the response to satisfy a subsequent request,
    +      subject to any other restrictions on caching. However, the
    +      specified field-name(s) MUST NOT be sent in the response to a
    +      subsequent request without successful revalidation with the origin
    +      server. This allows an origin server to prevent the re-use of
    +      certain header fields in a response, while still allowing caching
    +      of the rest of the response.
    +
    +       Note: Most HTTP/1.0 caches will not recognize or obey this
    +       directive.
    +
    +14.9.2 What May be Stored by Caches
    +
    +   no-store
    +      The purpose of the no-store directive is to prevent the
    +      inadvertent release or retention of sensitive information (for
    +      example, on backup tapes). The no-store directive applies to the
    +      entire message, and MAY be sent either in a response or in a
    +      request. If sent in a request, a cache MUST NOT store any part of
    +      either this request or any response to it. If sent in a response,
    +      a cache MUST NOT store any part of either this response or the
    +      request that elicited it. This directive applies to both non-
    +      shared and shared caches. "MUST NOT store" in this context means
    +      that the cache MUST NOT intentionally store the information in
    +      non-volatile storage, and MUST make a best-effort attempt to
    +      remove the information from volatile storage as promptly as
    +      possible after forwarding it.
    +
    +      Even when this directive is associated with a response, users
    +      might explicitly store such a response outside of the caching
    +      system (e.g., with a "Save As" dialog). History buffers MAY store
    +      such responses as part of their normal operation.
    +
    +      The purpose of this directive is to meet the stated requirements
    +      of certain users and service authors who are concerned about
    +      accidental releases of information via unanticipated accesses to
    +      cache data structures. While the use of this directive might
    +      improve privacy in some cases, we caution that it is NOT in any
    +      way a reliable or sufficient mechanism for ensuring privacy. In
    +      particular, malicious or compromised caches might not recognize or
    +      obey this directive, and communications networks might be
    +      vulnerable to eavesdropping.
    +
    +14.9.3 Modifications of the Basic Expiration Mechanism
    +
    +   The expiration time of an entity MAY be specified by the origin
    +   server using the Expires header (see section 14.21). Alternatively,
    +   it MAY be specified using the max-age directive in a response. When
    +   the max-age cache-control directive is present in a cached response,
    +   the response is stale if its current age is greater than the age
    +   value given (in seconds) at the time of a new request for that
    +   resource. The max-age directive on a response implies that the
    +   response is cacheable (i.e., "public") unless some other, more
    +   restrictive cache directive is also present.
    +
    +   If a response includes both an Expires header and a max-age
    +   directive, the max-age directive overrides the Expires header, even
    +   if the Expires header is more restrictive. This rule allows an origin
    +   server to provide, for a given response, a longer expiration time to
    +   an HTTP/1.1 (or later) cache than to an HTTP/1.0 cache. This might be
    +   useful if certain HTTP/1.0 caches improperly calculate ages or
    +   expiration times, perhaps due to desynchronized clocks.
    +
    +   Many HTTP/1.0 cache implementations will treat an Expires value that
    +   is less than or equal to the response Date value as being equivalent
    +   to the Cache-Control response directive "no-cache". If an HTTP/1.1
    +   cache receives such a response, and the response does not include a
    +   Cache-Control header field, it SHOULD consider the response to be
    +   non-cacheable in order to retain compatibility with HTTP/1.0 servers.
    +
    +       Note: An origin server might wish to use a relatively new HTTP
    +       cache control feature, such as the "private" directive, on a
    +       network including older caches that do not understand that
    +       feature. The origin server will need to combine the new feature
    +       with an Expires field whose value is less than or equal to the
    +       Date value. This will prevent older caches from improperly
    +       caching the response.
    +
    +   s-maxage
    +       If a response includes an s-maxage directive, then for a shared
    +       cache (but not for a private cache), the maximum age specified by
    +       this directive overrides the maximum age specified by either the
    +       max-age directive or the Expires header. The s-maxage directive
    +       also implies the semantics of the proxy-revalidate directive (see
    +       section 14.9.4), i.e., that the shared cache must not use the
    +       entry after it becomes stale to respond to a subsequent request
    +       without first revalidating it with the origin server. The s-
    +       maxage directive is always ignored by a private cache.
    +
    +   Note that most older caches, not compliant with this specification,
    +   do not implement any cache-control directives. An origin server
    +   wishing to use a cache-control directive that restricts, but does not
    +   prevent, caching by an HTTP/1.1-compliant cache MAY exploit the
    +   requirement that the max-age directive overrides the Expires header,
    +   and the fact that pre-HTTP/1.1-compliant caches do not observe the
    +   max-age directive.
    +
    +   Other directives allow a user agent to modify the basic expiration
    +   mechanism. These directives MAY be specified on a request:
    +
    +   max-age
    +      Indicates that the client is willing to accept a response whose
    +      age is no greater than the specified time in seconds. Unless max-
    +      stale directive is also included, the client is not willing to
    +      accept a stale response.
    +
    +   min-fresh
    +      Indicates that the client is willing to accept a response whose
    +      freshness lifetime is no less than its current age plus the
    +      specified time in seconds. That is, the client wants a response
    +      that will still be fresh for at least the specified number of
    +      seconds.
    +
    +   max-stale
    +      Indicates that the client is willing to accept a response that has
    +      exceeded its expiration time. If max-stale is assigned a value,
    +      then the client is willing to accept a response that has exceeded
    +      its expiration time by no more than the specified number of
    +      seconds. If no value is assigned to max-stale, then the client is
    +      willing to accept a stale response of any age.
    +
    +   If a cache returns a stale response, either because of a max-stale
    +   directive on a request, or because the cache is configured to
    +   override the expiration time of a response, the cache MUST attach a
    +   Warning header to the stale response, using Warning 110 (Response is
    +   stale).
    +
    +   A cache MAY be configured to return stale responses without
    +   validation, but only if this does not conflict with any "MUST"-level
    +   requirements concerning cache validation (e.g., a "must-revalidate"
    +   cache-control directive).
    +
    +   If both the new request and the cached entry include "max-age"
    +   directives, then the lesser of the two values is used for determining
    +   the freshness of the cached entry for that request.
    +
    +14.9.4 Cache Revalidation and Reload Controls
    +
    +   Sometimes a user agent might want or need to insist that a cache
    +   revalidate its cache entry with the origin server (and not just with
    +   the next cache along the path to the origin server), or to reload its
    +   cache entry from the origin server. End-to-end revalidation might be
    +   necessary if either the cache or the origin server has overestimated
    +   the expiration time of the cached response. End-to-end reload may be
    +   necessary if the cache entry has become corrupted for some reason.
    +
    +   End-to-end revalidation may be requested either when the client does
    +   not have its own local cached copy, in which case we call it
    +   "unspecified end-to-end revalidation", or when the client does have a
    +   local cached copy, in which case we call it "specific end-to-end
    +   revalidation."
    +
    +   The client can specify these three kinds of action using Cache-
    +   Control request directives:
    +
    +   End-to-end reload
    +      The request includes a "no-cache" cache-control directive or, for
    +      compatibility with HTTP/1.0 clients, "Pragma: no-cache". Field
    +      names MUST NOT be included with the no-cache directive in a
    +      request. The server MUST NOT use a cached copy when responding to
    +      such a request.
    +
    +   Specific end-to-end revalidation
    +      The request includes a "max-age=0" cache-control directive, which
    +      forces each cache along the path to the origin server to
    +      revalidate its own entry, if any, with the next cache or server.
    +      The initial request includes a cache-validating conditional with
    +      the client's current validator.
    +
    +   Unspecified end-to-end revalidation
    +      The request includes "max-age=0" cache-control directive, which
    +      forces each cache along the path to the origin server to
    +      revalidate its own entry, if any, with the next cache or server.
    +      The initial request does not include a cache-validating
    +
    +      conditional; the first cache along the path (if any) that holds a
    +      cache entry for this resource includes a cache-validating
    +      conditional with its current validator.
    +
    +   max-age
    +      When an intermediate cache is forced, by means of a max-age=0
    +      directive, to revalidate its own cache entry, and the client has
    +      supplied its own validator in the request, the supplied validator
    +      might differ from the validator currently stored with the cache
    +      entry. In this case, the cache MAY use either validator in making
    +      its own request without affecting semantic transparency.
    +
    +      However, the choice of validator might affect performance. The
    +      best approach is for the intermediate cache to use its own
    +      validator when making its request. If the server replies with 304
    +      (Not Modified), then the cache can return its now validated copy
    +      to the client with a 200 (OK) response. If the server replies with
    +      a new entity and cache validator, however, the intermediate cache
    +      can compare the returned validator with the one provided in the
    +      client's request, using the strong comparison function. If the
    +      client's validator is equal to the origin server's, then the
    +      intermediate cache simply returns 304 (Not Modified). Otherwise,
    +      it returns the new entity with a 200 (OK) response.
    +
    +      If a request includes the no-cache directive, it SHOULD NOT
    +      include min-fresh, max-stale, or max-age.
    +
    +   only-if-cached
    +      In some cases, such as times of extremely poor network
    +      connectivity, a client may want a cache to return only those
    +      responses that it currently has stored, and not to reload or
    +      revalidate with the origin server. To do this, the client may
    +      include the only-if-cached directive in a request. If it receives
    +      this directive, a cache SHOULD either respond using a cached entry
    +      that is consistent with the other constraints of the request, or
    +      respond with a 504 (Gateway Timeout) status. However, if a group
    +      of caches is being operated as a unified system with good internal
    +      connectivity, such a request MAY be forwarded within that group of
    +      caches.
    +
    +   must-revalidate
    +      Because a cache MAY be configured to ignore a server's specified
    +      expiration time, and because a client request MAY include a max-
    +      stale directive (which has a similar effect), the protocol also
    +      includes a mechanism for the origin server to require revalidation
    +      of a cache entry on any subsequent use. When the must-revalidate
    +      directive is present in a response received by a cache, that cache
    +      MUST NOT use the entry after it becomes stale to respond to a
    +
    +      subsequent request without first revalidating it with the origin
    +      server. (I.e., the cache MUST do an end-to-end revalidation every
    +      time, if, based solely on the origin server's Expires or max-age
    +      value, the cached response is stale.)
    +
    +      The must-revalidate directive is necessary to support reliable
    +      operation for certain protocol features. In all circumstances an
    +      HTTP/1.1 cache MUST obey the must-revalidate directive; in
    +      particular, if the cache cannot reach the origin server for any
    +      reason, it MUST generate a 504 (Gateway Timeout) response.
    +
    +      Servers SHOULD send the must-revalidate directive if and only if
    +      failure to revalidate a request on the entity could result in
    +      incorrect operation, such as a silently unexecuted financial
    +      transaction. Recipients MUST NOT take any automated action that
    +      violates this directive, and MUST NOT automatically provide an
    +      unvalidated copy of the entity if revalidation fails.
    +
    +      Although this is not recommended, user agents operating under
    +      severe connectivity constraints MAY violate this directive but, if
    +      so, MUST explicitly warn the user that an unvalidated response has
    +      been provided. The warning MUST be provided on each unvalidated
    +      access, and SHOULD require explicit user confirmation.
    +
    +   proxy-revalidate
    +      The proxy-revalidate directive has the same meaning as the must-
    +      revalidate directive, except that it does not apply to non-shared
    +      user agent caches. It can be used on a response to an
    +      authenticated request to permit the user's cache to store and
    +      later return the response without needing to revalidate it (since
    +      it has already been authenticated once by that user), while still
    +      requiring proxies that service many users to revalidate each time
    +      (in order to make sure that each user has been authenticated).
    +      Note that such authenticated responses also need the public cache
    +      control directive in order to allow them to be cached at all.
    +
    +14.9.5 No-Transform Directive
    +
    +   no-transform
    +      Implementors of intermediate caches (proxies) have found it useful
    +      to convert the media type of certain entity bodies. A non-
    +      transparent proxy might, for example, convert between image
    +      formats in order to save cache space or to reduce the amount of
    +      traffic on a slow link.
    +
    +      Serious operational problems occur, however, when these
    +      transformations are applied to entity bodies intended for certain
    +      kinds of applications. For example, applications for medical
    +
    +      imaging, scientific data analysis and those using end-to-end
    +      authentication, all depend on receiving an entity body that is bit
    +      for bit identical to the original entity-body.
    +
    +      Therefore, if a message includes the no-transform directive, an
    +      intermediate cache or proxy MUST NOT change those headers that are
    +      listed in section 13.5.2 as being subject to the no-transform
    +      directive. This implies that the cache or proxy MUST NOT change
    +      any aspect of the entity-body that is specified by these headers,
    +      including the value of the entity-body itself.
    +
    +14.9.6 Cache Control Extensions
    +
    +   The Cache-Control header field can be extended through the use of one
    +   or more cache-extension tokens, each with an optional assigned value.
    +   Informational extensions (those which do not require a change in
    +   cache behavior) MAY be added without changing the semantics of other
    +   directives. Behavioral extensions are designed to work by acting as
    +   modifiers to the existing base of cache directives. Both the new
    +   directive and the standard directive are supplied, such that
    +   applications which do not understand the new directive will default
    +   to the behavior specified by the standard directive, and those that
    +   understand the new directive will recognize it as modifying the
    +   requirements associated with the standard directive. In this way,
    +   extensions to the cache-control directives can be made without
    +   requiring changes to the base protocol.
    +
    +   This extension mechanism depends on an HTTP cache obeying all of the
    +   cache-control directives defined for its native HTTP-version, obeying
    +   certain extensions, and ignoring all directives that it does not
    +   understand.
    +
    +   For example, consider a hypothetical new response directive called
    +   community which acts as a modifier to the private directive. We
    +   define this new directive to mean that, in addition to any non-shared
    +   cache, any cache which is shared only by members of the community
    +   named within its value may cache the response. An origin server
    +   wishing to allow the UCI community to use an otherwise private
    +   response in their shared cache(s) could do so by including
    +
    +       Cache-Control: private, community="UCI"
    +
    +   A cache seeing this header field will act correctly even if the cache
    +   does not understand the community cache-extension, since it will also
    +   see and understand the private directive and thus default to the safe
    +   behavior.
    +
    +   Unrecognized cache-directives MUST be ignored; it is assumed that any
    +   cache-directive likely to be unrecognized by an HTTP/1.1 cache will
    +   be combined with standard directives (or the response's default
    +   cacheability) such that the cache behavior will remain minimally
    +   correct even if the cache does not understand the extension(s).
    +
    +14.10 Connection
    +
    +   The Connection general-header field allows the sender to specify
    +   options that are desired for that particular connection and MUST NOT
    +   be communicated by proxies over further connections.
    +
    +   The Connection header has the following grammar:
    +
    +       Connection = "Connection" ":" 1#(connection-token)
    +       connection-token  = token
    +
    +   HTTP/1.1 proxies MUST parse the Connection header field before a
    +   message is forwarded and, for each connection-token in this field,
    +   remove any header field(s) from the message with the same name as the
    +   connection-token. Connection options are signaled by the presence of
    +   a connection-token in the Connection header field, not by any
    +   corresponding additional header field(s), since the additional header
    +   field may not be sent if there are no parameters associated with that
    +   connection option.
    +
    +   Message headers listed in the Connection header MUST NOT include
    +   end-to-end headers, such as Cache-Control.
    +
    +   HTTP/1.1 defines the "close" connection option for the sender to
    +   signal that the connection will be closed after completion of the
    +   response. For example,
    +
    +       Connection: close
    +
    +   in either the request or the response header fields indicates that
    +   the connection SHOULD NOT be considered `persistent' (section 8.1)
    +   after the current request/response is complete.
    +
    +   HTTP/1.1 applications that do not support persistent connections MUST
    +   include the "close" connection option in every message.
    +
    +   A system receiving an HTTP/1.0 (or lower-version) message that
    +   includes a Connection header MUST, for each connection-token in this
    +   field, remove and ignore any header field(s) from the message with
    +   the same name as the connection-token. This protects against mistaken
    +   forwarding of such header fields by pre-HTTP/1.1 proxies. See section
    +   19.6.2.
    +
    +14.11 Content-Encoding
    +
    +   The Content-Encoding entity-header field is used as a modifier to the
    +   media-type. When present, its value indicates what additional content
    +   codings have been applied to the entity-body, and thus what decoding
    +   mechanisms must be applied in order to obtain the media-type
    +   referenced by the Content-Type header field. Content-Encoding is
    +   primarily used to allow a document to be compressed without losing
    +   the identity of its underlying media type.
    +
    +       Content-Encoding  = "Content-Encoding" ":" 1#content-coding
    +
    +   Content codings are defined in section 3.5. An example of its use is
    +
    +       Content-Encoding: gzip
    +
    +   The content-coding is a characteristic of the entity identified by
    +   the Request-URI. Typically, the entity-body is stored with this
    +   encoding and is only decoded before rendering or analogous usage.
    +   However, a non-transparent proxy MAY modify the content-coding if the
    +   new coding is known to be acceptable to the recipient, unless the
    +   "no-transform" cache-control directive is present in the message.
    +
    +   If the content-coding of an entity is not "identity", then the
    +   response MUST include a Content-Encoding entity-header (section
    +   14.11) that lists the non-identity content-coding(s) used.
    +
    +   If the content-coding of an entity in a request message is not
    +   acceptable to the origin server, the server SHOULD respond with a
    +   status code of 415 (Unsupported Media Type).
    +
    +   If multiple encodings have been applied to an entity, the content
    +   codings MUST be listed in the order in which they were applied.
    +   Additional information about the encoding parameters MAY be provided
    +   by other entity-header fields not defined by this specification.
    +
    +14.12 Content-Language
    +
    +   The Content-Language entity-header field describes the natural
    +   language(s) of the intended audience for the enclosed entity. Note
    +   that this might not be equivalent to all the languages used within
    +   the entity-body.
    +
    +       Content-Language  = "Content-Language" ":" 1#language-tag
    +
    +   Language tags are defined in section 3.10. The primary purpose of
    +   Content-Language is to allow a user to identify and differentiate
    +   entities according to the user's own preferred language. Thus, if the
    +   body content is intended only for a Danish-literate audience, the
    +   appropriate field is
    +
    +       Content-Language: da
    +
    +   If no Content-Language is specified, the default is that the content
    +   is intended for all language audiences. This might mean that the
    +   sender does not consider it to be specific to any natural language,
    +   or that the sender does not know for which language it is intended.
    +
    +   Multiple languages MAY be listed for content that is intended for
    +   multiple audiences. For example, a rendition of the "Treaty of
    +   Waitangi," presented simultaneously in the original Maori and English
    +   versions, would call for
    +
    +       Content-Language: mi, en
    +
    +   However, just because multiple languages are present within an entity
    +   does not mean that it is intended for multiple linguistic audiences.
    +   An example would be a beginner's language primer, such as "A First
    +   Lesson in Latin," which is clearly intended to be used by an
    +   English-literate audience. In this case, the Content-Language would
    +   properly only include "en".
    +
    +   Content-Language MAY be applied to any media type -- it is not
    +   limited to textual documents.
    +
    +14.13 Content-Length
    +
    +   The Content-Length entity-header field indicates the size of the
    +   entity-body, in decimal number of OCTETs, sent to the recipient or,
    +   in the case of the HEAD method, the size of the entity-body that
    +   would have been sent had the request been a GET.
    +
    +       Content-Length    = "Content-Length" ":" 1*DIGIT
    +
    +   An example is
    +
    +       Content-Length: 3495
    +
    +   Applications SHOULD use this field to indicate the transfer-length of
    +   the message-body, unless this is prohibited by the rules in section
    +   4.4.
    +
    +   Any Content-Length greater than or equal to zero is a valid value.
    +   Section 4.4 describes how to determine the length of a message-body
    +   if a Content-Length is not given.
    +
    +   Note that the meaning of this field is significantly different from
    +   the corresponding definition in MIME, where it is an optional field
    +   used within the "message/external-body" content-type. In HTTP, it
    +   SHOULD be sent whenever the message's length can be determined prior
    +   to being transferred, unless this is prohibited by the rules in
    +   section 4.4.
    +
    +14.14 Content-Location
    +
    +   The Content-Location entity-header field MAY be used to supply the
    +   resource location for the entity enclosed in the message when that
    +   entity is accessible from a location separate from the requested
    +   resource's URI. A server SHOULD provide a Content-Location for the
    +   variant corresponding to the response entity; especially in the case
    +   where a resource has multiple entities associated with it, and those
    +   entities actually have separate locations by which they might be
    +   individually accessed, the server SHOULD provide a Content-Location
    +   for the particular variant which is returned.
    +
    +       Content-Location = "Content-Location" ":"
    +                         ( absoluteURI | relativeURI )
    +
    +   The value of Content-Location also defines the base URI for the
    +   entity.
    +
    +   The Content-Location value is not a replacement for the original
    +   requested URI; it is only a statement of the location of the resource
    +   corresponding to this particular entity at the time of the request.
    +   Future requests MAY specify the Content-Location URI as the request-
    +   URI if the desire is to identify the source of that particular
    +   entity.
    +
    +   A cache cannot assume that an entity with a Content-Location
    +   different from the URI used to retrieve it can be used to respond to
    +   later requests on that Content-Location URI. However, the Content-
    +   Location can be used to differentiate between multiple entities
    +   retrieved from a single requested resource, as described in section
    +   13.6.
    +
    +   If the Content-Location is a relative URI, the relative URI is
    +   interpreted relative to the Request-URI.
    +
    +   The meaning of the Content-Location header in PUT or POST requests is
    +   undefined; servers are free to ignore it in those cases.
    +
    +14.15 Content-MD5
    +
    +   The Content-MD5 entity-header field, as defined in RFC 1864 [23], is
    +   an MD5 digest of the entity-body for the purpose of providing an
    +   end-to-end message integrity check (MIC) of the entity-body. (Note: a
    +   MIC is good for detecting accidental modification of the entity-body
    +   in transit, but is not proof against malicious attacks.)
    +
    +        Content-MD5   = "Content-MD5" ":" md5-digest
    +        md5-digest   = <base64 of 128 bit MD5 digest as per RFC 1864>
    +
    +   The Content-MD5 header field MAY be generated by an origin server or
    +   client to function as an integrity check of the entity-body. Only
    +   origin servers or clients MAY generate the Content-MD5 header field;
    +   proxies and gateways MUST NOT generate it, as this would defeat its
    +   value as an end-to-end integrity check. Any recipient of the entity-
    +   body, including gateways and proxies, MAY check that the digest value
    +   in this header field matches that of the entity-body as received.
    +
    +   The MD5 digest is computed based on the content of the entity-body,
    +   including any content-coding that has been applied, but not including
    +   any transfer-encoding applied to the message-body. If the message is
    +   received with a transfer-encoding, that encoding MUST be removed
    +   prior to checking the Content-MD5 value against the received entity.
    +
    +   This has the result that the digest is computed on the octets of the
    +   entity-body exactly as, and in the order that, they would be sent if
    +   no transfer-encoding were being applied.
    +
    +   HTTP extends RFC 1864 to permit the digest to be computed for MIME
    +   composite media-types (e.g., multipart/* and message/rfc822), but
    +   this does not change how the digest is computed as defined in the
    +   preceding paragraph.
    +
    +   There are several consequences of this. The entity-body for composite
    +   types MAY contain many body-parts, each with its own MIME and HTTP
    +   headers (including Content-MD5, Content-Transfer-Encoding, and
    +   Content-Encoding headers). If a body-part has a Content-Transfer-
    +   Encoding or Content-Encoding header, it is assumed that the content
    +   of the body-part has had the encoding applied, and the body-part is
    +   included in the Content-MD5 digest as is -- i.e., after the
    +   application. The Transfer-Encoding header field is not allowed within
    +   body-parts.
    +
    +   Conversion of all line breaks to CRLF MUST NOT be done before
    +   computing or checking the digest: the line break convention used in
    +   the text actually transmitted MUST be left unaltered when computing
    +   the digest.
    +
    +      Note: while the definition of Content-MD5 is exactly the same for
    +      HTTP as in RFC 1864 for MIME entity-bodies, there are several ways
    +      in which the application of Content-MD5 to HTTP entity-bodies
    +      differs from its application to MIME entity-bodies. One is that
    +      HTTP, unlike MIME, does not use Content-Transfer-Encoding, and
    +      does use Transfer-Encoding and Content-Encoding. Another is that
    +      HTTP more frequently uses binary content types than MIME, so it is
    +      worth noting that, in such cases, the byte order used to compute
    +      the digest is the transmission byte order defined for the type.
    +      Lastly, HTTP allows transmission of text types with any of several
    +      line break conventions and not just the canonical form using CRLF.
    +
    +14.16 Content-Range
    +
    +   The Content-Range entity-header is sent with a partial entity-body to
    +   specify where in the full entity-body the partial body should be
    +   applied. Range units are defined in section 3.12.
    +
    +       Content-Range = "Content-Range" ":" content-range-spec
    +
    +       content-range-spec      = byte-content-range-spec
    +       byte-content-range-spec = bytes-unit SP
    +                                 byte-range-resp-spec "/"
    +                                 ( instance-length | "*" )
    +
    +       byte-range-resp-spec = (first-byte-pos "-" last-byte-pos)
    +                                      | "*"
    +       instance-length           = 1*DIGIT
    +
    +   The header SHOULD indicate the total length of the full entity-body,
    +   unless this length is unknown or difficult to determine. The asterisk
    +   "*" character means that the instance-length is unknown at the time
    +   when the response was generated.
    +
    +   Unlike byte-ranges-specifier values (see section 14.35.1), a byte-
    +   range-resp-spec MUST only specify one range, and MUST contain
    +   absolute byte positions for both the first and last byte of the
    +   range.
    +
    +   A byte-content-range-spec with a byte-range-resp-spec whose last-
    +   byte-pos value is less than its first-byte-pos value, or whose
    +   instance-length value is less than or equal to its last-byte-pos
    +   value, is invalid. The recipient of an invalid byte-content-range-
    +   spec MUST ignore it and any content transferred along with it.
    +
    +   A server sending a response with status code 416 (Requested range not
    +   satisfiable) SHOULD include a Content-Range field with a byte-range-
    +   resp-spec of "*". The instance-length specifies the current length of
    +
    +   the selected resource. A response with status code 206 (Partial
    +   Content) MUST NOT include a Content-Range field with a byte-range-
    +   resp-spec of "*".
    +
    +   Examples of byte-content-range-spec values, assuming that the entity
    +   contains a total of 1234 bytes:
    +
    +      . The first 500 bytes:
    +       bytes 0-499/1234
    +
    +      . The second 500 bytes:
    +       bytes 500-999/1234
    +
    +      . All except for the first 500 bytes:
    +       bytes 500-1233/1234
    +
    +      . The last 500 bytes:
    +       bytes 734-1233/1234
    +
    +   When an HTTP message includes the content of a single range (for
    +   example, a response to a request for a single range, or to a request
    +   for a set of ranges that overlap without any holes), this content is
    +   transmitted with a Content-Range header, and a Content-Length header
    +   showing the number of bytes actually transferred. For example,
    +
    +       HTTP/1.1 206 Partial content
    +       Date: Wed, 15 Nov 1995 06:25:24 GMT
    +       Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT
    +       Content-Range: bytes 21010-47021/47022
    +       Content-Length: 26012
    +       Content-Type: image/gif
    +
    +   When an HTTP message includes the content of multiple ranges (for
    +   example, a response to a request for multiple non-overlapping
    +   ranges), these are transmitted as a multipart message. The multipart
    +   media type used for this purpose is "multipart/byteranges" as defined
    +   in appendix 19.2. See appendix 19.6.3 for a compatibility issue.
    +
    +   A response to a request for a single range MUST NOT be sent using the
    +   multipart/byteranges media type.  A response to a request for
    +   multiple ranges, whose result is a single range, MAY be sent as a
    +   multipart/byteranges media type with one part. A client that cannot
    +   decode a multipart/byteranges message MUST NOT ask for multiple
    +   byte-ranges in a single request.
    +
    +   When a client requests multiple byte-ranges in one request, the
    +   server SHOULD return them in the order that they appeared in the
    +   request.
    +
    +   If the server ignores a byte-range-spec because it is syntactically
    +   invalid, the server SHOULD treat the request as if the invalid Range
    +   header field did not exist. (Normally, this means return a 200
    +   response containing the full entity).
    +
    +   If the server receives a request (other than one including an If-
    +   Range request-header field) with an unsatisfiable Range request-
    +   header field (that is, all of whose byte-range-spec values have a
    +   first-byte-pos value greater than the current length of the selected
    +   resource), it SHOULD return a response code of 416 (Requested range
    +   not satisfiable) (section 10.4.17).
    +
    +      Note: clients cannot depend on servers to send a 416 (Requested
    +      range not satisfiable) response instead of a 200 (OK) response for
    +      an unsatisfiable Range request-header, since not all servers
    +      implement this request-header.
    +
    +14.17 Content-Type
    +
    +   The Content-Type entity-header field indicates the media type of the
    +   entity-body sent to the recipient or, in the case of the HEAD method,
    +   the media type that would have been sent had the request been a GET.
    +
    +       Content-Type   = "Content-Type" ":" media-type
    +
    +   Media types are defined in section 3.7. An example of the field is
    +
    +       Content-Type: text/html; charset=ISO-8859-4
    +
    +   Further discussion of methods for identifying the media type of an
    +   entity is provided in section 7.2.1.
    +
    +14.18 Date
    +
    +   The Date general-header field represents the date and time at which
    +   the message was originated, having the same semantics as orig-date in
    +   RFC 822. The field value is an HTTP-date, as described in section
    +   3.3.1; it MUST be sent in RFC 1123 [8]-date format.
    +
    +       Date  = "Date" ":" HTTP-date
    +
    +   An example is
    +
    +       Date: Tue, 15 Nov 1994 08:12:31 GMT
    +
    +   Origin servers MUST include a Date header field in all responses,
    +   except in these cases:
    +
    +      1. If the response status code is 100 (Continue) or 101 (Switching
    +         Protocols), the response MAY include a Date header field, at
    +         the server's option.
    +
    +      2. If the response status code conveys a server error, e.g. 500
    +         (Internal Server Error) or 503 (Service Unavailable), and it is
    +         inconvenient or impossible to generate a valid Date.
    +
    +      3. If the server does not have a clock that can provide a
    +         reasonable approximation of the current time, its responses
    +         MUST NOT include a Date header field. In this case, the rules
    +         in section 14.18.1 MUST be followed.
    +
    +   A received message that does not have a Date header field MUST be
    +   assigned one by the recipient if the message will be cached by that
    +   recipient or gatewayed via a protocol which requires a Date. An HTTP
    +   implementation without a clock MUST NOT cache responses without
    +   revalidating them on every use. An HTTP cache, especially a shared
    +   cache, SHOULD use a mechanism, such as NTP [28], to synchronize its
    +   clock with a reliable external standard.
    +
    +   Clients SHOULD only send a Date header field in messages that include
    +   an entity-body, as in the case of the PUT and POST requests, and even
    +   then it is optional. A client without a clock MUST NOT send a Date
    +   header field in a request.
    +
    +   The HTTP-date sent in a Date header SHOULD NOT represent a date and
    +   time subsequent to the generation of the message. It SHOULD represent
    +   the best available approximation of the date and time of message
    +   generation, unless the implementation has no means of generating a
    +   reasonably accurate date and time. In theory, the date ought to
    +   represent the moment just before the entity is generated. In
    +   practice, the date can be generated at any time during the message
    +   origination without affecting its semantic value.
    +
    +14.18.1 Clockless Origin Server Operation
    +
    +   Some origin server implementations might not have a clock available.
    +   An origin server without a clock MUST NOT assign Expires or Last-
    +   Modified values to a response, unless these values were associated
    +   with the resource by a system or user with a reliable clock. It MAY
    +   assign an Expires value that is known, at or before server
    +   configuration time, to be in the past (this allows "pre-expiration"
    +   of responses without storing separate Expires values for each
    +   resource).
    +
    +14.19 ETag
    +
    +   The ETag response-header field provides the current value of the
    +   entity tag for the requested variant. The headers used with entity
    +   tags are described in sections 14.24, 14.26 and 14.44. The entity tag
    +   MAY be used for comparison with other entities from the same resource
    +   (see section 13.3.3).
    +
    +      ETag = "ETag" ":" entity-tag
    +
    +   Examples:
    +
    +      ETag: "xyzzy"
    +      ETag: W/"xyzzy"
    +      ETag: ""
    +
    +14.20 Expect
    +
    +   The Expect request-header field is used to indicate that particular
    +   server behaviors are required by the client.
    +
    +      Expect       =  "Expect" ":" 1#expectation
    +
    +      expectation  =  "100-continue" | expectation-extension
    +      expectation-extension =  token [ "=" ( token | quoted-string )
    +                               *expect-params ]
    +      expect-params =  ";" token [ "=" ( token | quoted-string ) ]
    +
    +   A server that does not understand or is unable to comply with any of
    +   the expectation values in the Expect field of a request MUST respond
    +   with appropriate error status. The server MUST respond with a 417
    +   (Expectation Failed) status if any of the expectations cannot be met
    +   or, if there are other problems with the request, some other 4xx
    +   status.
    +
    +   This header field is defined with extensible syntax to allow for
    +   future extensions. If a server receives a request containing an
    +   Expect field that includes an expectation-extension that it does not
    +   support, it MUST respond with a 417 (Expectation Failed) status.
    +
    +   Comparison of expectation values is case-insensitive for unquoted
    +   tokens (including the 100-continue token), and is case-sensitive for
    +   quoted-string expectation-extensions.
    +
    +   The Expect mechanism is hop-by-hop: that is, an HTTP/1.1 proxy MUST
    +   return a 417 (Expectation Failed) status if it receives a request
    +   with an expectation that it cannot meet. However, the Expect
    +   request-header itself is end-to-end; it MUST be forwarded if the
    +   request is forwarded.
    +
    +   Many older HTTP/1.0 and HTTP/1.1 applications do not understand the
    +   Expect header.
    +
    +   See section 8.2.3 for the use of the 100 (continue) status.
    +
    +14.21 Expires
    +
    +   The Expires entity-header field gives the date/time after which the
    +   response is considered stale. A stale cache entry may not normally be
    +   returned by a cache (either a proxy cache or a user agent cache)
    +   unless it is first validated with the origin server (or with an
    +   intermediate cache that has a fresh copy of the entity). See section
    +   13.2 for further discussion of the expiration model.
    +
    +   The presence of an Expires field does not imply that the original
    +   resource will change or cease to exist at, before, or after that
    +   time.
    +
    +   The format is an absolute date and time as defined by HTTP-date in
    +   section 3.3.1; it MUST be in RFC 1123 date format:
    +
    +      Expires = "Expires" ":" HTTP-date
    +
    +   An example of its use is
    +
    +      Expires: Thu, 01 Dec 1994 16:00:00 GMT
    +
    +      Note: if a response includes a Cache-Control field with the max-
    +      age directive (see section 14.9.3), that directive overrides the
    +      Expires field.
    +
    +   HTTP/1.1 clients and caches MUST treat other invalid date formats,
    +   especially including the value "0", as in the past (i.e., "already
    +   expired").
    +
    +   To mark a response as "already expired," an origin server sends an
    +   Expires date that is equal to the Date header value. (See the rules
    +   for expiration calculations in section 13.2.4.)
    +
    +   To mark a response as "never expires," an origin server sends an
    +   Expires date approximately one year from the time the response is
    +   sent. HTTP/1.1 servers SHOULD NOT send Expires dates more than one
    +   year in the future.
    +
    +   The presence of an Expires header field with a date value of some
    +   time in the future on a response that otherwise would by default be
    +   non-cacheable indicates that the response is cacheable, unless
    +   indicated otherwise by a Cache-Control header field (section 14.9).
    +
    +14.22 From
    +
    +   The From request-header field, if given, SHOULD contain an Internet
    +   e-mail address for the human user who controls the requesting user
    +   agent. The address SHOULD be machine-usable, as defined by "mailbox"
    +   in RFC 822 [9] as updated by RFC 1123 [8]:
    +
    +       From   = "From" ":" mailbox
    +
    +   An example is:
    +
    +       From: webmaster@w3.org
    +
    +   This header field MAY be used for logging purposes and as a means for
    +   identifying the source of invalid or unwanted requests. It SHOULD NOT
    +   be used as an insecure form of access protection. The interpretation
    +   of this field is that the request is being performed on behalf of the
    +   person given, who accepts responsibility for the method performed. In
    +   particular, robot agents SHOULD include this header so that the
    +   person responsible for running the robot can be contacted if problems
    +   occur on the receiving end.
    +
    +   The Internet e-mail address in this field MAY be separate from the
    +   Internet host which issued the request. For example, when a request
    +   is passed through a proxy the original issuer's address SHOULD be
    +   used.
    +
    +   The client SHOULD NOT send the From header field without the user's
    +   approval, as it might conflict with the user's privacy interests or
    +   their site's security policy. It is strongly recommended that the
    +   user be able to disable, enable, and modify the value of this field
    +   at any time prior to a request.
    +
    +14.23 Host
    +
    +   The Host request-header field specifies the Internet host and port
    +   number of the resource being requested, as obtained from the original
    +   URI given by the user or referring resource (generally an HTTP URL,
    +
    +   as described in section 3.2.2). The Host field value MUST represent
    +   the naming authority of the origin server or gateway given by the
    +   original URL. This allows the origin server or gateway to
    +   differentiate between internally-ambiguous URLs, such as the root "/"
    +   URL of a server for multiple host names on a single IP address.
    +
    +       Host = "Host" ":" host [ ":" port ] ; Section 3.2.2
    +
    +   A "host" without any trailing port information implies the default
    +   port for the service requested (e.g., "80" for an HTTP URL). For
    +   example, a request on the origin server for
    +   <http://www.w3.org/pub/WWW/> would properly include:
    +
    +       GET /pub/WWW/ HTTP/1.1
    +       Host: www.w3.org
    +
    +   A client MUST include a Host header field in all HTTP/1.1 request
    +   messages . If the requested URI does not include an Internet host
    +   name for the service being requested, then the Host header field MUST
    +   be given with an empty value. An HTTP/1.1 proxy MUST ensure that any
    +   request message it forwards does contain an appropriate Host header
    +   field that identifies the service being requested by the proxy. All
    +   Internet-based HTTP/1.1 servers MUST respond with a 400 (Bad Request)
    +   status code to any HTTP/1.1 request message which lacks a Host header
    +   field.
    +
    +   See sections 5.2 and 19.6.1.1 for other requirements relating to
    +   Host.
    +
    +14.24 If-Match
    +
    +   The If-Match request-header field is used with a method to make it
    +   conditional. A client that has one or more entities previously
    +   obtained from the resource can verify that one of those entities is
    +   current by including a list of their associated entity tags in the
    +   If-Match header field. Entity tags are defined in section 3.11. The
    +   purpose of this feature is to allow efficient updates of cached
    +   information with a minimum amount of transaction overhead. It is also
    +   used, on updating requests, to prevent inadvertent modification of
    +   the wrong version of a resource. As a special case, the value "*"
    +   matches any current entity of the resource.
    +
    +       If-Match = "If-Match" ":" ( "*" | 1#entity-tag )
    +
    +   If any of the entity tags match the entity tag of the entity that
    +   would have been returned in the response to a similar GET request
    +   (without the If-Match header) on that resource, or if "*" is given
    +
    +   and any current entity exists for that resource, then the server MAY
    +   perform the requested method as if the If-Match header field did not
    +   exist.
    +
    +   A server MUST use the strong comparison function (see section 13.3.3)
    +   to compare the entity tags in If-Match.
    +
    +   If none of the entity tags match, or if "*" is given and no current
    +   entity exists, the server MUST NOT perform the requested method, and
    +   MUST return a 412 (Precondition Failed) response. This behavior is
    +   most useful when the client wants to prevent an updating method, such
    +   as PUT, from modifying a resource that has changed since the client
    +   last retrieved it.
    +
    +   If the request would, without the If-Match header field, result in
    +   anything other than a 2xx or 412 status, then the If-Match header
    +   MUST be ignored.
    +
    +   The meaning of "If-Match: *" is that the method SHOULD be performed
    +   if the representation selected by the origin server (or by a cache,
    +   possibly using the Vary mechanism, see section 14.44) exists, and
    +   MUST NOT be performed if the representation does not exist.
    +
    +   A request intended to update a resource (e.g., a PUT) MAY include an
    +   If-Match header field to signal that the request method MUST NOT be
    +   applied if the entity corresponding to the If-Match value (a single
    +   entity tag) is no longer a representation of that resource. This
    +   allows the user to indicate that they do not wish the request to be
    +   successful if the resource has been changed without their knowledge.
    +   Examples:
    +
    +       If-Match: "xyzzy"
    +       If-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
    +       If-Match: *
    +
    +   The result of a request having both an If-Match header field and
    +   either an If-None-Match or an If-Modified-Since header fields is
    +   undefined by this specification.
    +
    +14.25 If-Modified-Since
    +
    +   The If-Modified-Since request-header field is used with a method to
    +   make it conditional: if the requested variant has not been modified
    +   since the time specified in this field, an entity will not be
    +   returned from the server; instead, a 304 (not modified) response will
    +   be returned without any message-body.
    +
    +       If-Modified-Since = "If-Modified-Since" ":" HTTP-date
    +
    +   An example of the field is:
    +
    +       If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
    +
    +   A GET method with an If-Modified-Since header and no Range header
    +   requests that the identified entity be transferred only if it has
    +   been modified since the date given by the If-Modified-Since header.
    +   The algorithm for determining this includes the following cases:
    +
    +      a) If the request would normally result in anything other than a
    +         200 (OK) status, or if the passed If-Modified-Since date is
    +         invalid, the response is exactly the same as for a normal GET.
    +         A date which is later than the server's current time is
    +         invalid.
    +
    +      b) If the variant has been modified since the If-Modified-Since
    +         date, the response is exactly the same as for a normal GET.
    +
    +      c) If the variant has not been modified since a valid If-
    +         Modified-Since date, the server SHOULD return a 304 (Not
    +         Modified) response.
    +
    +   The purpose of this feature is to allow efficient updates of cached
    +   information with a minimum amount of transaction overhead.
    +
    +      Note: The Range request-header field modifies the meaning of If-
    +      Modified-Since; see section 14.35 for full details.
    +
    +      Note: If-Modified-Since times are interpreted by the server, whose
    +      clock might not be synchronized with the client.
    +
    +      Note: When handling an If-Modified-Since header field, some
    +      servers will use an exact date comparison function, rather than a
    +      less-than function, for deciding whether to send a 304 (Not
    +      Modified) response. To get best results when sending an If-
    +      Modified-Since header field for cache validation, clients are
    +      advised to use the exact date string received in a previous Last-
    +      Modified header field whenever possible.
    +
    +      Note: If a client uses an arbitrary date in the If-Modified-Since
    +      header instead of a date taken from the Last-Modified header for
    +      the same request, the client should be aware of the fact that this
    +      date is interpreted in the server's understanding of time. The
    +      client should consider unsynchronized clocks and rounding problems
    +      due to the different encodings of time between the client and
    +      server. This includes the possibility of race conditions if the
    +      document has changed between the time it was first requested and
    +      the If-Modified-Since date of a subsequent request, and the
    +
    +      possibility of clock-skew-related problems if the If-Modified-
    +      Since date is derived from the client's clock without correction
    +      to the server's clock. Corrections for different time bases
    +      between client and server are at best approximate due to network
    +      latency.
    +
    +   The result of a request having both an If-Modified-Since header field
    +   and either an If-Match or an If-Unmodified-Since header fields is
    +   undefined by this specification.
    +
    +14.26 If-None-Match
    +
    +   The If-None-Match request-header field is used with a method to make
    +   it conditional. A client that has one or more entities previously
    +   obtained from the resource can verify that none of those entities is
    +   current by including a list of their associated entity tags in the
    +   If-None-Match header field. The purpose of this feature is to allow
    +   efficient updates of cached information with a minimum amount of
    +   transaction overhead. It is also used to prevent a method (e.g. PUT)
    +   from inadvertently modifying an existing resource when the client
    +   believes that the resource does not exist.
    +
    +   As a special case, the value "*" matches any current entity of the
    +   resource.
    +
    +       If-None-Match = "If-None-Match" ":" ( "*" | 1#entity-tag )
    +
    +   If any of the entity tags match the entity tag of the entity that
    +   would have been returned in the response to a similar GET request
    +   (without the If-None-Match header) on that resource, or if "*" is
    +   given and any current entity exists for that resource, then the
    +   server MUST NOT perform the requested method, unless required to do
    +   so because the resource's modification date fails to match that
    +   supplied in an If-Modified-Since header field in the request.
    +   Instead, if the request method was GET or HEAD, the server SHOULD
    +   respond with a 304 (Not Modified) response, including the cache-
    +   related header fields (particularly ETag) of one of the entities that
    +   matched. For all other request methods, the server MUST respond with
    +   a status of 412 (Precondition Failed).
    +
    +   See section 13.3.3 for rules on how to determine if two entities tags
    +   match. The weak comparison function can only be used with GET or HEAD
    +   requests.
    +
    +   If none of the entity tags match, then the server MAY perform the
    +   requested method as if the If-None-Match header field did not exist,
    +   but MUST also ignore any If-Modified-Since header field(s) in the
    +   request. That is, if no entity tags match, then the server MUST NOT
    +   return a 304 (Not Modified) response.
    +
    +   If the request would, without the If-None-Match header field, result
    +   in anything other than a 2xx or 304 status, then the If-None-Match
    +   header MUST be ignored. (See section 13.3.4 for a discussion of
    +   server behavior when both If-Modified-Since and If-None-Match appear
    +   in the same request.)
    +
    +   The meaning of "If-None-Match: *" is that the method MUST NOT be
    +   performed if the representation selected by the origin server (or by
    +   a cache, possibly using the Vary mechanism, see section 14.44)
    +   exists, and SHOULD be performed if the representation does not exist.
    +   This feature is intended to be useful in preventing races between PUT
    +   operations.
    +
    +   Examples:
    +
    +       If-None-Match: "xyzzy"
    +       If-None-Match: W/"xyzzy"
    +       If-None-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
    +       If-None-Match: W/"xyzzy", W/"r2d2xxxx", W/"c3piozzzz"
    +       If-None-Match: *
    +
    +   The result of a request having both an If-None-Match header field and
    +   either an If-Match or an If-Unmodified-Since header fields is
    +   undefined by this specification.
    +
    +14.27 If-Range
    +
    +   If a client has a partial copy of an entity in its cache, and wishes
    +   to have an up-to-date copy of the entire entity in its cache, it
    +   could use the Range request-header with a conditional GET (using
    +   either or both of If-Unmodified-Since and If-Match.) However, if the
    +   condition fails because the entity has been modified, the client
    +   would then have to make a second request to obtain the entire current
    +   entity-body.
    +
    +   The If-Range header allows a client to "short-circuit" the second
    +   request. Informally, its meaning is `if the entity is unchanged, send
    +   me the part(s) that I am missing; otherwise, send me the entire new
    +   entity'.
    +
    +        If-Range = "If-Range" ":" ( entity-tag | HTTP-date )
    +
    +   If the client has no entity tag for an entity, but does have a Last-
    +   Modified date, it MAY use that date in an If-Range header. (The
    +   server can distinguish between a valid HTTP-date and any form of
    +   entity-tag by examining no more than two characters.) The If-Range
    +   header SHOULD only be used together with a Range header, and MUST be
    +   ignored if the request does not include a Range header, or if the
    +   server does not support the sub-range operation.
    +
    +   If the entity tag given in the If-Range header matches the current
    +   entity tag for the entity, then the server SHOULD provide the
    +   specified sub-range of the entity using a 206 (Partial content)
    +   response. If the entity tag does not match, then the server SHOULD
    +   return the entire entity using a 200 (OK) response.
    +
    +14.28 If-Unmodified-Since
    +
    +   The If-Unmodified-Since request-header field is used with a method to
    +   make it conditional. If the requested resource has not been modified
    +   since the time specified in this field, the server SHOULD perform the
    +   requested operation as if the If-Unmodified-Since header were not
    +   present.
    +
    +   If the requested variant has been modified since the specified time,
    +   the server MUST NOT perform the requested operation, and MUST return
    +   a 412 (Precondition Failed).
    +
    +      If-Unmodified-Since = "If-Unmodified-Since" ":" HTTP-date
    +
    +   An example of the field is:
    +
    +       If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT
    +
    +   If the request normally (i.e., without the If-Unmodified-Since
    +   header) would result in anything other than a 2xx or 412 status, the
    +   If-Unmodified-Since header SHOULD be ignored.
    +
    +   If the specified date is invalid, the header is ignored.
    +
    +   The result of a request having both an If-Unmodified-Since header
    +   field and either an If-None-Match or an If-Modified-Since header
    +   fields is undefined by this specification.
    +
    +14.29 Last-Modified
    +
    +   The Last-Modified entity-header field indicates the date and time at
    +   which the origin server believes the variant was last modified.
    +
    +       Last-Modified  = "Last-Modified" ":" HTTP-date
    +
    +   An example of its use is
    +
    +       Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT
    +
    +   The exact meaning of this header field depends on the implementation
    +   of the origin server and the nature of the original resource. For
    +   files, it may be just the file system last-modified time. For
    +   entities with dynamically included parts, it may be the most recent
    +   of the set of last-modify times for its component parts. For database
    +   gateways, it may be the last-update time stamp of the record. For
    +   virtual objects, it may be the last time the internal state changed.
    +
    +   An origin server MUST NOT send a Last-Modified date which is later
    +   than the server's time of message origination. In such cases, where
    +   the resource's last modification would indicate some time in the
    +   future, the server MUST replace that date with the message
    +   origination date.
    +
    +   An origin server SHOULD obtain the Last-Modified value of the entity
    +   as close as possible to the time that it generates the Date value of
    +   its response. This allows a recipient to make an accurate assessment
    +   of the entity's modification time, especially if the entity changes
    +   near the time that the response is generated.
    +
    +   HTTP/1.1 servers SHOULD send Last-Modified whenever feasible.
    +
    +14.30 Location
    +
    +   The Location response-header field is used to redirect the recipient
    +   to a location other than the Request-URI for completion of the
    +   request or identification of a new resource. For 201 (Created)
    +   responses, the Location is that of the new resource which was created
    +   by the request. For 3xx responses, the location SHOULD indicate the
    +   server's preferred URI for automatic redirection to the resource. The
    +   field value consists of a single absolute URI.
    +
    +       Location       = "Location" ":" absoluteURI
    +
    +   An example is:
    +
    +       Location: http://www.w3.org/pub/WWW/People.html
    +
    +      Note: The Content-Location header field (section 14.14) differs
    +      from Location in that the Content-Location identifies the original
    +      location of the entity enclosed in the request. It is therefore
    +      possible for a response to contain header fields for both Location
    +      and Content-Location. Also see section 13.10 for cache
    +      requirements of some methods.
    +
    +14.31 Max-Forwards
    +
    +   The Max-Forwards request-header field provides a mechanism with the
    +   TRACE (section 9.8) and OPTIONS (section 9.2) methods to limit the
    +   number of proxies or gateways that can forward the request to the
    +   next inbound server. This can be useful when the client is attempting
    +   to trace a request chain which appears to be failing or looping in
    +   mid-chain.
    +
    +       Max-Forwards   = "Max-Forwards" ":" 1*DIGIT
    +
    +   The Max-Forwards value is a decimal integer indicating the remaining
    +   number of times this request message may be forwarded.
    +
    +   Each proxy or gateway recipient of a TRACE or OPTIONS request
    +   containing a Max-Forwards header field MUST check and update its
    +   value prior to forwarding the request. If the received value is zero
    +   (0), the recipient MUST NOT forward the request; instead, it MUST
    +   respond as the final recipient. If the received Max-Forwards value is
    +   greater than zero, then the forwarded message MUST contain an updated
    +   Max-Forwards field with a value decremented by one (1).
    +
    +   The Max-Forwards header field MAY be ignored for all other methods
    +   defined by this specification and for any extension methods for which
    +   it is not explicitly referred to as part of that method definition.
    +
    +14.32 Pragma
    +
    +   The Pragma general-header field is used to include implementation-
    +   specific directives that might apply to any recipient along the
    +   request/response chain. All pragma directives specify optional
    +   behavior from the viewpoint of the protocol; however, some systems
    +   MAY require that behavior be consistent with the directives.
    +
    +       Pragma            = "Pragma" ":" 1#pragma-directive
    +       pragma-directive  = "no-cache" | extension-pragma
    +       extension-pragma  = token [ "=" ( token | quoted-string ) ]
    +
    +   When the no-cache directive is present in a request message, an
    +   application SHOULD forward the request toward the origin server even
    +   if it has a cached copy of what is being requested. This pragma
    +   directive has the same semantics as the no-cache cache-directive (see
    +   section 14.9) and is defined here for backward compatibility with
    +   HTTP/1.0. Clients SHOULD include both header fields when a no-cache
    +   request is sent to a server not known to be HTTP/1.1 compliant.
    +
    +   Pragma directives MUST be passed through by a proxy or gateway
    +   application, regardless of their significance to that application,
    +   since the directives might be applicable to all recipients along the
    +   request/response chain. It is not possible to specify a pragma for a
    +   specific recipient; however, any pragma directive not relevant to a
    +   recipient SHOULD be ignored by that recipient.
    +
    +   HTTP/1.1 caches SHOULD treat "Pragma: no-cache" as if the client had
    +   sent "Cache-Control: no-cache". No new Pragma directives will be
    +   defined in HTTP.
    +
    +      Note: because the meaning of "Pragma: no-cache as a response
    +      header field is not actually specified, it does not provide a
    +      reliable replacement for "Cache-Control: no-cache" in a response
    +
    +14.33 Proxy-Authenticate
    +
    +   The Proxy-Authenticate response-header field MUST be included as part
    +   of a 407 (Proxy Authentication Required) response. The field value
    +   consists of a challenge that indicates the authentication scheme and
    +   parameters applicable to the proxy for this Request-URI.
    +
    +       Proxy-Authenticate  = "Proxy-Authenticate" ":" 1#challenge
    +
    +   The HTTP access authentication process is described in "HTTP
    +   Authentication: Basic and Digest Access Authentication" [43]. Unlike
    +   WWW-Authenticate, the Proxy-Authenticate header field applies only to
    +   the current connection and SHOULD NOT be passed on to downstream
    +   clients. However, an intermediate proxy might need to obtain its own
    +   credentials by requesting them from the downstream client, which in
    +   some circumstances will appear as if the proxy is forwarding the
    +   Proxy-Authenticate header field.
    +
    +14.34 Proxy-Authorization
    +
    +   The Proxy-Authorization request-header field allows the client to
    +   identify itself (or its user) to a proxy which requires
    +   authentication. The Proxy-Authorization field value consists of
    +   credentials containing the authentication information of the user
    +   agent for the proxy and/or realm of the resource being requested.
    +
    +       Proxy-Authorization     = "Proxy-Authorization" ":" credentials
    +
    +   The HTTP access authentication process is described in "HTTP
    +   Authentication: Basic and Digest Access Authentication" [43] . Unlike
    +   Authorization, the Proxy-Authorization header field applies only to
    +   the next outbound proxy that demanded authentication using the Proxy-
    +   Authenticate field. When multiple proxies are used in a chain, the
    +
    +   Proxy-Authorization header field is consumed by the first outbound
    +   proxy that was expecting to receive credentials. A proxy MAY relay
    +   the credentials from the client request to the next proxy if that is
    +   the mechanism by which the proxies cooperatively authenticate a given
    +   request.
    +
    +14.35 Range
    +
    +14.35.1 Byte Ranges
    +
    +   Since all HTTP entities are represented in HTTP messages as sequences
    +   of bytes, the concept of a byte range is meaningful for any HTTP
    +   entity. (However, not all clients and servers need to support byte-
    +   range operations.)
    +
    +   Byte range specifications in HTTP apply to the sequence of bytes in
    +   the entity-body (not necessarily the same as the message-body).
    +
    +   A byte range operation MAY specify a single range of bytes, or a set
    +   of ranges within a single entity.
    +
    +       ranges-specifier = byte-ranges-specifier
    +       byte-ranges-specifier = bytes-unit "=" byte-range-set
    +       byte-range-set  = 1#( byte-range-spec | suffix-byte-range-spec )
    +       byte-range-spec = first-byte-pos "-" [last-byte-pos]
    +       first-byte-pos  = 1*DIGIT
    +       last-byte-pos   = 1*DIGIT
    +
    +   The first-byte-pos value in a byte-range-spec gives the byte-offset
    +   of the first byte in a range. The last-byte-pos value gives the
    +   byte-offset of the last byte in the range; that is, the byte
    +   positions specified are inclusive. Byte offsets start at zero.
    +
    +   If the last-byte-pos value is present, it MUST be greater than or
    +   equal to the first-byte-pos in that byte-range-spec, or the byte-
    +   range-spec is syntactically invalid. The recipient of a byte-range-
    +   set that includes one or more syntactically invalid byte-range-spec
    +   values MUST ignore the header field that includes that byte-range-
    +   set.
    +
    +   If the last-byte-pos value is absent, or if the value is greater than
    +   or equal to the current length of the entity-body, last-byte-pos is
    +   taken to be equal to one less than the current length of the entity-
    +   body in bytes.
    +
    +   By its choice of last-byte-pos, a client can limit the number of
    +   bytes retrieved without knowing the size of the entity.
    +
    +       suffix-byte-range-spec = "-" suffix-length
    +       suffix-length = 1*DIGIT
    +
    +   A suffix-byte-range-spec is used to specify the suffix of the
    +   entity-body, of a length given by the suffix-length value. (That is,
    +   this form specifies the last N bytes of an entity-body.) If the
    +   entity is shorter than the specified suffix-length, the entire
    +   entity-body is used.
    +
    +   If a syntactically valid byte-range-set includes at least one byte-
    +   range-spec whose first-byte-pos is less than the current length of
    +   the entity-body, or at least one suffix-byte-range-spec with a non-
    +   zero suffix-length, then the byte-range-set is satisfiable.
    +   Otherwise, the byte-range-set is unsatisfiable. If the byte-range-set
    +   is unsatisfiable, the server SHOULD return a response with a status
    +   of 416 (Requested range not satisfiable). Otherwise, the server
    +   SHOULD return a response with a status of 206 (Partial Content)
    +   containing the satisfiable ranges of the entity-body.
    +
    +   Examples of byte-ranges-specifier values (assuming an entity-body of
    +   length 10000):
    +
    +      - The first 500 bytes (byte offsets 0-499, inclusive):  bytes=0-
    +        499
    +
    +      - The second 500 bytes (byte offsets 500-999, inclusive):
    +        bytes=500-999
    +
    +      - The final 500 bytes (byte offsets 9500-9999, inclusive):
    +        bytes=-500
    +
    +      - Or bytes=9500-
    +
    +      - The first and last bytes only (bytes 0 and 9999):  bytes=0-0,-1
    +
    +      - Several legal but not canonical specifications of the second 500
    +        bytes (byte offsets 500-999, inclusive):
    +         bytes=500-600,601-999
    +         bytes=500-700,601-999
    +
    +14.35.2 Range Retrieval Requests
    +
    +   HTTP retrieval requests using conditional or unconditional GET
    +   methods MAY request one or more sub-ranges of the entity, instead of
    +   the entire entity, using the Range request header, which applies to
    +   the entity returned as the result of the request:
    +
    +      Range = "Range" ":" ranges-specifier
    +
    +   A server MAY ignore the Range header. However, HTTP/1.1 origin
    +   servers and intermediate caches ought to support byte ranges when
    +   possible, since Range supports efficient recovery from partially
    +   failed transfers, and supports efficient partial retrieval of large
    +   entities.
    +
    +   If the server supports the Range header and the specified range or
    +   ranges are appropriate for the entity:
    +
    +      - The presence of a Range header in an unconditional GET modifies
    +        what is returned if the GET is otherwise successful. In other
    +        words, the response carries a status code of 206 (Partial
    +        Content) instead of 200 (OK).
    +
    +      - The presence of a Range header in a conditional GET (a request
    +        using one or both of If-Modified-Since and If-None-Match, or
    +        one or both of If-Unmodified-Since and If-Match) modifies what
    +        is returned if the GET is otherwise successful and the
    +        condition is true. It does not affect the 304 (Not Modified)
    +        response returned if the conditional is false.
    +
    +   In some cases, it might be more appropriate to use the If-Range
    +   header (see section 14.27) in addition to the Range header.
    +
    +   If a proxy that supports ranges receives a Range request, forwards
    +   the request to an inbound server, and receives an entire entity in
    +   reply, it SHOULD only return the requested range to its client. It
    +   SHOULD store the entire received response in its cache if that is
    +   consistent with its cache allocation policies.
    +
    +14.36 Referer
    +
    +   The Referer[sic] request-header field allows the client to specify,
    +   for the server's benefit, the address (URI) of the resource from
    +   which the Request-URI was obtained (the "referrer", although the
    +   header field is misspelled.) The Referer request-header allows a
    +   server to generate lists of back-links to resources for interest,
    +   logging, optimized caching, etc. It also allows obsolete or mistyped
    +   links to be traced for maintenance. The Referer field MUST NOT be
    +   sent if the Request-URI was obtained from a source that does not have
    +   its own URI, such as input from the user keyboard.
    +
    +       Referer        = "Referer" ":" ( absoluteURI | relativeURI )
    +
    +   Example:
    +
    +       Referer: http://www.w3.org/hypertext/DataSources/Overview.html
    +
    +   If the field value is a relative URI, it SHOULD be interpreted
    +   relative to the Request-URI. The URI MUST NOT include a fragment. See
    +   section 15.1.3 for security considerations.
    +
    +14.37 Retry-After
    +
    +   The Retry-After response-header field can be used with a 503 (Service
    +   Unavailable) response to indicate how long the service is expected to
    +   be unavailable to the requesting client. This field MAY also be used
    +   with any 3xx (Redirection) response to indicate the minimum time the
    +   user-agent is asked wait before issuing the redirected request. The
    +   value of this field can be either an HTTP-date or an integer number
    +   of seconds (in decimal) after the time of the response.
    +
    +       Retry-After  = "Retry-After" ":" ( HTTP-date | delta-seconds )
    +
    +   Two examples of its use are
    +
    +       Retry-After: Fri, 31 Dec 1999 23:59:59 GMT
    +       Retry-After: 120
    +
    +   In the latter example, the delay is 2 minutes.
    +
    +14.38 Server
    +
    +   The Server response-header field contains information about the
    +   software used by the origin server to handle the request. The field
    +   can contain multiple product tokens (section 3.8) and comments
    +   identifying the server and any significant subproducts. The product
    +   tokens are listed in order of their significance for identifying the
    +   application.
    +
    +       Server         = "Server" ":" 1*( product | comment )
    +
    +   Example:
    +
    +       Server: CERN/3.0 libwww/2.17
    +
    +   If the response is being forwarded through a proxy, the proxy
    +   application MUST NOT modify the Server response-header. Instead, it
    +   SHOULD include a Via field (as described in section 14.45).
    +
    +      Note: Revealing the specific software version of the server might
    +      allow the server machine to become more vulnerable to attacks
    +      against software that is known to contain security holes. Server
    +      implementors are encouraged to make this field a configurable
    +      option.
    +
    +14.39 TE
    +
    +   The TE request-header field indicates what extension transfer-codings
    +   it is willing to accept in the response and whether or not it is
    +   willing to accept trailer fields in a chunked transfer-coding. Its
    +   value may consist of the keyword "trailers" and/or a comma-separated
    +   list of extension transfer-coding names with optional accept
    +   parameters (as described in section 3.6).
    +
    +       TE        = "TE" ":" #( t-codings )
    +       t-codings = "trailers" | ( transfer-extension [ accept-params ] )
    +
    +   The presence of the keyword "trailers" indicates that the client is
    +   willing to accept trailer fields in a chunked transfer-coding, as
    +   defined in section 3.6.1. This keyword is reserved for use with
    +   transfer-coding values even though it does not itself represent a
    +   transfer-coding.
    +
    +   Examples of its use are:
    +
    +       TE: deflate
    +       TE:
    +       TE: trailers, deflate;q=0.5
    +
    +   The TE header field only applies to the immediate connection.
    +   Therefore, the keyword MUST be supplied within a Connection header
    +   field (section 14.10) whenever TE is present in an HTTP/1.1 message.
    +
    +   A server tests whether a transfer-coding is acceptable, according to
    +   a TE field, using these rules:
    +
    +      1. The "chunked" transfer-coding is always acceptable. If the
    +         keyword "trailers" is listed, the client indicates that it is
    +         willing to accept trailer fields in the chunked response on
    +         behalf of itself and any downstream clients. The implication is
    +         that, if given, the client is stating that either all
    +         downstream clients are willing to accept trailer fields in the
    +         forwarded response, or that it will attempt to buffer the
    +         response on behalf of downstream recipients.
    +
    +         Note: HTTP/1.1 does not define any means to limit the size of a
    +         chunked response such that a client can be assured of buffering
    +         the entire response.
    +
    +      2. If the transfer-coding being tested is one of the transfer-
    +         codings listed in the TE field, then it is acceptable unless it
    +         is accompanied by a qvalue of 0. (As defined in section 3.9, a
    +         qvalue of 0 means "not acceptable.")
    +
    +      3. If multiple transfer-codings are acceptable, then the
    +         acceptable transfer-coding with the highest non-zero qvalue is
    +         preferred.  The "chunked" transfer-coding always has a qvalue
    +         of 1.
    +
    +   If the TE field-value is empty or if no TE field is present, the only
    +   transfer-coding  is "chunked". A message with no transfer-coding is
    +   always acceptable.
    +
    +14.40 Trailer
    +
    +   The Trailer general field value indicates that the given set of
    +   header fields is present in the trailer of a message encoded with
    +   chunked transfer-coding.
    +
    +       Trailer  = "Trailer" ":" 1#field-name
    +
    +   An HTTP/1.1 message SHOULD include a Trailer header field in a
    +   message using chunked transfer-coding with a non-empty trailer. Doing
    +   so allows the recipient to know which header fields to expect in the
    +   trailer.
    +
    +   If no Trailer header field is present, the trailer SHOULD NOT include
    +   any header fields. See section 3.6.1 for restrictions on the use of
    +   trailer fields in a "chunked" transfer-coding.
    +
    +   Message header fields listed in the Trailer header field MUST NOT
    +   include the following header fields:
    +
    +      . Transfer-Encoding
    +
    +      . Content-Length
    +
    +      . Trailer
    +
    +14.41 Transfer-Encoding
    +
    +   The Transfer-Encoding general-header field indicates what (if any)
    +   type of transformation has been applied to the message body in order
    +   to safely transfer it between the sender and the recipient. This
    +   differs from the content-coding in that the transfer-coding is a
    +   property of the message, not of the entity.
    +
    +     Transfer-Encoding       = "Transfer-Encoding" ":" 1#transfer-coding
    +
    +   Transfer-codings are defined in section 3.6. An example is:
    +
    +     Transfer-Encoding: chunked
    +
    +   If multiple encodings have been applied to an entity, the transfer-
    +   codings MUST be listed in the order in which they were applied.
    +   Additional information about the encoding parameters MAY be provided
    +   by other entity-header fields not defined by this specification.
    +
    +   Many older HTTP/1.0 applications do not understand the Transfer-
    +   Encoding header.
    +
    +14.42 Upgrade
    +
    +   The Upgrade general-header allows the client to specify what
    +   additional communication protocols it supports and would like to use
    +   if the server finds it appropriate to switch protocols. The server
    +   MUST use the Upgrade header field within a 101 (Switching Protocols)
    +   response to indicate which protocol(s) are being switched.
    +
    +       Upgrade        = "Upgrade" ":" 1#product
    +
    +   For example,
    +
    +       Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11
    +
    +   The Upgrade header field is intended to provide a simple mechanism
    +   for transition from HTTP/1.1 to some other, incompatible protocol. It
    +   does so by allowing the client to advertise its desire to use another
    +   protocol, such as a later version of HTTP with a higher major version
    +   number, even though the current request has been made using HTTP/1.1.
    +   This eases the difficult transition between incompatible protocols by
    +   allowing the client to initiate a request in the more commonly
    +   supported protocol while indicating to the server that it would like
    +   to use a "better" protocol if available (where "better" is determined
    +   by the server, possibly according to the nature of the method and/or
    +   resource being requested).
    +
    +   The Upgrade header field only applies to switching application-layer
    +   protocols upon the existing transport-layer connection. Upgrade
    +   cannot be used to insist on a protocol change; its acceptance and use
    +   by the server is optional. The capabilities and nature of the
    +   application-layer communication after the protocol change is entirely
    +   dependent upon the new protocol chosen, although the first action
    +   after changing the protocol MUST be a response to the initial HTTP
    +   request containing the Upgrade header field.
    +
    +   The Upgrade header field only applies to the immediate connection.
    +   Therefore, the upgrade keyword MUST be supplied within a Connection
    +   header field (section 14.10) whenever Upgrade is present in an
    +   HTTP/1.1 message.
    +
    +   The Upgrade header field cannot be used to indicate a switch to a
    +   protocol on a different connection. For that purpose, it is more
    +   appropriate to use a 301, 302, 303, or 305 redirection response.
    +
    +   This specification only defines the protocol name "HTTP" for use by
    +   the family of Hypertext Transfer Protocols, as defined by the HTTP
    +   version rules of section 3.1 and future updates to this
    +   specification. Any token can be used as a protocol name; however, it
    +   will only be useful if both the client and server associate the name
    +   with the same protocol.
    +
    +14.43 User-Agent
    +
    +   The User-Agent request-header field contains information about the
    +   user agent originating the request. This is for statistical purposes,
    +   the tracing of protocol violations, and automated recognition of user
    +   agents for the sake of tailoring responses to avoid particular user
    +   agent limitations. User agents SHOULD include this field with
    +   requests. The field can contain multiple product tokens (section 3.8)
    +   and comments identifying the agent and any subproducts which form a
    +   significant part of the user agent. By convention, the product tokens
    +   are listed in order of their significance for identifying the
    +   application.
    +
    +       User-Agent     = "User-Agent" ":" 1*( product | comment )
    +
    +   Example:
    +
    +       User-Agent: CERN-LineMode/2.15 libwww/2.17b3
    +
    +14.44 Vary
    +
    +   The Vary field value indicates the set of request-header fields that
    +   fully determines, while the response is fresh, whether a cache is
    +   permitted to use the response to reply to a subsequent request
    +   without revalidation. For uncacheable or stale responses, the Vary
    +   field value advises the user agent about the criteria that were used
    +   to select the representation. A Vary field value of "*" implies that
    +   a cache cannot determine from the request headers of a subsequent
    +   request whether this response is the appropriate representation. See
    +   section 13.6 for use of the Vary header field by caches.
    +
    +       Vary  = "Vary" ":" ( "*" | 1#field-name )
    +
    +   An HTTP/1.1 server SHOULD include a Vary header field with any
    +   cacheable response that is subject to server-driven negotiation.
    +   Doing so allows a cache to properly interpret future requests on that
    +   resource and informs the user agent about the presence of negotiation
    +
    +   on that resource. A server MAY include a Vary header field with a
    +   non-cacheable response that is subject to server-driven negotiation,
    +   since this might provide the user agent with useful information about
    +   the dimensions over which the response varies at the time of the
    +   response.
    +
    +   A Vary field value consisting of a list of field-names signals that
    +   the representation selected for the response is based on a selection
    +   algorithm which considers ONLY the listed request-header field values
    +   in selecting the most appropriate representation. A cache MAY assume
    +   that the same selection will be made for future requests with the
    +   same values for the listed field names, for the duration of time for
    +   which the response is fresh.
    +
    +   The field-names given are not limited to the set of standard
    +   request-header fields defined by this specification. Field names are
    +   case-insensitive.
    +
    +   A Vary field value of "*" signals that unspecified parameters not
    +   limited to the request-headers (e.g., the network address of the
    +   client), play a role in the selection of the response representation.
    +   The "*" value MUST NOT be generated by a proxy server; it may only be
    +   generated by an origin server.
    +
    +14.45  Via
    +
    +   The Via general-header field MUST be used by gateways and proxies to
    +   indicate the intermediate protocols and recipients between the user
    +   agent and the server on requests, and between the origin server and
    +   the client on responses. It is analogous to the "Received" field of
    +   RFC 822 [9] and is intended to be used for tracking message forwards,
    +   avoiding request loops, and identifying the protocol capabilities of
    +   all senders along the request/response chain.
    +
    +      Via =  "Via" ":" 1#( received-protocol received-by [ comment ] )
    +      received-protocol = [ protocol-name "/" ] protocol-version
    +      protocol-name     = token
    +      protocol-version  = token
    +      received-by       = ( host [ ":" port ] ) | pseudonym
    +      pseudonym         = token
    +
    +   The received-protocol indicates the protocol version of the message
    +   received by the server or client along each segment of the
    +   request/response chain. The received-protocol version is appended to
    +   the Via field value when the message is forwarded so that information
    +   about the protocol capabilities of upstream applications remains
    +   visible to all recipients.
    +
    +   The protocol-name is optional if and only if it would be "HTTP". The
    +   received-by field is normally the host and optional port number of a
    +   recipient server or client that subsequently forwarded the message.
    +   However, if the real host is considered to be sensitive information,
    +   it MAY be replaced by a pseudonym. If the port is not given, it MAY
    +   be assumed to be the default port of the received-protocol.
    +
    +   Multiple Via field values represents each proxy or gateway that has
    +   forwarded the message. Each recipient MUST append its information
    +   such that the end result is ordered according to the sequence of
    +   forwarding applications.
    +
    +   Comments MAY be used in the Via header field to identify the software
    +   of the recipient proxy or gateway, analogous to the User-Agent and
    +   Server header fields. However, all comments in the Via field are
    +   optional and MAY be removed by any recipient prior to forwarding the
    +   message.
    +
    +   For example, a request message could be sent from an HTTP/1.0 user
    +   agent to an internal proxy code-named "fred", which uses HTTP/1.1 to
    +   forward the request to a public proxy at nowhere.com, which completes
    +   the request by forwarding it to the origin server at www.ics.uci.edu.
    +   The request received by www.ics.uci.edu would then have the following
    +   Via header field:
    +
    +       Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1)
    +
    +   Proxies and gateways used as a portal through a network firewall
    +   SHOULD NOT, by default, forward the names and ports of hosts within
    +   the firewall region. This information SHOULD only be propagated if
    +   explicitly enabled. If not enabled, the received-by host of any host
    +   behind the firewall SHOULD be replaced by an appropriate pseudonym
    +   for that host.
    +
    +   For organizations that have strong privacy requirements for hiding
    +   internal structures, a proxy MAY combine an ordered subsequence of
    +   Via header field entries with identical received-protocol values into
    +   a single such entry. For example,
    +
    +       Via: 1.0 ricky, 1.1 ethel, 1.1 fred, 1.0 lucy
    +
    +        could be collapsed to
    +
    +       Via: 1.0 ricky, 1.1 mertz, 1.0 lucy
    +
    +   Applications SHOULD NOT combine multiple entries unless they are all
    +   under the same organizational control and the hosts have already been
    +   replaced by pseudonyms. Applications MUST NOT combine entries which
    +   have different received-protocol values.
    +
    +14.46 Warning
    +
    +   The Warning general-header field is used to carry additional
    +   information about the status or transformation of a message which
    +   might not be reflected in the message. This information is typically
    +   used to warn about a possible lack of semantic transparency from
    +   caching operations or transformations applied to the entity body of
    +   the message.
    +
    +   Warning headers are sent with responses using:
    +
    +       Warning    = "Warning" ":" 1#warning-value
    +
    +       warning-value = warn-code SP warn-agent SP warn-text
    +                                             [SP warn-date]
    +
    +       warn-code  = 3DIGIT
    +       warn-agent = ( host [ ":" port ] ) | pseudonym
    +                       ; the name or pseudonym of the server adding
    +                       ; the Warning header, for use in debugging
    +       warn-text  = quoted-string
    +       warn-date  = <"> HTTP-date <">
    +
    +   A response MAY carry more than one Warning header.
    +
    +   The warn-text SHOULD be in a natural language and character set that
    +   is most likely to be intelligible to the human user receiving the
    +   response. This decision MAY be based on any available knowledge, such
    +   as the location of the cache or user, the Accept-Language field in a
    +   request, the Content-Language field in a response, etc. The default
    +   language is English and the default character set is ISO-8859-1.
    +
    +   If a character set other than ISO-8859-1 is used, it MUST be encoded
    +   in the warn-text using the method described in RFC 2047 [14].
    +
    +   Warning headers can in general be applied to any message, however
    +   some specific warn-codes are specific to caches and can only be
    +   applied to response messages. New Warning headers SHOULD be added
    +   after any existing Warning headers. A cache MUST NOT delete any
    +   Warning header that it received with a message. However, if a cache
    +   successfully validates a cache entry, it SHOULD remove any Warning
    +   headers previously attached to that entry except as specified for
    +
    +   specific Warning codes. It MUST then add any Warning headers received
    +   in the validating response. In other words, Warning headers are those
    +   that would be attached to the most recent relevant response.
    +
    +   When multiple Warning headers are attached to a response, the user
    +   agent ought to inform the user of as many of them as possible, in the
    +   order that they appear in the response. If it is not possible to
    +   inform the user of all of the warnings, the user agent SHOULD follow
    +   these heuristics:
    +
    +      - Warnings that appear early in the response take priority over
    +        those appearing later in the response.
    +
    +      - Warnings in the user's preferred character set take priority
    +        over warnings in other character sets but with identical warn-
    +        codes and warn-agents.
    +
    +   Systems that generate multiple Warning headers SHOULD order them with
    +   this user agent behavior in mind.
    +
    +   Requirements for the behavior of caches with respect to Warnings are
    +   stated in section 13.1.2.
    +
    +   This is a list of the currently-defined warn-codes, each with a
    +   recommended warn-text in English, and a description of its meaning.
    +
    +   110 Response is stale
    +     MUST be included whenever the returned response is stale.
    +
    +   111 Revalidation failed
    +     MUST be included if a cache returns a stale response because an
    +     attempt to revalidate the response failed, due to an inability to
    +     reach the server.
    +
    +   112 Disconnected operation
    +     SHOULD be included if the cache is intentionally disconnected from
    +     the rest of the network for a period of time.
    +
    +   113 Heuristic expiration
    +     MUST be included if the cache heuristically chose a freshness
    +     lifetime greater than 24 hours and the response's age is greater
    +     than 24 hours.
    +
    +   199 Miscellaneous warning
    +     The warning text MAY include arbitrary information to be presented
    +     to a human user, or logged. A system receiving this warning MUST
    +     NOT take any automated action, besides presenting the warning to
    +     the user.
    +
    +   214 Transformation applied
    +     MUST be added by an intermediate cache or proxy if it applies any
    +     transformation changing the content-coding (as specified in the
    +     Content-Encoding header) or media-type (as specified in the
    +     Content-Type header) of the response, or the entity-body of the
    +     response, unless this Warning code already appears in the response.
    +
    +   299 Miscellaneous persistent warning
    +     The warning text MAY include arbitrary information to be presented
    +     to a human user, or logged. A system receiving this warning MUST
    +     NOT take any automated action.
    +
    +   If an implementation sends a message with one or more Warning headers
    +   whose version is HTTP/1.0 or lower, then the sender MUST include in
    +   each warning-value a warn-date that matches the date in the response.
    +
    +   If an implementation receives a message with a warning-value that
    +   includes a warn-date, and that warn-date is different from the Date
    +   value in the response, then that warning-value MUST be deleted from
    +   the message before storing, forwarding, or using it. (This prevents
    +   bad consequences of naive caching of Warning header fields.) If all
    +   of the warning-values are deleted for this reason, the Warning header
    +   MUST be deleted as well.
    +
    +14.47 WWW-Authenticate
    +
    +   The WWW-Authenticate response-header field MUST be included in 401
    +   (Unauthorized) response messages. The field value consists of at
    +   least one challenge that indicates the authentication scheme(s) and
    +   parameters applicable to the Request-URI.
    +
    +       WWW-Authenticate  = "WWW-Authenticate" ":" 1#challenge
    +
    +   The HTTP access authentication process is described in "HTTP
    +   Authentication: Basic and Digest Access Authentication" [43]. User
    +   agents are advised to take special care in parsing the WWW-
    +   Authenticate field value as it might contain more than one challenge,
    +   or if more than one WWW-Authenticate header field is provided, the
    +   contents of a challenge itself can contain a comma-separated list of
    +   authentication parameters.
    +
    +15 Security Considerations
    +
    +   This section is meant to inform application developers, information
    +   providers, and users of the security limitations in HTTP/1.1 as
    +   described by this document. The discussion does not include
    +   definitive solutions to the problems revealed, though it does make
    +   some suggestions for reducing security risks.
    +
    +15.1 Personal Information
    +
    +   HTTP clients are often privy to large amounts of personal information
    +   (e.g. the user's name, location, mail address, passwords, encryption
    +   keys, etc.), and SHOULD be very careful to prevent unintentional
    +   leakage of this information via the HTTP protocol to other sources.
    +   We very strongly recommend that a convenient interface be provided
    +   for the user to control dissemination of such information, and that
    +   designers and implementors be particularly careful in this area.
    +   History shows that errors in this area often create serious security
    +   and/or privacy problems and generate highly adverse publicity for the
    +   implementor's company.
    +
    +15.1.1 Abuse of Server Log Information
    +
    +   A server is in the position to save personal data about a user's
    +   requests which might identify their reading patterns or subjects of
    +   interest. This information is clearly confidential in nature and its
    +   handling can be constrained by law in certain countries. People using
    +   the HTTP protocol to provide data are responsible for ensuring that
    +   such material is not distributed without the permission of any
    +   individuals that are identifiable by the published results.
    +
    +15.1.2 Transfer of Sensitive Information
    +
    +   Like any generic data transfer protocol, HTTP cannot regulate the
    +   content of the data that is transferred, nor is there any a priori
    +   method of determining the sensitivity of any particular piece of
    +   information within the context of any given request. Therefore,
    +   applications SHOULD supply as much control over this information as
    +   possible to the provider of that information. Four header fields are
    +   worth special mention in this context: Server, Via, Referer and From.
    +
    +   Revealing the specific software version of the server might allow the
    +   server machine to become more vulnerable to attacks against software
    +   that is known to contain security holes. Implementors SHOULD make the
    +   Server header field a configurable option.
    +
    +   Proxies which serve as a portal through a network firewall SHOULD
    +   take special precautions regarding the transfer of header information
    +   that identifies the hosts behind the firewall. In particular, they
    +   SHOULD remove, or replace with sanitized versions, any Via fields
    +   generated behind the firewall.
    +
    +   The Referer header allows reading patterns to be studied and reverse
    +   links drawn. Although it can be very useful, its power can be abused
    +   if user details are not separated from the information contained in
    +
    +   the Referer. Even when the personal information has been removed, the
    +   Referer header might indicate a private document's URI whose
    +   publication would be inappropriate.
    +
    +   The information sent in the From field might conflict with the user's
    +   privacy interests or their site's security policy, and hence it
    +   SHOULD NOT be transmitted without the user being able to disable,
    +   enable, and modify the contents of the field. The user MUST be able
    +   to set the contents of this field within a user preference or
    +   application defaults configuration.
    +
    +   We suggest, though do not require, that a convenient toggle interface
    +   be provided for the user to enable or disable the sending of From and
    +   Referer information.
    +
    +   The User-Agent (section 14.43) or Server (section 14.38) header
    +   fields can sometimes be used to determine that a specific client or
    +   server have a particular security hole which might be exploited.
    +   Unfortunately, this same information is often used for other valuable
    +   purposes for which HTTP currently has no better mechanism.
    +
    +15.1.3 Encoding Sensitive Information in URI's
    +
    +   Because the source of a link might be private information or might
    +   reveal an otherwise private information source, it is strongly
    +   recommended that the user be able to select whether or not the
    +   Referer field is sent. For example, a browser client could have a
    +   toggle switch for browsing openly/anonymously, which would
    +   respectively enable/disable the sending of Referer and From
    +   information.
    +
    +   Clients SHOULD NOT include a Referer header field in a (non-secure)
    +   HTTP request if the referring page was transferred with a secure
    +   protocol.
    +
    +   Authors of services which use the HTTP protocol SHOULD NOT use GET
    +   based forms for the submission of sensitive data, because this will
    +   cause this data to be encoded in the Request-URI. Many existing
    +   servers, proxies, and user agents will log the request URI in some
    +   place where it might be visible to third parties. Servers can use
    +   POST-based form submission instead
    +
    +15.1.4 Privacy Issues Connected to Accept Headers
    +
    +   Accept request-headers can reveal information about the user to all
    +   servers which are accessed. The Accept-Language header in particular
    +   can reveal information the user would consider to be of a private
    +   nature, because the understanding of particular languages is often
    +
    +   strongly correlated to the membership of a particular ethnic group.
    +   User agents which offer the option to configure the contents of an
    +   Accept-Language header to be sent in every request are strongly
    +   encouraged to let the configuration process include a message which
    +   makes the user aware of the loss of privacy involved.
    +
    +   An approach that limits the loss of privacy would be for a user agent
    +   to omit the sending of Accept-Language headers by default, and to ask
    +   the user whether or not to start sending Accept-Language headers to a
    +   server if it detects, by looking for any Vary response-header fields
    +   generated by the server, that such sending could improve the quality
    +   of service.
    +
    +   Elaborate user-customized accept header fields sent in every request,
    +   in particular if these include quality values, can be used by servers
    +   as relatively reliable and long-lived user identifiers. Such user
    +   identifiers would allow content providers to do click-trail tracking,
    +   and would allow collaborating content providers to match cross-server
    +   click-trails or form submissions of individual users. Note that for
    +   many users not behind a proxy, the network address of the host
    +   running the user agent will also serve as a long-lived user
    +   identifier. In environments where proxies are used to enhance
    +   privacy, user agents ought to be conservative in offering accept
    +   header configuration options to end users. As an extreme privacy
    +   measure, proxies could filter the accept headers in relayed requests.
    +   General purpose user agents which provide a high degree of header
    +   configurability SHOULD warn users about the loss of privacy which can
    +   be involved.
    +
    +15.2 Attacks Based On File and Path Names
    +
    +   Implementations of HTTP origin servers SHOULD be careful to restrict
    +   the documents returned by HTTP requests to be only those that were
    +   intended by the server administrators. If an HTTP server translates
    +   HTTP URIs directly into file system calls, the server MUST take
    +   special care not to serve files that were not intended to be
    +   delivered to HTTP clients. For example, UNIX, Microsoft Windows, and
    +   other operating systems use ".." as a path component to indicate a
    +   directory level above the current one. On such a system, an HTTP
    +   server MUST disallow any such construct in the Request-URI if it
    +   would otherwise allow access to a resource outside those intended to
    +   be accessible via the HTTP server. Similarly, files intended for
    +   reference only internally to the server (such as access control
    +   files, configuration files, and script code) MUST be protected from
    +   inappropriate retrieval, since they might contain sensitive
    +   information. Experience has shown that minor bugs in such HTTP server
    +   implementations have turned into security risks.
    +
    +15.3 DNS Spoofing
    +
    +   Clients using HTTP rely heavily on the Domain Name Service, and are
    +   thus generally prone to security attacks based on the deliberate
    +   mis-association of IP addresses and DNS names. Clients need to be
    +   cautious in assuming the continuing validity of an IP number/DNS name
    +   association.
    +
    +   In particular, HTTP clients SHOULD rely on their name resolver for
    +   confirmation of an IP number/DNS name association, rather than
    +   caching the result of previous host name lookups. Many platforms
    +   already can cache host name lookups locally when appropriate, and
    +   they SHOULD be configured to do so. It is proper for these lookups to
    +   be cached, however, only when the TTL (Time To Live) information
    +   reported by the name server makes it likely that the cached
    +   information will remain useful.
    +
    +   If HTTP clients cache the results of host name lookups in order to
    +   achieve a performance improvement, they MUST observe the TTL
    +   information reported by DNS.
    +
    +   If HTTP clients do not observe this rule, they could be spoofed when
    +   a previously-accessed server's IP address changes. As network
    +   renumbering is expected to become increasingly common [24], the
    +   possibility of this form of attack will grow. Observing this
    +   requirement thus reduces this potential security vulnerability.
    +
    +   This requirement also improves the load-balancing behavior of clients
    +   for replicated servers using the same DNS name and reduces the
    +   likelihood of a user's experiencing failure in accessing sites which
    +   use that strategy.
    +
    +15.4 Location Headers and Spoofing
    +
    +   If a single server supports multiple organizations that do not trust
    +   one another, then it MUST check the values of Location and Content-
    +   Location headers in responses that are generated under control of
    +   said organizations to make sure that they do not attempt to
    +   invalidate resources over which they have no authority.
    +
    +15.5 Content-Disposition Issues
    +
    +   RFC 1806 [35], from which the often implemented Content-Disposition
    +   (see section 19.5.1) header in HTTP is derived, has a number of very
    +   serious security considerations. Content-Disposition is not part of
    +   the HTTP standard, but since it is widely implemented, we are
    +   documenting its use and risks for implementors. See RFC 2183 [49]
    +   (which updates RFC 1806) for details.
    +
    +15.6 Authentication Credentials and Idle Clients
    +
    +   Existing HTTP clients and user agents typically retain authentication
    +   information indefinitely. HTTP/1.1. does not provide a method for a
    +   server to direct clients to discard these cached credentials. This is
    +   a significant defect that requires further extensions to HTTP.
    +   Circumstances under which credential caching can interfere with the
    +   application's security model include but are not limited to:
    +
    +      - Clients which have been idle for an extended period following
    +        which the server might wish to cause the client to reprompt the
    +        user for credentials.
    +
    +      - Applications which include a session termination indication
    +        (such as a `logout' or `commit' button on a page) after which
    +        the server side of the application `knows' that there is no
    +        further reason for the client to retain the credentials.
    +
    +   This is currently under separate study. There are a number of work-
    +   arounds to parts of this problem, and we encourage the use of
    +   password protection in screen savers, idle time-outs, and other
    +   methods which mitigate the security problems inherent in this
    +   problem. In particular, user agents which cache credentials are
    +   encouraged to provide a readily accessible mechanism for discarding
    +   cached credentials under user control.
    +
    +15.7 Proxies and Caching
    +
    +   By their very nature, HTTP proxies are men-in-the-middle, and
    +   represent an opportunity for man-in-the-middle attacks. Compromise of
    +   the systems on which the proxies run can result in serious security
    +   and privacy problems. Proxies have access to security-related
    +   information, personal information about individual users and
    +   organizations, and proprietary information belonging to users and
    +   content providers. A compromised proxy, or a proxy implemented or
    +   configured without regard to security and privacy considerations,
    +   might be used in the commission of a wide range of potential attacks.
    +
    +   Proxy operators should protect the systems on which proxies run as
    +   they would protect any system that contains or transports sensitive
    +   information. In particular, log information gathered at proxies often
    +   contains highly sensitive personal information, and/or information
    +   about organizations. Log information should be carefully guarded, and
    +   appropriate guidelines for use developed and followed. (Section
    +   15.1.1).
    +
    +   Caching proxies provide additional potential vulnerabilities, since
    +   the contents of the cache represent an attractive target for
    +   malicious exploitation. Because cache contents persist after an HTTP
    +   request is complete, an attack on the cache can reveal information
    +   long after a user believes that the information has been removed from
    +   the network. Therefore, cache contents should be protected as
    +   sensitive information.
    +
    +   Proxy implementors should consider the privacy and security
    +   implications of their design and coding decisions, and of the
    +   configuration options they provide to proxy operators (especially the
    +   default configuration).
    +
    +   Users of a proxy need to be aware that they are no trustworthier than
    +   the people who run the proxy; HTTP itself cannot solve this problem.
    +
    +   The judicious use of cryptography, when appropriate, may suffice to
    +   protect against a broad range of security and privacy attacks. Such
    +   cryptography is beyond the scope of the HTTP/1.1 specification.
    +
    +15.7.1 Denial of Service Attacks on Proxies
    +
    +   They exist. They are hard to defend against. Research continues.
    +   Beware.
    +
    +16 Acknowledgments
    +
    +   This specification makes heavy use of the augmented BNF and generic
    +   constructs defined by David H. Crocker for RFC 822 [9]. Similarly, it
    +   reuses many of the definitions provided by Nathaniel Borenstein and
    +   Ned Freed for MIME [7]. We hope that their inclusion in this
    +   specification will help reduce past confusion over the relationship
    +   between HTTP and Internet mail message formats.
    +
    +   The HTTP protocol has evolved considerably over the years. It has
    +   benefited from a large and active developer community--the many
    +   people who have participated on the www-talk mailing list--and it is
    +   that community which has been most responsible for the success of
    +   HTTP and of the World-Wide Web in general. Marc Andreessen, Robert
    +   Cailliau, Daniel W. Connolly, Bob Denny, John Franks, Jean-Francois
    +   Groff, Phillip M. Hallam-Baker, Hakon W. Lie, Ari Luotonen, Rob
    +   McCool, Lou Montulli, Dave Raggett, Tony Sanders, and Marc
    +   VanHeyningen deserve special recognition for their efforts in
    +   defining early aspects of the protocol.
    +
    +   This document has benefited greatly from the comments of all those
    +   participating in the HTTP-WG. In addition to those already mentioned,
    +   the following individuals have contributed to this specification:
    +
    +       Gary Adams                  Ross Patterson
    +       Harald Tveit Alvestrand     Albert Lunde
    +       Keith Ball                  John C. Mallery
    +       Brian Behlendorf            Jean-Philippe Martin-Flatin
    +       Paul Burchard               Mitra
    +       Maurizio Codogno            David Morris
    +       Mike Cowlishaw              Gavin Nicol
    +       Roman Czyborra              Bill Perry
    +       Michael A. Dolan            Jeffrey Perry
    +       David J. Fiander            Scott Powers
    +       Alan Freier                 Owen Rees
    +       Marc Hedlund                Luigi Rizzo
    +       Greg Herlihy                David Robinson
    +       Koen Holtman                Marc Salomon
    +       Alex Hopmann                Rich Salz
    +       Bob Jernigan                Allan M. Schiffman
    +       Shel Kaphan                 Jim Seidman
    +       Rohit Khare                 Chuck Shotton
    +       John Klensin                Eric W. Sink
    +       Martijn Koster              Simon E. Spero
    +       Alexei Kosut                Richard N. Taylor
    +       David M. Kristol            Robert S. Thau
    +       Daniel LaLiberte            Bill (BearHeart) Weinman
    +       Ben Laurie                  Francois Yergeau
    +       Paul J. Leach               Mary Ellen Zurko
    +       Daniel DuBois               Josh Cohen
    +
    +   Much of the content and presentation of the caching design is due to
    +   suggestions and comments from individuals including: Shel Kaphan,
    +   Paul Leach, Koen Holtman, David Morris, and Larry Masinter.
    +
    +   Most of the specification of ranges is based on work originally done
    +   by Ari Luotonen and John Franks, with additional input from Steve
    +   Zilles.
    +
    +   Thanks to the "cave men" of Palo Alto. You know who you are.
    +
    +   Jim Gettys (the current editor of this document) wishes particularly
    +   to thank Roy Fielding, the previous editor of this document, along
    +   with John Klensin, Jeff Mogul, Paul Leach, Dave Kristol, Koen
    +   Holtman, John Franks, Josh Cohen, Alex Hopmann, Scott Lawrence, and
    +   Larry Masinter for their help. And thanks go particularly to Jeff
    +   Mogul and Scott Lawrence for performing the "MUST/MAY/SHOULD" audit.
    +
    +   The Apache Group, Anselm Baird-Smith, author of Jigsaw, and Henrik
    +   Frystyk implemented RFC 2068 early, and we wish to thank them for the
    +   discovery of many of the problems that this document attempts to
    +   rectify.
    +
    +17 References
    +
    +   [1] Alvestrand, H., "Tags for the Identification of Languages", RFC
    +       1766, March 1995.
    +
    +   [2] Anklesaria, F., McCahill, M., Lindner, P., Johnson, D., Torrey,
    +       D. and B. Alberti, "The Internet Gopher Protocol (a distributed
    +       document search and retrieval protocol)", RFC 1436, March 1993.
    +
    +   [3] Berners-Lee, T., "Universal Resource Identifiers in WWW", RFC
    +       1630, June 1994.
    +
    +   [4] Berners-Lee, T., Masinter, L. and M. McCahill, "Uniform Resource
    +       Locators (URL)", RFC 1738, December 1994.
    +
    +   [5] Berners-Lee, T. and D. Connolly, "Hypertext Markup Language -
    +       2.0", RFC 1866, November 1995.
    +
    +   [6] Berners-Lee, T., Fielding, R. and H. Frystyk, "Hypertext Transfer
    +       Protocol -- HTTP/1.0", RFC 1945, May 1996.
    +
    +   [7] Freed, N. and N. Borenstein, "Multipurpose Internet Mail
    +       Extensions (MIME) Part One: Format of Internet Message Bodies",
    +       RFC 2045, November 1996.
    +
    +   [8] Braden, R., "Requirements for Internet Hosts -- Communication
    +       Layers", STD 3, RFC 1123, October 1989.
    +
    +   [9] Crocker, D., "Standard for The Format of ARPA Internet Text
    +       Messages", STD 11, RFC 822, August 1982.
    +
    +   [10] Davis, F., Kahle, B., Morris, H., Salem, J., Shen, T., Wang, R.,
    +        Sui, J., and M. Grinbaum, "WAIS Interface Protocol Prototype
    +        Functional Specification," (v1.5), Thinking Machines
    +        Corporation, April 1990.
    +
    +   [11] Fielding, R., "Relative Uniform Resource Locators", RFC 1808,
    +        June 1995.
    +
    +   [12] Horton, M. and R. Adams, "Standard for Interchange of USENET
    +        Messages", RFC 1036, December 1987.
    +
    +   [13] Kantor, B. and P. Lapsley, "Network News Transfer Protocol", RFC
    +        977, February 1986.
    +
    +   [14] Moore, K., "MIME (Multipurpose Internet Mail Extensions) Part
    +        Three: Message Header Extensions for Non-ASCII Text", RFC 2047,
    +        November 1996.
    +
    +   [15] Nebel, E. and L. Masinter, "Form-based File Upload in HTML", RFC
    +        1867, November 1995.
    +
    +   [16] Postel, J., "Simple Mail Transfer Protocol", STD 10, RFC 821,
    +        August 1982.
    +
    +   [17] Postel, J., "Media Type Registration Procedure", RFC 1590,
    +        November 1996.
    +
    +   [18] Postel, J. and J. Reynolds, "File Transfer Protocol", STD 9, RFC
    +        959, October 1985.
    +
    +   [19] Reynolds, J. and J. Postel, "Assigned Numbers", STD 2, RFC 1700,
    +        October 1994.
    +
    +   [20] Sollins, K. and L. Masinter, "Functional Requirements for
    +        Uniform Resource Names", RFC 1737, December 1994.
    +
    +   [21] US-ASCII. Coded Character Set - 7-Bit American Standard Code for
    +        Information Interchange. Standard ANSI X3.4-1986, ANSI, 1986.
    +
    +   [22] ISO-8859. International Standard -- Information Processing --
    +        8-bit Single-Byte Coded Graphic Character Sets --
    +        Part 1: Latin alphabet No. 1, ISO-8859-1:1987.
    +        Part 2: Latin alphabet No. 2, ISO-8859-2, 1987.
    +        Part 3: Latin alphabet No. 3, ISO-8859-3, 1988.
    +        Part 4: Latin alphabet No. 4, ISO-8859-4, 1988.
    +        Part 5: Latin/Cyrillic alphabet, ISO-8859-5, 1988.
    +        Part 6: Latin/Arabic alphabet, ISO-8859-6, 1987.
    +        Part 7: Latin/Greek alphabet, ISO-8859-7, 1987.
    +        Part 8: Latin/Hebrew alphabet, ISO-8859-8, 1988.
    +        Part 9: Latin alphabet No. 5, ISO-8859-9, 1990.
    +
    +   [23] Meyers, J. and M. Rose, "The Content-MD5 Header Field", RFC
    +        1864, October 1995.
    +
    +   [24] Carpenter, B. and Y. Rekhter, "Renumbering Needs Work", RFC
    +        1900, February 1996.
    +
    +   [25] Deutsch, P., "GZIP file format specification version 4.3", RFC
    +        1952, May 1996.
    +
    +   [26] Venkata N. Padmanabhan, and Jeffrey C. Mogul. "Improving HTTP
    +        Latency", Computer Networks and ISDN Systems, v. 28, pp. 25-35,
    +        Dec. 1995. Slightly revised version of paper in Proc. 2nd
    +        International WWW Conference '94: Mosaic and the Web, Oct. 1994,
    +        which is available at
    +        http://www.ncsa.uiuc.edu/SDG/IT94/Proceedings/DDay/mogul/HTTPLat
    +        ency.html.
    +
    +   [27] Joe Touch, John Heidemann, and Katia Obraczka. "Analysis of HTTP
    +        Performance", <URL: http://www.isi.edu/touch/pubs/http-perf96/>,
    +        ISI Research Report ISI/RR-98-463, (original report dated Aug.
    +        1996), USC/Information Sciences Institute, August 1998.
    +
    +   [28] Mills, D., "Network Time Protocol (Version 3) Specification,
    +        Implementation and Analysis", RFC 1305, March 1992.
    +
    +   [29] Deutsch, P., "DEFLATE Compressed Data Format Specification
    +        version 1.3", RFC 1951, May 1996.
    +
    +   [30] S. Spero, "Analysis of HTTP Performance Problems,"
    +        http://sunsite.unc.edu/mdma-release/http-prob.html.
    +
    +   [31] Deutsch, P. and J. Gailly, "ZLIB Compressed Data Format
    +        Specification version 3.3", RFC 1950, May 1996.
    +
    +   [32] Franks, J., Hallam-Baker, P., Hostetler, J., Leach, P.,
    +        Luotonen, A., Sink, E. and L. Stewart, "An Extension to HTTP:
    +        Digest Access Authentication", RFC 2069, January 1997.
    +
    +   [33] Fielding, R., Gettys, J., Mogul, J., Frystyk, H. and T.
    +        Berners-Lee, "Hypertext Transfer Protocol -- HTTP/1.1", RFC
    +        2068, January 1997.
    +
    +   [34] Bradner, S., "Key words for use in RFCs to Indicate Requirement
    +        Levels", BCP 14, RFC 2119, March 1997.
    +
    +   [35] Troost, R. and Dorner, S., "Communicating Presentation
    +        Information in Internet Messages: The Content-Disposition
    +        Header", RFC 1806, June 1995.
    +
    +   [36] Mogul, J., Fielding, R., Gettys, J. and H. Frystyk, "Use and
    +        Interpretation of HTTP Version Numbers", RFC 2145, May 1997.
    +        [jg639]
    +
    +   [37] Palme, J., "Common Internet Message Headers", RFC 2076, February
    +        1997. [jg640]
    +
    +   [38] Yergeau, F., "UTF-8, a transformation format of Unicode and
    +        ISO-10646", RFC 2279, January 1998. [jg641]
    +
    +   [39] Nielsen, H.F., Gettys, J., Baird-Smith, A., Prud'hommeaux, E.,
    +        Lie, H., and C. Lilley. "Network Performance Effects of
    +        HTTP/1.1, CSS1, and PNG," Proceedings of ACM SIGCOMM '97, Cannes
    +        France, September 1997.[jg642]
    +
    +   [40] Freed, N. and N. Borenstein, "Multipurpose Internet Mail
    +        Extensions (MIME) Part Two: Media Types", RFC 2046, November
    +        1996. [jg643]
    +
    +   [41] Alvestrand, H., "IETF Policy on Character Sets and Languages",
    +        BCP 18, RFC 2277, January 1998. [jg644]
    +
    +   [42] Berners-Lee, T., Fielding, R. and L. Masinter, "Uniform Resource
    +        Identifiers (URI): Generic Syntax and Semantics", RFC 2396,
    +        August 1998. [jg645]
    +
    +   [43] Franks, J., Hallam-Baker, P., Hostetler, J., Lawrence, S.,
    +        Leach, P., Luotonen, A., Sink, E. and L. Stewart, "HTTP
    +        Authentication: Basic and Digest Access Authentication", RFC
    +        2617, June 1999. [jg646]
    +
    +   [44] Luotonen, A., "Tunneling TCP based protocols through Web proxy
    +        servers," Work in Progress. [jg647]
    +
    +   [45] Palme, J. and A. Hopmann, "MIME E-mail Encapsulation of
    +        Aggregate Documents, such as HTML (MHTML)", RFC 2110, March
    +        1997.
    +
    +   [46] Bradner, S., "The Internet Standards Process -- Revision 3", BCP
    +        9, RFC 2026, October 1996.
    +
    +   [47] Masinter, L., "Hyper Text Coffee Pot Control Protocol
    +        (HTCPCP/1.0)", RFC 2324, 1 April 1998.
    +
    +   [48] Freed, N. and N. Borenstein, "Multipurpose Internet Mail
    +        Extensions (MIME) Part Five: Conformance Criteria and Examples",
    +        RFC 2049, November 1996.
    +
    +   [49] Troost, R., Dorner, S. and K. Moore, "Communicating Presentation
    +        Information in Internet Messages: The Content-Disposition Header
    +        Field", RFC 2183, August 1997.
    +
    +18 Authors' Addresses
    +
    +   Roy T. Fielding
    +   Information and Computer Science
    +   University of California, Irvine
    +   Irvine, CA 92697-3425, USA
    +
    +   Fax: +1 (949) 824-1715
    +   EMail: fielding@ics.uci.edu
    +
    +   James Gettys
    +   World Wide Web Consortium
    +   MIT Laboratory for Computer Science
    +   545 Technology Square
    +   Cambridge, MA 02139, USA
    +
    +   Fax: +1 (617) 258 8682
    +   EMail: jg@w3.org
    +
    +   Jeffrey C. Mogul
    +   Western Research Laboratory
    +   Compaq Computer Corporation
    +   250 University Avenue
    +   Palo Alto, California, 94305, USA
    +
    +   EMail: mogul@wrl.dec.com
    +
    +   Henrik Frystyk Nielsen
    +   World Wide Web Consortium
    +   MIT Laboratory for Computer Science
    +   545 Technology Square
    +   Cambridge, MA 02139, USA
    +
    +   Fax: +1 (617) 258 8682
    +   EMail: frystyk@w3.org
    +
    +   Larry Masinter
    +   Xerox Corporation
    +   3333 Coyote Hill Road
    +   Palo Alto, CA 94034, USA
    +
    +   EMail: masinter@parc.xerox.com
    +
    +   Paul J. Leach
    +   Microsoft Corporation
    +   1 Microsoft Way
    +   Redmond, WA 98052, USA
    +
    +   EMail: paulle@microsoft.com
    +
    +   Tim Berners-Lee
    +   Director, World Wide Web Consortium
    +   MIT Laboratory for Computer Science
    +   545 Technology Square
    +   Cambridge, MA 02139, USA
    +
    +   Fax: +1 (617) 258 8682
    +   EMail: timbl@w3.org
    +
    +19 Appendices
    +
    +19.1 Internet Media Type message/http and application/http
    +
    +   In addition to defining the HTTP/1.1 protocol, this document serves
    +   as the specification for the Internet media type "message/http" and
    +   "application/http". The message/http type can be used to enclose a
    +   single HTTP request or response message, provided that it obeys the
    +   MIME restrictions for all "message" types regarding line length and
    +   encodings. The application/http type can be used to enclose a
    +   pipeline of one or more HTTP request or response messages (not
    +   intermixed). The following is to be registered with IANA [17].
    +
    +       Media Type name:         message
    +       Media subtype name:      http
    +       Required parameters:     none
    +       Optional parameters:     version, msgtype
    +        version: The HTTP-Version number of the enclosed message
    +                 (e.g., "1.1"). If not present, the version can be
    +                 determined from the first line of the body.
    +        msgtype: The message type -- "request" or "response". If not
    +                 present, the type can be determined from the first
    +                 line of the body.
    +       Encoding considerations: only "7bit", "8bit", or "binary" are
    +                                permitted
    +       Security considerations: none
    +
    +       Media Type name:         application
    +       Media subtype name:      http
    +       Required parameters:     none
    +       Optional parameters:     version, msgtype
    +        version: The HTTP-Version number of the enclosed messages
    +                 (e.g., "1.1"). If not present, the version can be
    +                 determined from the first line of the body.
    +        msgtype: The message type -- "request" or "response". If not
    +                 present, the type can be determined from the first
    +                 line of the body.
    +       Encoding considerations: HTTP messages enclosed by this type
    +                 are in "binary" format; use of an appropriate
    +                 Content-Transfer-Encoding is required when
    +                 transmitted via E-mail.
    +       Security considerations: none
    +
    +19.2 Internet Media Type multipart/byteranges
    +
    +   When an HTTP 206 (Partial Content) response message includes the
    +   content of multiple ranges (a response to a request for multiple
    +   non-overlapping ranges), these are transmitted as a multipart
    +   message-body. The media type for this purpose is called
    +   "multipart/byteranges".
    +
    +   The multipart/byteranges media type includes two or more parts, each
    +   with its own Content-Type and Content-Range fields. The required
    +   boundary parameter specifies the boundary string used to separate
    +   each body-part.
    +
    +       Media Type name:         multipart
    +       Media subtype name:      byteranges
    +       Required parameters:     boundary
    +       Optional parameters:     none
    +       Encoding considerations: only "7bit", "8bit", or "binary" are
    +                                permitted
    +       Security considerations: none
    +
    +   For example:
    +
    +   HTTP/1.1 206 Partial Content
    +   Date: Wed, 15 Nov 1995 06:25:24 GMT
    +   Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT
    +   Content-type: multipart/byteranges; boundary=THIS_STRING_SEPARATES
    +
    +   --THIS_STRING_SEPARATES
    +   Content-type: application/pdf
    +   Content-range: bytes 500-999/8000
    +
    +   ...the first range...
    +   --THIS_STRING_SEPARATES
    +   Content-type: application/pdf
    +   Content-range: bytes 7000-7999/8000
    +
    +   ...the second range
    +   --THIS_STRING_SEPARATES--
    +
    +      Notes:
    +
    +      1) Additional CRLFs may precede the first boundary string in the
    +         entity.
    +
    +      2) Although RFC 2046 [40] permits the boundary string to be
    +         quoted, some existing implementations handle a quoted boundary
    +         string incorrectly.
    +
    +      3) A number of browsers and servers were coded to an early draft
    +         of the byteranges specification to use a media type of
    +         multipart/x-byteranges, which is almost, but not quite
    +         compatible with the version documented in HTTP/1.1.
    +
    +19.3 Tolerant Applications
    +
    +   Although this document specifies the requirements for the generation
    +   of HTTP/1.1 messages, not all applications will be correct in their
    +   implementation. We therefore recommend that operational applications
    +   be tolerant of deviations whenever those deviations can be
    +   interpreted unambiguously.
    +
    +   Clients SHOULD be tolerant in parsing the Status-Line and servers
    +   tolerant when parsing the Request-Line. In particular, they SHOULD
    +   accept any amount of SP or HT characters between fields, even though
    +   only a single SP is required.
    +
    +   The line terminator for message-header fields is the sequence CRLF.
    +   However, we recommend that applications, when parsing such headers,
    +   recognize a single LF as a line terminator and ignore the leading CR.
    +
    +   The character set of an entity-body SHOULD be labeled as the lowest
    +   common denominator of the character codes used within that body, with
    +   the exception that not labeling the entity is preferred over labeling
    +   the entity with the labels US-ASCII or ISO-8859-1. See section 3.7.1
    +   and 3.4.1.
    +
    +   Additional rules for requirements on parsing and encoding of dates
    +   and other potential problems with date encodings include:
    +
    +      - HTTP/1.1 clients and caches SHOULD assume that an RFC-850 date
    +        which appears to be more than 50 years in the future is in fact
    +        in the past (this helps solve the "year 2000" problem).
    +
    +      - An HTTP/1.1 implementation MAY internally represent a parsed
    +        Expires date as earlier than the proper value, but MUST NOT
    +        internally represent a parsed Expires date as later than the
    +        proper value.
    +
    +      - All expiration-related calculations MUST be done in GMT. The
    +        local time zone MUST NOT influence the calculation or comparison
    +        of an age or expiration time.
    +
    +      - If an HTTP header incorrectly carries a date value with a time
    +        zone other than GMT, it MUST be converted into GMT using the
    +        most conservative possible conversion.
    +
    +19.4 Differences Between HTTP Entities and RFC 2045 Entities
    +
    +   HTTP/1.1 uses many of the constructs defined for Internet Mail (RFC
    +   822 [9]) and the Multipurpose Internet Mail Extensions (MIME [7]) to
    +   allow entities to be transmitted in an open variety of
    +   representations and with extensible mechanisms. However, RFC 2045
    +   discusses mail, and HTTP has a few features that are different from
    +   those described in RFC 2045. These differences were carefully chosen
    +   to optimize performance over binary connections, to allow greater
    +   freedom in the use of new media types, to make date comparisons
    +   easier, and to acknowledge the practice of some early HTTP servers
    +   and clients.
    +
    +   This appendix describes specific areas where HTTP differs from RFC
    +   2045. Proxies and gateways to strict MIME environments SHOULD be
    +   aware of these differences and provide the appropriate conversions
    +   where necessary. Proxies and gateways from MIME environments to HTTP
    +   also need to be aware of the differences because some conversions
    +   might be required.
    +
    +19.4.1 MIME-Version
    +
    +   HTTP is not a MIME-compliant protocol. However, HTTP/1.1 messages MAY
    +   include a single MIME-Version general-header field to indicate what
    +   version of the MIME protocol was used to construct the message. Use
    +   of the MIME-Version header field indicates that the message is in
    +   full compliance with the MIME protocol (as defined in RFC 2045[7]).
    +   Proxies/gateways are responsible for ensuring full compliance (where
    +   possible) when exporting HTTP messages to strict MIME environments.
    +
    +       MIME-Version   = "MIME-Version" ":" 1*DIGIT "." 1*DIGIT
    +
    +   MIME version "1.0" is the default for use in HTTP/1.1. However,
    +   HTTP/1.1 message parsing and semantics are defined by this document
    +   and not the MIME specification.
    +
    +19.4.2 Conversion to Canonical Form
    +
    +   RFC 2045 [7] requires that an Internet mail entity be converted to
    +   canonical form prior to being transferred, as described in section 4
    +   of RFC 2049 [48]. Section 3.7.1 of this document describes the forms
    +   allowed for subtypes of the "text" media type when transmitted over
    +   HTTP. RFC 2046 requires that content with a type of "text" represent
    +   line breaks as CRLF and forbids the use of CR or LF outside of line
    +
    +   break sequences. HTTP allows CRLF, bare CR, and bare LF to indicate a
    +   line break within text content when a message is transmitted over
    +   HTTP.
    +
    +   Where it is possible, a proxy or gateway from HTTP to a strict MIME
    +   environment SHOULD translate all line breaks within the text media
    +   types described in section 3.7.1 of this document to the RFC 2049
    +   canonical form of CRLF. Note, however, that this might be complicated
    +   by the presence of a Content-Encoding and by the fact that HTTP
    +   allows the use of some character sets which do not use octets 13 and
    +   10 to represent CR and LF, as is the case for some multi-byte
    +   character sets.
    +
    +   Implementors should note that conversion will break any cryptographic
    +   checksums applied to the original content unless the original content
    +   is already in canonical form. Therefore, the canonical form is
    +   recommended for any content that uses such checksums in HTTP.
    +
    +19.4.3 Conversion of Date Formats
    +
    +   HTTP/1.1 uses a restricted set of date formats (section 3.3.1) to
    +   simplify the process of date comparison. Proxies and gateways from
    +   other protocols SHOULD ensure that any Date header field present in a
    +   message conforms to one of the HTTP/1.1 formats and rewrite the date
    +   if necessary.
    +
    +19.4.4 Introduction of Content-Encoding
    +
    +   RFC 2045 does not include any concept equivalent to HTTP/1.1's
    +   Content-Encoding header field. Since this acts as a modifier on the
    +   media type, proxies and gateways from HTTP to MIME-compliant
    +   protocols MUST either change the value of the Content-Type header
    +   field or decode the entity-body before forwarding the message. (Some
    +   experimental applications of Content-Type for Internet mail have used
    +   a media-type parameter of ";conversions=<content-coding>" to perform
    +   a function equivalent to Content-Encoding. However, this parameter is
    +   not part of RFC 2045.)
    +
    +19.4.5 No Content-Transfer-Encoding
    +
    +   HTTP does not use the Content-Transfer-Encoding (CTE) field of RFC
    +   2045. Proxies and gateways from MIME-compliant protocols to HTTP MUST
    +   remove any non-identity CTE ("quoted-printable" or "base64") encoding
    +   prior to delivering the response message to an HTTP client.
    +
    +   Proxies and gateways from HTTP to MIME-compliant protocols are
    +   responsible for ensuring that the message is in the correct format
    +   and encoding for safe transport on that protocol, where "safe
    +
    +   transport" is defined by the limitations of the protocol being used.
    +   Such a proxy or gateway SHOULD label the data with an appropriate
    +   Content-Transfer-Encoding if doing so will improve the likelihood of
    +   safe transport over the destination protocol.
    +
    +19.4.6 Introduction of Transfer-Encoding
    +
    +   HTTP/1.1 introduces the Transfer-Encoding header field (section
    +   14.41). Proxies/gateways MUST remove any transfer-coding prior to
    +   forwarding a message via a MIME-compliant protocol.
    +
    +   A process for decoding the "chunked" transfer-coding (section 3.6)
    +   can be represented in pseudo-code as:
    +
    +       length := 0
    +       read chunk-size, chunk-extension (if any) and CRLF
    +       while (chunk-size > 0) {
    +          read chunk-data and CRLF
    +          append chunk-data to entity-body
    +          length := length + chunk-size
    +          read chunk-size and CRLF
    +       }
    +       read entity-header
    +       while (entity-header not empty) {
    +          append entity-header to existing header fields
    +          read entity-header
    +       }
    +       Content-Length := length
    +       Remove "chunked" from Transfer-Encoding
    +
    +19.4.7 MHTML and Line Length Limitations
    +
    +   HTTP implementations which share code with MHTML [45] implementations
    +   need to be aware of MIME line length limitations. Since HTTP does not
    +   have this limitation, HTTP does not fold long lines. MHTML messages
    +   being transported by HTTP follow all conventions of MHTML, including
    +   line length limitations and folding, canonicalization, etc., since
    +   HTTP transports all message-bodies as payload (see section 3.7.2) and
    +   does not interpret the content or any MIME header lines that might be
    +   contained therein.
    +
    +19.5 Additional Features
    +
    +   RFC 1945 and RFC 2068 document protocol elements used by some
    +   existing HTTP implementations, but not consistently and correctly
    +   across most HTTP/1.1 applications. Implementors are advised to be
    +   aware of these features, but cannot rely upon their presence in, or
    +   interoperability with, other HTTP/1.1 applications. Some of these
    +
    +   describe proposed experimental features, and some describe features
    +   that experimental deployment found lacking that are now addressed in
    +   the base HTTP/1.1 specification.
    +
    +   A number of other headers, such as Content-Disposition and Title,
    +   from SMTP and MIME are also often implemented (see RFC 2076 [37]).
    +
    +19.5.1 Content-Disposition
    +
    +   The Content-Disposition response-header field has been proposed as a
    +   means for the origin server to suggest a default filename if the user
    +   requests that the content is saved to a file. This usage is derived
    +   from the definition of Content-Disposition in RFC 1806 [35].
    +
    +        content-disposition = "Content-Disposition" ":"
    +                              disposition-type *( ";" disposition-parm )
    +        disposition-type = "attachment" | disp-extension-token
    +        disposition-parm = filename-parm | disp-extension-parm
    +        filename-parm = "filename" "=" quoted-string
    +        disp-extension-token = token
    +        disp-extension-parm = token "=" ( token | quoted-string )
    +
    +   An example is
    +
    +        Content-Disposition: attachment; filename="fname.ext"
    +
    +   The receiving user agent SHOULD NOT respect any directory path
    +   information present in the filename-parm parameter, which is the only
    +   parameter believed to apply to HTTP implementations at this time. The
    +   filename SHOULD be treated as a terminal component only.
    +
    +   If this header is used in a response with the application/octet-
    +   stream content-type, the implied suggestion is that the user agent
    +   should not display the response, but directly enter a `save response
    +   as...' dialog.
    +
    +   See section 15.5 for Content-Disposition security issues.
    +
    +19.6 Compatibility with Previous Versions
    +
    +   It is beyond the scope of a protocol specification to mandate
    +   compliance with previous versions. HTTP/1.1 was deliberately
    +   designed, however, to make supporting previous versions easy. It is
    +   worth noting that, at the time of composing this specification
    +   (1996), we would expect commercial HTTP/1.1 servers to:
    +
    +      - recognize the format of the Request-Line for HTTP/0.9, 1.0, and
    +        1.1 requests;
    +
    +      - understand any valid request in the format of HTTP/0.9, 1.0, or
    +        1.1;
    +
    +      - respond appropriately with a message in the same major version
    +        used by the client.
    +
    +   And we would expect HTTP/1.1 clients to:
    +
    +      - recognize the format of the Status-Line for HTTP/1.0 and 1.1
    +        responses;
    +
    +      - understand any valid response in the format of HTTP/0.9, 1.0, or
    +        1.1.
    +
    +   For most implementations of HTTP/1.0, each connection is established
    +   by the client prior to the request and closed by the server after
    +   sending the response. Some implementations implement the Keep-Alive
    +   version of persistent connections described in section 19.7.1 of RFC
    +   2068 [33].
    +
    +19.6.1 Changes from HTTP/1.0
    +
    +   This section summarizes major differences between versions HTTP/1.0
    +   and HTTP/1.1.
    +
    +19.6.1.1 Changes to Simplify Multi-homed Web Servers and Conserve IP
    +         Addresses
    +
    +   The requirements that clients and servers support the Host request-
    +   header, report an error if the Host request-header (section 14.23) is
    +   missing from an HTTP/1.1 request, and accept absolute URIs (section
    +   5.1.2) are among the most important changes defined by this
    +   specification.
    +
    +   Older HTTP/1.0 clients assumed a one-to-one relationship of IP
    +   addresses and servers; there was no other established mechanism for
    +   distinguishing the intended server of a request than the IP address
    +   to which that request was directed. The changes outlined above will
    +   allow the Internet, once older HTTP clients are no longer common, to
    +   support multiple Web sites from a single IP address, greatly
    +   simplifying large operational Web servers, where allocation of many
    +   IP addresses to a single host has created serious problems. The
    +   Internet will also be able to recover the IP addresses that have been
    +   allocated for the sole purpose of allowing special-purpose domain
    +   names to be used in root-level HTTP URLs. Given the rate of growth of
    +   the Web, and the number of servers already deployed, it is extremely
    +
    +   important that all implementations of HTTP (including updates to
    +   existing HTTP/1.0 applications) correctly implement these
    +   requirements:
    +
    +      - Both clients and servers MUST support the Host request-header.
    +
    +      - A client that sends an HTTP/1.1 request MUST send a Host header.
    +
    +      - Servers MUST report a 400 (Bad Request) error if an HTTP/1.1
    +        request does not include a Host request-header.
    +
    +      - Servers MUST accept absolute URIs.
    +
    +19.6.2 Compatibility with HTTP/1.0 Persistent Connections
    +
    +   Some clients and servers might wish to be compatible with some
    +   previous implementations of persistent connections in HTTP/1.0
    +   clients and servers. Persistent connections in HTTP/1.0 are
    +   explicitly negotiated as they are not the default behavior. HTTP/1.0
    +   experimental implementations of persistent connections are faulty,
    +   and the new facilities in HTTP/1.1 are designed to rectify these
    +   problems. The problem was that some existing 1.0 clients may be
    +   sending Keep-Alive to a proxy server that doesn't understand
    +   Connection, which would then erroneously forward it to the next
    +   inbound server, which would establish the Keep-Alive connection and
    +   result in a hung HTTP/1.0 proxy waiting for the close on the
    +   response. The result is that HTTP/1.0 clients must be prevented from
    +   using Keep-Alive when talking to proxies.
    +
    +   However, talking to proxies is the most important use of persistent
    +   connections, so that prohibition is clearly unacceptable. Therefore,
    +   we need some other mechanism for indicating a persistent connection
    +   is desired, which is safe to use even when talking to an old proxy
    +   that ignores Connection. Persistent connections are the default for
    +   HTTP/1.1 messages; we introduce a new keyword (Connection: close) for
    +   declaring non-persistence. See section 14.10.
    +
    +   The original HTTP/1.0 form of persistent connections (the Connection:
    +   Keep-Alive and Keep-Alive header) is documented in RFC 2068. [33]
    +
    +19.6.3 Changes from RFC 2068
    +
    +   This specification has been carefully audited to correct and
    +   disambiguate key word usage; RFC 2068 had many problems in respect to
    +   the conventions laid out in RFC 2119 [34].
    +
    +   Clarified which error code should be used for inbound server failures
    +   (e.g. DNS failures). (Section 10.5.5).
    +
    +   CREATE had a race that required an Etag be sent when a resource is
    +   first created. (Section 10.2.2).
    +
    +   Content-Base was deleted from the specification: it was not
    +   implemented widely, and there is no simple, safe way to introduce it
    +   without a robust extension mechanism. In addition, it is used in a
    +   similar, but not identical fashion in MHTML [45].
    +
    +   Transfer-coding and message lengths all interact in ways that
    +   required fixing exactly when chunked encoding is used (to allow for
    +   transfer encoding that may not be self delimiting); it was important
    +   to straighten out exactly how message lengths are computed. (Sections
    +   3.6, 4.4, 7.2.2, 13.5.2, 14.13, 14.16)
    +
    +   A content-coding of "identity" was introduced, to solve problems
    +   discovered in caching. (section 3.5)
    +
    +   Quality Values of zero should indicate that "I don't want something"
    +   to allow clients to refuse a representation. (Section 3.9)
    +
    +   The use and interpretation of HTTP version numbers has been clarified
    +   by RFC 2145. Require proxies to upgrade requests to highest protocol
    +   version they support to deal with problems discovered in HTTP/1.0
    +   implementations (Section 3.1)
    +
    +   Charset wildcarding is introduced to avoid explosion of character set
    +   names in accept headers. (Section 14.2)
    +
    +   A case was missed in the Cache-Control model of HTTP/1.1; s-maxage
    +   was introduced to add this missing case. (Sections 13.4, 14.8, 14.9,
    +   14.9.3)
    +
    +   The Cache-Control: max-age directive was not properly defined for
    +   responses. (Section 14.9.3)
    +
    +   There are situations where a server (especially a proxy) does not
    +   know the full length of a response but is capable of serving a
    +   byterange request. We therefore need a mechanism to allow byteranges
    +   with a content-range not indicating the full length of the message.
    +   (Section 14.16)
    +
    +   Range request responses would become very verbose if all meta-data
    +   were always returned; by allowing the server to only send needed
    +   headers in a 206 response, this problem can be avoided. (Section
    +   10.2.7, 13.5.3, and 14.27)
    +
    +   Fix problem with unsatisfiable range requests; there are two cases:
    +   syntactic problems, and range doesn't exist in the document. The 416
    +   status code was needed to resolve this ambiguity needed to indicate
    +   an error for a byte range request that falls outside of the actual
    +   contents of a document. (Section 10.4.17, 14.16)
    +
    +   Rewrite of message transmission requirements to make it much harder
    +   for implementors to get it wrong, as the consequences of errors here
    +   can have significant impact on the Internet, and to deal with the
    +   following problems:
    +
    +      1. Changing "HTTP/1.1 or later" to "HTTP/1.1", in contexts where
    +         this was incorrectly placing a requirement on the behavior of
    +         an implementation of a future version of HTTP/1.x
    +
    +      2. Made it clear that user-agents should retry requests, not
    +         "clients" in general.
    +
    +      3. Converted requirements for clients to ignore unexpected 100
    +         (Continue) responses, and for proxies to forward 100 responses,
    +         into a general requirement for 1xx responses.
    +
    +      4. Modified some TCP-specific language, to make it clearer that
    +         non-TCP transports are possible for HTTP.
    +
    +      5. Require that the origin server MUST NOT wait for the request
    +         body before it sends a required 100 (Continue) response.
    +
    +      6. Allow, rather than require, a server to omit 100 (Continue) if
    +         it has already seen some of the request body.
    +
    +      7. Allow servers to defend against denial-of-service attacks and
    +         broken clients.
    +
    +   This change adds the Expect header and 417 status code. The message
    +   transmission requirements fixes are in sections 8.2, 10.4.18,
    +   8.1.2.2, 13.11, and 14.20.
    +
    +   Proxies should be able to add Content-Length when appropriate.
    +   (Section 13.5.2)
    +
    +   Clean up confusion between 403 and 404 responses. (Section 10.4.4,
    +   10.4.5, and 10.4.11)
    +
    +   Warnings could be cached incorrectly, or not updated appropriately.
    +   (Section 13.1.2, 13.2.4, 13.5.2, 13.5.3, 14.9.3, and 14.46) Warning
    +   also needed to be a general header, as PUT or other methods may have
    +   need for it in requests.
    +
    +   Transfer-coding had significant problems, particularly with
    +   interactions with chunked encoding. The solution is that transfer-
    +   codings become as full fledged as content-codings. This involves
    +   adding an IANA registry for transfer-codings (separate from content
    +   codings), a new header field (TE) and enabling trailer headers in the
    +   future. Transfer encoding is a major performance benefit, so it was
    +   worth fixing [39]. TE also solves another, obscure, downward
    +   interoperability problem that could have occurred due to interactions
    +   between authentication trailers, chunked encoding and HTTP/1.0
    +   clients.(Section 3.6, 3.6.1, and 14.39)
    +
    +   The PATCH, LINK, UNLINK methods were defined but not commonly
    +   implemented in previous versions of this specification. See RFC 2068
    +   [33].
    +
    +   The Alternates, Content-Version, Derived-From, Link, URI, Public and
    +   Content-Base header fields were defined in previous versions of this
    +   specification, but not commonly implemented. See RFC 2068 [33].
    +
    +20 Index
    +
    +   Please see the PostScript version of this RFC for the INDEX.
    +
    +21.  Full Copyright Statement
    +
    +   Copyright (C) The Internet Society (1999).  All Rights Reserved.
    +
    +   This document and translations of it may be copied and furnished to
    +   others, and derivative works that comment on or otherwise explain it
    +   or assist in its implementation may be prepared, copied, published
    +   and distributed, in whole or in part, without restriction of any
    +   kind, provided that the above copyright notice and this paragraph are
    +   included on all such copies and derivative works.  However, this
    +   document itself may not be modified in any way, such as by removing
    +   the copyright notice or references to the Internet Society or other
    +   Internet organizations, except as needed for the purpose of
    +   developing Internet standards in which case the procedures for
    +   copyrights defined in the Internet Standards process must be
    +   followed, or as required to translate it into languages other than
    +   English.
    +
    +   The limited permissions granted above are perpetual and will not be
    +   revoked by the Internet Society or its successors or assigns.
    +
    +   This document and the information contained herein is provided on an
    +   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
    +   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
    +   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
    +   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
    +   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
    +
    +Acknowledgement
    +
    +   Funding for the RFC Editor function is currently provided by the
    +   Internet Society.
    +
    +
    +

    Comment on RFC 2616 +


    +
    +
    + +
    +

    Comments about this RFC:

    + +

    +

     

    +
    + + rfc2616.pdf + +
    +

    + +

    +
    +
    + \ No newline at end of file From ae9be1a63d7b579fb5bb8b4bf903f1a3efe7168f Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 10 Jan 2019 13:54:11 +0100 Subject: [PATCH 1231/1650] moc: Parse namespaces from other files We can parse the namespaces in order to find the enums in them and populate the related metaobjects of the current file's classes. The symbol clashes are avoided by only generating metaobjects for namespaces defined in the same file. Fixes: QTBUG-71966 Fixes: QTBUG-72069 Change-Id: Ibdf21c3f9dae48d95b0952b3e220b4c29e30ecb8 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/tools/moc/moc.cpp | 33 ++++++++++++++++---------------- src/tools/moc/moc.h | 1 + tests/auto/tools/moc/tst_moc.cpp | 13 +++++++++++++ 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index 5d777ece2e..c82a6d71ae 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -565,6 +565,7 @@ void Moc::parse() } else if (!test(SEMIC)) { NamespaceDef def; def.classname = nsName; + def.doGenerate = currentFilenames.size() <= 1; next(LBRACE); def.begin = index - 1; @@ -572,25 +573,22 @@ void Moc::parse() def.end = index; index = def.begin + 1; - const bool parseNamespace = currentFilenames.size() <= 1; - if (parseNamespace) { - for (int i = namespaceList.size() - 1; i >= 0; --i) { - if (inNamespace(&namespaceList.at(i))) { - def.qualified.prepend(namespaceList.at(i).classname + "::"); - } - } - for (const QByteArray &ns : nested) { - NamespaceDef parentNs; - parentNs.classname = ns; - parentNs.qualified = def.qualified; - def.qualified += ns + "::"; - parentNs.begin = def.begin; - parentNs.end = def.end; - namespaceList += parentNs; + for (int i = namespaceList.size() - 1; i >= 0; --i) { + if (inNamespace(&namespaceList.at(i))) { + def.qualified.prepend(namespaceList.at(i).classname + "::"); } } + for (const QByteArray &ns : nested) { + NamespaceDef parentNs; + parentNs.classname = ns; + parentNs.qualified = def.qualified; + def.qualified += ns + "::"; + parentNs.begin = def.begin; + parentNs.end = def.end; + namespaceList += parentNs; + } - while (parseNamespace && inNamespace(&def) && hasNext()) { + while (inNamespace(&def) && hasNext()) { switch (next()) { case NAMESPACE: if (test(IDENTIFIER)) { @@ -915,7 +913,8 @@ void Moc::parse() } else { knownGadgets.insert(def.classname, def.qualified); knownGadgets.insert(def.qualified, def.qualified); - classList += def; + if (n.doGenerate) + classList += def; } } } diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h index d6482f4e44..54f935a8da 100644 --- a/src/tools/moc/moc.h +++ b/src/tools/moc/moc.h @@ -188,6 +188,7 @@ Q_DECLARE_TYPEINFO(ClassDef::Interface, Q_MOVABLE_TYPE); struct NamespaceDef : BaseDef { bool hasQNamespace = false; + bool doGenerate = false; }; Q_DECLARE_TYPEINFO(NamespaceDef, Q_MOVABLE_TYPE); diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index 74ddfd5620..0acc90fd11 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -3847,6 +3847,14 @@ static void checkEnum(const QMetaEnum &enumerator, const QByteArray &name, const } } +class EnumFromNamespaceClass : public QObject +{ + Q_OBJECT + Q_PROPERTY(FooNamespace::Enum1 prop READ prop CONSTANT) +public: + FooNamespace::Enum1 prop() { return FooNamespace::Enum1::Key2; } +}; + void tst_Moc::testQNamespace() { QCOMPARE(TestQNamespace::staticMetaObject.enumeratorCount(), 4); @@ -3874,6 +3882,11 @@ void tst_Moc::testQNamespace() QCOMPARE(FooNamespace::staticMetaObject.enumeratorCount(), 1); QCOMPARE(FooNamespace::FooNestedNamespace::staticMetaObject.enumeratorCount(), 2); QCOMPARE(FooNamespace::FooNestedNamespace::FooMoreNestedNamespace::staticMetaObject.enumeratorCount(), 1); + + EnumFromNamespaceClass obj; + const QVariant prop = obj.property("prop"); + QCOMPARE(prop.type(), QMetaType::Int); + QCOMPARE(prop.toInt(), int(FooNamespace::Enum1::Key2)); } void tst_Moc::cxx17Namespaces() From 783953f09dcfe9c58dc991394535ba07dabe2560 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Wed, 23 Jan 2019 16:31:35 +0100 Subject: [PATCH 1232/1650] Add conversion to and from long and ulong This implements conversion parity with QString, which can convert to and from long and unsigned long. The implementation simply forwards to existing long long overloads or uses the existing helpers, so just as for the conversion to/from int or short, no additional test cases were added. Change-Id: I37ef06d9ce4d80d98bd72720353996bac723e09c Fixes: QTBUG-782 Reviewed-by: Volker Hilsheimer --- src/corelib/tools/qlocale.cpp | 126 +++++++++++++++++++++++++++++++++ src/corelib/tools/qlocale.h | 12 ++++ src/corelib/tools/qlocale.qdoc | 24 +++++++ 3 files changed, 162 insertions(+) diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index b3fb079342..ebb6c97975 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -1332,6 +1332,48 @@ uint QLocale::toUInt(const QString &s, bool *ok) const return toIntegral_helper(d, s, ok); } +/*! + Returns the long int represented by the localized string \a s. + + If the conversion fails the function returns 0. + + If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + to \c false, and success by setting *\a{ok} to \c true. + + This function ignores leading and trailing whitespace. + + \sa toInt(), toULong(), toDouble(), toString() + + \since 5.13 + */ + + +long QLocale::toLong(const QString &s, bool *ok) const +{ + return toIntegral_helper(d, s, ok); +} + +/*! + Returns the unsigned long int represented by the localized + string \a s. + + If the conversion fails the function returns 0. + + If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + to \c false, and success by setting *\a{ok} to \c true. + + This function ignores leading and trailing whitespace. + + \sa toLong(), toInt(), toDouble(), toString() + + \since 5.13 +*/ + +ulong QLocale::toULong(const QString &s, bool *ok) const +{ + return toIntegral_helper(d, s, ok); +} + /*! Returns the long long int represented by the localized string \a s. @@ -1499,6 +1541,48 @@ uint QLocale::toUInt(const QStringRef &s, bool *ok) const return toIntegral_helper(d, s, ok); } +/*! + Returns the long int represented by the localized string \a s. + + If the conversion fails the function returns 0. + + If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + to \c false, and success by setting *\a{ok} to \c true. + + This function ignores leading and trailing whitespace. + + \sa toInt(), toULong(), toDouble(), toString() + + \since 5.13 + */ + + +long QLocale::toLong(const QStringRef &s, bool *ok) const +{ + return toIntegral_helper(d, s, ok); +} + +/*! + Returns the unsigned long int represented by the localized + string \a s. + + If the conversion fails the function returns 0. + + If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + to \c false, and success by setting *\a{ok} to \c true. + + This function ignores leading and trailing whitespace. + + \sa toLong(), toInt(), toDouble(), toString() + + \since 5.13 + */ + +ulong QLocale::toULong(const QStringRef &s, bool *ok) const +{ + return toIntegral_helper(d, s, ok); +} + /*! Returns the long long int represented by the localized string \a s. @@ -1675,6 +1759,48 @@ uint QLocale::toUInt(QStringView s, bool *ok) const return toIntegral_helper(d, s, ok); } +/*! + Returns the long int represented by the localized string \a s. + + If the conversion fails the function returns 0. + + If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + to \c false, and success by setting *\a{ok} to \c true. + + This function ignores leading and trailing whitespace. + + \sa toInt(), toULong(), toDouble(), toString() + + \since 5.13 + */ + + +long QLocale::toLong(QStringView s, bool *ok) const +{ + return toIntegral_helper(d, s, ok); +} + +/*! + Returns the unsigned long int represented by the localized + string \a s. + + If the conversion fails the function returns 0. + + If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + to \c false, and success by setting *\a{ok} to \c true. + + This function ignores leading and trailing whitespace. + + \sa toLong(), toInt(), toDouble(), toString() + + \since 5.13 + */ + +ulong QLocale::toULong(QStringView s, bool *ok) const +{ + return toIntegral_helper(d, s, ok); +} + /*! Returns the long long int represented by the localized string \a s. diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h index 1fbd96c6d5..2b4f131552 100644 --- a/src/corelib/tools/qlocale.h +++ b/src/corelib/tools/qlocale.h @@ -961,6 +961,8 @@ public: ushort toUShort(const QString &s, bool *ok = nullptr) const; int toInt(const QString &s, bool *ok = nullptr) const; uint toUInt(const QString &s, bool *ok = nullptr) const; + long toLong(const QString &s, bool *ok = nullptr) const; + ulong toULong(const QString &s, bool *ok = nullptr) const; qlonglong toLongLong(const QString &s, bool *ok = nullptr) const; qulonglong toULongLong(const QString &s, bool *ok = nullptr) const; float toFloat(const QString &s, bool *ok = nullptr) const; @@ -970,6 +972,8 @@ public: ushort toUShort(const QStringRef &s, bool *ok = nullptr) const; int toInt(const QStringRef &s, bool *ok = nullptr) const; uint toUInt(const QStringRef &s, bool *ok = nullptr) const; + long toLong(const QStringRef &s, bool *ok = nullptr) const; + ulong toULong(const QStringRef &s, bool *ok = nullptr) const; qlonglong toLongLong(const QStringRef &s, bool *ok = nullptr) const; qulonglong toULongLong(const QStringRef &s, bool *ok = nullptr) const; float toFloat(const QStringRef &s, bool *ok = nullptr) const; @@ -980,6 +984,8 @@ public: ushort toUShort(QStringView s, bool *ok = nullptr) const; int toInt(QStringView s, bool *ok = nullptr) const; uint toUInt(QStringView s, bool *ok = nullptr) const; + long toLong(QStringView s, bool *ok = nullptr) const; + ulong toULong(QStringView s, bool *ok = nullptr) const; qlonglong toLongLong(QStringView s, bool *ok = nullptr) const; qulonglong toULongLong(QStringView s, bool *ok = nullptr) const; float toFloat(QStringView s, bool *ok = nullptr) const; @@ -987,6 +993,8 @@ public: QString toString(qlonglong i) const; QString toString(qulonglong i) const; + inline QString toString(long i) const; + inline QString toString(ulong i) const; inline QString toString(short i) const; inline QString toString(ushort i) const; inline QString toString(int i) const; @@ -1107,6 +1115,10 @@ private: Q_DECLARE_SHARED(QLocale) Q_DECLARE_OPERATORS_FOR_FLAGS(QLocale::NumberOptions) +inline QString QLocale::toString(long i) const + { return toString(qlonglong(i)); } +inline QString QLocale::toString(ulong i) const + { return toString(qulonglong(i)); } inline QString QLocale::toString(short i) const { return toString(qlonglong(i)); } inline QString QLocale::toString(ushort i) const diff --git a/src/corelib/tools/qlocale.qdoc b/src/corelib/tools/qlocale.qdoc index b852c10b8d..91b0ab6442 100644 --- a/src/corelib/tools/qlocale.qdoc +++ b/src/corelib/tools/qlocale.qdoc @@ -1163,6 +1163,30 @@ currency string. */ +/*! +\fn QString QLocale::toString(long i) const + +\overload + +\sa toLong() +*/ + +/*! +\fn QString QLocale::toString(ulong i) const + +\overload + +\sa toULong() +*/ + +/*! +\fn QString QLocale::toString(ushort i) const + +\overload + +\sa toUShort() +*/ + /*! \fn QString QLocale::toString(short i) const From 1136c9849e26423f72d7a0a7a92be8c93c13d7a6 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Thu, 21 Feb 2019 09:58:29 +0100 Subject: [PATCH 1233/1650] qmake: vcproj: Fix windeployqt config for dll targets Instead of hardcoding the target's extension to ".exe" we should rely on target information available in Visual Studio. $(TargetFileName) is documented as "The file name of the primary output file for the build (defined as base name + file extension)." so it can be used instead of $(TargetName) together with ".exe". Change-Id: I103d8d13456910617b2d53c9c8f4e2935eb93015 Reviewed-by: Kai Koehne --- qmake/generators/win32/msvc_vcproj.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 713a55d16b..f83e5c0247 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -1350,7 +1350,7 @@ void VcprojGenerator::initWinDeployQtTool() // structure manually by invoking windeployqt a second time, so that // the MDILXapCompile call succeeds and deployment continues. conf.windeployqt.CommandLine += commandLine - + QStringLiteral(" -list relative -dir \"$(MSBuildProjectDirectory)\" \"$(OutDir)\\$(TargetName).exe\" > ") + + QStringLiteral(" -list relative -dir \"$(MSBuildProjectDirectory)\" \"$(OutDir)\\$(TargetFileName)\" > ") + MakefileGenerator::shellQuote(conf.windeployqt.Record); conf.windeployqt.config = &vcProject.Configuration; conf.windeployqt.ExcludedFromBuild = false; From 3d7616a3160a5ae8bff5f901e4120ee152b43dc1 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Tue, 19 Feb 2019 12:36:07 +0100 Subject: [PATCH 1234/1650] offscreen: remove false condition This plugin does not use any XCB libs. This patch amends 94a4f06fb88ec6c7fa5e31dfd28af4e9b3cdbdd8 and 744be250bf8dbd3e5065662f55a4655c14aa512c Change-Id: I33e2647ace3d9f32a420551b3b198e33a182a06f Reviewed-by: Michal Klocek Reviewed-by: Allan Sandfeld Jensen --- src/plugins/platforms/offscreen/offscreen.pro | 2 +- src/plugins/platforms/offscreen/qoffscreenintegration.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/offscreen/offscreen.pro b/src/plugins/platforms/offscreen/offscreen.pro index a8f230a7b1..f226132592 100644 --- a/src/plugins/platforms/offscreen/offscreen.pro +++ b/src/plugins/platforms/offscreen/offscreen.pro @@ -17,7 +17,7 @@ HEADERS = qoffscreenintegration.h \ OTHER_FILES += offscreen.json -qtConfig(system-xcb):qtConfig(xlib):qtConfig(opengl):!qtConfig(opengles2) { +qtConfig(xlib):qtConfig(opengl):!qtConfig(opengles2) { SOURCES += qoffscreenintegration_x11.cpp HEADERS += qoffscreenintegration_x11.h QT += glx_support-private diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp index efd8fdf3fa..f2933b7179 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp +++ b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp @@ -66,7 +66,7 @@ #include -#if QT_CONFIG(system_xcb) && QT_CONFIG(xlib) && QT_CONFIG(opengl) && !QT_CONFIG(opengles2) +#if QT_CONFIG(xlib) && QT_CONFIG(opengl) && !QT_CONFIG(opengles2) #include "qoffscreenintegration_x11.h" #endif @@ -225,7 +225,7 @@ QPlatformServices *QOffscreenIntegration::services() const QOffscreenIntegration *QOffscreenIntegration::createOffscreenIntegration() { -#if QT_CONFIG(system_xcb) && QT_CONFIG(xlib) && QT_CONFIG(opengl) && !QT_CONFIG(opengles2) +#if QT_CONFIG(xlib) && QT_CONFIG(opengl) && !QT_CONFIG(opengles2) QByteArray glx = qgetenv("QT_QPA_OFFSCREEN_NO_GLX"); if (glx.isEmpty()) return new QOffscreenX11Integration; From b5c16921cca0d5ae966a36cb451ec0b322b967ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 21 Feb 2019 15:29:48 +0100 Subject: [PATCH 1235/1650] wasm: make setting the cursor shape work again Commit 960af0d64 ported away from EM_ASM but also changed the logic. Set the canvas.style.cursor property, like it originally did. Change-Id: Ie4b23abeae54173894bff1db000a305c459684bb Reviewed-by: Lorn Potter --- src/plugins/platforms/wasm/qwasmcursor.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/wasm/qwasmcursor.cpp b/src/plugins/platforms/wasm/qwasmcursor.cpp index 90431ab6a5..744b160dd1 100644 --- a/src/plugins/platforms/wasm/qwasmcursor.cpp +++ b/src/plugins/platforms/wasm/qwasmcursor.cpp @@ -53,7 +53,8 @@ void QWasmCursor::changeCursor(QCursor *windowCursor, QWindow *window) htmlCursorName = "auto"; // Set cursor on the main canvas - emscripten::val::global("window").set("cursor", emscripten::val(htmlCursorName.constData())); + emscripten::val canvasStyle = emscripten::val::module_property("canvas")["style"]; + canvasStyle.set("cursor", emscripten::val(htmlCursorName.constData())); } QByteArray QWasmCursor::cursorShapeToHtml(Qt::CursorShape shape) From 46589056c399191e1afe0b2ddb1e2f0570fa8ddc Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 12 Feb 2019 12:45:50 +0100 Subject: [PATCH 1236/1650] QObject: count declarative receivers also if there are no C++ ones Change-Id: If998cdd5eeb8a3ae85cd540cc9c1fd0c051e1d4b Fixes: QTBUG-73753 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/kernel/qobject.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 257575e141..7b9689f1cf 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -2404,8 +2404,7 @@ int QObject::receivers(const char *signal) const { Q_D(const QObject); int receivers = 0; - QObjectPrivate::ConnectionData *cd = d->connections.load(); - if (signal && cd) { + if (signal) { QByteArray signal_name = QMetaObject::normalizedSignature(signal); signal = signal_name; #ifndef QT_NO_DEBUG @@ -2429,8 +2428,9 @@ int QObject::receivers(const char *signal) const signal_index); } + QObjectPrivate::ConnectionData *cd = d->connections.load(); QBasicMutexLocker locker(signalSlotLock(this)); - if (signal_index < cd->signalVector.count()) { + if (cd && signal_index < cd->signalVector.count()) { const QObjectPrivate::Connection *c = cd->signalVector.at(signal_index).first; while (c) { From 0f431712fbcb3775d85891a97ccb080d0da581e0 Mon Sep 17 00:00:00 2001 From: Mikhail Svetkin Date: Fri, 4 Jan 2019 16:26:19 +0100 Subject: [PATCH 1237/1650] qtlite: Add a new option -no-pcre pcre only used by QRegularExpression. Change-Id: I704bdb46ed8956f875e1f5fcc0fa2e06122fd87e Reviewed-by: Lars Knoll --- config_help.txt | 2 +- src/corelib/configure.json | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/config_help.txt b/config_help.txt index 18f66c7931..77a333c89a 100644 --- a/config_help.txt +++ b/config_help.txt @@ -241,7 +241,7 @@ Core options: -inotify ............. Enable inotify support -iconv ............... Enable iconv(3) support [posix/sun/gnu/no] (Unix only) -icu ................. Enable ICU support [auto] - -pcre ................ Select used libpcre2 [system/qt] + -pcre ................ Select used libpcre2 [system/qt/no] -pps ................. Enable PPS support [auto] (QNX only) -zlib ................ Select used zlib [system/qt] diff --git a/src/corelib/configure.json b/src/corelib/configure.json index 948aa0829b..81768507f6 100644 --- a/src/corelib/configure.json +++ b/src/corelib/configure.json @@ -11,7 +11,7 @@ "icu": "boolean", "inotify": "boolean", "journald": "boolean", - "pcre": { "type": "enum", "values": [ "qt", "system" ] }, + "pcre": { "type": "enum", "values": [ "no", "qt", "system" ] }, "posix-ipc": { "type": "boolean", "name": "ipc_posix" }, "pps": { "type": "boolean", "name": "qqnx_pps" }, "slog2": "boolean", @@ -662,15 +662,18 @@ "condition": "features.textcodec", "output": [ "publicFeature", "feature" ] }, + "pcre2": { + "label": "PCRE2", + "disable": "input.pcre == 'no' || input.pcre == 'system'", + "enable": "input.pcre == 'qt'", + "output": [ "privateConfig" ] + }, "system-pcre2": { - "label": "Using system PCRE2", - "disable": "input.pcre == 'qt'", + "label": " Using system PCRE2", + "disable": "input.pcre == 'no' || input.pcre == 'qt'", "enable": "input.pcre == 'system'", "condition": "libs.pcre2", - "output": [ - "privateFeature", - { "type": "privateConfig", "negative": true, "name": "pcre2" } - ] + "output": [ "privateFeature" ] }, "poll_ppoll": { "label": "Native ppoll()", @@ -749,6 +752,7 @@ "label": "QRegularExpression", "purpose": "Provides an API to Perl-compatible regular expressions.", "section": "Kernel", + "condition": "features.system-pcre2 || features.pcre2", "output": [ "publicFeature", "feature" ] }, "sharedmemory": { @@ -1048,6 +1052,7 @@ Please apply the patch corresponding to your Standard Library vendor, found in "args": "qqnx_pps", "condition": "config.qnx" }, + "pcre2", "system-pcre2" ] } From 2be7746e0922fa404da567fd0bc0cbc00c6215cb Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Wed, 30 Jan 2019 14:11:07 +0100 Subject: [PATCH 1238/1650] Fix a typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit in a comment. Change-Id: I10252b2e732636993daba6b72ed86116691f2030 Reviewed-by: Mårten Nordheim Reviewed-by: Jesus Fernandez --- src/network/ssl/qsslsocket_openssl.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index c48cd42360..6a8269b521 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -476,7 +476,8 @@ bool QSslSocketBackendPrivate::initSslContext() { Q_Q(QSslSocket); - // If no external context was set (e.g. bei QHttpNetworkConnection) we will create a default context + // If no external context was set (e.g. by QHttpNetworkConnection) we will + // create a default context if (!sslContextPointer) { // create a deep copy of our configuration QSslConfigurationPrivate *configurationCopy = new QSslConfigurationPrivate(configuration); From c204f6e417fe9b10df29e0ba00c7a94e0aa52cef Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 20 Feb 2019 14:14:28 +0100 Subject: [PATCH 1239/1650] Update and expand public suffix list's attribution information Say where the git repo is, for finding commit IDs, but make clear that the download should come from the public site. Revised Description to the closest match to it I could find on the current web-site (on the home page). Mention where the script to convert the data live. Task-number: QTBUG-72623 Change-Id: Ie5f7b2b0c21cdf1c24e311c13866cb1bb02e6973 Reviewed-by: Allan Sandfeld Jensen --- src/corelib/io/qt_attribution.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qt_attribution.json b/src/corelib/io/qt_attribution.json index e9eb9c85e4..c52df67d98 100644 --- a/src/corelib/io/qt_attribution.json +++ b/src/corelib/io/qt_attribution.json @@ -2,7 +2,7 @@ "Id": "psl", "Name": "The Public Suffix List", "QDocModule": "qtcore", - "Description": "The Public Suffix List is an initiative of the Mozilla Project, + "Description": "The Public Suffix List is an initiative of Mozilla, but is maintained as a community resource. It is available for use in any software, but was originally created to meet the needs of browser manufacturers. It allows browsers to, for example: @@ -14,9 +14,11 @@ It allows browsers to, for example: - Accurately sort history entries by site", "Files": "qurltlds_p.h", - "QtUsage": "Used in Qt Core to avoid \"supercookies\" being set in the cookie jar + "QtUsage": "See util/corelib/qurl-generateTLDs/ for code-generator", + "QtUsage": "Used in Qt Core to avoid setting \"supercookies\" in the cookie jar supported by Qt (by the QNetworkCookieJar class).", + "Homepage": "Consult https://github.com/publicsuffix/list for the sha1 but download from ...", "Homepage": "http://publicsuffix.org/", "Version": "Generated on 2018-01-04", "License": "Mozilla Public License 2.0", From 656ce9fa9dd1a5cb268f8e3225b2ed65c05365db Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Sat, 9 Feb 2019 11:14:37 +0100 Subject: [PATCH 1240/1650] QGraphicsItemAnimation: add transformAt() an deprecate matrixAt() Replace QGraphicsItemAnimation::matrixAt(qreal) with transformAt(qreal) to avoid the usage of QMatrix which is deprecated. Change-Id: Iafcdf8b9b2fbffffa61417601a3ae4272d0176c6 Reviewed-by: Allan Sandfeld Jensen --- src/widgets/doc/snippets/timeline/main.cpp | 4 +-- .../graphicsview/qgraphicsitemanimation.cpp | 33 ++++++++++++++----- .../graphicsview/qgraphicsitemanimation.h | 5 +++ .../tst_qgraphicsitemanimation.cpp | 6 ++-- 4 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/widgets/doc/snippets/timeline/main.cpp b/src/widgets/doc/snippets/timeline/main.cpp index 74aa749254..4dfa2400d0 100644 --- a/src/widgets/doc/snippets/timeline/main.cpp +++ b/src/widgets/doc/snippets/timeline/main.cpp @@ -48,7 +48,7 @@ ** ****************************************************************************/ -#include +#include #include int main(int argv, char *args[]) @@ -68,7 +68,7 @@ int main(int argv, char *args[]) for (int i = 0; i < 200; ++i) animation->setPosAt(i / 200.0, QPointF(i, i)); - QGraphicsScene *scene = new QGraphicsScene(); + QGraphicsScene *scene = new QGraphicsScene; scene->setSceneRect(0, 0, 250, 250); scene->addItem(ball); diff --git a/src/widgets/graphicsview/qgraphicsitemanimation.cpp b/src/widgets/graphicsview/qgraphicsitemanimation.cpp index 78b91d5c39..ad77e2f260 100644 --- a/src/widgets/graphicsview/qgraphicsitemanimation.cpp +++ b/src/widgets/graphicsview/qgraphicsitemanimation.cpp @@ -115,7 +115,7 @@ public: QGraphicsItem *item; QPointF startPos; - QMatrix startMatrix; + QTransform startTransform; qreal step; @@ -294,23 +294,38 @@ QList > QGraphicsItemAnimation::posList() const return list; } +#if QT_DEPRECATED_SINCE(5, 14) /*! Returns the matrix used to transform the item at the specified \a step value. + + \obsolete Use transformAt() instead */ QMatrix QGraphicsItemAnimation::matrixAt(qreal step) const { check_step_valid(step, "matrixAt"); + return transformAt(step).toAffine(); +} +#endif - QMatrix matrix; +/*! + Returns the transform used for the item at the specified \a step value. + + \since 5.14 +*/ +QTransform QGraphicsItemAnimation::transformAt(qreal step) const +{ + check_step_valid(step, "transformAt"); + + QTransform transform; if (!d->rotation.isEmpty()) - matrix.rotate(rotationAt(step)); + transform.rotate(rotationAt(step)); if (!d->verticalScale.isEmpty()) - matrix.scale(horizontalScaleAt(step), verticalScaleAt(step)); + transform.scale(horizontalScaleAt(step), verticalScaleAt(step)); if (!d->verticalShear.isEmpty()) - matrix.shear(horizontalShearAt(step), verticalShearAt(step)); + transform.shear(horizontalShearAt(step), verticalShearAt(step)); if (!d->xTranslation.isEmpty()) - matrix.translate(xTranslationAt(step), yTranslationAt(step)); - return matrix; + transform.translate(xTranslationAt(step), yTranslationAt(step)); + return transform; } /*! @@ -542,7 +557,7 @@ void QGraphicsItemAnimation::setStep(qreal step) || !d->horizontalShear.isEmpty() || !d->xTranslation.isEmpty() || !d->yTranslation.isEmpty()) { - d->item->setMatrix(d->startMatrix * matrixAt(step)); + d->item->setTransform(d->startTransform * transformAt(step)); } } @@ -562,7 +577,7 @@ void QGraphicsItemAnimation::reset() if (!d->item) return; d->startPos = d->item->pos(); - d->startMatrix = d->item->matrix(); + d->startTransform = d->item->transform(); } #endif diff --git a/src/widgets/graphicsview/qgraphicsitemanimation.h b/src/widgets/graphicsview/qgraphicsitemanimation.h index f983bd8026..3051fb2e2b 100644 --- a/src/widgets/graphicsview/qgraphicsitemanimation.h +++ b/src/widgets/graphicsview/qgraphicsitemanimation.h @@ -51,6 +51,7 @@ class QGraphicsItem; class QMatrix; class QPointF; class QTimeLine; +class QTransform; template struct QPair; class QGraphicsItemAnimationPrivate; @@ -71,7 +72,11 @@ public: QList > posList() const; void setPosAt(qreal step, const QPointF &pos); +#if QT_DEPRECATED_SINCE(5, 14) + QT_DEPRECATED_X("Use transformAt() instead") QMatrix matrixAt(qreal step) const; +#endif + QTransform transformAt(qreal step) const; qreal rotationAt(qreal step) const; QList > rotationList() const; diff --git a/tests/auto/widgets/graphicsview/qgraphicsitemanimation/tst_qgraphicsitemanimation.cpp b/tests/auto/widgets/graphicsview/qgraphicsitemanimation/tst_qgraphicsitemanimation.cpp index dfb2752ee0..ed79904ed8 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsitemanimation/tst_qgraphicsitemanimation.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsitemanimation/tst_qgraphicsitemanimation.cpp @@ -54,9 +54,9 @@ void tst_QGraphicsItemAnimation::construction() QCOMPARE(animation.posAt(0), QPointF()); QCOMPARE(animation.posAt(0.5), QPointF()); QCOMPARE(animation.posAt(1), QPointF()); - QCOMPARE(animation.matrixAt(0), QMatrix()); - QCOMPARE(animation.matrixAt(0.5), QMatrix()); - QCOMPARE(animation.matrixAt(1), QMatrix()); + QCOMPARE(animation.transformAt(0), QTransform()); + QCOMPARE(animation.transformAt(0.5), QTransform()); + QCOMPARE(animation.transformAt(1), QTransform()); QCOMPARE(animation.rotationAt(0), qreal(0.0)); QCOMPARE(animation.rotationAt(0.5), qreal(0.0)); QCOMPARE(animation.rotationAt(1), qreal(0.0)); From bdf1c4f671c706832cea84269e91995e85eb9f07 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Tue, 5 Feb 2019 20:30:43 +0100 Subject: [PATCH 1241/1650] QComboBox: add two new signals textHighlighted() and textActivated() To avoid overloaded signals for highlighted() and activated() add two new signals textHighlighted()/textActivated() and deprecate the old QString overloads. [ChangeLog][QtWidgets][QComboBox] Two new signals textHighlighted() and textActivated() were added to replace highlighted()/activated() QString overloads Change-Id: I62df7e606b335b5c756315a800654d7d0de442bd Reviewed-by: Shawn Rutledge --- src/widgets/widgets/qcombobox.cpp | 6 ++++++ src/widgets/widgets/qcombobox.h | 12 +++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 1ad43fffb4..aa520e37a2 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -1364,7 +1364,10 @@ void QComboBoxPrivate::emitActivated(const QModelIndex &index) return; QString text(itemText(index)); emit q->activated(index.row()); + emit q->textActivated(text); +#if QT_DEPRECATED_SINCE(5, 15) emit q->activated(text); +#endif } void QComboBoxPrivate::_q_emitHighlighted(const QModelIndex &index) @@ -1374,7 +1377,10 @@ void QComboBoxPrivate::_q_emitHighlighted(const QModelIndex &index) return; QString text(itemText(index)); emit q->highlighted(index.row()); + emit q->textHighlighted(text); +#if QT_DEPRECATED_SINCE(5, 15) emit q->highlighted(text); +#endif } void QComboBoxPrivate::_q_emitCurrentIndexChanged(const QModelIndex &index) diff --git a/src/widgets/widgets/qcombobox.h b/src/widgets/widgets/qcombobox.h index 64fbebb3c5..6a87a675a4 100644 --- a/src/widgets/widgets/qcombobox.h +++ b/src/widgets/widgets/qcombobox.h @@ -220,15 +220,21 @@ public Q_SLOTS: Q_SIGNALS: void editTextChanged(const QString &); void activated(int index); - void activated(const QString &); + void textActivated(const QString &); void highlighted(int index); - void highlighted(const QString &); + void textHighlighted(const QString &); void currentIndexChanged(int index); + void currentTextChanged(const QString &); #if QT_DEPRECATED_SINCE(5, 13) QT_DEPRECATED_X("Use currentTextChanged() instead") void currentIndexChanged(const QString &); #endif - void currentTextChanged(const QString &); +#if QT_DEPRECATED_SINCE(5, 15) + QT_DEPRECATED_X("Use textActivated() instead") + void activated(const QString &); + QT_DEPRECATED_X("Use textHighlighted() instead") + void highlighted(const QString &); +#endif protected: void focusInEvent(QFocusEvent *e) override; From 8c10255e377c38a8655c733dc527674b1f5cb3da Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Wed, 23 Jan 2019 16:31:35 +0100 Subject: [PATCH 1242/1650] Add conversion to and from long and ulong This implements conversion parity with QString, which can convert to and from long and unsigned long. The implementation simply forwards to existing long long overloads or uses the existing helpers, so just as for the conversion to/from int or short, no additional test cases were added. Change-Id: I37ef06d9ce4d80d98bd72720353996bac723e09c Fixes: QTBUG-782 Reviewed-by: Volker Hilsheimer (cherry picked from commit 783953f09dcfe9c58dc991394535ba07dabe2560) Reviewed-by: Edward Welbourne --- src/corelib/tools/qlocale.cpp | 126 +++++++++++++++++++++++++++++++++ src/corelib/tools/qlocale.h | 12 ++++ src/corelib/tools/qlocale.qdoc | 24 +++++++ 3 files changed, 162 insertions(+) diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index b3fb079342..ebb6c97975 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -1332,6 +1332,48 @@ uint QLocale::toUInt(const QString &s, bool *ok) const return toIntegral_helper(d, s, ok); } +/*! + Returns the long int represented by the localized string \a s. + + If the conversion fails the function returns 0. + + If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + to \c false, and success by setting *\a{ok} to \c true. + + This function ignores leading and trailing whitespace. + + \sa toInt(), toULong(), toDouble(), toString() + + \since 5.13 + */ + + +long QLocale::toLong(const QString &s, bool *ok) const +{ + return toIntegral_helper(d, s, ok); +} + +/*! + Returns the unsigned long int represented by the localized + string \a s. + + If the conversion fails the function returns 0. + + If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + to \c false, and success by setting *\a{ok} to \c true. + + This function ignores leading and trailing whitespace. + + \sa toLong(), toInt(), toDouble(), toString() + + \since 5.13 +*/ + +ulong QLocale::toULong(const QString &s, bool *ok) const +{ + return toIntegral_helper(d, s, ok); +} + /*! Returns the long long int represented by the localized string \a s. @@ -1499,6 +1541,48 @@ uint QLocale::toUInt(const QStringRef &s, bool *ok) const return toIntegral_helper(d, s, ok); } +/*! + Returns the long int represented by the localized string \a s. + + If the conversion fails the function returns 0. + + If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + to \c false, and success by setting *\a{ok} to \c true. + + This function ignores leading and trailing whitespace. + + \sa toInt(), toULong(), toDouble(), toString() + + \since 5.13 + */ + + +long QLocale::toLong(const QStringRef &s, bool *ok) const +{ + return toIntegral_helper(d, s, ok); +} + +/*! + Returns the unsigned long int represented by the localized + string \a s. + + If the conversion fails the function returns 0. + + If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + to \c false, and success by setting *\a{ok} to \c true. + + This function ignores leading and trailing whitespace. + + \sa toLong(), toInt(), toDouble(), toString() + + \since 5.13 + */ + +ulong QLocale::toULong(const QStringRef &s, bool *ok) const +{ + return toIntegral_helper(d, s, ok); +} + /*! Returns the long long int represented by the localized string \a s. @@ -1675,6 +1759,48 @@ uint QLocale::toUInt(QStringView s, bool *ok) const return toIntegral_helper(d, s, ok); } +/*! + Returns the long int represented by the localized string \a s. + + If the conversion fails the function returns 0. + + If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + to \c false, and success by setting *\a{ok} to \c true. + + This function ignores leading and trailing whitespace. + + \sa toInt(), toULong(), toDouble(), toString() + + \since 5.13 + */ + + +long QLocale::toLong(QStringView s, bool *ok) const +{ + return toIntegral_helper(d, s, ok); +} + +/*! + Returns the unsigned long int represented by the localized + string \a s. + + If the conversion fails the function returns 0. + + If \a ok is not \c nullptr, failure is reported by setting *\a{ok} + to \c false, and success by setting *\a{ok} to \c true. + + This function ignores leading and trailing whitespace. + + \sa toLong(), toInt(), toDouble(), toString() + + \since 5.13 + */ + +ulong QLocale::toULong(QStringView s, bool *ok) const +{ + return toIntegral_helper(d, s, ok); +} + /*! Returns the long long int represented by the localized string \a s. diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h index 1fbd96c6d5..2b4f131552 100644 --- a/src/corelib/tools/qlocale.h +++ b/src/corelib/tools/qlocale.h @@ -961,6 +961,8 @@ public: ushort toUShort(const QString &s, bool *ok = nullptr) const; int toInt(const QString &s, bool *ok = nullptr) const; uint toUInt(const QString &s, bool *ok = nullptr) const; + long toLong(const QString &s, bool *ok = nullptr) const; + ulong toULong(const QString &s, bool *ok = nullptr) const; qlonglong toLongLong(const QString &s, bool *ok = nullptr) const; qulonglong toULongLong(const QString &s, bool *ok = nullptr) const; float toFloat(const QString &s, bool *ok = nullptr) const; @@ -970,6 +972,8 @@ public: ushort toUShort(const QStringRef &s, bool *ok = nullptr) const; int toInt(const QStringRef &s, bool *ok = nullptr) const; uint toUInt(const QStringRef &s, bool *ok = nullptr) const; + long toLong(const QStringRef &s, bool *ok = nullptr) const; + ulong toULong(const QStringRef &s, bool *ok = nullptr) const; qlonglong toLongLong(const QStringRef &s, bool *ok = nullptr) const; qulonglong toULongLong(const QStringRef &s, bool *ok = nullptr) const; float toFloat(const QStringRef &s, bool *ok = nullptr) const; @@ -980,6 +984,8 @@ public: ushort toUShort(QStringView s, bool *ok = nullptr) const; int toInt(QStringView s, bool *ok = nullptr) const; uint toUInt(QStringView s, bool *ok = nullptr) const; + long toLong(QStringView s, bool *ok = nullptr) const; + ulong toULong(QStringView s, bool *ok = nullptr) const; qlonglong toLongLong(QStringView s, bool *ok = nullptr) const; qulonglong toULongLong(QStringView s, bool *ok = nullptr) const; float toFloat(QStringView s, bool *ok = nullptr) const; @@ -987,6 +993,8 @@ public: QString toString(qlonglong i) const; QString toString(qulonglong i) const; + inline QString toString(long i) const; + inline QString toString(ulong i) const; inline QString toString(short i) const; inline QString toString(ushort i) const; inline QString toString(int i) const; @@ -1107,6 +1115,10 @@ private: Q_DECLARE_SHARED(QLocale) Q_DECLARE_OPERATORS_FOR_FLAGS(QLocale::NumberOptions) +inline QString QLocale::toString(long i) const + { return toString(qlonglong(i)); } +inline QString QLocale::toString(ulong i) const + { return toString(qulonglong(i)); } inline QString QLocale::toString(short i) const { return toString(qlonglong(i)); } inline QString QLocale::toString(ushort i) const diff --git a/src/corelib/tools/qlocale.qdoc b/src/corelib/tools/qlocale.qdoc index b852c10b8d..91b0ab6442 100644 --- a/src/corelib/tools/qlocale.qdoc +++ b/src/corelib/tools/qlocale.qdoc @@ -1163,6 +1163,30 @@ currency string. */ +/*! +\fn QString QLocale::toString(long i) const + +\overload + +\sa toLong() +*/ + +/*! +\fn QString QLocale::toString(ulong i) const + +\overload + +\sa toULong() +*/ + +/*! +\fn QString QLocale::toString(ushort i) const + +\overload + +\sa toUShort() +*/ + /*! \fn QString QLocale::toString(short i) const From a2b31cd5db6410144a613142a7b60f0cd2ba2b1d Mon Sep 17 00:00:00 2001 From: Kirill Burtsev Date: Tue, 19 Feb 2019 15:21:58 +0100 Subject: [PATCH 1243/1650] Fix build for size with gcc Fixes the error: variable 'isDifferent' set but not used Change-Id: Ibd60b17126057da64a41d325b7ef548316f27c4b Reviewed-by: Edward Welbourne Reviewed-by: Thiago Macieira --- src/corelib/tools/qstring.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 63d44eb39c..d8bfb69a8b 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -1047,6 +1047,7 @@ static int ucstrncmp(const QChar *a, const uchar *c, size_t l) __m128i nullmask = _mm_setzero_si128(); qptrdiff offset = 0; +# if !defined(__OPTIMIZE_SIZE__) // Using the PMOVMSKB instruction, we get two bits for each character // we compare. int retval; @@ -1059,6 +1060,7 @@ static int ucstrncmp(const QChar *a, const uchar *c, size_t l) retval = uc[offset + idx / 2] - c[offset + idx / 2]; return true; }; +# endif // we're going to read uc[offset..offset+15] (32 bytes) // and c[offset..offset+15] (16 bytes) From 36c2ceca955940e306abb966d1c768895ccf1014 Mon Sep 17 00:00:00 2001 From: Kari Oikarinen Date: Mon, 25 Feb 2019 09:37:31 +0200 Subject: [PATCH 1244/1650] Bump version Change-Id: I5561df4b90b02d88bb2fc7b52d74487e71efce7d --- .qmake.conf | 2 +- src/corelib/serialization/qdatastream.cpp | 1 + src/corelib/serialization/qdatastream.h | 5 +++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.qmake.conf b/.qmake.conf index c92e38c48f..08e1a4723c 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -4,4 +4,4 @@ CONFIG += warning_clean QT_SOURCE_TREE = $$PWD QT_BUILD_TREE = $$shadowed($$PWD) -MODULE_VERSION = 5.13.0 +MODULE_VERSION = 5.14.0 diff --git a/src/corelib/serialization/qdatastream.cpp b/src/corelib/serialization/qdatastream.cpp index ead6ed5083..3ea518907b 100644 --- a/src/corelib/serialization/qdatastream.cpp +++ b/src/corelib/serialization/qdatastream.cpp @@ -561,6 +561,7 @@ void QDataStream::setByteOrder(ByteOrder bo) \value Qt_5_11 Same as Qt_5_6 \value Qt_5_12 Version 18 (Qt 5.12) \value Qt_5_13 Version 19 (Qt 5.13) + \value Qt_5_14 Same as Qt_5_13 \omitvalue Qt_DefaultCompiledVersion \sa setVersion(), version() diff --git a/src/corelib/serialization/qdatastream.h b/src/corelib/serialization/qdatastream.h index 81134f74b0..6e358df02e 100644 --- a/src/corelib/serialization/qdatastream.h +++ b/src/corelib/serialization/qdatastream.h @@ -100,10 +100,11 @@ public: Qt_5_11 = Qt_5_10, Qt_5_12 = 18, Qt_5_13 = 19, -#if QT_VERSION >= 0x050e00 + Qt_5_14 = Qt_5_13, +#if QT_VERSION >= 0x050f00 #error Add the datastream version for this Qt version and update Qt_DefaultCompiledVersion #endif - Qt_DefaultCompiledVersion = Qt_5_13 + Qt_DefaultCompiledVersion = Qt_5_14 }; enum ByteOrder { From 1e0395f73e624bf9d40f508acd3da08294006947 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Thu, 7 Feb 2019 12:18:07 +0100 Subject: [PATCH 1245/1650] Fix assert when drawing lines with extreme coordinates For extreme coordinates, the rasterizer's width parameter could become NaN, which compares false with everything and hence would trigger an assert. Fixes: QTBUG-56434 Change-Id: I27abae6ab0bc94ce042be86ea0587095cdb7d487 Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qrasterizer.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/gui/painting/qrasterizer.cpp b/src/gui/painting/qrasterizer.cpp index 52501880e4..b4014272f4 100644 --- a/src/gui/painting/qrasterizer.cpp +++ b/src/gui/painting/qrasterizer.cpp @@ -755,11 +755,9 @@ static inline int qSafeFloatToQ16Dot16(qreal x) void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, bool squareCap) { - if (a == b || width == 0 || d->clipRect.isEmpty()) + if (a == b || !(width > 0.0) || d->clipRect.isEmpty()) return; - Q_ASSERT(width > 0.0); - QPointF pa = a; QPointF pb = b; From b56cfce73288263624f490c06215fad1026297b4 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 14 Feb 2019 11:03:17 -0800 Subject: [PATCH 1246/1650] Make the qfloat16tables.cpp depend on the executable, not the command qtPrepareTool could return a more complex command-line in the variable, for some reason. So declare the dependency on the actual executable only. Change-Id: Id061f35c088044b69a15fffd1583504f25936a7a Reviewed-by: Oswald Buddenhagen Reviewed-by: Joerg Bornemann --- src/corelib/global/global.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri index a4d132a4f4..029357ff43 100644 --- a/src/corelib/global/global.pri +++ b/src/corelib/global/global.pri @@ -131,7 +131,7 @@ qtPrepareTool(QMAKE_QFLOAT16_TABLES, qfloat16-tables) qfloat16_tables.commands = $$QMAKE_QFLOAT16_TABLES ${QMAKE_FILE_OUT} qfloat16_tables.output = global/qfloat16tables.cpp -qfloat16_tables.depends = $$QMAKE_QFLOAT16_TABLES +qfloat16_tables.depends = $$QMAKE_QFLOAT16_TABLES_EXE qfloat16_tables.input = QMAKE_QFLOAT16_TABLES_GENERATE qfloat16_tables.variable_out = SOURCES QMAKE_EXTRA_COMPILERS += qfloat16_tables From 241533962c56e79fe6809bfa81e3ffb34850942c Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Fri, 22 Feb 2019 15:58:11 +0100 Subject: [PATCH 1247/1650] Add ### Qt6 comment requested in code-review Task-number: QTBUG-73484 Change-Id: I7c1c5faf3d32fa21d8d2277ec434084450290156 Reviewed-by: Thiago Macieira --- src/dbus/qdbusargument.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dbus/qdbusargument.h b/src/dbus/qdbusargument.h index ac650d5f62..94a89a4e08 100644 --- a/src/dbus/qdbusargument.h +++ b/src/dbus/qdbusargument.h @@ -158,6 +158,7 @@ QT_END_NAMESPACE Q_DECLARE_METATYPE(QDBusArgument) QT_BEGIN_NAMESPACE +// ### Qt6: remove the defaulted T * = nullptr from these two (MSVC6 work-around): template inline T qdbus_cast(const QDBusArgument &arg, T * = nullptr) { T item; From 79644952f7e6e44e20820ffde5e974d7254329c7 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 20 Feb 2019 10:30:58 +0100 Subject: [PATCH 1248/1650] Revise download location for pcre2 in its qt_attribution.json file Changed DownloadLocation to match the version claimed in Version, 10.32, rather than the 10.31 tar-ball's URL. Task-number: QTBUG-72623 Change-Id: Id3e17085ea9bb0a854c95e4dce7f472cc38923ed Reviewed-by: Thiago Macieira --- src/3rdparty/pcre2/qt_attribution.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/3rdparty/pcre2/qt_attribution.json b/src/3rdparty/pcre2/qt_attribution.json index 828c4e8314..72f04e7c06 100644 --- a/src/3rdparty/pcre2/qt_attribution.json +++ b/src/3rdparty/pcre2/qt_attribution.json @@ -8,7 +8,7 @@ "Description": "The PCRE library is a set of functions that implement regular expression pattern matching using the same syntax and semantics as Perl 5.", "Homepage": "http://www.pcre.org/", "Version": "10.32", - "DownloadLocation": "https://ftp.pcre.org/pub/pcre/pcre2-10.31.tar.bz2", + "DownloadLocation": "https://ftp.pcre.org/pub/pcre/pcre2-10.32.tar.bz2", "License": "BSD 3-clause \"New\" or \"Revised\" License", "LicenseId": "BSD-3-Clause", "LicenseFile": "LICENCE", @@ -27,7 +27,7 @@ Copyright (c) 2013-2013 Tilera Corporation (jiwang@tilera.com)" "Description": "The PCRE library is a set of functions that implement regular expression pattern matching using the same syntax and semantics as Perl 5.", "Homepage": "http://www.pcre.org/", "Version": "10.32", - "DownloadLocation": "https://ftp.pcre.org/pub/pcre/pcre2-10.31.tar.bz2", + "DownloadLocation": "https://ftp.pcre.org/pub/pcre/pcre2-10.32.tar.bz2", "License": "BSD 2-clause \"Simplified\" License", "LicenseId": "BSD-2-Clause", "LicenseFile": "LICENCE-SLJIT", From d6d80ff2e925c5c52de498535cfdb808b3bd3670 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 21 Feb 2019 16:43:58 +0100 Subject: [PATCH 1249/1650] Automatic resources: Fix tooling support The files to be put into an auto-generated qrc file must not simply disappear, because IDE users still need to have them in the project tree. So we add them to OTHER_FILES now. Task-number: QTCREATORBUG-20103 Task-number: QTCREATORBUG-20104 Change-Id: I8a9136491f975def7c33385e375c407815ad269a Reviewed-by: hjk Reviewed-by: Joerg Bornemann --- mkspecs/features/resources.prf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mkspecs/features/resources.prf b/mkspecs/features/resources.prf index bb2a55b93d..b4e0db6445 100644 --- a/mkspecs/features/resources.prf +++ b/mkspecs/features/resources.prf @@ -28,6 +28,7 @@ for(resource, RESOURCES) { !exists($$absolute_path($$resource, $$_PRO_FILE_PWD_)): \ warning("Failure to find: $$resource") qmake_immediate.files += $$resource + OTHER_FILES *= $$resource } RESOURCES -= $$resource next() @@ -57,6 +58,7 @@ for(resource, RESOURCES) { alias = $$relative_path($$file, $$abs_base) resource_file_content += \ "$$xml_escape($$file)" + OTHER_FILES *= $$file } } From 1be070a2bef8b85caa5722ede60092b6038b13e6 Mon Sep 17 00:00:00 2001 From: Mikhail Svetkin Date: Tue, 22 Jan 2019 14:49:34 +0100 Subject: [PATCH 1250/1650] qtlite: Fix build the source code with -no-feature-shortcut Change-Id: If47149466a5da901e3eb6e6f2dcfb0a7816bc60b Reviewed-by: Gatis Paeglis --- .../xdgdesktopportal/qxdgdesktopportaltheme.cpp | 2 ++ .../platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.h | 2 ++ src/testlib/qtestkeyboard.h | 4 ++++ 3 files changed, 8 insertions(+) diff --git a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp index f07ca3f098..fb65f6d909 100644 --- a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp +++ b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.cpp @@ -185,11 +185,13 @@ QIconEngine * QXdgDesktopPortalTheme::createIconEngine(const QString &iconName) return d->baseTheme->createIconEngine(iconName); } +#if QT_CONFIG(shortcut) QList QXdgDesktopPortalTheme::keyBindings(QKeySequence::StandardKey key) const { Q_D(const QXdgDesktopPortalTheme); return d->baseTheme->keyBindings(key); } +#endif QString QXdgDesktopPortalTheme::standardButtonText(int button) const { diff --git a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.h b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.h index b72e676419..4c5f474595 100644 --- a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.h +++ b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportaltheme.h @@ -76,7 +76,9 @@ public: QIconEngine *createIconEngine(const QString &iconName) const override; +#if QT_CONFIG(shortcut) QList keyBindings(QKeySequence::StandardKey key) const override; +#endif QString standardButtonText(int button) const override; diff --git a/src/testlib/qtestkeyboard.h b/src/testlib/qtestkeyboard.h index 63501ffb1e..e8a7e0d5f5 100644 --- a/src/testlib/qtestkeyboard.h +++ b/src/testlib/qtestkeyboard.h @@ -166,6 +166,7 @@ namespace QTest Q_DECL_UNUSED inline static void keyPress(QWindow *window, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1) { keyEvent(Press, window, key, modifier, delay); } +#if QT_CONFIG(shortcut) Q_DECL_UNUSED inline static void keySequence(QWindow *window, const QKeySequence &keySequence) { for (int i = 0; i < keySequence.count(); ++i) { @@ -174,6 +175,7 @@ namespace QTest keyClick(window, key, modifiers); } } +#endif #ifdef QT_WIDGETS_LIB static void simulateEvent(QWidget *widget, bool press, int code, @@ -305,6 +307,7 @@ namespace QTest inline static void keyClick(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1) { keyEvent(Click, widget, key, modifier, delay); } +#if QT_CONFIG(shortcut) inline static void keySequence(QWidget *widget, const QKeySequence &keySequence) { for (int i = 0; i < keySequence.count(); ++i) { @@ -313,6 +316,7 @@ namespace QTest keyClick(widget, key, modifiers); } } +#endif #endif // QT_WIDGETS_LIB From 85b0ce8ca36d52db71b519ee8d2a1ce369c53a81 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Mon, 25 Feb 2019 13:54:26 +0100 Subject: [PATCH 1251/1650] Fix can not -> cannot Change-Id: Ie9992f67ca59aff662a4be046ace08640e7c2714 Reviewed-by: Paul Wicking --- src/3rdparty/angle/src/libANGLE/validationES.cpp | 2 +- src/corelib/Qt5CoreMacros.cmake | 2 +- src/corelib/global/qlogging.cpp | 2 +- src/corelib/io/qiodevice.cpp | 2 +- src/corelib/itemmodels/qabstractitemmodel.cpp | 4 ++-- src/corelib/itemmodels/qidentityproxymodel.cpp | 2 +- src/corelib/kernel/qcore_mac_objc.mm | 2 +- src/corelib/kernel/qeventdispatcher_unix.cpp | 2 +- src/corelib/kernel/qobject.cpp | 2 +- src/corelib/tools/qarraydata.cpp | 2 +- src/corelib/tools/qsharedpointer.cpp | 2 +- src/gui/kernel/qplatformgraphicsbuffer.cpp | 2 +- src/gui/kernel/qwindow.cpp | 4 ++-- src/gui/opengl/qopenglframebufferobject.cpp | 2 +- src/gui/text/qtextdocumentwriter.cpp | 4 ++-- src/gui/text/qtextodfwriter.cpp | 2 +- src/network/access/qnetworkreplyhttpimpl.cpp | 2 +- src/network/bearer/qnetworkconfiguration.cpp | 2 +- src/network/socket/qsocks5socketengine.cpp | 2 +- src/network/ssl/qsslsocket_schannel.cpp | 4 ++-- src/opengl/qglframebufferobject.cpp | 2 +- .../input/evdevkeyboard/qevdevkeyboardhandler.cpp | 2 +- src/plugins/platforms/cocoa/qcocoaglcontext.mm | 2 +- src/plugins/platforms/cocoa/qcocoawindow.mm | 2 +- src/plugins/platforms/cocoa/qnsview_drawing.mm | 2 +- src/testlib/qtestcase.cpp | 2 +- src/widgets/graphicsview/qgraphicsscene.cpp | 2 +- src/widgets/widgets/qabstractspinbox.cpp | 2 +- src/xml/dom/qdom.cpp | 2 +- util/local_database/xpathlite.py | 2 +- 30 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/3rdparty/angle/src/libANGLE/validationES.cpp b/src/3rdparty/angle/src/libANGLE/validationES.cpp index ae564b7412..069ca045f8 100644 --- a/src/3rdparty/angle/src/libANGLE/validationES.cpp +++ b/src/3rdparty/angle/src/libANGLE/validationES.cpp @@ -3525,7 +3525,7 @@ bool ValidateGetBufferPointervBase(Context *context, if (context->getGLState().getTargetBuffer(target) == nullptr) { context->handleError(InvalidOperation() - << "Can not get pointer for reserved buffer name zero."); + << "Cannot get pointer for reserved buffer name zero."); return false; } diff --git a/src/corelib/Qt5CoreMacros.cmake b/src/corelib/Qt5CoreMacros.cmake index 620795d2cf..a7b579165c 100644 --- a/src/corelib/Qt5CoreMacros.cmake +++ b/src/corelib/Qt5CoreMacros.cmake @@ -370,7 +370,7 @@ if (NOT CMAKE_VERSION VERSION_LESS 2.8.9) if (NOT Qt5${_module}_FOUND) find_package(Qt5${_module} PATHS "${_Qt5_COMPONENT_PATH}" NO_DEFAULT_PATH) if (NOT Qt5${_module}_FOUND) - message(FATAL_ERROR "Can not use \"${_module}\" module which has not yet been found.") + message(FATAL_ERROR "Cannot use \"${_module}\" module which has not yet been found.") endif() endif() target_link_libraries(${_target} ${_qt5_link_type} ${Qt5${_module}_LIBRARIES}) diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 168934c202..b2093101fa 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -239,7 +239,7 @@ static bool systemHasStderr() \note Qt Creator does not implement a pseudo TTY, nor does it launch apps with the override environment variable set, but it will read stderr and print it to - the user, so in effect this function can not be used to conclude that stderr + the user, so in effect this function cannot be used to conclude that stderr output will _not_ be visible to the user, as even if this function returns false, the output might still end up visible to the user. For this reason, we don't guard the stderr output in the default message handler with stderrHasConsoleAttached(). diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index 86e21f0a66..74df0f71ef 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -194,7 +194,7 @@ QIODevicePrivate::~QIODevicePrivate() QIODevice provides both a common implementation and an abstract interface for devices that support reading and writing of blocks of data, such as QFile, QBuffer and QTcpSocket. QIODevice is - abstract and can not be instantiated, but it is common to use the + abstract and cannot be instantiated, but it is common to use the interface it defines to provide device-independent I/O features. For example, Qt's XML classes operate on a QIODevice pointer, allowing them to be used with various devices (such as files and diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp index 75e13ff994..abd86f2b49 100644 --- a/src/corelib/itemmodels/qabstractitemmodel.cpp +++ b/src/corelib/itemmodels/qabstractitemmodel.cpp @@ -2329,7 +2329,7 @@ QModelIndex QAbstractItemModel::buddy(const QModelIndex &index) const The way the search is performed is defined by the \a flags given. The list that is returned may be empty. Note also that the order of results in the list may not correspond to the order in the model, if for example a proxy - model is used. The order of the results can not be relied upon. + model is used. The order of the results cannot be relied upon. The search begins from the \a start index, and continues until the number of matching data items equals \a hits, the search reaches the last row, or @@ -2903,7 +2903,7 @@ bool QAbstractItemModelPrivate::allowMove(const QModelIndex &srcParent, int star Note that other rows may be displaced accordingly. Note also that when moving items within the same parent you should not attempt invalid or no-op moves. In - the above example, item 2 is at row 2 before the move, so it can not be moved + the above example, item 2 is at row 2 before the move, so it cannot be moved to row 2 (where it is already) or row 3 (no-op as row 3 means above row 3, where it is already) diff --git a/src/corelib/itemmodels/qidentityproxymodel.cpp b/src/corelib/itemmodels/qidentityproxymodel.cpp index bb92857786..39992eccd3 100644 --- a/src/corelib/itemmodels/qidentityproxymodel.cpp +++ b/src/corelib/itemmodels/qidentityproxymodel.cpp @@ -95,7 +95,7 @@ class QIdentityProxyModelPrivate : public QAbstractProxyModelPrivate need to implement all data handling in the same class that creates the structure of the model, and can also be used to create re-usable components. - This also provides a way to change the data in the case where a source model is supplied by a third party which can not be modified. + This also provides a way to change the data in the case where a source model is supplied by a third party which cannot be modified. \snippet code/src_gui_itemviews_qidentityproxymodel.cpp 0 diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm index 4550891e2a..6687eb88a5 100644 --- a/src/corelib/kernel/qcore_mac_objc.mm +++ b/src/corelib/kernel/qcore_mac_objc.mm @@ -501,7 +501,7 @@ void qt_apple_check_os_version() if (!applicationName) applicationName = NSProcessInfo.processInfo.processName; - fprintf(stderr, "Sorry, \"%s\" can not be run on this version of %s. " + fprintf(stderr, "Sorry, \"%s\" cannot be run on this version of %s. " "Qt requires %s %ld.%ld.%ld or later, you have %s %ld.%ld.%ld.\n", applicationName.UTF8String, os, os, long(required.majorVersion), long(required.minorVersion), long(required.patchVersion), diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp index 535f86fefe..df0cac0239 100644 --- a/src/corelib/kernel/qeventdispatcher_unix.cpp +++ b/src/corelib/kernel/qeventdispatcher_unix.cpp @@ -225,7 +225,7 @@ int QThreadPipe::check(const pollfd &pfd) QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate() { if (Q_UNLIKELY(threadPipe.init() == false)) - qFatal("QEventDispatcherUNIXPrivate(): Can not continue without a thread pipe"); + qFatal("QEventDispatcherUNIXPrivate(): Cannot continue without a thread pipe"); } QEventDispatcherUNIXPrivate::~QEventDispatcherUNIXPrivate() diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 77f507ff3f..e67b2306c2 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -2152,7 +2152,7 @@ void QObject::removeEventFilter(QObject *obj) This signal is emitted immediately before the object \a obj is destroyed, after any instances of QPointer have been notified, - and can not be blocked. + and cannot be blocked. All the objects's children are destroyed immediately after this signal is emitted. diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp index a04536b18b..a91d833e3b 100644 --- a/src/corelib/tools/qarraydata.cpp +++ b/src/corelib/tools/qarraydata.cpp @@ -163,7 +163,7 @@ void QArrayData::deallocate(QArrayData *data, size_t objectSize, #endif Q_ASSERT_X(data == 0 || !data->ref.isStatic(), "QArrayData::deallocate", - "Static data can not be deleted"); + "Static data cannot be deleted"); ::free(data); } diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index ce0a1ad9cb..8bc0dc8a74 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -379,7 +379,7 @@ You can inherit this class when you need to create a QSharedPointer from any instance of a class; for instance, from within the object itself. The key point is that the technique of - just returning QSharedPointer(this) can not be used, because + just returning QSharedPointer(this) cannot be used, because this winds up creating multiple distinct QSharedPointer objects with separate reference counts. For this reason you must never create more than one QSharedPointer from the same raw pointer. diff --git a/src/gui/kernel/qplatformgraphicsbuffer.cpp b/src/gui/kernel/qplatformgraphicsbuffer.cpp index d361a8fc12..73ec033e19 100644 --- a/src/gui/kernel/qplatformgraphicsbuffer.cpp +++ b/src/gui/kernel/qplatformgraphicsbuffer.cpp @@ -184,7 +184,7 @@ void QPlatformGraphicsBuffer::unlock() \fn QPlatformGraphicsBuffer::doLock(AccessTypes access, const QRect &rect = QRect()) This function should be reimplemented by subclasses. If one of the \a - access types specified can not be locked, then all should fail and this + access types specified cannot be locked, then all should fail and this function should return false. \a rect is the subrect which is desired to be locked. This diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 0b833cfbc7..3040a20308 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -166,7 +166,7 @@ QWindow::QWindow(QScreen *targetScreen) static QWindow *nonDesktopParent(QWindow *parent) { if (parent && parent->type() == Qt::Desktop) { - qWarning("QWindows can not be reparented into desktop windows"); + qWarning("QWindows cannot be reparented into desktop windows"); return nullptr; } @@ -1351,7 +1351,7 @@ void QWindow::setTransientParent(QWindow *parent) return; } if (parent == this) { - qWarning() << "transient parent" << parent << "can not be same as window"; + qWarning() << "transient parent" << parent << "cannot be same as window"; return; } diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp index cae3d516c4..e7631b09ce 100644 --- a/src/gui/opengl/qopenglframebufferobject.cpp +++ b/src/gui/opengl/qopenglframebufferobject.cpp @@ -249,7 +249,7 @@ QOpenGLFramebufferObjectFormat::~QOpenGLFramebufferObjectFormat() If the desired amount of samples per pixel is not supported by the hardware then the maximum number of samples per pixel will be used. Note that - multisample framebuffer objects can not be bound as textures. Also, the + multisample framebuffer objects cannot be bound as textures. Also, the \c{GL_EXT_framebuffer_multisample} extension is required to create a framebuffer with more than one sample per pixel. diff --git a/src/gui/text/qtextdocumentwriter.cpp b/src/gui/text/qtextdocumentwriter.cpp index ee72300bc7..42e623153a 100644 --- a/src/gui/text/qtextdocumentwriter.cpp +++ b/src/gui/text/qtextdocumentwriter.cpp @@ -270,7 +270,7 @@ bool QTextDocumentWriter::write(const QTextDocument *document) #ifndef QT_NO_TEXTHTMLPARSER if (format == "html" || format == "htm") { if (!d->device->isWritable() && ! d->device->open(QIODevice::WriteOnly)) { - qWarning("QTextDocumentWriter::write: the device can not be opened for writing"); + qWarning("QTextDocumentWriter::write: the device cannot be opened for writing"); return false; } QTextStream ts(d->device); @@ -284,7 +284,7 @@ bool QTextDocumentWriter::write(const QTextDocument *document) #endif if (format == "txt" || format == "plaintext") { if (!d->device->isWritable() && ! d->device->open(QIODevice::WriteOnly)) { - qWarning("QTextDocumentWriter::write: the device can not be opened for writing"); + qWarning("QTextDocumentWriter::write: the device cannot be opened for writing"); return false; } QTextStream ts(d->device); diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp index c8fa5306c3..a62e7e425a 100644 --- a/src/gui/text/qtextodfwriter.cpp +++ b/src/gui/text/qtextodfwriter.cpp @@ -963,7 +963,7 @@ bool QTextOdfWriter::writeAll() m_strategy = new QXmlStreamStrategy(m_device); if (!m_device->isWritable() && ! m_device->open(QIODevice::WriteOnly)) { - qWarning("QTextOdfWriter::writeAll: the device can not be opened for writing"); + qWarning("QTextOdfWriter::writeAll: the device cannot be opened for writing"); return false; } QXmlStreamWriter writer(m_strategy->contentStream); diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index b55ae0ab71..9ae94afc5a 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -1562,7 +1562,7 @@ bool QNetworkReplyHttpImplPrivate::sendCacheContents(const QNetworkCacheMetaData QIODevice *contents = nc->data(url); if (!contents) { #if defined(QNETWORKACCESSHTTPBACKEND_DEBUG) - qDebug() << "Can not send cache, the contents are 0" << url; + qDebug() << "Cannot send cache, the contents are 0" << url; #endif return false; } diff --git a/src/network/bearer/qnetworkconfiguration.cpp b/src/network/bearer/qnetworkconfiguration.cpp index e36903fc94..f5ced0693a 100644 --- a/src/network/bearer/qnetworkconfiguration.cpp +++ b/src/network/bearer/qnetworkconfiguration.cpp @@ -518,7 +518,7 @@ QNetworkConfiguration::BearerType QNetworkConfiguration::bearerTypeFamily() cons /*! Returns the type of bearer used by this network configuration as a string. - The string is not translated and therefore can not be shown to the user. The subsequent table + The string is not translated and therefore cannot be shown to the user. The subsequent table shows the fixed mappings between BearerType and the bearer type name for known types. If the BearerType is unknown this function may return additional information if it is available; otherwise an empty string will be returned. diff --git a/src/network/socket/qsocks5socketengine.cpp b/src/network/socket/qsocks5socketengine.cpp index 3e4c35fcc5..23aec12390 100644 --- a/src/network/socket/qsocks5socketengine.cpp +++ b/src/network/socket/qsocks5socketengine.cpp @@ -372,7 +372,7 @@ QSocks5BindData *QSocks5BindStore::retrieve(qintptr socketDescriptor) store.erase(it); if (bindData) { if (bindData->controlSocket->thread() != QThread::currentThread()) { - qWarning("Can not access socks5 bind data from different thread"); + qWarning("Cannot access socks5 bind data from different thread"); return 0; } } else { diff --git a/src/network/ssl/qsslsocket_schannel.cpp b/src/network/ssl/qsslsocket_schannel.cpp index e75f81bd36..1314b432a4 100644 --- a/src/network/ssl/qsslsocket_schannel.cpp +++ b/src/network/ssl/qsslsocket_schannel.cpp @@ -615,8 +615,8 @@ bool QSslSocketBackendPrivate::acquireCredentialsHandle() nullptr); if (!chainContext) { const QString message = isClient - ? QSslSocket::tr("The certificate provided can not be used for a client.") - : QSslSocket::tr("The certificate provided can not be used for a server."); + ? QSslSocket::tr("The certificate provided cannot be used for a client.") + : QSslSocket::tr("The certificate provided cannot be used for a server."); setErrorAndEmit(QAbstractSocket::SocketError::SslInvalidUserDataError, message); return false; } diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index 0b2ddf97fe..b2158ebfaa 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -211,7 +211,7 @@ QGLFramebufferObjectFormat::~QGLFramebufferObjectFormat() If the desired amount of samples per pixel is not supported by the hardware then the maximum number of samples per pixel will be used. Note that - multisample framebuffer objects can not be bound as textures. Also, the + multisample framebuffer objects cannot be bound as textures. Also, the \c{GL_EXT_framebuffer_multisample} extension is required to create a framebuffer with more than one sample per pixel. diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp index ad134a825f..666613f09d 100644 --- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp +++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp @@ -557,7 +557,7 @@ bool QEvdevKeyboardHandler::loadKeymap(const QString &file) delete [] qmap_keymap; delete [] qmap_keycompose; - qWarning("Keymap file '%s' can not be loaded.", qPrintable(file)); + qWarning("Keymap file '%s' cannot be loaded.", qPrintable(file)); return false; } diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index 93d95b38ea..fe1fc31553 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -86,7 +86,7 @@ QCocoaGLContext::QCocoaGLContext(QOpenGLContext *context) } m_context = nativeHandle.value().context(); if (!m_context) { - qCWarning(lcQpaOpenGLContext, "QCocoaNativeContext's NSOpenGLContext can not be null"); + qCWarning(lcQpaOpenGLContext, "QCocoaNativeContext's NSOpenGLContext cannot be null"); return; } diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index ff2c4de985..298d11fe08 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -619,7 +619,7 @@ void QCocoaWindow::applyWindowState(Qt::WindowStates requestedState) if (nsWindow.styleMask & NSWindowStyleMaskUtilityWindow && newState & (Qt::WindowMinimized | Qt::WindowFullScreen)) { - qWarning() << window()->type() << "windows can not be made" << newState; + qWarning() << window()->type() << "windows cannot be made" << newState; handleWindowStateChanged(HandleUnconditionally); return; } diff --git a/src/plugins/platforms/cocoa/qnsview_drawing.mm b/src/plugins/platforms/cocoa/qnsview_drawing.mm index e9af90a45c..6db5ed8bad 100644 --- a/src/plugins/platforms/cocoa/qnsview_drawing.mm +++ b/src/plugins/platforms/cocoa/qnsview_drawing.mm @@ -106,7 +106,7 @@ "_q_mac_wantsLayer", "QT_MAC_WANTS_LAYER"); if (wantsLayer != -1 && [self layerEnabledByMacOS]) { - qCWarning(lcQpaDrawing) << "Layer-backing can not be explicitly controlled on 10.14 when built against the 10.14 SDK"; + qCWarning(lcQpaDrawing) << "Layer-backing cannot be explicitly controlled on 10.14 when built against the 10.14 SDK"; return true; } diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 840b4071e2..3ee8094ddf 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -2311,7 +2311,7 @@ void QTest::addColumnInternal(int id, const char *name) */ QTestData &QTest::newRow(const char *dataTag) { - QTEST_ASSERT_X(dataTag, "QTest::newRow()", "Data tag can not be null"); + QTEST_ASSERT_X(dataTag, "QTest::newRow()", "Data tag cannot be null"); QTestTable *tbl = QTestTable::currentTestTable(); QTEST_ASSERT_X(tbl, "QTest::newRow()", "Cannot add testdata outside of a _data slot."); QTEST_ASSERT_X(tbl->elementCount(), "QTest::newRow()", "Must add columns before attempting to add rows."); diff --git a/src/widgets/graphicsview/qgraphicsscene.cpp b/src/widgets/graphicsview/qgraphicsscene.cpp index a60c2872ae..c517198a23 100644 --- a/src/widgets/graphicsview/qgraphicsscene.cpp +++ b/src/widgets/graphicsview/qgraphicsscene.cpp @@ -1923,7 +1923,7 @@ void QGraphicsScene::setBspTreeDepth(int depth) QGraphicsSceneBspTreeIndex *bspTree = qobject_cast(d->index); if (!bspTree) { - qWarning("QGraphicsScene::setBspTreeDepth: can not apply if indexing method is not BSP"); + qWarning("QGraphicsScene::setBspTreeDepth: cannot apply if indexing method is not BSP"); return; } bspTree->setBspTreeDepth(depth); diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp index 00ac5034e9..6a35dbe274 100644 --- a/src/widgets/widgets/qabstractspinbox.cpp +++ b/src/widgets/widgets/qabstractspinbox.cpp @@ -688,7 +688,7 @@ QLineEdit *QAbstractSpinBox::lineEdit() const \fn void QAbstractSpinBox::setLineEdit(QLineEdit *lineEdit) Sets the line edit of the spinbox to be \a lineEdit instead of the - current line edit widget. \a lineEdit can not be 0. + current line edit widget. \a lineEdit cannot be 0. QAbstractSpinBox takes ownership of the new lineEdit diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp index a1f4d57da6..cffc1974af 100644 --- a/src/xml/dom/qdom.cpp +++ b/src/xml/dom/qdom.cpp @@ -5183,7 +5183,7 @@ QDomNodePrivate* QDomTextPrivate::cloneNode(bool deep) QDomTextPrivate* QDomTextPrivate::splitText(int offset) { if (!parent()) { - qWarning("QDomText::splitText The node has no parent. So I can not split"); + qWarning("QDomText::splitText The node has no parent. So I cannot split"); return 0; } diff --git a/util/local_database/xpathlite.py b/util/local_database/xpathlite.py index b3f8325569..218135d7a7 100644 --- a/util/local_database/xpathlite.py +++ b/util/local_database/xpathlite.py @@ -257,7 +257,7 @@ def findEntry(base, path, draft=None, attribute=None): if result: return result if not aliaspath: - raise Error("findEntry: fatal error: %s: can not find key %s" % (filename, path)) + raise Error("findEntry: fatal error: %s: cannot find key %s" % (filename, path)) path = aliaspath return result From 00cfb4d7801ec9b5d9b070879ef4a962390628b7 Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Mon, 18 Feb 2019 16:16:23 +0100 Subject: [PATCH 1252/1650] Windows QPA: Generate proper event when dragging item outside window When an item was dragged outside the window, the mouse release event was not being properly delivered and the item would stick to mouse cursor after moving it back into the window. Fixes: QTBUG-72994 Change-Id: Ibce990390c866e16d58f7d969673dd05e862d97e Reviewed-by: Oliver Wolff Reviewed-by: Friedemann Kleint --- .../platforms/windows/qwindowsdrag.cpp | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp index 95d1fc8b7d..322865b0f3 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.cpp +++ b/src/plugins/platforms/windows/qwindowsdrag.cpp @@ -49,6 +49,7 @@ #include "qwindowswindow.h" #include "qwindowsmousehandler.h" #include "qwindowscursor.h" +#include "qwindowskeymapper.h" #include #include @@ -205,6 +206,9 @@ static inline Qt::MouseButtons toQtMouseButtons(DWORD keyState) return buttons; } +static Qt::KeyboardModifiers lastModifiers = Qt::NoModifier; +static Qt::MouseButtons lastButtons = Qt::NoButton; + /*! \class QWindowsOleDropSource \brief Implementation of IDropSource @@ -403,7 +407,7 @@ QWindowsOleDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState) case DRAGDROP_S_DROP: case DRAGDROP_S_CANCEL: if (!m_windowUnderMouse.isNull() && m_mode != TouchDrag && fEscapePressed == FALSE - && buttons != QGuiApplicationPrivate::mouse_buttons) { + && buttons != lastButtons) { // QTBUG 66447: Synthesize a mouse release to the window under mouse at // start of the DnD operation as Windows does not send any. const QPoint globalPos = QWindowsCursor::mousePosition(); @@ -503,13 +507,14 @@ void QWindowsOleDropTarget::handleDrag(QWindow *window, DWORD grfKeyState, QWindowsDrag *windowsDrag = QWindowsDrag::instance(); const Qt::DropActions actions = translateToQDragDropActions(*pdwEffect); - const Qt::KeyboardModifiers keyboardModifiers = toQtKeyboardModifiers(grfKeyState); - const Qt::MouseButtons mouseButtons = toQtMouseButtons(grfKeyState); + + lastModifiers = toQtKeyboardModifiers(grfKeyState); + lastButtons = toQtMouseButtons(grfKeyState); const QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(window, windowsDrag->dropData(), m_lastPoint, actions, - mouseButtons, keyboardModifiers); + lastButtons, lastModifiers); m_answerRect = response.answerRect(); const Qt::DropAction action = response.acceptedAction(); @@ -521,7 +526,7 @@ void QWindowsOleDropTarget::handleDrag(QWindow *window, DWORD grfKeyState, *pdwEffect = m_chosenEffect; qCDebug(lcQpaMime) << __FUNCTION__ << m_window << windowsDrag->dropData() << " supported actions=" << actions - << " mods=" << keyboardModifiers << " mouse=" << mouseButtons + << " mods=" << lastModifiers << " mouse=" << lastButtons << " accepted: " << response.isAccepted() << action << m_answerRect << " effect" << *pdwEffect; } @@ -572,6 +577,9 @@ QWindowsOleDropTarget::DragLeave() qCDebug(lcQpaMime) << __FUNCTION__ << ' ' << m_window; + lastModifiers = QWindowsKeyMapper::queryKeyboardModifiers(); + lastButtons = QWindowsMouseHandler::queryMouseButtons(); + QWindowSystemInterface::handleDrag(m_window, nullptr, QPoint(), Qt::IgnoreAction, Qt::NoButton, Qt::NoModifier); @@ -598,12 +606,15 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState, QWindowsDrag *windowsDrag = QWindowsDrag::instance(); + lastModifiers = toQtKeyboardModifiers(grfKeyState); + lastButtons = toQtMouseButtons(grfKeyState); + const QPlatformDropQtResponse response = QWindowSystemInterface::handleDrop(m_window, windowsDrag->dropData(), m_lastPoint, translateToQDragDropActions(*pdwEffect), - toQtMouseButtons(grfKeyState), - toQtKeyboardModifiers(grfKeyState)); + lastButtons, + lastModifiers); m_lastKeyState = grfKeyState; From 93b7b0ec76572427291d8e2eef9a10eb499417a9 Mon Sep 17 00:00:00 2001 From: Sandro Mani Date: Thu, 12 Jul 2018 10:27:36 +0200 Subject: [PATCH 1253/1650] Add support for SPNEGO/Negotiate authentication MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds support for single-sign-on SPNEGO/Negotiate authentication to QAuthenticator, using SSPI on Windows and GSSAPI on other platforms (if KRB5 GSSAPI is available). [ChangeLog][QtNetwork][QAuthenticator] Add support for SPNEGO/Negotiate Task-number: QTBUG-4117 Change-Id: Ie246b887db3fd6201b7ed30b023feca292cd6530 Reviewed-by: Mårten Nordheim --- src/network/access/qhttpnetworkconnection.cpp | 13 +- src/network/access/qhttpnetworkreply.cpp | 3 + src/network/configure.json | 26 +- src/network/kernel/kernel.pri | 2 + src/network/kernel/qauthenticator.cpp | 416 ++++++++++++------ src/network/kernel/qauthenticator_p.h | 17 +- src/network/socket/qhttpsocketengine.cpp | 2 +- .../qauthenticator/tst_qauthenticator.cpp | 8 +- 8 files changed, 327 insertions(+), 160 deletions(-) diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 681d84fee8..ee1e3cfb8f 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -398,11 +398,12 @@ void QHttpNetworkConnectionPrivate::copyCredentials(int fromChannel, QAuthentica { Q_ASSERT(auth); - // NTLM is a multi phase authentication. Copying credentials between authenticators would mess things up. + // NTLM and Negotiate do multi-phase authentication. + // Copying credentialsbetween authenticators would mess things up. if (fromChannel >= 0) { - if (!isProxy && channels[fromChannel].authMethod == QAuthenticatorPrivate::Ntlm) - return; - if (isProxy && channels[fromChannel].proxyAuthMethod == QAuthenticatorPrivate::Ntlm) + const QHttpNetworkConnectionChannel &channel = channels[fromChannel]; + const QAuthenticatorPrivate::Method method = isProxy ? channel.proxyAuthMethod : channel.authMethod; + if (method == QAuthenticatorPrivate::Ntlm || method == QAuthenticatorPrivate::Negotiate) return; } @@ -592,7 +593,7 @@ void QHttpNetworkConnectionPrivate::createAuthorization(QAbstractSocket *socket, if ((channels[i].authMethod != QAuthenticatorPrivate::Ntlm && request.headerField("Authorization").isEmpty()) || channels[i].lastStatus == 401) { QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(channels[i].authenticator); if (priv && priv->method != QAuthenticatorPrivate::None) { - QByteArray response = priv->calculateResponse(request.methodName(), request.uri(false)); + QByteArray response = priv->calculateResponse(request.methodName(), request.uri(false), request.url().host()); request.setHeaderField("Authorization", response); channels[i].authenticationCredentialsSent = true; } @@ -604,7 +605,7 @@ void QHttpNetworkConnectionPrivate::createAuthorization(QAbstractSocket *socket, if (!(channels[i].proxyAuthMethod == QAuthenticatorPrivate::Ntlm && channels[i].lastStatus != 407)) { QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(channels[i].proxyAuthenticator); if (priv && priv->method != QAuthenticatorPrivate::None) { - QByteArray response = priv->calculateResponse(request.methodName(), request.uri(false)); + QByteArray response = priv->calculateResponse(request.methodName(), request.uri(false), networkProxy.hostName()); request.setHeaderField("Proxy-Authorization", response); channels[i].proxyCredentialsSent = true; } diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index c9c3172304..a8b635c45a 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -444,6 +444,9 @@ QAuthenticatorPrivate::Method QHttpNetworkReplyPrivate::authenticationMethod(boo } else if (method < QAuthenticatorPrivate::DigestMd5 && line.startsWith("digest")) { method = QAuthenticatorPrivate::DigestMd5; + } else if (method < QAuthenticatorPrivate::Negotiate + && line.startsWith("negotiate")) { + method = QAuthenticatorPrivate::Negotiate; } } return method; diff --git a/src/network/configure.json b/src/network/configure.json index e6c87b550b..aaedc05ea4 100644 --- a/src/network/configure.json +++ b/src/network/configure.json @@ -199,6 +199,15 @@ ] }, "use": "openssl" + }, + "gssapi": { + "label": "KRB5 GSSAPI support", + "type": "compile", + "test": { + "include": [ "gssapi/gssapi.h" ], + "main": ["gss_ctx_id_t ctx;"], + "qmake": "LIBS += -lgssapi_krb5" + } } }, @@ -374,6 +383,20 @@ "purpose": "Provides API for DNS lookups.", "section": "Networking", "output": [ "publicFeature" ] + }, + "gssapi": { + "label": "GSSAPI", + "purpose": "Enable SPNEGO authentication through GSSAPI", + "section": "Networking", + "condition": "!config.win32 && tests.gssapi", + "output": [ "publicFeature", "feature" ] + }, + "sspi": { + "label": "SSPI", + "purpose": "Enable NTLM/SPNEGO authentication through SSPI", + "section": "Networking", + "condition": "config.win32 && !config.winrt", + "output": [ "publicFeature", "feature" ] } }, @@ -433,7 +456,8 @@ For example: "dtls", "ocsp", "sctp", - "system-proxies" + "system-proxies", + "gssapi" ] } ] diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri index 11b80d59d5..f7269e5070 100644 --- a/src/network/kernel/kernel.pri +++ b/src/network/kernel/kernel.pri @@ -68,6 +68,8 @@ mac { !uikit: LIBS_PRIVATE += -framework CoreServices -framework SystemConfiguration } +qtConfig(gssapi): LIBS_PRIVATE += -lgssapi_krb5 + uikit:HEADERS += kernel/qnetworkinterface_uikit_p.h osx:SOURCES += kernel/qnetworkproxy_mac.cpp else:win32:!winrt: SOURCES += kernel/qnetworkproxy_win.cpp diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp index 47ce9ab0c6..3ca8806c2b 100644 --- a/src/network/kernel/qauthenticator.cpp +++ b/src/network/kernel/qauthenticator.cpp @@ -54,20 +54,29 @@ #include #include #include -#ifndef Q_OS_WINRT +#endif + +#if QT_CONFIG(sspi) // SSPI #define SECURITY_WIN32 1 #include -#endif +#elif QT_CONFIG(gssapi) // GSSAPI +#include #endif QT_BEGIN_NAMESPACE static QByteArray qNtlmPhase1(); static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phase2data); -#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) -static QByteArray qNtlmPhase1_SSPI(QAuthenticatorPrivate *ctx); -static QByteArray qNtlmPhase3_SSPI(QAuthenticatorPrivate *ctx, const QByteArray& phase2data); -#endif +#if QT_CONFIG(sspi) // SSPI +static QByteArray qSspiStartup(QAuthenticatorPrivate *ctx, QAuthenticatorPrivate::Method method, + const QString& host); +static QByteArray qSspiContinue(QAuthenticatorPrivate *ctx, QAuthenticatorPrivate::Method method, + const QString& host, const QByteArray& challenge = QByteArray()); +#elif QT_CONFIG(gssapi) // GSSAPI +static QByteArray qGssapiStartup(QAuthenticatorPrivate *ctx, const QString& host); +static QByteArray qGssapiContinue(QAuthenticatorPrivate *ctx, + const QByteArray& challenge = QByteArray()); +#endif // gssapi /*! \class QAuthenticator @@ -90,6 +99,7 @@ static QByteArray qNtlmPhase3_SSPI(QAuthenticatorPrivate *ctx, const QByteArray& \li Basic \li NTLM version 2 \li Digest-MD5 + \li SPNEGO/Negotiate \endlist \target qauthenticator-options @@ -133,6 +143,10 @@ static QByteArray qNtlmPhase3_SSPI(QAuthenticatorPrivate *ctx, const QByteArray& The Digest-MD5 authentication mechanism supports no outgoing options. + \section2 SPNEGO/Negotiate + + This authentication mechanism currently supports no incoming or outgoing options. + \sa QSslSocket */ @@ -187,7 +201,7 @@ QAuthenticator &QAuthenticator::operator=(const QAuthenticator &other) d->options = other.d->options; } else if (d->phase == QAuthenticatorPrivate::Start) { delete d; - d = 0; + d = nullptr; } return *this; } @@ -339,21 +353,25 @@ bool QAuthenticator::isNull() const return !d; } -#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) -class QNtlmWindowsHandles +#if QT_CONFIG(sspi) // SSPI +class QSSPIWindowsHandles { public: CredHandle credHandle; CtxtHandle ctxHandle; }; -#endif +#elif QT_CONFIG(gssapi) // GSSAPI +class QGssApiHandles +{ +public: + gss_ctx_id_t gssCtx = nullptr; + gss_name_t targetName; +}; +#endif // gssapi QAuthenticatorPrivate::QAuthenticatorPrivate() : method(None) - #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) - , ntlmWindowsHandles(0) - #endif , hasFailed(false) , phase(Start) , nonceCount(0) @@ -363,13 +381,7 @@ QAuthenticatorPrivate::QAuthenticatorPrivate() nonceCount = 0; } -QAuthenticatorPrivate::~QAuthenticatorPrivate() -{ -#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) - if (ntlmWindowsHandles) - delete ntlmWindowsHandles; -#endif -} +QAuthenticatorPrivate::~QAuthenticatorPrivate() = default; void QAuthenticatorPrivate::updateCredentials() { @@ -424,6 +436,9 @@ void QAuthenticatorPrivate::parseHttpResponse(const QList( reinterpret_cast(GetProcAddress(securityDLLHandle, "InitSecurityInterfaceW"))); - if (pInitSecurityInterface != NULL) + if (pInitSecurityInterface != nullptr) pSecurityFunctionTable = pInitSecurityInterface(); } } - if (pSecurityFunctionTable == NULL) + if (pSecurityFunctionTable == nullptr) return false; return true; } -// Phase 1: -static QByteArray qNtlmPhase1_SSPI(QAuthenticatorPrivate *ctx) +static QByteArray qSspiStartup(QAuthenticatorPrivate *ctx, QAuthenticatorPrivate::Method method, + const QString& host) { - QByteArray result; + if (!q_SSPI_library_load()) + return QByteArray(); - if (!q_NTLM_SSPI_library_load()) - return result; + TimeStamp expiry; // For Windows 9x compatibility of SSPI calls - // 1. The client obtains a representation of the credential set - // for the user via the SSPI AcquireCredentialsHandle function. - if (!ctx->ntlmWindowsHandles) - ctx->ntlmWindowsHandles = new QNtlmWindowsHandles; - memset(&ctx->ntlmWindowsHandles->credHandle, 0, sizeof(CredHandle)); - TimeStamp tsDummy; + if (!ctx->sspiWindowsHandles) + ctx->sspiWindowsHandles.reset(new QSSPIWindowsHandles); + memset(&ctx->sspiWindowsHandles->credHandle, 0, sizeof(CredHandle)); + + // Acquire our credentials handle SECURITY_STATUS secStatus = pSecurityFunctionTable->AcquireCredentialsHandle( - NULL, (SEC_WCHAR*)L"NTLM", SECPKG_CRED_OUTBOUND, NULL, NULL, - NULL, NULL, &ctx->ntlmWindowsHandles->credHandle, &tsDummy); + nullptr, + (SEC_WCHAR*)(method == QAuthenticatorPrivate::Negotiate ? L"Negotiate" : L"NTLM"), + SECPKG_CRED_OUTBOUND, nullptr, nullptr, nullptr, nullptr, + &ctx->sspiWindowsHandles->credHandle, &expiry + ); if (secStatus != SEC_E_OK) { - delete ctx->ntlmWindowsHandles; - ctx->ntlmWindowsHandles = 0; - return result; + ctx->sspiWindowsHandles.reset(nullptr); + return QByteArray(); } - // 2. The client calls the SSPI InitializeSecurityContext function - // to obtain an authentication request token (in our case, a Type 1 message). - // The client sends this token to the server. - SecBufferDesc desc; - SecBuffer buf; - desc.ulVersion = SECBUFFER_VERSION; - desc.cBuffers = 1; - desc.pBuffers = &buf; - buf.cbBuffer = 0; - buf.BufferType = SECBUFFER_TOKEN; - buf.pvBuffer = NULL; - ULONG attrs; - - secStatus = pSecurityFunctionTable->InitializeSecurityContext(&ctx->ntlmWindowsHandles->credHandle, NULL, - const_cast(L"") /* host */, - ISC_REQ_ALLOCATE_MEMORY, - 0, SECURITY_NETWORK_DREP, - NULL, 0, - &ctx->ntlmWindowsHandles->ctxHandle, &desc, - &attrs, &tsDummy); - if (secStatus == SEC_I_COMPLETE_AND_CONTINUE || - secStatus == SEC_I_CONTINUE_NEEDED) { - pSecurityFunctionTable->CompleteAuthToken(&ctx->ntlmWindowsHandles->ctxHandle, &desc); - } else if (secStatus != SEC_E_OK) { - if ((const char*)buf.pvBuffer) - pSecurityFunctionTable->FreeContextBuffer(buf.pvBuffer); - pSecurityFunctionTable->FreeCredentialsHandle(&ctx->ntlmWindowsHandles->credHandle); - delete ctx->ntlmWindowsHandles; - ctx->ntlmWindowsHandles = 0; - return result; - } - - result = QByteArray((const char*)buf.pvBuffer, buf.cbBuffer); - pSecurityFunctionTable->FreeContextBuffer(buf.pvBuffer); - return result; + return qSspiContinue(ctx, method, host); } -// Phase 2: -// 3. The server receives the token from the client, and uses it as input to the -// AcceptSecurityContext SSPI function. This creates a local security context on -// the server to represent the client, and yields an authentication response token -// (the Type 2 message), which is sent to the client. - -// Phase 3: -static QByteArray qNtlmPhase3_SSPI(QAuthenticatorPrivate *ctx, const QByteArray& phase2data) +static QByteArray qSspiContinue(QAuthenticatorPrivate *ctx, QAuthenticatorPrivate::Method method, + const QString &host, const QByteArray &challenge) { - // 4. The client receives the response token from the server and calls - // InitializeSecurityContext again, passing the server's token as input. - // This provides us with another authentication request token (the Type 3 message). - // The return value indicates that the security context was successfully initialized; - // the token is sent to the server. - QByteArray result; + SecBuffer challengeBuf; + SecBuffer responseBuf; + SecBufferDesc challengeDesc; + SecBufferDesc responseDesc; + unsigned long attrs; + TimeStamp expiry; // For Windows 9x compatibility of SSPI calls - if (pSecurityFunctionTable == NULL) - return result; - - SecBuffer type_2, type_3; - SecBufferDesc type_2_desc, type_3_desc; - ULONG attrs; - TimeStamp tsDummy; // For Windows 9x compatibility of SPPI calls - - type_2_desc.ulVersion = type_3_desc.ulVersion = SECBUFFER_VERSION; - type_2_desc.cBuffers = type_3_desc.cBuffers = 1; - type_2_desc.pBuffers = &type_2; - type_3_desc.pBuffers = &type_3; - - type_2.BufferType = SECBUFFER_TOKEN; - type_2.pvBuffer = (PVOID)phase2data.data(); - type_2.cbBuffer = phase2data.length(); - type_3.BufferType = SECBUFFER_TOKEN; - type_3.pvBuffer = 0; - type_3.cbBuffer = 0; - - SECURITY_STATUS secStatus = pSecurityFunctionTable->InitializeSecurityContext(&ctx->ntlmWindowsHandles->credHandle, - &ctx->ntlmWindowsHandles->ctxHandle, - const_cast(L"") /* host */, - ISC_REQ_ALLOCATE_MEMORY, - 0, SECURITY_NETWORK_DREP, &type_2_desc, - 0, &ctx->ntlmWindowsHandles->ctxHandle, &type_3_desc, - &attrs, &tsDummy); - - if (secStatus == SEC_E_OK && ((const char*)type_3.pvBuffer)) { - result = QByteArray((const char*)type_3.pvBuffer, type_3.cbBuffer); - pSecurityFunctionTable->FreeContextBuffer(type_3.pvBuffer); + if (!challenge.isEmpty()) + { + // Setup the challenge "input" security buffer + challengeDesc.ulVersion = SECBUFFER_VERSION; + challengeDesc.cBuffers = 1; + challengeDesc.pBuffers = &challengeBuf; + challengeBuf.BufferType = SECBUFFER_TOKEN; + challengeBuf.pvBuffer = (PVOID)(challenge.data()); + challengeBuf.cbBuffer = challenge.length(); } - pSecurityFunctionTable->FreeCredentialsHandle(&ctx->ntlmWindowsHandles->credHandle); - pSecurityFunctionTable->DeleteSecurityContext(&ctx->ntlmWindowsHandles->ctxHandle); - delete ctx->ntlmWindowsHandles; - ctx->ntlmWindowsHandles = 0; + // Setup the response "output" security buffer + responseDesc.ulVersion = SECBUFFER_VERSION; + responseDesc.cBuffers = 1; + responseDesc.pBuffers = &responseBuf; + responseBuf.BufferType = SECBUFFER_TOKEN; + responseBuf.pvBuffer = nullptr; + responseBuf.cbBuffer = 0; + + // Calculate target (SPN for Negotiate, empty for NTLM) + std::wstring targetNameW = (method == QAuthenticatorPrivate::Negotiate + ? QLatin1String("HTTP/") + host : QString()).toStdWString(); + + // Generate our challenge-response message + SECURITY_STATUS secStatus = pSecurityFunctionTable->InitializeSecurityContext( + &ctx->sspiWindowsHandles->credHandle, + !challenge.isEmpty() ? &ctx->sspiWindowsHandles->ctxHandle : nullptr, + const_cast(targetNameW.data()), + ISC_REQ_ALLOCATE_MEMORY, + 0, SECURITY_NATIVE_DREP, + !challenge.isEmpty() ? &challengeDesc : nullptr, + 0, &ctx->sspiWindowsHandles->ctxHandle, + &responseDesc, &attrs, + &expiry + ); + + if (secStatus == SEC_I_COMPLETE_NEEDED || secStatus == SEC_I_COMPLETE_AND_CONTINUE) { + secStatus = pSecurityFunctionTable->CompleteAuthToken(&ctx->sspiWindowsHandles->ctxHandle, + &responseDesc); + } + + if (secStatus != SEC_I_COMPLETE_AND_CONTINUE && secStatus != SEC_I_CONTINUE_NEEDED) { + pSecurityFunctionTable->FreeCredentialsHandle(&ctx->sspiWindowsHandles->credHandle); + pSecurityFunctionTable->DeleteSecurityContext(&ctx->sspiWindowsHandles->ctxHandle); + ctx->sspiWindowsHandles.reset(nullptr); + } + + result = QByteArray((const char*)responseBuf.pvBuffer, responseBuf.cbBuffer); + pSecurityFunctionTable->FreeContextBuffer(responseBuf.pvBuffer); return result; } -#endif // Q_OS_WIN && !Q_OS_WINRT + +// ---------------------------- End of SSPI code --------------------------------------- + +#elif QT_CONFIG(gssapi) // GSSAPI + +// ---------------------------- GSSAPI code ---------------------------------------------- +// See postgres src/interfaces/libpq/fe-auth.c + +// Fetch all errors of a specific type +static void q_GSSAPI_error_int(const char *message, OM_uint32 stat, int type) +{ + OM_uint32 minStat, msgCtx = 0; + gss_buffer_desc msg; + + do { + gss_display_status(&minStat, stat, type, GSS_C_NO_OID, &msgCtx, &msg); + qDebug() << message << ": " << reinterpret_cast(msg.value); + gss_release_buffer(&minStat, &msg); + } while (msgCtx); +} + +// GSSAPI errors contain two parts; extract both +static void q_GSSAPI_error(const char *message, OM_uint32 majStat, OM_uint32 minStat) +{ + // Fetch major error codes + q_GSSAPI_error_int(message, majStat, GSS_C_GSS_CODE); + + // Add the minor codes as well + q_GSSAPI_error_int(message, minStat, GSS_C_MECH_CODE); +} + +// Send initial GSS authentication token +static QByteArray qGssapiStartup(QAuthenticatorPrivate *ctx, const QString &host) +{ + OM_uint32 majStat, minStat; + + if (!ctx->gssApiHandles) + ctx->gssApiHandles.reset(new QGssApiHandles); + + // Convert target name to internal form + QByteArray serviceName = QStringLiteral("HTTPS@%1").arg(host).toLocal8Bit(); + gss_buffer_desc nameDesc = {static_cast(serviceName.size()), serviceName.data()}; + + majStat = gss_import_name(&minStat, &nameDesc, + GSS_C_NT_HOSTBASED_SERVICE, &ctx->gssApiHandles->targetName); + + if (majStat != GSS_S_COMPLETE) { + q_GSSAPI_error("gss_import_name error", majStat, minStat); + ctx->gssApiHandles.reset(nullptr); + return QByteArray(); + } + + // Call qGssapiContinue with GSS_C_NO_CONTEXT to get initial packet + ctx->gssApiHandles->gssCtx = GSS_C_NO_CONTEXT; + return qGssapiContinue(ctx); +} + +// Continue GSS authentication with next token as needed +static QByteArray qGssapiContinue(QAuthenticatorPrivate *ctx, const QByteArray& challenge) +{ + OM_uint32 majStat, minStat, ignored; + QByteArray result; + gss_buffer_desc inBuf = {0, nullptr}; // GSS input token + gss_buffer_desc outBuf; // GSS output token + + if (!challenge.isEmpty()) { + inBuf.value = const_cast(challenge.data()); + inBuf.length = challenge.length(); + } + + majStat = gss_init_sec_context(&minStat, + GSS_C_NO_CREDENTIAL, + &ctx->gssApiHandles->gssCtx, + ctx->gssApiHandles->targetName, + GSS_C_NO_OID, + GSS_C_MUTUAL_FLAG, + 0, + GSS_C_NO_CHANNEL_BINDINGS, + challenge.isEmpty() ? GSS_C_NO_BUFFER : &inBuf, + nullptr, + &outBuf, + nullptr, + nullptr); + + if (outBuf.length != 0) + result = QByteArray(reinterpret_cast(outBuf.value), outBuf.length); + gss_release_buffer(&ignored, &outBuf); + + if (majStat != GSS_S_COMPLETE && majStat != GSS_S_CONTINUE_NEEDED) { + q_GSSAPI_error("gss_init_sec_context error", majStat, minStat); + gss_release_name(&ignored, &ctx->gssApiHandles->targetName); + if (ctx->gssApiHandles->gssCtx) + gss_delete_sec_context(&ignored, &ctx->gssApiHandles->gssCtx, GSS_C_NO_BUFFER); + ctx->gssApiHandles.reset(nullptr); + } + + if (majStat == GSS_S_COMPLETE) { + gss_release_name(&ignored, &ctx->gssApiHandles->targetName); + ctx->gssApiHandles.reset(nullptr); + } + + return result; +} + +// ---------------------------- End of GSSAPI code ---------------------------------------------- + +#endif // gssapi QT_END_NAMESPACE diff --git a/src/network/kernel/qauthenticator_p.h b/src/network/kernel/qauthenticator_p.h index 265cb7afe2..e201d22650 100644 --- a/src/network/kernel/qauthenticator_p.h +++ b/src/network/kernel/qauthenticator_p.h @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include @@ -61,14 +62,16 @@ QT_BEGIN_NAMESPACE class QHttpResponseHeader; -#ifdef Q_OS_WIN -class QNtlmWindowsHandles; +#if QT_CONFIG(sspi) // SSPI +class QSSPIWindowsHandles; +#elif QT_CONFIG(gssapi) // GSSAPI +class QGssApiHandles; #endif class Q_AUTOTEST_EXPORT QAuthenticatorPrivate { public: - enum Method { None, Basic, Ntlm, DigestMd5 }; + enum Method { None, Basic, Ntlm, DigestMd5, Negotiate }; QAuthenticatorPrivate(); ~QAuthenticatorPrivate(); @@ -79,8 +82,10 @@ public: Method method; QString realm; QByteArray challenge; -#ifdef Q_OS_WIN - QNtlmWindowsHandles *ntlmWindowsHandles; +#if QT_CONFIG(sspi) // SSPI + QScopedPointer sspiWindowsHandles; +#elif QT_CONFIG(gssapi) // GSSAPI + QScopedPointer gssApiHandles; #endif bool hasFailed; //credentials have been tried but rejected by server. @@ -100,7 +105,7 @@ public: QString workstation; QString userDomain; - QByteArray calculateResponse(const QByteArray &method, const QByteArray &path); + QByteArray calculateResponse(const QByteArray &method, const QByteArray &path, const QString& host); inline static QAuthenticatorPrivate *getPrivate(QAuthenticator &auth) { return auth.d; } inline static const QAuthenticatorPrivate *getPrivate(const QAuthenticator &auth) { return auth.d; } diff --git a/src/network/socket/qhttpsocketengine.cpp b/src/network/socket/qhttpsocketengine.cpp index 49ea17f9f8..6cae29193d 100644 --- a/src/network/socket/qhttpsocketengine.cpp +++ b/src/network/socket/qhttpsocketengine.cpp @@ -524,7 +524,7 @@ void QHttpSocketEngine::slotSocketConnected() //qDebug() << "slotSocketConnected: priv=" << priv << (priv ? (int)priv->method : -1); if (priv && priv->method != QAuthenticatorPrivate::None) { d->credentialsSent = true; - data += "Proxy-Authorization: " + priv->calculateResponse(method, path); + data += "Proxy-Authorization: " + priv->calculateResponse(method, path, d->proxy.hostName()); data += "\r\n"; } data += "\r\n"; diff --git a/tests/auto/network/kernel/qauthenticator/tst_qauthenticator.cpp b/tests/auto/network/kernel/qauthenticator/tst_qauthenticator.cpp index 55053842dc..8cef351554 100644 --- a/tests/auto/network/kernel/qauthenticator/tst_qauthenticator.cpp +++ b/tests/auto/network/kernel/qauthenticator/tst_qauthenticator.cpp @@ -93,7 +93,7 @@ void tst_QAuthenticator::basicAuth() QCOMPARE(priv->phase, QAuthenticatorPrivate::Start); - QCOMPARE(priv->calculateResponse("GET", "/").constData(), QByteArray("Basic " + expectedReply).constData()); + QCOMPARE(priv->calculateResponse("GET", "/", "").constData(), QByteArray("Basic " + expectedReply).constData()); } void tst_QAuthenticator::ntlmAuth_data() @@ -133,9 +133,9 @@ void tst_QAuthenticator::ntlmAuth() headers << qMakePair("WWW-Authenticate", "NTLM"); priv->parseHttpResponse(headers, /*isProxy = */ false); if (sso) - QVERIFY(priv->calculateResponse("GET", "/").startsWith("NTLM ")); + QVERIFY(priv->calculateResponse("GET", "/", "").startsWith("NTLM ")); else - QCOMPARE(priv->calculateResponse("GET", "/").constData(), "NTLM TlRMTVNTUAABAAAABYIIAAAAAAAAAAAAAAAAAAAAAAA="); + QCOMPARE(priv->calculateResponse("GET", "/", "").constData(), "NTLM TlRMTVNTUAABAAAABYIIAAAAAAAAAAAAAAAAAAAAAAA="); // NTLM phase 2: challenge headers.clear(); @@ -146,7 +146,7 @@ void tst_QAuthenticator::ntlmAuth() QEXPECT_FAIL("with-realm-sso", "NTLM authentication code doesn't extract the realm", Continue); QCOMPARE(auth.realm(), realm); - QVERIFY(priv->calculateResponse("GET", "/").startsWith("NTLM ")); + QVERIFY(priv->calculateResponse("GET", "/", "").startsWith("NTLM ")); } void tst_QAuthenticator::equalityOperators() From 90959f7080d0d6d9953f0bc5fa7ac01a3e82e85f Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 25 Feb 2019 12:08:21 +0100 Subject: [PATCH 1254/1650] Add all library dependencies for static OpenSSL builds on Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Static builds of OpenSSL can now be linked with -openssl-linked without passing additional library dependencies like user32 or advapi32. Fixes: QTBUG-73205 Change-Id: I66c13096b0a1466c1e6dfbd014123e18655270e6 Reviewed-by: Mårten Nordheim Reviewed-by: Timur Pocheptsov --- src/network/configure.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/configure.json b/src/network/configure.json index f3e18662aa..2c005f0efb 100644 --- a/src/network/configure.json +++ b/src/network/configure.json @@ -84,11 +84,11 @@ "sources": [ { "type": "openssl" }, { - "libs": "-lssleay32 -llibeay32", + "libs": "-lssleay32 -llibeay32 -lUser32 -lWs2_32 -lAdvapi32 -lGdi32", "condition": "config.win32" }, { - "libs": "-llibssl -llibcrypto", + "libs": "-llibssl -llibcrypto -lUser32 -lWs2_32 -lAdvapi32 -lCrypt32", "condition": "config.msvc" }, { From 2f4c6582363d3fd2ece331913c4baedd6dae1061 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Fri, 15 Feb 2019 15:04:29 +0100 Subject: [PATCH 1255/1650] Mark QEglFSKmsEglDeviceIntegration::presentBuffer as override clang complains; this makes it build Change-Id: I874c51ea4500edcf3f0bb9c79f0ef0f36309d579 Reviewed-by: Laszlo Agocs --- .../eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h index 0c64d83b12..a5697ec831 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h @@ -62,7 +62,7 @@ public: bool supportsPBuffers() const override; QEglFSWindow *createWindow(QWindow *window) const override; - void presentBuffer(QPlatformSurface *surface); + void presentBuffer(QPlatformSurface *surface) override; EGLDeviceEXT eglDevice() const { return m_egl_device; } From c93670c5a03cecbca9bb43aff65ceea3a401c7b1 Mon Sep 17 00:00:00 2001 From: JiDe Zhang Date: Tue, 6 Nov 2018 15:29:03 +0800 Subject: [PATCH 1256/1650] QGenericUnixTheme: use QStandardPaths get the xdg data path The corresponding interface is already provided in QStandardPaths. We should use QStandardPaths::GenericDataLocation instead of the environment variable XDG_DATA_DIRS. Change-Id: I0e89e8c86d629585ec7d9a12989f24335aa6e3ba Reviewed-by: Anton Kudryavtsev Reviewed-by: Dmitry Shachnev Reviewed-by: Friedemann Kleint Reviewed-by: David Faure --- .../themes/genericunix/qgenericunixthemes.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp index 1003812767..7b3f9b624a 100644 --- a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp +++ b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp @@ -172,15 +172,9 @@ QStringList QGenericUnixTheme::xdgIconThemePaths() if (homeIconDir.isDir()) paths.prepend(homeIconDir.absoluteFilePath()); - QString xdgDirString = QFile::decodeName(qgetenv("XDG_DATA_DIRS")); - if (xdgDirString.isEmpty()) - xdgDirString = QLatin1String("/usr/local/share/:/usr/share/"); - const auto xdgDirs = xdgDirString.splitRef(QLatin1Char(':')); - for (const QStringRef &xdgDir : xdgDirs) { - const QFileInfo xdgIconsDir(xdgDir + QLatin1String("/icons")); - if (xdgIconsDir.isDir()) - paths.append(xdgIconsDir.absoluteFilePath()); - } + paths.append(QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, + QStringLiteral("icons"), + QStandardPaths::LocateDirectory)); return paths; } From 8f507a0b02e96072a7e2a9dda2d34efd85163926 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 25 Feb 2019 14:56:53 +0100 Subject: [PATCH 1257/1650] Display EXTRA_TRANSLATIONS files in VS projects This amends commit 01d2f35b. Change-Id: I958c924f7f5a477f5ebced895ce2678d282526ad Reviewed-by: Kai Koehne --- qmake/generators/win32/msvc_vcproj.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index f83e5c0247..e8340164ad 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -1447,6 +1447,7 @@ void VcprojGenerator::initTranslationFiles() vcProject.TranslationFiles.Guid = _GUIDTranslationFiles; vcProject.TranslationFiles.addFiles(project->values("TRANSLATIONS")); + vcProject.TranslationFiles.addFiles(project->values("EXTRA_TRANSLATIONS")); vcProject.TranslationFiles.Project = this; vcProject.TranslationFiles.Config = &(vcProject.Configuration); From b0dcb94d9462f38e36c15ddec64e5eb0a04630a4 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 25 Feb 2019 14:58:28 +0100 Subject: [PATCH 1258/1650] vcxproj generator: Fix files being in multiple filters Visual Studio doesn't support files being in multiple filters and refuses to load such projects. Source files that appear in variables that are mapped to file filters (SOURCES, TRANSLATIONS, ...) must not be added to a second filter if they are input for an extra compiler. Fixes: QTBUG-74004 Change-Id: Id2d752059c98d04e8154a7848c91f29a94bd092a Reviewed-by: Kai Koehne --- qmake/generators/win32/msvc_vcproj.cpp | 26 ++++++++++++++++++++++++-- qmake/generators/win32/msvc_vcproj.h | 1 + 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index e8340164ad..be0b67a9e6 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -1570,7 +1570,7 @@ void VcprojGenerator::initExtraCompilerOutputs() const ProStringList &tmp_in = project->values(project->first(ProKey(*it + ".input")).toKey()); for (int i = 0; i < tmp_in.count(); ++i) { const QString &filename = tmp_in.at(i).toQString(); - if (extraCompilerSources.contains(filename)) + if (extraCompilerSources.contains(filename) && !otherFiltersContain(filename)) extraCompile.addFile(Option::fixPathToTargetOS( replaceExtraCompilerVariables(filename, tmp_out, QString(), NoShell), false)); } @@ -1586,7 +1586,7 @@ void VcprojGenerator::initExtraCompilerOutputs() const ProStringList &tmp_in = project->values(inputVar.toKey()); for (int i = 0; i < tmp_in.count(); ++i) { const QString &filename = tmp_in.at(i).toQString(); - if (extraCompilerSources.contains(filename)) + if (extraCompilerSources.contains(filename) && !otherFiltersContain(filename)) extraCompile.addFile(Option::fixPathToTargetOS( replaceExtraCompilerVariables(filename, QString(), QString(), NoShell), false)); } @@ -1600,6 +1600,28 @@ void VcprojGenerator::initExtraCompilerOutputs() } } +bool VcprojGenerator::otherFiltersContain(const QString &fileName) const +{ + auto filterFileMatches = [&fileName] (const VCFilterFile &ff) + { + return ff.file == fileName; + }; + for (const VCFilter *filter : { &vcProject.RootFiles, + &vcProject.SourceFiles, + &vcProject.HeaderFiles, + &vcProject.GeneratedFiles, + &vcProject.LexYaccFiles, + &vcProject.TranslationFiles, + &vcProject.FormFiles, + &vcProject.ResourceFiles, + &vcProject.DeploymentFiles, + &vcProject.DistributionFiles}) { + if (std::any_of(filter->Files.cbegin(), filter->Files.cend(), filterFileMatches)) + return true; + } + return false; +} + // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ diff --git a/qmake/generators/win32/msvc_vcproj.h b/qmake/generators/win32/msvc_vcproj.h index 6af5ec7007..0b9770e962 100644 --- a/qmake/generators/win32/msvc_vcproj.h +++ b/qmake/generators/win32/msvc_vcproj.h @@ -131,6 +131,7 @@ private: ProString firstInputFileName(const ProString &extraCompilerName) const; QString firstExpandedOutputFileName(const ProString &extraCompilerName); void createCustomBuildToolFakeFile(const QString &cbtFilePath, const QString &realOutFilePath); + bool otherFiltersContain(const QString &fileName) const; friend class VCFilter; }; From bc107d81004a5f3929f30088f4a58a221bea5c3b Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 25 Feb 2019 13:33:18 +0100 Subject: [PATCH 1259/1650] Allow QML plugin to specify import name explicitly For creating the qmlplugindump rule we need the name of the import. So far we're trying to derive this from the directory name, but that becomes complicated if versions are included, like QtQuick/Controls.2/Fusion Instead of trying to tweak the regexp even more to capture this, we now allow a plugin to set it's name explicitly via IMPORT_NAME. Change-Id: Ie75dae7d41398b3ac19ccb6910002b6fad009891 Reviewed-by: Joerg Bornemann --- mkspecs/features/qml_plugin.prf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/qml_plugin.prf b/mkspecs/features/qml_plugin.prf index ad8ecdf5f1..02068ae766 100644 --- a/mkspecs/features/qml_plugin.prf +++ b/mkspecs/features/qml_plugin.prf @@ -94,7 +94,7 @@ load(qt_common) } load(resolve_target) - TARGETPATHBASE = $$replace(TARGETPATH, \\.\\d+\$, ) + isEmpty(IMPORT_NAME): IMPORT_NAME = $$replace(TARGETPATH, \\.\\d+\$, ) !qml1_target { isEmpty(QMAKE_PLUGINDUMP_DEPENDENCIES_FILE):exists($$_PRO_FILE_PWD_/dependencies.json): \ @@ -104,7 +104,7 @@ load(qt_common) } qmltypes.target = qmltypes - qmltypes.commands = $$QMLPLUGINDUMP -nonrelocatable $$QMAKE_QMLPLUGINDUMP_FLAGS $$replace(TARGETPATHBASE, /, .) $$IMPORT_VERSION > $$QMLTYPEFILE + qmltypes.commands = $$QMLPLUGINDUMP -nonrelocatable $$QMAKE_QMLPLUGINDUMP_FLAGS $$replace(IMPORT_NAME, /, .) $$IMPORT_VERSION > $$QMLTYPEFILE qmltypes.depends = $$QMAKE_RESOLVED_TARGET } else { qmltypes.CONFIG += recursive From 58cad5caf2064900ae95ef52b521ec8e4b963ff8 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Thu, 21 Feb 2019 23:56:58 +0100 Subject: [PATCH 1260/1650] build compose input context plugin not only for XCB platform It can be used by any platform that uses xkbcommon for keyboard input: wayland, eglfs. Change-Id: Iba7d8989f922063cdceb94c1c4bcd8d8e4ae294e Reviewed-by: Giulio Camuffo --- src/plugins/platforminputcontexts/platforminputcontexts.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforminputcontexts/platforminputcontexts.pro b/src/plugins/platforminputcontexts/platforminputcontexts.pro index ed6b1b8702..68f6792377 100644 --- a/src/plugins/platforminputcontexts/platforminputcontexts.pro +++ b/src/plugins/platforminputcontexts/platforminputcontexts.pro @@ -5,6 +5,6 @@ qtHaveModule(dbus) { !mac:!win32:SUBDIRS += ibus } -qtConfig(xcb): SUBDIRS += compose +qtConfig(xkbcommon): SUBDIRS += compose From 9694d754b815abdf302aba26bd1eada5768adb97 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 25 Feb 2019 15:01:56 +0100 Subject: [PATCH 1261/1650] Haiku: Fix mis-spelled module in .pro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix warning: Project ERROR: Unknown module(s) in QT: eventdistpatcher_support-private Change-Id: Ic74481621c541fc0a13640c5e5cae2df44ffb091 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/haiku/haiku.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/haiku/haiku.pro b/src/plugins/platforms/haiku/haiku.pro index fd1f47b963..e7702361ee 100644 --- a/src/plugins/platforms/haiku/haiku.pro +++ b/src/plugins/platforms/haiku/haiku.pro @@ -1,6 +1,6 @@ TARGET = qhaiku -QT += core-private gui-private eventdistpatcher_support-private +QT += core-private gui-private eventdispatcher_support-private SOURCES = \ main.cpp \ From 7e60858cbc40b8958482ca2e77bed4fda69b161c Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 14 Feb 2019 13:27:18 +0100 Subject: [PATCH 1262/1650] Don't edit the item if we did not get the press event on the same item With a QTreeView it is possible that collapsing an item can cause the item under the mouse to be a new one and over the checkbox area for the new item. As a result, a release can cause it to change the check state even though it did not get the press for that item. This ensures that it only allows the edit if it got the press as well. Fixes: QTBUG-61476 Change-Id: I9a0821466afc84c97c9819755ccbacd729f7fbd7 Reviewed-by: Christian Ehrlicher --- src/widgets/itemviews/qabstractitemview.cpp | 2 +- .../itemviews/qtreeview/tst_qtreeview.cpp | 54 +++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 02eae33a12..e1e45143b4 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -1912,7 +1912,7 @@ void QAbstractItemView::mouseReleaseEvent(QMouseEvent *event) bool click = (index == d->pressedIndex && index.isValid()); bool selectedClicked = click && (event->button() == Qt::LeftButton) && d->pressedAlreadySelected; EditTrigger trigger = (selectedClicked ? SelectedClicked : NoEditTriggers); - bool edited = edit(index, trigger, event); + const bool edited = click ? edit(index, trigger, event) : false; d->ctrlDragSelectionFlag = QItemSelectionModel::NoUpdate; diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index 8f9afeea4d..a9858ae420 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -199,6 +199,7 @@ private slots: void taskQTBUG_45697_crash(); void taskQTBUG_7232_AllowUserToControlSingleStep(); void taskQTBUG_8376(); + void taskQTBUG_61476(); void testInitialFocus(); }; @@ -4726,5 +4727,58 @@ void tst_QTreeView::taskQTBUG_8376() QCOMPARE(rowHeightLvl1Visible, rowHeightLvl1Visible2); } +void tst_QTreeView::taskQTBUG_61476() +{ + // This checks that if a user clicks on an item to collapse it that it + // does not edit (in this case change the check state) the item that is + // now over the mouse just because it got a release event + QTreeView tv; + QStandardItemModel model; + QStandardItem *lastTopLevel = nullptr; + { + for (int i = 0; i < 4; ++i) { + QStandardItem *item = new QStandardItem(QLatin1String("Row Item")); + item->setCheckable(true); + item->setCheckState(Qt::Checked); + model.appendRow(item); + lastTopLevel = item; + for (int j = 0; j < 2; ++j) { + QStandardItem *childItem = new QStandardItem(QLatin1String("Child row Item")); + childItem->setCheckable(true); + childItem->setCheckState(Qt::Checked); + item->appendRow(childItem); + QStandardItem *grandChild = new QStandardItem(QLatin1String("Grand child row Item")); + grandChild->setCheckable(true); + grandChild->setCheckState(Qt::Checked); + childItem->appendRow(grandChild); + } + } + } + tv.setModel(&model); + tv.expandAll(); + // We need it to be this size so that the effect of the collapsing will + // cause the parent item to move to be under the cursor + tv.resize(200, 200); + tv.show(); + QVERIFY(QTest::qWaitForWindowActive(&tv)); + tv.verticalScrollBar()->setValue(tv.verticalScrollBar()->maximum()); + + // We want to press specifically right around where a checkbox for the + // parent item could be when collapsing + QTreeViewPrivate *priv = static_cast(qt_widget_private(&tv)); + const QModelIndex mi = lastTopLevel->child(0)->index(); + const QRect rect = priv->itemDecorationRect(mi); + const QPoint pos = rect.center(); + + QTest::mousePress(tv.viewport(), Qt::LeftButton, 0, pos); + if (tv.style()->styleHint(QStyle::SH_ListViewExpand_SelectMouseType, 0, &tv) == + QEvent::MouseButtonPress) + QTRY_VERIFY(!tv.isExpanded(mi)); + + QTest::mouseRelease(tv.viewport(), Qt::LeftButton, 0, pos); + QTRY_VERIFY(!tv.isExpanded(mi)); + QCOMPARE(lastTopLevel->checkState(), Qt::Checked); +} + QTEST_MAIN(tst_QTreeView) #include "tst_qtreeview.moc" From 96f6cab22cab252cbe7a98bbeadde95497e0bd75 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 26 Feb 2019 10:38:58 +0100 Subject: [PATCH 1263/1650] Blacklist nouveau and llvmpipe for multithreading After removing Mesa drivers from being blank blacklisted, we still need to blacklist nouveau specifically due to their lack of proper locking: https://bugs.freedesktop.org/show_bug.cgi?id=91632 llvmpipe is similarly blacklisted for now, as we lack enough information to know if the underlying issue behind QTCREATORBUG-10666 has been solved. Fixes: QTBUG-73715 Change-Id: I1a60b562cd9db94fa8462b922d6bfeebf0088dc5 Reviewed-by: Laszlo Agocs --- .../xcb_glx/qglxintegration.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp index d42a33c22b..476de6d1e5 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp @@ -652,6 +652,12 @@ static const char *qglx_threadedgl_blacklist_renderer[] = { 0 }; +static const char *qglx_threadedgl_blacklist_vendor[] = { + "llvmpipe", // QTCREATORBUG-10666 + "nouveau", // https://bugs.freedesktop.org/show_bug.cgi?id=91632 + nullptr +}; + void QGLXContext::queryDummyContext() { if (m_queriedDummyContext) @@ -710,6 +716,18 @@ void QGLXContext::queryDummyContext() } } } + if (const char *vendor = (const char *) glGetString(GL_VENDOR)) { + for (int i = 0; qglx_threadedgl_blacklist_vendor[i]; ++i) { + if (strstr(vendor, qglx_threadedgl_blacklist_vendor[i]) != 0) { + qCDebug(lcQpaGl).nospace() << "Multithreaded OpenGL disabled: " + "blacklisted vendor \"" + << qglx_threadedgl_blacklist_vendor[i] + << "\""; + m_supportsThreading = false; + break; + } + } + } if (glxvendor && m_supportsThreading) { // Blacklist Mesa drivers due to QTCREATORBUG-10875 (crash in creator), From ac7f46dd9114051756f56571b9cb3bda002314a1 Mon Sep 17 00:00:00 2001 From: Ahmad Samir Date: Mon, 5 Nov 2018 17:07:03 +0200 Subject: [PATCH 1264/1650] Unix: QPageSetupDialog: Use print device default paper size When invoking QPageSetupDialog from QPrintPreviewDialog, don't construct a new QPageSetupDialog every time the pageSetup action is triggered, instead reuse the dialog if it's already been created. This way setPrinter is called only once. This matches how QPrintDialog invokes QPageSetupDialog. Set the default print device paper size in initPageSizes() instead of setPrinter(). Change-Id: Ic82e6dd47ee00ecdd942c5ba59dbf09fb18ef218 Reviewed-by: Frederik Gladhorn Reviewed-by: Andy Shaw --- .../dialogs/qpagesetupdialog_unix.cpp | 26 ++++++++++++------- .../dialogs/qprintpreviewdialog.cpp | 12 ++++++--- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp index d9b4a84aa9..1d8af9dbf0 100644 --- a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp +++ b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp @@ -361,13 +361,21 @@ void QPageSetupWidget::initPageSizes() QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get(); if (ps) { QPrintDevice printDevice = ps->createPrintDevice(m_printerName); + const QPageSize defaultSize = printDevice.defaultPageSize(); const auto pageSizes = printDevice.supportedPageSizes(); for (const QPageSize &pageSize : pageSizes) m_ui.pageSizeCombo->addItem(pageSize.name(), QVariant::fromValue(pageSize)); - if (m_ui.pageSizeCombo->count() > 0 && printDevice.supportsCustomPageSizes()) { - m_ui.pageSizeCombo->addItem(tr("Custom")); - m_realCustomPageSizeIndex = m_ui.pageSizeCombo->count() - 1; + if (m_ui.pageSizeCombo->count() > 0) { + if (printDevice.supportsCustomPageSizes()) { + m_ui.pageSizeCombo->addItem(tr("Custom")); + m_realCustomPageSizeIndex = m_ui.pageSizeCombo->count() - 1; + } m_blockSignals = false; + + // If the defaultSize is index 0, setCurrentIndex won't emit the currentIndexChanged + // signal; workaround the issue by initially setting the currentIndex to -1 + m_ui.pageSizeCombo->setCurrentIndex(-1); + m_ui.pageSizeCombo->setCurrentIndex(m_ui.pageSizeCombo->findData(QVariant::fromValue(defaultSize))); return; } } @@ -403,12 +411,6 @@ void QPageSetupWidget::setPrinter(QPrinter *printer, QPrintDevice *printDevice, // Initialize the layout to the current QPrinter layout m_pageLayout = m_printer->pageLayout(); - if (printDevice) { - const QPageSize pageSize = printDevice->defaultPageSize(); - const QMarginsF printable = printDevice->printableMargins(pageSize, m_pageLayout.orientation(), m_printer->resolution()); - m_pageLayout.setPageSize(pageSize, qt_convertMargins(printable, QPageLayout::Point, m_pageLayout.units())); - } - // Assume if margins are Points then is by default, so set to locale default units if (m_pageLayout.units() == QPageLayout::Point) { if (QLocale().measurementSystem() == QLocale::MetricSystem) @@ -735,8 +737,12 @@ int QPageSetupDialog::exec() Q_D(QPageSetupDialog); int ret = QDialog::exec(); - if (ret == Accepted) + if (ret == Accepted) { static_cast (d)->widget->setupPrinter(); + static_cast (d)->widget->updateSavedValues(); + } else { + static_cast (d)->widget->revertToSavedValues(); + } return ret; } diff --git a/src/printsupport/dialogs/qprintpreviewdialog.cpp b/src/printsupport/dialogs/qprintpreviewdialog.cpp index e6b665f82c..258741c35c 100644 --- a/src/printsupport/dialogs/qprintpreviewdialog.cpp +++ b/src/printsupport/dialogs/qprintpreviewdialog.cpp @@ -152,8 +152,8 @@ class QPrintPreviewDialogPrivate : public QDialogPrivate Q_DECLARE_PUBLIC(QPrintPreviewDialog) public: QPrintPreviewDialogPrivate() - : printDialog(nullptr), ownPrinter(false), - initialized(false) {} + : printDialog(nullptr), pageSetupDialog(nullptr), + ownPrinter(false), initialized(false) {} // private slots void _q_fit(QAction *action); @@ -178,6 +178,7 @@ public: void updateZoomFactor(); QPrintDialog *printDialog; + QPageSetupDialog *pageSetupDialog; QPrintPreviewWidget *preview; QPrinter *printer; bool ownPrinter; @@ -602,8 +603,10 @@ void QPrintPreviewDialogPrivate::_q_pageSetup() { Q_Q(QPrintPreviewDialog); - QPageSetupDialog pageSetup(printer, q); - if (pageSetup.exec() == QDialog::Accepted) { + if (!pageSetupDialog) + pageSetupDialog = new QPageSetupDialog(printer, q); + + if (pageSetupDialog->exec() == QDialog::Accepted) { // update possible orientation changes if (preview->orientation() == QPrinter::Portrait) { portraitAction->setChecked(true); @@ -713,6 +716,7 @@ QPrintPreviewDialog::~QPrintPreviewDialog() if (d->ownPrinter) delete d->printer; delete d->printDialog; + delete d->pageSetupDialog; } /*! From 1500d2283e17be72226b2960a79039254887977f Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Wed, 20 Feb 2019 13:55:03 +0100 Subject: [PATCH 1265/1650] Clear only one device from g_pointIdMap when all points released MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The new test tst_QTouchEvent::touchOnMultipleTouchscreens() needs the touchpoint IDs to be predictable, but another test currently has a QEXPECT_FAIL; without release events, g_pointIdMap continued to hold the touchpoints that were there when the test failed. So it's necessary to add QWindowSystemInterfacePrivate::clearPointIdMap() to be able to call it in the test cleanup function. Fixes: QTBUG-73830 Change-Id: Ia6a70d028be95cd2b6676db6363ec408c0b116bc Reviewed-by: Jan Arve Sæther --- src/gui/kernel/qwindowsysteminterface.cpp | 20 ++- src/gui/kernel/qwindowsysteminterface_p.h | 1 + .../kernel/qtouchevent/tst_qtouchevent.cpp | 155 ++++++++++++++++++ 3 files changed, 174 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index 5b32405f5e..7067ece1d8 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -695,13 +695,29 @@ QList } if (states == Qt::TouchPointReleased) { - g_nextPointId = 1; - g_pointIdMap->clear(); + // All points on deviceId have been released. + // Remove all points associated with that device from g_pointIdMap. + // (On other devices, some touchpoints might still be pressed. + // But this function is only called with points from one device at a time.) + for (auto it = g_pointIdMap->begin(); it != g_pointIdMap->end();) { + if (it.key() >> 32 == quint64(deviceId)) + it = g_pointIdMap->erase(it); + else + ++it; + } + if (g_pointIdMap->isEmpty()) + g_nextPointId = 1; } return touchPoints; } +void QWindowSystemInterfacePrivate::clearPointIdMap() +{ + g_pointIdMap->clear(); + g_nextPointId = 1; +} + QList QWindowSystemInterfacePrivate::toNativeTouchPoints(const QList& pointList, const QWindow *window) diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h index 9cb4e191cc..cea02fb8b7 100644 --- a/src/gui/kernel/qwindowsysteminterface_p.h +++ b/src/gui/kernel/qwindowsysteminterface_p.h @@ -537,6 +537,7 @@ public: static QList toNativeTouchPoints(const QList& pointList, const QWindow *window); + static void clearPointIdMap(); static void installWindowSystemEventHandler(QWindowSystemEventHandler *handler); static void removeWindowSystemEventhandler(QWindowSystemEventHandler *handler); diff --git a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp index db5e83e2c7..13dc924f93 100644 --- a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp +++ b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp @@ -204,6 +204,7 @@ private slots: void basicRawEventTranslationOfIds(); void multiPointRawEventTranslationOnTouchScreen(); void multiPointRawEventTranslationOnTouchPad(); + void touchOnMultipleTouchscreens(); void deleteInEventHandler(); void deleteInRawEventTranslation(); void crashInQGraphicsSceneAfterNotHandlingTouchBegin(); @@ -213,11 +214,13 @@ private slots: private: QTouchDevice *touchScreenDevice; + QTouchDevice *secondaryTouchScreenDevice; QTouchDevice *touchPadDevice; }; tst_QTouchEvent::tst_QTouchEvent() : touchScreenDevice(QTest::createTouchDevice()) + , secondaryTouchScreenDevice(QTest::createTouchDevice()) , touchPadDevice(QTest::createTouchDevice(QTouchDevice::TouchPad)) { } @@ -225,6 +228,7 @@ tst_QTouchEvent::tst_QTouchEvent() void tst_QTouchEvent::cleanup() { QVERIFY(QGuiApplication::topLevelWindows().isEmpty()); + QWindowSystemInterfacePrivate::clearPointIdMap(); } void tst_QTouchEvent::qPointerUniqueId() @@ -951,6 +955,157 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen() } } +void tst_QTouchEvent::touchOnMultipleTouchscreens() +{ + tst_QTouchEventWidget touchWidget; + touchWidget.setWindowTitle(QTest::currentTestFunction()); + touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); + touchWidget.setGeometry(100, 100, 400, 300); + touchWidget.show(); + QVERIFY(QTest::qWaitForWindowExposed(&touchWidget)); + QWindow *window = touchWidget.windowHandle(); + + QPointF pos = touchWidget.rect().center(); + QPointF screenPos = touchWidget.mapToGlobal(pos.toPoint()); + QPointF delta(10, 10); + QRectF screenGeometry = QApplication::desktop()->screenGeometry(&touchWidget); + + QVector rawTouchPoints(3); + rawTouchPoints[0].setId(0); + rawTouchPoints[1].setId(10); + rawTouchPoints[2].setId(11); + + // this should be translated to a TouchBegin + rawTouchPoints[0].setState(Qt::TouchPointPressed); + rawTouchPoints[0].setScreenPos(screenPos); + rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry)); + rawTouchPoints[0].setRawScreenPositions({{12, 34}, {56, 78}}); + ulong timestamp = 1234; + QList nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(QList() << rawTouchPoints[0], window); + QWindowSystemInterface::handleTouchEvent(window, timestamp, touchScreenDevice, nativeTouchPoints); + QCoreApplication::processEvents(); + QVERIFY(touchWidget.seenTouchBegin); + QVERIFY(!touchWidget.seenTouchUpdate); + QVERIFY(!touchWidget.seenTouchEnd); + QCOMPARE(touchWidget.touchBeginPoints.count(), 1); + QCOMPARE(touchWidget.timestamp, timestamp); + QTouchEvent::TouchPoint touchBeginPoint = touchWidget.touchBeginPoints.first(); + const int touchPointId = (QTouchDevicePrivate::get(touchScreenDevice)->id << 24) + 1; + const int secTouchPointId = (QTouchDevicePrivate::get(secondaryTouchScreenDevice)->id << 24) + 2; + QCOMPARE(touchBeginPoint.id(), touchPointId); + QCOMPARE(touchBeginPoint.state(), rawTouchPoints[0].state()); + QCOMPARE(touchBeginPoint.pos(), pos); + + // press a point on secondaryTouchScreenDevice + touchWidget.seenTouchBegin = false; + rawTouchPoints[1].setState(Qt::TouchPointPressed); + rawTouchPoints[1].setScreenPos(screenPos); + rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry)); + rawTouchPoints[1].setRawScreenPositions({{90, 100}, {110, 120}}); + nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(QList() << rawTouchPoints[1], window); + QWindowSystemInterface::handleTouchEvent(window, ++timestamp, secondaryTouchScreenDevice, nativeTouchPoints); + QCoreApplication::processEvents(); + QVERIFY(!touchWidget.seenTouchEnd); + QCOMPARE(touchWidget.touchBeginPoints.count(), 1); + QCOMPARE(touchWidget.timestamp, timestamp); + touchBeginPoint = touchWidget.touchBeginPoints[0]; + QCOMPARE(touchBeginPoint.id(), (QTouchDevicePrivate::get(secondaryTouchScreenDevice)->id << 24) + 2); + QCOMPARE(touchBeginPoint.state(), rawTouchPoints[1].state()); + QCOMPARE(touchBeginPoint.pos(), pos); + + // press another point on secondaryTouchScreenDevice + touchWidget.seenTouchBegin = false; + rawTouchPoints[2].setState(Qt::TouchPointPressed); + rawTouchPoints[2].setScreenPos(screenPos); + rawTouchPoints[2].setNormalizedPos(normalized(rawTouchPoints[2].pos(), screenGeometry)); + rawTouchPoints[2].setRawScreenPositions({{130, 140}, {150, 160}}); + nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(QList() << rawTouchPoints[2], window); + QWindowSystemInterface::handleTouchEvent(window, ++timestamp, secondaryTouchScreenDevice, nativeTouchPoints); + QCoreApplication::processEvents(); + QVERIFY(!touchWidget.seenTouchEnd); + QCOMPARE(touchWidget.touchBeginPoints.count(), 1); + QCOMPARE(touchWidget.timestamp, timestamp); + touchBeginPoint = touchWidget.touchBeginPoints[0]; + QCOMPARE(touchBeginPoint.id(), (QTouchDevicePrivate::get(secondaryTouchScreenDevice)->id << 24) + 3); + QCOMPARE(touchBeginPoint.state(), rawTouchPoints[2].state()); + QCOMPARE(touchBeginPoint.pos(), pos); + + // moving the first point should translate to TouchUpdate + rawTouchPoints[0].setState(Qt::TouchPointMoved); + rawTouchPoints[0].setScreenPos(screenPos + delta); + rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry)); + nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(QList() << rawTouchPoints[0], window); + QWindowSystemInterface::handleTouchEvent(window, ++timestamp, touchScreenDevice, nativeTouchPoints); + QCoreApplication::processEvents(); + QVERIFY(touchWidget.seenTouchBegin); + QVERIFY(touchWidget.seenTouchUpdate); + QVERIFY(!touchWidget.seenTouchEnd); + QCOMPARE(touchWidget.touchUpdatePoints.count(), 1); + QTouchEvent::TouchPoint touchUpdatePoint = touchWidget.touchUpdatePoints.first(); + QCOMPARE(touchUpdatePoint.id(), touchPointId); + QCOMPARE(touchUpdatePoint.state(), rawTouchPoints[0].state()); + QCOMPARE(touchUpdatePoint.pos(), pos + delta); + + // releasing the first point translates to TouchEnd + rawTouchPoints[0].setState(Qt::TouchPointReleased); + rawTouchPoints[0].setScreenPos(screenPos + delta + delta); + rawTouchPoints[0].setNormalizedPos(normalized(rawTouchPoints[0].pos(), screenGeometry)); + nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(QList() << rawTouchPoints[0], window); + QWindowSystemInterface::handleTouchEvent(window, ++timestamp, touchScreenDevice, nativeTouchPoints); + QCoreApplication::processEvents(); + QVERIFY(touchWidget.seenTouchBegin); + QVERIFY(touchWidget.seenTouchUpdate); + QVERIFY(touchWidget.seenTouchEnd); + QCOMPARE(touchWidget.touchEndPoints.count(), 1); + QTouchEvent::TouchPoint touchEndPoint = touchWidget.touchEndPoints.first(); + QCOMPARE(touchEndPoint.id(), touchPointId); + QCOMPARE(touchEndPoint.state(), rawTouchPoints[0].state()); + QCOMPARE(touchEndPoint.pos(), pos + delta + delta); + + // Widgets don't normally handle this case: if a TouchEnd was seen before, then + // WA_WState_AcceptedTouchBeginEvent will be false, and + // QApplicationPrivate::translateRawTouchEvent will ignore touch events that aren't TouchBegin. + // So we have to set it true. It _did_ in fact accept the touch begin from the secondary device, + // but it also got a TouchEnd from the primary device in the meantime. + touchWidget.setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent, true); + + // Releasing one point on the secondary touchscreen does not yet generate TouchEnd. + touchWidget.seenTouchEnd = false; + touchWidget.touchEndPoints.clear(); + rawTouchPoints[1].setState(Qt::TouchPointReleased); + rawTouchPoints[2].setState(Qt::TouchPointStationary); + nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(QList() << rawTouchPoints[1] << rawTouchPoints[2], window); + QWindowSystemInterface::handleTouchEvent(window, ++timestamp, secondaryTouchScreenDevice, nativeTouchPoints); + QCoreApplication::processEvents(); + QVERIFY(touchWidget.seenTouchBegin); + QVERIFY(touchWidget.seenTouchUpdate); + QVERIFY(!touchWidget.seenTouchEnd); + QCOMPARE(touchWidget.touchUpdatePoints.count(), 2); + QCOMPARE(touchWidget.touchUpdatePoints[0].id(), secTouchPointId); + QCOMPARE(touchWidget.touchUpdatePoints[1].id(), secTouchPointId + 1); + + // releasing the last point on the secondary touchscreen translates to TouchEnd + touchWidget.seenTouchEnd = false; + rawTouchPoints[2].setState(Qt::TouchPointReleased); + nativeTouchPoints = + QWindowSystemInterfacePrivate::toNativeTouchPoints(QList() << rawTouchPoints[2], window); + QWindowSystemInterface::handleTouchEvent(window, ++timestamp, secondaryTouchScreenDevice, nativeTouchPoints); + QCoreApplication::processEvents(); + QVERIFY(touchWidget.seenTouchBegin); + QVERIFY(touchWidget.seenTouchUpdate); + QVERIFY(touchWidget.seenTouchEnd); + QCOMPARE(touchWidget.touchEndPoints.count(), 1); + touchEndPoint = touchWidget.touchEndPoints.first(); + QCOMPARE(touchEndPoint.id(), secTouchPointId + 1); + QCOMPARE(touchEndPoint.state(), rawTouchPoints[2].state()); +} + void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad() { tst_QTouchEventWidget touchWidget; From 197029b3d23237e61311019de1b63e3ce6720ed5 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 10 Dec 2018 19:18:57 -0800 Subject: [PATCH 1266/1650] Make the QEventDispatcherWin32Private::interrupt flag atomic Not entirely sure that this solves the problem reported in the bug report, but here's the theory: the loop 633 while (!d->interrupt) { ... 710 } has few calls that recurse back, so the compiler optimizer can assume that the variable remains unchanged (not interrupted) in most of the branches. Additionally, it can assume the variable did not change from there to 712 // still nothing - wait for message or signalled objects 713 canWait = (!retVal 714 && !d->interrupt 715 && (flags & QEventLoop::WaitForMoreEvents)); Which causes canWait to be true, despite having been interrupted by another thread. Changing to an atomic does not force the reloading of the variable (strictly speaking, would need volatile, but all atomic implementations do reload now), but it solves the problem of data race, which was UB. The equivalent variable in the Unix event dispatcher is atomic (commit 49d7e71f77f899c05e4b5187e8834dfcbddf4505 from 2013). I've reordered the bool members so they're all together and reduce the amount of padding in this class. Fixes: QTBUG-72438 Change-Id: I4ac1156702324f0fb814fffd156f290df94dc4c7 Reviewed-by: Joerg Bornemann Reviewed-by: Thiago Macieira --- src/corelib/kernel/qeventdispatcher_win.cpp | 10 +++++----- src/corelib/kernel/qeventdispatcher_win_p.h | 7 ++++--- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 0bddf89b15..b3b6b1be20 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -95,7 +95,7 @@ class QEventDispatcherWin32Private; LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp); QEventDispatcherWin32Private::QEventDispatcherWin32Private() - : threadId(GetCurrentThreadId()), interrupt(false), closingDown(false), internalHwnd(0), + : threadId(GetCurrentThreadId()), interrupt(false), internalHwnd(0), getMessageHook(0), serialNumber(0), lastSerialNumber(0), sendPostedEventsWindowsTimerId(0), wakeUps(0), activateNotifiersPosted(false), winEventNotifierActivatedEvent(NULL) { @@ -552,7 +552,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) wakeUp(); // trigger a call to sendPostedEvents() } - d->interrupt = false; + d->interrupt.store(false); emit awake(); bool canWait; @@ -568,7 +568,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) pHandles = &d->winEventNotifierActivatedEvent; } QVarLengthArray processedTimers; - while (!d->interrupt) { + while (!d->interrupt.load()) { MSG msg; bool haveMessage; @@ -649,7 +649,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) // still nothing - wait for message or signalled objects canWait = (!retVal - && !d->interrupt + && !d->interrupt.load() && (flags & QEventLoop::WaitForMoreEvents)); if (canWait) { emit aboutToBlock(); @@ -1016,7 +1016,7 @@ void QEventDispatcherWin32::wakeUp() void QEventDispatcherWin32::interrupt() { Q_D(QEventDispatcherWin32); - d->interrupt = true; + d->interrupt.store(true); wakeUp(); } diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h index a7ed8dda8a..3bb618153b 100644 --- a/src/corelib/kernel/qeventdispatcher_win_p.h +++ b/src/corelib/kernel/qeventdispatcher_win_p.h @@ -165,8 +165,7 @@ public: DWORD threadId; - bool interrupt; - bool closingDown; + QAtomicInt interrupt; // internal window handle used for socketnotifiers/timers/etc HWND internalHwnd; @@ -193,9 +192,11 @@ public: void postActivateSocketNotifiers(); void doWsaAsyncSelect(int socket, long event); + bool closingDown = false; + + bool winEventNotifierListModified = false; HANDLE winEventNotifierActivatedEvent; QList winEventNotifierList; - bool winEventNotifierListModified = false; void activateEventNotifier(QWinEventNotifier * wen); QList queuedUserInputEvents; From 99566f68755449dbabb7345da5b5876e82f159f1 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 22 Jan 2019 10:52:57 -0800 Subject: [PATCH 1267/1650] Use qEnvironmentVariable for QT_PLUGIN_PATHS This is required for non-ANSI paths on Windows. Change-Id: Id98140e1c2f0426cabbefffd157c4065c3bdfd40 Reviewed-by: Friedemann Kleint --- src/corelib/kernel/qcoreapplication.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index b6b4da3885..c637f0c1c9 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -2668,9 +2668,9 @@ QStringList QCoreApplication::libraryPaths() QStringList *app_libpaths = new QStringList; coreappdata()->app_libpaths.reset(app_libpaths); - const QByteArray libPathEnv = qgetenv("QT_PLUGIN_PATH"); + QString libPathEnv = qEnvironmentVariable("QT_PLUGIN_PATH"); if (!libPathEnv.isEmpty()) { - QStringList paths = QFile::decodeName(libPathEnv).split(QDir::listSeparator(), QString::SkipEmptyParts); + QStringList paths = libPathEnv.split(QDir::listSeparator(), QString::SkipEmptyParts); for (QStringList::const_iterator it = paths.constBegin(); it != paths.constEnd(); ++it) { QString canonicalPath = QDir(*it).canonicalPath(); if (!canonicalPath.isEmpty() From 96404f7ac89244c944adaa7533c6292e7a614311 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 2 Feb 2019 08:00:15 -0800 Subject: [PATCH 1268/1650] Doc: update the note about nested deleteLater() If you enter a nested event loop, cause a deleteLater(), exit that event loop, then enter a new one, the nesting count will be the same so those are legitimate targets for deletion. Task-number: QTBUG-73432 Change-Id: Id98140e1c2f0426cabbefffd157f975b5e291ccd Reviewed-by: Paul Wicking Reviewed-by: Thiago Macieira --- src/corelib/kernel/qobject.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index b4e885e407..cf838b6947 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -2171,8 +2171,10 @@ void QObject::removeEventFilter(QObject *obj) Note that entering and leaving a new event loop (e.g., by opening a modal dialog) will \e not perform the deferred deletion; for the object to be - deleted, the control must return to the event loop from which - deleteLater() was called. + deleted, the control must return to the event loop from which deleteLater() + was called. This does not apply to objects deleted while a previous, nested + event loop was still running: the Qt event loop will delete those objects + as soon as the new nested event loop starts. \b{Note:} It is safe to call this function more than once; when the first deferred deletion event is delivered, any pending events for the From 16cb578a8d102f1c937dcc3a07b88b24c9ed685a Mon Sep 17 00:00:00 2001 From: Dominik Haumann Date: Tue, 26 Feb 2019 21:30:48 +0100 Subject: [PATCH 1269/1650] QSyntaxHighlighter: Fix crash when parent is a nullptr QSyntaxHighlighter has the follwoing constructor taking a QObject QSyntaxHighlighter::QSyntaxHighlighter(QObject *parent) : QObject(*new QSyntaxHighlighterPrivate, parent) { if (parent->inherits("QTextEdit")) { // ... } } Typically, a 'parent' refers to the parent/child hierarchy in Qt and is allowed to be a nullptr. However, in this case, passing a nullptr will lead to a crash, as reported in https://bugs.kde.org/show_bug.cgi?id=404820 This patch makes the QSyntaxHighlighter constructor nullptr safe by checking if parent is a valid pointer. Change-Id: Ia4e9b46b94fd37e6ceb2cd0538594353fdc1e349 Reviewed-by: Jesus Fernandez Reviewed-by: Christoph Cullmann --- src/gui/text/qsyntaxhighlighter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/qsyntaxhighlighter.cpp b/src/gui/text/qsyntaxhighlighter.cpp index 0e07b69868..102a776ed3 100644 --- a/src/gui/text/qsyntaxhighlighter.cpp +++ b/src/gui/text/qsyntaxhighlighter.cpp @@ -297,7 +297,7 @@ void QSyntaxHighlighterPrivate::reformatBlock(const QTextBlock &block) QSyntaxHighlighter::QSyntaxHighlighter(QObject *parent) : QObject(*new QSyntaxHighlighterPrivate, parent) { - if (parent->inherits("QTextEdit")) { + if (parent && parent->inherits("QTextEdit")) { QTextDocument *doc = parent->property("document").value(); if (doc) setDocument(doc); From 2c31516a1eb05597a5c7474448b7b413f5dc34c5 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 25 Feb 2019 15:58:22 +0100 Subject: [PATCH 1270/1650] Windows QPA: Fix override cursor when modal window is present Handle WM_SETCURSOR to apply override cursors to window that do not have mouse capture (as is done in Qt 4). Fixes: QTBUG-58590 Change-Id: I7ff6f799da1b8d4b4396c0a6137778a11a192617 Reviewed-by: Oliver Wolff Reviewed-by: Andre de la Rocha --- src/plugins/platforms/windows/qwindowscontext.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 41655dbd57..80517ffe69 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -1099,6 +1099,12 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, return false; case QtWindows::ClipboardEvent: return false; + case QtWindows::CursorEvent: // Sent to windows that do not have capture (see QTBUG-58590). + if (QWindowsCursor::hasOverrideCursor()) { + QWindowsCursor::enforceOverrideCursor(); + return true; + } + break; case QtWindows::UnknownEvent: return false; case QtWindows::AccessibleObjectFromWindowRequest: From 49ef377349ba4dae840c2d5caa36e2d516707baa Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 20 Feb 2019 09:47:27 +0100 Subject: [PATCH 1271/1650] Fix determination of OpenGL include paths on macOS, take 2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The sysrootification of OpenGL include paths must be done only once: at configure time. The resolved paths are stored since 521a8539 and must not be resolved again. Turn the makeSpec-type opengl library into a custom-type one, and do the sysrootification in the handler function. Fixes: QTBUG-73736 Change-Id: I2933144057d6f01d8bfc7bda2c2df56c57303459 Reviewed-by: Edward Welbourne Reviewed-by: Eirik Aavitsland Reviewed-by: Tor Arne Vestbø --- mkspecs/common/mac.conf | 2 +- mkspecs/features/mac/sdk.prf | 4 ---- src/gui/configure.json | 2 +- src/gui/configure.pri | 11 +++++++++++ 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/mkspecs/common/mac.conf b/mkspecs/common/mac.conf index b77494ec9b..f21ba5ec51 100644 --- a/mkspecs/common/mac.conf +++ b/mkspecs/common/mac.conf @@ -17,7 +17,7 @@ QMAKE_EXTENSION_SHLIB = dylib QMAKE_EXTENSIONS_AUX_SHLIB = tbd QMAKE_LIBDIR = -# sdk.prf will prefix the proper SDK sysroot +# qtConfLibrary_openglMakeSpec will prefix the proper SDK sysroot QMAKE_INCDIR_OPENGL = \ /System/Library/Frameworks/OpenGL.framework/Headers \ /System/Library/Frameworks/AGL.framework/Headers/ diff --git a/mkspecs/features/mac/sdk.prf b/mkspecs/features/mac/sdk.prf index 8360dd8b38..50a41657d8 100644 --- a/mkspecs/features/mac/sdk.prf +++ b/mkspecs/features/mac/sdk.prf @@ -33,10 +33,6 @@ QMAKE_MAC_SDK_PATH = $$xcodeSDKInfo(Path) QMAKE_MAC_SDK_PLATFORM_PATH = $$xcodeSDKInfo(PlatformPath) QMAKE_MAC_SDK_VERSION = $$xcodeSDKInfo(SDKVersion) -sysrootified = -for(val, QMAKE_INCDIR_OPENGL): sysrootified += $${QMAKE_MAC_SDK_PATH}$$val -QMAKE_INCDIR_OPENGL = $$sysrootified - QMAKESPEC_NAME = $$basename(QMAKESPEC) # Resolve SDK version of various tools diff --git a/src/gui/configure.json b/src/gui/configure.json index 44140bc7b6..e4f25ab313 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -448,7 +448,7 @@ ], "sources": [ { "type": "pkgConfig", "args": "gl", "condition": "!config.darwin" }, - { "type": "makeSpec", "spec": "OPENGL" } + { "type": "openglMakeSpec" } ] }, "opengl_es2": { diff --git a/src/gui/configure.pri b/src/gui/configure.pri index 1b95449a10..0db106597e 100644 --- a/src/gui/configure.pri +++ b/src/gui/configure.pri @@ -15,6 +15,17 @@ defineTest(qtConfLibrary_freetype) { return(true) } +defineTest(qtConfLibrary_openglMakeSpec) { + darwin:sdk { + sysrootified = + for(val, QMAKE_INCDIR_OPENGL): sysrootified += $${QMAKE_MAC_SDK_PATH}$$val + QMAKE_INCDIR_OPENGL = $$sysrootified + } + $${1}.spec = OPENGL + !qtConfLibrary_makeSpec($$1, $$2): return(false) + return(true) +} + # Check for Direct X shader compiler 'fxc'. # Up to Direct X SDK June 2010 and for MinGW, this is pointed to by the # DXSDK_DIR variable. Starting with Windows Kit 8, it is included in From d8cf721d60b488c1966e0ae224b669a9fc9f3e42 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 20 Feb 2019 13:25:33 +0100 Subject: [PATCH 1272/1650] Update the DNS public suffix list from publicsuffix.org Regular update in preparation for 5.13, adding tests for additions since 5.9.4/5.10.1/5.11.0's update 7e946030 (the last to record its upstream version sha1). Corrected the license header: it's now published under MPL 2.0 (not 1.1); and our secondary licensing of it is as LGPL3. Deferred full header over-haul until we've worked one out in detail. [ChangeLog][Third-Party Code] Updated DNS public suffix list Task-number: QTBUG-72623 Change-Id: Iabdbbbfd79624830396c2a6fe0a73389bd6ce5b7 Reviewed-by: Kai Koehne Reviewed-by: Qt CI Bot --- src/corelib/io/qt_attribution.json | 2 +- src/corelib/io/qurltlds_p.h | 27393 +++++++++++----------- tests/auto/corelib/io/qurl/tst_qurl.cpp | 15 + 3 files changed, 13729 insertions(+), 13681 deletions(-) diff --git a/src/corelib/io/qt_attribution.json b/src/corelib/io/qt_attribution.json index c52df67d98..9b7dcc6b54 100644 --- a/src/corelib/io/qt_attribution.json +++ b/src/corelib/io/qt_attribution.json @@ -20,7 +20,7 @@ supported by Qt (by the QNetworkCookieJar class).", "Homepage": "Consult https://github.com/publicsuffix/list for the sha1 but download from ...", "Homepage": "http://publicsuffix.org/", - "Version": "Generated on 2018-01-04", + "Version": "d6331e2b65fffbe9fe299dae1689db8de8fd6190, fetched on 2019-02-20", "License": "Mozilla Public License 2.0", "LicenseFile": "PSL-LICENSE.txt", "LicenseId": "MPL-2.0", diff --git a/src/corelib/io/qurltlds_p.h b/src/corelib/io/qurltlds_p.h index 5453644225..043e84e5ab 100644 --- a/src/corelib/io/qurltlds_p.h +++ b/src/corelib/io/qurltlds_p.h @@ -1,7 +1,7 @@ -// Version: MPL 1.1/GPL 2.0/LGPL 2.1 +// License: MPL 2.0/GPL 2.0/LGPL 3 // // The contents of this file are subject to the Mozilla Public License Version -// 1.1 (the "License"); you may not use this file except in compliance with +// 2.0 (the "License"); you may not use this file except in compliance with // the License. You may obtain a copy of the License at // http://www.mozilla.org/MPL/ // @@ -59,14106 +59,14139 @@ QT_BEGIN_NAMESPACE // note to maintainer: // this file should be updated before each release -> // for instructions see the program at -// util/corelib/qurl-generateTLDs +// util/corelib/qurl-generateTLDs/ -static const quint16 tldCount = 8621; +static const quint16 tldCount = 8666; static const quint32 tldIndices[] = { 0, -0, -26, -26, -26, -26, -40, -40, -54, -54, -54, -59, +7, +24, +31, +58, 65, -75, -75, -109, -117, -132, -149, -149, -149, -159, -166, -193, -193, -235, -235, -235, -241, -276, -282, -287, -309, -339, -349, -349, -390, -402, -420, -452, -468, -489, -489, -503, -508, -531, -551, -551, -574, -605, -605, -605, -615, -615, -615, -633, -655, -661, -661, -684, -702, -714, -736, +79, +103, +137, +137, +158, +194, +220, +255, +255, +298, +298, +298, +298, +298, +311, +311, +311, +311, +323, +359, +383, +383, +400, +400, +421, +421, +441, +441, +448, +490, +490, +497, +502, +520, +542, +549, +597, +611, +611, +635, +642, +649, +668, +683, +683, +683, +700, +705, +712, +724, +724, +740, 765, 765, 776, -794, -826, -847, -866, -866, -882, -895, -901, -960, -994, -994, -1012, -1012, -1012, -1032, -1048, -1048, -1068, -1090, -1090, -1090, -1101, -1114, -1114, -1133, -1133, -1140, -1140, -1147, -1147, -1156, -1163, -1163, -1163, -1173, -1185, -1185, -1201, -1201, -1208, -1225, -1230, -1285, -1316, -1374, -1394, -1417, -1417, -1417, -1424, -1438, -1476, -1532, -1549, -1556, -1563, -1570, -1590, -1590, -1597, -1604, -1617, -1617, -1629, -1629, -1641, -1648, -1662, -1662, -1680, -1706, -1722, +787, +802, +810, +820, +841, +848, +848, +858, +858, +864, +871, +871, +871, +881, +898, +930, +958, +972, +985, +999, +1006, +1013, +1030, +1056, +1063, +1086, +1086, +1086, +1093, +1100, +1107, +1117, +1117, +1117, +1117, +1128, +1153, +1153, +1180, +1186, +1186, +1193, +1221, +1239, +1239, +1252, +1279, +1286, +1286, +1293, +1307, +1325, +1348, +1348, +1348, +1355, +1355, +1355, +1355, +1373, +1395, +1395, +1413, +1440, +1440, +1440, +1440, +1447, +1457, +1464, +1498, +1498, +1498, +1572, +1606, +1613, +1613, +1613, +1620, +1625, +1632, +1651, +1658, +1672, +1688, +1704, +1712, +1712, 1729, -1745, -1745, +1751, 1757, -1779, -1779, -1786, -1835, +1771, +1787, +1831, +1831, +1831, +1831, 1848, -1848, -1875, -1895, -1895, -1923, -1943, -1943, -1950, -2004, -2023, -2023, -2030, -2051, -2068, -2083, -2100, +1919, +1926, +1926, +1926, +1949, +1961, +1961, +1981, +2001, +2001, +2001, +2009, +2028, +2028, +2035, +2054, +2054, +2077, 2107, -2142, -2155, -2155, -2155, -2162, -2174, -2174, -2174, +2121, +2137, +2157, 2196, 2196, -2218, -2254, -2281, -2287, -2303, -2313, -2313, -2313, -2333, -2354, -2367, -2367, -2367, -2420, -2442, -2460, -2483, -2494, -2513, -2521, -2521, -2538, -2545, -2555, -2583, -2610, -2610, -2617, -2631, -2638, +2217, +2235, +2235, +2243, +2243, +2259, +2259, +2283, +2290, +2290, +2316, +2329, +2356, +2356, +2356, +2356, +2356, +2393, +2414, +2428, +2428, +2440, +2481, +2487, +2487, +2487, +2507, +2507, +2507, +2546, +2562, +2562, +2580, +2607, +2614, +2626, 2649, -2661, -2661, -2668, -2699, -2705, -2705, -2705, -2712, +2649, +2665, +2675, +2682, 2721, +2731, 2737, -2749, -2768, -2775, -2792, -2815, -2825, -2841, -2841, -2868, -2868, -2905, -2905, -2934, -2957, -2957, -2975, -3005, -3012, -3037, -3046, -3046, -3053, -3053, -3066, -3073, -3083, -3083, -3105, -3123, -3123, -3181, -3226, -3245, -3245, -3301, -3323, -3332, -3360, -3370, -3370, -3370, -3380, -3380, -3387, -3387, -3394, -3394, -3394, -3402, -3409, -3416, -3431, -3448, +2765, +2770, +2770, +2803, +2803, +2813, +2833, +2855, +2855, +2855, +2863, +2863, +2863, +2880, +2888, +2896, +2896, +2903, +2903, +2910, +2910, +2928, +2928, +2935, +2999, +2999, +3031, +3031, +3050, +3100, +3141, +3141, +3141, +3147, +3185, +3185, +3197, +3197, +3234, +3241, +3248, +3257, +3272, +3272, +3272, +3309, +3328, +3328, +3346, +3356, +3356, +3356, +3356, +3364, +3392, +3392, +3413, +3441, +3465, +3465, +3465, +3465, +3482, +3482, +3487, +3487, +3487, +3487, +3487, +3497, +3497, +3510, +3510, 3519, -3543, -3569, -3607, -3607, -3613, -3625, -3625, -3682, -3689, -3696, -3734, -3750, -3750, -3760, -3760, -3769, -3786, -3786, -3786, -3793, -3809, -3816, -3822, -3829, -3829, -3836, -3852, -3852, -3867, -3874, -3892, -3892, -3902, -3935, -3960, -3980, -4005, -4019, -4032, -4059, -4089, -4089, -4122, -4122, -4151, -4151, -4151, -4151, -4158, -4158, -4158, -4158, -4158, -4158, -4158, -4173, -4191, -4200, -4200, -4224, -4232, -4265, -4281, -4288, -4309, -4348, -4370, -4377, -4396, -4396, -4403, -4403, -4419, -4439, -4446, -4462, -4469, -4469, -4469, -4476, -4483, -4511, -4518, +3519, +3519, +3519, +3519, +3519, +3530, +3530, +3541, +3568, +3568, +3568, +3586, +3586, +3606, +3627, +3637, +3637, +3645, +3667, +3667, +3708, +3721, +3740, +3762, +3762, +3762, +3762, +3762, +3762, +3775, +3775, +3790, +3812, +3812, +3818, +3818, +3834, +3845, +3881, +3904, +3904, +3910, +3937, +3937, +3937, +3943, +3950, +3950, +3969, +3999, +4017, +4017, +4017, +4017, +4033, +4033, +4033, +4033, +4098, +4135, +4159, +4159, +4159, +4159, +4159, +4169, +4189, +4205, +4239, +4261, +4261, +4261, +4261, +4261, +4261, +4278, +4278, +4293, +4308, +4317, +4336, +4343, +4371, +4371, +4376, +4376, +4376, +4399, +4409, +4424, +4451, +4473, +4473, +4473, +4489, +4489, +4526, +4532, +4532, 4538, -4563, -4580, -4580, -4587, -4608, -4608, -4624, -4640, -4664, -4664, -4664, -4680, -4690, -4699, -4707, -4707, -4707, -4717, -4717, -4741, -4741, -4741, -4741, -4766, -4778, -4778, -4794, -4801, -4834, -4854, -4867, -4874, -4874, -4888, -4888, -4888, -4936, -4942, -4963, -5001, -5008, -5008, -5008, -5008, -5008, -5017, -5024, -5062, -5069, -5074, -5095, -5139, -5146, -5156, -5175, -5182, -5193, +4570, +4570, +4570, +4613, +4632, +4643, +4688, +4688, +4726, +4771, +4783, +4799, +4799, +4865, +4865, +4865, +4885, +4909, +4909, +4926, +4926, +4956, +4994, +5010, +5010, +5020, +5041, +5056, +5075, +5092, +5122, +5122, +5122, +5122, +5130, +5157, +5164, +5177, +5194, 5200, -5212, -5225, -5238, -5261, -5268, -5298, -5298, -5305, -5305, -5315, -5315, -5329, -5329, -5349, -5363, -5363, -5399, -5399, -5418, -5445, -5466, +5200, +5211, +5224, +5241, +5241, +5273, +5273, +5273, +5294, +5294, +5294, +5343, +5343, +5350, +5386, +5396, +5403, +5417, +5449, +5463, +5463, +5480, 5490, -5505, -5505, -5505, -5530, -5530, -5546, -5546, -5582, -5610, -5610, -5634, -5676, -5676, -5722, -5735, -5774, -5774, -5828, -5828, -5828, -5828, -5851, -5881, -5894, -5894, -5901, -5901, -5906, -5906, +5541, +5591, +5597, +5604, +5604, +5625, +5639, +5649, +5649, +5649, +5666, +5685, +5705, +5705, +5705, +5723, +5772, +5783, +5790, +5804, +5837, +5878, +5915, +5915, +5915, 5937, -5937, -5950, -5950, -5950, -5956, -5956, -5956, -5998, -5998, -6030, -6055, -6074, -6090, -6090, -6103, -6103, -6155, -6177, -6207, +5984, +5989, +5989, +5989, +6006, +6051, +6051, +6073, +6080, +6080, +6089, +6100, +6149, +6164, +6169, 6207, 6214, -6214, -6226, -6244, -6266, +6242, +6278, +6284, +6290, 6303, -6303, -6330, -6330, -6344, -6360, -6387, -6410, -6410, -6410, -6410, -6438, -6451, -6451, -6451, -6465, +6326, +6383, +6399, +6416, +6416, +6437, +6444, +6457, +6463, +6463, 6477, -6477, -6477, -6484, -6500, -6500, -6519, -6519, -6530, -6548, -6567, -6567, -6567, -6586, -6604, +6520, +6535, +6555, +6555, +6555, +6555, +6603, 6652, 6652, -6672, -6683, -6716, -6716, -6727, -6727, -6727, -6727, -6727, -6747, -6747, -6781, -6781, -6791, -6821, -6821, -6827, -6827, -6843, +6670, +6691, +6698, +6698, +6712, +6712, +6719, +6719, +6726, +6739, +6778, +6778, +6797, +6797, +6807, +6807, +6830, +6830, +6842, +6865, +6865, +6865, 6869, -6877, -6877, -6877, -6877, -6896, -6896, -6903, -6919, -6919, -6919, -6935, -6935, -6935, -6935, -6935, -6935, -6935, -6966, -6983, -6983, -6999, -6999, -6999, -7013, -7022, -7022, -7022, -7022, -7022, -7022, -7070, -7085, -7105, -7105, -7122, -7139, -7148, -7162, -7162, -7172, -7172, -7210, -7210, -7230, -7242, -7242, -7249, -7259, -7259, -7279, -7279, -7294, -7311, -7317, -7353, -7369, -7375, -7395, -7395, -7431, -7496, -7496, -7505, -7505, -7505, -7505, -7511, -7539, -7551, +6875, +6888, +6888, +6888, +6910, +6926, +6933, +6944, +6964, +6980, +6980, +7024, +7024, +7024, +7024, +7036, +7058, +7068, +7068, +7083, +7087, +7109, +7117, +7124, +7143, +7159, +7194, +7194, +7194, +7201, +7208, +7224, +7231, +7262, +7309, +7323, +7352, +7352, +7359, +7366, +7366, +7381, +7381, +7412, +7412, +7449, +7459, +7459, +7487, +7487, +7487, +7487, +7527, +7545, +7559, +7559, +7559, +7559, +7559, +7564, 7564, -7583, 7595, -7595, -7595, -7628, -7628, -7628, -7665, -7674, -7686, -7711, -7737, -7755, -7755, -7794, -7805, -7811, -7811, -7831, -7831, -7850, -7850, -7858, -7874, -7879, -7903, -7923, -7958, -7958, -7972, -7987, -7987, -7998, -8008, -8008, -8042, -8042, -8059, -8059, -8076, -8096, -8096, -8096, -8114, -8114, -8132, -8132, -8148, -8163, -8175, -8194, -8194, -8205, -8214, -8218, -8246, -8246, -8246, -8286, -8286, -8286, -8286, -8286, +7602, +7626, +7643, +7655, +7655, +7682, +7701, +7725, +7736, +7751, +7765, +7832, +7852, +7906, +7965, +7965, +7976, +7976, +8024, +8041, +8058, +8071, +8084, +8105, +8105, +8115, +8144, +8160, +8182, +8210, +8216, +8229, +8229, +8234, +8282, +8282, +8282, +8289, 8305, 8312, 8312, 8312, 8312, -8335, -8357, -8357, -8366, -8382, -8390, -8394, -8394, -8407, -8414, -8446, -8453, -8466, -8466, -8500, -8500, -8522, +8319, +8363, +8401, +8408, +8415, +8415, +8425, +8454, +8464, +8464, +8482, +8505, 8542, -8554, -8577, -8588, -8608, -8614, -8621, -8652, -8675, -8675, -8687, -8687, -8712, -8712, -8734, -8744, -8798, -8808, -8827, -8827, -8827, +8542, +8557, +8603, +8629, +8629, +8643, +8643, +8667, +8690, +8690, +8714, +8721, +8721, +8726, +8746, +8766, +8783, +8790, +8804, +8833, 8840, -8855, -8855, -8880, -8880, -8897, -8897, -8897, -8930, -8968, -8968, -8968, -8968, -8992, -9055, +8863, +8870, +8884, +8934, +8956, +8956, +8956, +8956, +8965, +8991, +8991, +8997, +9007, +9007, +9013, +9031, +9031, +9038, +9059, +9066, 9073, -9085, -9094, +9090, +9105, +9109, 9116, -9116, -9145, -9164, -9175, -9187, -9214, -9214, -9226, -9242, -9272, -9291, -9305, -9324, -9324, -9324, -9324, -9331, -9368, -9374, -9393, -9415, -9415, -9415, -9428, -9428, -9434, -9451, -9451, -9451, -9486, -9486, -9486, -9486, -9503, -9503, -9503, -9509, -9509, -9541, -9548, -9548, -9548, -9597, -9597, -9604, -9619, -9646, -9657, -9664, -9701, -9730, -9737, -9743, -9755, -9774, -9795, -9802, -9816, -9816, -9824, -9847, -9865, -9865, +9120, +9120, +9178, +9233, +9241, +9259, +9275, +9275, +9275, +9292, +9299, +9299, +9318, +9332, +9351, +9358, +9400, +9422, +9497, +9513, +9517, +9517, +9530, +9537, +9552, +9592, +9592, +9608, +9627, +9643, +9643, +9643, +9653, +9653, +9683, +9691, +9723, +9733, +9758, +9762, +9762, +9762, +9842, +9842, +9871, +9871, 9890, 9904, 9911, -9931, -9955, +9918, +9932, +9949, 9969, -10008, -10015, -10032, -10032, -10039, -10046, -10065, -10065, -10113, -10120, -10128, -10135, -10142, -10142, -10167, -10178, -10198, -10232, -10251, -10307, -10325, -10325, -10325, -10332, -10338, -10360, -10372, -10379, -10412, -10443, -10443, -10460, -10468, -10490, -10490, -10500, -10519, -10534, -10541, -10574, -10598, -10633, -10653, -10673, -10694, -10694, -10694, +10000, +10024, +10024, +10055, +10055, +10082, +10098, +10098, +10126, +10126, +10138, +10138, +10147, +10174, +10174, +10174, +10174, +10196, +10203, +10210, +10210, +10210, +10233, +10245, +10252, +10252, +10282, +10289, +10300, +10346, +10369, +10375, +10402, +10402, +10402, +10402, +10423, +10444, +10453, +10473, +10497, +10503, +10513, +10531, +10579, +10595, +10602, +10602, +10602, +10627, +10648, +10659, +10659, +10674, +10674, +10681, 10706, 10706, -10715, -10725, -10725, -10736, -10743, -10750, -10782, -10798, -10814, -10833, -10833, -10848, -10858, -10858, -10858, -10863, +10722, +10760, +10760, +10772, +10785, +10785, +10785, +10796, +10815, +10836, +10836, +10844, 10875, -10900, -10907, -10930, -10961, -10989, -11020, -11068, -11075, -11082, -11114, -11131, -11156, -11176, -11184, -11212, -11218, -11235, -11235, -11247, -11247, -11254, -11265, -11269, -11304, -11311, -11340, -11340, -11354, -11384, -11384, -11409, -11409, -11422, -11439, -11449, -11449, -11462, -11469, -11469, -11477, -11488, -11488, -11502, -11522, -11589, -11628, -11657, -11670, -11670, +10875, +10875, +10875, +10885, +10885, +10892, +10892, +10892, +10892, +10920, +10920, +10963, +10963, +10963, +10970, +10977, +11007, +11007, +11007, +11007, +11007, +11031, +11041, +11051, +11070, +11078, +11078, +11078, +11091, +11101, +11101, +11123, +11129, +11139, +11155, +11191, +11233, +11233, +11233, +11244, +11244, +11256, +11262, +11262, +11262, +11262, +11278, +11285, +11285, +11314, +11335, +11341, +11359, +11359, +11387, +11401, +11408, +11442, +11442, +11463, +11463, +11470, +11492, +11492, +11492, +11492, +11503, +11537, +11547, +11572, +11572, +11591, +11610, +11610, +11618, +11636, +11652, +11652, +11652, +11675, +11675, +11675, +11675, 11699, -11706, -11723, -11723, -11763, -11763, -11763, -11790, -11825, -11844, -11875, -11875, -11891, -11891, -11898, -11898, -11898, -11898, -11898, -11911, -11911, -11932, -11939, -11939, -11946, -11946, -11957, -11957, -11964, -11988, -11995, -12047, -12110, -12117, -12124, -12131, -12131, -12147, -12173, -12192, -12228, -12235, -12252, -12252, -12284, -12284, -12299, -12299, -12312, -12336, -12343, -12367, -12374, -12400, -12417, -12417, -12437, -12437, -12444, -12479, -12513, -12527, -12541, -12541, -12564, -12607, -12614, -12625, -12632, -12670, -12698, -12739, -12753, -12760, -12791, -12791, -12791, -12791, -12818, -12818, -12818, -12839, -12851, -12851, -12851, -12861, +11710, +11710, +11738, +11748, +11748, +11748, +11768, +11768, +11768, +11768, +11768, +11778, +11778, +11788, +11812, +11820, +11820, +11835, +11852, +11872, +11872, +11929, +11929, +11933, +11952, +11962, +11962, +11979, +11979, +11979, +11992, +11999, +12014, +12014, +12023, +12023, +12023, +12023, +12023, +12023, +12041, +12041, +12066, +12066, +12076, +12076, +12076, +12076, +12087, +12099, +12114, +12137, +12137, +12146, +12166, +12175, +12185, +12201, +12220, +12239, +12253, +12291, +12304, +12304, +12315, +12323, +12342, +12342, +12351, +12357, +12361, +12381, +12381, +12397, +12424, +12452, +12475, +12481, +12481, +12481, +12485, +12502, +12535, +12535, +12552, +12566, +12570, +12601, +12605, +12605, +12611, +12623, +12633, +12633, +12642, +12642, +12642, +12642, +12646, +12656, +12656, +12656, +12656, +12677, +12677, +12714, +12720, +12734, +12734, +12734, +12751, +12774, +12794, +12806, +12806, +12819, +12819, +12819, +12819, +12836, +12836, 12877, -12899, -12899, -12906, -12906, -12918, -12925, -12925, -12925, -12925, -12945, -12949, -12968, -12968, -12980, -12996, -12996, -13003, -13030, -13037, -13044, -13080, -13084, -13137, -13156, -13175, -13197, -13213, -13220, -13227, -13227, -13245, -13245, -13245, -13262, -13277, -13304, -13311, -13311, -13319, -13319, -13319, -13324, -13324, -13324, -13324, -13335, -13342, -13342, -13347, -13378, -13390, -13408, -13413, -13413, -13413, -13420, +12877, +12877, +12893, +12909, +12936, +12936, +12936, +12936, +12950, +12950, +12950, +12950, +12969, +12974, +13000, +13000, +13028, +13034, +13051, +13051, +13051, +13051, +13051, +13067, +13067, +13071, +13071, +13087, +13113, +13164, +13204, +13204, +13211, +13226, +13226, +13230, +13230, +13260, +13276, +13301, +13332, +13340, +13357, +13357, +13357, +13374, +13397, +13410, 13433, -13440, -13447, -13466, -13511, -13525, -13537, -13555, -13600, -13600, -13618, -13629, -13636, -13636, -13679, -13686, -13725, -13757, -13757, -13800, -13826, -13836, -13847, -13867, -13867, -13882, -13911, -13925, -13925, -13942, -13954, -13991, -14001, -14016, -14057, -14073, -14095, -14095, -14104, -14118, -14124, -14124, -14130, -14156, -14156, -14179, -14201, -14201, +13445, +13481, +13503, +13532, +13532, +13584, +13602, +13622, +13650, +13675, +13682, +13682, +13701, +13710, +13721, +13721, +13735, +13735, +13771, +13777, +13797, +13817, +13817, +13817, +13837, +13837, +13842, +13861, +13892, +13892, +13937, +13955, +13994, +13994, +13994, +14023, +14035, +14042, +14052, +14052, +14052, +14074, +14074, +14074, +14074, +14074, +14082, +14116, +14123, +14160, +14174, +14191, +14197, +14197, 14205, 14205, -14209, -14216, -14224, -14231, -14249, -14253, +14205, +14205, +14205, +14243, +14256, +14256, +14256, +14256, +14256, 14291, -14338, -14366, +14291, +14291, +14302, +14302, +14316, +14330, +14330, 14370, -14375, -14407, -14427, -14427, -14434, -14447, -14463, -14473, -14473, -14484, -14484, -14501, -14501, -14501, -14510, -14529, -14543, -14543, -14555, -14559, -14585, -14585, -14601, -14614, -14618, +14370, +14370, +14370, +14387, +14399, +14433, +14441, +14458, +14458, +14458, +14458, +14458, +14458, +14476, +14514, +14527, +14527, +14537, +14560, +14590, +14590, +14590, +14590, 14622, -14642, -14711, -14711, -14730, -14730, -14730, -14730, -14743, -14764, -14764, -14782, -14817, -14829, -14829, -14829, -14835, -14839, -14839, -14839, -14839, -14851, -14859, -14859, +14622, +14648, +14648, +14648, +14656, +14667, +14687, +14705, +14705, +14705, +14705, +14718, +14733, +14759, +14766, +14795, +14795, +14795, +14795, +14801, +14801, +14824, +14832, +14832, +14832, +14832, +14832, +14848, +14860, +14870, 14888, -14888, -14888, -14888, -14927, -14939, -14951, -14951, -14971, +14934, +14952, +14959, +14977, +14977, +14994, +14994, 15007, 15007, -15018, -15034, -15034, +15007, +15007, +15017, 15045, -15045, -15067, -15106, -15106, -15141, -15147, -15163, -15195, -15195, -15209, -15209, -15216, -15216, -15224, -15224, -15224, -15243, -15243, -15243, -15253, -15285, -15285, -15306, -15324, -15382, -15403, -15403, -15407, -15407, -15435, -15435, -15468, -15472, -15499, -15516, -15516, +15052, +15062, +15072, +15094, +15101, +15101, +15125, +15125, +15133, +15140, +15164, +15183, +15201, +15201, +15207, +15211, +15228, +15228, +15242, +15251, +15260, +15260, +15266, +15266, +15266, +15290, +15290, +15290, +15290, +15303, +15317, +15317, +15317, +15323, +15323, +15330, +15343, +15383, +15390, +15390, +15397, +15397, +15397, +15412, +15420, +15427, +15451, +15467, +15467, +15503, +15509, 15528, -15533, -15533, -15538, -15538, -15550, -15568, -15579, +15528, +15537, +15537, +15537, +15542, +15542, +15542, +15558, +15558, +15558, +15580, +15580, +15580, 15603, -15603, -15611, -15621, -15621, -15621, -15621, -15631, -15647, -15655, -15655, -15655, -15655, -15655, -15707, -15707, -15713, -15713, -15733, -15774, -15774, -15784, -15784, -15784, -15784, -15784, -15795, -15795, -15800, -15800, -15800, -15825, -15825, -15825, -15857, -15884, -15884, -15884, -15884, -15884, -15903, -15922, -15937, -15937, +15615, +15615, +15615, +15657, +15690, +15712, +15741, +15741, +15757, +15757, +15792, +15792, +15819, +15819, +15839, +15860, +15867, +15874, +15888, +15888, +15900, +15913, +15927, +15938, +15938, +15956, +15971, +15993, +15993, +15993, +15993, 15997, -16004, -16019, -16065, -16065, -16065, -16086, -16100, -16112, -16112, -16129, -16138, -16138, -16138, -16153, -16169, +16020, +16020, +16033, +16033, +16033, +16069, +16069, +16097, +16109, +16109, +16109, +16145, +16145, +16145, 16186, -16186, -16228, -16228, -16228, -16259, -16270, -16306, -16316, -16322, -16322, -16383, -16393, -16393, -16423, -16423, -16423, -16433, -16448, -16448, -16472, -16472, -16477, -16487, -16528, -16537, -16547, -16552, -16574, +16230, +16250, +16269, +16276, +16283, +16295, +16329, +16359, +16391, +16404, +16404, +16453, +16470, +16480, +16480, +16480, +16499, +16512, +16530, +16530, +16541, +16541, +16563, 16579, +16586, 16596, -16603, -16651, -16686, -16686, -16686, -16703, -16703, -16753, -16753, -16753, -16767, -16767, +16618, +16633, +16665, +16665, +16690, +16721, +16733, +16733, +16740, +16762, +16762, +16762, +16762, +16762, +16762, +16762, +16762, +16777, +16777, 16784, -16825, -16832, -16843, -16843, +16812, +16830, 16851, -16862, -16879, -16898, -16898, -16917, -16917, -16924, -16932, -16970, -17008, -17016, -17034, -17034, -17034, -17034, -17063, -17098, -17127, -17142, -17142, -17160, -17160, -17160, -17160, -17186, -17213, -17240, -17254, -17259, -17259, -17259, +16870, +16870, +16901, +16908, +16908, +16908, +16929, +16953, +16953, +16959, +16959, +16986, +16986, +16986, +16996, +16996, +16996, +16996, +17010, +17030, +17050, +17057, +17057, +17057, +17057, +17066, +17076, +17093, +17093, +17122, +17122, +17138, +17138, +17157, +17164, +17179, +17179, +17198, +17198, +17218, +17236, +17236, +17266, +17283, 17294, -17350, -17376, -17414, -17443, -17459, -17459, -17477, -17482, -17495, -17508, -17508, -17515, -17521, -17544, -17544, -17544, -17544, -17550, -17573, -17580, -17587, -17631, -17673, -17673, -17691, -17733, -17743, -17762, -17762, -17771, -17771, -17771, -17780, -17807, -17807, -17840, -17847, -17847, -17855, -17867, -17883, -17900, -17900, -17924, -17964, -17964, -17970, -17970, -17998, -18006, -18006, -18006, -18006, -18006, -18035, -18084, -18110, -18110, -18127, -18135, -18167, -18167, -18203, -18203, -18208, -18208, -18238, -18238, -18255, -18267, -18267, -18298, -18314, -18344, -18344, -18352, -18352, -18352, -18352, -18392, -18398, -18437, -18437, -18449, -18463, -18497, -18497, -18546, -18553, -18566, -18616, -18647, -18647, -18663, -18663, -18663, -18696, -18730, -18749, -18749, -18759, -18771, -18771, +17294, +17294, +17311, +17321, +17336, +17336, +17336, +17336, +17336, +17347, +17353, +17353, +17353, +17353, +17361, +17361, +17361, +17361, +17374, +17374, +17374, +17388, +17388, +17388, +17395, +17411, +17411, +17411, +17428, +17440, +17457, +17471, +17492, +17492, +17529, +17533, +17546, +17546, +17558, +17566, +17566, +17566, +17578, +17604, +17620, +17650, +17650, +17669, +17695, +17695, +17741, +17741, +17741, +17769, +17774, +17774, +17779, +17785, +17795, +17795, +17803, +17819, +17859, +17859, +17916, +17916, +17955, +17963, +17977, +17977, +18009, +18009, +18021, +18044, +18044, +18044, +18044, +18044, +18044, +18064, +18079, +18079, +18096, +18096, +18132, +18138, +18138, +18171, +18171, +18171, +18171, +18177, +18200, +18220, +18220, +18220, +18234, +18234, +18234, +18270, +18286, +18332, +18343, +18343, +18348, +18367, +18409, +18464, +18486, +18493, +18544, +18544, +18544, +18550, +18575, +18580, +18634, +18646, +18672, +18695, +18695, +18695, +18713, +18744, +18762, +18762, +18770, +18770, +18777, +18781, 18785, 18785, 18785, 18785, -18803, -18803, -18803, -18803, -18803, -18826, -18832, -18832, -18861, -18861, -18870, -18887, +18791, +18839, +18850, +18864, +18864, +18881, +18881, 18897, -18897, -18903, +18912, +18919, 18926, -18933, -18933, -18941, -18957, -18983, -19025, -19034, -19034, -19055, -19122, -19122, +18944, +18944, +18944, +18951, +18951, +18958, +18969, +18994, +19010, +19054, +19054, +19086, +19097, +19115, +19129, +19129, 19152, -19152, -19163, -19163, -19198, -19198, -19198, -19198, -19198, -19210, -19218, -19238, -19238, +19183, +19189, +19226, +19226, +19226, +19226, +19236, +19260, 19266, -19274, -19303, -19317, -19317, -19329, -19329, -19329, -19329, -19355, -19355, -19410, -19410, -19410, -19433, -19450, -19450, -19450, -19463, -19463, -19490, -19524, -19531, -19558, -19597, -19609, -19609, +19273, +19291, +19298, +19298, +19298, +19335, +19352, +19352, +19363, +19383, +19383, +19399, +19409, +19430, +19430, +19447, +19469, +19485, +19485, +19493, +19499, +19499, +19506, +19506, +19516, +19537, +19549, +19588, +19588, 19633, -19642, -19642, -19642, -19642, -19658, -19671, -19703, -19710, -19710, -19727, -19741, -19741, -19748, -19748, -19748, -19755, -19791, -19808, -19827, -19835, -19859, +19655, +19676, +19676, +19720, +19723, +19739, +19742, +19745, +19768, +19768, +19771, +19788, +19795, +19823, +19843, +19850, 19869, -19869, -19869, -19886, -19900, +19893, 19919, -19931, -19940, -19960, -19974, -19983, -20002, -20002, -20002, -20002, -20011, -20011, -20011, -20018, -20031, -20049, -20049, -20049, -20065, +19936, +19939, +19942, +19963, +19966, +19982, +19995, +20004, +20010, +20010, +20045, +20048, +20062, +20071, +20071, +20074, 20084, -20139, -20152, -20159, -20177, -20191, -20202, -20202, -20229, -20248, -20248, -20254, -20254, -20265, -20265, -20275, -20275, -20295, -20322, -20322, -20347, -20377, -20377, -20377, -20401, -20412, -20412, -20419, -20419, -20419, +20090, +20108, +20108, +20114, +20120, +20147, +20153, +20156, +20166, +20169, +20184, +20187, +20195, +20210, +20221, +20246, +20246, +20246, +20273, +20293, +20296, +20313, +20331, +20337, +20346, +20362, +20395, +20395, +20423, +20423, +20429, +20429, 20432, -20455, -20462, -20514, -20514, -20514, -20582, -20588, -20603, -20603, -20603, -20615, -20657, +20443, +20465, +20465, +20468, +20479, +20479, +20497, +20537, +20546, +20558, +20614, +20621, +20639, +20639, +20658, +20661, +20671, 20674, -20691, +20674, +20674, +20674, +20677, +20677, +20677, +20696, +20699, +20699, +20702, +20702, 20705, 20711, -20711, -20711, +20724, 20727, -20727, -20727, -20747, -20769, -20775, -20775, -20790, -20790, -20807, -20826, -20834, -20843, -20856, -20859, -20862, -20873, -20903, -20926, -20926, -20929, -20948, -20982, -21012, -21012, -21018, -21024, -21046, -21062, -21087, -21117, -21151, -21157, -21160, -21166, -21182, -21193, +20730, +20753, +20763, +20766, +20783, +20783, +20783, +20806, +20809, +20819, +20819, +20822, +20911, +20944, +20961, +20992, +21004, +21014, +21017, +21033, +21036, +21036, +21067, +21074, +21094, +21119, +21162, +21179, 21204, -21207, -21223, -21223, -21283, -21304, -21310, -21316, -21316, -21358, -21364, -21371, -21377, -21386, -21386, -21389, -21427, -21490, -21493, -21493, -21517, -21539, -21545, -21545, +21230, +21239, +21250, +21256, +21290, +21297, +21297, +21297, +21333, +21333, +21349, +21352, +21378, +21393, +21411, +21414, +21424, +21435, +21438, +21461, +21461, +21489, +21504, +21511, +21511, +21511, +21511, +21516, +21516, +21526, +21529, +21538, +21538, 21551, -21554, -21592, -21608, -21611, -21617, -21636, -21636, -21646, -21650, +21606, +21609, +21609, +21612, +21634, 21662, -21688, -21700, -21736, -21739, -21766, +21737, +21737, +21756, +21759, 21787, -21805, +21808, +21811, 21814, -21831, -21852, -21871, -21884, -21901, -21901, -21924, -21932, -21932, -21964, -21964, -21967, -21970, -21973, -21973, -21973, -22007, -22026, -22039, -22056, -22063, -22076, -22115, -22152, -22152, -22155, -22179, -22179, -22182, -22185, -22201, -22204, -22237, -22240, -22257, -22257, +21820, +21841, +21860, +21860, +21867, +21875, +21894, +21900, +21921, +21936, +21936, +21945, +21945, +21945, +21986, +22001, +22021, +22027, +22033, +22059, +22080, +22105, +22127, +22130, +22146, +22171, +22174, +22202, +22222, +22244, +22253, 22285, -22288, -22306, -22306, -22309, -22322, 22325, -22328, -22331, -22334, -22334, +22347, 22359, -22366, -22386, -22399, -22414, -22437, -22440, -22450, -22459, -22475, -22485, -22488, -22495, +22371, +22395, +22401, +22404, +22433, +22465, +22465, +22468, +22468, 22507, -22513, -22513, -22513, -22513, -22518, -22518, -22530, -22533, -22536, -22539, -22556, -22587, -22590, -22605, -22620, -22641, -22644, -22644, -22644, -22674, -22674, -22685, -22716, -22732, -22748, -22748, -22764, +22522, +22546, +22546, +22580, +22580, +22612, +22615, +22622, +22622, +22622, +22634, +22655, +22655, +22687, +22699, +22711, +22711, +22731, +22734, +22740, 22767, -22783, -22799, -22799, -22799, -22813, -22825, -22838, -22851, -22854, -22854, -22854, -22899, -22918, -22921, -22921, -22924, -22927, -22975, -22978, -22988, -22988, +22795, +22798, +22801, +22822, +22845, +22883, +22883, +22886, +22916, +22919, +22938, +22947, +22947, +22962, 22994, 22997, -23004, -23010, +23000, 23013, -23016, -23016, -23024, -23024, -23035, -23070, -23073, +23026, +23029, +23029, +23032, +23042, +23042, +23069, +23076, 23087, -23104, -23119, -23150, -23153, -23156, -23173, -23198, -23225, -23241, -23256, -23256, -23259, -23284, -23324, -23340, -23374, -23380, -23383, -23389, -23415, -23421, -23429, -23450, -23453, -23453, -23456, -23456, -23456, -23468, -23485, -23498, -23517, -23529, -23536, -23539, -23553, -23565, -23571, -23571, -23589, -23611, -23611, -23631, -23647, -23670, -23670, -23673, -23700, -23700, -23706, -23709, -23712, -23712, -23715, -23732, -23743, -23746, -23761, -23774, -23777, -23783, -23783, -23800, -23803, -23806, +23094, +23107, +23124, +23142, +23149, +23149, +23152, +23159, +23159, +23181, +23181, +23212, +23219, +23233, +23233, +23255, +23265, +23265, +23279, +23307, +23339, +23349, +23376, +23401, +23451, +23514, +23524, +23552, +23555, +23575, +23591, +23601, +23604, +23620, +23627, +23630, +23640, +23659, +23674, +23714, +23747, +23776, +23786, +23802, +23809, +23812, 23827, -23827, -23837, -23844, +23863, 23882, -23891, -23907, -23914, -23938, -23948, -23948, -23948, -23948, -23948, -23948, -23963, -23963, -23980, -23989, -24003, -24012, -24030, -24036, -24065, +23882, +23892, +23917, +23949, +23974, +23974, +24009, +24039, +24039, +24052, +24060, 24081, -24102, -24102, -24134, -24134, -24137, -24158, -24185, -24255, +24100, +24131, +24131, +24138, +24138, +24148, +24169, +24175, +24233, +24262, +24262, +24265, +24272, 24278, -24287, -24320, -24333, -24350, -24357, -24399, -24425, -24464, -24467, -24470, -24470, -24470, -24488, -24491, -24497, -24500, -24506, -24529, -24535, -24563, -24576, -24579, -24582, +24300, +24321, +24332, +24339, +24349, +24349, +24349, +24353, +24370, +24370, +24370, +24373, +24376, +24405, +24405, +24414, +24454, +24461, +24461, +24461, +24461, +24484, +24504, +24511, +24543, +24558, +24558, +24558, +24571, +24584, 24591, -24594, -24614, -24614, -24617, -24620, -24620, -24623, -24629, -24647, -24669, -24669, -24669, -24711, -24734, -24753, -24758, -24781, -24781, -24805, -24828, -24871, -24895, -24895, -24911, -24911, -24942, -24952, -24984, -25004, -25016, -25029, -25036, -25039, -25039, -25039, -25061, -25061, -25067, -25094, -25118, -25121, -25121, -25121, -25126, -25126, +24619, +24626, +24626, +24678, +24703, +24714, +24729, +24757, +24765, +24769, +24794, +24794, +24827, +24827, +24827, +24834, +24834, +24834, +24834, +24834, +24834, +24852, +24894, +24912, +24919, +24919, +24919, +24922, +24932, +24966, +24982, +25019, +25044, +25059, +25081, +25096, 25145, 25145, -25145, -25145, -25145, -25176, -25196, +25162, +25168, +25188, +25188, +25188, +25200, +25200, 25218, -25259, -25259, -25259, -25259, -25259, -25269, -25306, -25306, -25306, -25313, -25313, -25336, -25346, -25356, -25366, -25366, -25386, -25386, -25397, -25397, -25411, -25439, -25439, -25439, -25439, +25226, +25226, +25233, +25250, +25250, +25250, +25250, +25264, +25264, +25293, +25300, +25311, +25333, +25347, +25347, +25347, +25364, +25403, +25414, +25443, +25460, +25477, +25494, 25511, -25515, -25515, -25521, -25521, -25521, -25521, -25536, -25539, -25549, -25549, -25573, -25608, -25608, -25608, -25608, -25643, -25646, -25646, -25646, -25656, -25656, -25656, -25672, -25672, -25692, -25709, -25729, -25729, -25746, -25766, -25766, -25766, -25793, -25793, -25806, -25806, -25817, -25847, -25847, -25873, -25873, -25884, -25892, -25892, -25892, -25892, -25902, -25909, -25917, -25917, -25949, -25949, -25949, -25953, -25953, -25959, -25959, -25974, -25974, -25974, -25985, -25992, -26003, -26003, -26003, -26003, -26003, -26003, -26003, -26019, -26025, -26033, -26041, -26053, -26053, -26067, +25511, +25522, +25555, +25576, +25583, +25623, +25630, +25630, +25630, +25630, +25630, +25645, +25652, +25659, +25666, +25693, +25723, +25763, +25780, +25788, +25801, +25801, +25821, +25828, +25828, +25835, +25852, +25852, +25859, +25859, +25878, +25896, +25920, +25937, +25969, +25998, +26012, +26049, +26070, 26076, -26092, -26105, -26105, -26105, -26105, -26138, -26163, -26163, -26169, -26182, -26200, -26200, -26205, -26215, +26088, +26088, +26088, +26088, +26088, +26101, +26128, +26149, +26158, +26177, +26183, 26219, -26231, -26231, -26231, -26256, -26277, -26277, -26295, -26295, -26299, -26329, -26336, -26342, -26342, -26366, -26413, -26413, -26413, -26434, -26455, -26455, -26472, -26472, -26483, -26497, -26497, -26497, -26508, -26508, -26512, -26532, -26532, -26532, -26536, -26536, -26545, -26545, -26565, -26565, -26565, -26576, -26586, -26595, -26595, -26608, -26612, -26612, -26639, -26639, -26639, -26639, -26655, -26655, -26676, -26676, -26692, -26707, -26707, -26707, -26707, -26722, -26722, -26730, -26739, -26739, -26739, -26739, -26759, -26759, -26759, -26769, -26769, -26769, -26781, -26796, -26815, -26815, -26815, -26826, -26839, -26839, -26869, -26873, -26914, -26921, -26933, -26950, -26975, -26980, -27007, -27007, -27007, -27042, -27042, -27042, -27046, -27046, -27062, -27070, -27086, -27086, -27086, -27098, -27098, -27105, -27105, -27133, -27133, -27138, -27147, -27147, -27154, -27154, -27154, -27154, -27170, -27170, -27192, -27269, -27269, -27269, -27312, -27312, -27319, -27332, -27345, -27393, -27410, -27410, -27432, -27452, -27452, -27452, -27452, -27452, -27479, -27479, -27507, -27507, -27513, -27513, -27530, -27535, -27535, -27535, -27535, -27535, -27548, -27563, -27579, -27601, -27601, -27611, -27611, -27624, -27624, -27624, -27629, -27648, -27648, -27648, -27656, -27656, -27666, -27683, -27683, -27683, -27704, -27723, -27729, -27729, -27762, -27798, -27798, +26236, +26243, +26253, +26261, +26268, +26278, +26278, +26296, +26307, +26307, +26307, +26315, +26378, +26385, +26402, +26409, +26439, +26459, +26466, +26485, +26485, +26492, +26499, +26499, +26511, +26556, +26572, +26596, +26621, +26621, +26621, +26621, +26659, +26659, +26675, +26700, +26716, +26741, +26755, +26755, +26755, +26785, +26785, +26785, +26825, +26825, +26846, +26864, +26891, +26898, +26936, +26936, +26951, +26951, +26971, +26978, +27008, +27054, +27068, +27075, +27089, +27089, +27120, +27127, +27127, +27127, +27144, +27151, +27169, +27176, +27183, +27208, +27225, +27272, +27272, +27279, +27308, +27354, +27358, +27358, +27374, +27388, +27388, +27388, +27395, +27419, +27426, +27430, +27465, +27472, +27508, +27515, +27529, +27558, +27580, +27590, +27590, +27590, +27605, +27605, +27615, +27615, +27625, +27625, +27625, +27631, +27681, +27681, +27688, +27688, +27707, +27711, +27742, +27749, +27749, +27765, +27793, +27839, +27839, +27839, +27849, +27849, 27864, 27864, -27877, -27907, -27946, -27972, -27972, -27972, -27983, -27983, -27983, -27991, -27998, -28014, +27871, +27871, +27871, +27871, +27871, +27871, +27884, +27903, +27928, +27949, +27949, +27963, +27963, +27975, +27982, +27982, +27982, +27982, +27982, +28019, +28019, 28040, 28040, -28064, -28064, -28080, -28092, -28101, -28101, -28123, -28141, -28161, -28168, -28185, -28196, -28209, -28238, -28259, -28259, -28286, -28304, -28304, -28331, -28348, -28348, -28366, -28379, -28389, -28398, -28398, -28398, -28423, -28449, -28472, -28514, -28523, -28523, -28542, -28542, -28551, -28551, -28565, -28579, -28579, -28589, -28597, -28601, -28633, -28633, -28651, -28679, -28696, -28759, -28759, -28759, -28759, -28759, -28778, -28793, -28836, -28842, -28852, -28859, -28859, -28885, -28885, -28915, -28915, -28915, -28919, -28923, -28971, -28971, -28978, -28982, -28987, +28040, +28040, +28108, +28134, +28134, +28134, +28174, +28183, +28197, +28197, +28197, +28220, +28230, +28241, +28241, +28257, +28257, +28263, +28290, +28290, +28361, +28368, +28368, +28368, +28373, +28397, +28421, +28433, +28440, +28440, +28450, +28450, +28466, +28481, +28481, +28490, +28532, +28532, +28539, +28548, +28555, +28573, +28573, +28603, +28627, +28645, +28645, +28658, +28684, +28684, +28722, +28749, +28767, +28774, +28774, +28788, +28801, +28844, +28844, +28844, +28850, +28870, +28870, +28877, +28883, +28893, +28893, +28893, +28918, +28918, +28931, +28931, +28931, +28959, +28973, +28973, 28991, -28991, -29008, -29031, -29041, -29081, -29081, -29081, -29081, -29088, -29088, -29088, -29100, -29110, -29124, -29147, -29147, -29147, -29153, -29153, -29153, -29175, -29185, -29190, -29214, -29231, -29231, -29231, -29231, -29237, -29265, +29010, +29029, +29038, +29048, +29099, +29099, +29109, +29109, +29109, +29109, +29109, +29109, +29128, +29139, +29162, +29162, +29176, +29176, +29194, +29194, +29194, +29205, +29205, +29227, +29227, +29227, +29227, +29248, +29254, +29270, +29270, 29302, -29333, -29333, -29374, -29421, -29446, -29446, -29456, -29456, -29473, -29489, -29497, -29497, -29530, -29538, -29571, -29602, -29623, -29631, -29631, -29642, -29655, -29702, -29702, -29702, -29702, -29720, -29720, -29731, -29753, -29753, -29753, -29765, +29309, +29326, +29343, +29359, +29369, +29369, +29386, +29411, +29411, +29411, +29411, +29452, +29463, +29463, +29468, +29468, +29492, +29492, +29523, +29535, +29535, +29539, +29539, +29546, +29557, +29557, +29564, +29570, +29579, +29595, +29601, +29608, +29608, +29608, +29664, +29683, +29698, +29698, +29698, +29698, +29706, +29706, +29721, +29746, +29775, 29793, -29800, -29849, -29884, -29884, -29884, -29894, -29919, -29940, -29973, -30037, -30037, -30054, -30054, -30054, -30054, -30054, -30066, -30090, -30103, -30144, -30144, -30144, -30165, -30189, -30189, -30189, -30189, -30189, -30208, -30222, +29813, +29831, +29831, +29852, +29852, +29897, +29916, +29955, +29971, +29971, +30000, +30040, +30040, +30055, +30064, +30071, +30071, +30071, +30071, +30071, +30088, +30088, +30118, +30118, +30130, +30130, +30141, +30164, +30171, +30178, +30194, +30194, +30204, +30223, 30231, -30241, -30241, -30259, 30269, -30276, -30298, -30298, -30298, -30304, -30304, -30314, -30314, -30314, -30314, -30314, -30314, -30321, -30321, -30321, -30321, -30327, -30327, -30334, -30340, -30340, -30362, -30378, -30385, -30385, -30385, -30385, +30308, +30308, +30308, +30352, +30374, +30394, +30394, 30406, -30412, -30424, -30464, +30406, +30406, +30414, +30431, +30431, +30437, +30443, +30461, 30483, 30483, -30492, -30498, -30522, -30529, -30554, -30554, -30554, -30554, -30572, -30572, -30584, -30584, -30606, -30626, -30665, -30678, -30678, -30697, -30725, +30483, +30514, +30519, +30553, +30553, +30558, +30563, +30563, +30604, +30604, +30610, +30610, +30610, +30631, +30642, +30646, +30646, +30646, +30650, +30650, +30681, +30681, +30681, +30698, +30714, +30714, +30714, +30714, +30714, +30721, +30732, +30732, +30732, +30745, +30745, +30751, 30765, -30771, -30771, -30771, -30791, -30791, -30824, -30840, -30844, -30872, -30896, -30896, -30922, -30946, -30946, -30970, +30782, +30805, +30805, +30821, +30821, +30842, +30855, +30881, +30881, +30903, +30903, +30912, +30965, +30965, +30980, +30980, +30980, +30987, 30998, -30998, -31028, -31047, -31070, -31070, -31070, -31076, -31113, -31134, -31140, -31151, -31158, +31002, +31064, +31075, +31087, +31103, +31109, +31109, +31109, +31122, +31122, +31122, +31135, +31150, +31150, 31165, -31185, -31185, -31185, -31203, -31218, -31233, -31233, -31233, -31256, -31263, -31263, -31287, -31287, -31287, -31297, -31309, -31317, -31327, -31343, -31353, -31353, -31389, -31389, -31389, -31406, -31406, -31406, -31423, -31439, -31439, -31459, -31469, -31476, -31493, -31499, -31515, -31515, -31534, -31534, +31165, +31175, +31175, +31175, +31189, +31220, +31220, +31230, +31240, +31274, +31281, +31307, +31307, +31313, +31342, +31349, +31372, +31413, +31413, +31429, +31435, +31435, +31435, +31447, +31454, +31454, +31454, +31461, +31461, +31488, +31488, +31488, +31488, +31488, +31507, +31537, +31546, +31546, +31546, 31566, -31585, -31608, -31608, -31626, -31641, +31590, +31602, +31602, +31602, +31622, +31622, 31648, -31648, -31665, -31665, -31665, -31665, -31681, -31705, -31746, -31768, -31841, -31851, -31927, -31927, -31934, -31962, -31986, -31992, -32008, -32021, -32021, -32021, -32021, -32027, -32027, -32053, -32053, -32057, -32088, -32088, -32098, -32098, -32098, -32129, -32172, -32193, -32208, -32208, -32228, -32228, -32248, -32254, -32274, -32274, -32287, -32309, -32319, -32350, -32355, -32391, -32397, -32397, -32412, -32412, -32419, -32461, -32468, -32468, -32468, -32485, -32485, -32510, -32553, -32565, -32578, -32586, -32591, -32591, -32595, -32608, -32608, -32636, -32636, -32636, -32658, -32676, +31677, +31692, +31701, +31717, +31728, +31728, +31744, +31744, +31754, +31783, +31816, +31827, +31827, +31834, +31834, +31863, +31884, +31884, +31898, +31954, +32001, +32023, +32023, +32041, +32054, +32076, +32086, +32121, +32128, +32135, +32135, +32158, +32188, +32203, +32203, +32255, +32255, +32255, +32279, +32308, +32346, +32374, +32394, +32394, +32394, +32394, +32414, +32431, +32431, +32447, +32447, +32447, +32462, +32462, +32462, +32462, +32505, +32522, +32522, +32522, +32539, +32544, +32569, +32569, +32569, +32598, +32614, +32633, +32633, +32633, +32648, +32648, +32659, 32680, 32680, -32695, -32695, -32695, -32695, -32695, +32720, +32720, 32726, 32726, -32768, -32779, -32804, -32821, -32835, -32835, -32835, -32851, -32866, -32881, -32881, -32886, -32886, -32886, -32893, -32893, -32912, -32924, -32935, -32935, -32955, -32975, -32993, +32726, +32726, +32769, +32803, +32803, +32803, +32803, +32803, +32819, +32819, +32836, +32836, +32836, +32856, +32856, +32871, +32871, +32889, +32913, +32919, +32919, +32919, +32919, +32942, +32942, +32942, +32942, +32942, +32963, +32984, 33012, -33020, -33038, -33046, -33069, -33069, -33118, -33131, -33131, -33157, -33157, -33172, -33177, -33182, -33197, -33204, +33018, +33018, +33018, +33018, +33034, +33060, +33060, +33077, +33110, +33110, +33120, +33120, +33144, +33181, +33195, +33195, +33195, +33212, +33225, 33238, -33254, -33281, -33294, -33309, -33320, -33360, -33360, -33364, -33379, -33379, -33397, -33415, -33415, -33415, -33415, -33415, -33415, -33441, -33465, +33248, +33248, +33248, +33248, +33259, +33259, +33259, +33273, +33273, +33273, +33273, +33273, +33273, +33273, +33273, +33273, +33273, +33293, +33303, +33303, +33313, +33325, +33325, +33325, +33336, +33342, +33347, +33347, +33357, +33370, +33403, +33442, +33467, +33477, +33477, +33491, +33491, 33508, 33508, -33508, -33525, -33531, -33558, -33572, -33572, -33579, -33579, -33607, -33636, -33642, -33642, -33663, -33663, -33663, -33663, -33670, -33670, -33670, -33670, -33677, -33677, -33677, -33688, -33688, -33688, -33709, -33723, -33741, -33741, -33741, -33741, -33741, -33741, -33752, -33752, -33752, -33771, -33771, -33771, -33790, +33560, +33569, +33569, +33569, +33589, +33628, +33654, +33665, +33681, +33700, +33719, +33719, +33742, +33760, +33760, +33760, +33760, +33760, +33788, +33788, 33804, -33824, -33864, -33875, -33886, -33903, -33903, -33916, -33928, -33948, -33961, -34011, -34048, -34065, -34097, -34112, -34112, -34112, -34112, -34130, -34148, -34148, -34148, -34178, -34191, -34223, -34228, -34228, -34260, -34260, -34260, -34260, -34282, -34305, -34315, -34315, -34336, -34356, -34373, -34373, -34379, -34401, -34419, -34419, -34419, -34419, -34432, -34432, -34438, -34460, -34489, -34508, -34515, -34515, -34515, -34515, -34537, -34546, -34546, -34546, -34546, -34546, -34562, -34573, -34573, -34583, -34621, +33804, +33804, +33830, +33854, +33854, +33854, +33860, +33860, +33878, +33898, +33898, +33898, +33898, +33898, +33941, +33941, +33955, +33982, +33982, +34002, +34002, +34017, +34030, +34090, +34104, +34104, +34140, +34180, +34195, +34214, +34214, +34214, +34244, +34244, +34263, +34263, +34263, +34263, +34263, +34263, +34263, +34263, +34279, +34312, +34341, +34345, +34351, +34374, +34386, +34407, +34407, +34407, +34417, +34437, +34437, +34449, +34459, +34465, +34484, +34484, +34494, +34534, +34556, +34556, +34556, +34566, +34576, +34576, +34582, +34607, +34607, +34628, 34634, -34644, -34664, -34664, -34695, -34719, -34719, -34762, -34762, -34762, -34805, -34811, -34832, -34836, -34836, -34836, -34836, -34865, +34646, +34646, +34655, +34673, +34673, +34686, +34686, +34697, +34697, +34714, +34714, +34714, +34714, +34714, +34731, +34731, +34731, +34731, +34731, +34741, +34767, +34767, +34767, +34783, +34783, +34792, +34792, +34847, +34862, +34876, +34876, 34891, -34911, -34916, -34916, -34916, -34916, -34933, -34963, -34979, -34979, -35021, -35035, -35035, -35044, -35055, -35092, -35120, -35120, -35120, -35120, -35120, -35139, -35179, -35208, -35218, +34891, +34902, +34919, +34919, +34939, +34939, +34939, +34954, +34954, +34954, +34954, +34971, +34971, +34988, +34988, +34998, +35006, +35006, +35006, +35017, +35023, +35023, +35028, +35028, +35047, +35066, +35066, +35076, +35128, +35137, +35158, +35174, +35174, +35181, +35181, +35223, 35233, -35249, -35249, -35298, -35309, -35325, +35248, +35258, +35277, +35277, +35282, +35300, +35316, +35335, +35335, 35344, -35344, -35358, -35358, -35395, -35410, -35410, +35378, +35400, 35419, -35419, -35419, -35419, -35419, -35451, -35470, -35470, -35494, -35523, -35523, -35573, -35573, -35597, -35609, -35644, -35662, -35662, -35676, -35680, -35680, -35680, -35680, -35685, -35694, -35694, -35694, -35729, -35747, -35747, -35754, -35761, -35761, -35771, -35793, -35802, -35837, -35889, -35889, -35889, -35889, -35899, -35915, -35947, -35947, -35947, -35957, -35957, -35980, -35986, -35986, -35986, -36002, -36050, -36050, -36074, -36084, -36092, -36092, -36117, -36117, +35433, +35433, +35448, +35461, +35477, +35498, +35522, +35533, +35554, +35569, +35569, +35586, +35595, +35608, +35608, +35608, +35618, +35623, +35635, +35645, +35645, +35645, +35682, +35682, +35682, +35682, +35687, +35701, +35705, +35705, +35705, +35715, +35715, +35715, +35753, +35766, +35808, +35821, +35825, +35835, +35857, +35877, +35877, +35877, +35888, +35888, +35905, +35967, +35967, +35974, +35974, +36001, +36027, +36027, +36038, +36038, +36054, +36064, +36064, +36064, +36083, +36111, +36133, 36133, 36156, -36171, -36184, -36227, -36247, -36288, -36288, -36317, -36325, -36342, -36342, -36342, -36349, -36349, -36369, -36378, -36397, -36410, -36410, -36449, -36473, -36473, -36488, -36488, -36500, -36527, -36538, -36538, -36578, -36610, -36632, -36651, -36651, -36651, -36651, -36664, -36664, -36682, -36682, -36682, -36713, -36732, -36732, -36732, -36732, -36732, -36745, -36745, -36751, -36751, +36178, +36198, +36198, +36198, +36202, +36255, +36276, +36282, +36290, +36290, +36313, +36334, +36334, +36334, +36345, +36411, +36424, +36450, +36472, +36472, +36472, +36479, +36495, +36511, +36575, +36575, +36593, +36593, +36593, +36593, +36602, +36616, +36628, +36628, +36656, +36672, +36719, +36719, +36719, +36719, +36719, +36737, +36737, +36737, +36750, +36750, +36750, +36758, 36770, 36770, -36770, -36776, -36807, -36827, -36827, -36844, -36844, -36853, -36863, -36873, -36873, -36880, -36880, -36880, -36884, -36897, -36928, -36928, -36950, -36968, -36973, -36973, -36989, -37055, -37055, -37073, -37085, -37094, -37106, -37157, -37163, +36778, +36778, +36778, +36778, +36826, +36835, +36835, +36835, +36850, +36850, +36855, +36872, +36872, +36903, +36919, +36934, +36939, +36939, +36954, +36954, +36986, +37016, +37043, +37051, +37062, +37062, +37062, +37069, +37069, +37069, +37069, +37069, +37069, +37069, +37069, +37096, +37096, +37115, +37115, +37149, +37177, 37193, -37232, +37214, +37228, +37228, +37228, +37228, +37228, 37241, -37265, -37265, -37272, -37281, -37324, -37359, -37391, -37415, -37429, -37429, -37457, -37457, -37463, -37463, -37469, -37469, -37498, -37498, -37498, -37498, -37498, -37498, -37498, -37498, -37498, -37515, -37526, -37541, -37559, -37597, -37617, -37627, -37634, -37668, -37668, -37668, -37668, -37699, +37245, +37245, +37245, +37250, +37250, +37268, +37294, +37299, +37314, +37328, +37335, +37335, +37372, +37380, +37396, +37410, +37416, +37428, +37468, +37490, +37511, +37516, +37516, +37528, +37528, +37528, +37528, +37534, +37534, +37562, +37589, +37589, +37589, +37611, +37611, +37611, +37625, +37631, +37654, +37654, +37654, +37658, +37685, +37685, 37706, -37706, -37706, -37706, -37715, -37724, -37733, -37751, -37767, -37767, +37717, +37717, +37717, +37732, +37732, +37732, +37758, 37783, -37783, -37793, -37793, -37793, -37806, -37806, -37828, -37841, -37841, -37841, -37841, -37866, -37879, -37879, -37896, -37903, -37910, -37910, +37803, +37822, +37840, +37840, +37840, +37840, +37863, +37881, +37894, 37926, -37971, -37971, -37981, -38033, -38082, -38113, -38122, -38122, -38122, -38122, -38144, -38144, -38144, -38169, -38210, -38244, -38284, +37949, +37949, +37949, +37970, +37970, +37991, +37991, +37991, +37991, +38025, +38025, +38025, +38025, +38045, +38058, +38058, +38080, +38080, +38095, +38095, +38142, +38179, +38187, +38211, +38218, +38225, +38232, +38277, +38298, +38298, 38328, -38339, -38339, -38377, -38402, -38412, -38429, -38429, -38452, -38474, -38481, -38488, -38488, -38488, -38488, -38511, -38525, -38568, -38568, -38575, -38592, -38613, -38629, -38629, -38654, -38684, -38684, -38703, -38710, -38710, -38735, -38748, -38755, -38762, -38776, -38776, -38776, -38776, -38776, -38812, -38819, -38834, -38847, -38854, -38861, -38868, -38868, -38888, -38888, -38908, -38908, +38352, +38352, +38371, +38371, +38378, +38407, +38428, +38448, +38448, +38458, +38458, +38458, +38489, +38489, +38489, +38489, +38499, +38515, +38532, +38532, +38578, +38578, +38586, +38606, +38606, +38624, +38624, +38624, +38642, +38647, +38647, +38658, +38665, +38682, +38723, +38767, +38767, +38795, +38795, +38801, +38801, +38801, +38837, +38837, +38856, +38856, +38894, 38915, -38926, -38942, -38949, -38956, -38956, -38956, -38963, -38980, -38980, -39003, -39009, +38941, +38965, +38965, +38965, +38965, +38992, +39015, 39039, -39052, -39059, -39077, -39084, -39084, -39091, -39091, -39108, -39115, -39115, -39150, -39150, -39179, -39184, -39184, -39240, -39240, -39277, -39284, -39284, -39284, -39309, -39351, +39045, +39045, +39053, +39058, +39058, +39088, +39088, +39118, +39118, +39129, +39129, +39129, +39147, +39155, +39155, +39178, +39182, +39222, +39222, +39230, +39230, +39230, +39230, +39238, +39238, +39260, +39260, +39260, +39281, +39295, +39310, +39328, +39335, +39342, 39358, -39363, -39395, -39408, -39421, -39421, -39427, -39427, -39440, -39453, -39461, -39461, -39473, -39473, -39473, -39490, -39497, -39510, -39510, -39516, -39516, -39523, -39523, -39535, -39544, -39551, -39561, -39561, +39371, +39386, +39386, +39415, +39415, +39422, +39454, +39471, +39471, +39471, +39478, +39520, +39520, +39534, +39541, +39541, +39548, +39548, +39548, 39568, -39568, -39585, -39585, -39592, -39592, -39599, -39622, -39622, -39637, -39677, -39715, -39736, -39765, -39765, -39775, -39793, -39793, -39814, -39850, -39864, -39889, -39893, -39917, -39927, -39934, -39934, -39952, -39959, -39977, -39984, -39991, -40009, -40009, -40013, -40013, -40032, -40032, -40032, -40032, -40032, -40032, -40047, -40062, -40078, -40078, -40095, -40131, -40137, -40151, -40186, -40201, -40208, -40227, -40236, -40236, -40243, -40250, -40250, -40359, -40366, -40373, +39581, +39605, +39613, +39627, +39634, +39672, +39699, +39705, +39712, +39728, +39741, +39748, +39755, +39762, +39799, +39843, +39884, +39891, +39905, +39922, +39922, +39929, +39936, +39943, +39970, +39970, +39970, +39988, +40002, +40022, +40026, +40026, +40043, +40073, +40097, +40107, +40107, +40166, +40178, +40184, +40211, +40234, +40260, +40260, +40285, +40310, +40310, +40331, +40348, +40348, +40362, 40380, -40404, -40404, -40415, -40422, -40434, -40458, -40465, -40472, -40472, -40472, +40380, +40394, +40414, +40414, +40421, +40421, +40460, 40472, +40483, +40490, 40497, -40502, -40509, +40512, 40527, -40527, -40540, -40547, -40562, -40569, -40584, -40591, -40591, -40598, -40605, -40605, -40612, -40619, -40630, -40660, -40667, -40674, -40690, -40714, -40721, -40748, -40763, -40770, -40784, -40795, -40827, -40827, -40841, -40841, -40870, -40870, -40889, -40889, -40889, +40546, +40587, +40587, +40587, +40587, +40607, +40614, +40614, +40614, +40614, +40614, +40635, +40635, +40635, +40653, +40673, +40673, +40673, +40673, +40673, +40680, +40680, +40694, +40708, +40731, +40731, +40738, +40757, +40757, +40764, +40803, +40812, +40825, +40825, +40832, +40838, +40869, +40922, 40936, -40942, -40952, -40982, -40991, -41001, -41017, -41033, -41040, -41060, -41073, -41104, -41114, -41114, -41149, -41149, -41149, -41149, -41149, -41156, -41221, -41244, -41266, -41292, -41292, -41309, -41309, +40955, +40990, +40997, +41010, +41053, +41071, +41101, +41107, +41119, +41194, +41208, +41208, +41208, +41215, +41233, +41265, +41285, +41295, 41318, -41325, -41361, -41389, -41415, -41415, -41442, -41457, -41471, -41478, -41478, -41478, -41487, -41487, -41502, -41518, -41553, -41553, -41575, -41575, -41575, -41596, -41596, -41596, -41596, -41603, -41603, -41603, -41603, -41617, -41625, -41638, -41671, -41704, -41721, -41752, -41788, -41810, -41828, -41842, -41849, -41849, -41859, -41874, -41881, -41881, -41881, -41881, -41881, -41906, -41919, -41935, -41942, -41942, -41959, -41959, -41966, -41973, -41980, -41980, -41987, -42017, -42024, -42031, -42031, -42038, -42045, -42055, -42092, -42125, -42144, -42151, -42162, -42181, -42192, -42215, -42215, -42241, -42255, -42255, -42255, -42255, -42255, -42279, +41318, +41336, +41356, +41356, +41363, +41379, +41407, +41439, +41469, +41500, +41500, +41524, +41524, +41524, +41524, +41529, +41578, +41616, +41616, +41631, +41672, +41677, +41711, +41726, +41787, +41787, +41787, +41818, +41845, +41845, +41845, +41900, +41930, +41937, +41937, +41937, +41937, +41986, +42025, +42037, +42059, +42073, +42080, +42148, +42148, +42163, +42179, +42186, +42197, +42219, +42226, +42240, +42240, +42240, +42259, +42264, +42280, 42290, -42297, -42315, -42315, -42315, -42356, -42356, -42356, -42382, -42382, -42389, -42398, -42398, -42398, -42408, -42426, -42426, -42437, -42443, -42448, -42448, -42448, -42470, -42470, -42478, -42520, -42546, +42313, +42313, +42328, +42346, +42373, +42380, +42399, +42406, +42406, +42413, +42427, +42476, +42494, +42533, +42533, +42540, +42540, 42556, -42571, -42588, -42594, -42645, -42656, -42656, -42656, -42656, -42673, -42680, -42680, -42680, -42688, -42688, -42719, -42758, -42758, -42758, -42768, -42794, -42794, -42794, -42806, -42822, -42846, -42865, -42865, -42874, -42874, -42887, -42887, -42894, -42920, -42932, -42932, -42966, -42987, -42987, -42987, -43015, -43030, -43041, -43041, -43049, -43069, -43082, -43082, -43082, -43082, -43108, -43125, -43147, -43155, -43174, -43180, -43193, -43193, -43193, -43193, -43193, -43193, -43220, -43232, -43232, -43232, -43246, -43262, -43270, -43278, -43278, -43278, -43278, -43301, -43301, -43320, -43320, -43366, -43370, -43388, -43388, -43388, -43433, +42567, +42587, +42601, +42615, +42622, +42643, +42664, +42664, +42664, +42702, +42718, +42718, +42734, +42746, +42761, +42781, +42793, +42810, +42815, +42841, +42890, +42897, +42905, +42917, +42924, +42931, +42936, +42941, +42951, +42967, +42988, +42988, +43012, +43028, +43054, +43070, +43123, +43127, +43144, +43175, +43199, +43199, +43236, +43244, +43244, +43273, +43280, +43287, +43302, +43318, +43318, +43318, +43331, +43353, +43373, +43373, +43390, +43390, +43390, +43390, +43425, +43437, +43437, 43447, -43462, -43462, -43462, -43462, -43462, -43495, -43495, -43521, -43528, -43528, -43552, -43612, -43612, -43632, -43648, -43659, -43666, -43693, -43710, -43723, -43728, -43757, -43768, -43780, -43797, -43797, -43797, -43809, -43816, -43821, -43849, -43871, -43890, -43923, -43923, -43932, -43940, -43940, -43958, -43979, -43979, -43979, -43979, -44002, -44002, -44002, -44002, -44058, -44077, -44099, -44129, -44140, -44146, -44146, -44146, -44165, -44178, -44178, -44202, -44202, -44220, -44238, -44255, -44255, -44263, +43464, +43504, +43504, +43504, +43504, +43504, +43504, +43512, +43587, +43587, +43613, +43620, +43620, +43669, +43684, +43698, +43711, +43732, +43752, +43766, +43773, +43796, +43811, +43820, +43840, +43840, +43856, +43876, +43891, +43922, +43922, +43945, +43970, +43984, +44011, +44024, +44024, +44048, +44055, +44055, +44060, +44067, +44074, +44094, +44094, +44106, +44126, +44136, +44149, +44149, +44149, +44190, +44232, +44232, +44250, +44264, +44264, +44264, 44280, -44298, -44302, -44302, -44330, -44351, -44351, -44363, -44363, -44363, -44378, -44385, +44280, +44280, +44303, +44335, +44361, +44361, +44398, 44406, -44406, -44434, -44444, -44472, -44472, -44472, -44488, -44492, -44523, -44561, -44592, -44611, -44611, -44632, -44644, -44644, +44425, +44425, +44452, +44459, +44459, +44459, +44459, +44466, +44481, +44516, +44550, +44556, +44576, +44576, +44583, +44583, +44599, +44621, +44642, 44651, -44651, -44651, -44651, -44651, -44684, -44684, -44690, -44706, -44725, -44731, -44731, -44731, -44731, -44746, -44746, -44757, -44757, -44757, -44757, -44787, -44787, -44787, -44787, -44787, -44799, -44812, -44812, -44827, -44847, -44856, -44856, -44856, -44856, -44884, +44661, +44661, +44661, +44679, +44679, +44710, +44728, +44740, +44747, +44761, +44772, +44795, +44804, +44804, +44804, +44804, +44804, +44808, +44814, +44814, +44814, +44832, +44832, +44832, +44844, +44872, 44899, -44911, -44911, -44911, -44928, -44958, -44958, -44981, -44981, -44990, -45012, -45037, -45037, -45046, -45046, -45073, -45073, -45085, -45096, -45096, -45100, -45113, -45123, -45158, +44924, +44931, +44931, +44939, +44983, +44988, +44988, +44998, +45008, +45015, +45015, +45028, +45028, +45045, +45045, +45074, +45091, +45091, +45091, +45091, +45095, +45141, +45141, +45155, +45155, +45155, 45173, -45206, -45214, -45230, -45230, -45258, -45268, -45295, -45307, -45307, -45307, -45307, -45307, -45307, -45338, -45338, -45355, -45372, -45372, -45393, -45393, -45393, -45403, -45403, -45403, -45414, +45196, +45209, +45226, +45238, +45266, +45266, +45266, +45266, +45302, +45308, +45312, +45312, +45333, +45365, +45377, +45386, +45409, +45409, +45409, +45409, +45445, 45455, -45455, -45455, -45455, -45455, -45463, -45463, 45478, -45497, -45514, -45514, -45524, -45540, -45540, -45540, -45558, -45558, -45558, -45558, -45574, -45574, -45574, -45590, -45654, -45674, -45686, -45686, -45686, -45705, -45705, -45711, -45721, -45732, -45732, -45732, -45732, -45732, -45738, -45748, -45748, -45769, -45789, -45789, -45800, -45837, -45856, -45868, -45876, -45885, -45902, -45908, -45918, -45918, -45918, -45948, +45478, +45494, +45511, +45511, +45511, +45523, +45523, +45538, +45538, +45553, +45553, +45589, +45589, +45600, +45610, +45629, +45657, +45720, +45725, +45725, +45755, +45777, +45777, +45791, +45814, +45840, +45890, +45890, +45890, +45927, +45927, +45934, +45934, +45954, +45954, 45976, 45976, 45976, -45976, -45981, -46009, +45998, +46007, +46016, 46016, -46027, -46027, -46027, 46034, -46050, -46090, -46108, -46108, -46112, -46119, -46126, -46149, -46149, -46149, -46149, +46034, +46066, +46081, +46102, +46117, +46146, +46146, +46162, +46162, 46169, -46193, -46193, -46193, -46204, -46213, -46222, -46222, -46238, -46245, -46257, -46257, -46301, -46301, -46322, -46322, -46322, -46327, -46345, -46359, +46174, +46215, +46215, +46234, +46239, +46286, +46286, +46300, +46313, +46370, +46370, +46370, 46374, -46384, -46417, -46417, -46428, -46458, -46458, -46458, -46493, -46493, -46500, -46505, -46555, -46567, -46567, -46580, -46580, -46580, -46595, -46595, -46595, -46595, -46628, -46628, -46652, -46652, -46669, -46669, -46698, -46718, -46718, -46718, -46738, -46753, -46761, -46776, -46776, -46776, +46379, +46393, +46401, +46416, +46416, +46446, +46467, +46482, +46482, +46496, +46538, +46538, +46581, +46581, +46629, +46629, +46629, +46640, +46644, +46649, +46649, +46659, +46659, +46673, +46700, +46731, +46731, +46731, +46741, +46766, +46766, +46771, +46771, +46782, 46794, 46794, -46802, -46816, -46846, -46863, -46899, -46899, -46899, -46907, -46907, -46917, -46930, -46957, -46957, -46961, -46961, -46969, -46975, -46975, -46975, -46991, -46999, -46999, -47012, -47018, -47018, -47048, -47058, -47076, -47145, -47145, -47162, -47183, -47228, -47244, -47267, -47267, -47295, -47295, -47295, -47316, -47316, -47316, -47353, -47361, -47385, -47385, -47415, -47419, -47430, -47450, -47465, -47470, -47470, -47470, -47470, -47479, -47501, -47521, -47529, -47536, -47554, -47572, -47572, -47597, -47606, -47614, -47614, -47614, -47623, -47623, -47660, -47660, -47669, -47681, -47694, -47694, -47694, -47698, -47702, -47720, -47720, -47730, -47749, -47767, -47790, -47808, -47824, -47824, -47824, -47830, -47830, -47836, -47869, -47869, -47875, -47898, -47898, -47958, -47962, -47978, -47978, -47985, -48019, -48023, -48023, -48023, -48023, -48043, -48043, -48058, -48058, -48058, -48058, +46812, +46812, +46828, +46851, +46851, +46851, +46851, +46851, +46855, +46868, +46875, +46875, +46886, +46890, +46925, +46925, +46925, +46936, +46954, +46972, +46972, +46972, +46998, +47068, +47068, +47068, +47098, +47107, +47122, +47128, +47151, +47156, +47156, +47170, +47177, +47182, +47193, +47200, +47226, +47226, +47253, +47273, +47283, +47283, +47290, +47303, +47303, +47303, +47320, +47327, +47327, +47335, +47335, +47344, +47344, +47356, +47356, +47360, +47360, +47369, +47394, +47425, +47425, +47425, +47443, +47466, +47466, +47481, +47495, +47513, +47513, +47532, +47532, +47543, +47590, +47603, +47613, +47618, +47618, +47635, +47641, +47641, +47679, +47727, +47740, +47753, +47769, +47779, +47801, +47809, +47829, +47859, +47859, +47878, +47885, +47906, +47906, +47906, +47940, +47950, +47950, +47950, +47950, +47984, +47991, +47991, +47991, +47991, +48029, +48029, +48029, +48038, +48038, +48038, +48055, +48055, 48065, -48070, -48101, -48101, -48116, -48127, -48127, -48139, -48139, -48163, -48163, -48177, -48177, -48204, -48218, -48246, -48262, -48262, -48262, -48283, -48283, -48306, -48306, -48312, -48312, -48317, -48331, -48347, -48354, -48364, -48364, -48364, -48394, -48447, -48452, -48452, -48476, -48476, -48476, -48542, -48572, -48582, -48622, -48658, -48669, -48669, -48669, -48686, -48686, -48686, -48693, -48693, -48699, -48724, +48065, +48065, +48065, +48105, +48105, +48123, +48138, +48164, +48179, +48179, +48179, +48205, +48211, +48250, +48310, +48343, +48368, +48368, +48374, +48381, +48397, +48397, +48397, +48406, +48426, +48426, +48439, +48458, +48458, +48485, +48485, +48494, +48520, +48532, +48578, +48595, +48608, +48608, +48608, +48623, +48636, +48636, +48636, +48636, +48648, +48687, +48703, +48711, +48727, 48741, -48741, -48752, -48764, -48784, -48784, -48794, -48799, -48799, -48799, -48799, -48820, -48830, -48866, -48884, -48894, -48913, -48913, -48913, -48913, -48925, -48966, +48746, +48746, +48746, +48746, +48746, +48746, +48771, +48771, +48771, +48806, +48847, +48847, +48847, +48847, +48847, +48886, +48886, +48886, +48886, +48886, +48886, +48899, +48933, +48933, +48933, 48975, -48975, -48975, -48980, -48987, -49020, -49028, -49054, -49060, -49060, -49086, -49110, -49110, -49121, -49121, -49121, -49134, -49134, -49134, -49141, +48979, +48986, +48986, +49019, +49019, +49019, +49040, +49040, +49040, +49059, +49076, +49103, +49103, +49132, +49132, +49132, +49132, +49132, +49132, +49154, 49171, -49185, -49197, -49228, -49254, -49254, -49286, -49302, -49315, -49315, -49353, -49362, +49191, +49216, +49226, +49264, +49264, +49278, +49278, +49301, +49340, +49340, +49360, +49370, +49370, 49374, -49385, -49412, +49381, +49381, +49399, +49406, 49419, -49447, -49447, -49489, -49514, -49526, -49526, -49559, -49559, -49603, -49615, -49655, -49667, -49667, -49682, -49699, -49743, -49743, +49428, +49428, +49464, +49464, +49497, +49497, +49497, +49497, +49501, +49501, +49501, +49518, +49548, +49548, +49579, +49594, +49619, +49619, +49639, +49665, +49665, +49665, +49665, +49671, +49671, +49671, +49686, +49686, +49686, +49701, +49701, +49701, +49724, +49738, 49755, 49755, -49755, -49768, -49778, -49799, -49816, -49816, -49816, -49822, -49822, -49835, -49854, -49872, -49872, -49872, -49882, -49882, -49945, -49969, -49978, -49993, -49993, +49765, +49785, +49795, +49807, +49807, +49842, +49862, +49862, +49876, +49899, +49899, +49899, +49929, +49929, +49929, +49959, +49959, +49959, +49990, +49994, +50012, 50028, -50044, -50054, -50076, -50083, -50108, -50108, -50120, -50120, -50143, -50143, -50202, -50202, -50214, +50071, +50071, +50081, +50081, +50081, +50091, +50099, +50139, +50139, +50139, +50139, +50156, +50184, +50209, +50209, +50209, +50216, +50216, +50223, +50231, +50231, +50231, +50231, +50251, 50265, -50279, -50279, -50291, -50291, -50316, -50366, -50366, -50387, -50387, -50387, -50387, -50387, -50405, -50405, -50425, -50425, -50432, -50432, -50432, -50439, -50439, -50463, -50470, -50470, -50470, -50470, -50474, -50486, -50495, -50495, -50518, -50518, -50518, -50533, -50558, -50579, -50579, -50601, -50611, -50645, -50674, -50674, -50692, -50729, -50748, -50784, -50784, -50801, -50814, -50831, -50831, -50831, -50831, -50844, +50273, +50295, +50311, +50311, +50330, +50330, +50339, +50348, +50373, +50373, +50406, +50406, +50406, +50422, +50422, +50433, +50494, +50526, +50542, +50542, +50542, +50542, +50542, +50552, +50552, +50586, +50586, +50586, +50612, +50619, +50619, +50644, +50659, +50659, +50676, +50676, +50676, +50676, +50676, +50723, +50736, +50736, +50736, +50736, +50755, +50778, +50778, +50778, +50785, +50785, +50793, +50815, 50856, -50860, -50872, +50856, +50874, +50886, 50909, -50921, -50921, -50964, -50964, -50986, -51006, -51006, -51006, -51021, -51021, -51029, -51035, -51047, -51058, -51058, -51062, -51089, -51089, -51120, -51120, -51120, -51126, -51126, -51139, -51139, -51153, -51153, -51153, -51153, -51165, -51186, -51186, -51208, -51247, -51247, -51247, -51261, -51273, -51273, -51298, -51298, -51298, -51321, -51321, -51321, -51338, -51343, -51371, -51395, -51417, -51417, -51417, -51426, -51426, -51426, -51445, -51455, -51469, -51469, -51488, -51492, -51492, -51511, -51529, -51529, -51549, -51549, -51564, -51583, -51611, -51622, -51644, -51644, -51644, -51656, -51674, -51674, +50918, +50973, +50998, +51014, +51030, +51030, +51030, +51036, +51036, +51046, +51072, +51072, +51078, +51118, +51118, +51118, +51118, +51134, +51182, +51203, +51219, +51219, +51230, +51240, +51240, +51260, +51260, +51260, +51260, +51260, +51260, +51260, +51275, +51275, +51301, +51358, +51374, +51386, +51393, +51402, +51402, +51402, +51441, +51471, +51507, +51507, +51531, +51547, +51547, +51571, +51571, +51571, +51571, +51571, +51571, +51587, +51612, +51626, +51642, +51665, +51681, +51681, +51681, +51681, 51700, -51733, -51741, -51768, -51822, -51829, -51850, -51850, -51857, -51857, +51713, +51734, +51742, +51746, +51746, +51746, +51759, +51759, +51799, +51799, +51811, +51811, +51816, +51816, +51851, +51851, 51867, -51874, -51874, -51874, -51874, -51888, -51910, -51938, -51945, -51958, -51976, -51990, -51990, +51879, +51879, +51885, +51902, +51918, +51940, +51940, +51946, +51966, +51997, 52007, -52033, -52043, -52055, -52055, -52095, -52111, -52123, -52128, -52128, -52147, -52153, -52175, -52199, -52223, -52223, -52223, -52223, -52223, -52223, -52262, -52283, -52324, -52346, -52346, -52380, -52380, +52018, +52018, +52049, +52049, +52049, +52064, +52064, +52084, +52104, +52130, +52168, +52204, +52236, +52249, +52249, +52276, +52276, +52309, +52328, +52328, +52338, +52364, +52364, +52377, 52395, -52395, -52407, -52407, -52419, -52426, -52439, -52483, -52495, -52495, -52514, -52514, -52523, -52523, -52535, -52559, -52559, -52563, -52563, -52582, -52594, -52644, -52661, -52661, -52720, -52732, -52740, -52740, -52740, -52740, -52759, -52782, -52809, -52809, -52821, -52833, -52853, -52853, -52853, -52887, -52899, -52903, -52930, -52930, -52942, -52942, -52972, -53012, -53012, -53054, +52402, +52418, +52441, +52441, +52485, +52524, +52524, +52567, +52567, +52567, +52567, +52614, +52628, +52628, +52642, +52654, +52680, +52699, +52760, +52765, +52765, +52765, +52785, +52785, +52785, +52785, +52806, +52832, +52832, +52871, +52871, +52885, +52885, +52892, +52911, +52935, +52958, +52976, +52996, +53005, +53005, +53022, +53022, +53022, 53066, -53066, -53066, -53092, -53106, +53081, +53088, +53102, +53109, +53109, +53120, 53124, -53124, -53131, -53171, -53176, -53176, -53176, -53176, -53186, -53186, -53210, -53230, -53230, -53230, -53240, -53277, -53291, -53291, -53291, -53302, -53320, -53320, -53347, -53347, -53364, -53378, -53382, -53399, -53424, -53437, -53437, -53437, -53470, -53470, -53470, -53477, -53477, -53484, -53484, -53484, -53499, -53499, -53499, -53504, -53510, -53528, -53528, -53528, -53537, -53537, -53537, -53542, +53158, +53174, +53174, +53185, +53185, +53221, +53249, +53256, +53256, +53285, +53290, +53309, +53309, +53309, +53317, +53322, +53322, +53322, +53360, +53369, +53369, +53369, +53386, +53405, +53405, +53405, +53412, +53432, +53444, +53464, +53472, +53494, +53494, +53494, +53531, 53547, -53570, -53576, -53601, -53601, +53547, +53547, +53547, +53556, +53556, +53556, +53556, +53556, +53564, +53587, 53606, -53606, -53625, -53625, -53643, -53650, -53686, -53686, -53693, -53724, -53743, -53759, -53764, -53764, +53610, +53628, +53651, +53651, +53667, +53667, +53674, +53674, +53681, +53697, +53701, +53701, +53722, +53722, +53729, +53741, +53749, +53749, +53749, +53749, +53765, 53774, -53774, -53794, -53800, -53835, -53851, -53851, -53871, -53892, -53917, -53917, -53925, -53925, -53925, -53973, -53973, -53977, +53785, +53799, +53799, +53821, +53831, +53847, +53902, +53902, +53902, +53902, +53941, +53962, +53972, +53972, 53998, -54018, -54036, -54054, -54062, -54123, -54123, -54123, -54142, -54194, -54194, -54208, +54016, +54033, +54049, +54066, +54066, +54079, +54089, +54089, +54089, +54096, +54118, +54139, +54163, +54179, +54184, +54210, 54232, -54242, -54259, -54259, -54268, -54275, -54282, -54305, -54312, -54335, -54348, -54355, -54369, -54369, -54369, -54382, -54382, -54382, -54410, -54436, -54456, -54456, -54456, -54463, -54463, -54472, -54497, -54537, +54254, +54278, +54278, +54292, +54325, +54337, +54371, +54396, +54421, +54434, +54455, +54462, +54495, +54507, +54507, +54523, +54542, +54552, +54552, +54552, +54552, +54552, +54559, +54559, 54569, -54591, -54591, -54591, -54591, -54617, -54617, -54664, -54664, -54664, -54664, -54693, -54700, -54700, -54736, -54746, -54771, -54782, -54804, -54850, -54868, -54901, -54901, -54921, -54921, -54921, -54960, -54987, -54993, -55000, -55000, -55028, +54620, +54692, +54710, +54721, +54721, +54759, +54773, +54787, +54787, +54803, +54808, +54834, +54834, +54848, +54848, +54848, +54855, +54855, +54879, +54891, +54891, +54891, +54891, +54900, +54910, +54949, +54962, +54978, +54978, +54985, +55005, +55018, 55037, +55037, +55044, +55049, +55049, +55056, 55066, -55118, -55133, -55133, -55133, -55138, -55138, -55138, -55138, -55138, -55159, -55191, -55191, -55191, -55226, -55232, -55232, -55242, -55257, -55257, -55270, -55270, -55270, -55298, -55317, -55317, -55317, -55317, -55317, -55317, -55331, -55350, -55350, -55350, +55073, +55081, +55143, +55151, +55161, +55168, +55190, +55196, +55213, +55213, +55230, +55237, +55247, +55267, +55272, +55279, +55279, +55286, +55306, +55334, +55341, +55348, +55354, 55363, -55387, -55387, -55411, -55411, -55422, -55435, -55481, -55490, +55363, +55378, +55386, +55395, +55432, +55432, +55437, +55446, +55458, +55479, 55502, -55502, -55502, -55520, +55512, +55512, 55532, -55554, -55563, -55570, -55585, -55585, -55603, -55610, -55610, -55662, -55662, -55684, -55700, -55707, -55707, -55749, -55765, -55784, -55784, -55784, -55791, -55791, -55791, -55816, -55823, -55852, -55852, -55906, -55941, -55971, -55971, -55978, -55978, -55978, -55987, -56011, -56018, -56024, -56024, -56024, -56055, -56071, -56071, -56078, -56078, -56085, -56092, -56122, -56141, -56141, -56141, -56141, -56146, -56146, -56155, -56178, -56209, -56238, -56257, -56257, -56257, -56262, -56275, -56275, -56275, -56275, -56290, -56307, -56323, -56341, -56341, -56347, -56366, -56375, -56375, -56375, -56375, -56413, -56445, -56450, -56450, -56450, -56454, +55543, +55565, +55573, +55580, +55580, +55618, +55638, +55645, +55657, +55657, +55657, +55691, +55708, +55708, +55708, +55708, +55729, +55735, +55758, +55758, +55767, +55772, +55820, +55830, +55830, +55854, +55854, +55866, +55886, +55886, +55886, +55886, +55910, +55910, +55914, +55929, +55939, +55965, +56006, +56025, +56037, +56037, +56037, +56064, +56115, +56115, +56128, +56133, +56133, +56133, +56133, +56133, +56140, +56140, +56140, +56151, +56177, +56205, +56205, +56219, +56219, +56219, +56236, +56250, +56250, +56250, +56260, +56264, +56271, +56271, +56283, +56292, +56312, +56329, +56338, +56338, +56338, +56364, +56371, +56382, +56382, +56389, +56389, +56389, +56417, +56417, +56417, +56417, +56417, +56437, +56437, +56444, 56460, -56467, -56490, -56510, -56517, -56527, -56534, -56534, -56534, -56565, -56577, -56577, -56584, -56608, -56608, -56615, -56615, -56640, -56658, -56658, -56658, -56677, -56677, -56701, -56701, -56722, -56750, -56757, -56757, -56802, -56802, -56802, -56821, -56839, -56863, -56863, +56460, +56474, +56503, +56511, +56524, +56594, +56599, +56659, +56685, +56700, +56707, +56707, +56738, +56761, +56774, +56785, +56792, +56805, +56829, +56829, +56840, +56868, +56868, +56868, +56868, 56874, 56874, -56905, -56941, -56976, -57006, -57006, -57025, -57032, -57037, -57037, -57061, -57061, -57067, -57067, -57074, -57093, -57131, +56874, +56874, +56881, +56881, +56893, +56922, +56934, +56934, +56944, +56944, +56944, +56944, +56965, +56973, +57005, +57081, +57126, 57138, -57138, -57158, -57158, -57158, -57169, -57169, -57177, -57191, -57191, -57191, -57191, -57226, -57248, -57261, -57278, -57306, -57306, -57329, -57329, -57349, -57349, -57356, -57356, -57409, -57416, -57422, -57422, -57446, -57463, -57463, -57463, -57487, -57507, -57507, -57507, -57528, -57528, -57528, -57535, -57542, -57542, -57578, -57578, -57592, -57592, -57598, -57598, -57645, +57159, +57175, +57199, +57216, +57216, +57222, +57222, +57222, +57237, +57259, +57282, +57282, +57296, +57312, +57312, +57341, +57397, +57405, +57442, +57442, +57442, +57456, +57466, +57482, +57500, +57512, +57537, +57537, +57575, +57575, +57575, +57582, +57609, +57633, 57651, -57665, -57665, -57684, -57684, -57692, -57692, -57692, -57709, -57724, -57724, -57766, -57766, -57773, -57773, -57780, -57780, -57797, -57842, -57842, -57842, -57842, -57852, -57852, -57852, +57688, +57714, +57767, +57775, +57783, +57783, +57810, +57849, +57856, 57869, -57882, -57899, -57899, -57936, -57943, -57943, -57973, -57989, -58001, -58001, -58001, -58001, -58024, -58024, -58024, -58024, -58051, -58051, -58051, -58082, -58091, -58091, -58091, -58097, -58097, -58097, -58130, -58130, -58130, -58130, -58130, -58150, -58150, -58166, -58166, -58171, -58171, -58203, -58209, -58216, -58229, -58235, -58242, -58249, -58260, -58267, -58322, -58332, -58372, -58372, -58384, -58384, -58384, -58405, -58430, -58449, -58476, -58492, -58492, -58499, -58506, -58520, -58554, -58560, -58579, -58595, -58627, -58651, -58651, -58651, +57889, +57916, +57941, +57941, +57941, +57948, +57956, +57974, +57996, +58017, +58048, +58048, +58048, +58048, +58070, +58070, +58094, +58151, +58192, +58224, +58224, +58224, +58224, +58263, +58263, +58273, +58283, +58314, +58356, +58356, +58363, +58363, +58363, +58380, +58396, +58396, +58417, +58417, +58417, +58423, +58423, +58450, +58461, +58461, +58470, +58470, +58514, +58514, +58537, +58544, +58557, +58557, +58557, +58557, +58557, +58591, +58615, +58636, +58636, 58658, 58679, 58686, 58686, 58686, -58714, -58714, -58728, -58735, -58753, -58753, -58770, -58777, -58842, -58842, -58859, -58879, -58886, -58886, -58940, -58940, -58964, -58964, -58982, -58988, -59002, -59032, -59056, -59067, -59083, -59112, -59112, -59121, -59152, -59152, +58700, +58717, +58732, +58739, +58739, +58745, +58752, +58762, +58784, +58811, +58825, +58832, +58839, +58863, +58899, +58905, +58912, +58912, +58912, +58939, +58939, +58939, +58960, +58973, +58973, +58973, +58973, +58973, +58980, +58980, +58987, +58994, +59012, +59012, +59019, +59055, +59110, +59110, +59110, +59110, +59135, +59153, +59153, 59180, -59185, -59192, -59192, -59192, -59219, -59229, -59229, -59229, -59229, -59229, -59239, -59239, -59250, -59265, -59288, -59306, -59306, -59318, -59329, -59329, -59350, -59368, -59377, -59394, -59417, +59186, +59196, +59210, +59236, +59244, +59244, +59244, +59276, +59282, +59300, +59300, +59342, +59351, +59372, +59390, +59402, +59418, 59444, -59465, -59465, -59472, -59472, -59472, -59479, -59479, -59479, -59497, -59514, -59514, -59514, -59528, -59528, -59554, -59554, -59592, -59597, -59628, -59669, -59676, -59683, -59690, -59690, -59719, -59757, -59757, -59764, +59444, +59444, +59444, +59482, +59495, +59495, +59525, +59545, +59568, +59578, +59584, +59584, +59596, +59596, +59596, +59596, +59615, +59625, +59663, +59663, +59670, +59711, +59731, +59731, +59761, 59782, -59793, -59819, -59823, -59835, -59850, -59879, -59886, -59893, -59903, -59903, -59918, -59918, -59935, -59963, -59963, -60006, -60030, -60034, -60041, -60041, -60060, -60060, -60074, -60074, -60103, -60103, -60110, -60124, -60138, -60138, -60138, -60152, -60162, -60171, -60186, -60186, -60192, -60240, -60260, -60298, -60298, -60298, -60340, -60354, -60361, -60390, -60390, -60408, -60446, -60452, -60452, -60475, -60482, -60489, -60509, -60509, -60509, -60524, -60531, -60531, -60557, -60564, -60581, -60586, -60629, -60629, -60629, -60629, -60629, -60636, -60663, -60675, -60675, -60682, -60704, -60704, -60724, -60776, -60809, -60832, -60849, -60870, -60877, -60907, -60956, -60956, -60989, +59837, +59837, +59862, +59904, +59931, +59931, +59931, +59931, +59946, +59958, +59958, +59958, +59958, +59958, +59981, +60003, +60003, +60003, +60012, +60012, +60012, +60039, +60047, +60088, +60116, +60161, +60195, +60195, +60227, +60238, +60256, +60283, +60292, +60296, +60301, +60325, +60325, +60325, +60335, +60335, +60368, +60368, +60368, +60399, +60440, +60449, +60470, +60485, +60499, +60535, +60535, +60542, +60550, +60550, +60562, +60562, +60569, +60614, +60614, +60614, +60634, +60634, +60648, +60648, +60648, +60669, +60669, +60690, +60698, +60698, +60723, +60752, +60772, +60772, +60772, +60788, +60788, +60810, +60821, +60846, +60869, +60899, +60916, +60916, +60916, +60916, +60925, +60931, +60931, +60931, +60931, +60938, +60972, +60972, +60972, +60985, +60985, 61003, -61024, -61048, -61062, -61069, -61101, -61101, -61101, -61101, -61125, -61138, -61155, -61162, -61162, -61184, -61184, -61184, -61184, -61184, -61184, -61216, -61242, -61296, -61296, -61296, -61303, -61303, -61303, -61334, -61360, -61360, -61397, -61416, -61423, -61448, -61476, -61483, -61483, +61003, +61003, +61003, +61003, +61003, +61003, +61003, +61003, +61031, +61031, +61044, +61056, +61072, +61108, +61146, +61146, +61146, +61146, +61207, +61231, +61231, +61250, +61257, +61257, +61288, +61288, +61322, +61322, +61338, +61338, +61343, +61352, +61352, +61373, +61383, +61389, +61436, +61443, +61449, +61503, +61520, +61520, +61520, +61520, 61532, -61539, -61560, -61578, -61578, -61578, -61617, -61624, +61544, +61557, +61557, +61557, +61557, +61563, +61563, +61591, +61610, 61631, -61681, -61706, -61721, -61721, -61729, -61729, -61764, -61776, -61776, -61776, -61808, -61831, -61831, -61837, -61846, -61846, +61631, +61631, +61651, +61659, +61691, +61726, +61744, +61744, +61748, +61758, +61794, +61829, +61836, +61856, +61856, 61864, -61883, -61890, -61910, -61910, -61910, -61917, -61917, -61954, -61954, -61954, -61961, -61968, -61978, -62000, -62007, -62014, -62028, -62042, -62077, -62102, -62109, -62109, -62116, -62116, -62123, -62156, -62163, -62197, -62197, -62197, -62218, -62218, -62232, -62250, -62257, -62286, -62286, -62293, -62300, -62320, -62382, -62430, -62437, -62484, -62484, -62498, -62540, -62552, -62559, -62559, -62559, -62573, -62583, -62592, -62592, -62596, -62628, -62649, -62674, -62674, -62694, -62699, -62699, -62734, +61897, +61924, +61924, +61924, +61924, +61924, +61946, +61946, +61962, +61977, +62005, +62015, +62015, +62033, +62033, +62033, +62065, +62075, +62075, +62087, +62104, +62104, +62104, +62104, +62138, +62138, +62165, +62165, +62193, +62220, +62235, +62235, +62255, +62262, +62269, +62269, +62269, +62269, +62269, +62282, +62282, +62291, +62307, +62307, +62307, +62316, +62316, +62333, +62333, +62344, +62370, +62392, +62392, +62392, +62396, +62411, +62411, +62411, +62418, +62422, +62463, +62463, +62486, +62500, +62504, +62512, +62512, +62522, +62539, +62544, +62557, +62567, +62567, +62567, +62571, +62571, +62571, +62575, +62575, +62575, +62575, +62591, +62591, +62632, +62638, +62638, +62638, +62648, +62675, +62675, +62675, +62675, +62696, +62696, +62715, +62715, +62732, 62745, -62752, -62759, -62773, -62773, -62804, -62821, -62821, -62825, -62836, -62874, +62801, +62828, +62853, +62853, +62863, +62863, +62879, 62884, -62911, -62923, -62923, -62935, -62941, -62963, -62987, -63002, -63002, +62884, +62893, +62929, +62949, +62949, +62961, +62980, +62998, +63007, +63017, 63027, -63027, -63027, -63027, -63027, -63045, -63045, -63057, -63064, -63064, -63108, -63121, -63136, -63136, -63136, -63136, -63136, -63136, -63143, -63143, -63178, -63178, -63178, -63215, -63238, -63264, -63279, -63315, -63337, -63337, -63360, -63360, -63364, -63378, -63378, -63426, -63440, -63460, -63460, -63460, -63460, +63034, +63034, +63050, +63050, +63050, +63050, +63088, +63111, +63111, +63111, +63111, +63111, +63111, +63111, +63111, +63142, +63155, +63155, +63165, +63165, +63165, +63172, +63172, +63172, +63172, +63172, +63172, +63172, +63191, +63191, +63201, +63221, +63230, +63230, +63230, +63230, +63249, +63254, +63254, +63266, +63266, +63287, +63287, +63313, +63327, +63327, +63327, +63327, +63346, +63377, +63377, +63377, +63392, +63392, +63392, +63392, +63392, +63412, +63412, +63431, +63437, +63437, 63464, -63468, -63491, -63517, -63517, -63535, -63548, -63548, -63601, -63624, -63643, -63660, -63660, -63702, -63714, -63714, -63714, -63723, -63742, -63742, -63742, -63761, -63779, -63790, -63805, -63805, -63805, +63473, +63479, +63494, +63509, +63509, +63520, +63520, +63520, +63520, +63520, +63547, +63547, +63547, +63547, +63547, +63582, +63614, +63632, +63632, +63640, +63640, +63664, +63664, +63664, +63677, +63690, +63690, +63713, +63738, +63738, +63771, +63788, +63788, +63811, +63811, +63818, +63818, +63818, +63818, +63830, 63852, -63858, -63880, -63910, -63927, -63938, -63938, -63985, -63985, -64010, -64010, -64010, -64017, -64017, -64049, -64049, -64065, -64083, -64083, -64102, -64102, -64102, -64110, -64110, -64122, -64122, -64156, -64186, -64186, +63863, +63863, +63883, +63883, +63887, +63887, +63920, +63931, +63956, +63956, +63956, +63975, +64026, +64030, +64067, +64067, +64067, +64080, +64080, +64097, +64124, +64124, +64139, +64139, +64139, +64139, +64148, +64148, +64148, +64148, +64173, 64193, -64232, -64249, -64269, -64287, -64287, -64330, -64361, -64379, -64407, -64412, -64412, -64431, -64453, -64461, -64498, -64512, -64512, -64512, -64553, -64558, -64558, -64614, +64200, +64217, +64231, +64235, +64241, +64241, +64279, +64313, +64332, +64345, +64368, +64424, +64430, +64448, +64479, +64496, +64514, +64574, +64574, +64595, +64599, +64618, +64643, 64657, -64657, -64657, -64694, -64694, -64694, -64710, -64710, -64717, -64735, -64735, -64745, -64755, -64763, -64782, -64782, -64782, -64782, -64782, -64796, -64796, -64796, -64822, -64822, -64839, -64839, -64855, -64866, +64672, +64691, +64691, +64691, +64691, +64728, +64742, +64760, +64760, +64787, +64819, +64819, +64837, +64844, +64860, 64874, -64889, -64906, -64934, -64963, -64963, -64963, -64963, -64969, -64982, -64982, -64982, -64996, -64996, -64996, -65008, -65033, -65045, -65045, -65045, -65060, -65075, -65075, -65075, -65075, -65100, -65121, -65121, +64885, +64885, +64891, +64901, +64953, +64953, +64953, +64967, +64997, +64997, +64997, +65020, +65027, +65044, +65051, +65062, +65078, +65099, +65099, +65099, 65126, -65126, -65126, -65150, -65159, -65159, -65184, -65184, -65206, -65206, -65222, -65228, -65247, -65256, -65263, -65275, -65275, -65294, +65133, +65162, +65209, +65217, +65234, +65265, +65265, +65265, +65285, +65285, +65291, +65291, +65291, 65308, -65308, -65359, -65359, -65359, -65381, -65381, -65397, -65415, -65465, -65476, -65482, -65490, -65490, +65328, +65335, +65341, +65353, +65366, +65390, +65408, +65418, +65429, +65440, +65440, +65457, +65466, 65496, -65532, -65559, -65603, +65502, +65508, +65508, +65517, +65535, +65554, +65558, +65564, +65564, +65570, +65581, 65607, -65607, -65633, -65643, -65715, -65721, -65782, -65782, -65782, -65810, -65825, -65825, -65831, -65831, -65831, -65831, -65845, -65850, -65863, -65873, -65882, -65882, -65886, -65904, -65923, -65923, -65939, -65983, -65995, -65995, -66004, -66035, -66061, -66092, -66112, -66112, -66121, -66150, -66162, -66166, -66166, -66175, -66175, -66200, -66230, -66249, -66275, -66292, -66313, -66317, -66317, -66337, -66344, -66344, -66351, +65627, +65635, +65635, +65635, +65635, +65647, +65685, +65693, +65712, +65729, +65729, +65734, +65734, +65734, +65755, +65776, +65776, +65793, +65808, +65828, +65842, +65878, +65891, +65891, +65891, +65982, +65989, +66003, +66003, +66003, +66023, +66057, +66088, +66101, +66132, +66139, +66146, +66146, +66159, +66159, +66182, +66182, +66182, +66189, +66217, +66259, +66271, +66271, +66285, +66297, +66332, +66349, +66349, 66364, 66364, -66381, -66391, -66391, -66391, -66400, -66400, -66411, -66411, -66416, -66416, -66436, -66448, -66455, -66469, -66478, -66478, -66478, -66482, -66482, -66482, -66482, -66492, -66492, -66501, -66511, -66518, -66531, -66541, -66541, -66561, -66561, -66561, -66576, -66576, -66576, -66576, -66576, -66576, -66602, -66602, -66614, -66619, -66619, -66619, -66680, -66685, -66685, -66685, -66707, -66716, -66716, -66716, -66716, -66716, -66729, -66748, -66748, -66804, -66814, -66814, -66814, -66822, -66832, -66876, -66876, -66895, -66895, -66905, -66914, -66933, -66942, -66967, -66987, -66987, -66998, +66421, +66449, +66463, +66503, +66535, +66548, +66555, +66555, +66570, +66570, +66580, +66580, +66587, +66587, +66587, +66603, +66631, +66631, +66650, +66650, +66675, +66695, +66702, +66702, +66702, +66702, +66709, +66709, +66739, +66755, +66762, +66762, +66775, +66805, +66823, +66835, +66841, +66841, +66841, +66841, +66841, +66841, +66861, +66907, +66907, +66907, +66907, +66907, +66922, +66940, +66940, +66940, +66940, +66975, +66975, +66975, +67002, 67016, -67024, -67034, -67034, -67043, -67043, -67043, -67062, -67103, -67103, -67112, -67145, -67145, -67160, -67168, -67168, -67168, -67176, -67205, -67242, -67242, -67242, -67256, -67276, -67276, -67276, -67276, -67297, -67345, -67345, -67345, -67345, -67345, -67358, -67362, -67382, -67382, -67382, -67388, -67422, -67422, -67454, -67454, -67472, -67488, -67506, -67506, -67506, -67506, -67525, -67525, -67544, -67560, -67578, -67578, -67578, -67583, -67600, -67614, -67641, -67659, -67675, -67706, +67032, +67032, +67039, +67069, +67075, +67086, +67119, +67146, +67146, +67151, +67167, +67197, +67197, +67214, +67214, +67221, +67236, +67236, +67249, +67265, +67279, +67306, +67313, +67336, +67353, +67404, +67420, +67420, +67420, +67420, +67420, +67420, +67429, +67429, +67446, +67446, +67462, +67462, +67473, +67480, +67490, +67511, +67511, +67568, +67605, +67639, +67646, +67682, +67689, +67696, +67702, +67720, 67744, -67761, -67801, -67801, -67837, -67837, -67844, -67844, -67844, -67844, -67844, -67854, -67873, -67907, -67907, -67922, -67922, -67929, -67947, -67947, -67977, -67984, -67994, -67994, -67994, -68022, -68038, -68038, -68046, -68087, -68098, -68104, -68104, -68120, -68120, -68120, -68126, -68126, -68138, -68143, -68169, -68169, -68199, -68241, -68256, -68279, -68279, -68279, +67763, +67763, +67782, +67806, +67806, +67806, +67810, +67817, +67817, +67827, +67840, +67840, +67840, +67840, +67840, +67847, +67867, +67874, +67874, +67886, +67886, +67920, +67927, +67932, +67960, +67967, +67974, +67992, +67992, +68004, +68004, +68031, +68031, +68063, +68088, +68095, +68112, +68112, +68112, +68127, +68135, +68146, +68176, +68193, +68200, +68221, +68228, +68245, +68245, +68280, +68280, 68320, -68330, -68330, -68335, -68335, -68356, -68390, -68390, -68407, -68434, -68434, +68345, +68352, +68383, +68425, +68445, +68445, 68452, -68475, -68484, -68514, -68524, -68524, -68524, -68524, -68524, -68532, -68532, -68532, -68556, -68572, -68587, -68587, -68594, -68594, -68604, -68604, -68621, -68693, -68703, -68737, -68759, -68784, -68784, -68808, -68808, -68808, -68822, -68822, -68881, -68881, -68881, +68479, +68503, +68510, +68517, +68576, +68583, +68628, +68642, +68646, +68662, +68701, +68717, +68724, +68724, +68733, +68740, +68756, +68777, +68777, +68777, +68777, +68791, +68803, +68803, +68825, +68843, +68857, +68879, +68907, +68907, +68907, 68919, -68919, -68919, -68934, -68934, -68934, -68951, -68969, -68991, -69022, -69022, -69022, -69022, -69043, -69052, -69052, -69123, -69141, -69141, -69155, -69177, -69194, -69194, -69194, -69212, -69223, -69223, -69241, -69257, -69271, -69300, -69300, -69300, -69300, -69332, -69367, -69377, -69377, -69381, -69427, -69427, -69427, -69459, -69476, -69524, -69543, -69573, -69573, -69585, -69585, -69585, +68959, +68994, +69006, +69023, +69023, +69040, +69055, +69055, +69076, +69102, +69102, +69140, +69149, +69165, +69183, +69221, +69228, +69235, +69256, +69256, +69256, +69268, +69292, +69326, +69363, +69380, +69380, +69380, +69380, +69405, +69417, +69445, +69445, +69464, +69464, +69464, +69464, +69464, +69480, +69508, +69544, +69544, +69557, +69557, +69557, +69587, 69607, -69683, -69698, -69698, -69698, -69698, -69756, -69778, -69792, -69818, -69828, -69853, -69853, -69876, +69628, +69655, +69725, +69749, +69760, +69796, +69803, +69847, +69872, +69872, 69893, -69916, -69916, -69916, -69916, -69931, -69944, -69952, -69952, -69982, -69982, -69987, -70026, -70042, -70042, -70059, -70078, -70078, -70135, -70143, -70143, -70158, -70167, -70167, -70167, -70188, -70224, -70260, -70260, -70260, -70287, -70298, -70298, -70314, -70323, -70351, -70382, -70382, -70393, -70402, -70440, -70440, -70440, -70440, -70440, -70448, -70448, -70448, -70472, -70472, -70472, -70472, +69893, +69893, +69893, +69893, +69902, +69926, +69941, +69948, +69948, +69965, +69979, +69986, +69993, +70000, +70005, +70030, +70050, +70057, +70064, +70091, +70117, +70163, +70163, +70170, +70180, +70211, +70218, +70264, +70264, +70278, +70285, +70285, +70332, +70332, +70337, +70337, +70337, +70361, +70368, +70385, +70392, +70410, +70429, +70435, +70435, +70435, +70435, +70442, +70442, +70456, +70485, 70503, -70503, -70503, -70503, -70551, -70551, -70564, -70564, -70564, -70564, -70564, +70512, +70521, +70521, +70525, +70525, +70563, +70575, +70586, +70586, +70586, +70603, 70609, -70609, -70620, -70620, -70627, -70634, -70651, -70651, -70657, -70663, -70663, -70681, -70687, -70694, -70694, -70701, -70714, -70724, -70724, -70724, -70755, -70755, -70755, -70755, -70755, -70755, -70755, -70755, -70786, -70786, -70808, -70808, -70826, -70826, -70826, -70852, -70852, -70852, -70852, -70852, -70852, -70852, -70852, -70860, -70908, -70918, -70926, -70943, -70943, -71014, -71014, -71014, -71023, -71031, -71049, -71049, -71073, -71073, -71094, -71094, -71103, -71103, -71132, -71149, -71149, -71167, +70640, +70656, +70664, +70664, +70670, +70685, +70692, +70710, +70731, +70750, +70767, +70785, +70816, +70823, +70839, +70839, +70853, +70853, +70853, +70871, +70889, +70889, +70889, +70907, +70916, +70955, +70955, +70970, +70970, +70990, +70998, +70998, +70998, +71024, +71045, +71051, +71058, +71058, +71058, +71058, +71058, +71058, +71058, +71074, +71096, +71096, +71105, +71105, +71112, +71112, +71119, +71135, +71135, +71152, +71152, +71152, +71152, +71170, 71177, -71195, -71204, -71204, -71224, -71248, -71248, -71252, -71273, -71279, -71279, -71279, -71313, -71319, -71319, -71319, -71319, -71336, -71336, -71336, -71336, -71336, -71357, -71367, -71367, -71391, -71457, -71457, -71465, -71465, +71199, +71199, +71199, +71210, +71210, +71238, +71238, +71238, +71238, +71243, +71243, +71243, +71261, +71288, +71302, +71318, +71361, +71361, +71361, +71389, +71389, +71389, +71410, +71422, +71439, +71439, +71439, +71439, +71439, +71449, +71449, +71449, 71469, -71469, -71487, -71521, -71521, -71559, -71559, -71559, -71559, -71559, -71591, -71618, -71618, -71624, -71650, -71650, -71650, -71680, -71680, -71680, -71680, -71708, -71720, +71483, +71490, +71490, +71494, +71506, +71544, +71544, +71571, +71580, +71580, +71580, +71580, +71593, +71611, +71626, +71626, +71640, +71653, +71653, +71653, +71665, +71684, +71700, 71729, -71752, -71752, -71752, -71752, -71757, -71757, -71793, -71805, -71805, -71805, -71805, -71805, -71805, -71805, -71810, -71810, -71820, -71840, -71888, -71911, -71911, -71921, -71932, -71968, -71992, -71992, -72002, -72002, -72002, -72013, -72013, +71729, +71729, +71729, +71741, +71741, +71748, +71809, +71818, +71818, +71836, +71876, +71926, +71946, +71946, +71946, +71946, +71946, +71971, +71984, +71984, +71994, +72010, +72010, +72010, +72010, +72010, +72010, 72035, -72046, -72074, -72099, -72099, -72135, -72135, -72135, -72145, -72202, -72202, -72202, -72227, -72234, +72079, +72079, +72102, +72129, +72138, +72151, +72151, +72151, +72151, +72162, +72162, +72166, +72166, +72166, +72175, +72175, +72175, +72191, +72191, +72191, +72191, +72191, +72191, 72242, -72247, -72255, -72255, -72255, -72277, -72277, -72277, -72284, -72284, -72329, +72242, +72242, +72248, +72264, +72282, +72290, +72308, +72324, 72345, -72382, -72382, -72382, -72393, +72345, +72345, +72345, +72351, +72370, +72370, +72401, +72401, 72407, 72407, -72428, -72436, -72436, -72467, -72495, -72495, -72504, -72504, -72504, -72526, -72553, +72407, +72407, +72435, +72453, +72453, +72453, +72468, +72486, +72506, +72512, +72512, +72537, +72537, +72556, +72567, 72579, -72585, 72601, -72640, -72650, -72656, -72661, -72661, -72669, -72688, -72688, -72688, -72730, -72743, -72743, -72764, -72779, -72803, -72813, -72813, -72813, -72825, -72825, -72857, -72866, -72895, -72895, -72934, -72969, -72969, -72969, -72969, -73020, -73020, -73033, -73046, -73057, -73057, -73057, -73069, -73078, -73082, -73082, -73109, -73129, -73174, -73180, -73180, -73180, -73186, -73186, -73196, -73196, -73196, -73212, -73230, -73230, -73254, -73260, -73260, -73274, -73281, -73311, -73311, -73311, -73337, -73368, -73381, +72613, +72619, +72625, +72625, +72631, +72637, +72667, +72680, +72692, +72692, +72692, +72710, +72720, +72720, +72733, +72733, +72741, +72741, +72752, +72765, +72771, +72771, +72771, +72771, +72785, +72785, +72807, +72807, +72827, +72834, +72843, +72878, +72878, +72892, +72901, +72901, +72901, +72906, +72916, +72916, +72916, +72927, +72927, +72927, +72927, +72963, +72963, +72963, +72963, +72963, +72963, +72985, +73029, +73044, +73064, +73064, +73064, +73064, +73064, +73064, +73073, +73073, +73093, +73120, +73126, +73144, +73144, +73159, +73159, +73165, +73165, +73203, +73213, +73238, +73258, +73273, +73273, +73273, +73273, +73273, +73287, +73303, +73335, +73359, +73365, +73387, 73402, -73435, -73456, -73456, -73456, -73456, -73472, -73472, -73488, -73488, -73488, -73488, -73488, -73488, +73402, +73402, +73413, +73413, +73413, +73423, +73442, +73468, +73485, +73485, 73503, -73522, -73522, -73522, -73530, -73530, -73559, -73616, -73637, -73662, -73685, -73700, -73700, -73711, -73745, -73755, -73790, -73815, -73815, -73815, -73815, -73821, -73844, -73867, -73883, -73907, -73907, -73942, -73974, -73974, -73974, -74007, -74026, -74043, -74043, -74057, -74063, -74079, -74079, -74102, -74102, -74102, -74125, -74136, -74136, -74136, -74136, -74158, -74164, -74164, -74164, -74172, -74188, -74188, -74210, -74246, -74256, -74256, -74256, -74264, -74300, -74312, -74320, -74328, -74360, -74360, +73537, +73575, +73575, +73610, +73629, +73635, +73635, +73635, +73635, +73658, +73658, +73681, +73687, +73687, +73712, +73736, +73753, +73780, +73797, +73816, +73838, +73850, +73850, +73863, +73909, +73918, +73930, +73946, +73976, +73986, +73986, +73986, +73986, +73990, +74017, +74017, +74017, +74025, +74025, +74025, +74025, +74055, +74073, +74073, +74073, +74084, +74095, +74095, +74095, +74123, +74150, +74150, +74155, +74155, +74155, +74155, +74161, +74170, +74176, +74193, +74216, +74224, +74266, +74266, +74277, +74277, +74289, +74289, +74295, +74330, +74330, +74342, +74348, 74383, -74389, -74401, -74413, -74430, -74430, -74430, -74460, -74486, -74486, -74486, -74486, -74486, -74510, -74531, -74531, -74561, -74601, -74620, -74631, -74631, -74674, -74674, -74684, -74684, -74695, -74710, -74710, -74719, -74748, -74773, -74781, -74789, -74789, -74809, -74809, -74809, -74825, -74845, -74845, -74857, -74891, -74891, -74891, -74891, -74891, +74420, +74420, +74426, +74426, +74451, +74469, +74483, +74500, +74500, +74515, +74520, +74520, +74537, +74547, +74547, +74547, +74558, +74558, +74571, +74578, +74590, +74590, +74603, +74619, +74628, +74628, +74634, +74634, +74634, +74655, +74667, +74691, +74702, +74725, +74725, +74725, +74725, +74730, +74730, +74730, +74730, +74736, +74758, +74764, +74764, +74764, +74764, +74784, +74803, +74803, +74832, +74832, +74856, +74867, +74867, +74885, +74890, +74890, +74910, 74925, 74925, -74925, -74943, -74988, -75011, -75011, -75011, -75011, -75011, -75021, -75021, -75037, -75037, -75064, -75097, -75102, -75102, -75140, -75140, -75158, -75158, -75172, -75172, -75193, -75193, -75212, -75227, -75245, -75256, -75272, +74939, +74939, +74954, +74963, +74989, +74996, +74996, +75013, +75013, +75013, +75042, +75059, +75067, +75108, +75128, +75136, +75155, +75160, +75160, +75173, +75173, +75173, +75173, +75179, +75179, +75190, +75213, +75217, +75236, +75236, +75265, +75265, 75283, -75293, -75308, -75315, -75315, -75341, -75356, -75367, -75397, -75397, -75453, -75471, -75471, -75471, -75485, -75534, -75534, -75534, -75545, -75551, -75551, -75551, -75564, -75576, -75609, -75621, -75638, -75671, -75681, -75696, -75702, -75702, -75714, -75714, -75721, -75736, -75736, -75743, +75294, +75311, +75311, +75317, +75317, +75325, +75345, +75370, +75370, +75382, +75382, +75382, +75411, +75417, +75434, +75443, +75449, +75455, +75478, +75484, +75517, +75542, +75548, +75561, +75561, +75567, +75573, +75573, +75579, +75579, +75593, +75593, +75593, +75593, +75599, +75615, +75651, +75685, +75692, +75713, +75719, +75725, +75737, +75746, +75750, +75750, 75761, -75770, -75778, -75778, -75778, -75778, -75778, -75805, -75805, -75823, -75834, -75840, -75857, -75893, -75893, -75893, -75893, -75893, +75783, +75789, +75804, +75814, +75814, +75814, +75833, +75833, +75867, +75867, +75867, +75867, 75904, +75909, +75928, +75928, +75928, +75928, +75928, 75945, -75945, -75958, -75958, -75958, -75977, -76016, -76031, -76037, -76037, -76051, -76051, -76079, -76084, -76084, -76102, +75959, +75973, +75973, +75995, +76066, +76066, +76066, +76082, +76082, +76082, +76098, +76109, 76120, 76120, 76120, -76120, -76134, -76166, -76175, -76205, -76216, -76216, -76227, -76244, -76275, -76284, -76318, -76337, -76343, -76389, -76389, -76389, -76389, -76402, -76416, -76416, -76434, -76434, -76444, -76497, -76497, -76509, -76519, -76566, -76604, -76611, -76611, -76611, -76640, -76654, -76654, -76654, -76654, -76671, -76671, -76676, -76676, -76697, -76697, -76697, -76697, -76707, -76751, -76751, -76751, -76774, -76778, -76807, -76807, -76807, -76830, -76830, -76848, +76129, +76149, +76170, +76170, +76170, +76170, +76170, +76186, +76199, +76199, +76199, +76218, +76235, +76249, +76261, +76300, +76305, +76328, +76342, +76366, +76366, +76399, +76413, +76413, +76413, +76431, +76437, +76459, +76459, +76475, +76475, +76475, +76475, +76475, +76475, +76482, +76493, +76493, +76501, +76501, +76515, +76532, +76532, +76544, +76544, +76578, +76603, +76603, +76612, +76628, +76644, +76657, +76666, +76705, +76705, +76730, +76730, +76740, +76740, +76757, +76804, +76816, +76832, +76832, +76832, +76832, +76847, 76864, -76897, -76913, -76932, -76932, -76944, -76970, -76986, -76986, -77002, -77017, -77022, -77039, -77049, -77049, -77049, -77067, -77067, -77067, -77081, -77081, -77081, -77089, -77089, -77105, -77121, -77121, -77156, -77156, -77156, -77156, -77156, -77165, -77173, -77173, -77173, -77173, -77191, -77211, -77211, -77211, -77218, -77242, +76871, +76881, +76881, +76917, +76929, +76929, +76938, +76938, +76938, +76938, +76960, +76979, +77000, +77041, +77058, +77058, +77066, +77084, +77084, +77084, +77106, +77122, +77122, +77122, +77122, +77143, +77152, +77152, +77152, +77158, +77158, +77158, +77158, +77158, +77158, +77171, +77183, +77183, +77188, +77188, +77188, +77188, +77188, +77204, +77204, +77227, +77251, +77251, +77251, +77270, 77290, -77308, -77308, -77325, -77343, -77343, -77376, -77376, -77376, -77376, -77386, -77386, -77386, -77386, +77290, +77290, +77290, +77311, +77327, +77327, +77341, +77341, +77358, +77358, +77358, 77393, -77399, -77419, -77428, -77450, +77393, +77400, +77407, +77407, +77436, 77450, +77464, +77464, 77492, 77492, -77492, -77492, -77529, -77529, -77529, -77540, -77540, -77540, -77557, -77570, -77570, -77570, -77570, -77570, -77570, -77587, -77597, +77508, +77508, +77533, +77545, +77545, +77556, +77578, +77593, +77610, 77620, -77640, -77640, -77640, -77661, -77680, -77680, -77680, -77680, -77680, -77680, -77712, -77732, -77739, -77739, -77739, -77748, -77765, -77824, -77824, -77834, -77850, -77860, -77860, -77872, -77872, -77889, -77889, -77889, -77902, -77920, -77934, -77962, -77982, -77982, -77982, -77982, -78000, -78000, -78000, -78009, -78025, -78036, -78036, -78043, -78043, -78062, -78072, -78123, -78153, -78167, -78189, -78211, -78211, -78211, -78222, -78222, -78222, -78230, -78230, -78236, -78236, -78236, -78236, -78254, -78254, -78254, -78254, -78254, -78272, -78296, -78313, -78332, -78368, -78384, -78394, -78404, -78411, -78423, -78444, -78451, -78464, -78485, -78501, -78501, -78514, -78514, -78514, -78514, -78523, -78532, -78544, -78544, -78544, -78544, -78544, -78544, -78555, -78575, -78612, -78612, -78641, -78672, -78678, -78678, -78705, -78705, -78720, -78737, -78737, -78753, -78753, -78757, -78778, -78778, -78778, -78819, -78837, -78837, -78837, -78843, -78843, -78853, -78869, -78869, -78908, -78908, -78908, -78908, -78908, -78913, -78958, -78958, -78958, -78969, -78990, -79019, -79019, -79025, -79025, -79025, -79059, -79079, -79079, -79079, -79086, -79086, -79102, -79102, -79102, -79109, -79109, -79109, -79109, -79109, -79109, -79109, -79109, -79109, -79123, -79136, -79155, +77657, +77657, +77693, +77693, +77693, +77693, +77705, +77705, +77705, +77718, +77718, +77734, +77742, +77742, +77781, +77789, +77819, +77830, +77830, +77830, +77830, +77830, +77847, +77870, +77870, +77904, +77904, +77916, +77916, +77942, +77958, +77958, +77958, +77972, +77972, +77972, +77988, +77988, +77994, +78017, +78031, +78044, +78089, +78099, +78129, +78129, +78129, +78129, +78135, +78140, +78155, +78176, +78214, +78235, +78243, +78277, +78277, +78277, +78285, +78312, +78312, +78328, +78339, +78357, +78373, +78389, +78389, +78414, +78432, +78439, +78455, +78484, +78492, +78500, +78536, +78556, +78582, +78582, +78615, +78624, +78664, +78664, +78675, +78675, +78694, +78694, +78709, +78715, +78715, +78724, +78724, +78733, +78733, +78766, +78766, +78780, +78791, +78812, +78812, +78812, +78821, +78865, +78865, +78865, +78865, +78890, +78890, +78890, +78890, +78911, +78911, +78911, +78933, +78943, +78943, +78943, +78943, +78943, +78978, +78986, +78986, +78997, +79027, +79047, +79047, +79078, +79078, +79093, +79093, +79093, +79093, +79093, +79131, +79131, +79152, +79152, +79152, 79180, 79180, -79187, -79187, -79187, -79187, -79217, -79217, -79249, -79249, +79180, +79180, +79202, +79202, +79202, +79221, +79221, +79227, +79233, +79241, +79260, +79260, +79260, 79266, -79266, -79278, +79274, +79274, 79288, -79288, -79302, -79311, -79311, -79341, -79357, -79357, -79364, -79382, -79395, -79395, -79395, -79395, -79408, -79427, -79444, -79444, -79464, -79484, -79484, -79491, +79303, +79319, +79351, +79374, +79374, +79380, +79390, +79390, +79390, +79396, +79416, +79416, +79426, +79426, +79426, +79443, +79453, +79453, +79472, +79503, +79503, +79508, 79514, -79526, -79526, -79539, -79571, -79571, -79591, -79626, -79626, -79626, -79656, -79656, -79671, -79671, -79671, -79685, -79685, -79697, -79705, -79722, -79748, -79773, -79773, -79802, -79802, -79802, -79808, -79808, -79818, -79818, -79841, -79841, -79841, +79530, +79540, +79540, +79548, +79563, +79584, +79636, +79645, +79675, +79682, +79682, +79715, +79725, +79754, +79754, +79774, +79793, +79793, +79816, +79816, +79816, +79831, +79831, 79850, -79850, -79850, -79850, -79850, -79859, -79859, -79876, -79876, -79906, -79927, -79952, -79963, -79974, -79980, -79996, -79996, -79996, -79996, +79867, +79867, +79867, +79867, +79875, +79896, +79896, +79896, +79896, +79922, +79922, +79922, +79934, +79934, +79947, +79964, +79964, +80000, 80014, 80014, -80014, -80014, -80014, -80014, -80014, -80044, -80067, -80074, -80090, -80090, -80090, -80090, -80090, -80090, -80123, -80132, -80137, -80152, -80152, -80177, -80194, -80211, -80211, -80231, -80248, -80269, +80025, +80025, +80037, +80071, +80105, +80105, +80111, +80161, +80171, +80181, +80197, +80217, +80227, +80227, +80227, +80252, +80264, 80276, -80276, -80283, 80293, -80310, -80310, -80315, -80332, -80352, -80352, -80404, -80415, -80432, -80464, -80492, -80524, -80534, -80541, -80581, -80581, -80588, -80588, -80601, -80618, -80618, -80634, -80652, -80675, -80675, -80682, -80682, -80682, -80682, -80682, -80682, -80704, -80733, -80733, -80749, -80796, -80796, -80812, -80812, -80819, -80819, -80829, -80862, -80885, -80909, -80917, -80917, +80293, +80293, +80293, +80293, +80333, +80339, +80353, +80380, +80421, +80484, +80484, +80484, +80498, +80543, +80543, +80569, +80569, +80578, +80578, +80595, +80616, +80616, +80623, +80631, +80631, +80631, +80649, +80649, +80649, +80649, +80659, +80686, +80703, +80710, +80726, +80741, +80741, +80764, +80764, +80764, +80783, +80799, +80799, +80799, +80833, +80833, +80872, +80872, +80872, +80899, +80916, +80916, 80937, -80951, -80951, -80974, -80992, -81014, -81032, -81032, -81032, -81032, -81061, -81069, -81106, -81106, -81111, -81111, -81167, -81201, -81219, -81219, -81219, -81266, -81266, -81280, -81280, -81280, -81287, -81308, -81314, -81336, -81354, -81360, -81360, -81360, -81389, -81410, -81410, -81410, -81410, -81418, -81437, +80937, +80937, +80937, +80937, +80947, +80947, +80965, +80965, +80977, +80977, +80986, +80986, +80986, +81006, +81013, +81013, +81023, +81048, +81066, +81066, +81097, +81107, +81118, +81118, +81118, +81140, +81175, +81187, +81187, +81187, +81192, +81192, +81192, +81212, +81240, +81240, +81298, +81298, +81298, +81298, +81310, +81316, +81316, +81327, +81335, +81335, +81342, +81359, +81359, +81359, +81359, +81370, +81370, +81370, +81381, +81395, +81405, +81413, +81447, +81447, 81460, 81460, -81485, -81497, -81513, -81525, -81525, -81532, -81543, -81543, -81558, +81471, +81471, +81476, +81495, +81510, +81510, +81526, +81526, +81553, +81571, +81587, +81587, 81592, -81592, -81613, -81613, -81630, -81637, -81680, -81727, -81727, -81727, -81727, -81732, -81732, -81732, -81732, +81611, +81638, +81638, +81664, +81690, +81696, +81696, +81696, +81721, +81721, 81739, 81739, -81751, -81758, -81758, -81778, -81778, -81785, -81785, -81808, -81830, -81830, -81838, +81739, +81749, +81766, +81773, +81773, +81773, +81791, +81791, +81815, +81839, +81846, 81855, -81868, -81885, -81885, -81892, -81892, -81905, -81905, -81921, -81934, -81959, -81959, -81966, -82004, +81855, +81855, +81879, +81903, +81915, +81939, +81939, +81965, +81985, 82004, 82004, 82021, -82021, -82048, -82048, -82048, -82070, -82093, -82114, -82114, -82114, -82136, -82160, -82182, -82182, -82191, -82198, -82198, -82211, -82245, -82280, -82287, -82287, -82287, -82287, -82308, -82308, -82308, -82315, -82336, -82336, -82336, -82336, -82365, -82375, -82375, -82375, -82375, -82382, -82382, -82417, -82433, -82440, -82474, -82488, -82531, -82531, -82552, -82563, -82581, -82597, -82597, -82613, -82634, -82648, -82654, -82661, -82661, -82661, -82668, -82675, -82690, -82696, +82037, +82082, +82082, +82115, +82154, +82161, +82169, +82169, +82207, +82223, +82233, +82233, +82233, +82233, +82249, +82249, +82249, +82264, +82270, +82283, +82309, +82340, +82353, +82380, +82380, +82400, +82425, +82456, +82462, +82462, +82481, +82481, +82499, +82499, +82499, +82499, +82499, +82499, +82499, +82512, +82547, +82564, +82607, +82607, +82607, +82620, +82629, +82629, +82629, +82640, +82640, +82664, +82664, +82664, +82664, +82664, +82674, +82689, +82689, +82689, +82689, 82703, -82717, +82703, +82703, +82719, 82724, -82752, -82752, -82772, -82788, -82795, -82802, -82814, -82837, -82858, -82865, -82888, -82895, -82929, -82948, -82960, -82967, -82981, -82981, -82996, -83015, -83031, -83038, -83045, -83081, -83100, -83149, -83182, -83182, -83206, -83213, -83236, -83236, -83243, -83243, -83249, -83261, -83268, -83268, +82741, +82750, +82750, +82757, +82809, +82821, +82821, +82821, +82821, +82833, +82833, +82863, +82863, +82879, +82898, +82906, +82906, +82923, +82923, +82942, +82942, +82966, +83020, +83020, +83044, +83044, +83067, +83067, +83105, +83105, +83122, +83143, +83161, +83178, +83194, +83210, +83210, +83210, +83210, +83210, +83232, 83292, -83306, -83328, -83328, -83354, -83361, -83395, -83401, -83415, -83425, -83448, -83454, -83481, -83510, -83558, -83565, +83309, +83323, +83357, +83357, +83406, +83406, +83406, +83406, +83453, +83468, +83487, +83513, +83513, +83513, +83519, +83567, +83580, 83591, -83607, -83617, -83645, -83658, -83665, -83682, -83682, -83682, -83699, -83733, -83743, -83797, -83813, -83829, +83606, +83616, +83653, +83653, +83670, +83684, +83684, +83684, +83684, +83684, +83695, +83714, +83714, +83714, +83759, +83759, +83759, +83759, +83759, +83759, +83791, +83791, +83791, +83791, +83791, +83791, +83791, +83799, +83799, +83812, +83812, +83822, +83822, +83837, +83837, +83837, +83837, 83843, -83855, -83859, -83873, -83873, -83873, -83889, -83904, -83945, -83974, -84021, -84021, -84081, -84092, -84106, -84123, -84140, -84212, -84212, -84212, -84212, -84241, -84248, -84255, -84255, -84262, -84282, -84308, -84308, -84308, -84317, -84317, -84331, -84360, -84384, -84401, +83843, +83861, +83861, +83861, +83874, +83888, +83936, +83936, +83950, +83950, +83950, +83963, +83963, +83970, +83995, +83995, +84018, +84040, +84040, +84040, +84040, +84053, +84053, +84074, +84105, +84115, +84154, +84177, +84194, +84211, +84211, +84211, +84211, +84229, +84229, +84245, +84266, +84278, +84285, +84285, +84285, +84285, +84285, +84285, +84285, +84323, +84348, +84368, +84368, +84368, +84368, +84388, +84388, +84388, +84388, +84388, +84388, 84408, -84455, -84488, -84488, -84530, -84551, -84577, -84577, -84586, -84593, -84612, -84619, -84619, -84666, +84421, +84426, +84433, +84433, +84433, +84433, +84433, +84449, +84472, +84472, +84472, +84472, +84492, +84492, +84499, +84499, +84506, +84506, +84524, +84567, +84585, +84585, +84585, +84585, +84585, +84585, +84608, +84608, +84618, +84618, +84618, +84650, +84670, +84670, 84682, -84697, -84714, -84766, -84766, -84766, -84766, -84778, -84792, -84799, -84799, -84799, -84805, -84817, -84842, -84842, -84842, -84849, -84864, -84876, -84930, -84936, -84936, -84948, -84960, -84960, -84960, -84983, -84996, -85003, -85011, -85046, -85066, -85111, -85127, -85149, -85165, -85210, -85229, -85229, -85229, -85235, -85235, -85253, -85266, -85285, -85299, -85329, -85343, -85361, -85379, -85413, -85413, -85446, -85453, -85482, -85492, -85514, -85521, -85521, -85521, -85561, -85568, -85585, -85599, -85654, -85671, -85685, -85699, -85699, -85699, -85699, -85699, -85709, -85734, -85734, -85748, -85748, -85771, -85787, -85787, -85820, -85830, -85830, -85837, -85837, -85837, -85860, -85921, -85944, -85944, -85962, -85968, -85982, -86007, -86014, -86019, -86034, -86054, -86061, -86074, -86112, -86119, -86125, -86144, -86163, -86163, -86170, -86202, -86253, -86310, -86310, -86337, -86344, -86361, -86376, -86410, -86428, -86428, -86444, -86456, -86456, -86456, -86474, -86492, -86500, -86500, -86528, -86528, -86541, -86541, -86562, -86582, -86602, +84682, +84689, +84699, +84699, +84709, +84709, +84709, +84709, +84709, +84709, +84709, +84724, +84733, +84733, +84741, +84741, +84776, +84776, +84776, +84795, +84825, +84834, +84834, +84841, +84851, +84861, +84871, +84871, +84882, +84882, +84892, +84927, +84932, +84966, +84984, +84984, +85015, +85039, +85051, +85088, +85088, +85088, +85088, +85108, +85134, +85163, +85163, +85163, +85174, +85180, +85198, +85198, +85198, +85198, +85230, +85257, +85257, +85278, +85278, +85278, +85278, +85324, +85365, +85377, +85414, +85420, +85436, +85465, +85490, +85490, +85501, +85501, +85529, +85553, +85553, +85560, +85560, +85571, +85571, +85571, +85571, +85571, +85571, +85598, +85598, +85598, +85620, +85649, +85649, +85664, +85664, +85675, +85687, +85687, +85687, +85687, +85687, +85687, +85705, +85705, +85717, +85755, +85755, +85765, +85765, +85784, +85784, +85784, +85818, +85848, +85873, +85904, +85954, +85954, +85967, +85974, +85983, +86022, +86030, +86050, +86050, +86050, +86050, +86087, +86087, +86087, +86099, +86099, +86109, +86127, +86150, +86161, +86187, +86187, +86205, +86217, +86236, +86243, +86254, +86254, +86254, +86270, +86270, +86282, +86295, +86304, +86332, +86332, +86332, +86332, +86343, +86343, +86343, +86343, +86343, +86354, +86354, +86354, +86354, +86354, +86354, +86372, +86377, +86398, +86398, +86421, +86427, +86427, +86427, +86427, +86432, +86454, +86468, +86468, +86482, +86482, +86487, +86498, +86512, +86512, +86535, +86544, +86577, 86615, -86615, -86615, -86645, -86645, -86666, -86692, -86720, -86727, -86734, +86651, +86672, +86672, +86672, +86698, +86698, +86721, +86721, 86757, -86781, -86801, -86801, -86801, -86823, -86853, -86853, -86870, -86889, -86895, -86895, +86757, +86757, +86778, +86789, +86789, +86789, +86809, +86833, +86833, +86845, +86867, +86867, +86867, 86895, 86920, -86927, -86939, -86957, -86981, -86988, -87009, -87044, -87044, -87075, -87108, -87129, -87146, -87158, -87176, -87183, -87213, -87266, -87284, -87284, -87291, -87307, -87307, -87312, -87339, -87339, -87346, -87353, -87385, -87419, -87419, +86920, +86920, +86920, +86982, +86982, +87000, +87006, +87067, +87067, +87067, +87067, +87077, +87077, +87085, +87090, +87106, +87106, +87112, +87112, +87112, +87118, +87127, +87127, +87127, +87143, +87143, +87143, +87143, +87155, +87155, +87168, +87168, +87182, +87182, +87188, +87188, +87188, +87188, +87188, +87204, +87215, +87236, +87236, +87236, +87248, +87257, +87274, +87282, +87297, +87297, +87297, +87297, +87302, +87321, +87341, +87341, +87367, +87367, +87373, +87379, +87387, +87406, +87406, +87406, +87412, +87426, 87441, -87448, -87470, -87503, -87503, -87509, -87509, -87537, -87561, -87580, -87580, -87625, -87632, -87644, -87656, -87656, -87656, -87656, -87656, -87696, -87713, -87713, -87713, -87713, -87713, -87713, +87441, +87441, +87449, +87458, +87458, +87458, +87467, +87476, +87541, +87541, +87541, +87541, +87577, +87583, +87583, +87612, +87612, +87620, +87626, +87639, +87639, +87639, +87661, +87671, +87686, +87707, +87707, +87707, 87738, -87746, -87753, -87753, -87785, -87800, -87811, -87823, +87738, +87759, +87770, +87780, +87797, +87797, +87810, +87810, +87819, 87833, -87833, -87844, -87844, -87859, -87878, -87878, -87889, -87920, -87925, -87945, -87945, -87945, -87964, -87974, -87974, -87974, -87980, -87996, -87996, -87996, -87996, -88015, -88015, -88037, -88037, -88042, -88054, -88063, -88070, -88084, -88084, -88116, +87841, +87869, +87869, +87869, +87869, +87885, +87885, +87899, +87912, +87929, +87941, +87955, +87970, +87984, +87984, +88000, +88026, +88026, +88026, +88026, +88036, +88051, +88061, +88104, +88114, +88114, 88125, 88125, 88125, -88125, -88164, -88164, -88179, -88179, -88193, -88193, -88237, -88237, -88237, -88237, -88237, -88237, -88261, -88270, -88282, -88293, -88293, -88310, -88323, -88345, -88365, -88385, -88385, -88385, -88385, -88385, -88403, -88403, -88418, -88418, -88418, -88453, -88473, -88483, -88498, -88508, -88508, -88529, -88539, -88550, -88550, -88550, -88558, -88581, -88596, -88596, -88596, -88596, -88596, -88596, -88596, +88132, +88161, +88166, +88178, +88178, +88178, +88178, +88208, +88213, +88213, +88220, +88227, +88227, +88244, +88260, +88260, +88266, +88291, +88297, +88297, +88297, +88334, +88334, +88366, +88398, +88415, +88432, +88442, +88456, +88478, +88520, +88520, +88520, +88569, 88617, -88641, -88650, -88678, -88678, -88678, -88700, -88700, -88714, -88756, -88762, -88773, -88828, -88855, -88861, -88861, -88892, -88952, -88962, -88962, -88962, -88968, -88993, -88993, -89003, -89033, -89033, -89078, -89086, -89091, -89102, -89102, -89127, -89138, -89138, -89155, -89166, -89188, -89188, -89205, -89211, -89211, -89211, -89221, -89221, -89268, +88626, +88632, +88632, +88649, +88661, +88661, +88693, +88705, +88705, +88705, +88705, +88705, +88712, +88734, +88779, +88779, +88779, +88785, +88785, +88800, +88817, +88817, +88824, +88824, +88868, +88868, +88868, +88868, +88868, +88913, +88936, +88977, +88990, +89019, +89025, +89044, +89068, +89068, +89085, +89085, +89085, +89085, +89131, +89143, +89143, +89158, +89168, +89197, +89202, +89202, +89207, +89278, 89290, -89303, -89316, +89309, +89319, 89324, -89383, +89324, +89344, +89354, +89354, +89386, 89393, -89404, -89421, -89437, -89466, -89466, -89502, -89502, -89515, +89405, +89430, +89430, +89430, +89438, +89438, +89489, +89496, +89511, +89529, 89545, -89580, -89586, -89586, -89586, -89591, -89591, -89620, -89633, -89649, -89654, -89694, -89694, -89706, -89706, -89706, -89721, -89721, -89727, -89727, -89727, -89756, -89756, -89756, -89763, +89563, +89569, +89569, +89569, +89592, +89598, +89598, +89598, +89653, +89659, +89659, +89669, +89669, +89690, +89714, +89722, +89732, +89776, +89776, +89776, 89782, -89782, -89804, -89804, -89826, -89826, -89831, -89840, -89847, +89795, +89795, +89795, +89795, +89813, +89824, +89824, +89841, +89848, +89848, +89848, 89858, -89885, -89885, -89885, -89920, -89942, -89949, -89949, -89949, -89959, -89971, -89978, -89984, -89984, -89999, -90035, -90053, -90064, -90075, -90083, -90083, -90083, -90101, -90101, -90116, -90116, -90150, -90157, -90157, -90157, -90168, -90205, -90205, -90212, -90212, -90242, -90274, -90280, -90292, -90302, -90302, -90302, -90309, -90309, -90321, -90327, -90343, -90399, -90426, -90435, -90435, -90453, -90459, -90459, -90476, -90476, -90482, +89858, +89891, +89891, +89918, +89928, +89928, +89947, +89977, +89977, +89977, +89977, +89998, +90025, +90025, +90065, +90071, +90086, +90086, +90086, +90104, +90104, +90136, +90163, +90163, +90163, +90163, +90169, +90194, +90194, +90194, +90194, +90207, +90224, +90247, +90256, +90256, +90262, +90275, +90275, +90293, +90303, +90303, +90303, +90361, +90376, +90417, +90428, +90452, +90491, 90502, -90502, -90502, -90522, -90522, -90536, -90563, -90563, -90583, -90583, -90583, -90604, -90604, -90610, -90610, -90610, -90610, -90629, -90629, -90654, -90663, -90669, -90690, -90699, -90699, -90699, -90729, -90752, -90752, -90758, -90758, -90774, -90780, -90825, -90845, -90857, -90857, -90857, -90857, -90873, -90905, -90905, -90905, -90920, -90920, -90920, -90963, -90969, +90509, +90515, +90538, +90564, +90594, +90638, +90638, +90638, +90638, +90659, +90668, +90683, +90691, +90698, +90706, +90724, +90735, +90770, +90770, +90778, +90778, +90795, +90795, +90795, +90795, +90831, +90831, +90869, +90883, +90901, +90907, +90913, +90929, +90929, +90959, +90977, 90987, -90987, -90987, -91004, -91023, -91029, -91029, -91061, -91061, -91061, -91067, -91073, -91093, -91093, -91093, -91101, -91126, -91126, -91126, -91126, -91131, -91178, -91185, -91195, -91216, +91007, +91019, +91033, +91039, +91104, +91104, +91110, +91110, +91110, +91124, +91130, +91136, +91157, +91163, +91163, +91169, +91209, +91209, +91225, +91225, +91225, +91225, 91241, -91268, -91268, -91268, -91278, -91288, -91297, -91297, -91297, -91314, -91320, -91320, -91320, -91328, -91328, -91345, -91365, -91365, -91365, -91365, -91386, -91422, -91449, -91458, -91495, -91533, -91551, -91579, -91579, -91579, -91624, -91631, -91631, -91631, -91639, -91657, -91688, -91709, -91709, -91709, -91709, -91709, -91709, -91709, -91715, -91743, -91777, -91777, -91800, -91817, -91817, -91848, -91848, -91858, -91858, -91867, -91884, -91884, -91900, -91900, -91900, -91913, -91919, -91926, -91934, -91947, -91947, -91947, -91965, -91965, -91965, -91972, -91982, -92009, -92036, +91241, +91253, +91273, +91273, +91283, +91304, +91310, +91337, +91354, +91354, +91354, +91354, +91368, +91381, +91381, +91416, +91435, +91441, +91441, +91441, +91441, +91441, +91463, +91489, +91504, +91504, +91520, +91520, +91520, +91566, +91566, +91576, +91576, +91594, +91599, +91599, +91610, +91610, +91619, +91635, +91641, +91675, +91683, +91683, +91683, +91683, +91683, +91683, +91683, +91683, +91749, +91749, +91749, +91749, +91760, +91809, +91814, +91814, +91814, +91824, +91824, +91835, +91847, +91865, +91879, +91891, +91935, +91935, +91955, +91986, +91996, +91996, +91996, +92023, 92057, -92068, -92068, -92093, -92107, -92114, -92120, -92206, -92218, -92218, -92218, -92218, -92233, -92233, -92290, -92303, -92303, -92315, -92315, -92315, -92326, -92339, -92360, -92360, -92372, -92372, -92387, -92387, -92387, -92407, -92431, -92453, -92453, -92453, -92471, -92494, -92494, -92515, -92539, -92557, -92557, -92562, -92573, -92573, -92595, -92601, -92633, -92633, -92633, -92675, -92706, -92706, -92723, -92729, -92729, -92745, -92745, -92760, -92760, -92806, -92831, -92844, -92844, -92850, -92850, -92856, -92856, -92881, -92913, +92057, +92062, +92103, +92111, +92117, +92117, +92117, +92117, +92117, +92117, +92117, +92136, +92157, +92192, +92203, +92203, +92223, +92223, +92241, +92241, +92241, +92241, +92241, +92281, +92319, +92329, +92329, +92351, +92358, +92358, +92358, +92371, +92390, +92404, +92410, +92410, +92423, +92423, +92449, +92491, +92532, +92532, +92540, +92546, +92552, +92572, +92572, +92572, +92592, +92603, +92603, +92603, +92626, +92658, +92666, +92666, +92666, +92672, +92714, +92714, +92724, +92744, +92776, +92776, +92797, +92797, +92828, +92828, +92847, +92847, +92874, +92874, +92874, +92892, +92900, +92900, +92900, 92930, -92941, -92956, -92967, -92967, +92930, +92936, +92936, +92944, +92962, 92977, -93000, -93006, -93025, -93051, -93066, -93079, -93091, -93091, -93097, -93103, -93103, -93133, -93133, -93133, -93139, -93139, -93139, -93158, -93164, -93191, -93191, -93191, +92977, +92983, +93027, +93033, +93033, +93050, +93082, +93107, +93125, +93125, +93125, +93143, +93143, +93157, +93157, +93157, +93157, +93187, +93187, +93194, +93194, 93206, -93220, -93235, -93251, -93251, -93251, -93257, -93265, -93265, -93271, -93323, -93341, -93358, -93373, -93390, -93390, -93390, -93398, -93398, -93398, -93407, -93413, -93422, -93428, -93428, -93452, -93477, -93500, -93508, -93529, -93535, -93535, -93561, -93561, -93561, -93594, -93601, -93617, -93617, -93625, -93642, -93659, -93669, -93669, -93675, -93675, -93691, -93691, -93703, -93718, -93718, -93725, -93725, -93725, -93725, -93733, -93733, -93733, -93733, -93749, -93772, -93799, -93814, -93814, -93839, -93861, -93861, -93861, -93861, -93861, -93883, -93883, -93883, +93206, +93212, +93229, +93258, +93285, +93297, +93297, +93297, +93297, +93343, +93343, +93343, +93370, +93387, +93387, +93387, +93387, +93387, +93412, +93417, +93430, +93430, +93430, +93430, +93430, +93430, +93430, +93436, +93455, +93464, +93483, +93496, +93496, +93513, +93513, +93513, +93554, +93584, +93584, +93584, +93584, +93592, +93602, +93607, +93631, +93657, +93664, +93672, +93744, +93753, +93753, +93761, +93776, +93776, +93776, +93776, +93776, +93776, +93810, +93822, +93822, +93852, +93871, +93884, 93897, -93910, -93917, -93917, -93940, -93940, -93956, -93956, -93968, -93985, -94005, -94005, -94005, -94011, -94035, -94035, -94066, -94089, -94089, -94089, -94108, -94132, -94157, -94175, -94175, -94183, -94212, -94218, +93914, +93926, +93939, +93939, +93954, +93954, +93954, +93954, +93969, +93977, +93977, +93977, +93990, +93990, +94031, +94062, +94068, +94068, +94068, +94099, +94123, +94141, +94191, +94209, +94209, +94209, 94228, -94234, -94257, -94270, -94270, -94270, -94270, -94292, -94308, -94314, -94314, -94331, -94331, -94355, -94380, -94424, -94445, -94445, -94445, -94445, -94467, -94473, -94488, -94497, -94515, -94524, -94531, -94571, -94571, -94587, -94610, -94620, -94620, -94627, -94633, -94643, -94643, -94643, -94661, -94661, -94661, -94661, -94668, -94668, -94668, -94668, -94696, -94696, -94696, -94696, -94711, +94263, +94263, +94298, +94307, +94321, +94321, +94327, +94327, +94358, +94358, +94358, +94370, +94370, +94370, +94370, +94377, +94410, +94464, +94496, +94513, +94542, +94548, +94548, +94563, +94569, +94575, +94593, +94593, +94593, +94593, +94613, +94613, +94618, +94618, +94618, +94625, +94637, +94644, +94650, +94663, +94682, +94695, +94728, +94728, 94734, -94756, -94756, -94794, -94807, -94820, -94837, -94857, -94857, -94868, -94878, -94884, -94884, -94884, -94915, -94935, -94935, -94994, -95020, -95020, -95028, -95028, -95028, -95028, -95042, -95052, -95062, -95076, -95099, -95120, -95126, -95156, -95165, -95218, -95218, -95230, -95230, -95230, -95230, -95242, -95284, +94734, +94759, +94789, +94814, +94826, +94826, +94826, +94840, +94840, +94840, +94871, +94877, +94877, +94885, +94885, +94885, +94892, +94892, +94904, +94904, +94904, +94904, +94904, +94904, +94904, +94920, +94920, +94941, +94959, +94959, +94959, +94959, +94959, +94971, +95005, +95034, +95034, +95068, +95073, +95098, +95098, +95098, +95115, +95144, +95153, +95170, +95170, +95207, +95227, +95227, +95250, +95264, +95264, +95264, +95280, 95303, -95316, -95329, -95329, -95329, -95361, -95398, -95411, -95411, -95427, -95427, -95462, -95481, -95496, -95496, -95508, -95540, -95540, -95558, -95558, -95585, -95585, -95597, -95607, -95643, -95674, -95688, -95688, -95688, -95718, -95718, -95731, -95750, -95750, -95750, -95768, -95768, -95776, -95776, -95776, -95776, -95776, -95776, -95776, -95804, -95804, -95822, -95829, -95836, -95836, -95836, -95836, -95849, -95849, -95861, -95861, -95861, -95886, -95886, -95886, -95893, -95893, +95303, +95303, +95319, +95319, +95319, +95342, +95364, +95407, +95420, +95420, +95435, +95435, +95452, +95452, +95452, +95470, +95476, +95505, +95536, +95536, +95536, +95536, +95536, +95536, +95568, +95568, +95587, +95629, +95629, +95640, +95647, +95660, +95705, +95742, +95754, +95825, +95831, +95848, +95848, +95848, +95868, +95888, 95911, -95911, -95918, -95918, -95951, -95951, -95951, -95961, -95998, -95998, -95998, -95998, -96013, -96013, -96013, -96013, -96027, -96057, -96065, -96065, -96076, -96076, -96076, -96076, -96108, -96120, -96120, -96120, -96129, -96156, -96156, +95936, +95936, +95979, +96003, +96016, +96047, +96047, +96059, +96082, +96107, +96107, +96119, +96133, +96157, +96169, +96169, +96169, 96177, -96189, -96201, -96211, -96211, -96211, -96211, -96232, -96232, -96244, -96263, -96280, -96280, -96301, -96301, -96301, -96321, -96321, -96321, -96333, -96351, -96363, -96363, -96381, -96387, -96394, -96394, -96399, -96399, -96428, -96441, -96441, -96441, -96454, -96463, -96471, -96471, -96481, -96521, -96521, -96534, -96534, -96544, -96566, -96566, -96566, -96566, -96596, -96596, -96596, -96596, -96611, -96611, -96611, -96611, -96629, -96629, +96177, +96203, +96234, +96234, +96234, +96247, +96268, +96274, +96274, +96315, +96354, +96372, +96372, +96372, +96392, +96407, +96444, +96444, +96470, +96510, +96527, +96562, +96583, +96583, +96599, +96599, +96599, 96642, -96642, -96662, -96662, -96676, -96689, -96689, -96699, -96714, -96725, -96725, -96741, -96769, -96769, -96775, -96775, -96783, -96783, -96783, -96801, -96817, -96834, -96834, -96834, -96834, -96844, -96860, -96889, -96929, -96929, -96945, -96945, -96975, -96985, -97002, +96657, +96657, +96657, +96698, +96720, +96735, +96735, +96761, +96802, +96802, +96814, +96826, +96826, +96843, +96855, +96866, +96884, +96896, +96896, +96905, +96905, +96905, +96905, +96905, +96933, +96933, +96933, +96933, +96950, +96950, +96950, +96950, +96965, +96974, +96992, +96992, +97012, +97041, 97047, -97062, -97062, -97069, -97069, -97082, -97082, -97093, -97126, -97150, -97150, -97150, -97150, -97150, -97175, -97175, -97175, -97175, -97175, -97175, +97091, +97091, +97091, +97098, +97098, +97120, +97138, +97138, 97196, -97196, -97196, -97196, -97213, -97232, -97249, -97249, -97276, -97289, -97296, -97307, -97307, -97314, -97338, -97338, -97338, -97358, -97375, -97387, -97408, -97408, -97408, -97408, -97425, -97461, -97483, -97502, -97502, -97509, -97509, -97509, -97518, -97540, -97553, -97553, -97553, +97227, +97227, +97255, +97267, +97267, +97292, +97331, +97355, +97365, +97373, +97457, +97457, +97457, +97519, +97519, +97534, +97548, +97548, 97570, -97576, -97576, -97576, -97610, -97610, -97618, -97624, -97630, -97640, -97674, -97699, -97699, -97709, -97709, -97709, -97709, -97720, -97740, -97740, -97740, -97759, -97759, -97759, -97769, -97776, -97829, -97829, -97829, -97863, -97863, -97887, -97904, -97914, -97914, +97593, +97613, +97631, +97661, +97667, +97689, +97717, +97717, +97717, +97735, +97735, +97735, +97745, +97771, +97786, +97798, +97798, +97839, +97839, +97839, +97848, +97848, +97867, +97918, +97918, +97918, 97927, -97937, -97947, -97947, -97947, -97959, -97959, -97959, -97977, -98002, -98016, -98044, -98044, -98062, -98062, -98072, -98072, -98072, -98072, -98086, -98105, -98124, -98132, -98132, -98148, -98173, -98185, -98206, -98240, -98240, -98259, -98294, -98320, +97942, +97942, +97942, +97942, +97942, +97967, +97979, +98012, +98012, +98054, +98054, +98078, +98078, +98106, +98106, +98115, +98130, +98130, +98130, +98130, +98137, +98137, +98137, +98144, +98168, +98188, +98188, +98202, +98202, +98220, +98234, +98266, +98273, +98292, +98317, +98328, +98328, 98346, 98346, 98346, -98379, -98387, -98415, -98442, -98469, +98357, +98357, +98357, +98365, +98400, +98412, +98431, +98438, 98477, -98490, -98528, -98528, -98528, -98553, -98562, -98593, -98608, -98622, -98630, -98630, -98637, -98647, +98488, +98504, +98504, +98511, +98540, +98559, +98566, +98595, +98601, +98607, +98615, +98638, +98651, +98651, +98651, +98667, +98667, +98686, 98703, -98733, -98733, -98733, -98749, -98749, -98754, -98759, -98783, -98783, -98808, +98703, +98716, +98728, +98762, +98762, +98762, +98779, +98804, 98827, -98827, -98827, -98853, -98888, -98888, -98906, -98906, -98926, -98954, -98963, -98963, -98963, -98973, -98991, -98997, -98997, -98997, -98997, -99014, -99014, -99014, -99014, -99022, -99036, -99036, -99080, -99096, -99101, -99101, -99115, -99125, -99135, -99135, -99135, -99163, -99163, -99163, -99203, -99203, -99222, -99222, -99253, -99253, -99285, -99308, -99308, -99308, -99308, -99333, -99360, -99394, -99394, -99408, -99408, -99414, -99420, -99420, -99420, -99469, -99476, -99476, -99476, -99498, -99498, -99498, +98833, +98847, +98865, +98865, +98865, +98865, +98876, +98876, +98876, +98895, +98905, +98905, +98946, +98946, +98946, +98946, +98977, +99002, +99019, +99026, +99026, +99038, +99051, +99078, +99106, +99113, +99126, +99144, +99164, +99164, +99189, +99238, +99245, +99257, +99288, +99306, +99306, +99334, +99355, +99383, +99437, +99437, +99458, +99485, +99505, +99517, 99528, -99528, -99528, -99546, -99552, -99558, -99576, -99576, -99576, -99600, -99611, -99611, -99621, -99636, -99636, -99636, -99636, -99636, -99636, -99636, -99687, -99687, -99721, -99728, +99553, +99560, +99573, +99590, +99602, +99624, +99624, +99631, +99638, +99657, +99688, +99701, +99708, 99747, -99753, -99753, -99753, -99796, -99801, -99817, -99826, -99858, -99858, -99873, -99873, -99873, -99912, -99912, -99912, -99912, -99939, -99939, -99939, -99939, -99953, -99963, -100010, -100045, -100056, -100056, -100078, -100078, -100078, -100093, -100098, -100098, -100098, -100106, -100113, -100126, -100126, -100126, -100126, -100126, -100126, -100131, -100156, -100156, -100166, -100166, -100166, -100186, -100186, -100186, -100186, -100219, -100236, -100236, -100236, -100236, -100287, -100305, -100313, -100313, -100328, -100328, -100328, -100328, -100352, -100352, -100352, -100352, -100363, -100399, -100399, -100399, -100417, -100433, -100446, -100446, -100464, -100464, -100464, -100521, -100530, -100539, -100565, -100583, -100591, -100601, -100612, -100612, -100612, -100612, -100612, -100618, -100644, -100644, -100652, -100685, -100695, -100695, -100706, -100712, -100749, -100766, -100811, -100834, -100834, -100860, -100869, -100869, -100869, -100889, -100907, -100907, -100913, -100932, -100932, -100932, -100932, -100932, -100932, +99759, +99781, +99781, +99804, +99822, +99841, +99841, +99859, +99859, +99859, +99877, +99890, +99913, +99930, +99944, +99976, +100005, +100005, +100018, +100025, +100025, +100032, +100032, +100048, +100059, +100059, +100086, +100095, +100111, +100138, +100153, +100169, +100214, +100222, +100230, +100267, +100274, +100284, +100293, +100293, +100329, +100347, +100357, +100377, +100387, +100387, +100397, +100397, +100409, +100425, +100425, +100425, +100441, +100455, +100472, +100472, +100479, +100508, +100508, +100517, +100549, +100549, +100568, +100578, +100603, +100603, +100610, +100610, +100641, +100682, +100690, +100705, +100723, +100743, +100743, +100750, +100763, +100763, +100822, +100844, +100865, +100877, +100877, +100877, +100884, +100891, +100903, +100926, 100950, 100950, -100963, -100963, -101015, -101026, +100968, +100968, +100987, +101007, +101027, +101027, +101027, +101034, +101034, +101041, 101048, -101048, -101084, -101090, -101103, -101119, -101119, -101119, -101137, -101160, -101171, -101180, -101186, -101194, -101194, -101212, -101237, -101260, -101260, -101260}; +101055, +101105, +101126, +101142, +101149, +101156, +101163, +101163, +101205, +101205, +101228, +101228, +101228, +101228, +101228, +101228, +101250, +101275, +101282, +101282, +101310, +101316, +101316, +101316, +101323, +101344, +101366, +101392, +101399, +101424, +101441, +101441, +101441, +101441, +101464, +101500, +101520, +101537, +101544, +101552, +101552, +101580, +101580, +101610, +101620, +101627, +101634, +101649, +101656, +101663, +101670, +101670, +101686, +101686, +101693, +101720, +101720, +101748, +101765, +101786, +101802, +101809, +101828}; static const char *tldData[] = { -"ac.lk\0lu.eu.org\0me.eu.org\0" -"hazu.aichi.jp\0" -"ac.ma\0auto.pl\0" -"meme\0" -"ac.me\0" -"kuokgroup\0" -"trentinsu\xcc\x88""d-tirol.it\0holtalen.no\0" -"alibaba\0" -"\xd9\x85\xd9\x88\xd8\xa8\xd8\xa7\xd9\x8a\xd9\x84\xd9\x8a\0" -"k12.ct.us\0hu.com\0" -"lib.ar.us\0" -"bbs.tr\0" -"arao.kumamoto.jp\0no-ip.biz\0" -"js.cn\0s3-fips-us-gov-west-1.amazonaws.com\0" -"ac.mu\0" -"bato.tochigi.jp\0agriculture.museum\0" -"ac.mw\0" -"h.se\0" -"ac.ni\0home.dyndns.org\0" -"umi.fukuoka.jp\0ac.mz\0varoy.no\0" -"lv.eu.org\0" -"slg.br\0bando.ibaraki.jp\0community.museum\0" -"s\xc3\xb8rfold.no\0" -"nysa.pl\0travelers\0" -"krokstadelva.no\0is-a-lawyer.com\0" -"baseball.museum\0" -"southcarolina.museum\0" -"menu\0verisign\0" -"kddi\0" -"fc.it\0docs\0nfshost.com\0" -"outsystemscloud.com\0" -"larsson.museum\0med.pro\0" -"forli\xcc\x80""cesena.it\0arts.nf\0ac.nz\0" -"\xe3\x82\xb9\xe3\x83\x88\xe3\x82\xa2\0" -"tsuruta.aomori.jp\0" -"sp.it\0ac.pa\0fhapp.xyz\0" -"study\0" -"misato.akita.jp\0rocher\0" -"us-1.evennode.com\0" -"ralingen.no\0" -"nesna.no\0ddnsfree.com\0" -"urakawa.hokkaido.jp\0tychy.pl\0" -"webhop.org\0" -"artgallery.museum\0" -"saigawa.fukuoka.jp\0state.museum\0" -"contagem.br\0snasa.no\0" -"museum\0doomdns.org\0" -"tone.ibaraki.jp\0" -"bashkiria.ru\0" -"ac.pr\0" -"uchiko.ehime.jp\0sue.fukuoka.jp\0toyosato.shiga.jp\0es.leg.br\0" -"asahi.nagano.jp\0es.kr\0from-wa.com\0" -"ooshika.nagano.jp\0" -"kasukabe.saitama.jp\0" -"sumita.iwate.jp\0" -"nannestad.no\0\xe5\x81\xa5\xe5\xba\xb7\0" -"teshikaga.hokkaido.jp\0" -"slattum.no\0" -"bashkiria.su\0" -"trentinos-tirol.it\0" -"laz.it\0" -"edu.ac\0" -"memorial\0" -"edu.af\0" -"k12.id.us\0" -"from-la.net\0" -"edu.al\0feedback\0" -"vik.no\0" -"ketrzyn.pl\0ac.rs\0" -"doha\0" -"edu.ba\0okaya.nagano.jp\0ac.ru\0ac.se\0cloudcontrolled.com\0" -"edu.ar\0edu.bb\0kunisaki.oita.jp\0" -"ac.rw\0s3.dualstack.eu-central-1.amazonaws.com\0from-al.com\0" -"kouzushima.tokyo.jp\0" -"edu.au\0is-a-knight.org\0" -"edu.bh\0" -"edu.bi\0inc.hk\0" -"edu.az\0yamashina.kyoto.jp\0time.museum\0" -"ishikawa.fukushima.jp\0naruto.tokushima.jp\0myravendb.com\0" -"stage.nodeart.io\0" -"edu.bm\0" -"edu.bn\0" -"edu.bo\0" -"lplfinancial\0ltd.ua\0" -"edu.br\0" -"edu.bs\0" -"edu.bt\0ac.th\0" -"ac.sz\0ac.tj\0" -"taki.mie.jp\0" -"edu.ci\0" -"edu.bz\0ltd.uk\0" -"github.io\0""32-b.it\0" -"hidaka.hokkaido.jp\0school\0" -"edu.cn\0acct.pro\0" -"edu.co\0" -"windmill.museum\0" -"nittedal.no\0" -"r\xc3\xb8st.no\0ac.ug\0unicom\0" -"edu.cu\0" -"latina.it\0oristano.it\0shakotan.hokkaido.jp\0ac.tz\0" -"edu.cw\0ac.uk\0" -"anan.nagano.jp\0notteroy.no\0" -"miyawaka.fukuoka.jp\0" -"accident-investigation.aero\0" -"edu.dm\0gifu.gifu.jp\0" -"edu.do\0" -"kokubunji.tokyo.jp\0kawanishi.yamagata.jp\0thruhere.net\0" -"zentsuji.kagawa.jp\0" -"edu.ec\0" -"\xc3\xa5seral.no\0mincom.tn\0" -"edu.ee\0marine.ru\0" -"equipment.aero\0" -"edu.eg\0kr.eu.org\0" -"arq.br\0" -"tabuse.yamaguchi.jp\0hamburg.museum\0" -"edu.dz\0ac.vn\0" -"emr.it\0" -"from-mi.com\0" -"christiansburg.museum\0" -"edu.es\0kami.miyagi.jp\0" -"edu.et\0fitness\0*.kunden.ortsinfo.at\0" -"tokoname.aichi.jp\0daegu.kr\0" -"ck.ua\0" -"mobara.chiba.jp\0" -"hsbc\0icbc\0" -"\xe5\xa5\x88\xe8\x89\xaf.jp\0k12.mt.us\0" -"ven.it\0virgin\0yachts\0" -"bjerkreim.no\0" -"idv.hk\0namikata.ehime.jp\0tamatsukuri.ibaraki.jp\0luxe\0" -"macerata.it\0microsoft\0" -"minano.saitama.jp\0" -"f.bg\0oseto.nagasaki.jp\0" -"protection\0" -"edu.ge\0from-ak.com\0" -"aaa.pro\0" -"edu.gh\0novara.it\0" -"edu.gi\0" -"maceio.br\0" -"av.it\0turystyka.pl\0download\0" -"edu.gl\0ringsaker.no\0africa\0" -"edu.gn\0" -"movimiento.bo\0" -"edu.gp\0" -"camdvr.org\0" -"edu.gr\0skin\0" -"edu.gt\0" -"edu.gu\0usdecorativearts.museum\0" -"pc.it\0" -"edu.gy\0" -"flora.no\0" -"edu.hk\0perso.sn\0" -"moskenes.no\0" -"sk\xc3\xa5nland.no\0ac.za\0" -"edu.hn\0" -"annefrank.museum\0" -"higashikurume.tokyo.jp\0" -"powiat.pl\0" -"sandnessjoen.no\0" -"edu.ht\0yamagata.ibaraki.jp\0" -"inzai.chiba.jp\0koto.shiga.jp\0godaddy\0" -"niihama.ehime.jp\0flesberg.no\0" -"ac.zm\0community\0viajes\0" -"perso.tn\0observer\0" -"cesenaforli.it\0cloudfront.net\0" -"secure\0" -"edu.in\0zamami.okinawa.jp\0" -"volda.no\0" -"edu.iq\0" -"edu.is\0ac.zw\0" -"edu.it\0" -"fitjar.no\0" -"sukagawa.fukushima.jp\0" -"versailles.museum\0" -"satsumasendai.kagoshima.jp\0educational.museum\0myphotos.cc\0" -"shingu.fukuoka.jp\0shibata.miyagi.jp\0hemne.no\0" -"oyamazaki.kyoto.jp\0" -"nationalheritage.museum\0north-kazakhstan.su\0dscloud.biz\0" -"edu.jo\0diskstation.me\0" -"feira.br\0" -"\xe0\xb2\xad\xe0\xb2\xbe\xe0\xb2\xb0\xe0\xb2\xa4\0vladikavkaz.ru\0" -"tranby.no\0" -"lib.ca.us\0" -"edu.kg\0" -"edu.ki\0" -"windows\0" -"edu.km\0" -"edu.kn\0" -"diskstation.eu\0" -"edu.kp\0lib.pr.us\0" -"kyonan.chiba.jp\0munakata.fukuoka.jp\0edu.la\0andasuolo.no\0vladikavkaz.su\0" -"edu.lb\0schaeffler\0tushu\0" -"takatsuki.shiga.jp\0edu.lc\0" -"slz.br\0koya.wakayama.jp\0meeres.museum\0" -"aetna\0" -"edu.kw\0game\0" -"hanamaki.iwate.jp\0kuroiso.tochigi.jp\0edu.ky\0dscloud.mobi\0" -"edu.kz\0" -"edu.lk\0" -"in-addr.arpa\0soja.okayama.jp\0hamar.no\0" -"mito.ibaraki.jp\0" -"ic.gov.pl\0" -"cc.ga.us\0" -"edu.lr\0bindal.no\0" -"edu.me\0" -"edu.lv\0naroy.no\0" -"edu.mg\0" -"ts.it\0" -"edu.ly\0" -"edu.mk\0" -"edu.ml\0cc.tn.us\0" -"edu.mn\0cruises\0" -"edu.mo\0" -"hasuda.saitama.jp\0" -"um.gov.pl\0" -"edu.ms\0sande.m\xc3\xb8re-og-romsdal.no\0" -"kitagawa.kochi.jp\0edu.mt\0" -"spy.museum\0stryn.no\0" -"kamijima.ehime.jp\0edu.mv\0" -"edu.mw\0edu.ng\0" -"edu.mx\0house\0" -"saga.saga.jp\0edu.my\0edu.ni\0" -"edu.mz\0boldlygoingnowhere.org\0" -"yoshioka.gunma.jp\0lajolla.museum\0" -"pc.pl\0pagespeedmobilizer.com\0" -"edu.nr\0" -"minoh.osaka.jp\0" -"masuda.shimane.jp\0" -"commbank\0" -"oiso.kanagawa.jp\0edu.om\0" -"banamex\0" -"sobetsu.hokkaido.jp\0trust.museum\0" -"nesoddtangen.no\0" -"edu.pa\0" -"chesapeakebay.museum\0" -"trentino-su\xcc\x88""d-tirol.it\0pacific.museum\0" -"dyn.home-webserver.de\0" +"edu.mt\0" +"off.ai\0k12.dc.us\0" +"edu.mv\0" +"edu.mw\0edu.ng\0berlev\xc3\xa5g.no\0" +"edu.mx\0" +"edu.my\0edu.ni\0" +"edu.mz\0fastpanel.direct\0" +"suzuki\0s3-eu-west-1.amazonaws.com\0" +"livinghistory.museum\0" +"trentinoalto-adige.it\0dontexist.net\0" +"hamburg.museum\0muos\xc3\xa1t.no\0" +"cn-northwest-1.eb.amazonaws.com.cn\0" +"edu.nr\0\xe0\xb8\x98\xe0\xb8\xb8\xe0\xb8\xa3\xe0\xb8\x81\xe0\xb8\xb4\xe0\xb8\x88.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0direct\0" +"fl.us\0agency\0" +"from-ok.com\0" +"nishiizu.shizuoka.jp\0komae.tokyo.jp\0" +"edu.om\0team\0doomdns.com\0" +"vestre-slidre.no\0" +"sweden.museum\0edu.pa\0" +"newhampshire.museum\0" "edu.pe\0" -"edu.pf\0duckdns.org\0" +"pro.az\0ar.it\0nishihara.kumamoto.jp\0edu.pf\0" "edu.ph\0" -"\xe6\xa0\x83\xe6\x9c\xa8.jp\0mk.ua\0" -"edu.pk\0myiphost.com\0" +"page\0" +"hikimi.shimane.jp\0" +"santafe.museum\0edu.pk\0" "edu.pl\0" -"jdf.br\0\xd8\xb9\xd8\xb1\xd8\xa7\xd9\x82\0" -"edu.pn\0" +"s3-ap-southeast-1.amazonaws.com\0home.dyndns.org\0" +"pro.br\0edu.pn\0" +"kasai.hyogo.jp\0clan.rip\0" "edu.qa\0" "edu.pr\0" -"kunneppu.hokkaido.jp\0edu.ps\0" -"edu.pt\0" -"yabuki.fukushima.jp\0" -"kr\xc3\xb8""dsherad.no\0mel\xc3\xb8y.no\0" -"plurinacional.bo\0" +"edu.ps\0mordovia.ru\0" +"nysa.pl\0edu.pt\0" +"\xe7\xbd\x91\xe7\xbb\x9c.hk\0ing.pa\0" +"tech\0" "edu.py\0" -"shikokuchuo.ehime.jp\0" -"kiyose.tokyo.jp\0" -"miho.ibaraki.jp\0" -"bolzano.it\0versicherung\0" -"shisui.chiba.jp\0" -"us.gov.pl\0" -"cc.la.us\0" -"aure.no\0" -"\xe9\xb3\xa5\xe5\x8f\x96.jp\0" -"kawanishi.nara.jp\0av.tr\0" -"government.aero\0jampa.br\0" -"sortland.no\0" -"mymailer.com.tw\0" -"edu.sa\0" -"aerobatic.aero\0edu.sb\0defense.tn\0" -"in.na\0edu.rs\0edu.sc\0" -"sn.cn\0edu.sd\0" +"ugim.gov.pl\0" +"kameyama.mie.jp\0" +"madrid.museum\0gjesdal.no\0" +"elverum.no\0" +"saotome.st\0" +"sveio.no\0iveco\0" +"gifu.jp\0" +"k12.me.us\0" +"samsclub\0now-dns.top\0" +"pro.cy\0" +"solund.no\0" +"store\0" +"nym.gr\0" +"gjovik.no\0" +"miyoshi.aichi.jp\0" +"pro.ec\0convent.museum\0hopto.org\0" +"ichikawamisato.yamanashi.jp\0" +"edu.sa\0nym.gy\0" +"edu.sb\0lamer\0" +"edu.rs\0edu.sc\0" +"edu.sd\0" "edu.ru\0" -"edu.rw\0edu.sg\0" -"okuizumo.shimane.jp\0sykkylven.no\0weatherchannel\0" -"in.ni\0" -"edu.sl\0idv.tw\0review\0" -"higashitsuno.kochi.jp\0channelsdvr.net\0" +"map.fastlylb.net\0" +"langevag.no\0edu.rw\0edu.sg\0" +"bmd.br\0" +"brasil.museum\0cc.ar.us\0" +"edu.sl\0" +"nym.ie\0" "edu.sn\0" -"selje.no\0" -"edu.st\0" -"kawanishi.hyogo.jp\0\xe0\xae\x87\xe0\xae\xb2\xe0\xae\x99\xe0\xaf\x8d\xe0\xae\x95\xe0\xaf\x88\0" -"edu.sv\0" -"free\0" -"b\xc3\xa5""d\xc3\xa5""ddj\xc3\xa5.no\0azure\0" -"kembuchi.hokkaido.jp\0edu.sy\0dev.static.land\0" -"edu.tj\0" -"k12.az.us\0" -"sells-for-less.com\0" -"edu.tm\0" -"cloud66.ws\0" -"edu.to\0" -"surnadal.no\0" -"edu.ua\0dn.ua\0" -"hi.cn\0edu.tr\0" -"fukushima.fukushima.jp\0" -"edu.tt\0" -"kunstsammlung.museum\0bargains\0" -"edu.tw\0" -"lib.ma.us\0" -"yabu.hyogo.jp\0" -"nagatoro.saitama.jp\0" -"y.bg\0marriott\0" -"associates\0builders\0diskstation.org\0" -"okegawa.saitama.jp\0" -"kikonai.hokkaido.jp\0edu.vc\0" -"fujikawa.shizuoka.jp\0" -"usculture.museum\0edu.ve\0" -"ci.it\0bomlo.no\0" -"omura.nagasaki.jp\0edu.uy\0" -"hashima.gifu.jp\0" -"casadelamoneda.museum\0hasura-app.io\0" -"bulsan-su\xcc\x88""dtirol.it\0edu.vn\0" -"friulivenezia-giulia.it\0" -"pv.it\0childrensgarden.museum\0stj\xc3\xb8rdal.no\0" -"shintoku.hokkaido.jp\0gs.va.no\0forgot.his.name\0" -"familyds.com\0" -"es.gov.br\0garden.museum\0edu.vu\0weather\0" -"kudamatsu.yamaguchi.jp\0is-a-democrat.com\0crafting.xyz\0" -"wa.gov.au\0taku.saga.jp\0" -"mitane.akita.jp\0taka.hyogo.jp\0" -"paris.museum\0" -"\xd5\xb0\xd5\xa1\xd5\xb5\0" -"f.se\0" -"komoro.nagano.jp\0edu.ws\0george\0" -"pmn.it\0in.rs\0" -"aa.no\0" -"kamisu.ibaraki.jp\0arai.shizuoka.jp\0iki.fi\0" -"tokai.ibaraki.jp\0shiwa.iwate.jp\0" -"telekommunikation.museum\0" -"rokunohe.aomori.jp\0" -"bounty-full.com\0" -"cyber.museum\0" -"chichibu.saitama.jp\0vantaa.museum\0jgora.pl\0hdfcbank\0" -"is-a-conservative.com\0" -"\xe9\xa6\x99\xe5\xb7\x9d.jp\0v\xc3\xa5gs\xc3\xb8y.no\0flights\0" -"emp.br\0" -"in.th\0movie\0" -"mediocampidano.it\0" -"frontdoor\0gbiz\0zappos\0" -"fie.ee\0military.museum\0ovre-eiker.no\0" -"shimosuwa.nagano.jp\0kep.tr\0" -"edu.za\0\xe5\xae\xb6\xe9\x9b\xbb\0" -"tajiri.osaka.jp\0" -"abashiri.hokkaido.jp\0in.ua\0" -"ikaruga.nara.jp\0\xc3\xa5s.no\0" -"ribeirao.br\0aya.miyazaki.jp\0" -"tokushima.jp\0" -"assisi.museum\0" -"edu.zm\0bofa\0" -"sch.ae\0" -"corvette.museum\0" -"mikasa.hokkaido.jp\0" -"in.us\0work\0" -"iwata.shizuoka.jp\0" -"amami.kagoshima.jp\0" -"miyoshi.saitama.jp\0" -"eu-4.evennode.com\0" -"flekkefjord.no\0kvalsund.no\0*.spectrum.myjino.ru\0" -"ohtawara.tochigi.jp\0" -"poltava.ua\0" -"ikusaka.nagano.jp\0ikeda.osaka.jp\0" -"\xd8\xa7\xd9\x84\xd9\x8a\xd9\x85\xd9\x86\0" -"cc.va.us\0net.eu.org\0" -"film.hu\0moscow.museum\0from-nh.com\0" -"ris\xc3\xb8r.no\0" -"nagahama.shiga.jp\0kv.ua\0trade\0" -"e4.cz\0" -"*.statics.cloud\0" -"mitsue.nara.jp\0properties\0" -"osen.no\0" -"yoichi.hokkaido.jp\0" -"fam.pk\0" -"finearts.museum\0" -"berkeley.museum\0" -"furudono.fukushima.jp\0gs.ol.no\0" -"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xd9\x8a\xd9\x87\0" -"monzabrianza.it\0" -"dontexist.com\0" -"penza.su\0" -"takasu.hokkaido.jp\0gyeongbuk.kr\0cc.wy.us\0spb.ru\0" -"motosu.gifu.jp\0" -"imakane.hokkaido.jp\0" -"servesarcasm.com\0" -"yashiro.hyogo.jp\0" -"naklo.pl\0" -"kicks-ass.net\0" -"equipment\0" -"moroyama.saitama.jp\0eu-3.evennode.com\0" -"avoues.fr\0lib.wa.us\0" -"poa.br\0zara\0" -"spb.su\0" -"tozsde.hu\0" -"homesecuritymac.com\0" -"bitballoon.com\0" -"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xd9\x8a\xd8\xa9\0" -"tools\0" -"aizumisato.fukushima.jp\0dvrcam.info\0" -"nikaho.akita.jp\0" -"mi.it\0" -"is-a-linux-user.org\0" -"semboku.akita.jp\0iwanai.hokkaido.jp\0" -"himeshima.oita.jp\0house.museum\0vf.no\0unj\xc3\xa1rga.no\0cc.md.us\0gallup\0" -"attorney\0" -"gd.cn\0" -"audible\0richardli\0gdynia.pl\0" -"k\xc3\xa5""fjord.no\0" -"depot.museum\0" -"ashoro.hokkaido.jp\0" -"homeftp.org\0" -"friulivegiulia.it\0sakae.chiba.jp\0" -"s3.dualstack.us-east-2.amazonaws.com\0" -"d.bg\0aaa\0" -"limanowa.pl\0" -"kimitsu.chiba.jp\0digital\0" -"cust.testing.thingdust.io\0" -"chuo.yamanashi.jp\0" -"vic.edu.au\0dellogliastra.it\0war.museum\0" -"mitsubishi\0" -"at.it\0" -"hashikami.aomori.jp\0" -"geometre-expert.fr\0" -"ferrari\0" -"sch.id\0graphics\0" -"bond\0" -"nagareyama.chiba.jp\0abb\0" -"b\xc3\xb8.nordland.no\0abc\0" -"pa.it\0kanuma.tochigi.jp\0webhop.net\0" -"webhosting.be\0" -"tomi.nagano.jp\0" -"g\xc3\xa1ls\xc3\xa1.no\0" -"lib.ak.us\0" -"vibovalentia.it\0eu-2.evennode.com\0" -"sch.ir\0fujixerox\0" -"kamioka.akita.jp\0" -"saskatchewan.museum\0" -"kamikawa.hyogo.jp\0" -"asahi.yamagata.jp\0" -"harstad.no\0book\0" -"aisho.shiga.jp\0" -"dali.museum\0" -"sch.jo\0from-ks.com\0" -"lebesby.no\0" -"sampa.br\0" -"aco\0" -"cagliari.it\0olbia-tempio.it\0" -"obihiro.hokkaido.jp\0r\xc3\xb8ros.no\0kozow.com\0" -"kyotanabe.kyoto.jp\0" -"int.ar\0" -"ri.it\0imabari.ehime.jp\0" -"nakaniikawa.toyama.jp\0" -"vanguard\0" -"int.az\0""4lima.de\0" -"rost.no\0" -"ads\0" -"homeunix.net\0" -"int.bo\0" -"sch.lk\0snoasa.no\0aeg\0memset.net\0" -"bharti\0" -"batsfjord.no\0" -"katsuura.chiba.jp\0kashiba.nara.jp\0" -"niiza.saitama.jp\0y.se\0" -"hagebostad.no\0za.bz\0" -"flight.aero\0" -"int.ci\0dyndns-work.com\0" -"revista.bo\0" -"solund.no\0daplie.me\0" -"ubank\0" -"\xe7\xbd\x91\xe5\x9d\x80\0" -"sch.ly\0marburg.museum\0odesa.ua\0" -"int.co\0meguro.tokyo.jp\0" -"hi.us\0video\0" -"online.museum\0dvrdns.org\0" -"afl\0eu-1.evennode.com\0" -"nt.edu.au\0" -"wios.gov.pl\0beats\0ftpaccess.cc\0global.prod.fastly.net\0" -"\xe6\x96\xb0\xe6\xbd\x9f.jp\0" -"rindal.no\0""4lima.at\0" -"nl.ca\0sch.ng\0" -"blogspot.co.at\0" -"niigata.jp\0sydney.museum\0" -"pesaro-urbino.it\0" -"shizuoka.shizuoka.jp\0nerdpol.ovh\0" -"\xe5\x8d\x83\xe8\x91\x89.jp\0hemsedal.no\0sandvikcoromant\0" -"barreau.bj\0ohi.fukui.jp\0" -"viking.museum\0\xd8\xa7\xd9\x84\xd9\x85\xd8\xba\xd8\xb1\xd8\xa8\0from-wy.com\0synology-diskstation.de\0" -"shinjo.okayama.jp\0" -"from-co.net\0" -"4lima.ch\0" -"pharmacy.museum\0actor\0" -"muenster.museum\0embaixada.st\0" -"association.museum\0" -"dyndns.org\0" -"jessheim.no\0" -"\xd0\xbe\xd0\xb4.\xd1\x81\xd1\x80\xd0\xb1\0ieee\0\xe6\xb7\xa1\xe9\xa9\xac\xe9\x94\xa1\0" -"gyeonggi.kr\0" -"consultant.aero\0" -"s3-eu-central-1.amazonaws.com\0" -"bulsan-sudtirol.it\0" -"museet.museum\0" -"ecn.br\0brindisi.it\0" -"studio\0" -"ami.ibaraki.jp\0h\xc3\xa1mm\xc3\xa1rfeasta.no\0aig\0" -"cisco\0" -"ebetsu.hokkaido.jp\0" -"denmark.museum\0kr.com\0" -"sch.qa\0promo\0" -"mi.th\0" -"tomiya.miyagi.jp\0" -"vao.it\0kawasaki.miyagi.jp\0cc.vt.us\0" -"hekinan.aichi.jp\0" -"bd.se\0" -"nagaokakyo.kyoto.jp\0bill.museum\0" -"kinder\0" -"org.ac\0lib.ut.us\0accountant\0allstate\0from-ne.com\0" -"org.ae\0" -"org.af\0asso.fr\0" -"org.ag\0kakinoki.shimane.jp\0" -"wiw.gov.pl\0" -"org.ai\0" -"loyalist.museum\0gloppen.no\0fresenius\0" -"guam.gu\0miyoshi.hiroshima.jp\0" -"org.al\0" -"mi.us\0" -"aarborte.no\0" -"shimonita.gunma.jp\0" -"sch.sa\0\xe8\x87\xba\xe7\x81\xa3\0\xe7\x82\xb9\xe7\x9c\x8b\0" -"org.ba\0" -"org.ar\0org.bb\0" -"asso.gp\0" -"org.au\0sannan.hyogo.jp\0" -"miyama.fukuoka.jp\0" -"org.bh\0kosai.shizuoka.jp\0" -"org.bi\0etc.br\0" -"org.az\0" -"nakatsugawa.gifu.jp\0" -"futsu.nagasaki.jp\0paris\0" -"org.bm\0int.is\0" -"org.bn\0s3-ap-southeast-2.amazonaws.com\0" -"org.bo\0" -"minokamo.gifu.jp\0" -"org.br\0" -"org.bs\0" -"org.bt\0for-the.biz\0" -"karasuyama.tochigi.jp\0plants.museum\0static.land\0" -"org.bw\0" -"asso.ht\0" -"org.ci\0" -"org.bz\0" -"union.aero\0*.platform.sh\0" -"erotica.hu\0" -"org.cn\0ino.kochi.jp\0" -"org.co\0randaberg.no\0vindafjord.no\0" -"hiraizumi.iwate.jp\0" -"railway.museum\0swidnica.pl\0\xe0\xb8\xad\xe0\xb8\x87\xe0\xb8\x84\xe0\xb9\x8c\xe0\xb8\x81\xe0\xb8\xa3.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" -"friuli-vgiulia.it\0" -"org.cu\0" -"pa.us\0" -"org.cw\0blogspot.co.id\0" -"accountants\0" -"org.cy\0" -"kamimine.saga.jp\0naumburg.museum\0" -"int.la\0stor-elvdal.no\0property\0" -"org.dm\0statebank\0" -"asso.bj\0" -"org.do\0blogspot.co.il\0" -"d\xc3\xb8nna.no\0" -"misato.wakayama.jp\0" -"org.ec\0saga.jp\0" -"isa.us\0" -"org.ee\0int.lk\0rade.no\0bukhara.su\0" -"\xe6\xbb\x8b\xe8\xb3\x80.jp\0herokuapp.com\0" -"org.eg\0experts-comptables.fr\0lease\0" -"takarazuka.hyogo.jp\0" -"niyodogawa.kochi.jp\0" -"org.dz\0yasu.shiga.jp\0" -"asso.ci\0anz\0" -"w.bg\0aol\0" -"amsterdam\0" -"unjarga.no\0" -"org.es\0" -"org.et\0" -"s3.ap-northeast-2.amazonaws.com\0" -"gojome.akita.jp\0" -"nerima.tokyo.jp\0" -"\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4\xe0\xa4\xae\xe0\xa5\x8d\0" -"val-d-aosta.it\0" -"jp.eu.org\0" -"sncf\0" -"ri.us\0dodge\0" -"mima.tokushima.jp\0int.mv\0" -"int.mw\0" -"pt.it\0southwest.museum\0" -"int.ni\0s\xc3\xb8r-fron.no\0app\0kindle\0" -"nishihara.okinawa.jp\0yandex\0" -"org.ge\0pisa.it\0doesntexist.com\0" -"watari.miyagi.jp\0yono.saitama.jp\0kosei.shiga.jp\0" -"org.gg\0" -"org.gh\0" -"org.gi\0zhitomir.ua\0karaganda.su\0" -"satte.saitama.jp\0" -"mitaka.tokyo.jp\0frogn.no\0" -"org.gl\0h\xc3\xb8yanger.no\0" -"systems\0" -"asso.dz\0org.gn\0sarpsborg.no\0" -"swiss\0" -"org.gp\0\xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0\0" -"org.gr\0d.se\0" -"org.gt\0" -"org.gu\0bar\0" -"bbc\0" -"tempio-olbia.it\0tobishima.aichi.jp\0" -"elk.pl\0" -"org.gy\0trentinoalto-adige.it\0" -"aju.br\0org.hk\0" -"tanabe.wakayama.jp\0apartments\0" -"org.hn\0suginami.tokyo.jp\0" -"pimienta.org\0" -"fortworth.museum\0" -"\xe7\x9f\xb3\xe5\xb7\x9d.jp\0" -"org.ht\0nl.no\0" -"org.hu\0" -"art\0bbt\0" -"barsy.info\0" -"bcg\0education\0" -"itoigawa.niigata.jp\0" -"org.il\0hakusan.ishikawa.jp\0yamato.kanagawa.jp\0ina.nagano.jp\0sch.zm\0" -"org.im\0ap-south-1.elasticbeanstalk.com\0" -"org.in\0int.pt\0turen.tn\0chase\0" -"l\xc3\xa4ns.museum\0" -"org.iq\0valle\xcc\x81""edaoste.it\0bcn\0" -"org.ir\0" -"org.is\0byen.site\0" -"org.je\0environmentalconservation.museum\0" -"watchandclock.museum\0intel\0" -"minamidaito.okinawa.jp\0bonn.museum\0" -"doshi.yamanashi.jp\0" -"daito.osaka.jp\0katano.osaka.jp\0" -"taiwa.miyagi.jp\0" -"org.jo\0" -"a\xc3\xa9roport.ci\0" -"miyake.nara.jp\0il.us\0" -"org.kg\0" -"org.ki\0" -"q-a.eu.org\0" -"org.km\0" -"org.kn\0nuernberg.museum\0" -"int.ru\0" -"yamanashi.jp\0org.kp\0\xe0\xb8\x97\xe0\xb8\xab\xe0\xb8\xb2\xe0\xb8\xa3.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0pictures\0" -"ueno.gunma.jp\0chiyoda.tokyo.jp\0org.la\0int.rw\0wi.us\0lamborghini\0" -"org.lb\0" -"org.lc\0" -"eu.com\0" -"sakura.chiba.jp\0" -"org.kw\0bet\0virtualuser.de\0" -"saroma.hokkaido.jp\0" -"org.ky\0cincinnati.museum\0ybo.review\0" -"org.kz\0" -"org.lk\0gdansk.pl\0" -"design.museum\0vlaanderen.museum\0" -"society.museum\0" -"org.ma\0smart\0" -"org.lr\0australia.museum\0" -"org.ls\0" -"int.tj\0is-very-nice.org\0" -"org.me\0" -"marumori.miyagi.jp\0org.lv\0" -"org.mg\0dnsup.net\0" -"org.ly\0ddnsgeek.com\0" -"org.mk\0" -"org.ml\0\xd8\xa7\xd9\x8a\xd8\xb1\xd8\xa7\xd9\x86\0parts\0\xd8\xa8\xd8\xa7\xd8\xb2\xd8\xa7\xd8\xb1\0" -"\xe5\x92\x8c\xe6\xad\x8c\xe5\xb1\xb1.jp\0omotego.fukushima.jp\0" -"org.mn\0int.tt\0" -"org.mo\0center\0" -"freiburg.museum\0org.na\0" -"journalist.aero\0chuo.tokyo.jp\0estate\0party\0" -"org.ms\0" -"org.mt\0axa\0" -"org.mu\0" -"calabria.it\0org.mv\0aws\0googleapis.com\0" -"miners.museum\0org.mw\0org.ng\0" -"niimi.okayama.jp\0toyama.toyama.jp\0org.mx\0" -"org.my\0org.ni\0" -"org.mz\0" -"val-daosta.it\0oumu.hokkaido.jp\0" -"naganohara.gunma.jp\0int.ve\0" -"l\xc3\xb8renskog.no\0org.nr\0" -"ens.tn\0\xd0\xb1\xd0\xb3\0" -"\xe6\x9d\xb1\xe4\xba\xac.jp\0" -"principe.st\0bid\0" -"shiso.hyogo.jp\0int.vn\0" -"org.nz\0" -"olayangroup\0" -"org.om\0" -"org.pa\0\xd8\xa7\xd9\x85\xd8\xa7\xd8\xb1\xd8\xa7\xd8\xaa\0" -"bio\0" -"musashino.tokyo.jp\0" -"org.pe\0cafe\0" -"org.pf\0mytis.ru\0" -"org.ph\0" -"village.museum\0from-pr.com\0" -"\xe6\x9c\xba\xe6\x9e\x84\0" -"org.pk\0" -"name.hr\0org.pl\0browsersafetymark.io\0" -"biz\0" -"ogose.saitama.jp\0org.pn\0kicks-ass.org\0blogspot.co.uk\0" -"okagaki.fukuoka.jp\0" -"nayoro.hokkaido.jp\0" -"openair.museum\0org.qa\0" -"org.pr\0istanbul\0" -"org.ps\0" -"org.pt\0" -"bibai.hokkaido.jp\0" -"org.py\0k12.nh.us\0" -"tsuno.kochi.jp\0" -"tokamachi.niigata.jp\0wales\0" -"cng.br\0" -"name.et\0" -"b.bg\0" -"karpacz.pl\0" -"otsuka\0" -"mini\0" -"ar.it\0hikawa.shimane.jp\0\xe5\x95\x86\xe5\x9f\x8e\0" -"homeftp.net\0" -"video.hu\0gs.fm.no\0" -"b.br\0" -"org.ro\0" -"rennes\xc3\xb8y.no\0" -"org.sa\0" -"org.sb\0" -"org.rs\0org.sc\0mint\0" -"sayama.osaka.jp\0nirasaki.yamanashi.jp\0org.sd\0" -"org.se\0org.ru\0" -"gjerstad.no\0" -"kommune.no\0org.sg\0" -"takashima.shiga.jp\0fhs.no\0org.sh\0from-mn.com\0" -"bsb.br\0\xc3\xb8rskog.no\0" -"jfk.museum\0" -"org.sl\0" -"iwatsuki.saitama.jp\0nanto.toyama.jp\0org.sn\0" -"org.so\0" -"kurashiki.okayama.jp\0\xc3\xa5""fjord.no\0\xd2\x9b\xd0\xb0\xd0\xb7\0" -"civilaviation.aero\0clock.museum\0" -"name.cy\0traniandriabarletta.it\0pruszkow.pl\0" -"org.st\0fastvps-server.com\0" -"lib.mn.us\0" -"org.sv\0bms\0" -"mashiki.kumamoto.jp\0" -"asso.re\0org.sy\0" -"sogndal.no\0org.sz\0org.tj\0bmw\0" -"balestrand.no\0" -"org.tm\0insurance\0" -"org.tn\0\xd0\xb5\xd1\x8e\0" -"otofuke.hokkaido.jp\0org.to\0bnl\0citic\0" -"\xc3\xa5rdal.no\0" -"name.eg\0org.ua\0" -"cz.it\0toyohashi.aichi.jp\0skaun.no\0org.tr\0" -"mihama.aichi.jp\0" -"jewelry.museum\0org.tt\0" -"cc.de.us\0" -"org.tw\0org.ug\0" -"lupin\0" -"shoes\0" -"org.uk\0here-for-more.info\0" -"rg.it\0matta-varjjat.no\0" -"\xe5\x95\x86\xe6\xa5\xad.tw\0wedeploy.sh\0" -"bom\0" -"boo\0" -"org.vc\0" -"name.az\0" -"org.ve\0" -"tateyama.chiba.jp\0" -"bot\0" -"chungnam.kr\0blogspot.co.ke\0nhlfan.net\0" -"kanie.aichi.jp\0miura.kanagawa.jp\0org.uy\0org.vi\0" -"ishinomaki.miyagi.jp\0org.uz\0" -"box\0" -"call\0" -"national.museum\0stavern.no\0w.se\0" -"org.vn\0lima-city.de\0" -"aip.ee\0" -"kani.gifu.jp\0" -"wake.okayama.jp\0" -"\xe5\xbe\xb3\xe5\xb3\xb6.jp\0" -"org.vu\0cab\0" -"soeda.fukuoka.jp\0" -"terni.it\0" -"fr.it\0homeunix.org\0" -"\xd0\xbe\xd0\xb1\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0" -"from-sd.com\0" -"cal\0" -"cam\0camp\0blackbaudcdn.net\0" -"hidaka.kochi.jp\0" -"ut.us\0org.ws\0" -"cba\0" -"car\0" -"to.it\0servebeer.com\0" -"cat\0fukusaki.hyogo.jp\0takanezawa.tochigi.jp\0asso.nc\0*.ex.ortsinfo.at\0" -"klabu.no\0k12.ga.us\0" -"lima-city.at\0" -"higashiyama.kyoto.jp\0" -"shikatsu.aichi.jp\0" -"gorizia.it\0cbn\0*.hosting.myjino.ru\0" -"gjerdrum.no\0" -"ikano\0" -"cbs\0" -"wakayama.jp\0" -"mobi.gp\0" -"hasvik.no\0sosnowiec.pl\0apple\0" -"kaita.hiroshima.jp\0org.za\0lima-city.ch\0" -"eidsvoll.no\0" -"siracusa.it\0" -"miharu.fukushima.jp\0" -"palmsprings.museum\0teaches-yoga.com\0" -"ibestad.no\0" -"kagami.kochi.jp\0" -"avocat.pro\0" -"org.zm\0blogspot.co.nz\0" -"foundation.museum\0style\0dattorelay.com\0" -"air-surveillance.aero\0for-more.biz\0" -"toray\0" -"zaporizhzhia.ua\0" -"sande.more-og-romsdal.no\0\xe7\xbd\x91\xe7\xab\x99\0" -"lib.gu.us\0ceb\0" -"org.zw\0" -"jeju.kr\0" -"haebaru.okinawa.jp\0" -"police.uk\0" -"nomi.ishikawa.jp\0is-a-green.com\0" -"divttasvuotna.no\0ceo\0" -"tree.museum\0zt.ua\0" -"yugawara.kanagawa.jp\0v\xc3\xa5gan.no\0cfa\0engineering\0""001www.com\0" -"choshi.chiba.jp\0care\0" -"cfd\0" -"usa.oita.jp\0lowicz.pl\0gifts\0" -"uscountryestate.museum\0is.eu.org\0" -"buy\0" -"kr.it\0missoula.museum\0sohu\0" -"iide.yamagata.jp\0" -"from-sc.com\0" -"casa\0" -"cars\0" -"per.la\0case\0" -"soma.fukushima.jp\0" -"romskog.no\0" -"izumisano.osaka.jp\0cash\0" -"booking\0" -"k12.la.us\0" -"\xe4\xbd\x90\xe8\xb3\x80.jp\0" -"ibigawa.gifu.jp\0" -"asso.km\0" -"muni.il\0karatsu.saga.jp\0science-fiction.museum\0xbox\0" -"ar.us\0" -"valle\xcc\x81""e-d-aoste.it\0" -"kozagawa.wakayama.jp\0it.eu.org\0myvnc.com\0" -"cog.mi.us\0" -"folldal.no\0" -"\xd1\x80\xd1\x84\0" -"honjo.saitama.jp\0asso.mc\0" -"cultural.museum\0per.nf\0cc.ne.us\0" -"tvedestrand.no\0wedeploy.me\0" -"he.cn\0spydeberg.no\0" -"kommunalforbund.se\0" -"rifu.miyagi.jp\0" -"inuyama.aichi.jp\0nishio.aichi.jp\0akagi.shimane.jp\0k12.ny.us\0" -"mormon\0" -"gs.svalbard.no\0" -"jevnaker.no\0lib.me.us\0office\0myshopblocks.com\0" -"shibecha.hokkaido.jp\0" -"tj\xc3\xb8me.no\0bzh\0" -"u.bg\0\xe9\xa3\x9f\xe5\x93\x81\0" -"takatori.nara.jp\0" -"czest.pl\0" -"modelling.aero\0" -"hammarfeasta.no\0" -"ce.it\0gausdal.no\0" -"\xd7\x99\xd7\xa8\xd7\x95\xd7\xa9\xd7\x9c\xd7\x99\xd7\x9d.museum\0square7.net\0edu.krd\0" -"shinjo.nara.jp\0is-very-bad.org\0" -"potenza.it\0" -"jelenia-gora.pl\0localhost.daplie.me\0" -"9guacu.br\0" -"audio\0" -"naples.it\0pr.it\0furano.hokkaido.jp\0kamikawa.hokkaido.jp\0song\0" -"ask\xc3\xb8y.no\0" -"orange\0telecity\0serveblog.net\0" -"orland.no\0" -"ikata.ehime.jp\0" -"name.vn\0mozilla-iot.org\0" -"fund\0" -"in.eu.org\0" -"matsushima.miyagi.jp\0c66.me\0dattoweb.com\0" -"realm.cz\0" -"\xe5\xba\x83\xe5\xb3\xb6.jp\0" -"b.se\0" -"myactivedirectory.com\0" -"sony\0" -"ookuwa.nagano.jp\0" -"berlin\0" -"xj.cn\0barletta-trani-andria.it\0is-a-painter.com\0" -"annaka.gunma.jp\0tsukui.kanagawa.jp\0" -"towada.aomori.jp\0" -"deporte.bo\0fukuyama.hiroshima.jp\0gent\0does-it.net\0" -"bieszczady.pl\0" -"b\xc3\xa1hccavuotna.no\0" -"kikuchi.kumamoto.jp\0surrey.museum\0piaget\0" -"tos.it\0" -"barsy.club\0" -"name.tj\0" -"republican\0" -"aquarelle\0dunlop\0" -"nakagawa.nagano.jp\0" -"environment.museum\0" -"per.sg\0" -"name.tr\0" -"verm\xc3\xb6gensberatung\0customer.enonic.io\0" -"samukawa.kanagawa.jp\0name.tt\0ericsson\0" -"compare\0" -"katagami.akita.jp\0" -"elburg.museum\0blogspot.co.za\0" -"mashiko.tochigi.jp\0imizu.toyama.jp\0" -"seika.kyoto.jp\0gildesk\xc3\xa5l.no\0" -"station.museum\0" -"elvendrell.museum\0" -"kitashiobara.fukushima.jp\0" -"nic.in\0iglesiascarbonia.it\0" -"sunagawa.hokkaido.jp\0bu.no\0" -"com\0\xe9\x9d\x92\xe6\xa3\xae.jp\0" -"ollo\0" -"kashiwa.chiba.jp\0otobe.hokkaido.jp\0" -"shibuya.tokyo.jp\0halsa.no\0\xd0\xbc\xd0\xbe\xd1\x81\xd0\xba\xd0\xb2\xd0\xb0\0*.cns.joyent.com\0" -"catering.aero\0dyn-ip24.de\0" -"s3.dualstack.ap-south-1.amazonaws.com\0" -"\xe7\xbd\x91\xe7\xb5\xa1.hk\0okoppe.hokkaido.jp\0" -"chosei.chiba.jp\0" -"agdenes.no\0\xe5\x85\xab\xe5\x8d\xa6\0" -"vana\0" -"riobranco.br\0" -"cam.it\0canon\0" -"airtel\0" -"vb.it\0" -"higashinaruse.akita.jp\0" -"pizza\0" -"fjell.no\0dad\0myjino.ru\0" -"career\0" -"\xe5\x8f\xb0\xe6\xb9\xbe\0" -"kitaakita.akita.jp\0kr.ua\0*.quipelements.com\0" -"nanmoku.gunma.jp\0musashimurayama.tokyo.jp\0" -"joetsu.niigata.jp\0" -"s3.dualstack.ap-southeast-1.amazonaws.com\0" -"k12.va.us\0" -"macapa.br\0ehime.jp\0" -"yokohama\0" -"radoy.no\0" -"kiyama.saga.jp\0j\xc3\xb8lster.no\0" -"estate.museum\0serveminecraft.net\0" -"reg.dk\0" -"name.qa\0" -"name.pr\0day\0" -"yoshino.nara.jp\0" -"fedorapeople.org\0" -"gunma.jp\0vestv\xc3\xa5g\xc3\xb8y.no\0" -"lombardy.it\0gamo.shiga.jp\0my-gateway.de\0" -"mango\0" -"reisen\0is-an-accountant.com\0" -"crs\0csc\0" -"name.na\0fedorainfracloud.org\0" -"nagara.chiba.jp\0utashinai.hokkaido.jp\0creditcard\0" -"joyo.kyoto.jp\0katowice.pl\0" -"s3.amazonaws.com\0" -"name.mv\0" -"mihama.fukui.jp\0name.ng\0support\0" -"!city.kitakyushu.jp\0name.my\0company\0" -"8.bg\0" -"vix.br\0computerhistory.museum\0" -"fujimi.nagano.jp\0" -"contractors\0" -"nakai.kanagawa.jp\0\xd9\x85\xd9\x84\xd9\x8a\xd8\xb3\xd9\x8a\xd8\xa7\0" -"miyako.iwate.jp\0" -"okawa.fukuoka.jp\0gujo.gifu.jp\0" -"kids.us\0" -"campidano-medio.it\0mishima.fukushima.jp\0" -"nj.us\0" -"karuizawa.nagano.jp\0dds\0groks-the.info\0" -"lu.it\0me.it\0" -"dyndns-ip.com\0" -"campinagrande.br\0education.museum\0" -"trentin-su\xcc\x88""dtirol.it\0sekigahara.gifu.jp\0moss.no\0" -"makeup\0" -"bible.museum\0" -"parachuting.aero\0chikugo.fukuoka.jp\0chernivtsi.ua\0" -"us-west-2.elasticbeanstalk.com\0" -"ballooning.aero\0" -"galsa.no\0gok.pk\0cbre\0wedeploy.io\0" -"bjark\xc3\xb8y.no\0\xe3\x82\xbb\xe3\x83\xbc\xe3\x83\xab\0from-tx.com\0" -"sumoto.kumamoto.jp\0" -"me.ke\0dev\0" -"grosseto.it\0" -"sevastopol.ua\0" -"yakage.okayama.jp\0" -"abiko.chiba.jp\0name.mk\0" -"ap.it\0" -"tm.cy\0center.museum\0belau.pw\0" -"cc.ak.us\0" -"gobo.wakayama.jp\0" -"ma.gov.br\0" -"pr.us\0" -"oshima.tokyo.jp\0no.com\0" -"\xe5\x9c\xa8\xe7\xba\xbf\0" -"taxi.br\0" -"columbus.museum\0" -"hamura.tokyo.jp\0utsira.no\0" -"minami.fukuoka.jp\0swinoujscie.pl\0cc.oh.us\0" -"bjugn.no\0" -"is-a-libertarian.com\0" -"name.jo\0s3-website-eu-west-1.amazonaws.com\0dattolocal.net\0sopot.pl\0" -"noboribetsu.hokkaido.jp\0we.bs\0" -"enebakk.no\0" -"soka.saitama.jp\0mobi.tt\0dhl\0\xeb\x8b\xb7\xec\xbb\xb4\0" -"krager\xc3\xb8.no\0" -"mobi.tz\0" -"minamiboso.chiba.jp\0" -"taa.it\0omihachiman.shiga.jp\0" -"flowers\0" -"\xe5\xae\xae\xe5\xb4\x8e.jp\0nakijin.okinawa.jp\0" -"kamo.kyoto.jp\0" -"londrina.br\0" -"tm.fr\0\xe9\xb9\xbf\xe5\x85\x90\xe5\xb3\xb6.jp\0\xe5\xa8\xb1\xe4\xb9\x90\0" -"kosuge.yamanashi.jp\0eng.pro\0naturbruksgymn.se\0cc.dc.us\0" -"oceanographique.museum\0" -"myhome-server.de\0" -"re.it\0nic.tj\0" -"toki.gifu.jp\0hapmir.no\0diy\0" -"akabira.hokkaido.jp\0\xe5\x85\xac\xe5\x8f\xb8\0\xe6\x97\xb6\xe5\xb0\x9a\0" -"uk.com\0" -"\xe3\x81\xbf\xe3\x82\x93\xe3\x81\xaa\0is-a-blogger.com\0" -"yamagata.gifu.jp\0tosa.kochi.jp\0fusa.no\0" -"psse.gov.pl\0" -"valleaosta.it\0ma.leg.br\0" -"stord.no\0" -"settlers.museum\0" -"gaivuotna.no\0" -"u.se\0s3-eu-west-2.amazonaws.com\0" -"nhs.uk\0" -"cesenaforli\xcc\x80.it\0" -"wolterskluwer\0" -"events\0" -"church\0" -"tm.hu\0ushiku.ibaraki.jp\0glas.museum\0" -"kafjord.no\0gu.us\0" -"aejrie.no\0computer\0" -"iselect\0" -"como.it\0re.kr\0komvux.se\0" -"utazas.hu\0" -"kurobe.toyama.jp\0" -"engineer.aero\0" -"duck\0travelchannel\0" -"from-ia.com\0" -"*.s5y.io\0" -"franziskaner.museum\0" -"omasvuotna.no\0" -"baseball\0" -"tawaramoto.nara.jp\0" -"lecce.it\0" -"pub.sa\0" -"mobi.na\0spot\0" -"midtre-gauldal.no\0" -"toyono.osaka.jp\0" -"k12.tn.us\0catering\0" -"asakawa.fukushima.jp\0pharmaciens.km\0nyc.museum\0mobi.ng\0" -"freeboxos.fr\0" -"realty\0" -"yakumo.shimane.jp\0" -"oshu.iwate.jp\0" +"muosat.no\0" "usa.museum\0" -"trolley.museum\0skanland.no\0" +"oguni.kumamoto.jp\0edu.st\0" +"friuli-ve-giulia.it\0edu.sv\0" +"lg.ua\0" +"edu.sy\0" +"shiwa.iwate.jp\0edu.tj\0cheap\0" +"tysfjord.no\0miami\0" +"edu.tm\0apple\0" +"kunimi.fukushima.jp\0iwi.nz\0" +"edu.to\0" +"edu.ua\0" +"cim.br\0edu.tr\0" +"bindal.no\0arts.ve\0" +"ikaruga.nara.jp\0edu.tt\0" +"edu.tw\0" +"eu-4.evennode.com\0" +"shirahama.wakayama.jp\0" +"yoshioka.gunma.jp\0" +"stuttgart.museum\0sn\xc3\xa5sa.no\0" +"edu.vc\0" +"sicily.it\0" +"edu.ve\0" +"sakahogi.gifu.jp\0daigo.ibaraki.jp\0" +"indianapolis.museum\0edu.uy\0s3.dualstack.eu-central-1.amazonaws.com\0nym.la\0" +"iwamizawa.hokkaido.jp\0buzz\0piaget\0" +"nym.lc\0" +"edu.vn\0" +"o.bg\0" +"pro.ht\0" +"skanland.no\0nym.li\0" +"nym.kz\0" +"riik.ee\0audio\0" +"adachi.tokyo.jp\0" +"edu.vu\0exnet.su\0" +"iselect\0" +"sanjo.niigata.jp\0" +"jamison.museum\0abbvie\0" +"za.bz\0" +"sor-aurdal.no\0" +"adult.ht\0nym.lt\0" +"miners.museum\0is-an-actor.com\0nym.lu\0nym.me\0" +"*.cns.joyent.com\0" +"sv.it\0mukawa.hokkaido.jp\0oshu.iwate.jp\0kawanehon.shizuoka.jp\0krakow.pl\0" +"edu.ws\0" +"asahi.toyama.jp\0nym.mn\0" +"from-ak.com\0" +"preservation.museum\0" +"rec.br\0oga.akita.jp\0" +"okinawa\0" +"chikuho.fukuoka.jp\0" +"nym.mx\0" +"levanger.no\0living\0" +"8.bg\0space-to-rent.com\0" +"tokushima.jp\0wanouchi.gifu.jp\0" +"lifeinsurance\0" +"\xe7\xa6\x8f\xe5\xb3\xb6.jp\0jetzt\0" +"rec.co\0bible.museum\0" +"ibaraki.jp\0usui.fukuoka.jp\0chungbuk.kr\0" +"takamori.kumamoto.jp\0" +"eu-3.evennode.com\0" +"arts.ro\0" +"is-a-lawyer.com\0" +"edu.za\0is-a-student.com\0" +"nym.nz\0" +"nishikatsura.yamanashi.jp\0" +"app.lmpm.com\0" +"po.it\0nishigo.fukushima.jp\0" +"s3.dualstack.us-east-2.amazonaws.com\0" +"fj.cn\0tome.miyagi.jp\0" +"edu.zm\0nym.pe\0" +"v-info.info\0" +"tomakomai.hokkaido.jp\0hosting-cluster.nl\0" +"click\0" +"miharu.fukushima.jp\0" +"r\xc3\xb8st.no\0s3.eu-central-1.amazonaws.com\0" +"midori.chiba.jp\0" +"moriyama.shiga.jp\0" +"natuurwetenschappen.museum\0" +"nym.pt\0" +"pro.na\0moto\0" +"aero.tt\0map.fastly.net\0" +"hidaka.kochi.jp\0" +"crew.aero\0" +"pro.mv\0" +"histoire.museum\0krokstadelva.no\0giving\0" +"microsoft\0" +"ar.us\0" +"sc.cn\0higashiosaka.osaka.jp\0" +"pars\0" +"philadelphia.museum\0lima-city.de\0" +"lib.nv.us\0" +"nakagawa.fukuoka.jp\0" +"\xe4\xb8\xaa\xe4\xba\xba.hk\0nordkapp.no\0" +"aero.mv\0" +"baltimore.museum\0" +"arts.nf\0" +"shiksha\0" +"nym.ro\0" +"pro.om\0" +"eu-2.evennode.com\0" +"google\0" +"nisshin.aichi.jp\0oyamazaki.kyoto.jp\0higashimatsuyama.saitama.jp\0" +"vallee-d-aoste.it\0serveblog.net\0" +"agro.pl\0agrinet.tn\0" +"\xe3\x82\xb0\xe3\x83\xbc\xe3\x82\xb0\xe3\x83\xab\0verm\xc3\xb6gensberatung\0loginto.me\0nym.sk\0" +"kiyokawa.kanagawa.jp\0kagamino.okayama.jp\0" +"zt.ua\0" +"barletta-trani-andria.it\0lima-city.at\0" +"aeroport.fr\0" +"kikonai.hokkaido.jp\0shell\0boomla.net\0" +"nym.su\0" +"pro.pr\0" +"yokohama\0" +"jobs.tt\0nym.sx\0" +"club.aero\0journalism.museum\0symantec\0" +"takamori.nagano.jp\0" +"kamigori.hyogo.jp\0" +"github.io\0" +"reviews\0" +"ariake.saga.jp\0lima-city.ch\0" +"trentinos\xc3\xbc""dtirol.it\0" +"mysecuritycamera.org\0nym.tw\0" +"inzai.chiba.jp\0verisign\0" +"nakagyo.kyoto.jp\0" +"surf\0" +"k12.tn.us\0" +"apps.lair.io\0" +"risor.no\0" +"finn\xc3\xb8y.no\0" +"kafjord.no\0" +"ujitawara.kyoto.jp\0""64-b.it\0" +"eu-1.evennode.com\0" +"hamburg\0dvrcam.info\0" +"minamiaiki.nagano.jp\0" +"mt.eu.org\0" +"abogado\0" +"shimokawa.hokkaido.jp\0" +"ninomiya.kanagawa.jp\0hatogaya.saitama.jp\0" +"batsfjord.no\0" +"kamikoani.akita.jp\0" +"\xd9\x85\xd9\x84\xd9\x8a\xd8\xb3\xd9\x8a\xd8\xa7\0lenug.su\0" +"samnanger.no\0" +"gs.ol.no\0glade\0" +"pro.tt\0\xd9\xbe\xd8\xa7\xd9\x83\xd8\xb3\xd8\xaa\xd8\xa7\xd9\x86\0" +"hn.cn\0" +"mihama.chiba.jp\0" +"stavern.no\0" +"bs.it\0kuji.iwate.jp\0kisosaki.mie.jp\0" +"tydal.no\0\xe5\x85\xac\xe5\x8f\xb8.\xe9\xa6\x99\xe6\xb8\xaf\0" +"cv.ua\0" +"sakado.saitama.jp\0hospital\0" +"sc.ke\0" +"rec.nf\0" +"takatsuki.shiga.jp\0" +"\xe7\xb5\x84\xe7\xb9\x94.\xe9\xa6\x99\xe6\xb8\xaf\0teva\0square7.de\0" +"yuasa.wakayama.jp\0" +"choshi.chiba.jp\0" +"shiroishi.miyagi.jp\0tottori.tottori.jp\0sc.kr\0pro.vn\0thruhere.net\0" +"balashov.su\0cust.disrec.thingdust.io\0" +"tw.cn\0yawara.ibaraki.jp\0" +"lib.pr.us\0" +"kitamoto.saitama.jp\0" +"hurdal.no\0sling\0" +"chonan.chiba.jp\0endofinternet.net\0" +"githubusercontent.com\0" +"sc.ls\0sogndal.no\0" +"judaica.museum\0" +"heguri.nara.jp\0" +"cc.sc.us\0" +"wajima.ishikawa.jp\0" +"sec.ps\0" +"masaki.ehime.jp\0augustow.pl\0" +"imdb\0" +"\xd1\x83\xd0\xbf\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0hdfcbank\0" +"landrover\0" +"costume.museum\0" +"*.compute.amazonaws.com.cn\0" +"history.museum\0alsace\0" +"karatsu.saga.jp\0" +"fukushima.fukushima.jp\0nabari.mie.jp\0" +"skype\0" +"cc.na\0" +"le.it\0rifu.miyagi.jp\0square7.ch\0" +"fla.no\0watches\0backplaneapp.io\0definima.io\0" +"mikasa.hokkaido.jp\0" +"nyc.museum\0" +"seranishi.hiroshima.jp\0nakatane.kagoshima.jp\0" +"aya.miyazaki.jp\0custom.metacentrum.cz\0" +"its.me\0harvestcelebration.museum\0abo.pa\0o.se\0" +"limanowa.pl\0" +"corvette.museum\0" +"artsandcrafts.museum\0watchandclock.museum\0pors\xc3\xa1\xc5\x8bgu.no\0vard\xc3\xb8.no\0" +"naruto.tokushima.jp\0" +"devices.resinstaging.io\0" +"rec.ro\0accenture\0" +"boston.museum\0sciences.museum\0" +"takayama.gifu.jp\0abashiri.hokkaido.jp\0" +"dyndns-wiki.com\0" +"solutions\0" +"minamata.kumamoto.jp\0" +"s\xc3\xb8r-aurdal.no\0" +"ibaraki.ibaraki.jp\0" +"fantasyleague.cc\0" +"vet.br\0\xe5\xb2\xa9\xe6\x89\x8b.jp\0inabe.mie.jp\0" +"pila.pl\0" +"balestrand.no\0hornindal.no\0" +"virgin\0" +"hepforge.org\0" +"ukiha.fukuoka.jp\0" +"ol.no\0" +"ufcfan.org\0" +"ino.kochi.jp\0" +"farmstead.museum\0" +"community.museum\0land-4-sale.us\0" +"kaneyama.yamagata.jp\0" +"topology.museum\0\xc3\xa1laheadju.no\0aurskog-h\xc3\xb8land.no\0" +"tec.ve\0" +"kumakogen.ehime.jp\0ujiie.tochigi.jp\0" +"idrett.no\0" +"esp.br\0" +"is-a-guru.com\0" +"ikawa.akita.jp\0kamitsue.oita.jp\0" +"\xe7\xb6\xb2\xe7\xb5\xa1.\xe9\xa6\x99\xe6\xb8\xaf\0" +"alt.za\0xnbay.com\0" +"ragusa.it\0" +"scienceandindustry.museum\0holmestrand.no\0lib.wi.us\0" +"minokamo.gifu.jp\0chikusei.ibaraki.jp\0definima.net\0" +"uz.ua\0" +"cal.it\0" +"trento.it\0twmail.net\0" +"aero\0halsa.no\0" +"\xe5\xae\xae\xe5\xb4\x8e.jp\0" +"rec.ve\0nohost.me\0" +"mifune.kumamoto.jp\0" +"skj\xc3\xa5k.no\0my.eu.org\0" +"kuzumaki.iwate.jp\0" +"net.ac\0academia.bo\0s3-ca-central-1.amazonaws.com\0" +"dnsking.ch\0" +"net.ae\0" +"net.af\0umb.it\0" +"net.ag\0alaheadju.no\0hobol.no\0aaa\0" +"ojiya.niigata.jp\0yamanakako.yamanashi.jp\0" +"net.ai\0communication.museum\0grong.no\0" +"net.al\0imb.br\0cartier\0" +"juif.museum\0bardu.no\0surnadal.no\0accesscam.org\0" +"read\0" +"net.ba\0kaluga.su\0" +"net.ar\0net.bb\0aquila.it\0kuriyama.hokkaido.jp\0" +"inazawa.aichi.jp\0chat\0" +"net.au\0" +"hemne.no\0" +"net.bh\0abb\0" +"windmill.museum\0spydeberg.no\0abc\0ditchyourip.com\0" +"net.az\0citadel\0" +"pccw\0" +"okagaki.fukuoka.jp\0ginowan.okinawa.jp\0" +"net.bm\0" +"net.bn\0takazaki.miyazaki.jp\0" +"net.bo\0askim.no\0l\xc3\xb8renskog.no\0sc.ug\0" +"ap.it\0" +"deals\0" +"net.br\0sc.tz\0" +"net.bs\0k12.al.us\0cc.ua\0" +"net.bt\0tainai.niigata.jp\0kakinoki.shimane.jp\0pcloud.host\0" +"stuff-4-sale.us\0" +"gobo.wakayama.jp\0" +"takikawa.hokkaido.jp\0" +"net.ci\0" +"net.bz\0my.id\0" +"sc.us\0" +"net.cm\0energy\0" +"net.cn\0konan.aichi.jp\0biratori.hokkaido.jp\0" +"net.co\0coupons\0" +"ownip.net\0gotdns.ch\0" +"gonohe.aomori.jp\0inawashiro.fukushima.jp\0jp.net\0" +"net.cu\0coloradoplateau.museum\0giessen.museum\0aco\0" +"act.edu.au\0net.cw\0" +"shimodate.ibaraki.jp\0" +"net.cy\0" +"hjelmeland.no\0" +"net.dm\0" +"net.do\0" +"joinville.br\0" +"unj\xc3\xa1rga.no\0immo\0\xe5\xa4\xa7\xe6\x8b\xbf\0dyndns-web.com\0" +"net.ec\0rennesoy.no\0" +"komvux.se\0" +"net.eg\0memorial.museum\0" +"ads\0science\0" +"net.dz\0minato.tokyo.jp\0" +"aeg\0" +"quest\0" +"cymru.museum\0" +"trentin-s\xc3\xbc""d-tirol.it\0" +"muenchen.museum\0" +"net.et\0" +"h\xc3\xa1""bmer.no\0" +"yonabaru.okinawa.jp\0" +"loyalist.museum\0" +"galsa.no\0s3-website-sa-east-1.amazonaws.com\0" +"from-nv.com\0" +"trentino-s\xc3\xbc""dtirol.it\0" +"nl.eu.org\0" +"england.museum\0" +"afl\0" +"comunica\xc3\xa7\xc3\xb5""es.museum\0" +"theater\0" +"net.ge\0" +"yamaga.kumamoto.jp\0" +"urn.arpa\0net.gg\0" +"bozen-suedtirol.it\0honjyo.akita.jp\0" +"vik.no\0" +"net.gl\0" +"rindal.no\0glass\0" +"net.gn\0" +"tvedestrand.no\0internet-dns.de\0" +"net.gp\0kozaki.chiba.jp\0rzgw.gov.pl\0ravendb.run\0" +"dontexist.org\0" +"net.gr\0nishimera.miyazaki.jp\0" +"net.gt\0" +"net.gu\0" +"alabama.museum\0" +"net.gy\0asso.eu.org\0freeddns.us\0" +"net.hk\0gs.st.no\0fairwinds\0africa.com\0" +"morena.br\0" +"net.hn\0minamimaki.nagano.jp\0" +"tagami.niigata.jp\0nakagawa.tokushima.jp\0" +"name\0my-router.de\0" +"net.ht\0net.id\0" +"m.bg\0" +"eu-west-1.elasticbeanstalk.com\0" +"net.il\0" +"net.im\0stathelle.no\0aig\0" +"net.in\0modena.it\0" +"from-wv.com\0" +"net.iq\0\xc3\xa5lg\xc3\xa5rd.no\0hoteles\0" +"net.ir\0williamhill\0" +"net.is\0newspaper.museum\0" +"niteroi.br\0" +"net.je\0jewelry\0" +"chuo.osaka.jp\0" +"ap-southeast-1.elasticbeanstalk.com\0us-west-1.elasticbeanstalk.com\0" +"hirono.fukushima.jp\0" +"uri.arpa\0guernsey.museum\0lancashire.museum\0sn\xc3\xa5""ase.no\0" +"soma.fukushima.jp\0onomichi.hiroshima.jp\0urausu.hokkaido.jp\0" +"barreau.bj\0" +"fujioka.gunma.jp\0komatsushima.tokushima.jp\0reit\0" +"net.jo\0police.uk\0" +"niiza.saitama.jp\0" +"isa-geek.org\0" +"la-spezia.it\0" +"sm\xc3\xb8la.no\0barsy.info\0" +"travelers\0" +"ct.it\0kitagata.gifu.jp\0crown\0" +"net.kg\0valle.no\0" +"samegawa.fukushima.jp\0" +"net.ki\0is-an-accountant.com\0" +"nowtv\0" +"in-addr.arpa\0" +"6.bg\0" +"oamishirasato.chiba.jp\0tarama.okinawa.jp\0net.kn\0" +"net.la\0" +"lucca.it\0net.lb\0" +"net.lc\0" +"net.kw\0" +"midori.gunma.jp\0sayama.saitama.jp\0mincom.tn\0" +"net.ky\0encyclopedic.museum\0*.0emm.com\0" +"net.kz\0" +"net.lk\0" +"dgca.aero\0" +"shirataka.yamagata.jp\0kinder\0" +"ng.eu.org\0" +"net.ma\0air.museum\0" +"ogawa.nagano.jp\0net.lr\0" +"net.ls\0is-a-socialist.com\0co.network\0" +"net.me\0courses\0" +"ichinomiya.chiba.jp\0kishiwada.osaka.jp\0net.lv\0" +"sa.au\0fortmissoula.museum\0" +"emb.kw\0net.ly\0" +"net.mk\0lib.as.us\0luxury\0" +"osaki.miyagi.jp\0net.ml\0" +"hamura.tokyo.jp\0capital\0" +"net.mo\0" +"info\0" +"oishida.yamagata.jp\0" +"net.ms\0eigersund.no\0" +"biella.it\0net.mt\0" +"net.mu\0" +"net.mv\0net.nf\0" +"virtual.museum\0net.mw\0net.ng\0" +"net.mx\0" +"net.my\0net.ni\0cc.ct.us\0" +"net.mz\0" +"torino.museum\0" +"uruma.okinawa.jp\0stalowa-wola.pl\0azure-mobile.net\0" +"aarborte.no\0dnsfor.me\0" +"odesa.ua\0" +"nanbu.yamanashi.jp\0net.nr\0" +"sa.cr\0" +"lib.oh.us\0" +"st.no\0" +"taiji.wakayama.jp\0" +"net.nz\0" +"couchpotatofries.org\0" +"search\0" +"net.om\0" +"pinb.gov.pl\0rent\0" +"game-server.cc\0" +"anz\0" +"net.pa\0" +"aol\0" +"friuli-veneziagiulia.it\0oiso.kanagawa.jp\0muika.niigata.jp\0" +"artgallery.museum\0handson.museum\0net.pe\0on-aptible.com\0" +"enna.it\0" +"honefoss.no\0press\0" +"net.ph\0etisalat\0" +"s\xc3\xb8rum.no\0net.pk\0" +"net.pl\0" +"wios.gov.pl\0net.pn\0" +"servepics.com\0" +"marugame.kagawa.jp\0" +"net.qa\0" +"joso.ibaraki.jp\0tsubame.niigata.jp\0net.pr\0" +"net.ps\0myfirewall.org\0" +"bergamo.it\0rishirifuji.hokkaido.jp\0ina.nagano.jp\0kokubunji.tokyo.jp\0net.pt\0" +"sweetpepper.org\0" +"app\0" +"benevento.it\0" +"net.py\0" +"akita.akita.jp\0" +"s3-website-ap-northeast-1.amazonaws.com\0" +"forgot.her.name\0" "shinshiro.aichi.jp\0" -"tm.km\0" -"vistaprint\0" +"scotland.museum\0" +"\xe5\x85\xb5\xe5\xba\xab.jp\0" +"sassari.it\0okuma.fukushima.jp\0" +"mypi.co\0" +"numazu.shizuoka.jp\0\xe7\xbb\x84\xe7\xbb\x87\xe6\x9c\xba\xe6\x9e\x84\0" +"ris\xc3\xb8r.no\0" +"fuefuki.yamanashi.jp\0bar\0" +"bbc\0" +"toscana.it\0atsugi.kanagawa.jp\0settsu.osaka.jp\0kusatsu.shiga.jp\0yamada.toyama.jp\0" +"\xe0\xb8\xa3\xe0\xb8\xb1\xe0\xb8\x90\xe0\xb8\x9a\xe0\xb8\xb2\xe0\xb8\xa5.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" +"omitama.ibaraki.jp\0" +"net.sa\0kindle\0" +"net.sb\0" +"net.sc\0" +"net.sd\0dunlop\0" +"net.ru\0myftp.org\0" +"sekikawa.niigata.jp\0" +"hemsedal.no\0net.rw\0net.sg\0navy\0" +"niimi.okayama.jp\0net.sh\0" +"kamifurano.hokkaido.jp\0art\0bbt\0" +"kumejima.okinawa.jp\0net.sl\0" +"broker.aero\0bcg\0" +"fet.no\0net.so\0nsupdate.info\0" +"dagestan.ru\0" +"property\0" +"iki.nagasaki.jp\0net.st\0bcn\0" +"prof.pr\0net.th\0walter\0" +"net.sy\0" +"net.tj\0" +"sor-varanger.no\0net.tm\0" +"net.tn\0rest\0" +"net.to\0" +"unjarga.no\0net.ua\0dagestan.su\0" +"net.tr\0" +"cargo.aero\0" +"aizubange.fukushima.jp\0kamo.niigata.jp\0net.tt\0" +"society.museum\0ebiz.tw\0" +"sa.it\0" +"net.tw\0localhost.daplie.me\0" +"net.uk\0cards\0organic\0" +"hl.cn\0\xd0\xba\xd0\xbe\xd0\xbc\0""32-b.it\0" +"diamonds\0" +"naganohara.gunma.jp\0" +"vennesla.no\0blogdns.org\0" +"ca.it\0" +"lib.co.us\0" +"kyotango.kyoto.jp\0" +"safety.aero\0net.vc\0\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4\xe0\xa4\xae\xe0\xa5\x8d\0cyon.link\0" +"sandvikcoromant\0" +"net.ve\0" +"koge.tottori.jp\0guardian\0" +"hof.no\0net.uy\0net.vi\0" +"net.uz\0bet\0" +"sakae.chiba.jp\0" +"net.vn\0" +"ekloges.cy\0bryne.no\0kpmg\0" +"dyndns-home.com\0" +"\xe5\xa4\xa7\xe5\x88\x86.jp\0higashimatsushima.miyagi.jp\0" +"gmbh\0\xe7\xa7\xbb\xe5\x8a\xa8\0" +"ct.us\0net.vu\0" +"wsa.gov.pl\0" +"gemological.museum\0" +"pistoia.it\0travel.pl\0" +"realtor\0" +"vindafjord.no\0k12.mn.us\0viajes\0" "tysnes.no\0" -"pp.az\0pors\xc3\xa1\xc5\x8bgu.no\0" -"even\xc3\xa1\xc5\xa1\xc5\xa1i.no\0dnp\0tickets\0" -"datsun\0home-webserver.de\0" -"valer.ostfold.no\0blogsite.xyz\0" -"murmansk.su\0brasilia.me\0" -"dog\0schule\0" -"vic.au\0" -"space.museum\0" -"takata.fukuoka.jp\0zero\0" -"sel.no\0" -"shimokitayama.nara.jp\0tm.mc\0brandywinevalley.museum\0" -"nuremberg.museum\0homegoods\0kiwi\0ap-northeast-2.elasticbeanstalk.com\0" -"tm.mg\0" -"bergamo.it\0dot\0" -"from-tn.com\0" -"yatomi.aichi.jp\0narita.chiba.jp\0drobak.no\0" -"transport.museum\0" -"carrara-massa.it\0" -"me.tz\0wanggou\0" -"me.uk\0" -"gs.jan-mayen.no\0" -"ichinomiya.chiba.jp\0" -"uenohara.yamanashi.jp\0" -"me.us\0" -"ushuaia.museum\0" -"bizen.okayama.jp\0" -"koori.fukushima.jp\0" -"ac\0aarp\0" -"ad\0tm.no\0" -"ae\0orskog.no\0" -"af\0" -"ag\0" -"perugia.it\0" -"ai\0lewismiller.museum\0monster\0" -"izumizaki.fukushima.jp\0" -"al\0" -"am\0karasjok.no\0eat\0" -"tas.edu.au\0ferrero\0dyn-o-saur.com\0" -"ao\0kiyokawa.kanagawa.jp\0cheap\0" -"aq\0ba\0" -"ar\0bb\0" -"as\0dupont\0from-wi.com\0" -"at\0leirfjord.no\0" -"au\0be\0sh.cn\0kunst.museum\0" -"bf\0shiojiri.nagano.jp\0mobi.ke\0" -"asn.au\0aw\0bg\0wakkanai.hokkaido.jp\0" -"ax\0bh\0" -"bi\0" -"az\0bj\0" -"forli-cesena.it\0" -"air.museum\0" -"bm\0jewelry\0" -"bn\0" -"bo\0lorenskog.no\0" -"ca\0kuroishi.aomori.jp\0hirono.fukushima.jp\0tm.pl\0credit\0ggee\0" -"br\0yawara.ibaraki.jp\0" -"bs\0cc\0" -"bt\0cd\0" -"bv\0cf\0artsandcrafts.museum\0kosher\0neustar\0" -"bw\0cg\0" -"ch\0eco\0" -"by\0ci\0" -"bz\0total\0" -"cl\0" -"media.aero\0cm\0cc.ms.us\0cc.nc.us\0hyatt\0" -"trading.aero\0cn\0isen.kagoshima.jp\0wegrow.pl\0northwesternmutual\0" -"co\0" -"mino.gifu.jp\0nflfan.org\0" -"cr\0assabu.hokkaido.jp\0" -"gs.cn\0" -"cu\0de\0" -"cv\0" -"cw\0s3-website-us-west-1.amazonaws.com\0" -"cx\0servebbs.net\0" -"cy\0" -"cz\0dj\0" -"dk\0portland.museum\0" -"fst.br\0dm\0" +"net.ws\0" +"axa\0place\0visa\0isa-geek.com\0" +"civilisation.museum\0aws\0u2-local.xnbay.com\0" +"ppg.br\0" +"\xe5\x95\x86\xe5\xba\x97\0" +"kami.kochi.jp\0sado.niigata.jp\0" +"cc.ca.us\0kerrylogistics\0" +"puglia.it\0" +"siljan.no\0" +"toyohashi.aichi.jp\0" +"xfinity\0" +"lomza.pl\0bid\0" +"evenes.no\0" +"monmouth.museum\0ca.na\0" +"lc.it\0" +"lib.nm.us\0" +"cloudaccess.net\0" +"gs.hl.no\0lv.ua\0net.za\0""1337.pictures\0" +"iwafune.tochigi.jp\0tokushima.tokushima.jp\0" +"bio\0inc.hk\0" +"m.se\0online\0" +"seven\0" +"sukumo.kochi.jp\0" +"net.zm\0" +"rochester.museum\0dynserv.org\0" +"biz\0watari.miyagi.jp\0" +"tokyo\0" +"yasuoka.nagano.jp\0" +"koshigaya.saitama.jp\0tjmaxx\0" +"democracia.bo\0" +"tur.ar\0" +"stavanger.no\0theatre\0viva\0myds.me\0" +"bilbao.museum\0webcam\0" +"tienda\0" +"hashimoto.wakayama.jp\0" +"cosenza.it\0" +"louvre.museum\0askoy.no\0boxfuse.io\0" +"travel.tt\0" +"\xd0\xb1\xd0\xb3\0is-a-celticsfan.org\0" +"vivo\0cleverapps.io\0" +"riopreto.br\0tur.br\0" +"walmart\0" +"manchester.museum\0" +"asahi.nagano.jp\0" +"valer.hedmark.no\0fh.se\0" +"wiki.bo\0cc.ks.us\0\xe8\xb4\xad\xe7\x89\xa9\0" +"homeip.net\0" +"wiki.br\0imakane.hokkaido.jp\0" +"snoasa.no\0" +"kumagaya.saitama.jp\0" +"tromsa.no\0" +"hob\xc3\xb8l.no\0" +"ecn.br\0koza.wakayama.jp\0" +"krym.ua\0" +"filegear-de.me\0" +"toyama.toyama.jp\0" +"rygge.no\0istmein.de\0" +"jewish.museum\0usgarden.museum\0raisa.no\0endofinternet.org\0" +"bms\0" +"ryokami.saitama.jp\0" +"\xe0\xb8\x84\xe0\xb8\xad\xe0\xb8\xa1\0" +"haugesund.no\0bmw\0" +"homeunix.net\0" +"asn.au\0" +"messina.it\0bnl\0" +"lazio.it\0" +"*.in.futurecms.at\0" +"val-d-aosta.it\0pa.leg.br\0" +"\xe9\xa3\x9e\xe5\x88\xa9\xe6\xb5\xa6\0" +"gorlice.pl\0" +"assn.lk\0bom\0" +"kanna.gunma.jp\0" +"timekeeping.museum\0boo\0" +"ardal.no\0" +"monza.it\0fukuoka.jp\0" +"tksat.bo\0" +"an.it\0bot\0" +"sandnessjoen.no\0" +"calvinklein\0report\0" +"hl.no\0\xe9\x9b\xbb\xe8\xa8\x8a\xe7\x9b\x88\xe7\xa7\x91\0" +"genova.it\0box\0" +"epilepsy.museum\0geology.museum\0casino\0" +"pordenone.it\0" +"ostroda.pl\0" +"tana.no\0" +"tochigi.tochigi.jp\0" +"opole.pl\0" +"sucks\0" +"cab\0" +"artanddesign.museum\0" +"webredirect.org\0" +"kashiwa.chiba.jp\0pb.leg.br\0" +"tele.amune.org\0dnsalias.com\0" +"kiwi.nz\0\xd0\xb5\xd1\x8e\0honeywell\0" +"ca.us\0" +"cal\0" +"space.museum\0cam\0" +"rankoshi.hokkaido.jp\0rawa-maz.pl\0" +"zama.kanagawa.jp\0" +"k12.mi.us\0cba\0" +"car\0" +"journalist.aero\0synology-ds.de\0" +"cat\0" +"rehab\0" +"r\xc3\xb8mskog.no\0" +"dynv6.net\0" +"tychy.pl\0" +"cbn\0" +"\xe3\x82\xbb\xe3\x83\xbc\xe3\x83\xab\0" +"cbs\0stuff-4-sale.org\0" +"shell.museum\0cloud.fedoraproject.org\0" +"sport\0" +"rsc.cdn77.org\0" +"omachi.nagano.jp\0" +"biev\xc3\xa1t.no\0tennis\0tiaa\0" +"ichinoseki.iwate.jp\0" +"time.museum\0" +"trading.aero\0" +"citi\0from-ma.com\0" +"ks.ua\0twmail.org\0synology-diskstation.de\0" +"anani.br\0dupont\0" +"\xd0\xb8\xd0\xba\xd0\xbe\xd0\xbc.museum\0" +"jpmorgan\0router.management\0" +"lincoln\0lixil\0" +"valle-aosta.it\0ceb\0" +"city\0" +"nuoro.it\0iheya.okinawa.jp\0" +"saitama.jp\0kamimine.saga.jp\0" +"ks.us\0" +"nakano.nagano.jp\0" +"patria.bo\0md.ci\0" +"ceo\0" +"cfa\0from-pa.com\0" +"tono.iwate.jp\0r.cdn77.net\0" +"artdeco.museum\0civilization.museum\0bodo.no\0kiev.ua\0" +"fujisato.akita.jp\0obama.nagasaki.jp\0cfd\0" +"int.ar\0" +"klabu.no\0radio\0" +"buy\0" +"ddnsgeek.com\0servesarcasm.com\0" +"olbia-tempio.it\0" +"k.bg\0\xc3\xb8rsta.no\0skodje.no\0" +"int.az\0otsuki.kochi.jp\0""16-b.it\0" +"mine.nu\0" +"naie.hokkaido.jp\0" +"int.bo\0algard.no\0" +"trentino-s\xc3\xbc""d-tirol.it\0" +"khakassia.su\0" +"kure.hiroshima.jp\0land\0" +"s\xc3\xb8rfold.no\0" +"kaisei.kanagawa.jp\0ohira.tochigi.jp\0" +"grane.no\0codespot.com\0" +"shikabe.hokkaido.jp\0targi.pl\0" +"takayama.nagano.jp\0itoigawa.niigata.jp\0zachpomor.pl\0" +"empresa.bo\0int.ci\0" +"mochizuki.nagano.jp\0" +"is-very-good.org\0webhop.org\0" +"fortal.br\0sr.it\0\xda\x80\xd8\xa7\xd8\xb1\xd8\xaa\0" +"per.la\0" +"int.co\0gjerdrum.no\0" +"vanguard\0" +"saltdal.no\0" +"magazine.aero\0" +"sciencesnaturelles.museum\0\xc3\xa5snes.no\0" +"cr.it\0" +"bievat.no\0lib.fl.us\0" +"obihiro.hokkaido.jp\0" +"ringebu.no\0cc.wi.us\0" +"4.bg\0" +"higashi.fukuoka.jp\0" +"l\xc3\xb8""dingen.no\0est-le-patron.com\0" +"mod.gi\0naturalhistorymuseum.museum\0hemnes.no\0" +"tadotsu.kagawa.jp\0" +"missoula.museum\0supply\0cable-modem.org\0" +"schmidt\0dynu.net\0nerdpol.ovh\0" +"getmyip.com\0" +"asn.lv\0" +"zapto.org\0" +"kyowa.akita.jp\0now.sh\0" +"lancome\0" +"odo.br\0shunan.yamaguchi.jp\0per.nf\0" +"nsn.us\0" +"salvador.br\0omaezaki.shizuoka.jp\0bzh\0" +"circus.museum\0" +"unnan.shimane.jp\0" +"gripe\0" +"shriram\0" +"cnt.br\0nikaho.akita.jp\0meiwa.gunma.jp\0" +"omega\0otsuka\0" +"toyoake.aichi.jp\0omura.nagasaki.jp\0" +"extraspace\0" +"game-host.org\0" +"udine.it\0\xd1\x80\xd1\x84\0" +"bulsan-suedtirol.it\0iglesiascarbonia.it\0" +"niki.hokkaido.jp\0" +"from-va.com\0" +"noshiro.akita.jp\0agano.niigata.jp\0" +"vega.no\0" +"lt.it\0suwalki.pl\0" +"yahiko.niigata.jp\0" +"usarts.museum\0hoyanger.no\0from-wa.com\0" +"oita.oita.jp\0" +"\xe3\x81\xbf\xe3\x82\x93\xe3\x81\xaa\0" +"childrensgarden.museum\0" +"tarnobrzeg.pl\0\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\x82\xe0\xa6\xb2\xe0\xa6\xbe\0" +"tajiri.osaka.jp\0toyono.osaka.jp\0" +"auto.pl\0cloudycluster.net\0" +"compare\0" +"barsy.club\0" +"r\xc3\xb8yrvik.no\0kids.us\0" +"trentinoaadige.it\0" +"saga.saga.jp\0" +"gs.vf.no\0zp.ua\0" +"tokyo.jp\0stargard.pl\0kred\0" +"int.is\0" +"nx.cn\0molise.it\0isa-geek.net\0" +"im.it\0" +"hyogo.jp\0toei.aichi.jp\0" +"vaga.no\0" +"jelenia-gora.pl\0" +"kvalsund.no\0" +"pi.leg.br\0" +"pilot.aero\0per.sg\0" +"trieste.it\0shimizu.hokkaido.jp\0seika.kyoto.jp\0" +"television.museum\0" +"coupon\0" +"bykle.no\0cc.md.us\0" +"com\0dscloud.mobi\0" +"dattoweb.com\0" +"tr.eu.org\0" +"tamba.hyogo.jp\0dynalias.net\0" +"int.la\0" +"teramo.it\0" +"lyngen.no\0" +"shimotsuke.tochigi.jp\0" +"secure\0" +"americanantiques.museum\0" +"cooking\0" +"\xd0\xbc\xd0\xba\xd0\xb4\0" +"int.lk\0ambulance.museum\0" +"takashima.shiga.jp\0" +"unusualperson.com\0" +"tushu\0" +"dad\0" +"2000.hu\0luroy.no\0" +"iamallama.com\0" +"radio.br\0" +"romsa.no\0" +"wi.us\0" +"noheji.aomori.jp\0nowruz\0" +"ozu.ehime.jp\0" +"arna.no\0ro.im\0" +"xj.cn\0" +"ato.br\0" +"vagan.no\0day\0" +"ro.it\0int.mv\0construction\0freebox-os.fr\0" +"int.mw\0" +"int.ni\0" +"gz.cn\0capetown\0" +"company\0" +"qsl.br\0" +"alfaromeo\0crs\0csc\0video\0" +"sp.gov.br\0bo.it\0" +"anamizu.ishikawa.jp\0sakae.nagano.jp\0" +"cr.ua\0" +"cloudfunctions.net\0" +"siena.it\0" +"tips\0" +"ashiya.hyogo.jp\0" +"myactivedirectory.com\0" +"kaminoyama.yamagata.jp\0" +"from-ca.com\0" +"tobe.ehime.jp\0nikko.tochigi.jp\0sko.gov.pl\0" +"otago.museum\0washingtondc.museum\0" +"shiranuka.hokkaido.jp\0" +"oceanographic.museum\0rana.no\0" +"divtasvuodna.no\0" +"vf.no\0meloy.no\0k12.mt.us\0insurance\0" +"koebenhavn.museum\0aigo\0dds\0" +"oyer.no\0netlify.com\0" +"shakotan.hokkaido.jp\0" +"\xd0\xbc\xd0\xbe\xd0\xbd\0" +"int.pt\0" +"\xe6\x95\x99\xe8\x82\xb2.\xe9\xa6\x99\xe6\xb8\xaf\0" +"from-ia.com\0" +"hita.oita.jp\0" +"\xd0\xbe\xd0\xb1\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0" +"\xd8\xa7\xdb\x8c\xd8\xb1\xd8\xa7\xd9\x86\0" +"seihi.nagasaki.jp\0" +"geekgalaxy.com\0" +"taketa.oita.jp\0mutual\0" +"dev\0" +"research.aero\0mytis.ru\0" +"gratangen.no\0" +"mihara.kochi.jp\0gyokuto.kumamoto.jp\0" +"takaishi.osaka.jp\0so.gov.pl\0" +"from-ga.com\0" +"furubira.hokkaido.jp\0ayabe.kyoto.jp\0" +"lt.ua\0s3-website.eu-west-3.amazonaws.com\0" +"tateyama.chiba.jp\0ohira.miyagi.jp\0pe.leg.br\0" +"larvik.no\0verdal.no\0" +"geometre-expert.fr\0" +"int.ru\0" +"biz.bb\0" +"int.rw\0k.se\0" +"hakata.fukuoka.jp\0czest.pl\0biz.at\0" +"wildlife.museum\0spreadbetting\0" +"otaki.chiba.jp\0suzu.ishikawa.jp\0" +"mydobiss.com\0" +"stpetersburg.museum\0cc.oh.us\0zone\0diskstation.me\0" +"biz.az\0miasta.pl\0" +"ask\xc3\xb8y.no\0" +"yoshimi.saitama.jp\0" +"md.us\0physio\0" +"maebashi.gunma.jp\0" +"ferrara.it\0" +"dhl\0scrapper-site.net\0" +"ann-arbor.mi.us\0" +"int.tj\0" +"lifestyle\0" +"ishikawa.fukushima.jp\0" +"diskstation.eu\0" +"toyooka.hyogo.jp\0oi.kanagawa.jp\0" +"maringa.br\0\xd8\xa7\xdb\x8c\xd8\xb1\xd8\xa7\xd9\x86.ir\0" +"kragero.no\0vinnica.ua\0co.place\0" +"blogdns.net\0" +"int.tt\0" +"baidar.no\0\xd0\xbe\xd0\xb4.\xd1\x81\xd1\x80\xd0\xb1\0" +"biz.cy\0law.pro\0" +"biz.dk\0" +"fuchu.tokyo.jp\0for-some.biz\0" +"*.sch.uk\0cc.la.us\0" +"shintoku.hokkaido.jp\0" +"airport.aero\0study\0" +"int.ve\0diy\0grocery\0certmgr.org\0" +"hiphop\0" +"booking\0homeunix.org\0" +"matsushige.tokushima.jp\0" +"ts.it\0" +"wajiki.tokushima.jp\0int.vn\0" +"ltd.co.im\0" +"hawaii.museum\0" +"chikuzen.fukuoka.jp\0" +"est-a-la-masion.com\0" +"biz.et\0" +"marriott\0" +"apigee.io\0" +"yuu.yamaguchi.jp\0" +"natal.br\0hachinohe.aomori.jp\0" +"sayama.osaka.jp\0" +"9guacu.br\0budapest\0" +"camera\0" +"showa.gunma.jp\0" +"eating-organic.net\0" +"hirata.fukushima.jp\0" +"wales\0dnsdojo.org\0" +"snasa.no\0stream\0dontexist.com\0" +"kuokgroup\0\xd8\xb9\xd8\xb1\xd8\xa8\0" +"m\xc3\xa5s\xc3\xb8y.no\0" +"nishi.fukuoka.jp\0" +"ddnss.org\0" +"ritto.shiga.jp\0" +"n\xc3\xa6r\xc3\xb8y.no\0" +"al.it\0" +"isla.pr\0" +"ide.kyoto.jp\0" +"tecnologia.bo\0" +"biz.id\0" +"zaporizhzhia.ua\0" +"kppsp.gov.pl\0dnp\0" +"birkenes.no\0" +"omuta.fukuoka.jp\0" +"\xe6\x94\xbf\xe5\xba\x9c.\xe9\xa6\x99\xe6\xb8\xaf\0" +"carbonia-iglesias.it\0" +"arai.shizuoka.jp\0hokuto.yamanashi.jp\0" +"dog\0" +"nara.nara.jp\0" +"swidnica.pl\0" +"storage\0" +"from-ny.net\0" +"brussel.museum\0stordal.no\0" +"mitane.akita.jp\0" +"botanicgarden.museum\0asker.no\0" +"judygarland.museum\0" +"ne.jp\0yono.saitama.jp\0dot\0" +"hiji.oita.jp\0oshima.tokyo.jp\0futurehosting.at\0" +"pri.ee\0ne.ke\0atlanta.museum\0" +"gold\0" +"golf\0" +"oh.us\0" +"sr.gov.pl\0" +"como.it\0" +"biz.ki\0cc.al.us\0" +"sarufutsu.hokkaido.jp\0arida.wakayama.jp\0" +"mashiko.tochigi.jp\0chizu.tottori.jp\0bosch\0global\0beep.pl\0" +"izumizaki.fukushima.jp\0ne.kr\0pr.leg.br\0" +"samsung\0" +"realestate.pl\0" +"daito.osaka.jp\0asaka.saitama.jp\0" +"kiho.mie.jp\0" +"gloppen.no\0porsangu.no\0" +"snaase.no\0uk.eu.org\0" +"bologna.it\0eat\0" +"yaita.tochigi.jp\0" +"kawagoe.mie.jp\0kalisz.pl\0tourism.tn\0" +"al.no\0" +"biz.ls\0cc.ne.us\0is-a-liberal.com\0" +"mb.ca\0" +"higashikurume.tokyo.jp\0" +"kv\xc3\xa6nangen.no\0la.us\0" +"ginan.gifu.jp\0" +"*.hosting.myjino.ru\0lima-city.rocks\0" +"!city.nagoya.jp\0" +"k12.vi.us\0ap-northeast-2.elasticbeanstalk.com\0" +"legnica.pl\0" +"rich\0" +"goog\0*.transurl.be\0" +"oketo.hokkaido.jp\0biz.mv\0starostwo.gov.pl\0" +"biz.mw\0vegarshei.no\0eco\0is-very-sweet.org\0blogsyte.com\0" +"fujikawa.yamanashi.jp\0" +"biz.ni\0" +"lig.it\0napoli.it\0aioi.hyogo.jp\0okuizumo.shimane.jp\0" +"gallo\0" +"tohma.hokkaido.jp\0rep.kp\0" +"i.bg\0" +"taishin.fukushima.jp\0sumita.iwate.jp\0hamatama.saga.jp\0" +"yk.ca\0reise\0" +"iwaki.fukushima.jp\0biz.nr\0" +"andebu.no\0karaganda.su\0" +"hamada.shimane.jp\0" +"finland.museum\0helsinki.museum\0" +"onagawa.miyagi.jp\0" +"zone.id\0" +"gob.ar\0" "edu\0" -"s.bg\0do\0dtv\0" -"hurum.no\0paroch.k12.ma.us\0" -"casacam.net\0" -"chihayaakasaka.osaka.jp\0cechire.com\0" +"dtv\0" +"sp.it\0" +"lib.tn.us\0s3-eu-west-3.amazonaws.com\0""001www.com\0" +"immobilien\0" +"gwiddle.co.uk\0" +"parachuting.aero\0" +"ip6.arpa\0gob.bo\0" +"chita.aichi.jp\0" +"biz.pk\0" +"biz.pl\0" +"lindas.no\0avianca\0" +"cri.br\0" +"biz.pr\0" +"2.bg\0ne.pw\0" +"musashimurayama.tokyo.jp\0" +"is-a-doctor.com\0" +"gob.cl\0bari.it\0tsuwano.shimane.jp\0ug.gov.pl\0" +"annaka.gunma.jp\0in-the-band.net\0" +"ski.museum\0" +"joyo.kyoto.jp\0dvr\0" +"indian.museum\0" +"servecounterstrike.com\0" +"date.hokkaido.jp\0zao.miyagi.jp\0" +"trade\0" +"bozen-s\xc3\xbc""dtirol.it\0warabi.saitama.jp\0" +"\xe4\xbd\x90\xe8\xb3\x80.jp\0" +"nesset.no\0*.transurl.eu\0" +"pi.it\0" +"no.com\0" +"yusuhara.kochi.jp\0" +"gob.do\0" +"yoshinogari.saga.jp\0johana.toyama.jp\0" +"gob.ec\0grozny.su\0" +"mad.museum\0" +"online.th\0a.run.app\0" +"nanto.toyama.jp\0" +"d\xc3\xb8nna.no\0" +"nhlfan.net\0myftp.biz\0" +"aguni.okinawa.jp\0" +"bergbau.museum\0rogers\0" +"oyabe.toyama.jp\0" +"univ.sn\0" +"prime\0" +"gob.es\0" +"gamvik.no\0" +"\xe7\xa6\x8f\xe4\xba\x95.jp\0memset.net\0" +"indigena.bo\0" +"okegawa.saitama.jp\0shimizu.shizuoka.jp\0" +"vix.br\0kyowa.hokkaido.jp\0nagaokakyo.kyoto.jp\0" +"al.us\0no-ip.org\0oy.lc\0" +"kunitomi.miyazaki.jp\0" +"balsan-suedtirol.it\0wakuya.miyagi.jp\0gb.net\0" +"ac\0" +"ad\0mb.it\0biz.tj\0" +"ae\0" +"af\0" +"ag\0yahoo\0dnsupdater.de\0" +"ai\0" +"tonami.toyama.jp\0" +"biz.ua\0" +"al\0kanuma.tochigi.jp\0biz.tr\0" +"am\0seljord.no\0ne.ug\0" +"biz.tt\0" +"ao\0creation.museum\0" +"otaru.hokkaido.jp\0ne.tz\0" +"aq\0ba\0stj\xc3\xb8rdalshalsen.no\0" +"ar\0bb\0schaeffler\0" +"as\0" +"at\0" +"au\0be\0jewelry.museum\0" +"bf\0" +"aw\0bg\0grozny.ru\0" +"ax\0bh\0gob.gt\0" +"bi\0ne.us\0" +"az\0bj\0" +"*.yokohama.jp\0matsumae.hokkaido.jp\0" +"bm\0" +"bn\0webhop.net\0" +"bo\0of.by\0" +"ca\0" +"br\0gob.hn\0" +"bs\0cc\0" +"bt\0cd\0szczytno.pl\0" +"bv\0cf\0" +"bw\0cg\0" +"ch\0vall\xc3\xa9""e-aoste.it\0biz.vn\0" +"by\0ci\0" +"bz\0" +"k12.gu.us\0" +"cl\0" +"cm\0c.cdn77.org\0" +"cn\0" +"co\0java\0" +"tempioolbia.it\0" +"alesund.no\0" +"cr\0fukuyama.hiroshima.jp\0" +"cu\0de\0farmequipment.museum\0" +"cv\0iruma.saitama.jp\0" +"cw\0" +"cx\0seto.aichi.jp\0" +"cy\0ushuaia.museum\0" +"cz\0dj\0" +"dk\0games\0" +"mobara.chiba.jp\0" +"dm\0gjerstad.no\0naamesjevuemie.no\0" +"do\0lur\xc3\xb8y.no\0is-a-green.com\0" +"tools\0" "ec\0" -"cargo.aero\0tm.ro\0mypsx.net\0" -"ee\0historical.museum\0" -"uonuma.niigata.jp\0" -"eg\0bs.it\0" -"misawa.aomori.jp\0" -"\xe6\x95\x8e\xe8\x82\xb2.hk\0gs.oslo.no\0" -"dz\0nagano.jp\0tm.se\0" -"scrapping.cc\0" -"nankoku.kochi.jp\0" -"higashiyoshino.nara.jp\0" -"kiev.ua\0" -"miyazaki.jp\0kushiro.hokkaido.jp\0" +"okinawa.jp\0" +"ee\0vefsn.no\0k12.tx.us\0" +"eg\0" +"tourism.pl\0" +"dz\0kin.okinawa.jp\0" +"museumcenter.museum\0valley.museum\0bingo\0" +"baseball\0" +"noticias.bo\0" +"inagawa.hyogo.jp\0abu.yamaguchi.jp\0global.ssl.fastly.net\0" +"co.com\0" +"takahama.aichi.jp\0" +"kayabe.hokkaido.jp\0" "es\0" -"et\0" +"et\0school\0" "eu\0" -"higashiizumo.shimane.jp\0lib.az.us\0" -"fi\0is-uberleet.com\0" -"intuit\0volvo\0" -"dvr\0*.advisor.ws\0" -"nagoya\0" -"fm\0\xc3\xa5snes.no\0" -"andriatranibarletta.it\0nes.akershus.no\0" -"fo\0botany.museum\0alesund.no\0grane.no\0" +"fi\0" +"aikawa.kanagawa.jp\0" +"fm\0" +"fo\0" "ga\0" -"fr\0gb\0california.museum\0" +"fr\0gb\0" +"dep.no\0media\0" "gd\0" "ge\0" -"gf\0mx.na\0\xe9\xa4\x90\xe5\x8e\x85\0" -"gg\0" -"gh\0sanagochi.tokushima.jp\0active\0" -"gi\0" -"zama.kanagawa.jp\0" -"gl\0namegawa.saitama.jp\0duns\0" +"gf\0rm.it\0*.transurl.nl\0" +"gg\0biz.zm\0" +"gh\0" +"gi\0i.ng\0gs.of.no\0" +"gx.cn\0gl\0ouchi.saga.jp\0" "gm\0" -"gn\0florida.museum\0" +"adm.br\0gn\0" "gp\0" -"gq\0pt.eu.org\0" -"gr\0" -"gs\0" -"gt\0" -"gu\0" -"gw\0\xe4\xb8\xaa\xe4\xba\xba.hk\0winb.gov.pl\0" -"fed.us\0" -"gy\0iwama.ibaraki.jp\0" -"tr\xc3\xb8gstad.no\0" -"riopreto.br\0hk\0" -"student.aero\0lancaster\0" -"hm\0" -"hn\0madrid\0" -"cc.sc.us\0" -"futtsu.chiba.jp\0" -"sicily.it\0" -"hr\0" -"\xe5\x98\x89\xe9\x87\x8c\0" -"ht\0id\0cc.na\0" +"recreation.aero\0gq\0lib.dc.us\0fitness\0s3.dualstack.ap-northeast-1.amazonaws.com\0mypets.ws\0" +"gr\0saga.jp\0matsubushi.saitama.jp\0" +"gs\0\xe5\x80\x8b\xe4\xba\xba.\xe9\xa6\x99\xe6\xb8\xaf\0" +"gt\0trentino-aadige.it\0lukow.pl\0" +"gu\0cc.ut.us\0" +"to.gov.br\0" +"gw\0" +"miyazu.kyoto.jp\0" +"gy\0" +"hk\0elvendrell.museum\0mel\xc3\xb8y.no\0" +"gob.mx\0" +"hm\0gob.ni\0hadsel.no\0" +"hn\0aridagawa.wakayama.jp\0" +"ubank\0s3.dualstack.eu-west-3.amazonaws.com\0" +"kep.tr\0coach\0fan\0" +"wpdevcloud.com\0cyon.site\0" +"hr\0saarland\0dynathome.net\0" +"andoy.no\0" +"ht\0id\0akdn\0" "hu\0ie\0" -"talk\0" -"economia.bo\0" -"il\0" +"oarai.ibaraki.jp\0futuremailing.at\0" +"bnr.la\0" +"higashi.okinawa.jp\0i.ph\0winb.gov.pl\0" +"il\0for-more.biz\0" "im\0" -"in\0" -"io\0togo.aichi.jp\0" -"noda.chiba.jp\0augustow.pl\0dvag\0" +"in\0matsumoto.kagoshima.jp\0" +"io\0from-al.com\0" +"naka.hiroshima.jp\0" "iq\0" -"ir\0cody.museum\0" -"is\0flakstad.no\0" -"it\0misato.shimane.jp\0" -"je\0" -"aver\xc3\xb8y.no\0prochowice.pl\0able\0" -"lucania.it\0" -"fortmissoula.museum\0gleeze.com\0" -"khmelnytskyi.ua\0" -"hichiso.gifu.jp\0" -"jo\0glass.museum\0" +"ir\0cri.nz\0" +"is\0oldnavy\0" +"it\0" +"je\0gob.pa\0togliatti.su\0" +"varoy.no\0is-a-bruinsfan.org\0" +"watarai.mie.jp\0" +"gob.pe\0" +"news\0" +"jo\0gob.pk\0" "jp\0" -"chino.nagano.jp\0" -"internet-dns.de\0" -"ke\0opoczno.pl\0" -"griw.gov.pl\0" -"kg\0k12.il.us\0" -"rakkestad.no\0" -"ki\0" -"kikugawa.shizuoka.jp\0nasushiobara.tochigi.jp\0" -"km\0misconfused.org\0" -"kn\0" +"floro.no\0" +"radoy.no\0esq\0" +"treviso.it\0katori.chiba.jp\0toga.toyama.jp\0freeboxos.fr\0" +"ke\0" +"kg\0" +"furudono.fukushima.jp\0" +"ki\0tree.museum\0dynalias.org\0" +"mobi.gp\0trentinoa-adige.it\0toba.mie.jp\0ooshika.nagano.jp\0nagai.yamagata.jp\0" +"koshu.yamanashi.jp\0" +"km\0" +"kn\0club\0next\0blogspot.co.at\0" +"folldal.no\0lib.ma.us\0" "kp\0" "la\0" -"shimodate.ibaraki.jp\0nagasaki.nagasaki.jp\0kr\0lb\0" -"lc\0" -"tromso.no\0" -"tm.za\0" -"kw\0" -"\xe5\x85\xac\xe7\x9b\x8a\0" +"kr\0lb\0" +"lc\0naturbruksgymn.se\0" +"shonai.yamagata.jp\0" +"\xe6\xbe\xb3\xe9\x96\x80\0" +"kw\0i.se\0" +"haboro.hokkaido.jp\0" "ky\0li\0" -"kz\0" -"lk\0" -"realtor\0" -"storj.farm\0" -"!city.yokohama.jp\0is-a-student.com\0" -"ma\0" -"lr\0elverum.no\0" -"ls\0mc\0norddal.no\0" -"lt\0md\0gs.of.no\0" -"minamifurano.hokkaido.jp\0lu\0me\0" -"lv\0" -"mg\0" -"asn.lv\0mh\0hughes\0" -"tokorozawa.saitama.jp\0ly\0" -"ainan.ehime.jp\0mydrobo.com\0" -"airport.aero\0mk\0" -"ml\0mordovia.su\0" -"mn\0" -"kobayashi.miyazaki.jp\0mo\0" -"trainer.aero\0mp\0click\0technology\0\xe9\x9b\x86\xe5\x9b\xa2\0" -"milano.it\0mq\0na\0" -"workinggroup.aero\0mr\0togliatti.su\0" -"ms\0nc\0" -"mt\0" -"mu\0ne\0" -"togitsu.nagasaki.jp\0mv\0nf\0" +"chikuma.nagano.jp\0kz\0" +"lk\0motorcycles\0" +"cc.nv.us\0" +"kawamata.fukushima.jp\0nagasu.kumamoto.jp\0" +"ma\0protonet.io\0" +"friulivgiulia.it\0lr\0" +"ls\0mc\0" +"lt\0md\0" +"lu\0me\0\xc4\x8d\xc3\xa1hcesuolo.no\0eus\0" +"hachioji.tokyo.jp\0lv\0" +"mg\0alpha-myqnapcloud.com\0" +"takasu.hokkaido.jp\0mh\0" +"ly\0" +"soccer\0stcgroup\0" +"mk\0flakstad.no\0k12.vt.us\0" +"ml\0" +"ssl.origin.cdn77-secure.org\0" +"cesena-forl\xc3\xac.it\0mn\0" +"mo\0eidfjord.no\0\xd0\xbe\xd1\x80\xd0\xb3\0" +"mp\0dabur\0" +"mq\0na\0edu.eu.org\0tselinograd.su\0" +"anpachi.gifu.jp\0kamakura.kanagawa.jp\0mr\0" +"ms\0nc\0myqnapcloud.com\0" +"fermo.it\0mt\0" +"mu\0ne\0of.no\0" +"ranzan.saitama.jp\0mv\0nf\0" "mw\0ng\0" -"6.bg\0mx\0" -"my\0ni\0rana.no\0\xe5\xb9\xbf\xe4\xb8\x9c\0" -"mz\0" +"mx\0" +"z.bg\0my\0ni\0is-into-anime.com\0" +"asahikawa.hokkaido.jp\0mz\0gob.sv\0" "nl\0" -"no\0helsinki\0" -"uwajima.ehime.jp\0" -"dnsalias.net\0" -"tahara.aichi.jp\0nr\0" -"pp.se\0pp.ru\0" -"\xe5\x8f\xb0\xe7\x81\xa3\0" +"miyama.fukuoka.jp\0yanaizu.fukushima.jp\0" +"no\0from-il.com\0" +"nagano.nagano.jp\0makeup\0" +"aizumi.tokushima.jp\0nr\0nextdirect\0" +"yokawa.hyogo.jp\0yoshino.nara.jp\0" "nu\0" -"realestate.pl\0" -"medicina.bo\0" -"nh.us\0" -"awaji.hyogo.jp\0nz\0" -"mc.it\0kiyosu.aichi.jp\0" -"om\0is-a-teacher.com\0" -"sumida.tokyo.jp\0" -"sakai.osaka.jp\0avianca\0" +"tos.it\0" +"from-fl.com\0" +"nz\0trafficplex.cloud\0" +"sardegna.it\0oshima.yamaguchi.jp\0" +"masoy.no\0om\0" +"dnsdojo.net\0" +"takahagi.ibaraki.jp\0" "pa\0" -"tsubata.ishikawa.jp\0""4u.com\0" -"cc.ua\0" +"jl.cn\0" +"national.museum\0bygland.no\0" +"shimoichi.nara.jp\0lebork.pl\0" "pe\0" "pf\0" -"ph\0" -"myoko.niigata.jp\0" -"brescia.it\0" +"fosnes.no\0syno-ds.de\0" +"chitose.hokkaido.jp\0ph\0" +"quebec.museum\0aurland.no\0gob.ve\0money\0" "pk\0" -"pl\0mordovia.ru\0" -"\xe7\xbd\x91\xe7\xbb\x9c.cn\0pm\0" -"pn\0" -"pp.ua\0" -"ouchi.saga.jp\0qa\0" -"pr\0" +"koya.wakayama.jp\0pl\0financial\0" +"pm\0" +"shoo.okayama.jp\0pn\0" +"sogne.no\0" +"qa\0ut.us\0we.bs\0" +"taiki.mie.jp\0taiwa.miyagi.jp\0pr\0" "ps\0" -"takasago.hyogo.jp\0pt\0" -"\xe8\xaf\xba\xe5\x9f\xba\xe4\xba\x9a\0" -"pw\0fan\0" -"hachinohe.aomori.jp\0tsugaru.aomori.jp\0" -"an.it\0py\0" -"muenchen.museum\0" -"teo.br\0" -"tsurugashima.saitama.jp\0" -"\xe9\x9d\x99\xe5\xb2\xa1.jp\0" -"bristol.museum\0" -"miki.hyogo.jp\0re\0" -"security\0" -"lebtimnetz.de\0" -"cc.nv.us\0" -"flt.cloud.muni.cz\0" -"yahoo\0" -"floripa.br\0lezajsk.pl\0luxury\0" -"adachi.tokyo.jp\0" -"niikappu.hokkaido.jp\0" -"nara.nara.jp\0hattfjelldal.no\0ro\0" -"sa\0" -"mg.gov.br\0sb\0netflix\0" -"takamori.kumamoto.jp\0rs\0sc\0" -"la-spezia.it\0nishiokoppe.hokkaido.jp\0barcelona.museum\0\xc3\xb8ygarden.no\0sd\0" -"togura.nagano.jp\0ru\0se\0" -"donna.no\0" -"shiraoi.hokkaido.jp\0rw\0sg\0abbott\0" -"sn\xc3\xa5sa.no\0sh\0" -"si\0cleverapps.io\0" -"sj\0esq\0" -"usgarden.museum\0sk\0servecounterstrike.com\0" -"tank.museum\0v\xc3\xa6r\xc3\xb8y.no\0sl\0" -"tomigusuku.okinawa.jp\0sm\0azerbaijan.su\0" -"sn\0" +"pt\0" +"basel.museum\0" +"ulsan.kr\0fit\0" +"pw\0" +"py\0" +"\xe6\x9d\xb1\xe4\xba\xac.jp\0" +"shinto.gunma.jp\0gwangju.kr\0" +"org.ac\0" +"wif.gov.pl\0" +"org.ae\0" +"org.af\0pz.it\0" +"org.ag\0lib.sd.us\0" +"yaizu.shizuoka.jp\0" +"org.ai\0" +"re\0" +"org.al\0" +"kaminokawa.tochigi.jp\0" +"kyotamba.kyoto.jp\0fastlylb.net\0" +"org.ba\0" +"org.ar\0org.bb\0" +"\xe6\xbe\xb3\xe9\x97\xa8\0blogspot.co.id\0" +"org.au\0ro\0" +"tysv\xc3\xa6r.no\0sa\0" +"org.bh\0ashiya.fukuoka.jp\0sb\0" +"org.bi\0kopervik.no\0rs\0sc\0beauty\0" +"org.az\0sd\0" +"ru\0se\0fastly-terrarium.com\0" +"balsan.it\0blogspot.co.il\0" +"org.bm\0archaeological.museum\0trustee.museum\0rw\0sg\0" +"org.bn\0toki.gifu.jp\0kahoku.ishikawa.jp\0yoshikawa.saitama.jp\0sh\0" +"org.bo\0si\0" +"kaszuby.pl\0sj\0on-the-web.tv\0" +"sk\0" +"org.br\0mielno.pl\0sl\0" +"org.bs\0sm\0black\0" +"org.bt\0sn\0" "so\0" -"british.museum\0sr\0" -"tc\0" -"st\0td\0" -"su\0" -"sv\0tf\0" -"architecture.museum\0tg\0" -"sx\0th\0" -"pup.gov.pl\0sy\0*.transurl.be\0" -"sz\0tj\0vuelos\0" -"tk\0" +"df.gov.br\0sn.cn\0" +"org.bw\0" +"sr\0" +"org.ci\0tc\0" +"org.bz\0ms.it\0st\0td\0" +"b\xc3\xa1jddar.no\0su\0" +"\xd8\xa7\xd9\x8a\xd8\xb1\xd8\xa7\xd9\x86.ir\0asakuchi.okayama.jp\0sv\0tf\0" +"karmoy.no\0lier.no\0tg\0redumbrella\0" +"org.cn\0forl\xc3\xac""cesena.it\0sx\0th\0" +"org.co\0sy\0" +"slupsk.pl\0sz\0tj\0" +"tk\0fly\0" "tl\0" -"rc.it\0tm\0" -"tn\0" -"westfalen.museum\0to\0" -"ua\0" -"tr\0" -"tt\0" -"yk.ca\0" -"tv\0is-a-nurse.com\0" -"tw\0ug\0taxi\0boxfuse.io\0" -"\xe7\xbd\x91\xe7\xbb\x9c.hk\0arboretum.museum\0tz\0williamhill\0" -"oishida.yamagata.jp\0uk\0" -"profesional.bo\0eus\0" -"s.se\0" -"cooking\0cookingchannel\0" -"arita.saga.jp\0lahppi.no\0" -"riodejaneiro.museum\0va\0" -"hiraya.nagano.jp\0cinema.museum\0nyny.museum\0" -"kyotango.kyoto.jp\0us\0vc\0" -"pordenone.it\0ve\0" -"ontario.museum\0vg\0hepforge.org\0" -"zapto.xyz\0" -"fribourg.museum\0uy\0vi\0mg.leg.br\0" -"beauxarts.museum\0uz\0" -"no-ip.co.uk\0" -"frosinone.it\0" -"plc.ly\0" -"vn\0" -"trentino-suedtirol.it\0" -"nf.ca\0" -"nature.museum\0\xe9\x9b\xbb\xe8\xa8\x8a\xe7\x9b\x88\xe7\xa7\x91\0" -"sciencecenter.museum\0vu\0" -"wf\0" -"qpon\0" -"is-a-anarchist.com\0" -"us-east-1.elasticbeanstalk.com\0" -"tingvoll.no\0careers\0" -"*.nom.br\0essex.museum\0" -"kibichuo.okayama.jp\0birthplace.museum\0ws\0" -"rovigo.it\0" -"kagoshima.kagoshima.jp\0*.transurl.eu\0" -"its.me\0" -"oharu.aichi.jp\0brother\0" -"reklam.hu\0" -"rollag.no\0" -"afjord.no\0" -"yawatahama.ehime.jp\0" -"vpnplus.to\0" -"hino.tokyo.jp\0" -"kamiichi.toyama.jp\0cc.ia.us\0" -"leasing.aero\0yamato.fukushima.jp\0fuchu.toyama.jp\0media.museum\0logoip.de\0" -"fit\0" -"vs.it\0" -"valledaosta.it\0" -"yt\0" -"lib.hi.us\0" -"fuji.shizuoka.jp\0co.com\0" -"mutsuzawa.chiba.jp\0gotpantheon.com\0" -"showa.gunma.jp\0shimizu.shizuoka.jp\0" -"zm\0" -"teramo.it\0" -"arezzo.it\0zp.ua\0" -"aizumi.tokushima.jp\0" -"br\xc3\xb8nn\xc3\xb8ysund.no\0" -"nakagyo.kyoto.jp\0zw\0" -"r\xc3\xa1hkker\xc3\xa1vju.no\0" -"odawara.kanagawa.jp\0" -"insurance.aero\0from-ut.com\0" -"cloudapp.net\0" -"l\xc3\xa6rdal.no\0" -"aland.fi\0hachirogata.akita.jp\0" -"yazu.tottori.jp\0wielun.pl\0" -"bajddar.no\0" -"website\0" -"casino.hu\0" -"vda.it\0" -"lanxess\0" -"federation.aero\0koga.fukuoka.jp\0" -"fly\0" -"legal\0" -"ikawa.akita.jp\0" -"etnedal.no\0" -"gb.net\0" -"uzs.gov.pl\0" -"doesntexist.org\0" -"ok.us\0" -"starhub\0" -"frogans\0" -"linz.museum\0" -"mydissent.net\0" -"busan.kr\0" -"nakano.tokyo.jp\0" -"u2.xnbay.com\0" -"stj\xc3\xb8rdalshalsen.no\0cv.ua\0plc.uk\0" -"ha.cn\0hidaka.wakayama.jp\0" -"dy.fi\0" -"h\xc3\xb8nefoss.no\0" -"endofinternet.net\0" -"adac\0" -"lib.mi.us\0" -"foo\0" -"nagasaki.jp\0" -"q.bg\0kannami.shizuoka.jp\0" -"chungbuk.kr\0dyroy.no\0" -"*.platformsh.site\0" -"fox\0" -"ohira.miyagi.jp\0onthewifi.com\0" -"\xe9\xa6\x99\xe6\xb8\xaf\0" -"ca.it\0" -"museumvereniging.museum\0" -"democracia.bo\0*.sendai.jp\0tachiarai.fukuoka.jp\0" -"beta.bounty-full.com\0" -"bauhaus\0apps.lair.io\0" -"meldal.no\0\xe8\x81\x94\xe9\x80\x9a\0" -"pn.it\0raid\0" -"*.transurl.nl\0" -"square7.de\0" -"gal\0" -"isehara.kanagawa.jp\0" -"gap\0" -"tydal.no\0" -"yugawa.fukushima.jp\0" -"uber.space\0" -"sirdal.no\0" -"shopping\0" -"ddnsking.com\0" -"frl\0" -"\xe7\xb5\x84\xe7\xbb\x87.hk\0stuff-4-sale.org\0" -"otsuki.kochi.jp\0" -"couchpotatofries.org\0" -"*.vps.myjino.ru\0" -"asago.hyogo.jp\0" -"damnserver.com\0" -"zone.id\0" -"symantec\0" -"higashiomi.shiga.jp\0" -"lib.ct.us\0" -"ca.na\0if.ua\0" -"kin.okinawa.jp\0" -"cloudfunctions.net\0" -"square7.ch\0" -"gulen.no\0gdn\0" -"lib.ri.us\0is-a-republican.com\0" -"gea\0" -"otaki.chiba.jp\0hole.no\0ftr\0dynathome.net\0" -"\xe7\xbd\x91\xe7\xbb\x9c\0" -"skiptvet.no\0" -"nakano.nagano.jp\0" -"warmia.pl\0bananarepublic\0" -"gift\0" -"ouda.nara.jp\0jur.pro\0tours\0" -"shiroishi.miyagi.jp\0ritto.shiga.jp\0" -"fun\0" -"cards\0goldpoint\0" -"port.fr\0" -"joso.ibaraki.jp\0" -"nesodden.no\0" -"rec.br\0" -"otaki.nagano.jp\0bahn.museum\0" -"cern\0" -"engineer\0" -"lom.it\0" -"sowa.ibaraki.jp\0" -"rec.co\0umaji.kochi.jp\0" -"varese.it\0sosa.chiba.jp\0minnesota.museum\0posts-and-telecommunications.museum\0" -"modalen.no\0s3-ap-southeast-1.amazonaws.com\0" -"rnu.tn\0" -"asahi.mie.jp\0" -"dynalias.com\0" -"kamo.niigata.jp\0betainabox.com\0is-certified.com\0" -"hanno.saitama.jp\0" -"aridagawa.wakayama.jp\0" -"kamikawa.saitama.jp\0" -"trentinosuedtirol.it\0vegas\0" -"katashina.gunma.jp\0gs.nt.no\0" -"sf.no\0" -"miyada.nagano.jp\0" -"open\0" -"servebbs.org\0" -"otoyo.kochi.jp\0" -"cologne\0toshiba\0" -"hiratsuka.kanagawa.jp\0" -"lib.id.us\0" -"fyi\0hospital\0" -"4.bg\0" -"chikujo.fukuoka.jp\0" -"origins\0" -"lib.wi.us\0" -"is-very-good.org\0" -"biratori.hokkaido.jp\0" -"aukra.no\0lindas.no\0" -"ha.no\0" -"yamatokoriyama.nara.jp\0ddnss.org\0" -"suzu.ishikawa.jp\0yamagata.nagano.jp\0" -"tokai.aichi.jp\0saikai.nagasaki.jp\0americana.museum\0bearalvahki.no\0" -"plaza.museum\0" -"nemuro.hokkaido.jp\0klodzko.pl\0" -"itakura.gunma.jp\0nishihara.kumamoto.jp\0" -"maniwa.okayama.jp\0de.cool\0" -"salerno.it\0" -"android\0" -"lom.no\0" -"misaki.osaka.jp\0" -"nishinoomote.kagoshima.jp\0" -"hammerfest.no\0k12.nj.us\0" -"nago.okinawa.jp\0" -"sandcats.io\0" -"kutno.pl\0" -"stange.no\0vladimir.su\0" -"shika.ishikawa.jp\0" -"gle\0dyndns-free.com\0" -"k12.ec\0" -"s\xc3\xb8r-varanger.no\0" -"pointto.us\0" -"id.au\0\xd0\xba\xd0\xbe\xd0\xbc\0" -"kawaminami.miyazaki.jp\0ca.us\0" -"kawaue.gifu.jp\0deals\0" -"al.it\0tosashimizu.kochi.jp\0" -"kumatori.osaka.jp\0" -"iizuka.fukuoka.jp\0services\0" -"discovery.museum\0" -"ato.br\0twmail.net\0" -"wa.au\0hol.no\0" -"e164.arpa\0" -"ddnss.de\0" -"yokoshibahikari.chiba.jp\0" -"uruma.okinawa.jp\0gs.st.no\0" -"express.aero\0k12.as.us\0" -"sasaguri.fukuoka.jp\0kushimoto.wakayama.jp\0" -"rauma.no\0" -"suwa.nagano.jp\0gmo\0" -"wlocl.pl\0" -"cahcesuolo.no\0" -"masfjorden.no\0" -"k12.or.us\0" -"latrobe\0" -"gmx\0" -"lib.mt.us\0lib.nd.us\0from-nm.com\0" -"tsuno.miyazaki.jp\0" -"kawanehon.shizuoka.jp\0rv.ua\0" -"artcenter.museum\0" -"yamakita.kanagawa.jp\0ternopil.ua\0homeunix.com\0fantasyleague.cc\0" -"tur.ar\0vladimir.ru\0" -"hara.nagano.jp\0" -"psi.br\0miyama.mie.jp\0katsuragi.wakayama.jp\0" -"ct.it\0" -"buzz\0star\0" -"the.br\0" -"abu.yamaguchi.jp\0cc.co.us\0" -"s3.ca-central-1.amazonaws.com\0" -"goo\0" -"gop\0" -"ra.it\0matsumoto.kagoshima.jp\0shibata.niigata.jp\0" -"tur.br\0" -"got\0" -"mobi\0" -"gov\0" -"isleofman.museum\0" -"yamanashi.yamanashi.jp\0" -"osasco.br\0" -"aomori.aomori.jp\0sor-varanger.no\0\xe6\xb8\xb8\xe6\x88\x8f\0" -"k12.il\0" -"enterprises\0" -"is.gov.pl\0" -"\xc3\xa1laheadju.no\0" -"tranibarlettaandria.it\0" -"al.no\0" -"rec.nf\0americanfamily\0" -"slupsk.pl\0" -"moda\0" -"luzern.museum\0fairwinds\0" -"is-a-liberal.com\0" -"crown\0" -"museum.tt\0is-into-games.com\0" -"bio.br\0nakagawa.hokkaido.jp\0ilawa.pl\0" -"gliding.aero\0portlligat.museum\0" -"nishikatsura.yamanashi.jp\0seaport.museum\0" -"kasuya.fukuoka.jp\0hirado.nagasaki.jp\0barsy.net\0" -"higashiyodogawa.osaka.jp\0" -"lebork.pl\0" -"official.academy\0" -"mer\xc3\xa5ker.no\0hbo\0" -"aca.pro\0" -"aircraft.aero\0chattanooga.museum\0" -"nara.jp\0" -"\xe6\x94\xbf\xe5\xba\x9c.hk\0alaheadju.no\0\xe0\xa4\xa8\xe0\xa5\x87\xe0\xa4\x9f\0" -"issmarterthanyou.com\0al.eu.org\0" -"*.nagoya.jp\0capetown\0" -"rentals\0" -"budejju.no\0" -"construction\0" -"lib.sd.us\0dnsalias.org\0from-mt.com\0from-nd.com\0" -"tomisato.chiba.jp\0" -"liguria.it\0" -"tomakomai.hokkaido.jp\0" -"cloudns.biz\0" -"id.ir\0shinichi.hiroshima.jp\0" -"hiphop\0" -"showa.yamanashi.jp\0royrvik.no\0url.tw\0pcloud.host\0" -"iris.arpa\0ferrara.it\0oxford.museum\0" -"larvik.no\0" -"konan.shiga.jp\0school.na\0" -"yamanobe.yamagata.jp\0" -"lucca.it\0handson.museum\0dedyn.io\0" -"trentinsued-tirol.it\0kawaguchi.saitama.jp\0wv.us\0ann-arbor.mi.us\0" -"yuu.yamaguchi.jp\0" -"sor-odal.no\0" -"eu.int\0astronomy.museum\0" -"obu.aichi.jp\0" -"muroto.kochi.jp\0newspaper.museum\0amli.no\0" -"oum.gov.pl\0gotdns.ch\0" -"koryo.nara.jp\0lyngen.no\0" -"judygarland.museum\0" -"rec.ro\0aramco\0" -"olawa.pl\0" -"school.nz\0" -"oguni.yamagata.jp\0" -"rimini.it\0" -"now.sh\0" -"torsken.no\0mmafan.biz\0" -"ma.us\0" -"pgfog.com\0" -"gratis\0" -"id.lv\0" -"\xeb\x8b\xb7\xeb\x84\xb7\0" -"id.ly\0" -"k12.ks.us\0merseine.nu\0" -"wazuka.kyoto.jp\0" -"tattoo\0" -"trentino-sudtirol.it\0" -"sd.cn\0" -"tonsberg.no\0" -"tsunan.niigata.jp\0pl.eu.org\0protonet.io\0" -"midatlantic.museum\0" -"business\0" -"al.us\0" -"from-ms.com\0from-nc.com\0" -"iwi.nz\0" -"satosho.okayama.jp\0tires\0" -"tanohata.iwate.jp\0" -"is-leet.com\0" -"monmouth.museum\0ny.us\0" -"est-a-la-masion.com\0" -"indian.museum\0settlement.museum\0""2ix.at\0" -"mt.it\0rec.ve\0" -"nagaoka.niigata.jp\0" -"komforb.se\0linkitools.space\0" -"shishikui.tokushima.jp\0cc.mo.us\0farmers\0" -"go.ci\0" -"toyota.yamaguchi.jp\0" -"higashimatsushima.miyagi.jp\0page\0" -"aogaki.hyogo.jp\0" -"hiv\0" -"salvadordali.museum\0lapy.pl\0" -"go.cr\0k12.ok.us\0gallery\0" -"higashikagura.hokkaido.jp\0" -"cnt.br\0itako.ibaraki.jp\0" -"vestby.no\0\xe5\xa4\xa7\xe6\x8b\xbf\0""2ix.ch\0" -"piemonte.it\0washtenaw.mi.us\0" -"o.bg\0r\xc3\xb8mskog.no\0vestvagoy.no\0" -"marugame.kagawa.jp\0" -"kuchinotsu.nagasaki.jp\0" -"ct.us\0" -"pol.dz\0museum.mv\0dev-myqnapcloud.com\0" -"museum.mw\0pomorze.pl\0" -"bo.it\0" -"dr\xc3\xb8""bak.no\0" -"2ix.de\0" -"\xe7\xbd\x91\xe5\xba\x97\0" -"lugansk.ua\0cc.az.us\0" -"museum.no\0bestbuy\0" -"culture.museum\0" -"quicksytes.com\0" -"shingu.wakayama.jp\0hkt\0" -"k12.tr\0" -"kisofukushima.nagano.jp\0" -"ancona.it\0" -"rennesoy.no\0" -"2038.io\0" -"museum.om\0" -"onna.okinawa.jp\0" -"hvaler.no\0" -"seihi.nagasaki.jp\0linkyard-cloud.ch\0" -"publishproxy.com\0" -"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xdb\x8c\xd8\xa9\0" -"servehumour.com\0" -"fosnes.no\0\xe4\xb8\xad\xe6\x96\x87\xe7\xbd\x91\0" -"and\xc3\xb8y.no\0" -"k12.vi\0" -"traeumtgerade.de\0" -"fl.us\0" -"koga.ibaraki.jp\0" -"moriyoshi.akita.jp\0" -"toyota.aichi.jp\0bahccavuotna.no\0" -"uchinomi.kagawa.jp\0" -"\xd9\xbe\xd8\xa7\xda\xa9\xd8\xb3\xd8\xaa\xd8\xa7\xd9\x86\0spiegel\0" -"moriya.ibaraki.jp\0" -"tempioolbia.it\0" -"villas\0" -"soo.kagoshima.jp\0" -"naka.ibaraki.jp\0" -"pol.ht\0murata.miyagi.jp\0" -"cherkasy.ua\0\xe0\xb8\xa3\xe0\xb8\xb1\xe0\xb8\x90\xe0\xb8\x9a\xe0\xb8\xb2\xe0\xb8\xa5.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" -"kusatsu.gunma.jp\0team\0" -"tenei.fukushima.jp\0misugi.mie.jp\0s3-website-ap-southeast-1.amazonaws.com\0" -"barsy.pro\0" -"tsukigata.hokkaido.jp\0misato.miyagi.jp\0s3.dualstack.eu-west-3.amazonaws.com\0" -"prd.fr\0" -"ru.com\0is-not-certified.com\0" -"matsushige.tokushima.jp\0" -"go.id\0" -"wakasa.fukui.jp\0" -"vinnytsia.ua\0" -"og.ao\0" -"beppu.oita.jp\0town.museum\0" -"hot\0" -"eu-west-3.elasticbeanstalk.com\0" -"id.us\0how\0" -"go.it\0minamiyamashiro.kyoto.jp\0" -"lodi.it\0shizuoka.jp\0cadaques.museum\0\xec\x82\xbc\xec\x84\xb1\0" -"namerikawa.toyama.jp\0" -"sa.edu.au\0tech\0" -"bandai.fukushima.jp\0" -"isahaya.nagasaki.jp\0" -"wa.us\0" -"hanawa.fukushima.jp\0" -"homelink.one\0" -"airtraffic.aero\0go.jp\0" -"barsy.pub\0" -"louvre.museum\0oystre-slidre.no\0" -"aero\0" -"sorocaba.br\0lakas.hu\0sydney\0i234.me\0" -"go.ke\0" -"oto.fukuoka.jp\0" -"hu.net\0" -"s3.dualstack.ap-northeast-1.amazonaws.com\0" -"sic.it\0" -"iheya.okinawa.jp\0" -"hamatonbetsu.hokkaido.jp\0" -"news.hu\0nakanoto.ishikawa.jp\0rns.tn\0za.com\0" -"go.kr\0tirol\0" -"uji.kyoto.jp\0" -"organic\0" -"moto\0" -"ibm\0" -"tara.saga.jp\0" -"yurihonjo.akita.jp\0frana.no\0" -"kerrylogistics\0locker\0" -"chikuma.nagano.jp\0" -"ice\0" -"collegefan.org\0" -"trentinsudtirol.it\0navuotna.no\0" -"dnipropetrovsk.ua\0lilly\0endofinternet.org\0" -"tran\xc3\xb8y.no\0" -"forlicesena.it\0bievat.no\0" -"kijo.miyazaki.jp\0" -"prd.km\0nowruz\0" -"film.museum\0icu\0" -"kawagoe.mie.jp\0" -"birdart.museum\0" -"2.bg\0" -"pvt.ge\0" -"qld.au\0bridgestone\0" -"ecologia.bo\0" -"moareke.no\0" -"fujimino.saitama.jp\0" -"hikari.yamaguchi.jp\0" -"tohma.hokkaido.jp\0" -"numata.hokkaido.jp\0" -"city.hu\0" -"fujisato.akita.jp\0" -"govt.nz\0" -"vinnica.ua\0mt.us\0nd.us\0" -"arte.bo\0kaisei.kanagawa.jp\0higashine.yamagata.jp\0" -"lo.it\0prd.mg\0" -"*.compute-1.amazonaws.com\0" -"kanna.gunma.jp\0" -"chat\0" -"pars\0" -"kongsvinger.no\0" -"physio\0" -"urayasu.chiba.jp\0echizen.fukui.jp\0" -"fj.cn\0\xe6\x84\x9b\xe5\xaa\x9b.jp\0" -"science\0dyndns-at-home.com\0" -"kviteseid.no\0" -"\xd8\xa7\xd8\xaa\xd8\xb5\xd8\xa7\xd9\x84\xd8\xa7\xd8\xaa\0" -"varggat.no\0" -"raisa.no\0temasek\0ae.org\0in-the-band.net\0" -"ifm\0" -"amot.no\0imamat\0" -"oji.nara.jp\0pl.ua\0" -"naka.hiroshima.jp\0" -"kawakami.nara.jp\0esurance\0" -"m\xc4\x81ori.nz\0imdb\0clan.rip\0" -"gonohe.aomori.jp\0kariwa.niigata.jp\0jpn.com\0" -"matsuno.ehime.jp\0" -"go.pw\0" -"s3-us-west-1.amazonaws.com\0" -"snillfjord.no\0" -"\xd0\xbc\xd0\xba\xd0\xb4\0" -"alaska.museum\0isteingeek.de\0" -"transporte.bo\0boleslawiec.pl\0" -"og.it\0" -"iwate.jp\0ybo.science\0" -"n4t.co\0" -"\xe5\x95\x86\xe5\xba\x97\0" -"skedsmo.no\0" -"kitagawa.miyazaki.jp\0" -"yoka.hyogo.jp\0" -"tohnosho.chiba.jp\0" -"eidskog.no\0" -"kahoku.ishikawa.jp\0" -"cr.it\0otago.museum\0" -"homelinux.com\0" -"gs.hm.no\0capitalone\0" -"hirogawa.wakayama.jp\0is-a-therapist.com\0" -"\xd8\xb3\xd9\x88\xd8\xaf\xd8\xa7\xd9\x86\0" -"ravenna.it\0" -"biei.hokkaido.jp\0" -"sd.us\0moscow\0" -"curitiba.br\0" -"arteducation.museum\0" -"go.th\0pol.tr\0" -"esan.hokkaido.jp\0hannan.osaka.jp\0gotsu.shimane.jp\0" -"toyone.aichi.jp\0ostre-toten.no\0go.tj\0" -"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xdb\x8c\xdb\x83\0" -"kanmaki.nara.jp\0undersea.museum\0" -"academy.museum\0" -"sayama.saitama.jp\0" -"fermo.it\0maori.nz\0" -"iglesias-carbonia.it\0bryne.no\0" -"ogliastra.it\0" -"ando.nara.jp\0yao.osaka.jp\0go.ug\0" -"o.se\0" -"go.tz\0is-a-financialadvisor.com\0" -"kawamata.fukushima.jp\0" -"honjyo.akita.jp\0dealer\0" -"orkdal.no\0" -"lindesnes.no\0wedding\0" -"trentinosudtirol.it\0" -"namsos.no\0\xd0\xbc\xd0\xbe\xd0\xbd\0" -"nokia\0" -"onomichi.hiroshima.jp\0" -"tagawa.fukuoka.jp\0" -"blogspot.com\0" -"nb.ca\0" -"is-a-photographer.com\0" -"qsl.br\0tarumizu.kagoshima.jp\0" -"volkenkunde.museum\0" -"fin.ec\0" -"tuscany.it\0vicenza.it\0" -"akita.jp\0" -"brussels.museum\0" -"jab.br\0inc\0" -"k12.tx.us\0" -"s3-website.eu-central-1.amazonaws.com\0" -"ing\0barsy.me\0" -"no.eu.org\0" -"uchihara.ibaraki.jp\0" -"fuso.aichi.jp\0v\xc3\xa1rgg\xc3\xa1t.no\0ink\0" -"chuo.chiba.jp\0barsy.org\0" -"oamishirasato.chiba.jp\0hokuryu.hokkaido.jp\0" -"oz.au\0ogawa.saitama.jp\0oshino.yamanashi.jp\0" -"bosch\0" -"kamiizumi.saitama.jp\0" -"int\0" -"histoire.museum\0yolasite.com\0" -"\xe7\xa6\x8f\xe5\xb3\xb6.jp\0lea\xc5\x8bgaviika.no\0" -"schlesisches.museum\0" -"surf\0" -"smile\0pgafan.net\0" -"toda.saitama.jp\0babia-gora.pl\0" -"stuff-4-sale.us\0" -"k12.ia.us\0apps.fbsbx.com\0flynnhosting.net\0" -"sund.no\0phone\0" -"skjak.no\0" -"\xc3\xb8rland.no\0" -"blanco\0whoswho\0alpha.bounty-full.com\0" -"lombardia.it\0whaling.museum\0" -"tomari.hokkaido.jp\0" -"naturalhistorymuseum.museum\0from-fl.com\0" -"brasil.museum\0sibenik.museum\0" -"lib.tn.us\0" -"castres.museum\0" -"consulting.aero\0" -"countryestate.museum\0olecko.pl\0immo\0appchizi.com\0" -"twmail.org\0" -"ohda.shimane.jp\0" +"tm\0brasilia.me\0" +"ven.it\0shinagawa.tokyo.jp\0atm.pl\0tn\0" +"org.cu\0to\0boutique\0" +"org.cw\0ua\0" +"shiga.jp\0gose.nara.jp\0tr\0" +"org.cy\0is-a-personaltrainer.com\0" +"tt\0olayan\0for-better.biz\0" +"hakodate.hokkaido.jp\0jeonbuk.kr\0tv\0" +"org.dm\0tw\0ug\0fedorapeople.org\0" +"org.do\0nv.us\0" +"tz\0hair\0" +"losangeles.museum\0uk\0" "shimoji.okinawa.jp\0" -"mus.br\0expert\0" -"tatsuno.nagano.jp\0kawazu.shizuoka.jp\0" -"santafe.museum\0" -"lighting\0" -"valleedaoste.it\0kazuno.akita.jp\0" -"is-a-bulls-fan.com\0" -"nishiawakura.okayama.jp\0" -"livinghistory.museum\0bar.pro\0" -"shirakawa.gifu.jp\0sanuki.kagawa.jp\0carrier.museum\0" -"k12.ky.us\0\xe6\x94\xbf\xe5\xba\x9c.\xe9\xa6\x99\xe6\xb8\xaf\0" -"now-dns.net\0" -"cn-northwest-1.eb.amazonaws.com.cn\0" -"tsuiki.fukuoka.jp\0" -"fylkesbibl.no\0" -"jcb\0" -"teva\0" -"tksat.bo\0" -"saijo.ehime.jp\0kawajima.saitama.jp\0" -"oguni.kumamoto.jp\0" -"grp.lk\0" -"hk.org\0" -"bingo\0jcp\0" -"narusawa.yamanashi.jp\0" -"balat.no\0" -"ujitawara.kyoto.jp\0\xc3\xb8stre-toten.no\0" -"urbino-pesaro.it\0hamada.shimane.jp\0mo-i-rana.no\0ist\0" -"nz.eu.org\0" -"is-an-actor.com\0" -"asker.no\0extraspace\0from-ri.com\0" -"gaular.no\0" -"aizubange.fukushima.jp\0" -"cr.ua\0" -"ashiya.hyogo.jp\0" -"athleta\0s3.dualstack.ca-central-1.amazonaws.com\0" -"akkeshi.hokkaido.jp\0itv\0" -"solutions\0" -"rome.it\0" -"sagae.yamagata.jp\0atm.pl\0" -"tanabe.kyoto.jp\0" -"m.bg\0azurewebsites.net\0" -"georgia.museum\0" -"salem.museum\0" -"shiranuka.hokkaido.jp\0yoshikawa.saitama.jp\0" -"kumagaya.saitama.jp\0" -"\xe7\xbe\xa4\xe9\xa6\xac.jp\0s3-us-gov-west-1.amazonaws.com\0" -"rankoshi.hokkaido.jp\0hosting\0" -"hotmail\0" -"stockholm.museum\0" -"flickr\0" -"is-with-theband.com\0" -"catholic\0" -"snaase.no\0barsy.uk\0" -"london\0photo\0" -"minowa.nagano.jp\0skole.museum\0trana.no\0" -"kiryu.gunma.jp\0orsta.no\0" -"science.museum\0" -"rendalen.no\0" -"nozawaonsen.nagano.jp\0pccw\0" -"lyngdal.no\0" -"pa.gov.br\0frosta.no\0vaga.no\0wskr.gov.pl\0" -"shirosato.ibaraki.jp\0os\xc3\xb8yro.no\0" -"rikubetsu.hokkaido.jp\0" -"mihama.wakayama.jp\0" -"porsgrunn.no\0" -"unzen.nagasaki.jp\0" -"*.yokohama.jp\0etne.no\0zgora.pl\0" -"archaeology.museum\0" -"agrigento.it\0" -"watch\0" -"hasami.nagasaki.jp\0" -"mr.no\0" -"kashiwara.osaka.jp\0rhcloud.com\0" -"\xe7\xb6\xb2\xe7\xb5\xa1.\xe9\xa6\x99\xe6\xb8\xaf\0koeln\0" -"orkanger.no\0read\0" -"infiniti\0" -"pb.gov.br\0" -"horten.no\0" -"us.org\0" -"jio\0" -"dlugoleka.pl\0" -"osaki.miyagi.jp\0synology-ds.de\0" -"industries\0gotdns.org\0" -"pittsburgh.museum\0" -"info\0" -"kuki.saitama.jp\0" -"trentinosued-tirol.it\0yokaichiba.chiba.jp\0nagano.nagano.jp\0taobao\0" -"aeroport.fr\0linde\0" -"dsmynas.org\0" -"showtime\0" -"farm.museum\0" -"zj.cn\0osakikamijima.hiroshima.jp\0shari.hokkaido.jp\0" -"solar\0" -"ishigaki.okinawa.jp\0pa.leg.br\0" -"mad.museum\0name\0degree\0myqnapcloud.com\0" -"\xd0\xb4\xd0\xb5\xd1\x82\xd0\xb8\0" -"avellino.it\0c.cdn77.org\0" -"coupon\0" -"saarland\0" -"ranzan.saitama.jp\0biev\xc3\xa1t.no\0freebox-os.fr\0" -"itami.hyogo.jp\0hokuto.yamanashi.jp\0" -"saka.hiroshima.jp\0palace.museum\0" -"khmelnitskiy.ua\0capital\0" -"kuji.iwate.jp\0" -"koshimizu.hokkaido.jp\0green\0" -"nu.ca\0" -"ah.cn\0" -"ofunato.iwate.jp\0jlc\0qa2.com\0" -"jll\0familyds.net\0" -"donetsk.ua\0" -"\xd8\xa7\xd9\x84\xd8\xac\xd8\xb2\xd8\xa7\xd8\xa6\xd8\xb1\0" -"\xe7\xb6\xb2\xe7\xb5\xa1.cn\0samsung\0" -"k12.vi.us\0verm\xc3\xb6gensberater\0pb.leg.br\0" -"otsuki.yamanashi.jp\0" -"biella.it\0" -"fin.tn\0" -"hirakata.osaka.jp\0database.museum\0" -"airguard.museum\0loseyourip.com\0" -"jor.br\0" -"ip6.arpa\0" -"genoa.it\0" -"luroy.no\0" -"usarts.museum\0jmp\0" -"g\xc3\xa1\xc5\x8bgaviika.no\0" -"domains\0""16-b.it\0" -"b\xc3\xa6rum.no\0" -"servebbs.com\0" -"kamagaya.chiba.jp\0jnj\0" -"my-router.de\0" -"yaizu.shizuoka.jp\0walter\0" -"hyllestad.no\0" -"kai.yamanashi.jp\0" -"beauty\0" -"msk.ru\0" -"0.bg\0vpndns.net\0" -"tomioka.gunma.jp\0botanical.museum\0gjemnes.no\0" -"\xe9\xa3\x9e\xe5\x88\xa9\xe6\xb5\xa6\0" -"aisai.aichi.jp\0ayagawa.kagawa.jp\0mosjoen.no\0schmidt\0" -"noshiro.akita.jp\0kunimi.fukushima.jp\0witd.gov.pl\0" -"chieti.it\0fujisawa.kanagawa.jp\0" -"cityeats\0" -"naturalhistory.museum\0" -"kobierzyce.pl\0jot\0msk.su\0" -"yoshimi.saitama.jp\0giize.com\0forumz.info\0" -"montreal.museum\0sherbrooke.museum\0" -"kawahara.tottori.jp\0intelligence.museum\0" -"rishirifuji.hokkaido.jp\0bern.museum\0statoil\0" -"gov.ac\0joy\0" -"gov.ae\0porsangu.no\0gmbh\0homelinux.net\0" -"gov.af\0ilovecollege.info\0" -"school.za\0" -"iruma.saitama.jp\0" -"hembygdsforbund.museum\0" -"yufu.oita.jp\0zarow.pl\0" -"gov.al\0" -"rio.br\0" -"gov.ba\0guernsey.museum\0" -"gov.ar\0gov.bb\0" -"aerodrome.aero\0gov.as\0beeldengeluid.museum\0" -"gov.au\0" -"gov.bf\0\xe7\xb6\xb2\xe7\xb5\xa1.hk\0" -"matsumae.hokkaido.jp\0" -"gov.bh\0\xd1\x81\xd0\xb0\xd0\xb9\xd1\x82\0" -"gov.az\0azurecontainer.io\0" -"takaoka.toyama.jp\0calvinklein\0" -"gov.bm\0pinb.gov.pl\0" -"gov.bn\0" -"reit\0wellbeingzone.co.uk\0" -"\xe7\xa5\x9e\xe5\xa5\x88\xe5\xb7\x9d.jp\0" -"gov.br\0" -"gov.bs\0" -"gov.bt\0gov.cd\0" -"gov.by\0children.museum\0gorge.museum\0" -"gov.bz\0" -"scientist.aero\0" -"gov.cl\0nu.it\0" -"gov.cm\0" -"gov.cn\0" -"gov.co\0" -"cloudcontrolapp.com\0" -"legnica.pl\0barsy.bg\0" -"gov.cu\0" -"karacol.su\0" -"aviation.museum\0" -"gov.cx\0" -"gov.cy\0" +"org.ec\0berg.no\0b\xc3\xb8.nordland.no\0" +"org.ee\0" +"org.eg\0va\0" +"oto.fukuoka.jp\0ms.kr\0" +"us\0vc\0" +"org.dz\0sardinia.it\0trentins\xc3\xbc""dtirol.it\0kyotanabe.kyoto.jp\0" +"ve\0whoswho\0home-webserver.de\0" +"vg\0" +"sos.pl\0" +"uy\0vi\0" +"uz\0freetls.fastly.net\0" +"mysecuritycamera.com\0" +"ptplus.fit\0" +"org.es\0" +"org.et\0vn\0" +"foo\0" +"kasugai.aichi.jp\0" +"vu\0" +"wf\0" +"cc.ms.us\0cc.nc.us\0mypep.link\0" +"smola.no\0" +"minamiawaji.hyogo.jp\0kami.miyagi.jp\0fox\0" +"fie.ee\0" +"org.ge\0mymailer.com.tw\0" +"niyodogawa.kochi.jp\0" +"org.gg\0" +"org.gh\0anan.nagano.jp\0ac.leg.br\0" +"org.gi\0ws\0lego\0" +"org.gl\0cloud\0" +"\xe9\xa6\x99\xe6\xa0\xbc\xe9\x87\x8c\xe6\x8b\x89\0" +"org.gn\0" +"bjerkreim.no\0filegear-au.me\0" +"org.gp\0" +"org.gr\0ge.it\0shikaoi.hokkaido.jp\0mitsuke.niigata.jp\0" +"l\xc3\xb8ten.no\0readthedocs.io\0" +"org.gt\0gal\0" +"org.gu\0bar.pro\0" +"mie.jp\0kunneppu.hokkaido.jp\0" +"holiday\0" +"gap\0" +"g.bg\0org.gy\0priv.hu\0pics\0" +"org.hk\0computer.museum\0crimea.ua\0" +"org.hn\0" +"org.ht\0frl\0uk.net\0" +"org.hu\0arboretum.museum\0is-a-rockstar.com\0" +"sites.static.land\0" +"eun.eg\0" +"yt\0" +"\xe5\xa4\xa9\xe4\xb8\xbb\xe6\x95\x99\0" +"org.il\0tateshina.nagano.jp\0intuit\0" +"org.im\0naroy.no\0" +"org.in\0yawatahama.ehime.jp\0ms.leg.br\0" +"aeroclub.aero\0qld.gov.au\0" +"umi.fukuoka.jp\0" +"org.iq\0nordre-land.no\0" +"org.ir\0support\0" +"org.is\0kunst.museum\0zm\0cust.testing.thingdust.io\0" +"org.je\0ee.eu.org\0" +"cn.it\0" +"l\xc3\xa4ns.museum\0\xe4\xbd\x9b\xe5\xb1\xb1\0" +"ribeirao.br\0" +"miyako.fukuoka.jp\0" +"0.bg\0zw\0" +"org.jo\0" +"shibuya.tokyo.jp\0" +"saiki.oita.jp\0" +"monza-e-della-brianza.it\0gdn\0" +"org.kg\0" +"ketrzyn.pl\0" +"org.ki\0skedsmo.no\0gea\0" +"\xe9\xab\x98\xe7\x9f\xa5.jp\0ftr\0" +"org.km\0amsterdam\0" +"alessandria.it\0org.kn\0church\0mt.leg.br\0" +"cuisinella\0" +"pg.it\0hannan.osaka.jp\0org.kp\0" +"org.la\0lib.ri.us\0" +"org.lb\0no-ip.net\0" +"org.lc\0k12.ny.us\0" +"nomi.ishikawa.jp\0" +"waw.pl\0fun\0" +"org.kw\0anthro.museum\0from-mo.com\0" +"omihachiman.shiga.jp\0" +"org.ky\0" +"nahari.kochi.jp\0nagiso.nagano.jp\0org.kz\0" +"org.lk\0" +"chofu.tokyo.jp\0" +"org.ma\0" +"org.lr\0" +"org.ls\0" +"gen.in\0nobeoka.miyazaki.jp\0" +"org.me\0naumburg.museum\0gos.pk\0" +"belluno.it\0ashibetsu.hokkaido.jp\0org.lv\0" +"org.mg\0\xe5\x95\x86\xe6\xa5\xad.tw\0" +"priv.at\0" +"org.ly\0gives\0" +"org.mk\0field.museum\0" +"org.ml\0" +"org.mn\0" +"org.mo\0lenvik.no\0" +"org.na\0" +"org.ms\0arts.museum\0" +"caserta.it\0org.mt\0" +"org.mu\0museum\0lib.mn.us\0" +"\xe8\x8c\xa8\xe5\x9f\x8e.jp\0org.mv\0" +"humanities.museum\0org.mw\0org.ng\0" +"takko.aomori.jp\0org.mx\0nc.tr\0" +"org.my\0org.ni\0" +"mihama.wakayama.jp\0org.mz\0gniezno.pl\0" +"nt.au\0blogspot.co.uk\0" +"earth\0" +"z.se\0iki.fi\0" +"org.nr\0epost\0" +"s3.eu-west-3.amazonaws.com\0" +"trentins\xc3\xbc""d-tirol.it\0" +"frana.no\0" +"takatsuki.osaka.jp\0" +"nt.ca\0" +"kashihara.nara.jp\0verm\xc3\xb6gensberater\0" +"ms.us\0nc.us\0itau\0" +"org.nz\0" +"hareid.no\0" +"from.hr\0" +"org.om\0" +"miyagi.jp\0" +"saito.miyazaki.jp\0" +"org.pa\0fyi\0" +"mobi.tt\0" +"civilwar.museum\0rissa.no\0org.pe\0security\0\xd9\x85\xd9\x88\xd9\x82\xd8\xb9\0remotewd.com\0" +"org.pf\0" +"filatelia.museum\0" +"org.ph\0" +"dolls.museum\0rodoy.no\0tinn.no\0" +"mobi.tz\0creditunion\0" +"org.pk\0" +"org.pl\0vapor.cloud\0" +"org.pn\0" "ski.no\0" -"gov.dm\0lib.nh.us\0" -"gov.do\0oizumi.gunma.jp\0" -"sb.ua\0" -"kawagoe.saitama.jp\0seljord.no\0" -"wloclawek.pl\0" -"gov.ec\0" -"yokoze.saitama.jp\0" -"gov.ee\0" -"gov.eg\0" -"black\0armenia.su\0" -"gov.dz\0" -"kyowa.hokkaido.jp\0kurotaki.nara.jp\0" -"kadogawa.miyazaki.jp\0network\0" -"navy\0" -"yokkaichi.mie.jp\0kounosu.saitama.jp\0mup.gov.pl\0barsy.de\0" -"kihoku.ehime.jp\0takahata.yamagata.jp\0" -"gov.et\0" -"andria-trani-barletta.it\0" -"botanicalgarden.museum\0askim.no\0k12.co.us\0" -"leg.br\0" -"kpmg\0" -"automotive.museum\0hb.cldmail.ru\0" -"catanzaro.it\0" -"audnedaln.no\0" -"jx.cn\0" -"shima.mie.jp\0" -"kfh\0ddns.net\0" -"staples\0" -"gov.ge\0m.se\0" -"gov.gh\0umbria.it\0" -"gov.gi\0" -"blogsite.org\0" -"ah.no\0" -"gov.gn\0" -"bas.it\0rent\0" -"barsy.eu\0" -"gov.gr\0" -"pi.gov.br\0" -"gov.gu\0" +"org.qa\0haus\0" +"kumenan.okayama.jp\0yatsuka.shimane.jp\0org.pr\0" +"gulen.no\0org.ps\0" +"misawa.aomori.jp\0org.pt\0" +"ally\0bugatti\0filegear.me\0" +"usculture.museum\0org.py\0keymachine.de\0" +"military.museum\0" +"koto.shiga.jp\0restaurant\0" +"nt.edu.au\0volvo\0" +"sannan.hyogo.jp\0other.nf\0" +"swiss\0youtube\0" +"vb.it\0aizumisato.fukushima.jp\0" +"s3-website.ap-northeast-2.amazonaws.com\0" +"sch.ae\0panama.museum\0" +"hyuga.miyazaki.jp\0" +"s3-us-west-1.amazonaws.com\0" +"agr.br\0" +"s3-website.ca-central-1.amazonaws.com\0" +"gv.ao\0gle\0ping\0" +"org.ro\0pimienta.org\0" +"gen.nz\0" +"org.sa\0lexus\0pink\0nfshost.com\0" +"gv.at\0hiroshima.jp\0kawajima.saitama.jp\0org.sb\0" +"org.rs\0org.sc\0" +"org.sd\0" +"org.se\0org.ru\0" +"omaha.museum\0org.sg\0nflfan.org\0" +"org.sh\0" +"sandnessj\xc3\xb8""en.no\0" +"org.sl\0" +"sande.vestfold.no\0" +"org.sn\0" +"org.so\0" +"nakatombetsu.hokkaido.jp\0" +"nesna.no\0country\0" +"ancona.it\0kiryu.gunma.jp\0hitachiota.ibaraki.jp\0" +"org.st\0" +"karasjohka.no\0blogspot.co.ke\0" +"kitagawa.miyazaki.jp\0hasuda.saitama.jp\0org.sv\0" +"gmo\0" +"gs.nt.no\0org.sy\0" +"org.sz\0org.tj\0" +"org.tm\0" +"yorii.saitama.jp\0org.tn\0" +"org.to\0" +"gmx\0" +"mobi.na\0and\xc3\xb8y.no\0org.ua\0lib.de.us\0" +"org.tr\0" +"entomology.museum\0moskenes.no\0cn.ua\0" +"org.tt\0" +"modern.museum\0" +"\xe6\x96\xb0\xe6\xbd\x9f.jp\0hioki.kagoshima.jp\0" +"mobi.ng\0org.tw\0org.ug\0" +"olkusz.pl\0" +"org.uk\0tickets\0" +"1kapp.com\0" +"lardal.no\0" +"fedex\0" +"moareke.no\0org.vc\0ap-south-1.elasticbeanstalk.com\0" +"org.ve\0" +"goo\0hobby-site.com\0" +"gop\0" +"minnesota.museum\0org.uy\0org.vi\0" +"org.uz\0" +"got\0wedeploy.sh\0" +"plantation.museum\0k12.nh.us\0" +"gov\0fukui.fukui.jp\0matsuda.kanagawa.jp\0org.vn\0" +"rad\xc3\xb8y.no\0" +"readmyblog.org\0" +"org.vu\0" +"vic.au\0edeka\0" +"sekigahara.gifu.jp\0" +"telekommunikation.museum\0" +"kembuchi.hokkaido.jp\0" +"agakhan\0irish\0" +"piedmont.it\0" +"org.ws\0" +"shima.mie.jp\0ogose.saitama.jp\0gen.tr\0" +"qh.cn\0blogspot.co.nz\0" +"yokosuka.kanagawa.jp\0minamisanriku.miyagi.jp\0katano.osaka.jp\0swatch\0" +"overhalla.no\0baidu\0\xe9\x80\x9a\xe8\xb2\xa9\0" +"kamikitayama.nara.jp\0kimino.wakayama.jp\0" +"donna.no\0" +"ah.cn\0kitchen\0" +"berlin.museum\0g.se\0hbo\0" +"al.leg.br\0" +"int.eu.org\0" +"american.museum\0" +"toray\0" +"haibara.shizuoka.jp\0""2ix.at\0" +"aosta-valley.it\0oki.fukuoka.jp\0kitashiobara.fukushima.jp\0misugi.mie.jp\0" +"org.za\0" +"amex\0" +"mobi.ke\0herad.no\0aramco\0" +"sch.id\0bando.ibaraki.jp\0" +"glug.org.uk\0" +"madrid\0" +"szkola.pl\0" +"imizu.toyama.jp\0" +"osen.no\0org.zm\0" +"\xd8\xb4\xd8\xa8\xd9\x83\xd8\xa9\0" +"trentin-sudtirol.it\0uenohara.yamanashi.jp\0" +"2ix.ch\0" +"fidelity\0" +"sch.ir\0" +"frog.museum\0nt.no\0" +"org.zw\0cbg.ru\0stufftoread.com\0" +"urasoe.okinawa.jp\0mopar\0" +"council.aero\0x.bg\0" +"soundcast.me\0" +"savona.it\0kyuragi.saga.jp\0" +"miyakonojo.miyazaki.jp\0cookingchannel\0" +"is-an-anarchist.com\0""2ix.de\0" +"kurate.fukuoka.jp\0" +"sch.jo\0" +"theworkpc.com\0" +"lplfinancial\0" +"karate.museum\0kommunalforbund.se\0cn.eu.org\0" +"zj.cn\0" +"hoylandet.no\0law.za\0" +"family\0" +"to.it\0" +"lib.va.us\0" +"shinshinotsu.hokkaido.jp\0" +"ando.nara.jp\0" +"cranbrook.museum\0r\xc3\xa5holt.no\0" +"vald-aosta.it\0" +"erimo.hokkaido.jp\0" +"gs.ah.no\0k12.ca.us\0" +"hitachi.ibaraki.jp\0" +"cc.wv.us\0" +"rj.gov.br\0" +"sch.lk\0s3-website.eu-west-2.amazonaws.com\0hopto.me\0" +"lerdal.no\0" +"customer.enonic.io\0" +"trapani.it\0" +"vic.gov.au\0investments\0" +"gc.ca\0domains\0" +"sch.ly\0cloud66.ws\0" +"volkswagen\0" +"assedic.fr\0psp.gov.pl\0" +"fujishiro.ibaraki.jp\0" +"nt.ro\0" +"toyone.aichi.jp\0" +"nemuro.hokkaido.jp\0broke-it.net\0" +"sch.ng\0" +"okawa.fukuoka.jp\0" +"guovdageaidnu.no\0" +"kaho.fukuoka.jp\0" +"fage\0vote\0" +"wellbeingzone.eu\0" +"valle-d-aosta.it\0priv.pl\0" +"asaminami.hiroshima.jp\0notogawa.shiga.jp\0" +"karm\xc3\xb8y.no\0" +"voto\0" +"kerryhotels\0wedeploy.me\0" +"baghdad.museum\0amfam\0ro.eu.org\0" +"wakayama.jp\0" +"hiv\0" +"lel.br\0" +"forsand.no\0" +"\xd1\x80\xd1\x83\xd1\x81\0" +"na.it\0" +"bradesco\0" +"ureshino.mie.jp\0" +"od.ua\0" +"sic.it\0" +"interactive.museum\0norfolk.museum\0\xd7\x99\xd7\xa8\xd7\x95\xd7\xa9\xd7\x9c\xd7\x99\xd7\x9d.museum\0" +"reggio-calabria.it\0" +"gs.svalbard.no\0" +"alibaba\0" +"priv.no\0sch.qa\0" +"sobetsu.hokkaido.jp\0fail\0" +"dominic.ua\0cy.eu.org\0goip.de\0" +"iz.hr\0square7.net\0" +"pe.ca\0masfjorden.no\0" +"tamayu.shimane.jp\0" +"padua.it\0static.land\0" +"marumori.miyagi.jp\0kamitonda.wakayama.jp\0hkt\0" +"aure.no\0onyourside\0" +"*.kobe.jp\0chihayaakasaka.osaka.jp\0lgbt\0" +"misconfused.org\0" +"canada.museum\0blogspot.co.za\0" +"itoman.okinawa.jp\0nakaniikawa.toyama.jp\0" +"avocat.fr\0jeep\0" +"trana.no\0" +"rel.ht\0" +"meraker.no\0km.ua\0" +"academy.museum\0miniserver.com\0" +"jevnaker.no\0" +"harstad.no\0" +"abruzzo.it\0hashbang.sh\0" +"sch.sa\0" +"nic.in\0" +"ah.no\0cz.eu.org\0" +"tranby.no\0" +"kunitachi.tokyo.jp\0" +"priv.me\0" +"kibichuo.okayama.jp\0mugi.tokushima.jp\0" +"si.eu.org\0app.os.stg.fedoraproject.org\0" +"minamiechizen.fukui.jp\0tsubetsu.hokkaido.jp\0" +"ostre-toten.no\0orange\0" +"nakatsugawa.gifu.jp\0" +"vs.it\0smart\0" +"cologne\0" +"tsuruga.fukui.jp\0" +"ln.cn\0" +"loans\0" +"fukusaki.hyogo.jp\0" +"lavagis.no\0cloudns.eu\0" +"itami.hyogo.jp\0wroclaw.pl\0cool\0" +"nico\0" +"udi.br\0tsuno.kochi.jp\0nowaruda.pl\0" +"coop\0" +"e.bg\0" +"eu-west-2.elasticbeanstalk.com\0dk.eu.org\0" +"wv.us\0" +"namerikawa.toyama.jp\0" +"lyngdal.no\0" +"hot\0" +"how\0" +"us-west-2.elasticbeanstalk.com\0" "oyama.tochigi.jp\0" -"gov.gy\0" -"gov.hk\0" -"eng.br\0mp.br\0krakow.pl\0" -"te.it\0merckmsd\0" -"yamada.fukuoka.jp\0iwamizawa.hokkaido.jp\0" -"miyazu.kyoto.jp\0bungoono.oita.jp\0citi\0" -"kouyama.kagoshima.jp\0" -"evje-og-hornnes.no\0mt.eu.org\0" -"aseral.no\0" -"gov.ie\0utwente.io\0" -"ryugasaki.ibaraki.jp\0" -"togane.chiba.jp\0hirata.fukushima.jp\0" -"sayo.hyogo.jp\0" -"iki.nagasaki.jp\0pharmacy\0" +"bellevue.museum\0" +"nyc.mn\0" +"fans\0style\0" +"\xd9\x81\xd9\x84\xd8\xb3\xd8\xb7\xd9\x8a\xd9\x86\0" +"cl.it\0" +"sevastopol.ua\0" +"okutama.tokyo.jp\0" +"stateofdelaware.museum\0" +"dyndns-work.com\0" +"sel.no\0co.technology\0" +"kwpsp.gov.pl\0" +"engine.aero\0design.museum\0" +"sorreisa.no\0sk.eu.org\0" +"vardo.no\0" +"karumai.iwate.jp\0akishima.tokyo.jp\0itabashi.tokyo.jp\0" +"sue.fukuoka.jp\0" +"\xe6\x94\xbf\xe5\x8a\xa1\0" +"cloudns.in\0" +"ibm\0" +"ba.gov.br\0cesena-forli.it\0hekinan.aichi.jp\0moriyoshi.akita.jp\0" +"inderoy.no\0" +"brindisi.it\0" +"dyndns.ddnss.de\0" +"pe.it\0" +"dyroy.no\0ice\0" +"\xe0\xa6\xad\xe0\xa6\xbe\xe0\xa6\xb0\xe0\xa6\xa4\0" +"filegear-ie.me\0" +"simple-url.com\0" +"de.eu.org\0" +"hazu.aichi.jp\0" +"riodejaneiro.museum\0cloudns.cc\0" +"beardu.no\0" +"bulsan.it\0" +"arendal.no\0icu\0dynamisches-dns.de\0" +"rel.pl\0" +"sa.gov.au\0barsycenter.com\0" +"codes\0" +"takayama.gunma.jp\0olsztyn.pl\0" +"za.com\0" +"mamurogawa.yamagata.jp\0" +"intelligence.museum\0\xc3\xb8stre-toten.no\0farm\0" +"\xc3\xa1k\xc5\x8boluokta.no\0" +"pe.kr\0" +"mer\xc3\xa5ker.no\0" +"dental\0" +"sch.zm\0" +"yosemite.museum\0dyndns.org\0" +"katsuyama.fukui.jp\0" +"x.se\0afamilycompany\0vacations\0" +"rieti.it\0" +"ru.eu.org\0se.eu.org\0" +"kounosu.saitama.jp\0fast\0" +"bill.museum\0" +"akabira.hokkaido.jp\0" +"matsuno.ehime.jp\0fbxos.fr\0" +"\xe6\x95\x8e\xe8\x82\xb2.hk\0\xd1\x81\xd1\x80\xd0\xb1\0wedeploy.io\0" +"achi.nagano.jp\0" +"ifm\0nike\0" +"happou.akita.jp\0" +"gleeze.com\0" +"airforce\0hk.org\0" +"k12.wy.us\0" +"rr.gov.br\0tawaramoto.nara.jp\0" +"mansion.museum\0ulvik.no\0tunk.org\0" +"venezia.it\0" +"tel.tr\0" +"iwata.shizuoka.jp\0incheon.kr\0" +"castle.museum\0bostik\0" +"fhs.no\0h\xc3\xa5.no\0" +"nishiawakura.okayama.jp\0tabuse.yamaguchi.jp\0wskr.gov.pl\0" +"\xe0\xb6\xbd\xe0\xb6\x82\xe0\xb6\x9a\xe0\xb7\x8f\0*.compute.amazonaws.com\0webhop.me\0" +"karasuyama.tochigi.jp\0" +"zushi.kanagawa.jp\0" +"homeunix.com\0" +"trentino-sud-tirol.it\0" +"christmas\0" +"val-daosta.it\0iwakuni.yamaguchi.jp\0" +"joburg\0" +"nic.tj\0" +"jab.br\0*.kitakyushu.jp\0" +"donostia.museum\0kvinnherad.no\0" +"\xd0\xba\xd0\xb0\xd1\x82\xd0\xbe\xd0\xbb\xd0\xb8\xd0\xba\0" +"eti.br\0aizuwakamatsu.fukushima.jp\0kitakami.iwate.jp\0" +"belau.pw\0philips\0sa.com\0" +"cuiaba.br\0kamiichi.toyama.jp\0" +"her\xc3\xb8y.m\xc3\xb8re-og-romsdal.no\0vaksdal.no\0" +"rs.gov.br\0sc.gov.br\0asti.it\0" +"historisches.museum\0" +"nhs.uk\0flynnhub.com\0" +"soo.kagoshima.jp\0" +"pesarourbino.it\0" +"flekkefjord.no\0" +"americana.museum\0leangaviika.no\0torsken.no\0" +"zp.gov.pl\0center\0" +"myhome-server.de\0" +"rmit\0" +"hdfc\0\xe4\xb8\xad\xe4\xbf\xa1\0familyds.com\0" +"srv.br\0milan.it\0tosu.saga.jp\0" +"forgot.his.name\0" +"am.gov.br\0turen.tn\0" +"groks-the.info\0" +"h\xc3\xa1pmir.no\0" +"fujikawa.shizuoka.jp\0" +"tsukuba.ibaraki.jp\0kitadaito.okinawa.jp\0" +"ri.it\0" +"*.nom.br\0okazaki.aichi.jp\0izumo.shimane.jp\0" +"airline.aero\0ca.eu.org\0logoip.com\0" +"bi.it\0museum.tt\0" +"natori.miyagi.jp\0" +"namsskogan.no\0macys\0" +"sondre-land.no\0" +"historisch.museum\0" +"imari.saga.jp\0homedepot\0" +"shoes\0" +"kharkov.ua\0from-nj.com\0" +"kawakita.ishikawa.jp\0" +"fedorainfracloud.org\0" +"osasco.br\0friuli-vgiulia.it\0" +"cymru\0" +"washtenaw.mi.us\0" +"tsuyama.okayama.jp\0boston\0" +"tokai.ibaraki.jp\0" +"sherbrooke.museum\0virtuel.museum\0" +"tm.cy\0inc\0" +"scholarships\0bryansk.su\0" +"komoro.nagano.jp\0kunigami.okinawa.jp\0" +"lib.al.us\0ing\0" +"uryu.hokkaido.jp\0" +"cc.ri.us\0ink\0" +"turystyka.pl\0" +"directory\0" +"cloudns.us\0" +"rn.gov.br\0int\0" +"kutchan.hokkaido.jp\0" +"verran.no\0" +"lib.me.us\0" +"oristano.it\0" +"bolivia.bo\0" +"group\0" +"play\0" +"e.se\0erni\0" +"ome.tokyo.jp\0" +"chicago.museum\0steiermark.museum\0" +"tm.fr\0yachimata.chiba.jp\0beppu.oita.jp\0" +"camdvr.org\0hb.cldmail.ru\0" +"ap.gov.br\0" +"omi.nagano.jp\0" +"eiheiji.fukui.jp\0" +"ro.gov.br\0seirou.niigata.jp\0nishinoshima.shimane.jp\0" +"somna.no\0" +"setouchi.okayama.jp\0" +"iris.arpa\0ravendb.community\0uklugs.org\0" +"fuji.shizuoka.jp\0gmina.pl\0" +"dvrdns.org\0" +"joboji.iwate.jp\0" +"gs.tm.no\0cd.eu.org\0" +"kawazu.shizuoka.jp\0" +"mo.cn\0chiyoda.tokyo.jp\0" +"dh.bytemark.co.uk\0" +"asahi.ibaraki.jp\0tsu.mie.jp\0" +"ap.gov.pl\0total\0" +"v.bg\0bus.museum\0namsos.no\0" +"nanmoku.gunma.jp\0bel.tr\0" +"tm.hu\0" +"drobak.no\0mex.com\0" +"hikone.shiga.jp\0jcb\0" +"malvik.no\0agric.za\0wang\0fastvps-server.com\0" +"is-a-chef.org\0" +"prato.it\0*.cryptonomic.net\0" +"!city.kitakyushu.jp\0" +"\xd9\x85\xd9\x88\xd8\xa8\xd8\xa7\xd9\x8a\xd9\x84\xd9\x8a\0" +"mayfirst.org\0" +"shirosato.ibaraki.jp\0izumisano.osaka.jp\0kiyose.tokyo.jp\0jcp\0" +"omasvuotna.no\0" +"schokoladen.museum\0official.academy\0" +"togane.chiba.jp\0yotsukaido.chiba.jp\0ist\0" +"wa.au\0clothing\0" +"hongo.hiroshima.jp\0" +"services.aero\0tas.au\0rivne.ua\0" +"her\xc3\xb8y.nordland.no\0" +"conference.aero\0" +"andriatranibarletta.it\0museum.mv\0" +"museum.mw\0is-a-therapist.com\0" +"itv\0" +"tm.km\0" +"pomorskie.pl\0dyndns.tv\0" +"bonn.museum\0" +"kiyosato.hokkaido.jp\0" +"museum.no\0" +"nagato.yamaguchi.jp\0" +"casacam.net\0" +"bamble.no\0" +"pv.it\0" +"is-a-candidate.org\0" +"k12.or.us\0" +"shibetsu.hokkaido.jp\0shiojiri.nagano.jp\0" +"surrey.museum\0forsale\0" +"\xe5\xa4\xa7\xe9\x98\xaa.jp\0" +"museum.om\0" +"tm.mc\0" +"tajimi.gifu.jp\0edunet.tn\0" +"izumozaki.niigata.jp\0" +"tm.mg\0" +"hokkaido.jp\0" +"bozen.it\0" +"dyndns-remote.com\0" +"ri.us\0hotels\0" +"agdenes.no\0" +"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xd9\x8a\xd9\x87\0" +"itakura.gunma.jp\0" +"dyndns.ws\0" +"mo.it\0toyoura.hokkaido.jp\0" +"tm.no\0k12.la.us\0" +"woodside\0" +"delaware.museum\0h\xc3\xa1mm\xc3\xa1rfeasta.no\0lamborghini\0reliance\0" +"cancerresearch\0" +"is-a-chef.com\0" +"arkhangelsk.su\0" +"s\xc3\xa1l\xc3\xa1t.no\0" +"hiraya.nagano.jp\0" +"yamato.fukushima.jp\0" +"webspace.rocks\0" +"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xd9\x8a\xd8\xa9\0" +"jio\0u2.xnbay.com\0" +"gen.mi.us\0" +"brother\0" +"cloudns.pw\0" +"tm.pl\0" +"town\0" +"kawanishi.hyogo.jp\0" +"charter.aero\0vegas\0" +"k12.id.us\0" +"sanuki.kagawa.jp\0agematsu.nagano.jp\0haga.tochigi.jp\0" +"holdings\0" +"higashi.fukushima.jp\0" +"nes.akershus.no\0" +"\xe6\x9b\xb8\xe7\xb1\x8d\0" +"profesional.bo\0lviv.ua\0homesecuritypc.com\0" +"dnsup.net\0" +"vossevangen.no\0" +"m\xc4\x81ori.nz\0" +"cc.mo.us\0pgfog.com\0" +"guge\0" +"kanonji.kagawa.jp\0" +"nebraska.museum\0" +"kawagoe.saitama.jp\0" +"download\0" +"southcarolina.museum\0bremanger.no\0" +"grosseto.it\0\xe0\xa4\x95\xe0\xa5\x89\xe0\xa4\xae\0" +"evje-og-hornnes.no\0" +"oyodo.nara.jp\0" +"hasama.oita.jp\0" +"chernigov.ua\0" +"sumoto.hyogo.jp\0" +"insurance.aero\0tm.ro\0" +"makurazaki.kagoshima.jp\0" +"\xd9\x87\xd9\x85\xd8\xb1\xd8\xa7\xd9\x87\0" +"aomori.aomori.jp\0jll\0" +"homegoods\0toys\0" +"tm.se\0cupcake.is\0" +"seoul.kr\0" +"neues.museum\0" +"se.gov.br\0" +"c.bg\0" +"upow.gov.pl\0" +"\xe6\xb7\xa1\xe9\xa9\xac\xe9\x94\xa1\0" +"tsuruoka.yamagata.jp\0goodyear\0pictet\0" +"lidl\0" +"jdevcloud.com\0" +"jmp\0" +"s\xc3\xa1lat.no\0" +"tahara.aichi.jp\0nakagusuku.okinawa.jp\0" +"steinkjer.no\0" +"yokoshibahikari.chiba.jp\0nanjo.okinawa.jp\0" +"press.museum\0" +"jnj\0" +"lpages.co\0" +"higashine.yamagata.jp\0" +"illustration.museum\0" +"mragowo.pl\0" +"bz.it\0mmafan.biz\0" +"amusement.aero\0s3.dualstack.ca-central-1.amazonaws.com\0cya.gg\0" +"villas\0" +"hyllestad.no\0cc.wa.us\0life\0" +"tatsuno.hyogo.jp\0maori.nz\0" +"kwp.gov.pl\0" +"uto.kumamoto.jp\0" +"dyr\xc3\xb8y.no\0" +"atsuma.hokkaido.jp\0" +"nsw.au\0inder\xc3\xb8y.no\0cc.ga.us\0" +"sabae.fukui.jp\0design\0" +"sasebo.nagasaki.jp\0jot\0" +"gucci\0*.alces.network\0" +"kannami.shizuoka.jp\0" +"joy\0" +"nanao.ishikawa.jp\0akagi.shimane.jp\0*.bzz.dapps.earth\0" +"iraq.museum\0esurance\0" +"pc.it\0" +"guam.gu\0" +"cust.prod.thingdust.io\0" +"horonobe.hokkaido.jp\0" +"ibestad.no\0" +"abc.br\0novara.it\0nichinan.tottori.jp\0fujikawaguchiko.yamanashi.jp\0" +"wales.museum\0" +"shikokuchuo.ehime.jp\0help\0" +"textile.museum\0c66.me\0" +"\xd1\x83\xd0\xba\xd1\x80\0" +"dyndns-free.com\0" +"uki.kumamoto.jp\0" +"anthropology.museum\0botanicalgarden.museum\0raholt.no\0gjemnes.no\0" +"us-4.evennode.com\0" +"deloitte\0" +"mydissent.net\0" +"kustanai.ru\0" +"veg\xc3\xa5rshei.no\0leitungsen.de\0" +"valleedaoste.it\0" +"settlers.museum\0sa-east-1.elasticbeanstalk.com\0" +"sa.gov.pl\0clubmed\0" +"paleo.museum\0" +"rnrt.tn\0" +"kustanai.su\0" +"kyiv.ua\0" +"control.aero\0tm.za\0data\0lundbeck\0dattolocal.com\0" +"chiba.jp\0" +"rollag.no\0date\0" +"plus\0" +"maibara.shiga.jp\0" +"trani-andria-barletta.it\0epson\0" +"ruovat.no\0mo.us\0" +"ueda.nagano.jp\0" +"like\0" +"birdart.museum\0" +"gateway.museum\0pagefrontapp.com\0" +"higashihiroshima.hiroshima.jp\0" +"fribourg.museum\0etnedal.no\0" +"port.fr\0" +"union.aero\0" +"aju.br\0" +"higashichichibu.saitama.jp\0" +"furano.hokkaido.jp\0" +"yamanouchi.nagano.jp\0\xe0\xaa\xad\xe0\xaa\xbe\xe0\xaa\xb0\xe0\xaa\xa4\0" +"stange.no\0us-3.evennode.com\0" +"toda.saitama.jp\0" +"newport.museum\0locus\0" +"nose.osaka.jp\0" +"north.museum\0" +"kfh\0" +"here\0" +"bukhara.su\0ras.ru\0" +"nishinoomote.kagoshima.jp\0" +"c.la\0" +"oe.yamagata.jp\0" +"limo\0*.s5y.io\0" +"rocher\0" +"godo.gifu.jp\0shikama.miyagi.jp\0pc.pl\0" +"jur.pro\0" +"miasa.nagano.jp\0" +"n\xc3\xb8tter\xc3\xb8y.no\0" +"en.it\0" +"design.aero\0" +"takinoue.hokkaido.jp\0shinjo.yamagata.jp\0" +"barcelona.museum\0guru\0" +"bas.it\0kita.kyoto.jp\0" +"link\0" +"nyny.museum\0" +"wa.us\0" +"show.aero\0usantiques.museum\0" +"asago.hyogo.jp\0wiih.gov.pl\0" +"heimatunduhren.museum\0" +"ikoma.nara.jp\0" +"ga.us\0" +"gyeongbuk.kr\0ybo.faith\0" "kia\0" -"gov.il\0ambulance.museum\0" -"\xe7\xbb\x84\xe7\xbb\x87.hk\0" -"gov.in\0" -"wales.museum\0city\0" +"rg.it\0shizukuishi.iwate.jp\0" +"shobara.hiroshima.jp\0" +"uber.space\0" +"hb.cn\0store.nf\0" +"bushey.museum\0ashgabad.su\0" +"bg.it\0mimata.miyazaki.jp\0" +"kim\0promo\0ch.eu.org\0" +"matsubara.osaka.jp\0" +"us-2.evennode.com\0" +"logistics.aero\0windows\0" +"minano.saitama.jp\0" +"salem.museum\0" +"cremona.it\0higashiyama.kyoto.jp\0" +"watch-and-clock.museum\0" +"shibecha.hokkaido.jp\0" +"funagata.yamagata.jp\0" +"motosu.gifu.jp\0kuroiso.tochigi.jp\0" +"yoshida.shizuoka.jp\0" +"paris.eu.org\0" +"davvenj\xc3\xa1rga.no\0amica\0" +"western.museum\0" +"environmentalconservation.museum\0schule\0own.pm\0" +"noto.ishikawa.jp\0iwatsuki.saitama.jp\0" +"info.gu\0" +"nom.ad\0yuza.yamagata.jp\0" +"nom.ae\0" +"nom.af\0" +"nom.ag\0" +"isumi.chiba.jp\0shirakawa.gifu.jp\0witd.gov.pl\0" +"square.museum\0nom.ai\0" +"astronomy.museum\0vinnytsia.ua\0" +"kasahara.gifu.jp\0nom.al\0" +"funabashi.chiba.jp\0" +"\xe4\xb8\x96\xe7\x95\x8c\0" +"nature.museum\0bo.nordland.no\0" +"info.ht\0ono.fukui.jp\0" +"info.hu\0tank.museum\0" +"bloomberg\0" +"kofu.yamanashi.jp\0co.education\0" +"sp.leg.br\0" +"freiburg.museum\0" +"machida.tokyo.jp\0" +"obu.aichi.jp\0gifu.gifu.jp\0ashikaga.tochigi.jp\0" +"info.et\0" +"arte.bo\0homeftp.org\0" +"us-1.evennode.com\0" +"shika.ishikawa.jp\0" +"c.se\0" +"erotica.hu\0" +"nom.cl\0" +"is-very-nice.org\0" +"tagawa.fukuoka.jp\0shishikui.tokushima.jp\0" +"air-traffic-control.aero\0nom.co\0from-ne.com\0" +"colonialwilliamsburg.museum\0" +"homes\0" +"bifuka.hokkaido.jp\0ogawa.saitama.jp\0" +"yamashina.kyoto.jp\0" +"matsushima.miyagi.jp\0kodaira.tokyo.jp\0" +"imageandsound.museum\0" +"tado.mie.jp\0is-a-chef.net\0" +"live\0\xe5\x95\x86\xe6\xa0\x87\0murmansk.su\0" +"fr\xc3\xa6na.no\0nore-og-uvdal.no\0" +"kasumigaura.ibaraki.jp\0" +"niepce.museum\0s\xc3\xb8gne.no\0" +"gr.it\0" +"info.cx\0" +"room\0" +"nexus\0us-east-1.amazonaws.com\0" +"t.bg\0is-found.org\0forumz.info\0" +"ivanovo.su\0" +"campinas.br\0gr.jp\0" +"info.ec\0" +"nom.es\0ulm.museum\0baby\0" +"kpn\0" +"barsy.me\0serveexchange.com\0homelink.one\0" +"game.tw\0" +"voss.no\0" +"store.ve\0applinzi.com\0" +"info.bb\0frosinone.it\0" +"moscow.museum\0" +"nom.fr\0info.at\0" +"info.au\0at.eu.org\0" +"nom.gd\0" +"nom.ge\0" +"!city.sendai.jp\0" +"nannestad.no\0" +"info.az\0social\0" +"tsuchiura.ibaraki.jp\0krd\0lat\0" +"nom.gl\0" +"info.bo\0law\0applicationcloud.io\0" +"nankoku.kochi.jp\0" +"com.ac\0" +"ebetsu.hokkaido.jp\0*.elb.amazonaws.com.cn\0" +"com.af\0nom.gt\0" +"com.ag\0" +"com.ai\0" +"com.al\0aparecida.br\0" +"ddnslive.com\0" +"chippubetsu.hokkaido.jp\0" +"info.co\0" +"monash\0nom.hn\0" +"com.ba\0" +"com.ar\0com.bb\0art.br\0pesaro-urbino.it\0" +"r\xc3\xa1hkker\xc3\xa1vju.no\0hisamitsu\0" +"pt.it\0" +"com.au\0" +"kashima.saga.jp\0" +"com.aw\0tours\0" +"com.bh\0" +"com.bi\0" +"com.az\0" +"s3.dualstack.eu-west-1.amazonaws.com\0" +"fukushima.hokkaido.jp\0tokorozawa.saitama.jp\0" +"com.bm\0oregontrail.museum\0read-books.org\0" +"com.bn\0" +"com.bo\0nom.im\0" +"ogano.saitama.jp\0" +"com.br\0" +"com.bs\0" +"com.bt\0" +"software.aero\0pubol.museum\0" +"abira.hokkaido.jp\0" +"com.by\0com.ci\0" +"com.bz\0ad.jp\0flickr\0" +"lds\0" +"com.cm\0plc.co.im\0" +"com.cn\0traniandriabarletta.it\0" +"pueblo.bo\0com.co\0art.do\0" +"\xe5\x85\xac\xe5\x8f\xb8.cn\0" +"tohnosho.chiba.jp\0kawanabe.kagoshima.jp\0nakagawa.nagano.jp\0" +"politica.bo\0" +"sh.cn\0" +"com.cu\0tr\xc3\xb8gstad.no\0com.de\0" +"sanagochi.tokushima.jp\0" +"com.cw\0karasjok.no\0nom.ke\0" +"com.cy\0tolga.no\0store.ro\0" +"art.dz\0lom.it\0mantova.it\0" +"nakadomari.aomori.jp\0" +"com.dm\0\xe5\x85\xac\xe5\x8f\xb8.hk\0" +"com.do\0nom.km\0" +"\xe6\xbb\x8b\xe8\xb3\x80.jp\0weather\0" +"koka.shiga.jp\0" +"com.ec\0bashkiria.ru\0" +"com.ee\0" +"com.eg\0settlement.museum\0herokussl.com\0" +"gets-it.net\0" +"works.aero\0" +"com.dz\0" +"nom.li\0" +"omachi.saga.jp\0" +"bearalvahki.no\0" +"\xe7\xa7\x8b\xe7\x94\xb0.jp\0store.st\0" +"mandal.no\0north-kazakhstan.su\0obninsk.su\0" +"com.es\0bashkiria.su\0" +"com.et\0" +"nom.mg\0mein-iserv.de\0" +"choyo.kumamoto.jp\0" +"music.museum\0nom.mk\0" +"com.fr\0" +"anjo.aichi.jp\0" +"com.ge\0nom.nc\0" +"palmas.br\0\xd8\xa7\xd8\xb1\xd8\xa7\xd9\x85\xd9\x83\xd9\x88\0" +"com.gh\0" +"economia.bo\0com.gi\0" +"nom.ni\0" +"com.gl\0kawara.fukuoka.jp\0tenri.nara.jp\0" +"barsy.uk\0" +"com.gn\0email\0" +"com.gp\0" +"delta\0" +"com.gr\0nagara.chiba.jp\0florist\0" +"dovre.no\0porsanger.no\0s3-us-gov-west-1.amazonaws.com\0" +"com.gt\0art.ht\0" +"com.gu\0from-de.com\0" +"towada.aomori.jp\0takata.fukuoka.jp\0" +"nom.nu\0" +"chambagri.fr\0" +"com.gy\0ap-northeast-1.elasticbeanstalk.com\0" +"iwanuma.miyagi.jp\0" +"catering.aero\0com.hk\0roros.no\0" +"watch\0" +"vladimir.su\0" +"com.hn\0semboku.akita.jp\0hanamigawa.chiba.jp\0chiyoda.gunma.jp\0kuwana.mie.jp\0" +"cinema.museum\0" +"com.hr\0" +"nom.pa\0lug.org.uk\0" +"com.ht\0higashishirakawa.gifu.jp\0" +"lom.no\0vestvagoy.no\0" +"ce.gov.br\0" +"a.bg\0romskog.no\0nom.pe\0" +"is-into-games.com\0" +"inatsuki.fukuoka.jp\0" +"tra.kp\0" +"com.im\0abudhabi\0" +"kudoyama.wakayama.jp\0nom.pl\0" +"com.io\0aejrie.no\0davvenjarga.no\0" +"nango.fukushima.jp\0band\0forex\0" +"com.iq\0nationalfirearms.museum\0" +"com.is\0bergen.no\0nom.qa\0" +"bank\0" +"kurashiki.okayama.jp\0musashino.tokyo.jp\0hotel.tz\0" +"botany.museum\0newmexico.museum\0nom.pw\0" +"llc\0university\0" +"higashinaruse.akita.jp\0fujimi.saitama.jp\0" +"dclk\0" +"bunkyo.tokyo.jp\0office-on-the.net\0" +"com.jo\0mycd.eu\0" +"kawatana.nagasaki.jp\0satosho.okayama.jp\0kawaguchi.saitama.jp\0" +"honda\0barrel-of-knowledge.info\0" +"ch.it\0kanazawa.ishikawa.jp\0" +"com.kg\0matta-varjjat.no\0nom.re\0mckinsey\0ciscofreak.com\0" +"*.bd\0higashiagatsuma.gunma.jp\0" +"com.ki\0" +"com.km\0schoenbrunn.museum\0vladimir.ru\0ybo.review\0" +"ichinomiya.aichi.jp\0numata.hokkaido.jp\0" +"lans.museum\0" +"mitake.gifu.jp\0com.kp\0" +"com.la\0nom.ro\0" +"com.lb\0" +"veterinaire.km\0com.lc\0uzhgorod.ua\0is-a-musician.com\0freedesktop.org\0" +"info.ve\0nom.rs\0" +"tanabe.kyoto.jp\0" +"com.kw\0" +"pgafan.net\0" +"com.ky\0missile.museum\0" +"com.kz\0" +"com.lk\0nom.si\0" +"pa.it\0info.vn\0arab\0" +"*.ck\0" +"miyako.iwate.jp\0" +"k12.ok.us\0" +"com.lr\0wlocl.pl\0\xe5\xb7\xa5\xe8\xa1\x8c\0" +"\xd9\xbe\xd8\xa7\xda\xa9\xd8\xb3\xd8\xaa\xd8\xa7\xd9\x86\0" +"isa-hockeynut.com\0" +"com.lv\0ostrowiec.pl\0nom.st\0" +"com.mg\0" +"kawasaki.miyagi.jp\0" +"com.ly\0" +"com.mk\0" +"com.ml\0nom.tj\0" +"historyofscience.museum\0midtre-gauldal.no\0bir.ru\0" +"minami.fukuoka.jp\0" +"com.mo\0southwest.museum\0nom.tm\0drud.io\0" +"com.na\0" +"com.ms\0showtime\0" +"com.mt\0lol\0" +"com.mu\0plaza.museum\0" +"com.mv\0com.nf\0" +"com.mw\0com.ng\0" +"com.mx\0" +"com.my\0com.ni\0nom.ug\0" +"yonezawa.yamagata.jp\0" +"production.aero\0sciencecenters.museum\0" +"lodi.it\0info.tn\0" +"chiryu.aichi.jp\0" +"blogdns.com\0" +"com.nr\0info.tr\0" +"lib.mt.us\0lib.nd.us\0" +"info.tt\0lpl\0" +"ooguy.com\0nom.vc\0" +"*.er\0" +"sande.m\xc3\xb8re-og-romsdal.no\0" +"veterinaire.fr\0rikuzentakata.iwate.jp\0jeonnam.kr\0" +"nom.vg\0" +"info.tz\0" +"t.se\0nom.uy\0" +"art.pl\0" +"com.om\0" +"*.fj\0" +"*.fk\0" +"\xe4\xb8\x89\xe9\x87\x8d.jp\0" +"com.pa\0cc.pa.us\0" +"nishinomiya.hyogo.jp\0" +"tsurugashima.saitama.jp\0" +"aukra.no\0com.pe\0" +"hara.nagano.jp\0com.pf\0man\0" +"pharmacy.museum\0" +"piemonte.it\0trentinosudtirol.it\0com.ph\0map\0zapto.xyz\0" +"mba\0" +"izena.okinawa.jp\0" +"museumvereniging.museum\0com.pk\0" +"tomioka.gunma.jp\0com.pl\0" +"takasaki.gunma.jp\0hiraizumi.iwate.jp\0" +"info.ro\0" +"historichouses.museum\0com.qa\0" +"com.pr\0" +"com.ps\0" +"com.pt\0info.sd\0" +"g\xc3\xa1\xc5\x8bgaviika.no\0" +"hida.gifu.jp\0" +"hotel.lk\0com.py\0paris\0" +"\xe5\xb1\xb1\xe5\x8f\xa3.jp\0fujixerox\0" +"yachiyo.chiba.jp\0" +"trentinosued-tirol.it\0\xe0\xa6\xad\xe0\xa6\xbe\xe0\xa7\xb0\xe0\xa6\xa4\0" +"holtalen.no\0" +"\xe7\xb5\x84\xe7\xb9\x94.tw\0" +"soeda.fukuoka.jp\0" +"gorge.museum\0com.re\0au.eu.org\0be.eu.org\0" +"info.pk\0" +"trentinosuedtirol.it\0tokamachi.niigata.jp\0gushikami.okinawa.jp\0info.pl\0ltd\0" +"miyoshi.saitama.jp\0art.sn\0" +"com.ro\0" +"denmark.museum\0uhren.museum\0com.sa\0servegame.com\0" +"info.pr\0com.sb\0" +"com.sc\0nom.za\0" +"hs.kr\0com.sd\0" +"\xc3\xa5l.no\0com.se\0com.ru\0" +"mashiki.kumamoto.jp\0" +"com.rw\0com.sg\0" +"com.sh\0" +"rade.no\0americanfamily\0" +"valledaosta.it\0" +"froya.no\0" +"store.bb\0com.sl\0med\0" +"com.sn\0ericsson\0" +"com.so\0git-repos.de\0" +"ryuoh.shiga.jp\0" +"*.jm\0info.na\0is-a-democrat.com\0" +"britishcolumbia.museum\0" +"motobu.okinawa.jp\0com.st\0" +"myravendb.com\0" +"info.mv\0info.nf\0com.sv\0men\0" +"trainer.aero\0" +"info.ni\0com.sy\0barsy.bg\0" +"com.tj\0" +"*.kh\0" +"com.tm\0" +"com.tn\0" +"depot.museum\0com.to\0" +"com.ua\0safe\0" +"info.nr\0com.tr\0pohl\0" +"tysvar.no\0" +"re.it\0com.tt\0" +"muncie.museum\0com.tw\0cherkassy.ua\0com.ug\0" +"geisei.kochi.jp\0izumi.osaka.jp\0swidnik.pl\0" +"tomobe.ibaraki.jp\0" +"exeter.museum\0" +"monzabrianza.it\0" +"info.la\0bitballoon.com\0" +"\xe0\xb8\x97\xe0\xb8\xab\xe0\xb8\xb2\xe0\xb8\xa3.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0istanbul\0" +"hotel.hu\0com.vc\0barcelona\0" +"com.ve\0realestate\0store.dk\0bg.eu.org\0" +"flog.br\0" +"\xe7\xbb\x84\xe7\xb9\x94.hk\0barsy.de\0" +"com.uy\0com.vi\0ddnsking.com\0" +"com.uz\0" +"com.vn\0" +"bronnoysund.no\0" +"toya.hokkaido.jp\0ebina.kanagawa.jp\0" +"*.mm\0zoological.museum\0lind\xc3\xa5s.no\0" +"re.kr\0" +"info.ls\0no-ip.co.uk\0" +"com.vu\0" +"finearts.museum\0" +"hiratsuka.kanagawa.jp\0" +"media.hu\0iron.museum\0" +"jampa.br\0" +"k12.nj.us\0" +"tamano.okayama.jp\0" +"misaki.okayama.jp\0cloudns.club\0" +"heroy.nordland.no\0" +"homeftp.net\0" +"com.ws\0" +"mil\0*.np\0hgtv\0" +"varggat.no\0" +"vlog.br\0oharu.aichi.jp\0" +"barsy.eu\0" +"mit\0" +"pa.us\0" +"friulivegiulia.it\0" +"town.museum\0" +"\xe5\xb1\xb1\xe5\xbd\xa2.jp\0hidaka.saitama.jp\0" +"ab.ca\0info.ke\0forum\0us.com\0" +"chuo.fukuoka.jp\0sklep.pl\0" +"qld.au\0" +"info.ki\0" +"jinsekikogen.hiroshima.jp\0yashio.saitama.jp\0" +"*.pg\0" +"lib.mi.us\0" +"to.leg.br\0" +"comsec\0" +"jan-mayen.no\0" +"loten.no\0drud.us\0" +"a.se\0army\0east-kazakhstan.su\0" +"tomiya.miyagi.jp\0" +"mlb\0" +"s3-website.ap-south-1.amazonaws.com\0kurgan.su\0" +"sld.do\0com.zm\0" +"campidanomedio.it\0" +"luxembourg.museum\0sale\0" +"ouda.nara.jp\0" +"dynamic-dns.info\0" +"griw.gov.pl\0" +"s3-external-1.amazonaws.com\0" +"karikatur.museum\0project.museum\0mma\0" +"kg.kr\0" +"mls\0" +"arpa\0michigan.museum\0" +"nanporo.hokkaido.jp\0uppo.gov.pl\0" +"flesberg.no\0" +"barsy.in\0" +"it.ao\0time.no\0barsy.io\0" +"freemasonry.museum\0africa\0hr.eu.org\0" +"ntdll.top\0" +"r.bg\0skierva.no\0qc.com\0" +"r\xc3\xa1isa.no\0parts\0" +"omiya.saitama.jp\0" +"roma.museum\0" +"res.aero\0party\0" +"rockart.museum\0" +"mj\xc3\xb8ndalen.no\0contractors\0passagens\0" +"hamaroy.no\0" +"go.gov.br\0" +"educational.museum\0" +"amagasaki.hyogo.jp\0frontier\0" +"\xe7\xae\x87\xe4\xba\xba.hk\0ddr.museum\0s3.dualstack.ap-southeast-2.amazonaws.com\0" +"weir\0" +"feira.br\0asakawa.fukushima.jp\0" +"fl\xc3\xa5.no\0k12.sc.us\0moe\0" +"oregon.museum\0" +"vercelli.it\0basketball\0" +"aip.ee\0nedre-eiker.no\0moi\0" +"togakushi.nagano.jp\0final\0barsy.support\0no-ip.biz\0" +"consulting\0mom\0tires\0lcube-server.de\0" +"voting\0" +"is-a-landscaper.com\0" +"conf.au\0suisse.museum\0" +"kamikawa.hyogo.jp\0mov\0" +"frogn.no\0" +"media.pl\0" +"bsb.br\0swiftcover\0" +"koori.fukushima.jp\0porn\0noho.st\0" +"b\xc3\xa5""d\xc3\xa5""ddj\xc3\xa5.no\0" +"honbetsu.hokkaido.jp\0" +"pacific.museum\0" +"fm.br\0makinohara.shizuoka.jp\0" +"nab\0myfritz.net\0" +"co.krd\0" +"asda\0" +"pr.it\0kakamigahara.gifu.jp\0\xd8\xb9\xd9\x85\xd8\xa7\xd9\x86\0deal\0" +"aogashima.tokyo.jp\0" +"arte\0" +"reggioemilia.it\0ehime.jp\0teshikaga.hokkaido.jp\0" +"santamaria.br\0" +"cyber.museum\0" +"nakagawa.hokkaido.jp\0yamato.kanagawa.jp\0ogimi.okinawa.jp\0" +"nba\0" +"post\0" +"cahcesuolo.no\0" +"android\0" +"\xd9\x83\xd8\xa7\xd8\xab\xd9\x88\xd9\x84\xd9\x8a\xd9\x83\0" +"s3-eu-central-1.amazonaws.com\0" +"kawai.nara.jp\0\xe8\xb0\xb7\xe6\xad\x8c\0" +"withgoogle.com\0" +"nh-serv.co.uk\0" +"iizuka.fukuoka.jp\0meiwa.mie.jp\0lezajsk.pl\0" +"minamiboso.chiba.jp\0hashima.gifu.jp\0imamat\0" +"manaus.br\0urbino-pesaro.it\0kariya.aichi.jp\0sarl\0" +"vpnplus.to\0" +"msd\0" +"bbva\0" +"meldal.no\0" +"*.triton.zone\0" +"crotone.it\0toho.fukuoka.jp\0" +"portal.museum\0tr\xc3\xa6na.no\0\xd9\x82\xd8\xb7\xd8\xb1\0" +"allfinanz\0" +"heroy.more-og-romsdal.no\0" +"*.ye\0" +"nrw.museum\0" +"does-it.net\0" +"ginoza.okinawa.jp\0" +"yahaba.iwate.jp\0" +"cc.pr.us\0azerbaijan.su\0" +"mtn\0" +"cloudns.info\0" +"abarth\0" +"\xe1\x83\x92\xe1\x83\x94\0mtr\0" +"nec\0" +"yokote.akita.jp\0sodegaura.chiba.jp\0" +"l\xc3\xa1hppi.no\0" +"kitagawa.kochi.jp\0" +"workinggroup.aero\0" +"padova.it\0onga.fukuoka.jp\0" +"stjordal.no\0us-east-1.elasticbeanstalk.com\0s3-sa-east-1.amazonaws.com\0" +"\xe5\xbe\xb3\xe5\xb3\xb6.jp\0komatsu.ishikawa.jp\0" +"gs.fm.no\0" +"saobernardo.br\0" +"globo\0" +"okinawa.okinawa.jp\0net\0" +"asia\0" +"melhus.no\0new\0" +"vao.it\0" +"save\0" +"defense.tn\0" +"lefrak\0" +"kawanishi.yamagata.jp\0nfl\0" +"katsushika.tokyo.jp\0lawyer\0" +"\xe7\xb5\x84\xe7\xb9\x94.hk\0pramerica\0" +"df.leg.br\0" +"airtel\0" +"rakkestad.no\0" +"tsuga.tochigi.jp\0" +"sld.pa\0" +"med.pro\0" +"gs.sf.no\0" +"ecologia.bo\0" +"ngo\0" +"everbank\0" +"fm.it\0nishiazai.shiga.jp\0" +"v\xc3\xa5gan.no\0is-into-cartoons.com\0" +"def.br\0\xd8\xb3\xd9\x88\xd8\xaf\xd8\xa7\xd9\x86\0" +"public.museum\0software\0" +"seaport.museum\0" +"hino.tokyo.jp\0" +"austin.museum\0nhk\0" +"writesthisblog.com\0" +"mlbfan.org\0" +"\xe7\xb6\xb2\xe7\xb5\xa1.cn\0abr.it\0varese.it\0hirokawa.fukuoka.jp\0" +"kvanangen.no\0" +"maceio.br\0" +"saxo\0" +"furniture.museum\0" +"tirol\0" +"saka.hiroshima.jp\0*.magentosite.cloud\0" +"brunel.museum\0tingvoll.no\0eaton.mi.us\0daplie.me\0" +"s\xc3\xbc""dtirol.it\0" +"stadt.museum\0" +"yamada.iwate.jp\0" +"lib.tx.us\0" +"ravenna.it\0cistron.nl\0" +"bestbuy\0" +"kamisato.saitama.jp\0" +"\xc3\xa5seral.no\0drive\0drayddns.com\0" +"corporation.museum\0" +"adv.br\0" +"jorpeland.no\0info.zm\0" +"abeno.osaka.jp\0showa.yamanashi.jp\0" +"k12.ar.us\0" +"idv.hk\0medizinhistorisches.museum\0" +"locker\0" +"sampa.br\0tsumagoi.gunma.jp\0wiw.gov.pl\0" +"allstate\0" +"miyota.nagano.jp\0" +"\xe9\x9d\x99\xe5\xb2\xa1.jp\0" +"mihama.fukui.jp\0nishiokoppe.hokkaido.jp\0" +"tsuiki.fukuoka.jp\0" +"even\xc3\xa1\xc5\xa1\xc5\xa1i.no\0" +"higashisumiyoshi.osaka.jp\0" +"acct.pro\0movie\0" +"nichinan.miyazaki.jp\0dell\0" +"pizza\0" +"trentinsud-tirol.it\0\xe0\xae\x87\xe0\xae\xb2\xe0\xae\x99\xe0\xaf\x8d\xe0\xae\x95\xe0\xaf\x88\0" +"r\xc3\xb8""d\xc3\xb8y.no\0vikna.no\0s3-website-ap-southeast-1.amazonaws.com\0" +"tone.ibaraki.jp\0cloudaccess.host\0" +"touch.museum\0nesodden.no\0" +"fm.no\0" +"\xe3\x82\xb3\xe3\x83\xa0\0" +"khmelnytskyi.ua\0" +"jgora.pl\0" +"is-with-theband.com\0" +"gok.pk\0pr.us\0" +"kotoura.tottori.jp\0" +"minamiashigara.kanagawa.jp\0" +"kyoto.jp\0" +"satx.museum\0brumunddal.no\0" +"curitiba.br\0" +"bc.ca\0\xe7\xb6\xb2\xe7\xb5\xa1.hk\0uscountryestate.museum\0hockey\0" +"kawakami.nara.jp\0" +"ringsaker.no\0" +"suwa.nagano.jp\0" +"t\xc3\xb8nsberg.no\0" +"sf.no\0mk.ua\0" +"komagane.nagano.jp\0murakami.niigata.jp\0" +"fjell.no\0events\0" +"pioneer\0" +"dyndns-mail.com\0" +"hizen.saga.jp\0" +"r.se\0" +"health.museum\0no-ip.info\0" +"elblag.pl\0eurovision\0international\0" +"nl.ca\0user.party.eus\0is-a-bookkeeper.com\0" +"\xe9\xb3\xa5\xe5\x8f\x96.jp\0ogasawara.tokyo.jp\0\xe8\xaf\xba\xe5\x9f\xba\xe4\xba\x9a\0" +"\xd8\xa7\xd8\xa8\xd9\x88\xd8\xb8\xd8\xa8\xd9\x8a\0" +"capebreton.museum\0s\xc3\xb8ndre-land.no\0" +"niigata.jp\0!city.kawasaki.jp\0\xd8\xa7\xd9\x84\xd8\xa7\xd8\xb1\xd8\xaf\xd9\x86\0" +"now\0" +"london\0" +"ishikawa.jp\0samukawa.kanagawa.jp\0" +"kunstsammlung.museum\0" +"yamato.kumamoto.jp\0" +"australia.museum\0" +"rome.it\0tsuru.yamanashi.jp\0" +"wake.okayama.jp\0wloclawek.pl\0" +"chigasaki.kanagawa.jp\0" +"ngrok.io\0noip.us\0" +"etc.br\0seki.gifu.jp\0" +"lincoln.museum\0il.eu.org\0" +"\xe5\xba\x83\xe5\xb3\xb6.jp\0" +"eastcoast.museum\0sor-fron.no\0ipiranga\0" +"nra\0twmail.cc\0" +"\xc3\xa5krehamn.no\0lib.vt.us\0" +"anan.tokushima.jp\0yamanobe.yamagata.jp\0" +"ichiba.tokushima.jp\0" +"f\xc3\xb8rde.no\0" +"obi\0" +"garden\0" +"inami.wakayama.jp\0" +"photos\0" +"crafting.xyz\0" +"parti.se\0" +"svizzera.museum\0firewall-gateway.de\0" +"pharmaciens.km\0chernihiv.ua\0desi\0" +"nrw\0" +"shiki.saitama.jp\0" +"caa.aero\0sor-odal.no\0cc.ia.us\0" +"norddal.no\0hu.eu.org\0ie.eu.org\0" +"sakai.fukui.jp\0" +"balsfjord.no\0bloxcms.com\0" +"\xe7\x8f\xa0\xe5\xae\x9d\0shiftedit.io\0" +"kitanakagusuku.okinawa.jp\0" +"rc.it\0" +"gs.nl.no\0rv.ua\0" +"kanie.aichi.jp\0" +"dnipropetrovsk.ua\0tube\0" +"fuso.aichi.jp\0" +"loppa.no\0tiffany\0" +"reklam.hu\0" +"numata.gunma.jp\0ntt\0" +"sa.edu.au\0" +"verbania.it\0" +"shimabara.nagasaki.jp\0dnsalias.net\0" +"nesseby.no\0plumbing\0" +"servehttp.com\0" +"onjuku.chiba.jp\0adv.mz\0" +"kids.museum\0motorcycle.museum\0" +"kamioka.akita.jp\0ine.kyoto.jp\0" +"nationalheritage.museum\0gratis\0" +"off\0" +"gausdal.no\0condos\0" +"daisen.akita.jp\0" +"openair.museum\0gaular.no\0\xc3\xb8ystre-slidre.no\0" +"lib.or.us\0" +"uw.gov.pl\0" +"ismaili\0" +"furukawa.miyagi.jp\0kitakata.miyazaki.jp\0" +"nagawa.nagano.jp\0" +"s\xc3\xb8mna.no\0lpusercontent.com\0" +"pp.az\0yomitan.okinawa.jp\0" +"idv.tw\0" +"estate\0" +"caravan\0" +"yamagata.ibaraki.jp\0" +"b\xc3\xa5tsfjord.no\0" +"nara.jp\0" +"gliding.aero\0cc.as.us\0" +"yamazoe.nara.jp\0" +"\xe7\x9f\xb3\xe5\xb7\x9d.jp\0democrat\0" +"iwate.jp\0" +"skien.no\0" +"taxi.br\0takagi.nagano.jp\0" +"embetsu.hokkaido.jp\0kuju.oita.jp\0" +"servehumour.com\0" +"dr\xc3\xb8""bak.no\0" +"minamiminowa.nagano.jp\0yamatotakada.nara.jp\0toshima.tokyo.jp\0" +"fineart.museum\0storfjord.no\0nyc\0" +"vall\xc3\xa9""eaoste.it\0" +"statebank\0" +"is-a-nascarfan.com\0""3utilities.com\0" +"nachikatsuura.wakayama.jp\0" +"fin.ec\0" +"dali.museum\0songdalen.no\0" +"obama.fukui.jp\0" +"imabari.ehime.jp\0" +"trysil.no\0s3.dualstack.us-east-1.amazonaws.com\0" +"\xe0\xb2\xad\xe0\xb2\xbe\xe0\xb2\xb0\xe0\xb2\xa4\0" +"ashoro.hokkaido.jp\0" +"hembygdsforbund.museum\0" +"\xe6\x89\x8b\xe8\xa1\xa8\0" +"conf.lv\0" +"nl.no\0feedback\0shouji\0" +"iglesias-carbonia.it\0hashikami.aomori.jp\0" +"sakura.tochigi.jp\0" +"p.bg\0emerck\0" +"sakaiminato.tottori.jp\0" +"cleaning\0" +"shijonawate.osaka.jp\0hino.tottori.jp\0nanyo.yamagata.jp\0" +"\xe6\x95\x99\xe8\x82\xb2.hk\0indiana.museum\0" +"izu.shizuoka.jp\0" +"is-a-techie.com\0" +"adult\0" +"equipment\0" +"discovery.museum\0pharmacy\0" +"ia.us\0" +"nishihara.okinawa.jp\0izumiotsu.osaka.jp\0" +"nasu.tochigi.jp\0" +"lib.vi.us\0servegame.org\0noip.me\0pantheonsite.io\0" +"sakegawa.yamagata.jp\0" +"ass.km\0skaun.no\0" +"armenia.su\0" +"half.host\0" +"tsubata.ishikawa.jp\0" +"servequake.com\0" +"9.bg\0v\xc3\xa6r\xc3\xb8y.no\0gr.eu.org\0" +"yachiyo.ibaraki.jp\0fujisawa.kanagawa.jp\0urawa.saitama.jp\0" +"maryland.museum\0" +"taki.mie.jp\0" +"\xe6\x96\xb0\xe9\x97\xbb\0" +"ilawa.pl\0" +"fundacio.museum\0one\0travelersinsurance\0" +"wada.nagano.jp\0\xd8\xa7\xd9\x84\xd8\xb9\xd9\x84\xd9\x8a\xd8\xa7\xd9\x86\0" +"ong\0*.elb.amazonaws.com\0from-ks.com\0" +"nord-aurdal.no\0\xd8\xaa\xd9\x88\xd9\x86\xd8\xb3\0" +"ninohe.iwate.jp\0" +"otsuki.yamanashi.jp\0onl\0" +"meguro.tokyo.jp\0" +"trust.museum\0zhytomyr.ua\0" +"tarui.gifu.jp\0" +"ballooning.aero\0" +"miyazaki.jp\0vpndns.net\0" +"railroad.museum\0" +"blog.bo\0capitalone\0" +"aki.kochi.jp\0" +"chintai\0rackmaze.com\0" +"blog.br\0" +"ooo\0" +"bialystok.pl\0" +"manno.kagawa.jp\0shichikashuku.miyagi.jp\0" +"med.br\0scor\0" +"scot\0" +"fvg.it\0toyako.hokkaido.jp\0discover\0" +"miho.ibaraki.jp\0" +"oppegard.no\0" +"as.us\0" +"sd.cn\0malbork.pl\0" +"virginia.museum\0" +"higashitsuno.kochi.jp\0" +"mi.it\0" +"oksnes.no\0shangrila\0" +"gyeongnam.kr\0limited\0rj.leg.br\0" +"k12.ks.us\0" +"brescia.it\0" +"jeju.kr\0management\0podzone.net\0" +"vads\xc3\xb8.no\0audi\0" +"outsystemscloud.com\0" +"funahashi.toyama.jp\0" +"autos\0wellbeingzone.co.uk\0" +"forlicesena.it\0olawa.pl\0ostrowwlkp.pl\0" +"vanylven.no\0from-ms.com\0from-nc.com\0" +"asuke.aichi.jp\0flynnhosting.net\0" +"r\xc3\xa6lingen.no\0" +"med.ec\0org\0delivery\0n4t.co\0" +"vic.edu.au\0med.ee\0pay\0golffan.us\0" +"kinko.kagoshima.jp\0" +"marche.it\0" +"*.compute-1.amazonaws.com\0" +"porsgrunn.no\0" +"tochio.niigata.jp\0" +"unicom\0" +"konsulat.gov.pl\0" +"lakas.hu\0dyndns-ip.com\0" +"heritage.museum\0starnberg.museum\0dscloud.me\0" +"yamatsuri.fukushima.jp\0beer\0barsy.shop\0" +"\xe5\xb1\xb1\xe6\xa2\xa8.jp\0komaki.aichi.jp\0myoko.niigata.jp\0" +"veneto.it\0tobetsu.hokkaido.jp\0semine.miyagi.jp\0" +"movimiento.bo\0" +"hammerfest.no\0" +"zakopane.pl\0" +"quebec\0fuettertdasnetz.de\0" +"nishiwaki.hyogo.jp\0" +"brandywinevalley.museum\0s3.dualstack.eu-west-2.amazonaws.com\0" +"fiat\0" +"granvin.no\0cc.mi.us\0" +"grp.lk\0pvt.k12.ma.us\0" +"name.hr\0sugito.saitama.jp\0" +"mishima.fukushima.jp\0joetsu.niigata.jp\0" +"suzuka.mie.jp\0" +"\xe6\x85\x88\xe5\x96\x84\0" +"is-an-engineer.com\0" +"minami.tokushima.jp\0ott\0" +"nationwide\0from-sc.com\0" +"potenza.it\0career\0" +"\xe6\x94\xbf\xe5\xba\x9c.hk\0panasonic\0" +"\xd1\x81\xd0\xb0\xd0\xb9\xd1\x82\0" +"goshiki.hyogo.jp\0" +"delmenhorst.museum\0zoology.museum\0lib.gu.us\0" +"name.et\0\xe6\x89\x8b\xe6\x9c\xba\0" +"\xd9\x83\xd9\x88\xd9\x85\0" +"*.platform.sh\0" +"yachts\0" +"svelvik.no\0" +"pet\0" +"naturalsciences.museum\0jolster.no\0" +"massacarrara.it\0" +"med.ht\0ovh\0" +"trentinsuedtirol.it\0wazuka.kyoto.jp\0" +"county.museum\0oxford.museum\0" +"inf.br\0" +"ushiku.ibaraki.jp\0accountant\0" +"fido\0" +"kuroishi.aomori.jp\0" +"metlife\0" +"rsvp\0" +"narvik.no\0mytuleap.com\0freebox-os.com\0" +"barefoot\0" +"bronnoy.no\0smile\0" +"trentino-stirol.it\0" +"inf.cu\0" +"bt.it\0tamaki.mie.jp\0" +"pp.se\0pp.ru\0" +"takarazuka.hyogo.jp\0" +"name.cy\0" +"misasa.tottori.jp\0phd\0" +"correios-e-telecomunica\xc3\xa7\xc3\xb5""es.museum\0" +"kazuno.akita.jp\0" +"pavia.it\0" +"name.eg\0" +"kawaminami.miyazaki.jp\0" +"photography.museum\0" +"pid\0" +"california.museum\0" +"kudamatsu.yamaguchi.jp\0" +"sakurai.nara.jp\0" +"fin.tn\0" +"travel\0" +"k12.mo.us\0pp.ua\0" +"pin\0" +"szczecin.pl\0zagan.pl\0" +"\xe6\x8b\x9b\xe8\x81\x98\0" +"is-lost.org\0" +"name.az\0" +"yazu.tottori.jp\0" +"cc.sd.us\0" +"catania.it\0" +"aknoluokta.no\0" +"med.ly\0fredrikstad.no\0" +"um.gov.pl\0" +"montreal.museum\0" +"sosa.chiba.jp\0matsumoto.nagano.jp\0loan\0instantcloud.cn\0" +"hokuto.hokkaido.jp\0odawara.kanagawa.jp\0" +"is-a-hard-worker.com\0" +"\xe5\xb2\xa1\xe5\xb1\xb1.jp\0" +"chikuhoku.nagano.jp\0mi.th\0" +"cartoonart.museum\0" +"nieruchomosci.pl\0" +"hammarfeasta.no\0" +"seiro.niigata.jp\0" +"ohi.fukui.jp\0" +"lib.nh.us\0" +"expert\0" +"ddnsfree.com\0yombo.me\0" +"trentin-suedtirol.it\0" +"newjersey.museum\0\xe4\xb8\xad\xe5\x9b\xbd\0" +"nerima.tokyo.jp\0" +"p.se\0" +"vda.it\0aoste.it\0ic.gov.pl\0" +"koeln.museum\0r\xc3\xa5""de.no\0" +"muko.kyoto.jp\0govt.nz\0" +"tcm.museum\0austrheim.no\0" +"vaporcloud.io\0" +"toon.ehime.jp\0moriguchi.osaka.jp\0" +"rightathome\0" +"torahime.shiga.jp\0gmail\0ba.leg.br\0" +"med.om\0institute\0systems\0" +"moroyama.saitama.jp\0prod\0" +"mi.us\0\xe4\xb8\xad\xe5\x9c\x8b\0" +"hinode.tokyo.jp\0prof\0" +"med.pa\0" +"yasuda.kochi.jp\0hakuba.nagano.jp\0" +"from-dc.com\0" +"vestre-toten.no\0" +"shinonsen.hyogo.jp\0" +"k12.wa.us\0" +"med.pl\0" +"barsy.net\0" +"usdecorativearts.museum\0osteroy.no\0pnc\0dray-dns.de\0" +"tsushima.aichi.jp\0yukuhashi.fukuoka.jp\0kiso.nagano.jp\0fukaya.saitama.jp\0" +"club.tw\0k12.ga.us\0" +"taranto.it\0" +"calabria.it\0uchinomi.kagawa.jp\0red.sv\0" +"kr\xc3\xa5""anghke.no\0" +"miki.hyogo.jp\0" +"oguchi.aichi.jp\0" +"film\0" +"narita.chiba.jp\0us.gov.pl\0" +"wolterskluwer\0" +"mil.ac\0" +"mil.ae\0association.aero\0" +"pruszkow.pl\0" +"\xd0\xb4\xd0\xb5\xd1\x82\xd0\xb8\0" +"\xe7\xb6\xb2\xe8\xb7\xaf.tw\0" +"mil.al\0higashiizumo.shimane.jp\0run.app\0" +"trondheim.no\0" +"scjohnson\0solar\0" +"cam.it\0" +"mil.ba\0kviteseid.no\0" +"mil.ar\0js.cn\0" +"americanart.museum\0" +"med.sa\0" +"loft\0" +"med.sd\0" +"k12.ct.us\0" +"mil.az\0" +"sund.no\0" +"emiliaromagna.it\0yashiro.hyogo.jp\0kaizuka.osaka.jp\0skoczow.pl\0" +"alta.no\0" +"\xe5\xa5\x88\xe8\x89\xaf.jp\0" +"mil.bo\0" +"foz.br\0tomi.nagano.jp\0" +"guide\0" +"mil.br\0arezzo.it\0" +"minowa.nagano.jp\0" +"inf.mk\0" +"rr.leg.br\0" +"mosvik.no\0termez.su\0" +"best\0" +"mil.by\0" +"\xd9\x85\xd8\xb5\xd8\xb1\0" +"mil.cl\0\xd0\xbc\xd0\xbe\xd1\x81\xd0\xba\xd0\xb2\xd0\xb0\0" +"collection.museum\0fitjar.no\0" +"mil.cn\0" +"mil.co\0" +"ra.it\0" +"scapp.io\0" +"auto\0lima.zone\0" +"asso.fr\0" +"catering\0" +"mitsue.nara.jp\0kushimoto.wakayama.jp\0" +"seat\0" +"barclays\0" +"aq.it\0ba.it\0" +"egersund.no\0tokke.no\0" +"\xe0\xb9\x80\xe0\xb8\x99\xe0\xb9\x87\xe0\xb8\x95.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" +"k12.ak.us\0" +"mil.do\0pro\0cc.tx.us\0" +"bss.design\0" +"christiansburg.museum\0" +"asso.gp\0" +"mil.ec\0" +"sd.us\0pru\0s3-ap-south-1.amazonaws.com\0" +"rs.leg.br\0sc.leg.br\0" +"mil.eg\0" +"ena.gifu.jp\0" +"passenger-association.aero\0racing\0" +"shirako.chiba.jp\0" +"miyoshi.tokushima.jp\0" +"dance\0" +"sakyo.kyoto.jp\0nome.pt\0" +"\xd8\xa8\xd8\xa7\xd8\xb1\xd8\xaa\0" +"fire\0" +"asso.ht\0yoshida.saitama.jp\0hotmail\0servebbs.net\0" +"wa.gov.au\0" +"nuremberg.museum\0fam.pk\0" +"ingatlan.hu\0" +"aibetsu.hokkaido.jp\0" +"kumano.mie.jp\0am.leg.br\0" +"pub\0" +"cooperativa.bo\0" +"verona.it\0" +"mil.ge\0association.museum\0" +"niikappu.hokkaido.jp\0kawahara.tottori.jp\0" +"bmoattachments.org\0" +"mil.gh\0fish\0" +"s3-eu-west-2.amazonaws.com\0" +"asso.bj\0nagano.jp\0shinyoshitomi.fukuoka.jp\0starhub\0" +"kagoshima.jp\0" +"seek\0" +"mil.gt\0" +"vaapste.no\0" +"yakage.okayama.jp\0name.vn\0" +"eastafrica.museum\0averoy.no\0" +"asso.ci\0kv.ua\0" +"es.gov.br\0mil.hn\0" +"freeboxos.com\0" +"venice.it\0" +"pwc\0" +"mil.id\0" +"uda.nara.jp\0" +"cc.nj.us\0" +"kouzushima.tokyo.jp\0" +"web.bo\0meland.no\0" +"radom.pl\0" +"planetarium.museum\0fed.us\0" +"mil.in\0" +"steigen.no\0" +"mil.iq\0" +"yokaichiba.chiba.jp\0name.tj\0" +"web.co\0yolasite.com\0" +"inf.ua\0" +"asso.dz\0name.tr\0" +"name.tt\0faith\0" +"mil.jo\0nativeamerican.museum\0" +"wroc.pl\0" +"gildeskal.no\0" +"shichinohe.aomori.jp\0kanoya.kagoshima.jp\0privatizehealthinsurance.net\0" +"n.bg\0" +"kanegasaki.iwate.jp\0ogawara.miyagi.jp\0\xe0\xae\x87\xe0\xae\xa8\xe0\xaf\x8d\xe0\xae\xa4\xe0\xae\xbf\xe0\xae\xaf\xe0\xae\xbe\0" +"website\0dedyn.io\0ddnss.de\0" +"ruhr\0rn.leg.br\0" +"mil.kg\0" +"web.do\0hellas.museum\0fr\xc3\xb8ya.no\0" +"nakamichi.yamanashi.jp\0" +"dnsalias.org\0" +"kartuzy.pl\0" +"mil.km\0" +"kmpsp.gov.pl\0" +"pixolino.com\0telebit.io\0" +"barsy.site\0" +"matsuura.nagasaki.jp\0mil.kr\0" +"te.it\0" +"mil.kz\0" +"oirm.gov.pl\0" +"deporte.bo\0temasek\0barsy.pro\0" +"target\0wien\0" +"ap.leg.br\0" +"yamagata.yamagata.jp\0" +"moss.no\0" +"ama.shimane.jp\0mil.lv\0ro.leg.br\0" +"7.bg\0mil.mg\0jondal.no\0s3.dualstack.sa-east-1.amazonaws.com\0is-a-patsfan.org\0" +"turin.it\0dazaifu.fukuoka.jp\0miyada.nagano.jp\0" +"ternopil.ua\0" +"miyoshi.hiroshima.jp\0" +"tx.us\0marshalls\0" +"higashikawa.hokkaido.jp\0" +"eisenbahn.museum\0" +"horse\0" +"cloudfront.net\0" +"culturalcenter.museum\0" +"kawachinagano.osaka.jp\0" +"mil.mv\0gda.pl\0" +"mil.ng\0forde.no\0" +"mil.my\0mil.ni\0lillehammer.no\0" +"pn.it\0yamakita.kanagawa.jp\0nozawaonsen.nagano.jp\0mil.mz\0" +"name.qa\0" +"ntr.br\0tomigusuku.okinawa.jp\0name.pr\0" +"web.gu\0mil.no\0" +"barsy.pub\0" +"undersea.museum\0" +"fujisawa.iwate.jp\0" +"\xd0\xb0\xd0\xba.\xd1\x81\xd1\x80\xd0\xb1\0" +"fi.cr\0susono.shizuoka.jp\0" +"murata.miyagi.jp\0cloud.metacentrum.cz\0" +"voyage\0" +"bulsan-s\xc3\xbc""dtirol.it\0mil.nz\0" +"name.na\0nes.buskerud.no\0" +"shinjo.okayama.jp\0" +"whaling.museum\0podzone.org\0fr.eu.org\0" +"web.id\0aichi.jp\0health.nz\0" +"sunndal.no\0lancia\0s3-website-us-west-1.amazonaws.com\0" +"name.mv\0" +"name.ng\0" +"name.my\0vestby.no\0cc.de.us\0" +"azumino.nagano.jp\0nagasaki.nagasaki.jp\0" +"mil.pe\0" +"ostroleka.pl\0" +"*.landing.myjino.ru\0" +"munakata.fukuoka.jp\0mil.ph\0" +"revista.bo\0mining.museum\0" +"mil.pl\0" +"latrobe\0" +"katsuura.chiba.jp\0" +"engerdal.no\0lib.ny.us\0" +"wakayama.wakayama.jp\0" +"sandefjord.no\0mil.qa\0k12.ky.us\0" +"\xe5\x80\x8b\xe4\xba\xba.hk\0from-mn.com\0" +"entertainment.aero\0love\0" +"balsan-s\xc3\xbc""dtirol.it\0ina.ibaraki.jp\0okinoshima.shimane.jp\0" +"westfalen.museum\0stryn.no\0mil.py\0hosting\0" +"shisui.chiba.jp\0sowa.ibaraki.jp\0" +"tanagura.fukushima.jp\0nanbu.tottori.jp\0" +"gov.nc.tr\0" +"stockholm\0" +"kitami.hokkaido.jp\0lubartow.pl\0" +"r\xc3\xb8ros.no\0nj.us\0industries\0hobby-site.org\0" +"ru.com\0" +"ono.fukushima.jp\0" +"wiki\0georgia.su\0" +"bauern.museum\0taipei\0" +"lupin\0" +"gojome.akita.jp\0boehringer\0" +"pointto.us\0" +"\xd8\xa8\xd9\x8a\xd8\xaa\xd9\x83\0" +"web.lk\0name.mk\0mil.ru\0k12.il.us\0spacekit.io\0" +"mil.rw\0dyndns-blog.com\0" +"mil.sh\0" +"nordreisa.no\0" +"hichiso.gifu.jp\0shinjuku.tokyo.jp\0" +"bahn.museum\0ybo.science\0" +"trentinoaltoadige.it\0" +"minamiizu.shizuoka.jp\0" +"properties\0us.eu.org\0" +"mil.st\0" +"elburg.museum\0" +"at-band-camp.net\0" +"name.jo\0mil.sy\0" +"mil.tj\0" +"vi.it\0" +"mil.tm\0" +"on-web.fr\0" +"mil.to\0is-a-nurse.com\0" +"yonaguni.okinawa.jp\0web.nf\0" +"spjelkavik.no\0" +"mil.tr\0" +"web.ni\0" +"mitoyo.kagawa.jp\0yandex\0" +"j\xc3\xb8rpeland.no\0wine\0is-a-painter.com\0" +"fi.it\0" +"mil.tw\0" +"futaba.fukushima.jp\0mil.tz\0" +"saves-the-whales.com\0" +"yufu.oita.jp\0" +"mil.vc\0" +"mil.ve\0" +"ind.br\0" +"barsyonline.co.uk\0" +"mil.uy\0" +"\xe5\x8d\x83\xe8\x91\x89.jp\0kitahiroshima.hokkaido.jp\0" +"can.museum\0yorkshire.museum\0bjugn.no\0vm.bytemark.co.uk\0" +"sande.more-og-romsdal.no\0" +"akaiwa.okayama.jp\0" +"sejny.pl\0health.vn\0contact\0" +"te.ua\0" +"tv.bb\0red\0" +"web.pk\0\xd7\xa7\xd7\x95\xd7\x9d\0" +"\xe0\xb8\xa8\xe0\xb8\xb6\xe0\xb8\x81\xe0\xb8\xa9\xe0\xb8\xb2.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" +"asso.re\0" +"br.it\0cb.it\0shimoda.shizuoka.jp\0" +"archi\0" +"tanohata.iwate.jp\0" +"kamishihoro.hokkaido.jp\0diet\0ren\0cnpy.gdn\0" +"cc.vi.us\0" +"omotego.fukushima.jp\0" +"tv.bo\0sandcats.io\0" +"blockbuster\0" +"qvc\0from-tn.com\0" +"fnd.br\0tv.br\0rackmaze.net\0" +"mihara.hiroshima.jp\0azurewebsites.net\0" +"stada\0hu.com\0" +"mulhouse.museum\0school.museum\0" +"shimada.shizuoka.jp\0" +"pagespeedmobilizer.com\0" +"bedzin.pl\0" +"de.us\0" +"manx.museum\0" +"lease\0serveirc.com\0" +"se.leg.br\0" +"copenhagen.museum\0lanbib.se\0k12.ne.us\0" +"studio\0" +"friuliveneziagiulia.it\0ikeda.hokkaido.jp\0" +"notaires.km\0leka.no\0" +"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xdb\x8c\xd8\xa9\0*.advisor.ws\0" +"fukagawa.hokkaido.jp\0" +"hanggliding.aero\0s3.dualstack.ap-south-1.amazonaws.com\0" +"resistance.museum\0mil.za\0" +"yamagata.jp\0kamikawa.saitama.jp\0wielun.pl\0" +"beiarn.no\0is-into-cars.com\0" +"film.hu\0eu.com\0" +"for-the.biz\0" +"mil.zm\0*.vps.myjino.ru\0" +"morimachi.shizuoka.jp\0" +"maserati\0" +"nagareyama.chiba.jp\0web.tj\0" +"asso.nc\0" +"takehara.hiroshima.jp\0yamagata.nagano.jp\0" +"oppdal.no\0\xd8\xb3\xd9\x88\xd8\xb1\xd9\x8a\xd8\xa7\0mil.zw\0" +"ind.gt\0!city.yokohama.jp\0fujimino.saitama.jp\0" +"lib.nj.us\0\xd8\xb3\xd9\x88\xd8\xb1\xd9\x8a\xd8\xa9\0xs4all.space\0" +"gs.hm.no\0netbank\0wanggou\0de.com\0" +"web.tr\0ril\0" +"leasing.aero\0sexy\0" +"hirono.iwate.jp\0debian.net\0" +"jobs\0rio\0" +"rip\0" +"n.se\0" +"ggf.br\0urayasu.chiba.jp\0" +"barsy.org\0" +"cc.ok.us\0is-leet.com\0dsmynas.org\0" +"ochi.kochi.jp\0satte.saitama.jp\0" +"m\xc3\xa5lselv.no\0is-a-teacher.com\0synology.me\0" +"zarow.pl\0" +"firewall-gateway.com\0" +"okawa.kochi.jp\0" +"web.ve\0latino\0" +"kusatsu.gunma.jp\0saikai.nagasaki.jp\0" +"ind.in\0" +"corsica\0" +"oster\xc3\xb8y.no\0" +"pub.sa\0" +"\xe9\x95\xb7\xe9\x87\x8e.jp\0niigata.niigata.jp\0nago.okinawa.jp\0" +"est-a-la-maison.com\0" +"namdalseid.no\0" +"nishikata.tochigi.jp\0" +"kumamoto.jp\0ustka.pl\0" +"tuva.su\0" +"accident-prevention.aero\0" +"roma.it\0mombetsu.hokkaido.jp\0" +"odda.no\0barsy.co.uk\0" +"\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa5\x8b\xe0\xa4\xa4\0" +"oita.jp\0moonscale.net\0" +"gotdns.org\0" +"higashimurayama.tokyo.jp\0" +"tv.im\0publishproxy.com\0" +"shimogo.fukushima.jp\0sanok.pl\0" +"!www.ck\0sport.hu\0" +"catholic\0" +"tv.it\0" +"eco.br\0" +"ind.kw\0transport.museum\0homesense\0" +"soni.nara.jp\0" +"hinohara.tokyo.jp\0" +"nombre.bo\0versailles.museum\0" +"vi.us\0web.za\0" +"now-dns.net\0" +"is-very-bad.org\0" +"otoineppu.hokkaido.jp\0freesite.host\0" +"asso.km\0gallery.museum\0rahkkeravju.no\0" +"posts-and-telecommunications.museum\0station.museum\0community\0" +"minamiuonuma.niigata.jp\0" +"hirosaki.aomori.jp\0" +"dating\0" +"horten.no\0endoftheinternet.org\0" +"ethnology.museum\0giske.no\0charity\0" +"sb.ua\0k12.pa.us\0" +"cyou\0" +"lubin.pl\0" +"tachiarai.fukuoka.jp\0" +"tj\xc3\xb8me.no\0" +"ao.it\0" +"asso.mc\0ontario.museum\0chernovtsy.ua\0lib.ca.us\0" +"mus.br\0" +"hm.no\0" +"dellogliastra.it\0yoita.niigata.jp\0kainan.tokushima.jp\0" +"myshopblocks.com\0" +"from-in.com\0" +"dscloud.biz\0" +"mo-i-rana.no\0" +"tv.na\0" +"author.aero\0nesoddtangen.no\0" +"showa.fukushima.jp\0" +"folkebibl.no\0athleta\0" +"nagatoro.saitama.jp\0" +"bokn.no\0" +"moka.tochigi.jp\0nogi.tochigi.jp\0" +"mesaverde.museum\0technology.museum\0" +"kamisu.ibaraki.jp\0" +"sap\0" +"k12.md.us\0" +"hikari.yamaguchi.jp\0\xe0\xa4\xb8\xe0\xa4\x82\xe0\xa4\x97\xe0\xa4\xa0\xe0\xa4\xa8\0" +"casadelamoneda.museum\0sas\0shopping\0" +"jus.br\0" +"groundhandling.aero\0" +"wedding\0" +"urbinopesaro.it\0podlasie.pl\0maif\0" +"konyvelo.hu\0sbi\0adygeya.su\0" +"morotsuka.miyazaki.jp\0" +"naha.okinawa.jp\0" +"aver\xc3\xb8y.no\0sca\0" +"rokunohe.aomori.jp\0dish\0scb\0" +"ok.us\0sbs\0" +"\xc3\xa5mot.no\0flora.no\0" +"sondrio.it\0takahata.yamagata.jp\0" +"royken.no\0" +"salangen.no\0" +"oirase.aomori.jp\0" +"pescara.it\0kuchinotsu.nagasaki.jp\0" +"shiraoi.hokkaido.jp\0vision\0" +"tottori.jp\0onojo.fukuoka.jp\0" +"maritimo.museum\0\xc3\xb8ksnes.no\0" +"iida.nagano.jp\0" +"yabuki.fukushima.jp\0" +"gub.uy\0" +"res.in\0" +"h\xc3\xb8nefoss.no\0" +"cc.nh.us\0" +"susaki.kochi.jp\0" +"haram.no\0" +"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xdb\x8c\xdb\x83\0" +"adygeya.ru\0" +"bhz.br\0iwanai.hokkaido.jp\0" +"mx.na\0gs.jan-mayen.no\0" +"run\0" +"culture.museum\0" +"ind.tn\0" +"ses\0" +"bandai.fukushima.jp\0etajima.hiroshima.jp\0" +"campinagrande.br\0tv.sd\0" +"lib.id.us\0sew\0" +"sex\0" +"fhsk.se\0" +"tranoy.no\0" +"kakuda.miyagi.jp\0" +"l.bg\0" +"walbrzych.pl\0" +"\xe7\xb6\xb2\xe7\xbb\x9c.hk\0" +"sfr\0" +"rwe\0" +"salzburg.museum\0" +"press.aero\0railway.museum\0net-freaks.com\0" +"yn.cn\0" +"dynns.com\0" +"ss.it\0hachirogata.akita.jp\0" +"tv.tr\0redirectme.net\0" +"shingu.wakayama.jp\0" +"bungoono.oita.jp\0" +"servebbs.org\0" +"cs.it\0mediocampidano.it\0esashi.hokkaido.jp\0cloudapp.net\0" +"s3.eu-west-2.amazonaws.com\0" +"kahoku.yamagata.jp\0tv.tz\0" +"fhapp.xyz\0" +"kihoku.ehime.jp\0" +"5.bg\0" +"press.cy\0" +"koga.ibaraki.jp\0hakusan.ishikawa.jp\0" +"saskatchewan.museum\0" +"trogstad.no\0" +"hakone.kanagawa.jp\0" +"xenapponazure.com\0" +"bytom.pl\0" +"analytics\0" +"toyama.jp\0" +"\xe4\xbf\xa1\xe6\x81\xaf\0" +"kristiansund.no\0" +"aquarelle\0mango\0is-a-photographer.com\0" +"minamidaito.okinawa.jp\0" +"\xe7\xa5\x9e\xe5\xa5\x88\xe5\xb7\x9d.jp\0chuo.yamanashi.jp\0" +"leikanger.no\0" +"lib.ar.us\0" +"za.net\0" +"ambulance.aero\0ski\0" +"voagat.no\0" +"namegawa.saitama.jp\0" +"cc.dc.us\0" +"*.quipelements.com\0" +"flir\0" +"nagasaki.jp\0" +"wakkanai.hokkaido.jp\0" +"lu.it\0me.it\0*.telebit.xyz\0" +"lib.ok.us\0sky\0" +"v\xc3\xa5ler.\xc3\xb8stfold.no\0" +"himeji.hyogo.jp\0alwaysdata.net\0" +"science.museum\0" +"higashiura.aichi.jp\0" +"hadano.kanagawa.jp\0" +"me.ke\0" +"dyndns.info\0dnsiskinky.com\0" +"gunma.jp\0" +"nh.us\0" +"ikeda.fukui.jp\0" +"googleapis.com\0" +"farsund.no\0" +"okoppe.hokkaido.jp\0publ.pt\0" +"paderborn.museum\0dyndns-server.com\0" +"*.sapporo.jp\0shibata.niigata.jp\0" +"halloffame.museum\0" +"farmers\0" +"eidsberg.no\0doomdns.org\0" +"asahi.mie.jp\0" +"neat-url.com\0" +"oceanographique.museum\0" +"shinkamigoto.nagasaki.jp\0" +"friuliv-giulia.it\0kanra.gunma.jp\0" +"cc.me.us\0""2038.io\0" +"lillesand.no\0es.eu.org\0" +"url.tw\0" +"evenassi.no\0" +"utashinai.hokkaido.jp\0" +"ravendb.me\0" +"tromso.no\0lib.wy.us\0" +"soy\0" +"beauxarts.museum\0bounty-full.com\0" +"uzs.gov.pl\0" +"kvam.no\0giehtavuoatna.no\0" +"fg.it\0familyds.net\0" +"alaska.museum\0lib.hi.us\0s3.us-east-2.amazonaws.com\0" +"tab\0" +"naturhistorisches.museum\0hjartdal.no\0" +"ora.gunma.jp\0" +"oumu.hokkaido.jp\0" +"paragliding.aero\0halden.no\0" +"badajoz.museum\0" +"cc.in.us\0" +"modelling.aero\0mc.eu.org\0" +"ishikawa.okinawa.jp\0" +"www.ro\0" +"niihama.ehime.jp\0" +"kautokeino.no\0" +"tax\0" +"in.na\0" +"shaw\0est-mon-blogueur.com\0from-ky.com\0" +"daiwa.hiroshima.jp\0rzeszow.pl\0srl\0" +"eidsvoll.no\0ryukyu\0" +"taku.saga.jp\0" +"family.museum\0bargains\0" +"hk.cn\0notaires.fr\0bolzano-altoadige.it\0isesaki.gunma.jp\0" +"in.ni\0" +"kurume.fukuoka.jp\0" +"chattanooga.museum\0lodingen.no\0" +"przeworsk.pl\0srt\0" +"ed.ao\0from-mi.com\0" +"greta.fr\0amami.kagoshima.jp\0chuo.tokyo.jp\0yonago.tottori.jp\0" +"rnu.tn\0cdn77-ssl.net\0" +"tci\0" +"kitaaiki.nagano.jp\0" +"app.os.fedoraproject.org\0" +"miyama.mie.jp\0" +"theater.museum\0" +"katashina.gunma.jp\0" +"tsuno.miyazaki.jp\0fujiidera.osaka.jp\0" +"stc\0lt.eu.org\0" +"takasago.hyogo.jp\0" +"ponpes.id\0ham-radio-op.net\0" +"sells-for-u.com\0ownprovider.com\0" +"dc.us\0duckdns.org\0" +"mormon\0" +"nikolaev.ua\0tdk\0" +"usuki.oita.jp\0" +"apartments\0" +"ed.ci\0" +"ce.leg.br\0" +"oystre-slidre.no\0pl.ua\0k12.ms.us\0k12.nc.us\0softbank\0" +"ikeda.gifu.jp\0" +"flight.aero\0k12.ec\0\xc3\xb8rskog.no\0" +"ed.cr\0fujimi.nagano.jp\0" +"nagoya\0" +"kui.hiroshima.jp\0" +"pvt.ge\0" +"g12.br\0tel\0" +"khmelnitskiy.ua\0" +"kamiizumi.saitama.jp\0" +"s3-us-east-2.amazonaws.com\0" +"futbol\0" +"v\xc3\xa5gs\xc3\xb8y.no\0valer.ostfold.no\0" +"osaka.jp\0hidaka.wakayama.jp\0mail.pl\0podhale.pl\0" +"ddns.me\0" +"goto.nagasaki.jp\0" +"cincinnati.museum\0myddns.rocks\0" +"minobu.yamanashi.jp\0" +"am.br\0" +"amsterdam.museum\0" +"trentino-s-tirol.it\0" +"4u.com\0" +"kr.it\0" +"graz.museum\0" +"yoro.gifu.jp\0" +"cruise\0teaches-yoga.com\0" +"minakami.gunma.jp\0" +"orkdal.no\0" +"imperia.it\0" +"*.awdev.ca\0" +"in.rs\0l.se\0dubai\0" +"aosta.it\0" +"alstom\0is-a-cubicle-slave.com\0" +"me.tz\0" +"me.uk\0" +"cc.ny.us\0" +, + +"ichikawa.hyogo.jp\0" +"\xe3\x83\x95\xe3\x82\xa1\xe3\x83\x83\xe3\x82\xb7\xe3\x83\xa7\xe3\x83\xb3\0" +"thd\0" +"nf.ca\0" +"me.us\0" +"pup.gov.pl\0" +"klepp.no\0bike\0mydatto.com\0" +"trentino-a-adige.it\0" +"sandvik\0" +"from-ri.com\0" +"*.kawasaki.jp\0nakama.fukuoka.jp\0in.th\0" +"i234.me\0" +"toyotsu.fukuoka.jp\0" +"broadcast.museum\0" +"shia\0" +"kouyama.kagoshima.jp\0" +"coldwar.museum\0in.ua\0" +"gov.ac\0v\xc3\xa5g\xc3\xa5.no\0" +"aga.niigata.jp\0" +"gov.ae\0kvinesdal.no\0" +"gov.af\0k12.il\0" +"jprs\0eu-west-3.elasticbeanstalk.com\0" +"sells-it.net\0" +"hitra.no\0s3-website-ap-southeast-2.amazonaws.com\0*.otap.co\0from-wy.com\0net.eu.org\0""4lima.de\0" +"gov.al\0" +"landes.museum\0" +"chijiwa.nagasaki.jp\0" +"gov.ba\0tt.im\0beeldengeluid.museum\0" +"gov.ar\0gov.bb\0edogawa.tokyo.jp\0" +"gov.as\0in.us\0" +"s3.cn-north-1.amazonaws.com.cn\0" +"gov.au\0" +"gov.bf\0" +"gov.bh\0ud.it\0" +"gov.az\0kiyosu.aichi.jp\0" +"gov.bm\0" +"gov.bn\0miyashiro.saitama.jp\0" +"jerusalem.museum\0sydney\0servehalflife.com\0" +"tjx\0yamaxun\0" +"gov.br\0emr.it\0" +"gov.bs\0bing\0" +"gov.bt\0gov.cd\0fukuchiyama.kyoto.jp\0" +"cn.com\0fi.eu.org\0" +"press.se\0house\0" +"gov.by\0cpa.pro\0s3.ca-central-1.amazonaws.com\0from-wi.com\0" +"gov.bz\0florence.it\0""4lima.at\0" +"viking.museum\0" +"gov.cl\0forl\xc3\xac-cesena.it\0kagami.kochi.jp\0" +"gov.cm\0isleofman.museum\0rentals\0" +"gov.cn\0ed.jp\0" +"gov.co\0" +"chtr.k12.ma.us\0" +"\xe6\x96\xb0\xe5\x8a\xa0\xe5\x9d\xa1\0" +"gov.cu\0" +"gov.cx\0perso.ht\0" +"gov.cy\0pilots.museum\0hughes\0" +"dyndns-at-work.com\0" +"gov.dm\0lib.sc.us\0flowers\0" +"bielawa.pl\0""4lima.ch\0" +"gov.do\0" +"gov.ec\0" +"gov.ee\0bern.museum\0sk\xc3\xa1nit.no\0" +"kyonan.chiba.jp\0" +"gov.eg\0" +"h\xc3\xb8yanger.no\0" +"gov.dz\0tamatsukuri.ibaraki.jp\0" +"asnes.no\0molde.no\0" +"dsmynas.net\0" +"phone\0" +"salvadordali.museum\0" +"gov.et\0sakuragawa.ibaraki.jp\0fukudomi.saga.jp\0" +"kr\xc3\xb8""dsherad.no\0" +"pippu.hokkaido.jp\0" +"mima.tokushima.jp\0ube.yamaguchi.jp\0" +"firebaseapp.com\0barsy.menu\0" +"basilicata.it\0" +"government.aero\0" +"gov.ge\0" +"cq.cn\0naples.it\0toyo.kochi.jp\0" +"oz.au\0" +"gov.gh\0top\0" +"express.aero\0gov.gi\0force.museum\0" +"aostavalley.it\0gyeonggi.kr\0" +"shop\0" +"fujitsu\0recipes\0" +"gov.gn\0kashiwazaki.niigata.jp\0" +"buzen.fukuoka.jp\0" +"gov.gr\0" +"fresenius\0show\0" +"gov.gu\0ny.us\0" +"*.statics.cloud\0" +"isteingeek.de\0" +"caxias.br\0suzaka.nagano.jp\0" +"gov.gy\0" +"shirakawa.fukushima.jp\0" +"gov.hk\0habmer.no\0" +"otama.fukushima.jp\0koryo.nara.jp\0kumatori.osaka.jp\0" +"\xe0\xb0\xad\xe0\xb0\xbe\xe0\xb0\xb0\xe0\xb0\xa4\xe0\xb1\x8d\0" +"press.ma\0" +"gov.ie\0lib.la.us\0" +"kr.ua\0k12.ia.us\0" +"eidskog.no\0" +"\xe4\xbc\x81\xe4\xb8\x9a\0" +"mk.eu.org\0" +"gov.il\0kizu.kyoto.jp\0" +"gov.in\0mito.ibaraki.jp\0kita.osaka.jp\0\xe6\x94\xbf\xe5\xba\x9c\0blogsite.xyz\0" +"m\xc3\xa1latvuopmi.no\0beta.bounty-full.com\0" +"kamagaya.chiba.jp\0aso.kumamoto.jp\0" "gov.iq\0" -"gov.ir\0ise.mie.jp\0" +"the.br\0gov.ir\0kaneyama.fukushima.jp\0" "gov.is\0" "gov.it\0" -"otaru.hokkaido.jp\0" -"kim\0" -"sklep.pl\0szkola.pl\0" -"gov.jo\0gifu.jp\0" -"farmers.museum\0" -"kadoma.osaka.jp\0" -"semine.miyagi.jp\0" -"akiruno.tokyo.jp\0eating-organic.net\0" -"glade\0" -"anjo.aichi.jp\0" -"piacenza.it\0gov.kg\0cable-modem.org\0" -"kiso.nagano.jp\0" +"ed.pw\0" +"kasuya.fukuoka.jp\0" +"lugs.org.uk\0now-dns.org\0" +"matsuyama.ehime.jp\0" +"doshi.yamanashi.jp\0" +"tran\xc3\xb8y.no\0ubs\0navoi.su\0" +"trv\0" +"gov.jo\0" +"k12.ut.us\0" +"feste-ip.net\0" +"gov.kg\0" +"vicenza.it\0uconnect\0" "gov.ki\0" -"pi.leg.br\0barsy.in\0" -"barsy.io\0" -"gov.km\0" +"from-hi.com\0" +"tas.edu.au\0gov.km\0aquarium.museum\0" "gov.kn\0" -"yaita.tochigi.jp\0tokushima.tokushima.jp\0gov.kp\0jan-mayen.no\0ap-northeast-1.elasticbeanstalk.com\0mytuleap.com\0" +"j.bg\0" +"hayashima.okayama.jp\0gov.kp\0" "gov.la\0" "gov.lb\0" -"gov.lc\0" -"\xe5\xb2\xa9\xe6\x89\x8b.jp\0landes.museum\0" -"tourism.tn\0" -"gov.kw\0" -"v-info.info\0" -"maizuru.kyoto.jp\0gov.ky\0" -"gov.kz\0" +"gov.lc\0g\xc3\xa1ls\xc3\xa1.no\0" +"cloudns.pro\0" +"gov.kw\0center.museum\0photo\0" +"gov.ky\0stokke.no\0vladikavkaz.ru\0" +"iwade.wakayama.jp\0gov.kz\0" "gov.lk\0" -"barrel-of-knowledge.info\0" -"rest\0" -"gov.ma\0" -"gov.lr\0finn\xc3\xb8y.no\0" -"gov.lt\0baidu\0" -"gov.me\0" -"gov.lv\0tana.no\0" -"gov.mg\0" -"judaica.museum\0" -"gov.ly\0" -"gov.mk\0" -"gov.ml\0" -"gov.mn\0" -"gov.mo\0" -"ski.museum\0" -"politica.bo\0tagami.niigata.jp\0" +"ma.gov.br\0k12.tr\0" +"volyn.ua\0rugby\0" +"schwarz\0" +"gov.ma\0tui\0" +"ta.it\0yamagata.gifu.jp\0gov.lr\0" +"gov.ls\0\xc3\xa5rdal.no\0" +"gov.lt\0" +"gov.me\0palace.museum\0" +"gov.lv\0" +"gov.mg\0orskog.no\0" +"gov.ly\0for-our.info\0vladikavkaz.su\0" +"gov.mk\0lu.eu.org\0me.eu.org\0servemp3.com\0" +"hiranai.aomori.jp\0gov.ml\0" +"plo.ps\0" +"kisofukushima.nagano.jp\0gov.mn\0" +"gov.mo\0us-gov-west-1.elasticbeanstalk.com\0" +"uchihara.ibaraki.jp\0" "gov.mr\0" -"gov.ms\0" -"ascolipiceno.it\0" -"ujiie.tochigi.jp\0gov.mu\0" +"3.bg\0gov.ms\0lund.no\0k12.vi\0" +"friulivenezia-giulia.it\0" +"gov.mu\0" "gov.mv\0" -"force.museum\0gov.mw\0gov.ng\0" -"ogata.akita.jp\0" -"gov.my\0" -"gov.mz\0\xd0\xbe\xd1\x80\xd0\xb3\0" -"sassari.it\0" -"off.ai\0pueblo.bo\0dnsiskinky.com\0" -"\xd1\x83\xd0\xbf\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0" -"hellas.museum\0virtual.museum\0" -"york.museum\0gov.nr\0" -"s3-ap-northeast-1.amazonaws.com\0redirectme.net\0" -"amfam\0" -"toyama.jp\0" -"baidar.no\0roan.no\0doomdns.com\0" -"broadway\0" -"aomori.jp\0" -"carraramassa.it\0" -"building.museum\0" -"gov.om\0" -"kumejima.okinawa.jp\0" -"dolls.museum\0" -"yamagata.yamagata.jp\0evenes.no\0" -"k12.al.us\0" -"pe.gov.br\0minami-alps.yamanashi.jp\0" -"gov.ph\0" -"shimada.shizuoka.jp\0nachikatsuura.wakayama.jp\0interactive.museum\0" -"kamifurano.hokkaido.jp\0" -"gov.pk\0coupons\0report\0" -"gov.pl\0k12.mo.us\0exchange\0" -"tysvar.no\0gov.pn\0" -"frontier\0" -"gov.qa\0" -"misaki.okayama.jp\0gov.pr\0mlbfan.org\0" -"shop.ht\0kvinesdal.no\0gov.ps\0" -"k.bg\0shop.hu\0gov.pt\0fh.se\0" -"tsukuba.ibaraki.jp\0lier.no\0" -"brussel.museum\0" -"\xe5\xa4\xa7\xe5\x88\x86.jp\0kpn\0" -"gov.py\0" -"lutsk.ua\0" -"*.uberspace.de\0" -"barsycenter.com\0" -"mukawa.hokkaido.jp\0stalbans.museum\0" -"okinoshima.shimane.jp\0" -"kawakita.ishikawa.jp\0" -"udi.br\0" -"gwiddle.co.uk\0" -"krd\0lat\0" -"barsy.online\0" -"hasama.oita.jp\0koebenhavn.museum\0" -"higashiosaka.osaka.jp\0gov.sa\0law\0" -"gov.sb\0my.eu.org\0" -"sanjo.niigata.jp\0gov.rs\0gov.sc\0" -"susaki.kochi.jp\0porsanger.no\0gov.sd\0" -"aga.niigata.jp\0gov.ru\0" -"obira.hokkaido.jp\0" -"gov.rw\0gov.sg\0" +"chiropractic.museum\0gov.mw\0gov.ng\0j\xc3\xb8lster.no\0is-slick.com\0" +"gsm.pl\0" +"midatlantic.museum\0gov.my\0is-a-bulls-fan.com\0" +"gov.mz\0durban\0" +"tvs\0" +"valled-aosta.it\0" +"santabarbara.museum\0naustdal.no\0za.org\0" +"mizuho.tokyo.jp\0" +"nov.ru\0" +"brand.se\0" +"gov.nr\0" +"columbia.museum\0" +"kamoenai.hokkaido.jp\0" +"konskowola.pl\0" +"progressive\0" +"hokksund.no\0lv.eu.org\0" +"nakamura.kochi.jp\0" +"soc.lk\0gov.om\0" +"tondabayashi.osaka.jp\0" +"nov.su\0*.spectrum.myjino.ru\0" +"laz.it\0host\0" +"b\xc3\xa1hccavuotna.no\0helsinki\0homelinux.com\0" +"tmp.br\0siracusa.it\0vibovalentia.it\0" +"skjervoy.no\0" +"togura.nagano.jp\0" +"gov.ph\0go.leg.br\0" +"\xc3\xb8vre-eiker.no\0" +"ullensaker.no\0gov.pk\0" +"otake.hiroshima.jp\0gov.pl\0" +"bolzano.it\0fukuroi.shizuoka.jp\0gov.pn\0" +"exchange\0" +"futtsu.chiba.jp\0" +"gs.oslo.no\0gov.qa\0" +"kimobetsu.hokkaido.jp\0gov.pr\0merckmsd\0" +"gov.ps\0" +"gov.pt\0" +"sauda.no\0cherkasy.ua\0" +"from-la.net\0" +"bruxelles.museum\0gov.py\0" +"mc.it\0iwate.iwate.jp\0ota.tokyo.jp\0" +"og.ao\0bajddar.no\0e12.ve\0leadpages.co\0" +"tagajo.miyagi.jp\0" +"aoki.nagano.jp\0leczna.pl\0" +"webhop.info\0" +"latina.it\0virtueeldomein.nl\0" +"tobishima.aichi.jp\0" +"pasadena.museum\0" +"contagem.br\0chosei.chiba.jp\0" +"homesecuritymac.com\0diskstation.org\0" +"naval.museum\0" +"fujinomiya.shizuoka.jp\0tkmaxx\0" +"holt\xc3\xa5len.no\0gov.sa\0" +"gov.sb\0kicks-ass.net\0" +"paris.museum\0gov.rs\0gov.sc\0" +"trentino-suedtirol.it\0itano.tokushima.jp\0obanazawa.yamagata.jp\0gov.sd\0" +"frankfurt.museum\0gov.ru\0" +"\xd8\xa7\xd9\x84\xd9\x8a\xd9\x85\xd9\x86\0" +"gov.rw\0gov.sg\0health-carereform.com\0" "gov.sh\0" -"pe.leg.br\0" -"aichi.jp\0te.ua\0" -"gov.sl\0" -"okinawa.okinawa.jp\0coach\0" -"tjeldsund.no\0" -"shoo.okayama.jp\0" +"assisi.museum\0cadaques.museum\0herokuapp.com\0" +"kamisunagawa.hokkaido.jp\0" +"kota.aichi.jp\0gov.sl\0" +"supplies\0" +"noboribetsu.hokkaido.jp\0" +"*.uberspace.de\0" "gov.st\0" -"valle\xcc\x81""eaoste.it\0" +"!city.sapporo.jp\0" +"yalta.ua\0silk\0" "gov.sx\0" "gov.sy\0" "gov.tj\0" -"gov.tl\0" -"laspezia.it\0kragero.no\0gov.tm\0" +"ltda\0" +"ichinohe.iwate.jp\0gov.tl\0" +"oppeg\xc3\xa5rd.no\0gov.tm\0" "gov.tn\0" "gov.to\0" -"gov.ua\0" -"gov.tr\0" -"k12.fl.us\0" -"davvenj\xc3\xa1rga.no\0konskowola.pl\0gov.tt\0" -"fukushima.hokkaido.jp\0boomla.net\0" -"her\xc3\xb8y.nordland.no\0" +"kamo.kyoto.jp\0wodzislaw.pl\0" +"volkenkunde.museum\0gov.ua\0" +"honjo.akita.jp\0kamiamakusa.kumamoto.jp\0gov.tr\0" +"gov.tt\0" +"skanit.no\0" +"kisarazu.chiba.jp\0ono.hyogo.jp\0" "gov.tw\0" -"mywire.org\0" -"is-a-candidate.org\0" -"boehringer\0" -"uto.kumamoto.jp\0gov.uk\0" -"ena.gifu.jp\0pa.gov.pl\0lds\0" -"kv\xc3\xa6nangen.no\0" -"kvafjord.no\0gov.vc\0visa\0" -"loginto.me\0" -"gov.ve\0" -"zoological.museum\0" -"trentin-sud-tirol.it\0sandoy.no\0panasonic\0" -"salat.no\0futuremailing.at\0" -"gov.vn\0" -"bardu.no\0" -"scjohnson\0" -"inabe.mie.jp\0aigo\0" -"ibaraki.jp\0" -"ns.ca\0" -"land\0" -"mandal.no\0now-dns.org\0" -"bokn.no\0" -"\xe7\xa7\xbb\xe5\x8a\xa8\0s3-website-sa-east-1.amazonaws.com\0" -"fukumitsu.toyama.jp\0stada\0" -"recht.pro\0" -"asahi.chiba.jp\0" -"vibo-valentia.it\0" -"kh.ua\0" -"nasu.tochigi.jp\0leka.no\0sorfold.no\0gov.ws\0yombo.me\0" -"tourism.pl\0" -"h\xc3\xa1""bmer.no\0onion\0" -"abbvie\0" -"yamaxun\0" -"tra.kp\0gs.aa.no\0net-freaks.com\0" -"kujukuri.chiba.jp\0fukagawa.hokkaido.jp\0" -"nl.eu.org\0" -"takaharu.miyazaki.jp\0viva\0" -"mydatto.com\0" -"is.it\0lifestyle\0" -"yamanakako.yamanashi.jp\0" -"itano.tokushima.jp\0" -"cc.in.us\0" -"zgorzelec.pl\0" -"br.com\0" -"far.br\0lib.ee\0notodden.no\0" -"gov.za\0vivo\0" -"act.au\0pr.gov.br\0nanbu.tottori.jp\0" -"moseushi.hokkaido.jp\0" -"padua.it\0susono.shizuoka.jp\0" -"ciscofreak.com\0" -"karm\xc3\xb8y.no\0" -"vang.no\0" -"haibara.shizuoka.jp\0" -"gov.zm\0lotte\0" -"kiho.mie.jp\0valley.museum\0" -"cambridge.museum\0" -"mol.it\0vagan.no\0glass\0" -"info.gu\0" -"takayama.nagano.jp\0" -"ox.rs\0" -"gov.zw\0lotto\0" -"zlg.br\0bungotakada.oita.jp\0" -"dabur\0kyoto\0" -"hawaii.museum\0" -"ninohe.iwate.jp\0" -"info.ht\0" -"info.hu\0" -"makinohara.shizuoka.jp\0" -"dazaifu.fukuoka.jp\0" -"bellevue.museum\0nativeamerican.museum\0theater\0" -"llc\0" -"k12.md.us\0courses\0" -"tas.gov.au\0shiki.saitama.jp\0eu.meteorapp.com\0" -"educator.aero\0" -"info.et\0sakura\0" -"egersund.no\0homelinux.org\0js.org\0" -"is-a-techie.com\0pr.leg.br\0" -"mobile\0" -"field.museum\0hamaroy.no\0" -"production.aero\0takamatsu.kagawa.jp\0wallonie.museum\0philips\0" -"ostroda.pl\0tgory.pl\0" -"\xd0\xb8\xd0\xba\xd0\xbe\xd0\xbc.museum\0" -"basketball\0" -"emb.kw\0" -"idf.il\0securitytactics.com\0" -"manaus.br\0hof.no\0" -"austrheim.no\0" -"kred\0" -"noheji.aomori.jp\0my-vigor.de\0" -"firenze.it\0" -"dnsdojo.com\0" -"giehtavuoatna.no\0" -"inder\xc3\xb8y.no\0" -"mobily\0" -"tiaa\0" -"azumino.nagano.jp\0nesset.no\0" -"ng.eu.org\0dsmynas.net\0" -"hn.cn\0\xe0\xac\xad\xe0\xac\xbe\xe0\xac\xb0\xe0\xac\xa4\0" -"\xe7\xa6\x8f\xe4\xba\x95.jp\0kashiwazaki.niigata.jp\0" -"no-ip.ca\0" -"info.cx\0" -"hakata.fukuoka.jp\0" -"m\xc3\xa5s\xc3\xb8y.no\0lib.nj.us\0" -"trentinosu\xcc\x88""d-tirol.it\0" -"info.ec\0higashimurayama.tokyo.jp\0stateofdelaware.museum\0" -"yachiyo.ibaraki.jp\0" -"tamakawa.fukushima.jp\0" -"parma.it\0firewall-gateway.com\0" -"psc.br\0lol\0" -"cn.it\0" -"cloud\0servemp3.com\0" -"\xe7\xbb\x84\xe7\xbb\x87\xe6\x9c\xba\xe6\x9e\x84\0" -"nsn.us\0azure-mobile.net\0" -"aurskog-holand.no\0" -"eniwa.hokkaido.jp\0" -"info.bb\0parti.se\0" -"info.at\0" -"info.au\0gs.vf.no\0" -"bari.it\0k12.de.us\0" -"lpl\0" -"palermo.it\0farmstead.museum\0" -"info.az\0familyds.org\0" -"engerdal.no\0" -"info.bo\0inf.br\0" -"\xd8\xb9\xd8\xb1\xd8\xa8\0" -"nakadomari.aomori.jp\0" -"minamiechizen.fukui.jp\0k.se\0" -"lib.or.us\0" -"north.museum\0rahkkeravju.no\0" -"mallorca.museum\0" -"man\0" -"chonan.chiba.jp\0bo.nordland.no\0" -"hayashima.okayama.jp\0map\0paris.eu.org\0" -"lavagis.no\0\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\x82\xe0\xa6\xb2\xe0\xa6\xbe\0mba\0" -"bifuka.hokkaido.jp\0" -"info.co\0meiwa.mie.jp\0" -"b\xc3\xa1id\xc3\xa1r.no\0" -"inf.cu\0" -"ozu.ehime.jp\0storage\0from-oh.com\0" -"tx.us\0" -"lima-city.rocks\0" -"nagasu.kumamoto.jp\0" -"ss.it\0" -"okawa.kochi.jp\0" -"trapani.it\0" -"izumi.kagoshima.jp\0svelvik.no\0" -"rightathome\0" -"storfjord.no\0" -"tajimi.gifu.jp\0" -"otari.nagano.jp\0ltd\0" -"lubin.pl\0" -"yahaba.iwate.jp\0uzhgorod.ua\0" -"davvenjarga.no\0" -"engine.aero\0" -"is-a-caterer.com\0" -"huissier-justice.fr\0fjaler.no\0" -"kasumigaura.ibaraki.jp\0" -"cc.hi.us\0" -"reggiocalabria.it\0med\0" -"shimonoseki.yamaguchi.jp\0" -"rygge.no\0" -"press.cy\0static-access.net\0" -"from-md.com\0" -"mantova.it\0" -"men\0" -"l\xc3\xb8""dingen.no\0" -"lib.ga.us\0" -"valle\xcc\x81""e-aoste.it\0childrens.museum\0" -"uozu.toyama.jp\0" -"matsumoto.nagano.jp\0oita.oita.jp\0" -"shop.ro\0" -"dyndns-home.com\0" -"balsan-suedtirol.it\0hyundai\0" -"k12.vt.us\0" -"natuurwetenschappen.museum\0" -"kvits\xc3\xb8y.no\0" -"sekikawa.niigata.jp\0piw.gov.pl\0" -"stockholm\0tkmaxx\0" -"santacruz.museum\0" -"realestate\0dd-dns.de\0" -"\xe7\xb6\xb2\xe7\xbb\x9c.hk\0" -"sdn.gov.pl\0" -"nowaruda.pl\0nat.tn\0cartier\0mangyshlak.su\0" -"shop.pl\0" -"emergency.aero\0" -"shonai.yamagata.jp\0" -"sakai.ibaraki.jp\0" -"shangrila\0" -"development.run\0" -"office-on-the.net\0" -"tenkawa.nara.jp\0" -"sweetpepper.org\0" -"yomitan.okinawa.jp\0bus.museum\0philadelphiaarea.museum\0po.gov.pl\0" -"\xe5\xb1\xb1\xe5\x8f\xa3.jp\0bamble.no\0" -"from-ca.com\0" -"friuli-vegiulia.it\0" -"tv.bb\0" -"aquila.it\0" -"art.br\0mil\0" -"mn.it\0" -"ponpes.id\0" -"mit\0fastpanel.direct\0" -"cc.mi.us\0vlaanderen\0" -"tv.bo\0gold\0" -"is-a-hard-worker.com\0pantheonsite.io\0" -"zao.miyagi.jp\0golf\0" -"tv.br\0cn.ua\0" -"leclerc\0" -"\xd8\xb4\xd8\xa8\xd9\x83\xd8\xa9\0" -"johana.toyama.jp\0" -"lipsy\0" -"k12.ne.us\0" -"roma.it\0jaworzno.pl\0lib.la.us\0" -"kusu.oita.jp\0fuchu.tokyo.jp\0" -"i.bg\0" -"\xd8\xb3\xd9\x88\xd8\xb1\xd9\x8a\xd8\xa7\0clinique\0beep.pl\0" -"art.do\0" -"\xd8\xb3\xd9\x88\xd8\xb1\xd9\x8a\xd8\xa9\0" -"inf.mk\0" -"pesarourbino.it\0" -"bi.it\0kitayama.wakayama.jp\0baths.museum\0" -"saotome.st\0\xe4\xbd\x9b\xe5\xb1\xb1\0" -"mlb\0" -"jus.br\0" -"art.dz\0" -"trentino-sued-tirol.it\0" -"coal.museum\0myds.me\0" -"happou.akita.jp\0info.ve\0" -"tysv\xc3\xa6r.no\0" -"cc.pa.us\0" -"greta.fr\0" -"stargard.pl\0mma\0" -"aid.pl\0" -"info.vn\0mls\0" -"friuli-veneziagiulia.it\0shunan.yamaguchi.jp\0" -"elasticbeanstalk.com\0" -"goog\0" -"lib.ny.us\0pioneer\0" -"chuo.osaka.jp\0" -"ariake.saga.jp\0" -"xnbay.com\0" -"trentino-stirol.it\0usuki.oita.jp\0" -"istmein.de\0" -"shiraoka.saitama.jp\0olkusz.pl\0" -"s3-website.us-east-2.amazonaws.com\0" -"rep.kp\0" -"tips\0" -"ora.gunma.jp\0timekeeping.museum\0isa-hockeynut.com\0" -"uvic.museum\0" -"nord-odal.no\0" -"ayabe.kyoto.jp\0" -"rn.it\0gokase.miyazaki.jp\0info.tn\0" -"folkebibl.no\0moe\0own.pm\0" -"info.tr\0cc.ri.us\0" -"caltanissetta.it\0info.tt\0moi\0" -"shikabe.hokkaido.jp\0" -"mom\0dyndns.ddnss.de\0" -"art.ht\0intl.tn\0" -"info.tz\0" -"trustee.museum\0" -"wakasa.tottori.jp\0" -"theatre\0" -"mov\0statefarm\0" -"higashihiroshima.hiroshima.jp\0" -"agano.niigata.jp\0" -"hiranai.aomori.jp\0opencraft.hosting\0" -"shiksha\0" -"\xc3\xa1lt\xc3\xa1.no\0" -"kolobrzeg.pl\0" -"cci.fr\0fujieda.shizuoka.jp\0" -"nab\0" -"info.ro\0" -"tv.im\0" -"presidio.museum\0" -"info.sd\0" -"berlev\xc3\xa5g.no\0" -"tv.it\0" -"britishcolumbia.museum\0\xd1\x80\xd1\x83\xd1\x81\0" -"ybo.party\0" -"passagens\0trading\0" -"date.fukushima.jp\0futaba.fukushima.jp\0tokashiki.okinawa.jp\0iveco\0nba\0" -"alstom\0barcelona\0" -"kamikitayama.nara.jp\0" -"groundhandling.aero\0fujiyoshida.yamanashi.jp\0" -"hikone.shiga.jp\0" -"ushistory.museum\0rugby\0" -"ssl.origin.cdn77-secure.org\0" -"modern.museum\0energy\0" -"mihama.chiba.jp\0tsuruoka.yamagata.jp\0" -"info.pk\0" -"info.pl\0forgot.her.name\0" -"suli.hu\0sologne.museum\0inf.ua\0" -"msd\0" -"niteroi.br\0" -"shimoda.shizuoka.jp\0" -"abo.pa\0info.pr\0" -"akdn\0" -"gs.nl.no\0" -"izunokuni.shizuoka.jp\0" -"olsztyn.pl\0cc.il.us\0" -"conf.au\0" -"bmd.br\0" -"iwade.wakayama.jp\0" -"misasa.tottori.jp\0" -"county.museum\0logoip.com\0" -"agric.za\0" -"info.na\0" -"cc.wi.us\0" -"belluno.it\0info.mv\0info.nf\0lib.il.us\0" -"radom.pl\0" -"info.ni\0mtn\0" -"journal.aero\0" -"mtr\0" -"nec\0" -"nanyo.yamagata.jp\0" -"lib.va.us\0" -"arendal.no\0info.nr\0" -"hachioji.tokyo.jp\0" -"machida.tokyo.jp\0tv.na\0" -"kurogi.fukuoka.jp\0" -"\xc4\x8d\xc3\xa1hcesuolo.no\0" -"nadex\0" -"mn.us\0" -"trentino-su\xcc\x88""dtirol.it\0glogow.pl\0" -"li.it\0" -"net\0u2-local.xnbay.com\0" -"ac.gov.br\0puglia.it\0gushikami.okinawa.jp\0info.la\0iveland.no\0" -"new\0" -"is-a-soxfan.org\0" -"odo.br\0" -"kitahiroshima.hokkaido.jp\0finance\0" -"nfl\0" -"preservation.museum\0" -"meiwa.gunma.jp\0" -"art.pl\0" -"i.ng\0" -"cn-north-1.eb.amazonaws.com.cn\0" -"detroit.museum\0" -"karelia.su\0" -"nordkapp.no\0" -"ichinomiya.aichi.jp\0ngo\0" -"namsskogan.no\0" -"massacarrara.it\0suwalki.pl\0" -"living.museum\0" -"tozawa.yamagata.jp\0press.se\0" -"microlight.aero\0" -"nsw.edu.au\0verona.it\0" -"nhk\0from-in.com\0eu.org\0" -"ad.jp\0" -"club\0" -"ullensaker.no\0" -"kisosaki.mie.jp\0" -"\xe8\xb4\xad\xe7\x89\xa9\0" -"mw.gov.pl\0" -"hl.cn\0cesena-forli\xcc\x80.it\0jetzt\0" -"ishikari.hokkaido.jp\0java\0\xd9\x85\xd9\x88\xd9\x82\xd8\xb9\0serveexchange.com\0" -"i.ph\0" -"info.ke\0asmatart.museum\0" -"seirou.niigata.jp\0scienceandindustry.museum\0wiih.gov.pl\0ac.leg.br\0" -"udine.it\0info.ki\0stadt.museum\0" -"\xe5\x9f\xbc\xe7\x8e\x89.jp\0" -"s3-website-ap-southeast-2.amazonaws.com\0" -"minamiuonuma.niigata.jp\0blogspot.vn\0" -"barsy.shop\0" -"kitagata.gifu.jp\0" -"art.sn\0" -"cl.it\0" -"higashiagatsuma.gunma.jp\0" -"isernia.it\0tv.sd\0" -"abruzzo.it\0" -"roma.museum\0" -"mihara.hiroshima.jp\0" -"ntdll.top\0" -"zone\0" -"bolzano-altoadige.it\0" -"k12.dc.us\0" -"ms.gov.br\0chofu.tokyo.jp\0b\xc3\xa1l\xc3\xa1t.no\0" -"seki.gifu.jp\0rich\0" -"lib.as.us\0" -"ichikai.tochigi.jp\0" -"asso.eu.org\0" -"ind.br\0nichinan.miyazaki.jp\0balsfjord.no\0" -"reliance\0" -"i.se\0" -"cri.br\0" -"naturhistorisches.museum\0grue.no\0" -"zuerich\0" -"hakui.ishikawa.jp\0tcp4.me\0" -"tv.tr\0" -"siena.it\0kodaira.tokyo.jp\0" -"joinville.br\0caserta.it\0" -"kharkiv.ua\0" -"mie.jp\0tv.tz\0" -"co.krd\0" -"s\xc3\xb8r-aurdal.no\0service.gov.uk\0" -"austin.museum\0" -"blogspot.re\0" -"mt.gov.br\0etajima.hiroshima.jp\0" -"hachijo.tokyo.jp\0konin.pl\0" -"london.museum\0cloudycluster.net\0" -"chuo.fukuoka.jp\0" -"ta.it\0\xd1\x81\xd1\x80\xd0\xb1\0" -"shobara.hiroshima.jp\0sandnessj\xc3\xb8""en.no\0" -"press.ma\0" -"blogspot.ro\0" -"goiania.br\0" -"sport.hu\0notogawa.shiga.jp\0" -"bel.tr\0" -"haga.tochigi.jp\0blogspot.rs\0" -"!city.kawasaki.jp\0blogspot.ru\0blogspot.se\0" -"kmpsp.gov.pl\0from-wv.com\0" -"blogspot.sg\0" -"blogspot.si\0mysecuritycamera.net\0" -"hanamigawa.chiba.jp\0blogspot.sk\0freeddns.us\0" -"hjartdal.no\0" -"miyako.fukuoka.jp\0zhytomyr.ua\0ms.leg.br\0" -"blogspot.sn\0" -"ueda.nagano.jp\0" -"iwakura.aichi.jp\0" -"nishiarita.saga.jp\0stat.no\0tr.eu.org\0ras.ru\0" -"blogspot.td\0" -"shiftedit.io\0" -"hurdal.no\0" -"matsuura.nagasaki.jp\0" -"kasahara.gifu.jp\0" -"amica\0" -"myeffect.net\0" -"kazimierz-dolny.pl\0" -"hidaka.saitama.jp\0" -"vi.it\0now\0" -"takahashi.okayama.jp\0fujikawa.yamanashi.jp\0is-a-bookkeeper.com\0" -"blogspot.tw\0blogspot.ug\0" -"cc.ut.us\0" -"game-server.cc\0" -"sumoto.hyogo.jp\0tsuyama.okayama.jp\0" -"midori.chiba.jp\0" -"mt.leg.br\0" -"trentinosu\xcc\x88""dtirol.it\0" -"uk.net\0" -"ind.gt\0heroy.nordland.no\0" -"blogspot.mr\0" -"hjelmeland.no\0tokke.no\0" -"yoro.gifu.jp\0artanddesign.museum\0muncie.museum\0abkhazia.su\0" -"blogspot.mx\0" -"castle.museum\0monticello.museum\0soccer\0blogspot.my\0" -"iamallama.com\0" -"blogspot.nl\0" -"lunner.no\0nra\0university\0" -"pistoia.it\0mombetsu.hokkaido.jp\0ky.us\0blogspot.no\0" -"hadsel.no\0swiftcover\0" -"berlin.museum\0obi\0" -"ashikaga.tochigi.jp\0" -"ind.in\0" -"pictet\0" -"yuasa.wakayama.jp\0earth\0" -"\xe1\x83\x92\xe1\x83\x94\0" -"nrw\0" -"blogspot.pe\0" -"\xda\x80\xd8\xa7\xd8\xb1\xd8\xaa\0" -"fauske.no\0serveftp.net\0" -"likescandy.com\0" -"international\0syno-ds.de\0" -"lillehammer.no\0nikon\0" -"health-carereform.com\0" -"show.aero\0" -"matsuzaki.shizuoka.jp\0blogspot.qa\0" -"kawai.iwate.jp\0otsu.shiga.jp\0" -"hl.no\0blogspot.pt\0" -"s3.dualstack.eu-west-1.amazonaws.com\0" -"shinagawa.tokyo.jp\0" -"s3-website.ap-south-1.amazonaws.com\0" -"maibara.shiga.jp\0" -"control.aero\0" -"ascoli-piceno.it\0" -"*.sapporo.jp\0" -"design.aero\0" -"ntt\0" -"upow.gov.pl\0" -"ichihara.chiba.jp\0ind.kw\0blogspot.is\0" -"blogspot.it\0" -"shimizu.hokkaido.jp\0uslivinghistory.museum\0" -"bedzin.pl\0webhop.info\0" -"k12.ms.us\0k12.nc.us\0" -"lib.ks.us\0news\0" -"politie\0" -"codes\0" -"blogspot.jp\0" -"g.bg\0gripe\0" -"off\0" -"philately.museum\0dnsfor.me\0" -"ochi.kochi.jp\0democrat\0winners\0" -"bg.it\0" -"broke-it.net\0" -"cc.ar.us\0next\0" -"bale.museum\0" -"\xc3\xb8yer.no\0blogspot.kr\0" -"ot.it\0pd.it\0gitlab.io\0" -"godo.gifu.jp\0iwanuma.miyagi.jp\0hangout\0" -"toon.ehime.jp\0" -"blogspot.li\0" -"shinshinotsu.hokkaido.jp\0" -"sakaiminato.tottori.jp\0" -"omachi.nagano.jp\0" -"hair\0" -"al.gov.br\0toyokawa.aichi.jp\0" -"blogspot.lt\0blogspot.md\0" -"lib.ok.us\0blogspot.lu\0" -"turin.it\0" -"cri.nz\0blogspot.mk\0" -"ragusa.it\0" -"alto-adige.it\0" -"info.zm\0restaurant\0" -"nyc\0" -"niigata.niigata.jp\0" -"gallo\0filegear.me\0" -"qld.edu.au\0hobol.no\0" -"knx-server.net\0" -"yamaga.kumamoto.jp\0" -"epilepsy.museum\0blogspot.fi\0" -"kherson.ua\0" -"nishimera.miyazaki.jp\0" -"blackfriday\0" -"usantiques.museum\0" -"umb.it\0aogashima.tokyo.jp\0" -"media.hu\0rawa-maz.pl\0blogspot.fr\0" -"geek.nz\0" -"nom.ad\0trentin-sudtirol.it\0" -"uhren.museum\0bykle.no\0nom.ae\0customer.speedpartner.de\0" -"nom.af\0" -"nom.ag\0kita.tokyo.jp\0" -"nom.ai\0" -"k12.sc.us\0" -"nom.al\0" -"aeroclub.aero\0" -"biz.bb\0history.museum\0" -"takino.hyogo.jp\0blogspot.gr\0" -"biz.at\0" -"altoadige.it\0" -"author.aero\0rocks\0" -"freesite.host\0" -"ab.ca\0malbork.pl\0" -"biz.az\0grandrapids.museum\0" -"al.leg.br\0" -"blogspot.hk\0" -"s3-website-ap-northeast-1.amazonaws.com\0" -"shingu.hyogo.jp\0" -"tt.im\0space\0" -"ally\0" -"webcam\0blogspot.hr\0" -"vi.us\0" -"kaminokawa.tochigi.jp\0" -"blogspot.hu\0blogspot.ie\0" -"ud.it\0homeoffice.gov.uk\0" -"yonago.tottori.jp\0mayfirst.info\0nom.cl\0" -"yukuhashi.fukuoka.jp\0" -"kitahata.saga.jp\0vennesla.no\0blogspot.in\0" -"nom.co\0\xe6\xbe\xb3\xe9\x96\x80\0tiffany\0" -"shimokawa.hokkaido.jp\0blogspot.ba\0" -"homebuilt.aero\0" -"blogspot.be\0" -"blogspot.bg\0" -"biz.cy\0" -"bydgoszcz.pl\0" -"unazuki.toyama.jp\0ind.tn\0biz.dk\0blogspot.bj\0" -"ashgabad.su\0" -"sakata.yamagata.jp\0" -"plumbing\0" -"blogspot.ca\0" -"kushima.miyazaki.jp\0one\0" -"ong\0" -"tmp.br\0blogspot.cf\0" -"zakopane.pl\0" -"rl.no\0s3-ap-northeast-2.amazonaws.com\0blogspot.ch\0" -"soni.nara.jp\0onl\0" -"amsterdam.museum\0archaeological.museum\0edeka\0jdevcloud.com\0" -"blogspot.cl\0" -"conf.lv\0" -"hongo.hiroshima.jp\0" -"maryland.museum\0juegos\0" -"nom.es\0biz.et\0for-some.biz\0" -"blogspot.de\0" -"blogspot.cv\0" -"*.bd\0tele.amune.org\0" -"oi.kanagawa.jp\0\xe4\xb8\xad\xe4\xbf\xa1\0blogspot.cz\0" -"blogspot.dk\0" -"ooo\0" -"campinas.br\0miniserver.com\0" -"lodingen.no\0" -"valleeaoste.it\0mitake.gifu.jp\0" -"nom.fr\0mizunami.gifu.jp\0kristiansund.no\0" -"gs.bu.no\0broker\0freetls.fastly.net\0nom.gd\0" -"lego\0nom.ge\0" -"bihoro.hokkaido.jp\0gub.uy\0" -"tobe.ehime.jp\0" -"bozen-sudtirol.it\0" -"nom.gl\0" -"trentino-s-tirol.it\0minami.tokushima.jp\0" -"*.ck\0" -"uk.eu.org\0" -"yaese.okinawa.jp\0nom.gt\0" -"iitate.fukushima.jp\0" -"directory\0" -"lg.jp\0kimobetsu.hokkaido.jp\0media.pl\0" -"cdn77-ssl.net\0" -"tatamotors\0" -"bryansk.su\0nom.hn\0" -"s3.eu-west-3.amazonaws.com\0" -"monza-brianza.it\0" -"biz.id\0shouji\0" -"org\0" -"urawa.saitama.jp\0" -"minamiaiki.nagano.jp\0pay\0" -"e12.ve\0games\0" -"ppg.br\0higashisumiyoshi.osaka.jp\0" -"nom.im\0" -"\xed\x95\x9c\xea\xb5\xad\0" -"fussa.tokyo.jp\0" -"*.er\0" -"no.it\0" -"\xe6\xbe\xb3\xe9\x97\xa8\0barsy.site\0" -"cc.nj.us\0" -"*.fj\0" -"*.fk\0" -"flatanger.no\0f\xc3\xb8rde.no\0" -"gz.cn\0" -"labour.museum\0skierva.no\0" -"haus\0" -"blogspot.ae\0nom.ke\0" -"\xc3\xb8ystre-slidre.no\0" -"biz.ki\0" -"nishiazai.shiga.jp\0cranbrook.museum\0" -"pro.az\0" -"z.bg\0celtic.museum\0blogspot.al\0" -"nom.km\0blogspot.am\0" -"virginia.museum\0" -"amex\0" -"ott\0rodeo\0" -"airline.aero\0pro.br\0" -"bz.it\0" -"fukudomi.saga.jp\0tendo.yamagata.jp\0" -"komaki.aichi.jp\0" -"indiana.museum\0itau\0" -"b\xc3\xa5tsfjord.no\0nom.li\0" -"rockart.museum\0ybo.trade\0" -"citadel\0" -"m\xc3\xa1tta-v\xc3\xa1rjjat.no\0privatizehealthinsurance.net\0" -"pet\0" -"juif.museum\0football\0" -"viterbo.it\0cc.pr.us\0" -"choyo.kumamoto.jp\0" -"krodsherad.no\0ovh\0" -"szex.hu\0" -"morioka.iwate.jp\0nom.mg\0s3.dualstack.us-east-1.amazonaws.com\0" -"pro.cy\0gets-it.net\0" -"tynset.no\0s3-website-us-east-1.amazonaws.com\0nom.mk\0" -"gsm.pl\0nym.by\0" -"frankfurt.museum\0nym.bz\0" -"g.se\0pics\0" -"group.aero\0epost\0" -"stcgroup\0" -"nom.nc\0" -"pro.ec\0" -"biz.mv\0\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa5\x8b\xe0\xa4\xa4\0" -"biz.mw\0" -"goshiki.hyogo.jp\0poker\0" -"biz.ni\0lamer\0" -"nom.ni\0" -"sebastopol.ua\0" -"yamaguchi.jp\0" -"friuliveneziagiulia.it\0*.jm\0" -"norfolk.museum\0biz.nr\0phd\0" -"historisches.museum\0" -"nom.nu\0" -"redstone\0" -"so.it\0kumenan.okayama.jp\0" -"takamori.nagano.jp\0funagata.yamagata.jp\0" -"natural.bo\0campobasso.it\0\xd1\x83\xd0\xba\xd1\x80\0" -"ojiya.niigata.jp\0*.kh\0" -"hirosaki.aomori.jp\0waw.pl\0" -"nagato.yamaguchi.jp\0nom.pa\0americanexpress\0pid\0" -"kr\xc3\xa5""anghke.no\0nom.pe\0agakhan\0" -"giving\0" -"tsuchiura.ibaraki.jp\0ina.saitama.jp\0" -"club.aero\0" -"historisch.museum\0biz.pk\0" -"biz.pl\0pin\0" -"pb.ao\0smola.no\0nom.pl\0" -"matsuyama.ehime.jp\0ikeda.fukui.jp\0mydatto.net\0" -"ikeda.hokkaido.jp\0" -"university.museum\0user.party.eus\0" -"or.at\0biz.pr\0nom.qa\0" -"omitama.ibaraki.jp\0kanegasaki.iwate.jp\0" -"higashichichibu.saitama.jp\0" -"or.bi\0" -"nom.pw\0" -"kartuzy.pl\0dynamic-dns.info\0" -"cc.gu.us\0" -"lincoln.museum\0veg\xc3\xa5rshei.no\0" -"sasebo.nagasaki.jp\0mysecuritycamera.org\0bloxcms.com\0" -"achi.nagano.jp\0" -"*.mm\0" -"pro.ht\0sos.pl\0nom.re\0" -"or.ci\0shimane.shimane.jp\0nym.gr\0" -"nishiaizu.fukushima.jp\0tashkent.su\0" -"lg.ua\0" -"institute\0" -"64-b.it\0nym.gy\0" -"or.cr\0nom.ro\0" -"verbania.it\0cloudaccess.net\0" -"*.np\0travel\0nom.rs\0" -"nym.ie\0nom.si\0" -"wajima.ishikawa.jp\0" -"mayfirst.org\0" -"research.aero\0spdns.org\0" -"nuoro.it\0pavia.it\0cymru\0" -"toscana.it\0" -"skjerv\xc3\xb8y.no\0" -"yoshida.shizuoka.jp\0osaka\0\xd8\xa7\xd8\xa8\xd9\x88\xd8\xb8\xd8\xa8\xd9\x8a\0nom.st\0" -"skien.no\0" -"indigena.bo\0" -"erotika.hu\0biz.tj\0" -"*.pg\0nom.tj\0" -"from.hr\0ikoma.nara.jp\0" -"ulsan.kr\0" -"nom.tm\0" -"sabae.fukui.jp\0" -"sci.eg\0pnc\0biz.ua\0" -"biz.tr\0" -"ozu.kumamoto.jp\0fujikawaguchiko.yamanashi.jp\0biz.tt\0" -"chikushino.fukuoka.jp\0" -"railroad.museum\0" -"nom.ug\0" -"nishinoshima.shimane.jp\0setagaya.tokyo.jp\0" -"geisei.kochi.jp\0" -"katsuyama.fukui.jp\0" -"pug.it\0" -"historicalsociety.museum\0" -"natura\0" -"tanagura.fukushima.jp\0nom.vc\0" -"surgeonshall.museum\0bjarkoy.no\0nym.la\0virtual-user.de\0" -"kameyama.mie.jp\0ryokami.saitama.jp\0" -"grocery\0youtube\0nym.lc\0nom.vg\0" -"nom.uy\0" -"cc.me.us\0" -"biz.vn\0dynns.com\0nym.li\0" -"nym.kz\0" -"tatar\0" -"kasaoka.okayama.jp\0pro.na\0fage\0" -"dyndns-wiki.com\0" -"gop.pk\0" -"pro.mv\0" -"nym.lt\0" -"kaho.fukuoka.jp\0nym.lu\0nym.me\0" -"wa.edu.au\0ipiranga\0" -"e.bg\0" -"monza.it\0" -"or.id\0dielddanuorri.no\0" -"rel.ht\0iijima.nagano.jp\0nym.mn\0" -"minamitane.kagoshima.jp\0ping\0" -"\xd8\xa8\xda\xbe\xd8\xa7\xd8\xb1\xd8\xaa\0lasalle\0" -"pink\0" -"samnanger.no\0" -"oldnavy\0nym.mx\0" -"inazawa.aichi.jp\0" -"bozen.it\0pro.om\0" -"losangeles.museum\0" -"or.it\0" -"nango.fukushima.jp\0" -"gs.tm.no\0" -"americanantiques.museum\0wzmiuw.gov.pl\0" -"certification.aero\0aki.kochi.jp\0" -"fail\0" -"pro\0" -"or.jp\0" -"nym.nz\0" -"k12.pa.us\0\xe0\xb6\xbd\xe0\xb6\x82\xe0\xb6\x9a\xe0\xb7\x8f\0" -"*.landing.myjino.ru\0" -"nom.za\0" -"or.ke\0pru\0" -"pro.pr\0" -"cool\0is-a-doctor.com\0half.host\0" -"satx.museum\0" -"nym.pe\0" -"coop\0ostrowiec.pl\0fedex\0" -"biz.zm\0" -"naval.museum\0balashov.su\0" -"or.kr\0stjordal.no\0" -"is-a-socialist.com\0" -"chippubetsu.hokkaido.jp\0" -"minamimaki.nagano.jp\0" -"historichouses.museum\0vista\0" -"nym.pt\0" -"kokonoe.oita.jp\0ringerike.no\0backplaneapp.io\0" -"medio-campidano.it\0" -"nogata.fukuoka.jp\0" -"embetsu.hokkaido.jp\0pub\0" -"dyndns1.de\0" -"\xe0\xaa\xad\xe0\xaa\xbe\xe0\xaa\xb0\xe0\xaa\xa4\0a.prod.fastly.net\0" -"agematsu.nagano.jp\0iizuna.nagano.jp\0" -"takayama.gunma.jp\0paderborn.museum\0" -"ichiba.tokushima.jp\0myftp.org\0" -"toyako.hokkaido.jp\0" -"doctor\0" -"z.se\0" -"homedns.org\0synology.me\0" -"or.na\0" -"tec.ve\0" -"ulm.museum\0goip.de\0" -"or.mu\0localhistory.museum\0playstation\0" -"nym.ro\0" -"hirokawa.fukuoka.jp\0" -"ge.it\0*.ye\0" -"bentley\0" -"fhv.se\0\xe6\x94\xbf\xe5\x8a\xa1\0" -"higashimatsuyama.saitama.jp\0nym.sk\0" -"urasoe.okinawa.jp\0pwc\0" -"ddnslive.com\0" -"iiyama.nagano.jp\0" -"tr.it\0shimotsuma.ibaraki.jp\0" -"kozaki.chiba.jp\0pro.tt\0" -"trentinsud-tirol.it\0" -"nym.su\0" -"harima.hyogo.jp\0serveftp.org\0cloud.fedoraproject.org\0" -"nym.sx\0" -"nm.cn\0" -"ogaki.gifu.jp\0\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" -"\xc3\xa5lg\xc3\xa5rd.no\0fans\0" -"ddr.museum\0is-slick.com\0" -"froland.no\0sochi.su\0" -"fukuchiyama.kyoto.jp\0" -"rel.pl\0" -"nym.tw\0" -"trentino-a-adige.it\0moka.tochigi.jp\0" -"eco.br\0pro.vn\0" -"im.it\0" -"owariasahi.aichi.jp\0jeep\0jp.net\0operaunite.com\0" -"or.pw\0" -"suisse.museum\0" -"r\xc3\xb8""d\xc3\xb8y.no\0markets\0" -"blog.bo\0" -"blog.br\0lundbeck\0" -"servequake.com\0" -"yusui.kagoshima.jp\0k12.in.us\0\xd8\xa7\xd9\x84\xd8\xa7\xd8\xb1\xd8\xaf\xd9\x86\0" -"gen.in\0" -"chanel\0" -"dreamhosters.com\0" -"mizuho.tokyo.jp\0os.hordaland.no\0freeddns.org\0" -"k12.wy.us\0" -"jondal.no\0alipay\0" -"ine.kyoto.jp\0" -"hamatama.saga.jp\0" -"kamiamakusa.kumamoto.jp\0rackmaze.com\0" -"gr.com\0" -"tonami.toyama.jp\0kraanghke.no\0" -"laakesvuemie.no\0" -"hokkaido.jp\0" -"le.it\0farm\0lgbt\0vision\0" -"kanazawa.ishikawa.jp\0tr.no\0" -"est-le-patron.com\0for-our.info\0" -"targi.pl\0" -"or.th\0" -"yawata.kyoto.jp\0nagawa.nagano.jp\0" -"wajiki.tokushima.jp\0" -"conference.aero\0" -"fast\0" -"shonai.fukuoka.jp\0theworkpc.com\0" -"or.ug\0" -"com.ac\0" -"aparecida.br\0" -"or.tz\0" -"com.af\0" -"com.ag\0" -"jeonbuk.kr\0" -"com.ai\0" -"heguri.nara.jp\0tochigi.tochigi.jp\0imageandsound.museum\0" -"balsan.it\0" -"com.al\0yamagata.jp\0andebu.no\0czeladz.pl\0" -"or.us\0ninja\0" -"com.ba\0nabari.mie.jp\0" -"com.ar\0com.bb\0leirvik.no\0" -"schoenbrunn.museum\0" -"yamazoe.nara.jp\0stranda.no\0" -"com.au\0cc.nh.us\0" -"com.aw\0" -"com.bh\0" -"com.bi\0suzuki\0" -"com.az\0minamiashigara.kanagawa.jp\0" -"gx.cn\0" -"kumakogen.ehime.jp\0" -"com.bm\0kochi.jp\0" -"com.bn\0cust.disrec.thingdust.io\0" -"com.bo\0shingo.aomori.jp\0" -"com.br\0" -"com.bs\0bauern.museum\0" -"com.bt\0" -"x.bg\0isla.pr\0map.fastly.net\0" -"com.by\0com.ci\0" -"com.bz\0" -"gj\xc3\xb8vik.no\0gen.nz\0" -"com.cm\0ee.eu.org\0" -"com.cn\0" -"com.co\0ch.it\0saku.nagano.jp\0s3.dualstack.sa-east-1.amazonaws.com\0" -"association.aero\0" -"philadelphia.museum\0" -"safety\0" -"com.cu\0chigasaki.kanagawa.jp\0com.de\0virtueeldomein.nl\0" -"com.cw\0sakahogi.gifu.jp\0" -"com.cy\0selfip.net\0" -"pu.it\0" -"keymachine.de\0" -"hatogaya.saitama.jp\0jambyl.su\0" -"com.dm\0massa-carrara.it\0" -"agrinet.tn\0" -"com.do\0dovre.no\0" -"isumi.chiba.jp\0lifeinsurance\0" -"lesja.no\0" -"com.ec\0kamishihoro.hokkaido.jp\0" -"com.ee\0hakodate.hokkaido.jp\0" -"nico\0" -"com.eg\0" -"com.dz\0e.se\0dattolocal.com\0" -"hisamitsu\0" -"\xe7\xb5\x84\xe7\xb9\x94.tw\0" -"messina.it\0" -"com.es\0lancome\0" -"com.et\0vestre-toten.no\0" -"yuzawa.niigata.jp\0" -"warszawa.pl\0" -"shimane.jp\0" -"murayama.yamagata.jp\0" -"championship.aero\0" -"meloy.no\0" -"kusatsu.shiga.jp\0" -"hemnes.no\0nord-fron.no\0" -"pvt.k12.ma.us\0isa-geek.org\0" -"botanicgarden.museum\0" -"com.fr\0" -"com.ge\0" -"com.gh\0kaszuby.pl\0" -"com.gi\0lib.co.us\0" -"sld.do\0com.gl\0" -"com.gn\0naoshima.kagawa.jp\0" -"com.gp\0tsuruga.fukui.jp\0likes-pie.com\0" -"hdfc\0" -"med.br\0com.gr\0furniture.museum\0" -"oyodo.nara.jp\0takaishi.osaka.jp\0woodside\0" -"com.gt\0" -"com.gu\0" -"\xe4\xb8\x96\xe7\x95\x8c\0" -"nakama.fukuoka.jp\0gangwon.kr\0" -"com.gy\0aremark.no\0knightpoint.systems\0" -"com.hk\0" -"kashihara.nara.jp\0" -"rennebu.no\0" -"bc.ca\0com.hn\0hiji.oita.jp\0" -"red\0" -"uppo.gov.pl\0" -"nishi.osaka.jp\0" -"com.hr\0himeji.hyogo.jp\0adult\0" -"gen.tr\0" -"com.ht\0" -"oksnes.no\0" -"kyowa.akita.jp\0" -"wodzislaw.pl\0ren\0" -"nrw.museum\0stuttgart.museum\0" -"ve.it\0fuefuki.yamanashi.jp\0scotland.museum\0" -"com.im\0goto.nagasaki.jp\0" -"qvc\0" -"com.io\0" -"com.iq\0honefoss.no\0" -"med.ec\0com.is\0" -"fnd.br\0med.ee\0arkhangelsk.su\0" -"ass.km\0" -"ardal.no\0vote\0" -"is-a-guru.com\0" -"vaporcloud.io\0" -"lib.tx.us\0" -"movistar\0" -"com.jo\0country\0" -"gives\0" -"kamogawa.chiba.jp\0yokawa.hyogo.jp\0slask.pl\0voto\0" -"tokigawa.saitama.jp\0" -"yatsuka.shimane.jp\0erni\0tuxfamily.org\0" -"sakaki.nagano.jp\0com.kg\0is-a-musician.com\0" -"freeboxos.com\0" -"com.ki\0" -"sciencehistory.museum\0\xe3\x82\xb3\xe3\x83\xa0\0" -"naamesjevuemie.no\0" -"mitou.yamaguchi.jp\0com.km\0sorreisa.no\0" -"miami\0" -"masaki.ehime.jp\0com.kp\0" -"com.la\0" -"com.lb\0" -"com.lc\0consulado.st\0" -"seiyo.ehime.jp\0" -"com.kw\0" -"com.ky\0ivano-frankivsk.ua\0" -"com.kz\0" -"com.lk\0beiarn.no\0" -"nike\0" -"\xe7\x86\x8a\xe6\x9c\xac.jp\0fukui.fukui.jp\0shinjuku.tokyo.jp\0" -"com.lr\0" -"discover\0router.management\0" -"pokrovsk.su\0" -"com.lv\0" -"com.mg\0inderoy.no\0ril\0" -"com.ly\0kv\xc3\xa6""fjord.no\0" -"trader.aero\0kawanabe.kagoshima.jp\0saiki.oita.jp\0rio\0" -"com.mk\0coastaldefence.museum\0rip\0" -"kosaka.akita.jp\0com.ml\0" -"jewishart.museum\0" -"goodhands\0bplaced.de\0" -"com.mo\0" -"gc.ca\0tainai.niigata.jp\0nm.us\0" -"kanonji.kagawa.jp\0com.na\0nore-og-uvdal.no\0est.pr\0" -"ito.shizuoka.jp\0com.ms\0verdal.no\0" -"med.ht\0com.mt\0" -"com.mu\0family.museum\0" -"com.mv\0com.nf\0cyon.link\0" -"com.mw\0com.ng\0" -"com.mx\0" -"kitakami.iwate.jp\0com.my\0com.ni\0" -"iwate.iwate.jp\0maserati\0" -"is-saved.org\0" -"ogimi.okinawa.jp\0" -"gon.pk\0" -"com.nr\0\xd8\xa7\xd9\x84\xd8\xb9\xd9\x84\xd9\x8a\xd8\xa7\xd9\x86\0" -"karate.museum\0dyndns-remote.com\0" -"c.bg\0iwakuni.yamaguchi.jp\0" -"hamamatsu.shizuoka.jp\0dinosaur.museum\0freedesktop.org\0" -"com.om\0" -"campidanomedio.it\0tosu.saga.jp\0" -"kashima.ibaraki.jp\0com.pa\0" -"fukaya.saitama.jp\0numazu.shizuoka.jp\0" -"kainan.wakayama.jp\0" -"com.pe\0" -"inami.wakayama.jp\0com.pf\0" -"inagawa.hyogo.jp\0draydns.de\0" -"com.ph\0" -"reggioemilia.it\0yuki.ibaraki.jp\0starostwo.gov.pl\0" -"com.pk\0" -"com.pl\0\xe7\xb5\x84\xe7\xb9\x94.\xe9\xa6\x99\xe6\xb8\xaf\0" -"sakado.saitama.jp\0" -"exeter.museum\0s\xc3\xb8ndre-land.no\0cc.ok.us\0" -"com.qa\0" -"com.pr\0" -"culturalcenter.museum\0sandefjord.no\0com.ps\0agency\0" -"halloffame.museum\0com.pt\0" -"leangaviika.no\0" -"x443.pw\0" -"nyuzen.toyama.jp\0com.py\0barsy.menu\0" -"piedmont.it\0" -"decorativearts.museum\0lib.mo.us\0" -"gniezno.pl\0dyndns.info\0" -"sm.ua\0" -"risor.no\0" -"sasayama.hyogo.jp\0" -"saitama.saitama.jp\0" -"com.re\0" -"kanoya.kagoshima.jp\0" -"med.ly\0" -"hitachiota.ibaraki.jp\0atlanta.museum\0" -"sld.pa\0" -"com.ro\0" -"yodobashi\0" -"com.sa\0land-4-sale.us\0" -"com.sb\0" -"com.sc\0" -"com.sd\0direct\0" -"com.se\0com.ru\0" -"s3-website-us-west-2.amazonaws.com\0" -"h\xc3\xa1pmir.no\0com.rw\0com.sg\0" -"com.sh\0" -"\xe5\x95\x86\xe6\xa0\x87\0" -"com.sl\0" -"nishinomiya.hyogo.jp\0kustanai.ru\0" -"com.sn\0" -"passenger-association.aero\0com.so\0" -"tsushima.nagasaki.jp\0" -"com.st\0uy.com\0" -"x.se\0isa-geek.com\0" -"com.sv\0" -"\xe8\x8c\xa8\xe5\x9f\x8e.jp\0otama.fukushima.jp\0" -"com.sy\0" -"com.tj\0" -"crimea.ua\0ybo.faith\0" -"jinsekikogen.hiroshima.jp\0nishikawa.yamagata.jp\0sor-aurdal.no\0" -"\xc3\xa5mli.no\0t\xc3\xb8nsberg.no\0med.om\0com.tm\0kustanai.su\0" -"com.tn\0" -"hatoyama.saitama.jp\0museumcenter.museum\0com.to\0" -"med.pa\0com.ua\0" -"charter.aero\0pvh.br\0com.tr\0simple-url.com\0" -"salvador.br\0" -"com.tt\0" -"com.tw\0com.ug\0" -"marche.it\0" -"goodyear\0" -"sap\0" -"dyndns-office.com\0hzc.io\0med.pl\0" -"kvitsoy.no\0cn.eu.org\0" -"saobernardo.br\0tp.it\0sas\0" -"carboniaiglesias.it\0" -"rmit\0" -"boavista.br\0kawaba.gunma.jp\0com.vc\0" -"photos\0sbi\0" -"com.ve\0" -"vgs.no\0" -"bialowieza.pl\0" -"hakuba.nagano.jp\0com.uy\0com.vi\0" -"l\xc3\xb8ten.no\0com.uz\0" -"sca\0" -"mod.gi\0scb\0" -"aizuwakamatsu.fukushima.jp\0com.vn\0sbs\0" -"\xe5\x85\xb5\xe5\xba\xab.jp\0" -"tinn.no\0dynamisches-dns.de\0" -"from-vt.com\0" -"from-az.net\0" -"delta\0" -"lucerne.museum\0com.vu\0" -"minamisanriku.miyagi.jp\0" -"oki.fukuoka.jp\0" -"hita.oita.jp\0fyresdal.no\0" -"saito.miyazaki.jp\0" -"ingatlan.hu\0" -"med.sa\0" -"com.ws\0s3.dualstack.eu-west-2.amazonaws.com\0" -"qc.ca\0med.sd\0" -"olbiatempio.it\0" -"\xe6\x9b\xb8\xe7\xb1\x8d\0" -"chirurgiens-dentistes-en-france.fr\0" -"firestone\0*.compute.amazonaws.com.cn\0" -"pilot.aero\0m\xc3\xa5lselv.no\0" -"barrell-of-knowledge.info\0" -"guge\0play\0c.la\0" -"\xe7\xb5\x84\xe7\xb9\x94.hk\0iwaki.fukushima.jp\0law.za\0" -"is-an-entertainer.com\0" -"mamurogawa.yamagata.jp\0" -"run\0" -"se.net\0ru.net\0" -"scienceandhistory.museum\0investments\0ravendb.me\0" -"anthro.museum\0" -"izu.shizuoka.jp\0ses\0" -"sew\0" -"sex\0" -"coloradoplateau.museum\0" -"lc.it\0\xe5\xae\xae\xe5\x9f\x8e.jp\0stokke.no\0" -"kurume.fukuoka.jp\0" -"gratangen.no\0" -"kotohira.kagawa.jp\0ohkura.yamagata.jp\0gateway.museum\0" -"canada.museum\0exnet.su\0" -"shinonsen.hyogo.jp\0" -"sk.ca\0com.zm\0sfr\0" -"kitaura.miyazaki.jp\0githubusercontent.com\0" -"oita.jp\0rwe\0" -"dynu.net\0" -"otake.hiroshima.jp\0" -"kinko.kagoshima.jp\0" -"pippu.hokkaido.jp\0" -"gv.ao\0data\0" -"skydiving.aero\0" -"tsushima.aichi.jp\0date\0cy.eu.org\0servehttp.com\0" -"gv.at\0" -"nakatane.kagoshima.jp\0" -"sakurai.nara.jp\0as.us\0academy\0" -"tadaoka.osaka.jp\0" -"steigen.no\0" -"recreation.aero\0omachi.saga.jp\0aquarium.museum\0" -"gouv.fr\0nanjo.okinawa.jp\0" -"za.net\0" -"etisalat\0dynalias.net\0sp.leg.br\0" -"memorial.museum\0" -"motobu.okinawa.jp\0" -"gs.sf.no\0ro.eu.org\0" -"lincoln\0" -"selfip.info\0" -"mielno.pl\0us-east-1.amazonaws.com\0" -"kazo.saitama.jp\0on-the-web.tv\0" -"sar.it\0" -"omaezaki.shizuoka.jp\0is-into-anime.com\0" -"newjersey.museum\0" -"edunet.tn\0cz.eu.org\0" -"ayase.kanagawa.jp\0" -"kitanakagusuku.okinawa.jp\0rad\xc3\xb8y.no\0maison\0" -"trentinoa-adige.it\0scrysec.com\0" -"kamigori.hyogo.jp\0" -"kashima.saga.jp\0notaires.km\0" -"v.bg\0" -"furukawa.miyagi.jp\0" -"shirahama.wakayama.jp\0" -"gouv.ht\0" -"sodegaura.chiba.jp\0plantation.museum\0" -"taifun-dns.de\0" -"fujinomiya.shizuoka.jp\0luxembourg.museum\0" -"help\0" -"lans.museum\0askvoll.no\0cc.ca.us\0racing\0map.fastlylb.net\0" -"koriyama.fukushima.jp\0communication.museum\0" -"copenhagen.museum\0western.museum\0ski\0" -"konsulat.gov.pl\0" -"comsec\0" -"ravendb.community\0" -"savona.it\0" -"dk.eu.org\0" -"gouv.bj\0" -"aurskog-h\xc3\xb8land.no\0" -"skodje.no\0sky\0" -"koshigaya.saitama.jp\0c.se\0" -"monzaebrianza.it\0" -"inami.toyama.jp\0" -"ptplus.fit\0" -"gouv.ci\0" -"geekgalaxy.com\0" -"pagefrontapp.com\0" -"overhalla.no\0lidl\0si.eu.org\0" -"sugito.saitama.jp\0grajewo.pl\0" -"en.it\0" -"cloudns.club\0" -"crafts.museum\0" -"axis.museum\0" -"nakatombetsu.hokkaido.jp\0" -"kumamoto.jp\0" -"virtuel.museum\0" -"convent.museum\0" -"figueres.museum\0ustka.pl\0" -"vardo.no\0blogdns.org\0" -"life\0" -"eastcoast.museum\0dep.no\0" -"firmdale\0" -"sunndal.no\0servepics.com\0" -"durham.museum\0contact\0" -"settsu.osaka.jp\0" -"bv.nl\0" -"akune.kagoshima.jp\0" -"chiba.jp\0" -"nid.io\0" -"\xc3\xa5lesund.no\0" -"komagane.nagano.jp\0" -"tenri.nara.jp\0" -"kasama.ibaraki.jp\0ullensvang.no\0\xd8\xb9\xd9\x85\xd8\xa7\xd9\x86\0de.eu.org\0" -"tondabayashi.osaka.jp\0" -"aso.kumamoto.jp\0" -"br\xc3\xb8nn\xc3\xb8y.no\0here\0" -"kuromatsunai.hokkaido.jp\0everbank\0soy\0from-nv.com\0" -"drammen.no\0" -"on.ca\0" -"univ.sn\0" -"vc.it\0" -"contemporary.museum\0farsund.no\0wang\0" -, - -"obama.nagasaki.jp\0supplies\0" -"s3-eu-west-1.amazonaws.com\0bci.dnstrace.pro\0" -"tab\0" -"krym.ua\0usr.cloud.muni.cz\0" -"sk.eu.org\0" -"\xe0\xb8\x98\xe0\xb8\xb8\xe0\xb8\xa3\xe0\xb8\x81\xe0\xb8\xb4\xe0\xb8\x88.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0fujitsu\0s3-ap-south-1.amazonaws.com\0cn.com\0" -"ks.ua\0" -"asahi.toyama.jp\0other.nf\0guru\0us-east-2.elasticbeanstalk.com\0" -"nordre-land.no\0rackmaze.net\0" -"kanan.osaka.jp\0" -"autos\0" -"gangaviika.no\0" -"baby\0" -"shell.museum\0" -"melhus.no\0" -"\xc3\xa5mot.no\0" -"tax\0" -"ugim.gov.pl\0ks.us\0" -"hioki.kagoshima.jp\0" -"srl\0from-va.com\0" -"epson\0s3-website.ca-central-1.amazonaws.com\0" -"dsmynas.com\0" -"natal.br\0" -"friulive-giulia.it\0photography\0" -"\xe5\xaf\x8c\xe5\xb1\xb1.jp\0sano.tochigi.jp\0" -"tselinograd.su\0lcube-server.de\0" -"bunkyo.tokyo.jp\0srt\0" -"grainger\0" -"genkai.saga.jp\0meteorapp.com\0" -"certmgr.org\0" -"tci\0" -"cc.wv.us\0" -"mansion.museum\0lib.ia.us\0" -"oppeg\xc3\xa5rd.no\0oster\xc3\xb8y.no\0like\0" -"corporation.museum\0" -"foz.br\0yamato.kumamoto.jp\0" -"naie.hokkaido.jp\0" -"9.bg\0yame.fukuoka.jp\0" -"stc\0" -"matsuda.kanagawa.jp\0" -"gol.no\0" -"\xe9\x80\x9a\xe8\xb2\xa9\0" -"drayddns.com\0" -"us.na\0caseih\0tdk\0" -"narvik.no\0" -"jpmorgan\0" -"selfip.org\0" -"town\0" -"ru.eu.org\0se.eu.org\0" -"langevag.no\0" -"market\0" -"su\xcc\x88""dtirol.it\0" -"cc.ma.us\0" -"tel\0" -"bulsan.it\0" -"masoy.no\0" -"k12.nm.us\0" -"sanofi\0" -"cloudns.info\0" -"lib.ky.us\0" -"obama.fukui.jp\0limo\0" -"a.bg\0r\xc3\xa1isa.no\0" -"cymru.museum\0isa-geek.net\0" -"aq.it\0ba.it\0" -"link\0" -"bozen-suedtirol.it\0minamiminowa.nagano.jp\0cc.al.us\0lima.zone\0" -"toys\0" -"sciencecenters.museum\0" -"guardian\0" -"kongsberg.no\0" -"cc.ny.us\0ca.eu.org\0" -"trentino-alto-adige.it\0kitaaiki.nagano.jp\0lib.al.us\0thd\0" -"halden.no\0" -"fashion\0" -"myftp.biz\0" -"moriyama.shiga.jp\0rsc.cdn77.org\0from-ky.com\0" -"\xe4\xb8\x89\xe9\x87\x8d.jp\0fidelity\0" -"\xe5\xb1\xb1\xe6\xa2\xa8.jp\0" -"somna.no\0" -"productions\0voting\0" -"forde.no\0" -"chikuzen.fukuoka.jp\0plus\0" -"mashike.hokkaido.jp\0" -"leksvik.no\0" -"hagi.yamaguchi.jp\0" -"publ.pt\0" -"1kapp.com\0" -"\xd8\xaa\xd9\x88\xd9\x86\xd8\xb3\0" -"showa.fukushima.jp\0" -"yamatsuri.fukushima.jp\0is-a-designer.com\0" -"cc.ct.us\0" -"takikawa.hokkaido.jp\0*.stolos.io\0" -"cpa.pro\0garden\0" -"wiki.bo\0" -"wiki.br\0" -"itayanagi.aomori.jp\0store.nf\0" -"asahikawa.hokkaido.jp\0fudai.iwate.jp\0" -"dallas.museum\0" -"is-an-anarchist.com\0" -"sakegawa.yamagata.jp\0" -"kanagawa.jp\0yamatotakada.nara.jp\0alabama.museum\0" -"\xd0\xbe\xd0\xbd\xd0\xbb\xd0\xb0\xd0\xb9\xd0\xbd\0" -"tjx\0" -"est-a-la-maison.com\0" -"yn.cn\0" -"funahashi.toyama.jp\0torino.museum\0" -"eiheiji.fukui.jp\0coldwar.museum\0" -"podhale.pl\0airbus\0" -"yamada.iwate.jp\0" -"walmart\0on-web.fr\0" -"friuli-v-giulia.it\0" -"hareid.no\0cc.fl.us\0" -"valled-aosta.it\0" -"shiroishi.saga.jp\0" -"band\0" -"karumai.iwate.jp\0" -"tn.it\0gouv.rw\0" -"spjelkavik.no\0zachpomor.pl\0" -"iwaizumi.iwate.jp\0" -"turek.pl\0\xe5\xb7\xa5\xe8\xa1\x8c\0" -"exhibition.museum\0serveftp.com\0" -"otaki.saitama.jp\0m\xc3\xa1latvuopmi.no\0bank\0" -"lib.fl.us\0social\0" -"bronnoy.no\0hoyanger.no\0gouv.sn\0software\0" -"stalowa-wola.pl\0consulting\0spdns.eu\0" -"kaufen\0" -"tromsa.no\0" -"takatsuki.osaka.jp\0" -"kagamiishi.fukushima.jp\0cd.eu.org\0" -"sondre-land.no\0" -"tennis\0" -"ginoza.okinawa.jp\0" -"s3.eu-central-1.amazonaws.com\0" -"ngo.lk\0" -"beardu.no\0" -"rikuzentakata.iwate.jp\0live\0" -"rotorcraft.aero\0" -"frei.no\0" -"sk\xc3\xa1nit.no\0mazowsze.pl\0cc.id.us\0tunk.org\0" -"laquila.it\0" -"ricoh\0" -"nagi.okayama.jp\0" -"vv.it\0" -"shacknet.nu\0" -"arab\0" -"matsusaka.mie.jp\0cc.wa.us\0" -"daiwa.hiroshima.jp\0dnsking.ch\0" -"sardinia.it\0mihara.kochi.jp\0lanbib.se\0top\0" -"prato.it\0lixil\0" -"nosegawa.nara.jp\0lv.ua\0" -"namegata.ibaraki.jp\0wolomin.pl\0christmas\0" -"sp.gov.br\0" -"dclk\0" -"nesseby.no\0lib.vi.us\0" -"trentinsuedtirol.it\0herokussl.com\0" -"ham-radio-op.net\0" -"shiogama.miyagi.jp\0jobs.tt\0" -"kawara.fukuoka.jp\0" -"nsw.au\0divtasvuodna.no\0" -"res.aero\0" -"kagamino.okayama.jp\0alvdal.no\0" -"enonic.io\0" -"mex.com\0" -"devices.resinstaging.io\0" -"nebraska.museum\0" -"jamison.museum\0" -"esp.br\0" -"muosat.no\0" -"chiyoda.gunma.jp\0" -"monza-e-della-brianza.it\0okutama.tokyo.jp\0sn\xc3\xa5""ase.no\0s\xc3\xb8rreisa.no\0email\0" -"cuiaba.br\0" -"yasugi.shimane.jp\0ngo.ph\0store.ve\0" -"shimabara.nagasaki.jp\0" -"friuli-venezia-giulia.it\0" -"zaporizhzhe.ua\0mortgage\0" -"brunel.museum\0" -"my.id\0kita.kyoto.jp\0kawatana.nagasaki.jp\0mugi.tokushima.jp\0" -"ubs\0kalmykia.su\0cust.dev.thingdust.io\0" -"newholland\0trv\0" -"assn.lk\0spdns.de\0" -"embroidery.museum\0" -"shiriuchi.hokkaido.jp\0" -"utah.museum\0forsand.no\0mycd.eu\0" -"fukuoka.jp\0so.gov.pl\0" -"romsa.no\0" -"odate.akita.jp\0anamizu.ishikawa.jp\0tateyama.toyama.jp\0bodo.no\0holdings\0" -"cc.mt.us\0cc.nd.us\0" -"go.dyndns.org\0" -"\xd8\xa7\xd9\x8a\xd8\xb1\xd8\xa7\xd9\x86.ir\0alta.no\0" -"ukiha.fukuoka.jp\0" -"sites.static.land\0" -"stordal.no\0" -"katsuragi.nara.jp\0" -"katori.chiba.jp\0" -"firm.ht\0sener\0" -"lib.md.us\0from-nj.com\0za.org\0" -"tokyo.jp\0higashiizu.shizuoka.jp\0" -"t.bg\0shimotsuke.tochigi.jp\0gouv.km\0" -"verran.no\0" -"tui\0" -"uri.arpa\0firm.in\0ureshino.mie.jp\0flynnhub.com\0" -"notaires.fr\0*.elb.amazonaws.com\0" -"bt.it\0gjesdal.no\0" -"*.kitakyushu.jp\0shijonawate.osaka.jp\0cloud.goog\0" -"aikawa.kanagawa.jp\0" -"edogawa.tokyo.jp\0\xe5\xa4\xa7\xe4\xbc\x97\xe6\xb1\xbd\xe8\xbd\xa6\0" -"kalmykia.ru\0" -"enna.it\0leitungsen.de\0" -"morotsuka.miyazaki.jp\0nichinan.tottori.jp\0burghof.museum\0\xe3\x83\x95\xe3\x82\xa1\xe3\x83\x83\xe3\x82\xb7\xe3\x83\xa7\xe3\x83\xb3\0" -"ryuoh.shiga.jp\0" -"fortal.br\0!city.nagoya.jp\0kamoenai.hokkaido.jp\0int.eu.org\0" -"floro.no\0holt\xc3\xa5len.no\0" -"condos\0stream\0" -"supply\0bmoattachments.org\0" -"to.leg.br\0" -"kanzaki.saga.jp\0store.ro\0" -"jl.cn\0taiki.mie.jp\0tvs\0" -"jerusalem.museum\0" -"gouv.ml\0""3utilities.com\0" -"a.se\0pramerica\0" -"money.museum\0" -"firm.co\0" -"ono.fukushima.jp\0nordreisa.no\0" -"room\0" -"paragliding.aero\0pri.ee\0hobby-site.com\0" -"pasadena.museum\0" -"newmexico.museum\0" -"bremanger.no\0ga.us\0" -"ostroleka.pl\0store.st\0s3-website.eu-west-3.amazonaws.com\0" -"firm.dk\0" -"fineart.museum\0" -"osaka.jp\0" -"trentinsu\xcc\x88""dtirol.it\0" -"torahime.shiga.jp\0unusualperson.com\0" -"priv.hu\0tn.us\0alpha-myqnapcloud.com\0" -"si.it\0miyashiro.saitama.jp\0" -"*.awdev.ca\0" -"tsukumi.oita.jp\0" -"cc.sd.us\0" -"md.ci\0kaneyama.fukushima.jp\0" -"kakamigahara.gifu.jp\0lib.dc.us\0" -"vologda.su\0" -"\xd8\xa8\xd8\xa7\xd8\xb1\xd8\xaa\0" -"yotsukaido.chiba.jp\0motorcycle.museum\0" -"bugatti\0" -"ogawa.nagano.jp\0dentist\0" -"chitose.hokkaido.jp\0debian.net\0" -"chicago.museum\0newhampshire.museum\0stavanger.no\0" -"n\xc3\xa1vuotna.no\0" -"can.museum\0oceanographic.museum\0definima.net\0" -"telefonica\0" -"chrome\0" -"cal.it\0" -"living\0cyon.site\0" -"va.it\0" -"trust\0" -"kakogawa.hyogo.jp\0" -"group\0" -"ngo.za\0" -"ong.br\0" -"\xe0\xa8\xad\xe0\xa8\xbe\xe0\xa8\xb0\xe0\xa8\xa4\0" -"morena.br\0" -"s3.cn-north-1.amazonaws.com.cn\0" -"yura.wakayama.jp\0dnsupdater.de\0" -"shirataka.yamagata.jp\0" -"army\0dynalias.org\0" -"fukuroi.shizuoka.jp\0la.us\0" -"priv.at\0" -"kira.aichi.jp\0nagai.yamagata.jp\0kristiansand.no\0" -"sr.gov.pl\0" -"abogado\0" -"asahi.ibaraki.jp\0" -"\xe7\xa7\x8b\xe7\x94\xb0.jp\0yakumo.hokkaido.jp\0higashikagawa.kagawa.jp\0dnepropetrovsk.ua\0" -"askoy.no\0" -"fishing\0" -"tamano.okayama.jp\0" -"arpa\0*.sensiosite.cloud\0" -"birkenes.no\0sejny.pl\0" -"7.bg\0uno\0" -"hisayama.fukuoka.jp\0delivery\0" -"adm.br\0skanit.no\0" -"praxi\0getmyip.com\0" -"lib.vt.us\0" -"friuliv-giulia.it\0" -"agrar.hu\0" -"williamsburg.museum\0" -"minamioguni.kumamoto.jp\0" -"uol\0" -"beskidy.pl\0df.leg.br\0" -"archi\0" -"2000.hu\0kyoto.jp\0mitoyo.kagawa.jp\0" -"lt.it\0" -"cosenza.it\0va.no\0" -"musica.ar\0cuisinella\0" -"mus.mi.us\0" -"chiryu.aichi.jp\0kyiv.ua\0" -"services.aero\0takahama.fukui.jp\0yanagawa.fukuoka.jp\0kautokeino.no\0" -"fl\xc3\xa5.no\0" -"ups\0" -"tonosho.kagawa.jp\0" -"forum.hu\0is-a-personaltrainer.com\0" -"musica.bo\0otsuchi.iwate.jp\0adygeya.su\0" -"broker.aero\0yonabaru.okinawa.jp\0" -"s3-us-east-2.amazonaws.com\0" -"ao.it\0" -"firm.ve\0*.ex.futurecms.at\0" -"shiiba.miyazaki.jp\0management\0" -"ichinohe.iwate.jp\0lardal.no\0" -"blogdns.net\0" -"lazio.it\0" -"trentinoaadige.it\0asda\0" -"arte\0" -"bulsan-suedtirol.it\0egyptian.museum\0" -"kerryhotels\0" -"hgtv\0" -"\xe0\xb8\x84\xe0\xb8\xad\xe0\xb8\xa1\0" -"lib.ms.us\0lib.nc.us\0" -"valle-d-aosta.it\0komatsu.ishikawa.jp\0ringebu.no\0" -"sagamihara.kanagawa.jp\0" -"ug.gov.pl\0" -"taranto.it\0" -"ap-southeast-2.elasticbeanstalk.com\0" -"ogi.saga.jp\0mill.museum\0" -"health.nz\0" -"adygeya.ru\0" -"gru.br\0dyn.cosidns.de\0" -"bbva\0tmall\0" -"oshima.yamaguchi.jp\0sumy.ua\0" -"shiga.jp\0sakawa.kochi.jp\0" -"drive\0s3-ca-central-1.amazonaws.com\0" -"mielec.pl\0" -"minamiawaji.hyogo.jp\0okayama.okayama.jp\0baltimore.museum\0" -"paleo.museum\0eidsberg.no\0" -"hotels\0" -"aero.tt\0" -"deal\0" -"drud.io\0" -"alstahaug.no\0uconnect\0" -"ryukyu\0" -"suzuka.mie.jp\0ch.eu.org\0firewall-gateway.net\0" -"naha.okinawa.jp\0" -"entertainment.aero\0store.bb\0t.se\0vet\0" -"l\xc3\xa1hppi.no\0" -"brumunddal.no\0" -"aero.mv\0kwpsp.gov.pl\0" -"firm.ro\0" -"eu-west-1.elasticbeanstalk.com\0" -"keisen.fukuoka.jp\0dynv6.net\0" -"klepp.no\0" -"matsubushi.saitama.jp\0" -"takazaki.miyazaki.jp\0irish\0" -"taishi.hyogo.jp\0luster.no\0" -"ol.no\0" -"vallee-aoste.it\0" -"sannohe.aomori.jp\0kumamoto.kumamoto.jp\0" -"vacations\0" -"va.us\0" -"asia\0" -"hamburg\0" -"agents.aero\0\xd9\x82\xd8\xb7\xd8\xb1\0" -"sula.no\0\xe0\xae\x9a\xe0\xae\xbf\xe0\xae\x99\xe0\xaf\x8d\xe0\xae\x95\xe0\xae\xaa\xe0\xaf\x8d\xe0\xae\xaa\xe0\xaf\x82\xe0\xae\xb0\xe0\xaf\x8d\0" -"benevento.it\0" -"yonezawa.yamagata.jp\0" -"giessen.museum\0" -"venezia.it\0serveirc.com\0" -"dyr\xc3\xb8y.no\0" -"toba.mie.jp\0" -"higashi.fukushima.jp\0skoczow.pl\0" -"store.dk\0" -"esashi.hokkaido.jp\0lib.sc.us\0" -"komae.tokyo.jp\0sells-it.net\0nalchik.ru\0" -"daigo.ibaraki.jp\0kirkenes.no\0nowtv\0" -"shiroi.chiba.jp\0kakegawa.shizuoka.jp\0mining.museum\0" -"vig\0\xd8\xa8\xd9\x8a\xd8\xaa\xd9\x83\0" -"myddns.rocks\0" -"muos\xc3\xa1t.no\0" -"oygarden.no\0" -"gs.mr.no\0" -"vin\0" -"florence.it\0vip\0nalchik.su\0" -"saitama.jp\0asnes.no\0" -"tateshina.nagano.jp\0kamitsue.oita.jp\0firm.nf\0" -"wy.us\0" -"vt.it\0" -"lerdal.no\0" -"groks-this.info\0" -"fujisawa.iwate.jp\0" -"tas.au\0ibara.okayama.jp\0" -"lt.ua\0" -"health.museum\0" -"pfizer\0" -"toride.ibaraki.jp\0salangen.no\0" -"toyonaka.osaka.jp\0charity\0" -"izena.okinawa.jp\0school.museum\0" -"l-o-g-i-n.de\0" -"health.vn\0dyndns.biz\0" -"friuli-ve-giulia.it\0vegarshei.no\0" -"nahari.kochi.jp\0pohl\0" -"dyndns-blog.com\0" -"suldal.no\0md.us\0" -"nord-aurdal.no\0" -"higashi.fukuoka.jp\0" -"gran.no\0" -"app.os.stg.fedoraproject.org\0" -"katsushika.tokyo.jp\0nanbu.yamanashi.jp\0anquan\0cloudns.eu\0" -"honbetsu.hokkaido.jp\0" -"salzburg.museum\0sorum.no\0" -"asaminami.hiroshima.jp\0" -"is-a-llama.com\0" -"selfip.biz\0" -"malatvuopmi.no\0rivne.ua\0lib.in.us\0" -"\xe5\xb1\xb1\xe5\xbd\xa2.jp\0" -"shikaoi.hokkaido.jp\0buyshouses.net\0" -"lind\xc3\xa5s.no\0tarnobrzeg.pl\0" -"forex\0" -"andriabarlettatrani.it\0" -"\xe0\xb9\x80\xe0\xb8\x99\xe0\xb9\x87\xe0\xb8\x95.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" -"toho.fukuoka.jp\0" -"nationalfirearms.museum\0" -"aioi.hyogo.jp\0at.eu.org\0georgia.su\0" -"toei.aichi.jp\0onagawa.miyagi.jp\0" -"to.gov.br\0\xe5\x80\x8b\xe4\xba\xba.hk\0blogsyte.com\0" -"software.aero\0safe\0" -"is-a-patsfan.org\0" -"worse-than.tv\0" -"gucci\0" -"svizzera.museum\0" -"cust.prod.thingdust.io\0" -"contemporaryart.museum\0" -"\xc3\xb8ksnes.no\0" -"communications.museum\0" -"hb.cn\0" -"noho.st\0" -"k12.oh.us\0today\0" -"hayakawa.yamanashi.jp\0" -"heroy.more-og-romsdal.no\0grondar.za\0" -"vard\xc3\xb8.no\0" -"kvam.no\0" -"r.bg\0tcm.museum\0levanger.no\0cricket\0" -"hashbang.sh\0" -"holiday\0" -"priv.pl\0" -"miyazaki.miyazaki.jp\0cloudns.in\0" -"habikino.osaka.jp\0dell\0" -"weber\0" -"br.it\0cb.it\0" -"creditunion\0" -"shitara.aichi.jp\0" -"matsukawa.nagano.jp\0\xe0\xa4\x95\xe0\xa5\x89\xe0\xa4\xae\0" -"madrid.museum\0redumbrella\0" -"po.it\0ozora.hokkaido.jp\0" -"trentinosud-tirol.it\0" -"chernigov.ua\0k12.ca.us\0\xe4\xb8\xad\xe5\x9b\xbd\0" -"taketomi.okinawa.jp\0mine.nu\0dray-dns.de\0" -"kunitachi.tokyo.jp\0" -"cloudns.cc\0" -"nakamura.kochi.jp\0valer.hedmark.no\0drud.us\0" -"fr\xc3\xb8ya.no\0" -"wsa.gov.pl\0" -"veterinaire.km\0" -"abudhabi\0" -"komono.mie.jp\0*.futurecms.at\0" -"rebun.hokkaido.jp\0\xe4\xb8\xad\xe5\x9c\x8b\0" -"fhsk.se\0" -"priv.no\0" -"mjondalen.no\0in.net\0" -"computer.museum\0" -"iraq.museum\0lund.no\0" -"vercelli.it\0" -"\xe3\x83\x9d\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\x88\0mysecuritycamera.com\0" -"monzaedellabrianza.it\0dnsdojo.org\0" -"tarama.okinawa.jp\0" -"toyoake.aichi.jp\0ichikawamisato.yamanashi.jp\0" -"mb.ca\0francaise.museum\0" -"fbx-os.fr\0" -"topology.museum\0" -"miyoshi.aichi.jp\0lib.de.us\0" -"medizinhistorisches.museum\0salon\0" -"sale\0" -"ashibetsu.hokkaido.jp\0\xc3\xa5l.no\0brand.se\0" -"shioya.tochigi.jp\0" -"pilots.museum\0" -"priv.me\0haugesund.no\0" -"time.no\0healthcare\0" -"gallery.museum\0" -"tadotsu.kagawa.jp\0" -"durban\0wed\0" -"antiques.museum\0" -"sandnes.no\0" -"royken.no\0" -"veterinaire.fr\0" -"bnr.la\0" -"am.br\0training\0edu.eu.org\0" -"asuke.aichi.jp\0" -"gr.it\0porn\0" -"prof.pr\0mckinsey\0\xe9\xa6\x99\xe6\xa0\xbc\xe9\x87\x8c\xe6\x8b\x89\0" -"act.edu.au\0atsugi.kanagawa.jp\0ventures\0at-band-camp.net\0" -"kasamatsu.gifu.jp\0" -"basilicata.it\0" -"tatsuno.hyogo.jp\0kunohe.iwate.jp\0vt.us\0ownip.net\0" -"siellak.no\0" -"gr.jp\0" -"trondheim.no\0" -"svalbard.no\0" -"niki.hokkaido.jp\0delaware.museum\0" -"mosj\xc3\xb8""en.no\0" -"yuza.yamagata.jp\0" -"dental\0sharp\0*.magentosite.cloud\0" -"dgca.aero\0" -"df.gov.br\0post\0" -"iz.hr\0" -"abc.br\0desi\0" -"dni.us\0" -"aoki.nagano.jp\0" -"bir.ru\0" -"sakura.tochigi.jp\0" -"gs.ah.no\0" -"college\0" -"her\xc3\xb8y.m\xc3\xb8re-og-romsdal.no\0" -"abira.hokkaido.jp\0" -"karlsoy.no\0" -"dance\0" -"sakuho.nagano.jp\0" -"!city.sendai.jp\0chijiwa.nagasaki.jp\0" -"empresa.bo\0" -"nishigo.fukushima.jp\0anthropology.museum\0" -"git-repos.de\0" -"americanart.museum\0" -"s3.us-east-2.amazonaws.com\0wmflabs.org\0" -"for-better.biz\0" -"final\0" -"test-iserv.de\0" -"colonialwilliamsburg.museum\0" -"5.bg\0" -"stjohn.museum\0win\0" -"r\xc3\xa5holt.no\0insure\0" -"spreadbetting\0" -"yamada.toyama.jp\0on-aptible.com\0" -"cipriani\0" -"srv.br\0from-de.com\0gotdns.com\0" -"selfip.com\0" -"nationwide\0" -"bruxelles.museum\0" -"okuma.fukushima.jp\0silk.museum\0" -"opole.pl\0" -"fm.br\0s3-external-1.amazonaws.com\0" -"tamaki.mie.jp\0sarl\0" -"mb.it\0" -"tarui.gifu.jp\0fujiidera.osaka.jp\0t3l3p0rt.net\0" -"\xd8\xa7\xd8\xb1\xd8\xa7\xd9\x85\xd9\x83\xd9\x88\0" -"karasjohka.no\0" -"shikama.miyagi.jp\0" -"gen.mi.us\0" -"amagasaki.hyogo.jp\0togakushi.nagano.jp\0kirovograd.ua\0" -"sor-fron.no\0" -"k12.ma.us\0" -"\xe7\xbb\x84\xe7\xb9\x94.hk\0wassamu.hokkaido.jp\0arakawa.tokyo.jp\0" -"onojo.fukuoka.jp\0horonobe.hokkaido.jp\0" -"g12.br\0" -"honai.ehime.jp\0bilbao.museum\0" -"tj.cn\0oyer.no\0" -"reggio-emilia.it\0" -"weir\0" -"miasta.pl\0cloudns.us\0" -"rj.leg.br\0" -"zushi.kanagawa.jp\0chiropractic.museum\0forum\0" -"rzgw.gov.pl\0cistron.nl\0" -"wme\0" -"shirako.chiba.jp\0spacekit.io\0" -"\xc3\xa5krehamn.no\0averoy.no\0" -"resistance.museum\0" -"firebaseapp.com\0" -"hanyu.saitama.jp\0sandiego.museum\0" -"workshop.museum\0" -"homesecuritypc.com\0" -"from-or.com\0" -"honeywell\0sells-for-u.com\0" -"\xe0\xb4\xad\xe0\xb4\xbe\xe0\xb4\xb0\xe0\xb4\xa4\xe0\xb4\x82\0" -"hirono.iwate.jp\0" -"chita.aichi.jp\0" -"save\0" -"toyooka.hyogo.jp\0" -"lib.ne.us\0" -"ichikawa.chiba.jp\0" -"imari.saga.jp\0" -"oslo.no\0" -"hinode.tokyo.jp\0" -"deloitte\0\xe6\x89\x8b\xe8\xa1\xa8\0" -"n\xc3\xb8tter\xc3\xb8y.no\0is-into-cartoons.com\0" -"kepno.pl\0" -"rexroth\0" -"cheltenham.museum\0" -"au.eu.org\0be.eu.org\0" -"lel.br\0" -"hitachiomiya.ibaraki.jp\0" -"alessandria.it\0tsu.mie.jp\0wow\0xenapponazure.com\0" -"warabi.saitama.jp\0" -"a.ssl.fastly.net\0" -"nakanojo.gunma.jp\0" -"mitsuke.niigata.jp\0tama.tokyo.jp\0" -"r.se\0saxo\0" -"google\0" -"xz.cn\0" -"civilization.museum\0" -"*.sch.uk\0" -"livorno.it\0medecin.km\0" -"s3.dualstack.ap-southeast-2.amazonaws.com\0" -"fm.it\0owani.aomori.jp\0kasai.hyogo.jp\0" -"midsund.no\0" -"kaga.ishikawa.jp\0" -"eigersund.no\0" -"izumo.shimane.jp\0" -"fr\xc3\xa6na.no\0" -"taishi.osaka.jp\0quebec\0" -"illustration.museum\0" -"takinoue.hokkaido.jp\0" -"vald-aosta.it\0audi\0" -"barlettatraniandria.it\0samsclub\0" -"marshalls\0no-ip.org\0" -"\xe6\x85\x88\xe5\x96\x84\0" -"froya.no\0" -"ube.yamaguchi.jp\0" -"kota.aichi.jp\0hitachi.ibaraki.jp\0wildlife.museum\0s\xc3\xb8mna.no\0" -"bg.eu.org\0" -"wtc\0dagestan.ru\0" -"\xe6\x84\x9b\xe7\x9f\xa5.jp\0" -"clubmed\0wtf\0" -"tagajo.miyagi.jp\0" -"krasnodar.su\0" -"basel.museum\0beer\0" -"niepce.museum\0" -"amber.museum\0england.museum\0" -"rishiri.hokkaido.jp\0" -"vr.it\0dagestan.su\0" -"bod\xc3\xb8.no\0" -"b\xc3\xa1hcavuotna.no\0" -"crotone.it\0" -"viking\0" -"tsuru.yamanashi.jp\0" -"ba.leg.br\0" -"kizu.kyoto.jp\0kvanangen.no\0trysil.no\0\xe5\x80\x8b\xe4\xba\xba.\xe9\xa6\x99\xe6\xb8\xaf\0" -"midori.gunma.jp\0jewish.museum\0" -"\xd0\xbe\xd1\x80\xd0\xb3.\xd1\x81\xd1\x80\xd0\xb1\0" -"k12.wa.us\0bplaced.com\0" -"shimamaki.hokkaido.jp\0" -"barsy.mobi\0" -"liaison\0" -"fm.no\0" -"hiroo.hokkaido.jp\0" -"motegi.tochigi.jp\0" -"kakuda.miyagi.jp\0\xe6\x89\x8b\xe6\x9c\xba\0" -"ogano.saitama.jp\0" -"fuchu.hiroshima.jp\0" -"amusement.aero\0kaneyama.yamagata.jp\0" -"ownprovider.com\0" -"siljan.no\0" -"mosvik.no\0" -"red.sv\0" -"tananger.no\0" -"yamanouchi.nagano.jp\0" -"\xe6\x96\xb0\xe9\x97\xbb\0" -"remotewd.com\0" -"flor\xc3\xb8.no\0cloudns.pw\0" -"ditchyourip.com\0" -"hida.gifu.jp\0" -"sogne.no\0" -"hopto.me\0" -"now-dns.top\0" -"vestnes.no\0" -"yoshinogari.saga.jp\0" -"reggio-calabria.it\0cartoonart.museum\0" -"shinto.gunma.jp\0scholarships\0" -"mansions.museum\0readmyblog.org\0" -"media\0" -"yosemite.museum\0no-ip.info\0" -"newport.museum\0" -"kitagata.saga.jp\0" -"american.museum\0" -"xin\0" -"tatebayashi.gunma.jp\0" -"jefferson.museum\0casino\0\xd9\x83\xd9\x88\xd9\x85\0hr.eu.org\0" -"tsumagoi.gunma.jp\0" -"ne.jp\0" -"k12.nv.us\0" -"withyoutube.com\0" -"aguni.okinawa.jp\0ne.ke\0civilwar.museum\0" -"p.bg\0" -"santoandre.br\0yahiko.niigata.jp\0songdalen.no\0" -"fiat\0homes\0" -"schweiz.museum\0de.us\0" -"yasuoka.nagano.jp\0nextdirect\0" -"ne.kr\0" -"shimofusa.chiba.jp\0project.museum\0" -"nobeoka.miyazaki.jp\0" -"\xe7\x8f\xa0\xe5\xae\x9d\0" -"mutsu.aomori.jp\0" -"voyage\0" -"is-a-geek.com\0" -"lillesand.no\0" -"tottori.tottori.jp\0" -"wada.nagano.jp\0rr.leg.br\0" -"mat.br\0" -"chernihiv.ua\0cloudaccess.host\0" -"planetarium.museum\0is-a-cpa.com\0" -"www.ro\0grozny.su\0" -"nikolaev.ua\0" -"am.leg.br\0" -"fido\0softbank\0" -"tjome.no\0" -"kuzumaki.iwate.jp\0appspot.com\0" -"loppa.no\0clinic\0" -"\xe6\x8b\x9b\xe8\x81\x98\0" -"kamaishi.iwate.jp\0" -"\xe3\x82\xaf\xe3\x83\xa9\xe3\x82\xa6\xe3\x83\x89\0" -"r\xc3\xa6lingen.no\0" -"narashino.chiba.jp\0" -"takayama.gifu.jp\0" -"indianmarket.museum\0" -"rs.leg.br\0sc.leg.br\0" -"tienda\0" -"zagan.pl\0mein-iserv.de\0" -"dnsdojo.net\0" -"texas.museum\0" -"miyagi.jp\0artdeco.museum\0global\0" -"blockbuster\0guitars\0" -"kasuga.hyogo.jp\0tube\0servegame.com\0" -"gemological.museum\0fuossko.no\0" -"taito.tokyo.jp\0" -"kami.kochi.jp\0" -"myfritz.net\0" -"tula.su\0" -"wanouchi.gifu.jp\0" -"ibaraki.ibaraki.jp\0ar.com\0" -"from-ny.net\0neat-url.com\0" -"kayabe.hokkaido.jp\0grozny.ru\0" -"ne.pw\0" -"s\xc3\xa1lat.no\0" -"onyourside\0from-id.com\0" -"anani.br\0" -"cc.tx.us\0" -"k\xc3\xa1r\xc3\xa1\xc5\xa1johka.no\0" -"emilia-romagna.it\0frog.museum\0" -"phoenix.museum\0km.ua\0" -"nx.cn\0tsuwano.shimane.jp\0" -"art.museum\0" -"*.0emm.com\0" -"lexus\0" -"oguchi.aichi.jp\0" -"television.museum\0" -"mil.ac\0best\0dyndns-server.com\0" -"naturalsciences.museum\0" -"mil.ae\0" -"obuse.nagano.jp\0" -"mil.al\0heritage.museum\0skj\xc3\xa5k.no\0" -"bytom.pl\0" -"auto\0" -"ama.shimane.jp\0" -"mil.ba\0steiermark.museum\0" -"mil.ar\0ap.leg.br\0" -"eisenbahn.museum\0" -"murakami.niigata.jp\0" -"vestre-slidre.no\0" -"balsan-su\xcc\x88""dtirol.it\0" -"nis.za\0" -"mil.az\0" -"rj.gov.br\0" -"fot.br\0landrover\0" -"3.bg\0" -"crew.aero\0mil.bo\0" -"kainan.tokushima.jp\0" -"mil.br\0sauherad.no\0ne.ug\0prudential\0dyndns-mail.com\0" -"medecin.fr\0" -"is-very-evil.org\0" -"ne.tz\0blogspot.com.cy\0rn.leg.br\0" -"sera.hiroshima.jp\0accenture\0" -"fujimi.saitama.jp\0malopolska.pl\0" -"gamvik.no\0" -"mil.by\0" -"kurate.fukuoka.jp\0omi.niigata.jp\0hockey\0" -"mil.cl\0" -"mil.cn\0ne.us\0" -"mil.co\0\xe5\xb2\x90\xe9\x98\x9c.jp\0" -"blogspot.com.ee\0" -"gildeskal.no\0film\0" -"\xd9\x85\xd8\xb5\xd8\xb1\0blogspot.com.eg\0" -"fet.no\0" -"nissan\0wpdevcloud.com\0" -"east-kazakhstan.su\0hopto.org\0" -"blogspot.com.ar\0" -"mil.do\0nakasatsunai.hokkaido.jp\0missile.museum\0" -"blogspot.com.au\0" -"mil.ec\0" -"ro.leg.br\0" -"sx.cn\0trentino.it\0nissay\0noip.us\0" -"mil.eg\0cesena-forli.it\0" -"inawashiro.fukushima.jp\0" -"auspost\0" -"vevelstad.no\0nyc.mn\0" -"is-a-geek.org\0" -"design\0blogspot.com.br\0" -"sellsyourhome.org\0" -"\xe0\xae\x87\xe0\xae\xa8\xe0\xaf\x8d\xe0\xae\xa4\xe0\xae\xbf\xe0\xae\xaf\xe0\xae\xbe\0" -"collection.museum\0" -"blogspot.com.by\0soundcast.me\0" -"surgery\0" -"shichinohe.aomori.jp\0*.alces.network\0" -"scor\0" -"scot\0s3-website.eu-west-2.amazonaws.com\0blogspot.com.co\0" -"ca-central-1.elasticbeanstalk.com\0" -"gliwice.pl\0gda.pl\0" -"lig.it\0miyoshi.tokushima.jp\0kahoku.yamagata.jp\0" -"mein-vigor.de\0" -"mil.ge\0" -"\xc3\xb8rsta.no\0mragowo.pl\0" -"honda\0" -"mil.gh\0vossevangen.no\0" -"\xe5\x85\xac\xe5\x8f\xb8.cn\0xfinity\0" -"globo\0" -"xxx\0app.os.fedoraproject.org\0" -"yokosuka.kanagawa.jp\0" -"corsica\0" -"s\xc3\xb8r-odal.no\0omega\0" -"mil.gt\0is-a-hunter.com\0" -"\xe5\x85\xac\xe5\x8f\xb8.hk\0honjo.akita.jp\0" -"chimkent.su\0" -"cs.it\0twmail.cc\0" -"academia.bo\0" -"select\0" -"loan\0place\0" -"mil.hn\0tuva.su\0" -"j\xc3\xb8rpeland.no\0xyz\0blogspot.com.es\0" -"oppdal.no\0rzeszow.pl\0" -"sko.gov.pl\0press\0" -"mil.id\0" -"taishin.fukushima.jp\0tokuyama.yamaguchi.jp\0" -"napoli.it\0correios-e-telecomunica\xc3\xa7\xc3\xb5""es.museum\0" -"fire\0" -"mil.in\0" -"eaton.mi.us\0" -"mil.iq\0" -"badajoz.museum\0p.se\0" -"lawyer\0" -"mibu.tochigi.jp\0\xe8\xb0\xb7\xe6\xad\x8c\0" -"otoineppu.hokkaido.jp\0" -"lacaixa\0" -"fujioka.gunma.jp\0" -"applinzi.com\0" -"fish\0bplaced.net\0" -"mil.jo\0" -"xs4all.space\0" -"onjuku.chiba.jp\0" -"przeworsk.pl\0" -"mo\xc3\xa5reke.no\0pomorskie.pl\0" -"mil.kg\0" -"ba.gov.br\0jogasz.hu\0nanao.ishikawa.jp\0" -"isesaki.gunma.jp\0" -"mochizuki.nagano.jp\0mil.km\0" -"himi.toyama.jp\0camera\0" -"fuel.aero\0servep2p.com\0" -"mil.kr\0ostrowwlkp.pl\0" -"morimachi.shizuoka.jp\0" -"*.compute.amazonaws.com\0" -"iron.museum\0il.eu.org\0" -"haram.no\0" -"mil.kz\0" -"austevoll.no\0" -"eu-central-1.elasticbeanstalk.com\0" -"tonaki.okinawa.jp\0karikatur.museum\0" -"family\0" -"nonoichi.ishikawa.jp\0" -"mil.lv\0" -"mil.mg\0tolga.no\0rsvp\0" -"tamamura.gunma.jp\0osteroy.no\0" -"no-ip.net\0" -"net.ac\0" -"net.ae\0miyakonojo.miyazaki.jp\0loft\0" -"net.af\0belem.br\0" -"net.ag\0" -"guovdageaidnu.no\0workisboring.com\0" -"net.ai\0mil.mv\0" -"mil.ng\0knowsitall.info\0hu.eu.org\0ie.eu.org\0" -"net.al\0mil.my\0mil.ni\0" -"mil.mz\0you\0" -"yusuhara.kochi.jp\0" -"bearalv\xc3\xa1hki.no\0" -"net.ba\0yalta.ua\0" -"net.ar\0net.bb\0mil.no\0" -"bushey.museum\0" -"money\0" -"net.au\0" -"net.bh\0" -"\xd7\xa7\xd7\x95\xd7\x9d\0" -"net.az\0coop.ht\0" -"hs.kr\0" -"nov.ru\0" -"net.bm\0mil.nz\0" -"net.bn\0" -"net.bo\0saves-the-whales.com\0" -"sa.gov.au\0ladbrokes\0" -"net.br\0sanok.pl\0" -"net.bs\0" -"net.bt\0" -"ravendb.run\0" -"yasuda.kochi.jp\0\xe4\xbf\xa1\xe6\x81\xaf\0" -"jaguar\0myasustor.com\0" -"mil.pe\0" -"net.ci\0yokote.akita.jp\0" -"net.bz\0" -"\xd8\xa7\xdb\x8c\xd8\xb1\xd8\xa7\xd9\x86.ir\0mil.ph\0prod\0noip.me\0" -"mykolaiv.ua\0nov.su\0" -"net.cm\0prof\0" -"net.cn\0" -"net.co\0mil.pl\0" -"kochi.kochi.jp\0" -"presse.km\0discount\0" -"blogspot.com.mt\0" -"mil.qa\0" -"net.cu\0" -"takahagi.ibaraki.jp\0blogspot.com.ng\0" -"net.cw\0tysfjord.no\0" -"coop.br\0humanities.museum\0\xe0\xa6\xad\xe0\xa6\xbe\xe0\xa6\xb0\xe0\xa6\xa4\0se.leg.br\0" -"net.cy\0geelvinck.museum\0volyn.ua\0" -"sc.cn\0kumiyama.kyoto.jp\0" -"mil.py\0" -"net.dm\0ikeda.nagano.jp\0" -"net.do\0" -"ak.us\0" -"ipifony.net\0" -"net.ec\0" -"h\xc3\xb8ylandet.no\0pulawy.pl\0" -"seto.aichi.jp\0" -"net.eg\0\xc3\xb8vre-eiker.no\0" -"venice.it\0is-a-player.com\0" -"net.dz\0" -"sciencesnaturelles.museum\0sandvik\0" -"oh.us\0" -"kumano.mie.jp\0" -"rr.gov.br\0" -"ms.it\0nieruchomosci.pl\0" -"xerox\0" -"trd.br\0\xe6\x95\x99\xe8\x82\xb2.hk\0presse.ml\0" -"ogori.fukuoka.jp\0hokksund.no\0" -"trentino-aadige.it\0tsurugi.ishikawa.jp\0cc.mn.us\0" -"net.et\0" -"nanae.hokkaido.jp\0caravan\0" -"\xe0\xa4\xb8\xe0\xa4\x82\xe0\xa4\x97\xe0\xa4\xa0\xe0\xa4\xa8\0" -"gjovik.no\0" -"mil.ru\0endoftheinternet.org\0" -"council.aero\0" -"mil.rw\0" -"am.gov.br\0mil.sh\0" -"bolt.hu\0hotel.tz\0" -"tsukiyono.gunma.jp\0bahcavuotna.no\0" -"deatnu.no\0" -"maringa.br\0usui.fukuoka.jp\0bnpparibas\0blogspot.com.tr\0" -"dyndns-pics.com\0" -"nogi.tochigi.jp\0" -"tono.iwate.jp\0" -"n.bg\0net.ge\0" -"yun\0" -"net.gg\0mil.st\0" -"lur\xc3\xb8y.no\0dc.us\0" -"taketa.oita.jp\0" -"net.gl\0mil.sy\0s3-eu-west-3.amazonaws.com\0" -"bn.it\0ms.kr\0malvik.no\0mil.tj\0" -"rs.gov.br\0sc.gov.br\0net.gn\0nakagawa.fukuoka.jp\0" -"net.gp\0oirase.aomori.jp\0oketo.hokkaido.jp\0mil.tm\0ivanovo.su\0" -"eurovision\0" -"net.gr\0mil.to\0" -"rochester.museum\0" -"net.gt\0tec.mi.us\0" -"net.gu\0sardegna.it\0koshu.yamanashi.jp\0yorkshire.museum\0tr\xc3\xa6na.no\0mil.tr\0" -"net.gy\0trentino-altoadige.it\0" -"mil.tw\0" -"net.hk\0" -"mil.tz\0" -"industria.bo\0net.hn\0" -"bozen-su\xcc\x88""dtirol.it\0faith\0" -"urn.arpa\0" -"net.ht\0net.id\0" -"emiliaromagna.it\0moma.museum\0" -"matsudo.chiba.jp\0mil.vc\0" -"nishi.fukuoka.jp\0" -"mil.ve\0" -"kitamoto.saitama.jp\0chizu.tottori.jp\0s\xc3\xb8rum.no\0" -"mizumaki.fukuoka.jp\0bounceme.net\0" -"net.il\0delmenhorst.museum\0ulvik.no\0mil.uy\0" -"net.im\0mihama.mie.jp\0" -"net.in\0odda.no\0s\xc3\xa1l\xc3\xa1t.no\0" -"barclays\0" -"net.iq\0" -"net.ir\0naustdal.no\0" -"net.is\0" -"net.je\0s3-website.ap-northeast-2.amazonaws.com\0" -"kyuragi.saga.jp\0" -"medical.museum\0" -"yoita.niigata.jp\0" -"tachikawa.tokyo.jp\0kvinnherad.no\0is-an-engineer.com\0" -"badaddja.no\0" -"aktyubinsk.su\0" -"net.jo\0" -"quest\0" -"trogstad.no\0" -"hofu.yamaguchi.jp\0tel.tr\0" -"net.kg\0" -"okinawa.jp\0zip\0" -"net.ki\0diet\0" -"manno.kagawa.jp\0omiya.saitama.jp\0vaapste.no\0gr.eu.org\0" -"ln.cn\0" -"saogonca.br\0" -"net.kn\0seat\0" -"uki.kumamoto.jp\0net.la\0" -"sc.ke\0net.lb\0" -"net.lc\0" -"recipes\0" -"harvestcelebration.museum\0chrysler\0" -"santabarbara.museum\0" -"chikusei.ibaraki.jp\0itoman.okinawa.jp\0net.kw\0" -"blogspot.com.uy\0" -"net.ky\0googlecode.com\0" -"net.kz\0selbu.no\0" -"ap.gov.br\0ishikawa.okinawa.jp\0net.lk\0law.pro\0" -"dyndns-at-work.com\0" -"sc.kr\0" -"net.ma\0cupcake.is\0" -"net.lr\0boats\0" -"kamikoani.akita.jp\0" -"mil.za\0oracle\0" -"net.me\0vadso.no\0game-host.org\0" -"not.br\0net.lv\0" -"scrapper-site.net\0" -"capebreton.museum\0" -"ichinoseki.iwate.jp\0net.ly\0online\0" -"santamaria.br\0net.mk\0from-ma.com\0" -"net.ml\0" -"hadano.kanagawa.jp\0k12.gu.us\0" -"rn.gov.br\0" -"of.by\0hotel.lk\0net.mo\0" -"mil.zm\0" -"accident-prevention.aero\0net.ms\0rnrt.tn\0" -"net.mt\0" -"net.mu\0ap.gov.pl\0" -"net.mv\0net.nf\0" -"muika.niigata.jp\0net.mw\0net.ng\0foundation\0feste-ip.net\0" -"net.mx\0k12.ut.us\0" -"net.my\0net.ni\0" -"net.mz\0mil.zw\0" -"avocat.fr\0" -"gyeongnam.kr\0lavangen.no\0" -"net.nr\0tjmaxx\0" -"radio.br\0accesscam.org\0" -"incheon.kr\0seek\0" -"maritimo.museum\0abarth\0kurgan.su\0" -"molise.it\0" -"net.nz\0" -"b\xc3\xb8.telemark.no\0net.om\0" -"ro.gov.br\0valle-daosta.it\0est-mon-blogueur.com\0nh-serv.co.uk\0" -"claims\0\xe5\x98\x89\xe9\x87\x8c\xe5\xa4\xa7\xe9\x85\x92\xe5\xba\x97\0" -"granvin.no\0net.pa\0" -"cq.cn\0" -"nsupdate.info\0" -"daisen.akita.jp\0barum.no\0" -"net.pe\0" -"love\0" -"oe.yamagata.jp\0" -"drangedal.no\0net.ph\0" -"mar.it\0" -"\xd9\x81\xd9\x84\xd8\xb3\xd8\xb7\xd9\x8a\xd9\x86\0" -"shinjo.yamagata.jp\0oppegard.no\0net.pk\0" -"net.pl\0" -"nc.tr\0" -"1.bg\0fvg.it\0net.pn\0" -"ogasawara.tokyo.jp\0" -"net.qa\0" -"ako.hyogo.jp\0net.pr\0from-me.org\0" -"fujishiro.ibaraki.jp\0higashiyamato.tokyo.jp\0net.ps\0" -"kitadaito.okinawa.jp\0fundacio.museum\0net.pt\0\xe3\x82\xb0\xe3\x83\xbc\xe3\x82\xb0\xe3\x83\xab\0" -"assassination.museum\0loans\0" -"qc.com\0" -"kui.hiroshima.jp\0" -"net.py\0ddns.me\0" -"sennan.osaka.jp\0kofu.yamanashi.jp\0" -"juedisches.museum\0" -"andoy.no\0rogers\0" -"ms.us\0nc.us\0" -"akishima.tokyo.jp\0" -"kyotamba.kyoto.jp\0" -"arna.no\0" -"freight.aero\0cc.ky.us\0shell\0" -"hoylandet.no\0" -"hotel.hu\0barclaycard\0" -"b\xc3\xa1jddar.no\0juniper\0" -"n\xc3\xa5\xc3\xa5mesjevuemie.no\0" -"!www.ck\0ruhr\0" -"fi.cr\0panama.museum\0k12.me.us\0" -"net.sa\0\xe5\x85\xac\xe5\x8f\xb8.\xe9\xa6\x99\xe6\xb8\xaf\0" -"hokuto.hokkaido.jp\0net.sb\0" -"\xe5\xb2\xa1\xe5\xb1\xb1.jp\0saltdal.no\0net.sc\0" -"net.sd\0" -"net.ru\0" -"exposed\0resindevice.io\0" -"net.rw\0net.sg\0nohost.me\0" -"net.sh\0app.lmpm.com\0" -"horokanai.hokkaido.jp\0" -"akrehamn.no\0meraker.no\0net.sl\0" -"asaka.saitama.jp\0" -"ishikawa.jp\0net.so\0" -"ws.na\0" -"namdalseid.no\0dscloud.me\0" -"net.st\0" -"szczytno.pl\0" -"sigdal.no\0metlife\0" -"wif.gov.pl\0pixolino.com\0" -"net.th\0" -"tako.chiba.jp\0net.sy\0" -"noto.ishikawa.jp\0net.tj\0immobilien\0" -"isa.kagoshima.jp\0is-a-geek.net\0" -"taira.toyama.jp\0net.tm\0k12.ar.us\0" -"net.tn\0is-a-chef.org\0" -"net.to\0melbourne\0" -"from-ok.com\0" -"net.ua\0mypep.link\0" -"net.tr\0" -"kishiwada.osaka.jp\0bygland.no\0" -"assedic.fr\0omuta.fukuoka.jp\0hyuga.miyazaki.jp\0net.tt\0" -"is-a-rockstar.com\0" -"net.tw\0" -"columbia.museum\0" -"cyou\0" -"gov.nc.tr\0net.uk\0alfaromeo\0" -"de.com\0" -"emerck\0" -"obninsk.su\0townnews-staging.com\0" -"soundandvision.museum\0grimstad.no\0" -"sakuragawa.ibaraki.jp\0" -"net.vc\0" -"sciences.museum\0sc.ug\0" -"izumi.osaka.jp\0troms\xc3\xb8.no\0net.ve\0" -"sc.tz\0" -"net.uy\0net.vi\0servegame.org\0" -"gs.hl.no\0coop.tt\0net.uz\0" -"yoshida.saitama.jp\0" -"kamisunagawa.hokkaido.jp\0v\xc3\xa5g\xc3\xa5.no\0termez.su\0" -"net.vn\0" -"vapor.cloud\0" -"sc.us\0store\0" -"sakae.nagano.jp\0ibaraki.osaka.jp\0net.vu\0" -"chocolate.museum\0" -"coop.mv\0b.ssl.fastly.net\0" -"coop.mw\0" -"swatch\0" -"works.aero\0minamata.kumamoto.jp\0" -"jobs\0tranoy.no\0" -"webhop.biz\0" -"n.se\0net.ws\0" -"lib.pa.us\0" -"aurland.no\0" -"dyndns-web.com\0" -"kitami.hokkaido.jp\0" -"tottori.jp\0" -"forli\xcc\x80-cesena.it\0youth.museum\0" -"dish\0" -"touch.museum\0\xe4\xbc\x81\xe4\xb8\x9a\0" -"fi.it\0fastlylb.net\0" -"homesense\0" -"of.no\0" -"loten.no\0olayan\0" -"mifune.kumamoto.jp\0" -"sv.it\0joboji.iwate.jp\0" -"wien\0" -"wuoz.gov.pl\0" -"hyogo.jp\0" -"net.za\0" +"ve.it\0kosaka.akita.jp\0matsusaka.mie.jp\0pfizer\0" "swiebodzin.pl\0" -"ogawara.miyagi.jp\0is-a-chef.com\0" -"sveio.no\0" -"vet.br\0schokoladen.museum\0dnsalias.com\0" -"yaotsu.gifu.jp\0" -"def.br\0net.zm\0" -"atsuma.hokkaido.jp\0ohira.tochigi.jp\0coop.py\0" -"shichikashuku.miyagi.jp\0" -"sauda.no\0" -"szczecin.pl\0" -"press.aero\0" -"loabat.no\0mattel\0" -"ota.gunma.jp\0" -"odessa.ua\0netlify.com\0" -"asakuchi.okayama.jp\0" -"se.gov.br\0presse.ci\0" -"saintlouis.museum\0" -"tome.miyagi.jp\0" -"us-gov-west-1.elasticbeanstalk.com\0" -"fuoisku.no\0cc.vi.us\0" -"financial\0" -"vipsinaapp.com\0" -"ltd.co.im\0" -"ed.ao\0myfirewall.org\0" -"raholt.no\0" -"jeonnam.kr\0" -"coop.km\0" -"boston.museum\0clothing\0" -"abeno.osaka.jp\0" -"kudoyama.wakayama.jp\0" -"entomology.museum\0mopar\0" -"ngrok.io\0" -"sa.au\0samegawa.fukushima.jp\0" -"recife.br\0poivron.org\0" -"hizen.saga.jp\0" -"sango.nara.jp\0minato.tokyo.jp\0lugs.org.uk\0" -"sling\0" -"fetsund.no\0" -"ed.ci\0numata.gunma.jp\0seranishi.hiroshima.jp\0vagsoy.no\0" -"s3-us-west-2.amazonaws.com\0" -"zippo\0" -"ogawa.ibaraki.jp\0omi.nagano.jp\0" -"trentin-sued-tirol.it\0tomobe.ibaraki.jp\0setouchi.okayama.jp\0" -"\xe9\xab\x98\xe7\x9f\xa5.jp\0" -"ed.cr\0" -"gob.ar\0shimoichi.nara.jp\0" -"osoyro.no\0" -"aibetsu.hokkaido.jp\0ce.leg.br\0" -"presse.fr\0tsubame.niigata.jp\0michigan.museum\0" -"hoteles\0" -"wiki\0" -"sand\xc3\xb8y.no\0" -"sa.cr\0is-a-bruinsfan.org\0" -"kharkov.ua\0" -"gob.bo\0lib.wy.us\0" -"hasura.app\0" -"utsunomiya.tochigi.jp\0" -"maintenance.aero\0" -"skype\0" -"kaluga.su\0" -"nishitosa.kochi.jp\0obanazawa.yamagata.jp\0nv.us\0" -"manx.museum\0\xe6\x96\xb0\xe5\x8a\xa0\xe5\x9d\xa1\0" -"ome.tokyo.jp\0" -"gob.cl\0na.it\0" -"kiwi.nz\0" -"buzen.fukuoka.jp\0gs.rl.no\0read-books.org\0servehalflife.com\0" -"k12.ak.us\0" -"uklugs.org\0" -"skedsmokorset.no\0" -"kerryproperties\0" -"kinokawa.wakayama.jp\0forsale\0" -"marnardal.no\0psp.gov.pl\0\xd0\xb0\xd0\xba.\xd1\x81\xd1\x80\xd0\xb1\0" -"kppsp.gov.pl\0" -"seoul.kr\0sa.gov.pl\0cieszyn.pl\0" -"kimino.wakayama.jp\0macys\0marketing\0" -"gmail\0" -"\xce\xb5\xce\xbb\0" -"gob.do\0heimatunduhren.museum\0" -"it.ao\0alsace\0" -"research.museum\0" -"l.bg\0" -"gob.ec\0kanra.gunma.jp\0vega.no\0zp.gov.pl\0" -"agr.br\0wine\0" -"\xd0\xba\xd0\xb0\xd1\x82\xd0\xbe\xd0\xbb\xd0\xb8\xd0\xba\0" -"bl.it\0" -"encyclopedic.museum\0boutique\0" -"res.in\0" -"stjordalshalsen.no\0" -"gob.es\0\xe6\xb2\x96\xe7\xb8\x84.jp\0sexy\0" -"pi.it\0onga.fukuoka.jp\0" -"maif\0" -"barefoot\0" -"alt.za\0" -"pescara.it\0" -"s3.eu-west-2.amazonaws.com\0" -"yasaka.nagano.jp\0hinohara.tokyo.jp\0" -"motorcycles\0my-wan.de\0" -"dating\0" -"k12.pr.us\0" -"kopervik.no\0" -"abr.it\0" -"tunes\0" -"iida.nagano.jp\0" -"sarufutsu.hokkaido.jp\0parliament.nz\0" -"omaha.museum\0flir\0" -"barueri.br\0" -"daejeon.kr\0" -"desa.id\0" -"s\xc3\xb8gne.no\0pila.pl\0" -"baghdad.museum\0" -"gob.gt\0shizukuishi.iwate.jp\0oy.lc\0" -"health\0" -"\xd8\xa7\xdb\x8c\xd8\xb1\xd8\xa7\xd9\x86\0" -"qld.gov.au\0eidfjord.no\0\xe6\x95\x99\xe8\x82\xb2.\xe9\xa6\x99\xe6\xb8\xaf\0" -"sex.hu\0" -"from-ar.com\0barsyonline.co.uk\0" -"gob.hn\0sa.it\0kotoura.tottori.jp\0" -"ed.jp\0" -"podzone.net\0" -"sytes.net\0" -"bayern\0" -"umig.gov.pl\0" -"radio\0" -"herad.no\0lancia\0" -"shinyoshitomi.fukuoka.jp\0jorpeland.no\0trafficplex.cloud\0" -"salud.bo\0atami.shizuoka.jp\0" -"is-by.us\0" -"mypets.ws\0mypi.co\0" -"dubai\0" -"suzaka.nagano.jp\0" -"vn.ua\0" -"yonaguni.okinawa.jp\0" -"washingtondc.museum\0" -"nt.au\0express\0" -"r\xc3\xa5""de.no\0ia.us\0definima.io\0" -"minobu.yamanashi.jp\0" -"takanabe.miyazaki.jp\0" -"rehab\0" -"nt.ca\0leikanger.no\0" -"co.ae\0shibukawa.gunma.jp\0" -"aoste.it\0" -"co.ag\0" -"davvesiida.no\0bostik\0" -"airforce\0" -"motoyama.kochi.jp\0potager.org\0" -"fukui.jp\0oregon.museum\0" -"co.ao\0" -"creation.museum\0" -"co.bb\0" -"chirurgiens-dentistes.fr\0toyoura.hokkaido.jp\0" -"co.at\0""1337.pictures\0" -"noticias.bo\0" -"co.bi\0kagawa.jp\0" -"unnan.shimane.jp\0freebox-os.com\0" -"handa.aichi.jp\0" -"makurazaki.kagoshima.jp\0fuettertdasnetz.de\0" -"co.ca\0" -"lancashire.museum\0" -"kasugai.aichi.jp\0" -"rieti.it\0\xe7\xb6\xb2\xe8\xb7\xaf.tw\0" -"co.bw\0" -"co.ci\0komatsushima.tokushima.jp\0" -"co.cl\0" -"co.cm\0" -"kutchan.hokkaido.jp\0" -"watches\0" -"co.cr\0fukuchi.fukuoka.jp\0" -"bike\0" -"chambagri.fr\0toya.hokkaido.jp\0gob.mx\0allfinanz\0" -"gob.ni\0" -"fr.eu.org\0" -"sanda.hyogo.jp\0co.cz\0" -"matsubara.osaka.jp\0co.dk\0" -"moriguchi.osaka.jp\0lviv.ua\0" -"webhop.me\0" -"algard.no\0" -"demon.nl\0" -"oarai.ibaraki.jp\0" -"ed.pw\0" -"asti.it\0" -"ethnology.museum\0" -"mishima.shizuoka.jp\0" -"carbonia-iglesias.it\0" -"maebashi.gunma.jp\0gob.pa\0golffan.us\0" -"amakusa.kumamoto.jp\0sex.pl\0" -"milan.it\0" -"magazine.aero\0kaminoyama.yamagata.jp\0" -"ntr.br\0\xe9\x95\xb7\xe5\xb4\x8e.jp\0kuwana.mie.jp\0gob.pe\0" -"takasaki.gunma.jp\0" -"adult.ht\0vikna.no\0poznan.pl\0" -"kagoshima.jp\0takehara.hiroshima.jp\0voagat.no\0" -"gob.pk\0" -"auction\0" -"arida.wakayama.jp\0" -"evenassi.no\0writesthisblog.com\0" -"kiyosato.hokkaido.jp\0" -"co.gg\0" -"holmestrand.no\0bing\0kitchen\0" -"urbinopesaro.it\0misato.saitama.jp\0" -"ag.it\0kalisz.pl\0boston\0" -"vic.gov.au\0co.gl\0" -"utazu.kagawa.jp\0better-than.tv\0" -"foggia.it\0" -"nodum.co\0" -"lierne.no\0joburg\0" -"sado.niigata.jp\0" -"stathelle.no\0" -"co.gy\0" -"monash\0" -"komatsu\0" -"ono.hyogo.jp\0" -"journalism.museum\0" -"sa.com\0" -"hicam.net\0" -"co.id\0\xe9\x95\xb7\xe9\x87\x8e.jp\0dominic.ua\0" -"co.hu\0dontexist.net\0cya.gg\0" -"uchinada.ishikawa.jp\0" -"n\xc3\xa6r\xc3\xb8y.no\0" -"modena.it\0afamilycompany\0" -"is-a-chef.net\0" -"sjc.br\0" -"co.il\0" -"co.im\0seiro.niigata.jp\0ap-southeast-1.elasticbeanstalk.com\0s3-sa-east-1.amazonaws.com\0" -"co.in\0guide\0" -"co.ir\0nodum.io\0" -"trentinoaltoadige.it\0co.it\0yachiyo.chiba.jp\0polkowice.pl\0" -"co.je\0gob.sv\0" -"graz.museum\0" -"wroclaw.pl\0" -"iyo.ehime.jp\0" -"osakasayama.osaka.jp\0" -"campania.it\0" -"co.jp\0diamonds\0" -"stpetersburg.museum\0" -"bronnoysund.no\0lomza.pl\0" -"takko.aomori.jp\0co.ke\0" -"kisarazu.chiba.jp\0" -"ota.tokyo.jp\0rybnik.pl\0" -"sm\xc3\xb8la.no\0vaksdal.no\0" -"*.kawasaki.jp\0us.eu.org\0" -"is-an-actress.com\0" -"l.se\0" -"loab\xc3\xa1t.no\0" -"co.kr\0donostia.museum\0" -"co.lc\0" -"zoology.museum\0gob.ve\0go.leg.br\0" -"s3.dualstack.ap-northeast-2.amazonaws.com\0" -"eu-west-2.elasticbeanstalk.com\0" -"omigawa.chiba.jp\0" -"build\0" -"fg.it\0ruovat.no\0" -"point2this.com\0" -"kunitomi.miyazaki.jp\0co.ma\0nt.no\0ballangen.no\0" -"trani-barletta-andria.it\0" -"bhz.br\0co.ls\0" -"co.me\0" -"co.mg\0" -"hatsukaichi.hiroshima.jp\0" -"kameoka.kyoto.jp\0fredrikstad.no\0" -"isshiki.aichi.jp\0" -"bologna.it\0" -"theater.museum\0" -"ekloges.cy\0" -"padova.it\0" -"gosen.niigata.jp\0co.na\0" -"mo.cn\0" -"is-a-nascarfan.com\0" -"\xe0\xb8\xa8\xe0\xb8\xb6\xe0\xb8\x81\xe0\xb8\xa9\xe0\xb8\xb2.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" -"co.mu\0hitra.no\0" -"gose.nara.jp\0" -"co.mw\0prime\0" -"co.ni\0" -"co.mz\0" -"higashikawa.hokkaido.jp\0co.nl\0" -"co.no\0" -"higashi.okinawa.jp\0" -"seven\0" -"oirm.gov.pl\0\xd9\xbe\xd8\xa7\xd9\x83\xd8\xb3\xd8\xaa\xd8\xa7\xd9\x86\0" -"h\xc3\xa6gebostad.no\0" -"mj\xc3\xb8ndalen.no\0" -"sakai.fukui.jp\0" -"ce.gov.br\0co.nz\0" -"co.om\0" -"flog.br\0" -"bj.cn\0" -"miasa.nagano.jp\0nishikata.tochigi.jp\0bergbau.museum\0" -"trentinostirol.it\0" -"okazaki.aichi.jp\0" -"nedre-eiker.no\0" -"uryu.hokkaido.jp\0" -"shriram\0" -"brussels\0" -"co.pl\0" -"valle.no\0" -"co.pn\0" -"vanylven.no\0jprs\0\xe6\x94\xbf\xe5\xba\x9c\0" -"hakone.kanagawa.jp\0nt.ro\0" -"portal.museum\0gmina.pl\0" -"schwarz\0" -"wakayama.wakayama.jp\0" -"locus\0" -"caa.aero\0co.pw\0volkswagen\0" -"exchange.aero\0shimamoto.osaka.jp\0" -"coffee\0" -"nes.buskerud.no\0" -"vlog.br\0" -"*.compute.estate\0" -"filatelia.museum\0" -"*.otap.co\0" -"st.no\0" -"aosta-valley.it\0" -"r\xc3\xb8yrvik.no\0" -"alwaysdata.net\0" -"sec.ps\0" -"wroc.pl\0" -"sukumo.kochi.jp\0" -"bielawa.pl\0co.rs\0od.ua\0" -"minamiise.mie.jp\0dst.mi.us\0" -"cancerresearch\0" -"urausu.hokkaido.jp\0co.rw\0" -"tabayama.yamanashi.jp\0" -"kg.kr\0mulhouse.museum\0" -"g\xc3\xa1ivuotna.no\0" -"hiroshima.jp\0" -"lefrak\0" -"co.st\0futurehosting.at\0" -"maritime.museum\0" -"mo.it\0co.th\0" -"koza.wakayama.jp\0" -"co.sz\0co.tj\0club.tw\0" -"co.tm\0" -"broadcast.museum\0latino\0" -"muko.kyoto.jp\0berlevag.no\0shaw\0" -"mutual\0co.ua\0dynvpn.de\0" -"co.tt\0codespot.com\0" -"anpachi.gifu.jp\0florist\0" -"starachowice.pl\0lenug.su\0" -"co.ug\0from-ga.com\0" -"hitachi\0" -"watch-and-clock.museum\0co.tz\0" -"co.uk\0" -"b\xc3\xb8mlo.no\0" -"tw.cn\0" -"j.bg\0dell-ogliastra.it\0" -"cherkassy.ua\0" -"co.us\0stufftoread.com\0" -"navigation.aero\0" -"co.ve\0" -"nisshin.aichi.jp\0" -"ebino.miyazaki.jp\0co.vi\0" -"toyotsu.fukuoka.jp\0co.uz\0" -"is-a-cubicle-slave.com\0cloud.metacentrum.cz\0" -"shibetsu.hokkaido.jp\0" -"minamiizu.shizuoka.jp\0" -"pg.it\0" -"cooperativa.bo\0" -"gs.tr.no\0" -"vallee-d-aoste.it\0" -"cc.or.us\0" -"eun.eg\0" -"vads\xc3\xb8.no\0travelersinsurance\0dnshome.de\0" -"helsinki.museum\0" -"inagi.tokyo.jp\0sola.no\0" -"dyndns.tv\0" -"imb.br\0" -"weibo\0" -"nombre.bo\0" -"lib.nv.us\0okinawa\0" -"soc.lk\0" -"ninomiya.kanagawa.jp\0ing.pa\0" -"finland.museum\0" -"kariya.aichi.jp\0cbg.ru\0" -"aostavalley.it\0taipei\0" -"trieste.it\0koganei.tokyo.jp\0bloomberg\0" -"circle\0ro.im\0" -"ono.fukui.jp\0" -"kaizuka.osaka.jp\0" -"indianapolis.museum\0" -"ufcfan.org\0" -"finnoy.no\0" -"ro.it\0" -"sa-east-1.elasticbeanstalk.com\0" -"panerai\0from-mo.com\0" -"shirakawa.fukushima.jp\0historyofscience.museum\0kids.museum\0" -"gotemba.shizuoka.jp\0co.za\0" -"agro.bo\0" -"parliament.cy\0" -"dyndns.ws\0" -"marker.no\0" -"moonscale.net\0" -"nakamichi.yamanashi.jp\0" -"nakayama.yamagata.jp\0" -"co.zm\0" -"shinanomachi.nagano.jp\0xihuan\0" -"rissa.no\0" -"trentino-sud-tirol.it\0funabashi.chiba.jp\0podlasie.pl\0" -"podzone.org\0" -"safety.aero\0" -"neyagawa.osaka.jp\0marylhurst.museum\0co.zw\0" -"haboro.hokkaido.jp\0" -"fukushima.jp\0" -"channel\0shia\0" -"kita.osaka.jp\0v\xc3\xa5ler.hedmark.no\0" -"higashiura.aichi.jp\0chintai\0navoi.su\0" -"\xe5\x8c\x97\xe6\xb5\xb7\xe9\x81\x93.jp\0" -"\xe0\xb0\xad\xe0\xb0\xbe\xe0\xb0\xb0\xe0\xb0\xa4\xe0\xb1\x8d\0" -"chikuhoku.nagano.jp\0toga.toyama.jp\0" -"balsan-sudtirol.it\0" -"ismaili\0\xe5\xbe\xae\xe5\x8d\x9a\0" -"sinaapp.com\0" -"trentin-su\xcc\x88""d-tirol.it\0lecco.it\0" -"itabashi.tokyo.jp\0" -"farmequipment.museum\0dr.na\0" -"host\0gb.com\0" -"\xe4\xba\xac\xe9\x83\xbd.jp\0" -"akita.akita.jp\0shimogo.fukushima.jp\0" -"furubira.hokkaido.jp\0idrett.no\0" -"ginan.gifu.jp\0" -"minato.osaka.jp\0pyatigorsk.ru\0" -"\xe0\xa6\xad\xe0\xa6\xbe\xe0\xa7\xb0\xe0\xa6\xa4\0" -"web.bo\0from-ct.com\0" -"erimo.hokkaido.jp\0" -"test.tj\0" -"games.hu\0kawakami.nagano.jp\0" -"technology.museum\0" -"target\0" -"web.co\0" -"repbody.aero\0" -"\xd0\xbf\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0" -"sondrio.it\0circus.museum\0" -"plo.ps\0" -"savannahga.museum\0" -"web.do\0" -"ide.kyoto.jp\0civilisation.museum\0" -"caxias.br\0" -"valle-aosta.it\0global.ssl.fastly.net\0" -"geology.museum\0" -"sweden.museum\0" -"yashio.saitama.jp\0mo.us\0vodka\0" -"test.ru\0" -"troitsk.su\0" -"hirara.okinawa.jp\0mymediapc.net\0" -"glug.org.uk\0" -"modum.no\0" -"eti.br\0game.tw\0from-pa.com\0" -"kamakura.kanagawa.jp\0" -"blogdns.com\0" -"foodnetwork\0" -"k12.mi.us\0" -"toyotomi.hokkaido.jp\0" -"r.cdn77.net\0" -"yachimata.chiba.jp\0" -"is-into-cars.com\0" -"trentin-suedtirol.it\0" -"tecnologia.bo\0az.us\0" -"tado.mie.jp\0" -"suedtirol.it\0shop\0" -"from-dc.com\0" -"matsue.shimane.jp\0" -"horse\0" -"web.gu\0" -"show\0" -"kawachinagano.osaka.jp\0reise\0" -"neues.museum\0" -"steam.museum\0" -"cc.nm.us\0" -"genting\0" -"go.gov.br\0" -"higashishirakawa.gifu.jp\0clinton.museum\0" -"web.id\0dr.tr\0" -"genova.it\0" -"dynserv.org\0zapto.org\0" -"lib.nm.us\0\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4\0ath.cx\0" -"bo.telemark.no\0" -"gamagori.aichi.jp\0" -"dyn.ddnss.de\0" -"muroran.hokkaido.jp\0" -"xen.prgmr.com\0" -"svn-repos.de\0" -"\xe7\xa6\x8f\xe5\xb2\xa1.jp\0" -"\xd9\x83\xd8\xa7\xd8\xab\xd9\x88\xd9\x84\xd9\x8a\xd9\x83\0" -"tochigi.jp\0" -"kouhoku.saga.jp\0" -"s3.ap-south-1.amazonaws.com\0" -"pz.it\0" -"voss.no\0" -"tochio.niigata.jp\0" -"akashi.hyogo.jp\0" -"yorii.saitama.jp\0" -"palmas.br\0" -"lenvik.no\0sport\0" -"v\xc3\xa5ler.\xc3\xb8stfold.no\0es.eu.org\0" -"molde.no\0strand.no\0k12.ri.us\0homeip.net\0" -"horology.museum\0" -"trento.it\0toyota\0khakassia.su\0" -"travel.pl\0" -"ggf.br\0karmoy.no\0" -"mimata.miyazaki.jp\0fedje.no\0ltda\0cloudns.pro\0" -"costume.museum\0" -"web.lk\0" -"hornindal.no\0" -"okayama.jp\0" -"!city.kobe.jp\0chikuho.fukuoka.jp\0" -"fe.it\0is-very-sweet.org\0" -"air-traffic-control.aero\0" -"sr.it\0konan.aichi.jp\0" -"natori.miyagi.jp\0" -"ginowan.okinawa.jp\0" -"date.hokkaido.jp\0" -"konyvelo.hu\0newyork.museum\0" -"pubol.museum\0" -"web.nf\0" -"cremona.it\0" -"web.ni\0" -"treviso.it\0temp-dns.com\0" -"kumano.hiroshima.jp\0" -"bergen.no\0hermes\0" -"narviika.no\0" -"kuriyama.hokkaido.jp\0" -"kwp.gov.pl\0sucks\0" -"hino.tottori.jp\0firewall-gateway.de\0" -"custom.metacentrum.cz\0" -"photography.museum\0" -"search\0" -"partners\0" -"nakagusuku.okinawa.jp\0" -"koeln.museum\0" -"friulivgiulia.it\0" -"pe.ca\0" -"riik.ee\0nagiso.nagano.jp\0giske.no\0" -"ivgu.no\0" -"works\0" -"world\0" -"matera.it\0" -"cim.br\0web.pk\0is-a-celticsfan.org\0" -"taiji.wakayama.jp\0cruise\0" -"travel.tt\0" -"sokndal.no\0" -"k12.wi.us\0mc.eu.org\0" -"nishiwaki.hyogo.jp\0" -"hob\xc3\xb8l.no\0" -"repair\0" -"miyota.nagano.jp\0mesaverde.museum\0oregontrail.museum\0" -"hitachinaka.ibaraki.jp\0and.museum\0" -"patria.bo\0koka.shiga.jp\0" -"starnberg.museum\0" -"ooguy.com\0" -"udono.mie.jp\0" -"\xe5\xa4\xa9\xe4\xb8\xbb\xe6\x95\x99\0" -"\xe5\xb3\xb6\xe6\xa0\xb9.jp\0" -"is-gone.com\0" -"kadena.okinawa.jp\0" -"trani-andria-barletta.it\0" -"koto.tokyo.jp\0" -"dontexist.org\0*.triton.zone\0" -"sande.vestfold.no\0" -"lt.eu.org\0" -"cloudeity.net\0" -"mikawa.yamagata.jp\0" -"izumiotsu.osaka.jp\0" -"reviews\0" -"adv.br\0vefsn.no\0" -"oyabe.toyama.jp\0roros.no\0" -"nissedal.no\0" -"izumozaki.niigata.jp\0" -"kure.hiroshima.jp\0koge.tottori.jp\0" -"yamamoto.miyagi.jp\0" -"kitakata.fukushima.jp\0press.museum\0" -"noda.iwate.jp\0skierv\xc3\xa1.no\0" -"hm.no\0eid.no\0cloudns.asia\0" -"\xe7\xae\x87\xe4\xba\xba.hk\0r\xc3\xb8yken.no\0from-il.com\0" -"pisz.pl\0" -"nishiizu.shizuoka.jp\0web.tj\0" -"kamitonda.wakayama.jp\0silk\0" -"inatsuki.fukuoka.jp\0futbol\0" -"ebiz.tw\0" -"valdaosta.it\0" -"hashimoto.wakayama.jp\0my-firewall.org\0" -"mizusawa.iwate.jp\0web.tr\0" -"bradesco\0" -"us-west-1.elasticbeanstalk.com\0" -"hobby-site.org\0" -"os.hedmark.no\0" -"agro.pl\0" -"gos.pk\0" -"k12.mn.us\0" -"arts.co\0freemasonry.museum\0troandin.no\0is-an-artist.com\0" -"kasuga.fukuoka.jp\0barsy.co.uk\0" +"gov.uk\0" +"art.museum\0vestv\xc3\xa5g\xc3\xb8y.no\0sina\0virtual-user.de\0" +"yoga\0" +"fe.it\0miura.kanagawa.jp\0" +"gov.vc\0" +"yasaka.nagano.jp\0" +"gov.ve\0" +"uonuma.niigata.jp\0" +"florida.museum\0uno\0" +"intel\0" +"market\0" +"gov.vn\0maison\0" +"kristiansand.no\0blogspot.com\0" +"misato.saitama.jp\0" +"cc.il.us\0" +"perso.sn\0" +"uol\0" +"chanel\0cn-north-1.eb.amazonaws.com.cn\0" +"cody.museum\0" +"czeladz.pl\0" +"sakura\0kr.eu.org\0" +"rn.it\0" +"maritime.museum\0vipsinaapp.com\0" +"harima.hyogo.jp\0" +"staples\0" +"boats\0" +"hi.cn\0perso.tn\0" +"gov.ws\0" +"dell-ogliastra.it\0" +"browsersafetymark.io\0" +"bn.it\0dlugoleka.pl\0" +"annefrank.museum\0" +"hagi.yamaguchi.jp\0" +"k12.az.us\0space\0loseyourip.com\0" +"rns.tn\0" +"mill.museum\0ups\0" +"go.dyndns.org\0" +"bozen-sudtirol.it\0" +"dyndns-office.com\0" +"hofu.yamaguchi.jp\0" +"no-ip.ca\0" +"togitsu.nagasaki.jp\0misato.wakayama.jp\0" +"better-than.tv\0" +"emp.br\0kani.gifu.jp\0" +"oslo.no\0" +"foggia.it\0mibu.tochigi.jp\0" +"orsta.no\0is-gone.com\0" +"og.it\0" +"gov.za\0" +"tenkawa.nara.jp\0" +"communications.museum\0" +"builders\0" +"gov.zm\0" +"juegos\0" "minami.kyoto.jp\0" -"sina\0" -"h.bg\0" -"budapest\0schokokeks.net\0" -"tamayu.shimane.jp\0web.ve\0" -"iwafune.tochigi.jp\0" -"chtr.k12.ma.us\0dyn-vpn.de\0" -"yanaizu.fukushima.jp\0barsy.support\0" -"*.cryptonomic.net\0" -"catania.it\0cc.as.us\0" -"kunstunddesign.museum\0tokyo\0" -"cleaning\0" -"elblag.pl\0" -"takahama.aichi.jp\0" -"pe.it\0" -"hanggliding.aero\0" -"limited\0" -"toyo.kochi.jp\0" -"comunica\xc3\xa7\xc3\xb5""es.museum\0is-lost.org\0fi.eu.org\0" -"webredirect.org\0" -"food\0" -"pharmacien.fr\0" -"homedepot\0" -"lib.oh.us\0" -"wakuya.miyagi.jp\0jolster.no\0" -"kunigami.okinawa.jp\0sanfrancisco.museum\0" +"blackbaudcdn.net\0" +"auction\0mypsx.net\0" +"gov.zw\0" +"monzaedellabrianza.it\0" +"q-a.eu.org\0" +"federation.aero\0cloudns.org\0" +"site\0" +"zamami.okinawa.jp\0" +"emergency.aero\0from-md.com\0" +"not.br\0repair\0" +"airtraffic.aero\0" +"satsumasendai.kagoshima.jp\0\xe0\xb4\xad\xe0\xb4\xbe\xe0\xb4\xb0\xe0\xb4\xa4\xe0\xb4\x82\0" +"lajolla.museum\0familyds.org\0" +"trentino-sudtirol.it\0" +"mosj\xc3\xb8""en.no\0" +"takatori.nara.jp\0" +"recht.pro\0" +"inashiki.ibaraki.jp\0" +"durham.museum\0" +"\xe5\xbe\xae\xe5\x8d\x9a\0" +"vet\0" +"co.business\0" +"andria-barletta-trani.it\0suedtirol.it\0" +"konin.pl\0linkyard-cloud.ch\0" +"gs.tr.no\0" +"labor.museum\0" +"ayagawa.kagawa.jp\0" +"zaporizhzhe.ua\0" +"ovre-eiker.no\0" +"yao.osaka.jp\0" +"my-vigor.de\0" +"northwesternmutual\0" +"stalbans.museum\0" +"hokuryu.hokkaido.jp\0football\0" +"*.nagoya.jp\0" +"teo.br\0" +"presidio.museum\0b\xc3\xb8mlo.no\0kharkiv.ua\0from-mt.com\0from-nd.com\0" +"lecco.it\0" +"asahi.yamagata.jp\0" +"salud.bo\0contemporaryart.museum\0aca.pro\0" +"soja.okayama.jp\0tokigawa.saitama.jp\0prochowice.pl\0" +"il.us\0is-a-geek.com\0" +"tr.it\0gokase.miyazaki.jp\0" +"dyn.ddnss.de\0" +"ladbrokes\0" +"uchiko.ehime.jp\0" +"toyosato.shiga.jp\0ens.tn\0" +"berkeley.museum\0s3.ap-south-1.amazonaws.com\0" +"media.aero\0aaa.pro\0vig\0" +"rimini.it\0itako.ibaraki.jp\0" +"cc.wy.us\0" +"gujo.gifu.jp\0" +"fot.br\0vin\0" +"vip\0" +"cc.hi.us\0" +"taishi.hyogo.jp\0" +"neyagawa.osaka.jp\0genkai.saga.jp\0wakasa.tottori.jp\0" +"co.ae\0" +"development.run\0" +"co.ag\0from-sd.com\0" +"neustar\0" +"birthplace.museum\0" +"cesenaforl\xc3\xac.it\0" +"amot.no\0skjerv\xc3\xb8y.no\0" +"co.ao\0" +"arakawa.saitama.jp\0" +"co.bb\0trani-barletta-andria.it\0" +"co.at\0" +"suifu.ibaraki.jp\0oum.gov.pl\0" +"co.bi\0kvafjord.no\0" +"odate.akita.jp\0" +"embroidery.museum\0" +"takamatsu.kagawa.jp\0" +"nokia\0" +"civilaviation.aero\0co.ca\0" +"sells-for-less.com\0" +"creditcard\0" +"from-ut.com\0" +"rikubetsu.hokkaido.jp\0" +"co.bw\0dr.na\0" +"mt.it\0" +"co.ci\0" +"tr.no\0" +"co.cl\0" +"co.cm\0philadelphiaarea.museum\0" +"bounceme.net\0" +"from-vt.com\0" +"co.cr\0playstation\0" +"hvaler.no\0" +"servebbs.com\0" +"guitars\0" +"storj.farm\0" +"poa.br\0co.cz\0" +"co.dk\0" +"dallas.museum\0" +"leirfjord.no\0cc.ak.us\0" +"localhistory.museum\0" +"\xeb\x8b\xb7\xec\xbb\xb4\0" +"attorney\0" +"awaji.hyogo.jp\0higashiomi.shiga.jp\0" +"homelinux.net\0" +"business\0" +"meet\0" +"lib.ks.us\0" +"krasnik.pl\0" +"isshiki.aichi.jp\0okayama.okayama.jp\0" +"koriyama.fukushima.jp\0" +"horology.museum\0cc.mt.us\0cc.nd.us\0ybo.trade\0" +"valleeaoste.it\0" +"williamsburg.museum\0" +"\xc3\xa5mli.no\0" +"is-a-linux-user.org\0" +"vv.it\0kozagawa.wakayama.jp\0" +"co.gg\0" +"tokoname.aichi.jp\0" +"mg.gov.br\0food\0" +"co.gl\0" +"wassamu.hokkaido.jp\0hakui.ishikawa.jp\0" +"orland.no\0" +"friuli-venezia-giulia.it\0" +"sanfrancisco.museum\0" +"omi.niigata.jp\0" +"h.bg\0infiniti\0" +"kokonoe.oita.jp\0" +"co.gy\0meeres.museum\0merseine.nu\0" +"ebino.miyazaki.jp\0tatar\0" +"wy.us\0" +"trentino-altoadige.it\0" +"malatvuopmi.no\0" +"\xd8\xa7\xd9\x8a\xd8\xb1\xd8\xa7\xd9\x86\0" +"melbourne\0" +"co.id\0valdaosta.it\0" +"co.hu\0hi.us\0is-a-geek.org\0" +"xz.cn\0prudential\0" +"yasugi.shimane.jp\0" +"games.hu\0from-ct.com\0scrapping.cc\0" +"so.it\0iwakura.aichi.jp\0saijo.ehime.jp\0" +"co.il\0friulive-giulia.it\0mielec.pl\0" +"co.im\0ikano\0msk.ru\0" +"co.in\0" +"co.ir\0kurotaki.nara.jp\0" +"co.it\0ogawa.ibaraki.jp\0" +"co.je\0" +"foundation.museum\0clinic\0" +"kamogawa.chiba.jp\0dr.tr\0" +"santacruz.museum\0" +"tsukigata.hokkaido.jp\0ford\0" +"1.bg\0kalmykia.su\0" +"shimofusa.chiba.jp\0" +"bananarepublic\0msk.su\0" +"umig.gov.pl\0" +"co.jp\0warman\0" +"luzern.museum\0s3-ap-northeast-1.amazonaws.com\0" +"cuneo.it\0" +"tananger.no\0" +"vallee-aoste.it\0" +"co.ke\0lindesnes.no\0cloud.goog\0" +"milano.it\0" +"wed\0" +"wa.edu.au\0is-a-caterer.com\0" +"edu.krd\0" +"\xe5\xb2\x90\xe9\x98\x9c.jp\0co.kr\0legal\0rexroth\0" +"co.lc\0*.stolos.io\0" +"selfip.net\0" +"slattum.no\0" +"kawakami.nagano.jp\0computer\0" +"stor-elvdal.no\0from-id.com\0" +"meme\0" +"co.ma\0" +"akita.jp\0" +"co.ls\0" +"sakai.ibaraki.jp\0" +"co.me\0royrvik.no\0rocks\0" +"geek.nz\0" +"co.mg\0school.na\0cc.co.us\0s3.amazonaws.com\0" +"kommune.no\0" +"kalmykia.ru\0" +"ak.us\0" +"aogaki.hyogo.jp\0kashima.ibaraki.jp\0" +"shizuoka.jp\0" +"co.na\0" +"tako.chiba.jp\0kamikawa.hokkaido.jp\0" +"media.museum\0lib.mo.us\0kicks-ass.org\0" +"co.mu\0" +"certification.aero\0co.mw\0" +"nakanojo.gunma.jp\0" +"suli.hu\0co.ni\0" +"sicilia.it\0co.mz\0" +"movistar\0co.nl\0" +"menu\0" +"co.no\0utwente.io\0" +"school.nz\0" +"vologda.su\0" +"nu.ca\0george\0" +"xihuan\0" +"mt.us\0nd.us\0" +"drangedal.no\0" +"\xe5\xaf\x8c\xe5\xb1\xb1.jp\0co.nz\0" +"rauma.no\0" +"co.om\0" +"nakanoto.ishikawa.jp\0" +"poivron.org\0" +"cesenaforli.it\0discount\0" +"loab\xc3\xa1t.no\0" +"nakijin.okinawa.jp\0win\0" +"skin\0" +"co.pl\0" +"soundandvision.museum\0" +"co.pn\0" +"kasukabe.saitama.jp\0" +"vgs.no\0notodden.no\0" +"surgeonshall.museum\0cc.ma.us\0" +"university.museum\0co.pw\0" +"klodzko.pl\0" +"static-access.net\0" +"kddi\0" +"volda.no\0troitsk.su\0" +"kawai.iwate.jp\0" +"coop.ht\0vc.it\0" +"ikata.ehime.jp\0" +"gs.rl.no\0" +"catanzaro.it\0ogliastra.it\0" +"\xc3\xa5s.no\0" +"dreamhosters.com\0" +"fc.it\0sagamihara.kanagawa.jp\0" +"skedsmokorset.no\0" +"lapy.pl\0" +"figueres.museum\0midsund.no\0tuxfamily.org\0" +"kushiro.hokkaido.jp\0" +"x443.pw\0" +"yamamoto.miyagi.jp\0" +"blog\0" +"co.rs\0active\0" +"co.rw\0" +"sorfold.no\0" +"trentino-sued-tirol.it\0" +"wme\0" +"shimonita.gunma.jp\0" +"coop.br\0kadogawa.miyazaki.jp\0" +"shari.hokkaido.jp\0" +"avocat.pro\0" +"massa-carrara.it\0" +"co.st\0" +"shop.ht\0" +"shop.hu\0productions\0" +"yamaguchi.jp\0es.kr\0co.th\0" +"co.sz\0co.tj\0" +"francaise.museum\0co.tm\0ox.rs\0" +"bl.it\0" +"e164.arpa\0fhv.se\0" +"genoa.it\0" +"co.ua\0" +"build\0" +"langev\xc3\xa5g.no\0loabat.no\0" +"co.tt\0" +"skydiving.aero\0is-a-designer.com\0" +"psi.br\0oseto.nagasaki.jp\0" +"co.ug\0" +"uji.kyoto.jp\0" +"co.tz\0" +"co.uk\0" +"us.na\0" +"transporte.bo\0" +"co.us\0" +"ito.shizuoka.jp\0" +"osoyro.no\0co.ve\0knightpoint.systems\0" +"pmn.it\0arita.saga.jp\0sosnowiec.pl\0" +"sci.eg\0" +"nu.it\0swinoujscie.pl\0" +"co.vi\0" +"co.uz\0" +"nissedal.no\0" +"grainger\0" +"wow\0" +"associates\0" +"narusawa.yamanashi.jp\0" +"rodeo\0" +"kiyama.saga.jp\0" +"lib.ak.us\0" +"medio-campidano.it\0" +"chikushino.fukuoka.jp\0mazowsze.pl\0" +"ogori.fukuoka.jp\0kitaura.miyazaki.jp\0" +"luxe\0" +"assabu.hokkaido.jp\0" +"geelvinck.museum\0" +"malopolska.pl\0" +"living.museum\0" +"farmers.museum\0coffee\0" +"fukushima.jp\0shingo.aomori.jp\0sasaguri.fukuoka.jp\0toyotomi.hokkaido.jp\0" +"b\xc3\xa1hcavuotna.no\0" +"tempio-olbia.it\0" +"rl.no\0blue\0" +"perugia.it\0" +"commbank\0" +"chichibu.saitama.jp\0" +"hattfjelldal.no\0h.se\0" +"inami.toyama.jp\0" +"ftpaccess.cc\0" +"yurihonjo.akita.jp\0" +"nb.ca\0draydns.de\0" +"mymediapc.net\0" +"ma.us\0co.za\0" +"kitaakita.akita.jp\0kosuge.yamanashi.jp\0" +"docs\0" +"tranibarlettaandria.it\0" +"sydney.museum\0" +"tamamura.gunma.jp\0onion\0" +"taketomi.okinawa.jp\0myeffect.net\0" +"k12.wi.us\0wtc\0" +"noda.iwate.jp\0wtf\0" +"co.zm\0" +"horokanai.hokkaido.jp\0" +"ikeda.nagano.jp\0" +"jor.br\0" +"y.bg\0co.zw\0" +"news.hu\0" +"xen.prgmr.com\0" +"otaki.saitama.jp\0" +"ipifony.net\0" +"minamitane.kagoshima.jp\0olecko.pl\0" +"jpn.com\0workisboring.com\0" +"tjome.no\0" +"forli-cesena.it\0" +"os.hordaland.no\0" +"ako.hyogo.jp\0" +"video.hu\0" +"huissier-justice.fr\0kotohira.kagawa.jp\0" +"tp.it\0ichikai.tochigi.jp\0" +"gdansk.pl\0" +"maizuru.kyoto.jp\0" +"hsbc\0icbc\0lanxess\0singles\0elasticbeanstalk.com\0" +"katowice.pl\0" +"consulting.aero\0" +"detroit.museum\0" +"yaese.okinawa.jp\0" +"office\0" +"umbria.it\0" +"toyota.aichi.jp\0gotemba.shizuoka.jp\0" +"selfip.info\0" +"vadso.no\0" +"mo\xc3\xa5reke.no\0doha\0work\0" +"ohkura.yamagata.jp\0" +"pictures\0myphotos.cc\0" +"eu.int\0shonai.fukuoka.jp\0sennan.osaka.jp\0" +"philately.museum\0" +"gallery\0" +"misato.shimane.jp\0" +"aerobatic.aero\0review\0" +"yatomi.aichi.jp\0" +"tosashimizu.kochi.jp\0" +"gs.mr.no\0" +"gd.cn\0" +"polkowice.pl\0" +"bale.museum\0" +"zara\0" +"mutsu.aomori.jp\0" +"jaworzno.pl\0doctor\0xin\0" +"chimkent.su\0sinaapp.com\0" +"nishiarita.saga.jp\0" +"cloudcontrolled.com\0" +"chrome\0aktyubinsk.su\0" +"muroto.kochi.jp\0" +"tama.tokyo.jp\0" +"hanyu.saitama.jp\0" +"s3-website.us-east-2.amazonaws.com\0" +"\xe8\x87\xba\xe7\x81\xa3\0" +"\xe7\xbd\x91\xe5\x9d\x80\0" +"\xe0\xb8\xad\xe0\xb8\x87\xe0\xb8\x84\xe0\xb9\x8c\xe0\xb8\x81\xe0\xb8\xa3.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" +"homelinux.org\0" +"noda.chiba.jp\0" +"ama.aichi.jp\0ami.ibaraki.jp\0" +"misato.akita.jp\0" +"cci.fr\0kawanishi.nara.jp\0" +"cechire.com\0" +"\xd8\xa8\xd8\xa7\xd8\xb2\xd8\xa7\xd8\xb1\0" +"newholland\0vistaprint\0" +"lucerne.museum\0" +"vibo-valentia.it\0" +"jp.eu.org\0" +"haebaru.okinawa.jp\0suginami.tokyo.jp\0" +"otofuke.hokkaido.jp\0kasuga.hyogo.jp\0" +"mydatto.net\0" +"marnardal.no\0" +"blogspot.com.cy\0" +"monster\0" +"shimane.jp\0chikugo.fukuoka.jp\0zgora.pl\0" +"komatsu\0" +"trentino.it\0yakumo.shimane.jp\0" +"tatamotors\0" +"morioka.iwate.jp\0" +"\xe9\xa3\x9f\xe5\x93\x81\0blogspot.com.ee\0" +"kherson.ua\0blogspot.com.eg\0nid.io\0" +"rendalen.no\0" +"is-a-financialadvisor.com\0" +"kouhoku.saga.jp\0" +"myasustor.com\0" +"blogspot.com.ar\0" +"vt.it\0" +"alipay\0blogspot.com.au\0" +"is-a-geek.net\0" +"youth.museum\0" +"kasuga.fukuoka.jp\0arao.kumamoto.jp\0is.gov.pl\0" +"kozow.com\0" +"daegu.kr\0*.kunden.ortsinfo.at\0" +"weber\0" +"game\0" +"umaji.kochi.jp\0" +"mr.no\0service.gov.uk\0" +"hamamatsu.shizuoka.jp\0blogspot.com.br\0" +"russia.museum\0spb.ru\0" +"coop.tt\0" +"f.bg\0is-uberleet.com\0krasnodar.su\0" +"liaison\0" +"karlsoy.no\0blogspot.com.by\0" +"sandiego.museum\0" +"republican\0" +"v\xc3\xa5ler.hedmark.no\0" +"obuse.nagano.jp\0" +"blogspot.com.co\0" +"historicalsociety.museum\0" +"masuda.shimane.jp\0" +"spb.su\0" +"oizumi.gunma.jp\0" +"wallonie.museum\0versicherung\0" +"coop.mv\0" +"coop.mw\0" +"naka.ibaraki.jp\0isahaya.nagasaki.jp\0" +"lierne.no\0utsira.no\0" +"onna.okinawa.jp\0es.leg.br\0" +"bydgoszcz.pl\0\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4\0jaguar\0" +"sochi.su\0" +"biei.hokkaido.jp\0konan.shiga.jp\0shop.th\0" +"gliwice.pl\0" +"trentinos-tirol.it\0" +"uozu.toyama.jp\0" +"dp.ua\0" +"cc.vt.us\0" +"bomlo.no\0" +"grondar.za\0dyn.home-webserver.de\0" +"gangaviika.no\0" +"okayama.jp\0" +"townnews-staging.com\0" +"parma.it\0" +"agents.aero\0doesntexist.com\0blogspot.com.es\0" +"student.aero\0engineering\0" +"college\0cloudns.asia\0" +"tgory.pl\0embaixada.st\0" +"mus.mi.us\0" +"katsuragi.wakayama.jp\0kolobrzeg.pl\0" +"shop.ro\0" +"tas.gov.au\0" +"pharmacien.fr\0sakura.chiba.jp\0" +"coop.py\0zhitomir.ua\0" +"jefferson.museum\0mangyshlak.su\0" +"georgia.museum\0" +"reggiocalabria.it\0muroran.hokkaido.jp\0" +"pomorze.pl\0lancaster\0" +"dinosaur.museum\0fyresdal.no\0" +"kvitsoy.no\0dyndns1.de\0" +"tsukiyono.gunma.jp\0" +"lo.it\0" +"zippo\0" +"shop.pl\0" +"genting\0mitsubishi\0" +"bj.cn\0" +"frei.no\0" +"hurum.no\0y.se\0" +"linkyard.cloud\0" +"antiques.museum\0" +"kimitsu.chiba.jp\0aisho.shiga.jp\0" +"coop.km\0dattorelay.com\0" +"lilly\0" +"wegrow.pl\0" +"ns.ca\0" +"fujieda.shizuoka.jp\0" +"\xe4\xba\xac\xe9\x83\xbd.jp\0" +"dielddanuorri.no\0" +"\xe9\xa6\x99\xe5\xb7\x9d.jp\0" +"kasaoka.okayama.jp\0" +"gs.va.no\0alpha.bounty-full.com\0" +"free\0" +"hyatt\0" +"mansions.museum\0" +"\xe6\xb2\x96\xe7\xb8\x84.jp\0" +"hangout\0" +"larsson.museum\0" +"osakasayama.osaka.jp\0" +"fortworth.museum\0googlecode.com\0securitytactics.com\0" +"kochi.jp\0" +"nuernberg.museum\0br\xc3\xb8nn\xc3\xb8y.no\0" +"elk.pl\0" +"caltanissetta.it\0owani.aomori.jp\0" +"\xe7\xbb\x84\xe7\xbb\x87.hk\0" +"tateyama.toyama.jp\0fbx-os.fr\0" +"hanawa.fukushima.jp\0" +"berlevag.no\0eid.no\0" +"audnedaln.no\0gitlab.io\0" +"kosei.shiga.jp\0" "namie.fukushima.jp\0" -"ama.aichi.jp\0ashiya.fukuoka.jp\0" -"takagi.nagano.jp\0webspace.rocks\0" -"suifu.ibaraki.jp\0pe.kr\0" -"andria-barletta-trani.it\0" -"fbxos.fr\0*.in.futurecms.at\0" -"nose.osaka.jp\0grong.no\0malselv.no\0" -"aknoluokta.no\0" -"ac.ae\0" -"rm.it\0" -"ciencia.bo\0ebina.kanagawa.jp\0web.za\0is-found.org\0" -"fla.no\0" -"nakagawa.tokushima.jp\0" -"textile.museum\0linkyard.cloud\0" -"taiki.hokkaido.jp\0" +"firestone\0insure\0" +"stat.no\0" +"va.it\0fudai.iwate.jp\0" +"nishikawa.yamagata.jp\0xxx\0" +"uvic.museum\0" +"dynalias.com\0" +"yokkaichi.mie.jp\0" +"mutsuzawa.chiba.jp\0uwajima.ehime.jp\0" +"kirovograd.ua\0" +"selfip.org\0" +"nittedal.no\0" +"lucania.it\0higashiizu.shizuoka.jp\0" +"asmatart.museum\0exhibition.museum\0" +"vt.us\0" +"riobranco.br\0xyz\0*.ex.ortsinfo.at\0blogspot.com.mt\0" +"aseral.no\0" +"warmia.pl\0" +"blogspot.com.ng\0" +"mizumaki.fukuoka.jp\0" +"sandoy.no\0" +"hatsukaichi.hiroshima.jp\0" +"pokrovsk.su\0" +"laspezia.it\0" +"is-certified.com\0" +"motegi.tochigi.jp\0hayakawa.yamanashi.jp\0" +"sm.ua\0" +"babia-gora.pl\0" +"bo.telemark.no\0narviika.no\0" +"he.cn\0esan.hokkaido.jp\0unzen.nagasaki.jp\0" +"vevelstad.no\0s3-fips-us-gov-west-1.amazonaws.com\0test-iserv.de\0" +"valleaosta.it\0" +"ciencia.bo\0fuossko.no\0s\xc3\xb8rreisa.no\0lib.ct.us\0" +"dyn-ip24.de\0hasura-app.io\0" +"cc.va.us\0" +"k\xc3\xa1r\xc3\xa1\xc5\xa1johka.no\0" +"nagi.okayama.jp\0gbiz\0" +"aid.pl\0" +"hole.no\0" +"nakai.kanagawa.jp\0" +"chieti.it\0" +"flatanger.no\0krodsherad.no\0" +"reggio-emilia.it\0" +"us.org\0" +"blogspot.com.tr\0" +"is-a-llama.com\0" +"enebakk.no\0scrysec.com\0" +"*.sensiosite.cloud\0" +"va.no\0k12.nm.us\0" +"kurogi.fukuoka.jp\0shingu.hyogo.jp\0" +"carrara-massa.it\0tamakawa.fukushima.jp\0" +"s3-us-west-2.amazonaws.com\0" +"kurobe.toyama.jp\0" +"shizuoka.shizuoka.jp\0" +"go-vip.co\0" +"saintlouis.museum\0" +"appspot.com\0" +"cc.az.us\0" +"hisayama.fukuoka.jp\0" +"claims\0" +"cog.mi.us\0" +"sorocaba.br\0siteleaf.net\0" +"historical.museum\0" +"us-east-2.elasticbeanstalk.com\0" +"torino.it\0" +"iveland.no\0" +"tokuyama.yamaguchi.jp\0" +"clinton.museum\0you\0groks-this.info\0" +"kiwa.mie.jp\0" +"f.se\0" +"mishima.shizuoka.jp\0" +"lutsk.ua\0here-for-more.info\0" +"s3.dualstack.ap-northeast-2.amazonaws.com\0barsyonline.com\0" +"kirkenes.no\0" +"mp.br\0" +"mup.gov.pl\0" +"flights\0" +"\xe7\x82\xb9\xe7\x9c\x8b\0" +"kunisaki.oita.jp\0" +"sdn.gov.pl\0" +"siellak.no\0" +"otsu.shiga.jp\0" +"is.eu.org\0" +"netflix\0" +"bahcavuotna.no\0\xe5\x81\xa5\xe5\xba\xb7\0potager.org\0" +"kongsberg.no\0" +"telefonica\0" +"w.bg\0" +"hasami.nagasaki.jp\0" +"homebuilt.aero\0" +"blogspot.com.uy\0" +"school.za\0stage.nodeart.io\0" +"bibai.hokkaido.jp\0" +"city.hu\0lacaixa\0" +"bofa\0" +"izumi.kagoshima.jp\0" +"monticello.museum\0cityeats\0" +"essex.museum\0tjeldsund.no\0" +"kakegawa.shizuoka.jp\0sncf\0" +"gifts\0" +"tn.it\0saitama.saitama.jp\0" +"katagami.akita.jp\0" +"it.eu.org\0" +"monza-brianza.it\0" +"js.org\0" +"yamada.fukuoka.jp\0" +"kagamiishi.fukushima.jp\0" +"bjark\xc3\xb8y.no\0bplaced.com\0" +"trd.br\0" +"aland.fi\0" +"ogi.saga.jp\0chungnam.kr\0" +"deatnu.no\0likes-pie.com\0" +"avellino.it\0" +"va.us\0moscow\0barsy.mobi\0" +"gildesk\xc3\xa5l.no\0mydrobo.com\0" +"akkeshi.hokkaido.jp\0" +"alvdal.no\0cc.gu.us\0" +"is-an-artist.com\0" +"shiroi.chiba.jp\0" +"h\xc3\xa6gebostad.no\0firmdale\0uy.com\0webhosting.be\0" +"americanexpress\0traeumtgerade.de\0" +"nishitosa.kochi.jp\0sakawa.kochi.jp\0yun\0" +"\xec\x82\xbc\xec\x84\xb1\0" +"pisz.pl\0" +"monzaebrianza.it\0yugawara.kanagawa.jp\0" +"gotpantheon.com\0" +"goldpoint\0" +"koga.fukuoka.jp\0" +"likescandy.com\0" +"ag.it\0" +"\xc3\xb8ygarden.no\0" +"ogata.akita.jp\0gangwon.kr\0" +"workshop.museum\0filegear-jp.me\0" +"consulado.st\0" +"l\xc3\xa6rdal.no\0cc.tn.us\0\xe7\xbd\x91\xe7\xab\x99\0" +"\xe7\xb5\x84\xe7\xbb\x87.hk\0marketing\0" +"fujiyoshida.yamanashi.jp\0" +"repbody.aero\0sk.ca\0ralingen.no\0" +"trust\0" +"bulsan-sudtirol.it\0" +"sasayama.hyogo.jp\0" +"lib.ee\0az.us\0" +"ofunato.iwate.jp\0shibata.miyagi.jp\0" +"\xe5\xae\xb6\xe9\x9b\xbb\0in.eu.org\0" +"andria-trani-barletta.it\0katsuragi.nara.jp\0" +"freeddns.org\0" +"belem.br\0" +"lebesby.no\0" +"consultant.aero\0amli.no\0" +"\xe5\x9f\xbc\xe7\x8e\x89.jp\0" +"ivgu.no\0viking\0" +"sebastopol.ua\0" +"author\0ddns.net\0" +"ieee\0" +"mat.br\0\xe5\xae\xae\xe5\x9f\x8e.jp\0" +"services\0" +"\xd0\xb1\xd0\xb5\xd0\xbb\0" +"sayo.hyogo.jp\0shiiba.miyazaki.jp\0zip\0buyshouses.net\0" +"wmflabs.org\0" +"from-or.com\0" +"moma.museum\0homeoffice.gov.uk\0" +"children.museum\0" +"balsan-sudtirol.it\0" +"winners\0" +"is-very-evil.org\0" +"\xe9\xa4\x90\xe5\x8e\x85\0from-pr.com\0" +"gj\xc3\xb8vik.no\0appchizi.com\0" +"miyazaki.miyazaki.jp\0shiroishi.saga.jp\0anquan\0channel\0" +"prd.fr\0koganei.tokyo.jp\0" +"boleslawiec.pl\0exposed\0" +"nishi.osaka.jp\0sagae.yamagata.jp\0bond\0" +"iwama.ibaraki.jp\0" +"surgery\0servep2p.com\0" +"ayase.kanagawa.jp\0" +"maintenance.aero\0" +"yawata.kyoto.jp\0" +"skjak.no\0vuelos\0" +"vr.it\0kunohe.iwate.jp\0" +"brussels.museum\0os.hedmark.no\0sk\xc3\xa5nland.no\0eu.meteorapp.com\0" +"minamiise.mie.jp\0" +"hagebostad.no\0" +"rishiri.hokkaido.jp\0wzmiuw.gov.pl\0" +"floripa.br\0namegata.ibaraki.jp\0xerox\0from-co.net\0" +"fr.it\0higashikagura.hokkaido.jp\0saku.nagano.jp\0" +"lib.il.us\0book\0" +"saigawa.fukuoka.jp\0" +"sirdal.no\0linde\0myjino.ru\0" +"poker\0" +"d.bg\0is-an-entertainer.com\0is-not-certified.com\0" +"serveftp.net\0" +"medecin.km\0" +"yaotsu.gifu.jp\0" +"vagsoy.no\0" +"campidano-medio.it\0kamijima.ehime.jp\0" +"gotsu.shimane.jp\0" +"onthewifi.com\0" +"\xd8\xa8\xda\xbe\xd8\xa7\xd8\xb1\xd8\xaa\0" +"gu.us\0\xd0\xbe\xd0\xbd\xd0\xbb\xd0\xb0\xd0\xb9\xd0\xbd\0" +"trentinosud-tirol.it\0firenze.it\0\xe3\x83\x9d\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\x88\0" +"yamanashi.yamanashi.jp\0realm.cz\0" +"cruises\0" +"dn.ua\0bharti\0" +"tynset.no\0" +"\xd8\xa7\xd9\x84\xd8\xac\xd8\xb2\xd8\xa7\xd8\xa6\xd8\xb1\0" +"tn.us\0" +"prd.km\0r\xc3\xb8yken.no\0" +"t3l3p0rt.net\0" +"plants.museum\0" +"vall\xc3\xa9""e-d-aoste.it\0nagaoka.niigata.jp\0rybnik.pl\0" +"yasu.shiga.jp\0" +"randaberg.no\0" +"\xeb\x8b\xb7\xeb\x84\xb7\0" +"ot.it\0pd.it\0\xe5\x92\x8c\xe6\xad\x8c\xe5\xb1\xb1.jp\0" +"hitachinaka.ibaraki.jp\0" +"b\xc3\xa1id\xc3\xa1r.no\0k12.oh.us\0" +"alstahaug.no\0" +"\xd5\xb0\xd5\xa1\xd5\xb5\0\xd0\xbe\xd1\x80\xd0\xb3.\xd1\x81\xd1\x80\xd0\xb1\0" +"yamatokoriyama.nara.jp\0dentist\0" +"lib.az.us\0" +"taiki.hokkaido.jp\0kitayama.wakayama.jp\0" +"prd.mg\0bahccavuotna.no\0" +"a.ssl.fastly.net\0" +"ushistory.museum\0" +"is-an-actress.com\0" +"fedje.no\0gop.pk\0" +"kikugawa.shizuoka.jp\0" +"kvits\xc3\xb8y.no\0" +"slz.br\0" +"castres.museum\0training\0lebtimnetz.de\0" +"shimonoseki.yamaguchi.jp\0" +"architecture.museum\0" +"lib.ms.us\0lib.nc.us\0" +"dev-myqnapcloud.com\0" +"\xe0\xa8\xad\xe0\xa8\xbe\xe0\xa8\xb0\xe0\xa8\xa4\0" +"w.se\0" +"broker\0" +"database.museum\0" +"soka.saitama.jp\0norton\0" +"kushima.miyazaki.jp\0" +"\xe9\x9b\x86\xe5\x9b\xa2\0" +"sjc.br\0" +"emilia-romagna.it\0" +"spy.museum\0s3-ap-northeast-2.amazonaws.com\0" +"kasamatsu.gifu.jp\0" +"kagoshima.kagoshima.jp\0" +"pa.gov.br\0" +"s3-ap-southeast-2.amazonaws.com\0" +"xbox\0*.futurecms.at\0" +"*.sendai.jp\0" +"abbott\0" +"fjaler.no\0" +"b\xc3\xa6rum.no\0" +"minoh.osaka.jp\0" +"agrar.hu\0" +"markets\0" +"computerhistory.museum\0notteroy.no\0" +"kaita.hiroshima.jp\0" +"indianmarket.museum\0lib.wa.us\0" +"naklo.pl\0" +"taa.it\0" +"luster.no\0" +"pb.gov.br\0" +"ybo.party\0" +"sand\xc3\xb8y.no\0" +"lib.ga.us\0" +"vall\xc3\xa9""edaoste.it\0ichikawa.chiba.jp\0" +"mini\0" +"yusui.kagoshima.jp\0schokokeks.net\0" +"automotive.museum\0" +"kunstunddesign.museum\0barum.no\0" +"nasushiobara.tochigi.jp\0" +"from-ar.com\0" +"amakusa.kumamoto.jp\0kai.yamanashi.jp\0" +"miyake.nara.jp\0mint\0" +"aviation.museum\0fauske.no\0" +"zlg.br\0shiriuchi.hokkaido.jp\0" +"askvoll.no\0" +"tmall\0" +"ngo.lk\0poltava.ua\0" +"s3.ap-northeast-2.amazonaws.com\0" +"tenei.fukushima.jp\0spiegel\0" +"kinokawa.wakayama.jp\0" +"gs.cn\0experts-comptables.fr\0toride.ibaraki.jp\0" +"jewishart.museum\0ivano-frankivsk.ua\0sohu\0" +"wuoz.gov.pl\0" +"palmsprings.museum\0dnepropetrovsk.ua\0" +"koeln\0" +"mallorca.museum\0" +"nirasaki.yamanashi.jp\0bayern\0" +"m\xc3\xa1tta-v\xc3\xa1rjjat.no\0ck.ua\0" +"fetsund.no\0" +"medical.museum\0blogsite.org\0" +"komono.mie.jp\0powiat.pl\0" +"ath.cx\0" +"piw.gov.pl\0" +"\xe5\xb3\xb6\xe6\xa0\xb9.jp\0glogow.pl\0nat.tn\0" +"natural.bo\0mosjoen.no\0" +"akiruno.tokyo.jp\0bplaced.net\0" +"taito.tokyo.jp\0" +"beskidy.pl\0" +"film.museum\0" +"sellsyourhome.org\0" +"foodnetwork\0" +"boavista.br\0saogonca.br\0yabu.hyogo.jp\0" +"aomori.jp\0" +"sakata.yamagata.jp\0" +"\xe0\xae\x9a\xe0\xae\xbf\xe0\xae\x99\xe0\xaf\x8d\xe0\xae\x95\xe0\xae\xaa\xe0\xaf\x8d\xe0\xae\xaa\xe0\xaf\x82\xe0\xae\xb0\xe0\xaf\x8d\0" +"sera.hiroshima.jp\0psse.gov.pl\0" +"safety\0*.platformsh.site\0" +"\xe7\xa6\x8f\xe5\xb2\xa1.jp\0ngo.ph\0travelchannel\0" +"express\0s3.dualstack.ap-southeast-1.amazonaws.com\0" +"kv\xc3\xa6""fjord.no\0" +"slg.br\0" +"ventures\0" +"sakuho.nagano.jp\0utsunomiya.tochigi.jp\0" +"audible\0" +"yanagawa.fukuoka.jp\0" +"kashiwara.osaka.jp\0a.prod.fastly.net\0" +"homedns.org\0" +"lib.md.us\0" +"*.ex.futurecms.at\0" +"gaivuotna.no\0k12.in.us\0" +"protection\0" +"engineer.aero\0lavangen.no\0" +"opencraft.hosting\0" +"olayangroup\0" +"celtic.museum\0d.se\0" +"\xe6\x9c\xba\xe6\x9e\x84\0" +"and.museum\0" +"kanzaki.saga.jp\0" +"principe.st\0" +"politie\0song\0" +"\xd8\xb9\xd8\xb1\xd8\xa7\xd9\x82\0" +"cheltenham.museum\0marker.no\0" +"\xc3\xa5""fjord.no\0" +"daejeon.kr\0" +"mizusawa.iwate.jp\0" +"sony\0" +"gru.br\0tosa.kochi.jp\0" +"barlettatraniandria.it\0" +"if.ua\0" +"u.bg\0" +"shimamaki.hokkaido.jp\0" +"h\xc3\xb8ylandet.no\0" +"bible\0ferrari\0" +"vana\0" +"medecin.fr\0" +"pyatigorsk.ru\0" +"\xe9\xa6\x99\xe6\xb8\xaf\0statefarm\0today\0" +"kutno.pl\0" +"education.museum\0is-a-player.com\0" +"!city.kobe.jp\0bialowieza.pl\0frontdoor\0" +"ap-southeast-2.elasticbeanstalk.com\0" +"firewall-gateway.net\0" +"presse.km\0mozilla-iot.org\0" +"airguard.museum\0hzc.io\0" +"arteducation.museum\0research.museum\0" +"tsushima.nagasaki.jp\0" +"karacol.su\0" +"ishigaki.okinawa.jp\0" +"freight.aero\0\xc3\xb8rland.no\0" +"dnsdojo.com\0" +"selfip.biz\0hasura.app\0" +"tozsde.hu\0vlaanderen.museum\0" +"nakasatsunai.hokkaido.jp\0" +"\xe6\x84\x9b\xe7\x9f\xa5.jp\0mihama.aichi.jp\0matsudo.chiba.jp\0tachikawa.tokyo.jp\0" +"toyonaka.osaka.jp\0" +"ws.na\0" +"tomisato.chiba.jp\0takahashi.okayama.jp\0matsuzaki.shizuoka.jp\0" +"presse.ml\0" +"gouv.fr\0" +"cafe\0" +"ascolipiceno.it\0" +"pu.it\0" +"osaka\0" +"demon.nl\0" +"lotte\0pt.eu.org\0" +"sortland.no\0" +"nord-odal.no\0" +"servebeer.com\0" +"lotto\0" +"kazo.saitama.jp\0" +"nalchik.ru\0" +"pi.gov.br\0vlaanderen\0" +"dsmynas.com\0" +"kepno.pl\0" +"childrens.museum\0" +"gouv.ht\0" +"api.stdlib.com\0" +"\xce\xb5\xce\xbb\0" +"mn.it\0\xe5\x8c\x97\xe6\xb5\xb7\xe9\x81\x93.jp\0" +"pb.ao\0fylkesbibl.no\0" +"fusa.no\0ngo.za\0nalchik.su\0" +"dodge\0" +"or.at\0" +"grue.no\0" +"kazimierz-dolny.pl\0" +"or.bi\0" +"se.net\0ru.net\0" +"scientist.aero\0" +"gouv.bj\0" +"selje.no\0" +"sopot.pl\0" +"spdns.eu\0" +"shimotsuma.ibaraki.jp\0tanabe.wakayama.jp\0intl.tn\0dev.static.land\0" +"taka.hyogo.jp\0shimokitayama.nara.jp\0" +"or.ci\0" +"szex.hu\0chesapeakebay.museum\0" +"gouv.ci\0" +"sener\0" +"kraanghke.no\0" +"or.cr\0nakano.tokyo.jp\0" +"lib.ky.us\0" +"\xd8\xa7\xd8\xaa\xd8\xb5\xd8\xa7\xd9\x84\xd8\xa7\xd8\xaa\0" +"microlight.aero\0ollo\0" +"ota.gunma.jp\0himeshima.oita.jp\0" +"tokashiki.okinawa.jp\0" +"nsw.edu.au\0" +"\xe7\x86\x8a\xe6\x9c\xac.jp\0" +"botanical.museum\0" +"house.museum\0" +"cc.mn.us\0" +"ogaki.gifu.jp\0" +"gran.no\0" +"shinichi.hiroshima.jp\0nadex\0" +"ibigawa.gifu.jp\0" +"koto.tokyo.jp\0" +"steam.museum\0" +"arakawa.tokyo.jp\0" +"medicina.bo\0" +"turek.pl\0call\0" +"apps.fbsbx.com\0" +"*.dapps.earth\0" +"utazu.kagawa.jp\0" +"assassination.museum\0zero\0" +"\xe7\xbd\x91\xe7\xb5\xa1.hk\0" +"himi.toyama.jp\0" +"k12.fl.us\0" +"sar.it\0ichihara.chiba.jp\0unazuki.toyama.jp\0" +"furniture\0" +"id.au\0b.bg\0" +"nissan\0" +"bjarkoy.no\0azurecontainer.io\0" +"camp\0" +"mykolaiv.ua\0" +"online.museum\0is-a-hunter.com\0" +"b.br\0" +"far.br\0" +"nissay\0" +"wpcomstaging.com\0" +"starachowice.pl\0" +"si.it\0" +"erotika.hu\0garden.museum\0" +"nikon\0" +"cultural.museum\0issmarterthanyou.com\0" +"egyptian.museum\0\xe5\x98\x89\xe9\x87\x8c\xe5\xa4\xa7\xe9\x85\x92\xe5\xba\x97\0" +"misato.miyagi.jp\0weatherchannel\0" +"br\xc3\xb8nn\xc3\xb8ysund.no\0" +"ci.it\0karpacz.pl\0" +"dynvpn.de\0" +"togo.aichi.jp\0" +"trader.aero\0k12.as.us\0" +"sannohe.aomori.jp\0mizunami.gifu.jp\0hu.net\0" +"cambridge.museum\0lewismiller.museum\0svn-repos.de\0" +"pe.gov.br\0nosegawa.nara.jp\0cieszyn.pl\0hicam.net\0" +"spdns.de\0" +"or.id\0" +"otsuchi.iwate.jp\0" +"jessheim.no\0" +"chernivtsi.ua\0kyoto\0from-nm.com\0" +"macerata.it\0" +"kr.com\0" +"takanezawa.tochigi.jp\0" +"london.museum\0bod\xc3\xb8.no\0is-a-conservative.com\0" +"or.it\0" +"desa.id\0mar.it\0" +"k12.nv.us\0nis.za\0" +"zappos\0" +"aurskog-holand.no\0skiptvet.no\0my-gateway.de\0" +"or.jp\0shiogama.miyagi.jp\0bungotakada.oita.jp\0" +"clock.museum\0strand.no\0" +"higashiyamato.tokyo.jp\0oguni.yamagata.jp\0" +"andasuolo.no\0" +"musica.ar\0shimamoto.osaka.jp\0" +"or.ke\0" +"mikawa.yamagata.jp\0" +"sumy.ua\0care\0selfip.com\0" +"gon.pk\0dst.mi.us\0" +"sokndal.no\0s3-website-us-east-1.amazonaws.com\0" +"from-az.net\0" +"ikeda.osaka.jp\0" +"musica.bo\0" +"takaoka.toyama.jp\0or.kr\0fund\0" +"casa\0" +"cars\0" +"nishiaizu.fukushima.jp\0kusu.oita.jp\0minato.osaka.jp\0bieszczady.pl\0spot\0" +"case\0gr.com\0" +"nayoro.hokkaido.jp\0" +"lib.ne.us\0" +"cash\0" +"owariasahi.aichi.jp\0" +"utazas.hu\0" +"decorativearts.museum\0sigdal.no\0" +"mattel\0" +"u.se\0gb.com\0" +"shiraoka.saitama.jp\0gent\0" +"bauhaus\0" +"artcenter.museum\0cc.or.us\0serveftp.org\0shacknet.nu\0" +"jdf.br\0" +"collegefan.org\0" +"isen.kagoshima.jp\0" +"b\xc3\xb8.telemark.no\0" +"tsuruta.aomori.jp\0" +"mn.us\0" +"higashiyoshino.nara.jp\0" +"or.na\0" +"tochigi.jp\0osakikamijima.hiroshima.jp\0kitagata.saga.jp\0" +"or.mu\0" +"enonic.io\0" +"texas.museum\0leclerc\0" +"id.ir\0habikino.osaka.jp\0" +"qa2.com\0" +"pa.gov.pl\0" +"air-surveillance.aero\0axis.museum\0marine.ru\0" +"ricoh\0" +"ballangen.no\0" +"odessa.ua\0careers\0" +"palermo.it\0" +"kitahata.saga.jp\0" +"br.com\0" +"\xe9\x95\xb7\xe5\xb4\x8e.jp\0" +"campania.it\0hirogawa.wakayama.jp\0" +"macapa.br\0yura.wakayama.jp\0" +"my-wan.de\0" +"k\xc3\xa5""fjord.no\0ar.com\0" +"aisai.aichi.jp\0sanda.hyogo.jp\0" +"trentin-s\xc3\xbc""dtirol.it\0" +"estate.museum\0ringerike.no\0" +"dyndns-at-home.com\0is-a-libertarian.com\0" +"jx.cn\0" +"newyork.museum\0" +"yuzawa.niigata.jp\0" +"hitachiomiya.ibaraki.jp\0test.tj\0" +"k12.co.us\0linkitools.space\0" +"or.pw\0" +"fukui.jp\0mitaka.tokyo.jp\0" +"\xe0\xac\xad\xe0\xac\xbe\xe0\xac\xb0\xe0\xac\xa4\0" +"is-a-blogger.com\0" +"kijo.miyazaki.jp\0id.lv\0" +"cc.id.us\0" +"id.ly\0" +"altoadige.it\0" +"hirara.okinawa.jp\0" +"hapmir.no\0" +"obira.hokkaido.jp\0kochi.kochi.jp\0higashiyodogawa.osaka.jp\0" +"damnserver.com\0" +"yame.fukuoka.jp\0ina.saitama.jp\0lowicz.pl\0" +"war.museum\0" +"omigawa.chiba.jp\0datsun\0" +"modalen.no\0k12.pr.us\0tattoo\0karelia.su\0" +"grajewo.pl\0" +"sanofi\0" +"ha.cn\0" +"academy\0filegear-gb.me\0" +"pr.gov.br\0tsukumi.oita.jp\0" +"stjordalshalsen.no\0komforb.se\0" +"av.it\0sunagawa.hokkaido.jp\0iijima.nagano.jp\0" +"ishinomaki.miyagi.jp\0" +"stord.no\0" +"sakai.osaka.jp\0" +"gouv.rw\0" +"psc.br\0" +"test.ru\0" +"kakogawa.hyogo.jp\0" +"budejju.no\0" +"kariwa.niigata.jp\0iide.yamagata.jp\0" +"gouv.sn\0" +"kameoka.kyoto.jp\0" +"uchinada.ishikawa.jp\0or.th\0observer\0" +"tj.cn\0handa.aichi.jp\0kaga.ishikawa.jp\0" +"snillfjord.no\0" +"idf.il\0tuscany.it\0" +"azure\0" +"no.it\0" +"ac.ae\0lib.pa.us\0" +"presse.ci\0k12.ma.us\0\xe0\xa4\xa8\xe0\xa5\x87\xe0\xa4\x9f\0" +"kasama.ibaraki.jp\0" +"tec.mi.us\0" +"karuizawa.nagano.jp\0" +"photography\0" +"reisen\0\xe5\x95\x86\xe5\x9f\x8e\0" +"or.ug\0" +"hamatonbetsu.hokkaido.jp\0tomari.hokkaido.jp\0kita.tokyo.jp\0select\0" +"or.tz\0" +"mayfirst.info\0" "ac.at\0" "ac.be\0" -"minakami.gunma.jp\0" -"torino.it\0ikeda.gifu.jp\0" -"uz.ua\0ford\0" -"kl\xc3\xa6""bu.no\0" -"withgoogle.com\0" -"kitakata.miyazaki.jp\0nikko.tochigi.jp\0bialystok.pl\0" -"veneto.it\0*.kobe.jp\0kawai.nara.jp\0" -"hk.com\0" -"h\xc3\xa5.no\0cloudns.org\0" -"ac.ci\0" -"ltd.cy\0plc.co.im\0hikimi.shimane.jp\0comcast\0" -"site\0" -"ac.cn\0\xe5\xa4\xa7\xe9\x98\xaa.jp\0" -"aosta.it\0" -"ambulance.aero\0!city.sapporo.jp\0" -"ac.cr\0cuneo.it\0" -"bolivia.bo\0meland.no\0us-4.evennode.com\0" -"ac.cy\0tsubetsu.hokkaido.jp\0" -"public.museum\0" -"habmer.no\0" -"sakyo.kyoto.jp\0eastafrica.museum\0square.museum\0" -"shintomi.miyazaki.jp\0russia.museum\0" -"gorlice.pl\0" -"tamba.hyogo.jp\0norton\0" -"tomika.gifu.jp\0" -"blog\0" -"12hp.de\0" -"\xd0\xb1\xd0\xb5\xd0\xbb\0" -"music.museum\0" -"yoga\0" -"nanporo.hokkaido.jp\0meet\0" -"mazury.pl\0" -"inashiki.ibaraki.jp\0" -"ltd.gi\0adv.mz\0hosting-cluster.nl\0" -"tsuga.tochigi.jp\0" -"suita.osaka.jp\0ap-northeast-3.elasticbeanstalk.com\0" -"qh.cn\0kiwa.mie.jp\0" -"nome.pt\0" -"perso.ht\0nexus\0" -"arts.ve\0netbank\0""12hp.at\0" -"sicilia.it\0" -"ac.gn\0quebec.museum\0rovno.ua\0ltd.hk\0" -"anan.tokushima.jp\0" -"nantan.kyoto.jp\0" -"walbrzych.pl\0" -"us-3.evennode.com\0" -"ina.ibaraki.jp\0labor.museum\0skjervoy.no\0wellbeingzone.eu\0" -"rodoy.no\0" -"cc.ks.us\0" -"berg.no\0singles\0mk.eu.org\0" -"akaiwa.okayama.jp\0" +"rovigo.it\0ise.mie.jp\0" +"qc.ca\0" +"or.us\0" +"laquila.it\0gamagori.aichi.jp\0foundation\0" +"taira.toyama.jp\0" +"valle-daosta.it\0" +"barclaycard\0" +"cloudcontrolapp.com\0" +"hasvik.no\0" +"takaharu.miyazaki.jp\0" +"cisco\0" +"hatoyama.saitama.jp\0credit\0" +"ac.ci\0malselv.no\0" +"ullensvang.no\0" +"ac.cn\0gallup\0" +"\xe9\x9d\x92\xe6\xa3\xae.jp\0minami-alps.yamanashi.jp\0" +"g\xc3\xa1ivuotna.no\0b.se\0" +"ac.cr\0" +"baths.museum\0balat.no\0" +"liguria.it\0kanan.osaka.jp\0" +"ac.cy\0forum.hu\0" +"is-a-knight.org\0" +"pol.dz\0kitakata.fukushima.jp\0iizuna.nagano.jp\0" +"presse.fr\0" +"tsugaru.aomori.jp\0" +"talk\0" +"sandnes.no\0" +"graphics\0" +"carraramassa.it\0" +"lipsy\0" +"iiyama.nagano.jp\0nyuzen.toyama.jp\0" +"network\0" +"s.bg\0chocolate.museum\0labour.museum\0marburg.museum\0kongsvinger.no\0" +"bnpparibas\0" +"kashiba.nara.jp\0parliament.nz\0chrysler\0poznan.pl\0" +"kiwi\0" +"gdynia.pl\0" +"barueri.br\0" +"\xd0\xbf\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0" +"kamaishi.iwate.jp\0" +"id.us\0lasalle\0" +"warszawa.pl\0" +"sciencecenter.museum\0yodobashi\0myiphost.com\0" +"is-a-republican.com\0" +"chikujo.fukuoka.jp\0usa.oita.jp\0" +"lib.ut.us\0" +"gorizia.it\0ozu.kumamoto.jp\0" +"franziskaner.museum\0mein-vigor.de\0" +"cbre\0" +"ac.gn\0friuli-v-giulia.it\0kuki.saitama.jp\0" +"bentley\0" +"cz.it\0" +"gouv.km\0froland.no\0" +"pol.ht\0worse-than.tv\0" +"s3-website-eu-west-1.amazonaws.com\0" +"salerno.it\0" +"mino.gifu.jp\0\xe8\x81\x94\xe9\x80\x9a\0" +"atami.shizuoka.jp\0" +"building.museum\0flanders.museum\0""12hp.de\0" +"ac.id\0kira.aichi.jp\0flt.cloud.muni.cz\0" +"suldal.no\0" +"british.museum\0reg.dk\0" +"\xe6\x97\xb6\xe5\xb0\x9a\0" +"journal.aero\0" +"ac.il\0poniatowa.pl\0" +"ac.im\0vang.no\0" +"ac.in\0" +"\xd8\xa7\xd9\x84\xd9\x85\xd8\xba\xd8\xb1\xd8\xa8\0" +"ac.ir\0kagawa.jp\0\xe6\x84\x9b\xe5\xaa\x9b.jp\0" +"coal.museum\0davvesiida.no\0knowsitall.info\0" +"\xe7\xbe\xa4\xe9\xa6\xac.jp\0asahi.chiba.jp\0bato.tochigi.jp\0" +"gouv.ml\0" +"ha.no\0" +"av.tr\0" +"n\xc3\xa5\xc3\xa5mesjevuemie.no\0" +"mashike.hokkaido.jp\0" +"fuoisku.no\0" +"ac.jp\0isa.kagoshima.jp\0" +"portland.museum\0doesntexist.org\0" +"12hp.at\0" +"ac.ke\0" +"mol.it\0saroma.hokkaido.jp\0ohda.shimane.jp\0" +"\xe6\xa0\x83\xe6\x9c\xa8.jp\0" +"schweiz.museum\0duck\0" +"leg.br\0kuromatsunai.hokkaido.jp\0" +"ryugasaki.ibaraki.jp\0" +"ainan.ehime.jp\0wakasa.fukui.jp\0" +"sumoto.kumamoto.jp\0" +"murayama.yamagata.jp\0ac.kr\0" +"portlligat.museum\0" "12hp.ch\0" -"analytics\0" -"gwangju.kr\0" -"ac.id\0" -"arakawa.saitama.jp\0us.com\0" -"mail.pl\0" -"tobetsu.hokkaido.jp\0kuju.oita.jp\0" -"furniture\0" -"lug.org.uk\0" -"ac.il\0" -"ac.im\0watarai.mie.jp\0flanders.museum\0" -"ac.in\0africa.com\0" -"logistics.aero\0progressive\0space-to-rent.com\0" -"*.elb.amazonaws.com.cn\0" -"ac.ir\0is-a-landscaper.com\0" -"lukow.pl\0" -"kamisato.saitama.jp\0" -"manchester.museum\0" -"bible\0" -"arts.museum\0author\0" -"ac.jp\0uda.nara.jp\0" -"langev\xc3\xa5g.no\0" -"ichikawa.hyogo.jp\0gyokuto.kumamoto.jp\0chernovtsy.ua\0" -"ac.ke\0blue\0" -"uw.gov.pl\0from-hi.com\0" -"toshima.tokyo.jp\0steinkjer.no\0dp.ua\0" -"hk.cn\0" -"oga.akita.jp\0" -"\xc3\xa1k\xc5\x8boluokta.no\0" -"imperia.it\0ltd.lk\0" +"aircraft.aero\0navigation.aero\0" +"ac.lk\0" +"finance\0" +"usr.cloud.muni.cz\0" +"betainabox.com\0" +"ac.ma\0" +"trentino-alto-adige.it\0nonoichi.ishikawa.jp\0" +"ac.ls\0" +"ac.me\0mywire.org\0" +"yuki.ibaraki.jp\0nantan.kyoto.jp\0" +"stjohn.museum\0bplaced.de\0" +"hanamaki.iwate.jp\0" +"pittsburgh.museum\0" +"educator.aero\0" +"muenster.museum\0taifun-dns.de\0" +"blanco\0" +"ac.mu\0kh.ua\0" +"ac.mw\0" +"ascoli-piceno.it\0" +"uslivinghistory.museum\0ac.ni\0" +"trentin-sud-tirol.it\0ac.mz\0" +"svalbard.no\0" +"giize.com\0customer.speedpartner.de\0dyn-vpn.de\0" +"inuyama.aichi.jp\0po.gov.pl\0" +"mortgage\0toshiba\0" +"cagliari.it\0sharp\0\xe7\xbd\x91\xe7\xbb\x9c\0" +"ggee\0" +"pug.it\0ac.nz\0" +"ac.pa\0" +"shibukawa.gunma.jp\0" +"sorum.no\0" +"fukuchi.fukuoka.jp\0" +"sarpsborg.no\0" +"vestnes.no\0chase\0" +"tarumizu.kagoshima.jp\0shimane.shimane.jp\0" +"farm.museum\0ilovecollege.info\0" +"hitachi\0" +"education\0" +"taxi\0" +"date.fukushima.jp\0ac.pr\0" +"barrell-of-knowledge.info\0" +"dealer\0" +"fishing\0" +"trentin-sued-tirol.it\0nanae.hokkaido.jp\0akashi.hyogo.jp\0sumida.tokyo.jp\0" +"selbu.no\0" +"rost.no\0" +"tomika.gifu.jp\0" +"ookuwa.nagano.jp\0hachijo.tokyo.jp\0" +"silk.museum\0" +"mjondalen.no\0k12.ri.us\0uk.com\0" +"hidaka.hokkaido.jp\0" +"austevoll.no\0" +"iyo.ehime.jp\0" +"plurinacional.bo\0" +"kanagawa.jp\0" +"is-a-cpa.com\0" +"aerodrome.aero\0" +"operaunite.com\0" +"zuerich\0" +"hol.no\0ac.rs\0" +"nord-fron.no\0ac.ru\0ac.se\0lighting\0eu.org\0" +"kujukuri.chiba.jp\0tara.saga.jp\0" +"ac.rw\0" +"yugawa.fukushima.jp\0dyndns.biz\0" +"sauherad.no\0accountants\0" +"eniwa.hokkaido.jp\0" +"gol.no\0bridgestone\0dyndns-pics.com\0point2this.com\0" +"takahama.fukui.jp\0" +"skierv\xc3\xa1.no\0\xd2\x9b\xd0\xb0\xd0\xb7\0" +"iitate.fukushima.jp\0otoyo.kochi.jp\0" +"tatsuno.nagano.jp\0ibaraki.osaka.jp\0" +"clinique\0" +"pol.tr\0kosher\0" +"ac.th\0" +"mazury.pl\0slask.pl\0ac.sz\0ac.tj\0" +"rhcloud.com\0" +"natura\0" +"okaya.nagano.jp\0b.ssl.fastly.net\0" +"lunner.no\0aetna\0s3-website.eu-central-1.amazonaws.com\0" +"fuchu.toyama.jp\0salon\0ma.leg.br\0" +"divttasvuotna.no\0" +"campobasso.it\0inagi.tokyo.jp\0" +"ac.ug\0" +"bristol.museum\0" +"ac.tz\0" +"ac.uk\0" +"matsue.shimane.jp\0" +"abiko.chiba.jp\0qpon\0" +"aarp\0" +"mobile\0" +"oji.nara.jp\0" +"ae.org\0" +"li.it\0" +"glass.museum\0" +"serveminecraft.net\0" +"amber.museum\0" +"hirado.nagasaki.jp\0\xe5\x8f\xb0\xe6\xb9\xbe\0in.net\0" +"ac.vn\0" +"fussa.tokyo.jp\0\xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0\0" +"ltd.cy\0money.museum\0s.se\0duns\0" +"minamifurano.hokkaido.jp\0" +"glas.museum\0" +"mihama.mie.jp\0" +"degree\0mobily\0\xe5\x9c\xa8\xe7\xba\xbf\0logoip.de\0" +"e4.cz\0" +"fashion\0" +"realty\0" +"from-nh.com\0" +"recife.br\0nm.cn\0" +"rio.br\0ueno.gunma.jp\0" +"citic\0from-oh.com\0" +"blogspot.vn\0" +"ca-central-1.elasticbeanstalk.com\0" +"viterbo.it\0shingu.fukuoka.jp\0" +"chuo.chiba.jp\0urakawa.hokkaido.jp\0" +"dvag\0" +"fst.br\0tsunan.niigata.jp\0" +"stockholm.museum\0" +"kobayashi.miyazaki.jp\0\xe5\xa8\xb1\xe4\xb9\x90\0" +"cc.ky.us\0" +"bizen.okayama.jp\0" +"koshimizu.hokkaido.jp\0shinjo.nara.jp\0" +"trading\0from-tx.com\0" +"ltd.gi\0ac.za\0al.eu.org\0" +"gamo.shiga.jp\0" +"rovno.ua\0hk.com\0" "yatsushiro.kumamoto.jp\0" -"\xd9\x87\xd9\x85\xd8\xb1\xd8\xa7\xd9\x87\0" -"cnpy.gdn\0" -"ac.kr\0" -"arts.ro\0" -"us-2.evennode.com\0" -"shinkamigoto.nagasaki.jp\0" -"warman\0barsyonline.com\0" +"vn.ua\0richardli\0" +"taishi.osaka.jp\0kaufen\0" +"bearalv\xc3\xa1hki.no\0ac.zm\0" +"chirurgiens-dentistes.fr\0rebun.hokkaido.jp\0" +"state.museum\0" +"equipment.aero\0" +"k12.de.us\0ltd.hk\0" +"setagaya.tokyo.jp\0" +"ac.zw\0" +"pvh.br\0firm.ht\0bbs.tr\0\xe5\x85\xab\xe5\x8d\xa6\0" +"grandrapids.museum\0enterprises\0" +"a\xc3\xa9roport.ci\0\xe4\xb8\xad\xe6\x96\x87\xe7\xbd\x91\0nodum.co\0" +"bolt.hu\0technology\0" +"firm.in\0hiroo.hokkaido.jp\0kadoma.osaka.jp\0" +"isernia.it\0" +"act.au\0" +"agrigento.it\0" +"drammen.no\0troandin.no\0pl.eu.org\0blogspot.re\0" +"shioya.tochigi.jp\0mitou.yamaguchi.jp\0" +"badaddja.no\0" +"nogata.fukuoka.jp\0tonosho.kagawa.jp\0minamioguni.kumamoto.jp\0opoczno.pl\0" +"go.ci\0" +"shitara.aichi.jp\0" +"beats\0meteorapp.com\0" +"kumano.hiroshima.jp\0" +"leksvik.no\0blogspot.ro\0" +"maniwa.okayama.jp\0health\0" +"londrina.br\0go.cr\0at.it\0yoichi.hokkaido.jp\0" +"oygarden.no\0blogspot.rs\0" +"zgorzelec.pl\0" +"airbus\0blogspot.ru\0blogspot.se\0" +"blogspot.sg\0" +"andriabarlettatrani.it\0" +"stj\xc3\xb8rdal.no\0blogspot.si\0" +"blogspot.sk\0" +"alto-adige.it\0" +"filegear-sg.me\0nodum.io\0" +"blogspot.sn\0" +"firm.co\0" +"kerryproperties\0dd-dns.de\0" +"fuchu.hiroshima.jp\0blogspot.td\0" +"temp-dns.com\0" +"sx.cn\0tokai.aichi.jp\0" +"ninja\0" +"marylhurst.museum\0science-fiction.museum\0" +"tozawa.yamagata.jp\0oshino.yamanashi.jp\0" +"casino.hu\0firm.dk\0" +"ac.gov.br\0mw.gov.pl\0" +"ltd.lk\0hyundai\0" +"kosai.shizuoka.jp\0kainan.wakayama.jp\0" +"shintomi.miyazaki.jp\0raid\0" +"lorenskog.no\0able\0cust.dev.thingdust.io\0" +"hanno.saitama.jp\0" +"rennebu.no\0blogspot.tw\0blogspot.ug\0" +"nakayama.yamagata.jp\0" +"nishio.aichi.jp\0" +"origins\0dyn.cosidns.de\0abkhazia.su\0tula.su\0" +"dattolocal.net\0" +"baseball.museum\0vantaa.museum\0os\xc3\xb8yro.no\0" +"\xe3\x82\xb9\xe3\x83\x88\xe3\x82\xa2\0blogspot.mr\0" +"quicksytes.com\0" +"sex.hu\0agriculture.museum\0" +"muni.il\0kikuchi.kumamoto.jp\0\xe5\xa4\xa7\xe4\xbc\x97\xe6\xb1\xbd\xe8\xbd\xa6\0" +"blogspot.mx\0" +"blogspot.my\0" +"bci.dnstrace.pro\0" +"blogspot.nl\0" +"qld.edu.au\0" +"ikusaka.nagano.jp\0" +"blogspot.no\0" +"\xc3\xb8yer.no\0" +"ms.gov.br\0otobe.hokkaido.jp\0" +"sakaki.nagano.jp\0" +"knx-server.net\0" +"cc.nm.us\0" +"moriya.ibaraki.jp\0" +"miyawaka.fukuoka.jp\0" +"sciencehistory.museum\0circle\0" +"go.id\0" +"burghof.museum\0donetsk.ua\0ky.us\0blogspot.pe\0" +"bio.br\0" +"izunokuni.shizuoka.jp\0" +"frogans\0spdns.org\0" +"york.museum\0k12.va.us\0ap-northeast-3.elasticbeanstalk.com\0" +"takanabe.miyazaki.jp\0\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" +"isehara.kanagawa.jp\0auspost\0" +"blogspot.qa\0" +"scienceandhistory.museum\0" +"trentinsued-tirol.it\0go.it\0blogspot.pt\0" +"parliament.cy\0lib.ia.us\0" +"mt.gov.br\0" +"etne.no\0" +"trentinos\xc3\xbc""d-tirol.it\0trentinsudtirol.it\0olbiatempio.it\0fukumitsu.toyama.jp\0juniper\0" +"q.bg\0naturalhistory.museum\0s3-website-us-west-2.amazonaws.com\0" +"sologne.museum\0" +"santoandre.br\0" +"go.jp\0kawaba.gunma.jp\0" +"flor\xc3\xb8.no\0l-o-g-i-n.de\0" +"ohtawara.tochigi.jp\0" +"weibo\0blogspot.is\0" +"lecce.it\0memorial\0blogspot.it\0" +"go.ke\0" +"tabayama.yamanashi.jp\0" +"accident-investigation.aero\0" +"kadena.okinawa.jp\0" +"frosta.no\0" +"toyokawa.aichi.jp\0banamex\0" +"sibenik.museum\0" +"blogspot.jp\0" +"go.kr\0chirurgiens-dentistes-en-france.fr\0" +"hamar.no\0" +"environment.museum\0" +"higashikagawa.kagawa.jp\0matsukawa.nagano.jp\0\xe5\x85\xac\xe5\x8f\xb8\0" +"gs.aa.no\0" +"honai.ehime.jp\0" +"skole.museum\0utah.museum\0" +"blogspot.kr\0" +"trolley.museum\0bd.se\0from-me.org\0" +"carrier.museum\0salat.no\0brussels\0cipriani\0" +"grimstad.no\0krager\xc3\xb8.no\0" +"lea\xc5\x8bgaviika.no\0blogspot.li\0" +"is-by.us\0" +"shiso.hyogo.jp\0" +"arq.br\0" +"\xed\x95\x9c\xea\xb5\xad\0" +"blogspot.lt\0blogspot.md\0" +"roan.no\0blogspot.lu\0" +"dni.us\0ltd.ua\0" +"championship.aero\0" +"kobierzyce.pl\0" +"schlesisches.museum\0blogspot.mk\0" +"sex.pl\0" +"archaeology.museum\0" +"tonaki.okinawa.jp\0est.pr\0" +"gotdns.com\0" +"ltd.uk\0healthcare\0" +"webhop.biz\0" +"firm.ve\0" +"itayanagi.aomori.jp\0suita.osaka.jp\0" +"blogspot.fi\0" +"narashino.chiba.jp\0" +"\xe7\xbd\x91\xe5\xba\x97\0" +"tsukui.kanagawa.jp\0shimosuwa.nagano.jp\0" +"troms\xc3\xb8.no\0" +"otaki.nagano.jp\0" +"\xe5\xb9\xbf\xe4\xb8\x9c\0" +"jfk.museum\0kl\xc3\xa6""bu.no\0ferrero\0" +"berlin\0blogspot.fr\0" +"oracle\0" +"sukagawa.fukushima.jp\0\xe5\x98\x89\xe9\x87\x8c\0" +"works\0" +"world\0" +"tcp4.me\0" +"kumiyama.kyoto.jp\0open\0" +"is-saved.org\0" +"channelsdvr.net\0" +"friuli-vegiulia.it\0" +"taobao\0co.events\0" +"\xe3\x82\xaf\xe3\x83\xa9\xe3\x82\xa6\xe3\x83\x89\0" +"blogspot.gr\0" +"praxi\0barsy.online\0resindevice.io\0" +"tadaoka.osaka.jp\0" +"go.pw\0is-a-anarchist.com\0" +"trentinostirol.it\0star\0" +"on.ca\0" +"cloudeity.net\0" +"nm.us\0blogspot.hk\0" +"leirvik.no\0" +"ong.br\0blogspot.hr\0" +"lahppi.no\0" +"*.compute.estate\0blogspot.hu\0blogspot.ie\0" +"edu.ac\0\xc3\xa5lesund.no\0blackfriday\0" +"is.it\0zentsuji.kagawa.jp\0" +"paroch.k12.ma.us\0" +"edu.af\0" +"blogspot.in\0" +"rennes\xc3\xb8y.no\0" +"ozora.hokkaido.jp\0busan.kr\0" +"blogspot.ba\0withyoutube.com\0" +"edu.al\0" +"sykkylven.no\0" +"hirakata.osaka.jp\0" +"eng.pro\0blogspot.be\0" +"edu.ba\0aa.no\0blogspot.bg\0" +"edu.ar\0edu.bb\0matera.it\0ibara.okayama.jp\0de.cool\0" +"plc.ly\0" +"blogspot.bj\0" +"edu.au\0godaddy\0is-a-soxfan.org\0" +"keisen.fukuoka.jp\0" +"edu.bh\0moseushi.hokkaido.jp\0" +"edu.bi\0crafts.museum\0" +"edu.az\0kumamoto.kumamoto.jp\0" +"firm.ro\0eu-central-1.elasticbeanstalk.com\0blogspot.ca\0" +"exchange.aero\0edu.bm\0" +"edu.bn\0tsurugi.ishikawa.jp\0" +"edu.bo\0s\xc3\xb8r-odal.no\0" +"blogspot.cf\0" +"aremark.no\0" +"edu.br\0go.th\0blogspot.ch\0" +"edu.bs\0" +"edu.bt\0go.tj\0" +"s\xc3\xb8r-varanger.no\0" +"blogspot.cl\0" +"jogasz.hu\0orkanger.no\0" +"edu.ci\0" +"edu.bz\0" +"gs.bu.no\0jambyl.su\0" +"lublin.pl\0mysecuritycamera.net\0" +"v\xc3\xa1rgg\xc3\xa1t.no\0" +"edu.cn\0" +"edu.co\0contemporary.museum\0blogspot.de\0" +"blogspot.cv\0" +"laakesvuemie.no\0go.ug\0" +"boldlygoingnowhere.org\0" +"go.tz\0blogspot.cz\0" +"edu.cu\0blogspot.dk\0" +"edu.cw\0stranda.no\0" +"hikawa.shimane.jp\0" +"serveftp.com\0" +"shinanomachi.nagano.jp\0" +"edu.dm\0finnoy.no\0" +"yoka.hyogo.jp\0" +"edu.do\0museet.museum\0b\xc3\xa1l\xc3\xa1t.no\0" +"sano.tochigi.jp\0\xd8\xa7\xd9\x85\xd8\xa7\xd8\xb1\xd8\xa7\xd8\xaa\0" +"\xe9\xb9\xbf\xe5\x85\x90\xe5\xb3\xb6.jp\0" +"edu.ec\0" +"edu.ee\0" +"edu.eg\0broadway\0" +"livorno.it\0" +"edu.dz\0carboniaiglesias.it\0" +"lesja.no\0" +"ce.it\0sytes.net\0" +"linz.museum\0virtualuser.de\0" +"seiyo.ehime.jp\0" +"my-firewall.org\0" +"kanmaki.nara.jp\0tendo.yamagata.jp\0wolomin.pl\0" +"sula.no\0" +"firm.nf\0" +"edu.es\0savannahga.museum\0tonsberg.no\0" +"edu.et\0" +"myvnc.com\0" +"engineer\0" +"avoues.fr\0bihoro.hokkaido.jp\0caseih\0" +"juedisches.museum\0" +"al.gov.br\0" +"group.aero\0cc.fl.us\0" +"mg.leg.br\0" +"pulawy.pl\0" +"eng.br\0gift\0" +"columbus.museum\0" +"otari.nagano.jp\0" +"edu.ge\0hermes\0" +"honjo.saitama.jp\0" +"edu.gh\0" +"edu.gi\0coastaldefence.museum\0" +"partners\0" +"edu.gl\0minamiyamashiro.kyoto.jp\0" +"edu.gn\0cloudns.biz\0" +"no.eu.org\0" +"edu.gp\0namikata.ehime.jp\0" +"edu.gr\0" +"cng.br\0edu.gt\0gosen.niigata.jp\0" +"agro.bo\0edu.gu\0phoenix.museum\0lugansk.ua\0" +"digital\0" +"dyn-o-saur.com\0" +"motoyama.kochi.jp\0" +"industria.bo\0edu.gy\0" +"edu.hk\0" +"lombardia.it\0" +"edu.hn\0iwaizumi.iwate.jp\0chino.nagano.jp\0futsu.nagasaki.jp\0" +"fuel.aero\0blogspot.ae\0" +"ishikari.hokkaido.jp\0" +"akrehamn.no\0" +"edu.ht\0" +"toyota\0" +"blogspot.al\0" +"mobi\0tunes\0blogspot.am\0" +"goiania.br\0co.financial\0" +"yokoze.saitama.jp\0" +"naoshima.kagawa.jp\0" +"sola.no\0adac\0\xe6\xb8\xb8\xe6\x88\x8f\0" +"edu.in\0yamanashi.jp\0" +"edu.iq\0" +"edu.is\0" +"edu.it\0" +"plc.uk\0" +"piacenza.it\0terni.it\0lg.jp\0echizen.fukui.jp\0actor\0" +"bu.no\0modum.no\0dy.fi\0" +"takino.hyogo.jp\0" +"\xe5\x8f\xb0\xe7\x81\xa3\0" +"\xe5\x85\xac\xe7\x9b\x8a\0" +"isa.us\0" +"arts.co\0village.museum\0s\xc3\xb8r-fron.no\0vodka\0" +"edu.jo\0moda\0dnshome.de\0" +"tashkent.su\0byen.site\0" +"akune.kagoshima.jp\0canon\0" +"edu.kg\0" +"edu.ki\0countryestate.museum\0" +"green\0" +"edu.km\0" +"sango.nara.jp\0edu.kn\0" +"navuotna.no\0lib.in.us\0" +"yakumo.hokkaido.jp\0edu.kp\0" +"edu.la\0" +"nagahama.shiga.jp\0edu.lb\0" +"edu.lc\0afjord.no\0" +"rotorcraft.aero\0edu.kw\0" +"udono.mie.jp\0global.prod.fastly.net\0" +"edu.ky\0n\xc3\xa1vuotna.no\0" +"\xe7\xbd\x91\xe7\xbb\x9c.cn\0edu.kz\0" +"edu.lk\0" +"pisa.it\0" +"toyota.yamaguchi.jp\0comcast\0" +"lombardy.it\0shikatsu.aichi.jp\0" +"\xc3\xa1lt\xc3\xa1.no\0" +"edu.lr\0" +"edu.ls\0" +"kawaue.gifu.jp\0" +"edu.me\0" +"edu.lv\0" +"edu.mg\0" +"edu.ly\0penza.su\0" +"edu.mk\0" +"edu.ml\0cricket\0telebit.app\0" +"misaki.osaka.jp\0edu.mn\0cern\0" +"edu.mo\0nz.eu.org\0" +"tatebayashi.gunma.jp\0" +"redstone\0nym.by\0" +"nym.bz\0" +"edu.ms\0mordovia.su\0" }; static const quint16 tldChunkCount = 2; -static const quint32 tldChunks[] = {65532, 101260}; +static const quint32 tldChunks[] = {65517, 101828}; QT_END_NAMESPACE diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 4f173d2dfd..3ee6a656b0 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -3402,6 +3402,21 @@ void tst_QUrl::effectiveTLDs_data() QTest::newRow("yes16") << QUrl::fromEncoded("http://anything.pagespeedmobilizer.com") << ".pagespeedmobilizer.com"; QTest::newRow("yes17") << QUrl::fromEncoded("http://anything.eu-central-1.compute.amazonaws.com") << ".eu-central-1.compute.amazonaws.com"; QTest::newRow("yes18") << QUrl::fromEncoded("http://anything.ltd.hk") << ".ltd.hk"; + QTest::newRow("trentino.it") + << QUrl::fromEncoded("http://any.thing.trentino.it") << ".trentino.it"; + QTest::newRow("net.ni") << QUrl::fromEncoded("http://test.net.ni") << ".net.ni"; + QTest::newRow("dyn.cosidns.de") + << QUrl::fromEncoded("http://test.dyn.cosidns.de") << ".dyn.cosidns.de"; + QTest::newRow("freeddns.org") + << QUrl::fromEncoded("http://test.freeddns.org") << ".freeddns.org"; + QTest::newRow("app.os.stg.fedoraproject.org") + << QUrl::fromEncoded("http://test.app.os.stg.fedoraproject.org") + << ".app.os.stg.fedoraproject.org"; + QTest::newRow("development.run") << QUrl::fromEncoded("http://test.development.run") << ".development.run"; + QTest::newRow("crafting.xyz") << QUrl::fromEncoded("http://test.crafting.xyz") << ".crafting.xyz"; + QTest::newRow("nym.ie") << QUrl::fromEncoded("http://shamus.nym.ie") << ".nym.ie"; + QTest::newRow("vapor.cloud") << QUrl::fromEncoded("http://test.vapor.cloud") << ".vapor.cloud"; + QTest::newRow("official.academy") << QUrl::fromEncoded("http://acredited.official.academy") << ".official.academy"; } void tst_QUrl::effectiveTLDs() From 116a66179196c272282b67cff51707f96cc3316a Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 25 Feb 2019 12:20:42 +0100 Subject: [PATCH 1273/1650] Properly deprecate assorted enum members This adds the first uses of Q_DECL_ENUMERATOR_DEPRECATED. Prompted by API change review for 5.13, comment by Christian Ehrlicher. Task-number: QTBUG-73484 Change-Id: Ic106048cec18960a91f88eb12650abab6abf0e97 Reviewed-by: Rolf Eike Beer Reviewed-by: Christian Ehrlicher --- src/corelib/global/qnamespace.h | 12 +++++++----- src/widgets/styles/qstyle.h | 27 ++++++++++++++++++--------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 41b94bf15a..6488426e64 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -500,7 +500,9 @@ public: AA_NativeWindows = 3, AA_DontCreateNativeWidgetSiblings = 4, AA_PluginApplication = 5, - AA_MacPluginApplication = AA_PluginApplication, // ### Qt 6: remove me +#if QT_DEPRECATED_SINCE(5, 13) // ### Qt 6: remove me + AA_MacPluginApplication Q_DECL_ENUMERATOR_DEPRECATED = AA_PluginApplication, +#endif AA_DontUseNativeMenuBar = 6, AA_MacDontSwapCtrlAndMeta = 7, AA_Use96Dpi = 8, @@ -1504,12 +1506,12 @@ public: // Metadata FontRole = 6, TextAlignmentRole = 7, -#if QT_DEPRECATED_SINCE(5, 13) - BackgroundColorRole = 8, - TextColorRole = 9, -#endif BackgroundRole = 8, ForegroundRole = 9, +#if QT_DEPRECATED_SINCE(5, 13) // ### Qt 6: remove me + BackgroundColorRole Q_DECL_ENUMERATOR_DEPRECATED = BackgroundRole, + TextColorRole Q_DECL_ENUMERATOR_DEPRECATED = ForegroundRole, +#endif CheckStateRole = 10, // Accessibility AccessibleTextRole = 11, diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h index 8256f908db..5ee37bd8e9 100644 --- a/src/widgets/styles/qstyle.h +++ b/src/widgets/styles/qstyle.h @@ -141,8 +141,10 @@ public: PE_FrameGroupBox, PE_FrameLineEdit, PE_FrameMenu, - PE_FrameStatusBar, // ### Qt 6: remove - PE_FrameStatusBarItem = PE_FrameStatusBar, + PE_FrameStatusBarItem, +#if QT_DEPRECATED_SINCE(5, 13) // ### Qt 6: remove + PE_FrameStatusBar Q_DECL_ENUMERATOR_DEPRECATED = PE_FrameStatusBarItem, +#endif PE_FrameTabWidget, PE_FrameWindow, PE_FrameButtonBevel, @@ -162,8 +164,10 @@ public: PE_IndicatorArrowUp, PE_IndicatorBranch, PE_IndicatorButtonDropDown, - PE_IndicatorViewItemCheck, // ### Qt 6: remove - PE_IndicatorItemViewItemCheck = PE_IndicatorViewItemCheck, + PE_IndicatorItemViewItemCheck, +#if QT_DEPRECATED_SINCE(5, 13) // ### Qt 6: remove + PE_IndicatorViewItemCheck Q_DECL_ENUMERATOR_DEPRECATED = PE_IndicatorItemViewItemCheck, +#endif PE_IndicatorCheckBox, PE_IndicatorDockWidgetResizeHandle, PE_IndicatorHeaderArrow, @@ -309,8 +313,9 @@ public: SE_TabWidgetRightCorner, SE_ItemViewItemCheckIndicator, - SE_ViewItemCheckIndicator = SE_ItemViewItemCheckIndicator, // ### Qt 6: remove - +#if QT_DEPRECATED_SINCE(5, 13) // ### Qt 6: remove + SE_ViewItemCheckIndicator Q_DECL_ENUMERATOR_DEPRECATED = SE_ItemViewItemCheckIndicator, +#endif SE_TabBarTearIndicator, SE_TabBarTearIndicatorLeft = SE_TabBarTearIndicator, @@ -506,9 +511,11 @@ public: PM_DialogButtonsButtonHeight, PM_MdiSubWindowFrameWidth, - PM_MDIFrameWidth = PM_MdiSubWindowFrameWidth, // ### Qt 6: remove PM_MdiSubWindowMinimizedWidth, - PM_MDIMinimizedWidth = PM_MdiSubWindowMinimizedWidth, // ### Qt 6: remove +#if QT_DEPRECATED_SINCE(5, 13) // ### Qt 6: remove + PM_MDIFrameWidth Q_DECL_ENUMERATOR_DEPRECATED = PM_MdiSubWindowFrameWidth, + PM_MDIMinimizedWidth Q_DECL_ENUMERATOR_DEPRECATED = PM_MdiSubWindowMinimizedWidth, +#endif PM_HeaderMargin, PM_HeaderMarkSize, @@ -649,7 +656,9 @@ public: SH_ComboBox_Popup, SH_TitleBar_NoBorder, SH_Slider_StopMouseOverSlider, - SH_ScrollBar_StopMouseOverSlider = SH_Slider_StopMouseOverSlider, // ### Qt 6: remove +#if QT_DEPRECATED_SINCE(5, 13) // ### Qt 6: remove + SH_ScrollBar_StopMouseOverSlider Q_DECL_ENUMERATOR_DEPRECATED = SH_Slider_StopMouseOverSlider, +#endif SH_BlinkCursorWhenTextSelected, SH_RichText_FullWidthSelection, SH_Menu_Scrollable, From 97e78b0e1f0396cdee0319bafaf8ce1d6eb74f64 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Mon, 25 Feb 2019 14:05:29 +0100 Subject: [PATCH 1274/1650] Update bundled libjpeg-turbo to version 2.0.2 [ChangeLog][Third-Party Code] libjpeg-turbo was updated to version 2.0.2 Task-number: QTBUG-73883 Change-Id: Ib4ed145f1ed9c51933aae565dcb4064ffd60ec24 Reviewed-by: Kai Koehne --- src/3rdparty/libjpeg/LICENSE | 29 ++-------- src/3rdparty/libjpeg/jconfig.h | 18 +++--- src/3rdparty/libjpeg/qt_attribution.json | 4 +- src/3rdparty/libjpeg/src/ChangeLog.md | 70 ++++++++++++++++++++++++ src/3rdparty/libjpeg/src/jconfig.h.in | 28 +++++----- src/3rdparty/libjpeg/src/jdcolor.c | 2 +- src/3rdparty/libjpeg/src/jdmerge.c | 2 +- src/3rdparty/libjpeg/src/jquant1.c | 2 +- src/3rdparty/libjpeg/src/jversion.h | 6 +- 9 files changed, 105 insertions(+), 56 deletions(-) diff --git a/src/3rdparty/libjpeg/LICENSE b/src/3rdparty/libjpeg/LICENSE index 0f6ec4b30a..5ca512b34d 100644 --- a/src/3rdparty/libjpeg/LICENSE +++ b/src/3rdparty/libjpeg/LICENSE @@ -14,7 +14,7 @@ libjpeg-turbo is covered by three compatible BSD-style open source licenses: This license covers the TurboJPEG API library and associated programs, as well as the build system. -- The zlib License, which is listed below +- The [zlib License](https://opensource.org/licenses/Zlib) This license is a subset of the other two, and it covers the libjpeg-turbo SIMD extensions. @@ -66,7 +66,7 @@ best of our understanding. 2. If your binary distribution includes or uses the TurboJPEG API, then your product documentation must include the text of the Modified BSD - License. + License (see below.) **Origin** - Clause 2 of the Modified BSD License @@ -91,7 +91,8 @@ best of our understanding. The Modified (3-clause) BSD License =================================== -Copyright (C)\ \. All Rights Reserved. +Copyright (C)2009-2019 D. R. Commander. All Rights Reserved. +Copyright (C)2015 Viktor Szathmáry. All Rights Reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -118,28 +119,6 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -The zlib License -================ - -Copyright (C) \, \. - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. -2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. - - Why Three Licenses? =================== diff --git a/src/3rdparty/libjpeg/jconfig.h b/src/3rdparty/libjpeg/jconfig.h index bcfef5f0b6..3f6a7f6b3c 100644 --- a/src/3rdparty/libjpeg/jconfig.h +++ b/src/3rdparty/libjpeg/jconfig.h @@ -2,22 +2,22 @@ #define JPEG_LIB_VERSION 80 -#define LIBJPEG_TURBO_VERSION 2.0.0 +#define LIBJPEG_TURBO_VERSION 2.0.2 -#define LIBJPEG_TURBO_VERSION_NUMBER 2000000 +#define LIBJPEG_TURBO_VERSION_NUMBER 2000002 -#define C_ARITH_CODING_SUPPORTED +#define C_ARITH_CODING_SUPPORTED 1 -#define D_ARITH_CODING_SUPPORTED +#define D_ARITH_CODING_SUPPORTED 1 -#define MEM_SRCDST_SUPPORTED +#define MEM_SRCDST_SUPPORTED 1 #define BITS_IN_JSAMPLE 8 -#define HAVE_STDDEF_H +#define HAVE_STDDEF_H 1 -#define HAVE_STDLIB_H +#define HAVE_STDLIB_H 1 -#define HAVE_UNSIGNED_CHAR +#define HAVE_UNSIGNED_CHAR 1 -#define HAVE_UNSIGNED_SHORT +#define HAVE_UNSIGNED_SHORT 1 diff --git a/src/3rdparty/libjpeg/qt_attribution.json b/src/3rdparty/libjpeg/qt_attribution.json index 8fbdfdb9b7..d1497bc20f 100644 --- a/src/3rdparty/libjpeg/qt_attribution.json +++ b/src/3rdparty/libjpeg/qt_attribution.json @@ -6,11 +6,11 @@ "Description": "The Independent JPEG Group's JPEG software", "Homepage": "http://libjpeg-turbo.virtualgl.org/", - "Version": "2.0.0", + "Version": "2.0.2", "License": "Independent JPEG Group License", "LicenseId": "IJG", "LicenseFile": "LICENSE", - "Copyright": "Copyright (C) 2009-2018 D. R. Commander + "Copyright": "Copyright (C) 2009-2019 D. R. Commander Copyright (C) 2011-2016 Siarhei Siamashka Copyright (C) 2015-2016, 2018 Matthieu Darbois Copyright (C) 2015 Intel Corporation diff --git a/src/3rdparty/libjpeg/src/ChangeLog.md b/src/3rdparty/libjpeg/src/ChangeLog.md index 8f0d11b1a6..7cf92c30fd 100644 --- a/src/3rdparty/libjpeg/src/ChangeLog.md +++ b/src/3rdparty/libjpeg/src/ChangeLog.md @@ -1,3 +1,73 @@ +2.0.2 +===== + +### Significant changes relative to 2.0.1: + +1. Fixed a regression introduced by 2.0.1[5] that prevented a runtime search +path (rpath) from being embedded in the libjpeg-turbo shared libraries and +executables for macOS and iOS. This caused a fatal error of the form +"dyld: Library not loaded" when attempting to use one of the executables, +unless `DYLD_LIBRARY_PATH` was explicitly set to the location of the +libjpeg-turbo shared libraries. + +2. Fixed an integer overflow and subsequent segfault (CVE-2018-20330) that +occurred when attempting to load a BMP file with more than 1 billion pixels +using the `tjLoadImage()` function. + +3. Fixed a buffer overrun (CVE-2018-19664) that occurred when attempting to +decompress a specially-crafted malformed JPEG image to a 256-color BMP using +djpeg. + +4. Fixed a floating point exception that occurred when attempting to +decompress a specially-crafted malformed JPEG image with a specified image +width or height of 0 using the C version of TJBench. + +5. The TurboJPEG API will now decompress 4:4:4 JPEG images with 2x1, 1x2, 3x1, +or 1x3 luminance and chrominance sampling factors. This is a non-standard way +of specifying 1x subsampling (normally 4:4:4 JPEGs have 1x1 luminance and +chrominance sampling factors), but the JPEG format and the libjpeg API both +allow it. + +6. Fixed a regression introduced by 2.0 beta1[7] that caused djpeg to generate +incorrect PPM images when used with the `-colors` option. + +7. Fixed an issue whereby a static build of libjpeg-turbo (a build in which +`ENABLE_SHARED` is `0`) could not be installed using the Visual Studio IDE. + +8. Fixed a severe performance issue in the Loongson MMI SIMD extensions that +occurred when compressing RGB images whose image rows were not 64-bit-aligned. + + +2.0.1 +===== + +### Significant changes relative to 2.0.0: + +1. Fixed a regression introduced with the new CMake-based Un*x build system, +whereby jconfig.h could cause compiler warnings of the form +`"HAVE_*_H" redefined` if it was included by downstream Autotools-based +projects that used `AC_CHECK_HEADERS()` to check for the existence of locale.h, +stddef.h, or stdlib.h. + +2. The `jsimd_quantize_float_dspr2()` and `jsimd_convsamp_float_dspr2()` +functions in the MIPS DSPr2 SIMD extensions are now disabled at compile time +if the soft float ABI is enabled. Those functions use instructions that are +incompatible with the soft float ABI. + +3. Fixed a regression in the SIMD feature detection code, introduced by +the AVX2 SIMD extensions (2.0 beta1[1]), that caused libjpeg-turbo to crash on +Windows 7 if Service Pack 1 was not installed. + +4. Fixed out-of-bounds read in cjpeg that occurred when attempting to compress +a specially-crafted malformed color-index (8-bit-per-sample) Targa file in +which some of the samples (color indices) exceeded the bounds of the Targa +file's color table. + +5. Fixed an issue whereby installing a fully static build of libjpeg-turbo +(a build in which `CFLAGS` contains `-static` and `ENABLE_SHARED` is `0`) would +fail with "No valid ELF RPATH or RUNPATH entry exists in the file." + + 2.0.0 ===== diff --git a/src/3rdparty/libjpeg/src/jconfig.h.in b/src/3rdparty/libjpeg/src/jconfig.h.in index 28427548e8..18a69a4814 100644 --- a/src/3rdparty/libjpeg/src/jconfig.h.in +++ b/src/3rdparty/libjpeg/src/jconfig.h.in @@ -10,16 +10,16 @@ #define LIBJPEG_TURBO_VERSION_NUMBER @LIBJPEG_TURBO_VERSION_NUMBER@ /* Support arithmetic encoding */ -#cmakedefine C_ARITH_CODING_SUPPORTED +#cmakedefine C_ARITH_CODING_SUPPORTED 1 /* Support arithmetic decoding */ -#cmakedefine D_ARITH_CODING_SUPPORTED +#cmakedefine D_ARITH_CODING_SUPPORTED 1 /* Support in-memory source/destination managers */ -#cmakedefine MEM_SRCDST_SUPPORTED +#cmakedefine MEM_SRCDST_SUPPORTED 1 /* Use accelerated SIMD routines. */ -#cmakedefine WITH_SIMD +#cmakedefine WITH_SIMD 1 /* * Define BITS_IN_JSAMPLE as either @@ -33,37 +33,37 @@ #define BITS_IN_JSAMPLE @BITS_IN_JSAMPLE@ /* use 8 or 12 */ /* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LOCALE_H +#cmakedefine HAVE_LOCALE_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STDDEF_H +#cmakedefine HAVE_STDDEF_H 1 /* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STDLIB_H +#cmakedefine HAVE_STDLIB_H 1 /* Define if you need to include to get size_t. */ -#cmakedefine NEED_SYS_TYPES_H +#cmakedefine NEED_SYS_TYPES_H 1 /* Define if you have BSD-like bzero and bcopy in rather than memset/memcpy in . */ -#cmakedefine NEED_BSD_STRINGS +#cmakedefine NEED_BSD_STRINGS 1 /* Define to 1 if the system has the type `unsigned char'. */ -#cmakedefine HAVE_UNSIGNED_CHAR +#cmakedefine HAVE_UNSIGNED_CHAR 1 /* Define to 1 if the system has the type `unsigned short'. */ -#cmakedefine HAVE_UNSIGNED_SHORT +#cmakedefine HAVE_UNSIGNED_SHORT 1 /* Compiler does not support pointers to undefined structures. */ -#cmakedefine INCOMPLETE_TYPES_BROKEN +#cmakedefine INCOMPLETE_TYPES_BROKEN 1 /* Define if your (broken) compiler shifts signed values as if they were unsigned. */ -#cmakedefine RIGHT_SHIFT_IS_UNSIGNED +#cmakedefine RIGHT_SHIFT_IS_UNSIGNED 1 /* Define to 1 if type `char' is unsigned and you are not using gcc. */ #ifndef __CHAR_UNSIGNED__ - #cmakedefine __CHAR_UNSIGNED__ + #cmakedefine __CHAR_UNSIGNED__ 1 #endif /* Define to empty if `const' does not conform to ANSI C. */ diff --git a/src/3rdparty/libjpeg/src/jdcolor.c b/src/3rdparty/libjpeg/src/jdcolor.c index fd7f661d5a..dc0e3b6c0e 100644 --- a/src/3rdparty/libjpeg/src/jdcolor.c +++ b/src/3rdparty/libjpeg/src/jdcolor.c @@ -592,7 +592,7 @@ ycck_cmyk_convert(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, /* Declarations for ordered dithering * * We use a 4x4 ordered dither array packed into 32 bits. This array is - * sufficent for dithering RGB888 to RGB565. + * sufficient for dithering RGB888 to RGB565. */ #define DITHER_MASK 0x3 diff --git a/src/3rdparty/libjpeg/src/jdmerge.c b/src/3rdparty/libjpeg/src/jdmerge.c index d67faec036..b3fec04f71 100644 --- a/src/3rdparty/libjpeg/src/jdmerge.c +++ b/src/3rdparty/libjpeg/src/jdmerge.c @@ -448,7 +448,7 @@ h2v2_merged_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf, /* Declarations for ordered dithering * * We use a 4x4 ordered dither array packed into 32 bits. This array is - * sufficent for dithering RGB888 to RGB565. + * sufficient for dithering RGB888 to RGB565. */ #define DITHER_MASK 0x3 diff --git a/src/3rdparty/libjpeg/src/jquant1.c b/src/3rdparty/libjpeg/src/jquant1.c index a336abdbbb..40bbb28cc7 100644 --- a/src/3rdparty/libjpeg/src/jquant1.c +++ b/src/3rdparty/libjpeg/src/jquant1.c @@ -154,7 +154,7 @@ typedef struct { */ boolean is_padded; /* is the colorindex padded for odither? */ - int Ncolors[MAX_Q_COMPS]; /* # of values alloced to each component */ + int Ncolors[MAX_Q_COMPS]; /* # of values allocated to each component */ /* Variables for ordered dithering */ int row_index; /* cur row's vertical index in dither matrix */ diff --git a/src/3rdparty/libjpeg/src/jversion.h b/src/3rdparty/libjpeg/src/jversion.h index 2039f44c3a..191fb6bb54 100644 --- a/src/3rdparty/libjpeg/src/jversion.h +++ b/src/3rdparty/libjpeg/src/jversion.h @@ -4,7 +4,7 @@ * This file was part of the Independent JPEG Group's software: * Copyright (C) 1991-2012, Thomas G. Lane, Guido Vollbeding. * libjpeg-turbo Modifications: - * Copyright (C) 2010, 2012-2018, D. R. Commander. + * Copyright (C) 2010, 2012-2019, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -36,7 +36,7 @@ */ #define JCOPYRIGHT \ - "Copyright (C) 2009-2018 D. R. Commander\n" \ + "Copyright (C) 2009-2019 D. R. Commander\n" \ "Copyright (C) 2011-2016 Siarhei Siamashka\n" \ "Copyright (C) 2015-2016, 2018 Matthieu Darbois\n" \ "Copyright (C) 2015 Intel Corporation\n" \ @@ -49,4 +49,4 @@ "Copyright (C) 1991-2016 Thomas G. Lane, Guido Vollbeding" #define JCOPYRIGHT_SHORT \ - "Copyright (C) 1991-2018 The libjpeg-turbo Project and many others" + "Copyright (C) 1991-2019 The libjpeg-turbo Project and many others" From 42b42602c40ade7b057b1e169b99405e0c17b01f Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Mon, 18 Feb 2019 13:09:58 +0100 Subject: [PATCH 1275/1650] QTextureFileReader: add support for astc format files The standard astc encoder has its own file format. Change-Id: I9a2f7b1fa20ba344b79637bafb50ff2bd0596747 Reviewed-by: Paul Olav Tvete --- src/gui/util/qastchandler.cpp | 168 ++++++++++++++++++ src/gui/util/qastchandler_p.h | 73 ++++++++ src/gui/util/qtexturefilereader.cpp | 5 +- src/gui/util/util.pri | 6 +- .../qtexturefilereader/qtexturefilereader.qrc | 2 + .../texturefiles/newlogo.astc | Bin 0 -> 2512 bytes .../texturefiles/newlogo_srgb.astc | Bin 0 -> 2512 bytes .../tst_qtexturefilereader.cpp | 70 +++++--- 8 files changed, 297 insertions(+), 27 deletions(-) create mode 100644 src/gui/util/qastchandler.cpp create mode 100644 src/gui/util/qastchandler_p.h create mode 100644 tests/auto/gui/util/qtexturefilereader/texturefiles/newlogo.astc create mode 100644 tests/auto/gui/util/qtexturefilereader/texturefiles/newlogo_srgb.astc diff --git a/src/gui/util/qastchandler.cpp b/src/gui/util/qastchandler.cpp new file mode 100644 index 0000000000..6d163c6701 --- /dev/null +++ b/src/gui/util/qastchandler.cpp @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qastchandler_p.h" +#include "qtexturefiledata_p.h" + +#include + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +struct AstcHeader +{ + quint8 magic[4]; + quint8 blockDimX; + quint8 blockDimY; + quint8 blockDimZ; + quint8 xSize[3]; + quint8 ySize[3]; + quint8 zSize[3]; +}; + +bool QAstcHandler::canRead(const QByteArray &suffix, const QByteArray &block) +{ + Q_UNUSED(suffix) + + return block.startsWith("\x13\xAB\xA1\x5C"); +} + +quint32 QAstcHandler::astcGLFormat(quint8 xBlockDim, quint8 yBlockDim) const +{ + static const quint32 glFormatRGBABase = 0x93B0; // GL_COMPRESSED_RGBA_ASTC_4x4_KHR + static const quint32 glFormatSRGBBase = 0x93D0; // GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR + + static QSize dims[14] = { + { 4, 4 }, // GL_COMPRESSED_xxx_ASTC_4x4_KHR + { 5, 4 }, // GL_COMPRESSED_xxx_ASTC_5x4_KHR + { 5, 5 }, // GL_COMPRESSED_xxx_ASTC_5x5_KHR + { 6, 5 }, // GL_COMPRESSED_xxx_ASTC_6x5_KHR + { 6, 6 }, // GL_COMPRESSED_xxx_ASTC_6x6_KHR + { 8, 5 }, // GL_COMPRESSED_xxx_ASTC_8x5_KHR + { 8, 6 }, // GL_COMPRESSED_xxx_ASTC_8x6_KHR + { 8, 8 }, // GL_COMPRESSED_xxx_ASTC_8x8_KHR + { 10, 5 }, // GL_COMPRESSED_xxx_ASTC_10x5_KHR + { 10, 6 }, // GL_COMPRESSED_xxx_ASTC_10x6_KHR + { 10, 8 }, // GL_COMPRESSED_xxx_ASTC_10x8_KHR + { 10, 10 }, // GL_COMPRESSED_xxx_ASTC_10x10_KHR + { 12, 10 }, // GL_COMPRESSED_xxx_ASTC_12x10_KHR + { 12, 12 } // GL_COMPRESSED_xxx_ASTC_12x12_KHR + }; + + const QSize dim(xBlockDim, yBlockDim); + int index = -1; + for (int i = 0; i < 14; i++) { + if (dim == dims[i]) { + index = i; + break; + } + } + if (index < 0) + return 0; + + bool useSrgb = qEnvironmentVariableIsSet("QT_ASTCHANDLER_USE_SRGB") + || logName().toLower().contains("srgb"); + + return useSrgb ? (glFormatSRGBBase + index) : (glFormatRGBABase + index); +} + +QTextureFileData QAstcHandler::read() +{ + QTextureFileData nullData; + QTextureFileData res; + + if (!device()) + return nullData; + + QByteArray fileData = device()->readAll(); + if (fileData.size() < int(sizeof(AstcHeader)) || !canRead(QByteArray(), fileData)) { + qCDebug(lcQtGuiTextureIO, "Not an ASTC file: %s", logName().constData()); + return nullData; + } + res.setData(fileData); + + const AstcHeader *header = reinterpret_cast(fileData.constData()); + + int xSz = int(header->xSize[0]) | int(header->xSize[1]) << 8 | int(header->xSize[2]) << 16; + int ySz = int(header->ySize[0]) | int(header->ySize[1]) << 8 | int(header->ySize[2]) << 16; + int zSz = int(header->zSize[0]) | int(header->zSize[1]) << 8 | int(header->zSize[2]) << 16; + + quint32 glFmt = astcGLFormat(header->blockDimX, header->blockDimY); + + if (!xSz || !ySz || !zSz || !glFmt || header->blockDimZ != 1) { + qCDebug(lcQtGuiTextureIO, "Invalid ASTC header data in file %s", logName().constData()); + return nullData; + } + + res.setSize(QSize(xSz, ySz)); + res.setGLFormat(0); // 0 for compressed textures + res.setGLInternalFormat(glFmt); + //? BaseInternalFormat + + int xBlocks = (xSz + header->blockDimX - 1) / header->blockDimX; + int yBlocks = (ySz + header->blockDimY - 1) / header->blockDimY; + int zBlocks = (zSz + header->blockDimZ - 1) / header->blockDimZ; + + int byteCount = 0; + bool oob = mul_overflow(xBlocks, yBlocks, &byteCount) + || mul_overflow(byteCount, zBlocks, &byteCount) + || mul_overflow(byteCount, 16, &byteCount); + + + res.setDataOffset(sizeof(AstcHeader)); + res.setNumLevels(1); + res.setDataLength(byteCount); + + if (oob || !res.isValid()) { + qCDebug(lcQtGuiTextureIO, "Invalid ASTC file %s", logName().constData()); + return nullData; + } + + res.setLogName(logName()); + +#if 0 + qDebug() << "ASTC file handler read" << res << res.dataOffset() << res.dataLength(); +#endif + return res; +} + +QT_END_NAMESPACE diff --git a/src/gui/util/qastchandler_p.h b/src/gui/util/qastchandler_p.h new file mode 100644 index 0000000000..398f1833b6 --- /dev/null +++ b/src/gui/util/qastchandler_p.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QASTCHANDLER_H +#define QASTCHANDLER_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qtexturefilehandler_p.h" + +QT_BEGIN_NAMESPACE + +class QAstcHandler : public QTextureFileHandler +{ +public: + using QTextureFileHandler::QTextureFileHandler; + + static bool canRead(const QByteArray &suffix, const QByteArray &block); + + QTextureFileData read() override; + +private: + quint32 astcGLFormat(quint8 xBlockDim, quint8 yBlockDim) const; +}; + +QT_END_NAMESPACE + +#endif // QASTCHANDLER_H diff --git a/src/gui/util/qtexturefilereader.cpp b/src/gui/util/qtexturefilereader.cpp index 5d4bd600e0..fefb957323 100644 --- a/src/gui/util/qtexturefilereader.cpp +++ b/src/gui/util/qtexturefilereader.cpp @@ -41,6 +41,7 @@ #include "qpkmhandler_p.h" #include "qktxhandler_p.h" +#include "qastchandler_p.h" #include @@ -80,6 +81,8 @@ bool QTextureFileReader::canRead() m_handler = new QPkmHandler(m_device, logName); } else if (QKtxHandler::canRead(suffix, headerBlock)) { m_handler = new QKtxHandler(m_device, logName); + } else if (QAstcHandler::canRead(suffix, headerBlock)) { + m_handler = new QAstcHandler(m_device, logName); } // else if OtherHandler::canRead() ...etc. } @@ -89,7 +92,7 @@ bool QTextureFileReader::canRead() QList QTextureFileReader::supportedFileFormats() { // Hardcoded for now - return {QByteArrayLiteral("pkm"), QByteArrayLiteral("ktx")}; + return {QByteArrayLiteral("pkm"), QByteArrayLiteral("ktx"), QByteArrayLiteral("astc")}; } bool QTextureFileReader::init() diff --git a/src/gui/util/util.pri b/src/gui/util/util.pri index 6324642505..e5e711b1a0 100644 --- a/src/gui/util/util.pri +++ b/src/gui/util/util.pri @@ -19,7 +19,8 @@ HEADERS += \ util/qtexturefilereader_p.h \ util/qtexturefilehandler_p.h \ util/qpkmhandler_p.h \ - util/qktxhandler_p.h + util/qktxhandler_p.h \ + util/qastchandler_p.h SOURCES += \ util/qdesktopservices.cpp \ @@ -38,4 +39,5 @@ SOURCES += \ util/qtexturefiledata.cpp \ util/qtexturefilereader.cpp \ util/qpkmhandler.cpp \ - util/qktxhandler.cpp + util/qktxhandler.cpp \ + util/qastchandler.cpp diff --git a/tests/auto/gui/util/qtexturefilereader/qtexturefilereader.qrc b/tests/auto/gui/util/qtexturefilereader/qtexturefilereader.qrc index ab882b5db2..8aab86e1ff 100644 --- a/tests/auto/gui/util/qtexturefilereader/qtexturefilereader.qrc +++ b/tests/auto/gui/util/qtexturefilereader/qtexturefilereader.qrc @@ -3,5 +3,7 @@ texturefiles/car.ktx texturefiles/pattern.pkm texturefiles/car_mips.ktx + texturefiles/newlogo_srgb.astc + texturefiles/newlogo.astc diff --git a/tests/auto/gui/util/qtexturefilereader/texturefiles/newlogo.astc b/tests/auto/gui/util/qtexturefilereader/texturefiles/newlogo.astc new file mode 100644 index 0000000000000000000000000000000000000000..39bf3f1734597dbdc34dd680864d0c8219956562 GIT binary patch literal 2512 zcmchY4NMzU5P=Cg`MjzSi?q#0iFdw0J~8AtbVR%p8j+aD#2X-p7*X0Y0d}9Cf4=;U;hI5HvTsU ziP=j-h|}evBE(MR#*L-A5osyEX?{pdoQoFv_0M^!baXT;>(2RqtH&ViR~>z(X#fbI zAGqK9d#Db`21IkzX)kJ>Mxm+k;Fp_a1G+uah&8&a+7FXK?;r$ zRW-Eh4Mti@Lhj1nz49R)P_T;ZL0>x$wM`sP7v&T~t7U%`L4-qu1mDT0@Bb{9eq9;M8NBe(*I2giV-vFqxIgQb)Jvpe3O+oob;TvkvukXZ z9`vura{Os%%yOVM2zZ`gRI*X)WWYwic}`q`afLX8;jvQ#4<2YPh}O+;6;>H%UCQ$+ z$5o3MJ2^%qeyy&ij*%olA9CfGQ6-;rcEX;`EK^kV=qb`nT|t-4T|?)^6~lV zvr_(8q;>0w$!$ZB2ugrQk*=Q^0gw;~r(@vF6aMkM_VrKiW=4u0ztGmE5O5oY!~Xh_ zb?9MvP<=<0B}{35mv9Wv)$IG}?K2m}b^iYT`bzl)@h1ucH|I@#yU>@v9g=~?EM)XS zK7gb-1~i*>{_zAlW=ntduXWT1;Q-8hi(%?#hCbQMjmmr|t+DA8UuEAEu34|*omXmm zbI+Ii`}^xF<)^$mC~s3Gt^GKiC<2|fbk?RfY}-D)0Wd77w}8nX5@a%D(c>VAiH>5b zk=$~i3QMpANst0bih3h6j|_)a9#^mkaX1|G{RbA=yqxB8bF z85&m0!32i)y?D+_O6h#(BL0}b8twH3U^}{-+07&Q^WxsUvqC2k6B*L-^h2gty6-)5 zdq4T+jeor5_ypMn{_rX=biK>+Cj*dFJHd@2AO34LI3~& literal 0 HcmV?d00001 diff --git a/tests/auto/gui/util/qtexturefilereader/texturefiles/newlogo_srgb.astc b/tests/auto/gui/util/qtexturefilereader/texturefiles/newlogo_srgb.astc new file mode 100644 index 0000000000000000000000000000000000000000..38e876829bd9c3edb9c0d3f12943c8928a05a5ad GIT binary patch literal 2512 zcmchY4NTir5Ww%X^nWgBd|#4L0kv?en#>+fuUNLhzC{z1+KZ zzuvvO3q9MNw~C7n0z40Z0JfvL8N+PP9R2AeRMPmu-5*{dvdnWyCeHQ$U;hGxHsLq> ziP=j-h|}evBE(MR#*M|g5$PzuX>L$ToC_BE_3wF^Y-A)o{m%LSsz)Q;SM9x~DF6td zAGqK9lyN%+gP-lrNU6FO)Tc;w`21IjzX0jh8!nlW5aXc*xCU`+cuw*sxk+@cAQjJu zD(l+}okm(pLhj1nz49UJS8)pLL0>x$w2mKvh=4+9vFxoRi13J*;5+&B{hy`sZ$x$V z?S>xXgeN|g4Aegn@Qm7l6};6R-bv-!%RQ4nWWw zgZ}kcia!;NTK3fhfxr`tN(O3~2v`p|+lk9DE|;dUJa%djzynQrQTl1V$|~orNq(`+ zan&NlP9D;&HkeIOD1x4$A`>!)vNB^`oiA;Z>yn5|xr4jy@XO4jQ?V#_ovQQ|AD^#2 z%jJ(jI=6wC+%^OWpaysh>HFB>0P%rvA{yQ~>L1T*f9TmA>UoO8W?r47ChV032=X-OuKoW4+`K(^Z z0brVyNX5gc4UNY+W%gmx{r=3k^MCj3 zBDr1X6W3!WojK@SX6HjTR13Eu;fu=z(hwyvNcF) z*;k1f%peA-5L0j}LUCv)q~eH*Lx{uSpzlAhz^=?ZR_W?Y7+yTDmdn2hMGkI~bN&Db z1Naodt$tugu$6!_m?572Zo8|$6N@)CcbUV@QgNvRZ^k^0w|@{_H5jlKYfGMbJx<=* zC@4KUd|d4&B)>nosOwl)hq>dEa26cC>R-?0@=NqwP5PTG>wso#BYiYb2o{U9#yic- zZgQQ}d|A`n_PJv~EXEiYAt*z?-JC_Qs-$HOT#a8dOHQv!EI)s-L%mS6-F5|&61C-IlG5?F8h)vo_viK3m*VFR4ahF1b>zIAkme%6gcQQ4Wp52wDXLfe?>h*$`j;A6 zT2Ax+c$W9Qc+N7#biVVEa8zWC^7;aB9o8U+u#7-h5a-&h)r vXxOgb$FsVM=Upd33%-3}qeeDO;7aSF7NIGFb2>Zo%+AJgz{r;`U%vkVZpZ{I literal 0 HcmV?d00001 diff --git a/tests/auto/gui/util/qtexturefilereader/tst_qtexturefilereader.cpp b/tests/auto/gui/util/qtexturefilereader/tst_qtexturefilereader.cpp index 9ff4f0ccf2..9b78d18954 100644 --- a/tests/auto/gui/util/qtexturefilereader/tst_qtexturefilereader.cpp +++ b/tests/auto/gui/util/qtexturefilereader/tst_qtexturefilereader.cpp @@ -49,33 +49,55 @@ void tst_qtexturefilereader::checkHandlers_data() QTest::addColumn>("dataOffsets"); QTest::addColumn>("dataLengths"); - QTest::addRow("pattern.pkm") << QStringLiteral(":/texturefiles/pattern.pkm") - << QSize(64, 64) - << quint32(0x0) - << quint32(0x8d64) - << quint32(0x0) - << 1 - << (QList() << 16) - << (QList() << 2048); + QTest::addRow("pattern.pkm") + << QStringLiteral(":/texturefiles/pattern.pkm") + << QSize(64, 64) + << quint32(0x0) + << quint32(0x8d64) + << quint32(0x0) + << 1 + << (QList() << 16) + << (QList() << 2048); - QTest::addRow("car.ktx") << QStringLiteral(":/texturefiles/car.ktx") - << QSize(146, 80) - << quint32(0x0) - << quint32(0x9278) - << quint32(0x1908) - << 1 - << (QList() << 68) - << (QList() << 11840); + QTest::addRow("car.ktx") + << QStringLiteral(":/texturefiles/car.ktx") + << QSize(146, 80) + << quint32(0x0) + << quint32(0x9278) + << quint32(0x1908) + << 1 + << (QList() << 68) + << (QList() << 11840); - QTest::addRow("car_mips.ktx") << QStringLiteral(":/texturefiles/car_mips.ktx") - << QSize(146, 80) - << quint32(0x0) - << quint32(0x9274) - << quint32(0x1907) - << 8 - << (QList() << 68 << 5992 << 7516 << 7880 << 8004 << 8056 << 8068 << 8080) - << (QList() << 5920 << 1520 << 360 << 120 << 48 << 8 << 8 << 8); + QTest::addRow("car_mips.ktx") + << QStringLiteral(":/texturefiles/car_mips.ktx") + << QSize(146, 80) + << quint32(0x0) + << quint32(0x9274) + << quint32(0x1907) + << 8 + << (QList() << 68 << 5992 << 7516 << 7880 << 8004 << 8056 << 8068 << 8080) + << (QList() << 5920 << 1520 << 360 << 120 << 48 << 8 << 8 << 8); + QTest::addRow("newlogo.astc") + << QStringLiteral(":/texturefiles/newlogo.astc") + << QSize(111, 78) + << quint32(0x0) + << quint32(0x93b9) + << quint32(0x0) + << 1 + << (QList() << 16) + << (QList() << 2496); + + QTest::addRow("newlogo_srgb.astc") + << QStringLiteral(":/texturefiles/newlogo_srgb.astc") + << QSize(111, 78) + << quint32(0x0) + << quint32(0x93d9) + << quint32(0x0) + << 1 + << (QList() << 16) + << (QList() << 2496); } void tst_qtexturefilereader::checkHandlers() From d15b02ff291e3124d9bb8ac3b06b704c292f52ab Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Wed, 20 Feb 2019 09:54:07 +0100 Subject: [PATCH 1276/1650] QOpenGLTexture::setData add overloads to allow specifying sub images All current setData implementation only allow to specify a full size sub image for a given mip level. In some cases, we might only want to update a small region on an image, in which cases being able to specify the x, y, z offsets as well as the dimensions is required. Change-Id: I880cfcc67a814733e8ab880aa8766c87b7bc7e45 Reviewed-by: Giuseppe D'Angelo --- src/gui/opengl/qopengltexture.cpp | 234 ++++++++++++++++++++++++++++++ src/gui/opengl/qopengltexture.h | 26 ++++ src/gui/opengl/qopengltexture_p.h | 4 + 3 files changed, 264 insertions(+) diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp index 5b7956d31e..f25988585e 100644 --- a/src/gui/opengl/qopengltexture.cpp +++ b/src/gui/opengl/qopengltexture.cpp @@ -1467,6 +1467,122 @@ void QOpenGLTexturePrivate::setData(int mipLevel, int layer, int layerCount, QOp } } +void QOpenGLTexturePrivate::setData(int xOffset, int yOffset, int zOffset, int width, int height, int depth, + int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace, + QOpenGLTexture::PixelFormat sourceFormat, QOpenGLTexture::PixelType sourceType, + const void *data, const QOpenGLPixelTransferOptions * const options) +{ + switch (target) { + case QOpenGLTexture::Target1D: + Q_UNUSED(layer); + Q_UNUSED(cubeFace); + Q_UNUSED(layerCount); + Q_UNUSED(yOffset); + Q_UNUSED(zOffset); + Q_UNUSED(height); + Q_UNUSED(depth); + texFuncs->glTextureSubImage1D(textureId, target, bindingTarget, mipLevel, + xOffset, width, + sourceFormat, sourceType, data, options); + break; + + case QOpenGLTexture::Target1DArray: + Q_UNUSED(cubeFace); + Q_UNUSED(yOffset); + Q_UNUSED(zOffset); + Q_UNUSED(height); + Q_UNUSED(depth); + texFuncs->glTextureSubImage2D(textureId, target, bindingTarget, mipLevel, + xOffset, layer, + width, + layerCount, + sourceFormat, sourceType, data, options); + break; + + case QOpenGLTexture::Target2D: + Q_UNUSED(layer); + Q_UNUSED(cubeFace); + Q_UNUSED(layerCount); + Q_UNUSED(zOffset); + Q_UNUSED(depth); + texFuncs->glTextureSubImage2D(textureId, target, bindingTarget, mipLevel, + xOffset, yOffset, + width, height, + sourceFormat, sourceType, data, options); + break; + + case QOpenGLTexture::Target2DArray: + Q_UNUSED(cubeFace); + Q_UNUSED(zOffset); + Q_UNUSED(depth); + texFuncs->glTextureSubImage3D(textureId, target, bindingTarget, mipLevel, + xOffset, yOffset, layer, + width, height, layerCount, + sourceFormat, sourceType, data, options); + break; + + case QOpenGLTexture::Target3D: + Q_UNUSED(cubeFace); + Q_UNUSED(layerCount); + texFuncs->glTextureSubImage3D(textureId, target, bindingTarget, mipLevel, + xOffset, yOffset, zOffset, + width, height, depth, + sourceFormat, sourceType, data, options); + break; + + case QOpenGLTexture::TargetCubeMap: + Q_UNUSED(layer); + Q_UNUSED(layerCount); + Q_UNUSED(zOffset); + Q_UNUSED(depth); + texFuncs->glTextureSubImage2D(textureId, cubeFace, bindingTarget, mipLevel, + xOffset, yOffset, + width, height, + sourceFormat, sourceType, data, options); + break; + + case QOpenGLTexture::TargetCubeMapArray: { + Q_UNUSED(zOffset); + Q_UNUSED(depth); + int faceIndex = cubeFace - QOpenGLTexture::CubeMapPositiveX; + int layerFace = 6 * layer + faceIndex; + texFuncs->glTextureSubImage3D(textureId, target, bindingTarget, mipLevel, + xOffset, yOffset, layerFace, + width, height, + layerCount, + sourceFormat, sourceType, data, options); + break; + } + + case QOpenGLTexture::TargetRectangle: + Q_UNUSED(mipLevel); + Q_UNUSED(layer); + Q_UNUSED(cubeFace); + Q_UNUSED(layerCount); + Q_UNUSED(zOffset); + Q_UNUSED(depth); + texFuncs->glTextureSubImage2D(textureId, target, bindingTarget, 0, + xOffset, yOffset, + width, height, + sourceFormat, sourceType, data, options); + break; + + case QOpenGLTexture::Target2DMultisample: + case QOpenGLTexture::Target2DMultisampleArray: + case QOpenGLTexture::TargetBuffer: + // We don't upload pixel data for these targets + qWarning("QOpenGLTexture::setData(): Texture target does not support pixel data upload"); + break; + } + + // If requested perform automatic mip map generation + if (mipLevel == 0 && autoGenerateMipMaps && mipLevels > 1) { + Q_Q(QOpenGLTexture); + q->generateMipMaps(); + } +} + + void QOpenGLTexturePrivate::setCompressedData(int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace, int dataSize, const void *data, @@ -3380,6 +3496,124 @@ void QOpenGLTexture::setData(PixelFormat sourceFormat, PixelType sourceType, d->setData(0, 0, 1, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options); } +/*! + \since 5.14 + \overload + + This overload is to be used to update a part of the texture. Parameters \a + xOffset, \a yOffset, \a zOffset specify the texel offsets within the + texture. Parameters \a width, \a height and \a depth specify the dimensions + of the sub image. + + The structure of the pixel data pointed to by \a data is specified by \a + sourceFormat and \a sourceType. The pixel data upload can optionally be + controlled by \a options. +*/ +void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset, + int width, int height, int depth, + PixelFormat sourceFormat, PixelType sourceType, + const void *data, const QOpenGLPixelTransferOptions * const options) +{ + Q_D(QOpenGLTexture); + Q_ASSERT(d->textureId); + d->setData(xOffset, yOffset, zOffset, + width, height, depth, + 0, 0, 1, + QOpenGLTexture::CubeMapPositiveX, sourceFormat, + sourceType, data, options); +} + +/*! + \since 5.14 + \overload + + This overload is to be used to update a part of the texture. Parameters \a + xOffset, \a yOffset, \a zOffset specify the texel offsets within the + texture. Parameters \a width, \a height and \a depth specify the dimensions + of the sub image. The mip map level and layerof the sub image we want to + update are specified with \a mipLevel and \a layer. + + The structure of the pixel data pointed to by \a data is specified by \a + sourceFormat and \a sourceType. The pixel data upload can optionally be + controlled by \a options. +*/ +void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset, + int width, int height, int depth, + int mipLevel, int layer, + PixelFormat sourceFormat, PixelType sourceType, + const void *data, const QOpenGLPixelTransferOptions * const options) +{ + Q_D(QOpenGLTexture); + Q_ASSERT(d->textureId); + d->setData(xOffset, yOffset, zOffset, + width, height, depth, + mipLevel, layer, 1, + QOpenGLTexture::CubeMapPositiveX, sourceFormat, + sourceType, data, options); +} + +/*! + \since 5.14 + \overload + + This overload is to be used to update a part of the texture. Parameters \a + xOffset, \a yOffset, \a zOffset specify the texel offsets within the + texture. Parameters \a width, \a height and \a depth specify the dimensions + of the sub image.The mip map level, layer and cube map face of the sub + image we want to update are specified with \a mipLevel, \a layer and \a + face. + + The structure of the pixel data pointed to by \a data is specified by \a + sourceFormat and \a sourceType. The pixel data upload can optionally be + controlled by \a options. +*/ +void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset, + int width, int height, int depth, + int mipLevel, int layer, + CubeMapFace face, + PixelFormat sourceFormat, PixelType sourceType, + const void *data, const QOpenGLPixelTransferOptions * const options) +{ + Q_D(QOpenGLTexture); + Q_ASSERT(d->textureId); + d->setData(xOffset, yOffset, zOffset, + width, height, depth, + mipLevel, layer, 1, + face, sourceFormat, + sourceType, data, options); +} + +/*! + \since 5.14 + \overload + + This overload is to be used to update a part of the texture. Parameters \a + xOffset, \a yOffset, \a zOffset specify the texel offsets within the + texture. Parameters \a width, \a height and \a depth specify the dimensions + of the sub image.The mip map level, starting layer, cube map face and + number of layers of the sub image we want to update are specified with \a + mipLevel, \a layer, \a face and \a layerCount. + + The structure of the pixel data pointed to by \a data is specified by \a + sourceFormat and \a sourceType. The pixel data upload can optionally be + controlled by \a options. +*/ +void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset, + int width, int height, int depth, + int mipLevel, int layer, + CubeMapFace face, int layerCount, + PixelFormat sourceFormat, PixelType sourceType, + const void *data, const QOpenGLPixelTransferOptions * const options) +{ + Q_D(QOpenGLTexture); + Q_ASSERT(d->textureId); + d->setData(xOffset, yOffset, zOffset, + width, height, depth, + mipLevel, layer, layerCount, + face, sourceFormat, + sourceType, data, options); +} + #if QT_DEPRECATED_SINCE(5, 3) /*! \obsolete diff --git a/src/gui/opengl/qopengltexture.h b/src/gui/opengl/qopengltexture.h index c0c5283374..7d984babc8 100644 --- a/src/gui/opengl/qopengltexture.h +++ b/src/gui/opengl/qopengltexture.h @@ -485,6 +485,32 @@ public: void setData(PixelFormat sourceFormat, PixelType sourceType, const void *data, const QOpenGLPixelTransferOptions * const options = nullptr); + void setData(int xOffset, int yOffset, int zOffset, + int width, int height, int depth, + PixelFormat sourceFormat, PixelType sourceType, + const void *data, const QOpenGLPixelTransferOptions * const options = nullptr); + void setData(int xOffset, int yOffset, int zOffset, + int width, int height, int depth, int mipLevel, + PixelFormat sourceFormat, PixelType sourceType, + const void *data, const QOpenGLPixelTransferOptions * const options = nullptr); + void setData(int xOffset, int yOffset, int zOffset, + int width, int height, int depth, + int mipLevel, int layer, + PixelFormat sourceFormat, PixelType sourceType, + const void *data, const QOpenGLPixelTransferOptions * const options = nullptr); + void setData(int xOffset, int yOffset, int zOffset, + int width, int height, int depth, + int mipLevel, int layer, + CubeMapFace cubeFace, + PixelFormat sourceFormat, PixelType sourceType, + const void *data, const QOpenGLPixelTransferOptions * const options = nullptr); + void setData(int xOffset, int yOffset, int zOffset, + int width, int height, int depth, + int mipLevel, int layer, + CubeMapFace cubeFace, int layerCount, + PixelFormat sourceFormat, PixelType sourceType, + const void *data, const QOpenGLPixelTransferOptions * const options = nullptr); + // Compressed data upload // ### Qt 6: remove the non-const void * overloads #if QT_DEPRECATED_SINCE(5, 3) diff --git a/src/gui/opengl/qopengltexture_p.h b/src/gui/opengl/qopengltexture_p.h index f7694f77bc..9f3457ad0a 100644 --- a/src/gui/opengl/qopengltexture_p.h +++ b/src/gui/opengl/qopengltexture_p.h @@ -101,6 +101,10 @@ public: void setData(int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace, QOpenGLTexture::PixelFormat sourceFormat, QOpenGLTexture::PixelType sourceType, const void *data, const QOpenGLPixelTransferOptions * const options); + void setData(int xOffset, int yOffset, int zOffset, int width, int height, int depth, + int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace, + QOpenGLTexture::PixelFormat sourceFormat, QOpenGLTexture::PixelType sourceType, + const void *data, const QOpenGLPixelTransferOptions * const options); void setCompressedData(int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace, int dataSize, const void *data, const QOpenGLPixelTransferOptions * const options); From 2ec47d6cb53066b052c13d088e249a44f8a04c79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Tue, 26 Feb 2019 12:57:00 +0100 Subject: [PATCH 1277/1650] Fix crash in QTest's signal dumper It Q_ASSERTs that argv is not a nullptr, so it would fail when an unconnected signal with 0 arguments was emitted. Change-Id: I5dd810fbeea5b6b511eff4705efdaa6a55739604 Reviewed-by: Thiago Macieira --- src/corelib/kernel/qobject.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 1382015d76..63bb386107 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -3593,6 +3593,10 @@ void doActivate(QObject *sender, int signal_index, void **argv) const QSignalSpyCallbackSet *signal_spy_set = callbacks_enabled ? qt_signal_spy_callback_set.load() : nullptr; + void *empty_argv[] = { nullptr }; + if (!argv) + argv = empty_argv; + if (!sp->isSignalConnected(signal_index, false)) { // The possible declarative connection is done, and nothing else is connected if (callbacks_enabled && signal_spy_set->signal_begin_callback != nullptr) @@ -3604,10 +3608,6 @@ void doActivate(QObject *sender, int signal_index, void **argv) return; } - void *empty_argv[] = { nullptr }; - if (!argv) - argv = empty_argv; - if (callbacks_enabled && signal_spy_set->signal_begin_callback != nullptr) signal_spy_set->signal_begin_callback(sender, signal_index, argv); Q_TRACE(QMetaObject_activate_begin_signal, sender, signal_index); From ca991ee22d3509f8f54ee26d4c30d45319428c8f Mon Sep 17 00:00:00 2001 From: Elena Zaretskaya Date: Thu, 14 Feb 2019 09:49:33 -0500 Subject: [PATCH 1278/1650] Segfault when the exiting the application under platform eglfs If you run an application under eglfs, it falls with segfault on the exit. For example, examples/gui/analogclock, examples/widgets/widgets/analogclock, examples/opengl/cube, examples/opengl/qopenglwidget, etc. (I have added the function keyPressEvent to exit by qApp->quit(), if needed). It isn't appear in applications using QQuickView or QGLWindow. This is because QCoreApplication destructor, where the variable self = 0 (therefore, qGuiApp = 0), is called before than QOpenGLVertexArrayObject::destroy(), where qGuiApp is accessed (qGuiApp->thread()). Task-number: QTBUG-73824 Change-Id: I1dc55d5e811bfe8a8ea2178752e8771f8644d356 Reviewed-by: Laszlo Agocs --- .../platforms/eglfs/api/qeglfsscreen.cpp | 3 --- .../platforms/eglfs/api/qeglfswindow.cpp | 27 ++++++++++++------- .../platforms/eglfs/api/qeglfswindow_p.h | 1 + 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp index 285dbd93d3..11b68c0589 100644 --- a/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp @@ -62,9 +62,6 @@ QEglFSScreen::QEglFSScreen(EGLDisplay dpy) QEglFSScreen::~QEglFSScreen() { delete m_cursor; -#ifndef QT_NO_OPENGL - QOpenGLCompositor::destroy(); -#endif } QRect QEglFSScreen::geometry() const diff --git a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp index 29cfd4ea79..98e9ee4728 100644 --- a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp +++ b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp @@ -62,6 +62,7 @@ QEglFSWindow::QEglFSWindow(QWindow *w) : QPlatformWindow(w), #ifndef QT_NO_OPENGL m_backingStore(0), + m_rasterCompositingContext(0), #endif m_raster(false), m_winId(0), @@ -144,18 +145,18 @@ void QEglFSWindow::create() #ifndef QT_NO_OPENGL if (isRaster()) { - QOpenGLContext *context = new QOpenGLContext(QGuiApplication::instance()); - context->setShareContext(qt_gl_global_share_context()); - context->setFormat(m_format); - context->setScreen(window()->screen()); - if (Q_UNLIKELY(!context->create())) + m_rasterCompositingContext = new QOpenGLContext; + m_rasterCompositingContext->setShareContext(qt_gl_global_share_context()); + m_rasterCompositingContext->setFormat(m_format); + m_rasterCompositingContext->setScreen(window()->screen()); + if (Q_UNLIKELY(!m_rasterCompositingContext->create())) qFatal("EGLFS: Failed to create compositing context"); - compositor->setTarget(context, window(), screen->rawGeometry()); + compositor->setTarget(m_rasterCompositingContext, window(), screen->rawGeometry()); compositor->setRotation(qEnvironmentVariableIntValue("QT_QPA_EGLFS_ROTATION")); // If there is a "root" window into which raster and QOpenGLWidget content is // composited, all other contexts must share with its context. if (!qt_gl_global_share_context()) { - qt_gl_set_global_share_context(context); + qt_gl_set_global_share_context(m_rasterCompositingContext); // What we set up here is in effect equivalent to the application setting // AA_ShareOpenGLContexts. Set the attribute to be fully consistent. QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); @@ -166,6 +167,10 @@ void QEglFSWindow::create() void QEglFSWindow::destroy() { +#ifndef QT_NO_OPENGL + QOpenGLCompositor::instance()->removeWindow(this); +#endif + QEglFSScreen *screen = this->screen(); if (m_flags.testFlag(HasNativeWindow)) { #ifndef QT_NO_OPENGL @@ -177,12 +182,14 @@ void QEglFSWindow::destroy() screen->setPrimarySurface(EGL_NO_SURFACE); invalidateSurface(); + +#ifndef QT_NO_OPENGL + QOpenGLCompositor::destroy(); + delete m_rasterCompositingContext; +#endif } m_flags = 0; -#ifndef QT_NO_OPENGL - QOpenGLCompositor::instance()->removeWindow(this); -#endif } void QEglFSWindow::invalidateSurface() diff --git a/src/plugins/platforms/eglfs/api/qeglfswindow_p.h b/src/plugins/platforms/eglfs/api/qeglfswindow_p.h index c61f04f569..b0091e2a62 100644 --- a/src/plugins/platforms/eglfs/api/qeglfswindow_p.h +++ b/src/plugins/platforms/eglfs/api/qeglfswindow_p.h @@ -116,6 +116,7 @@ public: protected: #ifndef QT_NO_OPENGL QOpenGLCompositorBackingStore *m_backingStore; + QOpenGLContext *m_rasterCompositingContext; #endif bool m_raster; WId m_winId; From f657c7426329d3763bbf3373b986378c22020269 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Thu, 7 Feb 2019 13:58:12 +0300 Subject: [PATCH 1279/1650] QListView: Fix Shift+click selection for non-default itemAlignment QListView::setSelection() algorithm is designed for items to occupy their cells completely, which is not the case when itemAlignment is used. The middle part of the selection rect goes beyond the column borders and extra items are selected. Use the introduced cellRectForIndex() instead of rectForIndex() to calculate the middle part correctly. Fixes: QTBUG-73684 Change-Id: I4a1e42a056d56e85a16d8ae0ffe18b78d1d6deb7 Reviewed-by: Richard Moe Gustavsen --- src/widgets/itemviews/qlistview.cpp | 4 +- src/widgets/itemviews/qlistview_p.h | 19 +++++++- .../itemviews/qlistview/tst_qlistview.cpp | 46 +++++++++++++++++++ 3 files changed, 66 insertions(+), 3 deletions(-) diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index 6b5857f1ca..e07514f297 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -1315,8 +1315,8 @@ void QListView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFl if (tl.isValid() && br.isValid() && d->isIndexEnabled(tl) && d->isIndexEnabled(br)) { - QRect first = rectForIndex(tl); - QRect last = rectForIndex(br); + QRect first = d->cellRectForIndex(tl); + QRect last = d->cellRectForIndex(br); QRect middle; if (d->flow == LeftToRight) { QRect &top = first; diff --git a/src/widgets/itemviews/qlistview_p.h b/src/widgets/itemviews/qlistview_p.h index 181386d4d0..c94357afe9 100644 --- a/src/widgets/itemviews/qlistview_p.h +++ b/src/widgets/itemviews/qlistview_p.h @@ -333,14 +333,31 @@ public: inline QModelIndex listViewItemToIndex(const QListViewItem &item) const { return model->index(commonListView->itemIndex(item), column, root); } + inline bool hasRectForIndex(const QModelIndex &index) const + { + return isIndexValid(index) && index.parent() == root && index.column() == column && !isHidden(index.row()); + } + QRect rectForIndex(const QModelIndex &index) const { - if (!isIndexValid(index) || index.parent() != root || index.column() != column || isHidden(index.row())) + if (!hasRectForIndex(index)) return QRect(); executePostedLayout(); return viewItemRect(indexToListViewItem(index)); } + QRect cellRectForIndex(const QModelIndex &index) + { + if (!hasRectForIndex(index)) + return QRect(); + executePostedLayout(); + auto oldItemAlignment = itemAlignment; + itemAlignment = Qt::Alignment(); + const QRect rect = rectForIndex(index); + itemAlignment = oldItemAlignment; + return rect; + } + void viewUpdateGeometries() { q_func()->updateGeometries(); } diff --git a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp index 9175c0bff4..9511654110 100644 --- a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp +++ b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp @@ -121,6 +121,7 @@ private slots: void task254449_draggingItemToNegativeCoordinates(); void keyboardSearch(); void shiftSelectionWithNonUniformItemSizes(); + void shiftSelectionWithItemAlignment(); void clickOnViewportClearsSelection(); void task262152_setModelColumnNavigate(); void taskQTBUG_2233_scrollHiddenItems_data(); @@ -1798,6 +1799,51 @@ void tst_QListView::shiftSelectionWithNonUniformItemSizes() } } +void tst_QListView::shiftSelectionWithItemAlignment() +{ + QStringList items; + for (int c = 0; c < 2; c++) { + for (int i = 10; i > 0; i--) + items << QString(i, QLatin1Char('*')); + + for (int i = 1; i < 11; i++) + items << QString(i, QLatin1Char('*')); + } + + QListView view; + view.setFlow(QListView::TopToBottom); + view.setWrapping(true); + view.setItemAlignment(Qt::AlignLeft); + view.setSelectionMode(QAbstractItemView::ExtendedSelection); + + QStringListModel model(items); + view.setModel(&model); + + QFont font = view.font(); + font.setPixelSize(10); + view.setFont(font); + view.resize(300, view.sizeHintForRow(0) * items.size() / 2 + view.horizontalScrollBar()->height()); + + view.show(); + QApplication::setActiveWindow(&view); + QVERIFY(QTest::qWaitForWindowActive(&view)); + QCOMPARE(static_cast(&view), QApplication::activeWindow()); + + QModelIndex index1 = view.model()->index(items.size() / 4, 0); + QPoint p = view.visualRect(index1).center(); + QVERIFY(view.viewport()->rect().contains(p)); + QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, p); + QCOMPARE(view.currentIndex(), index1); + QCOMPARE(view.selectionModel()->selectedIndexes().size(), 1); + + QModelIndex index2 = view.model()->index(items.size() / 4 * 3, 0); + p = view.visualRect(index2).center(); + QVERIFY(view.viewport()->rect().contains(p)); + QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::ShiftModifier, p); + QCOMPARE(view.currentIndex(), index2); + QCOMPARE(view.selectionModel()->selectedIndexes().size(), index2.row() - index1.row() + 1); +} + void tst_QListView::clickOnViewportClearsSelection() { QStringList items; From f6ce77f3e4dbc67531db7eeaf271c5416b4a4934 Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Tue, 26 Feb 2019 11:58:12 +1000 Subject: [PATCH 1280/1650] wasm: activateWindow when needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-74066 Change-Id: I6babab888de118c8c881fd8a18a90049563d7a23 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/wasm/qwasmeventtranslator.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp index ddf0ff61e5..334f183703 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp @@ -550,8 +550,11 @@ void QWasmEventTranslator::processMouse(int eventType, const EmscriptenMouseEven switch (eventType) { case EMSCRIPTEN_EVENT_MOUSEDOWN: { - if (window2) + if (window2) { window2->raise(); + if (!window2->isActive()) + window2->requestActivate(); + } pressedButtons.setFlag(button); From 15adc79bbcaa909f43c2da3c61306cc2138567fa Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Fri, 22 Feb 2019 06:50:58 +1000 Subject: [PATCH 1281/1650] wasm: fix clipboard use MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change 5242126a inadvertantly removed clipboard functionality Change-Id: Ie15e08470dd51d1c166063bbd443fd04416b2786 Reviewed-by: Morten Johan Sørvig --- .../platforms/wasm/qwasmeventtranslator.cpp | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp index 334f183703..3fc8f600a1 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp @@ -831,16 +831,30 @@ bool QWasmEventTranslator::processKeyboard(int eventType, const EmscriptenKeyboa if (keyType == QEvent::None) return 0; + QFlags mods = translateKeyboardEventModifier(keyEvent); bool accepted = false; - if (keyText.isEmpty()) - keyText = QString(keyEvent->key); - if (keyText.size() > 1) - keyText.clear(); - accepted = QWindowSystemInterface::handleKeyEvent( - 0, keyType, qtKey, modifiers, keyText); + if (keyType == QEvent::KeyPress && + mods.testFlag(Qt::ControlModifier) + && qtKey == Qt::Key_V) { + QWasmIntegration::get()->getWasmClipboard()->readTextFromClipboard(); + } else { + if (keyText.isEmpty()) + keyText = QString(keyEvent->key); + if (keyText.size() > 1) + keyText.clear(); + accepted = QWindowSystemInterface::handleKeyEvent( + 0, keyType, qtKey, modifiers, keyText); + } + if (keyType == QEvent::KeyPress && + mods.testFlag(Qt::ControlModifier) + && qtKey == Qt::Key_C) { + QWasmIntegration::get()->getWasmClipboard()->writeTextToClipboard(); + } + QWasmEventDispatcher::maintainTimers(); - return accepted ? 1 : 0; + + return accepted; } QT_END_NAMESPACE From 01f5d41a406b7baf1cb01692c870e5084fc11b1f Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Wed, 20 Feb 2019 13:30:52 +0100 Subject: [PATCH 1282/1650] Make tst_QUdpSocket::lincLocalIPv6 less sadistic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It fails on CI (Windows 10). Given our qabstractsocket disables read notifications/stops emitting readyRead if it already has pending data (unbuffered, aka UDP socket type) - make sure we do not suffer from this. The change does not affect the test's logic (unless the logic was to fail), it just makes it more fail-proof. Change-Id: I6c9b7ded20478f675260872a2a7032b4f356f197 Fixes: QTBUG-73884 Reviewed-by: Edward Welbourne Reviewed-by: Mårten Nordheim (cherry picked from commit d3eb9e944ac73f238b8716bb25b8051377bba946) Reviewed-by: Timur Pocheptsov --- tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp index 8ebb27e58c..707c1acf48 100644 --- a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp @@ -1640,15 +1640,14 @@ void tst_QUdpSocket::linkLocalIPv6() sockets << s; } - QUdpSocket neutral; - QVERIFY(neutral.bind(QHostAddress(QHostAddress::AnyIPv6))); - QSignalSpy neutralReadSpy(&neutral, SIGNAL(readyRead())); - QByteArray testData("hello"); foreach (QUdpSocket *s, sockets) { + QUdpSocket neutral; + QVERIFY(neutral.bind(QHostAddress(QHostAddress::AnyIPv6))); + QSignalSpy neutralReadSpy(&neutral, SIGNAL(readyRead())); + QSignalSpy spy(s, SIGNAL(readyRead())); - neutralReadSpy.clear(); QVERIFY(s->writeDatagram(testData, s->localAddress(), neutral.localPort())); QTRY_VERIFY(neutralReadSpy.count() > 0); //note may need to accept a firewall prompt From e8d3306c8f86bf21648693521d8be91bb8f1335e Mon Sep 17 00:00:00 2001 From: Antti Kokko Date: Wed, 20 Feb 2019 15:21:30 +0200 Subject: [PATCH 1283/1650] Add changes file for Qt 5.12.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Done-with: Thiago Macieira Change-Id: Ia8c265403aa557be180eaa634474fb5f96a52b9f Reviewed-by: Edward Welbourne Reviewed-by: Tor Arne Vestbø Reviewed-by: Thiago Macieira --- dist/changes-5.12.2 | 105 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 dist/changes-5.12.2 diff --git a/dist/changes-5.12.2 b/dist/changes-5.12.2 new file mode 100644 index 0000000000..dc61d135a7 --- /dev/null +++ b/dist/changes-5.12.2 @@ -0,0 +1,105 @@ +Qt 5.12.2 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.12.0 through 5.12.1. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.12 series is binary compatible with the 5.11.x series. +Applications compiled for 5.11 will continue to run with 5.12. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Important Behavior Changes * +**************************************************************************** + + - QtTestLib: + * [QTBUG-72928] Blacklisting of tests will be taken into account for + XPASS and XFAIL. A blacklisted test that causes an XPASS will no + longer be a fail. + +**************************************************************************** +* QtCore * +**************************************************************************** + + - [QTBUG-72885] Fixed a number of warnings with Clang or Clang-Tidy in + Qt headers related to alignment of Qt private classes. + + - QDate, QTime and QDateTime; + * [QTBUG-51208] Corrected documentation of how non-placeholder + characters are handled in format patterns passed to toString(). + + - QCoreApplication: + * [QTBUG-57171] Fixed an out-of-bounds access if the translatable + string passed to tr() ended in '%'. + + - QFileInfo: + * [QTBUG-72644] Fixed a bug that would cause QFileInfo to report an + link incorrectly as a non-link. + + - QLocale: + * Fixed a crash if qDebug() is used after main() has exited. + * [QTBUG-73403] Fixed a race condition in getting the system locale + (possible regression from Qt 5.11.x) + + - QSysInfo: + * Fixed a bug on BSD systems in getting the machineUniqueId(). + * Fixed a bug on Windows in 32-bit applications getting the + machineUniqueId() when the OS is 64-bit. + + - QWaitCondition: + * Fixed handling of wait(QDeadlineTimer::Forever) on 32-bit platforms. + +**************************************************************************** +* QtWidgets * +**************************************************************************** + + - ItemViews: + * Fixed a regression with wrongly drawn centered/right aligned item + texts + +**************************************************************************** +* Third-Party Code * +**************************************************************************** + + - libpng was updated to version 1.6.36 + +**************************************************************************** +* Freetype * +**************************************************************************** + + - Upgraded bundled Freetype version to 2.9.1. This also adds support for + the latest emoji font in use on Android 9. + +**************************************************************************** +* Android * +**************************************************************************** + + - Added the --no-strip command line option to androiddeployqt. + + - qmake: + * Can now set the version name and code for Android using + ANDROID_VERSION_NAME and ANDROID_VERSION_CODE respectively in the pro + file. + +**************************************************************************** +* Windows * +**************************************************************************** + + - Fixed an issue where loading fonts from files or data would sometimes + mistakenly classify them as oblique. + +**************************************************************************** +* qmake * +**************************************************************************** + + - [QTBUG-27079] A new feature "cmdline" was added that implies "CONFIG += + console" and "CONFIG -= app_bundle". From 077e4993046ee5e564dfcc7710d07c905f2dee83 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 26 Feb 2019 11:55:15 +0100 Subject: [PATCH 1284/1650] Handle QMAKE_SUBSTITUTES input files as Latin 1 QMake's strategy is generally "pretend everything is Latin 1", which basically equals "do 8-bit pass-through". Change the handling of QMAKE_SUBSTITUTES input accordingly to avoid conversion losses when converting from and to UTF-8. Fixes: QTBUG-72130 Change-Id: Id903bbd2afa99708c92fd09fab3db944aa819a94 Reviewed-by: Oliver Wolff Reviewed-by: Kai Koehne --- qmake/generators/makefile.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 7762e47f41..ab261d02f1 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -532,7 +532,7 @@ MakefileGenerator::init() QStack state; enum { IN_CONDITION, MET_CONDITION, PENDING_CONDITION }; for (int count = 1; !in.atEnd(); ++count) { - QString line = QString::fromUtf8(in.readLine()); + QString line = QString::fromLatin1(in.readLine()); if (line.startsWith("!!IF ")) { if (state.isEmpty() || state.top() == IN_CONDITION) { QString test = line.mid(5, line.length()-(5+1)); @@ -578,7 +578,7 @@ MakefileGenerator::init() contents += project->expand(line, in.fileName(), count); } } - contentBytes = contents.toUtf8(); + contentBytes = contents.toLatin1(); } QFile out(outn); QFileInfo outfi(out); From 8880ef79311d283a1357ca0c14be6e56281ba5f0 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Mon, 11 Feb 2019 19:41:48 +0200 Subject: [PATCH 1285/1650] Terminate Qt gracefully When the application is closed via the task manager on Android then we need to ensure that that the application can close down any running event loops. So we wake up all the event loops and then call quit() directly on the application object to start a graceful termination of the application. In order to aid the graceful termination of Qt then a check is added to ensure that it does not try to create a new surface when the application is suspended. This prevents it from locking while trying to create a new surface when this is not possible. Fixes: QTBUG-70772 Change-Id: I6795b3d280e178d7f1207004a1b965a31a0cc9e9 Reviewed-by: Paul Olav Tvete Reviewed-by: Andy Shaw --- src/plugins/platforms/android/androidjnimain.cpp | 16 +++++++++------- .../android/qandroidplatformopenglwindow.cpp | 3 ++- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index 13d41bea99..74edfd8356 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -560,10 +560,15 @@ static void quitQtAndroidPlugin(JNIEnv *env, jclass /*clazz*/) static void terminateQt(JNIEnv *env, jclass /*clazz*/) { // QAndroidEventDispatcherStopper is stopped when the user uses the task manager to kill the application - if (!QAndroidEventDispatcherStopper::instance()->stopped()) { - sem_wait(&m_terminateSemaphore); - sem_destroy(&m_terminateSemaphore); + if (QAndroidEventDispatcherStopper::instance()->stopped()) { + QAndroidEventDispatcherStopper::instance()->startAll(); + QCoreApplication::quit(); + QAndroidEventDispatcherStopper::instance()->goingToStop(false); } + + sem_wait(&m_terminateSemaphore); + sem_destroy(&m_terminateSemaphore); + env->DeleteGlobalRef(m_applicationClass); env->DeleteGlobalRef(m_classLoaderObject); if (m_resourcesObj) @@ -583,10 +588,7 @@ static void terminateQt(JNIEnv *env, jclass /*clazz*/) m_androidPlatformIntegration = nullptr; delete m_androidAssetsFileEngineHandler; m_androidAssetsFileEngineHandler = nullptr; - - if (!QAndroidEventDispatcherStopper::instance()->stopped()) { - sem_post(&m_exitSemaphore); - } + sem_post(&m_exitSemaphore); } static void setSurface(JNIEnv *env, jobject /*thiz*/, jint id, jobject jSurface, jint w, jint h) diff --git a/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp b/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp index 3e1cfe305d..3de5d30623 100644 --- a/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp +++ b/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp @@ -47,6 +47,7 @@ #include #include +#include #include #include @@ -121,7 +122,7 @@ void QAndroidPlatformOpenGLWindow::setGeometry(const QRect &rect) EGLSurface QAndroidPlatformOpenGLWindow::eglSurface(EGLConfig config) { - if (QAndroidEventDispatcherStopper::stopped()) + if (QAndroidEventDispatcherStopper::stopped() || QGuiApplication::applicationState() == Qt::ApplicationSuspended) return m_eglSurface; QMutexLocker lock(&m_surfaceMutex); From 11c728713ff56c6c8e5fce60bde9147ddaafc802 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Mon, 11 Feb 2019 11:33:56 +0100 Subject: [PATCH 1286/1650] Android: Show correct keyboard when using Gboard and Japanese layout In 71a63836ed5d21feacbfcdbfdbd4b405f635282f a workaround for Samsung devices using ImhNoPredictiveText was included as there is a bug on those devices. However this causes a problem with other keyboards such as Gboard when using languages such as Japanese, as it would not show the right keyboard at all and only showed a qwerty one in those cases. Therefore we default to not working around the issue as it is more of a problem to not allow certain keyboard layouts as opposed to having predictive text even if it is turned off. For those who want to disable predictive text and as such have the consequences of not showing some keyboard layouts, they can set the QT_ANDROID_ENABLE_WORKAROUND_TO_DISABLE_PREDICTIVE_TEXT environment variable. [ChangeLog][Platform Specific Changes][Android] Text fields with ImhNoPredictiveText set are no longer working around keyboards that disregard this setting. To enforce the workaround then the environment variable - QT_ANDROID_ENABLE_WORKAROUND_TO_DISABLE_PREDICTIVE_TEXT should be set. Change-Id: I9ace7ba96ebad68987b53783e25067b66c002f25 Reviewed-by: Paul Olav Tvete --- .../jar/src/org/qtproject/qt5/android/QtActivityDelegate.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index 4b87c25787..350c6eee96 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -346,7 +346,9 @@ public class QtActivityDelegate } } else if ((inputHints & ImhHiddenText) != 0) { inputType |= android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD; - } else if ((inputHints & ImhSensitiveData) != 0 || (inputHints & ImhNoPredictiveText) != 0) { + } else if ((inputHints & ImhSensitiveData) != 0 || + ((inputHints & ImhNoPredictiveText) != 0 && + System.getenv("QT_ANDROID_ENABLE_WORKAROUND_TO_DISABLE_PREDICTIVE_TEXT") != null)) { inputType |= android.text.InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD; } From 1844f011f67a767d163d16d5338ad24ade7eb0c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Thu, 7 Feb 2019 13:23:36 +0100 Subject: [PATCH 1287/1650] Convert the QSocks5SocketEngine test to use Docker Change-Id: I5d223758471a72c93ad57d250001c1de51a208cd Reviewed-by: Timur Pocheptsov --- tests/auto/network-settings.h | 24 ++++++++++- .../qsocks5socketengine.pro | 6 +++ .../tst_qsocks5socketengine.cpp | 42 +++++++++++-------- tests/testserver/cyrus/cyrus.sh | 34 +++++++++++++++ tests/testserver/docker-compose.yml | 12 ++++++ 5 files changed, 98 insertions(+), 20 deletions(-) create mode 100755 tests/testserver/cyrus/cyrus.sh diff --git a/tests/auto/network-settings.h b/tests/auto/network-settings.h index f162c3ae9f..092830a51a 100644 --- a/tests/auto/network-settings.h +++ b/tests/auto/network-settings.h @@ -72,15 +72,20 @@ public: } #ifdef QT_NETWORK_LIB - static QHostAddress serverIP() + static QHostAddress getServerIpImpl(const QString &serverName) { - const QHostInfo info = QHostInfo::fromName(serverName()); + const QHostInfo info = QHostInfo::fromName(serverName); if (info.error()) { QTest::qFail(qPrintable(info.errorString()), __FILE__, __LINE__); return QHostAddress(); } return info.addresses().constFirst(); } + + static QHostAddress serverIP() + { + return getServerIpImpl(serverName()); + } #endif static bool compareReplyIMAP(QByteArray const& actual) @@ -214,4 +219,19 @@ public: return serverName(); #endif } + static QString imapServerName() + { +#ifdef QT_TEST_SERVER_NAME + return QString("cyrus.") % serverDomainName(); +#else + return serverName(); +#endif + } + +#ifdef QT_NETWORK_LIB + static QHostAddress imapServerIp() + { + return getServerIpImpl(imapServerName()); + } +#endif }; diff --git a/tests/auto/network/socket/qsocks5socketengine/qsocks5socketengine.pro b/tests/auto/network/socket/qsocks5socketengine/qsocks5socketengine.pro index 71ceafa133..ca9e44873c 100644 --- a/tests/auto/network/socket/qsocks5socketengine/qsocks5socketengine.pro +++ b/tests/auto/network/socket/qsocks5socketengine/qsocks5socketengine.pro @@ -11,3 +11,9 @@ MOC_DIR=tmp QT = core-private network-private testlib requires(qtConfig(private_tests)) + +# Only on Linux until cyrus has been added to docker-compose-for-{windows,macOS}.yml and tested +linux { + QT_TEST_SERVER_LIST = danted apache2 cyrus + include($$dirname(_QMAKE_CONF_)/tests/auto/testserver.pri) +} diff --git a/tests/auto/network/socket/qsocks5socketengine/tst_qsocks5socketengine.cpp b/tests/auto/network/socket/qsocks5socketengine/tst_qsocks5socketengine.cpp index 1212ea20e5..464054f8a6 100644 --- a/tests/auto/network/socket/qsocks5socketengine/tst_qsocks5socketengine.cpp +++ b/tests/auto/network/socket/qsocks5socketengine/tst_qsocks5socketengine.cpp @@ -137,7 +137,13 @@ private slots: void tst_QSocks5SocketEngine::initTestCase() { +#ifdef QT_TEST_SERVER + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::socksProxyServerName(), 1080)); + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::httpServerName(), 80)); + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::imapServerName(), 143)); +#else QVERIFY(QtNetworkSettings::verifyTestNetworkSettings()); +#endif } //--------------------------------------------------------------------------- @@ -293,13 +299,13 @@ void tst_QSocks5SocketEngine::simpleConnectToIMAP() QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol)); QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState); - socketDevice.setProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1080)); + socketDevice.setProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::socksProxyServerName(), 1080)); - QVERIFY(!socketDevice.connectToHost(QtNetworkSettings::serverIP(), 143)); + QVERIFY(!socketDevice.connectToHost(QtNetworkSettings::imapServerIp(), 143)); QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectingState); QVERIFY(socketDevice.waitForWrite()); QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectedState); - QCOMPARE(socketDevice.peerAddress(), QtNetworkSettings::serverIP()); + QCOMPARE(socketDevice.peerAddress(), QtNetworkSettings::imapServerIp()); // Wait for the greeting QVERIFY(socketDevice.waitForRead()); @@ -347,10 +353,10 @@ void tst_QSocks5SocketEngine::simpleErrorsAndStates() // Initialize device QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol)); - socketDevice.setProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1080)); + socketDevice.setProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::socksProxyServerName(), 1080)); QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState); - QVERIFY(!socketDevice.connectToHost(QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first(), 8088)); + QVERIFY(!socketDevice.connectToHost(QHostInfo::fromName(QtNetworkSettings::socksProxyServerName()).addresses().first(), 8088)); QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectingState); if (socketDevice.waitForWrite(15000)) { QVERIFY(socketDevice.state() == QAbstractSocket::UnconnectedState || @@ -433,7 +439,7 @@ void tst_QSocks5SocketEngine::serverTest() // Initialize a Tcp socket QVERIFY(server.initialize(QAbstractSocket::TcpSocket)); - QNetworkProxy proxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1080); + QNetworkProxy proxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::socksProxyServerName(), 1080); server.setProxy(proxy); @@ -510,7 +516,7 @@ void tst_QSocks5SocketEngine::udpTest() QVERIFY(udpSocket.initialize(QAbstractSocket::UdpSocket)); QVERIFY(udpSocket.isValid()); - QNetworkProxy proxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1080); + QNetworkProxy proxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::socksProxyServerName(), 1080); udpSocket.setProxy(proxy); @@ -564,7 +570,7 @@ void tst_QSocks5SocketEngine::tcpSocketBlockingTest() QTcpSocket socket; // Connect - socket.connectToHost(QtNetworkSettings::serverName(), 143); + socket.connectToHost(QtNetworkSettings::imapServerName(), 143); QVERIFY(socket.waitForConnected()); QCOMPARE(socket.state(), QTcpSocket::ConnectedState); @@ -635,7 +641,7 @@ void tst_QSocks5SocketEngine::tcpSocketNonBlockingTest() }); // Connect - socket.connectToHost(QtNetworkSettings::serverName(), 143); + socket.connectToHost(QtNetworkSettings::imapServerName(), 143); QVERIFY(socket.state() == QTcpSocket::HostLookupState || socket.state() == QTcpSocket::ConnectingState); @@ -754,13 +760,13 @@ void tst_QSocks5SocketEngine::downloadBigFile() << " (" << stopWatch.elapsed() << "ms)"; }); - socket.connectToHost(QtNetworkSettings::serverName(), 80); + socket.connectToHost(QtNetworkSettings::httpServerName(), 80); QTestEventLoop::instance().enterLoop(30); if (QTestEventLoop::instance().timeout()) QFAIL("Network operation timed out"); - QByteArray hostName = QtNetworkSettings::serverName().toLatin1(); + QByteArray hostName = QtNetworkSettings::httpServerName().toLatin1(); QCOMPARE(socket.state(), QAbstractSocket::ConnectedState); QVERIFY(socket.write("GET /qtest/mediumfile HTTP/1.0\r\n") > 0); QVERIFY(socket.write("HOST: ") > 0); @@ -791,13 +797,13 @@ void tst_QSocks5SocketEngine::passwordAuth() QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol)); QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState); - socketDevice.setProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1080, "qsockstest", "password")); + socketDevice.setProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::socksProxyServerName(), 1080, "qsockstest", "password")); // Connect to imap.trolltech.com's IP - QVERIFY(!socketDevice.connectToHost(QtNetworkSettings::serverIP(), 143)); + QVERIFY(!socketDevice.connectToHost(QtNetworkSettings::imapServerIp(), 143)); QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectingState); QVERIFY(socketDevice.waitForWrite()); - if (!socketDevice.connectToHost(QtNetworkSettings::serverIP(), 143)) { + if (!socketDevice.connectToHost(QtNetworkSettings::imapServerIp(), 143)) { qDebug("%d, %s", socketDevice.error(), socketDevice.errorString().toLatin1().constData()); } QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectedState); @@ -857,19 +863,19 @@ void tst_QSocks5SocketEngine::passwordAuth2() QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol)); QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState); - socketDevice.setProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1081)); + socketDevice.setProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::socksProxyServerName(), 1081)); socketDevice.setReceiver(this); - QVERIFY(!socketDevice.connectToHost(QtNetworkSettings::serverIP(), 143)); + QVERIFY(!socketDevice.connectToHost(QtNetworkSettings::imapServerIp(), 143)); QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectingState); while (socketDevice.state() == QAbstractSocket::ConnectingState) { QVERIFY(socketDevice.waitForWrite()); - socketDevice.connectToHost(QtNetworkSettings::serverIP(), 143); + socketDevice.connectToHost(QtNetworkSettings::imapServerIp(), 143); } if (socketDevice.state() != QAbstractSocket::ConnectedState) qDebug("%d, %s", socketDevice.error(), socketDevice.errorString().toLatin1().constData()); QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectedState); - QCOMPARE(socketDevice.peerAddress(), QtNetworkSettings::serverIP()); + QCOMPARE(socketDevice.peerAddress(), QtNetworkSettings::imapServerIp()); // Wait for the greeting QVERIFY(socketDevice.waitForRead()); diff --git a/tests/testserver/cyrus/cyrus.sh b/tests/testserver/cyrus/cyrus.sh new file mode 100755 index 0000000000..bd09acffc8 --- /dev/null +++ b/tests/testserver/cyrus/cyrus.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the test suite of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:GPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 3 or (at your option) any later version +## approved by the KDE Free Qt Foundation. The licenses are as published by +## the Free Software Foundation and appearing in the file LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +set -ex + +service cyrus-imapd start diff --git a/tests/testserver/docker-compose.yml b/tests/testserver/docker-compose.yml index be65e5a26a..fe39a49cca 100644 --- a/tests/testserver/docker-compose.yml +++ b/tests/testserver/docker-compose.yml @@ -76,8 +76,20 @@ services: - apache2:apache2.${TEST_DOMAIN} - vsftpd:vsftpd.${TEST_DOMAIN} - ftp-proxy:ftp-proxy.${TEST_DOMAIN} + - cyrus:cyrus.${TEST_DOMAIN} volumes: - ./common:/common:ro - ./danted:/service:ro entrypoint: common/startup.sh command: service/danted.sh + + cyrus: + image: qt-test-server-cyrus:c8d72754abc0e501afd624ce838e4df35505abc9 + container_name: qt-test-server-cyrus + domainname: ${TEST_DOMAIN} + hostname: cyrus + volumes: + - ./common:/common:ro + - ./cyrus:/service:ro + entrypoint: common/startup.sh + command: service/cyrus.sh From a247d08faef289dcaab2c7132189e3cf051d27fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Tue, 12 Feb 2019 17:05:51 +0100 Subject: [PATCH 1288/1650] Port tst_qtcpsocket to the docker server The iptables container launches with extra capabilities to actually be able to make changes to the tables. Change-Id: I892fd18853ce882709e21791e6c88217e5029d53 Reviewed-by: Timur Pocheptsov --- tests/auto/network-settings.h | 48 +++++ .../network/socket/qtcpsocket/test/test.pro | 6 + .../socket/qtcpsocket/tst_qtcpsocket.cpp | 174 ++++++++++-------- tests/testserver/docker-compose.yml | 17 ++ tests/testserver/iptables/iptables.sh | 34 ++++ 5 files changed, 206 insertions(+), 73 deletions(-) create mode 100755 tests/testserver/iptables/iptables.sh diff --git a/tests/auto/network-settings.h b/tests/auto/network-settings.h index 092830a51a..bf632c9846 100644 --- a/tests/auto/network-settings.h +++ b/tests/auto/network-settings.h @@ -228,10 +228,58 @@ public: #endif } + static QString echoServerName() + { +#ifdef QT_TEST_SERVER_NAME + return QString("echo.") % serverDomainName(); +#else + return serverName(); +#endif + } + + static QString firewallServerName() + { +#ifdef QT_TEST_SERVER_NAME + return QString("iptables.") % serverDomainName(); +#else + return serverName(); +#endif + } + #ifdef QT_NETWORK_LIB static QHostAddress imapServerIp() { return getServerIpImpl(imapServerName()); } + + static QHostAddress httpServerIp() + { + return getServerIpImpl(httpServerName()); + } + + static QHostAddress httpProxyServerIp() + { + return getServerIpImpl(httpProxyServerName()); + } + + static QHostAddress socksProxyServerIp() + { + return getServerIpImpl(socksProxyServerName()); + } + + static QHostAddress ftpProxyServerIp() + { + return getServerIpImpl(ftpProxyServerName()); + } + + static QHostAddress ftpServerIp() + { + return getServerIpImpl(ftpServerName()); + } + + static QHostAddress firewallServerIp() + { + return getServerIpImpl(firewallServerName()); + } #endif }; diff --git a/tests/auto/network/socket/qtcpsocket/test/test.pro b/tests/auto/network/socket/qtcpsocket/test/test.pro index 337e75b372..29d9414b03 100644 --- a/tests/auto/network/socket/qtcpsocket/test/test.pro +++ b/tests/auto/network/socket/qtcpsocket/test/test.pro @@ -15,3 +15,9 @@ win32 { } else { DESTDIR = ../ } + +# Only on Linux until cyrus has been added to docker-compose-for-{windows,macOS}.yml and tested +linux { + QT_TEST_SERVER_LIST = danted squid apache2 ftp-proxy vsftpd iptables cyrus + include($$dirname(_QMAKE_CONF_)/tests/auto/testserver.pri) +} diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp index c473230246..abe9845213 100644 --- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp +++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp @@ -317,7 +317,7 @@ tst_QTcpSocket::tst_QTcpSocket() connect(earlyConstructedSockets->endPoints[1], SIGNAL(bytesWritten(qint64)), this, SLOT(earlySocketBytesSent(qint64))); earlyConstructedSockets->endPoints[1]->write("hello work"); - firstFailInfo.setAddresses(QList() << QHostAddress("224.0.0.0") << QtNetworkSettings::serverIP()); + firstFailInfo.setAddresses(QList() << QHostAddress("224.0.0.0") << QtNetworkSettings::httpServerIp()); } void tst_QTcpSocket::initTestCase_data() @@ -326,7 +326,6 @@ void tst_QTcpSocket::initTestCase_data() QTest::addColumn("proxyType"); QTest::addColumn("ssl"); - qDebug() << QtNetworkSettings::serverName(); QTest::newRow("WithoutProxy") << false << 0 << false; //QTest::newRow("WithSocks5Proxy") << true << int(Socks5Proxy) << false; ### temporarily disabled, QTBUG-38385 //QTest::newRow("WithSocks5ProxyAuth") << true << int(Socks5Proxy | AuthBasic) << false; ### temporarily disabled, QTBUG-38385 @@ -352,7 +351,17 @@ void tst_QTcpSocket::initTestCase_data() void tst_QTcpSocket::initTestCase() { +#ifdef QT_TEST_SERVER + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::httpServerName(), 80)); + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::httpProxyServerName(), 3128)); + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::imapServerName(), 143)); + //QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::firewallServerName(), 1357)); + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::socksProxyServerName(), 1080)); + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::ftpServerName(), 21)); + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::ftpProxyServerName(), 2121)); +#else QVERIFY(QtNetworkSettings::verifyTestNetworkSettings()); +#endif } void tst_QTcpSocket::init() @@ -361,30 +370,33 @@ void tst_QTcpSocket::init() if (setProxy) { #ifndef QT_NO_NETWORKPROXY QFETCH_GLOBAL(int, proxyType); - QList addresses = QHostInfo::fromName(QtNetworkSettings::serverName()).addresses(); - QVERIFY2(addresses.count() > 0, "failed to get ip address for test server"); - QString fluke = addresses.first().toString(); + QList socks5Addresses = QHostInfo::fromName(QtNetworkSettings::socksProxyServerName()).addresses(); + QList httpProxyAddresses = QHostInfo::fromName(QtNetworkSettings::httpProxyServerName()).addresses(); + QVERIFY2(socks5Addresses.count() > 0, "failed to get ip address for SOCKS5 proxy server"); + QVERIFY2(httpProxyAddresses.count() > 0, "failed to get ip address for HTTP proxy server"); + QString socks5Address = socks5Addresses.first().toString(); + QString httpProxyAddress = httpProxyAddresses.first().toString(); QNetworkProxy proxy; switch (proxyType) { case Socks5Proxy: - proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, fluke, 1080); + proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, socks5Address, 1080); break; case Socks5Proxy | AuthBasic: - proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, fluke, 1081); + proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, socks5Address, 1081); break; case HttpProxy | NoAuth: - proxy = QNetworkProxy(QNetworkProxy::HttpProxy, fluke, 3128); + proxy = QNetworkProxy(QNetworkProxy::HttpProxy, httpProxyAddress, 3128); break; case HttpProxy | AuthBasic: - proxy = QNetworkProxy(QNetworkProxy::HttpProxy, fluke, 3129); + proxy = QNetworkProxy(QNetworkProxy::HttpProxy, httpProxyAddress, 3129); break; case HttpProxy | AuthNtlm: - proxy = QNetworkProxy(QNetworkProxy::HttpProxy, fluke, 3130); + proxy = QNetworkProxy(QNetworkProxy::HttpProxy, httpProxyAddress, 3130); break; } QNetworkProxy::setApplicationProxy(proxy); @@ -644,8 +656,8 @@ void tst_QTcpSocket::bind() void tst_QTcpSocket::bindThenResolveHost_data() { QTest::addColumn("hostName"); - QTest::newRow("ip-literal") << QtNetworkSettings::serverIP().toString(); - QTest::newRow("name") << QtNetworkSettings::serverName(); + QTest::newRow("ip-literal") << QtNetworkSettings::httpServerIp().toString(); + QTest::newRow("name") << QtNetworkSettings::httpServerName(); QTest::newRow("first-fail") << firstFailName; } @@ -715,7 +727,7 @@ void tst_QTcpSocket::setSocketDescriptor() #ifdef Q_OS_WIN // need the dummy to ensure winsock is started QTcpSocket *dummy = newSocket(); - dummy->connectToHost(QtNetworkSettings::serverName(), 143); + dummy->connectToHost(QtNetworkSettings::imapServerName(), 143); QVERIFY(dummy->waitForConnected()); SOCKET sock = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); @@ -737,7 +749,7 @@ void tst_QTcpSocket::setSocketDescriptor() QCOMPARE(socket->socketDescriptor(), (qintptr)sock); qt_qhostinfo_clear_cache(); //avoid the HostLookupState being skipped due to address being in cache from previous test. - socket->connectToHost(QtNetworkSettings::serverName(), 80); + socket->connectToHost(QtNetworkSettings::httpServerName(), 80); QCOMPARE(socket->state(), QTcpSocket::HostLookupState); QCOMPARE(socket->socketDescriptor(), (qintptr)sock); QVERIFY(socket->waitForConnected(10000)); @@ -758,7 +770,7 @@ void tst_QTcpSocket::socketDescriptor() QTcpSocket *socket = newSocket(); QCOMPARE(socket->socketDescriptor(), (qintptr)-1); - socket->connectToHost(QtNetworkSettings::serverName(), 143); + socket->connectToHost(QtNetworkSettings::imapServerName(), 143); QVERIFY(socket->state() == QAbstractSocket::HostLookupState || socket->state() == QAbstractSocket::ConnectingState); QVERIFY(socket->waitForConnected(10000)); @@ -775,7 +787,7 @@ void tst_QTcpSocket::blockingIMAP() QTcpSocket *socket = newSocket(); // Connect - socket->connectToHost(QtNetworkSettings::serverName(), 143); + socket->connectToHost(QtNetworkSettings::imapServerName(), 143); QVERIFY(socket->waitForConnected(10000)); QCOMPARE(socket->state(), QTcpSocket::ConnectedState); QVERIFY(socket->isValid()); @@ -852,6 +864,14 @@ void tst_QTcpSocket::hostNotFound() socket->connectToHost("nosuchserver.qt-project.org", 80); QVERIFY(!socket->waitForConnected()); QCOMPARE(socket->state(), QTcpSocket::UnconnectedState); +#ifdef QT_TEST_SERVER + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) { + QEXPECT_FAIL("", "QTBUG-73953: The version of Squid in the docker container behaves " + "differently to the one in the network testing server, returning 503 " + "when we expect 404", Continue); + } +#endif QCOMPARE(int(socket->error()), int(QTcpSocket::HostNotFoundError)); delete socket; @@ -861,8 +881,8 @@ void tst_QTcpSocket::hostNotFound() void tst_QTcpSocket::timeoutConnect_data() { QTest::addColumn("address"); - QTest::newRow("host") << QtNetworkSettings::serverName(); - QTest::newRow("ip") << QtNetworkSettings::serverIP().toString(); + QTest::newRow("host") << QtNetworkSettings::firewallServerName(); + QTest::newRow("ip") << QtNetworkSettings::firewallServerIp().toString(); } void tst_QTcpSocket::timeoutConnect() @@ -910,7 +930,7 @@ void tst_QTcpSocket::nonBlockingIMAP() nonBlockingIMAP_socket = socket; // Connect - socket->connectToHost(QtNetworkSettings::serverName(), 143); + socket->connectToHost(QtNetworkSettings::imapServerName(), 143); QVERIFY(socket->state() == QTcpSocket::HostLookupState || socket->state() == QTcpSocket::ConnectingState); @@ -1036,7 +1056,7 @@ void tst_QTcpSocket::delayedClose() connect(socket, SIGNAL(connected()), SLOT(nonBlockingIMAP_connected())); connect(socket, SIGNAL(disconnected()), SLOT(exitLoopSlot())); - socket->connectToHost(QtNetworkSettings::serverName(), 143); + socket->connectToHost(QtNetworkSettings::imapServerName(), 143); enterLoop(30); if (timeout()) @@ -1082,7 +1102,7 @@ QByteArray tst_QTcpSocket::expectedReplyIMAP() void tst_QTcpSocket::fetchExpectedReplyIMAP() { QTcpSocket *socket = newSocket(); - socket->connectToHost(QtNetworkSettings::serverName(), 143); + socket->connectToHost(QtNetworkSettings::imapServerName(), 143); QVERIFY2(socket->waitForConnected(10000), qPrintable(socket->errorString())); QVERIFY2(socket->state() == QTcpSocket::ConnectedState, qPrintable(socket->errorString())); @@ -1101,7 +1121,7 @@ void tst_QTcpSocket::fetchExpectedReplyIMAP() void tst_QTcpSocket::partialRead() { QTcpSocket *socket = newSocket(); - socket->connectToHost(QtNetworkSettings::serverName(), 143); + socket->connectToHost(QtNetworkSettings::imapServerName(), 143); QVERIFY(socket->waitForConnected(10000)); QCOMPARE(socket->state(), QTcpSocket::ConnectedState); char buf[512]; @@ -1125,7 +1145,7 @@ void tst_QTcpSocket::partialRead() void tst_QTcpSocket::unget() { QTcpSocket *socket = newSocket(); - socket->connectToHost(QtNetworkSettings::serverName(), 143); + socket->connectToHost(QtNetworkSettings::imapServerName(), 143); QVERIFY(socket->waitForConnected(10000)); QCOMPARE(socket->state(), QTcpSocket::ConnectedState); char buf[512]; @@ -1162,7 +1182,7 @@ void tst_QTcpSocket::readRegularFile_readyRead() void tst_QTcpSocket::readAllAfterClose() { QTcpSocket *socket = newSocket(); - socket->connectToHost(QtNetworkSettings::serverName(), 143); + socket->connectToHost(QtNetworkSettings::imapServerName(), 143); connect(socket, SIGNAL(readyRead()), SLOT(readRegularFile_readyRead())); enterLoop(10); if (timeout()) @@ -1202,7 +1222,7 @@ void tst_QTcpSocket::openCloseOpenClose() QCOMPARE(socket->state(), QTcpSocket::UnconnectedState); - socket->connectToHost(QtNetworkSettings::serverName(), 143); + socket->connectToHost(QtNetworkSettings::imapServerName(), 143); QVERIFY(socket->waitForConnected(10000)); socket->close(); } @@ -1225,7 +1245,7 @@ void tst_QTcpSocket::connectDisconnectConnectDisconnect() QCOMPARE(int(socket->peerPort()), 0); QCOMPARE(socket->peerAddress(), QHostAddress()); - socket->connectToHost(QtNetworkSettings::serverName(), 143); + socket->connectToHost(QtNetworkSettings::imapServerName(), 143); QVERIFY(socket->waitForReadyRead(10000)); QCOMPARE(QString::fromLatin1(socket->read(4)), QString("* OK")); @@ -1429,7 +1449,7 @@ void tst_QTcpSocket::disconnectWhileLookingUp() // just connect and disconnect, then make sure nothing weird happened QTcpSocket *socket = newSocket(); - socket->connectToHost(QtNetworkSettings::serverName(), 21); + socket->connectToHost(QtNetworkSettings::ftpServerName(), 21); // check that connect is in progress QVERIFY(socket->state() != QAbstractSocket::UnconnectedState); @@ -1477,7 +1497,7 @@ void tst_QTcpSocket::downloadBigFile() connect(tmpSocket, SIGNAL(readyRead()), SLOT(downloadBigFileSlot())); connect(tmpSocket, SIGNAL(disconnected()), SLOT(exitLoopSlot())); - tmpSocket->connectToHost(QtNetworkSettings::serverName(), 80); + tmpSocket->connectToHost(QtNetworkSettings::httpServerName(), 80); enterLoop(30); if (timeout()) { @@ -1486,7 +1506,7 @@ void tst_QTcpSocket::downloadBigFile() QFAIL("Network operation timed out"); } - QByteArray hostName = QtNetworkSettings::serverName().toLatin1(); + QByteArray hostName = QtNetworkSettings::httpServerName().toLatin1(); QCOMPARE(tmpSocket->state(), QAbstractSocket::ConnectedState); QVERIFY(tmpSocket->write("GET /qtest/mediumfile HTTP/1.0\r\n") > 0); QVERIFY(tmpSocket->write("HOST: ") > 0); @@ -1552,7 +1572,7 @@ void tst_QTcpSocket::downloadBigFileSlot() void tst_QTcpSocket::readLine() { QTcpSocket *socket = newSocket(); - socket->connectToHost(QtNetworkSettings::serverName(), 143); + socket->connectToHost(QtNetworkSettings::imapServerName(), 143); QVERIFY(socket->waitForConnected(5000)); while (!socket->canReadLine()) @@ -1601,7 +1621,7 @@ void tst_QTcpSocket::readLine() void tst_QTcpSocket::readLineString() { QTcpSocket *socket = newSocket(); - socket->connectToHost(QtNetworkSettings::serverName(), 143); + socket->connectToHost(QtNetworkSettings::imapServerName(), 143); QVERIFY(socket->waitForReadyRead(10000)); QByteArray arr = socket->readLine(); @@ -1614,7 +1634,7 @@ void tst_QTcpSocket::readLineString() void tst_QTcpSocket::readChunks() { QTcpSocket *socket = newSocket(); - socket->connectToHost(QtNetworkSettings::serverName(), 143); + socket->connectToHost(QtNetworkSettings::imapServerName(), 143); QVERIFY(socket->waitForConnected(10000)); QVERIFY(socket->waitForReadyRead(5000)); @@ -1634,7 +1654,7 @@ void tst_QTcpSocket::readChunks() void tst_QTcpSocket::waitForBytesWritten() { QTcpSocket *socket = newSocket(); - socket->connectToHost(QtNetworkSettings::serverName(), 80); + socket->connectToHost(QtNetworkSettings::httpServerName(), 80); QVERIFY(socket->waitForConnected(10000)); socket->write("GET / HTTP/1.0\r\n\r\n"); @@ -1652,7 +1672,7 @@ void tst_QTcpSocket::waitForBytesWrittenMinusOne() QSKIP("QTBUG-24451 - indefinite wait may hang"); #endif QTcpSocket *socket = newSocket(); - socket->connectToHost(QtNetworkSettings::serverName(), 80); + socket->connectToHost(QtNetworkSettings::httpServerName(), 80); QVERIFY(socket->waitForConnected(10000)); socket->write("GET / HTTP/1.0\r\n\r\n"); @@ -1667,7 +1687,7 @@ void tst_QTcpSocket::waitForBytesWrittenMinusOne() void tst_QTcpSocket::waitForReadyRead() { QTcpSocket *socket = newSocket(); - socket->connectToHost(QtNetworkSettings::serverName(), 80); + socket->connectToHost(QtNetworkSettings::httpServerName(), 80); socket->write("GET / HTTP/1.0\r\n\r\n"); QVERIFY(socket->waitForReadyRead(5000)); delete socket; @@ -1680,7 +1700,7 @@ void tst_QTcpSocket::waitForReadyReadMinusOne() QSKIP("QTBUG-24451 - indefinite wait may hang"); #endif QTcpSocket *socket = newSocket(); - socket->connectToHost(QtNetworkSettings::serverName(), 80); + socket->connectToHost(QtNetworkSettings::httpServerName(), 80); socket->write("GET / HTTP/1.0\r\n\r\n"); QVERIFY(socket->waitForReadyRead(-1)); delete socket; @@ -1693,7 +1713,7 @@ void tst_QTcpSocket::flush() socket->flush(); connect(socket, SIGNAL(connected()), SLOT(exitLoopSlot())); - socket->connectToHost(QtNetworkSettings::serverName(), 143); + socket->connectToHost(QtNetworkSettings::imapServerName(), 143); enterLoop(60); QVERIFY(socket->isOpen()); @@ -1710,7 +1730,7 @@ void tst_QTcpSocket::flush() void tst_QTcpSocket::synchronousApi() { QTcpSocket *ftpSocket = newSocket(); - ftpSocket->connectToHost(QtNetworkSettings::serverName(), 21); + ftpSocket->connectToHost(QtNetworkSettings::ftpServerName(), 21); ftpSocket->write("QUIT\r\n"); QVERIFY(ftpSocket->waitForDisconnected(10000)); QVERIFY(ftpSocket->bytesAvailable() > 0); @@ -1757,10 +1777,10 @@ void tst_QTcpSocket::recursiveReadyRead() QSignalSpy spy(testSocket, SIGNAL(readyRead())); - testSocket->connectToHost(QtNetworkSettings::serverName(), 143); + testSocket->connectToHost(QtNetworkSettings::imapServerName(), 143); enterLoop(30); QVERIFY2(!timeout(), - "Timed out when connecting to QtNetworkSettings::serverName()."); + "Timed out when connecting to QtNetworkSettings::imapServerName()."); enterLoop(30); QVERIFY2(!timeout(), @@ -1794,7 +1814,7 @@ void tst_QTcpSocket::recursiveReadyReadSlot() void tst_QTcpSocket::atEnd() { QTcpSocket *socket = newSocket(); - socket->connectToHost(QtNetworkSettings::serverName(), 21); + socket->connectToHost(QtNetworkSettings::ftpServerName(), 21); QVERIFY(socket->waitForReadyRead(15000)); QTextStream stream(socket); @@ -1802,9 +1822,15 @@ void tst_QTcpSocket::atEnd() QString greeting = stream.readLine(); QVERIFY(stream.atEnd()); +#ifdef QT_TEST_SERVER + // Test server must use some vsFTPd 3.x.x version + QVERIFY2(greeting.length() == sizeof("220 (vsFTPd 3.x.x)")-1, qPrintable(greeting)); + QVERIFY2(greeting.startsWith("220 (vsFTPd 3."), qPrintable(greeting)); +#else // Test server must use some vsFTPd 2.x.x version QVERIFY2(greeting.length() == sizeof("220 (vsFTPd 2.x.x)")-1, qPrintable(greeting)); QVERIFY2(greeting.startsWith("220 (vsFTPd 2."), qPrintable(greeting)); +#endif QVERIFY2(greeting.endsWith(QLatin1Char(')')), qPrintable(greeting)); delete socket; @@ -1835,7 +1861,7 @@ protected: connect(socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), Qt::DirectConnection); - socket->connectToHost(QtNetworkSettings::serverName(), 21); + socket->connectToHost(QtNetworkSettings::ftpServerName(), 21); socket->write("QUIT\r\n"); exec(); @@ -1909,7 +1935,7 @@ void tst_QTcpSocket::waitForReadyReadInASlot() tmpSocket = socket; connect(socket, SIGNAL(connected()), this, SLOT(waitForReadyReadInASlotSlot())); - socket->connectToHost(QtNetworkSettings::serverName(), 80); + socket->connectToHost(QtNetworkSettings::httpServerName(), 80); socket->write("GET / HTTP/1.0\r\n\r\n"); enterLoop(30); @@ -2073,7 +2099,7 @@ void tst_QTcpSocket::waitForConnectedInHostLookupSlot() timer.start(15000); connect(tmpSocket, SIGNAL(hostFound()), this, SLOT(hostLookupSlot())); - tmpSocket->connectToHost(QtNetworkSettings::serverName(), 143); + tmpSocket->connectToHost(QtNetworkSettings::imapServerName(), 143); // only execute the loop if not already connected if (tmpSocket->state() != QAbstractSocket::ConnectedState) @@ -2128,7 +2154,7 @@ public slots: inline void doIt() { attemptedToConnect = true; - sock->connectToHost(QtNetworkSettings::serverName(), 80); + sock->connectToHost(QtNetworkSettings::httpServerName(), 80); #if defined(Q_OS_MAC) pthread_yield_np(); @@ -2179,7 +2205,7 @@ void tst_QTcpSocket::readyReadSignalsAfterWaitForReadyRead() QSignalSpy readyReadSpy(socket, SIGNAL(readyRead())); // Connect - socket->connectToHost(QtNetworkSettings::serverName(), 143); + socket->connectToHost(QtNetworkSettings::imapServerName(), 143); // Wait for the read QVERIFY(socket->waitForReadyRead(10000)); @@ -2315,7 +2341,7 @@ void tst_QTcpSocket::localAddressEmptyOnBSD() void tst_QTcpSocket::zeroAndMinusOneReturns() { QTcpSocket *socket = newSocket(); - socket->connectToHost(QtNetworkSettings::serverName(), 80); + socket->connectToHost(QtNetworkSettings::httpServerName(), 80); socket->write("GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n"); QVERIFY(socket->waitForReadyRead(15000)); @@ -2376,7 +2402,7 @@ void tst_QTcpSocket::connectionRefused() connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), &QTestEventLoop::instance(), SLOT(exitLoop())); - socket->connectToHost(QtNetworkSettings::serverName(), 144); + socket->connectToHost(QtNetworkSettings::httpServerName(), 144); enterLoop(10); disconnect(socket, SIGNAL(error(QAbstractSocket::SocketError)), @@ -2523,7 +2549,7 @@ void tst_QTcpSocket::moveToThread0() { // Case 1: Moved after connecting, before waiting for connection. QTcpSocket *socket = newSocket();; - socket->connectToHost(QtNetworkSettings::serverName(), 143); + socket->connectToHost(QtNetworkSettings::imapServerName(), 143); socket->moveToThread(0); QVERIFY(socket->waitForConnected(5000)); socket->write("XXX LOGOUT\r\n"); @@ -2535,7 +2561,7 @@ void tst_QTcpSocket::moveToThread0() // Case 2: Moved before connecting QTcpSocket *socket = newSocket(); socket->moveToThread(0); - socket->connectToHost(QtNetworkSettings::serverName(), 143); + socket->connectToHost(QtNetworkSettings::imapServerName(), 143); QVERIFY(socket->waitForConnected(5000)); socket->write("XXX LOGOUT\r\n"); QVERIFY(socket->waitForBytesWritten(5000)); @@ -2545,7 +2571,7 @@ void tst_QTcpSocket::moveToThread0() { // Case 3: Moved after writing, while waiting for bytes to be written. QTcpSocket *socket = newSocket(); - socket->connectToHost(QtNetworkSettings::serverName(), 143); + socket->connectToHost(QtNetworkSettings::imapServerName(), 143); QVERIFY(socket->waitForConnected(5000)); socket->write("XXX LOGOUT\r\n"); socket->moveToThread(0); @@ -2556,7 +2582,7 @@ void tst_QTcpSocket::moveToThread0() { // Case 4: Moved after writing, while waiting for response. QTcpSocket *socket = newSocket(); - socket->connectToHost(QtNetworkSettings::serverName(), 143); + socket->connectToHost(QtNetworkSettings::imapServerName(), 143); QVERIFY(socket->waitForConnected(5000)); socket->write("XXX LOGOUT\r\n"); QVERIFY(socket->waitForBytesWritten(5000)); @@ -2687,7 +2713,7 @@ void tst_QTcpSocket::taskQtBug5799ConnectionErrorWaitForConnected() // use waitForConnected, e.g. this should use a synchronous select() on the OS level QTcpSocket socket; - socket.connectToHost(QtNetworkSettings::serverName(), 12346); + socket.connectToHost(QtNetworkSettings::httpServerName(), 12346); QTime timer; timer.start(); socket.waitForConnected(10000); @@ -2707,7 +2733,7 @@ void tst_QTcpSocket::taskQtBug5799ConnectionErrorEventLoop() // This testcase uses an event loop QTcpSocket socket; connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)), &QTestEventLoop::instance(), SLOT(exitLoop())); - socket.connectToHost(QtNetworkSettings::serverName(), 12346); + socket.connectToHost(QtNetworkSettings::httpServerName(), 12346); QTestEventLoop::instance().enterLoop(10); QVERIFY2(!QTestEventLoop::instance().timeout(), "Connection to closed port timed out instead of refusing, something is wrong"); @@ -2720,7 +2746,7 @@ void tst_QTcpSocket::taskQtBug7054TimeoutErrorResetting() { QTcpSocket *socket = newSocket(); - socket->connectToHost(QtNetworkSettings::serverName(), 443); + socket->connectToHost(QtNetworkSettings::httpServerName(), 443); QVERIFY(socket->waitForConnected(5*1000)); QCOMPARE(socket->error(), QAbstractSocket::UnknownSocketError); @@ -2749,10 +2775,12 @@ void tst_QTcpSocket::invalidProxy_data() QTest::addColumn("failsAtConnect"); QTest::addColumn("expectedError"); - QString fluke = QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString(); - QTest::newRow("ftp-proxy") << int(QNetworkProxy::FtpCachingProxy) << fluke << 21 << true + const QString ftpAddress = QtNetworkSettings::ftpServerIp().toString(); + const QString httpProxyAddress = QtNetworkSettings::httpProxyServerIp().toString(); + const QString socksProxyAddress = QtNetworkSettings::socksProxyServerIp().toString(); + QTest::newRow("ftp-proxy") << int(QNetworkProxy::FtpCachingProxy) << ftpAddress << 21 << true << int(QAbstractSocket::UnsupportedSocketOperationError); - QTest::newRow("http-caching-proxy") << int(QNetworkProxy::HttpCachingProxy) << fluke << 3128 << true + QTest::newRow("http-caching-proxy") << int(QNetworkProxy::HttpCachingProxy) << httpProxyAddress << 3128 << true << int(QAbstractSocket::UnsupportedSocketOperationError); QTest::newRow("no-such-host-socks5") << int(QNetworkProxy::Socks5Proxy) << "this-host-will-never-exist.qt-project.org" << 1080 << false @@ -2760,9 +2788,9 @@ void tst_QTcpSocket::invalidProxy_data() QTest::newRow("no-such-host-http") << int(QNetworkProxy::HttpProxy) << "this-host-will-never-exist.qt-project.org" << 3128 << false << int(QAbstractSocket::ProxyNotFoundError); - QTest::newRow("http-on-socks5") << int(QNetworkProxy::HttpProxy) << fluke << 1080 << false + QTest::newRow("http-on-socks5") << int(QNetworkProxy::HttpProxy) << socksProxyAddress << 1080 << false << int(QAbstractSocket::ProxyConnectionClosedError); - QTest::newRow("socks5-on-http") << int(QNetworkProxy::Socks5Proxy) << fluke << 3128 << false + QTest::newRow("socks5-on-http") << int(QNetworkProxy::Socks5Proxy) << httpProxyAddress << 3128 << false << int(QAbstractSocket::SocketTimeoutError); } @@ -2781,7 +2809,7 @@ void tst_QTcpSocket::invalidProxy() QTcpSocket *socket = newSocket(); socket->setProxy(proxy); - socket->connectToHost(QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString(), 80); + socket->connectToHost(QtNetworkSettings::httpServerIp().toString(), 80); if (failsAtConnect) { QCOMPARE(socket->state(), QAbstractSocket::UnconnectedState); @@ -2833,48 +2861,48 @@ void tst_QTcpSocket::proxyFactory_data() // tests that do connect - proxyList << QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::serverName(), 3129); + proxyList << QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::httpProxyServerName(), 3129); QTest::newRow("http") << proxyList << proxyList.at(0) << false << int(QAbstractSocket::UnknownSocketError); proxyList.clear(); - proxyList << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1081); + proxyList << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::socksProxyServerName(), 1081); QTest::newRow("socks5") << proxyList << proxyList.at(0) << false << int(QAbstractSocket::UnknownSocketError); proxyList.clear(); - proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129) - << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1081); + proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::httpProxyServerName(), 3129) + << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::socksProxyServerName(), 1081); QTest::newRow("cachinghttp+socks5") << proxyList << proxyList.at(1) << false << int(QAbstractSocket::UnknownSocketError); proxyList.clear(); - proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::serverName(), 2121) - << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129) - << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1081); + proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::ftpProxyServerName(), 2121) + << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::httpProxyServerName(), 3129) + << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::socksProxyServerName(), 1081); QTest::newRow("ftp+cachinghttp+socks5") << proxyList << proxyList.at(2) << false << int(QAbstractSocket::UnknownSocketError); // tests that fail to connect proxyList.clear(); - proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129); + proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::httpProxyServerName(), 3129); QTest::newRow("cachinghttp") << proxyList << QNetworkProxy() << true << int(QAbstractSocket::UnsupportedSocketOperationError); proxyList.clear(); - proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::serverName(), 2121); + proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::ftpProxyServerName(), 2121); QTest::newRow("ftp") << proxyList << QNetworkProxy() << true << int(QAbstractSocket::UnsupportedSocketOperationError); proxyList.clear(); - proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::serverName(), 2121) - << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129); + proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::ftpProxyServerName(), 2121) + << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::httpProxyServerName(), 3129); QTest::newRow("ftp+cachinghttp") << proxyList << QNetworkProxy() << true << int(QAbstractSocket::UnsupportedSocketOperationError); @@ -2895,7 +2923,7 @@ void tst_QTcpSocket::proxyFactory() QNetworkProxyFactory::setApplicationProxyFactory(factory); QTcpSocket *socket = newSocket(); - QString host = QtNetworkSettings::serverName(); + QString host = QtNetworkSettings::httpServerName(); socket->connectToHost(host, 80); // Verify that the factory was called properly diff --git a/tests/testserver/docker-compose.yml b/tests/testserver/docker-compose.yml index fe39a49cca..4286c88211 100644 --- a/tests/testserver/docker-compose.yml +++ b/tests/testserver/docker-compose.yml @@ -31,6 +31,9 @@ services: - apache2 external_links: - apache2:apache2.${TEST_DOMAIN} + - cyrus:cyrus.${TEST_DOMAIN} + - iptables:iptables.${TEST_DOMAIN} + - vsftpd:vsftpd.${TEST_DOMAIN} volumes: - ./common:/common:ro - ./squid:/service:ro @@ -93,3 +96,17 @@ services: - ./cyrus:/service:ro entrypoint: common/startup.sh command: service/cyrus.sh + + iptables: + image: qt-test-server-iptables:cb7a8bd6d28602085a88c8ced7d67e28e75781e2 + container_name: qt-test-server-iptables + domainname: ${TEST_DOMAIN} + hostname: iptables + volumes: + - ./common:/common:ro + - ./iptables:/service:ro + entrypoint: common/startup.sh + command: service/iptables.sh + cap_add: + - NET_ADMIN + - NET_RAW diff --git a/tests/testserver/iptables/iptables.sh b/tests/testserver/iptables/iptables.sh new file mode 100755 index 0000000000..9a48686d8b --- /dev/null +++ b/tests/testserver/iptables/iptables.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the test suite of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:GPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 3 or (at your option) any later version +## approved by the KDE Free Qt Foundation. The licenses are as published by +## the Free Software Foundation and appearing in the file LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +set -ex + +iptables -A INPUT -p tcp --destination-port 1357 -j DROP From c47ec42f02196f387c28ab1a5ac70a23ec642a63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Thu, 21 Feb 2019 15:16:37 +0100 Subject: [PATCH 1289/1650] Convert tst_qtcpserver to use docker Change-Id: Id456fa8ea6ab4f23b6b83c5f6388e96443ccf9e0 Reviewed-by: Edward Welbourne Reviewed-by: Timur Pocheptsov --- .../network/socket/qtcpserver/test/test.pro | 6 +++ .../socket/qtcpserver/tst_qtcpserver.cpp | 43 +++++++++++-------- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/tests/auto/network/socket/qtcpserver/test/test.pro b/tests/auto/network/socket/qtcpserver/test/test.pro index 4491523383..ac4ed9a989 100644 --- a/tests/auto/network/socket/qtcpserver/test/test.pro +++ b/tests/auto/network/socket/qtcpserver/test/test.pro @@ -16,3 +16,9 @@ win32 { QT = core network testlib MOC_DIR=tmp + +# Only on Linux until cyrus has been added to docker-compose-for-{windows,macOS}.yml and tested +linux { + QT_TEST_SERVER_LIST = danted cyrus squid ftp-proxy + include($$dirname(_QMAKE_CONF_)/tests/auto/testserver.pri) +} diff --git a/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp b/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp index 161d94d642..22ac9aa076 100644 --- a/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp +++ b/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp @@ -160,8 +160,15 @@ void tst_QTcpServer::initTestCase_data() void tst_QTcpServer::initTestCase() { +#ifdef QT_TEST_SERVER + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::socksProxyServerName(), 1080)); + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::httpProxyServerName(), 3128)); + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::ftpProxyServerName(), 2121)); + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::imapServerName(), 143)); +#else if (!QtNetworkSettings::verifyTestNetworkSettings()) QSKIP("No network test server available"); +#endif #ifndef QT_NO_BEARERMANAGEMENT QNetworkConfigurationManager man; networkSession = new QNetworkSession(man.defaultConfiguration(), this); @@ -177,7 +184,7 @@ void tst_QTcpServer::init() #ifndef QT_NO_NETWORKPROXY QFETCH_GLOBAL(int, proxyType); if (proxyType == QNetworkProxy::Socks5Proxy) { - QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1080)); + QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::socksProxyServerName(), 1080)); } #else // !QT_NO_NETWORKPROXY QSKIP("No proxy support"); @@ -513,7 +520,7 @@ void tst_QTcpServer::waitForConnectionTest() } QTcpSocket findLocalIpSocket; - findLocalIpSocket.connectToHost(QtNetworkSettings::serverName(), 143); + findLocalIpSocket.connectToHost(QtNetworkSettings::imapServerName(), 143); QVERIFY(findLocalIpSocket.waitForConnected(5000)); QTcpServer server; @@ -668,16 +675,18 @@ void tst_QTcpServer::invalidProxy_data() QTest::addColumn("port"); QTest::addColumn("expectedError"); - QString fluke = QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString(); - QTest::newRow("ftp-proxy") << int(QNetworkProxy::FtpCachingProxy) << fluke << 143 + const QString imapIp = QtNetworkSettings::imapServerIp().toString(); + const QString httpProxyIp = QtNetworkSettings::httpProxyServerIp().toString(); + const QString socksIp = QtNetworkSettings::socksProxyServerIp().toString(); + QTest::newRow("ftp-proxy") << int(QNetworkProxy::FtpCachingProxy) << imapIp << 143 << int(QAbstractSocket::UnsupportedSocketOperationError); - QTest::newRow("http-proxy") << int(QNetworkProxy::HttpProxy) << fluke << 3128 + QTest::newRow("http-proxy") << int(QNetworkProxy::HttpProxy) << httpProxyIp << 3128 << int(QAbstractSocket::UnsupportedSocketOperationError); QTest::newRow("no-such-host") << int(QNetworkProxy::Socks5Proxy) << "invalid.test.qt-project.org" << 1080 << int(QAbstractSocket::ProxyNotFoundError); - QTest::newRow("socks5-on-http") << int(QNetworkProxy::Socks5Proxy) << fluke << 3128 + QTest::newRow("socks5-on-http") << int(QNetworkProxy::Socks5Proxy) << httpProxyIp << 3128 << int(QAbstractSocket::SocketTimeoutError); } @@ -740,48 +749,48 @@ void tst_QTcpServer::proxyFactory_data() // tests that do get to listen - proxyList << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1080); + proxyList << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::socksProxyServerName(), 1080); QTest::newRow("socks5") << proxyList << proxyList.at(0) << false << int(QAbstractSocket::UnknownSocketError); proxyList.clear(); - proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3128) - << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1080); + proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::httpProxyServerName(), 3128) + << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::socksProxyServerName(), 1080); QTest::newRow("cachinghttp+socks5") << proxyList << proxyList.at(1) << false << int(QAbstractSocket::UnknownSocketError); proxyList.clear(); - proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::serverName(), 2121) - << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3128) - << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1080); + proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::ftpProxyServerName(), 2121) + << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::httpProxyServerName(), 3128) + << QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::socksProxyServerName(), 1080); QTest::newRow("ftp+cachinghttp+socks5") << proxyList << proxyList.at(2) << false << int(QAbstractSocket::UnknownSocketError); // tests that fail to listen proxyList.clear(); - proxyList << QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::serverName(), 3128); + proxyList << QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::httpProxyServerName(), 3128); QTest::newRow("http") << proxyList << proxyList.at(0) << true << int(QAbstractSocket::UnsupportedSocketOperationError); proxyList.clear(); - proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3128); + proxyList << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::httpProxyServerName(), 3128); QTest::newRow("cachinghttp") << proxyList << QNetworkProxy() << true << int(QAbstractSocket::UnsupportedSocketOperationError); proxyList.clear(); - proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::serverName(), 2121); + proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::ftpProxyServerName(), 2121); QTest::newRow("ftp") << proxyList << QNetworkProxy() << true << int(QAbstractSocket::UnsupportedSocketOperationError); proxyList.clear(); - proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::serverName(), 2121) - << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3128); + proxyList << QNetworkProxy(QNetworkProxy::FtpCachingProxy, QtNetworkSettings::ftpProxyServerName(), 2121) + << QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::httpProxyServerName(), 3128); QTest::newRow("ftp+cachinghttp") << proxyList << QNetworkProxy() << true << int(QAbstractSocket::UnsupportedSocketOperationError); From 703ca2606f0ec5fd91c0bd5caea9cbb94d07cd6b Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Wed, 27 Feb 2019 13:48:46 +0100 Subject: [PATCH 1290/1650] Convert tst_qsslsocket_*_static/member auto-tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To work with docker test server. Change-Id: I50a1c7b632748d7648dafd70356aa849614e4e12 Reviewed-by: Mårten Nordheim Reviewed-by: Edward Welbourne --- ...qsslsocket_onDemandCertificates_member.pro | 6 +++++ ...qsslsocket_onDemandCertificates_member.cpp | 21 +++++++++++++----- ...qsslsocket_onDemandCertificates_static.pro | 6 +++++ ...qsslsocket_onDemandCertificates_static.cpp | 22 ++++++++++++++----- 4 files changed, 43 insertions(+), 12 deletions(-) diff --git a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/qsslsocket_onDemandCertificates_member.pro b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/qsslsocket_onDemandCertificates_member.pro index 05755ff606..3e3ebeb358 100644 --- a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/qsslsocket_onDemandCertificates_member.pro +++ b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/qsslsocket_onDemandCertificates_member.pro @@ -17,3 +17,9 @@ win32 { DEFINES += SRCDIR=\\\"$$PWD/\\\" requires(qtConfig(private_tests)) + +# DOCKERTODO: linux, docker is disabled on macOS/Windows. +linux { + QT_TEST_SERVER_LIST = squid danted + include($$dirname(_QMAKE_CONF_)/tests/auto/testserver.pri) +} diff --git a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp index 25c2701f69..4199c0f465 100644 --- a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp +++ b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp @@ -102,7 +102,15 @@ void tst_QSslSocket_onDemandCertificates_member::initTestCase_data() void tst_QSslSocket_onDemandCertificates_member::initTestCase() { +#ifdef QT_TEST_SERVER + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::socksProxyServerName(), 1080)); + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::socksProxyServerName(), 1081)); + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::httpProxyServerName(), 3128)); + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::httpProxyServerName(), 3129)); + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::httpProxyServerName(), 3130)); +#else QVERIFY(QtNetworkSettings::verifyTestNetworkSettings()); +#endif // QT_TEST_SERVER } void tst_QSslSocket_onDemandCertificates_member::init() @@ -110,28 +118,29 @@ void tst_QSslSocket_onDemandCertificates_member::init() QFETCH_GLOBAL(bool, setProxy); if (setProxy) { QFETCH_GLOBAL(int, proxyType); - QString testServer = QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString(); + const auto socksAddr = QtNetworkSettings::socksProxyServerIp().toString(); + const auto squidAddr = QtNetworkSettings::httpProxyServerIp().toString(); QNetworkProxy proxy; switch (proxyType) { case Socks5Proxy: - proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, testServer, 1080); + proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, socksAddr, 1080); break; case Socks5Proxy | AuthBasic: - proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, testServer, 1081); + proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, socksAddr, 1081); break; case HttpProxy | NoAuth: - proxy = QNetworkProxy(QNetworkProxy::HttpProxy, testServer, 3128); + proxy = QNetworkProxy(QNetworkProxy::HttpProxy, squidAddr, 3128); break; case HttpProxy | AuthBasic: - proxy = QNetworkProxy(QNetworkProxy::HttpProxy, testServer, 3129); + proxy = QNetworkProxy(QNetworkProxy::HttpProxy, squidAddr, 3129); break; case HttpProxy | AuthNtlm: - proxy = QNetworkProxy(QNetworkProxy::HttpProxy, testServer, 3130); + proxy = QNetworkProxy(QNetworkProxy::HttpProxy, squidAddr, 3130); break; } QNetworkProxy::setApplicationProxy(proxy); diff --git a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/qsslsocket_onDemandCertificates_static.pro b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/qsslsocket_onDemandCertificates_static.pro index c345d7379f..1ad42b309e 100644 --- a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/qsslsocket_onDemandCertificates_static.pro +++ b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/qsslsocket_onDemandCertificates_static.pro @@ -16,3 +16,9 @@ win32 { DEFINES += SRCDIR=\\\"$$PWD/\\\" requires(qtConfig(private_tests)) + +#DOCKERTODO Linux, docker is disabled on macOS and Windows. +linux { + QT_TEST_SERVER_LIST = squid danted + include($$dirname(_QMAKE_CONF_)/tests/auto/testserver.pri) +} diff --git a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/tst_qsslsocket_onDemandCertificates_static.cpp b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/tst_qsslsocket_onDemandCertificates_static.cpp index 503edc0bff..671a21b1c2 100644 --- a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/tst_qsslsocket_onDemandCertificates_static.cpp +++ b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/tst_qsslsocket_onDemandCertificates_static.cpp @@ -98,7 +98,15 @@ void tst_QSslSocket_onDemandCertificates_static::initTestCase_data() void tst_QSslSocket_onDemandCertificates_static::initTestCase() { +#ifdef QT_TEST_SERVER + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::socksProxyServerName(), 1080)); + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::socksProxyServerName(), 1081)); + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::httpProxyServerName(), 3128)); + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::httpProxyServerName(), 3129)); + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::httpProxyServerName(), 3130)); +#else QVERIFY(QtNetworkSettings::verifyTestNetworkSettings()); +#endif // QT_TEST_SERVER } void tst_QSslSocket_onDemandCertificates_static::init() @@ -106,28 +114,30 @@ void tst_QSslSocket_onDemandCertificates_static::init() QFETCH_GLOBAL(bool, setProxy); if (setProxy) { QFETCH_GLOBAL(int, proxyType); - QString testServer = QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString(); + const auto socksAddr = QtNetworkSettings::socksProxyServerIp().toString(); + const auto squidAddr = QtNetworkSettings::httpProxyServerIp().toString(); + QNetworkProxy proxy; switch (proxyType) { case Socks5Proxy: - proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, testServer, 1080); + proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, socksAddr, 1080); break; case Socks5Proxy | AuthBasic: - proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, testServer, 1081); + proxy = QNetworkProxy(QNetworkProxy::Socks5Proxy, socksAddr, 1081); break; case HttpProxy | NoAuth: - proxy = QNetworkProxy(QNetworkProxy::HttpProxy, testServer, 3128); + proxy = QNetworkProxy(QNetworkProxy::HttpProxy, squidAddr, 3128); break; case HttpProxy | AuthBasic: - proxy = QNetworkProxy(QNetworkProxy::HttpProxy, testServer, 3129); + proxy = QNetworkProxy(QNetworkProxy::HttpProxy, squidAddr, 3129); break; case HttpProxy | AuthNtlm: - proxy = QNetworkProxy(QNetworkProxy::HttpProxy, testServer, 3130); + proxy = QNetworkProxy(QNetworkProxy::HttpProxy, squidAddr, 3130); break; } QNetworkProxy::setApplicationProxy(proxy); From 7f1ae3f99dd84f17511fc05daf6b69c90504e61a Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Fri, 8 Feb 2019 11:45:59 +0100 Subject: [PATCH 1291/1650] Convert tst_qhttpsocketengine to work with the Docker-server MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I6590f9cc5159083cba58cfdbacfaee1f9482bd0b Reviewed-by: Mårten Nordheim Reviewed-by: Edward Welbourne --- .../qhttpsocketengine/qhttpsocketengine.pro | 5 +++ .../tst_qhttpsocketengine.cpp | 44 +++++++++++-------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/tests/auto/network/socket/qhttpsocketengine/qhttpsocketengine.pro b/tests/auto/network/socket/qhttpsocketengine/qhttpsocketengine.pro index 56a4fb8aee..492bb6aa8d 100644 --- a/tests/auto/network/socket/qhttpsocketengine/qhttpsocketengine.pro +++ b/tests/auto/network/socket/qhttpsocketengine/qhttpsocketengine.pro @@ -10,3 +10,8 @@ MOC_DIR=tmp requires(qtConfig(private_tests)) QT = core-private network-private testlib +# TODO: For now linux-only, because cyrus is linux-only atm ... +linux { + QT_TEST_SERVER_LIST = squid danted cyrus apache2 + include($$dirname(_QMAKE_CONF_)/tests/auto/testserver.pri) +} diff --git a/tests/auto/network/socket/qhttpsocketengine/tst_qhttpsocketengine.cpp b/tests/auto/network/socket/qhttpsocketengine/tst_qhttpsocketengine.cpp index 68f3ea059b..cdc6fef663 100644 --- a/tests/auto/network/socket/qhttpsocketengine/tst_qhttpsocketengine.cpp +++ b/tests/auto/network/socket/qhttpsocketengine/tst_qhttpsocketengine.cpp @@ -122,7 +122,14 @@ public slots: void tst_QHttpSocketEngine::initTestCase() { +#ifdef QT_TEST_SERVER + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::httpProxyServerName(), 3128)); + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::socksProxyServerName(), 1080)); + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::httpServerName(), 80)); + QVERIFY(QtNetworkSettings::verifyConnection(QtNetworkSettings::imapServerName(), 143)); +#else QVERIFY(QtNetworkSettings::verifyTestNetworkSettings()); +#endif } void tst_QHttpSocketEngine::init() @@ -171,7 +178,7 @@ void tst_QHttpSocketEngine::errorTest_data() QTest::newRow("proxy-host-not-found") << "this-host-does-not-exist." << 1080 << QString() << QString() << int(QAbstractSocket::ProxyNotFoundError); - QTest::newRow("proxy-connection-refused") << QtNetworkSettings::serverName() << 2 << QString() + QTest::newRow("proxy-connection-refused") << QtNetworkSettings::socksProxyServerName() << 2 << QString() << QString() << int(QAbstractSocket::ProxyConnectionRefusedError); @@ -278,13 +285,12 @@ void tst_QHttpSocketEngine::simpleConnectToIMAP() QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol)); QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState); - socketDevice.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::serverName(), 3128)); - - QVERIFY(!socketDevice.connectToHost(QtNetworkSettings::serverIP(), 143)); + socketDevice.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::httpProxyServerName(), 3128)); + QVERIFY(!socketDevice.connectToHost(QtNetworkSettings::imapServerIp(), 143)); QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectingState); QVERIFY(socketDevice.waitForWrite()); QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectedState); - QCOMPARE(socketDevice.peerAddress(), QtNetworkSettings::serverIP()); + QCOMPARE(socketDevice.peerAddress(), QtNetworkSettings::imapServerIp()); QVERIFY(!socketDevice.localAddress().isNull()); QVERIFY(socketDevice.localPort() > 0); @@ -292,10 +298,10 @@ void tst_QHttpSocketEngine::simpleConnectToIMAP() QVERIFY(socketDevice.waitForRead()); // Read the greeting - qint64 available = socketDevice.bytesAvailable(); + qint64 available = int(socketDevice.bytesAvailable()); QVERIFY(available > 0); QByteArray array; - array.resize(available); + array.resize(int(available)); QVERIFY(socketDevice.read(array.data(), array.size()) == available); // Check that the greeting is what we expect it to be @@ -310,9 +316,9 @@ void tst_QHttpSocketEngine::simpleConnectToIMAP() // Wait for the response QVERIFY(socketDevice.waitForRead()); - available = socketDevice.bytesAvailable(); + available = int(socketDevice.bytesAvailable()); QVERIFY(available > 0); - array.resize(available); + array.resize(int(available)); QVERIFY(socketDevice.read(array.data(), array.size()) == available); // Check that the greeting is what we expect it to be @@ -321,7 +327,7 @@ void tst_QHttpSocketEngine::simpleConnectToIMAP() // Wait for the response QVERIFY(socketDevice.waitForRead()); char c; - QCOMPARE(socketDevice.read(&c, sizeof(c)), (qint64) -1); + QCOMPARE(socketDevice.read(&c, sizeof(c)), qint64(-1)); QCOMPARE(socketDevice.error(), QAbstractSocket::RemoteHostClosedError); QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState); } @@ -335,10 +341,10 @@ void tst_QHttpSocketEngine::simpleErrorsAndStates() // Initialize device QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol)); - socketDevice.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::serverName(), 3128)); + socketDevice.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::httpProxyServerName(), 3128)); QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState); - QVERIFY(!socketDevice.connectToHost(QHostAddress(QtNetworkSettings::serverName()), 8088)); + QVERIFY(!socketDevice.connectToHost(QHostAddress(QtNetworkSettings::socksProxyServerName()), 8088)); QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectingState); if (socketDevice.waitForWrite(30000)) { QVERIFY(socketDevice.state() == QAbstractSocket::ConnectedState || @@ -422,7 +428,7 @@ void tst_QHttpSocketEngine::tcpSocketBlockingTest() QTcpSocket socket; // Connect - socket.connectToHost(QtNetworkSettings::serverName(), 143); + socket.connectToHost(QtNetworkSettings::imapServerName(), 143); QVERIFY(socket.waitForConnected()); QCOMPARE(socket.state(), QTcpSocket::ConnectedState); @@ -479,7 +485,7 @@ void tst_QHttpSocketEngine::tcpSocketNonBlockingTest() tcpSocketNonBlocking_socket = &socket; // Connect - socket.connectToHost(QtNetworkSettings::serverName(), 143); + socket.connectToHost(QtNetworkSettings::imapServerName(), 143); QVERIFY(socket.state() == QTcpSocket::HostLookupState || socket.state() == QTcpSocket::ConnectingState); @@ -607,13 +613,13 @@ void tst_QHttpSocketEngine::downloadBigFile() connect(tmpSocket, SIGNAL(connected()), SLOT(exitLoopSlot())); connect(tmpSocket, SIGNAL(readyRead()), SLOT(downloadBigFileSlot())); - tmpSocket->connectToHost(QtNetworkSettings::serverName(), 80); + tmpSocket->connectToHost(QtNetworkSettings::httpServerName(), 80); QTestEventLoop::instance().enterLoop(30); if (QTestEventLoop::instance().timeout()) QFAIL("Network operation timed out"); - QByteArray hostName = QtNetworkSettings::serverName().toLatin1(); + QByteArray hostName = QtNetworkSettings::httpServerName().toLatin1(); QCOMPARE(tmpSocket->state(), QAbstractSocket::ConnectedState); QVERIFY(tmpSocket->write("GET /qtest/mediumfile HTTP/1.0\r\n") > 0); QVERIFY(tmpSocket->write("Host: ") > 0); @@ -664,13 +670,13 @@ void tst_QHttpSocketEngine::passwordAuth() QVERIFY(socketDevice.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol)); QCOMPARE(socketDevice.state(), QAbstractSocket::UnconnectedState); - socketDevice.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::serverName(), 3128, "qsockstest", "password")); + socketDevice.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::httpProxyServerName(), 3128, "qsockstest", "password")); - QVERIFY(!socketDevice.connectToHost(QtNetworkSettings::serverIP(), 143)); + QVERIFY(!socketDevice.connectToHost(QtNetworkSettings::imapServerIp(), 143)); QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectingState); QVERIFY(socketDevice.waitForWrite()); QCOMPARE(socketDevice.state(), QAbstractSocket::ConnectedState); - QCOMPARE(socketDevice.peerAddress(), QtNetworkSettings::serverIP()); + QCOMPARE(socketDevice.peerAddress(), QtNetworkSettings::imapServerIp()); // Wait for the greeting QVERIFY(socketDevice.waitForRead()); From 20063cf99995f45c16e5c6952eb1d7609324be9f Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 14 Feb 2019 16:06:44 +0100 Subject: [PATCH 1292/1650] Actively discard return value of qtConfGetNextCommandlineArg Calling a qmake replace function without assignment is undefined behavior. This amends 11ae0e77. Change-Id: Ie716f295275d1ba79a217745b332a8eca04b355d Reviewed-by: Oliver Wolff --- mkspecs/features/qt_configure.prf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/qt_configure.prf b/mkspecs/features/qt_configure.prf index 7ca65c92b3..e845bf1577 100644 --- a/mkspecs/features/qt_configure.prf +++ b/mkspecs/features/qt_configure.prf @@ -338,7 +338,7 @@ defineTest(qtConfParseCommandLine) { qtConfAddWarning("Command line option -skip is only effective in top-level builds.") skipOptionWarningAdded = 1 } - $$qtConfGetNextCommandlineArg() + val = $$qtConfGetNextCommandlineArg() next() } From f9421f0968b8067ca79d83dc75e35092ac4a4948 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 26 Feb 2019 11:33:13 +0100 Subject: [PATCH 1293/1650] Adjust chunk-size in TLD-suffix list to placate MSVC 2015 MSVC 2015 has a size limit on strings; sizeof (including the terminating '\0') must not exceed 0xffff. The generator for the suffix-list data worked round this by breaking its data into chunks of at most 0xffff bytes; however, it was limiting on the strlen, not the sizeof, so was off by one. It checked for this before adding each suffix, so has (until now) always happened to break early enough; but the latest update gave an exactly 0xffff chunk, whose terminating '\0' took it over MSVC's limit. So adjust the cutoff to effectively include the terminating '\0'. Task-number: QTBUG-72623 Change-Id: I76ea40060d9fc13c0f7002c5ba22e71b8d0af787 Reviewed-by: Peter Hartmann --- util/corelib/qurl-generateTLDs/main.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/util/corelib/qurl-generateTLDs/main.cpp b/util/corelib/qurl-generateTLDs/main.cpp index 006eaf92b1..7268fb077a 100644 --- a/util/corelib/qurl-generateTLDs/main.cpp +++ b/util/corelib/qurl-generateTLDs/main.cpp @@ -113,7 +113,7 @@ int main(int argc, char **argv) { outIndicesBuffer.write("] = {\n"); int totalUtf8Size = 0; - int chunkSize = 0; + int chunkSize = 0; // strlen of the current chunk (sizeof is bigger by 1) int stringUtf8Size = 0; QStringList chunks; for (int a = 0; a < lineCount; a++) { @@ -127,7 +127,8 @@ int main(int argc, char **argv) { int quoteCount = strings.at(a).count('"'); stringUtf8Size = strings.at(a).count() - (zeroCount + quoteCount + utf8CharsCount * 3); chunkSize += stringUtf8Size; - if (chunkSize > 65535) { + // MSVC 2015 chokes if sizeof(a single string) > 0xffff + if (chunkSize >= 0xffff) { static int chunkCount = 0; qWarning() << "chunk" << ++chunkCount << "has length" << chunkSize - stringUtf8Size; outDataBuffer.write(",\n\n"); From f5850cb0da5d9b610711d4fd3c1eaded9d6414e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Micha=C3=ABl=20Celerier?= Date: Mon, 18 Feb 2019 12:30:29 +0100 Subject: [PATCH 1294/1650] CMake: fix generation of config files for external Qt modules When such modules aren't following the libQt5Foo.so naming convention, the generated CMake files would be incorrect. Change-Id: I57908f7466bff7a05f19271ccd495849476bdf38 Reviewed-by: Simon Hausmann Reviewed-by: Paul Lemire Reviewed-by: Joerg Bornemann Reviewed-by: Kevin Funk --- mkspecs/features/create_cmake.prf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mkspecs/features/create_cmake.prf b/mkspecs/features/create_cmake.prf index 2ed708e085..6bf1380716 100644 --- a/mkspecs/features/create_cmake.prf +++ b/mkspecs/features/create_cmake.prf @@ -200,7 +200,9 @@ CMAKE_QT5_MODULE_DEPS = $$join(lib_deps, ";") CMAKE_INTERFACE_MODULE_DEPS = $$join(aux_mod_deps, ";") CMAKE_INTERFACE_QT5_MODULE_DEPS = $$join(aux_lib_deps, ";") -CMAKE_QT_STEM = Qt$$QT_MAJOR_VERSION$${CMAKE_MODULE_NAME}$${QT_LIBINFIX} +# TARGET here is the one changed at the end of qt_module.prf, +# which already contains the Qt5 prefix and QT_LIBINFIX suffix +CMAKE_QT_STEM = $${TARGET} mac { !isEmpty(CMAKE_STATIC_TYPE) { From a34e81ab8be6445877e040b1afb85deeaa725f86 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Fri, 30 Nov 2018 12:14:51 +0100 Subject: [PATCH 1295/1650] platformsupport/input: add xkbcommon utilities lib xcb/eglfs/wayland - all use XKB keyboard configs and APIs. There is a lot of duplicated and naturally a diverging code. This patch adds a helper library to avoid all the mentioned problems and unify feature set between these platforms. qlibinputkeyboard: Added a fixup for 2803cdf758dbae1006a0c50300af12dac9f71531. From spec: "keysyms, when bound to modifiers, affect the rules [..]", meaning we can't look at keys in isolation, but have to check if bounding exists in the keymap. This is done by using xkb_state_mod_name_is_active() API, but that API has its limitations - https://github.com/xkbcommon/libxkbcommon/issues/88 I will fix this separately in the LTS (5.12) branch. We need to read the modifier state before the key action. This patch fixes a regression introduced by aforementioned patch, which caused modifiers being reported wrongly in QKeyEvent::modifiers(). qtwayland: Moved toKeysym(QKeyEvent) from qtwayland repository into this library. For this and other key mapping functionality wayland was duplicating the key table. All of that will be removed from qtwayland, and calls will be replaced to use this lib. Adjusted toKeysym() to fix QTBUG-71301. Qt keys don't map to ASCII codes, so first we need search in our key table, instead of mapping from unicode. lookupStringNoKeysymTransformations(): fixed off-by-one error, where we were including terminating NUL in QString. Fixes: QTBUG-71301 Task-number: QTBUG-65503 Change-Id: Idfddea5b34ad620235dc08c0b9e5a0669111821a Reviewed-by: Johan Helsing --- src/platformsupport/input/input-support.pro | 35 + src/platformsupport/input/input.pro | 37 +- .../input/libinput/libinput.pri | 5 +- .../input/libinput/qlibinputkeyboard.cpp | 185 +--- .../input/libinput/qlibinputkeyboard_p.h | 8 +- .../input/xkbcommon/qxkbcommon.cpp | 797 ++++++++++++++++++ .../input/xkbcommon/qxkbcommon_3rdparty.cpp} | 28 +- .../input/xkbcommon/qxkbcommon_p.h | 118 +++ .../input/xkbcommon/xkbcommon.pro | 23 + src/plugins/platforms/xcb/qxcbkeyboard.cpp | 723 +--------------- src/plugins/platforms/xcb/qxcbkeyboard.h | 35 +- src/plugins/platforms/xcb/xcb_qpa_lib.pro | 4 +- sync.profile | 1 + 13 files changed, 1043 insertions(+), 956 deletions(-) create mode 100644 src/platformsupport/input/input-support.pro create mode 100644 src/platformsupport/input/xkbcommon/qxkbcommon.cpp rename src/{plugins/platforms/xcb/qxcbxkbcommon.h => platformsupport/input/xkbcommon/qxkbcommon_3rdparty.cpp} (94%) create mode 100644 src/platformsupport/input/xkbcommon/qxkbcommon_p.h create mode 100644 src/platformsupport/input/xkbcommon/xkbcommon.pro diff --git a/src/platformsupport/input/input-support.pro b/src/platformsupport/input/input-support.pro new file mode 100644 index 0000000000..3d39210b9e --- /dev/null +++ b/src/platformsupport/input/input-support.pro @@ -0,0 +1,35 @@ +TARGET = QtInputSupport +MODULE = input_support + +QT = core-private gui-private devicediscovery_support-private +CONFIG += static internal_module + +DEFINES += QT_NO_CAST_FROM_ASCII +PRECOMPILED_HEADER = ../../corelib/global/qt_pch.h + +qtConfig(evdev) { + include($$PWD/evdevmouse/evdevmouse.pri) + include($$PWD/evdevkeyboard/evdevkeyboard.pri) + include($$PWD/evdevtouch/evdevtouch.pri) + qtConfig(tabletevent) { + include($$PWD/evdevtablet/evdevtablet.pri) + } +} + +qtConfig(tslib) { + include($$PWD/tslib/tslib.pri) +} + +qtConfig(libinput) { + include($$PWD/libinput/libinput.pri) +} + +qtConfig(evdev)|qtConfig(libinput) { + include($$PWD/shared/shared.pri) +} + +qtConfig(integrityhid) { + include($$PWD/integrityhid/integrityhid.pri) +} + +load(qt_module) diff --git a/src/platformsupport/input/input.pro b/src/platformsupport/input/input.pro index 3d39210b9e..138c04dea3 100644 --- a/src/platformsupport/input/input.pro +++ b/src/platformsupport/input/input.pro @@ -1,35 +1,8 @@ -TARGET = QtInputSupport -MODULE = input_support +TEMPLATE = subdirs +QT_FOR_CONFIG += gui-private -QT = core-private gui-private devicediscovery_support-private -CONFIG += static internal_module +qtConfig(xkbcommon): SUBDIRS += xkbcommon -DEFINES += QT_NO_CAST_FROM_ASCII -PRECOMPILED_HEADER = ../../corelib/global/qt_pch.h +SUBDIRS += input-support.pro ### FIXME - QTBUG-52657 -qtConfig(evdev) { - include($$PWD/evdevmouse/evdevmouse.pri) - include($$PWD/evdevkeyboard/evdevkeyboard.pri) - include($$PWD/evdevtouch/evdevtouch.pri) - qtConfig(tabletevent) { - include($$PWD/evdevtablet/evdevtablet.pri) - } -} - -qtConfig(tslib) { - include($$PWD/tslib/tslib.pri) -} - -qtConfig(libinput) { - include($$PWD/libinput/libinput.pri) -} - -qtConfig(evdev)|qtConfig(libinput) { - include($$PWD/shared/shared.pri) -} - -qtConfig(integrityhid) { - include($$PWD/integrityhid/integrityhid.pri) -} - -load(qt_module) +CONFIG += ordered diff --git a/src/platformsupport/input/libinput/libinput.pri b/src/platformsupport/input/libinput/libinput.pri index 476f20c1b8..f80b5f41d9 100644 --- a/src/platformsupport/input/libinput/libinput.pri +++ b/src/platformsupport/input/libinput/libinput.pri @@ -14,4 +14,7 @@ QMAKE_USE_PRIVATE += libudev libinput INCLUDEPATH += $$PWD/../shared -qtConfig(xkbcommon): QMAKE_USE_PRIVATE += xkbcommon +qtConfig(xkbcommon): { + QMAKE_USE_PRIVATE += xkbcommon + QT += xkbcommon_support-private +} diff --git a/src/platformsupport/input/libinput/qlibinputkeyboard.cpp b/src/platformsupport/input/libinput/qlibinputkeyboard.cpp index baef769bc9..6586b084f1 100644 --- a/src/platformsupport/input/libinput/qlibinputkeyboard.cpp +++ b/src/platformsupport/input/libinput/qlibinputkeyboard.cpp @@ -47,6 +47,7 @@ #if QT_CONFIG(xkbcommon) #include #include +#include #endif QT_BEGIN_NAMESPACE @@ -56,88 +57,7 @@ Q_DECLARE_LOGGING_CATEGORY(qLcLibInput) const int REPEAT_DELAY = 500; const int REPEAT_RATE = 100; -#if QT_CONFIG(xkbcommon) -struct KeyTabEntry { - int xkbkey; - int qtkey; -}; - -static inline bool operator==(const KeyTabEntry &a, const KeyTabEntry &b) -{ - return a.xkbkey == b.xkbkey; -} - -static const KeyTabEntry keyTab[] = { - { XKB_KEY_Escape, Qt::Key_Escape }, - { XKB_KEY_Tab, Qt::Key_Tab }, - { XKB_KEY_ISO_Left_Tab, Qt::Key_Backtab }, - { XKB_KEY_BackSpace, Qt::Key_Backspace }, - { XKB_KEY_Return, Qt::Key_Return }, - { XKB_KEY_Insert, Qt::Key_Insert }, - { XKB_KEY_Delete, Qt::Key_Delete }, - { XKB_KEY_Clear, Qt::Key_Delete }, - { XKB_KEY_Pause, Qt::Key_Pause }, - { XKB_KEY_Print, Qt::Key_Print }, - - { XKB_KEY_Home, Qt::Key_Home }, - { XKB_KEY_End, Qt::Key_End }, - { XKB_KEY_Left, Qt::Key_Left }, - { XKB_KEY_Up, Qt::Key_Up }, - { XKB_KEY_Right, Qt::Key_Right }, - { XKB_KEY_Down, Qt::Key_Down }, - { XKB_KEY_Prior, Qt::Key_PageUp }, - { XKB_KEY_Next, Qt::Key_PageDown }, - - { XKB_KEY_Shift_L, Qt::Key_Shift }, - { XKB_KEY_Shift_R, Qt::Key_Shift }, - { XKB_KEY_Shift_Lock, Qt::Key_Shift }, - { XKB_KEY_Control_L, Qt::Key_Control }, - { XKB_KEY_Control_R, Qt::Key_Control }, - { XKB_KEY_Meta_L, Qt::Key_Meta }, - { XKB_KEY_Meta_R, Qt::Key_Meta }, - { XKB_KEY_Alt_L, Qt::Key_Alt }, - { XKB_KEY_Alt_R, Qt::Key_Alt }, - { XKB_KEY_Caps_Lock, Qt::Key_CapsLock }, - { XKB_KEY_Num_Lock, Qt::Key_NumLock }, - { XKB_KEY_Scroll_Lock, Qt::Key_ScrollLock }, - { XKB_KEY_Super_L, Qt::Key_Super_L }, - { XKB_KEY_Super_R, Qt::Key_Super_R }, - { XKB_KEY_Menu, Qt::Key_Menu }, - { XKB_KEY_Hyper_L, Qt::Key_Hyper_L }, - { XKB_KEY_Hyper_R, Qt::Key_Hyper_R }, - { XKB_KEY_Help, Qt::Key_Help }, - - { XKB_KEY_KP_Space, Qt::Key_Space }, - { XKB_KEY_KP_Tab, Qt::Key_Tab }, - { XKB_KEY_KP_Enter, Qt::Key_Enter }, - { XKB_KEY_KP_Home, Qt::Key_Home }, - { XKB_KEY_KP_Left, Qt::Key_Left }, - { XKB_KEY_KP_Up, Qt::Key_Up }, - { XKB_KEY_KP_Right, Qt::Key_Right }, - { XKB_KEY_KP_Down, Qt::Key_Down }, - { XKB_KEY_KP_Prior, Qt::Key_PageUp }, - { XKB_KEY_KP_Next, Qt::Key_PageDown }, - { XKB_KEY_KP_End, Qt::Key_End }, - { XKB_KEY_KP_Begin, Qt::Key_Clear }, - { XKB_KEY_KP_Insert, Qt::Key_Insert }, - { XKB_KEY_KP_Delete, Qt::Key_Delete }, - { XKB_KEY_KP_Equal, Qt::Key_Equal }, - { XKB_KEY_KP_Multiply, Qt::Key_Asterisk }, - { XKB_KEY_KP_Add, Qt::Key_Plus }, - { XKB_KEY_KP_Separator, Qt::Key_Comma }, - { XKB_KEY_KP_Subtract, Qt::Key_Minus }, - { XKB_KEY_KP_Decimal, Qt::Key_Period }, - { XKB_KEY_KP_Divide, Qt::Key_Slash }, -}; -#endif - QLibInputKeyboard::QLibInputKeyboard() -#if QT_CONFIG(xkbcommon) - : m_ctx(0), - m_keymap(0), - m_state(0), - m_mods(Qt::NoModifier) -#endif { #if QT_CONFIG(xkbcommon) qCDebug(qLcLibInput) << "Using xkbcommon for key mapping"; @@ -148,18 +68,14 @@ QLibInputKeyboard::QLibInputKeyboard() } m_keymap = xkb_keymap_new_from_names(m_ctx, nullptr, XKB_KEYMAP_COMPILE_NO_FLAGS); if (!m_keymap) { - qWarning("Failed to compile keymap"); + qCWarning(qLcLibInput, "Failed to compile keymap"); return; } m_state = xkb_state_new(m_keymap); if (!m_state) { - qWarning("Failed to create xkb state"); + qCWarning(qLcLibInput, "Failed to create xkb state"); return; } - m_modindex[0] = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_CTRL); - m_modindex[1] = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_ALT); - m_modindex[2] = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_SHIFT); - m_modindex[3] = xkb_keymap_mod_get_index(m_keymap, XKB_MOD_NAME_LOGO); m_repeatTimer.setSingleShot(true); connect(&m_repeatTimer, &QTimer::timeout, this, &QLibInputKeyboard::handleRepeat); @@ -186,52 +102,33 @@ void QLibInputKeyboard::processKey(libinput_event_keyboard *e) if (!m_ctx || !m_keymap || !m_state) return; - const uint32_t k = libinput_event_keyboard_get_key(e) + 8; + const uint32_t keycode = libinput_event_keyboard_get_key(e) + 8; + const xkb_keysym_t sym = xkb_state_key_get_one_sym(m_state, keycode); const bool pressed = libinput_event_keyboard_get_key_state(e) == LIBINPUT_KEY_STATE_PRESSED; - QVarLengthArray chars(32); - const int size = xkb_state_key_get_utf8(m_state, k, chars.data(), chars.size()); - if (Q_UNLIKELY(size + 1 > chars.size())) { // +1 for NUL - chars.resize(size + 1); - xkb_state_key_get_utf8(m_state, k, chars.data(), chars.size()); - } - const QString text = QString::fromUtf8(chars.constData(), size); + // Modifiers here is the modifier state before the event, i.e. not + // including the current key in case it is a modifier. See the XOR + // logic in QKeyEvent::modifiers(). ### QTBUG-73826 + Qt::KeyboardModifiers modifiers = QXkbCommon::modifiers(m_state); - const xkb_keysym_t sym = xkb_state_key_get_one_sym(m_state, k); + const QString text = QXkbCommon::lookupString(m_state, keycode); + const int qtkey = QXkbCommon::keysymToQtKey(sym, modifiers, m_state, keycode); - // mods here is the modifier state before the event, i.e. not - // including the current key in case it is a modifier. - Qt::KeyboardModifiers mods = Qt::NoModifier; - const int qtkey = keysymToQtKey(sym, &mods, text); + xkb_state_update_key(m_state, keycode, pressed ? XKB_KEY_DOWN : XKB_KEY_UP); - if (qtkey == Qt::Key_Control) - mods |= Qt::ControlModifier; - if (qtkey == Qt::Key_Alt) - mods |= Qt::AltModifier; - if (qtkey == Qt::Key_Shift) - mods |= Qt::ShiftModifier; - if (qtkey == Qt::Key_Meta) - mods |= Qt::MetaModifier; - xkb_state_update_key(m_state, k, pressed ? XKB_KEY_DOWN : XKB_KEY_UP); + Qt::KeyboardModifiers modifiersAfterStateChange = QXkbCommon::modifiers(m_state); + QGuiApplicationPrivate::inputDeviceManager()->setKeyboardModifiers(modifiersAfterStateChange); - if (mods != Qt::NoModifier) { - if (pressed) - m_mods |= mods; - else - m_mods &= ~mods; - - QGuiApplicationPrivate::inputDeviceManager()->setKeyboardModifiers(m_mods); - } QWindowSystemInterface::handleExtendedKeyEvent(nullptr, pressed ? QEvent::KeyPress : QEvent::KeyRelease, - qtkey, m_mods, k, sym, m_mods, text); + qtkey, modifiers, keycode, sym, modifiers, text); - if (pressed && xkb_keymap_key_repeats(m_keymap, k)) { + if (pressed && xkb_keymap_key_repeats(m_keymap, keycode)) { m_repeatData.qtkey = qtkey; - m_repeatData.mods = mods; - m_repeatData.nativeScanCode = k; + m_repeatData.mods = modifiers; + m_repeatData.nativeScanCode = keycode; m_repeatData.virtualKey = sym; - m_repeatData.nativeMods = mods; + m_repeatData.nativeMods = modifiers; m_repeatData.unicodeText = text; m_repeatData.repeatCount = 1; m_repeatTimer.setInterval(REPEAT_DELAY); @@ -256,50 +153,6 @@ void QLibInputKeyboard::handleRepeat() m_repeatTimer.setInterval(REPEAT_RATE); m_repeatTimer.start(); } - -int QLibInputKeyboard::keysymToQtKey(xkb_keysym_t key) const -{ - const size_t elemCount = sizeof(keyTab) / sizeof(KeyTabEntry); - KeyTabEntry e; - e.xkbkey = key; - const KeyTabEntry *result = std::find(keyTab, keyTab + elemCount, e); - return result != keyTab + elemCount ? result->qtkey : 0; -} - -int QLibInputKeyboard::keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers *modifiers, const QString &text) const -{ - int code = 0; -#if QT_CONFIG(textcodec) - QTextCodec *systemCodec = QTextCodec::codecForLocale(); -#endif - if (keysym < 128 || (keysym < 256 -#if QT_CONFIG(textcodec) - && systemCodec->mibEnum() == 4 -#endif - )) { - // upper-case key, if known - code = isprint((int)keysym) ? toupper((int)keysym) : 0; - } else if (keysym >= XKB_KEY_F1 && keysym <= XKB_KEY_F35) { - // function keys - code = Qt::Key_F1 + ((int)keysym - XKB_KEY_F1); - } else if (keysym >= XKB_KEY_KP_Space && keysym <= XKB_KEY_KP_9) { - if (keysym >= XKB_KEY_KP_0) { - // numeric keypad keys - code = Qt::Key_0 + ((int)keysym - XKB_KEY_KP_0); - } else { - code = keysymToQtKey(keysym); - } - *modifiers |= Qt::KeypadModifier; - } else if (text.length() == 1 && text.unicode()->unicode() > 0x1f - && text.unicode()->unicode() != 0x7f - && !(keysym >= XKB_KEY_dead_grave && keysym <= XKB_KEY_dead_longsolidusoverlay)) { - code = text.unicode()->toUpper().unicode(); - } else { - // any other keys - code = keysymToQtKey(keysym); - } - return code; -} #endif QT_END_NAMESPACE diff --git a/src/platformsupport/input/libinput/qlibinputkeyboard_p.h b/src/platformsupport/input/libinput/qlibinputkeyboard_p.h index 14ae71b545..7521902e02 100644 --- a/src/platformsupport/input/libinput/qlibinputkeyboard_p.h +++ b/src/platformsupport/input/libinput/qlibinputkeyboard_p.h @@ -79,10 +79,9 @@ private: int keysymToQtKey(xkb_keysym_t key) const; int keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers *modifiers, const QString &text) const; - xkb_context *m_ctx; - xkb_keymap *m_keymap; - xkb_state *m_state; - xkb_mod_index_t m_modindex[4]; + xkb_context *m_ctx = nullptr; + xkb_keymap *m_keymap = nullptr; + xkb_state *m_state = nullptr; QTimer m_repeatTimer; @@ -95,7 +94,6 @@ private: QString unicodeText; int repeatCount; } m_repeatData; - Qt::KeyboardModifiers m_mods; #endif }; diff --git a/src/platformsupport/input/xkbcommon/qxkbcommon.cpp b/src/platformsupport/input/xkbcommon/qxkbcommon.cpp new file mode 100644 index 0000000000..4bee868fa9 --- /dev/null +++ b/src/platformsupport/input/xkbcommon/qxkbcommon.cpp @@ -0,0 +1,797 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qxkbcommon_p.h" + +#include + +#include + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcXkbcommon, "qt.xkbcommon") + +static int keysymToQtKey_internal(xkb_keysym_t keysym, Qt::KeyboardModifiers modifiers, + xkb_state *state, xkb_keycode_t code, + bool superAsMeta, bool hyperAsMeta); + +typedef struct xkb2qt +{ + unsigned int xkb; + unsigned int qt; + + constexpr bool operator <=(const xkb2qt &that) const noexcept + { + return xkb <= that.xkb; + } + + constexpr bool operator <(const xkb2qt &that) const noexcept + { + return xkb < that.xkb; + } +} xkb2qt_t; + +template +struct Xkb2Qt +{ + using Type = xkb2qt_t; + static constexpr Type data() noexcept { return Type{Xkb, Qt}; } +}; + +static constexpr const auto KeyTbl = qMakeArray( + QSortedData< + // misc keys + + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt<0x1005FF60, Qt::Key_SysReq>, // hardcoded Sun SysReq + Xkb2Qt<0x1007ff00, Qt::Key_SysReq>, // hardcoded X386 SysReq + + // cursor movement + + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + + // modifiers + + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt<0x1000FF74, Qt::Key_Backtab>, // hardcoded HP backtab + Xkb2Qt<0x1005FF10, Qt::Key_F11>, // hardcoded Sun F36 (labeled F11) + Xkb2Qt<0x1005FF11, Qt::Key_F12>, // hardcoded Sun F37 (labeled F12) + + // numeric and function keypad keys + + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + + // special non-XF86 function keys + + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + + // International input method support keys + + // International & multi-key character composition + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + + // Misc Functions + Xkb2Qt, + Xkb2Qt, + + // Japanese keyboard support + Xkb2Qt, + Xkb2Qt, + //Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + //Xkb2Qt, + //Xkb2Qt, + //Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + + // Korean keyboard support + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + //Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + //Xkb2Qt, + //Xkb2Qt, + //Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + //Xkb2Qt, + Xkb2Qt, + + // dead keys + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + + // Special keys from X.org - This include multimedia keys, + // wireless/bluetooth/uwb keys, special launcher keys, etc. + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, // ### Qt 6: remap properly + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, // ### Qt 6: remap properly + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt, + Xkb2Qt + >::Data{} +); + +xkb_keysym_t QXkbCommon::qxkbcommon_xkb_keysym_to_upper(xkb_keysym_t ks) +{ + xkb_keysym_t lower, upper; + + xkbcommon_XConvertCase(ks, &lower, &upper); + + return upper; +} + +QString QXkbCommon::lookupString(struct xkb_state *state, xkb_keycode_t code) +{ + QVarLengthArray chars(32); + const int size = xkb_state_key_get_utf8(state, code, chars.data(), chars.size()); + if (Q_UNLIKELY(size + 1 > chars.size())) { // +1 for NUL + chars.resize(size + 1); + xkb_state_key_get_utf8(state, code, chars.data(), chars.size()); + } + return QString::fromUtf8(chars.constData(), size); +} + +QString QXkbCommon::lookupStringNoKeysymTransformations(xkb_keysym_t keysym) +{ + QVarLengthArray chars(32); + const int size = xkb_keysym_to_utf8(keysym, chars.data(), chars.size()); + if (size == 0) + return QString(); // the keysym does not have a Unicode representation + + if (Q_UNLIKELY(size > chars.size())) { + chars.resize(size); + xkb_keysym_to_utf8(keysym, chars.data(), chars.size()); + } + return QString::fromUtf8(chars.constData(), size - 1); +} + +QVector QXkbCommon::toKeysym(QKeyEvent *event) +{ + QVector keysyms; + int qtKey = event->key(); + + if (qtKey >= Qt::Key_F1 && qtKey <= Qt::Key_F35) { + keysyms.append(XKB_KEY_F1 + (qtKey - Qt::Key_F1)); + } else if (event->modifiers() & Qt::KeypadModifier) { + if (qtKey >= Qt::Key_0 && qtKey <= Qt::Key_9) + keysyms.append(XKB_KEY_KP_0 + (qtKey - Qt::Key_0)); + } else if (isLatin(qtKey) && event->text().isUpper()) { + keysyms.append(qtKey); + } + + if (!keysyms.isEmpty()) + return keysyms; + + // check if we have a direct mapping + auto it = std::find_if(KeyTbl.cbegin(), KeyTbl.cend(), [&qtKey](xkb2qt_t elem) { + return elem.qt == static_cast(qtKey); + }); + if (it != KeyTbl.end()) { + keysyms.append(it->xkb); + return keysyms; + } + + QVector ucs4; + if (event->text().isEmpty()) + ucs4.append(qtKey); + else + ucs4 = event->text().toUcs4(); + + // From libxkbcommon keysym-utf.c: + // "We allow to represent any UCS character in the range U-00000000 to + // U-00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff." + for (uint utf32 : qAsConst(ucs4)) + keysyms.append(utf32 | 0x01000000); + + return keysyms; +} + +int QXkbCommon::keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers modifiers) +{ + return keysymToQtKey(keysym, modifiers, nullptr, 0); +} + +int QXkbCommon::keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers modifiers, + xkb_state *state, xkb_keycode_t code, + bool superAsMeta, bool hyperAsMeta) +{ + // Note 1: All standard key sequences on linux (as defined in platform theme) + // that use a latin character also contain a control modifier, which is why + // checking for Qt::ControlModifier is sufficient here. It is possible to + // override QPlatformTheme::keyBindings() and provide custom sequences for + // QKeySequence::StandardKey. Custom sequences probably should respect this + // convention (alternatively, we could test against other modifiers here). + // Note 2: The possibleKeys() shorcut mechanism is not affected by this value + // adjustment and does its own thing. + if (modifiers & Qt::ControlModifier) { + // With standard shortcuts we should prefer a latin character, this is + // for checks like "some qkeyevent == QKeySequence::Copy" to work even + // when using for example 'russian' keyboard layout. + if (!QXkbCommon::isLatin(keysym)) { + xkb_keysym_t latinKeysym = QXkbCommon::lookupLatinKeysym(state, code); + if (latinKeysym != XKB_KEY_NoSymbol) + keysym = latinKeysym; + } + } + + return keysymToQtKey_internal(keysym, modifiers, state, code, superAsMeta, hyperAsMeta); +} + +static int keysymToQtKey_internal(xkb_keysym_t keysym, Qt::KeyboardModifiers modifiers, + xkb_state *state, xkb_keycode_t code, + bool superAsMeta, bool hyperAsMeta) +{ + int qtKey = 0; + + // lookup from direct mapping + if (keysym >= XKB_KEY_F1 && keysym <= XKB_KEY_F35) { + // function keys + qtKey = Qt::Key_F1 + (keysym - XKB_KEY_F1); + } else if (keysym >= XKB_KEY_KP_0 && keysym <= XKB_KEY_KP_9) { + // numeric keypad keys + qtKey = Qt::Key_0 + (keysym - XKB_KEY_KP_0); + } else if (QXkbCommon::isLatin(keysym)) { + qtKey = QXkbCommon::qxkbcommon_xkb_keysym_to_upper(keysym); + } else { + // check if we have a direct mapping + xkb2qt_t searchKey{keysym, 0}; + auto it = std::lower_bound(KeyTbl.cbegin(), KeyTbl.cend(), searchKey); + if (it != KeyTbl.end() && !(searchKey < *it)) + qtKey = it->qt; + } + + if (qtKey) + return qtKey; + + // lookup from unicode + QString text; + if (!state || modifiers & Qt::ControlModifier) { + // Control modifier changes the text to ASCII control character, therefore we + // can't use this text to map keysym to a qt key. We can use the same keysym + // (it is not affectd by transformation) to obtain untransformed text. For details + // see "Appendix A. Default Symbol Transformations" in the XKB specification. + text = QXkbCommon::lookupStringNoKeysymTransformations(keysym); + } else { + text = QXkbCommon::lookupString(state, code); + } + if (!text.isEmpty()) { + if (text.unicode()->isDigit()) { + // Ensures that also non-latin digits are mapped to corresponding qt keys, + // e.g CTRL + ۲ (arabic two), is mapped to CTRL + Qt::Key_2. + qtKey = Qt::Key_0 + text.unicode()->digitValue(); + } else { + qtKey = text.unicode()->toUpper().unicode(); + } + } + + // translate Super/Hyper keys to Meta if we're using them as the MetaModifier + if (superAsMeta && (qtKey == Qt::Key_Super_L || qtKey == Qt::Key_Super_R)) + qtKey = Qt::Key_Meta; + if (hyperAsMeta && (qtKey == Qt::Key_Hyper_L || qtKey == Qt::Key_Hyper_R)) + qtKey = Qt::Key_Meta; + + return qtKey; +} + +Qt::KeyboardModifiers QXkbCommon::modifiers(struct xkb_state *state) +{ + Qt::KeyboardModifiers modifiers = Qt::NoModifier; + + if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_CTRL, XKB_STATE_MODS_EFFECTIVE) > 0) + modifiers |= Qt::ControlModifier; + if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_ALT, XKB_STATE_MODS_EFFECTIVE) > 0) + modifiers |= Qt::AltModifier; + if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_SHIFT, XKB_STATE_MODS_EFFECTIVE) > 0) + modifiers |= Qt::ShiftModifier; + if (xkb_state_mod_name_is_active(state, XKB_MOD_NAME_LOGO, XKB_STATE_MODS_EFFECTIVE) > 0) + modifiers |= Qt::MetaModifier; + + return modifiers; +} + +// Possible modifier states. +static const Qt::KeyboardModifiers ModsTbl[] = { + Qt::NoModifier, // 0 + Qt::ShiftModifier, // 1 + Qt::ControlModifier, // 2 + Qt::ControlModifier | Qt::ShiftModifier, // 3 + Qt::AltModifier, // 4 + Qt::AltModifier | Qt::ShiftModifier, // 5 + Qt::AltModifier | Qt::ControlModifier, // 6 + Qt::AltModifier | Qt::ShiftModifier | Qt::ControlModifier, // 7 + Qt::NoModifier // Fall-back to raw Key_*, for non-latin1 kb layouts +}; + +QList QXkbCommon::possibleKeys(xkb_state *state, const QKeyEvent *event, + bool superAsMeta, bool hyperAsMeta) +{ + QList result; + quint32 keycode = event->nativeScanCode(); + Qt::KeyboardModifiers modifiers = event->modifiers(); + xkb_keymap *keymap = xkb_state_get_keymap(state); + // turn off the modifier bits which doesn't participate in shortcuts + Qt::KeyboardModifiers notNeeded = Qt::KeypadModifier | Qt::GroupSwitchModifier; + modifiers &= ~notNeeded; + // create a fresh kb state and test against the relevant modifier combinations + ScopedXKBState scopedXkbQueryState(xkb_state_new(keymap)); + xkb_state *queryState = scopedXkbQueryState.get(); + if (!queryState) { + qCWarning(lcXkbcommon) << Q_FUNC_INFO << "failed to compile xkb keymap"; + return result; + } + // get kb state from the master state and update the temporary state + xkb_layout_index_t lockedLayout = xkb_state_serialize_layout(state, XKB_STATE_LAYOUT_LOCKED); + xkb_mod_mask_t latchedMods = xkb_state_serialize_mods(state, XKB_STATE_MODS_LATCHED); + xkb_mod_mask_t lockedMods = xkb_state_serialize_mods(state, XKB_STATE_MODS_LOCKED); + xkb_mod_mask_t depressedMods = xkb_state_serialize_mods(state, XKB_STATE_MODS_DEPRESSED); + xkb_state_update_mask(queryState, depressedMods, latchedMods, lockedMods, 0, 0, lockedLayout); + // handle shortcuts for level three and above + xkb_layout_index_t layoutIndex = xkb_state_key_get_layout(queryState, keycode); + xkb_level_index_t levelIndex = 0; + if (layoutIndex != XKB_LAYOUT_INVALID) { + levelIndex = xkb_state_key_get_level(queryState, keycode, layoutIndex); + if (levelIndex == XKB_LEVEL_INVALID) + levelIndex = 0; + } + if (levelIndex <= 1) + xkb_state_update_mask(queryState, 0, latchedMods, lockedMods, 0, 0, lockedLayout); + + xkb_keysym_t sym = xkb_state_key_get_one_sym(queryState, keycode); + if (sym == XKB_KEY_NoSymbol) + return result; + + int baseQtKey = keysymToQtKey_internal(sym, modifiers, queryState, keycode, superAsMeta, hyperAsMeta); + if (baseQtKey) + result += (baseQtKey + modifiers); + + xkb_mod_index_t shiftMod = xkb_keymap_mod_get_index(keymap, "Shift"); + xkb_mod_index_t altMod = xkb_keymap_mod_get_index(keymap, "Alt"); + xkb_mod_index_t controlMod = xkb_keymap_mod_get_index(keymap, "Control"); + xkb_mod_index_t metaMod = xkb_keymap_mod_get_index(keymap, "Meta"); + + Q_ASSERT(shiftMod < 32); + Q_ASSERT(altMod < 32); + Q_ASSERT(controlMod < 32); + + xkb_mod_mask_t depressed; + int qtKey = 0; + // obtain a list of possible shortcuts for the given key event + for (uint i = 1; i < sizeof(ModsTbl) / sizeof(*ModsTbl) ; ++i) { + Qt::KeyboardModifiers neededMods = ModsTbl[i]; + if ((modifiers & neededMods) == neededMods) { + if (i == 8) { + if (isLatin(baseQtKey)) + continue; + // add a latin key as a fall back key + sym = lookupLatinKeysym(state, keycode); + } else { + depressed = 0; + if (neededMods & Qt::AltModifier) + depressed |= (1 << altMod); + if (neededMods & Qt::ShiftModifier) + depressed |= (1 << shiftMod); + if (neededMods & Qt::ControlModifier) + depressed |= (1 << controlMod); + if (metaMod < 32 && neededMods & Qt::MetaModifier) + depressed |= (1 << metaMod); + xkb_state_update_mask(queryState, depressed, latchedMods, lockedMods, 0, 0, lockedLayout); + sym = xkb_state_key_get_one_sym(queryState, keycode); + } + if (sym == XKB_KEY_NoSymbol) + continue; + + Qt::KeyboardModifiers mods = modifiers & ~neededMods; + qtKey = keysymToQtKey_internal(sym, mods, queryState, keycode, superAsMeta, hyperAsMeta); + if (!qtKey || qtKey == baseQtKey) + continue; + + // catch only more specific shortcuts, i.e. Ctrl+Shift+= also generates Ctrl++ and +, + // but Ctrl++ is more specific than +, so we should skip the last one + bool ambiguous = false; + for (int shortcut : qAsConst(result)) { + if (int(shortcut & ~Qt::KeyboardModifierMask) == qtKey && (shortcut & mods) == mods) { + ambiguous = true; + break; + } + } + if (ambiguous) + continue; + + result += (qtKey + mods); + } + } + + return result; +} + +void QXkbCommon::verifyHasLatinLayout(xkb_keymap *keymap) +{ + const xkb_layout_index_t layoutCount = xkb_keymap_num_layouts(keymap); + const xkb_keycode_t minKeycode = xkb_keymap_min_keycode(keymap); + const xkb_keycode_t maxKeycode = xkb_keymap_max_keycode(keymap); + + const xkb_keysym_t *keysyms = nullptr; + int nrLatinKeys = 0; + for (xkb_layout_index_t layout = 0; layout < layoutCount; ++layout) { + for (xkb_keycode_t code = minKeycode; code < maxKeycode; ++code) { + xkb_keymap_key_get_syms_by_level(keymap, code, layout, 0, &keysyms); + if (keysyms && isLatin(keysyms[0])) + nrLatinKeys++; + if (nrLatinKeys > 10) // arbitrarily chosen threshold + return; + } + } + // This means that lookupLatinKeysym() will not find anything and latin + // key shortcuts might not work. This is a bug in the affected desktop + // environment. Usually can be solved via system settings by adding e.g. 'us' + // layout to the list of seleced layouts, or by using command line, "setxkbmap + // -layout rus,en". The position of latin key based layout in the list of the + // selected layouts is irrelevant. Properly functioning desktop environments + // handle this behind the scenes, even if no latin key based layout has been + // explicitly listed in the selected layouts. + qCDebug(lcXkbcommon, "no keyboard layouts with latin keys present"); +} + +xkb_keysym_t QXkbCommon::lookupLatinKeysym(xkb_state *state, xkb_keycode_t keycode) +{ + xkb_layout_index_t layout; + xkb_keysym_t sym = XKB_KEY_NoSymbol; + xkb_keymap *keymap = xkb_state_get_keymap(state); + const xkb_layout_index_t layoutCount = xkb_keymap_num_layouts_for_key(keymap, keycode); + const xkb_layout_index_t currentLayout = xkb_state_key_get_layout(state, keycode); + // Look at user layouts in the order in which they are defined in system + // settings to find a latin keysym. + for (layout = 0; layout < layoutCount; ++layout) { + if (layout == currentLayout) + continue; + const xkb_keysym_t *syms = nullptr; + xkb_level_index_t level = xkb_state_key_get_level(state, keycode, layout); + if (xkb_keymap_key_get_syms_by_level(keymap, keycode, layout, level, &syms) != 1) + continue; + if (isLatin(syms[0])) { + sym = syms[0]; + break; + } + } + + if (sym == XKB_KEY_NoSymbol) + return sym; + + xkb_mod_mask_t latchedMods = xkb_state_serialize_mods(state, XKB_STATE_MODS_LATCHED); + xkb_mod_mask_t lockedMods = xkb_state_serialize_mods(state, XKB_STATE_MODS_LOCKED); + + // Check for uniqueness, consider the following setup: + // setxkbmap -layout us,ru,us -variant dvorak,, -option 'grp:ctrl_alt_toggle' (set 'ru' as active). + // In this setup, the user would expect to trigger a ctrl+q shortcut by pressing ctrl+, + // because "US dvorak" is higher up in the layout settings list. This check verifies that an obtained + // 'sym' can not be acquired by any other layout higher up in the user's layout list. If it can be acquired + // then the obtained key is not unique. This prevents ctrl+ from generating a ctrl+q + // shortcut in the above described setup. We don't want ctrl+ and ctrl+ to + // generate the same shortcut event in this case. + const xkb_keycode_t minKeycode = xkb_keymap_min_keycode(keymap); + const xkb_keycode_t maxKeycode = xkb_keymap_max_keycode(keymap); + ScopedXKBState queryState(xkb_state_new(keymap)); + for (xkb_layout_index_t prevLayout = 0; prevLayout < layout; ++prevLayout) { + xkb_state_update_mask(queryState.get(), 0, latchedMods, lockedMods, 0, 0, prevLayout); + for (xkb_keycode_t code = minKeycode; code < maxKeycode; ++code) { + xkb_keysym_t prevSym = xkb_state_key_get_one_sym(queryState.get(), code); + if (prevSym == sym) { + sym = XKB_KEY_NoSymbol; + break; + } + } + } + + return sym; +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbxkbcommon.h b/src/platformsupport/input/xkbcommon/qxkbcommon_3rdparty.cpp similarity index 94% rename from src/plugins/platforms/xcb/qxcbxkbcommon.h rename to src/platformsupport/input/xkbcommon/qxkbcommon_3rdparty.cpp index 422c0c0f12..08f43b3b72 100644 --- a/src/plugins/platforms/xcb/qxcbxkbcommon.h +++ b/src/platformsupport/input/xkbcommon/qxkbcommon_3rdparty.cpp @@ -1,9 +1,9 @@ /**************************************************************************** ** -** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage @@ -37,10 +37,7 @@ ** ****************************************************************************/ -/* XConvertCase was copied from src/3rdparty/xkbcommon/src/keysym.c, - which contains the following license information: - - Copyright 1985, 1987, 1990, 1998 The Open Group +/* Copyright 1985, 1987, 1990, 1998 The Open Group Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -89,6 +86,7 @@ */ /* + XConvertCase was copied from src/3rdparty/xkbcommon/src/keysym.c The following code modifications were applied: XConvertCase() was renamed to xkbcommon_XConvertCase(), to not confuse it @@ -99,10 +97,9 @@ results instead of using the less complete version from keysym.c */ -#include -#include +#include "qxkbcommon_p.h" -QT_BEGIN_NAMESPACE +#include static void qt_UCSConvertCase(uint32_t code, xkb_keysym_t *lower, xkb_keysym_t *upper) { @@ -110,7 +107,7 @@ static void qt_UCSConvertCase(uint32_t code, xkb_keysym_t *lower, xkb_keysym_t * *upper = QChar::toUpper(code); } -void xkbcommon_XConvertCase(xkb_keysym_t sym, xkb_keysym_t *lower, xkb_keysym_t *upper) +void QXkbCommon::xkbcommon_XConvertCase(xkb_keysym_t sym, xkb_keysym_t *lower, xkb_keysym_t *upper) { /* Latin 1 keysym */ if (sym < 0x100) { @@ -220,14 +217,3 @@ void xkbcommon_XConvertCase(xkb_keysym_t sym, xkb_keysym_t *lower, xkb_keysym_t break; } } - -xkb_keysym_t xkbcommon_xkb_keysym_to_upper(xkb_keysym_t ks) -{ - xkb_keysym_t lower, upper; - - xkbcommon_XConvertCase(ks, &lower, &upper); - - return upper; -} - -QT_END_NAMESPACE diff --git a/src/platformsupport/input/xkbcommon/qxkbcommon_p.h b/src/platformsupport/input/xkbcommon/qxkbcommon_p.h new file mode 100644 index 0000000000..475c51ad91 --- /dev/null +++ b/src/platformsupport/input/xkbcommon/qxkbcommon_p.h @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QXKBCOMMON_P_H +#define QXKBCOMMON_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include +#include +#include + +#include + +#include + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(lcXkbcommon) + +class QKeyEvent; + +class QXkbCommon +{ +public: + static QString lookupString(struct xkb_state *state, xkb_keycode_t code); + static QString lookupStringNoKeysymTransformations(xkb_keysym_t keysym); + + static QVector toKeysym(QKeyEvent *event); + + static int keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers modifiers); + static int keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers modifiers, + xkb_state *state, xkb_keycode_t code, + bool superAsMeta = false, bool hyperAsMeta = false); + + // xkbcommon_* API is part of libxkbcommon internals, with modifications as + // desribed in the header of the implementation file. + static void xkbcommon_XConvertCase(xkb_keysym_t sym, xkb_keysym_t *lower, xkb_keysym_t *upper); + static xkb_keysym_t qxkbcommon_xkb_keysym_to_upper(xkb_keysym_t ks); + + static Qt::KeyboardModifiers modifiers(struct xkb_state *state); + + static QList possibleKeys(xkb_state *state, const QKeyEvent *event, + bool superAsMeta = false, bool hyperAsMeta = false); + + static void verifyHasLatinLayout(xkb_keymap *keymap); + static xkb_keysym_t lookupLatinKeysym(xkb_state *state, xkb_keycode_t keycode); + + static bool isLatin(xkb_keysym_t sym) { + return ((sym >= 'a' && sym <= 'z') || (sym >= 'A' && sym <= 'Z')); + } + static bool isKeypad(xkb_keysym_t sym) { + return sym >= XKB_KEY_KP_Space && sym <= XKB_KEY_KP_9; + } + + struct XKBStateDeleter { + void operator()(struct xkb_state *state) const { return xkb_state_unref(state); } + }; + struct XKBKeymapDeleter { + void operator()(struct xkb_keymap *keymap) const { return xkb_keymap_unref(keymap); } + }; + struct XKBContextDeleter { + void operator()(struct xkb_context *context) const { return xkb_context_unref(context); } + }; + using ScopedXKBState = std::unique_ptr; + using ScopedXKBKeymap = std::unique_ptr; + using ScopedXKBContext = std::unique_ptr; +}; + +QT_END_NAMESPACE + +#endif // QXKBCOMMON_P_H diff --git a/src/platformsupport/input/xkbcommon/xkbcommon.pro b/src/platformsupport/input/xkbcommon/xkbcommon.pro new file mode 100644 index 0000000000..2f5d132b5c --- /dev/null +++ b/src/platformsupport/input/xkbcommon/xkbcommon.pro @@ -0,0 +1,23 @@ +TARGET = QtXkbCommonSupport +MODULE = xkbcommon_support + +QT = core-private gui-private +CONFIG += static internal_module + +DEFINES += QT_NO_CAST_FROM_ASCII +PRECOMPILED_HEADER = ../../../corelib/global/qt_pch.h + +QMAKE_USE_PRIVATE += xkbcommon + +HEADERS += \ + qxkbcommon_p.h + +SOURCES += \ + qxkbcommon.cpp \ + qxkbcommon_3rdparty.cpp + +# qxkbcommon.cpp::KeyTbl has more than 256 levels of expansion and older +# Clang uses that as a limit (it's 1024 in current versions). +clang:!intel_icc: QMAKE_CXXFLAGS += -ftemplate-depth=1024 + +load(qt_module) diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index c5dc7b21ad..6eb31d67bd 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -39,7 +39,6 @@ #include "qxcbkeyboard.h" #include "qxcbwindow.h" #include "qxcbscreen.h" -#include "qxcbxkbcommon.h" #include #include @@ -49,404 +48,20 @@ #include #include -#include -#include +#if QT_CONFIG(xkb) +#include +#endif #if QT_CONFIG(xcb_xinput) #include #endif + QT_BEGIN_NAMESPACE -typedef struct xkb2qt -{ - unsigned int xkb; - unsigned int qt; - - constexpr bool operator <=(const xkb2qt &that) const noexcept - { - return xkb <= that.xkb; - } - - constexpr bool operator <(const xkb2qt &that) const noexcept - { - return xkb < that.xkb; - } -} xkb2qt_t; - -template -struct Xkb2Qt -{ - using Type = xkb2qt_t; - static constexpr Type data() noexcept { return Type{Xkb, Qt}; } -}; - -static constexpr const auto KeyTbl = qMakeArray( - QSortedData< - // misc keys - - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt<0x1005FF60, Qt::Key_SysReq>, // hardcoded Sun SysReq - Xkb2Qt<0x1007ff00, Qt::Key_SysReq>, // hardcoded X386 SysReq - - // cursor movement - - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - - // modifiers - - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt<0x1000FF74, Qt::Key_Backtab>, // hardcoded HP backtab - Xkb2Qt<0x1005FF10, Qt::Key_F11>, // hardcoded Sun F36 (labeled F11) - Xkb2Qt<0x1005FF11, Qt::Key_F12>, // hardcoded Sun F37 (labeled F12) - - // numeric and function keypad keys - - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - //Xkb2Qt, - //Xkb2Qt, - //Xkb2Qt, - //Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - - // special non-XF86 function keys - - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - - // International input method support keys - - // International & multi-key character composition - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - - // Misc Functions - Xkb2Qt, - Xkb2Qt, - - // Japanese keyboard support - Xkb2Qt, - Xkb2Qt, - //Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - //Xkb2Qt, - //Xkb2Qt, - //Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - - // Korean keyboard support - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - //Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - //Xkb2Qt, - //Xkb2Qt, - //Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - //Xkb2Qt, - Xkb2Qt, - - // dead keys - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - - // Special keys from X.org - This include multimedia keys, - // wireless/bluetooth/uwb keys, special launcher keys, etc. - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, // ### Qt 6: remap properly - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, // ### Qt 6: remap properly - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt, - Xkb2Qt - >::Data{} -); - -// Possible modifier states. -static const Qt::KeyboardModifiers ModsTbl[] = { - Qt::NoModifier, // 0 - Qt::ShiftModifier, // 1 - Qt::ControlModifier, // 2 - Qt::ControlModifier | Qt::ShiftModifier, // 3 - Qt::AltModifier, // 4 - Qt::AltModifier | Qt::ShiftModifier, // 5 - Qt::AltModifier | Qt::ControlModifier, // 6 - Qt::AltModifier | Qt::ShiftModifier | Qt::ControlModifier, // 7 - Qt::NoModifier // Fall-back to raw Key_*, for non-latin1 kb layouts -}; - Qt::KeyboardModifiers QXcbKeyboard::translateModifiers(int s) const { - Qt::KeyboardModifiers ret = 0; + Qt::KeyboardModifiers ret = Qt::NoModifier; if (s & XCB_MOD_MASK_SHIFT) ret |= Qt::ShiftModifier; if (s & XCB_MOD_MASK_CONTROL) @@ -473,7 +88,7 @@ static xcb_keysym_t getUnshiftedXKey(xcb_keysym_t unshifted, xcb_keysym_t shifte xcb_keysym_t xlower; xcb_keysym_t xupper; - xkbcommon_XConvertCase(unshifted, &xlower, &xupper); + QXkbCommon::xkbcommon_XConvertCase(unshifted, &xlower, &xupper); if (xlower != xupper // Check if symbol is cased && unshifted == xupper) { // Unshifted must be upper case @@ -805,7 +420,12 @@ void QXcbKeyboard::updateKeymap() updateXKBMods(); - checkForLatinLayout(); + QXkbCommon::verifyHasLatinLayout(m_xkbKeymap.get()); +} + +QList QXcbKeyboard::possibleKeys(const QKeyEvent *event) const +{ + return QXkbCommon::possibleKeys(m_xkbState.get(), event, m_superAsMeta, m_hyperAsMeta); } #if QT_CONFIG(xkb) @@ -918,272 +538,6 @@ void QXcbKeyboard::updateXKBMods() xkb_mods.mod5 = xkb_keymap_mod_get_index(m_xkbKeymap.get(), "Mod5"); } -static bool isLatin(xkb_keysym_t sym) -{ - return ((sym >= 'a' && sym <= 'z') || (sym >= 'A' && sym <= 'Z')); -} - -void QXcbKeyboard::checkForLatinLayout() const -{ - const xkb_layout_index_t layoutCount = xkb_keymap_num_layouts(m_xkbKeymap.get()); - const xcb_keycode_t minKeycode = xkb_keymap_min_keycode(m_xkbKeymap.get()); - const xcb_keycode_t maxKeycode = xkb_keymap_max_keycode(m_xkbKeymap.get()); - - const xkb_keysym_t *keysyms = nullptr; - int nrLatinKeys = 0; - for (xkb_layout_index_t layout = 0; layout < layoutCount; ++layout) { - for (xcb_keycode_t code = minKeycode; code < maxKeycode; ++code) { - xkb_keymap_key_get_syms_by_level(m_xkbKeymap.get(), code, layout, 0, &keysyms); - if (keysyms && isLatin(keysyms[0])) - nrLatinKeys++; - if (nrLatinKeys > 10) // arbitrarily chosen threshold - return; - } - } - // This means that lookupLatinKeysym() will not find anything and latin - // key shortcuts might not work. This is a bug in the affected desktop - // environment. Usually can be solved via system settings by adding e.g. 'us' - // layout to the list of seleced layouts, or by using command line, "setxkbmap - // -layout rus,en". The position of latin key based layout in the list of the - // selected layouts is irrelevant. Properly functioning desktop environments - // handle this behind the scenes, even if no latin key based layout has been - // explicitly listed in the selected layouts. - qCWarning(lcQpaKeyboard, "no keyboard layouts with latin keys present"); -} - -xkb_keysym_t QXcbKeyboard::lookupLatinKeysym(xkb_keycode_t keycode) const -{ - xkb_layout_index_t layout; - xkb_keysym_t sym = XKB_KEY_NoSymbol; - const xkb_layout_index_t layoutCount = xkb_keymap_num_layouts_for_key(m_xkbKeymap.get(), keycode); - const xkb_layout_index_t currentLayout = xkb_state_key_get_layout(m_xkbState.get(), keycode); - // Look at user layouts in the order in which they are defined in system - // settings to find a latin keysym. - for (layout = 0; layout < layoutCount; ++layout) { - if (layout == currentLayout) - continue; - const xkb_keysym_t *syms; - xkb_level_index_t level = xkb_state_key_get_level(m_xkbState.get(), keycode, layout); - if (xkb_keymap_key_get_syms_by_level(m_xkbKeymap.get(), keycode, layout, level, &syms) != 1) - continue; - if (isLatin(syms[0])) { - sym = syms[0]; - break; - } - } - - if (sym == XKB_KEY_NoSymbol) - return sym; - - xkb_mod_mask_t latchedMods = xkb_state_serialize_mods(m_xkbState.get(), XKB_STATE_MODS_LATCHED); - xkb_mod_mask_t lockedMods = xkb_state_serialize_mods(m_xkbState.get(), XKB_STATE_MODS_LOCKED); - - // Check for uniqueness, consider the following setup: - // setxkbmap -layout us,ru,us -variant dvorak,, -option 'grp:ctrl_alt_toggle' (set 'ru' as active). - // In this setup, the user would expect to trigger a ctrl+q shortcut by pressing ctrl+, - // because "US dvorak" is higher up in the layout settings list. This check verifies that an obtained - // 'sym' can not be acquired by any other layout higher up in the user's layout list. If it can be acquired - // then the obtained key is not unique. This prevents ctrl+ from generating a ctrl+q - // shortcut in the above described setup. We don't want ctrl+ and ctrl+ to - // generate the same shortcut event in this case. - const xcb_keycode_t minKeycode = xkb_keymap_min_keycode(m_xkbKeymap.get()); - const xcb_keycode_t maxKeycode = xkb_keymap_max_keycode(m_xkbKeymap.get()); - ScopedXKBState state(xkb_state_new(m_xkbKeymap.get())); - for (xkb_layout_index_t prevLayout = 0; prevLayout < layout; ++prevLayout) { - xkb_state_update_mask(state.get(), 0, latchedMods, lockedMods, 0, 0, prevLayout); - for (xcb_keycode_t code = minKeycode; code < maxKeycode; ++code) { - xkb_keysym_t prevSym = xkb_state_key_get_one_sym(state.get(), code); - if (prevSym == sym) { - sym = XKB_KEY_NoSymbol; - break; - } - } - } - - return sym; -} - -static const char *qtKeyName(int qtKey) -{ - int keyEnumIndex = qt_getQtMetaObject()->indexOfEnumerator("Key"); - QMetaEnum keyEnum = qt_getQtMetaObject()->enumerator(keyEnumIndex); - return keyEnum.valueToKey(qtKey); -} - -QList QXcbKeyboard::possibleKeys(const QKeyEvent *event) const -{ - // turn off the modifier bits which doesn't participate in shortcuts - Qt::KeyboardModifiers notNeeded = Qt::KeypadModifier | Qt::GroupSwitchModifier; - Qt::KeyboardModifiers modifiers = event->modifiers() &= ~notNeeded; - // create a fresh kb state and test against the relevant modifier combinations - struct xkb_state *kb_state = xkb_state_new(m_xkbKeymap.get()); - if (!kb_state) { - qWarning("QXcbKeyboard: failed to compile xkb keymap!"); - return QList(); - } - // get kb state from the master xkb_state and update the temporary kb_state - xkb_layout_index_t lockedLayout = xkb_state_serialize_layout(m_xkbState.get(), XKB_STATE_LAYOUT_LOCKED); - xkb_mod_mask_t latchedMods = xkb_state_serialize_mods(m_xkbState.get(), XKB_STATE_MODS_LATCHED); - xkb_mod_mask_t lockedMods = xkb_state_serialize_mods(m_xkbState.get(), XKB_STATE_MODS_LOCKED); - xkb_mod_mask_t depressedMods = xkb_state_serialize_mods(m_xkbState.get(), XKB_STATE_MODS_DEPRESSED); - - xkb_state_update_mask(kb_state, depressedMods, latchedMods, lockedMods, 0, 0, lockedLayout); - quint32 keycode = event->nativeScanCode(); - // handle shortcuts for level three and above - xkb_layout_index_t layoutIndex = xkb_state_key_get_layout(kb_state, keycode); - xkb_level_index_t levelIndex = 0; - if (layoutIndex != XKB_LAYOUT_INVALID) { - levelIndex = xkb_state_key_get_level(kb_state, keycode, layoutIndex); - if (levelIndex == XKB_LEVEL_INVALID) - levelIndex = 0; - } - if (levelIndex <= 1) - xkb_state_update_mask(kb_state, 0, latchedMods, lockedMods, 0, 0, lockedLayout); - - xkb_keysym_t sym = xkb_state_key_get_one_sym(kb_state, keycode); - if (sym == XKB_KEY_NoSymbol) { - xkb_state_unref(kb_state); - return QList(); - } - - QList result; - int baseQtKey = keysymToQtKey(sym, modifiers, kb_state, keycode); - if (baseQtKey) - result += (baseQtKey + modifiers); - - xkb_mod_index_t shiftMod = xkb_keymap_mod_get_index(m_xkbKeymap.get(), "Shift"); - xkb_mod_index_t altMod = xkb_keymap_mod_get_index(m_xkbKeymap.get(), "Alt"); - xkb_mod_index_t controlMod = xkb_keymap_mod_get_index(m_xkbKeymap.get(), "Control"); - xkb_mod_index_t metaMod = xkb_keymap_mod_get_index(m_xkbKeymap.get(), "Meta"); - - Q_ASSERT(shiftMod < 32); - Q_ASSERT(altMod < 32); - Q_ASSERT(controlMod < 32); - - xkb_mod_mask_t depressed; - int qtKey = 0; - // obtain a list of possible shortcuts for the given key event - for (uint i = 1; i < sizeof(ModsTbl) / sizeof(*ModsTbl) ; ++i) { - Qt::KeyboardModifiers neededMods = ModsTbl[i]; - if ((modifiers & neededMods) == neededMods) { - if (i == 8) { - if (isLatin(baseQtKey)) - continue; - // add a latin key as a fall back key - sym = lookupLatinKeysym(keycode); - } else { - depressed = 0; - if (neededMods & Qt::AltModifier) - depressed |= (1 << altMod); - if (neededMods & Qt::ShiftModifier) - depressed |= (1 << shiftMod); - if (neededMods & Qt::ControlModifier) - depressed |= (1 << controlMod); - if (metaMod < 32 && neededMods & Qt::MetaModifier) - depressed |= (1 << metaMod); - xkb_state_update_mask(kb_state, depressed, latchedMods, lockedMods, 0, 0, lockedLayout); - sym = xkb_state_key_get_one_sym(kb_state, keycode); - } - if (sym == XKB_KEY_NoSymbol) - continue; - - Qt::KeyboardModifiers mods = modifiers & ~neededMods; - qtKey = keysymToQtKey(sym, mods, kb_state, keycode); - if (!qtKey || qtKey == baseQtKey) - continue; - - // catch only more specific shortcuts, i.e. Ctrl+Shift+= also generates Ctrl++ and +, - // but Ctrl++ is more specific than +, so we should skip the last one - bool ambiguous = false; - for (int shortcut : qAsConst(result)) { - if (int(shortcut & ~Qt::KeyboardModifierMask) == qtKey && (shortcut & mods) == mods) { - ambiguous = true; - break; - } - } - if (ambiguous) - continue; - - result += (qtKey + mods); - } - } - xkb_state_unref(kb_state); - return result; -} - -int QXcbKeyboard::keysymToQtKey(xcb_keysym_t keysym, Qt::KeyboardModifiers modifiers, - struct xkb_state *state, xcb_keycode_t code) const -{ - int qtKey = 0; - - // lookup from direct mapping - if (keysym >= XKB_KEY_F1 && keysym <= XKB_KEY_F35) { - // function keys - qtKey = Qt::Key_F1 + (keysym - XKB_KEY_F1); - } else if (keysym >= XKB_KEY_KP_0 && keysym <= XKB_KEY_KP_9) { - // numeric keypad keys - qtKey = Qt::Key_0 + (keysym - XKB_KEY_KP_0); - } else if (isLatin(keysym)) { - qtKey = xkbcommon_xkb_keysym_to_upper(keysym); - } else { - // check if we have a direct mapping - xkb2qt_t searchKey{keysym, 0}; - auto it = std::lower_bound(KeyTbl.cbegin(), KeyTbl.cend(), searchKey); - if (it != KeyTbl.end() && !(searchKey < *it)) - qtKey = it->qt; - } - - QString text; - bool fromUnicode = qtKey == 0; - if (fromUnicode) { // lookup from unicode - if (modifiers & Qt::ControlModifier) { - // Control modifier changes the text to ASCII control character, therefore we - // can't use this text to map keysym to a qt key. We can use the same keysym - // (it is not affectd by transformation) to obtain untransformed text. For details - // see "Appendix A. Default Symbol Transformations" in the XKB specification. - text = lookupStringNoKeysymTransformations(keysym); - } else { - text = lookupString(state, code); - } - if (!text.isEmpty()) { - if (text.unicode()->isDigit()) { - // Ensures that also non-latin digits are mapped to corresponding qt keys, - // e.g CTRL + ۲ (arabic two), is mapped to CTRL + Qt::Key_2. - qtKey = Qt::Key_0 + text.unicode()->digitValue(); - } else { - qtKey = text.unicode()->toUpper().unicode(); - } - } - } - - if (rmod_masks.meta) { - // translate Super/Hyper keys to Meta if we're using them as the MetaModifier - if (rmod_masks.meta == rmod_masks.super && (qtKey == Qt::Key_Super_L - || qtKey == Qt::Key_Super_R)) { - qtKey = Qt::Key_Meta; - } else if (rmod_masks.meta == rmod_masks.hyper && (qtKey == Qt::Key_Hyper_L - || qtKey == Qt::Key_Hyper_R)) { - qtKey = Qt::Key_Meta; - } - } - - if (Q_UNLIKELY(lcQpaKeyboard().isDebugEnabled())) { - char keysymName[64]; - xkb_keysym_get_name(keysym, keysymName, sizeof(keysymName)); - QString keysymInHex = QString(QStringLiteral("0x%1")).arg(keysym, 0, 16); - if (qtKeyName(qtKey)) { - qCDebug(lcQpaKeyboard).nospace() << "keysym: " << keysymName << "(" - << keysymInHex << ") mapped to Qt::" << qtKeyName(qtKey) << " | text: " << text - << " | qt key: " << qtKey << " mapped from unicode number: " << fromUnicode; - } else { - qCDebug(lcQpaKeyboard).nospace() << "no Qt::Key for keysym: " << keysymName - << "(" << keysymInHex << ") | text: " << text << " | qt key: " << qtKey; - } - } - - return qtKey; -} - QXcbKeyboard::QXcbKeyboard(QXcbConnection *connection) : QXcbObject(connection) { @@ -1514,6 +868,12 @@ void QXcbKeyboard::resolveMaskConflicts() rmod_masks.meta = rmod_masks.hyper; } } + + // translate Super/Hyper keys to Meta if we're using them as the MetaModifier + if (rmod_masks.meta && rmod_masks.meta == rmod_masks.super) + m_superAsMeta = true; + if (rmod_masks.meta && rmod_masks.meta == rmod_masks.hyper) + m_hyperAsMeta = true; } void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, xcb_keycode_t code, @@ -1529,7 +889,7 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, if (type == QEvent::KeyPress) targetWindow->updateNetWmUserTime(time); - ScopedXKBState sendEventState; + QXkbCommon::ScopedXKBState sendEventState; if (fromSendEvent) { // Have a temporary keyboard state filled in from state // this way we allow for synthetic events to have different state @@ -1546,30 +906,13 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, struct xkb_state *xkbState = fromSendEvent ? sendEventState.get() : m_xkbState.get(); xcb_keysym_t sym = xkb_state_key_get_one_sym(xkbState, code); - QString text = lookupString(xkbState, code); + QString text = QXkbCommon::lookupString(xkbState, code); Qt::KeyboardModifiers modifiers = translateModifiers(state); - if (sym >= XKB_KEY_KP_Space && sym <= XKB_KEY_KP_9) + if (QXkbCommon::isKeypad(sym)) modifiers |= Qt::KeypadModifier; - // Note 1: All standard key sequences on linux (as defined in platform theme) - // that use a latin character also contain a control modifier, which is why - // checking for Qt::ControlModifier is sufficient here. It is possible to - // override QPlatformTheme::keyBindings() and provide custom sequences for - // QKeySequence::StandardKey. Custom sequences probably should respect this - // convention (alternatively, we could test against other modifiers here). - // Note 2: The possibleKeys() shorcut mechanism is not affected by this value - // adjustment and does its own thing. - xcb_keysym_t latinKeysym = XKB_KEY_NoSymbol; - if (modifiers & Qt::ControlModifier) { - // With standard shortcuts we should prefer a latin character, this is - // in checks like "event == QKeySequence::Copy". - if (!isLatin(sym)) - latinKeysym = lookupLatinKeysym(code); - } - - int qtcode = keysymToQtKey(latinKeysym != XKB_KEY_NoSymbol ? latinKeysym : sym, - modifiers, xkbState, code); + int qtcode = QXkbCommon::keysymToQtKey(sym, modifiers, xkbState, code, m_superAsMeta, m_hyperAsMeta); if (type == QEvent::KeyPress) { if (m_isAutoRepeat && m_autoRepeatCode != code) @@ -1611,28 +954,6 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, } } -QString QXcbKeyboard::lookupString(struct xkb_state *state, xcb_keycode_t code) const -{ - QVarLengthArray chars(32); - const int size = xkb_state_key_get_utf8(state, code, chars.data(), chars.size()); - if (Q_UNLIKELY(size + 1 > chars.size())) { // +1 for NUL - chars.resize(size + 1); - xkb_state_key_get_utf8(state, code, chars.data(), chars.size()); - } - return QString::fromUtf8(chars.constData(), size); -} - -QString QXcbKeyboard::lookupStringNoKeysymTransformations(xkb_keysym_t keysym) const -{ - QVarLengthArray chars(32); - const int size = xkb_keysym_to_utf8(keysym, chars.data(), chars.size()); - if (Q_UNLIKELY(size > chars.size())) { - chars.resize(size); - xkb_keysym_to_utf8(keysym, chars.data(), chars.size()); - } - return QString::fromUtf8(chars.constData(), size); -} - static bool fromSendEvent(const void *event) { // From X11 protocol: Every event contains an 8-bit type code. The most diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h index f8490592b7..75071d045f 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.h +++ b/src/plugins/platforms/xcb/qxcbkeyboard.h @@ -50,16 +50,12 @@ #endif #include -#if QT_CONFIG(xkb) -#include -#endif +#include #include QT_BEGIN_NAMESPACE -class QWindow; - class QXcbKeyboard : public QXcbObject { public: @@ -75,7 +71,7 @@ public: Qt::KeyboardModifiers translateModifiers(int s) const; void updateKeymap(xcb_mapping_notify_event_t *event); void updateKeymap(); - QList possibleKeys(const QKeyEvent *e) const; + QList possibleKeys(const QKeyEvent *event) const; // when XKEYBOARD not present on the X server void updateXKBMods(); @@ -96,10 +92,6 @@ protected: quint16 state, xcb_timestamp_t time, bool fromSendEvent); void resolveMaskConflicts(); - QString lookupString(struct xkb_state *state, xcb_keycode_t code) const; - QString lookupStringNoKeysymTransformations(xkb_keysym_t keysym) const; - int keysymToQtKey(xcb_keysym_t keysym, Qt::KeyboardModifiers modifiers, - struct xkb_state *state, xcb_keycode_t code) const; typedef QMap KeysymModifierMap; struct xkb_keymap *keymapFromCore(const KeysymModifierMap &keysymMods); @@ -111,9 +103,6 @@ protected: void updateVModMapping(); void updateVModToRModMapping(); - xkb_keysym_t lookupLatinKeysym(xkb_keycode_t keycode) const; - void checkForLatinLayout() const; - private: bool m_config = false; bool m_isAutoRepeat = false; @@ -148,22 +137,12 @@ private: int core_device_id; #endif - struct XKBStateDeleter { - void operator()(struct xkb_state *state) const { return xkb_state_unref(state); } - }; - struct XKBKeymapDeleter { - void operator()(struct xkb_keymap *keymap) const { return xkb_keymap_unref(keymap); } - }; - struct XKBContextDeleter { - void operator()(struct xkb_context *context) const { return xkb_context_unref(context); } - }; - using ScopedXKBState = std::unique_ptr; - using ScopedXKBKeymap = std::unique_ptr; - using ScopedXKBContext = std::unique_ptr; + QXkbCommon::ScopedXKBState m_xkbState; + QXkbCommon::ScopedXKBKeymap m_xkbKeymap; + QXkbCommon::ScopedXKBContext m_xkbContext; - ScopedXKBState m_xkbState; - ScopedXKBKeymap m_xkbKeymap; - ScopedXKBContext m_xkbContext; + bool m_superAsMeta = false; + bool m_hyperAsMeta = false; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro index db3d6629b3..34c671c8c7 100644 --- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro +++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro @@ -6,7 +6,8 @@ QT += \ core-private gui-private \ service_support-private theme_support-private \ fontdatabase_support-private \ - edid_support-private + edid_support-private \ + xkbcommon_support-private qtHaveModule(linuxaccessibility_support-private): \ QT += linuxaccessibility_support-private @@ -52,7 +53,6 @@ HEADERS = \ qxcbimage.h \ qxcbxsettings.h \ qxcbsystemtraytracker.h \ - qxcbxkbcommon.h \ qxcbeventqueue.h \ qxcbeventdispatcher.h \ qxcbconnection_basic.h \ diff --git a/sync.profile b/sync.profile index a6d0e2a4a7..e6fc285573 100644 --- a/sync.profile +++ b/sync.profile @@ -18,6 +18,7 @@ "QtEventDispatcherSupport" => "$basedir/src/platformsupport/eventdispatchers", "QtFontDatabaseSupport" => "$basedir/src/platformsupport/fontdatabases", "QtInputSupport" => "$basedir/src/platformsupport/input", + "QtXkbCommonSupport" => "$basedir/src/platformsupport/input/xkbcommon", "QtPlatformCompositorSupport" => "$basedir/src/platformsupport/platformcompositor", "QtServiceSupport" => "$basedir/src/platformsupport/services", "QtThemeSupport" => "$basedir/src/platformsupport/themes", From 2065bc070dcd1f88a1f5ba3dd6ef0139a9a441ec Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Fri, 24 Oct 2014 16:31:48 +0200 Subject: [PATCH 1296/1650] platforminputcontexts: use libxkbcommon compose key API Our implementation of compose table parser was added on Mar, 2013. libxkbcommon added APIs for the same thing in Oct, 2014 (ver: 0.5.0). After removing RHEL 6.6 from the list of supported platforms we were able to move the minimal required libxkbcommon version to 0.5.0. Now we can use the xkbcommon-compose APIs on all supported platforms. With this patch we can drop nearly 1000 lines of maintenance burden. This patch fixes user reported issues with our implementation. Known issues: - Testing revealed that xkbcommon-compose does not support non-utf8 locales, and that is by design - https://github.com/xkbcommon/libxkbcommon/issues/76 Our implementation did work for those locales too, but it is unclear if anyone actually uses non-utf8 locales. It is a corner case (work-arounds existing) and likely a configuration error on the users' system. - Looking at the release notes for versions above 0.6.1, only one issue that stands out. Compose input does not work on system with tr_TR.UTF-8 locale, fixed in 0.7.1. Compose input works fine when using e.g. en_US.UTF-8 locale with Turkish keyboard layout. Note: With Qt 5.13 we have removed Ubuntu 16.04 and openSUSE 42.3 from CI: Ubuntu 16.04 - 0.5.0 openSUSE 42.3 - 0.6.1 CI for Qt 5.13 has: Ubuntu 18.04 - 0.8.0 RHEL-7.4 - 0.7.1 openSUSE 15.0 - 0.8.1 Currently the minimal required libxkbcommon version in src/gui/configure.json is set to 0.5.0, but we could bump it to 0.7.1 to avoid known issues from above, but that is a decision for a separate patch. [ChangeLog][plugins][platforminputcontexts] Now using libxkbcommon-compose APIs for compose key input, instead of Qt's own implementation. Fixes: QTBUG-42181 Fixes: QTBUG-53663 Fixes: QTBUG-48657 Change-Id: I79aafe2bc601293844066e7e5f5eddd3719c6bba Reviewed-by: Giulio Camuffo Reviewed-by: Johan Helsing --- .../input/xkbcommon/qxkbcommon.cpp | 31 + .../input/xkbcommon/qxkbcommon_p.h | 4 + .../platforminputcontexts/compose/compose.pro | 8 +- .../compose/generator/qtablegenerator.cpp | 658 ------------------ .../compose/generator/qtablegenerator.h | 145 ---- .../compose/qcomposeplatforminputcontext.cpp | 297 ++------ .../compose/qcomposeplatforminputcontext.h | 33 +- .../qcomposeplatforminputcontextmain.cpp | 4 +- src/plugins/platforms/xcb/qxcbintegration.cpp | 2 + src/plugins/platforms/xcb/qxcbkeyboard.cpp | 6 + src/plugins/platforms/xcb/qxcbkeyboard.h | 1 + tests/auto/other/other.pro | 5 + .../other/xkbkeyboard/tst_xkbkeyboard.cpp | 60 ++ tests/auto/other/xkbkeyboard/xkbkeyboard.pro | 7 + 14 files changed, 210 insertions(+), 1051 deletions(-) delete mode 100644 src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp delete mode 100644 src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h create mode 100644 tests/auto/other/xkbkeyboard/tst_xkbkeyboard.cpp create mode 100644 tests/auto/other/xkbkeyboard/xkbkeyboard.pro diff --git a/src/platformsupport/input/xkbcommon/qxkbcommon.cpp b/src/platformsupport/input/xkbcommon/qxkbcommon.cpp index 4bee868fa9..877c5d848f 100644 --- a/src/platformsupport/input/xkbcommon/qxkbcommon.cpp +++ b/src/platformsupport/input/xkbcommon/qxkbcommon.cpp @@ -41,7 +41,12 @@ #include +#include #include +#include + +#include +#include QT_BEGIN_NAMESPACE @@ -794,4 +799,30 @@ xkb_keysym_t QXkbCommon::lookupLatinKeysym(xkb_state *state, xkb_keycode_t keyco return sym; } +void QXkbCommon::setXkbContext(QPlatformInputContext *inputContext, struct xkb_context *context) +{ + if (!inputContext || !context) + return; + + const char *const inputContextClassName = "QComposeInputContext"; + const char *const normalizedSignature = "setXkbContext(xkb_context*)"; + + if (inputContext->objectName() != QLatin1String(inputContextClassName)) + return; + + static const QMetaMethod setXkbContext = [&]() { + int methodIndex = inputContext->metaObject()->indexOfMethod(normalizedSignature); + QMetaMethod method = inputContext->metaObject()->method(methodIndex); + Q_ASSERT(method.isValid()); + if (!method.isValid()) + qCWarning(lcXkbcommon) << normalizedSignature << "not found on" << inputContextClassName; + return method; + }(); + + if (!setXkbContext.isValid()) + return; + + setXkbContext.invoke(inputContext, Qt::DirectConnection, Q_ARG(struct xkb_context*, context)); +} + QT_END_NAMESPACE diff --git a/src/platformsupport/input/xkbcommon/qxkbcommon_p.h b/src/platformsupport/input/xkbcommon/qxkbcommon_p.h index 475c51ad91..561eae03db 100644 --- a/src/platformsupport/input/xkbcommon/qxkbcommon_p.h +++ b/src/platformsupport/input/xkbcommon/qxkbcommon_p.h @@ -64,7 +64,9 @@ QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(lcXkbcommon) +class QEvent; class QKeyEvent; +class QPlatformInputContext; class QXkbCommon { @@ -99,6 +101,8 @@ public: return sym >= XKB_KEY_KP_Space && sym <= XKB_KEY_KP_9; } + static void setXkbContext(QPlatformInputContext *inputContext, struct xkb_context *context); + struct XKBStateDeleter { void operator()(struct xkb_state *state) const { return xkb_state_unref(state); } }; diff --git a/src/plugins/platforminputcontexts/compose/compose.pro b/src/plugins/platforminputcontexts/compose/compose.pro index 68bc2c3466..2e2f8600c3 100644 --- a/src/plugins/platforminputcontexts/compose/compose.pro +++ b/src/plugins/platforminputcontexts/compose/compose.pro @@ -3,18 +3,14 @@ TARGET = composeplatforminputcontextplugin QT += core-private gui-private SOURCES += $$PWD/qcomposeplatforminputcontextmain.cpp \ - $$PWD/qcomposeplatforminputcontext.cpp \ - $$PWD/generator/qtablegenerator.cpp \ + $$PWD/qcomposeplatforminputcontext.cpp -HEADERS += $$PWD/qcomposeplatforminputcontext.h \ - $$PWD/generator/qtablegenerator.h \ +HEADERS += $$PWD/qcomposeplatforminputcontext.h QMAKE_USE_PRIVATE += xkbcommon include($$OUT_PWD/../../../gui/qtgui-config.pri) -DEFINES += X11_PREFIX='\\"$$QMAKE_X11_PREFIX\\"' - OTHER_FILES += $$PWD/compose.json PLUGIN_TYPE = platforminputcontexts diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp deleted file mode 100644 index b5a0a5bbeb..0000000000 --- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp +++ /dev/null @@ -1,658 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qtablegenerator.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include // LC_CTYPE -#include // strchr, strncmp, etc. -#include // strncasecmp -#include // LC_CTYPE - -static const quint32 SupportedCacheVersion = 1; - -/* - In short on how and why the "Compose" file is cached: - - The "Compose" file is large, for en_US it's likely located at: - /usr/share/X11/locale/en_US.UTF-8/Compose - and it has about 6000 string lines. - Q(Gui)Applications parse this file each time they're created. On modern CPUs - it incurs a 4-10 ms startup penalty of each Qt gui app, on older CPUs - - tens of ms or more. - Since the "Compose" file (almost) never changes using a pre-parsed - cache file instead of the "Compose" file is a good idea to improve Qt5 - application startup time by about 5+ ms (or tens of ms on older CPUs). - - The cache file contains the contents of the QComposeCacheFileHeader struct at the - beginning followed by the pre-parsed contents of the "Compose" file. - - struct QComposeCacheFileHeader stores - (a) The cache version - in the unlikely event that some day one might need - to break compatibility. - (b) The (cache) file size. - (c) The lastModified field tracks if anything changed since the last time - the cache file was saved. - If anything did change then we read the compose file and save (cache) it - in binary/pre-parsed format, which should happen extremely rarely if at all. -*/ - -struct QComposeCacheFileHeader -{ - quint32 cacheVersion; - // The compiler will add 4 padding bytes anyway. - // Reserve them explicitly to possibly use in the future. - quint32 reserved; - quint64 fileSize; - qint64 lastModified; -}; - -// localHostName() copied from qtbase/src/corelib/io/qlockfile_unix.cpp -static QByteArray localHostName() -{ - QByteArray hostName(512, Qt::Uninitialized); - if (gethostname(hostName.data(), hostName.size()) == -1) - return QByteArray(); - hostName.truncate(strlen(hostName.data())); - return hostName; -} - -/* - Reads metadata about the Compose file. Later used to determine if the - compose cache should be updated. The fileSize field will be zero on failure. -*/ -static QComposeCacheFileHeader readFileMetadata(const QString &path) -{ - quint64 fileSize = 0; - qint64 lastModified = 0; - const QByteArray pathBytes = QFile::encodeName(path); - QT_STATBUF st; - if (QT_STAT(pathBytes.data(), &st) == 0) { - lastModified = st.st_mtime; - fileSize = st.st_size; - } - QComposeCacheFileHeader info = { 0, 0, fileSize, lastModified }; - return info; -} - -static const QString getCacheFilePath() -{ - QFile machineIdFile("/var/lib/dbus/machine-id"); - QString machineId; - if (machineIdFile.exists()) { - if (machineIdFile.open(QIODevice::ReadOnly)) - machineId = QString::fromLatin1(machineIdFile.readAll().trimmed()); - } - if (machineId.isEmpty()) - machineId = localHostName(); - const QString dirPath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation); - - if (QSysInfo::ByteOrder == QSysInfo::BigEndian) - return dirPath + QLatin1String("/qt_compose_cache_big_endian_") + machineId; - return dirPath + QLatin1String("/qt_compose_cache_little_endian_") + machineId; -} - -// Returns empty vector on failure -static QVector loadCache(const QComposeCacheFileHeader &composeInfo) -{ - QVector vec; - const QString cacheFilePath = getCacheFilePath(); - QFile inputFile(cacheFilePath); - - if (!inputFile.open(QIODevice::ReadOnly)) - return vec; - QComposeCacheFileHeader cacheInfo; - // use a "buffer" variable to make the line after this one more readable. - char *buffer = reinterpret_cast(&cacheInfo); - - if (inputFile.read(buffer, sizeof cacheInfo) != sizeof cacheInfo) - return vec; - if (cacheInfo.fileSize == 0) - return vec; - // using "!=" just in case someone replaced with a backup that existed before - if (cacheInfo.lastModified != composeInfo.lastModified) - return vec; - if (cacheInfo.cacheVersion != SupportedCacheVersion) - return vec; - const QByteArray pathBytes = QFile::encodeName(cacheFilePath); - QT_STATBUF st; - if (QT_STAT(pathBytes.data(), &st) != 0) - return vec; - const off_t fileSize = st.st_size; - if (fileSize > 1024 * 1024 * 5) { - // The cache file size is usually about 150KB, so if its size is over - // say 5MB then somebody inflated the file, abort. - return vec; - } - const off_t bufferSize = fileSize - (sizeof cacheInfo); - const size_t elemSize = sizeof (struct QComposeTableElement); - const int elemCount = bufferSize / elemSize; - const QByteArray ba = inputFile.read(bufferSize); - const char *data = ba.data(); - // Since we know the number of the (many) elements and their size in - // advance calling vector.reserve(..) seems reasonable. - vec.reserve(elemCount); - - for (int i = 0; i < elemCount; i++) { - const QComposeTableElement *elem = - reinterpret_cast(data + (i * elemSize)); - vec.push_back(*elem); - } - return vec; -} - -// Returns true on success, false otherwise. -static bool saveCache(const QComposeCacheFileHeader &info, const QVector &vec) -{ - const QString filePath = getCacheFilePath(); -#if QT_CONFIG(temporaryfile) - QSaveFile outputFile(filePath); -#else - QFile outputFile(filePath); -#endif - if (!outputFile.open(QIODevice::WriteOnly)) - return false; - const char *data = reinterpret_cast(&info); - - if (outputFile.write(data, sizeof info) != sizeof info) - return false; - data = reinterpret_cast(vec.constData()); - const qint64 size = vec.size() * (sizeof (struct QComposeTableElement)); - - if (outputFile.write(data, size) != size) - return false; -#if QT_CONFIG(temporaryfile) - return outputFile.commit(); -#else - return true; -#endif -} - -TableGenerator::TableGenerator() : m_state(NoErrors), - m_systemComposeDir(QString()) -{ - initPossibleLocations(); - QString composeFilePath = findComposeFile(); -#ifdef DEBUG_GENERATOR -// don't use cache when in debug mode. - if (!composeFilePath.isEmpty()) - qDebug() << "Using Compose file from: " << composeFilePath; -#else - QComposeCacheFileHeader fileInfo = readFileMetadata(composeFilePath); - if (fileInfo.fileSize != 0) - m_composeTable = loadCache(fileInfo); -#endif - if (m_composeTable.isEmpty() && cleanState()) { - if (composeFilePath.isEmpty()) { - m_state = MissingComposeFile; - } else { - QFile composeFile(composeFilePath); - composeFile.open(QIODevice::ReadOnly); - parseComposeFile(&composeFile); - orderComposeTable(); - if (m_composeTable.isEmpty()) { - m_state = EmptyTable; -#ifndef DEBUG_GENERATOR -// don't save cache when in debug mode - } else { - fileInfo.cacheVersion = SupportedCacheVersion; - saveCache(fileInfo, m_composeTable); -#endif - } - } - } -#ifdef DEBUG_GENERATOR - printComposeTable(); -#endif -} - -void TableGenerator::initPossibleLocations() -{ - // Compose files come as a part of Xlib library. Xlib doesn't provide - // a mechanism how to retrieve the location of these files reliably, since it was - // never meant for external software to parse compose tables directly. Best we - // can do is to hardcode search paths. To add an extra system path use - // the QTCOMPOSE environment variable - m_possibleLocations.reserve(7); - if (qEnvironmentVariableIsSet("QTCOMPOSE")) - m_possibleLocations.append(QString::fromLocal8Bit(qgetenv("QTCOMPOSE"))); - m_possibleLocations.append(QStringLiteral("/usr/share/X11/locale")); - m_possibleLocations.append(QStringLiteral("/usr/local/share/X11/locale")); - m_possibleLocations.append(QStringLiteral("/usr/lib/X11/locale")); - m_possibleLocations.append(QStringLiteral("/usr/local/lib/X11/locale")); - m_possibleLocations.append(QStringLiteral(X11_PREFIX "/share/X11/locale")); - m_possibleLocations.append(QStringLiteral(X11_PREFIX "/lib/X11/locale")); -} - -QString TableGenerator::findComposeFile() -{ - // check if XCOMPOSEFILE points to a Compose file - if (qEnvironmentVariableIsSet("XCOMPOSEFILE")) { - const QString path = QFile::decodeName(qgetenv("XCOMPOSEFILE")); - if (QFile::exists(path)) - return path; - else - qWarning("$XCOMPOSEFILE doesn't point to an existing file"); - } - - // check if user’s home directory has a file named .XCompose - if (cleanState()) { - QString path = qgetenv("HOME") + QLatin1String("/.XCompose"); - if (QFile::exists(path)) - return path; - } - - // check for the system provided compose files - if (cleanState()) { - QString table = composeTableForLocale(); - if (cleanState()) { - if (table.isEmpty()) - // no table mappings for the system's locale in the compose.dir - m_state = UnsupportedLocale; - else { - QString path = QDir(systemComposeDir()).filePath(table); - if (QFile::exists(path)) - return path; - } - } - } - return QString(); -} - -QString TableGenerator::composeTableForLocale() -{ - QByteArray loc = locale().toUpper().toUtf8(); - QString table = readLocaleMappings(loc); - if (table.isEmpty()) - table = readLocaleMappings(readLocaleAliases(loc)); - return table; -} - -bool TableGenerator::findSystemComposeDir() -{ - bool found = false; - for (int i = 0; i < m_possibleLocations.size(); ++i) { - QString path = m_possibleLocations.at(i); - if (QFile::exists(path + QLatin1String("/compose.dir"))) { - m_systemComposeDir = path; - found = true; - break; - } - } - - if (!found) { - // should we ask to report this in the qt bug tracker? - m_state = UnknownSystemComposeDir; - qWarning("Qt Warning: Could not find a location of the system's Compose files. " - "Consider setting the QTCOMPOSE environment variable."); - } - - return found; -} - -QString TableGenerator::systemComposeDir() -{ - if (m_systemComposeDir.isNull() - && !findSystemComposeDir()) { - return QLatin1String("$QTCOMPOSE"); - } - - return m_systemComposeDir; -} - -QString TableGenerator::locale() const -{ - char *name = setlocale(LC_CTYPE, (char *)0); - return QLatin1String(name); -} - -QString TableGenerator::readLocaleMappings(const QByteArray &locale) -{ - QString file; - if (locale.isEmpty()) - return file; - - QFile mappings(systemComposeDir() + QLatin1String("/compose.dir")); - if (mappings.open(QIODevice::ReadOnly)) { - const int localeNameLength = locale.size(); - const char * const localeData = locale.constData(); - - char l[1024]; - // formating of compose.dir has some inconsistencies - while (!mappings.atEnd()) { - int read = mappings.readLine(l, sizeof(l)); - if (read <= 0) - break; - - char *line = l; - if (*line >= 'a' && *line <= 'z') { - // file name - while (*line && *line != ':' && *line != ' ' && *line != '\t') - ++line; - if (!*line) - continue; - const char * const composeFileNameEnd = line; - *line = '\0'; - ++line; - - // locale name - while (*line && (*line == ' ' || *line == '\t')) - ++line; - const char * const lc = line; - while (*line && *line != ' ' && *line != '\t' && *line != '\n') - ++line; - *line = '\0'; - if (localeNameLength == (line - lc) && !strncasecmp(lc, localeData, line - lc)) { - file = QString::fromLocal8Bit(l, composeFileNameEnd - l); - break; - } - } - } - mappings.close(); - } - return file; -} - -QByteArray TableGenerator::readLocaleAliases(const QByteArray &locale) -{ - QFile aliases(systemComposeDir() + QLatin1String("/locale.alias")); - QByteArray fullLocaleName; - if (aliases.open(QIODevice::ReadOnly)) { - while (!aliases.atEnd()) { - char l[1024]; - int read = aliases.readLine(l, sizeof(l)); - char *line = l; - if (read && ((*line >= 'a' && *line <= 'z') || - (*line >= 'A' && *line <= 'Z'))) { - const char *alias = line; - while (*line && *line != ':' && *line != ' ' && *line != '\t') - ++line; - if (!*line) - continue; - *line = 0; - if (locale.size() == (line - alias) - && !strncasecmp(alias, locale.constData(), line - alias)) { - // found a match for alias, read the real locale name - ++line; - while (*line && (*line == ' ' || *line == '\t')) - ++line; - const char *fullName = line; - while (*line && *line != ' ' && *line != '\t' && *line != '\n') - ++line; - *line = 0; - fullLocaleName = fullName; -#ifdef DEBUG_GENERATOR - qDebug() << "Alias for: " << alias << "is: " << fullLocaleName; - break; -#endif - } - } - } - aliases.close(); - } - return fullLocaleName; -} - -bool TableGenerator::processFile(const QString &composeFileName) -{ - QFile composeFile(composeFileName); - if (composeFile.open(QIODevice::ReadOnly)) { - parseComposeFile(&composeFile); - return true; - } - qWarning() << QString(QLatin1String("Qt Warning: Compose file: \"%1\" can't be found")) - .arg(composeFile.fileName()); - return false; -} - -TableGenerator::~TableGenerator() -{ -} - -QVector TableGenerator::composeTable() const -{ - return m_composeTable; -} - -void TableGenerator::parseComposeFile(QFile *composeFile) -{ -#ifdef DEBUG_GENERATOR - qDebug() << "TableGenerator::parseComposeFile: " << composeFile->fileName(); -#endif - - char line[1024]; - while (!composeFile->atEnd()) { - composeFile->readLine(line, sizeof(line)); - if (*line == '<') - parseKeySequence(line); - else if (!strncmp(line, "include", 7)) - parseIncludeInstruction(QString::fromLocal8Bit(line)); - } - - composeFile->close(); -} - -void TableGenerator::parseIncludeInstruction(QString line) -{ - // Parse something that looks like: - // include "/usr/share/X11/locale/en_US.UTF-8/Compose" - QString quote = QStringLiteral("\""); - line.remove(0, line.indexOf(quote) + 1); - line.chop(line.length() - line.indexOf(quote)); - - // expand substitutions if present - line.replace(QLatin1String("%H"), QString(qgetenv("HOME"))); - line.replace(QLatin1String("%L"), systemComposeDir() + QLatin1Char('/') + composeTableForLocale()); - line.replace(QLatin1String("%S"), systemComposeDir()); - - processFile(line); -} - -ushort TableGenerator::keysymToUtf8(quint32 sym) -{ - QByteArray chars; - int bytes; - chars.resize(8); - bytes = xkb_keysym_to_utf8(sym, chars.data(), chars.size()); - if (bytes == -1) - qWarning("TableGenerator::keysymToUtf8 - buffer too small"); - - chars.resize(bytes-1); - -#ifdef DEBUG_GENERATOR - QTextCodec *codec = QTextCodec::codecForLocale(); - qDebug() << QString("keysym - 0x%1 : utf8 - %2").arg(QString::number(sym, 16)) - .arg(codec->toUnicode(chars)); -#endif - return QString::fromUtf8(chars).at(0).unicode(); -} - -static inline int fromBase8(const char *s, const char *end) -{ - int result = 0; - while (*s && s != end) { - if (*s < '0' || *s > '7') - return 0; - result *= 8; - result += *s - '0'; - ++s; - } - return result; -} - -static inline int fromBase16(const char *s, const char *end) -{ - int result = 0; - while (*s && s != end) { - result *= 16; - if (*s >= '0' && *s <= '9') - result += *s - '0'; - else if (*s >= 'a' && *s <= 'f') - result += *s - 'a' + 10; - else if (*s >= 'A' && *s <= 'F') - result += *s - 'A' + 10; - else - return 0; - ++s; - } - return result; -} - -void TableGenerator::parseKeySequence(char *line) -{ - // we are interested in the lines with the following format: - // : "♬" U266c # BEAMED SIXTEENTH NOTE - char *keysEnd = strchr(line, ':'); - if (!keysEnd) - return; - - QComposeTableElement elem; - // find the composed value - strings may be direct text encoded in the locale - // for which the compose file is to be used, or an escaped octal or hexadecimal - // character code. Octal codes are specified as "\123" and hexadecimal codes as "\0x123a". - char *composeValue = strchr(keysEnd, '"'); - if (!composeValue) - return; - ++composeValue; - - char *composeValueEnd = strchr(composeValue, '"'); - if (!composeValueEnd) - return; - - // if composed value is a quotation mark adjust the end pointer - if (composeValueEnd[1] == '"') - ++composeValueEnd; - - if (*composeValue == '\\' && composeValue[1] >= '0' && composeValue[1] <= '9') { - // handle octal and hex code values - char detectBase = composeValue[2]; - if (detectBase == 'x') { - // hexadecimal character code - elem.value = keysymToUtf8(fromBase16(composeValue + 3, composeValueEnd)); - } else { - // octal character code - elem.value = keysymToUtf8(fromBase8(composeValue + 1, composeValueEnd)); - } - } else { - // handle direct text encoded in the locale - if (*composeValue == '\\') - ++composeValue; - elem.value = QString::fromLocal8Bit(composeValue, composeValueEnd - composeValue).at(0).unicode(); - ++composeValue; - } - -#ifdef DEBUG_GENERATOR - // find the comment - elem.comment = QString::fromLocal8Bit(composeValueEnd + 1).trimmed(); -#endif - - // find the key sequence and convert to X11 keysym - char *k = line; - const char *kend = keysEnd; - - for (int i = 0; i < QT_KEYSEQUENCE_MAX_LEN; i++) { - // find the next pair of angle brackets and get the contents within - while (k < kend && *k != '<') - ++k; - char *sym = ++k; - while (k < kend && *k != '>') - ++k; - *k = '\0'; - if (k < kend) { - elem.keys[i] = xkb_keysym_from_name(sym, (xkb_keysym_flags)0); - if (elem.keys[i] == XKB_KEY_NoSymbol) { - if (!strcmp(sym, "dead_inverted_breve")) - elem.keys[i] = XKB_KEY_dead_invertedbreve; - else if (!strcmp(sym, "dead_double_grave")) - elem.keys[i] = XKB_KEY_dead_doublegrave; -#ifdef DEBUG_GENERATOR - else - qWarning() << QString("Qt Warning - invalid keysym: %1").arg(sym); -#endif - } - } else { - elem.keys[i] = 0; - } - } - m_composeTable.append(elem); -} - -void TableGenerator::printComposeTable() const -{ -#ifdef DEBUG_GENERATOR -# ifndef QT_NO_DEBUG_STREAM - if (m_composeTable.isEmpty()) - return; - - QDebug ds = qDebug() << "output:\n"; - ds.nospace(); - const int tableSize = m_composeTable.size(); - for (int i = 0; i < tableSize; ++i) { - const QComposeTableElement &elem = m_composeTable.at(i); - ds << "{ {"; - for (int j = 0; j < QT_KEYSEQUENCE_MAX_LEN; j++) { - ds << hex << showbase << elem.keys[j] << ", "; - } - ds << "}, " << hex << showbase << elem.value << ", \"\" }, // " << elem.comment << " \n"; - } -# endif -#endif -} - -void TableGenerator::orderComposeTable() -{ - // Stable-sorting to ensure that the item that appeared before the other in the - // original container will still appear first after the sort. This property is - // needed to handle the cases when user re-defines already defined key sequence - std::stable_sort(m_composeTable.begin(), m_composeTable.end(), ByKeys()); -} - diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h deleted file mode 100644 index 4f58358f4e..0000000000 --- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h +++ /dev/null @@ -1,145 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QTABLEGENERATOR_H -#define QTABLEGENERATOR_H - -#include -#include -#include -#include - -#include - -static Q_CONSTEXPR int QT_KEYSEQUENCE_MAX_LEN = 6; - -//#define DEBUG_GENERATOR - -/* Whenever QComposeTableElement gets modified supportedCacheVersion - from qtablegenerator.cpp must be bumped. */ -struct QComposeTableElement { - uint keys[QT_KEYSEQUENCE_MAX_LEN]; - uint value; -#ifdef DEBUG_GENERATOR - QString comment; -#endif -}; - -#ifndef DEBUG_GENERATOR -QT_BEGIN_NAMESPACE -Q_DECLARE_TYPEINFO(QComposeTableElement, Q_PRIMITIVE_TYPE); -QT_END_NAMESPACE -#endif - -struct ByKeys -{ - using uint_array = uint[QT_KEYSEQUENCE_MAX_LEN]; - using result_type = bool; - - bool operator()(const uint_array &lhs, const uint_array &rhs) const Q_DECL_NOTHROW - { - return std::lexicographical_compare(lhs, lhs + QT_KEYSEQUENCE_MAX_LEN, - rhs, rhs + QT_KEYSEQUENCE_MAX_LEN); - } - - bool operator()(const uint_array &lhs, const QComposeTableElement &rhs) const Q_DECL_NOTHROW - { - return operator()(lhs, rhs.keys); - } - - bool operator()(const QComposeTableElement &lhs, const uint_array &rhs) const Q_DECL_NOTHROW - { - return operator()(lhs.keys, rhs); - } - - bool operator()(const QComposeTableElement &lhs, const QComposeTableElement &rhs) const Q_DECL_NOTHROW - { - return operator()(lhs.keys, rhs.keys); - } -}; - -class TableGenerator -{ - -public: - enum TableState - { - UnsupportedLocale, - EmptyTable, - UnknownSystemComposeDir, - MissingComposeFile, - NoErrors - }; - - TableGenerator(); - ~TableGenerator(); - - void parseComposeFile(QFile *composeFile); - void printComposeTable() const; - void orderComposeTable(); - - QVector composeTable() const; - TableState tableState() const { return m_state; } - -protected: - bool processFile(const QString &composeFileName); - void parseKeySequence(char *line); - void parseIncludeInstruction(QString line); - - QString findComposeFile(); - bool findSystemComposeDir(); - QString systemComposeDir(); - QString composeTableForLocale(); - - ushort keysymToUtf8(quint32 sym); - - QString readLocaleMappings(const QByteArray &locale); - QByteArray readLocaleAliases(const QByteArray &locale); - void initPossibleLocations(); - bool cleanState() const { return m_state == NoErrors; } - QString locale() const; - -private: - QVector m_composeTable; - TableState m_state; - QString m_systemComposeDir; - QList m_possibleLocations; -}; - -#endif // QTABLEGENERATOR_H diff --git a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp index 81a730232c..6b9687c22d 100644 --- a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp +++ b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. @@ -36,131 +36,100 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ - #include "qcomposeplatforminputcontext.h" #include #include -#include -#include +#include QT_BEGIN_NAMESPACE -//#define DEBUG_COMPOSING - -static const int ignoreKeys[] = { - Qt::Key_Shift, - Qt::Key_Control, - Qt::Key_Meta, - Qt::Key_Alt, - Qt::Key_CapsLock, - Qt::Key_Super_L, - Qt::Key_Super_R, - Qt::Key_Hyper_L, - Qt::Key_Hyper_R, - Qt::Key_Mode_switch -}; - -static const int composingKeys[] = { - Qt::Key_Multi_key, - Qt::Key_Dead_Grave, - Qt::Key_Dead_Acute, - Qt::Key_Dead_Circumflex, - Qt::Key_Dead_Tilde, - Qt::Key_Dead_Macron, - Qt::Key_Dead_Breve, - Qt::Key_Dead_Abovedot, - Qt::Key_Dead_Diaeresis, - Qt::Key_Dead_Abovering, - Qt::Key_Dead_Doubleacute, - Qt::Key_Dead_Caron, - Qt::Key_Dead_Cedilla, - Qt::Key_Dead_Ogonek, - Qt::Key_Dead_Iota, - Qt::Key_Dead_Voiced_Sound, - Qt::Key_Dead_Semivoiced_Sound, - Qt::Key_Dead_Belowdot, - Qt::Key_Dead_Hook, - Qt::Key_Dead_Horn, - Qt::Key_Dead_Stroke, - Qt::Key_Dead_Abovecomma, - Qt::Key_Dead_Abovereversedcomma, - Qt::Key_Dead_Doublegrave, - Qt::Key_Dead_Belowring, - Qt::Key_Dead_Belowmacron, - Qt::Key_Dead_Belowcircumflex, - Qt::Key_Dead_Belowtilde, - Qt::Key_Dead_Belowbreve, - Qt::Key_Dead_Belowdiaeresis, - Qt::Key_Dead_Invertedbreve, - Qt::Key_Dead_Belowcomma, - Qt::Key_Dead_Currency, - Qt::Key_Dead_a, - Qt::Key_Dead_A, - Qt::Key_Dead_e, - Qt::Key_Dead_E, - Qt::Key_Dead_i, - Qt::Key_Dead_I, - Qt::Key_Dead_o, - Qt::Key_Dead_O, - Qt::Key_Dead_u, - Qt::Key_Dead_U, - Qt::Key_Dead_Small_Schwa, - Qt::Key_Dead_Capital_Schwa, - Qt::Key_Dead_Greek, - Qt::Key_Dead_Lowline, - Qt::Key_Dead_Aboveverticalline, - Qt::Key_Dead_Belowverticalline, - Qt::Key_Dead_Longsolidusoverlay -}; +Q_LOGGING_CATEGORY(lcXkbCompose, "qt.xkb.compose") QComposeInputContext::QComposeInputContext() - : m_tableState(TableGenerator::EmptyTable) - , m_compositionTableInitialized(false) { - clearComposeBuffer(); + setObjectName(QStringLiteral("QComposeInputContext")); + qCDebug(lcXkbCompose, "using xkb compose input context"); +} + +QComposeInputContext::~QComposeInputContext() +{ + xkb_compose_state_unref(m_composeState); + xkb_compose_table_unref(m_composeTable); +} + +void QComposeInputContext::ensureInitialized() +{ + if (m_initialized) + return; + + if (!m_XkbContext) { + qCWarning(lcXkbCompose) << "error: xkb context has not been set on" << metaObject()->className(); + return; + } + + m_initialized = true; + const char *const locale = setlocale(LC_CTYPE, ""); + qCDebug(lcXkbCompose) << "detected locale (LC_CTYPE):" << locale; + + m_composeTable = xkb_compose_table_new_from_locale(m_XkbContext, locale, XKB_COMPOSE_COMPILE_NO_FLAGS); + if (m_composeTable) + m_composeState = xkb_compose_state_new(m_composeTable, XKB_COMPOSE_STATE_NO_FLAGS); + + if (!m_composeTable) { + qCWarning(lcXkbCompose, "failed to create compose table"); + return; + } + if (!m_composeState) { + qCWarning(lcXkbCompose, "failed to create compose state"); + return; + } } bool QComposeInputContext::filterEvent(const QEvent *event) { - const QKeyEvent *keyEvent = (const QKeyEvent *)event; - // should pass only the key presses - if (keyEvent->type() != QEvent::KeyPress) { - return false; - } - - // if there were errors when generating the compose table input - // context should not try to filter anything, simply return false - if (m_compositionTableInitialized && (m_tableState & TableGenerator::NoErrors) != TableGenerator::NoErrors) + auto keyEvent = static_cast(event); + if (keyEvent->type() != QEvent::KeyPress) return false; - int keyval = keyEvent->key(); - int keysym = 0; - - if (ignoreKey(keyval)) + if (!inputMethodAccepted()) return false; - if (!composeKey(keyval) && keyEvent->text().isEmpty()) + // lazy initialization - we don't want to do this on an app startup + ensureInitialized(); + + if (!m_composeTable || !m_composeState) return false; - keysym = keyEvent->nativeVirtualKey(); + xkb_compose_state_feed(m_composeState, keyEvent->nativeVirtualKey()); - int nCompose = 0; - while (nCompose < QT_KEYSEQUENCE_MAX_LEN && m_composeBuffer[nCompose] != 0) - nCompose++; - - if (nCompose == QT_KEYSEQUENCE_MAX_LEN) { - reset(); - nCompose = 0; - } - - m_composeBuffer[nCompose] = keysym; - // check sequence - if (checkComposeTable()) + switch (xkb_compose_state_get_status(m_composeState)) { + case XKB_COMPOSE_COMPOSING: return true; + case XKB_COMPOSE_CANCELLED: + reset(); + return false; + case XKB_COMPOSE_COMPOSED: + { + const int size = xkb_compose_state_get_utf8(m_composeState, nullptr, 0); + QVarLengthArray buffer(size + 1); + xkb_compose_state_get_utf8(m_composeState, buffer.data(), buffer.size()); + QString composedText = QString::fromUtf8(buffer.constData()); - return false; + QInputMethodEvent event; + event.setCommitString(composedText); + QCoreApplication::sendEvent(m_focusObject, &event); + + reset(); + return true; + } + case XKB_COMPOSE_NOTHING: + return false; + default: + Q_UNREACHABLE(); + return false; + } } bool QComposeInputContext::isValid() const @@ -175,7 +144,8 @@ void QComposeInputContext::setFocusObject(QObject *object) void QComposeInputContext::reset() { - clearComposeBuffer(); + if (m_composeState) + xkb_compose_state_reset(m_composeState); } void QComposeInputContext::update(Qt::InputMethodQueries q) @@ -183,125 +153,4 @@ void QComposeInputContext::update(Qt::InputMethodQueries q) QPlatformInputContext::update(q); } -static bool isDuplicate(const QComposeTableElement &lhs, const QComposeTableElement &rhs) -{ - return std::equal(lhs.keys, lhs.keys + QT_KEYSEQUENCE_MAX_LEN, - QT_MAKE_CHECKED_ARRAY_ITERATOR(rhs.keys, QT_KEYSEQUENCE_MAX_LEN)); -} - -bool QComposeInputContext::checkComposeTable() -{ - if (!m_compositionTableInitialized) { - TableGenerator reader; - m_tableState = reader.tableState(); - - m_compositionTableInitialized = true; - if ((m_tableState & TableGenerator::NoErrors) == TableGenerator::NoErrors) { - m_composeTable = reader.composeTable(); - } else { -#ifdef DEBUG_COMPOSING - qDebug( "### FAILED_PARSING ###" ); -#endif - // if we have errors, don' try to look things up anyways. - reset(); - return false; - } - } - Q_ASSERT(!m_composeTable.isEmpty()); - QVector::const_iterator it = - std::lower_bound(m_composeTable.constBegin(), m_composeTable.constEnd(), m_composeBuffer, ByKeys()); - - // prevent dereferencing an 'end' iterator, which would result in a crash - if (it == m_composeTable.constEnd()) - it -= 1; - - QComposeTableElement elem = *it; - // would be nicer if qLowerBound had API that tells if the item was actually found - if (m_composeBuffer[0] != elem.keys[0]) { -#ifdef DEBUG_COMPOSING - qDebug( "### no match ###" ); -#endif - reset(); - return false; - } - // check if compose buffer is matched - for (int i=0; i < QT_KEYSEQUENCE_MAX_LEN; i++) { - - // check if partial match - if (m_composeBuffer[i] == 0 && elem.keys[i]) { -#ifdef DEBUG_COMPOSING - qDebug("### partial match ###"); -#endif - return true; - } - - if (m_composeBuffer[i] != elem.keys[i]) { -#ifdef DEBUG_COMPOSING - qDebug("### different entry ###"); -#endif - reset(); - return i != 0; - } - } -#ifdef DEBUG_COMPOSING - qDebug("### match exactly ###"); -#endif - - // check if the key sequence is overwriten - see the comment in - // TableGenerator::orderComposeTable() - int next = 1; - do { - // if we are at the end of the table, then we have nothing to do here - if (it + next != m_composeTable.constEnd()) { - QComposeTableElement nextElem = *(it + next); - if (isDuplicate(elem, nextElem)) { - elem = nextElem; - next++; - continue; - } else { - break; - } - } - break; - } while (true); - - commitText(elem.value); - reset(); - - return true; -} - -void QComposeInputContext::commitText(uint character) const -{ - QInputMethodEvent event; - event.setCommitString(QChar(character)); - QCoreApplication::sendEvent(m_focusObject, &event); -} - -bool QComposeInputContext::ignoreKey(int keyval) const -{ - for (uint i = 0; i < (sizeof(ignoreKeys) / sizeof(ignoreKeys[0])); i++) - if (keyval == ignoreKeys[i]) - return true; - - return false; -} - -bool QComposeInputContext::composeKey(int keyval) const -{ - for (uint i = 0; i < (sizeof(composingKeys) / sizeof(composingKeys[0])); i++) - if (keyval == composingKeys[i]) - return true; - - return false; -} - -void QComposeInputContext::clearComposeBuffer() -{ - for (uint i=0; i < (sizeof(m_composeBuffer) / sizeof(int)); i++) - m_composeBuffer[i] = 0; -} - -QComposeInputContext::~QComposeInputContext() {} - QT_END_NAMESPACE diff --git a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h index 4830959665..b1de1b1094 100644 --- a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h +++ b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. @@ -36,24 +36,24 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ - #ifndef QCOMPOSEPLATFORMINPUTCONTEXT_H #define QCOMPOSEPLATFORMINPUTCONTEXT_H +#include + #include -#include - -#include "generator/qtablegenerator.h" +#include QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcXkbCompose) + class QEvent; class QComposeInputContext : public QPlatformInputContext { Q_OBJECT - public: QComposeInputContext(); ~QComposeInputContext(); @@ -62,21 +62,22 @@ public: void setFocusObject(QObject *object) override; void reset() override; void update(Qt::InputMethodQueries) override; + bool filterEvent(const QEvent *event) override; + // This invokable is called from QXkbCommon::setXkbContext(). + Q_INVOKABLE void setXkbContext(struct xkb_context *context) { m_XkbContext = context; } + protected: - void clearComposeBuffer(); - bool ignoreKey(int keyval) const; - bool composeKey(int keyval) const; - bool checkComposeTable(); - void commitText(uint character) const; + void ensureInitialized(); private: - QObject *m_focusObject; - QVector m_composeTable; - uint m_composeBuffer[QT_KEYSEQUENCE_MAX_LEN]; - TableGenerator::TableState m_tableState; - bool m_compositionTableInitialized; + bool m_initialized = false; + xkb_context *m_context = nullptr; + xkb_compose_table *m_composeTable = nullptr; + xkb_compose_state *m_composeState = nullptr; + QObject *m_focusObject = nullptr; + struct xkb_context *m_XkbContext = nullptr; }; QT_END_NAMESPACE diff --git a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontextmain.cpp b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontextmain.cpp index 6b33df65b9..d062d4fd6a 100644 --- a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontextmain.cpp +++ b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontextmain.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. @@ -61,7 +61,7 @@ QComposeInputContext *QComposePlatformInputContextPlugin::create(const QString & if (system.compare(system, QLatin1String("compose"), Qt::CaseInsensitive) == 0 || system.compare(system, QLatin1String("xim"), Qt::CaseInsensitive) == 0) return new QComposeInputContext; - return 0; + return nullptr; } QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index ed9e87a036..a70c7db923 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -357,6 +357,8 @@ void QXcbIntegration::initialize() m_inputContext.reset(QPlatformInputContextFactory::create(icStr)); if (!m_inputContext && icStr != defaultInputContext && icStr != QLatin1String("none")) m_inputContext.reset(QPlatformInputContextFactory::create(defaultInputContext)); + + defaultConnection()->keyboard()->initialize(); } void QXcbIntegration::moveToScreen(QWindow *window, int screen) diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 6eb31d67bd..d0e02ecdd1 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -565,6 +565,12 @@ QXcbKeyboard::~QXcbKeyboard() xcb_key_symbols_free(m_key_symbols); } +void QXcbKeyboard::initialize() +{ + auto inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext(); + QXkbCommon::setXkbContext(inputContext, m_xkbContext.get()); +} + void QXcbKeyboard::selectEvents() { #if QT_CONFIG(xkb) diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h index 75071d045f..e35c82ad24 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.h +++ b/src/plugins/platforms/xcb/qxcbkeyboard.h @@ -63,6 +63,7 @@ public: ~QXcbKeyboard(); + void initialize(); void selectEvents(); void handleKeyPressEvent(const xcb_key_press_event_t *event); diff --git a/tests/auto/other/other.pro b/tests/auto/other/other.pro index a720860288..378750472d 100644 --- a/tests/auto/other/other.pro +++ b/tests/auto/other/other.pro @@ -67,3 +67,8 @@ winrt|!qtHaveModule(gui)|!qtConfig(accessibility): SUBDIRS -= qaccessibility android: SUBDIRS += \ android + +qtConfig(xkbcommon): { + SUBDIRS += \ + xkbkeyboard +} diff --git a/tests/auto/other/xkbkeyboard/tst_xkbkeyboard.cpp b/tests/auto/other/xkbkeyboard/tst_xkbkeyboard.cpp new file mode 100644 index 0000000000..65364eddf4 --- /dev/null +++ b/tests/auto/other/xkbkeyboard/tst_xkbkeyboard.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +#include +#include + +class tst_XkbKeyboard : public QObject +{ + Q_OBJECT +private slots: + void verifyComposeInputContextInterface(); +}; + +void tst_XkbKeyboard::verifyComposeInputContextInterface() +{ + QPlatformInputContext *inputContext = QPlatformInputContextFactory::create(QStringLiteral("compose")); + QVERIFY(inputContext); + + const char *const inputContextClassName = "QComposeInputContext"; + const char *const normalizedSignature = "setXkbContext(xkb_context*)"; + + QVERIFY(inputContext->objectName() == QLatin1String(inputContextClassName)); + + int methodIndex = inputContext->metaObject()->indexOfMethod(normalizedSignature); + QMetaMethod method = inputContext->metaObject()->method(methodIndex); + Q_ASSERT(method.isValid()); +} + +QTEST_MAIN(tst_XkbKeyboard) +#include "tst_xkbkeyboard.moc" + diff --git a/tests/auto/other/xkbkeyboard/xkbkeyboard.pro b/tests/auto/other/xkbkeyboard/xkbkeyboard.pro new file mode 100644 index 0000000000..17396ee475 --- /dev/null +++ b/tests/auto/other/xkbkeyboard/xkbkeyboard.pro @@ -0,0 +1,7 @@ +CONFIG += testcase +TARGET = tst_xkbkeyboard + +SOURCES += tst_xkbkeyboard.cpp + +QT = core-private gui-private testlib + From 381f79a53c57f59606c618769825569b3e7a7bcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Fri, 1 Mar 2019 12:29:16 +0100 Subject: [PATCH 1297/1650] Blacklist tst_qsocks5socketengine::passwordAuth2 It's flaky and has been for a while. However it is somewhat more flaky when using the docker setup. Task-number: QTBUG-74162 Change-Id: I49f346a39271b48395e0e17fa6821d73a24f81d4 Reviewed-by: Timur Pocheptsov --- tests/auto/network/socket/qsocks5socketengine/BLACKLIST | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/auto/network/socket/qsocks5socketengine/BLACKLIST b/tests/auto/network/socket/qsocks5socketengine/BLACKLIST index 60526827bf..8af3cea8dc 100644 --- a/tests/auto/network/socket/qsocks5socketengine/BLACKLIST +++ b/tests/auto/network/socket/qsocks5socketengine/BLACKLIST @@ -2,6 +2,9 @@ * [passwordAuth] * +# QTBUG-74162 +[passwordAuth2] +* [serverTest] windows [downloadBigFile] From 62f6fb30177043085d5ff3685ff24015b098ae14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Thu, 28 Feb 2019 14:28:00 +0100 Subject: [PATCH 1298/1650] Fix compilation without DTLS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I6062c4454c547b943d7ef26b22eeccf566888767 Reviewed-by: Mårten Nordheim --- src/network/ssl/qsslcontext_openssl11.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/network/ssl/qsslcontext_openssl11.cpp b/src/network/ssl/qsslcontext_openssl11.cpp index 21a5c779f7..db023b7331 100644 --- a/src/network/ssl/qsslcontext_openssl11.cpp +++ b/src/network/ssl/qsslcontext_openssl11.cpp @@ -193,7 +193,6 @@ init_context: minVersion = TLS1_2_VERSION; maxVersion = 0; break; -#if QT_CONFIG(dtls) case QSsl::DtlsV1_0: minVersion = DTLS1_VERSION; maxVersion = DTLS1_VERSION; @@ -210,7 +209,6 @@ init_context: minVersion = DTLS1_2_VERSION; maxVersion = DTLS_MAX_VERSION; break; -#endif // dtls case QSsl::TlsV1_3OrLater: #ifdef TLS1_3_VERSION minVersion = TLS1_3_VERSION; From b33eb938910392e2db45bfdfd3f1e2cb6aced7ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Thu, 28 Feb 2019 14:13:59 +0100 Subject: [PATCH 1299/1650] Disable DTLS is UDP socket is disabled The implementation of DTLS uses UDP socket. Change-Id: I8be5c286a47abe9fa80a5a0e139dedc2f297992d Reviewed-by: Paul Olav Tvete --- src/network/configure.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/configure.json b/src/network/configure.json index aaedc05ea4..2bccd35dc5 100644 --- a/src/network/configure.json +++ b/src/network/configure.json @@ -292,7 +292,7 @@ "label": "DTLS", "purpose": "Provides a DTLS implementation", "section": "Networking", - "condition": "features.openssl && tests.dtls", + "condition": "features.openssl && features.udpsocket && tests.dtls", "output": [ "publicFeature" ] }, "ocsp": { From 9eb50751b859cf46aa69ca5707346bd4a74a5f90 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Mon, 18 Feb 2019 22:18:24 +0100 Subject: [PATCH 1300/1650] QSpinBox: add new signal textChanged(QString) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new signal textChanged(QString) as a replacement for valueChanged(QString) so valueChanged(QString) can be removed with Qt6. This removes the ambiguous valueChanged() signal and also matches the 'text' property naming. Change-Id: I0676a7112f70add20a3a7ef9381268cd9b8a5851 Reviewed-by: Konstantin Shegunov Reviewed-by: Luca Beldi Reviewed-by: André Hartmann Reviewed-by: Richard Moe Gustavsen --- src/widgets/widgets/qabstractspinbox.cpp | 14 +++--- src/widgets/widgets/qspinbox.cpp | 47 ++++++++++++++++--- src/widgets/widgets/qspinbox.h | 8 ++++ .../widgets/widgets/qspinbox/tst_qspinbox.cpp | 6 +-- 4 files changed, 59 insertions(+), 16 deletions(-) diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp index 6a35dbe274..da4c2f98cf 100644 --- a/src/widgets/widgets/qabstractspinbox.cpp +++ b/src/widgets/widgets/qabstractspinbox.cpp @@ -252,7 +252,7 @@ QString QAbstractSpinBox::text() const All values are displayed with the prefix and suffix (if set), \e except for the special value, which only shows the special value - text. This special text is passed in the QSpinBox::valueChanged() + text. This special text is passed in the QSpinBox::textChanged() signal that passes a QString. To turn off the special-value text display, call this function @@ -342,18 +342,18 @@ void QAbstractSpinBox::setReadOnly(bool enable) \since 4.3 If keyboard tracking is enabled (the default), the spinbox - emits the valueChanged() signal while the new value is being - entered from the keyboard. + emits the valueChanged() and textChanged() signals while the + new value is being entered from the keyboard. E.g. when the user enters the value 600 by typing 6, 0, and 0, the spinbox emits 3 signals with the values 6, 60, and 600 respectively. If keyboard tracking is disabled, the spinbox doesn't emit the - valueChanged() signal while typing. It emits the signal later, - when the return key is pressed, when keyboard focus is lost, or - when other spinbox functionality is used, e.g. pressing an arrow - key. + valueChanged() and textChanged() signals while typing. It emits + the signals later, when the return key is pressed, when keyboard + focus is lost, or when other spinbox functionality is used, e.g. + pressing an arrow key. */ bool QAbstractSpinBox::keyboardTracking() const diff --git a/src/widgets/widgets/qspinbox.cpp b/src/widgets/widgets/qspinbox.cpp index 7624b1ed3c..40044223e2 100644 --- a/src/widgets/widgets/qspinbox.cpp +++ b/src/widgets/widgets/qspinbox.cpp @@ -128,9 +128,10 @@ public: manually. The spin box supports integer values but can be extended to use different strings with validate(), textFromValue() and valueFromText(). - Every time the value changes QSpinBox emits two valueChanged() signals, - one providing an int and the other a QString. The QString overload - provides the value with both prefix() and suffix(). + Every time the value changes QSpinBox emits valueChanged() and + textChanged() signals, the former providing a int and the latter + a QString. The textChanged() signal provides the value with both + prefix() and suffix(). The current value can be fetched with value() and set with setValue(). Clicking the up/down buttons or using the keyboard accelerator's @@ -182,13 +183,24 @@ public: The new value's integer value is passed in \a i. */ +/*! + \fn void QSpinBox::textChanged(const QString &text) + \since 5.14 + + This signal is emitted whenever the spin box's text is changed. + The new text is passed in \a text with prefix() and suffix(). +*/ + +#if QT_DEPRECATED_SINCE(5, 14) /*! \fn void QSpinBox::valueChanged(const QString &text) \overload + \obsolete Use textChanged(QString) instead The new value is passed in \a text with prefix() and suffix(). */ +#endif /*! Constructs a spin box with 0 as minimum value and 99 as maximum value, a @@ -594,9 +606,9 @@ void QSpinBox::fixup(QString &input) const values but can be extended to use different strings with validate(), textFromValue() and valueFromText(). - Every time the value changes QDoubleSpinBox emits two - valueChanged() signals, one taking providing a double and the other - a QString. The QString overload provides the value with both + Every time the value changes QDoubleSpinBox emits valueChanged() and + textChanged() signals, the former providing a double and the latter + a QString. The textChanged() signal provides the value with both prefix() and suffix(). The current value can be fetched with value() and set with setValue(). @@ -643,13 +655,24 @@ void QSpinBox::fixup(QString &input) const The new value is passed in \a d. */ +/*! + \fn void QDoubleSpinBox::textChanged(const QString &text) + \since 5.14 + + This signal is emitted whenever the spin box's text is changed. + The new text is passed in \a text with prefix() and suffix(). +*/ + +#if QT_DEPRECATED_SINCE(5, 14) /*! \fn void QDoubleSpinBox::valueChanged(const QString &text); \overload + \obsolete Use textChanged(QString) instead The new value is passed in \a text with prefix() and suffix(). */ +#endif /*! Constructs a spin box with 0.0 as minimum value and 99.99 as maximum value, @@ -1068,7 +1091,13 @@ void QSpinBoxPrivate::emitSignals(EmitPolicy ep, const QVariant &old) if (ep != NeverEmit) { pendingEmit = false; if (ep == AlwaysEmit || value != old) { +#if QT_DEPRECATED_SINCE(5, 14) +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED emit q->valueChanged(edit->displayText()); +QT_WARNING_POP +#endif + emit q->textChanged(edit->displayText()); emit q->valueChanged(value.toInt()); } } @@ -1219,7 +1248,13 @@ void QDoubleSpinBoxPrivate::emitSignals(EmitPolicy ep, const QVariant &old) if (ep != NeverEmit) { pendingEmit = false; if (ep == AlwaysEmit || value != old) { +#if QT_DEPRECATED_SINCE(5, 14) +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED emit q->valueChanged(edit->displayText()); +QT_WARNING_POP +#endif + emit q->textChanged(edit->displayText()); emit q->valueChanged(value.toDouble()); } } diff --git a/src/widgets/widgets/qspinbox.h b/src/widgets/widgets/qspinbox.h index d2eac903fb..762dd4a46a 100644 --- a/src/widgets/widgets/qspinbox.h +++ b/src/widgets/widgets/qspinbox.h @@ -106,7 +106,11 @@ public Q_SLOTS: Q_SIGNALS: void valueChanged(int); + void textChanged(const QString &); +#if QT_DEPRECATED_SINCE(5, 14) + QT_DEPRECATED_X("Use textChanged(QString) instead") void valueChanged(const QString &); +#endif private: Q_DISABLE_COPY(QSpinBox) @@ -168,7 +172,11 @@ public Q_SLOTS: Q_SIGNALS: void valueChanged(double); + void textChanged(const QString &); +#if QT_DEPRECATED_SINCE(5, 14) + QT_DEPRECATED_X("Use textChanged(QString) instead") void valueChanged(const QString &); +#endif private: Q_DISABLE_COPY(QDoubleSpinBox) diff --git a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp index 1d106f94f3..7174c274f9 100644 --- a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp +++ b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp @@ -206,7 +206,7 @@ private slots: void stepModifierPressAndHold_data(); void stepModifierPressAndHold(); public slots: - void valueChangedHelper(const QString &); + void textChangedHelper(const QString &); void valueChangedHelper(int); private: QStringList actualTexts; @@ -474,7 +474,7 @@ void tst_QSpinBox::setPrefixSuffix() QCOMPARE(spin.cleanText(), expectedCleanText); } -void tst_QSpinBox::valueChangedHelper(const QString &text) +void tst_QSpinBox::textChangedHelper(const QString &text) { actualTexts << text; } @@ -552,7 +552,7 @@ void tst_QSpinBox::setTracking() QSpinBox spin(0); spin.setKeyboardTracking(tracking); spin.show(); - connect(&spin, SIGNAL(valueChanged(QString)), this, SLOT(valueChangedHelper(QString))); + connect(&spin, &QSpinBox::textChanged, this, &tst_QSpinBox::textChangedHelper); keys.simulate(&spin); QCOMPARE(actualTexts, texts); From f58e47c2f34c6a703115c9b4486040ba12bd97e9 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 27 Feb 2019 14:33:10 +0100 Subject: [PATCH 1301/1650] QtWidgets: Fix deprecation warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix deprecation warnings where possible or add warnings scopes, fixing: dialogs/qdialog.cpp:783:41: warning: ‘void QDialog::showExtension(bool)’ is deprecated [-Wdeprecated-declarations] ^~~~~~~~~~~~~ widgets/qcombobox.cpp:1386:37: warning: ‘void QComboBox::currentIndexChanged(const QString&)’ is deprecated: Use currentTextChanged() instead [-Wdeprecated-declarations]= dialogs/qfiledialog_p.h:168:38: warning: ‘DirectoryOnly’ is deprecated: Use setOption(ShowDirsOnly, true) instead [-Wdeprecated-declarations] dialogs/qfiledialog.cpp:590:38: warning: ‘DirectoryOnly’ is deprecated: Use setOption(ShowDirsOnly, true) instead [-Wdeprecated-declarations] dialogs/qfiledialog.cpp:617:27: warning: ‘DirectoryOnly’ is deprecated: Use setOption(ShowDirsOnly, true) instead [-Wdeprecated-declarations] dialogs/qfiledialog.cpp:617:27: warning: ‘DirectoryOnly’ is deprecated: Use setOption(ShowDirsOnly, true) instead [-Wdeprecated-declarations] dialogs/qfiledialog.cpp:645:27: warning: ‘DirectoryOnly’ is deprecated: Use setOption(ShowDirsOnly, true) instead [-Wdeprecated-declarations] dialogs/qfiledialog.cpp:1730:17: warning: ‘DirectoryOnly’ is deprecated: Use setOption(ShowDirsOnly, true) instead [-Wdeprecated-declarations] dialogs/qfiledialog.cpp:2637:43: warning: ‘DirectoryOnly’ is deprecated: Use setOption(ShowDirsOnly, true) instead [-Wdeprecated-declarations] dialogs/qfiledialog.cpp:2750:10: warning: ‘DirectoryOnly’ is deprecated: Use setOption(ShowDirsOnly, true) instead [-Wdeprecated-declarations] dialogs/qfiledialog.cpp:2786:49: warning: ‘bool QFileDialog::confirmOverwrite() const’ is deprecated: Use !testOption(DontConfirmOverwrite) instead [-Wdeprecated-declarations] dialogs/qfiledialog.cpp:3654:27: warning: ‘DirectoryOnly’ is deprecated: Use setOption(ShowDirsOnly, true) instead [-Wdeprecated-declarations] dialogs/qfiledialog.cpp:3843:48: warning: ‘DirectoryOnly’ is deprecated: Use setOption(ShowDirsOnly, true) instead [-Wdeprecated-declarations] dialogs/qfiledialog.cpp:3895:72: warning: ‘DirectoryOnly’ is deprecated: Use setOption(ShowDirsOnly, true) instead [-Wdeprecated-declarations] styles/qwindowsstyle.cpp:836:19: warning: ‘PE_IndicatorViewItemCheck’ is deprecated [-Wdeprecated-declarations] graphicsview/qgraphicswidget.cpp:2309:51: warning: ‘PM_MDIFrameWidth’ is deprecated [-Wdeprecated-declarations] styles/qstylesheetstyle.cpp:4302:10: warning: ‘PE_FrameStatusBar’ is deprecated [-Wdeprecated-declarations] styles/qfusionstyle.cpp:3676:10: warning: ‘SH_ScrollBar_StopMouseOverSlider’ is deprecated [-Wdeprecated-declarations] Change-Id: I9e15f4a0996476ec88d8823b72f0c537dce97b9c Reviewed-by: Christian Ehrlicher --- src/widgets/dialogs/qdialog.cpp | 3 ++ src/widgets/dialogs/qfiledialog.cpp | 35 +++++++++++++++++++- src/widgets/dialogs/qfiledialog_p.h | 8 ++--- src/widgets/graphicsview/qgraphicswidget.cpp | 2 +- src/widgets/itemviews/qitemdelegate.cpp | 2 +- src/widgets/styles/qcommonstyle.cpp | 4 +-- src/widgets/styles/qfusionstyle.cpp | 4 +-- src/widgets/styles/qstylesheetstyle.cpp | 4 +-- src/widgets/styles/qwindowsstyle.cpp | 6 ++-- src/widgets/widgets/qcombobox.cpp | 3 ++ 10 files changed, 53 insertions(+), 18 deletions(-) diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp index 3c49016e2c..e7b526445e 100644 --- a/src/widgets/dialogs/qdialog.cpp +++ b/src/widgets/dialogs/qdialog.cpp @@ -780,7 +780,10 @@ void QDialog::setVisible(bool visible) QWidget::setVisible(visible); #if QT_DEPRECATED_SINCE(5, 13) +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED showExtension(d->doShowExtension); +QT_WARNING_POP #endif QWidget *fw = window()->focusWidget(); if (!fw) diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 625da78794..f772eb1241 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -587,10 +587,13 @@ void QFileDialogPrivate::retranslateWindowTitle() return; if (q->acceptMode() == QFileDialog::AcceptOpen) { const QFileDialog::FileMode fileMode = q->fileMode(); +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED if (fileMode == QFileDialog::DirectoryOnly || fileMode == QFileDialog::Directory) q->setWindowTitle(QFileDialog::tr("Find Directory")); else q->setWindowTitle(QFileDialog::tr("Open")); +QT_WARNING_POP } else q->setWindowTitle(QFileDialog::tr("Save As")); @@ -614,7 +617,10 @@ void QFileDialogPrivate::updateFileNameLabel() setLabelTextControl(QFileDialog::FileName, options->labelText(QFileDialogOptions::FileName)); } else { switch (q_func()->fileMode()) { +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED case QFileDialog::DirectoryOnly: +QT_WARNING_POP case QFileDialog::Directory: setLabelTextControl(QFileDialog::FileName, QFileDialog::tr("Directory:")); break; @@ -642,7 +648,10 @@ void QFileDialogPrivate::updateOkButtonText(bool saveAsOnFolder) return; } else { switch (q->fileMode()) { +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED case QFileDialog::DirectoryOnly: +QT_WARNING_POP case QFileDialog::Directory: setLabelTextControl(QFileDialog::Accept, QFileDialog::tr("&Choose")); break; @@ -1709,7 +1718,10 @@ void QFileDialog::setFileMode(QFileDialog::FileMode mode) d->options->setFileMode(static_cast(mode)); // keep ShowDirsOnly option in sync with fileMode (BTW, DirectoryOnly is obsolete) +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED setOption(ShowDirsOnly, mode == DirectoryOnly); +QT_WARNING_POP if (!d->usingWidgets()) return; @@ -1727,11 +1739,14 @@ void QFileDialog::setFileMode(QFileDialog::FileMode mode) // set filter d->model->setFilter(d->filterForMode(filter())); // setup file type for directory +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED if (mode == DirectoryOnly || mode == Directory) { d->qFileDialogUi->fileTypeCombo->clear(); d->qFileDialogUi->fileTypeCombo->addItem(tr("Directories")); d->qFileDialogUi->fileTypeCombo->setEnabled(false); } +QT_WARNING_POP d->updateFileNameLabel(); d->updateOkButtonText(); d->qFileDialogUi->fileTypeCombo->setEnabled(!testOption(ShowDirsOnly)); @@ -2634,7 +2649,10 @@ QUrl QFileDialog::getExistingDirectoryUrl(QWidget *parent, args.parent = parent; args.caption = caption; args.directory = QFileDialogPrivate::workingDirectory(dir); +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED args.mode = (options & ShowDirsOnly ? DirectoryOnly : Directory); +QT_WARNING_POP args.options = options; QFileDialog dialog(args); @@ -2747,7 +2765,10 @@ void QFileDialog::accept() } switch (fileMode()) { +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED case DirectoryOnly: +QT_WARNING_POP case Directory: { QString fn = files.first(); QFileInfo info(fn); @@ -2783,7 +2804,7 @@ void QFileDialog::accept() } // check if we have to ask for permission to overwrite the file - if (!info.exists() || !confirmOverwrite() || acceptMode() == AcceptOpen) { + if (!info.exists() || testOption(DontConfirmOverwrite) || acceptMode() == AcceptOpen) { d->emitFilesSelected(QStringList(fn)); QDialog::accept(); #if QT_CONFIG(messagebox) @@ -3651,7 +3672,10 @@ void QFileDialogPrivate::_q_updateOkButton() isOpenDirectory = true; } else { switch (fileMode) { +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED case QFileDialog::DirectoryOnly: +QT_WARNING_POP case QFileDialog::Directory: { QString fn = files.first(); QModelIndex idx = model->index(fn); @@ -3743,12 +3767,15 @@ void QFileDialogPrivate::_q_enterDirectory(const QModelIndex &index) const QFileDialog::FileMode fileMode = q->fileMode(); q->setDirectory(path); emit q->directoryEntered(path); +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED if (fileMode == QFileDialog::Directory || fileMode == QFileDialog::DirectoryOnly) { // ### find out why you have to do both of these. lineEdit()->setText(QString()); lineEdit()->clear(); } +QT_WARNING_POP } else { // Do not accept when shift-clicking to multi-select a file in environments with single-click-activation (KDE) if (!q->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, nullptr, qFileDialogUi->treeView) @@ -3840,7 +3867,10 @@ void QFileDialogPrivate::_q_selectionChanged() { const QFileDialog::FileMode fileMode = q_func()->fileMode(); const QModelIndexList indexes = qFileDialogUi->listView->selectionModel()->selectedRows(); +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED bool stripDirs = (fileMode != QFileDialog::DirectoryOnly && fileMode != QFileDialog::Directory); +QT_WARNING_POP QStringList allFiles; for (const auto &index : indexes) { @@ -3892,10 +3922,13 @@ void QFileDialogPrivate::_q_rowsInserted(const QModelIndex &parent) void QFileDialogPrivate::_q_fileRenamed(const QString &path, const QString &oldName, const QString &newName) { const QFileDialog::FileMode fileMode = q_func()->fileMode(); +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED if (fileMode == QFileDialog::Directory || fileMode == QFileDialog::DirectoryOnly) { if (path == rootPath() && lineEdit()->text() == oldName) lineEdit()->setText(newName); } +QT_WARNING_POP } void QFileDialogPrivate::_q_emitUrlSelected(const QUrl &file) diff --git a/src/widgets/dialogs/qfiledialog_p.h b/src/widgets/dialogs/qfiledialog_p.h index 96d0c1190e..463c77aa23 100644 --- a/src/widgets/dialogs/qfiledialog_p.h +++ b/src/widgets/dialogs/qfiledialog_p.h @@ -164,13 +164,9 @@ public: QDir::Filters filterForMode(QDir::Filters filters) const { - const QFileDialog::FileMode fileMode = q_func()->fileMode(); - if (fileMode == QFileDialog::DirectoryOnly) { - filters |= QDir::Drives | QDir::AllDirs | QDir::Dirs; + filters |= QDir::Drives | QDir::AllDirs | QDir::Dirs | QDir::Files; + if (q_func()->testOption(QFileDialog::ShowDirsOnly)) filters &= ~QDir::Files; - } else { - filters |= QDir::Drives | QDir::AllDirs | QDir::Files | QDir::Dirs; - } return filters; } diff --git a/src/widgets/graphicsview/qgraphicswidget.cpp b/src/widgets/graphicsview/qgraphicswidget.cpp index c994136091..f69faa7572 100644 --- a/src/widgets/graphicsview/qgraphicswidget.cpp +++ b/src/widgets/graphicsview/qgraphicswidget.cpp @@ -2306,7 +2306,7 @@ void QGraphicsWidget::paintWindowFrame(QPainter *painter, const QStyleOptionGrap QStyleHintReturnMask mask; bool setMask = style()->styleHint(QStyle::SH_WindowFrame_Mask, &bar, widget, &mask) && !mask.region.isEmpty(); bool hasBorder = !style()->styleHint(QStyle::SH_TitleBar_NoBorder, &bar, widget); - int frameWidth = style()->pixelMetric(QStyle::PM_MDIFrameWidth, &bar, widget); + int frameWidth = style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, &bar, widget); if (setMask) { painter->save(); painter->setClipRegion(mask.region, Qt::IntersectClip); diff --git a/src/widgets/itemviews/qitemdelegate.cpp b/src/widgets/itemviews/qitemdelegate.cpp index 6e57e0c32b..460764f1b8 100644 --- a/src/widgets/itemviews/qitemdelegate.cpp +++ b/src/widgets/itemviews/qitemdelegate.cpp @@ -789,7 +789,7 @@ void QItemDelegate::drawCheck(QPainter *painter, const QWidget *widget = d->widget(option); QStyle *style = widget ? widget->style() : QApplication::style(); - style->drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &opt, painter, widget); + style->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &opt, painter, widget); } /*! diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp index 56bc329827..b064b2eff2 100644 --- a/src/widgets/styles/qcommonstyle.cpp +++ b/src/widgets/styles/qcommonstyle.cpp @@ -194,7 +194,7 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q opt->state & (State_Sunken | State_On), 1, &opt->palette.brush(QPalette::Button)); break; - case PE_IndicatorViewItemCheck: + case PE_IndicatorItemViewItemCheck: proxy()->drawPrimitive(PE_IndicatorCheckBox, opt, p, widget); break; case PE_IndicatorCheckBox: @@ -2283,7 +2283,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, option.state |= QStyle::State_On; break; } - proxy()->drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &option, p, widget); + proxy()->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &option, p, widget); } // draw the icon diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp index 0e95d6efa4..f3961b2a99 100644 --- a/src/widgets/styles/qfusionstyle.cpp +++ b/src/widgets/styles/qfusionstyle.cpp @@ -558,7 +558,7 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, qt_fusion_draw_arrow(arrow, painter, option, option->rect, arrowColor); } break; - case PE_IndicatorViewItemCheck: + case PE_IndicatorItemViewItemCheck: { QStyleOptionButton button; button.QStyleOption::operator=(*option); @@ -3673,7 +3673,7 @@ int QFusionStyle::styleHint(StyleHint hint, const QStyleOption *option, const QW case SH_FontDialog_SelectAssociatedText: case SH_MenuBar_AltKeyNavigation: case SH_ComboBox_ListMouseTracking: - case SH_ScrollBar_StopMouseOverSlider: + case SH_Slider_StopMouseOverSlider: case SH_ScrollBar_MiddleClickAbsolutePosition: case SH_EtchDisabledText: case SH_TitleBar_AutoRaise: diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index b058d4c557..c104ac2498 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -4299,7 +4299,7 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op switch (pe) { - case PE_FrameStatusBar: { + case PE_FrameStatusBarItem: { QRenderRule subRule = renderRule(w ? w->parentWidget() : nullptr, opt, PseudoElement_Item); if (subRule.hasDrawable()) { subRule.drawRule(p, opt->rect); @@ -4320,7 +4320,7 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op pseudoElement = PseudoElement_ExclusiveIndicator; break; - case PE_IndicatorViewItemCheck: + case PE_IndicatorItemViewItemCheck: pseudoElement = PseudoElement_ViewItemIndicator; break; diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp index c0a8228e42..4e450813cb 100644 --- a/src/widgets/styles/qwindowsstyle.cpp +++ b/src/widgets/styles/qwindowsstyle.cpp @@ -554,7 +554,7 @@ int QWindowsStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWid case SH_MenuBar_MouseTracking: case SH_Menu_MouseTracking: case SH_ComboBox_ListMouseTracking: - case SH_ScrollBar_StopMouseOverSlider: + case SH_Slider_StopMouseOverSlider: case SH_MainWindow_SpaceBelowMenuBar: ret = 1; @@ -827,13 +827,13 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, p->setPen(opt->palette.text().color()); } Q_FALLTHROUGH(); - case PE_IndicatorViewItemCheck: + case PE_IndicatorItemViewItemCheck: if (!doRestore) { p->save(); doRestore = true; } #if QT_CONFIG(itemviews) - if (pe == PE_IndicatorViewItemCheck) { + if (pe == PE_IndicatorItemViewItemCheck) { const QStyleOptionViewItem *itemViewOpt = qstyleoption_cast(opt); p->setPen(itemViewOpt && itemViewOpt->showDecorationSelected diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 1ad43fffb4..a24c9d350f 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -1383,7 +1383,10 @@ void QComboBoxPrivate::_q_emitCurrentIndexChanged(const QModelIndex &index) const QString text = itemText(index); emit q->currentIndexChanged(index.row()); #if QT_DEPRECATED_SINCE(5, 13) + QT_WARNING_PUSH + QT_WARNING_DISABLE_DEPRECATED emit q->currentIndexChanged(text); + QT_WARNING_POP #endif // signal lineEdit.textChanged already connected to signal currentTextChanged, so don't emit double here if (!lineEdit) From a74b2b5f152ae81da6c0906afc63b8647c3a048a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 27 Feb 2019 11:30:31 +0100 Subject: [PATCH 1302/1650] macOS: Initialize QNSView mouse related members with other mouse logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I4ff67028823d62ed67bf4303a58bee127bd76501 Reviewed-by: Timur Pocheptsov Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qnsview.mm | 9 --------- src/plugins/platforms/cocoa/qnsview_mouse.mm | 13 +++++++++++++ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 17063f6e92..5309449dce 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -137,22 +137,13 @@ { if ((self = [super initWithFrame:NSZeroRect])) { m_platformWindow = platformWindow; - m_buttons = Qt::NoButton; - m_acceptedMouseDowns = Qt::NoButton; - m_frameStrutButtons = Qt::NoButton; m_sendKeyEvent = false; - m_sendUpAsRightButton = false; m_inputSource = nil; - m_mouseMoveHelper = [[QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) alloc] initWithView:self]; m_resendKeyEvent = false; - m_scrolling = false; m_updatingDrag = false; m_currentlyInterpretedKeyEvent = nil; - m_dontOverrideCtrlLMB = qt_mac_resolveOption(false, platformWindow->window(), - "_q_platform_MacDontOverrideCtrlLMB", "QT_MAC_DONT_OVERRIDE_CTRL_LMB"); self.focusRingType = NSFocusRingTypeNone; - self.cursor = nil; self.previousSuperview = nil; self.previousWindow = nil; diff --git a/src/plugins/platforms/cocoa/qnsview_mouse.mm b/src/plugins/platforms/cocoa/qnsview_mouse.mm index 49c94f18db..c9c87d9323 100644 --- a/src/plugins/platforms/cocoa/qnsview_mouse.mm +++ b/src/plugins/platforms/cocoa/qnsview_mouse.mm @@ -153,6 +153,19 @@ - (void)initMouse { + m_buttons = Qt::NoButton; + m_acceptedMouseDowns = Qt::NoButton; + m_frameStrutButtons = Qt::NoButton; + + m_scrolling = false; + self.cursor = nil; + + m_sendUpAsRightButton = false; + m_dontOverrideCtrlLMB = qt_mac_resolveOption(false, m_platformWindow->window(), + "_q_platform_MacDontOverrideCtrlLMB", "QT_MAC_DONT_OVERRIDE_CTRL_LMB"); + + m_mouseMoveHelper = [[QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) alloc] initWithView:self]; + NSUInteger trackingOptions = NSTrackingActiveInActiveApp | NSTrackingMouseEnteredAndExited | NSTrackingCursorUpdate; From 785d2b9d0728bbbc0d2a92b7d4186a3114d54128 Mon Sep 17 00:00:00 2001 From: David Edmundson Date: Wed, 27 Feb 2019 12:08:42 +0000 Subject: [PATCH 1303/1650] Add QStyle::standardPixmap support to all entries in QDialogButtonBox QDialogButtonBox fetches icons from the qstyle for most of the buttons it creates, with the exception of 7. This patch adds support for the remaining buttons, so that all buttons can have icons added by the theme. Behavior is unchanged until a style implements these new enumerations. Change-Id: I2eba488a11e1b9979fff3b32dafbda11332a3d92 Reviewed-by: Kai Uwe Broulik Reviewed-by: Shawn Rutledge --- src/widgets/styles/qstyle.h | 7 +++++++ src/widgets/widgets/qdialogbuttonbox.cpp | 13 +++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h index 5ee37bd8e9..ee234457f5 100644 --- a/src/widgets/styles/qstyle.h +++ b/src/widgets/styles/qstyle.h @@ -832,6 +832,13 @@ public: SP_MediaVolume, SP_MediaVolumeMuted, SP_LineEditClearButton, + SP_DialogYesToAllButton, + SP_DialogNoToAllButton, + SP_DialogSaveAllButton, + SP_DialogAbortButton, + SP_DialogRetryButton, + SP_DialogIgnoreButton, + SP_RestoreDefaultsButton, // do not add any values below/greater than this SP_CustomBase = 0xf0000000 }; diff --git a/src/widgets/widgets/qdialogbuttonbox.cpp b/src/widgets/widgets/qdialogbuttonbox.cpp index 26b86f80be..28f6cdc7bd 100644 --- a/src/widgets/widgets/qdialogbuttonbox.cpp +++ b/src/widgets/widgets/qdialogbuttonbox.cpp @@ -387,12 +387,25 @@ QPushButton *QDialogButtonBoxPrivate::createButton(QDialogButtonBox::StandardBut icon = QStyle::SP_DialogNoButton; break; case QDialogButtonBox::YesToAll: + icon = QStyle::SP_DialogYesToAllButton; + break; case QDialogButtonBox::NoToAll: + icon = QStyle::SP_DialogNoToAllButton; + break; case QDialogButtonBox::SaveAll: + icon = QStyle::SP_DialogSaveAllButton; + break; case QDialogButtonBox::Abort: + icon = QStyle::SP_DialogAbortButton; + break; case QDialogButtonBox::Retry: + icon = QStyle::SP_DialogRetryButton; + break; case QDialogButtonBox::Ignore: + icon = QStyle::SP_DialogIgnoreButton; + break; case QDialogButtonBox::RestoreDefaults: + icon = QStyle::SP_RestoreDefaultsButton; break; case QDialogButtonBox::NoButton: return 0; From 55cc93e9d68a8851163f16dfa8a25a817c2e129e Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 1 Mar 2019 14:39:25 +0100 Subject: [PATCH 1304/1650] Prefer BGRA uploading to swizzling The older BGRA extension is more likely to have stable driver support. Fixes: QTBUG-74150 Change-Id: If321b3024fbdeb9e199880744b9ee915b3b2bf6c Reviewed-by: Laszlo Agocs --- src/gui/opengl/qopengltextureuploader.cpp | 31 ++++++++++------------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/src/gui/opengl/qopengltextureuploader.cpp b/src/gui/opengl/qopengltextureuploader.cpp index 42e309b733..03b5cb6eb5 100644 --- a/src/gui/opengl/qopengltextureuploader.cpp +++ b/src/gui/opengl/qopengltextureuploader.cpp @@ -114,6 +114,18 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag externalFormat = GL_BGRA; internalFormat = GL_RGBA; pixelType = GL_UNSIGNED_INT_8_8_8_8_REV; +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + // Without GL_UNSIGNED_INT_8_8_8_8_REV, BGRA only matches ARGB on little endian: + } else if (funcs->hasOpenGLExtension(QOpenGLExtensions::BGRATextureFormat) && !sRgbBinding) { + // The GL_EXT_texture_format_BGRA8888 extension requires the internal format to match the external. + externalFormat = internalFormat = GL_BGRA; + pixelType = GL_UNSIGNED_BYTE; + } else if (context->isOpenGLES() && context->hasExtension(QByteArrayLiteral("GL_APPLE_texture_format_BGRA8888"))) { + // Is only allowed as an external format like OpenGL. + externalFormat = GL_BGRA; + internalFormat = GL_RGBA; + pixelType = GL_UNSIGNED_BYTE; +#endif } else if (funcs->hasOpenGLExtension(QOpenGLExtensions::TextureSwizzle)) { #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN GLint swizzle[4] = { GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA }; @@ -125,25 +137,8 @@ qsizetype QOpenGLTextureUploader::textureImage(GLenum target, const QImage &imag externalFormat = internalFormat = GL_RGBA; pixelType = GL_UNSIGNED_BYTE; } else { -#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN - // Without GL_UNSIGNED_INT_8_8_8_8_REV, BGRA only matches ARGB on little endian. - if (funcs->hasOpenGLExtension(QOpenGLExtensions::BGRATextureFormat) && !sRgbBinding) { - // The GL_EXT_texture_format_BGRA8888 extension requires the internal format to match the external. - externalFormat = internalFormat = GL_BGRA; - pixelType = GL_UNSIGNED_BYTE; - } else if (context->isOpenGLES() && context->hasExtension(QByteArrayLiteral("GL_APPLE_texture_format_BGRA8888"))) { - // Is only allowed as an external format like OpenGL. - externalFormat = GL_BGRA; - internalFormat = GL_RGBA; - pixelType = GL_UNSIGNED_BYTE; - } else { - // No support for direct ARGB32 upload. - break; - } -#else - // Big endian requires GL_UNSIGNED_INT_8_8_8_8_REV for ARGB to match BGRA + // No support for direct ARGB32 upload. break; -#endif } targetFormat = image.format(); break; From c6153660e458ee3790a446a327d29e622defee49 Mon Sep 17 00:00:00 2001 From: Lars Schmertmann Date: Sun, 11 Nov 2018 19:42:43 +0100 Subject: [PATCH 1305/1650] Extend the test for QSslKey MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Check if QSslKey::handle() returns data representing the same key information as that passed to the constructor. Task-number: QTBUG-64495 Change-Id: I1a91264e6f6d92d259b51fca9de00fcbfd5cc845 Reviewed-by: Mårten Nordheim Reviewed-by: Timur Pocheptsov --- .../ssl/qsslsocket_openssl11_symbols_p.h | 1 + .../ssl/qsslsocket_openssl_symbols.cpp | 4 ++ .../ssl/qsslsocket_openssl_symbols_p.h | 7 ++-- .../auto/network/ssl/qsslkey/tst_qsslkey.cpp | 38 ++++++++++++++++++- 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/network/ssl/qsslsocket_openssl11_symbols_p.h b/src/network/ssl/qsslsocket_openssl11_symbols_p.h index a44d00a830..9d0a14360d 100644 --- a/src/network/ssl/qsslsocket_openssl11_symbols_p.h +++ b/src/network/ssl/qsslsocket_openssl11_symbols_p.h @@ -82,6 +82,7 @@ Q_AUTOTEST_EXPORT const BIO_METHOD *q_BIO_s_mem(); int q_DSA_bits(DSA *a); int q_EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *c); +Q_AUTOTEST_EXPORT int q_EVP_PKEY_up_ref(EVP_PKEY *a); int q_EVP_PKEY_base_id(EVP_PKEY *a); int q_RSA_bits(RSA *a); Q_AUTOTEST_EXPORT int q_OPENSSL_sk_num(OPENSSL_STACK *a); diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index aa1dc681e0..f136c92a65 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -150,6 +150,7 @@ DEFINEFUNC(BIO *, BIO_new, const BIO_METHOD *a, a, return nullptr, return) DEFINEFUNC(const BIO_METHOD *, BIO_s_mem, void, DUMMYARG, return nullptr, return) DEFINEFUNC2(int, BN_is_word, BIGNUM *a, a, BN_ULONG w, w, return 0, return) DEFINEFUNC(int, EVP_CIPHER_CTX_reset, EVP_CIPHER_CTX *c, c, return 0, return) +DEFINEFUNC(int, EVP_PKEY_up_ref, EVP_PKEY *a, a, return 0, return) DEFINEFUNC(int, EVP_PKEY_base_id, EVP_PKEY *a, a, return NID_undef, return) DEFINEFUNC(int, RSA_bits, RSA *a, a, return 0, return) DEFINEFUNC(int, DSA_bits, DSA *a, a, return 0, return) @@ -366,6 +367,7 @@ DEFINEFUNC2(int, EVP_PKEY_set1_DH, EVP_PKEY *a, a, DH *b, b, return -1, return) #ifndef OPENSSL_NO_EC DEFINEFUNC2(int, EVP_PKEY_set1_EC_KEY, EVP_PKEY *a, a, EC_KEY *b, b, return -1, return) #endif +DEFINEFUNC2(int, EVP_PKEY_cmp, const EVP_PKEY *a, a, const EVP_PKEY *b, b, return -1, return) DEFINEFUNC(void, EVP_PKEY_free, EVP_PKEY *a, a, return, DUMMYARG) DEFINEFUNC(DSA *, EVP_PKEY_get1_DSA, EVP_PKEY *a, a, return nullptr, return) DEFINEFUNC(RSA *, EVP_PKEY_get1_RSA, EVP_PKEY *a, a, return nullptr, return) @@ -955,6 +957,7 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(OPENSSL_init_crypto) RESOLVEFUNC(ASN1_STRING_get0_data) RESOLVEFUNC(EVP_CIPHER_CTX_reset) + RESOLVEFUNC(EVP_PKEY_up_ref) RESOLVEFUNC(EVP_PKEY_base_id) RESOLVEFUNC(RSA_bits) RESOLVEFUNC(OPENSSL_sk_new_null) @@ -1184,6 +1187,7 @@ bool q_resolveOpenSslSymbols() #ifndef OPENSSL_NO_EC RESOLVEFUNC(EVP_PKEY_set1_EC_KEY) #endif + RESOLVEFUNC(EVP_PKEY_cmp) RESOLVEFUNC(EVP_PKEY_free) RESOLVEFUNC(EVP_PKEY_get1_DSA) RESOLVEFUNC(EVP_PKEY_get1_RSA) diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h index e09820b2f2..59b6e53940 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols_p.h +++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h @@ -284,11 +284,12 @@ const EVP_CIPHER *q_EVP_rc2_cbc(); Q_AUTOTEST_EXPORT const EVP_MD *q_EVP_sha1(); int q_EVP_PKEY_assign(EVP_PKEY *a, int b, char *c); Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_RSA(EVP_PKEY *a, RSA *b); -int q_EVP_PKEY_set1_DSA(EVP_PKEY *a, DSA *b); -int q_EVP_PKEY_set1_DH(EVP_PKEY *a, DH *b); +Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_DSA(EVP_PKEY *a, DSA *b); +Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_DH(EVP_PKEY *a, DH *b); #ifndef OPENSSL_NO_EC -int q_EVP_PKEY_set1_EC_KEY(EVP_PKEY *a, EC_KEY *b); +Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_EC_KEY(EVP_PKEY *a, EC_KEY *b); #endif +Q_AUTOTEST_EXPORT int q_EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b); Q_AUTOTEST_EXPORT void q_EVP_PKEY_free(EVP_PKEY *a); RSA *q_EVP_PKEY_get1_RSA(EVP_PKEY *a); DSA *q_EVP_PKEY_get1_DSA(EVP_PKEY *a); diff --git a/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp b/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp index 28476fce5b..d24fafb77b 100644 --- a/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp +++ b/tests/auto/network/ssl/qsslkey/tst_qsslkey.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -233,15 +234,50 @@ void tst_QSslKey::constructorHandle() QByteArray passphrase; if (QByteArray(QTest::currentDataTag()).contains("-pkcs8-")) passphrase = "1234"; + BIO* bio = q_BIO_new(q_BIO_s_mem()); q_BIO_write(bio, pem.constData(), pem.length()); - QSslKey key(func(bio, nullptr, nullptr, static_cast(passphrase.data())), type); + EVP_PKEY *origin = func(bio, nullptr, nullptr, static_cast(passphrase.data())); +#if QT_CONFIG(opensslv11) + q_EVP_PKEY_up_ref(origin); +#endif + QSslKey key(origin, type); +#if !QT_CONFIG(opensslv11) + q_BIO_write(bio, pem.constData(), pem.length()); + origin = func(bio, nullptr, nullptr, static_cast(passphrase.data())); +#endif q_BIO_free(bio); + EVP_PKEY *handle = q_EVP_PKEY_new(); + switch (algorithm) { + case QSsl::Rsa: + q_EVP_PKEY_set1_RSA(handle, static_cast(key.handle())); + break; + case QSsl::Dsa: + q_EVP_PKEY_set1_DSA(handle, static_cast(key.handle())); + break; + case QSsl::Dh: + q_EVP_PKEY_set1_DH(handle, static_cast(key.handle())); + break; +#ifndef OPENSSL_NO_EC + case QSsl::Ec: + q_EVP_PKEY_set1_EC_KEY(handle, static_cast(key.handle())); + break; +#endif + default: + break; + } + + auto cleanup = qScopeGuard([origin, handle] { + q_EVP_PKEY_free(origin); + q_EVP_PKEY_free(handle); + }); + QVERIFY(!key.isNull()); QCOMPARE(key.algorithm(), algorithm); QCOMPARE(key.type(), type); QCOMPARE(key.length(), length); + QCOMPARE(q_EVP_PKEY_cmp(origin, handle), 1); #endif } From eea3947842e461662cea4a31c7a5dd7f1969ec23 Mon Sep 17 00:00:00 2001 From: Nils Jeisecke Date: Sat, 6 Oct 2018 07:37:27 +0200 Subject: [PATCH 1306/1650] sqlite: Remove SQLITE_OMIT_LOAD_EXTENSION define This define prevents the usage of some customization possibilities, e.g. injecting data by using virtual tables that are implemented as an extension. [ChangeLog][Third-Party Code] Build sqlite without SQLITE_OMIT_LOAD_EXTENSION Fixes: QTBUG-70972 Change-Id: Idaf1c2c7bccbaec6f7bbf3d79334ffb4a0bad3fc Reviewed-by: Nils Jeisecke Reviewed-by: Simon Hausmann --- src/3rdparty/sqlite.pri | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/3rdparty/sqlite.pri b/src/3rdparty/sqlite.pri index 068764c726..6405beb3d0 100644 --- a/src/3rdparty/sqlite.pri +++ b/src/3rdparty/sqlite.pri @@ -1,5 +1,6 @@ CONFIG(release, debug|release):DEFINES *= NDEBUG -DEFINES += SQLITE_ENABLE_COLUMN_METADATA SQLITE_OMIT_LOAD_EXTENSION SQLITE_OMIT_COMPLETE SQLITE_ENABLE_FTS3 SQLITE_ENABLE_FTS3_PARENTHESIS SQLITE_ENABLE_FTS5 SQLITE_ENABLE_RTREE SQLITE_ENABLE_JSON1 +QT_FOR_CONFIG += core-private +DEFINES += SQLITE_ENABLE_COLUMN_METADATA SQLITE_OMIT_COMPLETE SQLITE_ENABLE_FTS3 SQLITE_ENABLE_FTS3_PARENTHESIS SQLITE_ENABLE_FTS5 SQLITE_ENABLE_RTREE SQLITE_ENABLE_JSON1 !contains(CONFIG, largefile):DEFINES += SQLITE_DISABLE_LFS qtConfig(posix_fallocate): DEFINES += HAVE_POSIX_FALLOCATE=1 winrt { @@ -8,6 +9,7 @@ winrt { } qnx: DEFINES += _QNX_SOURCE !win32:!winrt:!winphone: DEFINES += HAVE_USLEEP=1 +qtConfig(dlopen): QMAKE_USE += libdl integrity: QMAKE_CFLAGS += -include qplatformdefs.h INCLUDEPATH += $$PWD/sqlite SOURCES += $$PWD/sqlite/sqlite3.c From cc7444eb65fc42f00a33275f6b8d1d3d39f4d715 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 28 Feb 2019 10:02:21 +0100 Subject: [PATCH 1307/1650] Fix library search path order on Windows Commit 2327944d added the QMAKE_DEFAULT_LIBDIRS to the library search paths without taking care that explicit library search paths should be inserted before system search paths. Copy the behavior of the UnixMakefileGenerator, esp. of commits 5bc9541e and e185f343. Fixes: QTBUG-73959 Change-Id: I7e951f432bb5f71ce4bcdb18b7102b4380441181 Reviewed-by: Oswald Buddenhagen --- qmake/generators/win32/winmakefile.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp index 6046e5791e..208af1327f 100644 --- a/qmake/generators/win32/winmakefile.cpp +++ b/qmake/generators/win32/winmakefile.cpp @@ -84,6 +84,7 @@ Win32MakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags) if (impexts.isEmpty()) impexts = project->values("QMAKE_EXTENSION_STATICLIB"); QList dirs; + int libidx = 0; for (const ProString &dlib : project->values("QMAKE_DEFAULT_LIBDIRS")) dirs.append(QMakeLocalFileName(dlib.toQString())); static const char * const lflags[] = { "LIBS", "LIBS_PRIVATE", @@ -96,11 +97,12 @@ Win32MakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags) LibFlagType type = parseLibFlag(opt, &arg); if (type == LibFlagPath) { QMakeLocalFileName lp(arg.toQString()); - if (dirs.contains(lp)) { + int idx = dirs.indexOf(lp); + if (idx >= 0 && idx < libidx) { it = l.erase(it); continue; } - dirs.append(lp); + dirs.insert(libidx++, lp); (*it) = "-L" + lp.real(); } else if (type == LibFlagLib) { QString lib = arg.toQString(); From 070f75d3b0f5313a0f486fe5c811a8e40dd97967 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Sat, 23 Feb 2019 09:40:30 +0100 Subject: [PATCH 1308/1650] wasm: improve clipboard fallback path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This improves handling of cut/copy/paste clipboard events, ands allows clipboard access via the common keyboard shortcuts. Make the canvas be eligible for clipboard events by setting the contenteditable attribute. Install clipboard event handlers directly on the canvas. Suppress Ctrl+X/C/V key event handling in the keyboard event handler in order to make the browser generate clipboard events. Send synthetic key events from the clipboard event handlers to make the app copy/paste to Qt’s clipboard at the correct time. Access the system clipboard data using event.clipboardData. Task-number: QTBUG-64638 Change-Id: I584b78ffa2b755b1b76e477b970255c6e5522f6a Reviewed-by: Lorn Potter --- src/plugins/platforms/wasm/qtloader.js | 9 +++- src/plugins/platforms/wasm/qwasmclipboard.cpp | 50 +++++++++++++------ .../platforms/wasm/qwasmeventtranslator.cpp | 8 +++ src/plugins/platforms/wasm/wasm_shell.html | 8 ++- 4 files changed, 57 insertions(+), 18 deletions(-) diff --git a/src/plugins/platforms/wasm/qtloader.js b/src/plugins/platforms/wasm/qtloader.js index 84694c7b9f..203213db56 100644 --- a/src/plugins/platforms/wasm/qtloader.js +++ b/src/plugins/platforms/wasm/qtloader.js @@ -168,7 +168,14 @@ function QtLoader(config) removeChildren(container); var canvas = document.createElement("canvas"); canvas.className = "QtCanvas" - canvas.style = "height: 100%; width: 100%;" + canvas.style.height = "100%" + canvas.style.width = "100%" + + // Set contentEditable in order to enable clipboard events; hide the resulting focus frame. + canvas.contentEditable = true; + canvas.style.outline = "0px solid transparent"; + canvas.style.cursor = "default"; + return canvas; } diff --git a/src/plugins/platforms/wasm/qwasmclipboard.cpp b/src/plugins/platforms/wasm/qwasmclipboard.cpp index ec058f05dd..63fea7738d 100644 --- a/src/plugins/platforms/wasm/qwasmclipboard.cpp +++ b/src/plugins/platforms/wasm/qwasmclipboard.cpp @@ -67,23 +67,42 @@ static void qClipboardPromiseResolve(emscripten::val something) pasteClipboardData(emscripten::val("text/plain"), something); } -static void qClipboardCopyTo(val event) +static void qClipboardCutTo(val event) { - val target = event["target"]; - val clipboard = event["clipboardData"]; + if (!QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi) { + // Send synthetic Ctrl+X to make the app cut data to Qt's clipboard + QWindowSystemInterface::handleKeyEvent( + 0, QEvent::KeyPress, Qt::Key_X, Qt::ControlModifier, "X"); + } val module = val::global("Module"); val clipdata = module.call("getClipboardData"); val clipFormat = module.call("getClipboardFormat"); - clipboard.call("setData", clipFormat, clipdata); - target.call("preventDefault"); + event["clipboardData"].call("setData", clipFormat, clipdata); + event.call("preventDefault"); +} + +static void qClipboardCopyTo(val event) +{ + if (!QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi) { + // Send synthetic Ctrl+C to make the app copy data to Qt's clipboard + QWindowSystemInterface::handleKeyEvent( + 0, QEvent::KeyPress, Qt::Key_C, Qt::ControlModifier, "C"); + } + + val module = val::global("Module"); + val clipdata = module.call("getClipboardData"); + val clipFormat = module.call("getClipboardFormat"); + event["clipboardData"].call("setData", clipFormat, clipdata); + event.call("preventDefault"); } static void qClipboardPasteTo(val event) { - val target = event["clipboardData"]; - val module = val::global("Module"); - val clipdata = module.call("getClipboardData"); + bool hasClipboardApi = QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi; + val clipdata = hasClipboardApi ? + val::global("Module").call("getClipboardData") : + event["clipboardData"].call("getData", std::string("text")); const std::string data = clipdata.as(); if (data.length() > 0) { @@ -99,6 +118,7 @@ EMSCRIPTEN_BINDINGS(clipboard_module) { function("getClipboardFormat", &getClipboardFormat); function("pasteClipboardData", &pasteClipboardData); function("qClipboardPromiseResolve", &qClipboardPromiseResolve); + function("qClipboardCutTo", &qClipboardCutTo); function("qClipboardCopyTo", &qClipboardCopyTo); function("qClipboardPasteTo", &qClipboardPasteTo); } @@ -161,7 +181,7 @@ void QWasmClipboard::initClipboardEvents() val permissions = navigator["permissions"]; val clipboard = navigator["clipboard"]; - hasClipboardApi = (!clipboard.isUndefined()); + hasClipboardApi = (!clipboard.isUndefined() && !clipboard["readText"].isUndefined()); if (hasClipboardApi) { val readPermissionsMap = val::object(); readPermissionsMap.set("name", val("clipboard-read")); @@ -172,13 +192,13 @@ void QWasmClipboard::initClipboardEvents() permissions.call("query", writePermissionsMap); } else { - - val window = val::global("window"); - window.call("addEventListener", std::string("paste"), - val::module_property("qClipboardPasteTo")); - - window.call("addEventListener", std::string("copy"), + val canvas = val::module_property("canvas"); + canvas.call("addEventListener", std::string("cut"), + val::module_property("qClipboardCutTo")); + canvas.call("addEventListener", std::string("copy"), val::module_property("qClipboardCopyTo")); + canvas.call("addEventListener", std::string("paste"), + val::module_property("qClipboardPasteTo")); } } diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp index 3fc8f600a1..05c09ec9a0 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp @@ -832,6 +832,14 @@ bool QWasmEventTranslator::processKeyboard(int eventType, const EmscriptenKeyboa return 0; QFlags mods = translateKeyboardEventModifier(keyEvent); + + // Clipboard fallback path: cut/copy/paste are handled by clipboard event + // handlers if direct clipboard access is not available. + if (!QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi && modifiers & Qt::ControlModifier && + (qtKey == Qt::Key_X || qtKey == Qt::Key_C || qtKey == Qt::Key_V)) { + return 0; + } + bool accepted = false; if (keyType == QEvent::KeyPress && diff --git a/src/plugins/platforms/wasm/wasm_shell.html b/src/plugins/platforms/wasm/wasm_shell.html index 67bfcdfbdc..110d45e036 100644 --- a/src/plugins/platforms/wasm/wasm_shell.html +++ b/src/plugins/platforms/wasm/wasm_shell.html @@ -7,7 +7,11 @@ @@ -19,7 +23,7 @@ - +